Merge "i2c: qrd7627a: set i2c1 gpios to minimum strength"
diff --git a/Documentation/arm/msm/msm_smp2p.txt b/Documentation/arm/msm/msm_smp2p.txt
new file mode 100644
index 0000000..4f77614
--- /dev/null
+++ b/Documentation/arm/msm/msm_smp2p.txt
@@ -0,0 +1,416 @@
+Introduction
+============
+The Shared Memory Point to Point (SMP2P) protocol facilitates communication of
+a single 32-bit value between two processors.  Each value has a single writer
+(the local side) and a single reader (the remote side).  Values are uniquely
+identified in the system by the directed edge (local processor ID to remote
+processor ID) and a string identifier.
+
+Version and feature negotiation has been included in the design to allow for
+phased upgrades of all processors.
+
+Software Architecture Description
+=================================
+The data and interrupt coupling between processors is shown in Fig. 1.  Each
+processor is responsible for creating the outgoing SMEM items and each item is
+writable by the local processor and readable by the remote processor.  By using
+two separate SMEM items that are single-reader and single-writer, SMP2P does
+not require any remote locking mechanisms.
+
+The client API uses the Linux GPIO and interrupt framework to expose a virtual
+GPIO and a virtual interrupt controller for each entry.
+
+                                      =================
+                                      |               |
+                     -----write------>|SMEM item A->B |-----read------
+                    |                 |               |               |
+                    |                 =================               |
+                    |                                                 |
+                    |                                                 v
+  GPIO API =>  ------------    ======= Interrupt line ======>     ------------
+               Processor A                                        Processor B
+ Interrupt <=  ------------    <====== Interrupt line =======     ------------
+    API             ^                                                 |
+                    |                                                 |
+                    |                                                 |
+                    |                 =================               |
+                    |                 |               |               |
+                     ------read-------|SMEM item A<-B |<-----write----
+                                      |               |
+                                      =================
+
+                                    Fig 1
+
+
+Design
+======
+Each SMEM item contains a header that is used to identify and manage the edge
+along with an array of actual entries.  The overall structure is captured in
+Fig 2 and the details of the header and entries are covered later in this
+section.  The memory format of all shared structures is little-endian.
+
+      -----------------------------------------------
+     |               SMEM item A->B                  |
+     |                                               |
+     |   -----------------------------------------   |
+     |  |31      24|       16|         8|        0|  |
+     |  |----------|---------|----------|---------|  |
+     |  |       Identifier Constant(Magic Number) |  |
+     |  |----------|---------|----------|---------|  |
+     |  | Feature Flags                 |Version  |  |
+     |  |                               |Number   |  |
+     |  |----------|---------|----------|---------|  |
+     |  | Remote Proc ID     |Local Proc ID       |  |
+     |  |----------|---------|----------|---------|  |
+     |  | Entries Valid      | Entries Total      |  |
+     |  |-----------------------------------------|  |
+     |                                               |
+     |                                               |
+     |   -----------------------------------------   |
+     |   |            Entry 0                    |   |
+     |   |  ----------------------------------   |   |
+     |   |  |       Identifier String         |  |   |
+     |   |  |---------------------------------|  |   |
+     |   |  |       Data                      |  |   |
+     |   |  |---------------------------------|  |   |
+     |   |---------------------------------------|   |
+     |   -----------------------------------------   |
+     |   |            Entry 1                    |   |
+     |   |  ----------------------------------   |   |
+     |   |  |       Identifier String         |  |   |
+     |   |  |---------------------------------|  |   |
+     |   |  |       Data                      |  |   |
+     |   |  |---------------------------------|  |   |
+     |   |---------------------------------------|   |
+     |                      -                        |
+     |                      -                        |
+     |                      -                        |
+     |   -----------------------------------------   |
+     |   |            Entry N                    |   |
+     |   |  ----------------------------------   |   |
+     |   |  |       Identifier String         |  |   |
+     |   |  |---------------------------------|  |   |
+     |   |  |       Data                      |  |   |
+     |   |  |---------------------------------|  |   |
+     |   |---------------------------------------|   |
+      -----------------------------------------------
+
+                            Fig 2
+
+
+The header of each SMEM item contains metadata that describes the processors
+using the edge, the version information, and the entry count.  The constant
+identifier is used as a magic number to enable extraction of the items from a
+memory dump.  The size of each entry depends upon the version, but the number
+of total entries (and hence the size of each SMEM item) is configurable with a
+suggested value of 16.
+
+The number of valid entries is used to indicate how many of the Entries Total
+are currently used and are current valid.
+
+   ---------------------------------------------------------------------------
+  |Field        Size       Description                Valid Values            |
+   ---------------------------------------------------------------------------
+  | Identifier  4 Bytes    Value used to identify                             |
+  | Constant               structure in memory.     Must be set to $SMP       |
+  |                        Useful for debugging.    (0x504D5324)              |
+   ---------------------------------------------------------------------------
+  | Local       2 Bytes    Writing processor ID.    Refer Processor ID Table 3|
+  | Processor                                                                 |
+  | ID                                                                        |
+   ---------------------------------------------------------------------------
+  | Remote      2 Bytes    Reading processor ID.    Refer Processor ID Table 3|
+  | Processor                                                                 |
+  | ID                                                                        |
+   ---------------------------------------------------------------------------
+  | Version      1 Bytes   Refer to Version                                   |
+  | Number                 Feature Negotiation      Must be set to 1.         |
+  |                        section.                                           |
+   ---------------------------------------------------------------------------
+  | Feature      3 Bytes   Refer to Version                                   |
+  | flags                  and Feature Negotiation  Must be set to zero.      |
+  |                        section.                                           |
+   ---------------------------------------------------------------------------
+  | Entries      2 Bytes   Total number of          Must be 0 or greater.     |
+  | Total                  entries.                                           |
+   ---------------------------------------------------------------------------
+  | Entries      2 Bytes   Number of valid          Must be between 0         |
+  | Valid                  entries.                 and Entries Total.        |
+   ---------------------------------------------------------------------------
+  | Reserved     4 Bytes   Reserved                 Must be set to 0.         |
+   ---------------------------------------------------------------------------
+                           Table 1 - SMEM Item Header
+
+The content of each SMEM entries is described in Table 2 and consists of a
+string identifier and a 32-bit data value.  The string identifier must be
+unique for each SMEM item.  The data value is opaque to SMP2P giving the client
+complete flexibility as to its usage.
+
+   ----------------------- --------------------- -----------------------------
+  | Field      | Size     | Description         |      Valid Values           |
+   ------------|----------|---------------------|-----------------------------
+  |            |          |                     |                             |
+  | Identifier | 16 Bytes | Null Terminated     |     NON-NULL for            |
+  | String     |          | ASCII string.       |     valid entries.          |
+  |            |          |                     |                             |
+   ------------|----------|---------------------|-----------------------------
+  | Data       |  4 Bytes | Data                |     Any (client defined)    |
+   ------------ ---------- --------------------- -----------------------------
+                              Table 2 - Entry Format
+
+
+The processor IDs in the system are fixed and new processors IDs will be
+added to the end of the list (Table 3).
+
+              -------------------------------------------------
+             | Processor Name             |     ID value       |
+              -------------------------------------------------
+             | Application processor      |        0           |
+              -------------------------------------------------
+             | Modem processor            |        1           |
+              -------------------------------------------------
+             | Audio processor            |        2           |
+              -------------------------------------------------
+             | Sensor processor           |        3           |
+              -------------------------------------------------
+             | Wireless processor         |        4           |
+              -------------------------------------------------
+             | Modem Fw                   |        5           |
+              -------------------------------------------------
+             | Power processor            |        6           |
+              -------------------------------------------------
+             | NUM PROCESSORS             |        7           |
+              -------------------------------------------------
+                            Table 3 - Processor IDs
+
+SMEM Item
+---------
+The responsibility of creating an SMEM item is with the local processor that is
+initiating outbound traffic.  After creating the item, the local and remote
+processors negotiate the version and feature flags for the item to ensure
+compatibility.
+
+Table 4 lists the SMEM item base identifiers.  To get the SMEM item ID for a
+particular edge, the remote processor ID (Table 3) is added to the base item ID
+for the local processor (Table 4).  For example, the Apps ==> Modem (id 1) SMEM
+Item ID will be 427 + 1 = 428.
+
+          --------------------------------------------------
+         | Description                   | SMEM ID value    |
+          --------------------------------------------------
+         | Apps SMP2P SMEM Item base     |       427        |
+          --------------------------------------------------
+         | Modem SMP2P SMEM Item base    |       435        |
+          --------------------------------------------------
+         | Audio SMP2P SMEM Item base    |       443        |
+          --------------------------------------------------
+         | Wireless SMP2P SMEM Item base |       451        |
+          --------------------------------------------------
+         | Power SMP2P SMEM Item base    |       459        |
+          --------------------------------------------------
+                      Table 4 - SMEM Items Base IDs
+
+
+Version and Feature Negotiation
+-------------------------------
+To enable upgrading without breaking the system and to enable graceful feature
+fall-back support, SMP2P supports a version number and feature flags.  The
+combination of the version number and feature flags enable:
+ 1) SMP2P software updates to be rolled out to each processor separately.
+ 2) Individual features to be enabled or disabled per connection or edge.
+
+The version number represents any change in SMP2P that breaks compatibility
+between processors.  Examples would be a change in the shared data structures
+or changes to fundamental behavior.  Each implementation of SMP2P must be able
+to support a minimum of the current version and the previous version.
+
+The feature flags represent any changes in SMP2P that are optional and
+backwards compatible.  Endpoints will negotiate the supported flag when the
+SMEM items are created and they cannot be changed after negotiation has been
+completed.
+
+
+Negotiation Algorithm
+----------------------
+While creating the SMEM item the following algorithm shall be used.
+
+    if remote endpoint's SMEM Item exists
+        Read remote version number and flags
+        Local version number must be lower of
+            - remote version number
+            - highest supported local version number
+        Flags value is bitwise AND of
+            - remote feature flags
+            - locally supported flags
+        Create SMEM item and populate negotiated number and flags
+        Interrupt remote processor
+        if version and flags match, negotiation is complete, else wait
+        for remote interrupt below.
+    Else
+        Create SMEM item and populate it with highest supported version and any
+        requested feature flag.
+        Interrupt remote processor.
+        Wait for Interrupt below.
+
+Upon receiving the interrupt from remote processor and negotiation is not
+complete, check the version number and feature flags:
+    if equal, negotiation is complete.
+    if remote number is less than local number, and remote number is
+    supported:
+        Set local version number to remote version number
+        Bitwise AND local flags with remote flags
+        Interrupt remote processor
+        Negotiation is complete
+    if remote number is not supported, then negotiation has failed
+        Set version number to 0xFF and report failure in kernel log.
+    if remote number is more than local number:
+        Wait for remote endpoint to process our interrupt and negotiate down.
+
+
+Creating an SMEM Entry
+----------------------
+Each new SMEM entry used in data transfer must be created at the end of the
+entry array in the SMEM item and cannot be deleted until the system is
+rebooted.  The following sequence is be followed:
+    1) Compare Entries Valid and Entries Total to verify if there is room in the
+       entry array for this request (if not, return error code to client).
+    2) Populate the Identifier of new entry and do a write memory barrier.
+    3) Update Entries Valid and Entries Total and do a write memory barrier.
+    4) Interrupt remote endpoint.
+
+
+Entry Write
+-----------
+An entry write is achieved by the following sequence of operations:
+    1) Update data field in the entry and do a write memory barrier.
+    2) Interrupt remote endpoint.
+
+
+Entry Read / Receiving Interrupts
+---------------------------------
+An interrupt will be received from the remote system for one or more of the following events:
+    1) Initialization
+    2) Entry change
+    3) New Entry
+
+As long as the SMEM item initialization is complete, then each interrupt should
+trigger SMP2P to:
+    1) Compare valid entry data value to cached value and notify client if it
+       has changed.
+    2) Compare Entries Valid to cached value.  If changed, initialize new entries.
+
+Performance
+===========
+No performance issues are anticipated as the signaling rate is expected to be
+low and is performed in interrupt context which minimizes latency.
+
+Interfaces
+================
+SMP2P is only supported in the kernel and interfaces with clients through the
+GPIO and interrupt subsystems.
+
+To map an entry to the client, the client must add two nodes to the Device
+Tree:
+  1) A node that matches "qcom,smp2pgpio" to create the entry
+  2) A node that matches the client driver to provide the GPIO pin mapping
+
+The details of the device tree entries are contained in the file
+Documentionat/devicetree/bindings/arm/msm/smp2p.txt.
+
+
+    /* SMP2P Test Driver for inbound entry. */
+    smp2pgpio_smp2p_7_in: qcom,smp2pgpio-smp2p-7-in {
+        compatible = "qcom,smp2pgpio";
+        qcom,entry-name = "smp2p";
+        qcom,remote-pid = <7>;
+        qcom,is_inbound;
+        gpio-controller;
+        #gpio-cells = <2>;
+        interrupt-controller;
+        #interrupt-cells = <2>;
+    };
+
+    /* SMP2P Test Client for inbound entry. */
+    qcom,smp2pgpio_test_smp2p_7_in {
+        compatible = "qcom,smp2pgpio_test_smp2p_7_in";
+        gpios = <&smp2pgpio_smp2p_7_in 0 0>,
+            <&smp2pgpio_smp2p_7_in 1 0>,
+            . . .
+            <&smp2pgpio_smp2p_7_in 31 0>;
+    };
+
+    /* SMP2P Test Driver for outbound entries */
+    smp2pgpio_smp2p_345_out: qcom,smp2pgpio-smp2p-7-out {
+        compatible = "qcom,smp2pgpio";
+        qcom,entry-name = "smp2p";
+        qcom,remote-pid = <7>;
+        gpio-controller;
+        #gpio-cells = <2>;
+        interrupt-controller;
+        #interrupt-cells = <2>;
+    };
+
+    /* SMP2P Test Client for outbound entry. */
+    qcom,smp2pgpio_test_smp2p_7_out {
+        compatible = "qcom,smp2pgpio_test_smp2p_7_out";
+        gpios = <&smp2pgpio_smp2p_7_out 0 0>,
+            <&smp2pgpio_smp2p_7_out 1 0>,
+            . . .
+            <&smp2pgpio_smp2p_7_out 31 0>;
+
+The client can use a match entry for "qcom,smp2pgpio_test_smp2p_7_in" to
+retrieve the Device Tree configuration node.  Once that node has been
+retrieved, the client can call of_get_gpio() to get the virtual GPIO pin and
+also use gpio_to_irq() to map the GPIO pin to a virtual interrupt.  After that
+point, the standard GPIO and Interrupt APIs can be used to manipulate the SMP2P
+entries and receive notifications of changes.  Examples of typical function
+calls are shown below:
+    of_get_gpio()
+    gpio_get_value()
+    gpio_set_value()
+    gpio_to_irq()
+    request_irq()
+    free_irq()
+
+Please reference the unit test code for example usage.
+
+Debug
+=====
+The state values and names for all entries accessible by the Apps are
+accessible through debugfs nodes for general debug purposes.
+
+Debugfs entries for triggering unit-tests are also exported.
+
+Internal logging will be performed using the IPC Logging module to enable
+post-mortem analysis.
+
+Testing
+=======
+On-target unit testing will be done to verify internal functionality and the
+GPIO/IRQ API's.
+
+Driver parameters
+=================
+One module parameter will be provided to change the verbosity of internal logging.
+
+Config options
+==============
+Configuration of interrupts will be done using Device Tree.  By default, the
+testing components will be enabled since it does not affect performance and has
+a minimal impact on kernel size.  However, customers can disable the testing
+components for size optimization.
+
+    CONFIG_MSM_SMP2P - enables SMP2P core functionality
+    CONFIG_MSM_SMP2P_TEST - enables unit test support
+
+Dependencies
+===========
+Requires SMEM for creating the SMEM items.
+
+User Space utilities
+====================
+No userspace utilities are planned.
+
+Known issues
+============
+None.
diff --git a/Documentation/devicetree/bindings/arm/msm/acpuclock/acpuclock-a7.txt b/Documentation/devicetree/bindings/arm/msm/acpuclock/acpuclock-a7.txt
new file mode 100644
index 0000000..7a15f6a
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/acpuclock/acpuclock-a7.txt
@@ -0,0 +1,22 @@
+* Qualcomm Application CPU clock device
+
+acpuclock-a7 selects the clock source used by the cpus and l2 cache. It
+can be configured to divide the clock source by any value in [1, 16] in
+half-integer increments.
+
+Required properties:
+- compatible: "qcom,acpuclk-a7"
+- reg: offset and length of the register sets for the acpuclock controller
+- reg-names: name of the bases for the above registers. "rcg_base"
+	     is expected.
+- a7_cpu-supply: regulator to supply a7 cpu
+- a7_mem-supply: regulator to supply a7 l2 cache
+
+Example:
+	qcom,acpuclk@f9011050 {
+		compatible = "qcom,acpuclk-a7";
+		reg = <0xf9011050 0x8>;
+		reg-names = "rcg_base";
+		a7_cpu-supply = <&pm8026_s2>;
+		a7_mem-supply = <&pm8026_l3>;
+	};
diff --git a/Documentation/devicetree/bindings/arm/msm/bcl.txt b/Documentation/devicetree/bindings/arm/msm/bcl.txt
new file mode 100644
index 0000000..e11a817
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/bcl.txt
@@ -0,0 +1,15 @@
+* Battery Current Limit
+
+This Battery Current Limit device, provides an interface to detect and notify
+interested applications when the SOC is drawing current in excess of the limits
+specified.
+
+The device tree parameters for bcl are:
+
+Required parameters:
+- compatible: Must be "qcom,bcl"
+
+Example:
+	qcom,bcl {
+		compatible = "qcom,bcl";
+	};
diff --git a/Documentation/devicetree/bindings/arm/msm/debug-pc-cntr.txt b/Documentation/devicetree/bindings/arm/msm/debug-pc-cntr.txt
deleted file mode 100644
index 01301be..0000000
--- a/Documentation/devicetree/bindings/arm/msm/debug-pc-cntr.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-* MSM PC Debug Counters
-
-MSM PC debug counter reserves 16 registers in the IMEM memory space which
-maintains a count on the state of power collapse on each core. This count
-will be useful to debug the power collapse state on each core.
-
-The required nodes for MSM PC Debug Counters are:
-
-- compatible: "qcom,pc-cntr"
-- reg: physical IMEM address reserved for PC counters
-
-Example:
-
-qcom,pc-cntr@fe800000 {
-		compatible = "qcom,pc-cntr";
-		reg = <0xfe800664 0x40>;
-	};
-
diff --git a/Documentation/devicetree/bindings/arm/msm/imem.txt b/Documentation/devicetree/bindings/arm/msm/imem.txt
new file mode 100644
index 0000000..0d56b34
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/imem.txt
@@ -0,0 +1,15 @@
+Qualcomm IMEM
+
+IMEM is fast on-chip memory used for various debug features and dma transactions.
+
+Required properties
+
+-compatible: "qcom,msm-imem"
+-reg: start address and size of imem memory
+
+Example:
+
+	qcom,msm-imem {
+		compatible = "qcom,msm-imem";
+		reg = <0xdeadbeef 0x1000>; /* < start_address size > */
+	};
diff --git a/Documentation/devicetree/bindings/arm/msm/ipc-spinlock.txt b/Documentation/devicetree/bindings/arm/msm/ipc-spinlock.txt
new file mode 100644
index 0000000..24dbb4b
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/ipc-spinlock.txt
@@ -0,0 +1,27 @@
+Qualcomm Interprocessor Communication Spinlock
+
+--Dedicated Hardware Implementation--
+Required properties:
+- compatible : should be "qcom,ipc-spinlock-sfpb"
+- reg : the location and size of the spinlock hardware
+- qcom,num-locks : the number of locks supported
+
+Example:
+
+	qcom,ipc-spinlock@fd484000 {
+		compatible = "qcom,ipc-spinlock-sfpb";
+		reg = <0xfd484000 0x1000>;
+		qcom,num-locks = <32>;
+	};
+
+--LDREX Implementation--
+Required properties:
+- compatible : should be "qcom,ipc-spinlock-ldrex"
+- reg : the location and size of the shared lock memory
+
+Example:
+
+	qcom,ipc-spinlock@fa00000 {
+		compatible = "qcom,ipc-spinlock-ldrex";
+		reg = <0xfa00000 0x200000>;
+	};
diff --git a/Documentation/devicetree/bindings/arm/msm/jtag-mm.txt b/Documentation/devicetree/bindings/arm/msm/jtag-mm.txt
new file mode 100644
index 0000000..21dead3
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/jtag-mm.txt
@@ -0,0 +1,21 @@
+* JTAG-MM
+
+The jtag-mm entry specifies the memory mapped addresses for the debug and ETM
+registers. The jtag-mm driver uses these to save and restore the registers
+using memory mapped access during power collapse so as to retain their state
+accross power collapse. This is necessary in case cp14 access to the registers
+is not permitted.
+
+Required Properties:
+compatible: component name used for driver matching, should be "qcom,jtag-mm"
+reg: physical base address and length of the register set
+reg-names: should be "etm-base" for etm register set and "debug-base" for debug
+	register set.
+
+Example:
+jtag_mm: jtagmm@fc332000 {
+	compatible = "qcom,jtag-mm";
+	reg = <0xfc332000 0x1000>,
+		<0xfc333000 0x1000>;
+	reg-names = "etm-base","debug-base";
+	};
diff --git a/Documentation/devicetree/bindings/arm/msm/lpm-levels.txt b/Documentation/devicetree/bindings/arm/msm/lpm-levels.txt
index 4129f7f..6d22003 100644
--- a/Documentation/devicetree/bindings/arm/msm/lpm-levels.txt
+++ b/Documentation/devicetree/bindings/arm/msm/lpm-levels.txt
@@ -8,6 +8,10 @@
 lpm-level. The units for voltage are dependent on the PMIC used on the target
 and are in uV.
 
+The optional properties are:
+
+- qcom,use-qtimer: Indicates whether the target uses the synchronized QTimer.
+
 The required nodes for lpm-levels are:
 
 - compatible: "qcom,lpm-levels"
@@ -31,9 +35,17 @@
 	in mWatts.uSec
 - qcom,time-overhead: The time spent in entering and exiting this level in uS
 
+Optional properties
+- qcom,irqs-detectable: The field indicates whether the IRQs are detectable by
+			the GIC controller when entering a low power mode.
+- qcom,gpio-detectable: The field indicates whether the GPIOs can be detected
+			by the GPIO interrupt controller during a given low
+			power mode.
+
 Example:
 
 qcom,lpm-levels {
+	qcom,use-qtimer;
 	qcom,lpm-level@0 {
 		reg = <0>;
 		qcom,mode = <0>;        /* MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT */
@@ -43,6 +55,8 @@
 		qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
 		qcom,vdd-dig-upper-bound = <5>; /* MAX */
 		qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+		qcom,irqs-detectable;
+		qcom,gpio-detectable;
 		qcom,latency-us = <100>;
 		qcom,ss-power = <650>;
 		qcom,energy-overhead = <801>;
diff --git a/Documentation/devicetree/bindings/arm/msm/mpm_counter.txt b/Documentation/devicetree/bindings/arm/msm/mpm_counter.txt
new file mode 100644
index 0000000..e62b9ec
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/mpm_counter.txt
@@ -0,0 +1,17 @@
+* MSM Timetick counter (mpm-v2)
+
+The MPM provides a timetick that starts when the device is powered up and
+is not reset by any of the boot loaders or the HLOS. The MPM timetick counter
+driver provides an api to get this value.
+
+The required nodes for the MPM timetick counter driver are:
+
+- compatible: "qcom,mpm-counter"
+- reg: Specifies the physical address of the timetick count register.
+
+Example:
+	qcom,mpm-counter@fc4a3000 {
+		compatible = "qcom,mpm-counter";
+		reg = <0xfc4a3000 0x1000>;
+	};
+
diff --git a/Documentation/devicetree/bindings/arm/msm/msm_bus.txt b/Documentation/devicetree/bindings/arm/msm/msm_bus.txt
index fb72525..4d441ba 100644
--- a/Documentation/devicetree/bindings/arm/msm/msm_bus.txt
+++ b/Documentation/devicetree/bindings/arm/msm/msm_bus.txt
@@ -1,6 +1,141 @@
-MSM Bus Scaling Driver
+MSM Bus Devices
 
-The msm bus scaling driver provides the ability to configure
+The bus devices (fabrics/NoCs) are the interconnects between various
+components on chipsets. These devices form the backbone of the chip
+topology. Entire topology of the chipset is built using the
+device-tree data of these bus devices.
+
+To add the bus devices following properties are required:
+
+compatible:		The bus devices need to be compatible with
+			msm-bus-fabric
+cell-id:		A 32 bit integer unique per bus per chipset. The IDs
+			for buses are in multiples of 1024.
+label:			Bus name
+qcom,fabclk-dual:	Dual set (active/sleep) bus clock name
+qcom,fabclk-active:	Active set bus clock name
+
+
+The following properties are optional as a bus might not support
+these features:
+
+qcom,ntieredslaves:	Number of tiered slaves on the bus.
+qcom,qos-freq:		QoS frequency (In Hz)
+qcom,hw-sel:		A string which decides whether QoS data
+			should be sent to RPM, set using BIMC or NoCs.
+			It can be set to "RPM", "NoC" or "BIMC".
+qcom,rpm-en:		A boolean flag indicating whether RPM transactions are
+			supported for nodes of the bus.
+qcom,ahb:		A boolean flag indicating whether the bus is ahb type.
+qcom,virt:		A boolean property indicating this is a virtual bus.
+reg:			Register space of the bus device. Not required in case
+			the bus is virtual.
+
+The following properties are optional as collecting data via coresight might
+not be supported for every bus. The documentation for coresight properties
+can be found in:
+Documentation/devicetree/bindings/coresight/coresight.txt
+
+coreisght-id		Unique integer identifier for the bus.
+coresight-name		Unique descriptive name of the bus.
+coresight-nr-inports	Number of input ports on the bus.
+coresight-outports	List of output port numbers on the bus.
+coresight-child-list	List of phandles pointing to the children of this
+			component.
+coresight-child-ports	List of input port numbers of the children.
+
+
+Any interconnect on the bus is represented as a child node.
+A child node can be of type: master, slave or a gateway.
+A gateway is an interconnect between buses and can be of both
+master and slave type.
+
+The following properties are available to characterize a child node.
+The properties can be chosen depending on the type of child node.
+
+cell-id:		For a master the ID is between 0 - 512
+			For a slave the ID is between 512 - 1024
+label:			Name of the master/slave/gateway
+qcom,masterp:		Hardware master port number(s)
+qcom,tier:		The tier to which a master/slave belongs.
+			Note that tiering might not be supported on
+			all architectures.
+qcom,hw-sel:		A string which decides whether QoS data should be sent
+			to RPM, set using BIMC or NoCs.
+			It can be set to "RPM", "NoC" or "BIMC".
+qcom,mode:		Used for masters on NoC/BIMC. Indicates which of the
+			four modes (Fixed/Limiter/Bypass/Regulator) the master
+			belongs to.
+qcom,perm-mode:		Permissible mode switches. Indicates which of the four
+			modes are supported of the master node. Generally,
+			modes are set at boot-up and not switched at run-time.
+qcom,qport:		QoS port number. This can be different from the
+			master-port number.
+qcom,ws:		Window size (in Hz), used for NoC/BIMC masters to
+			calculate saturation values.
+qcom,mas-hw-id:		A unique hardware ID agreed upon by processors across
+			the system. This ID is assigned to every master. It can
+			be used to send master specific data from
+			Apps/Modem/LPASS to RPM.
+qcom,slv-hw-id:		A unique hardware ID agreed upon by processors across
+			the system. This ID is assigned to every slave. It can
+			be used to send slave specific data from
+			Apps/Modem/LPASS to RPM.
+qcom,gateway:		Flag indicating whether a particular node is a gateway.
+qcom,slavep:		Hardware slave port number(s).
+qcom,buswidth:		Width of the interconnect between a node and the bus.
+			(In Bytes).
+qcom,prio-rd:		Read priority for a BIMC bus master (Can be 0/1/2)
+qcom,prio-wr:		Write priority for a BIMC bus master (Can be 0/1/2)
+
+
+Example:
+
+
+	msm-mmss-noc@fc478000 {
+		compatible = "msm-bus-fabric";
+		reg = <0xfc478000 0x00004000>;
+		cell-id = <2048>;
+		label = "msm_mmss_noc";
+		qcom,fabclk-dual = "bus_clk";
+		qcom,fabclk-active = "bus_a_clk";
+		qcom,ntieredslaves = <0>;
+		qcom,qos-freq = <4800>;
+		qcom,hw-sel = "NoC";
+		qcom,rpm-en;
+
+		mas-gfx3d {
+			cell-id = <26>;
+			label = "mas-gfx3d";
+			qcom,masterp = <2 3>;
+			qcom,tier = <2>;
+			qcom,hw-sel = "NoC";
+			qcom,perm-mode = "Bypass";
+			qcom,mode = "Bypass";
+			qcom,ws = <10000>;
+			qcom,qport = <2 3>;
+			qcom,mas-hw-id = <6>;
+		};
+
+		mas-jpeg {
+			cell-id = <62>;
+			label = "mas-jpeg";
+			qcom,masterp = <4>;
+			qcom,tier = <2>;
+			qcom,hw-sel = "NoC";
+			qcom,perm-mode = "Bypass";
+			qcom,mode = "Bypass";
+			qcom,qport = <0>;
+			qcom,ws = <10000>;
+			qcom,mas-hw-id = <7>;
+		};
+	};
+
+
+
+
+
+The bus scaling driver also provides the ability to configure
 bus performance parameters across the entire chip-set.
 Various clients use MSM scaling APIs to request bandwidth
 between multiple master-slave pairs. The bus driver then finds
diff --git a/Documentation/devicetree/bindings/arm/msm/msm_iommu_domains.txt b/Documentation/devicetree/bindings/arm/msm/msm_iommu_domains.txt
new file mode 100644
index 0000000..7d69749
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/msm_iommu_domains.txt
@@ -0,0 +1,50 @@
+IOMMU Domains
+
+An IOMMU domain is a collection of IOMMU context banks and an optional
+virtual address space that is to be used with the domain. Domains that are
+defined will be created at bootup and associated with an iommu group. Clients
+can then refer to the iommu group and perform operations on the iommu group
+instead of individual devices/contexts.
+
+Required properties
+
+- compatible: "qcom,iommu-domains"
+
+- At least one child that defines a domain is required with the
+  following properties:
+
+	- label: Name of the domain
+	- qcom,iommu-contexts: List of phandles to context that belongs to
+	  this domain.
+
+	Optional properties
+
+		- qcom,virtual-addr-pool: List of <start_address size> pairs
+		  that define the virtual address space for this domain.
+		- qcom,secure-domain: boolean indicating that this is a secure
+		  domain that is to be programmed by Trustzone.
+		- qcom,l2-redirect: boolean indicating that page tables should
+		  be cached in L2 cache.
+Example:
+	qcom,iommu-domains {
+		compatible = "qcom,iommu-domains";
+
+		qcom,iommu-domain1 {
+			label = "lpass_secure";
+			qcom,iommu-contexts = <&lpass_q6_fw>;
+			qcom,virtual-addr-pool = <0x00000000 0x0FFFFFFF
+						  0xF0000000 0x0FFFFFFF>;
+		};
+
+		qcom,iommu-domain2 {
+			label = "lpass_audio";
+			qcom,iommu-contexts = <&lpass_audio_shared>;
+			qcom,virtual-addr-pool = <0x10000000 0x0FFFFFFF>;
+		};
+
+		qcom,iommu-domain3 {
+			label = "lpass_video";
+			qcom,iommu-contexts = <&lpass_video_shared>;
+			qcom,virtual-addr-pool = <0x20000000 0x0FFFFFFF>;
+		};
+	};
diff --git a/Documentation/devicetree/bindings/arm/msm/msm_memory_hole.txt b/Documentation/devicetree/bindings/arm/msm/msm_memory_hole.txt
new file mode 100644
index 0000000..3cce02c
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/msm_memory_hole.txt
@@ -0,0 +1,20 @@
+Memory Hole
+
+The msm_mem_hole module exists for the express purpose of removing
+memory via the msm memory-remove mechanism (see
+memory-reserve.txt). Compiling this module into a kernel is
+essentially the means by which any nodes in the device tree with
+compatible = "qcom,msm-mem-hole" will be "activated", thus providing a
+convenient mechanism for enabling/disabling memory removal
+(qcom,memory-*).
+
+
+Required properties
+
+- compatible: "qcom,msm-mem-hole"
+
+	qcom,msm-mem-hole {
+		compatible = "qcom,msm-mem-hole";
+		qcom,memblock-remove = <0x8100000 0x7e00000>; /* Address and Size of Hole */
+	};
+
diff --git a/Documentation/devicetree/bindings/arm/msm/msm_tspp.txt b/Documentation/devicetree/bindings/arm/msm/msm_tspp.txt
new file mode 100644
index 0000000..2b5e143
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/msm_tspp.txt
@@ -0,0 +1,73 @@
+TSPP Driver
+
+For information on the TSPP driver, please refer to the TSPP driver
+documentation: Documentation/arm/msm/tspp.txt.
+
+The devicetree representation of the TSPP block should be:
+
+Required properties:
+
+- compatible: "qcom,msm_tspp"
+- cell-index: <0> - represents device ID.
+- reg: physical memory base addresses and sizes for the following:
+	TSIF0, TSIF1, TSPP and TSPP_BAM.
+- reg-names: names of the memory regions.
+- interrupts: represents IRQ numbers for the following:
+	TSIF_TSPP_IRQ, TSIF0_IRQ, TSIF1_IRQ, TSIF_BAM_IRQ.
+- interrupt-names: TSPP, TSIF and BAM interrupt names.
+- qcom,tsif-pclk: interface clock name.
+- qcom,tsif-ref-clk: reference clock name.
+	The driver uses clk_get to get the clocks by name. The clocks
+	should be defined in the relevant clock file (e.g. clock-8974.c).
+- gpios: GPIO numbers for TSIF0 (CLK, EN, DATA and SYNC) and TSIF1 (same).
+- qcom,gpio-names: GPIO names - strings describing the GPIO functionality.
+- qcom,gpios-func: GPIO functionality according to the GPIO functionality table.
+	GPIO pins can have more than a single functionality, and the TSPP driver
+	is responsible for configuring the GPIOs to work in TSIF functionality
+	based on this parameter.
+	Note: it is assumed that the functionality value (e.g. 1 in 8974 case)
+	is applicable to all TSIF GPIOs.
+
+Example (for 8974 platform, avaialble at msm8974.dtsi):
+
+	tspp: msm_tspp@f99d8000 {
+		compatible = "qcom,msm_tspp";
+		cell-index = <0>;
+		reg = <0xf99d8000 0x1000>, /* MSM_TSIF0_PHYS */
+		      <0xf99d9000 0x1000>, /* MSM_TSIF1_PHYS */
+		      <0xf99da000 0x1000>, /* MSM_TSPP_PHYS  */
+		      <0xf99c4000 0x14000>; /* MSM_TSPP_BAM_PHYS */
+		reg-names = "MSM_TSIF0_PHYS",
+			"MSM_TSIF1_PHYS",
+			"MSM_TSPP_PHYS",
+			"MSM_TSPP_BAM_PHYS";
+		interrupts = <0 153 0>, /* TSIF_TSPP_IRQ */
+			<0 151 0>, /* TSIF0_IRQ */
+			<0 152 0>, /* TSIF1_IRQ */
+			<0 154 0>; /* TSIF_BAM_IRQ */
+		interrupt-names = "TSIF_TSPP_IRQ",
+			"TSIF0_IRQ",
+			"TSIF1_IRQ",
+			"TSIF_BAM_IRQ";
+		qcom,tsif-pclk = "iface_clk";
+		qcom,tsif-ref-clk = "ref_clk";
+		gpios = <&msmgpio 89 0>, /* TSIF0 CLK  */
+			<&msmgpio 90 0>, /* TSIF0 EN   */
+			<&msmgpio 91 0>, /* TSIF0 DATA */
+			<&msmgpio 92 0>, /* TSIF0 SYNC */
+			<&msmgpio 93 0>, /* TSIF1 CLK  */
+			<&msmgpio 94 0>, /* TSIF1 EN   */
+			<&msmgpio 95 0>, /* TSIF1 DATA */
+			<&msmgpio 96 0>; /* TSIF1 SYNC */
+		qcom,gpio-names = "tsif_clk",
+				"tsif_en",
+				"tsif_data",
+				"tsif_sync",
+				"tsif_clk",
+				"tsif_en",
+				"tsif_data",
+				"tsif_sync";
+		qcom,gpios-func = <1>;
+	};
+
+
diff --git a/Documentation/devicetree/bindings/arm/msm/msm_watchdog.txt b/Documentation/devicetree/bindings/arm/msm/msm_watchdog.txt
index 9f0c922..a665431 100644
--- a/Documentation/devicetree/bindings/arm/msm/msm_watchdog.txt
+++ b/Documentation/devicetree/bindings/arm/msm/msm_watchdog.txt
@@ -12,14 +12,17 @@
 
 The device tree parameters for the watchdog are:
 
-Required parameters:
+Required properties:
 
 - compatible : "qcom,msm-watchdog"
 - reg : offset and length of the register set for the watchdog block.
 - interrupts : should contain bark and bite irq numbers
 - qcom,pet-time : Non zero time interval at which watchdog should be pet in ms.
 - qcom,bark-time : Non zero timeout value for a watchdog bark in ms.
-- qcom,ipi-ping : send keep alive ping to other cpus if set to 1 else set to 0.
+
+Optional properties:
+
+- qcom,ipi-ping : (boolean) send keep alive ping to other cpus if present
 
 Example:
 
@@ -29,5 +32,5 @@
 		interrupts = <0 3 0 0 4 0>;
 		qcom,bark-time = <11000>;
 		qcom,pet-time = <10000>;
-		qcom,ipi-ping = <1>;
+		qcom,ipi-ping;
 	};
diff --git a/Documentation/devicetree/bindings/arm/msm/pm-8x60.txt b/Documentation/devicetree/bindings/arm/msm/pm-8x60.txt
index b429072..a372912 100644
--- a/Documentation/devicetree/bindings/arm/msm/pm-8x60.txt
+++ b/Documentation/devicetree/bindings/arm/msm/pm-8x60.txt
@@ -5,6 +5,9 @@
 the kernel to be notified of idle and suspend states and when called, follows
 through the set of instructions in putting the application cores to the lowest
 power mode possible.
+The PC debug counter reserves 16 registers in the IMEM memory space which maintains
+a count on the state of power collapse on each core. This count will be useful to
+debug the power collapse state on each core.
 
 The required properties for PM-8x60 are:
 
@@ -12,17 +15,22 @@
 
 The optional properties are:
 
+- reg: physical IMEM address reserved for PC counters and the size
 - qcom,use-sync-timer: Indicates whether the target uses the synchronized QTimer.
 - qcom,pc-mode: Indicates the type of power collapse used by the target. The
-           valid values for this are:
+	valid values for this are:
 	0  (Power collapse terminates in TZ; integrated L2 cache controller)
 	1, (Power collapse doesn't terminate in TZ; external L2 cache controller)
 	2  (Power collapse terminates in TZ; external L2 cache controller)
+- qcom,saw-turns-off-pll: Version of SAW2.1 or can turn off the HFPLL, when
+	doing power collapse and so the core need to switch to Global PLL before
+	PC.
 
 Example:
 
-qcom,pm-8x60 {
+qcom,pm-8x60@fe800664 {
 		compatible = "qcom,pm-8x60";
+		reg = <0xfe800664 0x40>;
 		qcom,pc-mode = <0>;
 		qcom,use-sync-timer;
 	};
diff --git a/Documentation/devicetree/bindings/arm/msm/rpm-log.txt b/Documentation/devicetree/bindings/arm/msm/rpm-log.txt
new file mode 100644
index 0000000..552955b
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/rpm-log.txt
@@ -0,0 +1,43 @@
+* RPM Log
+
+RPM maintains Ulog in the RPM RAM. A device tree node is added
+that will hold the address of the RPM RAM region from where
+Ulog is read. The physical address from the RPM RAM region
+contains a header where various parameters to read the log are
+defined. These parameter's offsets in the header are also stored
+as a part of the device tree node.
+
+The required properties for rpm-log are:
+
+- compatible: "qcom,rpm-log"
+- reg: Specifies the base physical address and the size of the RPM
+	registers from where ulog is read.
+- qcom,rpm-addr-phys: RPM reads physical address of the RPM RAM region
+		differently when compared to Apps. Physical address of
+		the RPM RAM region is at an offset when seen from Apps.
+		This property specifies the offset which will get added
+		to the physical address of RPM RAM to make it
+		accessible to the Apps.
+- qcom,offset-version: Offset from the start of the phys_addr_base where version
+			information is stored.
+- qcom,offset-page-buffer-addr: Offset from the start of the phys_addr_base
+				where raw log start address is stored. Raw log
+				start address is the start of raw log in the
+				RPM address space as it should be seen from rpm.
+- qcom,offset-log-len: Offset from the start of the phy_addr_base where log
+			length is stored.
+- qcom,offset-log-len-mask: Offset from the start of the phy_addr_base where
+				log length mask is stored.
+- qcom,offset-page-indices: Offset from the start of the phy_addr_base where
+				index to the writer is stored.
+Example:
+qcom,rpm-log@fc19dc00 {
+	compatible = "qcom,rpm-log";
+	reg = <0xfc19dc00 0x2000>,
+	qcom,offset-rpm-addr = <0xfc000000>;
+	qcom,offset-version = <4>;
+	qcom,offset-page-buffer-addr = <36>;
+	qcom,offset-log-len = <40>;
+	qcom,offset-log-len-mask = <44>;
+	qcom,offset-page-indices = <56>;
+};
diff --git a/Documentation/devicetree/bindings/arm/msm/rpm-regulator-smd.txt b/Documentation/devicetree/bindings/arm/msm/rpm-regulator-smd.txt
index 93b5144..d930799 100644
--- a/Documentation/devicetree/bindings/arm/msm/rpm-regulator-smd.txt
+++ b/Documentation/devicetree/bindings/arm/msm/rpm-regulator-smd.txt
@@ -113,8 +113,14 @@
 					14 = 1.37
 					15 = 1.28
 					16 = 1.20
-- qcom,init-head-room:         Voltage head room in uV required for the
-				regulator
+- qcom,init-head-room:         Voltage head room in mV required for the
+				regulator.  This head room value should be used
+				in situations where the device connected to the
+				output of the regulator has low noise tolerance.
+				Note that the RPM independently enforces a
+				safety head room value for subregulated LDOs
+				which is sufficient to account for LDO drop-out
+				voltage.
 - qcom,init-quiet-mode:        Specify that quiet mode is needed for an SMPS
 				regulator in order to have lower output noise.
 				Supported values are:
diff --git a/Documentation/devicetree/bindings/arm/msm/rpm-smd.txt b/Documentation/devicetree/bindings/arm/msm/rpm-smd.txt
index 8ebd3ba..7235a1a 100644
--- a/Documentation/devicetree/bindings/arm/msm/rpm-smd.txt
+++ b/Documentation/devicetree/bindings/arm/msm/rpm-smd.txt
@@ -20,6 +20,17 @@
 - rpm-channel-type: The interal SMD edge for this subsystem found in
 			<mach/msm_smd.h>
 
+Optional properties
+- rpm-standlone: Allow the driver to run in standalone mode. This is a
+			suggestion to the RPM driver and if the SMD
+			channel is made available for RPM, the driver
+			would continue to send requests to RPM processor,
+			but if the SMD channel is unavailable, driver will
+			return success even though the data is not sent
+			to the RPM processor. In the absence of this
+			option, the driver will fail if the SMD channel
+			is unavailable.
+
 Example:
 
 	qcom,rpm-smd {
diff --git a/Documentation/devicetree/bindings/arm/msm/smp2p.txt b/Documentation/devicetree/bindings/arm/msm/smp2p.txt
new file mode 100644
index 0000000..7a5f506
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/smp2p.txt
@@ -0,0 +1,21 @@
+Qualcomm SMSM Point-to-Point (SMP2P)
+
+Required properties:
+-compatible : should be "qcom,smp2p"
+-reg : the location and offset of the irq register base memory
+-reg-names : "irq-reg-base", "irq-reg-offset" - string to identify the irq
+             register region and offset values
+-qcom,remote-pid : the SMP2P remote processor ID (see smp2p_private_api.h)
+-qcom,irq-bitmask : the sending irq bitmask
+-interrupts : the receiving interrupt line
+
+Example:
+
+	qcom,smp2p-modem {
+		compatible = "qcom,smp2p";
+		reg = <0xfa006000 0x1000>, <0x8 0x0>;
+		reg-names = "irq-reg-base", "irq-reg-offset";
+		qcom,remote-pid = <1>;
+		qcom,irq-bitmask = <0x4000>;
+		interrupts = <0 27 1>;
+	};
diff --git a/Documentation/devicetree/bindings/bif/bif.txt b/Documentation/devicetree/bindings/bif/bif.txt
new file mode 100644
index 0000000..c4ff08b
--- /dev/null
+++ b/Documentation/devicetree/bindings/bif/bif.txt
@@ -0,0 +1,22 @@
+BIF (Battery Interface) Controllers
+
+Optional properties:
+- qcom,known-device-addresses:  Specifies a list of integers which correspond to
+                                the 8-bit BIF bus device addresses of BIF slaves
+                                found on the target.
+
+BIF Consumers
+
+Optional properties:
+- qcom,bif-ctrl:                phandle of parent BIF controller device node
+
+Example:
+	foo_ctrl: foo-controller {
+		...
+		qcom,known-device-addresses = <0x80, 0x81>;
+	};
+
+	bar-consumer {
+		...
+		qcom,bif-ctrl = <&foo_ctrl>;
+	};
diff --git a/Documentation/devicetree/bindings/bluetooth/bluetooth_power.txt b/Documentation/devicetree/bindings/bluetooth/bluetooth_power.txt
new file mode 100644
index 0000000..88d69e0
--- /dev/null
+++ b/Documentation/devicetree/bindings/bluetooth/bluetooth_power.txt
@@ -0,0 +1,16 @@
+* Bluetooth Controller
+Bluetooth controller communicates with the Bluetooth Host using HCI Transport layer.
+HCI Transport layer can be based on UART or USB serial communication protocol.
+
+Required properties:
+  - compatible: Should be "qca,ar3002"
+  - qca,bt-reset-gpio: GPIO pin to bring BT Controller out of reset
+
+Optional properties:
+  None
+
+Example:
+  bt-ar3002 {
+    compatible = "qca,ar3002";
+    qca,bt-reset-gpio = <&pm8941_gpios 34 0>;
+  };
diff --git a/Documentation/devicetree/bindings/bt-fm/fm.txt b/Documentation/devicetree/bindings/bt-fm/fm.txt
new file mode 100644
index 0000000..6bb3599
--- /dev/null
+++ b/Documentation/devicetree/bindings/bt-fm/fm.txt
@@ -0,0 +1,29 @@
+Qualcomm radio iris device
+
+-FM RX playback with no RDS
+
+   FM samples is filtered by external RF chips at baseband, then send to Riva-FM core through serial link.
+   FM signal is demodulated then audio L/R samples are stored inside memory.
+   FM Rx received samples data is connected to external audio codec.
+
+-Audio playback to FM TX
+
+  Used to play audio source  to FM TX.
+  FM TX module will read the audio samples from memory then modulated samples will be send through serial interface to external RF chip.
+
+-RX playback with RDS
+
+  FM Rx receive audio data along with RDS.
+
+-FM TX with RDS
+
+  Used to send RDS messages to external FM receiver.
+
+Required Properties:
+- compatible: "qcom,iris_fm"
+
+Example:
+	qcom,iris-fm {
+		compatible = "qcom,iris_fm";
+	};
+
diff --git a/Documentation/devicetree/bindings/coresight/coresight.txt b/Documentation/devicetree/bindings/coresight/coresight.txt
index f860618..48f25de 100644
--- a/Documentation/devicetree/bindings/coresight/coresight.txt
+++ b/Documentation/devicetree/bindings/coresight/coresight.txt
@@ -12,6 +12,7 @@
 
 - compatible : name of the component used for driver matching
 - reg : physical base address and length of the register set(s) of the component
+- reg-names: names corresponding to each reg property value
 - coresight-id : unique integer identifier for the component
 - coresight-name : unique descriptive name of the component
 - coresight-nr-inports : number of input ports on the component
@@ -31,14 +32,23 @@
 			 component
 - coresight-child-ports : list of input port numbers of the children
 - coresight-default-sink : represents the default compile time CoreSight sink
+- coresight-ctis : list of ctis that this component interacts with
 - qcom,pc-save : program counter save implemented
+- qcom,blk-size : block size for tmc-etr to usb transfers
+- qcom,round-robin : indicates if per core etms are allowed round-robin access
+		     by the funnel
+- qcom,reset-flush-race : indicates if a race exists between flushing and ddr
+			  being put into self-refresh during watchdog reset
+- qcom,write-64bit : only 64bit data writes supported by stm
 
 Examples:
 
 1. Sinks
 	tmc_etr: tmc@fc322000 {
 		compatible = "arm,coresight-tmc";
-		reg = <0xfc322000 0x1000>;
+		reg = <0xfc322000 0x1000>,
+		      <0xfc37c000 0x3000>;
+		reg-names = "tmc-etr-base", "tmc-etr-bam-base";
 
 		coresight-id = <0>;
 		coresight-name = "coresight-tmc-etr";
@@ -49,6 +59,7 @@
 	tpiu: tpiu@fc318000 {
 		compatible = "arm,coresight-tpiu";
 		reg = <0xfc318000 0x1000>;
+		reg-names = "tpiu-base";
 
 		coresight-id = <1>;
 		coresight-name = "coresight-tpiu";
@@ -59,6 +70,7 @@
 	funnel_merg: funnel@fc31b000 {
 		compatible = "arm,coresight-funnel";
 		reg = <0xfc31b000 0x1000>;
+		reg-names = "funnel-merg-base";
 
 		coresight-id = <4>;
 		coresight-name = "coresight-funnel-merg";
@@ -71,6 +83,7 @@
 	funnel_in0: funnel@fc319000 {
 		compatible = "arm,coresight-funnel";
 		reg = <0xfc319000 0x1000>;
+		reg-names = "funnel-in0-base";
 
 		coresight-id = <5>;
 		coresight-name = "coresight-funnel-in0";
@@ -85,6 +98,7 @@
 		compatible = "arm,coresight-stm";
 		reg = <0xfc321000 0x1000>,
 		      <0xfa280000 0x180000>;
+		reg-names = "stm-base", "stm-data-base";
 
 		coresight-id = <9>;
 		coresight-name = "coresight-stm";
@@ -97,6 +111,7 @@
 	etm0: etm@fc33c000 {
 		compatible = "arm,coresight-etm";
 		reg = <0xfc33c000 0x1000>;
+		reg-names = "etm0-base";
 
 		coresight-id = <10>;
 		coresight-name = "coresight-etm0";
@@ -105,4 +120,26 @@
 		coresight-child-list = <&funnel_kpss>;
 		coresight-child-ports = <0>;
 		qcom,pc-save;
+		qcom,round-robin;
+	};
+
+4. Miscellaneous
+	cti0: cti@fc308000 {
+		compatible = "arm,coresight-cti";
+		reg = <0xfc308000 0x1000>;
+		reg-names = "cti0-base";
+
+		coresight-id = <15>;
+		coresight-name = "coresight-cti0";
+		coresight-nr-inports = <0>;
+	};
+
+	cti1: cti@fc309000 {
+		compatible = "arm,coresight-cti";
+		reg = <0xfc309000 0x1000>;
+		reg-names = "cti1-base";
+
+		coresight-id = <16>;
+		coresight-name = "coresight-cti1";
+		coresight-nr-inports = <0>;
 	};
diff --git a/Documentation/devicetree/bindings/crypto/msm/qcedev.txt b/Documentation/devicetree/bindings/crypto/msm/qcedev.txt
index c50a6c3..bf97e80 100644
--- a/Documentation/devicetree/bindings/crypto/msm/qcedev.txt
+++ b/Documentation/devicetree/bindings/crypto/msm/qcedev.txt
@@ -3,16 +3,31 @@
 Required properties:
   - compatible : should be "qcom,qcedev"
   - reg : should contain crypto, BAM register map.
+  - reg-names : should contain the crypto and bam base register names.
   - interrupts : should contain crypto BAM interrupt.
   - qcom,bam-pipe-pair : should contain crypto BAM pipe pair index.
+  - qcom,ce-hw-instance : should contain crypto HW instance.
+  - qcom,msm_bus,name: Should be "qcedev-noc"
+  - qcom,msm_bus,num_cases: Depends on the use cases for bus scaling
+  - qcom,msm_bus,active-only: Default vector index
+  - qcom,msm_bus,num_paths: The paths for source and destination ports
+  - qcom,msm_bus,vectors: Vectors for bus topology.
 
 Example:
 
-        qcom,qcedev@fd440000 {
+	qcom,qcedev@fd440000 {
 		compatible = "qcom,qcedev";
 		reg = <0xfd440000 0x20000>,
-		      <0xfd444000 0x8000>;
+			<0xfd444000 0x8000>;
 		reg-names = "crypto-base","crypto-bam-base";
 		interrupts = <0 235 0>;
 		qcom,bam-pipe-pair = <0>;
+		qcom,ce-hw-instance = <1>;
+                qcom,msm-bus,name = "qcedev-noc";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,active-only = <0>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<56 512 0 0>,
+				<56 512 3936000 393600>,
 	};
diff --git a/Documentation/devicetree/bindings/crypto/msm/qcrypto.txt b/Documentation/devicetree/bindings/crypto/msm/qcrypto.txt
index 1b0f703..c99262b 100644
--- a/Documentation/devicetree/bindings/crypto/msm/qcrypto.txt
+++ b/Documentation/devicetree/bindings/crypto/msm/qcrypto.txt
@@ -3,8 +3,15 @@
 Required properties:
   - compatible : should be "qcom,qcrypto"
   - reg : should contain crypto, BAM register map.
+  - reg-names : should contain the crypto and bam base register names.
   - interrupts : should contain crypto BAM interrupt.
-  - qcom,bam-pipe-pair : should contain crypto BAM pipe pair.
+  - qcom,bam-pipe-pair : should contain crypto BAM pipe pair index.
+  - qcom,ce-hw-instance : should contain crypto HW instance.
+  - qcom,msm_bus,name: Should be "qcrypto-noc"
+  - qcom,msm_bus,num_cases: Depends on the use cases for bus scaling
+  - qcom,msm_bus,active-only: Default vector index
+  - qcom,msm_bus,num_paths: The paths for source and destination ports
+  - qcom,msm_bus,vectors: Vectors for bus topology.
 
 Example:
 
@@ -15,4 +22,12 @@
 		reg-names = "crypto-base","crypto-bam-base";
 		interrupts = <0 235 0>;
 		qcom,bam-pipe-pair = <1>;
+		qcom,ce-hw-instance = <1>;
+                qcom,msm-bus,name = "qcrypto-noc";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,active-only = <0>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<56 512 0 0>,
+				<56 512 3936000 393600>,
 	};
diff --git a/Documentation/devicetree/bindings/fb/mdss-dsi-ctrl.txt b/Documentation/devicetree/bindings/fb/mdss-dsi-ctrl.txt
new file mode 100644
index 0000000..7d19c03
--- /dev/null
+++ b/Documentation/devicetree/bindings/fb/mdss-dsi-ctrl.txt
@@ -0,0 +1,29 @@
+Qualcomm mdss-dsi-ctrl
+
+mdss-dsi-ctrl is a dsi controller device which supports host controllers that
+are compatable with MIPI display serial interface specification.
+
+Required properties:
+- compatible:				Must be "qcom,mdss-dsi-ctrl"
+- cell-index:				Specifies the controller used among the two controllers.
+- reg:					offset and length of the register set for the device.
+- vdd-supply:				Phandle for vdd regulator device node.
+- vdd-io-supply:			Phandle for vdd-io regulator device node.
+- vreg-supply:				Phandle for vreg regulator device node.
+- qcom,mdss-fb-map:			pHandle that specifies the framebuffer to which the
+					interface is mapped.
+
+Optional properties:
+- label:		        	A string used to describe the controller used.
+
+Example:
+        mdss_dsi0: qcom,mdss_dsi@fd922800 {
+                compatible = "qcom,mdss-dsi-ctrl";
+                label = "MDSS DSI CTRL->0";
+                cell-index = <0>;
+                reg = <0xfd922800 0x600>;
+                vdd-supply = <&pm8941_l22>;
+                vdd_io-supply = <&pm8941_l12>;
+                vreg-supply = <&pm8941_l2>;
+		qcom,mdss-fb-map = <&mdss_fb0>;
+        };
diff --git a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
index 26bddd9..0588c5e 100644
--- a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
@@ -1,6 +1,6 @@
 Qualcomm mdss-dsi-panel
 
-mdss-dsi-panel is a dsi panel driver which supports panels that
+mdss-dsi-panel is a dsi panel device which supports panels that
 are compatable with MIPI display serial interface specification.
 
 Required properties:
@@ -9,11 +9,17 @@
 					the panel driver. By default this property will be
 					set to "disable". Will be set to "ok/okay" status
 					for specific platforms.
+- qcom,dsi-ctrl-phandle:		Specifies the phandle for the DSI controller that
+					this panel will be mapped to.
 - qcom,mdss-pan-res:			A two dimensional array that specifies the panel
 					resolution.
 - qcom,mdss-pan-bpp:			Specifies the panel bits per pixel. Default value is 24(rgb888).
 					18 = for rgb666
 					16 = for rgb565
+- qcom,mdss-pan-dest:			A string that specifies the destination display for the panel.
+					Default is "display_1".
+					"display_1" = DISPLAY_1
+					"display_2" = DISPLAY_2
 - qcom,panel-phy-regulatorSettings:	An array of length 7 that specifies the PHY
 					regulator settings for the panel.
 - qcom,panel-phy-timingSettings:	An array of length 12 that specifies the PHY
@@ -45,15 +51,12 @@
 					--> size of payload
 					--> payload.
 
-Required structure:
-- A qcom,mdss-dsi-panel node must be a child of an mdss-dsi controller node that links to
-    one of the two DSI controllers.
-
-
 Optional properties:
 - label:		        	A string used as a descriptive name of the panel
 - qcom,enable-gpio:			Specifies the panel lcd/display enable gpio.
 - qcom,rst-gpio:			Specifies the panel reset gpio.
+- qcom,mdss-pan-broadcast-mode:		Boolean used to enable broadcast mode.
+- qcom,cont-splash-enabled:		Boolean used to enable continuous splash mode.
 - qcom,mdss-pan-porch-values:		An array of size 6 that specifies the panel blanking values.
 - qcom,mdss-pan-underflow-clr:		Specifies the controller settings for the panel underflow clear
 					settings. Default value is 0xff.
@@ -102,6 +105,15 @@
 					5 = DSI_RGB_SWAP_GBR
 - qcom,mdss-pan-dsi-data-lanes:		An array that specifies the data lanes enabled.
 					<1 1 0 0> = data lanes 1 and 2 are enabled.(default).
+- qcom,mdss-pan-dsi-dlane-swap:		Specifies the data lane swap configuration.
+					0 = <0 1 2 3> (default value)
+					1 = <3 0 1 2>
+					2 = <2 3 0 1>
+					3 = <1 2 3 0>
+					4 = <0 3 2 1>
+					5 = <1 0 3 2>
+					6 = <2 1 0 3>
+					7 = <3 2 1 0>
 - qcom,mdss-pan-dsi-t-clk:		An array that specifies the byte clock cycles
 					before and after each mode switch.
 - qcom,mdss-pan-dsi-stream:		Specifies the packet stream to be used.
@@ -120,38 +132,44 @@
 					6 = Software trigger and TE
 - qcom,mdss-pan-dsi-frame-rate:		Specifies the frame rate for the panel.
 					60 = 60 frames per second (default)
+- qcom,on-cmds-dsi-state:		A string that Specifies the ctrl state for sending ON commands.
+					Supported modes are "DSI_LP_MODE" and "DSI_HS_MODE".
+- qcom,off-cmds-dsi-state:		A string that Specifies the ctrl state for sending ON commands.
+					Supported modes are "DSI_LP_MODE" and "DSI_HS_MODE".
 
 Note, if a given optional qcom,* binding is not present, then the driver will configure
 the default values specified.
 
 Example:
-	qcom,mdss_dsi@fd922800 {
-
-		qcom,mdss_dsi_sim_video {
-			compatible = "qcom,mdss-dsi-panel";
-			label = "simulator video mode dsi panel";
-			status = "disable";
-			qcom,mdss-pan-res = <640 480>;
-			qcom,mdss-pan-bpp = <24>;
-			qcom,mdss-pan-porch-values = <6 2 6 6 2 6>;
-			qcom,mdss-pan-underflow-clr = <0xff>;
-			qcom,mdss-pan-bl-levels = <1 15>;
-			qcom,mdss-pan-dsi-mode = <0>;
-			qcom,mdss-pan-dsi-h-pulse-mode = <1>;
-			qcom,mdss-pan-dsi-h-power-stop = <1 1 1>;
-			qcom,mdss-pan-dsi-bllp-power-stop = <1 1>;
-			qcom,mdss-pan-dsi-traffic-mode = <0>;
-			qcom,mdss-pan-dsi-dst-format = <3>;
-			qcom,mdss-pan-dsi-vc = <0>;
-			qcom,mdss-pan-dsi-rgb-swap = <0>;
-			qcom,mdss-pan-dsi-data-lanes = <1 1 0 0>;
-			qcom,mdss-pan-dsi-t-clk = <0x24 0x03>;
-			qcom,mdss-pan-dsi-stream = <0>;
-			qcom,mdss-pan-dsi-mdp-tr = <0x04>;
-			qcom,mdss-pan-dsi-dma-tr = <0x04>;
-			qcom,mdss-pan-frame-rate = <60>;
-			qcom,panel-on-cmds = [32 01 00 00 00 02 00 00];
-			qcom,panel-off-cmds = [22 01 00 00 00 00 00];
-		};
-
+/ {
+	qcom,mdss_dsi_sim_video {
+		compatible = "qcom,mdss-dsi-panel";
+		label = "simulator video mode dsi panel";
+		status = "disable";
+		qcom,dsi-ctrl-phandle = <&mdss_dsi0>;
+		qcom,mdss-pan-res = <640 480>;
+		qcom,mdss-pan-bpp = <24>;
+		qcom,mdss-pan-dest = "display_1";
+		qcom,mdss-pan-porch-values = <6 2 6 6 2 6>;
+		qcom,mdss-pan-underflow-clr = <0xff>;
+		qcom,mdss-pan-bl-levels = <1 15>;
+		qcom,mdss-pan-dsi-mode = <0>;
+		qcom,mdss-pan-dsi-h-pulse-mode = <1>;
+		qcom,mdss-pan-dsi-h-power-stop = <1 1 1>;
+		qcom,mdss-pan-dsi-bllp-power-stop = <1 1>;
+		qcom,mdss-pan-dsi-traffic-mode = <0>;
+		qcom,mdss-pan-dsi-dst-format = <3>;
+		qcom,mdss-pan-dsi-vc = <0>;
+		qcom,mdss-pan-dsi-rgb-swap = <0>;
+		qcom,mdss-pan-dsi-data-lanes = <1 1 0 0>;
+		qcom,mdss-pan-dsi-t-clk = <0x24 0x03>;
+		qcom,mdss-pan-dsi-stream = <0>;
+		qcom,mdss-pan-dsi-mdp-tr = <0x04>;
+		qcom,mdss-pan-dsi-dma-tr = <0x04>;
+		qcom,mdss-pan-frame-rate = <60>;
+		qcom,panel-on-cmds = [32 01 00 00 00 02 00 00];
+		qcom,on-cmds-dsi-state = "DSI_LP_MODE";
+		qcom,panel-off-cmds = [22 01 00 00 00 00 00];
+		qcom,off-cmds-dsi-state = "DSI LP MODE";
 	};
+};
diff --git a/Documentation/devicetree/bindings/fb/mdss-edp.txt b/Documentation/devicetree/bindings/fb/mdss-edp.txt
index 3c4e1d3..578b07c 100644
--- a/Documentation/devicetree/bindings/fb/mdss-edp.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-edp.txt
@@ -12,12 +12,14 @@
 - vdda-supply :				Phandle for vdd regulator device node.
 - gpio-panel-en	:			GPIO for supplying power to panel and backlight
 							driver.
-- qcom,panel-lpg-channel :	LPG channel for backlight.
-- qcom,panel-pwm-period :	PWM period in microseconds.
-- status :					A string that has to be set to "okay/ok" to enable
-							the driver. By default this property will be set to
-							"disable". Will be set to "ok/okay" status for
-							specific platforms.
+- qcom,panel-lpg-channel :		LPG channel for backlight.
+- qcom,panel-pwm-period :		PWM period in microseconds.
+- status :				A string that has to be set to "okay/ok" to enable
+						the driver. By default this property will be set to
+						"disable". Will be set to "ok/okay" status for
+						specific platforms.
+- qcom,mdss-fb-map:			pHandle that specifies the framebuffer to which the
+					interface is mapped.
 
 Example:
 	mdss_edp: qcom,mdss_edp@fd923400 {
diff --git a/Documentation/devicetree/bindings/fb/mdss-mdp.txt b/Documentation/devicetree/bindings/fb/mdss-mdp.txt
index 478e335..0f31a38 100644
--- a/Documentation/devicetree/bindings/fb/mdss-mdp.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-mdp.txt
@@ -10,6 +10,97 @@
 - reg-names :		names to refer to register sets related to this device
 - interrupts :		Interrupt associated with MDSS.
 - vdd-supply :		Phandle for vdd regulator device node.
+- qcom,mdss-pipe-vig-off:	Array of offset for MDP source surface pipes of
+				type VIG, the offsets are calculated from
+				register "mdp_phys" defined in reg property.
+				The number of offsets defined here should
+				reflect the amount of VIG pipes that can be
+				active in MDP for this configuration.
+- qcom,mdss-pipe-vig-fetch-id:	Array of shared memory pool fetch ids
+				corresponding to the VIG pipe offsets defined in
+				previous property, the amount of fetch ids
+				defined should match the number of offsets
+				defined in property: qcom,mdss-pipe-vig-off
+- qcom,mdss-pipe-rgb-off:	Array of offsets for MDP source surface pipes of
+				type RGB, the offsets are calculated from
+				register "mdp_phys" defined in reg property.
+				The number of offsets defined here should
+				reflect the amount of RGB pipes that can be
+				active in MDP for this configuration.
+- qcom,mdss-pipe-rgb-fetch-id:	Array of shared memory pool fetch ids
+				corresponding to the RGB pipe offsets defined in
+				previous property, the amount of fetch ids
+				defined should match the number of offsets
+				defined in property: qcom,mdss-pipe-rgb-off
+- qcom,mdss-pipe-dma-off:	Array of offsets for MDP source surface pipes of
+				type DMA, the offsets are calculated from
+				register "mdp_phys" defined in reg property.
+				The number of offsets defined here should
+				reflect the amount of DMA pipes that can be
+				active in MDP for this configuration.
+- qcom,mdss-pipe-dma-fetch-id:	Array of shared memory pool fetch ids
+				corresponding to the DMA pipe offsets defined in
+				previous property, the amount of fetch ids
+				defined should match the number of offsets
+				defined in property: qcom,mdss-pipe-dma-off
+- qcom,mdss-ctl-off:		Array of offset addresses for the available ctl
+				hw blocks within MDP, these offsets are
+				calculated from register "mdp_phys" defined in
+				reg property.  The number of ctl offsets defined
+				here should reflect the number of control paths
+				that can be configured concurrently on MDP for
+				this configuration.
+- qcom,mdss-wb-off:		Array of offset addresses for the progammable
+				writeback blocks within MDP. The number of
+				offsets defined should match the number of ctl
+				blocks defined in property: qcom,mdss-ctl-off
+- qcom,mdss-mixer-intf-off: 	Array of offset addresses for the available
+				mixer blocks that can drive data to panel
+				interfaces.
+				These offsets are be calculated from register
+				"mdp_phys" defined in reg property.
+				The number of offsets defined should reflect the
+				amount of mixers that can drive data to a panel
+				interface.
+- qcom,mdss-dspp-off: 		Array of offset addresses for the available dspp
+				blocks. These offsets are calculated from
+				regsiter "mdp_phys" defined in reg property.
+				The number of dspp blocks should match the
+				number of mixers driving data to interface
+				defined in property: qcom,mdss-mixer-intf-off
+- qcom,mdss-mixer-wb-off: 	Array of offset addresses for the available
+				mixer blocks that can be drive data to writeback
+				block.  These offsets will be calculated from
+				register "mdp_phys" defined in reg property.
+				The number of writeback mixer offsets defined
+				should reflect the number of mixers that can
+				drive data to a writeback block.
+- qcom,mdss-intf-off:		Array of offset addresses for the available MDP
+				video interface blocks that can drive data to a
+				panel controller through timing engine.
+				The offsets are calculated from "mdp_phys"
+				defined in reg property. The number of offsets
+				defiend should reflect the number of progammable
+				interface blocks avaialble in hardware.
+
+Optional properties:
+- qcom,vbif-settings :	Array with key-value pairs of constant VBIF register
+			settings used to setup MDSS QoS for optimum performance.
+			The key used should be offset from "vbif_phys" register
+			defined in reg property.
+- qcom,mdp-settings :	Array with key-value pairs of constant MDP register
+			settings used to setup MDSS QoS for best performance.
+			The key used should be offset from "mdp_phys" register
+			defined in reg property.
+
+Optional subnodes:
+Child nodes representing the frame buffer virtual devices.
+
+Subnode properties:
+- compatible :		Must be "qcom,mdss-fb"
+- cell-index :		Index representing frame buffer
+
+
 
 Example:
 	qcom,mdss_mdp@fd900000 {
@@ -19,5 +110,34 @@
 		reg-names = "mdp_phys", "vbif_phys";
 		interrupts = <0 72 0>;
 		vdd-supply = <&gdsc_mdss>;
+
+		qcom,vbif-settings = <0x0004 0x00000001>,
+				     <0x00D8 0x00000707>;
+		qcom,mdp-settings = <0x02E0 0x000000AA>,
+				    <0x02E4 0x00000055>;
+		qcom,mdss-pipe-vig-off = <0x00001200 0x00001600
+					  0x00001A00>;
+		qcom,mdss-pipe-rgb-off = <0x00001E00 0x00002200
+					  0x00002600>;
+		qcom,mdss-pipe-dma-off = <0x00002A00 0x00002E00>;
+		qcom,mdss-pipe-vig-fetch-id = <1 4 7>;
+		qcom,mdss-pipe-rgb-fetch-id = <16 17 18>;
+		qcom,mdss-pipe-dma-fetch-id = <10 13>;
+
+		qcom,mdss-ctl-off = <0x00000600 0x00000700 0x00000800
+				     0x00000900 0x0000A00>;
+		qcom,mdss-mixer-intf-off = <0x00003200 0x00003600
+					    0x00003A00>;
+		qcom,mdss-mixer-wb-off = <0x00003E00 0x00004200>;
+		qcom,mdss-dspp-off = <0x00004600 0x00004A00 0x00004E00>;
+		qcom,mdss-wb-off = <0x00011100 0x00013100 0x00015100
+				    0x00017100 0x00019100>;
+		qcom,mdss-intf-off = <0x00021100 0x00021300
+					   0x00021500 0x00021700>;
+
+		mdss_fb0: qcom,mdss_fb_primary {
+			cell-index = <0>;
+			compatible = "qcom,mdss-fb";
+		};
 	};
 
diff --git a/Documentation/devicetree/bindings/fb/msm-hdmi-tx.txt b/Documentation/devicetree/bindings/fb/msm-hdmi-tx.txt
index a30d1d6..a2b66f7 100644
--- a/Documentation/devicetree/bindings/fb/msm-hdmi-tx.txt
+++ b/Documentation/devicetree/bindings/fb/msm-hdmi-tx.txt
@@ -43,7 +43,7 @@
 - compatible : "msm-hdmi-audio-codec-rx";
 
 Example:
-	qcom,hdmi_tx@fd922100 {
+	mdss_hdmi_tx: qcom,hdmi_tx@fd922100 {
 		cell-index = <0>;
 		compatible = "qcom,hdmi-tx";
 		reg =	<0xfd922100 0x35C>,
diff --git a/Documentation/devicetree/bindings/gpio/gpio-msm.txt b/Documentation/devicetree/bindings/gpio/gpio-msm.txt
index a5d50fd..1f88037 100644
--- a/Documentation/devicetree/bindings/gpio/gpio-msm.txt
+++ b/Documentation/devicetree/bindings/gpio/gpio-msm.txt
@@ -10,6 +10,9 @@
 - #interrupt-cells : Should be 2.
 - interrupt-controller: Mark the device node as an interrupt controller
 - interrupts : Specify the TLMM summary interrupt number
+- ngpio : Specify the number of MSM GPIOs
+- qcom,direct-connect-irqs : Specifies the number of GPIOs that can be used as
+  direct connect interrupts
 
 Example:
 
@@ -21,6 +24,8 @@
 		#interrupt-cells = <2>;
 		reg = <0xfd510000 0x4000>;
 		interrupts = <0 208 0>;
+		ngpio = <150>;
+		qcom,direct-connect-irqs = <8>;
 	};
 
 To specify gpios for a device:
diff --git a/Documentation/devicetree/bindings/gpio/gpio-smp2p.txt b/Documentation/devicetree/bindings/gpio/gpio-smp2p.txt
new file mode 100644
index 0000000..131c9d1
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-smp2p.txt
@@ -0,0 +1,77 @@
+Qualcomm SMSM Point-to-Point (SMP2P) GPIO Driver
+
+Used to map an SMP2P entry and remote processor ID to a virtual GPIO controller
+and virtual interrupt controller.
+
+Required properties:
+-compatible : should be "qcom,smp2pgpio";
+-qcom,entry-name : name of the SMP2P entry
+-qcom,remote-pid : the SMP2P remote processor ID (see smp2p_private_api.h)
+-gpio-controller : specifies that this is a GPIO controller
+-#gpio-cells : number of GPIO cells (should always be <2>)
+-interrupt-controller : specifies that this is an interrupt controller
+-#interrupt-cells : number of interrupt cells (should always be <2>)
+
+Optional properties:
+-qcom,is-inbound : specifies that this is an inbound entry (default is outbound)
+
+Comments:
+All device tree entries must be unique.  Therefore to prevent naming collisions
+between clients, it is recommended that the DT nodes should be named using the
+format:
+	smp2pgpio_<ENTRY_NAME>_<REMOTE PID>_<in|out>
+
+Example:
+	/* Maps inbound "smp2p" entry on remote PID 7 to GPIO controller. */
+	smp2pgpio_smp2p_7_in: qcom,smp2pgpio-smp2p-7-in {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <7>;
+		qcom,is-inbound;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	/*
+	 * Maps inbound "smp2p" entry on remote PID 7 to client driver
+	 * "qcom,smp2pgpio_test_smp2p_7_in".
+	 *
+	 * Note:  If all 32-pins are used by this client, then you
+	 *        can just list pin 0 here as a shortcut.
+	 */
+	qcom,smp2pgpio_test_smp2p_7_in {
+		compatible = "qcom,smp2pgpio_test_smp2p_7_in";
+		gpios = <&smp2pgpio_smp2p_7_in 0 0>, /* pin 0 */
+			<&smp2pgpio_smp2p_7_in 1 0>,
+			. . .
+			<&smp2pgpio_smp2p_7_in 31 0>;    /* pin 31 */
+	};
+
+
+	/* Maps outbound "smp2p" entry on remote PID 7 to GPIO controller. */
+	smp2pgpio_smp2p_7_out: qcom,smp2pgpio-smp2p-7-out {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <7>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	/*
+	 * Maps outbound "smp2p" entry on remote PID 7 to client driver
+	 * "qcom,smp2pgpio_test_smp2p_7_out".
+	 *
+	 * Note:  If all 32-pins are used by this client, then you
+	 *        can just list pin 0 here as a shortcut.
+	 */
+	qcom,smp2pgpio_test_smp2p_7_out {
+		compatible = "qcom,smp2pgpio_test_smp2p_7_out";
+		gpios = <&smp2pgpio_smp2p_7_out 0 0>, /* pin 0 */
+			<&smp2pgpio_smp2p_7_out 1 0>,
+			. . .
+			<&smp2pgpio_smp2p_7_out 31 0>;    /* pin 31 */
+	};
diff --git a/Documentation/devicetree/bindings/gpu/adreno.txt b/Documentation/devicetree/bindings/gpu/adreno.txt
index 2ea9ba9..0004302 100644
--- a/Documentation/devicetree/bindings/gpu/adreno.txt
+++ b/Documentation/devicetree/bindings/gpu/adreno.txt
@@ -24,7 +24,11 @@
 				KGSL_CLK_AXI    0x00000020
 
 Bus Scaling Data:
-- qcom,grp3d-vectors:	A series of 4 cell properties, format of which is:
+- qcom,msm-bus,name: String property to describe the name of the 3D graphics processor.
+- qcom,msm-bus,num-cases: This is the the number of Bus Scaling use cases defined in the vectors property.
+- qcom,msm-bus,active-only: A boolean flag indicating if it is active only.
+- qcom,msm-bus,num-paths: This represents the number of paths in each Bus Scaling Usecase.
+- qcom,msm-bus,vectors-KBps: A series of 4 cell properties, format of which is:
 						<src dst ab ib>, <src dst ab ib>, // For Bus Scaling Usecase 1
 						<src dst ab ib>, <src dst ab ib>, // For Bus Scaling Usecase 2
 						<..  ..  .. ..>, <..  ..  .. ..>; // For Bus Scaling Usecase n
@@ -41,8 +45,6 @@
 						1 = MSM_BUS_SLAVE_OCMEM
 					ab: Represents aggregated bandwidth. This value is 0 for Graphics.
 					ib: Represents instantaneous bandwidth. This value has a range <0 8000 MB/s>
-- qcom,grp3d-num-vectors-per-usecase:	This represents the number of vectors in each Bus Scaling Usecase.
-- qcom,grp3d-num-bus-scale-usecases:	This is the the number of Bus Scaling use cases defined in the vectors property
 
 GDSC Oxili Regulators:
 - vddcx-supply:			Phandle for vddcx regulator device node.
@@ -62,6 +64,7 @@
 Optional Properties:
 - qcom,initial-powerlevel: This value indicates which qcom,gpu-pwrlevel should be used at start time
 			   and when coming back out of resume
+- qcom,step-pwrlevel:	   How many qcom,gpu-pwrlevel should be decremented at once
 - qcom,idle-timeout:	   This property represents the time in microseconds for idle timeout.
 - qcom,nap-allowed:	   Boolean. <0> or <1> to disable/enable nap.
 - qcom,chipid:		   If it exists this property is used to replace
@@ -92,12 +95,17 @@
 		qcom,clk-map = <0x00000016>; //KGSL_CLK_CORE | KGSL_CLK_IFACE | KGSL_CLK_MEM_IFACE
 
 		/* Bus Scale Settings */
-		qcom,grp3d-vectors = <0 0 0 0>, <2 1 0 0>,
-				<0 0 0 2000>, <2 1 0 3000>,
-				<0 0 0 4000>, <2 1 0 5000>,
-				<0 0 0 6400>, <2 1 0 7600>;
-		qcom,grp3d-num-vectors-per-usecase = <2>;
-		qcom,grp3d-num-bus-scale-usecases = <4>;
+		qcom,msm-bus,name = "grp3d";
+		qcom,msm-bus,num-cases = <6>;
+		qcom,msm-bus,active-only = <0>;
+		qcom,msm-bus,num-paths = <2>;
+		qcom,msm-bus,vectors-KBps =
+				<26 512 0 0>, <89 604 0 0>,
+				<26 512 0 2200000>, <89 604 0 3000000>,
+				<26 512 0 4000000>, <89 604 0 3000000>,
+				<26 512 0 4000000>, <89 604 0 4500000>,
+				<26 512 0 6400000>, <89 604 0 4500000>,
+				<26 512 0 6400000>, <89 604 0 7600000>;
 
 		/* GDSC oxili regulators */
 		vddcx-supply = <&gdsc_oxili_cx>;
diff --git a/Documentation/devicetree/bindings/i2c/sii8334-i2c.txt b/Documentation/devicetree/bindings/i2c/sii8334-i2c.txt
index ed45192..27a2149 100644
--- a/Documentation/devicetree/bindings/i2c/sii8334-i2c.txt
+++ b/Documentation/devicetree/bindings/i2c/sii8334-i2c.txt
@@ -7,6 +7,7 @@
 - mhl-pwr-gpio: MHL power gpio required for power rails
 - mhl-rst-gpio: MHL reset gpio going into sii8334 for toggling reset pin
 - <supply-name>-supply: phandle to the regulator device tree node.
+- qcom,hdmi-tx-map: phandle to the hdmi tx device tree node.
 
 Example:
 	i2c@f9967000 {
@@ -22,5 +23,6 @@
 			avcc_12-supply = <&pm8941_l2>;
 			smps3a-supply = <&pm8941_s3>;
 			vdda-supply = <&pm8941_l12>;
+			qcom,hdmi-tx-map = <&mdss_hdmi_tx>;
 		};
 	};
diff --git a/Documentation/devicetree/bindings/input/gen_vkeys.txt b/Documentation/devicetree/bindings/input/gen_vkeys.txt
new file mode 100644
index 0000000..da99e19
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/gen_vkeys.txt
@@ -0,0 +1,24 @@
+Touchscreen Virtual Keys Device
+
+Generate virtual keys sysfs entry for Android
+
+Required properties:
+
+ - compatible	: should be "qcom,gen-vkeys"
+ - label		: name of the touch controller
+ - qcom,disp-maxx	: Maximum x-coordinate of display
+ - qcom,disp-maxy	: Maximum y-coordinate of display
+ - qcom,panel-maxx	: Maximum x-coordinate of touch panel
+ - qcom,panel-maxy	: Maximum y-coordinate of touch panel
+ - qcom,key-codes	: Array of key codes for virtual keys
+
+Example:
+	gen-vkeys {
+		compatible = "qcom,gen-vkeys";
+		label = "atmel_mxt_ts";
+		qcom,disp-maxx = <720>;
+		qcom,disp-maxy = <1280>;
+		qcom,panel-maxx = <760>;
+		qcom,panel-maxy = <1424>;
+		qcom,key-codes = <158 139 102 217>;
+	};
diff --git a/Documentation/devicetree/bindings/input/qpnp-keypad.txt b/Documentation/devicetree/bindings/input/qpnp-keypad.txt
new file mode 100644
index 0000000..8f7fbe7
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/qpnp-keypad.txt
@@ -0,0 +1,57 @@
+Qualcomm QPNP keypad controller
+
+The qpnp-keypad driver supports the PMIC keypad controller module
+in the Qualcomm PMICs. This controller supports 10 x 8 (row x col)
+configuration and is connected to the host processor on the
+SPMI interface.
+
+Required properties:
+- compatible:		Must be "qcom,qpnp-keypad"
+- reg:			Specifies the SPMI address and size for the keypad controller
+- interrupts:		Specifies the interrupt associated with keypad controller
+- interrupt-names: 	The names of the 2 interrupts assocaited with the keypad
+			controller. They are - "kp-sense" and "kp-stuck".
+- keypad,num-rows:	Number of rows used in the keypad configuration. These
+			rows are the number of PMIC gpios configured as drive
+			lines. Possible values: Max = 10, Min = 2.
+- keypad,num-columns:	Number of columns used in the keypad configuration. These
+			cols are number of PMIC gpios configured as sense lines.
+			Possible values: Max = 8, Min = 1.
+- linux,keymap:		Row-column-keycode mapping. It is an array of packed
+			entries containing the equivalent of row, column and
+			linux key-code. Each value represented as
+			(row << 24 | column << 16 | key-code)
+
+Optional Properties:
+- qcom,scan-delay-ms:	Wait time in milliseconds before each keypad scan.
+			This is used to determine if the key has been stuck.
+			Possible values: 1, 2, 4, 8, 16, 32, 64, 128ms.
+- qcom,row-hold-ns:	Wait time in nanoseconds between each row assertion.
+			Configured based on last-row scan delay.
+			Possible values: 31250, 62500, 125000, 250000ns.
+- qcom,debounce-ms:	Wait time in milliseconds before the column data is
+			sampled for key	press detection.
+			Possible values: 5, 10, 15, 20ms.
+- qcom,wakeup:		Configure the keypad as a wakeup source. This is a
+			boolean property.
+- linux,keypad-no-autorepeat:
+			Disables the auto-repeat feature for the keys. This
+			is a boolean property.
+
+Example:
+
+	qcom,keypad@a800 {
+		compatible = "qcom,qpnp-keypad";
+		reg = <0xA800 0x100>;
+		interrupts = <0x1 0xA8 0x0>,
+			     <0x1 0xA8 0x1>;
+		interrupt-names = "kp-sense", "kp-stuck";
+		keypad,num-rows = <2>;
+		keypad,num-cols = <2>;
+		qcom,scan-delay-ms = <128>;
+		qcom,row-hold-ns = <31250>;
+		qcom,debounce-ms = <20>;
+		qcom,wakeup;
+		linux,keymap = <0x00000001 0x00010002
+			       0x01000003 0x01010004>;
+	}
diff --git a/Documentation/devicetree/bindings/input/touchscreen/atmel-mxt-ts.txt b/Documentation/devicetree/bindings/input/touchscreen/atmel-mxt-ts.txt
index bcea355..6fe88a9 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/atmel-mxt-ts.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/atmel-mxt-ts.txt
@@ -17,11 +17,15 @@
  - atmel,family-id	: family identification of the controller
  - atmel,variant-id	: variant identification of the controller
  - atmel,version	: firmware version of the controller
- - atmel,build	i	: firmware build number of the controller
- - atmel,bootldr-id	: bootloader identification of the controller
- - atmel,fw-name	: firmware name to used for flashing firmware
+ - atmel,build		: firmware build number of the controller
+
+Required for firmware update only:
+ - atmel,fw-name		: firmware name to use for flashing firmware
+ - atmel,bootldr-id		: bootloader identification of the controller
 
 Optional property:
+ - atmel,bl-addr		: bootloader address, by default is looked up
+					in mxt_slave_addresses structure
  - atmel,config			: configuration parameter for the controller
  - atmel,i2c-pull-up		: specify to indicate pull up is needed
  - vcc_i2c-supply		: Power source required to pull up i2c bus
diff --git a/Documentation/devicetree/bindings/iommu/msm_iommu.txt b/Documentation/devicetree/bindings/iommu/msm_iommu.txt
deleted file mode 100644
index 7872280..0000000
--- a/Documentation/devicetree/bindings/iommu/msm_iommu.txt
+++ /dev/null
@@ -1,59 +0,0 @@
-* Qualcomm MSM IOMMU
-
-Required properties:
-- compatible : one of:
-	- "qcom,msm-smmu-v2"
-- reg : offset and length of the register set for the device.
-
-Optional properties:
-- qcom,iommu-secure-id : Secure identifier for the IOMMU block
-
-- List of sub nodes, one for each of the translation context banks supported.
-  Each sub node has the following required properties:
-
-  - reg : offset and length of the register set for the context bank.
-  - interrupts : should contain the context bank interrupt.
-  - qcom,iommu-ctx-sids : List of stream identifiers associated with this
-    translation context.
-  - label : Name of the context bank
-  - vdd-supply : vdd-supply: phandle to GDSC regulator controlling this IOMMU.
-
-Optional properties:
-- qcom,needs-alt-core-clk : boolean to enable the secondary core clock for
-  access to the IOMMU configuration registers
-- qcom,iommu-bfb-regs : An array of unsigned 32-bit integers corresponding to
-  BFB register addresses that need to be configured for performance tuning
-  purposes. If this property is present, the qcom,iommu-bfb-data must also be
-  present. Register addresses are specified as an offset from the base of the
-  IOMMU hardware block. This property may be omitted if no BFB register
-  configuration needs to be done for a particular IOMMU hardware instance. The
-  registers specified by this property shall fall within the IOMMU
-  implementation-defined register region.
-- qcom,iommu-bfb-data : An array of unsigned 32-bit integers representing the
-  values to be programmed into the corresponding registers given by the
-  qcom,iommu-bfb-regs property. If this property is present, the
-  qcom,iommu-bfb-regs property shall also be present, and the lengths of both
-  properties shall be the same.
-
-Example:
-
-        qcom,iommu@fda64000 {
-                compatible = "qcom,msm-smmu-v2";
-                reg = <0xfda64000 0x10000>;
-		vdd-supply = <&gdsc_iommu>;
-		qcom,iommu-bfb-regs = <0x204c 0x2050>;
-		qcom,iommu-bfb-data = <0xffff 0xffce>;
-
-                qcom,iommu-ctx@fda6c000 {
-                        reg = <0xfda6c000 0x1000>;
-                        interrupts = <0 70 0>;
-                        qcom,iommu-ctx-sids = <0 2>;
-			label = "ctx_0";
-                };
-                qcom,iommu-ctx@fda6d000 {
-                        reg = <0xfda6d000 0x1000>;
-                        interrupts = <0 71 0>;
-                        qcom,iommu-ctx-sids = <1>;
-			label = "ctx_1";
-                };
-        };
diff --git a/Documentation/devicetree/bindings/iommu/msm_iommu_v0.txt b/Documentation/devicetree/bindings/iommu/msm_iommu_v0.txt
new file mode 100644
index 0000000..cc1ffc2
--- /dev/null
+++ b/Documentation/devicetree/bindings/iommu/msm_iommu_v0.txt
@@ -0,0 +1,46 @@
+* Qualcomm MSM IOMMU v0
+
+Required properties:
+- compatible : one of:
+	- "qcom,msm-smmu-v0"
+- reg : offset and length of the register set for the device.
+- qcom,glb-offset : Offset for the global register base.
+
+Optional properties:
+- interrupts : should contain the performance monitor overflow interrupt number.
+- qcom,iommu-pmu-ngroups: Number of Performance Monitor Unit (PMU) groups.
+- qcom,iommu-pmu-ncounters: Number of PMU counters per group.
+- qcom,iommu-pmu-event-classes: List of event classes supported.
+- List of sub nodes, one for each of the translation context banks supported.
+  Each sub node has the following required properties:
+
+  - reg : offset and length of the register set for the context bank.
+  - interrupts : should contain the context bank interrupt.
+  - qcom,iommu-ctx-mids : List of machine identifiers associated with this
+    translation context.
+  - label : Name of the context bank
+
+Optional properties:
+  - none
+
+Example:
+
+	qcom,iommu@fd000000 {
+		compatible = "qcom,msm-smmu-v0";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		reg = <0xfd890000 0x10000>;
+		qcom,glb-offset = <0xF000>;
+		interrupts = <0 38 0>;
+		qcom,iommu-pmu-ngroups = <1>;
+		qcom,iommu-pmu-ncounters = <4>;
+		qcom,iommu-pmu-event-classes = <0x08
+						0x11>;
+
+		qcom,iommu-ctx@fd000000 {
+			reg = <0xfd000000 0x1000>;
+			interrupts = <0 250 0>;
+			qcom,iommu-ctx-mids = <0 3>;
+			label = "a_label";
+		};
diff --git a/Documentation/devicetree/bindings/iommu/msm_iommu_v1.txt b/Documentation/devicetree/bindings/iommu/msm_iommu_v1.txt
index d8e7791..2c47f74 100644
--- a/Documentation/devicetree/bindings/iommu/msm_iommu_v1.txt
+++ b/Documentation/devicetree/bindings/iommu/msm_iommu_v1.txt
@@ -3,35 +3,77 @@
 Required properties:
 - compatible : one of:
 	- "qcom,msm-smmu-v1"
-- reg : offset and length of the register set for the device.
-- qcom,glb-offset : Offset for the global register base.
+- reg : offset and length of the register set for the device. Optional
+	offset and length for clock register for additional clock that
+	needs to be turned on for access to this IOMMU.
+- reg-names: "iommu_base", "clk_base" (optional)
+- label: name of this IOMMU instance.
 
 Optional properties:
+- qcom,iommu-secure-id : Secure identifier for the IOMMU block
+- qcom,secure-context : boolean indicating that a context is secure and
+  programmed by the secure environment.
+- qcom,alt-vdd-supply : Alternative regulator needed to access IOMMU
+  configuration registers.
+- interrupts : should contain the performance monitor overflow interrupt number.
+- qcom,iommu-enable-halt : Enable halt of the IOMMU before programming certain	19
+  registers
+- qcom,iommu-pmu-ngroups: Number of Performance Monitor Unit (PMU) groups.
+- qcom,iommu-pmu-ncounters: Number of PMU counters per group.
+- qcom,iommu-pmu-event-classes: List of event classes supported.
+
 - List of sub nodes, one for each of the translation context banks supported.
   Each sub node has the following required properties:
 
   - reg : offset and length of the register set for the context bank.
   - interrupts : should contain the context bank interrupt.
-  - qcom,iommu-ctx-mids : List of machine identifiers associated with this
+  - qcom,iommu-ctx-sids : List of stream identifiers associated with this
     translation context.
   - label : Name of the context bank
+  - vdd-supply : vdd-supply: phandle to GDSC regulator controlling this IOMMU.
 
 Optional properties:
-  - none
+- qcom,needs-alt-core-clk : boolean to enable the secondary core clock for
+  access to the IOMMU configuration registers
+- qcom,iommu-bfb-regs : An array of unsigned 32-bit integers corresponding to
+  BFB register addresses that need to be configured for performance tuning
+  purposes. If this property is present, the qcom,iommu-bfb-data must also be
+  present. Register addresses are specified as an offset from the base of the
+  IOMMU hardware block. This property may be omitted if no BFB register
+  configuration needs to be done for a particular IOMMU hardware instance. The
+  registers specified by this property shall fall within the IOMMU
+  implementation-defined register region.
+- qcom,iommu-bfb-data : An array of unsigned 32-bit integers representing the
+  values to be programmed into the corresponding registers given by the
+  qcom,iommu-bfb-regs property. If this property is present, the
+  qcom,iommu-bfb-regs property shall also be present, and the lengths of both
+  properties shall be the same.
 
 Example:
 
-	qcom,iommu@fd000000 {
+	qcom,iommu@fda64000 {
 		compatible = "qcom,msm-smmu-v1";
-		#address-cells = <1>;
-		#size-cells = <1>;
-		ranges;
-		reg = <0xfd890000 0x10000>;
-		qcom,glb-offset = <0xF000>;
+		reg = <0xfda64000 0x10000>;
+		reg-names = "iommu_base";
+		vdd-supply = <&gdsc_iommu>;
+		qcom,iommu-bfb-regs = <0x204c 0x2050>;
+		qcom,iommu-bfb-data = <0xffff 0xffce>;
+		label = "iommu_0";
+		qcom,iommu-pmu-ngroups = <1>;
+		qcom,iommu-pmu-ncounters = <8>;
+		qcom,iommu-pmu-event-classes = <0x00,
+						0x01>;
 
-		qcom,iommu-ctx@fd000000 {
-			reg = <0xfd000000 0x1000>;
-			interrupts = <0 250 0>;
-			qcom,iommu-ctx-mids = <0 3>;
-			label = "a_label";
+		qcom,iommu-ctx@fda6c000 {
+			reg = <0xfda6c000 0x1000>;
+			interrupts = <0 70 0>;
+			qcom,iommu-ctx-sids = <0 2>;
+			label = "ctx_0";
 		};
+		qcom,iommu-ctx@fda6d000 {
+			reg = <0xfda6d000 0x1000>;
+			interrupts = <0 71 0>;
+			qcom,iommu-ctx-sids = <1>;
+			label = "ctx_1";
+		};
+	};
diff --git a/Documentation/devicetree/bindings/leds/leds-qpnp.txt b/Documentation/devicetree/bindings/leds/leds-qpnp.txt
index da0708f..b9bac1d 100644
--- a/Documentation/devicetree/bindings/leds/leds-qpnp.txt
+++ b/Documentation/devicetree/bindings/leds/leds-qpnp.txt
@@ -61,6 +61,7 @@
 Optional properties for RGB led:
 - linux,default-trigger: trigger the led from external modules such as display
 - qcom,default-state:  default state of the led, should be "on" or "off"
+- qcom,turn-off-delay-ms: delay in millisecond for turning off the led when its default-state is "on". Value is being ignored in case default-state is "off".
 
 Example:
 
@@ -96,7 +97,8 @@
 			qcom,duty-pcts = [00 19 32 4B 64
 					 64 4B 32 19 00];
 			qcom,max-current = <12>;
-			qcom,default-state = "off";
+			qcom,default-state = "on";
+			qcom,turn-off-delay-ms = <500>;
 			qcom,id = <5>;
 			linux,default-trigger = "none";
 		};
diff --git a/Documentation/devicetree/bindings/media/video/msm-cam-server.txt b/Documentation/devicetree/bindings/media/video/msm-cam-server.txt
deleted file mode 100644
index 2b6f513..0000000
--- a/Documentation/devicetree/bindings/media/video/msm-cam-server.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-* Qualcomm MSM Camera Server
-
-Required properties:
-- compatible :
-    - "qcom,cam_server"
-
-Example:
-
-   qcom,cam_server {
-       compatible = "qcom,cam_server";
-   };
diff --git a/Documentation/devicetree/bindings/media/video/msm-cam.txt b/Documentation/devicetree/bindings/media/video/msm-cam.txt
new file mode 100644
index 0000000..b5b6cf6
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/video/msm-cam.txt
@@ -0,0 +1,15 @@
+* Qualcomm MSM Camera
+
+Required properties:
+- compatible :
+    - "qcom,msm-cam"
+- reg : offset and length of msm camera device registers.
+- reg-names : should specify relevant names for each reg property defined.
+
+Example:
+
+   qcom,msm-cam@fd8c0000 {
+       compatible = "qcom,msm-cam";
+       reg = <0xfd8C0000 0x10000>;
+       reg-names = "msm-cam";
+   };
diff --git a/Documentation/devicetree/bindings/media/video/msm-cci.txt b/Documentation/devicetree/bindings/media/video/msm-cci.txt
index e256265..a432fb5 100644
--- a/Documentation/devicetree/bindings/media/video/msm-cci.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-cci.txt
@@ -11,6 +11,25 @@
 - interrupts : should contain the cci interrupt.
 - interrupt-names : should specify relevant names to each interrupts
   property defined.
+- gpios : should contain phandle to gpio controller node and array of
+    #gpio-cells specifying specific gpio (controller specific)
+- qcom,gpio-req-tbl-num : should contain index to gpios specific to this sensor
+- qcom,gpio-req-tbl-flags : should contain direction of gpios present in
+    qcom,gpio-req-tbl-num property (in the same order)
+- qcom,gpio-req-tbl-label : should contain name of gpios present in
+    qcom,gpio-req-tbl-num property (in the same order)
+- qcom,hw-thigh : should contain high period of the SCL clock in terms of CCI
+    clock cycle
+- qcom,hw-tlow : should contain high period of the SCL clock in terms of CCI
+    clock cycle
+- qcom,hw-tsu-sto : should contain setup time for STOP condition
+- qcom,hw-tsu-sta : should contain setup time for Repeated START condition
+- qcom,hw-thd-dat : should contain hold time for the data
+- qcom,hw-thd-sta : should contain hold time for START condition
+- qcom,hw-tbuf : should contain free time between a STOP and a START condition
+- qcom,hw-scl-stretch-en : should contain enable or disable clock stretching
+- qcom,hw-trdhld : should contain internal hold time for SDA
+- qcom,hw-tsp : should contain filtering of glitches
 
 [Second level nodes]
 * Qualcomm MSM Sensor
@@ -22,16 +41,14 @@
     - "qcom,s5k3l1yx"
 - reg : should contain i2c slave address of the camera sensor and
     length of data field which is 0x0
-- qcom,csi-if : should contain number of csid cores required at the receiver
-    side
-    - 1 for 2D sensor
-    - 2 for 3D sensor
-- qcom,csid-core : should contain csid core instance that will used to receive
-    sensor data
+- qcom,slave-id : should contain i2c slave address, device id address
+    and expected id read value
+- qcom,csiphy-sd-index : should contain csiphy instance that will used to
+    receive sensor data
+    - 0, 1, 2
+- qcom,csid-sd-index : should contain csid core instance that will used to
+    receive sensor data
     - 0, 1, 2, 3
-- qcom,is-vpe : should be enabled if VPE module is required for post processing
-    of this sensor
-    - 1 if required, 0 otherwise
 - qcom,sensor-name : should contain unique sensor name to differentiate from
     other sensor
     - "s5k3l1yx"
@@ -52,7 +69,7 @@
     regulators mentioned in qcom,cam-vreg-name property (in the same order)
 - qcom,cam-vreg-op-mode : should contain optimum voltage level for regulators
     mentioned in qcom,cam-vreg-name property (in the same order)
-- qcom,camera-type : should contain sensor type
+- qcom,sensor-mode : should contain sensor mode supported
     - 0 -> back camera 2D
     - 1 -> front camera 2D
     - 2 -> back camera 3D
@@ -62,9 +79,9 @@
     - 1 -> yuv format
 
 Optional properties:
-- qcom,flash-src-index : should contain phandle to flash source node if flash
-    is supported for this sensor
-    - led_flash0, led_flash1
+- qcom,is-vpe : should be enabled if VPE module is required for post processing
+    of this sensor
+    - 1 if required, 0 otherwise
 - qcom,mount-angle : should contain the physical mount angle of the sensor on
     the target
     - 0, 90, 180, 360
@@ -74,12 +91,7 @@
 - cam_vaf-supply : should contain regulator from which AF voltage is supplied
 - gpios : should contain phandle to gpio controller node and array of
     #gpio-cells specifying specific gpio (controller specific)
-- qcom,gpio-common-tbl-num : should contain index to gpios shared between
-    different sensors
-- qcom,gpio-common-tbl-flags : should contain direction of gpios present in
-    qcom,gpio-common-tbl-num property (in the same order)
-- qcom,gpio-common-tbl-label : should contain name of gpios present in
-    qcom,gpio-common-tbl-num property (in the same order)
+- qcom,gpio-reset : should contain index to gpio used by sensors reset_n
 - qcom,gpio-req-tbl-num : should contain index to gpios specific to this sensor
 - qcom,gpio-req-tbl-flags : should contain direction of gpios present in
     qcom,gpio-req-tbl-num property (in the same order)
@@ -107,6 +119,30 @@
     for actuator
 - qcom,actuator-vcm-enable : should contain value to be set for actuator vcm
     gpio
+- qcom,sensor-position : should contain the mount angle of the camera sensor
+    - 0 -> back camera
+    - 1 -> front camera
+- qcom,cci-master : should contain i2c master id to be used for this camera
+    sensor
+    - 0 -> MASTER 0
+    - 1 -> MASTER 1
+- qcom,actuator-src : if auto focus is supported by this sensor, this
+   property should contain phandle of respective actuator node
+- qcom,led-flash-src : if LED flash is supported by this sensor, this
+   property should contain phandle of respective LED flash node
+* Qualcomm MSM ACTUATOR
+
+Required properties:
+- cell-index : should contain unique identifier to differentiate
+    between multiple actuators
+- reg : should contain i2c slave address of the actuator and length of
+    data field which is 0x0
+- compatible :
+    - "qcom,actuator"
+- qcom,cci-master : should contain i2c master id to be used for this camera
+    sensor
+    - 0 -> MASTER 0
+    - 1 -> MASTER 1
 
 Example:
 
@@ -117,13 +153,42 @@
        reg-names = "cci";
        interrupts = <0 50 0>;
        interrupt-names = "cci";
+       gpios = <&msmgpio 19 0>,
+               <&msmgpio 20 0>,
+               <&msmgpio 21 0>,
+               <&msmgpio 22 0>;
+       qcom,gpio-tbl-num = <0 1 2 3>;
+       qcom,gpio-tbl-flags = <1 1 1 1>;
+       qcom,gpio-tbl-label = "CCI_I2C_DATA0",
+                             "CCI_I2C_CLK0",
+                             "CCI_I2C_DATA1",
+                             "CCI_I2C_CLK1";
+       qcom,hw-thigh = <78>;
+       qcom,hw-tlow = <114>;
+       qcom,hw-tsu-sto = <28>;
+       qcom,hw-tsu-sta = <28>;
+       qcom,hw-thd-dat = <10>;
+       qcom,hw-thd-sta = <77>;
+       qcom,hw-tbuf = <118>;
+       qcom,hw-scl-stretch-en = <0>;
+       qcom,hw-trdhld = <6>;
+       qcom,hw-tsp = <1>;
+
+        actuator0: qcom,actuator@18 {
+                cell-index = <0>;
+                reg = <0x18 0x0>;
+                compatible = "qcom,actuator";
+                qcom,cci-master = <0>;
+        };
+
        qcom,s5k3l1yx@6e {
                compatible = "qcom,s5k3l1yx";
                reg = <0x6e 0x0>;
-               qcom,csi-if = <1>;
-               qcom,csid-core = <0>;
-               qcom,is-vpe = <1>;
-               qcom,flash-type = <0>;
+               qcom,slave-id = <0x6e 0x0 0x3121>;
+               qcom,csiphy-sd-index = <2>;
+               qcom,csid-sd-index = <0>;
+               qcom,actuator-src = <&actuator0>;
+               qcom,led-flash-src = <&led_flash0>;
                qcom,mount-angle = <90>;
                qcom,sensor-name = "s5k3l1yx";
                cam_vdig-supply = <&pm8941_l3>;
@@ -137,23 +202,18 @@
                qcom,cam-vreg-op-mode = <105000 80000 0 100000>;
                qcom,gpio-no-mux = <0>;
                gpios = <&msmgpio 15 0>,
-                       <&msmgpio 19 0>,
-                       <&msmgpio 20 0>,
-                       <&msmgpio 90 0>;
-               qcom,gpio-common-tbl-num = <0 1 2>;
-               qcom,gpio-common-tbl-flags = <1 1 1>;
-               qcom,gpio-common-tbl-label = "CAMIF_MCLK", "CAMIF_I2C_DATA",
-                                            "CAMIF_I2C_CLK";
-               qcom,gpio-req-tbl-num = <3>;
-               qcom,gpio-req-tbl-flags = <0>;
-               qcom,gpio-req-tbl-label = "CAM_RESET1";
-               qcom,gpio-set-tbl-num = <3 3>;
+               qcom,gpio-reset = <1>;
+               qcom,gpio-req-tbl-num = <0 1>;
+               qcom,gpio-req-tbl-flags = <1 0>;
+               qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+                                         "CAM_RESET1";
+               qcom,gpio-set-tbl-num = <1 1>;
                qcom,gpio-set-tbl-flags = <0 2>;
                qcom,gpio-set-tbl-delay = <1000 4000>;
                qcom,csi-lane-assign = <0x4320>;
                qcom,csi-lane-mask = <0x1F>;
                qcom,csi-phy-sel = <0>;
-               qcom,camera-type = <0>;
-               qcom,sensor-type = <0>;
+               qcom,sensor-position = <0>;
+               qcom,sensor-mode = <1>;
        };
    };
diff --git a/Documentation/devicetree/bindings/media/video/msm-cpp.txt b/Documentation/devicetree/bindings/media/video/msm-cpp.txt
index 5cf0154..9d176d8 100644
--- a/Documentation/devicetree/bindings/media/video/msm-cpp.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-cpp.txt
@@ -7,6 +7,8 @@
 - reg : offset and length of the register set for the device
     for the cpp operating in compatible mode.
 - reg-names : should specify relevant names to each reg property defined.
+  - cpp - has CPP hardware register set.
+  - cpp_vbif - has VBIF core register set used by CPP.
 - interrupts : should contain the cpp interrupt.
 - interrupt-names : should specify relevant names to each interrupts
   property defined.
@@ -18,7 +20,8 @@
        cell-index = <0>;
        compatible = "qcom,cpp";
        reg = <0xfda04000 0x100>;
-       reg-names = "cpp";
+             <0xfda40000 0x200>;
+       reg-names = "cpp", "cpp_vbif";
        interrupts = <0 49 0>;
        interrupt-names = "cpp";
        vdd-supply = <&gdsc_vfe>;
diff --git a/Documentation/devicetree/bindings/media/video/msm-vfe.txt b/Documentation/devicetree/bindings/media/video/msm-vfe.txt
index 7a70cac..f02f35e 100644
--- a/Documentation/devicetree/bindings/media/video/msm-vfe.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-vfe.txt
@@ -4,6 +4,7 @@
 - cell-index: vfe hardware core index
 - compatible :
     - "qcom,vfe"
+    - "qcom,vfe40"
 - reg : offset and length of the register set for the device
     for the vfe operating in compatible mode.
 - reg-names : should specify relevant names to each reg property defined.
diff --git a/Documentation/devicetree/bindings/media/video/msm-vidc.txt b/Documentation/devicetree/bindings/media/video/msm-vidc.txt
index 79a3ab5..f97e063 100644
--- a/Documentation/devicetree/bindings/media/video/msm-vidc.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-vidc.txt
@@ -3,16 +3,42 @@
 Required properties:
 - compatible : one of:
 	- "qcom,msm-vidc"
+- qcom,hfi : supported Host-Firmware Interface, one of:
+	- "venus"
+	- "q6"
+
+Optional properties:
 - reg : offset and length of the register set for the device.
 - interrupts : should contain the vidc interrupt.
-- vidc-cp-map : start and size of device virtual address range for secure buffers.
-  Video hardware uses this address range to identify if the buffers are secure
-  or non-secure.
-- vidc-ns-map : start and size of device virtual address range for non-secure buffers.
-  Video hardware uses this address range to identify if the buffers are secure
-  or non-secure.
-- load-freq-tbl : load (in macroblocks/sec) and corresponding vcodec clock
-  required for optimal performance in descending order.
+- qcom,vidc-cp-map : start and size of device virtual address range for
+  secure buffers. Video hardware uses this address range to identify if
+  the buffers are secure or non-secure.
+- qcom,vidc-ns-map : start and size of device virtual address range for
+  non-secure buffers. Video hardware uses this address range to identify
+  if the buffers are secure or non-secure.
+- qcom,load-freq-tbl : load (in macroblocks/sec) and corresponding vcodec
+  clock required for optimal performance in descending order.
+- qcom,reg-presets : list of offset-value pairs for registers to be written.
+  The offsets are from the base offset specified in 'reg'. This is mainly
+  used for QoS, vbif, etc. presets for video.
+- qcom,bus-ports : number of bus ports supported by venus to access
+  ddr/ocmem.
+- qcom,enc-ocmem-ab-ib : list of bus vectors (ab, ib pair) for ocmem
+  bandwidth request by different video encoder usecases.
+- qcom,dec-ocmem-ab-ib : list of bus vectors(ab, ib pair) for ocmem
+  bandwidth request by different video decoder usecases.
+- qcom,enc-ddr-ab-ib : list of bus vectors(ab,ib pair) for ddr bandwidth
+  request by different video encoder usecases.
+- qcom,dec-ddr-ab-ib : list of bus vectors(ab, ib pair) for ddr bandwidth
+  request by different video decoder usecases.
+- qcom,iommu-groups : list of IOMMU groups to be used.  Groups are defined as
+  phandles in <target>-iommu-domains.dtsi (e.g msm8974-v1-iommu-domains.dtsi)
+- qcom,iommu-group-buffer-types : bitmap of buffer types that can be mapped into
+  the corresponding IOMMU group. Buffer types are defined within the vidc driver
+  by "enum hal_buffer" in msm_smem.h
+- qcom,buffer-type-tz-usage-table : a key-value pair, mapping a buffer type
+  (enum hal_buffer) to its corresponding TZ usage. The TZ usages are defined
+  as "enum cp_mem_usage" in include/linux/msm_ion.h
 
 Example:
 
@@ -21,12 +47,28 @@
 		compatible = "qcom,msm-vidc";
 		reg = <0xfdc00000 0xff000>;
 		interrupts = <0 44 0>;
-		vidc-cp-map = <0x1000000 0x40000000>;
-		vidc-ns-map = <0x40000000 0x40000000>;
-		load-freq-tbl = <979200 410000000>,
+		qcom,vidc-cp-map = <0x1000000 0x40000000>;
+		qcom,vidc-ns-map = <0x40000000 0x40000000>;
+		qcom,load-freq-tbl = <979200 410000000>,
 				<560145 266670000>,
 				<421161 200000000>,
 				<243000 133330000>,
 				<108000 100000000>,
 				<36000 50000000>;
+		qcom,hfi = "venus";
+		qcom,reg-presets = <0x80004 0x1>,
+			<0x80178 0x00001FFF>;
+		qcom,bus-ports = <1>;
+		qcom,enc-ocmem-ab-ib = <0 0>,
+			<138200 1222000>;
+		qcom,dec-ocmem-ab-ib = <0 0>,
+			<176900 1556640>;
+		qcom,enc-ddr-ab-ib = <0 0>,
+			<60000 664950>;
+		qcom,dec-ddr-ab-ib = <0 0>,
+			<110000 909000>;
+		qcom,iommu-groups = <&venus_domain_ns &venus_domain_cp>;
+		qcom,iommu-group-buffer-types = <0xfff 0x1ff>;
+		qcom,buffer-type-tz-usage-table = <0x1 0x1>,
+						<0x1fe 0x2>;
 	};
diff --git a/Documentation/devicetree/bindings/memory.txt b/Documentation/devicetree/bindings/memory.txt
new file mode 100644
index 0000000..e98ee05
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory.txt
@@ -0,0 +1,106 @@
+* Memory binding
+
+The /memory node provides basic information about the address and size
+of the physical memory. This node is usually filled or updated by the
+bootloader, depending on the actual memory configuration of the given
+hardware.
+
+The memory layout is described by the folllowing node:
+
+memory {
+	reg =  <(baseaddr1) (size1)
+		(baseaddr2) (size2)
+		...
+		(baseaddrN) (sizeN)>;
+};
+
+baseaddrX:	the base address of the defined memory bank
+sizeX:		the size of the defined memory bank
+
+More than one memory bank can be defined.
+
+
+* Memory regions
+
+In /memory node one can create additional nodes describing particular
+memory regions, usually for the special usage by various device drivers.
+A good example are contiguous memory allocations or memory sharing with
+other operating system on the same hardware board. Those special memory
+regions might depend on the board configuration and devices used on the
+target system.
+
+Parameters for each memory region can be encoded into the device tree
+wit the following convention:
+
+(name): region@(base-address) {
+	reg = <(baseaddr) (size)>;
+	(linux,contiguous-region);
+	(linux,default-contiguous-region);
+        label = (unique_name);
+};
+
+name:		an name given to the defined region.
+base-address:	the base address of the defined region.
+size:		the size of the memory region.
+linux,contiguous-region: property indicating that the defined memory
+		region is used for contiguous memory allocations,
+		Linux specific (optional)
+linux,default-contiguous-region: property indicating that the region
+		is the default region for all contiguous memory
+		allocations, Linux specific (optional)
+label:		an internal name used for automatically associating the
+		cma region with a given device. The label is optional;
+		if the label is not given the client is responsible for
+		calling the appropriate functions to associate the region
+		with a device.
+
+* Device nodes
+
+Once the regions in the /memory node are defined, they can be assigned
+to device some device nodes for their special use. The following
+properties are defined:
+
+linux,contiguous-region = <&phandle>;
+	This property indicates that the device driver should use the
+	memory region pointed by the given phandle.
+
+
+* Example:
+
+This example defines a memory consisting of 4 memory banks. 2 contiguous
+regions are defined for Linux kernel, one default of all device drivers
+(named contig_mem, placed at 0x72000000, 64MiB) and one dedicated to the
+framebuffer device (named display_mem, placed at 0x78000000, 16MiB). The
+display_mem region is then assigned to fb@12300000 device for contiguous
+memory allocation with Linux kernel drivers.
+
+The reason for creating a separate region for framebuffer device is to
+match the framebuffer address of from configuration done by bootloader,
+so once Linux kernel drivers starts, no glitches on the displayed boot
+logo appears.
+
+/ {
+	/* ... */
+	memory {
+		reg =  <0x40000000 0x10000000
+			0x50000000 0x10000000
+			0x60000000 0x10000000
+			0x70000000 0x10000000>;
+
+		contig_mem: region@72000000 {
+			linux,contiguous-region;
+			linux,default-contiguous-region;
+			reg = <0x72000000 0x4000000>;
+		};
+
+		display_mem: region@78000000 {
+			linux,contiguous-region;
+			reg = <0x78000000 0x1000000>;
+		};
+	};
+
+	fb@12300000 {
+		linux,contiguous-region = <&display_mem>;
+		status = "okay";
+	};
+};
diff --git a/Documentation/devicetree/bindings/misc/isa1200.txt b/Documentation/devicetree/bindings/misc/isa1200.txt
new file mode 100644
index 0000000..b30782d
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/isa1200.txt
@@ -0,0 +1,65 @@
+Imagis ISA1200 Haptics Vibrator
+
+Required properties:
+ - reg:	slave address of bus
+ - compatible: should be "imagis,isa1200"
+ - label: name for vibrator directory
+ - imagis,hap-en-gpio: haptic enable gpio
+ - imagis,mode-ctrl: mode of the controller, 0 = POWER_DOWN_MODE,
+	1 = PWM_INPUT_MODE, 2 = PWM_GEN_MODE, 3 = WAVE_GEN_MODE
+ - imagis,max-timeout: maximum timeout for vibration
+ - imagis,chip-en: chip enable
+ - vcc_i2c-supply: regulator supplying i2c bus
+
+Regulator described as a child of the main device:
+ - regulator-name: A string used as a descriptive name for regulator outputs,
+	should match vcc_i2c above
+ - regulator-min-microvolt: smallest voltage consumers may set
+ - regulator-max-microvolt: largest voltage consumers may set
+ - regulator-max-microamp: largest current consumers may set
+
+Optional properties:
+ - imagis,smart-en: automatically control haptic power based on pwm/clk signal
+ - imagis,is-erm: controlled by dc motor, use ERM driving method
+ - imagis,overdrive-high: overdrive high
+ - imagis,overdrive-en: enable overdrive
+ - imagis,pwm-freq: pwm frequency (hZ)
+ - imagis,pwm-ch-id: pwm channel id
+ - imagis,pwm-div: pwm division to be used for vibration
+ - imagis,need-pwm-clk: use "pwm_clk"
+ - imagis,hap-len-gpio: haptic ldo enable gpio
+ - imagis,etc-clk-en: use external clock
+ - xyz-supply: to be used if additional regulators are require beyond
+		"imagis,regulator" above
+
+Any additional regulators are described as child nodes of main device:
+ - regulator-name: A string used as a descriptive name for regulator outputs,
+	should match supply "xyz"
+ - regulator-min-microvolt: smallest voltage consumers may set
+ - regulator-max-microvolt: largest voltage consumers may set
+ - regulator-max-microamp: largest current consumers may set
+
+Example:
+	i2c@f9967000 {
+		isa1200@48 {
+			status = "okay";
+			reg = <0x48>;
+			vcc_i2c-supply = <&pm8941_s3>;
+			compatible = "imagis,isa1200";
+			label = "vibrator";
+			imagis,chip-en;
+			imagis,smart-en;
+			imagis,need-pwm-clk;
+			imagis,ext-clk-en;
+			imagis,hap-en-gpio = <&msmgpio 86 0x00>;
+			imagis,max-timeout = <15000>;
+			imagis,pwm-div = <256>;
+			imagis,mode-ctrl = <2>;
+			imagis,regulator {
+				regulator-name = "vcc_i2c";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-max-microamp = <9360>;
+			};
+		};
+	};
diff --git a/Documentation/devicetree/bindings/ocmem/msm-ocmem.txt b/Documentation/devicetree/bindings/ocmem/msm-ocmem.txt
index e212aca..0a0ed75 100644
--- a/Documentation/devicetree/bindings/ocmem/msm-ocmem.txt
+++ b/Documentation/devicetree/bindings/ocmem/msm-ocmem.txt
@@ -18,6 +18,7 @@
 		    "ocmem_irq" corresponds to OCMEM Error Interrupt.
 		    "dm_irq" corresponds to DM Interrupt.
 - qcom,ocmem-num-regions: The number of OCMEM hardware memory regions.
+- qcom,ocmem-num-macros: The number of OCMEM hardware memory macros.
 - qcom,resource-type: The hardware resource type of the OCMEM core.
 
 In addition to the information on the OCMEM core, the
diff --git a/Documentation/devicetree/bindings/pil/pil-q6v5-lpass.txt b/Documentation/devicetree/bindings/pil/pil-q6v5-lpass.txt
index ac9600d..2764657 100644
--- a/Documentation/devicetree/bindings/pil/pil-q6v5-lpass.txt
+++ b/Documentation/devicetree/bindings/pil/pil-q6v5-lpass.txt
@@ -12,8 +12,13 @@
 - reg-names:	      Names of the bases for the above registers. "qdsp6_base"
 		      and "halt_base" are expected.
 - interrupts:         The lpass watchdog interrupt
+- vdd_cx-supply:      Reference to the regulator that supplies the vdd_cx domain.
 - qcom,firmware-name: Base name of the firmware image. Ex. "lpass"
 
+Optional properties:
+- vdd_pll-supply:     Reference to the regulator that supplies the PLL's rail.
+- qcom,vdd_pll:       Voltage to be set for the PLL's rail.
+
 Example:
 	qcom,lpass@fe200000 {
 	        compatible = "qcom,pil-q6v5-lpass";
@@ -21,6 +26,6 @@
 	              <0xfd485100 0x00010>;
 		reg-names = "qdsp6_base", "halt_base";
 		interrupts = <0 194 1>;
-
+		vdd_cx-supply = <&pm8841_s2>;
 	        qcom,firmware-name = "lpass";
 	};
diff --git a/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt b/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt
index 5bef9b8..8f602b6 100644
--- a/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt
+++ b/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt
@@ -14,6 +14,7 @@
 		      "metadata_base" are expected.
 - interrupts:         The modem watchdog interrupt
 - vdd_mss-supply:     Reference to the regulator that supplies the processor.
+- vdd_cx-supply:      Reference to the regulator that supplies the vdd_cx domain.
 - vdd_mx-supply:      Reference to the regulator that supplies the memory rail.
 - qcom,firmware-name: Base name of the firmware image. Ex. "mdsp"
 - qcom,pil-self-auth: <0> if the hardware does not require self-authenticating
@@ -21,6 +22,10 @@
 		      <1> if the hardware requires self-authenticating images.
 - qcom,is-loadable:   if PIL is required to load the modem image
 
+Optional properties:
+- vdd_pll-supply:     Reference to the regulator that supplies the PLL's rail.
+- qcom,vdd_pll:       Voltage to be set for the PLL's rail.
+
 Example:
 	qcom,mss@fc880000 {
 		compatible = "qcom,pil-q6v5-mss";
@@ -33,6 +38,7 @@
 			    "restart_reg", metadata_base";
 		interrupts = <0 24 1>;
 		vdd_mss-supply = <&pm8841_s3>;
+		vdd_cx-supply = <&pm8841_s2>;
 		vdd_mx-supply = <&pm8841_s1>;
 
 		qcom,is-loadable;
diff --git a/Documentation/devicetree/bindings/platform/msm/ipa.txt b/Documentation/devicetree/bindings/platform/msm/ipa.txt
index 86c60e8..3cd29e4 100644
--- a/Documentation/devicetree/bindings/platform/msm/ipa.txt
+++ b/Documentation/devicetree/bindings/platform/msm/ipa.txt
@@ -13,9 +13,12 @@
        registers.
 - reg-names: "ipa-base" - string to identify the IPA CORE base registers.
 	     "bam-base" - string to identify the IPA BAM base registers.
+	     "a2-bam-base" - string to identify the A2 BAM base registers.
 - interrupts: Specifies the interrupt associated with IPA.
 - interrupt-names: "ipa-irq" - string to identify the IPA core interrupt.
                    "bam-irq" - string to identify the IPA BAM interrupt.
+                   "a2-bam-irq" - string to identify the A2 BAM interrupt.
+- qcom,ipa-hw-ver: Specifies the IPA hardware version.
 
 IPA pipe sub nodes (A2 static pipes configurations):
 
@@ -48,10 +51,13 @@
 	compatible = "qcom,ipa";
 	reg = <0xfd4c0000 0x26000>,
 	      <0xfd4c4000 0x14818>;
-	reg-names = "ipa-base", "bam-base";
+	      <0xfc834000 0x7000>;
+	reg-names = "ipa-base", "bam-base"; "a2-bam-base";
 	interrupts = <0 252 0>,
 	             <0 253 0>;
-	interrupt-names = "ipa-irq", "bam-irq";
+	             <0 29 1>;
+	interrupt-names = "ipa-irq", "bam-irq"; "a2-bam-irq";
+	qcom,ipa-hw-ver = <1>;
 
 	qcom,pipe1 {
 		label = "a2-to-ipa";
diff --git a/Documentation/devicetree/bindings/platform/msm/qpnp-vibrator.txt b/Documentation/devicetree/bindings/platform/msm/qpnp-vibrator.txt
new file mode 100644
index 0000000..87fa8d9
--- /dev/null
+++ b/Documentation/devicetree/bindings/platform/msm/qpnp-vibrator.txt
@@ -0,0 +1,25 @@
+QPNP Vibrator
+
+QPNP (Qualcomm Plug N Play) vibrator is a peripheral on
+Qualcomm PMICs.  The PMIC is connected to Host processor
+via SPMI bus.
+
+Required Properties:
+ - status: default status is set to "disabled.  Must be "okay"
+ - compatible: must be "qcom,qpnp-vibrator"
+ - label: name which describes the device
+ - reg: address of device
+
+Optional Properties:
+ - qcom,vib-timeout-ms: timeout of vibrator, in ms.  Default 15000 ms
+ - qcom,vib-vtg-level-mV: voltage level, in mV.  Default 3100 mV
+
+Example:
+		qcom,vib@c000 {
+			status = "okay";
+			compatible = "qcom,qpnp-vibrator";
+			reg = <0xc000 0x100>;
+			label = "vibrator";
+			qcom,vib-timeout-ms = <15000>;
+			qcom,vib-vtg-level-mV = <3100>;
+		};
diff --git a/Documentation/devicetree/bindings/platform/msm/ssm.txt b/Documentation/devicetree/bindings/platform/msm/ssm.txt
new file mode 100644
index 0000000..8fb3356
--- /dev/null
+++ b/Documentation/devicetree/bindings/platform/msm/ssm.txt
@@ -0,0 +1,30 @@
+* Qualcomm Secure Service Module (SSM)
+
+SSM provides an interface for OEM driver to communicate with Modem and
+trustzone.
+
+This module provides following features:
+ - Keyexchange between Modem and trustzone for encryption/Decryption
+ of mode information
+ - Interface to third party driver to send mode updates to modem
+ - Interface for loading the trustzone application
+
+Required properties:
+- compatible:		Must be "qcom,ssm"
+
+Optional properties:
+- qcom,channel-name:	Name of the SMD channel used for communication
+			between MODEM and SSM driver.
+- qcom,need-keyexhg	This property controls initial key exchange
+			between APPS(application processor) and MODEM.
+			If not mentioned the initial key exchange is
+			not required.
+			If this property is mentioned then it is mandatory
+			for modem to perform initial key exchange with APPS.
+
+Example:
+	qcom,ssm {
+		compatible = "qcom,ssm";
+		qcom,channel-name = "SSM_RTR";
+		qcom,need-keyexhg;
+	}
diff --git a/Documentation/devicetree/bindings/power/bq28400-battery.txt b/Documentation/devicetree/bindings/power/bq28400-battery.txt
index 1460d70..a95e61f 100644
--- a/Documentation/devicetree/bindings/power/bq28400-battery.txt
+++ b/Documentation/devicetree/bindings/power/bq28400-battery.txt
@@ -4,15 +4,20 @@
 The device interface is I2C, its I2C slave 7-bit address is 0xb.
 The device is usually embedded inside the "smart battery" pack.
 
-node required properties:
-- compatible:	Must be "ti,bq28400-battery" or "ti,bq30z55-battery"
-- reg:		I2C Address must be 0xb.
+Required properties:
+
+ - compatible : Must be "ti,bq28400-battery" or "ti,bq30z55-battery"
+ - reg : I2C Address must be 0xb.
+ - ti,temp-cold : Cold temperature limit in celsius degree
+ - ti,temp-hot : Hot temperature limit in celsius degree
 
 Example:
 	i2c@f9967000 {
 		battery@b {
 			compatible = "ti,bq28400-battery", "ti,bq30z55-battery";
 			reg = <0xb>;
+			ti,temp-cold = <2>;
+			ti,temp-hot = <43>;
 		};
 	};
 
diff --git a/Documentation/devicetree/bindings/power/qpnp-bms.txt b/Documentation/devicetree/bindings/power/qpnp-bms.txt
index d91086f..708ada1 100644
--- a/Documentation/devicetree/bindings/power/qpnp-bms.txt
+++ b/Documentation/devicetree/bindings/power/qpnp-bms.txt
@@ -15,51 +15,61 @@
 
 Parent node required properties:
 - compatible : should be "qcom,qpnp-bms" for the BM driver.
-- qcom,bms-r-sense-mohm : sensor resistance in in milli-ohms.
-- qcom,bms-v-cutoff-uv : cutoff voltage where the battery is considered dead in
+- qcom,r-sense-uohm : sensor resistance in in micro-ohms.
+- qcom,v-cutoff-uv : cutoff voltage where the battery is considered dead in
 			micro-volts.
-- qcom,bms-max-voltage-uv : maximum voltage for the battery in micro-volts.
-- qcom,bms-r-conn-mohm : connector resistance in milli-ohms.
-- qcom,bms-shutdown-soc-valid-limit : If the ocv upon restart is within this
+- qcom,max-voltage-uv : maximum voltage for the battery in micro-volts.
+- qcom,r-conn-mohm : connector resistance in milli-ohms.
+- qcom,shutdown-soc-valid-limit : If the ocv upon restart is within this
 			distance of the shutdown ocv, the BMS will try to force
 			the new SoC to the old one to provide charge continuity.
 			That is to say,
 				if (abs(shutdown-soc - current-soc) < limit)
 				then use old SoC.
-- qcom,bms-adjust-soc-low-threshold : The low threshold for the "flat portion"
+- qcom,adjust-soc-low-threshold : The low threshold for the "flat portion"
 			of the charging curve. The BMS will not adjust SoC
 			based on voltage during this time.
-- qcom,bms-adjust-soc-high-threshold : The high threshold for the "flat
+- qcom,adjust-soc-high-threshold : The high threshold for the "flat
 			portion" of the charging curve. The BMS will not
 			adjust SoC based on voltage during this time.
-- qcom,bms-low-soc-calculate-soc-threshold : The SoC threshold for when
+- qcom,ocv-voltage-low-threshold-uv : The low voltage threshold for the
+			"flat portion" of the discharge curve. The bms will not
+			accept new ocvs between these thresholds.
+- qcom,ocv-voltage-high-threshold-uv : The high voltage threshold for
+			the "flat portion" of the discharge curve.
+			The bms will not accept new ocvs between these
+			thresholds.
+- qcom,low-soc-calculate-soc-threshold : The SoC threshold for when
 			the period calculate_soc work speeds up. This ensures
 			SoC is updated in userspace constantly when we are near
 			shutdown.
-- qcom,bms-low-soc-calculate-soc-ms : The time period between subsequent
+- qcom,low-soc-calculate-soc-ms : The time period between subsequent
+
 			SoC recalculations when the current SoC is below
-			qcom,bms-low-soc-calculate-soc-threshold.
-- qcom,bms-soc-calculate-soc-ms : The time period between subsequent SoC
+			qcom,low-soc-calculate-soc-threshold.
+- qcom,soc-calculate-soc-ms : The time period between subsequent SoC
 			recalculations when the current SoC is above or equal
-			qcom,bms-low-soc-calculate-soc-threshold.
-- qcom,bms-chg-term-ua : current in micro-amps when charging is considered done.
+			qcom,low-soc-calculate-soc-threshold.
+- qcom,chg-term-ua : current in micro-amps when charging is considered done.
 			As soon as current passes this point, charging is
 			stopped.
-- qcom,bms-batt-type: Type of battery used. This is an integer that corresponds
+- qcom,batt-type: Type of battery used. This is an integer that corresponds
 			to the enum defined in
 			include/linux/mfd/pm8xxx/batterydata-lib.h
 
 Parent node optional properties:
-- qcom,bms-ignore-shutdown-soc: A boolean that controls whether BMS will
+- qcom,ignore-shutdown-soc: A boolean that controls whether BMS will
 			try to force the startup SoC to be the same as the
 			shutdown SoC. Defining it will make BMS ignore the
 			shutdown SoC.
-- qcom,bms-use-voltage-soc : A boolean that controls whether BMS will use
+- qcom,use-voltage-soc : A boolean that controls whether BMS will use
 			voltage-based SoC instead of a coulomb counter based
 			one. Voltage-based SoC will not guarantee linearity.
-- qcom,bms-use-external-rsense : A boolean that controls whether BMS will use
+- qcom,use-external-rsense : A boolean that controls whether BMS will use
 			an external sensor resistor instead of the default
 			RDS of the batfet.
+- qcom,use-ocv-thresholds : A boolean that controls whether BMS will take
+			new OCVs only between the defined thresholds.
 
 All sub node required properties:
 - reg : offset and length of the PMIC peripheral register map.
@@ -87,18 +97,20 @@
 	#size-cells = <1>;
 	status = "disabled";
 
-	qcom,bms-r-sense-mohm = <2>;
-	qcom,bms-v-cutoff-uv = <3400000>;
-	qcom,bms-max-voltage-uv = <4200000>;
-	qcom,bms-r-conn-mohm = <18>;
-	qcom,bms-shutdown-soc-valid-limit = <20>;
-	qcom,bms-adjust-soc-low-threshold = <25>;
-	qcom,bms-adjust-soc-high-threshold = <45>;
-	qcom,bms-low-soc-calculate-soc-threshold = <15>;
-	qcom,bms-low-soc-calculate-soc-ms = <5000>;
-	qcom,bms-calculate-soc-ms = <20000>;
-	qcom,bms-chg-term-ua = <100000>;
-	qcom,bms-batt-type = <0>;
+	qcom,r-sense-uohm = <10000>;
+	qcom,v-cutoff-uv = <3400000>;
+	qcom,max-voltage-uv = <4200000>;
+	qcom,r-conn-mohm = <18>;
+	qcom,shutdown-soc-valid-limit = <20>;
+	qcom,ocv-voltage-low-threshold-uv = <3650000>;
+	qcom,ocv-voltage-high-threshold-uv = <3750000>;
+	qcom,adjust-soc-low-threshold = <25>;
+	qcom,adjust-soc-high-threshold = <45>;
+	qcom,low-soc-calculate-soc-threshold = <15>;
+	qcom,low-soc-calculate-soc-ms = <5000>;
+	qcom,calculate-soc-ms = <20000>;
+	qcom,chg-term-ua = <100000>;
+	qcom,batt-type = <0>;
 
 	qcom,bms-iadc@3800 {
 		reg = <0x3800 0x100>;
diff --git a/Documentation/devicetree/bindings/power/qpnp-charger.txt b/Documentation/devicetree/bindings/power/qpnp-charger.txt
index 59a9fd9..a868b75 100644
--- a/Documentation/devicetree/bindings/power/qpnp-charger.txt
+++ b/Documentation/devicetree/bindings/power/qpnp-charger.txt
@@ -23,15 +23,19 @@
 			settings, comparator override features etc.
 
 Parent node required properties:
-- qcom,chg-vddmax-mv:	Target voltage of battery in mV
-- qcom,chg-vddsafe-mv:	Maximum Vdd voltage in mV
-- qcom,chg-vinmin-mv:	Minimum input voltage in mV
-- qcom,chg-vbatdet-mv:	Battery voltage at which charging resumes
-- qcom,chg-ibatmax-ma:	Maximum battery charge current in mA
-- qcom,chg-ibatterm-ma:	Current at which charging is terminated in mA.
-- qcom,chg-ibatsafe-ma:	Safety battery current setting
+- qcom,chg-vddmax-mv:			Target voltage of battery in mV.
+- qcom,chg-vddsafe-mv:			Maximum Vdd voltage in mV.
+- qcom,chg-vinmin-mv:			Minimum input voltage in mV.
+- qcom,chg-vbatdet-mv:			Battery charging resume voltage in mV.
+- qcom,chg-ibatmax-ma:			Maximum battery charge current in mA
+- qcom,chg-ibatterm-ma:			Current at which charging is terminated.
+- qcom,chg-ibatsafe-ma:			Safety battery current setting
+- qcom,chg-thermal-mitigation:		Array of ibatmax values for different
+					system thermal mitigation level.
 
 Parent node optional properties:
+- qcom,chg-maxinput-usb-ma:		Maximum input current USB.
+- qcom,chg-maxinput-dc-ma:		Maximum input current DC.
 - qcom,chg-charging-disabled:		Set this property to disable charging
 					by default. This can then be overriden
 					writing the the module parameter
@@ -128,8 +132,11 @@
 		qcom,chg-vddmax-mv = <4200>;
 		qcom,chg-vddsafe-mv = <4200>;
 		qcom,chg-vinmin-mv = <4200>;
-		qcom,chg-ibatmax-mv = <1500>;
-		qcom,chg-ibatterm-mv = <200>;
+		qcom,chg-vbatdet-mv = <4200>;
+		qcom,chg-ibatmax-ma = <1500>;
+		qcom,chg-ibatterm-ma = <200>;
+		qcom,chg-ibatsafe-ma = <1500>;
+		qcom,chg-thermal-mitigation = <1500 700 600 325>;
 
 		qcom,chg-chgr@1000 {
 			reg = <0x1000 0x100>;
diff --git a/Documentation/devicetree/bindings/regulator/fixed-regulator.txt b/Documentation/devicetree/bindings/regulator/fixed-regulator.txt
index 9cf57fd..7637adc 100644
--- a/Documentation/devicetree/bindings/regulator/fixed-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/fixed-regulator.txt
@@ -8,6 +8,7 @@
 - startup-delay-us: startup time in microseconds
 - enable-active-high: Polarity of GPIO is Active high
 If this property is missing, the default assumed is Active low.
+- parent-supply: phandle to the parent supply/regulator node if one exists.
 
 Any property defined as part of the core regulator
 binding, defined in regulator.txt, can also be used.
diff --git a/Documentation/devicetree/bindings/regulator/krait-regulator.txt b/Documentation/devicetree/bindings/regulator/krait-regulator.txt
index fddae80..c783ac8 100644
--- a/Documentation/devicetree/bindings/regulator/krait-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/krait-regulator.txt
@@ -1,27 +1,67 @@
 Krait Voltage regulators
 
+The cpus are powered using a single supply powered by PMIC ganged regulators operating in
+different phases. Individual kraits further can draw power from the single supply via
+a LDO or a head switch (BHS).  The first level node represents the PMIC ganged regulator
+and its properties and encompasses second level nodes that represent the individual
+krait LDO/BHS control regulator.
+
+[First Level Nodes]
+Required properties:
+- compatible:			Must be "qcom,krait-pdn"
+
+Optional properties:
+- qcom,use-phase-switching	indicates whether the driver should add/shed phases on the PMIC
+				ganged regulator as cpus are hotplugged.
+
+[Second Level Nodes]
 Required properties:
 - compatible:			Must be "qcom,krait-regulator"
-- reg:				Specifies the address and size for this regulator device
+- reg:				Specifies the address and size for this regulator device,
+				also specifies the address and the size for the MDD area
+				to be used along with the regulator
+- reg-names:			"acs" -string to identify the area where main power control
+					registers reside.
+				"mdd" - string to identify the area where mdd registers reside.
 - qcom,headroom-voltage:	The minimum required voltage drop between the input
 			 	voltage and the output voltage for the LDO to be
-			 	operational, in microvolts
-- qcom,retention-voltage:	The value for retention voltage in microvolts
-- qcom,ldo-default-voltage:	The default value for LDO voltage in microvolts
-- qcom,ldo-threshold-voltage:	The voltage value above which LDO is nonfunctional
+			 	operational, in microvolts. Acceptable values are from
+				50000uV to 250000uV
+- qcom,retention-voltage:	The value for retention voltage in microvolts. Acceptable
+				values are from 465000uV to 750000uV
+- qcom,ldo-default-voltage:	The default value for LDO voltage in microvolts. Acceptable
+				values are from 465000uV to 750000uV
+- qcom,ldo-threshold-voltage:	The voltage value above which LDO is nonfunctional.
+				Acceptable values are from 600000uV to 900000uV
+- qcom,ldo-delta-voltage:	The delta used to reduce the requested voltage in order
+				to derive the LDO output voltage while switching
+				to LDO mode. Acceptable values are from 1000uV to 100000uV
+- qcom,cpu-num:			Indicates what cpu this regulator controls
 
 Any property defined as part of the core regulator
 binding, defined in regulator.txt, can also be used.
 
 Example:
-	krait0_vreg: regulator@f9088000 {
-		compatible = "qcom,krait-regulator";
-		regulator-name = "krait0";
-		reg = <0xf9088000 0x1000>;
-		regulator-min-microvolt = <500000>;
-		regulator-max-microvolt = <1100000>;
-		qcom,headroom-voltage = <150000>;
-		qcom,retention-voltage = <745000>;
-		qcom,ldo-default-voltage = <745000>;
-		qcom,ldo-threshold-voltage = <750000>;
+	krait_pdn: krait-pdn {
+		compatible = "qcom,krait-pdn";
+		qcom,use-phase-switching;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		krait0_vreg: regulator@f9088000 {
+			compatible = "qcom,krait-regulator";
+			regulator-name = "krait0";
+			reg = <0xf9088000 0x1000>, /* APCS_ALIAS0_KPSS_ACS */
+				<0xf908a800 0x1000>; /* APCS_ALIAS0_KPSS_MDD */
+			reg-names = "acs", "mdd";
+			regulator-min-microvolt = <500000>;
+			regulator-max-microvolt = <1100000>;
+			qcom,headroom-voltage = <150000>;
+			qcom,retention-voltage = <675000>;
+			qcom,ldo-default-voltage = <750000>;
+			qcom,ldo-threshold-voltage = <850000>;
+			qcom,ldo-delta-voltage = <50000>;
+			qcom,cpu-num = <0>;
+		};
 	};
diff --git a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
index 104d6a2..fed8cb4 100644
--- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
+++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
@@ -6,6 +6,21 @@
 
  - compatible : "qcom,msm-pcm-dsp"
 
+ - qcom,msm-pcm-dsp-id : device node id
+
+* msm-pcm-low-latency
+
+Required properties:
+
+ - compatible : "qcom,msm-pcm-dsp"
+
+ - qcom,msm-pcm-dsp-id : device node id
+
+   Optional properties
+
+      - qcom,msm-pcm-low-latency : Flag indicating whether
+        the device node is of type low latency.
+
 * msm-pcm-routing
 
 Required properties:
@@ -54,6 +69,23 @@
 
  - compatible : "qcom,msm-pcm-afe"
 
+* msm-pcm-dtmf
+
+Required properties:
+
+ - compatible : "qcom,msm-pcm-dtmf"
+ - qcom,msm-pcm-dtmf : Enable DTMF driver in Audio. DTMF driver is
+   used for generation and detection of DTMF tones, when user is in
+   active voice call. APR commands are sent from DTMF driver to ADSP.
+
+* msm-dai-stub
+
+Required properties:
+
+ - compatible : "qcom,msm-dai-stub"
+ - qcom,msm-dai-stub : This enables stub CPU dai in Audio.
+   The stub dai is used when there is no real backend in Audio.
+
 * msm-dai-q6-hdmi
 
 Required properties:
@@ -85,9 +117,11 @@
  - qcom,msm-dai-q6-dev-id : The slimbus multi channel port ID
                             Value is from 16384 to 16393
                             BT SCO port ID value from 12288 to 12289
-                            RT Proxy port ID values from 224 to 225 and 240 to 241
+                            RT Proxy port ID values from 224 to 225 and 240 to
+			    241
                             FM Rx and TX port ID values from 12292 to 12293
                             incall record Rx and TX port ID values from 32771 to 32772
+                            inCall Music Delivery port ID is 32773
 
 * msm-auxpcm
 
@@ -97,25 +131,42 @@
 
  - compatible :                           "qcom,msm-auxpcm-resource"
 
- - qcom,msm-cpudai-auxpcm-clk:            clock for auxpcm
+ - qcom,msm-cpudai-auxpcm-clk:            clock for auxpcm. The first value is
+                                          for 8khz mode, the second is for
+                                          16khz
 
- - qcom,msm-cpudai-auxpcm-mode:           mode information
+ - qcom,msm-cpudai-auxpcm-mode:           mode information. The first value is
+                                          for 8khz mode, the second is for
+                                          16khz
                                           0 - for PCM
 
- - qcom,msm-cpudai-auxpcm-sync:           sync information
+ - qcom,msm-cpudai-auxpcm-sync:           sync information. The first value is
+                                          for 8khz mode, the second is for
+                                          16khz
 
- - qcom,msm-cpudai-auxpcm-frame:          No.of bytes per frame
+ - qcom,msm-cpudai-auxpcm-frame:          No.of bytes per frame. The first
+                                          value is for 8khz mode, the second
+                                          is for 16khz
                                           5 - 256BPF
+                                          4 - 128BPF
 
- - qcom,msm-cpudai-auxpcm-quant:          Type of quantization
+ - qcom,msm-cpudai-auxpcm-quant:          Type of quantization. The first
+                                          value is for 8khz mode, the second
+                                          is for 16khz
                                           2 - Linear quantization
 
  - qcom,msm-cpudai-auxpcm-slot:           Slot number for multichannel scenario
+                                          The first value is for 8khz mode the
+                                          second is for 16khz
                                           Value is 1
 
- - qcom,msm-cpudai-auxpcm-data:           Data field - 0
+ - qcom,msm-cpudai-auxpcm-data:           Data field - 0. The first value is
+                                          for 8khz mode, the second is for
+                                          16khz
 
- - qcom,msm-cpudai-auxpcm-pcm-clk-rate:   Clock rate for pcm - 2048000
+ - qcom,msm-cpudai-auxpcm-pcm-clk-rate:   Clock rate for pcm - 2048000. The
+                                          first value is for 8khz mode, the
+                                          second is for auxpcm
 
 [Second Level Nodes]
 
@@ -144,22 +195,24 @@
 
  - qcom,msm_bus,num_cases:                 Total number of use cases
 
- - qcom,msm_bus,active_only:               Context flag for requests in active or
-                                           dual (active & sleep) contex
+ - qcom,msm_bus,active_only:               Context flag for requests in active
+					   or dual (active & sleep) contex
 
  - qcom,msm_bus,num_paths:                 Total number of master-slave pairs
 
- - qcom,msm_bus,vectors:                   Arrays of unsigned integers representing:
-                                           master-id, slave-id, arbitrated bandwidth,
-                                           instantaneous bandwidth
+ - qcom,msm_bus,vectors:                   Arrays of unsigned integers
+					   representing:
+					       master-id, slave-id, arbitrated
+					       bandwidth,
+					       instantaneous bandwidth
 * wcd9xxx_intc
 
 Required properties:
 
  - compatible :                            "qcom,wcd9xxx-irq"
 
- - interrupt-controller :                  Mark this device node as an interrupt
-                                           controller
+ - interrupt-controller :                  Mark this device node as an
+					   interrupt controller
 
  - #interrupt-cells :                      Should be 1
 
@@ -174,7 +227,14 @@
 Example:
 
         qcom,msm-pcm {
-                compatible = "qcom,msm-pcm-dsp";
+		compatible = "qcom,msm-pcm-dsp";
+		qcom,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;
         };
 
         qcom,msm-pcm-routing {
@@ -201,6 +261,14 @@
                 compatible = "qcom,msm-dai-fe";
         };
 
+	qcom,msm-pcm-dtmf {
+		compatible = "qcom,msm-pcm-dtmf";
+	};
+
+	qcom,msm-dai-stub {
+		compatible = "qcom,msm-dai-stub";
+	};
+
 	qcom,msm-dai-q6-hdmi {
 		compatible = "qcom,msm-dai-q6-hdmi";
 		qcom,msm-dai-q6-dev-id = <8>;
@@ -297,18 +365,23 @@
 			compatible = "qcom,msm-dai-q6-dev";
 			qcom,msm-dai-q6-dev-id = <32772>;
 		};
+
+		qcom,msm-dai-q6-incall-music-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <32773>;
+		};
 	};
 
         qcom,msm-auxpcm {
                 compatible = "qcom,msm-auxpcm-resource";
                 qcom,msm-cpudai-auxpcm-clk = "pcm_clk";
-                qcom,msm-cpudai-auxpcm-mode = <0>;
-                qcom,msm-cpudai-auxpcm-sync = <1>;
-                qcom,msm-cpudai-auxpcm-frame = <5>;
-                qcom,msm-cpudai-auxpcm-quant = <2>;
-                qcom,msm-cpudai-auxpcm-slot = <1>;
-                qcom,msm-cpudai-auxpcm-data = <0>;
-                qcom,msm-cpudai-auxpcm-pcm-clk-rate = <2048000>;
+                qcom,msm-cpudai-auxpcm-mode = <0>, <0>;
+                qcom,msm-cpudai-auxpcm-sync = <1>, <1>;
+                qcom,msm-cpudai-auxpcm-frame = <5>, <4>;
+                qcom,msm-cpudai-auxpcm-quant = <2>, <2>;
+                qcom,msm-cpudai-auxpcm-slot = <1>, <1>;
+                qcom,msm-cpudai-auxpcm-data = <0>, <0>;
+                qcom,msm-cpudai-auxpcm-pcm-clk-rate = <2048000>, <2048000>;
 
                 qcom,msm-auxpcm-rx {
                         qcom,msm-auxpcm-dev-id = <4106>;
@@ -357,6 +430,10 @@
 - taiko-mclk-clk : phandle to PMIC8941 clkdiv1 node.
 - qcom,taiko-mclk-clk-freq : Taiko mclk Freq in Hz. currently only 9600000Hz
 				is supported.
+- prim-auxpcm-gpio-clk : GPIO on which AUXPCM clk signal is coming.
+- prim-auxpcm-gpio-sync : GPIO on which AUXPCM SYNC signal is coming.
+- prim-auxpcm-gpio-din : GPIO on which AUXPCM DIN signal is coming.
+- prim-auxpcm-gpio-dout : GPIO on which AUXPCM DOUT signal is coming.
 
 Optional properties:
 - qcom,hdmi-audio-rx: specifies if HDMI audio support is enabled or not.
@@ -401,6 +478,11 @@
 	qcom,taiko-mclk-clk-freq = <9600000>;
 
 	qcom,hdmi-audio-rx;
+
+	prim-auxpcm-gpio-clk  = <&msmgpio 65 0>;
+	prim-auxpcm-gpio-sync = <&msmgpio 66 0>;
+	prim-auxpcm-gpio-din  = <&msmgpio 67 0>;
+	prim-auxpcm-gpio-dout = <&msmgpio 68 0>;
 };
 
 * msm-dai-mi2s
@@ -416,25 +498,34 @@
 Required properties:
 
  - compatible : "qcom,msm-dai-q6-mi2s"
- - qcom,msm-dai-q6-mi2s-dev-id: MSM or MDM can use Slimbus or I2S interface to transfer data
-								to (WCD9XXX) codec. If slimbus interface is used then
-								"msm-dai-q6" needs to be filled with correct data for slimbus
-								interface. The sections "msm-dai-mi2s" is used by MDM or MSM
-								to use I2S interface with codec. This section is used by CPU
-								driver in ASOC MSM to configure MI2S interface. MSM internally
-								has multiple MI2S namely Primary, Secondary, Tertiary and
-								Quaternary MI2S. They are represented with id 0, 1, 2, 3
-								respectively. The field "qcom,msm-dai-q6-mi2s-dev-id" represents
-								which of the MI2S block is used. These MI2S are connected to I2S
-								interface.
+ - qcom,msm-dai-q6-mi2s-dev-id: MSM or MDM can use Slimbus or I2S interface to
+				transfer data to (WCD9XXX) codec.
+				If slimbus interface is used then "msm-dai-q6"
+				needs to be filled with correct data for
+				slimbus interface.
+				The sections "msm-dai-mi2s" is used by MDM or
+				MSM to use I2S interface with codec.
+				This section is used by CPU driver in ASOC MSM
+				to configure MI2S interface. MSM internally
+				has multiple MI2S namely Primary, Secondary,
+				Tertiary and Quaternary MI2S.
+				They are represented with id 0, 1, 2, 3
+				respectively.
+				The field "qcom,msm-dai-q6-mi2s-dev-id"
+				represents which of the MI2S block is used.
+				These MI2S are connected to I2S interface.
 
- - qcom,msm-mi2s-rx-lines:		Each MI2S interface in MSM has one or more SD lines. These lines
-								are used for data transfer between codec and MSM. This element in
-								indicates which output RX lines are used in the MI2S interface.
+ - qcom,msm-mi2s-rx-lines:	Each MI2S interface in MSM has one or more SD
+				lines. These lines are used for data transfer
+				between codec and MSM.
+				This element in indicates which output RX lines
+				are used in the MI2S interface.
 
- - qcom,msm-mi2s-tx-lines:  	Each MI2S interface in MSM has one or more SD lines. These lines
-								are used for data transfer between codec and MSM. This element in
-								indicates which input TX lines are used in the MI2S interface.
+ - qcom,msm-mi2s-tx-lines:  	Each MI2S interface in MSM has one or more SD
+				lines. These lines are used for data transfer
+				between codec and MSM.
+				This element in indicates which input TX lines
+				are used in the MI2S interface.
 
 Example:
 
@@ -459,6 +550,11 @@
 - qcom,taiko-mclk-clk-freq : Master clock value given to codec. Some WCD9XXX
   codec can run at different mclk values. Mclk value can be 9.6MHz or 12.288MHz.
   This element represents the value for MCLK provided to codec.
+- prim-i2s-gpio-ws : Specifies gpio assigned for primary WS I2S pin.
+- prim-i2s-gpio-din : Specifies gpio assigned for primary DIN I2S pin.
+- prim-i2s-gpio-dout : Specifies gpio assigned for primary DOUT I2S pin.
+- prim-i2s-gpio-sclk : Specifies gpio assigned for primary SCLK I2S pin.
+- prim-i2s-gpio-mclk : Specifies gpio assigned for MCLK I2S pin.
 
 Example:
 
@@ -494,6 +590,11 @@
 			"DMIC6", "MIC BIAS4 External",
 			"MIC BIAS4 External", "Digital Mic6";
 			qcom,taiko-mclk-clk-freq = <12288000>;
+			prim-i2s-gpio-ws   =  <&msmgpio 12 0>;
+			prim-i2s-gpio-din  =  <&msmgpio 13 0>;
+			prim-i2s-gpio-dout =  <&msmgpio 14 0>;
+			prim-i2s-gpio-sclk =  <&msmgpio 15 0>;
+			prim-i2s-gpio-mclk =  <&msmgpio 71 0>;
 };
 
 * msm-adsp-loader
@@ -504,9 +605,9 @@
 	It is possible that some MSM use PIL to load the ADSP image. While
 	other MSM may use SBL to load the ADSP image at boot. Audio APR needs
 	state of ADSP to register and enable APR to be used for sending commands
-	to ADSP. so adsp-state represents the state of ADSP to ADSP loader. Value
-	of 0 indicates ADSP loader needs to use PIL and value of 2 means ADSP
-	image is already loaded by SBL.
+	to ADSP. so adsp-state represents the state of ADSP to ADSP loader.
+	Value of 0 indicates ADSP loader needs to use PIL and value of 2 means
+	ADSP image is already loaded by SBL.
 
 Example:
 
diff --git a/Documentation/devicetree/bindings/sound/taiko_codec.txt b/Documentation/devicetree/bindings/sound/taiko_codec.txt
index 74c25a0..989bea8 100644
--- a/Documentation/devicetree/bindings/sound/taiko_codec.txt
+++ b/Documentation/devicetree/bindings/sound/taiko_codec.txt
@@ -8,33 +8,39 @@
   - qcom,cdc-reset-gpio: gpio used for codec SOC reset.
 
   - <supply-name>-supply: phandle to the regulator device tree node
-  - qcom,<supply-name>-voltage -  specifies voltage levels for supply. Should be
-       specified in pairs (min, max), units mV.
+  - qcom,<supply-name>-voltage - specifies voltage levels for supply.
+      Should be specified in pairs (min, max), units mV.
   - qcom,<supply-name>-current - specifies max current in mA that can drawn
-       from the <supply-name>.
+      from the <supply-name>.
 
-    above three properties with "supply-name" set to  "qcom,cdc-vdd-buck", "qcom,cdc-vdd-tx-h",
-     "qcom,cdc-vdd-rx-h", "qcom,cdc-vddpx-1", "qcom,cdc-vdd-a-1p2v", "qcom,cdc-vddcx-1",
-     "qcom,cdc-vddcx-2" should be present.
+    above three properties with "supply-name" set to "qcom,cdc-vdd-buck",
+        "qcom,cdc-vdd-tx-h", "qcom,cdc-vdd-rx-h", "qcom,cdc-vddpx-1",
+	"qcom,cdc-vdd-a-1p2v", "qcom,cdc-vddcx-1", "qcom,cdc-vddcx-2"
+	should be present.
 
- - qcom,cdc-micbias-ldoh-v - LDOH output in volts ( should be 1.95 V and 3.00 V).
+ - qcom,cdc-micbias-ldoh-v - LDOH output in volts (should be 1.95 V and 3.00 V).
 
  - qcom,cdc-micbias-cfilt1-mv - cfilt1 output voltage in milli volts.
  - qcom,cdc-micbias-cfilt2-mv - cfilt2 output voltage in milli volts.
  - qcom,cdc-micbias-cfilt3-mv - cfilt3 output voltage in milli volts.
    cfilt voltage can be set to max of qcom,cdc-micbias-ldoh-v - 0.15V.
 
- - qcom,cdc-micbias1-cfilt-sel = cfilt to use for micbias1 (should be from 1 to 3).
- - qcom,cdc-micbias2-cfilt-sel = cfilt to use for micbias2 (should be from 1 to 3).
- - qcom,cdc-micbias3-cfilt-sel = cfilt to use for micbias3 (should be from 1 to 3).
- - qcom,cdc-micbias4-cfilt-sel = cfilt to use for micbias4 (should be from 1 to 3).
+ - qcom,cdc-micbias1-cfilt-sel = cfilt to use for micbias1
+				 (should be from 1 to 3).
+ - qcom,cdc-micbias2-cfilt-sel = cfilt to use for micbias2
+				 (should be from 1 to 3).
+ - qcom,cdc-micbias3-cfilt-sel = cfilt to use for micbias3
+				 (should be from 1 to 3).
+ - qcom,cdc-micbias4-cfilt-sel = cfilt to use for micbias4
+				 (should be from 1 to 3).
    This value represents the connected CFLIT to MIC Bias.
 
  - qcom,cdc-micbias1-ext-cap: Boolean. Enable micbias 1 external capacitor mode.
  - qcom,cdc-micbias2-ext-cap: Boolean. Enable micbias 2 external capacitor mode.
  - qcom,cdc-micbias3-ext-cap: Boolean. Enable micbias 3 external capacitor mode.
  - qcom,cdc-micbias4-ext-cap: Boolean. Enable micbias 4 external capacitor mode.
- - qcom,cdc-mclk-clk-rate - Specifies the master clock rate in Hz required for codec.
+ - qcom,cdc-mclk-clk-rate - Specifies the master clock rate in Hz required for
+			    codec.
  - qcom,cdc-slim-ifd-dev - namme of the codec slim interface device.
  - qcom,cdc-slim-ifd-elemental-addr - codec slimbus slave interface device
 				     enumeration address.
@@ -97,33 +103,39 @@
   - reg: represents the slave address provided to the I2C driver.
   - qcom,cdc-reset-gpio: gpio used for codec SOC reset.
   - <supply-name>-supply: phandle to the regulator device tree node.
-  - qcom,<supply-name>-voltage -  specifies voltage levels for supply. Should be
-       specified in pairs (min, max), units mV.
+  - qcom,<supply-name>-voltage -  specifies voltage levels for supply.
+      Should be specified in pairs (min, max), units mV.
   - qcom,<supply-name>-current - specifies max current in mA that can drawn
-       from the <supply-name>.
+      from the <supply-name>.
 
-    above three properties with "supply-name" set to  "qcom,cdc-vdd-buck", "qcom,cdc-vdd-tx-h",
-     "qcom,cdc-vdd-rx-h", "qcom,cdc-vddpx-1", "qcom,cdc-vdd-a-1p2v", "qcom,cdc-vddcx-1",
-     "qcom,cdc-vddcx-2" should be present.
+    above three properties with "supply-name" set to  "qcom,cdc-vdd-buck",
+    "qcom,cdc-vdd-tx-h", "qcom,cdc-vdd-rx-h", "qcom,cdc-vddpx-1",
+    "qcom,cdc-vdd-a-1p2v", "qcom,cdc-vddcx-1", "qcom,cdc-vddcx-2"
+    should be present.
 
- - qcom,cdc-micbias-ldoh-v - LDOH output in volts ( should be 1.95 V and 3.00 V).
+ - qcom,cdc-micbias-ldoh-v - LDOH output in volts (should be 1.95 V and 3.00 V).
 
  - qcom,cdc-micbias-cfilt1-mv - cfilt1 output voltage in milli volts.
  - qcom,cdc-micbias-cfilt2-mv - cfilt2 output voltage in milli volts.
  - qcom,cdc-micbias-cfilt3-mv - cfilt3 output voltage in milli volts.
    cfilt voltage can be set to max of qcom,cdc-micbias-ldoh-v - 0.15V.
 
- - qcom,cdc-micbias1-cfilt-sel = cfilt to use for micbias1 (should be from 1 to 3).
- - qcom,cdc-micbias2-cfilt-sel = cfilt to use for micbias2 (should be from 1 to 3).
- - qcom,cdc-micbias3-cfilt-sel = cfilt to use for micbias3 (should be from 1 to 3).
- - qcom,cdc-micbias4-cfilt-sel = cfilt to use for micbias4 (should be from 1 to 3).
+ - qcom,cdc-micbias1-cfilt-sel = cfilt to use for micbias1
+     (should be from 1 to 3).
+ - qcom,cdc-micbias2-cfilt-sel = cfilt to use for micbias2
+     (should be from 1 to 3).
+ - qcom,cdc-micbias3-cfilt-sel = cfilt to use for micbias3
+     (should be from 1 to 3).
+ - qcom,cdc-micbias4-cfilt-sel = cfilt to use for micbias4
+     (should be from 1 to 3).
    This value represents the connected CFLIT to MIC Bias.
 
  - qcom,cdc-micbias1-ext-cap: Boolean. Enable micbias 1 external capacitor mode.
  - qcom,cdc-micbias2-ext-cap: Boolean. Enable micbias 2 external capacitor mode.
  - qcom,cdc-micbias3-ext-cap: Boolean. Enable micbias 3 external capacitor mode.
  - qcom,cdc-micbias4-ext-cap: Boolean. Enable micbias 4 external capacitor mode.
- - qcom,cdc-mclk-clk-rate - Specifies the master clock rate in Hz required for codec.
+ - qcom,cdc-mclk-clk-rate - Specifies the master clock rate in Hz required for
+			    codec.
 
 Example:
 i2c@f9925000 {
@@ -143,7 +155,8 @@
 		reg = <0x0d>;
 		qcom,cdc-reset-gpio = <&msmgpio 22 0>;
 		interrupt-parent = <&wcd9xxx_intc>;
-		interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28>;
+		interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
+			      20 21 22 23 24 25 26 27 28>;
 
 		cdc-vdd-buck-supply = <&pm8019_l11>;
 		qcom,cdc-vdd-buck-voltage = <1800000 1800000>;
diff --git a/Documentation/devicetree/bindings/spi/spi_qsd.txt b/Documentation/devicetree/bindings/spi/spi_qsd.txt
index 939f77b..4b912f3 100644
--- a/Documentation/devicetree/bindings/spi/spi_qsd.txt
+++ b/Documentation/devicetree/bindings/spi/spi_qsd.txt
@@ -1,25 +1,51 @@
 Qualcomm Serial Peripheral Interface (SPI)
 
 Required properties:
-- compatible : should be "qcom,spi-qup-v2".
-- reg : offset and length of the QUP register map.
-- interrupts : should contain the QUP core interrupt.
-- spi-max-frequency : specifies maximum SPI clock frequency, Units - Hz.
+- compatible : Should be "qcom,spi-qup-v2".
+- reg : Offset and length of the register regions for the device
+- reg-names : Register region names referenced in reg above.
+	Required register resource entries are:
+	"spi_physical" : Physical address of controller register blocks.
+- interrupts : Interrupt numbers used by this controller
+- interrupt-names : Interrupt resource names referenced in interrupts above.
+	Required interrupt resource entries are:
+	"spi_irq" : QUP-core interrupt.
+- spi-max-frequency : Specifies maximum SPI clock frequency, Units - Hz.
+
+Required alias:
+- The desired bus-number is specified via an alias with the following format
+	'spi{n}' where n is the bus number.
 
 Optional properties:
-- gpios : specifies the gpio pins to be used for SPI CLK, MISO, MOSI in
+- gpios : Specifies the gpio pins to be used for SPI CLK, MISO, MOSI in
   that order.
-- cs-gpios : specifies the gpio pins to be used for chipselects.
+- cs-gpios : Specifies the gpio pins to be used for chipselects.
+- qcom,infinite-mode: When missing or set to zero, QUP uses infinite-mode. When
+  value is non-zero, the value is the number of words in maximum transfer
+  length.
 
-SPI slave nodes must be children of the SPI master node and contain
+Optional properties which are required for support of BAM-mode:
+- qcom,ver-reg-exists : Boolean. When present, allows driver to verify if HW
+  version support latest features (e.g. BAM) and then enable them. Should be
+  removed for legacy HW.
+- qcom,use-bam : Boolean. When present, enables BAM-mode.
+- qcom,bam-consumer-pipe-index : BAM consumer-pipe index.
+- qcom,bam-producer-pipe-index : BAM producer-pipe index.
+- reg-names : register region names referenced in reg.
+	Required register resource for BAM are:
+	"spi_bam_physical" : Physical address of BAM for this controller.
+- interrupt-names : interrupt resource names referenced in interrupts.
+	Required interrupt resource from BAM are:
+	"spi_bam_irq" : BAM interrupt used by the controller.
+
+Optional SPI slave nodes must be children of the SPI master node and contain
 the following properties.
-- reg : (required) chip select address of device.
-- compatible : (required) name of SPI device following generic names
-  recommended practice
+- reg: (required) chip-select address of the device.
+- compatible : (required) Name of SPI device following generic names.
 - spi-max-frequency : (required) Maximum SPI clocking speed of device in Hz
-- interrupts : (recommended) should contain the SPI slave interrupt number
+- interrupts : (recommended) Should contain the SPI slave interrupt number
   encoded depending on the type of the interrupt controller.
-- interrupt-parent : (recommended) the phandle for the interrupt controller
+- interrupt-parent : (recommended) The phandle for the interrupt controller
   that services interrupts for this device.
 - spi-cpol : (optional) Empty property indicating device requires inverse
   clock polarity (CPOL) mode
@@ -29,18 +55,30 @@
   chip select active high
 
 Example:
-	spi@f9924000 {
-		compatible = "qcom,spi-qup-v2";
-		reg = <0xf9924000 0x1000>;
-		interrupts = <0 96 0>;
-		spi-max-frequency = <24000000>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		device@0 {
-			compatible = "spidev";
-			reg = <0>;
-			spi-max-frequency = <5000000>;
-		};
+	aliases {
+		spi0 = &spi_0;
 	};
 
+	spi_0: spi@f9923000 {
+		compatible = "qcom,spi-qup-v2";
+
+		reg-names = "spi_physical", "spi_bam_physical";
+		reg = <0xf9923000 0x1000>,
+			<0xf9904000 0x10000>;
+		interrupt-names = "spi_irq", "spi_bam_irq";
+		interrupts = <0 95 0>, <0 238 0>;
+
+		spi-max-frequency = <19200000>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		gpios = <&msmgpio 3 0>, /* CLK  */
+			<&msmgpio 1 0>, /* MISO */
+			<&msmgpio 0 0>; /* MOSI */
+		cs-gpios = <&msmgpio 9 0>;
+
+		qcom,infinite-mode = <0>;
+		qcom,use-bam;
+		qcom,bam-consumer-pipe-index = <12>;
+		qcom,bam-producer-pipe-index = <13>;
+		qcom,ver-reg-exists;
+	};
diff --git a/Documentation/devicetree/bindings/spmi/spmi-pmic-arb.txt b/Documentation/devicetree/bindings/spmi/spmi-pmic-arb.txt
index 63c1e87..dc0e00b 100644
--- a/Documentation/devicetree/bindings/spmi/spmi-pmic-arb.txt
+++ b/Documentation/devicetree/bindings/spmi/spmi-pmic-arb.txt
@@ -3,43 +3,30 @@
 Required properties:
 - cell-index : the bus identifier.
 - compatible : should be "qcom,spmi-pmic-arb".
+- reg-names  : should be "core", "intr", "cnfg"
 - reg : offset and length of the PMIC Arbiter Core register map.
 - reg : offset and length of the PMIC Arbiter Interrupt controller register map.
+- reg : offset and length of the PMIC Arbiter Configuration register map.
 - interrupts : the PMIC Arbiter interrupt.
 - qcom,pmic-arb-ee : the execution environment (EE) identifier.
 - qcom,pmic-arb-channel : the assigned channel number for channel registers.
-- qcom,pmic-arb-ppid-map : an array used to map a 12-bit PPID to 8-bit APID.
 
 Optional properties:
 - qcom,not-wakeup : boolean property which indicates that SPMI PMIC interrupts
 	should not be treated as wakeup sources
 
-Peripherals on the SPMI bus are identified with a 12-bit identifier (PPID)
-which is composed of a 4-bit slave address and an 8-bit peripheral identifier.
-The PMIC Arbiter hardware uses an 8-bit APID (Arbiter Peripheral Identifier)
-internally.  Software needs the mapping between the APID and the PPID.
-Up to a maximum of 256 peripherals are supported and the mapping is target
-specific.
-
-Data format of pmic-arb-ppid-map:
-<0x13100001>
-value is 32 bit.
-MSB 12 bits are the PPID
-12 bits padding
-LSB 8 bit are the APID
-
 Example:
 
 	qcom,spmi@fc4c0000 {
 		cell-index = <0>;
 		compatible = "qcom,spmi-pmic-arb";
+		reg-names = "core", "intr", "cnfg";
 		reg = <0xfc4cf000 0x1000>,
-		      <0Xfc4cb000 0x1000>;
+		      <0Xfc4cb000 0x1000>,
+		      <0Xfc4ca000 0x1000>;
 		interrupts = <0>;
 		qcom,pmic-arb-ee = <0>;
 		qcom,pmic-arb-channel = <0>;
-		qcom,pmic-arb-ppid-map = <0x13000000>, /* PPID 0x130, APID 0 */
-					 <0x13100001>, /* PPID 0x131, APID 1 */
 	};
 
 
diff --git a/Documentation/devicetree/bindings/thermal/tsens.txt b/Documentation/devicetree/bindings/thermal/tsens.txt
index 0682cd1..67a986b 100644
--- a/Documentation/devicetree/bindings/thermal/tsens.txt
+++ b/Documentation/devicetree/bindings/thermal/tsens.txt
@@ -29,6 +29,11 @@
 	       sensor used to compute the offset. Slope is represented
 	       as ADC code/DegC and the value is multipled by a factor
 	       of 1000.
+- qcom,calib-mode : Calibration masks to use to abstract the offset data from efuse.
+		    Select from the following strings.
+		    "fuse_map1" : Used for 8974/9x25 fuse calibration map.
+		    "fuse_map2" : Used for 8x26 fuse calibration map.
+		    "fuse_map3" : Used for 8x10 fuse calibration map.
 
 Optional properties:
 - qcom,calibration-less-mode : If present the pre-characterized data for offsets
@@ -45,6 +50,7 @@
 	interrupts = <0 184 0>;
 	qcom,calibration-less-mode;
 	qcom,sensors = <11>;
-	qcom,slope = <1134 1122 1142 1123 1176 1176 1176 1186 1176
-			1176>;
+	qcom,slope = <3200 3200 3200 3200 3200 3200 3200 3200 3200
+			3200>;
+	qcom,calib-mode = "fuse_map1";
 };
diff --git a/Documentation/devicetree/bindings/tty/serial/msm_serial.txt b/Documentation/devicetree/bindings/tty/serial/msm_serial.txt
index ae7d736..5861eea 100644
--- a/Documentation/devicetree/bindings/tty/serial/msm_serial.txt
+++ b/Documentation/devicetree/bindings/tty/serial/msm_serial.txt
@@ -34,6 +34,23 @@
 - reg : offset and length of the register set for the device.
 - interrupts : should contain the uart interrupt.
 
+Optional properties:
+- qcom,config-gpio : Set this value if UART GPIOs need to be configured by driver.
+set 4 if 4-wire UART used (for Tx, Rx, CTS, RFR GPIOs).
+Set 1 if 2-wire UART used (for Tx, Rx GPIOs).
+- qcom,<gpio-name>-gpio : handle to the GPIO node, see "gpios property" in
+Documentation/devicetree/bindings/gpio/gpio.txt.
+"gpio-name" can be "tx", "rx", "cts" and "rfr" based on number of UART GPIOs
+need to configured.
+qcom,use-pm : If present, this property will cause the device to prevent system
+suspend as long as the port remains open.
+- Refer to "Documentation/devicetree/bindings/arm/msm/msm_bus.txt" for below properties:
+    - qcom,msm_bus,name
+    - qcom,msm_bus,num_cases
+    - qcom,msm_bus,active_only
+    - qcom,msm_bus,num_paths
+    - qcom,msm_bus,vectors
+
 Aliases:
 An alias may optionally be used to bind the serial device to a tty device
 (ttyHSLx) with a given line number. Aliases are of the form serial<n> where <n>
@@ -50,4 +67,19 @@
 		compatible = "qcom,msm-lsuart-v14"
 		reg = <0x19c40000 0x1000">;
 		interrupts = <195>;
+
+		qcom,config-gpio = <4>;
+		qcom,tx-gpio = <&msmgpio 41 0x00>;
+		qcom,rx-gpio = <&msmgpio 42 0x00>;
+		qcom,cts-gpio = <&msmgpio 43 0x00>;
+		qcom,rfr-gpio = <&msmgpio 44 0x00>;
+		qcom,use-pm;
+
+		qcom,msm-bus,name = "serial_uart0";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,active-only = <0>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<84 512 0 0>,
+				<84 512 500 800>;
 	};
diff --git a/Documentation/devicetree/bindings/tty/serial/msm_serial_hs.txt b/Documentation/devicetree/bindings/tty/serial/msm_serial_hs.txt
new file mode 100644
index 0000000..c597536
--- /dev/null
+++ b/Documentation/devicetree/bindings/tty/serial/msm_serial_hs.txt
@@ -0,0 +1,101 @@
+* Qualcomm MSM HSUART
+
+Required properties:
+- compatible :
+	- "qcom,msm-hsuart-v14" to be used for UARTDM Core v1.4
+- reg : offset and length of the register set for both the device,
+	uart core and bam core
+- reg-names :
+	- "core_mem" to be used as name of the uart core
+	- "bam_mem" to be used as name of the bam core
+- interrupts : interrupts for both the device,uart core and bam core
+- interrupt-names :
+	- "core_irq" to be used as uart irq
+	- "bam irq" to be used as bam irq
+- bam-tx-ep-pipe-index : BAM TX Endpoint Pipe Index for HSUART
+- bam-rx-ep-pipe-index : BAM RX Endpoint Pipe Index for HSUART
+
+BLSP has a static pipe allocation and assumes a pair-pipe for each uart core.
+Pipes [2*i : 2*i+1] are allocated for UART cores where i = [0 : 5].
+Hence, Minimum and Maximum permitted value of endpoint pipe index to be used
+with uart core is 0 and 11 respectively.
+
+There is one HSUART block used in MSM devices,
+"qcom,msm-hsuart-v14". The msm-serial-hs driver is
+able to handle this, and matches against the "qcom,msm-hsuart-v14"
+as the compatibility.
+
+The registers for the "qcom,msm-hsuart-v14" device need to specify both
+register blocks - uart core and bam core.
+
+Example:
+
+	uart7: uart@f995d000 {
+		compatible = "qcom,msm-hsuart-v14";
+		reg = <0xf995d000 0x1000>,
+		      <0xf9944000 0x5000>;
+		reg-names = "core_mem", "bam_mem";
+		interrupts = <0 113 0>, <0 239 0>;
+		interrupt-names = "core_irq", "bam_irq";
+		qcom,bam-tx-ep-pipe-index = <0>;
+		qcom,bam-rx-ep-pipe-index = <1>;
+	};
+
+Optional properties:
+- qcom,<gpio-name>-gpio : handle to the GPIO node, see "gpios property" in
+Documentation/devicetree/bindings/gpio/gpio.txt.
+"gpio-name" can be "tx", "rx", "cts" and "rfr" based on number of UART GPIOs
+need to configured.
+Gpio's are optional if it is required to be not configured by UART driver or
+case where there is nothing connected and we want to use internal loopback mode
+for uart.
+- qcom, wakeup_irq : UART RX GPIO IRQ line to be configured as wakeup source.
+- qcom,inject_rx_on_wakeup : inject_rx_on_wakeup enables feature where on
+receiving interrupt with UART RX GPIO IRQ line (i.e. above wakeup_irq property),
+HSUART driver injects provided character with property rx_to_inject.
+- qcom, rx_to_inject : The character to be inserted on wakeup.
+- Refer to "Documentation/devicetree/bindings/arm/msm/msm_bus.txt" for
+below optional properties:
+    - qcom,msm_bus,name
+    - qcom,msm_bus,num_cases
+    - qcom,msm_bus,active_only
+    - qcom,msm_bus,num_paths
+    - qcom,msm_bus,vectors
+
+Aliases :
+An alias may be optionally used to bind the UART device to a TTY device
+(ttyHS<alias_num>) with a given alias number. Aliases are of the form
+uart<n> where <n> is an integer representing the alias number to use.
+On systems with multiple UART devices present, an alias may optionally be
+defined for such devices. The alias value should be from 0 to 255.
+
+Example:
+
+	aliases {
+		uart4 = &uart7; // This device will be enumerated as ttyHS4
+	};
+
+	uart7: uart@f995d000 {
+		compatible = "qcom,msm-hsuart-v14"
+		reg = <0x19c40000 0x1000">,
+		      <0xf9944000 0x5000>;
+		reg-names = "core_mem", "bam_mem";
+		interrupts = <0 113 0>, <0 239 0>;
+		interrupt-names = "core_irq", "bam_irq";
+
+		qcom,tx-gpio = <&msmgpio 41 0x00>;
+		qcom,rx-gpio = <&msmgpio 42 0x00>;
+		qcom,cts-gpio = <&msmgpio 43 0x00>;
+		qcom,rfr-gpio = <&msmgpio 44 0x00>;
+
+		qcom,bam-tx-ep-pipe-index = <0>;
+		qcom,bam-rx-ep-pipe-index = <1>;
+
+		qcom,msm-bus,name = "uart7";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,active-only = <0>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<84 512 0 0>,
+				<84 512 500 800>;
+	};
diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
index 015822f..2cdc7ff 100644
--- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
@@ -47,6 +47,18 @@
     - qcom,msm_bus,active_only
     - qcom,msm_bus,num_paths
     - qcom,msm_bus,vectors
+- qcom,hsusb-otg-lpm-on-dev-suspend: If present then USB enter to
+	    low power mode upon receiving bus suspend.
+- qcom,hsusb-otg-clk-always-on-workaround: If present then USB core clocks
+	    remain active upon receiving bus suspend and USB cable is connected.
+	    Used for allowing USB to respond for remote wakup.
+- <supply-name>-supply: handle to the regulator device tree node
+         Required "supply-name" is "HSUSB_VDDCX" (when voting for VDDCX) or
+         "hsusb_vdd_dig" (when voting for VDDCX Corner voltage),
+         "HSUSB_1p8-supply" and "HSUSB_3p3-supply".
+- qcom,vdd-voltage-level: This property must be a list of three integer
+	values (no, min, max) where each value represents either a voltage
+	in microvolts or a value corresponding to voltage corner.
 
 Example HSUSB OTG controller device node :
 	usb@f9690000 {
@@ -65,6 +77,12 @@
 		qcom,hsusb-otg-power-budget = <500>;
 		qcom,hsusb-otg-pclk-src-name = "dfab_usb_clk";
 		qcom,hsusb-otg-pmic-id-irq = <47>
+		qcom,hsusb-otg-lpm-on-dev-suspend;
+		qcom,hsusb-otg-clk-always-on-workaround;
+		hsusb_vdd_dig-supply = <&pm8226_s1_corner>;
+                HSUSB_1p8-supply = <&pm8226_l10>;
+                HSUSB_3p3-supply = <&pm8226_l20>;
+		qcom,vdd-voltage-level = <1 5 7>;
 
 		qcom,msm_bus,name = "usb2";
 		qcom,msm_bus,num_cases = <2>;
@@ -75,6 +93,34 @@
 				<87 512 60000000 960000000>;
 	};
 
+MSM HSUSB EHCI controller
+
+Required properties :
+- compatible : should be "qcom,ehci-host"
+- reg : offset and length of the register set in the memory map
+- interrupts: IRQ lines used by this controller
+- interrupt-names : Required interrupt resource entries are:
+            HSUSB EHCI expects "core_irq" and optionally "async_irq".
+- <supply-name>-supply: handle to the regulator device tree node
+  Required "supply-name" is "HSUSB_VDDCX" "HSUSB_1p8-supply" "HSUSB_3p3-supply".
+- qcom,usb2-power-budget: maximum vbus power (in mA) that can be provided.
+
+Optional properties :
+- qcom,usb2-enable-hsphy2: If present, select second PHY for USB operation.
+
+Example MSM HSUSB EHCI controller device node :
+	ehci: qcom,ehci-host@f9a55000 {
+		compatible = "qcom,ehci-host";
+		reg = <0xf9a55000 0x400>;
+		interrupts = <0 134 0>, <0 140 0>;
+		interrupt-names = "core_irq", "async_irq";
+		HSUSB_VDDCX-supply = <&pm8841_s2>;
+		HSUSB_1p8-supply = <&pm8941_l6>;
+		HSUSB_3p3-supply = <&pm8941_l24>;
+		qcom,usb2-enable-hsphy2;
+		qcom,usb2-power-budget = <500>;
+	};
+
 ANDROID USB:
 
 Required properties:
@@ -147,9 +193,15 @@
 - qcom,descriptor-fifo-offset: descriptor fifo offset address
 - qcom,descriptor-fifo-size: descriptor fifo size
 
+Optional Properties for Subnode:
+- qcom,reset-bam-on-connect: If present then BAM is RESET before connecting
+  pipe. This may be required if BAM peripheral is also reset before connect.
+
 Optional properties :
 - qcom,ignore-core-reset-ack: If present then BAM ignores ACK from USB core
 	    while performing PIPE RESET
+- qcom,disable-clk-gating: If present then disable BAM clock gating.
+
 
 Example USB BAM controller device node:
 
@@ -193,6 +245,7 @@
 			qcom,data-fifo-size = <0x4000>;
 			qcom,descriptor-fifo-offset = <0xf4000>;
 			qcom,descriptor-fifo-size = <0x1400>;
+			qcom,reset-bam-on-connect;
 		};
 
 		qcom,pipe3 {
diff --git a/Documentation/devicetree/bindings/usb/msm-ssusb.txt b/Documentation/devicetree/bindings/usb/msm-ssusb.txt
index d686523..7add91f 100644
--- a/Documentation/devicetree/bindings/usb/msm-ssusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-ssusb.txt
@@ -40,6 +40,13 @@
   otherwise depend on PHY.
 - qcom,charging-disabled: If present then battery charging using USB
   is disabled.
+- qcom,dwc-hsphy-init: This property if present represents phy init
+  value to be used for overriding HSPHY parameters into QSCRATCH register.
+  This 32 bit value represents parameters as follows:
+		bits 0-5   PARAMETER_OVERRIDE_A
+		bits 6-12  PARAMETER_OVERRIDE_B
+		bits 13-19 PARAMETER_OVERRIDE_C
+		bits 20-25 PARAMETER_OVERRIDE_D
 
 Example MSM USB3.0 controller device node :
 	usb@f9200000 {
@@ -56,6 +63,7 @@
 		vbus_dwc3-supply = <&pm8941_mvs1>;
 		qcom,dwc-usb3-msm-dbm-eps = <4>
 		qcom,vdd-voltage-level = <1 5 7>;
+		qcom,dwc-hsphy-init = <0x00D195A4>;
 
 		qcom,msm_bus,name = "usb3";
 		qcom,msm_bus,num_cases = <2>;
diff --git a/Documentation/mmc/mmc-dev-attrs.txt b/Documentation/mmc/mmc-dev-attrs.txt
index 43453d0..d96b431 100644
--- a/Documentation/mmc/mmc-dev-attrs.txt
+++ b/Documentation/mmc/mmc-dev-attrs.txt
@@ -25,14 +25,14 @@
 	running parallel lmdd write and lmdd read operations and calculating
 	the max number of packed writes requests.
 
-	min_sectors_to_check_bkops_status	This attribute is used to
-	determine whether the status bit that indicates the need for BKOPS
-	should be checked. The value is stored in this attribute represents
-	the minimum number of sectors that needs to be changed in the device
-	(written or discarded) in order to require the status-bit of BKOPS
-	to be checked. The value can modified via sysfs by writing the
-	required value to:
-	/sys/block/<block_dev_name>/min_sectors_to_check_bkops_status
+	bkops_check_threshold	This attribute is used to determine whether
+	the status bit that indicates the need for BKOPS should be checked.
+	The value should be given in percentages of the card size.
+	This value is used to calculate the minimum number of sectors that
+	needs to be changed in the device (written or discarded) in order to
+	require the status-bit of BKOPS to be checked.
+	The value can modified via sysfs by writing the required value to:
+	/sys/block/<block_dev_name>/bkops_check_threshold
 
 SD and MMC Device Attributes
 ============================
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 5aecb48..2d4a6db 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -1098,6 +1098,11 @@
 	Functional default: enabled if accept_ra is enabled.
 			    disabled if accept_ra is disabled.
 
+accept_ra_prefix_route - BOOLEAN
+	Set the prefix route for the autoconfigured interface address
+
+	Functional default: enabled
+
 accept_redirects - BOOLEAN
 	Accept Redirects.
 
diff --git a/Documentation/printk-formats.txt b/Documentation/printk-formats.txt
index 5df176e..6f53742 100644
--- a/Documentation/printk-formats.txt
+++ b/Documentation/printk-formats.txt
@@ -53,6 +53,14 @@
 	For printing struct resources. The 'R' and 'r' specifiers result in a
 	printed resource with ('R') or without ('r') a decoded flags member.
 
+Physical addresses:
+
+	%pa	0x01234567 or 0x0123456789abcdef
+
+	For printing a phys_addr_t type (and its derivatives, such as
+	resource_size_t) which can vary based on build options, regardless of
+	the width of the CPU data path. Passed by reference.
+
 MAC/FDDI addresses:
 
 	%pM	00:01:02:03:04:05
@@ -134,9 +142,9 @@
 	printk("%lld", (long long)s64_var);
 
 If <type> is dependent on a config option for its size (e.g., sector_t,
-blkcnt_t, phys_addr_t, resource_size_t) or is architecture-dependent
-for its size (e.g., tcflag_t), use a format specifier of its largest
-possible type and explicitly cast to it.  Example:
+blkcnt_t) or is architecture-dependent for its size (e.g., tcflag_t), use a
+format specifier of its largest possible type and explicitly cast to it.
+Example:
 
 	printk("test: sector number/total blocks: %llu/%llu\n",
 		(unsigned long long)sector, (unsigned long long)blockcount);
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 53fd3b2..2f686fa 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -782,6 +782,7 @@
 	select HAVE_CLK_PREPARE
 	select NEED_MACH_MEMORY_H
 	select NEED_MACH_IO_H
+	select SOC_BUS
 	help
 	  Support for Qualcomm MSM/QSD based systems.  This runs on the
 	  apps processor of the MSM/QSD and depends on a shared memory
@@ -1808,7 +1809,7 @@
 config OABI_COMPAT
 	bool "Allow old ABI binaries to run with this kernel (EXPERIMENTAL)"
 	depends on AEABI && EXPERIMENTAL && !THUMB2_KERNEL
-	default y
+	default y if !SMP
 	help
 	  This option preserves the old syscall interface along with the
 	  new (ARM EABI) one. It also provides a compatibility layer to
@@ -2048,7 +2049,7 @@
 	  Provide support for Coprocessor register access using /sys
 	  interface. Read and write to CP registers from userspace
 	  through sysfs interface. A sys file (cp_rw) will be created under
-	  /sys/devices/system/cpaccess/cpaccess0.
+	  /sys/devices/cpaccess/cpaccess0.
 
 	  If unsure, say N.
 
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index ed18cae..3a9b770 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -63,27 +63,6 @@
 	      8 - SIGSEGV faults
 	     16 - SIGBUS faults
 
-config DEBUG_RODATA
-	bool "Write protect kernel text section"
-	default n
-	depends on DEBUG_KERNEL && MMU
-	---help---
-	  Mark the kernel text section as write-protected in the pagetables,
-	  in order to catch accidental (and incorrect) writes to such const
-	  data. This will cause the size of the kernel, plus up to 4MB, to
-	  be mapped as pages instead of sections, which will increase TLB
-	  pressure.
-	  If in doubt, say "N".
-
-config DEBUG_RODATA_TEST
-	bool "Testcase for the DEBUG_RODATA feature"
-	depends on DEBUG_RODATA
-	default n
-	---help---
-	  This option enables a testcase for the DEBUG_RODATA
-	  feature.
-	  If in doubt, say "N"
-
 # These options are only for real kernel hackers who want to get their hands dirty.
 config DEBUG_LL
 	bool "Kernel low-level debugging functions (read help!)"
diff --git a/arch/arm/boot/dts/dsi-panel-orise-720p-video.dtsi b/arch/arm/boot/dts/dsi-panel-orise-720p-video.dtsi
new file mode 100644
index 0000000..7bd95e7
--- /dev/null
+++ b/arch/arm/boot/dts/dsi-panel-orise-720p-video.dtsi
@@ -0,0 +1,60 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/ {
+	qcom,mdss_dsi_orise_720p_video {
+		compatible = "qcom,mdss-dsi-panel";
+		label = "orise 720p video mode dsi panel";
+		status = "disable";
+		qcom,dsi-ctrl-phandle = <&mdss_dsi1>;
+		qcom,mdss-pan-res = <720 1280>;
+		qcom,mdss-pan-bpp = <24>;
+		qcom,mdss-pan-dest = "display_2";
+		qcom,mdss-pan-porch-values = <32 12 144 3 4 9>;
+		qcom,mdss-pan-underflow-clr = <0xff>;
+		qcom,mdss-pan-bl-levels = <1 255>;
+		qcom,mdss-pan-dsi-mode = <0>;
+		qcom,mdss-pan-dsi-h-pulse-mode = <0>;
+		qcom,mdss-pan-dsi-h-power-stop = <0 0 0>;
+		qcom,mdss-pan-dsi-bllp-power-stop = <1 1>;
+		qcom,mdss-pan-dsi-traffic-mode = <1>;
+		qcom,mdss-pan-dsi-dst-format = <3>;
+		qcom,mdss-pan-dsi-vc = <0>;
+		qcom,mdss-pan-dsi-rgb-swap = <0>;
+		qcom,mdss-pan-dsi-data-lanes = <1 1 1 1>;
+		qcom,mdss-pan-dsi-dlane-swap = <0>;
+		qcom,mdss-pan-dsi-t-clk = <0x1b 0x04>;
+		qcom,mdss-pan-dsi-stream = <0>;
+		qcom,mdss-pan-dsi-mdp-tr = <0x0>;
+		qcom,mdss-pan-dsi-dma-tr = <0x04>;
+		qcom,mdss-pan-frame-rate = <60>;
+		qcom,panel-phy-regulatorSettings = [03 01 01 00  /* Regualotor settings */
+						    20 00 01];
+		qcom,panel-phy-timingSettings = [69 29 1f 00 55 55
+						    19 2a 2a 03 04 00];
+		qcom,panel-phy-strengthCtrl = [77 06];
+		qcom,panel-phy-bistCtrl = [00 00 b1 ff           /* BIST Ctrl settings */
+					   00 00];
+		qcom,panel-phy-laneConfig = [00 c2 45 00 00 00 00 01 75 /* lane0 config */
+					     00 c2 45 00 00 00 00 01 75 /* lane1 config */
+					     00 c2 45 00 00 00 00 01 75 /* lane2 config */
+					     00 c2 45 00 00 00 00 01 75 /* lane3 config */
+					     00 02 45 00 00 00 00 01 97]; /* Clk ln config */
+
+		qcom,panel-on-cmds = [05 01 00 00 78 02 11 00
+					05 01 00 00 78 02 29 00];
+		qcom,on-cmds-dsi-state = "DSI_LP_MODE";
+		qcom,panel-off-cmds = [05 01 00 00 32 02 28 00
+					05 01 00 00 78 02 10 00];
+		qcom,off-cmds-dsi-state = "DSI_LP_MODE";
+	};
+};
diff --git a/arch/arm/boot/dts/dsi-panel-sim-video.dtsi b/arch/arm/boot/dts/dsi-panel-sim-video.dtsi
index 1e5c26c..98074c8 100644
--- a/arch/arm/boot/dts/dsi-panel-sim-video.dtsi
+++ b/arch/arm/boot/dts/dsi-panel-sim-video.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -10,14 +10,16 @@
  * GNU General Public License for more details.
  */
 
-&mdss_dsi {
+/ {
 
 	qcom,mdss_dsi_sim_video {
 		compatible = "qcom,mdss-dsi-panel";
 		label = "simulator video mode dsi panel";
 		status = "disable";
+		qcom,dsi-ctrl-phandle = <&mdss_dsi0>;
 		qcom,mdss-pan-res = <640 480>;
 		qcom,mdss-pan-bpp = <24>;
+		qcom,mdss-pan-dest = "display_1";
 		qcom,mdss-pan-porch-values = <6 2 6 6 2 6>;
 		qcom,mdss-pan-underflow-clr = <0xff>;
 		qcom,mdss-pan-bl-levels = <1 15>;
@@ -30,12 +32,15 @@
 		qcom,mdss-pan-dsi-vc = <0>;
 		qcom,mdss-pan-dsi-rgb-swap = <0>;
 		qcom,mdss-pan-dsi-data-lanes = <1 1 0 0>;
+		qcom,mdss-pan-dsi-dlane-swap = <0>;
 		qcom,mdss-pan-dsi-t-clk = <0x24 0x03>;
 		qcom,mdss-pan-dsi-stream = <0>;
 		qcom,mdss-pan-dsi-mdp-tr = <0x04>;
 		qcom,mdss-pan-dsi-dma-tr = <0x04>;
 		qcom,mdss-pan-frame-rate = <60>;
 		qcom,panel-on-cmds = [32 01 00 00 00 02 00 00];
+		qcom,on-cmds-dsi-state = "DSI_LP_MODE";
 		qcom,panel-off-cmds = [22 01 00 00 00 02 00 00];
+		qcom,off-cmds-dsi-state = "DSI_LP_MODE";
 	};
 };
diff --git a/arch/arm/boot/dts/dsi-panel-toshiba-720p-video.dtsi b/arch/arm/boot/dts/dsi-panel-toshiba-720p-video.dtsi
index 7731b33..1c3cf29 100644
--- a/arch/arm/boot/dts/dsi-panel-toshiba-720p-video.dtsi
+++ b/arch/arm/boot/dts/dsi-panel-toshiba-720p-video.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -10,16 +10,18 @@
  * GNU General Public License for more details.
  */
 
-&mdss_dsi {
+/ {
 
 	qcom,mdss_dsi_toshiba_720p_video {
 		compatible = "qcom,mdss-dsi-panel";
 		label = "toshiba 720p video mode dsi panel";
 		status = "disable";
+		qcom,dsi-ctrl-phandle = <&mdss_dsi0>;
 		qcom,enable-gpio = <&msmgpio 58 0>;
 		qcom,rst-gpio = <&pm8941_gpios 19 0>;
 		qcom,mdss-pan-res = <720 1280>;
 		qcom,mdss-pan-bpp = <24>;
+		qcom,mdss-pan-dest = "display_1";
 		qcom,mdss-pan-porch-values = <32 12 144 3 4 9>;
 		qcom,mdss-pan-underflow-clr = <0xff>;
 		qcom,mdss-pan-bl-ctrl = "bl_ctrl_wled";
@@ -33,23 +35,24 @@
 		qcom,mdss-pan-dsi-vc = <0>;
 		qcom,mdss-pan-dsi-rgb-swap = <0>;
 		qcom,mdss-pan-dsi-data-lanes = <1 1 1 1>;
+		qcom,mdss-pan-dsi-dlane-swap = <0>;
 		qcom,mdss-pan-dsi-t-clk = <0x1b 0x04>;
 		qcom,mdss-pan-dsi-stream = <0>;
 		qcom,mdss-pan-dsi-mdp-tr = <0x0>;
 		qcom,mdss-pan-dsi-dma-tr = <0x04>;
 		qcom,mdss-pan-frame-rate = <60>;
-		qcom,panel-phy-regulatorSettings = [03 01 01 00  /* Regualotor settings */
+		qcom,panel-phy-regulatorSettings = [07 09 03 00  /* Regualotor settings */
 						    20 00 01];
-		qcom,panel-phy-timingSettings = [69 29 1f 00 55 55
-						    19 2a 2a 03 04 00];
-		qcom,panel-phy-strengthCtrl = [77 06];
+		qcom,panel-phy-timingSettings = [b0 23 1b 00 94 93
+						    1e 25 15 03 04 00];
+		qcom,panel-phy-strengthCtrl = [ff 06];
 		qcom,panel-phy-bistCtrl = [00 00 b1 ff           /* BIST Ctrl settings */
 					   00 00];
-		qcom,panel-phy-laneConfig = [00 c2 45 00 00 00 00 01 75 /* lane0 config */
-					     00 c2 45 00 00 00 00 01 75 /* lane1 config */
-					     00 c2 45 00 00 00 00 01 75 /* lane2 config */
-					     00 c2 45 00 00 00 00 01 75 /* lane3 config */
-					     00 02 45 00 00 00 00 01 97]; /* Clk ln config */
+		qcom,panel-phy-laneConfig = [00 00 00 00 00 00 00 01 97 /* lane0 config */
+					     00 00 00 00 05 00 00 01 97 /* lane1 config */
+					     00 00 00 00 0a 00 00 01 97 /* lane2 config */
+					     00 00 00 00 0f 00 00 01 97 /* lane3 config */
+					     00 c0 00 00 00 00 00 01 bb]; /* Clk ln config */
 
 		qcom,panel-on-cmds = [23 01 00 00 0a 02 b0 00
 					23 01 00 00 0a 02 b2 00
@@ -113,7 +116,9 @@
 					23 01 00 00 0a 02 e2 00
 					05 01 00 00 78 02 11 00
 					05 01 00 00 32 02 29 00];
+		qcom,on-cmds-dsi-state = "DSI_LP_MODE";
 		qcom,panel-off-cmds = [05 01 00 00 32 02 28 00
 					05 01 00 00 78 02 10 00];
+		qcom,off-cmds-dsi-state = "DSI_HS_MODE";
 	};
 };
diff --git a/arch/arm/boot/dts/mpq8092-iommu.dtsi b/arch/arm/boot/dts/mpq8092-iommu.dtsi
index 6a88992..c6693e1 100644
--- a/arch/arm/boot/dts/mpq8092-iommu.dtsi
+++ b/arch/arm/boot/dts/mpq8092-iommu.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -10,7 +10,7 @@
  * GNU General Public License for more details.
  */
 
-/include/ "msm-iommu.dtsi"
+/include/ "msm-iommu-v1.dtsi"
 
 &jpeg_iommu {
 	status = "ok";
diff --git a/arch/arm/boot/dts/mpq8092.dtsi b/arch/arm/boot/dts/mpq8092.dtsi
index 0ab0a0c..75f168d 100644
--- a/arch/arm/boot/dts/mpq8092.dtsi
+++ b/arch/arm/boot/dts/mpq8092.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -35,7 +35,9 @@
 		interrupt-controller;
 		#interrupt-cells = <2>;
 		reg = <0xfd510000 0x4000>;
+		ngpio = <146>;
 		interrupts = <0 208 0>;
+		qcom,direct-connect-irqs = <8>;
 	};
 
 	timer {
@@ -61,174 +63,16 @@
 	spmi_bus: qcom,spmi@fc4c0000 {
 		cell-index = <0>;
 		compatible = "qcom,spmi-pmic-arb";
+		reg-names = "core", "intr", "cnfg";
 		reg = <0xfc4cf000 0x1000>,
-		      <0Xfc4cb000 0x1000>;
+		      <0Xfc4cb000 0x1000>,
+		      <0Xfc4ca000 0x1000>;
 		/* 190,ee0_krait_hlos_spmi_periph_irq */
 		/* 187,channel_0_krait_hlos_trans_done_irq */
 		interrupts = <0 190 0 0 187 0>;
 		qcom,not-wakeup;
 		qcom,pmic-arb-ee = <0>;
 		qcom,pmic-arb-channel = <0>;
-		qcom,pmic-arb-ppid-map = <0x00100000>, /* PM8644_0 */
-				 <0x10100001>, /* PM8644_1 */
-				 <0x00500002>, /* INTERRUPT */
-				 <0x00800003>, /* PON0 */
-				 <0x03000004>, /* ADC_1 */
-				 <0x03100005>, /* ADC_2 */
-				 <0x03200006>, /* ADC_3 */
-				 <0x03300007>, /* ADC_4 */
-				 <0x03400008>, /* ADC_5 */
-				 <0x03500009>, /* ADC_6 */
-				 <0x0360000a>, /* ADC_7 */
-				 <0x0370000b>, /* ADC_8 */
-				 <0x0500000c>, /* SHARED_XO */
-				 <0x0510000d>, /* BB_CLK1 */
-				 <0x0520000e>, /* BB_CLK2 */
-				 <0x05a0000f>, /* SLEEP_CLK */
-				 <0x06000010>, /* RTC_RW */
-				 <0x06100011>, /* RTC_ALARM */
-				 <0x07000012>, /* PBS_CORE */
-				 <0x07100013>, /* PBS_CLIENT_1 */
-				 <0x07200014>, /* PBS_CLIENT_2 */
-				 <0x07300015>, /* PBS_CLIENT_3 */
-				 <0x07400016>, /* PBS_CLIENT_4 */
-				 <0x07500017>, /* PBS_CLIENT_5 */
-				 <0x07600018>, /* PBS_CLIENT_6 */
-				 <0x07700019>, /* PBS_CLIENT_7 */
-				 <0x0780001a>, /* PBS_CLIENT_8 */
-				 <0x0790001b>, /* PBS_CLIENT_9 */
-				 <0x07a0001c>, /* PBS_CLIENT_10 */
-				 <0x07b0001d>, /* PBS_CLIENT_11 */
-				 <0x07c0001e>, /* PBS_CLIENT_12 */
-				 <0x07d0001f>, /* PBS_CLIENT_13 */
-				 <0x07e00020>, /* PBS_CLIENT_14 */
-				 <0x07f00021>, /* PBS_CLIENT_15 */
-				 <0x08000022>, /* PBS_CLIENT_16 */
-				 <0x0a000023>, /* MPP_1 */
-				 <0x0a100024>, /* MPP_2 */
-				 <0x0a200025>, /* MPP_3 */
-				 <0x0a300026>, /* MPP_4 */
-				 <0x0a400027>, /* MPP_5 */
-				 <0x0a500028>, /* MPP_6 */
-				 <0x0c000029>, /* PM8644_GPIO_1 */
-				 <0x0c10002a>, /* PM8644_GPIO_2 */
-				 <0x0c20002b>, /* PM8644_GPIO_3 */
-				 <0x0c30002c>, /* PM8644_GPIO_4 */
-				 <0x0c40002d>, /* PM8644_GPIO_5 */
-				 <0x0c50002e>, /* PM8644_GPIO_6 */
-				 <0x0c60002f>, /* PM8644_GPIO_7 */
-				 <0x0c700030>, /* PM8644_GPIO_8 */
-				 <0x0c800031>, /* PM8644_GPIO_9 */
-				 <0x0c900032>, /* PM8644_GPIO_10 */
-				 <0x0ca00033>, /* PM8644_GPIO_11 */
-				 <0x0cb00034>, /* PM8644_GPIO_12 */
-				 <0x0cc00035>, /* PM8644_GPIO_13 */
-				 <0x0cd00036>, /* PM8644_GPIO_14 */
-				 <0x0ce00037>, /* PM8644_GPIO_15 */
-				 <0x0cf00038>, /* PM8644_GPIO_16 */
-				 <0x0d000039>, /* PM8644_GPIO_17 */
-				 <0x0d10003a>, /* PM8644_GPIO_18 */
-				 <0x0d20003b>, /* PM8644_GPIO_19 */
-				 <0x0d30003c>, /* PM8644_GPIO_20 */
-				 <0x0d40003d>, /* PM8644_GPIO_21 */
-				 <0x0d50003e>, /* PM8644_GPIO_22 */
-				 <0x0d60003f>, /* PM8644_GPIO_23 */
-				 <0x0d700040>, /* PM8644_GPIO_24 */
-				 <0x0d800041>, /* PM8644_GPIO_25 */
-				 <0x0d900042>, /* PM8644_GPIO_26 */
-				 <0x0da00043>, /* PM8644_GPIO_27 */
-				 <0x0db00044>, /* PM8644_GPIO_28 */
-				 <0x0dc00045>, /* PM8644_GPIO_29 */
-				 <0x0dd00046>, /* PM8644_GPIO_30 */
-				 <0x0de00047>, /* PM8644_GPIO_31 */
-				 <0x0df00048>, /* PM8644_GPIO_32 */
-				 <0x0e000049>, /* PM8644_GPIO_33 */
-				 <0x0e10004a>, /* PM8644_GPIO_34 */
-				 <0x0e20004b>, /* PM8644_GPIO_35 */
-				 <0x0e30004c>, /* PM8644_GPIO_36 */
-				 <0x0e40004d>, /* PM8644_GPIO_37 */
-				 <0x0e50004e>, /* PM8644_GPIO_38 */
-				 <0x0e60004f>, /* PM8644_GPIO_39 */
-				 <0x0e700050>, /* PM8644_GPIO_40 */
-				 <0x0e800051>, /* PM8644_GPIO_41 */
-				 <0x0e900052>, /* PM8644_GPIO_42 */
-				 <0x0ea00053>, /* PM8644_GPIO_43 */
-				 <0x11000054>, /* BUCK_CMN_1 */
-				 <0x11100055>, /* BUCK_CMN_2 */
-				 <0x11200056>, /* BUCK_CMN_3 */
-				 <0x11400057>, /* PM8644_SMPS1 */
-				 <0x11500058>, /* SMPS_1_PS1 */
-				 <0x11600059>, /* BUCK_FREQ_1 */
-				 <0x1170005a>, /* PM8644_SMPS2 */
-				 <0x1180005b>, /* SMPS_2_PS1 */
-				 <0x1190005c>, /* BUCK_FREQ_2 */
-				 <0x11a0005d>, /* PM8644_SMPS3 */
-				 <0x11b0005e>, /* SMPS_3_PS1 */
-				 <0x11c0005f>, /* BUCK_FREQ_3 */
-				 <0x11d00060>, /* PM8644_SMPS4 */
-				 <0x11e00061>, /* SMPS_4_PS1 */
-				 <0x11f00062>, /* PM8644_BUCK_FREQ_4 */
-				 <0x12000063>, /* PM8644_SMPS5 */
-				 <0x12100064>, /* FTPS1_5 */
-				 <0x12200065>, /* PM8644_BUCK_FREQ_5 */
-				 <0x12300066>, /* PM8644_SMPS6 */
-				 <0x12400067>, /* FTPS1_6 */
-				 <0x12500068>, /* PM8644_BUCK_FREQ_6 */
-				 <0x12600069>, /* PM8644_SMPS7 */
-				 <0x1270006a>, /* FTPS1_7 */
-				 <0x1280006b>, /* PM8644_BUCK_FREQ_7 */
-				 <0x1290006c>, /* PM8644_SMPS8 */
-				 <0x12a0006d>, /* FTPS1_8 */
-				 <0x12b0006e>, /* PM8644_BUCK_FREQ_8 */
-				 <0x12c0006f>, /* PM8644_SMPS9 */
-				 <0x12d00070>, /* FTPS1_9 */
-				 <0x12e00071>, /* PM8644_BUCK_FREQ_9 */
-				 <0x12f00072>, /* PM8644_SMPS10 */
-				 <0x13000073>, /* FTPS1_10 */
-				 <0x13100074>, /* PM8644_BUCK_FREQ_10 */
-				 <0x13200075>, /* PM8644_SMPS11 */
-				 <0x13300076>, /* FTPS1_11 */
-				 <0x13400077>, /* BUCK_FREQ_11 */
-				 <0x14000078>, /* PM8644_LDO_1 */
-				 <0x14100079>, /* PM8644_LDO_2 */
-				 <0x1420007a>, /* PM8644_LDO_3 */
-				 <0x1430007b>, /* PM8644_LDO_4 */
-				 <0x1440007c>, /* PM8644_LDO_5 */
-				 <0x1450007d>, /* PM8644_LDO_6 */
-				 <0x1460007e>, /* PM8644_LDO_7 */
-				 <0x1470007f>, /* PM8644_LDO_8 */
-				 <0x14800080>, /* PM8644_LDO_9 */
-				 <0x14900081>, /* PM8644_LDO_10 */
-				 <0x14a00082>, /* PM8644_LDO_11 */
-				 <0x14b00083>, /* PM8644_LDO_12 */
-				 <0x14c00084>, /* PM8644_LDO_13 */
-				 <0x14d00085>, /* PM8644_LDO_14 */
-				 <0x14e00086>, /* PM8644_LDO_15 */
-				 <0x14f00087>, /* PM8644_LDO_16 */
-				 <0x15000088>, /* PM8644_LDO_17 */
-				 <0x15100089>, /* PM8644_LDO_18 */
-				 <0x1520008a>, /* PM8644_LDO_19 */
-				 <0x1530008b>, /* PM8644_LDO_20 */
-				 <0x1540008c>, /* PM8644_LDO_21 */
-				 <0x1550008d>, /* PM8644_LDO_22 */
-				 <0x1560008e>, /* PM8644_LDO_23 */
-				 <0x1570008f>, /* PM8644_LDO_24 */
-				 <0x15800090>, /* PM8644_LDO_25 */
-				 <0x18000091>, /* PM8644_LVS_1 */
-				 <0x18100092>, /* PM8644_LVS_2 */
-				 <0x18200093>, /* PM8644_OTG */
-				 <0x18300094>, /* PM8644_HDMI */
-				 <0x1a800095>, /* KEYPAD */
-				 <0x1b000096>, /* LPG_LUT */
-				 <0x1b100097>, /* LPG_CHAN_1 */
-				 <0x1b200098>, /* LPG_CHAN_2 */
-				 <0x1b300099>, /* LPG_CHAN_3 */
-				 <0x1b40009a>, /* LPG_CHAN_4 */
-				 <0x1b50009b>, /* LPG_CHAN_5 */
-				 <0x1b60009c>, /* LPG_CHAN_6 */
-				 <0x1b70009d>, /* LPG_CHAN_7 */
-				 <0x1b80009e>, /* LPG_CHAN_8 */
-				 <0x1bc0009f>; /* LPG_PWM */
 	};
 
 	sdcc1: qcom,sdcc@f9824000 {
diff --git a/arch/arm/boot/dts/msm-gdsc.dtsi b/arch/arm/boot/dts/msm-gdsc.dtsi
index f0570ba..cfd68fa 100644
--- a/arch/arm/boot/dts/msm-gdsc.dtsi
+++ b/arch/arm/boot/dts/msm-gdsc.dtsi
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/boot/dts/msm-iommu-v0.dtsi b/arch/arm/boot/dts/msm-iommu-v0.dtsi
new file mode 100644
index 0000000..0c44fb5
--- /dev/null
+++ b/arch/arm/boot/dts/msm-iommu-v0.dtsi
@@ -0,0 +1,276 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/ {
+	lpass_iommu: qcom,iommu@fd000000 {
+		compatible = "qcom,msm-smmu-v0";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		reg = <0xfd000000 0x10000>;
+		interrupts = <0 248 0>;
+		qcom,glb-offset = <0xF000>;
+		label = "lpass_iommu";
+		qcom,iommu-pmu-ngroups = <1>;
+		qcom,iommu-pmu-ncounters = <4>;
+		qcom,iommu-pmu-event-classes = <0x08
+						0x09
+						0x10
+						0x12
+						0x80>;
+		status = "disabled";
+
+		lpass_q6_fw: qcom,iommu-ctx@fd000000 {
+			reg = <0xfd000000 0x1000>;
+			interrupts = <0 250 0>;
+			qcom,iommu-ctx-mids = <0 15>;
+			label = "q6_fw";
+		};
+
+		lpass_audio_shared: qcom,iommu-ctx@fd001000 {
+			reg = <0xfd001000 0x1000>;
+			interrupts = <0 250 0>;
+			qcom,iommu-ctx-mids = <1>;
+			label = "audio_shared";
+		};
+
+		lpass_video_shared: qcom,iommu-ctx@fd002000 {
+			reg = <0xfd002000 0x1000>;
+			interrupts = <0 250 0>;
+			qcom,iommu-ctx-mids = <2>;
+			label = "video_shared";
+		};
+
+		lpass_q6_spare: qcom,iommu-ctx@fd003000 {
+			reg = <0xfd003000 0x1000>;
+			interrupts = <0 250 0>;
+			qcom,iommu-ctx-mids = <3 4 5 6 7 8 9 10 11 12 13 14>;
+			label = "q6_spare";
+		};
+	};
+
+	copss_iommu: qcom,iommu@fd010000 {
+		compatible = "qcom,msm-smmu-v0";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		reg = <0xfd010000 0x10000>;
+		interrupts = <0 252 0>;
+		qcom,glb-offset = <0xF000>;
+		label = "copss_iommu";
+		qcom,iommu-pmu-ngroups = <1>;
+		qcom,iommu-pmu-ncounters = <4>;
+		qcom,iommu-pmu-event-classes = <0x08
+						0x09
+						0x10
+						0x12
+						0x80>;
+		status = "disabled";
+
+		qcom,iommu-ctx@fd010000 {
+			reg = <0xfd010000 0x1000>;
+			interrupts = <0 254 0>;
+			qcom,iommu-ctx-mids = <0>;
+			label = "copss_0";
+		};
+
+		qcom,iommu-ctx@fd011000 {
+			reg = <0xfd011000 0x1000>;
+			interrupts = <0 254 0>;
+			qcom,iommu-ctx-mids = <1>;
+			label = "copss_1";
+		};
+
+		qcom,iommu-ctx@fd012000 {
+			reg = <0xfd012000 0x1000>;
+			interrupts = <0 254 0>;
+			qcom,iommu-ctx-mids = <2>;
+			label = "copss_2";
+		};
+
+		qcom,iommu-ctx@fd013000 {
+			reg = <0xfd013000 0x1000>;
+			interrupts = <0 254 0>;
+			qcom,iommu-ctx-mids = <3>;
+			label = "copss_3";
+		};
+
+		qcom,iommu-ctx@fd014000 {
+			reg = <0xfd014000 0x1000>;
+			interrupts = <0 254 0>;
+			qcom,iommu-ctx-mids = <4>;
+			label = "copss_4";
+		};
+
+		qcom,iommu-ctx@fd015000 {
+			reg = <0xfd015000 0x1000>;
+			interrupts = <0 254 0>;
+			qcom,iommu-ctx-mids = <5>;
+			label = "copss_5";
+		};
+
+		qcom,iommu-ctx@fd016000 {
+			reg = <0xfd016000 0x1000>;
+			interrupts = <0 254 0>;
+			qcom,iommu-ctx-mids = <6>;
+			label = "copss_6";
+		};
+
+		qcom,iommu-ctx@fd017000 {
+			reg = <0xfd017000 0x1000>;
+			interrupts = <0 254 0>;
+			qcom,iommu-ctx-mids = <7>;
+			label = "copss_7";
+		};
+	};
+
+	mdpe_iommu: qcom,iommu@fd860000 {
+		compatible = "qcom,msm-smmu-v0";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		reg = <0xfd860000 0x10000>;
+		interrupts = <0 245 0>;
+		qcom,glb-offset = <0xF000>;
+		label = "mdpe_iommu";
+		qcom,iommu-pmu-ngroups = <1>;
+		qcom,iommu-pmu-ncounters = <4>;
+		qcom,iommu-pmu-event-classes = <0x08
+						0x09
+						0x10
+						0x12
+						0x80>;
+		status = "disabled";
+
+		qcom,iommu-ctx@fd860000 {
+			reg = <0xfd860000 0x1000>;
+			interrupts = <0 247 0>;
+			qcom,iommu-ctx-mids = <0 1 3>;
+			label = "mdpe_0";
+		};
+
+		qcom,iommu-ctx@fd861000 {
+			reg = <0xfd861000 0x1000>;
+			interrupts = <0 247 0>;
+			qcom,iommu-ctx-mids = <2>;
+			label = "mdpe_1";
+		};
+	};
+
+	mdps_iommu: qcom,iommu@fd870000 {
+		compatible = "qcom,msm-smmu-v0";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		reg = <0xfd870000 0x10000>;
+		interrupts = <0 73 0>;
+		qcom,glb-offset = <0xF000>;
+		label = "mdps_iommu";
+		qcom,iommu-pmu-ngroups = <1>;
+		qcom,iommu-pmu-ncounters = <4>;
+		qcom,iommu-pmu-event-classes = <0x08
+						0x09
+						0x10
+						0x12
+						0x80>;
+		status = "disabled";
+
+		qcom,iommu-ctx@fd870000 {
+			reg = <0xfd870000 0x1000>;
+			interrupts = <0 47 0>;
+			qcom,iommu-ctx-mids = <0>;
+			label = "mdps_0";
+		};
+
+		qcom,iommu-ctx@fd871000 {
+			reg = <0xfd871000 0x1000>;
+			interrupts = <0 47 0>;
+			qcom,iommu-ctx-mids = <1>;
+			label = "mdps_1";
+		};
+	};
+
+	gfx_iommu: qcom,iommu@fd880000 {
+		compatible = "qcom,msm-smmu-v0";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		reg = <0xfd880000 0x10000>;
+		interrupts = <0 38 0>;
+		qcom,glb-offset = <0xF000>;
+		label = "gfx_iommu";
+		qcom,iommu-pmu-ngroups = <1>;
+		qcom,iommu-pmu-ncounters = <4>;
+		qcom,iommu-pmu-event-classes = <0x08
+						0x09
+						0x10
+						0x12
+						0x80>;
+		status = "disabled";
+
+		qcom,iommu-ctx@fd880000 {
+			reg = <0xfd880000 0x1000>;
+			interrupts = <0 241 0>;
+			qcom,iommu-ctx-mids = <0 1 2 3 4 5 6 7 8 9 10 11 12 13
+					       14 15>;
+			label = "gfx3d_user";
+		};
+
+		qcom,iommu-ctx@fd881000 {
+			reg = <0xfd881000 0x1000>;
+			interrupts = <0 241 0>;
+			qcom,iommu-ctx-mids = <16 17 18 19 20 21 22 23 24 25
+					       26 27 28 29 30 31>;
+			label = "gfx3d_priv";
+		};
+
+		qcom,iommu-ctx@fd882000 {
+			reg = <0xfd882000 0x1000>;
+			interrupts = <0 241 0>;
+			qcom,iommu-ctx-mids = <>;
+			label = "gfx3d_spare";
+		};
+	};
+
+	vfe_iommu: qcom,iommu@fd890000 {
+		compatible = "qcom,msm-smmu-v0";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		reg = <0xfd890000 0x10000>;
+		interrupts = <0 62 0>;
+		qcom,glb-offset = <0xF000>;
+		label = "vfe_iommu";
+		qcom,iommu-pmu-ngroups = <1>;
+		qcom,iommu-pmu-ncounters = <4>;
+		qcom,iommu-pmu-event-classes = <0x08
+						0x09
+						0x10
+						0x12
+						0x80>;
+		status = "disabled";
+
+		qcom,iommu-ctx@fd890000 {
+			reg = <0xfd890000 0x1000>;
+			interrupts = <0 65 0>;
+			qcom,iommu-ctx-mids = <0>;
+			label = "vfe0";
+		};
+
+		qcom,iommu-ctx@fd891000 {
+			reg = <0xfd891000 0x1000>;
+			interrupts = <0 65 0>;
+			qcom,iommu-ctx-mids = <1>;
+			label = "vfe1";
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/msm-iommu-v1.dtsi b/arch/arm/boot/dts/msm-iommu-v1.dtsi
index 5a08f51..71dcc6a 100644
--- a/arch/arm/boot/dts/msm-iommu-v1.dtsi
+++ b/arch/arm/boot/dts/msm-iommu-v1.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -11,218 +11,462 @@
  */
 
 / {
-	lpass_iommu: qcom,iommu@fd000000 {
+	jpeg_iommu: qcom,iommu@fda64000 {
 		compatible = "qcom,msm-smmu-v1";
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges;
-		reg = <0xfd000000 0x10000>;
-		qcom,glb-offset = <0xF000>;
-		label = "lpass_iommu";
+		reg = <0xfda64000 0x10000>;
+		reg-names = "iommu_base";
+		interrupts = <0 67 0>;
+		vdd-supply = <&gdsc_jpeg>;
+		qcom,needs-alt-core-clk;
+		label = "jpeg_iommu";
 		status = "disabled";
 
-		qcom,iommu-ctx@fd000000 {
-			reg = <0xfd000000 0x1000>;
-			interrupts = <0 250 0>;
-			qcom,iommu-ctx-mids = <0 15>;
-			label = "q6_fw";
+		qcom,iommu-pmu-ngroups = <1>;
+		qcom,iommu-pmu-ncounters = <8>;
+		qcom,iommu-pmu-event-classes = <0x00
+						0x01
+						0x08
+						0x09
+						0x0A
+						0x10
+						0x11
+						0x12
+						0x80
+						0x81
+						0x82
+						0x83
+						0x90
+						0x91
+						0x92
+						0xb0
+						0xb1>;
+
+		qcom,iommu-bfb-regs =  <0x204c
+					0x2050
+					0x2514
+					0x2540
+					0x256c
+					0x2314
+					0x2394
+					0x2414
+					0x20ac
+					0x215c
+					0x220c
+					0x2008
+					0x200c
+					0x2010
+					0x2014>;
+
+		qcom,iommu-bfb-data =  <0x0000ffff
+					0x0
+					0x4
+					0x4
+					0x0
+					0x0
+					0x10
+					0x50
+					0x0
+					0x10
+					0x20
+					0x0
+					0x0
+					0x0
+					0x0>;
+
+		qcom,iommu-ctx@fda6c000 {
+			reg = <0xfda6c000 0x1000>;
+			interrupts = <0 70 0>;
+			qcom,iommu-ctx-sids = <0>;
+			label = "jpeg_enc0";
 		};
 
-		qcom,iommu-ctx@fd001000 {
-			reg = <0xfd001000 0x1000>;
-			interrupts = <0 250 0>;
-			qcom,iommu-ctx-mids = <1>;
-			label = "audio_shared";
+		qcom,iommu-ctx@fda6d000 {
+			reg = <0xfda6d000 0x1000>;
+			interrupts = <0 70 0>;
+			qcom,iommu-ctx-sids = <1>;
+			label = "jpeg_enc1";
 		};
 
-		qcom,iommu-ctx@fd002000 {
-			reg = <0xfd002000 0x1000>;
-			interrupts = <0 250 0>;
-			qcom,iommu-ctx-mids = <2>;
-			label = "video_shared";
-		};
-
-		qcom,iommu-ctx@fd003000 {
-			reg = <0xfd003000 0x1000>;
-			interrupts = <0 250 0>;
-			qcom,iommu-ctx-mids = <3 4 5 6 7 8 9 10 11 12 13 14>;
-			label = "q6_spare";
+		qcom,iommu-ctx@fda6e000 {
+			reg = <0xfda6e000 0x1000>;
+			interrupts = <0 70 0>;
+			qcom,iommu-ctx-sids = <2>;
+			label = "jpeg_dec";
 		};
 	};
 
-	copss_iommu: qcom,iommu@fd010000 {
+	mdp_iommu: qcom,iommu@fd928000 {
 		compatible = "qcom,msm-smmu-v1";
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges;
-		reg = <0xfd010000 0x10000>;
-		qcom,glb-offset = <0xF000>;
-		label = "copss_iommu";
+		reg = <0xfd928000 0x10000>;
+		reg-names = "iommu_base";
+		interrupts = <0 73 0>;
+		vdd-supply = <&gdsc_mdss>;
+		qcom,iommu-secure-id = <1>;
+		label = "mdp_iommu";
 		status = "disabled";
 
-		qcom,iommu-ctx@fd010000 {
-			reg = <0xfd010000 0x1000>;
-			interrupts = <0 254 0>;
-			qcom,iommu-ctx-mids = <0>;
-			label = "copss_0";
+		qcom,iommu-pmu-ngroups = <1>;
+		qcom,iommu-pmu-ncounters = <8>;
+		qcom,iommu-pmu-event-classes = <0x00
+						0x01
+						0x08
+						0x09
+						0x0A
+						0x10
+						0x11
+						0x12
+						0x80
+						0x81
+						0x82
+						0x83
+						0x90
+						0x91
+						0x92
+						0xb0
+						0xb1>;
+
+		qcom,iommu-bfb-regs =  <0x204c
+					0x2050
+					0x2514
+					0x2540
+					0x256c
+					0x20ac
+					0x215c
+					0x220c
+					0x2314
+					0x2394
+					0x2414
+					0x2008
+					0x200c
+					0x2010
+					0x2014
+					0x2018
+					0x201c
+					0x2020>;
+
+		qcom,iommu-bfb-data =  <0xffffffff
+					0x0
+					0x00000004
+					0x00000010
+					0x00000000
+					0x00000000
+					0x00000034
+					0x00000044
+					0x0
+					0x34
+					0x74
+					0x0
+					0x0
+					0x0
+					0x0
+					0x0
+					0x0
+					0x0>;
+
+		qcom,iommu-ctx@fd930000 {
+			reg = <0xfd930000 0x1000>;
+			interrupts = <0 47 0>;
+			qcom,iommu-ctx-sids = <0>;
+			label = "mdp_0";
 		};
 
-		qcom,iommu-ctx@fd011000 {
-			reg = <0xfd011000 0x1000>;
-			interrupts = <0 254 0>;
-			qcom,iommu-ctx-mids = <1>;
-			label = "copss_1";
+		qcom,iommu-ctx@fd931000 {
+			reg = <0xfd931000 0x1000>;
+			interrupts = <0 47 0>;
+			qcom,iommu-ctx-sids = <1>;
+			label = "mdp_1";
+			qcom,secure-context;
 		};
 
-		qcom,iommu-ctx@fd012000 {
-			reg = <0xfd012000 0x1000>;
-			interrupts = <0 254 0>;
-			qcom,iommu-ctx-mids = <2>;
-			label = "copss_2";
-		};
-
-		qcom,iommu-ctx@fd013000 {
-			reg = <0xfd013000 0x1000>;
-			interrupts = <0 254 0>;
-			qcom,iommu-ctx-mids = <3>;
-			label = "copss_3";
-		};
-
-		qcom,iommu-ctx@fd014000 {
-			reg = <0xfd014000 0x1000>;
-			interrupts = <0 254 0>;
-			qcom,iommu-ctx-mids = <4>;
-			label = "copss_4";
-		};
-
-		qcom,iommu-ctx@fd015000 {
-			reg = <0xfd015000 0x1000>;
-			interrupts = <0 254 0>;
-			qcom,iommu-ctx-mids = <5>;
-			label = "copss_5";
-		};
-
-		qcom,iommu-ctx@fd016000 {
-			reg = <0xfd016000 0x1000>;
-			interrupts = <0 254 0>;
-			qcom,iommu-ctx-mids = <6>;
-			label = "copss_6";
-		};
-
-		qcom,iommu-ctx@fd017000 {
-			reg = <0xfd017000 0x1000>;
-			interrupts = <0 254 0>;
-			qcom,iommu-ctx-mids = <7>;
-			label = "copss_7";
+		qcom,iommu-ctx@fd932000 {
+			reg = <0xfd932000 0x1000>;
+			interrupts = <0 47 0>;
+			qcom,iommu-ctx-sids = <>;
+			label = "mdp_2";
+			qcom,secure-context;
 		};
 	};
 
-	mdpe_iommu: qcom,iommu@fd860000 {
+	venus_iommu: qcom,iommu@fdc84000 {
 		compatible = "qcom,msm-smmu-v1";
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges;
-		reg = <0xfd860000 0x10000>;
-		qcom,glb-offset = <0xF000>;
-		label = "mdpe_iommu";
+		reg = <0xfdc84000 0x10000
+		       0xfdce0004 0x4>;
+		reg-names = "iommu_base", "clk_base";
+		interrupts = <0 45 0>;
+		vdd-supply = <&gdsc_venus>;
+		qcom,iommu-secure-id = <0>;
+		qcom,needs-alt-core-clk;
+		label = "venus_iommu";
 		status = "disabled";
 
-		qcom,iommu-ctx@fd860000 {
-			reg = <0xfd860000 0x1000>;
-			interrupts = <0 247 0>;
-			qcom,iommu-ctx-mids = <>;
-			label = "mdpe_0";
+		qcom,iommu-pmu-ngroups = <1>;
+		qcom,iommu-pmu-ncounters = <8>;
+		qcom,iommu-pmu-event-classes = <0x00
+						0x01
+						0x08
+						0x09
+						0x0A
+						0x10
+						0x11
+						0x12
+						0x80
+						0x81
+						0x82
+						0x83
+						0x90
+						0x91
+						0x92
+						0xb0
+						0xb1>;
+
+		qcom,iommu-bfb-regs =  <0x204c
+					0x2050
+					0x2514
+					0x2540
+					0x256c
+					0x20ac
+					0x215c
+					0x220c
+					0x2314
+					0x2394
+					0x2414
+					0x2008
+					0x200c
+					0x2010
+					0x2014
+					0x2018
+					0x201c
+					0x2020
+					0x2024
+					0x2028
+					0x202c
+					0x2030
+					0x2034
+					0x2038>;
+
+		qcom,iommu-bfb-data =  <0xffffffff
+					0xffffffff
+					0x00000004
+					0x00000008
+					0x00000000
+					0x00000000
+					0x00000094
+					0x000000b4
+					0x0
+					0x94
+					0x114
+					0x0
+					0x0
+					0x0
+					0x0
+					0x0
+					0x0
+					0x0
+					0x0
+					0x0
+					0x0
+					0x0
+					0x0
+					0x0>;
+
+		venus_ns: qcom,iommu-ctx@fdc8c000 {
+			reg = <0xfdc8c000 0x1000>;
+			interrupts = <0 42 0>;
+			qcom,iommu-ctx-sids = <0 1 2 3 4 5>;
+			label = "venus_ns";
 		};
 
-		qcom,iommu-ctx@fd861000 {
-			reg = <0xfd861000 0x1000>;
-			interrupts = <0 247 0>;
-			qcom,iommu-ctx-mids = <>;
-			label = "mdpe_1";
+		venus_cp: qcom,iommu-ctx@fdc8d000 {
+			reg = <0xfdc8d000 0x1000>;
+			interrupts = <0 42 0>;
+			qcom,iommu-ctx-sids = <0x80 0x81 0x82 0x83 0x84 0x85>;
+			label = "venus_cp";
+			qcom,secure-context;
+		};
+
+		venus_fw: qcom,iommu-ctx@fdc8e000 {
+			reg = <0xfdc8e000 0x1000>;
+			interrupts = <0 42 0>;
+			qcom,iommu-ctx-sids = <0xc0 0xc6>;
+			label = "venus_fw";
+			qcom,secure-context;
 		};
 	};
 
-	mdps_iommu: qcom,iommu@fd870000 {
+	kgsl_iommu: qcom,iommu@fdb10000 {
 		compatible = "qcom,msm-smmu-v1";
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges;
-		reg = <0xfd870000 0x10000>;
-		qcom,glb-offset = <0xF000>;
-		label = "mdps_iommu";
+		reg = <0xfdb10000 0x10000>;
+		reg-names = "iommu_base";
+		interrupts = <0 38 0>;
+		vdd-supply = <&gdsc_oxili_cx>;
+		qcom,alt-vdd-supply = <&gdsc_oxili_gx>;
+		qcom,needs-alt-core-clk;
+		label = "kgsl_iommu";
 		status = "disabled";
 
-		qcom,iommu-ctx@fd870000 {
-			reg = <0xfd870000 0x1000>;
-			interrupts = <0 247 0>;
-			qcom,iommu-ctx-mids = <>;
-			label = "mdps_0";
-		};
+		qcom,iommu-pmu-ngroups = <1>;
+		qcom,iommu-pmu-ncounters = <8>;
+		qcom,iommu-pmu-event-classes = <0x00
+						0x01
+						0x08
+						0x09
+						0x0A
+						0x10
+						0x11
+						0x12
+						0x80
+						0x81
+						0x82
+						0x83
+						0x90
+						0x91
+						0x92
+						0xb0
+						0xb1>;
 
-		qcom,iommu-ctx@fd871000 {
-			reg = <0xfd871000 0x1000>;
-			interrupts = <0 247 0>;
-			qcom,iommu-ctx-mids = <>;
-			label = "mdps_1";
-		};
-	};
+		qcom,iommu-bfb-regs =  <0x204c
+					0x2050
+					0x2514
+					0x2540
+					0x256c
+					0x20ac
+					0x215c
+					0x220c
+					0x2314
+					0x2394
+					0x2414
+					0x2008>;
 
-	gfx_iommu: qcom,iommu@fd880000 {
-		compatible = "qcom,msm-smmu-v1";
-		#address-cells = <1>;
-		#size-cells = <1>;
-		ranges;
-		reg = <0xfd880000 0x10000>;
-		qcom,glb-offset = <0xF000>;
-		label = "gfx_iommu";
-		status = "disabled";
+		qcom,iommu-bfb-data =  <0x00000003
+					0x0
+					0x00000004
+					0x00000010
+					0x00000000
+					0x00000000
+					0x00000001
+					0x00000021
+					0x0
+					0x1
+					0x81
+					0x0>;
 
-		qcom,iommu-ctx@fd880000 {
-			reg = <0xfd880000 0x1000>;
+		qcom,iommu-ctx@fdb18000 {
+			reg = <0xfdb18000 0x1000>;
 			interrupts = <0 241 0>;
-			qcom,iommu-ctx-mids = <0 1 2 3 4 5 6 7 8 9 10 11 12 13
-					       14 15>;
+			qcom,iommu-ctx-sids = <0>;
 			label = "gfx3d_user";
 		};
 
-		qcom,iommu-ctx@fd881000 {
-			reg = <0xfd881000 0x1000>;
+		qcom,iommu-ctx@fdb19000 {
+			reg = <0xfdb19000 0x1000>;
 			interrupts = <0 241 0>;
-			qcom,iommu-ctx-mids = <16 17 18 19 20 21 22 23 24 25
-					       26 27 28 29 30 31>;
+			qcom,iommu-ctx-sids = <1>;
 			label = "gfx3d_priv";
 		};
-
-		qcom,iommu-ctx@fd882000 {
-			reg = <0xfd882000 0x1000>;
-			interrupts = <0 241 0>;
-			qcom,iommu-ctx-mids = <>;
-			label = "gfx3d_spare";
-		};
 	};
 
-	vfe_iommu: qcom,iommu@fd890000 {
+	vfe_iommu: qcom,iommu@fda44000 {
 		compatible = "qcom,msm-smmu-v1";
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges;
-		reg = <0xfd890000 0x10000>;
-		qcom,glb-offset = <0xF000>;
+		reg = <0xfda44000 0x10000>;
+		reg-names = "iommu_base";
+		interrupts = <0 62 0>;
+		vdd-supply = <&gdsc_vfe>;
+		qcom,needs-alt-core-clk;
 		label = "vfe_iommu";
 		status = "disabled";
 
-		qcom,iommu-ctx@fd890000 {
-			reg = <0xfd890000 0x1000>;
+		qcom,iommu-pmu-ngroups = <1>;
+		qcom,iommu-pmu-ncounters = <8>;
+		qcom,iommu-pmu-event-classes = <0x00
+						0x01
+						0x08
+						0x09
+						0x0A
+						0x10
+						0x11
+						0x12
+						0x80
+						0x81
+						0x82
+						0x83
+						0x90
+						0x91
+						0x92
+						0xb0
+						0xb1>;
+
+		qcom,iommu-bfb-regs =  <0x204c
+					0x2050
+					0x2514
+					0x2540
+					0x256c
+					0x2314
+					0x2394
+					0x2414
+					0x20ac
+					0x215c
+					0x220c
+					0x2008
+					0x200c
+					0x2010
+					0x2014
+					0x2018
+					0x201c
+					0x2020>;
+
+		qcom,iommu-bfb-data =  <0xffffffff
+					0x00000000
+					0x4
+					0x8
+					0x0
+					0x0
+					0x20
+					0x78
+					0x0
+					0x20
+					0x36
+					0x0
+					0x0
+					0x0
+					0x0
+					0x0
+					0x0
+					0x0>;
+
+		qcom,iommu-ctx@fda4c000 {
+			reg = <0xfda4c000 0x1000>;
 			interrupts = <0 65 0>;
-			qcom,iommu-ctx-mids = <0>;
+			qcom,iommu-ctx-sids = <0>;
 			label = "vfe0";
 		};
 
-		qcom,iommu-ctx@fd891000 {
-			reg = <0xfd891000 0x1000>;
+		qcom,iommu-ctx@fda4d000 {
+			reg = <0xfda4d000 0x1000>;
 			interrupts = <0 65 0>;
-			qcom,iommu-ctx-mids = <1>;
+			qcom,iommu-ctx-sids = <1>;
 			label = "vfe1";
 		};
+
+		qcom,iommu-ctx@fda4e000 {
+			reg = <0xfda4e000 0x1000>;
+			interrupts = <0 65 0>;
+			qcom,iommu-ctx-sids = <2>;
+			label = "cpp";
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/msm-iommu.dtsi b/arch/arm/boot/dts/msm-iommu.dtsi
deleted file mode 100755
index 839199a..0000000
--- a/arch/arm/boot/dts/msm-iommu.dtsi
+++ /dev/null
@@ -1,342 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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.
- */
-
-/ {
-	jpeg_iommu: qcom,iommu@fda64000 {
-		compatible = "qcom,msm-smmu-v2";
-		#address-cells = <1>;
-		#size-cells = <1>;
-		ranges;
-		reg = <0xfda64000 0x10000>;
-		vdd-supply = <&gdsc_jpeg>;
-		status = "disabled";
-
-		qcom,iommu-bfb-regs =  <0x204c
-					0x2050
-					0x2514
-					0x2540
-					0x256c
-					0x2314
-					0x2394
-					0x2414
-					0x20ac
-					0x215c
-					0x220c
-					0x2008
-					0x200c
-					0x2010
-					0x2014>;
-
-		qcom,iommu-bfb-data =  <0xffffffff
-					0xffffffff
-					0x4
-					0x4
-					0x0
-					0x0
-					0x10
-					0x50
-					0x0
-					0x10
-					0x20
-					0x0
-					0x0
-					0x0
-					0x0>;
-
-		qcom,iommu-ctx@fda6c000 {
-			reg = <0xfda6c000 0x1000>;
-			interrupts = <0 70 0>;
-			qcom,iommu-ctx-sids = <0>;
-			label = "jpeg_enc0";
-		};
-
-		qcom,iommu-ctx@fda6d000 {
-			reg = <0xfda6d000 0x1000>;
-			interrupts = <0 70 0>;
-			qcom,iommu-ctx-sids = <1>;
-			label = "jpeg_enc1";
-		};
-
-		qcom,iommu-ctx@fda6e000 {
-			reg = <0xfda6e000 0x1000>;
-			interrupts = <0 70 0>;
-			qcom,iommu-ctx-sids = <2>;
-			label = "jpeg_dec";
-		};
-	};
-
-	mdp_iommu: qcom,iommu@fd928000 {
-		compatible = "qcom,msm-smmu-v2";
-		#address-cells = <1>;
-		#size-cells = <1>;
-		ranges;
-		reg = <0xfd928000 0x10000>;
-		vdd-supply = <&gdsc_mdss>;
-		qcom,iommu-secure-id = <1>;
-		status = "disabled";
-
-		qcom,iommu-bfb-regs =  <0x204c
-					0x2050
-					0x2514
-					0x2540
-					0x256c
-					0x20ac
-					0x215c
-					0x220c
-					0x2314
-					0x2394
-					0x2414
-					0x2008
-					0x200c
-					0x2010
-					0x2014
-					0x2018
-					0x201c
-					0x2020>;
-
-		qcom,iommu-bfb-data =  <0xffffffff
-					0xffffffff
-					0x00000004
-					0x00000010
-					0x00000000
-					0x00000000
-					0x00000034
-					0x00000044
-					0x0
-					0x34
-					0x74
-					0x0
-					0x0
-					0x0
-					0x0
-					0x0
-					0x0
-					0x0>;
-
-		qcom,iommu-ctx@fd930000 {
-			reg = <0xfd930000 0x1000>;
-			interrupts = <0 47 0>;
-			qcom,iommu-ctx-sids = <0>;
-			label = "mdp_0";
-		};
-
-		qcom,iommu-ctx@fd931000 {
-			reg = <0xfd931000 0x1000>;
-			interrupts = <0 47 0>;
-			qcom,iommu-ctx-sids = <1>;
-			label = "mdp_1";
-		};
-	};
-
-	venus_iommu: qcom,iommu@fdc84000 {
-		compatible = "qcom,msm-smmu-v2";
-		#address-cells = <1>;
-		#size-cells = <1>;
-		ranges;
-		reg = <0xfdc84000 0x10000>;
-		vdd-supply = <&gdsc_venus>;
-		qcom,iommu-secure-id = <0>;
-		qcom,needs-alt-core-clk;
-		status = "disabled";
-
-		qcom,iommu-bfb-regs =  <0x204c
-					0x2050
-					0x2514
-					0x2540
-					0x256c
-					0x20ac
-					0x215c
-					0x220c
-					0x2314
-					0x2394
-					0x2414
-					0x2008
-					0x200c
-					0x2010
-					0x2014
-					0x2018
-					0x201c
-					0x2020
-					0x2024
-					0x2028
-					0x202c
-					0x2030
-					0x2034
-					0x2038>;
-
-		qcom,iommu-bfb-data =  <0xffffffff
-					0xffffffff
-					0x00000004
-					0x00000008
-					0x00000000
-					0x00000000
-					0x00000094
-					0x000000b4
-					0x0
-					0x94
-					0x114
-					0x0
-					0x0
-					0x0
-					0x0
-					0x0
-					0x0
-					0x0
-					0x0
-					0x0
-					0x0
-					0x0
-					0x0
-					0x0>;
-
-		qcom,iommu-ctx@fdc8c000 {
-			reg = <0xfdc8c000 0x1000>;
-			interrupts = <0 42 0>;
-			qcom,iommu-ctx-sids = <0 1 2 3 4 5>;
-			label = "venus_ns";
-		};
-
-		qcom,iommu-ctx@fdc8d000 {
-			reg = <0xfdc8d000 0x1000>;
-			interrupts = <0 42 0>;
-			qcom,iommu-ctx-sids = <0x80 0x81 0x82 0x83 0x84 0x85>;
-			label = "venus_cp";
-		};
-
-		qcom,iommu-ctx@fdc8e000 {
-			reg = <0xfdc8e000 0x1000>;
-			interrupts = <0 42 0>;
-			qcom,iommu-ctx-sids = <0xc0 0xc6>;
-			label = "venus_fw";
-		};
-	};
-
-	kgsl_iommu: qcom,iommu@fdb10000 {
-		compatible = "qcom,msm-smmu-v2";
-		#address-cells = <1>;
-		#size-cells = <1>;
-		ranges;
-		reg = <0xfdb10000 0x10000>;
-		vdd-supply = <&gdsc_oxili_cx>;
-		qcom,needs-alt-core-clk;
-		status = "disabled";
-
-		qcom,iommu-bfb-regs =  <0x204c
-					0x2050
-					0x2514
-					0x2540
-					0x256c
-					0x20ac
-					0x215c
-					0x220c
-					0x2314
-					0x2394
-					0x2414
-					0x2008>;
-
-		qcom,iommu-bfb-data =  <0xffffffff
-					0xffffffff
-					0x00000004
-					0x00000010
-					0x00000000
-					0x00000000
-					0x00000001
-					0x00000021
-					0x0
-					0x1
-					0x81
-					0x0>;
-
-		qcom,iommu-ctx@fdb18000 {
-			reg = <0xfdb18000 0x1000>;
-			interrupts = <0 241 0>;
-			qcom,iommu-ctx-sids = <0>;
-			label = "gfx3d_user";
-		};
-
-		qcom,iommu-ctx@fdb19000 {
-			reg = <0xfdb19000 0x1000>;
-			interrupts = <0 241 0>;
-			qcom,iommu-ctx-sids = <1>;
-			label = "gfx3d_priv";
-		};
-	};
-
-	vfe_iommu: qcom,iommu@fda44000 {
-		compatible = "qcom,msm-smmu-v2";
-		#address-cells = <1>;
-		#size-cells = <1>;
-		ranges;
-		reg = <0xfda44000 0x10000>;
-		vdd-supply = <&gdsc_vfe>;
-		status = "disabled";
-
-		qcom,iommu-bfb-regs =  <0x204c
-					0x2050
-					0x2514
-					0x2540
-					0x256c
-					0x2314
-					0x2394
-					0x2414
-					0x20ac
-					0x215c
-					0x220c
-					0x2008
-					0x200c
-					0x2010
-					0x2014
-					0x2018
-					0x201c
-					0x2020>;
-
-		qcom,iommu-bfb-data =  <0xffffffff
-					0xffffffff
-					0x4
-					0x8
-					0x0
-					0x0
-					0x20
-					0x78
-					0x0
-					0x20
-					0x36
-					0x0
-					0x0
-					0x0
-					0x0
-					0x0
-					0x0
-					0x0>;
-
-		qcom,iommu-ctx@fda4c000 {
-			reg = <0xfda4c000 0x1000>;
-			interrupts = <0 65 0>;
-			qcom,iommu-ctx-sids = <0>;
-			label = "vfe0";
-		};
-
-		qcom,iommu-ctx@fda4d000 {
-			reg = <0xfda4d000 0x1000>;
-			interrupts = <0 65 0>;
-			qcom,iommu-ctx-sids = <1>;
-			label = "vfe1";
-		};
-
-		qcom,iommu-ctx@fda4e000 {
-			reg = <0xfda4e000 0x1000>;
-			interrupts = <0 65 0>;
-			qcom,iommu-ctx-sids = <2>;
-			label = "cpp";
-		};
-	};
-};
diff --git a/arch/arm/boot/dts/msm-pm8019.dtsi b/arch/arm/boot/dts/msm-pm8019.dtsi
index 322e601..689bf0f 100755
--- a/arch/arm/boot/dts/msm-pm8019.dtsi
+++ b/arch/arm/boot/dts/msm-pm8019.dtsi
@@ -159,6 +159,7 @@
 			#address-cells = <1>;
 			#size-cells = <0>;
 			interrupts = <0x0 0x31 0x0>;
+			interrupt-names = "eoc-int-en-set";
 			qcom,adc-bit-resolution = <15>;
 			qcom,adc-vdd-reference = <1800>;
 
diff --git a/arch/arm/boot/dts/msm-pm8026.dtsi b/arch/arm/boot/dts/msm-pm8026.dtsi
deleted file mode 100644
index 94db3ea..0000000
--- a/arch/arm/boot/dts/msm-pm8026.dtsi
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-&spmi_bus {
-	#address-cells = <1>;
-	#size-cells = <0>;
-	interrupt-controller;
-	#interrupt-cells = <3>;
-};
diff --git a/arch/arm/boot/dts/msm-pm8226.dtsi b/arch/arm/boot/dts/msm-pm8226.dtsi
new file mode 100644
index 0000000..de23f4c
--- /dev/null
+++ b/arch/arm/boot/dts/msm-pm8226.dtsi
@@ -0,0 +1,481 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+&spmi_bus {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	interrupt-controller;
+	#interrupt-cells = <3>;
+
+	qcom,pm8226@0 {
+		spmi-slave-container;
+		reg = <0x0>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		pm8226_gpios: gpios {
+			spmi-dev-container;
+			compatible = "qcom,qpnp-pin";
+			gpio-controller;
+			#gpio-cells = <2>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			label = "pm8226-gpio";
+
+			gpio@c000 {
+				reg = <0xc000 0x100>;
+				qcom,pin-num = <1>;
+			};
+
+			gpio@c100 {
+				reg = <0xc100 0x100>;
+				qcom,pin-num = <2>;
+			};
+
+			gpio@c200 {
+				reg = <0xc200 0x100>;
+				qcom,pin-num = <3>;
+			};
+
+			gpio@c300 {
+				reg = <0xc300 0x100>;
+				qcom,pin-num = <4>;
+			};
+
+			gpio@c400 {
+				reg = <0xc400 0x100>;
+				qcom,pin-num = <5>;
+			};
+
+			gpio@c500 {
+				reg = <0xc500 0x100>;
+				qcom,pin-num = <6>;
+			};
+
+			gpio@c600 {
+				reg = <0xc600 0x100>;
+				qcom,pin-num = <7>;
+			};
+
+			gpio@c700 {
+				reg = <0xc700 0x100>;
+				qcom,pin-num = <8>;
+			};
+		};
+
+		pm8226_mpps: mpps {
+			spmi-dev-container;
+			compatible = "qcom,qpnp-pin";
+			gpio-controller;
+			#gpio-cells = <2>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			label = "pm8226-mpp";
+
+			mpp@a000 {
+				reg = <0xa000 0x100>;
+				qcom,pin-num = <1>;
+			};
+
+			mpp@a100 {
+				reg = <0xa100 0x100>;
+				qcom,pin-num = <2>;
+			};
+
+			mpp@a200 {
+				reg = <0xa200 0x100>;
+				qcom,pin-num = <3>;
+			};
+
+			mpp@a300 {
+				reg = <0xa300 0x100>;
+				qcom,pin-num = <4>;
+			};
+
+			mpp@a400 {
+				reg = <0xa400 0x100>;
+				qcom,pin-num = <5>;
+			};
+
+			mpp@a500 {
+				reg = <0xa500 0x100>;
+				qcom,pin-num = <6>;
+			};
+
+			mpp@a600 {
+				reg = <0xa600 0x100>;
+				qcom,pin-num = <7>;
+			};
+
+			mpp@a700 {
+				reg = <0xa700 0x100>;
+				qcom,pin-num = <8>;
+			};
+		};
+
+		pm8226_vadc: vadc@3100 {
+			compatible = "qcom,qpnp-vadc";
+			reg = <0x3100 0x100>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <0x0 0x31 0x0>;
+			interrupt-names = "eoc-int-en-set";
+			qcom,adc-bit-resolution = <15>;
+			qcom,adc-vdd-reference = <1800>;
+
+			chan@8 {
+				label = "die_temp";
+				reg = <8>;
+				qcom,decimation = <0>;
+				qcom,pre-div-channel-scaling = <0>;
+				qcom,calibration-type = "absolute";
+				qcom,scale-function = <3>;
+				qcom,hw-settle-time = <0>;
+				qcom,fast-avg-setup = <0>;
+			};
+
+			chan@9 {
+				label = "ref_625mv";
+				reg = <9>;
+				qcom,decimation = <0>;
+				qcom,pre-div-channel-scaling = <0>;
+				qcom,calibration-type = "absolute";
+				qcom,scale-function = <0>;
+				qcom,hw-settle-time = <0>;
+				qcom,fast-avg-setup = <0>;
+			};
+
+			chan@a {
+				label = "ref_1250v";
+				reg = <0xa>;
+				qcom,decimation = <0>;
+				qcom,pre-div-channel-scaling = <0>;
+				qcom,calibration-type = "absolute";
+				qcom,scale-function = <0>;
+				qcom,hw-settle-time = <0>;
+				qcom,fast-avg-setup = <0>;
+			};
+		};
+
+		iadc@3600 {
+			compatible = "qcom,qpnp-iadc";
+			reg = <0x3600 0x100>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <0x0 0x36 0x0>;
+			interrupt-names = "eoc-int-en-set";
+			qcom,adc-bit-resolution = <16>;
+			qcom,adc-vdd-reference = <1800>;
+			qcom,rsense = <1500>;
+
+			chan@0 {
+				label = "internal_rsense";
+				reg = <0>;
+				qcom,decimation = <0>;
+				qcom,pre-div-channel-scaling = <1>;
+				qcom,calibration-type = "absolute";
+				qcom,scale-function = <0>;
+				qcom,hw-settle-time = <0>;
+				qcom,fast-avg-setup = <0>;
+			};
+		};
+	};
+
+	qcom,pm8226@1 {
+		spmi-slave-container;
+		reg = <0x1>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		regulator@1400 {
+			regulator-name = "8226_s1";
+			spmi-dev-container;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "qcom,qpnp-regulator";
+			reg = <0x1400 0x300>;
+			status = "disabled";
+
+			qcom,ctl@1400 {
+				reg = <0x1400 0x100>;
+			};
+			qcom,ps@1500 {
+				reg = <0x1500 0x100>;
+			};
+			qcom,freq@1600 {
+				reg = <0x1600 0x100>;
+			};
+		};
+
+		regulator@1700 {
+			regulator-name = "8226_s2";
+			spmi-dev-container;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "qcom,qpnp-regulator";
+			reg = <0x1700 0x300>;
+			status = "disabled";
+
+			qcom,ctl@1700 {
+				reg = <0x1700 0x100>;
+			};
+			qcom,ps@1800 {
+				reg = <0x1800 0x100>;
+			};
+			qcom,freq@1900 {
+				reg = <0x1900 0x100>;
+			};
+		};
+
+		regulator@1a00 {
+			regulator-name = "8226_s3";
+			spmi-dev-container;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "qcom,qpnp-regulator";
+			reg = <0x1a00 0x300>;
+			status = "disabled";
+
+			qcom,ctl@1a00 {
+				reg = <0x1a00 0x100>;
+			};
+			qcom,ps@1b00 {
+				reg = <0x1b00 0x100>;
+			};
+			qcom,freq@1c00 {
+				reg = <0x1c00 0x100>;
+			};
+		};
+
+		regulator@1d00 {
+			regulator-name = "8226_s4";
+			spmi-dev-container;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "qcom,qpnp-regulator";
+			reg = <0x1d00 0x300>;
+			status = "disabled";
+
+			qcom,ctl@1d00 {
+				reg = <0x1d00 0x100>;
+			};
+			qcom,ps@1e00 {
+				reg = <0x1e00 0x100>;
+			};
+			qcom,freq@1f00 {
+				reg = <0x1f00 0x100>;
+			};
+		};
+
+		regulator@2000 {
+			regulator-name = "8226_s5";
+			spmi-dev-container;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "qcom,qpnp-regulator";
+			reg = <0x2000 0x300>;
+			status = "disabled";
+
+			qcom,ctl@2000 {
+				reg = <0x2000 0x100>;
+			};
+			qcom,ps@2100 {
+				reg = <0x2100 0x100>;
+			};
+			qcom,freq@2200 {
+				reg = <0x2200 0x100>;
+			};
+		};
+
+		regulator@4000 {
+			regulator-name = "8226_l1";
+			reg = <0x4000 0x100>;
+			compatible = "qcom,qpnp-regulator";
+			status = "disabled";
+		};
+
+		regulator@4100 {
+			regulator-name = "8226_l2";
+			reg = <0x4100 0x100>;
+			compatible = "qcom,qpnp-regulator";
+			status = "disabled";
+		};
+
+		regulator@4200 {
+			regulator-name = "8226_l3";
+			reg = <0x4200 0x100>;
+			compatible = "qcom,qpnp-regulator";
+			status = "disabled";
+		};
+
+		regulator@4300 {
+			regulator-name = "8226_l4";
+			reg = <0x4300 0x100>;
+			compatible = "qcom,qpnp-regulator";
+			status = "disabled";
+		};
+
+		regulator@4400 {
+			regulator-name = "8226_l5";
+			reg = <0x4400 0x100>;
+			compatible = "qcom,qpnp-regulator";
+			status = "disabled";
+		};
+
+		regulator@4500 {
+			regulator-name = "8226_l6";
+			reg = <0x4500 0x100>;
+			compatible = "qcom,qpnp-regulator";
+			status = "disabled";
+		};
+
+		regulator@4600 {
+			regulator-name = "8226_l7";
+			reg = <0x4600 0x100>;
+			compatible = "qcom,qpnp-regulator";
+			status = "disabled";
+		};
+
+		regulator@4700 {
+			regulator-name = "8226_l8";
+			reg = <0x4700 0x100>;
+			compatible = "qcom,qpnp-regulator";
+			status = "disabled";
+		};
+
+		regulator@4800 {
+			regulator-name = "8226_l9";
+			reg = <0x4800 0x100>;
+			compatible = "qcom,qpnp-regulator";
+			status = "disabled";
+		};
+
+		regulator@4900 {
+			regulator-name = "8226_l10";
+			reg = <0x4900 0x100>;
+			compatible = "qcom,qpnp-regulator";
+			status = "disabled";
+		};
+
+		regulator@4b00 {
+			regulator-name = "8226_l12";
+			reg = <0x4b00 0x100>;
+			compatible = "qcom,qpnp-regulator";
+			status = "disabled";
+		};
+
+		regulator@4d00 {
+			regulator-name = "8226_l14";
+			reg = <0x4d00 0x100>;
+			compatible = "qcom,qpnp-regulator";
+			status = "disabled";
+		};
+
+		regulator@4e00 {
+			regulator-name = "8226_l15";
+			reg = <0x4e00 0x100>;
+			compatible = "qcom,qpnp-regulator";
+			status = "disabled";
+		};
+
+		regulator@4f00 {
+			regulator-name = "8226_l16";
+			reg = <0x4f00 0x100>;
+			compatible = "qcom,qpnp-regulator";
+			status = "disabled";
+		};
+
+		regulator@5000 {
+			regulator-name = "8226_l17";
+			reg = <0x5000 0x100>;
+			compatible = "qcom,qpnp-regulator";
+			status = "disabled";
+		};
+
+		regulator@5100 {
+			regulator-name = "8226_l18";
+			reg = <0x5100 0x100>;
+			compatible = "qcom,qpnp-regulator";
+			status = "disabled";
+		};
+
+		regulator@5200 {
+			regulator-name = "8226_l19";
+			reg = <0x5200 0x100>;
+			compatible = "qcom,qpnp-regulator";
+			status = "disabled";
+		};
+
+		regulator@5300 {
+			regulator-name = "8226_l20";
+			reg = <0x5300 0x100>;
+			compatible = "qcom,qpnp-regulator";
+			status = "disabled";
+		};
+
+		regulator@5400 {
+			regulator-name = "8226_l21";
+			reg = <0x5400 0x100>;
+			compatible = "qcom,qpnp-regulator";
+			status = "disabled";
+		};
+
+		regulator@5500 {
+			regulator-name = "8226_l22";
+			reg = <0x5500 0x100>;
+			compatible = "qcom,qpnp-regulator";
+			status = "disabled";
+		};
+
+		regulator@5600 {
+			regulator-name = "8226_l23";
+			reg = <0x5600 0x100>;
+			compatible = "qcom,qpnp-regulator";
+			status = "disabled";
+		};
+
+		regulator@5700 {
+			regulator-name = "8226_l24";
+			reg = <0x5700 0x100>;
+			compatible = "qcom,qpnp-regulator";
+			status = "disabled";
+		};
+
+		regulator@5900 {
+			regulator-name = "8226_l26";
+			reg = <0x5900 0x100>;
+			compatible = "qcom,qpnp-regulator";
+			status = "disabled";
+		};
+
+		regulator@5a00 {
+			regulator-name = "8226_l27";
+			reg = <0x5a00 0x100>;
+			compatible = "qcom,qpnp-regulator";
+			status = "disabled";
+		};
+
+		regulator@5b00 {
+			regulator-name = "8226_l28";
+			reg = <0x5b00 0x100>;
+			compatible = "qcom,qpnp-regulator";
+			status = "disabled";
+		};
+
+		regulator@8000 {
+			regulator-name = "8226_lvs1";
+			reg = <0x8000 0x100>;
+			compatible = "qcom,qpnp-regulator";
+			status = "disabled";
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/msm-pm8841.dtsi b/arch/arm/boot/dts/msm-pm8841.dtsi
index 1e0e5dfa..68691c7 100644
--- a/arch/arm/boot/dts/msm-pm8841.dtsi
+++ b/arch/arm/boot/dts/msm-pm8841.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/boot/dts/msm-pm8941.dtsi b/arch/arm/boot/dts/msm-pm8941.dtsi
index 098f543..54f603d 100644
--- a/arch/arm/boot/dts/msm-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm-pm8941.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -65,19 +65,20 @@
 			#size-cells = <1>;
 			status = "disabled";
 
-			qcom,bms-r-sense-mohm = <2>;
-			qcom,bms-v-cutoff-uv = <3400000>;
-			qcom,bms-max-voltage-uv = <4200000>;
-			qcom,bms-r-conn-mohm = <18>;
-			qcom,bms-shutdown-soc-valid-limit = <20>;
-			qcom,bms-adjust-soc-low-threshold = <25>;
-			qcom,bms-adjust-soc-high-threshold = <45>;
-			qcom,bms-low-soc-calculate-soc-threshold = <15>;
-			qcom,bms-low-soc-calculate-soc-ms = <5000>;
-			qcom,bms-calculate-soc-ms = <20000>;
-			qcom,bms-chg-term-ua = <100000>;
-			qcom,bms-batt-type = <0>;
-			qcom,bms-use-external-rsense;
+			qcom,r-sense-uohm = <10000>;
+			qcom,v-cutoff-uv = <3400000>;
+			qcom,max-voltage-uv = <4200000>;
+			qcom,r-conn-mohm = <18>;
+			qcom,shutdown-soc-valid-limit = <20>;
+			qcom,adjust-soc-low-threshold = <25>;
+			qcom,adjust-soc-high-threshold = <45>;
+			qcom,ocv-voltage-high-threshold-uv = <3750000>;
+			qcom,ocv-voltage-low-threshold-uv = <3650000>;
+			qcom,low-soc-calculate-soc-threshold = <15>;
+			qcom,low-soc-calculate-soc-ms = <5000>;
+			qcom,calculate-soc-ms = <20000>;
+			qcom,chg-term-ua = <100000>;
+			qcom,batt-type = <0>;
 
 			qcom,bms-iadc@3800 {
 				reg = <0x3800 0x100>;
@@ -137,6 +138,7 @@
 			qcom,chg-ibatmax-ma = <1500>;
 			qcom,chg-ibatterm-ma = <200>;
 			qcom,chg-ibatsafe-ma = <1500>;
+			qcom,chg-thermal-mitigation = <1500 700 600 325>;
 
 			qcom,chg-chgr@1000 {
 				status = "disabled";
@@ -630,7 +632,7 @@
 				qcom,pre-div-channel-scaling = <0>;
 				qcom,calibration-type = "ratiometric";
 				qcom,scale-function = <1>;
-				qcom,hw-settle-time = <0>;
+				qcom,hw-settle-time = <2>;
 				qcom,fast-avg-setup = <0>;
 			};
 
@@ -641,7 +643,7 @@
 				qcom,pre-div-channel-scaling = <0>;
 				qcom,calibration-type = "ratiometric";
 				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
+				qcom,hw-settle-time = <2>;
 				qcom,fast-avg-setup = <0>;
 			};
 
@@ -652,7 +654,7 @@
 				qcom,pre-div-channel-scaling = <0>;
 				qcom,calibration-type = "ratiometric";
 				qcom,scale-function = <4>;
-				qcom,hw-settle-time = <0>;
+				qcom,hw-settle-time = <2>;
 				qcom,fast-avg-setup = <0>;
 			};
 
@@ -663,7 +665,7 @@
 				qcom,pre-div-channel-scaling = <0>;
 				qcom,calibration-type = "ratiometric";
 				qcom,scale-function = <2>;
-				qcom,hw-settle-time = <0>;
+				qcom,hw-settle-time = <2>;
 				qcom,fast-avg-setup = <0>;
 			};
 
@@ -674,7 +676,7 @@
 				qcom,pre-div-channel-scaling = <0>;
 				qcom,calibration-type = "ratiometric";
 				qcom,scale-function = <2>;
-				qcom,hw-settle-time = <0>;
+				qcom,hw-settle-time = <2>;
 				qcom,fast-avg-setup = <0>;
 			};
 
@@ -685,7 +687,7 @@
 				qcom,pre-div-channel-scaling = <0>;
 				qcom,calibration-type = "ratiometric";
 				qcom,scale-function = <2>;
-				qcom,hw-settle-time = <0>;
+				qcom,hw-settle-time = <2>;
 				qcom,fast-avg-setup = <0>;
 			};
 
@@ -696,7 +698,7 @@
 				qcom,pre-div-channel-scaling = <0>;
 				qcom,calibration-type = "ratiometric";
 				qcom,scale-function = <2>;
-				qcom,hw-settle-time = <0>;
+				qcom,hw-settle-time = <2>;
 				qcom,fast-avg-setup = <0>;
 			};
 
@@ -707,7 +709,7 @@
 				qcom,pre-div-channel-scaling = <0>;
 				qcom,calibration-type = "ratiometric";
 				qcom,scale-function = <2>;
-				qcom,hw-settle-time = <0>;
+				qcom,hw-settle-time = <2>;
 				qcom,fast-avg-setup = <0>;
 			};
 
@@ -718,7 +720,7 @@
 				qcom,pre-div-channel-scaling = <0>;
 				qcom,calibration-type = "ratiometric";
 				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
+				qcom,hw-settle-time = <2>;
 				qcom,fast-avg-setup = <0>;
 			};
 		};
@@ -768,7 +770,7 @@
 				qcom,pre-div-channel-scaling = <0>;
 				qcom,calibration-type = "ratiometric";
 				qcom,scale-function = <2>;
-				qcom,hw-settle-time = <0>;
+				qcom,hw-settle-time = <2>;
 				qcom,fast-avg-setup = <0>;
 				qcom,btm-channel-number = <0x48>;
 			};
@@ -780,7 +782,7 @@
 				qcom,pre-div-channel-scaling = <0>;
 				qcom,calibration-type = "ratiometric";
 				qcom,scale-function = <1>;
-				qcom,hw-settle-time = <0xf>;
+				qcom,hw-settle-time = <2>;
 				qcom,fast-avg-setup = <0>;
 				qcom,btm-channel-number = <0x68>;
 			};
@@ -792,7 +794,7 @@
 				qcom,pre-div-channel-scaling = <0>;
 				qcom,calibration-type = "absolute";
 				qcom,scale-function = <2>;
-				qcom,hw-settle-time = <0>;
+				qcom,hw-settle-time = <2>;
 				qcom,fast-avg-setup = <0>;
 				qcom,btm-channel-number = <0x70>;
 			};
@@ -804,7 +806,7 @@
 				qcom,pre-div-channel-scaling = <0>;
 				qcom,calibration-type = "ratiometric";
 				qcom,scale-function = <2>;
-				qcom,hw-settle-time = <0>;
+				qcom,hw-settle-time = <2>;
 				qcom,fast-avg-setup = <0>;
 				qcom,btm-channel-number = <0x78>;
 			};
@@ -816,7 +818,7 @@
 				qcom,pre-div-channel-scaling = <0>;
 				qcom,calibration-type = "ratiometric";
 				qcom,scale-function = <2>;
-				qcom,hw-settle-time = <0>;
+				qcom,hw-settle-time = <2>;
 				qcom,fast-avg-setup = <0>;
 				qcom,btm-channel-number = <0x80>;
 			};
@@ -1101,6 +1103,13 @@
 			status = "disabled";
 		};
 
+		qcom,vibrator@c000 {
+			compatible = "qcom,qpnp-vibrator";
+			reg = <0xc000 0x100>;
+			label = "vibrator";
+			status = "disabled";
+		};
+
 		qcom,leds@d000 {
 			compatible = "qcom,leds-qpnp";
 			reg = <0xd000 0x100>;
diff --git a/arch/arm/boot/dts/msm-pm8x41-rpm-regulator.dtsi b/arch/arm/boot/dts/msm-pm8x41-rpm-regulator.dtsi
index aced482..6e67dd8 100644
--- a/arch/arm/boot/dts/msm-pm8x41-rpm-regulator.dtsi
+++ b/arch/arm/boot/dts/msm-pm8x41-rpm-regulator.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/boot/dts/msm8226-bus.dtsi b/arch/arm/boot/dts/msm8226-bus.dtsi
new file mode 100644
index 0000000..28d0840
--- /dev/null
+++ b/arch/arm/boot/dts/msm8226-bus.dtsi
@@ -0,0 +1,1126 @@
+/* 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.
+ */
+
+/ {
+	msm-mmss-noc@fc478000 {
+		compatible = "msm-bus-fabric";
+		reg = <0xfc478000 0x00004000>;
+		cell-id = <2048>;
+		label = "msm_mmss_noc";
+		qcom,fabclk-dual = "bus_clk";
+		qcom,fabclk-active = "bus_a_clk";
+		qcom,ntieredslaves = <0>;
+		qcom,qos-freq = <4800>;
+		qcom,hw-sel = "NoC";
+		qcom,rpm-en;
+
+		mas-gfx3d {
+			cell-id = <26>;
+			label = "mas-gfx3d";
+			qcom,masterp = <2>;
+			qcom,tier = <2>;
+			qcom,hw-sel = "NoC";
+			qcom,perm-mode = "Bypass";
+			qcom,mode = "Bypass";
+			qcom,ws = <10000>;
+			qcom,qport = <2>;
+			qcom,mas-hw-id = <6>;
+		};
+
+		mas-jpeg {
+			cell-id = <62>;
+			label = "mas-jpeg";
+			qcom,masterp = <4>;
+			qcom,tier = <2>;
+			qcom,hw-sel = "NoC";
+			qcom,perm-mode = "Bypass";
+			qcom,mode = "Bypass";
+			qcom,qport = <0>;
+			qcom,ws = <10000>;
+			qcom,mas-hw-id = <7>;
+		};
+
+		mas-mdp-port0 {
+			cell-id = <22>;
+			label = "mas-mdp-port0";
+			qcom,masterp = <5>;
+			qcom,tier = <2>;
+			qcom,hw-sel = "NoC";
+			qcom,perm-mode = "Bypass";
+			qcom,mode = "Bypass";
+			qcom,qport = <1>;
+			qcom,ws = <10000>;
+			qcom,mas-hw-id = <8>;
+		};
+
+		mas-video-p0 {
+			cell-id = <63>;
+			label = "mas-video-p0";
+			qcom,masterp = <6>;
+			qcom,tier = <2>;
+			qcom,hw-sel = "NoC";
+			qcom,perm-mode = "Bypass";
+			qcom,mode = "Bypass";
+			qcom,ws = <10000>;
+			qcom,qport = <4>;
+			qcom,mas-hw-id = <9>;
+		};
+
+		mas-vfe {
+			cell-id = <29>;
+			label = "mas-vfe";
+			qcom,masterp = <16>;
+			qcom,tier = <2>;
+			qcom,hw-sel = "NoC";
+			qcom,perm-mode = "Bypass";
+			qcom,mode = "Bypass";
+			qcom,ws = <10000>;
+			qcom,qport = <6>;
+			qcom,mas-hw-id = <11>;
+		};
+
+		fab-cnoc {
+			cell-id = <5120>;
+			label = "fab-cnoc";
+			qcom,gateway;
+			qcom,masterp = <0 1>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "RPM";
+			qcom,mas-hw-id = <4>;
+		};
+
+		fab-bimc {
+			cell-id = <0>;
+			label = "fab-bimc";
+			qcom,gateway;
+			qcom,slavep = <16>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <16>;
+		};
+
+		slv-camera-cfg {
+			cell-id = <589>;
+			label = "slv-camera-cfg";
+			qcom,slavep = <0>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <3>;
+		};
+
+		slv-display-cfg {
+			cell-id = <590>;
+			label = "slv-display-cfg";
+			qcom,slavep = <1>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <4>;
+		};
+
+		slv-ocmem-cfg {
+			cell-id = <591>;
+			label = "slv-ocmem-cfg";
+			qcom,slavep = <2>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <5>;
+		};
+
+		slv-cpr-cfg {
+			cell-id = <592>;
+			label = "slv-cpr-cfg";
+			qcom,slavep = <3>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <6>;
+		};
+
+		slv-cpr-xpu-cfg {
+			cell-id = <593>;
+			label = "slv-cpr-xpu-cfg";
+			qcom,slavep = <4>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <7>;
+		};
+
+		slv-misc-cfg {
+			cell-id = <594>;
+			label = "slv-misc-cfg";
+			qcom,slavep = <6>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <8>;
+		};
+
+		slv-misc-xpu-cfg {
+			cell-id = <595>;
+			label = "slv-misc-xpu-cfg";
+			qcom,slavep = <7>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <9>;
+		};
+
+		slv-venus-cfg {
+			cell-id = <596>;
+			label = "slv-venus-cfg";
+			qcom,slavep = <8>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <10>;
+		};
+
+		slv-gfx3d-cfg {
+			cell-id = <598>;
+			label = "slv-gfx3d-cfg";
+			qcom,slavep = <9>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <11>;
+		};
+
+		slv-mmss-clk-cfg {
+			cell-id = <599>;
+			label = "slv-mmss-clk-cfg";
+			qcom,slavep = <11>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <12>;
+		};
+
+		slv-mmss-clk-xpu-cfg {
+			cell-id = <600>;
+			label = "slv-mmss-clk-xpu-cfg";
+			qcom,slavep = <12>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <13>;
+		};
+
+		slv-mnoc-mpu-cfg {
+			cell-id = <601>;
+			label = "slv-mnoc-mpu-cfg";
+			qcom,slavep = <13>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <14>;
+		};
+
+		slv-onoc-mpu-cfg {
+			cell-id = <602>;
+			label = "slv-onoc-mpu-cfg";
+			qcom,slavep = <14>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <15>;
+		};
+
+		slv-service-mnoc {
+			cell-id = <603>;
+			label = "slv-service-mnoc";
+			qcom,slavep = <18>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <17>;
+		};
+
+	};
+
+	msm-sys-noc@fc460000 {
+		compatible = "msm-bus-fabric";
+		reg = <0xfc460000 0x00004000>;
+		cell-id = <1024>;
+		label = "msm_sys_noc";
+		qcom,fabclk-dual = "bus_clk";
+		qcom,fabclk-active = "bus_a_clk";
+		qcom,ntieredslaves = <0>;
+		qcom,qos-freq = <4800>;
+		qcom,hw-sel = "NoC";
+		qcom,rpm-en;
+
+		mas-lpass-ahb {
+			cell-id = <52>;
+			label = "mas-lpass-ahb";
+			qcom,masterp = <0>;
+			qcom,tier = <2>;
+			qcom,qport = <0>;
+			qcom,mas-hw-id = <18>;
+			qcom,mode = "Fixed";
+			qcom,prio-rd = <2>;
+			qcom,prio-wr = <2>;
+		};
+
+		mas-qdss-bam {
+			cell-id = <53>;
+			label = "mas-qdss-bam";
+			qcom,masterp = <1>;
+			qcom,tier = <2>;
+			qcom,mode = "Fixed";
+			qcom,qport = <1>;
+			qcom,mas-hw-id = <19>;
+		};
+
+		mas-snoc-cfg {
+			cell-id = <54>;
+			label = "mas-snoc-cfg";
+			qcom,masterp = <2>;
+			qcom,tier = <2>;
+			qcom,mas-hw-id = <20>;
+		};
+
+		fab-bimc {
+			cell-id = <0>;
+			label= "fab-bimc";
+			qcom,gateway;
+			qcom,slavep = <7>;
+			qcom,masterp = <3>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <21>;
+			qcom,slv-hw-id = <24>;
+		};
+
+		fab-cnoc {
+			cell-id = <5120>;
+			label = "fab-cnoc";
+			qcom,gateway;
+			qcom,slavep = <8>;
+			qcom,masterp = <4>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <22>;
+			qcom,slv-hw-id = <25>;
+		};
+
+		fab-pnoc {
+			cell-id = <4096>;
+			label = "fab-pnoc";
+			qcom,gateway;
+			qcom,slavep = <10>;
+			qcom,masterp = <10>;
+			qcom,buswidth = <8>;
+			qcom,qport = <8>;
+			qcom,mas-hw-id = <29>;
+			qcom,slv-hw-id = <28>;
+			qcom,mode = "Fixed";
+			qcom,prio-rd = <2>;
+			qcom,prio-wr = <2>;
+		};
+
+		fab-ovnoc {
+			cell-id = <6144>;
+			label = "fab-ovnoc";
+			qcom,gateway;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <53>;
+			qcom,slv-hw-id = <77>;
+		};
+
+		mas-crypto-core0 {
+			cell-id = <55>;
+			label = "mas-crypto-core0";
+			qcom,masterp = <5>;
+			qcom,tier = <2>;
+			qcom,mode = "Fixed";
+/*			qcom,qport = <2>;*/
+			qcom,mas-hw-id = <23>;
+			qcom,hw-sel = "NoC";
+			qcom,prio-rd = <1>;
+			qcom,prio-wr = <1>;
+		};
+
+		mas-lpass-proc {
+			cell-id = <11>;
+			label = "mas-lpass-proc";
+			qcom,masterp = <6>;
+			qcom,tier = <2>;
+			qcom,qport = <4>;
+			qcom,mas-hw-id = <25>;
+			qcom,mode = "Fixed";
+			qcom,prio-rd = <2>;
+			qcom,prio-wr = <2>;
+		};
+
+		mas-mss {
+			cell-id = <38>;
+			label = "mas-mss";
+			qcom,masterp = <7>;
+			qcom,tier = <2>;
+			qcom,mas-hw-id = <26>;
+		};
+
+		mas-mss-nav {
+			cell-id = <57>;
+			label = "mas-mss-nav";
+			qcom,masterp = <8>;
+			qcom,tier = <2>;
+			qcom,mas-hw-id = <27>;
+		};
+
+		mas-ocmem-dma {
+			cell-id = <58>;
+			label = "mas-ocmem-dma";
+			qcom,masterp = <9>;
+			qcom,tier = <2>;
+			qcom,mode = "Fixed";
+			qcom,qport = <7>;
+			qcom,mas-hw-id = <28>;
+		};
+
+		mas-wcss {
+			cell-id = <59>;
+			label = "mas-wcss";
+			qcom,masterp = <11>;
+			qcom,tier = <2>;
+			qcom,mas-hw-id = <30>;
+		};
+
+		mas-qdss-etr {
+			cell-id = <60>;
+			label = "mas-qdss-etr";
+			qcom,masterp = <12>;
+			qcom,tier = <2>;
+			qcom,qport = <10>;
+			qcom,mode = "Fixed";
+			qcom,mas-hw-id = <31>;
+		};
+
+		slv-ampss {
+			cell-id = <520>;
+			label = "slv-ampss";
+			qcom,slavep = <1>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <20>;
+		};
+
+		slv-lpass {
+			cell-id = <522>;
+			label = "slv-lpass";
+			qcom,slavep = <2>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <21>;
+		};
+
+		slv-wcss {
+			cell-id = <584>;
+			label = "slv-wcss";
+			qcom,slavep = <6>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <23>;
+		};
+
+		slv-ocimem {
+			cell-id = <585>;
+			label = "slv-ocimem";
+			qcom,slavep = <9>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <26>;
+		};
+
+		slv-service-snoc {
+			cell-id = <587>;
+			label = "slv-service-snoc";
+			qcom,slavep = <11>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <29>;
+		};
+
+		slv-qdss-stm {
+			cell-id = <588>;
+			label = "slv-qdss-stm";
+			qcom,slavep = <12>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <30>;
+		};
+
+	};
+
+	msm-periph-noc@fc468000 {
+		compatible = "msm-bus-fabric";
+		reg = <0xfc468000 0x00004000>;
+		cell-id = <4096>;
+		label = "msm_periph_noc";
+		qcom,fabclk-dual = "bus_clk";
+		qcom,fabclk-active = "bus_a_clk";
+		qcom,ntieredslaves = <0>;
+		qcom,hw-sel = "NoC";
+		qcom,rpm-en;
+
+		mas-pnoc-cfg {
+			cell-id = <88>;
+			label = "mas-pnoc-cfg";
+			qcom,masterp = <7>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <43>;
+		};
+
+		mas-sdcc-1 {
+			cell-id = <78>;
+			label = "mas-sdcc-1";
+			qcom,masterp = <0>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <33>;
+		};
+
+		mas-sdcc-3 {
+			cell-id = <79>;
+			label = "mas-sdcc-3";
+			qcom,masterp = <1>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <34>;
+		};
+
+		mas-sdcc-2 {
+			cell-id = <81>;
+			label = "mas-sdcc-2";
+			qcom,masterp = <2>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <35>;
+		};
+
+		mas-bam-dma {
+			cell-id = <83>;
+			label = "mas-bam-dma";
+			qcom,masterp = <3>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <38>;
+		};
+
+		mas-usb-hsic {
+			cell-id = <85>;
+			label = "mas-usb-hsic";
+			qcom,masterp = <4>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <40>;
+		};
+
+		mas-blsp-1 {
+			cell-id = <86>;
+			label = "mas-blsp-1";
+			qcom,masterp = <5>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <41>;
+		};
+
+		mas-usb-hs {
+			cell-id = <87>;
+			label = "mas-usb-hs";
+			qcom,masterp = <6>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <42>;
+		};
+
+		fab-snoc {
+			cell-id = <1024>;
+			label = "fab-snoc";
+			qcom,gateway;
+			qcom,slavep = <12>;
+			qcom,masterp = <8>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <45>;
+			qcom,mas-hw-id = <44>;
+		};
+
+		slv-sdcc-1 {
+			cell-id = <606>;
+			label = "slv-sdcc-1";
+			qcom,slavep = <0>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <31>;
+		};
+
+		slv-sdcc-3 {
+			cell-id = <607>;
+			label = "slv-sdcc-3";
+			qcom,slavep = <1>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <32>;
+		};
+
+		slv-sdcc-2 {
+			cell-id = <608>;
+			label = "slv-sdcc-2";
+			qcom,slavep = <2>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <33>;
+		};
+
+		slv-bam-dma {
+			cell-id = <610>;
+			label = "slv-bam-dma";
+			qcom,slavep = <3>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <36>;
+		};
+
+		slv-usb-hsic {
+			cell-id = <612>;
+			label = "slv-usb-hsic";
+			qcom,slavep = <4>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <38>;
+		};
+
+		slv-blsp-1 {
+			cell-id = <613>;
+			label = "slv-blsp-1";
+			qcom,slavep = <5>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <39>;
+		};
+
+		slv-usb-hs {
+			cell-id = <614>;
+			label = "slv-usb-hs";
+			qcom,slavep = <6>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <40>;
+		};
+
+		slv-pdm	{
+			cell-id = <615>;
+			label = "slv-pdm";
+			qcom,slavep = <7>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <41>;
+		};
+
+		slv-periph-apu-cfg {
+			cell-id = <616>;
+			label = "slv-periph-apu-cfg";
+			qcom,slavep = <8>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <42>;
+		};
+
+		slv-pnoc-mpu-cfg {
+			cell-id = <617>;
+			label = "slv-pnoc-mpu-cfg";
+			qcom,slavep = <9>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <43>;
+		};
+
+		slv-prng {
+			cell-id = <618>;
+			label = "slv-prng";
+			qcom,slavep = <10>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <44>;
+		};
+
+		slv-service-pnoc {
+			cell-id = <619>;
+			label = "slv-service-pnoc";
+			qcom,slavep = <12>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <46>;
+		};
+
+	};
+
+	msm-config-noc@fc480000 {
+		compatible = "msm-bus-fabric";
+		reg = <0xfc480000 0x00004000>;
+		cell-id = <5120>;
+		label = "msm_config_noc";
+		qcom,fabclk-dual = "bus_clk";
+		qcom,fabclk-active = "bus_a_clk";
+		qcom,ntieredslaves = <0>;
+		qcom,hw-sel = "NoC";
+		qcom,rpm-en;
+
+		mas-rpm-inst {
+			cell-id = <72>;
+			label = "mas-rpm-inst";
+			qcom,masterp = <0>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <45>;
+		};
+
+		mas-rpm-data {
+			cell-id = <73>;
+			label = "mas-rpm-data";
+			qcom,masterp = <1>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <46>;
+		};
+
+		mas-rpm-sys {
+			cell-id = <74>;
+			label = "mas-rpm-sys";
+			qcom,masterp = <2>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <47>;
+		};
+
+		mas-dehr {
+			cell-id = <75>;
+			label = "mas-dehr";
+			qcom,masterp = <3>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <48>;
+		};
+
+		mas-qdss-dsp {
+			cell-id = <76>;
+			label = "mas-qdss-dap";
+			qcom,masterp = <4>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <49>;
+		};
+
+		mas-spdm {
+			cell-id = <36>;
+			label = "mas-spdm";
+			qcom,masterp = <5>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <50>;
+		};
+
+		mas-tic	{
+			cell-id = <77>;
+			label = "mas-tic";
+			qcom,masterp = <6>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <51>;
+		};
+
+		slv-clk-ctl {
+			cell-id = <620>;
+			label = "slv-clk-ctl";
+			qcom,slavep = <1>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <47>;
+		};
+
+		slv-cnoc-mss {
+			cell-id = <621>;
+			label = "slv-cnoc-mss";
+			qcom,slavep = <2>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <48>;
+		};
+
+		slv-security {
+			cell-id = <622>;
+			label = "slv-security";
+			qcom,slavep = <3>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <49>;
+		};
+
+		slv-tcsr {
+			cell-id = <623>;
+			label = "slv-tcsr";
+			qcom,slavep = <4>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <50>;
+		};
+
+		slv-tlmm {
+			cell-id = <624>;
+			label = "slv-tlmm";
+			qcom,slavep = <5>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <51>;
+		};
+
+		slv-crypto-0-cfg {
+			cell-id = <625>;
+			label = "slv-crypto-0-cfg";
+			qcom,slavep = <6>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <52>;
+		};
+
+		slv-imem-cfg {
+			cell-id = <627>;
+			label = "slv-imem-cfg";
+			qcom,slavep = <7>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <54>;
+		};
+
+		slv-message-ram	{
+			cell-id = <628>;
+			label = "slv-message-ram";
+			qcom,slavep = <8>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <55>;
+		};
+
+		slv-bimc-cfg {
+			cell-id = <629>;
+			label = "slv-bimc-cfg";
+			qcom,slavep = <9>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <56>;
+		};
+
+		slv-boot-rom {
+			cell-id = <630>;
+			label = "slv-boot-rom";
+			qcom,slavep = <10>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <57>;
+		};
+
+		slv-pmic-arb {
+			cell-id = <632>;
+			label = "slv-pmic-arb";
+			qcom,slavep = <12>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <59>;
+		};
+
+		slv-spdm-wrapper {
+			cell-id = <633>;
+			label = "slv-spdm-wrapper";
+			qcom,slavep = <13>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <60>;
+		};
+
+		slv-dehr-cfg {
+			cell-id = <634>;
+			label = "slv-dehr-cfg";
+			qcom,slavep = <14>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <61>;
+		};
+
+		slv-mpm	{
+			cell-id = <536>;
+			label = "slv-mpm";
+			qcom,slavep = <15>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <62>;
+		};
+
+		slv-qdss-cfg {
+			cell-id = <635>;
+			label = "slv-qdss-cfg";
+			qcom,slavep = <16>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <63>;
+		};
+
+		slv-rbcpr-cfg {
+			cell-id = <636>;
+			label = "slv-rbcpr-cfg";
+			qcom,slavep = <17>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <64>;
+		};
+
+		slv-rbcpr-qdss-apu-cfg {
+			cell-id = <637>;
+			label = "slv-rbcpr-qdss-apu-cfg";
+			qcom,slavep = <18>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <65>;
+		};
+
+		fab-snoc {
+			cell-id = <1024>;
+			label = "fab-snoc";
+			qcom,gateway;
+			qcom,slavep = <26>;
+			qcom,masterp = <7>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <52>;
+			qcom,slv-hw-id = <75>;
+		};
+
+		slv-cnoc-mnoc-mmss-cfg {
+			cell-id = <631>;
+			label = "slv-cnoc-mnoc-mmss-cfg";
+			qcom,slavep = <11>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <58>;
+		};
+
+		slv-cnoc-mnoc-cfg {
+			cell-id = <640>;
+			label = "slv-cnoc-mnoc-cfg";
+			qcom,slavep = <19>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <66>;
+		};
+
+		slv-pnoc-cfg {
+			cell-id = <641>;
+			label = "slv-pnoc-cfg";
+			qcom,slavep = <21>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <69>;
+		};
+
+		slv-snoc-mpu-cfg {
+			cell-id = <638>;
+			label = "slv-snoc-mpu-cfg";
+			qcom,slavep = <20>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <67>;
+		};
+
+		slv-snoc-cfg {
+			cell-id = <642>;
+			label = "slv-snoc-cfg";
+			qcom,slavep = <22>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <70>;
+		};
+
+		slv-phy-apu-cfg {
+			cell-id = <644>;
+			label = "slv-phy-apu-cfg";
+			qcom,slavep = <23>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <72>;
+		};
+
+		slv-ebi1-phy-cfg {
+			cell-id = <645>;
+			label = "slv-ebi1-phy-cfg";
+			qcom,slavep = <24>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <73>;
+		};
+
+		slv-rpm {
+			cell-id = <534>;
+			label = "slv-rpm";
+			qcom,slavep = <25>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <74>;
+		};
+
+		slv-service-cnoc {
+			cell-id = <646>;
+			label = "slv-service-cnoc";
+			qcom,slavep = <27>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <76>;
+		};
+
+	};
+
+	msm-bimc@0xfc380000 {
+		compatible = "msm-bus-fabric";
+		reg = <0xfc380000 0x0006A000>;
+		cell-id = <0>;
+		label = "msm_bimc";
+		qcom,fabclk-dual = "mem_clk";
+		qcom,fabclk-active = "mem_a_clk";
+		qcom,ntieredslaves = <0>;
+		qcom,qos-freq = <4800>;
+		qcom,hw-sel = "BIMC";
+		qcom,rpm-en;
+
+		mas-ampss-m0 {
+			cell-id = <1>;
+			label = "mas-ampss-m0";
+			qcom,masterp = <0>;
+			qcom,tier = <2>;
+			qcom,hw-sel = "BIMC";
+			qcom,mode = "Fixed";
+			qcom,qport = <0>;
+			qcom,ws = <10000>;
+			qcom,mas-hw-id = <0>;
+			qcom,prio-rd = <1>;
+			qcom,prio-wr = <1>;
+		};
+
+		mas-mss-proc {
+			cell-id = <65>;
+			label = "mas-mss-proc";
+			qcom,masterp = <1>;
+			qcom,tier = <2>;
+			qcom,hw-sel = "RPM";
+			qcom,mas-hw-id = <1>;
+		};
+
+		fab-mmss-noc {
+			cell-id = <2048>;
+			label = "fab_mmss_noc";
+			qcom,gateway;
+			qcom,masterp = <2>;
+			qcom,qport = <2>;
+			qcom,buswidth = <8>;
+			qcom,ws = <10000>;
+			qcom,mas-hw-id = <2>;
+			qcom,hw-sel = "BIMC";
+			qcom,mode = "Bypass";
+		};
+
+		fab-snoc {
+			cell-id = <1024>;
+			label = "fab-snoc";
+			qcom,gateway;
+			qcom,slavep = <2>;
+			qcom,masterp = <4>;
+			qcom,qport = <4>;
+			qcom,buswidth = <8>;
+			qcom,ws = <10000>;
+			qcom,mas-hw-id = <3>;
+			qcom,slv-hw-id = <2>;
+		};
+
+		slv-ebi-ch0 {
+			cell-id = <512>;
+			label = "slv-ebi-ch0";
+			qcom,slavep = <0>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <0>;
+			qcom,mode = "Bypass";
+		};
+
+		slv-ampss-l2 {
+			cell-id = <514>;
+			label = "slv-ampss-l2";
+			qcom,slavep = <1>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <1>;
+		};
+	};
+
+	msm-ocmem-vnoc@6144 {
+		compatible = "msm-bus-fabric";
+		reg = <0x6144 0x2>;
+		cell-id = <6144>;
+		label = "msm-ocmem-vnoc";
+		qcom,ntieredslaves = <0>;
+		qcom,hw-sel = "NoC";
+		qcom,rpm-en;
+		qcom,virt;
+
+		mas-v-ocmem-gfx3d {
+			cell-id = <89>;
+			label = "mas-v-ocmem-gfx3d";
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <55>;
+		};
+
+		slv-ocmem {
+			cell-id = <604>;
+			label = "slv-ocmem";
+			qcom,slavep = <0 1>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,slv-hw-id = <18>;
+			qcom,slaveclk-dual = "ocmem_clk";
+			qcom,slaveclk-active = "ocmem_a_clk";
+		};
+
+		fab-snoc {
+			cell-id = <1024>;
+			label = "fab-snoc";
+			qcom,gateway;
+			qcom,buswidth = <32>;
+			qcom,ws = <10000>;
+			qcom,mas-hw-id = <57>;
+			qcom,slv-hw-id = <80>;
+		};
+
+		fab-onoc {
+			cell-id = <3072>;
+			label = "fab-onoc";
+			qcom,gateway;
+			qcom,buswidth = <16>;
+			qcom,ws = <10000>;
+			qcom,mas-hw-id = <56>;
+			qcom,slv-hw-id = <79>;
+		};
+
+	};
+};
+
+
diff --git a/arch/arm/boot/dts/msm8226-cdp.dts b/arch/arm/boot/dts/msm8226-cdp.dts
new file mode 100644
index 0000000..1c431e8
--- /dev/null
+++ b/arch/arm/boot/dts/msm8226-cdp.dts
@@ -0,0 +1,24 @@
+/* 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/ "msm8226.dtsi"
+
+/ {
+	model = "Qualcomm MSM 8226 CDP";
+	compatible = "qcom,msm8226-cdp", "qcom,msm8226";
+	qcom,msm-id = <145 1 0>;
+
+	serial@f991f000 {
+		status = "ok";
+	};
+};
diff --git a/arch/arm/boot/dts/msm8226-fluid.dts b/arch/arm/boot/dts/msm8226-fluid.dts
new file mode 100644
index 0000000..af86922
--- /dev/null
+++ b/arch/arm/boot/dts/msm8226-fluid.dts
@@ -0,0 +1,24 @@
+/* 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/ "msm8226.dtsi"
+
+/ {
+	model = "Qualcomm MSM 8226 FLUID";
+	compatible = "qcom,msm8226-fluid", "qcom,msm8226";
+	qcom,msm-id = <145 3 0>;
+
+	serial@f991f000 {
+		status = "disabled";
+	};
+};
\ No newline at end of file
diff --git a/arch/arm/boot/dts/msm8226-gpu.dtsi b/arch/arm/boot/dts/msm8226-gpu.dtsi
new file mode 100644
index 0000000..2734726
--- /dev/null
+++ b/arch/arm/boot/dts/msm8226-gpu.dtsi
@@ -0,0 +1,69 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/include/ "msm8974-gpu.dtsi"
+
+&msm_gpu {
+	qcom,chipid = <0x03000510>;
+
+	qcom,clk-map = <0x00000016>; /* KGSL_CLK_CORE | KGSL_CLK_IFACE | KGSL_CLK_MEM_IFACE */
+
+	/* Bus Scale Settings */
+	qcom,msm-bus,name = "grp3d";
+	qcom,msm-bus,num-cases = <4>;
+	qcom,msm-bus,active-only = <0>;
+	qcom,msm-bus,num-paths = <2>;
+	qcom,msm-bus,vectors-KBps =
+			<26 512 0 0>, <89 604 0 0>,
+			<26 512 0 1600000>, <89 604 0 6400000>,
+			<26 512 0 3200000>, <89 604 0 12800000>,
+			<26 512 0 4264000>, <89 604 0 12800000>;
+
+	/* GDSC oxili regulators */
+	vddcx-supply = "\0";
+	vdd-supply = <&gdsc_oxili_cx>;
+
+	qcom,gpu-pwrlevels {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		compatible = "qcom,gpu-pwrlevels";
+
+		qcom,gpu-pwrlevel@0 {
+			reg = <0>;
+			qcom,gpu-freq = <450000000>;
+			qcom,bus-freq = <3>;
+			qcom,io-fraction = <0>;
+		};
+
+		qcom,gpu-pwrlevel@1 {
+			reg = <1>;
+			qcom,gpu-freq = <320000000>;
+			qcom,bus-freq = <2>;
+			qcom,io-fraction = <33>;
+		};
+
+		qcom,gpu-pwrlevel@2 {
+			reg = <2>;
+			qcom,gpu-freq = <200000000>;
+			qcom,bus-freq = <1>;
+			qcom,io-fraction = <100>;
+		};
+
+		qcom,gpu-pwrlevel@3 {
+			reg = <3>;
+			qcom,gpu-freq = <19000000>;
+			qcom,bus-freq = <0>;
+			qcom,io-fraction = <0>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/msm8226-iommu.dtsi b/arch/arm/boot/dts/msm8226-iommu.dtsi
new file mode 100644
index 0000000..51c2f38
--- /dev/null
+++ b/arch/arm/boot/dts/msm8226-iommu.dtsi
@@ -0,0 +1,229 @@
+/* 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/ "msm-iommu-v1.dtsi"
+
+&jpeg_iommu {
+	status = "ok";
+
+	qcom,iommu-bfb-regs =  <0x604c
+				0x6050
+				0x6514
+				0x6540
+				0x656c
+				0x6314
+				0x6394
+				0x6414
+				0x60ac
+				0x615c
+				0x620c
+				0x6008
+				0x600c
+				0x6010
+				0x6014>;
+
+	qcom,iommu-bfb-data =  <0x0000ffff
+				0x00000000
+				0x4
+				0x4
+				0x0
+				0x0
+				0x10
+				0x50
+				0x0
+				0x10
+				0x20
+				0x0
+				0x0
+				0x0
+				0x0>;
+};
+
+&mdp_iommu {
+	status = "ok";
+	/* HACK: set to -1 during pre-si due to lack of TZ */
+	qcom,iommu-secure-id = <0xFFFFFFFF>;
+
+	qcom,iommu-bfb-regs =  <0x604c
+				0x6050
+				0x6514
+				0x6540
+				0x656c
+				0x60ac
+				0x615c
+				0x620c
+				0x6314
+				0x6394
+				0x6414
+				0x6008
+				0x600c
+				0x6010
+				0x6014
+				0x6018
+				0x601c
+				0x6020>;
+
+	qcom,iommu-bfb-data =  <0xffffffff
+				0x00000000
+				0x00000004
+				0x00000010
+				0x00000000
+				0x00000000
+				0x00000013
+				0x00000017
+				0x0
+				0x13
+				0x23
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0>;
+};
+
+&venus_iommu {
+	status = "ok";
+	/* HACK: set to -1 during pre-si due to lack of TZ */
+	qcom,iommu-secure-id = <0xFFFFFFFF>;
+
+	qcom,iommu-bfb-regs =  <0x604c
+				0x6050
+				0x6514
+				0x6540
+				0x656c
+				0x60ac
+				0x615c
+				0x620c
+				0x6314
+				0x6394
+				0x6414
+				0x6008
+				0x600c
+				0x6010
+				0x6014
+				0x6018
+				0x601c
+				0x6020
+				0x6024
+				0x6028
+				0x602c
+				0x6030
+				0x6034
+				0x6038>;
+
+	qcom,iommu-bfb-data =  <0xffffffff
+				0xffffffff
+				0x00000004
+				0x00000008
+				0x00000000
+				0x00000000
+				0x00000094
+				0x000000b4
+				0x0
+				0x94
+				0x114
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0>;
+};
+
+&venus_ns {
+	   qcom,iommu-ctx-sids = <0 1 2 3 4 5 7>;
+};
+
+&venus_cp {
+	   qcom,iommu-ctx-sids = <0x80 0x81 0x82 0x83 0x84>;
+};
+
+&kgsl_iommu {
+	status = "ok";
+
+	qcom,iommu-bfb-regs =  <0x604c
+				0x6050
+				0x6514
+				0x6540
+				0x656c
+				0x60ac
+				0x615c
+				0x620c
+				0x6314
+				0x6394
+				0x6414
+				0x6008>;
+
+	qcom,iommu-bfb-data =  <0x00000003
+				0x0
+				0x00000004
+				0x00000010
+				0x00000000
+				0x00000000
+				0x00000001
+				0x00000011
+				0x0
+				0x1
+				0x41
+				0x0>;
+};
+
+&vfe_iommu {
+	status = "ok";
+
+	qcom,iommu-bfb-regs =  <0x604c
+				0x6050
+				0x6514
+				0x6540
+				0x656c
+				0x6314
+				0x6394
+				0x6414
+				0x60ac
+				0x615c
+				0x620c
+				0x6008
+				0x600c
+				0x6010
+				0x6014
+				0x6018
+				0x601c
+				0x6020>;
+
+	qcom,iommu-bfb-data =  <0xffffffff
+				0x00000000
+				0x4
+				0x8
+				0x0
+				0x0
+				0x1b
+				0x5b
+				0x0
+				0x1b
+				0x2b
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0>;
+};
diff --git a/arch/arm/boot/dts/msm8226-mtp.dts b/arch/arm/boot/dts/msm8226-mtp.dts
new file mode 100644
index 0000000..ef0fdc0
--- /dev/null
+++ b/arch/arm/boot/dts/msm8226-mtp.dts
@@ -0,0 +1,24 @@
+/* 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/ "msm8226.dtsi"
+
+/ {
+	model = "Qualcomm MSM 8226 MTP";
+	compatible = "qcom,msm8226-mtp", "qcom,msm8226";
+	qcom,msm-id = <145 8 0>;
+
+	serial@f991f000 {
+		status = "ok";
+	};
+};
diff --git a/arch/arm/boot/dts/msm8226-pm.dtsi b/arch/arm/boot/dts/msm8226-pm.dtsi
new file mode 100644
index 0000000..4937efe
--- /dev/null
+++ b/arch/arm/boot/dts/msm8226-pm.dtsi
@@ -0,0 +1,398 @@
+/* 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/ "skeleton.dtsi"
+
+/ {
+	qcom,spm@f9089000 {
+		compatible = "qcom,spm-v2";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0xf9089000 0x1000>;
+		qcom,core-id = <0>;
+		qcom,saw2-ver-reg = <0xfd0>;
+		qcom,saw2-cfg = <0x01>;
+		qcom,saw2-spm-dly= <0x3c102800>;
+		qcom,saw2-spm-ctl = <0x1>;
+		qcom,saw2-spm-cmd-wfi = [60 03 60 0b 0f];
+		qcom,saw2-spm-cmd-spc = [00 20 10 80 30 90 5b 60 03 60 3b 76 76
+				0b 94 5b 80 10 2b 06 26 30 0f];
+		qcom,saw2-spm-cmd-pc = [00 20 10 80 30 90 5b 60 07 60 3b 76 76
+				0b 94 5b 80 10 2b 06 26 30 0f];
+	};
+
+	qcom,spm@f9099000 {
+		compatible = "qcom,spm-v2";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0xf9099000 0x1000>;
+		qcom,core-id = <1>;
+		qcom,saw2-ver-reg = <0xfd0>;
+		qcom,saw2-cfg = <0x01>;
+		qcom,saw2-spm-dly= <0x3c102800>;
+		qcom,saw2-spm-ctl = <0x1>;
+		qcom,saw2-spm-cmd-wfi = [60 03 60 0b 0f];
+		qcom,saw2-spm-cmd-spc = [00 20 10 80 30 90 5b 60 03 60 3b 76 76
+				0b 94 5b 80 10 2b 06 26 30 0f];
+		qcom,saw2-spm-cmd-pc = [00 20 10 80 30 90 5b 60 07 60 3b 76 76
+				0b 94 5b 80 10 2b 06 26 30 0f];
+	};
+
+	qcom,spm@f90a9000 {
+		compatible = "qcom,spm-v2";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0xf90a9000 0x1000>;
+		qcom,core-id = <2>;
+		qcom,saw2-ver-reg = <0xfd0>;
+		qcom,saw2-cfg = <0x01>;
+		qcom,saw2-spm-dly= <0x3c102800>;
+		qcom,saw2-spm-ctl = <0x1>;
+		qcom,saw2-spm-cmd-wfi = [60 03 60 76 76 0b 0f];
+		qcom,saw2-spm-cmd-spc = [00 20 10 80 30 90 5b 60 03 60 3b 76 76
+				0b 94 5b 80 10 2b 06 26 30 0f];
+		qcom,saw2-spm-cmd-pc = [00 20 10 80 30 90 5b 60 07 60 3b 76 76
+				0b 94 5b 80 10 2b 06 26 30 0f];
+	};
+
+	qcom,spm@f90b9000 {
+		compatible = "qcom,spm-v2";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0xf90b9000 0x1000>;
+		qcom,core-id = <3>;
+		qcom,saw2-ver-reg = <0xfd0>;
+		qcom,saw2-cfg = <0x01>;
+		qcom,saw2-spm-dly= <0x3c102800>;
+		qcom,saw2-spm-ctl = <0x1>;
+		qcom,saw2-spm-cmd-wfi = [60 03 60 76 76 0b 0f];
+		qcom,saw2-spm-cmd-spc = [00 20 10 80 30 90 5b 60 03 60 3b 76 76
+				0b 94 5b 80 10 2b 06 26 30 0f];
+		qcom,saw2-spm-cmd-pc = [00 20 10 80 30 90 5b 60 07 60 3b 76 76
+				0b 94 5b 80 10 2b 06 26 30 0f];
+	};
+
+	qcom,spm@f9012000 {
+		compatible = "qcom,spm-v2";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0xf9012000 0x1000>;
+		qcom,core-id = <0xffff>; /* L2/APCS SAW */
+		qcom,saw2-ver-reg = <0xfd0>;
+		qcom,saw2-cfg = <0x14>;
+		qcom,saw2-spm-dly= <0x3c102800>;
+		qcom,saw2-spm-ctl = <0x1>;
+		qcom,saw2-pmic-data0 = <0x0400009c>;
+		qcom,saw2-pmic-data1 = <0x0000001c>;
+		qcom,vctl-timeout-us = <50>;
+		qcom,vctl-port = <0x0>;
+		qcom,phase-port = <0x1>;
+		qcom,pfm-port = <0x2>;
+		qcom,saw2-spm-cmd-ret = [00 03 00 7b 0f];
+		qcom,saw2-spm-cmd-gdhs = [00 20 32 60 70 80 6b c0 e0 d0 42 07
+				78 1f 80 4e d0 e0 c0 22 6b 50 4b 60 02 32 50 7b
+				0f];
+		qcom,saw2-spm-cmd-pc = [00 32 60 70 80 b0 10 e0 d0 6b c0
+				42 f0 11 07 01 b0 78 1f 80 4e c0 d0 12 e0 6b 50 4b
+				60 02 32 50 f0 7b 0f]; /*APCS_PMIC_OFF_L2RAM_OFF*/
+	};
+
+	qcom,lpm-resources {
+		compatible = "qcom,lpm-resources";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		qcom,lpm-resources@0 {
+			reg = <0x0>;
+			qcom,name = "vdd-dig";
+			qcom,resource-type = <0>;
+			qcom,type = <0x62706d73>;	/* "smpb" */
+			qcom,id = <0x02>;
+			qcom,key = <0x6e726f63>;	/* "corn" */
+			qcom,init-value = <5>;		/* Super Turbo */
+		};
+
+		qcom,lpm-resources@1 {
+			reg = <0x1>;
+			qcom,name = "vdd-mem";
+			qcom,resource-type = <0>;
+			qcom,type = <0x62706d73>;	/* "smpb" */
+			qcom,id = <0x01>;
+			qcom,key = <0x7675>;		/* "uv" */
+			qcom,init-value = <1050000>;	/* Super Turbo */
+		};
+
+		qcom,lpm-resources@2 {
+			reg = <0x2>;
+			qcom,name = "pxo";
+			qcom,resource-type = <0>;
+			qcom,type = <0x306b6c63>;	/* "clk0" */
+			qcom,id = <0x00>;
+			qcom,key = <0x62616e45>;	/* "Enab" */
+			qcom,init-value = <1>;		/* On */
+		};
+
+		qcom,lpm-resources@3 {
+			reg = <0x3>;
+			qcom,name = "l2";
+			qcom,resource-type = <1>;
+			qcom,init-value = <2>;		/* Retention */
+		};
+	};
+
+	qcom,lpm-levels {
+		compatible = "qcom,lpm-levels";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		qcom,lpm-level@0 {
+			reg = <0x0>;
+			qcom,mode = <0>;        /* MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT */
+			qcom,xo = <1>;          /* ON */
+			qcom,l2 = <3>;          /* ACTIVE */
+			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
+			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
+			qcom,vdd-dig-upper-bound = <5>; /* MAX */
+			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,latency-us = <1>;
+			qcom,ss-power = <784>;
+			qcom,energy-overhead = <190000>;
+			qcom,time-overhead = <100>;
+		};
+
+		qcom,lpm-level@1 {
+			reg = <0x1>;
+			qcom,mode = <4>;        /* MSM_PM_SLEEP_MODE_RETENTION*/
+			qcom,xo = <1>;          /* ON */
+			qcom,l2 = <3>;          /* ACTIVE */
+			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
+			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
+			qcom,vdd-dig-upper-bound = <5>; /* MAX */
+			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,latency-us = <75>;
+			qcom,ss-power = <735>;
+			qcom,energy-overhead = <77341>;
+			qcom,time-overhead = <105>;
+		};
+
+
+		qcom,lpm-level@2 {
+			reg = <0x2>;
+			qcom,mode = <2>;        /* MSM_PM_SLEEP_MODE_STANDALONE_POWER_COLLAPSE */
+			qcom,xo = <1>;          /* ON */
+			qcom,l2 = <3>;          /* ACTIVE */
+			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
+			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
+			qcom,vdd-dig-upper-bound = <5>; /* MAX */
+			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,latency-us = <95>;
+			qcom,ss-power = <725>;
+			qcom,energy-overhead = <99500>;
+			qcom,time-overhead = <130>;
+		};
+
+		qcom,lpm-level@3 {
+			reg = <0x3>;
+			qcom,mode = <3>;        /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
+			qcom,xo = <1>;          /* ON */
+			qcom,l2 = <1>;          /* GDHS */
+			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
+			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
+			qcom,vdd-dig-upper-bound = <5>; /* MAX */
+			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,latency-us = <2000>;
+			qcom,ss-power = <138>;
+			qcom,energy-overhead = <1208400>;
+			qcom,time-overhead = <3200>;
+		};
+
+		qcom,lpm-level@4 {
+			reg = <0x4>;
+			qcom,mode = <3>;        /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
+			qcom,xo = <1>;          /* ON */
+			qcom,l2 = <0>;          /* OFF */
+			qcom,vdd-mem-upper-bound = <1050000>; /* ACTIVE */
+			qcom,vdd-mem-lower-bound = <750000>;  /* RETENTION HIGH */
+			qcom,vdd-dig-upper-bound = <3>;  /* ACTIVE */
+			qcom,vdd-dig-lower-bound = <2>;  /* RETENTION HIGH */
+			qcom,latency-us = <3000>;
+			qcom,ss-power = <110>;
+			qcom,energy-overhead = <1250300>;
+			qcom,time-overhead = <3500>;
+		};
+
+		qcom,lpm-level@5 {
+			reg = <0x5>;
+			qcom,mode = <3>;        /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
+			qcom,xo = <0>;          /* OFF */
+			qcom,l2 = <1>;          /* GDHS */
+			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
+			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
+			qcom,vdd-dig-upper-bound = <5>; /* MAX */
+			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,latency-us = <3000>;
+			qcom,ss-power = <68>;
+			qcom,energy-overhead = <1350200>;
+			qcom,time-overhead = <4000>;
+		};
+
+		qcom,lpm-level@6 {
+			reg = <0x6>;
+			qcom,mode = <3>;        /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
+			qcom,xo = <0>;          /* OFF */
+			qcom,l2 = <0>;          /* OFF */
+			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
+			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
+			qcom,vdd-dig-upper-bound = <5>; /* MAX */
+			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,latency-us = <10300>;
+			qcom,ss-power = <63>;
+			qcom,energy-overhead = <2128000>;
+			qcom,time-overhead = <18200>;
+		};
+
+		qcom,lpm-level@7 {
+			reg = <0x7>;
+			qcom,mode= <3>;         /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
+			qcom,xo = <0>;          /* OFF */
+			qcom,l2 = <0>;          /* OFF */
+			qcom,vdd-mem-upper-bound = <1050000>; /* ACTIVE */
+			qcom,vdd-mem-lower-bound = <750000>;  /* RETENTION HIGH */
+			qcom,vdd-dig-upper-bound = <3>;  /* ACTIVE */
+			qcom,vdd-dig-lower-bound = <2>;  /* RETIONTION HIGH */
+			qcom,latency-us = <18000>;
+			qcom,ss-power = <10>;
+			qcom,energy-overhead = <3202600>;
+			qcom,time-overhead = <27000>;
+		};
+
+		qcom,lpm-level@8 {
+			reg = <0x8>;
+			qcom,mode= <3>;         /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
+			qcom,xo = <0>;          /* OFF */
+			qcom,l2 = <0>;          /* OFF */
+			qcom,vdd-mem-upper-bound = <750000>; /* RETENTION HIGH */
+			qcom,vdd-mem-lower-bound = <750000>; /* RETENTION LOW */
+			qcom,vdd-dig-upper-bound = <2>; /* RETENTION HIGH */
+			qcom,vdd-dig-lower-bound = <0>; /* RETENTION LOW */
+			qcom,latency-us = <20000>;
+			qcom,ss-power = <2>;
+			qcom,energy-overhead = <4252000>;
+			qcom,time-overhead = <32000>;
+		};
+	};
+
+	qcom,pm-boot {
+		compatible = "qcom,pm-boot";
+		qcom,mode = <0>; /* MSM_PM_BOOT_CONFIG_TZ */
+	};
+
+	qcom,mpm@fc4281d0 {
+		compatible = "qcom,mpm-v2";
+		reg = <0xfc4281d0 0x1000>, /* MSM_RPM_MPM_BASE 4K */
+		    <0xf9011008 0x4>;   /* MSM_APCS_GCC_BASE 4K */
+		reg-names = "vmpm", "ipc";
+		interrupts = <0 171 1>;
+
+		qcom,ipc-bit-offset = <1>;
+
+		qcom,gic-parent = <&intc>;
+		qcom,gic-map = <47 172>, /* usb2_hsic_async_wakeup_irq */
+			<53 104>, /* mdss_irq */
+			<62 222>, /* ee0_krait_hlos_spmi_periph_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 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 188>, /* lpass_irq_out_apcs(0) */
+			<0xff 189>, /* lpass_irq_out_apcs(1) */
+			<0xff 190>, /* lpass_irq_out_apcs(2) */
+			<0xff 191>, /* lpass_irq_out_apcs(3) */
+			<0xff 192>, /* lpass_irq_out_apcs(4) */
+			<0xff 193>, /* lpass_irq_out_apcs(5) */
+			<0xff 194>, /* lpass_irq_out_apcs(6) */
+			<0xff 195>, /* lpass_irq_out_apcs(7) */
+			<0xff 196>, /* lpass_irq_out_apcs(8) */
+			<0xff 197>, /* lpass_irq_out_apcs(9) */
+			<0xff 200>, /* rpm_ipc(4) */
+			<0xff 201>, /* rpm_ipc(5) */
+			<0xff 202>, /* rpm_ipc(6) */
+			<0xff 203>, /* rpm_ipc(7) */
+			<0xff 204>, /* rpm_ipc(24) */
+			<0xff 205>, /* rpm_ipc(25) */
+			<0xff 206>, /* rpm_ipc(26) */
+			<0xff 207>, /* rpm_ipc(27) */
+			<0xff 240>; /* summary_irq_kpss */
+
+		qcom,gpio-parent = <&msmgpio>;
+		qcom,gpio-map = <3  102>,
+			<4  1 >,
+			<5  5 >,
+			<6  9 >,
+			<7  18>,
+			<8  20>,
+			<9  24>,
+			<10  27>,
+			<11  28>,
+			<12  34>,
+			<13  35>,
+			<14  37>,
+			<15  42>,
+			<16  44>,
+			<17  46>,
+			<18  50>,
+			<19  54>,
+			<20  59>,
+			<21  61>,
+			<22  62>,
+			<23  64>,
+			<24  65>,
+			<25  66>,
+			<26  67>,
+			<27  68>,
+			<28  71>,
+			<29  72>,
+			<30  73>,
+			<31  74>,
+			<32  75>,
+			<33  77>,
+			<34  79>,
+			<35  80>,
+			<36  82>,
+			<37  86>,
+			<38  92>,
+			<39  93>,
+			<40  95>;
+	};
+
+	qcom,pm-8x60@fe805664 {
+		compatible = "qcom,pm-8x60";
+		reg = <0xfe805664 0x40>;
+		qcom,pc-mode = <0>; /*MSM_PC_TZ_L2_INT */
+		qcom,use-sync-timer;
+	};
+
+	qcom,rpm-stats@0xfc19dbd0{
+		compatible = "qcom,rpm-stats";
+		reg = <0xfc19dbd0 0x1000>;
+		reg-names = "phys_addr_base";
+		qcom,sleep-stats-version = <2>;
+	};
+};
diff --git a/arch/arm/boot/dts/msm8226-qrd.dts b/arch/arm/boot/dts/msm8226-qrd.dts
new file mode 100644
index 0000000..7909435
--- /dev/null
+++ b/arch/arm/boot/dts/msm8226-qrd.dts
@@ -0,0 +1,24 @@
+/* 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/ "msm8226.dtsi"
+
+/ {
+	model = "Qualcomm MSM 8226 QRD";
+	compatible = "qcom,msm8226-qrd", "qcom,msm8226";
+	qcom,msm-id = <145 11 0>;
+
+	serial@f991f000 {
+		status = "ok";
+	};
+};
diff --git a/arch/arm/boot/dts/msm8226-regulator.dtsi b/arch/arm/boot/dts/msm8226-regulator.dtsi
index 8fe94a5..8168826 100644
--- a/arch/arm/boot/dts/msm8226-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8226-regulator.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -10,265 +10,300 @@
  * GNU General Public License for more details.
  */
 
- /* Stub Regulators */
+/* Stub Regulators */
 
- / {
-	pm8026_s1: regulator-s1 {
+/ {
+	pm8226_s1_corner: regulator-s1-corner {
 		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_s1";
+		regulator-name = "8226_s1_corner";
 		qcom,hpm-min-load = <100000>;
-		regulator-min-microvolt = <1150000>;
-		regulator-max-microvolt = <1150000>;
+		regulator-min-microvolt = <1>;
+		regulator-max-microvolt = <7>;
+		qcom,consumer-supplies = "vdd_dig", "";
 	};
+};
 
-	pm8026_s2: regulator-s2 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_s2";
-		qcom,hpm-min-load = <100000>;
-		regulator-min-microvolt = <1050000>;
-		regulator-max-microvolt = <1050000>;
-	};
+/* QPNP controlled regulators: */
 
-	pm8026_s3: regulator-s3 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_s3";
-		qcom,hpm-min-load = <100000>;
-		regulator-min-microvolt = <1300000>;
-		regulator-max-microvolt = <1300000>;
-	};
+&spmi_bus {
 
-	pm8026_s4: regulator-s4 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_s4";
-		qcom,hpm-min-load = <100000>;
-		regulator-min-microvolt = <2100000>;
-		regulator-max-microvolt = <2100000>;
-	};
+	qcom,pm8226@1 {
 
-	pm8026_s5: regulator-s5 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_s5";
-		qcom,hpm-min-load = <100000>;
-		regulator-min-microvolt = <1150000>;
-		regulator-max-microvolt = <1150000>;
-	};
+		pm8226_s1: regulator@1400 {
+			status = "okay";
+			regulator-name = "8226_s1";
+			qcom,enable-time = <500>;
+			qcom,system-load = <100000>;
+			regulator-always-on;
+			regulator-min-microvolt = <1150000>;
+			regulator-max-microvolt = <1150000>;
+		};
 
-	pm8026_l1: regulator-l1 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_l1";
-		parent-supply = <&pm8026_s3>;
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <1225000>;
-		regulator-max-microvolt = <1225000>;
-	};
+		pm8226_s2: regulator@1700 {
+			status = "okay";
+			regulator-name = "8226_s2";
+			qcom,enable-time = <500>;
+			qcom,system-load = <100000>;
+			regulator-always-on;
+			regulator-min-microvolt = <1050000>;
+			regulator-max-microvolt = <1150000>;
+		};
 
-	pm8026_l2: regulator-l2 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_l2";
-		parent-supply = <&pm8026_s3>;
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <1200000>;
-		regulator-max-microvolt = <1200000>;
-	};
+		pm8226_s3: regulator@1a00 {
+			status = "okay";
+			regulator-name = "8226_s3";
+			qcom,enable-time = <500>;
+			qcom,system-load = <100000>;
+			regulator-always-on;
+			regulator-min-microvolt = <1300000>;
+			regulator-max-microvolt = <1300000>;
+		};
 
-	pm8026_l3: regulator-l3 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_l3";
-		parent-supply = <&pm8026_s3>;
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <1150000>;
-		regulator-max-microvolt = <1150000>;
-	};
+		pm8226_s4: regulator@1d00 {
+			status = "okay";
+			regulator-name = "8226_s4";
+			qcom,enable-time = <500>;
+			qcom,system-load = <100000>;
+			regulator-always-on;
+			regulator-min-microvolt = <2100000>;
+			regulator-max-microvolt = <2100000>;
+		};
 
-	pm8026_l4: regulator-l4 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_l4";
-		parent-supply = <&pm8026_s3>;
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <1200000>;
-		regulator-max-microvolt = <1200000>;
-	};
+		pm8226_s5: regulator@2000 {
+			status = "okay";
+			regulator-name = "8226_s5";
+			qcom,enable-time = <500>;
+			regulator-min-microvolt = <1150000>;
+			regulator-max-microvolt = <1150000>;
+		};
 
-	pm8026_l5: regulator-l5 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_l5";
-		parent-supply = <&pm8026_s3>;
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <1200000>;
-		regulator-max-microvolt = <1200000>;
-	};
+		pm8226_l1: regulator@4000 {
+			status = "okay";
+			regulator-name = "8226_l1";
+			parent-supply = <&pm8226_s3>;
+			qcom,enable-time = <200>;
+			regulator-min-microvolt = <1225000>;
+			regulator-max-microvolt = <1225000>;
+		};
 
-	pm8026_l6: regulator-l6 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_l6";
-		parent-supply = <&pm8026_s4>;
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <1800000>;
-	};
+		pm8226_l2: regulator@4100 {
+			status = "okay";
+			regulator-name = "8226_l2";
+			parent-supply = <&pm8226_s3>;
+			regulator-always-on;
+			qcom,enable-time = <200>;
+			qcom,system-load = <10000>;
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+		};
 
-	pm8026_l7: regulator-l7 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_l7";
-		parent-supply = <&pm8026_s4>;
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <1850000>;
-		regulator-max-microvolt = <1850000>;
-	};
+		pm8226_l3: regulator@4200 {
+			status = "okay";
+			regulator-name = "8226_l3";
+			parent-supply = <&pm8226_s3>;
+			qcom,system-load = <10000>;
+			regulator-always-on;
+			qcom,enable-time = <200>;
+			regulator-min-microvolt = <1150000>;
+			regulator-max-microvolt = <1150000>;
+		};
 
-	pm8026_l8: regulator-l8 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_l8";
-		parent-supply = <&pm8026_s4>;
-		qcom,hpm-min-load = <5000>;
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <1800000>;
-	};
+		pm8226_l4: regulator@4300 {
+			status = "okay";
+			regulator-name = "8226_l4";
+			parent-supply = <&pm8226_s3>;
+			qcom,enable-time = <200>;
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+		};
 
-	pm8026_l9: regulator-l9 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_l9";
-		parent-supply = <&pm8026_s4>;
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <2050000>;
-		regulator-max-microvolt = <2050000>;
-	};
+		pm8226_l5: regulator@4400 {
+			status = "okay";
+			regulator-name = "8226_l5";
+			parent-supply = <&pm8226_s3>;
+			qcom,enable-time = <200>;
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+		};
 
-	pm8026_l10: regulator-l10 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_l10";
-		parent-supply = <&pm8026_s4>;
-		qcom,hpm-min-load = <5000>;
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <1800000>;
-	};
+		pm8226_l6: regulator@4500 {
+			status = "okay";
+			regulator-name = "8226_l6";
+			parent-supply = <&pm8226_s4>;
+			qcom,system-load = <10000>;
+			regulator-always-on;
+			qcom,enable-time = <200>;
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+		};
 
-	pm8026_l12: regulator-l12 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_l12";
-		qcom,hpm-min-load = <5000>;
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <1800000>;
-	};
+		pm8226_l7: regulator@4600 {
+			status = "okay";
+			regulator-name = "8226_l7";
+			parent-supply = <&pm8226_s4>;
+			qcom,enable-time = <200>;
+			regulator-min-microvolt = <1850000>;
+			regulator-max-microvolt = <1850000>;
+		};
 
-	pm8026_l14: regulator-l14 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_l14";
-		qcom,hpm-min-load = <5000>;
-		regulator-min-microvolt = <2750000>;
-		regulator-max-microvolt = <2750000>;
-	};
+		pm8226_l8: regulator@4700 {
+			status = "okay";
+			regulator-name = "8226_l8";
+			parent-supply = <&pm8226_s4>;
+			qcom,enable-time = <200>;
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			qcom,consumer-supplies = "vdd_sr2_pll", "";
+		};
 
-	pm8026_l15: regulator-l15 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_l15";
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <2800000>;
-		regulator-max-microvolt = <2800000>;
-	};
+		pm8226_l9: regulator@4800 {
+			status = "okay";
+			regulator-name = "8226_l9";
+			parent-supply = <&pm8226_s4>;
+			qcom,enable-time = <200>;
+			regulator-min-microvolt = <2050000>;
+			regulator-max-microvolt = <2050000>;
+		};
 
-	pm8026_l16: regulator-l16 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_l16";
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <3000000>;
-		regulator-max-microvolt = <3000000>;
-	};
+		pm8226_l10: regulator@4900 {
+			status = "okay";
+			regulator-name = "8226_l10";
+			parent-supply = <&pm8226_s4>;
+			qcom,enable-time = <200>;
+			qcom,system-load = <5000>;
+			regulator-always-on;
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+		};
 
-	pm8026_l17: regulator-l17 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_l17";
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <2950000>;
-		regulator-max-microvolt = <2950000>;
-	};
+		pm8226_l12: regulator@4b00 {
+			status = "okay";
+			regulator-name = "8226_l12";
+			qcom,enable-time = <200>;
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+		};
 
-	pm8026_l18: regulator-l18 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_l18";
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <2950000>;
-		regulator-max-microvolt = <2950000>;
-	};
+		pm8226_l14: regulator@4d00 {
+			status = "okay";
+			regulator-name = "8226_l14";
+			qcom,enable-time = <200>;
+			regulator-min-microvolt = <2750000>;
+			regulator-max-microvolt = <2750000>;
+		};
 
-	pm8026_l19: regulator-l19 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_l19";
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <2850000>;
-		regulator-max-microvolt = <2850000>;
-	};
+		pm8226_l15: regulator@4e00 {
+			status = "okay";
+			regulator-name = "8226_l15";
+			qcom,enable-time = <200>;
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2800000>;
+		};
 
-	pm8026_l20: regulator-l20 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_l20";
-		qcom,hpm-min-load = <5000>;
-		regulator-min-microvolt = <3075000>;
-		regulator-max-microvolt = <3075000>;
-	};
+		pm8226_l16: regulator@4f00 {
+			status = "okay";
+			regulator-name = "8226_l16";
+			qcom,enable-time = <200>;
+			regulator-min-microvolt = <3000000>;
+			regulator-max-microvolt = <3300000>;
+		};
 
-	pm8026_l21: regulator-l21 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_l21";
-		qcom,hpm-min-load = <5000>;
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <2950000>;
-	};
+		pm8226_l17: regulator@5000 {
+			status = "okay";
+			regulator-name = "8226_l17";
+			qcom,enable-time = <200>;
+			regulator-min-microvolt = <2950000>;
+			regulator-max-microvolt = <2950000>;
+		};
 
-	pm8026_l22: regulator-l22 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_l22";
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <2950000>;
-	};
+		pm8226_l18: regulator@5100 {
+			status = "okay";
+			regulator-name = "8226_l18";
+			qcom,enable-time = <200>;
+			regulator-min-microvolt = <2950000>;
+			regulator-max-microvolt = <2950000>;
+		};
 
-	pm8026_l23: regulator-l23 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_l23";
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <2950000>;
-	};
+		pm8226_l19: regulator@5200 {
+			status = "okay";
+			regulator-name = "8226_l19";
+			qcom,enable-time = <200>;
+			regulator-min-microvolt = <2850000>;
+			regulator-max-microvolt = <2850000>;
+		};
 
-	pm8026_l24: regulator-l24 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_l24";
-		parent-supply = <&pm8026_s3>;
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <1300000>;
-		regulator-max-microvolt = <1300000>;
-	};
+		pm8226_l20: regulator@5300 {
+			status = "okay";
+			regulator-name = "8226_l20";
+			qcom,enable-time = <200>;
+			regulator-min-microvolt = <3075000>;
+			regulator-max-microvolt = <3075000>;
+		};
 
-	pm8026_l26: regulator-l26 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_l26";
-		parent-supply = <&pm8026_s3>;
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <1225000>;
-		regulator-max-microvolt = <1225000>;
-	};
+		pm8226_l21: regulator@5400 {
+			status = "okay";
+			regulator-name = "8226_l21";
+			qcom,enable-time = <200>;
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <2950000>;
+		};
 
-	pm8026_l27: regulator-l27 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_l27";
-		parent-supply = <&pm8026_s4>;
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <2050000>;
-		regulator-max-microvolt = <2050000>;
-	};
+		pm8226_l22: regulator@5500 {
+			status = "okay";
+			regulator-name = "8226_l22";
+			qcom,enable-time = <200>;
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <2950000>;
+		};
 
-	pm8026_l28: regulator-l28 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_l28";
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <2950000>;
-	};
+		pm8226_l23: regulator@5600 {
+			status = "okay";
+			regulator-name = "8226_l23";
+			qcom,enable-time = <200>;
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <2950000>;
+		};
 
-	 pm8026_lvs1: regulator-lvs1 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8026_lvs1";
-		parent-supply = <&pm8026_l6>;
+		pm8226_l24: regulator@5700 {
+			status = "okay";
+			regulator-name = "8226_l24";
+			parent-supply = <&pm8226_s3>;
+			qcom,enable-time = <200>;
+			regulator-min-microvolt = <1300000>;
+			regulator-max-microvolt = <1300000>;
+		};
+
+		pm8226_l26: regulator@5900 {
+			status = "okay";
+			regulator-name = "8226_l26";
+			parent-supply = <&pm8226_s3>;
+			qcom,enable-time = <200>;
+			regulator-min-microvolt = <1225000>;
+			regulator-max-microvolt = <1225000>;
+		};
+
+		pm8226_l27: regulator@5a00 {
+			status = "okay";
+			regulator-name = "8226_l27";
+			parent-supply = <&pm8226_s4>;
+			qcom,enable-time = <200>;
+			regulator-min-microvolt = <2050000>;
+			regulator-max-microvolt = <2050000>;
+		};
+
+		pm8226_l28: regulator@5b00 {
+			status = "okay";
+			regulator-name = "8226_l28";
+			qcom,enable-time = <200>;
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <2950000>;
+		};
+
+		pm8226_lvs1: regulator@8000 {
+			status = "okay";
+			regulator-name = "8226_lvs1";
+			parent-supply = <&pm8226_l6>;
+			qcom,enable-time = <200>;
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/msm8226-sim.dts b/arch/arm/boot/dts/msm8226-sim.dts
index 9a0ec17..b6590b3 100644
--- a/arch/arm/boot/dts/msm8226-sim.dts
+++ b/arch/arm/boot/dts/msm8226-sim.dts
@@ -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
@@ -17,7 +17,7 @@
 / {
 	model = "Qualcomm MSM 8226 Simulator";
 	compatible = "qcom,msm8226-sim", "qcom,msm8226";
-	qcom,msm-id = <145 1 0>;
+	qcom,msm-id = <145 16 0>;
 
 	serial@f991f000 {
 		status = "ok";
@@ -39,8 +39,8 @@
 	qcom,pad-drv-on = <0x7 0x4 0x4>; /* 16mA, 10mA, 10mA */
 	qcom,pad-drv-off = <0x0 0x0 0x0>; /* 2mA, 2mA, 2mA */
 
-	vdd-supply = <&pm8026_l17>;
-	vdd-io-supply = <&pm8026_l6>;
+	vdd-supply = <&pm8226_l17>;
+	vdd-io-supply = <&pm8226_l6>;
 	qcom,clk-rates = <400000 25000000 50000000 100000000 200000000>;
 	qcom,sup-voltages = <2950 2950>;
 
@@ -50,8 +50,8 @@
 };
 
 &sdcc2 {
-	vdd-supply = <&pm8026_l18>;
-	vdd-io-supply = <&pm8026_l21>;
+	vdd-supply = <&pm8226_l18>;
+	vdd-io-supply = <&pm8226_l21>;
 	qcom,vdd-voltage-level = <2950000 2950000>;
 	qcom,vdd-current-level = <9000 800000>;
 
@@ -74,3 +74,57 @@
 
 	status = "ok";
 };
+
+&pm8226_gpios {
+	gpio@c000 { /* GPIO 1 */
+	};
+
+	gpio@c100 { /* GPIO 2 */
+	};
+
+	gpio@c200 { /* GPIO 3 */
+	};
+
+	gpio@c300 { /* GPIO 4 */
+	};
+
+	gpio@c400 { /* GPIO 5 */
+	};
+
+	gpio@c500 { /* GPIO 6 */
+	};
+
+	gpio@c600 { /* GPIO 7 */
+	};
+
+	gpio@c700 { /* GPIO 8 */
+	};
+};
+
+&pm8226_mpps {
+	mpp@a000 { /* MPP 1 */
+	};
+
+	mpp@a100 { /* MPP 2 */
+	};
+
+	mpp@a200 { /* MPP 3 */
+	};
+
+	mpp@a300 { /* MPP 4 */
+	};
+
+	mpp@a400 { /* MPP 5 */
+	};
+
+	mpp@a500 { /* MPP 6 */
+	};
+
+	mpp@a600 { /* MPP 7 */
+	};
+
+	mpp@a700 { /* MPP 8 */
+	};
+};
+
+
diff --git a/arch/arm/boot/dts/msm8226-smp2p.dtsi b/arch/arm/boot/dts/msm8226-smp2p.dtsi
new file mode 100644
index 0000000..60f63a8
--- /dev/null
+++ b/arch/arm/boot/dts/msm8226-smp2p.dtsi
@@ -0,0 +1,194 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+/ {
+	qcom,smp2p-modem {
+		compatible = "qcom,smp2p";
+		reg = <0xfa006000 0x1000>, <0x8 0x0>;
+		reg-names = "irq-reg-base", "irq-reg-offset";
+		qcom,remote-pid = <1>;
+		qcom,irq-bitmask = <0x4000>;
+		interrupts = <0 27 1>;
+	};
+
+	qcom,smp2p-adsp {
+		compatible = "qcom,smp2p";
+		reg = <0xfa006000 0x1000>, <0x8 0x0>;
+		reg-names = "irq-reg-base", "irq-reg-offset";
+		qcom,remote-pid = <2>;
+		qcom,irq-bitmask = <0x400>;
+		interrupts = <0 158 1>;
+	};
+
+	qcom,smp2p-wcnss {
+		compatible = "qcom,smp2p";
+		reg = <0xfa006000 0x1000>, <0x8 0x0>;
+		reg-names = "irq-reg-base", "irq-reg-offset";
+		qcom,remote-pid = <4>;
+		qcom,irq-bitmask = <0x40000>;
+		interrupts = <0 143 1>;
+	};
+
+	/* SMP2P Test Driver for inbound entries */
+	smp2pgpio_smp2p_7_in: qcom,smp2pgpio-smp2p-7-in {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <7>;
+		qcom,is-inbound;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	qcom,smp2pgpio_test_smp2p_7_in {
+		compatible = "qcom,smp2pgpio_test_smp2p_7_in";
+		gpios = <&smp2pgpio_smp2p_7_in 0 0>;
+	};
+
+	/* SMP2P Test Driver for outbound entries */
+	smp2pgpio_smp2p_7_out: qcom,smp2pgpio-smp2p-7-out {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <7>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	qcom,smp2pgpio_test_smp2p_7_out {
+		compatible = "qcom,smp2pgpio_test_smp2p_7_out";
+		gpios = <&smp2pgpio_smp2p_7_out 0 0>;
+	};
+
+	/* SMP2P Test Driver for modem inbound */
+	smp2pgpio_smp2p_1_in: qcom,smp2pgpio-smp2p-1-in {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <1>;
+		qcom,is-inbound;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	qcom,smp2pgpio_test_smp2p_1_in {
+		compatible = "qcom,smp2pgpio_test_smp2p_1_in";
+		gpios = <&smp2pgpio_smp2p_1_in 0 0>;
+	};
+
+	/* SMP2P Test Driver for modem output */
+	smp2pgpio_smp2p_1_out: qcom,smp2pgpio-smp2p-1-out {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <1>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	qcom,smp2pgpio_test_smp2p_1_out {
+		compatible = "qcom,smp2pgpio_test_smp2p_1_out";
+		gpios = <&smp2pgpio_smp2p_1_out 0 0>;
+	};
+
+	/* SMP2P SSR Driver for inbound entry from modem. */
+	smp2pgpio_ssr_smp2p_1_in: qcom,smp2pgpio-ssr-smp2p-1-in {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "slave-kernel";
+		qcom,remote-pid = <1>;
+		qcom,is-inbound;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	/* SMP2P SSR Driver for outbound entry to modem */
+	smp2pgpio_ssr_smp2p_1_out: qcom,smp2pgpio-ssr-smp2p-1-out {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "master-kernel";
+		qcom,remote-pid = <1>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	/* SMP2P Test Driver for adsp inbound */
+	smp2pgpio_smp2p_2_in: qcom,smp2pgpio-smp2p-2-in {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <2>;
+		qcom,is-inbound;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	qcom,smp2pgpio_test_smp2p_2_in {
+		compatible = "qcom,smp2pgpio_test_smp2p_2_in";
+		gpios = <&smp2pgpio_smp2p_2_in 0 0>;
+	};
+
+	/* SMP2P Test Driver for adsp output */
+	smp2pgpio_smp2p_2_out: qcom,smp2pgpio-smp2p-2-out {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <2>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	qcom,smp2pgpio_test_smp2p_2_out {
+		compatible = "qcom,smp2pgpio_test_smp2p_2_out";
+		gpios = <&smp2pgpio_smp2p_2_out 0 0>;
+	};
+
+	/* SMP2P Test Driver for wcnss inbound */
+	smp2pgpio_smp2p_4_in: qcom,smp2pgpio-smp2p-4-in {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <4>;
+		qcom,is-inbound;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	qcom,smp2pgpio_test_smp2p_4_in {
+		compatible = "qcom,smp2pgpio_test_smp2p_4_in";
+		gpios = <&smp2pgpio_smp2p_4_in 0 0>;
+	};
+
+	/* SMP2P Test Driver for wcnss output */
+	smp2pgpio_smp2p_4_out: qcom,smp2pgpio-smp2p-4-out {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <4>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	qcom,smp2pgpio_test_smp2p_4_out {
+		compatible = "qcom,smp2pgpio_test_smp2p_4_out";
+		gpios = <&smp2pgpio_smp2p_4_out 0 0>;
+	};
+};
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index 475ed40..25d292f 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -13,6 +13,11 @@
 /include/ "skeleton.dtsi"
 /include/ "msm8226-ion.dtsi"
 /include/ "msm-gdsc.dtsi"
+/include/ "msm8226-iommu.dtsi"
+/include/ "msm8226-pm.dtsi"
+/include/ "msm8226-smp2p.dtsi"
+/include/ "msm8226-gpu.dtsi"
+/include/ "msm8226-bus.dtsi"
 
 / {
 	model = "Qualcomm MSM 8226";
@@ -34,7 +39,13 @@
 		reg = <0xfd510000 0x4000>;
 		gpio-controller;
 		#gpio-cells = <2>;
+		ngpio = <117>;
 		interrupts = <0 208 0>;
+		qcom,direct-connect-irqs = <8>;
+	};
+
+	aliases {
+		spi0 = &spi_0;
 	};
 
 	timer {
@@ -57,6 +68,11 @@
 		status = "disabled";
 	};
 
+	qcom,msm-imem@fe805000 {
+		compatible = "qcom,msm-imem";
+		reg = <0xfe805000 0x1000>; /* Address and size of IMEM */
+	};
+
 	qcom,sps@f9984000 {
 		compatible = "qcom,msm_sps";
 		reg = <0xf9984000 0x15000>,
@@ -67,11 +83,12 @@
         usb@f9a55000 {
 		compatible = "qcom,hsusb-otg";
 		reg = <0xf9a55000 0x400>;
-		interrupts = <0 134 0>;
-		interrupt-names = "core_irq";
-                HSUSB_VDDCX-supply = <&pm8026_s1>;
-                HSUSB_1p8-supply = <&pm8026_l10>;
-                HSUSB_3p3-supply = <&pm8026_l20>;
+		interrupts = <0 134 0>, <0 140 0>;
+		interrupt-names = "core_irq", "async_irq";
+		hsusb_vdd_dig-supply = <&pm8226_s1_corner>;
+		HSUSB_1p8-supply = <&pm8226_l10>;
+		HSUSB_3p3-supply = <&pm8226_l20>;
+		qcom,vdd-voltage-level = <1 5 7>;
 
 		qcom,hsusb-otg-phy-type = <2>;
 		qcom,hsusb-otg-mode = <1>;
@@ -79,8 +96,234 @@
 		qcom,hsusb-otg-disable-reset;
 	};
 
-	android_usb {
+	android_usb@fe8050c8 {
 		compatible = "qcom,android-usb";
+		reg = <0xfe8050c8 0xc8>;
+	};
+
+	wcd9xxx_intc: wcd9xxx-irq {
+		compatible = "qcom,wcd9xxx-irq";
+		interrupt-controller;
+		#interrupt-cells = <1>;
+		interrupt-parent = <&msmgpio>;
+		interrupts = <68 0>;
+		interrupt-names = "cdc-int";
+	};
+
+	slim@fe12f000 {
+		cell-index = <1>;
+		compatible = "qcom,slim-ngd";
+		reg = <0xfe12f000 0x35000>,
+			  <0xfe104000 0x20000>;
+		reg-names = "slimbus_physical", "slimbus_bam_physical";
+		interrupts = <0 163 0>, <0 164 0>;
+		interrupt-names = "slimbus_irq", "slimbus_bam_irq";
+
+		tapan_codec {
+			compatible = "qcom,tapan-slim-pgd";
+			elemental-addr = [00 01 E0 00 17 02];
+
+			interrupt-parent = <&wcd9xxx_intc>;
+			interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
+					17 18 19 20 21 22 23 24 25 26 27 28>;
+			qcom,cdc-reset-gpio = <&msmgpio 72 0>;
+
+			cdc-vdd-buck-supply = <&pm8226_s4>;
+			qcom,cdc-vdd-buck-voltage = <2100000 2100000>;
+			qcom,cdc-vdd-buck-current = <650000>;
+
+			cdc-vdd-h-supply = <&pm8226_l6>;
+			qcom,cdc-vdd-h-voltage = <1800000 1800000>;
+			qcom,cdc-vdd-h-current = <25000>;
+
+			cdc-vdd-px-supply = <&pm8226_l6>;
+			qcom,cdc-vdd-px-voltage = <1800000 1800000>;
+			qcom,cdc-vdd-px-current = <25000>;
+
+			cdc-vdd-a-1p2v-supply = <&pm8226_l4>;
+			qcom,cdc-vdd-a-1p2v-voltage = <1200000 1200000>;
+			qcom,cdc-vdd-a-1p2v-current = <10000>;
+
+			cdc-vdd-cx-supply = <&pm8226_l4>;
+			qcom,cdc-vdd-cx-voltage = <1200000 1200000>;
+			qcom,cdc-vdd-cx-current = <10000>;
+
+			qcom,cdc-micbias-ldoh-v = <0x3>;
+			qcom,cdc-micbias-cfilt1-mv = <1800>;
+			qcom,cdc-micbias-cfilt2-mv = <1800>;
+			qcom,cdc-micbias-cfilt3-mv = <1800>;
+
+			qcom,cdc-micbias1-cfilt-sel = <0x0>;
+			qcom,cdc-micbias2-cfilt-sel = <0x1>;
+			qcom,cdc-micbias3-cfilt-sel = <0x2>;
+
+			qcom,cdc-mclk-clk-rate = <9600000>;
+			qcom,cdc-slim-ifd = "tapan-slim-ifd";
+			qcom,cdc-slim-ifd-elemental-addr = [00 00 E0 00 17 02];
+		};
+	};
+
+	qcom,msm-adsp-loader {
+		compatible = "qcom,adsp-loader";
+		qcom,adsp-state = <0>;
+	};
+
+	sound {
+		compatible = "qcom,msm8226-audio-tapan";
+		qcom,model = "msm8226-tapan-snd-card";
+
+		qcom,audio-routing =
+			"RX_BIAS", "MCLK",
+			"LDO_H", "MCLK",
+			"AMIC1", "MIC BIAS1 Internal1",
+			"MIC BIAS1 Internal1", "Handset Mic",
+			"AMIC2", "MIC BIAS2 External",
+			"MIC BIAS2 External", "Headset Mic",
+			"AMIC3", "MIC BIAS2 External",
+			"MIC BIAS2 External", "ANCRight Headset Mic",
+			"AMIC4", "MIC BIAS2 External",
+			"MIC BIAS2 External", "ANCLeft Headset Mic",
+			"DMIC1", "MIC BIAS1 External",
+			"MIC BIAS1 External", "Digital Mic1",
+			"DMIC2", "MIC BIAS1 External",
+			"MIC BIAS1 External", "Digital Mic2",
+			"DMIC3", "MIC BIAS3 External",
+			"MIC BIAS3 External", "Digital Mic3",
+			"DMIC4", "MIC BIAS3 External",
+			"MIC BIAS3 External", "Digital Mic4",
+			"DMIC5", "MIC BIAS4 External",
+			"MIC BIAS4 External", "Digital Mic5",
+			"DMIC6", "MIC BIAS4 External",
+			"MIC BIAS4 External", "Digital Mic6";
+		qcom,tapan-mclk-clk-freq = <9600000>;
+	};
+
+	qcom,msm-pcm {
+		compatible = "qcom,msm-pcm-dsp";
+	};
+
+	qcom,msm-pcm-routing {
+		compatible = "qcom,msm-pcm-routing";
+	};
+
+	qcom,msm-pcm-lpa {
+		compatible = "qcom,msm-pcm-lpa";
+	};
+
+	qcom,msm-compr-dsp {
+		compatible = "qcom,msm-compr-dsp";
+	};
+
+	qcom,msm-voip-dsp {
+		compatible = "qcom,msm-voip-dsp";
+	};
+
+	qcom,msm-pcm-voice {
+		compatible = "qcom,msm-pcm-voice";
+	};
+
+	qcom,msm-stub-codec {
+		compatible = "qcom,msm-stub-codec";
+	};
+
+	qcom,msm-dai-fe {
+		compatible = "qcom,msm-dai-fe";
+	};
+
+	qcom,msm-pcm-afe {
+		compatible = "qcom,msm-pcm-afe";
+	};
+
+	qcom,msm-dai-q6-hdmi {
+		compatible = "qcom,msm-dai-q6-hdmi";
+		qcom,msm-dai-q6-dev-id = <8>;
+	};
+
+	qcom,msm-dai-q6 {
+		compatible = "qcom,msm-dai-q6";
+		qcom,msm-dai-q6-sb-0-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <16384>;
+		};
+
+		qcom,msm-dai-q6-sb-0-tx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <16385>;
+		};
+
+		qcom,msm-dai-q6-sb-1-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <16386>;
+		};
+
+		qcom,msm-dai-q6-sb-1-tx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <16387>;
+		};
+
+		qcom,msm-dai-q6-sb-3-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <16390>;
+		};
+
+		qcom,msm-dai-q6-sb-3-tx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <16391>;
+		};
+
+		qcom,msm-dai-q6-sb-4-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <16392>;
+		};
+
+		qcom,msm-dai-q6-sb-4-tx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <16393>;
+		};
+
+		qcom,msm-dai-q6-bt-sco-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <12288>;
+		};
+
+		qcom,msm-dai-q6-bt-sco-tx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <12289>;
+		};
+
+		qcom,msm-dai-q6-int-fm-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <12292>;
+		};
+
+		qcom,msm-dai-q6-int-fm-tx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <12293>;
+		};
+
+		qcom,msm-dai-q6-be-afe-pcm-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <224>;
+		};
+
+		qcom,msm-dai-q6-be-afe-pcm-tx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <225>;
+		};
+
+		qcom,msm-dai-q6-afe-proxy-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <241>;
+		};
+
+		qcom,msm-dai-q6-afe-proxy-tx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <240>;
+		};
+	};
+
+	qcom,msm-pcm-hostless {
+		compatible = "qcom,msm-pcm-hostless";
 	};
 
 	qcom,wdt@f9017000 {
@@ -89,7 +332,7 @@
 		interrupts = <0 3 0>, <0 4 0>;
 		qcom,bark-time = <11000>;
 		qcom,pet-time = <10000>;
-		qcom,ipi-ping = <1>;
+		qcom,ipi-ping;
 	};
 
 	qcom,smem@fa00000 {
@@ -160,6 +403,13 @@
 		};
 	};
 
+	rpm_bus: qcom,rpm-smd {
+		compatible = "qcom,rpm-smd";
+		rpm-channel-name = "rpm_requests";
+		rpm-channel-type = <15>; /* SMD_APPS_RPM */
+		rpm-standalone;
+	};
+
 	sdcc1: qcom,sdcc@f9824000 {
 		cell-index = <1>; /* SDC1 eMMC slot */
 		compatible = "qcom,msm-sdcc";
@@ -193,132 +443,147 @@
 	spmi_bus: qcom,spmi@fc4c0000 {
 		cell-index = <0>;
 		compatible = "qcom,spmi-pmic-arb";
+		reg-names = "core", "intr", "cnfg";
 		reg = <0xfc4cf000 0x1000>,
-		      <0Xfc4cb000 0x1000>;
+		      <0Xfc4cb000 0x1000>,
+		      <0Xfc4ca000 0x1000>;
 		/* 190,ee0_krait_hlos_spmi_periph_irq */
 		/* 187,channel_0_krait_hlos_trans_done_irq */
 		interrupts = <0 190 0>, <0 187 0>;
 		qcom,not-wakeup;
 		qcom,pmic-arb-ee = <0>;
 		qcom,pmic-arb-channel = <0>;
-		qcom,pmic-arb-ppid-map = <0x001000a0>, /* PM8026_0 */
-					 <0x005000a2>, /* INTERRUPT */
-					 <0x006000a3>, /* SPMI_0 */
-					 <0x00800000>, /* PON0 */
-					 <0x00a000a5>, /* VREF_LPDDR3 */
-					 <0x01000001>, /* SMBB_CHG */
-					 <0x01100002>, /* SMBB_BUCK */
-					 <0x01200003>, /* SMBB_BIF */
-					 <0x01300004>, /* SMBB_USB */
-					 <0x01500005>, /* SMBB_BOOST */
-					 <0x01600006>, /* SMBB_MISC */
-					 <0x02800009>, /* COINCELL */
-					 <0x02c000a6>, /* MBG */
-					 <0x0310000a>, /* VADC1_USR */
-					 <0x03200041>, /* VADC1_MDM */
-					 <0x0330000b>, /* VADC1_BMS */
-					 <0x0340000c>, /* VADC2_BTM */
-					 <0x0360000d>, /* IADC1_USR */
-					 <0x03700042>, /* IADC1_MDM */
-					 <0x0380000e>, /* IADC1_BMS */
-					 <0x0400000f>, /* BMS_1 */
-					 <0x050000a7>, /* SHARED_XO */
-					 <0x051000a8>, /* BB_CLK1 */
-					 <0x05200010>, /* BB_CLK2 */
-					 <0x05a000ac>, /* SLEEP_CLK */
-					 <0x06000045>, /* RTC_RW */
-					 <0x06100012>, /* RTC_ALARM */
-					 <0x070000ae>, /* PBS_CORE */
-					 <0x071000af>, /* PBS_CLIENT_1 */
-					 <0x072000b0>, /* PBS_CLIENT_2 */
-					 <0x073000b1>, /* PBS_CLIENT_3 */
-					 <0x074000b2>, /* PBS_CLIENT_4 */
-					 <0x075000b3>, /* PBS_CLIENT_5 */
-					 <0x076000b4>, /* PBS_CLIENT_6 */
-					 <0x07700046>, /* PBS_CLIENT_7 */
-					 <0x07800047>, /* PBS_CLIENT_8 */
-					 <0x079000b5>, /* PBS_CLIENT_9 */
-					 <0x07a000b6>, /* PBS_CLIENT_10 */
-					 <0x07b000b7>, /* PBS_CLIENT_11 */
-					 <0x07c000b8>, /* PBS_CLIENT_12 */
-					 <0x07d000b9>, /* PBS_CLIENT_13 */
-					 <0x07e000ba>, /* PBS_CLIENT_14 */
-					 <0x07f000bb>, /* PBS_CLIENT_15 */
-					 <0x0a0000bd>, /* MPP_1 */
-					 <0x0a100014>, /* MPP_2 */
-					 <0x0a200015>, /* MPP_3 */
-					 <0x0a300016>, /* MPP_4 */
-					 <0x0a400048>, /* MPP_5 */
-					 <0x0a500017>, /* MPP_6 */
-					 <0x0a600018>, /* MPP_7 */
-					 <0x0a700049>, /* MPP_8 */
-					 <0x0c000019>, /* GPIO_1 */
-					 <0x0c10001a>, /* GPIO_2 */
-					 <0x0c20004a>, /* GPIO_3 */
-					 <0x0c30004b>, /* GPIO_4 */
-					 <0x0c40001b>, /* GPIO_5 */
-					 <0x0c50001c>, /* GPIO_6 */
-					 <0x0c60001d>, /* GPIO_7 */
-					 <0x0c70004c>, /* GPIO_8 */
-					 <0x0fe000be>, /* TRIM_0 */
-					 <0x110000bf>, /* BUCK_CMN_1 */
-					 <0x114000c0>, /* SMPS1 */
-					 <0x115000c1>, /* FTPS1_1 */
-					 <0x116000c2>, /* BUCK_FREQ_1 */
-					 <0x1170001e>, /* SMPS2 */
-					 <0x1180001f>, /* FTPS1_2 */
-					 <0x11900020>, /* BUCK_FREQ_2 */
-					 <0x11a000c3>, /* SMPS3 */
-					 <0x11b000c4>, /* SMPS_3_PS1 */
-					 <0x11c000c5>, /* BUCK_FREQ_3 */
-					 <0x11d000c6>, /* SMPS4 */
-					 <0x11e000c7>, /* SMPS_4_PS1 */
-					 <0x11f000c8>, /* BUCK_FREQ_4 */
-					 <0x120000c9>, /* SMPS5 */
-					 <0x121000ca>, /* SMPS_5_PS1 */
-					 <0x122000cb>, /* BUCK_FREQ_5 */
-					 <0x140000cc>, /* LDO_1 */
-					 <0x141000cd>, /* LDO_2 */
-					 <0x142000ce>, /* LDO_3 */
-					 <0x143000cf>, /* LDO_4 */
-					 <0x144000d0>, /* LDO_5 */
-					 <0x145000d1>, /* LDO_6 */
-					 <0x146000d2>, /* LDO_7 */
-					 <0x147000d3>, /* LDO_8 */
-					 <0x148000d4>, /* LDO_9 */
-					 <0x149000d5>, /* LDO_10 */
-					 <0x14a000d6>, /* LDO_11 */
-					 <0x14b000d7>, /* LDO_12 */
-					 <0x14c000d8>, /* LDO_13 */
-					 <0x14d000d9>, /* LDO_14 */
-					 <0x14e000da>, /* LDO_15 */
-					 <0x14f000db>, /* LDO_16 */
-					 <0x150000dc>, /* LDO_17 */
-					 <0x151000dd>, /* LDO_18 */
-					 <0x152000de>, /* LDO_19 */
-					 <0x153000df>, /* LDO_20 */
-					 <0x154000e0>, /* LDO_21 */
-					 <0x155000e1>, /* LDO_22 */
-					 <0x156000e2>, /* LDO_23 */
-					 <0x157000e3>, /* LDO_24 */
-					 <0x158000e4>, /* LDO_25 */
-					 <0x159000e5>, /* LDO_26 */
-					 <0x15a000e6>, /* LDO_27 */
-					 <0x15b000e7>, /* LDO_28 */
-					 <0x180000e8>, /* LVS_1 */
-					 <0x1b0000e9>, /* LPG_LUT */
-					 <0x1b1000ea>, /* LPG_CHAN_1 */
-					 <0x1b200023>, /* LPG_CHAN_2 */
-					 <0x1b300024>, /* LPG_CHAN_3 */
-					 <0x1b400025>, /* LPG_CHAN_4 */
-					 <0x1b500026>, /* LPG_CHAN_5 */
-					 <0x1b600027>, /* LPG_CHAN_6 */
-					 <0x1bc00028>, /* PWM_3D */
-					 <0x1c000029>, /* VIB1 */
-					 <0x1d30002a>, /* FLASH_DRV */
-					 <0x1d80002b>; /* WLED */
 	};
 
+	i2c@f9926000 { /* BLSP-1 QUP-4 */
+		cell-index = <0>;
+		compatible = "qcom,i2c-qup";
+		reg = <0xf9926000 0x1000>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg-names = "qup_phys_addr";
+		interrupts = <0 98 0>;
+		interrupt-names = "qup_err_intr";
+		qcom,i2c-bus-freq = <100000>;
+	};
+
+	qcom,acpuclk@f9011050 {
+		compatible = "qcom,acpuclk-a7";
+		reg = <0xf9011050 0x8>;
+		reg-names = "rcg_base";
+		a7_cpu-supply = <&pm8226_s2>;
+		a7_mem-supply = <&pm8226_l3>;
+	};
+
+	qcom,ocmem@fdd00000 {
+		compatible = "qcom,msm-ocmem";
+		reg = <0xfdd00000 0x2000>,
+		      <0xfdd02000 0x2000>,
+		      <0xfe039000 0x400>,
+		      <0xfec00000 0x180000>;
+		reg-names = "ocmem_ctrl_physical", "dm_ctrl_physical", "br_ctrl_physical", "ocmem_physical";
+		interrupts = <0 76 0 0 77 0>;
+		interrupt-names = "ocmem_irq", "dm_irq";
+		qcom,ocmem-num-regions = <0x1>;
+		qcom,ocmem-num-macros = <0x2>;
+		qcom,resource-type = <0x706d636f>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x0 0xfec00000 0x180000>;
+
+		partition@0 {
+			reg = <0x0 0x100000>;
+			qcom,ocmem-part-name = "graphics";
+			qcom,ocmem-part-min = <0x80000>;
+		};
+	};
+
+	qcom,venus@fdce0000 {
+		compatible = "qcom,pil-venus";
+		reg = <0xfdce0000 0x4000>,
+		      <0xfdc80000 0x400>;
+		reg-names = "wrapper_base", "vbif_base";
+		vdd-supply = <&gdsc_venus>;
+
+		qcom,firmware-name = "venus";
+	};
+
+	qcom,pronto@fb21b000 {
+		compatible = "qcom,pil-pronto";
+		reg = <0xfb21b000 0x3000>,
+		      <0xfc401700 0x4>,
+		      <0xfd485300 0xc>;
+		reg-names = "pmu_base", "clk_base", "halt_base";
+		interrupts = <0 149 1>;
+		vdd_pronto_pll-supply = <&pm8226_l8>;
+
+		qcom,firmware-name = "wcnss";
+	};
+
+	qcom,lpass@fe200000 {
+		compatible = "qcom,pil-q6v5-lpass";
+		reg = <0xfe200000 0x00100>,
+		      <0xfd485100 0x00010>;
+		reg-names = "qdsp6_base", "halt_base";
+		vdd_cx-supply = <&pm8226_s1_corner>;
+		interrupts = <0 162 1>;
+
+		qcom,firmware-name = "adsp";
+	};
+
+	qcom,msm-mem-hole {
+		compatible = "qcom,msm-mem-hole";
+		qcom,memblock-remove = <0x8400000 0x7b00000>; /* Address and Size of Hole */
+	};
+
+	tsens: tsens@fc4a8000 {
+		compatible = "qcom,msm-tsens";
+		reg = <0xfc4a8000 0x2000>,
+		      <0xfc4b8000 0x1000>;
+		reg-names = "tsens_physical", "tsens_eeprom_physical";
+		interrupts = <0 184 0>;
+		qcom,sensors = <6>;
+		qcom,slope = <3200 3200 3200 3200 3200 3200>;
+		qcom,calib-mode = "fuse_map2";
+	};
+
+	qcom,msm-thermal {
+		compatible = "qcom,msm-thermal";
+		qcom,sensor-id = <0>;
+		qcom,poll-ms = <250>;
+		qcom,limit-temp = <60>;
+		qcom,temp-hysteresis = <10>;
+		qcom,freq-step = <2>;
+	};
+
+	spi_0: spi@f9923000 { /* BLSP1 QUP1 */
+		compatible = "qcom,spi-qup-v2";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg-names = "spi_physical", "spi_bam_physical";
+		reg = <0xf9923000 0x1000>,
+		      <0xf9904000 0xF000>;
+		interrupt-names = "spi_irq", "spi_bam_irq";
+		interrupts = <0 95 0>, <0 238 0>;
+		spi-max-frequency = <19200000>;
+
+		gpios = <&msmgpio 3 0>, /* CLK  */
+			<&msmgpio 1 0>, /* MISO */
+			<&msmgpio 0 0>; /* MOSI */
+		cs-gpios = <&msmgpio 2 0>;
+
+		qcom,infinite-mode = <0>;
+		qcom,use-bam;
+		qcom,ver-reg-exists;
+		qcom,bam-consumer-pipe-index = <12>;
+		qcom,bam-producer-pipe-index = <13>;
+	};
+
+	qcom,bam_dmux@fc834000 {
+		compatible = "qcom,bam_dmux";
+		reg = <0xfc834000 0x7000>;
+		interrupts = <0 29 1>;
+	};
 };
 
 &gdsc_venus {
@@ -345,5 +610,95 @@
 	status = "ok";
 };
 
+/include/ "msm-pm8226.dtsi"
 /include/ "msm8226-regulator.dtsi"
-/include/ "msm-pm8026.dtsi"
+
+&pm8226_vadc {
+	chan@0 {
+		label = "usb_in";
+		reg = <0>;
+		qcom,decimation = <0>;
+		qcom,pre-div-channel-scaling = <4>;
+		qcom,calibration-type = "absolute";
+		qcom,scale-function = <0>;
+		qcom,hw-settle-time = <0>;
+		qcom,fast-avg-setup = <0>;
+	};
+
+	chan@2 {
+		label = "vchg_sns";
+		reg = <2>;
+		qcom,decimation = <0>;
+		qcom,pre-div-channel-scaling = <3>;
+		qcom,calibration-type = "absolute";
+		qcom,scale-function = <0>;
+		qcom,hw-settle-time = <0>;
+		qcom,fast-avg-setup = <0>;
+	};
+
+	chan@5 {
+		label = "vcoin";
+		reg = <5>;
+		qcom,decimation = <0>;
+		qcom,pre-div-channel-scaling = <1>;
+		qcom,calibration-type = "absolute";
+		qcom,scale-function = <0>;
+		qcom,hw-settle-time = <0>;
+		qcom,fast-avg-setup = <0>;
+	};
+
+	chan@6 {
+		label = "vbat_sns";
+		reg = <6>;
+		qcom,decimation = <0>;
+		qcom,pre-div-channel-scaling = <1>;
+		qcom,calibration-type = "absolute";
+		qcom,scale-function = <0>;
+		qcom,hw-settle-time = <0>;
+		qcom,fast-avg-setup = <0>;
+	};
+
+	chan@7 {
+		label = "vph_pwr";
+		reg = <7>;
+		qcom,decimation = <0>;
+		qcom,pre-div-channel-scaling = <1>;
+		qcom,calibration-type = "absolute";
+		qcom,scale-function = <0>;
+		qcom,hw-settle-time = <0>;
+		qcom,fast-avg-setup = <0>;
+	};
+
+	chan@30 {
+		label = "batt_therm";
+		reg = <0x30>;
+		qcom,decimation = <0>;
+		qcom,pre-div-channel-scaling = <0>;
+		qcom,calibration-type = "ratiometric";
+		qcom,scale-function = <1>;
+		qcom,hw-settle-time = <2>;
+		qcom,fast-avg-setup = <0>;
+	};
+
+	chan@31 {
+		label = "batt_id";
+		reg = <0x31>;
+		qcom,decimation = <0>;
+		qcom,pre-div-channel-scaling = <0>;
+		qcom,calibration-type = "ratiometric";
+		qcom,scale-function = <0>;
+		qcom,hw-settle-time = <2>;
+		qcom,fast-avg-setup = <0>;
+	};
+
+	chan@b2 {
+		label = "xo_therm_pu2";
+		reg = <0xb2>;
+		qcom,decimation = <0>;
+		qcom,pre-div-channel-scaling = <0>;
+		qcom,calibration-type = "ratiometric";
+		qcom,scale-function = <4>;
+		qcom,hw-settle-time = <2>;
+		qcom,fast-avg-setup = <0>;
+	};
+};
diff --git a/arch/arm/boot/dts/msm8610-iommu-domains.dtsi b/arch/arm/boot/dts/msm8610-iommu-domains.dtsi
new file mode 100644
index 0000000..52a8c47
--- /dev/null
+++ b/arch/arm/boot/dts/msm8610-iommu-domains.dtsi
@@ -0,0 +1,36 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/ {
+	qcom,iommu-domains {
+		compatible = "qcom,iommu-domains";
+
+		qcom,iommu-domain1 {
+			label = "lpass_secure";
+			qcom,iommu-contexts = <&lpass_q6_fw>;
+			qcom,virtual-addr-pool = <0x00000000 0x0FFFFFFF
+						  0xF0000000 0x0FFFFFFF>;
+		};
+
+		qcom,iommu-domain2 {
+			label = "lpass_audio";
+			qcom,iommu-contexts = <&lpass_audio_shared>;
+			qcom,virtual-addr-pool = <0x10000000 0x0FFFFFFF>;
+		};
+
+		qcom,iommu-domain3 {
+			label = "lpass_video";
+			qcom,iommu-contexts = <&lpass_video_shared>;
+			qcom,virtual-addr-pool = <0x20000000 0x0FFFFFFF>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/msm8610-ion.dtsi b/arch/arm/boot/dts/msm8610-ion.dtsi
new file mode 100644
index 0000000..0abaca5
--- /dev/null
+++ b/arch/arm/boot/dts/msm8610-ion.dtsi
@@ -0,0 +1,62 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/ {
+	qcom,ion {
+		compatible = "qcom,msm-ion";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		qcom,ion-heap@30 { /* SYSTEM HEAP */
+			reg = <30>;
+		};
+
+		qcom,ion-heap@8 { /* CP_MM HEAP */
+			compatible = "qcom,msm-ion-reserve";
+			reg = <8>;
+			qcom,heap-align = <0x1000>;
+			qcom,memory-reservation-type = "EBI1"; /* reserve EBI memory */
+			qcom,memory-reservation-size = <0x3800000>;
+		};
+
+		qcom,ion-heap@25 { /* IOMMU HEAP */
+			reg = <25>;
+		};
+
+		qcom,ion-heap@27 { /* QSECOM HEAP */
+			compatible = "qcom,msm-ion-reserve";
+			reg = <27>;
+			qcom,heap-align = <0x1000>;
+			qcom,memory-reservation-type = "EBI1"; /* reserve EBI memory */
+			qcom,memory-reservation-size = <0x780000>;
+		};
+
+		qcom,ion-heap@28 { /* AUDIO HEAP */
+			compatible = "qcom,msm-ion-reserve";
+			reg = <28>;
+			qcom,heap-align = <0x1000>;
+			qcom,memory-reservation-type = "EBI1"; /* reserve EBI memory */
+			qcom,memory-reservation-size = <0x314000>;
+		};
+
+		qcom,ion-heap@29 { /* FIRMWARE HEAP */
+			compatible = "qcom,msm-ion-reserve";
+			reg = <29>;
+			qcom,heap-align = <0x20000>;
+			qcom,heap-adjacent = <8>;
+			qcom,memory-reservation-type = "EBI1"; /* reserve EBI memory */
+			qcom,memory-reservation-size = <0xA00000>;
+		};
+
+	};
+};
+
diff --git a/arch/arm/boot/dts/msm8610-pm.dtsi b/arch/arm/boot/dts/msm8610-pm.dtsi
new file mode 100644
index 0000000..feb3087
--- /dev/null
+++ b/arch/arm/boot/dts/msm8610-pm.dtsi
@@ -0,0 +1,398 @@
+/* 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/ "skeleton.dtsi"
+
+/ {
+	qcom,spm@f9089000 {
+		compatible = "qcom,spm-v2";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0xf9089000 0x1000>;
+		qcom,core-id = <0>;
+		qcom,saw2-ver-reg = <0xfd0>;
+		qcom,saw2-cfg = <0x01>;
+		qcom,saw2-spm-dly= <0x20000400>;
+		qcom,saw2-spm-ctl = <0x1>;
+		qcom,saw2-spm-cmd-wfi = [60 03 60 76 76 0b 0f];
+		qcom,saw2-spm-cmd-spc = [00 20 10 80 90 5b 60 03 60 3b 76 76 94
+				5b 80 10 2b 30 06 26 30 0f];
+		qcom,saw2-spm-cmd-pc = [00 20 10 80 90 5b 60 07 3b 76 76 0b 94
+				5b 80 10 2b 30 06 26 30 0f];
+	};
+
+	qcom,spm@f9099000 {
+		compatible = "qcom,spm-v2";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0xf9099000 0x1000>;
+		qcom,core-id = <1>;
+		qcom,saw2-ver-reg = <0xfd0>;
+		qcom,saw2-cfg = <0x01>;
+		qcom,saw2-spm-dly= <0x20000400>;
+		qcom,saw2-spm-ctl = <0x1>;
+		qcom,saw2-spm-cmd-wfi = [60 03 60 76 76 0b 0f];
+		qcom,saw2-spm-cmd-spc = [00 20 10 80 90 5b 60 03 60 3b 76 76 94
+				5b 80 10 2b 30 06 26 30 0f];
+		qcom,saw2-spm-cmd-pc = [00 20 10 80 90 5b 60 07 3b 76 76 0b 94
+				5b 80 10 2b 30 06 26 30 0f];
+	};
+
+	qcom,spm@f90a9000 {
+		compatible = "qcom,spm-v2";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0xf90a9000 0x1000>;
+		qcom,core-id = <2>;
+		qcom,saw2-ver-reg = <0xfd0>;
+		qcom,saw2-cfg = <0x01>;
+		qcom,saw2-spm-dly= <0x20000400>;
+		qcom,saw2-spm-ctl = <0x1>;
+		qcom,saw2-spm-cmd-wfi = [60 03 60 76 76 0b 0f];
+		qcom,saw2-spm-cmd-spc = [00 20 10 80 90 5b 60 03 60 3b 76 76 94
+				5b 80 10 2b 30 06 26 30 0f];
+		qcom,saw2-spm-cmd-pc = [00 20 10 80 90 5b 60 07 3b 76 76 0b 94
+				5b 80 10 2b 30 06 26 30 0f];
+	};
+
+	qcom,spm@f90b9000 {
+		compatible = "qcom,spm-v2";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0xf90b9000 0x1000>;
+		qcom,core-id = <3>;
+		qcom,saw2-ver-reg = <0xfd0>;
+		qcom,saw2-cfg = <0x01>;
+		qcom,saw2-spm-dly= <0x20000400>;
+		qcom,saw2-spm-ctl = <0x1>;
+		qcom,saw2-spm-cmd-wfi = [60 03 60 76 76 0b 0f];
+		qcom,saw2-spm-cmd-spc = [00 20 10 80 90 5b 60 03 60 3b 76 76 94
+				5b 80 10 2b 30 06 26 30 0f];
+		qcom,saw2-spm-cmd-pc = [00 20 10 80 90 5b 60 07 3b 76 76 0b 94
+				5b 80 10 2b 30 06 26 30 0f];
+	};
+
+	qcom,spm@f9012000 {
+		compatible = "qcom,spm-v2";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0xf9012000 0x1000>;
+		qcom,core-id = <0xffff>; /* L2/APCS SAW */
+		qcom,saw2-ver-reg = <0xfd0>;
+		qcom,saw2-cfg = <0x14>;
+		qcom,saw2-spm-dly= <0x20000400>;
+		qcom,saw2-spm-ctl = <0x1>;
+		qcom,saw2-pmic-data0 = <0x02030080>;
+		qcom,saw2-pmic-data1 = <0x00030000>;
+		qcom,vctl-timeout-us = <50>;
+		qcom,vctl-port = <0x0>;
+		qcom,phase-port = <0x1>;
+		qcom,pfm-port = <0x2>;
+		qcom,saw2-spm-cmd-ret = [0b 00 03 00 7b 0f];
+		qcom,saw2-spm-cmd-gdhs = [00 20 32 60 70 80 0b 6b c0 e0 d0 42 07
+				78 1f 80 4e d0 e0 c0 22 6b 50 4b 60 02 32 50 7b
+				0f];
+		qcom,saw2-spm-cmd-pc = [00 32 60 70 80 b0 0b 10 e0 d0 6b c0
+				42 f0 11 07 01 b0 78 1f 80 4e c0 d0 12 e0 6b 50 4b
+				60 02 32 50 f0 7b 0f]; /*APCS_PMIC_OFF_L2RAM_OFF*/
+	};
+
+	qcom,lpm-resources {
+		compatible = "qcom,lpm-resources";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		qcom,lpm-resources@0 {
+			reg = <0x0>;
+			qcom,name = "vdd-dig";
+			qcom,resource-type = <0>;
+			qcom,type = <0x62706d73>;	/* "smpb" */
+			qcom,id = <0x02>;
+			qcom,key = <0x6e726f63>;	/* "corn" */
+			qcom,init-value = <5>;		/* Super Turbo */
+		};
+
+		qcom,lpm-resources@1 {
+			reg = <0x1>;
+			qcom,name = "vdd-mem";
+			qcom,resource-type = <0>;
+			qcom,type = <0x62706d73>;	/* "smpb" */
+			qcom,id = <0x01>;
+			qcom,key = <0x7675>;		/* "uv" */
+			qcom,init-value = <1050000>;	/* Super Turbo */
+		};
+
+		qcom,lpm-resources@2 {
+			reg = <0x2>;
+			qcom,name = "pxo";
+			qcom,resource-type = <0>;
+			qcom,type = <0x306b6c63>;	/* "clk0" */
+			qcom,id = <0x00>;
+			qcom,key = <0x62616e45>;	/* "Enab" */
+			qcom,init-value = <1>;		/* On */
+		};
+
+		qcom,lpm-resources@3 {
+			reg = <0x3>;
+			qcom,name = "l2";
+			qcom,resource-type = <1>;
+			qcom,init-value = <2>;		/* Retention */
+		};
+	};
+
+	qcom,lpm-levels {
+		compatible = "qcom,lpm-levels";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		qcom,lpm-level@0 {
+			reg = <0x0>;
+			qcom,mode = <0>;        /* MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT */
+			qcom,xo = <1>;          /* ON */
+			qcom,l2 = <3>;          /* ACTIVE */
+			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
+			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
+			qcom,vdd-dig-upper-bound = <5>; /* MAX */
+			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,latency-us = <1>;
+			qcom,ss-power = <784>;
+			qcom,energy-overhead = <190000>;
+			qcom,time-overhead = <100>;
+		};
+
+		qcom,lpm-level@1 {
+			reg = <0x1>;
+			qcom,mode = <4>;        /* MSM_PM_SLEEP_MODE_RETENTION*/
+			qcom,xo = <1>;          /* ON */
+			qcom,l2 = <3>;          /* ACTIVE */
+			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
+			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
+			qcom,vdd-dig-upper-bound = <5>; /* MAX */
+			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,latency-us = <75>;
+			qcom,ss-power = <735>;
+			qcom,energy-overhead = <77341>;
+			qcom,time-overhead = <105>;
+		};
+
+
+		qcom,lpm-level@2 {
+			reg = <0x2>;
+			qcom,mode = <2>;        /* MSM_PM_SLEEP_MODE_STANDALONE_POWER_COLLAPSE */
+			qcom,xo = <1>;          /* ON */
+			qcom,l2 = <3>;          /* ACTIVE */
+			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
+			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
+			qcom,vdd-dig-upper-bound = <5>; /* MAX */
+			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,latency-us = <95>;
+			qcom,ss-power = <725>;
+			qcom,energy-overhead = <99500>;
+			qcom,time-overhead = <130>;
+		};
+
+		qcom,lpm-level@3 {
+			reg = <0x3>;
+			qcom,mode = <3>;        /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
+			qcom,xo = <1>;          /* ON */
+			qcom,l2 = <1>;          /* GDHS */
+			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
+			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
+			qcom,vdd-dig-upper-bound = <5>; /* MAX */
+			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,latency-us = <2000>;
+			qcom,ss-power = <138>;
+			qcom,energy-overhead = <1208400>;
+			qcom,time-overhead = <3200>;
+		};
+
+		qcom,lpm-level@4 {
+			reg = <0x4>;
+			qcom,mode = <3>;        /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
+			qcom,xo = <1>;          /* ON */
+			qcom,l2 = <0>;          /* OFF */
+			qcom,vdd-mem-upper-bound = <1050000>; /* ACTIVE */
+			qcom,vdd-mem-lower-bound = <750000>;  /* RETENTION HIGH */
+			qcom,vdd-dig-upper-bound = <3>;  /* ACTIVE */
+			qcom,vdd-dig-lower-bound = <2>;  /* RETENTION HIGH */
+			qcom,latency-us = <3000>;
+			qcom,ss-power = <110>;
+			qcom,energy-overhead = <1250300>;
+			qcom,time-overhead = <3500>;
+		};
+
+		qcom,lpm-level@5 {
+			reg = <0x5>;
+			qcom,mode = <3>;        /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
+			qcom,xo = <0>;          /* OFF */
+			qcom,l2 = <1>;          /* GDHS */
+			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
+			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
+			qcom,vdd-dig-upper-bound = <5>; /* MAX */
+			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,latency-us = <3000>;
+			qcom,ss-power = <68>;
+			qcom,energy-overhead = <1350200>;
+			qcom,time-overhead = <4000>;
+		};
+
+		qcom,lpm-level@6 {
+			reg = <0x6>;
+			qcom,mode = <3>;        /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
+			qcom,xo = <0>;          /* OFF */
+			qcom,l2 = <0>;          /* OFF */
+			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
+			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
+			qcom,vdd-dig-upper-bound = <5>; /* MAX */
+			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,latency-us = <10300>;
+			qcom,ss-power = <63>;
+			qcom,energy-overhead = <2128000>;
+			qcom,time-overhead = <18200>;
+		};
+
+		qcom,lpm-level@7 {
+			reg = <0x7>;
+			qcom,mode= <3>;         /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
+			qcom,xo = <0>;          /* OFF */
+			qcom,l2 = <0>;          /* OFF */
+			qcom,vdd-mem-upper-bound = <1050000>; /* ACTIVE */
+			qcom,vdd-mem-lower-bound = <750000>;  /* RETENTION HIGH */
+			qcom,vdd-dig-upper-bound = <3>;  /* ACTIVE */
+			qcom,vdd-dig-lower-bound = <2>;  /* RETIONTION HIGH */
+			qcom,latency-us = <18000>;
+			qcom,ss-power = <10>;
+			qcom,energy-overhead = <3202600>;
+			qcom,time-overhead = <27000>;
+		};
+
+		qcom,lpm-level@8 {
+			reg = <0x8>;
+			qcom,mode= <3>;         /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
+			qcom,xo = <0>;          /* OFF */
+			qcom,l2 = <0>;          /* OFF */
+			qcom,vdd-mem-upper-bound = <750000>; /* RETENTION HIGH */
+			qcom,vdd-mem-lower-bound = <750000>; /* RETENTION LOW */
+			qcom,vdd-dig-upper-bound = <2>; /* RETENTION HIGH */
+			qcom,vdd-dig-lower-bound = <0>; /* RETENTION LOW */
+			qcom,latency-us = <20000>;
+			qcom,ss-power = <2>;
+			qcom,energy-overhead = <4252000>;
+			qcom,time-overhead = <32000>;
+		};
+	};
+
+	qcom,pm-boot {
+		compatible = "qcom,pm-boot";
+		qcom,mode = <0>; /* MSM_PM_BOOT_CONFIG_TZ */
+	};
+
+	qcom,mpm@fc4281d0 {
+		compatible = "qcom,mpm-v2";
+		reg = <0xfc4281d0 0x1000>, /* MSM_RPM_MPM_BASE 4K */
+		    <0xf9011008 0x4>;   /* MSM_APCS_GCC_BASE 4K */
+		reg-names = "vmpm", "ipc";
+		interrupts = <0 171 1>;
+
+		qcom,ipc-bit-offset = <1>;
+
+		qcom,gic-parent = <&intc>;
+		qcom,gic-map = <47 172>, /* usb2_hsic_async_wakeup_irq */
+			<53 104>, /* mdss_irq */
+			<62 222>, /* ee0_krait_hlos_spmi_periph_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 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 188>, /* lpass_irq_out_apcs(0) */
+			<0xff 189>, /* lpass_irq_out_apcs(1) */
+			<0xff 190>, /* lpass_irq_out_apcs(2) */
+			<0xff 191>, /* lpass_irq_out_apcs(3) */
+			<0xff 192>, /* lpass_irq_out_apcs(4) */
+			<0xff 193>, /* lpass_irq_out_apcs(5) */
+			<0xff 194>, /* lpass_irq_out_apcs(6) */
+			<0xff 195>, /* lpass_irq_out_apcs(7) */
+			<0xff 196>, /* lpass_irq_out_apcs(8) */
+			<0xff 197>, /* lpass_irq_out_apcs(9) */
+			<0xff 200>, /* rpm_ipc(4) */
+			<0xff 201>, /* rpm_ipc(5) */
+			<0xff 202>, /* rpm_ipc(6) */
+			<0xff 203>, /* rpm_ipc(7) */
+			<0xff 204>, /* rpm_ipc(24) */
+			<0xff 205>, /* rpm_ipc(25) */
+			<0xff 206>, /* rpm_ipc(26) */
+			<0xff 207>, /* rpm_ipc(27) */
+			<0xff 240>; /* summary_irq_kpss */
+
+		qcom,gpio-parent = <&msmgpio>;
+		qcom,gpio-map = <3  102>,
+			<4  1 >,
+			<5  5 >,
+			<6  9 >,
+			<7  18>,
+			<8  20>,
+			<9  24>,
+			<10  27>,
+			<11  28>,
+			<12  34>,
+			<13  35>,
+			<14  37>,
+			<15  42>,
+			<16  44>,
+			<17  46>,
+			<18  50>,
+			<19  54>,
+			<20  59>,
+			<21  61>,
+			<22  62>,
+			<23  64>,
+			<24  65>,
+			<25  66>,
+			<26  67>,
+			<27  68>,
+			<28  71>,
+			<29  72>,
+			<30  73>,
+			<31  74>,
+			<32  75>,
+			<33  77>,
+			<34  79>,
+			<35  80>,
+			<36  82>,
+			<37  86>,
+			<38  92>,
+			<39  93>,
+			<40  95>;
+	};
+
+	qcom,pm-8x60@fe805664 {
+		compatible = "qcom,pm-8x60";
+		reg = <0xfe805664 0x40>;
+		qcom,pc-mode = <0>; /*MSM_PC_TZ_L2_INT */
+		qcom,use-sync-timer;
+	};
+
+	qcom,rpm-stats@0xfc19dbd0{
+		compatible = "qcom,rpm-stats";
+		reg = <0xfc19dbd0 0x1000>;
+		reg-names = "phys_addr_base";
+		qcom,sleep-stats-version = <2>;
+	};
+};
diff --git a/arch/arm/boot/dts/msm8610-regulator.dtsi b/arch/arm/boot/dts/msm8610-regulator.dtsi
new file mode 100644
index 0000000..362d126
--- /dev/null
+++ b/arch/arm/boot/dts/msm8610-regulator.dtsi
@@ -0,0 +1,227 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+ /* Stub Regulators */
+
+ / {
+	pm8110_s1: regulator-s1 {
+		compatible = "qcom,stub-regulator";
+		regulator-name = "8110_s1";
+		qcom,hpm-min-load = <100000>;
+		regulator-min-microvolt = <1150000>;
+		regulator-max-microvolt = <1150000>;
+	};
+
+	pm8110_s1_corner: regulator-s1-corner {
+		compatible = "qcom,stub-regulator";
+		regulator-name = "8110_s1_corner";
+		regulator-min-microvolt = <1>;
+		regulator-max-microvolt = <7>;
+		qcom,consumer-supplies = "vdd_dig", "";
+	};
+
+	pm8110_s2: regulator-s2 {
+		compatible = "qcom,stub-regulator";
+		regulator-name = "8110_s2";
+		qcom,hpm-min-load = <100000>;
+		regulator-min-microvolt = <1050000>;
+		regulator-max-microvolt = <1050000>;
+	};
+
+	pm8110_s3: regulator-s3 {
+		compatible = "qcom,stub-regulator";
+		regulator-name = "8110_s3";
+		qcom,hpm-min-load = <100000>;
+		regulator-min-microvolt = <1350000>;
+		regulator-max-microvolt = <1350000>;
+	};
+
+	pm8110_s4: regulator-s4 {
+		compatible = "qcom,stub-regulator";
+		regulator-name = "8110_s4";
+		qcom,hpm-min-load = <100000>;
+		regulator-min-microvolt = <2150000>;
+		regulator-max-microvolt = <2150000>;
+	};
+
+	pm8110_l1: regulator-l1 {
+		compatible = "qcom,stub-regulator";
+		regulator-name = "8110_l1";
+		parent-supply = <&pm8110_s3>;
+		qcom,hpm-min-load = <10000>;
+		regulator-min-microvolt = <1225000>;
+		regulator-max-microvolt = <1225000>;
+	};
+
+	pm8110_l2: regulator-l2 {
+		compatible = "qcom,stub-regulator";
+		regulator-name = "8110_l2";
+		parent-supply = <&pm8110_s3>;
+		qcom,hpm-min-load = <10000>;
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <1200000>;
+	};
+
+	pm8110_l3: regulator-l3 {
+		compatible = "qcom,stub-regulator";
+		regulator-name = "8110_l3";
+		parent-supply = <&pm8110_s3>;
+		qcom,hpm-min-load = <10000>;
+		regulator-min-microvolt = <1150000>;
+		regulator-max-microvolt = <1150000>;
+	};
+
+	pm8110_l4: regulator-l4 {
+		compatible = "qcom,stub-regulator";
+		regulator-name = "8110_l4";
+		parent-supply = <&pm8110_s3>;
+		qcom,hpm-min-load = <10000>;
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <1200000>;
+	};
+
+	pm8110_l5: regulator-l5 {
+		compatible = "qcom,stub-regulator";
+		regulator-name = "8110_l5";
+		parent-supply = <&pm8110_s3>;
+		qcom,hpm-min-load = <10000>;
+		regulator-min-microvolt = <1300000>;
+		regulator-max-microvolt = <1300000>;
+	};
+
+	pm8110_l6: regulator-l6 {
+		compatible = "qcom,stub-regulator";
+		regulator-name = "8110_l6";
+		parent-supply = <&pm8110_s4>;
+		qcom,hpm-min-load = <10000>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+	};
+
+	pm8110_l7: regulator-l7 {
+		compatible = "qcom,stub-regulator";
+		regulator-name = "8110_l7";
+		parent-supply = <&pm8110_s4>;
+		qcom,hpm-min-load = <10000>;
+		regulator-min-microvolt = <2050000>;
+		regulator-max-microvolt = <2050000>;
+	};
+
+	pm8110_l8: regulator-l8 {
+		compatible = "qcom,stub-regulator";
+		regulator-name = "8110_l8";
+		parent-supply = <&pm8110_s4>;
+		qcom,hpm-min-load = <5000>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+	};
+
+	pm8110_l9: regulator-l9 {
+		compatible = "qcom,stub-regulator";
+		regulator-name = "8110_l9";
+		parent-supply = <&pm8110_s4>;
+		qcom,hpm-min-load = <10000>;
+		regulator-min-microvolt = <2050000>;
+		regulator-max-microvolt = <2050000>;
+	};
+
+	pm8110_l10: regulator-l10 {
+		compatible = "qcom,stub-regulator";
+		regulator-name = "8110_l10";
+		parent-supply = <&pm8110_s4>;
+		qcom,hpm-min-load = <10000>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		qcom,consumer-supplies = "vdd_sr2_pll", "";
+	};
+
+	pm8110_l12: regulator-l12 {
+		compatible = "qcom,stub-regulator";
+		regulator-name = "8110_l12";
+		qcom,hpm-min-load = <10000>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	pm8110_l14: regulator-l14 {
+		compatible = "qcom,stub-regulator";
+		regulator-name = "8110_l14";
+		parent-supply = <&pm8110_s4>;
+		qcom,hpm-min-load = <10000>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+	};
+
+	pm8110_l15: regulator-l15 {
+		compatible = "qcom,stub-regulator";
+		regulator-name = "8110_l15";
+		qcom,hpm-min-load = <10000>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	pm8110_l16: regulator-l16 {
+		compatible = "qcom,stub-regulator";
+		regulator-name = "8110_l16";
+		qcom,hpm-min-load = <10000>;
+		regulator-min-microvolt = <3000000>;
+		regulator-max-microvolt = <3000000>;
+	};
+
+	pm8110_l17: regulator-l17 {
+		compatible = "qcom,stub-regulator";
+		regulator-name = "8110_l17";
+		qcom,hpm-min-load = <10000>;
+		regulator-min-microvolt = <2900000>;
+		regulator-max-microvolt = <2900000>;
+	};
+
+	pm8110_l18: regulator-l18 {
+		compatible = "qcom,stub-regulator";
+		regulator-name = "8110_l18";
+		qcom,hpm-min-load = <10000>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <2950000>;
+	};
+
+	pm8110_l19: regulator-l19 {
+		compatible = "qcom,stub-regulator";
+		regulator-name = "8110_l19";
+		qcom,hpm-min-load = <10000>;
+		regulator-min-microvolt = <2850000>;
+		regulator-max-microvolt = <2850000>;
+	};
+
+	pm8110_l20: regulator-l20 {
+		compatible = "qcom,stub-regulator";
+		regulator-name = "8110_l20";
+		qcom,hpm-min-load = <5000>;
+		regulator-min-microvolt = <3075000>;
+		regulator-max-microvolt = <3075000>;
+	};
+
+	pm8110_l21: regulator-l21 {
+		compatible = "qcom,stub-regulator";
+		regulator-name = "8110_l21";
+		qcom,hpm-min-load = <10000>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <2950000>;
+	};
+
+	pm8110_l22: regulator-l22 {
+		compatible = "qcom,stub-regulator";
+		regulator-name = "8110_l22";
+		qcom,hpm-min-load = <10000>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+	};
+};
diff --git a/arch/arm/boot/dts/msm8610-rumi.dts b/arch/arm/boot/dts/msm8610-rumi.dts
new file mode 100644
index 0000000..a4507e3
--- /dev/null
+++ b/arch/arm/boot/dts/msm8610-rumi.dts
@@ -0,0 +1,29 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/include/ "msm8610.dtsi"
+
+/ {
+	model = "Qualcomm MSM 8610 Rumi";
+	compatible = "qcom,msm8610-rumi", "qcom,msm8610";
+	qcom,msm-id = <147 15 0>;
+
+	serial@f991f000 {
+		status = "ok";
+	};
+};
+
+&gfx_iommu {
+	status = "disabled";
+};
diff --git a/arch/arm/boot/dts/msm8610-sim.dts b/arch/arm/boot/dts/msm8610-sim.dts
new file mode 100644
index 0000000..2268daf
--- /dev/null
+++ b/arch/arm/boot/dts/msm8610-sim.dts
@@ -0,0 +1,25 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/include/ "msm8610.dtsi"
+
+/ {
+	model = "Qualcomm MSM 8610 Simulator";
+	compatible = "qcom,msm8610-sim", "qcom,msm8610";
+	qcom,msm-id = <147 16 0>;
+
+	serial@f991f000 {
+		status = "ok";
+	};
+};
diff --git a/arch/arm/boot/dts/msm8610.dtsi b/arch/arm/boot/dts/msm8610.dtsi
new file mode 100644
index 0000000..ce6011b
--- /dev/null
+++ b/arch/arm/boot/dts/msm8610.dtsi
@@ -0,0 +1,477 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/include/ "skeleton.dtsi"
+/include/ "msm-iommu-v0.dtsi"
+/include/ "msm8610-ion.dtsi"
+/include/ "msm-gdsc.dtsi"
+/include/ "msm8610-pm.dtsi"
+
+/ {
+	model = "Qualcomm MSM 8610";
+	compatible = "qcom,msm8610";
+	interrupt-parent = <&intc>;
+
+	intc: interrupt-controller@f9000000 {
+		compatible = "qcom,msm-qgic2";
+		interrupt-controller;
+		#interrupt-cells = <3>;
+		reg = <0xf9000000 0x1000>,
+		      <0xf9002000 0x1000>;
+	};
+
+	msmgpio: gpio@fd510000 {
+		compatible = "qcom,msm-gpio";
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		reg = <0xfd510000 0x4000>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		ngpio = <102>;
+		interrupts = <0 208 0>;
+		qcom,direct-connect-irqs = <8>;
+	};
+
+	aliases {
+		spi0 = &spi_0;
+	};
+
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupts = <1 2 0 1 3 0>;
+		clock-frequency = <19200000>;
+	};
+
+	qcom,msm-adsp-loader {
+		compatible = "qcom,adsp-loader";
+		qcom,adsp-state = <0>;
+	};
+
+	qcom,msm-imem@fe805000 {
+		compatible = "qcom,msm-imem";
+		reg = <0xfe805000 0x1000>; /* Address and size of IMEM */
+	};
+
+	serial@f991f000 {
+		compatible = "qcom,msm-lsuart-v14";
+		reg = <0xf991f000 0x1000>;
+		interrupts = <0 109 0>;
+		status = "disabled";
+	};
+
+	qcom,vidc@fdc00000 {
+		compatible = "qcom,msm-vidc";
+		hfi = "q6";
+	};
+
+	usb@f9a55000 {
+		compatible = "qcom,hsusb-otg";
+		reg = <0xf9a55000 0x400>;
+		interrupts = <0 134 0>, <0 140 0>;
+		interrupt-names = "core_irq", "async_irq";
+		HSUSB_VDDCX-supply = <&pm8110_s1>;
+		HSUSB_1p8-supply = <&pm8110_l10>;
+		HSUSB_3p3-supply = <&pm8110_l20>;
+
+		qcom,hsusb-otg-phy-type = <2>;
+		qcom,hsusb-otg-mode = <1>;
+		qcom,hsusb-otg-otg-control = <1>;
+		qcom,hsusb-otg-disable-reset;
+	};
+
+	android_usb@fe8050c8 {
+		compatible = "qcom,android-usb";
+		reg = <0xfe8050c8 0xc8>;
+	};
+
+	sdcc1: qcom,sdcc@f9824000 {
+		cell-index = <1>; /* SDC1 eMMC slot */
+		compatible = "qcom,msm-sdcc";
+		reg = <0xf9824000 0x800>,
+		      <0xf9824800 0x100>,
+		      <0xf9804000 0x7000>;
+		reg-names = "core_mem", "dml_mem", "bam_mem";
+		interrupts = <0 123 0>, <0 137 0>;
+		interrupt-names = "core_irq", "bam_irq";
+
+		vdd-supply = <&pm8110_l17>;
+		qcom,vdd-always-on;
+		qcom,vdd-lpm-sup;
+		qcom,vdd-voltage-level = <2900000 2900000>;
+		qcom,vdd-current-level = <9000 400000>;
+
+		vdd-io-supply = <&pm8110_l6>;
+		qcom,vdd-io-always-on;
+		qcom,vdd-io-lpm-sup;
+		qcom,vdd-io-voltage-level = <1800000 1800000>;
+		qcom,vdd-io-current-level = <9000 60000>;
+
+		qcom,pad-pull-on = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+		qcom,pad-pull-off = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+		qcom,pad-drv-on = <0x7 0x4 0x4>; /* 16mA, 10mA, 10mA */
+		qcom,pad-drv-off = <0x0 0x0 0x0>; /* 2mA, 2mA, 2mA */
+
+		qcom,clk-rates = <400000 25000000 50000000 100000000 200000000>;
+		qcom,sup-voltages = <2900 2900>;
+		qcom,bus-width = <8>;
+		qcom,nonremovable;
+		qcom,bus-speed-mode = "HS200_1p8v", "DDR_1p8v";
+	};
+
+	sdcc2: qcom,sdcc@f98a4000 {
+		cell-index = <2>; /* SDC2 SD card slot */
+		compatible = "qcom,msm-sdcc";
+		reg = <0xf98a4000 0x800>,
+		      <0xf98a4800 0x100>,
+		      <0xf9884000 0x7000>;
+		reg-names = "core_mem", "dml_mem", "bam_mem";
+		interrupts = <0 125 0>, <0 220 0>;
+		interrupt-names = "core_irq", "bam_irq";
+
+		vdd-supply = <&pm8110_l18>;
+		qcom,vdd-voltage-level = <2950000 2950000>;
+		qcom,vdd-current-level = <9000 400000>;
+
+		vdd-io-supply = <&pm8110_l21>;
+		qcom,vdd-io-voltage-level = <1800000 2950000>;
+		qcom,vdd-io-current-level = <9000 50000>;
+
+		qcom,pad-pull-on = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+		qcom,pad-pull-off = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+		qcom,pad-drv-on = <0x7 0x4 0x4>; /* 16mA, 10mA, 10mA */
+		qcom,pad-drv-off = <0x0 0x0 0x0>; /* 2mA, 2mA, 2mA */
+
+		qcom,clk-rates = <400000 25000000 50000000 100000000 200000000>;
+		qcom,sup-voltages = <2950 2950>;
+		qcom,bus-width = <4>;
+		qcom,xpc;
+		qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104";
+		qcom,current-limit = <800>;
+	};
+
+	qcom,sps {
+		compatible = "qcom,msm_sps";
+		qcom,device-type = <3>;
+	};
+
+	qcom,smem@d600000 {
+		compatible = "qcom,smem";
+		reg = <0xd600000 0x200000>,
+			<0xfa006000 0x1000>,
+			<0xfc428000 0x4000>;
+		reg-names = "smem", "irq-reg-base", "aux-mem1";
+
+		qcom,smd-modem {
+			compatible = "qcom,smd";
+			qcom,smd-edge = <0>;
+			qcom,smd-irq-offset = <0x8>;
+			qcom,smd-irq-bitmask = <0x1000>;
+			qcom,pil-string = "modem";
+			interrupts = <0 25 1>;
+		};
+
+		qcom,smsm-modem {
+			compatible = "qcom,smsm";
+			qcom,smsm-edge = <0>;
+			qcom,smsm-irq-offset = <0x8>;
+			qcom,smsm-irq-bitmask = <0x2000>;
+			interrupts = <0 26 1>;
+		};
+
+		qcom,smd-adsp {
+			compatible = "qcom,smd";
+			qcom,smd-edge = <1>;
+			qcom,smd-irq-offset = <0x8>;
+			qcom,smd-irq-bitmask = <0x100>;
+			qcom,pil-string = "adsp";
+			interrupts = <0 156 1>;
+		};
+
+		qcom,smsm-adsp {
+			compatible = "qcom,smsm";
+			qcom,smsm-edge = <1>;
+			qcom,smsm-irq-offset = <0x8>;
+			qcom,smsm-irq-bitmask = <0x200>;
+			interrupts = <0 157 1>;
+		};
+
+		qcom,smd-wcnss {
+			compatible = "qcom,smd";
+			qcom,smd-edge = <6>;
+			qcom,smd-irq-offset = <0x8>;
+			qcom,smd-irq-bitmask = <0x20000>;
+			qcom,pil-string = "wcnss";
+			interrupts = <0 142 1>;
+		};
+
+		qcom,smsm-wcnss {
+			compatible = "qcom,smsm";
+			qcom,smsm-edge = <6>;
+			qcom,smsm-irq-offset = <0x8>;
+			qcom,smsm-irq-bitmask = <0x80000>;
+			interrupts = <0 144 1>;
+		};
+
+		qcom,smd-rpm {
+			compatible = "qcom,smd";
+			qcom,smd-edge = <15>;
+			qcom,smd-irq-offset = <0x8>;
+			qcom,smd-irq-bitmask = <0x1>;
+			interrupts = <0 168 1>;
+			qcom,irq-no-suspend;
+		};
+	};
+
+	rpm_bus: qcom,rpm-smd {
+		compatible = "qcom,rpm-smd";
+		rpm-channel-name = "rpm_requests";
+		rpm-channel-type = <15>; /* SMD_APPS_RPM */
+		rpm-standalone;
+	};
+
+	qcom,msm-mem-hole {
+		compatible = "qcom,msm-mem-hole";
+		qcom,memblock-remove = <0x07C00000 0x6000000>; /* Address and Size of Hole */
+	};
+
+	qcom,wdt@f9017000 {
+		compatible = "qcom,msm-watchdog";
+		reg = <0xf9017000 0x1000>;
+		interrupts = <0 3 0>, <0 4 0>;
+		qcom,bark-time = <11000>;
+		qcom,pet-time = <10000>;
+		qcom,ipi-ping;
+	};
+
+	qcom,acpuclk@f9011050 {
+		compatible = "qcom,acpuclk-a7";
+		reg = <0xf9011050 0x8>;
+		reg-names = "rcg_base";
+		a7_cpu-supply = <&pm8110_s2>;
+		a7_mem-supply = <&pm8110_l3>;
+	};
+
+	spmi_bus: qcom,spmi@fc4c0000 {
+		cell-index = <0>;
+		compatible = "qcom,spmi-pmic-arb";
+		reg-names = "core", "intr", "cnfg";
+		reg = <0xfc4cf000 0x1000>,
+		      <0Xfc4cb000 0x1000>,
+		      <0Xfc4ca000 0x1000>;
+		/* 190,ee0_krait_hlos_spmi_periph_irq */
+		/* 187,channel_0_krait_hlos_trans_done_irq */
+		interrupts = <0 190 0>, <0 187 0>;
+		qcom,not-wakeup;
+		qcom,pmic-arb-ee = <0>;
+		qcom,pmic-arb-channel = <0>;
+	};
+
+	i2c@f9925000 { /* BLSP-1 QUP-3 */
+		cell-index = <0>;
+		compatible = "qcom,i2c-qup";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg-names = "qup_phys_addr";
+		reg = <0xf9925000 0x1000>;
+		interrupt-names = "qup_err_intr";
+		interrupts = <0 97 0>;
+		qcom,i2c-bus-freq = <100000>;
+	};
+
+
+	spi_0: spi@f9923000 { /* BLSP1 QUP1 */
+		compatible = "qcom,spi-qup-v2";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg-names = "spi_physical", "spi_bam_physical";
+		reg = <0xf9923000 0x1000>,
+		      <0xf9904000 0xF000>;
+		interrupt-names = "spi_irq", "spi_bam_irq";
+		interrupts = <0 95 0>, <0 238 0>;
+		spi-max-frequency = <19200000>;
+
+		gpios = <&msmgpio 3 0>, /* CLK  */
+			<&msmgpio 1 0>, /* MISO */
+			<&msmgpio 0 0>; /* MOSI */
+		cs-gpios = <&msmgpio 2 0>;
+
+		qcom,infinite-mode = <0>;
+		qcom,use-bam;
+		qcom,ver-reg-exists;
+		qcom,bam-consumer-pipe-index = <12>;
+		qcom,bam-producer-pipe-index = <13>;
+	};
+
+	qcom,pronto@fb21b000 {
+		compatible = "qcom,pil-pronto";
+		reg = <0xfb21b000 0x3000>,
+		      <0xfc401700 0x4>,
+		      <0xfd485300 0xc>;
+		reg-names = "pmu_base", "clk_base", "halt_base";
+		interrupts = <0 149 1>;
+		vdd_pronto_pll-supply = <&pm8110_l10>;
+
+		qcom,firmware-name = "wcnss";
+	};
+
+	sound {
+		compatible = "qcom,msm8x10-audio-codec";
+		qcom,model = "msm8x10-snd-card";
+	};
+
+	qcom,msm-pcm {
+		compatible = "qcom,msm-pcm-dsp";
+	};
+
+	qcom,msm-pcm-routing {
+		compatible = "qcom,msm-pcm-routing";
+	};
+
+	qcom,msm-pcm-lpa {
+		compatible = "qcom,msm-pcm-lpa";
+	};
+
+	qcom,msm-compr-dsp {
+		compatible = "qcom,msm-compr-dsp";
+	};
+
+	qcom,msm-voip-dsp {
+		compatible = "qcom,msm-voip-dsp";
+	};
+
+	qcom,msm-pcm-voice {
+		compatible = "qcom,msm-pcm-voice";
+	};
+
+	qcom,msm-stub-codec {
+		compatible = "qcom,msm-stub-codec";
+	};
+
+	qcom,msm-dai-fe {
+		compatible = "qcom,msm-dai-fe";
+	};
+
+	qcom,msm-pcm-afe {
+		compatible = "qcom,msm-pcm-afe";
+	};
+
+	qcom,msm-dai-mi2s {
+		compatible = "qcom,msm-dai-mi2s";
+		qcom,msm-dai-q6-mi2s-prim {
+			compatible = "qcom,msm-dai-q6-mi2s";
+			qcom,msm-dai-q6-mi2s-dev-id = <0>;
+			qcom,msm-mi2s-rx-lines = <1>;
+			qcom,msm-mi2s-tx-lines = <0>;
+		};
+
+		qcom,msm-dai-q6-mi2s-sec {
+			compatible = "qcom,msm-dai-q6-mi2s";
+			qcom,msm-dai-q6-mi2s-dev-id = <1>;
+			qcom,msm-mi2s-rx-lines = <0>;
+			qcom,msm-mi2s-tx-lines = <3>;
+		};
+	};
+
+	qcom,msm-dai-q6 {
+		compatible = "qcom,msm-dai-q6";
+		qcom,msm-dai-q6-bt-sco-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <12288>;
+		};
+
+		qcom,msm-dai-q6-bt-sco-tx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <12289>;
+		};
+
+		qcom,msm-dai-q6-int-fm-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <12292>;
+		};
+
+		qcom,msm-dai-q6-int-fm-tx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <12293>;
+		};
+
+		qcom,msm-dai-q6-be-afe-pcm-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <224>;
+		};
+
+		qcom,msm-dai-q6-be-afe-pcm-tx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <225>;
+		};
+
+		qcom,msm-dai-q6-afe-proxy-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <241>;
+		};
+
+		qcom,msm-dai-q6-afe-proxy-tx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <240>;
+		};
+	};
+
+	qcom,msm-pcm-hostless {
+		compatible = "qcom,msm-pcm-hostless";
+	};
+
+	qcom,lpass@fe200000 {
+		compatible = "qcom,pil-q6v5-lpass";
+		reg = <0xfe200000 0x00100>,
+		      <0xfd485100 0x00010>;
+		reg-names = "qdsp6_base", "halt_base";
+		interrupts = <0 162 1>;
+		vdd_cx-supply = <&pm8110_s1_corner>;
+		qcom,firmware-name = "adsp";
+	};
+};
+
+&gdsc_vfe {
+	status = "ok";
+};
+
+&gdsc_oxili_cx {
+	status = "ok";
+};
+
+&lpass_iommu {
+	status = "ok";
+};
+
+&copss_iommu {
+	status = "ok";
+};
+
+&mdpe_iommu {
+	status = "ok";
+};
+
+&mdps_iommu {
+	status = "ok";
+};
+
+&gfx_iommu {
+	status = "ok";
+};
+
+&vfe_iommu {
+	status = "ok";
+};
+
+/include/ "msm8610-iommu-domains.dtsi"
+
+/include/ "msm8610-regulator.dtsi"
+/include/ "msm-pm8110.dtsi"
diff --git a/arch/arm/boot/dts/msm8910-ion.dtsi b/arch/arm/boot/dts/msm8910-ion.dtsi
deleted file mode 100644
index 88bb1ab..0000000
--- a/arch/arm/boot/dts/msm8910-ion.dtsi
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-/ {
-	qcom,ion {
-		compatible = "qcom,msm-ion";
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		qcom,ion-heap@30 { /* SYSTEM HEAP */
-			reg = <30>;
-		};
-
-		qcom,ion-heap@8 { /* CP_MM HEAP */
-			compatible = "qcom,msm-ion-reserve";
-			reg = <8>;
-			qcom,heap-align = <0x1000>;
-			qcom,memory-reservation-type = "EBI1"; /* reserve EBI memory */
-			qcom,memory-reservation-size = <0x3800000>;
-		};
-
-		qcom,ion-heap@25 { /* IOMMU HEAP */
-			reg = <25>;
-		};
-
-		qcom,ion-heap@27 { /* QSECOM HEAP */
-			compatible = "qcom,msm-ion-reserve";
-			reg = <27>;
-			qcom,heap-align = <0x1000>;
-			qcom,memory-reservation-type = "EBI1"; /* reserve EBI memory */
-			qcom,memory-reservation-size = <0x780000>;
-		};
-
-		qcom,ion-heap@28 { /* AUDIO HEAP */
-			compatible = "qcom,msm-ion-reserve";
-			reg = <28>;
-			qcom,heap-align = <0x1000>;
-			qcom,memory-reservation-type = "EBI1"; /* reserve EBI memory */
-			qcom,memory-reservation-size = <0x314000>;
-		};
-
-		qcom,ion-heap@29 { /* FIRMWARE HEAP */
-			compatible = "qcom,msm-ion-reserve";
-			reg = <29>;
-			qcom,heap-align = <0x20000>;
-			qcom,heap-adjacent = <8>;
-			qcom,memory-reservation-type = "EBI1"; /* reserve EBI memory */
-			qcom,memory-reservation-size = <0xA00000>;
-		};
-
-	};
-};
-
diff --git a/arch/arm/boot/dts/msm8910-regulator.dtsi b/arch/arm/boot/dts/msm8910-regulator.dtsi
deleted file mode 100644
index a32d4ab..0000000
--- a/arch/arm/boot/dts/msm8910-regulator.dtsi
+++ /dev/null
@@ -1,218 +0,0 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
- /* Stub Regulators */
-
- / {
-	pm8110_s1: regulator-s1 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8110_s1";
-		qcom,hpm-min-load = <100000>;
-		regulator-min-microvolt = <1150000>;
-		regulator-max-microvolt = <1150000>;
-	};
-
-	pm8110_s2: regulator-s2 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8110_s2";
-		qcom,hpm-min-load = <100000>;
-		regulator-min-microvolt = <1050000>;
-		regulator-max-microvolt = <1050000>;
-	};
-
-	pm8110_s3: regulator-s3 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8110_s3";
-		qcom,hpm-min-load = <100000>;
-		regulator-min-microvolt = <1350000>;
-		regulator-max-microvolt = <1350000>;
-	};
-
-	pm8110_s4: regulator-s4 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8110_s4";
-		qcom,hpm-min-load = <100000>;
-		regulator-min-microvolt = <2150000>;
-		regulator-max-microvolt = <2150000>;
-	};
-
-	pm8110_l1: regulator-l1 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8110_l1";
-		parent-supply = <&pm8110_s3>;
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <1225000>;
-		regulator-max-microvolt = <1225000>;
-	};
-
-	pm8110_l2: regulator-l2 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8110_l2";
-		parent-supply = <&pm8110_s3>;
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <1200000>;
-		regulator-max-microvolt = <1200000>;
-	};
-
-	pm8110_l3: regulator-l3 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8110_l3";
-		parent-supply = <&pm8110_s3>;
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <1150000>;
-		regulator-max-microvolt = <1150000>;
-	};
-
-	pm8110_l4: regulator-l4 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8110_l4";
-		parent-supply = <&pm8110_s3>;
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <1200000>;
-		regulator-max-microvolt = <1200000>;
-	};
-
-	pm8110_l5: regulator-l5 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8110_l5";
-		parent-supply = <&pm8110_s3>;
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <1300000>;
-		regulator-max-microvolt = <1300000>;
-	};
-
-	pm8110_l6: regulator-l6 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8110_l6";
-		parent-supply = <&pm8110_s4>;
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <1800000>;
-	};
-
-	pm8110_l7: regulator-l7 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8110_l7";
-		parent-supply = <&pm8110_s4>;
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <2050000>;
-		regulator-max-microvolt = <2050000>;
-	};
-
-	pm8110_l8: regulator-l8 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8110_l8";
-		parent-supply = <&pm8110_s4>;
-		qcom,hpm-min-load = <5000>;
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <1800000>;
-	};
-
-	pm8110_l9: regulator-l9 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8110_l9";
-		parent-supply = <&pm8110_s4>;
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <2050000>;
-		regulator-max-microvolt = <2050000>;
-	};
-
-	pm8110_l10: regulator-l10 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8110_l10";
-		parent-supply = <&pm8110_s4>;
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <1800000>;
-	};
-
-	pm8110_l12: regulator-l12 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8110_l12";
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <3300000>;
-	};
-
-	pm8110_l14: regulator-l14 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8110_l14";
-		parent-supply = <&pm8110_s4>;
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <1800000>;
-	};
-
-	pm8110_l15: regulator-l15 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8110_l15";
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <3300000>;
-	};
-
-	pm8110_l16: regulator-l16 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8110_l16";
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <3000000>;
-		regulator-max-microvolt = <3000000>;
-	};
-
-	pm8110_l17: regulator-l17 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8110_l17";
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <2900000>;
-		regulator-max-microvolt = <2900000>;
-	};
-
-	pm8110_l18: regulator-l18 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8110_l18";
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <2950000>;
-	};
-
-	pm8110_l19: regulator-l19 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8110_l19";
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <2850000>;
-		regulator-max-microvolt = <2850000>;
-	};
-
-	pm8110_l20: regulator-l20 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8110_l20";
-		qcom,hpm-min-load = <5000>;
-		regulator-min-microvolt = <3075000>;
-		regulator-max-microvolt = <3075000>;
-	};
-
-	pm8110_l21: regulator-l21 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8110_l21";
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <2950000>;
-	};
-
-	pm8110_l22: regulator-l22 {
-		compatible = "qcom,stub-regulator";
-		regulator-name = "8110_l22";
-		qcom,hpm-min-load = <10000>;
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <3300000>;
-	};
-};
diff --git a/arch/arm/boot/dts/msm8910-rumi.dts b/arch/arm/boot/dts/msm8910-rumi.dts
deleted file mode 100644
index 0d944aa..0000000
--- a/arch/arm/boot/dts/msm8910-rumi.dts
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-/dts-v1/;
-
-/include/ "msm8910.dtsi"
-
-/ {
-	model = "Qualcomm MSM 8910 Rumi";
-	compatible = "qcom,msm8910-rumi", "qcom,msm8910";
-	qcom,msm-id = <147 1 0>;
-
-	serial@f991f000 {
-		status = "ok";
-	};
-};
diff --git a/arch/arm/boot/dts/msm8910-sim.dts b/arch/arm/boot/dts/msm8910-sim.dts
deleted file mode 100644
index aae88b1..0000000
--- a/arch/arm/boot/dts/msm8910-sim.dts
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-/dts-v1/;
-
-/include/ "msm8910.dtsi"
-
-/ {
-	model = "Qualcomm MSM 8910 Simulator";
-	compatible = "qcom,msm8910-sim", "qcom,msm8910";
-	qcom,msm-id = <147 1 0>;
-
-	serial@f991f000 {
-		status = "ok";
-	};
-};
diff --git a/arch/arm/boot/dts/msm8910.dtsi b/arch/arm/boot/dts/msm8910.dtsi
deleted file mode 100644
index 8ad4eda..0000000
--- a/arch/arm/boot/dts/msm8910.dtsi
+++ /dev/null
@@ -1,344 +0,0 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-/include/ "skeleton.dtsi"
-/include/ "msm-iommu-v1.dtsi"
-/include/ "msm8910-ion.dtsi"
-/include/ "msm-gdsc.dtsi"
-
-/ {
-	model = "Qualcomm MSM 8910";
-	compatible = "qcom,msm8910";
-	interrupt-parent = <&intc>;
-
-	intc: interrupt-controller@f9000000 {
-		compatible = "qcom,msm-qgic2";
-		interrupt-controller;
-		#interrupt-cells = <3>;
-		reg = <0xf9000000 0x1000>,
-		      <0xf9002000 0x1000>;
-	};
-
-	msmgpio: gpio@fd510000 {
-		compatible = "qcom,msm-gpio";
-		interrupt-controller;
-		#interrupt-cells = <2>;
-		reg = <0xfd510000 0x4000>;
-		gpio-controller;
-		#gpio-cells = <2>;
-		interrupts = <0 208 0>;
-	};
-
-	timer {
-		compatible = "arm,armv7-timer";
-		interrupts = <1 2 0 1 3 0>;
-		clock-frequency = <19200000>;
-	};
-
-	serial@f991f000 {
-		compatible = "qcom,msm-lsuart-v14";
-		reg = <0xf991f000 0x1000>;
-		interrupts = <0 109 0>;
-		status = "disabled";
-	};
-
-	usb@f9a55000 {
-		compatible = "qcom,hsusb-otg";
-		reg = <0xf9a55000 0x400>;
-		interrupts = <0 134 0>;
-		interrupt-names = "core_irq";
-		HSUSB_VDDCX-supply = <&pm8110_s1>;
-		HSUSB_1p8-supply = <&pm8110_l10>;
-		HSUSB_3p3-supply = <&pm8110_l20>;
-
-		qcom,hsusb-otg-phy-type = <2>;
-		qcom,hsusb-otg-mode = <1>;
-		qcom,hsusb-otg-otg-control = <1>;
-		qcom,hsusb-otg-disable-reset;
-	};
-
-	android_usb {
-		compatible = "qcom,android-usb";
-	};
-
-	sdcc1: qcom,sdcc@f9824000 {
-		cell-index = <1>; /* SDC1 eMMC slot */
-		compatible = "qcom,msm-sdcc";
-		reg = <0xf9824000 0x800>,
-		      <0xf9824800 0x100>,
-		      <0xf9804000 0x7000>;
-		reg-names = "core_mem", "dml_mem", "bam_mem";
-		interrupts = <0 123 0>, <0 137 0>;
-		interrupt-names = "core_irq", "bam_irq";
-
-		vdd-supply = <&pm8110_l17>;
-		qcom,vdd-always-on;
-		qcom,vdd-lpm-sup;
-		qcom,vdd-voltage-level = <2900000 2900000>;
-		qcom,vdd-current-level = <9000 400000>;
-
-		vdd-io-supply = <&pm8110_l6>;
-		qcom,vdd-io-always-on;
-		qcom,vdd-io-lpm-sup;
-		qcom,vdd-io-voltage-level = <1800000 1800000>;
-		qcom,vdd-io-current-level = <9000 60000>;
-
-		qcom,pad-pull-on = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
-		qcom,pad-pull-off = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
-		qcom,pad-drv-on = <0x7 0x4 0x4>; /* 16mA, 10mA, 10mA */
-		qcom,pad-drv-off = <0x0 0x0 0x0>; /* 2mA, 2mA, 2mA */
-
-		qcom,clk-rates = <400000 25000000 50000000 100000000 200000000>;
-		qcom,sup-voltages = <2900 2900>;
-		qcom,bus-width = <8>;
-		qcom,nonremovable;
-		qcom,bus-speed-mode = "HS200_1p8v", "DDR_1p8v";
-	};
-
-	sdcc2: qcom,sdcc@f98a4000 {
-		cell-index = <2>; /* SDC2 SD card slot */
-		compatible = "qcom,msm-sdcc";
-		reg = <0xf98a4000 0x800>,
-		      <0xf98a4800 0x100>,
-		      <0xf9884000 0x7000>;
-		reg-names = "core_mem", "dml_mem", "bam_mem";
-		interrupts = <0 125 0>, <0 220 0>;
-		interrupt-names = "core_irq", "bam_irq";
-
-		vdd-supply = <&pm8110_l18>;
-		qcom,vdd-voltage-level = <2950000 2950000>;
-		qcom,vdd-current-level = <9000 400000>;
-
-		vdd-io-supply = <&pm8110_l21>;
-		qcom,vdd-io-voltage-level = <1800000 2950000>;
-		qcom,vdd-io-current-level = <9000 50000>;
-
-		qcom,pad-pull-on = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
-		qcom,pad-pull-off = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
-		qcom,pad-drv-on = <0x7 0x4 0x4>; /* 16mA, 10mA, 10mA */
-		qcom,pad-drv-off = <0x0 0x0 0x0>; /* 2mA, 2mA, 2mA */
-
-		qcom,clk-rates = <400000 25000000 50000000 100000000 200000000>;
-		qcom,sup-voltages = <2950 2950>;
-		qcom,bus-width = <4>;
-		qcom,xpc;
-		qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104";
-		qcom,current-limit = <800>;
-	};
-
-	qcom,sps {
-		compatible = "qcom,msm_sps";
-		qcom,device-type = <3>;
-	};
-
-	qcom,smem@d600000 {
-		compatible = "qcom,smem";
-		reg = <0xd600000 0x200000>,
-			<0xfa006000 0x1000>,
-			<0xfc428000 0x4000>;
-		reg-names = "smem", "irq-reg-base", "aux-mem1";
-
-		qcom,smd-modem {
-			compatible = "qcom,smd";
-			qcom,smd-edge = <0>;
-			qcom,smd-irq-offset = <0x8>;
-			qcom,smd-irq-bitmask = <0x1000>;
-			qcom,pil-string = "modem";
-			interrupts = <0 25 1>;
-		};
-
-		qcom,smsm-modem {
-			compatible = "qcom,smsm";
-			qcom,smsm-edge = <0>;
-			qcom,smsm-irq-offset = <0x8>;
-			qcom,smsm-irq-bitmask = <0x2000>;
-			interrupts = <0 26 1>;
-		};
-
-		qcom,smd-adsp {
-			compatible = "qcom,smd";
-			qcom,smd-edge = <1>;
-			qcom,smd-irq-offset = <0x8>;
-			qcom,smd-irq-bitmask = <0x100>;
-			qcom,pil-string = "adsp";
-			interrupts = <0 156 1>;
-		};
-
-		qcom,smsm-adsp {
-			compatible = "qcom,smsm";
-			qcom,smsm-edge = <1>;
-			qcom,smsm-irq-offset = <0x8>;
-			qcom,smsm-irq-bitmask = <0x200>;
-			interrupts = <0 157 1>;
-		};
-
-		qcom,smd-wcnss {
-			compatible = "qcom,smd";
-			qcom,smd-edge = <6>;
-			qcom,smd-irq-offset = <0x8>;
-			qcom,smd-irq-bitmask = <0x20000>;
-			qcom,pil-string = "wcnss";
-			interrupts = <0 142 1>;
-		};
-
-		qcom,smsm-wcnss {
-			compatible = "qcom,smsm";
-			qcom,smsm-edge = <6>;
-			qcom,smsm-irq-offset = <0x8>;
-			qcom,smsm-irq-bitmask = <0x80000>;
-			interrupts = <0 144 1>;
-		};
-
-		qcom,smd-rpm {
-			compatible = "qcom,smd";
-			qcom,smd-edge = <15>;
-			qcom,smd-irq-offset = <0x8>;
-			qcom,smd-irq-bitmask = <0x1>;
-			interrupts = <0 168 1>;
-			qcom,irq-no-suspend;
-		};
-	};
-
-	qcom,wdt@f9017000 {
-		compatible = "qcom,msm-watchdog";
-		reg = <0xf9017000 0x1000>;
-		interrupts = <0 3 0>, <0 4 0>;
-		qcom,bark-time = <11000>;
-		qcom,pet-time = <10000>;
-		qcom,ipi-ping = <1>;
-	};
-
-	spmi_bus: qcom,spmi@fc4c0000 {
-		cell-index = <0>;
-		compatible = "qcom,spmi-pmic-arb";
-		reg = <0xfc4cf000 0x1000>,
-		      <0Xfc4cb000 0x1000>;
-		/* 190,ee0_krait_hlos_spmi_periph_irq */
-		/* 187,channel_0_krait_hlos_trans_done_irq */
-		interrupts = <0 190 0>, <0 187 0>;
-		qcom,not-wakeup;
-		qcom,pmic-arb-ee = <0>;
-		qcom,pmic-arb-channel = <0>;
-		qcom,pmic-arb-ppid-map = <0x001000a0>, /* PM8110 */
-					 <0x005000a2>, /* INTERRUPT */
-					 <0x006000a3>, /* SPMI_0 */
-					 <0x00800000>, /* PON0 */
-					 <0x01000002>, /* SMBB_CHG */
-					 <0x01100003>, /* SMBB_BUCK */
-					 <0x01200004>, /* SMBB_BIF */
-					 <0x01300005>, /* SMBB_USB */
-					 <0x01500006>, /* SMBB_BOOST */
-					 <0x01600007>, /* SMBB_MISC */
-					 <0x0280000a>, /* COINCELL */
-					 <0x02c000a5>, /* MBG */
-					 <0x0310000b>, /* VADC1_LC_USR */
-					 <0x03200041>, /* VADC3_LC_MDM */
-					 <0x0330000c>, /* VADC3_LC_BMS */
-					 <0x0340000d>, /* VADC2_LC_BTM */
-					 <0x0360000e>, /* IADC1_USR */
-					 <0x03700042>, /* IADC2_MDM */
-					 <0x0380000f>, /* IADC2_BMS */
-					 <0x04000010>, /* BMS_1 */
-					 <0x050000a6>, /* SHARED_XO */
-					 <0x051000a7>, /* BB_CLK1 */
-					 <0x054000a8>, /* RF_CLK1 */
-					 <0x055000a9>, /* RF_CLK1 */
-					 <0x05a000ab>, /* SLEEP_CLK */
-					 <0x06000043>, /* RTC_RW */
-					 <0x06100011>, /* RTC_ALARM */
-					 <0x070000ac>, /* PBS_CORE */
-					 <0x071000ad>, /* PBS_CLIENT_1 */
-					 <0x072000ae>, /* PBS_CLIENT_2 */
-					 <0x07300013>, /* PBS_CLIENT_3 */
-					 <0x07400044>, /* PBS_CLIENT_4 */
-					 <0x0a000014>, /* MPP_1 */
-					 <0x0a100015>, /* MPP_2 */
-					 <0x0a200016>, /* MPP_3 */
-					 <0x0a300045>, /* MPP_4 */
-					 <0x0c000046>, /* GPIO_1 */
-					 <0x0c1000f0>, /* GPIO_2 */
-					 <0x0c2000af>, /* GPIO_3 */
-					 <0x0c300047>, /* GPIO_4 */
-					 <0x0fe000b0>, /* TRIM_0 */
-					 <0x110000b1>, /* BUCK_CMN_1 */
-					 <0x11400048>, /* SMPS1 */
-					 <0x115000b2>, /* SMPS_1_PS1 */
-					 <0x116000b3>, /* BUCK_FREQ_1 */
-					 <0x11700017>, /* SMPS2 */
-					 <0x11800018>, /* FTPS1_2 */
-					 <0x11900019>, /* BUCK_FREQ_2 */
-					 <0x11a000b4>, /* SMPS3 */
-					 <0x11b000b5>, /* SMPS_3_PS1 */
-					 <0x11c000b6>, /* BUCK_FREQ_3 */
-					 <0x11d000b7>, /* SMPS4 */
-					 <0x11e000b8>, /* SMPS_4_PS1 */
-					 <0x11f000b9>, /* BUCK_FREQ_4 */
-					 <0x140000ba>, /* LDO_1 */
-					 <0x141000bb>, /* LDO_2 */
-					 <0x142000bc>, /* LDO_3 */
-					 <0x143000bd>, /* LDO_4 */
-					 <0x144000be>, /* LDO_5 */
-					 <0x145000bf>, /* LDO_6 */
-					 <0x146000c0>, /* LDO_7 */
-					 <0x147000c1>, /* LDO_8 */
-					 <0x148000c2>, /* LDO_9 */
-					 <0x149000c3>, /* LDO_10 */
-					 <0x14a000c4>, /* LDO_11 */
-					 <0x14b000c5>, /* LDO_12 */
-					 <0x14c000c6>, /* LDO_13 */
-					 <0x14d000c7>, /* LDO_14 */
-					 <0x14e000c8>, /* LDO_15 */
-					 <0x14f000c9>, /* LDO_16 */
-					 <0x150000ca>, /* LDO_17 */
-					 <0x151000cb>, /* LDO_18 */
-					 <0x152000cc>, /* LDO_19 */
-					 <0x153000cd>, /* LDO_20 */
-					 <0x154000ce>, /* LDO_21 */
-					 <0x155000cf>; /* LDO_22 */
-	};
-
-};
-
-&gdsc_vfe {
-	status = "ok";
-};
-
-&gdsc_oxili_cx {
-	status = "ok";
-};
-
-&lpass_iommu {
-	status = "ok";
-};
-
-&copss_iommu {
-	status = "ok";
-};
-
-&mdpe_iommu {
-	status = "ok";
-};
-
-&mdps_iommu {
-	status = "ok";
-};
-
-&gfx_iommu {
-	status = "ok";
-};
-
-&vfe_iommu {
-	status = "ok";
-};
-
-/include/ "msm8910-regulator.dtsi"
-/include/ "msm-pm8110.dtsi"
diff --git a/arch/arm/boot/dts/msm8974-bus.dtsi b/arch/arm/boot/dts/msm8974-bus.dtsi
new file mode 100644
index 0000000..ba4a14e8
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974-bus.dtsi
@@ -0,0 +1,1403 @@
+/* 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.
+ */
+
+/ {
+	msm-mmss-noc@fc478000 {
+		compatible = "msm-bus-fabric";
+		reg = <0xfc478000 0x00004000>;
+		cell-id = <2048>;
+		label = "msm_mmss_noc";
+		qcom,fabclk-dual = "bus_clk";
+		qcom,fabclk-active = "bus_a_clk";
+		qcom,ntieredslaves = <0>;
+		qcom,qos-freq = <4800>;
+		qcom,hw-sel = "NoC";
+		qcom,rpm-en;
+
+		coresight-id = <52>;
+		coresight-name = "coresight-mnoc";
+		coresight-nr-inports = <0>;
+		coresight-outports = <0>;
+		coresight-child-list = <&funnel_in0>;
+		coresight-child-ports = <5>;
+
+		mas-gfx3d {
+			cell-id = <26>;
+			label = "mas-gfx3d";
+			qcom,masterp = <2 3>;
+			qcom,tier = <2>;
+			qcom,hw-sel = "NoC";
+			qcom,perm-mode = "Bypass";
+			qcom,mode = "Bypass";
+			qcom,ws = <10000>;
+			qcom,qport = <2 3>;
+			qcom,mas-hw-id = <6>;
+		};
+
+		mas-jpeg {
+			cell-id = <62>;
+			label = "mas-jpeg";
+			qcom,masterp = <4>;
+			qcom,tier = <2>;
+			qcom,hw-sel = "NoC";
+			qcom,perm-mode = "Bypass";
+			qcom,mode = "Bypass";
+			qcom,qport = <0>;
+			qcom,ws = <10000>;
+			qcom,mas-hw-id = <7>;
+		};
+
+		mas-mdp-port0 {
+			cell-id = <22>;
+			label = "mas-mdp-port0";
+			qcom,masterp = <5>;
+			qcom,tier = <2>;
+			qcom,hw-sel = "NoC";
+			qcom,perm-mode = "Bypass";
+			qcom,mode = "Bypass";
+			qcom,qport = <1>;
+			qcom,ws = <10000>;
+			qcom,mas-hw-id = <8>;
+		};
+
+		mas-video-p0 {
+			cell-id = <63>;
+			label = "mas-video-p0";
+			qcom,masterp = <6 7>;
+			qcom,tier = <2>;
+			qcom,hw-sel = "NoC";
+			qcom,perm-mode = "Bypass";
+			qcom,mode = "Bypass";
+			qcom,ws = <10000>;
+			qcom,qport = <4 5>;
+			qcom,mas-hw-id = <9>;
+		};
+
+		mas-vfe {
+			cell-id = <29>;
+			label = "mas-vfe";
+			qcom,masterp = <16>;
+			qcom,tier = <2>;
+			qcom,hw-sel = "NoC";
+			qcom,perm-mode = "Bypass";
+			qcom,mode = "Bypass";
+			qcom,ws = <10000>;
+			qcom,qport = <6>;
+			qcom,mas-hw-id = <11>;
+		};
+
+		fab-cnoc {
+			cell-id = <5120>;
+			label = "fab-cnoc";
+			qcom,gateway;
+			qcom,masterp = <0 1>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "RPM";
+			qcom,mas-hw-id = <4>;
+		};
+
+		fab-bimc {
+			cell-id = <0>;
+			label = "fab-bimc";
+			qcom,gateway;
+			qcom,slavep = <16 17>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <16>;
+		};
+
+		slv-camera-cfg {
+			cell-id = <589>;
+			label = "slv-camera-cfg";
+			qcom,slavep = <0>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <3>;
+		};
+
+		slv-display-cfg {
+			cell-id = <590>;
+			label = "slv-display-cfg";
+			qcom,slavep = <1>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <4>;
+		};
+
+		slv-ocmem-cfg {
+			cell-id = <591>;
+			label = "slv-ocmem-cfg";
+			qcom,slavep = <2>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <5>;
+		};
+
+		slv-cpr-cfg {
+			cell-id = <592>;
+			label = "slv-cpr-cfg";
+			qcom,slavep = <3>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <6>;
+		};
+
+		slv-cpr-xpu-cfg {
+			cell-id = <593>;
+			label = "slv-cpr-xpu-cfg";
+			qcom,slavep = <4>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <7>;
+		};
+
+		slv-misc-cfg {
+			cell-id = <594>;
+			label = "slv-misc-cfg";
+			qcom,slavep = <6>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <8>;
+		};
+
+		slv-misc-xpu-cfg {
+			cell-id = <595>;
+			label = "slv-misc-xpu-cfg";
+			qcom,slavep = <7>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <9>;
+		};
+
+		slv-venus-cfg {
+			cell-id = <596>;
+			label = "slv-venus-cfg";
+			qcom,slavep = <8>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <10>;
+		};
+
+		slv-gfx3d-cfg {
+			cell-id = <598>;
+			label = "slv-gfx3d-cfg";
+			qcom,slavep = <9>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <11>;
+		};
+
+		slv-mmss-clk-cfg {
+			cell-id = <599>;
+			label = "slv-mmss-clk-cfg";
+			qcom,slavep = <11>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <12>;
+		};
+
+		slv-mmss-clk-xpu-cfg {
+			cell-id = <600>;
+			label = "slv-mmss-clk-xpu-cfg";
+			qcom,slavep = <12>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <13>;
+		};
+
+		slv-mnoc-mpu-cfg {
+			cell-id = <601>;
+			label = "slv-mnoc-mpu-cfg";
+			qcom,slavep = <13>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <14>;
+		};
+
+		slv-onoc-mpu-cfg {
+			cell-id = <602>;
+			label = "slv-onoc-mpu-cfg";
+			qcom,slavep = <14>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <15>;
+		};
+
+		slv-service-mnoc {
+			cell-id = <603>;
+			label = "slv-service-mnoc";
+			qcom,slavep = <18>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,hw-sel = "NoC";
+			qcom,slv-hw-id = <17>;
+		};
+
+	};
+
+	msm-sys-noc@fc460000 {
+		compatible = "msm-bus-fabric";
+		reg = <0xfc460000 0x00004000>;
+		cell-id = <1024>;
+		label = "msm_sys_noc";
+		qcom,fabclk-dual = "bus_clk";
+		qcom,fabclk-active = "bus_a_clk";
+		qcom,ntieredslaves = <0>;
+		qcom,qos-freq = <4800>;
+		qcom,hw-sel = "NoC";
+		qcom,rpm-en;
+
+		coresight-id = <50>;
+		coresight-name = "coresight-snoc";
+		coresight-nr-inports = <0>;
+		coresight-outports = <0>;
+		coresight-child-list = <&funnel_in0>;
+		coresight-child-ports = <3>;
+
+		msm-lpass-ahb {
+			cell-id = <52>;
+			label = "mas-lpass-ahb";
+			qcom,masterp = <0>;
+			qcom,tier = <2>;
+			qcom,qport = <0>;
+			qcom,mas-hw-id = <18>;
+			qcom,mode = "Fixed";
+			qcom,prio-rd = <2>;
+			qcom,prio-wr = <2>;
+		};
+
+		mas-qdss-bam {
+			cell-id = <53>;
+			label = "mas-qdss-bam";
+			qcom,masterp = <1>;
+			qcom,tier = <2>;
+			qcom,mode = "Fixed";
+			qcom,qport = <1>;
+			qcom,mas-hw-id = <19>;
+		};
+
+		mas-snoc-cfg {
+			cell-id = <54>;
+			label = "mas-snoc-cfg";
+			qcom,masterp = <2>;
+			qcom,tier = <2>;
+			qcom,mas-hw-id = <20>;
+		};
+
+		fab-bimc {
+			cell-id = <0>;
+			label= "fab-bimc";
+			qcom,gateway;
+			qcom,slavep = <7 8>;
+			qcom,masterp = <3>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <21>;
+			qcom,slv-hw-id = <24>;
+		};
+
+		fab-cnoc {
+			cell-id = <5120>;
+			label = "fab-cnoc";
+			qcom,gateway;
+			qcom,slavep = <9>;
+			qcom,masterp = <4>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <22>;
+			qcom,slv-hw-id = <25>;
+		};
+
+		fab-pnoc {
+			cell-id = <4096>;
+			label = "fab-pnoc";
+			qcom,gateway;
+			qcom,slavep = <12>;
+			qcom,masterp = <11>;
+			qcom,buswidth = <8>;
+			qcom,qport = <8>;
+			qcom,mas-hw-id = <29>;
+			qcom,slv-hw-id = <28>;
+			qcom,mode = "Fixed";
+			qcom,prio-rd = <2>;
+			qcom,prio-wr = <2>;
+		};
+
+		fab-ovnoc {
+			cell-id = <6144>;
+			label = "fab-ovnoc";
+			qcom,gateway;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <53>;
+			qcom,slv-hw-id = <77>;
+		};
+
+		mas-crypto-core0 {
+			cell-id = <55>;
+			label = "mas-crypto-core0";
+			qcom,masterp = <5>;
+			qcom,tier = <2>;
+			qcom,mode = "Fixed";
+			qcom,qport = <2>;
+			qcom,mas-hw-id = <23>;
+			qcom,hw-sel = "NoC";
+			qcom,prio-rd = <1>;
+			qcom,prio-wr = <1>;
+		};
+
+		mas-crypto-core1 {
+			cell-id = <56>;
+			label = "mas-crypto-core1";
+			qcom,masterp = <6>;
+			qcom,tier = <2>;
+			qcom,mode = "Fixed";
+			qcom,qport = <3>;
+			qcom,mas-hw-id = <24>;
+			qcom,hw-sel = "NoC";
+			qcom,prio-rd = <1>;
+			qcom,prio-wr = <1>;
+		};
+
+		mas-lpass-proc {
+			cell-id = <11>;
+			label = "mas-lpass-proc";
+			qcom,masterp = <7>;
+			qcom,tier = <2>;
+			qcom,qport = <4>;
+			qcom,mas-hw-id = <25>;
+			qcom,mode = "Fixed";
+			qcom,prio-rd = <2>;
+			qcom,prio-wr = <2>;
+		};
+
+		mas-mss {
+			cell-id = <38>;
+			label = "mas-mss";
+			qcom,masterp = <8>;
+			qcom,tier = <2>;
+			qcom,mas-hw-id = <26>;
+		};
+
+		mas-mss-nav {
+			cell-id = <57>;
+			label = "mas-mss-nav";
+			qcom,masterp = <9>;
+			qcom,tier = <2>;
+			qcom,mas-hw-id = <27>;
+		};
+
+		mas-ocmem-dma {
+			cell-id = <58>;
+			label = "mas-ocmem-dma";
+			qcom,masterp = <10>;
+			qcom,tier = <2>;
+			qcom,mode = "Fixed";
+			qcom,qport = <7>;
+			qcom,mas-hw-id = <28>;
+		};
+
+		mas-wcss {
+			cell-id = <59>;
+			label = "mas-wcss";
+			qcom,masterp = <12>;
+			qcom,tier = <2>;
+			qcom,mas-hw-id = <30>;
+		};
+
+		mas-qdss-etr {
+			cell-id = <60>;
+			label = "mas-qdss-etr";
+			qcom,masterp = <13>;
+			qcom,tier = <2>;
+			qcom,qport = <10>;
+			qcom,mode = "Fixed";
+			qcom,mas-hw-id = <31>;
+		};
+
+		mas-usb3 {
+			cell-id = <61>;
+			label = "mas-usb3";
+			qcom,masterp = <14>;
+			qcom,tier = <2>;
+			qcom,mode = "Fixed";
+			qcom,qport = <11>;
+			qcom,mas-hw-id = <32>;
+			qcom,prio-rd = <2>;
+			qcom,prio-wr = <2>;
+			qcom,hw-sel = "NoC";
+			qcom,iface-clk-node = "msm_usb3";
+		};
+
+		slv-ampss {
+			cell-id = <520>;
+			label = "slv-ampss";
+			qcom,slavep = <1>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <20>;
+		};
+
+		slv-lpass {
+			cell-id = <522>;
+			label = "slv-lpass";
+			qcom,slavep = <2>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <21>;
+		};
+
+		slv-usb3 {
+			cell-id = <583>;
+			label = "slv-usb3";
+			qcom,slavep = <4>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <22>;
+		};
+
+		slv-wcss {
+			cell-id = <584>;
+			label = "slv-wcss";
+			qcom,slavep = <6>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <23>;
+		};
+
+		slv-ocimem {
+			cell-id = <585>;
+			label = "slv-ocimem";
+			qcom,slavep = <10>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <26>;
+		};
+
+		slv-snoc-ocmem {
+			cell-id = <586>;
+			label = "slv-snoc-ocmem";
+			qcom,slavep = <11>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <27>;
+		};
+
+		slv-service-snoc {
+			cell-id = <587>;
+			label = "slv-service-snoc";
+			qcom,slavep = <13>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <29>;
+		};
+
+		slv-qdss-stm {
+			cell-id = <588>;
+			label = "slv-qdss-stm";
+			qcom,slavep = <14>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <30>;
+		};
+
+	};
+
+	msm-periph-noc@fc468000 {
+		compatible = "msm-bus-fabric";
+		reg = <0xfc468000 0x00004000>;
+		cell-id = <4096>;
+		label = "msm_periph_noc";
+		qcom,fabclk-dual = "bus_clk";
+		qcom,fabclk-active = "bus_a_clk";
+		qcom,ntieredslaves = <0>;
+		qcom,hw-sel = "NoC";
+		qcom,rpm-en;
+
+		coresight-id = <54>;
+		coresight-name = "coresight-pnoc";
+		coresight-nr-inports = <0>;
+		coresight-outports = <0>;
+		coresight-child-list = <&funnel_in0>;
+		coresight-child-ports = <6>;
+
+		mas-pnoc-cfg {
+			cell-id = <88>;
+			label = "mas-pnoc-cfg";
+			qcom,masterp = <10>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <43>;
+		};
+
+		mas-sdcc-1 {
+			cell-id = <78>;
+			label = "mas-sdcc-1";
+			qcom,masterp = <0>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <33>;
+		};
+
+		mas-sdcc-3 {
+			cell-id = <79>;
+			label = "mas-sdcc-3";
+			qcom,masterp = <1>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <34>;
+		};
+
+		mas-sdcc-4 {
+			cell-id = <80>;
+			label = "mas-sdcc-4";
+			qcom,masterp = <3>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <36>;
+		};
+
+		mas-sdcc-2 {
+			cell-id = <81>;
+			label = "mas-sdcc-2";
+			qcom,masterp = <2>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <35>;
+		};
+
+		mas-tsif {
+			cell-id = <82>;
+			label = "mas-tsif";
+			qcom,masterp = <4>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <37>;
+		};
+
+		mas-bam-dma {
+			cell-id = <83>;
+			label = "mas-bam-dma";
+			qcom,masterp = <5>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <38>;
+		};
+
+		mas-blsp-2 {
+			cell-id = <84>;
+			label = "mas-blsp-2";
+			qcom,masterp = <6>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <39>;
+		};
+
+		mas-usb-hsic {
+			cell-id = <85>;
+			label = "mas-usb-hsic";
+			qcom,masterp = <7>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <40>;
+		};
+
+		mas-blsp-1 {
+			cell-id = <86>;
+			label = "mas-blsp-1";
+			qcom,masterp = <8>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <41>;
+		};
+
+		mas-usb-hs {
+			cell-id = <87>;
+			label = "mas-usb-hs";
+			qcom,masterp = <9>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <42>;
+		};
+
+		fab-snoc {
+			cell-id = <1024>;
+			label = "fab-snoc";
+			qcom,gateway;
+			qcom,slavep = <14>;
+			qcom,masterp = <11>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <45>;
+			qcom,mas-hw-id = <44>;
+		};
+
+		slv-sdcc-1 {
+			cell-id = <606>;
+			label = "slv-sdcc-1";
+			qcom,slavep = <0>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <31>;
+		};
+
+		slv-sdcc-3 {
+			cell-id = <607>;
+			label = "slv-sdcc-3";
+			qcom,slavep = <1>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <32>;
+		};
+
+		slv-sdcc-2 {
+			cell-id = <608>;
+			label = "slv-sdcc-2";
+			qcom,slavep = <2>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <33>;
+		};
+
+		slv-sdcc-4 {
+			cell-id = <609>;
+			label = "slv-sdcc-4";
+			qcom,slavep = <3>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <34>;
+		};
+
+		slv-tsif {
+			cell-id = <575>;
+			label = "slv-tsif";
+			qcom,slavep = <4>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <35>;
+		};
+
+		slv-bam-dma {
+			cell-id = <610>;
+			label = "slv-bam-dma";
+			qcom,slavep = <5>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <36>;
+		};
+
+		slv-blsp-2 {
+			cell-id = <611>;
+			label = "slv-blsp-2";
+			qcom,slavep = <6>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <37>;
+		};
+
+		slv-usb-hsic {
+			cell-id = <612>;
+			label = "slv-usb-hsic";
+			qcom,slavep = <7>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <38>;
+		};
+
+		slv-blsp-1 {
+			cell-id = <613>;
+			label = "slv-blsp-1";
+			qcom,slavep = <8>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <39>;
+		};
+
+		slv-usb-hs {
+			cell-id = <614>;
+			label = "slv-usb-hs";
+			qcom,slavep = <9>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <40>;
+		};
+
+		slv-pdm	{
+			cell-id = <615>;
+			label = "slv-pdm";
+			qcom,slavep = <10>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <41>;
+		};
+
+		slv-periph-apu-cfg {
+			cell-id = <616>;
+			label = "slv-periph-apu-cfg";
+			qcom,slavep = <11>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <42>;
+		};
+
+		slv-pnoc-mpu-cfg {
+			cell-id = <617>;
+			label = "slv-pnoc-mpu-cfg";
+			qcom,slavep = <12>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <43>;
+		};
+
+		slv-prng {
+			cell-id = <618>;
+			label = "slv-prng";
+			qcom,slavep = <13>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <44>;
+		};
+
+		slv-service-pnoc {
+			cell-id = <619>;
+			label = "slv-service-pnoc";
+			qcom,slavep = <15>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <46>;
+		};
+
+	};
+
+	msm-config-noc@fc480000 {
+		compatible = "msm-bus-fabric";
+		reg = <0xfc480000 0x00004000>;
+		cell-id = <5120>;
+		label = "msm_config_noc";
+		qcom,fabclk-dual = "bus_clk";
+		qcom,fabclk-active = "bus_a_clk";
+		qcom,ntieredslaves = <0>;
+		qcom,hw-sel = "NoC";
+		qcom,rpm-en;
+
+		mas-rpm-inst {
+			cell-id = <72>;
+			label = "mas-rpm-inst";
+			qcom,masterp = <0>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <45>;
+		};
+
+		mas-rpm-data {
+			cell-id = <73>;
+			label = "mas-rpm-data";
+			qcom,masterp = <1>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <46>;
+		};
+
+		mas-rpm-sys {
+			cell-id = <74>;
+			label = "mas-rpm-sys";
+			qcom,masterp = <2>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <47>;
+		};
+
+		mas-dehr {
+			cell-id = <75>;
+			label = "mas-dehr";
+			qcom,masterp = <3>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <48>;
+		};
+
+		mas-qdss-dsp {
+			cell-id = <76>;
+			label = "mas-qdss-dap";
+			qcom,masterp = <4>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <49>;
+		};
+
+		mas-spdm {
+			cell-id = <36>;
+			label = "mas-spdm";
+			qcom,masterp = <5>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <50>;
+		};
+
+		mas-tic	{
+			cell-id = <77>;
+			label = "mas-tic";
+			qcom,masterp = <6>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <51>;
+		};
+
+		slv-clk-ctl {
+			cell-id = <620>;
+			label = "slv-clk-ctl";
+			qcom,slavep = <1>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <47>;
+		};
+
+		slv-cnoc-mss {
+			cell-id = <621>;
+			label = "slv-cnoc-mss";
+			qcom,slavep = <2>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <48>;
+		};
+
+		slv-security {
+			cell-id = <622>;
+			label = "slv-security";
+			qcom,slavep = <3>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <49>;
+		};
+
+		slv-tcsr {
+			cell-id = <623>;
+			label = "slv-tcsr";
+			qcom,slavep = <4>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <50>;
+		};
+
+		slv-tlmm {
+			cell-id = <624>;
+			label = "slv-tlmm";
+			qcom,slavep = <5>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <51>;
+		};
+
+		slv-crypto-0-cfg {
+			cell-id = <625>;
+			label = "slv-crypto-0-cfg";
+			qcom,slavep = <6>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <52>;
+		};
+
+		slv-crypto-1-cfg {
+			cell-id = <626>;
+			label = "slv-crypto-1-cfg";
+			qcom,slavep = <7>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <53>;
+		};
+
+		slv-imem-cfg {
+			cell-id = <627>;
+			label = "slv-imem-cfg";
+			qcom,slavep = <8>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <54>;
+		};
+
+		slv-message-ram	{
+			cell-id = <628>;
+			label = "slv-message-ram";
+			qcom,slavep = <9>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <55>;
+		};
+
+		slv-bimc-cfg {
+			cell-id = <629>;
+			label = "slv-bimc-cfg";
+			qcom,slavep = <10>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <56>;
+		};
+
+		slv-boot-rom {
+			cell-id = <630>;
+			label = "slv-boot-rom";
+			qcom,slavep = <11>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <57>;
+		};
+
+		slv-pmic-arb {
+			cell-id = <632>;
+			label = "slv-pmic-arb";
+			qcom,slavep = <13>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <59>;
+		};
+
+		slv-spdm-wrapper {
+			cell-id = <633>;
+			label = "slv-spdm-wrapper";
+			qcom,slavep = <14>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <60>;
+		};
+
+		slv-dehr-cfg {
+			cell-id = <634>;
+			label = "slv-dehr-cfg";
+			qcom,slavep = <15>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <61>;
+		};
+
+		slv-mpm	{
+			cell-id = <536>;
+			label = "slv-mpm";
+			qcom,slavep = <16>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <62>;
+		};
+
+		slv-qdss-cfg {
+			cell-id = <635>;
+			label = "slv-qdss-cfg";
+			qcom,slavep = <17>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <63>;
+		};
+
+		slv-rbcpr-cfg {
+			cell-id = <636>;
+			label = "slv-rbcpr-cfg";
+			qcom,slavep = <18>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <64>;
+		};
+
+		slv-rbcpr-qdss-apu-cfg {
+			cell-id = <637>;
+			label = "slv-rbcpr-qdss-apu-cfg";
+			qcom,slavep = <19>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <65>;
+		};
+
+		fab-snoc {
+			cell-id = <1024>;
+			label = "fab-snoc";
+			qcom,gateway;
+			qcom,slavep = <29>;
+			qcom,masterp = <7>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <52>;
+			qcom,slv-hw-id = <75>;
+		};
+
+		slv-cnoc-onoc-cfg {
+			cell-id = <639>;
+			label = "slv-cnoc-onoc-cfg";
+			qcom,slavep = <22>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <68>;
+		};
+
+		slv-cnoc-mnoc-mmss-cfg {
+			cell-id = <631>;
+			label = "slv-cnoc-mnoc-mmss-cfg";
+			qcom,slavep = <12>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <58>;
+		};
+
+		slv-cnoc-mnoc-cfg {
+			cell-id = <640>;
+			label = "slv-cnoc-mnoc-cfg";
+			qcom,slavep = <20>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <66>;
+		};
+
+		slv-pnoc-cfg {
+			cell-id = <641>;
+			label = "slv-pnoc-cfg";
+			qcom,slavep = <23>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <69>;
+		};
+
+		slv-snoc-mpu-cfg {
+			cell-id = <638>;
+			label = "slv-snoc-mpu-cfg";
+			qcom,slavep = <21>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <67>;
+		};
+
+		slv-snoc-cfg {
+			cell-id = <642>;
+			label = "slv-snoc-cfg";
+			qcom,slavep = <24>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <70>;
+		};
+
+		slv-ebi1-dll-cfg {
+			cell-id = <643>;
+			label = "slv-ebi1-dll-cfg";
+			qcom,slavep = <25>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <71>;
+		};
+
+		slv-phy-apu-cfg {
+			cell-id = <644>;
+			label = "slv-phy-apu-cfg";
+			qcom,slavep = <26>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <72>;
+		};
+
+		slv-ebi1-phy-cfg {
+			cell-id = <645>;
+			label = "slv-ebi1-phy-cfg";
+			qcom,slavep = <27>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <73>;
+		};
+
+		slv-rpm {
+			cell-id = <534>;
+			label = "slv-rpm";
+			qcom,slavep = <28>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <74>;
+		};
+
+		slv-service-cnoc {
+			cell-id = <646>;
+			label = "slv-service-cnoc";
+			qcom,slavep = <30>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <76>;
+		};
+
+	};
+
+	msm-bimc@0xfc380000 {
+		compatible = "msm-bus-fabric";
+		reg = <0xfc380000 0x0006A000>;
+		cell-id = <0>;
+		label = "msm_bimc";
+		qcom,fabclk-dual = "mem_clk";
+		qcom,fabclk-active = "mem_a_clk";
+		qcom,ntieredslaves = <0>;
+		qcom,qos-freq = <4800>;
+		qcom,hw-sel = "BIMC";
+		qcom,rpm-en;
+
+		coresight-id = <55>;
+		coresight-name = "coresight-bimc";
+		coresight-nr-inports = <0>;
+		coresight-outports = <0>;
+		coresight-child-list = <&funnel_in1>;
+		coresight-child-ports = <3>;
+
+		mas-ampss-m0 {
+			cell-id = <1>;
+			label = "mas-ampss-m0";
+			qcom,masterp = <0>;
+			qcom,tier = <2>;
+			qcom,hw-sel = "BIMC";
+			qcom,mode = "Fixed";
+			qcom,qport = <0>;
+			qcom,ws = <10000>;
+			qcom,mas-hw-id = <0>;
+			qcom,prio-rd = <1>;
+			qcom,prio-wr = <1>;
+		};
+
+		mas-ampss-m1 {
+			cell-id = <2>;
+			label = "mas-ampss-m1";
+			qcom,masterp = <1>;
+			qcom,tier = <2>;
+			qcom,hw-sel = "BIMC";
+			qcom,mode = "Fixed";
+			qcom,qport = <1>;
+			qcom,ws = <10000>;
+			qcom,mas-hw-id = <0>;
+			qcom,prio-rd = <1>;
+			qcom,prio-wr = <1>;
+		};
+
+		mas-mss-proc {
+			cell-id = <65>;
+			label = "mas-mss-proc";
+			qcom,masterp = <2>;
+			qcom,tier = <2>;
+			qcom,hw-sel = "RPM";
+			qcom,mas-hw-id = <1>;
+		};
+
+		fab-mmss-noc {
+			cell-id = <2048>;
+			label = "fab_mmss_noc";
+			qcom,gateway;
+			qcom,masterp = <3 4>;
+			qcom,qport = <3 4>;
+			qcom,buswidth = <8>;
+			qcom,ws = <10000>;
+			qcom,mas-hw-id = <2>;
+			qcom,hw-sel = "BIMC";
+			qcom,mode = "Bypass";
+		};
+
+		fab-snoc {
+			cell-id = <1024>;
+			label = "fab-snoc";
+			qcom,gateway;
+			qcom,slavep = <3>;
+			qcom,masterp = <5 6>;
+			qcom,qport = <5 6>;
+			qcom,buswidth = <8>;
+			qcom,ws = <10000>;
+			qcom,mas-hw-id = <3>;
+			qcom,slv-hw-id = <2>;
+		};
+
+		slv-ebi-ch0 {
+			cell-id = <512>;
+			label = "slv-ebi-ch0";
+			qcom,slavep = <0 1>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <0>;
+			qcom,mode = "Bypass";
+		};
+
+		slv-ampss-l2 {
+			cell-id = <514>;
+			label = "slv-ampss-l2";
+			qcom,slavep = <2>;
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,slv-hw-id = <1>;
+		};
+	};
+
+	msm-ocmem-vnoc@6144 {
+		compatible = "msm-bus-fabric";
+		reg = <0x6144 0x2>;
+		cell-id = <6144>;
+		label = "msm-ocmem-vnoc";
+		qcom,ntieredslaves = <0>;
+		qcom,hw-sel = "NoC";
+		qcom,rpm-en;
+		qcom,virt;
+
+		mas-v-ocmem-gfx3d {
+			cell-id = <89>;
+			label = "mas-v-ocmem-gfx3d";
+			qcom,tier = <2>;
+			qcom,buswidth = <8>;
+			qcom,mas-hw-id = <55>;
+		};
+
+		slv-ocmem {
+			cell-id = <604>;
+			label = "slv-ocmem";
+			qcom,slavep = <0 1>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,slv-hw-id = <18>;
+			qcom,slaveclk-dual = "ocmem_clk";
+			qcom,slaveclk-active = "ocmem_a_clk";
+		};
+
+		fab-snoc {
+			cell-id = <1024>;
+			label = "fab-snoc";
+			qcom,gateway;
+			qcom,buswidth = <8>;
+			qcom,ws = <10000>;
+			qcom,mas-hw-id = <57>;
+			qcom,slv-hw-id = <80>;
+		};
+
+		fab-onoc {
+			cell-id = <3072>;
+			label = "fab-onoc";
+			qcom,gateway;
+			qcom,buswidth = <16>;
+			qcom,ws = <10000>;
+			qcom,mas-hw-id = <56>;
+			qcom,slv-hw-id = <79>;
+		};
+
+	};
+
+	msm-ocmem-noc@fc470000 {
+		compatible = "msm-bus-fabric";
+		reg = <0xfc470000 0x00004000>;
+		cell-id = <3072>;
+		label = "msm_ocmem_noc";
+		qcom,fabclk-dual = "bus_clk";
+		qcom,fabclk-active = "bus_a_clk";
+		qcom,ntieredslaves = <0>;
+		qcom,qos-freq = <4800>;
+		qcom,hw-sel = "NoC";
+		qcom,rpm-en;
+
+		coresight-id = <51>;
+		coresight-name = "coresight-onoc";
+		coresight-nr-inports = <0>;
+		coresight-outports = <0>;
+		coresight-child-list = <&funnel_in0>;
+		coresight-child-ports = <4>;
+
+		fab-ocmem-vnoc	{
+			cell-id = <6144>;
+			label = "fab-ocmem-vnoc";
+			qcom,gateway;
+			qcom,buswidth = <16>;
+			qcom,mas-hw-id = <54>;
+			qcom,slv-hw-id = <78>;
+		};
+
+		mas-jpeg-ocmem	{
+			cell-id = <66>;
+			label = "mas-jpeg-ocmem";
+			qcom,masterp = <1>;
+			qcom,tier = <2>;
+			qcom,perm-mode = "Fixed";
+			qcom,mode = "Fixed";
+			qcom,qport = <0>;
+			qcom,mas-hw-id = <13>;
+			qcom,hw-sel = "NoC";
+		};
+
+		mas-mdp-ocmem {
+			cell-id = <67>;
+			label = "mas-mdp-ocmem";
+			qcom,masterp = <2>;
+			qcom,tier = <2>;
+			qcom,perm-mode = "Fixed";
+			qcom,mode = "Fixed";
+			qcom,mas-hw-id = <14>;
+			qcom,hw-sel = "NoC";
+		};
+
+		mas-video-p0-ocmem {
+			cell-id = <68>;
+			label = "mas-video-p0-ocmem";
+			qcom,masterp = <3>;
+			qcom,tier = <2>;
+			qcom,perm-mode = "Fixed";
+			qcom,mode = "Fixed";
+			qcom,qport = <2>;
+			qcom,mas-hw-id = <15>;
+			qcom,hw-sel = "NoC";
+		};
+
+		mas-video-p1-ocmem {
+			cell-id = <69>;
+			label = "mas-video-p1-ocmem";
+			qcom,masterp = <4>;
+			qcom,tier = <2>;
+			qcom,perm-mode = "Fixed";
+			qcom,mode = "Fixed";
+			qcom,qport = <3>;
+			qcom,mas-hw-id = <16>;
+			qcom,hw-sel = "NoC";
+		};
+
+		mas-vfe-ocmem {
+			cell-id = <70>;
+			label = "mas-vfe-ocmem";
+			qcom,masterp = <5>;
+			qcom,tier = <2>;
+			qcom,perm-mode = "Fixed";
+			qcom,mode = "Fixed";
+			qcom,qport = <4>;
+			qcom,mas-hw-id = <17>;
+			qcom,hw-sel = "NoC";
+			qcom,prio-rd = <1>;
+			qcom,prio-wr = <1>;
+		};
+
+		mas-cnoc-onoc-cfg {
+			cell-id = <71>;
+			label = "mas-cnoc-onoc-cfg";
+			qcom,masterp = <0>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,mas-hw-id = <12>;
+			qcom,hw-sel = "NoC";
+		};
+
+		slv-service-onoc {
+			cell-id = <605>;
+			label = "slv-service-onoc";
+			qcom,slavep = <2>;
+			qcom,tier = <2>;
+			qcom,buswidth = <16>;
+			qcom,slv-hw-id = <19>;
+		};
+	};
+};
+
+
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor-cdp-mtp.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor-cdp-mtp.dtsi
new file mode 100644
index 0000000..fb2917c
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974-camera-sensor-cdp-mtp.dtsi
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+&cci {
+
+	actuator0: qcom,actuator@18 {
+		cell-index = <0>;
+		reg = <0x18 0x0>;
+		compatible = "qcom,actuator";
+		qcom,cci-master = <0>;
+	};
+
+	qcom,camera@6e {
+		compatible = "qcom,s5k3l1yx";
+		reg = <0x6e 0x0>;
+		qcom,slave-id = <0x6e 0x0 0x3121>;
+		qcom,csiphy-sd-index = <0>;
+		qcom,csid-sd-index = <0>;
+		qcom,actuator-src = <&actuator0>;
+		qcom,mount-angle = <90>;
+		qcom,sensor-name = "s5k3l1yx";
+		cam_vdig-supply = <&pm8941_l3>;
+		cam_vana-supply = <&pm8941_l17>;
+		cam_vio-supply = <&pm8941_lvs3>;
+		cam_vaf-supply = <&pm8941_l23>;
+		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+				     "cam_vaf";
+		qcom,cam-vreg-type = <0 1 0 0>;
+		qcom,cam-vreg-min-voltage = <1225000 0 2850000 3000000>;
+		qcom,cam-vreg-max-voltage = <1225000 0 2850000 3000000>;
+		qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+		qcom,gpio-no-mux = <0>;
+		gpios = <&msmgpio 15 0>,
+			<&msmgpio 90 0>,
+			<&msmgpio 89 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-standby = <2>;
+		qcom,gpio-req-tbl-num = <0 1 2>;
+		qcom,gpio-req-tbl-flags = <1 0 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+					  "CAM_RESET1",
+					  "CAM_STANDBY";
+		qcom,gpio-set-tbl-num = <1 1>;
+		qcom,gpio-set-tbl-flags = <0 2>;
+		qcom,gpio-set-tbl-delay = <1000 30000>;
+		qcom,csi-lane-assign = <0x4320>;
+		qcom,csi-lane-mask = <0x1F>;
+		qcom,sensor-position = <0>;
+		qcom,sensor-mode = <1>;
+		qcom,cci-master = <0>;
+		status = "ok";
+	};
+
+	qcom,camera@6c {
+		compatible = "qcom,ov2720";
+		reg = <0x6c 0x0>;
+		qcom,slave-id = <0x6c 0x300A 0x2720>;
+		qcom,csiphy-sd-index = <2>;
+		qcom,csid-sd-index = <0>;
+		qcom,mount-angle = <90>;
+		qcom,sensor-name = "ov2720";
+		cam_vdig-supply = <&pm8941_l3>;
+		cam_vana-supply = <&pm8941_l17>;
+		cam_vio-supply = <&pm8941_lvs3>;
+		qcom,cam-vreg-name = "cam_vdig", "cam_vana", "cam_vio";
+		qcom,cam-vreg-type = <0 0 1>;
+		qcom,cam-vreg-min-voltage = <1225000 2850000 0>;
+		qcom,cam-vreg-max-voltage = <1225000 2850000 0>;
+		qcom,cam-vreg-op-mode = <105000 80000 0>;
+		qcom,gpio-no-mux = <0>;
+		gpios = <&msmgpio 17 0>,
+			<&msmgpio 18 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-req-tbl-num = <0 1>;
+		qcom,gpio-req-tbl-flags = <1 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+					  "CAM_RESET1";
+		qcom,gpio-set-tbl-num = <1 1>;
+		qcom,gpio-set-tbl-flags = <0 2>;
+		qcom,gpio-set-tbl-delay = <1000 4000>;
+		qcom,csi-lane-assign = <0x4320>;
+		qcom,csi-lane-mask = <0x7>;
+		qcom,sensor-position = <1>;
+		qcom,sensor-mode = <1>;
+		qcom,cci-master = <1>;
+		status = "ok";
+	};
+
+	qcom,camera@90 {
+		compatible = "qcom,mt9m114";
+		reg = <0x90 0x0>;
+		qcom,slave-id = <0x90 0x0 0x2481>;
+		qcom,csiphy-sd-index = <1>;
+		qcom,csid-sd-index = <0>;
+		qcom,mount-angle = <0>;
+		qcom,sensor-name = "mt9m114";
+		cam_vdig-supply = <&pm8941_l3>;
+		cam_vana-supply = <&pm8941_l17>;
+		cam_vio-supply = <&pm8941_lvs3>;
+		qcom,cam-vreg-name = "cam_vdig", "cam_vana", "cam_vio";
+		qcom,cam-vreg-type = <0 0 1>;
+		qcom,cam-vreg-min-voltage = <1225000 2850000 0>;
+		qcom,cam-vreg-max-voltage = <1225000 2850000 0>;
+		qcom,cam-vreg-op-mode = <105000 80000 0>;
+		qcom,gpio-no-mux = <0>;
+		gpios = <&msmgpio 16 0>,
+			<&msmgpio 92 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-req-tbl-num = <0 1>;
+		qcom,gpio-req-tbl-flags = <1 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+					  "CAM_RESET1";
+		qcom,gpio-set-tbl-num = <1 1>;
+		qcom,gpio-set-tbl-flags = <0 2>;
+		qcom,gpio-set-tbl-delay = <1000 4000>;
+		qcom,csi-lane-assign = <0x4320>;
+		qcom,csi-lane-mask = <0x3>;
+		qcom,sensor-position = <1>;
+		qcom,sensor-mode = <1>;
+		qcom,cci-master = <0>;
+	};
+};
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor-fluid.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor-fluid.dtsi
new file mode 100644
index 0000000..4fe4220
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974-camera-sensor-fluid.dtsi
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+&cci {
+
+	actuator0: qcom,actuator@18 {
+		cell-index = <0>;
+		reg = <0x18 0x0>;
+		compatible = "qcom,actuator";
+		qcom,cci-master = <0>;
+	};
+
+	qcom,camera@6e {
+		compatible = "qcom,s5k3l1yx";
+		reg = <0x6e>;
+		qcom,slave-id = <0x6e 0x0 0x3121>;
+		qcom,csiphy-sd-index = <0>;
+		qcom,csid-sd-index = <0>;
+		qcom,actuator-src = <&actuator0>;
+		qcom,led-flash-src = <&led_flash0>;
+		qcom,mount-angle = <270>;
+		qcom,sensor-name = "s5k3l1yx";
+		cam_vdig-supply = <&pm8941_l3>;
+		cam_vana-supply = <&pm8941_l17>;
+		cam_vio-supply = <&pm8941_lvs3>;
+		cam_vaf-supply = <&pm8941_l23>;
+		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+				     "cam_vaf";
+		qcom,cam-vreg-type = <0 1 0 0>;
+		qcom,cam-vreg-min-voltage = <1225000 0 2850000 3000000>;
+		qcom,cam-vreg-max-voltage = <1225000 0 2850000 3000000>;
+		qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+		qcom,gpio-no-mux = <0>;
+		gpios = <&msmgpio 15 0>,
+			<&msmgpio 90 0>,
+			<&msmgpio 89 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-standby = <2>;
+		qcom,gpio-req-tbl-num = <0 1 2>;
+		qcom,gpio-req-tbl-flags = <1 0 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+					  "CAM_RESET1",
+					  "CAM_STANDBY";
+		qcom,gpio-set-tbl-num = <1 1>;
+		qcom,gpio-set-tbl-flags = <0 2>;
+		qcom,gpio-set-tbl-delay = <1000 30000>;
+		qcom,csi-lane-assign = <0x4320>;
+		qcom,csi-lane-mask = <0x1F>;
+		qcom,sensor-position = <0>;
+		qcom,sensor-mode = <1>;
+		qcom,cci-master = <0>;
+		status = "ok";
+	};
+
+	qcom,camera@6c {
+		compatible = "qcom,ov2720";
+		reg = <0x6c>;
+		qcom,slave-id = <0x6c 0x300A 0x2720>;
+		qcom,csiphy-sd-index = <2>;
+		qcom,csid-sd-index = <0>;
+		qcom,mount-angle = <90>;
+		qcom,sensor-name = "ov2720";
+		cam_vdig-supply = <&pm8941_l3>;
+		cam_vana-supply = <&pm8941_l17>;
+		cam_vio-supply = <&pm8941_lvs3>;
+		qcom,cam-vreg-name = "cam_vdig", "cam_vana", "cam_vio";
+		qcom,cam-vreg-type = <0 0 1>;
+		qcom,cam-vreg-min-voltage = <1225000 2850000 0>;
+		qcom,cam-vreg-max-voltage = <1225000 2850000 0>;
+		qcom,cam-vreg-op-mode = <105000 80000 0>;
+		qcom,gpio-no-mux = <0>;
+		gpios = <&msmgpio 17 0>,
+			<&msmgpio 18 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-req-tbl-num = <0 1>;
+		qcom,gpio-req-tbl-flags = <1 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+					  "CAM_RESET1";
+		qcom,gpio-set-tbl-num = <1 1>;
+		qcom,gpio-set-tbl-flags = <0 2>;
+		qcom,gpio-set-tbl-delay = <1000 4000>;
+		qcom,csi-lane-assign = <0x4320>;
+		qcom,csi-lane-mask = <0x7>;
+		qcom,sensor-position = <1>;
+		qcom,sensor-mode = <1>;
+		qcom,cci-master = <1>;
+		status = "ok";
+	};
+
+	qcom,camera@90 {
+		compatible = "qcom,mt9m114";
+		reg = <0x90 0x0>;
+		qcom,slave-id = <0x90 0x0 0x2481>;
+		qcom,csiphy-sd-index = <1>;
+		qcom,csid-sd-index = <0>;
+		qcom,mount-angle = <0>;
+		qcom,sensor-name = "mt9m114";
+		cam_vdig-supply = <&pm8941_l3>;
+		cam_vana-supply = <&pm8941_l17>;
+		cam_vio-supply = <&pm8941_lvs3>;
+		qcom,cam-vreg-name = "cam_vdig", "cam_vana", "cam_vio";
+		qcom,cam-vreg-type = <0 0 1>;
+		qcom,cam-vreg-min-voltage = <1225000 2850000 0>;
+		qcom,cam-vreg-max-voltage = <1225000 2850000 0>;
+		qcom,cam-vreg-op-mode = <105000 80000 0>;
+		qcom,gpio-no-mux = <0>;
+		gpios = <&msmgpio 16 0>,
+			<&msmgpio 92 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-req-tbl-num = <0 1>;
+		qcom,gpio-req-tbl-flags = <1 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+					  "CAM_RESET1";
+		qcom,gpio-set-tbl-num = <1 1>;
+		qcom,gpio-set-tbl-flags = <0 2>;
+		qcom,gpio-set-tbl-delay = <1000 4000>;
+		qcom,csi-lane-assign = <0x4320>;
+		qcom,csi-lane-mask = <0x3>;
+		qcom,sensor-position = <1>;
+		qcom,sensor-mode = <1>;
+		qcom,cci-master = <0>;
+	};
+};
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor-liquid.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor-liquid.dtsi
index c9b999f..b313795 100644
--- a/arch/arm/boot/dts/msm8974-camera-sensor-liquid.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera-sensor-liquid.dtsi
@@ -1,6 +1,6 @@
 
 /*
- * 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
@@ -14,58 +14,61 @@
 
 &cci {
 
+	actuator0: qcom,actuator@18 {
+		cell-index = <0>;
+		reg = <0x18 0x0>;
+		compatible = "qcom,actuator";
+		qcom,cci-master = <0>;
+	};
+
 	qcom,camera@6e {
 		compatible = "qcom,s5k3l1yx";
 		reg = <0x6e 0x0>;
-		qcom,csi-if = <1>;
-		qcom,csid-core = <0>;
-		qcom,flash-src-index = <&led_flash0>;
+		qcom,slave-id = <0x6e 0x0 0x3121>;
+		qcom,csiphy-sd-index = <0>;
+		qcom,csid-sd-index = <0>;
 		qcom,mount-angle = <0>;
 		qcom,sensor-name = "s5k3l1yx";
 		cam_vdig-supply = <&pm8941_l3>;
 		cam_vana-supply = <&pm8941_l17>;
 		cam_vio-supply = <&pm8941_lvs3>;
 		cam_vaf-supply = <&pm8941_l23>;
-		qcom,cam-vreg-name = "cam_vdig", "cam_vana", "cam_vio",
+		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
 				     "cam_vaf";
-		qcom,cam-vreg-type = <0 0 1 0>;
-		qcom,cam-vreg-min-voltage = <1225000 2850000 0 3000000>;
-		qcom,cam-vreg-max-voltage = <1225000 2850000 0 3000000>;
-		qcom,cam-vreg-op-mode = <105000 80000 0 100000>;
+		qcom,cam-vreg-type = <0 1 0 0>;
+		qcom,cam-vreg-min-voltage = <1225000 0 2850000 3000000>;
+		qcom,cam-vreg-max-voltage = <1225000 0 2850000 3000000>;
+		qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
 		qcom,gpio-no-mux = <0>;
 		gpios = <&msmgpio 15 0>,
-			<&msmgpio 19 0>,
-			<&msmgpio 20 0>,
 			<&msmgpio 90 0>;
-		qcom,gpio-common-tbl-num = <0 1 2>;
-		qcom,gpio-common-tbl-flags = <1 1 1>;
-		qcom,gpio-common-tbl-label = "CAMIF_MCLK",
-					     "CAMIF_I2C_DATA",
-					     "CAMIF_I2C_CLK";
-		qcom,gpio-req-tbl-num = <3>;
-		qcom,gpio-req-tbl-flags = <0>;
-		qcom,gpio-req-tbl-label = "CAM_RESET1";
-		qcom,gpio-set-tbl-num = <3 3>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-req-tbl-num = <0 1>;
+		qcom,gpio-req-tbl-flags = <1 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+					  "CAM_RESET1";
+		qcom,gpio-set-tbl-num = <1 1>;
 		qcom,gpio-set-tbl-flags = <0 2>;
 		qcom,gpio-set-tbl-delay = <1000 30000>;
 		qcom,csi-lane-assign = <0x4320>;
 		qcom,csi-lane-mask = <0x1F>;
-		qcom,csi-phy-sel = <0>;
-		qcom,camera-type = <0>;
-		qcom,sensor-type = <0>;
+		qcom,sensor-position = <0>;
+		qcom,sensor-mode = <1>;
+		qcom,cci-master = <0>;
 		status = "ok";
 	};
 
 	qcom,camera@6c {
 		compatible = "qcom,ov2720";
 		reg = <0x6c 0x0>;
-		qcom,csi-if = <1>;
-		qcom,csid-core = <0>;
+		qcom,slave-id = <0x6c 0x300A 0x2720>;
+		qcom,csiphy-sd-index = <2>;
+		qcom,csid-sd-index = <0>;
 		qcom,mount-angle = <180>;
 		qcom,sensor-name = "ov2720";
 		cam_vdig-supply = <&pm8941_l3>;
 		cam_vana-supply = <&pm8941_l17>;
-		cam_vio-supply = <&pm8941_lvs2>;
+		cam_vio-supply = <&pm8941_lvs3>;
 		qcom,cam-vreg-name = "cam_vdig", "cam_vana", "cam_vio";
 		qcom,cam-vreg-type = <0 0 1>;
 		qcom,cam-vreg-min-voltage = <1225000 2850000 0>;
@@ -73,25 +76,54 @@
 		qcom,cam-vreg-op-mode = <105000 80000 0>;
 		qcom,gpio-no-mux = <0>;
 		gpios = <&msmgpio 17 0>,
-			<&msmgpio 19 0>,
-			<&msmgpio 20 0>,
 			<&msmgpio 18 0>;
-		qcom,gpio-common-tbl-num = <0 1 2>;
-		qcom,gpio-common-tbl-flags = <1 1 1>;
-		qcom,gpio-common-tbl-label = "CAMIF_MCLK",
-					     "CAMIF_I2C_DATA",
-					     "CAMIF_I2C_CLK";
-		qcom,gpio-req-tbl-num = <3>;
-		qcom,gpio-req-tbl-flags = <0>;
-		qcom,gpio-req-tbl-label = "CAM_RESET1";
-		qcom,gpio-set-tbl-num = <3 3>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-req-tbl-num = <0 1>;
+		qcom,gpio-req-tbl-flags = <1 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+					  "CAM_RESET1";
+		qcom,gpio-set-tbl-num = <1 1>;
 		qcom,gpio-set-tbl-flags = <0 2>;
 		qcom,gpio-set-tbl-delay = <1000 4000>;
 		qcom,csi-lane-assign = <0x4320>;
 		qcom,csi-lane-mask = <0x7>;
-		qcom,csi-phy-sel = <2>;
-		qcom,camera-type = <1>;
-		qcom,sensor-type = <0>;
+		qcom,sensor-position = <1>;
+		qcom,sensor-mode = <1>;
+		qcom,cci-master = <0>;
 		status = "ok";
 	};
+
+	qcom,camera@90 {
+		compatible = "qcom,mt9m114";
+		reg = <0x90 0x0>;
+		qcom,slave-id = <0x90 0x0 0x2481>;
+		qcom,csiphy-sd-index = <1>;
+		qcom,csid-sd-index = <0>;
+		qcom,mount-angle = <0>;
+		qcom,sensor-name = "mt9m114";
+		cam_vdig-supply = <&pm8941_l3>;
+		cam_vana-supply = <&pm8941_l17>;
+		cam_vio-supply = <&pm8941_lvs3>;
+		qcom,cam-vreg-name = "cam_vdig", "cam_vana", "cam_vio";
+		qcom,cam-vreg-type = <0 0 1>;
+		qcom,cam-vreg-min-voltage = <1225000 2850000 0>;
+		qcom,cam-vreg-max-voltage = <1225000 2850000 0>;
+		qcom,cam-vreg-op-mode = <105000 80000 0>;
+		qcom,gpio-no-mux = <0>;
+		gpios = <&msmgpio 16 0>,
+			<&msmgpio 92 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-req-tbl-num = <0 1>;
+		qcom,gpio-req-tbl-flags = <1 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+					  "CAM_RESET1";
+		qcom,gpio-set-tbl-num = <1 1>;
+		qcom,gpio-set-tbl-flags = <0 2>;
+		qcom,gpio-set-tbl-delay = <1000 4000>;
+		qcom,csi-lane-assign = <0x4320>;
+		qcom,csi-lane-mask = <0x3>;
+		qcom,sensor-position = <1>;
+		qcom,sensor-mode = <1>;
+		qcom,cci-master = <0>;
+	};
 };
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor.dtsi
deleted file mode 100644
index 68da844..0000000
--- a/arch/arm/boot/dts/msm8974-camera-sensor.dtsi
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-&cci {
-
-	qcom,camera@6e {
-		compatible = "qcom,s5k3l1yx";
-		reg = <0x6e 0x0>;
-		qcom,csi-if = <1>;
-		qcom,csid-core = <0>;
-		qcom,flash-src-index = <&led_flash0>;
-		qcom,mount-angle = <90>;
-		qcom,sensor-name = "s5k3l1yx";
-		cam_vdig-supply = <&pm8941_l3>;
-		cam_vana-supply = <&pm8941_l17>;
-		cam_vio-supply = <&pm8941_lvs3>;
-		cam_vaf-supply = <&pm8941_l23>;
-		qcom,cam-vreg-name = "cam_vdig", "cam_vana", "cam_vio",
-				     "cam_vaf";
-		qcom,cam-vreg-type = <0 0 1 0>;
-		qcom,cam-vreg-min-voltage = <1225000 2850000 0 3000000>;
-		qcom,cam-vreg-max-voltage = <1225000 2850000 0 3000000>;
-		qcom,cam-vreg-op-mode = <105000 80000 0 100000>;
-		qcom,gpio-no-mux = <0>;
-		gpios = <&msmgpio 15 0>,
-			<&msmgpio 19 0>,
-			<&msmgpio 20 0>,
-			<&msmgpio 90 0>;
-		qcom,gpio-common-tbl-num = <0 1 2>;
-		qcom,gpio-common-tbl-flags = <1 1 1>;
-		qcom,gpio-common-tbl-label = "CAMIF_MCLK",
-					     "CAMIF_I2C_DATA",
-					     "CAMIF_I2C_CLK";
-		qcom,gpio-req-tbl-num = <3>;
-		qcom,gpio-req-tbl-flags = <0>;
-		qcom,gpio-req-tbl-label = "CAM_RESET1";
-		qcom,gpio-set-tbl-num = <3 3>;
-		qcom,gpio-set-tbl-flags = <0 2>;
-		qcom,gpio-set-tbl-delay = <1000 30000>;
-		qcom,csi-lane-assign = <0x4320>;
-		qcom,csi-lane-mask = <0x1F>;
-		qcom,csi-phy-sel = <0>;
-		qcom,camera-type = <0>;
-		qcom,sensor-type = <0>;
-		status = "ok";
-	};
-
-	qcom,camera@6c {
-		compatible = "qcom,ov2720";
-		reg = <0x6c 0x0>;
-		qcom,csi-if = <1>;
-		qcom,csid-core = <0>;
-		qcom,mount-angle = <180>;
-		qcom,sensor-name = "ov2720";
-		cam_vdig-supply = <&pm8941_l3>;
-		cam_vana-supply = <&pm8941_l17>;
-		cam_vio-supply = <&pm8941_lvs3>;
-		qcom,cam-vreg-name = "cam_vdig", "cam_vana", "cam_vio";
-		qcom,cam-vreg-type = <0 0 1>;
-		qcom,cam-vreg-min-voltage = <1225000 2850000 0>;
-		qcom,cam-vreg-max-voltage = <1225000 2850000 0>;
-		qcom,cam-vreg-op-mode = <105000 80000 0>;
-		qcom,gpio-no-mux = <0>;
-		gpios = <&msmgpio 17 0>,
-			<&msmgpio 19 0>,
-			<&msmgpio 20 0>,
-			<&msmgpio 18 0>;
-		qcom,gpio-common-tbl-num = <0 1 2>;
-		qcom,gpio-common-tbl-flags = <1 1 1>;
-		qcom,gpio-common-tbl-label = "CAMIF_MCLK",
-					     "CAMIF_I2C_DATA",
-					     "CAMIF_I2C_CLK";
-		qcom,gpio-req-tbl-num = <3>;
-		qcom,gpio-req-tbl-flags = <0>;
-		qcom,gpio-req-tbl-label = "CAM_RESET1";
-		qcom,gpio-set-tbl-num = <3 3>;
-		qcom,gpio-set-tbl-flags = <0 2>;
-		qcom,gpio-set-tbl-delay = <1000 4000>;
-		qcom,csi-lane-assign = <0x4320>;
-		qcom,csi-lane-mask = <0x7>;
-		qcom,csi-phy-sel = <2>;
-		qcom,camera-type = <1>;
-		qcom,sensor-type = <0>;
-		status = "ok";
-	};
-};
diff --git a/arch/arm/boot/dts/msm8974-camera.dtsi b/arch/arm/boot/dts/msm8974-camera.dtsi
index 48dd4dc..ea99aa3 100644
--- a/arch/arm/boot/dts/msm8974-camera.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera.dtsi
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -14,10 +14,10 @@
 /include/ "skeleton.dtsi"
 
 / {
-	qcom,cam_server {
-		compatible = "qcom,cam_server";
+	qcom,msm-cam@fd8C0000 {
+		compatible = "qcom,msm-cam";
 		reg = <0xfd8C0000 0x10000>;
-		reg-names = "server";
+		reg-names = "msm-cam";
 	};
 
 	qcom,csiphy@fda0ac00 {
@@ -90,7 +90,7 @@
 	qcom,ispif@fda0A000 {
 		cell-index = <0>;
 		compatible = "qcom,ispif";
-		reg = <0xfda0A000 0x300>;
+		reg = <0xfda0A000 0x500>;
 		reg-names = "ispif";
 		interrupts = <0 55 0>;
 		interrupt-names = "ispif";
@@ -158,8 +158,9 @@
 	qcom,cpp@fda04000 {
 		cell-index = <0>;
 		compatible = "qcom,cpp";
-		reg = <0xfda04000 0x100>;
-		reg-names = "cpp";
+		reg = <0xfda04000 0x100>,
+		      <0xfda40000 0x200>;
+		reg-names = "cpp", "cpp_vbif";
 		interrupts = <0 49 0>;
 		interrupt-names = "cpp";
 		vdd-supply = <&gdsc_vfe>;
@@ -182,47 +183,25 @@
 		reg-names = "cci";
 		interrupts = <0 50 0>;
 		interrupt-names = "cci";
-
-		qcom,camera@6e {
-			status = "disable";
-		};
-
-		qcom,camera@6c {
-			status = "disable";
-		};
-
-		qcom,camera@90 {
-			compatible = "qcom,mt9m114";
-			reg = <0x90 0x0>;
-			qcom,csi-if = <1>;
-			qcom,csid-core = <0>;
-			qcom,mount-angle = <0>;
-			qcom,sensor-name = "mt9m114";
-			cam_vdig-supply = <&pm8941_l3>;
-			cam_vana-supply = <&pm8941_l17>;
-			cam_vio-supply = <&pm8941_lvs3>;
-			qcom,cam-vreg-name = "cam_vdig", "cam_vana", "cam_vio";
-			qcom,cam-vreg-type = <0 0 1>;
-			qcom,cam-vreg-min-voltage = <1225000 2850000 0>;
-			qcom,cam-vreg-max-voltage = <1225000 2850000 0>;
-			qcom,cam-vreg-op-mode = <105000 80000 0>;
-			qcom,gpio-no-mux = <0>;
-			gpios = <&msmgpio 16 0>,
-				<&msmgpio 92 0>;
-			qcom,gpio-common-tbl-num = <0>;
-			qcom,gpio-common-tbl-flags = <1>;
-			qcom,gpio-common-tbl-label = "CAMIF_MCLK";
-			qcom,gpio-req-tbl-num = <1>;
-			qcom,gpio-req-tbl-flags = <0>;
-			qcom,gpio-req-tbl-label = "CAM_RESET1";
-			qcom,gpio-set-tbl-num = <1 1>;
-			qcom,gpio-set-tbl-flags = <0 2>;
-			qcom,gpio-set-tbl-delay = <1000 4000>;
-			qcom,csi-lane-assign = <0x4320>;
-			qcom,csi-lane-mask = <0x3>;
-			qcom,csi-phy-sel = <1>;
-			qcom,camera-type = <1>;
-			qcom,sensor-type = <1>;
-		};
+		gpios = <&msmgpio 19 0>,
+			<&msmgpio 20 0>,
+			<&msmgpio 21 0>,
+			<&msmgpio 22 0>;
+		qcom,gpio-tbl-num = <0 1 2 3>;
+		qcom,gpio-tbl-flags = <1 1 1 1>;
+		qcom,gpio-tbl-label = "CCI_I2C_DATA0",
+				      "CCI_I2C_CLK0",
+				      "CCI_I2C_DATA1",
+				      "CCI_I2C_CLK1";
+		qcom,hw-thigh = <78>;
+		qcom,hw-tlow = <114>;
+		qcom,hw-tsu-sto = <28>;
+		qcom,hw-tsu-sta = <28>;
+		qcom,hw-thd-dat = <10>;
+		qcom,hw-thd-sta = <77>;
+		qcom,hw-tbuf = <118>;
+		qcom,hw-scl-stretch-en = <0>;
+		qcom,hw-trdhld = <6>;
+		qcom,hw-tsp = <1>;
 	};
 };
diff --git a/arch/arm/boot/dts/msm8974-cdp.dts b/arch/arm/boot/dts/msm8974-cdp.dts
deleted file mode 100644
index b8b3141..0000000
--- a/arch/arm/boot/dts/msm8974-cdp.dts
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/ "msm8974.dtsi"
-/include/ "msm8974-cdp.dtsi"
-
-/ {
-	model = "Qualcomm MSM 8974 CDP";
-	compatible = "qcom,msm8974-cdp", "qcom,msm8974";
-	qcom,msm-id = <126 1 0>;
-};
diff --git a/arch/arm/boot/dts/msm8974-cdp.dtsi b/arch/arm/boot/dts/msm8974-cdp.dtsi
index 6aaf677..0acfaf6 100644
--- a/arch/arm/boot/dts/msm8974-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8974-cdp.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -11,18 +11,21 @@
  */
 
 /include/ "dsi-panel-toshiba-720p-video.dtsi"
+/include/ "dsi-panel-orise-720p-video.dtsi"
 /include/ "msm8974-leds.dtsi"
-/include/ "msm8974-camera-sensor.dtsi"
+/include/ "msm8974-camera-sensor-cdp-mtp.dtsi"
 
 / {
 	serial@f991e000 {
 		status = "ok";
 	};
 
-	qcom,mdss_dsi@fd922800 {
-		qcom,mdss_dsi_toshiba_720p_video {
-			status = "ok";
-		};
+	qcom,mdss_dsi_toshiba_720p_video {
+		status = "ok";
+	};
+
+	qcom,mdss_dsi_orise_720p_video {
+		status = "disable";
 	};
 
 	qcom,hdmi_tx@fd922100 {
@@ -42,6 +45,7 @@
 			atmel,panel-coords = <0  0 760 1424>;
 			atmel,display-coords = <0 0 720 1280>;
 			atmel,i2c-pull-up;
+			atmel,no-force-update;
 			atmel,cfg_1 {
 				atmel,family-id = <0x82>;
 				atmel,variant-id = <0x19>;
@@ -51,16 +55,16 @@
 					/* Object 6, Instance = 0 */
 					00 00 00 00 00 00
 					/* Object 38, Instance = 0 */
-					15 00 02 10 08 0C 00 00
+					15 01 00 03 0A 0C 00 00
 					/* Object 7, Instance = 0 */
-					FF FF 32 03
+					20 08 32 03
 					/* Object 8, Instance = 0 */
-					0F 00 0A 0A 00 00 0A 00 00 00
+					0F 00 0A 0A 00 00 0A 0A 00 00
 					/* Object 9, Instance = 0 */
-					83 00 00 18 0E 00 70 32 02 01
-					00 03 01 01 05 0A 0A 0A 90 05
-					F8 02 00 00 0F 0F 00 00 48 2D
-					07 0C 00 00 00 00
+					83 00 00 18 0E 00 70 46 02 01
+					00 0A 03 31 04 05 0A 0A 90 05
+					F8 02 05 F1 F1 0F 00 00 08 2D
+					12 06 00 00 00 01
 					/* Object 15, Instance = 0 */
 					00 00 00 00 00 00 00 00 00 00
 					00
@@ -77,7 +81,7 @@
 					/* Object 40, Instance = 0 */
 					00 00 00 00 00
 					/* Object 42, Instance = 0 */
-					00 00 00 00 00 00 00 00 00 00
+					33 1E 19 10 80 00 00 00 FF 00
 					/* Object 46, Instance = 0 */
 					00 00 10 10 00 00 03 00 00 01
 					/* Object 47, Instance = 0 */
@@ -86,7 +90,7 @@
 					/* Object 55, Instance = 0 */
 					00 00 00 00 00 00
 					/* Object 56, Instance = 0 */
-					03 00 01 18 05 05 05 05 05 05
+					00 00 00 18 05 05 05 05 05 05
 					05 05 05 05 05 05 05 05 05 05
 					05 05 05 05 05 05 05 05 00 00
 					00 00 00 00 00 00 00 00 00 00
@@ -95,20 +99,52 @@
 					00 00 00
 					/* Object 61, Instance = 0 */
 					00 00 00 00 00
-					/* Object 61, Instance = 1 */
-					00 00 00 00 00
 					/* Object 62, Instance = 0 */
-					7F 03 00 16 00 00 00 00 00 00
-					04 08 10 18 05 00 0A 05 05 50
-					14 19 34 1A 64 00 00 04 40 00
-					00 00 00 00 30 32 02 00 01 00
-					05 00 00 00 00 00 00 00 00 00
-					00 00 0C 00
+					01 2A 00 16 00 00 00 00 0B 01
+					02 03 04 08 00 00 08 10 18 05
+					00 0A 05 05 50 14 19 34 1A 7F
+					00 00 00 00 00 00 00 00 00 30
+					05 02 00 01 00 05 00 00 00 00
+					00 00 00 00
 					];
 			};
 		};
 	};
 
+	gen-vkeys {
+		compatible = "qcom,gen-vkeys";
+		label = "atmel_mxt_ts";
+		qcom,disp-maxx = <720>;
+		qcom,disp-maxy = <1280>;
+		qcom,panel-maxx = <760>;
+		qcom,panel-maxy = <1424>;
+		qcom,key-codes = <158 139 102 217>;
+	};
+
+	i2c@f9967000 {
+		isa1200@48 {
+			status = "okay";
+			reg = <0x48>;
+			vcc_i2c-supply = <&pm8941_s3>;
+			compatible = "imagis,isa1200";
+			label = "vibrator";
+			imagis,chip-en;
+			imagis,smart-en;
+			imagis,need-pwm-clk;
+			imagis,ext-clk-en;
+			imagis,hap-en-gpio = <&msmgpio 86 0x00>;
+			imagis,max-timeout = <15000>;
+			imagis,pwm-div = <256>;
+			imagis,mode-ctrl = <2>;
+			imagis,regulator {
+				regulator-name = "vcc_i2c";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-max-microamp = <9360>;
+			};
+		};
+	};
+
 	gpio_keys {
 		compatible = "gpio-keys";
 		input-name = "gpio-keys";
@@ -158,6 +194,30 @@
 		qcom,model = "msm8974-taiko-cdp-snd-card";
 		qcom,hdmi-audio-rx;
 	};
+
+	usb2_otg_sw: regulator-tpd4s214 {
+		compatible = "regulator-fixed";
+		regulator-name = "usb2_otg_sw";
+		gpio = <&pm8941_gpios 18 0>;
+		parent-supply = <&pm8941_boost>;
+		startup-delay-us = <17000>;
+		enable-active-high;
+	};
+
+        hsic@f9a00000 {
+                compatible = "qcom,hsic-host";
+                reg = <0xf9a00000 0x400>;
+                interrupts = <0 136 0>, <0 148 0>;
+                interrupt-names = "core_irq", "async_irq";
+                HSIC_VDDCX-supply = <&pm8841_s2>;
+                HSIC_GDSC-supply = <&gdsc_usb_hsic>;
+                hsic,strobe-gpio = <&msmgpio 144 0x00>;
+                hsic,data-gpio = <&msmgpio 145 0x00>;
+                hsic,ignore-cal-pad-config;
+                hsic,strobe-pad-offset = <0x2050>;
+                hsic,data-pad-offset = <0x2054>;
+        };
+
 };
 
 &spmi_bus {
@@ -170,7 +230,7 @@
 				linux,default-trigger = "bkl-trigger";
 				qcom,cs-out-en;
 				qcom,op-fdbck;
-				qcom,default-state = "off";
+				qcom,default-state = "on";
 				qcom,max-current = <25>;
 				qcom,ctrl-delay-us = <0>;
 				qcom,boost-curr-lim = <3>;
@@ -234,6 +294,10 @@
 	wp-gpios = <&pm8941_gpios 29 0x1>;
 };
 
+&uart7 {
+	status = "ok";
+};
+
 &usb3 {
 	qcom,otg-capability;
 };
@@ -339,12 +403,27 @@
 	};
 
 	gpio@cf00 { /* GPIO 16 */
+		qcom,mode = <1>;
+		qcom,output-type = <0>;
+		qcom,pull = <2>;
+		qcom,vin-sel = <2>;
+		qcom,out-strength = <2>;
+		qcom,src-sel = <2>;
+		qcom,master-en = <1>;
 	};
 
 	gpio@d000 { /* GPIO 17 */
 	};
 
 	gpio@d100 { /* GPIO 18 */
+		/* usb2_otg_sw regulator enable */
+		qcom,mode = <1>;		/* Digital output */
+		qcom,output-type = <0>;		/* CMOS logic */
+		qcom,invert = <0>; 		/* Output low initially */
+		qcom,vin-sel = <2>; 		/* PM8941 S3 = 1.8 V */
+		qcom,src-sel = <0>; 		/* Constant */
+		qcom,out-strength = <2>;	/* Medium drive strength */
+		qcom,master-en = <1>;		/* Enable GPIO */
 	};
 
 	gpio@d200 { /* GPIO 19 */
@@ -465,3 +544,11 @@
 	mpp@a300 { /* MPP 4 */
 	};
 };
+
+&slim_msm {
+	taiko_codec {
+		qcom,cdc-micbias1-ext-cap;
+		qcom,cdc-micbias3-ext-cap;
+		qcom,cdc-micbias4-ext-cap;
+	};
+};
diff --git a/arch/arm/boot/dts/msm8974-clock.dtsi b/arch/arm/boot/dts/msm8974-clock.dtsi
index 043346f..bed5d70 100644
--- a/arch/arm/boot/dts/msm8974-clock.dtsi
+++ b/arch/arm/boot/dts/msm8974-clock.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/boot/dts/msm8974-coresight.dtsi b/arch/arm/boot/dts/msm8974-coresight.dtsi
index ee3df10..5df8f10 100644
--- a/arch/arm/boot/dts/msm8974-coresight.dtsi
+++ b/arch/arm/boot/dts/msm8974-coresight.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -15,6 +15,7 @@
 		compatible = "arm,coresight-tmc";
 		reg = <0xfc322000 0x1000>,
 		      <0xfc37c000 0x3000>;
+		reg-names = "tmc-etr-base", "tmc-etr-bam-base";
 
 		qcom,memory-reservation-type = "EBI1";
 		qcom,memory-reservation-size = <0x100000>; /* 1M EBI1 buffer */
@@ -22,11 +23,13 @@
 		coresight-id = <0>;
 		coresight-name = "coresight-tmc-etr";
 		coresight-nr-inports = <1>;
+		coresight-ctis = <&cti0 &cti8>;
 	};
 
 	tpiu: tpiu@fc318000 {
 		compatible = "arm,coresight-tpiu";
 		reg = <0xfc318000 0x1000>;
+		reg-names = "tpiu-base";
 
 		coresight-id = <1>;
 		coresight-name = "coresight-tpiu";
@@ -36,6 +39,7 @@
 	replicator: replicator@fc31c000 {
 		compatible = "qcom,coresight-replicator";
 		reg = <0xfc31c000 0x1000>;
+		reg-names = "replicator-base";
 
 		coresight-id = <2>;
 		coresight-name = "coresight-replicator";
@@ -48,6 +52,7 @@
 	tmc_etf: tmc@fc307000 {
 		compatible = "arm,coresight-tmc";
 		reg = <0xfc307000 0x1000>;
+		reg-names = "tmc-etf-base";
 
 		coresight-id = <3>;
 		coresight-name = "coresight-tmc-etf";
@@ -56,11 +61,13 @@
 		coresight-child-list = <&replicator>;
 		coresight-child-ports = <0>;
 		coresight-default-sink;
+		coresight-ctis = <&cti0 &cti8>;
 	};
 
 	funnel_merg: funnel@fc31b000 {
 		compatible = "arm,coresight-funnel";
 		reg = <0xfc31b000 0x1000>;
+		reg-names = "funnel-merg-base";
 
 		coresight-id = <4>;
 		coresight-name = "coresight-funnel-merg";
@@ -73,6 +80,7 @@
 	funnel_in0: funnel@fc319000 {
 		compatible = "arm,coresight-funnel";
 		reg = <0xfc319000 0x1000>;
+		reg-names = "funnel-in0-base";
 
 		coresight-id = <5>;
 		coresight-name = "coresight-funnel-in0";
@@ -85,6 +93,7 @@
 	funnel_in1: funnel@fc31a000 {
 		compatible = "arm,coresight-funnel";
 		reg = <0xfc31a000 0x1000>;
+		reg-names = "funnel-in1-base";
 
 		coresight-id = <6>;
 		coresight-name = "coresight-funnel-in1";
@@ -97,6 +106,7 @@
 	funnel_kpss: funnel@fc345000 {
 		compatible = "arm,coresight-funnel";
 		reg = <0xfc345000 0x1000>;
+		reg-names = "funnel-kpss-base";
 
 		coresight-id = <7>;
 		coresight-name = "coresight-funnel-kpss";
@@ -109,6 +119,8 @@
 	funnel_mmss: funnel@fc364000 {
 		compatible = "arm,coresight-funnel";
 		reg = <0xfc364000 0x1000>;
+		reg-names = "funnel-mmss-base";
+
 
 		coresight-id = <8>;
 		coresight-name = "coresight-funnel-mmss";
@@ -122,6 +134,7 @@
 		compatible = "arm,coresight-stm";
 		reg = <0xfc321000 0x1000>,
 		      <0xfa280000 0x180000>;
+		reg-names = "stm-base", "stm-data-base";
 
 		coresight-id = <9>;
 		coresight-name = "coresight-stm";
@@ -134,6 +147,7 @@
 	etm0: etm@fc33c000 {
 		compatible = "arm,coresight-etm";
 		reg = <0xfc33c000 0x1000>;
+		reg-names = "etm0-base";
 
 		coresight-id = <10>;
 		coresight-name = "coresight-etm0";
@@ -141,12 +155,15 @@
 		coresight-outports = <0>;
 		coresight-child-list = <&funnel_kpss>;
 		coresight-child-ports = <0>;
+
 		qcom,pc-save;
+		qcom,round-robin;
 	};
 
 	etm1: etm@fc33d000 {
 		compatible = "arm,coresight-etm";
 		reg = <0xfc33d000 0x1000>;
+		reg-names = "etm1-base";
 
 		coresight-id = <11>;
 		coresight-name = "coresight-etm1";
@@ -154,12 +171,15 @@
 		coresight-outports = <0>;
 		coresight-child-list = <&funnel_kpss>;
 		coresight-child-ports = <1>;
+
 		qcom,pc-save;
+		qcom,round-robin;
 	};
 
 	etm2: etm@fc33e000 {
 		compatible = "arm,coresight-etm";
 		reg = <0xfc33e000 0x1000>;
+		reg-names = "etm2-base";
 
 		coresight-id = <12>;
 		coresight-name = "coresight-etm2";
@@ -167,12 +187,15 @@
 		coresight-outports = <0>;
 		coresight-child-list = <&funnel_kpss>;
 		coresight-child-ports = <2>;
+
 		qcom,pc-save;
+		qcom,round-robin;
 	};
 
 	etm3: etm@fc33f000 {
 		compatible = "arm,coresight-etm";
 		reg = <0xfc33f000 0x1000>;
+		reg-names = "etm3-base";
 
 		coresight-id = <13>;
 		coresight-name = "coresight-etm3";
@@ -180,15 +203,160 @@
 		coresight-outports = <0>;
 		coresight-child-list = <&funnel_kpss>;
 		coresight-child-ports = <3>;
+
 		qcom,pc-save;
+		qcom,round-robin;
 	};
 
 	csr: csr@fc302000 {
 		compatible = "qcom,coresight-csr";
 		reg = <0xfc302000 0x1000>;
+		reg-names = "csr-base";
 
 		coresight-id = <14>;
 		coresight-name = "coresight-csr";
 		coresight-nr-inports = <0>;
+
+		qcom,blk-size = <3>;
+	};
+
+	cti0: cti@fc308000 {
+		compatible = "arm,coresight-cti";
+		reg = <0xfc308000 0x1000>;
+		reg-names = "cti0-base";
+
+		coresight-id = <15>;
+		coresight-name = "coresight-cti0";
+		coresight-nr-inports = <0>;
+	};
+
+	cti1: cti@fc309000 {
+		compatible = "arm,coresight-cti";
+		reg = <0xfc309000 0x1000>;
+		reg-names = "cti1-base";
+
+		coresight-id = <16>;
+		coresight-name = "coresight-cti1";
+		coresight-nr-inports = <0>;
+	};
+
+	cti2: cti@fc30a000 {
+		compatible = "arm,coresight-cti";
+		reg = <0xfc30a000 0x1000>;
+		reg-names = "cti2-base";
+
+		coresight-id = <17>;
+		coresight-name = "coresight-cti2";
+		coresight-nr-inports = <0>;
+	};
+
+	cti3: cti@fc30b000 {
+		compatible = "arm,coresight-cti";
+		reg = <0xfc30b000 0x1000>;
+		reg-names = "cti3-base";
+
+		coresight-id = <18>;
+		coresight-name = "coresight-cti3";
+		coresight-nr-inports = <0>;
+	};
+
+	cti4: cti@fc30c000 {
+		compatible = "arm,coresight-cti";
+		reg = <0xfc30c000 0x1000>;
+		reg-names = "cti4-base";
+
+		coresight-id = <19>;
+		coresight-name = "coresight-cti4";
+		coresight-nr-inports = <0>;
+	};
+
+	cti5: cti@fc30d000 {
+		compatible = "arm,coresight-cti";
+		reg = <0xfc30d000 0x1000>;
+		reg-names = "cti5-base";
+
+		coresight-id = <20>;
+		coresight-name = "coresight-cti5";
+		coresight-nr-inports = <0>;
+	};
+
+	cti6: cti@fc30e000 {
+		compatible = "arm,coresight-cti";
+		reg = <0xfc30e000 0x1000>;
+		reg-names = "cti6-base";
+
+		coresight-id = <21>;
+		coresight-name = "coresight-cti6";
+		coresight-nr-inports = <0>;
+	};
+
+	cti7: cti@fc30f000 {
+		compatible = "arm,coresight-cti";
+		reg = <0xfc30f000 0x1000>;
+		reg-names = "cti7-base";
+
+		coresight-id = <22>;
+		coresight-name = "coresight-cti7";
+		coresight-nr-inports = <0>;
+	};
+
+	cti8: cti@fc310000 {
+		compatible = "arm,coresight-cti";
+		reg = <0xfc310000 0x1000>;
+		reg-names = "cti8-base";
+
+		coresight-id = <23>;
+		coresight-name = "coresight-cti8";
+		coresight-nr-inports = <0>;
+	};
+
+	cti_l2: cti@fc340000 {
+		compatible = "arm,coresight-cti";
+		reg = <0xfc340000 0x1000>;
+		reg-names = "cti-l2-base";
+
+		coresight-id = <24>;
+		coresight-name = "coresight-cti-l2";
+		coresight-nr-inports = <0>;
+	};
+
+	cti_cpu0: cti@fc341000 {
+		compatible = "arm,coresight-cti";
+		reg = <0xfc341000 0x1000>;
+		reg-names = "cti-cpu0-base";
+
+		coresight-id = <25>;
+		coresight-name = "coresight-cti-cpu0";
+		coresight-nr-inports = <0>;
+	};
+
+	cti_cpu1: cti@fc342000 {
+		compatible = "arm,coresight-cti";
+		reg = <0xfc342000 0x1000>;
+		reg-names = "cti-cpu1-base";
+
+		coresight-id = <26>;
+		coresight-name = "coresight-cti-cpu1";
+		coresight-nr-inports = <0>;
+	};
+
+	cti_cpu2: cti@fc343000 {
+		compatible = "arm,coresight-cti";
+		reg = <0xfc343000 0x1000>;
+		reg-names = "cti-cpu2-base";
+
+		coresight-id = <27>;
+		coresight-name = "coresight-cti-cpu2";
+		coresight-nr-inports = <0>;
+	};
+
+	cti_cpu3: cti@fc344000 {
+		compatible = "arm,coresight-cti";
+		reg = <0xfc344000 0x1000>;
+		reg-names = "cti-cpu3-base";
+
+		coresight-id = <28>;
+		coresight-name = "coresight-cti-cpu3";
+		coresight-nr-inports = <0>;
 	};
 };
diff --git a/arch/arm/boot/dts/msm8974-fluid.dts b/arch/arm/boot/dts/msm8974-fluid.dts
deleted file mode 100644
index b014e14..0000000
--- a/arch/arm/boot/dts/msm8974-fluid.dts
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-/dts-v1/;
-
-/include/ "msm8974.dtsi"
-/include/ "msm8974-fluid.dtsi"
-
-/ {
-	model = "Qualcomm MSM 8974 FLUID";
-	compatible = "qcom,msm8974-fluid", "qcom,msm8974";
-	qcom,msm-id = <126 3 0>;
-};
diff --git a/arch/arm/boot/dts/msm8974-fluid.dtsi b/arch/arm/boot/dts/msm8974-fluid.dtsi
index a027a1e..92a6e01 100644
--- a/arch/arm/boot/dts/msm8974-fluid.dtsi
+++ b/arch/arm/boot/dts/msm8974-fluid.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -11,7 +11,7 @@
  */
 
 /include/ "dsi-panel-toshiba-720p-video.dtsi"
-/include/ "msm8974-camera-sensor.dtsi"
+/include/ "msm8974-camera-sensor-fluid.dtsi"
 /include/ "msm8974-leds.dtsi"
 
 / {
@@ -19,10 +19,8 @@
 		status = "ok";
 	};
 
-	qcom,mdss_dsi@fd922800 {
-		qcom,mdss_dsi_toshiba_720p_video {
-			status = "ok";
-		};
+	qcom,mdss_dsi_toshiba_720p_video {
+		status = "ok";
 	};
 
 	qcom,hdmi_tx@fd922100 {
@@ -42,6 +40,7 @@
 			atmel,panel-coords = <0  0 760 1424>;
 			atmel,display-coords = <0 0 720 1280>;
 			atmel,i2c-pull-up;
+			atmel,no-force-update;
 			atmel,cfg_1 {
 				atmel,family-id = <0x82>;
 				atmel,variant-id = <0x19>;
@@ -51,16 +50,16 @@
 					/* Object 6, Instance = 0 */
 					00 00 00 00 00 00
 					/* Object 38, Instance = 0 */
-					15 00 02 10 08 0C 00 00
+					15 01 00 03 0A 0C 00 00
 					/* Object 7, Instance = 0 */
-					FF FF 32 03
+					20 08 32 03
 					/* Object 8, Instance = 0 */
-					0F 00 0A 0A 00 00 0A 00 00 00
+					0F 00 0A 0A 00 00 0A 0A 00 00
 					/* Object 9, Instance = 0 */
-					83 00 00 18 0E 00 70 32 02 01
-					00 03 01 01 05 0A 0A 0A 90 05
-					F8 02 00 00 0F 0F 00 00 48 2D
-					07 0C 00 00 00 00
+					83 00 00 18 0E 00 70 46 02 01
+					00 0A 03 31 04 05 0A 0A 90 05
+					F8 02 05 F1 F1 0F 00 00 08 2D
+					12 06 00 00 00 01
 					/* Object 15, Instance = 0 */
 					00 00 00 00 00 00 00 00 00 00
 					00
@@ -77,7 +76,7 @@
 					/* Object 40, Instance = 0 */
 					00 00 00 00 00
 					/* Object 42, Instance = 0 */
-					00 00 00 00 00 00 00 00 00 00
+					33 1E 19 10 80 00 00 00 FF 00
 					/* Object 46, Instance = 0 */
 					00 00 10 10 00 00 03 00 00 01
 					/* Object 47, Instance = 0 */
@@ -86,7 +85,7 @@
 					/* Object 55, Instance = 0 */
 					00 00 00 00 00 00
 					/* Object 56, Instance = 0 */
-					03 00 01 18 05 05 05 05 05 05
+					00 00 00 18 05 05 05 05 05 05
 					05 05 05 05 05 05 05 05 05 05
 					05 05 05 05 05 05 05 05 00 00
 					00 00 00 00 00 00 00 00 00 00
@@ -95,15 +94,13 @@
 					00 00 00
 					/* Object 61, Instance = 0 */
 					00 00 00 00 00
-					/* Object 61, Instance = 1 */
-					00 00 00 00 00
 					/* Object 62, Instance = 0 */
-					7F 03 00 16 00 00 00 00 00 00
-					04 08 10 18 05 00 0A 05 05 50
-					14 19 34 1A 64 00 00 04 40 00
-					00 00 00 00 30 32 02 00 01 00
-					05 00 00 00 00 00 00 00 00 00
-					00 00 0C 00
+					01 2A 00 16 00 00 00 00 0B 01
+					02 03 04 08 00 00 08 10 18 05
+					00 0A 05 05 50 14 19 34 1A 7F
+					00 00 00 00 00 00 00 00 00 30
+					05 02 00 01 00 05 00 00 00 00
+					00 00 00 00
 					];
 			};
 		};
@@ -122,7 +119,39 @@
 			avcc_12-supply = <&pm8941_l2>;
 			smps3a-supply = <&pm8941_s3>;
 			vdda-supply = <&pm8941_l12>;
+			qcom,hdmi-tx-map = <&mdss_hdmi_tx>;
 		};
+
+		isa1200@48 {
+			status = "okay";
+			reg = <0x48>;
+			vcc_i2c-supply = <&pm8941_s3>;
+			compatible = "imagis,isa1200";
+			label = "vibrator";
+			imagis,chip-en;
+			imagis,need-pwm-clk;
+			imagis,ext-clk-en;
+			imagis,hap-en-gpio = <&msmgpio 86 0x00>;
+			imagis,max-timeout = <15000>;
+			imagis,pwm-div = <256>;
+			imagis,mode-ctrl = <2>;
+			imagis,regulator {
+				regulator-name = "vcc_i2c";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-max-microamp = <9360>;
+			};
+		};
+	};
+
+	gen-vkeys {
+		compatible = "qcom,gen-vkeys";
+		label = "atmel_mxt_ts";
+		qcom,disp-maxx = <720>;
+		qcom,disp-maxy = <1280>;
+		qcom,panel-maxx = <760>;
+		qcom,panel-maxy = <1424>;
+		qcom,key-codes = <158 139 102 217>;
 	};
 
 	gpio_keys {
@@ -176,6 +205,15 @@
 	};
 };
 
+&slim_msm {
+	taiko_codec {
+		qcom,cdc-micbias1-ext-cap;
+		qcom,cdc-micbias2-ext-cap;
+		qcom,cdc-micbias3-ext-cap;
+		qcom,cdc-micbias4-ext-cap;
+	};
+};
+
 &spmi_bus {
 	qcom,pm8941@1 {
 		qcom,leds@d800 {
@@ -186,7 +224,7 @@
 				linux,default-trigger = "bkl-trigger";
 				qcom,cs-out-en;
 				qcom,op-fdbck;
-				qcom,default-state = "off";
+				qcom,default-state = "on";
 				qcom,max-current = <25>;
 				qcom,ctrl-delay-us = <0>;
 				qcom,boost-curr-lim = <3>;
@@ -257,11 +295,13 @@
 	qcom,otg-capability;
 };
 
+&pm8941_bms {
+	status = "ok";
+};
+
 &pm8941_chg {
 	status = "ok";
 
-	qcom,chg-charging-disabled;
-
 	qcom,chg-chgr@1000 {
 		status = "ok";
 	};
@@ -343,7 +383,7 @@
 		qcom,pull = <5>;		/* QPNP_PIN_PULL_NO */
 		qcom,vin-sel = <2>;		/* QPNP_PIN_VIN2 */
 		qcom,out-strength = <2>;	/* QPNP_PIN_OUT_STRENGTH_MED */
-		qcom,src-select = <0>;		/* QPNP_PIN_SEL_FUNC_CONSTANT */
+		qcom,src-sel = <0>;		/* QPNP_PIN_SEL_FUNC_CONSTANT */
 		qcom,master-en = <1>;
 	};
 
@@ -364,6 +404,13 @@
 	};
 
 	gpio@cf00 { /* GPIO 16 */
+		qcom,mode = <1>;
+		qcom,output-type = <0>;
+		qcom,pull = <5>;
+		qcom,vin-sel = <2>;
+		qcom,out-strength = <3>;
+		qcom,src-sel = <2>;
+		qcom,master-en = <1>;
 	};
 
 	gpio@d000 { /* GPIO 17 */
@@ -475,9 +522,9 @@
 	mpp@a700 { /* MPP 8 */
 		qcom,mode = <1>; /* DIG_OUT */
 		qcom,output-type = <0>; /* CMOS */
-		qcom,pull-up = <0>;
+		qcom,pull = <0>;
 		qcom,vin-sel = <2>; /* PM8941_S3 1.8V > 1.6V */
-		qcom,src-select = <0>; /* CONSTANT */
+		qcom,src-sel = <0>; /* CONSTANT */
 		qcom,master-en = <1>; /* ENABLE MPP */
 	};
 };
diff --git a/arch/arm/boot/dts/msm8974-gpu.dtsi b/arch/arm/boot/dts/msm8974-gpu.dtsi
index 480a034..ceba72f 100644
--- a/arch/arm/boot/dts/msm8974-gpu.dtsi
+++ b/arch/arm/boot/dts/msm8974-gpu.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -10,7 +10,7 @@
  * GNU General Public License for more details.
  */
 / {
-	qcom,kgsl-3d0@fdb00000 {
+	msm_gpu: qcom,kgsl-3d0@fdb00000 {
 		label = "kgsl-3d0";
 		compatible = "qcom,kgsl-3d0", "qcom,kgsl-3d";
 		reg = <0xfdb00000 0x10000
@@ -22,22 +22,25 @@
 
 		qcom,chipid = <0x03030000>;
 
-		qcom,initial-pwrlevel = <1>;
+		qcom,initial-pwrlevel = <2>;
+		qcom,step-pwrlevel = <2>;
 
-		qcom,idle-timeout = <83>; //<HZ/12>
+		qcom,idle-timeout = <8>; //<HZ/12>
 		qcom,nap-allowed = <1>;
 		qcom,strtstp-sleepwake;
 		qcom,clk-map = <0x0000006>; //KGSL_CLK_CORE | KGSL_CLK_IFACE
 
 		/* Bus Scale Settings */
 		qcom,msm-bus,name = "grp3d";
-		qcom,msm-bus,num-cases = <4>;
+		qcom,msm-bus,num-cases = <6>;
 		qcom,msm-bus,active-only = <0>;
 		qcom,msm-bus,num-paths = <2>;
 		qcom,msm-bus,vectors-KBps =
 				<26 512 0 0>, <89 604 0 0>,
-				<26 512 0 1600000>, <89 604 0 3000000>,
+				<26 512 0 2200000>, <89 604 0 3000000>,
+				<26 512 0 4000000>, <89 604 0 3000000>,
 				<26 512 0 4000000>, <89 604 0 4500000>,
+				<26 512 0 6400000>, <89 604 0 4500000>,
 				<26 512 0 6400000>, <89 604 0 7600000>;
 
 		/* GDSC oxili regulators */
@@ -58,26 +61,40 @@
 			qcom,gpu-pwrlevel@0 {
 				reg = <0>;
 				qcom,gpu-freq = <450000000>;
-				qcom,bus-freq = <3>;
+				qcom,bus-freq = <5>;
 				qcom,io-fraction = <0>;
 			};
 
 			qcom,gpu-pwrlevel@1 {
 				reg = <1>;
 				qcom,gpu-freq = <300000000>;
-				qcom,bus-freq = <2>;
+				qcom,bus-freq = <4>;
 				qcom,io-fraction = <33>;
 			};
 
 			qcom,gpu-pwrlevel@2 {
 				reg = <2>;
+				qcom,gpu-freq = <300000000>;
+				qcom,bus-freq = <3>;
+				qcom,io-fraction = <33>;
+			};
+
+			qcom,gpu-pwrlevel@3 {
+				reg = <3>;
+				qcom,gpu-freq = <200000000>;
+				qcom,bus-freq = <2>;
+				qcom,io-fraction = <100>;
+			};
+
+			qcom,gpu-pwrlevel@4 {
+				reg = <4>;
 				qcom,gpu-freq = <200000000>;
 				qcom,bus-freq = <1>;
 				qcom,io-fraction = <100>;
 			};
 
-			qcom,gpu-pwrlevel@3 {
-				reg = <3>;
+			qcom,gpu-pwrlevel@5 {
+				reg = <5>;
 				qcom,gpu-freq = <27000000>;
 				qcom,bus-freq = <0>;
 				qcom,io-fraction = <0>;
diff --git a/arch/arm/boot/dts/msm8974-iommu.dtsi b/arch/arm/boot/dts/msm8974-iommu.dtsi
deleted file mode 100755
index 184826e..0000000
--- a/arch/arm/boot/dts/msm8974-iommu.dtsi
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/ "msm-iommu.dtsi"
-
-&jpeg_iommu {
-	status = "ok";
-};
-
-&mdp_iommu {
-	status = "ok";
-};
-
-&venus_iommu {
-	status = "ok";
-};
-
-&kgsl_iommu {
-	status = "ok";
-};
-
-&vfe_iommu {
-	status = "ok";
-};
diff --git a/arch/arm/boot/dts/msm8974-ion.dtsi b/arch/arm/boot/dts/msm8974-ion.dtsi
index 01e200a..dfa22c1 100644
--- a/arch/arm/boot/dts/msm8974-ion.dtsi
+++ b/arch/arm/boot/dts/msm8974-ion.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -24,34 +24,19 @@
 			compatible = "qcom,msm-ion-reserve";
 			reg = <8>;
 			qcom,heap-align = <0x1000>;
-			qcom,memory-reservation-type = "EBI1"; /* reserve EBI memory */
-			qcom,memory-reservation-size = <0x7800000>;
-		};
-
-		qcom,ion-heap@23 { /* PIL1 HEAP */
-			compatible = "qcom,msm-ion-reserve";
-			reg = <23>;
-			qcom,heap-align = <0x10000>;
-			qcom,memory-fixed = <0xd200000 0x2800000>;
+			linux,contiguous-region = <&secure_mem>;
 		};
 
 		qcom,ion-heap@25 { /* IOMMU HEAP */
 			reg = <25>;
 		};
 
-		qcom,ion-heap@26 { /* PIL2 HEAP */
-			compatible = "qcom,msm-ion-reserve";
-			reg = <26>;
-			qcom,heap-align = <0x10000>;
-			qcom,memory-fixed = <0x8400000 0x4e00000>;
-		};
-
 		qcom,ion-heap@27 { /* QSECOM HEAP */
 			compatible = "qcom,msm-ion-reserve";
 			reg = <27>;
 			qcom,heap-align = <0x1000>;
 			qcom,memory-reservation-type = "EBI1"; /* reserve EBI memory */
-			qcom,memory-reservation-size = <0x780000>;
+			qcom,memory-reservation-size = <0x1100000>;
 		};
 
 		qcom,ion-heap@28 { /* AUDIO HEAP */
diff --git a/arch/arm/boot/dts/msm8974-leds.dtsi b/arch/arm/boot/dts/msm8974-leds.dtsi
index 8ba3470..befd206 100644
--- a/arch/arm/boot/dts/msm8974-leds.dtsi
+++ b/arch/arm/boot/dts/msm8974-leds.dtsi
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -39,6 +39,17 @@
 				qcom,id = <4>;
 				linux,default-trigger = "battery-full";
 			};
+
+			qcom,rgb_2 {
+				label = "rgb";
+				linux,name = "led:rgb_blue";
+				qcom,mode = <0>;
+				qcom,pwm-channel = <4>;
+				qcom,pwm-us = <1000>;
+				qcom,max-current = <12>;
+				qcom,id = <5>;
+				status = "disabled";
+			};
 		};
 
 		qcom,leds@d100 {
diff --git a/arch/arm/boot/dts/msm8974-liquid.dts b/arch/arm/boot/dts/msm8974-liquid.dts
deleted file mode 100644
index ef38036..0000000
--- a/arch/arm/boot/dts/msm8974-liquid.dts
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-/dts-v1/;
-
-/include/ "msm8974.dtsi"
-/include/ "msm8974-liquid.dtsi"
-
-/ {
-	model = "Qualcomm MSM 8974 LIQUID";
-	compatible = "qcom,msm8974-liquid", "qcom,msm8974";
-	qcom,msm-id = <126 9 0>;
-};
diff --git a/arch/arm/boot/dts/msm8974-liquid.dtsi b/arch/arm/boot/dts/msm8974-liquid.dtsi
index 81f8c09..6e2719b 100644
--- a/arch/arm/boot/dts/msm8974-liquid.dtsi
+++ b/arch/arm/boot/dts/msm8974-liquid.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -26,6 +26,8 @@
 		battery@b {
 			compatible = "ti,bq28400-battery";
 			reg = <0xb>;
+			ti,temp-cold = <2>; /* degree celsius */
+			ti,temp-hot = <43>; /* degree celsius */
 		};
 
 		charger@2b {
@@ -71,10 +73,6 @@
 		};
 	};
 
-	qcom,mdss_mdp@fd900000 {
-		qcom,memory-reservation-size = <0x1000000>; /* size 16MB */
-	};
-
 	qcom,hdmi_tx@fd922100 {
 		status = "ok";
 
@@ -121,6 +119,7 @@
 			atmel,panel-coords = <0 0 1080 1920>;
 			atmel,display-coords = <0 0 1080 1920>;
 			atmel,i2c-pull-up;
+			atmel,no-force-update;
 			atmel,cfg_1 {
 				atmel,family-id = <0xa2>;
 				atmel,variant-id = <0x00>;
@@ -200,6 +199,90 @@
 					00 00
 					];
 			};
+			atmel,cfg_2 {
+				atmel,family-id = <0xa2>;
+				atmel,variant-id = <0x00>;
+				atmel,version = <0x11>;
+				atmel,build = <0xaa>;
+				atmel,config = [
+					/* Object 6, Instance = 0 */
+					00 00 00 00 00 00
+					/* Object 38, Instance = 0 */
+					19 01 00 0D 02 0D 00 00 00 00
+					00 00 00 00 00 00 00 00 00 00
+					00 00 00 00 00 00 00 00 00 00
+					00 00 00 00 00 00 00 00 00 00
+					00 00 00 00 00 00 00 00 00 00
+					00 00 00 00 00 00 00 00 00 00
+					00 00 00 00
+					/* Object 7, Instance = 0 */
+					20 08 32 C3
+					/* Object 8, Instance = 0 */
+					41 00 14 14 00 00 00 01 00 00
+					/* Object 9, Instance = 0 */
+					8F 00 00 20 34 00 87 4B 02 03
+					00 05 03 40 0A 14 14 0A 80 07
+					38 04 03 03 03 03 08 28 02 3C
+					0F 0F 2E 33 01 00
+					/* Object 15, Instance = 0 */
+					00 00 00 00 00 00 00 00 00 00
+					00
+					/* Object 18, Instance = 0 */
+					04 00
+					/* Object 24, Instance = 0 */
+					00 00 00 00 00 00 00 00 00 00
+					00 00 00 00 00 00 00 00 00
+					/* Object 25, Instance = 0 */
+					00 00 54 6F F0 55 00 00 00 00
+					00 00 00 00 00
+					/* Object 27, Instance = 0 */
+					00 00 00 00 00 00 00
+					/* Object 40, Instance = 0 */
+					00 14 14 14 14
+					/* Object 42, Instance = 0 */
+					23 32 14 14 80 00 0A 00 05 05
+					/* Object 43, Instance = 0 */
+					08 00 01 01 91 00 80 00 00 00
+					00 00
+					/* Object 46, Instance = 0 */
+					00 00 18 18 00 00 01 00 00 0F
+					0A
+					/* Object 47, Instance = 0 */
+					00 14 28 02 05 28 01 78 03 10
+					00 00 0C 00 00 00 00 00 00 00
+					00 00
+					/* Object 55, Instance = 0 */
+					00 00 00 00 00 00 00
+					/* Object 56, Instance = 0 */
+					01 00 00 30 13 14 14 14 15 15
+					15 15 15 15 15 16 16 16 16 16
+					16 16 16 16 16 15 14 14 14 14
+					15 14 14 14 14 13 03 20 03 01
+					0A 04 00 00 00 00 00 00 00 00
+					1A
+					/* Object 57, Instance = 0 */
+					00 00 00
+					/* Object 61, Instance = 0 */
+					00 00 00 00 00
+					/* Object 62, Instance = 0 */
+					00 03 00 07 02 00 00 00 00 00
+					0F 17 23 2D 05 00 05 03 03 69
+					14 14 34 11 64 06 06 04 40 00
+					00 00 00 00 69 3C 02 04 01 00
+					0A 14 14 03 03 03 03 00 00 00
+					00 64 1E 01 00 00 00 00 00 00
+					00 00 00 00 00 00 00 00 00 00
+					00 00 00 00
+					/* Object 63, Instance = 0 */
+					00 00 00 00 00 00 00 00 00 00
+					00 00
+					/* Object 65, Instance = 0 */
+					00 00 00 00 00 00 00 00 00 00
+					00 00 00 00 00 00 00
+					/* Object 66, Instance = 0 */
+					00 00 00 00 00
+					];
+			};
 		};
 	};
 
@@ -211,6 +294,11 @@
 		enable-active-high;
 	};
 
+	bt_ar3002 {
+		compatible = "qca,ar3002";
+		qca,bt-reset-gpio = <&pm8941_gpios 34 0>;
+	};
+
 	sound {
 		qcom,model = "msm8974-taiko-liquid-snd-card";
 
@@ -221,30 +309,34 @@
 			"Lineout_3 amp", "LINEOUT3",
 			"Lineout_2 amp", "LINEOUT2",
 			"Lineout_4 amp", "LINEOUT4",
-			"AMIC1", "MIC BIAS1 Internal1",
-			"MIC BIAS1 Internal1", "Handset Mic",
+			"AMIC1", "MIC BIAS4 External",
+			"MIC BIAS4 External", "Analog Mic4",
 			"AMIC2", "MIC BIAS2 External",
 			"MIC BIAS2 External", "Headset Mic",
 			"AMIC3", "MIC BIAS2 External",
 			"MIC BIAS2 External", "ANCRight Headset Mic",
 			"AMIC4", "MIC BIAS2 External",
 			"MIC BIAS2 External", "ANCLeft Headset Mic",
+			"AMIC5", "MIC BIAS1 External",
+			"MIC BIAS1 External", "Analog Mic6",
+			"AMIC6", "MIC BIAS1 External",
+			"MIC BIAS1 External", "Analog Mic7",
 			"DMIC1", "MIC BIAS3 External",
-			"MIC BIAS1 External", "Digital Mic1",
+			"MIC BIAS3 External", "Digital Mic1",
 			"DMIC2", "MIC BIAS3 External",
-			"MIC BIAS1 External", "Digital Mic2",
+			"MIC BIAS3 External", "Digital Mic2",
 			"DMIC3", "MIC BIAS2 External",
-			"MIC BIAS3 External", "Digital Mic3",
+			"MIC BIAS2 External", "Digital Mic3",
 			"DMIC4", "MIC BIAS3 External",
 			"MIC BIAS3 External", "Digital Mic4",
 			"DMIC5", "MIC BIAS2 External",
-			"MIC BIAS4 External", "Digital Mic5",
+			"MIC BIAS2 External", "Digital Mic5",
 			"DMIC6", "MIC BIAS2 External",
-			"MIC BIAS4 External", "Digital Mic6";
+			"MIC BIAS2 External", "Digital Mic6";
 
 		qcom,ext-spk-amp-supply = <&ext_5v>;
 		qcom,ext-spk-amp-gpio = <&pm8841_mpps 1 0>;
-
+		qcom,dock-plug-det-irq = <&pm8841_mpps 2 0>;
 		qcom,hdmi-audio-rx;
 	};
 
@@ -262,8 +354,8 @@
 		hsic@f9a00000 {
 			compatible = "qcom,hsic-host";
 			reg = <0xf9a00000 0x400>;
-			interrupts = <0 136 0>;
-			interrupt-names = "core_irq";
+			interrupts = <0 136 0>, <0 148 0>;
+			interrupt-names = "core_irq", "async_irq";
 			HSIC_VDDCX-supply = <&pm8841_s2>;
 			HSIC_GDSC-supply = <&gdsc_usb_hsic>;
 			hsic,strobe-gpio = <&msmgpio 144 0x00>;
@@ -275,8 +367,20 @@
 	};
 };
 
+&mdss_fb0 {
+	qcom,memory-reservation-size = <0x1000000>; /* size 16MB */
+};
+
+&uart7 {
+	status = "ok";
+	qcom,tx-gpio = <&msmgpio 41 0x00>;
+	qcom,rx-gpio = <&msmgpio 42 0x00>;
+	qcom,cts-gpio = <&msmgpio 43 0x00>;
+	qcom,rfr-gpio = <&msmgpio 44 0x00>;
+};
+
 &usb3 {
-	qcom,charging-disabled;
+	qcom,otg-capability;
 };
 
 &pm8941_mvs1 {
@@ -541,6 +645,11 @@
 	};
 
 	mpp@a100 { /* MPP 2 */
+		/* DOCK_PLUG_DET speakers+docking detect irq*/
+		qcom,mode = <0>; /* DIG_IN */
+		qcom,vin-sel = <2>; /* S3A 1.8v */
+		qcom,src-sel = <0>; /* CONSTANT */
+		qcom,master-en = <1>; /* ENABLE MPP */
 	};
 
 	mpp@a200 { /* HDMI_MUX_SEL MPP 3*/
@@ -562,6 +671,13 @@
 	};
 };
 
+&slim_msm {
+	taiko_codec {
+		qcom,cdc-micbias2-ext-cap;
+		qcom,cdc-micbias3-ext-cap;
+	};
+};
+
 &spi_epm {
 	epm-adc@0 {
 		compatible = "cy,epm-adc-cy8c5568lti-114";
@@ -580,3 +696,45 @@
 		qcom,channel-type = <0xf0000000>;
 	};
 };
+
+&spmi_bus {
+	qcom,pm8941@1 {
+		qcom,leds@d000 {
+			qcom,rgb_2 {
+				status = "ok";
+				qcom,default-state = "on";
+				qcom,turn-off-delay-ms = <1000>;
+			};
+		};
+	};
+};
+
+&pm8941_chg {
+	status = "ok";
+
+	qcom,chg-charging-disabled;
+
+	qcom,chg-chgr@1000 {
+		status = "ok";
+	};
+
+	qcom,chg-buck@1100 {
+		status = "ok";
+	};
+
+	qcom,chg-usb-chgpth@1300 {
+		status = "ok";
+	};
+
+	qcom,chg-dc-chgpth@1400 {
+		status = "ok";
+	};
+
+	qcom,chg-boost@1500 {
+		status = "ok";
+	};
+
+	qcom,chg-misc@1600 {
+		status = "ok";
+	};
+};
diff --git a/arch/arm/boot/dts/msm8974-mdss.dtsi b/arch/arm/boot/dts/msm8974-mdss.dtsi
index d0cec3a..0b95419 100644
--- a/arch/arm/boot/dts/msm8974-mdss.dtsi
+++ b/arch/arm/boot/dts/msm8974-mdss.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -11,27 +11,86 @@
  */
 
 / {
-	qcom,mdss_mdp@fd900000 {
+	mdss_mdp: qcom,mdss_mdp@fd900000 {
 		compatible = "qcom,mdss_mdp";
 		reg = <0xfd900000 0x22100>,
 			<0xfd924000 0x1000>;
 		reg-names = "mdp_phys", "vbif_phys";
 		interrupts = <0 72 0>;
 		vdd-supply = <&gdsc_mdss>;
-		qcom,memory-reservation-type = "EBI1"; /* reserve EBI memory */
-		qcom,memory-reservation-size = <0x800000>; /* size 8MB */
+
+		qcom,mdss-pipe-vig-off = <0x00001200 0x00001600
+					       0x00001A00>;
+		qcom,mdss-pipe-rgb-off = <0x00001E00 0x00002200
+					       0x00002600>;
+		qcom,mdss-pipe-dma-off = <0x00002A00 0x00002E00>;
+		qcom,mdss-pipe-vig-fetch-id = <1 4 7>;
+		qcom,mdss-pipe-rgb-fetch-id = <16 17 18>;
+		qcom,mdss-pipe-dma-fetch-id = <10 13>;
+
+		qcom,mdss-ctl-off = <0x00000600 0x00000700 0x00000800
+				     0x00000900 0x0000A00>;
+		qcom,mdss-mixer-intf-off = <0x00003200 0x00003600
+					    0x00003A00>;
+		qcom,mdss-mixer-wb-off = <0x00003E00 0x00004200>;
+		qcom,mdss-dspp-off = <0x00004600 0x00004A00 0x00004E00>;
+		qcom,mdss-wb-off = <0x00011100 0x00013100 0x00015100
+				    0x00017100 0x00019100>;
+		qcom,mdss-intf-off = <0x00021100 0x00021300
+					   0x00021500 0x00021700>;
+
+		qcom,vbif-settings = <0x0004 0x00000001>,
+				     <0x00D8 0x00000707>,
+				     <0x00F0 0x00000030>,
+				     <0x0124 0x00000001>,
+				     <0x0178 0x00000FFF>,
+				     <0x017C 0x0FFF0FFF>,
+				     <0x0160 0x22222222>,
+				     <0x0164 0x00002222>;
+		qcom,mdp-settings = <0x02E0 0x000000AA>,
+				    <0x02E4 0x00000055>;
+
+		mdss_fb0: qcom,mdss_fb_primary {
+			cell-index = <0>;
+			compatible = "qcom,mdss-fb";
+			qcom,memory-reservation-type = "EBI1";
+			qcom,memory-reservation-size = <0x800000>;
+		};
+
+		mdss_fb1: qcom,mdss_fb_external {
+			cell-index = <1>;
+			compatible = "qcom,mdss-fb";
+		};
+
+		mdss_fb2: qcom,mdss_fb_wfd {
+			cell-index = <2>;
+			compatible = "qcom,mdss-fb";
+		};
 	};
 
-	mdss_dsi: qcom,mdss_dsi@fd922800 {
-		compatible = "qcom,msm-mdss-dsi";
-		reg = <0xfd922800 0x600>,
-			<0xfd8c2000 0x01000>;
+	mdss_dsi0: qcom,mdss_dsi@fd922800 {
+		compatible = "qcom,mdss-dsi-ctrl";
+		label = "MDSS DSI CTRL->0";
+		cell-index = <0>;
+		reg = <0xfd922800 0x600>;
 		vdd-supply = <&pm8941_l22>;
 		vdd_io-supply = <&pm8941_l12>;
 		vreg-supply = <&pm8941_l2>;
+		qcom,mdss-fb-map = <&mdss_fb0>;
 	};
 
-	qcom,hdmi_tx@fd922100 {
+	mdss_dsi1: qcom,mdss_dsi@fd922e00 {
+		compatible = "qcom,mdss-dsi-ctrl";
+		label = "MDSS DSI CTRL->1";
+		cell-index = <1>;
+		reg = <0xfd922e00 0x600>;
+		vdd-supply = <&pm8941_l22>;
+		vdd_io-supply = <&pm8941_l12>;
+		vreg-supply = <&pm8941_l2>;
+		qcom,mdss-fb-map = <&mdss_fb0>;
+	};
+
+	mdss_hdmi_tx: qcom,hdmi_tx@fd922100 {
 		cell-index = <0>;
 		compatible = "qcom,hdmi-tx";
 		reg =	<0xfd922100 0x35C>,
@@ -53,7 +112,7 @@
 		qcom,hdmi-tx-ddc-clk = <&msmgpio 32 0>;
 		qcom,hdmi-tx-ddc-data = <&msmgpio 33 0>;
 		qcom,hdmi-tx-hpd = <&msmgpio 34 0>;
-
+		qcom,mdss-fb-map = <&mdss_fb1>;
 		qcom,msm-hdmi-audio-rx {
 			compatible = "qcom,msm-hdmi-audio-codec-rx";
 		};
@@ -63,6 +122,7 @@
 		compatible = "qcom,mdss_wb";
 		qcom,mdss_pan_res = <1920 1080>;
 		qcom,mdss_pan_bpp = <24>;
+		qcom,mdss-fb-map = <&mdss_fb2>;
 	};
 
 	mdss_edp: qcom,mdss_edp@fd923400 {
@@ -76,5 +136,6 @@
 		qcom,panel-lpg-channel = <7>; /* LPG Channel 8 */
 		qcom,panel-pwm-period = <53>;
 		status = "disable";
+		qcom,mdss-fb-map = <&mdss_fb0>;
 	};
 };
diff --git a/arch/arm/boot/dts/msm8974-mtp.dts b/arch/arm/boot/dts/msm8974-mtp.dts
deleted file mode 100644
index 9946cf0..0000000
--- a/arch/arm/boot/dts/msm8974-mtp.dts
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-/dts-v1/;
-
-/include/ "msm8974.dtsi"
-/include/ "msm8974-mtp.dtsi"
-
-/ {
-	model = "Qualcomm MSM 8974 MTP";
-	compatible = "qcom,msm8974-mtp", "qcom,msm8974";
-	qcom,msm-id = <126 8 0>;
-};
diff --git a/arch/arm/boot/dts/msm8974-mtp.dtsi b/arch/arm/boot/dts/msm8974-mtp.dtsi
index 48bb5ba..c6935f4 100644
--- a/arch/arm/boot/dts/msm8974-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8974-mtp.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -11,7 +11,7 @@
  */
 
 /include/ "dsi-panel-toshiba-720p-video.dtsi"
-/include/ "msm8974-camera-sensor.dtsi"
+/include/ "msm8974-camera-sensor-cdp-mtp.dtsi"
 /include/ "msm8974-leds.dtsi"
 
 / {
@@ -19,10 +19,8 @@
 		status = "ok";
 	};
 
-	qcom,mdss_dsi@fd922800 {
-		qcom,mdss_dsi_toshiba_720p_video {
-			status = "ok";
-		};
+	qcom,mdss_dsi_toshiba_720p_video {
+		status = "ok";
 	};
 
 	qcom,hdmi_tx@fd922100 {
@@ -42,6 +40,7 @@
 			atmel,panel-coords = <0  0 760 1424>;
 			atmel,display-coords = <0 0 720 1280>;
 			atmel,i2c-pull-up;
+			atmel,no-force-update;
 			atmel,cfg_1 {
 				atmel,family-id = <0x82>;
 				atmel,variant-id = <0x19>;
@@ -51,16 +50,16 @@
 					/* Object 6, Instance = 0 */
 					00 00 00 00 00 00
 					/* Object 38, Instance = 0 */
-					15 00 02 10 08 0C 00 00
+					15 01 00 03 0A 0C 00 00
 					/* Object 7, Instance = 0 */
-					FF FF 32 03
+					20 08 32 03
 					/* Object 8, Instance = 0 */
-					0F 00 0A 0A 00 00 0A 00 00 00
+					0F 00 0A 0A 00 00 0A 0A 00 00
 					/* Object 9, Instance = 0 */
-					83 00 00 18 0E 00 70 32 02 01
-					00 03 01 01 05 0A 0A 0A 90 05
-					F8 02 00 00 0F 0F 00 00 48 2D
-					07 0C 00 00 00 00
+					83 00 00 18 0E 00 70 46 02 01
+					00 0A 03 31 04 05 0A 0A 90 05
+					F8 02 05 F1 F1 0F 00 00 08 2D
+					12 06 00 00 00 01
 					/* Object 15, Instance = 0 */
 					00 00 00 00 00 00 00 00 00 00
 					00
@@ -77,7 +76,7 @@
 					/* Object 40, Instance = 0 */
 					00 00 00 00 00
 					/* Object 42, Instance = 0 */
-					00 00 00 00 00 00 00 00 00 00
+					33 1E 19 10 80 00 00 00 FF 00
 					/* Object 46, Instance = 0 */
 					00 00 10 10 00 00 03 00 00 01
 					/* Object 47, Instance = 0 */
@@ -86,7 +85,7 @@
 					/* Object 55, Instance = 0 */
 					00 00 00 00 00 00
 					/* Object 56, Instance = 0 */
-					03 00 01 18 05 05 05 05 05 05
+					00 00 00 18 05 05 05 05 05 05
 					05 05 05 05 05 05 05 05 05 05
 					05 05 05 05 05 05 05 05 00 00
 					00 00 00 00 00 00 00 00 00 00
@@ -95,20 +94,51 @@
 					00 00 00
 					/* Object 61, Instance = 0 */
 					00 00 00 00 00
-					/* Object 61, Instance = 1 */
-					00 00 00 00 00
 					/* Object 62, Instance = 0 */
-					7F 03 00 16 00 00 00 00 00 00
-					04 08 10 18 05 00 0A 05 05 50
-					14 19 34 1A 64 00 00 04 40 00
-					00 00 00 00 30 32 02 00 01 00
-					05 00 00 00 00 00 00 00 00 00
-					00 00 0C 00
+					01 2A 00 16 00 00 00 00 0B 01
+					02 03 04 08 00 00 08 10 18 05
+					00 0A 05 05 50 14 19 34 1A 7F
+					00 00 00 00 00 00 00 00 00 30
+					05 02 00 01 00 05 00 00 00 00
+					00 00 00 00
 					];
 			};
 		};
 	};
 
+	gen-vkeys {
+		compatible = "qcom,gen-vkeys";
+		label = "atmel_mxt_ts";
+		qcom,disp-maxx = <720>;
+		qcom,disp-maxy = <1280>;
+		qcom,panel-maxx = <760>;
+		qcom,panel-maxy = <1424>;
+		qcom,key-codes = <158 139 102 217>;
+	};
+
+	i2c@f9967000 {
+		isa1200@48 {
+			status = "okay";
+			reg = <0x48>;
+			vcc_i2c-supply = <&pm8941_s3>;
+			compatible = "imagis,isa1200";
+			label = "vibrator";
+			imagis,chip-en;
+			imagis,need-pwm-clk;
+			imagis,ext-clk-en;
+			imagis,hap-en-gpio = <&msmgpio 86 0x00>;
+			imagis,max-timeout = <15000>;
+			imagis,pwm-div = <256>;
+			imagis,mode-ctrl = <2>;
+			imagis,regulator {
+				regulator-name = "vcc_i2c";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-max-microamp = <9360>;
+			};
+		};
+	};
+
 	gpio_keys {
 		compatible = "gpio-keys";
 		input-name = "gpio-keys";
@@ -169,7 +199,7 @@
 				linux,default-trigger = "bkl-trigger";
 				qcom,cs-out-en;
 				qcom,op-fdbck;
-				qcom,default-state = "off";
+				qcom,default-state = "on";
 				qcom,max-current = <25>;
 				qcom,ctrl-delay-us = <0>;
 				qcom,boost-curr-lim = <3>;
@@ -236,6 +266,10 @@
 	qcom,hsusb-otg-otg-control = <2>;
 };
 
+&uart7 {
+	status = "ok";
+};
+
 &usb3 {
 	qcom,otg-capability;
 };
@@ -247,8 +281,6 @@
 &pm8941_chg {
 	status = "ok";
 
-	qcom,chg-charging-disabled;
-
 	qcom,chg-chgr@1000 {
 		status = "ok";
 	};
@@ -344,6 +376,13 @@
 	};
 
 	gpio@cf00 { /* GPIO 16 */
+		qcom,mode = <1>;
+		qcom,output-type = <0>;
+		qcom,pull = <5>;
+		qcom,vin-sel = <2>;
+		qcom,out-strength = <3>;
+		qcom,src-sel = <2>;
+		qcom,master-en = <1>;
 	};
 
 	gpio@d000 { /* GPIO 17 */
@@ -473,7 +512,9 @@
 
 &slim_msm {
 	taiko_codec {
+		qcom,cdc-micbias1-ext-cap;
 		qcom,cdc-micbias2-ext-cap;
+		qcom,cdc-micbias4-ext-cap;
 	};
 };
 
diff --git a/arch/arm/boot/dts/msm8974-pm.dtsi b/arch/arm/boot/dts/msm8974-pm.dtsi
index b8a977b..2de5fad 100644
--- a/arch/arm/boot/dts/msm8974-pm.dtsi
+++ b/arch/arm/boot/dts/msm8974-pm.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -179,15 +179,19 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 
+		qcom,use-qtimer;
+
 		qcom,lpm-level@0 {
 			reg = <0x0>;
 			qcom,mode = <0>;        /* MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT */
 			qcom,xo = <1>;          /* ON */
 			qcom,l2 = <3>;          /* ACTIVE */
-			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
-			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
-			qcom,vdd-dig-upper-bound = <5>; /* MAX */
-			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
+			qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
+			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
+			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
+			qcom,irqs-detectable;
+			qcom.gpios-detectable;
 			qcom,latency-us = <1>;
 			qcom,ss-power = <784>;
 			qcom,energy-overhead = <190000>;
@@ -199,10 +203,12 @@
 			qcom,mode = <4>;        /* MSM_PM_SLEEP_MODE_RETENTION*/
 			qcom,xo = <1>;          /* ON */
 			qcom,l2 = <3>;          /* ACTIVE */
-			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
-			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
-			qcom,vdd-dig-upper-bound = <5>; /* MAX */
-			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
+			qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
+			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
+			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
+			qcom,irqs-detectable;
+			qcom.gpios-detectable;
 			qcom,latency-us = <75>;
 			qcom,ss-power = <735>;
 			qcom,energy-overhead = <77341>;
@@ -215,10 +221,12 @@
 			qcom,mode = <2>;        /* MSM_PM_SLEEP_MODE_STANDALONE_POWER_COLLAPSE */
 			qcom,xo = <1>;          /* ON */
 			qcom,l2 = <3>;          /* ACTIVE */
-			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
-			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
-			qcom,vdd-dig-upper-bound = <5>; /* MAX */
-			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
+			qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
+			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
+			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
+			qcom,irqs-detectable;
+			qcom.gpios-detectable;
 			qcom,latency-us = <95>;
 			qcom,ss-power = <725>;
 			qcom,energy-overhead = <99500>;
@@ -230,10 +238,12 @@
 			qcom,mode = <3>;        /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
 			qcom,xo = <1>;          /* ON */
 			qcom,l2 = <1>;          /* GDHS */
-			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
-			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
-			qcom,vdd-dig-upper-bound = <5>; /* MAX */
-			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
+			qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
+			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
+			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
+			qcom,irqs-detectable;
+			qcom.gpios-detectable;
 			qcom,latency-us = <2000>;
 			qcom,ss-power = <138>;
 			qcom,energy-overhead = <1208400>;
@@ -245,10 +255,12 @@
 			qcom,mode = <3>;        /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
 			qcom,xo = <1>;          /* ON */
 			qcom,l2 = <0>;          /* OFF */
-			qcom,vdd-mem-upper-bound = <1050000>; /* ACTIVE */
-			qcom,vdd-mem-lower-bound = <750000>;  /* RETENTION HIGH */
-			qcom,vdd-dig-upper-bound = <3>;  /* ACTIVE */
-			qcom,vdd-dig-lower-bound = <2>;  /* RETENTION HIGH */
+			qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
+			qcom,vdd-mem-lower-bound = <950000>; /* SVS SOC */
+			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO  */
+			qcom,vdd-dig-lower-bound = <3>;  /* SVS SOC */
+			qcom,irqs-detectable;
+			qcom.gpios-detectable;
 			qcom,latency-us = <3000>;
 			qcom,ss-power = <110>;
 			qcom,energy-overhead = <1250300>;
@@ -260,10 +272,10 @@
 			qcom,mode = <3>;        /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
 			qcom,xo = <0>;          /* OFF */
 			qcom,l2 = <1>;          /* GDHS */
-			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
-			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
-			qcom,vdd-dig-upper-bound = <5>; /* MAX */
-			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
+			qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
+			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
+			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
 			qcom,latency-us = <3000>;
 			qcom,ss-power = <68>;
 			qcom,energy-overhead = <1350200>;
@@ -275,10 +287,10 @@
 			qcom,mode = <3>;        /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
 			qcom,xo = <0>;          /* OFF */
 			qcom,l2 = <0>;          /* OFF */
-			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
-			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
-			qcom,vdd-dig-upper-bound = <5>; /* MAX */
-			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,vdd-mem-upper-bound = <1050000>; /* SUPER TURBO */
+			qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
+			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
+			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
 			qcom,latency-us = <10300>;
 			qcom,ss-power = <63>;
 			qcom,energy-overhead = <2128000>;
@@ -290,10 +302,10 @@
 			qcom,mode= <3>;         /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
 			qcom,xo = <0>;          /* OFF */
 			qcom,l2 = <0>;          /* OFF */
-			qcom,vdd-mem-upper-bound = <1050000>; /* ACTIVE */
-			qcom,vdd-mem-lower-bound = <750000>;  /* RETENTION HIGH */
-			qcom,vdd-dig-upper-bound = <3>;  /* ACTIVE */
-			qcom,vdd-dig-lower-bound = <2>;  /* RETIONTION HIGH */
+			qcom,vdd-mem-upper-bound = <950000>; /* NORMAL */
+			qcom,vdd-mem-lower-bound = <950000>;  /* SVS SOC */
+			qcom,vdd-dig-upper-bound = <4>;  /* NORMAL */
+			qcom,vdd-dig-lower-bound = <3>;  /* SVS SOC */
 			qcom,latency-us = <18000>;
 			qcom,ss-power = <10>;
 			qcom,energy-overhead = <3202600>;
@@ -305,10 +317,10 @@
 			qcom,mode= <3>;         /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
 			qcom,xo = <0>;          /* OFF */
 			qcom,l2 = <0>;          /* OFF */
-			qcom,vdd-mem-upper-bound = <750000>; /* RETENTION HIGH */
-			qcom,vdd-mem-lower-bound = <750000>; /* RETENTION LOW */
-			qcom,vdd-dig-upper-bound = <2>; /* RETENTION HIGH */
-			qcom,vdd-dig-lower-bound = <0>; /* RETENTION LOW */
+			qcom,vdd-mem-upper-bound = <950000>; /* SVS SOC */
+			qcom,vdd-mem-lower-bound = <675000>; /* RETENTION */
+			qcom,vdd-dig-upper-bound = <3>; /* SVS SOC */
+			qcom,vdd-dig-lower-bound = <1>; /* RETENTION */
 			qcom,latency-us = <20000>;
 			qcom,ss-power = <2>;
 			qcom,energy-overhead = <4252000>;
@@ -407,17 +419,24 @@
 			<40  95>;
 	};
 
-	qcom,pc-cntr@fe805664 {
-		compatible = "qcom,pc-cntr";
-		reg = <0xfe805664 0x40>;
-	};
-
-	qcom,pm-8x60 {
+	qcom,pm-8x60@fe805664 {
 		compatible = "qcom,pm-8x60";
+		reg = <0xfe805664 0x40>;
 		qcom,pc-mode = <0>; /*MSM_PC_TZ_L2_INT */
 		qcom,use-sync-timer;
 	};
 
+	qcom,rpm-log@fc19dc00 {
+		compatible = "qcom,rpm-log";
+		reg = <0xfc19dc00 0x4000>;
+		qcom,rpm-addr-phys = <0xfc000000>;
+		qcom,offset-version = <4>;
+		qcom,offset-page-buffer-addr = <36>;
+		qcom,offset-log-len = <40>;
+		qcom,offset-log-len-mask = <44>;
+		qcom,offset-page-indices = <56>;
+	};
+
 	qcom,rpm-stats@0xfc19dbd0{
 		compatible = "qcom,rpm-stats";
 		reg = <0xfc19dbd0 0x1000>;
diff --git a/arch/arm/boot/dts/msm8974-regulator.dtsi b/arch/arm/boot/dts/msm8974-regulator.dtsi
index a7a7c88..2dad8e7 100644
--- a/arch/arm/boot/dts/msm8974-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8974-regulator.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -110,9 +110,17 @@
 		pm8841_s4: regulator-s4 {
 			regulator-min-microvolt = <815000>;
 			regulator-max-microvolt = <900000>;
-			qcom,init-voltage = <815000>;
 			status = "okay";
 		};
+		pm8841_s4_corner: regulator-s4-corner {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8841_s4_corner";
+			qcom,set = <3>;
+			qcom,use-voltage-corner;
+			regulator-min-microvolt = <1>;
+			regulator-max-microvolt = <7>;
+			qcom,init-voltage-corner = <3>; /* SVS SOC */
+		};
 	};
 
 	rpm-regulator-smpa1 {
@@ -415,52 +423,75 @@
 };
 
 / {
-	krait0_vreg: regulator@f9088000 {
-		compatible = "qcom,krait-regulator";
-		regulator-name = "krait0";
-		reg = <0xf9088000 0x1000>;
-		regulator-min-microvolt = <500000>;
-		regulator-max-microvolt = <1100000>;
-		qcom,headroom-voltage = <150000>;
-		qcom,retention-voltage = <745000>;
-		qcom,ldo-default-voltage = <745000>;
-		qcom,ldo-threshold-voltage = <750000>;
-	};
+	krait_pdn: krait-pdn {
+		compatible = "qcom,krait-pdn";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
 
-	krait1_vreg: regulator@f9098000 {
-		compatible = "qcom,krait-regulator";
-		regulator-name = "krait1";
-		reg = <0xf9098000 0x1000>;
-		regulator-min-microvolt = <500000>;
-		regulator-max-microvolt = <1100000>;
-		qcom,headroom-voltage = <150000>;
-		qcom,retention-voltage = <745000>;
-		qcom,ldo-default-voltage = <745000>;
-		qcom,ldo-threshold-voltage = <750000>;
-	};
+		krait0_vreg: regulator@f9088000 {
+			compatible = "qcom,krait-regulator";
+			regulator-name = "krait0";
+			reg = <0xf9088000 0x1000>, /* APCS_ALIAS0_KPSS_ACS */
+				<0xf908a800 0x1000>; /* APCS_ALIAS0_KPSS_MDD */
+			reg-names = "acs", "mdd";
+			regulator-min-microvolt = <500000>;
+			regulator-max-microvolt = <1100000>;
+			qcom,headroom-voltage = <150000>;
+			qcom,retention-voltage = <675000>;
+			qcom,ldo-default-voltage = <750000>;
+			qcom,ldo-threshold-voltage = <850000>;
+			qcom,ldo-delta-voltage = <50000>;
+			qcom,cpu-num = <0>;
+		};
 
-	krait2_vreg: regulator@f90a8000 {
-		compatible = "qcom,krait-regulator";
-		regulator-name = "krait2";
-		reg = <0xf90a8000 0x1000>;
-		regulator-min-microvolt = <500000>;
-		regulator-max-microvolt = <1100000>;
-		qcom,headroom-voltage = <150000>;
-		qcom,retention-voltage = <745000>;
-		qcom,ldo-default-voltage = <745000>;
-		qcom,ldo-threshold-voltage = <750000>;
-	};
+		krait1_vreg: regulator@f9098000 {
+			compatible = "qcom,krait-regulator";
+			regulator-name = "krait1";
+			reg = <0xf9098000 0x1000>, /* APCS_ALIAS1_KPSS_ACS */
+				<0xf909a800 0x1000>; /* APCS_ALIAS1_KPSS_MDD */
+			reg-names = "acs", "mdd";
+			regulator-min-microvolt = <500000>;
+			regulator-max-microvolt = <1100000>;
+			qcom,headroom-voltage = <150000>;
+			qcom,retention-voltage = <675000>;
+			qcom,ldo-default-voltage = <750000>;
+			qcom,ldo-threshold-voltage = <850000>;
+			qcom,ldo-delta-voltage = <50000>;
+			qcom,cpu-num = <1>;
+		};
 
-	krait3_vreg: regulator@f90b8000 {
-		compatible = "qcom,krait-regulator";
-		regulator-name = "krait3";
-		reg = <0xf90b8000 0x1000>;
-		regulator-min-microvolt = <500000>;
-		regulator-max-microvolt = <1100000>;
-		qcom,headroom-voltage = <150000>;
-		qcom,retention-voltage = <745000>;
-		qcom,ldo-default-voltage = <745000>;
-		qcom,ldo-threshold-voltage = <750000>;
+		krait2_vreg: regulator@f90a8000 {
+			compatible = "qcom,krait-regulator";
+			regulator-name = "krait2";
+			reg = <0xf90a8000 0x1000>, /* APCS_ALIAS2_KPSS_ACS */
+				<0xf90aa800 0x1000>; /* APCS_ALIAS2_KPSS_MDD */
+			reg-names = "acs", "mdd";
+			regulator-min-microvolt = <500000>;
+			regulator-max-microvolt = <1100000>;
+			qcom,headroom-voltage = <150000>;
+			qcom,retention-voltage = <675000>;
+			qcom,ldo-default-voltage = <750000>;
+			qcom,ldo-threshold-voltage = <850000>;
+			qcom,ldo-delta-voltage = <50000>;
+			qcom,cpu-num = <2>;
+		};
+
+		krait3_vreg: regulator@f90b8000 {
+			compatible = "qcom,krait-regulator";
+			regulator-name = "krait3";
+			reg = <0xf90b8000 0x1000>, /* APCS_ALIAS3_KPSS_ACS */
+				<0xf90ba800 0x1000>; /* APCS_ALIAS3_KPSS_MDD */
+			reg-names = "acs", "mdd";
+			regulator-min-microvolt = <500000>;
+			regulator-max-microvolt = <1100000>;
+			qcom,headroom-voltage = <150000>;
+			qcom,retention-voltage = <675000>;
+			qcom,ldo-default-voltage = <750000>;
+			qcom,ldo-threshold-voltage = <850000>;
+			qcom,ldo-delta-voltage = <50000>;
+			qcom,cpu-num = <3>;
+		};
 	};
 
 	spi_eth_vreg: spi_eth_phy_vreg {
diff --git a/arch/arm/boot/dts/msm8974-rumi.dts b/arch/arm/boot/dts/msm8974-rumi.dts
deleted file mode 100644
index 738ff86..0000000
--- a/arch/arm/boot/dts/msm8974-rumi.dts
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/ "msm8974.dtsi"
-/include/ "msm8974-rumi.dtsi"
-
-/ {
-	model = "Qualcomm MSM 8974 RUMI";
-	compatible = "qcom,msm8974-rumi", "qcom,msm8974";
-	qcom,msm-id = <126 15 0>;
-};
diff --git a/arch/arm/boot/dts/msm8974-rumi.dtsi b/arch/arm/boot/dts/msm8974-rumi.dtsi
index 4919391..ce9d6c9 100644
--- a/arch/arm/boot/dts/msm8974-rumi.dtsi
+++ b/arch/arm/boot/dts/msm8974-rumi.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -11,7 +11,7 @@
  */
 
 /include/ "msm8974-leds.dtsi"
-/include/ "msm8974-camera-sensor.dtsi"
+/include/ "msm8974-camera-sensor-cdp-mtp.dtsi"
 
 / {
 	timer {
@@ -75,7 +75,7 @@
 		interrupts = <0 105 0>;
 		interrupt-names = "qup_err_intr";
 		qcom,i2c-bus-freq = <100000>;
-		qcom,i2c-src-freq = <24000000>;
+		qcom,i2c-src-freq = <19200000>;
 		gpios = <&msmgpio 83 0>, /* DAT  */
 			<&msmgpio 84 0>; /* CLK */
 	};
@@ -140,3 +140,7 @@
 &gdsc_usb_hsic {
         status = "disabled";
 };
+
+&rpm_bus {
+	rpm-standalone;
+};
diff --git a/arch/arm/boot/dts/msm8974-sim.dts b/arch/arm/boot/dts/msm8974-sim.dts
deleted file mode 100644
index 09ea419..0000000
--- a/arch/arm/boot/dts/msm8974-sim.dts
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/ "msm8974.dtsi"
-/include/ "msm8974-sim.dtsi"
-
-/ {
-	model = "Qualcomm MSM 8974 Simulator";
-	compatible = "qcom,msm8974-sim", "qcom,msm8974";
-	qcom,msm-id = <126 16 0>;
-};
diff --git a/arch/arm/boot/dts/msm8974-sim.dtsi b/arch/arm/boot/dts/msm8974-sim.dtsi
index fb638f7..a5606b8 100644
--- a/arch/arm/boot/dts/msm8974-sim.dtsi
+++ b/arch/arm/boot/dts/msm8974-sim.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -12,7 +12,7 @@
 
 /include/ "dsi-panel-sim-video.dtsi"
 /include/ "msm8974-leds.dtsi"
-/include/ "msm8974-camera-sensor.dtsi"
+/include/ "msm8974-camera-sensor-cdp-mtp.dtsi"
 
 / {
 	qcom,mdss_dsi@fd922800 {
diff --git a/arch/arm/boot/dts/msm8974-smp2p.dtsi b/arch/arm/boot/dts/msm8974-smp2p.dtsi
new file mode 100644
index 0000000..511f91f
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974-smp2p.dtsi
@@ -0,0 +1,171 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+/ {
+	qcom,smp2p-modem {
+		compatible = "qcom,smp2p";
+		reg = <0xfa006000 0x1000>, <0x8 0x0>;
+		reg-names = "irq-reg-base", "irq-reg-offset";
+		qcom,remote-pid = <1>;
+		qcom,irq-bitmask = <0x4000>;
+		interrupts = <0 27 1>;
+	};
+
+	qcom,smp2p-adsp {
+		compatible = "qcom,smp2p";
+		reg = <0xfa006000 0x1000>, <0x8 0x0>;
+		reg-names = "irq-reg-base", "irq-reg-offset";
+		qcom,remote-pid = <2>;
+		qcom,irq-bitmask = <0x400>;
+		interrupts = <0 158 1>;
+	};
+
+	qcom,smp2p-wcnss {
+		compatible = "qcom,smp2p";
+		reg = <0xfa006000 0x1000>, <0x8 0x0>;
+		reg-names = "irq-reg-base", "irq-reg-offset";
+		qcom,remote-pid = <4>;
+		qcom,irq-bitmask = <0x40000>;
+		interrupts = <0 143 1>;
+	};
+
+	/* SMP2P Test Driver for inbound entries */
+	smp2pgpio_smp2p_7_in: qcom,smp2pgpio-smp2p-7-in {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <7>;
+		qcom,is-inbound;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	qcom,smp2pgpio_test_smp2p_7_in {
+		compatible = "qcom,smp2pgpio_test_smp2p_7_in";
+		gpios = <&smp2pgpio_smp2p_7_in 0 0>;
+	};
+
+	/* SMP2P Test Driver for outbound entries */
+	smp2pgpio_smp2p_7_out: qcom,smp2pgpio-smp2p-7-out {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <7>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	qcom,smp2pgpio_test_smp2p_7_out {
+		compatible = "qcom,smp2pgpio_test_smp2p_7_out";
+		gpios = <&smp2pgpio_smp2p_7_out 0 0>;
+	};
+
+	/* SMP2P Test Driver for modem inbound */
+	smp2pgpio_smp2p_1_in: qcom,smp2pgpio-smp2p-1-in {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <1>;
+		qcom,is-inbound;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	qcom,smp2pgpio_test_smp2p_1_in {
+		compatible = "qcom,smp2pgpio_test_smp2p_1_in";
+		gpios = <&smp2pgpio_smp2p_1_in 0 0>;
+	};
+
+	/* SMP2P Test Driver for modem output */
+	smp2pgpio_smp2p_1_out: qcom,smp2pgpio-smp2p-1-out {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <1>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	qcom,smp2pgpio_test_smp2p_1_out {
+		compatible = "qcom,smp2pgpio_test_smp2p_1_out";
+		gpios = <&smp2pgpio_smp2p_1_out 0 0>;
+	};
+
+	/* SMP2P Test Driver for adsp inbound */
+	smp2pgpio_smp2p_2_in: qcom,smp2pgpio-smp2p-2-in {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <2>;
+		qcom,is-inbound;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	qcom,smp2pgpio_test_smp2p_2_in {
+		compatible = "qcom,smp2pgpio_test_smp2p_2_in";
+		gpios = <&smp2pgpio_smp2p_2_in 0 0>;
+	};
+
+	/* SMP2P Test Driver for adsp output */
+	smp2pgpio_smp2p_2_out: qcom,smp2pgpio-smp2p-2-out {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <2>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	qcom,smp2pgpio_test_smp2p_2_out {
+		compatible = "qcom,smp2pgpio_test_smp2p_2_out";
+		gpios = <&smp2pgpio_smp2p_2_out 0 0>;
+	};
+
+	/* SMP2P Test Driver for wcnss inbound */
+	smp2pgpio_smp2p_4_in: qcom,smp2pgpio-smp2p-4-in {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <4>;
+		qcom,is-inbound;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	qcom,smp2pgpio_test_smp2p_4_in {
+		compatible = "qcom,smp2pgpio_test_smp2p_4_in";
+		gpios = <&smp2pgpio_smp2p_4_in 0 0>;
+	};
+
+	/* SMP2P Test Driver for wcnss output */
+	smp2pgpio_smp2p_4_out: qcom,smp2pgpio-smp2p-4-out {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <4>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	qcom,smp2pgpio_test_smp2p_4_out {
+		compatible = "qcom,smp2pgpio_test_smp2p_4_out";
+		gpios = <&smp2pgpio_smp2p_4_out 0 0>;
+	};
+};
diff --git a/arch/arm/boot/dts/msm8974-v1-cdp.dts b/arch/arm/boot/dts/msm8974-v1-cdp.dts
new file mode 100644
index 0000000..8db99b2
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974-v1-cdp.dts
@@ -0,0 +1,31 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/include/ "msm8974-v1.dtsi"
+/include/ "msm8974-cdp.dtsi"
+
+/ {
+	model = "Qualcomm MSM 8974 CDP";
+	compatible = "qcom,msm8974-cdp", "qcom,msm8974";
+	qcom,msm-id = <126 1 0>;
+
+	qcom,mdss_dsi_toshiba_720p_video {
+		qcom,cont-splash-enabled;
+	};
+};
+
+&ehci {
+	status = "ok";
+	vbus-supply = <&usb2_otg_sw>;
+};
diff --git a/arch/arm/boot/dts/msm8974-v1-fluid.dts b/arch/arm/boot/dts/msm8974-v1-fluid.dts
new file mode 100644
index 0000000..60f2c4b
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974-v1-fluid.dts
@@ -0,0 +1,26 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/include/ "msm8974-v1.dtsi"
+/include/ "msm8974-fluid.dtsi"
+
+/ {
+	model = "Qualcomm MSM 8974 FLUID";
+	compatible = "qcom,msm8974-fluid", "qcom,msm8974";
+	qcom,msm-id = <126 3 0>;
+
+	qcom,mdss_dsi_toshiba_720p_video {
+		qcom,cont-splash-enabled;
+	};
+};
diff --git a/arch/arm/boot/dts/msm8974-v1-iommu-domains.dtsi b/arch/arm/boot/dts/msm8974-v1-iommu-domains.dtsi
new file mode 100644
index 0000000..6ea5b9e
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974-v1-iommu-domains.dtsi
@@ -0,0 +1,31 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/ {
+	qcom,iommu-domains {
+		compatible = "qcom,iommu-domains";
+
+		venus_domain_ns: qcom,iommu-domain1 {
+			label = "venus_ns";
+			qcom,iommu-contexts = <&venus_ns>;
+			qcom,virtual-addr-pool = <0x40000000 0x3f000000
+						  0x7f000000 0x1000000>;
+		};
+
+		venus_domain_cp: qcom,iommu-domain2 {
+			label = "venus_cp";
+			qcom,iommu-contexts = <&venus_cp>;
+			qcom,virtual-addr-pool = <0x1000000 0x3f000000>;
+			qcom,secure-domain;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/msm8974-v1-iommu.dtsi b/arch/arm/boot/dts/msm8974-v1-iommu.dtsi
new file mode 100644
index 0000000..c6693e1
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974-v1-iommu.dtsi
@@ -0,0 +1,33 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/include/ "msm-iommu-v1.dtsi"
+
+&jpeg_iommu {
+	status = "ok";
+};
+
+&mdp_iommu {
+	status = "ok";
+};
+
+&venus_iommu {
+	status = "ok";
+};
+
+&kgsl_iommu {
+	status = "ok";
+};
+
+&vfe_iommu {
+	status = "ok";
+};
diff --git a/arch/arm/boot/dts/msm8974-v1-liquid.dts b/arch/arm/boot/dts/msm8974-v1-liquid.dts
new file mode 100644
index 0000000..5c12569
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974-v1-liquid.dts
@@ -0,0 +1,22 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/include/ "msm8974-v1.dtsi"
+/include/ "msm8974-liquid.dtsi"
+
+/ {
+	model = "Qualcomm MSM 8974 LIQUID";
+	compatible = "qcom,msm8974-liquid", "qcom,msm8974";
+	qcom,msm-id = <126 9 0>;
+};
diff --git a/arch/arm/boot/dts/msm8974-v1-mtp.dts b/arch/arm/boot/dts/msm8974-v1-mtp.dts
new file mode 100644
index 0000000..2d52f78
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974-v1-mtp.dts
@@ -0,0 +1,26 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/include/ "msm8974-v1.dtsi"
+/include/ "msm8974-mtp.dtsi"
+
+/ {
+	model = "Qualcomm MSM 8974 MTP";
+	compatible = "qcom,msm8974-mtp", "qcom,msm8974";
+	qcom,msm-id = <126 8 0>;
+
+	qcom,mdss_dsi_toshiba_720p_video {
+		qcom,cont-splash-enabled;
+	};
+};
diff --git a/arch/arm/boot/dts/msm8974-v1-rumi.dts b/arch/arm/boot/dts/msm8974-v1-rumi.dts
new file mode 100644
index 0000000..ebb37b7
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974-v1-rumi.dts
@@ -0,0 +1,22 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/include/ "msm8974-v1.dtsi"
+/include/ "msm8974-rumi.dtsi"
+
+/ {
+	model = "Qualcomm MSM 8974 RUMI";
+	compatible = "qcom,msm8974-rumi", "qcom,msm8974";
+	qcom,msm-id = <126 15 0>;
+};
diff --git a/arch/arm/boot/dts/msm8974-v1-sim.dts b/arch/arm/boot/dts/msm8974-v1-sim.dts
new file mode 100644
index 0000000..29add5d
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974-v1-sim.dts
@@ -0,0 +1,22 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/include/ "msm8974-v1.dtsi"
+/include/ "msm8974-sim.dtsi"
+
+/ {
+	model = "Qualcomm MSM 8974 Simulator";
+	compatible = "qcom,msm8974-sim", "qcom,msm8974";
+	qcom,msm-id = <126 16 0>;
+};
diff --git a/arch/arm/boot/dts/msm8974-v1.dtsi b/arch/arm/boot/dts/msm8974-v1.dtsi
new file mode 100644
index 0000000..64014b3
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974-v1.dtsi
@@ -0,0 +1,125 @@
+/* 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.
+ */
+
+/*
+ * As a general rule, only version-specific property overrides should be placed
+ * inside this file. However, device definitions should be placed inside the
+ * msm8974.dtsi file.
+ */
+
+/include/ "msm8974.dtsi"
+/include/ "msm8974-v1-iommu.dtsi"
+/include/ "msm8974-v1-iommu-domains.dtsi"
+
+/ {
+	android_usb@fc42b0c8 {
+		compatible = "qcom,android-usb";
+		reg = <0xfc42b0c8 0xc8>;
+		qcom,android-usb-swfi-latency = <1>;
+	};
+
+	qcom,msm-imem@fc42b000 {
+		compatible = "qcom,msm-imem";
+		reg = <0xfc42b000 0x1000>; /* Address and size of IMEM */
+	};
+};
+
+&tsens {
+	qcom,calibration-less-mode;
+};
+
+/* I2C clock frequency overrides */
+&i2c_0 {
+	qcom,i2c-src-freq = <19200000>;
+};
+
+&i2c_2 {
+	qcom,i2c-src-freq = <19200000>;
+};
+
+/* CoreSight */
+&tmc_etr {
+	qcom,reset-flush-race;
+};
+
+&stm {
+	qcom,write-64bit;
+};
+
+&msm_vidc {
+	qcom,vidc-cp-map = <0x1000000 0x3f000000>;
+	qcom,vidc-ns-map = <0x40000000 0x40000000>;
+	qcom,load-freq-tbl = <979200 410000000>,
+		<783360 410000000>,
+		<489600 266670000>,
+		<244800 133330000>;
+	qcom,reg-presets = <0x80004 0x1>,
+		<0x80178 0x00001FFF>,
+		<0x8017c 0x1FFF1FFF>,
+		<0x800b0 0x10101001>,
+		<0x800b4 0x10101010>,
+		<0x800b8 0x10101010>,
+		<0x800bc 0x00000010>,
+		<0x800c0 0x1010100f>,
+		<0x800c4 0x10101010>,
+		<0x800c8 0x10101010>,
+		<0x800cc 0x00000010>,
+		<0x800d0 0x00001010>,
+		<0x800d4 0x00001010>,
+		<0x800f0 0x00000030>,
+		<0x800d8 0x00000707>,
+		<0x800dc 0x00000707>,
+		<0x80124 0x00000001>,
+		<0xE0020 0x5555556>,
+		<0xE0024 0x0>;
+	qcom,bus-ports = <1>;
+	qcom,enc-ocmem-ab-ib = <0 0>,
+		<138200 1222000>,
+		<414700 1222000>,
+		<940000 2444000>,
+		<1880000 2444000>,
+		<3008000 3910400>,
+		<3760000 4888000>;
+	qcom,dec-ocmem-ab-ib = <0 0>,
+		<176900 1556640>,
+		<456200 1556640>,
+		<864800 1556640>,
+		<1729600 3113280>,
+		<2767360 4981248>,
+		<3459200 6226560>;
+	qcom,enc-ddr-ab-ib = <0 0>,
+		<60000 664950>,
+		<181000 664950>,
+		<403000 664950>,
+		<806000 1329900>,
+		<1289600 2127840>,
+		<161200 6400000>;
+	qcom,dec-ddr-ab-ib = <0 0>,
+		<110000 909000>,
+		<268000 909000>,
+		<505000 909000>,
+		<1010000 1818000>,
+		<1616000 2908800>,
+		<2020000 6400000>;
+	qcom,iommu-groups = <&venus_domain_ns &venus_domain_cp>;
+	qcom,iommu-group-buffer-types = <0xfff 0x1ff>;
+	qcom,buffer-type-tz-usage-table = <0x1 0x1>,
+					<0x1fe 0x2>;
+};
+
+&sfpb_spinlock {
+	status = "disable";
+};
+
+&ldrex_spinlock {
+	status = "ok";
+};
diff --git a/arch/arm/boot/dts/msm8974-v2-cdp.dts b/arch/arm/boot/dts/msm8974-v2-cdp.dts
new file mode 100644
index 0000000..58e172f
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974-v2-cdp.dts
@@ -0,0 +1,22 @@
+/* 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/ "msm8974-v2.dtsi"
+/include/ "msm8974-cdp.dtsi"
+
+/ {
+	model = "Qualcomm MSM 8974v2 CDP";
+	compatible = "qcom,msm8974-cdp", "qcom,msm8974";
+	qcom,msm-id = <126 1 0x20000>;
+};
diff --git a/arch/arm/boot/dts/msm8974-v2-fluid.dts b/arch/arm/boot/dts/msm8974-v2-fluid.dts
new file mode 100644
index 0000000..5759b56
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974-v2-fluid.dts
@@ -0,0 +1,22 @@
+/* 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/ "msm8974-v2.dtsi"
+/include/ "msm8974-fluid.dtsi"
+
+/ {
+	model = "Qualcomm MSM 8974v2 FLUID";
+	compatible = "qcom,msm8974-fluid", "qcom,msm8974";
+	qcom,msm-id = <126 3 0x20000>;
+};
diff --git a/arch/arm/boot/dts/msm8974-v2-iommu-domains.dtsi b/arch/arm/boot/dts/msm8974-v2-iommu-domains.dtsi
new file mode 100644
index 0000000..a83815e
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974-v2-iommu-domains.dtsi
@@ -0,0 +1,45 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/ {
+	qcom,iommu-domains {
+		compatible = "qcom,iommu-domains";
+
+		venus_domain_ns: qcom,iommu-domain1 {
+			label = "venus_ns";
+			qcom,iommu-contexts = <&venus_ns>;
+			qcom,virtual-addr-pool = <0x5dc00000 0x7f000000
+						 0xdcc00000 0x1000000>;
+		};
+
+		venus_domain_sec_bitstream: qcom,iommu-domain2 {
+			label = "venus_sec_bitstream";
+			qcom,iommu-contexts = <&venus_sec_bitstream>;
+			qcom,virtual-addr-pool = <0x4b000000 0x12c00000>;
+			qcom,secure-domain;
+		};
+
+		venus_domain_sec_pixel: qcom,iommu-domain3 {
+			label = "venus_sec_pixel";
+			qcom,iommu-contexts = <&venus_sec_pixel>;
+			qcom,virtual-addr-pool = <0x25800000 0x25800000>;
+			qcom,secure-domain;
+		};
+
+		venus_domain_sec_non_pixel: qcom,iommu-domain4 {
+			label = "venus_sec_non_pixel";
+			qcom,iommu-contexts = <&venus_sec_non_pixel>;
+			qcom,virtual-addr-pool = <0x1000000 0x24800000>;
+			qcom,secure-domain;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/msm8974-v2-iommu.dtsi b/arch/arm/boot/dts/msm8974-v2-iommu.dtsi
new file mode 100644
index 0000000..c974884
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974-v2-iommu.dtsi
@@ -0,0 +1,247 @@
+/* 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/ "msm-iommu-v1.dtsi"
+
+&venus_iommu {
+	status = "ok";
+	qcom,iommu-enable-halt;
+
+	qcom,iommu-bfb-regs =  <0x204c
+				0x2050
+				0x2514
+				0x2540
+				0x256c
+				0x20ac
+				0x215c
+				0x220c
+				0x2314
+				0x2394
+				0x2414
+				0x2008
+				0x200c
+				0x2010
+				0x2014
+				0x2018
+				0x201c
+				0x2020
+				0x2024
+				0x2028
+				0x202c
+				0x2030
+				0x2034
+				0x2038>;
+
+	qcom,iommu-bfb-data =  <0xFFFFFFFF
+				0xFFFFFFFF
+				0x00000004
+				0x00000008
+				0x00000000
+				0x00013205
+				0x00004000
+				0x00014020
+				0x0
+				0x94
+				0x114
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0>;
+
+	venus_ns: qcom,iommu-ctx@fdc8c000 {
+		qcom,iommu-ctx-sids = <0 1 2 3 4 5 7>;
+	};
+
+	venus_sec_bitstream: qcom,iommu-ctx@fdc8d000 {
+		qcom,iommu-ctx-sids = <0x80 0x81 0x82 0x83 0x84>;
+		label = "venus_sec_bitstream";
+	};
+
+	venus_sec_pixel: qcom,iommu-ctx@fdc8f000 {
+		reg = <0xfdc8f000 0x1000>;
+		interrupts = <0 42 0>;
+		qcom,iommu-ctx-sids = <0x85>;
+		label = "venus_sec_pixel";
+		qcom,secure-context;
+	};
+
+	venus_sec_non_pixel: qcom,iommu-ctx@fdc90000 {
+		reg = <0xfdc90000 0x1000>;
+		interrupts = <0 42 0>;
+		qcom,iommu-ctx-sids = <0x87 0xA0>;
+		label = "venus_sec_non_pixel";
+		qcom,secure-context;
+	};
+};
+
+&jpeg_iommu {
+	status = "ok";
+	qcom,iommu-enable-halt;
+
+	qcom,iommu-bfb-regs =  <0x204c
+				0x2050
+				0x2514
+				0x2540
+				0x256c
+				0x2314
+				0x2394
+				0x2414
+				0x20ac
+				0x215c
+				0x220c
+				0x2008
+				0x200c
+				0x2010
+				0x2014>;
+
+	qcom,iommu-bfb-data =  <0x3FFF
+				0x00000000
+				0x4
+				0x4
+				0x0
+				0x0
+				0x10
+				0x50
+				0x0
+				0x00002804
+				0x00009614
+				0x0
+				0x0
+				0x0
+				0x0>;
+};
+
+&mdp_iommu {
+	status = "ok";
+	qcom,iommu-enable-halt;
+
+	qcom,iommu-bfb-regs =  <0x204c
+				0x2050
+				0x2514
+				0x2540
+				0x256c
+				0x20ac
+				0x215c
+				0x220c
+				0x2314
+				0x2394
+				0x2414
+				0x2008
+				0x200c
+				0x2010
+				0x2014
+				0x2018
+				0x201c
+				0x2020>;
+
+	qcom,iommu-bfb-data =  <0xFFFFF
+				0x00000000
+				0x00000004
+				0x00000010
+				0x00000000
+				0x00006800
+				0x00006221
+				0x00016231
+				0x0
+				0x34
+				0x74
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0>;
+};
+
+&kgsl_iommu {
+	status = "ok";
+	qcom,iommu-enable-halt;
+
+	qcom,iommu-bfb-regs =  <0x204c
+				0x2050
+				0x2514
+				0x2540
+				0x256c
+				0x20ac
+				0x215c
+				0x220c
+				0x2314
+				0x2394
+				0x2414
+				0x2008>;
+
+	qcom,iommu-bfb-data =  <0x00000003
+				0x0
+				0x00000004
+				0x00000010
+				0x00000000
+				0x00000000
+				0x00000000
+				0x00000020
+				0x0
+				0x1
+				0x81
+				0x0>;
+};
+
+&vfe_iommu {
+	status = "ok";
+	qcom,iommu-enable-halt;
+
+	qcom,iommu-bfb-regs =  <0x204c
+				0x2050
+				0x2514
+				0x2540
+				0x256c
+				0x2314
+				0x2394
+				0x2414
+				0x20ac
+				0x215c
+				0x220c
+				0x2008
+				0x200c
+				0x2010
+				0x2014
+				0x2018
+				0x201c
+				0x2020>;
+
+	qcom,iommu-bfb-data =  <0xffffffff
+				0x00000000
+				0x4
+				0x8
+				0x0
+				0x0
+				0x20
+				0x78
+				0x0
+				0x00003c08
+				0x0000b41e
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0>;
+};
diff --git a/arch/arm/boot/dts/msm8974-v2-liquid.dts b/arch/arm/boot/dts/msm8974-v2-liquid.dts
new file mode 100644
index 0000000..6812f60
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974-v2-liquid.dts
@@ -0,0 +1,22 @@
+/* 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/ "msm8974-v2.dtsi"
+/include/ "msm8974-liquid.dtsi"
+
+/ {
+	model = "Qualcomm MSM 8974v2 LIQUID";
+	compatible = "qcom,msm8974-liquid", "qcom,msm8974";
+	qcom,msm-id = <126 9 0x20000>;
+};
diff --git a/arch/arm/boot/dts/msm8974-v2-mtp.dts b/arch/arm/boot/dts/msm8974-v2-mtp.dts
new file mode 100644
index 0000000..b29d4ca
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974-v2-mtp.dts
@@ -0,0 +1,22 @@
+/* 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/ "msm8974-v2.dtsi"
+/include/ "msm8974-mtp.dtsi"
+
+/ {
+	model = "Qualcomm MSM 8974v2 MTP";
+	compatible = "qcom,msm8974-mtp", "qcom,msm8974";
+	qcom,msm-id = <126 8 0x20000>;
+};
diff --git a/arch/arm/boot/dts/msm8974-v2.dtsi b/arch/arm/boot/dts/msm8974-v2.dtsi
new file mode 100644
index 0000000..3dda20f
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974-v2.dtsi
@@ -0,0 +1,123 @@
+/* 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.
+ */
+
+/*
+ * As a general rule, only version-specific property overrides should be placed
+ * inside this file. However, device definitions should be placed inside the
+ * msm8974.dtsi file.
+ */
+
+/include/ "msm8974.dtsi"
+/include/ "msm8974-v2-iommu.dtsi"
+/include/ "msm8974-v2-iommu-domains.dtsi"
+
+/ {
+	android_usb@fe8050c8 {
+		compatible = "qcom,android-usb";
+		reg = <0xfe8050c8 0xc8>;
+		qcom,android-usb-swfi-latency = <1>;
+	};
+
+	qcom,msm-imem@fe805000 {
+		compatible = "qcom,msm-imem";
+		reg = <0xfe805000 0x1000>; /* Address and size of IMEM */
+	};
+};
+
+/* GPU overrides */
+&msm_gpu {
+	/* Updated chip ID */
+	qcom,chipid = <0x03030001>;
+
+	/* Updated bus bandwidth requirements */
+	qcom,msm-bus,vectors-KBps =
+		/* Off */
+		<26 512 0 0>, <89 604 0 0>,
+		/* SVS */
+		<26 512 0 2400000>, <89 604 0 3000000>,
+		/* Nominal / SVS */
+		<26 512 0 4656000>, <89 604 0 3000000>,
+		/* Nominal */
+		<26 512 0 4656000>, <89 604 0 5334880>,
+		/* Turbo / Nominal */
+		<26 512 0 7464000>, <89 604 0 5334880>,
+		/* Turbo */
+		<26 512 0 7464000>, <89 604 0 6400000>;
+};
+
+&mdss_mdp {
+	qcom,vbif-settings = <0x0004 0x00000001>;
+	qcom,mdp-settings = <0x02E0 0x000000A9>,
+			    <0x02E4 0x00000055>;
+
+	qcom,mdss-wb-off = <0x00011100 0x00011500
+			    0x00011900 0x00011D00 0x00012100>;
+	qcom,mdss-intf-off = <0x00012500 0x00012700
+			      0x00012900 0x00012b00>;
+};
+
+&msm_vidc {
+	qcom,vidc-ns-map = <0x40000000 0x40000000>;
+	qcom,load-freq-tbl = <979200 465000000>,
+		<783360 465000000>,
+		<489600 266670000>,
+		<244800 133330000>;
+	qcom,reg-presets = <0x80070 0x11FFF>,
+		<0x80074 0xA4>,
+		<0x800A8 0x1FFF>,
+		<0x80124 0x3>,
+		<0xE0020 0x5555556>,
+		<0xE0024 0x0>;
+	qcom,bus-ports = <1>;
+	qcom,enc-ocmem-ab-ib = <0 0>,
+		<138000 1034000>,
+		<414000 1034000>,
+		<940000 1034000>,
+		<1880000 2068000>,
+		<3008000 3309000>,
+		<3760000 4136000>,
+		<4468000 2457000>;
+	qcom,dec-ocmem-ab-ib = <0 0>,
+		<176000 519000>,
+		<456000 519000>,
+		<864000 519000>,
+		<1728000 1038000>,
+		<2766000 1661000>,
+		<3456000 2076000>,
+		<3662000 2198000>;
+	qcom,enc-ddr-ab-ib = <0 0>,
+		<60000 302000>,
+		<182000 302000>,
+		<402000 302000>,
+		<804000 604000>,
+		<1288000 967000>,
+		<2340000 1404000>,
+		<24940000 1496000>;
+	qcom,dec-ddr-ab-ib = <0 0>,
+		<104000 303000>,
+		<268000 303000>,
+		<506000 303000>,
+		<1012000 606000>,
+		<1620000 970000>,
+		<2024000 1212000>,
+		<2132000 1279000>;
+	qcom,iommu-groups = <&venus_domain_ns &venus_domain_sec_bitstream
+			&venus_domain_sec_pixel &venus_domain_sec_non_pixel>;
+	qcom,iommu-group-buffer-types = <0xfff 0x91 0x42 0x120>;
+	qcom,buffer-type-tz-usage-table = <0x91 0x1>,
+					<0x42 0x2>,
+					<0x120 0x3>;
+};
+
+&krait_pdn {
+	qcom,use-phase-switching;
+};
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 74b6521..7c6a9d1 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -12,19 +12,34 @@
 
 /include/ "skeleton.dtsi"
 /include/ "msm8974-pm.dtsi"
-/include/ "msm8974-iommu.dtsi"
 /include/ "msm8974-camera.dtsi"
 /include/ "msm8974-coresight.dtsi"
 /include/ "msm-gdsc.dtsi"
 /include/ "msm8974-ion.dtsi"
 /include/ "msm8974-gpu.dtsi"
 /include/ "msm8974-mdss.dtsi"
+/include/ "msm8974-smp2p.dtsi"
+/include/ "msm8974-bus.dtsi"
 
 / {
 	model = "Qualcomm MSM 8974";
 	compatible = "qcom,msm8974";
 	interrupt-parent = <&intc>;
 
+	aliases {
+		spi0 = &spi_0;
+		spi7 = &spi_7;
+	};
+
+	memory {
+
+		secure_mem: region@0 {
+			linux,contiguous-region;
+			reg = <0 0x7800000>;
+			label = "secure_mem";
+		};
+	};
+
 	intc: interrupt-controller@F9000000 {
 		compatible = "qcom,msm-qgic2";
 		interrupt-controller;
@@ -40,7 +55,9 @@
 		interrupt-controller;
 		#interrupt-cells = <2>;
 		reg = <0xfd510000 0x4000>;
+		ngpio = <146>;
 		interrupts = <0 208 0>;
+		qcom,direct-connect-irqs = <8>;
 	};
 
 	wcd9xxx_intc: wcd9xxx-irq {
@@ -58,16 +75,16 @@
 		clock-frequency = <19200000>;
 	};
 
-	qcom,vidc@fdc00000 {
+	qcom,mpm-counter@fc4a3000 {
+		compatible = "qcom,mpm-counter";
+		reg = <0xfc4a3000 0x1000>;
+	};
+
+	msm_vidc: qcom,vidc@fdc00000 {
 		compatible = "qcom,msm-vidc";
 		reg = <0xfdc00000 0xff000>;
 		interrupts = <0 44 0>;
-		vidc-cp-map = <0x1000000 0x3f000000>;
-		vidc-ns-map = <0x40000000 0x40000000>;
-		load-freq-tbl = <979200 410000000>,
-			<783360 410000000>,
-			<489600 266670000>,
-			<244800 133330000>;
+		qcom,hfi = "venus";
 	};
 
 	qcom,wfd {
@@ -93,10 +110,20 @@
 		reg = <0xf991e000 0x1000>;
 		interrupts = <0 108 0>;
 		status = "disabled";
+
+		qcom,msm-bus,name = "serial_uart2";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,active-only = <0>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<84 512 0 0>,
+				<84 512 500 800>;
 	};
 
 	usb_otg: usb@f9a55000 {
 		compatible = "qcom,hsusb-otg";
+		status = "disabled";
+
 		reg = <0xf9a55000 0x400>;
 		interrupts = <0 134 0 0 140 0>;
 		interrupt-names = "core_irq", "async_irq";
@@ -120,12 +147,6 @@
 				<87 512 60000 960000>;
 	};
 
-	android_usb@fc42b0c8 {
-		compatible = "qcom,android-usb";
-		reg = <0xfc42b0c8 0xc8>;
-		qcom,android-usb-swfi-latency = <1>;
-	};
-
 	sdcc1: qcom,sdcc@f9824000 {
 		cell-index = <1>; /* SDC1 eMMC slot */
 		compatible = "qcom,msm-sdcc";
@@ -321,9 +342,8 @@
 		qcom,bam-dma-res-pipes = <6>;
 	};
 
-	spi_epm: spi@f9966000 {
+	spi_7: spi_epm: spi@f9966000 {
 		compatible = "qcom,spi-qup-v2";
-		cell-index = <7>;
 		reg = <0xf9966000 0x1000>;
 		interrupts = <0 104 0>;
 		spi-max-frequency = <19200000>;
@@ -335,6 +355,46 @@
 		cs-gpios = <&msmgpio 55 0>;
 	};
 
+	tspp: msm_tspp@f99d8000 {
+		compatible = "qcom,msm_tspp";
+		cell-index = <0>;
+		reg = <0xf99d8000 0x1000>, /* MSM_TSIF0_PHYS */
+		      <0xf99d9000 0x1000>, /* MSM_TSIF1_PHYS */
+		      <0xf99da000 0x1000>, /* MSM_TSPP_PHYS  */
+		      <0xf99c4000 0x14000>; /* MSM_TSPP_BAM_PHYS */
+		reg-names = "MSM_TSIF0_PHYS",
+			"MSM_TSIF1_PHYS",
+			"MSM_TSPP_PHYS",
+			"MSM_TSPP_BAM_PHYS";
+		interrupts = <0 153 0>, /* TSIF_TSPP_IRQ */
+			<0 151 0>, /* TSIF0_IRQ */
+			<0 152 0>, /* TSIF1_IRQ */
+			<0 154 0>; /* TSIF_BAM_IRQ */
+		interrupt-names = "TSIF_TSPP_IRQ",
+			"TSIF0_IRQ",
+			"TSIF1_IRQ",
+			"TSIF_BAM_IRQ";
+		qcom,tsif-pclk = "iface_clk";
+		qcom,tsif-ref-clk = "ref_clk";
+		gpios = <&msmgpio 89 0>, /* TSIF0 CLK  */
+			<&msmgpio 90 0>, /* TSIF0 EN   */
+			<&msmgpio 91 0>, /* TSIF0 DATA */
+			<&msmgpio 92 0>, /* TSIF0 SYNC */
+			<&msmgpio 93 0>, /* TSIF1 CLK  */
+			<&msmgpio 94 0>, /* TSIF1 EN   */
+			<&msmgpio 95 0>, /* TSIF1 DATA */
+			<&msmgpio 96 0>; /* TSIF1 SYNC */
+		qcom,gpio-names = "tsif_clk",
+				"tsif_en",
+				"tsif_data",
+				"tsif_sync",
+				"tsif_clk",
+				"tsif_en",
+				"tsif_data",
+				"tsif_sync";
+		qcom,gpios-func = <1>;
+	};
+
 	slim_msm: slim@fe12f000 {
 		cell-index = <1>;
 		compatible = "qcom,slim-ngd";
@@ -426,157 +486,27 @@
 		qcom,cdc-mclk-gpios = <&pm8941_gpios 15 0>;
 		taiko-mclk-clk = <&pm8941_clkdiv1>;
 		qcom,taiko-mclk-clk-freq = <9600000>;
+		prim-auxpcm-gpio-clk  = <&msmgpio 65 0>;
+		prim-auxpcm-gpio-sync = <&msmgpio 66 0>;
+		prim-auxpcm-gpio-din  = <&msmgpio 67 0>;
+		prim-auxpcm-gpio-dout = <&msmgpio 68 0>;
 	};
 
 	spmi_bus: qcom,spmi@fc4c0000 {
 		cell-index = <0>;
 		compatible = "qcom,spmi-pmic-arb";
+		reg-names = "core", "intr", "cnfg";
 		reg = <0xfc4cf000 0x1000>,
-		      <0Xfc4cb000 0x1000>;
+		      <0Xfc4cb000 0x1000>,
+		      <0Xfc4ca000 0x1000>;
 		/* 190,ee0_krait_hlos_spmi_periph_irq */
 		/* 187,channel_0_krait_hlos_trans_done_irq */
 		interrupts = <0 190 0 0 187 0>;
 		qcom,pmic-arb-ee = <0>;
 		qcom,pmic-arb-channel = <0>;
-		qcom,pmic-arb-ppid-map = <0x40400000>, /* BUS */
-					 <0x40500001>, /* INT */
-					 <0x40600002>, /* SPMI */
-					 <0x40800003>, /* PON */
-					 <0x42400004>, /* TEMP_ALARM */
-					 <0x47000005>, /* PBS_CORE */
-					 <0x47100006>, /* PBS_CLIENT0 */
-					 <0x47200007>, /* PBS_CLIENT1 */
-					 <0x47300008>, /* PBS_CLIENT2 */
-					 <0x47400009>, /* PBS_CLIENT3 */
-					 <0x4750000a>, /* PBS_CLIENT4 */
-					 <0x4760000b>, /* PBS_CLIENT5 */
-					 <0x4770000c>, /* PBS_CLIENT6 */
-					 <0x4780000d>, /* PBS_CLIENT7 */
-					 <0x4a00000e>, /* MPP1 */
-					 <0x4a100021>, /* MPP2 */
-					 <0x4a20000f>, /* MPP3 */
-					 <0x4a300010>, /* MPP4 */
-					 <0x51000011>, /* BCLK_GEN_MAIN */
-					 <0x51d00012>, /* S4_CTRL */
-					 <0x51e00013>, /* S4_PS */
-					 <0x51f00014>, /* S4_FREQ */
-					 <0x52000015>, /* S5_CTRL */
-					 <0x52100016>, /* S5_PS */
-					 <0x52200017>, /* S5_FREQ */
-					 <0x52300018>, /* S6_CTRL */
-					 <0x52400019>, /* S6_PS */
-					 <0x5250001a>, /* S6_FREQ */
-					 <0x5260001b>, /* S7_CTRL */
-					 <0x5270001c>, /* S7_PS */
-					 <0x5280001d>, /* S7_FREQ */
-					 <0x5290001e>, /* S8_CTRL */
-					 <0x52a0001f>, /* S8_PS */
-					 <0x52b00020>, /* S8_FREQ */
-					 <0x00400022>, /* BUS */
-					 <0x00500023>, /* INT */
-					 <0x00600024>, /* SPMI */
-					 <0x00800025>, /* PON */
-					 <0x00b00027>, /* VREG_TFT */
-					 <0x01000028>, /* SMBB_CHGR */
-					 <0x01100029>, /* SMBB_BUCK */
-					 <0x0120002a>, /* SMBB_BAT_IF */
-					 <0x0130002b>, /* SMBB_USB_CHGPTH */
-					 <0x0140002c>, /* SMBB_DC_CHGPTH */
-					 <0x0150002d>, /* SMBB_BOOST */
-					 <0x0160002e>, /* SMBB_MISC */
-					 <0x0170002f>, /* SMBB_FREQ */
-					 <0x02400030>, /* TEMP_ALARM */
-					 <0x02800031>, /* COIN */
-					 <0x03100032>, /* VADC1_USR */
-					 <0x03300033>, /* VADC1_BMS */
-					 <0x03400034>, /* VADC2_BTM */
-					 <0x03600035>, /* IADC1_USR */
-					 <0x03800036>, /* IADC1_BMS */
-					 <0x04000037>, /* BMS1 */
-					 <0x05700039>, /* DIFF_CLK1 */
-					 <0x05c0003b>, /* DIV_CLK2 */
-					 <0x0610003d>, /* RTC_ALARM */
-					 <0x0620003e>, /* RTC_TIMER */
-					 <0x07100040>, /* PBS_CLIENT0 */
-					 <0x07200041>, /* PBS_CLIENT1 */
-					 <0x07300042>, /* PBS_CLIENT2 */
-					 <0x07400043>, /* PBS_CLIENT3 */
-					 <0x07500044>, /* PBS_CLIENT4 */
-					 <0x07600045>, /* PBS_CLIENT5 */
-					 <0x07700046>, /* PBS_CLIENT6 */
-					 <0x07800047>, /* PBS_CLIENT7 */
-					 <0x07900048>, /* PBS_CLIENT8 */
-					 <0x07a00049>, /* PBS_CLIENT9 */
-					 <0x07b0004a>, /* PBS_CLIENT10 */
-					 <0x07c0004b>, /* PBS_CLIENT11 */
-					 <0x07d0004c>, /* PBS_CLIENT12 */
-					 <0x07e0004d>, /* PBS_CLIENT13 */
-					 <0x07f0004e>, /* PBS_CLIENT14 */
-					 <0x0800004f>, /* PBS_CLIENT15 */
-					 <0x0a100050>, /* MPP2 */
-					 <0x0a300051>, /* MPP4 */
-					 <0x0a400052>, /* MPP5 */
-					 <0x0a500053>, /* MPP6 */
-					 <0x0a600054>, /* MPP7 */
-					 <0x0a700055>, /* MPP8 */
-					 <0x0c000056>, /* GPIO1 */
-					 <0x0c100057>, /* GPIO2 */
-					 <0x0c200058>, /* GPIO3 */
-					 <0x0c300059>, /* GPIO4 */
-					 <0x0c40005a>, /* GPIO5 */
-					 <0x0c50005b>, /* GPIO6 */
-					 <0x0c60005c>, /* GPIO7 */
-					 <0x0c70005d>, /* GPIO8 */
-					 <0x0c80005e>, /* GPIO9 */
-					 <0x0c90005f>, /* GPIO10 */
-					 <0x0ca00060>, /* GPIO11 */
-					 <0x0cb00061>, /* GPIO12 */
-					 <0x0cc00062>, /* GPIO13 */
-					 <0x0cd00063>, /* GPIO14 */
-					 <0x0ce00064>, /* GPIO15 */
-					 <0x0cf00065>, /* GPIO16 */
-					 <0x0d200066>, /* GPIO19 */
-					 <0x0d300067>, /* GPIO20 */
-					 <0x0d500068>, /* GPIO22 */
-					 <0x0d600069>, /* GPIO23 */
-					 <0x0d70006a>, /* GPIO24 */
-					 <0x0d80006b>, /* GPIO25 */
-					 <0x0d90006c>, /* GPIO26 */
-					 <0x0da0006d>, /* GPIO27 */
-					 <0x0dc0006e>, /* GPIO29 */
-					 <0x0dd0006f>, /* GPIO30 */
-					 <0x0df00070>, /* GPIO32 */
-					 <0x0e000071>, /* GPIO33 */
-					 <0x0e100072>, /* GPIO34 */
-					 <0x0e200073>, /* GPIO35 */
-					 <0x0e300074>, /* GPIO36 */
-					 <0x11000075>, /* BUCK_CMN */
-					 <0x1a000076>, /* BOOST */
-					 <0x1a100077>, /* BOOST_FREQ */
-					 <0x1a800078>, /* KEYPAD1 */
-					 <0x1b000079>, /* LPG_LUT */
-					 <0x1b10007a>, /* LPG_CHAN1 */
-					 <0x1b20007b>, /* LPG_CHAN2 */
-					 <0x1b30007c>, /* LPG_CHAN3 */
-					 <0x1b40007d>, /* LPG_CHAN4 */
-					 <0x1b50007e>, /* LPG_CHAN5 */
-					 <0x1b60007f>, /* LPG_CHAN6 */
-					 <0x1b700080>, /* LPG_CHAN7 */
-					 <0x1b800081>, /* LPG_CHAN8 */
-					 <0x1bc00082>, /* PWM_3D */
-					 <0x1c000083>, /* VIB1 */
-					 <0x1d000084>, /* TRI_LED */
-					 <0x1d300085>, /* FLASH1 */
-					 <0x1d800086>, /* WLED1 */
-					 <0x1e200087>, /* KPDBL_MAIN */
-					 <0x1e300088>, /* KPDBL_LUT */
-					 <0x1e400089>, /* LPG_CHAN9 */
-					 <0x1e50008a>, /* LPG_CHAN10 */
-					 <0x1e60008b>, /* LPG_CHAN11 */
-					 <0x1e70008c>; /* LPG_CHAN12 */
 	};
 
-	i2c@f9967000 { /* BLSP#11 */
+	i2c_0: i2c@f9967000 { /* BLSP#11 */
 		cell-index = <0>;
 		compatible = "qcom,i2c-qup";
 		reg = <0Xf9967000 0x1000>;
@@ -586,10 +516,10 @@
 		interrupts = <0 105 0>;
 		interrupt-names = "qup_err_intr";
 		qcom,i2c-bus-freq = <100000>;
-		qcom,i2c-src-freq = <24000000>;
+		qcom,i2c-src-freq = <50000000>;
 	};
 
-	i2c@f9924000 {
+	i2c_2: i2c@f9924000 {
 		cell-index = <2>;
 		compatible = "qcom,i2c-qup";
 		reg = <0xf9924000 0x1000>;
@@ -599,11 +529,10 @@
 		interrupts = <0 96 0>;
 		interrupt-names = "qup_err_intr";
 		qcom,i2c-bus-freq = <100000>;
-		qcom,i2c-src-freq = <24000000>;
+		qcom,i2c-src-freq = <50000000>;
 	};
 
-	spi@f9923000 {
-		cell-index = <0>;
+	spi_0: spi@f9923000 {
 		compatible = "qcom,spi-qup-v2";
 		reg = <0xf9923000 0x1000>;
 		interrupts = <0 95 0>;
@@ -651,6 +580,7 @@
 		vbus_dwc3-supply = <&pm8941_mvs1>;
 		qcom,dwc-usb3-msm-dbm-eps = <4>;
 		qcom,vdd-voltage-level = <1 5 7>;
+		qcom,dwc-hsphy-init = <0x00D195A4>;
 
 		qcom,msm-bus,name = "usb3";
 		qcom,msm-bus,num-cases = <2>;
@@ -661,8 +591,21 @@
 				<61 512 240000 960000>;
 	};
 
+	ehci: qcom,ehci-host@f9a55000 {
+		compatible = "qcom,ehci-host";
+		status = "disabled";
+		reg = <0xf9a55000 0x400>;
+		interrupts = <0 134 0>, <0 140 0>;
+		interrupt-names = "core_irq", "async_irq";
+		HSUSB_VDDCX-supply = <&pm8841_s2>;
+		HSUSB_1p8-supply = <&pm8941_l6>;
+		HSUSB_3p3-supply = <&pm8941_l24>;
+		qcom,usb2-enable-hsphy2;
+		qcom,usb2-power-budget = <500>;
+	};
+
 	gdsc_oxili_gx: qcom,gdsc@fd8c4024 {
-		parent-supply = <&pm8841_s4>;
+		parent-supply = <&pm8841_s4_corner>;
 	};
 
 	qcom,lpass@fe200000 {
@@ -670,6 +613,7 @@
 		reg = <0xfe200000 0x00100>,
 		      <0xfd485100 0x00010>;
 		reg-names = "qdsp6_base", "halt_base";
+		vdd_cx-supply = <&pm8841_s2_corner>;
 		interrupts = <0 162 1>;
 
 		qcom,firmware-name = "adsp";
@@ -682,6 +626,13 @@
 
 	qcom,msm-pcm {
 		compatible = "qcom,msm-pcm-dsp";
+		qcom,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;
 	};
 
 	qcom,msm-pcm-routing {
@@ -743,6 +694,16 @@
 			qcom,msm-dai-q6-dev-id = <16387>;
 		};
 
+		qcom,msm-dai-q6-sb-2-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <16388>;
+		};
+
+		qcom,msm-dai-q6-sb-2-tx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <16389>;
+		};
+
 		qcom,msm-dai-q6-sb-3-rx {
 			compatible = "qcom,msm-dai-q6-dev";
 			qcom,msm-dai-q6-dev-id = <16390>;
@@ -812,18 +773,23 @@
 			compatible = "qcom,msm-dai-q6-dev";
 			qcom,msm-dai-q6-dev-id = <32772>;
 		};
+
+		qcom,msm-dai-q6-incall-music-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <32773>;
+		};
 	};
 
 	qcom,msm-auxpcm {
 		compatible = "qcom,msm-auxpcm-resource";
 		qcom,msm-cpudai-auxpcm-clk = "pcm_clk";
-		qcom,msm-cpudai-auxpcm-mode = <0>;
-		qcom,msm-cpudai-auxpcm-sync = <1>;
-		qcom,msm-cpudai-auxpcm-frame = <5>;
-		qcom,msm-cpudai-auxpcm-quant = <2>;
-		qcom,msm-cpudai-auxpcm-slot = <1>;
-		qcom,msm-cpudai-auxpcm-data = <0>;
-		qcom,msm-cpudai-auxpcm-pcm-clk-rate = <2048000>;
+		qcom,msm-cpudai-auxpcm-mode = <0>, <0>;
+		qcom,msm-cpudai-auxpcm-sync = <1>, <1>;
+		qcom,msm-cpudai-auxpcm-frame = <5>, <4>;
+		qcom,msm-cpudai-auxpcm-quant = <2>, <2>;
+		qcom,msm-cpudai-auxpcm-slot = <1>, <1>;
+		qcom,msm-cpudai-auxpcm-data = <0>, <0>;
+		qcom,msm-cpudai-auxpcm-pcm-clk-rate = <2048000>, <2048000>;
 
 		qcom,msm-auxpcm-rx {
 			qcom,msm-auxpcm-dev-id = <4106>;
@@ -881,8 +847,10 @@
 
 		interrupts = <0 24 1>;
 		vdd_mss-supply = <&pm8841_s3>;
+		vdd_cx-supply = <&pm8841_s2_corner>;
 		vdd_mx-supply = <&pm8841_s1>;
-
+		vdd_pll-supply = <&pm8941_l12>;
+		qcom,vdd_pll = <1800000>;
 		qcom,is-loadable;
 		qcom,firmware-name = "mba";
 		qcom,pil-self-auth = <1>;
@@ -900,6 +868,10 @@
 		qcom,firmware-name = "wcnss";
 	};
 
+	qcom,iris-fm {
+		compatible = "qcom,iris_fm";
+	};
+
 	qcom,wcnss-wlan@fb000000 {
 		compatible = "qcom,wcnss_wlan";
 		reg = <0xfb000000 0x280000>;
@@ -930,6 +902,7 @@
 		interrupts = <0 76 0 0 77 0>;
 		interrupt-names = "ocmem_irq", "dm_irq";
 		qcom,ocmem-num-regions = <0x3>;
+		qcom,ocmem-num-macros = <0x8>;
 		qcom,resource-type = <0x706d636f>;
 		#address-cells = <1>;
 		#size-cells = <1>;
@@ -942,15 +915,9 @@
 		};
 
 		partition@80000 {
-			reg = <0x80000 0xA0000>;
+			reg = <0x100000 0x80000>;
 			qcom,ocmem-part-name = "lp_audio";
-			qcom,ocmem-part-min = <0xA0000>;
-		};
-
-		partition@E0000 {
-			reg = <0x120000 0x20000>;
-			qcom,ocmem-part-name = "other_os";
-			qcom,ocmem-part-min = <0x20000>;
+			qcom,ocmem-part-min = <0x80000>;
 		};
 
 		partition@100000 {
@@ -959,11 +926,6 @@
 			qcom,ocmem-part-min = <0x55000>;
 		};
 
-		partition@140000 {
-			reg = <0x140000 0x40000>;
-			qcom,ocmem-part-name = "sensors";
-			qcom,ocmem-part-min = <0x40000>;
-		};
 	};
 
 	rpm_bus: qcom,rpm-smd {
@@ -998,7 +960,7 @@
 		interrupts = <0 3 0 0 4 0>;
 		qcom,bark-time = <11000>;
 		qcom,pet-time = <10000>;
-		qcom,ipi-ping = <1>;
+		qcom,ipi-ping;
 	};
 
 	qcom,tz-log@fc03000 {
@@ -1009,7 +971,7 @@
 	qcom,venus@fdce0000 {
 		compatible = "qcom,pil-venus";
 		reg = <0xfdce0000 0x4000>,
-		      <0xfdc80208 0x8>;
+		      <0xfdc80000 0x400>;
 		reg-names = "wrapper_base", "vbif_base";
 		vdd-supply = <&gdsc_venus>;
 
@@ -1030,16 +992,16 @@
 		qcom,memory-reservation-size = <0x600000>; /* 6M EBI1 buffer */
 	};
 
-	tsens@fc4a8000 {
+	tsens: tsens@fc4a8000 {
 		compatible = "qcom,msm-tsens";
 		reg = <0xfc4a8000 0x2000>,
 		      <0xfc4b8000 0x1000>;
 		reg-names = "tsens_physical", "tsens_eeprom_physical";
 		interrupts = <0 184 0>;
-		qcom,calibration-less-mode;
 		qcom,sensors = <11>;
 		qcom,slope = <3200 3200 3200 3200 3200 3200 3200 3200 3200
 				3200 3200>;
+		qcom,calib-mode = "fuse_map1";
 	};
 
 	qcom,msm-rtb {
@@ -1061,6 +1023,14 @@
 		reg-names = "crypto-base","crypto-bam-base";
 		interrupts = <0 236 0>;
 		qcom,bam-pipe-pair = <1>;
+		qcom,ce-hw-instance = <1>;
+                qcom,msm-bus,name = "qcedev-noc";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,active-only = <0>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<56 512 0 0>,
+				<56 512 3936000 393600>;
 	};
 
         qcom,qcrypto@fd444000 {
@@ -1070,6 +1040,14 @@
 		reg-names = "crypto-base","crypto-bam-base";
 		interrupts = <0 236 0>;
 		qcom,bam-pipe-pair = <2>;
+		qcom,ce-hw-instance = <1>;
+                qcom,msm-bus,name = "qcrypto-noc";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,active-only = <0>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<56 512 0 0>,
+				<56 512 3936000 393600>;
 	};
 
 	qcom,usbbam@f9304000 {
@@ -1085,6 +1063,7 @@
 		qcom,usb-bam-num-pipes = <16>;
 		qcom,usb-base-address = <0xf9200000>;
 		qcom,ignore-core-reset-ack;
+		qcom,disable-clk-gating;
 
 		qcom,pipe1 {
 			label = "usb-to-peri-qdss-dwc3";
@@ -1112,6 +1091,7 @@
 			qcom,data-fifo-size = <0x1800>;
 			qcom,descriptor-fifo-offset = <0xf4000>;
 			qcom,descriptor-fifo-size = <0x1400>;
+			qcom,reset-bam-on-connect;
 		};
 
 		qcom,pipe3 {
@@ -1145,7 +1125,7 @@
 
 	qcom,msm-thermal {
 		compatible = "qcom,msm-thermal";
-		qcom,sensor-id = <0>;
+		qcom,sensor-id = <5>;
 		qcom,poll-ms = <250>;
 		qcom,limit-temp = <60>;
 		qcom,temp-hysteresis = <10>;
@@ -1167,6 +1147,26 @@
                 qcom,memblock-remove = <0x7f00000 0x8000000>; /* Address and Size of Hole */
         };
 
+	uart7: uart@f995d000 { /*BLSP #2, UART #7 */
+		compatible = "qcom,msm-hsuart-v14";
+		status = "disabled";
+		reg = <0xf995d000 0x1000>,
+			<0xf9944000 0x19000>;
+		reg-names = "core_mem", "bam_mem";
+		interrupts = <0 113 0>, <0 239 0>;
+		interrupt-names = "core_irq", "bam_irq";
+
+		qcom,bam-tx-ep-pipe-index = <0>;
+		qcom,bam-rx-ep-pipe-index = <1>;
+		qcom,msm-bus,name = "uart7";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,active-only = <0>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<84 512 0 0>,
+				<84 512 500 800>;
+	};
+
 	qcom,smem@fa00000 {
 		compatible = "qcom,smem";
 		reg = <0xfa00000 0x200000>,
@@ -1234,6 +1234,27 @@
 			qcom,irq-no-suspend;
 		};
 	};
+
+	qcom,bcl {
+		compatible = "qcom,bcl";
+	};
+
+	qcom,ssm {
+		compatible = "qcom,ssm";
+		qcom,channel-name = "SSM_RTR";
+	};
+
+	sfpb_spinlock: qcom,ipc-spinlock@fd484000 {
+		compatible = "qcom,ipc-spinlock-sfpb";
+		reg = <0xfd484000 0x1000>;
+		qcom,num-locks = <32>;
+	};
+
+	ldrex_spinlock: qcom,ipc-spinlock@fa00000 {
+		compatible = "qcom,ipc-spinlock-ldrex";
+		reg = <0xfa00000 0x200000>;
+		status = "disable";
+	};
 };
 
 &gdsc_venus {
diff --git a/arch/arm/boot/dts/msm9625-cdp.dts b/arch/arm/boot/dts/msm9625-cdp.dts
deleted file mode 100644
index 232fba7..0000000
--- a/arch/arm/boot/dts/msm9625-cdp.dts
+++ /dev/null
@@ -1,97 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/ "msm9625.dtsi"
-
-/ {
-	model = "Qualcomm MSM 9625 CDP";
-	compatible = "qcom,msm9625-cdp", "qcom,msm9625";
-	qcom,msm-id = <134 1 0>, <152 1 0>;
-
-	i2c@f9925000 {
-		charger@57 {
-			compatible = "summit,smb137c";
-			reg = <0x57>;
-			summit,chg-current-ma = <1500>;
-			summit,term-current-ma = <50>;
-			summit,pre-chg-current-ma = <100>;
-			summit,float-voltage-mv = <4200>;
-			summit,thresh-voltage-mv = <3000>;
-			summit,recharge-thresh-mv = <75>;
-			summit,system-voltage-mv = <4250>;
-			summit,charging-timeout = <382>;
-			summit,pre-charge-timeout = <48>;
-			summit,therm-current-ua = <10>;
-			summit,temperature-min = <4>; /*  0 C */
-			summit,temperature-max = <3>; /* 45 C */
-		};
-	};
-
-	wlan0: qca,wlan {
-		cell-index = <0>;
-		compatible = "qca,ar6004-sdio";
-		qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
-		qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
-		qca,ar6004-vdd-io-supply = <&pm8019_l11>;
-	};
-};
-
-/* PM8019 GPIO and MPP configuration */
-&pm8019_gpios {
-	gpio@c000 { /* GPIO 1 */
-	};
-
-	gpio@c100 { /* GPIO 2 */
-	};
-
-	gpio@c200 { /* GPIO 3 */
-	};
-
-	gpio@c300 { /* GPIO 4 */
-		/* ext_2p95v regulator enable config */
-		qcom,mode = <1>; /* Digital output */
-		qcom,output-type = <0>; /* CMOS */
-		qcom,invert = <0>; /* Output low */
-		qcom,out-strength = <1>; /* Low */
-		qcom,vin-sel = <2>; /* PM8019 L11 - 1.8V */
-		qcom,src-sel = <0>; /* Constant */
-		qcom,master-en = <1>; /* Enable GPIO */
-	};
-
-	gpio@c400 { /* GPIO 5 */
-	};
-
-	gpio@c500 { /* GPIO 6 */
-	};
-};
-
-&pm8019_mpps {
-	mpp@a000 { /* MPP 1 */
-	};
-
-	mpp@a100 { /* MPP 2 */
-	};
-
-	mpp@a200 { /* MPP 3 */
-	};
-
-	mpp@a300 { /* MPP 4 */
-	};
-
-	mpp@a400 { /* MPP 5 */
-	};
-
-	mpp@a500 { /* MPP 6 */
-	};
-};
diff --git a/arch/arm/boot/dts/msm9625-coresight.dtsi b/arch/arm/boot/dts/msm9625-coresight.dtsi
index f01fe63..0af8fa5 100644
--- a/arch/arm/boot/dts/msm9625-coresight.dtsi
+++ b/arch/arm/boot/dts/msm9625-coresight.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -15,18 +15,21 @@
 		compatible = "arm,coresight-tmc";
 		reg = <0xfc322000 0x1000>,
 		      <0xfc37c000 0x3000>;
+		reg-names = "tmc-etr-base", "tmc-etr-bam-base";
 
 		qcom,memory-reservation-type = "EBI1";
-		qcom,memory-reservation-size = <0x100000>; /* 1M EBI1 buffer */
+		qcom,memory-reservation-size = <0x20000>; /* 128K EBI1 buffer */
 
 		coresight-id = <0>;
 		coresight-name = "coresight-tmc-etr";
 		coresight-nr-inports = <1>;
+		coresight-ctis = <&cti0 &cti8>;
 	};
 
 	tpiu: tpiu@fc318000 {
 		compatible = "arm,coresight-tpiu";
 		reg = <0xfc318000 0x1000>;
+		reg-names = "tpiu-base";
 
 		coresight-id = <1>;
 		coresight-name = "coresight-tpiu";
@@ -36,6 +39,7 @@
 	replicator: replicator@fc31c000 {
 		compatible = "qcom,coresight-replicator";
 		reg = <0xfc31c000 0x1000>;
+		reg-names = "replicator-base";
 
 		coresight-id = <2>;
 		coresight-name = "coresight-replicator";
@@ -48,6 +52,7 @@
 	tmc_etf: tmc@fc307000 {
 		compatible = "arm,coresight-tmc";
 		reg = <0xfc307000 0x1000>;
+		reg-names = "tmc-etf-base";
 
 		coresight-id = <3>;
 		coresight-name = "coresight-tmc-etf";
@@ -56,11 +61,13 @@
 		coresight-child-list = <&replicator>;
 		coresight-child-ports = <0>;
 		coresight-default-sink;
+		coresight-ctis = <&cti0 &cti8>;
 	};
 
 	funnel_merg: funnel@fc31b000 {
 		compatible = "arm,coresight-funnel";
 		reg = <0xfc31b000 0x1000>;
+		reg-names = "funnel-merg-base";
 
 		coresight-id = <4>;
 		coresight-name = "coresight-funnel-merg";
@@ -73,6 +80,7 @@
 	funnel_in0: funnel@fc319000 {
 		compatible = "arm,coresight-funnel";
 		reg = <0xfc319000 0x1000>;
+		reg-names = "funnel-in0-base";
 
 		coresight-id = <5>;
 		coresight-name = "coresight-funnel-in0";
@@ -85,6 +93,7 @@
 	funnel_in1: funnel@fc31a000 {
 		compatible = "arm,coresight-funnel";
 		reg = <0xfc31a000 0x1000>;
+		reg-names = "funnel-in1-base";
 
 		coresight-id = <6>;
 		coresight-name = "coresight-funnel-in1";
@@ -98,6 +107,7 @@
 		compatible = "arm,coresight-stm";
 		reg = <0xfc321000 0x1000>,
 		      <0xfa280000 0x180000>;
+		reg-names = "stm-base", "stm-data-base";
 
 		coresight-id = <7>;
 		coresight-name = "coresight-stm";
@@ -107,12 +117,130 @@
 		coresight-child-ports = <7>;
 	};
 
+	etm: etm@fc332000 {
+		compatible = "arm,coresight-etm";
+		reg = <0xfc332000 0x1000>;
+		reg-names = "etm-base";
+
+		coresight-id = <8>;
+		coresight-name = "coresight-etm";
+		coresight-nr-inports = <0>;
+		coresight-outports = <0>;
+		coresight-child-list = <&funnel_in0>;
+		coresight-child-ports = <4>;
+
+		qcom,round-robin;
+	};
+
 	csr: csr@fc302000 {
 		compatible = "qcom,coresight-csr";
 		reg = <0xfc302000 0x1000>;
+		reg-names = "csr-base";
 
-		coresight-id = <8>;
+		coresight-id = <9>;
 		coresight-name = "coresight-csr";
 		coresight-nr-inports = <0>;
+
+		qcom,blk-size = <1>;
+	};
+
+	cti0: cti@fc308000 {
+		compatible = "arm,coresight-cti";
+		reg = <0xfc308000 0x1000>;
+		reg-names = "cti0-base";
+
+		coresight-id = <10>;
+		coresight-name = "coresight-cti0";
+		coresight-nr-inports = <0>;
+	};
+
+	cti1: cti@fc309000 {
+		compatible = "arm,coresight-cti";
+		reg = <0xfc309000 0x1000>;
+		reg-names = "cti1-base";
+
+		coresight-id = <11>;
+		coresight-name = "coresight-cti1";
+		coresight-nr-inports = <0>;
+	};
+
+	cti2: cti@fc30a000 {
+		compatible = "arm,coresight-cti";
+		reg = <0xfc30a000 0x1000>;
+		reg-names = "cti2-base";
+
+		coresight-id = <12>;
+		coresight-name = "coresight-cti2";
+		coresight-nr-inports = <0>;
+	};
+
+	cti3: cti@fc30b000 {
+		compatible = "arm,coresight-cti";
+		reg = <0xfc30b000 0x1000>;
+		reg-names = "cti3-base";
+
+		coresight-id = <13>;
+		coresight-name = "coresight-cti3";
+		coresight-nr-inports = <0>;
+	};
+
+	cti4: cti@fc30c000 {
+		compatible = "arm,coresight-cti";
+		reg = <0xfc30c000 0x1000>;
+		reg-names = "cti4-base";
+
+		coresight-id = <14>;
+		coresight-name = "coresight-cti4";
+		coresight-nr-inports = <0>;
+	};
+
+	cti5: cti@fc30d000 {
+		compatible = "arm,coresight-cti";
+		reg = <0xfc30d000 0x1000>;
+		reg-names = "cti5-base";
+
+		coresight-id = <15>;
+		coresight-name = "coresight-cti5";
+		coresight-nr-inports = <0>;
+	};
+
+	cti6: cti@fc30e000 {
+		compatible = "arm,coresight-cti";
+		reg = <0xfc30e000 0x1000>;
+		reg-names = "cti6-base";
+
+		coresight-id = <16>;
+		coresight-name = "coresight-cti6";
+		coresight-nr-inports = <0>;
+	};
+
+	cti7: cti@fc30f000 {
+		compatible = "arm,coresight-cti";
+		reg = <0xfc30f000 0x1000>;
+		reg-names = "cti7-base";
+
+		coresight-id = <17>;
+		coresight-name = "coresight-cti7";
+		coresight-nr-inports = <0>;
+	};
+
+	cti8: cti@fc310000 {
+		compatible = "arm,coresight-cti";
+		reg = <0xfc310000 0x1000>;
+		reg-names = "cti8-base";
+
+		coresight-id = <18>;
+		coresight-name = "coresight-cti8";
+		coresight-nr-inports = <0>;
+	};
+
+	cti_cpu: cti@fc333000 {
+		compatible = "arm,coresight-cti";
+		reg = <0xfc333000 0x1000>;
+		reg-names = "cti-cpu-base";
+
+		coresight-id = <19>;
+		coresight-name = "coresight-cti-cpu";
+		coresight-nr-inports = <0>;
 	};
 };
diff --git a/arch/arm/boot/dts/msm9625-mtp.dts b/arch/arm/boot/dts/msm9625-mtp.dts
deleted file mode 100644
index faf86d4..0000000
--- a/arch/arm/boot/dts/msm9625-mtp.dts
+++ /dev/null
@@ -1,97 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/ "msm9625.dtsi"
-
-/ {
-	model = "Qualcomm MSM 9625 MTP";
-	compatible = "qcom,msm9625-mtp", "qcom,msm9625";
-	qcom,msm-id = <134 7 0>, <152 7 0>;
-
-	i2c@f9925000 {
-		charger@57 {
-			compatible = "summit,smb137c";
-			reg = <0x57>;
-			summit,chg-current-ma = <1500>;
-			summit,term-current-ma = <50>;
-			summit,pre-chg-current-ma = <100>;
-			summit,float-voltage-mv = <4200>;
-			summit,thresh-voltage-mv = <3000>;
-			summit,recharge-thresh-mv = <75>;
-			summit,system-voltage-mv = <4250>;
-			summit,charging-timeout = <382>;
-			summit,pre-charge-timeout = <48>;
-			summit,therm-current-ua = <10>;
-			summit,temperature-min = <4>; /*  0 C */
-			summit,temperature-max = <3>; /* 45 C */
-		};
-	};
-
-	wlan0: qca,wlan {
-		cell-index = <0>;
-		compatible = "qca,ar6004-sdio";
-		qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
-		qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
-		qca,ar6004-vdd-io-supply = <&pm8019_l11>;
-	};
-};
-
-/* PM8019 GPIO and MPP configuration */
-&pm8019_gpios {
-	gpio@c000 { /* GPIO 1 */
-	};
-
-	gpio@c100 { /* GPIO 2 */
-	};
-
-	gpio@c200 { /* GPIO 3 */
-	};
-
-	gpio@c300 { /* GPIO 4 */
-		/* ext_2p95v regulator enable config */
-		qcom,mode = <1>; /* Digital output */
-		qcom,output-type = <0>; /* CMOS */
-		qcom,invert = <0>; /* Output low */
-		qcom,out-strength = <1>; /* Low */
-		qcom,vin-sel = <2>; /* PM8019 L11 - 1.8V */
-		qcom,src-sel = <0>; /* Constant */
-		qcom,master-en = <1>; /* Enable GPIO */
-	};
-
-	gpio@c400 { /* GPIO 5 */
-	};
-
-	gpio@c500 { /* GPIO 6 */
-	};
-};
-
-&pm8019_mpps {
-	mpp@a000 { /* MPP 1 */
-	};
-
-	mpp@a100 { /* MPP 2 */
-	};
-
-	mpp@a200 { /* MPP 3 */
-	};
-
-	mpp@a300 { /* MPP 4 */
-	};
-
-	mpp@a400 { /* MPP 5 */
-	};
-
-	mpp@a500 { /* MPP 6 */
-	};
-};
diff --git a/arch/arm/boot/dts/msm9625-pm.dtsi b/arch/arm/boot/dts/msm9625-pm.dtsi
index 71fcfd6..1880965 100644
--- a/arch/arm/boot/dts/msm9625-pm.dtsi
+++ b/arch/arm/boot/dts/msm9625-pm.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -71,6 +71,8 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 
+		qcom,use-qtimer;
+
 		qcom,lpm-level@0 {
 			reg = <0x0>;
 			qcom,mode = <0>;        /* MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT */
@@ -80,6 +82,8 @@
 			qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
 			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
 			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
+			qcom,irqs-detectable;
+			qcom.gpios-detectable;
 			qcom,latency-us = <100>;
 			qcom,ss-power = <8000>;
 			qcom,energy-overhead = <100000>;
@@ -95,6 +99,8 @@
 			qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
 			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
 			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
+			qcom,irqs-detectable;
+			qcom.gpios-detectable;
 			qcom,latency-us = <2000>;
 			qcom,ss-power = <5000>;
 			qcom,energy-overhead = <60100000>;
@@ -110,6 +116,8 @@
 			qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
 			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
 			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
+			qcom,irqs-detectable;
+			qcom.gpios-detectable;
 			qcom,latency-us = <3500>;
 			qcom,ss-power = <5000>;
 			qcom,energy-overhead = <60350000>;
@@ -125,6 +133,8 @@
 			qcom,vdd-mem-lower-bound = <950000>; /* SVS SOC */
 			qcom,vdd-dig-upper-bound = <4>; /* NORMAL */
 			qcom,vdd-dig-lower-bound = <3>;  /* SVS SOC */
+			qcom,irqs-detectable;
+			qcom.gpios-detectable;
 			qcom,latency-us = <4500>;
 			qcom,ss-power = <5000>;
 			qcom,energy-overhead = <60350000>;
@@ -140,6 +150,7 @@
 			qcom,vdd-mem-lower-bound = <950000>; /* NORMAL */
 			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
 			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
+			qcom,irqs-detectable;
 			qcom,latency-us = <6800>;
 			qcom,ss-power = <2000>;
 			qcom,energy-overhead = <71850000>;
@@ -178,8 +189,38 @@
 
 		qcom,gic-parent = <&intc>;
 		qcom,gic-map = <47 172>, /* usb2_hsic_async_wakeup_irq */
-			<62 222>, /* ee0_krait_hlos_spmi_periph_irq */
-			<0xff 208>; /* summary_irq_kpss */
+			<41 180>,   /* usb_async_wakeup_irq */
+			<62 222>,   /* ee0_krait_hlos_spmi_periph_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 173>, /* o_wcss_apss_smd_hi */
+			<0xff 174>, /* o_wcss_apss_smd_med */
+			<0xff 175>, /* o_wcss_apss_smd_lo */
+			<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 188>, /* q6ss_irq_out(4) */
+			<0xff 189>, /* q6ss_irq_out(5) */
+			<0xff 190>, /* q6ss_irq_out(6) */
+			<0xff 191>, /* q6ss_irq_out(7) */
+			<0xff 192>, /* audio_out0_irq */
+			<0xff 193>, /* midi_arm_irq */
+			<0xff 194>, /* q6ss_wdog_exp_irq */
+			<0xff 195>, /* slimbus_core_ee1_irq */
+			<0xff 196>, /* bam_irq(1) */
+			<0xff 197>, /* qdss_irq_out(7) */
+			<0xff 200>, /* rpm_ipc(4) */
+			<0xff 201>, /* rpm_ipc(5) */
+			<0xff 202>, /* rpm_ipc(6) */
+			<0xff 203>, /* rpm_ipc(7)   */
+			<0xff 204>, /* rpm_ipc(24)   */
+			<0xff 205>, /* rpm_ipc(25)   */
+			<0xff 206>, /* rpm_ipc(26)   */
+			<0xff 207>, /* rpm_ipc(27)   */
+			<0xff 240>; /* summary_irq_kpss */
 
 		qcom,gpio-parent = <&msmgpio>;
 		qcom,gpio-map = <4  1>,
@@ -224,6 +265,17 @@
 		qcom,use-sync-timer;
 	};
 
+	qcom,rpm-log@fc19dc00 {
+		compatible = "qcom,rpm-log";
+		reg = <0xfc19dc00 0x4000>;
+		qcom,rpm-addr-phys = <0xfc000000>;
+		qcom,offset-version = <4>;
+		qcom,offset-page-buffer-addr = <36>;
+		qcom,offset-log-len = <40>;
+		qcom,offset-log-len-mask = <44>;
+		qcom,offset-page-indices = <56>;
+	};
+
 	qcom,rpm-stats@fc19dbd0 {
 		compatible = "qcom,rpm-stats";
 		reg = <0xfc19dbd0 0x1000>;
diff --git a/arch/arm/boot/dts/msm9625-rumi.dts b/arch/arm/boot/dts/msm9625-rumi.dts
deleted file mode 100644
index dadb3f7..0000000
--- a/arch/arm/boot/dts/msm9625-rumi.dts
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/ "msm9625.dtsi"
-
-/ {
-	model = "Qualcomm MSM 9625 RUMI";
-	compatible = "qcom,msm9625-rumi", "qcom,msm9625";
-	qcom,msm-id = <134 15 0>;
-
-	chosen{
-		bootargs = "root=/dev/ram rw init=/init console=ttyHSL0,115200n8 initrd=0x00000000,0x00000000 mem=29M@0x00200000 mem=10M@0x07600000";
-
-	};
-};
diff --git a/arch/arm/boot/dts/msm9625-smp2p.dtsi b/arch/arm/boot/dts/msm9625-smp2p.dtsi
new file mode 100644
index 0000000..425bf00
--- /dev/null
+++ b/arch/arm/boot/dts/msm9625-smp2p.dtsi
@@ -0,0 +1,152 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+/ {
+	qcom,smp2p-modem {
+		compatible = "qcom,smp2p";
+		reg = <0xfa006000 0x1000>, <0x8 0x0>;
+		reg-names = "irq-reg-base", "irq-reg-offset";
+		qcom,remote-pid = <1>;
+		qcom,irq-bitmask = <0x4000>;
+		interrupts = <0 27 1>;
+	};
+
+	qcom,smp2p-adsp {
+		compatible = "qcom,smp2p";
+		reg = <0xfa006000 0x1000>, <0x8 0x0>;
+		reg-names = "irq-reg-base", "irq-reg-offset";
+		qcom,remote-pid = <2>;
+		qcom,irq-bitmask = <0x400>;
+		interrupts = <0 158 1>;
+	};
+
+	/* SMP2P Test Driver for inbound entries */
+	smp2pgpio_smp2p_7_in: qcom,smp2pgpio-smp2p-7-in {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <7>;
+		qcom,is-inbound;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	qcom,smp2pgpio_test_smp2p_7_in {
+		compatible = "qcom,smp2pgpio_test_smp2p_7_in";
+		gpios = <&smp2pgpio_smp2p_7_in 0 0>;
+	};
+
+	/* SMP2P Test Driver for outbound entries */
+	smp2pgpio_smp2p_7_out: qcom,smp2pgpio-smp2p-7-out {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <7>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	qcom,smp2pgpio_test_smp2p_7_out {
+		compatible = "qcom,smp2pgpio_test_smp2p_7_out";
+		gpios = <&smp2pgpio_smp2p_7_out 0 0>;
+	};
+
+	/* SMP2P Test Driver for modem inbound */
+	smp2pgpio_smp2p_1_in: qcom,smp2pgpio-smp2p-1-in {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <1>;
+		qcom,is-inbound;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	qcom,smp2pgpio_test_smp2p_1_in {
+		compatible = "qcom,smp2pgpio_test_smp2p_1_in";
+		gpios = <&smp2pgpio_smp2p_1_in 0 0>;
+	};
+
+	/* SMP2P Test Driver for modem output */
+	smp2pgpio_smp2p_1_out: qcom,smp2pgpio-smp2p-1-out {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <1>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	qcom,smp2pgpio_test_smp2p_1_out {
+		compatible = "qcom,smp2pgpio_test_smp2p_1_out";
+		gpios = <&smp2pgpio_smp2p_1_out 0 0>;
+	};
+
+	/* SMP2P SSR Driver for inbound entry from modem. */
+	smp2pgpio_ssr_smp2p_1_in: qcom,smp2pgpio-ssr-smp2p-1-in {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "slave-kernel";
+		qcom,remote-pid = <1>;
+		qcom,is-inbound;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	/* SMP2P SSR Driver for outbound entry to modem */
+	smp2pgpio_ssr_smp2p_1_out: qcom,smp2pgpio-ssr-smp2p-1-out {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "master-kernel";
+		qcom,remote-pid = <1>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	/* SMP2P Test Driver for adsp inbound */
+	smp2pgpio_smp2p_2_in: qcom,smp2pgpio-smp2p-2-in {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <2>;
+		qcom,is-inbound;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	qcom,smp2pgpio_test_smp2p_2_in {
+		compatible = "qcom,smp2pgpio_test_smp2p_2_in";
+		gpios = <&smp2pgpio_smp2p_2_in 0 0>;
+	};
+
+	/* SMP2P Test Driver for adsp output */
+	smp2pgpio_smp2p_2_out: qcom,smp2pgpio-smp2p-2-out {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <2>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	qcom,smp2pgpio_test_smp2p_2_out {
+		compatible = "qcom,smp2pgpio_test_smp2p_2_out";
+		gpios = <&smp2pgpio_smp2p_2_out 0 0>;
+	};
+};
diff --git a/arch/arm/boot/dts/msm9625-v1-cdp.dts b/arch/arm/boot/dts/msm9625-v1-cdp.dts
new file mode 100644
index 0000000..6221ba1
--- /dev/null
+++ b/arch/arm/boot/dts/msm9625-v1-cdp.dts
@@ -0,0 +1,99 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/include/ "msm9625-v1.dtsi"
+
+/ {
+	model = "Qualcomm MSM 9625V1 CDP";
+	compatible = "qcom,msm9625-cdp", "qcom,msm9625";
+	qcom,msm-id = <134 1 0>, <152 1 0>, <149 1 0>, <150 1 0>,
+		      <151 1 0>, <148 1 0>, <173 1 0>, <174 1 0>,
+		      <175 1 0>;
+
+	i2c@f9925000 {
+		charger@57 {
+			compatible = "summit,smb137c";
+			reg = <0x57>;
+			summit,chg-current-ma = <1500>;
+			summit,term-current-ma = <50>;
+			summit,pre-chg-current-ma = <100>;
+			summit,float-voltage-mv = <4200>;
+			summit,thresh-voltage-mv = <3000>;
+			summit,recharge-thresh-mv = <75>;
+			summit,system-voltage-mv = <4250>;
+			summit,charging-timeout = <382>;
+			summit,pre-charge-timeout = <48>;
+			summit,therm-current-ua = <10>;
+			summit,temperature-min = <4>; /*  0 C */
+			summit,temperature-max = <3>; /* 45 C */
+		};
+	};
+
+	wlan0: qca,wlan {
+		cell-index = <0>;
+		compatible = "qca,ar6004-sdio";
+		qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
+		qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
+		qca,ar6004-vdd-io-supply = <&pm8019_l11>;
+	};
+};
+
+/* PM8019 GPIO and MPP configuration */
+&pm8019_gpios {
+	gpio@c000 { /* GPIO 1 */
+	};
+
+	gpio@c100 { /* GPIO 2 */
+	};
+
+	gpio@c200 { /* GPIO 3 */
+	};
+
+	gpio@c300 { /* GPIO 4 */
+		/* ext_2p95v regulator enable config */
+		qcom,mode = <1>; /* Digital output */
+		qcom,output-type = <0>; /* CMOS */
+		qcom,invert = <0>; /* Output low */
+		qcom,out-strength = <1>; /* Low */
+		qcom,vin-sel = <2>; /* PM8019 L11 - 1.8V */
+		qcom,src-sel = <0>; /* Constant */
+		qcom,master-en = <1>; /* Enable GPIO */
+	};
+
+	gpio@c400 { /* GPIO 5 */
+	};
+
+	gpio@c500 { /* GPIO 6 */
+	};
+};
+
+&pm8019_mpps {
+	mpp@a000 { /* MPP 1 */
+	};
+
+	mpp@a100 { /* MPP 2 */
+	};
+
+	mpp@a200 { /* MPP 3 */
+	};
+
+	mpp@a300 { /* MPP 4 */
+	};
+
+	mpp@a400 { /* MPP 5 */
+	};
+
+	mpp@a500 { /* MPP 6 */
+	};
+};
diff --git a/arch/arm/boot/dts/msm9625-v1-mtp.dts b/arch/arm/boot/dts/msm9625-v1-mtp.dts
new file mode 100644
index 0000000..5ff9e92
--- /dev/null
+++ b/arch/arm/boot/dts/msm9625-v1-mtp.dts
@@ -0,0 +1,99 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/include/ "msm9625-v1.dtsi"
+
+/ {
+	model = "Qualcomm MSM 9625V1 MTP";
+	compatible = "qcom,msm9625-mtp", "qcom,msm9625";
+	qcom,msm-id = <134 7 0>, <152 7 0>, <149 7 0>, <150 7 0>,
+		      <151 7 0>, <148 7 0>, <173 7 0>, <174 7 0>,
+		      <175 7 0>;
+
+	i2c@f9925000 {
+		charger@57 {
+			compatible = "summit,smb137c";
+			reg = <0x57>;
+			summit,chg-current-ma = <1500>;
+			summit,term-current-ma = <50>;
+			summit,pre-chg-current-ma = <100>;
+			summit,float-voltage-mv = <4200>;
+			summit,thresh-voltage-mv = <3000>;
+			summit,recharge-thresh-mv = <75>;
+			summit,system-voltage-mv = <4250>;
+			summit,charging-timeout = <382>;
+			summit,pre-charge-timeout = <48>;
+			summit,therm-current-ua = <10>;
+			summit,temperature-min = <4>; /*  0 C */
+			summit,temperature-max = <3>; /* 45 C */
+		};
+	};
+
+	wlan0: qca,wlan {
+		cell-index = <0>;
+		compatible = "qca,ar6004-sdio";
+		qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
+		qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
+		qca,ar6004-vdd-io-supply = <&pm8019_l11>;
+	};
+};
+
+/* PM8019 GPIO and MPP configuration */
+&pm8019_gpios {
+	gpio@c000 { /* GPIO 1 */
+	};
+
+	gpio@c100 { /* GPIO 2 */
+	};
+
+	gpio@c200 { /* GPIO 3 */
+	};
+
+	gpio@c300 { /* GPIO 4 */
+		/* ext_2p95v regulator enable config */
+		qcom,mode = <1>; /* Digital output */
+		qcom,output-type = <0>; /* CMOS */
+		qcom,invert = <0>; /* Output low */
+		qcom,out-strength = <1>; /* Low */
+		qcom,vin-sel = <2>; /* PM8019 L11 - 1.8V */
+		qcom,src-sel = <0>; /* Constant */
+		qcom,master-en = <1>; /* Enable GPIO */
+	};
+
+	gpio@c400 { /* GPIO 5 */
+	};
+
+	gpio@c500 { /* GPIO 6 */
+	};
+};
+
+&pm8019_mpps {
+	mpp@a000 { /* MPP 1 */
+	};
+
+	mpp@a100 { /* MPP 2 */
+	};
+
+	mpp@a200 { /* MPP 3 */
+	};
+
+	mpp@a300 { /* MPP 4 */
+	};
+
+	mpp@a400 { /* MPP 5 */
+	};
+
+	mpp@a500 { /* MPP 6 */
+	};
+};
diff --git a/arch/arm/boot/dts/msm9625-v1-rumi.dts b/arch/arm/boot/dts/msm9625-v1-rumi.dts
new file mode 100644
index 0000000..a854947
--- /dev/null
+++ b/arch/arm/boot/dts/msm9625-v1-rumi.dts
@@ -0,0 +1,26 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/include/ "msm9625-v1.dtsi"
+
+/ {
+	model = "Qualcomm MSM 9625V1 RUMI";
+	compatible = "qcom,msm9625-rumi", "qcom,msm9625";
+	qcom,msm-id = <134 15 0>;
+
+	chosen{
+		bootargs = "root=/dev/ram rw init=/init console=ttyHSL0,115200n8 initrd=0x00000000,0x00000000 mem=29M@0x00200000 mem=10M@0x07600000";
+
+	};
+};
diff --git a/arch/arm/boot/dts/msm9625-v1.dtsi b/arch/arm/boot/dts/msm9625-v1.dtsi
new file mode 100644
index 0000000..54fe443
--- /dev/null
+++ b/arch/arm/boot/dts/msm9625-v1.dtsi
@@ -0,0 +1,51 @@
+/* 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.
+ */
+
+/*
+ * As a general rule, only version-specific property overrides should be placed
+ * inside this file. However, device definitions should be placed inside the
+ * msm9625.dtsi file.
+ */
+
+/include/ "msm9625.dtsi"
+
+/ {
+	qcom,msm-imem@fc42a800 {
+		compatible = "qcom,msm-imem";
+		reg = <0xfc42a800 0x1000>; /* Address and size of IMEM */
+	};
+
+	android_usb@fc42a8c8 {
+		compatible = "qcom,android-usb";
+		reg = <0xfc42a8c8 0xc8>;
+		qcom,android-usb-swfi-latency = <100>;
+	};
+
+	qcom,bam_dmux@fc834000 {
+		compatible = "qcom,bam_dmux";
+		reg = <0xfc834000 0x7000>;
+		interrupts = <0 29 1>;
+	};
+};
+
+&ipa_hw {
+	qcom,ipa-hw-ver = <1>; /* IPA h-w revision */
+};
+
+/* CoreSight */
+&tmc_etr {
+	qcom,reset-flush-race;
+};
+
+&stm {
+	qcom,write-64bit;
+};
diff --git a/arch/arm/boot/dts/msm9625-v2-1-cdp.dts b/arch/arm/boot/dts/msm9625-v2-1-cdp.dts
new file mode 100644
index 0000000..8702184
--- /dev/null
+++ b/arch/arm/boot/dts/msm9625-v2-1-cdp.dts
@@ -0,0 +1,99 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/include/ "msm9625-v2-1.dtsi"
+
+/ {
+	model = "Qualcomm MSM 9625V2.1 CDP";
+	compatible = "qcom,msm9625-cdp", "qcom,msm9625";
+	qcom,msm-id = <134 1 0x20001>, <152 1 0x20001>, <149 1 0x20001>,
+		      <150 1 0x20001>, <151 1 0x20001>, <148 1 0x20001>,
+		      <173 1 0x20001>, <174 1 0x20001>, <175 1 0x20001>;
+
+	i2c@f9925000 {
+		charger@57 {
+			compatible = "summit,smb137c";
+			reg = <0x57>;
+			summit,chg-current-ma = <1500>;
+			summit,term-current-ma = <50>;
+			summit,pre-chg-current-ma = <100>;
+			summit,float-voltage-mv = <4200>;
+			summit,thresh-voltage-mv = <3000>;
+			summit,recharge-thresh-mv = <75>;
+			summit,system-voltage-mv = <4250>;
+			summit,charging-timeout = <382>;
+			summit,pre-charge-timeout = <48>;
+			summit,therm-current-ua = <10>;
+			summit,temperature-min = <4>; /*  0 C */
+			summit,temperature-max = <3>; /* 45 C */
+		};
+	};
+
+	wlan0: qca,wlan {
+		cell-index = <0>;
+		compatible = "qca,ar6004-sdio";
+		qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
+		qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
+		qca,ar6004-vdd-io-supply = <&pm8019_l11>;
+	};
+};
+
+/* PM8019 GPIO and MPP configuration */
+&pm8019_gpios {
+	gpio@c000 { /* GPIO 1 */
+	};
+
+	gpio@c100 { /* GPIO 2 */
+	};
+
+	gpio@c200 { /* GPIO 3 */
+	};
+
+	gpio@c300 { /* GPIO 4 */
+		/* ext_2p95v regulator enable config */
+		qcom,mode = <1>; /* Digital output */
+		qcom,output-type = <0>; /* CMOS */
+		qcom,invert = <0>; /* Output low */
+		qcom,out-strength = <1>; /* Low */
+		qcom,vin-sel = <2>; /* PM8019 L11 - 1.8V */
+		qcom,src-sel = <0>; /* Constant */
+		qcom,master-en = <1>; /* Enable GPIO */
+	};
+
+	gpio@c400 { /* GPIO 5 */
+	};
+
+	gpio@c500 { /* GPIO 6 */
+	};
+};
+
+&pm8019_mpps {
+	mpp@a000 { /* MPP 1 */
+	};
+
+	mpp@a100 { /* MPP 2 */
+	};
+
+	mpp@a200 { /* MPP 3 */
+	};
+
+	mpp@a300 { /* MPP 4 */
+	};
+
+	mpp@a400 { /* MPP 5 */
+	};
+
+	mpp@a500 { /* MPP 6 */
+	};
+};
diff --git a/arch/arm/boot/dts/msm9625-v2-1-mtp.dts b/arch/arm/boot/dts/msm9625-v2-1-mtp.dts
new file mode 100644
index 0000000..2dc040c
--- /dev/null
+++ b/arch/arm/boot/dts/msm9625-v2-1-mtp.dts
@@ -0,0 +1,99 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/include/ "msm9625-v2-1.dtsi"
+
+/ {
+	model = "Qualcomm MSM 9625V2.1 MTP";
+	compatible = "qcom,msm9625-mtp", "qcom,msm9625";
+	qcom,msm-id = <134 7 0x20001>, <152 7 0x20001>, <149 7 0x20001>,
+		      <150 7 0x20001>, <151 7 0x20001>, <148 7 0x20001>,
+		      <173 7 0x20001>, <174 7 0x20001>, <175 7 0x20001>;
+
+	i2c@f9925000 {
+		charger@57 {
+			compatible = "summit,smb137c";
+			reg = <0x57>;
+			summit,chg-current-ma = <1500>;
+			summit,term-current-ma = <50>;
+			summit,pre-chg-current-ma = <100>;
+			summit,float-voltage-mv = <4200>;
+			summit,thresh-voltage-mv = <3000>;
+			summit,recharge-thresh-mv = <75>;
+			summit,system-voltage-mv = <4250>;
+			summit,charging-timeout = <382>;
+			summit,pre-charge-timeout = <48>;
+			summit,therm-current-ua = <10>;
+			summit,temperature-min = <4>; /*  0 C */
+			summit,temperature-max = <3>; /* 45 C */
+		};
+	};
+
+	wlan0: qca,wlan {
+		cell-index = <0>;
+		compatible = "qca,ar6004-sdio";
+		qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
+		qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
+		qca,ar6004-vdd-io-supply = <&pm8019_l11>;
+	};
+};
+
+/* PM8019 GPIO and MPP configuration */
+&pm8019_gpios {
+	gpio@c000 { /* GPIO 1 */
+	};
+
+	gpio@c100 { /* GPIO 2 */
+	};
+
+	gpio@c200 { /* GPIO 3 */
+	};
+
+	gpio@c300 { /* GPIO 4 */
+		/* ext_2p95v regulator enable config */
+		qcom,mode = <1>; /* Digital output */
+		qcom,output-type = <0>; /* CMOS */
+		qcom,invert = <0>; /* Output low */
+		qcom,out-strength = <1>; /* Low */
+		qcom,vin-sel = <2>; /* PM8019 L11 - 1.8V */
+		qcom,src-sel = <0>; /* Constant */
+		qcom,master-en = <1>; /* Enable GPIO */
+	};
+
+	gpio@c400 { /* GPIO 5 */
+	};
+
+	gpio@c500 { /* GPIO 6 */
+	};
+};
+
+&pm8019_mpps {
+	mpp@a000 { /* MPP 1 */
+	};
+
+	mpp@a100 { /* MPP 2 */
+	};
+
+	mpp@a200 { /* MPP 3 */
+	};
+
+	mpp@a300 { /* MPP 4 */
+	};
+
+	mpp@a400 { /* MPP 5 */
+	};
+
+	mpp@a500 { /* MPP 6 */
+	};
+};
diff --git a/arch/arm/boot/dts/msm9625-v2-1.dtsi b/arch/arm/boot/dts/msm9625-v2-1.dtsi
new file mode 100644
index 0000000..c3c2c49
--- /dev/null
+++ b/arch/arm/boot/dts/msm9625-v2-1.dtsi
@@ -0,0 +1,36 @@
+/* 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.
+ */
+
+/*
+ * As a general rule, only version-specific property overrides should be placed
+ * inside this file. However, device definitions should be placed inside the
+ * msm9625.dtsi file.
+ */
+
+/include/ "msm9625.dtsi"
+
+/ {
+	qcom,msm-imem@fe807800 {
+		compatible = "qcom,msm-imem";
+		reg = <0xfe807800 0x1000>; /* Address and size of IMEM */
+	};
+
+	android_usb@fe8078c8 {
+		compatible = "qcom,android-usb";
+		reg = <0xfe8078c8 0xc8>;
+		qcom,android-usb-swfi-latency = <100>;
+	};
+};
+
+&ipa_hw {
+	qcom,ipa-hw-ver = <2>; /* IPA h-w revision */
+};
diff --git a/arch/arm/boot/dts/msm9625-v2-cdp.dts b/arch/arm/boot/dts/msm9625-v2-cdp.dts
new file mode 100644
index 0000000..244556d
--- /dev/null
+++ b/arch/arm/boot/dts/msm9625-v2-cdp.dts
@@ -0,0 +1,99 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/include/ "msm9625-v2.dtsi"
+
+/ {
+	model = "Qualcomm MSM 9625V2 CDP";
+	compatible = "qcom,msm9625-cdp", "qcom,msm9625";
+	qcom,msm-id = <134 1 0x20000>, <152 1 0x20000>, <149 1 0x20000>,
+		      <150 1 0x20000>, <151 1 0x20000>, <148 1 0x20000>,
+		      <173 1 0x20000>, <174 1 0x20000>, <175 1 0x20000>;
+
+	i2c@f9925000 {
+		charger@57 {
+			compatible = "summit,smb137c";
+			reg = <0x57>;
+			summit,chg-current-ma = <1500>;
+			summit,term-current-ma = <50>;
+			summit,pre-chg-current-ma = <100>;
+			summit,float-voltage-mv = <4200>;
+			summit,thresh-voltage-mv = <3000>;
+			summit,recharge-thresh-mv = <75>;
+			summit,system-voltage-mv = <4250>;
+			summit,charging-timeout = <382>;
+			summit,pre-charge-timeout = <48>;
+			summit,therm-current-ua = <10>;
+			summit,temperature-min = <4>; /*  0 C */
+			summit,temperature-max = <3>; /* 45 C */
+		};
+	};
+
+	wlan0: qca,wlan {
+		cell-index = <0>;
+		compatible = "qca,ar6004-sdio";
+		qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
+		qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
+		qca,ar6004-vdd-io-supply = <&pm8019_l11>;
+	};
+};
+
+/* PM8019 GPIO and MPP configuration */
+&pm8019_gpios {
+	gpio@c000 { /* GPIO 1 */
+	};
+
+	gpio@c100 { /* GPIO 2 */
+	};
+
+	gpio@c200 { /* GPIO 3 */
+	};
+
+	gpio@c300 { /* GPIO 4 */
+		/* ext_2p95v regulator enable config */
+		qcom,mode = <1>; /* Digital output */
+		qcom,output-type = <0>; /* CMOS */
+		qcom,invert = <0>; /* Output low */
+		qcom,out-strength = <1>; /* Low */
+		qcom,vin-sel = <2>; /* PM8019 L11 - 1.8V */
+		qcom,src-sel = <0>; /* Constant */
+		qcom,master-en = <1>; /* Enable GPIO */
+	};
+
+	gpio@c400 { /* GPIO 5 */
+	};
+
+	gpio@c500 { /* GPIO 6 */
+	};
+};
+
+&pm8019_mpps {
+	mpp@a000 { /* MPP 1 */
+	};
+
+	mpp@a100 { /* MPP 2 */
+	};
+
+	mpp@a200 { /* MPP 3 */
+	};
+
+	mpp@a300 { /* MPP 4 */
+	};
+
+	mpp@a400 { /* MPP 5 */
+	};
+
+	mpp@a500 { /* MPP 6 */
+	};
+};
diff --git a/arch/arm/boot/dts/msm9625-v2-mtp.dts b/arch/arm/boot/dts/msm9625-v2-mtp.dts
new file mode 100644
index 0000000..bf0f539
--- /dev/null
+++ b/arch/arm/boot/dts/msm9625-v2-mtp.dts
@@ -0,0 +1,99 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/include/ "msm9625-v2.dtsi"
+
+/ {
+	model = "Qualcomm MSM 9625V2 MTP";
+	compatible = "qcom,msm9625-mtp", "qcom,msm9625";
+	qcom,msm-id = <134 7 0x20000>, <152 7 0x20000>, <149 7 0x20000>,
+		      <150 7 0x20000>, <151 7 0x20000>, <148 7 0x20000>,
+		      <173 7 0x20000>, <174 7 0x20000>, <175 7 0x20000>;
+
+	i2c@f9925000 {
+		charger@57 {
+			compatible = "summit,smb137c";
+			reg = <0x57>;
+			summit,chg-current-ma = <1500>;
+			summit,term-current-ma = <50>;
+			summit,pre-chg-current-ma = <100>;
+			summit,float-voltage-mv = <4200>;
+			summit,thresh-voltage-mv = <3000>;
+			summit,recharge-thresh-mv = <75>;
+			summit,system-voltage-mv = <4250>;
+			summit,charging-timeout = <382>;
+			summit,pre-charge-timeout = <48>;
+			summit,therm-current-ua = <10>;
+			summit,temperature-min = <4>; /*  0 C */
+			summit,temperature-max = <3>; /* 45 C */
+		};
+	};
+
+	wlan0: qca,wlan {
+		cell-index = <0>;
+		compatible = "qca,ar6004-sdio";
+		qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
+		qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
+		qca,ar6004-vdd-io-supply = <&pm8019_l11>;
+	};
+};
+
+/* PM8019 GPIO and MPP configuration */
+&pm8019_gpios {
+	gpio@c000 { /* GPIO 1 */
+	};
+
+	gpio@c100 { /* GPIO 2 */
+	};
+
+	gpio@c200 { /* GPIO 3 */
+	};
+
+	gpio@c300 { /* GPIO 4 */
+		/* ext_2p95v regulator enable config */
+		qcom,mode = <1>; /* Digital output */
+		qcom,output-type = <0>; /* CMOS */
+		qcom,invert = <0>; /* Output low */
+		qcom,out-strength = <1>; /* Low */
+		qcom,vin-sel = <2>; /* PM8019 L11 - 1.8V */
+		qcom,src-sel = <0>; /* Constant */
+		qcom,master-en = <1>; /* Enable GPIO */
+	};
+
+	gpio@c400 { /* GPIO 5 */
+	};
+
+	gpio@c500 { /* GPIO 6 */
+	};
+};
+
+&pm8019_mpps {
+	mpp@a000 { /* MPP 1 */
+	};
+
+	mpp@a100 { /* MPP 2 */
+	};
+
+	mpp@a200 { /* MPP 3 */
+	};
+
+	mpp@a300 { /* MPP 4 */
+	};
+
+	mpp@a400 { /* MPP 5 */
+	};
+
+	mpp@a500 { /* MPP 6 */
+	};
+};
diff --git a/arch/arm/boot/dts/msm9625-v2.dtsi b/arch/arm/boot/dts/msm9625-v2.dtsi
new file mode 100644
index 0000000..c3c2c49
--- /dev/null
+++ b/arch/arm/boot/dts/msm9625-v2.dtsi
@@ -0,0 +1,36 @@
+/* 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.
+ */
+
+/*
+ * As a general rule, only version-specific property overrides should be placed
+ * inside this file. However, device definitions should be placed inside the
+ * msm9625.dtsi file.
+ */
+
+/include/ "msm9625.dtsi"
+
+/ {
+	qcom,msm-imem@fe807800 {
+		compatible = "qcom,msm-imem";
+		reg = <0xfe807800 0x1000>; /* Address and size of IMEM */
+	};
+
+	android_usb@fe8078c8 {
+		compatible = "qcom,android-usb";
+		reg = <0xfe8078c8 0xc8>;
+		qcom,android-usb-swfi-latency = <100>;
+	};
+};
+
+&ipa_hw {
+	qcom,ipa-hw-ver = <2>; /* IPA h-w revision */
+};
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 6fee4e6..8517605 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -14,12 +14,17 @@
 /include/ "msm9625-ion.dtsi"
 /include/ "msm9625-pm.dtsi"
 /include/ "msm9625-coresight.dtsi"
+/include/ "msm9625-smp2p.dtsi"
 
 / {
 	model = "Qualcomm MSM 9625";
 	compatible = "qcom,msm9625";
 	interrupt-parent = <&intc>;
 
+	aliases {
+		spi0 = &spi_0;
+	};
+
 	intc: interrupt-controller@F9000000 {
 		compatible = "qcom,msm-qgic2";
 		interrupt-controller;
@@ -42,7 +47,9 @@
 		interrupt-controller;
 		#interrupt-cells = <2>;
 		reg = <0xfd510000 0x4000>;
+		ngpio = <76>;
 		interrupts = <0 208 0>;
+		qcom,direct-connect-irqs = <8>;
 	};
 
 	timer: msm-qtimer@f9021000 {
@@ -79,15 +86,19 @@
 		vbus_otg-supply = <&usb_vbus>;
 
 		qcom,hsusb-otg-phy-type = <2>;
-		qcom,hsusb-otg-mode = <1>;
+		qcom,hsusb-otg-mode = <3>;
 		qcom,hsusb-otg-otg-control = <1>;
 		qcom,hsusb-otg-disable-reset;
-	};
+		qcom,hsusb-otg-lpm-on-dev-suspend;
+		qcom,hsusb-otg-clk-always-on-workaround;
 
-	android_usb@fc42b0c8 {
-		compatible = "qcom,android-usb";
-		reg = <0xfc42b0c8 0xc8>;
-		qcom,android-usb-swfi-latency = <100>;
+		qcom,msm-bus,name = "usb2";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,active-only = <0>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<87 512 0 0>,
+				<87 512 40000 640000>;
 	};
 
 	hsic@f9a15000 {
@@ -97,6 +108,14 @@
 		interrupt-names = "core_irq";
 		HSIC_VDDCX-supply = <&pm8019_l12>;
 		HSIC_GDSC-supply = <&gdsc_usb_hsic>;
+
+		qcom,msm-bus,name = "hsic";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,active-only = <0>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<85 512 0 0>,
+				<85 512 40000 640000>;
 	};
 
 	qcom,usbbam@f9a44000 {
@@ -109,25 +128,55 @@
 		qcom,usb-total-bam-num = <3>;
 		qcom,usb-bam-num-pipes = <16>;
 		qcom,ignore-core-reset-ack;
+		qcom,disable-clk-gating;
 
 		qcom,pipe0 {
 			label = "usb-to-ipa";
 			qcom,usb-bam-type = <1>;
-			qcom,usb-bam-mem-type = <2>;
+			qcom,usb-bam-mem-type = <0>;
 			qcom,src-bam-physical-address = <0xf9a44000>;
 			qcom,src-bam-pipe-index = <1>;
-			qcom,data-fifo-size = <0x600>;
-			qcom,descriptor-fifo-size = <0x300>;
+			qcom,data-fifo-offset = <0x2200>;
+			qcom,data-fifo-size = <0x1e00>;
+			qcom,descriptor-fifo-offset = <0x2100>;
+			qcom,descriptor-fifo-size = <0x100>;
 		};
-
 		qcom,pipe1 {
 			label = "ipa-to-usb";
 			qcom,usb-bam-type = <1>;
-			qcom,usb-bam-mem-type = <2>;
+			qcom,usb-bam-mem-type = <0>;
 			qcom,dst-bam-physical-address = <0xf9a44000>;
 			qcom,dst-bam-pipe-index = <0>;
-			qcom,data-fifo-size = <0x600>;
-			qcom,descriptor-fifo-size = <0x100>;
+			qcom,data-fifo-offset = <0x300>;
+			qcom,data-fifo-size = <0x1e00>;
+			qcom,descriptor-fifo-offset = <0>;
+			qcom,descriptor-fifo-size = <0x300>;
+		};
+		qcom,pipe2 {
+			label = "usb-to-qdss-hsusb";
+			qcom,usb-bam-type = <1>;
+			qcom,usb-bam-mem-type = <0>;
+			qcom,src-bam-physical-address = <0xf9a44000>;
+			qcom,src-bam-pipe-index = <0>;
+			qcom,dst-bam-physical-address = <0xfc37c000>;
+			qcom,dst-bam-pipe-index = <0>;
+			qcom,data-fifo-offset = <0>;
+			qcom,data-fifo-size = <0>;
+			qcom,descriptor-fifo-offset = <0>;
+			qcom,descriptor-fifo-size = <0>;
+		};
+		qcom,pipe3 {
+			label = "qdss-to-usb-hsusb";
+			qcom,usb-bam-type = <1>;
+			qcom,usb-bam-mem-type = <0>;
+			qcom,src-bam-physical-address = <0xfc37c000>;
+			qcom,src-bam-pipe-index = <0>;
+			qcom,dst-bam-physical-address = <0xf9a44000>;
+			qcom,dst-bam-pipe-index = <2>;
+			qcom,data-fifo-offset = <0x4100>;
+			qcom,data-fifo-size = <0x400>;
+			qcom,descriptor-fifo-offset = <0x4000>;
+			qcom,descriptor-fifo-size = <0x400>;
 		};
 	};
 
@@ -141,8 +190,7 @@
 		interrupt-names = "bam_irq";
 	};
 
-	spi@f9924000 {
-		cell-index = <0>;
+	spi_0: spi@f9924000 {
 		compatible = "qcom,spi-qup-v2";
 		reg = <0xf9924000 0x1000>;
 		interrupts = <0 96 0>;
@@ -170,7 +218,6 @@
 		interrupts = <1 2 0>, <1 1 0>;
 		qcom,bark-time = <11000>;
 		qcom,pet-time = <10000>;
-		qcom,ipi-ping = <0>;
 	};
 
 	rpm_bus: qcom,rpm-smd {
@@ -182,27 +229,15 @@
 	spmi_bus: qcom,spmi@fc4c0000 {
 		cell-index = <0>;
 		compatible = "qcom,spmi-pmic-arb";
+		reg-names = "core", "intr", "cnfg";
 		reg = <0xfc4cf000 0x1000>,
-		      <0Xfc4cb000 0x1000>;
+		      <0Xfc4cb000 0x1000>,
+		      <0Xfc4ca000 0x1000>;
 		/* 190,ee0_krait_hlos_spmi_periph_irq */
 		/* 187,channel_0_krait_hlos_trans_done_irq */
 		interrupts = <0 190 0 0 187 0>;
 		qcom,pmic-arb-ee = <0>;
 		qcom,pmic-arb-channel = <0>;
-		qcom,pmic-arb-ppid-map = <0x02400000>, /* TEMP_ALARM */
-					 <0x03100001>, /* VADC1_USR */
-					 <0x06100002>, /* RTC_ALARM */
-					 <0x06200003>, /* RTC_TIMER */
-					 <0x0a000004>, /* MPP1 */
-					 <0x0a100005>, /* MPP2 */
-					 <0x0a200006>, /* MPP3 */
-					 <0x0a300007>, /* MPP4 */
-					 <0x0a400008>, /* MPP5 */
-					 <0x0a500009>, /* MPP6 */
-					 <0x0c20000a>, /* GPIO3 */
-					 <0x0c30000b>, /* GPIO4 */
-					 <0x0c50000c>, /* GPIO6 */
-					 <0x0080000d>; /* PON */
 	};
 
 	i2c@f9925000 {
@@ -282,20 +317,16 @@
 		qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50";
 	};
 
-	qcom,bam_dmux@fc834000 {
-		compatible = "qcom,bam_dmux";
-		reg = <0xfc834000 0x7000>;
-		interrupts = <0 29 1>;
-	};
-
-	qcom,ipa@fd4c0000 {
+	ipa_hw: qcom,ipa@fd4c0000 {
 		compatible = "qcom,ipa";
 		reg = <0xfd4c0000 0x26000>,
-		      <0xfd4c4000 0x14818>;
-		reg-names = "ipa-base", "bam-base";
+		      <0xfd4c4000 0x14818>,
+		      <0xfc834000 0x7000>;
+		reg-names = "ipa-base", "bam-base", "a2-bam-base";
 		interrupts = <0 252 0>,
-		             <0 253 0>;
-		interrupt-names = "ipa-irq", "bam-irq";
+		             <0 253 0>,
+		             <0 29 1>;
+		interrupt-names = "ipa-irq", "bam-irq", "a2-bam-irq";
 
 		qcom,pipe1 {
 			label = "a2-to-ipa";
@@ -347,6 +378,7 @@
 		interrupts = <0 184 0>;
 		qcom,sensors = <5>;
 		qcom,slope = <3200 3200 3200 3200 3200>;
+		qcom,calib-mode = "fuse_map1";
 	};
 
 	qcom,msm-rng@f9bff000 {
@@ -469,6 +501,11 @@
 			"DMIC6", "MIC BIAS4 External",
 			"MIC BIAS4 External", "Digital Mic6";
 			qcom,taiko-mclk-clk-freq = <12288000>;
+			prim-i2s-gpio-ws   = <&msmgpio 12 0>;
+			prim-i2s-gpio-din  = <&msmgpio 13 0>;
+			prim-i2s-gpio-dout = <&msmgpio 14 0>;
+			prim-i2s-gpio-sclk = <&msmgpio 15 0>;
+			prim-i2s-gpio-mclk = <&msmgpio 71 0>;
 	};
 
 	qcom,msm-adsp-loader {
@@ -478,6 +515,7 @@
 
 	qcom,msm-pcm {
 		compatible = "qcom,msm-pcm-dsp";
+		qcom,msm-pcm-dsp-id = <0>;
 	};
 
 	qcom,msm-pcm-routing {
@@ -496,6 +534,10 @@
 		compatible = "qcom,msm-pcm-voice";
 	};
 
+	qcom,msm-stub-codec {
+		compatible = "qcom,msm-stub-codec";
+	};
+
 	qcom,msm-dai-fe {
 		compatible = "qcom,msm-dai-fe";
 	};
@@ -508,6 +550,62 @@
 		compatible = "qcom,msm-pcm-hostless";
 	};
 
+	qcom,msm-dai-q6 {
+		compatible = "qcom,msm-dai-q6";
+		qcom,msm-dai-q6-be-afe-pcm-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <224>;
+		};
+
+		qcom,msm-dai-q6-be-afe-pcm-tx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <225>;
+		};
+
+		qcom,msm-dai-q6-afe-proxy-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <241>;
+		};
+
+		qcom,msm-dai-q6-afe-proxy-tx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <240>;
+		};
+	};
+	qcom,msm-pcm-dtmf {
+		compatible = "qcom,msm-pcm-dtmf";
+	};
+
+	qcom,msm-dai-stub {
+		compatible = "qcom,msm-dai-stub";
+	};
+
+	qcom,msm-stub-codec {
+		compatible = "qcom,msm-stub-codec";
+	};
+
+	qcom,msm-auxpcm {
+		compatible = "qcom,msm-auxpcm-resource";
+		qcom,msm-cpudai-auxpcm-clk = "pcm_clk";
+		qcom,msm-cpudai-auxpcm-mode = <0>, <0>;
+		qcom,msm-cpudai-auxpcm-sync = <1>, <1>;
+		qcom,msm-cpudai-auxpcm-frame = <5>, <4>;
+		qcom,msm-cpudai-auxpcm-quant = <2>, <2>;
+		qcom,msm-cpudai-auxpcm-slot = <1>, <1>;
+		qcom,msm-cpudai-auxpcm-data = <0>, <0>;
+		qcom,msm-cpudai-auxpcm-pcm-clk-rate = <2048000>, <2048000>;
+
+		qcom,msm-auxpcm-rx {
+			qcom,msm-auxpcm-dev-id = <4106>;
+			compatible = "qcom,msm-auxpcm-dev";
+		};
+
+		qcom,msm-auxpcm-tx {
+			qcom,msm-auxpcm-dev-id = <4107>;
+			compatible = "qcom,msm-auxpcm-dev";
+		};
+	};
+
 	qcom,msm-dai-mi2s {
 		compatible = "qcom,msm-dai-mi2s";
 		qcom,msm-dai-q6-mi2s-prim {
@@ -525,6 +623,12 @@
 	qcom,mss {
 		compatible = "qcom,pil-q6v5-mss";
 		interrupts = <0 24 1>;
+
+		/* GPIO input from mss */
+		qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_1_in 0 0>;
+
+		/* GPIO output to mss */
+		qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_1_out 0 0>;
 	};
 
 	qcom,smem@fa00000 {
@@ -577,6 +681,43 @@
 			qcom,irq-no-suspend;
 		};
 	};
+
+	qcom,qcedev@fd400000 {
+		compatible = "qcom,qcedev";
+		reg = <0xfd400000 0x20000>,
+			  <0xfd404000 0x8000>;
+		reg-names = "crypto-base","crypto-bam-base";
+		interrupts = <0 207 0>;
+		qcom,bam-pipe-pair = <1>;
+	};
+
+	qcom,qcrypto@fd440000 {
+		compatible = "qcom,qcrypto";
+		reg = <0xfd400000 0x20000>,
+			  <0xfd404000 0x8000>;
+		reg-names = "crypto-base","crypto-bam-base";
+		interrupts = <0 207 0>;
+		qcom,bam-pipe-pair = <2>;
+	};
+
+	jtag_mm: jtagmm@fc332000 {
+		compatible = "qcom,jtag-mm";
+		reg = <0xfc332000 0x1000>,
+			<0xfc330000 0x1000>;
+		reg-names = "etm-base","debug-base";
+	};
+
+	qcom,msm-rtb {
+		compatible = "qcom,msm-rtb";
+		qcom,memory-reservation-type = "EBI1";
+		qcom,memory-reservation-size = <0x1000>; /* 4K EBI1 buffer */
+	};
+
+        qcom,msm-mem-hole {
+                compatible = "qcom,msm-mem-hole";
+                qcom,memblock-remove = <0x1f00000 0x5700000>; /* Address and Size of Hole */
+        };
+
 };
 
 /include/ "msm-pm8019-rpm-regulator.dtsi"
@@ -591,7 +732,7 @@
 		qcom,pre-div-channel-scaling = <0>;
 		qcom,calibration-type = "ratiometric";
 		qcom,scale-function = <0>;
-		qcom,hw-settle-time = <0>;
+		qcom,hw-settle-time = <2>;
 		qcom,fast-avg-setup = <0>;
 	};
 
@@ -602,7 +743,7 @@
 		qcom,pre-div-channel-scaling = <0>;
 		qcom,calibration-type = "ratiometric";
 		qcom,scale-function = <2>;
-		qcom,hw-settle-time = <0>;
+		qcom,hw-settle-time = <2>;
 		qcom,fast-avg-setup = <0>;
 	};
 
@@ -613,7 +754,7 @@
 		qcom,pre-div-channel-scaling = <0>;
 		qcom,calibration-type = "ratiometric";
 		qcom,scale-function = <2>;
-		qcom,hw-settle-time = <0>;
+		qcom,hw-settle-time = <2>;
 		qcom,fast-avg-setup = <0>;
 	};
 
@@ -624,7 +765,7 @@
 		qcom,pre-div-channel-scaling = <0>;
 		qcom,calibration-type = "ratiometric";
 		qcom,scale-function = <4>;
-		qcom,hw-settle-time = <0>;
+		qcom,hw-settle-time = <2>;
 		qcom,fast-avg-setup = <0>;
 	};
 
@@ -635,7 +776,7 @@
 		qcom,pre-div-channel-scaling = <0>;
 		qcom,calibration-type = "ratiometric";
 		qcom,scale-function = <4>;
-		qcom,hw-settle-time = <0>;
+		qcom,hw-settle-time = <2>;
 		qcom,fast-avg-setup = <0>;
 	};
 };
diff --git a/arch/arm/boot/dts/skeleton.dtsi b/arch/arm/boot/dts/skeleton.dtsi
index b41d241..f9988cd 100644
--- a/arch/arm/boot/dts/skeleton.dtsi
+++ b/arch/arm/boot/dts/skeleton.dtsi
@@ -9,5 +9,10 @@
 	#size-cells = <1>;
 	chosen { };
 	aliases { };
-	memory { device_type = "memory"; reg = <0 0>; };
+	memory {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		device_type = "memory";
+		reg = <0 0>;
+	};
 };
diff --git a/arch/arm/common/cpaccess.c b/arch/arm/common/cpaccess.c
index 85cd09f..3572e5a 100644
--- a/arch/arm/common/cpaccess.c
+++ b/arch/arm/common/cpaccess.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -260,14 +260,10 @@
 /*
  * cp_register_write_sysfs - sysfs interface for writing to
  * CP register
- * @dev:	sys device
- * @attr:	device attribute
- * @buf:	write value
- * @cnt:	not used
- *
  */
-static ssize_t cp_register_write_sysfs(struct sys_device *dev,
-	struct sysdev_attribute *attr, const char *buf, size_t cnt)
+static ssize_t cp_register_write_sysfs(
+	struct kobject *kobj, struct kobj_attribute *attr,
+	const char *buf, size_t cnt)
 {
 	char *str_tmp = (char *)buf;
 
@@ -280,18 +276,24 @@
 }
 
 /*
+ * wrapper for deprecated sysdev write interface
+ */
+static ssize_t sysdev_cp_register_write_sysfs(struct sys_device *dev,
+	struct sysdev_attribute *attr, const char *buf, size_t cnt)
+{
+	return cp_register_write_sysfs(NULL, NULL, buf, cnt);
+}
+
+/*
  * cp_register_read_sysfs - sysfs interface for reading CP registers
- * @dev:        sys device
- * @attr:       device attribute
- * @buf:        write value
  *
  * Code to read in the CPxx crn, crm, op1, op2 variables, or into
  * the base MRC opcode, store to executable memory, clean/invalidate
  * caches and then execute the new instruction and provide the
  * result to the caller.
  */
-static ssize_t cp_register_read_sysfs(struct sys_device *dev,
-	struct sysdev_attribute *attr, char *buf)
+static ssize_t cp_register_read_sysfs(
+	struct kobject *kobj, struct kobj_attribute *attr, char *buf)
 {
 	int ret;
 
@@ -310,20 +312,52 @@
 }
 
 /*
+ * wrapper for deprecated sysdev read interface
+ */
+static ssize_t sysdev_cp_register_read_sysfs(struct sys_device *dev,
+	struct sysdev_attribute *attr, char *buf)
+{
+	return cp_register_read_sysfs(NULL, NULL, buf);
+}
+
+/*
  * Setup sysfs files
  */
-SYSDEV_ATTR(cp_rw, 0644, cp_register_read_sysfs, cp_register_write_sysfs);
+SYSDEV_ATTR(cp_rw, 0644, sysdev_cp_register_read_sysfs,
+	    sysdev_cp_register_write_sysfs);
 
 static struct sys_device device_cpaccess = {
 	.id     = 0,
 	.cls    = &cpaccess_sysclass,
 };
 
+static struct device cpaccess_dev = {
+	.init_name = "cpaccess",
+};
+
+static struct kobj_attribute cp_rw_attribute =
+	__ATTR(cp_rw, 0644, cp_register_read_sysfs, cp_register_write_sysfs);
+
+static struct attribute *attrs[] = {
+	&cp_rw_attribute.attr,
+	NULL,
+};
+
+static struct attribute_group attr_group = {
+	.name = "cpaccess0",
+	.attrs = attrs,
+};
+
 /*
  * init_cpaccess_sysfs - initialize sys devices
  */
 static int __init init_cpaccess_sysfs(void)
 {
+	/*
+	 * sysdev interface is deprecated and will be removed
+	 * after migration to new sysfs entry
+	 */
+
 	int error = sysdev_class_register(&cpaccess_sysclass);
 
 	if (!error)
@@ -336,12 +370,28 @@
 		 &attr_cp_rw);
 	else {
 		pr_err("Error initializing cpaccess interface\n");
-		sysdev_unregister(&device_cpaccess);
-		sysdev_class_unregister(&cpaccess_sysclass);
+		goto exit0;
+	}
+
+	error = device_register(&cpaccess_dev);
+	if (error) {
+		pr_err("Error registering cpaccess device\n");
+		goto exit0;
+	}
+	error = sysfs_create_group(&cpaccess_dev.kobj, &attr_group);
+	if (error) {
+		pr_err("Error creating cpaccess sysfs group\n");
+		goto exit1;
 	}
 
 	sema_init(&cp_sem, 1);
+	return 0;
 
+exit1:
+	device_unregister(&cpaccess_dev);
+exit0:
+	sysdev_unregister(&device_cpaccess);
+	sysdev_class_unregister(&cpaccess_sysclass);
 	return error;
 }
 
@@ -350,6 +400,9 @@
 	sysdev_remove_file(&device_cpaccess, &attr_cp_rw);
 	sysdev_unregister(&device_cpaccess);
 	sysdev_class_unregister(&cpaccess_sysclass);
+
+	sysfs_remove_group(&cpaccess_dev.kobj, &attr_group);
+	device_unregister(&cpaccess_dev);
 }
 
 module_init(init_cpaccess_sysfs);
diff --git a/arch/arm/configs/msm8610_defconfig b/arch/arm/configs/msm8610_defconfig
new file mode 100644
index 0000000..3d710cc
--- /dev/null
+++ b/arch/arm/configs/msm8610_defconfig
@@ -0,0 +1,238 @@
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_RCU_FAST_NO_HZ=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_DEBUG=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_PANIC_TIMEOUT=5
+CONFIG_KALLSYMS_ALL=y
+CONFIG_ASHMEM=y
+CONFIG_EMBEDDED=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_EFI_PARTITION=y
+CONFIG_ARCH_MSM=y
+CONFIG_ARCH_MSM8610=y
+CONFIG_ARCH_MSM8226=y
+CONFIG_SND_SOC_MSM8226=y
+CONFIG_SND_SOC_MSM8X10=y
+# CONFIG_MSM_STACKED_MEMORY is not set
+CONFIG_CPU_HAS_L2_PMU=y
+# CONFIG_MSM_FIQ_SUPPORT is not set
+# CONFIG_MSM_PROC_COMM is not set
+CONFIG_MSM_SMD=y
+CONFIG_MSM_SMD_PKG4=y
+CONFIG_MSM_IPC_LOGGING=y
+CONFIG_MSM_BAM_DMUX=y
+CONFIG_MSM_SMP2P=y
+CONFIG_MSM_SMP2P_TEST=y
+CONFIG_MSM_IPC_ROUTER=y
+CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
+CONFIG_MSM_QMI_INTERFACE=y
+# CONFIG_MSM_HW3D is not set
+CONFIG_MSM_SUBSYSTEM_RESTART=y
+CONFIG_MSM_SYSMON_COMM=y
+CONFIG_MSM_PIL_LPASS_QDSP6V5=y
+CONFIG_MSM_PIL_PRONTO=y
+CONFIG_MSM_PIL_MSS_QDSP6V5=y
+CONFIG_MSM_PIL_VENUS=y
+CONFIG_WCNSS_CORE=y
+CONFIG_WCNSS_CORE_PRONTO=y
+CONFIG_MSM_DIRECT_SCLK_ACCESS=y
+CONFIG_MSM_WATCHDOG_V2=y
+CONFIG_MSM_DLOAD_MODE=y
+CONFIG_MSM_ADSP_LOADER=m
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_SMP=y
+CONFIG_SCHED_MC=y
+CONFIG_ARM_ARCH_TIMER=y
+CONFIG_HOTPLUG_CPU=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_VMALLOC_RESERVE=0x19000000
+CONFIG_USE_OF=y
+CONFIG_CPU_IDLE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_WAKELOCK=y
+CONFIG_PM_RUNTIME=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETFILTER=y
+CONFIG_BRIDGE_NF_EBTABLES=y
+CONFIG_BRIDGE_EBT_BROUTE=y
+CONFIG_BRIDGE=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_HTB=y
+CONFIG_NET_SCH_PRIO=y
+CONFIG_NET_CLS_FW=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=y
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+# CONFIG_MSM_RMNET is not set
+CONFIG_MSM_RMNET_BAM=y
+CONFIG_WCNSS_CORE=y
+CONFIG_WCNSS_CORE_PRONTO=y
+CONFIG_WCNSS_MEM_PRE_ALLOC=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_INPUT_GPIO=m
+CONFIG_SERIAL_MSM_HSL=y
+CONFIG_SERIAL_MSM_HSL_CONSOLE=y
+CONFIG_DIAG_CHAR=y
+CONFIG_HW_RANDOM=y
+CONFIG_SPMI=y
+CONFIG_SPMI_MSM_PMIC_ARB=y
+CONFIG_MSM_QPNP_INT=y
+CONFIG_SLIMBUS=y
+CONFIG_SLIMBUS_MSM_NGD=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_SPI=y
+CONFIG_SPI_QUP=y
+CONFIG_SPI_SPIDEV=m
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_QUP=y
+CONFIG_WCD9306_CODEC=y
+CONFIG_GPIO_QPNP_PIN=y
+# CONFIG_HWMON is not set
+CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
+CONFIG_SENSORS_QPNP_ADC_CURRENT=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_STUB=y
+CONFIG_REGULATOR_QPNP=y
+CONFIG_ION=y
+CONFIG_ION_MSM=y
+CONFIG_MSM_KGSL=y
+CONFIG_FB=y
+CONFIG_FB_VIRTUAL=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DEBUG_FILES=y
+CONFIG_USB_GADGET_DEBUG_FS=y
+CONFIG_USB_CI13XXX_MSM=y
+CONFIG_USB_G_ANDROID=y
+CONFIG_MMC=y
+CONFIG_MMC_PERF_PROFILING=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_EMBEDDED_SDIO=y
+CONFIG_MMC_PARANOID_SD_INIT=y
+CONFIG_MMC_BLOCK_MINORS=32
+CONFIG_MMC_TEST=m
+CONFIG_MMC_MSM=y
+CONFIG_STAGING=y
+CONFIG_ANDROID=y
+CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ANDROID_LOGGER=y
+CONFIG_ANDROID_RAM_CONSOLE=y
+CONFIG_ANDROID_TIMED_GPIO=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER=y
+CONFIG_MSM_IOMMU=y
+CONFIG_MSM_IOMMU_PMON=y
+CONFIG_SPS=y
+CONFIG_SPS_SUPPORT_NDP_BAM=y
+CONFIG_MMC_MSM_SPS_SUPPORT=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_DRV_MSM is not set
+CONFIG_RTC_DRV_QPNP=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT4_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_USER=y
+CONFIG_KEYS=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_TWOFISH=y
+# CONFIG_CRYPTO_HW is not set
+CONFIG_CRC_CCITT=y
+CONFIG_LIBCRC32C=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+# CONFIG_MSM_CAMERA is not set
+CONFIG_MSM_VIDC_V4L2=y
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
+CONFIG_VIDEOBUF2_MSM_MEM=y
+CONFIG_MSM_SUBSYSTEM_RESTART=y
+CONFIG_MSM_OCMEM=y
+CONFIG_MSM_OCMEM_LOCAL_POWER_CTRL=y
+CONFIG_MSM_OCMEM_DEBUG=y
+CONFIG_MSM_OCMEM_NONSECURE=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_TSENS8974=y
+CONFIG_THERMAL_MONITOR=y
diff --git a/arch/arm/configs/msm8910_defconfig b/arch/arm/configs/msm8910_defconfig
deleted file mode 100644
index 0fcfa97..0000000
--- a/arch/arm/configs/msm8910_defconfig
+++ /dev/null
@@ -1,172 +0,0 @@
-# CONFIG_ARM_PATCH_PHYS_VIRT is not set
-CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_SYSVIPC=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_CGROUPS=y
-CONFIG_CGROUP_DEBUG=y
-CONFIG_CGROUP_FREEZER=y
-CONFIG_CGROUP_CPUACCT=y
-CONFIG_RESOURCE_COUNTERS=y
-CONFIG_CGROUP_SCHED=y
-CONFIG_RT_GROUP_SCHED=y
-CONFIG_NAMESPACES=y
-# CONFIG_UTS_NS is not set
-# CONFIG_IPC_NS is not set
-# CONFIG_USER_NS is not set
-# CONFIG_PID_NS is not set
-CONFIG_RELAY=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_RD_BZIP2=y
-CONFIG_RD_LZMA=y
-CONFIG_PANIC_TIMEOUT=5
-CONFIG_KALLSYMS_ALL=y
-CONFIG_ASHMEM=y
-CONFIG_EMBEDDED=y
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_EFI_PARTITION=y
-CONFIG_ARCH_MSM=y
-CONFIG_ARCH_MSM8910=y
-CONFIG_ARCH_MSM8226=y
-# CONFIG_MSM_STACKED_MEMORY is not set
-CONFIG_CPU_HAS_L2_PMU=y
-# CONFIG_MSM_FIQ_SUPPORT is not set
-# CONFIG_MSM_PROC_COMM is not set
-CONFIG_MSM_SMD=y
-CONFIG_MSM_SMD_PKG4=y
-# CONFIG_MSM_HW3D is not set
-CONFIG_MSM_DIRECT_SCLK_ACCESS=y
-CONFIG_MSM_WATCHDOG_V2=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_SMP=y
-CONFIG_SCHED_MC=y
-CONFIG_ARM_ARCH_TIMER=y
-CONFIG_HOTPLUG_CPU=y
-CONFIG_PREEMPT=y
-CONFIG_AEABI=y
-CONFIG_HIGHMEM=y
-CONFIG_VMALLOC_RESERVE=0x19000000
-CONFIG_USE_OF=y
-CONFIG_VFP=y
-CONFIG_NEON=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-# CONFIG_SUSPEND is not set
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_IP_MULTIPLE_TABLES=y
-CONFIG_IP_ROUTE_VERBOSE=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-CONFIG_IPV6=y
-CONFIG_IPV6_PRIVACY=y
-CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_IPV6_ROUTE_INFO=y
-CONFIG_IPV6_OPTIMISTIC_DAD=y
-CONFIG_INET6_AH=y
-CONFIG_INET6_ESP=y
-CONFIG_INET6_IPCOMP=y
-CONFIG_IPV6_MIP6=y
-CONFIG_IPV6_MULTIPLE_TABLES=y
-CONFIG_IPV6_SUBTREES=y
-CONFIG_NETFILTER=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_MD=y
-CONFIG_BLK_DEV_DM=y
-CONFIG_DM_CRYPT=y
-CONFIG_NETDEVICES=y
-CONFIG_DUMMY=y
-CONFIG_INPUT_EVDEV=y
-CONFIG_INPUT_EVBUG=m
-CONFIG_INPUT_MISC=y
-CONFIG_INPUT_UINPUT=y
-CONFIG_INPUT_GPIO=m
-CONFIG_SERIAL_MSM_HSL=y
-CONFIG_SERIAL_MSM_HSL_CONSOLE=y
-CONFIG_DIAG_CHAR=y
-CONFIG_HW_RANDOM=y
-CONFIG_SPMI=y
-CONFIG_SPMI_MSM_PMIC_ARB=y
-CONFIG_MSM_QPNP_INT=y
-CONFIG_DEBUG_GPIO=y
-CONFIG_GPIO_SYSFS=y
-# CONFIG_HWMON is not set
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_STUB=y
-CONFIG_ION=y
-CONFIG_ION_MSM=y
-CONFIG_FB=y
-CONFIG_FB_VIRTUAL=y
-CONFIG_SOUND=y
-CONFIG_SND=y
-CONFIG_SND_SOC=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_GADGET_DEBUG_FILES=y
-CONFIG_USB_GADGET_DEBUG_FS=y
-CONFIG_USB_CI13XXX_MSM=y
-CONFIG_USB_G_ANDROID=y
-CONFIG_MMC=y
-CONFIG_MMC_PERF_PROFILING=y
-CONFIG_MMC_UNSAFE_RESUME=y
-CONFIG_MMC_CLKGATE=y
-CONFIG_MMC_EMBEDDED_SDIO=y
-CONFIG_MMC_PARANOID_SD_INIT=y
-CONFIG_MMC_BLOCK_MINORS=32
-CONFIG_MMC_TEST=m
-CONFIG_MMC_MSM=y
-CONFIG_MMC_MSM_SPS_SUPPORT=y
-CONFIG_STAGING=y
-CONFIG_ANDROID=y
-CONFIG_ANDROID_BINDER_IPC=y
-CONFIG_ANDROID_LOGGER=y
-CONFIG_ANDROID_RAM_CONSOLE=y
-CONFIG_ANDROID_TIMED_GPIO=y
-CONFIG_ANDROID_LOW_MEMORY_KILLER=y
-CONFIG_SPS=y
-CONFIG_SPS_SUPPORT_NDP_BAM=y
-CONFIG_MSM_IOMMU=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_EXT4_FS=y
-CONFIG_FUSE_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ASCII=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_PRINTK_TIME=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_FS=y
-CONFIG_SCHEDSTATS=y
-CONFIG_TIMER_STATS=y
-# CONFIG_DEBUG_PREEMPT is not set
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_MEMORY_INIT=y
-CONFIG_DYNAMIC_DEBUG=y
-CONFIG_DEBUG_USER=y
-CONFIG_KEYS=y
-CONFIG_CRYPTO_MD4=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_AES=y
-CONFIG_CRYPTO_ARC4=y
-CONFIG_CRYPTO_TWOFISH=y
-# CONFIG_CRYPTO_HW is not set
-CONFIG_CRC_CCITT=y
-CONFIG_LIBCRC32C=y
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index c95472f..7362ea0 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -2,6 +2,7 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_LOCALVERSION="-perf"
 CONFIG_SYSVIPC=y
+CONFIG_RCU_FAST_NO_HZ=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_CGROUPS=y
@@ -49,6 +50,7 @@
 CONFIG_MACH_MSM8627_CDP=y
 CONFIG_MACH_MSM8627_MTP=y
 CONFIG_MACH_APQ8064_CDP=y
+CONFIG_MACH_FSM8064_EP=y
 CONFIG_MACH_APQ8064_MTP=y
 CONFIG_MACH_APQ8064_LIQUID=y
 CONFIG_MACH_MPQ8064_CDP=y
@@ -122,15 +124,18 @@
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
 CONFIG_INET=y
 CONFIG_IP_ADVANCED_ROUTER=y
 CONFIG_IP_MULTIPLE_TABLES=y
 CONFIG_IP_ROUTE_VERBOSE=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
 # CONFIG_INET_LRO is not set
 CONFIG_IPV6=y
 CONFIG_IPV6_PRIVACY=y
@@ -212,6 +217,9 @@
 CONFIG_IP6_NF_TARGET_REJECT=y
 CONFIG_IP6_NF_MANGLE=y
 CONFIG_IP6_NF_RAW=y
+CONFIG_BRIDGE_NF_EBTABLES=y
+CONFIG_BRIDGE_EBT_BROUTE=y
+CONFIG_BRIDGE=y
 CONFIG_NET_SCHED=y
 CONFIG_NET_SCH_HTB=y
 CONFIG_NET_SCH_PRIO=y
@@ -244,7 +252,6 @@
 CONFIG_RFKILL=y
 CONFIG_GENLOCK=y
 CONFIG_GENLOCK_MISCDEVICE=y
-CONFIG_CMA=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_TSPP=m
@@ -252,7 +259,6 @@
 CONFIG_PMIC8XXX_VIBRATOR=y
 CONFIG_QSEECOM=y
 CONFIG_USB_HSIC_SMSC_HUB=y
-CONFIG_SCSI=y
 CONFIG_SCSI_TGT=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_SG=y
@@ -261,6 +267,8 @@
 CONFIG_SCSI_CONSTANTS=y
 CONFIG_SCSI_LOGGING=y
 CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_ATA=y
+CONFIG_SATA_AHCI_MSM=y
 CONFIG_MD=y
 CONFIG_BLK_DEV_DM=y
 CONFIG_DM_CRYPT=y
@@ -337,6 +345,7 @@
 CONFIG_MFD_PM8XXX_BATT_ALARM=y
 CONFIG_WCD9304_CODEC=y
 CONFIG_WCD9310_CODEC=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_PM8XXX=y
 CONFIG_REGULATOR_MSM_GPIO=y
 CONFIG_MEDIA_SUPPORT=y
@@ -369,6 +378,8 @@
 CONFIG_MSM_CSI20_HEADER=y
 CONFIG_S5K3L1YX=y
 CONFIG_IMX091=y
+CONFIG_MSM_CSIPHY=y
+CONFIG_MSM_CSID=y
 CONFIG_MSM_WFD=y
 CONFIG_RADIO_IRIS=y
 CONFIG_RADIO_IRIS_TRANSPORT=m
@@ -452,6 +463,8 @@
 CONFIG_MMC_MSM_SDC3_SUPPORT=y
 CONFIG_MMC_MSM_SDC3_WP_SUPPORT=y
 CONFIG_MMC_MSM_SPS_SUPPORT=y
+CONFIG_IOSCHED_TEST=y
+CONFIG_MMC_BLOCK_TEST=y
 CONFIG_LEDS_PM8XXX=y
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
@@ -473,8 +486,12 @@
 CONFIG_MSM_IOMMU=y
 CONFIG_MOBICORE_SUPPORT=m
 CONFIG_MOBICORE_API=m
-CONFIG_MSM_QDSS=y
-CONFIG_CONTROL_TRACE=m
+CONFIG_CORESIGHT=y
+CONFIG_CORESIGHT_TPIU=y
+CONFIG_CORESIGHT_ETB=y
+CONFIG_CORESIGHT_FUNNEL=y
+CONFIG_CORESIGHT_ETM=y
+CONFIG_CORESIGHT_EVENT=m
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT3_FS=y
@@ -502,6 +519,12 @@
 CONFIG_DYNAMIC_DEBUG=y
 CONFIG_DEBUG_USER=y
 CONFIG_PID_IN_CONTEXTIDR=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_CRYPTD=y
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_CTR=y
+CONFIG_CRYPTO_CTS=y
+CONFIG_CRYPTO_XCBC=y
 CONFIG_CRYPTO_TWOFISH=y
 CONFIG_CRYPTO_DEV_QCRYPTO=m
 CONFIG_CRYPTO_DEV_QCE=m
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 1842b6e..bb34075 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -1,6 +1,7 @@
 # CONFIG_ARM_PATCH_PHYS_VIRT is not set
 CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
+CONFIG_RCU_FAST_NO_HZ=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_CGROUPS=y
@@ -48,6 +49,7 @@
 CONFIG_MACH_MSM8627_CDP=y
 CONFIG_MACH_MSM8627_MTP=y
 CONFIG_MACH_APQ8064_CDP=y
+CONFIG_MACH_FSM8064_EP=y
 CONFIG_MACH_APQ8064_MTP=y
 CONFIG_MACH_APQ8064_LIQUID=y
 CONFIG_MACH_MPQ8064_CDP=y
@@ -127,15 +129,18 @@
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
 CONFIG_INET=y
 CONFIG_IP_ADVANCED_ROUTER=y
 CONFIG_IP_MULTIPLE_TABLES=y
 CONFIG_IP_ROUTE_VERBOSE=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
 # CONFIG_INET_LRO is not set
 CONFIG_IPV6=y
 CONFIG_IPV6_PRIVACY=y
@@ -217,6 +222,9 @@
 CONFIG_IP6_NF_TARGET_REJECT=y
 CONFIG_IP6_NF_MANGLE=y
 CONFIG_IP6_NF_RAW=y
+CONFIG_BRIDGE_NF_EBTABLES=y
+CONFIG_BRIDGE_EBT_BROUTE=y
+CONFIG_BRIDGE=y
 CONFIG_NET_SCHED=y
 CONFIG_NET_SCH_HTB=y
 CONFIG_NET_SCH_PRIO=y
@@ -249,7 +257,6 @@
 CONFIG_RFKILL=y
 CONFIG_GENLOCK=y
 CONFIG_GENLOCK_MISCDEVICE=y
-CONFIG_CMA=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_TSPP=m
@@ -257,7 +264,6 @@
 CONFIG_PMIC8XXX_VIBRATOR=y
 CONFIG_QSEECOM=y
 CONFIG_USB_HSIC_SMSC_HUB=y
-CONFIG_SCSI=y
 CONFIG_SCSI_TGT=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_SG=y
@@ -266,6 +272,8 @@
 CONFIG_SCSI_CONSTANTS=y
 CONFIG_SCSI_LOGGING=y
 CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_ATA=y
+CONFIG_SATA_AHCI_MSM=y
 CONFIG_MD=y
 CONFIG_BLK_DEV_DM=y
 CONFIG_DM_CRYPT=y
@@ -342,6 +350,7 @@
 CONFIG_MFD_PM8XXX_BATT_ALARM=y
 CONFIG_WCD9304_CODEC=y
 CONFIG_WCD9310_CODEC=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_PM8XXX=y
 CONFIG_REGULATOR_MSM_GPIO=y
 CONFIG_MEDIA_SUPPORT=y
@@ -373,6 +382,8 @@
 CONFIG_MSM_CSI20_HEADER=y
 CONFIG_S5K3L1YX=y
 CONFIG_IMX091=y
+CONFIG_MSM_CSIPHY=y
+CONFIG_MSM_CSID=y
 CONFIG_MSM_WFD=y
 CONFIG_RADIO_IRIS=y
 CONFIG_RADIO_IRIS_TRANSPORT=m
@@ -455,6 +466,8 @@
 CONFIG_MMC_MSM_SDC3_SUPPORT=y
 CONFIG_MMC_MSM_SDC3_WP_SUPPORT=y
 CONFIG_MMC_MSM_SPS_SUPPORT=y
+CONFIG_IOSCHED_TEST=y
+CONFIG_MMC_BLOCK_TEST=y
 CONFIG_LEDS_PM8XXX=y
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
@@ -475,9 +488,13 @@
 CONFIG_MSM_IOMMU=y
 CONFIG_MOBICORE_SUPPORT=m
 CONFIG_MOBICORE_API=m
-CONFIG_MSM_QDSS=y
-CONFIG_MSM_QDSS_ETM_DEFAULT_ENABLE=y
-CONFIG_CONTROL_TRACE=m
+CONFIG_CORESIGHT=y
+CONFIG_CORESIGHT_TPIU=y
+CONFIG_CORESIGHT_ETB=y
+CONFIG_CORESIGHT_FUNNEL=y
+CONFIG_CORESIGHT_ETM=y
+CONFIG_CORESIGHT_ETM_DEFAULT_ENABLE=y
+CONFIG_CORESIGHT_EVENT=m
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT3_FS=y
@@ -519,6 +536,12 @@
 CONFIG_DYNAMIC_DEBUG=y
 CONFIG_DEBUG_USER=y
 CONFIG_PID_IN_CONTEXTIDR=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_CRYPTD=y
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_CTR=y
+CONFIG_CRYPTO_CTS=y
+CONFIG_CRYPTO_XCBC=y
 CONFIG_CRYPTO_TWOFISH=y
 CONFIG_CRYPTO_DEV_QCRYPTO=m
 CONFIG_CRYPTO_DEV_QCE=m
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index ad6dc6a..d36d5a2 100644
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -1,8 +1,8 @@
 # CONFIG_ARM_PATCH_PHYS_VIRT is not set
 CONFIG_EXPERIMENTAL=y
 CONFIG_LOCALVERSION="-perf"
-# CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SYSVIPC=y
+CONFIG_RCU_FAST_NO_HZ=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_CGROUPS=y
@@ -35,6 +35,8 @@
 CONFIG_MODVERSIONS=y
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_EFI_PARTITION=y
+CONFIG_IOSCHED_TEST=y
+CONFIG_DEFAULT_ROW=y
 CONFIG_ARCH_MSM=y
 CONFIG_ARCH_MSM8974=y
 CONFIG_MSM_KRAIT_TBB_ABORT_HANDLER=y
@@ -45,6 +47,9 @@
 CONFIG_MSM_SMD=y
 CONFIG_MSM_SMD_PKG4=y
 CONFIG_MSM_BAM_DMUX=y
+CONFIG_MSM_SMP2P=y
+CONFIG_MSM_SMP2P_TEST=y
+CONFIG_MSM_IPC_LOGGING=y
 CONFIG_MSM_IPC_ROUTER=y
 CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
 CONFIG_MSM_IPC_ROUTER_SECURITY=y
@@ -66,7 +71,6 @@
 CONFIG_MSM_OCMEM=y
 CONFIG_MSM_OCMEM_LOCAL_POWER_CTRL=y
 CONFIG_MSM_OCMEM_DEBUG=y
-CONFIG_MSM_OCMEM_NONSECURE=y
 CONFIG_MSM_RTB=y
 CONFIG_MSM_RTB_SEPARATE_CPUS=y
 CONFIG_MSM_CACHE_ERP=y
@@ -75,6 +79,7 @@
 CONFIG_MSM_L1_ERR_LOG=y
 CONFIG_MSM_L2_ERP_2BIT_PANIC=y
 CONFIG_MSM_ENABLE_WDOG_DEBUG_CONTROL=y
+CONFIG_MSM_UARTDM_Core_v14=y
 CONFIG_STRICT_MEMORY_RWX=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
@@ -103,14 +108,17 @@
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
+CONFIG_XFRM_USER=y
 CONFIG_INET=y
 CONFIG_IP_ADVANCED_ROUTER=y
 CONFIG_IP_MULTIPLE_TABLES=y
 CONFIG_IP_ROUTE_VERBOSE=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
 CONFIG_IPV6=y
@@ -193,6 +201,9 @@
 CONFIG_IP6_NF_TARGET_REJECT=y
 CONFIG_IP6_NF_MANGLE=y
 CONFIG_IP6_NF_RAW=y
+CONFIG_BRIDGE_NF_EBTABLES=y
+CONFIG_BRIDGE_EBT_BROUTE=y
+CONFIG_BRIDGE=y
 CONFIG_NET_SCHED=y
 CONFIG_NET_SCH_HTB=y
 CONFIG_NET_SCH_PRIO=y
@@ -216,12 +227,17 @@
 CONFIG_BT_HIDP=y
 CONFIG_BT_HCISMD=y
 CONFIG_MSM_BT_POWER=y
-CONFIG_CFG80211=m
+CONFIG_CFG80211=y
+CONFIG_NL80211_TESTMODE=y
 CONFIG_RFKILL=y
 CONFIG_GENLOCK=y
 CONFIG_GENLOCK_MISCDEVICE=y
+CONFIG_SYNC=y
+CONFIG_SW_SYNC=y
+CONFIG_CMA=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
+CONFIG_HAPTIC_ISA1200=y
 CONFIG_QSEECOM=y
 CONFIG_USB_HSIC_SMSC_HUB=y
 CONFIG_TI_DRV2667=y
@@ -249,6 +265,7 @@
 CONFIG_USB_USBNET=y
 CONFIG_WCNSS_CORE=y
 CONFIG_WCNSS_CORE_PRONTO=y
+CONFIG_WCNSS_MEM_PRE_ALLOC=y
 CONFIG_INPUT_EVDEV=y
 CONFIG_INPUT_EVBUG=m
 CONFIG_KEYBOARD_GPIO=y
@@ -256,8 +273,10 @@
 CONFIG_JOYSTICK_XPAD=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+CONFIG_TOUCHSCREEN_GEN_VKEYS=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_UINPUT=y
+CONFIG_SERIAL_MSM_HS=y
 CONFIG_SERIAL_MSM_HSL=y
 CONFIG_SERIAL_MSM_HSL_CONSOLE=y
 CONFIG_DIAG_CHAR=y
@@ -299,24 +318,24 @@
 CONFIG_MEDIA_CONTROLLER=y
 CONFIG_VIDEO_DEV=y
 CONFIG_VIDEO_V4L2_SUBDEV_API=y
-CONFIG_VIDEOBUF2_MSM_MEM=y
-CONFIG_USB_VIDEO_CLASS=y
-CONFIG_V4L_PLATFORM_DRIVERS=y
-CONFIG_MSM_CAMERA_V4L2=y
+# CONFIG_MSM_CAMERA is not set
 CONFIG_MT9M114=y
-CONFIG_MSM_CAMERA_LED_TRIGGER_FLASH=y
 CONFIG_OV2720=y
 CONFIG_MSM_CAMERA_SENSOR=y
-CONFIG_MSM_ACTUATOR=y
-CONFIG_MSM_JPEG=y
 CONFIG_MSM_CCI=y
+CONFIG_MSM_CPP=y
 CONFIG_MSM_CSI30_HEADER=y
 CONFIG_MSM_CSIPHY=y
 CONFIG_MSM_CSID=y
-CONFIG_MSM_CSI2_REGISTER=y
 CONFIG_MSM_ISPIF=y
 CONFIG_S5K3L1YX=y
+CONFIG_MSMB_CAMERA=y
+CONFIG_MSMB_JPEG=y
+CONFIG_MSM_VIDC_V4L2=y
 CONFIG_MSM_WFD=y
+CONFIG_VIDEOBUF2_MSM_MEM=y
+CONFIG_USB_VIDEO_CLASS=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
 CONFIG_RADIO_IRIS=y
 CONFIG_RADIO_IRIS_TRANSPORT=m
 CONFIG_ION=y
@@ -328,6 +347,7 @@
 CONFIG_FB_MSM_MDSS=y
 CONFIG_FB_MSM_MDSS_WRITEBACK=y
 CONFIG_FB_MSM_MDSS_HDMI_PANEL=y
+CONFIG_FB_MSM_MDSS_HDMI_MHL_SII8334=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 # CONFIG_LCD_CLASS_DEVICE is not set
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
@@ -337,9 +357,11 @@
 CONFIG_SND_USB_AUDIO=y
 CONFIG_SND_SOC=y
 CONFIG_SND_SOC_MSM8974=y
+CONFIG_USB_SUSPEND=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_EHSET=y
+CONFIG_USB_EHCI_MSM=y
 CONFIG_USB_EHCI_MSM_HSIC=y
 CONFIG_USB_ACM=y
 CONFIG_USB_STORAGE=y
@@ -355,6 +377,7 @@
 CONFIG_USB_STORAGE_KARMA=y
 CONFIG_USB_STORAGE_CYPRESS_ATACB=y
 CONFIG_USB_STORAGE_ENE_UB6250=y
+CONFIG_USB_EHSET_TEST_FIXTURE=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_DEBUG_FILES=y
 CONFIG_USB_DWC3_MSM=y
@@ -367,6 +390,7 @@
 CONFIG_MMC_BLOCK_MINORS=32
 # CONFIG_MMC_BLOCK_BOUNCE is not set
 CONFIG_MMC_TEST=m
+CONFIG_MMC_BLOCK_TEST=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_MSM=y
@@ -386,7 +410,6 @@
 CONFIG_ANDROID_RAM_CONSOLE=y
 CONFIG_ANDROID_TIMED_GPIO=y
 CONFIG_ANDROID_LOW_MEMORY_KILLER=y
-CONFIG_MSM_SSBI=y
 CONFIG_SPS=y
 CONFIG_USB_BAM=y
 CONFIG_SPS_SUPPORT_BAMDMA=y
@@ -395,8 +418,17 @@
 CONFIG_QPNP_POWER_ON=y
 CONFIG_QPNP_CLKDIV=y
 CONFIG_MSM_IOMMU=y
-CONFIG_MSM_QDSS=y
-CONFIG_MSM_QDSS_ETM_PCSAVE_DEFAULT_ENABLE=y
+CONFIG_MOBICORE_SUPPORT=m
+CONFIG_MOBICORE_API=m
+CONFIG_CORESIGHT=y
+CONFIG_CORESIGHT_TMC=y
+CONFIG_CORESIGHT_TPIU=y
+CONFIG_CORESIGHT_FUNNEL=y
+CONFIG_CORESIGHT_REPLICATOR=y
+CONFIG_CORESIGHT_STM=y
+CONFIG_CORESIGHT_ETM=y
+CONFIG_CORESIGHT_ETM_PCSAVE_DEFAULT_ENABLE=y
+CONFIG_CORESIGHT_EVENT=m
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT3_FS=y
@@ -420,8 +452,10 @@
 CONFIG_DEBUG_USER=y
 CONFIG_PID_IN_CONTEXTIDR=y
 CONFIG_KEYS=y
+CONFIG_CRYPTO_NULL=y
 CONFIG_CRYPTO_MD4=y
 CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_XCBC=y
 CONFIG_CRYPTO_TWOFISH=y
 CONFIG_CRYPTO_DEV_QCRYPTO=m
 CONFIG_CRYPTO_DEV_QCE=m
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index ca60319..df0b5f0 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -1,7 +1,7 @@
 # CONFIG_ARM_PATCH_PHYS_VIRT is not set
 CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SYSVIPC=y
+CONFIG_RCU_FAST_NO_HZ=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_CGROUPS=y
@@ -34,6 +34,8 @@
 CONFIG_MODVERSIONS=y
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_EFI_PARTITION=y
+CONFIG_IOSCHED_TEST=y
+CONFIG_DEFAULT_ROW=y
 CONFIG_ARCH_MSM=y
 CONFIG_ARCH_MSM8974=y
 CONFIG_MSM_KRAIT_TBB_ABORT_HANDLER=y
@@ -44,6 +46,9 @@
 CONFIG_MSM_SMD=y
 CONFIG_MSM_SMD_PKG4=y
 CONFIG_MSM_BAM_DMUX=y
+CONFIG_MSM_SMP2P=y
+CONFIG_MSM_SMP2P_TEST=y
+CONFIG_MSM_IPC_LOGGING=y
 CONFIG_MSM_IPC_ROUTER=y
 CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
 CONFIG_MSM_IPC_ROUTER_SECURITY=y
@@ -65,7 +70,6 @@
 CONFIG_MSM_OCMEM=y
 CONFIG_MSM_OCMEM_LOCAL_POWER_CTRL=y
 CONFIG_MSM_OCMEM_DEBUG=y
-CONFIG_MSM_OCMEM_NONSECURE=y
 CONFIG_MSM_RTB=y
 CONFIG_MSM_RTB_SEPARATE_CPUS=y
 CONFIG_MSM_CACHE_ERP=y
@@ -73,10 +77,13 @@
 CONFIG_MSM_L1_RECOV_ERR_PANIC=y
 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
 CONFIG_MSM_ENABLE_WDOG_DEBUG_CONTROL=y
+CONFIG_MSM_UARTDM_Core_v14=y
 CONFIG_STRICT_MEMORY_RWX=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
@@ -105,14 +112,17 @@
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
+CONFIG_XFRM_USER=y
 CONFIG_INET=y
 CONFIG_IP_ADVANCED_ROUTER=y
 CONFIG_IP_MULTIPLE_TABLES=y
 CONFIG_IP_ROUTE_VERBOSE=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
 CONFIG_IPV6=y
@@ -195,6 +205,9 @@
 CONFIG_IP6_NF_TARGET_REJECT=y
 CONFIG_IP6_NF_MANGLE=y
 CONFIG_IP6_NF_RAW=y
+CONFIG_BRIDGE_NF_EBTABLES=y
+CONFIG_BRIDGE_EBT_BROUTE=y
+CONFIG_BRIDGE=y
 CONFIG_NET_SCHED=y
 CONFIG_NET_SCH_HTB=y
 CONFIG_NET_SCH_PRIO=y
@@ -218,12 +231,18 @@
 CONFIG_BT_HIDP=y
 CONFIG_BT_HCISMD=y
 CONFIG_MSM_BT_POWER=y
-CONFIG_CFG80211=m
+CONFIG_CFG80211=y
+CONFIG_NL80211_TESTMODE=y
 CONFIG_RFKILL=y
 CONFIG_GENLOCK=y
 CONFIG_GENLOCK_MISCDEVICE=y
+CONFIG_SYNC=y
+CONFIG_SW_SYNC=y
+CONFIG_CMA=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
+CONFIG_TSPP=m
+CONFIG_HAPTIC_ISA1200=y
 CONFIG_QSEECOM=y
 CONFIG_USB_HSIC_SMSC_HUB=y
 CONFIG_TI_DRV2667=y
@@ -251,6 +270,7 @@
 CONFIG_USB_USBNET=y
 CONFIG_WCNSS_CORE=y
 CONFIG_WCNSS_CORE_PRONTO=y
+CONFIG_WCNSS_MEM_PRE_ALLOC=y
 CONFIG_INPUT_EVDEV=y
 CONFIG_INPUT_EVBUG=m
 CONFIG_KEYBOARD_GPIO=y
@@ -258,8 +278,10 @@
 CONFIG_JOYSTICK_XPAD=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+CONFIG_TOUCHSCREEN_GEN_VKEYS=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_UINPUT=y
+CONFIG_SERIAL_MSM_HS=y
 CONFIG_SERIAL_MSM_HSL=y
 CONFIG_SERIAL_MSM_HSL_CONSOLE=y
 CONFIG_DIAG_CHAR=y
@@ -290,6 +312,7 @@
 CONFIG_SENSORS_QPNP_ADC_CURRENT=y
 CONFIG_THERMAL=y
 CONFIG_THERMAL_TSENS8974=y
+CONFIG_THERMAL_MONITOR=y
 CONFIG_THERMAL_QPNP=y
 CONFIG_THERMAL_QPNP_ADC_TM=y
 CONFIG_WCD9320_CODEC=y
@@ -300,24 +323,27 @@
 CONFIG_MEDIA_CONTROLLER=y
 CONFIG_VIDEO_DEV=y
 CONFIG_VIDEO_V4L2_SUBDEV_API=y
-CONFIG_VIDEOBUF2_MSM_MEM=y
-CONFIG_USB_VIDEO_CLASS=y
-CONFIG_V4L_PLATFORM_DRIVERS=y
-CONFIG_MSM_CAMERA_V4L2=y
+CONFIG_DVB_CORE=m
+# CONFIG_MSM_CAMERA is not set
 CONFIG_MT9M114=y
-CONFIG_MSM_CAMERA_LED_TRIGGER_FLASH=y
 CONFIG_OV2720=y
 CONFIG_MSM_CAMERA_SENSOR=y
-CONFIG_MSM_ACTUATOR=y
-CONFIG_MSM_JPEG=y
 CONFIG_MSM_CCI=y
+CONFIG_MSM_CPP=y
 CONFIG_MSM_CSI30_HEADER=y
 CONFIG_MSM_CSIPHY=y
 CONFIG_MSM_CSID=y
-CONFIG_MSM_CSI2_REGISTER=y
 CONFIG_MSM_ISPIF=y
 CONFIG_S5K3L1YX=y
+CONFIG_MSMB_CAMERA=y
+CONFIG_MSMB_JPEG=y
+CONFIG_MSM_VIDC_V4L2=y
 CONFIG_MSM_WFD=y
+CONFIG_DVB_MPQ=m
+CONFIG_DVB_MPQ_DEMUX=m
+CONFIG_VIDEOBUF2_MSM_MEM=y
+CONFIG_USB_VIDEO_CLASS=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
 CONFIG_RADIO_IRIS=y
 CONFIG_RADIO_IRIS_TRANSPORT=m
 CONFIG_ION=y
@@ -329,6 +355,7 @@
 CONFIG_FB_MSM_MDSS=y
 CONFIG_FB_MSM_MDSS_WRITEBACK=y
 CONFIG_FB_MSM_MDSS_HDMI_PANEL=y
+CONFIG_FB_MSM_MDSS_HDMI_MHL_SII8334=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 # CONFIG_LCD_CLASS_DEVICE is not set
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
@@ -338,9 +365,11 @@
 CONFIG_SND_USB_AUDIO=y
 CONFIG_SND_SOC=y
 CONFIG_SND_SOC_MSM8974=y
+CONFIG_USB_SUSPEND=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_EHSET=y
+CONFIG_USB_EHCI_MSM=y
 CONFIG_USB_EHCI_MSM_HSIC=y
 CONFIG_USB_ACM=y
 CONFIG_USB_STORAGE=y
@@ -356,6 +385,7 @@
 CONFIG_USB_STORAGE_KARMA=y
 CONFIG_USB_STORAGE_CYPRESS_ATACB=y
 CONFIG_USB_STORAGE_ENE_UB6250=y
+CONFIG_USB_EHSET_TEST_FIXTURE=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_DEBUG_FILES=y
 CONFIG_USB_DWC3_MSM=y
@@ -368,6 +398,7 @@
 CONFIG_MMC_BLOCK_MINORS=32
 # CONFIG_MMC_BLOCK_BOUNCE is not set
 CONFIG_MMC_TEST=m
+CONFIG_MMC_BLOCK_TEST=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_MSM=y
@@ -387,7 +418,6 @@
 CONFIG_ANDROID_RAM_CONSOLE=y
 CONFIG_ANDROID_TIMED_GPIO=y
 CONFIG_ANDROID_LOW_MEMORY_KILLER=y
-CONFIG_MSM_SSBI=y
 CONFIG_SPS=y
 CONFIG_USB_BAM=y
 CONFIG_SPS_SUPPORT_BAMDMA=y
@@ -396,8 +426,18 @@
 CONFIG_QPNP_POWER_ON=y
 CONFIG_QPNP_CLKDIV=y
 CONFIG_MSM_IOMMU=y
-CONFIG_MSM_QDSS=y
-CONFIG_MSM_QDSS_ETM_PCSAVE_DEFAULT_ENABLE=y
+CONFIG_MSM_IOMMU_PMON=y
+CONFIG_MOBICORE_SUPPORT=m
+CONFIG_MOBICORE_API=m
+CONFIG_CORESIGHT=y
+CONFIG_CORESIGHT_TMC=y
+CONFIG_CORESIGHT_TPIU=y
+CONFIG_CORESIGHT_FUNNEL=y
+CONFIG_CORESIGHT_REPLICATOR=y
+CONFIG_CORESIGHT_STM=y
+CONFIG_CORESIGHT_ETM=y
+CONFIG_CORESIGHT_ETM_PCSAVE_DEFAULT_ENABLE=y
+CONFIG_CORESIGHT_EVENT=m
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT3_FS=y
@@ -417,7 +457,6 @@
 CONFIG_TIMER_STATS=y
 CONFIG_DEBUG_KMEMLEAK=y
 CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y
-# CONFIG_DEBUG_PREEMPT is not set
 CONFIG_DEBUG_SPINLOCK=y
 CONFIG_DEBUG_MUTEXES=y
 CONFIG_DEBUG_ATOMIC_SLEEP=y
@@ -433,10 +472,14 @@
 CONFIG_CPU_FREQ_SWITCH_PROFILER=y
 CONFIG_DYNAMIC_DEBUG=y
 CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL=y
+CONFIG_EARLY_PRINTK=y
 CONFIG_PID_IN_CONTEXTIDR=y
 CONFIG_KEYS=y
+CONFIG_CRYPTO_NULL=y
 CONFIG_CRYPTO_MD4=y
 CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_XCBC=y
 CONFIG_CRYPTO_TWOFISH=y
 CONFIG_CRYPTO_DEV_QCRYPTO=m
 CONFIG_CRYPTO_DEV_QCE=m
diff --git a/arch/arm/configs/msm9615_defconfig b/arch/arm/configs/msm9615_defconfig
index 06ec01a..9ab1cdd 100644
--- a/arch/arm/configs/msm9615_defconfig
+++ b/arch/arm/configs/msm9615_defconfig
@@ -146,6 +146,9 @@
 CONFIG_IP6_NF_TARGET_REJECT_SKERR=y
 CONFIG_IP6_NF_MANGLE=y
 CONFIG_IP6_NF_RAW=y
+CONFIG_BRIDGE_NF_EBTABLES=y
+CONFIG_BRIDGE_EBT_BROUTE=y
+CONFIG_BRIDGE=y
 CONFIG_NET_SCHED=y
 CONFIG_NET_SCH_HTB=y
 CONFIG_NET_SCH_PRIO=y
diff --git a/arch/arm/configs/msm9625-perf_defconfig b/arch/arm/configs/msm9625-perf_defconfig
new file mode 100644
index 0000000..1fe528a
--- /dev/null
+++ b/arch/arm/configs/msm9625-perf_defconfig
@@ -0,0 +1,325 @@
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_DEBUG=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_SCHED=y
+# CONFIG_FAIR_GROUP_SCHED is not set
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_PANIC_TIMEOUT=5
+CONFIG_KALLSYMS_ALL=y
+CONFIG_EMBEDDED=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ARCH_MSM=y
+CONFIG_ARCH_MSM9625=y
+# CONFIG_MSM_STACKED_MEMORY is not set
+CONFIG_CPU_HAS_L2_PMU=y
+# CONFIG_MSM_FIQ_SUPPORT is not set
+# CONFIG_MSM_PROC_COMM is not set
+CONFIG_MSM_SMD=y
+CONFIG_MSM_SMD_PKG4=y
+CONFIG_MSM_BAM_DMUX=y
+CONFIG_MSM_SMP2P=y
+CONFIG_MSM_SMP2P_TEST=y
+CONFIG_MSM_IPC_LOGGING=y
+CONFIG_MSM_IPC_ROUTER=y
+CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
+CONFIG_MSM_RPM_REGULATOR_SMD=y
+CONFIG_MSM_SUBSYSTEM_RESTART=y
+CONFIG_MSM_PIL=y
+CONFIG_MSM_PIL_MSS_QDSP6V5=y
+CONFIG_MSM_DIRECT_SCLK_ACCESS=y
+CONFIG_MSM_BUS_SCALING=y
+CONFIG_MSM_WATCHDOG_V2=y
+CONFIG_MSM_DLOAD_MODE=y
+CONFIG_MSM_ADSP_LOADER=m
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_ARM_ARCH_TIMER=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_VMALLOC_RESERVE=0x19000000
+CONFIG_USE_OF=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_IDLE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_PM_RUNTIME=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_IPV6=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_DEBUG=y
+CONFIG_NETFILTER_NETLINK_QUEUE=y
+CONFIG_NETFILTER_NETLINK_LOG=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CONNTRACK_TIMESTAMP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+CONFIG_NF_CONNTRACK_AMANDA=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_H323=y
+CONFIG_NF_CONNTRACK_IRC=y
+CONFIG_NF_CONNTRACK_NETBIOS_NS=y
+CONFIG_NF_CONNTRACK_SNMP=y
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SIP=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_XT_MARK=y
+CONFIG_NETFILTER_XT_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_DSCP=y
+CONFIG_NETFILTER_XT_MATCH_ESP=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_IP_SET=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_IP_NF_TARGET_REJECT_SKERR=y
+CONFIG_IP_NF_TARGET_ULOG=y
+CONFIG_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NATTYPE_MODULE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_TARGET_ECN=y
+CONFIG_IP_NF_TARGET_TTL=y
+CONFIG_IP_NF_RAW=y
+CONFIG_NF_CONNTRACK_IPV6=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_MATCH_AH=y
+CONFIG_IP6_NF_MATCH_FRAG=y
+CONFIG_IP6_NF_MATCH_OPTS=y
+CONFIG_IP6_NF_MATCH_HL=y
+CONFIG_IP6_NF_MATCH_IPV6HEADER=y
+CONFIG_IP6_NF_MATCH_MH=y
+CONFIG_IP6_NF_MATCH_RT=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
+CONFIG_IP6_NF_TARGET_REJECT_SKERR=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_BRIDGE_NF_EBTABLES=y
+CONFIG_BRIDGE_EBT_BROUTE=y
+CONFIG_BRIDGE_EBT_T_FILTER=y
+CONFIG_BRIDGE=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_HTB=y
+CONFIG_NET_SCH_PRIO=y
+CONFIG_NET_CLS_FW=y
+CONFIG_CFG80211=m
+CONFIG_NL80211_TESTMODE=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_OF_PARTS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_MTD_MSM_NAND is not set
+CONFIG_MTD_MSM_QPIC_NAND=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+# CONFIG_ANDROID_PMEM is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+CONFIG_KS8851=y
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_MSM_RMNET is not set
+# CONFIG_MSM_RMNET_BAM is not set
+CONFIG_MSM_RMNET_WWAN=y
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+CONFIG_ATH6K_LEGACY_EXT=y
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_INPUT_GPIO=m
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_MSM_HSL=y
+CONFIG_SERIAL_MSM_HS=y
+CONFIG_MSM_UARTDM_Core_v14=y
+CONFIG_DIAG_CHAR=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_MSM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_QUP=y
+CONFIG_SPI=y
+CONFIG_SPI_QUP=y
+CONFIG_SPI_SPIDEV=m
+CONFIG_SPMI=y
+CONFIG_SPMI_MSM_PMIC_ARB=y
+CONFIG_MSM_QPNP_INT=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_QPNP_PIN=y
+CONFIG_GPIO_QPNP_PIN_DEBUG=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_SMB137C_CHARGER=y
+CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_TSENS8974=y
+CONFIG_WCD9320_CODEC=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_QPNP=y
+CONFIG_ION=y
+CONFIG_ION_MSM=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_MDM9625=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_CI13XXX_MSM=y
+CONFIG_USB_G_ANDROID=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_MSM_HSIC=y
+CONFIG_MMC=y
+CONFIG_MMC_PERF_PROFILING=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_EMBEDDED_SDIO=y
+CONFIG_MMC_PARANOID_SD_INIT=y
+CONFIG_MMC_BLOCK_MINORS=32
+CONFIG_MMC_TEST=m
+CONFIG_MMC_MSM=y
+CONFIG_MMC_MSM_SPS_SUPPORT=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_DRV_MSM is not set
+CONFIG_RTC_DRV_QPNP=y
+CONFIG_SPS=y
+CONFIG_USB_BAM=y
+CONFIG_SPS_SUPPORT_BAMDMA=y
+CONFIG_SPS_SUPPORT_NDP_BAM=y
+CONFIG_QPNP_POWER_ON=y
+CONFIG_IPA=y
+CONFIG_ECM_IPA=y
+CONFIG_CORESIGHT=y
+CONFIG_CORESIGHT_TMC=y
+CONFIG_CORESIGHT_TPIU=y
+CONFIG_CORESIGHT_FUNNEL=y
+CONFIG_CORESIGHT_REPLICATOR=y
+CONFIG_CORESIGHT_STM=y
+CONFIG_CORESIGHT_ETM=y
+CONFIG_CORESIGHT_EVENT=m
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_YAFFS_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_YAFFS_DISABLE_TAGS_ECC=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_ENABLE_DEFAULT_TRACERS=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_USER=y
+CONFIG_KEYS=y
+CONFIG_CRYPTO_AUTHENC=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_DEV_QCRYPTO=m
+CONFIG_CRYPTO_DEV_QCE=m
+CONFIG_CRYPTO_DEV_QCEDEV=m
+CONFIG_CRC_CCITT=y
+CONFIG_LIBCRC32C=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_EHSET=y
+CONFIG_USB_EHCI_MSM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DEBUG=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_KARMA=y
+CONFIG_USB_STORAGE_CYPRESS_ATACB=y
+CONFIG_USB_EHSET_TEST_FIXTURE=y
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_MSM_RTB=y
+CONFIG_MSM_MEMORY_DUMP=y
diff --git a/arch/arm/configs/msm9625_defconfig b/arch/arm/configs/msm9625_defconfig
index a3e7b98..aa18209 100644
--- a/arch/arm/configs/msm9625_defconfig
+++ b/arch/arm/configs/msm9625_defconfig
@@ -40,6 +40,9 @@
 CONFIG_MSM_SMD=y
 CONFIG_MSM_SMD_PKG4=y
 CONFIG_MSM_BAM_DMUX=y
+CONFIG_MSM_SMP2P=y
+CONFIG_MSM_SMP2P_TEST=y
+CONFIG_MSM_IPC_LOGGING=y
 CONFIG_MSM_IPC_ROUTER=y
 CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
 CONFIG_MSM_RPM_REGULATOR_SMD=y
@@ -88,15 +91,24 @@
 CONFIG_NF_CONNTRACK=y
 CONFIG_NF_CONNTRACK_EVENTS=y
 CONFIG_NF_CONNTRACK_TIMESTAMP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+CONFIG_NF_CONNTRACK_AMANDA=y
 CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_H323=y
+CONFIG_NF_CONNTRACK_IRC=y
+CONFIG_NF_CONNTRACK_NETBIOS_NS=y
+CONFIG_NF_CONNTRACK_SNMP=y
 CONFIG_NF_CONNTRACK_PPTP=y
 CONFIG_NF_CONNTRACK_SIP=y
 CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NF_CT_NETLINK=y
 CONFIG_NETFILTER_XT_MARK=y
 CONFIG_NETFILTER_XT_CONNMARK=y
 CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_DSCP=y
+CONFIG_NETFILTER_XT_MATCH_ESP=y
 CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
 CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
 CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
@@ -133,6 +145,10 @@
 CONFIG_IP6_NF_TARGET_REJECT_SKERR=y
 CONFIG_IP6_NF_MANGLE=y
 CONFIG_IP6_NF_RAW=y
+CONFIG_BRIDGE_NF_EBTABLES=y
+CONFIG_BRIDGE_EBT_BROUTE=y
+CONFIG_BRIDGE_EBT_T_FILTER=y
+CONFIG_BRIDGE=y
 CONFIG_NET_SCHED=y
 CONFIG_NET_SCH_HTB=y
 CONFIG_NET_SCH_PRIO=y
@@ -156,7 +172,8 @@
 CONFIG_KS8851=y
 # CONFIG_NET_VENDOR_MICROCHIP is not set
 # CONFIG_MSM_RMNET is not set
-CONFIG_MSM_RMNET_BAM=y
+# CONFIG_MSM_RMNET_BAM is not set
+CONFIG_MSM_RMNET_WWAN=y
 # CONFIG_NET_VENDOR_NATSEMI is not set
 # CONFIG_NET_VENDOR_SEEQ is not set
 # CONFIG_NET_VENDOR_SMSC is not set
@@ -173,6 +190,8 @@
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_MSM_HSL=y
 CONFIG_SERIAL_MSM_HSL_CONSOLE=y
+CONFIG_SERIAL_MSM_HS=y
+CONFIG_MSM_UARTDM_Core_v14=y
 CONFIG_DIAG_CHAR=y
 CONFIG_HW_RANDOM=y
 CONFIG_HW_RANDOM_MSM=y
@@ -207,6 +226,9 @@
 CONFIG_USB_GADGET=y
 CONFIG_USB_CI13XXX_MSM=y
 CONFIG_USB_G_ANDROID=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_MSM_HSIC=y
 CONFIG_MMC=y
 CONFIG_MMC_PERF_PROFILING=y
 CONFIG_MMC_UNSAFE_RESUME=y
@@ -226,10 +248,19 @@
 CONFIG_SPS_SUPPORT_NDP_BAM=y
 CONFIG_QPNP_POWER_ON=y
 CONFIG_IPA=y
-CONFIG_MSM_QDSS=y
+CONFIG_ECM_IPA=y
+CONFIG_CORESIGHT=y
+CONFIG_CORESIGHT_TMC=y
+CONFIG_CORESIGHT_TPIU=y
+CONFIG_CORESIGHT_FUNNEL=y
+CONFIG_CORESIGHT_REPLICATOR=y
+CONFIG_CORESIGHT_STM=y
+CONFIG_CORESIGHT_ETM=y
+CONFIG_CORESIGHT_EVENT=m
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
 CONFIG_YAFFS_FS=y
+CONFIG_EXT3_FS=y
 CONFIG_YAFFS_DISABLE_TAGS_ECC=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ASCII=y
@@ -257,6 +288,39 @@
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_TWOFISH=y
 CONFIG_CRYPTO_DEFLATE=y
-# CONFIG_CRYPTO_HW is not set
+CONFIG_CRYPTO_DEV_QCRYPTO=m
+CONFIG_CRYPTO_DEV_QCE=m
+CONFIG_CRYPTO_DEV_QCEDEV=m
 CONFIG_CRC_CCITT=y
 CONFIG_LIBCRC32C=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_EHSET=y
+CONFIG_USB_EHCI_MSM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DEBUG=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_KARMA=y
+CONFIG_USB_STORAGE_CYPRESS_ATACB=y
+CONFIG_USB_EHSET_TEST_FIXTURE=y
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_MSM_RTB=y
+CONFIG_MSM_MEMORY_DUMP=y
diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
index e32194f..bdfdfa0 100644
--- a/arch/arm/include/asm/arch_timer.h
+++ b/arch/arm/include/asm/arch_timer.h
@@ -3,6 +3,7 @@
 
 #include <linux/ioport.h>
 #include <linux/clocksource.h>
+#include <asm/errno.h>
 
 struct arch_timer {
 	struct resource	res[3];
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index d021905..584fe0b 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -16,7 +16,6 @@
 #include <asm/shmparam.h>
 #include <asm/cachetype.h>
 #include <asm/outercache.h>
-#include <asm/rodata.h>
 
 #define CACHE_COLOUR(vaddr)	((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
 
diff --git a/arch/arm/include/asm/delay.h b/arch/arm/include/asm/delay.h
index 5c6b9a3..ab98fdd 100644
--- a/arch/arm/include/asm/delay.h
+++ b/arch/arm/include/asm/delay.h
@@ -6,9 +6,27 @@
 #ifndef __ASM_ARM_DELAY_H
 #define __ASM_ARM_DELAY_H
 
+#include <asm/memory.h>
 #include <asm/param.h>	/* HZ */
 
-extern void __delay(unsigned long loops);
+#define MAX_UDELAY_MS	2
+#define UDELAY_MULT	((UL(2199023) * HZ) >> 11)
+#define UDELAY_SHIFT	30
+
+#ifndef __ASSEMBLY__
+
+struct delay_timer {
+	unsigned long (*read_current_timer)(void);
+	unsigned long freq;
+};
+
+extern struct arm_delay_ops {
+	void (*delay)(unsigned long);
+	void (*const_udelay)(unsigned long);
+	void (*udelay)(unsigned long);
+} arm_delay_ops;
+
+#define __delay(n)		arm_delay_ops.delay(n)
 
 /*
  * This function intentionally does not exist; if you see references to
@@ -23,25 +41,31 @@
  * division by multiplication: you don't have to worry about
  * loss of precision.
  *
- * Use only for very small delays ( < 1 msec).  Should probably use a
+ * Use only for very small delays ( < 2 msec).  Should probably use a
  * lookup table, really, as the multiplications take much too long with
  * short delays.  This is a "reasonable" implementation, though (and the
  * first constant multiplications gets optimized away if the delay is
  * a constant)
  */
-extern void __udelay(unsigned long usecs);
-extern void __const_udelay(unsigned long);
-
-#define MAX_UDELAY_MS 2
+#define __udelay(n)		arm_delay_ops.udelay(n)
+#define __const_udelay(n)	arm_delay_ops.const_udelay(n)
 
 #define udelay(n)							\
 	(__builtin_constant_p(n) ?					\
 	  ((n) > (MAX_UDELAY_MS * 1000) ? __bad_udelay() :		\
-			__const_udelay((n) * ((2199023U*HZ)>>11))) :	\
+			__const_udelay((n) * UDELAY_MULT)) :		\
 	  __udelay(n))
 
-extern void set_delay_fn(void (*fn)(unsigned long));
-extern void read_current_timer_delay_loop(unsigned long loops);
+/* Loop-based definitions for assembly code. */
+extern void __loop_delay(unsigned long loops);
+extern void __loop_udelay(unsigned long usecs);
+extern void __loop_const_udelay(unsigned long);
+
+/* Delay-loop timer registration. */
+#define ARCH_HAS_READ_CURRENT_TIMER
+extern void register_current_timer_delay(const struct delay_timer *timer);
+
+#endif /* __ASSEMBLY__ */
 
 #endif /* defined(_ARM_DELAY_H) */
 
diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h
index b216a00..6c88a86 100644
--- a/arch/arm/include/asm/domain.h
+++ b/arch/arm/include/asm/domain.h
@@ -2,7 +2,7 @@
  *  arch/arm/include/asm/domain.h
  *
  *  Copyright (C) 1999 Russell King.
- *  Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2009, 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 as
diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h
index 926ac0e..27ecb3a 100644
--- a/arch/arm/include/asm/hardware/cache-l2x0.h
+++ b/arch/arm/include/asm/hardware/cache-l2x0.h
@@ -116,6 +116,7 @@
 #define L2X0_PREFETCH_CTRL_WRAP8_SHIFT		30
 
 #ifndef __ASSEMBLY__
+extern void __iomem *l2x0_base;
 extern void l2cc_suspend(void);
 extern void l2cc_resume(void);
 extern void l2x0_cache_sync(void);
diff --git a/arch/arm/include/asm/mmu_writeable.h b/arch/arm/include/asm/mmu_writeable.h
index 96d348c..8c64b7f 100644
--- a/arch/arm/include/asm/mmu_writeable.h
+++ b/arch/arm/include/asm/mmu_writeable.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h
index a40f81e..4f41fd6 100644
--- a/arch/arm/include/asm/perf_event.h
+++ b/arch/arm/include/asm/perf_event.h
@@ -22,6 +22,7 @@
 	ARM_PERF_PMU_ID_CA9,
 	ARM_PERF_PMU_ID_CA5,
 	ARM_PERF_PMU_ID_CA15,
+	ARM_PERF_PMU_ID_L2X0,
 	ARM_PERF_PMU_ID_CA7,
 	ARM_PERF_PMU_ID_SCORPION,
 	ARM_PERF_PMU_ID_SCORPIONMP,
diff --git a/arch/arm/include/asm/perftypes.h b/arch/arm/include/asm/perftypes.h
index 8d21dcd..6716a65 100644
--- a/arch/arm/include/asm/perftypes.h
+++ b/arch/arm/include/asm/perftypes.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h
index 5188dbf..d1a3e61 100644
--- a/arch/arm/include/asm/pmu.h
+++ b/arch/arm/include/asm/pmu.h
@@ -151,6 +151,9 @@
 			    struct hw_perf_event *hwc,
 			    int idx);
 
+extern void enable_irq_callback(void *);
+extern void disable_irq_callback(void *);
+
 #endif /* CONFIG_HW_PERF_EVENTS */
 
 #endif /* __ARM_PMU_H__ */
diff --git a/arch/arm/include/asm/remote_spinlock.h b/arch/arm/include/asm/remote_spinlock.h
index 702b669..6a895c2 100644
--- a/arch/arm/include/asm/remote_spinlock.h
+++ b/arch/arm/include/asm/remote_spinlock.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/include/asm/rodata.h b/arch/arm/include/asm/rodata.h
deleted file mode 100644
index 8c8add8..0000000
--- a/arch/arm/include/asm/rodata.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- *  arch/arm/include/asm/rodata.h
- *
- *  Copyright (C) 2011 Google, Inc.
- *
- *  Author: Colin Cross <ccross@android.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef _ASMARM_RODATA_H
-#define _ASMARM_RODATA_H
-
-#ifndef __ASSEMBLY__
-
-#ifdef CONFIG_DEBUG_RODATA
-
-int set_memory_rw(unsigned long virt, int numpages);
-int set_memory_ro(unsigned long virt, int numpages);
-
-void mark_rodata_ro(void);
-void set_kernel_text_rw(void);
-void set_kernel_text_ro(void);
-#else
-static inline void set_kernel_text_rw(void) { }
-static inline void set_kernel_text_ro(void) { }
-#endif
-
-#endif
-
-#endif
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index 0f04d84..67d6443 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -153,7 +153,7 @@
 #define TIF_MEMDIE		18	/* is terminating due to OOM killer */
 #define TIF_RESTORE_SIGMASK	20
 #define TIF_SECCOMP		21
-
+#define TIF_MM_RELEASED		22	/* task MM has been released */
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
 #define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
diff --git a/arch/arm/include/asm/timex.h b/arch/arm/include/asm/timex.h
index 3be8de3..9acc135 100644
--- a/arch/arm/include/asm/timex.h
+++ b/arch/arm/include/asm/timex.h
@@ -15,10 +15,6 @@
 #include <mach/timex.h>
 
 typedef unsigned long cycles_t;
-
-static inline cycles_t get_cycles (void)
-{
-	return 0;
-}
+#define get_cycles()	({ cycles_t c; read_current_timer(&c) ? 0 : c; })
 
 #endif
diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c
index 2455d1f..2b3667f 100644
--- a/arch/arm/kernel/arch_timer.c
+++ b/arch/arm/kernel/arch_timer.c
@@ -25,6 +25,7 @@
 #include <linux/export.h>
 
 #include <asm/cputype.h>
+#include <asm/delay.h>
 #include <asm/localtimer.h>
 #include <asm/arch_timer.h>
 #include <asm/sched_clock.h>
@@ -72,6 +73,8 @@
 
 static struct arch_timer_operations *arch_specific_timer = &arch_timer_ops_cp15;
 
+static struct delay_timer arch_delay_timer;
+
 /*
  * Architected system timer support.
  */
@@ -331,13 +334,10 @@
 	return arch_counter_get_cntpct();
 }
 
-#ifdef ARCH_HAS_READ_CURRENT_TIMER
-int read_current_timer(unsigned long *timer_val)
+static unsigned long arch_timer_read_current_timer(void)
 {
-	*timer_val = (unsigned long)arch_specific_timer->get_cntpct();
-	return 0;
+	return arch_counter_get_cntpct();
 }
-#endif
 
 static struct clocksource clocksource_counter = {
 	.name	= "arch_sys_counter",
@@ -402,10 +402,6 @@
 
 	setup_sched_clock(arch_timer_update_sched_clock, 32, arch_timer_rate);
 
-#ifdef ARCH_HAS_READ_CURRENT_TIMER
-	set_delay_fn(read_current_timer_delay_loop);
-#endif
-
 	if (is_irq_percpu)
 		err = request_percpu_irq(arch_timer_ppi, arch_timer_handler,
 				 "arch_timer", arch_timer_evt);
@@ -439,6 +435,10 @@
 		goto out_free_irq;
 	percpu_timer_setup();
 
+	/* Use the architected timer for the delay loop. */
+	arch_delay_timer.read_current_timer = &arch_timer_read_current_timer;
+	arch_delay_timer.freq = arch_timer_rate;
+	register_current_timer_delay(&arch_delay_timer);
 	return 0;
 
 out_free_irq:
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index f1a50f3..7196228 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -48,6 +48,9 @@
 
 extern void fpundefinstr(void);
 
+	/* platform dependent support */
+EXPORT_SYMBOL(arm_delay_ops);
+
 	/* networking */
 EXPORT_SYMBOL(csum_partial);
 EXPORT_SYMBOL(csum_partial_copy_from_user);
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
index bf17145..df0bf0c 100644
--- a/arch/arm/kernel/ftrace.c
+++ b/arch/arm/kernel/ftrace.c
@@ -13,7 +13,6 @@
  */
 
 #include <linux/ftrace.h>
-#include <linux/module.h>
 #include <linux/uaccess.h>
 
 #include <asm/cacheflush.h>
@@ -64,20 +63,6 @@
 }
 #endif
 
-int ftrace_arch_code_modify_prepare(void)
-{
-	set_kernel_text_rw();
-	set_all_modules_text_rw();
-	return 0;
-}
-
-int ftrace_arch_code_modify_post_process(void)
-{
-	set_all_modules_text_ro();
-	set_kernel_text_ro();
-	return 0;
-}
-
 static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr)
 {
 	return arm_gen_branch_link(pc, addr);
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index d2e2e44..5311d74 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -739,6 +739,35 @@
 	armpmu->type = ARM_PMU_DEVICE_CPU;
 }
 
+static int cpu_has_active_perf(int cpu)
+{
+	struct pmu_hw_events *hw_events;
+	int enabled;
+
+	if (!cpu_pmu)
+		return 0;
+	hw_events = &per_cpu(cpu_hw_events, cpu);
+	enabled = bitmap_weight(hw_events->used_mask, cpu_pmu->num_events);
+
+	if (enabled)
+		/*Even one event's existence is good enough.*/
+		return 1;
+
+	return 0;
+}
+
+void enable_irq_callback(void *info)
+{
+	int irq = *(unsigned int *)info;
+	enable_percpu_irq(irq, IRQ_TYPE_EDGE_RISING);
+}
+
+void disable_irq_callback(void *info)
+{
+	int irq = *(unsigned int *)info;
+	disable_percpu_irq(irq);
+}
+
 /*
  * PMU hardware loses all context when a CPU goes offline.
  * When a CPU is hotplugged back in, since some hardware registers are
@@ -748,12 +777,50 @@
 static int __cpuinit pmu_cpu_notify(struct notifier_block *b,
 					unsigned long action, void *hcpu)
 {
+	int irq;
+
+	if (cpu_has_active_perf((int)hcpu)) {
+		switch ((action & ~CPU_TASKS_FROZEN)) {
+
+		case CPU_DOWN_PREPARE:
+			/*
+			 * If this is on a multicore CPU, we need
+			 * to disarm the PMU IRQ before disappearing.
+			 */
+			if (cpu_pmu &&
+				cpu_pmu->plat_device->dev.platform_data) {
+				irq = platform_get_irq(cpu_pmu->plat_device, 0);
+				smp_call_function_single((int)hcpu,
+						disable_irq_callback, &irq, 1);
+			}
+			return NOTIFY_DONE;
+
+		case CPU_UP_PREPARE:
+			/*
+			 * If this is on a multicore CPU, we need
+			 * to arm the PMU IRQ before appearing.
+			 */
+			if (cpu_pmu &&
+				cpu_pmu->plat_device->dev.platform_data) {
+				irq = platform_get_irq(cpu_pmu->plat_device, 0);
+				smp_call_function_single((int)hcpu,
+						enable_irq_callback, &irq, 1);
+			}
+			return NOTIFY_DONE;
+
+		case CPU_STARTING:
+			if (cpu_pmu && cpu_pmu->reset) {
+				cpu_pmu->reset(NULL);
+				return NOTIFY_OK;
+			}
+		default:
+			return NOTIFY_DONE;
+		}
+	}
+
 	if ((action & ~CPU_TASKS_FROZEN) != CPU_STARTING)
 		return NOTIFY_DONE;
 
-	if (cpu_pmu && cpu_pmu->reset)
-		cpu_pmu->reset(NULL);
-
 	return NOTIFY_OK;
 }
 
@@ -777,24 +844,6 @@
 	}
 }
 
-static int cpu_has_active_perf(void)
-{
-	struct pmu_hw_events *hw_events;
-	int enabled;
-
-	if (!cpu_pmu)
-		return 0;
-
-	hw_events = cpu_pmu->get_hw_events();
-	enabled = bitmap_weight(hw_events->used_mask, cpu_pmu->num_events);
-
-	if (enabled)
-		/*Even one event's existence is good enough.*/
-		return 1;
-
-	return 0;
-}
-
 static struct notifier_block __cpuinitdata pmu_cpu_notifier = {
 	.notifier_call = pmu_cpu_notify,
 };
@@ -805,7 +854,7 @@
 {
 	switch (cmd) {
 	case CPU_PM_ENTER:
-		if (cpu_has_active_perf()) {
+		if (cpu_has_active_perf((int)v)) {
 			armpmu_update_counters();
 			perf_pmu_disable(&cpu_pmu->pmu);
 		}
@@ -813,7 +862,7 @@
 
 	case CPU_PM_ENTER_FAILED:
 	case CPU_PM_EXIT:
-		if (cpu_has_active_perf() && cpu_pmu->reset) {
+		if (cpu_has_active_perf((int)v) && cpu_pmu->reset) {
 			/*
 			 * Flip this bit so armpmu_enable knows it needs
 			 * to re-enable active counters.
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index 678c55d..58e9068 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -997,6 +997,7 @@
 {
 	unsigned long flags;
 	struct pmu_hw_events *events = cpu_pmu->get_hw_events();
+	unsigned long long prev_count = local64_read(&hwc->prev_count);
 
 	/*
 	 * Enable counter and interrupt, and set the counter to count
@@ -1022,6 +1023,9 @@
 	 */
 	armv7_pmnc_enable_intens(idx);
 
+	/* Restore prev val */
+	armv7pmu_write_counter(idx, prev_count & 0xffffffff);
+
 	/*
 	 * Enable counter
 	 */
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index dea0f1f..cf10056 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -269,7 +269,7 @@
 	mb();
 
 	/* Tell __cpu_die() that this CPU is now safe to dispose of */
-	RCU_NONIDLE(complete(&cpu_died));
+	complete(&cpu_died);
 
 	/*
 	 * actual CPU shutdown procedure is at least platform (if not
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 0ade0ac..8ade75d 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -6,7 +6,7 @@
 
 lib-y		:= backtrace.o changebit.o csumipv6.o csumpartial.o   \
 		   csumpartialcopy.o csumpartialcopyuser.o clearbit.o \
-		   delay.o findbit.o memchr.o memcpy.o		      \
+		   delay.o delay-loop.o findbit.o memchr.o memcpy.o   \
 		   memmove.o memset.o memzero.o setbit.o              \
 		   strncpy_from_user.o strnlen_user.o                 \
 		   strchr.o strrchr.o                                 \
diff --git a/arch/arm/lib/delay-loop.S b/arch/arm/lib/delay-loop.S
new file mode 100644
index 0000000..36b668d
--- /dev/null
+++ b/arch/arm/lib/delay-loop.S
@@ -0,0 +1,67 @@
+/*
+ *  linux/arch/arm/lib/delay.S
+ *
+ *  Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/delay.h>
+		.text
+
+.LC0:		.word	loops_per_jiffy
+.LC1:		.word	UDELAY_MULT
+
+/*
+ * r0  <= 2000
+ * lpj <= 0x01ffffff (max. 3355 bogomips)
+ * HZ  <= 1000
+ */
+
+ENTRY(__loop_udelay)
+		ldr	r2, .LC1
+		mul	r0, r2, r0
+ENTRY(__loop_const_udelay)			@ 0 <= r0 <= 0x7fffff06
+		mov	r1, #-1
+		ldr	r2, .LC0
+		ldr	r2, [r2]		@ max = 0x01ffffff
+		add	r0, r0, r1, lsr #32-14
+		mov	r0, r0, lsr #14		@ max = 0x0001ffff
+		add	r2, r2, r1, lsr #32-10
+		mov	r2, r2, lsr #10		@ max = 0x00007fff
+		mul	r0, r2, r0		@ max = 2^32-1
+		add	r0, r0, r1, lsr #32-6
+		movs	r0, r0, lsr #6
+		moveq	pc, lr
+
+/*
+ * loops = r0 * HZ * loops_per_jiffy / 1000000
+ */
+
+@ Delay routine
+ENTRY(__loop_delay)
+		subs	r0, r0, #1
+#if 0
+		movls	pc, lr
+		subs	r0, r0, #1
+		movls	pc, lr
+		subs	r0, r0, #1
+		movls	pc, lr
+		subs	r0, r0, #1
+		movls	pc, lr
+		subs	r0, r0, #1
+		movls	pc, lr
+		subs	r0, r0, #1
+		movls	pc, lr
+		subs	r0, r0, #1
+		movls	pc, lr
+		subs	r0, r0, #1
+#endif
+		bhi	__loop_delay
+		mov	pc, lr
+ENDPROC(__loop_udelay)
+ENDPROC(__loop_const_udelay)
+ENDPROC(__loop_delay)
diff --git a/arch/arm/lib/delay.c b/arch/arm/lib/delay.c
index fc9a37c..0dc5385 100644
--- a/arch/arm/lib/delay.c
+++ b/arch/arm/lib/delay.c
@@ -1,90 +1,90 @@
 /*
- *  Originally from linux/arch/arm/lib/delay.S
+ * Delay loops based on the OpenRISC implementation.
  *
- *  Copyright (C) 1995, 1996 Russell King
- *  Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *  Copyright (C) 1993 Linus Torvalds
- *  Copyright (C) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
- *  Copyright (C) 2005-2006 Atmel Corporation
+ * Copyright (C) 2012 ARM Limited
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Will Deacon <will.deacon@arm.com>
  */
-#include <linux/module.h>
+
 #include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/timex.h>
 
 /*
- * Oh, if only we had a cycle counter...
+ * Default to the loop-based delay implementation.
  */
-void delay_loop(unsigned long loops)
+struct arm_delay_ops arm_delay_ops = {
+	.delay		= __loop_delay,
+	.const_udelay	= __loop_const_udelay,
+	.udelay		= __loop_udelay,
+};
+
+static const struct delay_timer *delay_timer;
+static bool delay_calibrated;
+
+int read_current_timer(unsigned long *timer_val)
 {
-	asm volatile(
-	"1:	subs %0, %0, #1 \n"
-	"	bhi 1b		\n"
-	: /* No output */
-	: "r" (loops)
-	);
+	if (!delay_timer)
+		return -ENXIO;
+
+	*timer_val = delay_timer->read_current_timer();
+	return 0;
+}
+EXPORT_SYMBOL_GPL(read_current_timer);
+
+static void __timer_delay(unsigned long cycles)
+{
+	cycles_t start = get_cycles();
+
+	while ((get_cycles() - start) < cycles)
+		cpu_relax();
 }
 
-#ifdef ARCH_HAS_READ_CURRENT_TIMER
-/*
- * Assuming read_current_timer() is monotonically increasing
- * across calls.
- */
-void read_current_timer_delay_loop(unsigned long loops)
+static void __timer_const_udelay(unsigned long xloops)
 {
-	unsigned long bclock, now;
-
-	read_current_timer(&bclock);
-	do {
-		read_current_timer(&now);
-	} while ((now - bclock) < loops);
-}
-#endif
-
-static void (*delay_fn)(unsigned long) = delay_loop;
-
-void set_delay_fn(void (*fn)(unsigned long))
-{
-	delay_fn = fn;
+	unsigned long long loops = xloops;
+	loops *= loops_per_jiffy;
+	__timer_delay(loops >> UDELAY_SHIFT);
 }
 
-/*
- * loops = usecs * HZ * loops_per_jiffy / 1000000
- */
-void __delay(unsigned long loops)
+static void __timer_udelay(unsigned long usecs)
 {
-	delay_fn(loops);
+	__timer_const_udelay(usecs * UDELAY_MULT);
 }
-EXPORT_SYMBOL(__delay);
 
-/*
- * 0 <= xloops <= 0x7fffff06
- * loops_per_jiffy <= 0x01ffffff (max. 3355 bogomips)
- */
-void __const_udelay(unsigned long xloops)
+void __init register_current_timer_delay(const struct delay_timer *timer)
 {
-	unsigned long lpj;
-	unsigned long loops;
-
-	xloops >>= 14;			/* max = 0x01ffffff */
-	lpj = loops_per_jiffy >> 10;	/* max = 0x0001ffff */
-	loops = lpj * xloops;		/* max = 0x00007fff */
-	loops >>= 6;			/* max = 2^32-1 */
-
-	if (loops)
-		__delay(loops);
+	if (!delay_calibrated) {
+		pr_info("Switching to timer-based delay loop\n");
+		delay_timer			= timer;
+		lpj_fine			= timer->freq / HZ;
+		loops_per_jiffy			= lpj_fine;
+		arm_delay_ops.delay		= __timer_delay;
+		arm_delay_ops.const_udelay	= __timer_const_udelay;
+		arm_delay_ops.udelay		= __timer_udelay;
+		delay_calibrated		= true;
+	} else {
+		pr_info("Ignoring duplicate/late registration of read_current_timer delay\n");
+	}
 }
-EXPORT_SYMBOL(__const_udelay);
 
-/*
- * usecs  <= 2000
- * HZ  <= 1000
- */
-void __udelay(unsigned long usecs)
+unsigned long __cpuinit calibrate_delay_is_known(void)
 {
-	__const_udelay(usecs * ((2199023UL*HZ)>>11));
+	delay_calibrated = true;
+	return lpj_fine;
 }
-EXPORT_SYMBOL(__udelay);
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 8dd8579..f0b706a 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -184,6 +184,7 @@
 	select ARM_USE_USER_ACCESSIBLE_TIMERS
 	select MSM_USE_USER_ACCESSIBLE_TIMERS
 	select MSM_CPU_PWRCTL
+	select MSM_LPM_TEST
 
 config ARCH_MSM8930
 	bool "MSM8930"
@@ -287,6 +288,9 @@
 	select QMI_ENCDEC
 	select DONT_MAP_HOLE_AFTER_MEMBANK0
 	select SENSORS_ADSP
+	select MSM_ULTRASOUND_B
+	select MSM_LPM_TEST
+	select MSM_RPM_LOG
 
 config ARCH_MPQ8092
 	bool "MPQ8092"
@@ -346,6 +350,7 @@
 	select MSM_RUN_QUEUE_STATS
 	select MIGHT_HAVE_CACHE_L2X0
 	select ARM_HAS_SG_CHAIN
+	select CPU_HAS_L2_PMU
 
 config ARCH_MSM9625
 	bool "MSM9625"
@@ -372,9 +377,13 @@
 	select MSM_QDSP6_APRV2
 	select MSM_QDSP6V2_CODECS
 	select MSM_AUDIO_QDSP6V2 if SND_SOC
+	select CPU_HAS_L2_PMU
+	select MSM_JTAG_MM if CORESIGHT_ETM
+	select MEMORY_HOLE_CARVEOUT
+	select MSM_RPM_LOG
 
-config ARCH_MSM8910
-	bool "MSM8910"
+config ARCH_MSM8610
+	bool "MSM8610"
 	select ARM_GIC
 	select GIC_SECURE
 	select ARCH_MSM_CORTEXMP
@@ -387,6 +396,23 @@
 	select MSM_GPIOMUX
 	select MSM_NATIVE_RESTART
 	select MSM_RESTART_V2
+	select MEMORY_HOLE_CARVEOUT
+	select DONT_MAP_HOLE_AFTER_MEMBANK
+	select QMI_ENCDEC
+	select MSM_QDSP6_APRV2
+	select MSM_QDSP6V2_CODECS
+	select MSM_AUDIO_QDSP6V2 if SND_SOC
+	select MSM_RPM_SMD
+	select MSM_SPM_V2
+	select MSM_L2_SPM
+	select MSM_PM8X60 if PM
+	select CPU_FREQ_MSM
+	select CPU_FREQ
+	select CPU_FREQ_GOV_USERSPACE
+	select CPU_FREQ_GOV_ONDEMAND
+	select MSM_PIL
+	select MSM_RUN_QUEUE_STATS
+	select ARM_HAS_SG_CHAIN
 
 config ARCH_MSM8226
 	bool "MSM8226"
@@ -402,6 +428,18 @@
 	select MSM_GPIOMUX
 	select MSM_NATIVE_RESTART
 	select MSM_RESTART_V2
+	select MSM_QDSP6_APRV2
+	select MSM_QDSP6V2_CODECS
+	select MSM_AUDIO_QDSP6V2 if SND_SOC
+	select QMI_ENCDEC
+	select MSM_RPM_SMD
+	select MSM_SPM_V2
+	select MSM_L2_SPM
+	select MSM_PM8X60 if PM
+	select MEMORY_HOLE_CARVEOUT
+	select DONT_MAP_HOLE_AFTER_MEMBANK0
+	select MSM_BUS_SCALING
+	select ARM_HAS_SG_CHAIN
 endmenu
 
 choice
@@ -446,14 +484,14 @@
 	select ARCH_MSM_SCORPION
 	select MSM_SMP
 	select HAVE_ARCH_HAS_CURRENT_TIMER
-	select MSM_JTAG if MSM_QDSS
+	select MSM_JTAG if CORESIGHT_ETM
 	bool
 
 config  ARCH_MSM_KRAITMP
 	select ARCH_MSM_KRAIT
 	select MSM_SMP
 	select HAVE_ARCH_HAS_CURRENT_TIMER
-	select MSM_JTAG if MSM_QDSS
+	select MSM_JTAG if CORESIGHT_ETM
 	bool
 
 config  ARCH_MSM_CORTEXMP
@@ -478,6 +516,7 @@
 	select ARCH_MSM_CORTEXMP
 	select MIGHT_HAVE_CACHE_L2X0
 	select ARM_HAS_SG_CHAIN
+	select CPU_HAS_L2_PMU
 
 config  MSM_VIC
 	bool
@@ -516,6 +555,17 @@
 	  enables the MPM driver that supports initialization from a device
 	  tree
 
+config MSM_LPM_TEST
+	bool "Low Power Mode test framework"
+	depends on MSM_RPM || MSM_RPM_SMD
+	depends on MSM_PM8X60
+	help
+	  LPM_TEST is a test framework that assists in exercising the low
+	  power mode algorithm on MSM targets. This test framework tracks
+	  notifications sent during entry/exit of the low power modes and
+	  processes them to measure various stats including latency
+	  measurement.
+
 config MSM_XO
 	bool
 
@@ -922,6 +972,15 @@
 	help
 	  Support for the Qualcomm APQ8064 CDP device.
 
+config MACH_FSM8064_EP
+	depends on ARCH_APQ8064
+	bool "FSM8064 EP"
+	help
+	  Support for the Qualcomm FSM8064 EP device.
+	  This board also known as Femto development platform (FDP)
+	  is based on APQ8064 chipset. This board does not support
+	  keyboard, display or multimedia.
+
 config MACH_APQ8064_MTP
 	depends on ARCH_APQ8064
 	bool "APQ8064 MTP"
@@ -980,8 +1039,8 @@
 	default "0x80200000" if ARCH_MSM8930
 	default "0x00000000" if ARCH_MSM8974
 	default "0x00000000" if ARCH_MPQ8092
-	default "0x00000000" if ARCH_MSM8226
-	default "0x00000000" if ARCH_MSM8910
+	default "0x00100000" if ARCH_MSM8226
+	default "0x00100000" if ARCH_MSM8610
 	default "0x10000000" if ARCH_FSM9XXX
 	default "0x00200000" if ARCH_MSM9625
 	default "0x00200000" if !MSM_STACKED_MEMORY
@@ -1421,6 +1480,27 @@
 	  Supports APPS-QDSP SMSM communication along with
 	  normal APPS-MODEM SMSM communication.
 
+config MSM_SMP2P
+	bool "SMSM Point-to-Point (SMP2P)"
+	depends on MSM_SMD
+	help
+	  Provide point-to-point remote signaling support.
+	  SMP2P enables transferring 32-bit values between
+	  the local and a remote system using shared
+	  memory and interrupts.  A client can open multiple
+	  32-bit values by specifying a unique string and
+	  remote processor ID.
+
+config MSM_SMP2P_TEST
+	bool "SMSM Point-to-Point Test"
+	depends on MSM_SMP2P
+	help
+	  Enables loopback and unit testing support for
+	  SMP2P.  Loopback support is used by other
+	  processors to do unit testing.  Unit tests
+	  are used to verify the local and remote
+	  implementations.
+
 config MSM_RESET_MODEM
 	tristate "Reset Modem Driver"
 	depends on MSM_SMD
@@ -1562,6 +1642,16 @@
 	  to perform QMI message marshaling and transport them over IPC
 	  Router.
 
+config MSM_TEST_QMI_CLIENT
+	depends on MSM_QMI_INTERFACE
+	bool "MSM TEST QMI CLIENT"
+	help
+	  The sample QMI client provides a test code for QMI usage. The
+	  test_service client driver uses QMI interface library to send
+	  and receive QMI messages over IPC Router. The test code sends
+	  a synchronous QMI request to the test_service and handles the
+	  QMI responses.
+
 config MSM_ONCRPCROUTER_DEBUG
 	depends on MSM_ONCRPCROUTER
 	default y
@@ -2122,7 +2212,7 @@
 config MSM_RPM_LOG
 	tristate "MSM Resource Power Manager Log Driver"
 	depends on DEBUG_FS
-	depends on MSM_RPM
+	depends on MSM_RPM || MSM_RPM_SMD
 	default n
 	help
 	  This option enables a driver which can read from a circular buffer
@@ -2225,7 +2315,6 @@
 
 config MSM_DLOAD_MODE
 	bool "Enable download mode on crashes"
-	depends on ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_MSM9615 || ARCH_MSM8974 || ARCH_MSM9625
 	default n
 	help
 		This makes the SoC enter download mode when it resets
@@ -2234,15 +2323,29 @@
 		enabled via another mechanism.
 
 config MSM_JTAG
-	bool "JTAG and kernel debug and trace support across power collapse"
+	bool "Debug and ETM trace support across power collapse"
 	help
-	  Enables support for kernel debugging (specifically breakpoints) and
+	  Enables support for debugging (specifically breakpoints) and ETM
 	  processor tracing across power collapse both for JTag and OS hosted
 	  software running on the target. Enabling this will ensure debug
 	  and ETM registers are saved and restored across power collapse.
 
-	  For production builds, you should probably say 'N' here to avoid
-	  potential power, performance and memory penalty.
+	  If unsure, say 'N' here to avoid potential power, performance and
+	  memory penalty.
+
+config MSM_JTAG_MM
+	bool "Debug and ETM trace support across power collapse using memory mapped access"
+	help
+	  Enables support for debugging (specifically breakpoints) and ETM
+	  processor tracing across power collapse both for JTag and OS hosted
+	  software running on the target. Enabling this will ensure debug
+	  and ETM registers are saved and restored across power collapse.
+
+	  Required on targets on which cp14 access to debug and ETM registers is
+	  not permitted and so memory mapped access is necessary.
+
+	  If unsure, say 'N' here to avoid potential power, performance and
+	  memory penalty.
 
 config MSM_ETM
 	tristate "Enable MSM ETM and ETB"
@@ -2384,6 +2487,16 @@
           HW and services, calculating input events
           upon the  ultrasound data.
 
+config MSM_ULTRASOUND_B
+	bool "QDSP6V2 HW Ultrasound support"
+	help
+	  Enable HW Ultrasound support in QDSP6V2.
+	  QDSP6V2 can support HW encoder & decoder and
+	  ultrasound processing. It will enable
+	  ultrasound data paths between
+	  HW and services, calculating input events
+	  upon the ultrasound data.
+
 config MSM_RPC_VIBRATOR
 	bool "RPC based MSM Vibrator Support"
 	depends on MSM_ONCRPCROUTER
@@ -2736,4 +2849,9 @@
 	  stand alone power collapse operation. Selecting this option
 	  ensures that they are always off.
 
+config MSM_UARTDM_Core_v14
+	bool "Use MSM BLSP based HSUART Core v1.4"
+	depends on SERIAL_MSM_HS
+	help
+		Select if BLSP based UART Core v.14 or higher is present.
 endif
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index ff21190..cb5e712 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -33,7 +33,13 @@
 obj-$(CONFIG_ARCH_MSM_SCORPIONMP) += perf_event_msm_l2.o
 obj-$(CONFIG_ARCH_MSM_KRAIT) += msm-krait-l2-accessors.o pmu.o perf_event_msm_krait_l2.o
 obj-$(CONFIG_ARCH_MSM_KRAIT) += krait-scm.o
-obj-$(CONFIG_ARCH_MSM7X27A) += pmu.o
+ifdef CONFIG_HW_PERF_EVENTS
+obj-$(CONFIG_ARCH_MSM7X27A) += pmu.o perf_event_msm_pl310.o
+obj-$(CONFIG_ARCH_MSM9625) += pmu.o perf_event_msm_pl310.o
+obj-$(CONFIG_ARCH_MSM8625) += pmu.o perf_event_msm_pl310.o
+obj-$(CONFIG_ARCH_MSM9615) += pmu.o perf_event_msm_pl310.o
+obj-$(CONFIG_DEBUG_FS) += perf_debug.o
+endif
 
 ifndef CONFIG_MSM_SMP
 obj-$(CONFIG_ARCH_MSM_SCORPION) += msm_fault_handlers.o
@@ -55,6 +61,7 @@
 obj-$(CONFIG_CPU_V6) += idle-v6.o
 obj-$(CONFIG_CPU_V7) += idle-v7.o
 obj-$(CONFIG_MSM_JTAG) += jtag.o
+obj-$(CONFIG_MSM_JTAG_MM) +=  jtag-mm.o
 
 msm-etm-objs := etm.o
 obj-$(CONFIG_MSM_ETM) += msm-etm.o
@@ -67,7 +74,8 @@
 	$(call if_changed,mkrpcsym)
 
 obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o remote_spinlock.o smd_private.o
-
+obj-$(CONFIG_MSM_SMP2P) += smp2p.o smp2p_debug.o smp2p_gpio.o
+obj-$(CONFIG_MSM_SMP2P_TEST) += smp2p_loopback.o smp2p_test.o smp2p_gpio_test.o smp2p_spinlock_test.o
 obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o
 obj-$(CONFIG_MSM_SECURE_IO) += scm-io.o
 obj-$(CONFIG_MSM_PIL) += peripheral-loader.o
@@ -107,7 +115,7 @@
 ifndef CONFIG_ARCH_MSM8226
 ifndef CONFIG_ARCH_MSM9625
 ifndef CONFIG_ARCH_MPQ8092
-ifndef CONFIG_ARCH_MSM8910
+ifndef CONFIG_ARCH_MSM8610
 	obj-y += nand_partitions.o
 endif
 endif
@@ -133,6 +141,7 @@
 obj-$(CONFIG_MSM_IPC_ROUTER)+= ipc_socket.o
 obj-$(CONFIG_MSM_IPC_ROUTER_SECURITY)+= msm_ipc_router_security.o
 obj-$(CONFIG_MSM_QMI_INTERFACE) += msm_qmi_interface.o
+obj-$(CONFIG_MSM_TEST_QMI_CLIENT) += kernel_test_service_v01.o test_qmi_client.o
 obj-$(CONFIG_DEBUG_FS) += smd_rpc_sym.o
 obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter_servers.o
 obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter_clients.o
@@ -203,14 +212,7 @@
 endif
 obj-$(CONFIG_MSM_SYSMON_COMM) += sysmon.o
 
-ifdef CONFIG_CPU_IDLE
-	obj-$(CONFIG_ARCH_APQ8064) += cpuidle.o
-	obj-$(CONFIG_ARCH_MSM8960) += cpuidle.o
-	obj-$(CONFIG_ARCH_MSM8X60) += cpuidle.o
-	obj-$(CONFIG_ARCH_MSM9615) += cpuidle.o
-	obj-$(CONFIG_ARCH_MSM9625) += cpuidle.o
-	obj-$(CONFIG_ARCH_MSM8974) += cpuidle.o
-endif
+obj-$(CONFIG_CPU_IDLE) += cpuidle.o
 
 ifdef CONFIG_MSM_CAMERA_V4L2
 	obj-$(CONFIG_ARCH_MSM8X60) += board-msm8x60-camera.o
@@ -277,6 +279,7 @@
 obj-$(CONFIG_MACH_MSM8930_FLUID) += board-8930-all.o board-8930-regulator-pm8038.o board-8930-regulator-pm8917.o
 obj-$(CONFIG_PM8921_BMS) += bms-batterydata.o bms-batterydata-desay.o batterydata-lib.o
 obj-$(CONFIG_QPNP_BMS) += bms-batterydata.o bms-batterydata-desay.o batterydata-lib.o
+obj-$(CONFIG_QPNP_BMS) += bms-batterydata-oem.o
 obj-$(CONFIG_MACH_APQ8064_CDP) += board-8064-all.o board-8064-regulator.o
 obj-$(CONFIG_MACH_APQ8064_MTP) += board-8064-all.o board-8064-regulator.o
 obj-$(CONFIG_MACH_APQ8064_LIQUID) += board-8064-all.o board-8064-regulator.o
@@ -290,15 +293,17 @@
 obj-$(CONFIG_ARCH_MSM8974) += gdsc.o
 obj-$(CONFIG_ARCH_MSM9625) += gdsc.o
 obj-$(CONFIG_ARCH_MSM8226) += gdsc.o
-obj-$(CONFIG_ARCH_MSM8910) += gdsc.o
+obj-$(CONFIG_ARCH_MSM8610) += gdsc.o
 obj-$(CONFIG_ARCH_MSM8974) += krait-regulator.o
 obj-$(CONFIG_ARCH_MSM9625) += board-9625.o board-9625-gpiomux.o
-obj-$(CONFIG_ARCH_MSM9625) += clock-local2.o clock-pll.o clock-9625.o clock-rpm.o clock-voter.o acpuclock-9625.o
+obj-$(CONFIG_ARCH_MSM9625) += clock-local2.o clock-pll.o clock-9625.o clock-rpm.o clock-voter.o acpuclock-9625.o acpuclock-cortex.o
 obj-$(CONFIG_ARCH_MSM8930) += acpuclock-8930.o acpuclock-8627.o acpuclock-8930aa.o acpuclock-8930ab.o
 obj-$(CONFIG_ARCH_MPQ8092) += board-8092.o board-8092-gpiomux.o
 obj-$(CONFIG_ARCH_MSM8226) += board-8226.o board-8226-gpiomux.o
-obj-$(CONFIG_ARCH_MSM8910) += board-8910.o board-8910-gpiomux.o
-obj-$(CONFIG_ARCH_MSM8910) += clock-local2.o clock-pll.o clock-8910.o clock-rpm.o clock-voter.o
+obj-$(CONFIG_ARCH_MSM8226) += clock-local2.o clock-pll.o clock-8226.o clock-rpm.o clock-voter.o clock-mdss-8974.o
+obj-$(CONFIG_ARCH_MSM8226) += acpuclock-8226.o acpuclock-cortex.o
+obj-$(CONFIG_ARCH_MSM8610) += board-8610.o board-8610-gpiomux.o
+obj-$(CONFIG_ARCH_MSM8610) += clock-local2.o clock-pll.o clock-8610.o clock-rpm.o clock-voter.o
 
 obj-$(CONFIG_MACH_SAPPHIRE) += board-sapphire.o board-sapphire-gpio.o
 obj-$(CONFIG_MACH_SAPPHIRE) += board-sapphire-keypad.o board-sapphire-panel.o
@@ -316,17 +321,9 @@
 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
-ifdef CONFIG_MSM_RPM
-	obj-$(CONFIG_ARCH_APQ8064) += rpm_resources.o
-	obj-$(CONFIG_ARCH_MSM8960) += rpm_resources.o
-	obj-$(CONFIG_ARCH_MSM8X60) += rpm_resources.o
-	obj-$(CONFIG_ARCH_MSM9615) += rpm_resources.o
-endif
-ifdef CONFIG_MSM_RPM_SMD
-	obj-$(CONFIG_ARCH_MSM8974) += lpm_levels.o lpm_resources.o
-	obj-$(CONFIG_ARCH_MSM9625) += lpm_levels.o lpm_resources.o
-endif
+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 lpm_resources.o
 obj-$(CONFIG_MSM_MPM_OF) += mpm-of.o
 obj-$(CONFIG_MSM_MPM) += mpm.o
 obj-$(CONFIG_MSM_RPM_STATS_LOG) += rpm_stats.o rpm_master_stat.o
@@ -364,7 +361,7 @@
 obj-$(CONFIG_ARCH_MSM9625) += gpiomux-v2.o gpiomux.o
 obj-$(CONFIG_ARCH_MPQ8092) += gpiomux-v2.o gpiomux.o
 obj-$(CONFIG_ARCH_MSM8226) += gpiomux-v2.o gpiomux.o
-obj-$(CONFIG_ARCH_MSM8910) += gpiomux-v2.o gpiomux.o
+obj-$(CONFIG_ARCH_MSM8610) += gpiomux-v2.o gpiomux.o
 
 obj-$(CONFIG_MSM_SLEEP_STATS_DEVICE) += idle_stats_device.o
 obj-$(CONFIG_MSM_DCVS) += msm_dcvs_scm.o msm_dcvs.o msm_mpdecision.o
@@ -414,3 +411,5 @@
 
 obj-$(CONFIG_MSM_SMCMOD) += smcmod.o
 obj-$(CONFIG_MSM_CPU_PWRCTL) +=  msm_cpu_pwrctl.o
+
+obj-$(CONFIG_ARCH_MSM8974) += msm_mpmctr.o
diff --git a/arch/arm/mach-msm/Makefile.boot b/arch/arm/mach-msm/Makefile.boot
index e74d61a..f683b33 100644
--- a/arch/arm/mach-msm/Makefile.boot
+++ b/arch/arm/mach-msm/Makefile.boot
@@ -47,25 +47,36 @@
 
 # MSM8974
    zreladdr-$(CONFIG_ARCH_MSM8974)	:= 0x00008000
-        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-cdp.dtb
-        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-fluid.dtb
-        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-liquid.dtb
-        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-mtp.dtb
-        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-rumi.dtb
-        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-sim.dtb
+        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-v1-cdp.dtb
+        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-v1-fluid.dtb
+        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-v1-liquid.dtb
+        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-v1-mtp.dtb
+        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-v1-rumi.dtb
+        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-v1-sim.dtb
+        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-v2-cdp.dtb
+        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-v2-fluid.dtb
+        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-v2-liquid.dtb
+        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-v2-mtp.dtb
 
 # MSM9615
    zreladdr-$(CONFIG_ARCH_MSM9615)	:= 0x40808000
 
 # MSM9625
    zreladdr-$(CONFIG_ARCH_MSM9625)	:= 0x00208000
-        dtb-$(CONFIG_ARCH_MSM9625)	+= msm9625-cdp.dtb
-        dtb-$(CONFIG_ARCH_MSM9625)	+= msm9625-mtp.dtb
-        dtb-$(CONFIG_ARCH_MSM9625)	+= msm9625-rumi.dtb
+        dtb-$(CONFIG_ARCH_MSM9625)	+= msm9625-v1-cdp.dtb
+        dtb-$(CONFIG_ARCH_MSM9625)	+= msm9625-v1-mtp.dtb
+        dtb-$(CONFIG_ARCH_MSM9625)	+= msm9625-v1-rumi.dtb
+	dtb-$(CONFIG_ARCH_MSM9625)      += msm9625-v2-cdp.dtb
+	dtb-$(CONFIG_ARCH_MSM9625)      += msm9625-v2-mtp.dtb
+	dtb-$(CONFIG_ARCH_MSM9625)      += msm9625-v2-1-mtp.dtb
+	dtb-$(CONFIG_ARCH_MSM9625)      += msm9625-v2-1-cdp.dtb
 
 # MSM8226
-   zreladdr-$(CONFIG_ARCH_MSM8226)	:= 0x00008000
+   zreladdr-$(CONFIG_ARCH_MSM8226)	:= 0x00108000
         dtb-$(CONFIG_ARCH_MSM8226)	+= msm8226-sim.dtb
+        dtb-$(CONFIG_ARCH_MSM8226)	+= msm8226-cdp.dtb
+        dtb-$(CONFIG_ARCH_MSM8226)	+= msm8226-mtp.dtb
+        dtb-$(CONFIG_ARCH_MSM8226)	+= msm8226-qrd.dtb
 
 # FSM9XXX
    zreladdr-$(CONFIG_ARCH_FSM9XXX)	:= 0x10008000
@@ -75,7 +86,7 @@
 # MPQ8092
    zreladdr-$(CONFIG_ARCH_MPQ8092)	:= 0x00008000
 
-# MSM8910
-   zreladdr-$(CONFIG_ARCH_MSM8910)	:= 0x00008000
-        dtb-$(CONFIG_ARCH_MSM8910)	+= msm8910-rumi.dtb
-        dtb-$(CONFIG_ARCH_MSM8910)	+= msm8910-sim.dtb
+# MSM8610
+   zreladdr-$(CONFIG_ARCH_MSM8610)	:= 0x00108000
+        dtb-$(CONFIG_ARCH_MSM8610)	+= msm8610-rumi.dtb
+        dtb-$(CONFIG_ARCH_MSM8610)	+= msm8610-sim.dtb
diff --git a/arch/arm/mach-msm/acpuclock-7627.c b/arch/arm/mach-msm/acpuclock-7627.c
index 00b6458..d0b81b0 100644
--- a/arch/arm/mach-msm/acpuclock-7627.c
+++ b/arch/arm/mach-msm/acpuclock-7627.c
@@ -2,7 +2,7 @@
  * MSM architecture clock driver
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
  * Author: San Mehat <san@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/acpuclock-7x30.c b/arch/arm/mach-msm/acpuclock-7x30.c
index 5b947e6..9f24538 100644
--- a/arch/arm/mach-msm/acpuclock-7x30.c
+++ b/arch/arm/mach-msm/acpuclock-7x30.c
@@ -1,7 +1,7 @@
 /*
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/acpuclock-8064.c b/arch/arm/mach-msm/acpuclock-8064.c
index db77a34..a0727b7 100644
--- a/arch/arm/mach-msm/acpuclock-8064.c
+++ b/arch/arm/mach-msm/acpuclock-8064.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -122,7 +122,7 @@
 	[3]  = { {  540000, HFPLL, 2, 0x28 }, 1050000, 1050000, 2 },
 	[4]  = { {  594000, HFPLL, 1, 0x16 }, 1050000, 1050000, 2 },
 	[5]  = { {  648000, HFPLL, 1, 0x18 }, 1050000, 1050000, 4 },
-	[6]  = { {  702000, HFPLL, 1, 0x1A }, 1050000, 1050000, 4 },
+	[6]  = { {  702000, HFPLL, 1, 0x1A }, 1150000, 1150000, 4 },
 	[7]  = { {  756000, HFPLL, 1, 0x1C }, 1150000, 1150000, 4 },
 	[8]  = { {  810000, HFPLL, 1, 0x1E }, 1150000, 1150000, 4 },
 	[9]  = { {  864000, HFPLL, 1, 0x20 }, 1150000, 1150000, 4 },
@@ -137,18 +137,18 @@
 
 static struct acpu_level tbl_slow[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   950000 },
-	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(6),   975000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   975000 },
-	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(6),  1000000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),  1000000 },
-	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(6),  1025000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),  1025000 },
-	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(6),  1075000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),  1075000 },
-	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(6),  1100000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),  1100000 },
-	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(6),  1125000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),  1125000 },
+	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(5),   975000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   975000 },
+	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(5),  1000000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),  1000000 },
+	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(5),  1025000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),  1025000 },
+	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(5),  1075000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),  1075000 },
+	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(5),  1100000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),  1100000 },
+	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(5),  1125000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1125000 },
 	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1175000 },
 	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(15), 1200000 },
@@ -163,18 +163,18 @@
 
 static struct acpu_level tbl_nom[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   900000 },
-	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(6),   925000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   925000 },
-	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(6),   950000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   950000 },
-	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(6),   975000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   975000 },
-	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(6),  1025000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),  1025000 },
-	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(6),  1050000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),  1050000 },
-	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(6),  1075000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),  1075000 },
+	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(5),   925000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   925000 },
+	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(5),   950000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   950000 },
+	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(5),   975000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   975000 },
+	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(5),  1025000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),  1025000 },
+	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(5),  1050000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),  1050000 },
+	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(5),  1075000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1075000 },
 	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(15), 1125000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1125000 },
 	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(15), 1150000 },
@@ -189,18 +189,18 @@
 
 static struct acpu_level tbl_fast[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   850000 },
-	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(6),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   875000 },
-	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(6),   900000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   900000 },
-	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(6),   925000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   925000 },
-	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(6),   975000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   975000 },
-	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(6),  1000000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),  1000000 },
-	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(6),  1025000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),  1025000 },
+	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(5),   875000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
+	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(5),   900000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   900000 },
+	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(5),   925000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   925000 },
+	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(5),   975000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   975000 },
+	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(5),  1000000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),  1000000 },
+	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(5),  1025000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1025000 },
 	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(15), 1075000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1075000 },
 	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(15), 1100000 },
@@ -215,18 +215,18 @@
 
 static struct acpu_level tbl_faster[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   850000 },
-	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(6),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   875000 },
-	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(6),   900000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   900000 },
-	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(6),   925000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   925000 },
-	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(6),   962500 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   962500 },
-	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(6),   975000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),   975000 },
-	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(6),  1000000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),  1000000 },
+	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(5),   875000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
+	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(5),   900000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   900000 },
+	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(5),   925000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   925000 },
+	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(5),   962500 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   962500 },
+	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(5),   975000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   975000 },
+	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(5),  1000000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1000000 },
 	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(15), 1050000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1050000 },
 	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(15), 1075000 },
@@ -239,14 +239,126 @@
 	{ 0, { 0 } }
 };
 
+static struct acpu_level tbl_PVS0_1512MHz[] __initdata = {
+	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   950000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   950000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   950000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   962500 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),  1000000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),  1025000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1037500 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1075000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1087500 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1125000 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1150000 },
+	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(15), 1162500 },
+	{ 0, { 0 } }
+};
+
+static struct acpu_level tbl_PVS1_1512MHz[] __initdata = {
+	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   950000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   950000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   950000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   962500 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   975000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),  1000000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1012500 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1037500 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1050000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1087500 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1112500 },
+	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(15), 1125000 },
+	{ 0, { 0 } }
+};
+
+static struct acpu_level tbl_PVS2_1512MHz[] __initdata = {
+	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   925000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   925000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   925000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   925000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   937500 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   950000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   975000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1000000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1012500 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1037500 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1075000 },
+	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(15), 1087500 },
+	{ 0, { 0 } }
+};
+
+static struct acpu_level tbl_PVS3_1512MHz[] __initdata = {
+	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   900000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   900000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   900000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   900000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   900000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   925000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   950000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  975000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  987500 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1000000 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1037500 },
+	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(15), 1050000 },
+	{ 0, { 0 } }
+};
+
+static struct acpu_level tbl_PVS4_1512MHz[] __initdata = {
+	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   875000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   875000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  950000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  962500 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15),  975000 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1000000 },
+	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(15), 1012500 },
+	{ 0, { 0 } }
+};
+
+static struct acpu_level tbl_PVS5_1512MHz[] __initdata = {
+	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   875000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   875000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  937500 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  950000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15),  962500 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15),  987500 },
+	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(15), 1000000 },
+	{ 0, { 0 } }
+};
+
+static struct acpu_level tbl_PVS6_1512MHz[] __initdata = {
+	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   875000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   875000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  937500 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  950000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15),  962500 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15),  975000 },
+	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(15),  987500 },
+	{ 0, { 0 } }
+};
+
 static struct acpu_level tbl_PVS0_1700MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   950000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   950000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   950000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   962500 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),  1000000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),  1025000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),  1037500 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   950000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   950000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   962500 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),  1000000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),  1025000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1037500 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1075000 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1087500 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1125000 },
@@ -259,12 +371,12 @@
 
 static struct acpu_level tbl_PVS1_1700MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   950000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   950000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   950000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   962500 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   975000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),  1000000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),  1012500 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   950000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   950000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   962500 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   975000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),  1000000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1012500 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1037500 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1050000 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1087500 },
@@ -277,12 +389,12 @@
 
 static struct acpu_level tbl_PVS2_1700MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   925000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   925000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   925000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   925000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   937500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),   950000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),   975000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   925000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   925000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   925000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   937500 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   950000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   975000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1000000 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1012500 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1037500 },
@@ -295,12 +407,12 @@
 
 static struct acpu_level tbl_PVS3_1700MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   900000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   900000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   900000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   900000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   900000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),   925000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),   950000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   900000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   900000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   900000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   900000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   925000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   950000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  975000 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  987500 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1000000 },
@@ -313,12 +425,12 @@
 
 static struct acpu_level tbl_PVS4_1700MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   875000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   875000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   875000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   887500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),   900000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),   925000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   875000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   875000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  950000 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  962500 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15),  975000 },
@@ -331,12 +443,12 @@
 
 static struct acpu_level tbl_PVS5_1700MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   875000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   875000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   875000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   887500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),   900000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),   925000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   875000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   875000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  937500 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  950000 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15),  962500 },
@@ -349,12 +461,12 @@
 
 static struct acpu_level tbl_PVS6_1700MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   875000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   875000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   875000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   887500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),   900000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),   925000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   875000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   875000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  937500 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  950000 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15),  962500 },
@@ -367,12 +479,12 @@
 
 static struct acpu_level tbl_PVS0_2000MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   950000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   950000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   950000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   950000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   962500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),   975000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),  1000000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   950000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   950000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   950000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   962500 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   975000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1000000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1025000 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1037500 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1062500 },
@@ -386,12 +498,12 @@
 
 static struct acpu_level tbl_PVS1_2000MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   925000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   925000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   925000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   925000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   937500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),   950000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),   975000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   925000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   925000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   925000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   937500 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   950000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   975000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1000000 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1012500 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1037500 },
@@ -405,12 +517,12 @@
 
 static struct acpu_level tbl_PVS2_2000MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   900000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   900000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   900000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   900000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   912500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),   925000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),   950000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   900000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   900000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   900000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   912500 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   925000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   950000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  975000 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  987500 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1012500 },
@@ -424,12 +536,12 @@
 
 static struct acpu_level tbl_PVS3_2000MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   900000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   900000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   900000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   900000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   900000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),   912500 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),   937500 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   900000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   900000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   900000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   900000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   912500 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   937500 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  962500 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  975000 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1000000 },
@@ -443,12 +555,12 @@
 
 static struct acpu_level tbl_PVS4_2000MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   875000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   875000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   875000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   887500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),   900000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),   925000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   875000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   875000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  950000 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  962500 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15),  975000 },
@@ -462,12 +574,12 @@
 
 static struct acpu_level tbl_PVS5_2000MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   875000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   875000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   875000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   887500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),   900000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),   925000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   875000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   875000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  937500 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  950000 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15),  962500 },
@@ -481,12 +593,12 @@
 
 static struct acpu_level tbl_PVS6_2000MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   875000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   875000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   875000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   887500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),   900000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),   925000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   875000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   875000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  937500 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  950000 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15),  962500 },
@@ -519,6 +631,14 @@
 	[2][4] = { tbl_PVS4_2000MHz, sizeof(tbl_PVS4_2000MHz),     25000 },
 	[2][5] = { tbl_PVS5_2000MHz, sizeof(tbl_PVS5_2000MHz),     25000 },
 	[2][6] = { tbl_PVS6_2000MHz, sizeof(tbl_PVS6_2000MHz),     25000 },
+
+	[14][0] = { tbl_PVS0_1512MHz, sizeof(tbl_PVS0_1512MHz),     0 },
+	[14][1] = { tbl_PVS1_1512MHz, sizeof(tbl_PVS1_1512MHz),     25000 },
+	[14][2] = { tbl_PVS2_1512MHz, sizeof(tbl_PVS2_1512MHz),     25000 },
+	[14][3] = { tbl_PVS3_1512MHz, sizeof(tbl_PVS3_1512MHz),     25000 },
+	[14][4] = { tbl_PVS4_1512MHz, sizeof(tbl_PVS4_1512MHz),     25000 },
+	[14][5] = { tbl_PVS5_1512MHz, sizeof(tbl_PVS5_1512MHz),     25000 },
+	[14][6] = { tbl_PVS6_1512MHz, sizeof(tbl_PVS6_1512MHz),     25000 },
 };
 
 static struct acpuclk_krait_params acpuclk_8064_params __initdata = {
@@ -530,6 +650,7 @@
 	.l2_freq_tbl_size = sizeof(l2_freq_tbl),
 	.bus_scale = &bus_scale_data,
 	.pte_efuse_phys = 0x007000C0,
+	.get_bin_info = get_krait_bin_format_a,
 	.stby_khz = 384000,
 };
 
diff --git a/arch/arm/mach-msm/acpuclock-8226.c b/arch/arm/mach-msm/acpuclock-8226.c
new file mode 100644
index 0000000..8ba1b39
--- /dev/null
+++ b/arch/arm/mach-msm/acpuclock-8226.c
@@ -0,0 +1,133 @@
+/*
+ * 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) "%s: " fmt, __func__
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+
+#include <mach/clk-provider.h>
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
+#include <mach/rpm-regulator-smd.h>
+
+#include "acpuclock-cortex.h"
+
+#define RCG_CONFIG_UPDATE_BIT		BIT(0)
+
+static struct msm_bus_paths bw_level_tbl[] = {
+	[0] =  BW_MBPS(152), /* At least 19 MHz on bus. */
+	[1] =  BW_MBPS(300), /* At least 37.5 MHz on bus. */
+	[2] =  BW_MBPS(400), /* At least 50 MHz on bus. */
+	[3] =  BW_MBPS(800), /* At least 100 MHz on bus. */
+	[4] = BW_MBPS(1600), /* At least 200 MHz on bus. */
+	[5] = BW_MBPS(2128), /* At least 266 MHz on bus. */
+	[6] = BW_MBPS(3200), /* At least 400 MHz on bus. */
+	[7] = BW_MBPS(4264), /* At least 533 MHz on bus. */
+};
+
+static struct msm_bus_scale_pdata bus_client_pdata = {
+	.usecase = bw_level_tbl,
+	.num_usecases = ARRAY_SIZE(bw_level_tbl),
+	.active_only = 1,
+	.name = "acpuclock",
+};
+
+/* TODO:
+ * 1) Update MX voltage when data is avaiable
+ * 2) Update bus bandwidth
+ * 3) Depending on Frodo version, may need minimum of LVL_NOM
+ */
+static struct clkctl_acpu_speed acpu_freq_tbl[] = {
+	{ 0,   19200, CXO,     0, 0,   1150000,   1150000, 0 },
+	{ 1,  300000, PLL0,    4, 2,   1150000,   1150000, 4 },
+	{ 1,  384000, ACPUPLL, 5, 0,   1150000,   1150000, 4 },
+	{ 1,  600000, PLL0,    4, 0,   1150000,   1150000, 6 },
+	{ 1,  787200, ACPUPLL, 5, 0,   1150000,   1150000, 6 },
+	{ 0,  998400, ACPUPLL, 5, 0,   1150000,   1150000, 7 },
+	{ 0, 1190400, ACPUPLL, 5, 0,   1150000,   1150000, 7 },
+	{ 0 }
+};
+
+static struct acpuclk_drv_data drv_data = {
+	.freq_tbl = acpu_freq_tbl,
+	.current_speed = &(struct clkctl_acpu_speed){ 0 },
+	.bus_scale = &bus_client_pdata,
+	/* FIXME regulator doesn't support corners yet */
+	.vdd_max_cpu = 1150000,
+	.vdd_max_mem = 1150000,
+	.src_clocks = {
+		[PLL0].name = "gpll0",
+		[ACPUPLL].name = "a7sspll",
+	},
+	.reg_data = {
+		.cfg_src_mask = BM(10, 8),
+		.cfg_src_shift = 8,
+		.cfg_div_mask = BM(4, 0),
+		.cfg_div_shift = 0,
+		.update_mask = RCG_CONFIG_UPDATE_BIT,
+		.poll_mask = RCG_CONFIG_UPDATE_BIT,
+	},
+};
+
+static int __init acpuclk_a7_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rcg_base");
+	if (!res)
+		return -EINVAL;
+
+	drv_data.apcs_rcg_cmd = ioremap(res->start, resource_size(res));
+	if (!drv_data.apcs_rcg_cmd)
+		return -ENOMEM;
+
+	drv_data.apcs_rcg_config = drv_data.apcs_rcg_cmd + 4;
+
+	drv_data.vdd_cpu = regulator_get(&pdev->dev, "a7_cpu");
+	if (IS_ERR(drv_data.vdd_cpu)) {
+		dev_err(&pdev->dev, "regulator for %s get failed\n", "a7_cpu");
+		return PTR_ERR(drv_data.vdd_cpu);
+	}
+
+	drv_data.vdd_mem = regulator_get(&pdev->dev, "a7_mem");
+	if (IS_ERR(drv_data.vdd_mem)) {
+		dev_err(&pdev->dev, "regulator for %s get failed\n", "a7_mem");
+		return PTR_ERR(drv_data.vdd_mem);
+	}
+
+	return acpuclk_cortex_init(pdev, &drv_data);
+}
+
+static struct of_device_id acpuclk_a7_match_table[] = {
+	{.compatible = "qcom,acpuclk-a7"},
+	{}
+};
+
+static struct platform_driver acpuclk_a7_driver = {
+	.driver = {
+		.name = "acpuclk-a7",
+		.of_match_table = acpuclk_a7_match_table,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init acpuclk_a7_init(void)
+{
+	return platform_driver_probe(&acpuclk_a7_driver, acpuclk_a7_probe);
+}
+device_initcall(acpuclk_a7_init);
diff --git a/arch/arm/mach-msm/acpuclock-8625q.c b/arch/arm/mach-msm/acpuclock-8625q.c
index 0a6dfbe..80cb0ae 100644
--- a/arch/arm/mach-msm/acpuclock-8625q.c
+++ b/arch/arm/mach-msm/acpuclock-8625q.c
@@ -121,7 +121,11 @@
 # define DELTA_LEVEL_2_UV 75000
 # define DELTA_LEVEL_3_UV 150000
 
-
+/*
+ * The default initialization is according to the requirements of
+ * SKUD_prime. If the target is quad core, we reinitialize this table using
+ * the reinitalize_freq_table() function.
+ */
 static struct clkctl_acpu_speed acpu_freq_tbl_cmn[] = {
 	{ 0, 19200, ACPU_PLL_TCXO, 0, 0, 2400, 3, 0, 30720 },
 	{ 1, 245760, ACPU_PLL_1, 1, 0, 30720, 3, MAX_NOMINAL_VOLTAGE, 61440 },
@@ -552,11 +556,40 @@
 		return 0;
 }
 
+static int reinitialize_freq_table(bool target_select)
+{
+	/*
+	 * target_flag is set only if it is a Quad core chip,
+	 * In that case, we modify the initialization
+	 * of the table according to the specific requirement
+	 * for this target. Otherwise the default initialized table is
+	 * used for SKUD_prime.
+	 */
+	if (target_select) {
+		struct clkctl_acpu_speed *tbl;
+		for (tbl = acpu_freq_tbl; tbl->a11clk_khz; tbl++) {
+
+			if (tbl->a11clk_khz >= 1008000) {
+				tbl->axiclk_khz = 300000;
+				if (tbl->a11clk_khz == 1209600)
+					tbl->vdd = 0;
+			} else {
+				if (tbl->a11clk_khz != 600000
+					&& tbl->a11clk_khz != 19200)
+					tbl->vdd = 1050000;
+				if (tbl->a11clk_khz == 700800)
+					tbl->axiclk_khz = 245000;
+			}
+		}
+
+	}
+	return 0;
+}
+
 #define MHZ 1000000
 
 static void __devinit select_freq_plan(unsigned int pvs_voltage,
-					unsigned int nominal_vol_uv,
-					unsigned int default_vol_uv)
+							bool target_sel)
 {
 	unsigned long pll_mhz[ACPU_PLL_END];
 	int i;
@@ -617,6 +650,8 @@
 		}
 	}
 
+	reinitialize_freq_table(target_sel);
+
 	/*
 	 *PVS Voltage calculation  formula
 	 *1.4 Ghz device
@@ -630,8 +665,6 @@
 	*/
 	for (tbl = acpu_freq_tbl; tbl->a11clk_khz; tbl++) {
 		if (tbl->a11clk_khz >= 1008000) {
-			if (tbl->a11clk_khz == 1209600)
-				tbl->vdd = default_vol_uv;
 			/*
 			 * Change voltage as per PVS formula,
 			 * i is initialized above with 2 or 1
@@ -643,9 +676,7 @@
 
 			tbl->vdd = max((int)(pvs_voltage - delta[i]), tbl->vdd);
 			i--;
-		} else if (tbl->a11clk_khz != 600000
-					&& tbl->a11clk_khz != 19200)
-			tbl->vdd = nominal_vol_uv;
+		}
 	}
 
 
@@ -729,8 +760,7 @@
 {
 	const struct acpuclk_pdata_8625q *pdata = pdev->dev.platform_data;
 	unsigned int pvs_voltage = pdata->pvs_voltage_uv;
-	unsigned int nom_vol_uv = pdata->nominal_voltage;
-	unsigned int default_vol_uv = pdata->default_turbo_voltage;
+	bool target_sel = pdata->flag;
 
 	drv_state.max_speed_delta_khz = pdata->acpu_clk_data->
 						max_speed_delta_khz;
@@ -739,7 +769,7 @@
 	BUG_ON(IS_ERR(drv_state.ebi1_clk));
 
 	mutex_init(&drv_state.lock);
-	select_freq_plan(pvs_voltage, nom_vol_uv, default_vol_uv);
+	select_freq_plan(pvs_voltage, target_sel);
 	acpuclk_8625q_data.wait_for_irq_khz = find_wait_for_irq_khz();
 
 	if (acpuclk_hw_init() < 0)
diff --git a/arch/arm/mach-msm/acpuclock-8625q.h b/arch/arm/mach-msm/acpuclock-8625q.h
index c91e3bd..ced2f70 100644
--- a/arch/arm/mach-msm/acpuclock-8625q.h
+++ b/arch/arm/mach-msm/acpuclock-8625q.h
@@ -23,8 +23,7 @@
 struct acpuclk_pdata_8625q {
 	struct acpuclk_pdata *acpu_clk_data;
 	unsigned int pvs_voltage_uv;
-	unsigned int nominal_voltage;
-	unsigned int default_turbo_voltage;
+	bool flag;
 };
 
 #endif /* __ARCH_ARM_MACH_MSM_ACPUCLOCK_8625Q_H */
diff --git a/arch/arm/mach-msm/acpuclock-8627.c b/arch/arm/mach-msm/acpuclock-8627.c
index ac29cac..405b26b 100644
--- a/arch/arm/mach-msm/acpuclock-8627.c
+++ b/arch/arm/mach-msm/acpuclock-8627.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -142,6 +142,7 @@
 	.l2_freq_tbl_size = sizeof(l2_freq_tbl),
 	.bus_scale = &bus_scale_data,
 	.pte_efuse_phys = 0x007000C0,
+	.get_bin_info = get_krait_bin_format_a,
 	.stby_khz = 384000,
 };
 
diff --git a/arch/arm/mach-msm/acpuclock-8930.c b/arch/arm/mach-msm/acpuclock-8930.c
index 948ecdd..e29d6fe 100644
--- a/arch/arm/mach-msm/acpuclock-8930.c
+++ b/arch/arm/mach-msm/acpuclock-8930.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -54,7 +54,7 @@
 		.l2cpmr_iaddr = 0x4501,
 		.vreg[VREG_CORE] = { "krait0", 1300000 },
 		.vreg[VREG_MEM]  = { "krait0_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait0_dig", 1150000 },
+		.vreg[VREG_DIG]  = { "krait0_dig", LVL_HIGH},
 		.vreg[VREG_HFPLL_A] = { "krait0_s8", 2050000 },
 		.vreg[VREG_HFPLL_B] = { "krait0_l23", 1800000 },
 	},
@@ -66,7 +66,7 @@
 		.l2cpmr_iaddr = 0x5501,
 		.vreg[VREG_CORE] = { "krait1", 1300000 },
 		.vreg[VREG_MEM]  = { "krait1_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait1_dig", 1150000 },
+		.vreg[VREG_DIG]  = { "krait1_dig", LVL_HIGH},
 		.vreg[VREG_HFPLL_A] = { "krait1_s8", 2050000 },
 		.vreg[VREG_HFPLL_B] = { "krait1_l23", 1800000 },
 	},
@@ -90,7 +90,7 @@
 		.l2cpmr_iaddr = 0x4501,
 		.vreg[VREG_CORE] = { "krait0", 1300000 },
 		.vreg[VREG_MEM]  = { "krait0_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait0_dig", 1150000 },
+		.vreg[VREG_DIG]  = { "krait0_dig", LVL_HIGH},
 		.vreg[VREG_HFPLL_A] = { "krait0_hfpll", 1800000 },
 	},
 	[CPU1] = {
@@ -101,7 +101,7 @@
 		.l2cpmr_iaddr = 0x5501,
 		.vreg[VREG_CORE] = { "krait1", 1300000 },
 		.vreg[VREG_MEM]  = { "krait1_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait1_dig", 1150000 },
+		.vreg[VREG_DIG]  = { "krait1_dig", LVL_HIGH},
 		.vreg[VREG_HFPLL_A] = { "krait1_hfpll", 1800000 },
 	},
 	[L2] = {
@@ -132,9 +132,8 @@
 	.name = "acpuclk-8930",
 };
 
-/* TODO: Update vdd_dig, vdd_mem and bw when data is available. */
 static struct l2_level l2_freq_tbl[] __initdata = {
-	[0]  = { {  384000, PLL_8, 0, 0x00 },  LVL_NOM, 1050000, 1 },
+	[0]  = { {  384000, PLL_8, 0, 0x00 },  LVL_LOW, 1050000, 1 },
 	[1]  = { {  432000, HFPLL, 2, 0x20 },  LVL_NOM, 1050000, 2 },
 	[2]  = { {  486000, HFPLL, 2, 0x24 },  LVL_NOM, 1050000, 2 },
 	[3]  = { {  540000, HFPLL, 2, 0x28 },  LVL_NOM, 1050000, 2 },
@@ -228,6 +227,7 @@
 	.l2_freq_tbl_size = sizeof(l2_freq_tbl),
 	.bus_scale = &bus_scale_data,
 	.pte_efuse_phys = 0x007000C0,
+	.get_bin_info = get_krait_bin_format_a,
 	.stby_khz = 384000,
 };
 
diff --git a/arch/arm/mach-msm/acpuclock-8930aa.c b/arch/arm/mach-msm/acpuclock-8930aa.c
index 8d48b54..c824323 100644
--- a/arch/arm/mach-msm/acpuclock-8930aa.c
+++ b/arch/arm/mach-msm/acpuclock-8930aa.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -54,7 +54,7 @@
 		.l2cpmr_iaddr = 0x4501,
 		.vreg[VREG_CORE] = { "krait0", 1300000 },
 		.vreg[VREG_MEM]  = { "krait0_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait0_dig", 1150000 },
+		.vreg[VREG_DIG]  = { "krait0_dig", LVL_HIGH},
 		.vreg[VREG_HFPLL_A] = { "krait0_hfpll", 1800000 },
 	},
 	[CPU1] = {
@@ -65,7 +65,7 @@
 		.l2cpmr_iaddr = 0x5501,
 		.vreg[VREG_CORE] = { "krait1", 1300000 },
 		.vreg[VREG_MEM]  = { "krait1_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait1_dig", 1150000 },
+		.vreg[VREG_DIG]  = { "krait1_dig", LVL_HIGH},
 		.vreg[VREG_HFPLL_A] = { "krait1_hfpll", 1800000 },
 	},
 	[L2] = {
@@ -96,9 +96,8 @@
 	.name = "acpuclk-8930aa",
 };
 
-/* TODO: Update vdd_dig, vdd_mem and bw when data is available. */
 static struct l2_level l2_freq_tbl[] __initdata = {
-	[0]  = { {  384000, PLL_8, 0, 0x00 },  LVL_NOM, 1050000, 1 },
+	[0]  = { {  384000, PLL_8, 0, 0x00 },  LVL_LOW, 1050000, 1 },
 	[1]  = { {  432000, HFPLL, 2, 0x20 },  LVL_NOM, 1050000, 2 },
 	[2]  = { {  486000, HFPLL, 2, 0x24 },  LVL_NOM, 1050000, 2 },
 	[3]  = { {  540000, HFPLL, 2, 0x28 },  LVL_NOM, 1050000, 2 },
@@ -204,6 +203,7 @@
 	.l2_freq_tbl_size = sizeof(l2_freq_tbl),
 	.bus_scale = &bus_scale_data,
 	.pte_efuse_phys = 0x007000C0,
+	.get_bin_info = get_krait_bin_format_a,
 	.stby_khz = 384000,
 };
 
diff --git a/arch/arm/mach-msm/acpuclock-8930ab.c b/arch/arm/mach-msm/acpuclock-8930ab.c
index 5003862..7ec267b 100644
--- a/arch/arm/mach-msm/acpuclock-8930ab.c
+++ b/arch/arm/mach-msm/acpuclock-8930ab.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -54,7 +54,7 @@
 		.l2cpmr_iaddr = 0x4501,
 		.vreg[VREG_CORE] = { "krait0", 1300000 },
 		.vreg[VREG_MEM]  = { "krait0_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait0_dig", 1150000 },
+		.vreg[VREG_DIG]  = { "krait0_dig", LVL_HIGH},
 		.vreg[VREG_HFPLL_A] = { "krait0_s8", 2050000 },
 		.vreg[VREG_HFPLL_B] = { "krait0_l23", 1800000 },
 	},
@@ -66,7 +66,7 @@
 		.l2cpmr_iaddr = 0x5501,
 		.vreg[VREG_CORE] = { "krait1", 1300000 },
 		.vreg[VREG_MEM]  = { "krait1_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait1_dig", 1150000 },
+		.vreg[VREG_DIG]  = { "krait1_dig", LVL_HIGH},
 		.vreg[VREG_HFPLL_A] = { "krait1_s8", 2050000 },
 		.vreg[VREG_HFPLL_B] = { "krait1_l23", 1800000 },
 	},
@@ -90,7 +90,7 @@
 		.l2cpmr_iaddr = 0x4501,
 		.vreg[VREG_CORE] = { "krait0", 1300000 },
 		.vreg[VREG_MEM]  = { "krait0_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait0_dig", 1150000 },
+		.vreg[VREG_DIG]  = { "krait0_dig", LVL_HIGH},
 		.vreg[VREG_HFPLL_A] = { "krait0_hfpll", 1800000 },
 	},
 	[CPU1] = {
@@ -101,7 +101,7 @@
 		.l2cpmr_iaddr = 0x5501,
 		.vreg[VREG_CORE] = { "krait1", 1300000 },
 		.vreg[VREG_MEM]  = { "krait1_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait1_dig", 1150000 },
+		.vreg[VREG_DIG]  = { "krait1_dig", LVL_HIGH},
 		.vreg[VREG_HFPLL_A] = { "krait1_hfpll", 1800000 },
 	},
 	[L2] = {
@@ -130,9 +130,8 @@
 	.name = "acpuclk-8930ab",
 };
 
-/* TODO: Update new L2 freqs once they are available */
 static struct l2_level l2_freq_tbl[] __initdata = {
-	[0]  = { {  384000, PLL_8, 0, 0x00 },  LVL_NOM, 1050000, 1 },
+	[0]  = { {  384000, PLL_8, 0, 0x00 },  LVL_LOW, 1050000, 1 },
 	[1]  = { {  432000, HFPLL, 2, 0x20 },  LVL_NOM, 1050000, 2 },
 	[2]  = { {  486000, HFPLL, 2, 0x24 },  LVL_NOM, 1050000, 2 },
 	[3]  = { {  540000, HFPLL, 2, 0x28 },  LVL_NOM, 1050000, 2 },
@@ -151,101 +150,140 @@
 	{ }
 };
 
-static struct acpu_level acpu_freq_tbl_slow[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   950000 },
-	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(5),   975000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   975000 },
-	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(5),  1000000 },
+static struct acpu_level tbl_PVS0_1700MHz[] __initdata = {
+	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),  1000000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),  1000000 },
 	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),  1000000 },
-	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(5),  1025000 },
 	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),  1025000 },
-	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(10), 1075000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10), 1075000 },
-	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(10), 1100000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10), 1100000 },
-	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(10), 1125000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10), 1125000 },
-	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1175000 },
-	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(15), 1200000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1200000 },
-	{ 0, {  1296000, HFPLL, 1, 0x30 }, L2(15), 1225000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1225000 },
-	{ 0, {  1404000, HFPLL, 1, 0x34 }, L2(15), 1237500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1237500 },
-	{ 0, {  1512000, HFPLL, 1, 0x38 }, L2(15), 1250000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1250000 },
-	{ 0, {  1620000, HFPLL, 1, 0x3C }, L2(15), 1262500 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1262500 },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1287500 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10), 1050000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10), 1075000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10), 1100000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1125000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1150000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1175000 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1200000 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1225000 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1250000 },
+	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1275000 },
 	{ 0, { 0 } }
 };
 
-static struct acpu_level acpu_freq_tbl_nom[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   950000 },
-	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(5),   975000 },
+static struct acpu_level tbl_PVS1_1700MHz[] __initdata = {
+	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   975000 },
 	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   975000 },
-	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(5),  1000000 },
 	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),  1000000 },
-	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(5),  1025000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),  1025000 },
-	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(10), 1075000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10), 1075000 },
-	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(10), 1100000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10), 1100000 },
-	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(10), 1125000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10), 1125000 },
-	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1175000 },
-	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(15), 1200000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1200000 },
-	{ 0, {  1296000, HFPLL, 1, 0x30 }, L2(15), 1225000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1225000 },
-	{ 0, {  1404000, HFPLL, 1, 0x34 }, L2(15), 1237500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1237500 },
-	{ 0, {  1512000, HFPLL, 1, 0x38 }, L2(15), 1250000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1250000 },
-	{ 0, {  1620000, HFPLL, 1, 0x3C }, L2(15), 1262500 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1262500 },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1287500 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),  1000000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10), 1025000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10), 1050000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10), 1075000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1100000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1125000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1150000 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1175000 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1200000 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1225000 },
+	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1250000 },
 	{ 0, { 0 } }
 };
 
-static struct acpu_level acpu_freq_tbl_fast[] __initdata = {
+static struct acpu_level tbl_PVS2_1700MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   950000 },
-	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(5),   975000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   975000 },
-	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(5),  1000000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),  1000000 },
-	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(5),  1025000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),  1025000 },
-	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(10), 1075000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10), 1075000 },
-	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(10), 1100000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10), 1100000 },
-	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(10), 1125000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10), 1125000 },
-	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1175000 },
-	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(15), 1200000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1200000 },
-	{ 0, {  1296000, HFPLL, 1, 0x30 }, L2(15), 1225000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1225000 },
-	{ 0, {  1404000, HFPLL, 1, 0x34 }, L2(15), 1237500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1237500 },
-	{ 0, {  1512000, HFPLL, 1, 0x38 }, L2(15), 1250000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1250000 },
-	{ 0, {  1620000, HFPLL, 1, 0x3C }, L2(15), 1262500 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1262500 },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1287500 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   950000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   950000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   975000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10), 1000000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10), 1025000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10), 1050000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1075000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1100000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1125000 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1150000 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1175000 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1200000 },
+	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1225000 },
 	{ 0, { 0 } }
 };
 
-/* TODO: Update boost voltage once the pvs data is available */
+static struct acpu_level tbl_PVS3_1700MHz[] __initdata = {
+	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   925000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   925000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   925000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   950000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10),  975000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10), 1000000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10), 1025000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1050000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1075000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1100000 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1125000 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1150000 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1175000 },
+	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1200000 },
+	{ 0, { 0 } }
+};
+
+static struct acpu_level tbl_PVS4_1700MHz[] __initdata = {
+	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   925000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   925000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   925000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   925000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10),  950000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10),  975000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10), 1000000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1025000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1050000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1075000 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1100000 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1125000 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1150000 },
+	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1175000 },
+	{ 0, { 0 } }
+};
+
+static struct acpu_level tbl_PVS5_1700MHz[] __initdata = {
+	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   900000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   900000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   900000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   900000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10),  925000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10),  950000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10),  975000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1000000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1025000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1050000 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1075000 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1100000 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1125000 },
+	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1150000 },
+	{ 0, { 0 } }
+};
+
+static struct acpu_level tbl_PVS6_1700MHz[] __initdata = {
+	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   875000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   875000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10),  900000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10),  925000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10),  950000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  975000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1000000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1025000 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1050000 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1075000 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1100000 },
+	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1125000 },
+	{ 0, { 0 } }
+};
+
 static struct pvs_table pvs_tables[NUM_SPEED_BINS][NUM_PVS] __initdata = {
-[0][PVS_SLOW]    = { acpu_freq_tbl_slow, sizeof(acpu_freq_tbl_slow), 0 },
-[0][PVS_NOMINAL] = { acpu_freq_tbl_nom,  sizeof(acpu_freq_tbl_nom),  25000 },
-[0][PVS_FAST]    = { acpu_freq_tbl_fast, sizeof(acpu_freq_tbl_fast), 25000 },
+	[0][0] = { tbl_PVS0_1700MHz, sizeof(tbl_PVS0_1700MHz), 0 },
+	[0][1] = { tbl_PVS1_1700MHz, sizeof(tbl_PVS1_1700MHz), 25000 },
+	[0][2] = { tbl_PVS2_1700MHz, sizeof(tbl_PVS2_1700MHz), 25000 },
+	[0][3] = { tbl_PVS3_1700MHz, sizeof(tbl_PVS3_1700MHz), 25000 },
+	[0][4] = { tbl_PVS4_1700MHz, sizeof(tbl_PVS4_1700MHz), 25000 },
+	[0][5] = { tbl_PVS5_1700MHz, sizeof(tbl_PVS5_1700MHz), 25000 },
+	[0][6] = { tbl_PVS6_1700MHz, sizeof(tbl_PVS6_1700MHz), 25000 },
 };
 
 static struct acpuclk_krait_params acpuclk_8930ab_params __initdata = {
@@ -257,6 +295,7 @@
 	.l2_freq_tbl_size = sizeof(l2_freq_tbl),
 	.bus_scale = &bus_scale_data,
 	.pte_efuse_phys = 0x007000C0,
+	.get_bin_info = get_krait_bin_format_a,
 	.stby_khz = 384000,
 };
 
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index d7d3edd..317729f 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -210,6 +210,7 @@
 	.l2_freq_tbl_size = sizeof(l2_freq_tbl),
 	.bus_scale = &bus_scale_data,
 	.pte_efuse_phys = 0x007000C0,
+	.get_bin_info = get_krait_bin_format_a,
 	.stby_khz = 384000,
 };
 
diff --git a/arch/arm/mach-msm/acpuclock-8960ab.c b/arch/arm/mach-msm/acpuclock-8960ab.c
index d2e88fb..38658a2 100644
--- a/arch/arm/mach-msm/acpuclock-8960ab.c
+++ b/arch/arm/mach-msm/acpuclock-8960ab.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -252,6 +252,7 @@
 	.l2_freq_tbl_size = sizeof(l2_freq_tbl),
 	.bus_scale = &bus_scale_data,
 	.pte_efuse_phys = 0x007000C0,
+	.get_bin_info = get_krait_bin_format_a,
 	.stby_khz = 384000,
 };
 
diff --git a/arch/arm/mach-msm/acpuclock-8974.c b/arch/arm/mach-msm/acpuclock-8974.c
index f929943..5211c6e 100644
--- a/arch/arm/mach-msm/acpuclock-8974.c
+++ b/arch/arm/mach-msm/acpuclock-8974.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. 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
@@ -112,83 +112,219 @@
 };
 
 static struct l2_level l2_freq_tbl[] __initdata = {
-	[0]  = { {  300000, PLL_0, 0,   0 }, LVL_LOW,  1050000, 0 },
-	[1]  = { {  345600, HFPLL, 2,  36 }, LVL_NOM,  1050000, 1 },
-	[2]  = { {  422400, HFPLL, 2,  44 }, LVL_NOM,  1050000, 1 },
-	[3]  = { {  499200, HFPLL, 2,  52 }, LVL_NOM,  1050000, 2 },
-	[4]  = { {  576000, HFPLL, 1,  30 }, LVL_NOM,  1050000, 2 },
-	[5]  = { {  652800, HFPLL, 1,  34 }, LVL_NOM,  1050000, 3 },
-	[6]  = { {  729600, HFPLL, 1,  38 }, LVL_NOM,  1050000, 3 },
-	[7]  = { {  806400, HFPLL, 1,  42 }, LVL_NOM,  1050000, 3 },
+	[0]  = { {  300000, PLL_0, 0,   0 }, LVL_LOW,   950000, 0 },
+	[1]  = { {  345600, HFPLL, 2,  36 }, LVL_NOM,   950000, 1 },
+	[2]  = { {  422400, HFPLL, 2,  44 }, LVL_NOM,   950000, 1 },
+	[3]  = { {  499200, HFPLL, 2,  52 }, LVL_NOM,   950000, 2 },
+	[4]  = { {  576000, HFPLL, 1,  30 }, LVL_NOM,   950000, 3 },
+	[5]  = { {  652800, HFPLL, 1,  34 }, LVL_NOM,   950000, 3 },
+	[6]  = { {  729600, HFPLL, 1,  38 }, LVL_NOM,   950000, 3 },
+	[7]  = { {  806400, HFPLL, 1,  42 }, LVL_HIGH, 1050000, 4 },
 	[8]  = { {  883200, HFPLL, 1,  46 }, LVL_HIGH, 1050000, 4 },
 	[9]  = { {  960000, HFPLL, 1,  50 }, LVL_HIGH, 1050000, 4 },
-	[10] = { { 1036800, HFPLL, 1,  54 }, LVL_HIGH, 1050000, 4 },
+	[10] = { { 1036800, HFPLL, 1,  54 }, LVL_HIGH, 1050000, 5 },
 	[11] = { { 1113600, HFPLL, 1,  58 }, LVL_HIGH, 1050000, 5 },
-	[12] = { { 1190400, HFPLL, 1,  62 }, LVL_HIGH, 1050000, 5 },
+	[12] = { { 1190400, HFPLL, 1,  62 }, LVL_HIGH, 1050000, 6 },
 	[13] = { { 1267200, HFPLL, 1,  66 }, LVL_HIGH, 1050000, 6 },
-	[14] = { { 1344000, HFPLL, 1,  70 }, LVL_HIGH, 1050000, 6 },
+	[14] = { { 1344000, HFPLL, 1,  70 }, LVL_HIGH, 1050000, 7 },
 	[15] = { { 1420800, HFPLL, 1,  74 }, LVL_HIGH, 1050000, 7 },
 	[16] = { { 1497600, HFPLL, 1,  78 }, LVL_HIGH, 1050000, 7 },
-	[17] = { { 1574400, HFPLL, 1,  82 }, LVL_HIGH, 1050000, 7 },
-	[18] = { { 1651200, HFPLL, 1,  86 }, LVL_HIGH, 1050000, 7 },
-	[19] = { { 1728000, HFPLL, 1,  90 }, LVL_HIGH, 1050000, 7 },
-	[20] = { { 1804800, HFPLL, 1,  94 }, LVL_HIGH, 1050000, 7 },
-	[21] = { { 1881600, HFPLL, 1,  98 }, LVL_HIGH, 1050000, 7 },
-	[22] = { { 1958400, HFPLL, 1, 102 }, LVL_HIGH, 1050000, 7 },
-	[23] = { { 2035200, HFPLL, 1, 106 }, LVL_HIGH, 1050000, 7 },
-	[24] = { { 2112000, HFPLL, 1, 110 }, LVL_HIGH, 1050000, 7 },
-	[25] = { { 2188800, HFPLL, 1, 114 }, LVL_HIGH, 1050000, 7 },
 	{ }
 };
 
-static struct acpu_level acpu_freq_tbl[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 }, L2(0),   850000,  100000 },
-	{ 0, {  345600, HFPLL, 2,  36 }, L2(0),   850000, 3200000 },
-	{ 1, {  422400, HFPLL, 2,  44 }, L2(0),   850000, 3200000 },
-	{ 0, {  499200, HFPLL, 2,  52 }, L2(0),   850000, 3200000 },
-	{ 1, {  576000, HFPLL, 1,  30 }, L2(0),   850000, 3200000 },
-	{ 1, {  652800, HFPLL, 1,  34 }, L2(16),  850000, 3200000 },
-	{ 0, {  729600, HFPLL, 1,  38 }, L2(16),  850000, 3200000 },
-	{ 1, {  806400, HFPLL, 1,  42 }, L2(16),  850000, 3200000 },
-	{ 1, {  883200, HFPLL, 1,  46 }, L2(16),  870000, 3200000 },
-	{ 1, {  960000, HFPLL, 1,  50 }, L2(16),  880000, 3200000 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(16),  900000, 3200000 },
-	{ 1, { 1113600, HFPLL, 1,  58 }, L2(16),  915000, 3200000 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(16),  935000, 3200000 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(16),  950000, 3200000 },
-	{ 1, { 1344000, HFPLL, 1,  70 }, L2(16),  970000, 3200000 },
-	{ 1, { 1420800, HFPLL, 1,  74 }, L2(16),  985000, 3200000 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16), 1000000, 3200000 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(16), 1015000, 3200000 },
-	{ 1, { 1651200, HFPLL, 1,  86 }, L2(16), 1030000, 3200000 },
+static struct acpu_level acpu_freq_tbl_pvs0[] __initdata = {
+	{ 1, {  300000, PLL_0, 0,   0 }, L2(0),   825000,  400000 },
+	{ 0, {  345600, HFPLL, 2,  36 }, L2(3),   825000, 3200000 },
+	{ 1, {  422400, HFPLL, 2,  44 }, L2(3),   825000, 3200000 },
+	{ 0, {  499200, HFPLL, 2,  52 }, L2(6),   825000, 3200000 },
+	{ 1, {  576000, HFPLL, 1,  30 }, L2(6),   825000, 3200000 },
+	{ 1, {  652800, HFPLL, 1,  34 }, L2(7),   825000, 3200000 },
+	{ 1, {  729600, HFPLL, 1,  38 }, L2(7),   825000, 3200000 },
+	{ 0, {  806400, HFPLL, 1,  42 }, L2(10),  835000, 3200000 },
+	{ 1, {  883200, HFPLL, 1,  46 }, L2(10),  845000, 3200000 },
+	{ 0, {  960000, HFPLL, 1,  50 }, L2(10),  860000, 3200000 },
+	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  880000, 3200000 },
+	{ 0, { 1113600, HFPLL, 1,  58 }, L2(12),  905000, 3200000 },
+	{ 0, { 1190400, HFPLL, 1,  62 }, L2(12),  920000, 3200000 },
+	{ 0, { 1267200, HFPLL, 1,  66 }, L2(12),  940000, 3200000 },
+	{ 1, { 1344000, HFPLL, 1,  70 }, L2(12),  960000, 3200000 },
+	{ 0, { 1420800, HFPLL, 1,  74 }, L2(16),  980000, 3200000 },
+	{ 0, { 1497600, HFPLL, 1,  78 }, L2(16),  995000, 3200000 },
+	{ 0, { 1574400, HFPLL, 1,  82 }, L2(16), 1015000, 3200000 },
+	{ 0, { 1651200, HFPLL, 1,  86 }, L2(16), 1030000, 3200000 },
 	{ 1, { 1728000, HFPLL, 1,  90 }, L2(16), 1050000, 3200000 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(16), 1050000, 3200000 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(16), 1050000, 3200000 },
-	{ 0, { 1958400, HFPLL, 1, 102 }, L2(16), 1050000, 3200000 },
-	{ 0, { 1996800, HFPLL, 1, 104 }, L2(16), 1050000, 3200000 },
 	{ 0, { 0 } }
 };
 
-static struct pvs_table pvs_tables[NUM_SPEED_BINS][NUM_PVS]  __initdata = {
-	[0][PVS_SLOW]    = { acpu_freq_tbl, sizeof(acpu_freq_tbl) },
-	[0][PVS_NOMINAL] = { acpu_freq_tbl, sizeof(acpu_freq_tbl) },
-	[0][PVS_FAST]    = { acpu_freq_tbl, sizeof(acpu_freq_tbl) },
+static struct acpu_level acpu_freq_tbl_pvs1[] __initdata = {
+	{ 1, {  300000, PLL_0, 0,   0 }, L2(0),   825000,  400000 },
+	{ 0, {  345600, HFPLL, 2,  36 }, L2(3),   825000, 3200000 },
+	{ 1, {  422400, HFPLL, 2,  44 }, L2(3),   825000, 3200000 },
+	{ 0, {  499200, HFPLL, 2,  52 }, L2(6),   825000, 3200000 },
+	{ 1, {  576000, HFPLL, 1,  30 }, L2(6),   825000, 3200000 },
+	{ 1, {  652800, HFPLL, 1,  34 }, L2(7),   825000, 3200000 },
+	{ 1, {  729600, HFPLL, 1,  38 }, L2(7),   825000, 3200000 },
+	{ 0, {  806400, HFPLL, 1,  42 }, L2(10),  835000, 3200000 },
+	{ 1, {  883200, HFPLL, 1,  46 }, L2(10),  845000, 3200000 },
+	{ 0, {  960000, HFPLL, 1,  50 }, L2(10),  860000, 3200000 },
+	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  880000, 3200000 },
+	{ 0, { 1113600, HFPLL, 1,  58 }, L2(12),  905000, 3200000 },
+	{ 0, { 1190400, HFPLL, 1,  62 }, L2(12),  920000, 3200000 },
+	{ 0, { 1267200, HFPLL, 1,  66 }, L2(12),  940000, 3200000 },
+	{ 1, { 1344000, HFPLL, 1,  70 }, L2(12),  960000, 3200000 },
+	{ 0, { 1420800, HFPLL, 1,  74 }, L2(16),  980000, 3200000 },
+	{ 0, { 1497600, HFPLL, 1,  78 }, L2(16),  995000, 3200000 },
+	{ 0, { 1574400, HFPLL, 1,  82 }, L2(16), 1015000, 3200000 },
+	{ 0, { 1651200, HFPLL, 1,  86 }, L2(16), 1030000, 3200000 },
+	{ 1, { 1728000, HFPLL, 1,  90 }, L2(16), 1050000, 3200000 },
+	{ 0, { 0 } }
+};
+
+static struct acpu_level acpu_freq_tbl_pvs2[] __initdata = {
+	{ 1, {  300000, PLL_0, 0,   0 }, L2(0),   825000,  400000 },
+	{ 0, {  345600, HFPLL, 2,  36 }, L2(3),   825000, 3200000 },
+	{ 1, {  422400, HFPLL, 2,  44 }, L2(3),   825000, 3200000 },
+	{ 0, {  499200, HFPLL, 2,  52 }, L2(6),   825000, 3200000 },
+	{ 1, {  576000, HFPLL, 1,  30 }, L2(6),   825000, 3200000 },
+	{ 1, {  652800, HFPLL, 1,  34 }, L2(7),   825000, 3200000 },
+	{ 1, {  729600, HFPLL, 1,  38 }, L2(7),   825000, 3200000 },
+	{ 0, {  806400, HFPLL, 1,  42 }, L2(10),  825000, 3200000 },
+	{ 1, {  883200, HFPLL, 1,  46 }, L2(10),  825000, 3200000 },
+	{ 0, {  960000, HFPLL, 1,  50 }, L2(10),  835000, 3200000 },
+	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  855000, 3200000 },
+	{ 0, { 1113600, HFPLL, 1,  58 }, L2(12),  875000, 3200000 },
+	{ 0, { 1190400, HFPLL, 1,  62 }, L2(12),  895000, 3200000 },
+	{ 0, { 1267200, HFPLL, 1,  66 }, L2(12),  915000, 3200000 },
+	{ 1, { 1344000, HFPLL, 1,  70 }, L2(12),  930000, 3200000 },
+	{ 0, { 1420800, HFPLL, 1,  74 }, L2(16),  945000, 3200000 },
+	{ 0, { 1497600, HFPLL, 1,  78 }, L2(16),  960000, 3200000 },
+	{ 0, { 1574400, HFPLL, 1,  82 }, L2(16),  975000, 3200000 },
+	{ 0, { 1651200, HFPLL, 1,  86 }, L2(16),  990000, 3200000 },
+	{ 1, { 1728000, HFPLL, 1,  90 }, L2(16), 1000000, 3200000 },
+	{ 0, { 0 } }
+};
+
+static struct acpu_level acpu_freq_tbl_pvs3[] __initdata = {
+	{ 1, {  300000, PLL_0, 0,   0 }, L2(0),   825000,  400000 },
+	{ 0, {  345600, HFPLL, 2,  36 }, L2(3),   825000, 3200000 },
+	{ 1, {  422400, HFPLL, 2,  44 }, L2(3),   825000, 3200000 },
+	{ 0, {  499200, HFPLL, 2,  52 }, L2(6),   825000, 3200000 },
+	{ 1, {  576000, HFPLL, 1,  30 }, L2(6),   825000, 3200000 },
+	{ 1, {  652800, HFPLL, 1,  34 }, L2(7),   825000, 3200000 },
+	{ 1, {  729600, HFPLL, 1,  38 }, L2(7),   825000, 3200000 },
+	{ 0, {  806400, HFPLL, 1,  42 }, L2(10),  825000, 3200000 },
+	{ 1, {  883200, HFPLL, 1,  46 }, L2(10),  825000, 3200000 },
+	{ 0, {  960000, HFPLL, 1,  50 }, L2(10),  835000, 3200000 },
+	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  855000, 3200000 },
+	{ 0, { 1113600, HFPLL, 1,  58 }, L2(12),  875000, 3200000 },
+	{ 0, { 1190400, HFPLL, 1,  62 }, L2(12),  895000, 3200000 },
+	{ 0, { 1267200, HFPLL, 1,  66 }, L2(12),  915000, 3200000 },
+	{ 1, { 1344000, HFPLL, 1,  70 }, L2(12),  930000, 3200000 },
+	{ 0, { 1420800, HFPLL, 1,  74 }, L2(16),  945000, 3200000 },
+	{ 0, { 1497600, HFPLL, 1,  78 }, L2(16),  960000, 3200000 },
+	{ 0, { 1574400, HFPLL, 1,  82 }, L2(16),  975000, 3200000 },
+	{ 0, { 1651200, HFPLL, 1,  86 }, L2(16),  990000, 3200000 },
+	{ 1, { 1728000, HFPLL, 1,  90 }, L2(16), 1000000, 3200000 },
+	{ 0, { 0 } }
+};
+
+static struct acpu_level acpu_freq_tbl_pvs4[] __initdata = {
+	{ 1, {  300000, PLL_0, 0,   0 }, L2(0),  825000,  400000 },
+	{ 0, {  345600, HFPLL, 2,  36 }, L2(3),  825000, 3200000 },
+	{ 1, {  422400, HFPLL, 2,  44 }, L2(3),  825000, 3200000 },
+	{ 0, {  499200, HFPLL, 2,  52 }, L2(6),  825000, 3200000 },
+	{ 1, {  576000, HFPLL, 1,  30 }, L2(6),  825000, 3200000 },
+	{ 1, {  652800, HFPLL, 1,  34 }, L2(7),  825000, 3200000 },
+	{ 1, {  729600, HFPLL, 1,  38 }, L2(7),  825000, 3200000 },
+	{ 0, {  806400, HFPLL, 1,  42 }, L2(10), 825000, 3200000 },
+	{ 1, {  883200, HFPLL, 1,  46 }, L2(10), 825000, 3200000 },
+	{ 0, {  960000, HFPLL, 1,  50 }, L2(10), 825000, 3200000 },
+	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10), 825000, 3200000 },
+	{ 0, { 1113600, HFPLL, 1,  58 }, L2(12), 835000, 3200000 },
+	{ 0, { 1190400, HFPLL, 1,  62 }, L2(12), 855000, 3200000 },
+	{ 0, { 1267200, HFPLL, 1,  66 }, L2(12), 870000, 3200000 },
+	{ 1, { 1344000, HFPLL, 1,  70 }, L2(12), 885000, 3200000 },
+	{ 0, { 1420800, HFPLL, 1,  74 }, L2(16), 900000, 3200000 },
+	{ 0, { 1497600, HFPLL, 1,  78 }, L2(16), 910000, 3200000 },
+	{ 0, { 1574400, HFPLL, 1,  82 }, L2(16), 925000, 3200000 },
+	{ 0, { 1651200, HFPLL, 1,  86 }, L2(16), 940000, 3200000 },
+	{ 1, { 1728000, HFPLL, 1,  90 }, L2(16), 950000, 3200000 },
+	{ 0, { 0 } }
+};
+
+static struct pvs_table pvs_v1[NUM_SPEED_BINS][NUM_PVS] __initdata = {
+	[0][0] = { acpu_freq_tbl_pvs0, sizeof(acpu_freq_tbl_pvs0) },
+	[0][1] = { acpu_freq_tbl_pvs1, sizeof(acpu_freq_tbl_pvs1) },
+	[0][2] = { acpu_freq_tbl_pvs2, sizeof(acpu_freq_tbl_pvs2) },
+	[0][3] = { acpu_freq_tbl_pvs3, sizeof(acpu_freq_tbl_pvs3) },
+	[0][4] = { acpu_freq_tbl_pvs4, sizeof(acpu_freq_tbl_pvs4) },
+};
+
+static struct pvs_table pvs_v2[NUM_SPEED_BINS][NUM_PVS] __initdata = {
+	[0][0] = { acpu_freq_tbl_pvs0, sizeof(acpu_freq_tbl_pvs0) },
+	[0][1] = { acpu_freq_tbl_pvs1, sizeof(acpu_freq_tbl_pvs1) },
+	[0][2] = { acpu_freq_tbl_pvs2, sizeof(acpu_freq_tbl_pvs2) },
+	[0][3] = { acpu_freq_tbl_pvs3, sizeof(acpu_freq_tbl_pvs3) },
+	[0][4] = { acpu_freq_tbl_pvs4, sizeof(acpu_freq_tbl_pvs4) },
+	[0][5] = { acpu_freq_tbl_pvs4, sizeof(acpu_freq_tbl_pvs4) },
+	[0][6] = { acpu_freq_tbl_pvs4, sizeof(acpu_freq_tbl_pvs4) },
+	[0][7] = { acpu_freq_tbl_pvs4, sizeof(acpu_freq_tbl_pvs4) },
+	[1][0] = { acpu_freq_tbl_pvs0, sizeof(acpu_freq_tbl_pvs0) },
+	[1][1] = { acpu_freq_tbl_pvs1, sizeof(acpu_freq_tbl_pvs1) },
+	[1][2] = { acpu_freq_tbl_pvs2, sizeof(acpu_freq_tbl_pvs2) },
+	[1][3] = { acpu_freq_tbl_pvs3, sizeof(acpu_freq_tbl_pvs3) },
+	[1][4] = { acpu_freq_tbl_pvs4, sizeof(acpu_freq_tbl_pvs4) },
+	[1][5] = { acpu_freq_tbl_pvs4, sizeof(acpu_freq_tbl_pvs4) },
+	[1][6] = { acpu_freq_tbl_pvs4, sizeof(acpu_freq_tbl_pvs4) },
+	[1][7] = { acpu_freq_tbl_pvs4, sizeof(acpu_freq_tbl_pvs4) },
 };
 
 static struct acpuclk_krait_params acpuclk_8974_params __initdata = {
 	.scalable = scalable,
 	.scalable_size = sizeof(scalable),
 	.hfpll_data = &hfpll_data,
-	.pvs_tables = pvs_tables,
+	.pvs_tables = pvs_v2,
 	.l2_freq_tbl = l2_freq_tbl,
 	.l2_freq_tbl_size = sizeof(l2_freq_tbl),
 	.bus_scale = &bus_scale_data,
 	.pte_efuse_phys = 0xFC4B80B0,
+	.get_bin_info = get_krait_bin_format_b,
 	.stby_khz = 300000,
 };
 
+static void __init apply_v1_l2_workaround(void)
+{
+	static struct l2_level resticted_l2_tbl[] __initdata = {
+		[0] = { {  300000, PLL_0, 0,   0 }, LVL_LOW,  1050000, 0 },
+		[1] = { { 1497600, HFPLL, 1,  78 }, LVL_HIGH, 1050000, 7 },
+		{ }
+	};
+	struct acpu_level *l;
+	int s, p;
+
+	for (s = 0; s < NUM_SPEED_BINS; s++)
+		for (p = 0; p < NUM_PVS; p++)
+			for (l = pvs_v1[s][p].table; l && l->speed.khz; l++)
+				l->l2_level = l->l2_level > 5 ? 1 : 0;
+
+	acpuclk_8974_params.l2_freq_tbl = resticted_l2_tbl;
+	acpuclk_8974_params.l2_freq_tbl_size = sizeof(resticted_l2_tbl);
+}
+
 static int __init acpuclk_8974_probe(struct platform_device *pdev)
 {
+	/*
+	 * 8974 hardware revisions older than v1.2 may experience L2 parity
+	 * errors when running at some performance points between 300MHz
+	 * and 1497.6MHz (non-inclusive), or when vdd_mx is less than 1.05V.
+	 * Restrict L2 operation to safe performance points on these devices.
+	 */
+	if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 1) {
+		acpuclk_8974_params.pvs_tables = pvs_v1;
+		if (SOCINFO_VERSION_MINOR(socinfo_get_version()) < 2)
+			apply_v1_l2_workaround();
+	}
+
 	return acpuclk_krait_init(&pdev->dev, &acpuclk_8974_params);
 }
 
diff --git a/arch/arm/mach-msm/acpuclock-8x50.c b/arch/arm/mach-msm/acpuclock-8x50.c
index eed8000..4d63c04 100644
--- a/arch/arm/mach-msm/acpuclock-8x50.c
+++ b/arch/arm/mach-msm/acpuclock-8x50.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/arch/arm/mach-msm/acpuclock-8x60.c b/arch/arm/mach-msm/acpuclock-8x60.c
index f94f0b2..de63feb 100644
--- a/arch/arm/mach-msm/acpuclock-8x60.c
+++ b/arch/arm/mach-msm/acpuclock-8x60.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/acpuclock-9615.c b/arch/arm/mach-msm/acpuclock-9615.c
index db7bab3..2163830 100644
--- a/arch/arm/mach-msm/acpuclock-9615.c
+++ b/arch/arm/mach-msm/acpuclock-9615.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/acpuclock-9625.c b/arch/arm/mach-msm/acpuclock-9625.c
index b0556c3..b439088 100644
--- a/arch/arm/mach-msm/acpuclock-9625.c
+++ b/arch/arm/mach-msm/acpuclock-9625.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -15,96 +15,22 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <linux/spinlock.h>
 #include <linux/errno.h>
-#include <linux/cpufreq.h>
-#include <linux/clk.h>
 #include <linux/platform_device.h>
-#include <linux/iopoll.h>
+#include <linux/regulator/consumer.h>
 
-#include <mach/board.h>
-#include <mach/msm_iomap.h>
 #include <mach/msm_bus.h>
 #include <mach/msm_bus_board.h>
-#include <mach/rpm-regulator.h>
 #include <mach/clk-provider.h>
 #include <mach/rpm-regulator-smd.h>
 
-#include "acpuclock.h"
+#include "acpuclock-cortex.h"
 
-#define RCG_SRC_DIV_MASK		BM(7, 0)
 #define RCG_CONFIG_PGM_DATA_BIT		BIT(11)
 #define RCG_CONFIG_PGM_ENA_BIT		BIT(10)
-#define POLL_INTERVAL_US		1
-#define APCS_RCG_UPDATE_TIMEOUT_US	20
 #define GPLL0_TO_A5_ALWAYS_ENABLE	BIT(18)
 
-#define MAX_VDD_MEM			1050000
-#define MAX_VDD_CPU			1050000
-
-/* Corner type vreg VDD values */
-#define LVL_NONE        RPM_REGULATOR_CORNER_NONE
-#define LVL_LOW         RPM_REGULATOR_CORNER_SVS_SOC
-#define LVL_NOM         RPM_REGULATOR_CORNER_NORMAL
-#define LVL_HIGH        RPM_REGULATOR_CORNER_SUPER_TURBO
-
-enum clk_src {
-	CXO,
-	PLL0,
-	ACPUPLL,
-	NUM_SRC,
-};
-
-struct src_clock {
-	struct clk *clk;
-	const char *name;
-};
-
-static struct src_clock src_clocks[NUM_SRC] = {
-	[PLL0].name = "pll0",
-	[ACPUPLL].name = "pll14",
-};
-
-struct clkctl_acpu_speed {
-	bool use_for_scaling;
-	unsigned int khz;
-	int src;
-	unsigned int src_sel;
-	unsigned int src_div;
-	unsigned int vdd_cpu;
-	unsigned int vdd_mem;
-	unsigned int bw_level;
-};
-
-struct acpuclk_drv_data {
-	struct mutex			lock;
-	struct clkctl_acpu_speed	*current_speed;
-	void __iomem			*apcs_rcg_config;
-	void __iomem			*apcs_cpu_pwr_ctl;
-	struct regulator		*vdd_cpu;
-	struct regulator		*vdd_mem;
-};
-
-static struct acpuclk_drv_data drv_data = {
-	.current_speed = &(struct clkctl_acpu_speed){ 0 },
-};
-
-/* Instantaneous bandwidth requests in MB/s. */
-#define BW_MBPS(_bw) \
-	{ \
-		.vectors = &(struct msm_bus_vectors){ \
-			.src = MSM_BUS_MASTER_AMPSS_M0, \
-			.dst = MSM_BUS_SLAVE_EBI_CH0, \
-			.ib = (_bw) * 1000000UL, \
-			.ab = 0, \
-		}, \
-		.num_paths = 1, \
-	}
-
 static struct msm_bus_paths bw_level_tbl[] = {
 	[0] =  BW_MBPS(152), /* At least 19 MHz on bus. */
 	[1] =  BW_MBPS(264), /* At least 33 MHz on bus. */
@@ -123,8 +49,6 @@
 	.name = "acpuclock",
 };
 
-static uint32_t bus_perf_client;
-
 /* TODO:
  * 1) Update MX voltage when they are avaiable
  * 2) Update bus bandwidth
@@ -138,265 +62,31 @@
 	{ 0 }
 };
 
-/* Update the bus bandwidth request. */
-static void set_bus_bw(unsigned int bw)
-{
-	int ret;
-
-	if (bw >= ARRAY_SIZE(bw_level_tbl)) {
-		pr_err("invalid bandwidth request (%d)\n", bw);
-		return;
-	}
-
-	/* Update bandwidth if request has changed. This may sleep. */
-	ret = msm_bus_scale_client_update_request(bus_perf_client, bw);
-	if (ret)
-		pr_err("bandwidth request failed (%d)\n", ret);
-
-	return;
-}
-
-/* Apply any per-cpu voltage increases. */
-static int increase_vdd(unsigned int vdd_cpu, unsigned int vdd_mem)
-{
-	int rc = 0;
-
-	/* Increase vdd_mem before vdd_cpu. vdd_mem should be >= vdd_cpu. */
-	rc = regulator_set_voltage(drv_data.vdd_mem, vdd_mem, MAX_VDD_MEM);
-	if (rc) {
-		pr_err("vdd_mem increase failed (%d)\n", rc);
-		return rc;
-	}
-
-	rc = regulator_set_voltage(drv_data.vdd_cpu, vdd_cpu, MAX_VDD_CPU);
-	if (rc)
-		pr_err("vdd_cpu increase failed (%d)\n", rc);
-
-	return rc;
-}
-
-/* Apply any per-cpu voltage decreases. */
-static void decrease_vdd(unsigned int vdd_cpu, unsigned int vdd_mem)
-{
-	int ret;
-
-	/* Update CPU voltage. */
-	ret = regulator_set_voltage(drv_data.vdd_cpu, vdd_cpu, MAX_VDD_CPU);
-	if (ret) {
-		pr_err("vdd_cpu decrease failed (%d)\n", ret);
-		return;
-	}
-
-	/* Decrease vdd_mem after vdd_cpu. vdd_mem should be >= vdd_cpu. */
-	ret = regulator_set_voltage(drv_data.vdd_mem, vdd_mem, MAX_VDD_MEM);
-	if (ret)
-		pr_err("vdd_mem decrease failed (%d)\n", ret);
-}
-
-static void select_clk_source_div(struct clkctl_acpu_speed *s)
-{
-	u32 regval, rc, src_div;
-	void __iomem *apcs_rcg_config = drv_data.apcs_rcg_config;
-
-	src_div = s->src_div ? ((2 * s->src_div) - 1) : s->src_div;
-
-	regval = readl_relaxed(apcs_rcg_config);
-	regval &= ~RCG_SRC_DIV_MASK;
-	regval |= BVAL(2, 0, s->src_sel) | BVAL(7, 3, src_div);
-	writel_relaxed(regval, apcs_rcg_config);
-
-	/*
-	 * Make sure writing of src and div finishes before update
-	 * the configuration
-	 */
-	mb();
-
-	/* Update the configruation */
-	regval = readl_relaxed(apcs_rcg_config);
-	regval |= RCG_CONFIG_PGM_DATA_BIT | RCG_CONFIG_PGM_ENA_BIT;
-	writel_relaxed(regval, apcs_rcg_config);
-
-	/* Wait for update to take effect */
-	rc = readl_poll_timeout(apcs_rcg_config, regval,
-		   !(regval & RCG_CONFIG_PGM_DATA_BIT),
-		   POLL_INTERVAL_US,
-		   APCS_RCG_UPDATE_TIMEOUT_US);
-	if (rc)
-		pr_warn("acpu rcg didn't update its configuration\n");
-}
-
-static int set_speed(struct clkctl_acpu_speed *tgt_s)
-{
-	int rc = 0;
-	unsigned int tgt_freq_hz = tgt_s->khz * 1000;
-	struct clkctl_acpu_speed *strt_s = drv_data.current_speed;
-	struct clkctl_acpu_speed *cxo_s = &acpu_freq_tbl[0];
-	struct clk *strt = src_clocks[strt_s->src].clk;
-	struct clk *tgt = src_clocks[tgt_s->src].clk;
-
-	if (strt_s->src == ACPUPLL && tgt_s->src == ACPUPLL) {
-		/* Switch to another always on src */
-		select_clk_source_div(cxo_s);
-
-		/* Re-program acpu pll */
-		clk_disable(tgt);
-		rc = clk_set_rate(tgt, tgt_freq_hz);
-		if (rc)
-			pr_err("Failed to set ACPU PLL to %u\n", tgt_freq_hz);
-		BUG_ON(clk_enable(tgt));
-
-		/* Switch back to acpu pll */
-		select_clk_source_div(tgt_s);
-	} else if (strt_s->src != ACPUPLL && tgt_s->src == ACPUPLL) {
-		rc = clk_set_rate(tgt, tgt_freq_hz);
-		if (rc) {
-			pr_err("Failed to set ACPU PLL to %u\n", tgt_freq_hz);
-			return rc;
-		}
-
-		rc = clk_enable(tgt);
-		if (rc) {
-			pr_err("ACPU PLL enable failed\n");
-			return rc;
-		}
-
-		select_clk_source_div(tgt_s);
-
-		clk_disable(strt);
-	} else {
-		rc = clk_enable(tgt);
-		if (rc) {
-			pr_err("%s enable failed\n",
-					src_clocks[tgt_s->src].name);
-			return rc;
-		}
-
-		select_clk_source_div(tgt_s);
-
-		clk_disable(strt);
-	}
-
-	return rc;
-}
-
-static int acpuclk_9625_set_rate(int cpu, unsigned long rate,
-				 enum setrate_reason reason)
-{
-	struct clkctl_acpu_speed *tgt_s, *strt_s;
-	int rc = 0;
-
-	if (reason == SETRATE_CPUFREQ)
-		mutex_lock(&drv_data.lock);
-
-	strt_s = drv_data.current_speed;
-
-	/* Return early if rate didn't change */
-	if (rate == strt_s->khz)
-		goto out;
-
-	/* Find target frequency */
-	for (tgt_s = acpu_freq_tbl; tgt_s->khz != 0; tgt_s++)
-		if (tgt_s->khz == rate)
-			break;
-	if (tgt_s->khz == 0) {
-		rc = -EINVAL;
-		goto out;
-	}
-
-	/* Increase VDD levels if needed */
-	if ((reason == SETRATE_CPUFREQ || reason == SETRATE_INIT)
-			&& (tgt_s->khz > strt_s->khz)) {
-		rc = increase_vdd(tgt_s->vdd_cpu, tgt_s->vdd_mem);
-		if (rc)
-			goto out;
-	}
-
-	pr_debug("Switching from CPU rate %u KHz -> %u KHz\n",
-		strt_s->khz, tgt_s->khz);
-
-	/* Switch CPU speed. */
-	rc = set_speed(tgt_s);
-	if (rc)
-		goto out;
-
-	drv_data.current_speed = tgt_s;
-	pr_debug("CPU speed change complete\n");
-
-	/* Nothing else to do for SWFI or power-collapse. */
-	if (reason == SETRATE_SWFI || reason == SETRATE_PC)
-		goto out;
-
-	/* Update bus bandwith request */
-	set_bus_bw(tgt_s->bw_level);
-
-	/* Drop VDD levels if we can. */
-	if (tgt_s->khz < strt_s->khz)
-		decrease_vdd(tgt_s->vdd_cpu, tgt_s->vdd_mem);
-
-out:
-	if (reason == SETRATE_CPUFREQ)
-		mutex_unlock(&drv_data.lock);
-	return rc;
-}
-
-static unsigned long acpuclk_9625_get_rate(int cpu)
-{
-	return drv_data.current_speed->khz;
-}
-
-#ifdef CONFIG_CPU_FREQ_MSM
-static struct cpufreq_frequency_table freq_table[30];
-
-static void __init cpufreq_table_init(void)
-{
-	int i, freq_cnt = 0;
-
-	/* Construct the freq_table tables from acpu_freq_tbl. */
-	for (i = 0; acpu_freq_tbl[i].khz != 0
-			&& freq_cnt < ARRAY_SIZE(freq_table); i++) {
-		if (!acpu_freq_tbl[i].use_for_scaling)
-			continue;
-		freq_table[freq_cnt].index = freq_cnt;
-		freq_table[freq_cnt].frequency = acpu_freq_tbl[i].khz;
-		freq_cnt++;
-	}
-	/* freq_table not big enough to store all usable freqs. */
-	BUG_ON(acpu_freq_tbl[i].khz != 0);
-
-	freq_table[freq_cnt].index = freq_cnt;
-	freq_table[freq_cnt].frequency = CPUFREQ_TABLE_END;
-
-	pr_info("CPU: %d scaling frequencies supported.\n", freq_cnt);
-
-	/* Register table with CPUFreq. */
-	cpufreq_frequency_table_get_attr(freq_table, smp_processor_id());
-}
-#else
-static void __init cpufreq_table_init(void) {}
-#endif
-
-static struct acpuclk_data acpuclk_9625_data = {
-	.set_rate = acpuclk_9625_set_rate,
-	.get_rate = acpuclk_9625_get_rate,
-	.power_collapse_khz = 19200,
-	.wait_for_irq_khz = 19200,
+static struct acpuclk_drv_data drv_data = {
+	.freq_tbl = acpu_freq_tbl,
+	.current_speed = &(struct clkctl_acpu_speed){ 0 },
+	.bus_scale = &bus_client_pdata,
+	.vdd_max_cpu = LVL_HIGH,
+	.vdd_max_mem = 1050000,
+	.src_clocks = {
+		[PLL0].name = "pll0",
+		[ACPUPLL].name = "pll14",
+	},
+	.reg_data = {
+		.cfg_src_mask = BM(2, 0),
+		.cfg_src_shift = 0,
+		.cfg_div_mask = BM(7, 3),
+		.cfg_div_shift = 3,
+		.update_mask = RCG_CONFIG_PGM_DATA_BIT | RCG_CONFIG_PGM_ENA_BIT,
+		.poll_mask = RCG_CONFIG_PGM_DATA_BIT,
+	},
 };
 
 static int __init acpuclk_9625_probe(struct platform_device *pdev)
 {
-	unsigned long max_cpu_khz = 0;
 	struct resource *res;
-	int i, rc;
 	u32 regval;
 
-	mutex_init(&drv_data.lock);
-
-	bus_perf_client = msm_bus_scale_register_client(&bus_client_pdata);
-	if (!bus_perf_client) {
-		pr_err("Unable to register bus client\n");
-		BUG();
-	}
-
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rcg_base");
 	if (!res)
 		return -EINVAL;
@@ -405,6 +95,8 @@
 	if (!drv_data.apcs_rcg_config)
 		return -ENOMEM;
 
+	drv_data.apcs_rcg_cmd = drv_data.apcs_rcg_config;
+
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwr_base");
 	if (!res)
 		return -EINVAL;
@@ -430,60 +122,7 @@
 	regval |= GPLL0_TO_A5_ALWAYS_ENABLE;
 	writel_relaxed(regval, drv_data.apcs_cpu_pwr_ctl);
 
-	for (i = 0; i < NUM_SRC; i++) {
-		if (!src_clocks[i].name)
-			continue;
-		src_clocks[i].clk = clk_get(&pdev->dev, src_clocks[i].name);
-		BUG_ON(IS_ERR(src_clocks[i].clk));
-		/*
-		 * Prepare the PLLs because we enable/disable them
-		 * in atomic context during power collapse/restore.
-		 */
-		BUG_ON(clk_prepare(src_clocks[i].clk));
-	}
-
-	/* Improve boot time by ramping up CPU immediately */
-	for (i = 0; acpu_freq_tbl[i].khz != 0 &&
-				acpu_freq_tbl[i].use_for_scaling; i++)
-		max_cpu_khz = acpu_freq_tbl[i].khz;
-
-	/* Initialize regulators */
-	rc = increase_vdd(acpu_freq_tbl[i].vdd_cpu, acpu_freq_tbl[i].vdd_mem);
-	if (rc)
-		goto err_vdd;
-
-	rc = regulator_enable(drv_data.vdd_mem);
-	if (rc) {
-		dev_err(&pdev->dev, "regulator_enable for a5_mem failed\n");
-		goto err_vdd;
-	}
-
-	rc = regulator_enable(drv_data.vdd_cpu);
-	if (rc) {
-		dev_err(&pdev->dev, "regulator_enable for a5_cpu failed\n");
-		goto err_vdd_cpu;
-	}
-
-	acpuclk_9625_set_rate(smp_processor_id(), max_cpu_khz, SETRATE_INIT);
-
-	acpuclk_register(&acpuclk_9625_data);
-	cpufreq_table_init();
-
-	return 0;
-
-err_vdd_cpu:
-	regulator_disable(drv_data.vdd_mem);
-err_vdd:
-	regulator_put(drv_data.vdd_mem);
-	regulator_put(drv_data.vdd_cpu);
-
-	for (i = 0; i < NUM_SRC; i++) {
-		if (!src_clocks[i].name)
-			continue;
-		clk_unprepare(src_clocks[i].clk);
-		clk_put(src_clocks[i].clk);
-	}
-	return rc;
+	return acpuclk_cortex_init(pdev, &drv_data);
 }
 
 static struct of_device_id acpuclk_9625_match_table[] = {
diff --git a/arch/arm/mach-msm/acpuclock-cortex.c b/arch/arm/mach-msm/acpuclock-cortex.c
new file mode 100644
index 0000000..febf95a
--- /dev/null
+++ b/arch/arm/mach-msm/acpuclock-cortex.c
@@ -0,0 +1,375 @@
+/*
+ * 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) "%s: " fmt, __func__
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+#include <linux/cpufreq.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/iopoll.h>
+
+#include <mach/board.h>
+#include <mach/msm_iomap.h>
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
+#include <mach/rpm-regulator.h>
+#include <mach/clk-provider.h>
+#include <mach/rpm-regulator-smd.h>
+
+#include "acpuclock.h"
+#include "acpuclock-cortex.h"
+
+#define POLL_INTERVAL_US		1
+#define APCS_RCG_UPDATE_TIMEOUT_US	20
+
+static struct acpuclk_drv_data *acpuclk_init_data;
+static uint32_t bus_perf_client;
+
+/* Update the bus bandwidth request. */
+static void set_bus_bw(unsigned int bw)
+{
+	int ret;
+
+	if (bw >= acpuclk_init_data->bus_scale->num_usecases) {
+		pr_err("invalid bandwidth request (%d)\n", bw);
+		return;
+	}
+
+	/* Update bandwidth if request has changed. This may sleep. */
+	ret = msm_bus_scale_client_update_request(bus_perf_client, bw);
+	if (ret)
+		pr_err("bandwidth request failed (%d)\n", ret);
+
+	return;
+}
+
+/* Apply any voltage increases. */
+static int increase_vdd(unsigned int vdd_cpu, unsigned int vdd_mem)
+{
+	int rc = 0;
+
+	/* Increase vdd_mem before vdd_cpu. vdd_mem should be >= vdd_cpu. */
+	rc = regulator_set_voltage(acpuclk_init_data->vdd_mem, vdd_mem,
+		acpuclk_init_data->vdd_max_mem);
+	if (rc) {
+		pr_err("vdd_mem increase failed (%d)\n", rc);
+		return rc;
+	}
+
+	rc = regulator_set_voltage(acpuclk_init_data->vdd_cpu, vdd_cpu,
+		acpuclk_init_data->vdd_max_cpu);
+	if (rc)
+		pr_err("vdd_cpu increase failed (%d)\n", rc);
+
+	return rc;
+}
+
+/* Apply any per-cpu voltage decreases. */
+static void decrease_vdd(unsigned int vdd_cpu, unsigned int vdd_mem)
+{
+	int ret;
+
+	/* Update CPU voltage. */
+	ret = regulator_set_voltage(acpuclk_init_data->vdd_cpu, vdd_cpu,
+		acpuclk_init_data->vdd_max_cpu);
+	if (ret) {
+		pr_err("vdd_cpu decrease failed (%d)\n", ret);
+		return;
+	}
+
+	/* Decrease vdd_mem after vdd_cpu. vdd_mem should be >= vdd_cpu. */
+	ret = regulator_set_voltage(acpuclk_init_data->vdd_mem, vdd_mem,
+		acpuclk_init_data->vdd_max_mem);
+	if (ret)
+		pr_err("vdd_mem decrease failed (%d)\n", ret);
+}
+
+static void select_clk_source_div(struct acpuclk_drv_data *drv_data,
+	struct clkctl_acpu_speed *s)
+{
+	u32 regval, rc, src_div;
+	void __iomem *apcs_rcg_config = drv_data->apcs_rcg_config;
+	void __iomem *apcs_rcg_cmd = drv_data->apcs_rcg_cmd;
+	struct acpuclk_reg_data *r = &drv_data->reg_data;
+
+	src_div = s->src_div ? ((2 * s->src_div) - 1) : s->src_div;
+
+	regval = readl_relaxed(apcs_rcg_config);
+	regval &= ~r->cfg_src_mask;
+	regval |= s->src_sel << r->cfg_src_shift;
+	regval &= ~r->cfg_div_mask;
+	regval |= src_div << r->cfg_div_shift;
+	writel_relaxed(regval, apcs_rcg_config);
+
+	/* Update the configuration */
+	regval = readl_relaxed(apcs_rcg_cmd);
+	regval |= r->update_mask;
+	writel_relaxed(regval, apcs_rcg_cmd);
+
+	/* Wait for the update to take effect */
+	rc = readl_poll_timeout(apcs_rcg_cmd, regval,
+		   !(regval & r->poll_mask),
+		   POLL_INTERVAL_US,
+		   APCS_RCG_UPDATE_TIMEOUT_US);
+	if (rc)
+		pr_warn("acpu rcg didn't update its configuration\n");
+}
+
+static int set_speed(struct clkctl_acpu_speed *tgt_s)
+{
+	int rc = 0;
+	unsigned int tgt_freq_hz = tgt_s->khz * 1000;
+	struct clkctl_acpu_speed *strt_s = acpuclk_init_data->current_speed;
+	struct clkctl_acpu_speed *cxo_s = &acpuclk_init_data->freq_tbl[0];
+	struct clk *strt = acpuclk_init_data->src_clocks[strt_s->src].clk;
+	struct clk *tgt = acpuclk_init_data->src_clocks[tgt_s->src].clk;
+
+	if (strt_s->src == ACPUPLL && tgt_s->src == ACPUPLL) {
+		/* Switch to another always on src */
+		select_clk_source_div(acpuclk_init_data, cxo_s);
+
+		/* Re-program acpu pll */
+		clk_disable(tgt);
+		rc = clk_set_rate(tgt, tgt_freq_hz);
+		if (rc)
+			pr_err("Failed to set ACPU PLL to %u\n", tgt_freq_hz);
+		BUG_ON(clk_enable(tgt));
+
+		/* Switch back to acpu pll */
+		select_clk_source_div(acpuclk_init_data, tgt_s);
+
+	} else if (strt_s->src != ACPUPLL && tgt_s->src == ACPUPLL) {
+		rc = clk_set_rate(tgt, tgt_freq_hz);
+		if (rc) {
+			pr_err("Failed to set ACPU PLL to %u\n", tgt_freq_hz);
+			return rc;
+		}
+
+		rc = clk_enable(tgt);
+		if (rc) {
+			pr_err("ACPU PLL enable failed\n");
+			return rc;
+		}
+
+		select_clk_source_div(acpuclk_init_data, tgt_s);
+
+		clk_disable(strt);
+	} else {
+		rc = clk_enable(tgt);
+		if (rc) {
+			pr_err("%s enable failed\n",
+				acpuclk_init_data->src_clocks[tgt_s->src].name);
+			return rc;
+		}
+
+		select_clk_source_div(acpuclk_init_data, tgt_s);
+
+		clk_disable(strt);
+	}
+
+	return rc;
+}
+
+static int acpuclk_cortex_set_rate(int cpu, unsigned long rate,
+				 enum setrate_reason reason)
+{
+	struct clkctl_acpu_speed *tgt_s, *strt_s;
+	int rc = 0;
+
+	if (reason == SETRATE_CPUFREQ)
+		mutex_lock(&acpuclk_init_data->lock);
+
+	strt_s = acpuclk_init_data->current_speed;
+
+	/* Return early if rate didn't change */
+	if (rate == strt_s->khz)
+		goto out;
+
+	/* Find target frequency */
+	for (tgt_s = acpuclk_init_data->freq_tbl; tgt_s->khz != 0; tgt_s++)
+		if (tgt_s->khz == rate)
+			break;
+	if (tgt_s->khz == 0) {
+		rc = -EINVAL;
+		goto out;
+	}
+
+	/* Increase VDD levels if needed */
+	if ((reason == SETRATE_CPUFREQ || reason == SETRATE_INIT)
+			&& (tgt_s->khz > strt_s->khz)) {
+		rc = increase_vdd(tgt_s->vdd_cpu, tgt_s->vdd_mem);
+		if (rc)
+			goto out;
+	}
+
+	pr_debug("Switching from CPU rate %u KHz -> %u KHz\n",
+		strt_s->khz, tgt_s->khz);
+
+	/* Switch CPU speed. */
+	rc = set_speed(tgt_s);
+	if (rc)
+		goto out;
+
+	acpuclk_init_data->current_speed = tgt_s;
+	pr_debug("CPU speed change complete\n");
+
+	/* Nothing else to do for SWFI or power-collapse. */
+	if (reason == SETRATE_SWFI || reason == SETRATE_PC)
+		goto out;
+
+	/* Update bus bandwith request */
+	set_bus_bw(tgt_s->bw_level);
+
+	/* Drop VDD levels if we can. */
+	if (tgt_s->khz < strt_s->khz)
+		decrease_vdd(tgt_s->vdd_cpu, tgt_s->vdd_mem);
+
+out:
+	if (reason == SETRATE_CPUFREQ)
+		mutex_unlock(&acpuclk_init_data->lock);
+	return rc;
+}
+
+static unsigned long acpuclk_cortex_get_rate(int cpu)
+{
+	return acpuclk_init_data->current_speed->khz;
+}
+
+#ifdef CONFIG_CPU_FREQ_MSM
+static struct cpufreq_frequency_table freq_table[30];
+
+static void __init cpufreq_table_init(void)
+{
+	int i, freq_cnt = 0;
+
+	/* Construct the freq_table tables from acpuclk_init_data->freq_tbl. */
+	for (i = 0; acpuclk_init_data->freq_tbl[i].khz != 0
+			&& freq_cnt < ARRAY_SIZE(freq_table); i++) {
+		if (!acpuclk_init_data->freq_tbl[i].use_for_scaling)
+			continue;
+		freq_table[freq_cnt].index = freq_cnt;
+		freq_table[freq_cnt].frequency =
+			acpuclk_init_data->freq_tbl[i].khz;
+		freq_cnt++;
+	}
+	/* freq_table not big enough to store all usable freqs. */
+	BUG_ON(acpuclk_init_data->freq_tbl[i].khz != 0);
+
+	freq_table[freq_cnt].index = freq_cnt;
+	freq_table[freq_cnt].frequency = CPUFREQ_TABLE_END;
+
+	pr_info("CPU: %d scaling frequencies supported.\n", freq_cnt);
+
+	/* Register table with CPUFreq. */
+	for_each_possible_cpu(i)
+		cpufreq_frequency_table_get_attr(freq_table, i);
+}
+#else
+static void __init cpufreq_table_init(void) {}
+#endif
+
+static struct acpuclk_data acpuclk_cortex_data = {
+	.set_rate = acpuclk_cortex_set_rate,
+	.get_rate = acpuclk_cortex_get_rate,
+	.power_collapse_khz = 19200,
+	.wait_for_irq_khz = 19200,
+};
+
+int __init acpuclk_cortex_init(struct platform_device *pdev,
+	struct acpuclk_drv_data *data)
+{
+	unsigned long max_cpu_khz = 0;
+	int i, rc;
+
+	acpuclk_init_data = data;
+	mutex_init(&acpuclk_init_data->lock);
+
+	bus_perf_client = msm_bus_scale_register_client(
+		acpuclk_init_data->bus_scale);
+	if (!bus_perf_client) {
+		pr_err("Unable to register bus client\n");
+		BUG();
+	}
+
+	for (i = 0; i < NUM_SRC; i++) {
+		if (!acpuclk_init_data->src_clocks[i].name)
+			continue;
+		acpuclk_init_data->src_clocks[i].clk =
+			clk_get(&pdev->dev,
+				acpuclk_init_data->src_clocks[i].name);
+		BUG_ON(IS_ERR(acpuclk_init_data->src_clocks[i].clk));
+		/*
+		 * Prepare the PLLs because we enable/disable them
+		 * in atomic context during power collapse/restore.
+		 */
+		BUG_ON(clk_prepare(acpuclk_init_data->src_clocks[i].clk));
+	}
+
+	/* Improve boot time by ramping up CPU immediately */
+	for (i = 0; acpuclk_init_data->freq_tbl[i].khz != 0; i++)
+		if (acpuclk_init_data->freq_tbl[i].use_for_scaling)
+			max_cpu_khz = acpuclk_init_data->freq_tbl[i].khz;
+
+	/* Initialize regulators */
+	rc = increase_vdd(acpuclk_init_data->vdd_max_cpu,
+		acpuclk_init_data->vdd_max_mem);
+	if (rc)
+		goto err_vdd;
+
+	rc = regulator_enable(acpuclk_init_data->vdd_mem);
+	if (rc) {
+		dev_err(&pdev->dev, "regulator_enable for mem failed\n");
+		goto err_vdd;
+	}
+
+	rc = regulator_enable(acpuclk_init_data->vdd_cpu);
+	if (rc) {
+		dev_err(&pdev->dev, "regulator_enable for cpu failed\n");
+		goto err_vdd_cpu;
+	}
+
+	/*
+	 * Select a state which is always a valid transition to align SW with
+	 * the HW configuration set by the bootloaders.
+	 */
+	acpuclk_cortex_set_rate(0, acpuclk_cortex_data.power_collapse_khz,
+		SETRATE_INIT);
+	acpuclk_cortex_set_rate(0, max_cpu_khz, SETRATE_INIT);
+
+	acpuclk_register(&acpuclk_cortex_data);
+	cpufreq_table_init();
+
+	return 0;
+
+err_vdd_cpu:
+	regulator_disable(acpuclk_init_data->vdd_mem);
+err_vdd:
+	regulator_put(acpuclk_init_data->vdd_mem);
+	regulator_put(acpuclk_init_data->vdd_cpu);
+
+	for (i = 0; i < NUM_SRC; i++) {
+		if (!acpuclk_init_data->src_clocks[i].name)
+			continue;
+		clk_unprepare(acpuclk_init_data->src_clocks[i].clk);
+		clk_put(acpuclk_init_data->src_clocks[i].clk);
+	}
+	return rc;
+}
diff --git a/arch/arm/mach-msm/acpuclock-cortex.h b/arch/arm/mach-msm/acpuclock-cortex.h
new file mode 100644
index 0000000..2db3987
--- /dev/null
+++ b/arch/arm/mach-msm/acpuclock-cortex.h
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+/* Corner type vreg VDD values */
+#define LVL_NONE        RPM_REGULATOR_CORNER_NONE
+#define LVL_LOW         RPM_REGULATOR_CORNER_SVS_SOC
+#define LVL_NOM         RPM_REGULATOR_CORNER_NORMAL
+#define LVL_HIGH        RPM_REGULATOR_CORNER_SUPER_TURBO
+
+enum clk_src {
+	CXO,
+	PLL0,
+	ACPUPLL,
+	NUM_SRC,
+};
+
+struct src_clock {
+	struct clk *clk;
+	const char *name;
+};
+
+struct clkctl_acpu_speed {
+	bool use_for_scaling;
+	unsigned int khz;
+	int src;
+	unsigned int src_sel;
+	unsigned int src_div;
+	unsigned int vdd_cpu;
+	unsigned int vdd_mem;
+	unsigned int bw_level;
+};
+
+struct acpuclk_reg_data {
+	u32 cfg_src_mask;
+	u32 cfg_src_shift;
+	u32 cfg_div_mask;
+	u32 cfg_div_shift;
+	u32 update_mask;
+	u32 poll_mask;
+};
+
+struct acpuclk_drv_data {
+	struct mutex			lock;
+	struct clkctl_acpu_speed	*freq_tbl;
+	struct clkctl_acpu_speed	*current_speed;
+	struct msm_bus_scale_pdata	*bus_scale;
+	void __iomem			*apcs_rcg_config;
+	void __iomem			*apcs_rcg_cmd;
+	void __iomem			*apcs_cpu_pwr_ctl;
+	struct regulator		*vdd_cpu;
+	unsigned long			vdd_max_cpu;
+	struct regulator		*vdd_mem;
+	unsigned long			vdd_max_mem;
+	struct src_clock		src_clocks[NUM_SRC];
+	struct acpuclk_reg_data		reg_data;
+};
+
+/* Instantaneous bandwidth requests in MB/s. */
+#define BW_MBPS(_bw) \
+	{ \
+		.vectors = &(struct msm_bus_vectors){ \
+			.src = MSM_BUS_MASTER_AMPSS_M0, \
+			.dst = MSM_BUS_SLAVE_EBI_CH0, \
+			.ib = (_bw) * 1000000ULL, \
+			.ab = 0, \
+		}, \
+		.num_paths = 1, \
+	}
+
+int __init acpuclk_cortex_init(struct platform_device *pdev,
+	struct acpuclk_drv_data *data);
+
diff --git a/arch/arm/mach-msm/acpuclock-fsm9xxx.c b/arch/arm/mach-msm/acpuclock-fsm9xxx.c
index af1c0eb..6e1eb7e 100644
--- a/arch/arm/mach-msm/acpuclock-fsm9xxx.c
+++ b/arch/arm/mach-msm/acpuclock-fsm9xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/acpuclock-krait.c b/arch/arm/mach-msm/acpuclock-krait.c
index 10c4d6c..9566cea 100644
--- a/arch/arm/mach-msm/acpuclock-krait.c
+++ b/arch/arm/mach-msm/acpuclock-krait.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -1019,7 +1019,7 @@
 	.notifier_call = acpuclk_cpu_callback,
 };
 
-static const int krait_needs_vmin(void)
+static const int __init krait_needs_vmin(void)
 {
 	switch (read_cpuid_id()) {
 	case 0x511F04D0: /* KR28M2A20 */
@@ -1031,7 +1031,7 @@
 	};
 }
 
-static void krait_apply_vmin(struct acpu_level *tbl)
+static void __init krait_apply_vmin(struct acpu_level *tbl)
 {
 	for (; tbl->speed.khz != 0; tbl++) {
 		if (tbl->vdd_core < 1150000)
@@ -1040,62 +1040,78 @@
 	}
 }
 
-static int __init get_speed_bin(u32 pte_efuse)
+void __init get_krait_bin_format_a(void __iomem *base, struct bin_info *bin)
 {
-	uint32_t speed_bin;
+	u32 pte_efuse = readl_relaxed(base);
 
-	speed_bin = pte_efuse & 0xF;
-	if (speed_bin == 0xF)
-		speed_bin = (pte_efuse >> 4) & 0xF;
+	bin->speed = pte_efuse & 0xF;
+	if (bin->speed == 0xF)
+		bin->speed = (pte_efuse >> 4) & 0xF;
+	bin->speed_valid = bin->speed != 0xF;
 
-	if (speed_bin == 0xF) {
-		speed_bin = 0;
-		dev_warn(drv.dev, "SPEED BIN: Defaulting to %d\n", speed_bin);
-	} else {
-		dev_info(drv.dev, "SPEED BIN: %d\n", speed_bin);
-	}
-
-	return speed_bin;
+	bin->pvs = (pte_efuse >> 10) & 0x7;
+	if (bin->pvs == 0x7)
+		bin->pvs = (pte_efuse >> 13) & 0x7;
+	bin->pvs_valid = bin->pvs != 0x7;
 }
 
-static int __init get_pvs_bin(u32 pte_efuse)
+void __init get_krait_bin_format_b(void __iomem *base, struct bin_info *bin)
 {
-	uint32_t pvs_bin;
+	u32 pte_efuse, redundant_sel;
 
-	pvs_bin = (pte_efuse >> 10) & 0x7;
-	if (pvs_bin == 0x7)
-		pvs_bin = (pte_efuse >> 13) & 0x7;
+	pte_efuse = readl_relaxed(base);
+	redundant_sel = (pte_efuse >> 24) & 0x7;
+	bin->speed = pte_efuse & 0x7;
+	bin->pvs = (pte_efuse >> 6) & 0x7;
 
-	if (pvs_bin == 0x7) {
-		pvs_bin = 0;
-		dev_warn(drv.dev, "ACPU PVS: Defaulting to %d\n", pvs_bin);
-	} else {
-		dev_info(drv.dev, "ACPU PVS: %d\n", pvs_bin);
+	switch (redundant_sel) {
+	case 1:
+		bin->speed = (pte_efuse >> 27) & 0x7;
+		break;
+	case 2:
+		bin->pvs = (pte_efuse >> 27) & 0x7;
+		break;
 	}
+	bin->speed_valid = true;
 
-	return pvs_bin;
+	/* Check PVS_BLOW_STATUS */
+	pte_efuse = readl_relaxed(base + 0x4);
+	bin->pvs_valid = !!(pte_efuse & BIT(21));
 }
 
-static struct pvs_table * __init select_freq_plan(u32 pte_efuse_phys,
-			struct pvs_table (*pvs_tables)[NUM_PVS])
+static struct pvs_table * __init select_freq_plan(
+		const struct acpuclk_krait_params *params)
 {
-	void __iomem *pte_efuse;
-	u32 pte_efuse_val;
+	void __iomem *pte_efuse_base;
+	struct bin_info bin;
 
-	pte_efuse = ioremap(pte_efuse_phys, 4);
-	if (!pte_efuse) {
-		dev_err(drv.dev, "Unable to map QFPROM base\n");
+	pte_efuse_base = ioremap(params->pte_efuse_phys, 8);
+	if (!pte_efuse_base) {
+		dev_err(drv.dev, "Unable to map PTE eFuse base\n");
 		return NULL;
 	}
+	params->get_bin_info(pte_efuse_base, &bin);
+	iounmap(pte_efuse_base);
 
-	pte_efuse_val = readl_relaxed(pte_efuse);
-	iounmap(pte_efuse);
+	if (bin.speed_valid) {
+		drv.speed_bin = bin.speed;
+		dev_info(drv.dev, "SPEED BIN: %d\n", drv.speed_bin);
+	} else {
+		drv.speed_bin = 0;
+		dev_warn(drv.dev, "SPEED BIN: Defaulting to %d\n",
+			 drv.speed_bin);
+	}
 
-	/* Select frequency tables. */
-	drv.speed_bin = get_speed_bin(pte_efuse_val);
-	drv.pvs_bin = get_pvs_bin(pte_efuse_val);
+	if (bin.pvs_valid) {
+		drv.pvs_bin = bin.pvs;
+		dev_info(drv.dev, "ACPU PVS: %d\n", drv.pvs_bin);
+	} else {
+		drv.pvs_bin = 0;
+		dev_warn(drv.dev, "ACPU PVS: Defaulting to %d\n",
+			 drv.pvs_bin);
+	}
 
-	return &pvs_tables[drv.speed_bin][drv.pvs_bin];
+	return &params->pvs_tables[drv.speed_bin][drv.pvs_bin];
 }
 
 static void __init drv_data_init(struct device *dev,
@@ -1124,7 +1140,7 @@
 		GFP_KERNEL);
 	BUG_ON(!drv.bus_scale->usecase);
 
-	pvs = select_freq_plan(params->pte_efuse_phys, params->pvs_tables);
+	pvs = select_freq_plan(params);
 	BUG_ON(!pvs->table);
 
 	drv.acpu_freq_tbl = kmemdup(pvs->table, pvs->size, GFP_KERNEL);
diff --git a/arch/arm/mach-msm/acpuclock-krait.h b/arch/arm/mach-msm/acpuclock-krait.h
index ca8013e..11d58dd 100644
--- a/arch/arm/mach-msm/acpuclock-krait.h
+++ b/arch/arm/mach-msm/acpuclock-krait.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -50,7 +50,7 @@
 	PVS_NOMINAL = 1,
 	PVS_FAST = 3,
 	PVS_FASTER = 4,
-	NUM_PVS = 7
+	NUM_PVS = 8
 };
 
 /**
@@ -152,7 +152,7 @@
 struct acpu_level {
 	const int use_for_scaling;
 	const struct core_speed speed;
-	const unsigned int l2_level;
+	unsigned int l2_level;
 	int vdd_core;
 	int ua_core;
 	unsigned int avsdscr_setting;
@@ -227,6 +227,20 @@
 };
 
 /**
+ * struct bin_info - Hardware speed and voltage binning info.
+ * @speed_valid: @speed field is valid
+ * @pvs_valid: @pvs field is valid
+ * @speed: Speed bin ID
+ * @pvs: PVS bin ID
+ */
+struct bin_info {
+	bool speed_valid;
+	bool pvs_valid;
+	int speed;
+	int pvs;
+};
+
+/**
  * struct pvs_table - CPU performance level table and size.
  * @table: CPU performance level table
  * @size: sizeof(@table)
@@ -247,6 +261,7 @@
  * @l2_freq_tbl: L2 frequency table.
  * @l2_freq_tbl_size: Size of @l2_freq_tbl.
  * @pte_efuse_phys: Physical address of PTE EFUSE.
+ * @get_bin_info: Function to populate bin_info from pte_efuse.
  * @bus_scale: MSM bus driver parameters.
  * @stby_khz: KHz value corresponding to an always-on clock source.
  */
@@ -258,6 +273,7 @@
 	struct l2_level *l2_freq_tbl;
 	size_t l2_freq_tbl_size;
 	phys_addr_t pte_efuse_phys;
+	void (*get_bin_info)(void __iomem *base, struct bin_info *bin);
 	struct msm_bus_scale_pdata *bus_scale;
 	unsigned long stby_khz;
 };
@@ -297,6 +313,16 @@
 };
 
 /**
+ * get_krait_bin_format_a - Populate bin_info from a 'Format A' pte_efuse
+ */
+void __init get_krait_bin_format_a(void __iomem *base, struct bin_info *bin);
+
+/**
+ * get_krait_bin_format_b - Populate bin_info from a 'Format B' pte_efuse
+ */
+void __init get_krait_bin_format_b(void __iomem *base, struct bin_info *bin);
+
+/**
  * acpuclk_krait_init - Initialize the Krait CPU clock driver give SoC params.
  */
 extern int acpuclk_krait_init(struct device *dev,
diff --git a/arch/arm/mach-msm/acpuclock.c b/arch/arm/mach-msm/acpuclock.c
index 2b33c4c..13c7b21 100644
--- a/arch/arm/mach-msm/acpuclock.c
+++ b/arch/arm/mach-msm/acpuclock.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/acpuclock.h b/arch/arm/mach-msm/acpuclock.h
index 841f717..510a62e 100644
--- a/arch/arm/mach-msm/acpuclock.h
+++ b/arch/arm/mach-msm/acpuclock.h
@@ -2,7 +2,7 @@
  * MSM architecture CPU clock driver header
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
  * Author: San Mehat <san@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/arch-init-scorpion.S b/arch/arm/mach-msm/arch-init-scorpion.S
index 82a6db8..db0a1e6 100644
--- a/arch/arm/mach-msm/arch-init-scorpion.S
+++ b/arch/arm/mach-msm/arch-init-scorpion.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  * Copyright (c) 2008-2009, Google Inc.
  * All rights reserved.
  *
diff --git a/arch/arm/mach-msm/audio-7627a-devices.c b/arch/arm/mach-msm/audio-7627a-devices.c
index 3a636e8..61d06e7 100644
--- a/arch/arm/mach-msm/audio-7627a-devices.c
+++ b/arch/arm/mach-msm/audio-7627a-devices.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index c475e2d..833b213 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -28,7 +28,7 @@
 #include <linux/wakelock.h>
 #include <linux/kfifo.h>
 #include <linux/of.h>
-
+#include <mach/msm_ipc_logging.h>
 #include <mach/sps.h>
 #include <mach/bam_dmux.h>
 #include <mach/msm_smsm.h>
@@ -269,6 +269,8 @@
 static DEFINE_MUTEX(delayed_ul_vote_lock);
 static int need_delayed_ul_vote;
 static int power_management_only_mode;
+static int in_ssr;
+static int ssr_skipped_disconnect;
 
 struct outside_notify_func {
 	void (*notify)(void *, int, unsigned long);
@@ -300,93 +302,56 @@
 #define bam_ch_is_in_reset(x)			\
 	(bam_ch[(x)].status & BAM_CH_IN_RESET)
 
-#define LOG_MESSAGE_MAX_SIZE 80
 struct kfifo bam_dmux_state_log;
-static uint32_t bam_dmux_state_logging_disabled;
-static DEFINE_SPINLOCK(bam_dmux_logging_spinlock);
 static int bam_dmux_uplink_vote;
 static int bam_dmux_power_state;
 
-static void bam_dmux_log(const char *fmt, ...)
-					__printf(1, 2);
+static void *bam_ipc_log_txt;
 
-
-#define DMUX_LOG_KERR(fmt...) \
-do { \
-	bam_dmux_log(fmt); \
-	pr_err(fmt); \
-} while (0)
+#define BAM_IPC_LOG_PAGES 5
 
 /**
  * Log a state change along with a small message.
- *
  * Complete size of messsage is limited to @todo.
+ * Logging is done using IPC Logging infrastructure.
+ *
+ * States
+ * D: 1 = Power collapse disabled
+ * R: 1 = in global reset
+ * P: 1 = BAM is powered up
+ * A: 1 = BAM initialized and ready for data
+ * V: 1 = Uplink vote for power
+ * U: 1 = Uplink active
+ * W: 1 = Uplink Wait-for-ack
+ * A: 1 = Uplink ACK received
+ * #: >=1 On-demand uplink vote
+ * D: 1 = Disconnect ACK active
  */
-static void bam_dmux_log(const char *fmt, ...)
-{
-	char buff[LOG_MESSAGE_MAX_SIZE];
-	unsigned long flags;
-	va_list arg_list;
-	unsigned long long t_now;
-	unsigned long nanosec_rem;
-	int len = 0;
 
-	if (bam_dmux_state_logging_disabled)
-		return;
+#define BAM_DMUX_LOG(fmt, args...) \
+do { \
+	if (bam_ipc_log_txt) { \
+		ipc_log_string(bam_ipc_log_txt, \
+		"<DMUX> %c%c%c%c %c%c%c%c%d%c " fmt, \
+		a2_pc_disabled ? 'D' : 'd', \
+		in_global_reset ? 'R' : 'r', \
+		bam_dmux_power_state ? 'P' : 'p', \
+		bam_connection_is_active ? 'A' : 'a', \
+		bam_dmux_uplink_vote ? 'V' : 'v', \
+		bam_is_connected ?  'U' : 'u', \
+		wait_for_ack ? 'W' : 'w', \
+		ul_wakeup_ack_completion.done ? 'A' : 'a', \
+		atomic_read(&ul_ondemand_vote), \
+		disconnect_ack ? 'D' : 'd', \
+		args); \
+	} \
+} while (0)
 
-	t_now = sched_clock();
-	nanosec_rem = do_div(t_now, 1000000000U);
-
-	/*
-	 * States
-	 * D: 1 = Power collapse disabled
-	 * R: 1 = in global reset
-	 * P: 1 = BAM is powered up
-	 * A: 1 = BAM initialized and ready for data
-	 *
-	 * V: 1 = Uplink vote for power
-	 * U: 1 = Uplink active
-	 * W: 1 = Uplink Wait-for-ack
-	 * A: 1 = Uplink ACK received
-	 * #: >=1 On-demand uplink vote
-	 * D: 1 = Disconnect ACK active
-	 */
-	len += scnprintf(buff, sizeof(buff),
-		"<DMUX> %u.%09lu %c%c%c%c %c%c%c%c%d%c ",
-		(unsigned)t_now, nanosec_rem,
-		a2_pc_disabled ? 'D' : 'd',
-		in_global_reset ? 'R' : 'r',
-		bam_dmux_power_state ? 'P' : 'p',
-		bam_connection_is_active ? 'A' : 'a',
-		bam_dmux_uplink_vote ? 'V' : 'v',
-		bam_is_connected ?  'U' : 'u',
-		wait_for_ack ? 'W' : 'w',
-		ul_wakeup_ack_completion.done ? 'A' : 'a',
-		atomic_read(&ul_ondemand_vote),
-		disconnect_ack ? 'D' : 'd'
-		);
-
-	va_start(arg_list, fmt);
-	len += vscnprintf(buff + len, sizeof(buff) - len, fmt, arg_list);
-	va_end(arg_list);
-	memset(buff + len, 0x0, sizeof(buff) - len);
-
-	spin_lock_irqsave(&bam_dmux_logging_spinlock, flags);
-	if (kfifo_avail(&bam_dmux_state_log) < LOG_MESSAGE_MAX_SIZE) {
-		char junk[LOG_MESSAGE_MAX_SIZE];
-		int ret;
-
-		ret = kfifo_out(&bam_dmux_state_log, junk, sizeof(junk));
-		if (ret != LOG_MESSAGE_MAX_SIZE) {
-			pr_err("%s: unable to empty log %d\n", __func__, ret);
-			spin_unlock_irqrestore(&bam_dmux_logging_spinlock,
-					flags);
-			return;
-		}
-	}
-	kfifo_in(&bam_dmux_state_log, buff, sizeof(buff));
-	spin_unlock_irqrestore(&bam_dmux_logging_spinlock, flags);
-}
+#define DMUX_LOG_KERR(fmt, args...) \
+do { \
+	BAM_DMUX_LOG(fmt, args); \
+	pr_err(fmt, args); \
+} while (0)
 
 static inline void set_tx_timestamp(struct tx_pkt_info *pkt)
 {
@@ -406,12 +371,12 @@
 	spin_lock_irqsave(&bam_tx_pool_spinlock, flags);
 	list_for_each_entry(info, &bam_tx_pool, list_node) {
 		if (!reported) {
-			bam_dmux_log("%s: tx pool not empty\n", func);
+			BAM_DMUX_LOG("%s: tx pool not empty\n", func);
 			if (!in_global_reset)
 				pr_err("%s: tx pool not empty\n", func);
 			reported = 1;
 		}
-		bam_dmux_log("%s: node=%p ts=%u.%09lu\n", __func__,
+		BAM_DMUX_LOG("%s: node=%p ts=%u.%09lu\n", __func__,
 			&info->list_node, info->ts_sec, info->ts_nsec);
 		if (!in_global_reset)
 			pr_err("%s: node=%p ts=%u.%09lu\n", __func__,
@@ -494,7 +459,7 @@
 	kfree(info);
 
 fail:
-	if (rx_len_cached == 0) {
+	if (rx_len_cached == 0 && !in_global_reset) {
 		DMUX_LOG_KERR("%s: rescheduling\n", __func__);
 		schedule_delayed_work(&queue_rx_work, msecs_to_jiffies(100));
 	}
@@ -539,7 +504,7 @@
 
 	mutex_lock(&bam_pdev_mutexlock);
 	if (in_global_reset) {
-		bam_dmux_log("%s: open cid %d aborted due to ssr\n",
+		BAM_DMUX_LOG("%s: open cid %d aborted due to ssr\n",
 				__func__, rx_hdr->ch_id);
 		mutex_unlock(&bam_pdev_mutexlock);
 		queue_rx();
@@ -603,18 +568,18 @@
 		bam_mux_process_data(rx_skb);
 		break;
 	case BAM_MUX_HDR_CMD_OPEN:
-		bam_dmux_log("%s: opening cid %d PC enabled\n", __func__,
+		BAM_DMUX_LOG("%s: opening cid %d PC enabled\n", __func__,
 				rx_hdr->ch_id);
 		handle_bam_mux_cmd_open(rx_hdr);
 		if (!(rx_hdr->reserved & ENABLE_DISCONNECT_ACK)) {
-			bam_dmux_log("%s: deactivating disconnect ack\n",
+			BAM_DMUX_LOG("%s: deactivating disconnect ack\n",
 								__func__);
 			disconnect_ack = 0;
 		}
 		dev_kfree_skb_any(rx_skb);
 		break;
 	case BAM_MUX_HDR_CMD_OPEN_NO_A2_PC:
-		bam_dmux_log("%s: opening cid %d PC disabled\n", __func__,
+		BAM_DMUX_LOG("%s: opening cid %d PC disabled\n", __func__,
 				rx_hdr->ch_id);
 
 		if (!a2_pc_disabled) {
@@ -627,11 +592,11 @@
 		break;
 	case BAM_MUX_HDR_CMD_CLOSE:
 		/* probably should drop pending write */
-		bam_dmux_log("%s: closing cid %d\n", __func__,
+		BAM_DMUX_LOG("%s: closing cid %d\n", __func__,
 				rx_hdr->ch_id);
 		mutex_lock(&bam_pdev_mutexlock);
 		if (in_global_reset) {
-			bam_dmux_log("%s: close cid %d aborted due to ssr\n",
+			BAM_DMUX_LOG("%s: close cid %d aborted due to ssr\n",
 					__func__, rx_hdr->ch_id);
 			mutex_unlock(&bam_pdev_mutexlock);
 			break;
@@ -889,6 +854,7 @@
 write_fail3:
 	kfree(pkt);
 write_fail2:
+	skb_pull(skb, sizeof(struct bam_mux_hdr));
 	if (new_skb)
 		dev_kfree_skb_any(new_skb);
 write_fail:
@@ -1375,60 +1341,6 @@
 	return i;
 }
 
-static int debug_log(char *buff, int max, loff_t *ppos)
-{
-	unsigned long flags;
-	int i = 0;
-
-	if (bam_dmux_state_logging_disabled) {
-		i += scnprintf(buff - i, max - i, "Logging disabled\n");
-		return i;
-	}
-
-	if (*ppos == 0) {
-		i += scnprintf(buff - i, max - i,
-			"<DMUX> timestamp FLAGS [Message]\n"
-			"FLAGS:\n"
-			"\tD: 1 = Power collapse disabled\n"
-			"\tR: 1 = in global reset\n"
-			"\tP: 1 = BAM is powered up\n"
-			"\tA: 1 = BAM initialized and ready for data\n"
-			"\n"
-			"\tV: 1 = Uplink vote for power\n"
-			"\tU: 1 = Uplink active\n"
-			"\tW: 1 = Uplink Wait-for-ack\n"
-			"\tA: 1 = Uplink ACK received\n"
-			"\t#: >=1 On-demand uplink vote\n"
-			"\tD: 1 = Disconnect ACK active\n"
-				);
-		buff += i;
-	}
-
-	spin_lock_irqsave(&bam_dmux_logging_spinlock, flags);
-	while (kfifo_len(&bam_dmux_state_log)
-			&& (i + LOG_MESSAGE_MAX_SIZE) < max) {
-		int k_len;
-		k_len = kfifo_out(&bam_dmux_state_log,
-				buff, LOG_MESSAGE_MAX_SIZE);
-		if (k_len != LOG_MESSAGE_MAX_SIZE) {
-			pr_err("%s: retrieve failure %d\n", __func__, k_len);
-			break;
-		}
-
-		/* keep non-null portion of string and add line break */
-		k_len = strnlen(buff, LOG_MESSAGE_MAX_SIZE);
-		buff += k_len;
-		i += k_len;
-		if (k_len && *(buff - 1) != '\n') {
-			*buff++ = '\n';
-			++i;
-		}
-	}
-	spin_unlock_irqrestore(&bam_dmux_logging_spinlock, flags);
-
-	return i;
-}
-
 #define DEBUG_BUFMAX 4096
 static char debug_buffer[DEBUG_BUFMAX];
 
@@ -1440,30 +1352,6 @@
 	return simple_read_from_buffer(buf, count, ppos, debug_buffer, bsize);
 }
 
-static ssize_t debug_read_multiple(struct file *file, char __user *buff,
-				size_t count, loff_t *ppos)
-{
-	int (*util_func)(char *buf, int max, loff_t *) = file->private_data;
-	char *buffer;
-	int bsize;
-
-	buffer = kmalloc(count, GFP_KERNEL);
-	if (!buffer)
-		return -ENOMEM;
-
-	bsize = util_func(buffer, count, ppos);
-
-	if (bsize >= 0) {
-		if (copy_to_user(buff, buffer, bsize)) {
-			kfree(buffer);
-			return -EFAULT;
-		}
-		*ppos += bsize;
-	}
-	kfree(buffer);
-	return bsize;
-}
-
 static int debug_open(struct inode *inode, struct file *file)
 {
 	file->private_data = inode->i_private;
@@ -1476,11 +1364,6 @@
 	.open = debug_open,
 };
 
-static const struct file_operations debug_ops_multiple = {
-	.read = debug_read_multiple,
-	.open = debug_open,
-};
-
 static void debug_create(const char *name, mode_t mode,
 				struct dentry *dent,
 				int (*fill)(char *buf, int max))
@@ -1493,17 +1376,6 @@
 				(int)PTR_ERR(file));
 }
 
-static void debug_create_multiple(const char *name, mode_t mode,
-				struct dentry *dent,
-				int (*fill)(char *buf, int max, loff_t *ppos))
-{
-	struct dentry *file;
-
-	file = debugfs_create_file(name, mode, dent, fill, &debug_ops_multiple);
-	if (IS_ERR(file))
-		pr_err("%s: debugfs create failed %d\n", __func__,
-				(int)PTR_ERR(file));
-}
 #endif
 
 static void notify_all(int event, unsigned long data)
@@ -1515,7 +1387,7 @@
 	for (i = 0; i < BAM_DMUX_NUM_CHANNELS; ++i) {
 		if (bam_ch_is_open(i)) {
 			bam_ch[i].notify(bam_ch[i].priv, event, data);
-			bam_dmux_log("%s: cid=%d, event=%d, data=%lu\n",
+			BAM_DMUX_LOG("%s: cid=%d, event=%d, data=%lu\n",
 					__func__, i, event, data);
 		}
 	}
@@ -1558,11 +1430,11 @@
 
 static void power_vote(int vote)
 {
-	bam_dmux_log("%s: curr=%d, vote=%d\n", __func__,
+	BAM_DMUX_LOG("%s: curr=%d, vote=%d\n", __func__,
 			bam_dmux_uplink_vote, vote);
 
 	if (bam_dmux_uplink_vote == vote)
-		bam_dmux_log("%s: warning - duplicate power vote\n", __func__);
+		BAM_DMUX_LOG("%s: warning - duplicate power vote\n", __func__);
 
 	bam_dmux_uplink_vote = vote;
 	if (vote)
@@ -1576,7 +1448,7 @@
  */
 static inline void ul_powerdown(void)
 {
-	bam_dmux_log("%s: powerdown\n", __func__);
+	BAM_DMUX_LOG("%s: powerdown\n", __func__);
 	verify_tx_queue_is_empty(__func__);
 
 	if (a2_pc_disabled) {
@@ -1688,7 +1560,7 @@
 		}
 
 		if (ul_packet_written || atomic_read(&ul_ondemand_vote)) {
-			bam_dmux_log("%s: pkt written %d\n",
+			BAM_DMUX_LOG("%s: pkt written %d\n",
 				__func__, ul_packet_written);
 			ul_packet_written = 0;
 			schedule_delayed_work(&ul_timeout_work,
@@ -1717,7 +1589,7 @@
 
 	mutex_lock(&wakeup_lock);
 	if (bam_is_connected) { /* bam got connected before lock grabbed */
-		bam_dmux_log("%s Already awake\n", __func__);
+		BAM_DMUX_LOG("%s Already awake\n", __func__);
 		mutex_unlock(&wakeup_lock);
 		return;
 	}
@@ -1780,35 +1652,35 @@
 	 * instead of waiting
 	 */
 	if (wait_for_ack) {
-		bam_dmux_log("%s waiting for previous ack\n", __func__);
+		BAM_DMUX_LOG("%s waiting for previous ack\n", __func__);
 		ret = wait_for_completion_timeout(
 					&ul_wakeup_ack_completion, HZ);
 		wait_for_ack = 0;
 		if (unlikely(ret == 0) && ssrestart_check()) {
 			mutex_unlock(&wakeup_lock);
-			bam_dmux_log("%s timeout previous ack\n", __func__);
+			BAM_DMUX_LOG("%s timeout previous ack\n", __func__);
 			return;
 		}
 	}
 	INIT_COMPLETION(ul_wakeup_ack_completion);
 	power_vote(1);
-	bam_dmux_log("%s waiting for wakeup ack\n", __func__);
+	BAM_DMUX_LOG("%s waiting for wakeup ack\n", __func__);
 	ret = wait_for_completion_timeout(&ul_wakeup_ack_completion, HZ);
 	if (unlikely(ret == 0) && ssrestart_check()) {
 		mutex_unlock(&wakeup_lock);
-		bam_dmux_log("%s timeout wakeup ack\n", __func__);
+		BAM_DMUX_LOG("%s timeout wakeup ack\n", __func__);
 		return;
 	}
-	bam_dmux_log("%s waiting completion\n", __func__);
+	BAM_DMUX_LOG("%s waiting completion\n", __func__);
 	ret = wait_for_completion_timeout(&bam_connection_completion, HZ);
 	if (unlikely(ret == 0) && ssrestart_check()) {
 		mutex_unlock(&wakeup_lock);
-		bam_dmux_log("%s timeout power on\n", __func__);
+		BAM_DMUX_LOG("%s timeout power on\n", __func__);
 		return;
 	}
 
 	bam_is_connected = 1;
-	bam_dmux_log("%s complete\n", __func__);
+	BAM_DMUX_LOG("%s complete\n", __func__);
 	schedule_delayed_work(&ul_timeout_work,
 				msecs_to_jiffies(UL_TIMEOUT_DELAY));
 	mutex_unlock(&wakeup_lock);
@@ -1819,12 +1691,17 @@
 	int i;
 
 	in_global_reset = 0;
+	in_ssr = 0;
 	vote_dfab();
 	if (!power_management_only_mode) {
-		sps_disconnect(bam_tx_pipe);
-		sps_disconnect(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);
+		if (ssr_skipped_disconnect) {
+			/* delayed to here to prevent bus stall */
+			sps_disconnect(bam_tx_pipe);
+			sps_disconnect(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);
 		if (i)
 			pr_err("%s: device reset failed rc = %d\n", __func__,
@@ -1869,7 +1746,7 @@
 	/* handle disconnect during active UL */
 	write_lock_irqsave(&ul_wakeup_lock, flags);
 	if (bam_is_connected) {
-		bam_dmux_log("%s: UL active - forcing powerdown\n", __func__);
+		BAM_DMUX_LOG("%s: UL active - forcing powerdown\n", __func__);
 		ul_powerdown();
 	}
 	write_unlock_irqrestore(&ul_wakeup_lock, flags);
@@ -1877,6 +1754,19 @@
 
 	/* tear down BAM connection */
 	INIT_COMPLETION(bam_connection_completion);
+
+	/* in_ssr documentation/assumptions found in restart_notifier_cb */
+	if (!power_management_only_mode) {
+		if (likely(!in_ssr)) {
+			sps_disconnect(bam_tx_pipe);
+			sps_disconnect(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);
+			sps_device_reset(a2_device_handle);
+		} else {
+			ssr_skipped_disconnect = 1;
+		}
+	}
 	unvote_dfab();
 
 	mutex_lock(&bam_rx_pool_mutexlock);
@@ -1902,10 +1792,10 @@
 {
 	int rc;
 
-	bam_dmux_log("%s\n", __func__);
+	BAM_DMUX_LOG("%s\n", __func__);
 	mutex_lock(&dfab_status_lock);
 	if (dfab_is_on) {
-		bam_dmux_log("%s: dfab is already on\n", __func__);
+		BAM_DMUX_LOG("%s: dfab is already on\n", __func__);
 		mutex_unlock(&dfab_status_lock);
 		return;
 	}
@@ -1927,7 +1817,7 @@
 
 static void unvote_dfab(void)
 {
-	bam_dmux_log("%s\n", __func__);
+	BAM_DMUX_LOG("%s\n", __func__);
 	mutex_lock(&dfab_status_lock);
 	if (!dfab_is_on) {
 		DMUX_LOG_KERR("%s: dfab is already off\n", __func__);
@@ -1949,7 +1839,7 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&wakelock_reference_lock, flags);
-	bam_dmux_log("%s: ref count = %d\n", __func__,
+	BAM_DMUX_LOG("%s: ref count = %d\n", __func__,
 						wakelock_reference_count);
 	if (wakelock_reference_count == 0)
 		wake_lock(&bam_wakelock);
@@ -1968,7 +1858,7 @@
 		spin_unlock_irqrestore(&wakelock_reference_lock, flags);
 		return;
 	}
-	bam_dmux_log("%s: ref count = %d\n", __func__,
+	BAM_DMUX_LOG("%s: ref count = %d\n", __func__,
 						wakelock_reference_count);
 	--wakelock_reference_count;
 	if (wakelock_reference_count == 0)
@@ -1986,12 +1876,28 @@
 	int temp_remote_status;
 	unsigned long flags;
 
+	/*
+	 * Bam_dmux counts on the fact that the BEFORE_SHUTDOWN level of
+	 * notifications are guarenteed to execute before the AFTER_SHUTDOWN
+	 * level of notifications, and that BEFORE_SHUTDOWN always occurs in
+	 * all SSR events, no matter what triggered the SSR.  Also, bam_dmux
+	 * assumes that SMD does its SSR processing in the AFTER_SHUTDOWN level
+	 * thus bam_dmux is guarenteed to detect SSR before SMD, since the
+	 * callbacks for all the drivers within the AFTER_SHUTDOWN level could
+	 * occur in any order.  Bam_dmux uses this knowledge to skip accessing
+	 * the bam hardware when disconnect_to_bam() is triggered by SMD's SSR
+	 * processing.  We do not wat to access the bam hardware during SSR
+	 * because a watchdog crash from a bus stall would likely occur.
+	 */
+	if (code == SUBSYS_BEFORE_SHUTDOWN) {
+		in_global_reset = 1;
+		in_ssr = 1;
+		BAM_DMUX_LOG("%s: begin\n", __func__);
+		flush_workqueue(bam_mux_rx_workqueue);
+	}
 	if (code != SUBSYS_AFTER_SHUTDOWN)
 		return NOTIFY_DONE;
 
-	bam_dmux_log("%s: begin\n", __func__);
-	in_global_reset = 1;
-
 	/* Handle uplink Powerdown */
 	write_lock_irqsave(&ul_wakeup_lock, flags);
 	if (bam_is_connected) {
@@ -2047,7 +1953,7 @@
 	}
 	spin_unlock_irqrestore(&bam_tx_pool_spinlock, flags);
 
-	bam_dmux_log("%s: complete\n", __func__);
+	BAM_DMUX_LOG("%s: complete\n", __func__);
 	return NOTIFY_DONE;
 }
 
@@ -2294,7 +2200,7 @@
 {
 	static unsigned int clear_bit; /* 0 = set the bit, else clear bit */
 
-	bam_dmux_log("%s: apps ack %d->%d\n", __func__,
+	BAM_DMUX_LOG("%s: apps ack %d->%d\n", __func__,
 			clear_bit & 0x1, ~clear_bit & 0x1);
 	smsm_change_state(SMSM_APPS_STATE,
 				clear_bit & SMSM_A2_POWER_CONTROL_ACK,
@@ -2310,10 +2216,10 @@
 	mutex_lock(&smsm_cb_lock);
 	bam_dmux_power_state = new_state & SMSM_A2_POWER_CONTROL ? 1 : 0;
 	DBG_INC_A2_POWER_CONTROL_IN_CNT();
-	bam_dmux_log("%s: 0x%08x -> 0x%08x\n", __func__, old_state,
+	BAM_DMUX_LOG("%s: 0x%08x -> 0x%08x\n", __func__, old_state,
 			new_state);
 	if (last_processed_state == (new_state & SMSM_A2_POWER_CONTROL)) {
-		bam_dmux_log("%s: already processed this state\n", __func__);
+		BAM_DMUX_LOG("%s: already processed this state\n", __func__);
 		mutex_unlock(&smsm_cb_lock);
 		return;
 	}
@@ -2321,23 +2227,23 @@
 	last_processed_state = new_state & SMSM_A2_POWER_CONTROL;
 
 	if (bam_mux_initialized && new_state & SMSM_A2_POWER_CONTROL) {
-		bam_dmux_log("%s: reconnect\n", __func__);
+		BAM_DMUX_LOG("%s: reconnect\n", __func__);
 		grab_wakelock();
 		reconnect_to_bam();
 	} else if (bam_mux_initialized &&
 					!(new_state & SMSM_A2_POWER_CONTROL)) {
-		bam_dmux_log("%s: disconnect\n", __func__);
+		BAM_DMUX_LOG("%s: disconnect\n", __func__);
 		disconnect_to_bam();
 		release_wakelock();
 	} else if (new_state & SMSM_A2_POWER_CONTROL) {
-		bam_dmux_log("%s: init\n", __func__);
+		BAM_DMUX_LOG("%s: init\n", __func__);
 		grab_wakelock();
 		if (cpu_is_msm9615())
 			msm9615_bam_init();
 		else
 			bam_init();
 	} else {
-		bam_dmux_log("%s: bad state change\n", __func__);
+		BAM_DMUX_LOG("%s: bad state change\n", __func__);
 		pr_err("%s: unsupported state change\n", __func__);
 	}
 	mutex_unlock(&smsm_cb_lock);
@@ -2348,7 +2254,7 @@
 						uint32_t new_state)
 {
 	DBG_INC_ACK_IN_CNT();
-	bam_dmux_log("%s: 0x%08x -> 0x%08x\n", __func__, old_state,
+	BAM_DMUX_LOG("%s: 0x%08x -> 0x%08x\n", __func__, old_state,
 			new_state);
 	complete_all(&ul_wakeup_ack_completion);
 }
@@ -2391,12 +2297,12 @@
 
 	xo_clk = clk_get(&pdev->dev, "xo");
 	if (IS_ERR(xo_clk)) {
-		bam_dmux_log("%s: did not get xo clock\n", __func__);
+		BAM_DMUX_LOG("%s: did not get xo clock\n", __func__);
 		xo_clk = NULL;
 	}
 	dfab_clk = clk_get(&pdev->dev, "bus_clk");
 	if (IS_ERR(dfab_clk)) {
-		bam_dmux_log("%s: did not get dfab clock\n", __func__);
+		BAM_DMUX_LOG("%s: did not get dfab clock\n", __func__);
 		dfab_clk = NULL;
 	} else {
 		rc = clk_set_rate(dfab_clk, 64000000);
@@ -2489,7 +2395,6 @@
 
 static int __init bam_dmux_init(void)
 {
-	int ret;
 #ifdef CONFIG_DEBUG_FS
 	struct dentry *dent;
 
@@ -2498,13 +2403,12 @@
 		debug_create("tbl", 0444, dent, debug_tbl);
 		debug_create("ul_pkt_cnt", 0444, dent, debug_ul_pkt_cnt);
 		debug_create("stats", 0444, dent, debug_stats);
-		debug_create_multiple("log", 0444, dent, debug_log);
 	}
 #endif
-	ret = kfifo_alloc(&bam_dmux_state_log, PAGE_SIZE, GFP_KERNEL);
-	if (ret) {
-		pr_err("%s: failed to allocate log %d\n", __func__, ret);
-		bam_dmux_state_logging_disabled = 1;
+
+	bam_ipc_log_txt = ipc_log_context_create(BAM_IPC_LOG_PAGES, "bam_dmux");
+	if (!bam_ipc_log_txt) {
+		pr_err("%s : unable to create IPC Logging Context", __func__);
 	}
 
 	rx_timer_interval = DEFAULT_POLLING_MIN_SLEEP;
diff --git a/arch/arm/mach-msm/bms-batterydata-desay.c b/arch/arm/mach-msm/bms-batterydata-desay.c
index d9fa061..dd3f346 100644
--- a/arch/arm/mach-msm/bms-batterydata-desay.c
+++ b/arch/arm/mach-msm/bms-batterydata-desay.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -83,4 +83,5 @@
 	.pc_temp_ocv_lut	= &desay_5200_pc_temp_ocv,
 	.pc_sf_lut		= &desay_5200_pc_sf,
 	.default_rbatt_mohm	= 156,
+	.rbatt_capacitive_mohm	= 50,
 };
diff --git a/arch/arm/mach-msm/bms-batterydata-oem.c b/arch/arm/mach-msm/bms-batterydata-oem.c
new file mode 100644
index 0000000..036bf88
--- /dev/null
+++ b/arch/arm/mach-msm/bms-batterydata-oem.c
@@ -0,0 +1,108 @@
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/mfd/pm8xxx/batterydata-lib.h>
+
+static struct single_row_lut fcc_temp = {
+	.x		= {-20, 0, 25, 40, 65},
+	.y		= {1492, 1492, 1493, 1483, 1502},
+	.cols	= 5
+};
+
+static struct pc_temp_ocv_lut pc_temp_ocv = {
+	.rows		= 29,
+	.cols		= 5,
+	.temp		= {-20, 0, 25, 40, 65},
+	.percent	= {100, 95, 90, 85, 80, 75, 70, 65, 60, 55, 50, 45, 40,
+					35, 30, 25, 20, 15, 10, 9, 8, 7, 6, 5,
+					4, 3, 2, 1, 0},
+	.ocv		= {
+				{4173, 4167, 4163, 4156, 4154},
+				{4104, 4107, 4108, 4102, 4104},
+				{4057, 4072, 4069, 4061, 4060},
+				{3973, 4009, 4019, 4016, 4020},
+				{3932, 3959, 3981, 3982, 3983},
+				{3899, 3928, 3954, 3950, 3950},
+				{3868, 3895, 3925, 3921, 3920},
+				{3837, 3866, 3898, 3894, 3892},
+				{3812, 3841, 3853, 3856, 3862},
+				{3794, 3818, 3825, 3823, 3822},
+				{3780, 3799, 3804, 3804, 3803},
+				{3768, 3787, 3790, 3788, 3788},
+				{3757, 3779, 3778, 3775, 3776},
+				{3747, 3772, 3771, 3766, 3765},
+				{3736, 3763, 3766, 3760, 3746},
+				{3725, 3749, 3756, 3747, 3729},
+				{3714, 3718, 3734, 3724, 3706},
+				{3701, 3703, 3696, 3689, 3668},
+				{3675, 3695, 3682, 3675, 3662},
+				{3670, 3691, 3680, 3673, 3661},
+				{3661, 3686, 3679, 3672, 3656},
+				{3649, 3680, 3676, 3669, 3641},
+				{3633, 3669, 3667, 3655, 3606},
+				{3610, 3647, 3640, 3620, 3560},
+				{3580, 3607, 3596, 3572, 3501},
+				{3533, 3548, 3537, 3512, 3425},
+				{3457, 3468, 3459, 3429, 3324},
+				{3328, 3348, 3340, 3297, 3172},
+				{3000, 3000, 3000, 3000, 3000}
+	}
+};
+
+static struct sf_lut rbatt_sf = {
+	.rows		= 29,
+	.cols		= 5,
+	/* row_entries are temperature */
+	.row_entries	= {-20, 0, 20, 40, 65},
+	.percent	= {100, 95, 90, 85, 80, 75, 70, 65, 60, 55, 50, 45, 40,
+					35, 30, 25, 20, 15, 10, 9, 8, 7, 6, 5,
+					4, 3, 2, 1, 0},
+	.sf		= {
+				{357, 187, 100, 91, 91},
+				{400, 208, 105, 94, 94},
+				{390, 204, 106, 95, 96},
+				{391, 201, 108, 98, 98},
+				{391, 202, 110, 98, 100},
+				{390, 200, 110, 99, 102},
+				{389, 200, 110, 99, 102},
+				{393, 202, 101, 93, 100},
+				{407, 205, 99, 89, 94},
+				{428, 208, 100, 91, 96},
+				{455, 212, 102, 92, 98},
+				{495, 220, 104, 93, 101},
+				{561, 232, 107, 95, 102},
+				{634, 245, 112, 98, 98},
+				{714, 258, 114, 98, 98},
+				{791, 266, 114, 97, 100},
+				{871, 289, 108, 95, 97},
+				{973, 340, 124, 108, 105},
+				{489, 241, 109, 96, 99},
+				{511, 246, 110, 96, 99},
+				{534, 252, 111, 95, 98},
+				{579, 263, 112, 96, 96},
+				{636, 276, 111, 95, 97},
+				{730, 294, 109, 96, 99},
+				{868, 328, 112, 98, 104},
+				{1089, 374, 119, 101, 115},
+				{1559, 457, 128, 105, 213},
+				{12886, 1026, 637, 422, 3269},
+				{170899, 127211, 98968, 88907, 77102},
+	}
+};
+
+struct bms_battery_data oem_batt_data = {
+	.fcc			= 1500,
+	.fcc_temp_lut		= &fcc_temp,
+	.pc_temp_ocv_lut	= &pc_temp_ocv,
+	.rbatt_sf_lut		= &rbatt_sf,
+	.default_rbatt_mohm	= 236,
+};
diff --git a/arch/arm/mach-msm/bms-batterydata.c b/arch/arm/mach-msm/bms-batterydata.c
index fb4f967..0c39df6 100644
--- a/arch/arm/mach-msm/bms-batterydata.c
+++ b/arch/arm/mach-msm/bms-batterydata.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -105,4 +105,5 @@
 	.pc_temp_ocv_lut	= &pc_temp_ocv,
 	.rbatt_sf_lut		= &rbatt_sf,
 	.default_rbatt_mohm	= 236,
+	.rbatt_capacitive_mohm	= 50,
 };
diff --git a/arch/arm/mach-msm/board-8064-bt.c b/arch/arm/mach-msm/board-8064-bt.c
index a8ae9fa..963b1a3 100644
--- a/arch/arm/mach-msm/board-8064-bt.c
+++ b/arch/arm/mach-msm/board-8064-bt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, 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
@@ -121,7 +121,7 @@
 
 	const struct bahama_config_register *p;
 
-	u8 version;
+	int version;
 
 	const struct bahama_config_register v10_bt_on[] = {
 		{ 0xE9, 0x00, 0xFF },
@@ -203,7 +203,7 @@
 	u8 offset = 0; /* index into bahama configs */
 	on = on ? 1 : 0;
 	version = marimba_read_bahama_ver(&config);
-	if ((int)version < 0 || version == BAHAMA_VER_UNSUPPORTED) {
+	if (version < 0 || version == BAHAMA_VER_UNSUPPORTED) {
 		dev_err(&msm_bt_power_device.dev,
 			"%s : Bahama version read Error, version = %d\n",
 			__func__, version);
@@ -237,10 +237,9 @@
 				__func__, (p+i)->reg,
 				value, (p+i)->mask);
 		value = 0;
-		rc = marimba_read_bit_mask(&config,
+		if (marimba_read_bit_mask(&config,
 				(p+i)->reg, &value,
-				sizeof((p+i)->value), (p+i)->mask);
-		if (rc < 0)
+				sizeof((p+i)->value), (p+i)->mask) < 0)
 			dev_err(&msm_bt_power_device.dev,
 				"%s marimba_read_bit_mask- error",
 				__func__);
@@ -298,15 +297,14 @@
 			dev_err(&msm_bt_power_device.dev,
 				"%s: could not %sable regulator %s: %d\n",
 					__func__, "dis", bt_vregs[i].name, rc);
-			goto reg_disable;
 		}
 	}
 
 	return rc;
 reg_disable:
 	pr_err("bluetooth_switch_regulators - FAIL!!!!\n");
-	while (i) {
-		if (on) {
+	if (on) {
+		while (i) {
 			i--;
 			regulator_disable(bt_vregs[i].reg);
 			regulator_put(bt_vregs[i].reg);
@@ -419,8 +417,9 @@
 	int rc = 0;
 	const char *id = "BTPW";
 	int cid = 0;
+	int bt_state = 0;
+	struct marimba config = { .mod_id =  SLAVE_ID_BAHAMA};
 
-	pr_debug("bluetooth_power entered....\n");
 	cid = adie_get_detected_connectivity_type();
 	if (cid != BAHAMA_ID) {
 		pr_err("%s: unexpected adie connectivity type: %d\n",
@@ -429,6 +428,7 @@
 	}
 
 	if (on) {
+		pr_debug("%s: Powering up the BT module.\n", __func__);
 		rc = bluetooth_switch_regulators(on);
 		if (rc < 0) {
 			pr_err("%s: bluetooth_switch_regulators rc = %d",
@@ -437,11 +437,13 @@
 		}
 		/* UART GPIO configuration to be done by by UART module*/
 		/*Setup BT clocks*/
+		pr_debug("%s: Voting for the 19.2MHz clock\n", __func__);
 		bt_clock = msm_xo_get(MSM_XO_TCXO_A2, id);
 		if (IS_ERR(bt_clock)) {
 			rc = PTR_ERR(bt_clock);
 			pr_err("%s: failed to get the handle for A2(%d)\n",
 					__func__, rc);
+			goto fail_power;
 		}
 		rc = msm_xo_mode_vote(bt_clock, MSM_XO_MODE_ON);
 		if (rc < 0) {
@@ -451,20 +453,23 @@
 		msleep(20);
 
 		/*I2C config for Bahama*/
+		pr_debug("%s: BT Turn On sequence in-progress.\n", __func__);
 		rc = bahama_bt(1);
 		if (rc < 0) {
 			pr_err("%s: bahama_bt rc = %d", __func__, rc);
-			goto fail_i2c;
+			goto fail_xo_vote;
 		}
 		msleep(20);
 
 		/*setup BT PCM lines*/
+		pr_debug("%s: Configuring PCM lines.\n", __func__);
 		rc = config_pcm(BT_PCM_ON);
 		if (rc < 0) {
-			pr_err("%s: config_pcm , rc =%d\n",
+			pr_err("%s: config_pcm , rc = %d\n",
 				__func__, rc);
-				goto fail_power;
+			goto fail_i2c;
 		}
+		pr_debug("%s: BT Turn On complete.\n", __func__);
 		/* TO DO - Enable PIN CTRL */
 		/*
 		rc = msm_xo_mode_vote(bt_clock, MSM_XO_MODE_PIN_CTRL);
@@ -474,9 +479,12 @@
 			goto fail_xo_vote;
 		} */
 	} else {
-		rc = bahama_bt(0);
-		if (rc < 0)
-			pr_err("%s: bahama_bt rc = %d", __func__, rc);
+		pr_debug("%s: Turning BT Off.\n", __func__);
+		bt_state = marimba_get_bt_status(&config);
+		if (!bt_state) {
+			pr_err("%s: BT is already turned OFF.\n", __func__);
+			return 0;
+		}
 
 		rc = config_pcm(BT_PCM_OFF);
 		if (rc < 0) {
@@ -484,19 +492,21 @@
 				__func__, rc);
 		}
 fail_i2c:
-		pr_err("bluetooth_power...FAIL_I2C\n");
-
+		rc = bahama_bt(0);
+		if (rc < 0)
+			pr_err("%s: bahama_bt rc = %d", __func__, rc);
 fail_xo_vote:
-		pr_err("bluetooth_power...FAIL_XO_VOTE\n");
+		pr_debug("%s: Voting off the 19.2MHz clk\n", __func__);
 		msm_xo_put(bt_clock);
 fail_power:
-		pr_err("bluetooth_power...FAIL POWER\n");
+		pr_debug("%s: Switching off voltage regulators.\n", __func__);
 		rc = bluetooth_switch_regulators(0);
 		if (rc < 0) {
 			pr_err("%s: switch_regulators : rc = %d",\
 				__func__, rc);
 			goto exit;
 		}
+		pr_debug("%s: BT Power Off complete.\n", __func__);
 	}
 	return rc;
 exit:
diff --git a/arch/arm/mach-msm/board-8064-camera.c b/arch/arm/mach-msm/board-8064-camera.c
index 76d2844..6de7708 100644
--- a/arch/arm/mach-msm/board-8064-camera.c
+++ b/arch/arm/mach-msm/board-8064-camera.c
@@ -543,6 +543,7 @@
 	.csi_if = 1,
 	.camera_type = BACK_CAMERA_2D,
 	.sensor_type = BAYER_SENSOR,
+	.actuator_info = &msm_act_main_cam_1_info,
 };
 
 static struct i2c_board_info sc628a_flash_i2c_info = {
diff --git a/arch/arm/mach-msm/board-8064-display.c b/arch/arm/mach-msm/board-8064-display.c
index b717973..415bc8d 100644
--- a/arch/arm/mach-msm/board-8064-display.c
+++ b/arch/arm/mach-msm/board-8064-display.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -818,12 +818,13 @@
 		return 0;
 
 	/* TBD: PM8921 regulator instead of 8901 */
-	if (!reg_ext_3p3v) {
+	if (!reg_ext_3p3v &&
+		(!(machine_is_mpq8064_hrd() || machine_is_mpq8064_dtv()))) {
 		reg_ext_3p3v = regulator_get(&hdmi_msm_device.dev,
-					     "hdmi_mux_vdd");
+						"hdmi_mux_vdd");
 		if (IS_ERR_OR_NULL(reg_ext_3p3v)) {
 			pr_err("could not get reg_ext_3p3v, rc = %ld\n",
-			       PTR_ERR(reg_ext_3p3v));
+				PTR_ERR(reg_ext_3p3v));
 			reg_ext_3p3v = NULL;
 			return -ENODEV;
 		}
@@ -831,7 +832,7 @@
 
 	if (!reg_8921_lvs7) {
 		reg_8921_lvs7 = regulator_get(&hdmi_msm_device.dev,
-					      "hdmi_vdda");
+						"hdmi_vdda");
 		if (IS_ERR(reg_8921_lvs7)) {
 			pr_err("could not get reg_8921_lvs7, rc = %ld\n",
 				PTR_ERR(reg_8921_lvs7));
@@ -841,7 +842,7 @@
 	}
 	if (!reg_8921_s4) {
 		reg_8921_s4 = regulator_get(&hdmi_msm_device.dev,
-					    "hdmi_lvl_tsl");
+						"hdmi_lvl_tsl");
 		if (IS_ERR(reg_8921_s4)) {
 			pr_err("could not get reg_8921_s4, rc = %ld\n",
 				PTR_ERR(reg_8921_s4));
@@ -860,17 +861,22 @@
 		 * Configure 3P3V_BOOST_EN as GPIO, 8mA drive strength,
 		 * pull none, out-high
 		 */
-		rc = regulator_set_optimum_mode(reg_ext_3p3v, 290000);
-		if (rc < 0) {
-			pr_err("set_optimum_mode ext_3p3v failed, rc=%d\n", rc);
-			return -EINVAL;
+		if (!(machine_is_mpq8064_hrd() || machine_is_mpq8064_dtv())) {
+			rc = regulator_set_optimum_mode(reg_ext_3p3v, 290000);
+			if (rc < 0) {
+				pr_err("set_optimum_mode ext_3p3v failed," \
+					"rc=%d\n", rc);
+				return -EINVAL;
+			}
+
+			rc = regulator_enable(reg_ext_3p3v);
+			if (rc) {
+				pr_err("enable reg_ext_3p3v failed, rc=%d\n",
+					rc);
+				return rc;
+			}
 		}
 
-		rc = regulator_enable(reg_ext_3p3v);
-		if (rc) {
-			pr_err("enable reg_ext_3p3v failed, rc=%d\n", rc);
-			return rc;
-		}
 		rc = regulator_enable(reg_8921_lvs7);
 		if (rc) {
 			pr_err("'%s' regulator enable failed, rc=%d\n",
@@ -885,11 +891,15 @@
 		}
 		pr_debug("%s(on): success\n", __func__);
 	} else {
-		rc = regulator_disable(reg_ext_3p3v);
-		if (rc) {
-			pr_err("disable reg_ext_3p3v failed, rc=%d\n", rc);
-			return -ENODEV;
+		if (!(machine_is_mpq8064_hrd() || machine_is_mpq8064_dtv())) {
+			rc = regulator_disable(reg_ext_3p3v);
+			if (rc) {
+				pr_err("disable reg_ext_3p3v failed, rc=%d\n",
+					rc);
+				return -ENODEV;
+			}
 		}
+
 		rc = regulator_disable(reg_8921_lvs7);
 		if (rc) {
 			pr_err("disable reg_8921_l23 failed, rc=%d\n", rc);
@@ -910,7 +920,8 @@
 error2:
 	regulator_disable(reg_8921_lvs7);
 error1:
-	regulator_disable(reg_ext_3p3v);
+	if (!(machine_is_mpq8064_hrd() || machine_is_mpq8064_dtv()))
+		regulator_disable(reg_ext_3p3v);
 	return rc;
 }
 
diff --git a/arch/arm/mach-msm/board-8064-gpiomux.c b/arch/arm/mach-msm/board-8064-gpiomux.c
index 9e34f47..0f88287 100644
--- a/arch/arm/mach-msm/board-8064-gpiomux.c
+++ b/arch/arm/mach-msm/board-8064-gpiomux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -74,259 +74,207 @@
 #endif
 
 #ifdef CONFIG_MSM_VCAP
-static struct gpiomux_setting gpio_vcap_config[] = {
-	{
-		.func = GPIOMUX_FUNC_GPIO,
-		.drv = GPIOMUX_DRV_2MA,
-		.pull = GPIOMUX_PULL_DOWN,
-	},
-	{
-		.func = GPIOMUX_FUNC_1,
-		.drv = GPIOMUX_DRV_2MA,
-		.pull = GPIOMUX_PULL_DOWN,
-	},
-	{
-		.func = GPIOMUX_FUNC_2,
-		.drv = GPIOMUX_DRV_2MA,
-		.pull = GPIOMUX_PULL_DOWN,
-	},
-	{
-		.func = GPIOMUX_FUNC_3,
-		.drv = GPIOMUX_DRV_2MA,
-		.pull = GPIOMUX_PULL_DOWN,
-	},
-	{
-		.func = GPIOMUX_FUNC_4,
-		.drv = GPIOMUX_DRV_2MA,
-		.pull = GPIOMUX_PULL_DOWN,
-	},
-	{
-		.func = GPIOMUX_FUNC_5,
-		.drv = GPIOMUX_DRV_2MA,
-		.pull = GPIOMUX_PULL_DOWN,
-	},
-	{
-		.func = GPIOMUX_FUNC_6,
-		.drv = GPIOMUX_DRV_2MA,
-		.pull = GPIOMUX_PULL_DOWN,
-	},
-	{
-		.func = GPIOMUX_FUNC_7,
-		.drv = GPIOMUX_DRV_2MA,
-		.pull = GPIOMUX_PULL_DOWN,
-	},
-	{
-		.func = GPIOMUX_FUNC_8,
-		.drv = GPIOMUX_DRV_2MA,
-		.pull = GPIOMUX_PULL_DOWN,
-	},
-	{
-		.func = GPIOMUX_FUNC_9,
-		.drv = GPIOMUX_DRV_2MA,
-		.pull = GPIOMUX_PULL_DOWN,
-	},
-	{
-		.func = GPIOMUX_FUNC_A,
-		.drv = GPIOMUX_DRV_2MA,
-		.pull = GPIOMUX_PULL_DOWN,
-	},
+static struct gpiomux_setting gpio_vcap_config = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
 };
 
 struct msm_gpiomux_config vcap_configs[] = {
 	{
 		.gpio = 20,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[7],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[7],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 	{
 		.gpio = 25,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[2],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[2],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 	{
 		.gpio = 24,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[1],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[1],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 	{
 		.gpio = 23,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[2],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[2],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 	{
 		.gpio = 19,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[8],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[8],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 	{
 		.gpio = 22,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[2],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[2],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 	{
 		.gpio = 21,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[7],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[7],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 	{
 		.gpio = 12,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[6],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[6],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 	{
 		.gpio = 18,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[9],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[9],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 	{
 		.gpio = 11,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[10],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[10],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 	{
 		.gpio = 10,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[9],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[9],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 	{
 		.gpio = 9,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[2],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[2],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 	{
 		.gpio = 26,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[1],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[1],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 	{
 		.gpio = 8,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[3],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[3],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 	{
 		.gpio = 7,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[7],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[7],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 	{
 		.gpio = 6,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[7],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[7],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 	{
 		.gpio = 80,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[2],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[2],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 	{
 		.gpio = 86,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[1],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[1],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 	{
 		.gpio = 85,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[4],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[4],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 	{
 		.gpio = 84,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[3],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[3],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 	{
 		.gpio = 5,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[2],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[2],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 	{
 		.gpio = 4,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[3],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[3],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 	{
 		.gpio = 3,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[6],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[6],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 	{
 		.gpio = 2,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[5],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[5],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 	{
 		.gpio = 82,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[4],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[4],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 	{
 		.gpio = 83,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[4],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[4],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 	{
 		.gpio = 87,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[2],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[2],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 	{
 		.gpio = 13,
 		.settings = {
-			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config[6],
-			[GPIOMUX_ACTIVE] =		&gpio_vcap_config[6],
+			[GPIOMUX_SUSPENDED] =	&gpio_vcap_config,
+			[GPIOMUX_ACTIVE] =		&gpio_vcap_config,
 		}
 	},
 };
@@ -404,6 +352,18 @@
 	.pull = GPIOMUX_PULL_NONE,
 };
 
+static struct gpiomux_setting gsbi2_uart_config = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_16MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting gsbi4_uart_config = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_16MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
 static struct gpiomux_setting ext_regulator_config = {
 	.func = GPIOMUX_FUNC_GPIO,
 	.drv = GPIOMUX_DRV_8MA,
@@ -768,6 +728,75 @@
 	},
 };
 
+static struct msm_gpiomux_config fsm8064_ep_gsbi_configs[] __initdata = {
+	{
+		.gpio      = 10,	/* GSBI4 UART TX */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi4_uart_config,
+		},
+	},
+	{
+		.gpio      = 11,	/* GSBI4 UART RX */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi4_uart_config,
+		},
+	},
+	{
+		.gpio      = 18,	/* GSBI1 UART TX */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi1_uart_config,
+		},
+	},
+	{
+		.gpio      = 19,	/* GSBI1 UART RX */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi1_uart_config,
+		},
+	},
+	{
+		.gpio      = 22,	/* GSBI2 UART TX */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi2_uart_config,
+		},
+	},
+	{
+		.gpio      = 23,	/* GSBI7 UART2 RX */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi2_uart_config,
+		},
+	},
+	{
+		.gpio      = 51,	/* GSBI5 QUP SPI_DATA_MOSI */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
+		},
+	},
+	{
+		.gpio      = 52,	/* GSBI5 QUP SPI_DATA_MISO */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
+		},
+	},
+	{
+		.gpio      = 53,	/* Funny CS0 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
+		},
+	},
+	{
+		.gpio      = 54,	/* GSBI5 QUP SPI_CLK */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
+		},
+	},
+	{
+		.gpio      = 53,	/* NOR CS */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_cs_config,
+		},
+	},
+};
+
 static struct msm_gpiomux_config apq8064_non_mi2s_gsbi_configs[] __initdata = {
 	{
 		.gpio      = 32,		/* EPM CS */
@@ -917,38 +946,38 @@
 
 static struct gpiomux_setting ap2mdm_cfg = {
 	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_8MA,
+	.drv = GPIOMUX_DRV_4MA,
 	.pull = GPIOMUX_PULL_DOWN,
 };
 
 static struct gpiomux_setting mdm2ap_status_cfg = {
 	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_8MA,
+	.drv = GPIOMUX_DRV_2MA,
 	.pull = GPIOMUX_PULL_DOWN,
 };
 
 static struct gpiomux_setting mdm2ap_errfatal_cfg = {
 	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_16MA,
+	.drv = GPIOMUX_DRV_2MA,
 	.pull = GPIOMUX_PULL_DOWN,
 };
 
 static struct gpiomux_setting mdm2ap_pblrdy = {
 	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_16MA,
+	.drv = GPIOMUX_DRV_2MA,
 	.pull = GPIOMUX_PULL_DOWN,
 };
 
 
 static struct gpiomux_setting ap2mdm_soft_reset_cfg = {
 	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_8MA,
+	.drv = GPIOMUX_DRV_4MA,
 	.pull = GPIOMUX_PULL_DOWN,
 };
 
 static struct gpiomux_setting ap2mdm_wakeup = {
 	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_8MA,
+	.drv = GPIOMUX_DRV_4MA,
 	.pull = GPIOMUX_PULL_DOWN,
 };
 
@@ -1568,6 +1597,241 @@
 	},
 };
 
+static struct gpiomux_setting boot_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
+static struct msm_gpiomux_config fsm8064_ep_boot_configs[] __initdata = {
+	{
+		.gpio      = 2,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &boot_cfg,
+		},
+	},
+	{
+		.gpio      = 3,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &boot_cfg,
+		},
+	},
+	{
+		.gpio      = 4,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &boot_cfg,
+		},
+	},
+	{
+		.gpio      = 5,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &boot_cfg,
+		},
+	},
+	{
+		.gpio      = 33,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &boot_cfg,
+		},
+	},
+	{
+		.gpio      = 34,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &boot_cfg,
+		},
+	},
+	{
+		.gpio      = 39,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &boot_cfg,
+		},
+	},
+	{
+		.gpio      = 50,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &boot_cfg,
+		},
+	},
+	{
+		.gpio      = 87,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &boot_cfg,
+		},
+	},
+};
+
+static struct gpiomux_setting fsm8064_ep_backup_suspended_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+	.dir = GPIOMUX_OUT_LOW,
+};
+
+static struct msm_gpiomux_config fsm8064_ep_backup_configs[] __initdata = {
+	{
+		.gpio      = 45,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &fsm8064_ep_backup_suspended_cfg,
+		},
+	},
+	{
+		.gpio      = 46,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &fsm8064_ep_backup_suspended_cfg,
+		},
+	},
+	{
+		.gpio      = 47,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &fsm8064_ep_backup_suspended_cfg,
+		},
+	},
+	{
+		.gpio      = 62,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &fsm8064_ep_backup_suspended_cfg,
+		},
+	},
+	{
+		.gpio      = 82,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &fsm8064_ep_backup_suspended_cfg,
+		},
+	},
+};
+
+static struct gpiomux_setting fsm8064_ep_uim_rst_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_UP,
+	.dir = GPIOMUX_OUT_LOW,
+};
+
+static struct gpiomux_setting fsm8064_ep_uim_pwr_sel_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_UP,
+	.dir = GPIOMUX_OUT_HIGH,
+};
+
+static struct msm_gpiomux_config fsm8064_ep_uim_configs[] __initdata = {
+	{
+		.gpio      = 49,	/* UIM_RST */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &fsm8064_ep_uim_rst_cfg,
+		},
+	},
+	{
+		.gpio      = 55,	/* UIM_PWR_SEL */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &fsm8064_ep_uim_pwr_sel_cfg,
+		},
+	},
+};
+
+static struct gpiomux_setting fsm8064_ep_sync_input_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_4MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
+static struct msm_gpiomux_config fsm8064_ep_sync_configs[] __initdata = {
+	{
+		.gpio      = 6,		/* GPSPPSIN_DRSYNC */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &fsm8064_ep_sync_input_cfg,
+		},
+	},
+	{
+		.gpio      = 7,		/* KRAIT_PPS_INPUT */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &fsm8064_ep_sync_input_cfg,
+		},
+	},
+	{
+		.gpio      = 8,		/* QDSP_PPS_INPUT */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &fsm8064_ep_sync_input_cfg,
+		},
+	},
+	{
+		.gpio      = 9,		/* DAN_TTI_INPUT */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &fsm8064_ep_sync_input_cfg,
+		},
+	},
+};
+
+static struct gpiomux_setting fsm8064_ep_led_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_4MA,
+	.pull = GPIOMUX_PULL_DOWN,
+	.dir = GPIOMUX_OUT_LOW,
+};
+
+static struct msm_gpiomux_config fsm8064_ep_led_configs[] __initdata = {
+	{
+		.gpio      = 58,		/* RED1 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &fsm8064_ep_led_cfg,
+		},
+	},
+	{
+		.gpio      = 59,		/* GREEN1 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &fsm8064_ep_led_cfg,
+		},
+	},
+	{
+		.gpio      = 60,		/* RED2 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &fsm8064_ep_led_cfg,
+		},
+	},
+	{
+		.gpio      = 61,		/* GREEN2 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &fsm8064_ep_led_cfg,
+		},
+	},
+	{
+		.gpio      = 69,		/* RED3 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &fsm8064_ep_led_cfg,
+		},
+	},
+	{
+		.gpio      = 70,		/* GREEN3 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &fsm8064_ep_led_cfg,
+		},
+	},
+	{
+		.gpio      = 71,		/* RED4 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &fsm8064_ep_led_cfg,
+		},
+	},
+	{
+		.gpio      = 72,		/* GREEN4 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &fsm8064_ep_led_cfg,
+		},
+	},
+	{
+		.gpio      = 77,		/* RED5 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &fsm8064_ep_led_cfg,
+		},
+	},
+	{
+		.gpio      = 80,		/* GREEN5 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &fsm8064_ep_led_cfg,
+		},
+	},
+};
+
 void __init apq8064_init_gpiomux(void)
 {
 	int rc;
@@ -1600,8 +1864,12 @@
 				ARRAY_SIZE(apq8064_ethernet_configs));
 		#endif
 
-		msm_gpiomux_install(apq8064_gsbi_configs,
-				ARRAY_SIZE(apq8064_gsbi_configs));
+		if (machine_is_fsm8064_ep())
+			msm_gpiomux_install(fsm8064_ep_gsbi_configs,
+					ARRAY_SIZE(fsm8064_ep_gsbi_configs));
+		else
+			msm_gpiomux_install(apq8064_gsbi_configs,
+					ARRAY_SIZE(apq8064_gsbi_configs));
 
 		if (!(machine_is_apq8064_mtp() &&
 		(SOCINFO_VERSION_MINOR(platform_version) == 1)))
@@ -1619,8 +1887,14 @@
 			msm_gpiomux_install(apq8064_gsbi1_i2c_2ma_configs,
 				ARRAY_SIZE(apq8064_gsbi1_i2c_2ma_configs));
 	} else {
-		msm_gpiomux_install(apq8064_slimbus_config,
+		if (!machine_is_fsm8064_ep()) {
+			msm_gpiomux_install(apq8064_slimbus_config,
 				ARRAY_SIZE(apq8064_slimbus_config));
+		}
+	}
+
+	if (!(machine_is_mpq8064_cdp() || machine_is_mpq8064_hrd() ||
+		 machine_is_mpq8064_dtv()) && !machine_is_apq8064_mtp()) {
 		msm_gpiomux_install(apq8064_gsbi1_i2c_8ma_configs,
 				ARRAY_SIZE(apq8064_gsbi1_i2c_8ma_configs));
 	}
@@ -1647,7 +1921,7 @@
 		msm_gpiomux_install(mpq8064_mi2s_configs,
 			ARRAY_SIZE(mpq8064_mi2s_configs));
 
-	if (!machine_is_mpq8064_hrd())
+	if (!machine_is_mpq8064_hrd() && !machine_is_fsm8064_ep())
 		msm_gpiomux_install(apq8064_ext_regulator_configs,
 			ARRAY_SIZE(apq8064_ext_regulator_configs));
 
@@ -1680,8 +1954,9 @@
 		msm_gpiomux_install(apq8064_mxt_configs,
 			ARRAY_SIZE(apq8064_mxt_configs));
 
-	msm_gpiomux_install(apq8064_hdmi_configs,
-			ARRAY_SIZE(apq8064_hdmi_configs));
+	if (!machine_is_fsm8064_ep())
+		msm_gpiomux_install(apq8064_hdmi_configs,
+				ARRAY_SIZE(apq8064_hdmi_configs));
 
 	if (apq8064_mhl_display_enabled())
 		msm_gpiomux_install(apq8064_mhl_configs,
@@ -1705,9 +1980,25 @@
 			     ARRAY_SIZE(apq8064_sdc4_configs));
 #endif
 
-	msm_gpiomux_install(apq8064_sdc3_configs,
-			ARRAY_SIZE(apq8064_sdc3_configs));
+	if (!(machine_is_mpq8064_cdp() || machine_is_mpq8064_hrd() ||
+		 machine_is_mpq8064_dtv())) {
+		msm_gpiomux_install(apq8064_sdc3_configs,
+				ARRAY_SIZE(apq8064_sdc3_configs));
+	}
 	 if (machine_is_mpq8064_hrd() || machine_is_mpq8064_dtv())
 		msm_gpiomux_install(mpq8064_uartdm_configs,
 				ARRAY_SIZE(mpq8064_uartdm_configs));
+
+	if (machine_is_fsm8064_ep()) {
+		msm_gpiomux_install(fsm8064_ep_boot_configs,
+				    ARRAY_SIZE(fsm8064_ep_boot_configs));
+		msm_gpiomux_install(fsm8064_ep_backup_configs,
+				    ARRAY_SIZE(fsm8064_ep_backup_configs));
+		msm_gpiomux_install(fsm8064_ep_uim_configs,
+				    ARRAY_SIZE(fsm8064_ep_uim_configs));
+		msm_gpiomux_install(fsm8064_ep_sync_configs,
+				    ARRAY_SIZE(fsm8064_ep_sync_configs));
+		msm_gpiomux_install(fsm8064_ep_led_configs,
+				    ARRAY_SIZE(fsm8064_ep_led_configs));
+	}
 }
diff --git a/arch/arm/mach-msm/board-8064-pmic.c b/arch/arm/mach-msm/board-8064-pmic.c
index f6dd2ea..a1ed251 100644
--- a/arch/arm/mach-msm/board-8064-pmic.c
+++ b/arch/arm/mach-msm/board-8064-pmic.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -130,6 +130,25 @@
 	PM8921_GPIO_INPUT(12, PM_GPIO_PULL_UP_30),     /* PCIE_WAKE_N */
 };
 
+static struct pm8xxx_gpio_init pm8921_fsm8064_ep_gpios[] __initdata = {
+	PM8921_GPIO_OUTPUT_VIN(1, 1, PM_GPIO_VIN_VPH),	/* 5V reg */
+	PM8921_GPIO_OUTPUT_VIN(12, 1, PM_GPIO_VIN_VPH),	/* 12V reg */
+	/* De-assert CW_GPS_RST_N for CW GPS module to lock to GPS source */
+	PM8921_GPIO_OUTPUT_VIN(14, 1, PM_GPIO_VIN_VPH),
+	/* PPS_SRC_SEL_N, chooses between WGR7640 PPS source (high) or
+	 * CW GPS module PPS source (low) */
+	PM8921_GPIO_OUTPUT_VIN(19, 0, PM_GPIO_VIN_VPH),	/* PPS_SRC_SEL_N */
+
+	PM8921_GPIO_OUTPUT_VIN(13, 1, PM_GPIO_VIN_VPH),	/* PCIE_CLK_PWR_EN */
+	PM8921_GPIO_OUTPUT_VIN(37, 1, PM_GPIO_VIN_VPH),	/* PCIE_RST_N */
+	PM8921_GPIO_INPUT(11, PM_GPIO_PULL_UP_30),	/* PCIE_WAKE_N */
+
+	PM8921_GPIO_OUTPUT_VIN(23, 1, PM_GPIO_VIN_VPH),	/* USB2_HSIC_RST_N */
+
+	PM8921_GPIO_OUTPUT_VIN(24, 1, PM_GPIO_VIN_VPH),	/* USB3_RST_N */
+	PM8921_GPIO_OUTPUT_VIN(34, 1, PM_GPIO_VIN_VPH),	/* USB4_RST_N */
+};
+
 static struct pm8xxx_gpio_init pm8921_mtp_kp_gpios[] __initdata = {
 	PM8921_GPIO_INPUT(3, PM_GPIO_PULL_UP_30),
 	PM8921_GPIO_INPUT(4, PM_GPIO_PULL_UP_30),
@@ -183,6 +202,8 @@
 /* Initial PM8XXX MPP configurations */
 static struct pm8xxx_mpp_init pm8xxx_mpps[] __initdata = {
 	PM8921_MPP_INIT(3, D_OUTPUT, PM8921_MPP_DIG_LEVEL_VPH, DOUT_CTRL_LOW),
+	/* External 5V regulator enable; shared by HDMI and USB_OTG switches. */
+	PM8921_MPP_INIT(7, D_OUTPUT, PM8921_MPP_DIG_LEVEL_VPH, DOUT_CTRL_LOW),
 	PM8921_MPP_INIT(8, D_OUTPUT, PM8921_MPP_DIG_LEVEL_S4, DOUT_CTRL_LOW),
 	/*MPP9 is used to detect docking station connection/removal on Liquid*/
 	PM8921_MPP_INIT(9, D_INPUT, PM8921_MPP_DIG_LEVEL_S4, DIN_TO_INT),
@@ -207,10 +228,27 @@
 {
 	int i, rc;
 
-	if (socinfo_get_pmic_model() != PMIC_MODEL_PM8917)
-		apq8064_configure_gpios(pm8921_gpios, ARRAY_SIZE(pm8921_gpios));
-	else
+	if (socinfo_get_pmic_model() != PMIC_MODEL_PM8917) {
+		/* PCIE_CLK_PWR_EN is 23 and PCIE_WAKE_N is 22
+		   for MPQ8064 Hybrid */
+		if (machine_is_mpq8064_hrd()) {
+			int size = ARRAY_SIZE(pm8921_gpios);
+			for (i = 0; i < size; i++)
+				if (pm8921_gpios[i].gpio == 13)
+					pm8921_gpios[i].gpio = 23;
+				else if (pm8921_gpios[i].gpio == 12)
+					pm8921_gpios[i].gpio = 22;
+		}
+
+		if (machine_is_fsm8064_ep())
+			apq8064_configure_gpios(pm8921_fsm8064_ep_gpios,
+					ARRAY_SIZE(pm8921_fsm8064_ep_gpios));
+		else
+			apq8064_configure_gpios(pm8921_gpios,
+					ARRAY_SIZE(pm8921_gpios));
+	} else {
 		apq8064_configure_gpios(pm8917_gpios, ARRAY_SIZE(pm8917_gpios));
+	}
 
 	if (machine_is_apq8064_cdp() || machine_is_apq8064_liquid()) {
 		apq8064_configure_gpios(touchscreen_gpios,
@@ -435,6 +473,8 @@
 	.chg_term_ua			= CHG_TERM_MA * 1000,
 	.normal_voltage_calc_ms		= 20000,
 	.low_voltage_calc_ms		= 1000,
+	.alarm_low_mv			= 3400,
+	.alarm_high_mv			= 4000,
 };
 
 static struct pm8921_platform_data
@@ -517,4 +557,7 @@
 
 	if (!machine_is_apq8064_mtp() && !machine_is_apq8064_liquid())
 		apq8064_pm8921_chg_pdata.battery_less_hardware = 1;
+
+	if (machine_is_mpq8064_hrd())
+		apq8064_pm8921_chg_pdata.disable_chg_rmvl_wrkarnd = 1;
 }
diff --git a/arch/arm/mach-msm/board-8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
index 1a8e7e4..57ecc27 100644
--- a/arch/arm/mach-msm/board-8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -190,6 +190,7 @@
 	REGULATOR_SUPPLY("vddp",		"0-0048"),
 	REGULATOR_SUPPLY("hdmi_lvl_tsl",	"hdmi_msm.0"),
 	REGULATOR_SUPPLY("vdd-io",		"spi0.2"),
+	REGULATOR_SUPPLY("sata_pmp_pwr",	"msm_sata.0"),
 };
 VREG_CONSUMERS(S5) = {
 	REGULATOR_SUPPLY("8921_s5",		NULL),
@@ -260,12 +261,15 @@
 	REGULATOR_SUPPLY("dsi1_vccs_3p3v",      "mipi_dsi.1"),
 	REGULATOR_SUPPLY("hdmi_mux_vdd",        "hdmi_msm.0"),
 	REGULATOR_SUPPLY("pcie_ext_3p3v",       "msm_pcie"),
-	REGULATOR_SUPPLY("sata_ext_3p3v",       "ahci.0"),
 };
 VREG_CONSUMERS(EXT_TS_SW) = {
 	REGULATOR_SUPPLY("ext_ts_sw",		NULL),
 	REGULATOR_SUPPLY("vdd_ana",		"3-005b"),
 };
+VREG_CONSUMERS(EXT_SATA_PWR) = {
+	REGULATOR_SUPPLY("ext_sata_pwr",	NULL),
+	REGULATOR_SUPPLY("sata_ext_3p3v",       "msm_sata.0"),
+};
 VREG_CONSUMERS(AVC_1P2V) = {
 	REGULATOR_SUPPLY("avc_1p2v",	NULL),
 };
@@ -299,7 +303,6 @@
 };
 VREG_CONSUMERS(EXT_5V) = {
 	REGULATOR_SUPPLY("ext_5v",		NULL),
-	REGULATOR_SUPPLY("ext_ddr3",		NULL),
 	REGULATOR_SUPPLY("vbus",		"msm_ehci_host.0"),
 };
 
@@ -437,7 +440,8 @@
 		.pin_ctrl	= _pin_ctrl, \
 	}
 
-#define GPIO_VREG(_id, _reg_name, _gpio_label, _gpio, _supply_regulator) \
+#define GPIO_VREG(_id, _reg_name, _gpio_label, _gpio, _supply_regulator, \
+		_active_low) \
 	[GPIO_VREG_ID_##_id] = { \
 		.init_data = { \
 			.constraints = { \
@@ -451,6 +455,17 @@
 		.regulator_name = _reg_name, \
 		.gpio_label	= _gpio_label, \
 		.gpio		= _gpio, \
+		.active_low	= _active_low, \
+	}
+
+#define FIXED_VREG_INIT(_id, _supply_regulator) \
+	{ \
+		.constraints = { \
+			.valid_ops_mask	= REGULATOR_CHANGE_STATUS, \
+		}, \
+		.num_consumer_supplies	= ARRAY_SIZE(vreg_consumers_##_id), \
+		.consumer_supplies	= vreg_consumers_##_id, \
+		.supply_regulator	= _supply_regulator, \
 	}
 
 #define SAW_VREG_INIT(_id, _name, _min_uV, _max_uV) \
@@ -566,25 +581,41 @@
 /* GPIO regulator constraints */
 struct gpio_regulator_platform_data
 apq8064_gpio_regulator_pdata[] __devinitdata = {
-	/*        ID      vreg_name gpio_label   gpio                  supply */
-	GPIO_VREG(EXT_5V, "ext_5v", "ext_5v_en", PM8921_MPP_PM_TO_SYS(7), NULL),
+	/*        ID      vreg_name gpio_label   gpio   supply   active_low */
+	GPIO_VREG(EXT_5V, "ext_5v", "ext_5v_en",
+			PM8921_MPP_PM_TO_SYS(7), NULL, 0),
 	GPIO_VREG(EXT_3P3V, "ext_3p3v", "ext_3p3v_en",
-		  APQ8064_EXT_3P3V_REG_EN_GPIO, NULL),
+		  APQ8064_EXT_3P3V_REG_EN_GPIO, NULL, 0),
 	GPIO_VREG(EXT_TS_SW, "ext_ts_sw", "ext_ts_sw_en",
-		  PM8921_GPIO_PM_TO_SYS(23), "ext_3p3v"),
+		  PM8921_GPIO_PM_TO_SYS(23), "ext_3p3v", 0),
 	GPIO_VREG(EXT_MPP8, "ext_mpp8", "ext_mpp8_en",
-			PM8921_MPP_PM_TO_SYS(8), NULL),
+			PM8921_MPP_PM_TO_SYS(8), NULL, 0),
+	GPIO_VREG(EXT_SATA_PWR, "ext_sata_pwr", "ext_sata_pwr_en",
+			PM8921_MPP_PM_TO_SYS(4), "ext_3p3v", 1),
 };
 
 struct gpio_regulator_platform_data
 mpq8064_gpio_regulator_pdata[] __devinitdata = {
-	GPIO_VREG(AVC_1P2V, "avc_1p2v", "avc_1p2v_en", SX150X_GPIO(4, 2), NULL),
-	GPIO_VREG(AVC_1P8V, "avc_1p8v", "avc_1p8v_en", SX150X_GPIO(4, 4), NULL),
+	GPIO_VREG(AVC_1P2V, "avc_1p2v", "avc_1p2v_en",
+			SX150X_GPIO(4, 2), NULL, 0),
+	GPIO_VREG(AVC_1P8V, "avc_1p8v", "avc_1p8v_en",
+			SX150X_GPIO(4, 4), NULL, 0),
 	GPIO_VREG(AVC_2P2V, "avc_2p2v", "avc_2p2v_en",
-						 SX150X_GPIO(4, 14), NULL),
-	GPIO_VREG(AVC_5V, "avc_5v", "avc_5v_en", SX150X_GPIO(4, 3), NULL),
+						 SX150X_GPIO(4, 14), NULL, 0),
+	GPIO_VREG(AVC_5V, "avc_5v", "avc_5v_en", SX150X_GPIO(4, 3), NULL, 0),
 	GPIO_VREG(AVC_3P3V, "avc_3p3v", "avc_3p3v_en",
-					SX150X_GPIO(4, 15), "avc_5v"),
+					SX150X_GPIO(4, 15), "avc_5v", 0),
+};
+
+/* Fixed regulator constraints */
+static struct regulator_init_data mpq8064_3p3_regulator_init =
+	/*              ID        supply */
+	FIXED_VREG_INIT(EXT_3P3V, NULL);
+
+struct fixed_voltage_config mpq8064_3p3_regulator_pdata = {
+	.supply_name = "ext_3p3v",
+	.gpio = -EINVAL,
+	.init_data = &mpq8064_3p3_regulator_init,
 };
 
 /* SAW regulator constraints */
diff --git a/arch/arm/mach-msm/board-8064-storage.c b/arch/arm/mach-msm/board-8064-storage.c
index 28f7f63..dd6c9ec 100644
--- a/arch/arm/mach-msm/board-8064-storage.c
+++ b/arch/arm/mach-msm/board-8064-storage.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 549a029..f3d648e 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -10,6 +10,7 @@
  * GNU General Public License for more details.
  *
  */
+#include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/bitops.h>
 #include <linux/platform_device.h>
@@ -141,6 +142,13 @@
 #define PCIE_WAKE_N_PMIC_GPIO 12
 #define PCIE_PWR_EN_PMIC_GPIO 13
 #define PCIE_RST_N_PMIC_MPP 1
+#define PCIE_WAKE_N_PMIC_GPIO_HRD 22
+#define PCIE_PWR_EN_PMIC_GPIO_HRD 23
+
+/* PCIe pmic gpios for fsm8064_ep */
+/* Unused pin. The WAKE feature is not supported on fsm8064_ep */
+#define PCIE_EP_WAKE_N_PMIC_GPIO	11
+#define PCIE_EP_RST_N_PMIC_GPIO		37
 
 #ifdef CONFIG_KERNEL_MSM_CONTIG_MEM_REGION
 static unsigned msm_contig_mem_size = MSM_CONTIG_MEM_SIZE;
@@ -298,8 +306,6 @@
 	.reusable = FMEM_ENABLED,
 	.mem_is_fmem = FMEM_ENABLED,
 	.fixed_position = FIXED_MIDDLE,
-	.is_cma = 1,
-	.no_nonsecure_alloc = 1,
 };
 
 static struct ion_cp_heap_pdata cp_mfc_apq8064_ion_pdata = {
@@ -308,7 +314,6 @@
 	.reusable = 0,
 	.mem_is_fmem = FMEM_ENABLED,
 	.fixed_position = FIXED_HIGH,
-	.no_nonsecure_alloc = 1,
 };
 
 static struct ion_co_heap_pdata co_apq8064_ion_pdata = {
@@ -959,7 +964,7 @@
 {
 	if (machine_is_apq8064_liquid() || machine_is_mpq8064_cdp() ||
 		machine_is_mpq8064_hrd() || machine_is_mpq8064_dtv() ||
-					machine_is_apq8064_cdp()) {
+			machine_is_apq8064_cdp() || machine_is_fsm8064_ep()) {
 		if (machine_is_apq8064_liquid())
 			msm_ehci_host_pdata3.dock_connect_irq =
 					PM8921_MPP_IRQ(PM8921_IRQ_BASE, 9);
@@ -1518,6 +1523,57 @@
 	0,
 };
 
+/* configuration data for mxt1386e using V2.4.AB firmware */
+static const u8 mxt1386e_config_data_v2_4_AB[] = {
+	/* T6 Object */
+	0, 0, 0, 0, 0, 0,
+	/* Object 38, Instance = 0 */
+	14, 5, 0, 0,
+	/* Object 7, Instance = 0 */
+	32, 8, 50, 0,
+	/* Object 8, Instance = 0 */
+	25, 0, 20, 20, 0, 0, 0, 0, 0, 0,
+	/* Object 9, Instance = 0 */
+	139, 0, 0, 26, 42, 0, 32, 80, 2, 5,
+	0, 5, 5, 79, 10, 30, 10, 10, 255, 2,
+	85, 5, 0, 5, 9, 5, 12, 35, 70, 40,
+	20, 5, 0, 0, 0, 0,
+	/* Object 18, Instance = 0 */
+	0, 0,
+	/* Object 24, Instance = 0 */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0,
+	/* Object 25, Instance = 0 */
+	1, 0, 60, 115, 156, 99,
+	/* Object 27, Instance = 0 */
+	0, 0, 0, 0, 0, 0, 0,
+	/* Object 40, Instance = 0 */
+	0, 0, 0, 0, 0,
+	/* Object 42, Instance = 0 */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	/* Object 43, Instance = 0 */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0,
+	/* Object 46, Instance = 0 */
+	68, 0, 16, 16, 0, 0, 0, 0, 0,
+	/* Object 47, Instance = 0 */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	/* Object 56, Instance = 0 */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0,
+	/* Object 62, Instance = 0 */
+	1, 0, 0, 2, 0, 0, 0, 0, 10, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 32,
+	40, 10, 52, 10, 100, 10, 10, 10, 90, 0,
+	0, 0, 0, 0, 33, 0, 1, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0,
+};
+
 #define MXT_TS_GPIO_IRQ			6
 #define MXT_TS_PWR_EN_GPIO		PM8921_GPIO_PM_TO_SYS(23)
 #define MXT_TS_RESET_GPIO		33
@@ -1531,7 +1587,7 @@
 		.version	= 0x21,
 		.build		= 0xAA,
 		.bootldr_id	= MXT_BOOTLOADER_ID_1386E,
-		.fw_name	= "atmel_8064_liquid_v2_2_AA.hex",
+		.fw_name	= "atmel_8064_liquid_v2_4_AB.hex",
 	},
 	{
 		/* The config data for V2.2.AA is the same as for V2.1.AA */
@@ -1542,6 +1598,16 @@
 		.version	= 0x22,
 		.build		= 0xAA,
 		.bootldr_id	= MXT_BOOTLOADER_ID_1386E,
+		.fw_name	= "atmel_8064_liquid_v2_4_AB.hex",
+	},
+	{
+		.config		= mxt1386e_config_data_v2_4_AB,
+		.config_length	= ARRAY_SIZE(mxt1386e_config_data_v2_4_AB),
+		.family_id	= 0xA0,
+		.variant_id	= 0x7,
+		.version	= 0x24,
+		.build		= 0xAB,
+		.bootldr_id	= MXT_BOOTLOADER_ID_1386E,
 	},
 };
 
@@ -2013,7 +2079,7 @@
 	msm_shared_ram_phys = MSM_SHARED_RAM_PHYS;
 	msm_map_apq8064_io();
 	if (socinfo_init() < 0)
-		pr_err("socinfo_init() failed!\n");
+		pr_err("%s: socinfo_init() failed\n", __func__);
 }
 
 static void __init apq8064_init_irq(void)
@@ -2194,6 +2260,13 @@
 	0x0B, 0x00, 0x0f,
 };
 
+static uint8_t spm_retention_with_krait_v3_cmd_sequence[] __initdata = {
+	0x42, 0x1B, 0x00,
+	0x05, 0x03, 0x01, 0x0B,
+	0x00, 0x42, 0x1B,
+	0x0f,
+};
+
 static uint8_t spm_power_collapse_with_rpm[] __initdata = {
 	0x00, 0x24, 0x54, 0x10,
 	0x09, 0x07, 0x01, 0x0B,
@@ -2245,11 +2318,16 @@
 		.cmd = spm_wfi_cmd_sequence,
 	},
 	[1] = {
+		.mode = MSM_SPM_MODE_POWER_RETENTION,
+		.notify_rpm = false,
+		.cmd = spm_retention_cmd_sequence,
+	},
+	[2] = {
 		.mode = MSM_SPM_MODE_POWER_COLLAPSE,
 		.notify_rpm = false,
 		.cmd = spm_power_collapse_without_rpm,
 	},
-	[2] = {
+	[3] = {
 		.mode = MSM_SPM_MODE_POWER_COLLAPSE,
 		.notify_rpm = true,
 		.cmd = spm_power_collapse_with_rpm,
@@ -2412,10 +2490,22 @@
 };
 
 static struct msm_pcie_platform msm_pcie_platform_data = {
-	.gpio = msm_pcie_gpio_info,
 	.axi_addr = PCIE_AXI_BAR_PHYS,
 	.axi_size = PCIE_AXI_BAR_SIZE,
-	.wake_n = PM8921_GPIO_IRQ(PM8921_IRQ_BASE, PCIE_WAKE_N_PMIC_GPIO),
+};
+
+/* FSM8064_EP PCIe gpios */
+static struct msm_pcie_gpio_info_t ep_pcie_gpio_info[MSM_PCIE_MAX_GPIO] = {
+	{"rst_n", PM8921_GPIO_PM_TO_SYS(PCIE_EP_RST_N_PMIC_GPIO), 0},
+	{"pwr_en", PM8921_GPIO_PM_TO_SYS(PCIE_PWR_EN_PMIC_GPIO), 1},
+};
+
+static struct msm_pcie_platform ep_pcie_platform_data = {
+	.gpio = ep_pcie_gpio_info,
+	.axi_addr = PCIE_AXI_BAR_PHYS,
+	.axi_size = PCIE_AXI_BAR_SIZE,
+	.wake_n = PM8921_GPIO_IRQ(PM8921_IRQ_BASE, PCIE_EP_WAKE_N_PMIC_GPIO),
+	.vreg_n = 4
 };
 
 static int __init mpq8064_pcie_enabled(void)
@@ -2427,11 +2517,39 @@
 static void __init mpq8064_pcie_init(void)
 {
 	if (mpq8064_pcie_enabled()) {
+		if (machine_is_mpq8064_hrd()) {
+			msm_pcie_platform_data.vreg_n = 3;
+			msm_pcie_gpio_info[1].num =
+			PM8921_GPIO_PM_TO_SYS(PCIE_PWR_EN_PMIC_GPIO_HRD);
+			msm_pcie_platform_data.wake_n =
+				PM8921_GPIO_IRQ(PM8921_IRQ_BASE,
+						PCIE_WAKE_N_PMIC_GPIO_HRD);
+		} else {
+			msm_pcie_platform_data.vreg_n = 4;
+			msm_pcie_platform_data.wake_n =
+				PM8921_GPIO_IRQ(PM8921_IRQ_BASE,
+						PCIE_WAKE_N_PMIC_GPIO);
+		}
+		msm_pcie_platform_data.gpio = msm_pcie_gpio_info;
+
 		msm_device_pcie.dev.platform_data = &msm_pcie_platform_data;
 		platform_device_register(&msm_device_pcie);
 	}
 }
 
+static void __init fsm8064_ep_pcie_init(void)
+{
+	msm_device_pcie.dev.platform_data = &ep_pcie_platform_data;
+	platform_device_register(&msm_device_pcie);
+}
+
+static struct platform_device mpq8064_device_ext_3p3v_vreg = {
+	.name			= "reg-fixed-voltage",
+	.dev			= {
+		.platform_data	= &mpq8064_3p3_regulator_pdata,
+	},
+};
+
 static struct platform_device apq8064_device_ext_5v_vreg __devinitdata = {
 	.name	= GPIO_REGULATOR_DEV_NAME,
 	.id	= PM8921_MPP_PM_TO_SYS(7),
@@ -2468,6 +2586,16 @@
 	},
 };
 
+static struct platform_device
+apq8064_device_ext_3p3v_mpp4_vreg __devinitdata = {
+	.name	= GPIO_REGULATOR_DEV_NAME,
+	.id	= PM8921_MPP_PM_TO_SYS(4),
+	.dev	= {
+		.platform_data =
+		&apq8064_gpio_regulator_pdata[GPIO_VREG_ID_EXT_SATA_PWR],
+	},
+};
+
 static struct platform_device apq8064_device_rpm_regulator __devinitdata = {
 	.name	= "rpm-regulator",
 	.id	= 0,
@@ -2510,6 +2638,93 @@
 	&mpq_cpudai_pseudo,
 };
 
+static struct platform_device *ep_devices[] __initdata = {
+	&msm_device_smd_apq8064,
+	&apq8064_device_gadget_peripheral,
+	&apq8064_device_hsusb_host,
+	&android_usb_device,
+	&msm_device_wcnss_wlan,
+	&apq8064_fmem_device,
+#ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
+	&apq8064_android_pmem_device,
+	&apq8064_android_pmem_adsp_device,
+	&apq8064_android_pmem_audio_device,
+#endif /*CONFIG_MSM_MULTIMEDIA_USE_ION*/
+#endif /*CONFIG_ANDROID_PMEM*/
+#ifdef CONFIG_ION_MSM
+	&apq8064_ion_dev,
+#endif
+	&msm8064_device_watchdog,
+	&msm8064_device_saw_regulator_core0,
+	&msm8064_device_saw_regulator_core1,
+	&msm8064_device_saw_regulator_core2,
+	&msm8064_device_saw_regulator_core3,
+#if defined(CONFIG_QSEECOM)
+	&qseecom_device,
+#endif
+
+	&msm_8064_device_tsif[0],
+	&msm_8064_device_tsif[1],
+
+#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
+		defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE)
+	&qcrypto_device,
+#endif
+
+#if defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
+		defined(CONFIG_CRYPTO_DEV_QCEDEV_MODULE)
+	&qcedev_device,
+#endif
+
+#ifdef CONFIG_HW_RANDOM_MSM
+	&apq8064_device_rng,
+#endif
+	&apq_pcm,
+	&apq_pcm_routing,
+	&apq8064_rpm_device,
+	&apq8064_rpm_log_device,
+	&apq8064_rpm_stat_device,
+	&apq8064_rpm_master_stat_device,
+	&apq_device_tz_log,
+	&msm_bus_8064_apps_fabric,
+	&msm_bus_8064_sys_fabric,
+	&msm_bus_8064_mm_fabric,
+	&msm_bus_8064_sys_fpb,
+	&msm_bus_8064_cpss_fpb,
+	&msm_pil_dsps,
+	&msm_8960_q6_lpass,
+	&apq8064_rtb_device,
+	&apq8064_dcvs_device,
+	&apq8064_msm_gov_device,
+	&apq8064_device_cache_erp,
+	&msm8960_device_ebi1_ch0_erp,
+	&msm8960_device_ebi1_ch1_erp,
+	&epm_adc_device,
+	&coresight_tpiu_device,
+	&coresight_etb_device,
+	&apq8064_coresight_funnel_device,
+	&coresight_etm0_device,
+	&coresight_etm1_device,
+	&coresight_etm2_device,
+	&coresight_etm3_device,
+#ifdef CONFIG_MSM_GEMINI
+	&msm8960_gemini_device,
+#endif
+	&msm_tsens_device,
+	&apq8064_cache_dump_device,
+	&msm_8064_device_tspp,
+#ifdef CONFIG_BATTERY_BCL
+	&battery_bcl_device,
+#endif
+	&apq8064_msm_mpd_device,
+	&apq8064_device_qup_i2c_gsbi1,
+	&apq8064_device_uart_gsbi2,
+	&apq8064_device_uart_gsbi1,
+	&apq8064_device_uart_gsbi4,
+	&msm_device_sps_apq8064,
+};
+
 static struct platform_device *common_i2s_devices[] __initdata = {
 	&apq_cpudai_mi2s,
 	&apq_cpudai_i2s_rx,
@@ -2533,6 +2748,7 @@
 static struct platform_device *pm8921_mpq_hrd_common_devices[] __initdata = {
 	&apq8064_device_ext_5v_vreg,
 	&apq8064_device_ext_mpp8_vreg,
+	&mpq8064_device_ext_3p3v_vreg,
 	&apq8064_device_ssbi_pmic1,
 	&apq8064_device_ssbi_pmic2,
 };
@@ -2671,7 +2887,7 @@
 #ifdef CONFIG_MSM_ROTATOR
 	&msm_rotator_device,
 #endif
-	&msm8064_pc_cntr,
+	&msm8064_cpu_slp_status,
 };
 
 static struct platform_device
@@ -2919,12 +3135,14 @@
 	wmb();
 	iounmap(gsbi_mem);
 	apq8064_i2c_qup_gsbi1_pdata.use_gsbi_shared_mode = 1;
-	apq8064_device_qup_i2c_gsbi3.dev.platform_data =
-					&apq8064_i2c_qup_gsbi3_pdata;
 	apq8064_device_qup_i2c_gsbi1.dev.platform_data =
 					&apq8064_i2c_qup_gsbi1_pdata;
-	apq8064_device_qup_i2c_gsbi4.dev.platform_data =
-					&apq8064_i2c_qup_gsbi4_pdata;
+	if (!machine_is_fsm8064_ep()) {
+		apq8064_device_qup_i2c_gsbi3.dev.platform_data =
+						&apq8064_i2c_qup_gsbi3_pdata;
+		apq8064_device_qup_i2c_gsbi4.dev.platform_data =
+						&apq8064_i2c_qup_gsbi4_pdata;
+	}
 	mpq8064_device_qup_i2c_gsbi5.dev.platform_data =
 					&mpq8064_i2c_qup_gsbi5_pdata;
 }
@@ -3440,6 +3658,8 @@
 		mach_mask = I2C_LIQUID;
 	else if (PLATFORM_IS_MPQ8064())
 		mach_mask = I2C_MPQ_CDP;
+	else if (machine_is_fsm8064_ep())
+		mach_mask = I2C_SURF;
 	else
 		pr_err("unmatched machine ID in register_i2c_devices\n");
 
@@ -3478,20 +3698,6 @@
 
 }
 
-static void enable_ddr3_regulator(void)
-{
-	static struct regulator *ext_ddr3;
-
-	/* Use MPP7 output state as a flag for PCDDR3 presence. */
-	if (gpio_get_value_cansleep(PM8921_MPP_PM_TO_SYS(7)) > 0) {
-		ext_ddr3 = regulator_get(NULL, "ext_ddr3");
-		if (IS_ERR(ext_ddr3) || ext_ddr3 == NULL)
-			pr_err("Could not get MPP7 regulator\n");
-		else
-			regulator_enable(ext_ddr3);
-	}
-}
-
 static void enable_avc_i2c_bus(void)
 {
 	int avc_i2c_en_mpp = PM8921_MPP_PM_TO_SYS(8);
@@ -3512,6 +3718,23 @@
 	cdp_keys_data.nbuttons = ARRAY_SIZE(cdp_keys_pm8917);
 }
 
+static void __init apq8064ab_update_retention_spm(void)
+{
+	int i;
+
+	/* Update the SPM sequences for krait retention on all cores */
+	for (i = 0; i < ARRAY_SIZE(msm_spm_data); i++) {
+		int j;
+		struct msm_spm_platform_data *pdata = &msm_spm_data[i];
+		for (j = 0; j < pdata->num_modes; j++) {
+			if (pdata->modes[j].cmd ==
+					spm_retention_cmd_sequence)
+				pdata->modes[j].cmd =
+				spm_retention_with_krait_v3_cmd_sequence;
+		}
+	}
+}
+
 static void __init apq8064_common_init(void)
 {
 	u32 platform_version = socinfo_get_platform_version();
@@ -3579,9 +3802,11 @@
 					ARRAY_SIZE(pm8917_common_devices));
 	if (machine_is_apq8064_cdp() || machine_is_apq8064_liquid())
 		platform_device_register(&apq8064_device_ext_ts_sw_vreg);
-	platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
+	if (!machine_is_fsm8064_ep())
+		platform_add_devices(common_devices,
+				ARRAY_SIZE(common_devices));
 	if (!(machine_is_mpq8064_cdp() || machine_is_mpq8064_hrd() ||
-			machine_is_mpq8064_dtv()))
+			machine_is_mpq8064_dtv() || machine_is_fsm8064_ep()))
 		platform_add_devices(common_not_mpq_devices,
 			ARRAY_SIZE(common_not_mpq_devices));
 
@@ -3596,7 +3821,6 @@
 			ARRAY_SIZE(common_i2s_devices));
 	}
 
-	enable_ddr3_regulator();
 	rpmrs_level =
 		msm_rpmrs_levels[MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT];
 	msm_hsic_pdata.swfi_latency = rpmrs_level.latency_us;
@@ -3635,11 +3859,18 @@
 	}
 	if (cpu_is_apq8064ab())
 		apq8064ab_update_krait_spm();
+	if (cpu_is_krait_v3()) {
+		struct msm_pm_init_data_type *pdata =
+			msm8064_pm_8x60.dev.platform_data;
+		pdata->retention_calls_tz = false;
+		apq8064ab_update_retention_spm();
+	}
+	platform_device_register(&msm8064_pm_8x60);
+
 	msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
 	msm_spm_l2_init(msm_spm_l2_data);
 	BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
 	apq8064_epm_adc_init();
-	msm_pm_set_tz_retention_flag(1);
 }
 
 static void __init apq8064_allocate_memory_regions(void)
@@ -3714,6 +3945,41 @@
 	if (machine_is_mpq8064_cdp() || machine_is_mpq8064_hrd() ||
 		machine_is_mpq8064_dtv())
 		platform_device_register(&msm_dev_avtimer_device);
+
+	if (machine_is_apq8064_cdp() || machine_is_mpq8064_hrd()) {
+		int ret;
+		struct pm8xxx_mpp_config_data sata_pwr_cfg = {
+			.type = PM8XXX_MPP_TYPE_D_OUTPUT,
+			.level = PM8921_MPP_DIG_LEVEL_VPH,
+			.control = PM8XXX_MPP_DOUT_CTRL_HIGH,
+		};
+
+		/* Apply MPP-4 init only when it is used to control SATA PWR */
+		ret = pm8xxx_mpp_config(PM8921_MPP_PM_TO_SYS(4), &sata_pwr_cfg);
+		if (ret)
+			pr_err("%s: pm8921 MPP %d init config failed(%d)\n",
+					__func__, PM8921_MPP_PM_TO_SYS(4), ret);
+		platform_device_register(&apq8064_device_ext_3p3v_mpp4_vreg);
+		platform_device_register(&apq8064_device_sata);
+	}
+}
+
+static void __init fsm8064_ep_init(void)
+{
+	if (meminfo_init(SYS_MEMORY, SZ_256M) < 0)
+		pr_err("meminfo_init() failed!\n");
+
+	apq8064_common_init();
+	ethernet_init();
+	fsm8064_ep_pcie_init();
+	platform_add_devices(ep_devices, ARRAY_SIZE(ep_devices));
+	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+	apq8064_init_gpu();
+	platform_device_register(&cdp_kp_pdev);
+#ifdef CONFIG_MSM_CAMERA
+	apq8064_init_cam();
+#endif
+	change_memory_power = &apq8064_change_memory_power;
 }
 
 MACHINE_START(APQ8064_CDP, "QCT APQ8064 CDP")
@@ -3729,6 +3995,19 @@
 	.smp = &msm8960_smp_ops,
 MACHINE_END
 
+MACHINE_START(FSM8064_EP, "QCT FSM8064 EP")
+	.map_io = apq8064_map_io,
+	.reserve = apq8064_reserve,
+	.init_irq = apq8064_init_irq,
+	.handle_irq = gic_handle_irq,
+	.timer = &msm_timer,
+	.init_machine = fsm8064_ep_init,
+	.init_early = apq8064_allocate_memory_regions,
+	.init_very_early = apq8064_early_reserve,
+	.restart = msm_restart,
+	.smp = &msm8960_smp_ops,
+MACHINE_END
+
 MACHINE_START(APQ8064_MTP, "QCT APQ8064 MTP")
 	.map_io = apq8064_map_io,
 	.reserve = apq8064_reserve,
diff --git a/arch/arm/mach-msm/board-8064.h b/arch/arm/mach-msm/board-8064.h
index 2bc0981..adc037b 100644
--- a/arch/arm/mach-msm/board-8064.h
+++ b/arch/arm/mach-msm/board-8064.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -14,9 +14,9 @@
 #define __ARCH_ARM_MACH_MSM_BOARD_APQ8064_H
 
 #include <linux/regulator/msm-gpio-regulator.h>
+#include <linux/regulator/fixed.h>
 #include <linux/mfd/pm8xxx/pm8921.h>
 #include <linux/mfd/pm8xxx/pm8821.h>
-#include <linux/ahci_platform.h>
 #include <mach/msm_memtypes.h>
 #include <mach/irqs.h>
 #include <mach/rpm-regulator.h>
@@ -50,6 +50,7 @@
 #define GPIO_VREG_ID_EXT_3P3V		1
 #define GPIO_VREG_ID_EXT_TS_SW		2
 #define GPIO_VREG_ID_EXT_MPP8		3
+#define GPIO_VREG_ID_EXT_SATA_PWR	4
 
 #define GPIO_VREG_ID_AVC_1P2V		0
 #define GPIO_VREG_ID_AVC_1P8V		1
@@ -65,6 +66,8 @@
 extern struct gpio_regulator_platform_data
 	mpq8064_gpio_regulator_pdata[] __devinitdata;
 
+extern struct fixed_voltage_config mpq8064_3p3_regulator_pdata;
+
 extern struct rpm_regulator_platform_data
 	apq8064_rpm_regulator_pdata __devinitdata;
 
@@ -81,7 +84,6 @@
 		struct mmc_platform_data *plat);
 
 void apq8064_init_mmc(void);
-int __init apq8064_add_ahci(struct ahci_platform_data *platd);
 void apq8064_init_gpiomux(void);
 void apq8064_init_pmic(void);
 
diff --git a/arch/arm/mach-msm/board-8092-gpiomux.c b/arch/arm/mach-msm/board-8092-gpiomux.c
index 823ef70..3e21087 100644
--- a/arch/arm/mach-msm/board-8092-gpiomux.c
+++ b/arch/arm/mach-msm/board-8092-gpiomux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -43,9 +43,9 @@
 {
 	int rc;
 
-	rc = msm_gpiomux_init(NR_GPIO_IRQS);
+	rc = msm_gpiomux_init_dt();
 	if (rc) {
-		pr_err(KERN_ERR "mpq8092_init_gpiomux failed %d\n", rc);
+		pr_err("%s failed %d\n", __func__, rc);
 		return;
 	}
 
diff --git a/arch/arm/mach-msm/board-8092.c b/arch/arm/mach-msm/board-8092.c
index cbd257f..b4c63f9 100644
--- a/arch/arm/mach-msm/board-8092.c
+++ b/arch/arm/mach-msm/board-8092.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -10,6 +10,7 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/of.h>
@@ -78,9 +79,6 @@
 static void __init mpq8092_map_io(void)
 {
 	msm_map_mpq8092_io();
-	if (socinfo_init() < 0)
-		pr_err("%s: socinfo_init() failed\n", __func__);
-
 }
 
 static struct of_dev_auxdata mpq8092_auxdata_lookup[] __initdata = {
@@ -99,6 +97,9 @@
 {
 	struct of_dev_auxdata *adata = mpq8092_auxdata_lookup;
 
+	if (socinfo_init() < 0)
+		pr_err("%s: socinfo_init() failed\n", __func__);
+
 	mpq8092_init_gpiomux();
 	msm_clock_init(&mpq8092_clock_init_data);
 	of_platform_populate(NULL, of_default_bus_match_table, adata, NULL);
diff --git a/arch/arm/mach-msm/board-8226-gpiomux.c b/arch/arm/mach-msm/board-8226-gpiomux.c
index eb88ef4..8be5525 100644
--- a/arch/arm/mach-msm/board-8226-gpiomux.c
+++ b/arch/arm/mach-msm/board-8226-gpiomux.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
@@ -17,13 +17,95 @@
 #include <mach/gpio.h>
 #include <mach/gpiomux.h>
 
+#define KS8851_IRQ_GPIO 75
+
+#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
+static struct gpiomux_setting gpio_eth_config = {
+	.pull = GPIOMUX_PULL_UP,
+	.drv = GPIOMUX_DRV_2MA,
+	.func = GPIOMUX_FUNC_GPIO,
+};
+
+static struct msm_gpiomux_config msm_eth_configs[] = {
+	{
+		.gpio = KS8851_IRQ_GPIO,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_eth_config,
+		}
+	},
+};
+#endif
+
+static struct gpiomux_setting gpio_spi_config = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting gpio_spi_cs_config = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_6MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting gpio_i2c_config = {
+	.func = GPIOMUX_FUNC_3,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct msm_gpiomux_config msm_blsp_configs[] __initdata = {
+	{
+		.gpio      = 0,		/* BLSP1 QUP1 SPI_DATA_MOSI */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
+		},
+	},
+	{
+		.gpio      = 1,		/* BLSP1 QUP1 SPI_DATA_MISO */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
+		},
+	},
+	{
+		.gpio      = 2,		/* BLSP1 QUP1 SPI_CS1 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_cs_config,
+		},
+	},
+	{
+		.gpio      = 3,		/* BLSP1 QUP1 SPI_CLK */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
+		},
+	},
+	{
+		.gpio      = 14,	/* BLSP1 QUP4 I2C_SDA */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_i2c_config,
+		},
+	},
+	{
+		.gpio      = 15,	/* BLSP1 QUP4 I2C_SCL */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_i2c_config,
+		},
+	},
+};
+
 void __init msm8226_init_gpiomux(void)
 {
 	int rc;
 
-	rc = msm_gpiomux_init(NR_GPIO_IRQS);
+	rc = msm_gpiomux_init_dt();
 	if (rc) {
-		pr_err(KERN_ERR "msm_8226_init_gpiomux failed %d\n", rc);
+		pr_err("%s failed %d\n", __func__, rc);
 		return;
 	}
+
+#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
+	msm_gpiomux_install(msm_eth_configs, ARRAY_SIZE(msm_eth_configs));
+#endif
+
+	msm_gpiomux_install(msm_blsp_configs, ARRAY_SIZE(msm_blsp_configs));
 }
diff --git a/arch/arm/mach-msm/board-8226.c b/arch/arm/mach-msm/board-8226.c
index a5cb481..2b331d0 100644
--- a/arch/arm/mach-msm/board-8226.c
+++ b/arch/arm/mach-msm/board-8226.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
@@ -10,6 +10,7 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/platform_device.h>
@@ -26,6 +27,7 @@
 #ifdef CONFIG_ANDROID_PMEM
 #include <linux/android_pmem.h>
 #endif
+#include <linux/regulator/qpnp-regulator.h>
 #include <asm/mach/map.h>
 #include <asm/hardware/gic.h>
 #include <asm/mach/arch.h>
@@ -41,9 +43,14 @@
 #include <mach/socinfo.h>
 #include <mach/board.h>
 #include <mach/clk-provider.h>
+#include <mach/msm_smd.h>
+#include <mach/rpm-smd.h>
+#include <linux/msm_thermal.h>
 #include "board-dt.h"
 #include "clock.h"
 #include "platsmp.h"
+#include "spm.h"
+#include "lpm_resources.h"
 
 static struct memtype_reserve msm8226_reserve_table[] __initdata = {
 	[MEMTYPE_SMI] = {
@@ -60,25 +67,6 @@
 {
 	return MEMTYPE_EBI1;
 }
-static struct clk_lookup msm_clocks_dummy[] = {
-	CLK_DUMMY("core_clk",   BLSP1_UART_CLK, "f991f000.serial", OFF),
-	CLK_DUMMY("iface_clk",  BLSP1_UART_CLK, "f991f000.serial", OFF),
-	CLK_DUMMY("iface_clk",  HSUSB_IFACE_CLK, "f9a55000.usb", OFF),
-	CLK_DUMMY("core_clk",	HSUSB_CORE_CLK, "f9a55000.usb", OFF),
-	CLK_DUMMY("dfab_clk",	DFAB_CLK, "msm_sps", OFF),
-	CLK_DUMMY("dma_bam_pclk",	DMA_BAM_P_CLK, "msm_sps", OFF),
-	CLK_DUMMY("iface_clk",	NULL,		"msm_sdcc.1", OFF),
-	CLK_DUMMY("core_clk",	NULL,		"msm_sdcc.1", OFF),
-	CLK_DUMMY("bus_clk",	NULL,		"msm_sdcc.1", OFF),
-	CLK_DUMMY("iface_clk",	NULL,		"msm_sdcc.2", OFF),
-	CLK_DUMMY("core_clk",	NULL,		"msm_sdcc.2", OFF),
-	CLK_DUMMY("bus_clk",	NULL,		"msm_sdcc.2", OFF),
-};
-
-static struct clock_init_data msm_dummy_clock_init_data __initdata = {
-	.table = msm_clocks_dummy,
-	.size = ARRAY_SIZE(msm_clocks_dummy),
-};
 
 static struct of_dev_auxdata msm8226_auxdata_lookup[] __initdata = {
 	OF_DEV_AUXDATA("qcom,msm-sdcc", 0xF9824000, \
@@ -96,26 +84,46 @@
 static void __init msm8226_early_memory(void)
 {
 	reserve_info = &msm8226_reserve_info;
-	of_scan_flat_dt(dt_scan_for_memory_reserve, msm8226_reserve_table);
+	of_scan_flat_dt(dt_scan_for_memory_hole, msm8226_reserve_table);
 }
 
 static void __init msm8226_reserve(void)
 {
+	reserve_info = &msm8226_reserve_info;
+	of_scan_flat_dt(dt_scan_for_memory_reserve, msm8226_reserve_table);
 	msm_reserve();
 }
 
+/*
+ * Used to satisfy dependencies for devices that need to be
+ * run early or in a particular order. Most likely your device doesn't fall
+ * into this category, and thus the driver should not be added here. The
+ * EPROBE_DEFER can satisfy most dependency problems.
+ */
+void __init msm8226_add_drivers(void)
+{
+	msm_rpm_driver_init();
+	msm_lpmrs_module_init();
+	msm_spm_device_init();
+	qpnp_regulator_init();
+	if (machine_is_msm8226_rumi())
+		msm_clock_init(&msm8226_rumi_clock_init_data);
+	else
+		msm_clock_init(&msm8226_clock_init_data);
+
+	msm_thermal_device_init();
+}
+
 void __init msm8226_init(void)
 {
 	struct of_dev_auxdata *adata = msm8226_auxdata_lookup;
 
-	msm8226_init_gpiomux();
-
-	msm_clock_init(&msm_dummy_clock_init_data);
-
 	if (socinfo_init() < 0)
 		pr_err("%s: socinfo_init() failed\n", __func__);
 
+	msm8226_init_gpiomux();
 	of_platform_populate(NULL, of_default_bus_match_table, adata, NULL);
+	msm8226_add_drivers();
 }
 
 static const char *msm8226_dt_match[] __initconst = {
@@ -125,7 +133,7 @@
 
 DT_MACHINE_START(MSM8226_DT, "Qualcomm MSM 8226 (Flattened Device Tree)")
 	.map_io = msm_map_msm8226_io,
-	.init_irq = msm_dt_init_irq_nompm,
+	.init_irq = msm_dt_init_irq,
 	.init_machine = msm8226_init,
 	.handle_irq = gic_handle_irq,
 	.timer = &msm_dt_timer,
diff --git a/arch/arm/mach-msm/board-8610-gpiomux.c b/arch/arm/mach-msm/board-8610-gpiomux.c
new file mode 100644
index 0000000..15d7679
--- /dev/null
+++ b/arch/arm/mach-msm/board-8610-gpiomux.c
@@ -0,0 +1,88 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/gpiomux.h>
+
+static struct gpiomux_setting gpio_i2c_config = {
+	.func = GPIOMUX_FUNC_3,
+	.drv  = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting gpio_spi_config = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_6MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting gpio_spi_cs_config = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_6MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct msm_gpiomux_config msm_blsp_configs[] __initdata = {
+	{
+		.gpio      = 10,	/* BLSP1 QUP3 I2C_SDA */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_i2c_config,
+		},
+	},
+	{
+		.gpio      = 11,	/* BLSP1 QUP3 I2C_SCL */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_i2c_config,
+		},
+	},
+	{
+		.gpio      = 0,		/* BLSP1 QUP1 SPI_DATA_MOSI */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
+		},
+	},
+	{
+		.gpio      = 1,		/* BLSP1 QUP1 SPI_DATA_MISO */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
+		},
+	},
+	{
+		.gpio      = 3,		/* BLSP1 QUP1 SPI_CLK */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
+		},
+	},
+	{
+		.gpio      = 2,		/* BLSP1 QUP1 SPI_CS1 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_cs_config,
+		},
+	},
+};
+
+void __init msm8610_init_gpiomux(void)
+{
+	int rc;
+
+	rc = msm_gpiomux_init_dt();
+	if (rc) {
+		pr_err("%s failed %d\n", __func__, rc);
+		return;
+	}
+
+	msm_gpiomux_install(msm_blsp_configs, ARRAY_SIZE(msm_blsp_configs));
+}
diff --git a/arch/arm/mach-msm/board-8610.c b/arch/arm/mach-msm/board-8610.c
new file mode 100644
index 0000000..b4f202d
--- /dev/null
+++ b/arch/arm/mach-msm/board-8610.c
@@ -0,0 +1,135 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/of_fdt.h>
+#include <linux/of_irq.h>
+#include <linux/memory.h>
+#include <asm/mach/map.h>
+#include <asm/arch_timer.h>
+#include <asm/hardware/gic.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <mach/board.h>
+#include <mach/gpiomux.h>
+#include <mach/msm_iomap.h>
+#include <mach/restart.h>
+#ifdef CONFIG_ION_MSM
+#include <mach/ion.h>
+#endif
+#include <mach/msm_memtypes.h>
+#include <mach/socinfo.h>
+#include <mach/board.h>
+#include <mach/clk-provider.h>
+#include <mach/msm_smd.h>
+#include <mach/rpm-smd.h>
+#include <linux/msm_thermal.h>
+#include "board-dt.h"
+#include "clock.h"
+#include "platsmp.h"
+#include "spm.h"
+#include "lpm_resources.h"
+
+static struct memtype_reserve msm8610_reserve_table[] __initdata = {
+	[MEMTYPE_SMI] = {
+	},
+	[MEMTYPE_EBI0] = {
+		.flags	=	MEMTYPE_FLAGS_1M_ALIGN,
+	},
+	[MEMTYPE_EBI1] = {
+		.flags	=	MEMTYPE_FLAGS_1M_ALIGN,
+	},
+};
+
+static int msm8610_paddr_to_memtype(unsigned int paddr)
+{
+	return MEMTYPE_EBI1;
+}
+
+static struct of_dev_auxdata msm8610_auxdata_lookup[] __initdata = {
+	OF_DEV_AUXDATA("qcom,msm-sdcc", 0xF9824000, \
+			"msm_sdcc.1", NULL),
+	OF_DEV_AUXDATA("qcom,msm-sdcc", 0xF98A4000, \
+			"msm_sdcc.2", NULL),
+	{}
+};
+
+static struct reserve_info msm8610_reserve_info __initdata = {
+	.memtype_reserve_table = msm8610_reserve_table,
+	.paddr_to_memtype = msm8610_paddr_to_memtype,
+};
+
+static void __init msm8610_early_memory(void)
+{
+	reserve_info = &msm8610_reserve_info;
+	of_scan_flat_dt(dt_scan_for_memory_hole, msm8610_reserve_table);
+}
+
+static void __init msm8610_reserve(void)
+{
+	reserve_info = &msm8610_reserve_info;
+	of_scan_flat_dt(dt_scan_for_memory_reserve, msm8610_reserve_table);
+	msm_reserve();
+}
+
+void __init msm8610_add_drivers(void)
+{
+	msm_rpm_driver_init();
+	msm_lpmrs_module_init();
+	msm_spm_device_init();
+	msm_thermal_device_init();
+
+	if (machine_is_msm8610_rumi())
+		msm_clock_init(&msm8610_rumi_clock_init_data);
+	else
+		msm_clock_init(&msm8610_clock_init_data);
+}
+
+void __init msm8610_init(void)
+{
+	struct of_dev_auxdata *adata = msm8610_auxdata_lookup;
+
+	if (socinfo_init() < 0)
+		pr_err("%s: socinfo_init() failed\n", __func__);
+
+	msm8610_init_gpiomux();
+	of_platform_populate(NULL, of_default_bus_match_table, adata, NULL);
+	msm8610_add_drivers();
+}
+
+static const char *msm8610_dt_match[] __initconst = {
+	"qcom,msm8610",
+	NULL
+};
+
+DT_MACHINE_START(MSM8610_DT, "Qualcomm MSM 8610 (Flattened Device Tree)")
+	.map_io = msm_map_msm8610_io,
+	.init_irq = msm_dt_init_irq,
+	.init_machine = msm8610_init,
+	.handle_irq = gic_handle_irq,
+	.timer = &msm_dt_timer,
+	.dt_compat = msm8610_dt_match,
+	.restart = msm_restart,
+	.reserve = msm8610_reserve,
+	.init_very_early = msm8610_early_memory,
+	.smp = &arm_smp_ops,
+MACHINE_END
diff --git a/arch/arm/mach-msm/board-8910-gpiomux.c b/arch/arm/mach-msm/board-8910-gpiomux.c
deleted file mode 100644
index a67f916..0000000
--- a/arch/arm/mach-msm/board-8910-gpiomux.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <mach/board.h>
-#include <mach/gpio.h>
-#include <mach/gpiomux.h>
-
-void __init msm8910_init_gpiomux(void)
-{
-	int rc;
-
-	rc = msm_gpiomux_init(NR_GPIO_IRQS);
-	if (rc) {
-		pr_err(KERN_ERR "msm_8910_init_gpiomux failed %d\n", rc);
-		return;
-	}
-}
diff --git a/arch/arm/mach-msm/board-8910.c b/arch/arm/mach-msm/board-8910.c
deleted file mode 100644
index 2ff4567..0000000
--- a/arch/arm/mach-msm/board-8910.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-#include <linux/irq.h>
-#include <linux/irqdomain.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_platform.h>
-#include <linux/of_fdt.h>
-#include <linux/of_irq.h>
-#include <linux/memory.h>
-#include <asm/mach/map.h>
-#include <asm/arch_timer.h>
-#include <asm/hardware/gic.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <mach/board.h>
-#include <mach/gpiomux.h>
-#include <mach/msm_iomap.h>
-#include <mach/restart.h>
-#ifdef CONFIG_ION_MSM
-#include <mach/ion.h>
-#endif
-#include <mach/msm_memtypes.h>
-#include <mach/socinfo.h>
-#include <mach/board.h>
-#include <mach/clk-provider.h>
-#include "board-dt.h"
-#include "clock.h"
-#include "platsmp.h"
-
-static struct memtype_reserve msm8910_reserve_table[] __initdata = {
-	[MEMTYPE_SMI] = {
-	},
-	[MEMTYPE_EBI0] = {
-		.flags	=	MEMTYPE_FLAGS_1M_ALIGN,
-	},
-	[MEMTYPE_EBI1] = {
-		.flags	=	MEMTYPE_FLAGS_1M_ALIGN,
-	},
-};
-
-static int msm8910_paddr_to_memtype(unsigned int paddr)
-{
-	return MEMTYPE_EBI1;
-}
-
-static struct of_dev_auxdata msm8910_auxdata_lookup[] __initdata = {
-	OF_DEV_AUXDATA("qcom,msm-sdcc", 0xF9824000, \
-			"msm_sdcc.1", NULL),
-	OF_DEV_AUXDATA("qcom,msm-sdcc", 0xF98A4000, \
-			"msm_sdcc.2", NULL),
-	{}
-};
-
-static struct reserve_info msm8910_reserve_info __initdata = {
-	.memtype_reserve_table = msm8910_reserve_table,
-	.paddr_to_memtype = msm8910_paddr_to_memtype,
-};
-
-static void __init msm8910_early_memory(void)
-{
-	reserve_info = &msm8910_reserve_info;
-	of_scan_flat_dt(dt_scan_for_memory_reserve, msm8910_reserve_table);
-}
-
-static void __init msm8910_reserve(void)
-{
-	msm_reserve();
-}
-
-void __init msm8910_init(void)
-{
-	struct of_dev_auxdata *adata = msm8910_auxdata_lookup;
-
-	msm8910_init_gpiomux();
-
-	if (machine_is_msm8910_rumi())
-		msm_clock_init(&msm8910_rumi_clock_init_data);
-	else
-		msm_clock_init(&msm8910_clock_init_data);
-
-	if (socinfo_init() < 0)
-		pr_err("%s: socinfo_init() failed\n", __func__);
-
-	of_platform_populate(NULL, of_default_bus_match_table, adata, NULL);
-}
-
-static const char *msm8910_dt_match[] __initconst = {
-	"qcom,msm8910",
-	NULL
-};
-
-DT_MACHINE_START(MSM8910_DT, "Qualcomm MSM 8910 (Flattened Device Tree)")
-	.map_io = msm_map_msm8910_io,
-	.init_irq = msm_dt_init_irq_nompm,
-	.init_machine = msm8910_init,
-	.handle_irq = gic_handle_irq,
-	.timer = &msm_dt_timer,
-	.dt_compat = msm8910_dt_match,
-	.restart = msm_restart,
-	.reserve = msm8910_reserve,
-	.init_very_early = msm8910_early_memory,
-	.smp = &arm_smp_ops,
-MACHINE_END
diff --git a/arch/arm/mach-msm/board-8930-display.c b/arch/arm/mach-msm/board-8930-display.c
index 4506ea7..6154769 100644
--- a/arch/arm/mach-msm/board-8930-display.c
+++ b/arch/arm/mach-msm/board-8930-display.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/board-8930-gpiomux.c b/arch/arm/mach-msm/board-8930-gpiomux.c
index cf44e08..4298d96 100644
--- a/arch/arm/mach-msm/board-8930-gpiomux.c
+++ b/arch/arm/mach-msm/board-8930-gpiomux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/board-8930-gpu.c b/arch/arm/mach-msm/board-8930-gpu.c
index 3eb7d8a..0c6a271 100644
--- a/arch/arm/mach-msm/board-8930-gpu.c
+++ b/arch/arm/mach-msm/board-8930-gpu.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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,7 +146,7 @@
 	.set_grp_async = NULL,
 	.idle_timeout = HZ/12,
 	.nap_allowed = true,
-	.strtstp_sleepwake = true,
+	.strtstp_sleepwake = false,
 	.clk_map = KGSL_CLK_CORE | KGSL_CLK_IFACE | KGSL_CLK_MEM_IFACE,
 #ifdef CONFIG_MSM_BUS_SCALING
 	.bus_scale_table = &grp3d_bus_scale_pdata,
@@ -173,8 +173,10 @@
 
 	if (cpu_is_msm8930aa())
 		kgsl_3d0_pdata.pwrlevel[0].gpu_freq = 450000000;
-	else if (cpu_is_msm8930ab())
+	else if (cpu_is_msm8930ab()) {
 		kgsl_3d0_pdata.pwrlevel[0].gpu_freq = 500000000;
+		grp3d_max_vectors[0].ib = KGSL_CONVERT_TO_MBPS(4800);
+	}
 
 	/* Set up the chip ID based on the SoC version */
 
diff --git a/arch/arm/mach-msm/board-8930-pmic.c b/arch/arm/mach-msm/board-8930-pmic.c
index a5fded4..4f398f4 100644
--- a/arch/arm/mach-msm/board-8930-pmic.c
+++ b/arch/arm/mach-msm/board-8930-pmic.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -182,6 +182,8 @@
 static struct pm8xxx_mpp_init pm8917_mpps[] __initdata = {
 	PM8917_MPP_INIT(PM8XXX_AMUX_MPP_3, A_INPUT,
 				PM8XXX_MPP_AIN_AMUX_CH8, DIN_TO_INT),
+	/* Configure MPP01 for USB ID detection */
+	PM8917_MPP_INIT(1, D_INPUT, PM8921_MPP_DIG_LEVEL_S4, DIN_TO_INT),
 };
 
 void __init msm8930_pm8038_gpio_mpp_init(void)
@@ -372,7 +374,7 @@
 	.op_fdbck = true,
 	.ovp_val = WLED_OVP_32V,
 	.boost_curr_lim = WLED_CURR_LIMIT_525mA,
-	.num_strings = 1,
+	.strings = WLED_SECOND_STRING,
 };
 
 static int pm8038_led0_pwm_duty_pcts[56] = {
@@ -453,7 +455,7 @@
 
 static struct pm8xxx_spk_platform_data pm8xxx_spk_pdata = {
 	.spk_add_enable		= false,
-	.cd_ng_threshold	= 0x6,
+	.cd_ng_threshold	= 0x0,
 	.cd_nf_preamp_bias	= 0x1,
 	.cd_ng_hold		= 0x6,
 	.cd_ng_max_atten	= 0x0,
@@ -474,6 +476,8 @@
 	.rconn_mohm			= 18,
 	.normal_voltage_calc_ms		= 20000,
 	.low_voltage_calc_ms		= 1000,
+	.alarm_low_mv			= 3400,
+	.alarm_high_mv			= 4000,
 };
 
 static struct pm8038_platform_data pm8038_platform_data __devinitdata = {
diff --git a/arch/arm/mach-msm/board-8930-regulator-pm8038.c b/arch/arm/mach-msm/board-8930-regulator-pm8038.c
index eaebea0..c34394e 100644
--- a/arch/arm/mach-msm/board-8930-regulator-pm8038.c
+++ b/arch/arm/mach-msm/board-8930-regulator-pm8038.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/board-8930-regulator-pm8917.c b/arch/arm/mach-msm/board-8930-regulator-pm8917.c
index 9d0d3ee..8f853a4 100644
--- a/arch/arm/mach-msm/board-8930-regulator-pm8917.c
+++ b/arch/arm/mach-msm/board-8930-regulator-pm8917.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/board-8930-storage.c b/arch/arm/mach-msm/board-8930-storage.c
index 7280b22..d045040 100644
--- a/arch/arm/mach-msm/board-8930-storage.c
+++ b/arch/arm/mach-msm/board-8930-storage.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
@@ -63,11 +63,9 @@
 		 * hardware revisions - maybe once that is done, this can be
 		 * reverted.
 		 */
-		.always_on = 1,
 		.lpm_sup = 1,
 		.hpm_uA = 800000, /* 800mA */
 		.lpm_uA = 9000,
-		.reset_at_init = true,
 	},
 };
 
@@ -311,13 +309,11 @@
 	 * This change to the boards will be true for newer versions of the SoC
 	 * as well.
 	 */
-	if ((SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 1 &&
-			SOCINFO_VERSION_MINOR(socinfo_get_version()) >= 2) ||
-			machine_is_msm8930_cdp()) {
-		msm8960_sdc3_data.vreg_data->vdd_data->always_on = false;
-		msm8960_sdc3_data.vreg_data->vdd_data->reset_at_init = false;
+	if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 1 &&
+			SOCINFO_VERSION_MINOR(socinfo_get_version()) < 2) {
+		msm8960_sdc3_data.vreg_data->vdd_data->always_on = true;
+		msm8960_sdc3_data.vreg_data->vdd_data->reset_at_init = true;
 	}
-
 	/* SDC3: External card slot */
 	if (!machine_is_msm8930_cdp()) {
 		msm8960_sdc3_data.wpswitch_gpio = 0;
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 1a953da..fbcc6f1 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -10,6 +10,7 @@
  * GNU General Public License for more details.
  *
  */
+#include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
@@ -343,8 +344,6 @@
 	.reusable = FMEM_ENABLED,
 	.mem_is_fmem = FMEM_ENABLED,
 	.fixed_position = FIXED_MIDDLE,
-	.is_cma	= 1,
-	.no_nonsecure_alloc = 1,
 };
 
 static struct ion_cp_heap_pdata cp_mfc_msm8930_ion_pdata = {
@@ -353,7 +352,6 @@
 	.reusable = 0,
 	.mem_is_fmem = FMEM_ENABLED,
 	.fixed_position = FIXED_HIGH,
-	.no_nonsecure_alloc = 1,
 };
 
 static struct ion_co_heap_pdata co_msm8930_ion_pdata = {
@@ -1467,6 +1465,7 @@
 
 	if (socinfo_init() < 0)
 		pr_err("socinfo_init() failed!\n");
+
 }
 
 static void __init msm8930_init_irq(void)
@@ -1506,6 +1505,16 @@
 #ifdef CONFIG_USB_MSM_OTG_72K
 static struct msm_otg_platform_data msm_otg_pdata;
 #else
+static int enable_usb_host_mode;
+static int __init usb_host_mode_with_pm8917(char *param)
+{
+	int ret;
+
+	ret = kstrtoint(param, 10, &enable_usb_host_mode);
+	return ret;
+}
+early_param("usb_host_mode_pm8917", usb_host_mode_with_pm8917);
+
 #ifdef CONFIG_MSM_BUS_SCALING
 /* Bandwidth requests (zero) if no vote placed */
 static struct msm_bus_vectors usb_init_vectors[] = {
@@ -1559,7 +1568,6 @@
 	.mode			= USB_OTG,
 	.otg_control		= OTG_PMIC_CONTROL,
 	.phy_type		= SNPS_28NM_INTEGRATED_PHY,
-	.pmic_id_irq		= PM8038_USB_ID_IN_IRQ(PM8038_IRQ_BASE),
 	.power_budget		= 750,
 #ifdef CONFIG_MSM_BUS_SCALING
 	.bus_scale_table	= &usb_bus_scale_pdata,
@@ -1639,11 +1647,18 @@
 	0x03, 0x0f,
 };
 
+
 static uint8_t spm_retention_cmd_sequence[] __initdata = {
 	0x00, 0x05, 0x03, 0x0D,
 	0x0B, 0x00, 0x0f,
 };
 
+static uint8_t spm_retention_with_krait_v3_cmd_sequence[] __initdata = {
+	0x42, 0x1B, 0x00,
+	0x05, 0x03, 0x01, 0x0B,
+	0x00, 0x42, 0x1B,
+	0x0f,
+};
 static uint8_t spm_power_collapse_without_rpm[] __initdata = {
 	0x00, 0x24, 0x54, 0x10,
 	0x09, 0x03, 0x01,
@@ -1688,11 +1703,16 @@
 		.cmd = spm_wfi_cmd_sequence,
 	},
 	[1] = {
+		.mode = MSM_SPM_MODE_POWER_RETENTION,
+		.notify_rpm = false,
+		.cmd = spm_retention_cmd_sequence,
+	},
+	[2] = {
 		.mode = MSM_SPM_MODE_POWER_COLLAPSE,
 		.notify_rpm = false,
 		.cmd = spm_power_collapse_without_rpm,
 	},
-	[2] = {
+	[3] = {
 		.mode = MSM_SPM_MODE_POWER_COLLAPSE,
 		.notify_rpm = true,
 		.cmd = spm_power_collapse_with_rpm,
@@ -2453,7 +2473,7 @@
 	&msm8930_iommu_domain_device,
 	&msm_tsens_device,
 	&msm8930_cache_dump_device,
-	&msm8930_pc_cntr,
+	&msm8930_cpu_slp_status,
 };
 
 static struct platform_device *cdp_devices[] __initdata = {
@@ -2845,6 +2865,23 @@
 	pdata->uses_pm8917 = true;
 }
 
+static void __init msm8930ab_update_retention_spm(void)
+{
+	int i;
+
+	/* Update the SPM sequences for krait retention on all cores */
+	for (i = 0; i < ARRAY_SIZE(msm_spm_data); i++) {
+		int j;
+		struct msm_spm_platform_data *pdata = &msm_spm_data[i];
+		for (j = 0; j < pdata->num_modes; j++) {
+			if (pdata->modes[j].cmd ==
+					spm_retention_cmd_sequence)
+				pdata->modes[j].cmd =
+				spm_retention_with_krait_v3_cmd_sequence;
+		}
+	}
+}
+
 static void __init msm8930_cdp_init(void)
 {
 	if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917)
@@ -2871,6 +2908,27 @@
 		msm_clock_init(&msm8930_pm8917_clock_init_data);
 	else
 		msm_clock_init(&msm8930_clock_init_data);
+
+	if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917) {
+		/*
+		 * By default, set USB mode as USB Peripheral only due to
+		 * hardware rework requirement for USB Host Mode.
+		 * Provide pmic_id_irq number only if host mode is enable
+		 * by user assuming that hardware rework is available.
+		 */
+		if (enable_usb_host_mode) {
+			/* MPP01 IRQ number */
+			msm_otg_pdata.pmic_id_irq =
+				PM8921_MPP_IRQ(PM8917_IRQ_BASE, 1);
+		} else {
+			pr_err("Enabling USB Peripheral Only mode.\n");
+			msm_otg_pdata.mode = USB_PERIPHERAL;
+		}
+	} else {
+		msm_otg_pdata.pmic_id_irq =
+				PM8038_USB_ID_IN_IRQ(PM8038_IRQ_BASE);
+	}
+
 	msm_otg_pdata.phy_init_seq = hsusb_phy_init_seq;
 	if (msm8930_mhl_display_enabled()) {
 		mhl_platform_data.mhl_enabled = true;
@@ -2896,6 +2954,15 @@
 #endif
 	msm8930_i2c_init();
 	msm8930_init_gpu();
+	if (cpu_is_krait_v3()) {
+		struct msm_pm_init_data_type *pdata =
+			msm8930_pm_8x60.dev.platform_data;
+		pdata->retention_calls_tz = false;
+		msm8930ab_update_retention_spm();
+	}
+
+	platform_device_register(&msm8930_pm_8x60);
+
 	msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
 	msm_spm_l2_init(msm_spm_l2_data);
 	msm8930_init_buses();
@@ -2957,7 +3024,6 @@
 		ARRAY_SIZE(msm_slim_devices));
 	change_memory_power = &msm8930_change_memory_power;
 	BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
-	msm_pm_set_tz_retention_flag(1);
 
 	if (PLATFORM_IS_CHARM25())
 		platform_add_devices(mdm_devices, ARRAY_SIZE(mdm_devices));
diff --git a/arch/arm/mach-msm/board-8930.h b/arch/arm/mach-msm/board-8930.h
index dbcfa9d..90adb62 100644
--- a/arch/arm/mach-msm/board-8930.h
+++ b/arch/arm/mach-msm/board-8930.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/board-8960-camera.c b/arch/arm/mach-msm/board-8960-camera.c
index 3853e4c..836c8f37 100644
--- a/arch/arm/mach-msm/board-8960-camera.c
+++ b/arch/arm/mach-msm/board-8960-camera.c
@@ -812,6 +812,7 @@
 	.csi_if = 1,
 	.camera_type = BACK_CAMERA_2D,
 	.sensor_type = BAYER_SENSOR,
+	.actuator_info = &msm_act_main_cam_1_info,
 };
 
 static struct pm8xxx_mpp_config_data privacy_light_on_config = {
diff --git a/arch/arm/mach-msm/board-8960-display.c b/arch/arm/mach-msm/board-8960-display.c
index ecf5ec6..c779ab6 100644
--- a/arch/arm/mach-msm/board-8960-display.c
+++ b/arch/arm/mach-msm/board-8960-display.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/board-8960-gpiomux.c b/arch/arm/mach-msm/board-8960-gpiomux.c
index fe37f2a..1aa7508 100644
--- a/arch/arm/mach-msm/board-8960-gpiomux.c
+++ b/arch/arm/mach-msm/board-8960-gpiomux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/board-8960-pmic.c b/arch/arm/mach-msm/board-8960-pmic.c
index f0ba1c9..8c16984 100644
--- a/arch/arm/mach-msm/board-8960-pmic.c
+++ b/arch/arm/mach-msm/board-8960-pmic.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -433,6 +433,8 @@
 	.chg_term_ua			= CHG_TERM_MA * 1000,
 	.normal_voltage_calc_ms		= 20000,
 	.low_voltage_calc_ms		= 1000,
+	.alarm_low_mv			= 3400,
+	.alarm_high_mv			= 4000,
 };
 
 #define	PM8921_LC_LED_MAX_CURRENT	4	/* I = 4mA */
diff --git a/arch/arm/mach-msm/board-8960-regulator.c b/arch/arm/mach-msm/board-8960-regulator.c
index 22c16c7..a93cfe5 100644
--- a/arch/arm/mach-msm/board-8960-regulator.c
+++ b/arch/arm/mach-msm/board-8960-regulator.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/board-8960-storage.c b/arch/arm/mach-msm/board-8960-storage.c
index ded5bad..4a8c95a 100644
--- a/arch/arm/mach-msm/board-8960-storage.c
+++ b/arch/arm/mach-msm/board-8960-storage.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 9b19810..819ccc5 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -10,6 +10,7 @@
  * GNU General Public License for more details.
  *
  */
+#include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
@@ -366,8 +367,6 @@
 	.fixed_position = FIXED_MIDDLE,
 	.iommu_map_all = 1,
 	.iommu_2x_map_domain = VIDEO_DOMAIN,
-	.is_cma = 1,
-	.no_nonsecure_alloc = 1,
 };
 
 static struct ion_cp_heap_pdata cp_mfc_msm8960_ion_pdata = {
@@ -376,7 +375,6 @@
 	.reusable = 0,
 	.mem_is_fmem = FMEM_ENABLED,
 	.fixed_position = FIXED_HIGH,
-	.no_nonsecure_alloc = 1,
 };
 
 static struct ion_co_heap_pdata co_msm8960_ion_pdata = {
@@ -766,8 +764,8 @@
 			case ION_HEAP_TYPE_CP:
 				if (cpu_is_msm8960()) {
 					((struct ion_cp_heap_pdata *)
-					heap->extra_data)->no_nonsecure_alloc =
-						0;
+					heap->extra_data)->allow_nonsecure_alloc
+						= 1;
 				}
 
 			}
@@ -1393,6 +1391,8 @@
 static struct mdm_platform_data sglte_platform_data = {
 	.mdm_version = "4.0",
 	.ramdump_delay_ms = 1000,
+	/* delay between two PS_HOLDs */
+	.ps_hold_delay_ms = 500,
 	.soft_reset_inverted = 1,
 	.peripheral_platform_device = NULL,
 	.ramdump_timeout_ms = 600000,
@@ -1438,26 +1438,49 @@
 
 static struct resource tspp_resources[] = {
 	[0] = {
+		.name = "TSIF_TSPP_IRQ",
 		.flags = IORESOURCE_IRQ,
 		.start = TSIF_TSPP_IRQ,
-		.end   = TSIF1_IRQ,
+		.end   = TSIF_TSPP_IRQ,
 	},
 	[1] = {
+		.name = "TSIF0_IRQ",
+		.flags = IORESOURCE_IRQ,
+		.start = TSIF1_IRQ,
+		.end   = TSIF1_IRQ,
+	},
+	[2] = {
+		.name = "TSIF1_IRQ",
+		.flags = IORESOURCE_IRQ,
+		.start = TSIF2_IRQ,
+		.end   = TSIF2_IRQ,
+	},
+	[3] = {
+		.name = "TSIF_BAM_IRQ",
+		.flags = IORESOURCE_IRQ,
+		.start = TSIF_BAM_IRQ,
+		.end   = TSIF_BAM_IRQ,
+	},
+	[4] = {
+		.name = "MSM_TSIF0_PHYS",
 		.flags = IORESOURCE_MEM,
 		.start = MSM_TSIF0_PHYS,
 		.end   = MSM_TSIF0_PHYS + MSM_TSIF_SIZE - 1,
 	},
-	[2] = {
+	[5] = {
+		.name = "MSM_TSIF1_PHYS",
 		.flags = IORESOURCE_MEM,
 		.start = MSM_TSIF1_PHYS,
 		.end   = MSM_TSIF1_PHYS + MSM_TSIF_SIZE - 1,
 	},
-	[3] = {
+	[6] = {
+		.name = "MSM_TSPP_PHYS",
 		.flags = IORESOURCE_MEM,
 		.start = MSM_TSPP_PHYS,
 		.end   = MSM_TSPP_PHYS + MSM_TSPP_SIZE - 1,
 	},
-	[4] = {
+	[7] = {
+		.name = "MSM_TSPP_BAM_PHYS",
 		.flags = IORESOURCE_MEM,
 		.start = MSM_TSPP_BAM_PHYS,
 		.end   = MSM_TSPP_BAM_PHYS + MSM_TSPP_BAM_SIZE - 1,
@@ -1487,9 +1510,9 @@
 {
 	msm_shared_ram_phys = MSM_SHARED_RAM_PHYS;
 	msm_map_msm8960_io();
-
 	if (socinfo_init() < 0)
 		pr_err("socinfo_init() failed!\n");
+
 }
 
 static void __init msm8960_init_irq(void)
@@ -1713,6 +1736,13 @@
 	0x0B, 0x00, 0x0f,
 };
 
+static uint8_t spm_retention_with_krait_v3_cmd_sequence[] __initdata = {
+	0x42, 0x1B, 0x00,
+	0x05, 0x03, 0x01, 0x0B,
+	0x00, 0x42, 0x1B,
+	0x0f,
+};
+
 static uint8_t spm_power_collapse_without_rpm[] __initdata = {
 	0x00, 0x24, 0x54, 0x10,
 	0x09, 0x03, 0x01,
@@ -1771,12 +1801,20 @@
 		.notify_rpm = false,
 		.cmd = spm_wfi_cmd_sequence,
 	},
+
 	[1] = {
+		.mode = MSM_SPM_MODE_POWER_RETENTION,
+		.notify_rpm = false,
+		.cmd = spm_retention_cmd_sequence,
+	},
+
+	[2] = {
 		.mode = MSM_SPM_MODE_POWER_COLLAPSE,
 		.notify_rpm = false,
 		.cmd = spm_power_collapse_without_rpm,
 	},
-	[2] = {
+
+	[3] = {
 		.mode = MSM_SPM_MODE_POWER_COLLAPSE,
 		.notify_rpm = true,
 		.cmd = spm_power_collapse_with_rpm,
@@ -2917,7 +2955,7 @@
 	&msm8960_cache_dump_device,
 	&msm8960_iommu_domain_device,
 	&msm_tsens_device,
-	&msm8960_pc_cntr,
+	&msm8960_cpu_slp_status,
 };
 
 static struct platform_device *cdp_devices[] __initdata = {
@@ -3002,6 +3040,9 @@
 		kgsl_3d0_pdata->chipid = ADRENO_CHIPID(3, 2, 1, 0);
 		/* 8960PRO nominal clock rate is 320Mhz */
 		kgsl_3d0_pdata->pwrlevel[1].gpu_freq = 320000000;
+#ifdef CONFIG_MSM_BUS_SCALING
+		kgsl_3d0_pdata->bus_scale_table = &grp3d_bus_scale_pdata_ab;
+#endif
 
 		/*
 		 * If this an A320 GPU device (MSM8960AB), then
@@ -3372,6 +3413,23 @@
 	}
 }
 
+static void __init msm8960ab_update_retention_spm(void)
+{
+	int i;
+
+	/* Update the SPM sequences for krait retention on all cores */
+	for (i = 0; i < ARRAY_SIZE(msm_spm_data); i++) {
+		int j;
+		struct msm_spm_platform_data *pdata = &msm_spm_data[i];
+		for (j = 0; j < pdata->num_modes; j++) {
+			if (pdata->modes[j].cmd ==
+					spm_retention_cmd_sequence)
+				pdata->modes[j].cmd =
+				spm_retention_with_krait_v3_cmd_sequence;
+		}
+	}
+}
+
 static void __init msm8960_cdp_init(void)
 {
 	if (meminfo_init(SYS_MEMORY, SZ_256M) < 0)
@@ -3429,6 +3487,14 @@
 
 	if (cpu_is_msm8960ab())
 		msm8960ab_update_krait_spm();
+	if (cpu_is_krait_v3()) {
+		struct msm_pm_init_data_type *pdata =
+			msm8960_pm_8x60.dev.platform_data;
+		pdata->retention_calls_tz = false;
+		msm8960ab_update_retention_spm();
+	}
+	platform_device_register(&msm8960_pm_8x60);
+
 	msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
 	msm_spm_l2_init(msm_spm_l2_data);
 
@@ -3494,7 +3560,6 @@
 		mdm_sglte_device.dev.platform_data = &sglte_platform_data;
 		platform_device_register(&mdm_sglte_device);
 	}
-	msm_pm_set_tz_retention_flag(1);
 	ion_adjust_secure_allocation();
 }
 
diff --git a/arch/arm/mach-msm/board-8960.h b/arch/arm/mach-msm/board-8960.h
index 382723c..bfa5d17 100644
--- a/arch/arm/mach-msm/board-8960.h
+++ b/arch/arm/mach-msm/board-8960.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/board-8974-gpiomux.c b/arch/arm/mach-msm/board-8974-gpiomux.c
index 3245ff8..5240f38 100644
--- a/arch/arm/mach-msm/board-8974-gpiomux.c
+++ b/arch/arm/mach-msm/board-8974-gpiomux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -68,6 +68,20 @@
 };
 #endif
 
+static struct gpiomux_setting gpio_suspend_config[] = {
+	{
+		.func = GPIOMUX_FUNC_GPIO,  /* IN-NP */
+		.drv = GPIOMUX_DRV_2MA,
+		.pull = GPIOMUX_PULL_NONE,
+	},
+	{
+		.func = GPIOMUX_FUNC_GPIO,  /* O-LOW */
+		.drv = GPIOMUX_DRV_2MA,
+		.pull = GPIOMUX_PULL_NONE,
+		.dir = GPIOMUX_OUT_LOW,
+	},
+};
+
 static struct gpiomux_setting gpio_epm_config = {
 	.func = GPIOMUX_FUNC_GPIO,
 	.drv  = GPIOMUX_DRV_2MA,
@@ -88,7 +102,12 @@
 
 static struct gpiomux_setting gpio_i2c_config = {
 	.func = GPIOMUX_FUNC_3,
-	.drv = GPIOMUX_DRV_8MA,
+	/*
+	 * Please keep I2C GPIOs drive-strength at minimum (2ma). It is a
+	 * workaround for HW issue of glitches caused by rapid GPIO current-
+	 * change.
+	 */
+	.drv = GPIOMUX_DRV_2MA,
 	.pull = GPIOMUX_PULL_NONE,
 };
 
@@ -96,6 +115,7 @@
 	.func = GPIOMUX_FUNC_GPIO,
 	.drv = GPIOMUX_DRV_8MA,
 	.pull = GPIOMUX_PULL_NONE,
+	.dir = GPIOMUX_OUT_HIGH,
 };
 
 static struct gpiomux_setting lcd_en_sus_cfg = {
@@ -140,6 +160,26 @@
 	.drv = GPIOMUX_DRV_2MA,
 	.pull = GPIOMUX_PULL_NONE,
 };
+static struct gpiomux_setting hap_lvl_shft_suspended_config = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting hap_lvl_shft_active_config = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+static struct msm_gpiomux_config hap_lvl_shft_config[] __initdata = {
+	{
+		.gpio = 86,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &hap_lvl_shft_suspended_config,
+			[GPIOMUX_ACTIVE] = &hap_lvl_shft_active_config,
+		},
+	},
+};
 
 static struct msm_gpiomux_config msm_touch_configs[] __initdata = {
 	{
@@ -219,12 +259,6 @@
 	.dir = GPIOMUX_OUT_HIGH,
 };
 
-static struct gpiomux_setting mhl_active_2_cfg = {
-	.func = GPIOMUX_FUNC_1,
-	.drv = GPIOMUX_DRV_2MA,
-	.pull = GPIOMUX_PULL_UP,
-};
-
 static struct gpiomux_setting hdmi_suspend_cfg = {
 	.func = GPIOMUX_FUNC_GPIO,
 	.drv = GPIOMUX_DRV_2MA,
@@ -260,14 +294,6 @@
 			[GPIOMUX_ACTIVE]    = &mhl_active_1_cfg,
 		},
 	},
-	{
-		/* mhl-sii8334 reset */
-		.gpio = 8,
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &mhl_suspend_config,
-			[GPIOMUX_ACTIVE]    = &mhl_active_2_cfg,
-		},
-	},
 };
 
 
@@ -302,6 +328,49 @@
 	},
 };
 
+static struct gpiomux_setting gpio_uart7_active_cfg = {
+	.func = GPIOMUX_FUNC_3,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting gpio_uart7_suspend_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct msm_gpiomux_config msm_blsp2_uart7_configs[] __initdata = {
+	{
+		.gpio	= 41,	/* BLSP2 UART7 TX */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &gpio_uart7_active_cfg,
+			[GPIOMUX_SUSPENDED] = &gpio_uart7_suspend_cfg,
+		},
+	},
+	{
+		.gpio	= 42,	/* BLSP2 UART7 RX */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &gpio_uart7_active_cfg,
+			[GPIOMUX_SUSPENDED] = &gpio_uart7_suspend_cfg,
+		},
+	},
+	{
+		.gpio	= 43,	/* BLSP2 UART7 CTS */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &gpio_uart7_active_cfg,
+			[GPIOMUX_SUSPENDED] = &gpio_uart7_suspend_cfg,
+		},
+	},
+	{
+		.gpio	= 44,	/* BLSP2 UART7 RFR */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &gpio_uart7_active_cfg,
+			[GPIOMUX_SUSPENDED] = &gpio_uart7_suspend_cfg,
+		},
+	},
+};
+
 static struct msm_gpiomux_config msm_rumi_blsp_configs[] __initdata = {
 	{
 		.gpio      = 45,	/* BLSP2 UART8 TX */
@@ -317,6 +386,16 @@
 	},
 };
 
+static struct msm_gpiomux_config msm_lcd_configs[] __initdata = {
+	{
+		.gpio = 58,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &lcd_en_act_cfg,
+			[GPIOMUX_SUSPENDED] = &lcd_en_sus_cfg,
+		},
+	},
+};
+
 static struct msm_gpiomux_config msm_blsp_configs[] __initdata = {
 #if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
 	{
@@ -351,13 +430,6 @@
 	},
 #endif
 	{
-		.gpio = 58,
-		.settings = {
-			[GPIOMUX_ACTIVE]    = &lcd_en_act_cfg,
-			[GPIOMUX_SUSPENDED] = &lcd_en_sus_cfg,
-		},
-	},
-	{
 		.gpio      = 6,		/* BLSP1 QUP2 I2C_DAT */
 		.settings = {
 			[GPIOMUX_SUSPENDED] = &gpio_i2c_config,
@@ -396,25 +468,29 @@
 	{
 		.gpio      = 53,		/* BLSP2 QUP4 SPI_DATA_MOSI */
 		.settings = {
-			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
+			[GPIOMUX_ACTIVE] = &gpio_spi_config,
+			[GPIOMUX_SUSPENDED] = &gpio_suspend_config[1],
 		},
 	},
 	{
 		.gpio      = 54,		/* BLSP2 QUP4 SPI_DATA_MISO */
 		.settings = {
-			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
+			[GPIOMUX_ACTIVE] = &gpio_spi_config,
+			[GPIOMUX_SUSPENDED] = &gpio_suspend_config[1],
 		},
 	},
 	{
 		.gpio      = 56,		/* BLSP2 QUP4 SPI_CLK */
 		.settings = {
-			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
+			[GPIOMUX_ACTIVE] = &gpio_spi_config,
+			[GPIOMUX_SUSPENDED] = &gpio_suspend_config[0],
 		},
 	},
 	{
 		.gpio      = 55,		/* BLSP2 QUP4 SPI_CS0_N */
 		.settings = {
-			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
+			[GPIOMUX_ACTIVE] = &gpio_spi_config,
+			[GPIOMUX_SUSPENDED] = &gpio_suspend_config[0],
 		},
 	},
 	{
@@ -472,18 +548,25 @@
 	},
 };
 
-static struct gpiomux_setting sd_card_det_config = {
+static struct gpiomux_setting sd_card_det_active_config = {
 	.func = GPIOMUX_FUNC_GPIO,
 	.drv = GPIOMUX_DRV_2MA,
 	.pull = GPIOMUX_PULL_NONE,
 	.dir = GPIOMUX_IN,
 };
 
+static struct gpiomux_setting sd_card_det_sleep_config = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_UP,
+	.dir = GPIOMUX_IN,
+};
+
 static struct msm_gpiomux_config sd_card_det __initdata = {
 	.gpio = 62,
 	.settings = {
-		[GPIOMUX_ACTIVE]    = &sd_card_det_config,
-		[GPIOMUX_SUSPENDED] = &sd_card_det_config,
+		[GPIOMUX_ACTIVE]    = &sd_card_det_active_config,
+		[GPIOMUX_SUSPENDED] = &sd_card_det_sleep_config,
 	},
 };
 
@@ -520,49 +603,49 @@
 		.gpio = 19, /* CCI_I2C_SDA0 */
 		.settings = {
 			[GPIOMUX_ACTIVE]    = &cam_settings[0],
-			[GPIOMUX_SUSPENDED] = &cam_settings[2],
+			[GPIOMUX_SUSPENDED] = &gpio_suspend_config[0],
 		},
 	},
 	{
 		.gpio = 20, /* CCI_I2C_SCL0 */
 		.settings = {
 			[GPIOMUX_ACTIVE]    = &cam_settings[0],
-			[GPIOMUX_SUSPENDED] = &cam_settings[2],
+			[GPIOMUX_SUSPENDED] = &gpio_suspend_config[0],
 		},
 	},
 	{
 		.gpio = 21, /* CCI_I2C_SDA1 */
 		.settings = {
 			[GPIOMUX_ACTIVE]    = &cam_settings[0],
-			[GPIOMUX_SUSPENDED] = &cam_settings[2],
+			[GPIOMUX_SUSPENDED] = &gpio_suspend_config[0],
 		},
 	},
 	{
 		.gpio = 22, /* CCI_I2C_SCL1 */
 		.settings = {
 			[GPIOMUX_ACTIVE]    = &cam_settings[0],
-			[GPIOMUX_SUSPENDED] = &cam_settings[2],
+			[GPIOMUX_SUSPENDED] = &gpio_suspend_config[0],
 		},
 	},
 	{
 		.gpio = 23, /* FLASH_LED_EN */
 		.settings = {
 			[GPIOMUX_ACTIVE]    = &cam_settings[0],
-			[GPIOMUX_SUSPENDED] = &cam_settings[1],
+			[GPIOMUX_SUSPENDED] = &gpio_suspend_config[1],
 		},
 	},
 	{
 		.gpio = 24, /* FLASH_LED_NOW */
 		.settings = {
 			[GPIOMUX_ACTIVE]    = &cam_settings[0],
-			[GPIOMUX_SUSPENDED] = &cam_settings[1],
+			[GPIOMUX_SUSPENDED] = &gpio_suspend_config[1],
 		},
 	},
 	{
 		.gpio = 25, /* WEBCAM2_RESET_N */
 		.settings = {
 			[GPIOMUX_ACTIVE]    = &cam_settings[0],
-			[GPIOMUX_SUSPENDED] = &cam_settings[1],
+			[GPIOMUX_SUSPENDED] = &gpio_suspend_config[1],
 		},
 	},
 	{
@@ -576,14 +659,14 @@
 		.gpio = 27, /* OIS_SYNC */
 		.settings = {
 			[GPIOMUX_ACTIVE]    = &cam_settings[0],
-			[GPIOMUX_SUSPENDED] = &cam_settings[1],
+			[GPIOMUX_SUSPENDED] = &gpio_suspend_config[1],
 		},
 	},
 	{
 		.gpio = 28, /* WEBCAM1_STANDBY */
 		.settings = {
 			[GPIOMUX_ACTIVE]    = &cam_settings[0],
-			[GPIOMUX_SUSPENDED] = &cam_settings[1],
+			[GPIOMUX_SUSPENDED] = &gpio_suspend_config[1],
 		},
 	},
 	{
@@ -615,6 +698,51 @@
 		},
 	},
 };
+
+static struct gpiomux_setting pri_auxpcm_act_cfg = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+
+static struct gpiomux_setting pri_auxpcm_sus_cfg = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct msm_gpiomux_config msm8974_pri_auxpcm_configs[] __initdata = {
+	{
+		.gpio = 65,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &pri_auxpcm_sus_cfg,
+			[GPIOMUX_ACTIVE] = &pri_auxpcm_act_cfg,
+		},
+	},
+	{
+		.gpio = 66,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &pri_auxpcm_sus_cfg,
+			[GPIOMUX_ACTIVE] = &pri_auxpcm_act_cfg,
+		},
+	},
+	{
+		.gpio = 67,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &pri_auxpcm_sus_cfg,
+			[GPIOMUX_ACTIVE] = &pri_auxpcm_act_cfg,
+		},
+	},
+	{
+		.gpio = 68,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &pri_auxpcm_sus_cfg,
+			[GPIOMUX_ACTIVE] = &pri_auxpcm_act_cfg,
+		},
+	},
+};
+
 static struct msm_gpiomux_config wcnss_5wire_interface[] = {
 	{
 		.gpio = 36,
@@ -842,9 +970,9 @@
 {
 	int rc;
 
-	rc = msm_gpiomux_init(NR_GPIO_IRQS);
+	rc = msm_gpiomux_init_dt();
 	if (rc) {
-		pr_err(KERN_ERR "msm_8974_init_gpiomux failed %d\n", rc);
+		pr_err("%s failed %d\n", __func__, rc);
 		return;
 	}
 
@@ -852,6 +980,8 @@
 	msm_gpiomux_install(msm_eth_configs, ARRAY_SIZE(msm_eth_configs));
 #endif
 	msm_gpiomux_install(msm_blsp_configs, ARRAY_SIZE(msm_blsp_configs));
+	msm_gpiomux_install(msm_blsp2_uart7_configs,
+			 ARRAY_SIZE(msm_blsp2_uart7_configs));
 	msm_gpiomux_install(wcnss_5wire_interface,
 				ARRAY_SIZE(wcnss_5wire_interface));
 
@@ -859,6 +989,8 @@
 			ARRAY_SIZE(msm8974_slimbus_config));
 
 	msm_gpiomux_install(msm_touch_configs, ARRAY_SIZE(msm_touch_configs));
+		msm_gpiomux_install(hap_lvl_shft_config,
+				ARRAY_SIZE(hap_lvl_shft_config));
 
 	msm_gpiomux_install(msm_sensor_configs, ARRAY_SIZE(msm_sensor_configs));
 
@@ -873,7 +1005,15 @@
 				ARRAY_SIZE(msm_hsic_hub_configs));
 
 	msm_gpiomux_install(msm_hdmi_configs, ARRAY_SIZE(msm_hdmi_configs));
-	msm_gpiomux_install(msm_mhl_configs, ARRAY_SIZE(msm_mhl_configs));
+	if (machine_is_msm8974_fluid())
+		msm_gpiomux_install(msm_mhl_configs,
+				    ARRAY_SIZE(msm_mhl_configs));
+
+	msm_gpiomux_install(msm8974_pri_auxpcm_configs,
+				 ARRAY_SIZE(msm8974_pri_auxpcm_configs));
+
+	msm_gpiomux_install_nowrite(msm_lcd_configs,
+			ARRAY_SIZE(msm_lcd_configs));
 
 	if (machine_is_msm8974_rumi())
 		msm_gpiomux_install(msm_rumi_blsp_configs,
diff --git a/arch/arm/mach-msm/board-8974.c b/arch/arm/mach-msm/board-8974.c
index 2f6d3d0..f864583 100644
--- a/arch/arm/mach-msm/board-8974.c
+++ b/arch/arm/mach-msm/board-8974.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -10,6 +10,7 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
@@ -41,7 +42,6 @@
 #include <mach/rpm-smd.h>
 #include <mach/rpm-regulator-smd.h>
 #include <mach/socinfo.h>
-#include <mach/msm_bus_board.h>
 #include "board-dt.h"
 #include "clock.h"
 #include "devices.h"
@@ -85,193 +85,6 @@
 	of_scan_flat_dt(dt_scan_for_memory_hole, msm8974_reserve_table);
 }
 
-#define BIMC_BASE	0xfc380000
-#define BIMC_SIZE	0x0006A000
-#define SYS_NOC_BASE	0xfc460000
-#define PERIPH_NOC_BASE 0xFC468000
-#define OCMEM_NOC_BASE	0xfc470000
-#define	MMSS_NOC_BASE	0xfc478000
-#define CONFIG_NOC_BASE	0xfc480000
-#define NOC_SIZE	0x00004000
-
-static struct resource bimc_res[] = {
-	{
-		.start = BIMC_BASE,
-		.end = BIMC_BASE + BIMC_SIZE,
-		.flags = IORESOURCE_MEM,
-		.name = "bimc_mem",
-	},
-};
-
-static struct resource ocmem_noc_res[] = {
-	{
-		.start = OCMEM_NOC_BASE,
-		.end = OCMEM_NOC_BASE + NOC_SIZE,
-		.flags = IORESOURCE_MEM,
-		.name = "ocmem_noc_mem",
-	},
-};
-
-static struct resource mmss_noc_res[] = {
-	{
-		.start = MMSS_NOC_BASE,
-		.end = MMSS_NOC_BASE + NOC_SIZE,
-		.flags = IORESOURCE_MEM,
-		.name = "mmss_noc_mem",
-	},
-};
-
-static struct resource sys_noc_res[] = {
-	{
-		.start = SYS_NOC_BASE,
-		.end = SYS_NOC_BASE + NOC_SIZE,
-		.flags = IORESOURCE_MEM,
-		.name = "sys_noc_mem",
-	},
-};
-
-static struct resource config_noc_res[] = {
-	{
-		.start = CONFIG_NOC_BASE,
-		.end = CONFIG_NOC_BASE + NOC_SIZE,
-		.flags = IORESOURCE_MEM,
-		.name = "config_noc_mem",
-	},
-};
-
-static struct resource periph_noc_res[] = {
-	{
-		.start = PERIPH_NOC_BASE,
-		.end = PERIPH_NOC_BASE + NOC_SIZE,
-		.flags = IORESOURCE_MEM,
-		.name = "periph_noc_mem",
-	},
-};
-
-static struct platform_device msm_bus_sys_noc = {
-	.name  = "msm_bus_fabric",
-	.id    =  MSM_BUS_FAB_SYS_NOC,
-	.num_resources = ARRAY_SIZE(sys_noc_res),
-	.resource = sys_noc_res,
-};
-
-static struct platform_device msm_bus_bimc = {
-	.name  = "msm_bus_fabric",
-	.id    = MSM_BUS_FAB_BIMC,
-	.num_resources = ARRAY_SIZE(bimc_res),
-	.resource = bimc_res,
-};
-
-static struct platform_device msm_bus_mmss_noc = {
-	.name  = "msm_bus_fabric",
-	.id    = MSM_BUS_FAB_MMSS_NOC,
-	.num_resources = ARRAY_SIZE(mmss_noc_res),
-	.resource = mmss_noc_res,
-};
-
-static struct platform_device msm_bus_ocmem_noc = {
-	.name  = "msm_bus_fabric",
-	.id    = MSM_BUS_FAB_OCMEM_NOC,
-	.num_resources = ARRAY_SIZE(ocmem_noc_res),
-	.resource = ocmem_noc_res,
-};
-
-static struct platform_device msm_bus_periph_noc = {
-	.name  = "msm_bus_fabric",
-	.id    = MSM_BUS_FAB_PERIPH_NOC,
-	.num_resources = ARRAY_SIZE(periph_noc_res),
-	.resource = periph_noc_res,
-};
-
-static struct platform_device msm_bus_config_noc = {
-	.name  = "msm_bus_fabric",
-	.id    = MSM_BUS_FAB_CONFIG_NOC,
-	.num_resources = ARRAY_SIZE(config_noc_res),
-	.resource = config_noc_res,
-};
-
-static struct platform_device msm_bus_ocmem_vnoc = {
-	.name  = "msm_bus_fabric",
-	.id    = MSM_BUS_FAB_OCMEM_VNOC,
-};
-
-static struct platform_device msm_fm_platform_init = {
-	.name  = "iris_fm",
-	.id    = -1,
-};
-
-static struct platform_device *msm_bus_8974_devices[] = {
-	&msm_bus_sys_noc,
-	&msm_bus_bimc,
-	&msm_bus_mmss_noc,
-	&msm_bus_ocmem_noc,
-	&msm_bus_periph_noc,
-	&msm_bus_config_noc,
-	&msm_bus_ocmem_vnoc,
-	&msm_fm_platform_init,
-};
-
-static ssize_t mxt336s_vkeys_show(struct kobject *kobj,
-			struct kobj_attribute *attr, char *buf)
-{
-	return snprintf(buf, 200,
-	__stringify(EV_KEY) ":" __stringify(KEY_BACK) ":62:1345:90:90" \
-	":" __stringify(EV_KEY) ":" __stringify(KEY_MENU) ":240:1345:90:90" \
-	":" __stringify(EV_KEY) ":" __stringify(KEY_HOME) ":470:1345:90:90" \
-	":" __stringify(EV_KEY) ":" __stringify(KEY_SEARCH) ":658:1345:90:90" \
-	"\n");
-}
-
-static struct kobj_attribute mxt336s_vkeys_attr = {
-	.attr = {
-		.mode = S_IRUGO,
-	},
-	.show = &mxt336s_vkeys_show,
-};
-
-static struct attribute *mxt336s_properties_attrs[] = {
-	&mxt336s_vkeys_attr.attr,
-	NULL
-};
-
-static struct attribute_group mxt336s_properties_attr_group = {
-	.attrs = mxt336s_properties_attrs,
-};
-
-static void mxt_init_vkeys_8974(void)
-{
-	int rc = 0;
-	static struct kobject *mxt336s_properties_kobj;
-
-	mxt336s_vkeys_attr.attr.name = "virtualkeys.atmel_mxt_ts";
-	mxt336s_properties_kobj = kobject_create_and_add("board_properties",
-								NULL);
-	if (mxt336s_properties_kobj)
-		rc = sysfs_create_group(mxt336s_properties_kobj,
-					&mxt336s_properties_attr_group);
-	if (!mxt336s_properties_kobj || rc)
-		pr_err("%s: failed to create board_properties\n",
-				__func__);
-
-	return;
-}
-
-static void __init msm8974_init_buses(void)
-{
-#ifdef CONFIG_MSM_BUS_SCALING
-	msm_bus_sys_noc.dev.platform_data =
-		&msm_bus_8974_sys_noc_pdata;
-	msm_bus_bimc.dev.platform_data = &msm_bus_8974_bimc_pdata;
-	msm_bus_mmss_noc.dev.platform_data = &msm_bus_8974_mmss_noc_pdata;
-	msm_bus_ocmem_noc.dev.platform_data = &msm_bus_8974_ocmem_noc_pdata;
-	msm_bus_periph_noc.dev.platform_data = &msm_bus_8974_periph_noc_pdata;
-	msm_bus_config_noc.dev.platform_data = &msm_bus_8974_config_noc_pdata;
-	msm_bus_ocmem_vnoc.dev.platform_data = &msm_bus_8974_ocmem_vnoc_pdata;
-#endif
-	platform_add_devices(msm_bus_8974_devices,
-				ARRAY_SIZE(msm_bus_8974_devices));
-};
-
 /*
  * Used to satisfy dependencies for devices that need to be
  * run early or in a particular order. Most likely your device doesn't fall
@@ -291,14 +104,14 @@
 		msm_clock_init(&msm8974_rumi_clock_init_data);
 	else
 		msm_clock_init(&msm8974_clock_init_data);
-	msm8974_init_buses();
 	msm_thermal_device_init();
-	mxt_init_vkeys_8974();
 }
 
 static struct of_dev_auxdata msm8974_auxdata_lookup[] __initdata = {
 	OF_DEV_AUXDATA("qcom,hsusb-otg", 0xF9A55000, \
 			"msm_otg", NULL),
+	OF_DEV_AUXDATA("qcom,ehci-host", 0xF9A55000, \
+			"msm_ehci_host", NULL),
 	OF_DEV_AUXDATA("qcom,dwc-usb3-msm", 0xF9200000, \
 			"msm_dwc3", NULL),
 	OF_DEV_AUXDATA("qcom,usb-bam-msm", 0xF9304000, \
@@ -313,34 +126,6 @@
 			"msm_sdcc.3", NULL),
 	OF_DEV_AUXDATA("qcom,msm-sdcc", 0xF98E4000, \
 			"msm_sdcc.4", NULL),
-	OF_DEV_AUXDATA("arm,coresight-tmc", 0xFC322000, \
-			"coresight-tmc-etr", NULL),
-	OF_DEV_AUXDATA("arm,coresight-tpiu", 0xFC318000, \
-			"coresight-tpiu", NULL),
-	OF_DEV_AUXDATA("qcom,coresight-replicator", 0xFC31C000, \
-			"coresight-replicator", NULL),
-	OF_DEV_AUXDATA("arm,coresight-tmc", 0xFC307000, \
-			"coresight-tmc-etf", NULL),
-	OF_DEV_AUXDATA("arm,coresight-funnel", 0xFC31B000, \
-			"coresight-funnel-merg", NULL),
-	OF_DEV_AUXDATA("arm,coresight-funnel", 0xFC319000, \
-			"coresight-funnel-in0", NULL),
-	OF_DEV_AUXDATA("arm,coresight-funnel", 0xFC31A000, \
-			"coresight-funnel-in1", NULL),
-	OF_DEV_AUXDATA("arm,coresight-funnel", 0xFC345000, \
-			"coresight-funnel-kpss", NULL),
-	OF_DEV_AUXDATA("arm,coresight-funnel", 0xFC364000, \
-			"coresight-funnel-mmss", NULL),
-	OF_DEV_AUXDATA("arm,coresight-stm", 0xFC321000, \
-			"coresight-stm", NULL),
-	OF_DEV_AUXDATA("arm,coresight-etm", 0xFC33C000, \
-			"coresight-etm0", NULL),
-	OF_DEV_AUXDATA("arm,coresight-etm", 0xFC33D000, \
-			"coresight-etm1", NULL),
-	OF_DEV_AUXDATA("arm,coresight-etm", 0xFC33E000, \
-			"coresight-etm2", NULL),
-	OF_DEV_AUXDATA("arm,coresight-etm", 0xFC33F000, \
-			"coresight-etm3", NULL),
 	OF_DEV_AUXDATA("qcom,msm-rng", 0xF9BFF000, \
 			"msm_rng", NULL),
 	OF_DEV_AUXDATA("qcom,qseecom", 0xFE806000, \
@@ -352,24 +137,26 @@
 			"qcedev.0", NULL),
 	OF_DEV_AUXDATA("qcom,qcrypto", 0xFD440000, \
 			"qcrypto.0", NULL),
+	OF_DEV_AUXDATA("qcom,hsic-host", 0xF9A00000, \
+			"msm_hsic_host", NULL),
 	{}
 };
 
 static void __init msm8974_map_io(void)
 {
 	msm_map_8974_io();
-	if (socinfo_init() < 0)
-		pr_err("%s: socinfo_init() failed\n", __func__);
 }
 
 void __init msm8974_init(void)
 {
 	struct of_dev_auxdata *adata = msm8974_auxdata_lookup;
 
+	if (socinfo_init() < 0)
+		pr_err("%s: socinfo_init() failed\n", __func__);
+
 	msm_8974_init_gpiomux();
 	regulator_has_full_constraints();
 	of_platform_populate(NULL, of_default_bus_match_table, adata, NULL);
-
 	msm8974_add_drivers();
 }
 
diff --git a/arch/arm/mach-msm/board-9615-display.c b/arch/arm/mach-msm/board-9615-display.c
index 4e4ce7a..4b355d0 100644
--- a/arch/arm/mach-msm/board-9615-display.c
+++ b/arch/arm/mach-msm/board-9615-display.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/board-9615-gpiomux.c b/arch/arm/mach-msm/board-9615-gpiomux.c
index e5b7678..402e7f4 100644
--- a/arch/arm/mach-msm/board-9615-gpiomux.c
+++ b/arch/arm/mach-msm/board-9615-gpiomux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/board-9615-regulator.c b/arch/arm/mach-msm/board-9615-regulator.c
index 2561def..0a900e1 100644
--- a/arch/arm/mach-msm/board-9615-regulator.c
+++ b/arch/arm/mach-msm/board-9615-regulator.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/board-9615-storage.c b/arch/arm/mach-msm/board-9615-storage.c
index 6cb34f8..1a05c08 100644
--- a/arch/arm/mach-msm/board-9615-storage.c
+++ b/arch/arm/mach-msm/board-9615-storage.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index 2392f57..f609bbc 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -254,6 +254,8 @@
 		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
 	{"pa_therm0", ADC_MPP_1_AMUX3, CHAN_PATH_SCALING1, AMUX_RSV1,
 		ADC_DECIMATION_TYPE2, ADC_SCALE_PA_THERM},
+	{"xo_therm", CHANNEL_MUXOFF, CHAN_PATH_SCALING1, AMUX_RSV0,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_XOTHERM},
 };
 
 static struct pm8xxx_adc_properties pm8018_adc_data = {
@@ -913,6 +915,7 @@
 	&msm_stub_codec,
 	&msm_voice,
 	&msm_dtmf,
+	&msm_host_pcm_voice,
 	&msm_voip,
 	&msm_i2s_cpudai0,
 	&msm_i2s_cpudai1,
diff --git a/arch/arm/mach-msm/board-9615.h b/arch/arm/mach-msm/board-9615.h
index 68d9951..685e413 100644
--- a/arch/arm/mach-msm/board-9615.h
+++ b/arch/arm/mach-msm/board-9615.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/board-9625-gpiomux.c b/arch/arm/mach-msm/board-9625-gpiomux.c
index 686bb41..1b76441 100644
--- a/arch/arm/mach-msm/board-9625-gpiomux.c
+++ b/arch/arm/mach-msm/board-9625-gpiomux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -280,9 +280,9 @@
 {
 	int rc;
 
-	rc = msm_gpiomux_init(NR_GPIO_IRQS);
+	rc = msm_gpiomux_init_dt();
 	if (rc) {
-		pr_err(KERN_ERR "msm9625_init_gpiomux failed %d\n", rc);
+		pr_err("%s failed %d\n", __func__, rc);
 		return;
 	}
 
diff --git a/arch/arm/mach-msm/board-9625.c b/arch/arm/mach-msm/board-9625.c
index f6a354f..923dc2a 100644
--- a/arch/arm/mach-msm/board-9625.c
+++ b/arch/arm/mach-msm/board-9625.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -10,6 +10,7 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
@@ -111,17 +112,21 @@
 			"msm-tsens", NULL),
 	OF_DEV_AUXDATA("qcom,usb-bam-msm", 0xF9A44000, \
 			"usb_bam", NULL),
+	OF_DEV_AUXDATA("qcom,hsic-host", 0xF9A15000, \
+			"msm_hsic_host", NULL),
 	{}
 };
 
 static void __init msm9625_early_memory(void)
 {
 	reserve_info = &msm9625_reserve_info;
-	of_scan_flat_dt(dt_scan_for_memory_reserve, msm9625_reserve_table);
+	of_scan_flat_dt(dt_scan_for_memory_hole, msm9625_reserve_table);
 }
 
 static void __init msm9625_reserve(void)
 {
+	reserve_info = &msm9625_reserve_info;
+	of_scan_flat_dt(dt_scan_for_memory_reserve, msm9625_reserve_table);
 	msm_reserve();
 }
 
diff --git a/arch/arm/mach-msm/board-dt.c b/arch/arm/mach-msm/board-dt.c
index 74b0d0d..5d2fdf9 100644
--- a/arch/arm/mach-msm/board-dt.c
+++ b/arch/arm/mach-msm/board-dt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -14,13 +14,16 @@
 #include <linux/kernel.h>
 #include <linux/of.h>
 #include <linux/of_irq.h>
+#include <linux/of_fdt.h>
 #include <linux/mfd/wcd9xxx/core.h>
 #include <asm/arch_timer.h>
 #include <asm/mach/time.h>
+#include <asm/mach/map.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/hardware/gic.h>
 #include <mach/mpm.h>
 #include <mach/qpnp-int.h>
+#include <mach/msm_iomap.h>
 #include <mach/scm.h>
 
 #include "board-dt.h"
@@ -75,3 +78,40 @@
 	l2x0_of_init(0, ~0UL);
 	msm_dt_init_irq();
 }
+
+int __init msm_scan_dt_map_imem(unsigned long node, const char *uname,
+			int depth, void *data)
+{
+	unsigned int *imem_prop;
+	unsigned long imem_prop_len;
+	struct map_desc map;
+	int ret;
+	const char *compat = "qcom,msm-imem";
+
+	ret = of_flat_dt_is_compatible(node, compat);
+
+	if (!ret)
+		return 0;
+
+	imem_prop = of_get_flat_dt_prop(node, "reg",
+					&imem_prop_len);
+
+	if (!imem_prop) {
+		WARN(1, "IMEM reg field not found\n");
+		return 0;
+	}
+
+	if (imem_prop_len != (2*sizeof(u32))) {
+		WARN(1, "IMEM range malformed\n");
+		return 0;
+	}
+
+	map.virtual = (unsigned long)MSM_IMEM_BASE;
+	map.pfn = __phys_to_pfn(be32_to_cpu(imem_prop[0]));
+	map.length = be32_to_cpu(imem_prop[1]);
+	map.type = MT_DEVICE;
+	iotable_init(&map, 1);
+	pr_info("IMEM DT static mapping successful\n");
+
+	return 1;
+}
diff --git a/arch/arm/mach-msm/board-dt.h b/arch/arm/mach-msm/board-dt.h
index cc3e92c..03ffa0b 100644
--- a/arch/arm/mach-msm/board-dt.h
+++ b/arch/arm/mach-msm/board-dt.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
@@ -14,3 +14,5 @@
 void __init msm_dt_init_irq(void);
 void __init msm_dt_init_irq_nompm(void);
 void __init msm_dt_init_irq_l2x0(void);
+int __init msm_scan_dt_map_imem(unsigned long node, const char *uname,
+				int depth, void *data);
diff --git a/arch/arm/mach-msm/board-fsm9xxx.c b/arch/arm/mach-msm/board-fsm9xxx.c
index 274b338..cb2e766 100644
--- a/arch/arm/mach-msm/board-fsm9xxx.c
+++ b/arch/arm/mach-msm/board-fsm9xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -1003,9 +1003,7 @@
 	msm_shared_ram_phys = 0x00100000;
 	msm_map_fsm9xxx_io();
 	if (socinfo_init() < 0)
-		pr_err("%s: socinfo_init() failed!\n",
-		       __func__);
-
+		pr_err("socinfo_init() failed!\n");
 }
 
 MACHINE_START(FSM9XXX_SURF, "QCT FSM9XXX")
diff --git a/arch/arm/mach-msm/board-msm7627-regulator.c b/arch/arm/mach-msm/board-msm7627-regulator.c
index 7437911..3ef748d 100644
--- a/arch/arm/mach-msm/board-msm7627-regulator.c
+++ b/arch/arm/mach-msm/board-msm7627-regulator.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/arm/mach-msm/board-msm7627-regulator.h b/arch/arm/mach-msm/board-msm7627-regulator.h
index d82c5c0..aaf9598 100644
--- a/arch/arm/mach-msm/board-msm7627-regulator.h
+++ b/arch/arm/mach-msm/board-msm7627-regulator.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/arm/mach-msm/board-msm7627a-bt.c b/arch/arm/mach-msm/board-msm7627a-bt.c
index 1c2d8a2..3e90a15 100644
--- a/arch/arm/mach-msm/board-msm7627a-bt.c
+++ b/arch/arm/mach-msm/board-msm7627a-bt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -485,7 +485,7 @@
 
 	const struct bahama_config_register *p;
 
-	u8 version;
+	int version;
 
 	const struct bahama_config_register v10_bt_on[] = {
 		{ 0xE9, 0x00, 0xFF },
@@ -567,7 +567,7 @@
 	u8 offset = 0; /* index into bahama configs */
 	on = on ? 1 : 0;
 	version = marimba_read_bahama_ver(&config);
-	if ((int)version < 0 || version == BAHAMA_VER_UNSUPPORTED) {
+	if (version < 0 || version == BAHAMA_VER_UNSUPPORTED) {
 		dev_err(&msm_bt_power_device.dev, "%s : Bahama "
 			"version read Error, version = %d\n",
 			__func__, version);
@@ -602,10 +602,10 @@
 				__func__, (p+i)->reg,
 				value, (p+i)->mask);
 		value = 0;
-		rc = marimba_read_bit_mask(&config,
+		/* Ignoring the read failure as it is only for check */
+		if (marimba_read_bit_mask(&config,
 				(p+i)->reg, &value,
-				sizeof((p+i)->value), (p+i)->mask);
-		if (rc < 0)
+				sizeof((p+i)->value), (p+i)->mask) < 0)
 			dev_err(&msm_bt_power_device.dev,
 				"%s marimba_read_bit_mask- error",
 				__func__);
@@ -678,7 +678,6 @@
 			dev_err(&msm_bt_power_device.dev,
 				"%s: could not %sable regulator %s: %d\n",
 					__func__, "dis", bt_vregs[i].name, rc);
-			goto reg_disable;
 		}
 	}
 
@@ -687,8 +686,8 @@
 	if (on)
 		regulator_disable(bt_vregs[i].reg);
 reg_disable:
-	while (i) {
-		if (on) {
+	if (on) {
+		while (i) {
 			i--;
 			regulator_disable(bt_vregs[i].reg);
 			regulator_put(bt_vregs[i].reg);
@@ -835,7 +834,10 @@
 	int pin, rc = 0;
 	const char *id = "BTPW";
 	int cid = 0;
+	int bt_state = 0;
+	struct marimba config = { .mod_id =  SLAVE_ID_BAHAMA};
 
+	pr_debug("%s: on = %d\n", __func__, on);
 	cid = adie_get_detected_connectivity_type();
 	if (cid != BAHAMA_ID) {
 		pr_err("%s: unexpected adie connectivity type: %d\n",
@@ -854,7 +856,7 @@
 		if (rc < 0) {
 			pr_err("%s: bluetooth_switch_regulators rc = %d",
 					__func__, rc);
-			goto exit;
+			goto fail_gpio;
 		}
 		/*setup BT GPIO lines*/
 		for (pin = 0; pin < ARRAY_SIZE(bt_config_power_on);
@@ -874,7 +876,7 @@
 			PMAPP_CLOCK_VOTE_ON);
 		if (rc < 0) {
 			pr_err("Failed to vote for TCXO_D1 ON\n");
-			goto fail_clock;
+			goto fail_gpio_cfg;
 		}
 		msleep(20);
 
@@ -882,7 +884,7 @@
 		rc = bahama_bt(1);
 		if (rc < 0) {
 			pr_err("%s: bahama_bt rc = %d", __func__, rc);
-			goto fail_i2c;
+			goto fail_clock;
 		}
 		msleep(20);
 
@@ -891,7 +893,7 @@
 		if (rc < 0) {
 			pr_err("%s: msm_bahama_setup_pcm_i2s , rc =%d\n",
 				__func__, rc);
-				goto fail_power;
+			goto fail_i2c;
 			}
 		rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_D1,
 				  PMAPP_CLOCK_VOTE_PIN_CTRL);
@@ -900,26 +902,28 @@
 					__func__, rc);
 
 	} else {
-		rc = bahama_bt(0);
-		if (rc < 0)
-			pr_err("%s: bahama_bt rc = %d", __func__, rc);
+		bt_state = marimba_get_bt_status(&config);
+		if (!bt_state) {
+			pr_err("%s: BT is already turned OFF.\n", __func__);
+			return 0;
+		}
 
 		rc = msm_bahama_setup_pcm_i2s(BT_PCM_OFF);
 		if (rc < 0) {
 			pr_err("%s: msm_bahama_setup_pcm_i2s, rc =%d\n",
 				__func__, rc);
 		}
-		rc = bt_set_gpio(on);
-		if (rc) {
-			pr_err("%s: bt_set_gpio = %d\n",
-					__func__, rc);
-		}
 fail_i2c:
+		rc = bahama_bt(0);
+		if (rc < 0)
+			pr_err("%s: bahama_bt rc = %d", __func__, rc);
+
+fail_clock:
 		rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_D1,
 				  PMAPP_CLOCK_VOTE_OFF);
 		if (rc < 0)
 			pr_err("%s: Failed to vote Off D1\n", __func__);
-fail_clock:
+fail_gpio_cfg:
 		for (pin = 0; pin < ARRAY_SIZE(bt_config_power_off);
 			pin++) {
 			rc = gpio_tlmm_config(bt_config_power_off[pin],
@@ -936,6 +940,12 @@
 		if (rc < 0) {
 			pr_err("%s: switch_regulators : rc = %d",\
 				__func__, rc);
+		}
+fail_gpio:
+		rc = bt_set_gpio(0);
+		if (rc) {
+			pr_err("%s: bt_set_gpio = %d\n",
+					__func__, rc);
 			goto exit;
 		}
 	}
diff --git a/arch/arm/mach-msm/board-msm7627a-camera.c b/arch/arm/mach-msm/board-msm7627a-camera.c
index 79ad996..119b73b 100644
--- a/arch/arm/mach-msm/board-msm7627a-camera.c
+++ b/arch/arm/mach-msm/board-msm7627a-camera.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/board-msm7627a-display.c b/arch/arm/mach-msm/board-msm7627a-display.c
index 1249c7b..52ab97d 100644
--- a/arch/arm/mach-msm/board-msm7627a-display.c
+++ b/arch/arm/mach-msm/board-msm7627a-display.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/board-msm7627a-io.c b/arch/arm/mach-msm/board-msm7627a-io.c
index 4ec1d33..3acbfc6 100644
--- a/arch/arm/mach-msm/board-msm7627a-io.c
+++ b/arch/arm/mach-msm/board-msm7627a-io.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/board-msm7627a-storage.c b/arch/arm/mach-msm/board-msm7627a-storage.c
index 5351d41..6aff9b6 100644
--- a/arch/arm/mach-msm/board-msm7627a-storage.c
+++ b/arch/arm/mach-msm/board-msm7627a-storage.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/board-msm7627a-wlan.c b/arch/arm/mach-msm/board-msm7627a-wlan.c
index ab29fc5..a84b43b 100644
--- a/arch/arm/mach-msm/board-msm7627a-wlan.c
+++ b/arch/arm/mach-msm/board-msm7627a-wlan.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/board-msm7627a.h b/arch/arm/mach-msm/board-msm7627a.h
index cd7c1df..37d8031 100644
--- a/arch/arm/mach-msm/board-msm7627a.h
+++ b/arch/arm/mach-msm/board-msm7627a.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/board-msm7x27.c b/arch/arm/mach-msm/board-msm7x27.c
index a7fed3e..5f0d75f 100644
--- a/arch/arm/mach-msm/board-msm7x27.c
+++ b/arch/arm/mach-msm/board-msm7x27.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/board-msm7x27a-regulator.c b/arch/arm/mach-msm/board-msm7x27a-regulator.c
index c67ab7f..7c140cb 100644
--- a/arch/arm/mach-msm/board-msm7x27a-regulator.c
+++ b/arch/arm/mach-msm/board-msm7x27a-regulator.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/board-msm7x27a-regulator.h b/arch/arm/mach-msm/board-msm7x27a-regulator.h
index 01dc70e..999e2eb 100644
--- a/arch/arm/mach-msm/board-msm7x27a-regulator.h
+++ b/arch/arm/mach-msm/board-msm7x27a-regulator.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 3104aac..d20584a 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/board-msm7x30-regulator.c b/arch/arm/mach-msm/board-msm7x30-regulator.c
index a3f5ee1..193da15 100644
--- a/arch/arm/mach-msm/board-msm7x30-regulator.c
+++ b/arch/arm/mach-msm/board-msm7x30-regulator.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/arm/mach-msm/board-msm7x30-regulator.h b/arch/arm/mach-msm/board-msm7x30-regulator.h
index bd9b02d..12a9122 100644
--- a/arch/arm/mach-msm/board-msm7x30-regulator.h
+++ b/arch/arm/mach-msm/board-msm7x30-regulator.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index 9822aa9..0654a0d 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
@@ -11,6 +11,7 @@
  *
  */
 
+#include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/irq.h>
 #include <linux/gpio.h>
@@ -7349,8 +7350,7 @@
 	msm_shared_ram_phys = 0x00100000;
 	msm_map_msm7x30_io();
 	if (socinfo_init() < 0)
-		printk(KERN_ERR "%s: socinfo_init() failed!\n",
-		       __func__);
+		pr_err("socinfo_init() failed!\n");
 }
 
 static void __init msm7x30_init_early(void)
diff --git a/arch/arm/mach-msm/board-msm8x60-camera.c b/arch/arm/mach-msm/board-msm8x60-camera.c
index 7e5f022..3a09fa3 100644
--- a/arch/arm/mach-msm/board-msm8x60-camera.c
+++ b/arch/arm/mach-msm/board-msm8x60-camera.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012 The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/board-msm8x60-vcm.c b/arch/arm/mach-msm/board-msm8x60-vcm.c
index 6078367..de1c1e2 100644
--- a/arch/arm/mach-msm/board-msm8x60-vcm.c
+++ b/arch/arm/mach-msm/board-msm8x60-vcm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index d4205bd..02a753a 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -11,6 +11,7 @@
  *
  */
 
+#include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
@@ -5298,6 +5299,7 @@
 	&msm_device_tz_log,
 	&msm_rtb_device,
 	&msm8660_iommu_domain_device,
+	&msm8660_pm_8x60,
 };
 
 #ifdef CONFIG_ION_MSM
@@ -7540,9 +7542,9 @@
 {
 	msm_shared_ram_phys = MSM_SHARED_RAM_PHYS;
 	msm_map_msm8x60_io();
-
 	if (socinfo_init() < 0)
 		pr_err("socinfo_init() failed!\n");
+
 }
 
 /*
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index f41437e..9c9ccaa 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
@@ -695,6 +695,7 @@
 	.init_data = &ncp6335d_init_data,
 	.default_vsel = NCP6335D_VSEL0,
 	.slew_rate_ns = 166,
+	.sleep_enable = true,
 };
 
 static struct i2c_board_info i2c2_info[] __initdata = {
diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c
index 146c8a8..e3b42bc 100644
--- a/arch/arm/mach-msm/board-qsd8x50.c
+++ b/arch/arm/mach-msm/board-qsd8x50.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
@@ -2522,8 +2522,7 @@
 	msm_map_qsd8x50_io();
 	qsd8x50_allocate_memory_regions();
 	if (socinfo_init() < 0)
-		printk(KERN_ERR "%s: socinfo_init() failed!\n",
-		       __func__);
+		pr_err("socinfo_init() failed!\n");
 }
 
 MACHINE_START(QSD8X50_SURF, "QCT QSD8X50 SURF")
diff --git a/arch/arm/mach-msm/board-storage-common-a.h b/arch/arm/mach-msm/board-storage-common-a.h
index 7737819..f651677 100644
--- a/arch/arm/mach-msm/board-storage-common-a.h
+++ b/arch/arm/mach-msm/board-storage-common-a.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/btpintest.c b/arch/arm/mach-msm/btpintest.c
index 97a511e..543d557 100644
--- a/arch/arm/mach-msm/btpintest.c
+++ b/arch/arm/mach-msm/btpintest.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/cache_erp.c b/arch/arm/mach-msm/cache_erp.c
index 6b8f58b..ddea91c 100644
--- a/arch/arm/mach-msm/cache_erp.c
+++ b/arch/arm/mach-msm/cache_erp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/clock-7x30.c b/arch/arm/mach-msm/clock-7x30.c
index 3f59035..c991494 100644
--- a/arch/arm/mach-msm/clock-7x30.c
+++ b/arch/arm/mach-msm/clock-7x30.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/clock-7x30.h b/arch/arm/mach-msm/clock-7x30.h
index 1410445..9fb3240 100644
--- a/arch/arm/mach-msm/clock-7x30.h
+++ b/arch/arm/mach-msm/clock-7x30.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/clock-8226.c b/arch/arm/mach-msm/clock-8226.c
new file mode 100644
index 0000000..a963c19
--- /dev/null
+++ b/arch/arm/mach-msm/clock-8226.c
@@ -0,0 +1,3681 @@
+/* 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/init.h>
+#include <linux/err.h>
+#include <linux/ctype.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/iopoll.h>
+#include <linux/regulator/consumer.h>
+
+#include <mach/rpm-regulator-smd.h>
+#include <mach/socinfo.h>
+#include <mach/rpm-smd.h>
+
+#include "clock-local2.h"
+#include "clock-pll.h"
+#include "clock-rpm.h"
+#include "clock-voter.h"
+#include "clock-mdss-8974.h"
+#include "clock.h"
+
+enum {
+	GCC_BASE,
+	MMSS_BASE,
+	LPASS_BASE,
+	APCS_BASE,
+	APCS_PLL_BASE,
+	N_BASES,
+};
+
+static void __iomem *virt_bases[N_BASES];
+
+#define GCC_REG_BASE(x) (void __iomem *)(virt_bases[GCC_BASE] + (x))
+#define MMSS_REG_BASE(x) (void __iomem *)(virt_bases[MMSS_BASE] + (x))
+#define LPASS_REG_BASE(x) (void __iomem *)(virt_bases[LPASS_BASE] + (x))
+#define APCS_REG_BASE(x) (void __iomem *)(virt_bases[APCS_BASE] + (x))
+
+/* Mux source select values */
+#define xo_source_val  0
+#define gpll0_source_val 1
+#define gpll1_source_val 2
+
+#define xo_mm_source_val 0
+#define mmpll0_pll_mm_source_val 1
+#define mmpll1_pll_mm_source_val 2
+#define mmpll2_pll_mm_source_val 3
+#define gpll0_mm_source_val 5
+#define dsipll_750_mm_source_val 1
+#define dsipll_667_mm_source_val 1
+
+#define gpll1_hsic_source_val 4
+
+#define xo_lpass_source_val 0
+#define lpaaudio_pll_lpass_source_val 1
+#define gpll0_lpass_source_val 5
+
+/* Prevent a divider of -1 */
+#define FIXDIV(div) (div ? (2 * (div) - 1) : (0))
+
+#define F_GCC(f, s, div, m, n) \
+	{ \
+		.freq_hz = (f), \
+		.src_clk = &s.c, \
+		.m_val = (m), \
+		.n_val = ~((n)-(m)) * !!(n), \
+		.d_val = ~(n),\
+		.div_src_val = BVAL(4, 0, (int)(FIXDIV(div))) \
+			| BVAL(10, 8, s##_source_val), \
+	}
+
+#define F_MMSS(f, s, div, m, n) \
+	{ \
+		.freq_hz = (f), \
+		.src_clk = &s.c, \
+		.m_val = (m), \
+		.n_val = ~((n)-(m)) * !!(n), \
+		.d_val = ~(n),\
+		.div_src_val = BVAL(4, 0, (int)(FIXDIV(div))) \
+			| BVAL(10, 8, s##_mm_source_val), \
+	}
+
+#define F_MDSS(f, s, div, m, n) \
+	{ \
+		.freq_hz = (f), \
+		.m_val = (m), \
+		.n_val = ~((n)-(m)) * !!(n), \
+		.d_val = ~(n),\
+		.div_src_val = BVAL(4, 0, (int)(FIXDIV(div))) \
+			| BVAL(10, 8, s##_mm_source_val), \
+	}
+
+#define F_HSIC(f, s, div, m, n) \
+	{ \
+		.freq_hz = (f), \
+		.src_clk = &s.c, \
+		.m_val = (m), \
+		.n_val = ~((n)-(m)) * !!(n), \
+		.d_val = ~(n),\
+		.div_src_val = BVAL(4, 0, (int)(FIXDIV(div))) \
+			| BVAL(10, 8, s##_hsic_source_val), \
+	}
+
+#define F_LPASS(f, s, div, m, n) \
+	{ \
+		.freq_hz = (f), \
+		.src_clk = &s.c, \
+		.m_val = (m), \
+		.n_val = ~((n)-(m)) * !!(n), \
+		.d_val = ~(n),\
+		.div_src_val = BVAL(4, 0, (int)(FIXDIV(div))) \
+			| BVAL(10, 8, s##_lpass_source_val), \
+	}
+
+#define F_APCS_PLL(f, l, m, n, pre_div, post_div, vco) \
+	{ \
+		.freq_hz = (f), \
+		.l_val = (l), \
+		.m_val = (m), \
+		.n_val = (n), \
+		.pre_div_val = BVAL(12, 12, (pre_div)), \
+		.post_div_val = BVAL(9, 8, (post_div)), \
+		.vco_val = BVAL(29, 28, (vco)), \
+	}
+
+#define VDD_DIG_FMAX_MAP1(l1, f1) \
+	.vdd_class = &vdd_dig, \
+	.fmax = (unsigned long[VDD_DIG_NUM]) {  \
+		[VDD_DIG_##l1] = (f1),          \
+	},                                      \
+	.num_fmax = VDD_DIG_NUM
+
+#define VDD_DIG_FMAX_MAP2(l1, f1, l2, f2) \
+	.vdd_class = &vdd_dig, \
+	.fmax = (unsigned long[VDD_DIG_NUM]) {  \
+		[VDD_DIG_##l1] = (f1),          \
+		[VDD_DIG_##l2] = (f2),          \
+	},                                      \
+	.num_fmax = VDD_DIG_NUM
+
+#define VDD_DIG_FMAX_MAP3(l1, f1, l2, f2, l3, f3) \
+	.vdd_class = &vdd_dig, \
+	.fmax = (unsigned long[VDD_DIG_NUM]) {  \
+		[VDD_DIG_##l1] = (f1),          \
+		[VDD_DIG_##l2] = (f2),          \
+		[VDD_DIG_##l3] = (f3),          \
+	},                                      \
+	.num_fmax = VDD_DIG_NUM
+
+enum vdd_dig_levels {
+	VDD_DIG_NONE,
+	VDD_DIG_LOW,
+	VDD_DIG_NOMINAL,
+	VDD_DIG_HIGH,
+	VDD_DIG_NUM
+};
+
+static const int vdd_corner[] = {
+	[VDD_DIG_NONE]	  = RPM_REGULATOR_CORNER_NONE,
+	[VDD_DIG_LOW]	  = RPM_REGULATOR_CORNER_SVS_SOC,
+	[VDD_DIG_NOMINAL] = RPM_REGULATOR_CORNER_NORMAL,
+	[VDD_DIG_HIGH]	  = RPM_REGULATOR_CORNER_SUPER_TURBO,
+};
+
+static struct regulator *vdd_dig_reg;
+
+static int set_vdd_dig(struct clk_vdd_class *vdd_class, int level)
+{
+	return regulator_set_voltage(vdd_dig_reg, vdd_corner[level],
+					RPM_REGULATOR_CORNER_SUPER_TURBO);
+}
+
+static DEFINE_VDD_CLASS(vdd_dig, set_vdd_dig, VDD_DIG_NUM);
+
+#define RPM_MISC_CLK_TYPE	0x306b6c63
+#define RPM_BUS_CLK_TYPE	0x316b6c63
+#define RPM_MEM_CLK_TYPE	0x326b6c63
+
+#define RPM_SMD_KEY_ENABLE	0x62616E45
+
+#define CXO_ID			0x0
+#define QDSS_ID			0x1
+
+#define PNOC_ID		0x0
+#define SNOC_ID		0x1
+#define CNOC_ID		0x2
+#define MMSSNOC_AHB_ID  0x3
+
+#define BIMC_ID		0x0
+#define OXILI_ID	0x1
+#define OCMEM_ID	0x2
+
+#define D0_ID		 1
+#define D1_ID		 2
+#define A0_ID		 4
+#define A1_ID		 5
+#define A2_ID		 6
+#define DIFF_CLK_ID	 7
+#define DIV_CLK1_ID	11
+#define DIV_CLK2_ID	12
+
+DEFINE_CLK_RPM_SMD(pnoc_clk, pnoc_a_clk, RPM_BUS_CLK_TYPE, PNOC_ID, NULL);
+DEFINE_CLK_RPM_SMD(snoc_clk, snoc_a_clk, RPM_BUS_CLK_TYPE, SNOC_ID, NULL);
+DEFINE_CLK_RPM_SMD(cnoc_clk, cnoc_a_clk, RPM_BUS_CLK_TYPE, CNOC_ID, NULL);
+DEFINE_CLK_RPM_SMD(mmssnoc_ahb_clk, mmssnoc_ahb_a_clk, RPM_BUS_CLK_TYPE,
+			MMSSNOC_AHB_ID, NULL);
+
+DEFINE_CLK_RPM_SMD(bimc_clk, bimc_a_clk, RPM_MEM_CLK_TYPE, BIMC_ID, NULL);
+DEFINE_CLK_RPM_SMD(ocmemgx_clk, ocmemgx_a_clk, RPM_MEM_CLK_TYPE, OCMEM_ID,
+			NULL);
+DEFINE_CLK_RPM_SMD(gfx3d_clk_src, gfx3d_a_clk_src, RPM_MEM_CLK_TYPE, OXILI_ID,
+			NULL);
+
+DEFINE_CLK_RPM_SMD_BRANCH(xo, xo_a_clk,
+				RPM_MISC_CLK_TYPE, CXO_ID, 19200000);
+DEFINE_CLK_RPM_SMD_QDSS(qdss_clk, qdss_a_clk, RPM_MISC_CLK_TYPE, QDSS_ID);
+
+DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_d0, cxo_d0_a, D0_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_d1, cxo_d1_a, D1_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_a0, cxo_a0_a, A0_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_a1, cxo_a1_a, A1_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_a2, cxo_a2_a, A2_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(div_clk1, div_a_clk1, DIV_CLK1_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(div_clk2, div_a_clk2, DIV_CLK2_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(diff_clk, diff_a_clk, DIFF_CLK_ID);
+
+DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_d0_pin, cxo_d0_a_pin, D0_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_d1_pin, cxo_d1_a_pin, D1_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_a0_pin, cxo_a0_a_pin, A0_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_a1_pin, cxo_a1_a_pin, A1_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_a2_pin, cxo_a2_a_pin, A2_ID);
+
+struct measure_mux_entry {
+	struct clk *c;
+	int base;
+	u32 debug_mux;
+};
+
+static struct branch_clk oxilicx_axi_clk;
+
+#define MSS_DEBUG_CLOCK_CTL  0x0078
+#define LPASS_DEBUG_CLK_CTL  0x29000
+#define GLB_CLK_DIAG    0x01C
+#define GLB_TEST_BUS_SEL    0x020
+
+#define MMPLL0_PLL_MODE                                    (0x0000)
+#define MMPLL0_PLL_L_VAL                                   (0x0004)
+#define MMPLL0_PLL_M_VAL                                   (0x0008)
+#define MMPLL0_PLL_N_VAL                                   (0x000C)
+#define MMPLL0_PLL_USER_CTL                                (0x0010)
+#define MMPLL0_PLL_STATUS                                  (0x001C)
+#define MMPLL1_PLL_MODE                                    (0x0040)
+#define MMPLL1_PLL_L_VAL                                   (0x0044)
+#define MMPLL1_PLL_M_VAL                                   (0x0048)
+#define MMPLL1_PLL_N_VAL                                   (0x004C)
+#define MMPLL1_PLL_USER_CTL                                (0x0050)
+#define MMPLL1_PLL_STATUS                                  (0x005C)
+#define MMSS_PLL_VOTE_APCS                                 (0x0100)
+#define VCODEC0_CMD_RCGR                                   (0x1000)
+#define VENUS0_VCODEC0_CBCR                                (0x1028)
+#define VENUS0_AHB_CBCR                                    (0x1030)
+#define VENUS0_AXI_CBCR                                    (0x1034)
+#define PCLK0_CMD_RCGR                                     (0x2000)
+#define MDP_CMD_RCGR                                       (0x2040)
+#define VSYNC_CMD_RCGR                                     (0x2080)
+#define BYTE0_CMD_RCGR                                     (0x2120)
+#define ESC0_CMD_RCGR                                      (0x2160)
+#define MDSS_AHB_CBCR                                      (0x2308)
+#define MDSS_AXI_CBCR                                      (0x2310)
+#define MDSS_PCLK0_CBCR                                    (0x2314)
+#define MDSS_MDP_CBCR                                      (0x231C)
+#define MDSS_MDP_LUT_CBCR                                  (0x2320)
+#define MDSS_VSYNC_CBCR                                    (0x2328)
+#define MDSS_BYTE0_CBCR                                    (0x233C)
+#define MDSS_ESC0_CBCR                                     (0x2344)
+#define CSI0PHYTIMER_CMD_RCGR                              (0x3000)
+#define CAMSS_PHY0_CSI0PHYTIMER_CBCR                       (0x3024)
+#define CSI1PHYTIMER_CMD_RCGR                              (0x3030)
+#define CAMSS_PHY1_CSI1PHYTIMER_CBCR                       (0x3054)
+#define CSI0_CMD_RCGR                                      (0x3090)
+#define CAMSS_CSI0_CBCR                                    (0x30B4)
+#define CAMSS_CSI0_AHB_CBCR                                (0x30BC)
+#define CAMSS_CSI0PHY_CBCR                                 (0x30C4)
+#define CAMSS_CSI0RDI_CBCR                                 (0x30D4)
+#define CAMSS_CSI0PIX_CBCR                                 (0x30E4)
+#define CSI1_CMD_RCGR                                      (0x3100)
+#define CAMSS_CSI1_CBCR                                    (0x3124)
+#define CAMSS_CSI1_AHB_CBCR                                (0x3128)
+#define CAMSS_CSI1PHY_CBCR                                 (0x3134)
+#define CAMSS_CSI1RDI_CBCR                                 (0x3144)
+#define CAMSS_CSI1PIX_CBCR                                 (0x3154)
+#define CAMSS_ISPIF_AHB_CBCR                               (0x3224)
+#define CCI_CMD_RCGR                                       (0x3300)
+#define CAMSS_CCI_CCI_CBCR                                 (0x3344)
+#define CAMSS_CCI_CCI_AHB_CBCR                             (0x3348)
+#define MCLK0_CMD_RCGR                                     (0x3360)
+#define CAMSS_MCLK0_CBCR                                   (0x3384)
+#define MCLK1_CMD_RCGR                                     (0x3390)
+#define CAMSS_MCLK1_CBCR                                   (0x33B4)
+#define MMSS_GP0_CMD_RCGR                                  (0x3420)
+#define CAMSS_GP0_CBCR                                     (0x3444)
+#define MMSS_GP1_CMD_RCGR                                  (0x3450)
+#define CAMSS_GP1_CBCR                                     (0x3474)
+#define CAMSS_TOP_AHB_CBCR                                 (0x3484)
+#define CAMSS_MICRO_AHB_CBCR                               (0x3494)
+#define JPEG0_CMD_RCGR                                     (0x3500)
+#define CAMSS_JPEG_JPEG0_CBCR                              (0x35A8)
+#define CAMSS_JPEG_JPEG_AHB_CBCR                           (0x35B4)
+#define CAMSS_JPEG_JPEG_AXI_CBCR                           (0x35B8)
+#define VFE0_CMD_RCGR                                      (0x3600)
+#define CPP_CMD_RCGR                                       (0x3640)
+#define CAMSS_VFE_VFE0_CBCR                                (0x36A8)
+#define CAMSS_VFE_CPP_CBCR                                 (0x36B0)
+#define CAMSS_VFE_CPP_AHB_CBCR                             (0x36B4)
+#define CAMSS_VFE_VFE_AHB_CBCR                             (0x36B8)
+#define CAMSS_VFE_VFE_AXI_CBCR                             (0x36BC)
+#define CAMSS_CSI_VFE0_CBCR                                (0x3704)
+#define OXILI_GFX3D_CBCR                                   (0x4028)
+#define OXILICX_AXI_CBCR                                   (0x4038)
+#define OXILICX_AHB_CBCR                                   (0x403C)
+#define MMPLL2_PLL_MODE                                    (0x4100)
+#define MMPLL2_PLL_STATUS                                  (0x411C)
+#define MMSS_MMSSNOC_AHB_CBCR                              (0x5024)
+#define MMSS_MMSSNOC_BTO_AHB_CBCR                          (0x5028)
+#define MMSS_MISC_AHB_CBCR                                 (0x502C)
+#define AXI_CMD_RCGR                                       (0x5040)
+#define MMSS_S0_AXI_CBCR                                   (0x5064)
+#define MMSS_MMSSNOC_AXI_CBCR                              (0x506C)
+#define MMSS_DEBUG_CLK_CTL                                 (0x0900)
+#define GPLL0_MODE                                         (0x0000)
+#define GPLL0_L_VAL                                        (0x0004)
+#define GPLL0_M_VAL                                        (0x0008)
+#define GPLL0_N_VAL                                        (0x000C)
+#define GPLL0_USER_CTL                                     (0x0010)
+#define GPLL0_STATUS                                       (0x001C)
+#define GPLL1_MODE                                         (0x0040)
+#define GPLL1_L_VAL                                        (0x0044)
+#define GPLL1_M_VAL                                        (0x0048)
+#define GPLL1_N_VAL                                        (0x004C)
+#define GPLL1_USER_CTL                                     (0x0050)
+#define GPLL1_STATUS                                       (0x005C)
+#define PERIPH_NOC_AHB_CBCR                                (0x0184)
+#define NOC_CONF_XPU_AHB_CBCR                              (0x01C0)
+#define MMSS_NOC_CFG_AHB_CBCR                              (0x024C)
+#define MSS_CFG_AHB_CBCR                                   (0x0280)
+#define MSS_Q6_BIMC_AXI_CBCR                               (0x0284)
+#define USB_HS_HSIC_BCR                                    (0x0400)
+#define USB_HSIC_AHB_CBCR                                  (0x0408)
+#define USB_HSIC_SYSTEM_CMD_RCGR                           (0x041C)
+#define USB_HSIC_SYSTEM_CBCR                               (0x040C)
+#define USB_HSIC_CMD_RCGR                                  (0x0440)
+#define USB_HSIC_CBCR                                      (0x0410)
+#define USB_HSIC_IO_CAL_CMD_RCGR                           (0x0458)
+#define USB_HSIC_IO_CAL_CBCR                               (0x0414)
+#define USB_HS_BCR                                         (0x0480)
+#define USB_HS_SYSTEM_CBCR                                 (0x0484)
+#define USB_HS_AHB_CBCR                                    (0x0488)
+#define USB_HS_SYSTEM_CMD_RCGR                             (0x0490)
+#define USB2A_PHY_SLEEP_CBCR                               (0x04AC)
+#define SDCC1_APPS_CMD_RCGR                                (0x04D0)
+#define SDCC1_APPS_CBCR                                    (0x04C4)
+#define SDCC1_AHB_CBCR                                     (0x04C8)
+#define SDCC2_APPS_CMD_RCGR                                (0x0510)
+#define SDCC2_APPS_CBCR                                    (0x0504)
+#define SDCC2_AHB_CBCR                                     (0x0508)
+#define SDCC3_APPS_CMD_RCGR                                (0x0550)
+#define SDCC3_APPS_CBCR                                    (0x0544)
+#define SDCC3_AHB_CBCR                                     (0x0548)
+#define BLSP1_AHB_CBCR                                     (0x05C4)
+#define BLSP1_QUP1_SPI_APPS_CBCR                           (0x0644)
+#define BLSP1_QUP1_I2C_APPS_CBCR                           (0x0648)
+#define BLSP1_QUP1_I2C_APPS_CMD_RCGR                       (0x0660)
+#define BLSP1_QUP2_I2C_APPS_CMD_RCGR                       (0x06E0)
+#define BLSP1_QUP3_I2C_APPS_CMD_RCGR                       (0x0760)
+#define BLSP1_QUP4_I2C_APPS_CMD_RCGR                       (0x07E0)
+#define BLSP1_QUP5_I2C_APPS_CMD_RCGR                       (0x0860)
+#define BLSP1_QUP6_I2C_APPS_CMD_RCGR                       (0x08E0)
+#define BLSP1_QUP1_SPI_APPS_CMD_RCGR                       (0x064C)
+#define BLSP1_UART1_APPS_CBCR                              (0x0684)
+#define BLSP1_UART1_APPS_CMD_RCGR                          (0x068C)
+#define BLSP1_QUP2_SPI_APPS_CBCR                           (0x06C4)
+#define BLSP1_QUP2_I2C_APPS_CBCR                           (0x06C8)
+#define BLSP1_QUP2_SPI_APPS_CMD_RCGR                       (0x06CC)
+#define BLSP1_UART2_APPS_CBCR                              (0x0704)
+#define BLSP1_UART2_APPS_CMD_RCGR                          (0x070C)
+#define BLSP1_QUP3_SPI_APPS_CBCR                           (0x0744)
+#define BLSP1_QUP3_I2C_APPS_CBCR                           (0x0748)
+#define BLSP1_QUP3_SPI_APPS_CMD_RCGR                       (0x074C)
+#define BLSP1_UART3_APPS_CBCR                              (0x0784)
+#define BLSP1_UART3_APPS_CMD_RCGR                          (0x078C)
+#define BLSP1_QUP4_SPI_APPS_CBCR                           (0x07C4)
+#define BLSP1_QUP4_I2C_APPS_CBCR                           (0x07C8)
+#define BLSP1_QUP4_SPI_APPS_CMD_RCGR                       (0x07CC)
+#define BLSP1_UART4_APPS_CBCR                              (0x0804)
+#define BLSP1_UART4_APPS_CMD_RCGR                          (0x080C)
+#define BLSP1_QUP5_SPI_APPS_CBCR                           (0x0844)
+#define BLSP1_QUP5_I2C_APPS_CBCR                           (0x0848)
+#define BLSP1_QUP5_SPI_APPS_CMD_RCGR                       (0x084C)
+#define BLSP1_UART5_APPS_CBCR                              (0x0884)
+#define BLSP1_UART5_APPS_CMD_RCGR                          (0x088C)
+#define BLSP1_QUP6_SPI_APPS_CBCR                           (0x08C4)
+#define BLSP1_QUP6_I2C_APPS_CBCR                           (0x08C8)
+#define BLSP1_QUP6_SPI_APPS_CMD_RCGR                       (0x08CC)
+#define BLSP1_UART6_APPS_CBCR                              (0x0904)
+#define BLSP1_UART6_APPS_CMD_RCGR                          (0x090C)
+#define PDM_AHB_CBCR                                       (0x0CC4)
+#define PDM_XO4_CBCR                                       (0x0CC8)
+#define PDM2_CBCR                                          (0x0CCC)
+#define PDM2_CMD_RCGR                                      (0x0CD0)
+#define PRNG_AHB_CBCR                                      (0x0D04)
+#define BAM_DMA_AHB_CBCR                                   (0x0D44)
+#define BOOT_ROM_AHB_CBCR                                  (0x0E04)
+#define CE1_CMD_RCGR                                       (0x1050)
+#define CE1_CBCR                                           (0x1044)
+#define CE1_AXI_CBCR                                       (0x1048)
+#define CE1_AHB_CBCR                                       (0x104C)
+#define GCC_XO_DIV4_CBCR                                   (0x10C8)
+#define LPASS_Q6_AXI_CBCR                                  (0x11C0)
+#define APCS_GPLL_ENA_VOTE                                 (0x1480)
+#define APCS_CLOCK_BRANCH_ENA_VOTE                         (0x1484)
+#define APCS_CLOCK_SLEEP_ENA_VOTE                          (0x1488)
+#define GCC_DEBUG_CLK_CTL                                  (0x1880)
+#define CLOCK_FRQ_MEASURE_CTL                              (0x1884)
+#define CLOCK_FRQ_MEASURE_STATUS                           (0x1888)
+#define PLLTEST_PAD_CFG                                    (0x188C)
+#define GP1_CBCR                                           (0x1900)
+#define GP1_CMD_RCGR                                       (0x1904)
+#define GP2_CBCR                                           (0x1940)
+#define GP2_CMD_RCGR                                       (0x1944)
+#define GP3_CBCR                                           (0x1980)
+#define GP3_CMD_RCGR                                       (0x1984)
+#define Q6SS_BCR                                           (0x6000)
+#define Q6SS_AHB_LFABIF_CBCR                               (0x22000)
+#define Q6SS_AHBM_CBCR                                     (0x22004)
+#define Q6SS_XO_CBCR                                       (0x26000)
+
+static unsigned int soft_vote_gpll0;
+
+static struct pll_vote_clk gpll0 = {
+	.en_reg = (void __iomem *)APCS_GPLL_ENA_VOTE,
+	.en_mask = BIT(0),
+	.status_reg = (void __iomem *)GPLL0_STATUS,
+	.status_mask = BIT(17),
+	.soft_vote = &soft_vote_gpll0,
+	.soft_vote_mask = PLL_SOFT_VOTE_PRIMARY,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.rate = 600000000,
+		.parent = &xo.c,
+		.dbg_name = "gpll0",
+		.ops = &clk_ops_pll_acpu_vote,
+		CLK_INIT(gpll0.c),
+	},
+};
+
+/*Don't vote for xo if using this clock to allow xo shutdown*/
+static struct pll_vote_clk gpll0_ao = {
+	.en_reg = (void __iomem *)APCS_GPLL_ENA_VOTE,
+	.en_mask = BIT(0),
+	.status_reg = (void __iomem *)GPLL0_STATUS,
+	.status_mask = BIT(17),
+	.soft_vote = &soft_vote_gpll0,
+	.soft_vote_mask = PLL_SOFT_VOTE_ACPU,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.rate = 600000000,
+		.dbg_name = "gpll0_ao",
+		.ops = &clk_ops_pll_acpu_vote,
+		CLK_INIT(gpll0_ao.c),
+	},
+};
+
+static struct pll_vote_clk gpll1 = {
+	.en_reg = (void __iomem *)APCS_GPLL_ENA_VOTE,
+	.en_mask = BIT(1),
+	.status_reg = (void __iomem *)GPLL1_STATUS,
+	.status_mask = BIT(17),
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.rate = 480000000,
+		.parent = &xo.c,
+		.dbg_name = "gpll1",
+		.ops = &clk_ops_pll_vote,
+		CLK_INIT(gpll1.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_blsp1_qup1_6_i2c_apps_clk[] = {
+	F_GCC(  19200000,         xo,   1,    0,    0),
+	F_GCC(  50000000,      gpll0,  12,    0,    0),
+	F_END
+};
+
+static struct rcg_clk blsp1_qup1_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP1_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup1_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 50000000),
+		CLK_INIT(blsp1_qup1_i2c_apps_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_blsp1_qup1_6_spi_apps_clk[] = {
+	F_GCC(    960000,         xo,  10,    1,    2),
+	F_GCC(   4800000,         xo,   4,    0,    0),
+	F_GCC(   9600000,         xo,   2,    0,    0),
+	F_GCC(  15000000,      gpll0,  10,    1,    4),
+	F_GCC(  19200000,         xo,   1,    0,    0),
+	F_GCC(  25000000,      gpll0,  12,    1,    2),
+	F_GCC(  50000000,      gpll0,  12,    0,    0),
+	F_END
+};
+
+static struct rcg_clk blsp1_qup1_spi_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP1_SPI_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup1_spi_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+		CLK_INIT(blsp1_qup1_spi_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup2_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP2_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup2_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 50000000),
+		CLK_INIT(blsp1_qup2_i2c_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup2_spi_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP2_SPI_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup2_spi_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+		CLK_INIT(blsp1_qup2_spi_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup3_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP3_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup3_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 50000000),
+		CLK_INIT(blsp1_qup3_i2c_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup3_spi_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP3_SPI_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup3_spi_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+		CLK_INIT(blsp1_qup3_spi_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup4_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP4_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup4_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 50000000),
+		CLK_INIT(blsp1_qup4_i2c_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup4_spi_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP4_SPI_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup4_spi_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+		CLK_INIT(blsp1_qup4_spi_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup5_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP5_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup5_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 50000000),
+		CLK_INIT(blsp1_qup5_i2c_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup5_spi_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP5_SPI_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup5_spi_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+		CLK_INIT(blsp1_qup5_spi_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup6_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP6_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup6_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 50000000),
+		CLK_INIT(blsp1_qup6_i2c_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup6_spi_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP6_SPI_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup6_spi_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+		CLK_INIT(blsp1_qup6_spi_apps_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_blsp1_uart1_6_apps_clk[] = {
+	F_GCC(   3686400,      gpll0,   1,   96, 15625),
+	F_GCC(   7372800,      gpll0,   1,  192, 15625),
+	F_GCC(  14745600,      gpll0,   1,  384, 15625),
+	F_GCC(  16000000,      gpll0,   5,    2,   15),
+	F_GCC(  19200000,         xo,   1,    0,    0),
+	F_GCC(  24000000,      gpll0,   5,    1,    5),
+	F_GCC(  32000000,      gpll0,   1,    4,   75),
+	F_GCC(  40000000,      gpll0,  15,    0,    0),
+	F_GCC(  46400000,      gpll0,   1,   29,  375),
+	F_GCC(  48000000,      gpll0, 12.5,    0,    0),
+	F_GCC(  51200000,      gpll0,   1,   32,  375),
+	F_GCC(  56000000,      gpll0,   1,    7,   75),
+	F_GCC(  58982400,      gpll0,   1, 1536, 15625),
+	F_GCC(  60000000,      gpll0,  10,    0,    0),
+	F_END
+};
+
+static struct rcg_clk blsp1_uart1_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_UART1_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_uart1_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+		CLK_INIT(blsp1_uart1_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_uart2_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_UART2_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_uart2_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+		CLK_INIT(blsp1_uart2_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_uart3_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_UART3_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_uart3_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+		CLK_INIT(blsp1_uart3_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_uart4_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_UART4_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_uart4_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+		CLK_INIT(blsp1_uart4_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_uart5_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_UART5_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_uart5_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+		CLK_INIT(blsp1_uart5_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_uart6_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_UART6_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_uart6_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+		CLK_INIT(blsp1_uart6_apps_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_ce1_clk[] = {
+	F_GCC(  50000000,      gpll0,  12,    0,    0),
+	F_GCC( 100000000,      gpll0,   6,    0,    0),
+	F_END
+};
+
+static struct rcg_clk ce1_clk_src = {
+	.cmd_rcgr_reg = CE1_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_ce1_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "ce1_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP2(LOW, 50000000, NOMINAL, 100000000),
+		CLK_INIT(ce1_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_gp1_3_clk[] = {
+	F_GCC(  19200000,         xo,   1,    0,    0),
+	F_END
+};
+
+static struct rcg_clk gp1_clk_src = {
+	.cmd_rcgr_reg = GP1_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_gp1_3_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gp1_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+		CLK_INIT(gp1_clk_src.c),
+	},
+};
+
+static struct rcg_clk gp2_clk_src = {
+	.cmd_rcgr_reg = GP2_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_gp1_3_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gp2_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+		CLK_INIT(gp2_clk_src.c),
+	},
+};
+
+static struct rcg_clk gp3_clk_src = {
+	.cmd_rcgr_reg = GP3_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_gp1_3_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gp3_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+		CLK_INIT(gp3_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_pdm2_clk[] = {
+	F_GCC(  60000000,      gpll0,  10,    0,    0),
+	F_END
+};
+
+static struct rcg_clk pdm2_clk_src = {
+	.cmd_rcgr_reg = PDM2_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_pdm2_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "pdm2_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 60000000),
+		CLK_INIT(pdm2_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_sdcc1_3_apps_clk[] = {
+	F_GCC(    144000,         xo,  16,    3,   25),
+	F_GCC(    400000,         xo,  12,    1,    4),
+	F_GCC(  20000000,      gpll0,  15,    1,    2),
+	F_GCC(  25000000,      gpll0,  12,    1,    2),
+	F_GCC(  50000000,      gpll0,  12,    0,    0),
+	F_GCC( 100000000,      gpll0,   6,    0,    0),
+	F_GCC( 200000000,      gpll0,   3,    0,    0),
+	F_END
+};
+
+static struct rcg_clk sdcc1_apps_clk_src = {
+	.cmd_rcgr_reg = SDCC1_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_sdcc1_3_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "sdcc1_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+		CLK_INIT(sdcc1_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk sdcc2_apps_clk_src = {
+	.cmd_rcgr_reg = SDCC2_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_sdcc1_3_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "sdcc2_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+		CLK_INIT(sdcc2_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk sdcc3_apps_clk_src = {
+	.cmd_rcgr_reg = SDCC3_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_sdcc1_3_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "sdcc3_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 50000000, NOMINAL, 100000000),
+		CLK_INIT(sdcc3_apps_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_usb_hs_system_clk[] = {
+	F_GCC(  75000000,      gpll0,   8,    0,    0),
+	F_END
+};
+
+static struct rcg_clk usb_hs_system_clk_src = {
+	.cmd_rcgr_reg = USB_HS_SYSTEM_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_usb_hs_system_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "usb_hs_system_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP2(LOW, 37500000, NOMINAL, 75000000),
+		CLK_INIT(usb_hs_system_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_usb_hsic_clk[] = {
+	F_HSIC( 480000000,      gpll1,   0,    0,    0),
+	F_END
+};
+
+static struct rcg_clk usb_hsic_clk_src = {
+	.cmd_rcgr_reg = USB_HSIC_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_usb_hsic_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "usb_hsic_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 480000000),
+		CLK_INIT(usb_hsic_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_usb_hsic_io_cal_clk[] = {
+	F_GCC(   9600000,         xo,   2,    0,    0),
+	F_END
+};
+
+static struct rcg_clk usb_hsic_io_cal_clk_src = {
+	.cmd_rcgr_reg = USB_HSIC_IO_CAL_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_usb_hsic_io_cal_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "usb_hsic_io_cal_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 9600000),
+		CLK_INIT(usb_hsic_io_cal_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_usb_hsic_system_clk[] = {
+	F_GCC(  75000000,      gpll0,   8,    0,    0),
+	F_END
+};
+
+static struct rcg_clk usb_hsic_system_clk_src = {
+	.cmd_rcgr_reg = USB_HSIC_SYSTEM_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_usb_hsic_system_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "usb_hsic_system_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP2(LOW, 37500000, NOMINAL, 75000000),
+		CLK_INIT(usb_hsic_system_clk_src.c),
+	},
+};
+
+static struct local_vote_clk gcc_bam_dma_ahb_clk = {
+	.cbcr_reg = BAM_DMA_AHB_CBCR,
+	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask = BIT(12),
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_bam_dma_ahb_clk",
+		.ops = &clk_ops_vote,
+		CLK_INIT(gcc_bam_dma_ahb_clk.c),
+	},
+};
+
+static struct local_vote_clk gcc_blsp1_ahb_clk = {
+	.cbcr_reg = BLSP1_AHB_CBCR,
+	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask = BIT(17),
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_ahb_clk",
+		.ops = &clk_ops_vote,
+		CLK_INIT(gcc_blsp1_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup1_i2c_apps_clk = {
+	.cbcr_reg = BLSP1_QUP1_I2C_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_qup1_i2c_apps_clk",
+		.parent = &blsp1_qup1_i2c_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup1_i2c_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup1_spi_apps_clk = {
+	.cbcr_reg = BLSP1_QUP1_SPI_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_qup1_spi_apps_clk",
+		.parent = &blsp1_qup1_spi_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup1_spi_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup2_i2c_apps_clk = {
+	.cbcr_reg = BLSP1_QUP2_I2C_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_qup2_i2c_apps_clk",
+		.parent = &blsp1_qup2_i2c_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup2_i2c_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup2_spi_apps_clk = {
+	.cbcr_reg = BLSP1_QUP2_SPI_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_qup2_spi_apps_clk",
+		.parent = &blsp1_qup2_spi_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup2_spi_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup3_i2c_apps_clk = {
+	.cbcr_reg = BLSP1_QUP3_I2C_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_qup3_i2c_apps_clk",
+		.parent = &blsp1_qup3_i2c_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup3_i2c_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup3_spi_apps_clk = {
+	.cbcr_reg = BLSP1_QUP3_SPI_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_qup3_spi_apps_clk",
+		.parent = &blsp1_qup3_spi_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup3_spi_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup4_i2c_apps_clk = {
+	.cbcr_reg = BLSP1_QUP4_I2C_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_qup4_i2c_apps_clk",
+		.parent = &blsp1_qup4_i2c_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup4_i2c_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup4_spi_apps_clk = {
+	.cbcr_reg = BLSP1_QUP4_SPI_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_qup4_spi_apps_clk",
+		.parent = &blsp1_qup4_spi_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup4_spi_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup5_i2c_apps_clk = {
+	.cbcr_reg = BLSP1_QUP5_I2C_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_qup5_i2c_apps_clk",
+		.parent = &blsp1_qup5_i2c_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup5_i2c_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup5_spi_apps_clk = {
+	.cbcr_reg = BLSP1_QUP5_SPI_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_qup5_spi_apps_clk",
+		.parent = &blsp1_qup5_spi_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup5_spi_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup6_i2c_apps_clk = {
+	.cbcr_reg = BLSP1_QUP6_I2C_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_qup6_i2c_apps_clk",
+		.parent = &blsp1_qup6_i2c_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup6_i2c_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup6_spi_apps_clk = {
+	.cbcr_reg = BLSP1_QUP6_SPI_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_qup6_spi_apps_clk",
+		.parent = &blsp1_qup6_spi_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup6_spi_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_uart1_apps_clk = {
+	.cbcr_reg = BLSP1_UART1_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_uart1_apps_clk",
+		.parent = &blsp1_uart1_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_uart1_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_uart2_apps_clk = {
+	.cbcr_reg = BLSP1_UART2_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_uart2_apps_clk",
+		.parent = &blsp1_uart2_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_uart2_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_uart3_apps_clk = {
+	.cbcr_reg = BLSP1_UART3_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_uart3_apps_clk",
+		.parent = &blsp1_uart3_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_uart3_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_uart4_apps_clk = {
+	.cbcr_reg = BLSP1_UART4_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_uart4_apps_clk",
+		.parent = &blsp1_uart4_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_uart4_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_uart5_apps_clk = {
+	.cbcr_reg = BLSP1_UART5_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_uart5_apps_clk",
+		.parent = &blsp1_uart5_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_uart5_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_uart6_apps_clk = {
+	.cbcr_reg = BLSP1_UART6_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_uart6_apps_clk",
+		.parent = &blsp1_uart6_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_uart6_apps_clk.c),
+	},
+};
+
+static struct local_vote_clk gcc_boot_rom_ahb_clk = {
+	.cbcr_reg = BOOT_ROM_AHB_CBCR,
+	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask = BIT(10),
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_boot_rom_ahb_clk",
+		.ops = &clk_ops_vote,
+		CLK_INIT(gcc_boot_rom_ahb_clk.c),
+	},
+};
+
+static struct local_vote_clk gcc_ce1_ahb_clk = {
+	.cbcr_reg = CE1_AHB_CBCR,
+	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask = BIT(3),
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_ce1_ahb_clk",
+		.ops = &clk_ops_vote,
+		CLK_INIT(gcc_ce1_ahb_clk.c),
+	},
+};
+
+static struct local_vote_clk gcc_ce1_axi_clk = {
+	.cbcr_reg = CE1_AXI_CBCR,
+	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask = BIT(4),
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_ce1_axi_clk",
+		.ops = &clk_ops_vote,
+		CLK_INIT(gcc_ce1_axi_clk.c),
+	},
+};
+
+static struct local_vote_clk gcc_ce1_clk = {
+	.cbcr_reg = CE1_CBCR,
+	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask = BIT(5),
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_ce1_clk",
+		.ops = &clk_ops_vote,
+		CLK_INIT(gcc_ce1_clk.c),
+	},
+};
+
+static struct branch_clk gcc_gp1_clk = {
+	.cbcr_reg = GP1_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_gp1_clk",
+		.parent = &gp1_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_gp1_clk.c),
+	},
+};
+
+static struct branch_clk gcc_gp2_clk = {
+	.cbcr_reg = GP2_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_gp2_clk",
+		.parent = &gp2_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_gp2_clk.c),
+	},
+};
+
+static struct branch_clk gcc_gp3_clk = {
+	.cbcr_reg = GP3_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_gp3_clk",
+		.parent = &gp3_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_gp3_clk.c),
+	},
+};
+
+static struct branch_clk gcc_lpass_q6_axi_clk = {
+	.cbcr_reg = LPASS_Q6_AXI_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_lpass_q6_axi_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_lpass_q6_axi_clk.c),
+	},
+};
+
+static struct branch_clk gcc_mmss_noc_cfg_ahb_clk = {
+	.cbcr_reg = MMSS_NOC_CFG_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_mmss_noc_cfg_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_mmss_noc_cfg_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_mss_cfg_ahb_clk = {
+	.cbcr_reg = MSS_CFG_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_mss_cfg_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_mss_cfg_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_mss_q6_bimc_axi_clk = {
+	.cbcr_reg = MSS_Q6_BIMC_AXI_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_mss_q6_bimc_axi_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_mss_q6_bimc_axi_clk.c),
+	},
+};
+
+static struct branch_clk gcc_noc_conf_xpu_ahb_clk = {
+	.cbcr_reg = NOC_CONF_XPU_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_noc_conf_xpu_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_noc_conf_xpu_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_pdm2_clk = {
+	.cbcr_reg = PDM2_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_pdm2_clk",
+		.parent = &pdm2_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_pdm2_clk.c),
+	},
+};
+
+static struct branch_clk gcc_pdm_ahb_clk = {
+	.cbcr_reg = PDM_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_pdm_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_pdm_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_pdm_xo4_clk = {
+	.cbcr_reg = PDM_XO4_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_pdm_xo4_clk",
+		.parent = &xo.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_pdm_xo4_clk.c),
+	},
+};
+
+static struct branch_clk gcc_periph_noc_ahb_clk = {
+	.cbcr_reg = PERIPH_NOC_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_periph_noc_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_periph_noc_ahb_clk.c),
+	},
+};
+
+static struct local_vote_clk gcc_prng_ahb_clk = {
+	.cbcr_reg = PRNG_AHB_CBCR,
+	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask = BIT(13),
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_prng_ahb_clk",
+		.ops = &clk_ops_vote,
+		CLK_INIT(gcc_prng_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_sdcc1_ahb_clk = {
+	.cbcr_reg = SDCC1_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_sdcc1_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_sdcc1_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_sdcc1_apps_clk = {
+	.cbcr_reg = SDCC1_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_sdcc1_apps_clk",
+		.parent = &sdcc1_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_sdcc1_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_sdcc2_ahb_clk = {
+	.cbcr_reg = SDCC2_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_sdcc2_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_sdcc2_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_sdcc2_apps_clk = {
+	.cbcr_reg = SDCC2_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_sdcc2_apps_clk",
+		.parent = &sdcc2_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_sdcc2_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_sdcc3_ahb_clk = {
+	.cbcr_reg = SDCC3_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_sdcc3_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_sdcc3_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_sdcc3_apps_clk = {
+	.cbcr_reg = SDCC3_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_sdcc3_apps_clk",
+		.parent = &sdcc3_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_sdcc3_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_usb2a_phy_sleep_clk = {
+	.cbcr_reg = USB2A_PHY_SLEEP_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_usb2a_phy_sleep_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_usb2a_phy_sleep_clk.c),
+	},
+};
+
+static struct branch_clk gcc_usb_hs_ahb_clk = {
+	.cbcr_reg = USB_HS_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_usb_hs_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_usb_hs_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_usb_hs_system_clk = {
+	.cbcr_reg = USB_HS_SYSTEM_CBCR,
+	.has_sibling = 0,
+	.bcr_reg = USB_HS_BCR,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_usb_hs_system_clk",
+		.parent = &usb_hs_system_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_usb_hs_system_clk.c),
+	},
+};
+
+static struct branch_clk gcc_usb_hsic_ahb_clk = {
+	.cbcr_reg = USB_HSIC_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_usb_hsic_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_usb_hsic_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_usb_hsic_clk = {
+	.cbcr_reg = USB_HSIC_CBCR,
+	.has_sibling = 0,
+	.bcr_reg = USB_HS_HSIC_BCR,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_usb_hsic_clk",
+		.parent = &usb_hsic_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_usb_hsic_clk.c),
+	},
+};
+
+static struct branch_clk gcc_usb_hsic_io_cal_clk = {
+	.cbcr_reg = USB_HSIC_IO_CAL_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_usb_hsic_io_cal_clk",
+		.parent = &usb_hsic_io_cal_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_usb_hsic_io_cal_clk.c),
+	},
+};
+
+static struct branch_clk gcc_usb_hsic_system_clk = {
+	.cbcr_reg = USB_HSIC_SYSTEM_CBCR,
+	.has_sibling = 0,
+	.bcr_reg = USB_HS_HSIC_BCR,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_usb_hsic_system_clk",
+		.parent = &usb_hsic_system_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_usb_hsic_system_clk.c),
+	},
+};
+
+static struct measure_mux_entry measure_mux_GCC[] = {
+	{ &gcc_periph_noc_ahb_clk.c,  GCC_BASE, 0x0010 },
+	{ &gcc_noc_conf_xpu_ahb_clk.c,  GCC_BASE, 0x0018 },
+	{ &gcc_mmss_noc_cfg_ahb_clk.c,  GCC_BASE, 0x002a },
+	{ &gcc_mss_cfg_ahb_clk.c,  GCC_BASE, 0x0030 },
+	{ &gcc_mss_q6_bimc_axi_clk.c,  GCC_BASE, 0x0031 },
+	{ &gcc_usb_hsic_ahb_clk.c,  GCC_BASE, 0x0058 },
+	{ &gcc_usb_hsic_system_clk.c,  GCC_BASE, 0x0059 },
+	{ &gcc_usb_hsic_clk.c,  GCC_BASE, 0x005a },
+	{ &gcc_usb_hsic_io_cal_clk.c,  GCC_BASE, 0x005b },
+	{ &gcc_usb_hs_system_clk.c,  GCC_BASE, 0x0060 },
+	{ &gcc_usb_hs_ahb_clk.c,  GCC_BASE, 0x0061 },
+	{ &gcc_usb2a_phy_sleep_clk.c,  GCC_BASE, 0x0063 },
+	{ &gcc_sdcc1_apps_clk.c,  GCC_BASE, 0x0068 },
+	{ &gcc_sdcc1_ahb_clk.c,  GCC_BASE, 0x0069 },
+	{ &gcc_sdcc2_apps_clk.c,  GCC_BASE, 0x0070 },
+	{ &gcc_sdcc2_ahb_clk.c,  GCC_BASE, 0x0071 },
+	{ &gcc_sdcc3_apps_clk.c,  GCC_BASE, 0x0078 },
+	{ &gcc_sdcc3_ahb_clk.c,  GCC_BASE, 0x0079 },
+	{ &gcc_blsp1_ahb_clk.c,  GCC_BASE, 0x0088 },
+	{ &gcc_blsp1_qup1_spi_apps_clk.c,  GCC_BASE, 0x008a },
+	{ &gcc_blsp1_qup1_i2c_apps_clk.c,  GCC_BASE, 0x008b },
+	{ &gcc_blsp1_uart1_apps_clk.c,  GCC_BASE, 0x008c },
+	{ &gcc_blsp1_qup2_spi_apps_clk.c,  GCC_BASE, 0x008e },
+	{ &gcc_blsp1_qup2_i2c_apps_clk.c,  GCC_BASE, 0x0090 },
+	{ &gcc_blsp1_uart2_apps_clk.c,  GCC_BASE, 0x0091 },
+	{ &gcc_blsp1_qup3_spi_apps_clk.c,  GCC_BASE, 0x0093 },
+	{ &gcc_blsp1_qup3_i2c_apps_clk.c,  GCC_BASE, 0x0094 },
+	{ &gcc_blsp1_uart3_apps_clk.c,  GCC_BASE, 0x0095 },
+	{ &gcc_blsp1_qup4_spi_apps_clk.c,  GCC_BASE, 0x0098 },
+	{ &gcc_blsp1_qup4_i2c_apps_clk.c,  GCC_BASE, 0x0099 },
+	{ &gcc_blsp1_uart4_apps_clk.c,  GCC_BASE, 0x009a },
+	{ &gcc_blsp1_qup5_spi_apps_clk.c,  GCC_BASE, 0x009c },
+	{ &gcc_blsp1_qup5_i2c_apps_clk.c,  GCC_BASE, 0x009d },
+	{ &gcc_blsp1_uart5_apps_clk.c,  GCC_BASE, 0x009e },
+	{ &gcc_blsp1_qup6_spi_apps_clk.c,  GCC_BASE, 0x00a1 },
+	{ &gcc_blsp1_qup6_i2c_apps_clk.c,  GCC_BASE, 0x00a2 },
+	{ &gcc_blsp1_uart6_apps_clk.c,  GCC_BASE, 0x00a3 },
+	{ &gcc_pdm_ahb_clk.c,  GCC_BASE, 0x00d0 },
+	{ &gcc_pdm_xo4_clk.c,  GCC_BASE, 0x00d1 },
+	{ &gcc_pdm2_clk.c,  GCC_BASE, 0x00d2 },
+	{ &gcc_prng_ahb_clk.c,  GCC_BASE, 0x00d8 },
+	{ &gcc_bam_dma_ahb_clk.c,  GCC_BASE, 0x00e0 },
+	{ &gcc_boot_rom_ahb_clk.c,  GCC_BASE, 0x00f8 },
+	{ &gcc_ce1_clk.c,  GCC_BASE, 0x0138 },
+	{ &gcc_ce1_axi_clk.c,  GCC_BASE, 0x0139 },
+	{ &gcc_ce1_ahb_clk.c,  GCC_BASE, 0x013a },
+	{ &gcc_lpass_q6_axi_clk.c,  GCC_BASE, 0x0160 },
+	{&dummy_clk, N_BASES, 0x0000},
+};
+
+static struct pll_vote_clk mmpll0_pll = {
+	.en_reg = (void __iomem *)MMSS_PLL_VOTE_APCS,
+	.en_mask = BIT(0),
+	.status_reg = (void __iomem *)MMPLL0_PLL_STATUS,
+	.status_mask = BIT(17),
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.rate = 800000000,
+		.parent = &xo.c,
+		.dbg_name = "mmpll0_pll",
+		.ops = &clk_ops_pll_vote,
+		CLK_INIT(mmpll0_pll.c),
+	},
+};
+
+static struct pll_vote_clk mmpll1_pll = {
+	.en_reg = (void __iomem *)MMSS_PLL_VOTE_APCS,
+	.en_mask = BIT(1),
+	.status_reg = (void __iomem *)MMPLL1_PLL_STATUS,
+	.status_mask = BIT(17),
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.rate = 1000000000,
+		.parent = &xo.c,
+		.dbg_name = "mmpll1_pll",
+		.ops = &clk_ops_pll_vote,
+		CLK_INIT(mmpll1_pll.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_mmss_mmssnoc_axi_clk[] = {
+	F_MMSS(  19200000,         xo,   1,    0,    0),
+	F_MMSS(  37500000,      gpll0,  16,    0,    0),
+	F_MMSS(  50000000,      gpll0,  12,    0,    0),
+	F_MMSS(  75000000,      gpll0,   8,    0,    0),
+	F_MMSS( 100000000,      gpll0,   6,    0,    0),
+	F_MMSS( 150000000,      gpll0,   4,    0,    0),
+	F_MMSS( 200000000, mmpll0_pll,   4,    0,    0),
+	F_MMSS( 266000000, mmpll0_pll,   3,    0,    0),
+	F_END
+};
+
+static struct rcg_clk axi_clk_src = {
+	.cmd_rcgr_reg = AXI_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_mmss_mmssnoc_axi_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "axi_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP3(LOW, 100000000, NOMINAL, 200000000, HIGH,
+			266670000),
+		CLK_INIT(axi_clk_src.c),
+	},
+};
+
+static struct pll_clk mmpll2_pll = {
+	.mode_reg = (void __iomem *)MMPLL2_PLL_MODE,
+	.status_reg = (void __iomem *)MMPLL2_PLL_STATUS,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "mmpll2_pll",
+		.parent = &xo.c,
+		.rate = 900000000,
+		.ops = &clk_ops_local_pll,
+		CLK_INIT(mmpll2_pll.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_camss_csi0_1_clk[] = {
+	F_MMSS( 100000000,      gpll0,   6,    0,    0),
+	F_MMSS( 200000000, mmpll0_pll,   4,    0,    0),
+	F_END
+};
+
+static struct rcg_clk csi0_clk_src = {
+	.cmd_rcgr_reg = CSI0_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_camss_csi0_1_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "csi0_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+		CLK_INIT(csi0_clk_src.c),
+	},
+};
+
+static struct rcg_clk csi1_clk_src = {
+	.cmd_rcgr_reg = CSI1_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_camss_csi0_1_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "csi1_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+		CLK_INIT(csi1_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_camss_vfe_vfe0_clk[] = {
+	F_MMSS(  37500000,      gpll0,  16,    0,    0),
+	F_MMSS(  50000000,      gpll0,  12,    0,    0),
+	F_MMSS(  60000000,      gpll0,  10,    0,    0),
+	F_MMSS(  80000000,      gpll0, 7.5,    0,    0),
+	F_MMSS( 100000000,      gpll0,   6,    0,    0),
+	F_MMSS( 109090000,      gpll0, 5.5,    0,    0),
+	F_MMSS( 133330000,      gpll0, 4.5,    0,    0),
+	F_MMSS( 200000000,      gpll0,   3,    0,    0),
+	F_MMSS( 228570000, mmpll0_pll, 3.5,    0,    0),
+	F_MMSS( 266670000, mmpll0_pll,   3,    0,    0),
+	F_MMSS( 320000000, mmpll0_pll, 2.5,    0,    0),
+	F_END
+};
+
+static struct rcg_clk vfe0_clk_src = {
+	.cmd_rcgr_reg = VFE0_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_camss_vfe_vfe0_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "vfe0_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP3(LOW, 133330000, NOMINAL, 266670000, HIGH,
+			320000000),
+		CLK_INIT(vfe0_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_mdss_mdp_clk[] = {
+	F_MMSS(  37500000,      gpll0,  16,    0,    0),
+	F_MMSS(  60000000,      gpll0,  10,    0,    0),
+	F_MMSS(  75000000,      gpll0,   8,    0,    0),
+	F_MMSS(  92310000,      gpll0, 6.5,    0,    0),
+	F_MMSS( 100000000,      gpll0,   6,    0,    0),
+	F_MMSS( 133330000, mmpll0_pll,   6,    0,    0),
+	F_MMSS( 177780000, mmpll0_pll, 4.5,    0,    0),
+	F_MMSS( 200000000, mmpll0_pll,   4,    0,    0),
+	F_END
+};
+
+static struct rcg_clk mdp_clk_src = {
+	.cmd_rcgr_reg = MDP_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_mdss_mdp_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "mdp_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP3(LOW, 92310000, NOMINAL, 177780000, HIGH,
+			200000000),
+		CLK_INIT(mdp_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_camss_jpeg_jpeg0_clk[] = {
+	F_MMSS(  75000000,      gpll0,   8,    0,    0),
+	F_MMSS( 133330000,      gpll0, 4.5,    0,    0),
+	F_MMSS( 200000000,      gpll0,   3,    0,    0),
+	F_MMSS( 228570000, mmpll0_pll, 3.5,    0,    0),
+	F_MMSS( 266670000, mmpll0_pll,   3,    0,    0),
+	F_MMSS( 320000000, mmpll0_pll, 2.5,    0,    0),
+	F_END
+};
+
+static struct rcg_clk jpeg0_clk_src = {
+	.cmd_rcgr_reg = JPEG0_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_camss_jpeg_jpeg0_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "jpeg0_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP3(LOW, 133330000, NOMINAL, 266670000, HIGH,
+			320000000),
+		CLK_INIT(jpeg0_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_mdss_pclk0_clk[] = {
+	F_MDSS(  83000000, dsipll_667,   8,    0,    0),
+	F_MDSS( 166000000, dsipll_667,   4,    0,    0),
+	F_END
+};
+
+static struct rcg_clk pclk0_clk_src = {
+	.cmd_rcgr_reg = PCLK0_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_mdss_pclk0_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "pclk0_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 83330000, NOMINAL, 166670000),
+		CLK_INIT(pclk0_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_venus0_vcodec0_clk[] = {
+	F_MMSS(  66700000,      gpll0,   9,    0,    0),
+	F_MMSS( 100000000,      gpll0,   6,    0,    0),
+	F_MMSS( 133330000, mmpll0_pll,   6,    0,    0),
+	F_MMSS( 160000000, mmpll0_pll,   5,    0,    0),
+	F_END
+};
+
+static struct rcg_clk vcodec0_clk_src = {
+	.cmd_rcgr_reg = VCODEC0_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_venus0_vcodec0_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "vcodec0_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP3(LOW, 66670000, NOMINAL, 133330000, HIGH,
+			160000000),
+		CLK_INIT(vcodec0_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_camss_cci_cci_clk[] = {
+	F_MMSS(  19200000,         xo,   1,    0,    0),
+	F_END
+};
+
+static struct rcg_clk cci_clk_src = {
+	.cmd_rcgr_reg = CCI_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_camss_cci_cci_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "cci_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 20000000, NOMINAL, 40000000),
+		CLK_INIT(cci_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_camss_gp0_1_clk[] = {
+	F_MMSS(     10000,         xo,  16,    1,  120),
+	F_MMSS(     24000,         xo,  16,    1,   50),
+	F_MMSS(   6000000,      gpll0,  10,    1,   10),
+	F_MMSS(  12000000,      gpll0,  10,    1,    5),
+	F_MMSS(  13000000,      gpll0,   4,   13,  150),
+	F_MMSS(  24000000,      gpll0,   5,    1,    5),
+	F_END
+};
+
+static struct rcg_clk mmss_gp0_clk_src = {
+	.cmd_rcgr_reg = MMSS_GP0_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_camss_gp0_1_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "mmss_gp0_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+		CLK_INIT(mmss_gp0_clk_src.c),
+	},
+};
+
+static struct rcg_clk mmss_gp1_clk_src = {
+	.cmd_rcgr_reg = MMSS_GP1_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_camss_gp0_1_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "mmss_gp1_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+		CLK_INIT(mmss_gp1_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_camss_mclk0_1_clk[] = {
+	F_MMSS(  66670000,      gpll0,   9,    0,    0),
+	F_END
+};
+
+static struct rcg_clk mclk0_clk_src = {
+	.cmd_rcgr_reg = MCLK0_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_camss_mclk0_1_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "mclk0_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP1(LOW, 66670000),
+		CLK_INIT(mclk0_clk_src.c),
+	},
+};
+
+static struct rcg_clk mclk1_clk_src = {
+	.cmd_rcgr_reg = MCLK1_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_camss_mclk0_1_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "mclk1_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP1(LOW, 66670000),
+		CLK_INIT(mclk1_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_camss_phy0_1_csi0_1phytimer_clk[] = {
+	F_MMSS( 100000000,      gpll0,   6,    0,    0),
+	F_MMSS( 200000000, mmpll0_pll,   4,    0,    0),
+	F_END
+};
+
+static struct rcg_clk csi0phytimer_clk_src = {
+	.cmd_rcgr_reg = CSI0PHYTIMER_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_camss_phy0_1_csi0_1phytimer_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "csi0phytimer_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+		CLK_INIT(csi0phytimer_clk_src.c),
+	},
+};
+
+static struct rcg_clk csi1phytimer_clk_src = {
+	.cmd_rcgr_reg = CSI1PHYTIMER_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_camss_phy0_1_csi0_1phytimer_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "csi1phytimer_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+		CLK_INIT(csi1phytimer_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_camss_vfe_cpp_clk[] = {
+	F_MMSS( 133330000,      gpll0, 4.5,    0,    0),
+	F_MMSS( 266670000, mmpll0_pll,   3,    0,    0),
+	F_MMSS( 320000000, mmpll0_pll, 2.5,    0,    0),
+	F_END
+};
+
+static struct rcg_clk cpp_clk_src = {
+	.cmd_rcgr_reg = CPP_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_camss_vfe_cpp_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "cpp_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP3(LOW, 133330000, NOMINAL, 266670000, HIGH,
+			320000000),
+		CLK_INIT(cpp_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_mdss_byte0_clk[] = {
+	F_MDSS(  62500000, dsipll_750,  12,    0,    0),
+	F_MDSS( 125000000, dsipll_750,   6,    0,    0),
+	F_END
+};
+
+static struct rcg_clk byte0_clk_src = {
+	.cmd_rcgr_reg = BYTE0_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_mdss_byte0_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "byte0_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP2(LOW, 62500000, NOMINAL, 125000000),
+		CLK_INIT(byte0_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_mdss_esc0_clk[] = {
+	F_MDSS(  19200000,         xo,   1,    0,    0),
+	F_END
+};
+
+static struct rcg_clk esc0_clk_src = {
+	.cmd_rcgr_reg = ESC0_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_mdss_esc0_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "esc0_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP2(LOW, 20000000, NOMINAL, 40000000),
+		CLK_INIT(esc0_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_mdss_vsync_clk[] = {
+	F_MDSS(  19200000,         xo,   1,    0,    0),
+	F_END
+};
+
+static struct rcg_clk vsync_clk_src = {
+	.cmd_rcgr_reg = VSYNC_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_mdss_vsync_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "vsync_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP2(LOW, 20000000, NOMINAL, 40000000),
+		CLK_INIT(vsync_clk_src.c),
+	},
+};
+
+static struct branch_clk camss_cci_cci_ahb_clk = {
+	.cbcr_reg = CAMSS_CCI_CCI_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_cci_cci_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_cci_cci_ahb_clk.c),
+	},
+};
+
+static struct branch_clk camss_cci_cci_clk = {
+	.cbcr_reg = CAMSS_CCI_CCI_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_cci_cci_clk",
+		.parent = &cci_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_cci_cci_clk.c),
+	},
+};
+
+static struct branch_clk camss_csi0_ahb_clk = {
+	.cbcr_reg = CAMSS_CSI0_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_csi0_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_csi0_ahb_clk.c),
+	},
+};
+
+static struct branch_clk camss_csi0_clk = {
+	.cbcr_reg = CAMSS_CSI0_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_csi0_clk",
+		.parent = &csi0_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_csi0_clk.c),
+	},
+};
+
+static struct branch_clk camss_csi0phy_clk = {
+	.cbcr_reg = CAMSS_CSI0PHY_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_csi0phy_clk",
+		.parent = &csi0_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_csi0phy_clk.c),
+	},
+};
+
+static struct branch_clk camss_csi0pix_clk = {
+	.cbcr_reg = CAMSS_CSI0PIX_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_csi0pix_clk",
+		.parent = &csi0_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_csi0pix_clk.c),
+	},
+};
+
+static struct branch_clk camss_csi0rdi_clk = {
+	.cbcr_reg = CAMSS_CSI0RDI_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_csi0rdi_clk",
+		.parent = &csi0_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_csi0rdi_clk.c),
+	},
+};
+
+static struct branch_clk camss_csi1_ahb_clk = {
+	.cbcr_reg = CAMSS_CSI1_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_csi1_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_csi1_ahb_clk.c),
+	},
+};
+
+static struct branch_clk camss_csi1_clk = {
+	.cbcr_reg = CAMSS_CSI1_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_csi1_clk",
+		.parent = &csi1_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_csi1_clk.c),
+	},
+};
+
+static struct branch_clk camss_csi1phy_clk = {
+	.cbcr_reg = CAMSS_CSI1PHY_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_csi1phy_clk",
+		.parent = &csi1_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_csi1phy_clk.c),
+	},
+};
+
+static struct branch_clk camss_csi1pix_clk = {
+	.cbcr_reg = CAMSS_CSI1PIX_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_csi1pix_clk",
+		.parent = &csi1_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_csi1pix_clk.c),
+	},
+};
+
+static struct branch_clk camss_csi1rdi_clk = {
+	.cbcr_reg = CAMSS_CSI1RDI_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_csi1rdi_clk",
+		.parent = &csi1_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_csi1rdi_clk.c),
+	},
+};
+
+static struct branch_clk camss_csi_vfe0_clk = {
+	.cbcr_reg = CAMSS_CSI_VFE0_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_csi_vfe0_clk",
+		.parent = &vfe0_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_csi_vfe0_clk.c),
+	},
+};
+
+static struct branch_clk camss_gp0_clk = {
+	.cbcr_reg = CAMSS_GP0_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_gp0_clk",
+		.parent = &mmss_gp0_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_gp0_clk.c),
+	},
+};
+
+static struct branch_clk camss_gp1_clk = {
+	.cbcr_reg = CAMSS_GP1_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_gp1_clk",
+		.parent = &mmss_gp1_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_gp1_clk.c),
+	},
+};
+
+static struct branch_clk camss_ispif_ahb_clk = {
+	.cbcr_reg = CAMSS_ISPIF_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_ispif_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_ispif_ahb_clk.c),
+	},
+};
+
+static struct branch_clk camss_jpeg_jpeg0_clk = {
+	.cbcr_reg = CAMSS_JPEG_JPEG0_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_jpeg_jpeg0_clk",
+		.parent = &jpeg0_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_jpeg_jpeg0_clk.c),
+	},
+};
+
+static struct branch_clk camss_jpeg_jpeg_ahb_clk = {
+	.cbcr_reg = CAMSS_JPEG_JPEG_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_jpeg_jpeg_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_jpeg_jpeg_ahb_clk.c),
+	},
+};
+
+static struct branch_clk camss_jpeg_jpeg_axi_clk = {
+	.cbcr_reg = CAMSS_JPEG_JPEG_AXI_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_jpeg_jpeg_axi_clk",
+		.parent = &axi_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_jpeg_jpeg_axi_clk.c),
+	},
+};
+
+static struct branch_clk camss_mclk0_clk = {
+	.cbcr_reg = CAMSS_MCLK0_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_mclk0_clk",
+		.parent = &mclk0_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_mclk0_clk.c),
+	},
+};
+
+static struct branch_clk camss_mclk1_clk = {
+	.cbcr_reg = CAMSS_MCLK1_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_mclk1_clk",
+		.parent = &mclk1_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_mclk1_clk.c),
+	},
+};
+
+static struct branch_clk camss_micro_ahb_clk = {
+	.cbcr_reg = CAMSS_MICRO_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_micro_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_micro_ahb_clk.c),
+	},
+};
+
+static struct branch_clk camss_phy0_csi0phytimer_clk = {
+	.cbcr_reg = CAMSS_PHY0_CSI0PHYTIMER_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_phy0_csi0phytimer_clk",
+		.parent = &csi0phytimer_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_phy0_csi0phytimer_clk.c),
+	},
+};
+
+static struct branch_clk camss_phy1_csi1phytimer_clk = {
+	.cbcr_reg = CAMSS_PHY1_CSI1PHYTIMER_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_phy1_csi1phytimer_clk",
+		.parent = &csi1phytimer_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_phy1_csi1phytimer_clk.c),
+	},
+};
+
+static struct branch_clk camss_top_ahb_clk = {
+	.cbcr_reg = CAMSS_TOP_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_top_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_top_ahb_clk.c),
+	},
+};
+
+static struct branch_clk camss_vfe_cpp_ahb_clk = {
+	.cbcr_reg = CAMSS_VFE_CPP_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_vfe_cpp_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_vfe_cpp_ahb_clk.c),
+	},
+};
+
+static struct branch_clk camss_vfe_cpp_clk = {
+	.cbcr_reg = CAMSS_VFE_CPP_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_vfe_cpp_clk",
+		.parent = &cpp_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_vfe_cpp_clk.c),
+	},
+};
+
+static struct branch_clk camss_vfe_vfe0_clk = {
+	.cbcr_reg = CAMSS_VFE_VFE0_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_vfe_vfe0_clk",
+		.parent = &vfe0_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_vfe_vfe0_clk.c),
+	},
+};
+
+static struct branch_clk camss_vfe_vfe_ahb_clk = {
+	.cbcr_reg = CAMSS_VFE_VFE_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_vfe_vfe_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_vfe_vfe_ahb_clk.c),
+	},
+};
+
+static struct branch_clk camss_vfe_vfe_axi_clk = {
+	.cbcr_reg = CAMSS_VFE_VFE_AXI_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "camss_vfe_vfe_axi_clk",
+		.parent = &axi_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(camss_vfe_vfe_axi_clk.c),
+	},
+};
+
+static struct branch_clk mdss_ahb_clk = {
+	.cbcr_reg = MDSS_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "mdss_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(mdss_ahb_clk.c),
+	},
+};
+
+static struct branch_clk mdss_axi_clk = {
+	.cbcr_reg = MDSS_AXI_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "mdss_axi_clk",
+		.parent = &axi_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(mdss_axi_clk.c),
+	},
+};
+
+static struct branch_clk mdss_byte0_clk = {
+	.cbcr_reg = MDSS_BYTE0_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "mdss_byte0_clk",
+		.parent = &byte0_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(mdss_byte0_clk.c),
+	},
+};
+
+static struct branch_clk mdss_esc0_clk = {
+	.cbcr_reg = MDSS_ESC0_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "mdss_esc0_clk",
+		.parent = &esc0_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(mdss_esc0_clk.c),
+	},
+};
+
+static struct branch_clk mdss_mdp_clk = {
+	.cbcr_reg = MDSS_MDP_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "mdss_mdp_clk",
+		.parent = &mdp_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(mdss_mdp_clk.c),
+	},
+};
+
+static struct branch_clk mdss_mdp_lut_clk = {
+	.cbcr_reg = MDSS_MDP_LUT_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "mdss_mdp_lut_clk",
+		.parent = &mdp_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(mdss_mdp_lut_clk.c),
+	},
+};
+
+static struct branch_clk mdss_pclk0_clk = {
+	.cbcr_reg = MDSS_PCLK0_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "mdss_pclk0_clk",
+		.parent = &pclk0_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(mdss_pclk0_clk.c),
+	},
+};
+
+static struct branch_clk mdss_vsync_clk = {
+	.cbcr_reg = MDSS_VSYNC_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "mdss_vsync_clk",
+		.parent = &vsync_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(mdss_vsync_clk.c),
+	},
+};
+
+static struct branch_clk mmss_misc_ahb_clk = {
+	.cbcr_reg = MMSS_MISC_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "mmss_misc_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(mmss_misc_ahb_clk.c),
+	},
+};
+
+static struct branch_clk mmss_mmssnoc_ahb_clk = {
+	.cbcr_reg = MMSS_MMSSNOC_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "mmss_mmssnoc_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(mmss_mmssnoc_ahb_clk.c),
+	},
+};
+
+static struct branch_clk mmss_mmssnoc_bto_ahb_clk = {
+	.cbcr_reg = MMSS_MMSSNOC_BTO_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "mmss_mmssnoc_bto_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(mmss_mmssnoc_bto_ahb_clk.c),
+	},
+};
+
+static struct branch_clk mmss_mmssnoc_axi_clk = {
+	.cbcr_reg = MMSS_MMSSNOC_AXI_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "mmss_mmssnoc_axi_clk",
+		.parent = &axi_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(mmss_mmssnoc_axi_clk.c),
+	},
+};
+
+static struct branch_clk mmss_s0_axi_clk = {
+	.cbcr_reg = MMSS_S0_AXI_CBCR,
+	.has_sibling = 0,
+	.max_div = 0,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "mmss_s0_axi_clk",
+		.parent = &axi_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(mmss_s0_axi_clk.c),
+		.depends = &mmss_mmssnoc_axi_clk.c,
+	},
+};
+
+static struct branch_clk oxili_gfx3d_clk = {
+	.cbcr_reg = OXILI_GFX3D_CBCR,
+	.has_sibling = 1,
+	.max_div = 0,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "oxili_gfx3d_clk",
+		.parent = &gfx3d_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(oxili_gfx3d_clk.c),
+	},
+};
+
+static struct branch_clk oxilicx_ahb_clk = {
+	.cbcr_reg = OXILICX_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "oxilicx_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(oxilicx_ahb_clk.c),
+	},
+};
+
+static struct branch_clk oxilicx_axi_clk = {
+	.cbcr_reg = OXILICX_AXI_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "oxilicx_axi_clk",
+		.parent = &axi_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(oxilicx_axi_clk.c),
+	},
+};
+
+static struct branch_clk venus0_ahb_clk = {
+	.cbcr_reg = VENUS0_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "venus0_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(venus0_ahb_clk.c),
+	},
+};
+
+static struct branch_clk venus0_axi_clk = {
+	.cbcr_reg = VENUS0_AXI_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "venus0_axi_clk",
+		.parent = &axi_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(venus0_axi_clk.c),
+	},
+};
+
+static struct branch_clk venus0_vcodec0_clk = {
+	.cbcr_reg = VENUS0_VCODEC0_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "venus0_vcodec0_clk",
+		.parent = &vcodec0_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(venus0_vcodec0_clk.c),
+	},
+};
+
+static struct measure_mux_entry measure_mux_MMSS[] = {
+	{ &mmss_mmssnoc_ahb_clk.c,  MMSS_BASE, 0x0001 },
+	{ &mmss_mmssnoc_bto_ahb_clk.c,  MMSS_BASE, 0x0002 },
+	{ &mmss_misc_ahb_clk.c,  MMSS_BASE, 0x0003 },
+	{ &mmss_mmssnoc_axi_clk.c,  MMSS_BASE, 0x0004 },
+	{ &mmss_s0_axi_clk.c,  MMSS_BASE, 0x0005 },
+	{ &oxilicx_axi_clk.c,  MMSS_BASE, 0x000b },
+	{ &oxilicx_ahb_clk.c,  MMSS_BASE, 0x000c },
+	{ &oxili_gfx3d_clk.c,  MMSS_BASE, 0x000d },
+	{ &venus0_vcodec0_clk.c,  MMSS_BASE, 0x000e },
+	{ &venus0_axi_clk.c,  MMSS_BASE, 0x000f },
+	{ &venus0_ahb_clk.c,  MMSS_BASE, 0x0011 },
+	{ &mdss_mdp_clk.c,  MMSS_BASE, 0x0014 },
+	{ &mdss_mdp_lut_clk.c,  MMSS_BASE, 0x0015 },
+	{ &mdss_pclk0_clk.c,  MMSS_BASE, 0x0016 },
+	{ &mdss_vsync_clk.c,  MMSS_BASE, 0x001c },
+	{ &mdss_byte0_clk.c,  MMSS_BASE, 0x001e },
+	{ &mdss_esc0_clk.c,  MMSS_BASE, 0x0020 },
+	{ &mdss_ahb_clk.c,  MMSS_BASE, 0x0022 },
+	{ &mdss_axi_clk.c,  MMSS_BASE, 0x0024 },
+	{ &camss_top_ahb_clk.c,  MMSS_BASE, 0x0025 },
+	{ &camss_micro_ahb_clk.c,  MMSS_BASE, 0x0026 },
+	{ &camss_gp0_clk.c,  MMSS_BASE, 0x0027 },
+	{ &camss_gp1_clk.c,  MMSS_BASE, 0x0028 },
+	{ &camss_mclk0_clk.c,  MMSS_BASE, 0x0029 },
+	{ &camss_mclk1_clk.c,  MMSS_BASE, 0x002a },
+	{ &camss_cci_cci_clk.c,  MMSS_BASE, 0x002d },
+	{ &camss_cci_cci_ahb_clk.c,  MMSS_BASE, 0x002e },
+	{ &camss_phy0_csi0phytimer_clk.c,  MMSS_BASE, 0x002f },
+	{ &camss_phy1_csi1phytimer_clk.c,  MMSS_BASE, 0x0030 },
+	{ &camss_jpeg_jpeg0_clk.c,  MMSS_BASE, 0x0032 },
+	{ &camss_jpeg_jpeg_ahb_clk.c,  MMSS_BASE, 0x0035 },
+	{ &camss_jpeg_jpeg_axi_clk.c,  MMSS_BASE, 0x0036 },
+	{ &camss_vfe_vfe0_clk.c,  MMSS_BASE, 0x0038 },
+	{ &camss_vfe_cpp_clk.c,  MMSS_BASE, 0x003a },
+	{ &camss_vfe_cpp_ahb_clk.c,  MMSS_BASE, 0x003b },
+	{ &camss_vfe_vfe_ahb_clk.c,  MMSS_BASE, 0x003c },
+	{ &camss_vfe_vfe_axi_clk.c,  MMSS_BASE, 0x003d },
+	{ &camss_csi_vfe0_clk.c,  MMSS_BASE, 0x003f },
+	{ &camss_csi0_clk.c,  MMSS_BASE, 0x0041 },
+	{ &camss_csi0_ahb_clk.c,  MMSS_BASE, 0x0042 },
+	{ &camss_csi0phy_clk.c,  MMSS_BASE, 0x0043 },
+	{ &camss_csi0rdi_clk.c,  MMSS_BASE, 0x0044 },
+	{ &camss_csi0pix_clk.c,  MMSS_BASE, 0x0045 },
+	{ &camss_csi1_clk.c,  MMSS_BASE, 0x0046 },
+	{ &camss_csi1_ahb_clk.c,  MMSS_BASE, 0x0047 },
+	{ &camss_csi1phy_clk.c,  MMSS_BASE, 0x0048 },
+	{ &camss_csi1rdi_clk.c,  MMSS_BASE, 0x0049 },
+	{ &camss_csi1pix_clk.c,  MMSS_BASE, 0x004a },
+	{ &camss_ispif_ahb_clk.c,  MMSS_BASE, 0x0055 },
+	{&dummy_clk, N_BASES, 0x0000},
+};
+
+static struct branch_clk q6ss_ahb_lfabif_clk = {
+	.cbcr_reg = Q6SS_AHB_LFABIF_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "q6ss_ahb_lfabif_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(q6ss_ahb_lfabif_clk.c),
+	},
+};
+
+static struct branch_clk q6ss_ahbm_clk = {
+	.cbcr_reg = Q6SS_AHBM_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "q6ss_ahbm_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(q6ss_ahbm_clk.c),
+	},
+};
+
+static struct branch_clk q6ss_xo_clk = {
+	.cbcr_reg = Q6SS_XO_CBCR,
+	.has_sibling = 1,
+	.bcr_reg = Q6SS_BCR,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "q6ss_xo_clk",
+		.parent = &xo.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(q6ss_xo_clk.c),
+	},
+};
+
+static struct measure_mux_entry measure_mux_LPASS[] = {
+	{ &q6ss_ahbm_clk.c,  LPASS_BASE, 0x001d },
+	{ &q6ss_ahb_lfabif_clk.c,  LPASS_BASE, 0x001e },
+	{ &q6ss_xo_clk.c,  LPASS_BASE, 0x002b },
+	{&dummy_clk, N_BASES, 0x0000},
+};
+
+
+static DEFINE_CLK_MEASURE(apc0_m_clk);
+static DEFINE_CLK_MEASURE(apc1_m_clk);
+static DEFINE_CLK_MEASURE(apc2_m_clk);
+static DEFINE_CLK_MEASURE(apc3_m_clk);
+static DEFINE_CLK_MEASURE(l2_m_clk);
+
+static struct  measure_mux_entry measure_mux_APSS[] = {
+	{&apc0_m_clk,                    APCS_BASE, 0x00010},
+	{&apc1_m_clk,                    APCS_BASE, 0x00114},
+	{&apc2_m_clk,                    APCS_BASE, 0x00220},
+	{&apc3_m_clk,                    APCS_BASE, 0x00324},
+	{&l2_m_clk,                      APCS_BASE, 0x01000},
+	{&dummy_clk, N_BASES, 0x0000}
+};
+
+#define APCS_SH_PLL_MODE        (0x000)
+#define APCS_SH_PLL_L_VAL       (0x004)
+#define APCS_SH_PLL_M_VAL       (0x008)
+#define APCS_SH_PLL_N_VAL       (0x00C)
+#define APCS_SH_PLL_USER_CTL    (0x010)
+#define APCS_SH_PLL_CONFIG_CTL  (0x014)
+#define APCS_SH_PLL_STATUS      (0x01C)
+
+enum vdd_sr2_pll_levels {
+	VDD_SR2_PLL_OFF,
+	VDD_SR2_PLL_ON,
+	VDD_SR2_PLL_NUM
+};
+
+static struct regulator *vdd_sr2_reg;
+static int set_vdd_sr2_pll(struct clk_vdd_class *vdd_class, int level)
+{
+	if (level == VDD_SR2_PLL_ON) {
+		return regulator_set_voltage(vdd_sr2_reg, 1800000,
+		1800000);
+	} else {
+		return regulator_set_voltage(vdd_sr2_reg, 0, 1800000);
+	}
+}
+
+static DEFINE_VDD_CLASS(vdd_sr2_pll, set_vdd_sr2_pll,
+			VDD_SR2_PLL_NUM);
+
+static struct pll_freq_tbl apcs_pll_freq[] = {
+	F_APCS_PLL( 384000000, 20, 0x0, 0x1, 0x0, 0x0, 0x0),
+	F_APCS_PLL( 787200000, 41, 0x0, 0x1, 0x0, 0x0, 0x0),
+	F_APCS_PLL( 998400000, 52, 0x0, 0x1, 0x0, 0x0, 0x0),
+	F_APCS_PLL(1190400000, 62, 0x0, 0x1, 0x0, 0x0, 0x0),
+	PLL_F_END
+};
+
+static struct pll_clk a7sspll = {
+	.mode_reg = (void __iomem *)APCS_SH_PLL_MODE,
+	.l_reg = (void __iomem *)APCS_SH_PLL_L_VAL,
+	.m_reg = (void __iomem *)APCS_SH_PLL_M_VAL,
+	.n_reg = (void __iomem *)APCS_SH_PLL_N_VAL,
+	.config_reg = (void __iomem *)APCS_SH_PLL_USER_CTL,
+	.status_reg = (void __iomem *)APCS_SH_PLL_STATUS,
+	.freq_tbl = apcs_pll_freq,
+	.masks = {
+		.vco_mask = BM(29, 28),
+		.pre_div_mask = BIT(12),
+		.post_div_mask = BM(9, 8),
+		.mn_en_mask = BIT(24),
+		.main_output_mask = BIT(0),
+	},
+	.base = &virt_bases[APCS_PLL_BASE],
+	.c = {
+		.dbg_name = "a7sspll",
+		.ops = &clk_ops_sr2_pll,
+		.vdd_class = &vdd_sr2_pll,
+		.fmax = (unsigned long [VDD_SR2_PLL_NUM]) {
+			[VDD_SR2_PLL_ON] = ULONG_MAX,
+		},
+		.num_fmax = VDD_SR2_PLL_NUM,
+		CLK_INIT(a7sspll.c),
+		/*
+		 * Need to skip handoff of the acpu pll to avoid
+		 * turning off the pll when the cpu is using it
+		 */
+		.flags = CLKFLAG_SKIP_HANDOFF,
+	},
+};
+
+static DEFINE_CLK_VOTER(pnoc_msmbus_clk, &pnoc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(snoc_msmbus_clk, &snoc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(cnoc_msmbus_clk, &cnoc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(pnoc_msmbus_a_clk, &pnoc_a_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(snoc_msmbus_a_clk, &snoc_a_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(cnoc_msmbus_a_clk, &cnoc_a_clk.c, LONG_MAX);
+
+static DEFINE_CLK_VOTER(bimc_msmbus_clk, &bimc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(bimc_msmbus_a_clk, &bimc_a_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(bimc_acpu_a_clk, &bimc_a_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(oxili_gfx3d_clk_src, &gfx3d_clk_src.c, LONG_MAX);
+static DEFINE_CLK_VOTER(ocmemgx_msmbus_clk, &ocmemgx_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(ocmemgx_msmbus_a_clk, &ocmemgx_a_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(ocmemgx_core_clk, &ocmemgx_clk.c, LONG_MAX);
+
+static DEFINE_CLK_VOTER(pnoc_sps_clk, &pnoc_clk.c, LONG_MAX);
+
+#ifdef CONFIG_DEBUG_FS
+static int measure_clk_set_parent(struct clk *c, struct clk *parent)
+{
+	struct measure_clk *clk = to_measure_clk(c);
+	unsigned long flags;
+	u32 regval, clk_sel, found = 0;
+	int i;
+	static const struct measure_mux_entry *array[] = {
+		measure_mux_GCC,
+		measure_mux_MMSS,
+		measure_mux_LPASS,
+		measure_mux_APSS,
+		NULL
+	};
+	const struct measure_mux_entry *mux = array[0];
+
+	if (!parent)
+		return -EINVAL;
+
+	for (i = 0; array[i] && !found; i++) {
+		for (mux = array[i]; mux->c != &dummy_clk; mux++)
+			if (mux->c == parent) {
+				found = 1;
+				break;
+			}
+	}
+
+	if (mux->c == &dummy_clk)
+		return -EINVAL;
+
+	spin_lock_irqsave(&local_clock_reg_lock, flags);
+	/*
+	 * Program the test vector, measurement period (sample_ticks)
+	 * and scaling multiplier.
+	 */
+	clk->sample_ticks = 0x10000;
+	clk->multiplier = 1;
+
+	switch (mux->base) {
+
+	case GCC_BASE:
+		writel_relaxed(0, GCC_REG_BASE(GCC_DEBUG_CLK_CTL));
+		clk_sel = mux->debug_mux;
+		break;
+
+	case MMSS_BASE:
+		writel_relaxed(0, MMSS_REG_BASE(MMSS_DEBUG_CLK_CTL));
+		clk_sel = 0x02C;
+		regval = BVAL(11, 0, mux->debug_mux);
+		writel_relaxed(regval, MMSS_REG_BASE(MMSS_DEBUG_CLK_CTL));
+
+		/* Activate debug clock output */
+		regval |= BIT(16);
+		writel_relaxed(regval, MMSS_REG_BASE(MMSS_DEBUG_CLK_CTL));
+		break;
+
+	case LPASS_BASE:
+		writel_relaxed(0, LPASS_REG_BASE(LPASS_DEBUG_CLK_CTL));
+		clk_sel = 0x161;
+		regval = BVAL(11, 0, mux->debug_mux);
+		writel_relaxed(regval, LPASS_REG_BASE(LPASS_DEBUG_CLK_CTL));
+
+		/* Activate debug clock output */
+		regval |= BIT(20);
+		writel_relaxed(regval, LPASS_REG_BASE(LPASS_DEBUG_CLK_CTL));
+		break;
+
+	case APCS_BASE:
+		clk->multiplier = 4;
+		clk_sel = 362;
+		regval = readl_relaxed(APCS_REG_BASE(GLB_CLK_DIAG));
+		regval &= ~0xC0037335;
+		/* configure a divider of 4 */
+		regval = BVAL(31, 30, 0x3) | mux->debug_mux;
+		writel_relaxed(regval, APCS_REG_BASE(GLB_CLK_DIAG));
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	/* Set debug mux clock index */
+	regval = BVAL(8, 0, clk_sel);
+	writel_relaxed(regval, GCC_REG_BASE(GCC_DEBUG_CLK_CTL));
+
+	/* Activate debug clock output */
+	regval |= BIT(16);
+	writel_relaxed(regval, GCC_REG_BASE(GCC_DEBUG_CLK_CTL));
+
+	/* Make sure test vector is set before starting measurements. */
+	mb();
+	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
+
+	return 0;
+}
+
+/* Sample clock for 'ticks' reference clock ticks. */
+static u32 run_measurement(unsigned ticks)
+{
+	/* Stop counters and set the XO4 counter start value. */
+	writel_relaxed(ticks, GCC_REG_BASE(CLOCK_FRQ_MEASURE_CTL));
+
+	/* Wait for timer to become ready. */
+	while ((readl_relaxed(GCC_REG_BASE(CLOCK_FRQ_MEASURE_STATUS)) &
+			BIT(25)) != 0)
+		cpu_relax();
+
+	/* Run measurement and wait for completion. */
+	writel_relaxed(BIT(20)|ticks, GCC_REG_BASE(CLOCK_FRQ_MEASURE_CTL));
+	while ((readl_relaxed(GCC_REG_BASE(CLOCK_FRQ_MEASURE_STATUS)) &
+			BIT(25)) == 0)
+		cpu_relax();
+
+	/* Return measured ticks. */
+	return readl_relaxed(GCC_REG_BASE(CLOCK_FRQ_MEASURE_STATUS)) &
+				BM(24, 0);
+}
+
+/*
+ * Perform a hardware rate measurement for a given clock.
+ * FOR DEBUG USE ONLY: Measurements take ~15 ms!
+ */
+static unsigned long measure_clk_get_rate(struct clk *c)
+{
+	unsigned long flags;
+	u32 gcc_xo4_reg_backup;
+	u64 raw_count_short, raw_count_full;
+	struct measure_clk *clk = to_measure_clk(c);
+	unsigned ret;
+
+	ret = clk_prepare_enable(&xo.c);
+	if (ret) {
+		pr_warn("CXO clock failed to enable. Can't measure\n");
+		return 0;
+	}
+
+	spin_lock_irqsave(&local_clock_reg_lock, flags);
+
+	/* Enable CXO/4 and RINGOSC branch. */
+	gcc_xo4_reg_backup = readl_relaxed(GCC_REG_BASE(GCC_XO_DIV4_CBCR));
+	writel_relaxed(0x1, GCC_REG_BASE(GCC_XO_DIV4_CBCR));
+
+	/*
+	 * The ring oscillator counter will not reset if the measured clock
+	 * is not running.  To detect this, run a short measurement before
+	 * the full measurement.  If the raw results of the two are the same
+	 * then the clock must be off.
+	 */
+
+	/* Run a short measurement. (~1 ms) */
+	raw_count_short = run_measurement(0x1000);
+	/* Run a full measurement. (~14 ms) */
+	raw_count_full = run_measurement(clk->sample_ticks);
+
+	writel_relaxed(gcc_xo4_reg_backup, GCC_REG_BASE(GCC_XO_DIV4_CBCR));
+
+	/* Return 0 if the clock is off. */
+	if (raw_count_full == raw_count_short) {
+		ret = 0;
+	} else {
+		/* Compute rate in Hz. */
+		raw_count_full = ((raw_count_full * 10) + 15) * 4800000;
+		do_div(raw_count_full, ((clk->sample_ticks * 10) + 35));
+		ret = (raw_count_full * clk->multiplier);
+	}
+
+	writel_relaxed(0x51A00, GCC_REG_BASE(PLLTEST_PAD_CFG));
+	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
+
+	clk_disable_unprepare(&xo.c);
+
+	return ret;
+}
+
+#else /* !CONFIG_DEBUG_FS */
+static int measure_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	return -EINVAL;
+}
+
+static unsigned long measure_clk_get_rate(struct clk *clk)
+{
+	return 0;
+}
+#endif /* CONFIG_DEBUG_FS */
+
+static struct clk_ops clk_ops_measure = {
+	.set_parent = measure_clk_set_parent,
+	.get_rate = measure_clk_get_rate,
+};
+
+static struct measure_clk measure_clk = {
+	.c = {
+		.dbg_name = "measure_clk",
+		.ops = &clk_ops_measure,
+		CLK_INIT(measure_clk.c),
+	},
+	.multiplier = 1,
+};
+
+static struct clk_lookup msm_clocks_8226[] = {
+	/* Debug Clocks */
+	CLK_LOOKUP("measure", measure_clk.c, "debug"),
+	CLK_LOOKUP("apc0_m_clk", apc0_m_clk, ""),
+	CLK_LOOKUP("apc1_m_clk", apc1_m_clk, ""),
+	CLK_LOOKUP("apc2_m_clk", apc2_m_clk, ""),
+	CLK_LOOKUP("apc3_m_clk", apc3_m_clk, ""),
+	CLK_LOOKUP("l2_m_clk", l2_m_clk, ""),
+
+	/* PIL-LPASS */
+	CLK_LOOKUP("xo",                         xo.c, "fe200000.qcom,lpass"),
+	CLK_LOOKUP("core_clk",          q6ss_xo_clk.c, "fe200000.qcom,lpass"),
+	CLK_LOOKUP("bus_clk",  gcc_lpass_q6_axi_clk.c, "fe200000.qcom,lpass"),
+	CLK_LOOKUP("iface_clk", q6ss_ahb_lfabif_clk.c, "fe200000.qcom,lpass"),
+	CLK_LOOKUP("reg_clk",         q6ss_ahbm_clk.c, "fe200000.qcom,lpass"),
+
+	/* PIL-MODEM */
+	CLK_LOOKUP("xo",                           xo.c, "fc880000.qcom,mss"),
+	CLK_LOOKUP("bus_clk", gcc_mss_q6_bimc_axi_clk.c, "fc880000.qcom,mss"),
+	CLK_LOOKUP("iface_clk",   gcc_mss_cfg_ahb_clk.c, "fc880000.qcom,mss"),
+	CLK_LOOKUP("mem_clk",    gcc_boot_rom_ahb_clk.c, "fc880000.qcom,mss"),
+
+	/* PIL-PRONTO */
+	CLK_LOOKUP("xo", xo.c, "fb21b000.qcom,pronto"),
+
+	/* PIL-VENUS */
+	CLK_LOOKUP("src_clk",     vcodec0_clk_src.c, "fdce0000.qcom,venus"),
+	CLK_LOOKUP("core_clk", venus0_vcodec0_clk.c, "fdce0000.qcom,venus"),
+	CLK_LOOKUP("iface_clk",    venus0_ahb_clk.c, "fdce0000.qcom,venus"),
+	CLK_LOOKUP("bus_clk",      venus0_axi_clk.c, "fdce0000.qcom,venus"),
+	CLK_LOOKUP("mem_clk",      venus0_ahb_clk.c, "fdce0000.qcom,venus"),
+
+	/* ACPUCLOCK */
+	CLK_LOOKUP("xo",     xo_a_clk.c, "f9011050.qcom,acpuclk"),
+	CLK_LOOKUP("gpll0",  gpll0_ao.c, "f9011050.qcom,acpuclk"),
+	CLK_LOOKUP("a7sspll", a7sspll.c, "f9011050.qcom,acpuclk"),
+
+	/* WCNSS CLOCKS */
+	CLK_LOOKUP("xo", xo.c, "fb000000.qcom,wcnss-wlan"),
+
+	/* BUS DRIVER */
+	CLK_LOOKUP("bus_clk", cnoc_msmbus_clk.c, "msm_config_noc"),
+	CLK_LOOKUP("bus_a_clk", cnoc_msmbus_a_clk.c, "msm_config_noc"),
+	CLK_LOOKUP("bus_clk", snoc_msmbus_clk.c, "msm_sys_noc"),
+	CLK_LOOKUP("bus_a_clk", snoc_msmbus_a_clk.c, "msm_sys_noc"),
+	CLK_LOOKUP("bus_clk", pnoc_msmbus_clk.c, "msm_periph_noc"),
+	CLK_LOOKUP("bus_a_clk", pnoc_msmbus_a_clk.c, "msm_periph_noc"),
+	CLK_LOOKUP("mem_clk", bimc_msmbus_clk.c, "msm_bimc"),
+	CLK_LOOKUP("mem_a_clk", bimc_msmbus_a_clk.c, "msm_bimc"),
+	CLK_LOOKUP("mem_clk", bimc_acpu_a_clk.c, ""),
+	CLK_LOOKUP("ocmem_clk",	ocmemgx_msmbus_clk.c,	  "msm_bus"),
+	CLK_LOOKUP("ocmem_a_clk", ocmemgx_msmbus_a_clk.c, "msm_bus"),
+	CLK_LOOKUP("bus_clk",	mmss_s0_axi_clk.c,	"msm_mmss_noc"),
+	CLK_LOOKUP("bus_a_clk",	mmss_s0_axi_clk.c,	"msm_mmss_noc"),
+	CLK_LOOKUP("iface_clk", gcc_mmss_noc_cfg_ahb_clk.c, ""),
+
+	/* CoreSight clocks */
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc322000.tmc"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc318000.tpiu"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc31c000.replicator"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc307000.tmc"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc31b000.funnel"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc319000.funnel"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc31a000.funnel"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc345000.funnel"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc364000.funnel"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc321000.stm"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc33c000.etm"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc33d000.etm"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc33e000.etm"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc33f000.etm"),
+
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc322000.tmc"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc318000.tpiu"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc31c000.replicator"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc307000.tmc"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc31b000.funnel"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc319000.funnel"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc31a000.funnel"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc345000.funnel"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc364000.funnel"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc321000.stm"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc33c000.etm"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc33d000.etm"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc33e000.etm"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc33f000.etm"),
+
+	/* HSUSB-OTG Clocks */
+	CLK_LOOKUP("xo",                          xo.c, "f9a55000.usb"),
+	CLK_LOOKUP("iface_clk",   gcc_usb_hs_ahb_clk.c, "f9a55000.usb"),
+	CLK_LOOKUP("core_clk", gcc_usb_hs_system_clk.c, "f9a55000.usb"),
+
+	/* SPS CLOCKS */
+	CLK_LOOKUP("dfab_clk",            pnoc_sps_clk.c, "f9984000.qcom,sps"),
+	CLK_LOOKUP("dma_bam_pclk", gcc_bam_dma_ahb_clk.c, "f9884000.qcom,sps"),
+	CLK_LOOKUP("dfab_clk",            pnoc_sps_clk.c, "msm_sps"),
+	CLK_LOOKUP("dma_bam_pclk", gcc_bam_dma_ahb_clk.c, "msm_sps"),
+
+	/* I2C Clocks */
+	CLK_LOOKUP("iface_clk",          gcc_blsp1_ahb_clk.c, "f9926000.i2c"),
+	CLK_LOOKUP("core_clk", gcc_blsp1_qup4_i2c_apps_clk.c, "f9926000.i2c"),
+
+	/* lsuart-v14 Clocks */
+	CLK_LOOKUP("iface_clk",       gcc_blsp1_ahb_clk.c, "f991f000.serial"),
+	CLK_LOOKUP("core_clk", gcc_blsp1_uart3_apps_clk.c, "f991f000.serial"),
+
+	CLK_LOOKUP("iface_clk",       gcc_blsp1_ahb_clk.c, "f995e000.serial"),
+	CLK_LOOKUP("core_clk", gcc_blsp1_uart2_apps_clk.c, "f995e000.serial"),
+
+	CLK_LOOKUP("iface_clk",          gcc_blsp1_ahb_clk.c, "f9923000.spi"),
+	CLK_LOOKUP("core_clk", gcc_blsp1_qup1_spi_apps_clk.c, "f9923000.spi"),
+
+	CLK_LOOKUP("core_clk",     gcc_ce1_clk.c,         "qseecom"),
+	CLK_LOOKUP("iface_clk",    gcc_ce1_ahb_clk.c,     "qseecom"),
+	CLK_LOOKUP("bus_clk",      gcc_ce1_axi_clk.c,     "qseecom"),
+	CLK_LOOKUP("core_clk_src", ce1_clk_src.c,         "qseecom"),
+
+	/* SDCC */
+	CLK_LOOKUP("iface_clk", gcc_sdcc1_ahb_clk.c, "f9824000.qcom,sdcc"),
+	CLK_LOOKUP("core_clk", gcc_sdcc1_apps_clk.c, "f9824000.qcom,sdcc"),
+	CLK_LOOKUP("iface_clk", gcc_sdcc1_ahb_clk.c, "msm_sdcc.1"),
+	CLK_LOOKUP("core_clk", gcc_sdcc1_apps_clk.c, "msm_sdcc.1"),
+
+	CLK_LOOKUP("iface_clk", gcc_sdcc2_ahb_clk.c, "f98a4000.qcom,sdcc"),
+	CLK_LOOKUP("core_clk", gcc_sdcc2_apps_clk.c, "f98a4000.qcom,sdcc"),
+	CLK_LOOKUP("iface_clk", gcc_sdcc2_ahb_clk.c, "msm_sdcc.2"),
+	CLK_LOOKUP("core_clk", gcc_sdcc2_apps_clk.c, "msm_sdcc.2"),
+
+	CLK_LOOKUP("iface_clk", gcc_sdcc3_ahb_clk.c, "msm_sdcc.3"),
+	CLK_LOOKUP("core_clk", gcc_sdcc3_apps_clk.c, "msm_sdcc.3"),
+
+	CLK_LOOKUP("sleep_a_clk", gcc_usb2a_phy_sleep_clk.c, "msm_dwc3"),
+	CLK_LOOKUP("ref_clk", diff_clk.c, "msm_dwc3"),
+
+
+	CLK_LOOKUP("bus_clk", pnoc_clk.c, ""),
+	CLK_LOOKUP("bus_clk", pnoc_a_clk.c, ""),
+	CLK_LOOKUP("bus_clk", snoc_clk.c, ""),
+	CLK_LOOKUP("bus_clk", snoc_a_clk.c, ""),
+	CLK_LOOKUP("bus_clk", cnoc_clk.c, ""),
+	CLK_LOOKUP("bus_clk", cnoc_a_clk.c, ""),
+	CLK_LOOKUP("bus_clk", mmssnoc_ahb_clk.c, ""),
+	CLK_LOOKUP("bus_clk", mmssnoc_ahb_a_clk.c, ""),
+	CLK_LOOKUP("bus_clk", bimc_clk.c, ""),
+	CLK_LOOKUP("bus_clk", bimc_a_clk.c, ""),
+	CLK_LOOKUP("bus_clk_src", axi_clk_src.c, ""),
+
+	CLK_LOOKUP("gpll0", gpll0.c, ""),
+	CLK_LOOKUP("gpll1", gpll1.c, ""),
+	CLK_LOOKUP("mmpll0", mmpll0_pll.c, ""),
+	CLK_LOOKUP("mmpll1", mmpll1_pll.c, ""),
+	CLK_LOOKUP("mmpll2", mmpll2_pll.c, ""),
+
+	CLK_LOOKUP("core_clk", gcc_blsp1_qup1_i2c_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_qup2_i2c_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_qup2_spi_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_qup3_i2c_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_qup3_spi_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_qup4_i2c_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_qup4_spi_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_qup5_i2c_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_qup5_spi_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_qup6_i2c_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_qup6_spi_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_uart1_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_uart4_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_uart5_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_uart6_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_pdm2_clk.c, ""),
+	CLK_LOOKUP("iface_clk", gcc_pdm_ahb_clk.c, ""),
+	CLK_LOOKUP("iface_clk", gcc_prng_ahb_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_gp1_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_gp2_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_gp3_clk.c, ""),
+
+	CLK_LOOKUP("iface_clk", gcc_usb_hsic_ahb_clk.c,	  "msm_hsic_host"),
+	CLK_LOOKUP("phy_clk", gcc_usb_hsic_clk.c,	  "msm_hsic_host"),
+	CLK_LOOKUP("cal_clk", gcc_usb_hsic_io_cal_clk.c,  "msm_hsic_host"),
+	CLK_LOOKUP("core_clk", gcc_usb_hsic_system_clk.c, "msm_hsic_host"),
+	CLK_LOOKUP("ref_clk", div_clk2.c, "msm_smsc_hub"),
+	CLK_LOOKUP("iface_clk", gcc_usb_hs_ahb_clk.c,     "msm_ehci_host"),
+	CLK_LOOKUP("core_clk", gcc_usb_hs_system_clk.c,   "msm_ehci_host"),
+	CLK_LOOKUP("pwm_clk", div_clk2.c, "0-0048"),
+
+	/* Multimedia clocks */
+	CLK_LOOKUP("byte_clk", mdss_byte0_clk.c, "fd922800.qcom,mdss_dsi"),
+	CLK_LOOKUP("core_clk", mdss_esc0_clk.c, "fd922800.qcom,mdss_dsi"),
+	CLK_LOOKUP("pixel_clk", mdss_pclk0_clk.c, "fd922800.qcom,mdss_dsi"),
+	CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "mdss_dsi_clk_ctrl"),
+
+	CLK_LOOKUP("core_clk", mdss_mdp_clk.c, "mdp.0"),
+	CLK_LOOKUP("lut_clk", mdss_mdp_lut_clk.c, "mdp.0"),
+	CLK_LOOKUP("core_clk_src", mdp_clk_src.c, "mdp.0"),
+	CLK_LOOKUP("vsync_clk", mdss_vsync_clk.c, "mdp.0"),
+	CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "mdp.0"),
+	CLK_LOOKUP("bus_clk", mdss_axi_clk.c, "mdp.0"),
+
+	CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "fd928000.qcom,iommu"),
+	CLK_LOOKUP("core_clk", mdss_axi_clk.c, "fd928000.qcom,iommu"),
+
+	/* MM sensor clocks */
+	CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6e.qcom,camera"),
+	CLK_LOOKUP("cam_src_clk", mclk1_clk_src.c, "90.qcom,camera"),
+	CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "6e.qcom,camera"),
+	CLK_LOOKUP("cam_clk", camss_mclk1_clk.c, "90.qcom,camera"),
+
+	/* CCI clocks */
+	CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+		"fda0c000.qcom,cci"),
+	CLK_LOOKUP("cci_ahb_clk", camss_cci_cci_ahb_clk.c,
+		"fda0c000.qcom,cci"),
+	CLK_LOOKUP("cci_src_clk", cci_clk_src.c, "fda0c000.qcom,cci"),
+	CLK_LOOKUP("cci_clk", camss_cci_cci_clk.c, "fda0c000.qcom,cci"),
+
+	/* CSIPHY clocks */
+	CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+		"fda0ac00.qcom,csiphy"),
+	CLK_LOOKUP("ispif_ahb_clk", camss_ispif_ahb_clk.c,
+		"fda0ac00.qcom,csiphy"),
+	CLK_LOOKUP("csiphy_timer_src_clk", csi0phytimer_clk_src.c,
+		"fda0ac00.qcom,csiphy"),
+	CLK_LOOKUP("csiphy_timer_clk", camss_phy0_csi0phytimer_clk.c,
+		"fda0ac00.qcom,csiphy"),
+	CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+		"fda0b000.qcom,csiphy"),
+	CLK_LOOKUP("ispif_ahb_clk", camss_ispif_ahb_clk.c,
+		"fda0b000.qcom,csiphy"),
+	CLK_LOOKUP("csiphy_timer_src_clk", csi1phytimer_clk_src.c,
+		"fda0b000.qcom,csiphy"),
+	CLK_LOOKUP("csiphy_timer_clk", camss_phy1_csi1phytimer_clk.c,
+		"fda0b000.qcom,csiphy"),
+
+	/* CSID clocks */
+	CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+		"fda08000.qcom,csid"),
+	CLK_LOOKUP("ispif_ahb_clk", camss_ispif_ahb_clk.c,
+		"fda08000.qcom,csid"),
+	CLK_LOOKUP("csi0_ahb_clk", camss_csi0_ahb_clk.c, "fda08000.qcom,csid"),
+	CLK_LOOKUP("csi0_src_clk", csi0_clk_src.c,       "fda08000.qcom,csid"),
+	CLK_LOOKUP("csi0_phy_clk", camss_csi0phy_clk.c,  "fda08000.qcom,csid"),
+	CLK_LOOKUP("csi0_clk", camss_csi0_clk.c,         "fda08000.qcom,csid"),
+	CLK_LOOKUP("csi0_pix_clk", camss_csi0pix_clk.c,  "fda08000.qcom,csid"),
+	CLK_LOOKUP("csi0_rdi_clk", camss_csi0rdi_clk.c,  "fda08000.qcom,csid"),
+
+	CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+		"fda08400.qcom,csid"),
+	CLK_LOOKUP("ispif_ahb_clk", camss_ispif_ahb_clk.c,
+		"fda08400.qcom,csid"),
+	CLK_LOOKUP("csi0_ahb_clk", camss_csi0_ahb_clk.c, "fda08400.qcom,csid"),
+	CLK_LOOKUP("csi1_ahb_clk", camss_csi1_ahb_clk.c, "fda08400.qcom,csid"),
+	CLK_LOOKUP("csi0_src_clk", csi0_clk_src.c,       "fda08400.qcom,csid"),
+	CLK_LOOKUP("csi1_src_clk", csi1_clk_src.c,       "fda08400.qcom,csid"),
+	CLK_LOOKUP("csi0_phy_clk", camss_csi0phy_clk.c,  "fda08400.qcom,csid"),
+	CLK_LOOKUP("csi1_phy_clk", camss_csi1phy_clk.c,  "fda08400.qcom,csid"),
+	CLK_LOOKUP("csi0_pix_clk", camss_csi0pix_clk.c,  "fda08400.qcom,csid"),
+	CLK_LOOKUP("csi1_pix_clk", camss_csi1pix_clk.c,  "fda08400.qcom,csid"),
+	CLK_LOOKUP("csi0_rdi_clk", camss_csi0rdi_clk.c,  "fda08400.qcom,csid"),
+	CLK_LOOKUP("csi1_rdi_clk", camss_csi1rdi_clk.c,  "fda08400.qcom,csid"),
+
+	/* ISPIF clocks */
+	CLK_LOOKUP("camss_vfe_vfe_clk", camss_vfe_vfe0_clk.c,
+		"fda0a000.qcom,ispif"),
+	CLK_LOOKUP("camss_csi_vfe_clk", camss_csi_vfe0_clk.c,
+		"fda0a000.qcom,ispif"),
+
+	/* VFE clocks */
+	CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+					"fda10000.qcom,vfe"),
+	CLK_LOOKUP("vfe_clk_src", vfe0_clk_src.c,	 "fda10000.qcom,vfe"),
+	CLK_LOOKUP("camss_vfe_vfe_clk", camss_vfe_vfe0_clk.c,
+					"fda10000.qcom,vfe"),
+	CLK_LOOKUP("camss_csi_vfe_clk", camss_csi_vfe0_clk.c,
+					"fda10000.qcom,vfe"),
+	CLK_LOOKUP("iface_clk", camss_vfe_vfe_ahb_clk.c, "fda10000.qcom,vfe"),
+	CLK_LOOKUP("bus_clk", camss_vfe_vfe_axi_clk.c,	 "fda10000.qcom,vfe"),
+
+	CLK_LOOKUP("iface_clk", camss_vfe_vfe_ahb_clk.c,
+	"fda44000.qcom,iommu"),
+	CLK_LOOKUP("core_clk", camss_vfe_vfe_axi_clk.c, "fda44000.qcom,iommu"),
+	CLK_LOOKUP("alt_core_clk", camss_top_ahb_clk.c, "fda44000.qcom,iommu"),
+
+	/* Jpeg Clocks */
+	CLK_LOOKUP("core_clk", camss_jpeg_jpeg0_clk.c, "fda1c000.qcom,jpeg"),
+	CLK_LOOKUP("iface_clk", camss_jpeg_jpeg_ahb_clk.c,
+						"fda1c000.qcom,jpeg"),
+	CLK_LOOKUP("bus_clk0", camss_jpeg_jpeg_axi_clk.c,
+	"fda1c000.qcom,jpeg"),
+	CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+						"fda1c000.qcom,jpeg"),
+
+	CLK_LOOKUP("alt_core_clk", camss_top_ahb_clk.c, "fda64000.qcom,iommu"),
+	CLK_LOOKUP("iface_clk", camss_jpeg_jpeg_ahb_clk.c,
+						"fda64000.qcom,iommu"),
+	CLK_LOOKUP("core_clk", camss_jpeg_jpeg_axi_clk.c,
+						"fda64000.qcom,iommu"),
+
+	/* KGSL Clocks */
+	CLK_LOOKUP("core_clk", oxili_gfx3d_clk.c, "fdb00000.qcom,kgsl-3d0"),
+	CLK_LOOKUP("iface_clk", oxilicx_ahb_clk.c, "fdb00000.qcom,kgsl-3d0"),
+	CLK_LOOKUP("mem_iface_clk", oxilicx_axi_clk.c,
+		"fdb00000.qcom,kgsl-3d0"),
+
+	CLK_LOOKUP("alt_core_clk", oxili_gfx3d_clk.c, "fdb10000.qcom,iommu"),
+	CLK_LOOKUP("iface_clk", oxilicx_ahb_clk.c, "fdb10000.qcom,iommu"),
+	CLK_LOOKUP("core_clk", oxilicx_axi_clk.c, "fdb10000.qcom,iommu"),
+
+	CLK_LOOKUP("core_clk", ocmemgx_core_clk.c, "fdd00000.qcom,ocmem"),
+
+	/* Venus Clocks */
+	CLK_LOOKUP("core_clk", venus0_vcodec0_clk.c, "fdc00000.qcom,vidc"),
+	CLK_LOOKUP("iface_clk",  venus0_ahb_clk.c, "fdc00000.qcom,vidc"),
+	CLK_LOOKUP("bus_clk",  venus0_axi_clk.c, "fdc00000.qcom,vidc"),
+
+	CLK_LOOKUP("alt_core_clk", venus0_vcodec0_clk.c,
+	"fdc84000.qcom,iommu"),
+	CLK_LOOKUP("iface_clk", venus0_ahb_clk.c, "fdc84000.qcom,iommu"),
+	CLK_LOOKUP("core_clk", venus0_axi_clk.c, "fdc84000.qcom,iommu"),
+
+	CLK_LOOKUP("cam_gp0_clk", camss_gp0_clk.c, ""),
+	CLK_LOOKUP("cam_gp1_clk", camss_gp1_clk.c, ""),
+	CLK_LOOKUP("iface_clk", camss_micro_ahb_clk.c, ""),
+
+	CLK_LOOKUP("", mmss_mmssnoc_ahb_clk.c, ""),
+	CLK_LOOKUP("", mmss_mmssnoc_bto_ahb_clk.c, ""),
+	CLK_LOOKUP("", mmss_mmssnoc_axi_clk.c, ""),
+	CLK_LOOKUP("", mmss_s0_axi_clk.c, ""),
+};
+
+static struct clk_lookup msm_clocks_8226_rumi[] = {
+	CLK_DUMMY("core_clk", BLSP1_UART_CLK, "f991f000.serial", OFF),
+	CLK_DUMMY("iface_clk", BLSP1_UART_CLK, "f991f000.serial", OFF),
+	CLK_DUMMY("iface_clk", HSUSB_IFACE_CLK, "f9a55000.usb", OFF),
+	CLK_DUMMY("core_clk", HSUSB_CORE_CLK, "f9a55000.usb", OFF),
+	CLK_DUMMY("iface_clk", NULL, "msm_sdcc.1", OFF),
+	CLK_DUMMY("core_clk",  NULL, "msm_sdcc.1", OFF),
+	CLK_DUMMY("bus_clk",   NULL, "msm_sdcc.1", OFF),
+	CLK_DUMMY("iface_clk", NULL, "msm_sdcc.2", OFF),
+	CLK_DUMMY("core_clk",  NULL, "msm_sdcc.2", OFF),
+	CLK_DUMMY("bus_clk",   NULL, "msm_sdcc.2", OFF),
+};
+
+struct clock_init_data msm8226_rumi_clock_init_data __initdata = {
+	.table = msm_clocks_8226_rumi,
+	.size = ARRAY_SIZE(msm_clocks_8226_rumi),
+};
+
+static struct pll_config_regs gpll0_regs __initdata = {
+	.l_reg = (void __iomem *)GPLL0_L_VAL,
+	.m_reg = (void __iomem *)GPLL0_M_VAL,
+	.n_reg = (void __iomem *)GPLL0_N_VAL,
+	.config_reg = (void __iomem *)GPLL0_USER_CTL,
+	.mode_reg = (void __iomem *)GPLL0_MODE,
+	.base = &virt_bases[GCC_BASE],
+};
+
+/* GPLL0 at 600 MHz, main output enabled. */
+static struct pll_config gpll0_config __initdata = {
+	.l = 0x1f,
+	.m = 0x1,
+	.n = 0x4,
+	.vco_val = 0x0,
+	.vco_mask = BM(21, 20),
+	.pre_div_val = 0x0,
+	.pre_div_mask = BM(14, 12),
+	.post_div_val = 0x0,
+	.post_div_mask = BM(9, 8),
+	.mn_ena_val = BIT(24),
+	.mn_ena_mask = BIT(24),
+	.main_output_val = BIT(0),
+	.main_output_mask = BIT(0),
+};
+
+static struct pll_config_regs gpll1_regs __initdata = {
+	.l_reg = (void __iomem *)GPLL1_L_VAL,
+	.m_reg = (void __iomem *)GPLL1_M_VAL,
+	.n_reg = (void __iomem *)GPLL1_N_VAL,
+	.config_reg = (void __iomem *)GPLL1_USER_CTL,
+	.mode_reg = (void __iomem *)GPLL1_MODE,
+	.base = &virt_bases[GCC_BASE],
+};
+
+/* GPLL1 at 480 MHz, main output enabled. */
+static struct pll_config gpll1_config __initdata = {
+	.l = 0x19,
+	.m = 0x0,
+	.n = 0x1,
+	.vco_val = 0x0,
+	.vco_mask = BM(21, 20),
+	.pre_div_val = 0x0,
+	.pre_div_mask = BM(14, 12),
+	.post_div_val = 0x0,
+	.post_div_mask = BM(9, 8),
+	.main_output_val = BIT(0),
+	.main_output_mask = BIT(0),
+};
+
+static struct pll_config_regs mmpll0_regs __initdata = {
+	.l_reg = (void __iomem *)MMPLL0_PLL_L_VAL,
+	.m_reg = (void __iomem *)MMPLL0_PLL_M_VAL,
+	.n_reg = (void __iomem *)MMPLL0_PLL_N_VAL,
+	.config_reg = (void __iomem *)MMPLL0_PLL_USER_CTL,
+	.mode_reg = (void __iomem *)MMPLL0_PLL_MODE,
+	.base = &virt_bases[MMSS_BASE],
+};
+
+/* MMPLL0 at 800 MHz, main output enabled. */
+static struct pll_config mmpll0_config __initdata = {
+	.l = 0x29,
+	.m = 0x2,
+	.n = 0x3,
+	.vco_val = 0x0,
+	.vco_mask = BM(21, 20),
+	.pre_div_val = 0x0,
+	.pre_div_mask = BM(14, 12),
+	.post_div_val = 0x0,
+	.post_div_mask = BM(9, 8),
+	.mn_ena_val = BIT(24),
+	.mn_ena_mask = BIT(24),
+	.main_output_val = BIT(0),
+	.main_output_mask = BIT(0),
+};
+
+static struct pll_config_regs mmpll1_regs __initdata = {
+	.l_reg = (void __iomem *)MMPLL1_PLL_L_VAL,
+	.m_reg = (void __iomem *)MMPLL1_PLL_M_VAL,
+	.n_reg = (void __iomem *)MMPLL1_PLL_N_VAL,
+	.config_reg = (void __iomem *)MMPLL1_PLL_USER_CTL,
+	.mode_reg = (void __iomem *)MMPLL1_PLL_MODE,
+	.base = &virt_bases[MMSS_BASE],
+};
+
+/* MMPLL1 at 1000 MHz, main output enabled. */
+static struct pll_config mmpll1_config __initdata = {
+	.l = 0x2C,
+	.m = 0x1,
+	.n = 0x10,
+	.vco_val = 0x0,
+	.vco_mask = BM(21, 20),
+	.pre_div_val = 0x0,
+	.pre_div_mask = BM(14, 12),
+	.post_div_val = 0x0,
+	.post_div_mask = BM(9, 8),
+	.mn_ena_val = BIT(24),
+	.mn_ena_mask = BIT(24),
+	.main_output_val = BIT(0),
+	.main_output_mask = BIT(0),
+};
+
+#define PLL_AUX_OUTPUT_BIT 1
+#define PLL_AUX2_OUTPUT_BIT 2
+
+#define PWR_ON_MASK		BIT(31)
+#define EN_REST_WAIT_MASK	(0xF << 20)
+#define EN_FEW_WAIT_MASK	(0xF << 16)
+#define CLK_DIS_WAIT_MASK	(0xF << 12)
+#define SW_OVERRIDE_MASK	BIT(2)
+#define HW_CONTROL_MASK		BIT(1)
+#define SW_COLLAPSE_MASK	BIT(0)
+
+/* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */
+#define EN_REST_WAIT_VAL	(0x2 << 20)
+#define EN_FEW_WAIT_VAL		(0x2 << 16)
+#define CLK_DIS_WAIT_VAL	(0x2 << 12)
+#define GDSC_TIMEOUT_US		50000
+
+#define PLL_OUTCTRL BIT(0)
+#define PLL_BYPASSNL BIT(1)
+#define PLL_RESET_N BIT(2)
+#define PLL_LOCKED_BIT BIT(16)
+#define ENABLE_WAIT_MAX_LOOPS 200
+
+static void __init reg_init(void)
+{
+	u32 regval;
+
+	if (!(readl_relaxed(GCC_REG_BASE(GPLL0_STATUS))
+			& gpll0.status_mask))
+		configure_sr_hpm_lp_pll(&gpll0_config, &gpll0_regs, 1);
+
+	if (!(readl_relaxed(GCC_REG_BASE(GPLL1_STATUS))
+			& gpll1.status_mask))
+		configure_sr_hpm_lp_pll(&gpll1_config, &gpll1_regs, 1);
+
+	configure_sr_hpm_lp_pll(&mmpll0_config, &mmpll0_regs, 1);
+	configure_sr_hpm_lp_pll(&mmpll1_config, &mmpll1_regs, 1);
+
+	/* Enable GPLL0's aux outputs. */
+	regval = readl_relaxed(GCC_REG_BASE(GPLL0_USER_CTL));
+	regval |= BIT(PLL_AUX_OUTPUT_BIT) | BIT(PLL_AUX2_OUTPUT_BIT);
+	writel_relaxed(regval, GCC_REG_BASE(GPLL0_USER_CTL));
+
+	/* Vote for GPLL0 to turn on. Needed by acpuclock. */
+	regval = readl_relaxed(GCC_REG_BASE(APCS_GPLL_ENA_VOTE));
+	regval |= BIT(0);
+	writel_relaxed(regval, GCC_REG_BASE(APCS_GPLL_ENA_VOTE));
+
+	/*
+	 * TODO: Confirm that no clocks need to be voted on in this sleep vote
+	 * register.
+	 */
+	writel_relaxed(0x0, GCC_REG_BASE(APCS_CLOCK_SLEEP_ENA_VOTE));
+}
+
+static void __init msm8226_clock_post_init(void)
+{
+
+	/* Set rates for single-rate clocks. */
+	clk_set_rate(&usb_hs_system_clk_src.c,
+			usb_hs_system_clk_src.freq_tbl[0].freq_hz);
+	clk_set_rate(&usb_hsic_clk_src.c,
+			usb_hsic_clk_src.freq_tbl[0].freq_hz);
+	clk_set_rate(&usb_hsic_io_cal_clk_src.c,
+			usb_hsic_io_cal_clk_src.freq_tbl[0].freq_hz);
+	clk_set_rate(&usb_hsic_system_clk_src.c,
+			usb_hsic_system_clk_src.freq_tbl[0].freq_hz);
+	clk_set_rate(&pdm2_clk_src.c, pdm2_clk_src.freq_tbl[0].freq_hz);
+	clk_set_rate(&cci_clk_src.c, cci_clk_src.freq_tbl[0].freq_hz);
+	clk_set_rate(&mclk0_clk_src.c, mclk0_clk_src.freq_tbl[0].freq_hz);
+	clk_set_rate(&mclk1_clk_src.c, mclk1_clk_src.freq_tbl[0].freq_hz);
+	clk_set_rate(&esc0_clk_src.c, esc0_clk_src.freq_tbl[0].freq_hz);
+	clk_set_rate(&vsync_clk_src.c, vsync_clk_src.freq_tbl[0].freq_hz);
+}
+
+#define GCC_CC_PHYS		0xFC400000
+#define GCC_CC_SIZE		SZ_16K
+
+#define MMSS_CC_PHYS		0xFD8C0000
+#define MMSS_CC_SIZE		SZ_256K
+
+#define LPASS_CC_PHYS		0xFE000000
+#define LPASS_CC_SIZE		SZ_256K
+
+#define APCS_KPSS_SH_PLL_PHYS	0xF9016000
+#define APCS_KPSS_SH_PLL_SIZE	SZ_64
+
+#define APCS_KPSS_GLB_PHYS	0xF9011000
+#define APCS_KPSS_GLB_SIZE	SZ_4K
+
+
+static void __init msm8226_clock_pre_init(void)
+{
+	virt_bases[GCC_BASE] = ioremap(GCC_CC_PHYS, GCC_CC_SIZE);
+	if (!virt_bases[GCC_BASE])
+		panic("clock-8226: Unable to ioremap GCC memory!");
+
+	virt_bases[MMSS_BASE] = ioremap(MMSS_CC_PHYS, MMSS_CC_SIZE);
+	if (!virt_bases[MMSS_BASE])
+		panic("clock-8226: Unable to ioremap MMSS_CC memory!");
+
+	virt_bases[LPASS_BASE] = ioremap(LPASS_CC_PHYS, LPASS_CC_SIZE);
+	if (!virt_bases[LPASS_BASE])
+		panic("clock-8226: Unable to ioremap LPASS_CC memory!");
+
+	virt_bases[APCS_BASE] = ioremap(APCS_KPSS_GLB_PHYS,
+		APCS_KPSS_GLB_SIZE);
+	if (!virt_bases[APCS_BASE])
+		panic("clock-8226: Unable to ioremap APCS_GCC_CC memory!");
+
+	virt_bases[APCS_PLL_BASE] = ioremap(APCS_KPSS_SH_PLL_PHYS,
+		APCS_KPSS_SH_PLL_SIZE);
+	if (!virt_bases[APCS_PLL_BASE])
+		panic("clock-8226: Unable to ioremap APCS_GCC_CC memory!");
+
+	clk_ops_local_pll.enable = sr_hpm_lp_pll_clk_enable;
+
+	vdd_dig_reg = regulator_get(NULL, "vdd_dig");
+	if (IS_ERR(vdd_dig_reg))
+		panic("clock-8226: Unable to get the vdd_dig regulator!");
+
+	vdd_sr2_reg = regulator_get(NULL, "vdd_sr2_pll");
+	if (IS_ERR(vdd_dig_reg))
+		panic("clock-8226: Unable to get the sr2_pll regulator!");
+
+	/*
+	 * The SR2 PLL is used at boot. Vote to prevent its regulator from
+	 * being turned off while the PLL is still in use.
+	 */
+	regulator_set_voltage(vdd_sr2_reg, 1800000, 1800000);
+	regulator_enable(vdd_sr2_reg);
+
+	/*
+	 * TODO: Set a voltage and enable vdd_dig, leaving the voltage high
+	 * until late_init. This may not be necessary with clock handoff;
+	 * Investigate this code on a real non-simulator target to determine
+	 * its necessity.
+	 */
+	vote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
+	regulator_enable(vdd_dig_reg);
+
+	/*
+	 * Hold an active set vote at a rate of 40MHz for the MMSS NOC AHB
+	 * source. Sleep set vote is 0.
+	 * RPM will also turn on gcc_mmss_noc_cfg_ahb_clk, which is needed to
+	 * access mmss clock controller registers.
+	 */
+	clk_set_rate(&mmssnoc_ahb_a_clk.c, 40000000);
+	clk_prepare_enable(&mmssnoc_ahb_a_clk.c);
+
+	/*
+	 * Hold an active set vote for CXO; this is because CXO is expected
+	 * to remain on whenever CPUs aren't power collapsed.
+	 */
+	clk_prepare_enable(&xo_a_clk.c);
+
+	enable_rpm_scaling();
+
+	reg_init();
+	/*
+	 * FIXME remove after bus driver is in place
+	 * Requires gpll0 to be configured
+	 */
+	clk_set_rate(&axi_clk_src.c, 200000000);
+	clk_prepare_enable(&mmss_s0_axi_clk.c);
+
+	/*
+	 * TODO: Enable the gcc_bimc_clk smcbc, which is the parent of thhe
+	 * mss_gcc_q6_bimc_axi_clk
+	 */
+	writel_relaxed(0x1, GCC_REG_BASE(0x1118));
+}
+
+static int __init msm8226_clock_late_init(void)
+{
+	return unvote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
+}
+
+struct clock_init_data msm8226_clock_init_data __initdata = {
+	.table = msm_clocks_8226,
+	.size = ARRAY_SIZE(msm_clocks_8226),
+	.pre_init = msm8226_clock_pre_init,
+	.post_init = msm8226_clock_post_init,
+	.late_init = msm8226_clock_late_init,
+};
diff --git a/arch/arm/mach-msm/clock-8610.c b/arch/arm/mach-msm/clock-8610.c
new file mode 100644
index 0000000..5690730
--- /dev/null
+++ b/arch/arm/mach-msm/clock-8610.c
@@ -0,0 +1,3566 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/ctype.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/iopoll.h>
+#include <linux/regulator/consumer.h>
+
+#include <mach/rpm-regulator-smd.h>
+#include <mach/socinfo.h>
+#include <mach/rpm-smd.h>
+
+#include "clock-local2.h"
+#include "clock-pll.h"
+#include "clock-rpm.h"
+#include "clock-voter.h"
+#include "clock.h"
+
+enum {
+	GCC_BASE,
+	MMSS_BASE,
+	LPASS_BASE,
+	APCS_BASE,
+	APCS_PLL_BASE,
+	N_BASES,
+};
+
+static void __iomem *virt_bases[N_BASES];
+
+#define GCC_REG_BASE(x) (void __iomem *)(virt_bases[GCC_BASE] + (x))
+#define MMSS_REG_BASE(x) (void __iomem *)(virt_bases[MMSS_BASE] + (x))
+#define LPASS_REG_BASE(x) (void __iomem *)(virt_bases[LPASS_BASE] + (x))
+#define APCS_REG_BASE(x) (void __iomem *)(virt_bases[APCS_BASE] + (x))
+
+#define                     GPLL0_MODE	    0x0000
+#define                    GPLL0_L_VAL	    0x0004
+#define                    GPLL0_M_VAL	    0x0008
+#define                    GPLL0_N_VAL	    0x000C
+#define                 GPLL0_USER_CTL	    0x0010
+#define                   GPLL0_STATUS	    0x001C
+#define                     GPLL2_MODE	    0x0080
+#define                    GPLL2_L_VAL	    0x0084
+#define                    GPLL2_M_VAL	    0x0088
+#define                    GPLL2_N_VAL	    0x008C
+#define                 GPLL2_USER_CTL	    0x0090
+#define                   GPLL2_STATUS	    0x009C
+#define                 CONFIG_NOC_BCR	    0x0140
+#define                       MMSS_BCR	    0x0240
+#define          MMSS_NOC_CFG_AHB_CBCR	    0x024C
+#define               MSS_CFG_AHB_CBCR	    0x0280
+#define           MSS_Q6_BIMC_AXI_CBCR	    0x0284
+#define                     USB_HS_BCR	    0x0480
+#define             USB_HS_SYSTEM_CBCR	    0x0484
+#define                USB_HS_AHB_CBCR	    0x0488
+#define         USB_HS_SYSTEM_CMD_RCGR	    0x0490
+#define                  USB2A_PHY_BCR	    0x04A8
+#define           USB2A_PHY_SLEEP_CBCR	    0x04AC
+#define                      SDCC1_BCR	    0x04C0
+#define            SDCC1_APPS_CMD_RCGR	    0x04D0
+#define                SDCC1_APPS_CBCR	    0x04C4
+#define                 SDCC1_AHB_CBCR	    0x04C8
+#define                      SDCC2_BCR	    0x0500
+#define            SDCC2_APPS_CMD_RCGR	    0x0510
+#define                SDCC2_APPS_CBCR	    0x0504
+#define                 SDCC2_AHB_CBCR	    0x0508
+#define                      BLSP1_BCR	    0x05C0
+#define                 BLSP1_AHB_CBCR	    0x05C4
+#define                 BLSP1_QUP1_BCR	    0x0640
+#define       BLSP1_QUP1_SPI_APPS_CBCR	    0x0644
+#define       BLSP1_QUP1_I2C_APPS_CBCR	    0x0648
+#define   BLSP1_QUP1_SPI_APPS_CMD_RCGR	    0x064C
+#define                BLSP1_UART1_BCR	    0x0680
+#define          BLSP1_UART1_APPS_CBCR	    0x0684
+#define           BLSP1_UART1_SIM_CBCR	    0x0688
+#define      BLSP1_UART1_APPS_CMD_RCGR	    0x068C
+#define                 BLSP1_QUP2_BCR	    0x06C0
+#define       BLSP1_QUP2_SPI_APPS_CBCR	    0x06C4
+#define       BLSP1_QUP2_I2C_APPS_CBCR	    0x06C8
+#define   BLSP1_QUP2_SPI_APPS_CMD_RCGR	    0x06CC
+#define                BLSP1_UART2_BCR	    0x0700
+#define          BLSP1_UART2_APPS_CBCR	    0x0704
+#define           BLSP1_UART2_SIM_CBCR	    0x0708
+#define      BLSP1_UART2_APPS_CMD_RCGR	    0x070C
+#define                 BLSP1_QUP3_BCR	    0x0740
+#define       BLSP1_QUP3_SPI_APPS_CBCR	    0x0744
+#define       BLSP1_QUP3_I2C_APPS_CBCR	    0x0748
+#define   BLSP1_QUP3_SPI_APPS_CMD_RCGR	    0x074C
+#define                BLSP1_UART3_BCR	    0x0780
+#define          BLSP1_UART3_APPS_CBCR	    0x0784
+#define           BLSP1_UART3_SIM_CBCR	    0x0788
+#define      BLSP1_UART3_APPS_CMD_RCGR	    0x078C
+#define                 BLSP1_QUP4_BCR	    0x07C0
+#define       BLSP1_QUP4_SPI_APPS_CBCR	    0x07C4
+#define       BLSP1_QUP4_I2C_APPS_CBCR	    0x07C8
+#define   BLSP1_QUP4_SPI_APPS_CMD_RCGR	    0x07CC
+#define                BLSP1_UART4_BCR	    0x0800
+#define          BLSP1_UART4_APPS_CBCR	    0x0804
+#define           BLSP1_UART4_SIM_CBCR	    0x0808
+#define      BLSP1_UART4_APPS_CMD_RCGR	    0x080C
+#define                 BLSP1_QUP5_BCR	    0x0840
+#define       BLSP1_QUP5_SPI_APPS_CBCR	    0x0844
+#define       BLSP1_QUP5_I2C_APPS_CBCR	    0x0848
+#define   BLSP1_QUP5_SPI_APPS_CMD_RCGR	    0x084C
+#define                BLSP1_UART5_BCR	    0x0880
+#define          BLSP1_UART5_APPS_CBCR	    0x0884
+#define           BLSP1_UART5_SIM_CBCR	    0x0888
+#define      BLSP1_UART5_APPS_CMD_RCGR	    0x088C
+#define                 BLSP1_QUP6_BCR	    0x08C0
+#define       BLSP1_QUP6_SPI_APPS_CBCR	    0x08C4
+#define       BLSP1_QUP6_I2C_APPS_CBCR	    0x08C8
+#define   BLSP1_QUP6_SPI_APPS_CMD_RCGR	    0x08CC
+#define                BLSP1_UART6_BCR	    0x0900
+#define          BLSP1_UART6_APPS_CBCR	    0x0904
+#define           BLSP1_UART6_SIM_CBCR	    0x0908
+#define      BLSP1_UART6_APPS_CMD_RCGR	    0x090C
+#define                        PDM_BCR	    0x0CC0
+#define                   PDM_AHB_CBCR	    0x0CC4
+#define                      PDM2_CBCR	    0x0CCC
+#define                  PDM2_CMD_RCGR	    0x0CD0
+#define                       PRNG_BCR	    0x0D00
+#define                  PRNG_AHB_CBCR	    0x0D04
+#define                   BOOT_ROM_BCR	    0x0E00
+#define              BOOT_ROM_AHB_CBCR	    0x0E04
+#define                        CE1_BCR	    0x1040
+#define                   CE1_CMD_RCGR	    0x1050
+#define                       CE1_CBCR	    0x1044
+#define                   CE1_AXI_CBCR	    0x1048
+#define                   CE1_AHB_CBCR	    0x104C
+#define            COPSS_SMMU_AHB_CBCR      0x015C
+#define             LPSS_SMMU_AHB_CBCR      0x0158
+#define              LPASS_Q6_AXI_CBCR	    0x11C0
+#define             APCS_GPLL_ENA_VOTE	    0x1480
+#define     APCS_CLOCK_BRANCH_ENA_VOTE	    0x1484
+#define      APCS_CLOCK_SLEEP_ENA_VOTE	    0x1488
+#define                       GP1_CBCR	    0x1900
+#define                   GP1_CMD_RCGR	    0x1904
+#define                       GP2_CBCR	    0x1940
+#define                   GP2_CMD_RCGR	    0x1944
+#define                       GP3_CBCR	    0x1980
+#define                   GP3_CMD_RCGR	    0x1984
+#define                        XO_CBCR	    0x0034
+
+#define                MMPLL0_PLL_MODE	    0x0000
+#define               MMPLL0_PLL_L_VAL	    0x0004
+#define               MMPLL0_PLL_M_VAL	    0x0008
+#define               MMPLL0_PLL_N_VAL	    0x000C
+#define            MMPLL0_PLL_USER_CTL	    0x0010
+#define              MMPLL0_PLL_STATUS	    0x001C
+#define         MMSS_PLL_VOTE_APCS_REG      0x0100
+#define                MMPLL1_PLL_MODE	    0x4100
+#define               MMPLL1_PLL_L_VAL	    0x4104
+#define               MMPLL1_PLL_M_VAL	    0x4108
+#define               MMPLL1_PLL_N_VAL	    0x410C
+#define            MMPLL1_PLL_USER_CTL	    0x4110
+#define              MMPLL1_PLL_STATUS	    0x411C
+#define              DSI_PCLK_CMD_RCGR	    0x2000
+#define                   DSI_CMD_RCGR	    0x2020
+#define             MDP_VSYNC_CMD_RCGR	    0x2080
+#define              DSI_BYTE_CMD_RCGR	    0x2120
+#define               DSI_ESC_CMD_RCGR	    0x2160
+#define                        DSI_BCR	    0x2200
+#define                   DSI_BYTE_BCR	    0x2204
+#define                    DSI_ESC_BCR	    0x2208
+#define                    DSI_AHB_BCR	    0x220C
+#define                   DSI_PCLK_BCR	    0x2214
+#define                   MDP_LCDC_BCR	    0x2218
+#define                    MDP_DSI_BCR	    0x221C
+#define                  MDP_VSYNC_BCR	    0x2220
+#define                    MDP_AXI_BCR	    0x2224
+#define                    MDP_AHB_BCR	    0x2228
+#define                   MDP_AXI_CBCR	    0x2314
+#define                 MDP_VSYNC_CBCR	    0x231C
+#define                   MDP_AHB_CBCR	    0x2318
+#define                  DSI_PCLK_CBCR	    0x233C
+#define                GMEM_GFX3D_CBCR      0x4038
+#define                  MDP_LCDC_CBCR	    0x2340
+#define                   MDP_DSI_CBCR	    0x2320
+#define                       DSI_CBCR	    0x2324
+#define                  DSI_BYTE_CBCR	    0x2328
+#define                   DSI_ESC_CBCR	    0x232C
+#define                   DSI_AHB_CBCR	    0x2330
+#define          CSI0PHYTIMER_CMD_RCGR	    0x3000
+#define               CSI0PHYTIMER_BCR	    0x3020
+#define              CSI0PHYTIMER_CBCR	    0x3024
+#define          CSI1PHYTIMER_CMD_RCGR	    0x3030
+#define               CSI1PHYTIMER_BCR	    0x3050
+#define              CSI1PHYTIMER_CBCR	    0x3054
+#define                  CSI0_CMD_RCGR	    0x3090
+#define                       CSI0_BCR	    0x30B0
+#define                      CSI0_CBCR	    0x30B4
+#define                    CSI_AHB_BCR	    0x30B8
+#define                   CSI_AHB_CBCR	    0x30BC
+#define                    CSI0PHY_BCR	    0x30C0
+#define                   CSI0PHY_CBCR	    0x30C4
+#define                    CSI0RDI_BCR	    0x30D0
+#define                   CSI0RDI_CBCR	    0x30D4
+#define                    CSI0PIX_BCR	    0x30E0
+#define                   CSI0PIX_CBCR	    0x30E4
+#define                  CSI1_CMD_RCGR	    0x3100
+#define                       CSI1_BCR	    0x3120
+#define                      CSI1_CBCR	    0x3124
+#define                    CSI1PHY_BCR	    0x3130
+#define                   CSI1PHY_CBCR	    0x3134
+#define                    CSI1RDI_BCR	    0x3140
+#define                   CSI1RDI_CBCR	    0x3144
+#define                    CSI1PIX_BCR	    0x3150
+#define                   CSI1PIX_CBCR	    0x3154
+#define                 MCLK0_CMD_RCGR	    0x3360
+#define                      MCLK0_BCR	    0x3380
+#define                     MCLK0_CBCR	    0x3384
+#define                 MCLK1_CMD_RCGR	    0x3390
+#define                      MCLK1_BCR	    0x33B0
+#define                     MCLK1_CBCR	    0x33B4
+#define                   VFE_CMD_RCGR	    0x3600
+#define                        VFE_BCR	    0x36A0
+#define                    VFE_AHB_BCR	    0x36AC
+#define                    VFE_AXI_BCR	    0x36B0
+#define                       VFE_CBCR	    0x36A8
+#define                   VFE_AHB_CBCR	    0x36B8
+#define                   VFE_AXI_CBCR	    0x36BC
+#define                    CSI_VFE_BCR	    0x3700
+#define                   CSI_VFE_CBCR	    0x3704
+#define                 GFX3D_CMD_RCGR	    0x4000
+#define               OXILI_GFX3D_CBCR	    0x4028
+#define                OXILI_GFX3D_BCR	    0x4030
+#define                  OXILI_AHB_BCR	    0x4044
+#define                 OXILI_AHB_CBCR	    0x403C
+#define                   AHB_CMD_RCGR	    0x5000
+#define                 MMSSNOCAHB_BCR	    0x5020
+#define             MMSSNOCAHB_BTO_BCR	    0x5030
+#define              MMSS_MISC_AHB_BCR	    0x5034
+#define          MMSS_MMSSNOC_AHB_CBCR	    0x5024
+#define      MMSS_MMSSNOC_BTO_AHB_CBCR	    0x5028
+#define             MMSS_MISC_AHB_CBCR	    0x502C
+#define                   AXI_CMD_RCGR	    0x5040
+#define                 MMSSNOCAXI_BCR	    0x5060
+#define                MMSS_S0_AXI_BCR	    0x5068
+#define               MMSS_S0_AXI_CBCR	    0x5064
+#define          MMSS_MMSSNOC_AXI_CBCR	    0x506C
+#define                   BIMC_GFX_BCR	    0x5090
+#define                  BIMC_GFX_CBCR	    0x5094
+
+#define				AUDIO_CORE_GDSCR	    0x7000
+#define                                 SPDM_BCR	    0x1000
+#define                        LPAAUDIO_PLL_MODE	    0x0000
+#define                       LPAAUDIO_PLL_L_VAL	    0x0004
+#define                       LPAAUDIO_PLL_M_VAL	    0x0008
+#define                       LPAAUDIO_PLL_N_VAL	    0x000C
+#define                    LPAAUDIO_PLL_USER_CTL	    0x0010
+#define                      LPAAUDIO_PLL_STATUS	    0x001C
+#define                           LPAQ6_PLL_MODE	    0x1000
+#define                       LPAQ6_PLL_USER_CTL	    0x1010
+#define                         LPAQ6_PLL_STATUS	    0x101C
+#define                        LPA_PLL_VOTE_APPS            0x2000
+#define                  AUDIO_CORE_BCR_SLP_CBCR	    0x4004
+#define                        Q6SS_BCR_SLP_CBCR	    0x6004
+#define                  AUDIO_CORE_GDSC_XO_CBCR	    0x7004
+#define                AUDIO_CORE_LPAIF_DMA_CBCR	    0x9000
+#define                AUDIO_CORE_LPAIF_CSR_CBCR	    0x9004
+#define                      LPAIF_SPKR_CMD_RCGR	    0xA000
+#define     AUDIO_CORE_LPAIF_CODEC_SPKR_OSR_CBCR	    0xA014
+#define    AUDIO_CORE_LPAIF_CODEC_SPKR_IBIT_CBCR	    0xA018
+#define    AUDIO_CORE_LPAIF_CODEC_SPKR_EBIT_CBCR	    0xA01C
+#define                       LPAIF_PRI_CMD_RCGR	    0xB000
+#define            AUDIO_CORE_LPAIF_PRI_OSR_CBCR	    0xB014
+#define           AUDIO_CORE_LPAIF_PRI_IBIT_CBCR	    0xB018
+#define           AUDIO_CORE_LPAIF_PRI_EBIT_CBCR	    0xB01C
+#define                       LPAIF_SEC_CMD_RCGR	    0xC000
+#define            AUDIO_CORE_LPAIF_SEC_OSR_CBCR	    0xC014
+#define           AUDIO_CORE_LPAIF_SEC_IBIT_CBCR	    0xC018
+#define           AUDIO_CORE_LPAIF_SEC_EBIT_CBCR	    0xC01C
+#define                       LPAIF_TER_CMD_RCGR	    0xD000
+#define            AUDIO_CORE_LPAIF_TER_OSR_CBCR	    0xD014
+#define           AUDIO_CORE_LPAIF_TER_IBIT_CBCR	    0xD018
+#define           AUDIO_CORE_LPAIF_TER_EBIT_CBCR	    0xD01C
+#define                      LPAIF_QUAD_CMD_RCGR	    0xE000
+#define           AUDIO_CORE_LPAIF_QUAD_OSR_CBCR	    0xE014
+#define          AUDIO_CORE_LPAIF_QUAD_IBIT_CBCR	    0xE018
+#define          AUDIO_CORE_LPAIF_QUAD_EBIT_CBCR	    0xE01C
+#define                      LPAIF_PCM0_CMD_RCGR	    0xF000
+#define          AUDIO_CORE_LPAIF_PCM0_IBIT_CBCR	    0xF014
+#define          AUDIO_CORE_LPAIF_PCM0_EBIT_CBCR	    0xF018
+#define                      LPAIF_PCM1_CMD_RCGR	   0x10000
+#define          AUDIO_CORE_LPAIF_PCM1_IBIT_CBCR	   0x10014
+#define          AUDIO_CORE_LPAIF_PCM1_EBIT_CBCR	   0x10018
+#define                         SLIMBUS_CMD_RCGR           0x12000
+#define             AUDIO_CORE_SLIMBUS_CORE_CBCR           0x12014
+#define                     LPAIF_PCMOE_CMD_RCGR	   0x13000
+#define        AUDIO_CORE_LPAIF_PCM_DATA_OE_CBCR	   0x13014
+#define                          Q6CORE_CMD_RCGR	   0x14000
+#define                           SLEEP_CMD_RCGR	   0x15000
+#define                            SPDM_CMD_RCGR	   0x16000
+#define                  AUDIO_WRAPPER_SPDM_CBCR	   0x16014
+#define                              XO_CMD_RCGR	   0x17000
+#define                       AHBFABRIC_CMD_RCGR	   0x18000
+#define                      AUDIO_CORE_LPM_CBCR	   0x19000
+#define               AUDIO_CORE_AVSYNC_CSR_CBCR	   0x1A000
+#define                AUDIO_CORE_AVSYNC_XO_CBCR	   0x1A004
+#define             AUDIO_CORE_AVSYNC_BT_XO_CBCR	   0x1A008
+#define             AUDIO_CORE_AVSYNC_FM_XO_CBCR	   0x1A00C
+#define                 AUDIO_CORE_IXFABRIC_CBCR	   0x1B000
+#define               AUDIO_WRAPPER_EFABRIC_CBCR	   0x1B004
+#define                AUDIO_CORE_TCM_SLAVE_CBCR	   0x1C000
+#define                      AUDIO_CORE_CSR_CBCR	   0x1D000
+#define                      AUDIO_CORE_DML_CBCR	   0x1E000
+#define                   AUDIO_CORE_SYSNOC_CBCR	   0x1F000
+#define           AUDIO_WRAPPER_SYSNOC_SWAY_CBCR	   0x1F004
+#define                  AUDIO_CORE_TIMEOUT_CBCR	   0x20000
+#define               AUDIO_WRAPPER_TIMEOUT_CBCR	   0x20004
+#define                 AUDIO_CORE_SECURITY_CBCR	   0x21000
+#define              AUDIO_WRAPPER_SECURITY_CBCR	   0x21004
+#define                     Q6SS_AHB_LFABIF_CBCR	   0x22000
+#define                           Q6SS_AHBM_CBCR	   0x22004
+#define               AUDIO_WRAPPER_LCC_CSR_CBCR	   0x23000
+#define                    AUDIO_WRAPPER_BR_CBCR	   0x24000
+#define                  AUDIO_WRAPPER_SMEM_CBCR	   0x25000
+#define                             Q6SS_XO_CBCR	   0x26000
+#define                            Q6SS_SLP_CBCR	   0x26004
+#define                           LPASS_Q6SS_BCR           0x6000
+#define                AUDIO_WRAPPER_STM_XO_CBCR	   0x27000
+#define      AUDIO_CORE_IXFABRIC_SPDMTM_CSR_CBCR	   0x28000
+#define    AUDIO_WRAPPER_EFABRIC_SPDMTM_CSR_CBCR	   0x28004
+
+/* Mux source select values */
+#define        gcc_xo_source_val 0
+#define         gpll0_source_val 1
+#define           gnd_source_val 5
+#define     mmpll0_mm_source_val 1
+#define     mmpll1_mm_source_val 2
+#define      gpll0_mm_source_val 5
+#define     gcc_xo_mm_source_val 0
+#define        mm_gnd_source_val 6
+#define     cxo_lpass_source_val 0
+#define lpapll0_lpass_source_val 1
+#define   gpll0_lpass_source_val 5
+#define     dsipll_mm_source_val 1
+
+#define F(f, s, div, m, n) \
+	{ \
+		.freq_hz = (f), \
+		.src_clk = &s##_clk_src.c, \
+		.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##_source_val), \
+	}
+
+#define F_APCS_PLL(f, l, m, n, pre_div, post_div, vco) \
+	{ \
+		.freq_hz = (f), \
+		.l_val = (l), \
+		.m_val = (m), \
+		.n_val = (n), \
+		.pre_div_val = BVAL(12, 12, (pre_div)), \
+		.post_div_val = BVAL(9, 8, (post_div)), \
+		.vco_val = BVAL(29, 28, (vco)), \
+	}
+
+#define F_MM(f, s, div, m, n) \
+	{ \
+		.freq_hz = (f), \
+		.src_clk = &s##_clk_src.c, \
+		.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_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_MDSS(f, s, div, m, n) \
+	{ \
+		.freq_hz = (f), \
+		.m_val = (m), \
+		.n_val = ~((n)-(m)) * !!(n), \
+		.d_val = ~(n),\
+		.div_src_val = BVAL(4, 0, (int)(2*(div) - 1)) \
+			| BVAL(10, 8, s##_mm_source_val), \
+	}
+
+#define F_LPASS(f, s, div, m, n) \
+	{ \
+		.freq_hz = (f), \
+		.src_clk = &s##_clk_src.c, \
+		.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##_lpass_source_val), \
+	}
+
+#define VDD_DIG_FMAX_MAP1(l1, f1) \
+	.vdd_class = &vdd_dig,			\
+	.fmax = (unsigned long[VDD_DIG_NUM]) {	\
+		[VDD_DIG_##l1] = (f1),		\
+	},					\
+	.num_fmax = VDD_DIG_NUM
+#define VDD_DIG_FMAX_MAP2(l1, f1, l2, f2) \
+	.vdd_class = &vdd_dig,			\
+	.fmax = (unsigned long[VDD_DIG_NUM]) {	\
+		[VDD_DIG_##l1] = (f1),		\
+		[VDD_DIG_##l2] = (f2),		\
+	},					\
+	.num_fmax = VDD_DIG_NUM
+#define VDD_DIG_FMAX_MAP3(l1, f1, l2, f2, l3, f3) \
+	.vdd_class = &vdd_dig,			\
+	.fmax = (unsigned long[VDD_DIG_NUM]) {	\
+		[VDD_DIG_##l1] = (f1),		\
+		[VDD_DIG_##l2] = (f2),		\
+		[VDD_DIG_##l3] = (f3),		\
+	},					\
+	.num_fmax = VDD_DIG_NUM
+
+enum vdd_dig_levels {
+	VDD_DIG_NONE,
+	VDD_DIG_LOW,
+	VDD_DIG_NOMINAL,
+	VDD_DIG_HIGH,
+	VDD_DIG_NUM
+};
+
+static const int vdd_corner[] = {
+	[VDD_DIG_NONE]	  = RPM_REGULATOR_CORNER_NONE,
+	[VDD_DIG_LOW]	  = RPM_REGULATOR_CORNER_SVS_SOC,
+	[VDD_DIG_NOMINAL] = RPM_REGULATOR_CORNER_NORMAL,
+	[VDD_DIG_HIGH]	  = RPM_REGULATOR_CORNER_SUPER_TURBO,
+};
+
+static struct regulator *vdd_dig_reg;
+
+static int set_vdd_dig(struct clk_vdd_class *vdd_class, int level)
+{
+	return regulator_set_voltage(vdd_dig_reg, vdd_corner[level],
+					RPM_REGULATOR_CORNER_SUPER_TURBO);
+}
+
+static DEFINE_VDD_CLASS(vdd_dig, set_vdd_dig, VDD_DIG_NUM);
+
+#define RPM_MISC_CLK_TYPE	0x306b6c63
+#define RPM_BUS_CLK_TYPE	0x316b6c63
+#define RPM_MEM_CLK_TYPE	0x326b6c63
+
+#define RPM_SMD_KEY_ENABLE	0x62616E45
+
+#define CXO_ID			0x0
+#define QDSS_ID			0x1
+#define RPM_SCALING_ENABLE_ID	0x2
+
+#define PNOC_ID		0x0
+#define SNOC_ID		0x1
+#define CNOC_ID		0x2
+#define MMSSNOC_AHB_ID  0x3
+
+#define BIMC_ID		0x0
+#define OXILI_ID	0x1
+#define OCMEM_ID	0x2
+
+#define D0_ID		 1
+#define D1_ID		 2
+#define A0_ID		 3
+#define A1_ID		 4
+#define A2_ID		 5
+#define DIFF_CLK_ID	 7
+#define DIV_CLK_ID	11
+
+DEFINE_CLK_RPM_SMD(pnoc_clk, pnoc_a_clk, RPM_BUS_CLK_TYPE, PNOC_ID, NULL);
+DEFINE_CLK_RPM_SMD(snoc_clk, snoc_a_clk, RPM_BUS_CLK_TYPE, SNOC_ID, NULL);
+DEFINE_CLK_RPM_SMD(cnoc_clk, cnoc_a_clk, RPM_BUS_CLK_TYPE, CNOC_ID, NULL);
+DEFINE_CLK_RPM_SMD(mmssnoc_ahb_clk, mmssnoc_ahb_a_clk, RPM_BUS_CLK_TYPE,
+			MMSSNOC_AHB_ID, NULL);
+
+DEFINE_CLK_RPM_SMD(bimc_clk, bimc_a_clk, RPM_MEM_CLK_TYPE, BIMC_ID, NULL);
+
+DEFINE_CLK_RPM_SMD_BRANCH(gcc_xo_clk_src, gcc_xo_a_clk_src,
+				RPM_MISC_CLK_TYPE, CXO_ID, 19200000);
+DEFINE_CLK_RPM_SMD_QDSS(qdss_clk, qdss_a_clk, RPM_MISC_CLK_TYPE, QDSS_ID);
+
+DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_d0, cxo_d0_a, D0_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_d1, cxo_d1_a, D1_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_a0, cxo_a0_a, A0_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_a1, cxo_a1_a, A1_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_a2, cxo_a2_a, A2_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(div_clk, div_a_clk, DIV_CLK_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(diff_clk, diff_a_clk, DIFF_CLK_ID);
+
+DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_d0_pin, cxo_d0_a_pin, D0_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_d1_pin, cxo_d1_a_pin, D1_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_a0_pin, cxo_a0_a_pin, A0_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_a1_pin, cxo_a1_a_pin, A1_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_a2_pin, cxo_a2_a_pin, A2_ID);
+
+static DEFINE_CLK_VOTER(pnoc_msmbus_clk, &pnoc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(snoc_msmbus_clk, &snoc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(cnoc_msmbus_clk, &cnoc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(pnoc_msmbus_a_clk, &pnoc_a_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(snoc_msmbus_a_clk, &snoc_a_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(cnoc_msmbus_a_clk, &cnoc_a_clk.c, LONG_MAX);
+
+static DEFINE_CLK_VOTER(bimc_msmbus_clk, &bimc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(bimc_msmbus_a_clk, &bimc_a_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(bimc_acpu_a_clk, &bimc_a_clk.c, LONG_MAX);
+
+static DEFINE_CLK_VOTER(pnoc_sps_clk, &pnoc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(pnoc_iommu_clk, &pnoc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(pnoc_qseecom_clk, &pnoc_clk.c, LONG_MAX);
+
+static DEFINE_CLK_MEASURE(apc0_m_clk);
+static DEFINE_CLK_MEASURE(apc1_m_clk);
+static DEFINE_CLK_MEASURE(apc2_m_clk);
+static DEFINE_CLK_MEASURE(apc3_m_clk);
+static DEFINE_CLK_MEASURE(l2_m_clk);
+
+#define APCS_SH_PLL_MODE        0x000
+#define APCS_SH_PLL_L_VAL       0x004
+#define APCS_SH_PLL_M_VAL       0x008
+#define APCS_SH_PLL_N_VAL       0x00C
+#define APCS_SH_PLL_USER_CTL    0x010
+#define APCS_SH_PLL_CONFIG_CTL  0x014
+#define APCS_SH_PLL_STATUS      0x01C
+
+enum vdd_sr2_pll_levels {
+	VDD_SR2_PLL_OFF,
+	VDD_SR2_PLL_ON,
+	VDD_SR2_PLL_NUM
+};
+
+static struct regulator *vdd_sr2_reg;
+
+static int set_vdd_sr2_pll(struct clk_vdd_class *vdd_class, int level)
+{
+	if (level == VDD_SR2_PLL_ON) {
+		return regulator_set_voltage(vdd_sr2_reg, 1800000,
+		1800000);
+	} else {
+		return regulator_set_voltage(vdd_sr2_reg, 0, 1800000);
+	}
+}
+
+static DEFINE_VDD_CLASS(vdd_sr2_pll, set_vdd_sr2_pll,
+			VDD_SR2_PLL_NUM);
+
+static struct pll_freq_tbl apcs_pll_freq[] = {
+	F_APCS_PLL( 384000000, 20, 0x0, 0x1, 0x0, 0x0, 0x0),
+	F_APCS_PLL( 787200000, 41, 0x0, 0x1, 0x0, 0x0, 0x0),
+	F_APCS_PLL( 998400000, 52, 0x0, 0x1, 0x0, 0x0, 0x0),
+	F_APCS_PLL(1190400000, 62, 0x0, 0x1, 0x0, 0x0, 0x0),
+	PLL_F_END
+};
+
+static struct pll_clk a7sspll = {
+	.mode_reg = (void __iomem *)APCS_SH_PLL_MODE,
+	.l_reg = (void __iomem *)APCS_SH_PLL_L_VAL,
+	.m_reg = (void __iomem *)APCS_SH_PLL_M_VAL,
+	.n_reg = (void __iomem *)APCS_SH_PLL_N_VAL,
+	.config_reg = (void __iomem *)APCS_SH_PLL_USER_CTL,
+	.status_reg = (void __iomem *)APCS_SH_PLL_STATUS,
+	.freq_tbl = apcs_pll_freq,
+	.masks = {
+		.vco_mask = BM(29, 28),
+		.pre_div_mask = BIT(12),
+		.post_div_mask = BM(9, 8),
+		.mn_en_mask = BIT(24),
+		.main_output_mask = BIT(0),
+	},
+	.base = &virt_bases[APCS_PLL_BASE],
+	.c = {
+		.dbg_name = "a7sspll",
+		.ops = &clk_ops_sr2_pll,
+		.vdd_class = &vdd_sr2_pll,
+		.fmax = (unsigned long [VDD_SR2_PLL_NUM]) {
+			[VDD_SR2_PLL_ON] = ULONG_MAX,
+		},
+		.num_fmax = VDD_SR2_PLL_NUM,
+		CLK_INIT(a7sspll.c),
+		/*
+		 * Need to skip handoff of the acpu pll to avoid
+		 * turning off the pll when the cpu is using it
+		 */
+		.flags = CLKFLAG_SKIP_HANDOFF,
+	},
+};
+
+static unsigned int soft_vote_gpll0;
+
+static struct pll_vote_clk gpll0_clk_src = {
+	.en_reg = (void __iomem *)APCS_GPLL_ENA_VOTE,
+	.en_mask = BIT(0),
+	.status_reg = (void __iomem *)GPLL0_STATUS,
+	.status_mask = BIT(17),
+	.soft_vote = &soft_vote_gpll0,
+	.soft_vote_mask = PLL_SOFT_VOTE_PRIMARY,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.parent = &gcc_xo_clk_src.c,
+		.rate = 600000000,
+		.dbg_name = "gpll0_clk_src",
+		.ops = &clk_ops_pll_acpu_vote,
+		CLK_INIT(gpll0_clk_src.c),
+	},
+};
+
+static struct pll_vote_clk gpll0_ao_clk_src = {
+	.en_reg = (void __iomem *)APCS_GPLL_ENA_VOTE,
+	.en_mask = BIT(0),
+	.status_reg = (void __iomem *)GPLL0_STATUS,
+	.status_mask = BIT(17),
+	.soft_vote = &soft_vote_gpll0,
+	.soft_vote_mask = PLL_SOFT_VOTE_ACPU,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.rate = 600000000,
+		.dbg_name = "gpll0_ao_clk_src",
+		.ops = &clk_ops_pll_acpu_vote,
+		CLK_INIT(gpll0_ao_clk_src.c),
+	},
+};
+
+static struct pll_vote_clk mmpll0_clk_src = {
+	.en_reg = (void __iomem *)MMSS_PLL_VOTE_APCS_REG,
+	.en_mask = BIT(0),
+	.status_reg = (void __iomem *)MMPLL0_PLL_STATUS,
+	.status_mask = BIT(17),
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.parent = &gcc_xo_clk_src.c,
+		.dbg_name = "mmpll0_clk_src",
+		.rate = 800000000,
+		.ops = &clk_ops_pll_vote,
+		CLK_INIT(mmpll0_clk_src.c),
+	},
+};
+
+static struct pll_config_regs mmpll0_regs __initdata = {
+	.l_reg = (void __iomem *)MMPLL0_PLL_L_VAL,
+	.m_reg = (void __iomem *)MMPLL0_PLL_M_VAL,
+	.n_reg = (void __iomem *)MMPLL0_PLL_N_VAL,
+	.config_reg = (void __iomem *)MMPLL0_PLL_USER_CTL,
+	.mode_reg = (void __iomem *)MMPLL0_PLL_MODE,
+	.base = &virt_bases[MMSS_BASE],
+};
+
+static struct pll_clk mmpll1_clk_src = {
+	.mode_reg = (void __iomem *)MMPLL1_PLL_MODE,
+	.status_reg = (void __iomem *)MMPLL1_PLL_STATUS,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.parent = &gcc_xo_clk_src.c,
+		.dbg_name = "mmpll1_clk_src",
+		.rate = 1200000000,
+		.ops = &clk_ops_local_pll,
+		CLK_INIT(mmpll1_clk_src.c),
+	},
+};
+
+static struct pll_config_regs mmpll1_regs __initdata = {
+	.l_reg = (void __iomem *)MMPLL1_PLL_L_VAL,
+	.m_reg = (void __iomem *)MMPLL1_PLL_M_VAL,
+	.n_reg = (void __iomem *)MMPLL1_PLL_N_VAL,
+	.config_reg = (void __iomem *)MMPLL1_PLL_USER_CTL,
+	.mode_reg = (void __iomem *)MMPLL1_PLL_MODE,
+	.base = &virt_bases[MMSS_BASE],
+};
+
+static struct pll_vote_clk lpapll0_clk_src = {
+	.en_reg = (void __iomem *)LPA_PLL_VOTE_APPS,
+	.en_mask = BIT(0),
+	.status_reg = (void __iomem *)LPAAUDIO_PLL_STATUS,
+	.status_mask = BIT(17),
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.parent = &gcc_xo_clk_src.c,
+		.rate = 491520000,
+		.dbg_name = "lpapll0_clk_src",
+		.ops = &clk_ops_pll_vote,
+		CLK_INIT(lpapll0_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_blsp1_qup1_6_spi_apps_clk[] = {
+	F(  960000, gcc_xo, 10, 1, 2),
+	F( 4800000, gcc_xo,  4, 0, 0),
+	F( 9600000, gcc_xo,  2, 0, 0),
+	F(15000000,  gpll0, 10, 1, 4),
+	F(19200000, gcc_xo,  1, 0, 0),
+	F(25000000,  gpll0, 12, 1, 2),
+	F(50000000,  gpll0, 12, 0, 0),
+	F_END,
+};
+
+static struct rcg_clk blsp1_qup1_spi_apps_clk_src = {
+	.cmd_rcgr_reg =  BLSP1_QUP1_SPI_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup1_spi_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+		CLK_INIT(blsp1_qup1_spi_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup2_spi_apps_clk_src = {
+	.cmd_rcgr_reg =  BLSP1_QUP2_SPI_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup2_spi_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+		CLK_INIT(blsp1_qup2_spi_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup3_spi_apps_clk_src = {
+	.cmd_rcgr_reg =  BLSP1_QUP3_SPI_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup3_spi_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+		CLK_INIT(blsp1_qup3_spi_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup4_spi_apps_clk_src = {
+	.cmd_rcgr_reg =  BLSP1_QUP4_SPI_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup4_spi_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+		CLK_INIT(blsp1_qup4_spi_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup5_spi_apps_clk_src = {
+	.cmd_rcgr_reg =  BLSP1_QUP5_SPI_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup5_spi_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+		CLK_INIT(blsp1_qup5_spi_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup6_spi_apps_clk_src = {
+	.cmd_rcgr_reg =  BLSP1_QUP6_SPI_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup6_spi_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+		CLK_INIT(blsp1_qup6_spi_apps_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_blsp1_uart1_6_apps_clk[] = {
+	F( 3686400,  gpll0,    1,   96, 15625),
+	F( 7372800,  gpll0,    1,  192, 15625),
+	F(14745600,  gpll0,    1,  384, 15625),
+	F(16000000,  gpll0,    5,    2,    15),
+	F(19200000, gcc_xo,    1,    0,     0),
+	F(24000000,  gpll0,    5,    1,     5),
+	F(32000000,  gpll0,    1,    4,    75),
+	F(40000000,  gpll0,   15,    0,     0),
+	F(46400000,  gpll0,    1,   29,   375),
+	F(48000000,  gpll0, 12.5,    0,     0),
+	F(51200000,  gpll0,    1,   32,   375),
+	F(56000000,  gpll0,    1,    7,    75),
+	F(58982400,  gpll0,    1, 1536, 15625),
+	F(60000000,  gpll0,   10,    0,     0),
+	F_END,
+};
+
+static struct rcg_clk blsp1_uart1_apps_clk_src = {
+	.cmd_rcgr_reg =  BLSP1_UART1_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_uart1_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+		CLK_INIT(blsp1_uart1_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_uart2_apps_clk_src = {
+	.cmd_rcgr_reg =  BLSP1_UART2_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_uart2_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+		CLK_INIT(blsp1_uart2_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_uart3_apps_clk_src = {
+	.cmd_rcgr_reg =  BLSP1_UART3_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_uart3_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+		CLK_INIT(blsp1_uart3_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_uart4_apps_clk_src = {
+	.cmd_rcgr_reg =  BLSP1_UART4_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_uart4_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+		CLK_INIT(blsp1_uart4_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_uart5_apps_clk_src = {
+	.cmd_rcgr_reg =  BLSP1_UART5_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_uart5_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+		CLK_INIT(blsp1_uart5_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_uart6_apps_clk_src = {
+	.cmd_rcgr_reg =  BLSP1_UART6_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_uart6_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+		CLK_INIT(blsp1_uart6_apps_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_ce1_clk[] = {
+	F(50000000, gpll0, 12, 0, 0),
+	F(100000000, gpll0, 6, 0, 0),
+	F_END,
+};
+
+static struct rcg_clk ce1_clk_src = {
+	.cmd_rcgr_reg = CE1_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_ce1_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "ce1_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP2(LOW, 50000000, NOMINAL, 100000000),
+		CLK_INIT(ce1_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_gp1_3_clk[] = {
+	F(19200000, gcc_xo, 1, 0, 0),
+	F_END,
+};
+
+static struct rcg_clk gp1_clk_src = {
+	.cmd_rcgr_reg =  GP1_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_gp1_3_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gp1_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+		CLK_INIT(gp1_clk_src.c),
+	},
+};
+
+static struct rcg_clk gp2_clk_src = {
+	.cmd_rcgr_reg =  GP2_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_gp1_3_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gp2_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+		CLK_INIT(gp2_clk_src.c),
+	},
+};
+
+static struct rcg_clk gp3_clk_src = {
+	.cmd_rcgr_reg =  GP3_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_gp1_3_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gp3_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+		CLK_INIT(gp3_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_pdm2_clk[] = {
+	F(60000000, gpll0, 10, 0, 0),
+	F_END,
+};
+
+static struct rcg_clk pdm2_clk_src = {
+	.cmd_rcgr_reg = PDM2_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_pdm2_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "pdm2_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 120000000),
+		CLK_INIT(pdm2_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_sdcc1_2_apps_clk[] = {
+	F(   144000, gcc_xo, 16, 3, 25),
+	F(   400000, gcc_xo, 12, 1,  4),
+	F( 20000000,  gpll0, 15, 1,  2),
+	F( 25000000,  gpll0, 12, 1,  2),
+	F( 50000000,  gpll0, 12, 0,  0),
+	F(100000000,  gpll0,  6, 0,  0),
+	F(200000000,  gpll0,  3, 0,  0),
+	F_END,
+};
+
+static struct rcg_clk sdcc1_apps_clk_src = {
+	.cmd_rcgr_reg =  SDCC1_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_sdcc1_2_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "sdcc1_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+		CLK_INIT(sdcc1_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk sdcc2_apps_clk_src = {
+	.cmd_rcgr_reg =  SDCC2_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_sdcc1_2_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "sdcc2_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+		CLK_INIT(sdcc2_apps_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_usb_hs_system_clk[] = {
+	F(75000000, gpll0, 8, 0, 0),
+	F_END,
+};
+
+static struct rcg_clk usb_hs_system_clk_src = {
+	.cmd_rcgr_reg = USB_HS_SYSTEM_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_usb_hs_system_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "usb_hs_system_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP2(LOW, 60000000, NOMINAL, 100000000),
+		CLK_INIT(usb_hs_system_clk_src.c),
+	},
+};
+
+static struct local_vote_clk gcc_blsp1_ahb_clk = {
+	.cbcr_reg = BLSP1_AHB_CBCR,
+	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask = BIT(17),
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_ahb_clk",
+		.ops = &clk_ops_vote,
+		CLK_INIT(gcc_blsp1_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup1_i2c_apps_clk = {
+	.cbcr_reg = BLSP1_QUP1_I2C_APPS_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.parent = &gcc_xo_clk_src.c,
+		.dbg_name = "gcc_blsp1_qup1_i2c_apps_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup1_i2c_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup1_spi_apps_clk = {
+	.cbcr_reg = BLSP1_QUP1_SPI_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.parent = &blsp1_qup1_spi_apps_clk_src.c,
+		.dbg_name = "gcc_blsp1_qup1_spi_apps_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup1_spi_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup2_i2c_apps_clk = {
+	.cbcr_reg = BLSP1_QUP2_I2C_APPS_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.parent = &gcc_xo_clk_src.c,
+		.dbg_name = "gcc_blsp1_qup2_i2c_apps_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup2_i2c_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup2_spi_apps_clk = {
+	.cbcr_reg = BLSP1_QUP2_SPI_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.parent = &blsp1_qup2_spi_apps_clk_src.c,
+		.dbg_name = "gcc_blsp1_qup2_spi_apps_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup2_spi_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup3_i2c_apps_clk = {
+	.cbcr_reg = BLSP1_QUP3_I2C_APPS_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.parent = &gcc_xo_clk_src.c,
+		.dbg_name = "gcc_blsp1_qup3_i2c_apps_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup3_i2c_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup3_spi_apps_clk = {
+	.cbcr_reg = BLSP1_QUP3_SPI_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.parent = &blsp1_qup3_spi_apps_clk_src.c,
+		.dbg_name = "gcc_blsp1_qup3_spi_apps_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup3_spi_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup4_i2c_apps_clk = {
+	.cbcr_reg = BLSP1_QUP4_I2C_APPS_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.parent = &gcc_xo_clk_src.c,
+		.dbg_name = "gcc_blsp1_qup4_i2c_apps_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup4_i2c_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup4_spi_apps_clk = {
+	.cbcr_reg = BLSP1_QUP4_SPI_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.parent = &blsp1_qup4_spi_apps_clk_src.c,
+		.dbg_name = "gcc_blsp1_qup4_spi_apps_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup4_spi_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup5_i2c_apps_clk = {
+	.cbcr_reg = BLSP1_QUP5_I2C_APPS_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.parent = &gcc_xo_clk_src.c,
+		.dbg_name = "gcc_blsp1_qup5_i2c_apps_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup5_i2c_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup5_spi_apps_clk = {
+	.cbcr_reg = BLSP1_QUP5_SPI_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.parent = &blsp1_qup5_spi_apps_clk_src.c,
+		.dbg_name = "gcc_blsp1_qup5_spi_apps_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup5_spi_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup6_i2c_apps_clk = {
+	.cbcr_reg = BLSP1_QUP6_I2C_APPS_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.parent = &gcc_xo_clk_src.c,
+		.dbg_name = "gcc_blsp1_qup6_i2c_apps_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup6_i2c_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup6_spi_apps_clk = {
+	.cbcr_reg = BLSP1_QUP6_SPI_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.parent = &blsp1_qup6_spi_apps_clk_src.c,
+		.dbg_name = "gcc_blsp1_qup6_spi_apps_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup6_spi_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_uart1_apps_clk = {
+	.cbcr_reg = BLSP1_UART1_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.parent = &blsp1_uart1_apps_clk_src.c,
+		.dbg_name = "gcc_blsp1_uart1_apps_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_uart1_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_uart2_apps_clk = {
+	.cbcr_reg = BLSP1_UART2_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.parent = &blsp1_uart2_apps_clk_src.c,
+		.dbg_name = "gcc_blsp1_uart2_apps_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_uart2_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_uart3_apps_clk = {
+	.cbcr_reg = BLSP1_UART3_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.parent = &blsp1_uart3_apps_clk_src.c,
+		.dbg_name = "gcc_blsp1_uart3_apps_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_uart3_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_uart4_apps_clk = {
+	.cbcr_reg = BLSP1_UART4_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.parent = &blsp1_uart4_apps_clk_src.c,
+		.dbg_name = "gcc_blsp1_uart4_apps_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_uart4_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_uart5_apps_clk = {
+	.cbcr_reg = BLSP1_UART5_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.parent = &blsp1_uart5_apps_clk_src.c,
+		.dbg_name = "gcc_blsp1_uart5_apps_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_uart5_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_uart6_apps_clk = {
+	.cbcr_reg = BLSP1_UART6_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.parent = &blsp1_uart6_apps_clk_src.c,
+		.dbg_name = "gcc_blsp1_uart6_apps_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_uart6_apps_clk.c),
+	},
+};
+
+static struct local_vote_clk gcc_boot_rom_ahb_clk = {
+	.cbcr_reg = BOOT_ROM_AHB_CBCR,
+	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask = BIT(10),
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_boot_rom_ahb_clk",
+		.ops = &clk_ops_vote,
+		CLK_INIT(gcc_boot_rom_ahb_clk.c),
+	},
+};
+
+static struct local_vote_clk gcc_ce1_ahb_clk = {
+	.cbcr_reg = CE1_AHB_CBCR,
+	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask = BIT(3),
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_ce1_ahb_clk",
+		.ops = &clk_ops_vote,
+		CLK_INIT(gcc_ce1_ahb_clk.c),
+	},
+};
+
+static struct local_vote_clk gcc_ce1_axi_clk = {
+	.cbcr_reg = CE1_AXI_CBCR,
+	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask = BIT(4),
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_ce1_axi_clk",
+		.ops = &clk_ops_vote,
+		CLK_INIT(gcc_ce1_axi_clk.c),
+	},
+};
+
+static struct local_vote_clk gcc_ce1_clk = {
+	.cbcr_reg = CE1_CBCR,
+	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask = BIT(5),
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_ce1_clk",
+		.ops = &clk_ops_vote,
+		CLK_INIT(gcc_ce1_clk.c),
+	},
+};
+
+static struct branch_clk gcc_copss_smmu_ahb_clk = {
+	.cbcr_reg = COPSS_SMMU_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_copss_smmu_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_copss_smmu_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_lpss_smmu_ahb_clk = {
+	.cbcr_reg = LPSS_SMMU_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+			.dbg_name = "gcc_lpss_smmu_ahb_clk",
+			.ops = &clk_ops_branch,
+			CLK_INIT(gcc_lpss_smmu_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_gp1_clk = {
+	.cbcr_reg = GP1_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.parent = &gp1_clk_src.c,
+		.dbg_name = "gcc_gp1_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_gp1_clk.c),
+	},
+};
+
+static struct branch_clk gcc_gp2_clk = {
+	.cbcr_reg = GP2_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.parent = &gp2_clk_src.c,
+		.dbg_name = "gcc_gp2_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_gp2_clk.c),
+	},
+};
+
+static struct branch_clk gcc_gp3_clk = {
+	.cbcr_reg = GP3_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.parent = &gp3_clk_src.c,
+		.dbg_name = "gcc_gp3_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_gp3_clk.c),
+	},
+};
+
+static struct branch_clk gcc_lpass_q6_axi_clk = {
+	.cbcr_reg = LPASS_Q6_AXI_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	 /* FIXME: Remove this once simulation is fixed. */
+	.halt_check = DELAY,
+	.c = {
+		.dbg_name = "gcc_lpass_q6_axi_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_lpass_q6_axi_clk.c),
+	},
+};
+
+static struct branch_clk gcc_mmss_noc_cfg_ahb_clk = {
+	.cbcr_reg = MMSS_NOC_CFG_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_mmss_noc_cfg_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_mmss_noc_cfg_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_mss_cfg_ahb_clk = {
+	.cbcr_reg = MSS_CFG_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_mss_cfg_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_mss_cfg_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_mss_q6_bimc_axi_clk = {
+	.cbcr_reg = MSS_Q6_BIMC_AXI_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_mss_q6_bimc_axi_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_mss_q6_bimc_axi_clk.c),
+	},
+};
+
+static struct branch_clk gcc_pdm2_clk = {
+	.cbcr_reg = PDM2_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.parent = &pdm2_clk_src.c,
+		.dbg_name = "gcc_pdm2_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_pdm2_clk.c),
+	},
+};
+
+static struct branch_clk gcc_pdm_ahb_clk = {
+	.cbcr_reg = PDM_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_pdm_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_pdm_ahb_clk.c),
+	},
+};
+
+static struct local_vote_clk gcc_prng_ahb_clk = {
+	.cbcr_reg = PRNG_AHB_CBCR,
+	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask = BIT(13),
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_prng_ahb_clk",
+		.ops = &clk_ops_vote,
+		CLK_INIT(gcc_prng_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_sdcc1_ahb_clk = {
+	.cbcr_reg = SDCC1_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_sdcc1_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_sdcc1_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_sdcc1_apps_clk = {
+	.cbcr_reg = SDCC1_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.parent = &sdcc1_apps_clk_src.c,
+		.dbg_name = "gcc_sdcc1_apps_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_sdcc1_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_sdcc2_ahb_clk = {
+	.cbcr_reg = SDCC2_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_sdcc2_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_sdcc2_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_sdcc2_apps_clk = {
+	.cbcr_reg = SDCC2_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.parent = &sdcc2_apps_clk_src.c,
+		.dbg_name = "gcc_sdcc2_apps_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_sdcc2_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_usb2a_phy_sleep_clk = {
+	.cbcr_reg = USB2A_PHY_SLEEP_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_usb2a_phy_sleep_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_usb2a_phy_sleep_clk.c),
+	},
+};
+
+static struct branch_clk gcc_usb_hs_ahb_clk = {
+	.cbcr_reg = USB_HS_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_usb_hs_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_usb_hs_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_usb_hs_system_clk = {
+	.cbcr_reg = USB_HS_SYSTEM_CBCR,
+	.has_sibling = 0,
+	.bcr_reg = USB_HS_BCR,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.parent = &usb_hs_system_clk_src.c,
+		.dbg_name = "gcc_usb_hs_system_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_usb_hs_system_clk.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_csi0_1_clk[] = {
+	F_MM(100000000,  gpll0, 6, 0, 0),
+	F_MM(200000000, mmpll0, 4, 0, 0),
+	F_END,
+};
+
+static struct rcg_clk csi0_clk_src = {
+	.cmd_rcgr_reg = CSI0_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_csi0_1_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "csi0_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+		CLK_INIT(csi0_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_mmss_mmssnoc_axi_clk[] = {
+	F_MM( 19200000, gcc_xo,  1, 0, 0),
+	F_MM( 37500000,  gpll0, 16, 0, 0),
+	F_MM( 50000000,  gpll0, 12, 0, 0),
+	F_MM( 75000000,  gpll0,  8, 0, 0),
+	F_MM(100000000,  gpll0,  6, 0, 0),
+	F_MM(150000000,  gpll0,  4, 0, 0),
+	F_MM(200000000, mmpll0,  4, 0, 0),
+	F_END,
+};
+
+static struct rcg_clk axi_clk_src = {
+	.cmd_rcgr_reg = AXI_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_mmss_mmssnoc_axi_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "axi_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+		CLK_INIT(axi_clk_src.c),
+	},
+};
+
+static DEFINE_CLK_VOTER(mdp_axi_clk_src, &axi_clk_src.c, 200000000);
+static DEFINE_CLK_VOTER(mmssnoc_axi_clk_src, &axi_clk_src.c, 200000000);
+
+static struct clk_freq_tbl ftbl_dsi_pclk_clk[] = {
+	F_MDSS( 50000000, dsipll, 10, 0, 0),
+	F_MDSS(103330000, dsipll,  9, 0, 0),
+	F_END,
+};
+
+static struct rcg_clk dsi_pclk_clk_src = {
+	.cmd_rcgr_reg =  DSI_PCLK_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_dsi_pclk_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "dsi_pclk_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 50000000, NOMINAL, 103330000),
+		CLK_INIT(dsi_pclk_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_oxili_gfx3d_clk[] = {
+	F_MM( 19200000, gcc_xo,  1, 0, 0),
+	F_MM( 37500000,  gpll0, 16, 0, 0),
+	F_MM( 50000000,  gpll0, 12, 0, 0),
+	F_MM( 75000000,  gpll0,  8, 0, 0),
+	F_MM(100000000,  gpll0,  6, 0, 0),
+	F_MM(150000000,  gpll0,  4, 0, 0),
+	F_MM(200000000,  gpll0,  3, 0, 0),
+	F_MM(300000000,  gpll0,  2, 0, 0),
+	F_MM(400000000, mmpll1,  3, 0, 0),
+	F_END,
+};
+
+static struct rcg_clk gfx3d_clk_src = {
+	.cmd_rcgr_reg = GFX3D_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_oxili_gfx3d_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "gfx3d_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP3(LOW, 150000000, NOMINAL, 300000000, HIGH,
+					400000000),
+		CLK_INIT(gfx3d_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_vfe_clk[] = {
+	F_MM( 37500000,  gpll0,  16, 0, 0),
+	F_MM( 50000000,  gpll0,  12, 0, 0),
+	F_MM( 60000000,  gpll0,  10, 0, 0),
+	F_MM( 80000000,  gpll0, 7.5, 0, 0),
+	F_MM(100000000,  gpll0,   6, 0, 0),
+	F_MM(109090000,  gpll0, 5.5, 0, 0),
+	F_MM(133330000,  gpll0, 4.5, 0, 0),
+	F_MM(200000000,  gpll0,   3, 0, 0),
+	F_MM(228570000, mmpll0, 3.5, 0, 0),
+	F_MM(266670000, mmpll0,   3, 0, 0),
+	F_MM(320000000, mmpll0, 2.5, 0, 0),
+	F_END,
+};
+
+static struct rcg_clk vfe_clk_src = {
+	.cmd_rcgr_reg = VFE_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_vfe_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "vfe_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP3(LOW, 133330000, NOMINAL, 266670000, HIGH,
+					320000000),
+		CLK_INIT(vfe_clk_src.c),
+	},
+};
+
+static struct rcg_clk csi1_clk_src = {
+	.cmd_rcgr_reg = CSI1_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_csi0_1_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "csi1_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+		CLK_INIT(csi1_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_csi0_1phytimer_clk[] = {
+	F_MM(100000000,  gpll0, 6, 0, 0),
+	F_MM(200000000, mmpll0, 4, 0, 0),
+	F_END,
+};
+
+static struct rcg_clk csi0phytimer_clk_src = {
+	.cmd_rcgr_reg = CSI0PHYTIMER_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_csi0_1phytimer_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "csi0phytimer_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+		CLK_INIT(csi0phytimer_clk_src.c),
+	},
+};
+
+static struct rcg_clk csi1phytimer_clk_src = {
+	.cmd_rcgr_reg = CSI1PHYTIMER_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_csi0_1phytimer_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "csi1phytimer_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+		CLK_INIT(csi1phytimer_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_dsi_clk[] = {
+	F_MDSS(155000000,  dsipll, 6, 0, 0),
+	F_MDSS(310000000,  dsipll, 3, 0, 0),
+	F_END,
+};
+
+static struct rcg_clk dsi_clk_src = {
+	.cmd_rcgr_reg =  DSI_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_dsi_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "dsi_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 155000000, NOMINAL, 310000000),
+		CLK_INIT(dsi_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_dsi_byte_clk[] = {
+	F_MDSS( 62500000, dsipll, 12, 0, 0),
+	F_MDSS(125000000, dsipll,  6, 0, 0),
+	F_END,
+};
+
+static struct rcg_clk dsi_byte_clk_src = {
+	.cmd_rcgr_reg = DSI_BYTE_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_dsi_byte_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "dsi_byte_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP2(LOW, 62500000, NOMINAL, 125000000),
+		CLK_INIT(dsi_byte_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_dsi_esc_clk[] = {
+	F_MM(19200000, gcc_xo, 1, 0, 0),
+	F_END,
+};
+
+static struct rcg_clk dsi_esc_clk_src = {
+	.cmd_rcgr_reg = DSI_ESC_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_dsi_esc_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "dsi_esc_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 19200000),
+		CLK_INIT(dsi_esc_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_mclk0_1_clk[] = {
+	F_MM(66670000, gpll0, 9, 0, 0),
+	F_END,
+};
+
+static struct rcg_clk mclk0_clk_src = {
+	.cmd_rcgr_reg =  MCLK0_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_mclk0_1_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "mclk0_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP1(LOW, 66670000),
+		CLK_INIT(mclk0_clk_src.c),
+	},
+};
+
+static struct rcg_clk mclk1_clk_src = {
+	.cmd_rcgr_reg =  MCLK1_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_mclk0_1_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "mclk1_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP1(LOW, 66670000),
+		CLK_INIT(mclk1_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_mdp_vsync_clk[] = {
+	F_MM(19200000, gcc_xo, 1, 0, 0),
+	F_END,
+};
+
+static struct rcg_clk mdp_vsync_clk_src = {
+	.cmd_rcgr_reg = MDP_VSYNC_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_mdp_vsync_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "mdp_vsync_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 19200000),
+		CLK_INIT(mdp_vsync_clk_src.c),
+	},
+};
+
+static struct branch_clk bimc_gfx_clk = {
+	.cbcr_reg = BIMC_GFX_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	 /* FIXME: Remove this once simulation is fixed. */
+	.halt_check = DELAY,
+	.c = {
+		.dbg_name = "bimc_gfx_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(bimc_gfx_clk.c),
+	},
+};
+
+static struct branch_clk csi0_clk = {
+	.cbcr_reg = CSI0_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.parent = &csi0_clk_src.c,
+		.dbg_name = "csi0_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(csi0_clk.c),
+	},
+};
+
+static struct branch_clk csi0phy_clk = {
+	.cbcr_reg = CSI0PHY_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.parent = &csi0_clk_src.c,
+		.dbg_name = "csi0phy_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(csi0phy_clk.c),
+	},
+};
+
+static struct branch_clk csi0phytimer_clk = {
+	.cbcr_reg = CSI0PHYTIMER_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.parent = &csi0phytimer_clk_src.c,
+		.dbg_name = "csi0phytimer_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(csi0phytimer_clk.c),
+	},
+};
+
+static struct branch_clk csi0pix_clk = {
+	.cbcr_reg = CSI0PIX_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.parent = &csi0_clk_src.c,
+		.dbg_name = "csi0pix_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(csi0pix_clk.c),
+	},
+};
+
+static struct branch_clk csi0rdi_clk = {
+	.cbcr_reg = CSI0RDI_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.parent = &csi0_clk_src.c,
+		.dbg_name = "csi0rdi_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(csi0rdi_clk.c),
+	},
+};
+
+static struct branch_clk csi1_clk = {
+	.cbcr_reg = CSI1_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.parent = &csi1_clk_src.c,
+		.dbg_name = "csi1_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(csi1_clk.c),
+	},
+};
+
+static struct branch_clk csi1phy_clk = {
+	.cbcr_reg = CSI1PHY_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.parent = &csi1_clk_src.c,
+		.dbg_name = "csi1phy_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(csi1phy_clk.c),
+	},
+};
+
+static struct branch_clk csi1phytimer_clk = {
+	.cbcr_reg = CSI1PHYTIMER_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.parent = &csi1phytimer_clk_src.c,
+		.dbg_name = "csi1phytimer_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(csi1phytimer_clk.c),
+	},
+};
+
+static struct branch_clk csi1pix_clk = {
+	.cbcr_reg = CSI1PIX_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.parent = &csi1_clk_src.c,
+		.dbg_name = "csi1pix_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(csi1pix_clk.c),
+	},
+};
+
+static struct branch_clk csi1rdi_clk = {
+	.cbcr_reg = CSI1RDI_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.parent = &csi1_clk_src.c,
+		.dbg_name = "csi1rdi_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(csi1rdi_clk.c),
+	},
+};
+
+static struct branch_clk csi_ahb_clk = {
+	.cbcr_reg = CSI_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "csi_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(csi_ahb_clk.c),
+	},
+};
+
+static struct branch_clk csi_vfe_clk = {
+	.cbcr_reg = CSI_VFE_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.parent = &vfe_clk_src.c,
+		.dbg_name = "csi_vfe_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(csi_vfe_clk.c),
+	},
+};
+
+static struct branch_clk dsi_clk = {
+	.cbcr_reg = DSI_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.parent = &dsi_clk_src.c,
+		.dbg_name = "dsi_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(dsi_clk.c),
+	},
+};
+
+static struct branch_clk dsi_ahb_clk = {
+	.cbcr_reg = DSI_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "dsi_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(dsi_ahb_clk.c),
+	},
+};
+
+static struct branch_clk dsi_byte_clk = {
+	.cbcr_reg = DSI_BYTE_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.parent = &dsi_byte_clk_src.c,
+		.dbg_name = "dsi_byte_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(dsi_byte_clk.c),
+	},
+};
+
+static struct branch_clk dsi_esc_clk = {
+	.cbcr_reg = DSI_ESC_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.parent = &dsi_esc_clk_src.c,
+		.dbg_name = "dsi_esc_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(dsi_esc_clk.c),
+	},
+};
+
+static struct branch_clk dsi_pclk_clk = {
+	.cbcr_reg = DSI_PCLK_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.parent = &dsi_pclk_clk_src.c,
+		.dbg_name = "dsi_pclk_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(dsi_pclk_clk.c),
+	},
+};
+
+static struct branch_clk gmem_gfx3d_clk = {
+	.cbcr_reg = GMEM_GFX3D_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.parent = &gfx3d_clk_src.c,
+		.dbg_name = "gmem_gfx3d_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gmem_gfx3d_clk.c),
+	},
+};
+
+static struct branch_clk mclk0_clk = {
+	.cbcr_reg = MCLK0_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.parent = &mclk0_clk_src.c,
+		.dbg_name = "mclk0_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(mclk0_clk.c),
+	},
+};
+
+static struct branch_clk mclk1_clk = {
+	.cbcr_reg = MCLK1_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.parent = &mclk1_clk_src.c,
+		.dbg_name = "mclk1_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(mclk1_clk.c),
+	},
+};
+
+static struct branch_clk mdp_ahb_clk = {
+	.cbcr_reg = MDP_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "mdp_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(mdp_ahb_clk.c),
+	},
+};
+
+static struct branch_clk mdp_axi_clk = {
+	.cbcr_reg = MDP_AXI_CBCR,
+	.base = &virt_bases[MMSS_BASE],
+	 /* FIXME: Remove this once simulation is fixed. */
+	.halt_check = DELAY,
+	.c = {
+		.parent = &mdp_axi_clk_src.c,
+		.dbg_name = "mdp_axi_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(mdp_axi_clk.c),
+	},
+};
+
+static struct branch_clk mdp_dsi_clk = {
+	.cbcr_reg = MDP_DSI_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.parent = &dsi_pclk_clk_src.c,
+		.dbg_name = "mdp_dsi_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(mdp_dsi_clk.c),
+	},
+};
+
+static struct branch_clk mdp_lcdc_clk = {
+	.cbcr_reg = MDP_LCDC_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.parent = &dsi_pclk_clk_src.c,
+		.dbg_name = "mdp_lcdc_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(mdp_lcdc_clk.c),
+	},
+};
+
+static struct branch_clk mdp_vsync_clk = {
+	.cbcr_reg = MDP_VSYNC_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.parent = &mdp_vsync_clk_src.c,
+		.dbg_name = "mdp_vsync_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(mdp_vsync_clk.c),
+	},
+};
+
+static struct branch_clk mmss_misc_ahb_clk = {
+	.cbcr_reg = MMSS_MISC_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "mmss_misc_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(mmss_misc_ahb_clk.c),
+	},
+};
+
+static struct branch_clk mmss_mmssnoc_axi_clk = {
+	.cbcr_reg = MMSS_MMSSNOC_AXI_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.parent = &axi_clk_src.c,
+		.dbg_name = "mmss_mmssnoc_axi_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(mmss_mmssnoc_axi_clk.c),
+	},
+};
+
+static struct branch_clk mmss_s0_axi_clk = {
+	.cbcr_reg = MMSS_S0_AXI_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.parent = &mmssnoc_axi_clk_src.c,
+		.dbg_name = "mmss_s0_axi_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(mmss_s0_axi_clk.c),
+		.depends = &mmss_mmssnoc_axi_clk.c,
+	},
+};
+
+static struct branch_clk mmss_mmssnoc_bto_ahb_clk = {
+	.cbcr_reg = MMSS_MMSSNOC_BTO_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "mmss_mmssnoc_bto_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(mmss_mmssnoc_bto_ahb_clk.c),
+	},
+};
+
+static struct branch_clk oxili_ahb_clk = {
+	.cbcr_reg = OXILI_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "oxili_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(oxili_ahb_clk.c),
+	},
+};
+
+static struct branch_clk oxili_gfx3d_clk = {
+	.cbcr_reg = OXILI_GFX3D_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.parent = &gfx3d_clk_src.c,
+		.dbg_name = "oxili_gfx3d_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(oxili_gfx3d_clk.c),
+	},
+};
+
+static struct branch_clk vfe_clk = {
+	.cbcr_reg = VFE_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.parent = &vfe_clk_src.c,
+		.dbg_name = "vfe_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(vfe_clk.c),
+	},
+};
+
+static struct branch_clk vfe_ahb_clk = {
+	.cbcr_reg = VFE_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	.c = {
+		.dbg_name = "vfe_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(vfe_ahb_clk.c),
+	},
+};
+
+static struct branch_clk vfe_axi_clk = {
+	.cbcr_reg = VFE_AXI_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[MMSS_BASE],
+	 /* FIXME: Remove this once simulation is fixed. */
+	.halt_check = DELAY,
+	.c = {
+		.parent = &axi_clk_src.c,
+		.dbg_name = "vfe_axi_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(vfe_axi_clk.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_audio_core_lpaif_clk[] = {
+	F_LPASS(  512000, lpapll0, 16, 1, 60),
+	F_LPASS(  768000, lpapll0, 16, 1, 40),
+	F_LPASS( 1024000, lpapll0, 16, 1, 30),
+	F_LPASS( 1536000, lpapll0, 16, 1, 20),
+	F_LPASS( 2048000, lpapll0, 16, 1, 15),
+	F_LPASS( 3072000, lpapll0, 16, 1, 10),
+	F_LPASS( 4096000, lpapll0, 15, 1,  8),
+	F_LPASS( 6144000, lpapll0, 10, 1,  8),
+	F_LPASS( 8192000, lpapll0, 15, 1,  4),
+	F_LPASS(12288000, lpapll0, 10, 1,  4),
+	F_END,
+};
+
+static struct rcg_clk lpaif_pri_clk_src = {
+	.cmd_rcgr_reg =  LPAIF_PRI_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_audio_core_lpaif_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "lpaif_pri_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 12290000, NOMINAL, 24580000),
+		CLK_INIT(lpaif_pri_clk_src.c),
+	},
+};
+
+static struct rcg_clk lpaif_quad_clk_src = {
+	.cmd_rcgr_reg =  LPAIF_QUAD_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_audio_core_lpaif_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "lpaif_quad_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 12290000, NOMINAL, 24580000),
+		CLK_INIT(lpaif_quad_clk_src.c),
+	},
+};
+
+static struct rcg_clk lpaif_sec_clk_src = {
+	.cmd_rcgr_reg =  LPAIF_SEC_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_audio_core_lpaif_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "lpaif_sec_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 12290000, NOMINAL, 24580000),
+		CLK_INIT(lpaif_sec_clk_src.c),
+	},
+};
+
+static struct rcg_clk lpaif_spkr_clk_src = {
+	.cmd_rcgr_reg =  LPAIF_SPKR_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_audio_core_lpaif_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "lpaif_spkr_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 12290000, NOMINAL, 24580000),
+		CLK_INIT(lpaif_spkr_clk_src.c),
+	},
+};
+
+static struct rcg_clk lpaif_ter_clk_src = {
+	.cmd_rcgr_reg =  LPAIF_TER_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_audio_core_lpaif_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "lpaif_ter_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 12290000, NOMINAL, 24580000),
+		CLK_INIT(lpaif_ter_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_audio_core_lpaif_pcm0_1_clk[] = {
+	F_LPASS( 512000, lpapll0, 16, 1, 60),
+	F_LPASS( 768000, lpapll0, 16, 1, 40),
+	F_LPASS(1024000, lpapll0, 16, 1, 30),
+	F_LPASS(1536000, lpapll0, 16, 1, 20),
+	F_LPASS(2048000, lpapll0, 16, 1, 15),
+	F_LPASS(3072000, lpapll0, 16, 1, 10),
+	F_LPASS(4096000, lpapll0, 15, 1,  8),
+	F_LPASS(6144000, lpapll0, 10, 1,  8),
+	F_LPASS(8192000, lpapll0, 15, 1,  4),
+	F_END,
+};
+
+static struct rcg_clk lpaif_pcm0_clk_src = {
+	.cmd_rcgr_reg =  LPAIF_PCM0_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_audio_core_lpaif_pcm0_1_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "lpaif_pcm0_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 4100000, NOMINAL, 8192000),
+		CLK_INIT(lpaif_pcm0_clk_src.c),
+	},
+};
+
+static struct rcg_clk lpaif_pcm1_clk_src = {
+	.cmd_rcgr_reg =  LPAIF_PCM1_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_audio_core_lpaif_pcm0_1_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "lpaif_pcm1_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 4100000, NOMINAL, 8192000),
+		CLK_INIT(lpaif_pcm1_clk_src.c),
+	},
+};
+
+static struct rcg_clk lpaif_pcmoe_clk_src = {
+	.cmd_rcgr_reg =  LPAIF_PCMOE_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_audio_core_lpaif_pcm0_1_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "lpaif_pcmoe_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 6140000, NOMINAL, 12290000),
+		CLK_INIT(lpaif_pcmoe_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_audio_core_slimbus_core_clock[] = {
+	F_LPASS(24576000, lpapll0, 4, 1, 5),
+	F_END
+};
+
+static struct rcg_clk audio_core_slimbus_core_clk_src = {
+	.cmd_rcgr_reg = SLIMBUS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_audio_core_slimbus_core_clock,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "audio_core_slimbus_core_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 12935000, NOMINAL, 25869000),
+		CLK_INIT(audio_core_slimbus_core_clk_src.c),
+	},
+};
+
+static struct branch_clk audio_core_slimbus_core_clk = {
+	.cbcr_reg = AUDIO_CORE_SLIMBUS_CORE_CBCR,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.parent = &audio_core_slimbus_core_clk_src.c,
+		.dbg_name = "audio_core_slimbus_core_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(audio_core_slimbus_core_clk.c),
+	},
+};
+
+static struct branch_clk audio_core_ixfabric_clk = {
+	.cbcr_reg = AUDIO_CORE_IXFABRIC_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "audio_core_ixfabric_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(audio_core_ixfabric_clk.c),
+	},
+};
+
+static struct branch_clk audio_wrapper_br_clk = {
+	.cbcr_reg = AUDIO_WRAPPER_BR_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "audio_wrapper_br_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(audio_wrapper_br_clk.c),
+	},
+};
+
+static struct branch_clk q6ss_ahb_lfabif_clk = {
+	.cbcr_reg = Q6SS_AHB_LFABIF_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "q6ss_ahb_lfabif_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(q6ss_ahb_lfabif_clk.c),
+	},
+};
+
+static struct branch_clk q6ss_ahbm_clk = {
+	.cbcr_reg = Q6SS_AHBM_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "q6ss_ahbm_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(q6ss_ahbm_clk.c),
+	},
+};
+
+static struct branch_clk q6ss_xo_clk = {
+	.cbcr_reg = Q6SS_XO_CBCR,
+	.has_sibling = 1,
+	.bcr_reg = LPASS_Q6SS_BCR,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.parent = &gcc_xo_clk_src.c,
+		.dbg_name = "q6ss_xo_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(q6ss_xo_clk.c),
+	},
+};
+
+static struct branch_clk audio_core_lpaif_pcm_data_oe_clk = {
+	.cbcr_reg = AUDIO_CORE_LPAIF_PCM_DATA_OE_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.parent = &lpaif_pcmoe_clk_src.c,
+		.dbg_name = "audio_core_lpaif_pcm_data_oe_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(audio_core_lpaif_pcm_data_oe_clk.c),
+	},
+};
+
+static struct branch_clk audio_core_lpaif_pri_ebit_clk = {
+	.cbcr_reg = AUDIO_CORE_LPAIF_PRI_EBIT_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "audio_core_lpaif_pri_ebit_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(audio_core_lpaif_pri_ebit_clk.c),
+	},
+};
+
+static struct branch_clk audio_core_lpaif_pri_ibit_clk = {
+	.cbcr_reg = AUDIO_CORE_LPAIF_PRI_IBIT_CBCR,
+	.has_sibling = 0,
+	.max_div = 511,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.parent = &lpaif_pri_clk_src.c,
+		.dbg_name = "audio_core_lpaif_pri_ibit_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(audio_core_lpaif_pri_ibit_clk.c),
+	},
+};
+
+static struct branch_clk audio_core_lpaif_pri_osr_clk = {
+	.cbcr_reg = AUDIO_CORE_LPAIF_PRI_OSR_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.parent = &lpaif_pri_clk_src.c,
+		.dbg_name = "audio_core_lpaif_pri_osr_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(audio_core_lpaif_pri_osr_clk.c),
+	},
+};
+
+static struct branch_clk audio_core_lpaif_pcm0_ebit_clk = {
+	.cbcr_reg = AUDIO_CORE_LPAIF_PCM0_EBIT_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "audio_core_lpaif_pcm0_ebit_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(audio_core_lpaif_pcm0_ebit_clk.c),
+	},
+};
+
+static struct branch_clk audio_core_lpaif_pcm0_ibit_clk = {
+	.cbcr_reg = AUDIO_CORE_LPAIF_PCM0_IBIT_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.parent = &lpaif_pcm0_clk_src.c,
+		.dbg_name = "audio_core_lpaif_pcm0_ibit_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(audio_core_lpaif_pcm0_ibit_clk.c),
+	},
+};
+
+static struct branch_clk audio_core_lpaif_quad_ebit_clk = {
+	.cbcr_reg = AUDIO_CORE_LPAIF_QUAD_EBIT_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "audio_core_lpaif_quad_ebit_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(audio_core_lpaif_quad_ebit_clk.c),
+	},
+};
+
+static struct branch_clk audio_core_lpaif_quad_ibit_clk = {
+	.cbcr_reg = AUDIO_CORE_LPAIF_QUAD_IBIT_CBCR,
+	.has_sibling = 0,
+	.max_div = 511,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.parent = &lpaif_quad_clk_src.c,
+		.dbg_name = "audio_core_lpaif_quad_ibit_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(audio_core_lpaif_quad_ibit_clk.c),
+	},
+};
+
+static struct branch_clk audio_core_lpaif_quad_osr_clk = {
+	.cbcr_reg = AUDIO_CORE_LPAIF_QUAD_OSR_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.parent = &lpaif_quad_clk_src.c,
+		.dbg_name = "audio_core_lpaif_quad_osr_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(audio_core_lpaif_quad_osr_clk.c),
+	},
+};
+
+static struct branch_clk audio_core_lpaif_sec_ebit_clk = {
+	.cbcr_reg = AUDIO_CORE_LPAIF_SEC_EBIT_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "audio_core_lpaif_sec_ebit_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(audio_core_lpaif_sec_ebit_clk.c),
+	},
+};
+
+static struct branch_clk audio_core_lpaif_sec_ibit_clk = {
+	.cbcr_reg = AUDIO_CORE_LPAIF_SEC_IBIT_CBCR,
+	.has_sibling = 0,
+	.max_div = 511,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.parent = &lpaif_sec_clk_src.c,
+		.dbg_name = "audio_core_lpaif_sec_ibit_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(audio_core_lpaif_sec_ibit_clk.c),
+	},
+};
+
+static struct branch_clk audio_core_lpaif_sec_osr_clk = {
+	.cbcr_reg = AUDIO_CORE_LPAIF_SEC_OSR_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.parent = &lpaif_sec_clk_src.c,
+		.dbg_name = "audio_core_lpaif_sec_osr_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(audio_core_lpaif_sec_osr_clk.c),
+	},
+};
+
+static struct branch_clk audio_core_lpaif_pcm1_ebit_clk = {
+	.cbcr_reg = AUDIO_CORE_LPAIF_PCM1_EBIT_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "audio_core_lpaif_pcm1_ebit_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(audio_core_lpaif_pcm1_ebit_clk.c),
+	},
+};
+
+static struct branch_clk audio_core_lpaif_pcm1_ibit_clk = {
+	.cbcr_reg = AUDIO_CORE_LPAIF_PCM1_IBIT_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.parent = &lpaif_pcm1_clk_src.c,
+		.dbg_name = "audio_core_lpaif_pcm1_ibit_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(audio_core_lpaif_pcm1_ibit_clk.c),
+	},
+};
+
+static struct branch_clk audio_core_lpaif_codec_spkr_ebit_clk = {
+	.cbcr_reg = AUDIO_CORE_LPAIF_CODEC_SPKR_EBIT_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "audio_core_lpaif_codec_spkr_ebit_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(audio_core_lpaif_codec_spkr_ebit_clk.c),
+	},
+};
+
+static struct branch_clk audio_core_lpaif_codec_spkr_ibit_clk = {
+	.cbcr_reg = AUDIO_CORE_LPAIF_CODEC_SPKR_IBIT_CBCR,
+	.has_sibling = 1,
+	.max_div = 511,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.parent = &lpaif_spkr_clk_src.c,
+		.dbg_name = "audio_core_lpaif_codec_spkr_ibit_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(audio_core_lpaif_codec_spkr_ibit_clk.c),
+	},
+};
+
+static struct branch_clk audio_core_lpaif_codec_spkr_osr_clk = {
+	.cbcr_reg = AUDIO_CORE_LPAIF_CODEC_SPKR_OSR_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.parent = &lpaif_spkr_clk_src.c,
+		.dbg_name = "audio_core_lpaif_codec_spkr_osr_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(audio_core_lpaif_codec_spkr_osr_clk.c),
+	},
+};
+
+static struct branch_clk audio_core_lpaif_ter_ebit_clk = {
+	.cbcr_reg = AUDIO_CORE_LPAIF_TER_EBIT_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "audio_core_lpaif_ter_ebit_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(audio_core_lpaif_ter_ebit_clk.c),
+	},
+};
+
+static struct branch_clk audio_core_lpaif_ter_ibit_clk = {
+	.cbcr_reg = AUDIO_CORE_LPAIF_TER_IBIT_CBCR,
+	.has_sibling = 0,
+	.max_div = 511,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.parent = &lpaif_ter_clk_src.c,
+		.dbg_name = "audio_core_lpaif_ter_ibit_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(audio_core_lpaif_ter_ibit_clk.c),
+	},
+};
+
+static struct branch_clk audio_core_lpaif_ter_osr_clk = {
+	.cbcr_reg = AUDIO_CORE_LPAIF_TER_OSR_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.parent = &lpaif_ter_clk_src.c,
+		.dbg_name = "audio_core_lpaif_ter_osr_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(audio_core_lpaif_ter_osr_clk.c),
+	},
+};
+
+#ifdef CONFIG_DEBUG_FS
+
+struct measure_mux_entry {
+	struct clk *c;
+	int base;
+	u32 debug_mux;
+};
+
+static struct measure_mux_entry measure_mux[] = {
+	{                   &snoc_clk.c, GCC_BASE, 0x0000},
+	{                   &cnoc_clk.c, GCC_BASE, 0x0008},
+	{     &gcc_copss_smmu_ahb_clk.c, GCC_BASE, 0x000c},
+	{      &gcc_lpss_smmu_ahb_clk.c, GCC_BASE, 0x000d},
+	{                   &pnoc_clk.c, GCC_BASE, 0x0010},
+	{   &gcc_mmss_noc_cfg_ahb_clk.c, GCC_BASE, 0x002a},
+	{        &gcc_mss_cfg_ahb_clk.c, GCC_BASE, 0x0030},
+	{    &gcc_mss_q6_bimc_axi_clk.c, GCC_BASE, 0x0031},
+	{      &gcc_usb_hs_system_clk.c, GCC_BASE, 0x0060},
+	{         &gcc_usb_hs_ahb_clk.c, GCC_BASE, 0x0061},
+	{    &gcc_usb2a_phy_sleep_clk.c, GCC_BASE, 0x0063},
+	{         &gcc_sdcc1_apps_clk.c, GCC_BASE, 0x0068},
+	{          &gcc_sdcc1_ahb_clk.c, GCC_BASE, 0x0069},
+	{         &gcc_sdcc2_apps_clk.c, GCC_BASE, 0x0070},
+	{          &gcc_sdcc2_ahb_clk.c, GCC_BASE, 0x0071},
+	{          &gcc_blsp1_ahb_clk.c, GCC_BASE, 0x0088},
+	{&gcc_blsp1_qup1_spi_apps_clk.c, GCC_BASE, 0x008a},
+	{&gcc_blsp1_qup1_i2c_apps_clk.c, GCC_BASE, 0x008b},
+	{   &gcc_blsp1_uart1_apps_clk.c, GCC_BASE, 0x008c},
+	{&gcc_blsp1_qup2_spi_apps_clk.c, GCC_BASE, 0x008e},
+	{&gcc_blsp1_qup2_i2c_apps_clk.c, GCC_BASE, 0x0090},
+	{   &gcc_blsp1_uart2_apps_clk.c, GCC_BASE, 0x0091},
+	{&gcc_blsp1_qup3_spi_apps_clk.c, GCC_BASE, 0x0093},
+	{&gcc_blsp1_qup3_i2c_apps_clk.c, GCC_BASE, 0x0094},
+	{   &gcc_blsp1_uart3_apps_clk.c, GCC_BASE, 0x0095},
+	{&gcc_blsp1_qup4_spi_apps_clk.c, GCC_BASE, 0x0098},
+	{&gcc_blsp1_qup4_i2c_apps_clk.c, GCC_BASE, 0x0099},
+	{   &gcc_blsp1_uart4_apps_clk.c, GCC_BASE, 0x009a},
+	{&gcc_blsp1_qup5_spi_apps_clk.c, GCC_BASE, 0x009c},
+	{&gcc_blsp1_qup5_i2c_apps_clk.c, GCC_BASE, 0x009d},
+	{   &gcc_blsp1_uart5_apps_clk.c, GCC_BASE, 0x009e},
+	{&gcc_blsp1_qup6_spi_apps_clk.c, GCC_BASE, 0x00a1},
+	{&gcc_blsp1_qup6_i2c_apps_clk.c, GCC_BASE, 0x00a2},
+	{   &gcc_blsp1_uart6_apps_clk.c, GCC_BASE, 0x00a3},
+	{            &gcc_pdm_ahb_clk.c, GCC_BASE, 0x00d0},
+	{               &gcc_pdm2_clk.c, GCC_BASE, 0x00d2},
+	{           &gcc_prng_ahb_clk.c, GCC_BASE, 0x00d8},
+	{       &gcc_boot_rom_ahb_clk.c, GCC_BASE, 0x00f8},
+	{                &gcc_ce1_clk.c, GCC_BASE, 0x0138},
+	{            &gcc_ce1_axi_clk.c, GCC_BASE, 0x0139},
+	{            &gcc_ce1_ahb_clk.c, GCC_BASE, 0x013a},
+	{             &gcc_xo_clk_src.c, GCC_BASE, 0x0149},
+	{                   &bimc_clk.c, GCC_BASE, 0x0154},
+	{       &gcc_lpass_q6_axi_clk.c, GCC_BASE, 0x0160},
+
+	{     &mmssnoc_ahb_clk.c, MMSS_BASE, 0x0001},
+	{   &mmss_misc_ahb_clk.c, MMSS_BASE, 0x0003},
+	{&mmss_mmssnoc_axi_clk.c, MMSS_BASE, 0x0004},
+	{     &mmss_s0_axi_clk.c, MMSS_BASE, 0x0005},
+	{       &oxili_ahb_clk.c, MMSS_BASE, 0x0007},
+	{     &oxili_gfx3d_clk.c, MMSS_BASE, 0x0008},
+	{      &gmem_gfx3d_clk.c, MMSS_BASE, 0x0009},
+	{         &mdp_axi_clk.c, MMSS_BASE, 0x000a},
+	{       &mdp_vsync_clk.c, MMSS_BASE, 0x000b},
+	{         &mdp_ahb_clk.c, MMSS_BASE, 0x000c},
+	{        &dsi_pclk_clk.c, MMSS_BASE, 0x000d},
+	{         &mdp_dsi_clk.c, MMSS_BASE, 0x000e},
+	{        &mdp_lcdc_clk.c, MMSS_BASE, 0x000f},
+	{             &dsi_clk.c, MMSS_BASE, 0x0010},
+	{        &dsi_byte_clk.c, MMSS_BASE, 0x0011},
+	{         &dsi_esc_clk.c, MMSS_BASE, 0x0012},
+	{         &dsi_ahb_clk.c, MMSS_BASE, 0x0013},
+	{           &mclk0_clk.c, MMSS_BASE, 0x0015},
+	{           &mclk1_clk.c, MMSS_BASE, 0x0016},
+	{    &csi0phytimer_clk.c, MMSS_BASE, 0x0017},
+	{    &csi1phytimer_clk.c, MMSS_BASE, 0x0018},
+	{             &vfe_clk.c, MMSS_BASE, 0x0019},
+	{         &vfe_ahb_clk.c, MMSS_BASE, 0x001a},
+	{         &vfe_axi_clk.c, MMSS_BASE, 0x001b},
+	{         &csi_vfe_clk.c, MMSS_BASE, 0x001c},
+	{            &csi0_clk.c, MMSS_BASE, 0x001d},
+	{         &csi_ahb_clk.c, MMSS_BASE, 0x001e},
+	{         &csi0phy_clk.c, MMSS_BASE, 0x001f},
+	{         &csi0rdi_clk.c, MMSS_BASE, 0x0020},
+	{         &csi0pix_clk.c, MMSS_BASE, 0x0021},
+	{            &csi1_clk.c, MMSS_BASE, 0x0022},
+	{         &csi1phy_clk.c, MMSS_BASE, 0x0023},
+	{         &csi1rdi_clk.c, MMSS_BASE, 0x0024},
+	{         &csi1pix_clk.c, MMSS_BASE, 0x0025},
+	{        &bimc_gfx_clk.c, MMSS_BASE, 0x0032},
+
+	{             &lpaif_pcmoe_clk_src.c, LPASS_BASE, 0x000f},
+	{              &lpaif_pcm1_clk_src.c, LPASS_BASE, 0x0012},
+	{              &lpaif_pcm0_clk_src.c, LPASS_BASE, 0x0013},
+	{              &lpaif_quad_clk_src.c, LPASS_BASE, 0x0014},
+	{               &lpaif_ter_clk_src.c, LPASS_BASE, 0x0015},
+	{               &lpaif_sec_clk_src.c, LPASS_BASE, 0x0016},
+	{               &lpaif_pri_clk_src.c, LPASS_BASE, 0x0017},
+	{              &lpaif_spkr_clk_src.c, LPASS_BASE, 0x0018},
+	{                   &q6ss_ahbm_clk.c, LPASS_BASE, 0x001d},
+	{             &q6ss_ahb_lfabif_clk.c, LPASS_BASE, 0x001e},
+	{            &audio_wrapper_br_clk.c, LPASS_BASE, 0x0022},
+	{                     &q6ss_xo_clk.c, LPASS_BASE, 0x002b},
+	{&audio_core_lpaif_pcm_data_oe_clk.c, LPASS_BASE, 0x0030},
+	{         &audio_core_ixfabric_clk.c, LPASS_BASE, 0x0059},
+
+	{&apc0_m_clk,                    APCS_BASE, 0x10},
+	{&apc1_m_clk,                    APCS_BASE, 0x11},
+	{&apc2_m_clk,                    APCS_BASE, 0x12},
+	{&apc3_m_clk,                    APCS_BASE, 0x13},
+	{&l2_m_clk,                      APCS_BASE, 0x15},
+
+	{&dummy_clk, N_BASES, 0x0000},
+};
+
+#define GCC_DEBUG_CLK_CTL		0x1880
+#define MMSS_DEBUG_CLK_CTL		0x0900
+#define LPASS_DEBUG_CLK_CTL		0x29000
+#define GLB_CLK_DIAG			0x001C
+
+static int measure_clk_set_parent(struct clk *c, struct clk *parent)
+{
+	struct measure_clk *clk = to_measure_clk(c);
+	unsigned long flags;
+	u32 regval, clk_sel, i;
+
+	if (!parent)
+		return -EINVAL;
+
+	for (i = 0; i < (ARRAY_SIZE(measure_mux) - 1); i++)
+		if (measure_mux[i].c == parent)
+			break;
+
+	if (measure_mux[i].c == &dummy_clk)
+		return -EINVAL;
+
+	spin_lock_irqsave(&local_clock_reg_lock, flags);
+	/*
+	 * Program the test vector, measurement period (sample_ticks)
+	 * and scaling multiplier.
+	 */
+	clk->sample_ticks = 0x10000;
+	clk->multiplier = 1;
+
+	switch (measure_mux[i].base) {
+
+	case GCC_BASE:
+		writel_relaxed(0, GCC_REG_BASE(GCC_DEBUG_CLK_CTL));
+		clk_sel = measure_mux[i].debug_mux;
+		break;
+
+	case MMSS_BASE:
+		writel_relaxed(0, MMSS_REG_BASE(MMSS_DEBUG_CLK_CTL));
+		clk_sel = 0x02C;
+		regval = BVAL(11, 0, measure_mux[i].debug_mux);
+		writel_relaxed(regval, MMSS_REG_BASE(MMSS_DEBUG_CLK_CTL));
+
+		/* Activate debug clock output */
+		regval |= BIT(16);
+		writel_relaxed(regval, MMSS_REG_BASE(MMSS_DEBUG_CLK_CTL));
+		break;
+
+	case LPASS_BASE:
+		writel_relaxed(0, LPASS_REG_BASE(LPASS_DEBUG_CLK_CTL));
+		clk_sel = 0x161;
+		regval = BVAL(11, 0, measure_mux[i].debug_mux);
+		writel_relaxed(regval, LPASS_REG_BASE(LPASS_DEBUG_CLK_CTL));
+
+		/* Activate debug clock output */
+		regval |= BIT(20);
+		writel_relaxed(regval, LPASS_REG_BASE(LPASS_DEBUG_CLK_CTL));
+		break;
+
+	case APCS_BASE:
+		clk->multiplier = 4;
+		clk_sel = 0x16A;
+		regval = measure_mux[i].debug_mux;
+		writel_relaxed(regval, APCS_REG_BASE(GLB_CLK_DIAG));
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	/* Set debug mux clock index */
+	regval = BVAL(8, 0, clk_sel);
+	writel_relaxed(regval, GCC_REG_BASE(GCC_DEBUG_CLK_CTL));
+
+	/* Activate debug clock output */
+	regval |= BIT(16);
+	writel_relaxed(regval, GCC_REG_BASE(GCC_DEBUG_CLK_CTL));
+
+	/* Make sure test vector is set before starting measurements. */
+	mb();
+	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
+
+	return 0;
+}
+
+#define CLOCK_FRQ_MEASURE_CTL		0x1884
+#define CLOCK_FRQ_MEASURE_STATUS	0x1888
+
+/* Sample clock for 'ticks' reference clock ticks. */
+static u32 run_measurement(unsigned ticks)
+{
+	/* Stop counters and set the XO4 counter start value. */
+	writel_relaxed(ticks, GCC_REG_BASE(CLOCK_FRQ_MEASURE_CTL));
+
+	/* Wait for timer to become ready. */
+	while ((readl_relaxed(GCC_REG_BASE(CLOCK_FRQ_MEASURE_STATUS)) &
+			BIT(25)) != 0)
+		cpu_relax();
+
+	/* Run measurement and wait for completion. */
+	writel_relaxed(BIT(20)|ticks, GCC_REG_BASE(CLOCK_FRQ_MEASURE_CTL));
+	while ((readl_relaxed(GCC_REG_BASE(CLOCK_FRQ_MEASURE_STATUS)) &
+			BIT(25)) == 0)
+		cpu_relax();
+
+	/* Return measured ticks. */
+	return readl_relaxed(GCC_REG_BASE(CLOCK_FRQ_MEASURE_STATUS)) &
+				BM(24, 0);
+}
+
+#define GCC_XO_DIV4_CBCR	0x10C8
+#define PLLTEST_PAD_CFG		0x188C
+
+/*
+ * Perform a hardware rate measurement for a given clock.
+ * FOR DEBUG USE ONLY: Measurements take ~15 ms!
+ */
+static unsigned long measure_clk_get_rate(struct clk *c)
+{
+	unsigned long flags;
+	u32 gcc_xo4_reg_backup;
+	u64 raw_count_short, raw_count_full;
+	struct measure_clk *clk = to_measure_clk(c);
+	unsigned ret;
+
+	ret = clk_prepare_enable(&gcc_xo_clk_src.c);
+	if (ret) {
+		pr_warning("CXO clock failed to enable. Can't measure\n");
+		return 0;
+	}
+
+	spin_lock_irqsave(&local_clock_reg_lock, flags);
+
+	/* Enable CXO/4 and RINGOSC branch. */
+	gcc_xo4_reg_backup = readl_relaxed(GCC_REG_BASE(GCC_XO_DIV4_CBCR));
+	writel_relaxed(0x1, GCC_REG_BASE(GCC_XO_DIV4_CBCR));
+
+	/*
+	 * The ring oscillator counter will not reset if the measured clock
+	 * is not running.  To detect this, run a short measurement before
+	 * the full measurement.  If the raw results of the two are the same
+	 * then the clock must be off.
+	 */
+
+	/* Run a short measurement. (~1 ms) */
+	raw_count_short = run_measurement(0x1000);
+	/* Run a full measurement. (~14 ms) */
+	raw_count_full = run_measurement(clk->sample_ticks);
+
+	writel_relaxed(gcc_xo4_reg_backup, GCC_REG_BASE(GCC_XO_DIV4_CBCR));
+
+	/* Return 0 if the clock is off. */
+	if (raw_count_full == raw_count_short) {
+		ret = 0;
+	} else {
+		/* Compute rate in Hz. */
+		raw_count_full = ((raw_count_full * 10) + 15) * 4800000;
+		do_div(raw_count_full, ((clk->sample_ticks * 10) + 35));
+		ret = (raw_count_full * clk->multiplier);
+	}
+
+	writel_relaxed(0x51A00, GCC_REG_BASE(PLLTEST_PAD_CFG));
+	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
+
+	clk_disable_unprepare(&gcc_xo_clk_src.c);
+
+	return ret;
+}
+#else /* !CONFIG_DEBUG_FS */
+static int measure_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	return -EINVAL;
+}
+
+static unsigned long measure_clk_get_rate(struct clk *clk)
+{
+	return 0;
+}
+#endif /* CONFIG_DEBUG_FS */
+
+static struct clk_ops clk_ops_measure = {
+	.set_parent = measure_clk_set_parent,
+	.get_rate = measure_clk_get_rate,
+};
+
+static struct measure_clk measure_clk = {
+	.c = {
+		.dbg_name = "measure_clk",
+		.ops = &clk_ops_measure,
+		CLK_INIT(measure_clk.c),
+	},
+	.multiplier = 1,
+};
+
+static struct clk_lookup msm_clocks_8610[] = {
+	CLK_LOOKUP("xo",	gcc_xo_clk_src.c, "msm_otg"),
+	CLK_LOOKUP("xo",	gcc_xo_clk_src.c, "fe200000.qcom,lpass"),
+	CLK_LOOKUP("xo",	gcc_xo_clk_src.c, "pil-q6v5-mss"),
+	CLK_LOOKUP("xo",	gcc_xo_clk_src.c, "pil-mba"),
+	CLK_LOOKUP("xo",	gcc_xo_clk_src.c, "fb000000.qcom,wcnss-wlan"),
+	CLK_LOOKUP("xo",	gcc_xo_clk_src.c, "fb21b000.qcom,pronto"),
+	CLK_LOOKUP("measure",	measure_clk.c,	"debug"),
+
+	CLK_LOOKUP("iface_clk",  gcc_blsp1_ahb_clk.c, "f991f000.serial"),
+	CLK_LOOKUP("core_clk",  gcc_blsp1_uart3_apps_clk.c, "f991f000.serial"),
+
+	CLK_LOOKUP("dfab_clk", pnoc_sps_clk.c, "msm_sps"),
+	CLK_LOOKUP("bus_clk",  pnoc_qseecom_clk.c, "qseecom"),
+
+	CLK_LOOKUP("bus_clk", snoc_clk.c, ""),
+	CLK_LOOKUP("bus_clk", pnoc_clk.c, ""),
+	CLK_LOOKUP("bus_clk", cnoc_clk.c, ""),
+	CLK_LOOKUP("mem_clk", bimc_clk.c, ""),
+	CLK_LOOKUP("bus_clk", snoc_a_clk.c, ""),
+	CLK_LOOKUP("bus_clk", pnoc_a_clk.c, ""),
+	CLK_LOOKUP("bus_clk", cnoc_a_clk.c, ""),
+	CLK_LOOKUP("mem_clk", bimc_a_clk.c, ""),
+
+	CLK_LOOKUP("bus_clk",	cnoc_msmbus_clk.c,	"msm_config_noc"),
+	CLK_LOOKUP("bus_a_clk",	cnoc_msmbus_a_clk.c,	"msm_config_noc"),
+	CLK_LOOKUP("bus_clk",	snoc_msmbus_clk.c,	"msm_sys_noc"),
+	CLK_LOOKUP("bus_a_clk",	snoc_msmbus_a_clk.c,	"msm_sys_noc"),
+	CLK_LOOKUP("bus_clk",	pnoc_msmbus_clk.c,	"msm_periph_noc"),
+	CLK_LOOKUP("bus_a_clk",	pnoc_msmbus_a_clk.c,	"msm_periph_noc"),
+	CLK_LOOKUP("mem_clk",	bimc_msmbus_clk.c,	"msm_bimc"),
+	CLK_LOOKUP("mem_a_clk",	bimc_msmbus_a_clk.c,	"msm_bimc"),
+	CLK_LOOKUP("mem_clk",	bimc_acpu_a_clk.c,	""),
+
+	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-tmc-etr"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-tpiu"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-replicator"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-tmc-etf"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-funnel-merg"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-funnel-in0"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-funnel-in1"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-funnel-kpss"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-funnel-mmss"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-stm"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-etm0"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-etm1"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-etm2"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-etm3"),
+
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-tmc-etr"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-tpiu"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-replicator"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-tmc-etf"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-funnel-merg"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-funnel-in0"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-funnel-in1"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-funnel-kpss"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-funnel-mmss"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-stm"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-etm0"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-etm1"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-etm2"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-etm3"),
+
+	CLK_LOOKUP("core_clk_src", blsp1_qup1_spi_apps_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src", blsp1_qup2_spi_apps_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src", blsp1_qup3_spi_apps_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src", blsp1_qup4_spi_apps_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src", blsp1_qup5_spi_apps_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src", blsp1_qup6_spi_apps_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",    blsp1_uart1_apps_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",    blsp1_uart2_apps_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",    blsp1_uart3_apps_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",    blsp1_uart4_apps_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",    blsp1_uart5_apps_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",    blsp1_uart6_apps_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",                 ce1_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",                 gp1_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",                 gp2_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",                 gp3_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",                pdm2_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",          sdcc1_apps_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",          sdcc2_apps_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",       usb_hs_system_clk_src.c, ""),
+	CLK_LOOKUP("iface_clk",           gcc_blsp1_ahb_clk.c, "f9925000.i2c"),
+	CLK_LOOKUP("iface_clk",           gcc_blsp1_ahb_clk.c, "f9923000.spi"),
+	CLK_LOOKUP("core_clk",  gcc_blsp1_qup1_i2c_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk",  gcc_blsp1_qup1_spi_apps_clk.c, "f9923000.spi"),
+	CLK_LOOKUP("core_clk",  gcc_blsp1_qup2_i2c_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk",  gcc_blsp1_qup2_spi_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk",  gcc_blsp1_qup3_i2c_apps_clk.c, "f9925000.i2c"),
+	CLK_LOOKUP("core_clk",  gcc_blsp1_qup3_spi_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk",  gcc_blsp1_qup4_i2c_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk",  gcc_blsp1_qup4_spi_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk",  gcc_blsp1_qup5_i2c_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk",  gcc_blsp1_qup5_spi_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk",  gcc_blsp1_qup6_i2c_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk",  gcc_blsp1_qup6_spi_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk",     gcc_blsp1_uart1_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk",     gcc_blsp1_uart2_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk",     gcc_blsp1_uart3_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk",     gcc_blsp1_uart4_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk",     gcc_blsp1_uart5_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk",     gcc_blsp1_uart6_apps_clk.c, ""),
+	CLK_LOOKUP("iface_clk",         gcc_boot_rom_ahb_clk.c, ""),
+	CLK_LOOKUP("iface_clk",              gcc_ce1_ahb_clk.c, ""),
+	CLK_LOOKUP("core_clk",              gcc_ce1_axi_clk.c, ""),
+	CLK_LOOKUP("core_clk",                  gcc_ce1_clk.c, ""),
+	CLK_LOOKUP("iface_clk",       gcc_copss_smmu_ahb_clk.c, ""),
+	CLK_LOOKUP("iface_clk",        gcc_lpss_smmu_ahb_clk.c, ""),
+	CLK_LOOKUP("core_clk",                  gcc_gp1_clk.c, ""),
+	CLK_LOOKUP("core_clk",                  gcc_gp2_clk.c, ""),
+	CLK_LOOKUP("core_clk",                  gcc_gp3_clk.c, ""),
+	CLK_LOOKUP("core_clk",         gcc_lpass_q6_axi_clk.c, ""),
+	CLK_LOOKUP("iface_clk",          gcc_mss_cfg_ahb_clk.c, ""),
+	CLK_LOOKUP("core_clk",      gcc_mss_q6_bimc_axi_clk.c, ""),
+	CLK_LOOKUP("core_clk",                 gcc_pdm2_clk.c, ""),
+	CLK_LOOKUP("iface_clk",              gcc_pdm_ahb_clk.c, ""),
+	CLK_LOOKUP("iface_clk",             gcc_prng_ahb_clk.c, ""),
+	CLK_LOOKUP("iface_clk",            gcc_sdcc1_ahb_clk.c, "msm_sdcc.1"),
+	CLK_LOOKUP("core_clk",           gcc_sdcc1_apps_clk.c, "msm_sdcc.1"),
+	CLK_LOOKUP("iface_clk",            gcc_sdcc2_ahb_clk.c, "msm_sdcc.2"),
+	CLK_LOOKUP("core_clk",           gcc_sdcc2_apps_clk.c, "msm_sdcc.2"),
+	CLK_LOOKUP("core_clk",      gcc_usb2a_phy_sleep_clk.c, ""),
+	CLK_LOOKUP("iface_clk",           gcc_usb_hs_ahb_clk.c, "f9a55000.usb"),
+	CLK_LOOKUP("core_clk",        gcc_usb_hs_system_clk.c, "f9a55000.usb"),
+
+	CLK_LOOKUP("core_clk_src",                csi0_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",                 axi_clk_src.c, ""),
+	CLK_LOOKUP("",                         mdp_axi_clk_src.c, ""),
+	CLK_LOOKUP("",                     mmssnoc_axi_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",            dsi_pclk_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",               gfx3d_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",                 vfe_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",                csi1_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",        csi0phytimer_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",        csi1phytimer_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",                 dsi_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",            dsi_byte_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",             dsi_esc_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",               mclk0_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",               mclk1_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",           mdp_vsync_clk_src.c, ""),
+
+	CLK_LOOKUP("core_clk",                 bimc_gfx_clk.c, ""),
+	CLK_LOOKUP("core_clk",                     csi0_clk.c, ""),
+	CLK_LOOKUP("core_clk",                  csi0phy_clk.c, ""),
+	CLK_LOOKUP("core_clk",             csi0phytimer_clk.c, ""),
+	CLK_LOOKUP("core_clk",                  csi0pix_clk.c, ""),
+	CLK_LOOKUP("core_clk",                  csi0rdi_clk.c, ""),
+	CLK_LOOKUP("core_clk",                     csi1_clk.c, ""),
+	CLK_LOOKUP("core_clk",                  csi1phy_clk.c, ""),
+	CLK_LOOKUP("core_clk",             csi1phytimer_clk.c, ""),
+	CLK_LOOKUP("core_clk",                  csi1pix_clk.c, ""),
+	CLK_LOOKUP("core_clk",                  csi1rdi_clk.c, ""),
+	CLK_LOOKUP("core_clk",                  csi_ahb_clk.c, ""),
+	CLK_LOOKUP("core_clk",                  csi_vfe_clk.c, ""),
+	CLK_LOOKUP("core_clk",                      dsi_clk.c, ""),
+	CLK_LOOKUP("core_clk",                  dsi_ahb_clk.c, ""),
+	CLK_LOOKUP("core_clk",                 dsi_byte_clk.c, ""),
+	CLK_LOOKUP("core_clk",                  dsi_esc_clk.c, ""),
+	CLK_LOOKUP("core_clk",                 dsi_pclk_clk.c, ""),
+	CLK_LOOKUP("core_clk",               gmem_gfx3d_clk.c, ""),
+	CLK_LOOKUP("core_clk",                    mclk0_clk.c, ""),
+	CLK_LOOKUP("core_clk",                    mclk1_clk.c, ""),
+	CLK_LOOKUP("core_clk",                  mdp_ahb_clk.c, ""),
+	CLK_LOOKUP("core_clk",                  mdp_axi_clk.c, ""),
+	CLK_LOOKUP("core_clk",                  mdp_dsi_clk.c, ""),
+	CLK_LOOKUP("core_clk",                 mdp_lcdc_clk.c, ""),
+	CLK_LOOKUP("core_clk",                mdp_vsync_clk.c, ""),
+	CLK_LOOKUP("core_clk",            mmss_misc_ahb_clk.c, ""),
+	CLK_LOOKUP("core_clk",              mmss_s0_axi_clk.c, ""),
+	CLK_LOOKUP("core_clk",     mmss_mmssnoc_bto_ahb_clk.c, ""),
+	CLK_LOOKUP("core_clk",         mmss_mmssnoc_axi_clk.c, ""),
+	CLK_LOOKUP("core_clk",                      vfe_clk.c, ""),
+	CLK_LOOKUP("core_clk",                  vfe_ahb_clk.c, ""),
+	CLK_LOOKUP("core_clk",                  vfe_axi_clk.c, ""),
+
+	CLK_LOOKUP("core_clk",   oxili_gfx3d_clk.c, "fdc00000.qcom,kgsl-3d0"),
+	CLK_LOOKUP("iface_clk",    oxili_ahb_clk.c, "fdc00000.qcom,kgsl-3d0"),
+	CLK_LOOKUP("mem_iface_clk", bimc_gfx_clk.c, "fdc00000.qcom,kgsl-3d0"),
+	CLK_LOOKUP("mem_clk",     gmem_gfx3d_clk.c, "fdc00000.qcom,kgsl-3d0"),
+
+	CLK_LOOKUP("iface_clk",           vfe_ahb_clk.c, "fd890000.qcom,iommu"),
+	CLK_LOOKUP("core_clk",            vfe_axi_clk.c, "fd890000.qcom,iommu"),
+	CLK_LOOKUP("iface_clk",           mdp_ahb_clk.c, "fd860000.qcom,iommu"),
+	CLK_LOOKUP("core_clk",            mdp_axi_clk.c, "fd860000.qcom,iommu"),
+	CLK_LOOKUP("iface_clk",           mdp_ahb_clk.c, "fd870000.qcom,iommu"),
+	CLK_LOOKUP("core_clk",            mdp_axi_clk.c, "fd870000.qcom,iommu"),
+	CLK_LOOKUP("iface_clk",         oxili_ahb_clk.c, "fd880000.qcom,iommu"),
+	CLK_LOOKUP("core_clk",           bimc_gfx_clk.c, "fd880000.qcom,iommu"),
+	CLK_LOOKUP("iface_clk", gcc_lpss_smmu_ahb_clk.c, "fd000000.qcom,iommu"),
+	CLK_LOOKUP("core_clk",   gcc_lpass_q6_axi_clk.c, "fd000000.qcom,iommu"),
+	CLK_LOOKUP("iface_clk", gcc_copss_smmu_ahb_clk.c,
+							 "fd010000.qcom,iommu"),
+	CLK_LOOKUP("core_clk",         pnoc_iommu_clk.c, "fd010000.qcom,iommu"),
+
+	CLK_LOOKUP("core_clk_src",                 lpaif_pri_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",                lpaif_quad_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",                 lpaif_sec_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",                lpaif_spkr_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",                 lpaif_ter_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",                lpaif_pcm0_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",                lpaif_pcm1_clk_src.c, ""),
+	CLK_LOOKUP("core_clk_src",               lpaif_pcmoe_clk_src.c, ""),
+	CLK_LOOKUP("core_clk",               audio_core_ixfabric_clk.c, ""),
+	CLK_LOOKUP("core_clk",                  audio_wrapper_br_clk.c, ""),
+	CLK_LOOKUP("core_clk",                   q6ss_ahb_lfabif_clk.c, ""),
+	CLK_LOOKUP("core_clk",                         q6ss_ahbm_clk.c, ""),
+	CLK_LOOKUP("core_clk",                           q6ss_xo_clk.c, ""),
+	CLK_LOOKUP("core_clk",      audio_core_lpaif_pcm_data_oe_clk.c, ""),
+	CLK_LOOKUP("core_clk",         audio_core_lpaif_pri_ebit_clk.c, ""),
+	CLK_LOOKUP("core_clk",         audio_core_lpaif_pri_ibit_clk.c, ""),
+	CLK_LOOKUP("core_clk",          audio_core_lpaif_pri_osr_clk.c, ""),
+	CLK_LOOKUP("core_clk",        audio_core_lpaif_pcm0_ebit_clk.c, ""),
+	CLK_LOOKUP("core_clk",        audio_core_lpaif_pcm0_ibit_clk.c, ""),
+	CLK_LOOKUP("core_clk",        audio_core_lpaif_quad_ebit_clk.c, ""),
+	CLK_LOOKUP("core_clk",        audio_core_lpaif_quad_ibit_clk.c, ""),
+	CLK_LOOKUP("core_clk",         audio_core_lpaif_quad_osr_clk.c, ""),
+	CLK_LOOKUP("core_clk",         audio_core_lpaif_sec_ebit_clk.c, ""),
+	CLK_LOOKUP("core_clk",         audio_core_lpaif_sec_ibit_clk.c, ""),
+	CLK_LOOKUP("core_clk",          audio_core_lpaif_sec_osr_clk.c, ""),
+	CLK_LOOKUP("core_clk",        audio_core_lpaif_pcm1_ebit_clk.c, ""),
+	CLK_LOOKUP("core_clk",        audio_core_lpaif_pcm1_ibit_clk.c, ""),
+	CLK_LOOKUP("core_clk",  audio_core_lpaif_codec_spkr_ebit_clk.c, ""),
+	CLK_LOOKUP("core_clk",  audio_core_lpaif_codec_spkr_ibit_clk.c, ""),
+	CLK_LOOKUP("core_clk",   audio_core_lpaif_codec_spkr_osr_clk.c, ""),
+	CLK_LOOKUP("core_clk",         audio_core_lpaif_ter_ebit_clk.c, ""),
+	CLK_LOOKUP("core_clk",         audio_core_lpaif_ter_ibit_clk.c, ""),
+	CLK_LOOKUP("core_clk",          audio_core_lpaif_ter_osr_clk.c, ""),
+
+	CLK_LOOKUP("core_clk",         q6ss_xo_clk.c,  "fe200000.qcom,lpass"),
+	CLK_LOOKUP("bus_clk", gcc_lpass_q6_axi_clk.c,  "fe200000.qcom,lpass"),
+	CLK_LOOKUP("iface_clk", q6ss_ahb_lfabif_clk.c, "fe200000.qcom,lpass"),
+	CLK_LOOKUP("reg_clk",        q6ss_ahbm_clk.c,  "fe200000.qcom,lpass"),
+
+	CLK_LOOKUP("xo",      gcc_xo_a_clk_src.c, "f9011050.qcom,acpuclk"),
+	CLK_LOOKUP("gpll0", gpll0_ao_clk_src.c, "f9011050.qcom,acpuclk"),
+	CLK_LOOKUP("a7sspll",        a7sspll.c, "f9011050.qcom,acpuclk"),
+
+	CLK_LOOKUP("measure_clk", apc0_m_clk, ""),
+	CLK_LOOKUP("measure_clk", apc1_m_clk, ""),
+	CLK_LOOKUP("measure_clk", apc2_m_clk, ""),
+	CLK_LOOKUP("measure_clk", apc3_m_clk, ""),
+	CLK_LOOKUP("measure_clk",   l2_m_clk, ""),
+};
+
+static struct clk_lookup msm_clocks_8610_rumi[] = {
+	CLK_DUMMY("core_clk",   BLSP1_UART_CLK, "f991f000.serial", OFF),
+	CLK_DUMMY("iface_clk",  BLSP1_UART_CLK, "f991f000.serial", OFF),
+	CLK_DUMMY("iface_clk",  HSUSB_IFACE_CLK, "f9a55000.usb", OFF),
+	CLK_DUMMY("core_clk",	HSUSB_CORE_CLK, "f9a55000.usb", OFF),
+	CLK_DUMMY("iface_clk",	NULL,		"msm_sdcc.1", OFF),
+	CLK_DUMMY("core_clk",	NULL,		"msm_sdcc.1", OFF),
+	CLK_DUMMY("bus_clk",	NULL,		"msm_sdcc.1", OFF),
+	CLK_DUMMY("iface_clk",	NULL,		"msm_sdcc.2", OFF),
+	CLK_DUMMY("core_clk",	NULL,		"msm_sdcc.2", OFF),
+	CLK_DUMMY("bus_clk",	NULL,		"msm_sdcc.2", OFF),
+	CLK_DUMMY("dfab_clk",	DFAB_CLK,	"msm_sps", OFF),
+	CLK_DUMMY("iface_clk",  NULL, "fd890000.qcom,iommu", OFF),
+	CLK_DUMMY("core_clk",   NULL, "fd890000.qcom,iommu", OFF),
+	CLK_DUMMY("iface_clk",  NULL, "fd860000.qcom,iommu", OFF),
+	CLK_DUMMY("core_clk",   NULL, "fd860000.qcom,iommu", OFF),
+	CLK_DUMMY("iface_clk",  NULL, "fd870000.qcom,iommu", OFF),
+	CLK_DUMMY("core_clk",   NULL, "fd870000.qcom,iommu", OFF),
+	CLK_DUMMY("iface_clk",  NULL, "fd880000.qcom,iommu", OFF),
+	CLK_DUMMY("core_clk",   NULL, "fd880000.qcom,iommu", OFF),
+	CLK_DUMMY("iface_clk",  NULL, "fd000000.qcom,iommu", OFF),
+	CLK_DUMMY("core_clk",   NULL, "fd000000.qcom,iommu", OFF),
+	CLK_DUMMY("iface_clk",  NULL, "fd010000.qcom,iommu", OFF),
+	CLK_DUMMY("core_clk",   NULL, "fd010000.qcom,iommu", OFF),
+	CLK_DUMMY("xo",      NULL, "f9011050.qcom,acpuclk", OFF),
+	CLK_DUMMY("gpll0",      NULL, "f9011050.qcom,acpuclk", OFF),
+	CLK_DUMMY("a7sspll",    NULL, "f9011050.qcom,acpuclk", OFF),
+};
+
+struct clock_init_data msm8610_rumi_clock_init_data __initdata = {
+	.table = msm_clocks_8610_rumi,
+	.size = ARRAY_SIZE(msm_clocks_8610_rumi),
+};
+
+static struct pll_config_regs gpll0_regs __initdata = {
+	.l_reg = (void __iomem *)GPLL0_L_VAL,
+	.m_reg = (void __iomem *)GPLL0_M_VAL,
+	.n_reg = (void __iomem *)GPLL0_N_VAL,
+	.config_reg = (void __iomem *)GPLL0_USER_CTL,
+	.mode_reg = (void __iomem *)GPLL0_MODE,
+	.base = &virt_bases[GCC_BASE],
+};
+
+/* GPLL0 at 600 MHz, main output enabled. */
+static struct pll_config gpll0_config __initdata = {
+	.l = 0x1f,
+	.m = 0x1,
+	.n = 0x4,
+	.vco_val = 0x0,
+	.vco_mask = BM(21, 20),
+	.pre_div_val = 0x0,
+	.pre_div_mask = BM(14, 12),
+	.post_div_val = 0x0,
+	.post_div_mask = BM(9, 8),
+	.mn_ena_val = BIT(24),
+	.mn_ena_mask = BIT(24),
+	.main_output_val = BIT(0),
+	.main_output_mask = BIT(0),
+};
+
+/* MMPLL0 at 800 MHz, main output enabled. */
+static struct pll_config mmpll0_config __initdata = {
+	.l = 0x29,
+	.m = 0x2,
+	.n = 0x3,
+	.vco_val = 0x0,
+	.vco_mask = BM(21, 20),
+	.pre_div_val = 0x0,
+	.pre_div_mask = BM(14, 12),
+	.post_div_val = 0x0,
+	.post_div_mask = BM(9, 8),
+	.mn_ena_val = BIT(24),
+	.mn_ena_mask = BIT(24),
+	.main_output_val = BIT(0),
+	.main_output_mask = BIT(0),
+};
+
+/* MMPLL1 at 1200 MHz, main output enabled. */
+static struct pll_config mmpll1_config __initdata = {
+	.l = 0x3E,
+	.m = 0x1,
+	.n = 0x2,
+	.vco_val = 0x0,
+	.vco_mask = BM(21, 20),
+	.pre_div_val = 0x0,
+	.pre_div_mask = BM(14, 12),
+	.post_div_val = 0x0,
+	.post_div_mask = BM(9, 8),
+	.mn_ena_val = BIT(24),
+	.mn_ena_mask = BIT(24),
+	.main_output_val = BIT(0),
+	.main_output_mask = BIT(0),
+};
+
+static struct pll_config_regs lpapll0_regs __initdata = {
+	.l_reg = (void __iomem *)LPAAUDIO_PLL_L_VAL,
+	.m_reg = (void __iomem *)LPAAUDIO_PLL_M_VAL,
+	.n_reg = (void __iomem *)LPAAUDIO_PLL_N_VAL,
+	.config_reg = (void __iomem *)LPAAUDIO_PLL_USER_CTL,
+	.mode_reg = (void __iomem *)LPAAUDIO_PLL_MODE,
+	.base = &virt_bases[LPASS_BASE],
+};
+
+/* LPAPLL0 at 491.52 MHz, main output enabled. */
+static struct pll_config lpapll0_config __initdata = {
+	.l = 0x33,
+	.m = 0x1,
+	.n = 0x5,
+	.vco_val = 0x0,
+	.vco_mask = BM(21, 20),
+	.pre_div_val = BVAL(14, 12, 0x1),
+	.pre_div_mask = BM(14, 12),
+	.post_div_val = 0x0,
+	.post_div_mask = BM(9, 8),
+	.mn_ena_val = BIT(24),
+	.mn_ena_mask = BIT(24),
+	.main_output_val = BIT(0),
+	.main_output_mask = BIT(0),
+};
+
+#define PLL_AUX_OUTPUT_BIT 1
+#define PLL_AUX2_OUTPUT_BIT 2
+
+#define PWR_ON_MASK		BIT(31)
+#define EN_REST_WAIT_MASK	(0xF << 20)
+#define EN_FEW_WAIT_MASK	(0xF << 16)
+#define CLK_DIS_WAIT_MASK	(0xF << 12)
+#define SW_OVERRIDE_MASK	BIT(2)
+#define HW_CONTROL_MASK		BIT(1)
+#define SW_COLLAPSE_MASK	BIT(0)
+
+/* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */
+#define EN_REST_WAIT_VAL	(0x2 << 20)
+#define EN_FEW_WAIT_VAL		(0x2 << 16)
+#define CLK_DIS_WAIT_VAL	(0x2 << 12)
+#define GDSC_TIMEOUT_US		50000
+
+static void __init reg_init(void)
+{
+	u32 regval, status;
+	int ret;
+
+	if (!(readl_relaxed(GCC_REG_BASE(GPLL0_STATUS))
+			& gpll0_clk_src.status_mask))
+		configure_sr_hpm_lp_pll(&gpll0_config, &gpll0_regs, 1);
+
+	configure_sr_hpm_lp_pll(&mmpll0_config, &mmpll0_regs, 1);
+	configure_sr_hpm_lp_pll(&mmpll1_config, &mmpll1_regs, 1);
+	configure_sr_hpm_lp_pll(&lpapll0_config, &lpapll0_regs, 1);
+
+	/* Enable GPLL0's aux outputs. */
+	regval = readl_relaxed(GCC_REG_BASE(GPLL0_USER_CTL));
+	regval |= BIT(PLL_AUX_OUTPUT_BIT) | BIT(PLL_AUX2_OUTPUT_BIT);
+	writel_relaxed(regval, GCC_REG_BASE(GPLL0_USER_CTL));
+
+	/* Vote for GPLL0 to turn on. Needed by acpuclock. */
+	regval = readl_relaxed(GCC_REG_BASE(APCS_GPLL_ENA_VOTE));
+	regval |= BIT(0);
+	writel_relaxed(regval, GCC_REG_BASE(APCS_GPLL_ENA_VOTE));
+
+	/*
+	 * TODO: Confirm that no clocks need to be voted on in this sleep vote
+	 * register.
+	 */
+	writel_relaxed(0x0, GCC_REG_BASE(APCS_CLOCK_SLEEP_ENA_VOTE));
+
+	/*
+	 * TODO: The following sequence enables the LPASS audio core GDSC.
+	 * Remove when this becomes unnecessary.
+	 */
+
+	/*
+	 * Disable HW trigger: collapse/restore occur based on registers writes.
+	 * Disable SW override: Use hardware state-machine for sequencing.
+	 */
+	regval = readl_relaxed(LPASS_REG_BASE(AUDIO_CORE_GDSCR));
+	regval &= ~(HW_CONTROL_MASK | SW_OVERRIDE_MASK);
+
+	/* Configure wait time between states. */
+	regval &= ~(EN_REST_WAIT_MASK | EN_FEW_WAIT_MASK | CLK_DIS_WAIT_MASK);
+	regval |= EN_REST_WAIT_VAL | EN_FEW_WAIT_VAL | CLK_DIS_WAIT_VAL;
+	writel_relaxed(regval, LPASS_REG_BASE(AUDIO_CORE_GDSCR));
+
+	regval = readl_relaxed(LPASS_REG_BASE(AUDIO_CORE_GDSCR));
+	regval &= ~BIT(0);
+	writel_relaxed(regval, LPASS_REG_BASE(AUDIO_CORE_GDSCR));
+
+	ret = readl_poll_timeout(LPASS_REG_BASE(AUDIO_CORE_GDSCR), status,
+				status & PWR_ON_MASK, 50, GDSC_TIMEOUT_US);
+	WARN(ret, "LPASS Audio Core GDSC did not power on.\n");
+}
+
+static void __init msm8610_clock_post_init(void)
+{
+	/*
+	 * Hold an active set vote for CXO; this is because CXO is expected
+	 * to remain on whenever CPUs aren't power collapsed.
+	 */
+	clk_prepare_enable(&gcc_xo_a_clk_src.c);
+
+
+	/* Set rates for single-rate clocks. */
+	clk_set_rate(&usb_hs_system_clk_src.c,
+			usb_hs_system_clk_src.freq_tbl[0].freq_hz);
+	clk_set_rate(&pdm2_clk_src.c, pdm2_clk_src.freq_tbl[0].freq_hz);
+	clk_set_rate(&mclk0_clk_src.c, mclk0_clk_src.freq_tbl[0].freq_hz);
+	clk_set_rate(&mclk1_clk_src.c, mclk1_clk_src.freq_tbl[0].freq_hz);
+	clk_set_rate(&audio_core_slimbus_core_clk_src.c,
+			audio_core_slimbus_core_clk_src.freq_tbl[0].freq_hz);
+}
+
+#define GCC_CC_PHYS		0xFC400000
+#define GCC_CC_SIZE		SZ_16K
+
+#define MMSS_CC_PHYS		0xFD8C0000
+#define MMSS_CC_SIZE		SZ_256K
+
+#define LPASS_CC_PHYS		0xFE000000
+#define LPASS_CC_SIZE		SZ_256K
+
+#define APCS_GCC_CC_PHYS	0xF9011000
+#define APCS_GCC_CC_SIZE	SZ_4K
+
+#define APCS_KPSS_SH_PLL_PHYS	0xF9016000
+#define APCS_KPSS_SH_PLL_SIZE	SZ_64
+
+static void __init msm8610_clock_pre_init(void)
+{
+	virt_bases[GCC_BASE] = ioremap(GCC_CC_PHYS, GCC_CC_SIZE);
+	if (!virt_bases[GCC_BASE])
+		panic("clock-8610: Unable to ioremap GCC memory!");
+
+	virt_bases[MMSS_BASE] = ioremap(MMSS_CC_PHYS, MMSS_CC_SIZE);
+	if (!virt_bases[MMSS_BASE])
+		panic("clock-8610: Unable to ioremap MMSS_CC memory!");
+
+	virt_bases[LPASS_BASE] = ioremap(LPASS_CC_PHYS, LPASS_CC_SIZE);
+	if (!virt_bases[LPASS_BASE])
+		panic("clock-8610: Unable to ioremap LPASS_CC memory!");
+
+	virt_bases[APCS_BASE] = ioremap(APCS_GCC_CC_PHYS, APCS_GCC_CC_SIZE);
+	if (!virt_bases[APCS_BASE])
+		panic("clock-8610: Unable to ioremap APCS_GCC_CC memory!");
+
+	virt_bases[APCS_PLL_BASE] = ioremap(APCS_KPSS_SH_PLL_PHYS,
+		APCS_KPSS_SH_PLL_SIZE);
+	if (!virt_bases[APCS_PLL_BASE])
+		panic("clock-8610: Unable to ioremap APCS_GCC_CC memory!");
+
+	clk_ops_local_pll.enable = sr_hpm_lp_pll_clk_enable;
+
+	vdd_dig_reg = regulator_get(NULL, "vdd_dig");
+	if (IS_ERR(vdd_dig_reg))
+		panic("clock-8610: Unable to get the vdd_dig regulator!");
+
+	vdd_sr2_reg = regulator_get(NULL, "vdd_sr2_pll");
+	if (IS_ERR(vdd_sr2_reg))
+		panic("clock-8610: Unable to get the vdd_sr2_pll regulator!");
+
+	regulator_set_voltage(vdd_sr2_reg, 1800000, 1800000);
+	regulator_enable(vdd_sr2_reg);
+
+	/*
+	 * TODO: Set a voltage and enable vdd_dig, leaving the voltage high
+	 * until late_init. This may not be necessary with clock handoff;
+	 * Investigate this code on a real non-simulator target to determine
+	 * its necessity.
+	 */
+	vote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
+	regulator_enable(vdd_dig_reg);
+
+	enable_rpm_scaling();
+
+	/* Enable a clock to allow access to MMSS clock registers */
+	clk_prepare_enable(&gcc_mmss_noc_cfg_ahb_clk.c),
+
+	reg_init();
+
+	/* Maintain the max nominal frequency on the MMSSNOC AHB bus. */
+	clk_set_rate(&mmssnoc_ahb_a_clk.c,  40000000);
+	clk_prepare_enable(&mmssnoc_ahb_a_clk.c);
+
+	/* TODO: Remove this once the bus driver is in place */
+	clk_set_rate(&axi_clk_src.c, 200000000);
+	clk_prepare_enable(&mmss_s0_axi_clk.c);
+
+	/* TODO: Temporarily enable a clock to allow access to LPASS core
+	 * registers.
+	 */
+	clk_prepare_enable(&audio_core_ixfabric_clk.c);
+}
+
+static int __init msm8610_clock_late_init(void)
+{
+	return unvote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
+}
+
+struct clock_init_data msm8610_clock_init_data __initdata = {
+	.table = msm_clocks_8610,
+	.size = ARRAY_SIZE(msm_clocks_8610),
+	.pre_init = msm8610_clock_pre_init,
+	.post_init = msm8610_clock_post_init,
+	.late_init = msm8610_clock_late_init,
+};
diff --git a/arch/arm/mach-msm/clock-8910.c b/arch/arm/mach-msm/clock-8910.c
deleted file mode 100644
index c5541b4..0000000
--- a/arch/arm/mach-msm/clock-8910.c
+++ /dev/null
@@ -1,3443 +0,0 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/ctype.h>
-#include <linux/io.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/iopoll.h>
-
-#include <mach/rpm-regulator-smd.h>
-#include <mach/socinfo.h>
-#include <mach/rpm-smd.h>
-
-#include "clock-local2.h"
-#include "clock-pll.h"
-#include "clock-rpm.h"
-#include "clock-voter.h"
-#include "clock.h"
-
-enum {
-	GCC_BASE,
-	MMSS_BASE,
-	LPASS_BASE,
-	APCS_BASE,
-	N_BASES,
-};
-
-static void __iomem *virt_bases[N_BASES];
-
-#define GCC_REG_BASE(x) (void __iomem *)(virt_bases[GCC_BASE] + (x))
-#define MMSS_REG_BASE(x) (void __iomem *)(virt_bases[MMSS_BASE] + (x))
-#define LPASS_REG_BASE(x) (void __iomem *)(virt_bases[LPASS_BASE] + (x))
-#define APCS_REG_BASE(x) (void __iomem *)(virt_bases[APCS_BASE] + (x))
-
-#define                     GPLL0_MODE	    0x0000
-#define                    GPLL0_L_VAL	    0x0004
-#define                    GPLL0_M_VAL	    0x0008
-#define                    GPLL0_N_VAL	    0x000C
-#define                 GPLL0_USER_CTL	    0x0010
-#define                   GPLL0_STATUS	    0x001C
-#define                     GPLL2_MODE	    0x0080
-#define                    GPLL2_L_VAL	    0x0084
-#define                    GPLL2_M_VAL	    0x0088
-#define                    GPLL2_N_VAL	    0x008C
-#define                 GPLL2_USER_CTL	    0x0090
-#define                   GPLL2_STATUS	    0x009C
-#define                 CONFIG_NOC_BCR	    0x0140
-#define                       MMSS_BCR	    0x0240
-#define          MMSS_NOC_CFG_AHB_CBCR	    0x024C
-#define               MSS_CFG_AHB_CBCR	    0x0280
-#define           MSS_Q6_BIMC_AXI_CBCR	    0x0284
-#define                     USB_HS_BCR	    0x0480
-#define             USB_HS_SYSTEM_CBCR	    0x0484
-#define                USB_HS_AHB_CBCR	    0x0488
-#define         USB_HS_SYSTEM_CMD_RCGR	    0x0490
-#define                  USB2A_PHY_BCR	    0x04A8
-#define           USB2A_PHY_SLEEP_CBCR	    0x04AC
-#define                      SDCC1_BCR	    0x04C0
-#define            SDCC1_APPS_CMD_RCGR	    0x04D0
-#define                SDCC1_APPS_CBCR	    0x04C4
-#define                 SDCC1_AHB_CBCR	    0x04C8
-#define                      SDCC2_BCR	    0x0500
-#define            SDCC2_APPS_CMD_RCGR	    0x0510
-#define                SDCC2_APPS_CBCR	    0x0504
-#define                 SDCC2_AHB_CBCR	    0x0508
-#define                      BLSP1_BCR	    0x05C0
-#define                 BLSP1_AHB_CBCR	    0x05C4
-#define                 BLSP1_QUP1_BCR	    0x0640
-#define       BLSP1_QUP1_SPI_APPS_CBCR	    0x0644
-#define       BLSP1_QUP1_I2C_APPS_CBCR	    0x0648
-#define   BLSP1_QUP1_SPI_APPS_CMD_RCGR	    0x064C
-#define                BLSP1_UART1_BCR	    0x0680
-#define          BLSP1_UART1_APPS_CBCR	    0x0684
-#define           BLSP1_UART1_SIM_CBCR	    0x0688
-#define      BLSP1_UART1_APPS_CMD_RCGR	    0x068C
-#define                 BLSP1_QUP2_BCR	    0x06C0
-#define       BLSP1_QUP2_SPI_APPS_CBCR	    0x06C4
-#define       BLSP1_QUP2_I2C_APPS_CBCR	    0x06C8
-#define   BLSP1_QUP2_SPI_APPS_CMD_RCGR	    0x06CC
-#define                BLSP1_UART2_BCR	    0x0700
-#define          BLSP1_UART2_APPS_CBCR	    0x0704
-#define           BLSP1_UART2_SIM_CBCR	    0x0708
-#define      BLSP1_UART2_APPS_CMD_RCGR	    0x070C
-#define                 BLSP1_QUP3_BCR	    0x0740
-#define       BLSP1_QUP3_SPI_APPS_CBCR	    0x0744
-#define       BLSP1_QUP3_I2C_APPS_CBCR	    0x0748
-#define   BLSP1_QUP3_SPI_APPS_CMD_RCGR	    0x074C
-#define                BLSP1_UART3_BCR	    0x0780
-#define          BLSP1_UART3_APPS_CBCR	    0x0784
-#define           BLSP1_UART3_SIM_CBCR	    0x0788
-#define      BLSP1_UART3_APPS_CMD_RCGR	    0x078C
-#define                 BLSP1_QUP4_BCR	    0x07C0
-#define       BLSP1_QUP4_SPI_APPS_CBCR	    0x07C4
-#define       BLSP1_QUP4_I2C_APPS_CBCR	    0x07C8
-#define   BLSP1_QUP4_SPI_APPS_CMD_RCGR	    0x07CC
-#define                BLSP1_UART4_BCR	    0x0800
-#define          BLSP1_UART4_APPS_CBCR	    0x0804
-#define           BLSP1_UART4_SIM_CBCR	    0x0808
-#define      BLSP1_UART4_APPS_CMD_RCGR	    0x080C
-#define                 BLSP1_QUP5_BCR	    0x0840
-#define       BLSP1_QUP5_SPI_APPS_CBCR	    0x0844
-#define       BLSP1_QUP5_I2C_APPS_CBCR	    0x0848
-#define   BLSP1_QUP5_SPI_APPS_CMD_RCGR	    0x084C
-#define                BLSP1_UART5_BCR	    0x0880
-#define          BLSP1_UART5_APPS_CBCR	    0x0884
-#define           BLSP1_UART5_SIM_CBCR	    0x0888
-#define      BLSP1_UART5_APPS_CMD_RCGR	    0x088C
-#define                 BLSP1_QUP6_BCR	    0x08C0
-#define       BLSP1_QUP6_SPI_APPS_CBCR	    0x08C4
-#define       BLSP1_QUP6_I2C_APPS_CBCR	    0x08C8
-#define   BLSP1_QUP6_SPI_APPS_CMD_RCGR	    0x08CC
-#define                BLSP1_UART6_BCR	    0x0900
-#define          BLSP1_UART6_APPS_CBCR	    0x0904
-#define           BLSP1_UART6_SIM_CBCR	    0x0908
-#define      BLSP1_UART6_APPS_CMD_RCGR	    0x090C
-#define                        PDM_BCR	    0x0CC0
-#define                   PDM_AHB_CBCR	    0x0CC4
-#define                      PDM2_CBCR	    0x0CCC
-#define                  PDM2_CMD_RCGR	    0x0CD0
-#define                       PRNG_BCR	    0x0D00
-#define                  PRNG_AHB_CBCR	    0x0D04
-#define                   BOOT_ROM_BCR	    0x0E00
-#define              BOOT_ROM_AHB_CBCR	    0x0E04
-#define                        CE1_BCR	    0x1040
-#define                   CE1_CMD_RCGR	    0x1050
-#define                       CE1_CBCR	    0x1044
-#define                   CE1_AXI_CBCR	    0x1048
-#define                   CE1_AHB_CBCR	    0x104C
-#define            COPSS_SMMU_AHB_CBCR      0x015C
-#define             LPSS_SMMU_AHB_CBCR      0x0158
-#define              LPASS_Q6_AXI_CBCR	    0x11C0
-#define             APCS_GPLL_ENA_VOTE	    0x1480
-#define     APCS_CLOCK_BRANCH_ENA_VOTE	    0x1484
-#define      APCS_CLOCK_SLEEP_ENA_VOTE	    0x1488
-#define                       GP1_CBCR	    0x1900
-#define                   GP1_CMD_RCGR	    0x1904
-#define                       GP2_CBCR	    0x1940
-#define                   GP2_CMD_RCGR	    0x1944
-#define                       GP3_CBCR	    0x1980
-#define                   GP3_CMD_RCGR	    0x1984
-#define                        XO_CBCR	    0x0034
-
-#define                MMPLL0_PLL_MODE	    0x0000
-#define               MMPLL0_PLL_L_VAL	    0x0004
-#define               MMPLL0_PLL_M_VAL	    0x0008
-#define               MMPLL0_PLL_N_VAL	    0x000C
-#define            MMPLL0_PLL_USER_CTL	    0x0010
-#define              MMPLL0_PLL_STATUS	    0x001C
-#define         MMSS_PLL_VOTE_APCS_REG      0x0100
-#define                MMPLL1_PLL_MODE	    0x4100
-#define               MMPLL1_PLL_L_VAL	    0x4104
-#define               MMPLL1_PLL_M_VAL	    0x4108
-#define               MMPLL1_PLL_N_VAL	    0x410C
-#define            MMPLL1_PLL_USER_CTL	    0x4110
-#define              MMPLL1_PLL_STATUS	    0x411C
-#define              DSI_PCLK_CMD_RCGR	    0x2000
-#define                   DSI_CMD_RCGR	    0x2020
-#define             MDP_VSYNC_CMD_RCGR	    0x2080
-#define              DSI_BYTE_CMD_RCGR	    0x2120
-#define               DSI_ESC_CMD_RCGR	    0x2160
-#define                        DSI_BCR	    0x2200
-#define                   DSI_BYTE_BCR	    0x2204
-#define                    DSI_ESC_BCR	    0x2208
-#define                    DSI_AHB_BCR	    0x220C
-#define                   DSI_PCLK_BCR	    0x2214
-#define                   MDP_LCDC_BCR	    0x2218
-#define                    MDP_DSI_BCR	    0x221C
-#define                  MDP_VSYNC_BCR	    0x2220
-#define                    MDP_AXI_BCR	    0x2224
-#define                    MDP_AHB_BCR	    0x2228
-#define                   MDP_AXI_CBCR	    0x2314
-#define                 MDP_VSYNC_CBCR	    0x231C
-#define                   MDP_AHB_CBCR	    0x2318
-#define                  DSI_PCLK_CBCR	    0x233C
-#define                GMEM_GFX3D_CBCR      0x4038
-#define                  MDP_LCDC_CBCR	    0x2340
-#define                   MDP_DSI_CBCR	    0x2320
-#define                       DSI_CBCR	    0x2324
-#define                  DSI_BYTE_CBCR	    0x2328
-#define                   DSI_ESC_CBCR	    0x232C
-#define                   DSI_AHB_CBCR	    0x2330
-#define          CSI0PHYTIMER_CMD_RCGR	    0x3000
-#define               CSI0PHYTIMER_BCR	    0x3020
-#define              CSI0PHYTIMER_CBCR	    0x3024
-#define          CSI1PHYTIMER_CMD_RCGR	    0x3030
-#define               CSI1PHYTIMER_BCR	    0x3050
-#define              CSI1PHYTIMER_CBCR	    0x3054
-#define                  CSI0_CMD_RCGR	    0x3090
-#define                       CSI0_BCR	    0x30B0
-#define                      CSI0_CBCR	    0x30B4
-#define                    CSI_AHB_BCR	    0x30B8
-#define                   CSI_AHB_CBCR	    0x30BC
-#define                    CSI0PHY_BCR	    0x30C0
-#define                   CSI0PHY_CBCR	    0x30C4
-#define                    CSI0RDI_BCR	    0x30D0
-#define                   CSI0RDI_CBCR	    0x30D4
-#define                    CSI0PIX_BCR	    0x30E0
-#define                   CSI0PIX_CBCR	    0x30E4
-#define                  CSI1_CMD_RCGR	    0x3100
-#define                       CSI1_BCR	    0x3120
-#define                      CSI1_CBCR	    0x3124
-#define                    CSI1PHY_BCR	    0x3130
-#define                   CSI1PHY_CBCR	    0x3134
-#define                    CSI1RDI_BCR	    0x3140
-#define                   CSI1RDI_CBCR	    0x3144
-#define                    CSI1PIX_BCR	    0x3150
-#define                   CSI1PIX_CBCR	    0x3154
-#define                 MCLK0_CMD_RCGR	    0x3360
-#define                      MCLK0_BCR	    0x3380
-#define                     MCLK0_CBCR	    0x3384
-#define                 MCLK1_CMD_RCGR	    0x3390
-#define                      MCLK1_BCR	    0x33B0
-#define                     MCLK1_CBCR	    0x33B4
-#define                   VFE_CMD_RCGR	    0x3600
-#define                        VFE_BCR	    0x36A0
-#define                    VFE_AHB_BCR	    0x36AC
-#define                    VFE_AXI_BCR	    0x36B0
-#define                       VFE_CBCR	    0x36A8
-#define                   VFE_AHB_CBCR	    0x36B8
-#define                   VFE_AXI_CBCR	    0x36BC
-#define                    CSI_VFE_BCR	    0x3700
-#define                   CSI_VFE_CBCR	    0x3704
-#define                 GFX3D_CMD_RCGR	    0x4000
-#define               OXILI_GFX3D_CBCR	    0x4028
-#define                OXILI_GFX3D_BCR	    0x4030
-#define                  OXILI_AHB_BCR	    0x4044
-#define                 OXILI_AHB_CBCR	    0x403C
-#define                   AHB_CMD_RCGR	    0x5000
-#define                 MMSSNOCAHB_BCR	    0x5020
-#define             MMSSNOCAHB_BTO_BCR	    0x5030
-#define              MMSS_MISC_AHB_BCR	    0x5034
-#define          MMSS_MMSSNOC_AHB_CBCR	    0x5024
-#define      MMSS_MMSSNOC_BTO_AHB_CBCR	    0x5028
-#define             MMSS_MISC_AHB_CBCR	    0x502C
-#define                   AXI_CMD_RCGR	    0x5040
-#define                 MMSSNOCAXI_BCR	    0x5060
-#define                MMSS_S0_AXI_BCR	    0x5068
-#define               MMSS_S0_AXI_CBCR	    0x5064
-#define          MMSS_MMSSNOC_AXI_CBCR	    0x506C
-#define                   BIMC_GFX_BCR	    0x5090
-#define                  BIMC_GFX_CBCR	    0x5094
-
-#define				AUDIO_CORE_GDSCR	    0x7000
-#define                                 SPDM_BCR	    0x1000
-#define                        LPAAUDIO_PLL_MODE	    0x0000
-#define                       LPAAUDIO_PLL_L_VAL	    0x0004
-#define                       LPAAUDIO_PLL_M_VAL	    0x0008
-#define                       LPAAUDIO_PLL_N_VAL	    0x000C
-#define                    LPAAUDIO_PLL_USER_CTL	    0x0010
-#define                      LPAAUDIO_PLL_STATUS	    0x001C
-#define                           LPAQ6_PLL_MODE	    0x1000
-#define                       LPAQ6_PLL_USER_CTL	    0x1010
-#define                         LPAQ6_PLL_STATUS	    0x101C
-#define                        LPA_PLL_VOTE_APPS            0x2000
-#define                  AUDIO_CORE_BCR_SLP_CBCR	    0x4004
-#define                        Q6SS_BCR_SLP_CBCR	    0x6004
-#define                  AUDIO_CORE_GDSC_XO_CBCR	    0x7004
-#define                AUDIO_CORE_LPAIF_DMA_CBCR	    0x9000
-#define                AUDIO_CORE_LPAIF_CSR_CBCR	    0x9004
-#define                      LPAIF_SPKR_CMD_RCGR	    0xA000
-#define     AUDIO_CORE_LPAIF_CODEC_SPKR_OSR_CBCR	    0xA014
-#define    AUDIO_CORE_LPAIF_CODEC_SPKR_IBIT_CBCR	    0xA018
-#define    AUDIO_CORE_LPAIF_CODEC_SPKR_EBIT_CBCR	    0xA01C
-#define                       LPAIF_PRI_CMD_RCGR	    0xB000
-#define            AUDIO_CORE_LPAIF_PRI_OSR_CBCR	    0xB014
-#define           AUDIO_CORE_LPAIF_PRI_IBIT_CBCR	    0xB018
-#define           AUDIO_CORE_LPAIF_PRI_EBIT_CBCR	    0xB01C
-#define                       LPAIF_SEC_CMD_RCGR	    0xC000
-#define            AUDIO_CORE_LPAIF_SEC_OSR_CBCR	    0xC014
-#define           AUDIO_CORE_LPAIF_SEC_IBIT_CBCR	    0xC018
-#define           AUDIO_CORE_LPAIF_SEC_EBIT_CBCR	    0xC01C
-#define                       LPAIF_TER_CMD_RCGR	    0xD000
-#define            AUDIO_CORE_LPAIF_TER_OSR_CBCR	    0xD014
-#define           AUDIO_CORE_LPAIF_TER_IBIT_CBCR	    0xD018
-#define           AUDIO_CORE_LPAIF_TER_EBIT_CBCR	    0xD01C
-#define                      LPAIF_QUAD_CMD_RCGR	    0xE000
-#define           AUDIO_CORE_LPAIF_QUAD_OSR_CBCR	    0xE014
-#define          AUDIO_CORE_LPAIF_QUAD_IBIT_CBCR	    0xE018
-#define          AUDIO_CORE_LPAIF_QUAD_EBIT_CBCR	    0xE01C
-#define                      LPAIF_PCM0_CMD_RCGR	    0xF000
-#define          AUDIO_CORE_LPAIF_PCM0_IBIT_CBCR	    0xF014
-#define          AUDIO_CORE_LPAIF_PCM0_EBIT_CBCR	    0xF018
-#define                      LPAIF_PCM1_CMD_RCGR	   0x10000
-#define          AUDIO_CORE_LPAIF_PCM1_IBIT_CBCR	   0x10014
-#define          AUDIO_CORE_LPAIF_PCM1_EBIT_CBCR	   0x10018
-#define                         SLIMBUS_CMD_RCGR           0x12000
-#define             AUDIO_CORE_SLIMBUS_CORE_CBCR           0x12014
-#define                     LPAIF_PCMOE_CMD_RCGR	   0x13000
-#define        AUDIO_CORE_LPAIF_PCM_DATA_OE_CBCR	   0x13014
-#define                          Q6CORE_CMD_RCGR	   0x14000
-#define                           SLEEP_CMD_RCGR	   0x15000
-#define                            SPDM_CMD_RCGR	   0x16000
-#define                  AUDIO_WRAPPER_SPDM_CBCR	   0x16014
-#define                              XO_CMD_RCGR	   0x17000
-#define                       AHBFABRIC_CMD_RCGR	   0x18000
-#define                      AUDIO_CORE_LPM_CBCR	   0x19000
-#define               AUDIO_CORE_AVSYNC_CSR_CBCR	   0x1A000
-#define                AUDIO_CORE_AVSYNC_XO_CBCR	   0x1A004
-#define             AUDIO_CORE_AVSYNC_BT_XO_CBCR	   0x1A008
-#define             AUDIO_CORE_AVSYNC_FM_XO_CBCR	   0x1A00C
-#define                 AUDIO_CORE_IXFABRIC_CBCR	   0x1B000
-#define               AUDIO_WRAPPER_EFABRIC_CBCR	   0x1B004
-#define                AUDIO_CORE_TCM_SLAVE_CBCR	   0x1C000
-#define                      AUDIO_CORE_CSR_CBCR	   0x1D000
-#define                      AUDIO_CORE_DML_CBCR	   0x1E000
-#define                   AUDIO_CORE_SYSNOC_CBCR	   0x1F000
-#define           AUDIO_WRAPPER_SYSNOC_SWAY_CBCR	   0x1F004
-#define                  AUDIO_CORE_TIMEOUT_CBCR	   0x20000
-#define               AUDIO_WRAPPER_TIMEOUT_CBCR	   0x20004
-#define                 AUDIO_CORE_SECURITY_CBCR	   0x21000
-#define              AUDIO_WRAPPER_SECURITY_CBCR	   0x21004
-#define                     Q6SS_AHB_LFABIF_CBCR	   0x22000
-#define                           Q6SS_AHBM_CBCR	   0x22004
-#define               AUDIO_WRAPPER_LCC_CSR_CBCR	   0x23000
-#define                    AUDIO_WRAPPER_BR_CBCR	   0x24000
-#define                  AUDIO_WRAPPER_SMEM_CBCR	   0x25000
-#define                             Q6SS_XO_CBCR	   0x26000
-#define                            Q6SS_SLP_CBCR	   0x26004
-#define                           LPASS_Q6SS_BCR           0x6000
-#define                AUDIO_WRAPPER_STM_XO_CBCR	   0x27000
-#define      AUDIO_CORE_IXFABRIC_SPDMTM_CSR_CBCR	   0x28000
-#define    AUDIO_WRAPPER_EFABRIC_SPDMTM_CSR_CBCR	   0x28004
-
-/* Mux source select values */
-#define        gcc_xo_source_val 0
-#define         gpll0_source_val 1
-#define           gnd_source_val 5
-#define     mmpll0_mm_source_val 1
-#define     mmpll1_mm_source_val 2
-#define      gpll0_mm_source_val 5
-#define     gcc_xo_mm_source_val 0
-#define        mm_gnd_source_val 6
-#define     cxo_lpass_source_val 0
-#define lpapll0_lpass_source_val 1
-#define   gpll0_lpass_source_val 5
-#define     dsipll_mm_source_val 1
-
-#define F(f, s, div, m, n) \
-	{ \
-		.freq_hz = (f), \
-		.src_clk = &s##_clk_src.c, \
-		.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##_source_val), \
-	}
-
-#define F_MM(f, s, div, m, n) \
-	{ \
-		.freq_hz = (f), \
-		.src_clk = &s##_clk_src.c, \
-		.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_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_MDSS(f, s, div, m, n) \
-	{ \
-		.freq_hz = (f), \
-		.m_val = (m), \
-		.n_val = ~((n)-(m)) * !!(n), \
-		.d_val = ~(n),\
-		.div_src_val = BVAL(4, 0, (int)(2*(div) - 1)) \
-			| BVAL(10, 8, s##_mm_source_val), \
-	}
-
-#define F_LPASS(f, s, div, m, n) \
-	{ \
-		.freq_hz = (f), \
-		.src_clk = &s##_clk_src.c, \
-		.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##_lpass_source_val), \
-	}
-
-#define VDD_DIG_FMAX_MAP1(l1, f1) \
-	.vdd_class = &vdd_dig,			\
-	.fmax = (unsigned long[VDD_DIG_NUM]) {	\
-		[VDD_DIG_##l1] = (f1),		\
-	},					\
-	.num_fmax = VDD_DIG_NUM
-#define VDD_DIG_FMAX_MAP2(l1, f1, l2, f2) \
-	.vdd_class = &vdd_dig,			\
-	.fmax = (unsigned long[VDD_DIG_NUM]) {	\
-		[VDD_DIG_##l1] = (f1),		\
-		[VDD_DIG_##l2] = (f2),		\
-	},					\
-	.num_fmax = VDD_DIG_NUM
-#define VDD_DIG_FMAX_MAP3(l1, f1, l2, f2, l3, f3) \
-	.vdd_class = &vdd_dig,			\
-	.fmax = (unsigned long[VDD_DIG_NUM]) {	\
-		[VDD_DIG_##l1] = (f1),		\
-		[VDD_DIG_##l2] = (f2),		\
-		[VDD_DIG_##l3] = (f3),		\
-	},					\
-	.num_fmax = VDD_DIG_NUM
-
-enum vdd_dig_levels {
-	VDD_DIG_NONE,
-	VDD_DIG_LOW,
-	VDD_DIG_NOMINAL,
-	VDD_DIG_HIGH,
-	VDD_DIG_NUM
-};
-
-static const int vdd_corner[] = {
-	[VDD_DIG_NONE]	  = RPM_REGULATOR_CORNER_NONE,
-	[VDD_DIG_LOW]	  = RPM_REGULATOR_CORNER_SVS_SOC,
-	[VDD_DIG_NOMINAL] = RPM_REGULATOR_CORNER_NORMAL,
-	[VDD_DIG_HIGH]	  = RPM_REGULATOR_CORNER_SUPER_TURBO,
-};
-
-static struct rpm_regulator *vdd_dig_reg;
-
-static int set_vdd_dig(struct clk_vdd_class *vdd_class, int level)
-{
-	return rpm_regulator_set_voltage(vdd_dig_reg, vdd_corner[level],
-					RPM_REGULATOR_CORNER_SUPER_TURBO);
-}
-
-static DEFINE_VDD_CLASS(vdd_dig, set_vdd_dig, VDD_DIG_NUM);
-
-#define RPM_MISC_CLK_TYPE	0x306b6c63
-#define RPM_BUS_CLK_TYPE	0x316b6c63
-#define RPM_MEM_CLK_TYPE	0x326b6c63
-
-#define RPM_SMD_KEY_ENABLE	0x62616E45
-
-#define CXO_ID			0x0
-#define QDSS_ID			0x1
-#define RPM_SCALING_ENABLE_ID	0x2
-
-#define PNOC_ID		0x0
-#define SNOC_ID		0x1
-#define CNOC_ID		0x2
-#define MMSSNOC_AHB_ID  0x3
-
-#define BIMC_ID		0x0
-#define OXILI_ID	0x1
-#define OCMEM_ID	0x2
-
-#define D0_ID		 1
-#define D1_ID		 2
-#define A0_ID		 3
-#define A1_ID		 4
-#define A2_ID		 5
-#define DIFF_CLK_ID	 7
-#define DIV_CLK_ID	11
-
-DEFINE_CLK_RPM_SMD(pnoc_clk, pnoc_a_clk, RPM_BUS_CLK_TYPE, PNOC_ID, NULL);
-DEFINE_CLK_RPM_SMD(snoc_clk, snoc_a_clk, RPM_BUS_CLK_TYPE, SNOC_ID, NULL);
-DEFINE_CLK_RPM_SMD(cnoc_clk, cnoc_a_clk, RPM_BUS_CLK_TYPE, CNOC_ID, NULL);
-DEFINE_CLK_RPM_SMD(mmssnoc_ahb_clk, mmssnoc_ahb_a_clk, RPM_BUS_CLK_TYPE,
-			MMSSNOC_AHB_ID, NULL);
-
-DEFINE_CLK_RPM_SMD(bimc_clk, bimc_a_clk, RPM_MEM_CLK_TYPE, BIMC_ID, NULL);
-
-DEFINE_CLK_RPM_SMD_BRANCH(gcc_xo_clk_src, gcc_xo_a_clk_src,
-				RPM_MISC_CLK_TYPE, CXO_ID, 19200000);
-DEFINE_CLK_RPM_SMD_QDSS(qdss_clk, qdss_a_clk, RPM_MISC_CLK_TYPE, QDSS_ID);
-
-DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_d0, cxo_d0_a, D0_ID);
-DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_d1, cxo_d1_a, D1_ID);
-DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_a0, cxo_a0_a, A0_ID);
-DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_a1, cxo_a1_a, A1_ID);
-DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_a2, cxo_a2_a, A2_ID);
-DEFINE_CLK_RPM_SMD_XO_BUFFER(div_clk, div_a_clk, DIV_CLK_ID);
-DEFINE_CLK_RPM_SMD_XO_BUFFER(diff_clk, diff_a_clk, DIFF_CLK_ID);
-
-DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_d0_pin, cxo_d0_a_pin, D0_ID);
-DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_d1_pin, cxo_d1_a_pin, D1_ID);
-DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_a0_pin, cxo_a0_a_pin, A0_ID);
-DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_a1_pin, cxo_a1_a_pin, A1_ID);
-DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_a2_pin, cxo_a2_a_pin, A2_ID);
-
-static DEFINE_CLK_VOTER(pnoc_msmbus_clk, &pnoc_clk.c, LONG_MAX);
-static DEFINE_CLK_VOTER(snoc_msmbus_clk, &snoc_clk.c, LONG_MAX);
-static DEFINE_CLK_VOTER(cnoc_msmbus_clk, &cnoc_clk.c, LONG_MAX);
-static DEFINE_CLK_VOTER(pnoc_msmbus_a_clk, &pnoc_a_clk.c, LONG_MAX);
-static DEFINE_CLK_VOTER(snoc_msmbus_a_clk, &snoc_a_clk.c, LONG_MAX);
-static DEFINE_CLK_VOTER(cnoc_msmbus_a_clk, &cnoc_a_clk.c, LONG_MAX);
-
-static DEFINE_CLK_VOTER(bimc_msmbus_clk, &bimc_clk.c, LONG_MAX);
-static DEFINE_CLK_VOTER(bimc_msmbus_a_clk, &bimc_a_clk.c, LONG_MAX);
-static DEFINE_CLK_VOTER(bimc_acpu_a_clk, &bimc_a_clk.c, LONG_MAX);
-
-static DEFINE_CLK_VOTER(pnoc_sps_clk, &pnoc_clk.c, LONG_MAX);
-static DEFINE_CLK_VOTER(pnoc_iommu_clk, &pnoc_clk.c, LONG_MAX);
-static DEFINE_CLK_VOTER(pnoc_qseecom_clk, &pnoc_clk.c, LONG_MAX);
-
-static struct pll_vote_clk gpll0_clk_src = {
-	.en_reg = (void __iomem *)APCS_GPLL_ENA_VOTE,
-	.en_mask = BIT(0),
-	.status_reg = (void __iomem *)GPLL0_STATUS,
-	.status_mask = BIT(17),
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.parent = &gcc_xo_clk_src.c,
-		.rate = 600000000,
-		.dbg_name = "gpll0_clk_src",
-		.ops = &clk_ops_pll_vote,
-		CLK_INIT(gpll0_clk_src.c),
-	},
-};
-
-static struct pll_vote_clk mmpll0_clk_src = {
-	.en_reg = (void __iomem *)MMSS_PLL_VOTE_APCS_REG,
-	.en_mask = BIT(0),
-	.status_reg = (void __iomem *)MMPLL0_PLL_STATUS,
-	.status_mask = BIT(17),
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &gcc_xo_clk_src.c,
-		.dbg_name = "mmpll0_clk_src",
-		.rate = 800000000,
-		.ops = &clk_ops_pll_vote,
-		CLK_INIT(mmpll0_clk_src.c),
-	},
-};
-
-static struct pll_config_regs mmpll0_regs __initdata = {
-	.l_reg = (void __iomem *)MMPLL0_PLL_L_VAL,
-	.m_reg = (void __iomem *)MMPLL0_PLL_M_VAL,
-	.n_reg = (void __iomem *)MMPLL0_PLL_N_VAL,
-	.config_reg = (void __iomem *)MMPLL0_PLL_USER_CTL,
-	.mode_reg = (void __iomem *)MMPLL0_PLL_MODE,
-	.base = &virt_bases[MMSS_BASE],
-};
-
-static struct pll_clk mmpll1_clk_src = {
-	.mode_reg = (void __iomem *)MMPLL1_PLL_MODE,
-	.status_reg = (void __iomem *)MMPLL1_PLL_STATUS,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &gcc_xo_clk_src.c,
-		.dbg_name = "mmpll1_clk_src",
-		.rate = 1200000000,
-		.ops = &clk_ops_local_pll,
-		CLK_INIT(mmpll1_clk_src.c),
-	},
-};
-
-static struct pll_config_regs mmpll1_regs __initdata = {
-	.l_reg = (void __iomem *)MMPLL1_PLL_L_VAL,
-	.m_reg = (void __iomem *)MMPLL1_PLL_M_VAL,
-	.n_reg = (void __iomem *)MMPLL1_PLL_N_VAL,
-	.config_reg = (void __iomem *)MMPLL1_PLL_USER_CTL,
-	.mode_reg = (void __iomem *)MMPLL1_PLL_MODE,
-	.base = &virt_bases[MMSS_BASE],
-};
-
-static struct pll_vote_clk lpapll0_clk_src = {
-	.en_reg = (void __iomem *)LPA_PLL_VOTE_APPS,
-	.en_mask = BIT(0),
-	.status_reg = (void __iomem *)LPAAUDIO_PLL_STATUS,
-	.status_mask = BIT(17),
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &gcc_xo_clk_src.c,
-		.rate = 491520000,
-		.dbg_name = "lpapll0_clk_src",
-		.ops = &clk_ops_pll_vote,
-		CLK_INIT(lpapll0_clk_src.c),
-	},
-};
-
-static struct clk_freq_tbl ftbl_gcc_blsp1_qup1_6_spi_apps_clk[] = {
-	F(  960000, gcc_xo, 10, 1, 2),
-	F( 4800000, gcc_xo,  4, 0, 0),
-	F( 9600000, gcc_xo,  2, 0, 0),
-	F(15000000,  gpll0, 10, 1, 4),
-	F(19200000, gcc_xo,  1, 0, 0),
-	F(25000000,  gpll0, 12, 1, 2),
-	F(50000000,  gpll0, 12, 0, 0),
-	F_END,
-};
-
-static struct rcg_clk blsp1_qup1_spi_apps_clk_src = {
-	.cmd_rcgr_reg =  BLSP1_QUP1_SPI_APPS_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "blsp1_qup1_spi_apps_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
-		CLK_INIT(blsp1_qup1_spi_apps_clk_src.c),
-	},
-};
-
-static struct rcg_clk blsp1_qup2_spi_apps_clk_src = {
-	.cmd_rcgr_reg =  BLSP1_QUP2_SPI_APPS_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "blsp1_qup2_spi_apps_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
-		CLK_INIT(blsp1_qup2_spi_apps_clk_src.c),
-	},
-};
-
-static struct rcg_clk blsp1_qup3_spi_apps_clk_src = {
-	.cmd_rcgr_reg =  BLSP1_QUP3_SPI_APPS_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "blsp1_qup3_spi_apps_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
-		CLK_INIT(blsp1_qup3_spi_apps_clk_src.c),
-	},
-};
-
-static struct rcg_clk blsp1_qup4_spi_apps_clk_src = {
-	.cmd_rcgr_reg =  BLSP1_QUP4_SPI_APPS_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "blsp1_qup4_spi_apps_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
-		CLK_INIT(blsp1_qup4_spi_apps_clk_src.c),
-	},
-};
-
-static struct rcg_clk blsp1_qup5_spi_apps_clk_src = {
-	.cmd_rcgr_reg =  BLSP1_QUP5_SPI_APPS_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "blsp1_qup5_spi_apps_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
-		CLK_INIT(blsp1_qup5_spi_apps_clk_src.c),
-	},
-};
-
-static struct rcg_clk blsp1_qup6_spi_apps_clk_src = {
-	.cmd_rcgr_reg =  BLSP1_QUP6_SPI_APPS_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "blsp1_qup6_spi_apps_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
-		CLK_INIT(blsp1_qup6_spi_apps_clk_src.c),
-	},
-};
-
-static struct clk_freq_tbl ftbl_gcc_blsp1_uart1_6_apps_clk[] = {
-	F( 3686400,  gpll0,    1,   96, 15625),
-	F( 7372800,  gpll0,    1,  192, 15625),
-	F(14745600,  gpll0,    1,  384, 15625),
-	F(16000000,  gpll0,    5,    2,    15),
-	F(19200000, gcc_xo,    1,    0,     0),
-	F(24000000,  gpll0,    5,    1,     5),
-	F(32000000,  gpll0,    1,    4,    75),
-	F(40000000,  gpll0,   15,    0,     0),
-	F(46400000,  gpll0,    1,   29,   375),
-	F(48000000,  gpll0, 12.5,    0,     0),
-	F(51200000,  gpll0,    1,   32,   375),
-	F(56000000,  gpll0,    1,    7,    75),
-	F(58982400,  gpll0,    1, 1536, 15625),
-	F(60000000,  gpll0,   10,    0,     0),
-	F_END,
-};
-
-static struct rcg_clk blsp1_uart1_apps_clk_src = {
-	.cmd_rcgr_reg =  BLSP1_UART1_APPS_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "blsp1_uart1_apps_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
-		CLK_INIT(blsp1_uart1_apps_clk_src.c),
-	},
-};
-
-static struct rcg_clk blsp1_uart2_apps_clk_src = {
-	.cmd_rcgr_reg =  BLSP1_UART2_APPS_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "blsp1_uart2_apps_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
-		CLK_INIT(blsp1_uart2_apps_clk_src.c),
-	},
-};
-
-static struct rcg_clk blsp1_uart3_apps_clk_src = {
-	.cmd_rcgr_reg =  BLSP1_UART3_APPS_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "blsp1_uart3_apps_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
-		CLK_INIT(blsp1_uart3_apps_clk_src.c),
-	},
-};
-
-static struct rcg_clk blsp1_uart4_apps_clk_src = {
-	.cmd_rcgr_reg =  BLSP1_UART4_APPS_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "blsp1_uart4_apps_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
-		CLK_INIT(blsp1_uart4_apps_clk_src.c),
-	},
-};
-
-static struct rcg_clk blsp1_uart5_apps_clk_src = {
-	.cmd_rcgr_reg =  BLSP1_UART5_APPS_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "blsp1_uart5_apps_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
-		CLK_INIT(blsp1_uart5_apps_clk_src.c),
-	},
-};
-
-static struct rcg_clk blsp1_uart6_apps_clk_src = {
-	.cmd_rcgr_reg =  BLSP1_UART6_APPS_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "blsp1_uart6_apps_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
-		CLK_INIT(blsp1_uart6_apps_clk_src.c),
-	},
-};
-
-static struct clk_freq_tbl ftbl_gcc_ce1_clk[] = {
-	F(50000000, gpll0, 12, 0, 0),
-	F(100000000, gpll0, 6, 0, 0),
-	F_END,
-};
-
-static struct rcg_clk ce1_clk_src = {
-	.cmd_rcgr_reg = CE1_CMD_RCGR,
-	.set_rate = set_rate_hid,
-	.freq_tbl = ftbl_gcc_ce1_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "ce1_clk_src",
-		.ops = &clk_ops_rcg,
-		VDD_DIG_FMAX_MAP2(LOW, 50000000, NOMINAL, 100000000),
-		CLK_INIT(ce1_clk_src.c),
-	},
-};
-
-static struct clk_freq_tbl ftbl_gcc_gp1_3_clk[] = {
-	F(19200000, gcc_xo, 1, 0, 0),
-	F_END,
-};
-
-static struct rcg_clk gp1_clk_src = {
-	.cmd_rcgr_reg =  GP1_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_gcc_gp1_3_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "gp1_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
-		CLK_INIT(gp1_clk_src.c),
-	},
-};
-
-static struct rcg_clk gp2_clk_src = {
-	.cmd_rcgr_reg =  GP2_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_gcc_gp1_3_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "gp2_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
-		CLK_INIT(gp2_clk_src.c),
-	},
-};
-
-static struct rcg_clk gp3_clk_src = {
-	.cmd_rcgr_reg =  GP3_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_gcc_gp1_3_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "gp3_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
-		CLK_INIT(gp3_clk_src.c),
-	},
-};
-
-static struct clk_freq_tbl ftbl_gcc_pdm2_clk[] = {
-	F(60000000, gpll0, 10, 0, 0),
-	F_END,
-};
-
-static struct rcg_clk pdm2_clk_src = {
-	.cmd_rcgr_reg = PDM2_CMD_RCGR,
-	.set_rate = set_rate_hid,
-	.freq_tbl = ftbl_gcc_pdm2_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "pdm2_clk_src",
-		.ops = &clk_ops_rcg,
-		VDD_DIG_FMAX_MAP1(LOW, 120000000),
-		CLK_INIT(pdm2_clk_src.c),
-	},
-};
-
-static struct clk_freq_tbl ftbl_gcc_sdcc1_2_apps_clk[] = {
-	F(   144000, gcc_xo, 16, 3, 25),
-	F(   400000, gcc_xo, 12, 1,  4),
-	F( 20000000,  gpll0, 15, 1,  2),
-	F( 25000000,  gpll0, 12, 1,  2),
-	F( 50000000,  gpll0, 12, 0,  0),
-	F(100000000,  gpll0,  6, 0,  0),
-	F(200000000,  gpll0,  3, 0,  0),
-	F_END,
-};
-
-static struct rcg_clk sdcc1_apps_clk_src = {
-	.cmd_rcgr_reg =  SDCC1_APPS_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_gcc_sdcc1_2_apps_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "sdcc1_apps_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
-		CLK_INIT(sdcc1_apps_clk_src.c),
-	},
-};
-
-static struct rcg_clk sdcc2_apps_clk_src = {
-	.cmd_rcgr_reg =  SDCC2_APPS_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_gcc_sdcc1_2_apps_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "sdcc2_apps_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
-		CLK_INIT(sdcc2_apps_clk_src.c),
-	},
-};
-
-static struct clk_freq_tbl ftbl_gcc_usb_hs_system_clk[] = {
-	F(75000000, gpll0, 8, 0, 0),
-	F_END,
-};
-
-static struct rcg_clk usb_hs_system_clk_src = {
-	.cmd_rcgr_reg = USB_HS_SYSTEM_CMD_RCGR,
-	.set_rate = set_rate_hid,
-	.freq_tbl = ftbl_gcc_usb_hs_system_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "usb_hs_system_clk_src",
-		.ops = &clk_ops_rcg,
-		VDD_DIG_FMAX_MAP2(LOW, 60000000, NOMINAL, 100000000),
-		CLK_INIT(usb_hs_system_clk_src.c),
-	},
-};
-
-static struct local_vote_clk gcc_blsp1_ahb_clk = {
-	.cbcr_reg = BLSP1_AHB_CBCR,
-	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
-	.en_mask = BIT(17),
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "gcc_blsp1_ahb_clk",
-		.ops = &clk_ops_vote,
-		CLK_INIT(gcc_blsp1_ahb_clk.c),
-	},
-};
-
-static struct branch_clk gcc_blsp1_qup1_i2c_apps_clk = {
-	.cbcr_reg = BLSP1_QUP1_I2C_APPS_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.parent = &gcc_xo_clk_src.c,
-		.dbg_name = "gcc_blsp1_qup1_i2c_apps_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_blsp1_qup1_i2c_apps_clk.c),
-	},
-};
-
-static struct branch_clk gcc_blsp1_qup1_spi_apps_clk = {
-	.cbcr_reg = BLSP1_QUP1_SPI_APPS_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.parent = &blsp1_qup1_spi_apps_clk_src.c,
-		.dbg_name = "gcc_blsp1_qup1_spi_apps_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_blsp1_qup1_spi_apps_clk.c),
-	},
-};
-
-static struct branch_clk gcc_blsp1_qup2_i2c_apps_clk = {
-	.cbcr_reg = BLSP1_QUP2_I2C_APPS_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.parent = &gcc_xo_clk_src.c,
-		.dbg_name = "gcc_blsp1_qup2_i2c_apps_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_blsp1_qup2_i2c_apps_clk.c),
-	},
-};
-
-static struct branch_clk gcc_blsp1_qup2_spi_apps_clk = {
-	.cbcr_reg = BLSP1_QUP2_SPI_APPS_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.parent = &blsp1_qup2_spi_apps_clk_src.c,
-		.dbg_name = "gcc_blsp1_qup2_spi_apps_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_blsp1_qup2_spi_apps_clk.c),
-	},
-};
-
-static struct branch_clk gcc_blsp1_qup3_i2c_apps_clk = {
-	.cbcr_reg = BLSP1_QUP3_I2C_APPS_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.parent = &gcc_xo_clk_src.c,
-		.dbg_name = "gcc_blsp1_qup3_i2c_apps_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_blsp1_qup3_i2c_apps_clk.c),
-	},
-};
-
-static struct branch_clk gcc_blsp1_qup3_spi_apps_clk = {
-	.cbcr_reg = BLSP1_QUP3_SPI_APPS_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.parent = &blsp1_qup3_spi_apps_clk_src.c,
-		.dbg_name = "gcc_blsp1_qup3_spi_apps_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_blsp1_qup3_spi_apps_clk.c),
-	},
-};
-
-static struct branch_clk gcc_blsp1_qup4_i2c_apps_clk = {
-	.cbcr_reg = BLSP1_QUP4_I2C_APPS_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.parent = &gcc_xo_clk_src.c,
-		.dbg_name = "gcc_blsp1_qup4_i2c_apps_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_blsp1_qup4_i2c_apps_clk.c),
-	},
-};
-
-static struct branch_clk gcc_blsp1_qup4_spi_apps_clk = {
-	.cbcr_reg = BLSP1_QUP4_SPI_APPS_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.parent = &blsp1_qup4_spi_apps_clk_src.c,
-		.dbg_name = "gcc_blsp1_qup4_spi_apps_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_blsp1_qup4_spi_apps_clk.c),
-	},
-};
-
-static struct branch_clk gcc_blsp1_qup5_i2c_apps_clk = {
-	.cbcr_reg = BLSP1_QUP5_I2C_APPS_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.parent = &gcc_xo_clk_src.c,
-		.dbg_name = "gcc_blsp1_qup5_i2c_apps_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_blsp1_qup5_i2c_apps_clk.c),
-	},
-};
-
-static struct branch_clk gcc_blsp1_qup5_spi_apps_clk = {
-	.cbcr_reg = BLSP1_QUP5_SPI_APPS_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.parent = &blsp1_qup5_spi_apps_clk_src.c,
-		.dbg_name = "gcc_blsp1_qup5_spi_apps_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_blsp1_qup5_spi_apps_clk.c),
-	},
-};
-
-static struct branch_clk gcc_blsp1_qup6_i2c_apps_clk = {
-	.cbcr_reg = BLSP1_QUP6_I2C_APPS_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.parent = &gcc_xo_clk_src.c,
-		.dbg_name = "gcc_blsp1_qup6_i2c_apps_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_blsp1_qup6_i2c_apps_clk.c),
-	},
-};
-
-static struct branch_clk gcc_blsp1_qup6_spi_apps_clk = {
-	.cbcr_reg = BLSP1_QUP6_SPI_APPS_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.parent = &blsp1_qup6_spi_apps_clk_src.c,
-		.dbg_name = "gcc_blsp1_qup6_spi_apps_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_blsp1_qup6_spi_apps_clk.c),
-	},
-};
-
-static struct branch_clk gcc_blsp1_uart1_apps_clk = {
-	.cbcr_reg = BLSP1_UART1_APPS_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.parent = &blsp1_uart1_apps_clk_src.c,
-		.dbg_name = "gcc_blsp1_uart1_apps_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_blsp1_uart1_apps_clk.c),
-	},
-};
-
-static struct branch_clk gcc_blsp1_uart2_apps_clk = {
-	.cbcr_reg = BLSP1_UART2_APPS_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.parent = &blsp1_uart2_apps_clk_src.c,
-		.dbg_name = "gcc_blsp1_uart2_apps_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_blsp1_uart2_apps_clk.c),
-	},
-};
-
-static struct branch_clk gcc_blsp1_uart3_apps_clk = {
-	.cbcr_reg = BLSP1_UART3_APPS_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.parent = &blsp1_uart3_apps_clk_src.c,
-		.dbg_name = "gcc_blsp1_uart3_apps_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_blsp1_uart3_apps_clk.c),
-	},
-};
-
-static struct branch_clk gcc_blsp1_uart4_apps_clk = {
-	.cbcr_reg = BLSP1_UART4_APPS_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.parent = &blsp1_uart4_apps_clk_src.c,
-		.dbg_name = "gcc_blsp1_uart4_apps_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_blsp1_uart4_apps_clk.c),
-	},
-};
-
-static struct branch_clk gcc_blsp1_uart5_apps_clk = {
-	.cbcr_reg = BLSP1_UART5_APPS_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.parent = &blsp1_uart5_apps_clk_src.c,
-		.dbg_name = "gcc_blsp1_uart5_apps_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_blsp1_uart5_apps_clk.c),
-	},
-};
-
-static struct branch_clk gcc_blsp1_uart6_apps_clk = {
-	.cbcr_reg = BLSP1_UART6_APPS_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.parent = &blsp1_uart6_apps_clk_src.c,
-		.dbg_name = "gcc_blsp1_uart6_apps_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_blsp1_uart6_apps_clk.c),
-	},
-};
-
-static struct local_vote_clk gcc_boot_rom_ahb_clk = {
-	.cbcr_reg = BOOT_ROM_AHB_CBCR,
-	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
-	.en_mask = BIT(10),
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "gcc_boot_rom_ahb_clk",
-		.ops = &clk_ops_vote,
-		CLK_INIT(gcc_boot_rom_ahb_clk.c),
-	},
-};
-
-static struct local_vote_clk gcc_ce1_ahb_clk = {
-	.cbcr_reg = CE1_AHB_CBCR,
-	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
-	.en_mask = BIT(3),
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "gcc_ce1_ahb_clk",
-		.ops = &clk_ops_vote,
-		CLK_INIT(gcc_ce1_ahb_clk.c),
-	},
-};
-
-static struct local_vote_clk gcc_ce1_axi_clk = {
-	.cbcr_reg = CE1_AXI_CBCR,
-	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
-	.en_mask = BIT(4),
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "gcc_ce1_axi_clk",
-		.ops = &clk_ops_vote,
-		CLK_INIT(gcc_ce1_axi_clk.c),
-	},
-};
-
-static struct local_vote_clk gcc_ce1_clk = {
-	.cbcr_reg = CE1_CBCR,
-	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
-	.en_mask = BIT(5),
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "gcc_ce1_clk",
-		.ops = &clk_ops_vote,
-		CLK_INIT(gcc_ce1_clk.c),
-	},
-};
-
-static struct branch_clk gcc_copss_smmu_ahb_clk = {
-	.cbcr_reg = COPSS_SMMU_AHB_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "gcc_copss_smmu_ahb_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_copss_smmu_ahb_clk.c),
-	},
-};
-
-static struct branch_clk gcc_lpss_smmu_ahb_clk = {
-	.cbcr_reg = LPSS_SMMU_AHB_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-			.dbg_name = "gcc_lpss_smmu_ahb_clk",
-			.ops = &clk_ops_branch,
-			CLK_INIT(gcc_lpss_smmu_ahb_clk.c),
-	},
-};
-
-static struct branch_clk gcc_gp1_clk = {
-	.cbcr_reg = GP1_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.parent = &gp1_clk_src.c,
-		.dbg_name = "gcc_gp1_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_gp1_clk.c),
-	},
-};
-
-static struct branch_clk gcc_gp2_clk = {
-	.cbcr_reg = GP2_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.parent = &gp2_clk_src.c,
-		.dbg_name = "gcc_gp2_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_gp2_clk.c),
-	},
-};
-
-static struct branch_clk gcc_gp3_clk = {
-	.cbcr_reg = GP3_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.parent = &gp3_clk_src.c,
-		.dbg_name = "gcc_gp3_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_gp3_clk.c),
-	},
-};
-
-static struct branch_clk gcc_lpass_q6_axi_clk = {
-	.cbcr_reg = LPASS_Q6_AXI_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "gcc_lpass_q6_axi_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_lpass_q6_axi_clk.c),
-	},
-};
-
-static struct branch_clk gcc_mmss_noc_cfg_ahb_clk = {
-	.cbcr_reg = MMSS_NOC_CFG_AHB_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "gcc_mmss_noc_cfg_ahb_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_mmss_noc_cfg_ahb_clk.c),
-	},
-};
-
-static struct branch_clk gcc_mss_cfg_ahb_clk = {
-	.cbcr_reg = MSS_CFG_AHB_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "gcc_mss_cfg_ahb_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_mss_cfg_ahb_clk.c),
-	},
-};
-
-static struct branch_clk gcc_mss_q6_bimc_axi_clk = {
-	.cbcr_reg = MSS_Q6_BIMC_AXI_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "gcc_mss_q6_bimc_axi_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_mss_q6_bimc_axi_clk.c),
-	},
-};
-
-static struct branch_clk gcc_pdm2_clk = {
-	.cbcr_reg = PDM2_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.parent = &pdm2_clk_src.c,
-		.dbg_name = "gcc_pdm2_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_pdm2_clk.c),
-	},
-};
-
-static struct branch_clk gcc_pdm_ahb_clk = {
-	.cbcr_reg = PDM_AHB_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "gcc_pdm_ahb_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_pdm_ahb_clk.c),
-	},
-};
-
-static struct local_vote_clk gcc_prng_ahb_clk = {
-	.cbcr_reg = PRNG_AHB_CBCR,
-	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
-	.en_mask = BIT(13),
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "gcc_prng_ahb_clk",
-		.ops = &clk_ops_vote,
-		CLK_INIT(gcc_prng_ahb_clk.c),
-	},
-};
-
-static struct branch_clk gcc_sdcc1_ahb_clk = {
-	.cbcr_reg = SDCC1_AHB_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "gcc_sdcc1_ahb_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_sdcc1_ahb_clk.c),
-	},
-};
-
-static struct branch_clk gcc_sdcc1_apps_clk = {
-	.cbcr_reg = SDCC1_APPS_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.parent = &sdcc1_apps_clk_src.c,
-		.dbg_name = "gcc_sdcc1_apps_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_sdcc1_apps_clk.c),
-	},
-};
-
-static struct branch_clk gcc_sdcc2_ahb_clk = {
-	.cbcr_reg = SDCC2_AHB_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "gcc_sdcc2_ahb_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_sdcc2_ahb_clk.c),
-	},
-};
-
-static struct branch_clk gcc_sdcc2_apps_clk = {
-	.cbcr_reg = SDCC2_APPS_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.parent = &sdcc2_apps_clk_src.c,
-		.dbg_name = "gcc_sdcc2_apps_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_sdcc2_apps_clk.c),
-	},
-};
-
-static struct branch_clk gcc_usb2a_phy_sleep_clk = {
-	.cbcr_reg = USB2A_PHY_SLEEP_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "gcc_usb2a_phy_sleep_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_usb2a_phy_sleep_clk.c),
-	},
-};
-
-static struct branch_clk gcc_usb_hs_ahb_clk = {
-	.cbcr_reg = USB_HS_AHB_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.dbg_name = "gcc_usb_hs_ahb_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_usb_hs_ahb_clk.c),
-	},
-};
-
-static struct branch_clk gcc_usb_hs_system_clk = {
-	.cbcr_reg = USB_HS_SYSTEM_CBCR,
-	.has_sibling = 0,
-	.bcr_reg = USB_HS_BCR,
-	.base = &virt_bases[GCC_BASE],
-	.c = {
-		.parent = &usb_hs_system_clk_src.c,
-		.dbg_name = "gcc_usb_hs_system_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gcc_usb_hs_system_clk.c),
-	},
-};
-
-static struct clk_freq_tbl ftbl_csi0_1_clk[] = {
-	F_MM(100000000,  gpll0, 6, 0, 0),
-	F_MM(200000000, mmpll0, 4, 0, 0),
-	F_END,
-};
-
-static struct rcg_clk csi0_clk_src = {
-	.cmd_rcgr_reg = CSI0_CMD_RCGR,
-	.set_rate = set_rate_hid,
-	.freq_tbl = ftbl_csi0_1_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.dbg_name = "csi0_clk_src",
-		.ops = &clk_ops_rcg,
-		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
-		CLK_INIT(csi0_clk_src.c),
-	},
-};
-
-static struct clk_freq_tbl ftbl_mmss_mmssnoc_ahb_clk[] = {
-	F_MM(19200000, gcc_xo,  1, 0, 0),
-	F_MM(40000000,  gpll0, 15, 0, 0),
-	F_MM(80000000, mmpll0, 10, 0, 0),
-	F_END,
-};
-
-static struct rcg_clk ahb_clk_src = {
-	.cmd_rcgr_reg = AHB_CMD_RCGR,
-	.set_rate = set_rate_hid,
-	.freq_tbl = ftbl_mmss_mmssnoc_ahb_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.dbg_name = "ahb_clk_src",
-		.ops = &clk_ops_rcg,
-		VDD_DIG_FMAX_MAP2(LOW, 40000000, NOMINAL, 80000000),
-		CLK_INIT(ahb_clk_src.c),
-	},
-};
-
-static struct clk_freq_tbl ftbl_mmss_mmssnoc_axi_clk[] = {
-	F_MM( 19200000, gcc_xo,  1, 0, 0),
-	F_MM( 37500000,  gpll0, 16, 0, 0),
-	F_MM( 50000000,  gpll0, 12, 0, 0),
-	F_MM( 75000000,  gpll0,  8, 0, 0),
-	F_MM(100000000,  gpll0,  6, 0, 0),
-	F_MM(150000000,  gpll0,  4, 0, 0),
-	F_MM(200000000, mmpll0,  4, 0, 0),
-	F_END,
-};
-
-static struct rcg_clk axi_clk_src = {
-	.cmd_rcgr_reg = AXI_CMD_RCGR,
-	.set_rate = set_rate_hid,
-	.freq_tbl = ftbl_mmss_mmssnoc_axi_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.dbg_name = "axi_clk_src",
-		.ops = &clk_ops_rcg,
-		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
-		CLK_INIT(axi_clk_src.c),
-	},
-};
-
-static struct clk_freq_tbl ftbl_dsi_pclk_clk[] = {
-	F_MDSS( 50000000, dsipll, 10, 0, 0),
-	F_MDSS(103330000, dsipll,  9, 0, 0),
-	F_END,
-};
-
-static struct rcg_clk dsi_pclk_clk_src = {
-	.cmd_rcgr_reg =  DSI_PCLK_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_dsi_pclk_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.dbg_name = "dsi_pclk_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 50000000, NOMINAL, 103330000),
-		CLK_INIT(dsi_pclk_clk_src.c),
-	},
-};
-
-static struct clk_freq_tbl ftbl_oxili_gfx3d_clk[] = {
-	F_MM( 19200000, gcc_xo,  1, 0, 0),
-	F_MM( 37500000,  gpll0, 16, 0, 0),
-	F_MM( 50000000,  gpll0, 12, 0, 0),
-	F_MM( 75000000,  gpll0,  8, 0, 0),
-	F_MM(100000000,  gpll0,  6, 0, 0),
-	F_MM(150000000,  gpll0,  4, 0, 0),
-	F_MM(200000000,  gpll0,  3, 0, 0),
-	F_MM(300000000,  gpll0,  2, 0, 0),
-	F_MM(400000000, mmpll1,  3, 0, 0),
-	F_END,
-};
-
-static struct rcg_clk gfx3d_clk_src = {
-	.cmd_rcgr_reg = GFX3D_CMD_RCGR,
-	.set_rate = set_rate_hid,
-	.freq_tbl = ftbl_oxili_gfx3d_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.dbg_name = "gfx3d_clk_src",
-		.ops = &clk_ops_rcg,
-		VDD_DIG_FMAX_MAP3(LOW, 150000000, NOMINAL, 300000000, HIGH,
-					400000000),
-		CLK_INIT(gfx3d_clk_src.c),
-	},
-};
-
-static struct clk_freq_tbl ftbl_vfe_clk[] = {
-	F_MM( 37500000,  gpll0,  16, 0, 0),
-	F_MM( 50000000,  gpll0,  12, 0, 0),
-	F_MM( 60000000,  gpll0,  10, 0, 0),
-	F_MM( 80000000,  gpll0, 7.5, 0, 0),
-	F_MM(100000000,  gpll0,   6, 0, 0),
-	F_MM(109090000,  gpll0, 5.5, 0, 0),
-	F_MM(133330000,  gpll0, 4.5, 0, 0),
-	F_MM(200000000,  gpll0,   3, 0, 0),
-	F_MM(228570000, mmpll0, 3.5, 0, 0),
-	F_MM(266670000, mmpll0,   3, 0, 0),
-	F_MM(320000000, mmpll0, 2.5, 0, 0),
-	F_END,
-};
-
-static struct rcg_clk vfe_clk_src = {
-	.cmd_rcgr_reg = VFE_CMD_RCGR,
-	.set_rate = set_rate_hid,
-	.freq_tbl = ftbl_vfe_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.dbg_name = "vfe_clk_src",
-		.ops = &clk_ops_rcg,
-		VDD_DIG_FMAX_MAP3(LOW, 133330000, NOMINAL, 266670000, HIGH,
-					320000000),
-		CLK_INIT(vfe_clk_src.c),
-	},
-};
-
-static struct rcg_clk csi1_clk_src = {
-	.cmd_rcgr_reg = CSI1_CMD_RCGR,
-	.set_rate = set_rate_hid,
-	.freq_tbl = ftbl_csi0_1_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.dbg_name = "csi1_clk_src",
-		.ops = &clk_ops_rcg,
-		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
-		CLK_INIT(csi1_clk_src.c),
-	},
-};
-
-static struct clk_freq_tbl ftbl_csi0_1phytimer_clk[] = {
-	F_MM(100000000,  gpll0, 6, 0, 0),
-	F_MM(200000000, mmpll0, 4, 0, 0),
-	F_END,
-};
-
-static struct rcg_clk csi0phytimer_clk_src = {
-	.cmd_rcgr_reg = CSI0PHYTIMER_CMD_RCGR,
-	.set_rate = set_rate_hid,
-	.freq_tbl = ftbl_csi0_1phytimer_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.dbg_name = "csi0phytimer_clk_src",
-		.ops = &clk_ops_rcg,
-		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
-		CLK_INIT(csi0phytimer_clk_src.c),
-	},
-};
-
-static struct rcg_clk csi1phytimer_clk_src = {
-	.cmd_rcgr_reg = CSI1PHYTIMER_CMD_RCGR,
-	.set_rate = set_rate_hid,
-	.freq_tbl = ftbl_csi0_1phytimer_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.dbg_name = "csi1phytimer_clk_src",
-		.ops = &clk_ops_rcg,
-		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
-		CLK_INIT(csi1phytimer_clk_src.c),
-	},
-};
-
-static struct clk_freq_tbl ftbl_dsi_clk[] = {
-	F_MDSS(155000000,  dsipll, 6, 0, 0),
-	F_MDSS(310000000,  dsipll, 3, 0, 0),
-	F_END,
-};
-
-static struct rcg_clk dsi_clk_src = {
-	.cmd_rcgr_reg =  DSI_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_dsi_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.dbg_name = "dsi_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 155000000, NOMINAL, 310000000),
-		CLK_INIT(dsi_clk_src.c),
-	},
-};
-
-static struct clk_freq_tbl ftbl_dsi_byte_clk[] = {
-	F_MDSS( 62500000, dsipll, 12, 0, 0),
-	F_MDSS(125000000, dsipll,  6, 0, 0),
-	F_END,
-};
-
-static struct rcg_clk dsi_byte_clk_src = {
-	.cmd_rcgr_reg = DSI_BYTE_CMD_RCGR,
-	.set_rate = set_rate_hid,
-	.freq_tbl = ftbl_dsi_byte_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.dbg_name = "dsi_byte_clk_src",
-		.ops = &clk_ops_rcg,
-		VDD_DIG_FMAX_MAP2(LOW, 62500000, NOMINAL, 125000000),
-		CLK_INIT(dsi_byte_clk_src.c),
-	},
-};
-
-static struct clk_freq_tbl ftbl_dsi_esc_clk[] = {
-	F_MM(19200000, gcc_xo, 1, 0, 0),
-	F_END,
-};
-
-static struct rcg_clk dsi_esc_clk_src = {
-	.cmd_rcgr_reg = DSI_ESC_CMD_RCGR,
-	.set_rate = set_rate_hid,
-	.freq_tbl = ftbl_dsi_esc_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.dbg_name = "dsi_esc_clk_src",
-		.ops = &clk_ops_rcg,
-		VDD_DIG_FMAX_MAP1(LOW, 19200000),
-		CLK_INIT(dsi_esc_clk_src.c),
-	},
-};
-
-static struct clk_freq_tbl ftbl_mclk0_1_clk[] = {
-	F_MM(66670000, gpll0, 9, 0, 0),
-	F_END,
-};
-
-static struct rcg_clk mclk0_clk_src = {
-	.cmd_rcgr_reg =  MCLK0_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_mclk0_1_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.dbg_name = "mclk0_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP1(LOW, 66670000),
-		CLK_INIT(mclk0_clk_src.c),
-	},
-};
-
-static struct rcg_clk mclk1_clk_src = {
-	.cmd_rcgr_reg =  MCLK1_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_mclk0_1_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.dbg_name = "mclk1_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP1(LOW, 66670000),
-		CLK_INIT(mclk1_clk_src.c),
-	},
-};
-
-static struct clk_freq_tbl ftbl_mdp_vsync_clk[] = {
-	F_MM(19200000, gcc_xo, 1, 0, 0),
-	F_END,
-};
-
-static struct rcg_clk mdp_vsync_clk_src = {
-	.cmd_rcgr_reg = MDP_VSYNC_CMD_RCGR,
-	.set_rate = set_rate_hid,
-	.freq_tbl = ftbl_mdp_vsync_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.dbg_name = "mdp_vsync_clk_src",
-		.ops = &clk_ops_rcg,
-		VDD_DIG_FMAX_MAP1(LOW, 19200000),
-		CLK_INIT(mdp_vsync_clk_src.c),
-	},
-};
-
-static struct branch_clk bimc_gfx_clk = {
-	.cbcr_reg = BIMC_GFX_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.dbg_name = "bimc_gfx_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(bimc_gfx_clk.c),
-	},
-};
-
-static struct branch_clk csi0_clk = {
-	.cbcr_reg = CSI0_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &csi0_clk_src.c,
-		.dbg_name = "csi0_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(csi0_clk.c),
-	},
-};
-
-static struct branch_clk csi0phy_clk = {
-	.cbcr_reg = CSI0PHY_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &csi0_clk_src.c,
-		.dbg_name = "csi0phy_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(csi0phy_clk.c),
-	},
-};
-
-static struct branch_clk csi0phytimer_clk = {
-	.cbcr_reg = CSI0PHYTIMER_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &csi0phytimer_clk_src.c,
-		.dbg_name = "csi0phytimer_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(csi0phytimer_clk.c),
-	},
-};
-
-static struct branch_clk csi0pix_clk = {
-	.cbcr_reg = CSI0PIX_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &csi0_clk_src.c,
-		.dbg_name = "csi0pix_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(csi0pix_clk.c),
-	},
-};
-
-static struct branch_clk csi0rdi_clk = {
-	.cbcr_reg = CSI0RDI_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &csi0_clk_src.c,
-		.dbg_name = "csi0rdi_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(csi0rdi_clk.c),
-	},
-};
-
-static struct branch_clk csi1_clk = {
-	.cbcr_reg = CSI1_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &csi1_clk_src.c,
-		.dbg_name = "csi1_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(csi1_clk.c),
-	},
-};
-
-static struct branch_clk csi1phy_clk = {
-	.cbcr_reg = CSI1PHY_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &csi1_clk_src.c,
-		.dbg_name = "csi1phy_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(csi1phy_clk.c),
-	},
-};
-
-static struct branch_clk csi1phytimer_clk = {
-	.cbcr_reg = CSI1PHYTIMER_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &csi1phytimer_clk_src.c,
-		.dbg_name = "csi1phytimer_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(csi1phytimer_clk.c),
-	},
-};
-
-static struct branch_clk csi1pix_clk = {
-	.cbcr_reg = CSI1PIX_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &csi0_clk_src.c,
-		.dbg_name = "csi1pix_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(csi1pix_clk.c),
-	},
-};
-
-static struct branch_clk csi1rdi_clk = {
-	.cbcr_reg = CSI1RDI_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &csi0_clk_src.c,
-		.dbg_name = "csi1rdi_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(csi1rdi_clk.c),
-	},
-};
-
-static struct branch_clk csi_ahb_clk = {
-	.cbcr_reg = CSI_AHB_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.dbg_name = "csi_ahb_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(csi_ahb_clk.c),
-	},
-};
-
-static struct branch_clk csi_vfe_clk = {
-	.cbcr_reg = CSI_VFE_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &vfe_clk_src.c,
-		.dbg_name = "csi_vfe_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(csi_vfe_clk.c),
-	},
-};
-
-static struct branch_clk dsi_clk = {
-	.cbcr_reg = DSI_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &dsi_clk_src.c,
-		.dbg_name = "dsi_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(dsi_clk.c),
-	},
-};
-
-static struct branch_clk dsi_ahb_clk = {
-	.cbcr_reg = DSI_AHB_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.dbg_name = "dsi_ahb_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(dsi_ahb_clk.c),
-	},
-};
-
-static struct branch_clk dsi_byte_clk = {
-	.cbcr_reg = DSI_BYTE_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &dsi_byte_clk_src.c,
-		.dbg_name = "dsi_byte_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(dsi_byte_clk.c),
-	},
-};
-
-static struct branch_clk dsi_esc_clk = {
-	.cbcr_reg = DSI_ESC_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &dsi_esc_clk_src.c,
-		.dbg_name = "dsi_esc_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(dsi_esc_clk.c),
-	},
-};
-
-static struct branch_clk dsi_pclk_clk = {
-	.cbcr_reg = DSI_PCLK_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &dsi_pclk_clk_src.c,
-		.dbg_name = "dsi_pclk_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(dsi_pclk_clk.c),
-	},
-};
-
-static struct branch_clk gmem_gfx3d_clk = {
-	.cbcr_reg = GMEM_GFX3D_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &gfx3d_clk_src.c,
-		.dbg_name = "gmem_gfx3d_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(gmem_gfx3d_clk.c),
-	},
-};
-
-static struct branch_clk mclk0_clk = {
-	.cbcr_reg = MCLK0_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &mclk0_clk_src.c,
-		.dbg_name = "mclk0_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(mclk0_clk.c),
-	},
-};
-
-static struct branch_clk mclk1_clk = {
-	.cbcr_reg = MCLK1_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &mclk1_clk_src.c,
-		.dbg_name = "mclk1_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(mclk1_clk.c),
-	},
-};
-
-static struct branch_clk mdp_ahb_clk = {
-	.cbcr_reg = MDP_AHB_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.dbg_name = "mdp_ahb_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(mdp_ahb_clk.c),
-	},
-};
-
-static struct branch_clk mdp_axi_clk = {
-	.cbcr_reg = MDP_AXI_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &axi_clk_src.c,
-		.dbg_name = "mdp_axi_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(mdp_axi_clk.c),
-	},
-};
-
-static struct branch_clk mdp_dsi_clk = {
-	.cbcr_reg = MDP_DSI_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &dsi_pclk_clk_src.c,
-		.dbg_name = "mdp_dsi_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(mdp_dsi_clk.c),
-	},
-};
-
-static struct branch_clk mdp_lcdc_clk = {
-	.cbcr_reg = MDP_LCDC_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &dsi_pclk_clk_src.c,
-		.dbg_name = "mdp_lcdc_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(mdp_lcdc_clk.c),
-	},
-};
-
-static struct branch_clk mdp_vsync_clk = {
-	.cbcr_reg = MDP_VSYNC_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &mdp_vsync_clk_src.c,
-		.dbg_name = "mdp_vsync_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(mdp_vsync_clk.c),
-	},
-};
-
-static struct branch_clk mmss_misc_ahb_clk = {
-	.cbcr_reg = MMSS_MISC_AHB_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.dbg_name = "mmss_misc_ahb_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(mmss_misc_ahb_clk.c),
-	},
-};
-
-static struct branch_clk mmss_mmssnoc_axi_clk = {
-	.cbcr_reg = MMSS_MMSSNOC_AXI_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &axi_clk_src.c,
-		.dbg_name = "mmss_mmssnoc_axi_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(mmss_mmssnoc_axi_clk.c),
-	},
-};
-
-static struct branch_clk mmss_s0_axi_clk = {
-	.cbcr_reg = MMSS_S0_AXI_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &axi_clk_src.c,
-		.dbg_name = "mmss_s0_axi_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(mmss_s0_axi_clk.c),
-		.depends = &mmss_mmssnoc_axi_clk.c,
-	},
-};
-
-static struct branch_clk mmss_mmssnoc_ahb_clk = {
-	.cbcr_reg = MMSS_MMSSNOC_AHB_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &ahb_clk_src.c,
-		.dbg_name = "mmss_mmssnoc_ahb_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(mmss_mmssnoc_ahb_clk.c),
-	},
-};
-
-static struct branch_clk mmss_mmssnoc_bto_ahb_clk = {
-	.cbcr_reg = MMSS_MMSSNOC_BTO_AHB_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.dbg_name = "mmss_mmssnoc_bto_ahb_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(mmss_mmssnoc_bto_ahb_clk.c),
-	},
-};
-
-static struct branch_clk oxili_ahb_clk = {
-	.cbcr_reg = OXILI_AHB_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.dbg_name = "oxili_ahb_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(oxili_ahb_clk.c),
-	},
-};
-
-static struct branch_clk oxili_gfx3d_clk = {
-	.cbcr_reg = OXILI_GFX3D_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &gfx3d_clk_src.c,
-		.dbg_name = "oxili_gfx3d_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(oxili_gfx3d_clk.c),
-	},
-};
-
-static struct branch_clk vfe_clk = {
-	.cbcr_reg = VFE_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &vfe_clk_src.c,
-		.dbg_name = "vfe_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(vfe_clk.c),
-	},
-};
-
-static struct branch_clk vfe_ahb_clk = {
-	.cbcr_reg = VFE_AHB_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.dbg_name = "vfe_ahb_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(vfe_ahb_clk.c),
-	},
-};
-
-static struct branch_clk vfe_axi_clk = {
-	.cbcr_reg = VFE_AXI_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[MMSS_BASE],
-	.c = {
-		.parent = &axi_clk_src.c,
-		.dbg_name = "vfe_axi_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(vfe_axi_clk.c),
-	},
-};
-
-static struct clk_freq_tbl ftbl_audio_core_lpaif_clk[] = {
-	F_LPASS(  512000, lpapll0, 16, 1, 60),
-	F_LPASS(  768000, lpapll0, 16, 1, 40),
-	F_LPASS( 1024000, lpapll0, 16, 1, 30),
-	F_LPASS( 1536000, lpapll0, 16, 1, 20),
-	F_LPASS( 2048000, lpapll0, 16, 1, 15),
-	F_LPASS( 3072000, lpapll0, 16, 1, 10),
-	F_LPASS( 4096000, lpapll0, 15, 1,  8),
-	F_LPASS( 6144000, lpapll0, 10, 1,  8),
-	F_LPASS( 8192000, lpapll0, 15, 1,  4),
-	F_LPASS(12288000, lpapll0, 10, 1,  4),
-	F_END,
-};
-
-static struct rcg_clk lpaif_pri_clk_src = {
-	.cmd_rcgr_reg =  LPAIF_PRI_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_audio_core_lpaif_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "lpaif_pri_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 12290000, NOMINAL, 24580000),
-		CLK_INIT(lpaif_pri_clk_src.c),
-	},
-};
-
-static struct rcg_clk lpaif_quad_clk_src = {
-	.cmd_rcgr_reg =  LPAIF_QUAD_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_audio_core_lpaif_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "lpaif_quad_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 12290000, NOMINAL, 24580000),
-		CLK_INIT(lpaif_quad_clk_src.c),
-	},
-};
-
-static struct rcg_clk lpaif_sec_clk_src = {
-	.cmd_rcgr_reg =  LPAIF_SEC_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_audio_core_lpaif_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "lpaif_sec_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 12290000, NOMINAL, 24580000),
-		CLK_INIT(lpaif_sec_clk_src.c),
-	},
-};
-
-static struct rcg_clk lpaif_spkr_clk_src = {
-	.cmd_rcgr_reg =  LPAIF_SPKR_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_audio_core_lpaif_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "lpaif_spkr_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 12290000, NOMINAL, 24580000),
-		CLK_INIT(lpaif_spkr_clk_src.c),
-	},
-};
-
-static struct rcg_clk lpaif_ter_clk_src = {
-	.cmd_rcgr_reg =  LPAIF_TER_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_audio_core_lpaif_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "lpaif_ter_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 12290000, NOMINAL, 24580000),
-		CLK_INIT(lpaif_ter_clk_src.c),
-	},
-};
-
-static struct clk_freq_tbl ftbl_audio_core_lpaif_pcm0_1_clk[] = {
-	F_LPASS( 512000, lpapll0, 16, 1, 60),
-	F_LPASS( 768000, lpapll0, 16, 1, 40),
-	F_LPASS(1024000, lpapll0, 16, 1, 30),
-	F_LPASS(1536000, lpapll0, 16, 1, 20),
-	F_LPASS(2048000, lpapll0, 16, 1, 15),
-	F_LPASS(3072000, lpapll0, 16, 1, 10),
-	F_LPASS(4096000, lpapll0, 15, 1,  8),
-	F_LPASS(6144000, lpapll0, 10, 1,  8),
-	F_LPASS(8192000, lpapll0, 15, 1,  4),
-	F_END,
-};
-
-static struct rcg_clk lpaif_pcm0_clk_src = {
-	.cmd_rcgr_reg =  LPAIF_PCM0_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_audio_core_lpaif_pcm0_1_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "lpaif_pcm0_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 4100000, NOMINAL, 8192000),
-		CLK_INIT(lpaif_pcm0_clk_src.c),
-	},
-};
-
-static struct rcg_clk lpaif_pcm1_clk_src = {
-	.cmd_rcgr_reg =  LPAIF_PCM1_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_audio_core_lpaif_pcm0_1_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "lpaif_pcm1_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 4100000, NOMINAL, 8192000),
-		CLK_INIT(lpaif_pcm1_clk_src.c),
-	},
-};
-
-static struct rcg_clk lpaif_pcmoe_clk_src = {
-	.cmd_rcgr_reg =  LPAIF_PCMOE_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_audio_core_lpaif_pcm0_1_clk,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "lpaif_pcmoe_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 6140000, NOMINAL, 12290000),
-		CLK_INIT(lpaif_pcmoe_clk_src.c),
-	},
-};
-
-static struct clk_freq_tbl ftbl_audio_core_slimbus_core_clock[] = {
-	F_LPASS(24576000, lpapll0, 4, 1, 5),
-	F_END
-};
-
-static struct rcg_clk audio_core_slimbus_core_clk_src = {
-	.cmd_rcgr_reg = SLIMBUS_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_audio_core_slimbus_core_clock,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_slimbus_core_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 12935000, NOMINAL, 25869000),
-		CLK_INIT(audio_core_slimbus_core_clk_src.c),
-	},
-};
-
-static struct branch_clk audio_core_slimbus_core_clk = {
-	.cbcr_reg = AUDIO_CORE_SLIMBUS_CORE_CBCR,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &audio_core_slimbus_core_clk_src.c,
-		.dbg_name = "audio_core_slimbus_core_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_slimbus_core_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_ixfabric_clk = {
-	.cbcr_reg = AUDIO_CORE_IXFABRIC_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_ixfabric_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_ixfabric_clk.c),
-	},
-};
-
-static struct branch_clk audio_wrapper_br_clk = {
-	.cbcr_reg = AUDIO_WRAPPER_BR_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_wrapper_br_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_wrapper_br_clk.c),
-	},
-};
-
-static struct branch_clk q6ss_ahb_lfabif_clk = {
-	.cbcr_reg = Q6SS_AHB_LFABIF_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "q6ss_ahb_lfabif_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(q6ss_ahb_lfabif_clk.c),
-	},
-};
-
-static struct branch_clk q6ss_ahbm_clk = {
-	.cbcr_reg = Q6SS_AHBM_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "q6ss_ahbm_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(q6ss_ahbm_clk.c),
-	},
-};
-
-static struct branch_clk q6ss_xo_clk = {
-	.cbcr_reg = Q6SS_XO_CBCR,
-	.has_sibling = 1,
-	.bcr_reg = LPASS_Q6SS_BCR,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &gcc_xo_clk_src.c,
-		.dbg_name = "q6ss_xo_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(q6ss_xo_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_pcm_data_oe_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_PCM_DATA_OE_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &lpaif_pcmoe_clk_src.c,
-		.dbg_name = "audio_core_lpaif_pcm_data_oe_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_pcm_data_oe_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_pri_ebit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_PRI_EBIT_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_pri_ebit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_pri_ebit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_pri_ibit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_PRI_IBIT_CBCR,
-	.has_sibling = 0,
-	.max_div = 511,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &lpaif_pri_clk_src.c,
-		.dbg_name = "audio_core_lpaif_pri_ibit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_pri_ibit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_pri_osr_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_PRI_OSR_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &lpaif_pri_clk_src.c,
-		.dbg_name = "audio_core_lpaif_pri_osr_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_pri_osr_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_pcm0_ebit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_PCM0_EBIT_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_pcm0_ebit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_pcm0_ebit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_pcm0_ibit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_PCM0_IBIT_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &lpaif_pcm0_clk_src.c,
-		.dbg_name = "audio_core_lpaif_pcm0_ibit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_pcm0_ibit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_quad_ebit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_QUAD_EBIT_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_quad_ebit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_quad_ebit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_quad_ibit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_QUAD_IBIT_CBCR,
-	.has_sibling = 0,
-	.max_div = 511,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &lpaif_quad_clk_src.c,
-		.dbg_name = "audio_core_lpaif_quad_ibit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_quad_ibit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_quad_osr_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_QUAD_OSR_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &lpaif_quad_clk_src.c,
-		.dbg_name = "audio_core_lpaif_quad_osr_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_quad_osr_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_sec_ebit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_SEC_EBIT_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_sec_ebit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_sec_ebit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_sec_ibit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_SEC_IBIT_CBCR,
-	.has_sibling = 0,
-	.max_div = 511,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &lpaif_sec_clk_src.c,
-		.dbg_name = "audio_core_lpaif_sec_ibit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_sec_ibit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_sec_osr_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_SEC_OSR_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &lpaif_sec_clk_src.c,
-		.dbg_name = "audio_core_lpaif_sec_osr_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_sec_osr_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_pcm1_ebit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_PCM1_EBIT_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_pcm1_ebit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_pcm1_ebit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_pcm1_ibit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_PCM1_IBIT_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &lpaif_pcm1_clk_src.c,
-		.dbg_name = "audio_core_lpaif_pcm1_ibit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_pcm1_ibit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_codec_spkr_ebit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_CODEC_SPKR_EBIT_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_codec_spkr_ebit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_codec_spkr_ebit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_codec_spkr_ibit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_CODEC_SPKR_IBIT_CBCR,
-	.has_sibling = 1,
-	.max_div = 511,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &lpaif_spkr_clk_src.c,
-		.dbg_name = "audio_core_lpaif_codec_spkr_ibit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_codec_spkr_ibit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_codec_spkr_osr_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_CODEC_SPKR_OSR_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &lpaif_spkr_clk_src.c,
-		.dbg_name = "audio_core_lpaif_codec_spkr_osr_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_codec_spkr_osr_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_ter_ebit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_TER_EBIT_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_ter_ebit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_ter_ebit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_ter_ibit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_TER_IBIT_CBCR,
-	.has_sibling = 0,
-	.max_div = 511,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &lpaif_ter_clk_src.c,
-		.dbg_name = "audio_core_lpaif_ter_ibit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_ter_ibit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_ter_osr_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_TER_OSR_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &lpaif_ter_clk_src.c,
-		.dbg_name = "audio_core_lpaif_ter_osr_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_ter_osr_clk.c),
-	},
-};
-
-#ifdef CONFIG_DEBUG_FS
-
-struct measure_mux_entry {
-	struct clk *c;
-	int base;
-	u32 debug_mux;
-};
-
-static struct measure_mux_entry measure_mux[] = {
-	{                   &snoc_clk.c, GCC_BASE, 0x0000},
-	{                   &cnoc_clk.c, GCC_BASE, 0x0008},
-	{     &gcc_copss_smmu_ahb_clk.c, GCC_BASE, 0x000c},
-	{      &gcc_lpss_smmu_ahb_clk.c, GCC_BASE, 0x000d},
-	{                   &pnoc_clk.c, GCC_BASE, 0x0010},
-	{   &gcc_mmss_noc_cfg_ahb_clk.c, GCC_BASE, 0x002a},
-	{        &gcc_mss_cfg_ahb_clk.c, GCC_BASE, 0x0030},
-	{    &gcc_mss_q6_bimc_axi_clk.c, GCC_BASE, 0x0031},
-	{      &gcc_usb_hs_system_clk.c, GCC_BASE, 0x0060},
-	{         &gcc_usb_hs_ahb_clk.c, GCC_BASE, 0x0061},
-	{    &gcc_usb2a_phy_sleep_clk.c, GCC_BASE, 0x0063},
-	{         &gcc_sdcc1_apps_clk.c, GCC_BASE, 0x0068},
-	{          &gcc_sdcc1_ahb_clk.c, GCC_BASE, 0x0069},
-	{         &gcc_sdcc2_apps_clk.c, GCC_BASE, 0x0070},
-	{          &gcc_sdcc2_ahb_clk.c, GCC_BASE, 0x0071},
-	{          &gcc_blsp1_ahb_clk.c, GCC_BASE, 0x0088},
-	{&gcc_blsp1_qup1_spi_apps_clk.c, GCC_BASE, 0x008a},
-	{&gcc_blsp1_qup1_i2c_apps_clk.c, GCC_BASE, 0x008b},
-	{   &gcc_blsp1_uart1_apps_clk.c, GCC_BASE, 0x008c},
-	{&gcc_blsp1_qup2_spi_apps_clk.c, GCC_BASE, 0x008e},
-	{&gcc_blsp1_qup2_i2c_apps_clk.c, GCC_BASE, 0x0090},
-	{   &gcc_blsp1_uart2_apps_clk.c, GCC_BASE, 0x0091},
-	{&gcc_blsp1_qup3_spi_apps_clk.c, GCC_BASE, 0x0093},
-	{&gcc_blsp1_qup3_i2c_apps_clk.c, GCC_BASE, 0x0094},
-	{   &gcc_blsp1_uart3_apps_clk.c, GCC_BASE, 0x0095},
-	{&gcc_blsp1_qup4_spi_apps_clk.c, GCC_BASE, 0x0098},
-	{&gcc_blsp1_qup4_i2c_apps_clk.c, GCC_BASE, 0x0099},
-	{   &gcc_blsp1_uart4_apps_clk.c, GCC_BASE, 0x009a},
-	{&gcc_blsp1_qup5_spi_apps_clk.c, GCC_BASE, 0x009c},
-	{&gcc_blsp1_qup5_i2c_apps_clk.c, GCC_BASE, 0x009d},
-	{   &gcc_blsp1_uart5_apps_clk.c, GCC_BASE, 0x009e},
-	{&gcc_blsp1_qup6_spi_apps_clk.c, GCC_BASE, 0x00a1},
-	{&gcc_blsp1_qup6_i2c_apps_clk.c, GCC_BASE, 0x00a2},
-	{   &gcc_blsp1_uart6_apps_clk.c, GCC_BASE, 0x00a3},
-	{            &gcc_pdm_ahb_clk.c, GCC_BASE, 0x00d0},
-	{               &gcc_pdm2_clk.c, GCC_BASE, 0x00d2},
-	{           &gcc_prng_ahb_clk.c, GCC_BASE, 0x00d8},
-	{       &gcc_boot_rom_ahb_clk.c, GCC_BASE, 0x00f8},
-	{                &gcc_ce1_clk.c, GCC_BASE, 0x0138},
-	{            &gcc_ce1_axi_clk.c, GCC_BASE, 0x0139},
-	{            &gcc_ce1_ahb_clk.c, GCC_BASE, 0x013a},
-	{             &gcc_xo_clk_src.c, GCC_BASE, 0x0149},
-	{                   &bimc_clk.c, GCC_BASE, 0x0154},
-	{       &gcc_lpass_q6_axi_clk.c, GCC_BASE, 0x0160},
-
-	{&mmss_mmssnoc_ahb_clk.c, MMSS_BASE, 0x0001},
-	{   &mmss_misc_ahb_clk.c, MMSS_BASE, 0x0003},
-	{&mmss_mmssnoc_axi_clk.c, MMSS_BASE, 0x0004},
-	{     &mmss_s0_axi_clk.c, MMSS_BASE, 0x0005},
-	{       &oxili_ahb_clk.c, MMSS_BASE, 0x0007},
-	{     &oxili_gfx3d_clk.c, MMSS_BASE, 0x0008},
-	{      &gmem_gfx3d_clk.c, MMSS_BASE, 0x0009},
-	{         &mdp_axi_clk.c, MMSS_BASE, 0x000a},
-	{       &mdp_vsync_clk.c, MMSS_BASE, 0x000b},
-	{         &mdp_ahb_clk.c, MMSS_BASE, 0x000c},
-	{        &dsi_pclk_clk.c, MMSS_BASE, 0x000d},
-	{         &mdp_dsi_clk.c, MMSS_BASE, 0x000e},
-	{        &mdp_lcdc_clk.c, MMSS_BASE, 0x000f},
-	{             &dsi_clk.c, MMSS_BASE, 0x0010},
-	{        &dsi_byte_clk.c, MMSS_BASE, 0x0011},
-	{         &dsi_esc_clk.c, MMSS_BASE, 0x0012},
-	{         &dsi_ahb_clk.c, MMSS_BASE, 0x0013},
-	{           &mclk0_clk.c, MMSS_BASE, 0x0015},
-	{           &mclk1_clk.c, MMSS_BASE, 0x0016},
-	{    &csi0phytimer_clk.c, MMSS_BASE, 0x0017},
-	{    &csi1phytimer_clk.c, MMSS_BASE, 0x0018},
-	{             &vfe_clk.c, MMSS_BASE, 0x0019},
-	{         &vfe_ahb_clk.c, MMSS_BASE, 0x001a},
-	{         &vfe_axi_clk.c, MMSS_BASE, 0x001b},
-	{         &csi_vfe_clk.c, MMSS_BASE, 0x001c},
-	{            &csi0_clk.c, MMSS_BASE, 0x001d},
-	{         &csi_ahb_clk.c, MMSS_BASE, 0x001e},
-	{         &csi0phy_clk.c, MMSS_BASE, 0x001f},
-	{         &csi0rdi_clk.c, MMSS_BASE, 0x0020},
-	{         &csi0pix_clk.c, MMSS_BASE, 0x0021},
-	{            &csi1_clk.c, MMSS_BASE, 0x0022},
-	{         &csi1phy_clk.c, MMSS_BASE, 0x0023},
-	{         &csi1rdi_clk.c, MMSS_BASE, 0x0024},
-	{         &csi1pix_clk.c, MMSS_BASE, 0x0025},
-	{        &bimc_gfx_clk.c, MMSS_BASE, 0x0032},
-
-	{             &lpaif_pcmoe_clk_src.c, LPASS_BASE, 0x000f},
-	{              &lpaif_pcm1_clk_src.c, LPASS_BASE, 0x0012},
-	{              &lpaif_pcm0_clk_src.c, LPASS_BASE, 0x0013},
-	{              &lpaif_quad_clk_src.c, LPASS_BASE, 0x0014},
-	{               &lpaif_ter_clk_src.c, LPASS_BASE, 0x0015},
-	{               &lpaif_sec_clk_src.c, LPASS_BASE, 0x0016},
-	{               &lpaif_pri_clk_src.c, LPASS_BASE, 0x0017},
-	{              &lpaif_spkr_clk_src.c, LPASS_BASE, 0x0018},
-	{                   &q6ss_ahbm_clk.c, LPASS_BASE, 0x001d},
-	{             &q6ss_ahb_lfabif_clk.c, LPASS_BASE, 0x001e},
-	{            &audio_wrapper_br_clk.c, LPASS_BASE, 0x0022},
-	{                     &q6ss_xo_clk.c, LPASS_BASE, 0x002b},
-	{&audio_core_lpaif_pcm_data_oe_clk.c, LPASS_BASE, 0x0030},
-	{         &audio_core_ixfabric_clk.c, LPASS_BASE, 0x0059},
-
-	{&dummy_clk, N_BASES, 0x0000},
-};
-
-#define GCC_DEBUG_CLK_CTL		0x1880
-#define MMSS_DEBUG_CLK_CTL		0x0900
-#define LPASS_DEBUG_CLK_CTL		0x29000
-#define GLB_CLK_DIAG			0x001C
-
-static int measure_clk_set_parent(struct clk *c, struct clk *parent)
-{
-	struct measure_clk *clk = to_measure_clk(c);
-	unsigned long flags;
-	u32 regval, clk_sel, i;
-
-	if (!parent)
-		return -EINVAL;
-
-	for (i = 0; i < (ARRAY_SIZE(measure_mux) - 1); i++)
-		if (measure_mux[i].c == parent)
-			break;
-
-	if (measure_mux[i].c == &dummy_clk)
-		return -EINVAL;
-
-	spin_lock_irqsave(&local_clock_reg_lock, flags);
-	/*
-	 * Program the test vector, measurement period (sample_ticks)
-	 * and scaling multiplier.
-	 */
-	clk->sample_ticks = 0x10000;
-	clk->multiplier = 1;
-
-	switch (measure_mux[i].base) {
-
-	case GCC_BASE:
-		writel_relaxed(0, GCC_REG_BASE(GCC_DEBUG_CLK_CTL));
-		clk_sel = measure_mux[i].debug_mux;
-		break;
-
-	case MMSS_BASE:
-		writel_relaxed(0, MMSS_REG_BASE(MMSS_DEBUG_CLK_CTL));
-		clk_sel = 0x02C;
-		regval = BVAL(11, 0, measure_mux[i].debug_mux);
-		writel_relaxed(regval, MMSS_REG_BASE(MMSS_DEBUG_CLK_CTL));
-
-		/* Activate debug clock output */
-		regval |= BIT(16);
-		writel_relaxed(regval, MMSS_REG_BASE(MMSS_DEBUG_CLK_CTL));
-		break;
-
-	case LPASS_BASE:
-		writel_relaxed(0, LPASS_REG_BASE(LPASS_DEBUG_CLK_CTL));
-		clk_sel = 0x161;
-		regval = BVAL(11, 0, measure_mux[i].debug_mux);
-		writel_relaxed(regval, LPASS_REG_BASE(LPASS_DEBUG_CLK_CTL));
-
-		/* Activate debug clock output */
-		regval |= BIT(20);
-		writel_relaxed(regval, LPASS_REG_BASE(LPASS_DEBUG_CLK_CTL));
-		break;
-
-	case APCS_BASE:
-		clk->multiplier = 4;
-		clk_sel = 0x16A;
-		regval = measure_mux[i].debug_mux;
-		writel_relaxed(regval, APCS_REG_BASE(GLB_CLK_DIAG));
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	/* Set debug mux clock index */
-	regval = BVAL(8, 0, clk_sel);
-	writel_relaxed(regval, GCC_REG_BASE(GCC_DEBUG_CLK_CTL));
-
-	/* Activate debug clock output */
-	regval |= BIT(16);
-	writel_relaxed(regval, GCC_REG_BASE(GCC_DEBUG_CLK_CTL));
-
-	/* Make sure test vector is set before starting measurements. */
-	mb();
-	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
-
-	return 0;
-}
-
-#define CLOCK_FRQ_MEASURE_CTL		0x1884
-#define CLOCK_FRQ_MEASURE_STATUS	0x1888
-
-/* Sample clock for 'ticks' reference clock ticks. */
-static u32 run_measurement(unsigned ticks)
-{
-	/* Stop counters and set the XO4 counter start value. */
-	writel_relaxed(ticks, GCC_REG_BASE(CLOCK_FRQ_MEASURE_CTL));
-
-	/* Wait for timer to become ready. */
-	while ((readl_relaxed(GCC_REG_BASE(CLOCK_FRQ_MEASURE_STATUS)) &
-			BIT(25)) != 0)
-		cpu_relax();
-
-	/* Run measurement and wait for completion. */
-	writel_relaxed(BIT(20)|ticks, GCC_REG_BASE(CLOCK_FRQ_MEASURE_CTL));
-	while ((readl_relaxed(GCC_REG_BASE(CLOCK_FRQ_MEASURE_STATUS)) &
-			BIT(25)) == 0)
-		cpu_relax();
-
-	/* Return measured ticks. */
-	return readl_relaxed(GCC_REG_BASE(CLOCK_FRQ_MEASURE_STATUS)) &
-				BM(24, 0);
-}
-
-#define GCC_XO_DIV4_CBCR	0x10C8
-#define PLLTEST_PAD_CFG		0x188C
-
-/*
- * Perform a hardware rate measurement for a given clock.
- * FOR DEBUG USE ONLY: Measurements take ~15 ms!
- */
-static unsigned long measure_clk_get_rate(struct clk *c)
-{
-	unsigned long flags;
-	u32 gcc_xo4_reg_backup;
-	u64 raw_count_short, raw_count_full;
-	struct measure_clk *clk = to_measure_clk(c);
-	unsigned ret;
-
-	ret = clk_prepare_enable(&gcc_xo_clk_src.c);
-	if (ret) {
-		pr_warning("CXO clock failed to enable. Can't measure\n");
-		return 0;
-	}
-
-	spin_lock_irqsave(&local_clock_reg_lock, flags);
-
-	/* Enable CXO/4 and RINGOSC branch. */
-	gcc_xo4_reg_backup = readl_relaxed(GCC_REG_BASE(GCC_XO_DIV4_CBCR));
-	writel_relaxed(0x1, GCC_REG_BASE(GCC_XO_DIV4_CBCR));
-
-	/*
-	 * The ring oscillator counter will not reset if the measured clock
-	 * is not running.  To detect this, run a short measurement before
-	 * the full measurement.  If the raw results of the two are the same
-	 * then the clock must be off.
-	 */
-
-	/* Run a short measurement. (~1 ms) */
-	raw_count_short = run_measurement(0x1000);
-	/* Run a full measurement. (~14 ms) */
-	raw_count_full = run_measurement(clk->sample_ticks);
-
-	writel_relaxed(gcc_xo4_reg_backup, GCC_REG_BASE(GCC_XO_DIV4_CBCR));
-
-	/* Return 0 if the clock is off. */
-	if (raw_count_full == raw_count_short) {
-		ret = 0;
-	} else {
-		/* Compute rate in Hz. */
-		raw_count_full = ((raw_count_full * 10) + 15) * 4800000;
-		do_div(raw_count_full, ((clk->sample_ticks * 10) + 35));
-		ret = (raw_count_full * clk->multiplier);
-	}
-
-	writel_relaxed(0x51A00, GCC_REG_BASE(PLLTEST_PAD_CFG));
-	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
-
-	clk_disable_unprepare(&gcc_xo_clk_src.c);
-
-	return ret;
-}
-#else /* !CONFIG_DEBUG_FS */
-static int measure_clk_set_parent(struct clk *clk, struct clk *parent)
-{
-	return -EINVAL;
-}
-
-static unsigned long measure_clk_get_rate(struct clk *clk)
-{
-	return 0;
-}
-#endif /* CONFIG_DEBUG_FS */
-
-static struct clk_ops clk_ops_measure = {
-	.set_parent = measure_clk_set_parent,
-	.get_rate = measure_clk_get_rate,
-};
-
-static struct measure_clk measure_clk = {
-	.c = {
-		.dbg_name = "measure_clk",
-		.ops = &clk_ops_measure,
-		CLK_INIT(measure_clk.c),
-	},
-	.multiplier = 1,
-};
-
-static struct clk_lookup msm_clocks_8910[] = {
-	CLK_LOOKUP("xo",	gcc_xo_clk_src.c, "msm_otg"),
-	CLK_LOOKUP("xo",	gcc_xo_clk_src.c, "fe200000.qcom,lpass"),
-	CLK_LOOKUP("xo",	gcc_xo_clk_src.c, "pil-q6v5-mss"),
-	CLK_LOOKUP("xo",	gcc_xo_clk_src.c, "pil-mba"),
-	CLK_LOOKUP("xo",	gcc_xo_clk_src.c, "fb000000.qcom,wcnss-wlan"),
-	CLK_LOOKUP("xo",	gcc_xo_clk_src.c, "pil_pronto"),
-	CLK_LOOKUP("measure",	measure_clk.c,	"debug"),
-
-	CLK_LOOKUP("iface_clk",  gcc_blsp1_ahb_clk.c, "f991f000.serial"),
-	CLK_LOOKUP("core_clk",  gcc_blsp1_uart3_apps_clk.c, "f991f000.serial"),
-
-	CLK_LOOKUP("dfab_clk", pnoc_sps_clk.c, "msm_sps"),
-	CLK_LOOKUP("bus_clk",  pnoc_qseecom_clk.c, "qseecom"),
-
-	CLK_LOOKUP("bus_clk", snoc_clk.c, ""),
-	CLK_LOOKUP("bus_clk", pnoc_clk.c, ""),
-	CLK_LOOKUP("bus_clk", cnoc_clk.c, ""),
-	CLK_LOOKUP("mem_clk", bimc_clk.c, ""),
-	CLK_LOOKUP("bus_clk", snoc_a_clk.c, ""),
-	CLK_LOOKUP("bus_clk", pnoc_a_clk.c, ""),
-	CLK_LOOKUP("bus_clk", cnoc_a_clk.c, ""),
-	CLK_LOOKUP("mem_clk", bimc_a_clk.c, ""),
-
-	CLK_LOOKUP("bus_clk",	cnoc_msmbus_clk.c,	"msm_config_noc"),
-	CLK_LOOKUP("bus_a_clk",	cnoc_msmbus_a_clk.c,	"msm_config_noc"),
-	CLK_LOOKUP("bus_clk",	snoc_msmbus_clk.c,	"msm_sys_noc"),
-	CLK_LOOKUP("bus_a_clk",	snoc_msmbus_a_clk.c,	"msm_sys_noc"),
-	CLK_LOOKUP("bus_clk",	pnoc_msmbus_clk.c,	"msm_periph_noc"),
-	CLK_LOOKUP("bus_a_clk",	pnoc_msmbus_a_clk.c,	"msm_periph_noc"),
-	CLK_LOOKUP("mem_clk",	bimc_msmbus_clk.c,	"msm_bimc"),
-	CLK_LOOKUP("mem_a_clk",	bimc_msmbus_a_clk.c,	"msm_bimc"),
-	CLK_LOOKUP("mem_clk",	bimc_acpu_a_clk.c,	""),
-
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-tmc-etr"),
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-tpiu"),
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-replicator"),
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-tmc-etf"),
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-funnel-merg"),
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-funnel-in0"),
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-funnel-in1"),
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-funnel-kpss"),
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-funnel-mmss"),
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-stm"),
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-etm0"),
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-etm1"),
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-etm2"),
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-etm3"),
-
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-tmc-etr"),
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-tpiu"),
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-replicator"),
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-tmc-etf"),
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-funnel-merg"),
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-funnel-in0"),
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-funnel-in1"),
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-funnel-kpss"),
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-funnel-mmss"),
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-stm"),
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-etm0"),
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-etm1"),
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-etm2"),
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-etm3"),
-
-	CLK_LOOKUP("core_clk_src", blsp1_qup1_spi_apps_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src", blsp1_qup2_spi_apps_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src", blsp1_qup3_spi_apps_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src", blsp1_qup4_spi_apps_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src", blsp1_qup5_spi_apps_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src", blsp1_qup6_spi_apps_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",    blsp1_uart1_apps_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",    blsp1_uart2_apps_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",    blsp1_uart3_apps_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",    blsp1_uart4_apps_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",    blsp1_uart5_apps_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",    blsp1_uart6_apps_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",                 ce1_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",                 gp1_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",                 gp2_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",                 gp3_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",                pdm2_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",          sdcc1_apps_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",          sdcc2_apps_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",       usb_hs_system_clk_src.c, ""),
-
-	CLK_LOOKUP("iface_clk",            gcc_blsp1_ahb_clk.c, ""),
-	CLK_LOOKUP("core_clk",  gcc_blsp1_qup1_i2c_apps_clk.c, ""),
-	CLK_LOOKUP("core_clk",  gcc_blsp1_qup1_spi_apps_clk.c, ""),
-	CLK_LOOKUP("core_clk",  gcc_blsp1_qup2_i2c_apps_clk.c, ""),
-	CLK_LOOKUP("core_clk",  gcc_blsp1_qup2_spi_apps_clk.c, ""),
-	CLK_LOOKUP("core_clk",  gcc_blsp1_qup3_i2c_apps_clk.c, ""),
-	CLK_LOOKUP("core_clk",  gcc_blsp1_qup3_spi_apps_clk.c, ""),
-	CLK_LOOKUP("core_clk",  gcc_blsp1_qup4_i2c_apps_clk.c, ""),
-	CLK_LOOKUP("core_clk",  gcc_blsp1_qup4_spi_apps_clk.c, ""),
-	CLK_LOOKUP("core_clk",  gcc_blsp1_qup5_i2c_apps_clk.c, ""),
-	CLK_LOOKUP("core_clk",  gcc_blsp1_qup5_spi_apps_clk.c, ""),
-	CLK_LOOKUP("core_clk",  gcc_blsp1_qup6_i2c_apps_clk.c, ""),
-	CLK_LOOKUP("core_clk",  gcc_blsp1_qup6_spi_apps_clk.c, ""),
-	CLK_LOOKUP("core_clk",     gcc_blsp1_uart1_apps_clk.c, ""),
-	CLK_LOOKUP("core_clk",     gcc_blsp1_uart2_apps_clk.c, ""),
-	CLK_LOOKUP("core_clk",     gcc_blsp1_uart3_apps_clk.c, ""),
-	CLK_LOOKUP("core_clk",     gcc_blsp1_uart4_apps_clk.c, ""),
-	CLK_LOOKUP("core_clk",     gcc_blsp1_uart5_apps_clk.c, ""),
-	CLK_LOOKUP("core_clk",     gcc_blsp1_uart6_apps_clk.c, ""),
-	CLK_LOOKUP("iface_clk",         gcc_boot_rom_ahb_clk.c, ""),
-	CLK_LOOKUP("iface_clk",              gcc_ce1_ahb_clk.c, ""),
-	CLK_LOOKUP("core_clk",              gcc_ce1_axi_clk.c, ""),
-	CLK_LOOKUP("core_clk",                  gcc_ce1_clk.c, ""),
-	CLK_LOOKUP("iface_clk",       gcc_copss_smmu_ahb_clk.c, ""),
-	CLK_LOOKUP("iface_clk",        gcc_lpss_smmu_ahb_clk.c, ""),
-	CLK_LOOKUP("core_clk",                  gcc_gp1_clk.c, ""),
-	CLK_LOOKUP("core_clk",                  gcc_gp2_clk.c, ""),
-	CLK_LOOKUP("core_clk",                  gcc_gp3_clk.c, ""),
-	CLK_LOOKUP("core_clk",         gcc_lpass_q6_axi_clk.c, ""),
-	CLK_LOOKUP("iface_clk",          gcc_mss_cfg_ahb_clk.c, ""),
-	CLK_LOOKUP("core_clk",      gcc_mss_q6_bimc_axi_clk.c, ""),
-	CLK_LOOKUP("core_clk",                 gcc_pdm2_clk.c, ""),
-	CLK_LOOKUP("iface_clk",              gcc_pdm_ahb_clk.c, ""),
-	CLK_LOOKUP("iface_clk",             gcc_prng_ahb_clk.c, ""),
-	CLK_LOOKUP("iface_clk",            gcc_sdcc1_ahb_clk.c, "msm_sdcc.1"),
-	CLK_LOOKUP("core_clk",           gcc_sdcc1_apps_clk.c, "msm_sdcc.1"),
-	CLK_LOOKUP("iface_clk",            gcc_sdcc2_ahb_clk.c, "msm_sdcc.2"),
-	CLK_LOOKUP("core_clk",           gcc_sdcc2_apps_clk.c, "msm_sdcc.2"),
-	CLK_LOOKUP("core_clk",      gcc_usb2a_phy_sleep_clk.c, ""),
-	CLK_LOOKUP("iface_clk",           gcc_usb_hs_ahb_clk.c, "f9a55000.usb"),
-	CLK_LOOKUP("core_clk",        gcc_usb_hs_system_clk.c, "f9a55000.usb"),
-
-	CLK_LOOKUP("core_clk_src",                csi0_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",                 axi_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",            dsi_pclk_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",               gfx3d_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",                 vfe_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",                csi1_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",        csi0phytimer_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",        csi1phytimer_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",                 dsi_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",            dsi_byte_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",             dsi_esc_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",               mclk0_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",               mclk1_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",           mdp_vsync_clk_src.c, ""),
-
-	CLK_LOOKUP("core_clk",                 bimc_gfx_clk.c, ""),
-	CLK_LOOKUP("core_clk",                     csi0_clk.c, ""),
-	CLK_LOOKUP("core_clk",                  csi0phy_clk.c, ""),
-	CLK_LOOKUP("core_clk",             csi0phytimer_clk.c, ""),
-	CLK_LOOKUP("core_clk",                  csi0pix_clk.c, ""),
-	CLK_LOOKUP("core_clk",                  csi0rdi_clk.c, ""),
-	CLK_LOOKUP("core_clk",                     csi1_clk.c, ""),
-	CLK_LOOKUP("core_clk",                  csi1phy_clk.c, ""),
-	CLK_LOOKUP("core_clk",             csi1phytimer_clk.c, ""),
-	CLK_LOOKUP("core_clk",                  csi1pix_clk.c, ""),
-	CLK_LOOKUP("core_clk",                  csi1rdi_clk.c, ""),
-	CLK_LOOKUP("core_clk",                  csi_ahb_clk.c, ""),
-	CLK_LOOKUP("core_clk",                  csi_vfe_clk.c, ""),
-	CLK_LOOKUP("core_clk",                      dsi_clk.c, ""),
-	CLK_LOOKUP("core_clk",                  dsi_ahb_clk.c, ""),
-	CLK_LOOKUP("core_clk",                 dsi_byte_clk.c, ""),
-	CLK_LOOKUP("core_clk",                  dsi_esc_clk.c, ""),
-	CLK_LOOKUP("core_clk",                 dsi_pclk_clk.c, ""),
-	CLK_LOOKUP("core_clk",               gmem_gfx3d_clk.c, ""),
-	CLK_LOOKUP("core_clk",                    mclk0_clk.c, ""),
-	CLK_LOOKUP("core_clk",                    mclk1_clk.c, ""),
-	CLK_LOOKUP("core_clk",                  mdp_ahb_clk.c, ""),
-	CLK_LOOKUP("core_clk",                  mdp_axi_clk.c, ""),
-	CLK_LOOKUP("core_clk",                  mdp_dsi_clk.c, ""),
-	CLK_LOOKUP("core_clk",                 mdp_lcdc_clk.c, ""),
-	CLK_LOOKUP("core_clk",                mdp_vsync_clk.c, ""),
-	CLK_LOOKUP("core_clk",            mmss_misc_ahb_clk.c, ""),
-	CLK_LOOKUP("core_clk",              mmss_s0_axi_clk.c, ""),
-	CLK_LOOKUP("core_clk",         mmss_mmssnoc_ahb_clk.c, ""),
-	CLK_LOOKUP("core_clk",     mmss_mmssnoc_bto_ahb_clk.c, ""),
-	CLK_LOOKUP("core_clk",         mmss_mmssnoc_axi_clk.c, ""),
-	CLK_LOOKUP("core_clk",                      vfe_clk.c, ""),
-	CLK_LOOKUP("core_clk",                  vfe_ahb_clk.c, ""),
-	CLK_LOOKUP("core_clk",                  vfe_axi_clk.c, ""),
-
-	CLK_LOOKUP("core_clk",   oxili_gfx3d_clk.c, "fdc00000.qcom,kgsl-3d0"),
-	CLK_LOOKUP("iface_clk",    oxili_ahb_clk.c, "fdc00000.qcom,kgsl-3d0"),
-	CLK_LOOKUP("mem_iface_clk", bimc_gfx_clk.c, "fdc00000.qcom,kgsl-3d0"),
-	CLK_LOOKUP("mem_clk",     gmem_gfx3d_clk.c, "fdc00000.qcom,kgsl-3d0"),
-
-	CLK_LOOKUP("iface_clk",           vfe_ahb_clk.c, "fd890000.qcom,iommu"),
-	CLK_LOOKUP("core_clk",            vfe_axi_clk.c, "fd890000.qcom,iommu"),
-	CLK_LOOKUP("iface_clk",           mdp_ahb_clk.c, "fd860000.qcom,iommu"),
-	CLK_LOOKUP("core_clk",            mdp_axi_clk.c, "fd860000.qcom,iommu"),
-	CLK_LOOKUP("iface_clk",           mdp_ahb_clk.c, "fd870000.qcom,iommu"),
-	CLK_LOOKUP("core_clk",            mdp_axi_clk.c, "fd870000.qcom,iommu"),
-	CLK_LOOKUP("iface_clk",         oxili_ahb_clk.c, "fd880000.qcom,iommu"),
-	CLK_LOOKUP("core_clk",           bimc_gfx_clk.c, "fd880000.qcom,iommu"),
-	CLK_LOOKUP("iface_clk", gcc_lpss_smmu_ahb_clk.c, "fd000000.qcom,iommu"),
-	CLK_LOOKUP("core_clk",   gcc_lpass_q6_axi_clk.c, "fd000000.qcom,iommu"),
-	CLK_LOOKUP("iface_clk", gcc_copss_smmu_ahb_clk.c,
-							 "fd010000.qcom,iommu"),
-	CLK_LOOKUP("core_clk",         pnoc_iommu_clk.c, "fd010000.qcom,iommu"),
-
-	CLK_LOOKUP("core_clk_src",                 lpaif_pri_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",                lpaif_quad_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",                 lpaif_sec_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",                lpaif_spkr_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",                 lpaif_ter_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",                lpaif_pcm0_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",                lpaif_pcm1_clk_src.c, ""),
-	CLK_LOOKUP("core_clk_src",               lpaif_pcmoe_clk_src.c, ""),
-	CLK_LOOKUP("core_clk",               audio_core_ixfabric_clk.c, ""),
-	CLK_LOOKUP("core_clk",                  audio_wrapper_br_clk.c, ""),
-	CLK_LOOKUP("core_clk",                   q6ss_ahb_lfabif_clk.c, ""),
-	CLK_LOOKUP("core_clk",                         q6ss_ahbm_clk.c, ""),
-	CLK_LOOKUP("core_clk",                           q6ss_xo_clk.c, ""),
-	CLK_LOOKUP("core_clk",      audio_core_lpaif_pcm_data_oe_clk.c, ""),
-	CLK_LOOKUP("core_clk",         audio_core_lpaif_pri_ebit_clk.c, ""),
-	CLK_LOOKUP("core_clk",         audio_core_lpaif_pri_ibit_clk.c, ""),
-	CLK_LOOKUP("core_clk",          audio_core_lpaif_pri_osr_clk.c, ""),
-	CLK_LOOKUP("core_clk",        audio_core_lpaif_pcm0_ebit_clk.c, ""),
-	CLK_LOOKUP("core_clk",        audio_core_lpaif_pcm0_ibit_clk.c, ""),
-	CLK_LOOKUP("core_clk",        audio_core_lpaif_quad_ebit_clk.c, ""),
-	CLK_LOOKUP("core_clk",        audio_core_lpaif_quad_ibit_clk.c, ""),
-	CLK_LOOKUP("core_clk",         audio_core_lpaif_quad_osr_clk.c, ""),
-	CLK_LOOKUP("core_clk",         audio_core_lpaif_sec_ebit_clk.c, ""),
-	CLK_LOOKUP("core_clk",         audio_core_lpaif_sec_ibit_clk.c, ""),
-	CLK_LOOKUP("core_clk",          audio_core_lpaif_sec_osr_clk.c, ""),
-	CLK_LOOKUP("core_clk",        audio_core_lpaif_pcm1_ebit_clk.c, ""),
-	CLK_LOOKUP("core_clk",        audio_core_lpaif_pcm1_ibit_clk.c, ""),
-	CLK_LOOKUP("core_clk",  audio_core_lpaif_codec_spkr_ebit_clk.c, ""),
-	CLK_LOOKUP("core_clk",  audio_core_lpaif_codec_spkr_ibit_clk.c, ""),
-	CLK_LOOKUP("core_clk",   audio_core_lpaif_codec_spkr_osr_clk.c, ""),
-	CLK_LOOKUP("core_clk",         audio_core_lpaif_ter_ebit_clk.c, ""),
-	CLK_LOOKUP("core_clk",         audio_core_lpaif_ter_ibit_clk.c, ""),
-	CLK_LOOKUP("core_clk",          audio_core_lpaif_ter_osr_clk.c, ""),
-
-	CLK_LOOKUP("core_clk",         q6ss_xo_clk.c,  "fe200000.qcom,lpass"),
-	CLK_LOOKUP("bus_clk", gcc_lpass_q6_axi_clk.c,  "fe200000.qcom,lpass"),
-	CLK_LOOKUP("iface_clk", q6ss_ahb_lfabif_clk.c, "fe200000.qcom,lpass"),
-	CLK_LOOKUP("reg_clk",        q6ss_ahbm_clk.c,  "fe200000.qcom,lpass"),
-};
-
-static struct clk_lookup msm_clocks_8910_rumi[] = {
-	CLK_DUMMY("core_clk",   BLSP1_UART_CLK, "f991f000.serial", OFF),
-	CLK_DUMMY("iface_clk",  BLSP1_UART_CLK, "f991f000.serial", OFF),
-	CLK_DUMMY("iface_clk",  HSUSB_IFACE_CLK, "f9a55000.usb", OFF),
-	CLK_DUMMY("core_clk",	HSUSB_CORE_CLK, "f9a55000.usb", OFF),
-	CLK_DUMMY("iface_clk",	NULL,		"msm_sdcc.1", OFF),
-	CLK_DUMMY("core_clk",	NULL,		"msm_sdcc.1", OFF),
-	CLK_DUMMY("bus_clk",	NULL,		"msm_sdcc.1", OFF),
-	CLK_DUMMY("iface_clk",	NULL,		"msm_sdcc.2", OFF),
-	CLK_DUMMY("core_clk",	NULL,		"msm_sdcc.2", OFF),
-	CLK_DUMMY("bus_clk",	NULL,		"msm_sdcc.2", OFF),
-	CLK_DUMMY("dfab_clk",	DFAB_CLK,	"msm_sps", OFF),
-	CLK_DUMMY("iface_clk",  NULL, "fd890000.qcom,iommu", OFF),
-	CLK_DUMMY("core_clk",   NULL, "fd890000.qcom,iommu", OFF),
-	CLK_DUMMY("iface_clk",  NULL, "fd860000.qcom,iommu", OFF),
-	CLK_DUMMY("core_clk",   NULL, "fd860000.qcom,iommu", OFF),
-	CLK_DUMMY("iface_clk",  NULL, "fd870000.qcom,iommu", OFF),
-	CLK_DUMMY("core_clk",   NULL, "fd870000.qcom,iommu", OFF),
-	CLK_DUMMY("iface_clk",  NULL, "fd880000.qcom,iommu", OFF),
-	CLK_DUMMY("core_clk",   NULL, "fd880000.qcom,iommu", OFF),
-	CLK_DUMMY("iface_clk",  NULL, "fd000000.qcom,iommu", OFF),
-	CLK_DUMMY("core_clk",   NULL, "fd000000.qcom,iommu", OFF),
-	CLK_DUMMY("iface_clk",  NULL, "fd010000.qcom,iommu", OFF),
-	CLK_DUMMY("core_clk",   NULL, "fd010000.qcom,iommu", OFF),
-};
-
-struct clock_init_data msm8910_rumi_clock_init_data __initdata = {
-	.table = msm_clocks_8910_rumi,
-	.size = ARRAY_SIZE(msm_clocks_8910_rumi),
-};
-
-static struct pll_config_regs gpll0_regs __initdata = {
-	.l_reg = (void __iomem *)GPLL0_L_VAL,
-	.m_reg = (void __iomem *)GPLL0_M_VAL,
-	.n_reg = (void __iomem *)GPLL0_N_VAL,
-	.config_reg = (void __iomem *)GPLL0_USER_CTL,
-	.mode_reg = (void __iomem *)GPLL0_MODE,
-	.base = &virt_bases[GCC_BASE],
-};
-
-/* GPLL0 at 600 MHz, main output enabled. */
-static struct pll_config gpll0_config __initdata = {
-	.l = 0x1f,
-	.m = 0x1,
-	.n = 0x4,
-	.vco_val = 0x0,
-	.vco_mask = BM(21, 20),
-	.pre_div_val = 0x0,
-	.pre_div_mask = BM(14, 12),
-	.post_div_val = 0x0,
-	.post_div_mask = BM(9, 8),
-	.mn_ena_val = BIT(24),
-	.mn_ena_mask = BIT(24),
-	.main_output_val = BIT(0),
-	.main_output_mask = BIT(0),
-};
-
-/* MMPLL0 at 800 MHz, main output enabled. */
-static struct pll_config mmpll0_config __initdata = {
-	.l = 0x29,
-	.m = 0x2,
-	.n = 0x3,
-	.vco_val = 0x0,
-	.vco_mask = BM(21, 20),
-	.pre_div_val = 0x0,
-	.pre_div_mask = BM(14, 12),
-	.post_div_val = 0x0,
-	.post_div_mask = BM(9, 8),
-	.mn_ena_val = BIT(24),
-	.mn_ena_mask = BIT(24),
-	.main_output_val = BIT(0),
-	.main_output_mask = BIT(0),
-};
-
-/* MMPLL1 at 1200 MHz, main output enabled. */
-static struct pll_config mmpll1_config __initdata = {
-	.l = 0x3E,
-	.m = 0x1,
-	.n = 0x2,
-	.vco_val = 0x0,
-	.vco_mask = BM(21, 20),
-	.pre_div_val = 0x0,
-	.pre_div_mask = BM(14, 12),
-	.post_div_val = 0x0,
-	.post_div_mask = BM(9, 8),
-	.mn_ena_val = BIT(24),
-	.mn_ena_mask = BIT(24),
-	.main_output_val = BIT(0),
-	.main_output_mask = BIT(0),
-};
-
-static struct pll_config_regs lpapll0_regs __initdata = {
-	.l_reg = (void __iomem *)LPAAUDIO_PLL_L_VAL,
-	.m_reg = (void __iomem *)LPAAUDIO_PLL_M_VAL,
-	.n_reg = (void __iomem *)LPAAUDIO_PLL_N_VAL,
-	.config_reg = (void __iomem *)LPAAUDIO_PLL_USER_CTL,
-	.mode_reg = (void __iomem *)LPAAUDIO_PLL_MODE,
-	.base = &virt_bases[LPASS_BASE],
-};
-
-/* LPAPLL0 at 491.52 MHz, main output enabled. */
-static struct pll_config lpapll0_config __initdata = {
-	.l = 0x33,
-	.m = 0x1,
-	.n = 0x5,
-	.vco_val = 0x0,
-	.vco_mask = BM(21, 20),
-	.pre_div_val = BVAL(14, 12, 0x1),
-	.pre_div_mask = BM(14, 12),
-	.post_div_val = 0x0,
-	.post_div_mask = BM(9, 8),
-	.mn_ena_val = BIT(24),
-	.mn_ena_mask = BIT(24),
-	.main_output_val = BIT(0),
-	.main_output_mask = BIT(0),
-};
-
-#define PLL_AUX_OUTPUT_BIT 1
-#define PLL_AUX2_OUTPUT_BIT 2
-
-#define PWR_ON_MASK		BIT(31)
-#define EN_REST_WAIT_MASK	(0xF << 20)
-#define EN_FEW_WAIT_MASK	(0xF << 16)
-#define CLK_DIS_WAIT_MASK	(0xF << 12)
-#define SW_OVERRIDE_MASK	BIT(2)
-#define HW_CONTROL_MASK		BIT(1)
-#define SW_COLLAPSE_MASK	BIT(0)
-
-/* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */
-#define EN_REST_WAIT_VAL	(0x2 << 20)
-#define EN_FEW_WAIT_VAL		(0x2 << 16)
-#define CLK_DIS_WAIT_VAL	(0x2 << 12)
-#define GDSC_TIMEOUT_US		50000
-
-static void __init reg_init(void)
-{
-	u32 regval, status;
-	int ret;
-
-	if (!(readl_relaxed(GCC_REG_BASE(GPLL0_STATUS))
-			& gpll0_clk_src.status_mask))
-		configure_sr_hpm_lp_pll(&gpll0_config, &gpll0_regs, 1);
-
-	configure_sr_hpm_lp_pll(&mmpll0_config, &mmpll0_regs, 1);
-	configure_sr_hpm_lp_pll(&mmpll1_config, &mmpll1_regs, 1);
-	configure_sr_hpm_lp_pll(&lpapll0_config, &lpapll0_regs, 1);
-
-	/* Enable GPLL0's aux outputs. */
-	regval = readl_relaxed(GCC_REG_BASE(GPLL0_USER_CTL));
-	regval |= BIT(PLL_AUX_OUTPUT_BIT) | BIT(PLL_AUX2_OUTPUT_BIT);
-	writel_relaxed(regval, GCC_REG_BASE(GPLL0_USER_CTL));
-
-	/* Vote for GPLL0 to turn on. Needed by acpuclock. */
-	regval = readl_relaxed(GCC_REG_BASE(APCS_GPLL_ENA_VOTE));
-	regval |= BIT(0);
-	writel_relaxed(regval, GCC_REG_BASE(APCS_GPLL_ENA_VOTE));
-
-	/*
-	 * TODO: Confirm that no clocks need to be voted on in this sleep vote
-	 * register.
-	 */
-	writel_relaxed(0x0, GCC_REG_BASE(APCS_CLOCK_SLEEP_ENA_VOTE));
-
-	/*
-	 * TODO: The following sequence enables the LPASS audio core GDSC.
-	 * Remove when this becomes unnecessary.
-	 */
-
-	/*
-	 * Disable HW trigger: collapse/restore occur based on registers writes.
-	 * Disable SW override: Use hardware state-machine for sequencing.
-	 */
-	regval = readl_relaxed(LPASS_REG_BASE(AUDIO_CORE_GDSCR));
-	regval &= ~(HW_CONTROL_MASK | SW_OVERRIDE_MASK);
-
-	/* Configure wait time between states. */
-	regval &= ~(EN_REST_WAIT_MASK | EN_FEW_WAIT_MASK | CLK_DIS_WAIT_MASK);
-	regval |= EN_REST_WAIT_VAL | EN_FEW_WAIT_VAL | CLK_DIS_WAIT_VAL;
-	writel_relaxed(regval, LPASS_REG_BASE(AUDIO_CORE_GDSCR));
-
-	regval = readl_relaxed(LPASS_REG_BASE(AUDIO_CORE_GDSCR));
-	regval &= ~BIT(0);
-	writel_relaxed(regval, LPASS_REG_BASE(AUDIO_CORE_GDSCR));
-
-	ret = readl_poll_timeout(LPASS_REG_BASE(AUDIO_CORE_GDSCR), status,
-				status & PWR_ON_MASK, 50, GDSC_TIMEOUT_US);
-	WARN(ret, "LPASS Audio Core GDSC did not power on.\n");
-}
-
-static void __init msm8910_clock_post_init(void)
-{
-	/*
-	 * Hold an active set vote for CXO; this is because CXO is expected
-	 * to remain on whenever CPUs aren't power collapsed.
-	 */
-	clk_prepare_enable(&gcc_xo_a_clk_src.c);
-
-
-	/* Set rates for single-rate clocks. */
-	clk_set_rate(&usb_hs_system_clk_src.c,
-			usb_hs_system_clk_src.freq_tbl[0].freq_hz);
-	clk_set_rate(&pdm2_clk_src.c, pdm2_clk_src.freq_tbl[0].freq_hz);
-	clk_set_rate(&mclk0_clk_src.c, mclk0_clk_src.freq_tbl[0].freq_hz);
-	clk_set_rate(&mclk1_clk_src.c, mclk1_clk_src.freq_tbl[0].freq_hz);
-	clk_set_rate(&audio_core_slimbus_core_clk_src.c,
-			audio_core_slimbus_core_clk_src.freq_tbl[0].freq_hz);
-}
-
-#define GCC_CC_PHYS		0xFC400000
-#define GCC_CC_SIZE		SZ_16K
-
-#define MMSS_CC_PHYS		0xFD8C0000
-#define MMSS_CC_SIZE		SZ_256K
-
-#define LPASS_CC_PHYS		0xFE000000
-#define LPASS_CC_SIZE		SZ_256K
-
-#define APCS_GCC_CC_PHYS	0xF9011000
-#define APCS_GCC_CC_SIZE	SZ_4K
-
-static void __init msm8910_clock_pre_init(void)
-{
-	virt_bases[GCC_BASE] = ioremap(GCC_CC_PHYS, GCC_CC_SIZE);
-	if (!virt_bases[GCC_BASE])
-		panic("clock-8910: Unable to ioremap GCC memory!");
-
-	virt_bases[MMSS_BASE] = ioremap(MMSS_CC_PHYS, MMSS_CC_SIZE);
-	if (!virt_bases[MMSS_BASE])
-		panic("clock-8910: Unable to ioremap MMSS_CC memory!");
-
-	virt_bases[LPASS_BASE] = ioremap(LPASS_CC_PHYS, LPASS_CC_SIZE);
-	if (!virt_bases[LPASS_BASE])
-		panic("clock-8910: Unable to ioremap LPASS_CC memory!");
-
-	virt_bases[APCS_BASE] = ioremap(APCS_GCC_CC_PHYS, APCS_GCC_CC_SIZE);
-	if (!virt_bases[APCS_BASE])
-		panic("clock-8910: Unable to ioremap APCS_GCC_CC memory!");
-
-	clk_ops_local_pll.enable = sr_hpm_lp_pll_clk_enable;
-
-	vdd_dig_reg = rpm_regulator_get(NULL, "vdd_dig");
-	if (IS_ERR(vdd_dig_reg))
-		panic("clock-8910: Unable to get the vdd_dig regulator!");
-
-	/*
-	 * TODO: Set a voltage and enable vdd_dig, leaving the voltage high
-	 * until late_init. This may not be necessary with clock handoff;
-	 * Investigate this code on a real non-simulator target to determine
-	 * its necessity.
-	 */
-	vote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
-	rpm_regulator_enable(vdd_dig_reg);
-
-	enable_rpm_scaling();
-
-	/* Enable a clock to allow access to MMSS clock registers */
-	clk_prepare_enable(&gcc_mmss_noc_cfg_ahb_clk.c),
-
-	reg_init();
-
-	/* TODO: Remove this once the bus driver is in place */
-	clk_set_rate(&ahb_clk_src.c,  40000000);
-	clk_set_rate(&axi_clk_src.c, 200000000);
-	clk_prepare_enable(&mmss_mmssnoc_ahb_clk.c);
-	clk_prepare_enable(&mmss_s0_axi_clk.c);
-
-	/* TODO: Temporarily enable a clock to allow access to LPASS core
-	 * registers.
-	 */
-	clk_prepare_enable(&audio_core_ixfabric_clk.c);
-}
-
-static int __init msm8910_clock_late_init(void)
-{
-	return unvote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
-}
-
-struct clock_init_data msm8910_clock_init_data __initdata = {
-	.table = msm_clocks_8910,
-	.size = ARRAY_SIZE(msm_clocks_8910),
-	.pre_init = msm8910_clock_pre_init,
-	.post_init = msm8910_clock_post_init,
-	.late_init = msm8910_clock_late_init,
-};
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 7038b06..aefaa5c 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
@@ -85,7 +85,12 @@
 #define BB_PLL8_CONFIG_REG			REG(0x3154)
 #define BB_PLL8_TEST_CTL_REG			REG(0x3150)
 #define BB_MMCC_PLL2_MODE_REG			REG(0x3160)
+#define BB_MMCC_PLL2_L_REG			REG(0x3164)
+#define BB_MMCC_PLL2_M_REG			REG(0x3168)
+#define BB_MMCC_PLL2_N_REG			REG(0x316C)
 #define BB_MMCC_PLL2_TEST_CTL_REG		REG(0x3170)
+#define BB_MMCC_PLL2_CONFIG_REG			REG(0x3174)
+#define BB_MMCC_PLL2_STATUS_REG			REG(0x3178)
 #define BB_PLL14_MODE_REG			REG(0x31C0)
 #define BB_PLL14_L_VAL_REG			REG(0x31C4)
 #define BB_PLL14_M_VAL_REG			REG(0x31C8)
@@ -114,6 +119,7 @@
 #define SATA_RXOOB_CLK_CTL_REG			REG(0x2C0C)
 #define SATA_PMALIVE_CLK_CTL_REG		REG(0x2C10)
 #define SATA_PHY_REF_CLK_CTL_REG		REG(0x2C14)
+#define SATA_RESET				REG(0x2C1C)
 #define SATA_ACLK_CTL_REG			REG(0x2C20)
 #define SATA_PHY_CFG_CLK_CTL_REG		REG(0x2C40)
 #define USB_FSn_HCLK_CTL_REG(n)			REG(0x2960+(0x20*((n)-1)))
@@ -2085,6 +2091,8 @@
 		.en_mask = BIT(4),
 		.halt_reg = CLK_HALT_MSS_SMPSS_MISC_STATE_REG,
 		.halt_bit = 27,
+		.reset_reg = SATA_RESET,
+		.reset_mask = BIT(0),
 	},
 	.c = {
 		.dbg_name = "sata_p_clk",
@@ -3046,22 +3054,30 @@
 	return -ENXIO;
 }
 
-static enum handoff pix_rdi_clk_handoff(struct clk *c)
+static struct clk *pix_rdi_clk_get_parent(struct clk *c)
 {
 	u32 reg;
 	struct pix_rdi_clk *rdi = to_pix_rdi_clk(c);
+
+	reg = readl_relaxed(rdi->s_reg);
+	rdi->cur_rate = reg & rdi->s_mask ? 1 : 0;
+	reg = readl_relaxed(rdi->s2_reg);
+	rdi->cur_rate = reg & rdi->s2_mask ? 2 : rdi->cur_rate;
+
+	return pix_rdi_mux_map[rdi->cur_rate];
+}
+
+static enum handoff pix_rdi_clk_handoff(struct clk *c)
+{
+	struct pix_rdi_clk *rdi = to_pix_rdi_clk(c);
 	enum handoff ret;
 
 	ret = branch_handoff(&rdi->b, &rdi->c);
 	if (ret == HANDOFF_DISABLED_CLK)
 		return ret;
 
-	reg = readl_relaxed(rdi->s_reg);
-	rdi->cur_rate = reg & rdi->s_mask ? 1 : 0;
-	reg = readl_relaxed(rdi->s2_reg);
-	rdi->cur_rate = reg & rdi->s2_mask ? 2 : rdi->cur_rate;
-	c->parent = pix_rdi_mux_map[rdi->cur_rate];
-
+	rdi->prepared = true;
+	rdi->enabled = true;
 	return HANDOFF_ENABLED_CLK;
 }
 
@@ -3075,6 +3091,7 @@
 	.get_rate = pix_rdi_clk_get_rate,
 	.list_rate = pix_rdi_clk_list_rate,
 	.reset = pix_rdi_clk_reset,
+	.get_parent = pix_rdi_clk_get_parent,
 };
 
 static struct pix_rdi_clk csi_pix_clk = {
@@ -3506,7 +3523,7 @@
 		.ctl_val = CC_BANKED(9, 6, n), \
 	}
 
-/*Shared by 8064, 8930, and 8960ab*/
+/*Shared by 8064, and 8930*/
 static struct clk_freq_tbl clk_tbl_gfx3d[] = {
 	F_GFX3D(        0, gnd,   0,  0),
 	F_GFX3D( 27000000, pxo,   0,  0),
@@ -3529,6 +3546,28 @@
 	F_END
 };
 
+static struct clk_freq_tbl clk_tbl_gfx3d_8960ab[] = {
+	F_GFX3D(        0, gnd,   0,  0),
+	F_GFX3D( 27000000, pxo,   0,  0),
+	F_GFX3D( 48000000, pll8,  1,  8),
+	F_GFX3D( 54857000, pll8,  1,  7),
+	F_GFX3D( 64000000, pll8,  1,  6),
+	F_GFX3D( 76800000, pll8,  1,  5),
+	F_GFX3D( 96000000, pll8,  1,  4),
+	F_GFX3D(128000000, pll8,  1,  3),
+	F_GFX3D(145455000, pll2,  2, 11),
+	F_GFX3D(160000000, pll2,  1,  5),
+	F_GFX3D(177778000, pll2,  2,  9),
+	F_GFX3D(192000000, pll8,  1,  2),
+	F_GFX3D(200000000, pll2,  1,  4),
+	F_GFX3D(228571000, pll2,  2,  7),
+	F_GFX3D(266667000, pll2,  1,  3),
+	F_GFX3D(320000000, pll2,  2,  5),
+	F_GFX3D(400000000, pll2,  1,  2),
+	F_GFX3D(440000000, pll3,  1,  2),
+	F_END
+};
+
 static struct clk_freq_tbl clk_tbl_gfx3d_8960[] = {
 	F_GFX3D(        0, gnd,  0,  0),
 	F_GFX3D( 27000000, pxo,  0,  0),
@@ -3602,6 +3641,23 @@
 	[VDD_DIG_HIGH]    = 500000000
 };
 
+static unsigned long fmax_gfx3d_8960ab_400[VDD_DIG_NUM] = {
+	[VDD_DIG_LOW]     = 192000000,
+	[VDD_DIG_NOMINAL] = 325000000,
+	[VDD_DIG_HIGH]    = 400000000
+};
+
+static unsigned long fmax_gfx3d_8960ab_440[VDD_DIG_NUM] = {
+	[VDD_DIG_LOW]     = 192000000,
+	[VDD_DIG_NOMINAL] = 325000000,
+	[VDD_DIG_HIGH]    = 440000000
+};
+
+static unsigned long *fmax_gfx3d_8960ab[] = {
+	[0] = fmax_gfx3d_8960ab_400,
+	[1] = fmax_gfx3d_8960ab_440,
+};
+
 static struct bank_masks bmnd_info_gfx3d = {
 	.bank_sel_mask =		BIT(11),
 	.bank0_mask = {
@@ -3834,26 +3890,6 @@
 		.ns_val = NS_MND_BANKED8(22, 14, n, m, 3, 0, s##_to_mm_mux), \
 		.ctl_val = CC_BANKED(9, 6, n), \
 	}
-static struct clk_freq_tbl clk_tbl_mdp_8960ab[] = {
-	F_MDP(        0, gnd,  0,  0),
-	F_MDP(  9600000, pll8, 1, 40),
-	F_MDP( 13710000, pll8, 1, 28),
-	F_MDP( 27000000, pxo,  0,  0),
-	F_MDP( 29540000, pll8, 1, 13),
-	F_MDP( 34910000, pll8, 1, 11),
-	F_MDP( 38400000, pll8, 1, 10),
-	F_MDP( 59080000, pll8, 2, 13),
-	F_MDP( 76800000, pll8, 1,  5),
-	F_MDP( 85330000, pll8, 2,  9),
-	F_MDP( 96000000, pll8, 1,  4),
-	F_MDP(128000000, pll8, 1,  3),
-	F_MDP(160000000, pll2, 1,  5),
-	F_MDP(177780000, pll2, 2,  9),
-	F_MDP(200000000, pll2, 1,  4),
-	F_MDP(228571000, pll2, 2,  7),
-	F_MDP(266667000, pll2, 1,  3),
-	F_END
-};
 
 static struct clk_freq_tbl clk_tbl_mdp[] = {
 	F_MDP(        0, gnd,  0,  0),
@@ -3871,6 +3907,7 @@
 	F_MDP(160000000, pll2, 1,  5),
 	F_MDP(177780000, pll2, 2,  9),
 	F_MDP(200000000, pll2, 1,  4),
+	F_MDP(228571000, pll2, 2,  7),
 	F_MDP(266667000, pll2, 1,  3),
 	F_END
 };
@@ -3924,6 +3961,11 @@
 	},
 };
 
+static unsigned long fmax_mdp_8960ab[VDD_DIG_NUM] = {
+	[VDD_DIG_LOW]     = 128000000,
+	[VDD_DIG_NOMINAL] = 266667000
+};
+
 static struct branch_clk lut_mdp_clk = {
 	.b = {
 		.ctl_reg = MDP_LUT_CC_REG,
@@ -4095,6 +4137,7 @@
 	F_TV( 27000000, hdmi_pll,  27000000, 1, 0, 0),
 	F_TV( 27030000, hdmi_pll,  27030000, 1, 0, 0),
 	F_TV( 74250000, hdmi_pll,  74250000, 1, 0, 0),
+	F_TV(108000000, hdmi_pll, 108000000, 1, 0, 0),
 	F_TV(148500000, hdmi_pll, 148500000, 1, 0, 0),
 	F_END
 };
@@ -5280,8 +5323,10 @@
 	CLK_LOOKUP("core_clk",		gp2_clk.c,		""),
 	CLK_LOOKUP("core_clk",		gsbi1_uart_clk.c, "msm_serial_hsl.1"),
 	CLK_LOOKUP("core_clk",		gsbi2_uart_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi2_uart_clk.c, "msm_serial_hsl.3"),
 	CLK_LOOKUP("core_clk",		gsbi3_uart_clk.c,	""),
 	CLK_LOOKUP("core_clk",		gsbi4_uart_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi4_uart_clk.c, "msm_serial_hsl.4"),
 	CLK_LOOKUP("core_clk",		gsbi5_uart_clk.c, "msm_serial_hsl.2"),
 	CLK_LOOKUP("core_clk",		gsbi6_uart_clk.c, "msm_serial_hs.0"),
 	CLK_LOOKUP("core_clk",		gsbi7_uart_clk.c, "msm_serial_hsl.0"),
@@ -5311,14 +5356,14 @@
 	CLK_LOOKUP("src_clk",		usb_fs1_src_clk.c,	""),
 	CLK_LOOKUP("alt_core_clk",	usb_fs1_xcvr_clk.c,	""),
 	CLK_LOOKUP("sys_clk",		usb_fs1_sys_clk.c,	""),
-	CLK_LOOKUP("ref_clk",		sata_phy_ref_clk.c,	""),
-	CLK_LOOKUP("cfg_clk",		sata_phy_cfg_clk.c,	""),
-	CLK_LOOKUP("src_clk",		sata_src_clk.c,		""),
-	CLK_LOOKUP("core_rxoob_clk",	sata_rxoob_clk.c,	""),
-	CLK_LOOKUP("core_pmalive_clk",	sata_pmalive_clk.c,	""),
-	CLK_LOOKUP("bus_clk",		sata_a_clk.c,		""),
-	CLK_LOOKUP("iface_clk",		sata_p_clk.c,		""),
-	CLK_LOOKUP("slave_iface_clk",	sfab_sata_s_p_clk.c,	""),
+	CLK_LOOKUP("ref_clk",		sata_phy_ref_clk.c,	"msm_sata.0"),
+	CLK_LOOKUP("cfg_clk",		sata_phy_cfg_clk.c,	"msm_sata.0"),
+	CLK_LOOKUP("src_clk",		sata_src_clk.c,		"msm_sata.0"),
+	CLK_LOOKUP("core_rxoob_clk",	sata_rxoob_clk.c,	"msm_sata.0"),
+	CLK_LOOKUP("core_pmalive_clk",	sata_pmalive_clk.c,	"msm_sata.0"),
+	CLK_LOOKUP("bus_clk",		sata_a_clk.c,		"msm_sata.0"),
+	CLK_LOOKUP("iface_clk",		sata_p_clk.c,		"msm_sata.0"),
+	CLK_LOOKUP("slave_iface_clk",	sfab_sata_s_p_clk.c,	"msm_sata.0"),
 	CLK_LOOKUP("iface_clk",		ce3_p_clk.c,		"qce.0"),
 	CLK_LOOKUP("iface_clk",		ce3_p_clk.c,		"qcrypto.0"),
 	CLK_LOOKUP("core_clk",		ce3_core_clk.c,		"qce.0"),
@@ -5329,6 +5374,7 @@
 	CLK_LOOKUP("iface_clk",		gsbi1_p_clk.c,	"msm_serial_hsl.1"),
 	CLK_LOOKUP("iface_clk",		gsbi1_p_clk.c,	"qup_i2c.0"),
 	CLK_LOOKUP("iface_clk",		gsbi2_p_clk.c,		""),
+	CLK_LOOKUP("iface_clk",		gsbi2_p_clk.c,	"msm_serial_hsl.3"),
 	CLK_LOOKUP("iface_clk",		gsbi3_p_clk.c,		"qup_i2c.3"),
 	CLK_LOOKUP("iface_clk",		gsbi4_p_clk.c,		"qup_i2c.4"),
 	CLK_LOOKUP("iface_clk",		gsbi5_p_clk.c,	"msm_serial_hsl.2"),
@@ -5337,6 +5383,7 @@
 	CLK_LOOKUP("iface_clk",		gsbi6_p_clk.c,	"msm_serial_hs.0"),
 	CLK_LOOKUP("iface_clk",		gsbi6_p_clk.c,		"spi_qsd.1"),
 	CLK_LOOKUP("iface_clk",		gsbi7_p_clk.c,	"msm_serial_hsl.0"),
+	CLK_LOOKUP("iface_clk",		gsbi7_p_clk.c,	"msm_serial_hsl.4"),
 	CLK_LOOKUP("ref_clk",	tsif_ref_clk.c,	"msm_tspp.0"),
 	CLK_LOOKUP("iface_clk",		tsif_p_clk.c,		"msm_tspp.0"),
 	CLK_LOOKUP("iface_clk",		usb_fs1_p_clk.c,	""),
@@ -5459,18 +5506,18 @@
 	CLK_LOOKUP("mem_iface_clk",	imem_p_clk.c,	"kgsl-3d0.0"),
 	CLK_LOOKUP("iface_clk",		mdp_p_clk.c,		"mdp.0"),
 	CLK_LOOKUP("iface_clk",		mdp_p_clk.c,	"footswitch-8x60.4"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.0"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.1"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.2"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.3"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.4"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.5"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.6"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.7"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.8"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.9"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.10"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.11"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.0"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.1"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.2"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.3"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.4"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.5"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.6"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.7"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.8"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.9"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.10"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.11"),
 	CLK_LOOKUP("iface_clk",		rot_p_clk.c,	"msm_rotator.0"),
 	CLK_LOOKUP("iface_clk",		rot_p_clk.c,	"footswitch-8x60.6"),
 	CLK_LOOKUP("iface_clk",		vcodec_p_clk.c,		"msm_vidc.0"),
@@ -5537,19 +5584,19 @@
 	CLK_LOOKUP("core_clk",	      usb_hsic_system_clk.c,   "msm_hsic_host"),
 	CLK_LOOKUP("iface_clk",	      usb_hsic_p_clk.c,        "msm_hsic_host"),
 
-	CLK_LOOKUP("core_clk",		jpegd_axi_clk.c,	"msm_iommu.0"),
-	CLK_LOOKUP("core_clk",		vpe_axi_clk.c,		"msm_iommu.1"),
-	CLK_LOOKUP("core_clk",		mdp_axi_clk.c,		"msm_iommu.2"),
-	CLK_LOOKUP("core_clk",		mdp_axi_clk.c,		"msm_iommu.3"),
-	CLK_LOOKUP("core_clk",		rot_axi_clk.c,		"msm_iommu.4"),
-	CLK_LOOKUP("core_clk",		ijpeg_axi_clk.c,	"msm_iommu.5"),
-	CLK_LOOKUP("core_clk",		vfe_axi_clk.c,		"msm_iommu.6"),
-	CLK_LOOKUP("core_clk",		vcodec_axi_a_clk.c,	"msm_iommu.7"),
-	CLK_LOOKUP("core_clk",		vcodec_axi_b_clk.c,	"msm_iommu.8"),
-	CLK_LOOKUP("core_clk",		gfx3d_axi_clk.c,	"msm_iommu.9"),
-	CLK_LOOKUP("core_clk",		gfx3d_axi_clk.c,	"msm_iommu.10"),
+	CLK_LOOKUP("core_clk",		jpegd_axi_clk.c,    "msm_iommu-v0.0"),
+	CLK_LOOKUP("core_clk",		vpe_axi_clk.c,	    "msm_iommu-v0.1"),
+	CLK_LOOKUP("core_clk",		mdp_axi_clk.c,	    "msm_iommu-v0.2"),
+	CLK_LOOKUP("core_clk",		mdp_axi_clk.c,	    "msm_iommu-v0.3"),
+	CLK_LOOKUP("core_clk",		rot_axi_clk.c,	    "msm_iommu-v0.4"),
+	CLK_LOOKUP("core_clk",		ijpeg_axi_clk.c,    "msm_iommu-v0.5"),
+	CLK_LOOKUP("core_clk",		vfe_axi_clk.c,	    "msm_iommu-v0.6"),
+	CLK_LOOKUP("core_clk",		vcodec_axi_a_clk.c, "msm_iommu-v0.7"),
+	CLK_LOOKUP("core_clk",		vcodec_axi_b_clk.c, "msm_iommu-v0.8"),
+	CLK_LOOKUP("core_clk",		gfx3d_axi_clk.c,    "msm_iommu-v0.9"),
+	CLK_LOOKUP("core_clk",		gfx3d_axi_clk.c,    "msm_iommu-v0.10"),
 
-	CLK_LOOKUP("core_clk",		vcap_axi_clk.c,		"msm_iommu.11"),
+	CLK_LOOKUP("core_clk",		vcap_axi_clk.c,	    "msm_iommu-v0.11"),
 
 	CLK_LOOKUP("mdp_iommu_clk", mdp_axi_clk.c,	"msm_vidc.0"),
 	CLK_LOOKUP("rot_iommu_clk",	rot_axi_clk.c,	"msm_vidc.0"),
@@ -5818,16 +5865,16 @@
 	CLK_LOOKUP("mem_iface_clk",	imem_p_clk.c,	"kgsl-3d0.0"),
 	CLK_LOOKUP("iface_clk",		mdp_p_clk.c,		"mdp.0"),
 	CLK_LOOKUP("iface_clk",		mdp_p_clk.c,	"footswitch-8x60.4"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.0"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.1"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.2"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.3"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.4"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.5"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.6"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.7"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.8"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.9"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.0"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.1"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.2"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.3"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.4"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.5"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.6"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.7"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.8"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.9"),
 	CLK_LOOKUP("iface_clk",		rot_p_clk.c,	"msm_rotator.0"),
 	CLK_LOOKUP("iface_clk",		rot_p_clk.c,	"footswitch-8x60.6"),
 	CLK_LOOKUP("iface_clk",		vcodec_p_clk.c,	"msm_vidc.0"),
@@ -5864,16 +5911,16 @@
 	CLK_LOOKUP("pcm_clk",		pcm_clk.c,		"msm-dai-q6.3"),
 	CLK_LOOKUP("sps_slimbus_clk",	sps_slimbus_clk.c,	NULL),
 	CLK_LOOKUP("core_clk",		audio_slimbus_clk.c, "msm_slim_ctrl.1"),
-	CLK_LOOKUP("core_clk",		jpegd_axi_clk.c,	"msm_iommu.0"),
-	CLK_LOOKUP("core_clk",		vpe_axi_clk.c,		"msm_iommu.1"),
-	CLK_LOOKUP("core_clk",		mdp_axi_clk.c,		"msm_iommu.2"),
-	CLK_LOOKUP("core_clk",		mdp_axi_clk.c,		"msm_iommu.3"),
-	CLK_LOOKUP("core_clk",		rot_axi_clk.c,		"msm_iommu.4"),
-	CLK_LOOKUP("core_clk",		ijpeg_axi_clk.c,	"msm_iommu.5"),
-	CLK_LOOKUP("core_clk",		vfe_axi_clk.c,		"msm_iommu.6"),
-	CLK_LOOKUP("core_clk",		vcodec_axi_a_clk.c,	"msm_iommu.7"),
-	CLK_LOOKUP("core_clk",		vcodec_axi_b_clk.c,	"msm_iommu.8"),
-	CLK_LOOKUP("core_clk",		gfx3d_clk.c,		"msm_iommu.9"),
+	CLK_LOOKUP("core_clk",		jpegd_axi_clk.c,    "msm_iommu-v0.0"),
+	CLK_LOOKUP("core_clk",		vpe_axi_clk.c,	    "msm_iommu-v0.1"),
+	CLK_LOOKUP("core_clk",		mdp_axi_clk.c,	    "msm_iommu-v0.2"),
+	CLK_LOOKUP("core_clk",		mdp_axi_clk.c,	    "msm_iommu-v0.3"),
+	CLK_LOOKUP("core_clk",		rot_axi_clk.c,	    "msm_iommu-v0.4"),
+	CLK_LOOKUP("core_clk",		ijpeg_axi_clk.c,    "msm_iommu-v0.5"),
+	CLK_LOOKUP("core_clk",		vfe_axi_clk.c,	    "msm_iommu-v0.6"),
+	CLK_LOOKUP("core_clk",		vcodec_axi_a_clk.c, "msm_iommu-v0.7"),
+	CLK_LOOKUP("core_clk",		vcodec_axi_b_clk.c, "msm_iommu-v0.8"),
+	CLK_LOOKUP("core_clk",		gfx3d_clk.c,	    "msm_iommu-v0.9"),
 
 	CLK_LOOKUP("mdp_iommu_clk", mdp_axi_clk.c,	"msm_vidc.0"),
 	CLK_LOOKUP("rot_iommu_clk",	rot_axi_clk.c,	"msm_vidc.0"),
@@ -5922,16 +5969,16 @@
 	CLK_LOOKUP("iface_clk",		gfx2d0_p_clk.c,	"footswitch-8x60.0"),
 	CLK_LOOKUP("iface_clk",		gfx2d1_p_clk.c,	"kgsl-2d1.1"),
 	CLK_LOOKUP("iface_clk",		gfx2d1_p_clk.c,	"footswitch-8x60.1"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,		"msm_iommu.10"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,		"msm_iommu.11"),
-	CLK_LOOKUP("core_clk",		gfx2d0_clk.c,		"msm_iommu.10"),
-	CLK_LOOKUP("core_clk",		gfx2d1_clk.c,		"msm_iommu.11"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.10"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.11"),
+	CLK_LOOKUP("core_clk",		gfx2d0_clk.c,	"msm_iommu-v0.10"),
+	CLK_LOOKUP("core_clk",		gfx2d1_clk.c,	"msm_iommu-v0.11"),
 };
 
 static struct clk_lookup msm_clocks_8960ab_only[] __initdata = {
 	CLK_LOOKUP("bus_clk", gfx3d_axi_clk.c, "footswitch-8x60.2"),
-	CLK_LOOKUP("iface_clk",	smmu_p_clk.c,	"msm_iommu.10"),
-	CLK_LOOKUP("core_clk", gfx3d_axi_clk.c, "msm_iommu.10"),
+	CLK_LOOKUP("iface_clk",	smmu_p_clk.c,	"msm_iommu-v0.10"),
+	CLK_LOOKUP("core_clk", gfx3d_axi_clk.c, "msm_iommu-v0.10"),
 	CLK_LOOKUP("div_clk",	tv_src_div_clk.c,	""),
 };
 
@@ -6167,17 +6214,17 @@
 	CLK_LOOKUP("mem_iface_clk",	imem_p_clk.c,	"kgsl-3d0.0"),
 	CLK_LOOKUP("iface_clk",		mdp_p_clk.c,		"mdp.0"),
 	CLK_LOOKUP("iface_clk",		mdp_p_clk.c,	"footswitch-8x60.4"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.0"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.1"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.2"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.3"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.4"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.5"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.6"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.7"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.8"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.9"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.10"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.0"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.1"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.2"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.3"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.4"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.5"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.6"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.7"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.8"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.9"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.10"),
 	CLK_LOOKUP("iface_clk",		rot_p_clk.c,	"msm_rotator.0"),
 	CLK_LOOKUP("iface_clk",		rot_p_clk.c,	"footswitch-8x60.6"),
 	CLK_LOOKUP("iface_clk",		vcodec_p_clk.c,	"msm_vidc.0"),
@@ -6211,16 +6258,16 @@
 	CLK_LOOKUP("pcm_clk",		pcm_clk.c,		"msm-dai-q6.2"),
 	CLK_LOOKUP("sps_slimbus_clk",	sps_slimbus_clk.c,	NULL),
 	CLK_LOOKUP("core_clk",		audio_slimbus_clk.c, "msm_slim_ctrl.1"),
-	CLK_LOOKUP("core_clk",		vpe_axi_clk.c,		"msm_iommu.1"),
-	CLK_LOOKUP("core_clk",		mdp_axi_clk.c,		"msm_iommu.2"),
-	CLK_LOOKUP("core_clk",		mdp_axi_clk.c,		"msm_iommu.3"),
-	CLK_LOOKUP("core_clk",		rot_axi_clk.c,		"msm_iommu.4"),
-	CLK_LOOKUP("core_clk",		ijpeg_axi_clk.c,	"msm_iommu.5"),
-	CLK_LOOKUP("core_clk",		vfe_axi_clk.c,		"msm_iommu.6"),
-	CLK_LOOKUP("core_clk",		vcodec_axi_a_clk.c,	"msm_iommu.7"),
-	CLK_LOOKUP("core_clk",		vcodec_axi_b_clk.c,	"msm_iommu.8"),
-	CLK_LOOKUP("core_clk",		gfx3d_axi_clk_8930.c,	"msm_iommu.9"),
-	CLK_LOOKUP("core_clk",		gfx3d_axi_clk_8930.c,	"msm_iommu.10"),
+	CLK_LOOKUP("core_clk",		vpe_axi_clk.c,	  "msm_iommu-v0.1"),
+	CLK_LOOKUP("core_clk",		mdp_axi_clk.c,	  "msm_iommu-v0.2"),
+	CLK_LOOKUP("core_clk",		mdp_axi_clk.c,	  "msm_iommu-v0.3"),
+	CLK_LOOKUP("core_clk",		rot_axi_clk.c,	  "msm_iommu-v0.4"),
+	CLK_LOOKUP("core_clk",		ijpeg_axi_clk.c,  "msm_iommu-v0.5"),
+	CLK_LOOKUP("core_clk",		vfe_axi_clk.c,	  "msm_iommu-v0.6"),
+	CLK_LOOKUP("core_clk",	   vcodec_axi_a_clk.c,    "msm_iommu-v0.7"),
+	CLK_LOOKUP("core_clk",	   vcodec_axi_b_clk.c,    "msm_iommu-v0.8"),
+	CLK_LOOKUP("core_clk",	   gfx3d_axi_clk_8930.c,  "msm_iommu-v0.9"),
+	CLK_LOOKUP("core_clk",	   gfx3d_axi_clk_8930.c,  "msm_iommu-v0.10"),
 
 	CLK_LOOKUP("mdp_iommu_clk", mdp_axi_clk.c,	"msm_vidc.0"),
 	CLK_LOOKUP("rot_iommu_clk",	rot_axi_clk.c,	"msm_vidc.0"),
@@ -6267,6 +6314,31 @@
 	writel_relaxed(regval, reg);
 }
 
+static struct pll_config_regs pll3_regs __initdata = {
+	.l_reg = BB_MMCC_PLL2_L_REG,
+	.m_reg = BB_MMCC_PLL2_M_REG,
+	.n_reg = BB_MMCC_PLL2_N_REG,
+	.config_reg = BB_MMCC_PLL2_CONFIG_REG,
+	.mode_reg = BB_MMCC_PLL2_MODE_REG,
+};
+
+/* Program PLL3 to 880MHZ */
+static struct pll_config pll3_config __initdata = {
+	.l = (32 | BVAL(31, 7, 0x8)),
+	.m = 16,
+	.n = 27,
+	.vco_val = 0x0,
+	.vco_mask = BM(8, 7),
+	.pre_div_val = 0x0,
+	.pre_div_mask = BIT(15),
+	.post_div_val = 0x0,
+	.post_div_mask = BIT(16),
+	.mn_ena_val = 0,
+	.mn_ena_mask = 0,
+	.main_output_val = 0,
+	.main_output_mask = 0,
+};
+
 static struct pll_config_regs pll4_regs __initdata = {
 	.l_reg = LCC_PLL0_L_VAL_REG,
 	.m_reg = LCC_PLL0_M_VAL_REG,
@@ -6366,7 +6438,7 @@
 		writel_relaxed(0x3C7097F9, AHB_EN2_REG);
 	}
 
-	if (cpu_is_apq8064() || cpu_is_apq8064ab())
+	if (soc_class_is_apq8064())
 		rmwreg(0x00000000, AHB_EN3_REG, 0x00000001);
 
 	/* Deassert all locally-owned MM AHB resets. */
@@ -6389,7 +6461,7 @@
 	rmwreg(0x0027FCFF, MAXI_EN3_REG, 0x003FFFFF);
 	rmwreg(0x0027FCFF, MAXI_EN4_REG, 0x017FFFFF);
 
-	if (cpu_is_apq8064() || cpu_is_apq8064ab())
+	if (soc_class_is_apq8064())
 		rmwreg(0x019FECFF, MAXI_EN5_REG, 0x01FFEFFF);
 	if (cpu_is_msm8930() || cpu_is_msm8930aa() || cpu_is_msm8627() ||
 	    cpu_is_msm8930ab())
@@ -6426,8 +6498,7 @@
 	rmwreg(0x80FF0000, VFE_CC_REG,        0xE0FF4010);
 	rmwreg(0x800000FF, VFE_CC2_REG,       0xE00000FF);
 	rmwreg(0x80FF0000, VPE_CC_REG,        0xE0FF0010);
-	if (cpu_is_msm8960ab() || cpu_is_msm8960() || cpu_is_apq8064()
-		 || cpu_is_apq8064ab()) {
+	if (cpu_is_msm8960ab() || cpu_is_msm8960() || soc_class_is_apq8064()) {
 		rmwreg(0x80FF0000, DSI2_BYTE_CC_REG,  0xE0FF0010);
 		rmwreg(0x80FF0000, DSI2_PIXEL_CC_REG, 0xE0FF0010);
 		rmwreg(0x80FF0000, JPEGD_CC_REG,      0xE0FF0010);
@@ -6445,7 +6516,7 @@
 		rmwreg(0x80FF0000, GFX2D0_CC_REG,     0xE0FF0010);
 		rmwreg(0x80FF0000, GFX2D1_CC_REG,     0xE0FF0010);
 	}
-	if (cpu_is_apq8064() || cpu_is_apq8064ab()) {
+	if (soc_class_is_apq8064()) {
 		rmwreg(0x00000000, TV_CC_REG,         0x00004010);
 		rmwreg(0x80FF0000, VCAP_CC_REG,       0xE0FF1010);
 	}
@@ -6456,7 +6527,7 @@
 	 * and wake-up value to max.
 	 */
 	rmwreg(0x0000004F, USB_HS1_HCLK_FS_REG, 0x0000007F);
-	if (cpu_is_apq8064() || cpu_is_apq8064ab()) {
+	if (soc_class_is_apq8064()) {
 		rmwreg(0x0000004F, USB_HS3_HCLK_FS_REG, 0x0000007F);
 		rmwreg(0x0000004F, USB_HS4_HCLK_FS_REG, 0x0000007F);
 	}
@@ -6478,8 +6549,7 @@
 
 	/* Source the dsi_byte_clks from the DSI PHY PLLs */
 	rmwreg(0x1, DSI1_BYTE_NS_REG, 0x7);
-	if (cpu_is_msm8960ab() || cpu_is_msm8960() || cpu_is_apq8064()
-		|| cpu_is_apq8064ab())
+	if (cpu_is_msm8960ab() || cpu_is_msm8960() || soc_class_is_apq8064())
 		rmwreg(0x2, DSI2_BYTE_NS_REG, 0x7);
 
 	/* Source the dsi1_esc_clk from the DSI1 PHY PLLs */
@@ -6489,7 +6559,7 @@
 	 * Source the sata_phy_ref_clk from PXO and set predivider of
 	 * sata_pmalive_clk to 1.
 	 */
-	if (cpu_is_apq8064() || cpu_is_apq8064ab()) {
+	if (soc_class_is_apq8064()) {
 		rmwreg(0, SATA_PHY_REF_CLK_CTL_REG, 0x1);
 		rmwreg(0, SATA_PMALIVE_CLK_CTL_REG, 0x3);
 	}
@@ -6498,7 +6568,7 @@
 	 * TODO: Programming below PLLs and prng_clk is temporary and
 	 *	 needs to be removed after bootloaders program them.
 	 */
-	if (cpu_is_apq8064() || cpu_is_apq8064ab()) {
+	if (soc_class_is_apq8064()) {
 		u32 is_pll_enabled;
 
 		/* Program pxo_src_clk to source from PXO */
@@ -6524,7 +6594,7 @@
 			writel_relaxed(0x2B, PRNG_CLK_NS_REG);
 	}
 
-	if (cpu_is_apq8064()) {
+	if (cpu_is_apq8064() || cpu_is_apq8064aa()) {
 		/* Program PLL15 to 975MHz with ref clk = 27MHz */
 		configure_sr_pll(&pll15_config, &pll15_regs, 0);
 	} else if (cpu_is_apq8064ab()) {
@@ -6533,6 +6603,9 @@
 		pll15_config.m = 0x1;
 		pll15_config.n = 0x3;
 		configure_sr_pll(&pll15_config, &pll15_regs, 0);
+	} else if (cpu_is_msm8960ab()) {
+		pll3_clk.c.rate = 880000000;
+		configure_sr_pll(&pll3_config, &pll3_regs, 0);
 	}
 
 	/*
@@ -6555,13 +6628,34 @@
 	}
 }
 
+#define PTE_EFUSE_GFX_PHYS (0x007000BC)
+
+static unsigned long *select_gfx_fmax_plan(unsigned long **gfx_fmax, int size)
+{
+	void __iomem *pte_efuse;
+	u32 gfx_speed_bin;
+
+	pte_efuse = ioremap(PTE_EFUSE_GFX_PHYS, 4);
+	gfx_speed_bin = readl_relaxed(pte_efuse);
+	gfx_speed_bin = (gfx_speed_bin & BM(25, 24)) >> 24;
+	iounmap(pte_efuse);
+
+	if (gfx_speed_bin >= size) {
+		pr_err("GFX_SPEED_BIN: defaulting to 0\n");
+		gfx_speed_bin = 0;
+	}
+
+	pr_info("GFX_SPEED_BIN: %d\n", gfx_speed_bin);
+	return gfx_fmax[gfx_speed_bin];
+}
+
 struct clock_init_data msm8960_clock_init_data __initdata;
 static void __init msm8960_clock_pre_init(void)
 {
 	/* Initialize clock registers. */
 	reg_init();
 
-	if (cpu_is_apq8064() || cpu_is_apq8064ab())
+	if (soc_class_is_apq8064())
 		vdd_sr2_hdmi_pll.set_vdd = set_vdd_sr2_hdmi_pll_8064;
 
 	/* Detect PLL4 programmed for alternate 491.52MHz clock plan. */
@@ -6580,13 +6674,11 @@
 		memcpy(msm_clocks_8960, msm_clocks_8960_common,
 			sizeof(msm_clocks_8960_common));
 	if (cpu_is_msm8960ab()) {
-		pll3_clk.c.rate = 650000000;
-		gfx3d_clk.c.fmax[VDD_DIG_LOW] = 192000000;
-		gfx3d_clk.c.fmax[VDD_DIG_NOMINAL] = 325000000;
-		gfx3d_clk.c.fmax[VDD_DIG_HIGH] = 400000000;
-		mdp_clk.freq_tbl = clk_tbl_mdp_8960ab;
-		mdp_clk.c.fmax[VDD_DIG_LOW] = 128000000;
-		mdp_clk.c.fmax[VDD_DIG_NOMINAL] = 266667000;
+		gfx3d_clk.freq_tbl = clk_tbl_gfx3d_8960ab;
+		mdp_clk.c.fmax = fmax_mdp_8960ab;
+
+		gfx3d_clk.c.fmax = select_gfx_fmax_plan(fmax_gfx3d_8960ab,
+						ARRAY_SIZE(fmax_gfx3d_8960ab));
 
 		memcpy(msm_clocks_8960 + ARRAY_SIZE(msm_clocks_8960_common),
 			msm_clocks_8960ab_only, sizeof(msm_clocks_8960ab_only));
@@ -6605,21 +6697,21 @@
 	 * Change the freq tables for and voltage requirements for
 	 * clocks which differ between chips.
 	 */
-	if (cpu_is_apq8064()) {
+	if (cpu_is_apq8064() || cpu_is_apq8064aa())
 		gfx3d_clk.c.fmax = fmax_gfx3d_8064;
-	}
-	if (cpu_is_apq8064ab()) {
+
+	if (cpu_is_apq8064ab())
 		gfx3d_clk.c.fmax = fmax_gfx3d_8064ab;
-	}
+
 	if ((cpu_is_apq8064() &&
 		SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 2) ||
-		cpu_is_apq8064ab()) {
+		cpu_is_apq8064ab() || cpu_is_apq8064aa()) {
 
 		vcodec_clk.c.fmax = fmax_vcodec_8064v2;
 		ce3_src_clk.c.fmax = fmax_ce3_8064v2;
 		sdc1_clk.c.fmax = fmax_sdc1_8064v2;
 	}
-	if (cpu_is_apq8064() || cpu_is_apq8064ab()) {
+	if (soc_class_is_apq8064()) {
 		ijpeg_clk.c.fmax = fmax_ijpeg_8064;
 		mdp_clk.c.fmax = fmax_mdp_8064;
 		tv_src_clk.c.fmax = fmax_tv_src_8064;
@@ -6692,7 +6784,7 @@
 	clk_set_rate(&tsif_ref_clk.c, 105000);
 	clk_set_rate(&tssc_clk.c, 27000000);
 	clk_set_rate(&usb_hs1_xcvr_clk.c, 60000000);
-	if (cpu_is_apq8064() || cpu_is_apq8064ab()) {
+	if (soc_class_is_apq8064()) {
 		clk_set_rate(&usb_hs3_xcvr_clk.c, 60000000);
 		clk_set_rate(&usb_hs4_xcvr_clk.c, 60000000);
 	}
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index 760587f..4cef377 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.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
@@ -112,6 +112,7 @@
 #define LPASS_LPA_PLL_VOTE_APPS_REG    0x2000
 
 #define GLB_CLK_DIAG_REG               0x001C
+#define L2_CBCR_REG                    0x004C
 
 #define USB30_MASTER_CMD_RCGR          0x03D4
 #define USB30_MOCK_UTMI_CMD_RCGR       0x03E8
@@ -128,28 +129,40 @@
 #define SDCC3_APPS_CMD_RCGR            0x0550
 #define SDCC4_APPS_CMD_RCGR            0x0590
 #define BLSP1_QUP1_SPI_APPS_CMD_RCGR   0x064C
+#define BLSP1_QUP1_I2C_APPS_CMD_RCGR   0x0660
 #define BLSP1_UART1_APPS_CMD_RCGR      0x068C
 #define BLSP1_QUP2_SPI_APPS_CMD_RCGR   0x06CC
+#define BLSP1_QUP2_I2C_APPS_CMD_RCGR   0x06E0
 #define BLSP1_UART2_APPS_CMD_RCGR      0x070C
 #define BLSP1_QUP3_SPI_APPS_CMD_RCGR   0x074C
+#define BLSP1_QUP3_I2C_APPS_CMD_RCGR   0x0760
 #define BLSP1_UART3_APPS_CMD_RCGR      0x078C
 #define BLSP1_QUP4_SPI_APPS_CMD_RCGR   0x07CC
+#define BLSP1_QUP4_I2C_APPS_CMD_RCGR   0x07E0
 #define BLSP1_UART4_APPS_CMD_RCGR      0x080C
 #define BLSP1_QUP5_SPI_APPS_CMD_RCGR   0x084C
+#define BLSP1_QUP5_I2C_APPS_CMD_RCGR   0x0860
 #define BLSP1_UART5_APPS_CMD_RCGR      0x088C
 #define BLSP1_QUP6_SPI_APPS_CMD_RCGR   0x08CC
+#define BLSP1_QUP6_I2C_APPS_CMD_RCGR   0x08E0
 #define BLSP1_UART6_APPS_CMD_RCGR      0x090C
 #define BLSP2_QUP1_SPI_APPS_CMD_RCGR   0x098C
+#define BLSP2_QUP1_I2C_APPS_CMD_RCGR   0x09A0
 #define BLSP2_UART1_APPS_CMD_RCGR      0x09CC
 #define BLSP2_QUP2_SPI_APPS_CMD_RCGR   0x0A0C
+#define BLSP2_QUP2_I2C_APPS_CMD_RCGR   0x0A20
 #define BLSP2_UART2_APPS_CMD_RCGR      0x0A4C
 #define BLSP2_QUP3_SPI_APPS_CMD_RCGR   0x0A8C
+#define BLSP2_QUP3_I2C_APPS_CMD_RCGR   0x0AA0
 #define BLSP2_UART3_APPS_CMD_RCGR      0x0ACC
 #define BLSP2_QUP4_SPI_APPS_CMD_RCGR   0x0B0C
+#define BLSP2_QUP4_I2C_APPS_CMD_RCGR   0x0B20
 #define BLSP2_UART4_APPS_CMD_RCGR      0x0B4C
 #define BLSP2_QUP5_SPI_APPS_CMD_RCGR   0x0B8C
+#define BLSP2_QUP5_I2C_APPS_CMD_RCGR   0x0BA0
 #define BLSP2_UART5_APPS_CMD_RCGR      0x0BCC
 #define BLSP2_QUP6_SPI_APPS_CMD_RCGR   0x0C0C
+#define BLSP2_QUP6_I2C_APPS_CMD_RCGR   0x0C20
 #define BLSP2_UART6_APPS_CMD_RCGR      0x0C4C
 #define PDM2_CMD_RCGR                  0x0CD0
 #define TSIF_REF_CMD_RCGR              0x0D90
@@ -513,7 +526,6 @@
 #define mm_gnd_source_val 6
 #define gpll1_hsic_source_val 4
 #define cxo_lpass_source_val 0
-#define lpapll0_lpass_source_val 1
 #define gpll0_lpass_source_val 5
 #define edppll_270_mm_source_val 4
 #define edppll_350_mm_source_val 4
@@ -662,9 +674,9 @@
 
 #define D0_ID		 1
 #define D1_ID		 2
-#define A0_ID		 3
-#define A1_ID		 4
-#define A2_ID		 5
+#define A0_ID		 4
+#define A1_ID		 5
+#define A2_ID		 6
 #define DIFF_CLK_ID	 7
 #define DIV_CLK1_ID	11
 #define DIV_CLK2_ID	12
@@ -729,21 +741,6 @@
 	},
 };
 
-static struct pll_vote_clk lpapll0_clk_src = {
-	.en_reg = (void __iomem *)LPASS_LPA_PLL_VOTE_APPS_REG,
-	.en_mask = BIT(0),
-	.status_reg = (void __iomem *)LPAPLL_STATUS_REG,
-	.status_mask = BIT(17),
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &cxo_clk_src.c,
-		.rate = 491520000,
-		.dbg_name = "lpapll0_clk_src",
-		.ops = &clk_ops_pll_vote,
-		CLK_INIT(lpapll0_clk_src.c),
-	},
-};
-
 static struct pll_vote_clk mmpll0_clk_src = {
 	.en_reg = (void __iomem *)MMSS_PLL_VOTE_APCS_REG,
 	.en_mask = BIT(0),
@@ -770,6 +767,8 @@
 		.dbg_name = "mmpll1_clk_src",
 		.rate = 846000000,
 		.ops = &clk_ops_pll_vote,
+		/* May be reassigned at runtime; alloc memory at compile time */
+		VDD_DIG_FMAX_MAP1(LOW, 846000000),
 		CLK_INIT(mmpll1_clk_src.c),
 	},
 };
@@ -781,7 +780,7 @@
 	.c = {
 		.parent = &cxo_clk_src.c,
 		.dbg_name = "mmpll3_clk_src",
-		.rate = 1000000000,
+		.rate = 820000000,
 		.ops = &clk_ops_local_pll,
 		CLK_INIT(mmpll3_clk_src.c),
 	},
@@ -804,6 +803,14 @@
 
 static DEFINE_CLK_VOTER(pnoc_sps_clk, &pnoc_clk.c, 0);
 
+static DEFINE_CLK_BRANCH_VOTER(cxo_otg_clk, &cxo_clk_src.c);
+static DEFINE_CLK_BRANCH_VOTER(cxo_pil_lpass_clk, &cxo_clk_src.c);
+static DEFINE_CLK_BRANCH_VOTER(cxo_pil_mss_clk, &cxo_clk_src.c);
+static DEFINE_CLK_BRANCH_VOTER(cxo_wlan_clk, &cxo_clk_src.c);
+static DEFINE_CLK_BRANCH_VOTER(cxo_pil_pronto_clk, &cxo_clk_src.c);
+static DEFINE_CLK_BRANCH_VOTER(cxo_dwc3_clk, &cxo_clk_src.c);
+static DEFINE_CLK_BRANCH_VOTER(cxo_ehci_host_clk, &cxo_clk_src.c);
+
 static struct clk_freq_tbl ftbl_gcc_usb30_master_clk[] = {
 	F(125000000,  gpll0,   1,   5,  24),
 	F_END
@@ -918,6 +925,95 @@
 	},
 };
 
+static struct clk_freq_tbl ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk[] = {
+	F(50000000,  gpll0,  12,   0,   0),
+	F_END
+};
+
+static struct rcg_clk blsp1_qup1_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP1_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup1_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 50000000),
+		CLK_INIT(blsp1_qup1_i2c_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup2_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP2_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup2_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 50000000),
+		CLK_INIT(blsp1_qup2_i2c_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup3_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP3_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup3_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 50000000),
+		CLK_INIT(blsp1_qup3_i2c_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup4_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP4_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup4_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 50000000),
+		CLK_INIT(blsp1_qup4_i2c_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup5_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP5_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup5_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 50000000),
+		CLK_INIT(blsp1_qup5_i2c_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup6_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP6_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup6_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 50000000),
+		CLK_INIT(blsp1_qup6_i2c_apps_clk_src.c),
+	},
+};
+
 static struct clk_freq_tbl ftbl_gcc_blsp1_2_uart1_6_apps_clk[] = {
 	F_GCC_GND,
 	F( 3686400,  gpll0,    1,  96,  15625),
@@ -934,6 +1030,7 @@
 	F(56000000,  gpll0,    1,   7,     75),
 	F(58982400,  gpll0,    1, 1536, 15625),
 	F(60000000,  gpll0,   10,   0,      0),
+	F(63160000,  gpll0,  9.5,   0,      0),
 	F_END
 };
 
@@ -1105,6 +1202,90 @@
 	},
 };
 
+static struct rcg_clk blsp2_qup1_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP2_QUP1_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp2_qup1_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 50000000),
+		CLK_INIT(blsp2_qup1_i2c_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp2_qup2_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP2_QUP2_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp2_qup2_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 50000000),
+		CLK_INIT(blsp2_qup2_i2c_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp2_qup3_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP2_QUP3_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp2_qup3_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 50000000),
+		CLK_INIT(blsp2_qup3_i2c_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp2_qup4_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP2_QUP4_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp2_qup4_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 50000000),
+		CLK_INIT(blsp2_qup4_i2c_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp2_qup5_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP2_QUP5_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp2_qup5_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 50000000),
+		CLK_INIT(blsp2_qup5_i2c_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp2_qup6_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP2_QUP6_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp2_qup6_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 50000000),
+		CLK_INIT(blsp2_qup6_i2c_apps_clk_src.c),
+	},
+};
+
 static struct rcg_clk blsp2_uart1_apps_clk_src = {
 	.cmd_rcgr_reg = BLSP2_UART1_APPS_CMD_RCGR,
 	.set_rate = set_rate_mnd,
@@ -1518,7 +1699,6 @@
 
 static struct branch_clk gcc_blsp1_qup1_i2c_apps_clk = {
 	.cbcr_reg = BLSP1_QUP1_I2C_APPS_CBCR,
-	.has_sibling = 1,
 	.base = &virt_bases[GCC_BASE],
 	.c = {
 		.parent = &cxo_clk_src.c,
@@ -1541,7 +1721,6 @@
 
 static struct branch_clk gcc_blsp1_qup2_i2c_apps_clk = {
 	.cbcr_reg = BLSP1_QUP2_I2C_APPS_CBCR,
-	.has_sibling = 1,
 	.base = &virt_bases[GCC_BASE],
 	.c = {
 		.parent = &cxo_clk_src.c,
@@ -1564,7 +1743,6 @@
 
 static struct branch_clk gcc_blsp1_qup3_i2c_apps_clk = {
 	.cbcr_reg = BLSP1_QUP3_I2C_APPS_CBCR,
-	.has_sibling = 1,
 	.base = &virt_bases[GCC_BASE],
 	.c = {
 		.parent = &cxo_clk_src.c,
@@ -1587,7 +1765,6 @@
 
 static struct branch_clk gcc_blsp1_qup4_i2c_apps_clk = {
 	.cbcr_reg = BLSP1_QUP4_I2C_APPS_CBCR,
-	.has_sibling = 1,
 	.base = &virt_bases[GCC_BASE],
 	.c = {
 		.parent = &cxo_clk_src.c,
@@ -1610,7 +1787,6 @@
 
 static struct branch_clk gcc_blsp1_qup5_i2c_apps_clk = {
 	.cbcr_reg = BLSP1_QUP5_I2C_APPS_CBCR,
-	.has_sibling = 1,
 	.base = &virt_bases[GCC_BASE],
 	.c = {
 		.parent = &cxo_clk_src.c,
@@ -1633,7 +1809,6 @@
 
 static struct branch_clk gcc_blsp1_qup6_i2c_apps_clk = {
 	.cbcr_reg = BLSP1_QUP6_I2C_APPS_CBCR,
-	.has_sibling = 1,
 	.base = &virt_bases[GCC_BASE],
 	.c = {
 		.parent = &cxo_clk_src.c,
@@ -1746,7 +1921,6 @@
 
 static struct branch_clk gcc_blsp2_qup1_i2c_apps_clk = {
 	.cbcr_reg = BLSP2_QUP1_I2C_APPS_CBCR,
-	.has_sibling = 1,
 	.base = &virt_bases[GCC_BASE],
 	.c = {
 		.parent = &cxo_clk_src.c,
@@ -1769,7 +1943,6 @@
 
 static struct branch_clk gcc_blsp2_qup2_i2c_apps_clk = {
 	.cbcr_reg = BLSP2_QUP2_I2C_APPS_CBCR,
-	.has_sibling = 1,
 	.base = &virt_bases[GCC_BASE],
 	.c = {
 		.parent = &cxo_clk_src.c,
@@ -1792,7 +1965,6 @@
 
 static struct branch_clk gcc_blsp2_qup3_i2c_apps_clk = {
 	.cbcr_reg = BLSP2_QUP3_I2C_APPS_CBCR,
-	.has_sibling = 1,
 	.base = &virt_bases[GCC_BASE],
 	.c = {
 		.parent = &cxo_clk_src.c,
@@ -1815,7 +1987,6 @@
 
 static struct branch_clk gcc_blsp2_qup4_i2c_apps_clk = {
 	.cbcr_reg = BLSP2_QUP4_I2C_APPS_CBCR,
-	.has_sibling = 1,
 	.base = &virt_bases[GCC_BASE],
 	.c = {
 		.parent = &cxo_clk_src.c,
@@ -1838,7 +2009,6 @@
 
 static struct branch_clk gcc_blsp2_qup5_i2c_apps_clk = {
 	.cbcr_reg = BLSP2_QUP5_I2C_APPS_CBCR,
-	.has_sibling = 1,
 	.base = &virt_bases[GCC_BASE],
 	.c = {
 		.parent = &cxo_clk_src.c,
@@ -1861,7 +2031,6 @@
 
 static struct branch_clk gcc_blsp2_qup6_i2c_apps_clk = {
 	.cbcr_reg = BLSP2_QUP6_I2C_APPS_CBCR,
-	.has_sibling = 1,
 	.base = &virt_bases[GCC_BASE],
 	.c = {
 		.parent = &cxo_clk_src.c,
@@ -2392,6 +2561,19 @@
 	F_END
 };
 
+static struct clk_freq_tbl ftbl_mmss_axi_v2_clk[] = {
+	F_MM( 19200000,    cxo,     1,   0,   0),
+	F_MM( 37500000,  gpll0,    16,   0,   0),
+	F_MM( 50000000,  gpll0,    12,   0,   0),
+	F_MM( 75000000,  gpll0,     8,   0,   0),
+	F_MM(100000000,  gpll0,     6,   0,   0),
+	F_MM(150000000,  gpll0,     4,   0,   0),
+	F_MM(333430000, mmpll1,   3.5,   0,   0),
+	F_MM(400000000, mmpll0,     2,   0,   0),
+	F_MM(466800000, mmpll1,   2.5,   0,   0),
+	F_END
+};
+
 static struct rcg_clk axi_clk_src = {
 	.cmd_rcgr_reg = 0x5040,
 	.set_rate = set_rate_hid,
@@ -2419,6 +2601,18 @@
 	F_END
 };
 
+static struct clk_freq_tbl ftbl_ocmemnoc_v2_clk[] = {
+	F_MM( 19200000,    cxo,   1,   0,   0),
+	F_MM( 37500000,  gpll0,  16,   0,   0),
+	F_MM( 50000000,  gpll0,  12,   0,   0),
+	F_MM( 75000000,  gpll0,   8,   0,   0),
+	F_MM(100000000,  gpll0,   6,   0,   0),
+	F_MM(150000000,  gpll0,   4,   0,   0),
+	F_MM(333430000, mmpll1, 3.5,   0,   0),
+	F_MM(400000000, mmpll0,   2,   0,   0),
+	F_END
+};
+
 struct rcg_clk ocmemnoc_clk_src = {
 	.cmd_rcgr_reg = OCMEMNOC_CMD_RCGR,
 	.set_rate = set_rate_hid,
@@ -2550,6 +2744,7 @@
 	F_MM(133330000, mmpll0,   6,   0,   0),
 	F_MM(160000000, mmpll0,   5,   0,   0),
 	F_MM(200000000, mmpll0,   4,   0,   0),
+	F_MM(240000000,  gpll0, 2.5,   0,   0),
 	F_MM(266670000, mmpll0,   3,   0,   0),
 	F_MM(320000000, mmpll0, 2.5,   0,   0),
 	F_END
@@ -2814,7 +3009,9 @@
 	},
 };
 
+static struct branch_clk mdss_ahb_clk;
 static struct clk dsipll0_byte_clk_src = {
+	.depends = &mdss_ahb_clk.c,
 	.parent = &cxo_clk_src.c,
 	.dbg_name = "dsipll0_byte_clk_src",
 	.ops = &clk_ops_dsi_byte_pll,
@@ -2822,6 +3019,7 @@
 };
 
 static struct clk dsipll0_pixel_clk_src = {
+	.depends = &mdss_ahb_clk.c,
 	.parent = &cxo_clk_src.c,
 	.dbg_name = "dsipll0_pixel_clk_src",
 	.ops = &clk_ops_dsi_pixel_pll,
@@ -2840,11 +3038,40 @@
 static struct clk_ops clk_ops_pixel;
 
 #define CFG_RCGR_DIV_MASK		BM(4, 0)
+#define CMD_RCGR_REG(x)			(*(x)->base + (x)->cmd_rcgr_reg + 0x0)
+#define CFG_RCGR_REG(x)			(*(x)->base + (x)->cmd_rcgr_reg + 0x4)
+#define M_REG(x)			(*(x)->base + (x)->cmd_rcgr_reg + 0x8)
+#define N_REG(x)			(*(x)->base + (x)->cmd_rcgr_reg + 0xC)
+#define MND_MODE_MASK			BM(13, 12)
+#define MND_DUAL_EDGE_MODE_BVAL		BVAL(13, 12, 0x2)
+#define CFG_RCGR_SRC_SEL_MASK		BM(10, 8)
+#define CMD_RCGR_ROOT_STATUS_BIT	BIT(31)
+
+static enum handoff byte_rcg_handoff(struct clk *clk)
+{
+	struct rcg_clk *rcg = to_rcg_clk(clk);
+	u32 div_val;
+	unsigned long pre_div_rate, parent_rate = clk_get_rate(clk->parent);
+
+	/* If the pre-divider is used, find the rate after the division */
+	div_val = readl_relaxed(CFG_RCGR_REG(rcg)) & CFG_RCGR_DIV_MASK;
+	if (div_val > 1)
+		pre_div_rate = parent_rate / ((div_val + 1) >> 1);
+	else
+		pre_div_rate = parent_rate;
+
+	clk->rate = pre_div_rate;
+
+	if (readl_relaxed(CMD_RCGR_REG(rcg)) & CMD_RCGR_ROOT_STATUS_BIT)
+		return HANDOFF_DISABLED_CLK;
+
+	return HANDOFF_ENABLED_CLK;
+}
 
 static int set_rate_byte(struct clk *clk, unsigned long rate)
 {
 	struct rcg_clk *rcg = to_rcg_clk(clk);
-	struct clk *pll = &dsipll0_byte_clk_src;
+	struct clk *pll = clk->parent;
 	unsigned long source_rate, div;
 	int rc;
 
@@ -2865,15 +3092,48 @@
 
 	byte_freq.div_src_val &= ~CFG_RCGR_DIV_MASK;
 	byte_freq.div_src_val |= BVAL(4, 0, div);
-	set_rate_mnd(rcg, &byte_freq);
+	set_rate_hid(rcg, &byte_freq);
 
 	return 0;
 }
 
+static enum handoff pixel_rcg_handoff(struct clk *clk)
+{
+	struct rcg_clk *rcg = to_rcg_clk(clk);
+	u32 div_val, mval, nval, cfg_regval;
+	unsigned long pre_div_rate, parent_rate = clk_get_rate(clk->parent);
+
+	cfg_regval = readl_relaxed(CFG_RCGR_REG(rcg));
+
+	/* If the pre-divider is used, find the rate after the division */
+	div_val = cfg_regval & CFG_RCGR_DIV_MASK;
+	if (div_val > 1)
+		pre_div_rate = parent_rate / ((div_val + 1) >> 1);
+	else
+		pre_div_rate = parent_rate;
+
+	clk->rate = pre_div_rate;
+
+	/* If MND is used, find the rate after the MND division */
+	if ((cfg_regval & MND_MODE_MASK) == MND_DUAL_EDGE_MODE_BVAL) {
+		mval = readl_relaxed(M_REG(rcg));
+		nval = readl_relaxed(N_REG(rcg));
+		if (!nval)
+			return HANDOFF_DISABLED_CLK;
+		nval = (~nval) + mval;
+		clk->rate = (pre_div_rate * mval) / nval;
+	}
+
+	if (readl_relaxed(CMD_RCGR_REG(rcg)) & CMD_RCGR_ROOT_STATUS_BIT)
+		return HANDOFF_DISABLED_CLK;
+
+	return HANDOFF_ENABLED_CLK;
+}
+
 static int set_rate_pixel(struct clk *clk, unsigned long rate)
 {
 	struct rcg_clk *rcg = to_rcg_clk(clk);
-	struct clk *pll = &dsipll0_pixel_clk_src;
+	struct clk *pll = clk->parent;
 	unsigned long source_rate, div;
 	int rc;
 
@@ -2894,7 +3154,7 @@
 
 	pixel_freq.div_src_val &= ~CFG_RCGR_DIV_MASK;
 	pixel_freq.div_src_val |= BVAL(4, 0, div);
-	set_rate_hid(rcg, &pixel_freq);
+	set_rate_mnd(rcg, &pixel_freq);
 
 	return 0;
 }
@@ -3181,6 +3441,16 @@
 	F_END
 };
 
+static struct clk_freq_tbl ftbl_venus0_vcodec0_v2_clk[] = {
+	F_MM( 50000000,  gpll0,  12,   0,   0),
+	F_MM(100000000,  gpll0,   6,   0,   0),
+	F_MM(133330000, mmpll0,   6,   0,   0),
+	F_MM(200000000, mmpll0,   4,   0,   0),
+	F_MM(266670000, mmpll0,   3,   0,   0),
+	F_MM(465000000, mmpll3,   2,   0,   0),
+	F_END
+};
+
 static struct rcg_clk vcodec0_clk_src = {
 	.cmd_rcgr_reg = VCODEC0_CMD_RCGR,
 	.set_rate = set_rate_mnd,
@@ -4130,411 +4400,6 @@
 	},
 };
 
-static struct clk_freq_tbl ftbl_audio_core_slimbus_core_clock[] = {
-	F_LPASS(24576000, lpapll0, 4, 1, 5),
-	F_END
-};
-
-static struct rcg_clk audio_core_slimbus_core_clk_src = {
-	.cmd_rcgr_reg = SLIMBUS_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_audio_core_slimbus_core_clock,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_slimbus_core_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 70000000, NOMINAL, 140000000),
-		CLK_INIT(audio_core_slimbus_core_clk_src.c),
-	},
-};
-
-static struct branch_clk audio_core_slimbus_core_clk = {
-	.cbcr_reg = AUDIO_CORE_SLIMBUS_CORE_CBCR,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &audio_core_slimbus_core_clk_src.c,
-		.dbg_name = "audio_core_slimbus_core_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_slimbus_core_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_slimbus_lfabif_clk = {
-	.cbcr_reg = AUDIO_CORE_SLIMBUS_LFABIF_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_slimbus_lfabif_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_slimbus_lfabif_clk.c),
-	},
-};
-
-static struct clk_freq_tbl ftbl_audio_core_lpaif_clock[] = {
-	F_LPASS(  512000, lpapll0, 16, 1, 60),
-	F_LPASS(  768000, lpapll0, 16, 1, 40),
-	F_LPASS( 1024000, lpapll0, 16, 1, 30),
-	F_LPASS( 1536000, lpapll0, 16, 1, 20),
-	F_LPASS( 2048000, lpapll0, 16, 1, 15),
-	F_LPASS( 3072000, lpapll0, 16, 1, 10),
-	F_LPASS( 4096000, lpapll0, 15, 1,  8),
-	F_LPASS( 6144000, lpapll0, 10, 1,  8),
-	F_LPASS( 8192000, lpapll0, 15, 1,  4),
-	F_LPASS(12288000, lpapll0, 10, 1,  4),
-	F_END
-};
-
-static struct rcg_clk audio_core_lpaif_codec_spkr_clk_src = {
-	.cmd_rcgr_reg = LPAIF_SPKR_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_audio_core_lpaif_clock,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_codec_spkr_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 12000000, NOMINAL, 25000000),
-		CLK_INIT(audio_core_lpaif_codec_spkr_clk_src.c),
-	},
-};
-
-static struct rcg_clk audio_core_lpaif_pri_clk_src = {
-	.cmd_rcgr_reg = LPAIF_PRI_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_audio_core_lpaif_clock,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_pri_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 12000000, NOMINAL, 25000000),
-		CLK_INIT(audio_core_lpaif_pri_clk_src.c),
-	},
-};
-
-static struct rcg_clk audio_core_lpaif_sec_clk_src = {
-	.cmd_rcgr_reg = LPAIF_SEC_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_audio_core_lpaif_clock,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_sec_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 12000000, NOMINAL, 25000000),
-		CLK_INIT(audio_core_lpaif_sec_clk_src.c),
-	},
-};
-
-static struct rcg_clk audio_core_lpaif_ter_clk_src = {
-	.cmd_rcgr_reg = LPAIF_TER_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_audio_core_lpaif_clock,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_ter_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 12000000, NOMINAL, 25000000),
-		CLK_INIT(audio_core_lpaif_ter_clk_src.c),
-	},
-};
-
-static struct rcg_clk audio_core_lpaif_quad_clk_src = {
-	.cmd_rcgr_reg = LPAIF_QUAD_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_audio_core_lpaif_clock,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_quad_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 12000000, NOMINAL, 25000000),
-		CLK_INIT(audio_core_lpaif_quad_clk_src.c),
-	},
-};
-
-static struct rcg_clk audio_core_lpaif_pcm0_clk_src = {
-	.cmd_rcgr_reg = LPAIF_PCM0_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_audio_core_lpaif_clock,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_pcm0_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 12000000, NOMINAL, 25000000),
-		CLK_INIT(audio_core_lpaif_pcm0_clk_src.c),
-	},
-};
-
-static struct rcg_clk audio_core_lpaif_pcm1_clk_src = {
-	.cmd_rcgr_reg = LPAIF_PCM1_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_audio_core_lpaif_clock,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_pcm1_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 12000000, NOMINAL, 25000000),
-		CLK_INIT(audio_core_lpaif_pcm1_clk_src.c),
-	},
-};
-
-struct rcg_clk audio_core_lpaif_pcmoe_clk_src = {
-	.cmd_rcgr_reg = LPAIF_PCMOE_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_audio_core_lpaif_clock,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_pcmoe_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP1(LOW, 12290000),
-		CLK_INIT(audio_core_lpaif_pcmoe_clk_src.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_codec_spkr_osr_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_CODEC_SPKR_OSR_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &audio_core_lpaif_codec_spkr_clk_src.c,
-		.dbg_name = "audio_core_lpaif_codec_spkr_osr_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_codec_spkr_osr_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_codec_spkr_ebit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_CODEC_SPKR_EBIT_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_codec_spkr_ebit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_codec_spkr_ebit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_codec_spkr_ibit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_CODEC_SPKR_IBIT_CBCR,
-	.has_sibling = 1,
-	.max_div = 15,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &audio_core_lpaif_codec_spkr_clk_src.c,
-		.dbg_name = "audio_core_lpaif_codec_spkr_ibit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_codec_spkr_ibit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_pri_osr_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_PRI_OSR_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &audio_core_lpaif_pri_clk_src.c,
-		.dbg_name = "audio_core_lpaif_pri_osr_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_pri_osr_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_pri_ebit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_PRI_EBIT_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_pri_ebit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_pri_ebit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_pri_ibit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_PRI_IBIT_CBCR,
-	.has_sibling = 1,
-	.max_div = 15,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &audio_core_lpaif_pri_clk_src.c,
-		.dbg_name = "audio_core_lpaif_pri_ibit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_pri_ibit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_sec_osr_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_SEC_OSR_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &audio_core_lpaif_sec_clk_src.c,
-		.dbg_name = "audio_core_lpaif_sec_osr_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_sec_osr_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_sec_ebit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_SEC_EBIT_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_sec_ebit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_sec_ebit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_sec_ibit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_SEC_IBIT_CBCR,
-	.has_sibling = 1,
-	.max_div = 15,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &audio_core_lpaif_sec_clk_src.c,
-		.dbg_name = "audio_core_lpaif_sec_ibit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_sec_ibit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_ter_osr_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_TER_OSR_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &audio_core_lpaif_ter_clk_src.c,
-		.dbg_name = "audio_core_lpaif_ter_osr_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_ter_osr_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_ter_ebit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_TER_EBIT_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_ter_ebit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_ter_ebit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_ter_ibit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_TER_IBIT_CBCR,
-	.has_sibling = 1,
-	.max_div = 15,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &audio_core_lpaif_ter_clk_src.c,
-		.dbg_name = "audio_core_lpaif_ter_ibit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_ter_ibit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_quad_osr_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_QUAD_OSR_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &audio_core_lpaif_quad_clk_src.c,
-		.dbg_name = "audio_core_lpaif_quad_osr_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_quad_osr_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_quad_ebit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_QUAD_EBIT_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_quad_ebit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_quad_ebit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_quad_ibit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_QUAD_IBIT_CBCR,
-	.has_sibling = 1,
-	.max_div = 15,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &audio_core_lpaif_quad_clk_src.c,
-		.dbg_name = "audio_core_lpaif_quad_ibit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_quad_ibit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_pcm0_ebit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_PCM0_EBIT_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_pcm0_ebit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_pcm0_ebit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_pcm0_ibit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_PCM0_IBIT_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &audio_core_lpaif_pcm0_clk_src.c,
-		.dbg_name = "audio_core_lpaif_pcm0_ibit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_pcm0_ibit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_pcm1_ebit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_PCM1_EBIT_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &audio_core_lpaif_pcm1_clk_src.c,
-		.dbg_name = "audio_core_lpaif_pcm1_ebit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_pcm1_ebit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_pcm1_ibit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_PCM1_IBIT_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &audio_core_lpaif_pcm1_clk_src.c,
-		.dbg_name = "audio_core_lpaif_pcm1_ibit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_pcm1_ibit_clk.c),
-	},
-};
-
-struct branch_clk audio_core_lpaif_pcmoe_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_PCM_DATA_OE_CBCR,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &audio_core_lpaif_pcmoe_clk_src.c,
-		.dbg_name = "audio_core_lpaif_pcmoe_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_pcmoe_clk.c),
-	},
-};
-
 static struct branch_clk q6ss_ahb_lfabif_clk = {
 	.cbcr_reg = LPASS_Q6SS_AHB_LFABIF_CBCR,
 	.has_sibling = 1,
@@ -4546,16 +4411,6 @@
 	},
 };
 
-static struct branch_clk audio_core_ixfabric_clk = {
-	.cbcr_reg = AUDIO_CORE_IXFABRIC_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_ixfabric_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_ixfabric_clk.c),
-	},
-};
 
 static struct branch_clk gcc_lpass_q6_axi_clk = {
 	.cbcr_reg = LPASS_Q6_AXI_CBCR,
@@ -4591,17 +4446,6 @@
 	},
 };
 
-static struct branch_clk audio_wrapper_br_clk = {
-	.cbcr_reg = AUDIO_WRAPPER_BR_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_wrapper_br_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_wrapper_br_clk.c),
-	},
-};
-
 static DEFINE_CLK_MEASURE(l2_m_clk);
 static DEFINE_CLK_MEASURE(krait0_m_clk);
 static DEFINE_CLK_MEASURE(krait1_m_clk);
@@ -4616,6 +4460,14 @@
 	u32 debug_mux;
 };
 
+enum {
+	M_ACPU0 = 0,
+	M_ACPU1,
+	M_ACPU2,
+	M_ACPU3,
+	M_L2,
+};
+
 struct measure_mux_entry measure_mux[] = {
 	{&gcc_pdm_ahb_clk.c,			GCC_BASE, 0x00d0},
 	{&gcc_blsp2_qup1_i2c_apps_clk.c,	GCC_BASE, 0x00ab},
@@ -4776,26 +4628,15 @@
 	{&mdss_hdmi_ahb_clk.c,			MMSS_BASE, 0x0023},
 	{&mdss_pclk0_clk.c,			MMSS_BASE, 0x0016},
 	{&mdss_pclk1_clk.c,			MMSS_BASE, 0x0017},
-	{&audio_core_lpaif_pri_clk_src.c,	LPASS_BASE, 0x0017},
-	{&audio_core_lpaif_sec_clk_src.c,	LPASS_BASE, 0x0016},
-	{&audio_core_lpaif_ter_clk_src.c,	LPASS_BASE, 0x0015},
-	{&audio_core_lpaif_quad_clk_src.c,	LPASS_BASE, 0x0014},
-	{&audio_core_lpaif_pcm0_clk_src.c,	LPASS_BASE, 0x0013},
-	{&audio_core_lpaif_pcm1_clk_src.c,	LPASS_BASE, 0x0012},
-	{&audio_core_lpaif_pcmoe_clk_src.c,	LPASS_BASE, 0x000f},
-	{&audio_core_slimbus_core_clk.c,	LPASS_BASE, 0x003d},
-	{&audio_core_slimbus_lfabif_clk.c,	LPASS_BASE, 0x003e},
 	{&q6ss_xo_clk.c,			LPASS_BASE, 0x002b},
 	{&q6ss_ahb_lfabif_clk.c,		LPASS_BASE, 0x001e},
 	{&q6ss_ahbm_clk.c,			LPASS_BASE, 0x001d},
-	{&audio_core_ixfabric_clk.c,		LPASS_BASE, 0x0059},
-	{&audio_wrapper_br_clk.c,		LPASS_BASE, 0x0022},
 
-	{&l2_m_clk,				APCS_BASE, 0x0081},
-	{&krait0_m_clk,				APCS_BASE, 0x0080},
-	{&krait1_m_clk,				APCS_BASE, 0x0088},
-	{&krait2_m_clk,				APCS_BASE, 0x0090},
-	{&krait3_m_clk,				APCS_BASE, 0x0098},
+	{&krait0_m_clk,				APCS_BASE, M_ACPU0},
+	{&krait1_m_clk,				APCS_BASE, M_ACPU1},
+	{&krait2_m_clk,				APCS_BASE, M_ACPU2},
+	{&krait3_m_clk,				APCS_BASE, M_ACPU3},
+	{&l2_m_clk,				APCS_BASE, M_L2},
 
 	{&dummy_clk,				N_BASES,   0x0000},
 };
@@ -4856,7 +4697,19 @@
 	case APCS_BASE:
 		clk->multiplier = 4;
 		clk_sel = 0x16A;
-		regval = measure_mux[i].debug_mux;
+
+		if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 1) {
+			if (measure_mux[i].debug_mux == M_L2)
+				regval = BIT(7)|BIT(0);
+			else
+				regval = BIT(7)|(measure_mux[i].debug_mux << 3);
+		} else {
+			if (measure_mux[i].debug_mux == M_L2)
+				regval = BIT(12);
+			else
+				regval = measure_mux[i].debug_mux << 8;
+			writel_relaxed(BIT(0), APCS_REG_BASE(L2_CBCR_REG));
+		}
 		writel_relaxed(regval, APCS_REG_BASE(GLB_CLK_DIAG_REG));
 		break;
 
@@ -5018,14 +4871,31 @@
 	CLK_DUMMY("vsync_clk", "mdp.0", NULL, 0),
 	CLK_DUMMY("iface_clk", "mdp.0", NULL, 0),
 	CLK_DUMMY("bus_clk", "mdp.0", NULL, 0),
+	CLK_DUMMY("iface_clk", NULL, "fda64000.qcom,iommu", OFF),
+	CLK_DUMMY("core_clk", NULL, "fda64000.qcom,iommu", OFF),
+	CLK_DUMMY("alt_core_clk", NULL, "fda64000.qcom,iommu", OFF),
+	CLK_DUMMY("iface_clk", NULL, "fda44000.qcom,iommu", OFF),
+	CLK_DUMMY("core_clk", NULL, "fda44000.qcom,iommu", OFF),
+	CLK_DUMMY("alt_core_clk", NULL, "fda44000.qcom,iommu", OFF),
+	CLK_DUMMY("iface_clk", NULL, "fd928000.qcom,iommu", OFF),
+	CLK_DUMMY("core_clk", NULL, "fd928000.qcom,iommu", oFF),
+	CLK_DUMMY("core_clk", NULL, "fdb10000.qcom,iommu", OFF),
+	CLK_DUMMY("iface_clk", NULL, "fdb10000.qcom,iommu", OFF),
+	CLK_DUMMY("alt_core_clk", NULL, "fdb10000.qcom,iommu", OFF),
+	CLK_DUMMY("iface_clk", NULL, "fdc84000.qcom,iommu", OFF),
+	CLK_DUMMY("alt_core_clk", NULL, "fdc84000.qcom,iommu", oFF),
+	CLK_DUMMY("core_clk", NULL, "fdc84000.qcom,iommu", oFF),
 };
 
 static struct clk_lookup msm_clocks_8974[] = {
-	CLK_LOOKUP("xo",	cxo_clk_src.c,	"msm_otg"),
-	CLK_LOOKUP("xo",	cxo_clk_src.c,	"fe200000.qcom,lpass"),
-	CLK_LOOKUP("xo",	cxo_clk_src.c,	"fc880000.qcom,mss"),
-	CLK_LOOKUP("xo",	cxo_clk_src.c,	"fb000000.qcom,wcnss-wlan"),
-	CLK_LOOKUP("xo",	cxo_clk_src.c,	"fb21b000.qcom,pronto"),
+	CLK_LOOKUP("xo",        cxo_otg_clk.c,                  "msm_otg"),
+	CLK_LOOKUP("xo",  cxo_pil_lpass_clk.c,      "fe200000.qcom,lpass"),
+	CLK_LOOKUP("xo",    cxo_pil_mss_clk.c,        "fc880000.qcom,mss"),
+	CLK_LOOKUP("xo",       cxo_wlan_clk.c, "fb000000.qcom,wcnss-wlan"),
+	CLK_LOOKUP("xo", cxo_pil_pronto_clk.c,     "fb21b000.qcom,pronto"),
+	CLK_LOOKUP("xo",       cxo_dwc3_clk.c,                 "msm_dwc3"),
+	CLK_LOOKUP("xo",  cxo_ehci_host_clk.c,            "msm_ehci_host"),
+
 	CLK_LOOKUP("measure",	measure_clk.c,	"debug"),
 
 	CLK_LOOKUP("dma_bam_pclk", gcc_bam_dma_ahb_clk.c, "msm_sps"),
@@ -5055,6 +4925,7 @@
 	CLK_LOOKUP("iface_clk", gcc_blsp2_ahb_clk.c, "f9967000.i2c"),
 	CLK_LOOKUP("iface_clk", gcc_blsp2_ahb_clk.c, "f9966000.spi"),
 	CLK_LOOKUP("iface_clk", gcc_blsp2_ahb_clk.c, "f995e000.serial"),
+	CLK_LOOKUP("iface_clk", gcc_blsp2_ahb_clk.c, "f995d000.uart"),
 	CLK_LOOKUP("core_clk", gcc_blsp2_qup1_i2c_apps_clk.c, ""),
 	CLK_LOOKUP("core_clk", gcc_blsp2_qup1_spi_apps_clk.c, ""),
 	CLK_LOOKUP("core_clk", gcc_blsp2_qup2_i2c_apps_clk.c, ""),
@@ -5067,7 +4938,7 @@
 	CLK_LOOKUP("core_clk", gcc_blsp2_qup5_spi_apps_clk.c, ""),
 	CLK_LOOKUP("core_clk", gcc_blsp2_qup6_i2c_apps_clk.c, ""),
 	CLK_LOOKUP("core_clk", gcc_blsp2_qup6_spi_apps_clk.c, ""),
-	CLK_LOOKUP("core_clk", gcc_blsp2_uart1_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp2_uart1_apps_clk.c, "f995d000.uart"),
 	CLK_LOOKUP("core_clk", gcc_blsp2_uart2_apps_clk.c, "f995e000.serial"),
 	CLK_LOOKUP("core_clk", gcc_blsp2_uart3_apps_clk.c, ""),
 	CLK_LOOKUP("core_clk", gcc_blsp2_uart4_apps_clk.c, ""),
@@ -5114,8 +4985,8 @@
 	CLK_LOOKUP("iface_clk", gcc_sdcc4_ahb_clk.c, "msm_sdcc.4"),
 	CLK_LOOKUP("core_clk", gcc_sdcc4_apps_clk.c, "msm_sdcc.4"),
 
-	CLK_LOOKUP("iface_clk", gcc_tsif_ahb_clk.c, ""),
-	CLK_LOOKUP("ref_clk", gcc_tsif_ref_clk.c, ""),
+	CLK_LOOKUP("iface_clk", gcc_tsif_ahb_clk.c, "f99d8000.msm_tspp"),
+	CLK_LOOKUP("ref_clk", gcc_tsif_ref_clk.c, "f99d8000.msm_tspp"),
 
 	CLK_LOOKUP("mem_clk", gcc_usb30_master_clk.c,           "usb_bam"),
 	CLK_LOOKUP("mem_iface_clk", gcc_sys_noc_usb3_axi_clk.c, "usb_bam"),
@@ -5134,10 +5005,15 @@
 	CLK_LOOKUP("cal_clk", gcc_usb_hsic_io_cal_clk.c,  "msm_hsic_host"),
 	CLK_LOOKUP("core_clk", gcc_usb_hsic_system_clk.c, "msm_hsic_host"),
 	CLK_LOOKUP("ref_clk", div_clk2.c, "msm_smsc_hub"),
+	CLK_LOOKUP("iface_clk", gcc_usb_hs_ahb_clk.c,     "msm_ehci_host"),
+	CLK_LOOKUP("core_clk", gcc_usb_hs_system_clk.c,   "msm_ehci_host"),
+	CLK_LOOKUP("sleep_clk", gcc_usb2b_phy_sleep_clk.c, "msm_ehci_host"),
+	CLK_LOOKUP("pwm_clk", div_clk2.c, "0-0048"),
 
 	/* Multimedia clocks */
 	CLK_LOOKUP("bus_clk_src", axi_clk_src.c, ""),
 	CLK_LOOKUP("bus_clk", mmss_mmssnoc_axi_clk.c, ""),
+	CLK_LOOKUP("bus_clk", mmssnoc_ahb_clk.c, ""),
 	CLK_LOOKUP("core_clk", mdss_edpaux_clk.c, "fd923400.qcom,mdss_edp"),
 	CLK_LOOKUP("pixel_clk", mdss_edppixel_clk.c, "fd923400.qcom,mdss_edp"),
 	CLK_LOOKUP("link_clk", mdss_edplink_clk.c, "fd923400.qcom,mdss_edp"),
@@ -5159,9 +5035,11 @@
 
 	/* MM sensor clocks */
 	CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6e.qcom,camera"),
+	CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "20.qcom,camera"),
 	CLK_LOOKUP("cam_src_clk", mclk2_clk_src.c, "6c.qcom,camera"),
 	CLK_LOOKUP("cam_src_clk", mclk1_clk_src.c, "90.qcom,camera"),
 	CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "6e.qcom,camera"),
+	CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "20.qcom,camera"),
 	CLK_LOOKUP("cam_clk", camss_mclk2_clk.c, "6c.qcom,camera"),
 	CLK_LOOKUP("cam_clk", camss_mclk1_clk.c, "90.qcom,camera"),
 	CLK_LOOKUP("cam_clk", camss_mclk1_clk.c, ""),
@@ -5178,18 +5056,24 @@
 	CLK_LOOKUP("cci_src_clk", cci_clk_src.c, "fda0c000.qcom,cci"),
 	CLK_LOOKUP("cci_clk", camss_cci_cci_clk.c, "fda0c000.qcom,cci"),
 	/* CSIPHY clocks */
+	CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+		"fda0ac00.qcom,csiphy"),
 	CLK_LOOKUP("ispif_ahb_clk", camss_ispif_ahb_clk.c,
 		"fda0ac00.qcom,csiphy"),
 	CLK_LOOKUP("csiphy_timer_src_clk", csi0phytimer_clk_src.c,
 		"fda0ac00.qcom,csiphy"),
 	CLK_LOOKUP("csiphy_timer_clk", camss_phy0_csi0phytimer_clk.c,
 		"fda0ac00.qcom,csiphy"),
+	CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+		"fda0b000.qcom,csiphy"),
 	CLK_LOOKUP("ispif_ahb_clk", camss_ispif_ahb_clk.c,
 		"fda0b000.qcom,csiphy"),
 	CLK_LOOKUP("csiphy_timer_src_clk", csi1phytimer_clk_src.c,
 		"fda0b000.qcom,csiphy"),
 	CLK_LOOKUP("csiphy_timer_clk", camss_phy1_csi1phytimer_clk.c,
 		"fda0b000.qcom,csiphy"),
+	CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+		"fda0b400.qcom,csiphy"),
 	CLK_LOOKUP("ispif_ahb_clk", camss_ispif_ahb_clk.c,
 		"fda0b400.qcom,csiphy"),
 	CLK_LOOKUP("csiphy_timer_src_clk", csi2phytimer_clk_src.c,
@@ -5197,6 +5081,10 @@
 	CLK_LOOKUP("csiphy_timer_clk", camss_phy2_csi2phytimer_clk.c,
 		"fda0b400.qcom,csiphy"),
 	/* CSID clocks */
+	CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+		"fda08000.qcom,csid"),
+	CLK_LOOKUP("ispif_ahb_clk", camss_ispif_ahb_clk.c,
+		"fda08000.qcom,csid"),
 	CLK_LOOKUP("csi0_ahb_clk", camss_csi0_ahb_clk.c, "fda08000.qcom,csid"),
 	CLK_LOOKUP("csi0_src_clk", csi0_clk_src.c, "fda08000.qcom,csid"),
 	CLK_LOOKUP("csi0_phy_clk", camss_csi0phy_clk.c, "fda08000.qcom,csid"),
@@ -5204,6 +5092,10 @@
 	CLK_LOOKUP("csi0_pix_clk", camss_csi0pix_clk.c, "fda08000.qcom,csid"),
 	CLK_LOOKUP("csi0_rdi_clk", camss_csi0rdi_clk.c, "fda08000.qcom,csid"),
 
+	CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+		"fda08400.qcom,csid"),
+	CLK_LOOKUP("ispif_ahb_clk", camss_ispif_ahb_clk.c,
+		"fda08400.qcom,csid"),
 	CLK_LOOKUP("csi0_ahb_clk", camss_csi0_ahb_clk.c, "fda08400.qcom,csid"),
 	CLK_LOOKUP("csi1_ahb_clk", camss_csi1_ahb_clk.c, "fda08400.qcom,csid"),
 	CLK_LOOKUP("csi0_src_clk", csi0_clk_src.c, "fda08400.qcom,csid"),
@@ -5217,6 +5109,10 @@
 	CLK_LOOKUP("csi0_rdi_clk", camss_csi0rdi_clk.c, "fda08400.qcom,csid"),
 	CLK_LOOKUP("csi1_rdi_clk", camss_csi1rdi_clk.c, "fda08400.qcom,csid"),
 
+	CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+		"fda08800.qcom,csid"),
+	CLK_LOOKUP("ispif_ahb_clk", camss_ispif_ahb_clk.c,
+		"fda08800.qcom,csid"),
 	CLK_LOOKUP("csi0_ahb_clk", camss_csi0_ahb_clk.c, "fda08800.qcom,csid"),
 	CLK_LOOKUP("csi2_ahb_clk", camss_csi2_ahb_clk.c, "fda08800.qcom,csid"),
 	CLK_LOOKUP("csi0_src_clk", csi0_clk_src.c, "fda08800.qcom,csid"),
@@ -5230,6 +5126,10 @@
 	CLK_LOOKUP("csi0_rdi_clk", camss_csi0rdi_clk.c, "fda08800.qcom,csid"),
 	CLK_LOOKUP("csi2_rdi_clk", camss_csi2rdi_clk.c, "fda08800.qcom,csid"),
 
+	CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+		"fda08c00.qcom,csid"),
+	CLK_LOOKUP("ispif_ahb_clk", camss_ispif_ahb_clk.c,
+		"fda08c00.qcom,csid"),
 	CLK_LOOKUP("csi0_ahb_clk", camss_csi0_ahb_clk.c, "fda08c00.qcom,csid"),
 	CLK_LOOKUP("csi3_ahb_clk", camss_csi3_ahb_clk.c, "fda08c00.qcom,csid"),
 	CLK_LOOKUP("csi0_src_clk", csi0_clk_src.c, "fda08c00.qcom,csid"),
@@ -5243,6 +5143,16 @@
 	CLK_LOOKUP("csi0_rdi_clk", camss_csi0rdi_clk.c, "fda08c00.qcom,csid"),
 	CLK_LOOKUP("csi3_rdi_clk", camss_csi3rdi_clk.c, "fda08c00.qcom,csid"),
 
+	/* ISPIF clocks */
+	CLK_LOOKUP("camss_vfe_vfe_clk", camss_vfe_vfe0_clk.c,
+		"fda0a000.qcom,ispif"),
+	CLK_LOOKUP("camss_csi_vfe_clk", camss_csi_vfe0_clk.c,
+		"fda0a000.qcom,ispif"),
+	CLK_LOOKUP("camss_vfe_vfe_clk1", camss_vfe_vfe1_clk.c,
+		"fda0a000.qcom,ispif"),
+	CLK_LOOKUP("camss_csi_vfe_clk1", camss_csi_vfe1_clk.c,
+		"fda0a000.qcom,ispif"),
+
 	/*VFE clocks*/
 	CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
 					"fda10000.qcom,vfe"),
@@ -5280,6 +5190,7 @@
 						"fda64000.qcom,iommu"),
 	CLK_LOOKUP("core_clk", camss_jpeg_jpeg_axi_clk.c,
 						"fda64000.qcom,iommu"),
+	CLK_LOOKUP("alt_core_clk", camss_top_ahb_clk.c, "fda64000.qcom,iommu"),
 	CLK_LOOKUP("bus_clk0", camss_jpeg_jpeg_axi_clk.c, "fda1c000.qcom,jpeg"),
 	CLK_LOOKUP("bus_clk0", camss_jpeg_jpeg_axi_clk.c, "fda20000.qcom,jpeg"),
 	CLK_LOOKUP("bus_clk0", camss_jpeg_jpeg_axi_clk.c, "fda24000.qcom,jpeg"),
@@ -5295,9 +5206,24 @@
 						"fda20000.qcom,jpeg"),
 	CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
 						"fda24000.qcom,jpeg"),
+	CLK_LOOKUP("micro_iface_clk", camss_micro_ahb_clk.c,
+		"fda04000.qcom,cpp"),
+	CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+		"fda04000.qcom,cpp"),
+	CLK_LOOKUP("cpp_iface_clk", camss_vfe_cpp_ahb_clk.c,
+		"fda04000.qcom,cpp"),
+	CLK_LOOKUP("cpp_core_clk", camss_vfe_cpp_clk.c, "fda04000.qcom,cpp"),
+	CLK_LOOKUP("cpp_bus_clk", camss_vfe_vfe_axi_clk.c, "fda04000.qcom,cpp"),
+	CLK_LOOKUP("vfe_clk_src", vfe0_clk_src.c,	 "fda04000.qcom,cpp"),
+	CLK_LOOKUP("camss_vfe_vfe_clk", camss_vfe_vfe0_clk.c,
+					"fda04000.qcom,cpp"),
+	CLK_LOOKUP("iface_clk", camss_vfe_vfe_ahb_clk.c, "fda04000.qcom,cpp"),
+
+
 	CLK_LOOKUP("iface_clk", camss_micro_ahb_clk.c, ""),
-	CLK_LOOKUP("iface_clk", camss_vfe_cpp_ahb_clk.c, "fda44000.qcom,iommu"),
-	CLK_LOOKUP("core_clk", camss_vfe_cpp_clk.c, "fda44000.qcom,iommu"),
+	CLK_LOOKUP("iface_clk", camss_vfe_vfe_ahb_clk.c, "fda44000.qcom,iommu"),
+	CLK_LOOKUP("core_clk", camss_vfe_vfe_axi_clk.c, "fda44000.qcom,iommu"),
+	CLK_LOOKUP("alt_core_clk", camss_top_ahb_clk.c, "fda44000.qcom,iommu"),
 	CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "mdp.0"),
 	CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "mdss_dsi_clk_ctrl"),
 	CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "fd923400.qcom,mdss_edp"),
@@ -5329,49 +5255,6 @@
 
 
 	/* LPASS clocks */
-	CLK_LOOKUP("bus_clk", audio_core_ixfabric_clk.c, ""),
-	CLK_LOOKUP("core_clk", audio_core_slimbus_core_clk.c, "fe12f000.slim"),
-	CLK_LOOKUP("iface_clk", audio_core_slimbus_lfabif_clk.c,
-			"fe12f000.slim"),
-	CLK_LOOKUP("core_clk", audio_core_lpaif_codec_spkr_clk_src.c, ""),
-	CLK_LOOKUP("osr_clk", audio_core_lpaif_codec_spkr_osr_clk.c, ""),
-	CLK_LOOKUP("ebit_clk", audio_core_lpaif_codec_spkr_ebit_clk.c, ""),
-	CLK_LOOKUP("ibit_clk", audio_core_lpaif_codec_spkr_ibit_clk.c, ""),
-	CLK_LOOKUP("core_clk", audio_core_lpaif_pri_clk_src.c, ""),
-	CLK_LOOKUP("osr_clk", audio_core_lpaif_pri_osr_clk.c, ""),
-	CLK_LOOKUP("ebit_clk", audio_core_lpaif_pri_ebit_clk.c, ""),
-	CLK_LOOKUP("ibit_clk", audio_core_lpaif_pri_ibit_clk.c, ""),
-	CLK_LOOKUP("core_clk", audio_core_lpaif_sec_clk_src.c, ""),
-	CLK_LOOKUP("osr_clk", audio_core_lpaif_sec_osr_clk.c, ""),
-	CLK_LOOKUP("ebit_clk", audio_core_lpaif_sec_ebit_clk.c, ""),
-	CLK_LOOKUP("ibit_clk", audio_core_lpaif_sec_ibit_clk.c, ""),
-	CLK_LOOKUP("core_clk", audio_core_lpaif_ter_clk_src.c, ""),
-	CLK_LOOKUP("osr_clk", audio_core_lpaif_ter_osr_clk.c, ""),
-	CLK_LOOKUP("ebit_clk", audio_core_lpaif_ter_ebit_clk.c, ""),
-	CLK_LOOKUP("ibit_clk", audio_core_lpaif_ter_ibit_clk.c, ""),
-	CLK_LOOKUP("core_clk", audio_core_lpaif_quad_clk_src.c,
-			"msm-dai-q6-mi2s.3"),
-	CLK_LOOKUP("osr_clk", audio_core_lpaif_quad_osr_clk.c,
-			"msm-dai-q6-mi2s.3"),
-	CLK_LOOKUP("ebit_clk", audio_core_lpaif_quad_ebit_clk.c,
-			"msm-dai-q6-mi2s.3"),
-	CLK_LOOKUP("ibit_clk", audio_core_lpaif_quad_ibit_clk.c,
-			"msm-dai-q6-mi2s.3"),
-	CLK_LOOKUP("pcm_clk", audio_core_lpaif_pcm0_clk_src.c,
-						"msm-dai-q6.4106"),
-	CLK_LOOKUP("ebit_clk", audio_core_lpaif_pcm0_ebit_clk.c, ""),
-	CLK_LOOKUP("ibit_clk", audio_core_lpaif_pcm0_ibit_clk.c,
-						"msm-dai-q6.4106"),
-	CLK_LOOKUP("ibit_clk", audio_core_lpaif_pcm0_ibit_clk.c, ""),
-	CLK_LOOKUP("core_clk", audio_core_lpaif_pcm1_clk_src.c, ""),
-	CLK_LOOKUP("ebit_clk", audio_core_lpaif_pcm1_ebit_clk.c, ""),
-	CLK_LOOKUP("ibit_clk", audio_core_lpaif_pcm1_ibit_clk.c, ""),
-	CLK_LOOKUP("core_oe_src_clk", audio_core_lpaif_pcmoe_clk_src.c,
-						"msm-dai-q6.4106"),
-	CLK_LOOKUP("core_oe_clk", audio_core_lpaif_pcmoe_clk.c,
-						"msm-dai-q6.4106"),
-	CLK_LOOKUP("br_clk", audio_wrapper_br_clk.c, "fdd00000.qcom,ocmem"),
-
 	CLK_LOOKUP("bus_clk", gcc_mss_q6_bimc_axi_clk.c, "fc880000.qcom,mss"),
 	CLK_LOOKUP("iface_clk", gcc_mss_cfg_ahb_clk.c, "fc880000.qcom,mss"),
 	CLK_LOOKUP("mem_clk", gcc_boot_rom_ahb_clk.c,  "fc880000.qcom,mss"),
@@ -5413,35 +5296,64 @@
 	CLK_LOOKUP("iface_clk", gcc_mmss_noc_cfg_ahb_clk.c, ""),
 	CLK_LOOKUP("iface_clk", gcc_ocmem_noc_cfg_ahb_clk.c, ""),
 
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-tmc-etr"),
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-tpiu"),
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-replicator"),
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-tmc-etf"),
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-funnel-merg"),
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-funnel-in0"),
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-funnel-in1"),
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-funnel-kpss"),
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-funnel-mmss"),
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-stm"),
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-etm0"),
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-etm1"),
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-etm2"),
-	CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-etm3"),
+	/* CoreSight clocks */
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc322000.tmc"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc318000.tpiu"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc31c000.replicator"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc307000.tmc"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc31b000.funnel"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc319000.funnel"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc31a000.funnel"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc345000.funnel"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc364000.funnel"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc321000.stm"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc33c000.etm"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc33d000.etm"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc33e000.etm"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc33f000.etm"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc308000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc309000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc30a000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc30b000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc30c000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc30d000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc30e000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc30f000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc310000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc340000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc341000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc342000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc343000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc344000.cti"),
 
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-tmc-etr"),
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-tpiu"),
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-replicator"),
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-tmc-etf"),
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-funnel-merg"),
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-funnel-in0"),
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-funnel-in1"),
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-funnel-kpss"),
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-funnel-mmss"),
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-stm"),
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-etm0"),
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-etm1"),
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-etm2"),
-	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-etm3"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc322000.tmc"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc318000.tpiu"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc31c000.replicator"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc307000.tmc"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc31b000.funnel"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc319000.funnel"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc31a000.funnel"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc345000.funnel"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc364000.funnel"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc321000.stm"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc33c000.etm"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc33d000.etm"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc33e000.etm"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc33f000.etm"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc308000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc309000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc30a000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc30b000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc30c000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc30d000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc30e000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc30f000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc310000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc340000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc341000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc342000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc343000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc344000.cti"),
 
 	CLK_LOOKUP("l2_m_clk",		l2_m_clk,     ""),
 	CLK_LOOKUP("krait0_m_clk",	krait0_m_clk, ""),
@@ -5450,56 +5362,6 @@
 	CLK_LOOKUP("krait3_m_clk",	krait3_m_clk, ""),
 };
 
-static struct pll_config_regs gpll0_regs __initdata = {
-	.l_reg = (void __iomem *)GPLL0_L_REG,
-	.m_reg = (void __iomem *)GPLL0_M_REG,
-	.n_reg = (void __iomem *)GPLL0_N_REG,
-	.config_reg = (void __iomem *)GPLL0_USER_CTL_REG,
-	.mode_reg = (void __iomem *)GPLL0_MODE_REG,
-	.base = &virt_bases[GCC_BASE],
-};
-
-/* GPLL0 at 600 MHz, main output enabled. */
-static struct pll_config gpll0_config __initdata = {
-	.l = 0x1f,
-	.m = 0x1,
-	.n = 0x4,
-	.vco_val = 0x0,
-	.vco_mask = BM(21, 20),
-	.pre_div_val = 0x0,
-	.pre_div_mask = BM(14, 12),
-	.post_div_val = 0x0,
-	.post_div_mask = BM(9, 8),
-	.mn_ena_val = BIT(24),
-	.mn_ena_mask = BIT(24),
-	.main_output_val = BIT(0),
-	.main_output_mask = BIT(0),
-};
-
-static struct pll_config_regs gpll1_regs __initdata = {
-	.l_reg = (void __iomem *)GPLL1_L_REG,
-	.m_reg = (void __iomem *)GPLL1_M_REG,
-	.n_reg = (void __iomem *)GPLL1_N_REG,
-	.config_reg = (void __iomem *)GPLL1_USER_CTL_REG,
-	.mode_reg = (void __iomem *)GPLL1_MODE_REG,
-	.base = &virt_bases[GCC_BASE],
-};
-
-/* GPLL1 at 480 MHz, main output enabled. */
-static struct pll_config gpll1_config __initdata = {
-	.l = 0x19,
-	.m = 0x0,
-	.n = 0x1,
-	.vco_val = 0x0,
-	.vco_mask = BM(21, 20),
-	.pre_div_val = 0x0,
-	.pre_div_mask = BM(14, 12),
-	.post_div_val = 0x0,
-	.post_div_mask = BM(9, 8),
-	.main_output_val = BIT(0),
-	.main_output_mask = BIT(0),
-};
-
 static struct pll_config_regs mmpll0_regs __initdata = {
 	.l_reg = (void __iomem *)MMPLL0_L_REG,
 	.m_reg = (void __iomem *)MMPLL0_M_REG,
@@ -5535,7 +5397,7 @@
 	.base = &virt_bases[MMSS_BASE],
 };
 
-/* MMPLL1 at 1000 MHz, main output enabled. */
+/* MMPLL1 at 846 MHz, main output enabled. */
 static struct pll_config mmpll1_config __initdata = {
 	.l = 0x2C,
 	.m = 0x1,
@@ -5552,6 +5414,23 @@
 	.main_output_mask = BIT(0),
 };
 
+/* MMPLL1 at 1167 MHz, main output enabled. */
+static struct pll_config mmpll1_v2_config __initdata = {
+	.l = 60,
+	.m = 25,
+	.n = 32,
+	.vco_val = 0x0,
+	.vco_mask = BM(21, 20),
+	.pre_div_val = 0x0,
+	.pre_div_mask = BM(14, 12),
+	.post_div_val = 0x0,
+	.post_div_mask = BM(9, 8),
+	.mn_ena_val = BIT(24),
+	.mn_ena_mask = BIT(24),
+	.main_output_val = BIT(0),
+	.main_output_mask = BIT(0),
+};
+
 static struct pll_config_regs mmpll3_regs __initdata = {
 	.l_reg = (void __iomem *)MMPLL3_L_REG,
 	.m_reg = (void __iomem *)MMPLL3_M_REG,
@@ -5578,23 +5457,14 @@
 	.main_output_mask = BIT(0),
 };
 
-static struct pll_config_regs lpapll0_regs __initdata = {
-	.l_reg = (void __iomem *)LPAPLL_L_REG,
-	.m_reg = (void __iomem *)LPAPLL_M_REG,
-	.n_reg = (void __iomem *)LPAPLL_N_REG,
-	.config_reg = (void __iomem *)LPAPLL_USER_CTL_REG,
-	.mode_reg = (void __iomem *)LPAPLL_MODE_REG,
-	.base = &virt_bases[LPASS_BASE],
-};
-
-/* LPAPLL0 at 491.52 MHz, main output enabled. */
-static struct pll_config lpapll0_config __initdata = {
-	.l = 0x33,
-	.m = 0x1,
-	.n = 0x5,
+/* MMPLL3 at 930 MHz, main output enabled. */
+static struct pll_config mmpll3_v2_config __initdata = {
+	.l = 48,
+	.m = 7,
+	.n = 16,
 	.vco_val = 0x0,
 	.vco_mask = BM(21, 20),
-	.pre_div_val = BVAL(14, 12, 0x1),
+	.pre_div_val = 0x0,
 	.pre_div_mask = BM(14, 12),
 	.post_div_val = 0x0,
 	.post_div_mask = BM(9, 8),
@@ -5604,9 +5474,6 @@
 	.main_output_mask = BIT(0),
 };
 
-#define PLL_AUX_OUTPUT_BIT 1
-#define PLL_AUX2_OUTPUT_BIT 2
-
 #define PWR_ON_MASK		BIT(31)
 #define EN_REST_WAIT_MASK	(0xF << 20)
 #define EN_FEW_WAIT_MASK	(0xF << 16)
@@ -5623,26 +5490,17 @@
 
 static void __init reg_init(void)
 {
-	u32 regval, status;
-	int ret;
-
-	if (!(readl_relaxed(GCC_REG_BASE(GPLL0_STATUS_REG))
-			& gpll0_clk_src.status_mask))
-		configure_sr_hpm_lp_pll(&gpll0_config, &gpll0_regs, 1);
-
-	if (!(readl_relaxed(GCC_REG_BASE(GPLL1_STATUS_REG))
-			& gpll1_clk_src.status_mask))
-		configure_sr_hpm_lp_pll(&gpll1_config, &gpll1_regs, 1);
+	u32 regval;
 
 	configure_sr_hpm_lp_pll(&mmpll0_config, &mmpll0_regs, 1);
-	configure_sr_hpm_lp_pll(&mmpll1_config, &mmpll1_regs, 1);
-	configure_sr_hpm_lp_pll(&mmpll3_config, &mmpll3_regs, 0);
-	configure_sr_hpm_lp_pll(&lpapll0_config, &lpapll0_regs, 1);
 
-	/* Enable GPLL0's aux outputs. */
-	regval = readl_relaxed(GCC_REG_BASE(GPLL0_USER_CTL_REG));
-	regval |= BIT(PLL_AUX_OUTPUT_BIT) | BIT(PLL_AUX2_OUTPUT_BIT);
-	writel_relaxed(regval, GCC_REG_BASE(GPLL0_USER_CTL_REG));
+	if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 2) {
+		configure_sr_hpm_lp_pll(&mmpll1_v2_config, &mmpll1_regs, 1);
+		configure_sr_hpm_lp_pll(&mmpll3_v2_config, &mmpll3_regs, 0);
+	} else {
+		configure_sr_hpm_lp_pll(&mmpll1_config, &mmpll1_regs, 1);
+		configure_sr_hpm_lp_pll(&mmpll3_config, &mmpll3_regs, 0);
+	}
 
 	/* Vote for GPLL0 to turn on. Needed by acpuclock. */
 	regval = readl_relaxed(GCC_REG_BASE(APCS_GPLL_ENA_VOTE_REG));
@@ -5650,55 +5508,54 @@
 	writel_relaxed(regval, GCC_REG_BASE(APCS_GPLL_ENA_VOTE_REG));
 
 	/*
+	 * V2 requires additional votes to allow the LPASS and MMSS
+	 * controllers to use GPLL0.
+	 */
+	if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 2) {
+		regval = readl_relaxed(
+				GCC_REG_BASE(APCS_CLOCK_BRANCH_ENA_VOTE));
+		writel_relaxed(regval | BIT(26) | BIT(25),
+				GCC_REG_BASE(APCS_CLOCK_BRANCH_ENA_VOTE));
+	}
+
+	/*
 	 * TODO: Confirm that no clocks need to be voted on in this sleep vote
 	 * register.
 	 */
 	writel_relaxed(0x0, GCC_REG_BASE(APCS_CLOCK_SLEEP_ENA_VOTE));
-
-	/*
-	 * TODO: The following sequence enables the LPASS audio core GDSC.
-	 * Remove when this becomes unnecessary.
-	 */
-
-	/*
-	 * Disable HW trigger: collapse/restore occur based on registers writes.
-	 * Disable SW override: Use hardware state-machine for sequencing.
-	 */
-	regval = readl_relaxed(LPASS_REG_BASE(AUDIO_CORE_GDSCR));
-	regval &= ~(HW_CONTROL_MASK | SW_OVERRIDE_MASK);
-
-	/* Configure wait time between states. */
-	regval &= ~(EN_REST_WAIT_MASK | EN_FEW_WAIT_MASK | CLK_DIS_WAIT_MASK);
-	regval |= EN_REST_WAIT_VAL | EN_FEW_WAIT_VAL | CLK_DIS_WAIT_VAL;
-	writel_relaxed(regval, LPASS_REG_BASE(AUDIO_CORE_GDSCR));
-
-	regval = readl_relaxed(LPASS_REG_BASE(AUDIO_CORE_GDSCR));
-	regval &= ~BIT(0);
-	writel_relaxed(regval, LPASS_REG_BASE(AUDIO_CORE_GDSCR));
-
-	ret = readl_poll_timeout(LPASS_REG_BASE(AUDIO_CORE_GDSCR), status,
-				status & PWR_ON_MASK, 50, GDSC_TIMEOUT_US);
-	WARN(ret, "LPASS Audio Core GDSC did not power on.\n");
 }
 
 static void __init mdss_clock_setup(void)
 {
-	clk_ops_byte = clk_ops_rcg_mnd;
+	clk_ops_byte = clk_ops_rcg;
 	clk_ops_byte.set_rate = set_rate_byte;
+	clk_ops_byte.handoff = byte_rcg_handoff;
+	clk_ops_byte.get_parent = NULL;
 
-	clk_ops_pixel = clk_ops_rcg;
+	clk_ops_pixel = clk_ops_rcg_mnd;
 	clk_ops_pixel.set_rate = set_rate_pixel;
+	clk_ops_pixel.handoff = pixel_rcg_handoff;
+	clk_ops_pixel.get_parent = NULL;
 
 	clk_ops_rcg_hdmi = clk_ops_rcg;
 	clk_ops_rcg_hdmi.set_rate = rcg_clk_set_rate_hdmi;
 
-	mdss_clk_ctrl_init();
+	/*
+	 * MDSS needs the ahb clock and needs to init before we register the
+	 * lookup table.
+	 */
+	mdss_clk_ctrl_pre_init(&mdss_ahb_clk.c);
 }
 
 static void __init msm8974_clock_post_init(void)
 {
-	clk_set_rate(&axi_clk_src.c, 282000000);
-	clk_set_rate(&ocmemnoc_clk_src.c, 282000000);
+	if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 2) {
+		clk_set_rate(&axi_clk_src.c, 333430000);
+		clk_set_rate(&ocmemnoc_clk_src.c, 333430000);
+	} else {
+		clk_set_rate(&axi_clk_src.c, 282000000);
+		clk_set_rate(&ocmemnoc_clk_src.c, 282000000);
+	}
 
 	/*
 	 * Hold an active set vote at a rate of 40MHz for the MMSS NOC AHB
@@ -5713,11 +5570,6 @@
 	 */
 	clk_prepare_enable(&cxo_a_clk_src.c);
 
-	/* TODO: Temporarily enable a clock to allow access to LPASS core
-	 * registers.
-	 */
-	clk_prepare_enable(&audio_core_ixfabric_clk.c);
-
 	/*
 	 * TODO: Temporarily enable NOC configuration AHB clocks. Remove when
 	 * the bus driver is ready.
@@ -5725,8 +5577,6 @@
 	clk_prepare_enable(&gcc_mmss_noc_cfg_ahb_clk.c);
 	clk_prepare_enable(&gcc_ocmem_noc_cfg_ahb_clk.c);
 
-	mdss_clock_setup();
-
 	/* Set rates for single-rate clocks. */
 	clk_set_rate(&usb30_master_clk_src.c,
 			usb30_master_clk_src.freq_tbl[0].freq_hz);
@@ -5752,8 +5602,6 @@
 	clk_set_rate(&esc1_clk_src.c, esc1_clk_src.freq_tbl[0].freq_hz);
 	clk_set_rate(&hdmi_clk_src.c, hdmi_clk_src.freq_tbl[0].freq_hz);
 	clk_set_rate(&vsync_clk_src.c, vsync_clk_src.freq_tbl[0].freq_hz);
-	clk_set_rate(&audio_core_slimbus_core_clk_src.c,
-			audio_core_slimbus_core_clk_src.freq_tbl[0].freq_hz);
 }
 
 #define GCC_CC_PHYS		0xFC400000
@@ -5768,6 +5616,21 @@
 #define APCS_GCC_CC_PHYS	0xF9011000
 #define APCS_GCC_CC_SIZE	SZ_4K
 
+static struct clk *qup_i2c_clks[][2] __initdata = {
+	{&gcc_blsp1_qup1_i2c_apps_clk.c, &blsp1_qup1_i2c_apps_clk_src.c,},
+	{&gcc_blsp1_qup2_i2c_apps_clk.c, &blsp1_qup2_i2c_apps_clk_src.c,},
+	{&gcc_blsp1_qup3_i2c_apps_clk.c, &blsp1_qup3_i2c_apps_clk_src.c,},
+	{&gcc_blsp1_qup4_i2c_apps_clk.c, &blsp1_qup4_i2c_apps_clk_src.c,},
+	{&gcc_blsp1_qup5_i2c_apps_clk.c, &blsp1_qup5_i2c_apps_clk_src.c,},
+	{&gcc_blsp1_qup6_i2c_apps_clk.c, &blsp1_qup6_i2c_apps_clk_src.c,},
+	{&gcc_blsp2_qup1_i2c_apps_clk.c, &blsp2_qup1_i2c_apps_clk_src.c,},
+	{&gcc_blsp2_qup2_i2c_apps_clk.c, &blsp2_qup2_i2c_apps_clk_src.c,},
+	{&gcc_blsp2_qup3_i2c_apps_clk.c, &blsp2_qup3_i2c_apps_clk_src.c,},
+	{&gcc_blsp2_qup4_i2c_apps_clk.c, &blsp2_qup4_i2c_apps_clk_src.c,},
+	{&gcc_blsp2_qup5_i2c_apps_clk.c, &blsp2_qup5_i2c_apps_clk_src.c,},
+	{&gcc_blsp2_qup6_i2c_apps_clk.c, &blsp2_qup6_i2c_apps_clk_src.c,},
+};
+
 static void __init msm8974_clock_pre_init(void)
 {
 	virt_bases[GCC_BASE] = ioremap(GCC_CC_PHYS, GCC_CC_SIZE);
@@ -5804,6 +5667,33 @@
 	enable_rpm_scaling();
 
 	reg_init();
+
+	/* v2 specific changes */
+	if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 2) {
+		int i;
+
+		mmpll3_clk_src.c.rate =  930000000;
+		mmpll1_clk_src.c.rate = 1167000000;
+		mmpll1_clk_src.c.fmax[VDD_DIG_NOMINAL] = 1167000000;
+
+		ocmemnoc_clk_src.freq_tbl = ftbl_ocmemnoc_v2_clk;
+		ocmemnoc_clk_src.c.fmax[VDD_DIG_NOMINAL] = 333430000;
+
+		axi_clk_src.freq_tbl = ftbl_mmss_axi_v2_clk;
+		axi_clk_src.c.fmax[VDD_DIG_NOMINAL] = 333430000;
+		axi_clk_src.c.fmax[VDD_DIG_HIGH] = 466800000;
+
+		vcodec0_clk_src.freq_tbl = ftbl_venus0_vcodec0_v2_clk;
+		vcodec0_clk_src.c.fmax[VDD_DIG_HIGH] = 465000000;
+
+		mdp_clk_src.c.fmax[VDD_DIG_NOMINAL] = 240000000;
+
+		/* The parent of each of the QUP I2C clocks is an RCG on V2 */
+		for (i = 0; i < ARRAY_SIZE(qup_i2c_clks); i++)
+			qup_i2c_clks[i][0]->parent =  qup_i2c_clks[i][1];
+	}
+
+	mdss_clock_setup();
 }
 
 static int __init msm8974_clock_late_init(void)
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index dade0ed..d0b4a32 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
@@ -3689,18 +3689,18 @@
 	CLK_LOOKUP("mem_iface_clk",	imem_p_clk.c,	"kgsl-3d0.0"),
 	CLK_LOOKUP("iface_clk",		mdp_p_clk.c,		"mdp.0"),
 	CLK_LOOKUP("iface_clk",		mdp_p_clk.c,	"footswitch-8x60.4"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.0"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.1"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.2"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.3"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.4"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.5"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.6"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.7"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.8"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.9"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.10"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu.11"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.0"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.1"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.2"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.3"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.4"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.5"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.6"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.7"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.8"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.9"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.10"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu-v0.11"),
 	CLK_LOOKUP("iface_clk",		rot_p_clk.c,	"msm_rotator.0"),
 	CLK_LOOKUP("iface_clk",		rot_p_clk.c,	"footswitch-8x60.6"),
 	CLK_LOOKUP("tv_enc_pclk",	tv_enc_p_clk.c,		NULL),
@@ -3721,18 +3721,18 @@
 	CLK_LOOKUP("i2s_spkr_osr_clk",	spare_i2s_spkr_osr_clk.c,	NULL),
 	CLK_LOOKUP("i2s_spkr_bit_clk",	spare_i2s_spkr_bit_clk.c,	NULL),
 	CLK_LOOKUP("pcm_clk",		pcm_clk.c,		NULL),
-	CLK_LOOKUP("core_clk",		jpegd_axi_clk.c,	"msm_iommu.0"),
-	CLK_LOOKUP("core_clk",		vpe_axi_clk.c,		"msm_iommu.1"),
-	CLK_LOOKUP("core_clk",		mdp_axi_clk.c,		"msm_iommu.2"),
-	CLK_LOOKUP("core_clk",		mdp_axi_clk.c,		"msm_iommu.3"),
-	CLK_LOOKUP("core_clk",		rot_axi_clk.c,		"msm_iommu.4"),
-	CLK_LOOKUP("core_clk",		ijpeg_axi_clk.c,	"msm_iommu.5"),
-	CLK_LOOKUP("core_clk",		vfe_axi_clk.c,		"msm_iommu.6"),
-	CLK_LOOKUP("core_clk",		vcodec_axi_clk.c,	"msm_iommu.7"),
-	CLK_LOOKUP("core_clk",		vcodec_axi_clk.c,	"msm_iommu.8"),
-	CLK_LOOKUP("core_clk",		gfx3d_clk.c,		"msm_iommu.9"),
-	CLK_LOOKUP("core_clk",		gfx2d0_clk.c,		"msm_iommu.10"),
-	CLK_LOOKUP("core_clk",		gfx2d1_clk.c,		"msm_iommu.11"),
+	CLK_LOOKUP("core_clk",		jpegd_axi_clk.c,  "msm_iommu-v0.0"),
+	CLK_LOOKUP("core_clk",		vpe_axi_clk.c,	  "msm_iommu-v0.1"),
+	CLK_LOOKUP("core_clk",		mdp_axi_clk.c,	  "msm_iommu-v0.2"),
+	CLK_LOOKUP("core_clk",		mdp_axi_clk.c,	  "msm_iommu-v0.3"),
+	CLK_LOOKUP("core_clk",		rot_axi_clk.c,	  "msm_iommu-v0.4"),
+	CLK_LOOKUP("core_clk",		ijpeg_axi_clk.c,  "msm_iommu-v0.5"),
+	CLK_LOOKUP("core_clk",		vfe_axi_clk.c,	  "msm_iommu-v0.6"),
+	CLK_LOOKUP("core_clk",		vcodec_axi_clk.c, "msm_iommu-v0.7"),
+	CLK_LOOKUP("core_clk",		vcodec_axi_clk.c, "msm_iommu-v0.8"),
+	CLK_LOOKUP("core_clk",		gfx3d_clk.c,	  "msm_iommu-v0.9"),
+	CLK_LOOKUP("core_clk",		gfx2d0_clk.c,	  "msm_iommu-v0.10"),
+	CLK_LOOKUP("core_clk",		gfx2d1_clk.c,	  "msm_iommu-v0.11"),
 
 	CLK_LOOKUP("mdp_iommu_clk", mdp_axi_clk.c,	"msm_vidc.0"),
 	CLK_LOOKUP("rot_iommu_clk",	rot_axi_clk.c,	"msm_vidc.0"),
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index fffbcea..d6ae4335 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/clock-9625.c b/arch/arm/mach-msm/clock-9625.c
index 2e85006..9648320 100644
--- a/arch/arm/mach-msm/clock-9625.c
+++ b/arch/arm/mach-msm/clock-9625.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
@@ -33,7 +33,6 @@
 
 enum {
 	GCC_BASE,
-	LPASS_BASE,
 	APCS_BASE,
 	APCS_PLL_BASE,
 	N_BASES,
@@ -42,7 +41,6 @@
 static void __iomem *virt_bases[N_BASES];
 
 #define GCC_REG_BASE(x) (void __iomem *)(virt_bases[GCC_BASE] + (x))
-#define LPASS_REG_BASE(x) (void __iomem *)(virt_bases[LPASS_BASE] + (x))
 #define APCS_REG_BASE(x) (void __iomem *)(virt_bases[APCS_BASE] + (x))
 #define APCS_PLL_REG_BASE(x) (void __iomem *)(virt_bases[APCS_PLL_BASE] + (x))
 
@@ -93,16 +91,22 @@
 #define SDCC2_APPS_CMD_RCGR            0x0510
 #define SDCC3_APPS_CMD_RCGR            0x0550
 #define BLSP1_QUP1_SPI_APPS_CMD_RCGR   0x064C
+#define BLSP1_QUP1_I2C_APPS_CMD_RCGR   0x0660
 #define BLSP1_UART1_APPS_CMD_RCGR      0x068C
 #define BLSP1_QUP2_SPI_APPS_CMD_RCGR   0x06CC
+#define BLSP1_QUP2_I2C_APPS_CMD_RCGR   0x06E0
 #define BLSP1_UART2_APPS_CMD_RCGR      0x070C
 #define BLSP1_QUP3_SPI_APPS_CMD_RCGR   0x074C
+#define BLSP1_QUP3_I2C_APPS_CMD_RCGR   0x0760
 #define BLSP1_UART3_APPS_CMD_RCGR      0x078C
 #define BLSP1_QUP4_SPI_APPS_CMD_RCGR   0x07CC
+#define BLSP1_QUP4_I2C_APPS_CMD_RCGR   0x07E0
 #define BLSP1_UART4_APPS_CMD_RCGR      0x080C
 #define BLSP1_QUP5_SPI_APPS_CMD_RCGR   0x084C
+#define BLSP1_QUP5_I2C_APPS_CMD_RCGR   0x0860
 #define BLSP1_UART5_APPS_CMD_RCGR      0x088C
 #define BLSP1_QUP6_SPI_APPS_CMD_RCGR   0x08CC
+#define BLSP1_QUP6_I2C_APPS_CMD_RCGR   0x08E0
 #define BLSP1_UART6_APPS_CMD_RCGR      0x090C
 #define PDM2_CMD_RCGR                  0x0CD0
 #define CE1_CMD_RCGR                   0x1050
@@ -197,54 +201,11 @@
 #define IPA_CNOC_CBCR                            0x1A88
 #define IPA_SLEEP_CBCR                           0x1A8C
 
-/* LPASS registers */
-/* TODO: Needs to double check lpass regiserts after get the SWI for hw */
-#define LPAPLL_MODE_REG				0x0000
-#define LPAPLL_L_REG				0x0004
-#define LPAPLL_M_REG				0x0008
-#define LPAPLL_N_REG				0x000C
-#define LPAPLL_USER_CTL_REG			0x0010
-#define LPAPLL_CONFIG_CTL_REG			0x0014
-#define LPAPLL_TEST_CTL_REG			0x0018
-#define LPAPLL_STATUS_REG			0x001C
-
-#define LPASS_DEBUG_CLK_CTL_REG			0x29000
-#define LPASS_LPA_PLL_VOTE_APPS_REG		0x2000
-
-#define LPAIF_PRI_CMD_RCGR			0xB000
-#define LPAIF_SEC_CMD_RCGR			0xC000
-#define LPAIF_PCM0_CMD_RCGR			0xF000
-#define LPAIF_PCM1_CMD_RCGR			0x10000
-#define SLIMBUS_CMD_RCGR			0x12000
-#define LPAIF_PCMOE_CMD_RCGR			0x13000
-
-#define AUDIO_CORE_BCR				0x4000
-
-#define AUDIO_CORE_GDSCR			0x7000
-#define AUDIO_CORE_LPAIF_PRI_OSR_CBCR		0xB014
-#define AUDIO_CORE_LPAIF_PRI_IBIT_CBCR		0xB018
-#define AUDIO_CORE_LPAIF_PRI_EBIT_CBCR		0xB01C
-#define AUDIO_CORE_LPAIF_SEC_OSR_CBCR		0xC014
-#define AUDIO_CORE_LPAIF_SEC_IBIT_CBCR		0xC018
-#define AUDIO_CORE_LPAIF_SEC_EBIT_CBCR		0xC01C
-#define AUDIO_CORE_LPAIF_PCM0_IBIT_CBCR		0xF014
-#define AUDIO_CORE_LPAIF_PCM0_EBIT_CBCR		0xF018
-#define AUDIO_CORE_LPAIF_PCM1_IBIT_CBCR		0x10014
-#define AUDIO_CORE_LPAIF_PCM1_EBIT_CBCR		0x10018
-#define AUDIO_CORE_RESAMPLER_CORE_CBCR		0x11014
-#define AUDIO_CORE_RESAMPLER_LFABIF_CBCR	0x11018
-#define AUDIO_CORE_SLIMBUS_CORE_CBCR		0x12014
-#define AUDIO_CORE_SLIMBUS_LFABIF_CBCR		0x12018
-#define AUDIO_CORE_LPAIF_PCM_DATA_OE_CBCR	0x13014
-
 /* Mux source select values */
 #define cxo_source_val	0
 #define gpll0_source_val 1
 #define gpll1_hsic_source_val 4
 #define gnd_source_val	5
-#define cxo_lpass_source_val 0
-#define lpapll0_lpass_source_val 1
-#define gpll0_lpass_source_val 5
 
 #define F_GCC_GND \
 	{ \
@@ -276,17 +237,6 @@
 			| BVAL(10, 8, s##_hsic_source_val), \
 	}
 
-#define F_LPASS(f, s, div, m, n) \
-	{ \
-		.freq_hz = (f), \
-		.src_clk = &s##_clk_src.c, \
-		.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##_lpass_source_val), \
-	}
-
 #define F_APCS_PLL(f, l, m, n, pre_div, post_div, vco) \
 	{ \
 		.freq_hz = (f), \
@@ -423,21 +373,6 @@
 	},
 };
 
-static struct pll_vote_clk lpapll0_clk_src = {
-	.en_reg = (void __iomem *)LPASS_LPA_PLL_VOTE_APPS_REG,
-	.en_mask = BIT(0),
-	.status_reg = (void __iomem *)LPAPLL_STATUS_REG,
-	.status_mask = BIT(17),
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &cxo_clk_src.c,
-		.rate = 393216000,
-		.dbg_name = "lpapll0_clk_src",
-		.ops = &clk_ops_pll_vote,
-		CLK_INIT(lpapll0_clk_src.c),
-	},
-};
-
 static struct pll_vote_clk gpll1_clk_src = {
 	.en_reg = (void __iomem *)APCS_GPLL_ENA_VOTE_REG,
 	.en_mask = BIT(1),
@@ -523,6 +458,96 @@
 	},
 };
 
+static struct clk_freq_tbl ftbl_gcc_blsp1_qup1_6_i2c_apps_clk[] = {
+	F(19200000, cxo,    1, 0, 0),
+	F(50000000, gpll0, 12, 0, 0),
+	F_END
+};
+
+static struct rcg_clk blsp1_qup1_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP1_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup1_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 50000000),
+		CLK_INIT(blsp1_qup1_i2c_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup2_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP2_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup2_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 50000000),
+		CLK_INIT(blsp1_qup2_i2c_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup3_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP3_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup3_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 50000000),
+		CLK_INIT(blsp1_qup3_i2c_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup4_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP4_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup4_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 50000000),
+		CLK_INIT(blsp1_qup4_i2c_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup5_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP5_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup5_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 50000000),
+		CLK_INIT(blsp1_qup5_i2c_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup6_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP6_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup6_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 50000000),
+		CLK_INIT(blsp1_qup6_i2c_apps_clk_src.c),
+	},
+};
+
 static struct clk_freq_tbl ftbl_gcc_blsp1_qup1_6_spi_apps_clk[] = {
 	F(  960000,     cxo,   10,   1,   2),
 	F( 4800000,     cxo,    4,   0,   0),
@@ -997,7 +1022,6 @@
 
 static struct branch_clk gcc_blsp1_qup1_i2c_apps_clk = {
 	.cbcr_reg = BLSP1_QUP1_I2C_APPS_CBCR,
-	.has_sibling = 1,
 	.base = &virt_bases[GCC_BASE],
 	.c = {
 		.parent = &cxo_clk_src.c,
@@ -1021,7 +1045,6 @@
 
 static struct branch_clk gcc_blsp1_qup2_i2c_apps_clk = {
 	.cbcr_reg = BLSP1_QUP2_I2C_APPS_CBCR,
-	.has_sibling = 1,
 	.base = &virt_bases[GCC_BASE],
 	.c = {
 		.parent = &cxo_clk_src.c,
@@ -1045,7 +1068,6 @@
 
 static struct branch_clk gcc_blsp1_qup3_i2c_apps_clk = {
 	.cbcr_reg = BLSP1_QUP3_I2C_APPS_CBCR,
-	.has_sibling = 1,
 	.base = &virt_bases[GCC_BASE],
 	.c = {
 		.parent = &cxo_clk_src.c,
@@ -1069,7 +1091,6 @@
 
 static struct branch_clk gcc_blsp1_qup4_i2c_apps_clk = {
 	.cbcr_reg = BLSP1_QUP4_I2C_APPS_CBCR,
-	.has_sibling = 1,
 	.base = &virt_bases[GCC_BASE],
 	.c = {
 		.parent = &cxo_clk_src.c,
@@ -1093,7 +1114,6 @@
 
 static struct branch_clk gcc_blsp1_qup5_i2c_apps_clk = {
 	.cbcr_reg = BLSP1_QUP5_I2C_APPS_CBCR,
-	.has_sibling = 1,
 	.base = &virt_bases[GCC_BASE],
 	.c = {
 		.parent = &cxo_clk_src.c,
@@ -1117,7 +1137,6 @@
 
 static struct branch_clk gcc_blsp1_qup6_i2c_apps_clk = {
 	.cbcr_reg = BLSP1_QUP6_I2C_APPS_CBCR,
-	.has_sibling = 1,
 	.base = &virt_bases[GCC_BASE],
 	.c = {
 		.parent = &cxo_clk_src.c,
@@ -1529,274 +1548,6 @@
 	},
 };
 
-/* LPASS clock data */
-static struct clk_freq_tbl ftbl_audio_core_lpaif_clock[] = {
-	F_LPASS(  512000,   lpapll0,   16,   1,   48),
-	F_LPASS(  768000,   lpapll0,   16,   1,   32),
-	F_LPASS( 1024000,   lpapll0,   16,   1,   24),
-	F_LPASS( 1536000,   lpapll0,   16,   1,   16),
-	F_LPASS( 2048000,   lpapll0,   16,   1,   12),
-	F_LPASS( 3072000,   lpapll0,   16,   1,    8),
-	F_LPASS( 4096000,   lpapll0,   16,   1,    6),
-	F_LPASS( 6144000,   lpapll0,   16,   1,    4),
-	F_LPASS( 8192000,   lpapll0,   16,   1,    3),
-	F_LPASS(12288000,   lpapll0,   16,   1,    2),
-	F_END
-};
-
-static struct clk_freq_tbl ftbl_audio_core_lpaif_pcm_clock[] = {
-	F_LPASS(  512000,   lpapll0,   16,   1,   48),
-	F_LPASS(  768000,   lpapll0,   16,   1,   32),
-	F_LPASS( 1024000,   lpapll0,   16,   1,   24),
-	F_LPASS( 1536000,   lpapll0,   16,   1,   16),
-	F_LPASS( 2048000,   lpapll0,   16,   1,   12),
-	F_LPASS( 3072000,   lpapll0,   16,   1,    8),
-	F_LPASS( 4096000,   lpapll0,   16,   1,    6),
-	F_LPASS( 6144000,   lpapll0,   16,   1,    4),
-	F_LPASS( 8192000,   lpapll0,   16,   1,    3),
-	F_END
-};
-
-static struct rcg_clk audio_core_lpaif_pcmoe_clk_src = {
-	.cmd_rcgr_reg =  LPAIF_PCMOE_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_audio_core_lpaif_clock,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_pcmoe_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP1(LOW, 12288000),
-		CLK_INIT(audio_core_lpaif_pcmoe_clk_src.c)
-	},
-};
-
-static struct rcg_clk audio_core_lpaif_pri_clk_src = {
-	.cmd_rcgr_reg =  LPAIF_PRI_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_audio_core_lpaif_clock,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_pri_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 12288000, NOMINAL, 24576000),
-		CLK_INIT(audio_core_lpaif_pri_clk_src.c)
-	},
-};
-
-static struct rcg_clk audio_core_lpaif_sec_clk_src = {
-	.cmd_rcgr_reg =  LPAIF_SEC_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_audio_core_lpaif_clock,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_sec_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 12288000, NOMINAL, 24576000),
-		CLK_INIT(audio_core_lpaif_sec_clk_src.c)
-	},
-};
-
-static struct clk_freq_tbl ftbl_audio_core_slimbus_core_clock[] = {
-	F_LPASS(26041000,   lpapll0,   1,   10,   151),
-	F_END
-};
-
-static struct rcg_clk audio_core_slimbus_core_clk_src = {
-	.cmd_rcgr_reg =  SLIMBUS_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_audio_core_slimbus_core_clock,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_slimbus_core_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 13107000, NOMINAL, 26214000),
-		CLK_INIT(audio_core_slimbus_core_clk_src.c)
-	},
-};
-
-static struct rcg_clk audio_core_lpaif_pcm0_clk_src = {
-	.cmd_rcgr_reg =  LPAIF_PCM0_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_audio_core_lpaif_pcm_clock,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_pcm0_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 4096000, NOMINAL, 8192000),
-		CLK_INIT(audio_core_lpaif_pcm0_clk_src.c)
-	},
-};
-
-static struct rcg_clk audio_core_lpaif_pcm1_clk_src = {
-	.cmd_rcgr_reg =  LPAIF_PCM1_CMD_RCGR,
-	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_audio_core_lpaif_pcm_clock,
-	.current_freq = &rcg_dummy_freq,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_pcm1_clk_src",
-		.ops = &clk_ops_rcg_mnd,
-		VDD_DIG_FMAX_MAP2(LOW, 4096000, NOMINAL, 8192000),
-		CLK_INIT(audio_core_lpaif_pcm1_clk_src.c)
-	},
-};
-
-static struct branch_clk audio_core_slimbus_lfabif_clk = {
-	.cbcr_reg = AUDIO_CORE_SLIMBUS_LFABIF_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_slimbus_lfabif_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_slimbus_lfabif_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_pcm_data_oe_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_PCM_DATA_OE_CBCR,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &audio_core_lpaif_pcmoe_clk_src.c,
-		.dbg_name = "audio_core_lpaif_pcm_data_oe_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_pcm_data_oe_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_slimbus_core_clk = {
-	.cbcr_reg = AUDIO_CORE_SLIMBUS_CORE_CBCR,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &audio_core_slimbus_core_clk_src.c,
-		.dbg_name = "audio_core_slimbus_core_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_slimbus_core_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_pri_ebit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_PRI_EBIT_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_pri_ebit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_pri_ebit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_pri_ibit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_PRI_IBIT_CBCR,
-	.has_sibling = 1,
-	.max_div = 15,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &audio_core_lpaif_pri_clk_src.c,
-		.dbg_name = "audio_core_lpaif_pri_ibit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_pri_ibit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_pri_osr_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_PRI_OSR_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &audio_core_lpaif_pri_clk_src.c,
-		.dbg_name = "audio_core_lpaif_pri_osr_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_pri_osr_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_pcm0_ebit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_PCM0_EBIT_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_pcm0_ebit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_pcm0_ebit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_pcm0_ibit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_PCM0_IBIT_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &audio_core_lpaif_pcm0_clk_src.c,
-		.dbg_name = "audio_core_lpaif_pcm0_ibit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_pcm0_ibit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_sec_ebit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_SEC_EBIT_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_sec_ebit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_sec_ebit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_sec_ibit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_SEC_IBIT_CBCR,
-	.has_sibling = 1,
-	.max_div = 15,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &audio_core_lpaif_sec_clk_src.c,
-		.dbg_name = "audio_core_lpaif_sec_ibit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_sec_ibit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_sec_osr_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_SEC_OSR_CBCR,
-	.has_sibling = 1,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &audio_core_lpaif_sec_clk_src.c,
-		.dbg_name = "audio_core_lpaif_sec_osr_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_sec_osr_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_pcm1_ebit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_PCM1_EBIT_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.dbg_name = "audio_core_lpaif_pcm1_ebit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_pcm1_ebit_clk.c),
-	},
-};
-
-static struct branch_clk audio_core_lpaif_pcm1_ibit_clk = {
-	.cbcr_reg = AUDIO_CORE_LPAIF_PCM1_IBIT_CBCR,
-	.has_sibling = 0,
-	.base = &virt_bases[LPASS_BASE],
-	.c = {
-		.parent = &audio_core_lpaif_pcm1_clk_src.c,
-		.dbg_name = "audio_core_lpaif_pcm1_ibit_clk",
-		.ops = &clk_ops_branch,
-		CLK_INIT(audio_core_lpaif_pcm1_ibit_clk.c),
-	},
-};
-
 static DEFINE_CLK_MEASURE(a5_m_clk);
 
 #ifdef CONFIG_DEBUG_FS
@@ -1807,7 +1558,7 @@
 	u32 debug_mux;
 };
 
-struct measure_mux_entry measure_mux[] = {
+struct measure_mux_entry measure_mux_common[] __initdata = {
 	{&gcc_pdm_ahb_clk.c,			GCC_BASE, 0x00d0},
 	{&gcc_usb_hsic_xcvr_fs_clk.c,		GCC_BASE, 0x005d},
 	{&gcc_usb_hsic_system_clk.c,		GCC_BASE, 0x0059},
@@ -1847,22 +1598,28 @@
 	{&gcc_sdcc2_ahb_clk.c,			GCC_BASE, 0x0071},
 	{&gcc_ce1_clk.c,			GCC_BASE, 0x0138},
 	{&gcc_sys_noc_ipa_axi_clk.c,		GCC_BASE, 0x0007},
-
-	{&audio_core_lpaif_pcm_data_oe_clk.c,	LPASS_BASE, 0x0030},
-	{&audio_core_slimbus_core_clk.c,	LPASS_BASE, 0x003d},
-	{&audio_core_lpaif_pri_clk_src.c,	LPASS_BASE, 0x0017},
-	{&audio_core_lpaif_sec_clk_src.c,	LPASS_BASE, 0x0016},
-	{&audio_core_slimbus_core_clk_src.c,	LPASS_BASE, 0x0011},
-	{&audio_core_lpaif_pcm1_clk_src.c,	LPASS_BASE, 0x0012},
-	{&audio_core_lpaif_pcm0_clk_src.c,	LPASS_BASE, 0x0013},
-	{&audio_core_lpaif_pcmoe_clk_src.c,	LPASS_BASE, 0x000f},
-	{&audio_core_slimbus_lfabif_clk.c,	LPASS_BASE, 0x003e},
+	{&gcc_ipa_clk.c,			GCC_BASE, 0x01E0},
+	{&gcc_ipa_cnoc_clk.c,			GCC_BASE, 0x01E1},
+	{&gcc_ipa_sleep_clk.c,			GCC_BASE, 0x01E2},
+	{&gcc_qpic_clk.c,			GCC_BASE, 0x01D8},
+	{&gcc_qpic_ahb_clk.c,			GCC_BASE, 0x01D9},
 
 	{&a5_m_clk,				APCS_BASE, 0x3},
 
 	{&dummy_clk,				N_BASES,    0x0000},
 };
 
+struct measure_mux_entry measure_mux_v2_only[] __initdata = {
+	{&gcc_ipa_clk.c,			GCC_BASE, 0x01E0},
+	{&gcc_ipa_cnoc_clk.c,			GCC_BASE, 0x01E1},
+	{&gcc_ipa_sleep_clk.c,			GCC_BASE, 0x01E2},
+	{&gcc_qpic_clk.c,			GCC_BASE, 0x01D8},
+	{&gcc_qpic_ahb_clk.c,			GCC_BASE, 0x01D9},
+};
+
+struct measure_mux_entry measure_mux[ARRAY_SIZE(measure_mux_common)
+				+ ARRAY_SIZE(measure_mux_v2_only)];
+
 static int measure_clk_set_parent(struct clk *c, struct clk *parent)
 {
 	struct measure_clk *clk = to_measure_clk(c);
@@ -1887,7 +1644,6 @@
 	clk->sample_ticks = 0x10000;
 	clk->multiplier = 1;
 
-	writel_relaxed(0, LPASS_REG_BASE(LPASS_DEBUG_CLK_CTL_REG));
 	writel_relaxed(0, GCC_REG_BASE(GCC_DEBUG_CLK_CTL_REG));
 
 	switch (measure_mux[i].base) {
@@ -1896,16 +1652,6 @@
 		clk_sel = measure_mux[i].debug_mux;
 		break;
 
-	case LPASS_BASE:
-		clk_sel = 0x161;
-		regval = BVAL(15, 0, measure_mux[i].debug_mux);
-		writel_relaxed(regval, LPASS_REG_BASE(LPASS_DEBUG_CLK_CTL_REG));
-
-		/* Activate debug clock output */
-		regval |= BIT(20);
-		writel_relaxed(regval, LPASS_REG_BASE(LPASS_DEBUG_CLK_CTL_REG));
-		break;
-
 	case APCS_BASE:
 		clk_sel = 0x16A;
 		regval = BVAL(5, 3, measure_mux[i].debug_mux);
@@ -2049,7 +1795,7 @@
 	CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "msm_serial_hsl.0"),
 	CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "f9924000.spi"),
 	CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "f9925000.i2c"),
-	CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, ""),
+	CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "f991d000.uart"),
 	CLK_LOOKUP("core_clk", gcc_blsp1_qup1_i2c_apps_clk.c, ""),
 	CLK_LOOKUP("core_clk", gcc_blsp1_qup1_spi_apps_clk.c, ""),
 	CLK_LOOKUP("core_clk", gcc_blsp1_qup2_i2c_apps_clk.c, ""),
@@ -2062,7 +1808,7 @@
 	CLK_LOOKUP("core_clk", gcc_blsp1_qup5_spi_apps_clk.c, ""),
 	CLK_LOOKUP("core_clk", gcc_blsp1_qup6_i2c_apps_clk.c, ""),
 	CLK_LOOKUP("core_clk", gcc_blsp1_qup6_spi_apps_clk.c, ""),
-	CLK_LOOKUP("core_clk", gcc_blsp1_uart1_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_uart1_apps_clk.c, "f991d000.uart"),
 	CLK_LOOKUP("core_clk", gcc_blsp1_uart2_apps_clk.c, ""),
 	CLK_LOOKUP("core_clk", gcc_blsp1_uart3_apps_clk.c, "msm_serial_hsl.0"),
 	CLK_LOOKUP("core_clk", gcc_blsp1_uart4_apps_clk.c, ""),
@@ -2097,37 +1843,21 @@
 
 	CLK_LOOKUP("iface_clk", gcc_usb_hs_ahb_clk.c,     "f9a55000.usb"),
 	CLK_LOOKUP("core_clk", gcc_usb_hs_system_clk.c,   "f9a55000.usb"),
-	CLK_LOOKUP("iface_clk", gcc_usb_hsic_ahb_clk.c,	  "f9a15000.hsic"),
-	CLK_LOOKUP("phy_clk", gcc_usb_hsic_clk.c,	  "f9a15000.hsic"),
-	CLK_LOOKUP("cal_clk", gcc_usb_hsic_io_cal_clk.c,  "f9a15000.hsic"),
-	CLK_LOOKUP("core_clk", gcc_usb_hsic_system_clk.c, "f9a15000.hsic"),
-	CLK_LOOKUP("alt_core_clk", gcc_usb_hsic_xcvr_fs_clk.c,
-							  "f9a15000.hsic"),
+	CLK_LOOKUP("iface_clk", gcc_usb_hsic_ahb_clk.c,	  "msm_hsic_host"),
+	CLK_LOOKUP("phy_clk", gcc_usb_hsic_clk.c,	  "msm_hsic_host"),
+	CLK_LOOKUP("cal_clk", gcc_usb_hsic_io_cal_clk.c,  "msm_hsic_host"),
+	CLK_LOOKUP("core_clk", gcc_usb_hsic_system_clk.c, "msm_hsic_host"),
+	CLK_LOOKUP("alt_core_clk", gcc_usb_hsic_xcvr_fs_clk.c, ""),
 
-	/* LPASS clocks */
-	CLK_LOOKUP("core_clk", audio_core_slimbus_core_clk.c, "fe12f000.slim"),
-	CLK_LOOKUP("iface_clk", audio_core_slimbus_lfabif_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_ce1_clk.c, "fd400000.qcom,qcedev"),
+	CLK_LOOKUP("iface_clk", gcc_ce1_ahb_clk.c, "fd400000.qcom,qcedev"),
+	CLK_LOOKUP("bus_clk", gcc_ce1_axi_clk.c, "fd400000.qcom,qcedev"),
+	CLK_LOOKUP("core_clk_src", ce1_clk_src.c, "fd400000.qcom,qcedev"),
 
-	CLK_LOOKUP("core_clk", audio_core_lpaif_pri_clk_src.c,
-		   "msm-dai-q6-mi2s.0"),
-	CLK_LOOKUP("osr_clk", audio_core_lpaif_pri_osr_clk.c,
-		   "msm-dai-q6-mi2s.0"),
-	CLK_LOOKUP("ebit_clk", audio_core_lpaif_pri_ebit_clk.c,
-		   "msm-dai-q6-mi2s.0"),
-	CLK_LOOKUP("ibit_clk", audio_core_lpaif_pri_ibit_clk.c,
-		   "msm-dai-q6-mi2s.0"),
-	CLK_LOOKUP("core_clk", audio_core_lpaif_sec_clk_src.c, ""),
-	CLK_LOOKUP("osr_clk", audio_core_lpaif_sec_osr_clk.c, ""),
-	CLK_LOOKUP("ebit_clk", audio_core_lpaif_sec_ebit_clk.c, ""),
-	CLK_LOOKUP("ibit_clk", audio_core_lpaif_sec_ibit_clk.c, ""),
-	CLK_LOOKUP("core_clk", audio_core_lpaif_pcm0_clk_src.c, ""),
-	CLK_LOOKUP("ebit_clk", audio_core_lpaif_pcm0_ebit_clk.c, ""),
-	CLK_LOOKUP("ibit_clk", audio_core_lpaif_pcm0_ibit_clk.c, ""),
-	CLK_LOOKUP("core_clk", audio_core_lpaif_pcm1_clk_src.c, ""),
-	CLK_LOOKUP("ebit_clk", audio_core_lpaif_pcm1_ebit_clk.c, ""),
-	CLK_LOOKUP("ibit_clk", audio_core_lpaif_pcm1_ibit_clk.c, ""),
-	CLK_LOOKUP("core_oe_src_clk", audio_core_lpaif_pcmoe_clk_src.c, ""),
-	CLK_LOOKUP("core_oe_clk", audio_core_lpaif_pcm_data_oe_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_ce1_clk.c, "fd400000.qcom,qcrypto"),
+	CLK_LOOKUP("iface_clk", gcc_ce1_ahb_clk.c, "fd400000.qcom,qcrypto"),
+	CLK_LOOKUP("bus_clk", gcc_ce1_axi_clk.c, "fd400000.qcom,qcrypto"),
+	CLK_LOOKUP("core_clk_src", ce1_clk_src.c, "fd400000.qcom,qcrypto"),
 
 	/* RPM and voter clocks */
 	CLK_LOOKUP("bus_clk", snoc_clk.c, ""),
@@ -2152,7 +1882,7 @@
 
 	CLK_LOOKUP("a5_m_clk", a5_m_clk, ""),
 
-	/* Coresight QDSS clocks */
+	/* CoreSight clocks */
 	CLK_LOOKUP("core_clk", qdss_clk.c, "fc322000.tmc"),
 	CLK_LOOKUP("core_clk", qdss_clk.c, "fc318000.tpiu"),
 	CLK_LOOKUP("core_clk", qdss_clk.c, "fc31c000.replicator"),
@@ -2161,94 +1891,42 @@
 	CLK_LOOKUP("core_clk", qdss_clk.c, "fc319000.funnel"),
 	CLK_LOOKUP("core_clk", qdss_clk.c, "fc31a000.funnel"),
 	CLK_LOOKUP("core_clk", qdss_clk.c, "fc321000.stm"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc332000.etm"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc332000.jtagmm"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc308000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc309000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc30a000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc30b000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc30c000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc30d000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc30e000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc30f000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc310000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc333000.cti"),
 
-	CLK_LOOKUP("core_a_clk", qdss_clk.c, "fc322000.tmc"),
-	CLK_LOOKUP("core_a_clk", qdss_clk.c, "fc318000.tpiu"),
-	CLK_LOOKUP("core_a_clk", qdss_clk.c, "fc31c000.replicator"),
-	CLK_LOOKUP("core_a_clk", qdss_clk.c, "fc307000.tmc"),
-	CLK_LOOKUP("core_a_clk", qdss_clk.c, "fc31b000.funnel"),
-	CLK_LOOKUP("core_a_clk", qdss_clk.c, "fc319000.funnel"),
-	CLK_LOOKUP("core_a_clk", qdss_clk.c, "fc31a000.funnel"),
-	CLK_LOOKUP("core_a_clk", qdss_clk.c, "fc321000.stm"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc322000.tmc"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc318000.tpiu"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc31c000.replicator"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc307000.tmc"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc31b000.funnel"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc319000.funnel"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc31a000.funnel"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc321000.stm"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc332000.etm"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc332000.jtagmm"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc308000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc309000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc30a000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc30b000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc30c000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc30d000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc30e000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc30f000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc310000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc333000.cti"),
 
 };
 
-static struct pll_config_regs gpll0_regs __initdata = {
-	.l_reg = (void __iomem *)GPLL0_L_REG,
-	.m_reg = (void __iomem *)GPLL0_M_REG,
-	.n_reg = (void __iomem *)GPLL0_N_REG,
-	.config_reg = (void __iomem *)GPLL0_USER_CTL_REG,
-	.mode_reg = (void __iomem *)GPLL0_MODE_REG,
-	.base = &virt_bases[GCC_BASE],
-};
-
-/* GPLL0 at 600 MHz, main output enabled. */
-static struct pll_config gpll0_config __initdata = {
-	.l = 0x1f,
-	.m = 0x1,
-	.n = 0x4,
-	.vco_val = 0x0,
-	.vco_mask = BM(21, 20),
-	.pre_div_val = 0x0,
-	.pre_div_mask = BM(14, 12),
-	.post_div_val = 0x0,
-	.post_div_mask = BM(9, 8),
-	.mn_ena_val = BIT(24),
-	.mn_ena_mask = BIT(24),
-	.main_output_val = BIT(0),
-	.main_output_mask = BIT(0),
-};
-
-static struct pll_config_regs gpll1_regs __initdata = {
-	.l_reg = (void __iomem *)GPLL1_L_REG,
-	.m_reg = (void __iomem *)GPLL1_M_REG,
-	.n_reg = (void __iomem *)GPLL1_N_REG,
-	.config_reg = (void __iomem *)GPLL1_USER_CTL_REG,
-	.mode_reg = (void __iomem *)GPLL1_MODE_REG,
-	.base = &virt_bases[GCC_BASE],
-};
-
-/* GPLL1 at 480 MHz, main output enabled. */
-static struct pll_config gpll1_config __initdata = {
-	.l = 0x19,
-	.m = 0x0,
-	.n = 0x1,
-	.vco_val = 0x0,
-	.vco_mask = BM(21, 20),
-	.pre_div_val = 0x0,
-	.pre_div_mask = BM(14, 12),
-	.post_div_val = 0x0,
-	.post_div_mask = BM(9, 8),
-	.main_output_val = BIT(0),
-	.main_output_mask = BIT(0),
-};
-
-static struct pll_config_regs lpapll0_regs __initdata = {
-	.l_reg = (void __iomem *)LPAPLL_L_REG,
-	.m_reg = (void __iomem *)LPAPLL_M_REG,
-	.n_reg = (void __iomem *)LPAPLL_N_REG,
-	.config_reg = (void __iomem *)LPAPLL_USER_CTL_REG,
-	.mode_reg = (void __iomem *)LPAPLL_MODE_REG,
-	.base = &virt_bases[LPASS_BASE],
-};
-
-/* LPAPLL0 at 393.216 MHz, main output enabled. */
-static struct pll_config lpapll0_config __initdata = {
-	.l = 0x28,
-	.m = 0x18,
-	.n = 0x19,
-	.vco_val = 0x0,
-	.vco_mask = BM(21, 20),
-	.pre_div_val = 0x0,
-	.pre_div_mask = BM(14, 12),
-	.post_div_val = BVAL(9, 8, 0x1),
-	.post_div_mask = BM(9, 8),
-	.mn_ena_val = BIT(24),
-	.mn_ena_mask = BIT(24),
-	.main_output_val = BIT(0),
-	.main_output_mask = BIT(0),
-};
-
 #define PLL_AUX_OUTPUT_BIT 1
 #define PLL_AUX2_OUTPUT_BIT 2
 
@@ -2290,64 +1968,9 @@
 	return 0;
 }
 
-static void __init configure_apcs_pll(void)
-{
-	u32 regval;
-
-	clk_set_rate(&apcspll_clk_src.c, 998400000);
-
-	writel_relaxed(0x00141200,
-			APCS_PLL_REG_BASE(APCS_CPU_PLL_CONFIG_CTL_REG));
-
-	/* Enable AUX and AUX2 output */
-	regval = readl_relaxed(APCS_PLL_REG_BASE(APCS_CPU_PLL_USER_CTL_REG));
-	regval |= BIT(PLL_AUX_OUTPUT_BIT) | BIT(PLL_AUX2_OUTPUT_BIT);
-	writel_relaxed(regval, APCS_PLL_REG_BASE(APCS_CPU_PLL_USER_CTL_REG));
-}
-
-#define PWR_ON_MASK		BIT(31)
-#define EN_REST_WAIT_MASK	(0xF << 20)
-#define EN_FEW_WAIT_MASK	(0xF << 16)
-#define CLK_DIS_WAIT_MASK	(0xF << 12)
-#define SW_OVERRIDE_MASK	BIT(2)
-#define HW_CONTROL_MASK		BIT(1)
-#define SW_COLLAPSE_MASK	BIT(0)
-
-/* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */
-#define EN_REST_WAIT_VAL	(0x2 << 20)
-#define EN_FEW_WAIT_VAL		(0x2 << 16)
-#define CLK_DIS_WAIT_VAL	(0x2 << 12)
-#define GDSC_TIMEOUT_US		50000
-
 static void __init reg_init(void)
 {
-	u32 regval, status;
-	int ret;
-
-	if (!(readl_relaxed(GCC_REG_BASE(GPLL0_STATUS_REG))
-			& gpll0_clk_src.status_mask))
-		configure_sr_hpm_lp_pll(&gpll0_config, &gpll0_regs, 1);
-
-	if (!(readl_relaxed(GCC_REG_BASE(GPLL1_STATUS_REG))
-			& gpll1_clk_src.status_mask))
-		configure_sr_hpm_lp_pll(&gpll1_config, &gpll1_regs, 1);
-
-	configure_sr_hpm_lp_pll(&lpapll0_config, &lpapll0_regs, 1);
-
-	/* TODO: Remove A5 pll configuration once the bootloader is avaiable */
-	regval = readl_relaxed(APCS_PLL_REG_BASE(APCS_CPU_PLL_MODE_REG));
-	if ((regval & BM(2, 0)) != 0x7)
-		configure_apcs_pll();
-
-	/* TODO:
-	 * 1) do we need to turn on AUX2 output too?
-	 * 2) if need to vote off all sleep clocks
-	 */
-
-	/* Enable GPLL0's aux outputs. */
-	regval = readl_relaxed(GCC_REG_BASE(GPLL0_USER_CTL_REG));
-	regval |= BIT(PLL_AUX_OUTPUT_BIT) | BIT(PLL_AUX2_OUTPUT_BIT);
-	writel_relaxed(regval, GCC_REG_BASE(GPLL0_USER_CTL_REG));
+	u32 regval;
 
 	/* Vote for GPLL0 to turn on. Needed by acpuclock. */
 	regval = readl_relaxed(GCC_REG_BASE(APCS_GPLL_ENA_VOTE_REG));
@@ -2359,31 +1982,6 @@
 	 * register.
 	 */
 	writel_relaxed(0x0, GCC_REG_BASE(APCS_CLOCK_SLEEP_ENA_VOTE));
-
-	/*
-	 * TODO: The following sequence enables the LPASS audio core GDSC.
-	 * Remove when this becomes unnecessary.
-	 */
-
-	/*
-	 * Disable HW trigger: collapse/restore occur based on registers writes.
-	 * Disable SW override: Use hardware state-machine for sequencing.
-	 */
-	regval = readl_relaxed(LPASS_REG_BASE(AUDIO_CORE_GDSCR));
-	regval &= ~(HW_CONTROL_MASK | SW_OVERRIDE_MASK);
-
-	/* Configure wait time between states. */
-	regval &= ~(EN_REST_WAIT_MASK | EN_FEW_WAIT_MASK | CLK_DIS_WAIT_MASK);
-	regval |= EN_REST_WAIT_VAL | EN_FEW_WAIT_VAL | CLK_DIS_WAIT_VAL;
-	writel_relaxed(regval, LPASS_REG_BASE(AUDIO_CORE_GDSCR));
-
-	regval = readl_relaxed(LPASS_REG_BASE(AUDIO_CORE_GDSCR));
-	regval &= ~BIT(0);
-	writel_relaxed(regval, LPASS_REG_BASE(AUDIO_CORE_GDSCR));
-
-	ret = readl_poll_timeout(LPASS_REG_BASE(AUDIO_CORE_GDSCR), status,
-				status & PWR_ON_MASK, 50, GDSC_TIMEOUT_US);
-	WARN(ret, "LPASS Audio Core GDSC did not power on.\n");
 }
 
 static void __init msm9625_clock_post_init(void)
@@ -2412,32 +2010,39 @@
 	clk_set_rate(&usb_hsic_xcvr_fs_clk_src.c,
 			usb_hsic_xcvr_fs_clk_src.freq_tbl[0].freq_hz);
 	clk_set_rate(&pdm2_clk_src.c, pdm2_clk_src.freq_tbl[0].freq_hz);
-	clk_set_rate(&audio_core_slimbus_core_clk_src.c,
-			audio_core_slimbus_core_clk_src.freq_tbl[0].freq_hz);
+	/*
+	 * TODO: set rate on behalf of the i2c driver until the i2c driver
+	 *	 distinguish v1/v2 and call set rate accordingly.
+	 */
+	if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 2)
+		clk_set_rate(&blsp1_qup3_i2c_apps_clk_src.c,
+			blsp1_qup3_i2c_apps_clk_src.freq_tbl[0].freq_hz);
 }
 
 #define GCC_CC_PHYS		0xFC400000
 #define GCC_CC_SIZE		SZ_16K
 
-#define LPASS_CC_PHYS		0xFE000000
-#define LPASS_CC_SIZE		SZ_256K
-
 #define APCS_GCC_CC_PHYS	0xF9011000
 #define APCS_GCC_CC_SIZE	SZ_4K
 
 #define APCS_PLL_PHYS		0xF9008018
 #define APCS_PLL_SIZE		0x18
 
+static struct clk *i2c_apps_clks[][2] __initdata = {
+	{&gcc_blsp1_qup1_i2c_apps_clk.c, &blsp1_qup1_i2c_apps_clk_src.c},
+	{&gcc_blsp1_qup2_i2c_apps_clk.c, &blsp1_qup2_i2c_apps_clk_src.c},
+	{&gcc_blsp1_qup3_i2c_apps_clk.c, &blsp1_qup3_i2c_apps_clk_src.c},
+	{&gcc_blsp1_qup4_i2c_apps_clk.c, &blsp1_qup4_i2c_apps_clk_src.c},
+	{&gcc_blsp1_qup5_i2c_apps_clk.c, &blsp1_qup5_i2c_apps_clk_src.c},
+	{&gcc_blsp1_qup6_i2c_apps_clk.c, &blsp1_qup6_i2c_apps_clk_src.c},
+};
+
 static void __init msm9625_clock_pre_init(void)
 {
 	virt_bases[GCC_BASE] = ioremap(GCC_CC_PHYS, GCC_CC_SIZE);
 	if (!virt_bases[GCC_BASE])
 		panic("clock-9625: Unable to ioremap GCC memory!");
 
-	virt_bases[LPASS_BASE] = ioremap(LPASS_CC_PHYS, LPASS_CC_SIZE);
-	if (!virt_bases[LPASS_BASE])
-		panic("clock-9625: Unable to ioremap LPASS_CC memory!");
-
 	virt_bases[APCS_BASE] = ioremap(APCS_GCC_CC_PHYS, APCS_GCC_CC_SIZE);
 	if (!virt_bases[APCS_BASE])
 		panic("clock-9625: Unable to ioremap APCS_GCC_CC memory!");
@@ -2446,6 +2051,13 @@
 	if (!virt_bases[APCS_PLL_BASE])
 		panic("clock-9625: Unable to ioremap APCS_PLL memory!");
 
+	/* The parent of each of the QUP I2C APPS clocks is an RCG on v2 */
+	if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 2) {
+		int i, num_cores = ARRAY_SIZE(i2c_apps_clks);
+		for (i = 0; i < num_cores; i++)
+			i2c_apps_clks[i][0]->parent = i2c_apps_clks[i][1];
+	}
+
 	clk_ops_local_pll.enable = sr_pll_clk_enable_9625;
 
 	vdd_dig_reg = regulator_get(NULL, "vdd_dig");
@@ -2458,6 +2070,16 @@
 	enable_rpm_scaling();
 
 	reg_init();
+
+	/* Construct measurement mux array */
+	if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 2) {
+		memcpy(measure_mux,
+			measure_mux_v2_only, sizeof(measure_mux_v2_only));
+		memcpy(measure_mux + ARRAY_SIZE(measure_mux_v2_only),
+			measure_mux_common, sizeof(measure_mux_common));
+	} else
+		memcpy(measure_mux,
+			measure_mux_common, sizeof(measure_mux_common));
 }
 
 static int __init msm9625_clock_late_init(void)
diff --git a/arch/arm/mach-msm/clock-debug.c b/arch/arm/mach-msm/clock-debug.c
index 489d623..d540f2b 100644
--- a/arch/arm/mach-msm/clock-debug.c
+++ b/arch/arm/mach-msm/clock-debug.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/clock-dss-8960.c b/arch/arm/mach-msm/clock-dss-8960.c
index ca1a3e1..c147a33 100644
--- a/arch/arm/mach-msm/clock-dss-8960.c
+++ b/arch/arm/mach-msm/clock-dss-8960.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
@@ -334,6 +334,22 @@
 		writel_relaxed(0x3B, HDMI_PHY_PLL_VCOCAL_CFG2);
 	break;
 
+	case 108000000:
+		writel_relaxed(0x08, HDMI_PHY_PLL_REFCLK_CFG);
+		writel_relaxed(0x21, HDMI_PHY_PLL_LOOP_FLT_CFG0);
+		writel_relaxed(0xF9, HDMI_PHY_PLL_LOOP_FLT_CFG1);
+		writel_relaxed(0x1C, HDMI_PHY_PLL_VCOCAL_CFG0);
+		writel_relaxed(0x02, HDMI_PHY_PLL_VCOCAL_CFG1);
+		writel_relaxed(0x3B, HDMI_PHY_PLL_VCOCAL_CFG2);
+		writel_relaxed(0x86, HDMI_PHY_PLL_VCOCAL_CFG4);
+		writel_relaxed(0x00, HDMI_PHY_PLL_VCOCAL_CFG5);
+		writel_relaxed(0x49, HDMI_PHY_PLL_SDM_CFG0);
+		writel_relaxed(0x49, HDMI_PHY_PLL_SDM_CFG1);
+		writel_relaxed(0x00, HDMI_PHY_PLL_SDM_CFG2);
+		writel_relaxed(0x00, HDMI_PHY_PLL_SDM_CFG3);
+		writel_relaxed(0x00, HDMI_PHY_PLL_SDM_CFG4);
+	break;
+
 	case 148500000:
 		/* 1080p60/1080p50 case */
 		writel_relaxed(0x2, HDMI_PHY_PLL_REFCLK_CFG);
diff --git a/arch/arm/mach-msm/clock-dss-8960.h b/arch/arm/mach-msm/clock-dss-8960.h
index 72e70fc..eb48c7f 100644
--- a/arch/arm/mach-msm/clock-dss-8960.h
+++ b/arch/arm/mach-msm/clock-dss-8960.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/clock-dummy.c b/arch/arm/mach-msm/clock-dummy.c
index fda7a92..883a5c2 100644
--- a/arch/arm/mach-msm/clock-dummy.c
+++ b/arch/arm/mach-msm/clock-dummy.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/clock-fsm9xxx.c b/arch/arm/mach-msm/clock-fsm9xxx.c
index 2900d45..e3a4818 100644
--- a/arch/arm/mach-msm/clock-fsm9xxx.c
+++ b/arch/arm/mach-msm/clock-fsm9xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/clock-local.c b/arch/arm/mach-msm/clock-local.c
index 4432795..a173ba9 100644
--- a/arch/arm/mach-msm/clock-local.c
+++ b/arch/arm/mach-msm/clock-local.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
@@ -598,20 +598,21 @@
 static enum handoff branch_clk_handoff(struct clk *c)
 {
 	struct branch_clk *br = to_branch_clk(c);
-	return branch_handoff(&br->b, &br->c);
+	if (branch_handoff(&br->b, &br->c) == HANDOFF_ENABLED_CLK) {
+		br->enabled = true;
+		return HANDOFF_ENABLED_CLK;
+	}
+
+	return HANDOFF_DISABLED_CLK;
 }
 
-static enum handoff rcg_clk_handoff(struct clk *c)
+static struct clk *rcg_clk_get_parent(struct clk *c)
 {
 	struct rcg_clk *rcg = to_rcg_clk(c);
 	uint32_t ctl_val, ns_val, md_val, ns_mask;
 	struct clk_freq_tbl *freq;
-	enum handoff ret;
 
 	ctl_val = readl_relaxed(rcg->b.ctl_reg);
-	ret = branch_handoff(&rcg->b, &rcg->c);
-	if (ret == HANDOFF_DISABLED_CLK)
-		return HANDOFF_DISABLED_CLK;
 
 	if (rcg->bank_info) {
 		const struct bank_masks *bank_masks = rcg->bank_info;
@@ -628,21 +629,40 @@
 		ns_mask = rcg->ns_mask;
 		md_val = rcg->md_reg ? readl_relaxed(rcg->md_reg) : 0;
 	}
+
 	if (!ns_mask)
-		return HANDOFF_UNKNOWN_RATE;
+		return NULL;
+
 	ns_val = readl_relaxed(rcg->ns_reg) & ns_mask;
 	for (freq = rcg->freq_tbl; freq->freq_hz != FREQ_END; freq++) {
 		if ((freq->ns_val & ns_mask) == ns_val &&
 		    (!freq->md_val || freq->md_val == md_val))
 			break;
 	}
+
 	if (freq->freq_hz == FREQ_END)
-		return HANDOFF_UNKNOWN_RATE;
+		return NULL;
 
+	/* Cache the results for the handoff code. */
 	rcg->current_freq = freq;
-	c->parent = freq->src_clk;
-	c->rate = freq->freq_hz;
 
+	return freq->src_clk;
+}
+
+static enum handoff rcg_clk_handoff(struct clk *c)
+{
+	struct rcg_clk *rcg = to_rcg_clk(c);
+	enum handoff ret;
+
+	if (rcg->current_freq && rcg->current_freq->freq_hz != FREQ_END)
+		c->rate = rcg->current_freq->freq_hz;
+
+	ret = branch_handoff(&rcg->b, &rcg->c);
+	if (ret == HANDOFF_DISABLED_CLK)
+		return HANDOFF_DISABLED_CLK;
+
+	rcg->prepared = true;
+	rcg->enabled = true;
 	return HANDOFF_ENABLED_CLK;
 }
 
@@ -861,6 +881,7 @@
 	.round_rate = rcg_clk_round_rate,
 	.reset = rcg_clk_reset,
 	.set_flags = rcg_clk_set_flags,
+	.get_parent = rcg_clk_get_parent,
 };
 
 static int cdiv_clk_enable(struct clk *c)
@@ -940,6 +961,7 @@
 		reg_val >>= cdiv->div_offset;
 		cdiv->cur_div = (reg_val & (cdiv->max_div - 1)) + 1;
 	}
+	c->rate = cdiv->cur_div;
 
 	return HANDOFF_ENABLED_CLK;
 }
diff --git a/arch/arm/mach-msm/clock-local.h b/arch/arm/mach-msm/clock-local.h
index ff6dc69..9476850 100644
--- a/arch/arm/mach-msm/clock-local.h
+++ b/arch/arm/mach-msm/clock-local.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/clock-local2.c b/arch/arm/mach-msm/clock-local2.c
index cf42355..dd78557 100644
--- a/arch/arm/mach-msm/clock-local2.c
+++ b/arch/arm/mach-msm/clock-local2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -69,8 +69,8 @@
 #define MND_MODE_MASK			BM(13, 12)
 #define MND_DUAL_EDGE_MODE_BVAL		BVAL(13, 12, 0x2)
 #define CMD_RCGR_CONFIG_DIRTY_MASK	BM(7, 4)
-#define CBCR_BRANCH_CDIV_MASK		BM(24, 16)
-#define CBCR_BRANCH_CDIV_MASKED(val)	BVAL(24, 16, (val));
+#define CBCR_CDIV_LSB			16
+#define CBCR_CDIV_MSB			24
 
 enum branch_state {
 	BRANCH_ON,
@@ -235,21 +235,17 @@
 	return (rcg->freq_tbl + n)->freq_hz;
 }
 
-static enum handoff _rcg_clk_handoff(struct rcg_clk *rcg, int has_mnd)
+static struct clk *_rcg_clk_get_parent(struct rcg_clk *rcg, int has_mnd)
 {
 	u32 n_regval = 0, m_regval = 0, d_regval = 0;
 	u32 cfg_regval;
 	struct clk_freq_tbl *freq;
 	u32 cmd_rcgr_regval;
 
-	/* Is the root enabled? */
-	cmd_rcgr_regval = readl_relaxed(CMD_RCGR_REG(rcg));
-	if ((cmd_rcgr_regval & CMD_RCGR_ROOT_STATUS_BIT))
-		return HANDOFF_DISABLED_CLK;
-
 	/* Is there a pending configuration? */
+	cmd_rcgr_regval = readl_relaxed(CMD_RCGR_REG(rcg));
 	if (cmd_rcgr_regval & CMD_RCGR_CONFIG_DIRTY_MASK)
-		return HANDOFF_UNKNOWN_RATE;
+		return NULL;
 
 	/* Get values of m, n, d, div and src_sel registers. */
 	if (has_mnd) {
@@ -299,23 +295,45 @@
 
 	/* No known frequency found */
 	if (freq->freq_hz == FREQ_END)
-		return HANDOFF_UNKNOWN_RATE;
+		return NULL;
 
 	rcg->current_freq = freq;
-	rcg->c.parent = freq->src_clk;
-	rcg->c.rate = freq->freq_hz;
+	return freq->src_clk;
+}
+
+static enum handoff _rcg_clk_handoff(struct rcg_clk *rcg)
+{
+	u32 cmd_rcgr_regval;
+
+	if (rcg->current_freq && rcg->current_freq->freq_hz != FREQ_END)
+		rcg->c.rate = rcg->current_freq->freq_hz;
+
+	/* Is the root enabled? */
+	cmd_rcgr_regval = readl_relaxed(CMD_RCGR_REG(rcg));
+	if ((cmd_rcgr_regval & CMD_RCGR_ROOT_STATUS_BIT))
+		return HANDOFF_DISABLED_CLK;
 
 	return HANDOFF_ENABLED_CLK;
 }
 
+static struct clk *rcg_mnd_clk_get_parent(struct clk *c)
+{
+	return _rcg_clk_get_parent(to_rcg_clk(c), 1);
+}
+
+static struct clk *rcg_clk_get_parent(struct clk *c)
+{
+	return _rcg_clk_get_parent(to_rcg_clk(c), 0);
+}
+
 static enum handoff rcg_mnd_clk_handoff(struct clk *c)
 {
-	return _rcg_clk_handoff(to_rcg_clk(c), 1);
+	return _rcg_clk_handoff(to_rcg_clk(c));
 }
 
 static enum handoff rcg_clk_handoff(struct clk *c)
 {
-	return _rcg_clk_handoff(to_rcg_clk(c), 0);
+	return _rcg_clk_handoff(to_rcg_clk(c));
 }
 
 #define BRANCH_CHECK_MASK	BM(31, 28)
@@ -412,8 +430,8 @@
 
 	spin_lock_irqsave(&local_clock_reg_lock, flags);
 	regval = readl_relaxed(CBCR_REG(branch));
-	regval &= ~CBCR_BRANCH_CDIV_MASK;
-	regval |= CBCR_BRANCH_CDIV_MASKED(rate);
+	regval &= ~BM(CBCR_CDIV_MSB, CBCR_CDIV_LSB);
+	regval |= BVAL(CBCR_CDIV_MSB, CBCR_CDIV_LSB, rate);
 	writel_relaxed(regval, CBCR_REG(branch));
 	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
 
@@ -496,9 +514,12 @@
 	if ((cbcr_regval & CBCR_BRANCH_OFF_BIT))
 		return HANDOFF_DISABLED_CLK;
 
-	if (c->parent) {
-		if (c->parent->ops->handoff)
-			return c->parent->ops->handoff(c->parent);
+	if (branch->max_div) {
+		cbcr_regval &= BM(CBCR_CDIV_MSB, CBCR_CDIV_LSB);
+		cbcr_regval >>= CBCR_CDIV_LSB;
+		c->rate = cbcr_regval;
+	} else if (!branch->has_sibling) {
+		c->rate = clk_get_rate(c->parent);
 	}
 
 	return HANDOFF_ENABLED_CLK;
@@ -611,6 +632,7 @@
 	.list_rate = rcg_clk_list_rate,
 	.round_rate = rcg_clk_round_rate,
 	.handoff = rcg_clk_handoff,
+	.get_parent = rcg_clk_get_parent,
 };
 
 struct clk_ops clk_ops_rcg_mnd = {
@@ -619,6 +641,7 @@
 	.list_rate = rcg_clk_list_rate,
 	.round_rate = rcg_clk_round_rate,
 	.handoff = rcg_mnd_clk_handoff,
+	.get_parent = rcg_mnd_clk_get_parent,
 };
 
 struct clk_ops clk_ops_branch = {
diff --git a/arch/arm/mach-msm/clock-local2.h b/arch/arm/mach-msm/clock-local2.h
index a6d2ed6..2e1b8a9 100644
--- a/arch/arm/mach-msm/clock-local2.h
+++ b/arch/arm/mach-msm/clock-local2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/clock-mdss-8974.c b/arch/arm/mach-msm/clock-mdss-8974.c
index 79bc639..91e96b7 100644
--- a/arch/arm/mach-msm/clock-mdss-8974.c
+++ b/arch/arm/mach-msm/clock-mdss-8974.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -27,6 +27,9 @@
 #define REG_R(addr)		readl_relaxed(addr)
 #define REG_W(data, addr)	writel_relaxed(data, addr)
 
+#define GDSC_PHYS		0xFD8C2304
+#define GDSC_SIZE		0x4
+
 #define DSI_PHY_PHYS		0xFD922800
 #define DSI_PHY_SIZE		0x00000800
 
@@ -99,6 +102,7 @@
 
 #define VCO_CLK				424000000
 static unsigned char *mdss_dsi_base;
+static unsigned char *gdsc_base;
 static int pll_byte_clk_rate;
 static int pll_pclk_rate;
 static int pll_initialized;
@@ -109,20 +113,19 @@
 static void __iomem *hdmi_phy_pll_base;
 static unsigned hdmi_pll_on;
 
-void __init mdss_clk_ctrl_init(void)
+void __init mdss_clk_ctrl_pre_init(struct clk *ahb_clk)
 {
+	BUG_ON(ahb_clk == NULL);
+
+	gdsc_base = ioremap(GDSC_PHYS, GDSC_SIZE);
+	if (!gdsc_base)
+		pr_err("%s: unable to remap gdsc base", __func__);
+
 	mdss_dsi_base = ioremap(DSI_PHY_PHYS, DSI_PHY_SIZE);
 	if (!mdss_dsi_base)
 		pr_err("%s: unable to remap dsi base", __func__);
 
-	mdss_dsi_ahb_clk = clk_get_sys("mdss_dsi_clk_ctrl", "iface_clk");
-	if (!IS_ERR(mdss_dsi_ahb_clk)) {
-		clk_prepare(mdss_dsi_ahb_clk);
-	} else {
-		mdss_dsi_ahb_clk = NULL;
-		pr_err("%s:%d unable to get dsi iface clock\n",
-			       __func__, __LINE__);
-	}
+	mdss_dsi_ahb_clk = ahb_clk;
 
 	hdmi_phy_base = ioremap(HDMI_PHY_PHYS, HDMI_PHY_SIZE);
 	if (!hdmi_phy_base)
@@ -133,6 +136,38 @@
 		pr_err("%s: unable to ioremap hdmi phy pll base", __func__);
 }
 
+#define PLL_POLL_MAX_READS 10
+#define PLL_POLL_TIMEOUT_US 50
+
+static int mdss_gdsc_enabled(void)
+{
+	if (!gdsc_base)
+		return 0;
+
+	return !!(readl_relaxed(gdsc_base) & BIT(31));
+}
+
+static int mdss_dsi_check_pll_lock(void)
+{
+	u32 status;
+
+	clk_prepare_enable(mdss_dsi_ahb_clk);
+	/* poll for PLL ready status */
+	if (readl_poll_timeout_noirq((mdss_dsi_base + 0x02c0),
+				status,
+				((status & BIT(0)) == 1),
+				PLL_POLL_MAX_READS, PLL_POLL_TIMEOUT_US)) {
+		pr_err("%s: DSI PLL status=%x failed to Lock\n",
+				__func__, status);
+		pll_initialized = 0;
+	} else {
+		pll_initialized = 1;
+	}
+	clk_disable_unprepare(mdss_dsi_ahb_clk);
+
+	return pll_initialized;
+}
+
 static long mdss_dsi_pll_byte_round_rate(struct clk *c, unsigned long rate)
 {
 	if (pll_initialized)
@@ -166,7 +201,7 @@
 	}
 }
 
-static int mdss_dsi_pll_byte_set_rate(struct clk *c, unsigned long rate)
+static int __mdss_dsi_pll_byte_set_rate(struct clk *c, unsigned long rate)
 {
 	int pll_divcfg1, pll_divcfg2;
 	int half_bitclk_rate;
@@ -175,14 +210,6 @@
 	if (pll_initialized)
 		return 0;
 
-	if (!mdss_dsi_ahb_clk) {
-		pr_err("%s: mdss_dsi_ahb_clk not initialized\n",
-				__func__);
-		return -EINVAL;
-	}
-
-	clk_enable(mdss_dsi_ahb_clk);
-
 	half_bitclk_rate = rate * 4;
 
 	pll_divcfg1 = (VCO_CLK / half_bitclk_rate) - 2;
@@ -205,19 +232,17 @@
 	REG_W(0x03, mdss_dsi_base + 0x0228); /* postDiv3 */
 
 	REG_W(0x2b, mdss_dsi_base + 0x0278); /* Cal CFG3 */
-	REG_W(0x06, mdss_dsi_base + 0x027c); /* Cal CFG4 */
-	REG_W(0x05, mdss_dsi_base + 0x0264); /* Cal CFG4 */
+	REG_W(0x66, mdss_dsi_base + 0x027c); /* Cal CFG4 */
+	REG_W(0x05, mdss_dsi_base + 0x0264); /* LKDET CFG2 */
 
 	REG_W(0x0a, mdss_dsi_base + 0x023c); /* SDM CFG1 */
 	REG_W(0xab, mdss_dsi_base + 0x0240); /* SDM CFG2 */
 	REG_W(0x0a, mdss_dsi_base + 0x0244); /* SDM CFG3 */
 	REG_W(0x00, mdss_dsi_base + 0x0248); /* SDM CFG4 */
 
-	udelay(10);
-
 	REG_W(0x01, mdss_dsi_base + 0x0200); /* REFCLK CFG */
 	REG_W(0x00, mdss_dsi_base + 0x0214); /* PWRGEN CFG */
-	REG_W(0x01, mdss_dsi_base + 0x020c); /* VCOLPF CFG */
+	REG_W(0x71, mdss_dsi_base + 0x020c); /* VCOLPF CFG */
 	REG_W(0x02, mdss_dsi_base + 0x0210); /* VREG CFG */
 	REG_W(0x00, mdss_dsi_base + 0x0238); /* SDM CFG0 */
 
@@ -235,13 +260,39 @@
 	pll_byte_clk_rate = 53000000;
 	pll_pclk_rate = 105000000;
 
-	clk_disable(mdss_dsi_ahb_clk);
 	pr_debug("%s: **** PLL initialized success\n", __func__);
 	pll_initialized = 1;
 
 	return 0;
 }
 
+static int mdss_dsi_pll_byte_set_rate(struct clk *c, unsigned long rate)
+{
+	int ret;
+
+	clk_prepare_enable(mdss_dsi_ahb_clk);
+	ret = __mdss_dsi_pll_byte_set_rate(c, rate);
+	clk_disable_unprepare(mdss_dsi_ahb_clk);
+
+	return ret;
+}
+
+static void mdss_dsi_uniphy_pll_lock_detect_setting(void)
+{
+	REG_W(0x04, mdss_dsi_base + 0x0264); /* LKDetect CFG2 */
+	udelay(100);
+	REG_W(0x05, mdss_dsi_base + 0x0264); /* LKDetect CFG2 */
+	udelay(500);
+}
+
+static void mdss_dsi_uniphy_pll_sw_reset(void)
+{
+	REG_W(0x01, mdss_dsi_base + 0x0268); /* PLL TEST CFG */
+	udelay(1);
+	REG_W(0x00, mdss_dsi_base + 0x0268); /* PLL TEST CFG */
+	udelay(1);
+}
+
 static int __mdss_dsi_pll_enable(struct clk *c)
 {
 	u32 status;
@@ -250,31 +301,29 @@
 
 	if (!pll_initialized) {
 		if (dsi_pll_rate)
-			mdss_dsi_pll_byte_set_rate(c, dsi_pll_rate);
+			__mdss_dsi_pll_byte_set_rate(c, dsi_pll_rate);
 		else
 			pr_err("%s: Calling clk_en before set_rate\n",
 						__func__);
 	}
 
-	if (!mdss_dsi_ahb_clk) {
-		pr_err("%s: mdss_dsi_ahb_clk not initialized\n",
-				__func__);
-		return -EINVAL;
-	}
-
-	clk_enable(mdss_dsi_ahb_clk);
-
+	mdss_dsi_uniphy_pll_sw_reset();
 	/* PLL power up */
-	for (i = 0; i < 3; i++) {
-		REG_W(0x01, mdss_dsi_base + 0x0220); /* GLB CFG */
-		REG_W(0x05, mdss_dsi_base + 0x0220); /* GLB CFG */
-		udelay(20);
-		REG_W(0x07, mdss_dsi_base + 0x0220); /* GLB CFG */
-		udelay(20);
-		REG_W(0x0f, mdss_dsi_base + 0x0220); /* GLB CFG */
+	/* Add HW recommended delay between
+	   register writes for the update to propagate */
+	REG_W(0x01, mdss_dsi_base + 0x0220); /* GLB CFG */
+	udelay(1000);
+	REG_W(0x05, mdss_dsi_base + 0x0220); /* GLB CFG */
+	udelay(1000);
+	REG_W(0x07, mdss_dsi_base + 0x0220); /* GLB CFG */
+	udelay(1000);
+	REG_W(0x0f, mdss_dsi_base + 0x0220); /* GLB CFG */
+	udelay(1000);
 
+	for (i = 0; i < 3; i++) {
+		mdss_dsi_uniphy_pll_lock_detect_setting();
 		/* poll for PLL ready status */
-		max_reads = 20;
+		max_reads = 5;
 		timeout_us = 100;
 		if (readl_poll_timeout_noirq((mdss_dsi_base + 0x02c0),
 				   status,
@@ -286,30 +335,40 @@
 			       __func__);
 		} else
 			break;
+
+		mdss_dsi_uniphy_pll_sw_reset();
+		udelay(1000);
+		/* Add HW recommended delay between
+		   register writes for the update to propagate */
+		REG_W(0x01, mdss_dsi_base + 0x0220); /* GLB CFG */
+		udelay(1000);
+		REG_W(0x05, mdss_dsi_base + 0x0220); /* GLB CFG */
+		udelay(1000);
+		REG_W(0x07, mdss_dsi_base + 0x0220); /* GLB CFG */
+		udelay(1000);
+		REG_W(0x05, mdss_dsi_base + 0x0220); /* GLB CFG */
+		udelay(1000);
+		REG_W(0x07, mdss_dsi_base + 0x0220); /* GLB CFG */
+		udelay(1000);
+		REG_W(0x0f, mdss_dsi_base + 0x0220); /* GLB CFG */
+		udelay(2000);
+
 	}
 
 	if ((status & 0x01) != 1) {
 		pr_err("%s: DSI PLL status=%x failed to Lock\n",
 		       __func__, status);
-		clk_disable(mdss_dsi_ahb_clk);
 		return -EINVAL;
 	}
 
 	pr_debug("%s: **** PLL Lock success\n", __func__);
-	clk_disable(mdss_dsi_ahb_clk);
 
 	return 0;
 }
 
 static void __mdss_dsi_pll_disable(void)
 {
-	if (!mdss_dsi_ahb_clk)
-		pr_err("%s: mdss_dsi_ahb_clk not initialized\n",
-				__func__);
-
-	clk_enable(mdss_dsi_ahb_clk);
 	writel_relaxed(0x00, mdss_dsi_base + 0x0220); /* GLB CFG */
-	clk_disable(mdss_dsi_ahb_clk);
 	pr_debug("%s: **** disable pll Initialize\n", __func__);
 	pll_initialized = 0;
 }
@@ -348,6 +407,31 @@
 	return ret;
 }
 
+static enum handoff mdss_dsi_pll_byte_handoff(struct clk *c)
+{
+	if (mdss_gdsc_enabled() && mdss_dsi_check_pll_lock()) {
+		c->rate = 53000000;
+		dsi_pll_rate = 53000000;
+		pll_byte_clk_rate = 53000000;
+		pll_pclk_rate = 105000000;
+		dsipll_refcount++;
+		return HANDOFF_ENABLED_CLK;
+	}
+
+	return HANDOFF_DISABLED_CLK;
+}
+
+static enum handoff mdss_dsi_pll_pixel_handoff(struct clk *c)
+{
+	if (mdss_gdsc_enabled() && mdss_dsi_check_pll_lock()) {
+		c->rate = 105000000;
+		dsipll_refcount++;
+		return HANDOFF_ENABLED_CLK;
+	}
+
+	return HANDOFF_DISABLED_CLK;
+}
+
 void hdmi_pll_disable(void)
 {
 	clk_enable(mdss_dsi_ahb_clk);
@@ -766,6 +850,7 @@
 	.disable = mdss_dsi_pll_disable,
 	.set_rate = mdss_dsi_pll_pixel_set_rate,
 	.round_rate = mdss_dsi_pll_pixel_round_rate,
+	.handoff = mdss_dsi_pll_pixel_handoff,
 };
 
 struct clk_ops clk_ops_dsi_byte_pll = {
@@ -773,4 +858,5 @@
 	.disable = mdss_dsi_pll_disable,
 	.set_rate = mdss_dsi_pll_byte_set_rate,
 	.round_rate = mdss_dsi_pll_byte_round_rate,
+	.handoff = mdss_dsi_pll_byte_handoff,
 };
diff --git a/arch/arm/mach-msm/clock-mdss-8974.h b/arch/arm/mach-msm/clock-mdss-8974.h
index 509a220..e242669 100644
--- a/arch/arm/mach-msm/clock-mdss-8974.h
+++ b/arch/arm/mach-msm/clock-mdss-8974.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -16,7 +16,8 @@
 extern struct clk_ops clk_ops_dsi_byte_pll;
 extern struct clk_ops clk_ops_dsi_pixel_pll;
 
-void mdss_clk_ctrl_init(void);
+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);
diff --git a/arch/arm/mach-msm/clock-pcom-lookup.c b/arch/arm/mach-msm/clock-pcom-lookup.c
index 2a2cc01..376af36 100644
--- a/arch/arm/mach-msm/clock-pcom-lookup.c
+++ b/arch/arm/mach-msm/clock-pcom-lookup.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/clock-pcom.c b/arch/arm/mach-msm/clock-pcom.c
index 801b40a..72bb0b4 100644
--- a/arch/arm/mach-msm/clock-pcom.c
+++ b/arch/arm/mach-msm/clock-pcom.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2011, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/clock-pcom.h b/arch/arm/mach-msm/clock-pcom.h
index 82a90ab..dcf5736 100644
--- a/arch/arm/mach-msm/clock-pcom.h
+++ b/arch/arm/mach-msm/clock-pcom.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/clock-pll.c b/arch/arm/mach-msm/clock-pll.c
index cd4ead1..c82058b 100644
--- a/arch/arm/mach-msm/clock-pll.c
+++ b/arch/arm/mach-msm/clock-pll.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/clock-pll.h b/arch/arm/mach-msm/clock-pll.h
index 823103a..c4addb2 100644
--- a/arch/arm/mach-msm/clock-pll.h
+++ b/arch/arm/mach-msm/clock-pll.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/clock-rpm.c b/arch/arm/mach-msm/clock-rpm.c
index a4def28..ee91a34 100644
--- a/arch/arm/mach-msm/clock-rpm.c
+++ b/arch/arm/mach-msm/clock-rpm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -245,6 +245,14 @@
 	return rc;
 }
 
+static int rpm_branch_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	if (rate == clk->rate)
+		return 0;
+
+	return -EPERM;
+}
+
 static unsigned long rpm_clk_get_rate(struct clk *clk)
 {
 	struct rpm_clk *r = to_rpm_clk(clk);
@@ -285,6 +293,18 @@
 	if (rc < 0)
 		return HANDOFF_DISABLED_CLK;
 
+	/*
+	 * Since RPM handoff code may update the software rate of the clock by
+	 * querying the RPM, we need to make sure our request to RPM now
+	 * matches the software rate of the clock. When we send the request
+	 * to RPM, we also need to update any other state info we would
+	 * normally update. So, call the appropriate clock function instead
+	 * of directly using the RPM driver APIs.
+	 */
+	rc = rpm_clk_prepare(clk);
+	if (rc < 0)
+		return HANDOFF_DISABLED_CLK;
+
 	return HANDOFF_ENABLED_CLK;
 }
 
@@ -323,6 +343,7 @@
 struct clk_ops clk_ops_rpm_branch = {
 	.prepare = rpm_clk_prepare,
 	.unprepare = rpm_clk_unprepare,
+	.set_rate = rpm_branch_clk_set_rate,
 	.is_local = rpm_clk_is_local,
 	.handoff = rpm_clk_handoff,
 };
diff --git a/arch/arm/mach-msm/clock-rpm.h b/arch/arm/mach-msm/clock-rpm.h
index 252e8cb..8d328e3 100644
--- a/arch/arm/mach-msm/clock-rpm.h
+++ b/arch/arm/mach-msm/clock-rpm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/clock-voter.c b/arch/arm/mach-msm/clock-voter.c
index 7421ba6..51d895a 100644
--- a/arch/arm/mach-msm/clock-voter.c
+++ b/arch/arm/mach-msm/clock-voter.c
@@ -1,5 +1,4 @@
-/*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
@@ -40,6 +39,9 @@
 	struct clk_voter *clkh, *v = to_clk_voter(clk);
 	unsigned long cur_rate, new_rate, other_rate = 0;
 
+	if (v->is_branch)
+		return 0;
+
 	mutex_lock(&voter_clk_lock);
 
 	if (v->enabled) {
@@ -78,6 +80,9 @@
 	struct clk *parent;
 	struct clk_voter *v = to_clk_voter(clk);
 
+	if (v->is_branch)
+		return 0;
+
 	mutex_lock(&voter_clk_lock);
 	parent = clk->parent;
 
@@ -104,6 +109,9 @@
 	struct clk *parent;
 	struct clk_voter *v = to_clk_voter(clk);
 
+	if (v->is_branch)
+		return;
+
 	mutex_lock(&voter_clk_lock);
 	parent = clk->parent;
 
@@ -139,11 +147,17 @@
 
 static enum handoff voter_clk_handoff(struct clk *clk)
 {
-	/* Apply default rate vote */
-	if (clk->rate)
-		return HANDOFF_ENABLED_CLK;
+	if (!clk->rate)
+		return HANDOFF_DISABLED_CLK;
 
-	return HANDOFF_DISABLED_CLK;
+	/*
+	 * Send the default rate to the parent if necessary and update the
+	 * software state of the voter clock.
+	 */
+	if (voter_clk_prepare(clk) < 0)
+		return HANDOFF_DISABLED_CLK;
+
+	return HANDOFF_ENABLED_CLK;
 }
 
 struct clk_ops clk_ops_voter = {
diff --git a/arch/arm/mach-msm/clock-voter.h b/arch/arm/mach-msm/clock-voter.h
index eb55a12..6d58b3c 100644
--- a/arch/arm/mach-msm/clock-voter.h
+++ b/arch/arm/mach-msm/clock-voter.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
@@ -20,6 +20,7 @@
 extern struct clk_ops clk_ops_voter;
 
 struct clk_voter {
+	int is_branch;
 	bool enabled;
 	struct clk c;
 };
@@ -29,8 +30,9 @@
 	return container_of(clk, struct clk_voter, c);
 }
 
-#define DEFINE_CLK_VOTER(clk_name, _parent, _default_rate) \
+#define __DEFINE_CLK_VOTER(clk_name, _parent, _default_rate, _is_branch) \
 	struct clk_voter clk_name = { \
+		.is_branch = (_is_branch), \
 		.c = { \
 			.parent = _parent, \
 			.dbg_name = #clk_name, \
@@ -40,4 +42,10 @@
 		}, \
 	}
 
+#define DEFINE_CLK_VOTER(clk_name, _parent, _default_rate) \
+	 __DEFINE_CLK_VOTER(clk_name, _parent, _default_rate, 0)
+
+#define DEFINE_CLK_BRANCH_VOTER(clk_name, _parent) \
+	 __DEFINE_CLK_VOTER(clk_name, _parent, 1000, 1)
+
 #endif
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index c2bf5ba..e0ee084 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/clock.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -467,56 +467,83 @@
 }
 EXPORT_SYMBOL(msm_clock_register);
 
-static enum handoff __init __handoff_clk(struct clk *clk)
+static int __init __handoff_clk(struct clk *clk)
 {
-	enum handoff ret;
-	struct handoff_clk *h;
-	unsigned long rate;
-	int err = 0;
+	enum handoff state = HANDOFF_DISABLED_CLK;
+	struct handoff_clk *h = NULL;
+	int rc;
+
+	if (clk == NULL || clk->flags & CLKFLAG_INIT_DONE ||
+	    clk->flags & CLKFLAG_SKIP_HANDOFF)
+		return 0;
+
+	if (clk->flags & CLKFLAG_INIT_ERR)
+		return -ENXIO;
+
+	/* Handoff any 'depends' clock first. */
+	rc = __handoff_clk(clk->depends);
+	if (rc)
+		goto err;
 
 	/*
-	 * Tree roots don't have parents, but need to be handed off. So,
-	 * terminate recursion by returning "enabled". Also return "enabled"
-	 * for clocks with non-zero enable counts since they must have already
-	 * been handed off.
+	 * Handoff functions for the parent must be called before the
+	 * children can be handed off. Without handing off the parents and
+	 * knowing their rate and state (on/off), it's impossible to figure
+	 * out the rate and state of the children.
 	 */
-	if (clk == NULL || clk->count)
-		return HANDOFF_ENABLED_CLK;
+	if (clk->ops->get_parent)
+		clk->parent = clk->ops->get_parent(clk);
 
-	/* Clocks without handoff functions are assumed to be disabled. */
-	if (!clk->ops->handoff || (clk->flags & CLKFLAG_SKIP_HANDOFF))
-		return HANDOFF_DISABLED_CLK;
+	if (IS_ERR(clk->parent)) {
+		rc = PTR_ERR(clk->parent);
+		goto err;
+	}
 
-	/*
-	 * Handoff functions for children must be called before their parents'
-	 * so that the correct parent is available below.
-	 */
-	ret = clk->ops->handoff(clk);
-	if (ret == HANDOFF_ENABLED_CLK) {
-		ret = __handoff_clk(clk->parent);
-		if (ret == HANDOFF_ENABLED_CLK) {
-			h = kmalloc(sizeof(*h), GFP_KERNEL);
-			if (!h) {
-				err = -ENOMEM;
-				goto out;
-			}
-			err = clk_prepare_enable(clk);
-			if (err)
-				goto out;
-			rate = clk_get_rate(clk);
-			if (rate)
-				pr_debug("%s rate=%lu\n", clk->dbg_name, rate);
-			h->clk = clk;
-			list_add_tail(&h->list, &handoff_list);
+	rc = __handoff_clk(clk->parent);
+	if (rc)
+		goto err;
+
+	if (clk->ops->handoff)
+		state = clk->ops->handoff(clk);
+
+	if (state == HANDOFF_ENABLED_CLK) {
+
+		h = kmalloc(sizeof(*h), GFP_KERNEL);
+		if (!h) {
+			rc = -ENOMEM;
+			goto err;
 		}
+
+		rc = clk_prepare_enable(clk->parent);
+		if (rc)
+			goto err;
+
+		rc = clk_prepare_enable(clk->depends);
+		if (rc)
+			goto err_depends;
+
+		rc = vote_rate_vdd(clk, clk->rate);
+		WARN(rc, "%s unable to vote for voltage!\n", clk->dbg_name);
+
+		clk->count = 1;
+		clk->prepare_count = 1;
+		h->clk = clk;
+		list_add_tail(&h->list, &handoff_list);
+
+		pr_debug("Handed off %s rate=%lu\n", clk->dbg_name, clk->rate);
 	}
-out:
-	if (err) {
-		pr_err("%s handoff failed (%d)\n", clk->dbg_name, err);
-		kfree(h);
-		ret = HANDOFF_DISABLED_CLK;
-	}
-	return ret;
+
+	clk->flags |= CLKFLAG_INIT_DONE;
+
+	return 0;
+
+err_depends:
+	clk_disable_unprepare(clk->parent);
+err:
+	kfree(h);
+	clk->flags |= CLKFLAG_INIT_ERR;
+	pr_err("%s handoff failed (%d)\n", clk->dbg_name, rc);
+	return rc;
 }
 
 /**
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h
index 181cf4c..9ca1965 100644
--- a/arch/arm/mach-msm/clock.h
+++ b/arch/arm/mach-msm/clock.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -49,8 +49,10 @@
 extern struct clock_init_data msm8930_pm8917_clock_init_data;
 extern struct clock_init_data msm8974_clock_init_data;
 extern struct clock_init_data msm8974_rumi_clock_init_data;
-extern struct clock_init_data msm8910_clock_init_data;
-extern struct clock_init_data msm8910_rumi_clock_init_data;
+extern struct clock_init_data msm8610_clock_init_data;
+extern struct clock_init_data msm8610_rumi_clock_init_data;
+extern struct clock_init_data msm8226_clock_init_data;
+extern struct clock_init_data msm8226_rumi_clock_init_data;
 
 int msm_clock_init(struct clock_init_data *data);
 int find_vdd_level(struct clk *clk, unsigned long rate);
diff --git a/arch/arm/mach-msm/cpufreq.c b/arch/arm/mach-msm/cpufreq.c
index d862d6d..46af77d 100644
--- a/arch/arm/mach-msm/cpufreq.c
+++ b/arch/arm/mach-msm/cpufreq.c
@@ -3,7 +3,7 @@
  * MSM architecture cpufreq driver
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
  * Author: Mike A. Chan <mikechan@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -223,11 +223,12 @@
 	if (table == NULL)
 		return -ENODEV;
 	/*
-	 * In 8625 both cpu core's frequency can not
+	 * In 8625, 8610, and 8226 both cpu core's frequency can not
 	 * be changed independently. Each cpu is bound to
 	 * same frequency. Hence set the cpumask to all cpu.
 	 */
-	if (cpu_is_msm8625() || cpu_is_msm8625q())
+	if (cpu_is_msm8625() || cpu_is_msm8625q() || cpu_is_msm8226()
+		|| cpu_is_msm8610())
 		cpumask_setall(policy->cpus);
 
 	if (cpufreq_frequency_table_cpuinfo(policy, table)) {
@@ -299,20 +300,24 @@
 	.notifier_call = msm_cpufreq_cpu_callback,
 };
 
-static int msm_cpufreq_suspend(void)
+/*
+ * Define suspend/resume for cpufreq_driver. Kernel will call
+ * these during suspend/resume with interrupts disabled. This
+ * helps the suspend/resume variable get's updated before cpufreq
+ * governor tries to change the frequency after coming out of suspend.
+ */
+static int msm_cpufreq_suspend(struct cpufreq_policy *policy)
 {
 	int cpu;
 
 	for_each_possible_cpu(cpu) {
-		mutex_lock(&per_cpu(cpufreq_suspend, cpu).suspend_mutex);
 		per_cpu(cpufreq_suspend, cpu).device_suspended = 1;
-		mutex_unlock(&per_cpu(cpufreq_suspend, cpu).suspend_mutex);
 	}
 
-	return NOTIFY_DONE;
+	return 0;
 }
 
-static int msm_cpufreq_resume(void)
+static int msm_cpufreq_resume(struct cpufreq_policy *policy)
 {
 	int cpu;
 
@@ -320,28 +325,9 @@
 		per_cpu(cpufreq_suspend, cpu).device_suspended = 0;
 	}
 
-	return NOTIFY_DONE;
+	return 0;
 }
 
-static int msm_cpufreq_pm_event(struct notifier_block *this,
-				unsigned long event, void *ptr)
-{
-	switch (event) {
-	case PM_POST_HIBERNATION:
-	case PM_POST_SUSPEND:
-		return msm_cpufreq_resume();
-	case PM_HIBERNATION_PREPARE:
-	case PM_SUSPEND_PREPARE:
-		return msm_cpufreq_suspend();
-	default:
-		return NOTIFY_DONE;
-	}
-}
-
-static struct notifier_block msm_cpufreq_pm_notifier = {
-	.notifier_call = msm_cpufreq_pm_event,
-};
-
 static struct freq_attr *msm_freq_attr[] = {
 	&cpufreq_freq_attr_scaling_available_freqs,
 	NULL,
@@ -354,6 +340,8 @@
 	.verify		= msm_cpufreq_verify,
 	.target		= msm_cpufreq_target,
 	.get		= msm_cpufreq_get_freq,
+	.suspend	= msm_cpufreq_suspend,
+	.resume		= msm_cpufreq_resume,
 	.name		= "msm",
 	.attr		= msm_freq_attr,
 };
@@ -369,7 +357,6 @@
 
 	register_hotcpu_notifier(&msm_cpufreq_cpu_notifier);
 
-	register_pm_notifier(&msm_cpufreq_pm_notifier);
 	return cpufreq_register_driver(&msm_cpufreq_driver);
 }
 
diff --git a/arch/arm/mach-msm/cpuidle.c b/arch/arm/mach-msm/cpuidle.c
index dd2dc1d..e87c7b5 100644
--- a/arch/arm/mach-msm/cpuidle.c
+++ b/arch/arm/mach-msm/cpuidle.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -72,35 +72,31 @@
 	struct cpuidle_device *dev, struct cpuidle_driver *drv, int index)
 {
 	int ret = 0;
-	int i = 0;
+	int i;
 	enum msm_pm_sleep_mode pm_mode;
-	struct cpuidle_state_usage *st_usage = NULL;
 
-#ifdef CONFIG_CPU_PM
 	cpu_pm_enter();
-#endif
 
-	pm_mode = msm_pm_idle_prepare(dev, drv, index);
-	dev->last_residency = msm_pm_idle_enter(pm_mode);
+	pm_mode = msm_pm_idle_enter(dev, drv, index);
+
 	for (i = 0; i < dev->state_count; i++) {
-		st_usage = &dev->states_usage[i];
-		if ((enum msm_pm_sleep_mode) cpuidle_get_statedata(st_usage)
-		    == pm_mode) {
+		struct cpuidle_state_usage *st_usage = &dev->states_usage[i];
+		enum msm_pm_sleep_mode last_mode =
+			(enum msm_pm_sleep_mode)cpuidle_get_statedata(st_usage);
+
+		if (last_mode == pm_mode) {
 			ret = i;
 			break;
 		}
 	}
 
-#ifdef CONFIG_CPU_PM
 	cpu_pm_exit();
-#endif
-
 	local_irq_enable();
 
 	return ret;
 }
 
-static void __init msm_cpuidle_set_states(void)
+static void __devinit msm_cpuidle_set_states(void)
 {
 	int i = 0;
 	int state_count = 0;
@@ -156,7 +152,7 @@
 	dev->state_count = state_count; /* Per cpu state count */
 }
 
-int __init msm_cpuidle_init(void)
+int __devinit msm_cpuidle_init(void)
 {
 	unsigned int cpu = 0;
 	int ret = 0;
diff --git a/arch/arm/mach-msm/dal.c b/arch/arm/mach-msm/dal.c
index 94c02f0..74dfe37 100644
--- a/arch/arm/mach-msm/dal.c
+++ b/arch/arm/mach-msm/dal.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/arch/arm/mach-msm/dal_axi.c b/arch/arm/mach-msm/dal_axi.c
index 1d873ca..7ef154d 100644
--- a/arch/arm/mach-msm/dal_axi.c
+++ b/arch/arm/mach-msm/dal_axi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/dal_remotetest.c b/arch/arm/mach-msm/dal_remotetest.c
index d7a3f34..b6fc8da 100644
--- a/arch/arm/mach-msm/dal_remotetest.c
+++ b/arch/arm/mach-msm/dal_remotetest.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/arch/arm/mach-msm/dal_remotetest.h b/arch/arm/mach-msm/dal_remotetest.h
index cb998c9..4fe4079 100644
--- a/arch/arm/mach-msm/dal_remotetest.h
+++ b/arch/arm/mach-msm/dal_remotetest.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index dcd90d0..b7707d7 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -20,11 +20,11 @@
 #include <linux/dma-mapping.h>
 #include <linux/coresight.h>
 #include <linux/avtimer.h>
-#include <linux/ahci_platform.h>
 #include <mach/irqs-8064.h>
 #include <mach/board.h>
 #include <mach/msm_iomap.h>
 #include <mach/usbdiag.h>
+#include <mach/msm_serial_hs_lite.h>
 #include <mach/msm_sps.h>
 #include <mach/dma.h>
 #include <mach/msm_dsps.h>
@@ -41,6 +41,7 @@
 #include <mach/msm_rtb.h>
 #include <linux/msm_ion.h>
 #include "clock.h"
+#include "pm.h"
 #include "devices.h"
 #include "footswitch.h"
 #include "msm_watchdog.h"
@@ -49,9 +50,11 @@
 #include <mach/mpm.h>
 #include <mach/iommu_domains.h>
 #include <mach/msm_cache_dump.h>
+#include "pm.h"
 
 /* Address of GSBI blocks */
 #define MSM_GSBI1_PHYS		0x12440000
+#define MSM_GSBI2_PHYS		0x12480000
 #define MSM_GSBI3_PHYS		0x16200000
 #define MSM_GSBI4_PHYS		0x16300000
 #define MSM_GSBI5_PHYS		0x1A200000
@@ -60,7 +63,9 @@
 
 /* GSBI UART devices */
 #define MSM_UART1DM_PHYS	(MSM_GSBI1_PHYS + 0x10000)
+#define MSM_UART2DM_PHYS	(MSM_GSBI2_PHYS + 0x10000)
 #define MSM_UART3DM_PHYS	(MSM_GSBI3_PHYS + 0x40000)
+#define MSM_UART4DM_PHYS	(MSM_GSBI4_PHYS + 0x40000)
 #define MSM_UART5DM_PHYS	(MSM_GSBI5_PHYS + 0x40000)
 #define MSM_UART6DM_PHYS	(MSM_GSBI6_PHYS + 0x40000)
 #define MSM_UART7DM_PHYS	(MSM_GSBI7_PHYS + 0x40000)
@@ -117,11 +122,37 @@
 	},
 };
 
-struct platform_device msm8064_pc_cntr = {
-	.name		= "pc-cntr",
+static uint32_t msm_pm_cp15_regs[] = {0x4501, 0x5501, 0x6501, 0x7501, 0x0500};
+
+static struct msm_pm_init_data_type msm_pm_data = {
+	.retention_calls_tz = true,
+	.cp15_data.save_cp15 = true,
+	.cp15_data.qsb_pc_vdd = 0x98,
+	.cp15_data.reg_data = &msm_pm_cp15_regs[0],
+	.cp15_data.reg_saved_state_size = ARRAY_SIZE(msm_pm_cp15_regs),
+};
+
+struct platform_device msm8064_pm_8x60 = {
+	.name		= "pm-8x60",
 	.id		= -1,
 	.num_resources	= ARRAY_SIZE(msm8064_resources_pccntr),
 	.resource	= msm8064_resources_pccntr,
+	.dev = {
+		.platform_data = &msm_pm_data,
+	},
+};
+
+static struct msm_pm_sleep_status_data msm_pm_slp_sts_data = {
+	.base_addr = MSM_ACC0_BASE + 0x08,
+	.cpu_offset = MSM_ACC1_BASE - MSM_ACC0_BASE,
+	.mask = 1UL << 13,
+};
+struct platform_device msm8064_cpu_slp_status = {
+	.name		= "cpu_slp_status",
+	.id		= -1,
+	.dev = {
+		.platform_data = &msm_pm_slp_sts_data,
+	},
 };
 
 static struct msm_watchdog_pdata msm_watchdog_pdata = {
@@ -204,6 +235,38 @@
 	.resource	= resources_uart_gsbi1,
 };
 
+static struct resource resources_uart_gsbi2[] = {
+	{
+		.start	= APQ8064_GSBI2_UARTDM_IRQ,
+		.end	= APQ8064_GSBI2_UARTDM_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= MSM_UART2DM_PHYS,
+		.end	= MSM_UART2DM_PHYS + PAGE_SIZE - 1,
+		.name	= "uartdm_resource",
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= MSM_GSBI2_PHYS,
+		.end	= MSM_GSBI2_PHYS + PAGE_SIZE - 1,
+		.name	= "gsbi_resource",
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct msm_serial_hslite_platform_data uart_gsbi2_pdata = {
+	.line		= 0,
+};
+
+struct platform_device apq8064_device_uart_gsbi2 = {
+	.name	= "msm_serial_hsl",
+	.id	= 3,
+	.num_resources	= ARRAY_SIZE(resources_uart_gsbi2),
+	.resource	= resources_uart_gsbi2,
+	.dev.platform_data = &uart_gsbi2_pdata,
+};
+
 static struct resource resources_uart_gsbi3[] = {
 	{
 		.start	= GSBI3_UARTDM_IRQ,
@@ -351,6 +414,38 @@
 	.resource	= resources_qup_i2c_gsbi4,
 };
 
+static struct resource resources_uart_gsbi4[] = {
+	{
+		.start	= GSBI4_UARTDM_IRQ,
+		.end	= GSBI4_UARTDM_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= MSM_UART4DM_PHYS,
+		.end	= MSM_UART4DM_PHYS + PAGE_SIZE - 1,
+		.name	= "uartdm_resource",
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= MSM_GSBI4_PHYS,
+		.end	= MSM_GSBI4_PHYS + PAGE_SIZE - 1,
+		.name	= "gsbi_resource",
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct msm_serial_hslite_platform_data uart_gsbi4_pdata = {
+	.line		= 2,
+};
+
+struct platform_device apq8064_device_uart_gsbi4 = {
+	.name	= "msm_serial_hsl",
+	.id	= 4,
+	.num_resources	= ARRAY_SIZE(resources_uart_gsbi4),
+	.resource	= resources_uart_gsbi4,
+	.dev.platform_data = &uart_gsbi4_pdata,
+};
+
 static struct resource resources_qup_spi_gsbi5[] = {
 	{
 		.name   = "spi_base",
@@ -755,26 +850,49 @@
 
 static struct resource tspp_resources[] = {
 	[0] = {
+		.name = "TSIF_TSPP_IRQ",
 		.flags = IORESOURCE_IRQ,
 		.start = TSIF_TSPP_IRQ,
-		.end   = TSIF1_IRQ,
+		.end   = TSIF_TSPP_IRQ,
 	},
 	[1] = {
+		.name = "TSIF0_IRQ",
+		.flags = IORESOURCE_IRQ,
+		.start = TSIF1_IRQ,
+		.end   = TSIF1_IRQ,
+	},
+	[2] = {
+		.name = "TSIF1_IRQ",
+		.flags = IORESOURCE_IRQ,
+		.start = TSIF2_IRQ,
+		.end   = TSIF2_IRQ,
+	},
+	[3] = {
+		.name = "TSIF_BAM_IRQ",
+		.flags = IORESOURCE_IRQ,
+		.start = TSIF_BAM_IRQ,
+		.end   = TSIF_BAM_IRQ,
+	},
+	[4] = {
+		.name = "MSM_TSIF0_PHYS",
 		.flags = IORESOURCE_MEM,
 		.start = MSM_TSIF0_PHYS,
 		.end   = MSM_TSIF0_PHYS + MSM_TSIF_SIZE - 1,
 	},
-	[2] = {
+	[5] = {
+		.name = "MSM_TSIF1_PHYS",
 		.flags = IORESOURCE_MEM,
 		.start = MSM_TSIF1_PHYS,
 		.end   = MSM_TSIF1_PHYS + MSM_TSIF_SIZE - 1,
 	},
-	[3] = {
+	[6] = {
+		.name = "MSM_TSPP_PHYS",
 		.flags = IORESOURCE_MEM,
 		.start = MSM_TSPP_PHYS,
 		.end   = MSM_TSPP_PHYS + MSM_TSPP_SIZE - 1,
 	},
-	[4] = {
+	[7] = {
+		.name = "MSM_TSPP_BAM_PHYS",
 		.flags = IORESOURCE_MEM,
 		.start = MSM_TSPP_BAM_PHYS,
 		.end   = MSM_TSPP_BAM_PHYS + MSM_TSPP_BAM_SIZE - 1,
@@ -1779,9 +1897,11 @@
 }
 
 #define MSM_SATA_AHCI_BASE	0x29000000
-#define MSM_SATA_AHCI_REGS_SZ	0x17C
+#define MSM_SATA_AHCI_REGS_SZ	0x180
+#define MSM_SATA_PHY_BASE	0x1B400000
+#define MSM_SATA_PHY_REGS_SZ	0x200
 
-static struct resource resources_ahci[] = {
+static struct resource resources_sata[] = {
 	{
 		.name	= "ahci_mem",
 		.flags	= IORESOURCE_MEM,
@@ -1794,31 +1914,25 @@
 		.start	= SATA_CONTROLLER_IRQ,
 		.end	= SATA_CONTROLLER_IRQ,
 	},
-};
-
-static u64 ahci_dma_mask = DMA_BIT_MASK(32);
-static struct platform_device apq8064_device_ahci = {
-	.name		= "ahci",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(resources_ahci),
-	.resource	= resources_ahci,
-	.dev		= {
-		.dma_mask		= &ahci_dma_mask,
-		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	{
+		.name	= "phy_mem",
+		.flags	= IORESOURCE_MEM,
+		.start	= MSM_SATA_PHY_BASE,
+		.end	= MSM_SATA_PHY_BASE + MSM_SATA_PHY_REGS_SZ - 1,
 	},
 };
 
-int __init apq8064_add_ahci(struct ahci_platform_data *platd)
-{
-	struct platform_device	*pdev;
-
-	if (!platd)
-		return -EINVAL;
-
-	pdev = &apq8064_device_ahci;
-	pdev->dev.platform_data = platd;
-	return platform_device_register(pdev);
-}
+static u64 sata_dma_mask = DMA_BIT_MASK(32);
+struct platform_device apq8064_device_sata = {
+	.name		= "msm_sata",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(resources_sata),
+	.resource	= resources_sata,
+	.dev		= {
+		.dma_mask		= &sata_dma_mask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+};
 
 static struct resource resources_sps[] = {
 	{
diff --git a/arch/arm/mach-msm/devices-8930.c b/arch/arm/mach-msm/devices-8930.c
index aad512e..2f8f547 100644
--- a/arch/arm/mach-msm/devices-8930.c
+++ b/arch/arm/mach-msm/devices-8930.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
@@ -32,6 +32,7 @@
 #include "rpm_rbcpr_stats.h"
 #include "footswitch.h"
 #include "acpuclock-krait.h"
+#include "pm.h"
 
 #ifdef CONFIG_MSM_MPM
 #include <mach/mpm.h>
@@ -48,11 +49,32 @@
 	},
 };
 
-struct platform_device msm8930_pc_cntr = {
-	.name		= "pc-cntr",
+static struct msm_pm_init_data_type msm_pm_data = {
+	.retention_calls_tz = true,
+};
+
+static struct msm_pm_sleep_status_data msm_pm_slp_sts_data = {
+	.base_addr = MSM_ACC0_BASE + 0x08,
+	.cpu_offset = MSM_ACC1_BASE - MSM_ACC0_BASE,
+	.mask = 1UL << 13,
+};
+
+struct platform_device msm8930_cpu_slp_status = {
+	.name		= "cpu_slp_status",
+	.id		= -1,
+	.dev = {
+		.platform_data = &msm_pm_slp_sts_data,
+	},
+};
+
+struct platform_device msm8930_pm_8x60 = {
+	.name		= "pm-8x60",
 	.id		= -1,
 	.num_resources	= ARRAY_SIZE(msm8930_resources_pccntr),
 	.resource	= msm8930_resources_pccntr,
+	.dev = {
+		.platform_data = &msm_pm_data,
+	},
 };
 
 struct msm_rpm_platform_data msm8930_rpm_data __initdata = {
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index 4780c57..2bd9dfe 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -19,6 +19,7 @@
 #include <linux/gpio.h>
 #include <linux/coresight.h>
 #include <asm/clkdev.h>
+#include <mach/gpio.h>
 #include <mach/kgsl.h>
 #include <linux/android_pmem.h>
 #include <mach/irqs-8960.h>
@@ -52,6 +53,7 @@
 #include <mach/msm_dcvs.h>
 #include <mach/iommu_domains.h>
 #include <mach/socinfo.h>
+#include "pm.h"
 
 #ifdef CONFIG_MSM_MPM
 #include <mach/mpm.h>
@@ -115,11 +117,18 @@
 	},
 };
 
-struct platform_device msm8960_pc_cntr = {
-	.name		= "pc-cntr",
+static struct msm_pm_init_data_type msm_pm_data = {
+	.retention_calls_tz = true,
+};
+
+struct platform_device msm8960_pm_8x60 = {
+	.name		= "pm-8x60",
 	.id		= -1,
 	.num_resources	= ARRAY_SIZE(msm8960_resources_pccntr),
 	.resource	= msm8960_resources_pccntr,
+	.dev = {
+		.platform_data = &msm_pm_data,
+	},
 };
 
 static struct resource resources_otg[] = {
@@ -1066,6 +1075,36 @@
 	},
 };
 
+int64_t vidc_v4l2_ns_iommu_mapping[] = {-1, -1};
+int64_t vidc_v4l2_cp_iommu_mapping[] = {-1, -1};
+int64_t *vidc_v4l2_iommu_mappings[] = {
+	[MSM_VIDC_V4L2_IOMMU_MAP_NS] = vidc_v4l2_ns_iommu_mapping,
+	[MSM_VIDC_V4L2_IOMMU_MAP_CP] = vidc_v4l2_cp_iommu_mapping,
+};
+
+int64_t vidc_v4l2_load_1[] = {-1, -1};
+int64_t vidc_v4l2_load_2[] = {-1, -1};
+int64_t *vidc_v4l2_load_table[] = {
+	vidc_v4l2_load_1,
+	vidc_v4l2_load_2,
+};
+
+static struct msm_vidc_v4l2_platform_data vidc_v4l2_plaform_data = {
+	.iommu_table = vidc_v4l2_iommu_mappings,
+	.num_iommu_table = 2,
+	.load_table = vidc_v4l2_load_table,
+	.num_load_table = 2,
+};
+
+struct platform_device msm_device_vidc_v4l2 = {
+	.name = "msm_vidc_v4l2",
+	.id = 0,
+	.num_resources = 0,
+	.dev = {
+		.platform_data = &vidc_v4l2_plaform_data,
+	},
+};
+
 struct msm_vidc_platform_data vidc_platform_data = {
 #ifdef CONFIG_MSM_BUS_SCALING
 	.vidc_bus_client_pdata = &vidc_bus_client_data,
@@ -1664,6 +1703,19 @@
 	.id		= -1,
 };
 
+static struct msm_pm_sleep_status_data msm_pm_slp_sts_data = {
+	.base_addr = MSM_ACC0_BASE + 0x08,
+	.cpu_offset = MSM_ACC1_BASE - MSM_ACC0_BASE,
+	.mask = 1UL << 13,
+};
+struct platform_device msm8960_cpu_slp_status = {
+	.name		= "cpu_slp_status",
+	.id		= -1,
+	.dev = {
+		.platform_data = &msm_pm_slp_sts_data,
+	},
+};
+
 static struct msm_watchdog_pdata msm_watchdog_pdata = {
 	.pet_time = 10000,
 	.bark_time = 11000,
@@ -3131,6 +3183,81 @@
 	},
 };
 
+struct msm_bus_vectors grp3d_init_vectors_1[] = {
+	{
+		.src = MSM_BUS_MASTER_GRAPHICS_3D,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_GRAPHICS_3D_PORT1,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = 0,
+	},
+};
+
+struct msm_bus_vectors grp3d_low_vectors_1[] = {
+	{
+		.src = MSM_BUS_MASTER_GRAPHICS_3D,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = KGSL_CONVERT_TO_MBPS(1000),
+	},
+	{
+		.src = MSM_BUS_MASTER_GRAPHICS_3D_PORT1,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = KGSL_CONVERT_TO_MBPS(1000),
+	},
+};
+
+struct msm_bus_vectors grp3d_nominal_low_vectors_1[] = {
+	{
+		.src = MSM_BUS_MASTER_GRAPHICS_3D,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = KGSL_CONVERT_TO_MBPS(2048),
+	},
+	{
+		.src = MSM_BUS_MASTER_GRAPHICS_3D_PORT1,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = KGSL_CONVERT_TO_MBPS(2048),
+	},
+};
+
+struct msm_bus_vectors grp3d_nominal_high_vectors_1[] = {
+	{
+		.src = MSM_BUS_MASTER_GRAPHICS_3D,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = KGSL_CONVERT_TO_MBPS(2656),
+	},
+	{
+		.src = MSM_BUS_MASTER_GRAPHICS_3D_PORT1,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = KGSL_CONVERT_TO_MBPS(2656),
+	},
+};
+
+struct msm_bus_vectors grp3d_max_vectors_1[] = {
+	{
+		.src = MSM_BUS_MASTER_GRAPHICS_3D,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = KGSL_CONVERT_TO_MBPS(3968),
+	},
+	{
+		.src = MSM_BUS_MASTER_GRAPHICS_3D_PORT1,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = KGSL_CONVERT_TO_MBPS(3968),
+	},
+};
+
 static struct msm_bus_paths grp3d_bus_scale_usecases[] = {
 	{
 		ARRAY_SIZE(grp3d_init_vectors),
@@ -3154,12 +3281,41 @@
 	},
 };
 
+struct msm_bus_paths grp3d_bus_scale_usecases_1[] = {
+	{
+		ARRAY_SIZE(grp3d_init_vectors_1),
+		grp3d_init_vectors_1,
+	},
+	{
+		ARRAY_SIZE(grp3d_low_vectors_1),
+		grp3d_low_vectors_1,
+	},
+	{
+		ARRAY_SIZE(grp3d_nominal_low_vectors_1),
+		grp3d_nominal_low_vectors_1,
+	},
+	{
+		ARRAY_SIZE(grp3d_nominal_high_vectors_1),
+		grp3d_nominal_high_vectors_1,
+	},
+	{
+		ARRAY_SIZE(grp3d_max_vectors_1),
+		grp3d_max_vectors_1,
+	},
+};
+
 static struct msm_bus_scale_pdata grp3d_bus_scale_pdata = {
 	grp3d_bus_scale_usecases,
 	ARRAY_SIZE(grp3d_bus_scale_usecases),
 	.name = "grp3d",
 };
 
+struct msm_bus_scale_pdata grp3d_bus_scale_pdata_ab = {
+	grp3d_bus_scale_usecases_1,
+	ARRAY_SIZE(grp3d_bus_scale_usecases_1),
+	.name = "grp3d",
+};
+
 static struct msm_bus_vectors grp2d0_init_vectors[] = {
 	{
 		.src = MSM_BUS_MASTER_GRAPHICS_2D_CORE0,
@@ -4438,11 +4594,17 @@
 	},
 };
 
+static struct msm_gpio_pdata msm8960_gpio_pdata = {
+	.ngpio = 152,
+	.direct_connect_irqs = 8,
+};
+
 struct platform_device msm_gpio_device = {
-	.name = "msmgpio",
-	.id = -1,
-	.num_resources	= ARRAY_SIZE(msm_gpio_resources),
-	.resource	= msm_gpio_resources,
+	.name			= "msmgpio",
+	.id			= -1,
+	.num_resources		= ARRAY_SIZE(msm_gpio_resources),
+	.resource		= msm_gpio_resources,
+	.dev.platform_data	= &msm8960_gpio_pdata,
 };
 
 struct platform_device mdm_sglte_device = {
@@ -4453,7 +4615,8 @@
 };
 
 struct platform_device *msm8960_vidc_device[] __initdata = {
-	&msm_device_vidc
+	&msm_device_vidc,
+	&msm_device_vidc_v4l2,
 };
 
 void __init msm8960_add_vidc_device(void)
diff --git a/arch/arm/mach-msm/devices-9615.c b/arch/arm/mach-msm/devices-9615.c
index fc65cb7..bf89321 100644
--- a/arch/arm/mach-msm/devices-9615.c
+++ b/arch/arm/mach-msm/devices-9615.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -11,6 +11,7 @@
  *
  */
 
+#include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/irq.h>
@@ -34,6 +35,7 @@
 #include <mach/dma.h>
 #include "pm.h"
 #include "devices.h"
+#include <mach/gpio.h>
 #include <mach/mpm.h>
 #include "spm.h"
 #include "rpm_resources.h"
@@ -607,7 +609,10 @@
 	.name	= "msm-pcm-dtmf",
 	.id	= -1,
 };
-
+struct platform_device msm_host_pcm_voice = {
+	.name	= "msm-host-pcm-voice",
+	.id	= -1,
+};
 struct platform_device msm_compr_dsp = {
 	.name	= "msm-compr-dsp",
 	.id	= -1,
@@ -1514,11 +1519,17 @@
 	},
 };
 
+static struct msm_gpio_pdata msm9615_gpio_pdata = {
+	.ngpio = 88,
+	.direct_connect_irqs = 8,
+};
+
 struct platform_device msm_gpio_device = {
-	.name = "msmgpio",
-	.id = -1,
-	.num_resources	= ARRAY_SIZE(msm_gpio_resources),
-	.resource	= msm_gpio_resources,
+	.name			= "msmgpio",
+	.id			= -1,
+	.num_resources		= ARRAY_SIZE(msm_gpio_resources),
+	.resource		= msm_gpio_resources,
+	.dev.platform_data	= &msm9615_gpio_pdata,
 };
 
 void __init msm9615_device_init(void)
diff --git a/arch/arm/mach-msm/devices-fsm9xxx.c b/arch/arm/mach-msm/devices-fsm9xxx.c
index 9043223..f30abe8 100644
--- a/arch/arm/mach-msm/devices-fsm9xxx.c
+++ b/arch/arm/mach-msm/devices-fsm9xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/devices-iommu.c b/arch/arm/mach-msm/devices-iommu.c
index 983b13e..b91e7fe 100644
--- a/arch/arm/mach-msm/devices-iommu.c
+++ b/arch/arm/mach-msm/devices-iommu.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+/* 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
@@ -387,7 +387,7 @@
 };
 
 static struct platform_device msm_device_iommu_jpegd = {
-	.name = "msm_iommu",
+	.name = "msm_iommu-v0",
 	.id = 0,
 	.dev = {
 		.platform_data = &jpegd_iommu,
@@ -397,7 +397,7 @@
 };
 
 static struct platform_device msm_device_iommu_vpe = {
-	.name = "msm_iommu",
+	.name = "msm_iommu-v0",
 	.id = 1,
 	.dev = {
 		.platform_data = &vpe_iommu,
@@ -407,7 +407,7 @@
 };
 
 static struct platform_device msm_device_iommu_mdp0 = {
-	.name = "msm_iommu",
+	.name = "msm_iommu-v0",
 	.id = 2,
 	.dev = {
 		.platform_data = &mdp0_iommu,
@@ -417,7 +417,7 @@
 };
 
 static struct platform_device msm_device_iommu_mdp1 = {
-	.name = "msm_iommu",
+	.name = "msm_iommu-v0",
 	.id = 3,
 	.dev = {
 		.platform_data = &mdp1_iommu,
@@ -427,7 +427,7 @@
 };
 
 static struct platform_device msm_device_iommu_rot = {
-	.name = "msm_iommu",
+	.name = "msm_iommu-v0",
 	.id = 4,
 	.dev = {
 		.platform_data = &rot_iommu,
@@ -437,7 +437,7 @@
 };
 
 static struct platform_device msm_device_iommu_ijpeg = {
-	.name = "msm_iommu",
+	.name = "msm_iommu-v0",
 	.id = 5,
 	.dev = {
 		.platform_data = &ijpeg_iommu,
@@ -447,7 +447,7 @@
 };
 
 static struct platform_device msm_device_iommu_vfe = {
-	.name = "msm_iommu",
+	.name = "msm_iommu-v0",
 	.id = 6,
 	.dev = {
 		.platform_data = &vfe_iommu,
@@ -457,7 +457,7 @@
 };
 
 static struct platform_device msm_device_iommu_vcodec_a = {
-	.name = "msm_iommu",
+	.name = "msm_iommu-v0",
 	.id = 7,
 	.dev = {
 		.platform_data = &vcodec_a_iommu,
@@ -467,7 +467,7 @@
 };
 
 static struct platform_device msm_device_iommu_vcodec_b = {
-	.name = "msm_iommu",
+	.name = "msm_iommu-v0",
 	.id = 8,
 	.dev = {
 		.platform_data = &vcodec_b_iommu,
@@ -477,7 +477,7 @@
 };
 
 static struct platform_device msm_device_iommu_gfx3d = {
-	.name = "msm_iommu",
+	.name = "msm_iommu-v0",
 	.id = 9,
 	.dev = {
 		.platform_data = &gfx3d_iommu,
@@ -487,7 +487,7 @@
 };
 
 static struct platform_device msm_device_iommu_gfx3d1 = {
-	.name = "msm_iommu",
+	.name = "msm_iommu-v0",
 	.id = 10,
 	.dev = {
 		.platform_data = &gfx3d1_iommu,
@@ -497,7 +497,7 @@
 };
 
 static struct platform_device msm_device_iommu_gfx2d0 = {
-	.name = "msm_iommu",
+	.name = "msm_iommu-v0",
 	.id = 10,
 	.dev = {
 		.platform_data = &gfx2d0_iommu,
@@ -507,7 +507,7 @@
 };
 
 static struct platform_device msm_device_iommu_gfx2d1 = {
-	.name = "msm_iommu",
+	.name = "msm_iommu-v0",
 	.id = 11,
 	.dev = {
 		.platform_data = &gfx2d1_iommu,
@@ -517,7 +517,7 @@
 };
 
 static struct platform_device msm_device_iommu_vcap = {
-	.name = "msm_iommu",
+	.name = "msm_iommu-v0",
 	.id = 11,
 	.dev = {
 		.platform_data = &vcap_iommu,
@@ -975,8 +975,8 @@
 static int __init iommu_init(void)
 {
 	int ret;
-	if (!msm_soc_version_supports_iommu_v1()) {
-		pr_err("IOMMU v1 is not supported on this SoC version.\n");
+	if (!msm_soc_version_supports_iommu_v0()) {
+		pr_err("IOMMU v0 is not supported on this SoC version.\n");
 		return -ENODEV;
 	}
 
diff --git a/arch/arm/mach-msm/devices-msm7x01a.c b/arch/arm/mach-msm/devices-msm7x01a.c
index 6472fc4..574fcdc 100644
--- a/arch/arm/mach-msm/devices-msm7x01a.c
+++ b/arch/arm/mach-msm/devices-msm7x01a.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/devices-msm7x25.c b/arch/arm/mach-msm/devices-msm7x25.c
index 6f89007..057930e 100644
--- a/arch/arm/mach-msm/devices-msm7x25.c
+++ b/arch/arm/mach-msm/devices-msm7x25.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/devices-msm7x27.c b/arch/arm/mach-msm/devices-msm7x27.c
index f869965..ad01042 100644
--- a/arch/arm/mach-msm/devices-msm7x27.c
+++ b/arch/arm/mach-msm/devices-msm7x27.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index 2d9872e..907af68 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -1667,7 +1667,7 @@
 	},
 	{
 		.name   = "l2_irq",
-		.start  = MSM8625_INT_L2CC_INTR,
+		.start  = MSM8625_INT_SC_SICL2PERFMONIRPTREQ,
 		.flags  = IORESOURCE_IRQ,
 	},
 };
@@ -2047,8 +2047,7 @@
 	return ret;
 }
 
-static int __init msm_acpuclock_init(int nominal_voltage,
-					int default_turbo_voltage)
+static int __init msm_acpuclock_init(bool flag)
 {
 	struct cpr_info_type *acpu_info = NULL;
 	acpu_info = kzalloc(sizeof(struct cpr_info_type), GFP_KERNEL);
@@ -2060,8 +2059,7 @@
 	msm8625q_acpuclk_pdata.pvs_voltage_uv =
 			msm_c2_pmic_mv[acpu_info->pvs_fuse & 0x1F];
 	kfree(acpu_info);
-	msm8625q_acpuclk_pdata.nominal_voltage = nominal_voltage;
-	msm8625q_acpuclk_pdata.default_turbo_voltage = default_turbo_voltage;
+	msm8625q_acpuclk_pdata.flag = flag;
 	return 0;
 }
 
@@ -2077,11 +2075,11 @@
 	if (cpu_is_msm7x27aa() || cpu_is_msm7x25ab())
 		platform_device_register(&msm7x27aa_device_acpuclk);
 	else if (cpu_is_msm8625q()) {
-			msm_acpuclock_init(1050000, 0);
-			platform_device_register(&msm8625q_device_acpuclk);
+		msm_acpuclock_init(1);
+		platform_device_register(&msm8625q_device_acpuclk);
 	} else if (cpu_is_msm8625()) {
 		if (machine_is_qrd_skud_prime()) {
-			msm_acpuclock_init(1150000, 1275000);
+			msm_acpuclock_init(0);
 			platform_device_register(&msm8625q_device_acpuclk);
 		} else if (msm8625_cpu_id() == MSM8625)
 			platform_device_register(&msm7x27aa_device_acpuclk);
@@ -2098,7 +2096,7 @@
 		msm_cpr_init();
 
 	if (!cpu_is_msm8625() && !cpu_is_msm8625q())
-		pl310_resources[1].start = INT_L2CC_INTR;
+		pl310_resources[1].start = SC_SICL2PERFMONIRPTREQ;
 
 	platform_device_register(&pl310_erp_device);
 
@@ -2150,7 +2148,7 @@
 {
 	msm_map_common_io();
 	if (socinfo_init() < 0)
-		pr_err("%s: socinfo_init() failed!\n", __func__);
+		pr_err("socinfo_init() failed!\n");
 	msm7x27x_cache_init();
 }
 
@@ -2166,7 +2164,7 @@
 	msm_map_msm8625_io();
 
 	if (socinfo_init() < 0)
-		pr_err("%s: socinfo_init() failed!\n", __func__);
+		pr_err("socinfo_init() failed!\n");
 	msm7x27x_cache_init();
 }
 
diff --git a/arch/arm/mach-msm/devices-msm7x2xa.h b/arch/arm/mach-msm/devices-msm7x2xa.h
index 614037c..60a4649 100644
--- a/arch/arm/mach-msm/devices-msm7x2xa.h
+++ b/arch/arm/mach-msm/devices-msm7x2xa.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
index b456f50..5152918 100644
--- a/arch/arm/mach-msm/devices-msm7x30.c
+++ b/arch/arm/mach-msm/devices-msm7x30.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/devices-msm8x60.c b/arch/arm/mach-msm/devices-msm8x60.c
index 0a080b1..f9e7863 100644
--- a/arch/arm/mach-msm/devices-msm8x60.c
+++ b/arch/arm/mach-msm/devices-msm8x60.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -108,11 +108,17 @@
 	},
 };
 
+static struct msm_gpio_pdata msm8660_gpio_pdata = {
+	.ngpio = 173,
+	.direct_connect_irqs = 10,
+};
+
 struct platform_device msm_gpio_device = {
-	.name = "msmgpio",
-	.id = -1,
-	.num_resources	= ARRAY_SIZE(msm_gpio_resources),
-	.resource	= msm_gpio_resources,
+	.name			= "msmgpio",
+	.id			= -1,
+	.num_resources		= ARRAY_SIZE(msm_gpio_resources),
+	.resource		= msm_gpio_resources,
+	.dev.platform_data	= &msm8660_gpio_pdata,
 };
 
 static void charm_ap2mdm_kpdpwr_on(void)
@@ -406,6 +412,7 @@
 	.uart_tx_gpio	= 67,
 	.uart_rx_gpio	= 66,
 	.line		= 1,
+	.set_uart_clk_zero = true,
 };
 
 static struct resource msm_uart_gsbi9_resources[] = {
@@ -3175,3 +3182,9 @@
 		.platform_data = &msm8660_iommu_domain_pdata,
 	}
 };
+
+struct platform_device msm8660_pm_8x60 = {
+	.name		= "pm-8x60",
+	.id		= -1,
+};
+
diff --git a/arch/arm/mach-msm/devices-msm8x60.h b/arch/arm/mach-msm/devices-msm8x60.h
index 9bfaeee..fafe4e4 100644
--- a/arch/arm/mach-msm/devices-msm8x60.h
+++ b/arch/arm/mach-msm/devices-msm8x60.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/devices-qsd8x50.c b/arch/arm/mach-msm/devices-qsd8x50.c
index 626367e..acb1076 100644
--- a/arch/arm/mach-msm/devices-qsd8x50.c
+++ b/arch/arm/mach-msm/devices-qsd8x50.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index b676518..327c11d 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -1,7 +1,7 @@
 /* linux/arch/arm/mach-msm/devices.h
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -85,7 +85,9 @@
 extern struct platform_device msm8960_device_ebi1_ch1_erp;
 
 extern struct platform_device apq8064_device_uart_gsbi1;
+extern struct platform_device apq8064_device_uart_gsbi2;
 extern struct platform_device apq8064_device_uart_gsbi3;
+extern struct platform_device apq8064_device_uart_gsbi4;
 extern struct platform_device apq8064_device_uart_gsbi7;
 extern struct platform_device apq8064_device_qup_i2c_gsbi1;
 extern struct platform_device apq8064_device_qup_i2c_gsbi3;
@@ -95,6 +97,7 @@
 extern struct platform_device apq8064_device_ssbi_pmic1;
 extern struct platform_device apq8064_device_ssbi_pmic2;
 extern struct platform_device apq8064_device_cache_erp;
+extern struct platform_device apq8064_device_sata;
 
 extern struct platform_device msm9615_device_uart_gsbi4;
 extern struct platform_device msm9615_device_qup_i2c_gsbi5;
@@ -110,17 +113,21 @@
 extern struct platform_device msm_device_sdc3;
 extern struct platform_device msm_device_sdc4;
 
+extern struct platform_device msm8960_pm_8x60;
+extern struct platform_device msm8064_pm_8x60;
+extern struct platform_device msm8930_pm_8x60;
 extern struct platform_device msm9615_pm_8x60;
-
-extern struct platform_device msm8960_pc_cntr;
-extern struct platform_device msm8064_pc_cntr;
-extern struct platform_device msm8930_pc_cntr;
+extern struct platform_device msm8660_pm_8x60;
 
 extern struct platform_device msm_device_gadget_peripheral;
 extern struct platform_device msm_device_hsusb_host;
 extern struct platform_device msm_device_hsusb_host2;
 extern struct platform_device msm_device_hsic_host;
 
+extern struct platform_device msm8960_cpu_slp_status;
+extern struct platform_device msm8064_cpu_slp_status;
+extern struct platform_device msm8930_cpu_slp_status;
+
 extern struct platform_device msm_device_otg;
 extern struct platform_device msm_android_usb_device;
 extern struct platform_device msm_android_usb_hsic_device;
@@ -236,6 +243,7 @@
 extern struct platform_device msm_voice;
 extern struct platform_device msm_voip;
 extern struct platform_device msm_dtmf;
+extern struct platform_device msm_host_pcm_voice;
 extern struct platform_device msm_lpa_pcm;
 extern struct platform_device msm_pcm_hostless;
 extern struct platform_device msm_cpudai_afe_01_rx;
@@ -330,6 +338,9 @@
 
 extern struct resource kgsl_3d0_resources_8960ab[];
 extern int kgsl_num_resources_8960ab;
+#ifdef CONFIG_MSM_BUS_SCALING
+extern struct msm_bus_scale_pdata grp3d_bus_scale_pdata_ab;
+#endif
 
 extern struct platform_device msm_mipi_dsi1_device;
 extern struct platform_device mipi_dsi_device;
diff --git a/arch/arm/mach-msm/dfe-fsm9xxx.c b/arch/arm/mach-msm/dfe-fsm9xxx.c
index 1a956e3..66272d2 100644
--- a/arch/arm/mach-msm/dfe-fsm9xxx.c
+++ b/arch/arm/mach-msm/dfe-fsm9xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c
index 22fc1ac..afee25f 100644
--- a/arch/arm/mach-msm/dma.c
+++ b/arch/arm/mach-msm/dma.c
@@ -1,7 +1,7 @@
 /* linux/arch/arm/mach-msm/dma.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2010, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2010, 2012 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/dma_test.c b/arch/arm/mach-msm/dma_test.c
index de1ee0a..3d13e4e 100644
--- a/arch/arm/mach-msm/dma_test.c
+++ b/arch/arm/mach-msm/dma_test.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/arch/arm/mach-msm/ebi_erp.c b/arch/arm/mach-msm/ebi_erp.c
index cd9119d..eb38101 100644
--- a/arch/arm/mach-msm/ebi_erp.c
+++ b/arch/arm/mach-msm/ebi_erp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/event_timer.c b/arch/arm/mach-msm/event_timer.c
index 9f46f68..df79e42 100644
--- a/arch/arm/mach-msm/event_timer.c
+++ b/arch/arm/mach-msm/event_timer.c
@@ -37,9 +37,9 @@
 	void *data;
 };
 
-
 static DEFINE_TIME_HEAD(timer_head);
 static DEFINE_SPINLOCK(event_timer_lock);
+static DEFINE_SPINLOCK(event_setup_lock);
 static struct hrtimer event_hrtimer;
 static enum hrtimer_restart event_hrtimer_cb(struct hrtimer *hrtimer);
 
@@ -73,6 +73,9 @@
 	event_info->data = data;
 	/* Init rb node and hr timer */
 	timerqueue_init(&event_info->node);
+	pr_debug("%s: New Event Added. Event 0x%x.",
+	__func__,
+	(unsigned int)event_info);
 
 	return event_info;
 }
@@ -140,10 +143,6 @@
 
 	event_hrtimer.function = event_hrtimer_cb;
 	hrtimer_start(&event_hrtimer, expires, HRTIMER_MODE_ABS);
-
-	if (msm_event_debug_mask && MSM_EVENT_TIMER_DEBUG)
-		pr_info("%s: Setting timer for %lu", __func__,
-			(unsigned long)ktime_to_ns(expires));
 }
 
 /**
@@ -155,7 +154,9 @@
 {
 	struct event_timer_info *event;
 	struct timerqueue_node *next;
+	unsigned long flags;
 
+	spin_lock_irqsave(&event_timer_lock, flags);
 	next = timerqueue_getnext(&timer_head);
 
 	while (next && (ktime_to_ns(next->expires)
@@ -168,7 +169,8 @@
 			goto hrtimer_cb_exit;
 
 		if (msm_event_debug_mask && MSM_EVENT_TIMER_DEBUG)
-			pr_info("%s: Deleting event @ %lu", __func__,
+			pr_info("%s: Deleting event 0x%x @ %lu", __func__,
+			(unsigned int)event,
 			(unsigned long)ktime_to_ns(next->expires));
 
 		timerqueue_del(&timer_head, &event->node);
@@ -181,6 +183,7 @@
 	if (next)
 		create_hrtimer(next->expires);
 
+	spin_unlock_irqrestore(&event_timer_lock, flags);
 hrtimer_cb_exit:
 	return HRTIMER_NORESTART;
 }
@@ -201,7 +204,10 @@
 
 	next = timerqueue_getnext(&timer_head);
 	timerqueue_add(&timer_head, &event->node);
-	spin_unlock_irqrestore(&event_timer_lock, flags);
+	if (msm_event_debug_mask && MSM_EVENT_TIMER_DEBUG)
+		pr_info("%s: Adding Event 0x%x for %lu", __func__,
+		(unsigned int)event,
+		(unsigned long)ktime_to_ns(event->node.expires));
 
 	if (!next ||
 		(next && (ktime_to_ns(event->node.expires) <
@@ -211,6 +217,7 @@
 			(unsigned long)ktime_to_ns(event->node.expires));
 		create_hrtimer(event->node.expires);
 	}
+	spin_unlock_irqrestore(&event_timer_lock, flags);
 }
 
 /**
@@ -239,9 +246,11 @@
 		pr_info("%s: Adding event timer @ %lu", __func__,
 				(unsigned long)ktime_to_us(event_time));
 
+	spin_lock(&event_setup_lock);
 	event->node.expires = event_time;
 	/* Start hr timer and add event to rb tree */
 	setup_event_hrtimer(event);
+	spin_unlock(&event_setup_lock);
 }
 
 
diff --git a/arch/arm/mach-msm/footswitch-8x60.c b/arch/arm/mach-msm/footswitch-8x60.c
index a7b26c1..d5fe866 100644
--- a/arch/arm/mach-msm/footswitch-8x60.c
+++ b/arch/arm/mach-msm/footswitch-8x60.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/footswitch-pcom.c b/arch/arm/mach-msm/footswitch-pcom.c
index 8903859..83c8c84 100644
--- a/arch/arm/mach-msm/footswitch-pcom.c
+++ b/arch/arm/mach-msm/footswitch-pcom.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/footswitch.h b/arch/arm/mach-msm/footswitch.h
index 1809b2e..2a49426 100644
--- a/arch/arm/mach-msm/footswitch.h
+++ b/arch/arm/mach-msm/footswitch.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012 Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/gdsc.c b/arch/arm/mach-msm/gdsc.c
index 4665aec..53a6616 100644
--- a/arch/arm/mach-msm/gdsc.c
+++ b/arch/arm/mach-msm/gdsc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/gpio.h b/arch/arm/mach-msm/gpio.h
index 59ee8f8..397be6e 100644
--- a/arch/arm/mach-msm/gpio.h
+++ b/arch/arm/mach-msm/gpio.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/arch/arm/mach-msm/gpiomux-7x27.c b/arch/arm/mach-msm/gpiomux-7x27.c
index 822cd04..010c94d 100644
--- a/arch/arm/mach-msm/gpiomux-7x27.c
+++ b/arch/arm/mach-msm/gpiomux-7x27.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/gpiomux-7x30.c b/arch/arm/mach-msm/gpiomux-7x30.c
index 822cd04..010c94d 100644
--- a/arch/arm/mach-msm/gpiomux-7x30.c
+++ b/arch/arm/mach-msm/gpiomux-7x30.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/gpiomux-8x50.c b/arch/arm/mach-msm/gpiomux-8x50.c
index 822cd04..010c94d 100644
--- a/arch/arm/mach-msm/gpiomux-8x50.c
+++ b/arch/arm/mach-msm/gpiomux-8x50.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/gpiomux-8x60.c b/arch/arm/mach-msm/gpiomux-8x60.c
index c23a41c..4b0b8f1 100644
--- a/arch/arm/mach-msm/gpiomux-8x60.c
+++ b/arch/arm/mach-msm/gpiomux-8x60.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/gpiomux-8x60.h b/arch/arm/mach-msm/gpiomux-8x60.h
index cacd1ba..619b5c0 100644
--- a/arch/arm/mach-msm/gpiomux-8x60.h
+++ b/arch/arm/mach-msm/gpiomux-8x60.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/gpiomux-v1.c b/arch/arm/mach-msm/gpiomux-v1.c
index 1163669..8338cd8 100644
--- a/arch/arm/mach-msm/gpiomux-v1.c
+++ b/arch/arm/mach-msm/gpiomux-v1.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011 Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/gpiomux-v1.h b/arch/arm/mach-msm/gpiomux-v1.h
index 7cf4582..6468d3d 100644
--- a/arch/arm/mach-msm/gpiomux-v1.h
+++ b/arch/arm/mach-msm/gpiomux-v1.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/gpiomux-v2.c b/arch/arm/mach-msm/gpiomux-v2.c
index ee1e17a..92b9148 100644
--- a/arch/arm/mach-msm/gpiomux-v2.c
+++ b/arch/arm/mach-msm/gpiomux-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/gpiomux-v2.h b/arch/arm/mach-msm/gpiomux-v2.h
index b200501..526ea21 100644
--- a/arch/arm/mach-msm/gpiomux-v2.h
+++ b/arch/arm/mach-msm/gpiomux-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/gpiomux.c b/arch/arm/mach-msm/gpiomux.c
index 85936ba..4714210 100644
--- a/arch/arm/mach-msm/gpiomux.c
+++ b/arch/arm/mach-msm/gpiomux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
@@ -10,6 +10,7 @@
  * GNU General Public License for more details.
  */
 #include <linux/module.h>
+#include <linux/of.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <mach/gpiomux.h>
@@ -23,13 +24,12 @@
 static struct gpiomux_setting *msm_gpiomux_sets;
 static unsigned msm_gpiomux_ngpio;
 
-int msm_gpiomux_write(unsigned gpio, enum msm_gpiomux_setting which,
+static int msm_gpiomux_store(unsigned gpio, enum msm_gpiomux_setting which,
 	struct gpiomux_setting *setting, struct gpiomux_setting *old_setting)
 {
 	struct msm_gpiomux_rec *rec = msm_gpiomux_recs + gpio;
 	unsigned set_slot = gpio * GPIOMUX_NSETTINGS + which;
 	unsigned long irq_flags;
-	struct gpiomux_setting *new_set;
 	int status = 0;
 
 	if (!msm_gpiomux_recs)
@@ -54,13 +54,31 @@
 		rec->sets[which] = NULL;
 	}
 
+	spin_unlock_irqrestore(&gpiomux_lock, irq_flags);
+	return status;
+}
+
+int msm_gpiomux_write(unsigned gpio, enum msm_gpiomux_setting which,
+	struct gpiomux_setting *setting, struct gpiomux_setting *old_setting)
+{
+	int ret;
+	unsigned long irq_flags;
+	struct gpiomux_setting *new_set;
+	struct msm_gpiomux_rec *rec = msm_gpiomux_recs + gpio;
+
+	ret = msm_gpiomux_store(gpio, which, setting, old_setting);
+	if (ret < 0)
+		return ret;
+
+	spin_lock_irqsave(&gpiomux_lock, irq_flags);
+
 	new_set = rec->ref ? rec->sets[GPIOMUX_ACTIVE] :
 		rec->sets[GPIOMUX_SUSPENDED];
 	if (new_set)
 		__msm_gpiomux_write(gpio, *new_set);
 
 	spin_unlock_irqrestore(&gpiomux_lock, irq_flags);
-	return status;
+	return ret;
 }
 EXPORT_SYMBOL(msm_gpiomux_write);
 
@@ -133,6 +151,22 @@
 }
 EXPORT_SYMBOL(msm_gpiomux_init);
 
+void msm_gpiomux_install_nowrite(struct msm_gpiomux_config *configs,
+				unsigned nconfigs)
+{
+	unsigned c, s;
+	int rc;
+
+	for (c = 0; c < nconfigs; ++c) {
+		for (s = 0; s < GPIOMUX_NSETTINGS; ++s) {
+			rc = msm_gpiomux_store(configs[c].gpio, s,
+				configs[c].settings[s], NULL);
+			if (rc)
+				pr_err("%s: write failure: %d\n", __func__, rc);
+		}
+	}
+}
+
 void msm_gpiomux_install(struct msm_gpiomux_config *configs, unsigned nconfigs)
 {
 	unsigned c, s;
@@ -148,3 +182,26 @@
 	}
 }
 EXPORT_SYMBOL(msm_gpiomux_install);
+
+int msm_gpiomux_init_dt(void)
+{
+	int rc;
+	unsigned int ngpio;
+	struct device_node *of_gpio_node;
+
+	of_gpio_node = of_find_compatible_node(NULL, NULL, "qcom,msm-gpio");
+	if (!of_gpio_node) {
+		pr_err("%s: Failed to find qcom,msm-gpio node\n", __func__);
+		return -ENODEV;
+	}
+
+	rc = of_property_read_u32(of_gpio_node, "ngpio", &ngpio);
+	if (rc) {
+		pr_err("%s: Failed to find ngpio property in msm-gpio device node %d\n"
+				, __func__, rc);
+		return rc;
+	}
+
+	return msm_gpiomux_init(ngpio);
+}
+EXPORT_SYMBOL(msm_gpiomux_init_dt);
diff --git a/arch/arm/mach-msm/headsmp.S b/arch/arm/mach-msm/headsmp.S
index 0537421..6ae2129 100644
--- a/arch/arm/mach-msm/headsmp.S
+++ b/arch/arm/mach-msm/headsmp.S
@@ -1,7 +1,7 @@
 /*
  *  Copyright (c) 2003 ARM Limited
  *  All Rights Reserved
- *  Copyright (c) 2010, 2012 Code Aurora Forum. All rights reserved.
+ *  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 as
diff --git a/arch/arm/mach-msm/hotplug.c b/arch/arm/mach-msm/hotplug.c
index f296aae..5cd5057 100644
--- a/arch/arm/mach-msm/hotplug.c
+++ b/arch/arm/mach-msm/hotplug.c
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 2002 ARM Ltd.
  *  All Rights Reserved
- *  Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2011-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 as
diff --git a/arch/arm/mach-msm/hsic_sysmon.c b/arch/arm/mach-msm/hsic_sysmon.c
index e088435..8270197 100644
--- a/arch/arm/mach-msm/hsic_sysmon.c
+++ b/arch/arm/mach-msm/hsic_sysmon.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/hsic_sysmon.h b/arch/arm/mach-msm/hsic_sysmon.h
index aa57b93..983f464 100644
--- a/arch/arm/mach-msm/hsic_sysmon.h
+++ b/arch/arm/mach-msm/hsic_sysmon.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/hsic_sysmon_test.c b/arch/arm/mach-msm/hsic_sysmon_test.c
index 9929cb7..bc60c6e 100644
--- a/arch/arm/mach-msm/hsic_sysmon_test.c
+++ b/arch/arm/mach-msm/hsic_sysmon_test.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/idle-macros.S b/arch/arm/mach-msm/idle-macros.S
index 1622e13..3d0c937 100644
--- a/arch/arm/mach-msm/idle-macros.S
+++ b/arch/arm/mach-msm/idle-macros.S
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/idle-v6.S b/arch/arm/mach-msm/idle-v6.S
index 8160877..35db96c 100644
--- a/arch/arm/mach-msm/idle-v6.S
+++ b/arch/arm/mach-msm/idle-v6.S
@@ -3,7 +3,7 @@
  * Work around bugs with SWFI.
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/idle-v7.S b/arch/arm/mach-msm/idle-v7.S
index 9a22996..6840f1c 100644
--- a/arch/arm/mach-msm/idle-v7.S
+++ b/arch/arm/mach-msm/idle-v7.S
@@ -2,7 +2,7 @@
  * Idle processing for ARMv7-based Qualcomm SoCs.
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2009, 2011-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2009, 2011-2013 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -97,7 +97,7 @@
 	mrc     p15, 0, ip, c13, c0, 1 /* context ID */
 	stmia   r0!, {r1-r9, ip}
 
-#ifdef CONFIG_MSM_JTAG
+#if defined(CONFIG_MSM_JTAG) || defined(CONFIG_MSM_JTAG_MM)
 	bl      msm_jtag_save_state
 #endif
 
@@ -185,7 +185,7 @@
 	blxne	r1
 	dmb
 
-#ifdef CONFIG_MSM_JTAG
+#if defined(CONFIG_MSM_JTAG) || defined(CONFIG_MSM_JTAG_MM)
 	bl	msm_jtag_restore_state
 #endif
 	ldr     r0, =msm_saved_state	/* address of msm_saved_state ptr */
@@ -286,7 +286,7 @@
 	stmfd   sp!, {lr}
 	blxne	r1
 	dmb
-#ifdef CONFIG_MSM_JTAG
+#if defined(CONFIG_MSM_JTAG) || defined(CONFIG_MSM_JTAG_MM)
 	bl      msm_jtag_restore_state
 #endif
 	ldmfd   sp!, {lr}
diff --git a/arch/arm/mach-msm/idle.h b/arch/arm/mach-msm/idle.h
index 5550e96..ead86a1 100644
--- a/arch/arm/mach-msm/idle.h
+++ b/arch/arm/mach-msm/idle.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2007-2009,2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2007-2009,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
diff --git a/arch/arm/mach-msm/idle_stats_device.c b/arch/arm/mach-msm/idle_stats_device.c
index 01b464a..54b8382 100644
--- a/arch/arm/mach-msm/idle_stats_device.c
+++ b/arch/arm/mach-msm/idle_stats_device.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/include/mach/audio_dma_msm8k.h b/arch/arm/mach-msm/include/mach/audio_dma_msm8k.h
index 1970d0b..bbe4961 100644
--- a/arch/arm/mach-msm/include/mach/audio_dma_msm8k.h
+++ b/arch/arm/mach-msm/include/mach/audio_dma_msm8k.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/bam_dmux.h b/arch/arm/mach-msm/include/mach/bam_dmux.h
index f11b72c..5a31525 100644
--- a/arch/arm/mach-msm/include/mach/bam_dmux.h
+++ b/arch/arm/mach-msm/include/mach/bam_dmux.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/include/mach/barriers.h b/arch/arm/mach-msm/include/mach/barriers.h
index 2d4792c..89734ad 100644
--- a/arch/arm/mach-msm/include/mach/barriers.h
+++ b/arch/arm/mach-msm/include/mach/barriers.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/board-msm8660.h b/arch/arm/mach-msm/include/mach/board-msm8660.h
index 22e378c..e1e1b17 100644
--- a/arch/arm/mach-msm/include/mach/board-msm8660.h
+++ b/arch/arm/mach-msm/include/mach/board-msm8660.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index 8b5c70f..327212e 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/include/mach/board.h
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2013, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -182,9 +182,8 @@
 	uint32_t delay;
 };
 
-struct msm_camera_csi_lane_params {
-	uint16_t csi_lane_assign;
-	uint16_t csi_lane_mask;
+struct msm_camera_gpio_num_info {
+	uint16_t gpio_num[2];
 };
 
 struct msm_camera_gpio_conf {
@@ -201,6 +200,7 @@
 	uint8_t camera_off_table_size;
 	uint32_t *camera_on_table;
 	uint8_t camera_on_table_size;
+	struct msm_camera_gpio_num_info *gpio_num_info;
 };
 
 enum msm_camera_i2c_mux_mode {
@@ -215,13 +215,6 @@
 	enum msm_camera_i2c_mux_mode i2c_mux_mode;
 };
 
-enum msm_camera_vreg_name_t {
-	CAM_VDIG,
-	CAM_VIO,
-	CAM_VANA,
-	CAM_VAF,
-};
-
 struct msm_camera_sensor_platform_info {
 	int mount_angle;
 	int sensor_reset;
@@ -552,6 +545,30 @@
 	unsigned long fw_addr;
 };
 
+enum msm_vidc_v4l2_iommu_map {
+	MSM_VIDC_V4L2_IOMMU_MAP_NS = 0,
+	MSM_VIDC_V4L2_IOMMU_MAP_CP,
+	MSM_VIDC_V4L2_IOMMU_MAP_MAX,
+};
+
+struct msm_vidc_v4l2_platform_data {
+	/*
+	 * Should be a <num_iommu_table x 2> array where
+	 * iommu_table[n][0] is the start address and
+	 * iommu_table[n][1] is the size.
+	 */
+	int64_t **iommu_table;
+	int num_iommu_table;
+
+	/*
+	 * Should be a <num_load_table x 2> array where
+	 * load_table[n][0] is the load and load_table[n][1]
+	 * is the desired clock rate.
+	 */
+	int64_t **load_table;
+	int num_load_table;
+};
+
 struct vcap_platform_data {
 	unsigned *gpios;
 	int num_gpios;
@@ -595,9 +612,9 @@
 void msm_map_msm8226_io(void);
 void msm8226_init_irq(void);
 void msm8226_init_gpiomux(void);
-void msm8910_init_gpiomux(void);
-void msm_map_msm8910_io(void);
-void msm8910_init_irq(void);
+void msm8610_init_gpiomux(void);
+void msm_map_msm8610_io(void);
+void msm8610_init_irq(void);
 
 /* Dump debug info (states, rate, etc) of clocks */
 #if defined(CONFIG_ARCH_MSM7X27)
diff --git a/arch/arm/mach-msm/include/mach/camera2.h b/arch/arm/mach-msm/include/mach/camera2.h
new file mode 100644
index 0000000..b518e56
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/camera2.h
@@ -0,0 +1,103 @@
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __CAMERA2_H__
+#define __CAMERA2_H__
+
+#include <media/msm_cam_sensor.h>
+#include <mach/board.h>
+
+enum msm_camera_device_type_t {
+	MSM_CAMERA_I2C_DEVICE,
+	MSM_CAMERA_PLATFORM_DEVICE,
+};
+
+enum msm_bus_perf_setting {
+	S_INIT,
+	S_PREVIEW,
+	S_VIDEO,
+	S_CAPTURE,
+	S_ZSL,
+	S_STEREO_VIDEO,
+	S_STEREO_CAPTURE,
+	S_DEFAULT,
+	S_LIVESHOT,
+	S_DUAL,
+	S_EXIT
+};
+
+enum cci_i2c_master_t {
+	MASTER_0,
+	MASTER_1,
+};
+
+struct msm_camera_slave_info {
+	uint16_t sensor_slave_addr;
+	uint16_t sensor_id_reg_addr;
+	uint16_t sensor_id;
+};
+
+struct msm_cam_clk_info {
+	const char *clk_name;
+	long clk_rate;
+	uint32_t delay;
+};
+
+struct msm_cam_clk_setting {
+	struct msm_cam_clk_info *clk_info;
+	uint16_t num_clk_info;
+	uint8_t enable;
+};
+
+struct v4l2_subdev_info {
+	enum v4l2_mbus_pixelcode code;
+	enum v4l2_colorspace colorspace;
+	uint16_t fmt;
+	uint16_t order;
+};
+
+struct msm_camera_sensor_board_info {
+	const char *sensor_name;
+	struct msm_camera_slave_info *slave_info;
+	struct msm_camera_csi_lane_params *csi_lane_params;
+	struct camera_vreg_t *cam_vreg;
+	int num_vreg;
+	struct msm_camera_sensor_strobe_flash_data *strobe_flash_data;
+	struct msm_camera_gpio_conf *gpio_conf;
+	struct msm_actuator_info *actuator_info;
+	struct msm_camera_i2c_conf *i2c_conf;
+	struct msm_sensor_info_t *sensor_info;
+	struct msm_sensor_init_params *sensor_init_params;
+};
+
+enum msm_camera_i2c_cmd_type {
+	MSM_CAMERA_I2C_CMD_WRITE,
+	MSM_CAMERA_I2C_CMD_POLL,
+};
+
+struct msm_camera_i2c_reg_conf {
+	uint16_t reg_addr;
+	uint16_t reg_data;
+	enum msm_camera_i2c_data_type dt;
+	enum msm_camera_i2c_cmd_type cmd_type;
+	int16_t mask;
+};
+
+struct msm_camera_i2c_conf_array {
+	struct msm_camera_i2c_reg_conf *conf;
+	uint16_t size;
+	uint16_t delay;
+	enum msm_camera_i2c_data_type data_type;
+};
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/clk-provider.h b/arch/arm/mach-msm/include/mach/clk-provider.h
index 0f2feaa..475b483 100644
--- a/arch/arm/mach-msm/include/mach/clk-provider.h
+++ b/arch/arm/mach-msm/include/mach/clk-provider.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2007-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -69,7 +69,6 @@
 enum handoff {
 	HANDOFF_ENABLED_CLK,
 	HANDOFF_DISABLED_CLK,
-	HANDOFF_UNKNOWN_RATE,
 };
 
 struct clk_ops {
diff --git a/arch/arm/mach-msm/include/mach/clk.h b/arch/arm/mach-msm/include/mach/clk.h
index d69b372..1191bb7 100644
--- a/arch/arm/mach-msm/include/mach/clk.h
+++ b/arch/arm/mach-msm/include/mach/clk.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
@@ -21,6 +21,8 @@
 #define CLKFLAG_SKIP_HANDOFF		0x00000100
 #define CLKFLAG_MIN			0x00000400
 #define CLKFLAG_MAX			0x00000800
+#define CLKFLAG_INIT_DONE		0x00001000
+#define CLKFLAG_INIT_ERR		0x00002000
 
 struct clk_lookup;
 struct clk;
diff --git a/arch/arm/mach-msm/include/mach/cpufreq.h b/arch/arm/mach-msm/include/mach/cpufreq.h
index 8c2be11..1a6f2d9 100644
--- a/arch/arm/mach-msm/include/mach/cpufreq.h
+++ b/arch/arm/mach-msm/include/mach/cpufreq.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/include/mach/cpuidle.h b/arch/arm/mach-msm/include/mach/cpuidle.h
index af773a0..fef7a5a 100644
--- a/arch/arm/mach-msm/include/mach/cpuidle.h
+++ b/arch/arm/mach-msm/include/mach/cpuidle.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/dal.h b/arch/arm/mach-msm/include/mach/dal.h
index d0c754d..c28a5e5 100644
--- a/arch/arm/mach-msm/include/mach/dal.h
+++ b/arch/arm/mach-msm/include/mach/dal.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/arch/arm/mach-msm/include/mach/dal_axi.h b/arch/arm/mach-msm/include/mach/dal_axi.h
index 84cd37f..9431060 100644
--- a/arch/arm/mach-msm/include/mach/dal_axi.h
+++ b/arch/arm/mach-msm/include/mach/dal_axi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/debug_mm.h b/arch/arm/mach-msm/include/mach/debug_mm.h
index 091798c..6b27ded 100644
--- a/arch/arm/mach-msm/include/mach/debug_mm.h
+++ b/arch/arm/mach-msm/include/mach/debug_mm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/include/mach/diag_bridge.h b/arch/arm/mach-msm/include/mach/diag_bridge.h
index b06f020..d67d664 100644
--- a/arch/arm/mach-msm/include/mach/diag_bridge.h
+++ b/arch/arm/mach-msm/include/mach/diag_bridge.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, 2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -23,32 +23,31 @@
 	void (*resume)(void *ctxt);
 };
 
-#if defined(CONFIG_USB_QCOM_DIAG_BRIDGE) \
-	|| defined(CONFIG_USB_QCOM_DIAG_BRIDGE_MODULE)
+#if IS_ENABLED(CONFIG_USB_QCOM_DIAG_BRIDGE)
 
-extern int diag_bridge_read(char *data, int size);
-extern int diag_bridge_write(char *data, int size);
-extern int diag_bridge_open(struct diag_bridge_ops *ops);
-extern void diag_bridge_close(void);
+extern int diag_bridge_read(int id, char *data, int size);
+extern int diag_bridge_write(int id, char *data, int size);
+extern int diag_bridge_open(int id, struct diag_bridge_ops *ops);
+extern void diag_bridge_close(int id);
 
 #else
 
-static int __maybe_unused diag_bridge_read(char *data, int size)
+static int __maybe_unused diag_bridge_read(int id, char *data, int size)
 {
 	return -ENODEV;
 }
 
-static int __maybe_unused diag_bridge_write(char *data, int size)
+static int __maybe_unused diag_bridge_write(int id, char *data, int size)
 {
 	return -ENODEV;
 }
 
-static int __maybe_unused diag_bridge_open(struct diag_bridge_ops *ops)
+static int __maybe_unused diag_bridge_open(int id, struct diag_bridge_ops *ops)
 {
 	return -ENODEV;
 }
 
-static void __maybe_unused diag_bridge_close(void) { }
+static void __maybe_unused diag_bridge_close(int id) { }
 
 #endif
 
diff --git a/arch/arm/mach-msm/include/mach/dma-fsm9xxx.h b/arch/arm/mach-msm/include/mach/dma-fsm9xxx.h
index e284267..c8c6cdf 100644
--- a/arch/arm/mach-msm/include/mach/dma-fsm9xxx.h
+++ b/arch/arm/mach-msm/include/mach/dma-fsm9xxx.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h
index 5fcf579..0f27f88 100644
--- a/arch/arm/mach-msm/include/mach/dma.h
+++ b/arch/arm/mach-msm/include/mach/dma.h
@@ -1,7 +1,7 @@
 /* linux/include/asm-arm/arch-msm/dma.h
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/dma_test.h b/arch/arm/mach-msm/include/mach/dma_test.h
index c0464fa..a1b35c1 100644
--- a/arch/arm/mach-msm/include/mach/dma_test.h
+++ b/arch/arm/mach-msm/include/mach/dma_test.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/arch/arm/mach-msm/include/mach/ecm_ipa.h b/arch/arm/mach-msm/include/mach/ecm_ipa.h
new file mode 100644
index 0000000..008a659
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/ecm_ipa.h
@@ -0,0 +1,76 @@
+/* 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 _ECM_IPA_H_
+#define _ECM_IPA_H_
+
+#include <mach/ipa.h>
+
+/*
+ * @priv: private data given upon ipa_connect
+ * @evt: event enum, should be IPA_WRITE_DONE
+ * @data: for tx path the data field is the sent socket buffer.
+ */
+typedef void (*ecm_ipa_callback)(void *priv,
+		enum ipa_dp_evt_type evt,
+		unsigned long data);
+
+
+#ifdef CONFIG_ECM_IPA
+
+int ecm_ipa_init(ecm_ipa_callback * ecm_ipa_rx_dp_notify,
+		ecm_ipa_callback * ecm_ipa_tx_dp_notify,
+		void **priv);
+
+int ecm_ipa_configure(u8 host_ethaddr[], u8 device_ethaddr[],
+		void *priv);
+
+int ecm_ipa_connect(u32 usb_to_ipa_hdl, u32 ipa_to_usb_hdl,
+		void *priv);
+
+int ecm_ipa_disconnect(void *priv);
+
+void ecm_ipa_cleanup(void *priv);
+
+#else /* CONFIG_ECM_IPA*/
+
+static inline int ecm_ipa_init(ecm_ipa_callback *ecm_ipa_rx_dp_notify,
+		ecm_ipa_callback *ecm_ipa_tx_dp_notify,
+		void **priv)
+{
+	return 0;
+}
+
+static inline int ecm_ipa_configure(u8 host_ethaddr[], u8 device_ethaddr[],
+		void *priv)
+{
+	return 0;
+}
+
+static inline int ecm_ipa_connect(u32 usb_to_ipa_hdl, u32 ipa_to_usb_hdl,
+		void *priv)
+{
+	return 0;
+}
+
+static inline int ecm_ipa_disconnect(void *priv)
+{
+	return 0;
+}
+
+static inline void ecm_ipa_cleanup(void *priv)
+{
+
+}
+#endif /* CONFIG_ECM_IPA*/
+
+#endif /* _ECM_IPA_H_ */
diff --git a/arch/arm/mach-msm/include/mach/entry-macro.S b/arch/arm/mach-msm/include/mach/entry-macro.S
index dd1b54d..5b43f2a 100644
--- a/arch/arm/mach-msm/include/mach/entry-macro.S
+++ b/arch/arm/mach-msm/include/mach/entry-macro.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/include/mach/gpio-tlmm-v1.h b/arch/arm/mach-msm/include/mach/gpio-tlmm-v1.h
index e41fe72..04e5e75 100644
--- a/arch/arm/mach-msm/include/mach/gpio-tlmm-v1.h
+++ b/arch/arm/mach-msm/include/mach/gpio-tlmm-v1.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2010, The Linux Foundation. All rights reserved.
  * Author: Mike Lockwood <lockwood@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/gpio-v1.h b/arch/arm/mach-msm/include/mach/gpio-v1.h
index eea4c88..ec62f15 100644
--- a/arch/arm/mach-msm/include/mach/gpio-v1.h
+++ b/arch/arm/mach-msm/include/mach/gpio-v1.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2010, The Linux Foundation. All rights reserved.
  * Author: Mike Lockwood <lockwood@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/gpio.h b/arch/arm/mach-msm/include/mach/gpio.h
index a0bcd2b..bfcce73 100644
--- a/arch/arm/mach-msm/include/mach/gpio.h
+++ b/arch/arm/mach-msm/include/mach/gpio.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  * Author: Mike Lockwood <lockwood@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -16,7 +16,7 @@
 #ifndef __ASM_ARCH_MSM_GPIO_H
 #define __ASM_ARCH_MSM_GPIO_H
 
-#define ARCH_NR_GPIOS 512
+#define ARCH_NR_GPIOS 1024
 
 #include <linux/interrupt.h>
 #include <asm-generic/gpio.h>
@@ -40,6 +40,11 @@
 	const char *label;
 };
 
+struct msm_gpio_pdata {
+	int ngpio;
+	int direct_connect_irqs;
+};
+
 /**
  * msm_gpios_request_enable() - request and enable set of GPIOs
  *
diff --git a/arch/arm/mach-msm/include/mach/gpiomux.h b/arch/arm/mach-msm/include/mach/gpiomux.h
index f75b0e0..5ffcabb 100644
--- a/arch/arm/mach-msm/include/mach/gpiomux.h
+++ b/arch/arm/mach-msm/include/mach/gpiomux.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-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
@@ -117,11 +117,22 @@
  */
 int msm_gpiomux_init(size_t ngpio);
 
+/* DT Variant of msm_gpiomux_init. This will look up the number of gpios from
+ * device tree rather than relying on NR_GPIO_IRQS
+ */
+int msm_gpiomux_init_dt(void);
+
 /* Install a block of gpiomux configurations in gpiomux.  This is functionally
  * identical to calling msm_gpiomux_write many times.
  */
 void msm_gpiomux_install(struct msm_gpiomux_config *configs, unsigned nconfigs);
 
+/* Install a block of gpiomux configurations in gpiomux. Do not however write
+ * to hardware. Just store the settings to be retrieved at a later time
+ */
+void msm_gpiomux_install_nowrite(struct msm_gpiomux_config *configs,
+				unsigned nconfigs);
+
 /* Increment a gpio's reference count, possibly activating the line. */
 int __must_check msm_gpiomux_get(unsigned gpio);
 
diff --git a/arch/arm/mach-msm/include/mach/hardware.h b/arch/arm/mach-msm/include/mach/hardware.h
index 7b7cbaa..fbf289e 100644
--- a/arch/arm/mach-msm/include/mach/hardware.h
+++ b/arch/arm/mach-msm/include/mach/hardware.h
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/include/mach/hardware.h
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/iommu.h b/arch/arm/mach-msm/include/mach/iommu.h
index 975b12c..c6e93de 100644
--- a/arch/arm/mach-msm/include/mach/iommu.h
+++ b/arch/arm/mach-msm/include/mach/iommu.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+/* 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
@@ -94,6 +94,8 @@
  * @bfb_settings: Optional BFB performance tuning parameters
  * @dev:	Struct device this hardware instance is tied to
  * @list:	List head to link all iommus together
+ * @clk_reg_virt: Optional clock register virtual address.
+ * @halt_enabled: Set to 1 if IOMMU halt is supported in the IOMMU, 0 otherwise.
  *
  * A msm_iommu_drvdata holds the global driver data about a single piece
  * of an IOMMU hardware instance.
@@ -108,14 +110,21 @@
 	struct clk *aclk;
 	const char *name;
 	struct regulator *gdsc;
+	struct regulator *alt_gdsc;
 	struct msm_iommu_bfb_settings *bfb_settings;
 	int sec_id;
 	struct device *dev;
 	struct list_head list;
+	void __iomem *clk_reg_virt;
+	int halt_enabled;
 };
 
 void msm_iommu_add_drv(struct msm_iommu_drvdata *drv);
 void msm_iommu_remove_drv(struct msm_iommu_drvdata *drv);
+void program_iommu_bfb_settings(void __iomem *base,
+			const struct msm_iommu_bfb_settings *bfb_settings);
+void iommu_halt(const struct msm_iommu_drvdata *iommu_drvdata);
+void iommu_resume(const struct msm_iommu_drvdata *iommu_drvdata);
 
 /**
  * struct msm_iommu_ctx_drvdata - an IOMMU context bank instance
@@ -127,6 +136,10 @@
  * @name		Human-readable name of this context device
  * @sids		List of Stream IDs mapped to this context
  * @nsid		Number of Stream IDs mapped to this context
+ * @secure_context	true if this is a secure context programmed by
+			the secure environment, false otherwise
+ * @asid		ASID used with this context.
+ * @attach_count	Number of time this context has been attached.
  *
  * A msm_iommu_ctx_drvdata holds the driver data for a single context bank
  * within each IOMMU hardware instance
@@ -139,6 +152,9 @@
 	const char *name;
 	u32 sids[MAX_NUM_SMR];
 	unsigned int nsid;
+	unsigned int secure_context;
+	int asid;
+	int attach_count;
 };
 
 /*
@@ -223,18 +239,18 @@
  */
 int msm_iommu_sec_program_iommu(int sec_id);
 
-static inline int msm_soc_version_supports_iommu_v1(void)
+static inline int msm_soc_version_supports_iommu_v0(void)
 {
 #ifdef CONFIG_OF
 	struct device_node *node;
 
-	node = of_find_compatible_node(NULL, NULL, "qcom,msm-smmu-v2");
+	node = of_find_compatible_node(NULL, NULL, "qcom,msm-smmu-v1");
 	if (node) {
 		of_node_put(node);
 		return 0;
 	}
 
-	node = of_find_compatible_node(NULL, NULL, "qcom,msm-smmu-v1");
+	node = of_find_compatible_node(NULL, NULL, "qcom,msm-smmu-v0");
 	if (node) {
 		of_node_put(node);
 		return 1;
diff --git a/arch/arm/mach-msm/include/mach/iommu_domains.h b/arch/arm/mach-msm/include/mach/iommu_domains.h
index 01bc479..a104a42 100644
--- a/arch/arm/mach-msm/include/mach/iommu_domains.h
+++ b/arch/arm/mach-msm/include/mach/iommu_domains.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -77,6 +77,7 @@
 #if defined(CONFIG_MSM_IOMMU)
 
 extern struct iommu_domain *msm_get_iommu_domain(int domain_num);
+extern int msm_find_domain_no(const struct iommu_domain *domain);
 
 extern int msm_allocate_iova_address(unsigned int iommu_domain,
 					unsigned int partition_no,
@@ -93,6 +94,7 @@
 
 extern int msm_iommu_map_extra(struct iommu_domain *domain,
 						unsigned long start_iova,
+						unsigned long phys_addr,
 						unsigned long size,
 						unsigned long page_size,
 						int cached);
@@ -123,6 +125,10 @@
 	*msm_get_iommu_domain(int subsys_id) { return NULL; }
 
 
+static inline int msm_find_domain_no(const struct iommu_domain *domain)
+{
+	return -EINVAL;
+}
 
 static inline int msm_allocate_iova_address(unsigned int iommu_domain,
 					unsigned int partition_no,
@@ -142,6 +148,7 @@
 
 static inline int msm_iommu_map_extra(struct iommu_domain *domain,
 						unsigned long start_iova,
+						unsigned long phys_addr,
 						unsigned long size,
 						unsigned long page_size,
 						int cached)
diff --git a/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h b/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
deleted file mode 100644
index 31b2b4f..0000000
--- a/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
+++ /dev/null
@@ -1,1863 +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.
- */
-
-#ifndef __ARCH_ARM_MACH_MSM_IOMMU_HW_8XXX_H
-#define __ARCH_ARM_MACH_MSM_IOMMU_HW_8XXX_H
-
-#define CTX_SHIFT 12
-
-#define GET_GLOBAL_REG(reg, base) (readl_relaxed((base) + (reg)))
-#define GET_CTX_REG(reg, base, ctx) \
-			(readl_relaxed((base) + (reg) + ((ctx) << CTX_SHIFT)))
-
-#define SET_GLOBAL_REG(reg, base, val)	writel_relaxed((val), ((base) + (reg)))
-
-#define SET_CTX_REG(reg, base, ctx, val) \
-		writel_relaxed((val), ((base) + (reg) + ((ctx) << CTX_SHIFT)))
-
-/* Wrappers for numbered registers */
-#define SET_GLOBAL_REG_N(b, n, r, v) SET_GLOBAL_REG(b, ((r) + (n << 2)), (v))
-#define GET_GLOBAL_REG_N(b, n, r)    GET_GLOBAL_REG(b, ((r) + (n << 2)))
-
-/* Field wrappers */
-#define GET_GLOBAL_FIELD(b, r, F)    GET_FIELD(((b) + (r)), F##_MASK, F##_SHIFT)
-#define GET_CONTEXT_FIELD(b, c, r, F)	\
-	GET_FIELD(((b) + (r) + ((c) << CTX_SHIFT)), F##_MASK, F##_SHIFT)
-
-#define SET_GLOBAL_FIELD(b, r, F, v) \
-	SET_FIELD(((b) + (r)), F##_MASK, F##_SHIFT, (v))
-#define SET_CONTEXT_FIELD(b, c, r, F, v)	\
-	SET_FIELD(((b) + (r) + ((c) << CTX_SHIFT)), F##_MASK, F##_SHIFT, (v))
-
-#define GET_FIELD(addr, mask, shift) ((readl_relaxed(addr) >> (shift)) & (mask))
-
-#define SET_FIELD(addr, mask, shift, v) \
-do { \
-	int t = readl_relaxed(addr); \
-	writel_relaxed((t & ~((mask) << (shift))) + (((v) & \
-		       (mask)) << (shift)), addr);\
-} while (0)
-
-
-#define NUM_FL_PTE	4096
-#define NUM_SL_PTE	256
-#define NUM_TEX_CLASS	8
-
-/* First-level page table bits */
-#define FL_BASE_MASK		0xFFFFFC00
-#define FL_TYPE_TABLE		(1 << 0)
-#define FL_TYPE_SECT		(2 << 0)
-#define FL_SUPERSECTION		(1 << 18)
-#define FL_AP0			(1 << 10)
-#define FL_AP1			(1 << 11)
-#define FL_AP2			(1 << 15)
-#define FL_SHARED		(1 << 16)
-#define FL_BUFFERABLE		(1 << 2)
-#define FL_CACHEABLE		(1 << 3)
-#define FL_TEX0			(1 << 12)
-#define FL_OFFSET(va)		(((va) & 0xFFF00000) >> 20)
-#define FL_NG			(1 << 17)
-
-/* Second-level page table bits */
-#define SL_BASE_MASK_LARGE	0xFFFF0000
-#define SL_BASE_MASK_SMALL	0xFFFFF000
-#define SL_TYPE_LARGE		(1 << 0)
-#define SL_TYPE_SMALL		(2 << 0)
-#define SL_AP0			(1 << 4)
-#define SL_AP1			(2 << 4)
-#define SL_AP2			(1 << 9)
-#define SL_SHARED		(1 << 10)
-#define SL_BUFFERABLE		(1 << 2)
-#define SL_CACHEABLE		(1 << 3)
-#define SL_TEX0			(1 << 6)
-#define SL_OFFSET(va)		(((va) & 0xFF000) >> 12)
-#define SL_NG			(1 << 11)
-
-/* Memory type and cache policy attributes */
-#define MT_SO			0
-#define MT_DEV			1
-#define MT_NORMAL		2
-#define CP_NONCACHED		0
-#define CP_WB_WA		1
-#define CP_WT			2
-#define CP_WB_NWA		3
-
-/* Global register setters / getters */
-#define SET_M2VCBR_N(b, N, v)	 SET_GLOBAL_REG_N(M2VCBR_N, N, (b), (v))
-#define SET_CBACR_N(b, N, v)	 SET_GLOBAL_REG_N(CBACR_N, N, (b), (v))
-#define SET_TLBRSW(b, v)	 SET_GLOBAL_REG(TLBRSW, (b), (v))
-#define SET_TLBTR0(b, v)	 SET_GLOBAL_REG(TLBTR0, (b), (v))
-#define SET_TLBTR1(b, v)	 SET_GLOBAL_REG(TLBTR1, (b), (v))
-#define SET_TLBTR2(b, v)	 SET_GLOBAL_REG(TLBTR2, (b), (v))
-#define SET_TESTBUSCR(b, v)	 SET_GLOBAL_REG(TESTBUSCR, (b), (v))
-#define SET_GLOBAL_TLBIALL(b, v) SET_GLOBAL_REG(GLOBAL_TLBIALL, (b), (v))
-#define SET_TLBIVMID(b, v)	 SET_GLOBAL_REG(TLBIVMID, (b), (v))
-#define SET_CR(b, v)		 SET_GLOBAL_REG(CR, (b), (v))
-#define SET_EAR(b, v)		 SET_GLOBAL_REG(EAR, (b), (v))
-#define SET_ESR(b, v)		 SET_GLOBAL_REG(ESR, (b), (v))
-#define SET_ESRRESTORE(b, v)	 SET_GLOBAL_REG(ESRRESTORE, (b), (v))
-#define SET_ESYNR0(b, v)	 SET_GLOBAL_REG(ESYNR0, (b), (v))
-#define SET_ESYNR1(b, v)	 SET_GLOBAL_REG(ESYNR1, (b), (v))
-#define SET_RPU_ACR(b, v)	 SET_GLOBAL_REG(RPU_ACR, (b), (v))
-
-#define GET_M2VCBR_N(b, N)	 GET_GLOBAL_REG_N(M2VCBR_N, N, (b))
-#define GET_CBACR_N(b, N)	 GET_GLOBAL_REG_N(CBACR_N, N, (b))
-#define GET_TLBTR0(b)		 GET_GLOBAL_REG(TLBTR0, (b))
-#define GET_TLBTR1(b)		 GET_GLOBAL_REG(TLBTR1, (b))
-#define GET_TLBTR2(b)		 GET_GLOBAL_REG(TLBTR2, (b))
-#define GET_TESTBUSCR(b)	 GET_GLOBAL_REG(TESTBUSCR, (b))
-#define GET_GLOBAL_TLBIALL(b)	 GET_GLOBAL_REG(GLOBAL_TLBIALL, (b))
-#define GET_TLBIVMID(b)		 GET_GLOBAL_REG(TLBIVMID, (b))
-#define GET_CR(b)		 GET_GLOBAL_REG(CR, (b))
-#define GET_EAR(b)		 GET_GLOBAL_REG(EAR, (b))
-#define GET_ESR(b)		 GET_GLOBAL_REG(ESR, (b))
-#define GET_ESRRESTORE(b)	 GET_GLOBAL_REG(ESRRESTORE, (b))
-#define GET_ESYNR0(b)		 GET_GLOBAL_REG(ESYNR0, (b))
-#define GET_ESYNR1(b)		 GET_GLOBAL_REG(ESYNR1, (b))
-#define GET_REV(b)		 GET_GLOBAL_REG(REV, (b))
-#define GET_IDR(b)		 GET_GLOBAL_REG(IDR, (b))
-#define GET_RPU_ACR(b)		 GET_GLOBAL_REG(RPU_ACR, (b))
-
-
-/* Context register setters/getters */
-#define SET_SCTLR(b, c, v)	 SET_CTX_REG(SCTLR, (b), (c), (v))
-#define SET_ACTLR(b, c, v)	 SET_CTX_REG(ACTLR, (b), (c), (v))
-#define SET_CONTEXTIDR(b, c, v)	 SET_CTX_REG(CONTEXTIDR, (b), (c), (v))
-#define SET_TTBR0(b, c, v)	 SET_CTX_REG(TTBR0, (b), (c), (v))
-#define SET_TTBR1(b, c, v)	 SET_CTX_REG(TTBR1, (b), (c), (v))
-#define SET_TTBCR(b, c, v)	 SET_CTX_REG(TTBCR, (b), (c), (v))
-#define SET_PAR(b, c, v)	 SET_CTX_REG(PAR, (b), (c), (v))
-#define SET_FSR(b, c, v)	 SET_CTX_REG(FSR, (b), (c), (v))
-#define SET_FSRRESTORE(b, c, v)	 SET_CTX_REG(FSRRESTORE, (b), (c), (v))
-#define SET_FAR(b, c, v)	 SET_CTX_REG(FAR, (b), (c), (v))
-#define SET_FSYNR0(b, c, v)	 SET_CTX_REG(FSYNR0, (b), (c), (v))
-#define SET_FSYNR1(b, c, v)	 SET_CTX_REG(FSYNR1, (b), (c), (v))
-#define SET_PRRR(b, c, v)	 SET_CTX_REG(PRRR, (b), (c), (v))
-#define SET_NMRR(b, c, v)	 SET_CTX_REG(NMRR, (b), (c), (v))
-#define SET_TLBLKCR(b, c, v)	 SET_CTX_REG(TLBLCKR, (b), (c), (v))
-#define SET_V2PSR(b, c, v)	 SET_CTX_REG(V2PSR, (b), (c), (v))
-#define SET_TLBFLPTER(b, c, v)	 SET_CTX_REG(TLBFLPTER, (b), (c), (v))
-#define SET_TLBSLPTER(b, c, v)	 SET_CTX_REG(TLBSLPTER, (b), (c), (v))
-#define SET_BFBCR(b, c, v)	 SET_CTX_REG(BFBCR, (b), (c), (v))
-#define SET_CTX_TLBIALL(b, c, v) SET_CTX_REG(CTX_TLBIALL, (b), (c), (v))
-#define SET_TLBIASID(b, c, v)	 SET_CTX_REG(TLBIASID, (b), (c), (v))
-#define SET_TLBIVA(b, c, v)	 SET_CTX_REG(TLBIVA, (b), (c), (v))
-#define SET_TLBIVAA(b, c, v)	 SET_CTX_REG(TLBIVAA, (b), (c), (v))
-#define SET_V2PPR(b, c, v)	 SET_CTX_REG(V2PPR, (b), (c), (v))
-#define SET_V2PPW(b, c, v)	 SET_CTX_REG(V2PPW, (b), (c), (v))
-#define SET_V2PUR(b, c, v)	 SET_CTX_REG(V2PUR, (b), (c), (v))
-#define SET_V2PUW(b, c, v)	 SET_CTX_REG(V2PUW, (b), (c), (v))
-#define SET_RESUME(b, c, v)	 SET_CTX_REG(RESUME, (b), (c), (v))
-
-#define GET_SCTLR(b, c)		 GET_CTX_REG(SCTLR, (b), (c))
-#define GET_ACTLR(b, c)		 GET_CTX_REG(ACTLR, (b), (c))
-#define GET_CONTEXTIDR(b, c)	 GET_CTX_REG(CONTEXTIDR, (b), (c))
-#define GET_TTBR0(b, c)		 GET_CTX_REG(TTBR0, (b), (c))
-#define GET_TTBR1(b, c)		 GET_CTX_REG(TTBR1, (b), (c))
-#define GET_TTBCR(b, c)		 GET_CTX_REG(TTBCR, (b), (c))
-#define GET_PAR(b, c)		 GET_CTX_REG(PAR, (b), (c))
-#define GET_FSR(b, c)		 GET_CTX_REG(FSR, (b), (c))
-#define GET_FSRRESTORE(b, c)	 GET_CTX_REG(FSRRESTORE, (b), (c))
-#define GET_FAR(b, c)		 GET_CTX_REG(FAR, (b), (c))
-#define GET_FSYNR0(b, c)	 GET_CTX_REG(FSYNR0, (b), (c))
-#define GET_FSYNR1(b, c)	 GET_CTX_REG(FSYNR1, (b), (c))
-#define GET_PRRR(b, c)		 GET_CTX_REG(PRRR, (b), (c))
-#define GET_NMRR(b, c)		 GET_CTX_REG(NMRR, (b), (c))
-#define GET_TLBLCKR(b, c)	 GET_CTX_REG(TLBLCKR, (b), (c))
-#define GET_V2PSR(b, c)		 GET_CTX_REG(V2PSR, (b), (c))
-#define GET_TLBFLPTER(b, c)	 GET_CTX_REG(TLBFLPTER, (b), (c))
-#define GET_TLBSLPTER(b, c)	 GET_CTX_REG(TLBSLPTER, (b), (c))
-#define GET_BFBCR(b, c)		 GET_CTX_REG(BFBCR, (b), (c))
-#define GET_CTX_TLBIALL(b, c)	 GET_CTX_REG(CTX_TLBIALL, (b), (c))
-#define GET_TLBIASID(b, c)	 GET_CTX_REG(TLBIASID, (b), (c))
-#define GET_TLBIVA(b, c)	 GET_CTX_REG(TLBIVA, (b), (c))
-#define GET_TLBIVAA(b, c)	 GET_CTX_REG(TLBIVAA, (b), (c))
-#define GET_V2PPR(b, c)		 GET_CTX_REG(V2PPR, (b), (c))
-#define GET_V2PPW(b, c)		 GET_CTX_REG(V2PPW, (b), (c))
-#define GET_V2PUR(b, c)		 GET_CTX_REG(V2PUR, (b), (c))
-#define GET_V2PUW(b, c)		 GET_CTX_REG(V2PUW, (b), (c))
-#define GET_RESUME(b, c)	 GET_CTX_REG(RESUME, (b), (c))
-
-
-/* Global field setters / getters */
-/* Global Field Setters: */
-/* CBACR_N */
-#define SET_RWVMID(b, n, v)   SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWVMID, v)
-#define SET_RWE(b, n, v)      SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWE, v)
-#define SET_RWGE(b, n, v)     SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWGE, v)
-#define SET_CBVMID(b, n, v)   SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), CBVMID, v)
-#define SET_IRPTNDX(b, n, v)  SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), IRPTNDX, v)
-
-
-/* M2VCBR_N */
-#define SET_VMID(b, n, v)     SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), VMID, v)
-#define SET_CBNDX(b, n, v)    SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), CBNDX, v)
-#define SET_BYPASSD(b, n, v)  SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BYPASSD, v)
-#define SET_BPRCOSH(b, n, v)  SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCOSH, v)
-#define SET_BPRCISH(b, n, v)  SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCISH, v)
-#define SET_BPRCNSH(b, n, v)  SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCNSH, v)
-#define SET_BPSHCFG(b, n, v)  SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPSHCFG, v)
-#define SET_NSCFG(b, n, v)    SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), NSCFG, v)
-#define SET_BPMTCFG(b, n, v)  SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPMTCFG, v)
-#define SET_BPMEMTYPE(b, n, v) \
-	SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPMEMTYPE, v)
-
-
-/* CR */
-#define SET_RPUE(b, v)		 SET_GLOBAL_FIELD(b, CR, RPUE, v)
-#define SET_RPUERE(b, v)	 SET_GLOBAL_FIELD(b, CR, RPUERE, v)
-#define SET_RPUEIE(b, v)	 SET_GLOBAL_FIELD(b, CR, RPUEIE, v)
-#define SET_DCDEE(b, v)		 SET_GLOBAL_FIELD(b, CR, DCDEE, v)
-#define SET_CLIENTPD(b, v)       SET_GLOBAL_FIELD(b, CR, CLIENTPD, v)
-#define SET_STALLD(b, v)	 SET_GLOBAL_FIELD(b, CR, STALLD, v)
-#define SET_TLBLKCRWE(b, v)      SET_GLOBAL_FIELD(b, CR, TLBLKCRWE, v)
-#define SET_CR_TLBIALLCFG(b, v)  SET_GLOBAL_FIELD(b, CR, CR_TLBIALLCFG, v)
-#define SET_TLBIVMIDCFG(b, v)    SET_GLOBAL_FIELD(b, CR, TLBIVMIDCFG, v)
-#define SET_CR_HUME(b, v)        SET_GLOBAL_FIELD(b, CR, CR_HUME, v)
-
-
-/* ESR */
-#define SET_CFG(b, v)		 SET_GLOBAL_FIELD(b, ESR, CFG, v)
-#define SET_BYPASS(b, v)	 SET_GLOBAL_FIELD(b, ESR, BYPASS, v)
-#define SET_ESR_MULTI(b, v)      SET_GLOBAL_FIELD(b, ESR, ESR_MULTI, v)
-
-
-/* ESYNR0 */
-#define SET_ESYNR0_AMID(b, v)    SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_AMID, v)
-#define SET_ESYNR0_APID(b, v)    SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_APID, v)
-#define SET_ESYNR0_ABID(b, v)    SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_ABID, v)
-#define SET_ESYNR0_AVMID(b, v)   SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_AVMID, v)
-#define SET_ESYNR0_ATID(b, v)    SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_ATID, v)
-
-
-/* ESYNR1 */
-#define SET_ESYNR1_AMEMTYPE(b, v) \
-			SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AMEMTYPE, v)
-#define SET_ESYNR1_ASHARED(b, v)  SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ASHARED, v)
-#define SET_ESYNR1_AINNERSHARED(b, v) \
-			SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AINNERSHARED, v)
-#define SET_ESYNR1_APRIV(b, v)   SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_APRIV, v)
-#define SET_ESYNR1_APROTNS(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_APROTNS, v)
-#define SET_ESYNR1_AINST(b, v)   SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AINST, v)
-#define SET_ESYNR1_AWRITE(b, v)  SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AWRITE, v)
-#define SET_ESYNR1_ABURST(b, v)  SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ABURST, v)
-#define SET_ESYNR1_ALEN(b, v)    SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ALEN, v)
-#define SET_ESYNR1_ASIZE(b, v)   SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ASIZE, v)
-#define SET_ESYNR1_ALOCK(b, v)   SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ALOCK, v)
-#define SET_ESYNR1_AOOO(b, v)    SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AOOO, v)
-#define SET_ESYNR1_AFULL(b, v)   SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AFULL, v)
-#define SET_ESYNR1_AC(b, v)      SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AC, v)
-#define SET_ESYNR1_DCD(b, v)     SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_DCD, v)
-
-
-/* TESTBUSCR */
-#define SET_TBE(b, v)		 SET_GLOBAL_FIELD(b, TESTBUSCR, TBE, v)
-#define SET_SPDMBE(b, v)	 SET_GLOBAL_FIELD(b, TESTBUSCR, SPDMBE, v)
-#define SET_WGSEL(b, v)		 SET_GLOBAL_FIELD(b, TESTBUSCR, WGSEL, v)
-#define SET_TBLSEL(b, v)	 SET_GLOBAL_FIELD(b, TESTBUSCR, TBLSEL, v)
-#define SET_TBHSEL(b, v)	 SET_GLOBAL_FIELD(b, TESTBUSCR, TBHSEL, v)
-#define SET_SPDM0SEL(b, v)       SET_GLOBAL_FIELD(b, TESTBUSCR, SPDM0SEL, v)
-#define SET_SPDM1SEL(b, v)       SET_GLOBAL_FIELD(b, TESTBUSCR, SPDM1SEL, v)
-#define SET_SPDM2SEL(b, v)       SET_GLOBAL_FIELD(b, TESTBUSCR, SPDM2SEL, v)
-#define SET_SPDM3SEL(b, v)       SET_GLOBAL_FIELD(b, TESTBUSCR, SPDM3SEL, v)
-
-
-/* TLBIVMID */
-#define SET_TLBIVMID_VMID(b, v)  SET_GLOBAL_FIELD(b, TLBIVMID, TLBIVMID_VMID, v)
-
-
-/* TLBRSW */
-#define SET_TLBRSW_INDEX(b, v)   SET_GLOBAL_FIELD(b, TLBRSW, TLBRSW_INDEX, v)
-#define SET_TLBBFBS(b, v)	 SET_GLOBAL_FIELD(b, TLBRSW, TLBBFBS, v)
-
-
-/* TLBTR0 */
-#define SET_PR(b, v)		 SET_GLOBAL_FIELD(b, TLBTR0, PR, v)
-#define SET_PW(b, v)		 SET_GLOBAL_FIELD(b, TLBTR0, PW, v)
-#define SET_UR(b, v)		 SET_GLOBAL_FIELD(b, TLBTR0, UR, v)
-#define SET_UW(b, v)		 SET_GLOBAL_FIELD(b, TLBTR0, UW, v)
-#define SET_XN(b, v)		 SET_GLOBAL_FIELD(b, TLBTR0, XN, v)
-#define SET_NSDESC(b, v)	 SET_GLOBAL_FIELD(b, TLBTR0, NSDESC, v)
-#define SET_ISH(b, v)		 SET_GLOBAL_FIELD(b, TLBTR0, ISH, v)
-#define SET_SH(b, v)		 SET_GLOBAL_FIELD(b, TLBTR0, SH, v)
-#define SET_MT(b, v)		 SET_GLOBAL_FIELD(b, TLBTR0, MT, v)
-#define SET_DPSIZR(b, v)	 SET_GLOBAL_FIELD(b, TLBTR0, DPSIZR, v)
-#define SET_DPSIZC(b, v)	 SET_GLOBAL_FIELD(b, TLBTR0, DPSIZC, v)
-
-
-/* TLBTR1 */
-#define SET_TLBTR1_VMID(b, v)    SET_GLOBAL_FIELD(b, TLBTR1, TLBTR1_VMID, v)
-#define SET_TLBTR1_PA(b, v)      SET_GLOBAL_FIELD(b, TLBTR1, TLBTR1_PA, v)
-
-
-/* TLBTR2 */
-#define SET_TLBTR2_ASID(b, v)    SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_ASID, v)
-#define SET_TLBTR2_V(b, v)       SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_V, v)
-#define SET_TLBTR2_NSTID(b, v)   SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_NSTID, v)
-#define SET_TLBTR2_NV(b, v)      SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_NV, v)
-#define SET_TLBTR2_VA(b, v)      SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_VA, v)
-
-
-/* Global Field Getters */
-/* CBACR_N */
-#define GET_RWVMID(b, n)	 GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWVMID)
-#define GET_RWE(b, n)		 GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWE)
-#define GET_RWGE(b, n)		 GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWGE)
-#define GET_CBVMID(b, n)	 GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), CBVMID)
-#define GET_IRPTNDX(b, n)	 GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), IRPTNDX)
-
-
-/* M2VCBR_N */
-#define GET_VMID(b, n)       GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), VMID)
-#define GET_CBNDX(b, n)      GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), CBNDX)
-#define GET_BYPASSD(b, n)    GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BYPASSD)
-#define GET_BPRCOSH(b, n)    GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCOSH)
-#define GET_BPRCISH(b, n)    GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCISH)
-#define GET_BPRCNSH(b, n)    GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCNSH)
-#define GET_BPSHCFG(b, n)    GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPSHCFG)
-#define GET_NSCFG(b, n)      GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), NSCFG)
-#define GET_BPMTCFG(b, n)    GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPMTCFG)
-#define GET_BPMEMTYPE(b, n)  GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPMEMTYPE)
-
-
-/* CR */
-#define GET_RPUE(b)		 GET_GLOBAL_FIELD(b, CR, RPUE)
-#define GET_RPUERE(b)		 GET_GLOBAL_FIELD(b, CR, RPUERE)
-#define GET_RPUEIE(b)		 GET_GLOBAL_FIELD(b, CR, RPUEIE)
-#define GET_DCDEE(b)		 GET_GLOBAL_FIELD(b, CR, DCDEE)
-#define GET_CLIENTPD(b)		 GET_GLOBAL_FIELD(b, CR, CLIENTPD)
-#define GET_STALLD(b)		 GET_GLOBAL_FIELD(b, CR, STALLD)
-#define GET_TLBLKCRWE(b)	 GET_GLOBAL_FIELD(b, CR, TLBLKCRWE)
-#define GET_CR_TLBIALLCFG(b)	 GET_GLOBAL_FIELD(b, CR, CR_TLBIALLCFG)
-#define GET_TLBIVMIDCFG(b)	 GET_GLOBAL_FIELD(b, CR, TLBIVMIDCFG)
-#define GET_CR_HUME(b)		 GET_GLOBAL_FIELD(b, CR, CR_HUME)
-
-
-/* ESR */
-#define GET_CFG(b)		 GET_GLOBAL_FIELD(b, ESR, CFG)
-#define GET_BYPASS(b)		 GET_GLOBAL_FIELD(b, ESR, BYPASS)
-#define GET_ESR_MULTI(b)	 GET_GLOBAL_FIELD(b, ESR, ESR_MULTI)
-
-
-/* ESYNR0 */
-#define GET_ESYNR0_AMID(b)	 GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_AMID)
-#define GET_ESYNR0_APID(b)	 GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_APID)
-#define GET_ESYNR0_ABID(b)	 GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_ABID)
-#define GET_ESYNR0_AVMID(b)	 GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_AVMID)
-#define GET_ESYNR0_ATID(b)	 GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_ATID)
-
-
-/* ESYNR1 */
-#define GET_ESYNR1_AMEMTYPE(b)   GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AMEMTYPE)
-#define GET_ESYNR1_ASHARED(b)    GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ASHARED)
-#define GET_ESYNR1_AINNERSHARED(b) \
-			GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AINNERSHARED)
-#define GET_ESYNR1_APRIV(b)      GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_APRIV)
-#define GET_ESYNR1_APROTNS(b)	 GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_APROTNS)
-#define GET_ESYNR1_AINST(b)	 GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AINST)
-#define GET_ESYNR1_AWRITE(b)	 GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AWRITE)
-#define GET_ESYNR1_ABURST(b)	 GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ABURST)
-#define GET_ESYNR1_ALEN(b)	 GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ALEN)
-#define GET_ESYNR1_ASIZE(b)	 GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ASIZE)
-#define GET_ESYNR1_ALOCK(b)	 GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ALOCK)
-#define GET_ESYNR1_AOOO(b)	 GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AOOO)
-#define GET_ESYNR1_AFULL(b)	 GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AFULL)
-#define GET_ESYNR1_AC(b)	 GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AC)
-#define GET_ESYNR1_DCD(b)	 GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_DCD)
-
-
-/* IDR */
-#define GET_NM2VCBMT(b)		 GET_GLOBAL_FIELD(b, IDR, NM2VCBMT)
-#define GET_HTW(b)		 GET_GLOBAL_FIELD(b, IDR, HTW)
-#define GET_HUM(b)		 GET_GLOBAL_FIELD(b, IDR, HUM)
-#define GET_TLBSIZE(b)		 GET_GLOBAL_FIELD(b, IDR, TLBSIZE)
-#define GET_NCB(b)		 GET_GLOBAL_FIELD(b, IDR, NCB)
-#define GET_NIRPT(b)		 GET_GLOBAL_FIELD(b, IDR, NIRPT)
-
-
-/* REV */
-#define GET_MAJOR(b)		 GET_GLOBAL_FIELD(b, REV, MAJOR)
-#define GET_MINOR(b)		 GET_GLOBAL_FIELD(b, REV, MINOR)
-
-
-/* TESTBUSCR */
-#define GET_TBE(b)		 GET_GLOBAL_FIELD(b, TESTBUSCR, TBE)
-#define GET_SPDMBE(b)		 GET_GLOBAL_FIELD(b, TESTBUSCR, SPDMBE)
-#define GET_WGSEL(b)		 GET_GLOBAL_FIELD(b, TESTBUSCR, WGSEL)
-#define GET_TBLSEL(b)		 GET_GLOBAL_FIELD(b, TESTBUSCR, TBLSEL)
-#define GET_TBHSEL(b)		 GET_GLOBAL_FIELD(b, TESTBUSCR, TBHSEL)
-#define GET_SPDM0SEL(b)		 GET_GLOBAL_FIELD(b, TESTBUSCR, SPDM0SEL)
-#define GET_SPDM1SEL(b)		 GET_GLOBAL_FIELD(b, TESTBUSCR, SPDM1SEL)
-#define GET_SPDM2SEL(b)		 GET_GLOBAL_FIELD(b, TESTBUSCR, SPDM2SEL)
-#define GET_SPDM3SEL(b)		 GET_GLOBAL_FIELD(b, TESTBUSCR, SPDM3SEL)
-
-
-/* TLBIVMID */
-#define GET_TLBIVMID_VMID(b)	 GET_GLOBAL_FIELD(b, TLBIVMID, TLBIVMID_VMID)
-
-
-/* TLBTR0 */
-#define GET_PR(b)		 GET_GLOBAL_FIELD(b, TLBTR0, PR)
-#define GET_PW(b)		 GET_GLOBAL_FIELD(b, TLBTR0, PW)
-#define GET_UR(b)		 GET_GLOBAL_FIELD(b, TLBTR0, UR)
-#define GET_UW(b)		 GET_GLOBAL_FIELD(b, TLBTR0, UW)
-#define GET_XN(b)		 GET_GLOBAL_FIELD(b, TLBTR0, XN)
-#define GET_NSDESC(b)		 GET_GLOBAL_FIELD(b, TLBTR0, NSDESC)
-#define GET_ISH(b)		 GET_GLOBAL_FIELD(b, TLBTR0, ISH)
-#define GET_SH(b)		 GET_GLOBAL_FIELD(b, TLBTR0, SH)
-#define GET_MT(b)		 GET_GLOBAL_FIELD(b, TLBTR0, MT)
-#define GET_DPSIZR(b)		 GET_GLOBAL_FIELD(b, TLBTR0, DPSIZR)
-#define GET_DPSIZC(b)		 GET_GLOBAL_FIELD(b, TLBTR0, DPSIZC)
-
-
-/* TLBTR1 */
-#define GET_TLBTR1_VMID(b)	 GET_GLOBAL_FIELD(b, TLBTR1, TLBTR1_VMID)
-#define GET_TLBTR1_PA(b)	 GET_GLOBAL_FIELD(b, TLBTR1, TLBTR1_PA)
-
-
-/* TLBTR2 */
-#define GET_TLBTR2_ASID(b)	 GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_ASID)
-#define GET_TLBTR2_V(b)		 GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_V)
-#define GET_TLBTR2_NSTID(b)	 GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_NSTID)
-#define GET_TLBTR2_NV(b)	 GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_NV)
-#define GET_TLBTR2_VA(b)	 GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_VA)
-
-
-/* Context Register setters / getters */
-/* Context Register setters */
-/* ACTLR */
-#define SET_CFERE(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, CFERE, v)
-#define SET_CFEIE(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, CFEIE, v)
-#define SET_PTSHCFG(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, PTSHCFG, v)
-#define SET_RCOSH(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, RCOSH, v)
-#define SET_RCISH(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, RCISH, v)
-#define SET_RCNSH(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, RCNSH, v)
-#define SET_PRIVCFG(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, PRIVCFG, v)
-#define SET_DNA(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, DNA, v)
-#define SET_DNLV2PA(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, DNLV2PA, v)
-#define SET_TLBMCFG(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, TLBMCFG, v)
-#define SET_CFCFG(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, CFCFG, v)
-#define SET_TIPCF(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, TIPCF, v)
-#define SET_V2PCFG(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, V2PCFG, v)
-#define SET_HUME(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, HUME, v)
-#define SET_PTMTCFG(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, PTMTCFG, v)
-#define SET_PTMEMTYPE(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, PTMEMTYPE, v)
-
-
-/* BFBCR */
-#define SET_BFBDFE(b, c, v)	 SET_CONTEXT_FIELD(b, c, BFBCR, BFBDFE, v)
-#define SET_BFBSFE(b, c, v)	 SET_CONTEXT_FIELD(b, c, BFBCR, BFBSFE, v)
-#define SET_SFVS(b, c, v)	 SET_CONTEXT_FIELD(b, c, BFBCR, SFVS, v)
-#define SET_FLVIC(b, c, v)	 SET_CONTEXT_FIELD(b, c, BFBCR, FLVIC, v)
-#define SET_SLVIC(b, c, v)	 SET_CONTEXT_FIELD(b, c, BFBCR, SLVIC, v)
-
-
-/* CONTEXTIDR */
-#define SET_CONTEXTIDR_ASID(b, c, v)   \
-		SET_CONTEXT_FIELD(b, c, CONTEXTIDR, CONTEXTIDR_ASID, v)
-#define SET_CONTEXTIDR_PROCID(b, c, v) \
-		SET_CONTEXT_FIELD(b, c, CONTEXTIDR, PROCID, v)
-
-
-/* FSR */
-#define SET_TF(b, c, v)		 SET_CONTEXT_FIELD(b, c, FSR, TF, v)
-#define SET_AFF(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSR, AFF, v)
-#define SET_APF(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSR, APF, v)
-#define SET_TLBMF(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSR, TLBMF, v)
-#define SET_HTWDEEF(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSR, HTWDEEF, v)
-#define SET_HTWSEEF(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSR, HTWSEEF, v)
-#define SET_MHF(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSR, MHF, v)
-#define SET_SL(b, c, v)		 SET_CONTEXT_FIELD(b, c, FSR, SL, v)
-#define SET_SS(b, c, v)		 SET_CONTEXT_FIELD(b, c, FSR, SS, v)
-#define SET_MULTI(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSR, MULTI, v)
-
-
-/* FSYNR0 */
-#define SET_AMID(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR0, AMID, v)
-#define SET_APID(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR0, APID, v)
-#define SET_ABID(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR0, ABID, v)
-#define SET_ATID(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR0, ATID, v)
-
-
-/* FSYNR1 */
-#define SET_AMEMTYPE(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR1, AMEMTYPE, v)
-#define SET_ASHARED(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR1, ASHARED, v)
-#define SET_AINNERSHARED(b, c, v)  \
-				SET_CONTEXT_FIELD(b, c, FSYNR1, AINNERSHARED, v)
-#define SET_APRIV(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR1, APRIV, v)
-#define SET_APROTNS(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR1, APROTNS, v)
-#define SET_AINST(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR1, AINST, v)
-#define SET_AWRITE(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR1, AWRITE, v)
-#define SET_ABURST(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR1, ABURST, v)
-#define SET_ALEN(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR1, ALEN, v)
-#define SET_FSYNR1_ASIZE(b, c, v) \
-				SET_CONTEXT_FIELD(b, c, FSYNR1, FSYNR1_ASIZE, v)
-#define SET_ALOCK(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR1, ALOCK, v)
-#define SET_AFULL(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR1, AFULL, v)
-
-
-/* NMRR */
-#define SET_ICPC0(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, ICPC0, v)
-#define SET_ICPC1(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, ICPC1, v)
-#define SET_ICPC2(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, ICPC2, v)
-#define SET_ICPC3(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, ICPC3, v)
-#define SET_ICPC4(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, ICPC4, v)
-#define SET_ICPC5(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, ICPC5, v)
-#define SET_ICPC6(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, ICPC6, v)
-#define SET_ICPC7(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, ICPC7, v)
-#define SET_OCPC0(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, OCPC0, v)
-#define SET_OCPC1(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, OCPC1, v)
-#define SET_OCPC2(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, OCPC2, v)
-#define SET_OCPC3(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, OCPC3, v)
-#define SET_OCPC4(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, OCPC4, v)
-#define SET_OCPC5(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, OCPC5, v)
-#define SET_OCPC6(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, OCPC6, v)
-#define SET_OCPC7(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, OCPC7, v)
-
-
-/* PAR */
-#define SET_FAULT(b, c, v)	 SET_CONTEXT_FIELD(b, c, PAR, FAULT, v)
-
-#define SET_FAULT_TF(b, c, v)	 SET_CONTEXT_FIELD(b, c, PAR, FAULT_TF, v)
-#define SET_FAULT_AFF(b, c, v)	 SET_CONTEXT_FIELD(b, c, PAR, FAULT_AFF, v)
-#define SET_FAULT_APF(b, c, v)	 SET_CONTEXT_FIELD(b, c, PAR, FAULT_APF, v)
-#define SET_FAULT_TLBMF(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, FAULT_TLBMF, v)
-#define SET_FAULT_HTWDEEF(b, c, v) \
-				SET_CONTEXT_FIELD(b, c, PAR, FAULT_HTWDEEF, v)
-#define SET_FAULT_HTWSEEF(b, c, v) \
-				SET_CONTEXT_FIELD(b, c, PAR, FAULT_HTWSEEF, v)
-#define SET_FAULT_MHF(b, c, v)	 SET_CONTEXT_FIELD(b, c, PAR, FAULT_MHF, v)
-#define SET_FAULT_SL(b, c, v)	 SET_CONTEXT_FIELD(b, c, PAR, FAULT_SL, v)
-#define SET_FAULT_SS(b, c, v)	 SET_CONTEXT_FIELD(b, c, PAR, FAULT_SS, v)
-
-#define SET_NOFAULT_SS(b, c, v)	 SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_SS, v)
-#define SET_NOFAULT_MT(b, c, v)	 SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_MT, v)
-#define SET_NOFAULT_SH(b, c, v)	 SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_SH, v)
-#define SET_NOFAULT_NS(b, c, v)	 SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_NS, v)
-#define SET_NOFAULT_NOS(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_NOS, v)
-#define SET_NPFAULT_PA(b, c, v)	 SET_CONTEXT_FIELD(b, c, PAR, NPFAULT_PA, v)
-
-
-/* PRRR */
-#define SET_MTC0(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, MTC0, v)
-#define SET_MTC1(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, MTC1, v)
-#define SET_MTC2(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, MTC2, v)
-#define SET_MTC3(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, MTC3, v)
-#define SET_MTC4(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, MTC4, v)
-#define SET_MTC5(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, MTC5, v)
-#define SET_MTC6(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, MTC6, v)
-#define SET_MTC7(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, MTC7, v)
-#define SET_SHDSH0(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, SHDSH0, v)
-#define SET_SHDSH1(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, SHDSH1, v)
-#define SET_SHNMSH0(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, SHNMSH0, v)
-#define SET_SHNMSH1(b, c, v)     SET_CONTEXT_FIELD(b, c, PRRR, SHNMSH1, v)
-#define SET_NOS0(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, NOS0, v)
-#define SET_NOS1(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, NOS1, v)
-#define SET_NOS2(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, NOS2, v)
-#define SET_NOS3(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, NOS3, v)
-#define SET_NOS4(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, NOS4, v)
-#define SET_NOS5(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, NOS5, v)
-#define SET_NOS6(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, NOS6, v)
-#define SET_NOS7(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, NOS7, v)
-
-
-/* RESUME */
-#define SET_TNR(b, c, v)	 SET_CONTEXT_FIELD(b, c, RESUME, TNR, v)
-
-
-/* SCTLR */
-#define SET_M(b, c, v)		 SET_CONTEXT_FIELD(b, c, SCTLR, M, v)
-#define SET_TRE(b, c, v)	 SET_CONTEXT_FIELD(b, c, SCTLR, TRE, v)
-#define SET_AFE(b, c, v)	 SET_CONTEXT_FIELD(b, c, SCTLR, AFE, v)
-#define SET_HAF(b, c, v)	 SET_CONTEXT_FIELD(b, c, SCTLR, HAF, v)
-#define SET_BE(b, c, v)		 SET_CONTEXT_FIELD(b, c, SCTLR, BE, v)
-#define SET_AFFD(b, c, v)	 SET_CONTEXT_FIELD(b, c, SCTLR, AFFD, v)
-
-
-/* TLBLKCR */
-#define SET_LKE(b, c, v)	   SET_CONTEXT_FIELD(b, c, TLBLKCR, LKE, v)
-#define SET_TLBLKCR_TLBIALLCFG(b, c, v) \
-			SET_CONTEXT_FIELD(b, c, TLBLKCR, TLBLCKR_TLBIALLCFG, v)
-#define SET_TLBIASIDCFG(b, c, v) \
-			SET_CONTEXT_FIELD(b, c, TLBLKCR, TLBIASIDCFG, v)
-#define SET_TLBIVAACFG(b, c, v)	SET_CONTEXT_FIELD(b, c, TLBLKCR, TLBIVAACFG, v)
-#define SET_FLOOR(b, c, v)	SET_CONTEXT_FIELD(b, c, TLBLKCR, FLOOR, v)
-#define SET_VICTIM(b, c, v)	SET_CONTEXT_FIELD(b, c, TLBLKCR, VICTIM, v)
-
-
-/* TTBCR */
-#define SET_N(b, c, v)	         SET_CONTEXT_FIELD(b, c, TTBCR, N, v)
-#define SET_PD0(b, c, v)	 SET_CONTEXT_FIELD(b, c, TTBCR, PD0, v)
-#define SET_PD1(b, c, v)	 SET_CONTEXT_FIELD(b, c, TTBCR, PD1, v)
-
-
-/* TTBR0 */
-#define SET_TTBR0_IRGNH(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_IRGNH, v)
-#define SET_TTBR0_SH(b, c, v)	 SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_SH, v)
-#define SET_TTBR0_ORGN(b, c, v)	 SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_ORGN, v)
-#define SET_TTBR0_NOS(b, c, v)	 SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_NOS, v)
-#define SET_TTBR0_IRGNL(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_IRGNL, v)
-#define SET_TTBR0_PA(b, c, v)	 SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_PA, v)
-
-
-/* TTBR1 */
-#define SET_TTBR1_IRGNH(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_IRGNH, v)
-#define SET_TTBR1_SH(b, c, v)	 SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_SH, v)
-#define SET_TTBR1_ORGN(b, c, v)	 SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_ORGN, v)
-#define SET_TTBR1_NOS(b, c, v)	 SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_NOS, v)
-#define SET_TTBR1_IRGNL(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_IRGNL, v)
-#define SET_TTBR1_PA(b, c, v)	 SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_PA, v)
-
-
-/* V2PSR */
-#define SET_HIT(b, c, v)	 SET_CONTEXT_FIELD(b, c, V2PSR, HIT, v)
-#define SET_INDEX(b, c, v)	 SET_CONTEXT_FIELD(b, c, V2PSR, INDEX, v)
-
-
-/* Context Register getters */
-/* ACTLR */
-#define GET_CFERE(b, c)	        GET_CONTEXT_FIELD(b, c, ACTLR, CFERE)
-#define GET_CFEIE(b, c)	        GET_CONTEXT_FIELD(b, c, ACTLR, CFEIE)
-#define GET_PTSHCFG(b, c)       GET_CONTEXT_FIELD(b, c, ACTLR, PTSHCFG)
-#define GET_RCOSH(b, c)	        GET_CONTEXT_FIELD(b, c, ACTLR, RCOSH)
-#define GET_RCISH(b, c)	        GET_CONTEXT_FIELD(b, c, ACTLR, RCISH)
-#define GET_RCNSH(b, c)	        GET_CONTEXT_FIELD(b, c, ACTLR, RCNSH)
-#define GET_PRIVCFG(b, c)       GET_CONTEXT_FIELD(b, c, ACTLR, PRIVCFG)
-#define GET_DNA(b, c)	        GET_CONTEXT_FIELD(b, c, ACTLR, DNA)
-#define GET_DNLV2PA(b, c)       GET_CONTEXT_FIELD(b, c, ACTLR, DNLV2PA)
-#define GET_TLBMCFG(b, c)       GET_CONTEXT_FIELD(b, c, ACTLR, TLBMCFG)
-#define GET_CFCFG(b, c)	        GET_CONTEXT_FIELD(b, c, ACTLR, CFCFG)
-#define GET_TIPCF(b, c)	        GET_CONTEXT_FIELD(b, c, ACTLR, TIPCF)
-#define GET_V2PCFG(b, c)        GET_CONTEXT_FIELD(b, c, ACTLR, V2PCFG)
-#define GET_HUME(b, c)	        GET_CONTEXT_FIELD(b, c, ACTLR, HUME)
-#define GET_PTMTCFG(b, c)       GET_CONTEXT_FIELD(b, c, ACTLR, PTMTCFG)
-#define GET_PTMEMTYPE(b, c)     GET_CONTEXT_FIELD(b, c, ACTLR, PTMEMTYPE)
-
-/* BFBCR */
-#define GET_BFBDFE(b, c)	GET_CONTEXT_FIELD(b, c, BFBCR, BFBDFE)
-#define GET_BFBSFE(b, c)	GET_CONTEXT_FIELD(b, c, BFBCR, BFBSFE)
-#define GET_SFVS(b, c)		GET_CONTEXT_FIELD(b, c, BFBCR, SFVS)
-#define GET_FLVIC(b, c)		GET_CONTEXT_FIELD(b, c, BFBCR, FLVIC)
-#define GET_SLVIC(b, c)		GET_CONTEXT_FIELD(b, c, BFBCR, SLVIC)
-
-
-/* CONTEXTIDR */
-#define GET_CONTEXTIDR_ASID(b, c) \
-			GET_CONTEXT_FIELD(b, c, CONTEXTIDR, CONTEXTIDR_ASID)
-#define GET_CONTEXTIDR_PROCID(b, c) GET_CONTEXT_FIELD(b, c, CONTEXTIDR, PROCID)
-
-
-/* FSR */
-#define GET_TF(b, c)		GET_CONTEXT_FIELD(b, c, FSR, TF)
-#define GET_AFF(b, c)		GET_CONTEXT_FIELD(b, c, FSR, AFF)
-#define GET_APF(b, c)		GET_CONTEXT_FIELD(b, c, FSR, APF)
-#define GET_TLBMF(b, c)		GET_CONTEXT_FIELD(b, c, FSR, TLBMF)
-#define GET_HTWDEEF(b, c)	GET_CONTEXT_FIELD(b, c, FSR, HTWDEEF)
-#define GET_HTWSEEF(b, c)	GET_CONTEXT_FIELD(b, c, FSR, HTWSEEF)
-#define GET_MHF(b, c)		GET_CONTEXT_FIELD(b, c, FSR, MHF)
-#define GET_SL(b, c)		GET_CONTEXT_FIELD(b, c, FSR, SL)
-#define GET_SS(b, c)		GET_CONTEXT_FIELD(b, c, FSR, SS)
-#define GET_MULTI(b, c)		GET_CONTEXT_FIELD(b, c, FSR, MULTI)
-
-
-/* FSYNR0 */
-#define GET_AMID(b, c)		GET_CONTEXT_FIELD(b, c, FSYNR0, AMID)
-#define GET_APID(b, c)		GET_CONTEXT_FIELD(b, c, FSYNR0, APID)
-#define GET_ABID(b, c)		GET_CONTEXT_FIELD(b, c, FSYNR0, ABID)
-#define GET_ATID(b, c)		GET_CONTEXT_FIELD(b, c, FSYNR0, ATID)
-
-
-/* FSYNR1 */
-#define GET_AMEMTYPE(b, c)	GET_CONTEXT_FIELD(b, c, FSYNR1, AMEMTYPE)
-#define GET_ASHARED(b, c)	GET_CONTEXT_FIELD(b, c, FSYNR1, ASHARED)
-#define GET_AINNERSHARED(b, c)  GET_CONTEXT_FIELD(b, c, FSYNR1, AINNERSHARED)
-#define GET_APRIV(b, c)		GET_CONTEXT_FIELD(b, c, FSYNR1, APRIV)
-#define GET_APROTNS(b, c)	GET_CONTEXT_FIELD(b, c, FSYNR1, APROTNS)
-#define GET_AINST(b, c)		GET_CONTEXT_FIELD(b, c, FSYNR1, AINST)
-#define GET_AWRITE(b, c)	GET_CONTEXT_FIELD(b, c, FSYNR1, AWRITE)
-#define GET_ABURST(b, c)	GET_CONTEXT_FIELD(b, c, FSYNR1, ABURST)
-#define GET_ALEN(b, c)		GET_CONTEXT_FIELD(b, c, FSYNR1, ALEN)
-#define GET_FSYNR1_ASIZE(b, c)	GET_CONTEXT_FIELD(b, c, FSYNR1, FSYNR1_ASIZE)
-#define GET_ALOCK(b, c)		GET_CONTEXT_FIELD(b, c, FSYNR1, ALOCK)
-#define GET_AFULL(b, c)		GET_CONTEXT_FIELD(b, c, FSYNR1, AFULL)
-
-
-/* NMRR */
-#define GET_ICPC0(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, ICPC0)
-#define GET_ICPC1(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, ICPC1)
-#define GET_ICPC2(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, ICPC2)
-#define GET_ICPC3(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, ICPC3)
-#define GET_ICPC4(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, ICPC4)
-#define GET_ICPC5(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, ICPC5)
-#define GET_ICPC6(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, ICPC6)
-#define GET_ICPC7(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, ICPC7)
-#define GET_OCPC0(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, OCPC0)
-#define GET_OCPC1(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, OCPC1)
-#define GET_OCPC2(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, OCPC2)
-#define GET_OCPC3(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, OCPC3)
-#define GET_OCPC4(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, OCPC4)
-#define GET_OCPC5(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, OCPC5)
-#define GET_OCPC6(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, OCPC6)
-#define GET_OCPC7(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, OCPC7)
-#define NMRR_ICP(nmrr, n)	(((nmrr) & (3 << ((n) * 2))) >> ((n) * 2))
-#define NMRR_OCP(nmrr, n)	(((nmrr) & (3 << ((n) * 2 + 16))) >> \
-								((n) * 2 + 16))
-
-/* PAR */
-#define GET_FAULT(b, c)		GET_CONTEXT_FIELD(b, c, PAR, FAULT)
-
-#define GET_FAULT_TF(b, c)	GET_CONTEXT_FIELD(b, c, PAR, FAULT_TF)
-#define GET_FAULT_AFF(b, c)	GET_CONTEXT_FIELD(b, c, PAR, FAULT_AFF)
-#define GET_FAULT_APF(b, c)	GET_CONTEXT_FIELD(b, c, PAR, FAULT_APF)
-#define GET_FAULT_TLBMF(b, c)   GET_CONTEXT_FIELD(b, c, PAR, FAULT_TLBMF)
-#define GET_FAULT_HTWDEEF(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_HTWDEEF)
-#define GET_FAULT_HTWSEEF(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_HTWSEEF)
-#define GET_FAULT_MHF(b, c)	GET_CONTEXT_FIELD(b, c, PAR, FAULT_MHF)
-#define GET_FAULT_SL(b, c)	GET_CONTEXT_FIELD(b, c, PAR, FAULT_SL)
-#define GET_FAULT_SS(b, c)	GET_CONTEXT_FIELD(b, c, PAR, FAULT_SS)
-
-#define GET_NOFAULT_SS(b, c)	GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_SS)
-#define GET_NOFAULT_MT(b, c)	GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_MT)
-#define GET_NOFAULT_SH(b, c)	GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_SH)
-#define GET_NOFAULT_NS(b, c)	GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_NS)
-#define GET_NOFAULT_NOS(b, c)   GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_NOS)
-#define GET_NPFAULT_PA(b, c)	GET_CONTEXT_FIELD(b, c, PAR, PAR_NPFAULT_PA)
-
-
-/* PRRR */
-#define GET_MTC0(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, MTC0)
-#define GET_MTC1(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, MTC1)
-#define GET_MTC2(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, MTC2)
-#define GET_MTC3(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, MTC3)
-#define GET_MTC4(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, MTC4)
-#define GET_MTC5(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, MTC5)
-#define GET_MTC6(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, MTC6)
-#define GET_MTC7(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, MTC7)
-#define GET_SHDSH0(b, c)	GET_CONTEXT_FIELD(b, c, PRRR, SHDSH0)
-#define GET_SHDSH1(b, c)	GET_CONTEXT_FIELD(b, c, PRRR, SHDSH1)
-#define GET_SHNMSH0(b, c)	GET_CONTEXT_FIELD(b, c, PRRR, SHNMSH0)
-#define GET_SHNMSH1(b, c)	GET_CONTEXT_FIELD(b, c, PRRR, SHNMSH1)
-#define GET_NOS0(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, NOS0)
-#define GET_NOS1(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, NOS1)
-#define GET_NOS2(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, NOS2)
-#define GET_NOS3(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, NOS3)
-#define GET_NOS4(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, NOS4)
-#define GET_NOS5(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, NOS5)
-#define GET_NOS6(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, NOS6)
-#define GET_NOS7(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, NOS7)
-#define PRRR_NOS(prrr, n)	 ((prrr) & (1 << ((n) + 24)) ? 1 : 0)
-#define PRRR_MT(prrr, n)	 ((((prrr) & (3 << ((n) * 2))) >> ((n) * 2)))
-
-
-/* RESUME */
-#define GET_TNR(b, c)		GET_CONTEXT_FIELD(b, c, RESUME, TNR)
-
-
-/* SCTLR */
-#define GET_M(b, c)		GET_CONTEXT_FIELD(b, c, SCTLR, M)
-#define GET_TRE(b, c)		GET_CONTEXT_FIELD(b, c, SCTLR, TRE)
-#define GET_AFE(b, c)		GET_CONTEXT_FIELD(b, c, SCTLR, AFE)
-#define GET_HAF(b, c)		GET_CONTEXT_FIELD(b, c, SCTLR, HAF)
-#define GET_BE(b, c)		GET_CONTEXT_FIELD(b, c, SCTLR, BE)
-#define GET_AFFD(b, c)		GET_CONTEXT_FIELD(b, c, SCTLR, AFFD)
-
-
-/* TLBLKCR */
-#define GET_LKE(b, c)		GET_CONTEXT_FIELD(b, c, TLBLKCR, LKE)
-#define GET_TLBLCKR_TLBIALLCFG(b, c) \
-			GET_CONTEXT_FIELD(b, c, TLBLKCR, TLBLCKR_TLBIALLCFG)
-#define GET_TLBIASIDCFG(b, c)   GET_CONTEXT_FIELD(b, c, TLBLKCR, TLBIASIDCFG)
-#define GET_TLBIVAACFG(b, c)	GET_CONTEXT_FIELD(b, c, TLBLKCR, TLBIVAACFG)
-#define GET_FLOOR(b, c)		GET_CONTEXT_FIELD(b, c, TLBLKCR, FLOOR)
-#define GET_VICTIM(b, c)	GET_CONTEXT_FIELD(b, c, TLBLKCR, VICTIM)
-
-
-/* TTBCR */
-#define GET_N(b, c)		GET_CONTEXT_FIELD(b, c, TTBCR, N)
-#define GET_PD0(b, c)		GET_CONTEXT_FIELD(b, c, TTBCR, PD0)
-#define GET_PD1(b, c)		GET_CONTEXT_FIELD(b, c, TTBCR, PD1)
-
-
-/* TTBR0 */
-#define GET_TTBR0_IRGNH(b, c)	GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_IRGNH)
-#define GET_TTBR0_SH(b, c)	GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_SH)
-#define GET_TTBR0_ORGN(b, c)	GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_ORGN)
-#define GET_TTBR0_NOS(b, c)	GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_NOS)
-#define GET_TTBR0_IRGNL(b, c)	GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_IRGNL)
-#define GET_TTBR0_PA(b, c)	GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_PA)
-
-
-/* TTBR1 */
-#define GET_TTBR1_IRGNH(b, c)	GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_IRGNH)
-#define GET_TTBR1_SH(b, c)	GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_SH)
-#define GET_TTBR1_ORGN(b, c)	GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_ORGN)
-#define GET_TTBR1_NOS(b, c)	GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_NOS)
-#define GET_TTBR1_IRGNL(b, c)	GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_IRGNL)
-#define GET_TTBR1_PA(b, c)	GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_PA)
-
-
-/* V2PSR */
-#define GET_HIT(b, c)		GET_CONTEXT_FIELD(b, c, V2PSR, HIT)
-#define GET_INDEX(b, c)		GET_CONTEXT_FIELD(b, c, V2PSR, INDEX)
-
-
-/* Global Registers */
-#define M2VCBR_N	(0x000)
-#define CBACR_N		(0x800)
-#define TLBRSW		(0xE00)
-#define TLBTR0		(0xE80)
-#define TLBTR1		(0xE84)
-#define TLBTR2		(0xE88)
-#define TESTBUSCR	(0xE8C)
-#define GLOBAL_TLBIALL	(0xF00)
-#define TLBIVMID	(0xF04)
-#define CR		(0xF80)
-#define EAR		(0xF84)
-#define ESR		(0xF88)
-#define ESRRESTORE	(0xF8C)
-#define ESYNR0		(0xF90)
-#define ESYNR1		(0xF94)
-#define REV		(0xFF4)
-#define IDR		(0xFF8)
-#define RPU_ACR		(0xFFC)
-
-
-/* Context Bank Registers */
-#define SCTLR		(0x000)
-#define ACTLR		(0x004)
-#define CONTEXTIDR	(0x008)
-#define TTBR0		(0x010)
-#define TTBR1		(0x014)
-#define TTBCR		(0x018)
-#define PAR		(0x01C)
-#define FSR		(0x020)
-#define FSRRESTORE	(0x024)
-#define FAR		(0x028)
-#define FSYNR0		(0x02C)
-#define FSYNR1		(0x030)
-#define PRRR		(0x034)
-#define NMRR		(0x038)
-#define TLBLCKR		(0x03C)
-#define V2PSR		(0x040)
-#define TLBFLPTER	(0x044)
-#define TLBSLPTER	(0x048)
-#define BFBCR		(0x04C)
-#define CTX_TLBIALL	(0x800)
-#define TLBIASID	(0x804)
-#define TLBIVA		(0x808)
-#define TLBIVAA		(0x80C)
-#define V2PPR		(0x810)
-#define V2PPW		(0x814)
-#define V2PUR		(0x818)
-#define V2PUW		(0x81C)
-#define RESUME		(0x820)
-
-
-/* Global Register Fields */
-/* CBACRn */
-#define RWVMID        (RWVMID_MASK       << RWVMID_SHIFT)
-#define RWE           (RWE_MASK          << RWE_SHIFT)
-#define RWGE          (RWGE_MASK         << RWGE_SHIFT)
-#define CBVMID        (CBVMID_MASK       << CBVMID_SHIFT)
-#define IRPTNDX       (IRPTNDX_MASK      << IRPTNDX_SHIFT)
-
-
-/* CR */
-#define RPUE          (RPUE_MASK          << RPUE_SHIFT)
-#define RPUERE        (RPUERE_MASK        << RPUERE_SHIFT)
-#define RPUEIE        (RPUEIE_MASK        << RPUEIE_SHIFT)
-#define DCDEE         (DCDEE_MASK         << DCDEE_SHIFT)
-#define CLIENTPD      (CLIENTPD_MASK      << CLIENTPD_SHIFT)
-#define STALLD        (STALLD_MASK        << STALLD_SHIFT)
-#define TLBLKCRWE     (TLBLKCRWE_MASK     << TLBLKCRWE_SHIFT)
-#define CR_TLBIALLCFG (CR_TLBIALLCFG_MASK << CR_TLBIALLCFG_SHIFT)
-#define TLBIVMIDCFG   (TLBIVMIDCFG_MASK   << TLBIVMIDCFG_SHIFT)
-#define CR_HUME       (CR_HUME_MASK       << CR_HUME_SHIFT)
-
-
-/* ESR */
-#define CFG           (CFG_MASK          << CFG_SHIFT)
-#define BYPASS        (BYPASS_MASK       << BYPASS_SHIFT)
-#define ESR_MULTI     (ESR_MULTI_MASK    << ESR_MULTI_SHIFT)
-
-
-/* ESYNR0 */
-#define ESYNR0_AMID   (ESYNR0_AMID_MASK  << ESYNR0_AMID_SHIFT)
-#define ESYNR0_APID   (ESYNR0_APID_MASK  << ESYNR0_APID_SHIFT)
-#define ESYNR0_ABID   (ESYNR0_ABID_MASK  << ESYNR0_ABID_SHIFT)
-#define ESYNR0_AVMID  (ESYNR0_AVMID_MASK << ESYNR0_AVMID_SHIFT)
-#define ESYNR0_ATID   (ESYNR0_ATID_MASK  << ESYNR0_ATID_SHIFT)
-
-
-/* ESYNR1 */
-#define ESYNR1_AMEMTYPE      (ESYNR1_AMEMTYPE_MASK    << ESYNR1_AMEMTYPE_SHIFT)
-#define ESYNR1_ASHARED       (ESYNR1_ASHARED_MASK     << ESYNR1_ASHARED_SHIFT)
-#define ESYNR1_AINNERSHARED  (ESYNR1_AINNERSHARED_MASK<< \
-						ESYNR1_AINNERSHARED_SHIFT)
-#define ESYNR1_APRIV         (ESYNR1_APRIV_MASK       << ESYNR1_APRIV_SHIFT)
-#define ESYNR1_APROTNS       (ESYNR1_APROTNS_MASK     << ESYNR1_APROTNS_SHIFT)
-#define ESYNR1_AINST         (ESYNR1_AINST_MASK       << ESYNR1_AINST_SHIFT)
-#define ESYNR1_AWRITE        (ESYNR1_AWRITE_MASK      << ESYNR1_AWRITE_SHIFT)
-#define ESYNR1_ABURST        (ESYNR1_ABURST_MASK      << ESYNR1_ABURST_SHIFT)
-#define ESYNR1_ALEN          (ESYNR1_ALEN_MASK        << ESYNR1_ALEN_SHIFT)
-#define ESYNR1_ASIZE         (ESYNR1_ASIZE_MASK       << ESYNR1_ASIZE_SHIFT)
-#define ESYNR1_ALOCK         (ESYNR1_ALOCK_MASK       << ESYNR1_ALOCK_SHIFT)
-#define ESYNR1_AOOO          (ESYNR1_AOOO_MASK        << ESYNR1_AOOO_SHIFT)
-#define ESYNR1_AFULL         (ESYNR1_AFULL_MASK       << ESYNR1_AFULL_SHIFT)
-#define ESYNR1_AC            (ESYNR1_AC_MASK          << ESYNR1_AC_SHIFT)
-#define ESYNR1_DCD           (ESYNR1_DCD_MASK         << ESYNR1_DCD_SHIFT)
-
-
-/* IDR */
-#define NM2VCBMT      (NM2VCBMT_MASK     << NM2VCBMT_SHIFT)
-#define HTW           (HTW_MASK          << HTW_SHIFT)
-#define HUM           (HUM_MASK          << HUM_SHIFT)
-#define TLBSIZE       (TLBSIZE_MASK      << TLBSIZE_SHIFT)
-#define NCB           (NCB_MASK          << NCB_SHIFT)
-#define NIRPT         (NIRPT_MASK        << NIRPT_SHIFT)
-
-
-/* M2VCBRn */
-#define VMID          (VMID_MASK         << VMID_SHIFT)
-#define CBNDX         (CBNDX_MASK        << CBNDX_SHIFT)
-#define BYPASSD       (BYPASSD_MASK      << BYPASSD_SHIFT)
-#define BPRCOSH       (BPRCOSH_MASK      << BPRCOSH_SHIFT)
-#define BPRCISH       (BPRCISH_MASK      << BPRCISH_SHIFT)
-#define BPRCNSH       (BPRCNSH_MASK      << BPRCNSH_SHIFT)
-#define BPSHCFG       (BPSHCFG_MASK      << BPSHCFG_SHIFT)
-#define NSCFG         (NSCFG_MASK        << NSCFG_SHIFT)
-#define BPMTCFG       (BPMTCFG_MASK      << BPMTCFG_SHIFT)
-#define BPMEMTYPE     (BPMEMTYPE_MASK    << BPMEMTYPE_SHIFT)
-
-
-/* REV */
-#define IDR_MINOR     (MINOR_MASK        << MINOR_SHIFT)
-#define IDR_MAJOR     (MAJOR_MASK        << MAJOR_SHIFT)
-
-
-/* TESTBUSCR */
-#define TBE           (TBE_MASK          << TBE_SHIFT)
-#define SPDMBE        (SPDMBE_MASK       << SPDMBE_SHIFT)
-#define WGSEL         (WGSEL_MASK        << WGSEL_SHIFT)
-#define TBLSEL        (TBLSEL_MASK       << TBLSEL_SHIFT)
-#define TBHSEL        (TBHSEL_MASK       << TBHSEL_SHIFT)
-#define SPDM0SEL      (SPDM0SEL_MASK     << SPDM0SEL_SHIFT)
-#define SPDM1SEL      (SPDM1SEL_MASK     << SPDM1SEL_SHIFT)
-#define SPDM2SEL      (SPDM2SEL_MASK     << SPDM2SEL_SHIFT)
-#define SPDM3SEL      (SPDM3SEL_MASK     << SPDM3SEL_SHIFT)
-
-
-/* TLBIVMID */
-#define TLBIVMID_VMID (TLBIVMID_VMID_MASK << TLBIVMID_VMID_SHIFT)
-
-
-/* TLBRSW */
-#define TLBRSW_INDEX  (TLBRSW_INDEX_MASK << TLBRSW_INDEX_SHIFT)
-#define TLBBFBS       (TLBBFBS_MASK      << TLBBFBS_SHIFT)
-
-
-/* TLBTR0 */
-#define PR            (PR_MASK           << PR_SHIFT)
-#define PW            (PW_MASK           << PW_SHIFT)
-#define UR            (UR_MASK           << UR_SHIFT)
-#define UW            (UW_MASK           << UW_SHIFT)
-#define XN            (XN_MASK           << XN_SHIFT)
-#define NSDESC        (NSDESC_MASK       << NSDESC_SHIFT)
-#define ISH           (ISH_MASK          << ISH_SHIFT)
-#define SH            (SH_MASK           << SH_SHIFT)
-#define MT            (MT_MASK           << MT_SHIFT)
-#define DPSIZR        (DPSIZR_MASK       << DPSIZR_SHIFT)
-#define DPSIZC        (DPSIZC_MASK       << DPSIZC_SHIFT)
-
-
-/* TLBTR1 */
-#define TLBTR1_VMID   (TLBTR1_VMID_MASK  << TLBTR1_VMID_SHIFT)
-#define TLBTR1_PA     (TLBTR1_PA_MASK    << TLBTR1_PA_SHIFT)
-
-
-/* TLBTR2 */
-#define TLBTR2_ASID   (TLBTR2_ASID_MASK  << TLBTR2_ASID_SHIFT)
-#define TLBTR2_V      (TLBTR2_V_MASK     << TLBTR2_V_SHIFT)
-#define TLBTR2_NSTID  (TLBTR2_NSTID_MASK << TLBTR2_NSTID_SHIFT)
-#define TLBTR2_NV     (TLBTR2_NV_MASK    << TLBTR2_NV_SHIFT)
-#define TLBTR2_VA     (TLBTR2_VA_MASK    << TLBTR2_VA_SHIFT)
-
-
-/* Context Register Fields */
-/* ACTLR */
-#define CFERE              (CFERE_MASK              << CFERE_SHIFT)
-#define CFEIE              (CFEIE_MASK              << CFEIE_SHIFT)
-#define PTSHCFG            (PTSHCFG_MASK            << PTSHCFG_SHIFT)
-#define RCOSH              (RCOSH_MASK              << RCOSH_SHIFT)
-#define RCISH              (RCISH_MASK              << RCISH_SHIFT)
-#define RCNSH              (RCNSH_MASK              << RCNSH_SHIFT)
-#define PRIVCFG            (PRIVCFG_MASK            << PRIVCFG_SHIFT)
-#define DNA                (DNA_MASK                << DNA_SHIFT)
-#define DNLV2PA            (DNLV2PA_MASK            << DNLV2PA_SHIFT)
-#define TLBMCFG            (TLBMCFG_MASK            << TLBMCFG_SHIFT)
-#define CFCFG              (CFCFG_MASK              << CFCFG_SHIFT)
-#define TIPCF              (TIPCF_MASK              << TIPCF_SHIFT)
-#define V2PCFG             (V2PCFG_MASK             << V2PCFG_SHIFT)
-#define HUME               (HUME_MASK               << HUME_SHIFT)
-#define PTMTCFG            (PTMTCFG_MASK            << PTMTCFG_SHIFT)
-#define PTMEMTYPE          (PTMEMTYPE_MASK          << PTMEMTYPE_SHIFT)
-
-
-/* BFBCR */
-#define BFBDFE             (BFBDFE_MASK             << BFBDFE_SHIFT)
-#define BFBSFE             (BFBSFE_MASK             << BFBSFE_SHIFT)
-#define SFVS               (SFVS_MASK               << SFVS_SHIFT)
-#define FLVIC              (FLVIC_MASK              << FLVIC_SHIFT)
-#define SLVIC              (SLVIC_MASK              << SLVIC_SHIFT)
-
-
-/* CONTEXTIDR */
-#define CONTEXTIDR_ASID    (CONTEXTIDR_ASID_MASK    << CONTEXTIDR_ASID_SHIFT)
-#define PROCID             (PROCID_MASK             << PROCID_SHIFT)
-
-
-/* FSR */
-#define TF                 (TF_MASK                 << TF_SHIFT)
-#define AFF                (AFF_MASK                << AFF_SHIFT)
-#define APF                (APF_MASK                << APF_SHIFT)
-#define TLBMF              (TLBMF_MASK              << TLBMF_SHIFT)
-#define HTWDEEF            (HTWDEEF_MASK            << HTWDEEF_SHIFT)
-#define HTWSEEF            (HTWSEEF_MASK            << HTWSEEF_SHIFT)
-#define MHF                (MHF_MASK                << MHF_SHIFT)
-#define SL                 (SL_MASK                 << SL_SHIFT)
-#define SS                 (SS_MASK                 << SS_SHIFT)
-#define MULTI              (MULTI_MASK              << MULTI_SHIFT)
-
-
-/* FSYNR0 */
-#define AMID               (AMID_MASK               << AMID_SHIFT)
-#define APID               (APID_MASK               << APID_SHIFT)
-#define ABID               (ABID_MASK               << ABID_SHIFT)
-#define ATID               (ATID_MASK               << ATID_SHIFT)
-
-
-/* FSYNR1 */
-#define AMEMTYPE           (AMEMTYPE_MASK           << AMEMTYPE_SHIFT)
-#define ASHARED            (ASHARED_MASK            << ASHARED_SHIFT)
-#define AINNERSHARED       (AINNERSHARED_MASK       << AINNERSHARED_SHIFT)
-#define APRIV              (APRIV_MASK              << APRIV_SHIFT)
-#define APROTNS            (APROTNS_MASK            << APROTNS_SHIFT)
-#define AINST              (AINST_MASK              << AINST_SHIFT)
-#define AWRITE             (AWRITE_MASK             << AWRITE_SHIFT)
-#define ABURST             (ABURST_MASK             << ABURST_SHIFT)
-#define ALEN               (ALEN_MASK               << ALEN_SHIFT)
-#define FSYNR1_ASIZE       (FSYNR1_ASIZE_MASK       << FSYNR1_ASIZE_SHIFT)
-#define ALOCK              (ALOCK_MASK              << ALOCK_SHIFT)
-#define AFULL              (AFULL_MASK              << AFULL_SHIFT)
-
-
-/* NMRR */
-#define ICPC0              (ICPC0_MASK              << ICPC0_SHIFT)
-#define ICPC1              (ICPC1_MASK              << ICPC1_SHIFT)
-#define ICPC2              (ICPC2_MASK              << ICPC2_SHIFT)
-#define ICPC3              (ICPC3_MASK              << ICPC3_SHIFT)
-#define ICPC4              (ICPC4_MASK              << ICPC4_SHIFT)
-#define ICPC5              (ICPC5_MASK              << ICPC5_SHIFT)
-#define ICPC6              (ICPC6_MASK              << ICPC6_SHIFT)
-#define ICPC7              (ICPC7_MASK              << ICPC7_SHIFT)
-#define OCPC0              (OCPC0_MASK              << OCPC0_SHIFT)
-#define OCPC1              (OCPC1_MASK              << OCPC1_SHIFT)
-#define OCPC2              (OCPC2_MASK              << OCPC2_SHIFT)
-#define OCPC3              (OCPC3_MASK              << OCPC3_SHIFT)
-#define OCPC4              (OCPC4_MASK              << OCPC4_SHIFT)
-#define OCPC5              (OCPC5_MASK              << OCPC5_SHIFT)
-#define OCPC6              (OCPC6_MASK              << OCPC6_SHIFT)
-#define OCPC7              (OCPC7_MASK              << OCPC7_SHIFT)
-
-
-/* PAR */
-#define FAULT              (FAULT_MASK              << FAULT_SHIFT)
-/* If a fault is present, these are the
-same as the fault fields in the FAR */
-#define FAULT_TF           (FAULT_TF_MASK           << FAULT_TF_SHIFT)
-#define FAULT_AFF          (FAULT_AFF_MASK          << FAULT_AFF_SHIFT)
-#define FAULT_APF          (FAULT_APF_MASK          << FAULT_APF_SHIFT)
-#define FAULT_TLBMF        (FAULT_TLBMF_MASK        << FAULT_TLBMF_SHIFT)
-#define FAULT_HTWDEEF      (FAULT_HTWDEEF_MASK      << FAULT_HTWDEEF_SHIFT)
-#define FAULT_HTWSEEF      (FAULT_HTWSEEF_MASK      << FAULT_HTWSEEF_SHIFT)
-#define FAULT_MHF          (FAULT_MHF_MASK          << FAULT_MHF_SHIFT)
-#define FAULT_SL           (FAULT_SL_MASK           << FAULT_SL_SHIFT)
-#define FAULT_SS           (FAULT_SS_MASK           << FAULT_SS_SHIFT)
-
-/* If NO fault is present, the following fields are in effect */
-/* (FAULT remains as before) */
-#define PAR_NOFAULT_SS     (PAR_NOFAULT_SS_MASK     << PAR_NOFAULT_SS_SHIFT)
-#define PAR_NOFAULT_MT     (PAR_NOFAULT_MT_MASK     << PAR_NOFAULT_MT_SHIFT)
-#define PAR_NOFAULT_SH     (PAR_NOFAULT_SH_MASK     << PAR_NOFAULT_SH_SHIFT)
-#define PAR_NOFAULT_NS     (PAR_NOFAULT_NS_MASK     << PAR_NOFAULT_NS_SHIFT)
-#define PAR_NOFAULT_NOS    (PAR_NOFAULT_NOS_MASK    << PAR_NOFAULT_NOS_SHIFT)
-#define PAR_NPFAULT_PA     (PAR_NPFAULT_PA_MASK     << PAR_NPFAULT_PA_SHIFT)
-
-
-/* PRRR */
-#define MTC0               (MTC0_MASK               << MTC0_SHIFT)
-#define MTC1               (MTC1_MASK               << MTC1_SHIFT)
-#define MTC2               (MTC2_MASK               << MTC2_SHIFT)
-#define MTC3               (MTC3_MASK               << MTC3_SHIFT)
-#define MTC4               (MTC4_MASK               << MTC4_SHIFT)
-#define MTC5               (MTC5_MASK               << MTC5_SHIFT)
-#define MTC6               (MTC6_MASK               << MTC6_SHIFT)
-#define MTC7               (MTC7_MASK               << MTC7_SHIFT)
-#define SHDSH0             (SHDSH0_MASK             << SHDSH0_SHIFT)
-#define SHDSH1             (SHDSH1_MASK             << SHDSH1_SHIFT)
-#define SHNMSH0            (SHNMSH0_MASK            << SHNMSH0_SHIFT)
-#define SHNMSH1            (SHNMSH1_MASK            << SHNMSH1_SHIFT)
-#define NOS0               (NOS0_MASK               << NOS0_SHIFT)
-#define NOS1               (NOS1_MASK               << NOS1_SHIFT)
-#define NOS2               (NOS2_MASK               << NOS2_SHIFT)
-#define NOS3               (NOS3_MASK               << NOS3_SHIFT)
-#define NOS4               (NOS4_MASK               << NOS4_SHIFT)
-#define NOS5               (NOS5_MASK               << NOS5_SHIFT)
-#define NOS6               (NOS6_MASK               << NOS6_SHIFT)
-#define NOS7               (NOS7_MASK               << NOS7_SHIFT)
-
-
-/* RESUME */
-#define TNR                (TNR_MASK                << TNR_SHIFT)
-
-
-/* SCTLR */
-#define M                  (M_MASK                  << M_SHIFT)
-#define TRE                (TRE_MASK                << TRE_SHIFT)
-#define AFE                (AFE_MASK                << AFE_SHIFT)
-#define HAF                (HAF_MASK                << HAF_SHIFT)
-#define BE                 (BE_MASK                 << BE_SHIFT)
-#define AFFD               (AFFD_MASK               << AFFD_SHIFT)
-
-
-/* TLBIASID */
-#define TLBIASID_ASID      (TLBIASID_ASID_MASK      << TLBIASID_ASID_SHIFT)
-
-
-/* TLBIVA */
-#define TLBIVA_ASID        (TLBIVA_ASID_MASK        << TLBIVA_ASID_SHIFT)
-#define TLBIVA_VA          (TLBIVA_VA_MASK          << TLBIVA_VA_SHIFT)
-
-
-/* TLBIVAA */
-#define TLBIVAA_VA         (TLBIVAA_VA_MASK         << TLBIVAA_VA_SHIFT)
-
-
-/* TLBLCKR */
-#define LKE                (LKE_MASK                << LKE_SHIFT)
-#define TLBLCKR_TLBIALLCFG (TLBLCKR_TLBIALLCFG_MASK<<TLBLCKR_TLBIALLCFG_SHIFT)
-#define TLBIASIDCFG        (TLBIASIDCFG_MASK        << TLBIASIDCFG_SHIFT)
-#define TLBIVAACFG         (TLBIVAACFG_MASK         << TLBIVAACFG_SHIFT)
-#define FLOOR              (FLOOR_MASK              << FLOOR_SHIFT)
-#define VICTIM             (VICTIM_MASK             << VICTIM_SHIFT)
-
-
-/* TTBCR */
-#define N                  (N_MASK                  << N_SHIFT)
-#define PD0                (PD0_MASK                << PD0_SHIFT)
-#define PD1                (PD1_MASK                << PD1_SHIFT)
-
-
-/* TTBR0 */
-#define TTBR0_IRGNH        (TTBR0_IRGNH_MASK        << TTBR0_IRGNH_SHIFT)
-#define TTBR0_SH           (TTBR0_SH_MASK           << TTBR0_SH_SHIFT)
-#define TTBR0_ORGN         (TTBR0_ORGN_MASK         << TTBR0_ORGN_SHIFT)
-#define TTBR0_NOS          (TTBR0_NOS_MASK          << TTBR0_NOS_SHIFT)
-#define TTBR0_IRGNL        (TTBR0_IRGNL_MASK        << TTBR0_IRGNL_SHIFT)
-#define TTBR0_PA           (TTBR0_PA_MASK           << TTBR0_PA_SHIFT)
-
-
-/* TTBR1 */
-#define TTBR1_IRGNH        (TTBR1_IRGNH_MASK        << TTBR1_IRGNH_SHIFT)
-#define TTBR1_SH           (TTBR1_SH_MASK           << TTBR1_SH_SHIFT)
-#define TTBR1_ORGN         (TTBR1_ORGN_MASK         << TTBR1_ORGN_SHIFT)
-#define TTBR1_NOS          (TTBR1_NOS_MASK          << TTBR1_NOS_SHIFT)
-#define TTBR1_IRGNL        (TTBR1_IRGNL_MASK        << TTBR1_IRGNL_SHIFT)
-#define TTBR1_PA           (TTBR1_PA_MASK           << TTBR1_PA_SHIFT)
-
-
-/* V2PSR */
-#define HIT                (HIT_MASK                << HIT_SHIFT)
-#define INDEX              (INDEX_MASK              << INDEX_SHIFT)
-
-
-/* V2Pxx */
-#define V2Pxx_INDEX        (V2Pxx_INDEX_MASK        << V2Pxx_INDEX_SHIFT)
-#define V2Pxx_VA           (V2Pxx_VA_MASK           << V2Pxx_VA_SHIFT)
-
-
-/* Global Register Masks */
-/* CBACRn */
-#define RWVMID_MASK               0x1F
-#define RWE_MASK                  0x01
-#define RWGE_MASK                 0x01
-#define CBVMID_MASK               0x1F
-#define IRPTNDX_MASK              0xFF
-
-
-/* CR */
-#define RPUE_MASK                 0x01
-#define RPUERE_MASK               0x01
-#define RPUEIE_MASK               0x01
-#define DCDEE_MASK                0x01
-#define CLIENTPD_MASK             0x01
-#define STALLD_MASK               0x01
-#define TLBLKCRWE_MASK            0x01
-#define CR_TLBIALLCFG_MASK        0x01
-#define TLBIVMIDCFG_MASK          0x01
-#define CR_HUME_MASK              0x01
-
-
-/* ESR */
-#define CFG_MASK                  0x01
-#define BYPASS_MASK               0x01
-#define ESR_MULTI_MASK            0x01
-
-
-/* ESYNR0 */
-#define ESYNR0_AMID_MASK          0xFF
-#define ESYNR0_APID_MASK          0x1F
-#define ESYNR0_ABID_MASK          0x07
-#define ESYNR0_AVMID_MASK         0x1F
-#define ESYNR0_ATID_MASK          0xFF
-
-
-/* ESYNR1 */
-#define ESYNR1_AMEMTYPE_MASK             0x07
-#define ESYNR1_ASHARED_MASK              0x01
-#define ESYNR1_AINNERSHARED_MASK         0x01
-#define ESYNR1_APRIV_MASK                0x01
-#define ESYNR1_APROTNS_MASK              0x01
-#define ESYNR1_AINST_MASK                0x01
-#define ESYNR1_AWRITE_MASK               0x01
-#define ESYNR1_ABURST_MASK               0x01
-#define ESYNR1_ALEN_MASK                 0x0F
-#define ESYNR1_ASIZE_MASK                0x01
-#define ESYNR1_ALOCK_MASK                0x03
-#define ESYNR1_AOOO_MASK                 0x01
-#define ESYNR1_AFULL_MASK                0x01
-#define ESYNR1_AC_MASK                   0x01
-#define ESYNR1_DCD_MASK                  0x01
-
-
-/* IDR */
-#define NM2VCBMT_MASK             0x1FF
-#define HTW_MASK                  0x01
-#define HUM_MASK                  0x01
-#define TLBSIZE_MASK              0x0F
-#define NCB_MASK                  0xFF
-#define NIRPT_MASK                0xFF
-
-
-/* M2VCBRn */
-#define VMID_MASK                 0x1F
-#define CBNDX_MASK                0xFF
-#define BYPASSD_MASK              0x01
-#define BPRCOSH_MASK              0x01
-#define BPRCISH_MASK              0x01
-#define BPRCNSH_MASK              0x01
-#define BPSHCFG_MASK              0x03
-#define NSCFG_MASK                0x03
-#define BPMTCFG_MASK              0x01
-#define BPMEMTYPE_MASK            0x07
-
-
-/* REV */
-#define MINOR_MASK                0x0F
-#define MAJOR_MASK                0x0F
-
-
-/* TESTBUSCR */
-#define TBE_MASK                  0x01
-#define SPDMBE_MASK               0x01
-#define WGSEL_MASK                0x03
-#define TBLSEL_MASK               0x03
-#define TBHSEL_MASK               0x03
-#define SPDM0SEL_MASK             0x0F
-#define SPDM1SEL_MASK             0x0F
-#define SPDM2SEL_MASK             0x0F
-#define SPDM3SEL_MASK             0x0F
-
-
-/* TLBIMID */
-#define TLBIVMID_VMID_MASK        0x1F
-
-
-/* TLBRSW */
-#define TLBRSW_INDEX_MASK         0xFF
-#define TLBBFBS_MASK              0x03
-
-
-/* TLBTR0 */
-#define PR_MASK                   0x01
-#define PW_MASK                   0x01
-#define UR_MASK                   0x01
-#define UW_MASK                   0x01
-#define XN_MASK                   0x01
-#define NSDESC_MASK               0x01
-#define ISH_MASK                  0x01
-#define SH_MASK                   0x01
-#define MT_MASK                   0x07
-#define DPSIZR_MASK               0x07
-#define DPSIZC_MASK               0x07
-
-
-/* TLBTR1 */
-#define TLBTR1_VMID_MASK          0x1F
-#define TLBTR1_PA_MASK            0x000FFFFF
-
-
-/* TLBTR2 */
-#define TLBTR2_ASID_MASK          0xFF
-#define TLBTR2_V_MASK             0x01
-#define TLBTR2_NSTID_MASK         0x01
-#define TLBTR2_NV_MASK            0x01
-#define TLBTR2_VA_MASK            0x000FFFFF
-
-
-/* Global Register Shifts */
-/* CBACRn */
-#define RWVMID_SHIFT             0
-#define RWE_SHIFT                8
-#define RWGE_SHIFT               9
-#define CBVMID_SHIFT             16
-#define IRPTNDX_SHIFT            24
-
-
-/* CR */
-#define RPUE_SHIFT               0
-#define RPUERE_SHIFT             1
-#define RPUEIE_SHIFT             2
-#define DCDEE_SHIFT              3
-#define CLIENTPD_SHIFT           4
-#define STALLD_SHIFT             5
-#define TLBLKCRWE_SHIFT          6
-#define CR_TLBIALLCFG_SHIFT      7
-#define TLBIVMIDCFG_SHIFT        8
-#define CR_HUME_SHIFT            9
-
-
-/* ESR */
-#define CFG_SHIFT                0
-#define BYPASS_SHIFT             1
-#define ESR_MULTI_SHIFT          31
-
-
-/* ESYNR0 */
-#define ESYNR0_AMID_SHIFT        0
-#define ESYNR0_APID_SHIFT        8
-#define ESYNR0_ABID_SHIFT        13
-#define ESYNR0_AVMID_SHIFT       16
-#define ESYNR0_ATID_SHIFT        24
-
-
-/* ESYNR1 */
-#define ESYNR1_AMEMTYPE_SHIFT           0
-#define ESYNR1_ASHARED_SHIFT            3
-#define ESYNR1_AINNERSHARED_SHIFT       4
-#define ESYNR1_APRIV_SHIFT              5
-#define ESYNR1_APROTNS_SHIFT            6
-#define ESYNR1_AINST_SHIFT              7
-#define ESYNR1_AWRITE_SHIFT             8
-#define ESYNR1_ABURST_SHIFT             10
-#define ESYNR1_ALEN_SHIFT               12
-#define ESYNR1_ASIZE_SHIFT              16
-#define ESYNR1_ALOCK_SHIFT              20
-#define ESYNR1_AOOO_SHIFT               22
-#define ESYNR1_AFULL_SHIFT              24
-#define ESYNR1_AC_SHIFT                 30
-#define ESYNR1_DCD_SHIFT                31
-
-
-/* IDR */
-#define NM2VCBMT_SHIFT           0
-#define HTW_SHIFT                9
-#define HUM_SHIFT                10
-#define TLBSIZE_SHIFT            12
-#define NCB_SHIFT                16
-#define NIRPT_SHIFT              24
-
-
-/* M2VCBRn */
-#define VMID_SHIFT               0
-#define CBNDX_SHIFT              8
-#define BYPASSD_SHIFT            16
-#define BPRCOSH_SHIFT            17
-#define BPRCISH_SHIFT            18
-#define BPRCNSH_SHIFT            19
-#define BPSHCFG_SHIFT            20
-#define NSCFG_SHIFT              22
-#define BPMTCFG_SHIFT            24
-#define BPMEMTYPE_SHIFT          25
-
-
-/* REV */
-#define MINOR_SHIFT              0
-#define MAJOR_SHIFT              4
-
-
-/* TESTBUSCR */
-#define TBE_SHIFT                0
-#define SPDMBE_SHIFT             1
-#define WGSEL_SHIFT              8
-#define TBLSEL_SHIFT             12
-#define TBHSEL_SHIFT             14
-#define SPDM0SEL_SHIFT           16
-#define SPDM1SEL_SHIFT           20
-#define SPDM2SEL_SHIFT           24
-#define SPDM3SEL_SHIFT           28
-
-
-/* TLBIMID */
-#define TLBIVMID_VMID_SHIFT      0
-
-
-/* TLBRSW */
-#define TLBRSW_INDEX_SHIFT       0
-#define TLBBFBS_SHIFT            8
-
-
-/* TLBTR0 */
-#define PR_SHIFT                 0
-#define PW_SHIFT                 1
-#define UR_SHIFT                 2
-#define UW_SHIFT                 3
-#define XN_SHIFT                 4
-#define NSDESC_SHIFT             6
-#define ISH_SHIFT                7
-#define SH_SHIFT                 8
-#define MT_SHIFT                 9
-#define DPSIZR_SHIFT             16
-#define DPSIZC_SHIFT             20
-
-
-/* TLBTR1 */
-#define TLBTR1_VMID_SHIFT        0
-#define TLBTR1_PA_SHIFT          12
-
-
-/* TLBTR2 */
-#define TLBTR2_ASID_SHIFT        0
-#define TLBTR2_V_SHIFT           8
-#define TLBTR2_NSTID_SHIFT       9
-#define TLBTR2_NV_SHIFT          10
-#define TLBTR2_VA_SHIFT          12
-
-
-/* Context Register Masks */
-/* ACTLR */
-#define CFERE_MASK                       0x01
-#define CFEIE_MASK                       0x01
-#define PTSHCFG_MASK                     0x03
-#define RCOSH_MASK                       0x01
-#define RCISH_MASK                       0x01
-#define RCNSH_MASK                       0x01
-#define PRIVCFG_MASK                     0x03
-#define DNA_MASK                         0x01
-#define DNLV2PA_MASK                     0x01
-#define TLBMCFG_MASK                     0x03
-#define CFCFG_MASK                       0x01
-#define TIPCF_MASK                       0x01
-#define V2PCFG_MASK                      0x03
-#define HUME_MASK                        0x01
-#define PTMTCFG_MASK                     0x01
-#define PTMEMTYPE_MASK                   0x07
-
-
-/* BFBCR */
-#define BFBDFE_MASK                      0x01
-#define BFBSFE_MASK                      0x01
-#define SFVS_MASK                        0x01
-#define FLVIC_MASK                       0x0F
-#define SLVIC_MASK                       0x0F
-
-
-/* CONTEXTIDR */
-#define CONTEXTIDR_ASID_MASK             0xFF
-#define PROCID_MASK                      0x00FFFFFF
-
-
-/* FSR */
-#define TF_MASK                          0x01
-#define AFF_MASK                         0x01
-#define APF_MASK                         0x01
-#define TLBMF_MASK                       0x01
-#define HTWDEEF_MASK                     0x01
-#define HTWSEEF_MASK                     0x01
-#define MHF_MASK                         0x01
-#define SL_MASK                          0x01
-#define SS_MASK                          0x01
-#define MULTI_MASK                       0x01
-
-
-/* FSYNR0 */
-#define AMID_MASK                        0xFF
-#define APID_MASK                        0x1F
-#define ABID_MASK                        0x07
-#define ATID_MASK                        0xFF
-
-
-/* FSYNR1 */
-#define AMEMTYPE_MASK                    0x07
-#define ASHARED_MASK                     0x01
-#define AINNERSHARED_MASK                0x01
-#define APRIV_MASK                       0x01
-#define APROTNS_MASK                     0x01
-#define AINST_MASK                       0x01
-#define AWRITE_MASK                      0x01
-#define ABURST_MASK                      0x01
-#define ALEN_MASK                        0x0F
-#define FSYNR1_ASIZE_MASK                0x07
-#define ALOCK_MASK                       0x03
-#define AFULL_MASK                       0x01
-
-
-/* NMRR */
-#define ICPC0_MASK                       0x03
-#define ICPC1_MASK                       0x03
-#define ICPC2_MASK                       0x03
-#define ICPC3_MASK                       0x03
-#define ICPC4_MASK                       0x03
-#define ICPC5_MASK                       0x03
-#define ICPC6_MASK                       0x03
-#define ICPC7_MASK                       0x03
-#define OCPC0_MASK                       0x03
-#define OCPC1_MASK                       0x03
-#define OCPC2_MASK                       0x03
-#define OCPC3_MASK                       0x03
-#define OCPC4_MASK                       0x03
-#define OCPC5_MASK                       0x03
-#define OCPC6_MASK                       0x03
-#define OCPC7_MASK                       0x03
-
-
-/* PAR */
-#define FAULT_MASK                       0x01
-/* If a fault is present, these are the
-same as the fault fields in the FAR */
-#define FAULT_TF_MASK                    0x01
-#define FAULT_AFF_MASK                   0x01
-#define FAULT_APF_MASK                   0x01
-#define FAULT_TLBMF_MASK                 0x01
-#define FAULT_HTWDEEF_MASK               0x01
-#define FAULT_HTWSEEF_MASK               0x01
-#define FAULT_MHF_MASK                   0x01
-#define FAULT_SL_MASK                    0x01
-#define FAULT_SS_MASK                    0x01
-
-/* If NO fault is present, the following
- * fields are in effect
- * (FAULT remains as before) */
-#define PAR_NOFAULT_SS_MASK              0x01
-#define PAR_NOFAULT_MT_MASK              0x07
-#define PAR_NOFAULT_SH_MASK              0x01
-#define PAR_NOFAULT_NS_MASK              0x01
-#define PAR_NOFAULT_NOS_MASK             0x01
-#define PAR_NPFAULT_PA_MASK              0x000FFFFF
-
-
-/* PRRR */
-#define MTC0_MASK                        0x03
-#define MTC1_MASK                        0x03
-#define MTC2_MASK                        0x03
-#define MTC3_MASK                        0x03
-#define MTC4_MASK                        0x03
-#define MTC5_MASK                        0x03
-#define MTC6_MASK                        0x03
-#define MTC7_MASK                        0x03
-#define SHDSH0_MASK                      0x01
-#define SHDSH1_MASK                      0x01
-#define SHNMSH0_MASK                     0x01
-#define SHNMSH1_MASK                     0x01
-#define NOS0_MASK                        0x01
-#define NOS1_MASK                        0x01
-#define NOS2_MASK                        0x01
-#define NOS3_MASK                        0x01
-#define NOS4_MASK                        0x01
-#define NOS5_MASK                        0x01
-#define NOS6_MASK                        0x01
-#define NOS7_MASK                        0x01
-
-
-/* RESUME */
-#define TNR_MASK                         0x01
-
-
-/* SCTLR */
-#define M_MASK                           0x01
-#define TRE_MASK                         0x01
-#define AFE_MASK                         0x01
-#define HAF_MASK                         0x01
-#define BE_MASK                          0x01
-#define AFFD_MASK                        0x01
-
-
-/* TLBIASID */
-#define TLBIASID_ASID_MASK               0xFF
-
-
-/* TLBIVA */
-#define TLBIVA_ASID_MASK                 0xFF
-#define TLBIVA_VA_MASK                   0x000FFFFF
-
-
-/* TLBIVAA */
-#define TLBIVAA_VA_MASK                  0x000FFFFF
-
-
-/* TLBLCKR */
-#define LKE_MASK                         0x01
-#define TLBLCKR_TLBIALLCFG_MASK          0x01
-#define TLBIASIDCFG_MASK                 0x01
-#define TLBIVAACFG_MASK                  0x01
-#define FLOOR_MASK                       0xFF
-#define VICTIM_MASK                      0xFF
-
-
-/* TTBCR */
-#define N_MASK                           0x07
-#define PD0_MASK                         0x01
-#define PD1_MASK                         0x01
-
-
-/* TTBR0 */
-#define TTBR0_IRGNH_MASK                 0x01
-#define TTBR0_SH_MASK                    0x01
-#define TTBR0_ORGN_MASK                  0x03
-#define TTBR0_NOS_MASK                   0x01
-#define TTBR0_IRGNL_MASK                 0x01
-#define TTBR0_PA_MASK                    0x0003FFFF
-
-
-/* TTBR1 */
-#define TTBR1_IRGNH_MASK                 0x01
-#define TTBR1_SH_MASK                    0x01
-#define TTBR1_ORGN_MASK                  0x03
-#define TTBR1_NOS_MASK                   0x01
-#define TTBR1_IRGNL_MASK                 0x01
-#define TTBR1_PA_MASK                    0x0003FFFF
-
-
-/* V2PSR */
-#define HIT_MASK                         0x01
-#define INDEX_MASK                       0xFF
-
-
-/* V2Pxx */
-#define V2Pxx_INDEX_MASK                 0xFF
-#define V2Pxx_VA_MASK                    0x000FFFFF
-
-
-/* Context Register Shifts */
-/* ACTLR */
-#define CFERE_SHIFT                    0
-#define CFEIE_SHIFT                    1
-#define PTSHCFG_SHIFT                  2
-#define RCOSH_SHIFT                    4
-#define RCISH_SHIFT                    5
-#define RCNSH_SHIFT                    6
-#define PRIVCFG_SHIFT                  8
-#define DNA_SHIFT                      10
-#define DNLV2PA_SHIFT                  11
-#define TLBMCFG_SHIFT                  12
-#define CFCFG_SHIFT                    14
-#define TIPCF_SHIFT                    15
-#define V2PCFG_SHIFT                   16
-#define HUME_SHIFT                     18
-#define PTMTCFG_SHIFT                  20
-#define PTMEMTYPE_SHIFT                21
-
-
-/* BFBCR */
-#define BFBDFE_SHIFT                   0
-#define BFBSFE_SHIFT                   1
-#define SFVS_SHIFT                     2
-#define FLVIC_SHIFT                    4
-#define SLVIC_SHIFT                    8
-
-
-/* CONTEXTIDR */
-#define CONTEXTIDR_ASID_SHIFT          0
-#define PROCID_SHIFT                   8
-
-
-/* FSR */
-#define TF_SHIFT                       1
-#define AFF_SHIFT                      2
-#define APF_SHIFT                      3
-#define TLBMF_SHIFT                    4
-#define HTWDEEF_SHIFT                  5
-#define HTWSEEF_SHIFT                  6
-#define MHF_SHIFT                      7
-#define SL_SHIFT                       16
-#define SS_SHIFT                       30
-#define MULTI_SHIFT                    31
-
-
-/* FSYNR0 */
-#define AMID_SHIFT                     0
-#define APID_SHIFT                     8
-#define ABID_SHIFT                     13
-#define ATID_SHIFT                     24
-
-
-/* FSYNR1 */
-#define AMEMTYPE_SHIFT                 0
-#define ASHARED_SHIFT                  3
-#define AINNERSHARED_SHIFT             4
-#define APRIV_SHIFT                    5
-#define APROTNS_SHIFT                  6
-#define AINST_SHIFT                    7
-#define AWRITE_SHIFT                   8
-#define ABURST_SHIFT                   10
-#define ALEN_SHIFT                     12
-#define FSYNR1_ASIZE_SHIFT             16
-#define ALOCK_SHIFT                    20
-#define AFULL_SHIFT                    24
-
-
-/* NMRR */
-#define ICPC0_SHIFT                    0
-#define ICPC1_SHIFT                    2
-#define ICPC2_SHIFT                    4
-#define ICPC3_SHIFT                    6
-#define ICPC4_SHIFT                    8
-#define ICPC5_SHIFT                    10
-#define ICPC6_SHIFT                    12
-#define ICPC7_SHIFT                    14
-#define OCPC0_SHIFT                    16
-#define OCPC1_SHIFT                    18
-#define OCPC2_SHIFT                    20
-#define OCPC3_SHIFT                    22
-#define OCPC4_SHIFT                    24
-#define OCPC5_SHIFT                    26
-#define OCPC6_SHIFT                    28
-#define OCPC7_SHIFT                    30
-
-
-/* PAR */
-#define FAULT_SHIFT                    0
-/* If a fault is present, these are the
-same as the fault fields in the FAR */
-#define FAULT_TF_SHIFT                 1
-#define FAULT_AFF_SHIFT                2
-#define FAULT_APF_SHIFT                3
-#define FAULT_TLBMF_SHIFT              4
-#define FAULT_HTWDEEF_SHIFT            5
-#define FAULT_HTWSEEF_SHIFT            6
-#define FAULT_MHF_SHIFT                7
-#define FAULT_SL_SHIFT                 16
-#define FAULT_SS_SHIFT                 30
-
-/* If NO fault is present, the following
- * fields are in effect
- * (FAULT remains as before) */
-#define PAR_NOFAULT_SS_SHIFT           1
-#define PAR_NOFAULT_MT_SHIFT           4
-#define PAR_NOFAULT_SH_SHIFT           7
-#define PAR_NOFAULT_NS_SHIFT           9
-#define PAR_NOFAULT_NOS_SHIFT          10
-#define PAR_NPFAULT_PA_SHIFT           12
-
-
-/* PRRR */
-#define MTC0_SHIFT                     0
-#define MTC1_SHIFT                     2
-#define MTC2_SHIFT                     4
-#define MTC3_SHIFT                     6
-#define MTC4_SHIFT                     8
-#define MTC5_SHIFT                     10
-#define MTC6_SHIFT                     12
-#define MTC7_SHIFT                     14
-#define SHDSH0_SHIFT                   16
-#define SHDSH1_SHIFT                   17
-#define SHNMSH0_SHIFT                  18
-#define SHNMSH1_SHIFT                  19
-#define NOS0_SHIFT                     24
-#define NOS1_SHIFT                     25
-#define NOS2_SHIFT                     26
-#define NOS3_SHIFT                     27
-#define NOS4_SHIFT                     28
-#define NOS5_SHIFT                     29
-#define NOS6_SHIFT                     30
-#define NOS7_SHIFT                     31
-
-
-/* RESUME */
-#define TNR_SHIFT                      0
-
-
-/* SCTLR */
-#define M_SHIFT                        0
-#define TRE_SHIFT                      1
-#define AFE_SHIFT                      2
-#define HAF_SHIFT                      3
-#define BE_SHIFT                       4
-#define AFFD_SHIFT                     5
-
-
-/* TLBIASID */
-#define TLBIASID_ASID_SHIFT            0
-
-
-/* TLBIVA */
-#define TLBIVA_ASID_SHIFT              0
-#define TLBIVA_VA_SHIFT                12
-
-
-/* TLBIVAA */
-#define TLBIVAA_VA_SHIFT               12
-
-
-/* TLBLCKR */
-#define LKE_SHIFT                      0
-#define TLBLCKR_TLBIALLCFG_SHIFT       1
-#define TLBIASIDCFG_SHIFT              2
-#define TLBIVAACFG_SHIFT               3
-#define FLOOR_SHIFT                    8
-#define VICTIM_SHIFT                   8
-
-
-/* TTBCR */
-#define N_SHIFT                        3
-#define PD0_SHIFT                      4
-#define PD1_SHIFT                      5
-
-
-/* TTBR0 */
-#define TTBR0_IRGNH_SHIFT              0
-#define TTBR0_SH_SHIFT                 1
-#define TTBR0_ORGN_SHIFT               3
-#define TTBR0_NOS_SHIFT                5
-#define TTBR0_IRGNL_SHIFT              6
-#define TTBR0_PA_SHIFT                 14
-
-
-/* TTBR1 */
-#define TTBR1_IRGNH_SHIFT              0
-#define TTBR1_SH_SHIFT                 1
-#define TTBR1_ORGN_SHIFT               3
-#define TTBR1_NOS_SHIFT                5
-#define TTBR1_IRGNL_SHIFT              6
-#define TTBR1_PA_SHIFT                 14
-
-
-/* V2PSR */
-#define HIT_SHIFT                      0
-#define INDEX_SHIFT                    8
-
-
-/* V2Pxx */
-#define V2Pxx_INDEX_SHIFT              0
-#define V2Pxx_VA_SHIFT                 12
-
-#endif
diff --git a/arch/arm/mach-msm/include/mach/iommu_hw-v0.h b/arch/arm/mach-msm/include/mach/iommu_hw-v0.h
new file mode 100644
index 0000000..68dec79
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/iommu_hw-v0.h
@@ -0,0 +1,1868 @@
+/* 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.
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_IOMMU_HW_8XXX_H
+#define __ARCH_ARM_MACH_MSM_IOMMU_HW_8XXX_H
+
+#define CTX_SHIFT 12
+
+#define GET_GLOBAL_REG(reg, base) (readl_relaxed((base) + (reg)))
+#define GET_CTX_REG(reg, base, ctx) \
+			(readl_relaxed((base) + (reg) + ((ctx) << CTX_SHIFT)))
+
+#define SET_GLOBAL_REG(reg, base, val)	writel_relaxed((val), ((base) + (reg)))
+
+#define SET_CTX_REG(reg, base, ctx, val) \
+		writel_relaxed((val), ((base) + (reg) + ((ctx) << CTX_SHIFT)))
+
+/* Wrappers for numbered registers */
+#define SET_GLOBAL_REG_N(b, n, r, v) SET_GLOBAL_REG(b, ((r) + (n << 2)), (v))
+#define GET_GLOBAL_REG_N(b, n, r)    GET_GLOBAL_REG(b, ((r) + (n << 2)))
+
+/* Field wrappers */
+#define GET_GLOBAL_FIELD(b, r, F)    GET_FIELD(((b) + (r)), F##_MASK, F##_SHIFT)
+#define GET_CONTEXT_FIELD(b, c, r, F)	\
+	GET_FIELD(((b) + (r) + ((c) << CTX_SHIFT)), F##_MASK, F##_SHIFT)
+
+#define SET_GLOBAL_FIELD(b, r, F, v) \
+	SET_FIELD(((b) + (r)), F##_MASK, F##_SHIFT, (v))
+#define SET_CONTEXT_FIELD(b, c, r, F, v)	\
+	SET_FIELD(((b) + (r) + ((c) << CTX_SHIFT)), F##_MASK, F##_SHIFT, (v))
+
+#define GET_FIELD(addr, mask, shift) ((readl_relaxed(addr) >> (shift)) & (mask))
+
+#define SET_FIELD(addr, mask, shift, v) \
+do { \
+	int t = readl_relaxed(addr); \
+	writel_relaxed((t & ~((mask) << (shift))) + (((v) & \
+		       (mask)) << (shift)), addr);\
+} while (0)
+
+
+#define NUM_FL_PTE	4096
+#define NUM_SL_PTE	256
+#define NUM_TEX_CLASS	8
+
+/* First-level page table bits */
+#define FL_BASE_MASK		0xFFFFFC00
+#define FL_TYPE_TABLE		(1 << 0)
+#define FL_TYPE_SECT		(2 << 0)
+#define FL_SUPERSECTION		(1 << 18)
+#define FL_AP0			(1 << 10)
+#define FL_AP1			(1 << 11)
+#define FL_AP2			(1 << 15)
+#define FL_SHARED		(1 << 16)
+#define FL_BUFFERABLE		(1 << 2)
+#define FL_CACHEABLE		(1 << 3)
+#define FL_TEX0			(1 << 12)
+#define FL_OFFSET(va)		(((va) & 0xFFF00000) >> 20)
+#define FL_NG			(1 << 17)
+
+/* Second-level page table bits */
+#define SL_BASE_MASK_LARGE	0xFFFF0000
+#define SL_BASE_MASK_SMALL	0xFFFFF000
+#define SL_TYPE_LARGE		(1 << 0)
+#define SL_TYPE_SMALL		(2 << 0)
+#define SL_AP0			(1 << 4)
+#define SL_AP1			(2 << 4)
+#define SL_AP2			(1 << 9)
+#define SL_SHARED		(1 << 10)
+#define SL_BUFFERABLE		(1 << 2)
+#define SL_CACHEABLE		(1 << 3)
+#define SL_TEX0			(1 << 6)
+#define SL_OFFSET(va)		(((va) & 0xFF000) >> 12)
+#define SL_NG			(1 << 11)
+
+/* Memory type and cache policy attributes */
+#define MT_SO			0
+#define MT_DEV			1
+#define MT_NORMAL		2
+#define CP_NONCACHED		0
+#define CP_WB_WA		1
+#define CP_WT			2
+#define CP_WB_NWA		3
+
+/* Global register setters / getters */
+#define SET_M2VCBR_N(b, N, v)	 SET_GLOBAL_REG_N(M2VCBR_N, N, (b), (v))
+#define SET_CBACR_N(b, N, v)	 SET_GLOBAL_REG_N(CBACR_N, N, (b), (v))
+#define SET_TLBRSW(b, v)	 SET_GLOBAL_REG(TLBRSW, (b), (v))
+#define SET_TLBTR0(b, v)	 SET_GLOBAL_REG(TLBTR0, (b), (v))
+#define SET_TLBTR1(b, v)	 SET_GLOBAL_REG(TLBTR1, (b), (v))
+#define SET_TLBTR2(b, v)	 SET_GLOBAL_REG(TLBTR2, (b), (v))
+#define SET_TESTBUSCR(b, v)	 SET_GLOBAL_REG(TESTBUSCR, (b), (v))
+#define SET_GLOBAL_TLBIALL(b, v) SET_GLOBAL_REG(GLOBAL_TLBIALL, (b), (v))
+#define SET_TLBIVMID(b, v)	 SET_GLOBAL_REG(TLBIVMID, (b), (v))
+#define SET_CR(b, v)		 SET_GLOBAL_REG(CR, (b), (v))
+#define SET_EAR(b, v)		 SET_GLOBAL_REG(EAR, (b), (v))
+#define SET_ESR(b, v)		 SET_GLOBAL_REG(ESR, (b), (v))
+#define SET_ESRRESTORE(b, v)	 SET_GLOBAL_REG(ESRRESTORE, (b), (v))
+#define SET_ESYNR0(b, v)	 SET_GLOBAL_REG(ESYNR0, (b), (v))
+#define SET_ESYNR1(b, v)	 SET_GLOBAL_REG(ESYNR1, (b), (v))
+#define SET_RPU_ACR(b, v)	 SET_GLOBAL_REG(RPU_ACR, (b), (v))
+
+#define GET_M2VCBR_N(b, N)	 GET_GLOBAL_REG_N(M2VCBR_N, N, (b))
+#define GET_CBACR_N(b, N)	 GET_GLOBAL_REG_N(CBACR_N, N, (b))
+#define GET_TLBTR0(b)		 GET_GLOBAL_REG(TLBTR0, (b))
+#define GET_TLBTR1(b)		 GET_GLOBAL_REG(TLBTR1, (b))
+#define GET_TLBTR2(b)		 GET_GLOBAL_REG(TLBTR2, (b))
+#define GET_TESTBUSCR(b)	 GET_GLOBAL_REG(TESTBUSCR, (b))
+#define GET_GLOBAL_TLBIALL(b)	 GET_GLOBAL_REG(GLOBAL_TLBIALL, (b))
+#define GET_TLBIVMID(b)		 GET_GLOBAL_REG(TLBIVMID, (b))
+#define GET_CR(b)		 GET_GLOBAL_REG(CR, (b))
+#define GET_EAR(b)		 GET_GLOBAL_REG(EAR, (b))
+#define GET_ESR(b)		 GET_GLOBAL_REG(ESR, (b))
+#define GET_ESRRESTORE(b)	 GET_GLOBAL_REG(ESRRESTORE, (b))
+#define GET_ESYNR0(b)		 GET_GLOBAL_REG(ESYNR0, (b))
+#define GET_ESYNR1(b)		 GET_GLOBAL_REG(ESYNR1, (b))
+#define GET_REV(b)		 GET_GLOBAL_REG(REV, (b))
+#define GET_IDR(b)		 GET_GLOBAL_REG(IDR, (b))
+#define GET_RPU_ACR(b)		 GET_GLOBAL_REG(RPU_ACR, (b))
+
+
+/* Context register setters/getters */
+#define SET_SCTLR(b, c, v)	 SET_CTX_REG(SCTLR, (b), (c), (v))
+#define SET_ACTLR(b, c, v)	 SET_CTX_REG(ACTLR, (b), (c), (v))
+#define SET_CONTEXTIDR(b, c, v)	 SET_CTX_REG(CONTEXTIDR, (b), (c), (v))
+#define SET_TTBR0(b, c, v)	 SET_CTX_REG(TTBR0, (b), (c), (v))
+#define SET_TTBR1(b, c, v)	 SET_CTX_REG(TTBR1, (b), (c), (v))
+#define SET_TTBCR(b, c, v)	 SET_CTX_REG(TTBCR, (b), (c), (v))
+#define SET_PAR(b, c, v)	 SET_CTX_REG(PAR, (b), (c), (v))
+#define SET_FSR(b, c, v)	 SET_CTX_REG(FSR, (b), (c), (v))
+#define SET_FSRRESTORE(b, c, v)	 SET_CTX_REG(FSRRESTORE, (b), (c), (v))
+#define SET_FAR(b, c, v)	 SET_CTX_REG(FAR, (b), (c), (v))
+#define SET_FSYNR0(b, c, v)	 SET_CTX_REG(FSYNR0, (b), (c), (v))
+#define SET_FSYNR1(b, c, v)	 SET_CTX_REG(FSYNR1, (b), (c), (v))
+#define SET_PRRR(b, c, v)	 SET_CTX_REG(PRRR, (b), (c), (v))
+#define SET_NMRR(b, c, v)	 SET_CTX_REG(NMRR, (b), (c), (v))
+#define SET_TLBLKCR(b, c, v)	 SET_CTX_REG(TLBLCKR, (b), (c), (v))
+#define SET_V2PSR(b, c, v)	 SET_CTX_REG(V2PSR, (b), (c), (v))
+#define SET_TLBFLPTER(b, c, v)	 SET_CTX_REG(TLBFLPTER, (b), (c), (v))
+#define SET_TLBSLPTER(b, c, v)	 SET_CTX_REG(TLBSLPTER, (b), (c), (v))
+#define SET_BFBCR(b, c, v)	 SET_CTX_REG(BFBCR, (b), (c), (v))
+#define SET_CTX_TLBIALL(b, c, v) SET_CTX_REG(CTX_TLBIALL, (b), (c), (v))
+#define SET_TLBIASID(b, c, v)	 SET_CTX_REG(TLBIASID, (b), (c), (v))
+#define SET_TLBIVA(b, c, v)	 SET_CTX_REG(TLBIVA, (b), (c), (v))
+#define SET_TLBIVAA(b, c, v)	 SET_CTX_REG(TLBIVAA, (b), (c), (v))
+#define SET_V2PPR(b, c, v)	 SET_CTX_REG(V2PPR, (b), (c), (v))
+#define SET_V2PPW(b, c, v)	 SET_CTX_REG(V2PPW, (b), (c), (v))
+#define SET_V2PUR(b, c, v)	 SET_CTX_REG(V2PUR, (b), (c), (v))
+#define SET_V2PUW(b, c, v)	 SET_CTX_REG(V2PUW, (b), (c), (v))
+#define SET_RESUME(b, c, v)	 SET_CTX_REG(RESUME, (b), (c), (v))
+
+#define GET_SCTLR(b, c)		 GET_CTX_REG(SCTLR, (b), (c))
+#define GET_ACTLR(b, c)		 GET_CTX_REG(ACTLR, (b), (c))
+#define GET_CONTEXTIDR(b, c)	 GET_CTX_REG(CONTEXTIDR, (b), (c))
+#define GET_TTBR0(b, c)		 GET_CTX_REG(TTBR0, (b), (c))
+#define GET_TTBR1(b, c)		 GET_CTX_REG(TTBR1, (b), (c))
+#define GET_TTBCR(b, c)		 GET_CTX_REG(TTBCR, (b), (c))
+#define GET_PAR(b, c)		 GET_CTX_REG(PAR, (b), (c))
+#define GET_FSR(b, c)		 GET_CTX_REG(FSR, (b), (c))
+#define GET_FSRRESTORE(b, c)	 GET_CTX_REG(FSRRESTORE, (b), (c))
+#define GET_FAR(b, c)		 GET_CTX_REG(FAR, (b), (c))
+#define GET_FSYNR0(b, c)	 GET_CTX_REG(FSYNR0, (b), (c))
+#define GET_FSYNR1(b, c)	 GET_CTX_REG(FSYNR1, (b), (c))
+#define GET_PRRR(b, c)		 GET_CTX_REG(PRRR, (b), (c))
+#define GET_NMRR(b, c)		 GET_CTX_REG(NMRR, (b), (c))
+#define GET_TLBLCKR(b, c)	 GET_CTX_REG(TLBLCKR, (b), (c))
+#define GET_V2PSR(b, c)		 GET_CTX_REG(V2PSR, (b), (c))
+#define GET_TLBFLPTER(b, c)	 GET_CTX_REG(TLBFLPTER, (b), (c))
+#define GET_TLBSLPTER(b, c)	 GET_CTX_REG(TLBSLPTER, (b), (c))
+#define GET_BFBCR(b, c)		 GET_CTX_REG(BFBCR, (b), (c))
+#define GET_CTX_TLBIALL(b, c)	 GET_CTX_REG(CTX_TLBIALL, (b), (c))
+#define GET_TLBIASID(b, c)	 GET_CTX_REG(TLBIASID, (b), (c))
+#define GET_TLBIVA(b, c)	 GET_CTX_REG(TLBIVA, (b), (c))
+#define GET_TLBIVAA(b, c)	 GET_CTX_REG(TLBIVAA, (b), (c))
+#define GET_V2PPR(b, c)		 GET_CTX_REG(V2PPR, (b), (c))
+#define GET_V2PPW(b, c)		 GET_CTX_REG(V2PPW, (b), (c))
+#define GET_V2PUR(b, c)		 GET_CTX_REG(V2PUR, (b), (c))
+#define GET_V2PUW(b, c)		 GET_CTX_REG(V2PUW, (b), (c))
+#define GET_RESUME(b, c)	 GET_CTX_REG(RESUME, (b), (c))
+
+
+/* Global field setters / getters */
+/* Global Field Setters: */
+/* CBACR_N */
+#define SET_RWVMID(b, n, v)   SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWVMID, v)
+#define SET_RWE(b, n, v)      SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWE, v)
+#define SET_RWGE(b, n, v)     SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWGE, v)
+#define SET_CBVMID(b, n, v)   SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), CBVMID, v)
+#define SET_IRPTNDX(b, n, v)  SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), IRPTNDX, v)
+
+
+/* M2VCBR_N */
+#define SET_VMID(b, n, v)     SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), VMID, v)
+#define SET_CBNDX(b, n, v)    SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), CBNDX, v)
+#define SET_BYPASSD(b, n, v)  SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BYPASSD, v)
+#define SET_BPRCOSH(b, n, v)  SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCOSH, v)
+#define SET_BPRCISH(b, n, v)  SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCISH, v)
+#define SET_BPRCNSH(b, n, v)  SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCNSH, v)
+#define SET_BPSHCFG(b, n, v)  SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPSHCFG, v)
+#define SET_NSCFG(b, n, v)    SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), NSCFG, v)
+#define SET_BPMTCFG(b, n, v)  SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPMTCFG, v)
+#define SET_BPMEMTYPE(b, n, v) \
+	SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPMEMTYPE, v)
+
+
+/* CR */
+#define SET_RPUE(b, v)		 SET_GLOBAL_FIELD(b, CR, RPUE, v)
+#define SET_RPUERE(b, v)	 SET_GLOBAL_FIELD(b, CR, RPUERE, v)
+#define SET_RPUEIE(b, v)	 SET_GLOBAL_FIELD(b, CR, RPUEIE, v)
+#define SET_DCDEE(b, v)		 SET_GLOBAL_FIELD(b, CR, DCDEE, v)
+#define SET_CLIENTPD(b, v)       SET_GLOBAL_FIELD(b, CR, CLIENTPD, v)
+#define SET_STALLD(b, v)	 SET_GLOBAL_FIELD(b, CR, STALLD, v)
+#define SET_TLBLKCRWE(b, v)      SET_GLOBAL_FIELD(b, CR, TLBLKCRWE, v)
+#define SET_CR_TLBIALLCFG(b, v)  SET_GLOBAL_FIELD(b, CR, CR_TLBIALLCFG, v)
+#define SET_TLBIVMIDCFG(b, v)    SET_GLOBAL_FIELD(b, CR, TLBIVMIDCFG, v)
+#define SET_CR_HUME(b, v)        SET_GLOBAL_FIELD(b, CR, CR_HUME, v)
+
+
+/* ESR */
+#define SET_CFG(b, v)		 SET_GLOBAL_FIELD(b, ESR, CFG, v)
+#define SET_BYPASS(b, v)	 SET_GLOBAL_FIELD(b, ESR, BYPASS, v)
+#define SET_ESR_MULTI(b, v)      SET_GLOBAL_FIELD(b, ESR, ESR_MULTI, v)
+
+
+/* ESYNR0 */
+#define SET_ESYNR0_AMID(b, v)    SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_AMID, v)
+#define SET_ESYNR0_APID(b, v)    SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_APID, v)
+#define SET_ESYNR0_ABID(b, v)    SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_ABID, v)
+#define SET_ESYNR0_AVMID(b, v)   SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_AVMID, v)
+#define SET_ESYNR0_ATID(b, v)    SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_ATID, v)
+
+
+/* ESYNR1 */
+#define SET_ESYNR1_AMEMTYPE(b, v) \
+			SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AMEMTYPE, v)
+#define SET_ESYNR1_ASHARED(b, v)  SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ASHARED, v)
+#define SET_ESYNR1_AINNERSHARED(b, v) \
+			SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AINNERSHARED, v)
+#define SET_ESYNR1_APRIV(b, v)   SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_APRIV, v)
+#define SET_ESYNR1_APROTNS(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_APROTNS, v)
+#define SET_ESYNR1_AINST(b, v)   SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AINST, v)
+#define SET_ESYNR1_AWRITE(b, v)  SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AWRITE, v)
+#define SET_ESYNR1_ABURST(b, v)  SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ABURST, v)
+#define SET_ESYNR1_ALEN(b, v)    SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ALEN, v)
+#define SET_ESYNR1_ASIZE(b, v)   SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ASIZE, v)
+#define SET_ESYNR1_ALOCK(b, v)   SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ALOCK, v)
+#define SET_ESYNR1_AOOO(b, v)    SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AOOO, v)
+#define SET_ESYNR1_AFULL(b, v)   SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AFULL, v)
+#define SET_ESYNR1_AC(b, v)      SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AC, v)
+#define SET_ESYNR1_DCD(b, v)     SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_DCD, v)
+
+
+/* TESTBUSCR */
+#define SET_TBE(b, v)		 SET_GLOBAL_FIELD(b, TESTBUSCR, TBE, v)
+#define SET_SPDMBE(b, v)	 SET_GLOBAL_FIELD(b, TESTBUSCR, SPDMBE, v)
+#define SET_WGSEL(b, v)		 SET_GLOBAL_FIELD(b, TESTBUSCR, WGSEL, v)
+#define SET_TBLSEL(b, v)	 SET_GLOBAL_FIELD(b, TESTBUSCR, TBLSEL, v)
+#define SET_TBHSEL(b, v)	 SET_GLOBAL_FIELD(b, TESTBUSCR, TBHSEL, v)
+#define SET_SPDM0SEL(b, v)       SET_GLOBAL_FIELD(b, TESTBUSCR, SPDM0SEL, v)
+#define SET_SPDM1SEL(b, v)       SET_GLOBAL_FIELD(b, TESTBUSCR, SPDM1SEL, v)
+#define SET_SPDM2SEL(b, v)       SET_GLOBAL_FIELD(b, TESTBUSCR, SPDM2SEL, v)
+#define SET_SPDM3SEL(b, v)       SET_GLOBAL_FIELD(b, TESTBUSCR, SPDM3SEL, v)
+
+
+/* TLBIVMID */
+#define SET_TLBIVMID_VMID(b, v)  SET_GLOBAL_FIELD(b, TLBIVMID, TLBIVMID_VMID, v)
+
+
+/* TLBRSW */
+#define SET_TLBRSW_INDEX(b, v)   SET_GLOBAL_FIELD(b, TLBRSW, TLBRSW_INDEX, v)
+#define SET_TLBBFBS(b, v)	 SET_GLOBAL_FIELD(b, TLBRSW, TLBBFBS, v)
+
+
+/* TLBTR0 */
+#define SET_PR(b, v)		 SET_GLOBAL_FIELD(b, TLBTR0, PR, v)
+#define SET_PW(b, v)		 SET_GLOBAL_FIELD(b, TLBTR0, PW, v)
+#define SET_UR(b, v)		 SET_GLOBAL_FIELD(b, TLBTR0, UR, v)
+#define SET_UW(b, v)		 SET_GLOBAL_FIELD(b, TLBTR0, UW, v)
+#define SET_XN(b, v)		 SET_GLOBAL_FIELD(b, TLBTR0, XN, v)
+#define SET_NSDESC(b, v)	 SET_GLOBAL_FIELD(b, TLBTR0, NSDESC, v)
+#define SET_ISH(b, v)		 SET_GLOBAL_FIELD(b, TLBTR0, ISH, v)
+#define SET_SH(b, v)		 SET_GLOBAL_FIELD(b, TLBTR0, SH, v)
+#define SET_MT(b, v)		 SET_GLOBAL_FIELD(b, TLBTR0, MT, v)
+#define SET_DPSIZR(b, v)	 SET_GLOBAL_FIELD(b, TLBTR0, DPSIZR, v)
+#define SET_DPSIZC(b, v)	 SET_GLOBAL_FIELD(b, TLBTR0, DPSIZC, v)
+
+
+/* TLBTR1 */
+#define SET_TLBTR1_VMID(b, v)    SET_GLOBAL_FIELD(b, TLBTR1, TLBTR1_VMID, v)
+#define SET_TLBTR1_PA(b, v)      SET_GLOBAL_FIELD(b, TLBTR1, TLBTR1_PA, v)
+
+
+/* TLBTR2 */
+#define SET_TLBTR2_ASID(b, v)    SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_ASID, v)
+#define SET_TLBTR2_V(b, v)       SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_V, v)
+#define SET_TLBTR2_NSTID(b, v)   SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_NSTID, v)
+#define SET_TLBTR2_NV(b, v)      SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_NV, v)
+#define SET_TLBTR2_VA(b, v)      SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_VA, v)
+
+
+/* Global Field Getters */
+/* CBACR_N */
+#define GET_RWVMID(b, n)	 GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWVMID)
+#define GET_RWE(b, n)		 GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWE)
+#define GET_RWGE(b, n)		 GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWGE)
+#define GET_CBVMID(b, n)	 GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), CBVMID)
+#define GET_IRPTNDX(b, n)	 GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), IRPTNDX)
+
+
+/* M2VCBR_N */
+#define GET_VMID(b, n)       GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), VMID)
+#define GET_CBNDX(b, n)      GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), CBNDX)
+#define GET_BYPASSD(b, n)    GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BYPASSD)
+#define GET_BPRCOSH(b, n)    GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCOSH)
+#define GET_BPRCISH(b, n)    GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCISH)
+#define GET_BPRCNSH(b, n)    GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCNSH)
+#define GET_BPSHCFG(b, n)    GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPSHCFG)
+#define GET_NSCFG(b, n)      GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), NSCFG)
+#define GET_BPMTCFG(b, n)    GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPMTCFG)
+#define GET_BPMEMTYPE(b, n)  GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPMEMTYPE)
+
+
+/* CR */
+#define GET_RPUE(b)		 GET_GLOBAL_FIELD(b, CR, RPUE)
+#define GET_RPUERE(b)		 GET_GLOBAL_FIELD(b, CR, RPUERE)
+#define GET_RPUEIE(b)		 GET_GLOBAL_FIELD(b, CR, RPUEIE)
+#define GET_DCDEE(b)		 GET_GLOBAL_FIELD(b, CR, DCDEE)
+#define GET_CLIENTPD(b)		 GET_GLOBAL_FIELD(b, CR, CLIENTPD)
+#define GET_STALLD(b)		 GET_GLOBAL_FIELD(b, CR, STALLD)
+#define GET_TLBLKCRWE(b)	 GET_GLOBAL_FIELD(b, CR, TLBLKCRWE)
+#define GET_CR_TLBIALLCFG(b)	 GET_GLOBAL_FIELD(b, CR, CR_TLBIALLCFG)
+#define GET_TLBIVMIDCFG(b)	 GET_GLOBAL_FIELD(b, CR, TLBIVMIDCFG)
+#define GET_CR_HUME(b)		 GET_GLOBAL_FIELD(b, CR, CR_HUME)
+
+
+/* ESR */
+#define GET_CFG(b)		 GET_GLOBAL_FIELD(b, ESR, CFG)
+#define GET_BYPASS(b)		 GET_GLOBAL_FIELD(b, ESR, BYPASS)
+#define GET_ESR_MULTI(b)	 GET_GLOBAL_FIELD(b, ESR, ESR_MULTI)
+
+
+/* ESYNR0 */
+#define GET_ESYNR0_AMID(b)	 GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_AMID)
+#define GET_ESYNR0_APID(b)	 GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_APID)
+#define GET_ESYNR0_ABID(b)	 GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_ABID)
+#define GET_ESYNR0_AVMID(b)	 GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_AVMID)
+#define GET_ESYNR0_ATID(b)	 GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_ATID)
+
+
+/* ESYNR1 */
+#define GET_ESYNR1_AMEMTYPE(b)   GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AMEMTYPE)
+#define GET_ESYNR1_ASHARED(b)    GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ASHARED)
+#define GET_ESYNR1_AINNERSHARED(b) \
+			GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AINNERSHARED)
+#define GET_ESYNR1_APRIV(b)      GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_APRIV)
+#define GET_ESYNR1_APROTNS(b)	 GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_APROTNS)
+#define GET_ESYNR1_AINST(b)	 GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AINST)
+#define GET_ESYNR1_AWRITE(b)	 GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AWRITE)
+#define GET_ESYNR1_ABURST(b)	 GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ABURST)
+#define GET_ESYNR1_ALEN(b)	 GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ALEN)
+#define GET_ESYNR1_ASIZE(b)	 GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ASIZE)
+#define GET_ESYNR1_ALOCK(b)	 GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ALOCK)
+#define GET_ESYNR1_AOOO(b)	 GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AOOO)
+#define GET_ESYNR1_AFULL(b)	 GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AFULL)
+#define GET_ESYNR1_AC(b)	 GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AC)
+#define GET_ESYNR1_DCD(b)	 GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_DCD)
+
+
+/* IDR */
+#define GET_NM2VCBMT(b)		 GET_GLOBAL_FIELD(b, IDR, NM2VCBMT)
+#define GET_HTW(b)		 GET_GLOBAL_FIELD(b, IDR, HTW)
+#define GET_HUM(b)		 GET_GLOBAL_FIELD(b, IDR, HUM)
+#define GET_TLBSIZE(b)		 GET_GLOBAL_FIELD(b, IDR, TLBSIZE)
+#define GET_NCB(b)		 GET_GLOBAL_FIELD(b, IDR, NCB)
+#define GET_NIRPT(b)		 GET_GLOBAL_FIELD(b, IDR, NIRPT)
+
+
+/* REV */
+#define GET_MAJOR(b)		 GET_GLOBAL_FIELD(b, REV, MAJOR)
+#define GET_MINOR(b)		 GET_GLOBAL_FIELD(b, REV, MINOR)
+
+
+/* TESTBUSCR */
+#define GET_TBE(b)		 GET_GLOBAL_FIELD(b, TESTBUSCR, TBE)
+#define GET_SPDMBE(b)		 GET_GLOBAL_FIELD(b, TESTBUSCR, SPDMBE)
+#define GET_WGSEL(b)		 GET_GLOBAL_FIELD(b, TESTBUSCR, WGSEL)
+#define GET_TBLSEL(b)		 GET_GLOBAL_FIELD(b, TESTBUSCR, TBLSEL)
+#define GET_TBHSEL(b)		 GET_GLOBAL_FIELD(b, TESTBUSCR, TBHSEL)
+#define GET_SPDM0SEL(b)		 GET_GLOBAL_FIELD(b, TESTBUSCR, SPDM0SEL)
+#define GET_SPDM1SEL(b)		 GET_GLOBAL_FIELD(b, TESTBUSCR, SPDM1SEL)
+#define GET_SPDM2SEL(b)		 GET_GLOBAL_FIELD(b, TESTBUSCR, SPDM2SEL)
+#define GET_SPDM3SEL(b)		 GET_GLOBAL_FIELD(b, TESTBUSCR, SPDM3SEL)
+
+
+/* TLBIVMID */
+#define GET_TLBIVMID_VMID(b)	 GET_GLOBAL_FIELD(b, TLBIVMID, TLBIVMID_VMID)
+
+
+/* TLBTR0 */
+#define GET_PR(b)		 GET_GLOBAL_FIELD(b, TLBTR0, PR)
+#define GET_PW(b)		 GET_GLOBAL_FIELD(b, TLBTR0, PW)
+#define GET_UR(b)		 GET_GLOBAL_FIELD(b, TLBTR0, UR)
+#define GET_UW(b)		 GET_GLOBAL_FIELD(b, TLBTR0, UW)
+#define GET_XN(b)		 GET_GLOBAL_FIELD(b, TLBTR0, XN)
+#define GET_NSDESC(b)		 GET_GLOBAL_FIELD(b, TLBTR0, NSDESC)
+#define GET_ISH(b)		 GET_GLOBAL_FIELD(b, TLBTR0, ISH)
+#define GET_SH(b)		 GET_GLOBAL_FIELD(b, TLBTR0, SH)
+#define GET_MT(b)		 GET_GLOBAL_FIELD(b, TLBTR0, MT)
+#define GET_DPSIZR(b)		 GET_GLOBAL_FIELD(b, TLBTR0, DPSIZR)
+#define GET_DPSIZC(b)		 GET_GLOBAL_FIELD(b, TLBTR0, DPSIZC)
+
+
+/* TLBTR1 */
+#define GET_TLBTR1_VMID(b)	 GET_GLOBAL_FIELD(b, TLBTR1, TLBTR1_VMID)
+#define GET_TLBTR1_PA(b)	 GET_GLOBAL_FIELD(b, TLBTR1, TLBTR1_PA)
+
+
+/* TLBTR2 */
+#define GET_TLBTR2_ASID(b)	 GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_ASID)
+#define GET_TLBTR2_V(b)		 GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_V)
+#define GET_TLBTR2_NSTID(b)	 GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_NSTID)
+#define GET_TLBTR2_NV(b)	 GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_NV)
+#define GET_TLBTR2_VA(b)	 GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_VA)
+
+
+/* Context Register setters / getters */
+/* Context Register setters */
+/* ACTLR */
+#define SET_CFERE(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, CFERE, v)
+#define SET_CFEIE(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, CFEIE, v)
+#define SET_PTSHCFG(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, PTSHCFG, v)
+#define SET_RCOSH(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, RCOSH, v)
+#define SET_RCISH(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, RCISH, v)
+#define SET_RCNSH(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, RCNSH, v)
+#define SET_PRIVCFG(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, PRIVCFG, v)
+#define SET_DNA(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, DNA, v)
+#define SET_DNLV2PA(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, DNLV2PA, v)
+#define SET_TLBMCFG(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, TLBMCFG, v)
+#define SET_CFCFG(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, CFCFG, v)
+#define SET_TIPCF(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, TIPCF, v)
+#define SET_V2PCFG(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, V2PCFG, v)
+#define SET_HUME(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, HUME, v)
+#define SET_PTMTCFG(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, PTMTCFG, v)
+#define SET_PTMEMTYPE(b, c, v)	 SET_CONTEXT_FIELD(b, c, ACTLR, PTMEMTYPE, v)
+
+
+/* BFBCR */
+#define SET_BFBDFE(b, c, v)	 SET_CONTEXT_FIELD(b, c, BFBCR, BFBDFE, v)
+#define SET_BFBSFE(b, c, v)	 SET_CONTEXT_FIELD(b, c, BFBCR, BFBSFE, v)
+#define SET_SFVS(b, c, v)	 SET_CONTEXT_FIELD(b, c, BFBCR, SFVS, v)
+#define SET_FLVIC(b, c, v)	 SET_CONTEXT_FIELD(b, c, BFBCR, FLVIC, v)
+#define SET_SLVIC(b, c, v)	 SET_CONTEXT_FIELD(b, c, BFBCR, SLVIC, v)
+
+
+/* CONTEXTIDR */
+#define SET_CONTEXTIDR_ASID(b, c, v)   \
+		SET_CONTEXT_FIELD(b, c, CONTEXTIDR, CONTEXTIDR_ASID, v)
+#define SET_CONTEXTIDR_PROCID(b, c, v) \
+		SET_CONTEXT_FIELD(b, c, CONTEXTIDR, PROCID, v)
+
+
+/* FSR */
+#define SET_TF(b, c, v)		 SET_CONTEXT_FIELD(b, c, FSR, TF, v)
+#define SET_AFF(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSR, AFF, v)
+#define SET_APF(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSR, APF, v)
+#define SET_TLBMF(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSR, TLBMF, v)
+#define SET_HTWDEEF(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSR, HTWDEEF, v)
+#define SET_HTWSEEF(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSR, HTWSEEF, v)
+#define SET_MHF(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSR, MHF, v)
+#define SET_SL(b, c, v)		 SET_CONTEXT_FIELD(b, c, FSR, SL, v)
+#define SET_SS(b, c, v)		 SET_CONTEXT_FIELD(b, c, FSR, SS, v)
+#define SET_MULTI(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSR, MULTI, v)
+
+
+/* FSYNR0 */
+#define SET_AMID(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR0, AMID, v)
+#define SET_APID(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR0, APID, v)
+#define SET_ABID(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR0, ABID, v)
+#define SET_ATID(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR0, ATID, v)
+
+
+/* FSYNR1 */
+#define SET_AMEMTYPE(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR1, AMEMTYPE, v)
+#define SET_ASHARED(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR1, ASHARED, v)
+#define SET_AINNERSHARED(b, c, v)  \
+				SET_CONTEXT_FIELD(b, c, FSYNR1, AINNERSHARED, v)
+#define SET_APRIV(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR1, APRIV, v)
+#define SET_APROTNS(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR1, APROTNS, v)
+#define SET_AINST(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR1, AINST, v)
+#define SET_AWRITE(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR1, AWRITE, v)
+#define SET_ABURST(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR1, ABURST, v)
+#define SET_ALEN(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR1, ALEN, v)
+#define SET_FSYNR1_ASIZE(b, c, v) \
+				SET_CONTEXT_FIELD(b, c, FSYNR1, FSYNR1_ASIZE, v)
+#define SET_ALOCK(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR1, ALOCK, v)
+#define SET_AFULL(b, c, v)	 SET_CONTEXT_FIELD(b, c, FSYNR1, AFULL, v)
+
+
+/* NMRR */
+#define SET_ICPC0(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, ICPC0, v)
+#define SET_ICPC1(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, ICPC1, v)
+#define SET_ICPC2(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, ICPC2, v)
+#define SET_ICPC3(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, ICPC3, v)
+#define SET_ICPC4(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, ICPC4, v)
+#define SET_ICPC5(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, ICPC5, v)
+#define SET_ICPC6(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, ICPC6, v)
+#define SET_ICPC7(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, ICPC7, v)
+#define SET_OCPC0(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, OCPC0, v)
+#define SET_OCPC1(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, OCPC1, v)
+#define SET_OCPC2(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, OCPC2, v)
+#define SET_OCPC3(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, OCPC3, v)
+#define SET_OCPC4(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, OCPC4, v)
+#define SET_OCPC5(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, OCPC5, v)
+#define SET_OCPC6(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, OCPC6, v)
+#define SET_OCPC7(b, c, v)	 SET_CONTEXT_FIELD(b, c, NMRR, OCPC7, v)
+
+
+/* PAR */
+#define SET_FAULT(b, c, v)	 SET_CONTEXT_FIELD(b, c, PAR, FAULT, v)
+
+#define SET_FAULT_TF(b, c, v)	 SET_CONTEXT_FIELD(b, c, PAR, FAULT_TF, v)
+#define SET_FAULT_AFF(b, c, v)	 SET_CONTEXT_FIELD(b, c, PAR, FAULT_AFF, v)
+#define SET_FAULT_APF(b, c, v)	 SET_CONTEXT_FIELD(b, c, PAR, FAULT_APF, v)
+#define SET_FAULT_TLBMF(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, FAULT_TLBMF, v)
+#define SET_FAULT_HTWDEEF(b, c, v) \
+				SET_CONTEXT_FIELD(b, c, PAR, FAULT_HTWDEEF, v)
+#define SET_FAULT_HTWSEEF(b, c, v) \
+				SET_CONTEXT_FIELD(b, c, PAR, FAULT_HTWSEEF, v)
+#define SET_FAULT_MHF(b, c, v)	 SET_CONTEXT_FIELD(b, c, PAR, FAULT_MHF, v)
+#define SET_FAULT_SL(b, c, v)	 SET_CONTEXT_FIELD(b, c, PAR, FAULT_SL, v)
+#define SET_FAULT_SS(b, c, v)	 SET_CONTEXT_FIELD(b, c, PAR, FAULT_SS, v)
+
+#define SET_NOFAULT_SS(b, c, v)	 SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_SS, v)
+#define SET_NOFAULT_MT(b, c, v)	 SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_MT, v)
+#define SET_NOFAULT_SH(b, c, v)	 SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_SH, v)
+#define SET_NOFAULT_NS(b, c, v)	 SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_NS, v)
+#define SET_NOFAULT_NOS(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_NOS, v)
+#define SET_NPFAULT_PA(b, c, v)	 SET_CONTEXT_FIELD(b, c, PAR, NPFAULT_PA, v)
+
+
+/* PRRR */
+#define SET_MTC0(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, MTC0, v)
+#define SET_MTC1(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, MTC1, v)
+#define SET_MTC2(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, MTC2, v)
+#define SET_MTC3(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, MTC3, v)
+#define SET_MTC4(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, MTC4, v)
+#define SET_MTC5(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, MTC5, v)
+#define SET_MTC6(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, MTC6, v)
+#define SET_MTC7(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, MTC7, v)
+#define SET_SHDSH0(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, SHDSH0, v)
+#define SET_SHDSH1(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, SHDSH1, v)
+#define SET_SHNMSH0(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, SHNMSH0, v)
+#define SET_SHNMSH1(b, c, v)     SET_CONTEXT_FIELD(b, c, PRRR, SHNMSH1, v)
+#define SET_NOS0(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, NOS0, v)
+#define SET_NOS1(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, NOS1, v)
+#define SET_NOS2(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, NOS2, v)
+#define SET_NOS3(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, NOS3, v)
+#define SET_NOS4(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, NOS4, v)
+#define SET_NOS5(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, NOS5, v)
+#define SET_NOS6(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, NOS6, v)
+#define SET_NOS7(b, c, v)	 SET_CONTEXT_FIELD(b, c, PRRR, NOS7, v)
+
+
+/* RESUME */
+#define SET_TNR(b, c, v)	 SET_CONTEXT_FIELD(b, c, RESUME, TNR, v)
+
+
+/* SCTLR */
+#define SET_M(b, c, v)		 SET_CONTEXT_FIELD(b, c, SCTLR, M, v)
+#define SET_TRE(b, c, v)	 SET_CONTEXT_FIELD(b, c, SCTLR, TRE, v)
+#define SET_AFE(b, c, v)	 SET_CONTEXT_FIELD(b, c, SCTLR, AFE, v)
+#define SET_HAF(b, c, v)	 SET_CONTEXT_FIELD(b, c, SCTLR, HAF, v)
+#define SET_BE(b, c, v)		 SET_CONTEXT_FIELD(b, c, SCTLR, BE, v)
+#define SET_AFFD(b, c, v)	 SET_CONTEXT_FIELD(b, c, SCTLR, AFFD, v)
+
+
+/* TLBLKCR */
+#define SET_LKE(b, c, v)	   SET_CONTEXT_FIELD(b, c, TLBLKCR, LKE, v)
+#define SET_TLBLKCR_TLBIALLCFG(b, c, v) \
+			SET_CONTEXT_FIELD(b, c, TLBLKCR, TLBLCKR_TLBIALLCFG, v)
+#define SET_TLBIASIDCFG(b, c, v) \
+			SET_CONTEXT_FIELD(b, c, TLBLKCR, TLBIASIDCFG, v)
+#define SET_TLBIVAACFG(b, c, v)	SET_CONTEXT_FIELD(b, c, TLBLKCR, TLBIVAACFG, v)
+#define SET_FLOOR(b, c, v)	SET_CONTEXT_FIELD(b, c, TLBLKCR, FLOOR, v)
+#define SET_VICTIM(b, c, v)	SET_CONTEXT_FIELD(b, c, TLBLKCR, VICTIM, v)
+
+
+/* TTBCR */
+#define SET_N(b, c, v)	         SET_CONTEXT_FIELD(b, c, TTBCR, N, v)
+#define SET_PD0(b, c, v)	 SET_CONTEXT_FIELD(b, c, TTBCR, PD0, v)
+#define SET_PD1(b, c, v)	 SET_CONTEXT_FIELD(b, c, TTBCR, PD1, v)
+
+
+/* TTBR0 */
+#define SET_TTBR0_IRGNH(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_IRGNH, v)
+#define SET_TTBR0_SH(b, c, v)	 SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_SH, v)
+#define SET_TTBR0_ORGN(b, c, v)	 SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_ORGN, v)
+#define SET_TTBR0_NOS(b, c, v)	 SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_NOS, v)
+#define SET_TTBR0_IRGNL(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_IRGNL, v)
+#define SET_TTBR0_PA(b, c, v)	 SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_PA, v)
+
+
+/* TTBR1 */
+#define SET_TTBR1_IRGNH(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_IRGNH, v)
+#define SET_TTBR1_SH(b, c, v)	 SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_SH, v)
+#define SET_TTBR1_ORGN(b, c, v)	 SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_ORGN, v)
+#define SET_TTBR1_NOS(b, c, v)	 SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_NOS, v)
+#define SET_TTBR1_IRGNL(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_IRGNL, v)
+#define SET_TTBR1_PA(b, c, v)	 SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_PA, v)
+
+
+/* V2PSR */
+#define SET_HIT(b, c, v)	 SET_CONTEXT_FIELD(b, c, V2PSR, HIT, v)
+#define SET_INDEX(b, c, v)	 SET_CONTEXT_FIELD(b, c, V2PSR, INDEX, v)
+
+
+/* Context Register getters */
+/* ACTLR */
+#define GET_CFERE(b, c)	        GET_CONTEXT_FIELD(b, c, ACTLR, CFERE)
+#define GET_CFEIE(b, c)	        GET_CONTEXT_FIELD(b, c, ACTLR, CFEIE)
+#define GET_PTSHCFG(b, c)       GET_CONTEXT_FIELD(b, c, ACTLR, PTSHCFG)
+#define GET_RCOSH(b, c)	        GET_CONTEXT_FIELD(b, c, ACTLR, RCOSH)
+#define GET_RCISH(b, c)	        GET_CONTEXT_FIELD(b, c, ACTLR, RCISH)
+#define GET_RCNSH(b, c)	        GET_CONTEXT_FIELD(b, c, ACTLR, RCNSH)
+#define GET_PRIVCFG(b, c)       GET_CONTEXT_FIELD(b, c, ACTLR, PRIVCFG)
+#define GET_DNA(b, c)	        GET_CONTEXT_FIELD(b, c, ACTLR, DNA)
+#define GET_DNLV2PA(b, c)       GET_CONTEXT_FIELD(b, c, ACTLR, DNLV2PA)
+#define GET_TLBMCFG(b, c)       GET_CONTEXT_FIELD(b, c, ACTLR, TLBMCFG)
+#define GET_CFCFG(b, c)	        GET_CONTEXT_FIELD(b, c, ACTLR, CFCFG)
+#define GET_TIPCF(b, c)	        GET_CONTEXT_FIELD(b, c, ACTLR, TIPCF)
+#define GET_V2PCFG(b, c)        GET_CONTEXT_FIELD(b, c, ACTLR, V2PCFG)
+#define GET_HUME(b, c)	        GET_CONTEXT_FIELD(b, c, ACTLR, HUME)
+#define GET_PTMTCFG(b, c)       GET_CONTEXT_FIELD(b, c, ACTLR, PTMTCFG)
+#define GET_PTMEMTYPE(b, c)     GET_CONTEXT_FIELD(b, c, ACTLR, PTMEMTYPE)
+
+/* BFBCR */
+#define GET_BFBDFE(b, c)	GET_CONTEXT_FIELD(b, c, BFBCR, BFBDFE)
+#define GET_BFBSFE(b, c)	GET_CONTEXT_FIELD(b, c, BFBCR, BFBSFE)
+#define GET_SFVS(b, c)		GET_CONTEXT_FIELD(b, c, BFBCR, SFVS)
+#define GET_FLVIC(b, c)		GET_CONTEXT_FIELD(b, c, BFBCR, FLVIC)
+#define GET_SLVIC(b, c)		GET_CONTEXT_FIELD(b, c, BFBCR, SLVIC)
+
+
+/* CONTEXTIDR */
+#define GET_CONTEXTIDR_ASID(b, c) \
+			GET_CONTEXT_FIELD(b, c, CONTEXTIDR, CONTEXTIDR_ASID)
+#define GET_CONTEXTIDR_PROCID(b, c) GET_CONTEXT_FIELD(b, c, CONTEXTIDR, PROCID)
+
+
+/* FSR */
+#define GET_TF(b, c)		GET_CONTEXT_FIELD(b, c, FSR, TF)
+#define GET_AFF(b, c)		GET_CONTEXT_FIELD(b, c, FSR, AFF)
+#define GET_APF(b, c)		GET_CONTEXT_FIELD(b, c, FSR, APF)
+#define GET_TLBMF(b, c)		GET_CONTEXT_FIELD(b, c, FSR, TLBMF)
+#define GET_HTWDEEF(b, c)	GET_CONTEXT_FIELD(b, c, FSR, HTWDEEF)
+#define GET_HTWSEEF(b, c)	GET_CONTEXT_FIELD(b, c, FSR, HTWSEEF)
+#define GET_MHF(b, c)		GET_CONTEXT_FIELD(b, c, FSR, MHF)
+#define GET_SL(b, c)		GET_CONTEXT_FIELD(b, c, FSR, SL)
+#define GET_SS(b, c)		GET_CONTEXT_FIELD(b, c, FSR, SS)
+#define GET_MULTI(b, c)		GET_CONTEXT_FIELD(b, c, FSR, MULTI)
+
+
+/* FSYNR0 */
+#define GET_AMID(b, c)		GET_CONTEXT_FIELD(b, c, FSYNR0, AMID)
+#define GET_APID(b, c)		GET_CONTEXT_FIELD(b, c, FSYNR0, APID)
+#define GET_ABID(b, c)		GET_CONTEXT_FIELD(b, c, FSYNR0, ABID)
+#define GET_ATID(b, c)		GET_CONTEXT_FIELD(b, c, FSYNR0, ATID)
+
+
+/* FSYNR1 */
+#define GET_AMEMTYPE(b, c)	GET_CONTEXT_FIELD(b, c, FSYNR1, AMEMTYPE)
+#define GET_ASHARED(b, c)	GET_CONTEXT_FIELD(b, c, FSYNR1, ASHARED)
+#define GET_AINNERSHARED(b, c)  GET_CONTEXT_FIELD(b, c, FSYNR1, AINNERSHARED)
+#define GET_APRIV(b, c)		GET_CONTEXT_FIELD(b, c, FSYNR1, APRIV)
+#define GET_APROTNS(b, c)	GET_CONTEXT_FIELD(b, c, FSYNR1, APROTNS)
+#define GET_AINST(b, c)		GET_CONTEXT_FIELD(b, c, FSYNR1, AINST)
+#define GET_AWRITE(b, c)	GET_CONTEXT_FIELD(b, c, FSYNR1, AWRITE)
+#define GET_ABURST(b, c)	GET_CONTEXT_FIELD(b, c, FSYNR1, ABURST)
+#define GET_ALEN(b, c)		GET_CONTEXT_FIELD(b, c, FSYNR1, ALEN)
+#define GET_FSYNR1_ASIZE(b, c)	GET_CONTEXT_FIELD(b, c, FSYNR1, FSYNR1_ASIZE)
+#define GET_ALOCK(b, c)		GET_CONTEXT_FIELD(b, c, FSYNR1, ALOCK)
+#define GET_AFULL(b, c)		GET_CONTEXT_FIELD(b, c, FSYNR1, AFULL)
+
+
+/* NMRR */
+#define GET_ICPC0(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, ICPC0)
+#define GET_ICPC1(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, ICPC1)
+#define GET_ICPC2(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, ICPC2)
+#define GET_ICPC3(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, ICPC3)
+#define GET_ICPC4(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, ICPC4)
+#define GET_ICPC5(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, ICPC5)
+#define GET_ICPC6(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, ICPC6)
+#define GET_ICPC7(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, ICPC7)
+#define GET_OCPC0(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, OCPC0)
+#define GET_OCPC1(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, OCPC1)
+#define GET_OCPC2(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, OCPC2)
+#define GET_OCPC3(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, OCPC3)
+#define GET_OCPC4(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, OCPC4)
+#define GET_OCPC5(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, OCPC5)
+#define GET_OCPC6(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, OCPC6)
+#define GET_OCPC7(b, c)		GET_CONTEXT_FIELD(b, c, NMRR, OCPC7)
+#define NMRR_ICP(nmrr, n)	(((nmrr) & (3 << ((n) * 2))) >> ((n) * 2))
+#define NMRR_OCP(nmrr, n)	(((nmrr) & (3 << ((n) * 2 + 16))) >> \
+								((n) * 2 + 16))
+
+/* PAR */
+#define GET_FAULT(b, c)		GET_CONTEXT_FIELD(b, c, PAR, FAULT)
+
+#define GET_FAULT_TF(b, c)	GET_CONTEXT_FIELD(b, c, PAR, FAULT_TF)
+#define GET_FAULT_AFF(b, c)	GET_CONTEXT_FIELD(b, c, PAR, FAULT_AFF)
+#define GET_FAULT_APF(b, c)	GET_CONTEXT_FIELD(b, c, PAR, FAULT_APF)
+#define GET_FAULT_TLBMF(b, c)   GET_CONTEXT_FIELD(b, c, PAR, FAULT_TLBMF)
+#define GET_FAULT_HTWDEEF(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_HTWDEEF)
+#define GET_FAULT_HTWSEEF(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_HTWSEEF)
+#define GET_FAULT_MHF(b, c)	GET_CONTEXT_FIELD(b, c, PAR, FAULT_MHF)
+#define GET_FAULT_SL(b, c)	GET_CONTEXT_FIELD(b, c, PAR, FAULT_SL)
+#define GET_FAULT_SS(b, c)	GET_CONTEXT_FIELD(b, c, PAR, FAULT_SS)
+
+#define GET_NOFAULT_SS(b, c)	GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_SS)
+#define GET_NOFAULT_MT(b, c)	GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_MT)
+#define GET_NOFAULT_SH(b, c)	GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_SH)
+#define GET_NOFAULT_NS(b, c)	GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_NS)
+#define GET_NOFAULT_NOS(b, c)   GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_NOS)
+#define GET_NPFAULT_PA(b, c)	GET_CONTEXT_FIELD(b, c, PAR, PAR_NPFAULT_PA)
+
+
+/* PRRR */
+#define GET_MTC0(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, MTC0)
+#define GET_MTC1(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, MTC1)
+#define GET_MTC2(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, MTC2)
+#define GET_MTC3(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, MTC3)
+#define GET_MTC4(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, MTC4)
+#define GET_MTC5(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, MTC5)
+#define GET_MTC6(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, MTC6)
+#define GET_MTC7(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, MTC7)
+#define GET_SHDSH0(b, c)	GET_CONTEXT_FIELD(b, c, PRRR, SHDSH0)
+#define GET_SHDSH1(b, c)	GET_CONTEXT_FIELD(b, c, PRRR, SHDSH1)
+#define GET_SHNMSH0(b, c)	GET_CONTEXT_FIELD(b, c, PRRR, SHNMSH0)
+#define GET_SHNMSH1(b, c)	GET_CONTEXT_FIELD(b, c, PRRR, SHNMSH1)
+#define GET_NOS0(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, NOS0)
+#define GET_NOS1(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, NOS1)
+#define GET_NOS2(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, NOS2)
+#define GET_NOS3(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, NOS3)
+#define GET_NOS4(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, NOS4)
+#define GET_NOS5(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, NOS5)
+#define GET_NOS6(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, NOS6)
+#define GET_NOS7(b, c)		GET_CONTEXT_FIELD(b, c, PRRR, NOS7)
+#define PRRR_NOS(prrr, n)	 ((prrr) & (1 << ((n) + 24)) ? 1 : 0)
+#define PRRR_MT(prrr, n)	 ((((prrr) & (3 << ((n) * 2))) >> ((n) * 2)))
+
+
+/* RESUME */
+#define GET_TNR(b, c)		GET_CONTEXT_FIELD(b, c, RESUME, TNR)
+
+
+/* SCTLR */
+#define GET_M(b, c)		GET_CONTEXT_FIELD(b, c, SCTLR, M)
+#define GET_TRE(b, c)		GET_CONTEXT_FIELD(b, c, SCTLR, TRE)
+#define GET_AFE(b, c)		GET_CONTEXT_FIELD(b, c, SCTLR, AFE)
+#define GET_HAF(b, c)		GET_CONTEXT_FIELD(b, c, SCTLR, HAF)
+#define GET_BE(b, c)		GET_CONTEXT_FIELD(b, c, SCTLR, BE)
+#define GET_AFFD(b, c)		GET_CONTEXT_FIELD(b, c, SCTLR, AFFD)
+
+
+/* TLBLKCR */
+#define GET_LKE(b, c)		GET_CONTEXT_FIELD(b, c, TLBLKCR, LKE)
+#define GET_TLBLCKR_TLBIALLCFG(b, c) \
+			GET_CONTEXT_FIELD(b, c, TLBLKCR, TLBLCKR_TLBIALLCFG)
+#define GET_TLBIASIDCFG(b, c)   GET_CONTEXT_FIELD(b, c, TLBLKCR, TLBIASIDCFG)
+#define GET_TLBIVAACFG(b, c)	GET_CONTEXT_FIELD(b, c, TLBLKCR, TLBIVAACFG)
+#define GET_FLOOR(b, c)		GET_CONTEXT_FIELD(b, c, TLBLKCR, FLOOR)
+#define GET_VICTIM(b, c)	GET_CONTEXT_FIELD(b, c, TLBLKCR, VICTIM)
+
+
+/* TTBCR */
+#define GET_N(b, c)		GET_CONTEXT_FIELD(b, c, TTBCR, N)
+#define GET_PD0(b, c)		GET_CONTEXT_FIELD(b, c, TTBCR, PD0)
+#define GET_PD1(b, c)		GET_CONTEXT_FIELD(b, c, TTBCR, PD1)
+
+
+/* TTBR0 */
+#define GET_TTBR0_IRGNH(b, c)	GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_IRGNH)
+#define GET_TTBR0_SH(b, c)	GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_SH)
+#define GET_TTBR0_ORGN(b, c)	GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_ORGN)
+#define GET_TTBR0_NOS(b, c)	GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_NOS)
+#define GET_TTBR0_IRGNL(b, c)	GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_IRGNL)
+#define GET_TTBR0_PA(b, c)	GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_PA)
+
+
+/* TTBR1 */
+#define GET_TTBR1_IRGNH(b, c)	GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_IRGNH)
+#define GET_TTBR1_SH(b, c)	GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_SH)
+#define GET_TTBR1_ORGN(b, c)	GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_ORGN)
+#define GET_TTBR1_NOS(b, c)	GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_NOS)
+#define GET_TTBR1_IRGNL(b, c)	GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_IRGNL)
+#define GET_TTBR1_PA(b, c)	GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_PA)
+
+
+/* V2PSR */
+#define GET_HIT(b, c)		GET_CONTEXT_FIELD(b, c, V2PSR, HIT)
+#define GET_INDEX(b, c)		GET_CONTEXT_FIELD(b, c, V2PSR, INDEX)
+
+
+/* Global Registers */
+#define M2VCBR_N	(0x000)
+#define CBACR_N		(0x800)
+#define TLBRSW		(0xE00)
+#define TLBTR0		(0xE80)
+#define TLBTR1		(0xE84)
+#define TLBTR2		(0xE88)
+#define TESTBUSCR	(0xE8C)
+#define GLOBAL_TLBIALL	(0xF00)
+#define TLBIVMID	(0xF04)
+#define CR		(0xF80)
+#define EAR		(0xF84)
+#define ESR		(0xF88)
+#define ESRRESTORE	(0xF8C)
+#define ESYNR0		(0xF90)
+#define ESYNR1		(0xF94)
+#define REV		(0xFF4)
+#define IDR		(0xFF8)
+#define RPU_ACR		(0xFFC)
+
+/* Event Monitor (EM) Registers */
+#define EMMC		(0xE000)
+#define EMCS		(0xE004)
+#define EMCC_N		(0xE100)
+#define EMC_N		(0xE200)
+
+/* Context Bank Registers */
+#define SCTLR		(0x000)
+#define ACTLR		(0x004)
+#define CONTEXTIDR	(0x008)
+#define TTBR0		(0x010)
+#define TTBR1		(0x014)
+#define TTBCR		(0x018)
+#define PAR		(0x01C)
+#define FSR		(0x020)
+#define FSRRESTORE	(0x024)
+#define FAR		(0x028)
+#define FSYNR0		(0x02C)
+#define FSYNR1		(0x030)
+#define PRRR		(0x034)
+#define NMRR		(0x038)
+#define TLBLCKR		(0x03C)
+#define V2PSR		(0x040)
+#define TLBFLPTER	(0x044)
+#define TLBSLPTER	(0x048)
+#define BFBCR		(0x04C)
+#define CTX_TLBIALL	(0x800)
+#define TLBIASID	(0x804)
+#define TLBIVA		(0x808)
+#define TLBIVAA		(0x80C)
+#define V2PPR		(0x810)
+#define V2PPW		(0x814)
+#define V2PUR		(0x818)
+#define V2PUW		(0x81C)
+#define RESUME		(0x820)
+
+
+/* Global Register Fields */
+/* CBACRn */
+#define RWVMID        (RWVMID_MASK       << RWVMID_SHIFT)
+#define RWE           (RWE_MASK          << RWE_SHIFT)
+#define RWGE          (RWGE_MASK         << RWGE_SHIFT)
+#define CBVMID        (CBVMID_MASK       << CBVMID_SHIFT)
+#define IRPTNDX       (IRPTNDX_MASK      << IRPTNDX_SHIFT)
+
+
+/* CR */
+#define RPUE          (RPUE_MASK          << RPUE_SHIFT)
+#define RPUERE        (RPUERE_MASK        << RPUERE_SHIFT)
+#define RPUEIE        (RPUEIE_MASK        << RPUEIE_SHIFT)
+#define DCDEE         (DCDEE_MASK         << DCDEE_SHIFT)
+#define CLIENTPD      (CLIENTPD_MASK      << CLIENTPD_SHIFT)
+#define STALLD        (STALLD_MASK        << STALLD_SHIFT)
+#define TLBLKCRWE     (TLBLKCRWE_MASK     << TLBLKCRWE_SHIFT)
+#define CR_TLBIALLCFG (CR_TLBIALLCFG_MASK << CR_TLBIALLCFG_SHIFT)
+#define TLBIVMIDCFG   (TLBIVMIDCFG_MASK   << TLBIVMIDCFG_SHIFT)
+#define CR_HUME       (CR_HUME_MASK       << CR_HUME_SHIFT)
+
+
+/* ESR */
+#define CFG           (CFG_MASK          << CFG_SHIFT)
+#define BYPASS        (BYPASS_MASK       << BYPASS_SHIFT)
+#define ESR_MULTI     (ESR_MULTI_MASK    << ESR_MULTI_SHIFT)
+
+
+/* ESYNR0 */
+#define ESYNR0_AMID   (ESYNR0_AMID_MASK  << ESYNR0_AMID_SHIFT)
+#define ESYNR0_APID   (ESYNR0_APID_MASK  << ESYNR0_APID_SHIFT)
+#define ESYNR0_ABID   (ESYNR0_ABID_MASK  << ESYNR0_ABID_SHIFT)
+#define ESYNR0_AVMID  (ESYNR0_AVMID_MASK << ESYNR0_AVMID_SHIFT)
+#define ESYNR0_ATID   (ESYNR0_ATID_MASK  << ESYNR0_ATID_SHIFT)
+
+
+/* ESYNR1 */
+#define ESYNR1_AMEMTYPE      (ESYNR1_AMEMTYPE_MASK    << ESYNR1_AMEMTYPE_SHIFT)
+#define ESYNR1_ASHARED       (ESYNR1_ASHARED_MASK     << ESYNR1_ASHARED_SHIFT)
+#define ESYNR1_AINNERSHARED  (ESYNR1_AINNERSHARED_MASK<< \
+						ESYNR1_AINNERSHARED_SHIFT)
+#define ESYNR1_APRIV         (ESYNR1_APRIV_MASK       << ESYNR1_APRIV_SHIFT)
+#define ESYNR1_APROTNS       (ESYNR1_APROTNS_MASK     << ESYNR1_APROTNS_SHIFT)
+#define ESYNR1_AINST         (ESYNR1_AINST_MASK       << ESYNR1_AINST_SHIFT)
+#define ESYNR1_AWRITE        (ESYNR1_AWRITE_MASK      << ESYNR1_AWRITE_SHIFT)
+#define ESYNR1_ABURST        (ESYNR1_ABURST_MASK      << ESYNR1_ABURST_SHIFT)
+#define ESYNR1_ALEN          (ESYNR1_ALEN_MASK        << ESYNR1_ALEN_SHIFT)
+#define ESYNR1_ASIZE         (ESYNR1_ASIZE_MASK       << ESYNR1_ASIZE_SHIFT)
+#define ESYNR1_ALOCK         (ESYNR1_ALOCK_MASK       << ESYNR1_ALOCK_SHIFT)
+#define ESYNR1_AOOO          (ESYNR1_AOOO_MASK        << ESYNR1_AOOO_SHIFT)
+#define ESYNR1_AFULL         (ESYNR1_AFULL_MASK       << ESYNR1_AFULL_SHIFT)
+#define ESYNR1_AC            (ESYNR1_AC_MASK          << ESYNR1_AC_SHIFT)
+#define ESYNR1_DCD           (ESYNR1_DCD_MASK         << ESYNR1_DCD_SHIFT)
+
+
+/* IDR */
+#define NM2VCBMT      (NM2VCBMT_MASK     << NM2VCBMT_SHIFT)
+#define HTW           (HTW_MASK          << HTW_SHIFT)
+#define HUM           (HUM_MASK          << HUM_SHIFT)
+#define TLBSIZE       (TLBSIZE_MASK      << TLBSIZE_SHIFT)
+#define NCB           (NCB_MASK          << NCB_SHIFT)
+#define NIRPT         (NIRPT_MASK        << NIRPT_SHIFT)
+
+
+/* M2VCBRn */
+#define VMID          (VMID_MASK         << VMID_SHIFT)
+#define CBNDX         (CBNDX_MASK        << CBNDX_SHIFT)
+#define BYPASSD       (BYPASSD_MASK      << BYPASSD_SHIFT)
+#define BPRCOSH       (BPRCOSH_MASK      << BPRCOSH_SHIFT)
+#define BPRCISH       (BPRCISH_MASK      << BPRCISH_SHIFT)
+#define BPRCNSH       (BPRCNSH_MASK      << BPRCNSH_SHIFT)
+#define BPSHCFG       (BPSHCFG_MASK      << BPSHCFG_SHIFT)
+#define NSCFG         (NSCFG_MASK        << NSCFG_SHIFT)
+#define BPMTCFG       (BPMTCFG_MASK      << BPMTCFG_SHIFT)
+#define BPMEMTYPE     (BPMEMTYPE_MASK    << BPMEMTYPE_SHIFT)
+
+
+/* REV */
+#define IDR_MINOR     (MINOR_MASK        << MINOR_SHIFT)
+#define IDR_MAJOR     (MAJOR_MASK        << MAJOR_SHIFT)
+
+
+/* TESTBUSCR */
+#define TBE           (TBE_MASK          << TBE_SHIFT)
+#define SPDMBE        (SPDMBE_MASK       << SPDMBE_SHIFT)
+#define WGSEL         (WGSEL_MASK        << WGSEL_SHIFT)
+#define TBLSEL        (TBLSEL_MASK       << TBLSEL_SHIFT)
+#define TBHSEL        (TBHSEL_MASK       << TBHSEL_SHIFT)
+#define SPDM0SEL      (SPDM0SEL_MASK     << SPDM0SEL_SHIFT)
+#define SPDM1SEL      (SPDM1SEL_MASK     << SPDM1SEL_SHIFT)
+#define SPDM2SEL      (SPDM2SEL_MASK     << SPDM2SEL_SHIFT)
+#define SPDM3SEL      (SPDM3SEL_MASK     << SPDM3SEL_SHIFT)
+
+
+/* TLBIVMID */
+#define TLBIVMID_VMID (TLBIVMID_VMID_MASK << TLBIVMID_VMID_SHIFT)
+
+
+/* TLBRSW */
+#define TLBRSW_INDEX  (TLBRSW_INDEX_MASK << TLBRSW_INDEX_SHIFT)
+#define TLBBFBS       (TLBBFBS_MASK      << TLBBFBS_SHIFT)
+
+
+/* TLBTR0 */
+#define PR            (PR_MASK           << PR_SHIFT)
+#define PW            (PW_MASK           << PW_SHIFT)
+#define UR            (UR_MASK           << UR_SHIFT)
+#define UW            (UW_MASK           << UW_SHIFT)
+#define XN            (XN_MASK           << XN_SHIFT)
+#define NSDESC        (NSDESC_MASK       << NSDESC_SHIFT)
+#define ISH           (ISH_MASK          << ISH_SHIFT)
+#define SH            (SH_MASK           << SH_SHIFT)
+#define MT            (MT_MASK           << MT_SHIFT)
+#define DPSIZR        (DPSIZR_MASK       << DPSIZR_SHIFT)
+#define DPSIZC        (DPSIZC_MASK       << DPSIZC_SHIFT)
+
+
+/* TLBTR1 */
+#define TLBTR1_VMID   (TLBTR1_VMID_MASK  << TLBTR1_VMID_SHIFT)
+#define TLBTR1_PA     (TLBTR1_PA_MASK    << TLBTR1_PA_SHIFT)
+
+
+/* TLBTR2 */
+#define TLBTR2_ASID   (TLBTR2_ASID_MASK  << TLBTR2_ASID_SHIFT)
+#define TLBTR2_V      (TLBTR2_V_MASK     << TLBTR2_V_SHIFT)
+#define TLBTR2_NSTID  (TLBTR2_NSTID_MASK << TLBTR2_NSTID_SHIFT)
+#define TLBTR2_NV     (TLBTR2_NV_MASK    << TLBTR2_NV_SHIFT)
+#define TLBTR2_VA     (TLBTR2_VA_MASK    << TLBTR2_VA_SHIFT)
+
+
+/* Context Register Fields */
+/* ACTLR */
+#define CFERE              (CFERE_MASK              << CFERE_SHIFT)
+#define CFEIE              (CFEIE_MASK              << CFEIE_SHIFT)
+#define PTSHCFG            (PTSHCFG_MASK            << PTSHCFG_SHIFT)
+#define RCOSH              (RCOSH_MASK              << RCOSH_SHIFT)
+#define RCISH              (RCISH_MASK              << RCISH_SHIFT)
+#define RCNSH              (RCNSH_MASK              << RCNSH_SHIFT)
+#define PRIVCFG            (PRIVCFG_MASK            << PRIVCFG_SHIFT)
+#define DNA                (DNA_MASK                << DNA_SHIFT)
+#define DNLV2PA            (DNLV2PA_MASK            << DNLV2PA_SHIFT)
+#define TLBMCFG            (TLBMCFG_MASK            << TLBMCFG_SHIFT)
+#define CFCFG              (CFCFG_MASK              << CFCFG_SHIFT)
+#define TIPCF              (TIPCF_MASK              << TIPCF_SHIFT)
+#define V2PCFG             (V2PCFG_MASK             << V2PCFG_SHIFT)
+#define HUME               (HUME_MASK               << HUME_SHIFT)
+#define PTMTCFG            (PTMTCFG_MASK            << PTMTCFG_SHIFT)
+#define PTMEMTYPE          (PTMEMTYPE_MASK          << PTMEMTYPE_SHIFT)
+
+
+/* BFBCR */
+#define BFBDFE             (BFBDFE_MASK             << BFBDFE_SHIFT)
+#define BFBSFE             (BFBSFE_MASK             << BFBSFE_SHIFT)
+#define SFVS               (SFVS_MASK               << SFVS_SHIFT)
+#define FLVIC              (FLVIC_MASK              << FLVIC_SHIFT)
+#define SLVIC              (SLVIC_MASK              << SLVIC_SHIFT)
+
+
+/* CONTEXTIDR */
+#define CONTEXTIDR_ASID    (CONTEXTIDR_ASID_MASK    << CONTEXTIDR_ASID_SHIFT)
+#define PROCID             (PROCID_MASK             << PROCID_SHIFT)
+
+
+/* FSR */
+#define TF                 (TF_MASK                 << TF_SHIFT)
+#define AFF                (AFF_MASK                << AFF_SHIFT)
+#define APF                (APF_MASK                << APF_SHIFT)
+#define TLBMF              (TLBMF_MASK              << TLBMF_SHIFT)
+#define HTWDEEF            (HTWDEEF_MASK            << HTWDEEF_SHIFT)
+#define HTWSEEF            (HTWSEEF_MASK            << HTWSEEF_SHIFT)
+#define MHF                (MHF_MASK                << MHF_SHIFT)
+#define SL                 (SL_MASK                 << SL_SHIFT)
+#define SS                 (SS_MASK                 << SS_SHIFT)
+#define MULTI              (MULTI_MASK              << MULTI_SHIFT)
+
+
+/* FSYNR0 */
+#define AMID               (AMID_MASK               << AMID_SHIFT)
+#define APID               (APID_MASK               << APID_SHIFT)
+#define ABID               (ABID_MASK               << ABID_SHIFT)
+#define ATID               (ATID_MASK               << ATID_SHIFT)
+
+
+/* FSYNR1 */
+#define AMEMTYPE           (AMEMTYPE_MASK           << AMEMTYPE_SHIFT)
+#define ASHARED            (ASHARED_MASK            << ASHARED_SHIFT)
+#define AINNERSHARED       (AINNERSHARED_MASK       << AINNERSHARED_SHIFT)
+#define APRIV              (APRIV_MASK              << APRIV_SHIFT)
+#define APROTNS            (APROTNS_MASK            << APROTNS_SHIFT)
+#define AINST              (AINST_MASK              << AINST_SHIFT)
+#define AWRITE             (AWRITE_MASK             << AWRITE_SHIFT)
+#define ABURST             (ABURST_MASK             << ABURST_SHIFT)
+#define ALEN               (ALEN_MASK               << ALEN_SHIFT)
+#define FSYNR1_ASIZE       (FSYNR1_ASIZE_MASK       << FSYNR1_ASIZE_SHIFT)
+#define ALOCK              (ALOCK_MASK              << ALOCK_SHIFT)
+#define AFULL              (AFULL_MASK              << AFULL_SHIFT)
+
+
+/* NMRR */
+#define ICPC0              (ICPC0_MASK              << ICPC0_SHIFT)
+#define ICPC1              (ICPC1_MASK              << ICPC1_SHIFT)
+#define ICPC2              (ICPC2_MASK              << ICPC2_SHIFT)
+#define ICPC3              (ICPC3_MASK              << ICPC3_SHIFT)
+#define ICPC4              (ICPC4_MASK              << ICPC4_SHIFT)
+#define ICPC5              (ICPC5_MASK              << ICPC5_SHIFT)
+#define ICPC6              (ICPC6_MASK              << ICPC6_SHIFT)
+#define ICPC7              (ICPC7_MASK              << ICPC7_SHIFT)
+#define OCPC0              (OCPC0_MASK              << OCPC0_SHIFT)
+#define OCPC1              (OCPC1_MASK              << OCPC1_SHIFT)
+#define OCPC2              (OCPC2_MASK              << OCPC2_SHIFT)
+#define OCPC3              (OCPC3_MASK              << OCPC3_SHIFT)
+#define OCPC4              (OCPC4_MASK              << OCPC4_SHIFT)
+#define OCPC5              (OCPC5_MASK              << OCPC5_SHIFT)
+#define OCPC6              (OCPC6_MASK              << OCPC6_SHIFT)
+#define OCPC7              (OCPC7_MASK              << OCPC7_SHIFT)
+
+
+/* PAR */
+#define FAULT              (FAULT_MASK              << FAULT_SHIFT)
+/* If a fault is present, these are the
+same as the fault fields in the FAR */
+#define FAULT_TF           (FAULT_TF_MASK           << FAULT_TF_SHIFT)
+#define FAULT_AFF          (FAULT_AFF_MASK          << FAULT_AFF_SHIFT)
+#define FAULT_APF          (FAULT_APF_MASK          << FAULT_APF_SHIFT)
+#define FAULT_TLBMF        (FAULT_TLBMF_MASK        << FAULT_TLBMF_SHIFT)
+#define FAULT_HTWDEEF      (FAULT_HTWDEEF_MASK      << FAULT_HTWDEEF_SHIFT)
+#define FAULT_HTWSEEF      (FAULT_HTWSEEF_MASK      << FAULT_HTWSEEF_SHIFT)
+#define FAULT_MHF          (FAULT_MHF_MASK          << FAULT_MHF_SHIFT)
+#define FAULT_SL           (FAULT_SL_MASK           << FAULT_SL_SHIFT)
+#define FAULT_SS           (FAULT_SS_MASK           << FAULT_SS_SHIFT)
+
+/* If NO fault is present, the following fields are in effect */
+/* (FAULT remains as before) */
+#define PAR_NOFAULT_SS     (PAR_NOFAULT_SS_MASK     << PAR_NOFAULT_SS_SHIFT)
+#define PAR_NOFAULT_MT     (PAR_NOFAULT_MT_MASK     << PAR_NOFAULT_MT_SHIFT)
+#define PAR_NOFAULT_SH     (PAR_NOFAULT_SH_MASK     << PAR_NOFAULT_SH_SHIFT)
+#define PAR_NOFAULT_NS     (PAR_NOFAULT_NS_MASK     << PAR_NOFAULT_NS_SHIFT)
+#define PAR_NOFAULT_NOS    (PAR_NOFAULT_NOS_MASK    << PAR_NOFAULT_NOS_SHIFT)
+#define PAR_NPFAULT_PA     (PAR_NPFAULT_PA_MASK     << PAR_NPFAULT_PA_SHIFT)
+
+
+/* PRRR */
+#define MTC0               (MTC0_MASK               << MTC0_SHIFT)
+#define MTC1               (MTC1_MASK               << MTC1_SHIFT)
+#define MTC2               (MTC2_MASK               << MTC2_SHIFT)
+#define MTC3               (MTC3_MASK               << MTC3_SHIFT)
+#define MTC4               (MTC4_MASK               << MTC4_SHIFT)
+#define MTC5               (MTC5_MASK               << MTC5_SHIFT)
+#define MTC6               (MTC6_MASK               << MTC6_SHIFT)
+#define MTC7               (MTC7_MASK               << MTC7_SHIFT)
+#define SHDSH0             (SHDSH0_MASK             << SHDSH0_SHIFT)
+#define SHDSH1             (SHDSH1_MASK             << SHDSH1_SHIFT)
+#define SHNMSH0            (SHNMSH0_MASK            << SHNMSH0_SHIFT)
+#define SHNMSH1            (SHNMSH1_MASK            << SHNMSH1_SHIFT)
+#define NOS0               (NOS0_MASK               << NOS0_SHIFT)
+#define NOS1               (NOS1_MASK               << NOS1_SHIFT)
+#define NOS2               (NOS2_MASK               << NOS2_SHIFT)
+#define NOS3               (NOS3_MASK               << NOS3_SHIFT)
+#define NOS4               (NOS4_MASK               << NOS4_SHIFT)
+#define NOS5               (NOS5_MASK               << NOS5_SHIFT)
+#define NOS6               (NOS6_MASK               << NOS6_SHIFT)
+#define NOS7               (NOS7_MASK               << NOS7_SHIFT)
+
+
+/* RESUME */
+#define TNR                (TNR_MASK                << TNR_SHIFT)
+
+
+/* SCTLR */
+#define M                  (M_MASK                  << M_SHIFT)
+#define TRE                (TRE_MASK                << TRE_SHIFT)
+#define AFE                (AFE_MASK                << AFE_SHIFT)
+#define HAF                (HAF_MASK                << HAF_SHIFT)
+#define BE                 (BE_MASK                 << BE_SHIFT)
+#define AFFD               (AFFD_MASK               << AFFD_SHIFT)
+
+
+/* TLBIASID */
+#define TLBIASID_ASID      (TLBIASID_ASID_MASK      << TLBIASID_ASID_SHIFT)
+
+
+/* TLBIVA */
+#define TLBIVA_ASID        (TLBIVA_ASID_MASK        << TLBIVA_ASID_SHIFT)
+#define TLBIVA_VA          (TLBIVA_VA_MASK          << TLBIVA_VA_SHIFT)
+
+
+/* TLBIVAA */
+#define TLBIVAA_VA         (TLBIVAA_VA_MASK         << TLBIVAA_VA_SHIFT)
+
+
+/* TLBLCKR */
+#define LKE                (LKE_MASK                << LKE_SHIFT)
+#define TLBLCKR_TLBIALLCFG (TLBLCKR_TLBIALLCFG_MASK<<TLBLCKR_TLBIALLCFG_SHIFT)
+#define TLBIASIDCFG        (TLBIASIDCFG_MASK        << TLBIASIDCFG_SHIFT)
+#define TLBIVAACFG         (TLBIVAACFG_MASK         << TLBIVAACFG_SHIFT)
+#define FLOOR              (FLOOR_MASK              << FLOOR_SHIFT)
+#define VICTIM             (VICTIM_MASK             << VICTIM_SHIFT)
+
+
+/* TTBCR */
+#define N                  (N_MASK                  << N_SHIFT)
+#define PD0                (PD0_MASK                << PD0_SHIFT)
+#define PD1                (PD1_MASK                << PD1_SHIFT)
+
+
+/* TTBR0 */
+#define TTBR0_IRGNH        (TTBR0_IRGNH_MASK        << TTBR0_IRGNH_SHIFT)
+#define TTBR0_SH           (TTBR0_SH_MASK           << TTBR0_SH_SHIFT)
+#define TTBR0_ORGN         (TTBR0_ORGN_MASK         << TTBR0_ORGN_SHIFT)
+#define TTBR0_NOS          (TTBR0_NOS_MASK          << TTBR0_NOS_SHIFT)
+#define TTBR0_IRGNL        (TTBR0_IRGNL_MASK        << TTBR0_IRGNL_SHIFT)
+#define TTBR0_PA           (TTBR0_PA_MASK           << TTBR0_PA_SHIFT)
+
+
+/* TTBR1 */
+#define TTBR1_IRGNH        (TTBR1_IRGNH_MASK        << TTBR1_IRGNH_SHIFT)
+#define TTBR1_SH           (TTBR1_SH_MASK           << TTBR1_SH_SHIFT)
+#define TTBR1_ORGN         (TTBR1_ORGN_MASK         << TTBR1_ORGN_SHIFT)
+#define TTBR1_NOS          (TTBR1_NOS_MASK          << TTBR1_NOS_SHIFT)
+#define TTBR1_IRGNL        (TTBR1_IRGNL_MASK        << TTBR1_IRGNL_SHIFT)
+#define TTBR1_PA           (TTBR1_PA_MASK           << TTBR1_PA_SHIFT)
+
+
+/* V2PSR */
+#define HIT                (HIT_MASK                << HIT_SHIFT)
+#define INDEX              (INDEX_MASK              << INDEX_SHIFT)
+
+
+/* V2Pxx */
+#define V2Pxx_INDEX        (V2Pxx_INDEX_MASK        << V2Pxx_INDEX_SHIFT)
+#define V2Pxx_VA           (V2Pxx_VA_MASK           << V2Pxx_VA_SHIFT)
+
+
+/* Global Register Masks */
+/* CBACRn */
+#define RWVMID_MASK               0x1F
+#define RWE_MASK                  0x01
+#define RWGE_MASK                 0x01
+#define CBVMID_MASK               0x1F
+#define IRPTNDX_MASK              0xFF
+
+
+/* CR */
+#define RPUE_MASK                 0x01
+#define RPUERE_MASK               0x01
+#define RPUEIE_MASK               0x01
+#define DCDEE_MASK                0x01
+#define CLIENTPD_MASK             0x01
+#define STALLD_MASK               0x01
+#define TLBLKCRWE_MASK            0x01
+#define CR_TLBIALLCFG_MASK        0x01
+#define TLBIVMIDCFG_MASK          0x01
+#define CR_HUME_MASK              0x01
+
+
+/* ESR */
+#define CFG_MASK                  0x01
+#define BYPASS_MASK               0x01
+#define ESR_MULTI_MASK            0x01
+
+
+/* ESYNR0 */
+#define ESYNR0_AMID_MASK          0xFF
+#define ESYNR0_APID_MASK          0x1F
+#define ESYNR0_ABID_MASK          0x07
+#define ESYNR0_AVMID_MASK         0x1F
+#define ESYNR0_ATID_MASK          0xFF
+
+
+/* ESYNR1 */
+#define ESYNR1_AMEMTYPE_MASK             0x07
+#define ESYNR1_ASHARED_MASK              0x01
+#define ESYNR1_AINNERSHARED_MASK         0x01
+#define ESYNR1_APRIV_MASK                0x01
+#define ESYNR1_APROTNS_MASK              0x01
+#define ESYNR1_AINST_MASK                0x01
+#define ESYNR1_AWRITE_MASK               0x01
+#define ESYNR1_ABURST_MASK               0x01
+#define ESYNR1_ALEN_MASK                 0x0F
+#define ESYNR1_ASIZE_MASK                0x01
+#define ESYNR1_ALOCK_MASK                0x03
+#define ESYNR1_AOOO_MASK                 0x01
+#define ESYNR1_AFULL_MASK                0x01
+#define ESYNR1_AC_MASK                   0x01
+#define ESYNR1_DCD_MASK                  0x01
+
+
+/* IDR */
+#define NM2VCBMT_MASK             0x1FF
+#define HTW_MASK                  0x01
+#define HUM_MASK                  0x01
+#define TLBSIZE_MASK              0x0F
+#define NCB_MASK                  0xFF
+#define NIRPT_MASK                0xFF
+
+
+/* M2VCBRn */
+#define VMID_MASK                 0x1F
+#define CBNDX_MASK                0xFF
+#define BYPASSD_MASK              0x01
+#define BPRCOSH_MASK              0x01
+#define BPRCISH_MASK              0x01
+#define BPRCNSH_MASK              0x01
+#define BPSHCFG_MASK              0x03
+#define NSCFG_MASK                0x03
+#define BPMTCFG_MASK              0x01
+#define BPMEMTYPE_MASK            0x07
+
+
+/* REV */
+#define MINOR_MASK                0x0F
+#define MAJOR_MASK                0x0F
+
+
+/* TESTBUSCR */
+#define TBE_MASK                  0x01
+#define SPDMBE_MASK               0x01
+#define WGSEL_MASK                0x03
+#define TBLSEL_MASK               0x03
+#define TBHSEL_MASK               0x03
+#define SPDM0SEL_MASK             0x0F
+#define SPDM1SEL_MASK             0x0F
+#define SPDM2SEL_MASK             0x0F
+#define SPDM3SEL_MASK             0x0F
+
+
+/* TLBIMID */
+#define TLBIVMID_VMID_MASK        0x1F
+
+
+/* TLBRSW */
+#define TLBRSW_INDEX_MASK         0xFF
+#define TLBBFBS_MASK              0x03
+
+
+/* TLBTR0 */
+#define PR_MASK                   0x01
+#define PW_MASK                   0x01
+#define UR_MASK                   0x01
+#define UW_MASK                   0x01
+#define XN_MASK                   0x01
+#define NSDESC_MASK               0x01
+#define ISH_MASK                  0x01
+#define SH_MASK                   0x01
+#define MT_MASK                   0x07
+#define DPSIZR_MASK               0x07
+#define DPSIZC_MASK               0x07
+
+
+/* TLBTR1 */
+#define TLBTR1_VMID_MASK          0x1F
+#define TLBTR1_PA_MASK            0x000FFFFF
+
+
+/* TLBTR2 */
+#define TLBTR2_ASID_MASK          0xFF
+#define TLBTR2_V_MASK             0x01
+#define TLBTR2_NSTID_MASK         0x01
+#define TLBTR2_NV_MASK            0x01
+#define TLBTR2_VA_MASK            0x000FFFFF
+
+
+/* Global Register Shifts */
+/* CBACRn */
+#define RWVMID_SHIFT             0
+#define RWE_SHIFT                8
+#define RWGE_SHIFT               9
+#define CBVMID_SHIFT             16
+#define IRPTNDX_SHIFT            24
+
+
+/* CR */
+#define RPUE_SHIFT               0
+#define RPUERE_SHIFT             1
+#define RPUEIE_SHIFT             2
+#define DCDEE_SHIFT              3
+#define CLIENTPD_SHIFT           4
+#define STALLD_SHIFT             5
+#define TLBLKCRWE_SHIFT          6
+#define CR_TLBIALLCFG_SHIFT      7
+#define TLBIVMIDCFG_SHIFT        8
+#define CR_HUME_SHIFT            9
+
+
+/* ESR */
+#define CFG_SHIFT                0
+#define BYPASS_SHIFT             1
+#define ESR_MULTI_SHIFT          31
+
+
+/* ESYNR0 */
+#define ESYNR0_AMID_SHIFT        0
+#define ESYNR0_APID_SHIFT        8
+#define ESYNR0_ABID_SHIFT        13
+#define ESYNR0_AVMID_SHIFT       16
+#define ESYNR0_ATID_SHIFT        24
+
+
+/* ESYNR1 */
+#define ESYNR1_AMEMTYPE_SHIFT           0
+#define ESYNR1_ASHARED_SHIFT            3
+#define ESYNR1_AINNERSHARED_SHIFT       4
+#define ESYNR1_APRIV_SHIFT              5
+#define ESYNR1_APROTNS_SHIFT            6
+#define ESYNR1_AINST_SHIFT              7
+#define ESYNR1_AWRITE_SHIFT             8
+#define ESYNR1_ABURST_SHIFT             10
+#define ESYNR1_ALEN_SHIFT               12
+#define ESYNR1_ASIZE_SHIFT              16
+#define ESYNR1_ALOCK_SHIFT              20
+#define ESYNR1_AOOO_SHIFT               22
+#define ESYNR1_AFULL_SHIFT              24
+#define ESYNR1_AC_SHIFT                 30
+#define ESYNR1_DCD_SHIFT                31
+
+
+/* IDR */
+#define NM2VCBMT_SHIFT           0
+#define HTW_SHIFT                9
+#define HUM_SHIFT                10
+#define TLBSIZE_SHIFT            12
+#define NCB_SHIFT                16
+#define NIRPT_SHIFT              24
+
+
+/* M2VCBRn */
+#define VMID_SHIFT               0
+#define CBNDX_SHIFT              8
+#define BYPASSD_SHIFT            16
+#define BPRCOSH_SHIFT            17
+#define BPRCISH_SHIFT            18
+#define BPRCNSH_SHIFT            19
+#define BPSHCFG_SHIFT            20
+#define NSCFG_SHIFT              22
+#define BPMTCFG_SHIFT            24
+#define BPMEMTYPE_SHIFT          25
+
+
+/* REV */
+#define MINOR_SHIFT              0
+#define MAJOR_SHIFT              4
+
+
+/* TESTBUSCR */
+#define TBE_SHIFT                0
+#define SPDMBE_SHIFT             1
+#define WGSEL_SHIFT              8
+#define TBLSEL_SHIFT             12
+#define TBHSEL_SHIFT             14
+#define SPDM0SEL_SHIFT           16
+#define SPDM1SEL_SHIFT           20
+#define SPDM2SEL_SHIFT           24
+#define SPDM3SEL_SHIFT           28
+
+
+/* TLBIMID */
+#define TLBIVMID_VMID_SHIFT      0
+
+
+/* TLBRSW */
+#define TLBRSW_INDEX_SHIFT       0
+#define TLBBFBS_SHIFT            8
+
+
+/* TLBTR0 */
+#define PR_SHIFT                 0
+#define PW_SHIFT                 1
+#define UR_SHIFT                 2
+#define UW_SHIFT                 3
+#define XN_SHIFT                 4
+#define NSDESC_SHIFT             6
+#define ISH_SHIFT                7
+#define SH_SHIFT                 8
+#define MT_SHIFT                 9
+#define DPSIZR_SHIFT             16
+#define DPSIZC_SHIFT             20
+
+
+/* TLBTR1 */
+#define TLBTR1_VMID_SHIFT        0
+#define TLBTR1_PA_SHIFT          12
+
+
+/* TLBTR2 */
+#define TLBTR2_ASID_SHIFT        0
+#define TLBTR2_V_SHIFT           8
+#define TLBTR2_NSTID_SHIFT       9
+#define TLBTR2_NV_SHIFT          10
+#define TLBTR2_VA_SHIFT          12
+
+
+/* Context Register Masks */
+/* ACTLR */
+#define CFERE_MASK                       0x01
+#define CFEIE_MASK                       0x01
+#define PTSHCFG_MASK                     0x03
+#define RCOSH_MASK                       0x01
+#define RCISH_MASK                       0x01
+#define RCNSH_MASK                       0x01
+#define PRIVCFG_MASK                     0x03
+#define DNA_MASK                         0x01
+#define DNLV2PA_MASK                     0x01
+#define TLBMCFG_MASK                     0x03
+#define CFCFG_MASK                       0x01
+#define TIPCF_MASK                       0x01
+#define V2PCFG_MASK                      0x03
+#define HUME_MASK                        0x01
+#define PTMTCFG_MASK                     0x01
+#define PTMEMTYPE_MASK                   0x07
+
+
+/* BFBCR */
+#define BFBDFE_MASK                      0x01
+#define BFBSFE_MASK                      0x01
+#define SFVS_MASK                        0x01
+#define FLVIC_MASK                       0x0F
+#define SLVIC_MASK                       0x0F
+
+
+/* CONTEXTIDR */
+#define CONTEXTIDR_ASID_MASK             0xFF
+#define PROCID_MASK                      0x00FFFFFF
+
+
+/* FSR */
+#define TF_MASK                          0x01
+#define AFF_MASK                         0x01
+#define APF_MASK                         0x01
+#define TLBMF_MASK                       0x01
+#define HTWDEEF_MASK                     0x01
+#define HTWSEEF_MASK                     0x01
+#define MHF_MASK                         0x01
+#define SL_MASK                          0x01
+#define SS_MASK                          0x01
+#define MULTI_MASK                       0x01
+
+
+/* FSYNR0 */
+#define AMID_MASK                        0xFF
+#define APID_MASK                        0x1F
+#define ABID_MASK                        0x07
+#define ATID_MASK                        0xFF
+
+
+/* FSYNR1 */
+#define AMEMTYPE_MASK                    0x07
+#define ASHARED_MASK                     0x01
+#define AINNERSHARED_MASK                0x01
+#define APRIV_MASK                       0x01
+#define APROTNS_MASK                     0x01
+#define AINST_MASK                       0x01
+#define AWRITE_MASK                      0x01
+#define ABURST_MASK                      0x01
+#define ALEN_MASK                        0x0F
+#define FSYNR1_ASIZE_MASK                0x07
+#define ALOCK_MASK                       0x03
+#define AFULL_MASK                       0x01
+
+
+/* NMRR */
+#define ICPC0_MASK                       0x03
+#define ICPC1_MASK                       0x03
+#define ICPC2_MASK                       0x03
+#define ICPC3_MASK                       0x03
+#define ICPC4_MASK                       0x03
+#define ICPC5_MASK                       0x03
+#define ICPC6_MASK                       0x03
+#define ICPC7_MASK                       0x03
+#define OCPC0_MASK                       0x03
+#define OCPC1_MASK                       0x03
+#define OCPC2_MASK                       0x03
+#define OCPC3_MASK                       0x03
+#define OCPC4_MASK                       0x03
+#define OCPC5_MASK                       0x03
+#define OCPC6_MASK                       0x03
+#define OCPC7_MASK                       0x03
+
+
+/* PAR */
+#define FAULT_MASK                       0x01
+/* If a fault is present, these are the
+same as the fault fields in the FAR */
+#define FAULT_TF_MASK                    0x01
+#define FAULT_AFF_MASK                   0x01
+#define FAULT_APF_MASK                   0x01
+#define FAULT_TLBMF_MASK                 0x01
+#define FAULT_HTWDEEF_MASK               0x01
+#define FAULT_HTWSEEF_MASK               0x01
+#define FAULT_MHF_MASK                   0x01
+#define FAULT_SL_MASK                    0x01
+#define FAULT_SS_MASK                    0x01
+
+/* If NO fault is present, the following
+ * fields are in effect
+ * (FAULT remains as before) */
+#define PAR_NOFAULT_SS_MASK              0x01
+#define PAR_NOFAULT_MT_MASK              0x07
+#define PAR_NOFAULT_SH_MASK              0x01
+#define PAR_NOFAULT_NS_MASK              0x01
+#define PAR_NOFAULT_NOS_MASK             0x01
+#define PAR_NPFAULT_PA_MASK              0x000FFFFF
+
+
+/* PRRR */
+#define MTC0_MASK                        0x03
+#define MTC1_MASK                        0x03
+#define MTC2_MASK                        0x03
+#define MTC3_MASK                        0x03
+#define MTC4_MASK                        0x03
+#define MTC5_MASK                        0x03
+#define MTC6_MASK                        0x03
+#define MTC7_MASK                        0x03
+#define SHDSH0_MASK                      0x01
+#define SHDSH1_MASK                      0x01
+#define SHNMSH0_MASK                     0x01
+#define SHNMSH1_MASK                     0x01
+#define NOS0_MASK                        0x01
+#define NOS1_MASK                        0x01
+#define NOS2_MASK                        0x01
+#define NOS3_MASK                        0x01
+#define NOS4_MASK                        0x01
+#define NOS5_MASK                        0x01
+#define NOS6_MASK                        0x01
+#define NOS7_MASK                        0x01
+
+
+/* RESUME */
+#define TNR_MASK                         0x01
+
+
+/* SCTLR */
+#define M_MASK                           0x01
+#define TRE_MASK                         0x01
+#define AFE_MASK                         0x01
+#define HAF_MASK                         0x01
+#define BE_MASK                          0x01
+#define AFFD_MASK                        0x01
+
+
+/* TLBIASID */
+#define TLBIASID_ASID_MASK               0xFF
+
+
+/* TLBIVA */
+#define TLBIVA_ASID_MASK                 0xFF
+#define TLBIVA_VA_MASK                   0x000FFFFF
+
+
+/* TLBIVAA */
+#define TLBIVAA_VA_MASK                  0x000FFFFF
+
+
+/* TLBLCKR */
+#define LKE_MASK                         0x01
+#define TLBLCKR_TLBIALLCFG_MASK          0x01
+#define TLBIASIDCFG_MASK                 0x01
+#define TLBIVAACFG_MASK                  0x01
+#define FLOOR_MASK                       0xFF
+#define VICTIM_MASK                      0xFF
+
+
+/* TTBCR */
+#define N_MASK                           0x07
+#define PD0_MASK                         0x01
+#define PD1_MASK                         0x01
+
+
+/* TTBR0 */
+#define TTBR0_IRGNH_MASK                 0x01
+#define TTBR0_SH_MASK                    0x01
+#define TTBR0_ORGN_MASK                  0x03
+#define TTBR0_NOS_MASK                   0x01
+#define TTBR0_IRGNL_MASK                 0x01
+#define TTBR0_PA_MASK                    0x0003FFFF
+
+
+/* TTBR1 */
+#define TTBR1_IRGNH_MASK                 0x01
+#define TTBR1_SH_MASK                    0x01
+#define TTBR1_ORGN_MASK                  0x03
+#define TTBR1_NOS_MASK                   0x01
+#define TTBR1_IRGNL_MASK                 0x01
+#define TTBR1_PA_MASK                    0x0003FFFF
+
+
+/* V2PSR */
+#define HIT_MASK                         0x01
+#define INDEX_MASK                       0xFF
+
+
+/* V2Pxx */
+#define V2Pxx_INDEX_MASK                 0xFF
+#define V2Pxx_VA_MASK                    0x000FFFFF
+
+
+/* Context Register Shifts */
+/* ACTLR */
+#define CFERE_SHIFT                    0
+#define CFEIE_SHIFT                    1
+#define PTSHCFG_SHIFT                  2
+#define RCOSH_SHIFT                    4
+#define RCISH_SHIFT                    5
+#define RCNSH_SHIFT                    6
+#define PRIVCFG_SHIFT                  8
+#define DNA_SHIFT                      10
+#define DNLV2PA_SHIFT                  11
+#define TLBMCFG_SHIFT                  12
+#define CFCFG_SHIFT                    14
+#define TIPCF_SHIFT                    15
+#define V2PCFG_SHIFT                   16
+#define HUME_SHIFT                     18
+#define PTMTCFG_SHIFT                  20
+#define PTMEMTYPE_SHIFT                21
+
+
+/* BFBCR */
+#define BFBDFE_SHIFT                   0
+#define BFBSFE_SHIFT                   1
+#define SFVS_SHIFT                     2
+#define FLVIC_SHIFT                    4
+#define SLVIC_SHIFT                    8
+
+
+/* CONTEXTIDR */
+#define CONTEXTIDR_ASID_SHIFT          0
+#define PROCID_SHIFT                   8
+
+
+/* FSR */
+#define TF_SHIFT                       1
+#define AFF_SHIFT                      2
+#define APF_SHIFT                      3
+#define TLBMF_SHIFT                    4
+#define HTWDEEF_SHIFT                  5
+#define HTWSEEF_SHIFT                  6
+#define MHF_SHIFT                      7
+#define SL_SHIFT                       16
+#define SS_SHIFT                       30
+#define MULTI_SHIFT                    31
+
+
+/* FSYNR0 */
+#define AMID_SHIFT                     0
+#define APID_SHIFT                     8
+#define ABID_SHIFT                     13
+#define ATID_SHIFT                     24
+
+
+/* FSYNR1 */
+#define AMEMTYPE_SHIFT                 0
+#define ASHARED_SHIFT                  3
+#define AINNERSHARED_SHIFT             4
+#define APRIV_SHIFT                    5
+#define APROTNS_SHIFT                  6
+#define AINST_SHIFT                    7
+#define AWRITE_SHIFT                   8
+#define ABURST_SHIFT                   10
+#define ALEN_SHIFT                     12
+#define FSYNR1_ASIZE_SHIFT             16
+#define ALOCK_SHIFT                    20
+#define AFULL_SHIFT                    24
+
+
+/* NMRR */
+#define ICPC0_SHIFT                    0
+#define ICPC1_SHIFT                    2
+#define ICPC2_SHIFT                    4
+#define ICPC3_SHIFT                    6
+#define ICPC4_SHIFT                    8
+#define ICPC5_SHIFT                    10
+#define ICPC6_SHIFT                    12
+#define ICPC7_SHIFT                    14
+#define OCPC0_SHIFT                    16
+#define OCPC1_SHIFT                    18
+#define OCPC2_SHIFT                    20
+#define OCPC3_SHIFT                    22
+#define OCPC4_SHIFT                    24
+#define OCPC5_SHIFT                    26
+#define OCPC6_SHIFT                    28
+#define OCPC7_SHIFT                    30
+
+
+/* PAR */
+#define FAULT_SHIFT                    0
+/* If a fault is present, these are the
+same as the fault fields in the FAR */
+#define FAULT_TF_SHIFT                 1
+#define FAULT_AFF_SHIFT                2
+#define FAULT_APF_SHIFT                3
+#define FAULT_TLBMF_SHIFT              4
+#define FAULT_HTWDEEF_SHIFT            5
+#define FAULT_HTWSEEF_SHIFT            6
+#define FAULT_MHF_SHIFT                7
+#define FAULT_SL_SHIFT                 16
+#define FAULT_SS_SHIFT                 30
+
+/* If NO fault is present, the following
+ * fields are in effect
+ * (FAULT remains as before) */
+#define PAR_NOFAULT_SS_SHIFT           1
+#define PAR_NOFAULT_MT_SHIFT           4
+#define PAR_NOFAULT_SH_SHIFT           7
+#define PAR_NOFAULT_NS_SHIFT           9
+#define PAR_NOFAULT_NOS_SHIFT          10
+#define PAR_NPFAULT_PA_SHIFT           12
+
+
+/* PRRR */
+#define MTC0_SHIFT                     0
+#define MTC1_SHIFT                     2
+#define MTC2_SHIFT                     4
+#define MTC3_SHIFT                     6
+#define MTC4_SHIFT                     8
+#define MTC5_SHIFT                     10
+#define MTC6_SHIFT                     12
+#define MTC7_SHIFT                     14
+#define SHDSH0_SHIFT                   16
+#define SHDSH1_SHIFT                   17
+#define SHNMSH0_SHIFT                  18
+#define SHNMSH1_SHIFT                  19
+#define NOS0_SHIFT                     24
+#define NOS1_SHIFT                     25
+#define NOS2_SHIFT                     26
+#define NOS3_SHIFT                     27
+#define NOS4_SHIFT                     28
+#define NOS5_SHIFT                     29
+#define NOS6_SHIFT                     30
+#define NOS7_SHIFT                     31
+
+
+/* RESUME */
+#define TNR_SHIFT                      0
+
+
+/* SCTLR */
+#define M_SHIFT                        0
+#define TRE_SHIFT                      1
+#define AFE_SHIFT                      2
+#define HAF_SHIFT                      3
+#define BE_SHIFT                       4
+#define AFFD_SHIFT                     5
+
+
+/* TLBIASID */
+#define TLBIASID_ASID_SHIFT            0
+
+
+/* TLBIVA */
+#define TLBIVA_ASID_SHIFT              0
+#define TLBIVA_VA_SHIFT                12
+
+
+/* TLBIVAA */
+#define TLBIVAA_VA_SHIFT               12
+
+
+/* TLBLCKR */
+#define LKE_SHIFT                      0
+#define TLBLCKR_TLBIALLCFG_SHIFT       1
+#define TLBIASIDCFG_SHIFT              2
+#define TLBIVAACFG_SHIFT               3
+#define FLOOR_SHIFT                    8
+#define VICTIM_SHIFT                   8
+
+
+/* TTBCR */
+#define N_SHIFT                        3
+#define PD0_SHIFT                      4
+#define PD1_SHIFT                      5
+
+
+/* TTBR0 */
+#define TTBR0_IRGNH_SHIFT              0
+#define TTBR0_SH_SHIFT                 1
+#define TTBR0_ORGN_SHIFT               3
+#define TTBR0_NOS_SHIFT                5
+#define TTBR0_IRGNL_SHIFT              6
+#define TTBR0_PA_SHIFT                 14
+
+
+/* TTBR1 */
+#define TTBR1_IRGNH_SHIFT              0
+#define TTBR1_SH_SHIFT                 1
+#define TTBR1_ORGN_SHIFT               3
+#define TTBR1_NOS_SHIFT                5
+#define TTBR1_IRGNL_SHIFT              6
+#define TTBR1_PA_SHIFT                 14
+
+
+/* V2PSR */
+#define HIT_SHIFT                      0
+#define INDEX_SHIFT                    8
+
+
+/* V2Pxx */
+#define V2Pxx_INDEX_SHIFT              0
+#define V2Pxx_VA_SHIFT                 12
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/iommu_hw-v1.h b/arch/arm/mach-msm/include/mach/iommu_hw-v1.h
new file mode 100644
index 0000000..554f7e0
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/iommu_hw-v1.h
@@ -0,0 +1,2122 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_IOMMU_HW_V2_H
+#define __ARCH_ARM_MACH_MSM_IOMMU_HW_V2_H
+
+#define CTX_SHIFT  12
+#define CTX_OFFSET 0x8000
+
+#define GET_GLOBAL_REG(reg, base) (readl_relaxed((base) + (reg)))
+#define GET_CTX_REG(reg, base, ctx) \
+	(readl_relaxed((base) + CTX_OFFSET + (reg) + ((ctx) << CTX_SHIFT)))
+
+#define SET_GLOBAL_REG(reg, base, val)	writel_relaxed((val), ((base) + (reg)))
+
+#define SET_CTX_REG(reg, base, ctx, val) \
+	writel_relaxed((val), \
+		((base) + CTX_OFFSET + (reg) + ((ctx) << CTX_SHIFT)))
+
+/* Wrappers for numbered registers */
+#define SET_GLOBAL_REG_N(b, n, r, v) SET_GLOBAL_REG((b), ((r) + (n << 2)), (v))
+#define GET_GLOBAL_REG_N(b, n, r)    GET_GLOBAL_REG((b), ((r) + (n << 2)))
+
+/* Field wrappers */
+#define GET_GLOBAL_FIELD(b, r, F) \
+	GET_FIELD(((b) + (r)), r##_##F##_MASK, r##_##F##_SHIFT)
+#define GET_CONTEXT_FIELD(b, c, r, F) \
+	GET_FIELD(((b) + CTX_OFFSET + (r) + ((c) << CTX_SHIFT)), \
+			r##_##F##_MASK, r##_##F##_SHIFT)
+
+#define SET_GLOBAL_FIELD(b, r, F, v) \
+	SET_FIELD(((b) + (r)), r##_##F##_MASK, r##_##F##_SHIFT, (v))
+#define SET_CONTEXT_FIELD(b, c, r, F, v) \
+	SET_FIELD(((b) + CTX_OFFSET + (r) + ((c) << CTX_SHIFT)), \
+			r##_##F##_MASK, r##_##F##_SHIFT, (v))
+
+/* Wrappers for numbered field registers */
+#define SET_GLOBAL_FIELD_N(b, n, r, F, v) \
+	SET_FIELD(((b) + ((n) << 2) + (r)), r##_##F##_MASK, r##_##F##_SHIFT, v)
+#define GET_GLOBAL_FIELD_N(b, n, r, F) \
+	GET_FIELD(((b) + ((n) << 2) + (r)), r##_##F##_MASK, r##_##F##_SHIFT)
+
+#define GET_FIELD(addr, mask, shift) ((readl_relaxed(addr) >> (shift)) & (mask))
+
+#define SET_FIELD(addr, mask, shift, v) \
+do { \
+	int t = readl_relaxed(addr); \
+	writel_relaxed((t & ~((mask) << (shift))) + (((v) & \
+			(mask)) << (shift)), addr); \
+} while (0)
+
+
+/* Global register space 0 setters / getters */
+#define SET_CR0(b, v)            SET_GLOBAL_REG(CR0, (b), (v))
+#define SET_SCR1(b, v)           SET_GLOBAL_REG(SCR1, (b), (v))
+#define SET_CR2(b, v)            SET_GLOBAL_REG(CR2, (b), (v))
+#define SET_ACR(b, v)            SET_GLOBAL_REG(ACR, (b), (v))
+#define SET_IDR0(b, N, v)        SET_GLOBAL_REG(IDR0, (b), (v))
+#define SET_IDR1(b, N, v)        SET_GLOBAL_REG(IDR1, (b), (v))
+#define SET_IDR2(b, N, v)        SET_GLOBAL_REG(IDR2, (b), (v))
+#define SET_IDR7(b, N, v)        SET_GLOBAL_REG(IDR7, (b), (v))
+#define SET_GFAR(b, v)           SET_GLOBAL_REG(GFAR, (b), (v))
+#define SET_GFSR(b, v)           SET_GLOBAL_REG(GFSR, (b), (v))
+#define SET_GFSRRESTORE(b, v)    SET_GLOBAL_REG(GFSRRESTORE, (b), (v))
+#define SET_GFSYNR0(b, v)        SET_GLOBAL_REG(GFSYNR0, (b), (v))
+#define SET_GFSYNR1(b, v)        SET_GLOBAL_REG(GFSYNR1, (b), (v))
+#define SET_GFSYNR2(b, v)        SET_GLOBAL_REG(GFSYNR2, (b), (v))
+#define SET_TLBIVMID(b, v)       SET_GLOBAL_REG(TLBIVMID, (b), (v))
+#define SET_TLBIALLNSNH(b, v)    SET_GLOBAL_REG(TLBIALLNSNH, (b), (v))
+#define SET_TLBIALLH(b, v)       SET_GLOBAL_REG(TLBIALLH, (b), (v))
+#define SET_TLBGSYNC(b, v)       SET_GLOBAL_REG(TLBGSYNC, (b), (v))
+#define SET_TLBGSTATUS(b, v)     SET_GLOBAL_REG(TLBSTATUS, (b), (v))
+#define SET_TLBIVAH(b, v)        SET_GLOBAL_REG(TLBIVAH, (b), (v))
+#define SET_GATS1UR(b, v)        SET_GLOBAL_REG(GATS1UR, (b), (v))
+#define SET_GATS1UW(b, v)        SET_GLOBAL_REG(GATS1UW, (b), (v))
+#define SET_GATS1PR(b, v)        SET_GLOBAL_REG(GATS1PR, (b), (v))
+#define SET_GATS1PW(b, v)        SET_GLOBAL_REG(GATS1PW, (b), (v))
+#define SET_GATS12UR(b, v)       SET_GLOBAL_REG(GATS12UR, (b), (v))
+#define SET_GATS12UW(b, v)       SET_GLOBAL_REG(GATS12UW, (b), (v))
+#define SET_GATS12PR(b, v)       SET_GLOBAL_REG(GATS12PR, (b), (v))
+#define SET_GATS12PW(b, v)       SET_GLOBAL_REG(GATS12PW, (b), (v))
+#define SET_GPAR(b, v)           SET_GLOBAL_REG(GPAR, (b), (v))
+#define SET_GATSR(b, v)          SET_GLOBAL_REG(GATSR, (b), (v))
+#define SET_NSCR0(b, v)          SET_GLOBAL_REG(NSCR0, (b), (v))
+#define SET_NSCR2(b, v)          SET_GLOBAL_REG(NSCR2, (b), (v))
+#define SET_NSACR(b, v)          SET_GLOBAL_REG(NSACR, (b), (v))
+#define SET_PMCR(b, v)           SET_GLOBAL_REG(PMCR, (b), (v))
+#define SET_SMR_N(b, N, v)       SET_GLOBAL_REG_N(SMR, N, (b), (v))
+#define SET_S2CR_N(b, N, v)      SET_GLOBAL_REG_N(S2CR, N, (b), (v))
+
+#define GET_CR0(b)               GET_GLOBAL_REG(CR0, (b))
+#define GET_SCR1(b)              GET_GLOBAL_REG(SCR1, (b))
+#define GET_CR2(b)               GET_GLOBAL_REG(CR2, (b))
+#define GET_ACR(b)               GET_GLOBAL_REG(ACR, (b))
+#define GET_IDR0(b, N)           GET_GLOBAL_REG(IDR0, (b))
+#define GET_IDR1(b, N)           GET_GLOBAL_REG(IDR1, (b))
+#define GET_IDR2(b, N)           GET_GLOBAL_REG(IDR2, (b))
+#define GET_IDR7(b, N)           GET_GLOBAL_REG(IDR7, (b))
+#define GET_GFAR(b)              GET_GLOBAL_REG(GFAR, (b))
+#define GET_GFSR(b)              GET_GLOBAL_REG(GFSR, (b))
+#define GET_GFSRRESTORE(b)       GET_GLOBAL_REG(GFSRRESTORE, (b))
+#define GET_GFSYNR0(b)           GET_GLOBAL_REG(GFSYNR0, (b))
+#define GET_GFSYNR1(b)           GET_GLOBAL_REG(GFSYNR1, (b))
+#define GET_GFSYNR2(b)           GET_GLOBAL_REG(GFSYNR2, (b))
+#define GET_TLBIVMID(b)          GET_GLOBAL_REG(TLBIVMID, (b))
+#define GET_TLBIALLNSNH(b)       GET_GLOBAL_REG(TLBIALLNSNH, (b))
+#define GET_TLBIALLH(b)          GET_GLOBAL_REG(TLBIALLH, (b))
+#define GET_TLBGSYNC(b)          GET_GLOBAL_REG(TLBGSYNC, (b))
+#define GET_TLBGSTATUS(b)        GET_GLOBAL_REG(TLBSTATUS, (b))
+#define GET_TLBIVAH(b)           GET_GLOBAL_REG(TLBIVAH, (b))
+#define GET_GATS1UR(b)           GET_GLOBAL_REG(GATS1UR, (b))
+#define GET_GATS1UW(b)           GET_GLOBAL_REG(GATS1UW, (b))
+#define GET_GATS1PR(b)           GET_GLOBAL_REG(GATS1PR, (b))
+#define GET_GATS1PW(b)           GET_GLOBAL_REG(GATS1PW, (b))
+#define GET_GATS12UR(b)          GET_GLOBAL_REG(GATS12UR, (b))
+#define GET_GATS12UW(b)          GET_GLOBAL_REG(GATS12UW, (b))
+#define GET_GATS12PR(b)          GET_GLOBAL_REG(GATS12PR, (b))
+#define GET_GATS12PW(b)          GET_GLOBAL_REG(GATS12PW, (b))
+#define GET_GPAR(b)              GET_GLOBAL_REG(GPAR, (b))
+#define GET_GATSR(b)             GET_GLOBAL_REG(GATSR, (b))
+#define GET_NSCR0(b)             GET_GLOBAL_REG(NSCR0, (b))
+#define GET_NSCR2(b)             GET_GLOBAL_REG(NSCR2, (b))
+#define GET_NSACR(b)             GET_GLOBAL_REG(NSACR, (b))
+#define GET_PMCR(b, v)           GET_GLOBAL_REG(PMCR, (b))
+#define GET_SMR_N(b, N)          GET_GLOBAL_REG_N(SMR, N, (b))
+#define GET_S2CR_N(b, N)         GET_GLOBAL_REG_N(S2CR, N, (b))
+
+/* Global register space 1 setters / getters */
+#define SET_CBAR_N(b, N, v)      SET_GLOBAL_REG_N(CBAR, N, (b), (v))
+#define SET_CBFRSYNRA_N(b, N, v) SET_GLOBAL_REG_N(CBFRSYNRA, N, (b), (v))
+
+#define GET_CBAR_N(b, N)         GET_GLOBAL_REG_N(CBAR, N, (b))
+#define GET_CBFRSYNRA_N(b, N)    GET_GLOBAL_REG_N(CBFRSYNRA, N, (b))
+
+/* Implementation defined register setters/getters */
+#define SET_MICRO_MMU_CTRL_HALT_REQ(b, v) \
+				SET_GLOBAL_FIELD(b, MICRO_MMU_CTRL, HALT_REQ, v)
+#define GET_MICRO_MMU_CTRL_IDLE(b) \
+				GET_GLOBAL_FIELD(b, MICRO_MMU_CTRL, IDLE)
+#define SET_PREDICTIONDIS0(b, v) SET_GLOBAL_REG(PREDICTIONDIS0, (b), (v))
+#define SET_PREDICTIONDIS1(b, v) SET_GLOBAL_REG(PREDICTIONDIS1, (b), (v))
+#define SET_S1L1BFBLP0(b, v)     SET_GLOBAL_REG(S1L1BFBLP0, (b), (v))
+
+/* SSD register setters/getters */
+#define SET_SSDR_N(b, N, v)      SET_GLOBAL_REG_N(SSDR_N, N, (b), (v))
+
+#define GET_SSDR_N(b, N)         GET_GLOBAL_REG_N(SSDR_N, N, (b))
+
+/* Context bank register setters/getters */
+#define SET_SCTLR(b, c, v)       SET_CTX_REG(CB_SCTLR, (b), (c), (v))
+#define SET_ACTLR(b, c, v)       SET_CTX_REG(CB_ACTLR, (b), (c), (v))
+#define SET_RESUME(b, c, v)      SET_CTX_REG(CB_RESUME, (b), (c), (v))
+#define SET_TTBR0(b, c, v)       SET_CTX_REG(CB_TTBR0, (b), (c), (v))
+#define SET_TTBR1(b, c, v)       SET_CTX_REG(CB_TTBR1, (b), (c), (v))
+#define SET_TTBCR(b, c, v)       SET_CTX_REG(CB_TTBCR, (b), (c), (v))
+#define SET_CONTEXTIDR(b, c, v)  SET_CTX_REG(CB_CONTEXTIDR, (b), (c), (v))
+#define SET_PRRR(b, c, v)        SET_CTX_REG(CB_PRRR, (b), (c), (v))
+#define SET_NMRR(b, c, v)        SET_CTX_REG(CB_NMRR, (b), (c), (v))
+#define SET_PAR(b, c, v)         SET_CTX_REG(CB_PAR, (b), (c), (v))
+#define SET_FSR(b, c, v)         SET_CTX_REG(CB_FSR, (b), (c), (v))
+#define SET_FSRRESTORE(b, c, v)  SET_CTX_REG(CB_FSRRESTORE, (b), (c), (v))
+#define SET_FAR(b, c, v)         SET_CTX_REG(CB_FAR, (b), (c), (v))
+#define SET_FSYNR0(b, c, v)      SET_CTX_REG(CB_FSYNR0, (b), (c), (v))
+#define SET_FSYNR1(b, c, v)      SET_CTX_REG(CB_FSYNR1, (b), (c), (v))
+#define SET_TLBIVA(b, c, v)      SET_CTX_REG(CB_TLBIVA, (b), (c), (v))
+#define SET_TLBIVAA(b, c, v)     SET_CTX_REG(CB_TLBIVAA, (b), (c), (v))
+#define SET_TLBIASID(b, c, v)    SET_CTX_REG(CB_TLBIASID, (b), (c), (v))
+#define SET_TLBIALL(b, c, v)     SET_CTX_REG(CB_TLBIALL, (b), (c), (v))
+#define SET_TLBIVAL(b, c, v)     SET_CTX_REG(CB_TLBIVAL, (b), (c), (v))
+#define SET_TLBIVAAL(b, c, v)    SET_CTX_REG(CB_TLBIVAAL, (b), (c), (v))
+#define SET_TLBSYNC(b, c, v)     SET_CTX_REG(CB_TLBSYNC, (b), (c), (v))
+#define SET_TLBSTATUS(b, c, v)   SET_CTX_REG(CB_TLBSTATUS, (b), (c), (v))
+#define SET_ATS1PR(b, c, v)      SET_CTX_REG(CB_ATS1PR, (b), (c), (v))
+#define SET_ATS1PW(b, c, v)      SET_CTX_REG(CB_ATS1PW, (b), (c), (v))
+#define SET_ATS1UR(b, c, v)      SET_CTX_REG(CB_ATS1UR, (b), (c), (v))
+#define SET_ATS1UW(b, c, v)      SET_CTX_REG(CB_ATS1UW, (b), (c), (v))
+#define SET_ATSR(b, c, v)        SET_CTX_REG(CB_ATSR, (b), (c), (v))
+
+#define GET_SCTLR(b, c)          GET_CTX_REG(CB_SCTLR, (b), (c))
+#define GET_ACTLR(b, c)          GET_CTX_REG(CB_ACTLR, (b), (c))
+#define GET_RESUME(b, c)         GET_CTX_REG(CB_RESUME, (b), (c))
+#define GET_TTBR0(b, c)          GET_CTX_REG(CB_TTBR0, (b), (c))
+#define GET_TTBR1(b, c)          GET_CTX_REG(CB_TTBR1, (b), (c))
+#define GET_TTBCR(b, c)          GET_CTX_REG(CB_TTBCR, (b), (c))
+#define GET_CONTEXTIDR(b, c)     GET_CTX_REG(CB_CONTEXTIDR, (b), (c))
+#define GET_PRRR(b, c)           GET_CTX_REG(CB_PRRR, (b), (c))
+#define GET_NMRR(b, c)           GET_CTX_REG(CB_NMRR, (b), (c))
+#define GET_PAR(b, c)            GET_CTX_REG(CB_PAR, (b), (c))
+#define GET_FSR(b, c)            GET_CTX_REG(CB_FSR, (b), (c))
+#define GET_FSRRESTORE(b, c)     GET_CTX_REG(CB_FSRRESTORE, (b), (c))
+#define GET_FAR(b, c)            GET_CTX_REG(CB_FAR, (b), (c))
+#define GET_FSYNR0(b, c)         GET_CTX_REG(CB_FSYNR0, (b), (c))
+#define GET_FSYNR1(b, c)         GET_CTX_REG(CB_FSYNR1, (b), (c))
+#define GET_TLBIVA(b, c)         GET_CTX_REG(CB_TLBIVA, (b), (c))
+#define GET_TLBIVAA(b, c)        GET_CTX_REG(CB_TLBIVAA, (b), (c))
+#define GET_TLBIASID(b, c)       GET_CTX_REG(CB_TLBIASID, (b), (c))
+#define GET_TLBIALL(b, c)        GET_CTX_REG(CB_TLBIALL, (b), (c))
+#define GET_TLBIVAL(b, c)        GET_CTX_REG(CB_TLBIVAL, (b), (c))
+#define GET_TLBIVAAL(b, c)       GET_CTX_REG(CB_TLBIVAAL, (b), (c))
+#define GET_TLBSYNC(b, c)        GET_CTX_REG(CB_TLBSYNC, (b), (c))
+#define GET_TLBSTATUS(b, c)      GET_CTX_REG(CB_TLBSTATUS, (b), (c))
+#define GET_ATS1PR(b, c)         GET_CTX_REG(CB_ATS1PR, (b), (c))
+#define GET_ATS1PW(b, c)         GET_CTX_REG(CB_ATS1PW, (b), (c))
+#define GET_ATS1UR(b, c)         GET_CTX_REG(CB_ATS1UR, (b), (c))
+#define GET_ATS1UW(b, c)         GET_CTX_REG(CB_ATS1UW, (b), (c))
+#define GET_ATSR(b, c)           GET_CTX_REG(CB_ATSR, (b), (c))
+
+/* Global Register field setters / getters */
+/* Configuration Register: CR0 */
+#define SET_CR0_NSCFG(b, v)        SET_GLOBAL_FIELD(b, CR0, NSCFG, v)
+#define SET_CR0_WACFG(b, v)        SET_GLOBAL_FIELD(b, CR0, WACFG, v)
+#define SET_CR0_RACFG(b, v)        SET_GLOBAL_FIELD(b, CR0, RACFG, v)
+#define SET_CR0_SHCFG(b, v)        SET_GLOBAL_FIELD(b, CR0, SHCFG, v)
+#define SET_CR0_SMCFCFG(b, v)      SET_GLOBAL_FIELD(b, CR0, SMCFCFG, v)
+#define SET_CR0_MTCFG(b, v)        SET_GLOBAL_FIELD(b, CR0, MTCFG, v)
+#define SET_CR0_BSU(b, v)          SET_GLOBAL_FIELD(b, CR0, BSU, v)
+#define SET_CR0_FB(b, v)           SET_GLOBAL_FIELD(b, CR0, FB, v)
+#define SET_CR0_PTM(b, v)          SET_GLOBAL_FIELD(b, CR0, PTM, v)
+#define SET_CR0_VMIDPNE(b, v)      SET_GLOBAL_FIELD(b, CR0, VMIDPNE, v)
+#define SET_CR0_USFCFG(b, v)       SET_GLOBAL_FIELD(b, CR0, USFCFG, v)
+#define SET_CR0_GSE(b, v)          SET_GLOBAL_FIELD(b, CR0, GSE, v)
+#define SET_CR0_STALLD(b, v)       SET_GLOBAL_FIELD(b, CR0, STALLD, v)
+#define SET_CR0_TRANSIENTCFG(b, v) SET_GLOBAL_FIELD(b, CR0, TRANSIENTCFG, v)
+#define SET_CR0_GCFGFIE(b, v)      SET_GLOBAL_FIELD(b, CR0, GCFGFIE, v)
+#define SET_CR0_GCFGFRE(b, v)      SET_GLOBAL_FIELD(b, CR0, GCFGFRE, v)
+#define SET_CR0_GFIE(b, v)         SET_GLOBAL_FIELD(b, CR0, GFIE, v)
+#define SET_CR0_GFRE(b, v)         SET_GLOBAL_FIELD(b, CR0, GFRE, v)
+#define SET_CR0_CLIENTPD(b, v)     SET_GLOBAL_FIELD(b, CR0, CLIENTPD, v)
+
+#define GET_CR0_NSCFG(b)           GET_GLOBAL_FIELD(b, CR0, NSCFG)
+#define GET_CR0_WACFG(b)           GET_GLOBAL_FIELD(b, CR0, WACFG)
+#define GET_CR0_RACFG(b)           GET_GLOBAL_FIELD(b, CR0, RACFG)
+#define GET_CR0_SHCFG(b)           GET_GLOBAL_FIELD(b, CR0, SHCFG)
+#define GET_CR0_SMCFCFG(b)         GET_GLOBAL_FIELD(b, CR0, SMCFCFG)
+#define GET_CR0_MTCFG(b)           GET_GLOBAL_FIELD(b, CR0, MTCFG)
+#define GET_CR0_BSU(b)             GET_GLOBAL_FIELD(b, CR0, BSU)
+#define GET_CR0_FB(b)              GET_GLOBAL_FIELD(b, CR0, FB)
+#define GET_CR0_PTM(b)             GET_GLOBAL_FIELD(b, CR0, PTM)
+#define GET_CR0_VMIDPNE(b)         GET_GLOBAL_FIELD(b, CR0, VMIDPNE)
+#define GET_CR0_USFCFG(b)          GET_GLOBAL_FIELD(b, CR0, USFCFG)
+#define GET_CR0_GSE(b)             GET_GLOBAL_FIELD(b, CR0, GSE)
+#define GET_CR0_STALLD(b)          GET_GLOBAL_FIELD(b, CR0, STALLD)
+#define GET_CR0_TRANSIENTCFG(b)    GET_GLOBAL_FIELD(b, CR0, TRANSIENTCFG)
+#define GET_CR0_GCFGFIE(b)         GET_GLOBAL_FIELD(b, CR0, GCFGFIE)
+#define GET_CR0_GCFGFRE(b)         GET_GLOBAL_FIELD(b, CR0, GCFGFRE)
+#define GET_CR0_GFIE(b)            GET_GLOBAL_FIELD(b, CR0, GFIE)
+#define GET_CR0_GFRE(b)            GET_GLOBAL_FIELD(b, CR0, GFRE)
+#define GET_CR0_CLIENTPD(b)        GET_GLOBAL_FIELD(b, CR0, CLIENTPD)
+
+/* Configuration Register: CR2 */
+#define SET_CR2_BPVMID(b, v)     SET_GLOBAL_FIELD(b, CR2, BPVMID, v)
+
+#define GET_CR2_BPVMID(b)        GET_GLOBAL_FIELD(b, CR2, BPVMID)
+
+/* Global Address Translation, Stage 1, Privileged Read: GATS1PR */
+#define SET_GATS1PR_ADDR(b, v)   SET_GLOBAL_FIELD(b, GATS1PR, ADDR, v)
+#define SET_GATS1PR_NDX(b, v)    SET_GLOBAL_FIELD(b, GATS1PR, NDX, v)
+
+#define GET_GATS1PR_ADDR(b)      GET_GLOBAL_FIELD(b, GATS1PR, ADDR)
+#define GET_GATS1PR_NDX(b)       GET_GLOBAL_FIELD(b, GATS1PR, NDX)
+
+/* Global Address Translation, Stage 1, Privileged Write: GATS1PW */
+#define SET_GATS1PW_ADDR(b, v)   SET_GLOBAL_FIELD(b, GATS1PW, ADDR, v)
+#define SET_GATS1PW_NDX(b, v)    SET_GLOBAL_FIELD(b, GATS1PW, NDX, v)
+
+#define GET_GATS1PW_ADDR(b)      GET_GLOBAL_FIELD(b, GATS1PW, ADDR)
+#define GET_GATS1PW_NDX(b)       GET_GLOBAL_FIELD(b, GATS1PW, NDX)
+
+/* Global Address Translation, Stage 1, User Read: GATS1UR */
+#define SET_GATS1UR_ADDR(b, v)   SET_GLOBAL_FIELD(b, GATS1UR, ADDR, v)
+#define SET_GATS1UR_NDX(b, v)    SET_GLOBAL_FIELD(b, GATS1UR, NDX, v)
+
+#define GET_GATS1UR_ADDR(b)      GET_GLOBAL_FIELD(b, GATS1UR, ADDR)
+#define GET_GATS1UR_NDX(b)       GET_GLOBAL_FIELD(b, GATS1UR, NDX)
+
+/* Global Address Translation, Stage 1, User Read: GATS1UW */
+#define SET_GATS1UW_ADDR(b, v)   SET_GLOBAL_FIELD(b, GATS1UW, ADDR, v)
+#define SET_GATS1UW_NDX(b, v)    SET_GLOBAL_FIELD(b, GATS1UW, NDX, v)
+
+#define GET_GATS1UW_ADDR(b)      GET_GLOBAL_FIELD(b, GATS1UW, ADDR)
+#define GET_GATS1UW_NDX(b)       GET_GLOBAL_FIELD(b, GATS1UW, NDX)
+
+/* Global Address Translation, Stage 1 and 2, Privileged Read: GATS12PR */
+#define SET_GATS12PR_ADDR(b, v)  SET_GLOBAL_FIELD(b, GATS12PR, ADDR, v)
+#define SET_GATS12PR_NDX(b, v)   SET_GLOBAL_FIELD(b, GATS12PR, NDX, v)
+
+#define GET_GATS12PR_ADDR(b)     GET_GLOBAL_FIELD(b, GATS12PR, ADDR)
+#define GET_GATS12PR_NDX(b)      GET_GLOBAL_FIELD(b, GATS12PR, NDX)
+
+/* Global Address Translation, Stage 1, Privileged Write: GATS1PW */
+#define SET_GATS12PW_ADDR(b, v)  SET_GLOBAL_FIELD(b, GATS12PW, ADDR, v)
+#define SET_GATS12PW_NDX(b, v)   SET_GLOBAL_FIELD(b, GATS12PW, NDX, v)
+
+#define GET_GATS12PW_ADDR(b)     GET_GLOBAL_FIELD(b, GATS12PW, ADDR)
+#define GET_GATS12PW_NDX(b)      GET_GLOBAL_FIELD(b, GATS12PW, NDX)
+
+/* Global Address Translation, Stage 1, User Read: GATS1UR */
+#define SET_GATS12UR_ADDR(b, v)  SET_GLOBAL_FIELD(b, GATS12UR, ADDR, v)
+#define SET_GATS12UR_NDX(b, v)   SET_GLOBAL_FIELD(b, GATS12UR, NDX, v)
+
+#define GET_GATS12UR_ADDR(b)     GET_GLOBAL_FIELD(b, GATS12UR, ADDR)
+#define GET_GATS12UR_NDX(b)      GET_GLOBAL_FIELD(b, GATS12UR, NDX)
+
+/* Global Address Translation, Stage 1, User Read: GATS1UW */
+#define SET_GATS12UW_ADDR(b, v)  SET_GLOBAL_FIELD(b, GATS12UW, ADDR, v)
+#define SET_GATS12UW_NDX(b, v)   SET_GLOBAL_FIELD(b, GATS12UW, NDX, v)
+
+#define GET_GATS12UW_ADDR(b)     GET_GLOBAL_FIELD(b, GATS12UW, ADDR)
+#define GET_GATS12UW_NDX(b)      GET_GLOBAL_FIELD(b, GATS12UW, NDX)
+
+/* Global Address Translation Status Register: GATSR */
+#define SET_GATSR_ACTIVE(b, v)   SET_GLOBAL_FIELD(b, GATSR, ACTIVE, v)
+
+#define GET_GATSR_ACTIVE(b)      GET_GLOBAL_FIELD(b, GATSR, ACTIVE)
+
+/* Global Fault Address Register: GFAR */
+#define SET_GFAR_FADDR(b, v)     SET_GLOBAL_FIELD(b, GFAR, FADDR, v)
+
+#define GET_GFAR_FADDR(b)        GET_GLOBAL_FIELD(b, GFAR, FADDR)
+
+/* Global Fault Status Register: GFSR */
+#define SET_GFSR_ICF(b, v)        SET_GLOBAL_FIELD(b, GFSR, ICF, v)
+#define SET_GFSR_USF(b, v)        SET_GLOBAL_FIELD(b, GFSR, USF, v)
+#define SET_GFSR_SMCF(b, v)       SET_GLOBAL_FIELD(b, GFSR, SMCF, v)
+#define SET_GFSR_UCBF(b, v)       SET_GLOBAL_FIELD(b, GFSR, UCBF, v)
+#define SET_GFSR_UCIF(b, v)       SET_GLOBAL_FIELD(b, GFSR, UCIF, v)
+#define SET_GFSR_CAF(b, v)        SET_GLOBAL_FIELD(b, GFSR, CAF, v)
+#define SET_GFSR_EF(b, v)         SET_GLOBAL_FIELD(b, GFSR, EF, v)
+#define SET_GFSR_PF(b, v)         SET_GLOBAL_FIELD(b, GFSR, PF, v)
+#define SET_GFSR_MULTI(b, v)      SET_GLOBAL_FIELD(b, GFSR, MULTI, v)
+
+#define GET_GFSR_ICF(b)           GET_GLOBAL_FIELD(b, GFSR, ICF)
+#define GET_GFSR_USF(b)           GET_GLOBAL_FIELD(b, GFSR, USF)
+#define GET_GFSR_SMCF(b)          GET_GLOBAL_FIELD(b, GFSR, SMCF)
+#define GET_GFSR_UCBF(b)          GET_GLOBAL_FIELD(b, GFSR, UCBF)
+#define GET_GFSR_UCIF(b)          GET_GLOBAL_FIELD(b, GFSR, UCIF)
+#define GET_GFSR_CAF(b)           GET_GLOBAL_FIELD(b, GFSR, CAF)
+#define GET_GFSR_EF(b)            GET_GLOBAL_FIELD(b, GFSR, EF)
+#define GET_GFSR_PF(b)            GET_GLOBAL_FIELD(b, GFSR, PF)
+#define GET_GFSR_MULTI(b)         GET_GLOBAL_FIELD(b, GFSR, MULTI)
+
+/* Global Fault Syndrome Register 0: GFSYNR0 */
+#define SET_GFSYNR0_NESTED(b, v)  SET_GLOBAL_FIELD(b, GFSYNR0, NESTED, v)
+#define SET_GFSYNR0_WNR(b, v)     SET_GLOBAL_FIELD(b, GFSYNR0, WNR, v)
+#define SET_GFSYNR0_PNU(b, v)     SET_GLOBAL_FIELD(b, GFSYNR0, PNU, v)
+#define SET_GFSYNR0_IND(b, v)     SET_GLOBAL_FIELD(b, GFSYNR0, IND, v)
+#define SET_GFSYNR0_NSSTATE(b, v) SET_GLOBAL_FIELD(b, GFSYNR0, NSSTATE, v)
+#define SET_GFSYNR0_NSATTR(b, v)  SET_GLOBAL_FIELD(b, GFSYNR0, NSATTR, v)
+
+#define GET_GFSYNR0_NESTED(b)     GET_GLOBAL_FIELD(b, GFSYNR0, NESTED)
+#define GET_GFSYNR0_WNR(b)        GET_GLOBAL_FIELD(b, GFSYNR0, WNR)
+#define GET_GFSYNR0_PNU(b)        GET_GLOBAL_FIELD(b, GFSYNR0, PNU)
+#define GET_GFSYNR0_IND(b)        GET_GLOBAL_FIELD(b, GFSYNR0, IND)
+#define GET_GFSYNR0_NSSTATE(b)    GET_GLOBAL_FIELD(b, GFSYNR0, NSSTATE)
+#define GET_GFSYNR0_NSATTR(b)     GET_GLOBAL_FIELD(b, GFSYNR0, NSATTR)
+
+/* Global Fault Syndrome Register 1: GFSYNR1 */
+#define SET_GFSYNR1_SID(b, v)     SET_GLOBAL_FIELD(b, GFSYNR1, SID, v)
+
+#define GET_GFSYNR1_SID(b)        GET_GLOBAL_FIELD(b, GFSYNR1, SID)
+
+/* Global Physical Address Register: GPAR */
+#define SET_GPAR_F(b, v)          SET_GLOBAL_FIELD(b, GPAR, F, v)
+#define SET_GPAR_SS(b, v)         SET_GLOBAL_FIELD(b, GPAR, SS, v)
+#define SET_GPAR_OUTER(b, v)      SET_GLOBAL_FIELD(b, GPAR, OUTER, v)
+#define SET_GPAR_INNER(b, v)      SET_GLOBAL_FIELD(b, GPAR, INNER, v)
+#define SET_GPAR_SH(b, v)         SET_GLOBAL_FIELD(b, GPAR, SH, v)
+#define SET_GPAR_NS(b, v)         SET_GLOBAL_FIELD(b, GPAR, NS, v)
+#define SET_GPAR_NOS(b, v)        SET_GLOBAL_FIELD(b, GPAR, NOS, v)
+#define SET_GPAR_PA(b, v)         SET_GLOBAL_FIELD(b, GPAR, PA, v)
+#define SET_GPAR_TF(b, v)         SET_GLOBAL_FIELD(b, GPAR, TF, v)
+#define SET_GPAR_AFF(b, v)        SET_GLOBAL_FIELD(b, GPAR, AFF, v)
+#define SET_GPAR_PF(b, v)         SET_GLOBAL_FIELD(b, GPAR, PF, v)
+#define SET_GPAR_EF(b, v)         SET_GLOBAL_FIELD(b, GPAR, EF, v)
+#define SET_GPAR_TLCMCF(b, v)     SET_GLOBAL_FIELD(b, GPAR, TLCMCF, v)
+#define SET_GPAR_TLBLKF(b, v)     SET_GLOBAL_FIELD(b, GPAR, TLBLKF, v)
+#define SET_GPAR_UCBF(b, v)       SET_GLOBAL_FIELD(b, GPAR, UCBF, v)
+
+#define GET_GPAR_F(b)             GET_GLOBAL_FIELD(b, GPAR, F)
+#define GET_GPAR_SS(b)            GET_GLOBAL_FIELD(b, GPAR, SS)
+#define GET_GPAR_OUTER(b)         GET_GLOBAL_FIELD(b, GPAR, OUTER)
+#define GET_GPAR_INNER(b)         GET_GLOBAL_FIELD(b, GPAR, INNER)
+#define GET_GPAR_SH(b)            GET_GLOBAL_FIELD(b, GPAR, SH)
+#define GET_GPAR_NS(b)            GET_GLOBAL_FIELD(b, GPAR, NS)
+#define GET_GPAR_NOS(b)           GET_GLOBAL_FIELD(b, GPAR, NOS)
+#define GET_GPAR_PA(b)            GET_GLOBAL_FIELD(b, GPAR, PA)
+#define GET_GPAR_TF(b)            GET_GLOBAL_FIELD(b, GPAR, TF)
+#define GET_GPAR_AFF(b)           GET_GLOBAL_FIELD(b, GPAR, AFF)
+#define GET_GPAR_PF(b)            GET_GLOBAL_FIELD(b, GPAR, PF)
+#define GET_GPAR_EF(b)            GET_GLOBAL_FIELD(b, GPAR, EF)
+#define GET_GPAR_TLCMCF(b)        GET_GLOBAL_FIELD(b, GPAR, TLCMCF)
+#define GET_GPAR_TLBLKF(b)        GET_GLOBAL_FIELD(b, GPAR, TLBLKF)
+#define GET_GPAR_UCBF(b)          GET_GLOBAL_FIELD(b, GPAR, UCBF)
+
+/* Identification Register: IDR0 */
+#define SET_IDR0_NUMSMRG(b, v)    SET_GLOBAL_FIELD(b, IDR0, NUMSMRG, v)
+#define SET_IDR0_NUMSIDB(b, v)    SET_GLOBAL_FIELD(b, IDR0, NUMSIDB, v)
+#define SET_IDR0_BTM(b, v)        SET_GLOBAL_FIELD(b, IDR0, BTM, v)
+#define SET_IDR0_CTTW(b, v)       SET_GLOBAL_FIELD(b, IDR0, CTTW, v)
+#define SET_IDR0_NUMIRPT(b, v)    SET_GLOBAL_FIELD(b, IDR0, NUMIRPT, v)
+#define SET_IDR0_PTFS(b, v)       SET_GLOBAL_FIELD(b, IDR0, PTFS, v)
+#define SET_IDR0_SMS(b, v)        SET_GLOBAL_FIELD(b, IDR0, SMS, v)
+#define SET_IDR0_NTS(b, v)        SET_GLOBAL_FIELD(b, IDR0, NTS, v)
+#define SET_IDR0_S2TS(b, v)       SET_GLOBAL_FIELD(b, IDR0, S2TS, v)
+#define SET_IDR0_S1TS(b, v)       SET_GLOBAL_FIELD(b, IDR0, S1TS, v)
+#define SET_IDR0_SES(b, v)        SET_GLOBAL_FIELD(b, IDR0, SES, v)
+
+#define GET_IDR0_NUMSMRG(b)       GET_GLOBAL_FIELD(b, IDR0, NUMSMRG)
+#define GET_IDR0_NUMSIDB(b)       GET_GLOBAL_FIELD(b, IDR0, NUMSIDB)
+#define GET_IDR0_BTM(b)           GET_GLOBAL_FIELD(b, IDR0, BTM)
+#define GET_IDR0_CTTW(b)          GET_GLOBAL_FIELD(b, IDR0, CTTW)
+#define GET_IDR0_NUMIRPT(b)       GET_GLOBAL_FIELD(b, IDR0, NUMIRPT)
+#define GET_IDR0_PTFS(b)          GET_GLOBAL_FIELD(b, IDR0, PTFS)
+#define GET_IDR0_SMS(b)           GET_GLOBAL_FIELD(b, IDR0, SMS)
+#define GET_IDR0_NTS(b)           GET_GLOBAL_FIELD(b, IDR0, NTS)
+#define GET_IDR0_S2TS(b)          GET_GLOBAL_FIELD(b, IDR0, S2TS)
+#define GET_IDR0_S1TS(b)          GET_GLOBAL_FIELD(b, IDR0, S1TS)
+#define GET_IDR0_SES(b)           GET_GLOBAL_FIELD(b, IDR0, SES)
+
+/* Identification Register: IDR1 */
+#define SET_IDR1_NUMCB(b, v)       SET_GLOBAL_FIELD(b, IDR1, NUMCB, v)
+#define SET_IDR1_NUMSSDNDXB(b, v)  SET_GLOBAL_FIELD(b, IDR1, NUMSSDNDXB, v)
+#define SET_IDR1_SSDTP(b, v)       SET_GLOBAL_FIELD(b, IDR1, SSDTP, v)
+#define SET_IDR1_SMCD(b, v)        SET_GLOBAL_FIELD(b, IDR1, SMCD, v)
+#define SET_IDR1_NUMS2CB(b, v)     SET_GLOBAL_FIELD(b, IDR1, NUMS2CB, v)
+#define SET_IDR1_NUMPAGENDXB(b, v) SET_GLOBAL_FIELD(b, IDR1, NUMPAGENDXB, v)
+#define SET_IDR1_PAGESIZE(b, v)    SET_GLOBAL_FIELD(b, IDR1, PAGESIZE, v)
+
+#define GET_IDR1_NUMCB(b)          GET_GLOBAL_FIELD(b, IDR1, NUMCB)
+#define GET_IDR1_NUMSSDNDXB(b)     GET_GLOBAL_FIELD(b, IDR1, NUMSSDNDXB)
+#define GET_IDR1_SSDTP(b)          GET_GLOBAL_FIELD(b, IDR1, SSDTP)
+#define GET_IDR1_SMCD(b)           GET_GLOBAL_FIELD(b, IDR1, SMCD)
+#define GET_IDR1_NUMS2CB(b)        GET_GLOBAL_FIELD(b, IDR1, NUMS2CB)
+#define GET_IDR1_NUMPAGENDXB(b)    GET_GLOBAL_FIELD(b, IDR1, NUMPAGENDXB)
+#define GET_IDR1_PAGESIZE(b)       GET_GLOBAL_FIELD(b, IDR1, PAGESIZE)
+
+/* Identification Register: IDR2 */
+#define SET_IDR2_IAS(b, v)       SET_GLOBAL_FIELD(b, IDR2, IAS, v)
+#define SET_IDR2_OAS(b, v)       SET_GLOBAL_FIELD(b, IDR2, OAS, v)
+
+#define GET_IDR2_IAS(b)          GET_GLOBAL_FIELD(b, IDR2, IAS)
+#define GET_IDR2_OAS(b)          GET_GLOBAL_FIELD(b, IDR2, OAS)
+
+/* Identification Register: IDR7 */
+#define SET_IDR7_MINOR(b, v)     SET_GLOBAL_FIELD(b, IDR7, MINOR, v)
+#define SET_IDR7_MAJOR(b, v)     SET_GLOBAL_FIELD(b, IDR7, MAJOR, v)
+
+#define GET_IDR7_MINOR(b)        GET_GLOBAL_FIELD(b, IDR7, MINOR)
+#define GET_IDR7_MAJOR(b)        GET_GLOBAL_FIELD(b, IDR7, MAJOR)
+
+/* Stream to Context Register: S2CR_N */
+#define SET_S2CR_CBNDX(b, n, v)   SET_GLOBAL_FIELD_N(b, n, S2CR, CBNDX, v)
+#define SET_S2CR_SHCFG(b, n, v)   SET_GLOBAL_FIELD_N(b, n, S2CR, SHCFG, v)
+#define SET_S2CR_MTCFG(b, n, v)   SET_GLOBAL_FIELD_N(b, n, S2CR, MTCFG, v)
+#define SET_S2CR_MEMATTR(b, n, v) SET_GLOBAL_FIELD_N(b, n, S2CR, MEMATTR, v)
+#define SET_S2CR_TYPE(b, n, v)    SET_GLOBAL_FIELD_N(b, n, S2CR, TYPE, v)
+#define SET_S2CR_NSCFG(b, n, v)   SET_GLOBAL_FIELD_N(b, n, S2CR, NSCFG, v)
+#define SET_S2CR_RACFG(b, n, v)   SET_GLOBAL_FIELD_N(b, n, S2CR, RACFG, v)
+#define SET_S2CR_WACFG(b, n, v)   SET_GLOBAL_FIELD_N(b, n, S2CR, WACFG, v)
+#define SET_S2CR_PRIVCFG(b, n, v) SET_GLOBAL_FIELD_N(b, n, S2CR, PRIVCFG, v)
+#define SET_S2CR_INSTCFG(b, n, v) SET_GLOBAL_FIELD_N(b, n, S2CR, INSTCFG, v)
+#define SET_S2CR_TRANSIENTCFG(b, n, v) \
+				SET_GLOBAL_FIELD_N(b, n, S2CR, TRANSIENTCFG, v)
+#define SET_S2CR_VMID(b, n, v)    SET_GLOBAL_FIELD_N(b, n, S2CR, VMID, v)
+#define SET_S2CR_BSU(b, n, v)     SET_GLOBAL_FIELD_N(b, n, S2CR, BSU, v)
+#define SET_S2CR_FB(b, n, v)      SET_GLOBAL_FIELD_N(b, n, S2CR, FB, v)
+
+#define GET_S2CR_CBNDX(b, n)      GET_GLOBAL_FIELD_N(b, n, S2CR, CBNDX)
+#define GET_S2CR_SHCFG(b, n)      GET_GLOBAL_FIELD_N(b, n, S2CR, SHCFG)
+#define GET_S2CR_MTCFG(b, n)      GET_GLOBAL_FIELD_N(b, n, S2CR, MTCFG)
+#define GET_S2CR_MEMATTR(b, n)    GET_GLOBAL_FIELD_N(b, n, S2CR, MEMATTR)
+#define GET_S2CR_TYPE(b, n)       GET_GLOBAL_FIELD_N(b, n, S2CR, TYPE)
+#define GET_S2CR_NSCFG(b, n)      GET_GLOBAL_FIELD_N(b, n, S2CR, NSCFG)
+#define GET_S2CR_RACFG(b, n)      GET_GLOBAL_FIELD_N(b, n, S2CR, RACFG)
+#define GET_S2CR_WACFG(b, n)      GET_GLOBAL_FIELD_N(b, n, S2CR, WACFG)
+#define GET_S2CR_PRIVCFG(b, n)    GET_GLOBAL_FIELD_N(b, n, S2CR, PRIVCFG)
+#define GET_S2CR_INSTCFG(b, n)    GET_GLOBAL_FIELD_N(b, n, S2CR, INSTCFG)
+#define GET_S2CR_TRANSIENTCFG(b, n) \
+				GET_GLOBAL_FIELD_N(b, n, S2CR, TRANSIENTCFG)
+#define GET_S2CR_VMID(b, n)       GET_GLOBAL_FIELD_N(b, n, S2CR, VMID)
+#define GET_S2CR_BSU(b, n)        GET_GLOBAL_FIELD_N(b, n, S2CR, BSU)
+#define GET_S2CR_FB(b, n)         GET_GLOBAL_FIELD_N(b, n, S2CR, FB)
+
+/* Stream Match Register: SMR_N */
+#define SET_SMR_ID(b, n, v)       SET_GLOBAL_FIELD_N(b, n, SMR, ID, v)
+#define SET_SMR_MASK(b, n, v)     SET_GLOBAL_FIELD_N(b, n, SMR, MASK, v)
+#define SET_SMR_VALID(b, n, v)    SET_GLOBAL_FIELD_N(b, n, SMR, VALID, v)
+
+#define GET_SMR_ID(b, n)          GET_GLOBAL_FIELD_N(b, n, SMR, ID)
+#define GET_SMR_MASK(b, n)        GET_GLOBAL_FIELD_N(b, n, SMR, MASK)
+#define GET_SMR_VALID(b, n)       GET_GLOBAL_FIELD_N(b, n, SMR, VALID)
+
+/* Global TLB Status: TLBGSTATUS */
+#define SET_TLBGSTATUS_GSACTIVE(b, v) \
+				SET_GLOBAL_FIELD(b, TLBGSTATUS, GSACTIVE, v)
+
+#define GET_TLBGSTATUS_GSACTIVE(b)    \
+				GET_GLOBAL_FIELD(b, TLBGSTATUS, GSACTIVE)
+
+/* Invalidate Hyp TLB by VA: TLBIVAH */
+#define SET_TLBIVAH_ADDR(b, v)  SET_GLOBAL_FIELD(b, TLBIVAH, ADDR, v)
+
+#define GET_TLBIVAH_ADDR(b)     GET_GLOBAL_FIELD(b, TLBIVAH, ADDR)
+
+/* Invalidate TLB by VMID: TLBIVMID */
+#define SET_TLBIVMID_VMID(b, v) SET_GLOBAL_FIELD(b, TLBIVMID, VMID, v)
+
+#define GET_TLBIVMID_VMID(b)    GET_GLOBAL_FIELD(b, TLBIVMID, VMID)
+
+/* Global Register Space 1 Field setters/getters*/
+/* Context Bank Attribute Register: CBAR_N */
+#define SET_CBAR_VMID(b, n, v)     SET_GLOBAL_FIELD_N(b, n, CBAR, VMID, v)
+#define SET_CBAR_CBNDX(b, n, v)    SET_GLOBAL_FIELD_N(b, n, CBAR, CBNDX, v)
+#define SET_CBAR_BPSHCFG(b, n, v)  SET_GLOBAL_FIELD_N(b, n, CBAR, BPSHCFG, v)
+#define SET_CBAR_HYPC(b, n, v)     SET_GLOBAL_FIELD_N(b, n, CBAR, HYPC, v)
+#define SET_CBAR_FB(b, n, v)       SET_GLOBAL_FIELD_N(b, n, CBAR, FB, v)
+#define SET_CBAR_MEMATTR(b, n, v)  SET_GLOBAL_FIELD_N(b, n, CBAR, MEMATTR, v)
+#define SET_CBAR_TYPE(b, n, v)     SET_GLOBAL_FIELD_N(b, n, CBAR, TYPE, v)
+#define SET_CBAR_BSU(b, n, v)      SET_GLOBAL_FIELD_N(b, n, CBAR, BSU, v)
+#define SET_CBAR_RACFG(b, n, v)    SET_GLOBAL_FIELD_N(b, n, CBAR, RACFG, v)
+#define SET_CBAR_WACFG(b, n, v)    SET_GLOBAL_FIELD_N(b, n, CBAR, WACFG, v)
+#define SET_CBAR_IRPTNDX(b, n, v)  SET_GLOBAL_FIELD_N(b, n, CBAR, IRPTNDX, v)
+
+#define GET_CBAR_VMID(b, n)        GET_GLOBAL_FIELD_N(b, n, CBAR, VMID)
+#define GET_CBAR_CBNDX(b, n)       GET_GLOBAL_FIELD_N(b, n, CBAR, CBNDX)
+#define GET_CBAR_BPSHCFG(b, n)     GET_GLOBAL_FIELD_N(b, n, CBAR, BPSHCFG)
+#define GET_CBAR_HYPC(b, n)        GET_GLOBAL_FIELD_N(b, n, CBAR, HYPC)
+#define GET_CBAR_FB(b, n)          GET_GLOBAL_FIELD_N(b, n, CBAR, FB)
+#define GET_CBAR_MEMATTR(b, n)     GET_GLOBAL_FIELD_N(b, n, CBAR, MEMATTR)
+#define GET_CBAR_TYPE(b, n)        GET_GLOBAL_FIELD_N(b, n, CBAR, TYPE)
+#define GET_CBAR_BSU(b, n)         GET_GLOBAL_FIELD_N(b, n, CBAR, BSU)
+#define GET_CBAR_RACFG(b, n)       GET_GLOBAL_FIELD_N(b, n, CBAR, RACFG)
+#define GET_CBAR_WACFG(b, n)       GET_GLOBAL_FIELD_N(b, n, CBAR, WACFG)
+#define GET_CBAR_IRPTNDX(b, n)     GET_GLOBAL_FIELD_N(b, n, CBAR, IRPTNDX)
+
+/* Context Bank Fault Restricted Syndrome Register A: CBFRSYNRA_N */
+#define SET_CBFRSYNRA_SID(b, n, v) SET_GLOBAL_FIELD_N(b, n, CBFRSYNRA, SID, v)
+
+#define GET_CBFRSYNRA_SID(b, n)    GET_GLOBAL_FIELD_N(b, n, CBFRSYNRA, SID)
+
+/* Stage 1 Context Bank Format Fields */
+#define SET_CB_ACTLR_REQPRIORITY (b, c, v) \
+		SET_CONTEXT_FIELD(b, c, CB_ACTLR, REQPRIORITY, v)
+#define SET_CB_ACTLR_REQPRIORITYCFG(b, c, v) \
+		SET_CONTEXT_FIELD(b, c, CB_ACTLR, REQPRIORITYCFG, v)
+#define SET_CB_ACTLR_PRIVCFG(b, c, v) \
+		SET_CONTEXT_FIELD(b, c, CB_ACTLR, PRIVCFG, v)
+#define SET_CB_ACTLR_BPRCOSH(b, c, v) \
+		SET_CONTEXT_FIELD(b, c, CB_ACTLR, BPRCOSH, v)
+#define SET_CB_ACTLR_BPRCISH(b, c, v) \
+		SET_CONTEXT_FIELD(b, c, CB_ACTLR, BPRCISH, v)
+#define SET_CB_ACTLR_BPRCNSH(b, c, v) \
+		SET_CONTEXT_FIELD(b, c, CB_ACTLR, BPRCNSH, v)
+
+#define GET_CB_ACTLR_REQPRIORITY (b, c) \
+		GET_CONTEXT_FIELD(b, c, CB_ACTLR, REQPRIORITY)
+#define GET_CB_ACTLR_REQPRIORITYCFG(b, c) \
+		GET_CONTEXT_FIELD(b, c, CB_ACTLR, REQPRIORITYCFG)
+#define GET_CB_ACTLR_PRIVCFG(b, c)  GET_CONTEXT_FIELD(b, c, CB_ACTLR, PRIVCFG)
+#define GET_CB_ACTLR_BPRCOSH(b, c)  GET_CONTEXT_FIELD(b, c, CB_ACTLR, BPRCOSH)
+#define GET_CB_ACTLR_BPRCISH(b, c)  GET_CONTEXT_FIELD(b, c, CB_ACTLR, BPRCISH)
+#define GET_CB_ACTLR_BPRCNSH(b, c)  GET_CONTEXT_FIELD(b, c, CB_ACTLR, BPRCNSH)
+
+/* Address Translation, Stage 1, Privileged Read: CB_ATS1PR */
+#define SET_CB_ATS1PR_ADDR(b, c, v) SET_CONTEXT_FIELD(b, c, CB_ATS1PR, ADDR, v)
+
+#define GET_CB_ATS1PR_ADDR(b, c)    GET_CONTEXT_FIELD(b, c, CB_ATS1PR, ADDR)
+
+/* Address Translation, Stage 1, Privileged Write: CB_ATS1PW */
+#define SET_CB_ATS1PW_ADDR(b, c, v) SET_CONTEXT_FIELD(b, c, CB_ATS1PW, ADDR, v)
+
+#define GET_CB_ATS1PW_ADDR(b, c)    GET_CONTEXT_FIELD(b, c, CB_ATS1PW, ADDR)
+
+/* Address Translation, Stage 1, User Read: CB_ATS1UR */
+#define SET_CB_ATS1UR_ADDR(b, c, v) SET_CONTEXT_FIELD(b, c, CB_ATS1UR, ADDR, v)
+
+#define GET_CB_ATS1UR_ADDR(b, c)    GET_CONTEXT_FIELD(b, c, CB_ATS1UR, ADDR)
+
+/* Address Translation, Stage 1, User Write: CB_ATS1UW */
+#define SET_CB_ATS1UW_ADDR(b, c, v) SET_CONTEXT_FIELD(b, c, CB_ATS1UW, ADDR, v)
+
+#define GET_CB_ATS1UW_ADDR(b, c)    GET_CONTEXT_FIELD(b, c, CB_ATS1UW, ADDR)
+
+/* Address Translation Status Register: CB_ATSR */
+#define SET_CB_ATSR_ACTIVE(b, c, v) SET_CONTEXT_FIELD(b, c, CB_ATSR, ACTIVE, v)
+
+#define GET_CB_ATSR_ACTIVE(b, c)    GET_CONTEXT_FIELD(b, c, CB_ATSR, ACTIVE)
+
+/* Context ID Register: CB_CONTEXTIDR */
+#define SET_CB_CONTEXTIDR_ASID(b, c, v) \
+			SET_CONTEXT_FIELD(b, c, CB_CONTEXTIDR, ASID, v)
+#define SET_CB_CONTEXTIDR_PROCID(b, c, v) \
+			SET_CONTEXT_FIELD(b, c, CB_CONTEXTIDR, PROCID, v)
+
+#define GET_CB_CONTEXTIDR_ASID(b, c)    \
+			GET_CONTEXT_FIELD(b, c, CB_CONTEXTIDR, ASID)
+#define GET_CB_CONTEXTIDR_PROCID(b, c)    \
+			GET_CONTEXT_FIELD(b, c, CB_CONTEXTIDR, PROCID)
+
+/* Fault Address Register: CB_FAR */
+#define SET_CB_FAR_FADDR(b, c, v) SET_CONTEXT_FIELD(b, c, CB_FAR, FADDR, v)
+
+#define GET_CB_FAR_FADDR(b, c)    GET_CONTEXT_FIELD(b, c, CB_FAR, FADDR)
+
+/* Fault Status Register: CB_FSR */
+#define SET_CB_FSR_TF(b, c, v)     SET_CONTEXT_FIELD(b, c, CB_FSR, TF, v)
+#define SET_CB_FSR_AFF(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_FSR, AFF, v)
+#define SET_CB_FSR_PF(b, c, v)     SET_CONTEXT_FIELD(b, c, CB_FSR, PF, v)
+#define SET_CB_FSR_EF(b, c, v)     SET_CONTEXT_FIELD(b, c, CB_FSR, EF, v)
+#define SET_CB_FSR_TLBMCF(b, c, v) SET_CONTEXT_FIELD(b, c, CB_FSR, TLBMCF, v)
+#define SET_CB_FSR_TLBLKF(b, c, v) SET_CONTEXT_FIELD(b, c, CB_FSR, TLBLKF, v)
+#define SET_CB_FSR_SS(b, c, v)     SET_CONTEXT_FIELD(b, c, CB_FSR, SS, v)
+#define SET_CB_FSR_MULTI(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_FSR, MULTI, v)
+
+#define GET_CB_FSR_TF(b, c)        GET_CONTEXT_FIELD(b, c, CB_FSR, TF)
+#define GET_CB_FSR_AFF(b, c)       GET_CONTEXT_FIELD(b, c, CB_FSR, AFF)
+#define GET_CB_FSR_PF(b, c)        GET_CONTEXT_FIELD(b, c, CB_FSR, PF)
+#define GET_CB_FSR_EF(b, c)        GET_CONTEXT_FIELD(b, c, CB_FSR, EF)
+#define GET_CB_FSR_TLBMCF(b, c)    GET_CONTEXT_FIELD(b, c, CB_FSR, TLBMCF)
+#define GET_CB_FSR_TLBLKF(b, c)    GET_CONTEXT_FIELD(b, c, CB_FSR, TLBLKF)
+#define GET_CB_FSR_SS(b, c)        GET_CONTEXT_FIELD(b, c, CB_FSR, SS)
+#define GET_CB_FSR_MULTI(b, c)     GET_CONTEXT_FIELD(b, c, CB_FSR, MULTI)
+
+/* Fault Syndrome Register 0: CB_FSYNR0 */
+#define SET_CB_FSYNR0_PLVL(b, c, v) SET_CONTEXT_FIELD(b, c, CB_FSYNR0, PLVL, v)
+#define SET_CB_FSYNR0_S1PTWF(b, c, v) \
+				SET_CONTEXT_FIELD(b, c, CB_FSYNR0, S1PTWF, v)
+#define SET_CB_FSYNR0_WNR(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_FSYNR0, WNR, v)
+#define SET_CB_FSYNR0_PNU(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_FSYNR0, PNU, v)
+#define SET_CB_FSYNR0_IND(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_FSYNR0, IND, v)
+#define SET_CB_FSYNR0_NSSTATE(b, c, v) \
+				SET_CONTEXT_FIELD(b, c, CB_FSYNR0, NSSTATE, v)
+#define SET_CB_FSYNR0_NSATTR(b, c, v) \
+				SET_CONTEXT_FIELD(b, c, CB_FSYNR0, NSATTR, v)
+#define SET_CB_FSYNR0_ATOF(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_FSYNR0, ATOF, v)
+#define SET_CB_FSYNR0_PTWF(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_FSYNR0, PTWF, v)
+#define SET_CB_FSYNR0_AFR(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_FSYNR0, AFR, v)
+#define SET_CB_FSYNR0_S1CBNDX(b, c, v) \
+				SET_CONTEXT_FIELD(b, c, CB_FSYNR0, S1CBNDX, v)
+
+#define GET_CB_FSYNR0_PLVL(b, c)    GET_CONTEXT_FIELD(b, c, CB_FSYNR0, PLVL)
+#define GET_CB_FSYNR0_S1PTWF(b, c)    \
+				GET_CONTEXT_FIELD(b, c, CB_FSYNR0, S1PTWF)
+#define GET_CB_FSYNR0_WNR(b, c)     GET_CONTEXT_FIELD(b, c, CB_FSYNR0, WNR)
+#define GET_CB_FSYNR0_PNU(b, c)     GET_CONTEXT_FIELD(b, c, CB_FSYNR0, PNU)
+#define GET_CB_FSYNR0_IND(b, c)     GET_CONTEXT_FIELD(b, c, CB_FSYNR0, IND)
+#define GET_CB_FSYNR0_NSSTATE(b, c)    \
+				GET_CONTEXT_FIELD(b, c, CB_FSYNR0, NSSTATE)
+#define GET_CB_FSYNR0_NSATTR(b, c)    \
+				GET_CONTEXT_FIELD(b, c, CB_FSYNR0, NSATTR)
+#define GET_CB_FSYNR0_ATOF(b, c)     GET_CONTEXT_FIELD(b, c, CB_FSYNR0, ATOF)
+#define GET_CB_FSYNR0_PTWF(b, c)     GET_CONTEXT_FIELD(b, c, CB_FSYNR0, PTWF)
+#define GET_CB_FSYNR0_AFR(b, c)      GET_CONTEXT_FIELD(b, c, CB_FSYNR0, AFR)
+#define GET_CB_FSYNR0_S1CBNDX(b, c)    \
+				GET_CONTEXT_FIELD(b, c, CB_FSYNR0, S1CBNDX)
+
+/* Normal Memory Remap Register: CB_NMRR */
+#define SET_CB_NMRR_IR0(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, IR0, v)
+#define SET_CB_NMRR_IR1(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, IR1, v)
+#define SET_CB_NMRR_IR2(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, IR2, v)
+#define SET_CB_NMRR_IR3(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, IR3, v)
+#define SET_CB_NMRR_IR4(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, IR4, v)
+#define SET_CB_NMRR_IR5(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, IR5, v)
+#define SET_CB_NMRR_IR6(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, IR6, v)
+#define SET_CB_NMRR_IR7(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, IR7, v)
+#define SET_CB_NMRR_OR0(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, OR0, v)
+#define SET_CB_NMRR_OR1(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, OR1, v)
+#define SET_CB_NMRR_OR2(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, OR2, v)
+#define SET_CB_NMRR_OR3(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, OR3, v)
+#define SET_CB_NMRR_OR4(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, OR4, v)
+#define SET_CB_NMRR_OR5(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, OR5, v)
+#define SET_CB_NMRR_OR6(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, OR6, v)
+#define SET_CB_NMRR_OR7(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, OR7, v)
+
+#define GET_CB_NMRR_IR0(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, IR0)
+#define GET_CB_NMRR_IR1(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, IR1)
+#define GET_CB_NMRR_IR2(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, IR2)
+#define GET_CB_NMRR_IR3(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, IR3)
+#define GET_CB_NMRR_IR4(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, IR4)
+#define GET_CB_NMRR_IR5(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, IR5)
+#define GET_CB_NMRR_IR6(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, IR6)
+#define GET_CB_NMRR_IR7(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, IR7)
+#define GET_CB_NMRR_OR0(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, OR0)
+#define GET_CB_NMRR_OR1(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, OR1)
+#define GET_CB_NMRR_OR2(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, OR2)
+#define GET_CB_NMRR_OR3(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, OR3)
+#define GET_CB_NMRR_OR4(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, OR4)
+#define GET_CB_NMRR_OR5(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, OR5)
+
+/* Physical Address Register: CB_PAR */
+#define SET_CB_PAR_F(b, c, v)       SET_CONTEXT_FIELD(b, c, CB_PAR, F, v)
+#define SET_CB_PAR_SS(b, c, v)      SET_CONTEXT_FIELD(b, c, CB_PAR, SS, v)
+#define SET_CB_PAR_OUTER(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_PAR, OUTER, v)
+#define SET_CB_PAR_INNER(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_PAR, INNER, v)
+#define SET_CB_PAR_SH(b, c, v)      SET_CONTEXT_FIELD(b, c, CB_PAR, SH, v)
+#define SET_CB_PAR_NS(b, c, v)      SET_CONTEXT_FIELD(b, c, CB_PAR, NS, v)
+#define SET_CB_PAR_NOS(b, c, v)     SET_CONTEXT_FIELD(b, c, CB_PAR, NOS, v)
+#define SET_CB_PAR_PA(b, c, v)      SET_CONTEXT_FIELD(b, c, CB_PAR, PA, v)
+#define SET_CB_PAR_TF(b, c, v)      SET_CONTEXT_FIELD(b, c, CB_PAR, TF, v)
+#define SET_CB_PAR_AFF(b, c, v)     SET_CONTEXT_FIELD(b, c, CB_PAR, AFF, v)
+#define SET_CB_PAR_PF(b, c, v)      SET_CONTEXT_FIELD(b, c, CB_PAR, PF, v)
+#define SET_CB_PAR_TLBMCF(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_PAR, TLBMCF, v)
+#define SET_CB_PAR_TLBLKF(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_PAR, TLBLKF, v)
+#define SET_CB_PAR_ATOT(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PAR, ATOT, v)
+#define SET_CB_PAR_PLVL(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PAR, PLVL, v)
+#define SET_CB_PAR_STAGE(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_PAR, STAGE, v)
+
+#define GET_CB_PAR_F(b, c)          GET_CONTEXT_FIELD(b, c, CB_PAR, F)
+#define GET_CB_PAR_SS(b, c)         GET_CONTEXT_FIELD(b, c, CB_PAR, SS)
+#define GET_CB_PAR_OUTER(b, c)      GET_CONTEXT_FIELD(b, c, CB_PAR, OUTER)
+#define GET_CB_PAR_INNER(b, c)      GET_CONTEXT_FIELD(b, c, CB_PAR, INNER)
+#define GET_CB_PAR_SH(b, c)         GET_CONTEXT_FIELD(b, c, CB_PAR, SH)
+#define GET_CB_PAR_NS(b, c)         GET_CONTEXT_FIELD(b, c, CB_PAR, NS)
+#define GET_CB_PAR_NOS(b, c)        GET_CONTEXT_FIELD(b, c, CB_PAR, NOS)
+#define GET_CB_PAR_PA(b, c)         GET_CONTEXT_FIELD(b, c, CB_PAR, PA)
+#define GET_CB_PAR_TF(b, c)         GET_CONTEXT_FIELD(b, c, CB_PAR, TF)
+#define GET_CB_PAR_AFF(b, c)        GET_CONTEXT_FIELD(b, c, CB_PAR, AFF)
+#define GET_CB_PAR_PF(b, c)         GET_CONTEXT_FIELD(b, c, CB_PAR, PF)
+#define GET_CB_PAR_TLBMCF(b, c)     GET_CONTEXT_FIELD(b, c, CB_PAR, TLBMCF)
+#define GET_CB_PAR_TLBLKF(b, c)     GET_CONTEXT_FIELD(b, c, CB_PAR, TLBLKF)
+#define GET_CB_PAR_ATOT(b, c)       GET_CONTEXT_FIELD(b, c, CB_PAR, ATOT)
+#define GET_CB_PAR_PLVL(b, c)       GET_CONTEXT_FIELD(b, c, CB_PAR, PLVL)
+#define GET_CB_PAR_STAGE(b, c)      GET_CONTEXT_FIELD(b, c, CB_PAR, STAGE)
+
+/* Primary Region Remap Register: CB_PRRR */
+#define SET_CB_PRRR_TR0(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PRRR, TR0, v)
+#define SET_CB_PRRR_TR1(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PRRR, TR1, v)
+#define SET_CB_PRRR_TR2(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PRRR, TR2, v)
+#define SET_CB_PRRR_TR3(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PRRR, TR3, v)
+#define SET_CB_PRRR_TR4(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PRRR, TR4, v)
+#define SET_CB_PRRR_TR5(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PRRR, TR5, v)
+#define SET_CB_PRRR_TR6(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PRRR, TR6, v)
+#define SET_CB_PRRR_TR7(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PRRR, TR7, v)
+#define SET_CB_PRRR_DS0(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PRRR, DS0, v)
+#define SET_CB_PRRR_DS1(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PRRR, DS1, v)
+#define SET_CB_PRRR_NS0(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PRRR, NS0, v)
+#define SET_CB_PRRR_NS1(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PRRR, NS1, v)
+#define SET_CB_PRRR_NOS0(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_PRRR, NOS0, v)
+#define SET_CB_PRRR_NOS1(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_PRRR, NOS1, v)
+#define SET_CB_PRRR_NOS2(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_PRRR, NOS2, v)
+#define SET_CB_PRRR_NOS3(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_PRRR, NOS3, v)
+#define SET_CB_PRRR_NOS4(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_PRRR, NOS4, v)
+#define SET_CB_PRRR_NOS5(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_PRRR, NOS5, v)
+#define SET_CB_PRRR_NOS6(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_PRRR, NOS6, v)
+#define SET_CB_PRRR_NOS7(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_PRRR, NOS7, v)
+
+#define GET_CB_PRRR_TR0(b, c)       GET_CONTEXT_FIELD(b, c, CB_PRRR, TR0)
+#define GET_CB_PRRR_TR1(b, c)       GET_CONTEXT_FIELD(b, c, CB_PRRR, TR1)
+#define GET_CB_PRRR_TR2(b, c)       GET_CONTEXT_FIELD(b, c, CB_PRRR, TR2)
+#define GET_CB_PRRR_TR3(b, c)       GET_CONTEXT_FIELD(b, c, CB_PRRR, TR3)
+#define GET_CB_PRRR_TR4(b, c)       GET_CONTEXT_FIELD(b, c, CB_PRRR, TR4)
+#define GET_CB_PRRR_TR5(b, c)       GET_CONTEXT_FIELD(b, c, CB_PRRR, TR5)
+#define GET_CB_PRRR_TR6(b, c)       GET_CONTEXT_FIELD(b, c, CB_PRRR, TR6)
+#define GET_CB_PRRR_TR7(b, c)       GET_CONTEXT_FIELD(b, c, CB_PRRR, TR7)
+#define GET_CB_PRRR_DS0(b, c)       GET_CONTEXT_FIELD(b, c, CB_PRRR, DS0)
+#define GET_CB_PRRR_DS1(b, c)       GET_CONTEXT_FIELD(b, c, CB_PRRR, DS1)
+#define GET_CB_PRRR_NS0(b, c)       GET_CONTEXT_FIELD(b, c, CB_PRRR, NS0)
+#define GET_CB_PRRR_NS1(b, c)       GET_CONTEXT_FIELD(b, c, CB_PRRR, NS1)
+#define GET_CB_PRRR_NOS0(b, c)      GET_CONTEXT_FIELD(b, c, CB_PRRR, NOS0)
+#define GET_CB_PRRR_NOS1(b, c)      GET_CONTEXT_FIELD(b, c, CB_PRRR, NOS1)
+#define GET_CB_PRRR_NOS2(b, c)      GET_CONTEXT_FIELD(b, c, CB_PRRR, NOS2)
+#define GET_CB_PRRR_NOS3(b, c)      GET_CONTEXT_FIELD(b, c, CB_PRRR, NOS3)
+#define GET_CB_PRRR_NOS4(b, c)      GET_CONTEXT_FIELD(b, c, CB_PRRR, NOS4)
+#define GET_CB_PRRR_NOS5(b, c)      GET_CONTEXT_FIELD(b, c, CB_PRRR, NOS5)
+#define GET_CB_PRRR_NOS6(b, c)      GET_CONTEXT_FIELD(b, c, CB_PRRR, NOS6)
+#define GET_CB_PRRR_NOS7(b, c)      GET_CONTEXT_FIELD(b, c, CB_PRRR, NOS7)
+
+/* Transaction Resume: CB_RESUME */
+#define SET_CB_RESUME_TNR(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_RESUME, TNR, v)
+
+#define GET_CB_RESUME_TNR(b, c)     GET_CONTEXT_FIELD(b, c, CB_RESUME, TNR)
+
+/* System Control Register: CB_SCTLR */
+#define SET_CB_SCTLR_M(b, c, v)     SET_CONTEXT_FIELD(b, c, CB_SCTLR, M, v)
+#define SET_CB_SCTLR_TRE(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_SCTLR, TRE, v)
+#define SET_CB_SCTLR_AFE(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_SCTLR, AFE, v)
+#define SET_CB_SCTLR_AFFD(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_SCTLR, AFFD, v)
+#define SET_CB_SCTLR_E(b, c, v)     SET_CONTEXT_FIELD(b, c, CB_SCTLR, E, v)
+#define SET_CB_SCTLR_CFRE(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_SCTLR, CFRE, v)
+#define SET_CB_SCTLR_CFIE(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_SCTLR, CFIE, v)
+#define SET_CB_SCTLR_CFCFG(b, c, v) SET_CONTEXT_FIELD(b, c, CB_SCTLR, CFCFG, v)
+#define SET_CB_SCTLR_HUPCF(b, c, v) SET_CONTEXT_FIELD(b, c, CB_SCTLR, HUPCF, v)
+#define SET_CB_SCTLR_WXN(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_SCTLR, WXN, v)
+#define SET_CB_SCTLR_UWXN(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_SCTLR, UWXN, v)
+#define SET_CB_SCTLR_ASIDPNE(b, c, v) \
+			SET_CONTEXT_FIELD(b, c, CB_SCTLR, ASIDPNE, v)
+#define SET_CB_SCTLR_TRANSIENTCFG(b, c, v) \
+			SET_CONTEXT_FIELD(b, c, CB_SCTLR, TRANSIENTCFG, v)
+#define SET_CB_SCTLR_MEMATTR(b, c, v) \
+			SET_CONTEXT_FIELD(b, c, CB_SCTLR, MEMATTR, v)
+#define SET_CB_SCTLR_MTCFG(b, c, v) SET_CONTEXT_FIELD(b, c, CB_SCTLR, MTCFG, v)
+#define SET_CB_SCTLR_SHCFG(b, c, v) SET_CONTEXT_FIELD(b, c, CB_SCTLR, SHCFG, v)
+#define SET_CB_SCTLR_RACFG(b, c, v) SET_CONTEXT_FIELD(b, c, CB_SCTLR, RACFG, v)
+#define SET_CB_SCTLR_WACFG(b, c, v) SET_CONTEXT_FIELD(b, c, CB_SCTLR, WACFG, v)
+#define SET_CB_SCTLR_NSCFG(b, c, v) SET_CONTEXT_FIELD(b, c, CB_SCTLR, NSCFG, v)
+
+#define GET_CB_SCTLR_M(b, c)        GET_CONTEXT_FIELD(b, c, CB_SCTLR, M)
+#define GET_CB_SCTLR_TRE(b, c)      GET_CONTEXT_FIELD(b, c, CB_SCTLR, TRE)
+#define GET_CB_SCTLR_AFE(b, c)      GET_CONTEXT_FIELD(b, c, CB_SCTLR, AFE)
+#define GET_CB_SCTLR_AFFD(b, c)     GET_CONTEXT_FIELD(b, c, CB_SCTLR, AFFD)
+#define GET_CB_SCTLR_E(b, c)        GET_CONTEXT_FIELD(b, c, CB_SCTLR, E)
+#define GET_CB_SCTLR_CFRE(b, c)     GET_CONTEXT_FIELD(b, c, CB_SCTLR, CFRE)
+#define GET_CB_SCTLR_CFIE(b, c)     GET_CONTEXT_FIELD(b, c, CB_SCTLR, CFIE)
+#define GET_CB_SCTLR_CFCFG(b, c)    GET_CONTEXT_FIELD(b, c, CB_SCTLR, CFCFG)
+#define GET_CB_SCTLR_HUPCF(b, c)    GET_CONTEXT_FIELD(b, c, CB_SCTLR, HUPCF)
+#define GET_CB_SCTLR_WXN(b, c)      GET_CONTEXT_FIELD(b, c, CB_SCTLR, WXN)
+#define GET_CB_SCTLR_UWXN(b, c)     GET_CONTEXT_FIELD(b, c, CB_SCTLR, UWXN)
+#define GET_CB_SCTLR_ASIDPNE(b, c)    \
+			GET_CONTEXT_FIELD(b, c, CB_SCTLR, ASIDPNE)
+#define GET_CB_SCTLR_TRANSIENTCFG(b, c)    \
+			GET_CONTEXT_FIELD(b, c, CB_SCTLR, TRANSIENTCFG)
+#define GET_CB_SCTLR_MEMATTR(b, c)    \
+			GET_CONTEXT_FIELD(b, c, CB_SCTLR, MEMATTR)
+#define GET_CB_SCTLR_MTCFG(b, c)    GET_CONTEXT_FIELD(b, c, CB_SCTLR, MTCFG)
+#define GET_CB_SCTLR_SHCFG(b, c)    GET_CONTEXT_FIELD(b, c, CB_SCTLR, SHCFG)
+#define GET_CB_SCTLR_RACFG(b, c)    GET_CONTEXT_FIELD(b, c, CB_SCTLR, RACFG)
+#define GET_CB_SCTLR_WACFG(b, c)    GET_CONTEXT_FIELD(b, c, CB_SCTLR, WACFG)
+#define GET_CB_SCTLR_NSCFG(b, c)    GET_CONTEXT_FIELD(b, c, CB_SCTLR, NSCFG)
+
+/* Invalidate TLB by ASID: CB_TLBIASID */
+#define SET_CB_TLBIASID_ASID(b, c, v) \
+				SET_CONTEXT_FIELD(b, c, CB_TLBIASID, ASID, v)
+
+#define GET_CB_TLBIASID_ASID(b, c)    \
+				GET_CONTEXT_FIELD(b, c, CB_TLBIASID, ASID)
+
+/* Invalidate TLB by VA: CB_TLBIVA */
+#define SET_CB_TLBIVA_ASID(b, c, v) SET_CONTEXT_FIELD(b, c, CB_TLBIVA, ASID, v)
+#define SET_CB_TLBIVA_VA(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_TLBIVA, VA, v)
+
+#define GET_CB_TLBIVA_ASID(b, c)    GET_CONTEXT_FIELD(b, c, CB_TLBIVA, ASID)
+#define GET_CB_TLBIVA_VA(b, c)      GET_CONTEXT_FIELD(b, c, CB_TLBIVA, VA)
+
+/* Invalidate TLB by VA, All ASID: CB_TLBIVAA */
+#define SET_CB_TLBIVAA_VA(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_TLBIVAA, VA, v)
+
+#define GET_CB_TLBIVAA_VA(b, c)     GET_CONTEXT_FIELD(b, c, CB_TLBIVAA, VA)
+
+/* Invalidate TLB by VA, All ASID, Last Level: CB_TLBIVAAL */
+#define SET_CB_TLBIVAAL_VA(b, c, v) SET_CONTEXT_FIELD(b, c, CB_TLBIVAAL, VA, v)
+
+#define GET_CB_TLBIVAAL_VA(b, c)    GET_CONTEXT_FIELD(b, c, CB_TLBIVAAL, VA)
+
+/* Invalidate TLB by VA, Last Level: CB_TLBIVAL */
+#define SET_CB_TLBIVAL_ASID(b, c, v) \
+			SET_CONTEXT_FIELD(b, c, CB_TLBIVAL, ASID, v)
+#define SET_CB_TLBIVAL_VA(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_TLBIVAL, VA, v)
+
+#define GET_CB_TLBIVAL_ASID(b, c)    \
+			GET_CONTEXT_FIELD(b, c, CB_TLBIVAL, ASID)
+#define GET_CB_TLBIVAL_VA(b, c)      GET_CONTEXT_FIELD(b, c, CB_TLBIVAL, VA)
+
+/* TLB Status: CB_TLBSTATUS */
+#define SET_CB_TLBSTATUS_SACTIVE(b, c, v) \
+			SET_CONTEXT_FIELD(b, c, CB_TLBSTATUS, SACTIVE, v)
+
+#define GET_CB_TLBSTATUS_SACTIVE(b, c)    \
+			GET_CONTEXT_FIELD(b, c, CB_TLBSTATUS, SACTIVE)
+
+/* Translation Table Base Control Register: CB_TTBCR */
+#define SET_CB_TTBCR_T0SZ(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_TTBCR, T0SZ, v)
+#define SET_CB_TTBCR_PD0(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_TTBCR, PD0, v)
+#define SET_CB_TTBCR_PD1(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_TTBCR, PD1, v)
+#define SET_CB_TTBCR_NSCFG0(b, c, v) \
+			SET_CONTEXT_FIELD(b, c, CB_TTBCR, NSCFG0, v)
+#define SET_CB_TTBCR_NSCFG1(b, c, v) \
+			SET_CONTEXT_FIELD(b, c, CB_TTBCR, NSCFG1, v)
+#define SET_CB_TTBCR_EAE(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_TTBCR, EAE, v)
+
+#define GET_CB_TTBCR_T0SZ(b, c)      GET_CONTEXT_FIELD(b, c, CB_TTBCR, T0SZ)
+#define GET_CB_TTBCR_PD0(b, c)       GET_CONTEXT_FIELD(b, c, CB_TTBCR, PD0)
+#define GET_CB_TTBCR_PD1(b, c)       GET_CONTEXT_FIELD(b, c, CB_TTBCR, PD1)
+#define GET_CB_TTBCR_NSCFG0(b, c)    \
+			GET_CONTEXT_FIELD(b, c, CB_TTBCR, NSCFG0)
+#define GET_CB_TTBCR_NSCFG1(b, c)    \
+			GET_CONTEXT_FIELD(b, c, CB_TTBCR, NSCFG1)
+#define GET_CB_TTBCR_EAE(b, c)       GET_CONTEXT_FIELD(b, c, CB_TTBCR, EAE)
+
+/* Translation Table Base Register 0: CB_TTBR */
+#define SET_CB_TTBR0_IRGN1(b, c, v) SET_CONTEXT_FIELD(b, c, CB_TTBR0, IRGN1, v)
+#define SET_CB_TTBR0_S(b, c, v)     SET_CONTEXT_FIELD(b, c, CB_TTBR0, S, v)
+#define SET_CB_TTBR0_RGN(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_TTBR0, RGN, v)
+#define SET_CB_TTBR0_NOS(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_TTBR0, NOS, v)
+#define SET_CB_TTBR0_IRGN0(b, c, v) SET_CONTEXT_FIELD(b, c, CB_TTBR0, IRGN0, v)
+#define SET_CB_TTBR0_ADDR(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_TTBR0, ADDR, v)
+
+#define GET_CB_TTBR0_IRGN1(b, c)    GET_CONTEXT_FIELD(b, c, CB_TTBR0, IRGN1)
+#define GET_CB_TTBR0_S(b, c)        GET_CONTEXT_FIELD(b, c, CB_TTBR0, S)
+#define GET_CB_TTBR0_RGN(b, c)      GET_CONTEXT_FIELD(b, c, CB_TTBR0, RGN)
+#define GET_CB_TTBR0_NOS(b, c)      GET_CONTEXT_FIELD(b, c, CB_TTBR0, NOS)
+#define GET_CB_TTBR0_IRGN0(b, c)    GET_CONTEXT_FIELD(b, c, CB_TTBR0, IRGN0)
+#define GET_CB_TTBR0_ADDR(b, c)     GET_CONTEXT_FIELD(b, c, CB_TTBR0, ADDR)
+
+/* Translation Table Base Register 1: CB_TTBR1 */
+#define SET_CB_TTBR1_IRGN1(b, c, v) SET_CONTEXT_FIELD(b, c, CB_TTBR1, IRGN1, v)
+#define SET_CB_TTBR1_0S(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_TTBR1, S, v)
+#define SET_CB_TTBR1_RGN(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_TTBR1, RGN, v)
+#define SET_CB_TTBR1_NOS(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_TTBR1, NOS, v)
+#define SET_CB_TTBR1_IRGN0(b, c, v) SET_CONTEXT_FIELD(b, c, CB_TTBR1, IRGN0, v)
+#define SET_CB_TTBR1_ADDR(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_TTBR1, ADDR, v)
+
+#define GET_CB_TTBR1_IRGN1(b, c)    GET_CONTEXT_FIELD(b, c, CB_TTBR1, IRGN1)
+#define GET_CB_TTBR1_0S(b, c)       GET_CONTEXT_FIELD(b, c, CB_TTBR1, S)
+#define GET_CB_TTBR1_RGN(b, c)      GET_CONTEXT_FIELD(b, c, CB_TTBR1, RGN)
+#define GET_CB_TTBR1_NOS(b, c)      GET_CONTEXT_FIELD(b, c, CB_TTBR1, NOS)
+#define GET_CB_TTBR1_IRGN0(b, c)    GET_CONTEXT_FIELD(b, c, CB_TTBR1, IRGN0)
+#define GET_CB_TTBR1_ADDR(b, c)     GET_CONTEXT_FIELD(b, c, CB_TTBR1, ADDR)
+
+/* Global Register Space 0 */
+#define CR0		(0x0000)
+#define SCR1		(0x0004)
+#define CR2		(0x0008)
+#define ACR		(0x0010)
+#define IDR0		(0x0020)
+#define IDR1		(0x0024)
+#define IDR2		(0x0028)
+#define IDR7		(0x003C)
+#define GFAR		(0x0040)
+#define GFSR		(0x0044)
+#define GFSRRESTORE	(0x004C)
+#define GFSYNR0		(0x0050)
+#define GFSYNR1		(0x0054)
+#define GFSYNR2		(0x0058)
+#define TLBIVMID	(0x0064)
+#define TLBIALLNSNH	(0x0068)
+#define TLBIALLH	(0x006C)
+#define TLBGSYNC	(0x0070)
+#define TLBGSTATUS	(0x0074)
+#define TLBIVAH		(0x0078)
+#define GATS1UR		(0x0100)
+#define GATS1UW		(0x0108)
+#define GATS1PR		(0x0110)
+#define GATS1PW		(0x0118)
+#define GATS12UR	(0x0120)
+#define GATS12UW	(0x0128)
+#define GATS12PR	(0x0130)
+#define GATS12PW	(0x0138)
+#define GPAR		(0x0180)
+#define GATSR		(0x0188)
+#define NSCR0		(0x0400)
+#define NSCR2		(0x0408)
+#define NSACR		(0x0410)
+#define SMR		(0x0800)
+#define S2CR		(0x0C00)
+
+/* Global Register Space 1 */
+#define CBAR		(0x1000)
+#define CBFRSYNRA	(0x1400)
+
+/* Implementation defined Register Space */
+#define MICRO_MMU_CTRL	(0x2000)
+#define PREDICTIONDIS0	(0x204C)
+#define PREDICTIONDIS1	(0x2050)
+#define S1L1BFBLP0	(0x215C)
+
+/* Performance Monitoring Register Space */
+#define PMEVCNTR_N	(0x3000)
+#define PMEVTYPER_N	(0x3400)
+#define PMCGCR_N	(0x3800)
+#define PMCGSMR_N	(0x3A00)
+#define PMCNTENSET_N	(0x3C00)
+#define PMCNTENCLR_N	(0x3C20)
+#define PMINTENSET_N	(0x3C40)
+#define PMINTENCLR_N	(0x3C60)
+#define PMOVSCLR_N	(0x3C80)
+#define PMOVSSET_N	(0x3CC0)
+#define PMCFGR		(0x3E00)
+#define PMCR		(0x3E04)
+#define PMCEID0		(0x3E20)
+#define PMCEID1		(0x3E24)
+#define PMAUTHSTATUS	(0x3FB8)
+#define PMDEVTYPE	(0x3FCC)
+
+/* Secure Status Determination Address Space */
+#define SSDR_N		(0x4000)
+
+/* Stage 1 Context Bank Format */
+#define CB_SCTLR	(0x000)
+#define CB_ACTLR	(0x004)
+#define CB_RESUME	(0x008)
+#define CB_TTBR0	(0x020)
+#define CB_TTBR1	(0x028)
+#define CB_TTBCR	(0x030)
+#define CB_CONTEXTIDR	(0x034)
+#define CB_PRRR		(0x038)
+#define CB_NMRR		(0x03C)
+#define CB_PAR		(0x050)
+#define CB_FSR		(0x058)
+#define CB_FSRRESTORE	(0x05C)
+#define CB_FAR		(0x060)
+#define CB_FSYNR0	(0x068)
+#define CB_FSYNR1	(0x06C)
+#define CB_TLBIVA	(0x600)
+#define CB_TLBIVAA	(0x608)
+#define CB_TLBIASID	(0x610)
+#define CB_TLBIALL	(0x618)
+#define CB_TLBIVAL	(0x620)
+#define CB_TLBIVAAL	(0x628)
+#define CB_TLBSYNC	(0x7F0)
+#define CB_TLBSTATUS	(0x7F4)
+#define CB_ATS1PR	(0x800)
+#define CB_ATS1PW	(0x808)
+#define CB_ATS1UR	(0x810)
+#define CB_ATS1UW	(0x818)
+#define CB_ATSR		(0x8F0)
+#define CB_PMXEVCNTR_N	(0xE00)
+#define CB_PMXEVTYPER_N	(0xE80)
+#define CB_PMCFGR	(0xF00)
+#define CB_PMCR		(0xF04)
+#define CB_PMCEID0	(0xF20)
+#define CB_PMCEID1	(0xF24)
+#define CB_PMCNTENSET	(0xF40)
+#define CB_PMCNTENCLR	(0xF44)
+#define CB_PMINTENSET	(0xF48)
+#define CB_PMINTENCLR	(0xF4C)
+#define CB_PMOVSCLR	(0xF50)
+#define CB_PMOVSSET	(0xF58)
+#define CB_PMAUTHSTATUS	(0xFB8)
+
+/* Global Register Fields */
+/* Configuration Register: CR0 */
+#define CR0_NSCFG         (CR0_NSCFG_MASK         << CR0_NSCFG_SHIFT)
+#define CR0_WACFG         (CR0_WACFG_MASK         << CR0_WACFG_SHIFT)
+#define CR0_RACFG         (CR0_RACFG_MASK         << CR0_RACFG_SHIFT)
+#define CR0_SHCFG         (CR0_SHCFG_MASK         << CR0_SHCFG_SHIFT)
+#define CR0_SMCFCFG       (CR0_SMCFCFG_MASK       << CR0_SMCFCFG_SHIFT)
+#define CR0_MTCFG         (CR0_MTCFG_MASK         << CR0_MTCFG_SHIFT)
+#define CR0_MEMATTR       (CR0_MEMATTR_MASK       << CR0_MEMATTR_SHIFT)
+#define CR0_BSU           (CR0_BSU_MASK           << CR0_BSU_SHIFT)
+#define CR0_FB            (CR0_FB_MASK            << CR0_FB_SHIFT)
+#define CR0_PTM           (CR0_PTM_MASK           << CR0_PTM_SHIFT)
+#define CR0_VMIDPNE       (CR0_VMIDPNE_MASK       << CR0_VMIDPNE_SHIFT)
+#define CR0_USFCFG        (CR0_USFCFG_MASK        << CR0_USFCFG_SHIFT)
+#define CR0_GSE           (CR0_GSE_MASK           << CR0_GSE_SHIFT)
+#define CR0_STALLD        (CR0_STALLD_MASK        << CR0_STALLD_SHIFT)
+#define CR0_TRANSIENTCFG  (CR0_TRANSIENTCFG_MASK  << CR0_TRANSIENTCFG_SHIFT)
+#define CR0_GCFGFIE       (CR0_GCFGFIE_MASK       << CR0_GCFGFIE_SHIFT)
+#define CR0_GCFGFRE       (CR0_GCFGFRE_MASK       << CR0_GCFGFRE_SHIFT)
+#define CR0_GFIE          (CR0_GFIE_MASK          << CR0_GFIE_SHIFT)
+#define CR0_GFRE          (CR0_GFRE_MASK          << CR0_GFRE_SHIFT)
+#define CR0_CLIENTPD      (CR0_CLIENTPD_MASK      << CR0_CLIENTPD_SHIFT)
+
+/* Configuration Register: CR2 */
+#define CR2_BPVMID        (CR2_BPVMID_MASK << CR2_BPVMID_SHIFT)
+
+/* Global Address Translation, Stage 1, Privileged Read: GATS1PR */
+#define GATS1PR_ADDR  (GATS1PR_ADDR_MASK  << GATS1PR_ADDR_SHIFT)
+#define GATS1PR_NDX   (GATS1PR_NDX_MASK   << GATS1PR_NDX_SHIFT)
+
+/* Global Address Translation, Stage 1, Privileged Write: GATS1PW */
+#define GATS1PW_ADDR  (GATS1PW_ADDR_MASK  << GATS1PW_ADDR_SHIFT)
+#define GATS1PW_NDX   (GATS1PW_NDX_MASK   << GATS1PW_NDX_SHIFT)
+
+/* Global Address Translation, Stage 1, User Read: GATS1UR */
+#define GATS1UR_ADDR  (GATS1UR_ADDR_MASK  << GATS1UR_ADDR_SHIFT)
+#define GATS1UR_NDX   (GATS1UR_NDX_MASK   << GATS1UR_NDX_SHIFT)
+
+/* Global Address Translation, Stage 1, User Write: GATS1UW */
+#define GATS1UW_ADDR  (GATS1UW_ADDR_MASK  << GATS1UW_ADDR_SHIFT)
+#define GATS1UW_NDX   (GATS1UW_NDX_MASK   << GATS1UW_NDX_SHIFT)
+
+/* Global Address Translation, Stage 1 and 2, Privileged Read: GATS1PR */
+#define GATS12PR_ADDR (GATS12PR_ADDR_MASK << GATS12PR_ADDR_SHIFT)
+#define GATS12PR_NDX  (GATS12PR_NDX_MASK  << GATS12PR_NDX_SHIFT)
+
+/* Global Address Translation, Stage 1 and 2, Privileged Write: GATS1PW */
+#define GATS12PW_ADDR (GATS12PW_ADDR_MASK << GATS12PW_ADDR_SHIFT)
+#define GATS12PW_NDX  (GATS12PW_NDX_MASK  << GATS12PW_NDX_SHIFT)
+
+/* Global Address Translation, Stage 1 and 2, User Read: GATS1UR */
+#define GATS12UR_ADDR (GATS12UR_ADDR_MASK << GATS12UR_ADDR_SHIFT)
+#define GATS12UR_NDX  (GATS12UR_NDX_MASK  << GATS12UR_NDX_SHIFT)
+
+/* Global Address Translation, Stage 1 and 2, User Write: GATS1UW */
+#define GATS12UW_ADDR (GATS12UW_ADDR_MASK << GATS12UW_ADDR_SHIFT)
+#define GATS12UW_NDX  (GATS12UW_NDX_MASK  << GATS12UW_NDX_SHIFT)
+
+/* Global Address Translation Status Register: GATSR */
+#define GATSR_ACTIVE  (GATSR_ACTIVE_MASK  << GATSR_ACTIVE_SHIFT)
+
+/* Global Fault Address Register: GFAR */
+#define GFAR_FADDR    (GFAR_FADDR_MASK << GFAR_FADDR_SHIFT)
+
+/* Global Fault Status Register: GFSR */
+#define GFSR_ICF      (GFSR_ICF_MASK   << GFSR_ICF_SHIFT)
+#define GFSR_USF      (GFSR_USF_MASK   << GFSR_USF_SHIFT)
+#define GFSR_SMCF     (GFSR_SMCF_MASK  << GFSR_SMCF_SHIFT)
+#define GFSR_UCBF     (GFSR_UCBF_MASK  << GFSR_UCBF_SHIFT)
+#define GFSR_UCIF     (GFSR_UCIF_MASK  << GFSR_UCIF_SHIFT)
+#define GFSR_CAF      (GFSR_CAF_MASK   << GFSR_CAF_SHIFT)
+#define GFSR_EF       (GFSR_EF_MASK    << GFSR_EF_SHIFT)
+#define GFSR_PF       (GFSR_PF_MASK    << GFSR_PF_SHIFT)
+#define GFSR_MULTI    (GFSR_MULTI_MASK << GFSR_MULTI_SHIFT)
+
+/* Global Fault Syndrome Register 0: GFSYNR0 */
+#define GFSYNR0_NESTED  (GFSYNR0_NESTED_MASK  << GFSYNR0_NESTED_SHIFT)
+#define GFSYNR0_WNR     (GFSYNR0_WNR_MASK     << GFSYNR0_WNR_SHIFT)
+#define GFSYNR0_PNU     (GFSYNR0_PNU_MASK     << GFSYNR0_PNU_SHIFT)
+#define GFSYNR0_IND     (GFSYNR0_IND_MASK     << GFSYNR0_IND_SHIFT)
+#define GFSYNR0_NSSTATE (GFSYNR0_NSSTATE_MASK << GFSYNR0_NSSTATE_SHIFT)
+#define GFSYNR0_NSATTR  (GFSYNR0_NSATTR_MASK  << GFSYNR0_NSATTR_SHIFT)
+
+/* Global Fault Syndrome Register 1: GFSYNR1 */
+#define GFSYNR1_SID     (GFSYNR1_SID_MASK     << GFSYNR1_SID_SHIFT)
+
+/* Global Physical Address Register: GPAR */
+#define GPAR_F          (GPAR_F_MASK      << GPAR_F_SHIFT)
+#define GPAR_SS         (GPAR_SS_MASK     << GPAR_SS_SHIFT)
+#define GPAR_OUTER      (GPAR_OUTER_MASK  << GPAR_OUTER_SHIFT)
+#define GPAR_INNER      (GPAR_INNER_MASK  << GPAR_INNER_SHIFT)
+#define GPAR_SH         (GPAR_SH_MASK     << GPAR_SH_SHIFT)
+#define GPAR_NS         (GPAR_NS_MASK     << GPAR_NS_SHIFT)
+#define GPAR_NOS        (GPAR_NOS_MASK    << GPAR_NOS_SHIFT)
+#define GPAR_PA         (GPAR_PA_MASK     << GPAR_PA_SHIFT)
+#define GPAR_TF         (GPAR_TF_MASK     << GPAR_TF_SHIFT)
+#define GPAR_AFF        (GPAR_AFF_MASK    << GPAR_AFF_SHIFT)
+#define GPAR_PF         (GPAR_PF_MASK     << GPAR_PF_SHIFT)
+#define GPAR_EF         (GPAR_EF_MASK     << GPAR_EF_SHIFT)
+#define GPAR_TLCMCF     (GPAR_TLBMCF_MASK << GPAR_TLCMCF_SHIFT)
+#define GPAR_TLBLKF     (GPAR_TLBLKF_MASK << GPAR_TLBLKF_SHIFT)
+#define GPAR_UCBF       (GPAR_UCBF_MASK   << GFAR_UCBF_SHIFT)
+
+/* Identification Register: IDR0 */
+#define IDR0_NUMSMRG    (IDR0_NUMSMRG_MASK  << IDR0_NUMSMGR_SHIFT)
+#define IDR0_NUMSIDB    (IDR0_NUMSIDB_MASK  << IDR0_NUMSIDB_SHIFT)
+#define IDR0_BTM        (IDR0_BTM_MASK      << IDR0_BTM_SHIFT)
+#define IDR0_CTTW       (IDR0_CTTW_MASK     << IDR0_CTTW_SHIFT)
+#define IDR0_NUMIRPT    (IDR0_NUMIPRT_MASK  << IDR0_NUMIRPT_SHIFT)
+#define IDR0_PTFS       (IDR0_PTFS_MASK     << IDR0_PTFS_SHIFT)
+#define IDR0_SMS        (IDR0_SMS_MASK      << IDR0_SMS_SHIFT)
+#define IDR0_NTS        (IDR0_NTS_MASK      << IDR0_NTS_SHIFT)
+#define IDR0_S2TS       (IDR0_S2TS_MASK     << IDR0_S2TS_SHIFT)
+#define IDR0_S1TS       (IDR0_S1TS_MASK     << IDR0_S1TS_SHIFT)
+#define IDR0_SES        (IDR0_SES_MASK      << IDR0_SES_SHIFT)
+
+/* Identification Register: IDR1 */
+#define IDR1_NUMCB       (IDR1_NUMCB_MASK       << IDR1_NUMCB_SHIFT)
+#define IDR1_NUMSSDNDXB  (IDR1_NUMSSDNDXB_MASK  << IDR1_NUMSSDNDXB_SHIFT)
+#define IDR1_SSDTP       (IDR1_SSDTP_MASK       << IDR1_SSDTP_SHIFT)
+#define IDR1_SMCD        (IDR1_SMCD_MASK        << IDR1_SMCD_SHIFT)
+#define IDR1_NUMS2CB     (IDR1_NUMS2CB_MASK     << IDR1_NUMS2CB_SHIFT)
+#define IDR1_NUMPAGENDXB (IDR1_NUMPAGENDXB_MASK << IDR1_NUMPAGENDXB_SHIFT)
+#define IDR1_PAGESIZE    (IDR1_PAGESIZE_MASK    << IDR1_PAGESIZE_SHIFT)
+
+/* Identification Register: IDR2 */
+#define IDR2_IAS         (IDR2_IAS_MASK << IDR2_IAS_SHIFT)
+#define IDR1_OAS         (IDR2_OAS_MASK << IDR2_OAS_SHIFT)
+
+/* Identification Register: IDR7 */
+#define IDR7_MINOR       (IDR7_MINOR_MASK << IDR7_MINOR_SHIFT)
+#define IDR7_MAJOR       (IDR7_MAJOR_MASK << IDR7_MAJOR_SHIFT)
+
+/* Stream to Context Register: S2CR */
+#define S2CR_CBNDX        (S2CR_CBNDX_MASK         << S2cR_CBNDX_SHIFT)
+#define S2CR_SHCFG        (S2CR_SHCFG_MASK         << s2CR_SHCFG_SHIFT)
+#define S2CR_MTCFG        (S2CR_MTCFG_MASK         << S2CR_MTCFG_SHIFT)
+#define S2CR_MEMATTR      (S2CR_MEMATTR_MASK       << S2CR_MEMATTR_SHIFT)
+#define S2CR_TYPE         (S2CR_TYPE_MASK          << S2CR_TYPE_SHIFT)
+#define S2CR_NSCFG        (S2CR_NSCFG_MASK         << S2CR_NSCFG_SHIFT)
+#define S2CR_RACFG        (S2CR_RACFG_MASK         << S2CR_RACFG_SHIFT)
+#define S2CR_WACFG        (S2CR_WACFG_MASK         << S2CR_WACFG_SHIFT)
+#define S2CR_PRIVCFG      (S2CR_PRIVCFG_MASK       << S2CR_PRIVCFG_SHIFT)
+#define S2CR_INSTCFG      (S2CR_INSTCFG_MASK       << S2CR_INSTCFG_SHIFT)
+#define S2CR_TRANSIENTCFG (S2CR_TRANSIENTCFG_MASK  << S2CR_TRANSIENTCFG_SHIFT)
+#define S2CR_VMID         (S2CR_VMID_MASK          << S2CR_VMID_SHIFT)
+#define S2CR_BSU          (S2CR_BSU_MASK           << S2CR_BSU_SHIFT)
+#define S2CR_FB           (S2CR_FB_MASK            << S2CR_FB_SHIFT)
+
+/* Stream Match Register: SMR */
+#define SMR_ID            (SMR_ID_MASK    << SMR_ID_SHIFT)
+#define SMR_MASK          (SMR_MASK_MASK  << SMR_MASK_SHIFT)
+#define SMR_VALID         (SMR_VALID_MASK << SMR_VALID_SHIFT)
+
+/* Global TLB Status: TLBGSTATUS */
+#define TLBGSTATUS_GSACTIVE (TLBGSTATUS_GSACTIVE_MASK << \
+					TLBGSTATUS_GSACTIVE_SHIFT)
+/* Invalidate Hyp TLB by VA: TLBIVAH */
+#define TLBIVAH_ADDR  (TLBIVAH_ADDR_MASK << TLBIVAH_ADDR_SHIFT)
+
+/* Invalidate TLB by VMID: TLBIVMID */
+#define TLBIVMID_VMID (TLBIVMID_VMID_MASK << TLBIVMID_VMID_SHIFT)
+
+/* Context Bank Attribute Register: CBAR */
+#define CBAR_VMID       (CBAR_VMID_MASK    << CBAR_VMID_SHIFT)
+#define CBAR_CBNDX      (CBAR_CBNDX_MASK   << CBAR_CBNDX_SHIFT)
+#define CBAR_BPSHCFG    (CBAR_BPSHCFG_MASK << CBAR_BPSHCFG_SHIFT)
+#define CBAR_HYPC       (CBAR_HYPC_MASK    << CBAR_HYPC_SHIFT)
+#define CBAR_FB         (CBAR_FB_MASK      << CBAR_FB_SHIFT)
+#define CBAR_MEMATTR    (CBAR_MEMATTR_MASK << CBAR_MEMATTR_SHIFT)
+#define CBAR_TYPE       (CBAR_TYPE_MASK    << CBAR_TYPE_SHIFT)
+#define CBAR_BSU        (CBAR_BSU_MASK     << CBAR_BSU_SHIFT)
+#define CBAR_RACFG      (CBAR_RACFG_MASK   << CBAR_RACFG_SHIFT)
+#define CBAR_WACFG      (CBAR_WACFG_MASK   << CBAR_WACFG_SHIFT)
+#define CBAR_IRPTNDX    (CBAR_IRPTNDX_MASK << CBAR_IRPTNDX_SHIFT)
+
+/* Context Bank Fault Restricted Syndrome Register A: CBFRSYNRA */
+#define CBFRSYNRA_SID   (CBFRSYNRA_SID_MASK << CBFRSYNRA_SID_SHIFT)
+
+/* Performance Monitoring Register Fields */
+
+/* Stage 1 Context Bank Format Fields */
+/* Auxiliary Control Register: CB_ACTLR */
+#define CB_ACTLR_REQPRIORITY \
+		(CB_ACTLR_REQPRIORITY_MASK << CB_ACTLR_REQPRIORITY_SHIFT)
+#define CB_ACTLR_REQPRIORITYCFG \
+		(CB_ACTLR_REQPRIORITYCFG_MASK << CB_ACTLR_REQPRIORITYCFG_SHIFT)
+#define CB_ACTLR_PRIVCFG (CB_ACTLR_PRIVCFG_MASK << CB_ACTLR_PRIVCFG_SHIFT)
+#define CB_ACTLR_BPRCOSH (CB_ACTLR_BPRCOSH_MASK << CB_ACTLR_BPRCOSH_SHIFT)
+#define CB_ACTLR_BPRCISH (CB_ACTLR_BPRCISH_MASK << CB_ACTLR_BPRCISH_SHIFT)
+#define CB_ACTLR_BPRCNSH (CB_ACTLR_BPRCNSH_MASK << CB_ACTLR_BPRCNSH_SHIFT)
+
+/* Address Translation, Stage 1, Privileged Read: CB_ATS1PR */
+#define CB_ATS1PR_ADDR  (CB_ATS1PR_ADDR_MASK << CB_ATS1PR_ADDR_SHIFT)
+
+/* Address Translation, Stage 1, Privileged Write: CB_ATS1PW */
+#define CB_ATS1PW_ADDR  (CB_ATS1PW_ADDR_MASK << CB_ATS1PW_ADDR_SHIFT)
+
+/* Address Translation, Stage 1, User Read: CB_ATS1UR */
+#define CB_ATS1UR_ADDR  (CB_ATS1UR_ADDR_MASK << CB_ATS1UR_ADDR_SHIFT)
+
+/* Address Translation, Stage 1, User Write: CB_ATS1UW */
+#define CB_ATS1UW_ADDR  (CB_ATS1UW_ADDR_MASK << CB_ATS1UW_ADDR_SHIFT)
+
+/* Address Translation Status Register: CB_ATSR */
+#define CB_ATSR_ACTIVE  (CB_ATSR_ACTIVE_MASK << CB_ATSR_ACTIVE_SHIFT)
+
+/* Context ID Register: CB_CONTEXTIDR */
+#define CB_CONTEXTIDR_ASID    (CB_CONTEXTIDR_ASID_MASK << \
+				CB_CONTEXTIDR_ASID_SHIFT)
+#define CB_CONTEXTIDR_PROCID  (CB_CONTEXTIDR_PROCID_MASK << \
+				CB_CONTEXTIDR_PROCID_SHIFT)
+
+/* Fault Address Register: CB_FAR */
+#define CB_FAR_FADDR  (CB_FAR_FADDR_MASK << CB_FAR_FADDR_SHIFT)
+
+/* Fault Status Register: CB_FSR */
+#define CB_FSR_TF     (CB_FSR_TF_MASK     << CB_FSR_TF_SHIFT)
+#define CB_FSR_AFF    (CB_FSR_AFF_MASK    << CB_FSR_AFF_SHIFT)
+#define CB_FSR_PF     (CB_FSR_PF_MASK     << CB_FSR_PF_SHIFT)
+#define CB_FSR_EF     (CB_FSR_EF_MASK     << CB_FSR_EF_SHIFT)
+#define CB_FSR_TLBMCF (CB_FSR_TLBMCF_MASK << CB_FSR_TLBMCF_SHIFT)
+#define CB_FSR_TLBLKF (CB_FSR_TLBLKF_MASK << CB_FSR_TLBLKF_SHIFT)
+#define CB_FSR_SS     (CB_FSR_SS_MASK     << CB_FSR_SS_SHIFT)
+#define CB_FSR_MULTI  (CB_FSR_MULTI_MASK  << CB_FSR_MULTI_SHIFT)
+
+/* Fault Syndrome Register 0: CB_FSYNR0 */
+#define CB_FSYNR0_PLVL     (CB_FSYNR0_PLVL_MASK    << CB_FSYNR0_PLVL_SHIFT)
+#define CB_FSYNR0_S1PTWF   (CB_FSYNR0_S1PTWF_MASK  << CB_FSYNR0_S1PTWF_SHIFT)
+#define CB_FSYNR0_WNR      (CB_FSYNR0_WNR_MASK     << CB_FSYNR0_WNR_SHIFT)
+#define CB_FSYNR0_PNU      (CB_FSYNR0_PNU_MASK     << CB_FSYNR0_PNU_SHIFT)
+#define CB_FSYNR0_IND      (CB_FSYNR0_IND_MASK     << CB_FSYNR0_IND_SHIFT)
+#define CB_FSYNR0_NSSTATE  (CB_FSYNR0_NSSTATE_MASK << CB_FSYNR0_NSSTATE_SHIFT)
+#define CB_FSYNR0_NSATTR   (CB_FSYNR0_NSATTR_MASK  << CB_FSYNR0_NSATTR_SHIFT)
+#define CB_FSYNR0_ATOF     (CB_FSYNR0_ATOF_MASK    << CB_FSYNR0_ATOF_SHIFT)
+#define CB_FSYNR0_PTWF     (CB_FSYNR0_PTWF_MASK    << CB_FSYNR0_PTWF_SHIFT)
+#define CB_FSYNR0_AFR      (CB_FSYNR0_AFR_MASK     << CB_FSYNR0_AFR_SHIFT)
+#define CB_FSYNR0_S1CBNDX  (CB_FSYNR0_S1CBNDX_MASK << CB_FSYNR0_S1CBNDX_SHIFT)
+
+/* Normal Memory Remap Register: CB_NMRR */
+#define CB_NMRR_IR0        (CB_NMRR_IR0_MASK   << CB_NMRR_IR0_SHIFT)
+#define CB_NMRR_IR1        (CB_NMRR_IR1_MASK   << CB_NMRR_IR1_SHIFT)
+#define CB_NMRR_IR2        (CB_NMRR_IR2_MASK   << CB_NMRR_IR2_SHIFT)
+#define CB_NMRR_IR3        (CB_NMRR_IR3_MASK   << CB_NMRR_IR3_SHIFT)
+#define CB_NMRR_IR4        (CB_NMRR_IR4_MASK   << CB_NMRR_IR4_SHIFT)
+#define CB_NMRR_IR5        (CB_NMRR_IR5_MASK   << CB_NMRR_IR5_SHIFT)
+#define CB_NMRR_IR6        (CB_NMRR_IR6_MASK   << CB_NMRR_IR6_SHIFT)
+#define CB_NMRR_IR7        (CB_NMRR_IR7_MASK   << CB_NMRR_IR7_SHIFT)
+#define CB_NMRR_OR0        (CB_NMRR_OR0_MASK   << CB_NMRR_OR0_SHIFT)
+#define CB_NMRR_OR1        (CB_NMRR_OR1_MASK   << CB_NMRR_OR1_SHIFT)
+#define CB_NMRR_OR2        (CB_NMRR_OR2_MASK   << CB_NMRR_OR2_SHIFT)
+#define CB_NMRR_OR3        (CB_NMRR_OR3_MASK   << CB_NMRR_OR3_SHIFT)
+#define CB_NMRR_OR4        (CB_NMRR_OR4_MASK   << CB_NMRR_OR4_SHIFT)
+#define CB_NMRR_OR5        (CB_NMRR_OR5_MASK   << CB_NMRR_OR5_SHIFT)
+#define CB_NMRR_OR6        (CB_NMRR_OR6_MASK   << CB_NMRR_OR6_SHIFT)
+#define CB_NMRR_OR7        (CB_NMRR_OR7_MASK   << CB_NMRR_OR7_SHIFT)
+
+/* Physical Address Register: CB_PAR */
+#define CB_PAR_F           (CB_PAR_F_MASK      << CB_PAR_F_SHIFT)
+#define CB_PAR_SS          (CB_PAR_SS_MASK     << CB_PAR_SS_SHIFT)
+#define CB_PAR_OUTER       (CB_PAR_OUTER_MASK  << CB_PAR_OUTER_SHIFT)
+#define CB_PAR_INNER       (CB_PAR_INNER_MASK  << CB_PAR_INNER_SHIFT)
+#define CB_PAR_SH          (CB_PAR_SH_MASK     << CB_PAR_SH_SHIFT)
+#define CB_PAR_NS          (CB_PAR_NS_MASK     << CB_PAR_NS_SHIFT)
+#define CB_PAR_NOS         (CB_PAR_NOS_MASK    << CB_PAR_NOS_SHIFT)
+#define CB_PAR_PA          (CB_PAR_PA_MASK     << CB_PAR_PA_SHIFT)
+#define CB_PAR_TF          (CB_PAR_TF_MASK     << CB_PAR_TF_SHIFT)
+#define CB_PAR_AFF         (CB_PAR_AFF_MASK    << CB_PAR_AFF_SHIFT)
+#define CB_PAR_PF          (CB_PAR_PF_MASK     << CB_PAR_PF_SHIFT)
+#define CB_PAR_TLBMCF      (CB_PAR_TLBMCF_MASK << CB_PAR_TLBMCF_SHIFT)
+#define CB_PAR_TLBLKF      (CB_PAR_TLBLKF_MASK << CB_PAR_TLBLKF_SHIFT)
+#define CB_PAR_ATOT        (CB_PAR_ATOT_MASK   << CB_PAR_ATOT_SHIFT)
+#define CB_PAR_PLVL        (CB_PAR_PLVL_MASK   << CB_PAR_PLVL_SHIFT)
+#define CB_PAR_STAGE       (CB_PAR_STAGE_MASK  << CB_PAR_STAGE_SHIFT)
+
+/* Primary Region Remap Register: CB_PRRR */
+#define CB_PRRR_TR0        (CB_PRRR_TR0_MASK   << CB_PRRR_TR0_SHIFT)
+#define CB_PRRR_TR1        (CB_PRRR_TR1_MASK   << CB_PRRR_TR1_SHIFT)
+#define CB_PRRR_TR2        (CB_PRRR_TR2_MASK   << CB_PRRR_TR2_SHIFT)
+#define CB_PRRR_TR3        (CB_PRRR_TR3_MASK   << CB_PRRR_TR3_SHIFT)
+#define CB_PRRR_TR4        (CB_PRRR_TR4_MASK   << CB_PRRR_TR4_SHIFT)
+#define CB_PRRR_TR5        (CB_PRRR_TR5_MASK   << CB_PRRR_TR5_SHIFT)
+#define CB_PRRR_TR6        (CB_PRRR_TR6_MASK   << CB_PRRR_TR6_SHIFT)
+#define CB_PRRR_TR7        (CB_PRRR_TR7_MASK   << CB_PRRR_TR7_SHIFT)
+#define CB_PRRR_DS0        (CB_PRRR_DS0_MASK   << CB_PRRR_DS0_SHIFT)
+#define CB_PRRR_DS1        (CB_PRRR_DS1_MASK   << CB_PRRR_DS1_SHIFT)
+#define CB_PRRR_NS0        (CB_PRRR_NS0_MASK   << CB_PRRR_NS0_SHIFT)
+#define CB_PRRR_NS1        (CB_PRRR_NS1_MASK   << CB_PRRR_NS1_SHIFT)
+#define CB_PRRR_NOS0       (CB_PRRR_NOS0_MASK  << CB_PRRR_NOS0_SHIFT)
+#define CB_PRRR_NOS1       (CB_PRRR_NOS1_MASK  << CB_PRRR_NOS1_SHIFT)
+#define CB_PRRR_NOS2       (CB_PRRR_NOS2_MASK  << CB_PRRR_NOS2_SHIFT)
+#define CB_PRRR_NOS3       (CB_PRRR_NOS3_MASK  << CB_PRRR_NOS3_SHIFT)
+#define CB_PRRR_NOS4       (CB_PRRR_NOS4_MASK  << CB_PRRR_NOS4_SHIFT)
+#define CB_PRRR_NOS5       (CB_PRRR_NOS5_MASK  << CB_PRRR_NOS5_SHIFT)
+#define CB_PRRR_NOS6       (CB_PRRR_NOS6_MASK  << CB_PRRR_NOS6_SHIFT)
+#define CB_PRRR_NOS7       (CB_PRRR_NOS7_MASK  << CB_PRRR_NOS7_SHIFT)
+
+/* Transaction Resume: CB_RESUME */
+#define CB_RESUME_TNR      (CB_RESUME_TNR_MASK << CB_RESUME_TNR_SHIFT)
+
+/* System Control Register: CB_SCTLR */
+#define CB_SCTLR_M           (CB_SCTLR_M_MASK       << CB_SCTLR_M_SHIFT)
+#define CB_SCTLR_TRE         (CB_SCTLR_TRE_MASK     << CB_SCTLR_TRE_SHIFT)
+#define CB_SCTLR_AFE         (CB_SCTLR_AFE_MASK     << CB_SCTLR_AFE_SHIFT)
+#define CB_SCTLR_AFFD        (CB_SCTLR_AFFD_MASK    << CB_SCTLR_AFFD_SHIFT)
+#define CB_SCTLR_E           (CB_SCTLR_E_MASK       << CB_SCTLR_E_SHIFT)
+#define CB_SCTLR_CFRE        (CB_SCTLR_CFRE_MASK    << CB_SCTLR_CFRE_SHIFT)
+#define CB_SCTLR_CFIE        (CB_SCTLR_CFIE_MASK    << CB_SCTLR_CFIE_SHIFT)
+#define CB_SCTLR_CFCFG       (CB_SCTLR_CFCFG_MASK   << CB_SCTLR_CFCFG_SHIFT)
+#define CB_SCTLR_HUPCF       (CB_SCTLR_HUPCF_MASK   << CB_SCTLR_HUPCF_SHIFT)
+#define CB_SCTLR_WXN         (CB_SCTLR_WXN_MASK     << CB_SCTLR_WXN_SHIFT)
+#define CB_SCTLR_UWXN        (CB_SCTLR_UWXN_MASK    << CB_SCTLR_UWXN_SHIFT)
+#define CB_SCTLR_ASIDPNE     (CB_SCTLR_ASIDPNE_MASK << CB_SCTLR_ASIDPNE_SHIFT)
+#define CB_SCTLR_TRANSIENTCFG (CB_SCTLR_TRANSIENTCFG_MASK << \
+						CB_SCTLR_TRANSIENTCFG_SHIFT)
+#define CB_SCTLR_MEMATTR     (CB_SCTLR_MEMATTR_MASK << CB_SCTLR_MEMATTR_SHIFT)
+#define CB_SCTLR_MTCFG       (CB_SCTLR_MTCFG_MASK   << CB_SCTLR_MTCFG_SHIFT)
+#define CB_SCTLR_SHCFG       (CB_SCTLR_SHCFG_MASK   << CB_SCTLR_SHCFG_SHIFT)
+#define CB_SCTLR_RACFG       (CB_SCTLR_RACFG_MASK   << CB_SCTLR_RACFG_SHIFT)
+#define CB_SCTLR_WACFG       (CB_SCTLR_WACFG_MASK   << CB_SCTLR_WACFG_SHIFT)
+#define CB_SCTLR_NSCFG       (CB_SCTLR_NSCFG_MASK   << CB_SCTLR_NSCFG_SHIFT)
+
+/* Invalidate TLB by ASID: CB_TLBIASID */
+#define CB_TLBIASID_ASID     (CB_TLBIASID_ASID_MASK << CB_TLBIASID_ASID_SHIFT)
+
+/* Invalidate TLB by VA: CB_TLBIVA */
+#define CB_TLBIVA_ASID       (CB_TLBIVA_ASID_MASK   << CB_TLBIVA_ASID_SHIFT)
+#define CB_TLBIVA_VA         (CB_TLBIVA_VA_MASK     << CB_TLBIVA_VA_SHIFT)
+
+/* Invalidate TLB by VA, All ASID: CB_TLBIVAA */
+#define CB_TLBIVAA_VA        (CB_TLBIVAA_VA_MASK    << CB_TLBIVAA_VA_SHIFT)
+
+/* Invalidate TLB by VA, All ASID, Last Level: CB_TLBIVAAL */
+#define CB_TLBIVAAL_VA       (CB_TLBIVAAL_VA_MASK   << CB_TLBIVAAL_VA_SHIFT)
+
+/* Invalidate TLB by VA, Last Level: CB_TLBIVAL */
+#define CB_TLBIVAL_ASID      (CB_TLBIVAL_ASID_MASK  << CB_TLBIVAL_ASID_SHIFT)
+#define CB_TLBIVAL_VA        (CB_TLBIVAL_VA_MASK    << CB_TLBIVAL_VA_SHIFT)
+
+/* TLB Status: CB_TLBSTATUS */
+#define CB_TLBSTATUS_SACTIVE (CB_TLBSTATUS_SACTIVE_MASK << \
+						CB_TLBSTATUS_SACTIVE_SHIFT)
+
+/* Translation Table Base Control Register: CB_TTBCR */
+#define CB_TTBCR_T0SZ        (CB_TTBCR_T0SZ_MASK    << CB_TTBCR_T0SZ_SHIFT)
+#define CB_TTBCR_PD0         (CB_TTBCR_PD0_MASK     << CB_TTBCR_PD0_SHIFT)
+#define CB_TTBCR_PD1         (CB_TTBCR_PD1_MASK     << CB_TTBCR_PD1_SHIFT)
+#define CB_TTBCR_NSCFG0      (CB_TTBCR_NSCFG0_MASK  << CB_TTBCR_NSCFG0_SHIFT)
+#define CB_TTBCR_NSCFG1      (CB_TTBCR_NSCFG1_MASK  << CB_TTBCR_NSCFG1_SHIFT)
+#define CB_TTBCR_EAE         (CB_TTBCR_EAE_MASK     << CB_TTBCR_EAE_SHIFT)
+
+/* Translation Table Base Register 0: CB_TTBR0 */
+#define CB_TTBR0_IRGN1       (CB_TTBR0_IRGN1_MASK   << CB_TTBR0_IRGN1_SHIFT)
+#define CB_TTBR0_S           (CB_TTBR0_S_MASK       << CB_TTBR0_S_SHIFT)
+#define CB_TTBR0_RGN         (CB_TTBR0_RGN_MASK     << CB_TTBR0_RGN_SHIFT)
+#define CB_TTBR0_NOS         (CB_TTBR0_NOS_MASK     << CB_TTBR0_NOS_SHIFT)
+#define CB_TTBR0_IRGN0       (CB_TTBR0_IRGN0_MASK   << CB_TTBR0_IRGN0_SHIFT)
+#define CB_TTBR0_ADDR        (CB_TTBR0_ADDR_MASK    << CB_TTBR0_ADDR_SHIFT)
+
+/* Translation Table Base Register 1: CB_TTBR1 */
+#define CB_TTBR1_IRGN1       (CB_TTBR1_IRGN1_MASK   << CB_TTBR1_IRGN1_SHIFT)
+#define CB_TTBR1_S           (CB_TTBR1_S_MASK       << CB_TTBR1_S_SHIFT)
+#define CB_TTBR1_RGN         (CB_TTBR1_RGN_MASK     << CB_TTBR1_RGN_SHIFT)
+#define CB_TTBR1_NOS         (CB_TTBR1_NOS_MASK     << CB_TTBR1_NOS_SHIFT)
+#define CB_TTBR1_IRGN0       (CB_TTBR1_IRGN0_MASK   << CB_TTBR1_IRGN0_SHIFT)
+#define CB_TTBR1_ADDR        (CB_TTBR1_ADDR_MASK    << CB_TTBR1_ADDR_SHIFT)
+
+/* Global Register Masks */
+/* Configuration Register 0 */
+#define CR0_NSCFG_MASK          0x03
+#define CR0_WACFG_MASK          0x03
+#define CR0_RACFG_MASK          0x03
+#define CR0_SHCFG_MASK          0x03
+#define CR0_SMCFCFG_MASK        0x01
+#define CR0_MTCFG_MASK          0x01
+#define CR0_MEMATTR_MASK        0x0F
+#define CR0_BSU_MASK            0x03
+#define CR0_FB_MASK             0x01
+#define CR0_PTM_MASK            0x01
+#define CR0_VMIDPNE_MASK        0x01
+#define CR0_USFCFG_MASK         0x01
+#define CR0_GSE_MASK            0x01
+#define CR0_STALLD_MASK         0x01
+#define CR0_TRANSIENTCFG_MASK   0x03
+#define CR0_GCFGFIE_MASK        0x01
+#define CR0_GCFGFRE_MASK        0x01
+#define CR0_GFIE_MASK           0x01
+#define CR0_GFRE_MASK           0x01
+#define CR0_CLIENTPD_MASK       0x01
+
+/* Configuration Register 2 */
+#define CR2_BPVMID_MASK         0xFF
+
+/* Global Address Translation, Stage 1, Privileged Read: GATS1PR */
+#define GATS1PR_ADDR_MASK       0xFFFFF
+#define GATS1PR_NDX_MASK        0xFF
+
+/* Global Address Translation, Stage 1, Privileged Write: GATS1PW */
+#define GATS1PW_ADDR_MASK       0xFFFFF
+#define GATS1PW_NDX_MASK        0xFF
+
+/* Global Address Translation, Stage 1, User Read: GATS1UR */
+#define GATS1UR_ADDR_MASK       0xFFFFF
+#define GATS1UR_NDX_MASK        0xFF
+
+/* Global Address Translation, Stage 1, User Write: GATS1UW */
+#define GATS1UW_ADDR_MASK       0xFFFFF
+#define GATS1UW_NDX_MASK        0xFF
+
+/* Global Address Translation, Stage 1 and 2, Privileged Read: GATS1PR */
+#define GATS12PR_ADDR_MASK      0xFFFFF
+#define GATS12PR_NDX_MASK       0xFF
+
+/* Global Address Translation, Stage 1 and 2, Privileged Write: GATS1PW */
+#define GATS12PW_ADDR_MASK      0xFFFFF
+#define GATS12PW_NDX_MASK       0xFF
+
+/* Global Address Translation, Stage 1 and 2, User Read: GATS1UR */
+#define GATS12UR_ADDR_MASK      0xFFFFF
+#define GATS12UR_NDX_MASK       0xFF
+
+/* Global Address Translation, Stage 1 and 2, User Write: GATS1UW */
+#define GATS12UW_ADDR_MASK      0xFFFFF
+#define GATS12UW_NDX_MASK       0xFF
+
+/* Global Address Translation Status Register: GATSR */
+#define GATSR_ACTIVE_MASK       0x01
+
+/* Global Fault Address Register: GFAR */
+#define GFAR_FADDR_MASK         0xFFFFFFFF
+
+/* Global Fault Status Register: GFSR */
+#define GFSR_ICF_MASK           0x01
+#define GFSR_USF_MASK           0x01
+#define GFSR_SMCF_MASK          0x01
+#define GFSR_UCBF_MASK          0x01
+#define GFSR_UCIF_MASK          0x01
+#define GFSR_CAF_MASK           0x01
+#define GFSR_EF_MASK            0x01
+#define GFSR_PF_MASK            0x01
+#define GFSR_MULTI_MASK         0x01
+
+/* Global Fault Syndrome Register 0: GFSYNR0 */
+#define GFSYNR0_NESTED_MASK     0x01
+#define GFSYNR0_WNR_MASK        0x01
+#define GFSYNR0_PNU_MASK        0x01
+#define GFSYNR0_IND_MASK        0x01
+#define GFSYNR0_NSSTATE_MASK    0x01
+#define GFSYNR0_NSATTR_MASK     0x01
+
+/* Global Fault Syndrome Register 1: GFSYNR1 */
+#define GFSYNR1_SID_MASK        0x7FFF
+#define GFSYNr1_SSD_IDX_MASK    0x7FFF
+
+/* Global Physical Address Register: GPAR */
+#define GPAR_F_MASK             0x01
+#define GPAR_SS_MASK            0x01
+#define GPAR_OUTER_MASK         0x03
+#define GPAR_INNER_MASK         0x03
+#define GPAR_SH_MASK            0x01
+#define GPAR_NS_MASK            0x01
+#define GPAR_NOS_MASK           0x01
+#define GPAR_PA_MASK            0xFFFFF
+#define GPAR_TF_MASK            0x01
+#define GPAR_AFF_MASK           0x01
+#define GPAR_PF_MASK            0x01
+#define GPAR_EF_MASK            0x01
+#define GPAR_TLBMCF_MASK        0x01
+#define GPAR_TLBLKF_MASK        0x01
+#define GPAR_UCBF_MASK          0x01
+
+/* Identification Register: IDR0 */
+#define IDR0_NUMSMRG_MASK       0xFF
+#define IDR0_NUMSIDB_MASK       0x0F
+#define IDR0_BTM_MASK           0x01
+#define IDR0_CTTW_MASK          0x01
+#define IDR0_NUMIPRT_MASK       0xFF
+#define IDR0_PTFS_MASK          0x01
+#define IDR0_SMS_MASK           0x01
+#define IDR0_NTS_MASK           0x01
+#define IDR0_S2TS_MASK          0x01
+#define IDR0_S1TS_MASK          0x01
+#define IDR0_SES_MASK           0x01
+
+/* Identification Register: IDR1 */
+#define IDR1_NUMCB_MASK         0xFF
+#define IDR1_NUMSSDNDXB_MASK    0x0F
+#define IDR1_SSDTP_MASK         0x01
+#define IDR1_SMCD_MASK          0x01
+#define IDR1_NUMS2CB_MASK       0xFF
+#define IDR1_NUMPAGENDXB_MASK   0x07
+#define IDR1_PAGESIZE_MASK      0x01
+
+/* Identification Register: IDR2 */
+#define IDR2_IAS_MASK           0x0F
+#define IDR2_OAS_MASK           0x0F
+
+/* Identification Register: IDR7 */
+#define IDR7_MINOR_MASK         0x0F
+#define IDR7_MAJOR_MASK         0x0F
+
+/* Stream to Context Register: S2CR */
+#define S2CR_CBNDX_MASK         0xFF
+#define S2CR_SHCFG_MASK         0x03
+#define S2CR_MTCFG_MASK         0x01
+#define S2CR_MEMATTR_MASK       0x0F
+#define S2CR_TYPE_MASK          0x03
+#define S2CR_NSCFG_MASK         0x03
+#define S2CR_RACFG_MASK         0x03
+#define S2CR_WACFG_MASK         0x03
+#define S2CR_PRIVCFG_MASK       0x03
+#define S2CR_INSTCFG_MASK       0x03
+#define S2CR_TRANSIENTCFG_MASK  0x03
+#define S2CR_VMID_MASK          0xFF
+#define S2CR_BSU_MASK           0x03
+#define S2CR_FB_MASK            0x01
+
+/* Stream Match Register: SMR */
+#define SMR_ID_MASK             0x7FFF
+#define SMR_MASK_MASK           0x7FFF
+#define SMR_VALID_MASK          0x01
+
+/* Global TLB Status: TLBGSTATUS */
+#define TLBGSTATUS_GSACTIVE_MASK 0x01
+
+/* Invalidate Hyp TLB by VA: TLBIVAH */
+#define TLBIVAH_ADDR_MASK       0xFFFFF
+
+/* Invalidate TLB by VMID: TLBIVMID */
+#define TLBIVMID_VMID_MASK      0xFF
+
+/* Global Register Space 1 Mask */
+/* Context Bank Attribute Register: CBAR */
+#define CBAR_VMID_MASK          0xFF
+#define CBAR_CBNDX_MASK         0x03
+#define CBAR_BPSHCFG_MASK       0x03
+#define CBAR_HYPC_MASK          0x01
+#define CBAR_FB_MASK            0x01
+#define CBAR_MEMATTR_MASK       0x0F
+#define CBAR_TYPE_MASK          0x03
+#define CBAR_BSU_MASK           0x03
+#define CBAR_RACFG_MASK         0x03
+#define CBAR_WACFG_MASK         0x03
+#define CBAR_IRPTNDX_MASK       0xFF
+
+/* Context Bank Fault Restricted Syndrome Register A: CBFRSYNRA */
+#define CBFRSYNRA_SID_MASK      0x7FFF
+
+/* Implementation defined register space masks */
+#define MICRO_MMU_CTRL_HALT_REQ_MASK          0x01
+#define MICRO_MMU_CTRL_IDLE_MASK              0x01
+
+/* Stage 1 Context Bank Format Masks */
+/* Auxiliary Control Register: CB_ACTLR */
+#define CB_ACTLR_REQPRIORITY_MASK    0x3
+#define CB_ACTLR_REQPRIORITYCFG_MASK 0x1
+#define CB_ACTLR_PRIVCFG_MASK        0x3
+#define CB_ACTLR_BPRCOSH_MASK        0x1
+#define CB_ACTLR_BPRCISH_MASK        0x1
+#define CB_ACTLR_BPRCNSH_MASK        0x1
+
+/* Address Translation, Stage 1, Privileged Read: CB_ATS1PR */
+#define CB_ATS1PR_ADDR_MASK     0xFFFFF
+
+/* Address Translation, Stage 1, Privileged Write: CB_ATS1PW */
+#define CB_ATS1PW_ADDR_MASK     0xFFFFF
+
+/* Address Translation, Stage 1, User Read: CB_ATS1UR */
+#define CB_ATS1UR_ADDR_MASK     0xFFFFF
+
+/* Address Translation, Stage 1, User Write: CB_ATS1UW */
+#define CB_ATS1UW_ADDR_MASK     0xFFFFF
+
+/* Address Translation Status Register: CB_ATSR */
+#define CB_ATSR_ACTIVE_MASK     0x01
+
+/* Context ID Register: CB_CONTEXTIDR */
+#define CB_CONTEXTIDR_ASID_MASK   0xFF
+#define CB_CONTEXTIDR_PROCID_MASK 0xFFFFFF
+
+/* Fault Address Register: CB_FAR */
+#define CB_FAR_FADDR_MASK       0xFFFFFFFF
+
+/* Fault Status Register: CB_FSR */
+#define CB_FSR_TF_MASK          0x01
+#define CB_FSR_AFF_MASK         0x01
+#define CB_FSR_PF_MASK          0x01
+#define CB_FSR_EF_MASK          0x01
+#define CB_FSR_TLBMCF_MASK      0x01
+#define CB_FSR_TLBLKF_MASK      0x01
+#define CB_FSR_SS_MASK          0x01
+#define CB_FSR_MULTI_MASK       0x01
+
+/* Fault Syndrome Register 0: CB_FSYNR0 */
+#define CB_FSYNR0_PLVL_MASK     0x03
+#define CB_FSYNR0_S1PTWF_MASK   0x01
+#define CB_FSYNR0_WNR_MASK      0x01
+#define CB_FSYNR0_PNU_MASK      0x01
+#define CB_FSYNR0_IND_MASK      0x01
+#define CB_FSYNR0_NSSTATE_MASK  0x01
+#define CB_FSYNR0_NSATTR_MASK   0x01
+#define CB_FSYNR0_ATOF_MASK     0x01
+#define CB_FSYNR0_PTWF_MASK     0x01
+#define CB_FSYNR0_AFR_MASK      0x01
+#define CB_FSYNR0_S1CBNDX_MASK  0xFF
+
+/* Normal Memory Remap Register: CB_NMRR */
+#define CB_NMRR_IR0_MASK        0x03
+#define CB_NMRR_IR1_MASK        0x03
+#define CB_NMRR_IR2_MASK        0x03
+#define CB_NMRR_IR3_MASK        0x03
+#define CB_NMRR_IR4_MASK        0x03
+#define CB_NMRR_IR5_MASK        0x03
+#define CB_NMRR_IR6_MASK        0x03
+#define CB_NMRR_IR7_MASK        0x03
+#define CB_NMRR_OR0_MASK        0x03
+#define CB_NMRR_OR1_MASK        0x03
+#define CB_NMRR_OR2_MASK        0x03
+#define CB_NMRR_OR3_MASK        0x03
+#define CB_NMRR_OR4_MASK        0x03
+#define CB_NMRR_OR5_MASK        0x03
+#define CB_NMRR_OR6_MASK        0x03
+#define CB_NMRR_OR7_MASK        0x03
+
+/* Physical Address Register: CB_PAR */
+#define CB_PAR_F_MASK           0x01
+#define CB_PAR_SS_MASK          0x01
+#define CB_PAR_OUTER_MASK       0x03
+#define CB_PAR_INNER_MASK       0x07
+#define CB_PAR_SH_MASK          0x01
+#define CB_PAR_NS_MASK          0x01
+#define CB_PAR_NOS_MASK         0x01
+#define CB_PAR_PA_MASK          0xFFFFF
+#define CB_PAR_TF_MASK          0x01
+#define CB_PAR_AFF_MASK         0x01
+#define CB_PAR_PF_MASK          0x01
+#define CB_PAR_TLBMCF_MASK      0x01
+#define CB_PAR_TLBLKF_MASK      0x01
+#define CB_PAR_ATOT_MASK        0x01
+#define CB_PAR_PLVL_MASK        0x03
+#define CB_PAR_STAGE_MASK       0x01
+
+/* Primary Region Remap Register: CB_PRRR */
+#define CB_PRRR_TR0_MASK        0x03
+#define CB_PRRR_TR1_MASK        0x03
+#define CB_PRRR_TR2_MASK        0x03
+#define CB_PRRR_TR3_MASK        0x03
+#define CB_PRRR_TR4_MASK        0x03
+#define CB_PRRR_TR5_MASK        0x03
+#define CB_PRRR_TR6_MASK        0x03
+#define CB_PRRR_TR7_MASK        0x03
+#define CB_PRRR_DS0_MASK        0x01
+#define CB_PRRR_DS1_MASK        0x01
+#define CB_PRRR_NS0_MASK        0x01
+#define CB_PRRR_NS1_MASK        0x01
+#define CB_PRRR_NOS0_MASK       0x01
+#define CB_PRRR_NOS1_MASK       0x01
+#define CB_PRRR_NOS2_MASK       0x01
+#define CB_PRRR_NOS3_MASK       0x01
+#define CB_PRRR_NOS4_MASK       0x01
+#define CB_PRRR_NOS5_MASK       0x01
+#define CB_PRRR_NOS6_MASK       0x01
+#define CB_PRRR_NOS7_MASK       0x01
+
+/* Transaction Resume: CB_RESUME */
+#define CB_RESUME_TNR_MASK      0x01
+
+/* System Control Register: CB_SCTLR */
+#define CB_SCTLR_M_MASK            0x01
+#define CB_SCTLR_TRE_MASK          0x01
+#define CB_SCTLR_AFE_MASK          0x01
+#define CB_SCTLR_AFFD_MASK         0x01
+#define CB_SCTLR_E_MASK            0x01
+#define CB_SCTLR_CFRE_MASK         0x01
+#define CB_SCTLR_CFIE_MASK         0x01
+#define CB_SCTLR_CFCFG_MASK        0x01
+#define CB_SCTLR_HUPCF_MASK        0x01
+#define CB_SCTLR_WXN_MASK          0x01
+#define CB_SCTLR_UWXN_MASK         0x01
+#define CB_SCTLR_ASIDPNE_MASK      0x01
+#define CB_SCTLR_TRANSIENTCFG_MASK 0x03
+#define CB_SCTLR_MEMATTR_MASK      0x0F
+#define CB_SCTLR_MTCFG_MASK        0x01
+#define CB_SCTLR_SHCFG_MASK        0x03
+#define CB_SCTLR_RACFG_MASK        0x03
+#define CB_SCTLR_WACFG_MASK        0x03
+#define CB_SCTLR_NSCFG_MASK        0x03
+
+/* Invalidate TLB by ASID: CB_TLBIASID */
+#define CB_TLBIASID_ASID_MASK      0xFF
+
+/* Invalidate TLB by VA: CB_TLBIVA */
+#define CB_TLBIVA_ASID_MASK        0xFF
+#define CB_TLBIVA_VA_MASK          0xFFFFF
+
+/* Invalidate TLB by VA, All ASID: CB_TLBIVAA */
+#define CB_TLBIVAA_VA_MASK         0xFFFFF
+
+/* Invalidate TLB by VA, All ASID, Last Level: CB_TLBIVAAL */
+#define CB_TLBIVAAL_VA_MASK        0xFFFFF
+
+/* Invalidate TLB by VA, Last Level: CB_TLBIVAL */
+#define CB_TLBIVAL_ASID_MASK       0xFF
+#define CB_TLBIVAL_VA_MASK         0xFFFFF
+
+/* TLB Status: CB_TLBSTATUS */
+#define CB_TLBSTATUS_SACTIVE_MASK  0x01
+
+/* Translation Table Base Control Register: CB_TTBCR */
+#define CB_TTBCR_T0SZ_MASK         0x07
+#define CB_TTBCR_PD0_MASK          0x01
+#define CB_TTBCR_PD1_MASK          0x01
+#define CB_TTBCR_NSCFG0_MASK       0x01
+#define CB_TTBCR_NSCFG1_MASK       0x01
+#define CB_TTBCR_EAE_MASK          0x01
+
+/* Translation Table Base Register 0/1: CB_TTBR */
+#define CB_TTBR0_IRGN1_MASK        0x01
+#define CB_TTBR0_S_MASK            0x01
+#define CB_TTBR0_RGN_MASK          0x01
+#define CB_TTBR0_NOS_MASK          0x01
+#define CB_TTBR0_IRGN0_MASK        0x01
+#define CB_TTBR0_ADDR_MASK         0xFFFFFF
+
+#define CB_TTBR1_IRGN1_MASK        0x1
+#define CB_TTBR1_S_MASK            0x1
+#define CB_TTBR1_RGN_MASK          0x1
+#define CB_TTBR1_NOS_MASK          0X1
+#define CB_TTBR1_IRGN0_MASK        0X1
+#define CB_TTBR1_ADDR_MASK         0xFFFFFF
+
+/* Global Register Shifts */
+/* Configuration Register: CR0 */
+#define CR0_NSCFG_SHIFT            28
+#define CR0_WACFG_SHIFT            26
+#define CR0_RACFG_SHIFT            24
+#define CR0_SHCFG_SHIFT            22
+#define CR0_SMCFCFG_SHIFT          21
+#define CR0_MTCFG_SHIFT            20
+#define CR0_MEMATTR_SHIFT          16
+#define CR0_BSU_SHIFT              14
+#define CR0_FB_SHIFT               13
+#define CR0_PTM_SHIFT              12
+#define CR0_VMIDPNE_SHIFT          11
+#define CR0_USFCFG_SHIFT           10
+#define CR0_GSE_SHIFT              9
+#define CR0_STALLD_SHIFT           8
+#define CR0_TRANSIENTCFG_SHIFT     6
+#define CR0_GCFGFIE_SHIFT          5
+#define CR0_GCFGFRE_SHIFT          4
+#define CR0_GFIE_SHIFT             2
+#define CR0_GFRE_SHIFT             1
+#define CR0_CLIENTPD_SHIFT         0
+
+/* Configuration Register: CR2 */
+#define CR2_BPVMID_SHIFT           0
+
+/* Global Address Translation, Stage 1, Privileged Read: GATS1PR */
+#define GATS1PR_ADDR_SHIFT         12
+#define GATS1PR_NDX_SHIFT          0
+
+/* Global Address Translation, Stage 1, Privileged Write: GATS1PW */
+#define GATS1PW_ADDR_SHIFT         12
+#define GATS1PW_NDX_SHIFT          0
+
+/* Global Address Translation, Stage 1, User Read: GATS1UR */
+#define GATS1UR_ADDR_SHIFT         12
+#define GATS1UR_NDX_SHIFT          0
+
+/* Global Address Translation, Stage 1, User Write: GATS1UW */
+#define GATS1UW_ADDR_SHIFT         12
+#define GATS1UW_NDX_SHIFT          0
+
+/* Global Address Translation, Stage 1 and 2, Privileged Read: GATS12PR */
+#define GATS12PR_ADDR_SHIFT        12
+#define GATS12PR_NDX_SHIFT         0
+
+/* Global Address Translation, Stage 1 and 2, Privileged Write: GATS12PW */
+#define GATS12PW_ADDR_SHIFT        12
+#define GATS12PW_NDX_SHIFT         0
+
+/* Global Address Translation, Stage 1 and 2, User Read: GATS12UR */
+#define GATS12UR_ADDR_SHIFT        12
+#define GATS12UR_NDX_SHIFT         0
+
+/* Global Address Translation, Stage 1 and 2, User Write: GATS12UW */
+#define GATS12UW_ADDR_SHIFT        12
+#define GATS12UW_NDX_SHIFT         0
+
+/* Global Address Translation Status Register: GATSR */
+#define GATSR_ACTIVE_SHIFT         0
+
+/* Global Fault Address Register: GFAR */
+#define GFAR_FADDR_SHIFT           0
+
+/* Global Fault Status Register: GFSR */
+#define GFSR_ICF_SHIFT             0
+#define GFSR_USF_SHIFT             1
+#define GFSR_SMCF_SHIFT            2
+#define GFSR_UCBF_SHIFT            3
+#define GFSR_UCIF_SHIFT            4
+#define GFSR_CAF_SHIFT             5
+#define GFSR_EF_SHIFT              6
+#define GFSR_PF_SHIFT              7
+#define GFSR_MULTI_SHIFT           31
+
+/* Global Fault Syndrome Register 0: GFSYNR0 */
+#define GFSYNR0_NESTED_SHIFT       0
+#define GFSYNR0_WNR_SHIFT          1
+#define GFSYNR0_PNU_SHIFT          2
+#define GFSYNR0_IND_SHIFT          3
+#define GFSYNR0_NSSTATE_SHIFT      4
+#define GFSYNR0_NSATTR_SHIFT       5
+
+/* Global Fault Syndrome Register 1: GFSYNR1 */
+#define GFSYNR1_SID_SHIFT          0
+
+/* Global Physical Address Register: GPAR */
+#define GPAR_F_SHIFT               0
+#define GPAR_SS_SHIFT              1
+#define GPAR_OUTER_SHIFT           2
+#define GPAR_INNER_SHIFT           4
+#define GPAR_SH_SHIFT              7
+#define GPAR_NS_SHIFT              9
+#define GPAR_NOS_SHIFT             10
+#define GPAR_PA_SHIFT              12
+#define GPAR_TF_SHIFT              1
+#define GPAR_AFF_SHIFT             2
+#define GPAR_PF_SHIFT              3
+#define GPAR_EF_SHIFT              4
+#define GPAR_TLCMCF_SHIFT          5
+#define GPAR_TLBLKF_SHIFT          6
+#define GFAR_UCBF_SHIFT            30
+
+/* Identification Register: IDR0 */
+#define IDR0_NUMSMRG_SHIFT         0
+#define IDR0_NUMSIDB_SHIFT         9
+#define IDR0_BTM_SHIFT             13
+#define IDR0_CTTW_SHIFT            14
+#define IDR0_NUMIRPT_SHIFT         16
+#define IDR0_PTFS_SHIFT            24
+#define IDR0_SMS_SHIFT             27
+#define IDR0_NTS_SHIFT             28
+#define IDR0_S2TS_SHIFT            29
+#define IDR0_S1TS_SHIFT            30
+#define IDR0_SES_SHIFT             31
+
+/* Identification Register: IDR1 */
+#define IDR1_NUMCB_SHIFT           0
+#define IDR1_NUMSSDNDXB_SHIFT      8
+#define IDR1_SSDTP_SHIFT           12
+#define IDR1_SMCD_SHIFT            15
+#define IDR1_NUMS2CB_SHIFT         16
+#define IDR1_NUMPAGENDXB_SHIFT     28
+#define IDR1_PAGESIZE_SHIFT        31
+
+/* Identification Register: IDR2 */
+#define IDR2_IAS_SHIFT             0
+#define IDR2_OAS_SHIFT             4
+
+/* Identification Register: IDR7 */
+#define IDR7_MINOR_SHIFT           0
+#define IDR7_MAJOR_SHIFT           4
+
+/* Stream to Context Register: S2CR */
+#define S2CR_CBNDX_SHIFT           0
+#define s2CR_SHCFG_SHIFT           8
+#define S2CR_MTCFG_SHIFT           11
+#define S2CR_MEMATTR_SHIFT         12
+#define S2CR_TYPE_SHIFT            16
+#define S2CR_NSCFG_SHIFT           18
+#define S2CR_RACFG_SHIFT           20
+#define S2CR_WACFG_SHIFT           22
+#define S2CR_PRIVCFG_SHIFT         24
+#define S2CR_INSTCFG_SHIFT         26
+#define S2CR_TRANSIENTCFG_SHIFT    28
+#define S2CR_VMID_SHIFT            0
+#define S2CR_BSU_SHIFT             24
+#define S2CR_FB_SHIFT              26
+
+/* Stream Match Register: SMR */
+#define SMR_ID_SHIFT               0
+#define SMR_MASK_SHIFT             16
+#define SMR_VALID_SHIFT            31
+
+/* Global TLB Status: TLBGSTATUS */
+#define TLBGSTATUS_GSACTIVE_SHIFT  0
+
+/* Invalidate Hyp TLB by VA: TLBIVAH */
+#define TLBIVAH_ADDR_SHIFT         12
+
+/* Invalidate TLB by VMID: TLBIVMID */
+#define TLBIVMID_VMID_SHIFT        0
+
+/* Context Bank Attribute Register: CBAR */
+#define CBAR_VMID_SHIFT            0
+#define CBAR_CBNDX_SHIFT           8
+#define CBAR_BPSHCFG_SHIFT         8
+#define CBAR_HYPC_SHIFT            10
+#define CBAR_FB_SHIFT              11
+#define CBAR_MEMATTR_SHIFT         12
+#define CBAR_TYPE_SHIFT            16
+#define CBAR_BSU_SHIFT             18
+#define CBAR_RACFG_SHIFT           20
+#define CBAR_WACFG_SHIFT           22
+#define CBAR_IRPTNDX_SHIFT         24
+
+/* Context Bank Fault Restricted Syndrome Register A: CBFRSYNRA */
+#define CBFRSYNRA_SID_SHIFT        0
+
+/* Implementation defined register space shift */
+#define MICRO_MMU_CTRL_HALT_REQ_SHIFT         0x02
+#define MICRO_MMU_CTRL_IDLE_SHIFT             0x03
+
+/* Stage 1 Context Bank Format Shifts */
+/* Auxiliary Control Register: CB_ACTLR */
+#define CB_ACTLR_REQPRIORITY_SHIFT     0
+#define CB_ACTLR_REQPRIORITYCFG_SHIFT  4
+#define CB_ACTLR_PRIVCFG_SHIFT         8
+#define CB_ACTLR_BPRCOSH_SHIFT         28
+#define CB_ACTLR_BPRCISH_SHIFT         29
+#define CB_ACTLR_BPRCNSH_SHIFT         30
+
+/* Address Translation, Stage 1, Privileged Read: CB_ATS1PR */
+#define CB_ATS1PR_ADDR_SHIFT       12
+
+/* Address Translation, Stage 1, Privileged Write: CB_ATS1PW */
+#define CB_ATS1PW_ADDR_SHIFT       12
+
+/* Address Translation, Stage 1, User Read: CB_ATS1UR */
+#define CB_ATS1UR_ADDR_SHIFT       12
+
+/* Address Translation, Stage 1, User Write: CB_ATS1UW */
+#define CB_ATS1UW_ADDR_SHIFT       12
+
+/* Address Translation Status Register: CB_ATSR */
+#define CB_ATSR_ACTIVE_SHIFT       0
+
+/* Context ID Register: CB_CONTEXTIDR */
+#define CB_CONTEXTIDR_ASID_SHIFT   0
+#define CB_CONTEXTIDR_PROCID_SHIFT 8
+
+/* Fault Address Register: CB_FAR */
+#define CB_FAR_FADDR_SHIFT         0
+
+/* Fault Status Register: CB_FSR */
+#define CB_FSR_TF_SHIFT            1
+#define CB_FSR_AFF_SHIFT           2
+#define CB_FSR_PF_SHIFT            3
+#define CB_FSR_EF_SHIFT            4
+#define CB_FSR_TLBMCF_SHIFT        5
+#define CB_FSR_TLBLKF_SHIFT        6
+#define CB_FSR_SS_SHIFT            30
+#define CB_FSR_MULTI_SHIFT         31
+
+/* Fault Syndrome Register 0: CB_FSYNR0 */
+#define CB_FSYNR0_PLVL_SHIFT       0
+#define CB_FSYNR0_S1PTWF_SHIFT     3
+#define CB_FSYNR0_WNR_SHIFT        4
+#define CB_FSYNR0_PNU_SHIFT        5
+#define CB_FSYNR0_IND_SHIFT        6
+#define CB_FSYNR0_NSSTATE_SHIFT    7
+#define CB_FSYNR0_NSATTR_SHIFT     8
+#define CB_FSYNR0_ATOF_SHIFT       9
+#define CB_FSYNR0_PTWF_SHIFT       10
+#define CB_FSYNR0_AFR_SHIFT        11
+#define CB_FSYNR0_S1CBNDX_SHIFT    16
+
+/* Normal Memory Remap Register: CB_NMRR */
+#define CB_NMRR_IR0_SHIFT          0
+#define CB_NMRR_IR1_SHIFT          2
+#define CB_NMRR_IR2_SHIFT          4
+#define CB_NMRR_IR3_SHIFT          6
+#define CB_NMRR_IR4_SHIFT          8
+#define CB_NMRR_IR5_SHIFT          10
+#define CB_NMRR_IR6_SHIFT          12
+#define CB_NMRR_IR7_SHIFT          14
+#define CB_NMRR_OR0_SHIFT          16
+#define CB_NMRR_OR1_SHIFT          18
+#define CB_NMRR_OR2_SHIFT          20
+#define CB_NMRR_OR3_SHIFT          22
+#define CB_NMRR_OR4_SHIFT          24
+#define CB_NMRR_OR5_SHIFT          26
+#define CB_NMRR_OR6_SHIFT          28
+#define CB_NMRR_OR7_SHIFT          30
+
+/* Physical Address Register: CB_PAR */
+#define CB_PAR_F_SHIFT             0
+#define CB_PAR_SS_SHIFT            1
+#define CB_PAR_OUTER_SHIFT         2
+#define CB_PAR_INNER_SHIFT         4
+#define CB_PAR_SH_SHIFT            7
+#define CB_PAR_NS_SHIFT            9
+#define CB_PAR_NOS_SHIFT           10
+#define CB_PAR_PA_SHIFT            12
+#define CB_PAR_TF_SHIFT            1
+#define CB_PAR_AFF_SHIFT           2
+#define CB_PAR_PF_SHIFT            3
+#define CB_PAR_TLBMCF_SHIFT        5
+#define CB_PAR_TLBLKF_SHIFT        6
+#define CB_PAR_ATOT_SHIFT          31
+#define CB_PAR_PLVL_SHIFT          0
+#define CB_PAR_STAGE_SHIFT         3
+
+/* Primary Region Remap Register: CB_PRRR */
+#define CB_PRRR_TR0_SHIFT          0
+#define CB_PRRR_TR1_SHIFT          2
+#define CB_PRRR_TR2_SHIFT          4
+#define CB_PRRR_TR3_SHIFT          6
+#define CB_PRRR_TR4_SHIFT          8
+#define CB_PRRR_TR5_SHIFT          10
+#define CB_PRRR_TR6_SHIFT          12
+#define CB_PRRR_TR7_SHIFT          14
+#define CB_PRRR_DS0_SHIFT          16
+#define CB_PRRR_DS1_SHIFT          17
+#define CB_PRRR_NS0_SHIFT          18
+#define CB_PRRR_NS1_SHIFT          19
+#define CB_PRRR_NOS0_SHIFT         24
+#define CB_PRRR_NOS1_SHIFT         25
+#define CB_PRRR_NOS2_SHIFT         26
+#define CB_PRRR_NOS3_SHIFT         27
+#define CB_PRRR_NOS4_SHIFT         28
+#define CB_PRRR_NOS5_SHIFT         29
+#define CB_PRRR_NOS6_SHIFT         30
+#define CB_PRRR_NOS7_SHIFT         31
+
+/* Transaction Resume: CB_RESUME */
+#define CB_RESUME_TNR_SHIFT        0
+
+/* System Control Register: CB_SCTLR */
+#define CB_SCTLR_M_SHIFT            0
+#define CB_SCTLR_TRE_SHIFT          1
+#define CB_SCTLR_AFE_SHIFT          2
+#define CB_SCTLR_AFFD_SHIFT         3
+#define CB_SCTLR_E_SHIFT            4
+#define CB_SCTLR_CFRE_SHIFT         5
+#define CB_SCTLR_CFIE_SHIFT         6
+#define CB_SCTLR_CFCFG_SHIFT        7
+#define CB_SCTLR_HUPCF_SHIFT        8
+#define CB_SCTLR_WXN_SHIFT          9
+#define CB_SCTLR_UWXN_SHIFT         10
+#define CB_SCTLR_ASIDPNE_SHIFT      12
+#define CB_SCTLR_TRANSIENTCFG_SHIFT 14
+#define CB_SCTLR_MEMATTR_SHIFT      16
+#define CB_SCTLR_MTCFG_SHIFT        20
+#define CB_SCTLR_SHCFG_SHIFT        22
+#define CB_SCTLR_RACFG_SHIFT        24
+#define CB_SCTLR_WACFG_SHIFT        26
+#define CB_SCTLR_NSCFG_SHIFT        28
+
+/* Invalidate TLB by ASID: CB_TLBIASID */
+#define CB_TLBIASID_ASID_SHIFT      0
+
+/* Invalidate TLB by VA: CB_TLBIVA */
+#define CB_TLBIVA_ASID_SHIFT        0
+#define CB_TLBIVA_VA_SHIFT          12
+
+/* Invalidate TLB by VA, All ASID: CB_TLBIVAA */
+#define CB_TLBIVAA_VA_SHIFT         12
+
+/* Invalidate TLB by VA, All ASID, Last Level: CB_TLBIVAAL */
+#define CB_TLBIVAAL_VA_SHIFT        12
+
+/* Invalidate TLB by VA, Last Level: CB_TLBIVAL */
+#define CB_TLBIVAL_ASID_SHIFT       0
+#define CB_TLBIVAL_VA_SHIFT         12
+
+/* TLB Status: CB_TLBSTATUS */
+#define CB_TLBSTATUS_SACTIVE_SHIFT  0
+
+/* Translation Table Base Control Register: CB_TTBCR */
+#define CB_TTBCR_T0SZ_SHIFT         0
+#define CB_TTBCR_PD0_SHIFT          4
+#define CB_TTBCR_PD1_SHIFT          5
+#define CB_TTBCR_NSCFG0_SHIFT       14
+#define CB_TTBCR_NSCFG1_SHIFT       30
+#define CB_TTBCR_EAE_SHIFT          31
+
+/* Translation Table Base Register 0/1: CB_TTBR */
+#define CB_TTBR0_IRGN1_SHIFT        0
+#define CB_TTBR0_S_SHIFT            1
+#define CB_TTBR0_RGN_SHIFT          3
+#define CB_TTBR0_NOS_SHIFT          5
+#define CB_TTBR0_IRGN0_SHIFT        6
+#define CB_TTBR0_ADDR_SHIFT         14
+
+#define CB_TTBR1_IRGN1_SHIFT        0
+#define CB_TTBR1_S_SHIFT            1
+#define CB_TTBR1_RGN_SHIFT          3
+#define CB_TTBR1_NOS_SHIFT          5
+#define CB_TTBR1_IRGN0_SHIFT        6
+#define CB_TTBR1_ADDR_SHIFT         14
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/iommu_hw-v2.h b/arch/arm/mach-msm/include/mach/iommu_hw-v2.h
deleted file mode 100644
index c4991bf..0000000
--- a/arch/arm/mach-msm/include/mach/iommu_hw-v2.h
+++ /dev/null
@@ -1,2111 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#ifndef __ARCH_ARM_MACH_MSM_IOMMU_HW_V2_H
-#define __ARCH_ARM_MACH_MSM_IOMMU_HW_V2_H
-
-#define CTX_SHIFT  12
-#define CTX_OFFSET 0x8000
-#define IMPLDEF_OFFSET	0x2000
-#define IMPLDEF_LENGTH	0xDFF
-
-#define GET_GLOBAL_REG(reg, base) (readl_relaxed((base) + (reg)))
-#define GET_CTX_REG(reg, base, ctx) \
-	(readl_relaxed((base) + CTX_OFFSET + (reg) + ((ctx) << CTX_SHIFT)))
-
-#define SET_GLOBAL_REG(reg, base, val)	writel_relaxed((val), ((base) + (reg)))
-
-#define SET_CTX_REG(reg, base, ctx, val) \
-	writel_relaxed((val), \
-		((base) + CTX_OFFSET + (reg) + ((ctx) << CTX_SHIFT)))
-
-/* Wrappers for numbered registers */
-#define SET_GLOBAL_REG_N(b, n, r, v) SET_GLOBAL_REG((b), ((r) + (n << 2)), (v))
-#define GET_GLOBAL_REG_N(b, n, r)    GET_GLOBAL_REG((b), ((r) + (n << 2)))
-
-/* Field wrappers */
-#define GET_GLOBAL_FIELD(b, r, F) \
-	GET_FIELD(((b) + (r)), r##_##F##_MASK, r##_##F##_SHIFT)
-#define GET_CONTEXT_FIELD(b, c, r, F) \
-	GET_FIELD(((b) + CTX_OFFSET + (r) + ((c) << CTX_SHIFT)), \
-			r##_##F##_MASK, r##_##F##_SHIFT)
-
-#define SET_GLOBAL_FIELD(b, r, F, v) \
-	SET_FIELD(((b) + (r)), r##_##F##_MASK, r##_##F##_SHIFT, (v))
-#define SET_CONTEXT_FIELD(b, c, r, F, v) \
-	SET_FIELD(((b) + CTX_OFFSET + (r) + ((c) << CTX_SHIFT)), \
-			r##_##F##_MASK, r##_##F##_SHIFT, (v))
-
-/* Wrappers for numbered field registers */
-#define SET_GLOBAL_FIELD_N(b, n, r, F, v) \
-	SET_FIELD(((b) + ((n) << 2) + (r)), r##_##F##_MASK, r##_##F##_SHIFT, v)
-#define GET_GLOBAL_FIELD_N(b, n, r, F) \
-	GET_FIELD(((b) + ((n) << 2) + (r)), r##_##F##_MASK, r##_##F##_SHIFT)
-
-#define GET_FIELD(addr, mask, shift) ((readl_relaxed(addr) >> (shift)) & (mask))
-
-#define SET_FIELD(addr, mask, shift, v) \
-do { \
-	int t = readl_relaxed(addr); \
-	writel_relaxed((t & ~((mask) << (shift))) + (((v) & \
-			(mask)) << (shift)), addr); \
-} while (0)
-
-
-/* Global register space 0 setters / getters */
-#define SET_CR0(b, v)            SET_GLOBAL_REG(CR0, (b), (v))
-#define SET_SCR1(b, v)           SET_GLOBAL_REG(SCR1, (b), (v))
-#define SET_CR2(b, v)            SET_GLOBAL_REG(CR2, (b), (v))
-#define SET_ACR(b, v)            SET_GLOBAL_REG(ACR, (b), (v))
-#define SET_IDR0(b, N, v)        SET_GLOBAL_REG(IDR0, (b), (v))
-#define SET_IDR1(b, N, v)        SET_GLOBAL_REG(IDR1, (b), (v))
-#define SET_IDR2(b, N, v)        SET_GLOBAL_REG(IDR2, (b), (v))
-#define SET_IDR7(b, N, v)        SET_GLOBAL_REG(IDR7, (b), (v))
-#define SET_GFAR(b, v)           SET_GLOBAL_REG(GFAR, (b), (v))
-#define SET_GFSR(b, v)           SET_GLOBAL_REG(GFSR, (b), (v))
-#define SET_GFSRRESTORE(b, v)    SET_GLOBAL_REG(GFSRRESTORE, (b), (v))
-#define SET_GFSYNR0(b, v)        SET_GLOBAL_REG(GFSYNR0, (b), (v))
-#define SET_GFSYNR1(b, v)        SET_GLOBAL_REG(GFSYNR1, (b), (v))
-#define SET_GFSYNR2(b, v)        SET_GLOBAL_REG(GFSYNR2, (b), (v))
-#define SET_TLBIVMID(b, v)       SET_GLOBAL_REG(TLBIVMID, (b), (v))
-#define SET_TLBIALLNSNH(b, v)    SET_GLOBAL_REG(TLBIALLNSNH, (b), (v))
-#define SET_TLBIALLH(b, v)       SET_GLOBAL_REG(TLBIALLH, (b), (v))
-#define SET_TLBGSYNC(b, v)       SET_GLOBAL_REG(TLBGSYNC, (b), (v))
-#define SET_TLBGSTATUS(b, v)     SET_GLOBAL_REG(TLBSTATUS, (b), (v))
-#define SET_TLBIVAH(b, v)        SET_GLOBAL_REG(TLBIVAH, (b), (v))
-#define SET_GATS1UR(b, v)        SET_GLOBAL_REG(GATS1UR, (b), (v))
-#define SET_GATS1UW(b, v)        SET_GLOBAL_REG(GATS1UW, (b), (v))
-#define SET_GATS1PR(b, v)        SET_GLOBAL_REG(GATS1PR, (b), (v))
-#define SET_GATS1PW(b, v)        SET_GLOBAL_REG(GATS1PW, (b), (v))
-#define SET_GATS12UR(b, v)       SET_GLOBAL_REG(GATS12UR, (b), (v))
-#define SET_GATS12UW(b, v)       SET_GLOBAL_REG(GATS12UW, (b), (v))
-#define SET_GATS12PR(b, v)       SET_GLOBAL_REG(GATS12PR, (b), (v))
-#define SET_GATS12PW(b, v)       SET_GLOBAL_REG(GATS12PW, (b), (v))
-#define SET_GPAR(b, v)           SET_GLOBAL_REG(GPAR, (b), (v))
-#define SET_GATSR(b, v)          SET_GLOBAL_REG(GATSR, (b), (v))
-#define SET_NSCR0(b, v)          SET_GLOBAL_REG(NSCR0, (b), (v))
-#define SET_NSCR2(b, v)          SET_GLOBAL_REG(NSCR2, (b), (v))
-#define SET_NSACR(b, v)          SET_GLOBAL_REG(NSACR, (b), (v))
-#define SET_PMCR(b, v)           SET_GLOBAL_REG(PMCR, (b), (v))
-#define SET_SMR_N(b, N, v)       SET_GLOBAL_REG_N(SMR, N, (b), (v))
-#define SET_S2CR_N(b, N, v)      SET_GLOBAL_REG_N(S2CR, N, (b), (v))
-
-#define GET_CR0(b)               GET_GLOBAL_REG(CR0, (b))
-#define GET_SCR1(b)              GET_GLOBAL_REG(SCR1, (b))
-#define GET_CR2(b)               GET_GLOBAL_REG(CR2, (b))
-#define GET_ACR(b)               GET_GLOBAL_REG(ACR, (b))
-#define GET_IDR0(b, N)           GET_GLOBAL_REG(IDR0, (b))
-#define GET_IDR1(b, N)           GET_GLOBAL_REG(IDR1, (b))
-#define GET_IDR2(b, N)           GET_GLOBAL_REG(IDR2, (b))
-#define GET_IDR7(b, N)           GET_GLOBAL_REG(IDR7, (b))
-#define GET_GFAR(b)              GET_GLOBAL_REG(GFAR, (b))
-#define GET_GFSR(b)              GET_GLOBAL_REG(GFSR, (b))
-#define GET_GFSRRESTORE(b)       GET_GLOBAL_REG(GFSRRESTORE, (b))
-#define GET_GFSYNR0(b)           GET_GLOBAL_REG(GFSYNR0, (b))
-#define GET_GFSYNR1(b)           GET_GLOBAL_REG(GFSYNR1, (b))
-#define GET_GFSYNR2(b)           GET_GLOBAL_REG(GFSYNR2, (b))
-#define GET_TLBIVMID(b)          GET_GLOBAL_REG(TLBIVMID, (b))
-#define GET_TLBIALLNSNH(b)       GET_GLOBAL_REG(TLBIALLNSNH, (b))
-#define GET_TLBIALLH(b)          GET_GLOBAL_REG(TLBIALLH, (b))
-#define GET_TLBGSYNC(b)          GET_GLOBAL_REG(TLBGSYNC, (b))
-#define GET_TLBGSTATUS(b)        GET_GLOBAL_REG(TLBSTATUS, (b))
-#define GET_TLBIVAH(b)           GET_GLOBAL_REG(TLBIVAH, (b))
-#define GET_GATS1UR(b)           GET_GLOBAL_REG(GATS1UR, (b))
-#define GET_GATS1UW(b)           GET_GLOBAL_REG(GATS1UW, (b))
-#define GET_GATS1PR(b)           GET_GLOBAL_REG(GATS1PR, (b))
-#define GET_GATS1PW(b)           GET_GLOBAL_REG(GATS1PW, (b))
-#define GET_GATS12UR(b)          GET_GLOBAL_REG(GATS12UR, (b))
-#define GET_GATS12UW(b)          GET_GLOBAL_REG(GATS12UW, (b))
-#define GET_GATS12PR(b)          GET_GLOBAL_REG(GATS12PR, (b))
-#define GET_GATS12PW(b)          GET_GLOBAL_REG(GATS12PW, (b))
-#define GET_GPAR(b)              GET_GLOBAL_REG(GPAR, (b))
-#define GET_GATSR(b)             GET_GLOBAL_REG(GATSR, (b))
-#define GET_NSCR0(b)             GET_GLOBAL_REG(NSCR0, (b))
-#define GET_NSCR2(b)             GET_GLOBAL_REG(NSCR2, (b))
-#define GET_NSACR(b)             GET_GLOBAL_REG(NSACR, (b))
-#define GET_PMCR(b, v)           GET_GLOBAL_REG(PMCR, (b))
-#define GET_SMR_N(b, N)          GET_GLOBAL_REG_N(SMR, N, (b))
-#define GET_S2CR_N(b, N)         GET_GLOBAL_REG_N(S2CR, N, (b))
-
-/* Global register space 1 setters / getters */
-#define SET_CBAR_N(b, N, v)      SET_GLOBAL_REG_N(CBAR, N, (b), (v))
-#define SET_CBFRSYNRA_N(b, N, v) SET_GLOBAL_REG_N(CBFRSYNRA, N, (b), (v))
-
-#define GET_CBAR_N(b, N)         GET_GLOBAL_REG_N(CBAR, N, (b))
-#define GET_CBFRSYNRA_N(b, N)    GET_GLOBAL_REG_N(CBFRSYNRA, N, (b))
-
-/* Implementation defined register setters/getters */
-#define SET_PREDICTIONDIS0(b, v) SET_GLOBAL_REG(PREDICTIONDIS0, (b), (v))
-#define SET_PREDICTIONDIS1(b, v) SET_GLOBAL_REG(PREDICTIONDIS1, (b), (v))
-#define SET_S1L1BFBLP0(b, v)     SET_GLOBAL_REG(S1L1BFBLP0, (b), (v))
-
-/* SSD register setters/getters */
-#define SET_SSDR_N(b, N, v)      SET_GLOBAL_REG_N(SSDR_N, N, (b), (v))
-
-#define GET_SSDR_N(b, N)         GET_GLOBAL_REG_N(SSDR_N, N, (b))
-
-/* Context bank register setters/getters */
-#define SET_SCTLR(b, c, v)       SET_CTX_REG(CB_SCTLR, (b), (c), (v))
-#define SET_ACTLR(b, c, v)       SET_CTX_REG(CB_ACTLR, (b), (c), (v))
-#define SET_RESUME(b, c, v)      SET_CTX_REG(CB_RESUME, (b), (c), (v))
-#define SET_TTBR0(b, c, v)       SET_CTX_REG(CB_TTBR0, (b), (c), (v))
-#define SET_TTBR1(b, c, v)       SET_CTX_REG(CB_TTBR1, (b), (c), (v))
-#define SET_TTBCR(b, c, v)       SET_CTX_REG(CB_TTBCR, (b), (c), (v))
-#define SET_CONTEXTIDR(b, c, v)  SET_CTX_REG(CB_CONTEXTIDR, (b), (c), (v))
-#define SET_PRRR(b, c, v)        SET_CTX_REG(CB_PRRR, (b), (c), (v))
-#define SET_NMRR(b, c, v)        SET_CTX_REG(CB_NMRR, (b), (c), (v))
-#define SET_PAR(b, c, v)         SET_CTX_REG(CB_PAR, (b), (c), (v))
-#define SET_FSR(b, c, v)         SET_CTX_REG(CB_FSR, (b), (c), (v))
-#define SET_FSRRESTORE(b, c, v)  SET_CTX_REG(CB_FSRRESTORE, (b), (c), (v))
-#define SET_FAR(b, c, v)         SET_CTX_REG(CB_FAR, (b), (c), (v))
-#define SET_FSYNR0(b, c, v)      SET_CTX_REG(CB_FSYNR0, (b), (c), (v))
-#define SET_FSYNR1(b, c, v)      SET_CTX_REG(CB_FSYNR1, (b), (c), (v))
-#define SET_TLBIVA(b, c, v)      SET_CTX_REG(CB_TLBIVA, (b), (c), (v))
-#define SET_TLBIVAA(b, c, v)     SET_CTX_REG(CB_TLBIVAA, (b), (c), (v))
-#define SET_TLBIASID(b, c, v)    SET_CTX_REG(CB_TLBIASID, (b), (c), (v))
-#define SET_TLBIALL(b, c, v)     SET_CTX_REG(CB_TLBIALL, (b), (c), (v))
-#define SET_TLBIVAL(b, c, v)     SET_CTX_REG(CB_TLBIVAL, (b), (c), (v))
-#define SET_TLBIVAAL(b, c, v)    SET_CTX_REG(CB_TLBIVAAL, (b), (c), (v))
-#define SET_TLBSYNC(b, c, v)     SET_CTX_REG(CB_TLBSYNC, (b), (c), (v))
-#define SET_TLBSTATUS(b, c, v)   SET_CTX_REG(CB_TLBSTATUS, (b), (c), (v))
-#define SET_ATS1PR(b, c, v)      SET_CTX_REG(CB_ATS1PR, (b), (c), (v))
-#define SET_ATS1PW(b, c, v)      SET_CTX_REG(CB_ATS1PW, (b), (c), (v))
-#define SET_ATS1UR(b, c, v)      SET_CTX_REG(CB_ATS1UR, (b), (c), (v))
-#define SET_ATS1UW(b, c, v)      SET_CTX_REG(CB_ATS1UW, (b), (c), (v))
-#define SET_ATSR(b, c, v)        SET_CTX_REG(CB_ATSR, (b), (c), (v))
-
-#define GET_SCTLR(b, c)          GET_CTX_REG(CB_SCTLR, (b), (c))
-#define GET_ACTLR(b, c)          GET_CTX_REG(CB_ACTLR, (b), (c))
-#define GET_RESUME(b, c)         GET_CTX_REG(CB_RESUME, (b), (c))
-#define GET_TTBR0(b, c)          GET_CTX_REG(CB_TTBR0, (b), (c))
-#define GET_TTBR1(b, c)          GET_CTX_REG(CB_TTBR1, (b), (c))
-#define GET_TTBCR(b, c)          GET_CTX_REG(CB_TTBCR, (b), (c))
-#define GET_CONTEXTIDR(b, c)     GET_CTX_REG(CB_CONTEXTIDR, (b), (c))
-#define GET_PRRR(b, c)           GET_CTX_REG(CB_PRRR, (b), (c))
-#define GET_NMRR(b, c)           GET_CTX_REG(CB_NMRR, (b), (c))
-#define GET_PAR(b, c)            GET_CTX_REG(CB_PAR, (b), (c))
-#define GET_FSR(b, c)            GET_CTX_REG(CB_FSR, (b), (c))
-#define GET_FSRRESTORE(b, c)     GET_CTX_REG(CB_FSRRESTORE, (b), (c))
-#define GET_FAR(b, c)            GET_CTX_REG(CB_FAR, (b), (c))
-#define GET_FSYNR0(b, c)         GET_CTX_REG(CB_FSYNR0, (b), (c))
-#define GET_FSYNR1(b, c)         GET_CTX_REG(CB_FSYNR1, (b), (c))
-#define GET_TLBIVA(b, c)         GET_CTX_REG(CB_TLBIVA, (b), (c))
-#define GET_TLBIVAA(b, c)        GET_CTX_REG(CB_TLBIVAA, (b), (c))
-#define GET_TLBIASID(b, c)       GET_CTX_REG(CB_TLBIASID, (b), (c))
-#define GET_TLBIALL(b, c)        GET_CTX_REG(CB_TLBIALL, (b), (c))
-#define GET_TLBIVAL(b, c)        GET_CTX_REG(CB_TLBIVAL, (b), (c))
-#define GET_TLBIVAAL(b, c)       GET_CTX_REG(CB_TLBIVAAL, (b), (c))
-#define GET_TLBSYNC(b, c)        GET_CTX_REG(CB_TLBSYNC, (b), (c))
-#define GET_TLBSTATUS(b, c)      GET_CTX_REG(CB_TLBSTATUS, (b), (c))
-#define GET_ATS1PR(b, c)         GET_CTX_REG(CB_ATS1PR, (b), (c))
-#define GET_ATS1PW(b, c)         GET_CTX_REG(CB_ATS1PW, (b), (c))
-#define GET_ATS1UR(b, c)         GET_CTX_REG(CB_ATS1UR, (b), (c))
-#define GET_ATS1UW(b, c)         GET_CTX_REG(CB_ATS1UW, (b), (c))
-#define GET_ATSR(b, c)           GET_CTX_REG(CB_ATSR, (b), (c))
-
-/* Global Register field setters / getters */
-/* Configuration Register: CR0 */
-#define SET_CR0_NSCFG(b, v)        SET_GLOBAL_FIELD(b, CR0, NSCFG, v)
-#define SET_CR0_WACFG(b, v)        SET_GLOBAL_FIELD(b, CR0, WACFG, v)
-#define SET_CR0_RACFG(b, v)        SET_GLOBAL_FIELD(b, CR0, RACFG, v)
-#define SET_CR0_SHCFG(b, v)        SET_GLOBAL_FIELD(b, CR0, SHCFG, v)
-#define SET_CR0_SMCFCFG(b, v)      SET_GLOBAL_FIELD(b, CR0, SMCFCFG, v)
-#define SET_CR0_MTCFG(b, v)        SET_GLOBAL_FIELD(b, CR0, MTCFG, v)
-#define SET_CR0_BSU(b, v)          SET_GLOBAL_FIELD(b, CR0, BSU, v)
-#define SET_CR0_FB(b, v)           SET_GLOBAL_FIELD(b, CR0, FB, v)
-#define SET_CR0_PTM(b, v)          SET_GLOBAL_FIELD(b, CR0, PTM, v)
-#define SET_CR0_VMIDPNE(b, v)      SET_GLOBAL_FIELD(b, CR0, VMIDPNE, v)
-#define SET_CR0_USFCFG(b, v)       SET_GLOBAL_FIELD(b, CR0, USFCFG, v)
-#define SET_CR0_GSE(b, v)          SET_GLOBAL_FIELD(b, CR0, GSE, v)
-#define SET_CR0_STALLD(b, v)       SET_GLOBAL_FIELD(b, CR0, STALLD, v)
-#define SET_CR0_TRANSIENTCFG(b, v) SET_GLOBAL_FIELD(b, CR0, TRANSIENTCFG, v)
-#define SET_CR0_GCFGFIE(b, v)      SET_GLOBAL_FIELD(b, CR0, GCFGFIE, v)
-#define SET_CR0_GCFGFRE(b, v)      SET_GLOBAL_FIELD(b, CR0, GCFGFRE, v)
-#define SET_CR0_GFIE(b, v)         SET_GLOBAL_FIELD(b, CR0, GFIE, v)
-#define SET_CR0_GFRE(b, v)         SET_GLOBAL_FIELD(b, CR0, GFRE, v)
-#define SET_CR0_CLIENTPD(b, v)     SET_GLOBAL_FIELD(b, CR0, CLIENTPD, v)
-
-#define GET_CR0_NSCFG(b)           GET_GLOBAL_FIELD(b, CR0, NSCFG)
-#define GET_CR0_WACFG(b)           GET_GLOBAL_FIELD(b, CR0, WACFG)
-#define GET_CR0_RACFG(b)           GET_GLOBAL_FIELD(b, CR0, RACFG)
-#define GET_CR0_SHCFG(b)           GET_GLOBAL_FIELD(b, CR0, SHCFG)
-#define GET_CR0_SMCFCFG(b)         GET_GLOBAL_FIELD(b, CR0, SMCFCFG)
-#define GET_CR0_MTCFG(b)           GET_GLOBAL_FIELD(b, CR0, MTCFG)
-#define GET_CR0_BSU(b)             GET_GLOBAL_FIELD(b, CR0, BSU)
-#define GET_CR0_FB(b)              GET_GLOBAL_FIELD(b, CR0, FB)
-#define GET_CR0_PTM(b)             GET_GLOBAL_FIELD(b, CR0, PTM)
-#define GET_CR0_VMIDPNE(b)         GET_GLOBAL_FIELD(b, CR0, VMIDPNE)
-#define GET_CR0_USFCFG(b)          GET_GLOBAL_FIELD(b, CR0, USFCFG)
-#define GET_CR0_GSE(b)             GET_GLOBAL_FIELD(b, CR0, GSE)
-#define GET_CR0_STALLD(b)          GET_GLOBAL_FIELD(b, CR0, STALLD)
-#define GET_CR0_TRANSIENTCFG(b)    GET_GLOBAL_FIELD(b, CR0, TRANSIENTCFG)
-#define GET_CR0_GCFGFIE(b)         GET_GLOBAL_FIELD(b, CR0, GCFGFIE)
-#define GET_CR0_GCFGFRE(b)         GET_GLOBAL_FIELD(b, CR0, GCFGFRE)
-#define GET_CR0_GFIE(b)            GET_GLOBAL_FIELD(b, CR0, GFIE)
-#define GET_CR0_GFRE(b)            GET_GLOBAL_FIELD(b, CR0, GFRE)
-#define GET_CR0_CLIENTPD(b)        GET_GLOBAL_FIELD(b, CR0, CLIENTPD)
-
-/* Configuration Register: CR2 */
-#define SET_CR2_BPVMID(b, v)     SET_GLOBAL_FIELD(b, CR2, BPVMID, v)
-
-#define GET_CR2_BPVMID(b)        GET_GLOBAL_FIELD(b, CR2, BPVMID)
-
-/* Global Address Translation, Stage 1, Privileged Read: GATS1PR */
-#define SET_GATS1PR_ADDR(b, v)   SET_GLOBAL_FIELD(b, GATS1PR, ADDR, v)
-#define SET_GATS1PR_NDX(b, v)    SET_GLOBAL_FIELD(b, GATS1PR, NDX, v)
-
-#define GET_GATS1PR_ADDR(b)      GET_GLOBAL_FIELD(b, GATS1PR, ADDR)
-#define GET_GATS1PR_NDX(b)       GET_GLOBAL_FIELD(b, GATS1PR, NDX)
-
-/* Global Address Translation, Stage 1, Privileged Write: GATS1PW */
-#define SET_GATS1PW_ADDR(b, v)   SET_GLOBAL_FIELD(b, GATS1PW, ADDR, v)
-#define SET_GATS1PW_NDX(b, v)    SET_GLOBAL_FIELD(b, GATS1PW, NDX, v)
-
-#define GET_GATS1PW_ADDR(b)      GET_GLOBAL_FIELD(b, GATS1PW, ADDR)
-#define GET_GATS1PW_NDX(b)       GET_GLOBAL_FIELD(b, GATS1PW, NDX)
-
-/* Global Address Translation, Stage 1, User Read: GATS1UR */
-#define SET_GATS1UR_ADDR(b, v)   SET_GLOBAL_FIELD(b, GATS1UR, ADDR, v)
-#define SET_GATS1UR_NDX(b, v)    SET_GLOBAL_FIELD(b, GATS1UR, NDX, v)
-
-#define GET_GATS1UR_ADDR(b)      GET_GLOBAL_FIELD(b, GATS1UR, ADDR)
-#define GET_GATS1UR_NDX(b)       GET_GLOBAL_FIELD(b, GATS1UR, NDX)
-
-/* Global Address Translation, Stage 1, User Read: GATS1UW */
-#define SET_GATS1UW_ADDR(b, v)   SET_GLOBAL_FIELD(b, GATS1UW, ADDR, v)
-#define SET_GATS1UW_NDX(b, v)    SET_GLOBAL_FIELD(b, GATS1UW, NDX, v)
-
-#define GET_GATS1UW_ADDR(b)      GET_GLOBAL_FIELD(b, GATS1UW, ADDR)
-#define GET_GATS1UW_NDX(b)       GET_GLOBAL_FIELD(b, GATS1UW, NDX)
-
-/* Global Address Translation, Stage 1 and 2, Privileged Read: GATS12PR */
-#define SET_GATS12PR_ADDR(b, v)  SET_GLOBAL_FIELD(b, GATS12PR, ADDR, v)
-#define SET_GATS12PR_NDX(b, v)   SET_GLOBAL_FIELD(b, GATS12PR, NDX, v)
-
-#define GET_GATS12PR_ADDR(b)     GET_GLOBAL_FIELD(b, GATS12PR, ADDR)
-#define GET_GATS12PR_NDX(b)      GET_GLOBAL_FIELD(b, GATS12PR, NDX)
-
-/* Global Address Translation, Stage 1, Privileged Write: GATS1PW */
-#define SET_GATS12PW_ADDR(b, v)  SET_GLOBAL_FIELD(b, GATS12PW, ADDR, v)
-#define SET_GATS12PW_NDX(b, v)   SET_GLOBAL_FIELD(b, GATS12PW, NDX, v)
-
-#define GET_GATS12PW_ADDR(b)     GET_GLOBAL_FIELD(b, GATS12PW, ADDR)
-#define GET_GATS12PW_NDX(b)      GET_GLOBAL_FIELD(b, GATS12PW, NDX)
-
-/* Global Address Translation, Stage 1, User Read: GATS1UR */
-#define SET_GATS12UR_ADDR(b, v)  SET_GLOBAL_FIELD(b, GATS12UR, ADDR, v)
-#define SET_GATS12UR_NDX(b, v)   SET_GLOBAL_FIELD(b, GATS12UR, NDX, v)
-
-#define GET_GATS12UR_ADDR(b)     GET_GLOBAL_FIELD(b, GATS12UR, ADDR)
-#define GET_GATS12UR_NDX(b)      GET_GLOBAL_FIELD(b, GATS12UR, NDX)
-
-/* Global Address Translation, Stage 1, User Read: GATS1UW */
-#define SET_GATS12UW_ADDR(b, v)  SET_GLOBAL_FIELD(b, GATS12UW, ADDR, v)
-#define SET_GATS12UW_NDX(b, v)   SET_GLOBAL_FIELD(b, GATS12UW, NDX, v)
-
-#define GET_GATS12UW_ADDR(b)     GET_GLOBAL_FIELD(b, GATS12UW, ADDR)
-#define GET_GATS12UW_NDX(b)      GET_GLOBAL_FIELD(b, GATS12UW, NDX)
-
-/* Global Address Translation Status Register: GATSR */
-#define SET_GATSR_ACTIVE(b, v)   SET_GLOBAL_FIELD(b, GATSR, ACTIVE, v)
-
-#define GET_GATSR_ACTIVE(b)      GET_GLOBAL_FIELD(b, GATSR, ACTIVE)
-
-/* Global Fault Address Register: GFAR */
-#define SET_GFAR_FADDR(b, v)     SET_GLOBAL_FIELD(b, GFAR, FADDR, v)
-
-#define GET_GFAR_FADDR(b)        GET_GLOBAL_FIELD(b, GFAR, FADDR)
-
-/* Global Fault Status Register: GFSR */
-#define SET_GFSR_ICF(b, v)        SET_GLOBAL_FIELD(b, GFSR, ICF, v)
-#define SET_GFSR_USF(b, v)        SET_GLOBAL_FIELD(b, GFSR, USF, v)
-#define SET_GFSR_SMCF(b, v)       SET_GLOBAL_FIELD(b, GFSR, SMCF, v)
-#define SET_GFSR_UCBF(b, v)       SET_GLOBAL_FIELD(b, GFSR, UCBF, v)
-#define SET_GFSR_UCIF(b, v)       SET_GLOBAL_FIELD(b, GFSR, UCIF, v)
-#define SET_GFSR_CAF(b, v)        SET_GLOBAL_FIELD(b, GFSR, CAF, v)
-#define SET_GFSR_EF(b, v)         SET_GLOBAL_FIELD(b, GFSR, EF, v)
-#define SET_GFSR_PF(b, v)         SET_GLOBAL_FIELD(b, GFSR, PF, v)
-#define SET_GFSR_MULTI(b, v)      SET_GLOBAL_FIELD(b, GFSR, MULTI, v)
-
-#define GET_GFSR_ICF(b)           GET_GLOBAL_FIELD(b, GFSR, ICF)
-#define GET_GFSR_USF(b)           GET_GLOBAL_FIELD(b, GFSR, USF)
-#define GET_GFSR_SMCF(b)          GET_GLOBAL_FIELD(b, GFSR, SMCF)
-#define GET_GFSR_UCBF(b)          GET_GLOBAL_FIELD(b, GFSR, UCBF)
-#define GET_GFSR_UCIF(b)          GET_GLOBAL_FIELD(b, GFSR, UCIF)
-#define GET_GFSR_CAF(b)           GET_GLOBAL_FIELD(b, GFSR, CAF)
-#define GET_GFSR_EF(b)            GET_GLOBAL_FIELD(b, GFSR, EF)
-#define GET_GFSR_PF(b)            GET_GLOBAL_FIELD(b, GFSR, PF)
-#define GET_GFSR_MULTI(b)         GET_GLOBAL_FIELD(b, GFSR, MULTI)
-
-/* Global Fault Syndrome Register 0: GFSYNR0 */
-#define SET_GFSYNR0_NESTED(b, v)  SET_GLOBAL_FIELD(b, GFSYNR0, NESTED, v)
-#define SET_GFSYNR0_WNR(b, v)     SET_GLOBAL_FIELD(b, GFSYNR0, WNR, v)
-#define SET_GFSYNR0_PNU(b, v)     SET_GLOBAL_FIELD(b, GFSYNR0, PNU, v)
-#define SET_GFSYNR0_IND(b, v)     SET_GLOBAL_FIELD(b, GFSYNR0, IND, v)
-#define SET_GFSYNR0_NSSTATE(b, v) SET_GLOBAL_FIELD(b, GFSYNR0, NSSTATE, v)
-#define SET_GFSYNR0_NSATTR(b, v)  SET_GLOBAL_FIELD(b, GFSYNR0, NSATTR, v)
-
-#define GET_GFSYNR0_NESTED(b)     GET_GLOBAL_FIELD(b, GFSYNR0, NESTED)
-#define GET_GFSYNR0_WNR(b)        GET_GLOBAL_FIELD(b, GFSYNR0, WNR)
-#define GET_GFSYNR0_PNU(b)        GET_GLOBAL_FIELD(b, GFSYNR0, PNU)
-#define GET_GFSYNR0_IND(b)        GET_GLOBAL_FIELD(b, GFSYNR0, IND)
-#define GET_GFSYNR0_NSSTATE(b)    GET_GLOBAL_FIELD(b, GFSYNR0, NSSTATE)
-#define GET_GFSYNR0_NSATTR(b)     GET_GLOBAL_FIELD(b, GFSYNR0, NSATTR)
-
-/* Global Fault Syndrome Register 1: GFSYNR1 */
-#define SET_GFSYNR1_SID(b, v)     SET_GLOBAL_FIELD(b, GFSYNR1, SID, v)
-
-#define GET_GFSYNR1_SID(b)        GET_GLOBAL_FIELD(b, GFSYNR1, SID)
-
-/* Global Physical Address Register: GPAR */
-#define SET_GPAR_F(b, v)          SET_GLOBAL_FIELD(b, GPAR, F, v)
-#define SET_GPAR_SS(b, v)         SET_GLOBAL_FIELD(b, GPAR, SS, v)
-#define SET_GPAR_OUTER(b, v)      SET_GLOBAL_FIELD(b, GPAR, OUTER, v)
-#define SET_GPAR_INNER(b, v)      SET_GLOBAL_FIELD(b, GPAR, INNER, v)
-#define SET_GPAR_SH(b, v)         SET_GLOBAL_FIELD(b, GPAR, SH, v)
-#define SET_GPAR_NS(b, v)         SET_GLOBAL_FIELD(b, GPAR, NS, v)
-#define SET_GPAR_NOS(b, v)        SET_GLOBAL_FIELD(b, GPAR, NOS, v)
-#define SET_GPAR_PA(b, v)         SET_GLOBAL_FIELD(b, GPAR, PA, v)
-#define SET_GPAR_TF(b, v)         SET_GLOBAL_FIELD(b, GPAR, TF, v)
-#define SET_GPAR_AFF(b, v)        SET_GLOBAL_FIELD(b, GPAR, AFF, v)
-#define SET_GPAR_PF(b, v)         SET_GLOBAL_FIELD(b, GPAR, PF, v)
-#define SET_GPAR_EF(b, v)         SET_GLOBAL_FIELD(b, GPAR, EF, v)
-#define SET_GPAR_TLCMCF(b, v)     SET_GLOBAL_FIELD(b, GPAR, TLCMCF, v)
-#define SET_GPAR_TLBLKF(b, v)     SET_GLOBAL_FIELD(b, GPAR, TLBLKF, v)
-#define SET_GPAR_UCBF(b, v)       SET_GLOBAL_FIELD(b, GPAR, UCBF, v)
-
-#define GET_GPAR_F(b)             GET_GLOBAL_FIELD(b, GPAR, F)
-#define GET_GPAR_SS(b)            GET_GLOBAL_FIELD(b, GPAR, SS)
-#define GET_GPAR_OUTER(b)         GET_GLOBAL_FIELD(b, GPAR, OUTER)
-#define GET_GPAR_INNER(b)         GET_GLOBAL_FIELD(b, GPAR, INNER)
-#define GET_GPAR_SH(b)            GET_GLOBAL_FIELD(b, GPAR, SH)
-#define GET_GPAR_NS(b)            GET_GLOBAL_FIELD(b, GPAR, NS)
-#define GET_GPAR_NOS(b)           GET_GLOBAL_FIELD(b, GPAR, NOS)
-#define GET_GPAR_PA(b)            GET_GLOBAL_FIELD(b, GPAR, PA)
-#define GET_GPAR_TF(b)            GET_GLOBAL_FIELD(b, GPAR, TF)
-#define GET_GPAR_AFF(b)           GET_GLOBAL_FIELD(b, GPAR, AFF)
-#define GET_GPAR_PF(b)            GET_GLOBAL_FIELD(b, GPAR, PF)
-#define GET_GPAR_EF(b)            GET_GLOBAL_FIELD(b, GPAR, EF)
-#define GET_GPAR_TLCMCF(b)        GET_GLOBAL_FIELD(b, GPAR, TLCMCF)
-#define GET_GPAR_TLBLKF(b)        GET_GLOBAL_FIELD(b, GPAR, TLBLKF)
-#define GET_GPAR_UCBF(b)          GET_GLOBAL_FIELD(b, GPAR, UCBF)
-
-/* Identification Register: IDR0 */
-#define SET_IDR0_NUMSMRG(b, v)    SET_GLOBAL_FIELD(b, IDR0, NUMSMRG, v)
-#define SET_IDR0_NUMSIDB(b, v)    SET_GLOBAL_FIELD(b, IDR0, NUMSIDB, v)
-#define SET_IDR0_BTM(b, v)        SET_GLOBAL_FIELD(b, IDR0, BTM, v)
-#define SET_IDR0_CTTW(b, v)       SET_GLOBAL_FIELD(b, IDR0, CTTW, v)
-#define SET_IDR0_NUMIRPT(b, v)    SET_GLOBAL_FIELD(b, IDR0, NUMIRPT, v)
-#define SET_IDR0_PTFS(b, v)       SET_GLOBAL_FIELD(b, IDR0, PTFS, v)
-#define SET_IDR0_SMS(b, v)        SET_GLOBAL_FIELD(b, IDR0, SMS, v)
-#define SET_IDR0_NTS(b, v)        SET_GLOBAL_FIELD(b, IDR0, NTS, v)
-#define SET_IDR0_S2TS(b, v)       SET_GLOBAL_FIELD(b, IDR0, S2TS, v)
-#define SET_IDR0_S1TS(b, v)       SET_GLOBAL_FIELD(b, IDR0, S1TS, v)
-#define SET_IDR0_SES(b, v)        SET_GLOBAL_FIELD(b, IDR0, SES, v)
-
-#define GET_IDR0_NUMSMRG(b)       GET_GLOBAL_FIELD(b, IDR0, NUMSMRG)
-#define GET_IDR0_NUMSIDB(b)       GET_GLOBAL_FIELD(b, IDR0, NUMSIDB)
-#define GET_IDR0_BTM(b)           GET_GLOBAL_FIELD(b, IDR0, BTM)
-#define GET_IDR0_CTTW(b)          GET_GLOBAL_FIELD(b, IDR0, CTTW)
-#define GET_IDR0_NUMIRPT(b)       GET_GLOBAL_FIELD(b, IDR0, NUMIRPT)
-#define GET_IDR0_PTFS(b)          GET_GLOBAL_FIELD(b, IDR0, PTFS)
-#define GET_IDR0_SMS(b)           GET_GLOBAL_FIELD(b, IDR0, SMS)
-#define GET_IDR0_NTS(b)           GET_GLOBAL_FIELD(b, IDR0, NTS)
-#define GET_IDR0_S2TS(b)          GET_GLOBAL_FIELD(b, IDR0, S2TS)
-#define GET_IDR0_S1TS(b)          GET_GLOBAL_FIELD(b, IDR0, S1TS)
-#define GET_IDR0_SES(b)           GET_GLOBAL_FIELD(b, IDR0, SES)
-
-/* Identification Register: IDR1 */
-#define SET_IDR1_NUMCB(b, v)       SET_GLOBAL_FIELD(b, IDR1, NUMCB, v)
-#define SET_IDR1_NUMSSDNDXB(b, v)  SET_GLOBAL_FIELD(b, IDR1, NUMSSDNDXB, v)
-#define SET_IDR1_SSDTP(b, v)       SET_GLOBAL_FIELD(b, IDR1, SSDTP, v)
-#define SET_IDR1_SMCD(b, v)        SET_GLOBAL_FIELD(b, IDR1, SMCD, v)
-#define SET_IDR1_NUMS2CB(b, v)     SET_GLOBAL_FIELD(b, IDR1, NUMS2CB, v)
-#define SET_IDR1_NUMPAGENDXB(b, v) SET_GLOBAL_FIELD(b, IDR1, NUMPAGENDXB, v)
-#define SET_IDR1_PAGESIZE(b, v)    SET_GLOBAL_FIELD(b, IDR1, PAGESIZE, v)
-
-#define GET_IDR1_NUMCB(b)          GET_GLOBAL_FIELD(b, IDR1, NUMCB)
-#define GET_IDR1_NUMSSDNDXB(b)     GET_GLOBAL_FIELD(b, IDR1, NUMSSDNDXB)
-#define GET_IDR1_SSDTP(b)          GET_GLOBAL_FIELD(b, IDR1, SSDTP)
-#define GET_IDR1_SMCD(b)           GET_GLOBAL_FIELD(b, IDR1, SMCD)
-#define GET_IDR1_NUMS2CB(b)        GET_GLOBAL_FIELD(b, IDR1, NUMS2CB)
-#define GET_IDR1_NUMPAGENDXB(b)    GET_GLOBAL_FIELD(b, IDR1, NUMPAGENDXB)
-#define GET_IDR1_PAGESIZE(b)       GET_GLOBAL_FIELD(b, IDR1, PAGESIZE)
-
-/* Identification Register: IDR2 */
-#define SET_IDR2_IAS(b, v)       SET_GLOBAL_FIELD(b, IDR2, IAS, v)
-#define SET_IDR2_OAS(b, v)       SET_GLOBAL_FIELD(b, IDR2, OAS, v)
-
-#define GET_IDR2_IAS(b)          GET_GLOBAL_FIELD(b, IDR2, IAS)
-#define GET_IDR2_OAS(b)          GET_GLOBAL_FIELD(b, IDR2, OAS)
-
-/* Identification Register: IDR7 */
-#define SET_IDR7_MINOR(b, v)     SET_GLOBAL_FIELD(b, IDR7, MINOR, v)
-#define SET_IDR7_MAJOR(b, v)     SET_GLOBAL_FIELD(b, IDR7, MAJOR, v)
-
-#define GET_IDR7_MINOR(b)        GET_GLOBAL_FIELD(b, IDR7, MINOR)
-#define GET_IDR7_MAJOR(b)        GET_GLOBAL_FIELD(b, IDR7, MAJOR)
-
-/* Stream to Context Register: S2CR_N */
-#define SET_S2CR_CBNDX(b, n, v)   SET_GLOBAL_FIELD_N(b, n, S2CR, CBNDX, v)
-#define SET_S2CR_SHCFG(b, n, v)   SET_GLOBAL_FIELD_N(b, n, S2CR, SHCFG, v)
-#define SET_S2CR_MTCFG(b, n, v)   SET_GLOBAL_FIELD_N(b, n, S2CR, MTCFG, v)
-#define SET_S2CR_MEMATTR(b, n, v) SET_GLOBAL_FIELD_N(b, n, S2CR, MEMATTR, v)
-#define SET_S2CR_TYPE(b, n, v)    SET_GLOBAL_FIELD_N(b, n, S2CR, TYPE, v)
-#define SET_S2CR_NSCFG(b, n, v)   SET_GLOBAL_FIELD_N(b, n, S2CR, NSCFG, v)
-#define SET_S2CR_RACFG(b, n, v)   SET_GLOBAL_FIELD_N(b, n, S2CR, RACFG, v)
-#define SET_S2CR_WACFG(b, n, v)   SET_GLOBAL_FIELD_N(b, n, S2CR, WACFG, v)
-#define SET_S2CR_PRIVCFG(b, n, v) SET_GLOBAL_FIELD_N(b, n, S2CR, PRIVCFG, v)
-#define SET_S2CR_INSTCFG(b, n, v) SET_GLOBAL_FIELD_N(b, n, S2CR, INSTCFG, v)
-#define SET_S2CR_TRANSIENTCFG(b, n, v) \
-				SET_GLOBAL_FIELD_N(b, n, S2CR, TRANSIENTCFG, v)
-#define SET_S2CR_VMID(b, n, v)    SET_GLOBAL_FIELD_N(b, n, S2CR, VMID, v)
-#define SET_S2CR_BSU(b, n, v)     SET_GLOBAL_FIELD_N(b, n, S2CR, BSU, v)
-#define SET_S2CR_FB(b, n, v)      SET_GLOBAL_FIELD_N(b, n, S2CR, FB, v)
-
-#define GET_S2CR_CBNDX(b, n)      GET_GLOBAL_FIELD_N(b, n, S2CR, CBNDX)
-#define GET_S2CR_SHCFG(b, n)      GET_GLOBAL_FIELD_N(b, n, S2CR, SHCFG)
-#define GET_S2CR_MTCFG(b, n)      GET_GLOBAL_FIELD_N(b, n, S2CR, MTCFG)
-#define GET_S2CR_MEMATTR(b, n)    GET_GLOBAL_FIELD_N(b, n, S2CR, MEMATTR)
-#define GET_S2CR_TYPE(b, n)       GET_GLOBAL_FIELD_N(b, n, S2CR, TYPE)
-#define GET_S2CR_NSCFG(b, n)      GET_GLOBAL_FIELD_N(b, n, S2CR, NSCFG)
-#define GET_S2CR_RACFG(b, n)      GET_GLOBAL_FIELD_N(b, n, S2CR, RACFG)
-#define GET_S2CR_WACFG(b, n)      GET_GLOBAL_FIELD_N(b, n, S2CR, WACFG)
-#define GET_S2CR_PRIVCFG(b, n)    GET_GLOBAL_FIELD_N(b, n, S2CR, PRIVCFG)
-#define GET_S2CR_INSTCFG(b, n)    GET_GLOBAL_FIELD_N(b, n, S2CR, INSTCFG)
-#define GET_S2CR_TRANSIENTCFG(b, n) \
-				GET_GLOBAL_FIELD_N(b, n, S2CR, TRANSIENTCFG)
-#define GET_S2CR_VMID(b, n)       GET_GLOBAL_FIELD_N(b, n, S2CR, VMID)
-#define GET_S2CR_BSU(b, n)        GET_GLOBAL_FIELD_N(b, n, S2CR, BSU)
-#define GET_S2CR_FB(b, n)         GET_GLOBAL_FIELD_N(b, n, S2CR, FB)
-
-/* Stream Match Register: SMR_N */
-#define SET_SMR_ID(b, n, v)       SET_GLOBAL_FIELD_N(b, n, SMR, ID, v)
-#define SET_SMR_MASK(b, n, v)     SET_GLOBAL_FIELD_N(b, n, SMR, MASK, v)
-#define SET_SMR_VALID(b, n, v)    SET_GLOBAL_FIELD_N(b, n, SMR, VALID, v)
-
-#define GET_SMR_ID(b, n)          GET_GLOBAL_FIELD_N(b, n, SMR, ID)
-#define GET_SMR_MASK(b, n)        GET_GLOBAL_FIELD_N(b, n, SMR, MASK)
-#define GET_SMR_VALID(b, n)       GET_GLOBAL_FIELD_N(b, n, SMR, VALID)
-
-/* Global TLB Status: TLBGSTATUS */
-#define SET_TLBGSTATUS_GSACTIVE(b, v) \
-				SET_GLOBAL_FIELD(b, TLBGSTATUS, GSACTIVE, v)
-
-#define GET_TLBGSTATUS_GSACTIVE(b)    \
-				GET_GLOBAL_FIELD(b, TLBGSTATUS, GSACTIVE)
-
-/* Invalidate Hyp TLB by VA: TLBIVAH */
-#define SET_TLBIVAH_ADDR(b, v)  SET_GLOBAL_FIELD(b, TLBIVAH, ADDR, v)
-
-#define GET_TLBIVAH_ADDR(b)     GET_GLOBAL_FIELD(b, TLBIVAH, ADDR)
-
-/* Invalidate TLB by VMID: TLBIVMID */
-#define SET_TLBIVMID_VMID(b, v) SET_GLOBAL_FIELD(b, TLBIVMID, VMID, v)
-
-#define GET_TLBIVMID_VMID(b)    GET_GLOBAL_FIELD(b, TLBIVMID, VMID)
-
-/* Global Register Space 1 Field setters/getters*/
-/* Context Bank Attribute Register: CBAR_N */
-#define SET_CBAR_VMID(b, n, v)     SET_GLOBAL_FIELD_N(b, n, CBAR, VMID, v)
-#define SET_CBAR_CBNDX(b, n, v)    SET_GLOBAL_FIELD_N(b, n, CBAR, CBNDX, v)
-#define SET_CBAR_BPSHCFG(b, n, v)  SET_GLOBAL_FIELD_N(b, n, CBAR, BPSHCFG, v)
-#define SET_CBAR_HYPC(b, n, v)     SET_GLOBAL_FIELD_N(b, n, CBAR, HYPC, v)
-#define SET_CBAR_FB(b, n, v)       SET_GLOBAL_FIELD_N(b, n, CBAR, FB, v)
-#define SET_CBAR_MEMATTR(b, n, v)  SET_GLOBAL_FIELD_N(b, n, CBAR, MEMATTR, v)
-#define SET_CBAR_TYPE(b, n, v)     SET_GLOBAL_FIELD_N(b, n, CBAR, TYPE, v)
-#define SET_CBAR_BSU(b, n, v)      SET_GLOBAL_FIELD_N(b, n, CBAR, BSU, v)
-#define SET_CBAR_RACFG(b, n, v)    SET_GLOBAL_FIELD_N(b, n, CBAR, RACFG, v)
-#define SET_CBAR_WACFG(b, n, v)    SET_GLOBAL_FIELD_N(b, n, CBAR, WACFG, v)
-#define SET_CBAR_IRPTNDX(b, n, v)  SET_GLOBAL_FIELD_N(b, n, CBAR, IRPTNDX, v)
-
-#define GET_CBAR_VMID(b, n)        GET_GLOBAL_FIELD_N(b, n, CBAR, VMID)
-#define GET_CBAR_CBNDX(b, n)       GET_GLOBAL_FIELD_N(b, n, CBAR, CBNDX)
-#define GET_CBAR_BPSHCFG(b, n)     GET_GLOBAL_FIELD_N(b, n, CBAR, BPSHCFG)
-#define GET_CBAR_HYPC(b, n)        GET_GLOBAL_FIELD_N(b, n, CBAR, HYPC)
-#define GET_CBAR_FB(b, n)          GET_GLOBAL_FIELD_N(b, n, CBAR, FB)
-#define GET_CBAR_MEMATTR(b, n)     GET_GLOBAL_FIELD_N(b, n, CBAR, MEMATTR)
-#define GET_CBAR_TYPE(b, n)        GET_GLOBAL_FIELD_N(b, n, CBAR, TYPE)
-#define GET_CBAR_BSU(b, n)         GET_GLOBAL_FIELD_N(b, n, CBAR, BSU)
-#define GET_CBAR_RACFG(b, n)       GET_GLOBAL_FIELD_N(b, n, CBAR, RACFG)
-#define GET_CBAR_WACFG(b, n)       GET_GLOBAL_FIELD_N(b, n, CBAR, WACFG)
-#define GET_CBAR_IRPTNDX(b, n)     GET_GLOBAL_FIELD_N(b, n, CBAR, IRPTNDX)
-
-/* Context Bank Fault Restricted Syndrome Register A: CBFRSYNRA_N */
-#define SET_CBFRSYNRA_SID(b, n, v) SET_GLOBAL_FIELD_N(b, n, CBFRSYNRA, SID, v)
-
-#define GET_CBFRSYNRA_SID(b, n)    GET_GLOBAL_FIELD_N(b, n, CBFRSYNRA, SID)
-
-/* Stage 1 Context Bank Format Fields */
-#define SET_CB_ACTLR_REQPRIORITY (b, c, v) \
-		SET_CONTEXT_FIELD(b, c, CB_ACTLR, REQPRIORITY, v)
-#define SET_CB_ACTLR_REQPRIORITYCFG(b, c, v) \
-		SET_CONTEXT_FIELD(b, c, CB_ACTLR, REQPRIORITYCFG, v)
-#define SET_CB_ACTLR_PRIVCFG(b, c, v) \
-		SET_CONTEXT_FIELD(b, c, CB_ACTLR, PRIVCFG, v)
-#define SET_CB_ACTLR_BPRCOSH(b, c, v) \
-		SET_CONTEXT_FIELD(b, c, CB_ACTLR, BPRCOSH, v)
-#define SET_CB_ACTLR_BPRCISH(b, c, v) \
-		SET_CONTEXT_FIELD(b, c, CB_ACTLR, BPRCISH, v)
-#define SET_CB_ACTLR_BPRCNSH(b, c, v) \
-		SET_CONTEXT_FIELD(b, c, CB_ACTLR, BPRCNSH, v)
-
-#define GET_CB_ACTLR_REQPRIORITY (b, c) \
-		GET_CONTEXT_FIELD(b, c, CB_ACTLR, REQPRIORITY)
-#define GET_CB_ACTLR_REQPRIORITYCFG(b, c) \
-		GET_CONTEXT_FIELD(b, c, CB_ACTLR, REQPRIORITYCFG)
-#define GET_CB_ACTLR_PRIVCFG(b, c)  GET_CONTEXT_FIELD(b, c, CB_ACTLR, PRIVCFG)
-#define GET_CB_ACTLR_BPRCOSH(b, c)  GET_CONTEXT_FIELD(b, c, CB_ACTLR, BPRCOSH)
-#define GET_CB_ACTLR_BPRCISH(b, c)  GET_CONTEXT_FIELD(b, c, CB_ACTLR, BPRCISH)
-#define GET_CB_ACTLR_BPRCNSH(b, c)  GET_CONTEXT_FIELD(b, c, CB_ACTLR, BPRCNSH)
-
-/* Address Translation, Stage 1, Privileged Read: CB_ATS1PR */
-#define SET_CB_ATS1PR_ADDR(b, c, v) SET_CONTEXT_FIELD(b, c, CB_ATS1PR, ADDR, v)
-
-#define GET_CB_ATS1PR_ADDR(b, c)    GET_CONTEXT_FIELD(b, c, CB_ATS1PR, ADDR)
-
-/* Address Translation, Stage 1, Privileged Write: CB_ATS1PW */
-#define SET_CB_ATS1PW_ADDR(b, c, v) SET_CONTEXT_FIELD(b, c, CB_ATS1PW, ADDR, v)
-
-#define GET_CB_ATS1PW_ADDR(b, c)    GET_CONTEXT_FIELD(b, c, CB_ATS1PW, ADDR)
-
-/* Address Translation, Stage 1, User Read: CB_ATS1UR */
-#define SET_CB_ATS1UR_ADDR(b, c, v) SET_CONTEXT_FIELD(b, c, CB_ATS1UR, ADDR, v)
-
-#define GET_CB_ATS1UR_ADDR(b, c)    GET_CONTEXT_FIELD(b, c, CB_ATS1UR, ADDR)
-
-/* Address Translation, Stage 1, User Write: CB_ATS1UW */
-#define SET_CB_ATS1UW_ADDR(b, c, v) SET_CONTEXT_FIELD(b, c, CB_ATS1UW, ADDR, v)
-
-#define GET_CB_ATS1UW_ADDR(b, c)    GET_CONTEXT_FIELD(b, c, CB_ATS1UW, ADDR)
-
-/* Address Translation Status Register: CB_ATSR */
-#define SET_CB_ATSR_ACTIVE(b, c, v) SET_CONTEXT_FIELD(b, c, CB_ATSR, ACTIVE, v)
-
-#define GET_CB_ATSR_ACTIVE(b, c)    GET_CONTEXT_FIELD(b, c, CB_ATSR, ACTIVE)
-
-/* Context ID Register: CB_CONTEXTIDR */
-#define SET_CB_CONTEXTIDR_ASID(b, c, v) \
-			SET_CONTEXT_FIELD(b, c, CB_CONTEXTIDR, ASID, v)
-#define SET_CB_CONTEXTIDR_PROCID(b, c, v) \
-			SET_CONTEXT_FIELD(b, c, CB_CONTEXTIDR, PROCID, v)
-
-#define GET_CB_CONTEXTIDR_ASID(b, c)    \
-			GET_CONTEXT_FIELD(b, c, CB_CONTEXTIDR, ASID)
-#define GET_CB_CONTEXTIDR_PROCID(b, c)    \
-			GET_CONTEXT_FIELD(b, c, CB_CONTEXTIDR, PROCID)
-
-/* Fault Address Register: CB_FAR */
-#define SET_CB_FAR_FADDR(b, c, v) SET_CONTEXT_FIELD(b, c, CB_FAR, FADDR, v)
-
-#define GET_CB_FAR_FADDR(b, c)    GET_CONTEXT_FIELD(b, c, CB_FAR, FADDR)
-
-/* Fault Status Register: CB_FSR */
-#define SET_CB_FSR_TF(b, c, v)     SET_CONTEXT_FIELD(b, c, CB_FSR, TF, v)
-#define SET_CB_FSR_AFF(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_FSR, AFF, v)
-#define SET_CB_FSR_PF(b, c, v)     SET_CONTEXT_FIELD(b, c, CB_FSR, PF, v)
-#define SET_CB_FSR_EF(b, c, v)     SET_CONTEXT_FIELD(b, c, CB_FSR, EF, v)
-#define SET_CB_FSR_TLBMCF(b, c, v) SET_CONTEXT_FIELD(b, c, CB_FSR, TLBMCF, v)
-#define SET_CB_FSR_TLBLKF(b, c, v) SET_CONTEXT_FIELD(b, c, CB_FSR, TLBLKF, v)
-#define SET_CB_FSR_SS(b, c, v)     SET_CONTEXT_FIELD(b, c, CB_FSR, SS, v)
-#define SET_CB_FSR_MULTI(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_FSR, MULTI, v)
-
-#define GET_CB_FSR_TF(b, c)        GET_CONTEXT_FIELD(b, c, CB_FSR, TF)
-#define GET_CB_FSR_AFF(b, c)       GET_CONTEXT_FIELD(b, c, CB_FSR, AFF)
-#define GET_CB_FSR_PF(b, c)        GET_CONTEXT_FIELD(b, c, CB_FSR, PF)
-#define GET_CB_FSR_EF(b, c)        GET_CONTEXT_FIELD(b, c, CB_FSR, EF)
-#define GET_CB_FSR_TLBMCF(b, c)    GET_CONTEXT_FIELD(b, c, CB_FSR, TLBMCF)
-#define GET_CB_FSR_TLBLKF(b, c)    GET_CONTEXT_FIELD(b, c, CB_FSR, TLBLKF)
-#define GET_CB_FSR_SS(b, c)        GET_CONTEXT_FIELD(b, c, CB_FSR, SS)
-#define GET_CB_FSR_MULTI(b, c)     GET_CONTEXT_FIELD(b, c, CB_FSR, MULTI)
-
-/* Fault Syndrome Register 0: CB_FSYNR0 */
-#define SET_CB_FSYNR0_PLVL(b, c, v) SET_CONTEXT_FIELD(b, c, CB_FSYNR0, PLVL, v)
-#define SET_CB_FSYNR0_S1PTWF(b, c, v) \
-				SET_CONTEXT_FIELD(b, c, CB_FSYNR0, S1PTWF, v)
-#define SET_CB_FSYNR0_WNR(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_FSYNR0, WNR, v)
-#define SET_CB_FSYNR0_PNU(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_FSYNR0, PNU, v)
-#define SET_CB_FSYNR0_IND(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_FSYNR0, IND, v)
-#define SET_CB_FSYNR0_NSSTATE(b, c, v) \
-				SET_CONTEXT_FIELD(b, c, CB_FSYNR0, NSSTATE, v)
-#define SET_CB_FSYNR0_NSATTR(b, c, v) \
-				SET_CONTEXT_FIELD(b, c, CB_FSYNR0, NSATTR, v)
-#define SET_CB_FSYNR0_ATOF(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_FSYNR0, ATOF, v)
-#define SET_CB_FSYNR0_PTWF(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_FSYNR0, PTWF, v)
-#define SET_CB_FSYNR0_AFR(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_FSYNR0, AFR, v)
-#define SET_CB_FSYNR0_S1CBNDX(b, c, v) \
-				SET_CONTEXT_FIELD(b, c, CB_FSYNR0, S1CBNDX, v)
-
-#define GET_CB_FSYNR0_PLVL(b, c)    GET_CONTEXT_FIELD(b, c, CB_FSYNR0, PLVL)
-#define GET_CB_FSYNR0_S1PTWF(b, c)    \
-				GET_CONTEXT_FIELD(b, c, CB_FSYNR0, S1PTWF)
-#define GET_CB_FSYNR0_WNR(b, c)     GET_CONTEXT_FIELD(b, c, CB_FSYNR0, WNR)
-#define GET_CB_FSYNR0_PNU(b, c)     GET_CONTEXT_FIELD(b, c, CB_FSYNR0, PNU)
-#define GET_CB_FSYNR0_IND(b, c)     GET_CONTEXT_FIELD(b, c, CB_FSYNR0, IND)
-#define GET_CB_FSYNR0_NSSTATE(b, c)    \
-				GET_CONTEXT_FIELD(b, c, CB_FSYNR0, NSSTATE)
-#define GET_CB_FSYNR0_NSATTR(b, c)    \
-				GET_CONTEXT_FIELD(b, c, CB_FSYNR0, NSATTR)
-#define GET_CB_FSYNR0_ATOF(b, c)     GET_CONTEXT_FIELD(b, c, CB_FSYNR0, ATOF)
-#define GET_CB_FSYNR0_PTWF(b, c)     GET_CONTEXT_FIELD(b, c, CB_FSYNR0, PTWF)
-#define GET_CB_FSYNR0_AFR(b, c)      GET_CONTEXT_FIELD(b, c, CB_FSYNR0, AFR)
-#define GET_CB_FSYNR0_S1CBNDX(b, c)    \
-				GET_CONTEXT_FIELD(b, c, CB_FSYNR0, S1CBNDX)
-
-/* Normal Memory Remap Register: CB_NMRR */
-#define SET_CB_NMRR_IR0(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, IR0, v)
-#define SET_CB_NMRR_IR1(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, IR1, v)
-#define SET_CB_NMRR_IR2(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, IR2, v)
-#define SET_CB_NMRR_IR3(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, IR3, v)
-#define SET_CB_NMRR_IR4(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, IR4, v)
-#define SET_CB_NMRR_IR5(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, IR5, v)
-#define SET_CB_NMRR_IR6(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, IR6, v)
-#define SET_CB_NMRR_IR7(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, IR7, v)
-#define SET_CB_NMRR_OR0(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, OR0, v)
-#define SET_CB_NMRR_OR1(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, OR1, v)
-#define SET_CB_NMRR_OR2(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, OR2, v)
-#define SET_CB_NMRR_OR3(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, OR3, v)
-#define SET_CB_NMRR_OR4(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, OR4, v)
-#define SET_CB_NMRR_OR5(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, OR5, v)
-#define SET_CB_NMRR_OR6(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, OR6, v)
-#define SET_CB_NMRR_OR7(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_NMRR, OR7, v)
-
-#define GET_CB_NMRR_IR0(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, IR0)
-#define GET_CB_NMRR_IR1(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, IR1)
-#define GET_CB_NMRR_IR2(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, IR2)
-#define GET_CB_NMRR_IR3(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, IR3)
-#define GET_CB_NMRR_IR4(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, IR4)
-#define GET_CB_NMRR_IR5(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, IR5)
-#define GET_CB_NMRR_IR6(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, IR6)
-#define GET_CB_NMRR_IR7(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, IR7)
-#define GET_CB_NMRR_OR0(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, OR0)
-#define GET_CB_NMRR_OR1(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, OR1)
-#define GET_CB_NMRR_OR2(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, OR2)
-#define GET_CB_NMRR_OR3(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, OR3)
-#define GET_CB_NMRR_OR4(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, OR4)
-#define GET_CB_NMRR_OR5(b, c)       GET_CONTEXT_FIELD(b, c, CB_NMRR, OR5)
-
-/* Physical Address Register: CB_PAR */
-#define SET_CB_PAR_F(b, c, v)       SET_CONTEXT_FIELD(b, c, CB_PAR, F, v)
-#define SET_CB_PAR_SS(b, c, v)      SET_CONTEXT_FIELD(b, c, CB_PAR, SS, v)
-#define SET_CB_PAR_OUTER(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_PAR, OUTER, v)
-#define SET_CB_PAR_INNER(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_PAR, INNER, v)
-#define SET_CB_PAR_SH(b, c, v)      SET_CONTEXT_FIELD(b, c, CB_PAR, SH, v)
-#define SET_CB_PAR_NS(b, c, v)      SET_CONTEXT_FIELD(b, c, CB_PAR, NS, v)
-#define SET_CB_PAR_NOS(b, c, v)     SET_CONTEXT_FIELD(b, c, CB_PAR, NOS, v)
-#define SET_CB_PAR_PA(b, c, v)      SET_CONTEXT_FIELD(b, c, CB_PAR, PA, v)
-#define SET_CB_PAR_TF(b, c, v)      SET_CONTEXT_FIELD(b, c, CB_PAR, TF, v)
-#define SET_CB_PAR_AFF(b, c, v)     SET_CONTEXT_FIELD(b, c, CB_PAR, AFF, v)
-#define SET_CB_PAR_PF(b, c, v)      SET_CONTEXT_FIELD(b, c, CB_PAR, PF, v)
-#define SET_CB_PAR_TLBMCF(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_PAR, TLBMCF, v)
-#define SET_CB_PAR_TLBLKF(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_PAR, TLBLKF, v)
-#define SET_CB_PAR_ATOT(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PAR, ATOT, v)
-#define SET_CB_PAR_PLVL(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PAR, PLVL, v)
-#define SET_CB_PAR_STAGE(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_PAR, STAGE, v)
-
-#define GET_CB_PAR_F(b, c)          GET_CONTEXT_FIELD(b, c, CB_PAR, F)
-#define GET_CB_PAR_SS(b, c)         GET_CONTEXT_FIELD(b, c, CB_PAR, SS)
-#define GET_CB_PAR_OUTER(b, c)      GET_CONTEXT_FIELD(b, c, CB_PAR, OUTER)
-#define GET_CB_PAR_INNER(b, c)      GET_CONTEXT_FIELD(b, c, CB_PAR, INNER)
-#define GET_CB_PAR_SH(b, c)         GET_CONTEXT_FIELD(b, c, CB_PAR, SH)
-#define GET_CB_PAR_NS(b, c)         GET_CONTEXT_FIELD(b, c, CB_PAR, NS)
-#define GET_CB_PAR_NOS(b, c)        GET_CONTEXT_FIELD(b, c, CB_PAR, NOS)
-#define GET_CB_PAR_PA(b, c)         GET_CONTEXT_FIELD(b, c, CB_PAR, PA)
-#define GET_CB_PAR_TF(b, c)         GET_CONTEXT_FIELD(b, c, CB_PAR, TF)
-#define GET_CB_PAR_AFF(b, c)        GET_CONTEXT_FIELD(b, c, CB_PAR, AFF)
-#define GET_CB_PAR_PF(b, c)         GET_CONTEXT_FIELD(b, c, CB_PAR, PF)
-#define GET_CB_PAR_TLBMCF(b, c)     GET_CONTEXT_FIELD(b, c, CB_PAR, TLBMCF)
-#define GET_CB_PAR_TLBLKF(b, c)     GET_CONTEXT_FIELD(b, c, CB_PAR, TLBLKF)
-#define GET_CB_PAR_ATOT(b, c)       GET_CONTEXT_FIELD(b, c, CB_PAR, ATOT)
-#define GET_CB_PAR_PLVL(b, c)       GET_CONTEXT_FIELD(b, c, CB_PAR, PLVL)
-#define GET_CB_PAR_STAGE(b, c)      GET_CONTEXT_FIELD(b, c, CB_PAR, STAGE)
-
-/* Primary Region Remap Register: CB_PRRR */
-#define SET_CB_PRRR_TR0(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PRRR, TR0, v)
-#define SET_CB_PRRR_TR1(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PRRR, TR1, v)
-#define SET_CB_PRRR_TR2(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PRRR, TR2, v)
-#define SET_CB_PRRR_TR3(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PRRR, TR3, v)
-#define SET_CB_PRRR_TR4(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PRRR, TR4, v)
-#define SET_CB_PRRR_TR5(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PRRR, TR5, v)
-#define SET_CB_PRRR_TR6(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PRRR, TR6, v)
-#define SET_CB_PRRR_TR7(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PRRR, TR7, v)
-#define SET_CB_PRRR_DS0(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PRRR, DS0, v)
-#define SET_CB_PRRR_DS1(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PRRR, DS1, v)
-#define SET_CB_PRRR_NS0(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PRRR, NS0, v)
-#define SET_CB_PRRR_NS1(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_PRRR, NS1, v)
-#define SET_CB_PRRR_NOS0(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_PRRR, NOS0, v)
-#define SET_CB_PRRR_NOS1(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_PRRR, NOS1, v)
-#define SET_CB_PRRR_NOS2(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_PRRR, NOS2, v)
-#define SET_CB_PRRR_NOS3(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_PRRR, NOS3, v)
-#define SET_CB_PRRR_NOS4(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_PRRR, NOS4, v)
-#define SET_CB_PRRR_NOS5(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_PRRR, NOS5, v)
-#define SET_CB_PRRR_NOS6(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_PRRR, NOS6, v)
-#define SET_CB_PRRR_NOS7(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_PRRR, NOS7, v)
-
-#define GET_CB_PRRR_TR0(b, c)       GET_CONTEXT_FIELD(b, c, CB_PRRR, TR0)
-#define GET_CB_PRRR_TR1(b, c)       GET_CONTEXT_FIELD(b, c, CB_PRRR, TR1)
-#define GET_CB_PRRR_TR2(b, c)       GET_CONTEXT_FIELD(b, c, CB_PRRR, TR2)
-#define GET_CB_PRRR_TR3(b, c)       GET_CONTEXT_FIELD(b, c, CB_PRRR, TR3)
-#define GET_CB_PRRR_TR4(b, c)       GET_CONTEXT_FIELD(b, c, CB_PRRR, TR4)
-#define GET_CB_PRRR_TR5(b, c)       GET_CONTEXT_FIELD(b, c, CB_PRRR, TR5)
-#define GET_CB_PRRR_TR6(b, c)       GET_CONTEXT_FIELD(b, c, CB_PRRR, TR6)
-#define GET_CB_PRRR_TR7(b, c)       GET_CONTEXT_FIELD(b, c, CB_PRRR, TR7)
-#define GET_CB_PRRR_DS0(b, c)       GET_CONTEXT_FIELD(b, c, CB_PRRR, DS0)
-#define GET_CB_PRRR_DS1(b, c)       GET_CONTEXT_FIELD(b, c, CB_PRRR, DS1)
-#define GET_CB_PRRR_NS0(b, c)       GET_CONTEXT_FIELD(b, c, CB_PRRR, NS0)
-#define GET_CB_PRRR_NS1(b, c)       GET_CONTEXT_FIELD(b, c, CB_PRRR, NS1)
-#define GET_CB_PRRR_NOS0(b, c)      GET_CONTEXT_FIELD(b, c, CB_PRRR, NOS0)
-#define GET_CB_PRRR_NOS1(b, c)      GET_CONTEXT_FIELD(b, c, CB_PRRR, NOS1)
-#define GET_CB_PRRR_NOS2(b, c)      GET_CONTEXT_FIELD(b, c, CB_PRRR, NOS2)
-#define GET_CB_PRRR_NOS3(b, c)      GET_CONTEXT_FIELD(b, c, CB_PRRR, NOS3)
-#define GET_CB_PRRR_NOS4(b, c)      GET_CONTEXT_FIELD(b, c, CB_PRRR, NOS4)
-#define GET_CB_PRRR_NOS5(b, c)      GET_CONTEXT_FIELD(b, c, CB_PRRR, NOS5)
-#define GET_CB_PRRR_NOS6(b, c)      GET_CONTEXT_FIELD(b, c, CB_PRRR, NOS6)
-#define GET_CB_PRRR_NOS7(b, c)      GET_CONTEXT_FIELD(b, c, CB_PRRR, NOS7)
-
-/* Transaction Resume: CB_RESUME */
-#define SET_CB_RESUME_TNR(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_RESUME, TNR, v)
-
-#define GET_CB_RESUME_TNR(b, c)     GET_CONTEXT_FIELD(b, c, CB_RESUME, TNR)
-
-/* System Control Register: CB_SCTLR */
-#define SET_CB_SCTLR_M(b, c, v)     SET_CONTEXT_FIELD(b, c, CB_SCTLR, M, v)
-#define SET_CB_SCTLR_TRE(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_SCTLR, TRE, v)
-#define SET_CB_SCTLR_AFE(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_SCTLR, AFE, v)
-#define SET_CB_SCTLR_AFFD(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_SCTLR, AFFD, v)
-#define SET_CB_SCTLR_E(b, c, v)     SET_CONTEXT_FIELD(b, c, CB_SCTLR, E, v)
-#define SET_CB_SCTLR_CFRE(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_SCTLR, CFRE, v)
-#define SET_CB_SCTLR_CFIE(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_SCTLR, CFIE, v)
-#define SET_CB_SCTLR_CFCFG(b, c, v) SET_CONTEXT_FIELD(b, c, CB_SCTLR, CFCFG, v)
-#define SET_CB_SCTLR_HUPCF(b, c, v) SET_CONTEXT_FIELD(b, c, CB_SCTLR, HUPCF, v)
-#define SET_CB_SCTLR_WXN(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_SCTLR, WXN, v)
-#define SET_CB_SCTLR_UWXN(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_SCTLR, UWXN, v)
-#define SET_CB_SCTLR_ASIDPNE(b, c, v) \
-			SET_CONTEXT_FIELD(b, c, CB_SCTLR, ASIDPNE, v)
-#define SET_CB_SCTLR_TRANSIENTCFG(b, c, v) \
-			SET_CONTEXT_FIELD(b, c, CB_SCTLR, TRANSIENTCFG, v)
-#define SET_CB_SCTLR_MEMATTR(b, c, v) \
-			SET_CONTEXT_FIELD(b, c, CB_SCTLR, MEMATTR, v)
-#define SET_CB_SCTLR_MTCFG(b, c, v) SET_CONTEXT_FIELD(b, c, CB_SCTLR, MTCFG, v)
-#define SET_CB_SCTLR_SHCFG(b, c, v) SET_CONTEXT_FIELD(b, c, CB_SCTLR, SHCFG, v)
-#define SET_CB_SCTLR_RACFG(b, c, v) SET_CONTEXT_FIELD(b, c, CB_SCTLR, RACFG, v)
-#define SET_CB_SCTLR_WACFG(b, c, v) SET_CONTEXT_FIELD(b, c, CB_SCTLR, WACFG, v)
-#define SET_CB_SCTLR_NSCFG(b, c, v) SET_CONTEXT_FIELD(b, c, CB_SCTLR, NSCFG, v)
-
-#define GET_CB_SCTLR_M(b, c)        GET_CONTEXT_FIELD(b, c, CB_SCTLR, M)
-#define GET_CB_SCTLR_TRE(b, c)      GET_CONTEXT_FIELD(b, c, CB_SCTLR, TRE)
-#define GET_CB_SCTLR_AFE(b, c)      GET_CONTEXT_FIELD(b, c, CB_SCTLR, AFE)
-#define GET_CB_SCTLR_AFFD(b, c)     GET_CONTEXT_FIELD(b, c, CB_SCTLR, AFFD)
-#define GET_CB_SCTLR_E(b, c)        GET_CONTEXT_FIELD(b, c, CB_SCTLR, E)
-#define GET_CB_SCTLR_CFRE(b, c)     GET_CONTEXT_FIELD(b, c, CB_SCTLR, CFRE)
-#define GET_CB_SCTLR_CFIE(b, c)     GET_CONTEXT_FIELD(b, c, CB_SCTLR, CFIE)
-#define GET_CB_SCTLR_CFCFG(b, c)    GET_CONTEXT_FIELD(b, c, CB_SCTLR, CFCFG)
-#define GET_CB_SCTLR_HUPCF(b, c)    GET_CONTEXT_FIELD(b, c, CB_SCTLR, HUPCF)
-#define GET_CB_SCTLR_WXN(b, c)      GET_CONTEXT_FIELD(b, c, CB_SCTLR, WXN)
-#define GET_CB_SCTLR_UWXN(b, c)     GET_CONTEXT_FIELD(b, c, CB_SCTLR, UWXN)
-#define GET_CB_SCTLR_ASIDPNE(b, c)    \
-			GET_CONTEXT_FIELD(b, c, CB_SCTLR, ASIDPNE)
-#define GET_CB_SCTLR_TRANSIENTCFG(b, c)    \
-			GET_CONTEXT_FIELD(b, c, CB_SCTLR, TRANSIENTCFG)
-#define GET_CB_SCTLR_MEMATTR(b, c)    \
-			GET_CONTEXT_FIELD(b, c, CB_SCTLR, MEMATTR)
-#define GET_CB_SCTLR_MTCFG(b, c)    GET_CONTEXT_FIELD(b, c, CB_SCTLR, MTCFG)
-#define GET_CB_SCTLR_SHCFG(b, c)    GET_CONTEXT_FIELD(b, c, CB_SCTLR, SHCFG)
-#define GET_CB_SCTLR_RACFG(b, c)    GET_CONTEXT_FIELD(b, c, CB_SCTLR, RACFG)
-#define GET_CB_SCTLR_WACFG(b, c)    GET_CONTEXT_FIELD(b, c, CB_SCTLR, WACFG)
-#define GET_CB_SCTLR_NSCFG(b, c)    GET_CONTEXT_FIELD(b, c, CB_SCTLR, NSCFG)
-
-/* Invalidate TLB by ASID: CB_TLBIASID */
-#define SET_CB_TLBIASID_ASID(b, c, v) \
-				SET_CONTEXT_FIELD(b, c, CB_TLBIASID, ASID, v)
-
-#define GET_CB_TLBIASID_ASID(b, c)    \
-				GET_CONTEXT_FIELD(b, c, CB_TLBIASID, ASID)
-
-/* Invalidate TLB by VA: CB_TLBIVA */
-#define SET_CB_TLBIVA_ASID(b, c, v) SET_CONTEXT_FIELD(b, c, CB_TLBIVA, ASID, v)
-#define SET_CB_TLBIVA_VA(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_TLBIVA, VA, v)
-
-#define GET_CB_TLBIVA_ASID(b, c)    GET_CONTEXT_FIELD(b, c, CB_TLBIVA, ASID)
-#define GET_CB_TLBIVA_VA(b, c)      GET_CONTEXT_FIELD(b, c, CB_TLBIVA, VA)
-
-/* Invalidate TLB by VA, All ASID: CB_TLBIVAA */
-#define SET_CB_TLBIVAA_VA(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_TLBIVAA, VA, v)
-
-#define GET_CB_TLBIVAA_VA(b, c)     GET_CONTEXT_FIELD(b, c, CB_TLBIVAA, VA)
-
-/* Invalidate TLB by VA, All ASID, Last Level: CB_TLBIVAAL */
-#define SET_CB_TLBIVAAL_VA(b, c, v) SET_CONTEXT_FIELD(b, c, CB_TLBIVAAL, VA, v)
-
-#define GET_CB_TLBIVAAL_VA(b, c)    GET_CONTEXT_FIELD(b, c, CB_TLBIVAAL, VA)
-
-/* Invalidate TLB by VA, Last Level: CB_TLBIVAL */
-#define SET_CB_TLBIVAL_ASID(b, c, v) \
-			SET_CONTEXT_FIELD(b, c, CB_TLBIVAL, ASID, v)
-#define SET_CB_TLBIVAL_VA(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_TLBIVAL, VA, v)
-
-#define GET_CB_TLBIVAL_ASID(b, c)    \
-			GET_CONTEXT_FIELD(b, c, CB_TLBIVAL, ASID)
-#define GET_CB_TLBIVAL_VA(b, c)      GET_CONTEXT_FIELD(b, c, CB_TLBIVAL, VA)
-
-/* TLB Status: CB_TLBSTATUS */
-#define SET_CB_TLBSTATUS_SACTIVE(b, c, v) \
-			SET_CONTEXT_FIELD(b, c, CB_TLBSTATUS, SACTIVE, v)
-
-#define GET_CB_TLBSTATUS_SACTIVE(b, c)    \
-			GET_CONTEXT_FIELD(b, c, CB_TLBSTATUS, SACTIVE)
-
-/* Translation Table Base Control Register: CB_TTBCR */
-#define SET_CB_TTBCR_T0SZ(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_TTBCR, T0SZ, v)
-#define SET_CB_TTBCR_PD0(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_TTBCR, PD0, v)
-#define SET_CB_TTBCR_PD1(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_TTBCR, PD1, v)
-#define SET_CB_TTBCR_NSCFG0(b, c, v) \
-			SET_CONTEXT_FIELD(b, c, CB_TTBCR, NSCFG0, v)
-#define SET_CB_TTBCR_NSCFG1(b, c, v) \
-			SET_CONTEXT_FIELD(b, c, CB_TTBCR, NSCFG1, v)
-#define SET_CB_TTBCR_EAE(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_TTBCR, EAE, v)
-
-#define GET_CB_TTBCR_T0SZ(b, c)      GET_CONTEXT_FIELD(b, c, CB_TTBCR, T0SZ)
-#define GET_CB_TTBCR_PD0(b, c)       GET_CONTEXT_FIELD(b, c, CB_TTBCR, PD0)
-#define GET_CB_TTBCR_PD1(b, c)       GET_CONTEXT_FIELD(b, c, CB_TTBCR, PD1)
-#define GET_CB_TTBCR_NSCFG0(b, c)    \
-			GET_CONTEXT_FIELD(b, c, CB_TTBCR, NSCFG0)
-#define GET_CB_TTBCR_NSCFG1(b, c)    \
-			GET_CONTEXT_FIELD(b, c, CB_TTBCR, NSCFG1)
-#define GET_CB_TTBCR_EAE(b, c)       GET_CONTEXT_FIELD(b, c, CB_TTBCR, EAE)
-
-/* Translation Table Base Register 0: CB_TTBR */
-#define SET_CB_TTBR0_IRGN1(b, c, v) SET_CONTEXT_FIELD(b, c, CB_TTBR0, IRGN1, v)
-#define SET_CB_TTBR0_S(b, c, v)     SET_CONTEXT_FIELD(b, c, CB_TTBR0, S, v)
-#define SET_CB_TTBR0_RGN(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_TTBR0, RGN, v)
-#define SET_CB_TTBR0_NOS(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_TTBR0, NOS, v)
-#define SET_CB_TTBR0_IRGN0(b, c, v) SET_CONTEXT_FIELD(b, c, CB_TTBR0, IRGN0, v)
-#define SET_CB_TTBR0_ADDR(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_TTBR0, ADDR, v)
-
-#define GET_CB_TTBR0_IRGN1(b, c)    GET_CONTEXT_FIELD(b, c, CB_TTBR0, IRGN1)
-#define GET_CB_TTBR0_S(b, c)        GET_CONTEXT_FIELD(b, c, CB_TTBR0, S)
-#define GET_CB_TTBR0_RGN(b, c)      GET_CONTEXT_FIELD(b, c, CB_TTBR0, RGN)
-#define GET_CB_TTBR0_NOS(b, c)      GET_CONTEXT_FIELD(b, c, CB_TTBR0, NOS)
-#define GET_CB_TTBR0_IRGN0(b, c)    GET_CONTEXT_FIELD(b, c, CB_TTBR0, IRGN0)
-#define GET_CB_TTBR0_ADDR(b, c)     GET_CONTEXT_FIELD(b, c, CB_TTBR0, ADDR)
-
-/* Translation Table Base Register 1: CB_TTBR1 */
-#define SET_CB_TTBR1_IRGN1(b, c, v) SET_CONTEXT_FIELD(b, c, CB_TTBR1, IRGN1, v)
-#define SET_CB_TTBR1_0S(b, c, v)    SET_CONTEXT_FIELD(b, c, CB_TTBR1, S, v)
-#define SET_CB_TTBR1_RGN(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_TTBR1, RGN, v)
-#define SET_CB_TTBR1_NOS(b, c, v)   SET_CONTEXT_FIELD(b, c, CB_TTBR1, NOS, v)
-#define SET_CB_TTBR1_IRGN0(b, c, v) SET_CONTEXT_FIELD(b, c, CB_TTBR1, IRGN0, v)
-#define SET_CB_TTBR1_ADDR(b, c, v)  SET_CONTEXT_FIELD(b, c, CB_TTBR1, ADDR, v)
-
-#define GET_CB_TTBR1_IRGN1(b, c)    GET_CONTEXT_FIELD(b, c, CB_TTBR1, IRGN1)
-#define GET_CB_TTBR1_0S(b, c)       GET_CONTEXT_FIELD(b, c, CB_TTBR1, S)
-#define GET_CB_TTBR1_RGN(b, c)      GET_CONTEXT_FIELD(b, c, CB_TTBR1, RGN)
-#define GET_CB_TTBR1_NOS(b, c)      GET_CONTEXT_FIELD(b, c, CB_TTBR1, NOS)
-#define GET_CB_TTBR1_IRGN0(b, c)    GET_CONTEXT_FIELD(b, c, CB_TTBR1, IRGN0)
-#define GET_CB_TTBR1_ADDR(b, c)     GET_CONTEXT_FIELD(b, c, CB_TTBR1, ADDR)
-
-/* Global Register Space 0 */
-#define CR0		(0x0000)
-#define SCR1		(0x0004)
-#define CR2		(0x0008)
-#define ACR		(0x0010)
-#define IDR0		(0x0020)
-#define IDR1		(0x0024)
-#define IDR2		(0x0028)
-#define IDR7		(0x003C)
-#define GFAR		(0x0040)
-#define GFSR		(0x0044)
-#define GFSRRESTORE	(0x004C)
-#define GFSYNR0		(0x0050)
-#define GFSYNR1		(0x0054)
-#define GFSYNR2		(0x0058)
-#define TLBIVMID	(0x0064)
-#define TLBIALLNSNH	(0x0068)
-#define TLBIALLH	(0x006C)
-#define TLBGSYNC	(0x0070)
-#define TLBGSTATUS	(0x0074)
-#define TLBIVAH		(0x0078)
-#define GATS1UR		(0x0100)
-#define GATS1UW		(0x0108)
-#define GATS1PR		(0x0110)
-#define GATS1PW		(0x0118)
-#define GATS12UR	(0x0120)
-#define GATS12UW	(0x0128)
-#define GATS12PR	(0x0130)
-#define GATS12PW	(0x0138)
-#define GPAR		(0x0180)
-#define GATSR		(0x0188)
-#define NSCR0		(0x0400)
-#define NSCR2		(0x0408)
-#define NSACR		(0x0410)
-#define SMR		(0x0800)
-#define S2CR		(0x0C00)
-
-/* Global Register Space 1 */
-#define CBAR		(0x1000)
-#define CBFRSYNRA	(0x1400)
-
-/* Implementation defined Register Space */
-#define PREDICTIONDIS0	(0x204C)
-#define PREDICTIONDIS1	(0x2050)
-#define S1L1BFBLP0	(0x215C)
-
-/* Performance Monitoring Register Space */
-#define PMEVCNTR_N	(0x3000)
-#define PMEVTYPER_N	(0x3400)
-#define PMCGCR_N	(0x3800)
-#define PMCGSMR_N	(0x3A00)
-#define PMCNTENSET_N	(0x3C00)
-#define PMCNTENCLR_N	(0x3C20)
-#define PMINTENSET_N	(0x3C40)
-#define PMINTENCLR_N	(0x3C60)
-#define PMOVSCLR_N	(0x3C80)
-#define PMOVSSET_N	(0x3CC0)
-#define PMCFGR		(0x3E00)
-#define PMCR		(0x3E04)
-#define PMCEID0		(0x3E20)
-#define PMCEID1		(0x3E24)
-#define PMAUTHSTATUS	(0x3FB8)
-#define PMDEVTYPE	(0x3FCC)
-
-/* Secure Status Determination Address Space */
-#define SSDR_N		(0x4000)
-
-/* Stage 1 Context Bank Format */
-#define CB_SCTLR	(0x000)
-#define CB_ACTLR	(0x004)
-#define CB_RESUME	(0x008)
-#define CB_TTBR0	(0x020)
-#define CB_TTBR1	(0x028)
-#define CB_TTBCR	(0x030)
-#define CB_CONTEXTIDR	(0x034)
-#define CB_PRRR		(0x038)
-#define CB_NMRR		(0x03C)
-#define CB_PAR		(0x050)
-#define CB_FSR		(0x058)
-#define CB_FSRRESTORE	(0x05C)
-#define CB_FAR		(0x060)
-#define CB_FSYNR0	(0x068)
-#define CB_FSYNR1	(0x06C)
-#define CB_TLBIVA	(0x600)
-#define CB_TLBIVAA	(0x608)
-#define CB_TLBIASID	(0x610)
-#define CB_TLBIALL	(0x618)
-#define CB_TLBIVAL	(0x620)
-#define CB_TLBIVAAL	(0x628)
-#define CB_TLBSYNC	(0x7F0)
-#define CB_TLBSTATUS	(0x7F4)
-#define CB_ATS1PR	(0x800)
-#define CB_ATS1PW	(0x808)
-#define CB_ATS1UR	(0x810)
-#define CB_ATS1UW	(0x818)
-#define CB_ATSR		(0x8F0)
-#define CB_PMXEVCNTR_N	(0xE00)
-#define CB_PMXEVTYPER_N	(0xE80)
-#define CB_PMCFGR	(0xF00)
-#define CB_PMCR		(0xF04)
-#define CB_PMCEID0	(0xF20)
-#define CB_PMCEID1	(0xF24)
-#define CB_PMCNTENSET	(0xF40)
-#define CB_PMCNTENCLR	(0xF44)
-#define CB_PMINTENSET	(0xF48)
-#define CB_PMINTENCLR	(0xF4C)
-#define CB_PMOVSCLR	(0xF50)
-#define CB_PMOVSSET	(0xF58)
-#define CB_PMAUTHSTATUS	(0xFB8)
-
-/* Global Register Fields */
-/* Configuration Register: CR0 */
-#define CR0_NSCFG         (CR0_NSCFG_MASK         << CR0_NSCFG_SHIFT)
-#define CR0_WACFG         (CR0_WACFG_MASK         << CR0_WACFG_SHIFT)
-#define CR0_RACFG         (CR0_RACFG_MASK         << CR0_RACFG_SHIFT)
-#define CR0_SHCFG         (CR0_SHCFG_MASK         << CR0_SHCFG_SHIFT)
-#define CR0_SMCFCFG       (CR0_SMCFCFG_MASK       << CR0_SMCFCFG_SHIFT)
-#define CR0_MTCFG         (CR0_MTCFG_MASK         << CR0_MTCFG_SHIFT)
-#define CR0_MEMATTR       (CR0_MEMATTR_MASK       << CR0_MEMATTR_SHIFT)
-#define CR0_BSU           (CR0_BSU_MASK           << CR0_BSU_SHIFT)
-#define CR0_FB            (CR0_FB_MASK            << CR0_FB_SHIFT)
-#define CR0_PTM           (CR0_PTM_MASK           << CR0_PTM_SHIFT)
-#define CR0_VMIDPNE       (CR0_VMIDPNE_MASK       << CR0_VMIDPNE_SHIFT)
-#define CR0_USFCFG        (CR0_USFCFG_MASK        << CR0_USFCFG_SHIFT)
-#define CR0_GSE           (CR0_GSE_MASK           << CR0_GSE_SHIFT)
-#define CR0_STALLD        (CR0_STALLD_MASK        << CR0_STALLD_SHIFT)
-#define CR0_TRANSIENTCFG  (CR0_TRANSIENTCFG_MASK  << CR0_TRANSIENTCFG_SHIFT)
-#define CR0_GCFGFIE       (CR0_GCFGFIE_MASK       << CR0_GCFGFIE_SHIFT)
-#define CR0_GCFGFRE       (CR0_GCFGFRE_MASK       << CR0_GCFGFRE_SHIFT)
-#define CR0_GFIE          (CR0_GFIE_MASK          << CR0_GFIE_SHIFT)
-#define CR0_GFRE          (CR0_GFRE_MASK          << CR0_GFRE_SHIFT)
-#define CR0_CLIENTPD      (CR0_CLIENTPD_MASK      << CR0_CLIENTPD_SHIFT)
-
-/* Configuration Register: CR2 */
-#define CR2_BPVMID        (CR2_BPVMID_MASK << CR2_BPVMID_SHIFT)
-
-/* Global Address Translation, Stage 1, Privileged Read: GATS1PR */
-#define GATS1PR_ADDR  (GATS1PR_ADDR_MASK  << GATS1PR_ADDR_SHIFT)
-#define GATS1PR_NDX   (GATS1PR_NDX_MASK   << GATS1PR_NDX_SHIFT)
-
-/* Global Address Translation, Stage 1, Privileged Write: GATS1PW */
-#define GATS1PW_ADDR  (GATS1PW_ADDR_MASK  << GATS1PW_ADDR_SHIFT)
-#define GATS1PW_NDX   (GATS1PW_NDX_MASK   << GATS1PW_NDX_SHIFT)
-
-/* Global Address Translation, Stage 1, User Read: GATS1UR */
-#define GATS1UR_ADDR  (GATS1UR_ADDR_MASK  << GATS1UR_ADDR_SHIFT)
-#define GATS1UR_NDX   (GATS1UR_NDX_MASK   << GATS1UR_NDX_SHIFT)
-
-/* Global Address Translation, Stage 1, User Write: GATS1UW */
-#define GATS1UW_ADDR  (GATS1UW_ADDR_MASK  << GATS1UW_ADDR_SHIFT)
-#define GATS1UW_NDX   (GATS1UW_NDX_MASK   << GATS1UW_NDX_SHIFT)
-
-/* Global Address Translation, Stage 1 and 2, Privileged Read: GATS1PR */
-#define GATS12PR_ADDR (GATS12PR_ADDR_MASK << GATS12PR_ADDR_SHIFT)
-#define GATS12PR_NDX  (GATS12PR_NDX_MASK  << GATS12PR_NDX_SHIFT)
-
-/* Global Address Translation, Stage 1 and 2, Privileged Write: GATS1PW */
-#define GATS12PW_ADDR (GATS12PW_ADDR_MASK << GATS12PW_ADDR_SHIFT)
-#define GATS12PW_NDX  (GATS12PW_NDX_MASK  << GATS12PW_NDX_SHIFT)
-
-/* Global Address Translation, Stage 1 and 2, User Read: GATS1UR */
-#define GATS12UR_ADDR (GATS12UR_ADDR_MASK << GATS12UR_ADDR_SHIFT)
-#define GATS12UR_NDX  (GATS12UR_NDX_MASK  << GATS12UR_NDX_SHIFT)
-
-/* Global Address Translation, Stage 1 and 2, User Write: GATS1UW */
-#define GATS12UW_ADDR (GATS12UW_ADDR_MASK << GATS12UW_ADDR_SHIFT)
-#define GATS12UW_NDX  (GATS12UW_NDX_MASK  << GATS12UW_NDX_SHIFT)
-
-/* Global Address Translation Status Register: GATSR */
-#define GATSR_ACTIVE  (GATSR_ACTIVE_MASK  << GATSR_ACTIVE_SHIFT)
-
-/* Global Fault Address Register: GFAR */
-#define GFAR_FADDR    (GFAR_FADDR_MASK << GFAR_FADDR_SHIFT)
-
-/* Global Fault Status Register: GFSR */
-#define GFSR_ICF      (GFSR_ICF_MASK   << GFSR_ICF_SHIFT)
-#define GFSR_USF      (GFSR_USF_MASK   << GFSR_USF_SHIFT)
-#define GFSR_SMCF     (GFSR_SMCF_MASK  << GFSR_SMCF_SHIFT)
-#define GFSR_UCBF     (GFSR_UCBF_MASK  << GFSR_UCBF_SHIFT)
-#define GFSR_UCIF     (GFSR_UCIF_MASK  << GFSR_UCIF_SHIFT)
-#define GFSR_CAF      (GFSR_CAF_MASK   << GFSR_CAF_SHIFT)
-#define GFSR_EF       (GFSR_EF_MASK    << GFSR_EF_SHIFT)
-#define GFSR_PF       (GFSR_PF_MASK    << GFSR_PF_SHIFT)
-#define GFSR_MULTI    (GFSR_MULTI_MASK << GFSR_MULTI_SHIFT)
-
-/* Global Fault Syndrome Register 0: GFSYNR0 */
-#define GFSYNR0_NESTED  (GFSYNR0_NESTED_MASK  << GFSYNR0_NESTED_SHIFT)
-#define GFSYNR0_WNR     (GFSYNR0_WNR_MASK     << GFSYNR0_WNR_SHIFT)
-#define GFSYNR0_PNU     (GFSYNR0_PNU_MASK     << GFSYNR0_PNU_SHIFT)
-#define GFSYNR0_IND     (GFSYNR0_IND_MASK     << GFSYNR0_IND_SHIFT)
-#define GFSYNR0_NSSTATE (GFSYNR0_NSSTATE_MASK << GFSYNR0_NSSTATE_SHIFT)
-#define GFSYNR0_NSATTR  (GFSYNR0_NSATTR_MASK  << GFSYNR0_NSATTR_SHIFT)
-
-/* Global Fault Syndrome Register 1: GFSYNR1 */
-#define GFSYNR1_SID     (GFSYNR1_SID_MASK     << GFSYNR1_SID_SHIFT)
-
-/* Global Physical Address Register: GPAR */
-#define GPAR_F          (GPAR_F_MASK      << GPAR_F_SHIFT)
-#define GPAR_SS         (GPAR_SS_MASK     << GPAR_SS_SHIFT)
-#define GPAR_OUTER      (GPAR_OUTER_MASK  << GPAR_OUTER_SHIFT)
-#define GPAR_INNER      (GPAR_INNER_MASK  << GPAR_INNER_SHIFT)
-#define GPAR_SH         (GPAR_SH_MASK     << GPAR_SH_SHIFT)
-#define GPAR_NS         (GPAR_NS_MASK     << GPAR_NS_SHIFT)
-#define GPAR_NOS        (GPAR_NOS_MASK    << GPAR_NOS_SHIFT)
-#define GPAR_PA         (GPAR_PA_MASK     << GPAR_PA_SHIFT)
-#define GPAR_TF         (GPAR_TF_MASK     << GPAR_TF_SHIFT)
-#define GPAR_AFF        (GPAR_AFF_MASK    << GPAR_AFF_SHIFT)
-#define GPAR_PF         (GPAR_PF_MASK     << GPAR_PF_SHIFT)
-#define GPAR_EF         (GPAR_EF_MASK     << GPAR_EF_SHIFT)
-#define GPAR_TLCMCF     (GPAR_TLBMCF_MASK << GPAR_TLCMCF_SHIFT)
-#define GPAR_TLBLKF     (GPAR_TLBLKF_MASK << GPAR_TLBLKF_SHIFT)
-#define GPAR_UCBF       (GPAR_UCBF_MASK   << GFAR_UCBF_SHIFT)
-
-/* Identification Register: IDR0 */
-#define IDR0_NUMSMRG    (IDR0_NUMSMRG_MASK  << IDR0_NUMSMGR_SHIFT)
-#define IDR0_NUMSIDB    (IDR0_NUMSIDB_MASK  << IDR0_NUMSIDB_SHIFT)
-#define IDR0_BTM        (IDR0_BTM_MASK      << IDR0_BTM_SHIFT)
-#define IDR0_CTTW       (IDR0_CTTW_MASK     << IDR0_CTTW_SHIFT)
-#define IDR0_NUMIRPT    (IDR0_NUMIPRT_MASK  << IDR0_NUMIRPT_SHIFT)
-#define IDR0_PTFS       (IDR0_PTFS_MASK     << IDR0_PTFS_SHIFT)
-#define IDR0_SMS        (IDR0_SMS_MASK      << IDR0_SMS_SHIFT)
-#define IDR0_NTS        (IDR0_NTS_MASK      << IDR0_NTS_SHIFT)
-#define IDR0_S2TS       (IDR0_S2TS_MASK     << IDR0_S2TS_SHIFT)
-#define IDR0_S1TS       (IDR0_S1TS_MASK     << IDR0_S1TS_SHIFT)
-#define IDR0_SES        (IDR0_SES_MASK      << IDR0_SES_SHIFT)
-
-/* Identification Register: IDR1 */
-#define IDR1_NUMCB       (IDR1_NUMCB_MASK       << IDR1_NUMCB_SHIFT)
-#define IDR1_NUMSSDNDXB  (IDR1_NUMSSDNDXB_MASK  << IDR1_NUMSSDNDXB_SHIFT)
-#define IDR1_SSDTP       (IDR1_SSDTP_MASK       << IDR1_SSDTP_SHIFT)
-#define IDR1_SMCD        (IDR1_SMCD_MASK        << IDR1_SMCD_SHIFT)
-#define IDR1_NUMS2CB     (IDR1_NUMS2CB_MASK     << IDR1_NUMS2CB_SHIFT)
-#define IDR1_NUMPAGENDXB (IDR1_NUMPAGENDXB_MASK << IDR1_NUMPAGENDXB_SHIFT)
-#define IDR1_PAGESIZE    (IDR1_PAGESIZE_MASK    << IDR1_PAGESIZE_SHIFT)
-
-/* Identification Register: IDR2 */
-#define IDR2_IAS         (IDR2_IAS_MASK << IDR2_IAS_SHIFT)
-#define IDR1_OAS         (IDR2_OAS_MASK << IDR2_OAS_SHIFT)
-
-/* Identification Register: IDR7 */
-#define IDR7_MINOR       (IDR7_MINOR_MASK << IDR7_MINOR_SHIFT)
-#define IDR7_MAJOR       (IDR7_MAJOR_MASK << IDR7_MAJOR_SHIFT)
-
-/* Stream to Context Register: S2CR */
-#define S2CR_CBNDX        (S2CR_CBNDX_MASK         << S2cR_CBNDX_SHIFT)
-#define S2CR_SHCFG        (S2CR_SHCFG_MASK         << s2CR_SHCFG_SHIFT)
-#define S2CR_MTCFG        (S2CR_MTCFG_MASK         << S2CR_MTCFG_SHIFT)
-#define S2CR_MEMATTR      (S2CR_MEMATTR_MASK       << S2CR_MEMATTR_SHIFT)
-#define S2CR_TYPE         (S2CR_TYPE_MASK          << S2CR_TYPE_SHIFT)
-#define S2CR_NSCFG        (S2CR_NSCFG_MASK         << S2CR_NSCFG_SHIFT)
-#define S2CR_RACFG        (S2CR_RACFG_MASK         << S2CR_RACFG_SHIFT)
-#define S2CR_WACFG        (S2CR_WACFG_MASK         << S2CR_WACFG_SHIFT)
-#define S2CR_PRIVCFG      (S2CR_PRIVCFG_MASK       << S2CR_PRIVCFG_SHIFT)
-#define S2CR_INSTCFG      (S2CR_INSTCFG_MASK       << S2CR_INSTCFG_SHIFT)
-#define S2CR_TRANSIENTCFG (S2CR_TRANSIENTCFG_MASK  << S2CR_TRANSIENTCFG_SHIFT)
-#define S2CR_VMID         (S2CR_VMID_MASK          << S2CR_VMID_SHIFT)
-#define S2CR_BSU          (S2CR_BSU_MASK           << S2CR_BSU_SHIFT)
-#define S2CR_FB           (S2CR_FB_MASK            << S2CR_FB_SHIFT)
-
-/* Stream Match Register: SMR */
-#define SMR_ID            (SMR_ID_MASK    << SMR_ID_SHIFT)
-#define SMR_MASK          (SMR_MASK_MASK  << SMR_MASK_SHIFT)
-#define SMR_VALID         (SMR_VALID_MASK << SMR_VALID_SHIFT)
-
-/* Global TLB Status: TLBGSTATUS */
-#define TLBGSTATUS_GSACTIVE (TLBGSTATUS_GSACTIVE_MASK << \
-					TLBGSTATUS_GSACTIVE_SHIFT)
-/* Invalidate Hyp TLB by VA: TLBIVAH */
-#define TLBIVAH_ADDR  (TLBIVAH_ADDR_MASK << TLBIVAH_ADDR_SHIFT)
-
-/* Invalidate TLB by VMID: TLBIVMID */
-#define TLBIVMID_VMID (TLBIVMID_VMID_MASK << TLBIVMID_VMID_SHIFT)
-
-/* Context Bank Attribute Register: CBAR */
-#define CBAR_VMID       (CBAR_VMID_MASK    << CBAR_VMID_SHIFT)
-#define CBAR_CBNDX      (CBAR_CBNDX_MASK   << CBAR_CBNDX_SHIFT)
-#define CBAR_BPSHCFG    (CBAR_BPSHCFG_MASK << CBAR_BPSHCFG_SHIFT)
-#define CBAR_HYPC       (CBAR_HYPC_MASK    << CBAR_HYPC_SHIFT)
-#define CBAR_FB         (CBAR_FB_MASK      << CBAR_FB_SHIFT)
-#define CBAR_MEMATTR    (CBAR_MEMATTR_MASK << CBAR_MEMATTR_SHIFT)
-#define CBAR_TYPE       (CBAR_TYPE_MASK    << CBAR_TYPE_SHIFT)
-#define CBAR_BSU        (CBAR_BSU_MASK     << CBAR_BSU_SHIFT)
-#define CBAR_RACFG      (CBAR_RACFG_MASK   << CBAR_RACFG_SHIFT)
-#define CBAR_WACFG      (CBAR_WACFG_MASK   << CBAR_WACFG_SHIFT)
-#define CBAR_IRPTNDX    (CBAR_IRPTNDX_MASK << CBAR_IRPTNDX_SHIFT)
-
-/* Context Bank Fault Restricted Syndrome Register A: CBFRSYNRA */
-#define CBFRSYNRA_SID   (CBFRSYNRA_SID_MASK << CBFRSYNRA_SID_SHIFT)
-
-/* Performance Monitoring Register Fields */
-
-/* Stage 1 Context Bank Format Fields */
-/* Auxiliary Control Register: CB_ACTLR */
-#define CB_ACTLR_REQPRIORITY \
-		(CB_ACTLR_REQPRIORITY_MASK << CB_ACTLR_REQPRIORITY_SHIFT)
-#define CB_ACTLR_REQPRIORITYCFG \
-		(CB_ACTLR_REQPRIORITYCFG_MASK << CB_ACTLR_REQPRIORITYCFG_SHIFT)
-#define CB_ACTLR_PRIVCFG (CB_ACTLR_PRIVCFG_MASK << CB_ACTLR_PRIVCFG_SHIFT)
-#define CB_ACTLR_BPRCOSH (CB_ACTLR_BPRCOSH_MASK << CB_ACTLR_BPRCOSH_SHIFT)
-#define CB_ACTLR_BPRCISH (CB_ACTLR_BPRCISH_MASK << CB_ACTLR_BPRCISH_SHIFT)
-#define CB_ACTLR_BPRCNSH (CB_ACTLR_BPRCNSH_MASK << CB_ACTLR_BPRCNSH_SHIFT)
-
-/* Address Translation, Stage 1, Privileged Read: CB_ATS1PR */
-#define CB_ATS1PR_ADDR  (CB_ATS1PR_ADDR_MASK << CB_ATS1PR_ADDR_SHIFT)
-
-/* Address Translation, Stage 1, Privileged Write: CB_ATS1PW */
-#define CB_ATS1PW_ADDR  (CB_ATS1PW_ADDR_MASK << CB_ATS1PW_ADDR_SHIFT)
-
-/* Address Translation, Stage 1, User Read: CB_ATS1UR */
-#define CB_ATS1UR_ADDR  (CB_ATS1UR_ADDR_MASK << CB_ATS1UR_ADDR_SHIFT)
-
-/* Address Translation, Stage 1, User Write: CB_ATS1UW */
-#define CB_ATS1UW_ADDR  (CB_ATS1UW_ADDR_MASK << CB_ATS1UW_ADDR_SHIFT)
-
-/* Address Translation Status Register: CB_ATSR */
-#define CB_ATSR_ACTIVE  (CB_ATSR_ACTIVE_MASK << CB_ATSR_ACTIVE_SHIFT)
-
-/* Context ID Register: CB_CONTEXTIDR */
-#define CB_CONTEXTIDR_ASID    (CB_CONTEXTIDR_ASID_MASK << \
-				CB_CONTEXTIDR_ASID_SHIFT)
-#define CB_CONTEXTIDR_PROCID  (CB_CONTEXTIDR_PROCID_MASK << \
-				CB_CONTEXTIDR_PROCID_SHIFT)
-
-/* Fault Address Register: CB_FAR */
-#define CB_FAR_FADDR  (CB_FAR_FADDR_MASK << CB_FAR_FADDR_SHIFT)
-
-/* Fault Status Register: CB_FSR */
-#define CB_FSR_TF     (CB_FSR_TF_MASK     << CB_FSR_TF_SHIFT)
-#define CB_FSR_AFF    (CB_FSR_AFF_MASK    << CB_FSR_AFF_SHIFT)
-#define CB_FSR_PF     (CB_FSR_PF_MASK     << CB_FSR_PF_SHIFT)
-#define CB_FSR_EF     (CB_FSR_EF_MASK     << CB_FSR_EF_SHIFT)
-#define CB_FSR_TLBMCF (CB_FSR_TLBMCF_MASK << CB_FSR_TLBMCF_SHIFT)
-#define CB_FSR_TLBLKF (CB_FSR_TLBLKF_MASK << CB_FSR_TLBLKF_SHIFT)
-#define CB_FSR_SS     (CB_FSR_SS_MASK     << CB_FSR_SS_SHIFT)
-#define CB_FSR_MULTI  (CB_FSR_MULTI_MASK  << CB_FSR_MULTI_SHIFT)
-
-/* Fault Syndrome Register 0: CB_FSYNR0 */
-#define CB_FSYNR0_PLVL     (CB_FSYNR0_PLVL_MASK    << CB_FSYNR0_PLVL_SHIFT)
-#define CB_FSYNR0_S1PTWF   (CB_FSYNR0_S1PTWF_MASK  << CB_FSYNR0_S1PTWF_SHIFT)
-#define CB_FSYNR0_WNR      (CB_FSYNR0_WNR_MASK     << CB_FSYNR0_WNR_SHIFT)
-#define CB_FSYNR0_PNU      (CB_FSYNR0_PNU_MASK     << CB_FSYNR0_PNU_SHIFT)
-#define CB_FSYNR0_IND      (CB_FSYNR0_IND_MASK     << CB_FSYNR0_IND_SHIFT)
-#define CB_FSYNR0_NSSTATE  (CB_FSYNR0_NSSTATE_MASK << CB_FSYNR0_NSSTATE_SHIFT)
-#define CB_FSYNR0_NSATTR   (CB_FSYNR0_NSATTR_MASK  << CB_FSYNR0_NSATTR_SHIFT)
-#define CB_FSYNR0_ATOF     (CB_FSYNR0_ATOF_MASK    << CB_FSYNR0_ATOF_SHIFT)
-#define CB_FSYNR0_PTWF     (CB_FSYNR0_PTWF_MASK    << CB_FSYNR0_PTWF_SHIFT)
-#define CB_FSYNR0_AFR      (CB_FSYNR0_AFR_MASK     << CB_FSYNR0_AFR_SHIFT)
-#define CB_FSYNR0_S1CBNDX  (CB_FSYNR0_S1CBNDX_MASK << CB_FSYNR0_S1CBNDX_SHIFT)
-
-/* Normal Memory Remap Register: CB_NMRR */
-#define CB_NMRR_IR0        (CB_NMRR_IR0_MASK   << CB_NMRR_IR0_SHIFT)
-#define CB_NMRR_IR1        (CB_NMRR_IR1_MASK   << CB_NMRR_IR1_SHIFT)
-#define CB_NMRR_IR2        (CB_NMRR_IR2_MASK   << CB_NMRR_IR2_SHIFT)
-#define CB_NMRR_IR3        (CB_NMRR_IR3_MASK   << CB_NMRR_IR3_SHIFT)
-#define CB_NMRR_IR4        (CB_NMRR_IR4_MASK   << CB_NMRR_IR4_SHIFT)
-#define CB_NMRR_IR5        (CB_NMRR_IR5_MASK   << CB_NMRR_IR5_SHIFT)
-#define CB_NMRR_IR6        (CB_NMRR_IR6_MASK   << CB_NMRR_IR6_SHIFT)
-#define CB_NMRR_IR7        (CB_NMRR_IR7_MASK   << CB_NMRR_IR7_SHIFT)
-#define CB_NMRR_OR0        (CB_NMRR_OR0_MASK   << CB_NMRR_OR0_SHIFT)
-#define CB_NMRR_OR1        (CB_NMRR_OR1_MASK   << CB_NMRR_OR1_SHIFT)
-#define CB_NMRR_OR2        (CB_NMRR_OR2_MASK   << CB_NMRR_OR2_SHIFT)
-#define CB_NMRR_OR3        (CB_NMRR_OR3_MASK   << CB_NMRR_OR3_SHIFT)
-#define CB_NMRR_OR4        (CB_NMRR_OR4_MASK   << CB_NMRR_OR4_SHIFT)
-#define CB_NMRR_OR5        (CB_NMRR_OR5_MASK   << CB_NMRR_OR5_SHIFT)
-#define CB_NMRR_OR6        (CB_NMRR_OR6_MASK   << CB_NMRR_OR6_SHIFT)
-#define CB_NMRR_OR7        (CB_NMRR_OR7_MASK   << CB_NMRR_OR7_SHIFT)
-
-/* Physical Address Register: CB_PAR */
-#define CB_PAR_F           (CB_PAR_F_MASK      << CB_PAR_F_SHIFT)
-#define CB_PAR_SS          (CB_PAR_SS_MASK     << CB_PAR_SS_SHIFT)
-#define CB_PAR_OUTER       (CB_PAR_OUTER_MASK  << CB_PAR_OUTER_SHIFT)
-#define CB_PAR_INNER       (CB_PAR_INNER_MASK  << CB_PAR_INNER_SHIFT)
-#define CB_PAR_SH          (CB_PAR_SH_MASK     << CB_PAR_SH_SHIFT)
-#define CB_PAR_NS          (CB_PAR_NS_MASK     << CB_PAR_NS_SHIFT)
-#define CB_PAR_NOS         (CB_PAR_NOS_MASK    << CB_PAR_NOS_SHIFT)
-#define CB_PAR_PA          (CB_PAR_PA_MASK     << CB_PAR_PA_SHIFT)
-#define CB_PAR_TF          (CB_PAR_TF_MASK     << CB_PAR_TF_SHIFT)
-#define CB_PAR_AFF         (CB_PAR_AFF_MASK    << CB_PAR_AFF_SHIFT)
-#define CB_PAR_PF          (CB_PAR_PF_MASK     << CB_PAR_PF_SHIFT)
-#define CB_PAR_TLBMCF      (CB_PAR_TLBMCF_MASK << CB_PAR_TLBMCF_SHIFT)
-#define CB_PAR_TLBLKF      (CB_PAR_TLBLKF_MASK << CB_PAR_TLBLKF_SHIFT)
-#define CB_PAR_ATOT        (CB_PAR_ATOT_MASK   << CB_PAR_ATOT_SHIFT)
-#define CB_PAR_PLVL        (CB_PAR_PLVL_MASK   << CB_PAR_PLVL_SHIFT)
-#define CB_PAR_STAGE       (CB_PAR_STAGE_MASK  << CB_PAR_STAGE_SHIFT)
-
-/* Primary Region Remap Register: CB_PRRR */
-#define CB_PRRR_TR0        (CB_PRRR_TR0_MASK   << CB_PRRR_TR0_SHIFT)
-#define CB_PRRR_TR1        (CB_PRRR_TR1_MASK   << CB_PRRR_TR1_SHIFT)
-#define CB_PRRR_TR2        (CB_PRRR_TR2_MASK   << CB_PRRR_TR2_SHIFT)
-#define CB_PRRR_TR3        (CB_PRRR_TR3_MASK   << CB_PRRR_TR3_SHIFT)
-#define CB_PRRR_TR4        (CB_PRRR_TR4_MASK   << CB_PRRR_TR4_SHIFT)
-#define CB_PRRR_TR5        (CB_PRRR_TR5_MASK   << CB_PRRR_TR5_SHIFT)
-#define CB_PRRR_TR6        (CB_PRRR_TR6_MASK   << CB_PRRR_TR6_SHIFT)
-#define CB_PRRR_TR7        (CB_PRRR_TR7_MASK   << CB_PRRR_TR7_SHIFT)
-#define CB_PRRR_DS0        (CB_PRRR_DS0_MASK   << CB_PRRR_DS0_SHIFT)
-#define CB_PRRR_DS1        (CB_PRRR_DS1_MASK   << CB_PRRR_DS1_SHIFT)
-#define CB_PRRR_NS0        (CB_PRRR_NS0_MASK   << CB_PRRR_NS0_SHIFT)
-#define CB_PRRR_NS1        (CB_PRRR_NS1_MASK   << CB_PRRR_NS1_SHIFT)
-#define CB_PRRR_NOS0       (CB_PRRR_NOS0_MASK  << CB_PRRR_NOS0_SHIFT)
-#define CB_PRRR_NOS1       (CB_PRRR_NOS1_MASK  << CB_PRRR_NOS1_SHIFT)
-#define CB_PRRR_NOS2       (CB_PRRR_NOS2_MASK  << CB_PRRR_NOS2_SHIFT)
-#define CB_PRRR_NOS3       (CB_PRRR_NOS3_MASK  << CB_PRRR_NOS3_SHIFT)
-#define CB_PRRR_NOS4       (CB_PRRR_NOS4_MASK  << CB_PRRR_NOS4_SHIFT)
-#define CB_PRRR_NOS5       (CB_PRRR_NOS5_MASK  << CB_PRRR_NOS5_SHIFT)
-#define CB_PRRR_NOS6       (CB_PRRR_NOS6_MASK  << CB_PRRR_NOS6_SHIFT)
-#define CB_PRRR_NOS7       (CB_PRRR_NOS7_MASK  << CB_PRRR_NOS7_SHIFT)
-
-/* Transaction Resume: CB_RESUME */
-#define CB_RESUME_TNR      (CB_RESUME_TNR_MASK << CB_RESUME_TNR_SHIFT)
-
-/* System Control Register: CB_SCTLR */
-#define CB_SCTLR_M           (CB_SCTLR_M_MASK       << CB_SCTLR_M_SHIFT)
-#define CB_SCTLR_TRE         (CB_SCTLR_TRE_MASK     << CB_SCTLR_TRE_SHIFT)
-#define CB_SCTLR_AFE         (CB_SCTLR_AFE_MASK     << CB_SCTLR_AFE_SHIFT)
-#define CB_SCTLR_AFFD        (CB_SCTLR_AFFD_MASK    << CB_SCTLR_AFFD_SHIFT)
-#define CB_SCTLR_E           (CB_SCTLR_E_MASK       << CB_SCTLR_E_SHIFT)
-#define CB_SCTLR_CFRE        (CB_SCTLR_CFRE_MASK    << CB_SCTLR_CFRE_SHIFT)
-#define CB_SCTLR_CFIE        (CB_SCTLR_CFIE_MASK    << CB_SCTLR_CFIE_SHIFT)
-#define CB_SCTLR_CFCFG       (CB_SCTLR_CFCFG_MASK   << CB_SCTLR_CFCFG_SHIFT)
-#define CB_SCTLR_HUPCF       (CB_SCTLR_HUPCF_MASK   << CB_SCTLR_HUPCF_SHIFT)
-#define CB_SCTLR_WXN         (CB_SCTLR_WXN_MASK     << CB_SCTLR_WXN_SHIFT)
-#define CB_SCTLR_UWXN        (CB_SCTLR_UWXN_MASK    << CB_SCTLR_UWXN_SHIFT)
-#define CB_SCTLR_ASIDPNE     (CB_SCTLR_ASIDPNE_MASK << CB_SCTLR_ASIDPNE_SHIFT)
-#define CB_SCTLR_TRANSIENTCFG (CB_SCTLR_TRANSIENTCFG_MASK << \
-						CB_SCTLR_TRANSIENTCFG_SHIFT)
-#define CB_SCTLR_MEMATTR     (CB_SCTLR_MEMATTR_MASK << CB_SCTLR_MEMATTR_SHIFT)
-#define CB_SCTLR_MTCFG       (CB_SCTLR_MTCFG_MASK   << CB_SCTLR_MTCFG_SHIFT)
-#define CB_SCTLR_SHCFG       (CB_SCTLR_SHCFG_MASK   << CB_SCTLR_SHCFG_SHIFT)
-#define CB_SCTLR_RACFG       (CB_SCTLR_RACFG_MASK   << CB_SCTLR_RACFG_SHIFT)
-#define CB_SCTLR_WACFG       (CB_SCTLR_WACFG_MASK   << CB_SCTLR_WACFG_SHIFT)
-#define CB_SCTLR_NSCFG       (CB_SCTLR_NSCFG_MASK   << CB_SCTLR_NSCFG_SHIFT)
-
-/* Invalidate TLB by ASID: CB_TLBIASID */
-#define CB_TLBIASID_ASID     (CB_TLBIASID_ASID_MASK << CB_TLBIASID_ASID_SHIFT)
-
-/* Invalidate TLB by VA: CB_TLBIVA */
-#define CB_TLBIVA_ASID       (CB_TLBIVA_ASID_MASK   << CB_TLBIVA_ASID_SHIFT)
-#define CB_TLBIVA_VA         (CB_TLBIVA_VA_MASK     << CB_TLBIVA_VA_SHIFT)
-
-/* Invalidate TLB by VA, All ASID: CB_TLBIVAA */
-#define CB_TLBIVAA_VA        (CB_TLBIVAA_VA_MASK    << CB_TLBIVAA_VA_SHIFT)
-
-/* Invalidate TLB by VA, All ASID, Last Level: CB_TLBIVAAL */
-#define CB_TLBIVAAL_VA       (CB_TLBIVAAL_VA_MASK   << CB_TLBIVAAL_VA_SHIFT)
-
-/* Invalidate TLB by VA, Last Level: CB_TLBIVAL */
-#define CB_TLBIVAL_ASID      (CB_TLBIVAL_ASID_MASK  << CB_TLBIVAL_ASID_SHIFT)
-#define CB_TLBIVAL_VA        (CB_TLBIVAL_VA_MASK    << CB_TLBIVAL_VA_SHIFT)
-
-/* TLB Status: CB_TLBSTATUS */
-#define CB_TLBSTATUS_SACTIVE (CB_TLBSTATUS_SACTIVE_MASK << \
-						CB_TLBSTATUS_SACTIVE_SHIFT)
-
-/* Translation Table Base Control Register: CB_TTBCR */
-#define CB_TTBCR_T0SZ        (CB_TTBCR_T0SZ_MASK    << CB_TTBCR_T0SZ_SHIFT)
-#define CB_TTBCR_PD0         (CB_TTBCR_PD0_MASK     << CB_TTBCR_PD0_SHIFT)
-#define CB_TTBCR_PD1         (CB_TTBCR_PD1_MASK     << CB_TTBCR_PD1_SHIFT)
-#define CB_TTBCR_NSCFG0      (CB_TTBCR_NSCFG0_MASK  << CB_TTBCR_NSCFG0_SHIFT)
-#define CB_TTBCR_NSCFG1      (CB_TTBCR_NSCFG1_MASK  << CB_TTBCR_NSCFG1_SHIFT)
-#define CB_TTBCR_EAE         (CB_TTBCR_EAE_MASK     << CB_TTBCR_EAE_SHIFT)
-
-/* Translation Table Base Register 0: CB_TTBR0 */
-#define CB_TTBR0_IRGN1       (CB_TTBR0_IRGN1_MASK   << CB_TTBR0_IRGN1_SHIFT)
-#define CB_TTBR0_S           (CB_TTBR0_S_MASK       << CB_TTBR0_S_SHIFT)
-#define CB_TTBR0_RGN         (CB_TTBR0_RGN_MASK     << CB_TTBR0_RGN_SHIFT)
-#define CB_TTBR0_NOS         (CB_TTBR0_NOS_MASK     << CB_TTBR0_NOS_SHIFT)
-#define CB_TTBR0_IRGN0       (CB_TTBR0_IRGN0_MASK   << CB_TTBR0_IRGN0_SHIFT)
-#define CB_TTBR0_ADDR        (CB_TTBR0_ADDR_MASK    << CB_TTBR0_ADDR_SHIFT)
-
-/* Translation Table Base Register 1: CB_TTBR1 */
-#define CB_TTBR1_IRGN1       (CB_TTBR1_IRGN1_MASK   << CB_TTBR1_IRGN1_SHIFT)
-#define CB_TTBR1_S           (CB_TTBR1_S_MASK       << CB_TTBR1_S_SHIFT)
-#define CB_TTBR1_RGN         (CB_TTBR1_RGN_MASK     << CB_TTBR1_RGN_SHIFT)
-#define CB_TTBR1_NOS         (CB_TTBR1_NOS_MASK     << CB_TTBR1_NOS_SHIFT)
-#define CB_TTBR1_IRGN0       (CB_TTBR1_IRGN0_MASK   << CB_TTBR1_IRGN0_SHIFT)
-#define CB_TTBR1_ADDR        (CB_TTBR1_ADDR_MASK    << CB_TTBR1_ADDR_SHIFT)
-
-/* Global Register Masks */
-/* Configuration Register 0 */
-#define CR0_NSCFG_MASK          0x03
-#define CR0_WACFG_MASK          0x03
-#define CR0_RACFG_MASK          0x03
-#define CR0_SHCFG_MASK          0x03
-#define CR0_SMCFCFG_MASK        0x01
-#define CR0_MTCFG_MASK          0x01
-#define CR0_MEMATTR_MASK        0x0F
-#define CR0_BSU_MASK            0x03
-#define CR0_FB_MASK             0x01
-#define CR0_PTM_MASK            0x01
-#define CR0_VMIDPNE_MASK        0x01
-#define CR0_USFCFG_MASK         0x01
-#define CR0_GSE_MASK            0x01
-#define CR0_STALLD_MASK         0x01
-#define CR0_TRANSIENTCFG_MASK   0x03
-#define CR0_GCFGFIE_MASK        0x01
-#define CR0_GCFGFRE_MASK        0x01
-#define CR0_GFIE_MASK           0x01
-#define CR0_GFRE_MASK           0x01
-#define CR0_CLIENTPD_MASK       0x01
-
-/* Configuration Register 2 */
-#define CR2_BPVMID_MASK         0xFF
-
-/* Global Address Translation, Stage 1, Privileged Read: GATS1PR */
-#define GATS1PR_ADDR_MASK       0xFFFFF
-#define GATS1PR_NDX_MASK        0xFF
-
-/* Global Address Translation, Stage 1, Privileged Write: GATS1PW */
-#define GATS1PW_ADDR_MASK       0xFFFFF
-#define GATS1PW_NDX_MASK        0xFF
-
-/* Global Address Translation, Stage 1, User Read: GATS1UR */
-#define GATS1UR_ADDR_MASK       0xFFFFF
-#define GATS1UR_NDX_MASK        0xFF
-
-/* Global Address Translation, Stage 1, User Write: GATS1UW */
-#define GATS1UW_ADDR_MASK       0xFFFFF
-#define GATS1UW_NDX_MASK        0xFF
-
-/* Global Address Translation, Stage 1 and 2, Privileged Read: GATS1PR */
-#define GATS12PR_ADDR_MASK      0xFFFFF
-#define GATS12PR_NDX_MASK       0xFF
-
-/* Global Address Translation, Stage 1 and 2, Privileged Write: GATS1PW */
-#define GATS12PW_ADDR_MASK      0xFFFFF
-#define GATS12PW_NDX_MASK       0xFF
-
-/* Global Address Translation, Stage 1 and 2, User Read: GATS1UR */
-#define GATS12UR_ADDR_MASK      0xFFFFF
-#define GATS12UR_NDX_MASK       0xFF
-
-/* Global Address Translation, Stage 1 and 2, User Write: GATS1UW */
-#define GATS12UW_ADDR_MASK      0xFFFFF
-#define GATS12UW_NDX_MASK       0xFF
-
-/* Global Address Translation Status Register: GATSR */
-#define GATSR_ACTIVE_MASK       0x01
-
-/* Global Fault Address Register: GFAR */
-#define GFAR_FADDR_MASK         0xFFFFFFFF
-
-/* Global Fault Status Register: GFSR */
-#define GFSR_ICF_MASK           0x01
-#define GFSR_USF_MASK           0x01
-#define GFSR_SMCF_MASK          0x01
-#define GFSR_UCBF_MASK          0x01
-#define GFSR_UCIF_MASK          0x01
-#define GFSR_CAF_MASK           0x01
-#define GFSR_EF_MASK            0x01
-#define GFSR_PF_MASK            0x01
-#define GFSR_MULTI_MASK         0x01
-
-/* Global Fault Syndrome Register 0: GFSYNR0 */
-#define GFSYNR0_NESTED_MASK     0x01
-#define GFSYNR0_WNR_MASK        0x01
-#define GFSYNR0_PNU_MASK        0x01
-#define GFSYNR0_IND_MASK        0x01
-#define GFSYNR0_NSSTATE_MASK    0x01
-#define GFSYNR0_NSATTR_MASK     0x01
-
-/* Global Fault Syndrome Register 1: GFSYNR1 */
-#define GFSYNR1_SID_MASK        0x7FFF
-#define GFSYNr1_SSD_IDX_MASK    0x7FFF
-
-/* Global Physical Address Register: GPAR */
-#define GPAR_F_MASK             0x01
-#define GPAR_SS_MASK            0x01
-#define GPAR_OUTER_MASK         0x03
-#define GPAR_INNER_MASK         0x03
-#define GPAR_SH_MASK            0x01
-#define GPAR_NS_MASK            0x01
-#define GPAR_NOS_MASK           0x01
-#define GPAR_PA_MASK            0xFFFFF
-#define GPAR_TF_MASK            0x01
-#define GPAR_AFF_MASK           0x01
-#define GPAR_PF_MASK            0x01
-#define GPAR_EF_MASK            0x01
-#define GPAR_TLBMCF_MASK        0x01
-#define GPAR_TLBLKF_MASK        0x01
-#define GPAR_UCBF_MASK          0x01
-
-/* Identification Register: IDR0 */
-#define IDR0_NUMSMRG_MASK       0xFF
-#define IDR0_NUMSIDB_MASK       0x0F
-#define IDR0_BTM_MASK           0x01
-#define IDR0_CTTW_MASK          0x01
-#define IDR0_NUMIPRT_MASK       0xFF
-#define IDR0_PTFS_MASK          0x01
-#define IDR0_SMS_MASK           0x01
-#define IDR0_NTS_MASK           0x01
-#define IDR0_S2TS_MASK          0x01
-#define IDR0_S1TS_MASK          0x01
-#define IDR0_SES_MASK           0x01
-
-/* Identification Register: IDR1 */
-#define IDR1_NUMCB_MASK         0xFF
-#define IDR1_NUMSSDNDXB_MASK    0x0F
-#define IDR1_SSDTP_MASK         0x01
-#define IDR1_SMCD_MASK          0x01
-#define IDR1_NUMS2CB_MASK       0xFF
-#define IDR1_NUMPAGENDXB_MASK   0x07
-#define IDR1_PAGESIZE_MASK      0x01
-
-/* Identification Register: IDR2 */
-#define IDR2_IAS_MASK           0x0F
-#define IDR2_OAS_MASK           0x0F
-
-/* Identification Register: IDR7 */
-#define IDR7_MINOR_MASK         0x0F
-#define IDR7_MAJOR_MASK         0x0F
-
-/* Stream to Context Register: S2CR */
-#define S2CR_CBNDX_MASK         0xFF
-#define S2CR_SHCFG_MASK         0x03
-#define S2CR_MTCFG_MASK         0x01
-#define S2CR_MEMATTR_MASK       0x0F
-#define S2CR_TYPE_MASK          0x03
-#define S2CR_NSCFG_MASK         0x03
-#define S2CR_RACFG_MASK         0x03
-#define S2CR_WACFG_MASK         0x03
-#define S2CR_PRIVCFG_MASK       0x03
-#define S2CR_INSTCFG_MASK       0x03
-#define S2CR_TRANSIENTCFG_MASK  0x03
-#define S2CR_VMID_MASK          0xFF
-#define S2CR_BSU_MASK           0x03
-#define S2CR_FB_MASK            0x01
-
-/* Stream Match Register: SMR */
-#define SMR_ID_MASK             0x7FFF
-#define SMR_MASK_MASK           0x7FFF
-#define SMR_VALID_MASK          0x01
-
-/* Global TLB Status: TLBGSTATUS */
-#define TLBGSTATUS_GSACTIVE_MASK 0x01
-
-/* Invalidate Hyp TLB by VA: TLBIVAH */
-#define TLBIVAH_ADDR_MASK       0xFFFFF
-
-/* Invalidate TLB by VMID: TLBIVMID */
-#define TLBIVMID_VMID_MASK      0xFF
-
-/* Global Register Space 1 Mask */
-/* Context Bank Attribute Register: CBAR */
-#define CBAR_VMID_MASK          0xFF
-#define CBAR_CBNDX_MASK         0x03
-#define CBAR_BPSHCFG_MASK       0x03
-#define CBAR_HYPC_MASK          0x01
-#define CBAR_FB_MASK            0x01
-#define CBAR_MEMATTR_MASK       0x0F
-#define CBAR_TYPE_MASK          0x03
-#define CBAR_BSU_MASK           0x03
-#define CBAR_RACFG_MASK         0x03
-#define CBAR_WACFG_MASK         0x03
-#define CBAR_IRPTNDX_MASK       0xFF
-
-/* Context Bank Fault Restricted Syndrome Register A: CBFRSYNRA */
-#define CBFRSYNRA_SID_MASK      0x7FFF
-
-/* Stage 1 Context Bank Format Masks */
-/* Auxiliary Control Register: CB_ACTLR */
-#define CB_ACTLR_REQPRIORITY_MASK    0x3
-#define CB_ACTLR_REQPRIORITYCFG_MASK 0x1
-#define CB_ACTLR_PRIVCFG_MASK        0x3
-#define CB_ACTLR_BPRCOSH_MASK        0x1
-#define CB_ACTLR_BPRCISH_MASK        0x1
-#define CB_ACTLR_BPRCNSH_MASK        0x1
-
-/* Address Translation, Stage 1, Privileged Read: CB_ATS1PR */
-#define CB_ATS1PR_ADDR_MASK     0xFFFFF
-
-/* Address Translation, Stage 1, Privileged Write: CB_ATS1PW */
-#define CB_ATS1PW_ADDR_MASK     0xFFFFF
-
-/* Address Translation, Stage 1, User Read: CB_ATS1UR */
-#define CB_ATS1UR_ADDR_MASK     0xFFFFF
-
-/* Address Translation, Stage 1, User Write: CB_ATS1UW */
-#define CB_ATS1UW_ADDR_MASK     0xFFFFF
-
-/* Address Translation Status Register: CB_ATSR */
-#define CB_ATSR_ACTIVE_MASK     0x01
-
-/* Context ID Register: CB_CONTEXTIDR */
-#define CB_CONTEXTIDR_ASID_MASK   0xFF
-#define CB_CONTEXTIDR_PROCID_MASK 0xFFFFFF
-
-/* Fault Address Register: CB_FAR */
-#define CB_FAR_FADDR_MASK       0xFFFFFFFF
-
-/* Fault Status Register: CB_FSR */
-#define CB_FSR_TF_MASK          0x01
-#define CB_FSR_AFF_MASK         0x01
-#define CB_FSR_PF_MASK          0x01
-#define CB_FSR_EF_MASK          0x01
-#define CB_FSR_TLBMCF_MASK      0x01
-#define CB_FSR_TLBLKF_MASK      0x01
-#define CB_FSR_SS_MASK          0x01
-#define CB_FSR_MULTI_MASK       0x01
-
-/* Fault Syndrome Register 0: CB_FSYNR0 */
-#define CB_FSYNR0_PLVL_MASK     0x03
-#define CB_FSYNR0_S1PTWF_MASK   0x01
-#define CB_FSYNR0_WNR_MASK      0x01
-#define CB_FSYNR0_PNU_MASK      0x01
-#define CB_FSYNR0_IND_MASK      0x01
-#define CB_FSYNR0_NSSTATE_MASK  0x01
-#define CB_FSYNR0_NSATTR_MASK   0x01
-#define CB_FSYNR0_ATOF_MASK     0x01
-#define CB_FSYNR0_PTWF_MASK     0x01
-#define CB_FSYNR0_AFR_MASK      0x01
-#define CB_FSYNR0_S1CBNDX_MASK  0xFF
-
-/* Normal Memory Remap Register: CB_NMRR */
-#define CB_NMRR_IR0_MASK        0x03
-#define CB_NMRR_IR1_MASK        0x03
-#define CB_NMRR_IR2_MASK        0x03
-#define CB_NMRR_IR3_MASK        0x03
-#define CB_NMRR_IR4_MASK        0x03
-#define CB_NMRR_IR5_MASK        0x03
-#define CB_NMRR_IR6_MASK        0x03
-#define CB_NMRR_IR7_MASK        0x03
-#define CB_NMRR_OR0_MASK        0x03
-#define CB_NMRR_OR1_MASK        0x03
-#define CB_NMRR_OR2_MASK        0x03
-#define CB_NMRR_OR3_MASK        0x03
-#define CB_NMRR_OR4_MASK        0x03
-#define CB_NMRR_OR5_MASK        0x03
-#define CB_NMRR_OR6_MASK        0x03
-#define CB_NMRR_OR7_MASK        0x03
-
-/* Physical Address Register: CB_PAR */
-#define CB_PAR_F_MASK           0x01
-#define CB_PAR_SS_MASK          0x01
-#define CB_PAR_OUTER_MASK       0x03
-#define CB_PAR_INNER_MASK       0x07
-#define CB_PAR_SH_MASK          0x01
-#define CB_PAR_NS_MASK          0x01
-#define CB_PAR_NOS_MASK         0x01
-#define CB_PAR_PA_MASK          0xFFFFF
-#define CB_PAR_TF_MASK          0x01
-#define CB_PAR_AFF_MASK         0x01
-#define CB_PAR_PF_MASK          0x01
-#define CB_PAR_TLBMCF_MASK      0x01
-#define CB_PAR_TLBLKF_MASK      0x01
-#define CB_PAR_ATOT_MASK        0x01
-#define CB_PAR_PLVL_MASK        0x03
-#define CB_PAR_STAGE_MASK       0x01
-
-/* Primary Region Remap Register: CB_PRRR */
-#define CB_PRRR_TR0_MASK        0x03
-#define CB_PRRR_TR1_MASK        0x03
-#define CB_PRRR_TR2_MASK        0x03
-#define CB_PRRR_TR3_MASK        0x03
-#define CB_PRRR_TR4_MASK        0x03
-#define CB_PRRR_TR5_MASK        0x03
-#define CB_PRRR_TR6_MASK        0x03
-#define CB_PRRR_TR7_MASK        0x03
-#define CB_PRRR_DS0_MASK        0x01
-#define CB_PRRR_DS1_MASK        0x01
-#define CB_PRRR_NS0_MASK        0x01
-#define CB_PRRR_NS1_MASK        0x01
-#define CB_PRRR_NOS0_MASK       0x01
-#define CB_PRRR_NOS1_MASK       0x01
-#define CB_PRRR_NOS2_MASK       0x01
-#define CB_PRRR_NOS3_MASK       0x01
-#define CB_PRRR_NOS4_MASK       0x01
-#define CB_PRRR_NOS5_MASK       0x01
-#define CB_PRRR_NOS6_MASK       0x01
-#define CB_PRRR_NOS7_MASK       0x01
-
-/* Transaction Resume: CB_RESUME */
-#define CB_RESUME_TNR_MASK      0x01
-
-/* System Control Register: CB_SCTLR */
-#define CB_SCTLR_M_MASK            0x01
-#define CB_SCTLR_TRE_MASK          0x01
-#define CB_SCTLR_AFE_MASK          0x01
-#define CB_SCTLR_AFFD_MASK         0x01
-#define CB_SCTLR_E_MASK            0x01
-#define CB_SCTLR_CFRE_MASK         0x01
-#define CB_SCTLR_CFIE_MASK         0x01
-#define CB_SCTLR_CFCFG_MASK        0x01
-#define CB_SCTLR_HUPCF_MASK        0x01
-#define CB_SCTLR_WXN_MASK          0x01
-#define CB_SCTLR_UWXN_MASK         0x01
-#define CB_SCTLR_ASIDPNE_MASK      0x01
-#define CB_SCTLR_TRANSIENTCFG_MASK 0x03
-#define CB_SCTLR_MEMATTR_MASK      0x0F
-#define CB_SCTLR_MTCFG_MASK        0x01
-#define CB_SCTLR_SHCFG_MASK        0x03
-#define CB_SCTLR_RACFG_MASK        0x03
-#define CB_SCTLR_WACFG_MASK        0x03
-#define CB_SCTLR_NSCFG_MASK        0x03
-
-/* Invalidate TLB by ASID: CB_TLBIASID */
-#define CB_TLBIASID_ASID_MASK      0xFF
-
-/* Invalidate TLB by VA: CB_TLBIVA */
-#define CB_TLBIVA_ASID_MASK        0xFF
-#define CB_TLBIVA_VA_MASK          0xFFFFF
-
-/* Invalidate TLB by VA, All ASID: CB_TLBIVAA */
-#define CB_TLBIVAA_VA_MASK         0xFFFFF
-
-/* Invalidate TLB by VA, All ASID, Last Level: CB_TLBIVAAL */
-#define CB_TLBIVAAL_VA_MASK        0xFFFFF
-
-/* Invalidate TLB by VA, Last Level: CB_TLBIVAL */
-#define CB_TLBIVAL_ASID_MASK       0xFF
-#define CB_TLBIVAL_VA_MASK         0xFFFFF
-
-/* TLB Status: CB_TLBSTATUS */
-#define CB_TLBSTATUS_SACTIVE_MASK  0x01
-
-/* Translation Table Base Control Register: CB_TTBCR */
-#define CB_TTBCR_T0SZ_MASK         0x07
-#define CB_TTBCR_PD0_MASK          0x01
-#define CB_TTBCR_PD1_MASK          0x01
-#define CB_TTBCR_NSCFG0_MASK       0x01
-#define CB_TTBCR_NSCFG1_MASK       0x01
-#define CB_TTBCR_EAE_MASK          0x01
-
-/* Translation Table Base Register 0/1: CB_TTBR */
-#define CB_TTBR0_IRGN1_MASK        0x01
-#define CB_TTBR0_S_MASK            0x01
-#define CB_TTBR0_RGN_MASK          0x01
-#define CB_TTBR0_NOS_MASK          0x01
-#define CB_TTBR0_IRGN0_MASK        0x01
-#define CB_TTBR0_ADDR_MASK         0xFFFFFF
-
-#define CB_TTBR1_IRGN1_MASK        0x1
-#define CB_TTBR1_S_MASK            0x1
-#define CB_TTBR1_RGN_MASK          0x1
-#define CB_TTBR1_NOS_MASK          0X1
-#define CB_TTBR1_IRGN0_MASK        0X1
-#define CB_TTBR1_ADDR_MASK         0xFFFFFF
-
-/* Global Register Shifts */
-/* Configuration Register: CR0 */
-#define CR0_NSCFG_SHIFT            28
-#define CR0_WACFG_SHIFT            26
-#define CR0_RACFG_SHIFT            24
-#define CR0_SHCFG_SHIFT            22
-#define CR0_SMCFCFG_SHIFT          21
-#define CR0_MTCFG_SHIFT            20
-#define CR0_MEMATTR_SHIFT          16
-#define CR0_BSU_SHIFT              14
-#define CR0_FB_SHIFT               13
-#define CR0_PTM_SHIFT              12
-#define CR0_VMIDPNE_SHIFT          11
-#define CR0_USFCFG_SHIFT           10
-#define CR0_GSE_SHIFT              9
-#define CR0_STALLD_SHIFT           8
-#define CR0_TRANSIENTCFG_SHIFT     6
-#define CR0_GCFGFIE_SHIFT          5
-#define CR0_GCFGFRE_SHIFT          4
-#define CR0_GFIE_SHIFT             2
-#define CR0_GFRE_SHIFT             1
-#define CR0_CLIENTPD_SHIFT         0
-
-/* Configuration Register: CR2 */
-#define CR2_BPVMID_SHIFT           0
-
-/* Global Address Translation, Stage 1, Privileged Read: GATS1PR */
-#define GATS1PR_ADDR_SHIFT         12
-#define GATS1PR_NDX_SHIFT          0
-
-/* Global Address Translation, Stage 1, Privileged Write: GATS1PW */
-#define GATS1PW_ADDR_SHIFT         12
-#define GATS1PW_NDX_SHIFT          0
-
-/* Global Address Translation, Stage 1, User Read: GATS1UR */
-#define GATS1UR_ADDR_SHIFT         12
-#define GATS1UR_NDX_SHIFT          0
-
-/* Global Address Translation, Stage 1, User Write: GATS1UW */
-#define GATS1UW_ADDR_SHIFT         12
-#define GATS1UW_NDX_SHIFT          0
-
-/* Global Address Translation, Stage 1 and 2, Privileged Read: GATS12PR */
-#define GATS12PR_ADDR_SHIFT        12
-#define GATS12PR_NDX_SHIFT         0
-
-/* Global Address Translation, Stage 1 and 2, Privileged Write: GATS12PW */
-#define GATS12PW_ADDR_SHIFT        12
-#define GATS12PW_NDX_SHIFT         0
-
-/* Global Address Translation, Stage 1 and 2, User Read: GATS12UR */
-#define GATS12UR_ADDR_SHIFT        12
-#define GATS12UR_NDX_SHIFT         0
-
-/* Global Address Translation, Stage 1 and 2, User Write: GATS12UW */
-#define GATS12UW_ADDR_SHIFT        12
-#define GATS12UW_NDX_SHIFT         0
-
-/* Global Address Translation Status Register: GATSR */
-#define GATSR_ACTIVE_SHIFT         0
-
-/* Global Fault Address Register: GFAR */
-#define GFAR_FADDR_SHIFT           0
-
-/* Global Fault Status Register: GFSR */
-#define GFSR_ICF_SHIFT             0
-#define GFSR_USF_SHIFT             1
-#define GFSR_SMCF_SHIFT            2
-#define GFSR_UCBF_SHIFT            3
-#define GFSR_UCIF_SHIFT            4
-#define GFSR_CAF_SHIFT             5
-#define GFSR_EF_SHIFT              6
-#define GFSR_PF_SHIFT              7
-#define GFSR_MULTI_SHIFT           31
-
-/* Global Fault Syndrome Register 0: GFSYNR0 */
-#define GFSYNR0_NESTED_SHIFT       0
-#define GFSYNR0_WNR_SHIFT          1
-#define GFSYNR0_PNU_SHIFT          2
-#define GFSYNR0_IND_SHIFT          3
-#define GFSYNR0_NSSTATE_SHIFT      4
-#define GFSYNR0_NSATTR_SHIFT       5
-
-/* Global Fault Syndrome Register 1: GFSYNR1 */
-#define GFSYNR1_SID_SHIFT          0
-
-/* Global Physical Address Register: GPAR */
-#define GPAR_F_SHIFT               0
-#define GPAR_SS_SHIFT              1
-#define GPAR_OUTER_SHIFT           2
-#define GPAR_INNER_SHIFT           4
-#define GPAR_SH_SHIFT              7
-#define GPAR_NS_SHIFT              9
-#define GPAR_NOS_SHIFT             10
-#define GPAR_PA_SHIFT              12
-#define GPAR_TF_SHIFT              1
-#define GPAR_AFF_SHIFT             2
-#define GPAR_PF_SHIFT              3
-#define GPAR_EF_SHIFT              4
-#define GPAR_TLCMCF_SHIFT          5
-#define GPAR_TLBLKF_SHIFT          6
-#define GFAR_UCBF_SHIFT            30
-
-/* Identification Register: IDR0 */
-#define IDR0_NUMSMRG_SHIFT         0
-#define IDR0_NUMSIDB_SHIFT         9
-#define IDR0_BTM_SHIFT             13
-#define IDR0_CTTW_SHIFT            14
-#define IDR0_NUMIRPT_SHIFT         16
-#define IDR0_PTFS_SHIFT            24
-#define IDR0_SMS_SHIFT             27
-#define IDR0_NTS_SHIFT             28
-#define IDR0_S2TS_SHIFT            29
-#define IDR0_S1TS_SHIFT            30
-#define IDR0_SES_SHIFT             31
-
-/* Identification Register: IDR1 */
-#define IDR1_NUMCB_SHIFT           0
-#define IDR1_NUMSSDNDXB_SHIFT      8
-#define IDR1_SSDTP_SHIFT           12
-#define IDR1_SMCD_SHIFT            15
-#define IDR1_NUMS2CB_SHIFT         16
-#define IDR1_NUMPAGENDXB_SHIFT     28
-#define IDR1_PAGESIZE_SHIFT        31
-
-/* Identification Register: IDR2 */
-#define IDR2_IAS_SHIFT             0
-#define IDR2_OAS_SHIFT             4
-
-/* Identification Register: IDR7 */
-#define IDR7_MINOR_SHIFT           0
-#define IDR7_MAJOR_SHIFT           4
-
-/* Stream to Context Register: S2CR */
-#define S2CR_CBNDX_SHIFT           0
-#define s2CR_SHCFG_SHIFT           8
-#define S2CR_MTCFG_SHIFT           11
-#define S2CR_MEMATTR_SHIFT         12
-#define S2CR_TYPE_SHIFT            16
-#define S2CR_NSCFG_SHIFT           18
-#define S2CR_RACFG_SHIFT           20
-#define S2CR_WACFG_SHIFT           22
-#define S2CR_PRIVCFG_SHIFT         24
-#define S2CR_INSTCFG_SHIFT         26
-#define S2CR_TRANSIENTCFG_SHIFT    28
-#define S2CR_VMID_SHIFT            0
-#define S2CR_BSU_SHIFT             24
-#define S2CR_FB_SHIFT              26
-
-/* Stream Match Register: SMR */
-#define SMR_ID_SHIFT               0
-#define SMR_MASK_SHIFT             16
-#define SMR_VALID_SHIFT            31
-
-/* Global TLB Status: TLBGSTATUS */
-#define TLBGSTATUS_GSACTIVE_SHIFT  0
-
-/* Invalidate Hyp TLB by VA: TLBIVAH */
-#define TLBIVAH_ADDR_SHIFT         12
-
-/* Invalidate TLB by VMID: TLBIVMID */
-#define TLBIVMID_VMID_SHIFT        0
-
-/* Context Bank Attribute Register: CBAR */
-#define CBAR_VMID_SHIFT            0
-#define CBAR_CBNDX_SHIFT           8
-#define CBAR_BPSHCFG_SHIFT         8
-#define CBAR_HYPC_SHIFT            10
-#define CBAR_FB_SHIFT              11
-#define CBAR_MEMATTR_SHIFT         12
-#define CBAR_TYPE_SHIFT            16
-#define CBAR_BSU_SHIFT             18
-#define CBAR_RACFG_SHIFT           20
-#define CBAR_WACFG_SHIFT           22
-#define CBAR_IRPTNDX_SHIFT         24
-
-/* Context Bank Fault Restricted Syndrome Register A: CBFRSYNRA */
-#define CBFRSYNRA_SID_SHIFT        0
-
-/* Stage 1 Context Bank Format Shifts */
-/* Auxiliary Control Register: CB_ACTLR */
-#define CB_ACTLR_REQPRIORITY_SHIFT     0
-#define CB_ACTLR_REQPRIORITYCFG_SHIFT  4
-#define CB_ACTLR_PRIVCFG_SHIFT         8
-#define CB_ACTLR_BPRCOSH_SHIFT         28
-#define CB_ACTLR_BPRCISH_SHIFT         29
-#define CB_ACTLR_BPRCNSH_SHIFT         30
-
-/* Address Translation, Stage 1, Privileged Read: CB_ATS1PR */
-#define CB_ATS1PR_ADDR_SHIFT       12
-
-/* Address Translation, Stage 1, Privileged Write: CB_ATS1PW */
-#define CB_ATS1PW_ADDR_SHIFT       12
-
-/* Address Translation, Stage 1, User Read: CB_ATS1UR */
-#define CB_ATS1UR_ADDR_SHIFT       12
-
-/* Address Translation, Stage 1, User Write: CB_ATS1UW */
-#define CB_ATS1UW_ADDR_SHIFT       12
-
-/* Address Translation Status Register: CB_ATSR */
-#define CB_ATSR_ACTIVE_SHIFT       0
-
-/* Context ID Register: CB_CONTEXTIDR */
-#define CB_CONTEXTIDR_ASID_SHIFT   0
-#define CB_CONTEXTIDR_PROCID_SHIFT 8
-
-/* Fault Address Register: CB_FAR */
-#define CB_FAR_FADDR_SHIFT         0
-
-/* Fault Status Register: CB_FSR */
-#define CB_FSR_TF_SHIFT            1
-#define CB_FSR_AFF_SHIFT           2
-#define CB_FSR_PF_SHIFT            3
-#define CB_FSR_EF_SHIFT            4
-#define CB_FSR_TLBMCF_SHIFT        5
-#define CB_FSR_TLBLKF_SHIFT        6
-#define CB_FSR_SS_SHIFT            30
-#define CB_FSR_MULTI_SHIFT         31
-
-/* Fault Syndrome Register 0: CB_FSYNR0 */
-#define CB_FSYNR0_PLVL_SHIFT       0
-#define CB_FSYNR0_S1PTWF_SHIFT     3
-#define CB_FSYNR0_WNR_SHIFT        4
-#define CB_FSYNR0_PNU_SHIFT        5
-#define CB_FSYNR0_IND_SHIFT        6
-#define CB_FSYNR0_NSSTATE_SHIFT    7
-#define CB_FSYNR0_NSATTR_SHIFT     8
-#define CB_FSYNR0_ATOF_SHIFT       9
-#define CB_FSYNR0_PTWF_SHIFT       10
-#define CB_FSYNR0_AFR_SHIFT        11
-#define CB_FSYNR0_S1CBNDX_SHIFT    16
-
-/* Normal Memory Remap Register: CB_NMRR */
-#define CB_NMRR_IR0_SHIFT          0
-#define CB_NMRR_IR1_SHIFT          2
-#define CB_NMRR_IR2_SHIFT          4
-#define CB_NMRR_IR3_SHIFT          6
-#define CB_NMRR_IR4_SHIFT          8
-#define CB_NMRR_IR5_SHIFT          10
-#define CB_NMRR_IR6_SHIFT          12
-#define CB_NMRR_IR7_SHIFT          14
-#define CB_NMRR_OR0_SHIFT          16
-#define CB_NMRR_OR1_SHIFT          18
-#define CB_NMRR_OR2_SHIFT          20
-#define CB_NMRR_OR3_SHIFT          22
-#define CB_NMRR_OR4_SHIFT          24
-#define CB_NMRR_OR5_SHIFT          26
-#define CB_NMRR_OR6_SHIFT          28
-#define CB_NMRR_OR7_SHIFT          30
-
-/* Physical Address Register: CB_PAR */
-#define CB_PAR_F_SHIFT             0
-#define CB_PAR_SS_SHIFT            1
-#define CB_PAR_OUTER_SHIFT         2
-#define CB_PAR_INNER_SHIFT         4
-#define CB_PAR_SH_SHIFT            7
-#define CB_PAR_NS_SHIFT            9
-#define CB_PAR_NOS_SHIFT           10
-#define CB_PAR_PA_SHIFT            12
-#define CB_PAR_TF_SHIFT            1
-#define CB_PAR_AFF_SHIFT           2
-#define CB_PAR_PF_SHIFT            3
-#define CB_PAR_TLBMCF_SHIFT        5
-#define CB_PAR_TLBLKF_SHIFT        6
-#define CB_PAR_ATOT_SHIFT          31
-#define CB_PAR_PLVL_SHIFT          0
-#define CB_PAR_STAGE_SHIFT         3
-
-/* Primary Region Remap Register: CB_PRRR */
-#define CB_PRRR_TR0_SHIFT          0
-#define CB_PRRR_TR1_SHIFT          2
-#define CB_PRRR_TR2_SHIFT          4
-#define CB_PRRR_TR3_SHIFT          6
-#define CB_PRRR_TR4_SHIFT          8
-#define CB_PRRR_TR5_SHIFT          10
-#define CB_PRRR_TR6_SHIFT          12
-#define CB_PRRR_TR7_SHIFT          14
-#define CB_PRRR_DS0_SHIFT          16
-#define CB_PRRR_DS1_SHIFT          17
-#define CB_PRRR_NS0_SHIFT          18
-#define CB_PRRR_NS1_SHIFT          19
-#define CB_PRRR_NOS0_SHIFT         24
-#define CB_PRRR_NOS1_SHIFT         25
-#define CB_PRRR_NOS2_SHIFT         26
-#define CB_PRRR_NOS3_SHIFT         27
-#define CB_PRRR_NOS4_SHIFT         28
-#define CB_PRRR_NOS5_SHIFT         29
-#define CB_PRRR_NOS6_SHIFT         30
-#define CB_PRRR_NOS7_SHIFT         31
-
-/* Transaction Resume: CB_RESUME */
-#define CB_RESUME_TNR_SHIFT        0
-
-/* System Control Register: CB_SCTLR */
-#define CB_SCTLR_M_SHIFT            0
-#define CB_SCTLR_TRE_SHIFT          1
-#define CB_SCTLR_AFE_SHIFT          2
-#define CB_SCTLR_AFFD_SHIFT         3
-#define CB_SCTLR_E_SHIFT            4
-#define CB_SCTLR_CFRE_SHIFT         5
-#define CB_SCTLR_CFIE_SHIFT         6
-#define CB_SCTLR_CFCFG_SHIFT        7
-#define CB_SCTLR_HUPCF_SHIFT        8
-#define CB_SCTLR_WXN_SHIFT          9
-#define CB_SCTLR_UWXN_SHIFT         10
-#define CB_SCTLR_ASIDPNE_SHIFT      12
-#define CB_SCTLR_TRANSIENTCFG_SHIFT 14
-#define CB_SCTLR_MEMATTR_SHIFT      16
-#define CB_SCTLR_MTCFG_SHIFT        20
-#define CB_SCTLR_SHCFG_SHIFT        22
-#define CB_SCTLR_RACFG_SHIFT        24
-#define CB_SCTLR_WACFG_SHIFT        26
-#define CB_SCTLR_NSCFG_SHIFT        28
-
-/* Invalidate TLB by ASID: CB_TLBIASID */
-#define CB_TLBIASID_ASID_SHIFT      0
-
-/* Invalidate TLB by VA: CB_TLBIVA */
-#define CB_TLBIVA_ASID_SHIFT        0
-#define CB_TLBIVA_VA_SHIFT          12
-
-/* Invalidate TLB by VA, All ASID: CB_TLBIVAA */
-#define CB_TLBIVAA_VA_SHIFT         12
-
-/* Invalidate TLB by VA, All ASID, Last Level: CB_TLBIVAAL */
-#define CB_TLBIVAAL_VA_SHIFT        12
-
-/* Invalidate TLB by VA, Last Level: CB_TLBIVAL */
-#define CB_TLBIVAL_ASID_SHIFT       0
-#define CB_TLBIVAL_VA_SHIFT         12
-
-/* TLB Status: CB_TLBSTATUS */
-#define CB_TLBSTATUS_SACTIVE_SHIFT  0
-
-/* Translation Table Base Control Register: CB_TTBCR */
-#define CB_TTBCR_T0SZ_SHIFT         0
-#define CB_TTBCR_PD0_SHIFT          4
-#define CB_TTBCR_PD1_SHIFT          5
-#define CB_TTBCR_NSCFG0_SHIFT       14
-#define CB_TTBCR_NSCFG1_SHIFT       30
-#define CB_TTBCR_EAE_SHIFT          31
-
-/* Translation Table Base Register 0/1: CB_TTBR */
-#define CB_TTBR0_IRGN1_SHIFT        0
-#define CB_TTBR0_S_SHIFT            1
-#define CB_TTBR0_RGN_SHIFT          3
-#define CB_TTBR0_NOS_SHIFT          5
-#define CB_TTBR0_IRGN0_SHIFT        6
-#define CB_TTBR0_ADDR_SHIFT         14
-
-#define CB_TTBR1_IRGN1_SHIFT        0
-#define CB_TTBR1_S_SHIFT            1
-#define CB_TTBR1_RGN_SHIFT          3
-#define CB_TTBR1_NOS_SHIFT          5
-#define CB_TTBR1_IRGN0_SHIFT        6
-#define CB_TTBR1_ADDR_SHIFT         14
-
-#endif
diff --git a/arch/arm/mach-msm/include/mach/iommu_perfmon.h b/arch/arm/mach-msm/include/mach/iommu_perfmon.h
new file mode 100644
index 0000000..c03c752
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/iommu_perfmon.h
@@ -0,0 +1,247 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/list.h>
+#include <linux/irqreturn.h>
+
+#ifndef MSM_IOMMU_PERFMON_H
+#define MSM_IOMMU_PERFMON_H
+
+/**
+ * struct iommu_access_ops - Callbacks for accessing IOMMU
+ * @iommu_power_on:     Turn on clocks/power to unit
+ * @iommu_power_off:    Turn off clocks/power to unit
+ * @iommu_lock_acquire: Acquire any locks needed
+ * @iommu_lock_release: Release locks needed
+ */
+struct iommu_access_ops {
+	int (*iommu_power_on)(void *);
+	int (*iommu_power_off)(void *);
+	void (*iommu_lock_acquire)(void);
+	void (*iommu_lock_release)(void);
+};
+
+/**
+ * struct iommu_pmon_counter - container for a performance counter.
+ * @counter_no:          counter number within the group
+ * @absolute_counter_no: counter number within IOMMU PMU
+ * @value:               cached counter value
+ * @overflow_count:      no of times counter has overflowed
+ * @enabled:             indicates whether counter is enabled or not
+ * @current_event_class: current selected event class, -1 if none
+ * @counter_dir:         debugfs directory for this counter
+ * @cnt_group:           group this counter belongs to
+ */
+struct iommu_pmon_counter {
+	unsigned int counter_no;
+	unsigned int absolute_counter_no;
+	unsigned long value;
+	unsigned long overflow_count;
+	unsigned int enabled;
+	int current_event_class;
+	struct dentry *counter_dir;
+	struct iommu_pmon_cnt_group *cnt_group;
+};
+
+/**
+ * struct iommu_pmon_cnt_group - container for a perf mon counter group.
+ * @grp_no:       group number
+ * @num_counters: number of counters in this group
+ * @counters:     list of counter in this group
+ * @group_dir:    debugfs directory for this group
+ * @pmon:         pointer to the iommu_pmon object this group belongs to
+ */
+struct iommu_pmon_cnt_group {
+	unsigned int grp_no;
+	unsigned int num_counters;
+	struct iommu_pmon_counter *counters;
+	struct dentry *group_dir;
+	struct iommu_pmon *pmon;
+};
+
+/**
+ * struct iommu_info - container for a perf mon iommu info.
+ * @iommu_name: name of the iommu from device tree
+ * @base:       virtual base address for this iommu
+ * @evt_irq:    irq number for event overflow interrupt
+ * @iommu_dev:  pointer to iommu device
+ * @ops:        iommu access operations pointer.
+ * @hw_ops:     iommu pm hw access operations pointer.
+ */
+struct iommu_info {
+	const char *iommu_name;
+	void *base;
+	int evt_irq;
+	struct device *iommu_dev;
+	struct iommu_access_ops *ops;
+	struct iommu_pm_hw_ops *hw_ops;
+};
+
+/**
+ * struct iommu_pmon - main container for a perf mon data.
+ * @iommu_dir:            debugfs directory for this iommu
+ * @iommu:                iommu_info instance
+ * @iommu_list:           iommu_list head
+ * @cnt_grp:              list of counter groups
+ * @num_groups:           number of counter groups
+ * @num_counters:         number of counters per group
+ * @event_cls_supported:  an array of event classes supported for this PMU
+ * @nevent_cls_supported: number of event classes supported.
+ * @enabled:              Indicates whether perf. mon is enabled or not
+ * @iommu_attached        Indicates whether iommu is attached or not.
+ * @lock:                 mutex used to synchronize access to shared data
+ */
+struct iommu_pmon {
+	struct dentry *iommu_dir;
+	struct iommu_info iommu;
+	struct list_head iommu_list;
+	struct iommu_pmon_cnt_group *cnt_grp;
+	u32 num_groups;
+	u32 num_counters;
+	u32 *event_cls_supported;
+	u32 nevent_cls_supported;
+	unsigned int enabled;
+	unsigned int iommu_attach_count;
+	struct mutex lock;
+};
+
+/**
+ * struct iommu_hw_ops - Callbacks for accessing IOMMU HW
+ * @initialize_hw: Call to do any initialization before enabling ovf interrupts
+ * @is_hw_access_ok: Returns 1 if we can access HW, 0 otherwise
+ * @grp_enable: Call to enable a counter group
+ * @grp_disable: Call to disable a counter group
+ * @enable_pm: Call to enable PM
+ * @disable_pm: Call to disable PM
+ * @reset_counters:  Call to reset counters
+ * @check_for_overflow:  Call to check for overflow
+ * @evt_ovfl_int_handler: Overflow interrupt handler callback
+ * @counter_enable: Call to enable counters
+ * @counter_disable: Call to disable counters
+ * @ovfl_int_enable: Call to enable overflow interrupts
+ * @ovfl_int_disable: Call to disable overflow interrupts
+ * @set_event_class: Call to set event class
+ * @read_counter: Call to read a counter value
+ */
+struct iommu_pm_hw_ops {
+	void (*initialize_hw)(const struct iommu_pmon *);
+	unsigned int (*is_hw_access_OK)(const struct iommu_pmon *);
+	void (*grp_enable)(struct iommu_info *, unsigned int);
+	void (*grp_disable)(struct iommu_info *, unsigned int);
+	void (*enable_pm)(struct iommu_info *);
+	void (*disable_pm)(struct iommu_info *);
+	void (*reset_counters)(const struct iommu_info *);
+	void (*check_for_overflow)(struct iommu_pmon *);
+	irqreturn_t (*evt_ovfl_int_handler)(int, void *);
+	void (*counter_enable)(struct iommu_info *,
+			       struct iommu_pmon_counter *);
+	void (*counter_disable)(struct iommu_info *,
+			       struct iommu_pmon_counter *);
+	void (*ovfl_int_enable)(struct iommu_info *,
+				const struct iommu_pmon_counter *);
+	void (*ovfl_int_disable)(struct iommu_info *,
+				const struct iommu_pmon_counter *);
+	void (*set_event_class)(struct iommu_pmon *pmon, unsigned int,
+				unsigned int);
+	unsigned int (*read_counter)(struct iommu_pmon_counter *);
+};
+
+extern struct iommu_access_ops iommu_access_ops_v0;
+extern struct iommu_access_ops iommu_access_ops_v1;
+#define MSM_IOMMU_PMU_NO_EVENT_CLASS -1
+
+#ifdef CONFIG_MSM_IOMMU_PMON
+
+/**
+ * Get pointer to PMU hardware access functions for IOMMUv0 PMU
+ */
+struct iommu_pm_hw_ops *iommu_pm_get_hw_ops_v0(void);
+
+/**
+ * Get pointer to PMU hardware access functions for IOMMUv1 PMU
+ */
+struct iommu_pm_hw_ops *iommu_pm_get_hw_ops_v1(void);
+
+/**
+ * Allocate memory for performance monitor structure. Must
+ * be called before iommu_pm_iommu_register
+ */
+struct iommu_pmon *msm_iommu_pm_alloc(struct device *iommu_dev);
+
+/**
+ * Free memory previously allocated with iommu_pm_alloc
+ */
+void msm_iommu_pm_free(struct device *iommu_dev);
+
+/**
+ * Register iommu with the performance monitor module.
+ */
+int msm_iommu_pm_iommu_register(struct iommu_pmon *info);
+
+/**
+ * Unregister iommu with the performance monitor module.
+ */
+void msm_iommu_pm_iommu_unregister(struct device *dev);
+
+/**
+ * Called by iommu driver when attaching is complete
+ * Must NOT be called with IOMMU mutexes held.
+ * @param iommu_dev IOMMU device that is attached
+  */
+void msm_iommu_attached(struct device *dev);
+
+/**
+ * Called by iommu driver before detaching.
+ * Must NOT be called with IOMMU mutexes held.
+ * @param iommu_dev IOMMU device that is going to be detached
+  */
+void msm_iommu_detached(struct device *dev);
+#else
+static inline struct iommu_pm_hw_ops *iommu_pm_get_hw_ops_v0(void)
+{
+	return NULL;
+}
+
+static inline struct iommu_pm_hw_ops *iommu_pm_get_hw_ops_v1(void)
+{
+	return NULL;
+}
+
+static inline struct iommu_pmon *msm_iommu_pm_alloc(struct device *iommu_dev)
+{
+	return NULL;
+}
+
+static inline void msm_iommu_pm_free(struct device *iommu_dev)
+{
+	return;
+}
+
+static inline int msm_iommu_pm_iommu_register(struct iommu_pmon *info)
+{
+	return -EIO;
+}
+
+static inline void msm_iommu_pm_iommu_unregister(struct device *dev)
+{
+}
+
+static inline void msm_iommu_attached(struct device *dev)
+{
+}
+
+static inline void msm_iommu_detached(struct device *dev)
+{
+}
+#endif
+#endif
diff --git a/arch/arm/mach-msm/include/mach/ion.h b/arch/arm/mach-msm/include/mach/ion.h
index 9fbc720..b472d27 100644
--- a/arch/arm/mach-msm/include/mach/ion.h
+++ b/arch/arm/mach-msm/include/mach/ion.h
@@ -1,6 +1,6 @@
 /**
  *
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/include/mach/ipa.h b/arch/arm/mach-msm/include/mach/ipa.h
index c37b518..f2a4427 100644
--- a/arch/arm/mach-msm/include/mach/ipa.h
+++ b/arch/arm/mach-msm/include/mach/ipa.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
@@ -201,6 +201,9 @@
 	struct ipa_ep_cfg_route route;
 };
 
+typedef void (*ipa_notify_cb)(void *priv, enum ipa_dp_evt_type evt,
+		       unsigned long data);
+
 /**
  * struct ipa_connect_params - low-level client connect input parameters. Either
  * client allocates the data and desc FIFO and specifies that in data+desc OR
@@ -228,8 +231,7 @@
 	u32 client_bam_hdl;
 	u32 client_ep_idx;
 	void *priv;
-	void (*notify)(void *priv, enum ipa_dp_evt_type evt,
-			unsigned long data);
+	ipa_notify_cb notify;
 	u32 desc_fifo_sz;
 	u32 data_fifo_sz;
 	bool pipe_mem_preferred;
@@ -290,22 +292,7 @@
 	enum ipa_client_type client;
 	u32 desc_fifo_sz;
 	void *priv;
-	void (*notify)(void *priv,
-			enum ipa_dp_evt_type evt,
-			unsigned long data);
-};
-
-/**
- * struct ipa_msg_meta_wrapper - message meta-data wrapper
- * @meta:	the meta-data itself
- * @link:	opaque to client
- * @meta_wrapper_free:	function to free the metadata wrapper when IPA driver
- *			is done with it
- */
-struct ipa_msg_meta_wrapper {
-	struct ipa_msg_meta meta;
-	struct list_head link;
-	void (*meta_wrapper_free)(struct ipa_msg_meta_wrapper *buff);
+	ipa_notify_cb notify;
 };
 
 /**
@@ -319,32 +306,183 @@
 };
 
 /**
- * struct ipa_msg_wrapper - message wrapper
- * @msg:	the message buffer itself, MUST exist after call returns, will
- *		be freed by IPA driver when it is done with it
- * @link:	opaque to client
- * @msg_free:	function to free the message when IPA driver is done with it
- * @msg_wrapper_free:	function to free the message wrapper when IPA driver is
- *			done with it
+ * typedef ipa_msg_free_fn - callback function
+ * @param buff - [in] the message payload to free
+ * @param len - [in] size of message payload
+ * @param type - [in] the message type
+ *
+ * Message callback registered by kernel client with IPA driver to
+ * free message payload after IPA driver processing is complete
+ *
+ * No return value
  */
-struct ipa_msg_wrapper {
-	void *msg;
-	struct list_head link;
-	void (*msg_free)(void *msg);
-	void (*msg_wrapper_free)(struct ipa_msg_wrapper *buff);
+typedef void (*ipa_msg_free_fn)(void *buff, u32 len, u32 type);
+
+/**
+ * typedef ipa_msg_pull_fn - callback function
+ * @param buff - [in] where to copy message payload
+ * @param len - [in] size of buffer to copy payload into
+ * @param type - [in] the message type
+ *
+ * Message callback registered by kernel client with IPA driver for
+ * IPA driver to pull messages from the kernel client upon demand from
+ * user-space
+ *
+ * Returns how many bytes were copied into the buffer.
+ */
+typedef int (*ipa_msg_pull_fn)(void *buff, u32 len, u32 type);
+
+/**
+ * enum ipa_bridge_dir - direction of the bridge from air interface perspective
+ *
+ * IPA bridge direction
+ */
+enum ipa_bridge_dir {
+	IPA_BRIDGE_DIR_DL,
+	IPA_BRIDGE_DIR_UL,
+	IPA_BRIDGE_DIR_MAX
 };
 
 /**
- * typedef ipa_pull_fn - callback function
- * @buf - [in] the buffer to populate the message into
- * @sz - [in] the size of the buffer
+ * enum ipa_bridge_type - type of SW bridge
  *
- * callback function registered by kernel client with IPA driver for IPA driver
- * to be able to pull messages from the kernel client asynchronously.
- *
- * Returns how many bytes were copied into the buffer, negative on failure.
+ * IPA bridge type
  */
-typedef int (*ipa_pull_fn)(void *buf, uint16_t sz);
+enum ipa_bridge_type {
+	IPA_BRIDGE_TYPE_TETHERED,
+	IPA_BRIDGE_TYPE_EMBEDDED,
+	IPA_BRIDGE_TYPE_MAX
+};
+
+/**
+ * enum ipa_rm_resource_name - IPA RM clients identification names
+ *
+ * Add new mapping to ipa_rm_dep_prod_index() / ipa_rm_dep_cons_index()
+ * when adding new entry to this enum.
+ */
+enum ipa_rm_resource_name {
+	IPA_RM_RESOURCE_PROD = 0,
+	IPA_RM_RESOURCE_BRIDGE_PROD = IPA_RM_RESOURCE_PROD,
+	IPA_RM_RESOURCE_A2_PROD,
+	IPA_RM_RESOURCE_USB_PROD,
+	IPA_RM_RESOURCE_HSIC_PROD,
+	IPA_RM_RESOURCE_STD_ECM_PROD,
+	IPA_RM_RESOURCE_WWAN_0_PROD,
+	IPA_RM_RESOURCE_WWAN_1_PROD,
+	IPA_RM_RESOURCE_WWAN_2_PROD,
+	IPA_RM_RESOURCE_WWAN_3_PROD,
+	IPA_RM_RESOURCE_WWAN_4_PROD,
+	IPA_RM_RESOURCE_WWAN_5_PROD,
+	IPA_RM_RESOURCE_WWAN_6_PROD,
+	IPA_RM_RESOURCE_WWAN_7_PROD,
+	IPA_RM_RESOURCE_WLAN_PROD,
+	IPA_RM_RESOURCE_PROD_MAX,
+
+	IPA_RM_RESOURCE_A2_CONS = IPA_RM_RESOURCE_PROD_MAX,
+	IPA_RM_RESOURCE_USB_CONS,
+	IPA_RM_RESOURCE_HSIC_CONS,
+	IPA_RM_RESOURCE_MAX
+};
+
+/**
+ * enum ipa_rm_event - IPA RM events
+ *
+ * Indicate the resource state change
+ */
+enum ipa_rm_event {
+	IPA_RM_RESOURCE_GRANTED,
+	IPA_RM_RESOURCE_RELEASED
+};
+
+typedef void (*ipa_rm_notify_cb)(void *user_data,
+		enum ipa_rm_event event,
+		unsigned long data);
+/**
+ * struct ipa_rm_register_params - information needed to
+ *      register IPA RM client with IPA RM
+ *
+ * @user_data: IPA RM client provided information
+ *		to be passed to notify_cb callback below
+ * @notify_cb: callback which is called by resource
+ *		to notify the IPA RM client about its state
+ *		change IPA RM client is expected to perform non
+ *		blocking operations only in notify_cb and
+ *		release notification context as soon as
+ *		possible.
+ */
+struct ipa_rm_register_params {
+	void *user_data;
+	ipa_rm_notify_cb notify_cb;
+};
+
+/**
+ * struct ipa_rm_create_params - information needed to initialize
+ *				the resource
+ * @name: resource name
+ * @reg_params: register parameters, contains are ignored
+ *		for consumer resource NULL should be provided
+ *		for consumer resource
+ * @request_resource: function which should be called to request resource,
+ *			NULL should be provided for producer resource
+ * @release_resource: function which should be called to release resource,
+ *			NULL should be provided for producer resource
+ *
+ * IPA RM client is expected to perform non blocking operations only
+ * in request_resource and release_resource functions and
+ * release notification context as soon as possible.
+ */
+struct ipa_rm_create_params {
+	enum ipa_rm_resource_name name;
+	struct ipa_rm_register_params reg_params;
+	int (*request_resource)(void);
+	int (*release_resource)(void);
+};
+
+#define A2_MUX_HDR_NAME_V4_PREF "dmux_hdr_v4_"
+#define A2_MUX_HDR_NAME_V6_PREF "dmux_hdr_v6_"
+
+enum a2_mux_event_type {
+	A2_MUX_RECEIVE,
+	A2_MUX_WRITE_DONE
+};
+
+enum a2_mux_logical_channel_id {
+	A2_MUX_WWAN_0,
+	A2_MUX_WWAN_1,
+	A2_MUX_WWAN_2,
+	A2_MUX_WWAN_3,
+	A2_MUX_WWAN_4,
+	A2_MUX_WWAN_5,
+	A2_MUX_WWAN_6,
+	A2_MUX_WWAN_7,
+	A2_MUX_TETHERED_0,
+	A2_MUX_NUM_CHANNELS
+};
+
+typedef void (*a2_mux_notify_cb)(void *user_data,
+		enum a2_mux_event_type event,
+		unsigned long data);
+
+/**
+ * enum teth_tethering_mode - Tethering mode (Rmnet / MBIM)
+ */
+enum teth_tethering_mode {
+	TETH_TETHERING_MODE_RMNET,
+	TETH_TETHERING_MODE_MBIM,
+	TETH_TETHERING_MODE_MAX,
+};
+
+/**
+ * struct teth_bridge_connect_params - Parameters used in teth_bridge_connect()
+ * @ipa_usb_pipe_hdl:	IPA to USB pipe handle, returned from ipa_connect()
+ * @usb_ipa_pipe_hdl:	USB to IPA pipe handle, returned from ipa_connect()
+ * @tethering_mode:	Rmnet or MBIM
+ */
+struct teth_bridge_connect_params {
+	u32 ipa_usb_pipe_hdl;
+	u32 usb_ipa_pipe_hdl;
+	enum teth_tethering_mode tethering_mode;
+};
 
 #ifdef CONFIG_IPA
 
@@ -425,6 +563,21 @@
 int ipa_nat_del_cmd(struct ipa_ioc_v4_nat_del *del);
 
 /*
+ * Messaging
+ */
+int ipa_send_msg(struct ipa_msg_meta *meta, void *buff,
+		  ipa_msg_free_fn callback);
+int ipa_register_pull_msg(struct ipa_msg_meta *meta, ipa_msg_pull_fn callback);
+int ipa_deregister_pull_msg(struct ipa_msg_meta *meta);
+
+/*
+ * Interface
+ */
+int ipa_register_intf(const char *name, const struct ipa_tx_intf *tx,
+		       const struct ipa_rx_intf *rx);
+int ipa_deregister_intf(const char *name);
+
+/*
  * Aggregation
  */
 int ipa_set_aggr_mode(enum ipa_aggr_mode mode);
@@ -445,6 +598,15 @@
 			 int wwan_logical_channel_id);
 
 /*
+ * SW bridge (between IPA and A2)
+ */
+int ipa_bridge_setup(enum ipa_bridge_dir dir, enum ipa_bridge_type type,
+		     struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl);
+int ipa_bridge_teardown(enum ipa_bridge_dir dir, enum ipa_bridge_type type,
+			u32 clnt_hdl);
+
+
+/*
  * Data path
  */
 int ipa_tx_dp(enum ipa_client_type dst, struct sk_buff *skb,
@@ -457,8 +619,105 @@
 
 int ipa_teardown_sys_pipe(u32 clnt_hdl);
 
+/*
+ * Resource manager
+ */
+int ipa_rm_create_resource(struct ipa_rm_create_params *create_params);
+
+int ipa_rm_register(enum ipa_rm_resource_name resource_name,
+			struct ipa_rm_register_params *reg_params);
+
+int ipa_rm_deregister(enum ipa_rm_resource_name resource_name,
+			struct ipa_rm_register_params *reg_params);
+
+int ipa_rm_add_dependency(enum ipa_rm_resource_name resource_name,
+			enum ipa_rm_resource_name depends_on_name);
+
+int ipa_rm_delete_dependency(enum ipa_rm_resource_name resource_name,
+			enum ipa_rm_resource_name depends_on_name);
+
+int ipa_rm_request_resource(enum ipa_rm_resource_name resource_name);
+
+int ipa_rm_release_resource(enum ipa_rm_resource_name resource_name);
+
+int ipa_rm_notify_completion(enum ipa_rm_event event,
+		enum ipa_rm_resource_name resource_name);
+
+int ipa_rm_inactivity_timer_init(enum ipa_rm_resource_name resource_name,
+				 unsigned long msecs);
+
+int ipa_rm_inactivity_timer_destroy(enum ipa_rm_resource_name resource_name);
+
+int ipa_rm_inactivity_timer_request_resource(
+				enum ipa_rm_resource_name resource_name);
+
+int ipa_rm_inactivity_timer_release_resource(
+				enum ipa_rm_resource_name resource_name);
+
+/*
+ * a2 service
+ */
+int a2_mux_open_channel(enum a2_mux_logical_channel_id lcid,
+			void *user_data,
+			a2_mux_notify_cb notify_cb);
+
+int a2_mux_close_channel(enum a2_mux_logical_channel_id lcid);
+
+int a2_mux_write(enum a2_mux_logical_channel_id lcid, struct sk_buff *skb);
+
+int a2_mux_is_ch_low(enum a2_mux_logical_channel_id lcid);
+
+int a2_mux_is_ch_full(enum a2_mux_logical_channel_id lcid);
+
+int a2_mux_get_tethered_client_handles(enum a2_mux_logical_channel_id lcid,
+		unsigned int *clnt_cons_handle,
+		unsigned int *clnt_prod_handle);
+
+/*
+ * Tethering bridge (Rmnet / MBIM)
+ */
+int teth_bridge_init(ipa_notify_cb *usb_notify_cb_ptr, void **private_data_ptr);
+
+int teth_bridge_disconnect(void);
+
+int teth_bridge_connect(struct teth_bridge_connect_params *connect_params);
+
 #else /* CONFIG_IPA */
 
+static inline int a2_mux_open_channel(enum a2_mux_logical_channel_id lcid,
+	void *user_data, a2_mux_notify_cb notify_cb)
+{
+	return -EPERM;
+}
+
+static inline int a2_mux_close_channel(enum a2_mux_logical_channel_id lcid)
+{
+	return -EPERM;
+}
+
+static inline int a2_mux_write(enum a2_mux_logical_channel_id lcid,
+			       struct sk_buff *skb)
+{
+	return -EPERM;
+}
+
+static inline int a2_mux_is_ch_low(enum a2_mux_logical_channel_id lcid)
+{
+	return -EPERM;
+}
+
+static inline int a2_mux_is_ch_full(enum a2_mux_logical_channel_id lcid)
+{
+	return -EPERM;
+}
+
+static inline int a2_mux_get_tethered_client_handles(
+	enum a2_mux_logical_channel_id lcid, unsigned int *clnt_cons_handle,
+	unsigned int *clnt_prod_handle)
+{
+	return -EPERM;
+}
+
 /*
  * Connect / Disconnect
  */
@@ -473,7 +732,6 @@
 	return -EPERM;
 }
 
-
 /*
  * Configuration
  */
@@ -483,42 +741,36 @@
 	return -EPERM;
 }
 
-
 static inline int ipa_cfg_ep_nat(u32 clnt_hdl,
 		const struct ipa_ep_cfg_nat *ipa_ep_cfg)
 {
 	return -EPERM;
 }
 
-
 static inline int ipa_cfg_ep_hdr(u32 clnt_hdl,
 		const struct ipa_ep_cfg_hdr *ipa_ep_cfg)
 {
 	return -EPERM;
 }
 
-
 static inline int ipa_cfg_ep_mode(u32 clnt_hdl,
 		const struct ipa_ep_cfg_mode *ipa_ep_cfg)
 {
 	return -EPERM;
 }
 
-
 static inline int ipa_cfg_ep_aggr(u32 clnt_hdl,
 		const struct ipa_ep_cfg_aggr *ipa_ep_cfg)
 {
 	return -EPERM;
 }
 
-
 static inline int ipa_cfg_ep_route(u32 clnt_hdl,
 		const struct ipa_ep_cfg_route *ipa_ep_cfg)
 {
 	return -EPERM;
 }
 
-
 /*
  * Header removal / addition
  */
@@ -527,43 +779,36 @@
 	return -EPERM;
 }
 
-
 static inline int ipa_del_hdr(struct ipa_ioc_del_hdr *hdls)
 {
 	return -EPERM;
 }
 
-
 static inline int ipa_commit_hdr(void)
 {
 	return -EPERM;
 }
 
-
 static inline int ipa_reset_hdr(void)
 {
 	return -EPERM;
 }
 
-
 static inline int ipa_get_hdr(struct ipa_ioc_get_hdr *lookup)
 {
 	return -EPERM;
 }
 
-
 static inline int ipa_put_hdr(u32 hdr_hdl)
 {
 	return -EPERM;
 }
 
-
 static inline int ipa_copy_hdr(struct ipa_ioc_copy_hdr *copy)
 {
 	return -EPERM;
 }
 
-
 /*
  * Routing
  */
@@ -572,37 +817,31 @@
 	return -EPERM;
 }
 
-
 static inline int ipa_del_rt_rule(struct ipa_ioc_del_rt_rule *hdls)
 {
 	return -EPERM;
 }
 
-
 static inline int ipa_commit_rt(enum ipa_ip_type ip)
 {
 	return -EPERM;
 }
 
-
 static inline int ipa_reset_rt(enum ipa_ip_type ip)
 {
 	return -EPERM;
 }
 
-
 static inline int ipa_get_rt_tbl(struct ipa_ioc_get_rt_tbl *lookup)
 {
 	return -EPERM;
 }
 
-
 static inline int ipa_put_rt_tbl(u32 rt_tbl_hdl)
 {
 	return -EPERM;
 }
 
-
 /*
  * Filtering
  */
@@ -611,25 +850,21 @@
 	return -EPERM;
 }
 
-
 static inline int ipa_del_flt_rule(struct ipa_ioc_del_flt_rule *hdls)
 {
 	return -EPERM;
 }
 
-
 static inline int ipa_commit_flt(enum ipa_ip_type ip)
 {
 	return -EPERM;
 }
 
-
 static inline int ipa_reset_flt(enum ipa_ip_type ip)
 {
 	return -EPERM;
 }
 
-
 /*
  * NAT
  */
@@ -656,6 +891,40 @@
 	return -EPERM;
 }
 
+/*
+ * Messaging
+ */
+static inline int ipa_send_msg(struct ipa_msg_meta *meta, void *buff,
+		ipa_msg_free_fn callback)
+{
+	return -EPERM;
+}
+
+static inline int ipa_register_pull_msg(struct ipa_msg_meta *meta,
+		ipa_msg_pull_fn callback)
+{
+	return -EPERM;
+}
+
+static inline int ipa_deregister_pull_msg(struct ipa_msg_meta *meta)
+{
+	return -EPERM;
+}
+
+/*
+ * Interface
+ */
+static inline int ipa_register_intf(const char *name,
+				     const struct ipa_tx_intf *tx,
+				     const struct ipa_rx_intf *rx)
+{
+	return -EPERM;
+}
+
+static inline int ipa_deregister_intf(const char *name)
+{
+	return -EPERM;
+}
 
 /*
  * Aggregation
@@ -665,19 +934,16 @@
 	return -EPERM;
 }
 
-
 static inline int ipa_set_qcncm_ndp_sig(char sig[3])
 {
 	return -EPERM;
 }
 
-
 static inline int ipa_set_single_ndp_per_mbim(bool enable)
 {
 	return -EPERM;
 }
 
-
 /*
  * rmnet bridge
  */
@@ -686,13 +952,11 @@
 	return -EPERM;
 }
 
-
 static inline int rmnet_bridge_disconnect(void)
 {
 	return -EPERM;
 }
 
-
 static inline int rmnet_bridge_connect(u32 producer_hdl,
 			 u32 consumer_hdl,
 			 int wwan_logical_channel_id)
@@ -700,6 +964,23 @@
 	return -EPERM;
 }
 
+/*
+ * SW bridge (between IPA and A2)
+ */
+static inline int ipa_bridge_setup(enum ipa_bridge_dir dir,
+				    enum ipa_bridge_type type,
+				    struct ipa_sys_connect_params *sys_in,
+				    u32 *clnt_hdl)
+{
+	return -EPERM;
+}
+
+static inline int ipa_bridge_teardown(enum ipa_bridge_dir dir,
+				       enum ipa_bridge_type type,
+				      u32 clnt_hdl)
+{
+	return -EPERM;
+}
 
 /*
  * Data path
@@ -710,7 +991,6 @@
 	return -EPERM;
 }
 
-
 /*
  * System pipes
  */
@@ -720,12 +1000,108 @@
 	return -EPERM;
 }
 
-
 static inline int ipa_teardown_sys_pipe(u32 clnt_hdl)
 {
 	return -EPERM;
 }
 
+/*
+ * Resource manager
+ */
+static inline int ipa_rm_create_resource(
+		struct ipa_rm_create_params *create_params)
+{
+	return -EPERM;
+}
+
+static inline int ipa_rm_register(enum ipa_rm_resource_name resource_name,
+			struct ipa_rm_register_params *reg_params)
+{
+	return -EPERM;
+}
+
+static inline int ipa_rm_deregister(enum ipa_rm_resource_name resource_name,
+			struct ipa_rm_register_params *reg_params)
+{
+	return -EPERM;
+}
+
+static inline int ipa_rm_add_dependency(
+		enum ipa_rm_resource_name resource_name,
+		enum ipa_rm_resource_name depends_on_name)
+{
+	return -EPERM;
+}
+
+static inline int ipa_rm_delete_dependency(
+		enum ipa_rm_resource_name resource_name,
+		enum ipa_rm_resource_name depends_on_name)
+{
+	return -EPERM;
+}
+
+static inline int ipa_rm_request_resource(
+		enum ipa_rm_resource_name resource_name)
+{
+	return -EPERM;
+}
+
+static inline int ipa_rm_release_resource(
+		enum ipa_rm_resource_name resource_name)
+{
+	return -EPERM;
+}
+
+static inline int ipa_rm_notify_completion(enum ipa_rm_event event,
+		enum ipa_rm_resource_name resource_name)
+{
+	return -EPERM;
+}
+
+static inline int ipa_rm_inactivity_timer_init(
+		enum ipa_rm_resource_name resource_name,
+			unsigned long msecs)
+{
+	return -EPERM;
+}
+
+static inline int ipa_rm_inactivity_timer_destroy(
+		enum ipa_rm_resource_name resource_name)
+{
+	return -EPERM;
+}
+
+static inline int ipa_rm_inactivity_timer_request_resource(
+				enum ipa_rm_resource_name resource_name)
+{
+	return -EPERM;
+}
+
+static inline int ipa_rm_inactivity_timer_release_resource(
+				enum ipa_rm_resource_name resource_name)
+{
+	return -EPERM;
+}
+
+/*
+ * Tethering bridge (Rmnetm / MBIM)
+ */
+static inline int teth_bridge_init(ipa_notify_cb *usb_notify_cb_ptr,
+				   void **private_data_ptr)
+{
+	return -EPERM;
+}
+
+static inline int teth_bridge_disconnect(void)
+{
+	return -EPERM;
+}
+
+static inline int teth_bridge_connect(struct teth_bridge_connect_params
+				      *connect_params)
+{
+	return -EPERM;
+}
 
 #endif /* CONFIG_IPA*/
 
diff --git a/arch/arm/mach-msm/include/mach/irqs-7x00.h b/arch/arm/mach-msm/include/mach/irqs-7x00.h
index a8e1da2..5b39c4c 100644
--- a/arch/arm/mach-msm/include/mach/irqs-7x00.h
+++ b/arch/arm/mach-msm/include/mach/irqs-7x00.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2010, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  */
 
diff --git a/arch/arm/mach-msm/include/mach/irqs-7x30.h b/arch/arm/mach-msm/include/mach/irqs-7x30.h
index a624bbf..d88fa17 100644
--- a/arch/arm/mach-msm/include/mach/irqs-7x30.h
+++ b/arch/arm/mach-msm/include/mach/irqs-7x30.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/include/mach/irqs-7xxx.h b/arch/arm/mach-msm/include/mach/irqs-7xxx.h
index c90b4ee..bff17ac 100644
--- a/arch/arm/mach-msm/include/mach/irqs-7xxx.h
+++ b/arch/arm/mach-msm/include/mach/irqs-7xxx.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  */
 
@@ -75,7 +75,7 @@
 /* 22-31 are reserved except 7x27a*/
 #if defined(CONFIG_ARCH_MSM7X27A)
 #define INT_L2CC_EM          (32 + 22)
-#define INT_L2CC_INTR        (32 + 23)
+#define SC_SICL2PERFMONIRPTREQ (32 + 23)
 #define INT_CE_IRQ           (32 + 24)
 #endif
 
diff --git a/arch/arm/mach-msm/include/mach/irqs-8064.h b/arch/arm/mach-msm/include/mach/irqs-8064.h
index f4129fe..f604a6e 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8064.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8064.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/include/mach/irqs-8092.h b/arch/arm/mach-msm/include/mach/irqs-8092.h
index 955e669..e766d72 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8092.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8092.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/include/mach/irqs-8625.h b/arch/arm/mach-msm/include/mach/irqs-8625.h
index a83dd2e..c9d5b7f 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8625.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8625.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -83,7 +83,7 @@
 #define MSM8625_INT_UART2DM_IRQ		(GIC_SPI_START + 32 + 20)
 #define MSM8625_INT_UART2DM_RX		(GIC_SPI_START + 32 + 21)
 #define MSM8625_INT_L2CC_EM		(GIC_SPI_START + 32 + 22)
-#define MSM8625_INT_L2CC_INTR		(GIC_SPI_START + 32 + 23)
+#define MSM8625_INT_SC_SICL2PERFMONIRPTREQ	(GIC_SPI_START + 32 + 23)
 #define MSM8625_INT_CE_IRQ		(GIC_SPI_START + 32 + 24)
 #define MSM8625_INT_CPR_IRQ0		(GIC_SPI_START + 32 + 25)
 #define MSM8625_INT_CPR_IRQ1		(GIC_SPI_START + 32 + 26)
diff --git a/arch/arm/mach-msm/include/mach/irqs-8930.h b/arch/arm/mach-msm/include/mach/irqs-8930.h
index fbde7cb..b6c7257 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8930.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8930.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/irqs-8960.h b/arch/arm/mach-msm/include/mach/irqs-8960.h
index 64be113..07915d1 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8960.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8960.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/include/mach/irqs-8974.h b/arch/arm/mach-msm/include/mach/irqs-8974.h
index d11c35c..95d6aae 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8974.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8974.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/include/mach/irqs-8x50.h b/arch/arm/mach-msm/include/mach/irqs-8x50.h
index f0d70f9..7f62ee4 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8x50.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8x50.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/arch/arm/mach-msm/include/mach/irqs-8x60.h b/arch/arm/mach-msm/include/mach/irqs-8x60.h
index d08f645..a2936bf 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8x60.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8x60.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011 Code Aurora Forum. All rights reserved.
+/* 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
@@ -242,7 +242,6 @@
 #define SMPSS_SPARE_6				(GIC_SPI_START + 222)
 #define SMPSS_SPARE_7				(GIC_SPI_START + 223)
 
-#define NR_TLMM_MSM_DIR_CONN_IRQ 10
 #define NR_GPIO_IRQS 173
 #define NR_MSM_GPIOS NR_GPIO_IRQS
 #define NR_MSM_IRQS 256
diff --git a/arch/arm/mach-msm/include/mach/irqs-9615.h b/arch/arm/mach-msm/include/mach/irqs-9615.h
index b9c66c3..285fce4 100644
--- a/arch/arm/mach-msm/include/mach/irqs-9615.h
+++ b/arch/arm/mach-msm/include/mach/irqs-9615.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
@@ -181,7 +181,6 @@
 #define NR_WCD9XXX_IRQS 49
 #define NR_TABLA_IRQS NR_WCD9XXX_IRQS
 #define NR_BOARD_IRQS (NR_PM8018_IRQS + NR_WCD9XXX_IRQS)
-#define NR_TLMM_MSM_DIR_CONN_IRQ 8 /*Need to Verify this Count*/
 #define NR_MSM_GPIOS NR_GPIO_IRQS
 
 /* Backwards compatible IRQ macros. */
diff --git a/arch/arm/mach-msm/include/mach/irqs-9625.h b/arch/arm/mach-msm/include/mach/irqs-9625.h
index 9ba77af..e4e1043 100644
--- a/arch/arm/mach-msm/include/mach/irqs-9625.h
+++ b/arch/arm/mach-msm/include/mach/irqs-9625.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -20,10 +20,6 @@
 #define APCC_QGICL2PERFMONIRPTREQ	(GIC_SPI_START + 1)
 #define SC_SICL2PERFMONIRPTREQ		APCC_QGICL2PERFMONIRPTREQ
 
-#define NR_MSM_IRQS 288
-#define NR_GPIO_IRQS 76
-#define NR_BOARD_IRQS 0
 #define NR_TLMM_MSM_DIR_CONN_IRQ 8 /*Need to Verify this Count*/
-#define NR_MSM_GPIOS NR_GPIO_IRQS
 
 #endif
diff --git a/arch/arm/mach-msm/include/mach/irqs-fsm9xxx.h b/arch/arm/mach-msm/include/mach/irqs-fsm9xxx.h
index 721db1d..5b36bde 100644
--- a/arch/arm/mach-msm/include/mach/irqs-fsm9xxx.h
+++ b/arch/arm/mach-msm/include/mach/irqs-fsm9xxx.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/irqs.h b/arch/arm/mach-msm/include/mach/irqs.h
index 8c6b959..65d5d02 100644
--- a/arch/arm/mach-msm/include/mach/irqs.h
+++ b/arch/arm/mach-msm/include/mach/irqs.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2013, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -37,22 +37,6 @@
 #include "irqs-8092.h"
 #endif
 
-#define NR_MSM_IRQS 1020 /* Should be 256 - but higher due to bug in sim */
-#define NR_GPIO_IRQS 146
-#define NR_QPNP_IRQS 32768
-#define NR_BOARD_IRQS NR_QPNP_IRQS
-#define NR_TLMM_MSM_DIR_CONN_IRQ 8
-#define NR_MSM_GPIOS NR_GPIO_IRQS
-
-#elif defined(CONFIG_ARCH_MSM8910) || defined(CONFIG_ARCH_MSM8226)
-
-#define NR_MSM_IRQS 256
-#define NR_GPIO_IRQS 117
-#define NR_QPNP_IRQS 32768
-#define NR_BOARD_IRQS NR_QPNP_IRQS
-#define NR_TLMM_MSM_DIR_CONN_IRQ 8
-#define NR_MSM_GPIOS NR_GPIO_IRQS
-
 #elif defined(CONFIG_ARCH_MSM8960) || defined(CONFIG_ARCH_APQ8064) || \
 	defined(CONFIG_ARCH_MSM8930)
 
@@ -85,7 +69,6 @@
 #define NR_BOARD_IRQS (NR_PM8921_IRQS + NR_PM8821_IRQS + \
 		NR_WCD9XXX_IRQS + NR_GPIO_EXPANDER_IRQS)
 #endif
-#define NR_TLMM_MSM_DIR_CONN_IRQ 8 /*Need to Verify this Count*/
 #define NR_MSM_GPIOS NR_GPIO_IRQS
 
 #else
@@ -113,17 +96,36 @@
 #elif defined(CONFIG_ARCH_FSM9XXX)
 #include "irqs-fsm9xxx.h"
 #include "sirc.h"
-#else
-#error "Unknown architecture specification"
 #endif
 
 #endif
 
 #if !defined(CONFIG_SPARSE_IRQ)
+
+#if defined(CONFIG_ARCH_MSM8974) || defined(CONFIG_ARCH_MPQ8092)
+#define NR_MSM_IRQS 1020 /* Should be 256 - but higher due to bug in sim */
+#define NR_GPIO_IRQS 146
+#define NR_QPNP_IRQS 32768
+#define NR_BOARD_IRQS NR_QPNP_IRQS
+
+#elif defined(CONFIG_ARCH_MSM8610) || defined(CONFIG_ARCH_MSM8226)
+#define NR_MSM_IRQS 256
+#define NR_GPIO_IRQS 117
+#define NR_QPNP_IRQS 32768
+#define NR_BOARD_IRQS NR_QPNP_IRQS
+
+#elif defined(CONFIG_ARCH_MSM9625)
+#define NR_MSM_IRQS 288
+#define NR_GPIO_IRQS 76
+#define NR_BOARD_IRQS 0
+
+#endif
+
 #define NR_IRQS (NR_MSM_IRQS + NR_GPIO_IRQS + NR_BOARD_IRQS)
 #define MSM_GPIO_TO_INT(n) (NR_MSM_IRQS + (n))
 #define FIRST_GPIO_IRQ MSM_GPIO_TO_INT(0)
 #define MSM_INT_TO_REG(base, irq) (base + irq / 32)
+
 #endif
 
 #if defined(CONFIG_PCI_MSI) && defined(CONFIG_MSM_PCIE)
diff --git a/arch/arm/mach-msm/include/mach/jtag.h b/arch/arm/mach-msm/include/mach/jtag.h
index 3850eff..2131be6 100644
--- a/arch/arm/mach-msm/include/mach/jtag.h
+++ b/arch/arm/mach-msm/include/mach/jtag.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -13,7 +13,7 @@
 #ifndef __MACH_JTAG_H
 #define __MACH_JTAG_H
 
-#ifdef CONFIG_MSM_JTAG
+#if defined(CONFIG_MSM_JTAG) || defined(CONFIG_MSM_JTAG_MM)
 extern void msm_jtag_save_state(void);
 extern void msm_jtag_restore_state(void);
 #else
diff --git a/arch/arm/mach-msm/include/mach/kgsl.h b/arch/arm/mach-msm/include/mach/kgsl.h
index f07a9e8..b68aff8 100644
--- a/arch/arm/mach-msm/include/mach/kgsl.h
+++ b/arch/arm/mach-msm/include/mach/kgsl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -21,7 +21,7 @@
 #define KGSL_CLK_MEM_IFACE 0x00000010
 #define KGSL_CLK_AXI	0x00000020
 
-#define KGSL_MAX_PWRLEVELS 5
+#define KGSL_MAX_PWRLEVELS 10
 
 #define KGSL_CONVERT_TO_MBPS(val) \
 	(val*1000*1000U)
@@ -73,6 +73,7 @@
 	unsigned int nap_allowed;
 	unsigned int clk_map;
 	unsigned int idle_needed;
+	unsigned int step_mul;
 	struct msm_bus_scale_pdata *bus_scale_table;
 	struct kgsl_device_iommu_data *iommu_data;
 	int iommu_count;
diff --git a/arch/arm/mach-msm/include/mach/mdm-peripheral.h b/arch/arm/mach-msm/include/mach/mdm-peripheral.h
index 0f3bd33..ef44659 100644
--- a/arch/arm/mach-msm/include/mach/mdm-peripheral.h
+++ b/arch/arm/mach-msm/include/mach/mdm-peripheral.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/mdm.h b/arch/arm/mach-msm/include/mach/mdm.h
index f0100fe..9757d31 100644
--- a/arch/arm/mach-msm/include/mach/mdm.h
+++ b/arch/arm/mach-msm/include/mach/mdm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/mdm2.h b/arch/arm/mach-msm/include/mach/mdm2.h
index fd63fd2..46069d2 100644
--- a/arch/arm/mach-msm/include/mach/mdm2.h
+++ b/arch/arm/mach-msm/include/mach/mdm2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -24,6 +24,7 @@
 struct mdm_platform_data {
 	char *mdm_version;
 	int ramdump_delay_ms;
+	int ps_hold_delay_ms;
 	int soft_reset_inverted;
 	int early_power_on;
 	int sfr_query;
diff --git a/arch/arm/mach-msm/include/mach/memory.h b/arch/arm/mach-msm/include/mach/memory.h
index d089924..cf68108 100644
--- a/arch/arm/mach-msm/include/mach/memory.h
+++ b/arch/arm/mach-msm/include/mach/memory.h
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/include/mach/memory.h
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/mpm.h b/arch/arm/mach-msm/include/mach/mpm.h
index fabaa09..b92c039 100644
--- a/arch/arm/mach-msm/include/mach/mpm.h
+++ b/arch/arm/mach-msm/include/mach/mpm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/mpp.h b/arch/arm/mach-msm/include/mach/mpp.h
index 8ac1f54..040312c 100644
--- a/arch/arm/mach-msm/include/mach/mpp.h
+++ b/arch/arm/mach-msm/include/mach/mpp.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/arch/arm/mach-msm/include/mach/msm72k_otg.h b/arch/arm/mach-msm/include/mach/msm72k_otg.h
index 50e2936..ac99d47 100644
--- a/arch/arm/mach-msm/include/mach/msm72k_otg.h
+++ b/arch/arm/mach-msm/include/mach/msm72k_otg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/include/mach/msm_adsp.h b/arch/arm/mach-msm/include/mach/msm_adsp.h
index ea08f0c..0797447 100644
--- a/arch/arm/mach-msm/include/mach/msm_adsp.h
+++ b/arch/arm/mach-msm/include/mach/msm_adsp.h
@@ -1,7 +1,7 @@
 /* include/asm-arm/arch-msm/msm_adsp.h
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2009-2010, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2010, 2012 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/msm_audio_aac.h b/arch/arm/mach-msm/include/mach/msm_audio_aac.h
index 8c4d91b..ac54173 100644
--- a/arch/arm/mach-msm/include/mach/msm_audio_aac.h
+++ b/arch/arm/mach-msm/include/mach/msm_audio_aac.h
@@ -1,6 +1,6 @@
 /* arch/arm/mach-msm/include/mach/msm_audio_aac.h
  *
- * Copyright (c) 2009 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009 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
diff --git a/arch/arm/mach-msm/include/mach/msm_battery.h b/arch/arm/mach-msm/include/mach/msm_battery.h
index fe496d5..959d8a8 100644
--- a/arch/arm/mach-msm/include/mach/msm_battery.h
+++ b/arch/arm/mach-msm/include/mach/msm_battery.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/include/mach/msm_bus.h b/arch/arm/mach-msm/include/mach/msm_bus.h
index 6b94a43..049cf02 100644
--- a/arch/arm/mach-msm/include/mach/msm_bus.h
+++ b/arch/arm/mach-msm/include/mach/msm_bus.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
@@ -78,24 +78,11 @@
 uint32_t msm_bus_scale_register_client(struct msm_bus_scale_pdata *pdata);
 int msm_bus_scale_client_update_request(uint32_t cl, unsigned int index);
 void msm_bus_scale_unregister_client(uint32_t cl);
-struct msm_bus_scale_pdata *msm_bus_cl_get_pdata(struct platform_device *pdev);
-void msm_bus_cl_clear_pdata(struct msm_bus_scale_pdata *pdata);
 /* AXI Port configuration APIs */
 int msm_bus_axi_porthalt(int master_port);
 int msm_bus_axi_portunhalt(int master_port);
 
 #else
-static inline struct msm_bus_scale_pdata
-*msm_bus_cl_get_pdata(struct platform_device *pdev)
-{
-	return NULL;
-}
-
-static inline void
-msm_bus_cl_clear_pdata(struct msm_bus_scale_pdata *pdata)
-{
-}
-
 static inline uint32_t
 msm_bus_scale_register_client(struct msm_bus_scale_pdata *pdata)
 {
@@ -124,4 +111,18 @@
 }
 #endif
 
+#if defined(CONFIG_OF) && defined(CONFIG_MSM_BUS_SCALING)
+struct msm_bus_scale_pdata *msm_bus_cl_get_pdata(struct platform_device *pdev);
+void msm_bus_cl_clear_pdata(struct msm_bus_scale_pdata *pdata);
+#else
+static inline struct msm_bus_scale_pdata
+*msm_bus_cl_get_pdata(struct platform_device *pdev)
+{
+	return NULL;
+}
+
+static inline void msm_bus_cl_clear_pdata(struct msm_bus_scale_pdata *pdata)
+{
+}
+#endif
 #endif /*_ARCH_ARM_MACH_MSM_BUS_H*/
diff --git a/arch/arm/mach-msm/include/mach/msm_bus_board.h b/arch/arm/mach-msm/include/mach/msm_bus_board.h
index ab0e72f..8fd3cfc 100644
--- a/arch/arm/mach-msm/include/mach/msm_bus_board.h
+++ b/arch/arm/mach-msm/include/mach/msm_bus_board.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -24,7 +24,7 @@
 
 struct msm_bus_fabric_registration {
 	unsigned int id;
-	char *name;
+	const char *name;
 	struct msm_bus_node_info *info;
 	unsigned int len;
 	int ahb;
@@ -33,9 +33,9 @@
 	unsigned int offset;
 	unsigned int haltid;
 	unsigned int rpm_enabled;
-	const unsigned int nmasters;
-	const unsigned int nslaves;
-	const unsigned int ntieredslaves;
+	unsigned int nmasters;
+	unsigned int nslaves;
+	unsigned int ntieredslaves;
 	bool il_flag;
 	const struct msm_bus_board_algorithm *board_algo;
 	int hw_sel;
@@ -102,6 +102,10 @@
 int msm_bus_board_rpm_get_il_ids(uint16_t *id);
 int msm_bus_board_get_iid(int id);
 
+#ifdef CONFIG_ARCH_MSM8226
+#define NFAB 6
+#endif
+
 /*
  * These macros specify the convention followed for allocating
  * ids to fabrics, masters and slaves for 8x60.
@@ -111,7 +115,6 @@
  */
 #define FABRIC_ID_KEY 1024
 #define SLAVE_ID_KEY ((FABRIC_ID_KEY) >> 1)
-#define NUM_FAB 5
 #define MAX_FAB_KEY 7168  /* OR(All fabric ids) */
 
 #define GET_FABID(id) ((id) & MAX_FAB_KEY)
@@ -300,7 +303,7 @@
 	MSM_BUS_MASTER_IPA,
 	MSM_BUS_MASTER_QPIC,
 
-	MSM_BUS_MASTER_LAST = MSM_BUS_MASTER_QPIC,
+	MSM_BUS_MASTER_LAST,
 
 	MSM_BUS_SYSTEM_FPB_MASTER_SYSTEM =
 		MSM_BUS_SYSTEM_MASTER_SYSTEM_FPB,
@@ -457,7 +460,7 @@
 	MSM_BUS_SLAVE_IPS_CFG,
 	MSM_BUS_SLAVE_QPIC,
 
-	MSM_BUS_SLAVE_LAST = MSM_BUS_SLAVE_QPIC,
+	MSM_BUS_SLAVE_LAST,
 
 	MSM_BUS_SYSTEM_FPB_SLAVE_SYSTEM =
 		MSM_BUS_SYSTEM_SLAVE_SYSTEM_FPB,
diff --git a/arch/arm/mach-msm/include/mach/msm_cache_dump.h b/arch/arm/mach-msm/include/mach/msm_cache_dump.h
index 80f4159..a79bcbd 100644
--- a/arch/arm/mach-msm/include/mach/msm_cache_dump.h
+++ b/arch/arm/mach-msm/include/mach/msm_cache_dump.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/include/mach/msm_dsps.h b/arch/arm/mach-msm/include/mach/msm_dsps.h
index ac81616..8e77f07 100644
--- a/arch/arm/mach-msm/include/mach/msm_dsps.h
+++ b/arch/arm/mach-msm/include/mach/msm_dsps.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/include/mach/msm_fb.h b/arch/arm/mach-msm/include/mach/msm_fb.h
index 3bbaa25..3e42048 100644
--- a/arch/arm/mach-msm/include/mach/msm_fb.h
+++ b/arch/arm/mach-msm/include/mach/msm_fb.h
@@ -77,7 +77,7 @@
 			     uint32_t reg);
 	uint32_t (*remote_read)(struct msm_mddi_client_data *, uint32_t reg);
 	void (*auto_hibernate)(struct msm_mddi_client_data *, int);
-	/* custom data that needs to be passed from the board file to a 
+	/* custom data that needs to be passed from the board file to a
 	 * particular client */
 	void *private_client_data;
 	struct resource *fb_resource;
@@ -190,7 +190,7 @@
 
 struct mdp_v4l2_req;
 int msm_fb_v4l2_enable(struct mdp_overlay *req, bool enable, void **par);
-int msm_fb_v4l2_update(void *par,
+int msm_fb_v4l2_update(void *par, bool bUserPtr,
 	unsigned long srcp0_addr, unsigned long srcp0_size,
 	unsigned long srcp1_addr, unsigned long srcp1_size,
 	unsigned long srcp2_addr, unsigned long srcp2_size);
diff --git a/arch/arm/mach-msm/include/mach/msm_gpiomux.h b/arch/arm/mach-msm/include/mach/msm_gpiomux.h
index 0c7d393..b70a449 100644
--- a/arch/arm/mach-msm/include/mach/msm_gpiomux.h
+++ b/arch/arm/mach-msm/include/mach/msm_gpiomux.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/msm_hdmi_audio.h b/arch/arm/mach-msm/include/mach/msm_hdmi_audio.h
index 9b04141..9a35c73 100644
--- a/arch/arm/mach-msm/include/mach/msm_hdmi_audio.h
+++ b/arch/arm/mach-msm/include/mach/msm_hdmi_audio.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/include/mach/msm_hsusb.h b/arch/arm/mach-msm/include/mach/msm_hsusb.h
index c6eb527..f5f890f 100644
--- a/arch/arm/mach-msm/include/mach/msm_hsusb.h
+++ b/arch/arm/mach-msm/include/mach/msm_hsusb.h
@@ -1,7 +1,7 @@
 /* linux/include/mach/hsusb.h
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/msm_hsusb_hw.h b/arch/arm/mach-msm/include/mach/msm_hsusb_hw.h
index 831b40e..94a1f36 100644
--- a/arch/arm/mach-msm/include/mach/msm_hsusb_hw.h
+++ b/arch/arm/mach-msm/include/mach/msm_hsusb_hw.h
@@ -1,6 +1,6 @@
  /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/msm_i2ckbd.h b/arch/arm/mach-msm/include/mach/msm_i2ckbd.h
index dc33c75..ba42b15 100644
--- a/arch/arm/mach-msm/include/mach/msm_i2ckbd.h
+++ b/arch/arm/mach-msm/include/mach/msm_i2ckbd.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h
index dfc6f23..4f3d969 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012 The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7xxx.h b/arch/arm/mach-msm/include/mach/msm_iomap-7xxx.h
index 4c26d08..ae7334e 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-7xxx.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-7xxx.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8064.h b/arch/arm/mach-msm/include/mach/msm_iomap-8064.h
index 10e2b74..5ecd105 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8064.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8064.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8092.h b/arch/arm/mach-msm/include/mach/msm_iomap-8092.h
index 732aaff..2fdd99c 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8092.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8092.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8226.h b/arch/arm/mach-msm/include/mach/msm_iomap-8226.h
index ab43a8a..81b3c48 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8226.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8226.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 software is licensed under the terms of the GNU General Public
@@ -37,9 +37,6 @@
 #define MSM8226_TLMM_PHYS	0xFD510000
 #define MSM8226_TLMM_SIZE	SZ_16K
 
-#define MSM8226_IMEM_PHYS	0xFE805000
-#define MSM8226_IMEM_SIZE	SZ_4K
-
 #define MSM8226_MPM2_PSHOLD_PHYS	0xFC4AB000
 #define MSM8226_MPM2_PSHOLD_SIZE	SZ_4K
 
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8610.h b/arch/arm/mach-msm/include/mach/msm_iomap-8610.h
new file mode 100644
index 0000000..b07ddba
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8610.h
@@ -0,0 +1,41 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 __ASM_ARCH_MSM_IOMAP_8610_H
+#define __ASM_ARCH_MSM_IOMAP_8610_H
+
+/* Physical base address and size of peripherals.
+ * Ordered by the virtual base addresses they will be mapped at.
+ *
+ * If you add or remove entries here, you'll want to edit the
+ * io desc array in arch/arm/mach-msm/io.c to reflect your
+ * changes.
+ *
+ */
+
+#define MSM8610_MSM_SHARED_RAM_PHYS	0x0D600000
+
+#define MSM8610_APCS_GCC_PHYS	0xF9011000
+#define MSM8610_APCS_GCC_SIZE	SZ_4K
+
+#define MSM8610_TLMM_PHYS	0xFD510000
+#define MSM8610_TLMM_SIZE	SZ_16K
+
+#define MSM8610_MPM2_PSHOLD_PHYS	0xFC4AB000
+#define MSM8610_MPM2_PSHOLD_SIZE	SZ_4K
+
+#ifdef CONFIG_DEBUG_MSM8610_UART
+#define MSM_DEBUG_UART_BASE	IOMEM(0xFA71E000)
+#define MSM_DEBUG_UART_PHYS	0xF991E000
+#endif
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8625.h b/arch/arm/mach-msm/include/mach/msm_iomap-8625.h
index 9b6de20..1cf8207 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8625.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8625.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8910.h b/arch/arm/mach-msm/include/mach/msm_iomap-8910.h
deleted file mode 100644
index 64990da..0000000
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8910.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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 __ASM_ARCH_MSM_IOMAP_8910_H
-#define __ASM_ARCH_MSM_IOMAP_8910_H
-
-/* Physical base address and size of peripherals.
- * Ordered by the virtual base addresses they will be mapped at.
- *
- * If you add or remove entries here, you'll want to edit the
- * io desc array in arch/arm/mach-msm/io.c to reflect your
- * changes.
- *
- */
-
-#define MSM8910_MSM_SHARED_RAM_PHYS	0x0D600000
-
-#define MSM8910_APCS_GCC_PHYS	0xF9011000
-#define MSM8910_APCS_GCC_SIZE	SZ_4K
-
-#define MSM8910_TLMM_PHYS	0xFD510000
-#define MSM8910_TLMM_SIZE	SZ_16K
-
-#define MSM8910_IMEM_PHYS	0xFE805000
-#define MSM8910_IMEM_SIZE	SZ_4K
-
-#define MSM8910_MPM2_PSHOLD_PHYS	0xFC4AB000
-#define MSM8910_MPM2_PSHOLD_SIZE	SZ_4K
-
-#ifdef CONFIG_DEBUG_MSM8910_UART
-#define MSM_DEBUG_UART_BASE	IOMEM(0xFA71E000)
-#define MSM_DEBUG_UART_PHYS	0xF991E000
-#endif
-
-#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8930.h b/arch/arm/mach-msm/include/mach/msm_iomap-8930.h
index f3f8b8f..456c39d 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8930.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8930.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2011, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8960.h b/arch/arm/mach-msm/include/mach/msm_iomap-8960.h
index 2cea3c3..2329540 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8960.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8960.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2011, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8974.h b/arch/arm/mach-msm/include/mach/msm_iomap-8974.h
index 15be294..594b1cc 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8974.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8974.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -40,27 +40,9 @@
 #define MSM8974_MPM2_PSHOLD_PHYS	0xFC4AB000
 #define MSM8974_MPM2_PSHOLD_SIZE	SZ_4K
 
-/*
- * TODO: Revert IMEM_PHYS back to actual
- * address 0xfe805000
- * after IMEM issues resolved.
- *
- */
-#define MSM8974_IMEM_PHYS	0xFC42B000
-#define MSM8974_IMEM_SIZE	SZ_4K
-
 #ifdef CONFIG_DEBUG_MSM8974_UART
 #define MSM_DEBUG_UART_BASE	IOMEM(0xFA71E000)
 #define MSM_DEBUG_UART_PHYS	0xF991E000
 #endif
 
-/*
- * IMEM is retained for secure watchdog reset
- * Debug Image looks at actual IMEM to
- * do memory dumping.
- */
-
-#define MSM8974_DBG_IMEM_PHYS	0xFE805000
-#define MSM8974_DBG_IMEM_SIZE	SZ_4K
-
 #endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h
index a1b32ec..281b602 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2010, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
index fe928b9..b86364f 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-9615.h b/arch/arm/mach-msm/include/mach/msm_iomap-9615.h
index fc9b198..c815294 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-9615.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-9615.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-9625.h b/arch/arm/mach-msm/include/mach/msm_iomap-9625.h
index 89252a5..341bbe3 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-9625.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-9625.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -40,15 +40,6 @@
 #define MSM9625_TLMM_PHYS	0xFD510000
 #define MSM9625_TLMM_SIZE	SZ_16K
 
-/*
- * TODO: Revert IMEM_PHYS back to actual
- * address 0xfe807800
- * after IMEM issues resolved.
- *
- */
-#define MSM9625_IMEM_PHYS	0xFC42B000
-#define MSM9625_IMEM_SIZE	SZ_2K
-
 #define MSM9625_MPM2_PSHOLD_PHYS	0xFC4AB000
 #define MSM9625_MPM2_PSHOLD_SIZE	SZ_4K
 
@@ -57,13 +48,4 @@
 #define MSM_DEBUG_UART_PHYS	0xF991E000
 #endif
 
-/*
- * IMEM is retained for secure watchdog reset
- * Debug Image looks at actual IMEM to
- * do memory dumping.
- */
-
-#define MSM9625_DBG_IMEM_PHYS	0xFE807800
-#define MSM9625_DBG_IMEM_SIZE	SZ_4K
-
 #endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-fsm9xxx.h b/arch/arm/mach-msm/include/mach/msm_iomap-fsm9xxx.h
index a99f1f7..9b4204d 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-fsm9xxx.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-fsm9xxx.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h
index f372b1e..ebb096e 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2013, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -54,7 +54,7 @@
 	defined(CONFIG_ARCH_MSM7X25) || defined(CONFIG_ARCH_MSM7X01A) || \
 	defined(CONFIG_ARCH_MSM8625) || defined(CONFIG_ARCH_MSM7X30) || \
 	defined(CONFIG_ARCH_MSM9625) || defined(CONFIG_ARCH_MPQ8092) || \
-	defined(CONFIG_ARCH_MSM8226) || defined(CONFIG_ARCH_MSM8910)
+	defined(CONFIG_ARCH_MSM8226) || defined(CONFIG_ARCH_MSM8610)
 
 /* Unified iomap */
 
@@ -67,7 +67,11 @@
 #define MSM_SAW_L2_BASE		IOMEM(0xFA007000)	/*  4K	*/
 #define MSM_SAW0_BASE		IOMEM(0xFA008000)	/*  4K	*/
 #define MSM_SAW1_BASE		IOMEM(0xFA009000)	/*  4K	*/
+
+#ifndef CONFIG_ARCH_MSM9625
 #define MSM_IMEM_BASE		IOMEM(0xFA00A000)	/*  4K	*/
+#endif
+
 #define MSM_ACC0_BASE		IOMEM(0xFA00B000)	/*  4K	*/
 #define MSM_ACC1_BASE		IOMEM(0xFA00C000)	/*  4K	*/
 #define MSM_ACC2_BASE		IOMEM(0xFA00D000)	/*  4K	*/
@@ -77,7 +81,7 @@
 #define MSM_LPASS_CLK_CTL_BASE	IOMEM(0xFA015000)	/*  4K	*/
 #define MSM_HFPLL_BASE		IOMEM(0xFA016000)	/*  4K	*/
 #define MSM_TLMM_BASE		IOMEM(0xFA017000)	/* 16K	*/
-#define MSM_SHARED_RAM_BASE	IOMEM(0xFA300000)	/*  2M  */
+#define MSM_SHARED_RAM_BASE	IOMEM(0xFA400000)	/*  2M  */
 #define MSM_SIC_NON_SECURE_BASE	IOMEM(0xFA600000)	/* 64K	*/
 #define MSM_HDMI_BASE		IOMEM(0xFA800000)	/*  4K  */
 #define MSM_RPM_BASE		IOMEM(0xFA801000)	/*  4K	*/
@@ -98,7 +102,13 @@
 #define MSM_MDC_BASE		IOMEM(0xFA400000)	/*  1M */
 #define MSM_AD5_BASE		IOMEM(0xFA900000)	/*  13M (D00000)
 							  0xFB600000 */
-#define MSM_DBG_IMEM_BASE	IOMEM(0xFB600000)	/*  4K */
+/* MSM9625 has unaligned imem so we need to map excess 2K virtually
+ * to get the correct mapping. This should not be done for any
+ * other chipset under normal circumstances.
+ */
+#ifdef CONFIG_ARCH_MSM9625
+#define MSM_IMEM_BASE		IOMEM(0xFB601800)	/* 6K -> 8K */
+#endif
 
 #define MSM_STRONGLY_ORDERED_PAGE	0xFA0F0000
 #define MSM8625_CPU_PHYS		0x0FE00000
@@ -122,7 +132,7 @@
 #include "msm_iomap-9625.h"
 #include "msm_iomap-8092.h"
 #include "msm_iomap-8226.h"
-#include "msm_iomap-8910.h"
+#include "msm_iomap-8610.h"
 
 #else
 /* Legacy single-target iomap */
diff --git a/arch/arm/mach-msm/include/mach/msm_ipc_logging.h b/arch/arm/mach-msm/include/mach/msm_ipc_logging.h
index 0a203a5..b675c00 100644
--- a/arch/arm/mach-msm/include/mach/msm_ipc_logging.h
+++ b/arch/arm/mach-msm/include/mach/msm_ipc_logging.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -113,7 +113,7 @@
  * @ilctxt: Debug Log Context created using ipc_log_context_create()
  * @fmt:    Data specified using format specifiers
  */
-int ipc_log_string(void *ilctxt, const char *fmt, ...);
+int ipc_log_string(void *ilctxt, const char *fmt, ...) __printf(2, 3);
 
 /*
  * Print a string to decode context.
@@ -185,47 +185,49 @@
 				      struct decode_context *));
 #else
 
-void *ipc_log_context_create(int max_num_pages, const char *modname)
+static inline void *ipc_log_context_create(int max_num_pages,
+	const char *modname)
 { return NULL; }
 
-void msg_encode_start(struct encode_context *ectxt, uint32_t type) { }
+static inline void msg_encode_start(struct encode_context *ectxt,
+	uint32_t type) { }
 
-int tsv_timestamp_write(struct encode_context *ectxt)
+static inline int tsv_timestamp_write(struct encode_context *ectxt)
 { return -EINVAL; }
 
-int tsv_pointer_write(struct encode_context *ectxt, void *pointer)
+static inline int tsv_pointer_write(struct encode_context *ectxt, void *pointer)
 { return -EINVAL; }
 
-int tsv_int32_write(struct encode_context *ectxt, int32_t n)
+static inline int tsv_int32_write(struct encode_context *ectxt, int32_t n)
 { return -EINVAL; }
 
-int tsv_byte_array_write(struct encode_context *ectxt,
+static inline int tsv_byte_array_write(struct encode_context *ectxt,
 			 void *data, int data_size)
 { return -EINVAL; }
 
-void msg_encode_end(struct encode_context *ectxt) { }
+static inline void msg_encode_end(struct encode_context *ectxt) { }
 
-void ipc_log_write(void *ctxt, struct encode_context *ectxt) { }
+static inline void ipc_log_write(void *ctxt, struct encode_context *ectxt) { }
 
-int ipc_log_string(void *ilctxt, const char *fmt, ...)
+static inline int ipc_log_string(void *ilctxt, const char *fmt, ...)
 { return -EINVAL; }
 
 #define IPC_SPRINTF_DECODE(dctxt, args...) do { } while (0)
 
-void tsv_timestamp_read(struct encode_context *ectxt,
+static inline void tsv_timestamp_read(struct encode_context *ectxt,
 			struct decode_context *dctxt, const char *format) { }
 
-void tsv_pointer_read(struct encode_context *ectxt,
+static inline void tsv_pointer_read(struct encode_context *ectxt,
 		      struct decode_context *dctxt, const char *format) { }
 
-int32_t tsv_int32_read(struct encode_context *ectxt,
+static inline int32_t tsv_int32_read(struct encode_context *ectxt,
 		       struct decode_context *dctxt, const char *format)
 { return 0; }
 
-void tsv_byte_array_read(struct encode_context *ectxt,
+static inline void tsv_byte_array_read(struct encode_context *ectxt,
 			 struct decode_context *dctxt, const char *format) { }
 
-int add_deserialization_func(void *ctxt, int type,
+static inline int add_deserialization_func(void *ctxt, int type,
 			void (*dfunc)(struct encode_context *,
 				      struct decode_context *))
 { return 0; }
diff --git a/arch/arm/mach-msm/include/mach/msm_memory_dump.h b/arch/arm/mach-msm/include/mach/msm_memory_dump.h
index 729a077..89df485 100644
--- a/arch/arm/mach-msm/include/mach/msm_memory_dump.h
+++ b/arch/arm/mach-msm/include/mach/msm_memory_dump.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/include/mach/msm_memtypes.h b/arch/arm/mach-msm/include/mach/msm_memtypes.h
index 80e454a..a989059 100644
--- a/arch/arm/mach-msm/include/mach/msm_memtypes.h
+++ b/arch/arm/mach-msm/include/mach/msm_memtypes.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/msm_migrate_pages.h b/arch/arm/mach-msm/include/mach/msm_migrate_pages.h
index 5812a64..51d98ba 100644
--- a/arch/arm/mach-msm/include/mach/msm_migrate_pages.h
+++ b/arch/arm/mach-msm/include/mach/msm_migrate_pages.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/msm_mpmctr.h b/arch/arm/mach-msm/include/mach/msm_mpmctr.h
new file mode 100644
index 0000000..d3d853f
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_mpmctr.h
@@ -0,0 +1,21 @@
+/*
+ * 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 __MSM_MPMCTR_H__
+#define __MSM_MPMCTR_H__
+
+/*
+ * returns the count value of the mpm timetick.
+ */
+uint32_t msm_mpm_get_count(void);
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_otg.h b/arch/arm/mach-msm/include/mach/msm_otg.h
index 178b65a..9d30cb9 100644
--- a/arch/arm/mach-msm/include/mach/msm_otg.h
+++ b/arch/arm/mach-msm/include/mach/msm_otg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/msm_pcie.h b/arch/arm/mach-msm/include/mach/msm_pcie.h
index 74f0f5b..790a390 100644
--- a/arch/arm/mach-msm/include/mach/msm_pcie.h
+++ b/arch/arm/mach-msm/include/mach/msm_pcie.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -36,6 +36,7 @@
 	uint32_t                      axi_addr;
 	uint32_t                      axi_size;
 	uint32_t                      wake_n;
+	uint32_t                      vreg_n;
 };
 
 #endif
diff --git a/arch/arm/mach-msm/include/mach/msm_qdsp6_audiov2.h b/arch/arm/mach-msm/include/mach/msm_qdsp6_audiov2.h
index 90a6b56..f862c36 100644
--- a/arch/arm/mach-msm/include/mach/msm_qdsp6_audiov2.h
+++ b/arch/arm/mach-msm/include/mach/msm_qdsp6_audiov2.h
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/include/mach/msm_qdsp6_audio.h
  *
  * Copyright (C) 2009 Google, Inc.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * Author: Brian Swetland <swetland@google.com>
  *
diff --git a/arch/arm/mach-msm/include/mach/msm_rotator_imem.h b/arch/arm/mach-msm/include/mach/msm_rotator_imem.h
index 580bc81..c027ab7 100644
--- a/arch/arm/mach-msm/include/mach/msm_rotator_imem.h
+++ b/arch/arm/mach-msm/include/mach/msm_rotator_imem.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/include/mach/msm_rpcrouter.h b/arch/arm/mach-msm/include/mach/msm_rpcrouter.h
index 28841a9..b055e94 100644
--- a/arch/arm/mach-msm/include/mach/msm_rpcrouter.h
+++ b/arch/arm/mach-msm/include/mach/msm_rpcrouter.h
@@ -1,7 +1,7 @@
 /** include/asm-arm/arch-msm/msm_rpcrouter.h
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2011, The Linux Foundation. All rights reserved.
  * Author: San Mehat <san@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/msm_rtb.h b/arch/arm/mach-msm/include/mach/msm_rtb.h
index 74ddfbd..19d171e 100644
--- a/arch/arm/mach-msm/include/mach/msm_rtb.h
+++ b/arch/arm/mach-msm/include/mach/msm_rtb.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/include/mach/msm_serial_hs.h b/arch/arm/mach-msm/include/mach/msm_serial_hs.h
index d2905d4..dd53911 100644
--- a/arch/arm/mach-msm/include/mach/msm_serial_hs.h
+++ b/arch/arm/mach-msm/include/mach/msm_serial_hs.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2008 Google, Inc.
+ * Copyright (C) 2010-2013, The Linux Foundation. All rights reserved.
  * Author: Nick Pelly <npelly@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -17,15 +18,34 @@
 
 #include<linux/serial_core.h>
 
-/* Optional platform device data for msm_serial_hs driver.
- * Used to configure low power wakeup */
+/**
+ * struct msm_serial_hs_platform_data - platform device data
+ *					for msm hsuart device
+ * @wakeup_irq : IRQ line to be configured as Wakeup source.
+ * @inject_rx_on_wakeup : Set 1 if specific character to be inserted on wakeup
+ * @rx_to_inject : Character to be inserted on wakeup
+ * @gpio_config : Configure gpios that are used for uart communication
+ * @userid : User-defined number to be used to enumerate device as tty<userid>
+ * @uart_tx_gpio: GPIO number for UART Tx Line.
+ * @uart_rx_gpio: GPIO number for UART Rx Line.
+ * @uart_cts_gpio: GPIO number for UART CTS Line.
+ * @uart_rfr_gpio: GPIO number for UART RFR Line.
+ * @bam_tx_ep_pipe_index : BAM TX Endpoint Pipe Index for HSUART
+ * @bam_tx_ep_pipe_index : BAM RX Endpoint Pipe Index for HSUART
+ */
 struct msm_serial_hs_platform_data {
 	int wakeup_irq;  /* wakeup irq */
-	/* bool: inject char into rx tty on wakeup */
 	unsigned char inject_rx_on_wakeup;
 	char rx_to_inject;
 	int (*gpio_config)(int);
 	int userid;
+
+	int uart_tx_gpio;
+	int uart_rx_gpio;
+	int uart_cts_gpio;
+	int uart_rfr_gpio;
+	unsigned bam_tx_ep_pipe_index;
+	unsigned bam_rx_ep_pipe_index;
 };
 
 unsigned int msm_hs_tx_empty(struct uart_port *uport);
diff --git a/arch/arm/mach-msm/include/mach/msm_serial_hs_lite.h b/arch/arm/mach-msm/include/mach/msm_serial_hs_lite.h
index 577a097..7a24190 100644
--- a/arch/arm/mach-msm/include/mach/msm_serial_hs_lite.h
+++ b/arch/arm/mach-msm/include/mach/msm_serial_hs_lite.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013 The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -13,11 +13,30 @@
 
 #ifndef __ASM_ARCH_MSM_SERIAL_HS_LITE_H
 #define __ASM_ARCH_MSM_SERIAL_HS_LITE_H
-
+/**
+ * struct msm_serial_hslite_platform_data - platform device data
+ *              for msm_hs_lite.
+ * @config_gpio: Select GPIOs to configure.
+ *		Set 4 if 4-wire UART used (for Tx, Rx, CTS, RFR GPIOs).
+ *		Set 1 if 2-wire UART used (for Tx, Rx GPIOs).
+ * @uart_tx_gpio: GPIO number for UART Tx Line.
+ * @uart_rx_gpio: GPIO number for UART Rx Line.
+ * @uart_cts_gpio: GPIO number for UART CTS Line.
+ * @uart_rfr_gpio: GPIO number for UART RFR Line.
+ * @set_uart_clk_zero: use this if setting UART Clock to zero is required
+ * It is mainly required where same UART is used across different processor.
+ * Make sure that Clock driver for platform support setting clock rate to zero.
+ * @use_pm: use this to enable power management
+ * @line: Used to set UART Port number.
+ */
 struct msm_serial_hslite_platform_data {
 	unsigned config_gpio;
 	unsigned uart_tx_gpio;
 	unsigned uart_rx_gpio;
+	unsigned uart_cts_gpio;
+	unsigned uart_rfr_gpio;
+	bool set_uart_clk_zero;
+	bool use_pm;
 	int line;
 };
 
diff --git a/arch/arm/mach-msm/include/mach/msm_serial_hsl_regs.h b/arch/arm/mach-msm/include/mach/msm_serial_hsl_regs.h
index b465b56..774c91d 100644
--- a/arch/arm/mach-msm/include/mach/msm_serial_hsl_regs.h
+++ b/arch/arm/mach-msm/include/mach/msm_serial_hsl_regs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/msm_serial_pdata.h b/arch/arm/mach-msm/include/mach/msm_serial_pdata.h
index 40bdc9d..7c1319e 100644
--- a/arch/arm/mach-msm/include/mach/msm_serial_pdata.h
+++ b/arch/arm/mach-msm/include/mach/msm_serial_pdata.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/msm_smd.h b/arch/arm/mach-msm/include/mach/msm_smd.h
index 0c452f8..2748636 100644
--- a/arch/arm/mach-msm/include/mach/msm_smd.h
+++ b/arch/arm/mach-msm/include/mach/msm_smd.h
@@ -1,7 +1,7 @@
 /* linux/include/asm-arm/arch-msm/msm_smd.h
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/msm_smsm.h b/arch/arm/mach-msm/include/mach/msm_smsm.h
index c77c181..d983ce5 100644
--- a/arch/arm/mach-msm/include/mach/msm_smsm.h
+++ b/arch/arm/mach-msm/include/mach/msm_smsm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -198,7 +198,15 @@
 	SMEM_SSR_REASON_LPASS0,
 	SMEM_SSR_REASON_DSPS0,
 	SMEM_SSR_REASON_VCODEC0,
-	SMEM_MEM_LAST = SMEM_SSR_REASON_VCODEC0,
+	SMEM_SMP2P_APPS_BASE = 427,
+	SMEM_SMP2P_MODEM_BASE = SMEM_SMP2P_APPS_BASE + 8,    /* 435 */
+	SMEM_SMP2P_AUDIO_BASE = SMEM_SMP2P_MODEM_BASE + 8,   /* 443 */
+	SMEM_SMP2P_WIRLESS_BASE = SMEM_SMP2P_AUDIO_BASE + 8, /* 451 */
+	SMEM_SMP2P_POWER_BASE = SMEM_SMP2P_WIRLESS_BASE + 8, /* 459 */
+	SMEM_FLASH_DEVICE_INFO = SMEM_SMP2P_POWER_BASE + 8,  /* 467 */
+	SMEM_BAM_PIPE_MEMORY,     /* 468 */
+	SMEM_IMAGE_VERSION_TABLE, /* 469 */
+	SMEM_LC_DEBUGGER, /* 470 */
 	SMEM_NUM_ITEMS,
 };
 
diff --git a/arch/arm/mach-msm/include/mach/msm_sps.h b/arch/arm/mach-msm/include/mach/msm_sps.h
index 3af6f71..da12ced 100644
--- a/arch/arm/mach-msm/include/mach/msm_sps.h
+++ b/arch/arm/mach-msm/include/mach/msm_sps.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/msm_subsystem_map.h b/arch/arm/mach-msm/include/mach/msm_subsystem_map.h
index ebb2327..3119023 100644
--- a/arch/arm/mach-msm/include/mach/msm_subsystem_map.h
+++ b/arch/arm/mach-msm/include/mach/msm_subsystem_map.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/arm/mach-msm/include/mach/msm_touch.h b/arch/arm/mach-msm/include/mach/msm_touch.h
index 763d6a8..cd895d4 100644
--- a/arch/arm/mach-msm/include/mach/msm_touch.h
+++ b/arch/arm/mach-msm/include/mach/msm_touch.h
@@ -2,7 +2,7 @@
  *
  * Platform data for MSM touchscreen driver.
  *
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/msm_touchpad.h b/arch/arm/mach-msm/include/mach/msm_touchpad.h
index 4b2d537..2cc6e05 100644
--- a/arch/arm/mach-msm/include/mach/msm_touchpad.h
+++ b/arch/arm/mach-msm/include/mach/msm_touchpad.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/arch/arm/mach-msm/include/mach/msm_tsif.h b/arch/arm/mach-msm/include/mach/msm_tsif.h
index 62595e3..d260ec1 100644
--- a/arch/arm/mach-msm/include/mach/msm_tsif.h
+++ b/arch/arm/mach-msm/include/mach/msm_tsif.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/include/mach/msm_tspp.h b/arch/arm/mach-msm/include/mach/msm_tspp.h
index a024a99..696d4ef 100644
--- a/arch/arm/mach-msm/include/mach/msm_tspp.h
+++ b/arch/arm/mach-msm/include/mach/msm_tspp.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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
@@ -42,6 +42,8 @@
 int tspp_close_stream(u32 dev, u32 channel_id);
 int tspp_open_channel(u32 dev, u32 channel_id);
 int tspp_close_channel(u32 dev, u32 channel_id);
+int tspp_get_ref_clk_counter(u32 dev,
+	enum tspp_source source, u32 *tcr_counter);
 int tspp_add_filter(u32 dev, u32 channel_id, struct tspp_filter *filter);
 int tspp_remove_filter(u32 dev, u32 channel_id,	struct tspp_filter *filter);
 int tspp_set_key(u32 dev, u32 channel_id, struct tspp_key *key);
diff --git a/arch/arm/mach-msm/include/mach/msm_xo.h b/arch/arm/mach-msm/include/mach/msm_xo.h
index f9795b4..f9ccfee 100644
--- a/arch/arm/mach-msm/include/mach/msm_xo.h
+++ b/arch/arm/mach-msm/include/mach/msm_xo.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/ocmem.h b/arch/arm/mach-msm/include/mach/ocmem.h
index 5355215..92ae6b6 100644
--- a/arch/arm/mach-msm/include/mach/ocmem.h
+++ b/arch/arm/mach-msm/include/mach/ocmem.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -136,6 +136,9 @@
 int ocmem_unmap(int client_id, struct ocmem_buf *buffer,
 			struct ocmem_map_list *list);
 
+int ocmem_drop(int client_id, struct ocmem_buf *buffer,
+			struct ocmem_map_list *list);
+
 int ocmem_dump(int client_id, struct ocmem_buf *buffer,
 				unsigned long dst_phys_addr);
 
diff --git a/arch/arm/mach-msm/include/mach/ocmem_priv.h b/arch/arm/mach-msm/include/mach/ocmem_priv.h
index 380fde1..abb5653 100644
--- a/arch/arm/mach-msm/include/mach/ocmem_priv.h
+++ b/arch/arm/mach-msm/include/mach/ocmem_priv.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -29,6 +29,16 @@
 #define TO_OCMEM 0x0
 #define TO_DDR 0x1
 
+#define OCMEM_SVC_ID 15
+#define OCMEM_LOCK_CMD_ID 0x1
+#define OCMEM_UNLOCK_CMD_ID 0x2
+#define OCMEM_ENABLE_DUMP_CMD_ID 0x3
+#define OCMEM_DISABLE_DUMP_CMD_ID 0x4
+
+#define OCMEM_SECURE_SVC_ID 12
+#define OCMEM_SECURE_CFG_ID 0x2
+#define OCMEM_SECURE_DEV_ID 0x5
+
 struct ocmem_zone;
 
 struct ocmem_zone_ops {
@@ -158,6 +168,8 @@
 	/* Request Power State */
 	unsigned power_state;
 	struct ocmem_eviction_data *edata;
+	/* Request that triggered eviction */
+	struct ocmem_req *e_handle;
 };
 
 struct ocmem_handle {
@@ -187,6 +199,10 @@
 int ocmem_notifier_init(void);
 int check_notifier(int);
 const char *get_name(int);
+int get_tz_id(int);
+int ocmem_enable_sec_program(int);
+int ocmem_enable_dump(enum ocmem_client, unsigned long, unsigned long);
+int ocmem_disable_dump(enum ocmem_client, unsigned long, unsigned long);
 int check_id(int);
 int dispatch_notification(int, enum ocmem_notif_type, struct ocmem_buf *);
 
@@ -197,6 +213,7 @@
 			unsigned long, bool, bool);
 int process_free(int, struct ocmem_handle *);
 int process_xfer(int, struct ocmem_handle *, struct ocmem_map_list *, int);
+int process_drop(int, struct ocmem_handle *, struct ocmem_map_list *);
 int process_evict(int);
 int process_restore(int);
 int process_shrink(int, struct ocmem_handle *, unsigned long);
diff --git a/arch/arm/mach-msm/include/mach/oem_rapi_client.h b/arch/arm/mach-msm/include/mach/oem_rapi_client.h
index d7a2416..374124f 100644
--- a/arch/arm/mach-msm/include/mach/oem_rapi_client.h
+++ b/arch/arm/mach-msm/include/mach/oem_rapi_client.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/include/mach/pmic.h b/arch/arm/mach-msm/include/mach/pmic.h
index b143a59..03b523b 100644
--- a/arch/arm/mach-msm/include/mach/pmic.h
+++ b/arch/arm/mach-msm/include/mach/pmic.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/include/mach/proc_comm.h b/arch/arm/mach-msm/include/mach/proc_comm.h
index 8a0a218..655692a 100644
--- a/arch/arm/mach-msm/include/mach/proc_comm.h
+++ b/arch/arm/mach-msm/include/mach/proc_comm.h
@@ -1,6 +1,6 @@
 /* arch/arm/mach-msm/include/mach/proc_comm.h
  *
- * Copyright (c) 2007-2009,2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2009,2011 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/acdb_commands.h b/arch/arm/mach-msm/include/mach/qdsp5/acdb_commands.h
index 188af9f..b24a3d9 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/acdb_commands.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/acdb_commands.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/audio_acdb_def.h b/arch/arm/mach-msm/include/mach/qdsp5/audio_acdb_def.h
index e1fc0cd..5fc87e0 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/audio_acdb_def.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/audio_acdb_def.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -48,4 +48,5 @@
 /* ID used for virtual devices */
 #define PSEUDO_ACDB_ID					0xFFFF
 
+int is_acdb_enabled(void);
 #endif /* _MACH_QDSP5_V2_AUDIO_ACDB_DEF_H */
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/audio_acdbi.h b/arch/arm/mach-msm/include/mach/qdsp5/audio_acdbi.h
index 5bad4fa..682e4d9 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/audio_acdbi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/audio_acdbi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012 The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audplaycmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audplaycmdi.h
index 575a286..67ee549 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audplaycmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audplaycmdi.h
@@ -17,7 +17,7 @@
     Send buffer to AUDPLAY task
 	
   
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audplaymsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audplaymsg.h
index 0bf2468..e79554a 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audplaymsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audplaymsg.h
@@ -12,7 +12,7 @@
   None
 
   
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpp.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpp.h
index bbd82a0..5fa36d6 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpp.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpp.h
@@ -1,7 +1,7 @@
 /*arch/arm/mach-msm/qdsp5audpp.h
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppcmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppcmdi.h
index de30c65..93b77f4 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppcmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppcmdi.h
@@ -15,7 +15,7 @@
 EXTERNALIZED FUNCTIONS
   None
 
-Copyright(c) 1992-2009, 2012 Code Aurora Forum. All rights reserved.
+Copyright(c) 1992-2009, 2012-2013 The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
@@ -1071,6 +1071,9 @@
 } __packed;
 #define AUDPP_CMD_SAMPLING_FREQUENCY	7
 #define AUDPP_CMD_QRUMBLE		9
+#define AUDPP_CMD_SRS			18
+#define AUDPP_DISABLE_FEATS_LSW		2
+#define AUDPP_DISABLE_FEATS_MSW		3
 
 #endif /* QDSP5AUDPPCMDI_H */
 
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppmsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppmsg.h
index fef4c35..664e246 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppmsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppmsg.h
@@ -2,29 +2,29 @@
 #define QDSP5AUDPPMSG_H
 
 /*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
-*
-*       Q D S P 5  A U D I O   P O S T   P R O C E S S I N G   M S G
-*
-* GENERAL DESCRIPTION
-*   Messages sent by AUDPPTASK to ARM
-*
-* REFERENCES
-*   None
-*
-* EXTERNALIZED FUNCTIONS
-*   None
-*
-* Copyright (c) 1992-2009, 2012 Code Aurora Forum. All rights reserved.
-*
-* This software is licensed under the terms of the GNU General Public
-* License version 2, as published by the Free Software Foundation, and
-* may be copied, distributed, and modified under those terms.
-*
-* 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.
-*
+
+       Q D S P 5  A U D I O   P O S T   P R O C E S S I N G   M S G
+
+ GENERAL DESCRIPTION
+   Messages sent by AUDPPTASK to ARM
+
+ REFERENCES
+   None
+
+ EXTERNALIZED FUNCTIONS
+   None
+
+ Copyright (c) 1992-2009, 2012-2013 The Linux Foundation. All rights reserved.
+
+ This software is licensed under the terms of the GNU General Public
+ License version 2, as published by the Free Software Foundation, and
+ may be copied, distributed, and modified under those terms.
+
+ 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.
+
 *====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
 /*===========================================================================
 
@@ -319,4 +319,18 @@
 #define ADSP_MESSAGE_ID 0xFFFF
 
 #define AUDPP_MSG_FEAT_QUERY_DM_DONE 0x000b
+
+/*
+ * ADSP sends this message when a PP feature is disabled
+ * due to ADSP resource limitation.
+ */
+#define AUDPP_MSG_PP_DISABLE_FEEDBACK 0x000C
+
+/*
+ * This message is sent by ADSP if any PP features is disabled
+ * due to video and audio concurrency due to MIPS limitation and
+ * the video session is ended in ADSP.
+ */
+#define AUDPP_MSG_PP_FEATS_RE_ENABLE 0x000D
+
 #endif /* QDSP5AUDPPMSG_H */
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproc.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproc.h
index 5c7c5dc..7153c2d 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproc.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproccmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproccmdi.h
index a38d224..0fc1e46 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproccmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproccmdi.h
@@ -15,7 +15,7 @@
 * EXTERNALIZED FUNCTIONS
 *   None
 *
-* Copyright (c) 1992-2009, 2012 Code Aurora Forum. All rights reserved.
+* Copyright (c) 1992-2009, 2012 The Linux Foundation. All rights reserved.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreprocmsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreprocmsg.h
index d299995..6a93279 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreprocmsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreprocmsg.h
@@ -15,7 +15,7 @@
 * EXTERNALIZED FUNCTIONS
 *   None
 *
-* Copyright (c) 1992-2009, 2012 Code Aurora Forum. All rights reserved.
+* Copyright (c) 1992-2009, 2012 The Linux Foundation. All rights reserved.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audreccmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audreccmdi.h
index 5045de0..72f12c9 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audreccmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audreccmdi.h
@@ -15,7 +15,7 @@
  * EXTERNALIZED FUNCTIONS
  *  None
  *
- * Copyright (c) 1992-2009, 2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 1992-2009, 2011 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audrecmsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audrecmsg.h
index 339e4f7..22bdaa2 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audrecmsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audrecmsg.h
@@ -15,7 +15,7 @@
  * EXTERNALIZED FUNCTIONS
  *  None
  *
- * Copyright (c) 1992-2009, 2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 1992-2009, 2011 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5jpegcmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5jpegcmdi.h
index 7f25f47..40e96d7 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5jpegcmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5jpegcmdi.h
@@ -15,7 +15,7 @@
 EXTERNALIZED FUNCTIONS
   None
 
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5jpegmsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5jpegmsg.h
index 993af42..9b5ce77 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5jpegmsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5jpegmsg.h
@@ -15,7 +15,7 @@
 EXTERNALIZED FUNCTIONS
   None
 
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5lpmcmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5lpmcmdi.h
index 4ab6cbf4..3d4fe56 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5lpmcmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5lpmcmdi.h
@@ -15,7 +15,7 @@
 EXTERNALIZED FUNCTIONS
   None
 
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5lpmmsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5lpmmsg.h
index 68f8874..81f766d 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5lpmmsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5lpmmsg.h
@@ -15,7 +15,7 @@
 EXTERNALIZED FUNCTIONS
   None
 
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5rmtcmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5rmtcmdi.h
index 7a66b68..9b9521f 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5rmtcmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5rmtcmdi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5rmtmsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5rmtmsg.h
index a890e76..4e7ed33 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5rmtmsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5rmtmsg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vdeccmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vdeccmdi.h
index 1064b17..89af4aa 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vdeccmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vdeccmdi.h
@@ -15,7 +15,7 @@
 EXTERNALIZED FUNCTIONS
   None
 
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vdecmsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vdecmsg.h
index 2d3ab89..ccd129d 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vdecmsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vdecmsg.h
@@ -15,7 +15,7 @@
 EXTERNALIZED FUNCTIONS
   None
 
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5venccmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5venccmdi.h
index b3c018f..34e00a6 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5venccmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5venccmdi.h
@@ -15,7 +15,7 @@
 EXTERNALIZED FUNCTIONS
   None
 
-Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
 *====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
 /*===========================================================================
 
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vfecmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vfecmdi.h
index 4c5d752..18ea21c 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vfecmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vfecmdi.h
@@ -15,7 +15,7 @@
 EXTERNALIZED FUNCTIONS
   None
 
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vfemsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vfemsg.h
index a628f92..7d7f731 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vfemsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vfemsg.h
@@ -15,7 +15,7 @@
 EXTERNALIZED FUNCTIONS
   None
 
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/snd_adie.h b/arch/arm/mach-msm/include/mach/qdsp5/snd_adie.h
index bf1714e..2bad3b0 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/snd_adie.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/snd_adie.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/acdb_commands.h b/arch/arm/mach-msm/include/mach/qdsp5v2/acdb_commands.h
index 2e6fcdb..9386307 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/acdb_commands.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/acdb_commands.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/adie_marimba.h b/arch/arm/mach-msm/include/mach/qdsp5v2/adie_marimba.h
index 919da65..1851322 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/adie_marimba.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/adie_marimba.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/afe.h b/arch/arm/mach-msm/include/mach/qdsp5v2/afe.h
index c15facc..e4e2933 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/afe.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/afe.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_acdb_def.h b/arch/arm/mach-msm/include/mach/qdsp5v2/audio_acdb_def.h
index a2a15dc..0a0c308 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_acdb_def.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/audio_acdb_def.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010 - 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_acdbi.h b/arch/arm/mach-msm/include/mach/qdsp5v2/audio_acdbi.h
index 559073c..f05ebaa 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_acdbi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/audio_acdbi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_def.h b/arch/arm/mach-msm/include/mach/qdsp5v2/audio_def.h
index 236c6f6..35a4d5c 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_def.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/audio_def.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009,2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009,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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_dev_ctl.h b/arch/arm/mach-msm/include/mach/qdsp5v2/audio_dev_ctl.h
index 7c0abcc..976d9ae 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_dev_ctl.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/audio_dev_ctl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_interct.h b/arch/arm/mach-msm/include/mach/qdsp5v2/audio_interct.h
index 2a7b89e..2690bf5 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_interct.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/audio_interct.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/audpp.h b/arch/arm/mach-msm/include/mach/qdsp5v2/audpp.h
index bdec256..763a651 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/audpp.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/audpp.h
@@ -1,7 +1,7 @@
 /*arch/arm/mach-msm/qdsp5iv2/audpp.h
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2011, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/audpreproc.h b/arch/arm/mach-msm/include/mach/qdsp5v2/audpreproc.h
index 6abeae1..16a0a8f 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/audpreproc.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/audpreproc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/aux_pcm.h b/arch/arm/mach-msm/include/mach/qdsp5v2/aux_pcm.h
index 100ddea..d9b9427 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/aux_pcm.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/aux_pcm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/lpa.h b/arch/arm/mach-msm/include/mach/qdsp5v2/lpa.h
index d71cf72..d9d9ab1 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/lpa.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/lpa.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/lpa_hw.h b/arch/arm/mach-msm/include/mach/qdsp5v2/lpa_hw.h
index bfff384..beb4aee 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/lpa_hw.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/lpa_hw.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/marimba_profile.h b/arch/arm/mach-msm/include/mach/qdsp5v2/marimba_profile.h
index c1cb3fe..7e455a1 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/marimba_profile.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/marimba_profile.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011,  Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/mi2s.h b/arch/arm/mach-msm/include/mach/qdsp5v2/mi2s.h
index e304e25..2106bfc 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/mi2s.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/mi2s.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/mp3_funcs.h b/arch/arm/mach-msm/include/mach/qdsp5v2/mp3_funcs.h
index ac06d3b..b3f7c54 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/mp3_funcs.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/mp3_funcs.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/msm_lpa.h b/arch/arm/mach-msm/include/mach/qdsp5v2/msm_lpa.h
index 0dced94..cdfa19b 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/msm_lpa.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/msm_lpa.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/pcm_funcs.h b/arch/arm/mach-msm/include/mach/qdsp5v2/pcm_funcs.h
index fa65000..b8fe2ba 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/pcm_funcs.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/pcm_funcs.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5afecmdi.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5afecmdi.h
index 25fe3a0..b4ff5b8 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5afecmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5afecmdi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5afemsg.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5afemsg.h
index 16134e3..292683a 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5afemsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5afemsg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audplaycmdi.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audplaycmdi.h
index 53128d3..dad7fab 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audplaycmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audplaycmdi.h
@@ -16,7 +16,7 @@
   Send buffer to AUDPLAY task
 
 
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audplaymsg.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audplaymsg.h
index 2eeb557..653f0e7 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audplaymsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audplaymsg.h
@@ -11,7 +11,7 @@
   None
 
 
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audppcmdi.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audppcmdi.h
index 0416f52..bdcf5d8 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audppcmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audppcmdi.h
@@ -15,7 +15,7 @@
 EXTERNALIZED FUNCTIONS
   None
 
-Copyright(c) 1992-2011, Code Aurora Forum. All rights reserved.
+Copyright(c) 1992-2011, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audppmsg.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audppmsg.h
index b27bd83..300232d 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audppmsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audppmsg.h
@@ -14,7 +14,7 @@
 EXTERNALIZED FUNCTIONS
   None
 
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audpreproccmdi.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audpreproccmdi.h
index f579e1a..3d5cf84 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audpreproccmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audpreproccmdi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audpreprocmsg.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audpreprocmsg.h
index 29da664..d3efbcd 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audpreprocmsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audpreprocmsg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audreccmdi.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audreccmdi.h
index 9ba8645..49642df 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audreccmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audreccmdi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audrecmsg.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audrecmsg.h
index 32ccbbc..eb46235 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audrecmsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audrecmsg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_ecodec.h b/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_ecodec.h
index 35c1edb..8e7d96c 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_ecodec.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_ecodec.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_icodec.h b/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_icodec.h
index 7f9938e..7a811a0 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_icodec.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_icodec.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_mi2s.h b/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_mi2s.h
index cd834a5..a8f5234 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_mi2s.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_mi2s.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_virtual.h b/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_virtual.h
index 695b19d..639e981 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_virtual.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_virtual.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/voice.h b/arch/arm/mach-msm/include/mach/qdsp5v2/voice.h
index 5ca2d6d..93f9bad 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/voice.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/voice.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/apr.h b/arch/arm/mach-msm/include/mach/qdsp6v2/apr.h
index 4c06af4..59908e6 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/apr.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/apr.h
@@ -82,7 +82,8 @@
 #define APR_SVC_ADSP_CVS	0x0A
 #define APR_SVC_ADSP_CVP	0x0B
 #define APR_SVC_USM		0x0C
-#define APR_SVC_MAX		0x0D
+#define APR_SVC_VIDC		0x16
+#define APR_SVC_MAX		0x17
 
 /* Modem Service IDs */
 #define APR_SVC_MVS		0x3
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/apr_tal.h b/arch/arm/mach-msm/include/mach/qdsp6v2/apr_tal.h
index 163ba7b..dd64424 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/apr_tal.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/apr_tal.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us.h b/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us.h
index 22f343c..2cfb5ac 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us_b.h b/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us_b.h
new file mode 100644
index 0000000..11de6ef
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us_b.h
@@ -0,0 +1,70 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef __APR_US_B_H__
+#define __APR_US_B_H__
+
+#include "apr_us.h"
+
+/* ======================================================================= */
+/*  Session Level commands */
+#define USM_CMD_SHARED_MEM_MAP_REGION		0x00012728
+struct usm_cmd_memory_map_region {
+	struct apr_hdr hdr;
+	u16            mempool_id;
+	u16            num_regions;
+	u32            flags;
+	u32            shm_addr_lsw;
+	u32            shm_addr_msw;
+	u32            mem_size_bytes;
+} __packed;
+
+#define USM_CMDRSP_SHARED_MEM_MAP_REGION	0x00012729
+struct usm_cmdrsp_memory_map_region {
+	u32            mem_map_handle;
+} __packed;
+
+#define USM_CMD_SHARED_MEM_UNMAP_REGION         0x0001272A
+struct usm_cmd_memory_unmap_region {
+	struct apr_hdr hdr;
+	u32            mem_map_handle;
+} __packed;
+
+#define USM_DATA_CMD_READ			0x00012724
+struct usm_stream_cmd_read {
+	struct apr_hdr hdr;
+	u32            buf_addr_lsw;
+	u32            buf_addr_msw;
+	u32            mem_map_handle;
+	u32            buf_size;
+	u32            seq_id;
+	u32            counter;
+} __packed;
+
+#define USM_DATA_EVENT_READ_DONE		0x00012725
+
+#define USM_DATA_CMD_WRITE			0x00012726
+struct usm_stream_cmd_write {
+	struct apr_hdr hdr;
+	u32            buf_addr_lsw;
+	u32            buf_addr_msw;
+	u32            mem_map_handle;
+	u32            buf_size;
+	u32            seq_id;
+	u32            res0;
+	u32            res1;
+	u32            res2;
+} __packed;
+
+#define USM_DATA_EVENT_WRITE_DONE		0x00012727
+
+#endif /* __APR_US_B_H__ */
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h b/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h
index 88cb94a..31dd582 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -14,11 +14,8 @@
 #define _AUDIO_ACDB_H
 
 #include <linux/msm_audio_acdb.h>
-#if defined CONFIG_ARCH_MSM8974 || defined CONFIG_ARCH_MSM9625
-#include <sound/q6adm-v2.h>
-#else
 #include <sound/q6adm.h>
-#endif
+
 enum {
 	RX_CAL,
 	TX_CAL,
@@ -60,14 +57,11 @@
 void get_all_vocproc_cal(struct acdb_cal_block *cal_block);
 void get_all_vocstrm_cal(struct acdb_cal_block *cal_block);
 void get_all_vocvol_cal(struct acdb_cal_block *cal_block);
-void get_voice_col_data(uint32_t vocproc_type,
-	struct acdb_cal_block *cal_block);
 void get_anc_cal(struct acdb_cal_block *cal_block);
 void get_afe_cal(int32_t path, struct acdb_cal_block *cal_block);
 void get_audproc_cal(int32_t path, struct acdb_cal_block *cal_block);
 void get_audstrm_cal(int32_t path, struct acdb_cal_block *cal_block);
 void get_audvol_cal(int32_t path, struct acdb_cal_block *cal_block);
-void get_vocproc_dev_cfg_cal(struct acdb_cal_block *cal_block);
 void get_vocproc_cal(struct acdb_cal_data *cal_data);
 void get_vocstrm_cal(struct acdb_cal_data *cal_data);
 void get_vocvol_cal(struct acdb_cal_data *cal_data);
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/audio_dev_ctl.h b/arch/arm/mach-msm/include/mach/qdsp6v2/audio_dev_ctl.h
index 20c6fc4..6b2d7cc 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/audio_dev_ctl.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/audio_dev_ctl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/dsp_debug.h b/arch/arm/mach-msm/include/mach/qdsp6v2/dsp_debug.h
index 94f4ab4..bc1cd9e 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/dsp_debug.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/dsp_debug.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/q6voice.h b/arch/arm/mach-msm/include/mach/qdsp6v2/q6voice.h
index 674cfe8..7165998 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/q6voice.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/q6voice.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/rtac.h b/arch/arm/mach-msm/include/mach/qdsp6v2/rtac.h
index f5bea31..07be428 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/rtac.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/rtac.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/usf.h b/arch/arm/mach-msm/include/mach/qdsp6v2/usf.h
index f747a80..ff39929 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/usf.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/usf.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/include/mach/qpnp-int.h b/arch/arm/mach-msm/include/mach/qpnp-int.h
index 21d95e6..2b86216 100644
--- a/arch/arm/mach-msm/include/mach/qpnp-int.h
+++ b/arch/arm/mach-msm/include/mach/qpnp-int.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -57,6 +57,14 @@
 				struct qpnp_local_int *li_cb);
 
 /**
+ * qpnpint_unregister_controller() - Unregister local interrupt callbacks
+ *
+ * Used by the PMIC Arbiter driver or equivalent to unregister
+ * callbacks for interrupt events.
+ */
+int qpnpint_unregister_controller(struct device_node *node);
+
+/**
  * qpnpint_handle_irq - Main interrupt handling routine
  *
  * Pass a PMIC Arbiter interrupt to Linux.
@@ -78,6 +86,12 @@
 	return -ENXIO;
 }
 
+static inline int qpnpint_unregister_controller(struct device_node *node)
+
+{
+	return -ENXIO;
+}
+
 static inline int qpnpint_handle_irq(struct spmi_controller *spmi_ctrl,
 		       struct qpnp_irq_spec *spec)
 {
diff --git a/arch/arm/mach-msm/include/mach/qseecomi.h b/arch/arm/mach-msm/include/mach/qseecomi.h
new file mode 100644
index 0000000..3a13af8
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/qseecomi.h
@@ -0,0 +1,130 @@
+/*
+ * 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 __QSEECOMI_H_
+#define __QSEECOMI_H_
+
+#include <linux/qseecom.h>
+
+enum qseecom_command_scm_resp_type {
+	QSEOS_APP_ID = 0xEE01,
+	QSEOS_LISTENER_ID
+};
+
+enum qseecom_qceos_cmd_id {
+	QSEOS_APP_START_COMMAND      = 0x01,
+	QSEOS_APP_SHUTDOWN_COMMAND,
+	QSEOS_APP_LOOKUP_COMMAND,
+	QSEOS_REGISTER_LISTENER,
+	QSEOS_DEREGISTER_LISTENER,
+	QSEOS_CLIENT_SEND_DATA_COMMAND,
+	QSEOS_LISTENER_DATA_RSP_COMMAND,
+	QSEOS_LOAD_EXTERNAL_ELF_COMMAND,
+	QSEOS_UNLOAD_EXTERNAL_ELF_COMMAND,
+	QSEOS_GET_APP_STATE_COMMAND,
+	QSEOS_LOAD_SERV_IMAGE_COMMAND,
+	QSEOS_UNLOAD_SERV_IMAGE_COMMAND,
+	QSEOS_APP_REGION_NOTIFICATION,
+	QSEOS_REGISTER_LOG_BUF_COMMAND,
+	QSEOS_CMD_MAX     = 0xEFFFFFFF
+};
+
+enum qseecom_qceos_cmd_status {
+	QSEOS_RESULT_SUCCESS = 0,
+	QSEOS_RESULT_INCOMPLETE,
+	QSEOS_RESULT_FAILURE  = 0xFFFFFFFF
+};
+
+__packed  struct qsee_apps_region_info_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t addr;
+	uint32_t size;
+};
+
+__packed struct qseecom_check_app_ireq {
+	uint32_t qsee_cmd_id;
+	char     app_name[MAX_APP_NAME_SIZE];
+};
+
+__packed struct qseecom_load_app_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t mdt_len;		/* Length of the mdt file */
+	uint32_t img_len;		/* Length of .bxx and .mdt files */
+	uint32_t phy_addr;		/* phy addr of the start of image */
+	char     app_name[MAX_APP_NAME_SIZE];	/* application name*/
+};
+
+__packed struct qseecom_unload_app_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t  app_id;
+};
+
+__packed struct qseecom_load_lib_image_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t mdt_len;
+	uint32_t img_len;
+	uint32_t phy_addr;
+};
+
+__packed struct qseecom_unload_lib_image_ireq {
+	uint32_t qsee_cmd_id;
+};
+
+__packed struct qseecom_register_listener_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t listener_id;
+	void *sb_ptr;
+	uint32_t sb_len;
+};
+
+__packed struct qseecom_unregister_listener_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t  listener_id;
+};
+
+__packed struct qseecom_client_send_data_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t app_id;
+	void *req_ptr;
+	uint32_t req_len;
+	void *rsp_ptr;   /* First 4 bytes should always be the return status */
+	uint32_t rsp_len;
+};
+
+__packed struct qseecom_reg_log_buf_ireq {
+	uint32_t qsee_cmd_id;
+	unsigned long phy_addr;
+	uint32_t len;
+};
+
+/* send_data resp */
+__packed struct qseecom_client_listener_data_irsp {
+	uint32_t qsee_cmd_id;
+	uint32_t listener_id;
+	uint32_t status;
+};
+
+/*
+ * struct qseecom_command_scm_resp - qseecom response buffer
+ * @cmd_status: value from enum tz_sched_cmd_status
+ * @sb_in_rsp_addr: points to physical location of response
+ *                buffer
+ * @sb_in_rsp_len: length of command response
+ */
+__packed struct qseecom_command_scm_resp {
+	uint32_t result;
+	enum qseecom_command_scm_resp_type resp_type;
+	unsigned int data;
+};
+
+#endif /* __QSEECOMI_H_ */
diff --git a/arch/arm/mach-msm/include/mach/remote_spinlock.h b/arch/arm/mach-msm/include/mach/remote_spinlock.h
index 75b70f3..8c8b821 100644
--- a/arch/arm/mach-msm/include/mach/remote_spinlock.h
+++ b/arch/arm/mach-msm/include/mach/remote_spinlock.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2011 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
@@ -39,192 +39,15 @@
 typedef raw_remote_spinlock_t *_remote_spinlock_t;
 
 #define remote_spinlock_id_t const char *
-#define SMEM_SPINLOCK_PID_APPS 1
-
-static inline void __raw_remote_ex_spin_lock(raw_remote_spinlock_t *lock)
-{
-	unsigned long tmp;
-
-	__asm__ __volatile__(
-"1:	ldrex	%0, [%1]\n"
-"	teq	%0, #0\n"
-"	strexeq	%0, %2, [%1]\n"
-"	teqeq	%0, #0\n"
-"	bne	1b"
-	: "=&r" (tmp)
-	: "r" (&lock->lock), "r" (1)
-	: "cc");
-
-	smp_mb();
-}
-
-static inline int __raw_remote_ex_spin_trylock(raw_remote_spinlock_t *lock)
-{
-	unsigned long tmp;
-
-	__asm__ __volatile__(
-"	ldrex	%0, [%1]\n"
-"	teq	%0, #0\n"
-"	strexeq	%0, %2, [%1]\n"
-	: "=&r" (tmp)
-	: "r" (&lock->lock), "r" (1)
-	: "cc");
-
-	if (tmp == 0) {
-		smp_mb();
-		return 1;
-	}
-	return 0;
-}
-
-static inline void __raw_remote_ex_spin_unlock(raw_remote_spinlock_t *lock)
-{
-	smp_mb();
-
-	__asm__ __volatile__(
-"	str	%1, [%0]\n"
-	:
-	: "r" (&lock->lock), "r" (0)
-	: "cc");
-}
-
-static inline void __raw_remote_swp_spin_lock(raw_remote_spinlock_t *lock)
-{
-	unsigned long tmp;
-
-	__asm__ __volatile__(
-"1:	swp	%0, %2, [%1]\n"
-"	teq	%0, #0\n"
-"	bne	1b"
-	: "=&r" (tmp)
-	: "r" (&lock->lock), "r" (1)
-	: "cc");
-
-	smp_mb();
-}
-
-static inline int __raw_remote_swp_spin_trylock(raw_remote_spinlock_t *lock)
-{
-	unsigned long tmp;
-
-	__asm__ __volatile__(
-"	swp	%0, %2, [%1]\n"
-	: "=&r" (tmp)
-	: "r" (&lock->lock), "r" (1)
-	: "cc");
-
-	if (tmp == 0) {
-		smp_mb();
-		return 1;
-	}
-	return 0;
-}
-
-static inline void __raw_remote_swp_spin_unlock(raw_remote_spinlock_t *lock)
-{
-	smp_mb();
-
-	__asm__ __volatile__(
-"	str	%1, [%0]"
-	:
-	: "r" (&lock->lock), "r" (0)
-	: "cc");
-}
-
-#define DEK_LOCK_REQUEST		1
-#define DEK_LOCK_YIELD			(!DEK_LOCK_REQUEST)
-#define DEK_YIELD_TURN_SELF		0
-static inline void __raw_remote_dek_spin_lock(raw_remote_spinlock_t *lock)
-{
-	lock->dek.self_lock = DEK_LOCK_REQUEST;
-
-	while (lock->dek.other_lock) {
-
-		if (lock->dek.next_yield == DEK_YIELD_TURN_SELF)
-			lock->dek.self_lock = DEK_LOCK_YIELD;
-
-		while (lock->dek.other_lock)
-			;
-
-		lock->dek.self_lock = DEK_LOCK_REQUEST;
-	}
-	lock->dek.next_yield = DEK_YIELD_TURN_SELF;
-
-	smp_mb();
-}
-
-static inline int __raw_remote_dek_spin_trylock(raw_remote_spinlock_t *lock)
-{
-	lock->dek.self_lock = DEK_LOCK_REQUEST;
-
-	if (lock->dek.other_lock) {
-		lock->dek.self_lock = DEK_LOCK_YIELD;
-		return 0;
-	}
-
-	lock->dek.next_yield = DEK_YIELD_TURN_SELF;
-
-	smp_mb();
-	return 1;
-}
-
-static inline void __raw_remote_dek_spin_unlock(raw_remote_spinlock_t *lock)
-{
-	smp_mb();
-
-	lock->dek.self_lock = DEK_LOCK_YIELD;
-}
-
-static inline int __raw_remote_dek_spin_release(raw_remote_spinlock_t *lock,
-		uint32_t pid)
-{
-	return -EINVAL;
-}
-
-static inline void __raw_remote_sfpb_spin_lock(raw_remote_spinlock_t *lock)
-{
-	do {
-		writel_relaxed(SMEM_SPINLOCK_PID_APPS, lock);
-		smp_mb();
-	} while (readl_relaxed(lock) != SMEM_SPINLOCK_PID_APPS);
-}
-
-static inline int __raw_remote_sfpb_spin_trylock(raw_remote_spinlock_t *lock)
-{
-	return 1;
-}
-
-static inline void __raw_remote_sfpb_spin_unlock(raw_remote_spinlock_t *lock)
-{
-	writel_relaxed(0, lock);
-	smp_mb();
-}
-
-/**
- * Release spinlock if it is owned by @pid.
- *
- * This is only to be used for situations where the processor owning
- * the spinlock has crashed and the spinlock must be released.
- *
- * @lock - lock structure
- * @pid - processor ID of processor to release
- */
-static inline int __raw_remote_gen_spin_release(raw_remote_spinlock_t *lock,
-		uint32_t pid)
-{
-	int ret = 1;
-
-	if (readl_relaxed(&lock->lock) == pid) {
-		writel_relaxed(0, &lock->lock);
-		wmb();
-		ret = 0;
-	}
-	return ret;
-}
 
 #if defined(CONFIG_MSM_SMD) || defined(CONFIG_MSM_REMOTE_SPINLOCK_SFPB)
 int _remote_spin_lock_init(remote_spinlock_id_t, _remote_spinlock_t *lock);
 void _remote_spin_release_all(uint32_t pid);
+void _remote_spin_lock(_remote_spinlock_t *lock);
+void _remote_spin_unlock(_remote_spinlock_t *lock);
+int _remote_spin_trylock(_remote_spinlock_t *lock);
+int _remote_spin_release(_remote_spinlock_t *lock, uint32_t pid);
+int _remote_spin_owner(_remote_spinlock_t *lock);
 #else
 static inline
 int _remote_spin_lock_init(remote_spinlock_id_t id, _remote_spinlock_t *lock)
@@ -232,38 +55,22 @@
 	return -EINVAL;
 }
 static inline void _remote_spin_release_all(uint32_t pid) {}
+static inline void _remote_spin_lock(_remote_spinlock_t *lock) {}
+static inline void _remote_spin_unlock(_remote_spinlock_t *lock) {}
+static inline int _remote_spin_trylock(_remote_spinlock_t *lock)
+{
+	return -ENODEV;
+}
+static inline int _remote_spin_release(_remote_spinlock_t *lock, uint32_t pid)
+{
+	return -ENODEV;
+}
+static inline int _remote_spin_owner(_remote_spinlock_t *lock)
+{
+	return -ENODEV;
+}
 #endif
 
-#if defined(CONFIG_MSM_REMOTE_SPINLOCK_DEKKERS)
-/* Use Dekker's algorithm when LDREX/STREX and SWP are unavailable for
- * shared memory */
-#define _remote_spin_lock(lock)		__raw_remote_dek_spin_lock(*lock)
-#define _remote_spin_unlock(lock)	__raw_remote_dek_spin_unlock(*lock)
-#define _remote_spin_trylock(lock)	__raw_remote_dek_spin_trylock(*lock)
-#define _remote_spin_release(lock, pid)	__raw_remote_dek_spin_release(*lock,\
-		pid)
-#elif defined(CONFIG_MSM_REMOTE_SPINLOCK_SWP)
-/* Use SWP-based locks when LDREX/STREX are unavailable for shared memory. */
-#define _remote_spin_lock(lock)		__raw_remote_swp_spin_lock(*lock)
-#define _remote_spin_unlock(lock)	__raw_remote_swp_spin_unlock(*lock)
-#define _remote_spin_trylock(lock)	__raw_remote_swp_spin_trylock(*lock)
-#define _remote_spin_release(lock, pid)	__raw_remote_gen_spin_release(*lock,\
-		pid)
-#elif defined(CONFIG_MSM_REMOTE_SPINLOCK_SFPB)
-/* Use SFPB Hardware Mutex Registers */
-#define _remote_spin_lock(lock)		__raw_remote_sfpb_spin_lock(*lock)
-#define _remote_spin_unlock(lock)	__raw_remote_sfpb_spin_unlock(*lock)
-#define _remote_spin_trylock(lock)	__raw_remote_sfpb_spin_trylock(*lock)
-#define _remote_spin_release(lock, pid)	__raw_remote_gen_spin_release(*lock,\
-		pid)
-#else
-/* Use LDREX/STREX for shared memory locking, when available */
-#define _remote_spin_lock(lock)		__raw_remote_ex_spin_lock(*lock)
-#define _remote_spin_unlock(lock)	__raw_remote_ex_spin_unlock(*lock)
-#define _remote_spin_trylock(lock)	__raw_remote_ex_spin_trylock(*lock)
-#define _remote_spin_release(lock, pid)	__raw_remote_gen_spin_release(*lock, \
-		pid)
-#endif
 
 /* Remote mutex definitions. */
 
diff --git a/arch/arm/mach-msm/include/mach/restart.h b/arch/arm/mach-msm/include/mach/restart.h
index b913e3f..84bb91d 100644
--- a/arch/arm/mach-msm/include/mach/restart.h
+++ b/arch/arm/mach-msm/include/mach/restart.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/rpc_hsusb.h b/arch/arm/mach-msm/include/mach/rpc_hsusb.h
index 88d7650..9627e2b 100644
--- a/arch/arm/mach-msm/include/mach/rpc_hsusb.h
+++ b/arch/arm/mach-msm/include/mach/rpc_hsusb.h
@@ -1,6 +1,6 @@
 /* linux/include/mach/rpc_hsusb.h
  *
- * Copyright (c) 2008-2010, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2010, 2012 The Linux Foundation. All rights reserved.
  *
  * All source code in this file is licensed under the following license except
  * where indicated.
diff --git a/arch/arm/mach-msm/include/mach/rpc_pmapp.h b/arch/arm/mach-msm/include/mach/rpc_pmapp.h
index 86f04bf..5a62f1d 100644
--- a/arch/arm/mach-msm/include/mach/rpc_pmapp.h
+++ b/arch/arm/mach-msm/include/mach/rpc_pmapp.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/include/mach/rpc_server_handset.h b/arch/arm/mach-msm/include/mach/rpc_server_handset.h
index 0856a4a..fad38cc 100644
--- a/arch/arm/mach-msm/include/mach/rpc_server_handset.h
+++ b/arch/arm/mach-msm/include/mach/rpc_server_handset.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/include/mach/rpm-8064.h b/arch/arm/mach-msm/include/mach/rpm-8064.h
index 39ec7ff..69c6b1e 100644
--- a/arch/arm/mach-msm/include/mach/rpm-8064.h
+++ b/arch/arm/mach-msm/include/mach/rpm-8064.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/include/mach/rpm-8660.h b/arch/arm/mach-msm/include/mach/rpm-8660.h
index 5e3b404..a9fdcbe 100644
--- a/arch/arm/mach-msm/include/mach/rpm-8660.h
+++ b/arch/arm/mach-msm/include/mach/rpm-8660.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/include/mach/rpm-8930.h b/arch/arm/mach-msm/include/mach/rpm-8930.h
index bc1b918..02696c9 100644
--- a/arch/arm/mach-msm/include/mach/rpm-8930.h
+++ b/arch/arm/mach-msm/include/mach/rpm-8930.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/include/mach/rpm-8960.h b/arch/arm/mach-msm/include/mach/rpm-8960.h
index 6fe8832..eab1bce 100644
--- a/arch/arm/mach-msm/include/mach/rpm-8960.h
+++ b/arch/arm/mach-msm/include/mach/rpm-8960.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/include/mach/rpm-9615.h b/arch/arm/mach-msm/include/mach/rpm-9615.h
index 4ca5eea..5c9d882 100644
--- a/arch/arm/mach-msm/include/mach/rpm-9615.h
+++ b/arch/arm/mach-msm/include/mach/rpm-9615.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/include/mach/rpm-regulator-8660.h b/arch/arm/mach-msm/include/mach/rpm-regulator-8660.h
index 85dcd89..44e7cd9 100644
--- a/arch/arm/mach-msm/include/mach/rpm-regulator-8660.h
+++ b/arch/arm/mach-msm/include/mach/rpm-regulator-8660.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/arm/mach-msm/include/mach/rpm-regulator-8930.h b/arch/arm/mach-msm/include/mach/rpm-regulator-8930.h
index f8f53f6..cbe6b45 100644
--- a/arch/arm/mach-msm/include/mach/rpm-regulator-8930.h
+++ b/arch/arm/mach-msm/include/mach/rpm-regulator-8930.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/include/mach/rpm-regulator-8960.h b/arch/arm/mach-msm/include/mach/rpm-regulator-8960.h
index abcdbb8..8134173 100644
--- a/arch/arm/mach-msm/include/mach/rpm-regulator-8960.h
+++ b/arch/arm/mach-msm/include/mach/rpm-regulator-8960.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/arm/mach-msm/include/mach/rpm-regulator-8974.h b/arch/arm/mach-msm/include/mach/rpm-regulator-8974.h
index 07ae600..1bb7eed 100644
--- a/arch/arm/mach-msm/include/mach/rpm-regulator-8974.h
+++ b/arch/arm/mach-msm/include/mach/rpm-regulator-8974.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/arm/mach-msm/include/mach/rpm-regulator-9615.h b/arch/arm/mach-msm/include/mach/rpm-regulator-9615.h
index 6a7fae5..3299be2 100644
--- a/arch/arm/mach-msm/include/mach/rpm-regulator-9615.h
+++ b/arch/arm/mach-msm/include/mach/rpm-regulator-9615.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/arm/mach-msm/include/mach/rpm-regulator-smd.h b/arch/arm/mach-msm/include/mach/rpm-regulator-smd.h
index a32e168..9e70510 100644
--- a/arch/arm/mach-msm/include/mach/rpm-regulator-smd.h
+++ b/arch/arm/mach-msm/include/mach/rpm-regulator-smd.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/include/mach/rpm-regulator.h b/arch/arm/mach-msm/include/mach/rpm-regulator.h
index b063b97..ecfbe0d 100644
--- a/arch/arm/mach-msm/include/mach/rpm-regulator.h
+++ b/arch/arm/mach-msm/include/mach/rpm-regulator.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/rpm-smd.h b/arch/arm/mach-msm/include/mach/rpm-smd.h
index 0239e36..e340256 100644
--- a/arch/arm/mach-msm/include/mach/rpm-smd.h
+++ b/arch/arm/mach-msm/include/mach/rpm-smd.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/include/mach/rpm.h b/arch/arm/mach-msm/include/mach/rpm.h
index 200a8cf..0adb453 100644
--- a/arch/arm/mach-msm/include/mach/rpm.h
+++ b/arch/arm/mach-msm/include/mach/rpm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/scm-io.h b/arch/arm/mach-msm/include/mach/scm-io.h
index 5393da1..a5c36cb 100644
--- a/arch/arm/mach-msm/include/mach/scm-io.h
+++ b/arch/arm/mach-msm/include/mach/scm-io.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/scm.h b/arch/arm/mach-msm/include/mach/scm.h
index 7cc5f7a..8a06fe3 100644
--- a/arch/arm/mach-msm/include/mach/scm.h
+++ b/arch/arm/mach-msm/include/mach/scm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/sdio_al.h b/arch/arm/mach-msm/include/mach/sdio_al.h
index 8b8ee5a..c75d12b 100644
--- a/arch/arm/mach-msm/include/mach/sdio_al.h
+++ b/arch/arm/mach-msm/include/mach/sdio_al.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/sdio_cmux.h b/arch/arm/mach-msm/include/mach/sdio_cmux.h
index 4bcd607..0297f07 100644
--- a/arch/arm/mach-msm/include/mach/sdio_cmux.h
+++ b/arch/arm/mach-msm/include/mach/sdio_cmux.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/sdio_dmux.h b/arch/arm/mach-msm/include/mach/sdio_dmux.h
index afc1b11..bb8cd51 100644
--- a/arch/arm/mach-msm/include/mach/sdio_dmux.h
+++ b/arch/arm/mach-msm/include/mach/sdio_dmux.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/sdio_smem.h b/arch/arm/mach-msm/include/mach/sdio_smem.h
index b47001f..eed0671 100644
--- a/arch/arm/mach-msm/include/mach/sdio_smem.h
+++ b/arch/arm/mach-msm/include/mach/sdio_smem.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/sirc-fsm9xxx.h b/arch/arm/mach-msm/include/mach/sirc-fsm9xxx.h
index b862211..ddbfd02 100644
--- a/arch/arm/mach-msm/include/mach/sirc-fsm9xxx.h
+++ b/arch/arm/mach-msm/include/mach/sirc-fsm9xxx.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/sirc.h b/arch/arm/mach-msm/include/mach/sirc.h
index 607bab5..7b19d15 100644
--- a/arch/arm/mach-msm/include/mach/sirc.h
+++ b/arch/arm/mach-msm/include/mach/sirc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/smem_log.h b/arch/arm/mach-msm/include/mach/smem_log.h
index a94ae76..992ab05 100644
--- a/arch/arm/mach-msm/include/mach/smem_log.h
+++ b/arch/arm/mach-msm/include/mach/smem_log.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/arch/arm/mach-msm/include/mach/socinfo.h b/arch/arm/mach-msm/include/mach/socinfo.h
index c0624bb..aeeaae6 100644
--- a/arch/arm/mach-msm/include/mach/socinfo.h
+++ b/arch/arm/mach-msm/include/mach/socinfo.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
@@ -40,6 +40,8 @@
 	of_machine_is_compatible("qcom,msm8974-sim")
 #define machine_is_msm8974_rumi()	\
 	of_machine_is_compatible("qcom,msm8974-rumi")
+#define machine_is_msm8974_fluid()	\
+	of_machine_is_compatible("qcom,msm8974-fluid")
 #define early_machine_is_msm9625()	\
 	of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,msm9625")
 #define machine_is_msm9625()		\
@@ -56,19 +58,28 @@
 	of_machine_is_compatible("qcom,msm8226-sim")
 #define machine_is_msm8226_rumi()		\
 	of_machine_is_compatible("qcom,msm8226-rumi")
-#define early_machine_is_msm8910()	\
-	of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,msm8910")
-#define machine_is_msm8910()		\
-	of_machine_is_compatible("qcom,msm8910")
-#define machine_is_msm8910_sim()		\
-	of_machine_is_compatible("qcom,msm8910-sim")
-#define machine_is_msm8910_rumi()		\
-	of_machine_is_compatible("qcom,msm8910-rumi")
+#define machine_is_msm8226_cdp()		\
+	of_machine_is_compatible("qcom,msm8226-cdp")
+#define machine_is_msm8226_fluid()		\
+	of_machine_is_compatible("qcom,msm8226-fluid")
+#define machine_is_msm8226_mtp()		\
+	of_machine_is_compatible("qcom,msm8226-mtp")
+#define machine_is_msm8226_qrd()		\
+	of_machine_is_compatible("qcom,msm8226-qrd")
+#define early_machine_is_msm8610()	\
+	of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,msm8610")
+#define machine_is_msm8610()		\
+	of_machine_is_compatible("qcom,msm8610")
+#define machine_is_msm8610_sim()		\
+	of_machine_is_compatible("qcom,msm8610-sim")
+#define machine_is_msm8610_rumi()		\
+	of_machine_is_compatible("qcom,msm8610-rumi")
 #else
 #define early_machine_is_msm8974()	0
 #define machine_is_msm8974()		0
 #define machine_is_msm8974_sim()	0
 #define machine_is_msm8974_rumi()	0
+#define machine_is_msm8974_fluid()	0
 #define early_machine_is_msm9625()	0
 #define machine_is_msm9625()		0
 #define early_machine_is_mpq8092()	0
@@ -77,10 +88,10 @@
 #define machine_is_msm8226()		0
 #define machine_is_msm8226_sim()	0
 #define machine_is_msm8226_rumi()	0
-#define early_machine_is_msm8910()	0
-#define machine_is_msm8910()		0
-#define machine_is_msm8910_sim()	0
-#define machine_is_msm8910_rumi()	0
+#define early_machine_is_msm8610()	0
+#define machine_is_msm8610()		0
+#define machine_is_msm8610_sim()	0
+#define machine_is_msm8610_rumi()	0
 
 #endif
 
@@ -105,6 +116,7 @@
 	MSM_CPU_7X25AB,
 	MSM_CPU_8064,
 	MSM_CPU_8064AB,
+	MSM_CPU_8064AA,
 	MSM_CPU_8930,
 	MSM_CPU_8930AA,
 	MSM_CPU_8930AB,
@@ -116,7 +128,7 @@
 	MSM_CPU_9625,
 	MSM_CPU_8092,
 	MSM_CPU_8226,
-	MSM_CPU_8910,
+	MSM_CPU_8610,
 	MSM_CPU_8625Q,
 };
 
@@ -332,6 +344,15 @@
 #endif
 }
 
+static inline int cpu_is_apq8064aa(void)
+{
+#ifdef CONFIG_ARCH_APQ8064
+	return read_msm_cpu_type() == MSM_CPU_8064AA;
+#else
+	return 0;
+#endif
+}
+
 static inline int cpu_is_msm8930(void)
 {
 #ifdef CONFIG_ARCH_MSM8930
@@ -442,13 +463,13 @@
 #endif
 }
 
-static inline int cpu_is_msm8910(void)
+static inline int cpu_is_msm8610(void)
 {
-#ifdef CONFIG_ARCH_MSM8910
+#ifdef CONFIG_ARCH_MSM8610
 	enum msm_cpu cpu = socinfo_get_msm_cpu();
 
 	BUG_ON(cpu == MSM_CPU_UNKNOWN);
-	return cpu == MSM_CPU_8910;
+	return cpu == MSM_CPU_8610;
 #else
 	return 0;
 #endif
@@ -473,7 +494,7 @@
 
 static inline int soc_class_is_apq8064(void)
 {
-	return cpu_is_apq8064() || cpu_is_apq8064ab();
+	return cpu_is_apq8064() || cpu_is_apq8064ab() || cpu_is_apq8064aa();
 }
 
 static inline int soc_class_is_msm8930(void)
diff --git a/arch/arm/mach-msm/include/mach/sps.h b/arch/arm/mach-msm/include/mach/sps.h
index a000c3e..cf59dd8 100644
--- a/arch/arm/mach-msm/include/mach/sps.h
+++ b/arch/arm/mach-msm/include/mach/sps.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
@@ -77,6 +77,8 @@
 #define SPS_BAM_OPT_IRQ_WAKEUP      (1UL << 3)
 /* Ignore external block pipe reset */
 #define SPS_BAM_NO_EXT_P_RST        (1UL << 4)
+/* Don't enable local clock gating */
+#define SPS_BAM_NO_LOCAL_CLK_GATING (1UL << 5)
 
 /* BAM device management flags */
 
@@ -1253,13 +1255,13 @@
  *
  * @tb_sel - testbus selection
  *
- * @pre_level - prescreening level
+ * @desc_sel - selection of descriptors
  *
  * @return 0 on success, negative value on error
  *
  */
 int sps_get_bam_debug_info(u32 dev, u32 option, u32 para,
-		u32 tb_sel, u8 pre_level);
+		u32 tb_sel, u8 desc_sel);
 
 #else
 static inline int sps_register_bam_device(const struct sps_bam_props
diff --git a/arch/arm/mach-msm/include/mach/subsystem_notif.h b/arch/arm/mach-msm/include/mach/subsystem_notif.h
index 37d4eec..5865eff 100644
--- a/arch/arm/mach-msm/include/mach/subsystem_notif.h
+++ b/arch/arm/mach-msm/include/mach/subsystem_notif.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, 2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -24,6 +24,7 @@
 	SUBSYS_AFTER_SHUTDOWN,
 	SUBSYS_BEFORE_POWERUP,
 	SUBSYS_AFTER_POWERUP,
+	SUBSYS_RAMDUMP_NOTIFICATION,
 	SUBSYS_NOTIF_TYPE_COUNT
 };
 
@@ -50,7 +51,8 @@
  */
 void *subsys_notif_add_subsys(const char *);
 int subsys_notif_queue_notification(void *subsys_handle,
-					enum subsys_notif_type notif_type);
+					enum subsys_notif_type notif_type,
+					void *data);
 #else
 
 static inline void *subsys_notif_register_notifier(
@@ -71,7 +73,8 @@
 }
 
 static inline int subsys_notif_queue_notification(void *subsys_handle,
-					enum subsys_notif_type notif_type)
+					enum subsys_notif_type notif_type,
+					void *data)
 {
 	return 0;
 }
diff --git a/arch/arm/mach-msm/include/mach/subsystem_restart.h b/arch/arm/mach-msm/include/mach/subsystem_restart.h
index 17b11e1..1f6ca66 100644
--- a/arch/arm/mach-msm/include/mach/subsystem_restart.h
+++ b/arch/arm/mach-msm/include/mach/subsystem_restart.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/include/mach/tpm_st_i2c.h b/arch/arm/mach-msm/include/mach/tpm_st_i2c.h
index 362acbb..e1d9bc1 100644
--- a/arch/arm/mach-msm/include/mach/tpm_st_i2c.h
+++ b/arch/arm/mach-msm/include/mach/tpm_st_i2c.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/include/mach/uncompress.h b/arch/arm/mach-msm/include/mach/uncompress.h
index dc20df5..d1f89f5 100644
--- a/arch/arm/mach-msm/include/mach/uncompress.h
+++ b/arch/arm/mach-msm/include/mach/uncompress.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/usb_bam.h b/arch/arm/mach-msm/include/mach/usb_bam.h
index 5e1ef6f..a7f052e 100644
--- a/arch/arm/mach-msm/include/mach/usb_bam.h
+++ b/arch/arm/mach-msm/include/mach/usb_bam.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -102,6 +102,22 @@
 	 int (*callback)(void *), void* param);
 
 /**
+ * Register a callback for peer BAM reset.
+ *
+ * @idx - Connection index.
+ *
+ * @callback - the callback function that will be called in USB
+ *				driver upon a peer bam reset
+ *
+ * @param - context that the caller can supply
+ *
+ * @return 0 on success, negative value on error
+ *
+ */
+int usb_bam_register_peer_reset_cb(u8 idx,
+	 int (*callback)(void *), void *param);
+
+/**
  * Disconnect USB-to-Periperal SPS connection.
  *
  * @idx - Connection index.
@@ -132,6 +148,27 @@
 	u32 *usb_bam_handle, u32 *usb_bam_pipe_idx, u32 *peer_pipe_idx,
 	struct sps_mem_buffer *desc_fifo, struct sps_mem_buffer *data_fifo);
 
+/**
+ * Resets the entire USB BAM.
+ *
+ */
+int usb_bam_reset(void);
+
+/**
+ * Indicates if the client of the USB BAM is ready to start
+ * sending/receiving transfers.
+ *
+ * @ready - TRUE to enable, FALSE to disable.
+ *
+ */
+int usb_bam_client_ready(bool ready);
+
+/**
+ * Returns QDSS BAM connection number
+ *
+ */
+u8 usb_bam_get_qdss_num(void);
+
 #else
 static inline int usb_bam_connect(u8 idx, u32 *src_pipe_idx, u32 *dst_pipe_idx)
 {
@@ -156,6 +193,12 @@
 	return -ENODEV;
 }
 
+static inline int usb_bam_register_peer_reset_cb(u8 idx,
+	 int (*callback)(void *), void *param)
+{
+	return -ENODEV;
+}
+
 static inline int usb_bam_disconnect_pipe(u8 idx)
 {
 	return -ENODEV;
@@ -168,5 +211,21 @@
 {
 	return;
 }
+
+static inline int usb_bam_reset(void)
+{
+	return -ENODEV;
+}
+
+static inline int usb_bam_client_ready(bool ready)
+{
+	return -ENODEV;
+}
+
+static inline u8 usb_bam_get_qdss_num(void)
+{
+	return -ENODEV;
+}
+
 #endif
 #endif				/* _USB_BAM_H_ */
diff --git a/arch/arm/mach-msm/include/mach/usb_bridge.h b/arch/arm/mach-msm/include/mach/usb_bridge.h
index 1a1c23b..c62cf01 100644
--- a/arch/arm/mach-msm/include/mach/usb_bridge.h
+++ b/arch/arm/mach-msm/include/mach/usb_bridge.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/include/mach/usb_gadget_xport.h b/arch/arm/mach-msm/include/mach/usb_gadget_xport.h
index 41dac62..a183f0e 100644
--- a/arch/arm/mach-msm/include/mach/usb_gadget_xport.h
+++ b/arch/arm/mach-msm/include/mach/usb_gadget_xport.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -19,6 +19,7 @@
 	USB_GADGET_XPORT_TTY,
 	USB_GADGET_XPORT_SDIO,
 	USB_GADGET_XPORT_SMD,
+	USB_GADGET_XPORT_QTI,
 	USB_GADGET_XPORT_BAM,
 	USB_GADGET_XPORT_BAM2BAM,
 	USB_GADGET_XPORT_BAM2BAM_IPA,
@@ -38,6 +39,8 @@
 		return "SDIO";
 	case USB_GADGET_XPORT_SMD:
 		return "SMD";
+	case USB_GADGET_XPORT_QTI:
+		return "QTI";
 	case USB_GADGET_XPORT_BAM:
 		return "BAM";
 	case USB_GADGET_XPORT_BAM2BAM:
@@ -63,6 +66,8 @@
 		return USB_GADGET_XPORT_SDIO;
 	if (!strncasecmp("SMD", name, XPORT_STR_LEN))
 		return USB_GADGET_XPORT_SMD;
+	if (!strncasecmp("QTI", name, XPORT_STR_LEN))
+		return USB_GADGET_XPORT_QTI;
 	if (!strncasecmp("BAM", name, XPORT_STR_LEN))
 		return USB_GADGET_XPORT_BAM;
 	if (!strncasecmp("BAM2BAM", name, XPORT_STR_LEN))
diff --git a/arch/arm/mach-msm/include/mach/usbdiag.h b/arch/arm/mach-msm/include/mach/usbdiag.h
index d9320c3..15f4783 100644
--- a/arch/arm/mach-msm/include/mach/usbdiag.h
+++ b/arch/arm/mach-msm/include/mach/usbdiag.h
@@ -26,6 +26,7 @@
 #define DIAG_LEGACY		"diag"
 #define DIAG_MDM		"diag_mdm"
 #define DIAG_QSC		"diag_qsc"
+#define DIAG_MDM2		"diag_mdm2"
 
 #define USB_DIAG_CONNECT	0
 #define USB_DIAG_DISCONNECT	1
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index cd70ae9..fd096ec 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -3,7 +3,7 @@
  * MSM7K, QSD io support
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2013, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -28,8 +28,10 @@
 #include <mach/memory.h>
 #include <asm/mach/map.h>
 #include <linux/dma-mapping.h>
+#include <linux/of_fdt.h>
 
 #include <mach/board.h>
+#include "board-dt.h"
 
 #define MSM_CHIP_DEVICE(name, chip) { \
 		.virtual = (unsigned long) MSM_##name##_BASE, \
@@ -303,7 +305,6 @@
 	MSM_CHIP_DEVICE(APCS_GCC, MSM8974),
 	MSM_CHIP_DEVICE(TLMM, MSM8974),
 	MSM_CHIP_DEVICE(MPM2_PSHOLD, MSM8974),
-	MSM_CHIP_DEVICE(IMEM, MSM8974),
 	{
 		.virtual =  (unsigned long) MSM_SHARED_RAM_BASE,
 		.length =   MSM_SHARED_RAM_SIZE,
@@ -312,13 +313,13 @@
 #ifdef CONFIG_DEBUG_MSM8974_UART
 	MSM_DEVICE(DEBUG_UART),
 #endif
-	MSM_CHIP_DEVICE(DBG_IMEM, MSM8974),
 };
 
 void __init msm_map_8974_io(void)
 {
 	msm_shared_ram_phys = MSM8974_MSM_SHARED_RAM_PHYS;
 	msm_map_io(msm_8974_io_desc, ARRAY_SIZE(msm_8974_io_desc));
+	of_scan_flat_dt(msm_scan_dt_map_imem, NULL);
 }
 #endif /* CONFIG_ARCH_MSM8974 */
 
@@ -470,7 +471,6 @@
 	MSM_CHIP_DEVICE(TLMM, MSM9625),
 	MSM_CHIP_DEVICE(MPM2_PSHOLD, MSM9625),
 	MSM_CHIP_DEVICE(TMR, MSM9625),
-	MSM_CHIP_DEVICE(IMEM, MSM9625),
 	{
 		.virtual =  (unsigned long) MSM_SHARED_RAM_BASE,
 		.length =   MSM_SHARED_RAM_SIZE,
@@ -479,13 +479,13 @@
 #ifdef CONFIG_DEBUG_MSM9625_UART
 	MSM_DEVICE(DEBUG_UART),
 #endif
-	MSM_CHIP_DEVICE(DBG_IMEM, MSM9625),
 };
 
 void __init msm_map_msm9625_io(void)
 {
 	msm_shared_ram_phys = MSM9625_SHARED_RAM_PHYS;
 	msm_map_io(msm9625_io_desc, ARRAY_SIZE(msm9625_io_desc));
+	of_scan_flat_dt(msm_scan_dt_map_imem, NULL);
 }
 #endif /* CONFIG_ARCH_MSM9625 */
 
@@ -518,7 +518,6 @@
 	MSM_CHIP_DEVICE(QGIC_CPU, MSM8226),
 	MSM_CHIP_DEVICE(APCS_GCC, MSM8226),
 	MSM_CHIP_DEVICE(TLMM, MSM8226),
-	MSM_CHIP_DEVICE(IMEM, MSM8226),
 	MSM_CHIP_DEVICE(MPM2_PSHOLD, MSM8226),
 	{
 		.virtual =  (unsigned long) MSM_SHARED_RAM_BASE,
@@ -535,15 +534,15 @@
 {
 	msm_shared_ram_phys = MSM8226_MSM_SHARED_RAM_PHYS;
 	msm_map_io(msm_8226_io_desc, ARRAY_SIZE(msm_8226_io_desc));
+	of_scan_flat_dt(msm_scan_dt_map_imem, NULL);
 }
 #endif /* CONFIG_ARCH_MSM8226 */
 
-#ifdef CONFIG_ARCH_MSM8910
-static struct map_desc msm8910_io_desc[] __initdata = {
-	MSM_CHIP_DEVICE(APCS_GCC, MSM8910),
-	MSM_CHIP_DEVICE(TLMM, MSM8910),
-	MSM_CHIP_DEVICE(MPM2_PSHOLD, MSM8910),
-	MSM_CHIP_DEVICE(IMEM, MSM8910),
+#ifdef CONFIG_ARCH_MSM8610
+static struct map_desc msm8610_io_desc[] __initdata = {
+	MSM_CHIP_DEVICE(APCS_GCC, MSM8610),
+	MSM_CHIP_DEVICE(TLMM, MSM8610),
+	MSM_CHIP_DEVICE(MPM2_PSHOLD, MSM8610),
 	{
 		.virtual =  (unsigned long) MSM_SHARED_RAM_BASE,
 		.length =   MSM_SHARED_RAM_SIZE,
@@ -551,9 +550,10 @@
 	},
 };
 
-void __init msm_map_msm8910_io(void)
+void __init msm_map_msm8610_io(void)
 {
-	msm_shared_ram_phys = MSM8910_MSM_SHARED_RAM_PHYS;
-	msm_map_io(msm8910_io_desc, ARRAY_SIZE(msm8910_io_desc));
+	msm_shared_ram_phys = MSM8610_MSM_SHARED_RAM_PHYS;
+	msm_map_io(msm8610_io_desc, ARRAY_SIZE(msm8610_io_desc));
+	of_scan_flat_dt(msm_scan_dt_map_imem, NULL);
 }
-#endif /* CONFIG_ARCH_MSM8910 */
+#endif /* CONFIG_ARCH_MSM8610 */
diff --git a/arch/arm/mach-msm/iommu_domains.c b/arch/arm/mach-msm/iommu_domains.c
index 75e56fe..eb44c40 100644
--- a/arch/arm/mach-msm/iommu_domains.c
+++ b/arch/arm/mach-msm/iommu_domains.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -19,6 +19,9 @@
 #include <linux/rbtree.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
 #include <asm/sizes.h>
 #include <asm/page.h>
 #include <mach/iommu.h>
@@ -26,9 +29,6 @@
 #include <mach/socinfo.h>
 #include <mach/msm_subsystem_map.h>
 
-/* dummy 64K for overmapping */
-char iommu_dummy[2*SZ_64K-4];
-
 struct msm_iova_data {
 	struct rb_node node;
 	struct mem_pool *pools;
@@ -46,17 +46,29 @@
 	return iommu_present(&platform_bus_type);
 }
 
+bool msm_iommu_page_size_is_supported(unsigned long page_size)
+{
+	return page_size == SZ_4K
+		|| page_size == SZ_64K
+		|| page_size == SZ_1M
+		|| page_size == SZ_16M;
+}
+
 int msm_iommu_map_extra(struct iommu_domain *domain,
 				unsigned long start_iova,
+				unsigned long phy_addr,
 				unsigned long size,
 				unsigned long page_size,
-				int cached)
+				int prot)
 {
 	int ret = 0;
 	int i = 0;
-	unsigned long phy_addr = ALIGN(virt_to_phys(iommu_dummy), page_size);
 	unsigned long temp_iova = start_iova;
-	if (page_size == SZ_4K) {
+	/* the extra "padding" should never be written to. map it
+	 * read-only. */
+	prot &= ~IOMMU_WRITE;
+
+	if (msm_iommu_page_size_is_supported(page_size)) {
 		struct scatterlist *sglist;
 		unsigned int nrpages = PFN_ALIGN(size) >> PAGE_SHIFT;
 		struct page *dummy_page = phys_to_page(phy_addr);
@@ -72,7 +84,7 @@
 		for (i = 0; i < nrpages; i++)
 			sg_set_page(&sglist[i], dummy_page, PAGE_SIZE, 0);
 
-		ret = iommu_map_range(domain, temp_iova, sglist, size, cached);
+		ret = iommu_map_range(domain, temp_iova, sglist, size, prot);
 		if (ret) {
 			pr_err("%s: could not map extra %lx in domain %p\n",
 				__func__, start_iova, domain);
@@ -86,7 +98,7 @@
 
 		for (i = 0; i < nrpages; i++) {
 			ret = iommu_map(domain, temp_iova, phy_addr, page_size,
-						cached);
+						prot);
 			if (ret) {
 				pr_err("%s: could not map %lx in domain %p, error: %d\n",
 					__func__, start_iova, domain, ret);
@@ -269,6 +281,27 @@
 }
 EXPORT_SYMBOL(msm_get_iommu_domain);
 
+int msm_find_domain_no(const struct iommu_domain *domain)
+{
+	struct rb_root *root = &domain_root;
+	struct rb_node *n;
+	struct msm_iova_data *node;
+	int domain_num = -EINVAL;
+
+	mutex_lock(&domain_mutex);
+
+	for (n = rb_first(root); n; n = rb_next(n)) {
+		node = rb_entry(n, struct msm_iova_data, node);
+		if (node->domain == domain) {
+			domain_num = node->domain_num;
+			break;
+		}
+	}
+	mutex_unlock(&domain_mutex);
+	return domain_num;
+}
+EXPORT_SYMBOL(msm_find_domain_no);
+
 int msm_allocate_iova_address(unsigned int iommu_domain,
 					unsigned int partition_no,
 					unsigned long size,
@@ -411,7 +444,170 @@
 }
 EXPORT_SYMBOL(msm_register_domain);
 
-static int __init iommu_domain_probe(struct platform_device *pdev)
+static int find_and_add_contexts(struct iommu_group *group,
+				 const struct device_node *node,
+				 unsigned int num_contexts)
+{
+	unsigned int i;
+	struct device *ctx;
+	const char *name;
+	struct device_node *ctx_node;
+	int ret_val = 0;
+
+	for (i = 0; i < num_contexts; ++i) {
+		ctx_node = of_parse_phandle((struct device_node *) node,
+					    "qcom,iommu-contexts", i);
+		if (!ctx_node) {
+			pr_err("Unable to parse phandle #%u\n", i);
+			ret_val = -EINVAL;
+			goto out;
+		}
+		if (of_property_read_string(ctx_node, "label", &name)) {
+			pr_err("Could not find label property\n");
+			ret_val = -EINVAL;
+			goto out;
+		}
+		ctx = msm_iommu_get_ctx(name);
+		if (!ctx) {
+			pr_err("Unable to find context %s\n", name);
+			ret_val = -EINVAL;
+			goto out;
+		}
+		iommu_group_add_device(group, ctx);
+	}
+out:
+	return ret_val;
+}
+
+static int create_and_add_domain(struct iommu_group *group,
+				 const struct device_node *node)
+{
+	unsigned int ret_val = 0;
+	unsigned int i, j;
+	struct msm_iova_layout l;
+	struct msm_iova_partition *part = 0;
+	struct iommu_domain *domain = 0;
+	unsigned int *addr_array;
+	unsigned int array_size;
+	int domain_no;
+	int secure_domain;
+	int l2_redirect;
+
+	if (of_get_property(node, "qcom,virtual-addr-pool", &array_size)) {
+		l.npartitions = array_size / sizeof(unsigned int) / 2;
+		part = kmalloc(
+			sizeof(struct msm_iova_partition) * l.npartitions,
+			       GFP_KERNEL);
+		if (!part) {
+			pr_err("%s: could not allocate space for partition",
+				__func__);
+			ret_val = -ENOMEM;
+			goto out;
+		}
+		addr_array = kmalloc(array_size, GFP_KERNEL);
+		if (!addr_array) {
+			pr_err("%s: could not allocate space for partition",
+				__func__);
+			ret_val = -ENOMEM;
+			goto free_mem;
+		}
+
+		ret_val = of_property_read_u32_array(node,
+					"qcom,virtual-addr-pool",
+					addr_array,
+					array_size/sizeof(unsigned int));
+		if (ret_val) {
+			ret_val = -EINVAL;
+			goto free_mem;
+		}
+
+		for (i = 0, j = 0; j < l.npartitions * 2; i++, j += 2) {
+			part[i].start = addr_array[j];
+			part[i].size = addr_array[j+1];
+		}
+	} else {
+		l.npartitions = 1;
+		part = kmalloc(
+			sizeof(struct msm_iova_partition) * l.npartitions,
+			       GFP_KERNEL);
+		if (!part) {
+			pr_err("%s: could not allocate space for partition",
+				__func__);
+			ret_val = -ENOMEM;
+			goto out;
+		}
+		part[0].start = 0x0;
+		part[0].size = 0xFFFFFFFF;
+	}
+
+	l.partitions = part;
+
+	secure_domain = of_property_read_bool(node, "qcom,secure-domain");
+	l.is_secure = (secure_domain) ? MSM_IOMMU_DOMAIN_SECURE : 0;
+
+	l2_redirect = of_property_read_bool(node, "qcom,l2-redirect");
+	l.domain_flags = (l2_redirect) ? MSM_IOMMU_DOMAIN_PT_CACHEABLE : 0;
+
+	domain_no = msm_register_domain(&l);
+	if (domain_no >= 0)
+		domain = msm_get_iommu_domain(domain_no);
+	else
+		ret_val = domain_no;
+
+	iommu_group_set_iommudata(group, domain, NULL);
+
+free_mem:
+	kfree(part);
+out:
+	return ret_val;
+}
+
+static int iommu_domain_parse_dt(const struct device_node *dt_node)
+{
+	struct device_node *node;
+	int sz;
+	unsigned int num_contexts;
+	int ret_val = 0;
+	struct iommu_group *group = 0;
+	const char *name;
+
+	for_each_child_of_node(dt_node, node) {
+		group = iommu_group_alloc();
+		if (IS_ERR(group)) {
+			ret_val = PTR_ERR(group);
+			goto out;
+		}
+		if (of_property_read_string(node, "label", &name)) {
+			ret_val = -EINVAL;
+			goto free_group;
+		}
+		iommu_group_set_name(group, name);
+
+		if (!of_get_property(node, "qcom,iommu-contexts", &sz)) {
+			pr_err("Could not find qcom,iommu-contexts property\n");
+			ret_val = -EINVAL;
+			goto free_group;
+		}
+		num_contexts = sz / sizeof(unsigned int);
+
+		ret_val = find_and_add_contexts(group, node, num_contexts);
+		if (ret_val) {
+			ret_val = -EINVAL;
+			goto free_group;
+		}
+		ret_val = create_and_add_domain(group, node);
+		if (ret_val) {
+			ret_val = -EINVAL;
+			goto free_group;
+		}
+	}
+free_group:
+	/* No iommu_group_free() function */
+out:
+	return ret_val;
+}
+
+static int iommu_domain_probe(struct platform_device *pdev)
 {
 	struct iommu_domains_pdata *p  = pdev->dev.platform_data;
 	int i, j;
@@ -419,7 +615,9 @@
 	if (!msm_use_iommu())
 		return -ENODEV;
 
-	if (!p)
+	if (pdev->dev.of_node)
+		return iommu_domain_parse_dt(pdev->dev.of_node);
+	else if (!p)
 		return -ENODEV;
 
 	for (i = 0; i < p->ndomains; i++) {
@@ -465,26 +663,48 @@
 			continue;
 
 		if (iommu_attach_device(domain, ctx)) {
-			WARN(1, "%s: could not attach domain %p to context %s."
-				" iommu programming will not occur.\n",
-				__func__, domain,
-				p->domain_names[i].name);
+			WARN(1, "%s: could not attach domain %p to context %s. iommu programming will not occur.\n",
+				__func__, domain, p->domain_names[i].name);
 			continue;
 		}
 	}
-
 	return 0;
 }
 
+static int __devexit iommu_domain_exit(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static struct of_device_id msm_iommu_domain_match_table[] = {
+	{ .name = "qcom,iommu-domains", },
+	{}
+};
+
 static struct platform_driver iommu_domain_driver = {
 	.driver         = {
 		.name = "iommu_domains",
+		.of_match_table = msm_iommu_domain_match_table,
 		.owner = THIS_MODULE
 	},
+	.probe		= iommu_domain_probe,
+	.remove		= __devexit_p(iommu_domain_exit),
 };
 
 static int __init msm_subsystem_iommu_init(void)
 {
-	return platform_driver_probe(&iommu_domain_driver, iommu_domain_probe);
+	int ret;
+	ret = platform_driver_register(&iommu_domain_driver);
+	if (ret != 0)
+		pr_err("Failed to register IOMMU domain driver\n");
+	return ret;
 }
+
+static void __exit msm_subsystem_iommu_exit(void)
+{
+	platform_driver_unregister(&iommu_domain_driver);
+}
+
 device_initcall(msm_subsystem_iommu_init);
+module_exit(msm_subsystem_iommu_exit);
+
diff --git a/arch/arm/mach-msm/ipc_logging.c b/arch/arm/mach-msm/ipc_logging.c
index 2cd30de..1260a1a 100644
--- a/arch/arm/mach-msm/ipc_logging.c
+++ b/arch/arm/mach-msm/ipc_logging.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/ipc_logging.h b/arch/arm/mach-msm/ipc_logging.h
index 5e614ab..0eb82a5 100644
--- a/arch/arm/mach-msm/ipc_logging.h
+++ b/arch/arm/mach-msm/ipc_logging.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/ipc_logging_debug.c b/arch/arm/mach-msm/ipc_logging_debug.c
index ee3672e..ff947ef 100644
--- a/arch/arm/mach-msm/ipc_logging_debug.c
+++ b/arch/arm/mach-msm/ipc_logging_debug.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/ipc_router.c b/arch/arm/mach-msm/ipc_router.c
index fde43b0..ea874bd 100644
--- a/arch/arm/mach-msm/ipc_router.c
+++ b/arch/arm/mach-msm/ipc_router.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -198,12 +198,6 @@
 static struct workqueue_struct *msm_ipc_router_workqueue;
 
 enum {
-	CLIENT_PORT,
-	SERVER_PORT,
-	CONTROL_PORT,
-};
-
-enum {
 	DOWN,
 	UP,
 };
@@ -564,9 +558,9 @@
 	mutex_init(&port_ptr->port_rx_q_lock);
 	init_waitqueue_head(&port_ptr->port_rx_wait_q);
 	snprintf(port_ptr->rx_wakelock_name, MAX_WAKELOCK_NAME_SZ,
-		 "msm_ipc_read%08x:%08x",
-		 port_ptr->this_port.node_id,
-		 port_ptr->this_port.port_id);
+		 "ipc%08x_%s",
+		 port_ptr->this_port.port_id,
+		 current->comm);
 	wake_lock_init(&port_ptr->port_rx_wake_lock,
 			WAKE_LOCK_SUSPEND, port_ptr->rx_wakelock_name);
 
@@ -1465,8 +1459,9 @@
 	for (i = 0; i < RT_HASH_SIZE; i++) {
 		list_for_each_entry(rt_entry, &routing_table[i], list) {
 			if ((rt_entry->node_id != IPC_ROUTER_NID_LOCAL) &&
-			    (rt_entry->xprt_info->xprt->link_id ==
-			     xprt_info->xprt->link_id))
+			    (!rt_entry->xprt_info ||
+			     (rt_entry->xprt_info->xprt->link_id ==
+			      xprt_info->xprt->link_id)))
 				continue;
 			rc = msm_ipc_router_send_server_list(rt_entry->node_id,
 							     xprt_info);
@@ -1872,6 +1867,7 @@
 	struct rr_header *hdr;
 	struct msm_ipc_port *port_ptr;
 	struct rr_packet *pkt;
+	int ret_len;
 
 	if (!data) {
 		pr_err("%s: Invalid pkt pointer\n", __func__);
@@ -1917,11 +1913,12 @@
 	mutex_lock(&port_ptr->port_rx_q_lock);
 	wake_lock(&port_ptr->port_rx_wake_lock);
 	list_add_tail(&pkt->list, &port_ptr->port_rx_q);
+	ret_len = pkt->length;
 	wake_up(&port_ptr->port_rx_wait_q);
 	mutex_unlock(&port_ptr->port_rx_q_lock);
 	mutex_unlock(&local_ports_lock);
 
-	return pkt->length;
+	return ret_len;
 }
 
 static int msm_ipc_router_write_pkt(struct msm_ipc_port *src,
@@ -2288,19 +2285,30 @@
 			RR("x REMOVE_SERVER Name=%d:%08x Id=%d:%08x\n",
 			   msg.srv.service, msg.srv.instance,
 			   msg.srv.node_id, msg.srv.port_id);
-		} else if (port_ptr->type == CLIENT_PORT) {
-			msg.cmd = IPC_ROUTER_CTRL_CMD_REMOVE_CLIENT;
-			msg.cli.node_id = port_ptr->this_port.node_id;
-			msg.cli.port_id = port_ptr->this_port.port_id;
-			RR("x REMOVE_CLIENT id=%d:%08x\n",
-			   msg.cli.node_id, msg.cli.port_id);
+			broadcast_ctl_msg(&msg);
+			broadcast_ctl_msg_locally(&msg);
 		}
+
+		/*
+		 * Server port could have been a client port earlier.
+		 * Send REMOVE_CLIENT message in either case.
+		 */
+		msg.cmd = IPC_ROUTER_CTRL_CMD_REMOVE_CLIENT;
+		msg.cli.node_id = port_ptr->this_port.node_id;
+		msg.cli.port_id = port_ptr->this_port.port_id;
+		RR("x REMOVE_CLIENT id=%d:%08x\n",
+		   msg.cli.node_id, msg.cli.port_id);
 		broadcast_ctl_msg(&msg);
 		broadcast_ctl_msg_locally(&msg);
 	} else if (port_ptr->type == CONTROL_PORT) {
 		mutex_lock(&control_ports_lock);
 		list_del(&port_ptr->list);
 		mutex_unlock(&control_ports_lock);
+	} else if (port_ptr->type == IRSC_PORT) {
+		mutex_lock(&local_ports_lock);
+		list_del(&port_ptr->list);
+		mutex_unlock(&local_ports_lock);
+		signal_irsc_completion();
 	}
 
 	mutex_lock(&port_ptr->port_rx_q_lock);
diff --git a/arch/arm/mach-msm/ipc_router.h b/arch/arm/mach-msm/ipc_router.h
index 39bde30..a50a37d 100644
--- a/arch/arm/mach-msm/ipc_router.h
+++ b/arch/arm/mach-msm/ipc_router.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -55,6 +55,13 @@
 #define ALL_SERVICE 0xFFFFFFFF
 #define ALL_INSTANCE 0xFFFFFFFF
 
+enum {
+	CLIENT_PORT,
+	SERVER_PORT,
+	CONTROL_PORT,
+	IRSC_PORT,
+};
+
 union rr_control_msg {
 	uint32_t cmd;
 	struct {
diff --git a/arch/arm/mach-msm/ipc_router_smd_xprt.c b/arch/arm/mach-msm/ipc_router_smd_xprt.c
index 8c0bf4b..88ab8e0 100644
--- a/arch/arm/mach-msm/ipc_router_smd_xprt.c
+++ b/arch/arm/mach-msm/ipc_router_smd_xprt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
@@ -40,7 +40,7 @@
 
 #define MIN_FRAG_SZ (IPC_ROUTER_HDR_SIZE + sizeof(union rr_control_msg))
 
-#define NUM_SMD_XPRTS 3
+#define NUM_SMD_XPRTS 4
 #define XPRT_NAME_LEN (SMD_MAX_CH_NAME_LEN + 12)
 
 struct msm_ipc_router_smd_xprt {
@@ -76,6 +76,7 @@
 	{"RPCRPY_CNTL", "ipc_rtr_smd_rpcrpy_cntl", SMD_APPS_MODEM, 1},
 	{"IPCRTR", "ipc_rtr_smd_ipcrtr", SMD_APPS_MODEM, 1},
 	{"IPCRTR", "ipc_rtr_q6_ipcrtr", SMD_APPS_QDSP, 1},
+	{"IPCRTR", "ipc_rtr_wcnss_ipcrtr", SMD_APPS_WCNSS, 1},
 };
 
 static struct msm_ipc_router_smd_xprt smd_remote_xprt[NUM_SMD_XPRTS];
diff --git a/arch/arm/mach-msm/ipc_socket.c b/arch/arm/mach-msm/ipc_socket.c
index 5d21fa5..a08e7de 100644
--- a/arch/arm/mach-msm/ipc_socket.c
+++ b/arch/arm/mach-msm/ipc_socket.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -20,6 +20,9 @@
 #include <linux/fcntl.h>
 #include <linux/gfp.h>
 #include <linux/msm_ipc.h>
+#include <linux/sched.h>
+#include <linux/thread_info.h>
+#include <linux/qmi_encdec.h>
 
 #include <asm/string.h>
 #include <asm/atomic.h>
@@ -27,16 +30,93 @@
 #include <net/sock.h>
 
 #include <mach/msm_ipc_router.h>
+#include <mach/msm_ipc_logging.h>
 
 #include "ipc_router.h"
 #include "msm_ipc_router_security.h"
 
 #define msm_ipc_sk(sk) ((struct msm_ipc_sock *)(sk))
 #define msm_ipc_sk_port(sk) ((struct msm_ipc_port *)(msm_ipc_sk(sk)->port))
+#define REQ_RESP_IPC_LOG_PAGES 5
+#define IND_IPC_LOG_PAGES 5
+#define IPC_SEND 1
+#define IPC_RECV 2
+#define IPC_REQ_RESP_LOG(level, buf...) \
+do { \
+	if (ipc_req_resp_log_txt) { \
+		ipc_log_string(ipc_req_resp_log_txt, buf); \
+	} \
+} while (0) \
+
+#define IPC_IND_LOG(level, buf...) \
+do { \
+	if (ipc_ind_log_txt) { \
+		ipc_log_string(ipc_ind_log_txt, buf); \
+	} \
+} while (0) \
 
 static int sockets_enabled;
 static struct proto msm_ipc_proto;
 static const struct proto_ops msm_ipc_proto_ops;
+static void *ipc_req_resp_log_txt;
+static void *ipc_ind_log_txt;
+
+/**
+ * msm_ipc_router_ipc_log() - Pass log data to IPC logging framework
+ * @tran:	Identifies the data to be a receive or send.
+ * @ipc_buf:	Buffer to extract the log data.
+ * @port_ptr:	IPC Router port corresponding to the current log data.
+ *
+ * This function builds the data the would be passed on to the IPC logging
+ * framework. The data that would be passed corresponds to the information
+ * that is exchanged between the IPC Router and user space modules during
+ * request/response/indication transactions.
+ */
+
+static void msm_ipc_router_ipc_log(uint8_t tran,
+			struct sk_buff *ipc_buf, struct msm_ipc_port *port_ptr)
+{
+	struct qmi_header *hdr = (struct qmi_header *)ipc_buf->data;
+
+	/*
+	 * IPC Logging format is as below:-
+	 * <Name>(Name of the User Space Process):
+	 * <PID> (PID of the user space process) :
+	 * <TID> (TID of the user space thread)  :
+	 * <User Space Module>(CLNT or  SERV)    :
+	 * <Opertaion Type> (Transmit)		 :
+	 * <Control Flag> (Req/Resp/Ind)	 :
+	 * <Transaction ID>			 :
+	 * <Message ID>				 :
+	 * <Message Length>			 :
+	 */
+	if (ipc_req_resp_log_txt &&
+		(((uint8_t) hdr->cntl_flag == QMI_REQUEST_CONTROL_FLAG) ||
+		((uint8_t) hdr->cntl_flag == QMI_RESPONSE_CONTROL_FLAG)) &&
+		(port_ptr->type == CLIENT_PORT ||
+					port_ptr->type == SERVER_PORT)) {
+		IPC_REQ_RESP_LOG(KERN_DEBUG,
+			"%s %d %d %s %s CF:%x TI:%x MI:%x ML:%x",
+			current->comm, current->tgid, current->pid,
+			(port_ptr->type == CLIENT_PORT ? "QCCI" : "QCSI"),
+			(tran == IPC_RECV ? "RX" :
+			(tran == IPC_SEND ? "TX" : "ERR")),
+			(uint8_t)hdr->cntl_flag, hdr->txn_id, hdr->msg_id,
+			hdr->msg_len);
+	} else if (ipc_ind_log_txt &&
+		((uint8_t)hdr->cntl_flag == QMI_INDICATION_CONTROL_FLAG) &&
+		(port_ptr->type == CLIENT_PORT ||
+					port_ptr->type == SERVER_PORT)) {
+		IPC_IND_LOG(KERN_DEBUG,
+			"%s %d %d %s %s CF:%x TI:%x MI:%x ML:%x",
+			current->comm, current->tgid, current->pid,
+			(port_ptr->type == CLIENT_PORT ? "QCCI" : "QCSI"),
+			(tran == IPC_RECV ? "RX" :
+			(tran == IPC_SEND ? "TX" : "ERR")),
+			(uint8_t)hdr->cntl_flag, hdr->txn_id, hdr->msg_id,
+			hdr->msg_len);
+	}
+}
 
 static struct sk_buff_head *msm_ipc_router_build_msg(unsigned int num_sect,
 					  struct iovec const *msg_sect,
@@ -174,12 +254,6 @@
 	struct msm_ipc_port *port_ptr;
 	void *pil;
 
-	if (!check_permissions()) {
-		pr_err("%s: %s Do not have permissions\n",
-			__func__, current->comm);
-		return -EPERM;
-	}
-
 	if (unlikely(protocol != 0)) {
 		pr_err("%s: Protocol not supported\n", __func__);
 		return -EPROTONOSUPPORT;
@@ -229,6 +303,12 @@
 	if (!sk)
 		return -EINVAL;
 
+	if (!check_permissions()) {
+		pr_err("%s: %s Do not have permissions\n",
+			__func__, current->comm);
+		return -EPERM;
+	}
+
 	if (!uaddr_len) {
 		pr_err("%s: Invalid address length\n", __func__);
 		return -EINVAL;
@@ -263,6 +343,7 @@
 	struct msm_ipc_port *port_ptr = msm_ipc_sk_port(sk);
 	struct sockaddr_msm_ipc *dest = (struct sockaddr_msm_ipc *)m->msg_name;
 	struct sk_buff_head *msg;
+	struct sk_buff *ipc_buf;
 	int ret;
 
 	if (!dest)
@@ -282,6 +363,10 @@
 		goto out_sendmsg;
 	}
 
+	if (port_ptr->type == CLIENT_PORT)
+		wait_for_irsc_completion();
+	ipc_buf = skb_peek(msg);
+	msm_ipc_router_ipc_log(IPC_SEND, ipc_buf, port_ptr);
 	ret = msm_ipc_router_send_to(port_ptr, msg, &dest->address);
 	if (ret == (IPC_ROUTER_HDR_SIZE + total_len))
 		ret = total_len;
@@ -297,6 +382,7 @@
 	struct sock *sk = sock->sk;
 	struct msm_ipc_port *port_ptr = msm_ipc_sk_port(sk);
 	struct sk_buff_head *msg;
+	struct sk_buff *ipc_buf;
 	long timeout;
 	int ret;
 
@@ -341,6 +427,8 @@
 	}
 
 	ret = msm_ipc_router_extract_msg(m, msg);
+	ipc_buf = skb_peek(msg);
+	msm_ipc_router_ipc_log(IPC_RECV, ipc_buf, port_ptr);
 	msm_ipc_router_release_msg(msg);
 	msg = NULL;
 	release_sock(sk);
@@ -397,6 +485,14 @@
 		if (server_arg.num_entries_in_array) {
 			srv_info_sz = server_arg.num_entries_in_array *
 					sizeof(*srv_info);
+			if ((srv_info_sz / sizeof(*srv_info)) !=
+			    server_arg.num_entries_in_array) {
+				pr_err("%s: Integer Overflow %d * %d\n",
+					__func__, sizeof(*srv_info),
+					server_arg.num_entries_in_array);
+				ret = -EINVAL;
+				break;
+			}
 			srv_info = kmalloc(srv_info_sz, GFP_KERNEL);
 			if (!srv_info) {
 				ret = -ENOMEM;
@@ -431,6 +527,8 @@
 
 	case IPC_ROUTER_IOCTL_CONFIG_SEC_RULES:
 		ret = msm_ipc_config_sec_rules((void *)arg);
+		if (ret != -EPERM)
+			port_ptr->type = IRSC_PORT;
 		break;
 
 	default:
@@ -505,6 +603,29 @@
 	.obj_size       = sizeof(struct msm_ipc_sock),
 };
 
+/**
+ * msm_ipc_router_ipc_log_init() - Init function for IPC Logging
+ *
+ * Initialize the buffers to be used to provide the log information
+ * pertaining to the request, response and indication data flow that
+ * happens between user and kernel spaces.
+ */
+void msm_ipc_router_ipc_log_init(void)
+{
+	ipc_req_resp_log_txt =
+		ipc_log_context_create(REQ_RESP_IPC_LOG_PAGES, "req_resp");
+	if (!ipc_req_resp_log_txt) {
+		pr_err("%s: Unable to create IPC logging for Req/Resp",
+			__func__);
+	}
+	ipc_ind_log_txt =
+		ipc_log_context_create(IND_IPC_LOG_PAGES, "indication");
+	if (!ipc_ind_log_txt) {
+		pr_err("%s: Unable to create IPC logging for Indications",
+			__func__);
+	}
+}
+
 int msm_ipc_router_init_sockets(void)
 {
 	int ret;
@@ -523,6 +644,7 @@
 	}
 
 	sockets_enabled = 1;
+	msm_ipc_router_ipc_log_init();
 out_init_sockets:
 	return ret;
 }
diff --git a/arch/arm/mach-msm/irq-vic.c b/arch/arm/mach-msm/irq-vic.c
index 489faa3..7e485ed 100644
--- a/arch/arm/mach-msm/irq-vic.c
+++ b/arch/arm/mach-msm/irq-vic.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009, 2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, 2011 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/irq.h b/arch/arm/mach-msm/irq.h
index 8b0fbc0..67ff446 100644
--- a/arch/arm/mach-msm/irq.h
+++ b/arch/arm/mach-msm/irq.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/arch/arm/mach-msm/jtag-mm.c b/arch/arm/mach-msm/jtag-mm.c
new file mode 100644
index 0000000..af05995
--- /dev/null
+++ b/arch/arm/mach-msm/jtag-mm.c
@@ -0,0 +1,747 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/smp.h>
+#include <linux/export.h>
+#include <linux/printk.h>
+#include <linux/ratelimit.h>
+#include <linux/coresight.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/bitops.h>
+#include <mach/scm.h>
+#include <mach/jtag.h>
+
+/* Coresight management registers */
+#define CORESIGHT_ITCTRL	(0xF00)
+#define CORESIGHT_CLAIMSET	(0xFA0)
+#define CORESIGHT_CLAIMCLR	(0xFA4)
+#define CORESIGHT_LAR		(0xFB0)
+#define CORESIGHT_LSR		(0xFB4)
+#define CORESIGHT_AUTHSTATUS	(0xFB8)
+#define CORESIGHT_DEVID		(0xFC8)
+#define CORESIGHT_DEVTYPE	(0xFCC)
+
+#define CORESIGHT_UNLOCK	(0xC5ACCE55)
+
+#define TIMEOUT_US		(100)
+
+#define BM(lsb, msb)		((BIT(msb) - BIT(lsb)) + BIT(msb))
+#define BMVAL(val, lsb, msb)	((val & BM(lsb, msb)) >> lsb)
+#define BVAL(val, n)		((val & BIT(n)) >> n)
+
+/* Trace registers */
+#define ETMCR			(0x000)
+#define ETMCCR			(0x004)
+#define ETMTRIGGER		(0x008)
+#define ETMASICCTLR		(0x00C)
+#define ETMSR			(0x010)
+#define ETMSCR			(0x014)
+#define ETMTSSCR		(0x018)
+#define ETMTECR2		(0x01C)
+#define ETMTEEVR		(0x020)
+#define ETMTECR1		(0x024)
+#define ETMFFLR			(0x02C)
+#define ETMVDEVR		(0x030)
+#define ETMVDCR1		(0x034)
+#define ETMVDCR3		(0x03C)
+#define ETMACVRn(n)		(0x040 + (n * 4))
+#define ETMACTRn(n)		(0x080 + (n * 4))
+#define ETMDCVRn(n)		(0x0C0 + (n * 8))
+#define ETMDCMRn(n)		(0x100 + (n * 8))
+#define ETMCNTRLDVRn(n)		(0x140 + (n * 4))
+#define ETMCNTENRn(n)		(0x150 + (n * 4))
+#define ETMCNTRLDEVRn(n)	(0x160 + (n * 4))
+#define ETMCNTVRn(n)		(0x170 + (n * 4))
+#define ETMSQ12EVR		(0x180)
+#define ETMSQ21EVR		(0x184)
+#define ETMSQ23EVR		(0x188)
+#define ETMSQ31EVR		(0x18C)
+#define ETMSQ32EVR		(0x190)
+#define ETMSQ13EVR		(0x194)
+#define ETMSQR			(0x19C)
+#define ETMEXTOUTEVRn(n)	(0x1A0 + (n * 4))
+#define ETMCIDCVRn(n)		(0x1B0 + (n * 4))
+#define ETMCIDCMR		(0x1BC)
+#define ETMIMPSPEC0		(0x1C0)
+#define ETMIMPSPEC1		(0x1C4)
+#define ETMIMPSPEC2		(0x1C8)
+#define ETMIMPSPEC3		(0x1CC)
+#define ETMIMPSPEC4		(0x1D0)
+#define ETMIMPSPEC5		(0x1D4)
+#define ETMIMPSPEC6		(0x1D8)
+#define ETMIMPSPEC7		(0x1DC)
+#define ETMSYNCFR		(0x1E0)
+#define ETMIDR			(0x1E4)
+#define ETMCCER			(0x1E8)
+#define ETMEXTINSELR		(0x1EC)
+#define ETMTESSEICR		(0x1F0)
+#define ETMEIBCR		(0x1F4)
+#define ETMTSEVR		(0x1F8)
+#define ETMAUXCR		(0x1FC)
+#define ETMTRACEIDR		(0x200)
+#define ETMIDR2			(0x208)
+#define ETMVMIDCVR		(0x240)
+#define ETMCLAIMSET		(0xFA0)
+#define ETMCLAIMCLR		(0xFA4)
+/* ETM Management registers */
+#define ETMOSLAR		(0x300)
+#define ETMOSLSR		(0x304)
+#define ETMOSSRR		(0x308)
+#define ETMPDCR			(0x310)
+#define ETMPDSR			(0x314)
+
+#define ETM_MAX_ADDR_CMP	(16)
+#define ETM_MAX_CNTR		(4)
+#define ETM_MAX_CTXID_CMP	(3)
+
+/* DBG Registers */
+#define DBGDIDR			(0x0)
+#define DBGWFAR			(0x18)
+#define DBGVCR			(0x1C)
+#define DBGDTRRXext		(0x80)
+#define DBGDSCRext		(0x88)
+#define DBGDTRTXext		(0x8C)
+#define DBGDRCR			(0x90)
+#define DBGBVRn(n)		(0x100 + (n * 4))
+#define DBGBCRn(n)		(0x140 + (n * 4))
+#define DBGWVRn(n)		(0x180 + (n * 4))
+#define DBGWCRn(n)		(0x1C0 + (n * 4))
+#define DBGPRCR			(0x310)
+#define DBGITMISCOUT		(0xEF8)
+#define DBGITMISCIN		(0xEFC)
+#define DBGCLAIMSET		(0xFA0)
+#define DBGCLAIMCLR		(0xFA4)
+
+#define DBGDSCR_MASK		(0x6C30FC3C)
+
+#define MAX_DBG_STATE_SIZE	(90)
+#define MAX_ETM_STATE_SIZE	(78)
+
+#define TZ_DBG_ETM_FEAT_ID	(0x8)
+#define TZ_DBG_ETM_VER		(0x400000)
+
+#define ARCH_V3_5		(0x25)
+#define ARM_DEBUG_ARCH_V7B	(0x3)
+
+#define etm_write(etm, val, off)	\
+			__raw_writel(val, etm->base + off)
+#define etm_read(etm, off)	\
+			__raw_readl(etm->base + off)
+
+#define dbg_write(dbg, val, off)	\
+			__raw_writel(val, dbg->base + off)
+#define dbg_read(dbg, off)	\
+			__raw_readl(dbg->base + off)
+
+#define ETM_LOCK(base)						\
+do {									\
+	/* recommended by spec to ensure ETM writes are committed prior
+	 * to resuming execution
+	 */								\
+	mb();								\
+	etm_write(base, 0x0, CORESIGHT_LAR);			\
+} while (0)
+
+#define ETM_UNLOCK(base)						\
+do {									\
+	etm_write(base, CORESIGHT_UNLOCK, CORESIGHT_LAR);	\
+	/* ensure unlock and any pending writes are committed prior to
+	 * programming ETM registers
+	 */								\
+	mb();								\
+} while (0)
+
+#define DBG_LOCK(base)						\
+do {									\
+	/* recommended by spec to ensure ETM writes are committed prior
+	 * to resuming execution
+	 */								\
+	mb();								\
+	dbg_write(base, 0x0, CORESIGHT_LAR);			\
+} while (0)
+
+#define DBG_UNLOCK(base)						\
+do {									\
+	dbg_write(base, CORESIGHT_UNLOCK, CORESIGHT_LAR);	\
+	/* ensure unlock and any pending writes are committed prior to
+	 * programming ETM registers
+	 */								\
+	mb();								\
+} while (0)
+
+uint32_t msm_jtag_save_cntr[NR_CPUS];
+uint32_t msm_jtag_restore_cntr[NR_CPUS];
+
+struct dbg_cpu_ctx {
+	void __iomem		*base;
+	uint32_t		*state;
+};
+
+struct dbg_ctx {
+	uint8_t			arch;
+	uint8_t			nr_wp;
+	uint8_t			nr_bp;
+	uint8_t			nr_ctx_cmp;
+	struct dbg_cpu_ctx	*cpu_ctx[NR_CPUS];
+	bool			save_restore_enabled[NR_CPUS];
+};
+static struct dbg_ctx dbg;
+
+struct etm_cpu_ctx {
+	void __iomem		*base;
+	struct device		*dev;
+	uint32_t		*state;
+};
+
+struct etm_ctx {
+	uint8_t			arch;
+	uint8_t			nr_addr_cmp;
+	uint8_t			nr_data_cmp;
+	uint8_t			nr_cntr;
+	uint8_t			nr_ext_inp;
+	uint8_t			nr_ext_out;
+	uint8_t			nr_ctxid_cmp;
+	struct etm_cpu_ctx	*cpu_ctx[NR_CPUS];
+	bool			save_restore_enabled[NR_CPUS];
+};
+
+static struct etm_ctx etm;
+
+static struct clk *clock[NR_CPUS];
+
+static void etm_set_pwrdwn(struct etm_cpu_ctx *etmdata)
+{
+	uint32_t etmcr;
+
+	/* ensure all writes are complete before setting pwrdwn */
+	mb();
+	etmcr = etm_read(etmdata, ETMCR);
+	etmcr |= BIT(0);
+	etm_write(etmdata, etmcr, ETMCR);
+}
+
+static void etm_clr_pwrdwn(struct etm_cpu_ctx *etmdata)
+{
+	uint32_t etmcr;
+
+	etmcr = etm_read(etmdata, ETMCR);
+	etmcr &= ~BIT(0);
+	etm_write(etmdata, etmcr, ETMCR);
+	/* ensure pwrup completes before subsequent register accesses */
+	mb();
+}
+
+static void etm_set_prog(struct etm_cpu_ctx *etmdata)
+{
+	uint32_t etmcr;
+	int count;
+
+	etmcr = etm_read(etmdata, ETMCR);
+	etmcr |= BIT(10);
+	etm_write(etmdata, etmcr, ETMCR);
+	for (count = TIMEOUT_US; BVAL(etm_read(etmdata, ETMSR), 1) != 1
+				&& count > 0; count--)
+		udelay(1);
+	WARN(count == 0, "timeout while setting prog bit, ETMSR: %#x\n",
+	     etm_read(etmdata, ETMSR));
+}
+
+static inline void etm_save_state(struct etm_cpu_ctx *etmdata)
+{
+	int i, j;
+
+	i = 0;
+	ETM_UNLOCK(etmdata);
+
+	switch (etm.arch) {
+	case ETM_ARCH_V3_5:
+		etmdata->state[i++] = etm_read(etmdata, ETMTRIGGER);
+		etmdata->state[i++] = etm_read(etmdata, ETMASICCTLR);
+		etmdata->state[i++] = etm_read(etmdata, ETMSR);
+		etmdata->state[i++] = etm_read(etmdata, ETMTSSCR);
+		etmdata->state[i++] = etm_read(etmdata, ETMTECR2);
+		etmdata->state[i++] = etm_read(etmdata, ETMTEEVR);
+		etmdata->state[i++] = etm_read(etmdata, ETMTECR1);
+		etmdata->state[i++] = etm_read(etmdata, ETMFFLR);
+		etmdata->state[i++] = etm_read(etmdata, ETMVDEVR);
+		etmdata->state[i++] = etm_read(etmdata, ETMVDCR1);
+		etmdata->state[i++] = etm_read(etmdata, ETMVDCR3);
+		for (j = 0; j < etm.nr_addr_cmp; j++) {
+			etmdata->state[i++] = etm_read(etmdata,
+								ETMACVRn(j));
+			etmdata->state[i++] = etm_read(etmdata,
+								ETMACTRn(j));
+		}
+		for (j = 0; j < etm.nr_data_cmp; j++) {
+			etmdata->state[i++] = etm_read(etmdata,
+								ETMDCVRn(j));
+			etmdata->state[i++] = etm_read(etmdata,
+								ETMDCMRn(j));
+		}
+		for (j = 0; j < etm.nr_cntr; j++) {
+			etmdata->state[i++] = etm_read(etmdata,
+							ETMCNTRLDVRn(j));
+			etmdata->state[i++] = etm_read(etmdata,
+							ETMCNTENRn(j));
+			etmdata->state[i++] = etm_read(etmdata,
+							ETMCNTRLDEVRn(j));
+			etmdata->state[i++] = etm_read(etmdata,
+							ETMCNTVRn(j));
+		}
+		etmdata->state[i++] = etm_read(etmdata, ETMSQ12EVR);
+		etmdata->state[i++] = etm_read(etmdata, ETMSQ21EVR);
+		etmdata->state[i++] = etm_read(etmdata, ETMSQ23EVR);
+		etmdata->state[i++] = etm_read(etmdata, ETMSQ31EVR);
+		etmdata->state[i++] = etm_read(etmdata, ETMSQ32EVR);
+		etmdata->state[i++] = etm_read(etmdata, ETMSQ13EVR);
+		etmdata->state[i++] = etm_read(etmdata, ETMSQR);
+		for (j = 0; j < etm.nr_ext_out; j++)
+			etmdata->state[i++] = etm_read(etmdata,
+							ETMEXTOUTEVRn(j));
+		for (j = 0; j < etm.nr_ctxid_cmp; j++)
+			etmdata->state[i++] = etm_read(etmdata,
+							ETMCIDCVRn(j));
+		etmdata->state[i++] = etm_read(etmdata, ETMCIDCMR);
+		etmdata->state[i++] = etm_read(etmdata, ETMSYNCFR);
+		etmdata->state[i++] = etm_read(etmdata, ETMEXTINSELR);
+		etmdata->state[i++] = etm_read(etmdata, ETMTSEVR);
+		etmdata->state[i++] = etm_read(etmdata, ETMAUXCR);
+		etmdata->state[i++] = etm_read(etmdata, ETMTRACEIDR);
+		etmdata->state[i++] = etm_read(etmdata, ETMVMIDCVR);
+		etmdata->state[i++] = etm_read(etmdata, ETMCLAIMCLR);
+		etmdata->state[i++] = etm_read(etmdata, ETMCR);
+		break;
+	default:
+		pr_err_ratelimited("unsupported etm arch %d in %s\n", etm.arch,
+								__func__);
+	}
+
+	ETM_LOCK(etmdata);
+}
+
+static inline void etm_restore_state(struct etm_cpu_ctx *etmdata)
+{
+	int i, j;
+
+	i = 0;
+	ETM_UNLOCK(etmdata);
+
+	switch (etm.arch) {
+	case ETM_ARCH_V3_5:
+		etm_clr_pwrdwn(etmdata);
+		etm_write(etmdata, etmdata->state[i++], ETMTRIGGER);
+		etm_write(etmdata, etmdata->state[i++], ETMASICCTLR);
+		etm_write(etmdata, etmdata->state[i++], ETMSR);
+		etm_write(etmdata, etmdata->state[i++], ETMTSSCR);
+		etm_write(etmdata, etmdata->state[i++], ETMTECR2);
+		etm_write(etmdata, etmdata->state[i++], ETMTEEVR);
+		etm_write(etmdata, etmdata->state[i++], ETMTECR1);
+		etm_write(etmdata, etmdata->state[i++], ETMFFLR);
+		etm_write(etmdata, etmdata->state[i++], ETMVDEVR);
+		etm_write(etmdata, etmdata->state[i++], ETMVDCR1);
+		etm_write(etmdata, etmdata->state[i++], ETMVDCR3);
+		for (j = 0; j < etm.nr_addr_cmp; j++) {
+			etm_write(etmdata, etmdata->state[i++],
+								ETMACVRn(j));
+			etm_write(etmdata, etmdata->state[i++],
+								ETMACTRn(j));
+		}
+		for (j = 0; j < etm.nr_data_cmp; j++) {
+			etm_write(etmdata, etmdata->state[i++],
+								ETMDCVRn(j));
+			etm_write(etmdata, etmdata->state[i++],
+								ETMDCMRn(j));
+		}
+		for (j = 0; j < etm.nr_cntr; j++) {
+			etm_write(etmdata, etmdata->state[i++],
+							ETMCNTRLDVRn(j));
+			etm_write(etmdata, etmdata->state[i++],
+							ETMCNTENRn(j));
+			etm_write(etmdata, etmdata->state[i++],
+							ETMCNTRLDEVRn(j));
+			etm_write(etmdata, etmdata->state[i++],
+							ETMCNTVRn(j));
+		}
+		etm_write(etmdata, etmdata->state[i++], ETMSQ12EVR);
+		etm_write(etmdata, etmdata->state[i++], ETMSQ21EVR);
+		etm_write(etmdata, etmdata->state[i++], ETMSQ23EVR);
+		etm_write(etmdata, etmdata->state[i++], ETMSQ31EVR);
+		etm_write(etmdata, etmdata->state[i++], ETMSQ32EVR);
+		etm_write(etmdata, etmdata->state[i++], ETMSQ13EVR);
+		etm_write(etmdata, etmdata->state[i++], ETMSQR);
+		for (j = 0; j < etm.nr_ext_out; j++)
+			etm_write(etmdata, etmdata->state[i++],
+							ETMEXTOUTEVRn(j));
+		for (j = 0; j < etm.nr_ctxid_cmp; j++)
+			etm_write(etmdata, etmdata->state[i++],
+							ETMCIDCVRn(j));
+		etm_write(etmdata, etmdata->state[i++], ETMCIDCMR);
+		etm_write(etmdata, etmdata->state[i++], ETMSYNCFR);
+		etm_write(etmdata, etmdata->state[i++], ETMEXTINSELR);
+		etm_write(etmdata, etmdata->state[i++], ETMTSEVR);
+		etm_write(etmdata, etmdata->state[i++], ETMAUXCR);
+		etm_write(etmdata, etmdata->state[i++], ETMTRACEIDR);
+		etm_write(etmdata, etmdata->state[i++], ETMVMIDCVR);
+		etm_write(etmdata, etmdata->state[i++], ETMCLAIMSET);
+		/*
+		 * Set ETMCR at last as we dont know the saved status of pwrdwn
+		 * bit
+		 */
+		etm_write(etmdata, etmdata->state[i++], ETMCR);
+		break;
+	default:
+		pr_err_ratelimited("unsupported etm arch %d in %s\n", etm.arch,
+								__func__);
+	}
+
+	ETM_LOCK(etmdata);
+}
+
+static inline void dbg_save_state(struct dbg_cpu_ctx *dbgdata)
+{
+	int i, j;
+
+	i = 0;
+	DBG_UNLOCK(dbgdata);
+
+	dbgdata->state[i++] =  dbg_read(dbgdata, DBGWFAR);
+	dbgdata->state[i++] =  dbg_read(dbgdata, DBGVCR);
+	for (j = 0; j < dbg.nr_bp; j++) {
+		dbgdata->state[i++] =  dbg_read(dbgdata, DBGBVRn(j));
+		dbgdata->state[i++] =  dbg_read(dbgdata, DBGBCRn(j));
+	}
+	for (j = 0; j < dbg.nr_wp; j++) {
+		dbgdata->state[i++] =  dbg_read(dbgdata, DBGWVRn(j));
+		dbgdata->state[i++] =  dbg_read(dbgdata, DBGWCRn(j));
+	}
+	dbgdata->state[i++] =  dbg_read(dbgdata, DBGPRCR);
+	dbgdata->state[i++] =  dbg_read(dbgdata, DBGCLAIMSET);
+	dbgdata->state[i++] =  dbg_read(dbgdata, DBGCLAIMCLR);
+	dbgdata->state[i++] =  dbg_read(dbgdata, DBGDTRTXext);
+	dbgdata->state[i++] =  dbg_read(dbgdata, DBGDTRRXext);
+	dbgdata->state[i++] =  dbg_read(dbgdata, DBGDSCRext);
+
+	DBG_LOCK(dbgdata);
+}
+
+static inline void dbg_restore_state(struct dbg_cpu_ctx *dbgdata)
+{
+	int i, j;
+
+	i = 0;
+	DBG_UNLOCK(dbgdata);
+
+	dbg_write(dbgdata, dbgdata->state[i++], DBGWFAR);
+	dbg_write(dbgdata, dbgdata->state[i++], DBGVCR);
+	for (j = 0; j < dbg.nr_bp; j++) {
+		dbg_write(dbgdata, dbgdata->state[i++], DBGBVRn(j));
+		dbg_write(dbgdata, dbgdata->state[i++], DBGBCRn(j));
+	}
+	for (j = 0; j < dbg.nr_wp; j++) {
+		dbg_write(dbgdata, dbgdata->state[i++], DBGWVRn(j));
+		dbg_write(dbgdata, dbgdata->state[i++], DBGWCRn(j));
+	}
+	dbg_write(dbgdata, dbgdata->state[i++], DBGPRCR);
+	dbg_write(dbgdata, dbgdata->state[i++], DBGCLAIMSET);
+	dbg_write(dbgdata, dbgdata->state[i++], DBGCLAIMCLR);
+	dbg_write(dbgdata, dbgdata->state[i++], DBGDTRTXext);
+	dbg_write(dbgdata, dbgdata->state[i++], DBGDTRRXext);
+	dbg_write(dbgdata, dbgdata->state[i++] & DBGDSCR_MASK,
+								DBGDSCRext);
+
+	DBG_LOCK(dbgdata);
+}
+
+void msm_jtag_save_state(void)
+{
+	int cpu;
+
+	cpu = raw_smp_processor_id();
+
+	msm_jtag_save_cntr[cpu]++;
+	/* ensure counter is updated before moving forward */
+	mb();
+
+	if (dbg.save_restore_enabled[cpu])
+		dbg_save_state(dbg.cpu_ctx[cpu]);
+	if (etm.save_restore_enabled[cpu])
+		etm_save_state(etm.cpu_ctx[cpu]);
+}
+EXPORT_SYMBOL(msm_jtag_save_state);
+
+void msm_jtag_restore_state(void)
+{
+	int cpu;
+
+	cpu = raw_smp_processor_id();
+
+	/* Attempt restore only if save has been done. If power collapse
+	 * is disabled, hotplug off of non-boot core will result in WFI
+	 * and hence msm_jtag_save_state will not occur. Subsequently,
+	 * during hotplug on of non-boot core when msm_jtag_restore_state
+	 * is called via msm_platform_secondary_init, this check will help
+	 * bail us out without restoring.
+	 */
+	if (msm_jtag_save_cntr[cpu] == msm_jtag_restore_cntr[cpu])
+		return;
+	else if (msm_jtag_save_cntr[cpu] != msm_jtag_restore_cntr[cpu] + 1)
+		pr_err_ratelimited("jtag imbalance, save:%lu, restore:%lu\n",
+				   (unsigned long)msm_jtag_save_cntr[cpu],
+				   (unsigned long)msm_jtag_restore_cntr[cpu]);
+
+	msm_jtag_restore_cntr[cpu]++;
+	/* ensure counter is updated before moving forward */
+	mb();
+
+	if (dbg.save_restore_enabled[cpu])
+		dbg_restore_state(dbg.cpu_ctx[cpu]);
+	if (etm.save_restore_enabled[cpu])
+		etm_restore_state(etm.cpu_ctx[cpu]);
+}
+EXPORT_SYMBOL(msm_jtag_restore_state);
+
+static inline bool etm_arch_supported(uint8_t arch)
+{
+	switch (arch) {
+	case ETM_ARCH_V3_5:
+		break;
+	default:
+		return false;
+	}
+	return true;
+}
+
+static void __devinit etm_init_arch_data(void *info)
+{
+	uint32_t etmidr;
+	uint32_t etmccr;
+	struct etm_cpu_ctx  *etmdata = info;
+
+	/*
+	 * Clear power down bit since when this bit is set writes to
+	 * certain registers might be ignored.
+	 */
+	ETM_UNLOCK(etmdata);
+
+	etm_clr_pwrdwn(etmdata);
+	/* Set prog bit. It will be set from reset but this is included to
+	 * ensure it is set
+	 */
+	etm_set_prog(etmdata);
+
+	/* find all capabilities */
+	etmidr = etm_read(etmdata, ETMIDR);
+	etm.arch = BMVAL(etmidr, 4, 11);
+
+	etmccr = etm_read(etmdata, ETMCCR);
+	etm.nr_addr_cmp = BMVAL(etmccr, 0, 3) * 2;
+	etm.nr_data_cmp = BMVAL(etmccr, 4, 7);
+	etm.nr_cntr = BMVAL(etmccr, 13, 15);
+	etm.nr_ext_inp = BMVAL(etmccr, 17, 19);
+	etm.nr_ext_out = BMVAL(etmccr, 20, 22);
+	etm.nr_ctxid_cmp = BMVAL(etmccr, 24, 25);
+
+	etm_set_pwrdwn(etmdata);
+
+	ETM_LOCK(etmdata);
+}
+
+static int __devinit jtag_mm_etm_probe(struct platform_device *pdev,
+								uint32_t cpu)
+{
+	struct etm_cpu_ctx *etmdata;
+	struct resource *res;
+	struct device *dev = &pdev->dev;
+
+	/* Allocate memory per cpu */
+	etmdata = devm_kzalloc(dev, sizeof(struct etm_cpu_ctx), GFP_KERNEL);
+	if (!etmdata)
+		return -ENOMEM;
+
+	etm.cpu_ctx[cpu] = etmdata;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	etmdata->base = devm_ioremap(dev, res->start, resource_size(res));
+	if (!etmdata->base)
+		return -EINVAL;
+
+	/* Allocate etm state save space per core */
+	etmdata->state = devm_kzalloc(dev,
+			(MAX_ETM_STATE_SIZE * sizeof(uint32_t)), GFP_KERNEL);
+	if (!etmdata->state)
+		return -ENOMEM;
+
+	smp_call_function_single(0, etm_init_arch_data, etmdata, 1);
+
+	if (etm_arch_supported(etm.arch)) {
+		if (scm_get_feat_version(TZ_DBG_ETM_FEAT_ID) < TZ_DBG_ETM_VER)
+			etm.save_restore_enabled[cpu] = true;
+		else
+			pr_info("etm save-restore supported by TZ\n");
+	} else
+		pr_info("etm arch %u not supported\n", etm.arch);
+	return 0;
+}
+
+static inline bool dbg_arch_supported(uint8_t arch)
+{
+	switch (arch) {
+	case ARM_DEBUG_ARCH_V7B:
+		break;
+	default:
+		return false;
+	}
+	return true;
+}
+
+static void __devinit dbg_init_arch_data(void *info)
+{
+	uint32_t dbgdidr;
+	struct dbg_cpu_ctx *dbgdata = info;
+
+	/* This will run on core0 so use it to populate parameters */
+	dbgdidr = dbg_read(dbgdata, DBGDIDR);
+	dbg.arch = BMVAL(dbgdidr, 16, 19);
+	dbg.nr_ctx_cmp = BMVAL(dbgdidr, 20, 23) + 1;
+	dbg.nr_bp = BMVAL(dbgdidr, 24, 27) + 1;
+	dbg.nr_wp = BMVAL(dbgdidr, 28, 31) + 1;
+}
+
+
+
+static int __devinit jtag_mm_dbg_probe(struct platform_device *pdev,
+								uint32_t cpu)
+{
+	struct dbg_cpu_ctx *dbgdata;
+	struct resource *res;
+	struct device *dev = &pdev->dev;
+
+	/* Allocate memory per cpu */
+	dbgdata = devm_kzalloc(dev, sizeof(struct dbg_cpu_ctx), GFP_KERNEL);
+	if (!dbgdata)
+		return -ENOMEM;
+
+	dbg.cpu_ctx[cpu] = dbgdata;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+
+	dbgdata->base = devm_ioremap(dev, res->start, resource_size(res));
+	if (!dbgdata->base)
+		return -EINVAL;
+
+	/* Allocate etm state save space per core */
+	dbgdata->state = devm_kzalloc(dev,
+			(MAX_DBG_STATE_SIZE * sizeof(uint32_t)), GFP_KERNEL);
+	if (!dbgdata->state)
+		return -ENOMEM;
+
+	smp_call_function_single(0, dbg_init_arch_data, dbgdata, 1);
+
+	if (dbg_arch_supported(dbg.arch)) {
+		if (scm_get_feat_version(TZ_DBG_ETM_FEAT_ID) < TZ_DBG_ETM_VER)
+			dbg.save_restore_enabled[cpu] = true;
+		else
+			pr_info("dbg save-restore supported by TZ\n");
+	} else
+		pr_info("dbg arch %u not supported\n", dbg.arch);
+	return 0;
+}
+
+static int __devinit jtag_mm_probe(struct platform_device *pdev)
+{
+	int etm_ret, dbg_ret, ret;
+	static uint32_t cpu;
+	static uint32_t count;
+	struct device *dev = &pdev->dev;
+
+	cpu = count;
+	count++;
+
+	clock[cpu] = devm_clk_get(dev, "core_clk");
+	if (IS_ERR(clock[cpu])) {
+		ret = PTR_ERR(clock[cpu]);
+		return ret;
+	}
+
+	ret = clk_set_rate(clock[cpu], CORESIGHT_CLK_RATE_TRACE);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(clock[cpu]);
+	if (ret)
+		return ret;
+
+	platform_set_drvdata(pdev, clock[cpu]);
+
+	etm_ret  = jtag_mm_etm_probe(pdev, cpu);
+
+	dbg_ret = jtag_mm_dbg_probe(pdev, cpu);
+
+	/* The probe succeeds even when only one of the etm and dbg probes
+	 * succeeds. This allows us to save-restore etm and dbg registers
+	 * independently.
+	 */
+	if (etm_ret && dbg_ret) {
+		clk_disable_unprepare(clock[cpu]);
+		ret = etm_ret;
+	} else
+		ret = 0;
+	return ret;
+}
+
+static int __devexit jtag_mm_remove(struct platform_device *pdev)
+{
+	struct clk *clock = platform_get_drvdata(pdev);
+
+	clk_disable_unprepare(clock);
+	return 0;
+}
+
+static struct of_device_id msm_qdss_mm_match[] = {
+	{ .compatible = "qcom,jtag-mm"},
+	{}
+};
+
+static struct platform_driver jtag_mm_driver = {
+	.probe          = jtag_mm_probe,
+	.remove         = __devexit_p(jtag_mm_remove),
+	.driver         = {
+		.name   = "msm-jtag-mm",
+		.owner	= THIS_MODULE,
+		.of_match_table	= msm_qdss_mm_match,
+		},
+};
+
+static int __init jtag_mm_init(void)
+{
+	return platform_driver_register(&jtag_mm_driver);
+}
+module_init(jtag_mm_init);
+
+static void __exit jtag_mm_exit(void)
+{
+	platform_driver_unregister(&jtag_mm_driver);
+}
+module_exit(jtag_mm_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Coresight debug and ETM save-restore driver");
diff --git a/arch/arm/mach-msm/kernel_test_service_v01.c b/arch/arm/mach-msm/kernel_test_service_v01.c
new file mode 100644
index 0000000..498e046
--- /dev/null
+++ b/arch/arm/mach-msm/kernel_test_service_v01.c
@@ -0,0 +1,254 @@
+/* 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/qmi_encdec.h>
+
+#include <mach/msm_qmi_interface.h>
+
+#include "kernel_test_service_v01.h"
+
+#define PING_REQ1_TLV_TYPE 0x1
+#define PING_RESP1_TLV_TYPE 0x2
+#define PING_OPT1_TLV_TYPE 0x10
+#define PING_OPT2_TLV_TYPE 0x11
+
+#define DATA_REQ1_TLV_TYPE 0x1
+#define DATA_RESP1_TLV_TYPE 0x2
+#define DATA_OPT1_TLV_TYPE 0x10
+#define DATA_OPT2_TLV_TYPE 0x11
+
+static struct elem_info test_name_type_v01_ei[] = {
+	{
+		.data_type      = QMI_DATA_LEN,
+		.elem_len	= 1,
+		.elem_size      = sizeof(uint8_t),
+		.is_array	= NO_ARRAY,
+		.tlv_type	= QMI_COMMON_TLV_TYPE,
+		.offset		= offsetof(struct test_name_type_v01,
+					   name_len),
+	},
+	{
+		.data_type      = QMI_UNSIGNED_1_BYTE,
+		.elem_len       = TEST_MAX_NAME_SIZE_V01,
+		.elem_size      = sizeof(char),
+		.is_array       = VAR_LEN_ARRAY,
+		.tlv_type       = QMI_COMMON_TLV_TYPE,
+		.offset         = offsetof(struct test_name_type_v01,
+					   name),
+	},
+	{
+		.data_type      = QMI_EOTI,
+		.is_array       = NO_ARRAY,
+		.tlv_type       = QMI_COMMON_TLV_TYPE,
+	},
+};
+
+struct elem_info test_ping_req_msg_v01_ei[] = {
+	{
+		.data_type      = QMI_UNSIGNED_1_BYTE,
+		.elem_len       = 4,
+		.elem_size      = sizeof(char),
+		.is_array       = STATIC_ARRAY,
+		.tlv_type       = PING_REQ1_TLV_TYPE,
+		.offset         = offsetof(struct test_ping_req_msg_v01,
+					   ping),
+	},
+	{
+		.data_type      = QMI_OPT_FLAG,
+		.elem_len       = 1,
+		.elem_size      = sizeof(uint8_t),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = PING_OPT1_TLV_TYPE,
+		.offset         = offsetof(struct test_ping_req_msg_v01,
+					   client_name_valid),
+	},
+	{
+		.data_type      = QMI_STRUCT,
+		.elem_len       = 1,
+		.elem_size      = sizeof(struct test_name_type_v01),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = PING_OPT1_TLV_TYPE,
+		.offset         = offsetof(struct test_ping_req_msg_v01,
+					   client_name),
+		.ei_array       = test_name_type_v01_ei,
+	},
+	{
+		.data_type      = QMI_EOTI,
+		.is_array       = NO_ARRAY,
+		.tlv_type       = QMI_COMMON_TLV_TYPE,
+	},
+};
+
+struct elem_info test_ping_resp_msg_v01_ei[] = {
+	{
+		.data_type      = QMI_STRUCT,
+		.elem_len       = 1,
+		.elem_size      = sizeof(struct qmi_response_type_v01),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = PING_RESP1_TLV_TYPE,
+		.offset         = offsetof(struct test_ping_resp_msg_v01,
+					   resp),
+		.ei_array       = get_qmi_response_type_v01_ei(),
+	},
+	{
+		.data_type      = QMI_OPT_FLAG,
+		.elem_len       = 1,
+		.elem_size      = sizeof(uint8_t),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = PING_OPT1_TLV_TYPE,
+		.offset         = offsetof(struct test_ping_resp_msg_v01,
+					   pong_valid),
+	},
+	{
+		.data_type      = QMI_UNSIGNED_1_BYTE,
+		.elem_len       = 4,
+		.elem_size      = sizeof(char),
+		.is_array       = STATIC_ARRAY,
+		.tlv_type       = PING_OPT1_TLV_TYPE,
+		.offset         = offsetof(struct test_ping_resp_msg_v01,
+					   pong),
+	},
+	{
+		.data_type      = QMI_OPT_FLAG,
+		.elem_len       = 1,
+		.elem_size      = sizeof(uint8_t),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = PING_OPT2_TLV_TYPE,
+		.offset         = offsetof(struct test_ping_resp_msg_v01,
+					   service_name_valid),
+	},
+	{
+		.data_type      = QMI_STRUCT,
+		.elem_len       = 1,
+		.elem_size      = sizeof(struct test_name_type_v01),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = PING_OPT2_TLV_TYPE,
+		.offset         = offsetof(struct test_ping_resp_msg_v01,
+					   service_name),
+		.ei_array       = test_name_type_v01_ei,
+	},
+	{
+		.data_type      = QMI_EOTI,
+		.is_array       = NO_ARRAY,
+		.tlv_type       = QMI_COMMON_TLV_TYPE,
+	},
+};
+
+struct elem_info test_data_req_msg_v01_ei[] = {
+	{
+		.data_type      = QMI_DATA_LEN,
+		.elem_len       = 1,
+		.elem_size      = sizeof(uint32_t),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = DATA_REQ1_TLV_TYPE,
+		.offset         = offsetof(struct test_data_req_msg_v01,
+					   data_len),
+	},
+	{
+		.data_type      = QMI_UNSIGNED_1_BYTE,
+		.elem_len       = TEST_MED_DATA_SIZE_V01,
+		.elem_size      = sizeof(uint8_t),
+		.is_array       = VAR_LEN_ARRAY,
+		.tlv_type       = DATA_REQ1_TLV_TYPE,
+		.offset         = offsetof(struct test_data_req_msg_v01,
+					   data),
+	},
+	{
+		.data_type      = QMI_OPT_FLAG,
+		.elem_len       = 1,
+		.elem_size      = sizeof(uint8_t),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = DATA_OPT1_TLV_TYPE,
+		.offset         = offsetof(struct test_data_req_msg_v01,
+					   client_name_valid),
+	},
+	{
+		.data_type      = QMI_STRUCT,
+		.elem_len       = 1,
+		.elem_size      = sizeof(struct test_name_type_v01),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = DATA_OPT1_TLV_TYPE,
+		.offset         = offsetof(struct test_data_req_msg_v01,
+					   client_name),
+		.ei_array       = test_name_type_v01_ei,
+	},
+	{
+		.data_type      = QMI_EOTI,
+		.is_array       = NO_ARRAY,
+		.tlv_type       = QMI_COMMON_TLV_TYPE,
+	},
+};
+
+struct elem_info test_data_resp_msg_v01_ei[] = {
+	{
+		.data_type      = QMI_STRUCT,
+		.elem_len       = 1,
+		.elem_size      = sizeof(struct qmi_response_type_v01),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = DATA_RESP1_TLV_TYPE,
+		.offset         = offsetof(struct test_data_resp_msg_v01,
+					   resp),
+		.ei_array       = get_qmi_response_type_v01_ei(),
+	},
+	{
+		.data_type      = QMI_OPT_FLAG,
+		.elem_len       = 1,
+		.elem_size      = sizeof(uint8_t),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = DATA_OPT1_TLV_TYPE,
+		.offset         = offsetof(struct test_data_resp_msg_v01,
+					   data_valid),
+	},
+	{
+		.data_type      = QMI_DATA_LEN,
+		.elem_len       = 1,
+		.elem_size      = sizeof(uint32_t),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = DATA_OPT1_TLV_TYPE,
+		.offset         = offsetof(struct test_data_resp_msg_v01,
+					   data_len),
+	},
+	{
+		.data_type      = QMI_UNSIGNED_1_BYTE,
+		.elem_len       = TEST_MED_DATA_SIZE_V01,
+		.elem_size      = sizeof(uint8_t),
+		.is_array       = VAR_LEN_ARRAY,
+		.tlv_type       = DATA_OPT1_TLV_TYPE,
+		.offset         = offsetof(struct test_data_resp_msg_v01,
+					   data),
+	},
+	{
+		.data_type      = QMI_OPT_FLAG,
+		.elem_len       = 1,
+		.elem_size      = sizeof(uint8_t),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = DATA_OPT2_TLV_TYPE,
+		.offset         = offsetof(struct test_data_resp_msg_v01,
+					   service_name_valid),
+	},
+	{
+		.data_type      = QMI_STRUCT,
+		.elem_len       = 1,
+		.elem_size      = sizeof(struct test_name_type_v01),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = DATA_OPT2_TLV_TYPE,
+		.offset         = offsetof(struct test_data_resp_msg_v01,
+					   service_name),
+		.ei_array       = test_name_type_v01_ei,
+	},
+	{
+		.data_type      = QMI_EOTI,
+		.is_array       = NO_ARRAY,
+		.tlv_type       = QMI_COMMON_TLV_TYPE,
+	},
+};
diff --git a/arch/arm/mach-msm/kernel_test_service_v01.h b/arch/arm/mach-msm/kernel_test_service_v01.h
new file mode 100644
index 0000000..79c1845
--- /dev/null
+++ b/arch/arm/mach-msm/kernel_test_service_v01.h
@@ -0,0 +1,73 @@
+/* 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 MSM_QMI_TEST_SERVICE_V01_H
+#define MSM_QMI_TEST_SERVICE_V01_H
+
+#include <mach/msm_qmi_interface.h>
+
+#define TEST_MED_DATA_SIZE_V01 8192
+#define TEST_MAX_NAME_SIZE_V01 255
+
+#define TEST_PING_REQ_MSG_ID_V01 0x20
+#define TEST_DATA_REQ_MSG_ID_V01 0x21
+
+#define TEST_PING_REQ_MAX_MSG_LEN_V01 266
+#define TEST_DATA_REQ_MAX_MSG_LEN_V01 8456
+
+struct test_name_type_v01 {
+	uint32_t name_len;
+	char name[TEST_MAX_NAME_SIZE_V01];
+};
+
+struct test_ping_req_msg_v01 {
+	char ping[4];
+
+	uint8_t client_name_valid;
+	struct test_name_type_v01 client_name;
+};
+
+struct test_ping_resp_msg_v01 {
+	struct qmi_response_type_v01 resp;
+
+	uint8_t pong_valid;
+	char pong[4];
+
+	uint8_t service_name_valid;
+	struct test_name_type_v01 service_name;
+};
+
+struct test_data_req_msg_v01 {
+	uint32_t data_len;
+	uint8_t data[TEST_MED_DATA_SIZE_V01];
+
+	uint8_t client_name_valid;
+	struct test_name_type_v01 client_name;
+};
+
+struct test_data_resp_msg_v01 {
+	struct qmi_response_type_v01 resp;
+
+	uint8_t data_valid;
+	uint32_t data_len;
+	uint8_t data[TEST_MED_DATA_SIZE_V01];
+
+	uint8_t service_name_valid;
+	struct test_name_type_v01 service_name;
+};
+
+extern struct elem_info test_ping_req_msg_v01_ei[];
+extern struct elem_info test_data_req_msg_v01_ei[];
+extern struct elem_info test_ping_resp_msg_v01_ei[];
+extern struct elem_info test_data_resp_msg_v01_ei[];
+
+#endif
diff --git a/arch/arm/mach-msm/keypad-surf-ffa.c b/arch/arm/mach-msm/keypad-surf-ffa.c
index 711cdbb..5d7763f 100644
--- a/arch/arm/mach-msm/keypad-surf-ffa.c
+++ b/arch/arm/mach-msm/keypad-surf-ffa.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/krait-regulator.c b/arch/arm/mach-msm/krait-regulator.c
index f7b2b1e..dc0b755 100644
--- a/arch/arm/mach-msm/krait-regulator.c
+++ b/arch/arm/mach-msm/krait-regulator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -10,7 +10,7 @@
  * GNU General Public License for more details.
  */
 
-#define pr_fmt(fmt) "%s: " fmt, __func__
+#define pr_fmt(fmt) "PDN %s: " fmt, __func__
 
 #include <linux/err.h>
 #include <linux/kernel.h>
@@ -27,28 +27,28 @@
 #include <linux/regulator/machine.h>
 #include <linux/regulator/of_regulator.h>
 #include <linux/regulator/krait-regulator.h>
+#include <linux/debugfs.h>
 #include <mach/msm_iomap.h>
 
 #include "spm.h"
+#include "pm.h"
 
 /*
  *                   supply
  *                   from
  *                   pmic
  *                   gang
- *                    |        LDO BYP [6]
- *                    |         /
- *                    |        /
- *                    |_______/   _____
- *                    |                |
- *                 ___|___             |
- *		  |       |            |
- *		  |       |               /
- *		  |  LDO  |              /
- *		  |       |             /    BHS[6]
- *                |_______|            |
- *                    |                |
- *                    |________________|
+ *                    |
+ *                    |________________________________
+ *                    |                |               |
+ *                 ___|___             |               |
+ *		  |       |            |               |
+ *		  |       |               /               /
+ *		  |  LDO  |              /               /LDO BYP [6]
+ *		  |       |             /    BHS[6]     /(bypass is a weak BHS
+ *                |_______|            |               |  needs to be on when in
+ *                    |                |               |  BHS mode)
+ *                    |________________|_______________|
  *                    |
  *            ________|________
  *           |                 |
@@ -70,6 +70,7 @@
 
 #define BHS_SETTLING_DELAY_US		1
 #define LDO_SETTLING_DELAY_US		1
+#define MDD_SETTLING_DELAY_US		5
 
 #define _KRAIT_MASK(BITS, POS)  (((u32)(1 << (BITS)) - 1) << POS)
 #define KRAIT_MASK(LEFT_BIT_POS, RIGHT_BIT_POS) \
@@ -88,6 +89,10 @@
 #define PWR_GATE_CONFIG		0x00000044
 #define VERSION			0x00000FD0
 
+/* MDD register group */
+#define MDD_CONFIG_CTL		0x00000000
+#define MDD_MODE		0x00000010
+
 /* bit definitions for APC_PWR_GATE_CTL */
 #define BHS_CNT_BIT_POS		24
 #define BHS_CNT_MASK		KRAIT_MASK(31, 24)
@@ -117,6 +122,18 @@
 #define VREF_LDO_BIT_POS	0
 #define VREF_LDO_MASK		KRAIT_MASK(6, 0)
 
+#define LDO_HDROOM_MIN		50000
+#define LDO_HDROOM_MAX		250000
+
+#define LDO_UV_MIN		465000
+#define LDO_UV_MAX		750000
+
+#define LDO_TH_MIN		600000
+#define LDO_TH_MAX		900000
+
+#define LDO_DELTA_MIN		10000
+#define LDO_DELTA_MAX		100000
+
 /**
  * struct pmic_gang_vreg -
  * @name:			the string used to represent the gang
@@ -136,6 +153,9 @@
 	struct list_head	krait_power_vregs;
 	struct mutex		krait_power_vregs_lock;
 	bool			pfm_mode;
+	int			pmic_min_uV_for_retention;
+	bool			retention_enabled;
+	bool			use_phase_switching;
 };
 
 static struct pmic_gang_vreg *the_gang;
@@ -155,15 +175,29 @@
 	int				load_uA;
 	enum krait_supply_mode		mode;
 	void __iomem			*reg_base;
+	void __iomem			*mdd_base;
 	int				ldo_default_uV;
 	int				retention_uV;
 	int				headroom_uV;
 	int				ldo_threshold_uV;
+	int				ldo_delta_uV;
+	int				cpu_num;
 	bool				online;
 };
 
+DEFINE_PER_CPU(struct krait_power_vreg *, krait_vregs);
+
 static u32 version;
 
+static int is_between(int left, int right, int value)
+{
+	if (left >= right && left >= value && value >= right)
+		return 1;
+	if (left <= right && left <= value && value <= right)
+		return 1;
+	return 0;
+}
+
 static void krait_masked_write(struct krait_power_vreg *kvreg,
 					int reg, uint32_t mask, uint32_t val)
 {
@@ -182,6 +216,23 @@
 	mb();
 }
 
+static int get_krait_retention_ldo_uv(struct krait_power_vreg *kvreg)
+{
+	uint32_t reg_val;
+	int uV;
+
+	reg_val = readl_relaxed(kvreg->reg_base + APC_LDO_VREF_SET);
+	reg_val &= VREF_RET_MASK;
+	reg_val >>= VREF_RET_POS;
+
+	if (reg_val == 0)
+		uV = 0;
+	else
+		uV = KRAIT_LDO_VOLTAGE_OFFSET + reg_val * KRAIT_LDO_STEP;
+
+	return uV;
+}
+
 static int get_krait_ldo_uv(struct krait_power_vreg *kvreg)
 {
 	uint32_t reg_val;
@@ -221,19 +272,56 @@
 	return 0;
 }
 
+static int __krait_power_mdd_enable(struct krait_power_vreg *kvreg, bool on)
+{
+	if (on) {
+		writel_relaxed(0x00000002, kvreg->mdd_base + MDD_MODE);
+		/* complete the above write before the delay */
+		mb();
+		udelay(MDD_SETTLING_DELAY_US);
+	} else {
+		writel_relaxed(0x00000000, kvreg->mdd_base + MDD_MODE);
+		/*
+		 * complete the above write before other accesses
+		 * to krait regulator
+		 */
+		mb();
+	}
+	return 0;
+}
+
+int krait_power_mdd_enable(int cpu_num, bool on)
+{
+	/*
+	 * Expected to be called when the cpu goes to retention mode as a part
+	 * of idle power collapse. IT is guaranteed that cpu won't be put in
+	 * retention while being hotplugged out
+	 */
+	struct krait_power_vreg *kvreg = per_cpu(krait_vregs, cpu_num);
+
+	if (!on && kvreg->mode == LDO_MODE) {
+		pr_debug("%s using LDO - cannot turn off MDD\n", kvreg->name);
+		return -EINVAL;
+	}
+
+	if (on && kvreg->mode == LDO_MODE)
+		return 0;
+
+	__krait_power_mdd_enable(kvreg, on);
+	return 0;
+}
+
 static int switch_to_using_hs(struct krait_power_vreg *kvreg)
 {
 	if (kvreg->mode == HS_MODE)
 		return 0;
-
-	/*
-	 * enable ldo bypass - the krait is powered still by LDO since
-	 * LDO is enabled and BHS is disabled
-	 */
-	krait_masked_write(kvreg, APC_PWR_GATE_CTL, LDO_BYP_MASK, LDO_BYP_MASK);
-
 	/* enable bhs */
-	krait_masked_write(kvreg, APC_PWR_GATE_CTL, BHS_EN_MASK, BHS_EN_MASK);
+	krait_masked_write(kvreg, APC_PWR_GATE_CTL,
+		BHS_SEG_EN_MASK | BHS_EN_MASK,
+		BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS | BHS_EN_MASK);
+
+	/* complete the above write before the delay */
+	mb();
 
 	/*
 	 * wait for the bhs to settle - note that
@@ -242,17 +330,27 @@
 	 */
 	udelay(BHS_SETTLING_DELAY_US);
 
+	/*
+	 * enable ldo bypass - the krait is powered still by LDO since
+	 * LDO is enabled
+	 */
+	krait_masked_write(kvreg, APC_PWR_GATE_CTL, LDO_BYP_MASK, LDO_BYP_MASK);
+
 	/* disable ldo - only the BHS provides voltage to the cpu after this */
 	krait_masked_write(kvreg, APC_PWR_GATE_CTL,
 				LDO_PWR_DWN_MASK, LDO_PWR_DWN_MASK);
 
+	/* turn off MDD since LDO is not used */
+	__krait_power_mdd_enable(kvreg, false);
 	kvreg->mode = HS_MODE;
+	pr_debug("%s using BHS\n", kvreg->name);
 	return 0;
 }
 
 static int switch_to_using_ldo(struct krait_power_vreg *kvreg)
 {
-	if (kvreg->mode == LDO_MODE && get_krait_ldo_uv(kvreg) == kvreg->uV)
+	if (kvreg->mode == LDO_MODE
+		&& get_krait_ldo_uv(kvreg) == kvreg->uV - kvreg->ldo_delta_uV)
 		return 0;
 
 	/*
@@ -262,7 +360,10 @@
 	if (kvreg->mode == LDO_MODE)
 		switch_to_using_hs(kvreg);
 
-	set_krait_ldo_uv(kvreg, kvreg->uV);
+	/* turn on MDD since LDO is being turned on */
+	__krait_power_mdd_enable(kvreg, true);
+
+	set_krait_ldo_uv(kvreg, kvreg->uV - kvreg->ldo_delta_uV);
 
 	/*
 	 * enable ldo - note that both LDO and BHS are are supplying voltage to
@@ -271,6 +372,9 @@
 	 */
 	krait_masked_write(kvreg, APC_PWR_GATE_CTL, LDO_PWR_DWN_MASK, 0);
 
+	/* complete the writes before the delay */
+	mb();
+
 	/* wait for the ldo to settle */
 	udelay(LDO_SETTLING_DELAY_US);
 
@@ -280,23 +384,35 @@
 	 */
 	krait_masked_write(kvreg, APC_PWR_GATE_CTL,
 		BHS_EN_MASK | LDO_BYP_MASK, 0);
+	krait_masked_write(kvreg, APC_PWR_GATE_CTL, BHS_SEG_EN_MASK, 0);
 
 	kvreg->mode = LDO_MODE;
+	pr_debug("%s using LDO\n", kvreg->name);
 	return 0;
 }
 
-static int set_pmic_gang_phases(int phase_count)
+static int set_pmic_gang_phases(struct pmic_gang_vreg *pvreg, int phase_count)
 {
-	/*
-	 * TODO : spm writes for phase control,
-	 * pmic phase control is not working yet
-	 */
-	return 0;
+	pr_debug("programming phase_count = %d\n", phase_count);
+	if (pvreg->use_phase_switching)
+		/*
+		 * note the PMIC sets the phase count to one more than
+		 * the value in the register - hence subtract 1 from it
+		 */
+		return msm_spm_apcs_set_phase(phase_count - 1);
+	else
+		return 0;
 }
 
-static int set_pmic_gang_voltage(int uV)
+static int set_pmic_gang_voltage(struct pmic_gang_vreg *pvreg, int uV)
 {
 	int setpoint;
+	int rc;
+
+	if (pvreg->pmic_vmax_uV == uV)
+		return 0;
+
+	pr_debug("%d\n", uV);
 
 	if (uV < PMIC_VOLTAGE_MIN) {
 		pr_err("requested %d < %d, restricting it to %d\n",
@@ -309,12 +425,35 @@
 		uV = PMIC_VOLTAGE_MAX;
 	}
 
+	if (uV < pvreg->pmic_min_uV_for_retention) {
+		if (pvreg->retention_enabled) {
+			pr_debug("Disabling Retention pmic = %duV, pmic_min_uV_for_retention = %duV",
+					uV, pvreg->pmic_min_uV_for_retention);
+			msm_pm_enable_retention(false);
+			pvreg->retention_enabled = false;
+		}
+	} else {
+		if (!pvreg->retention_enabled) {
+			pr_debug("Enabling Retention pmic = %duV, pmic_min_uV_for_retention = %duV",
+					uV, pvreg->pmic_min_uV_for_retention);
+			msm_pm_enable_retention(true);
+			pvreg->retention_enabled = true;
+		}
+	}
+
 	setpoint = DIV_ROUND_UP(uV, LV_RANGE_STEP);
 
-	return msm_spm_apcs_set_vdd(setpoint);
+	rc = msm_spm_apcs_set_vdd(setpoint);
+	if (rc < 0)
+		pr_err("could not set %duV setpt = 0x%x rc = %d\n",
+				uV, setpoint, rc);
+	else
+		pvreg->pmic_vmax_uV = uV;
+
+	return rc;
 }
 
-static int configure_ldo_or_hs(struct krait_power_vreg *from, int vmax)
+static int configure_ldo_or_hs_all(struct krait_power_vreg *from, int vmax)
 {
 	struct pmic_gang_vreg *pvreg = from->pvreg;
 	struct krait_power_vreg *kvreg;
@@ -323,18 +462,19 @@
 	list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
 		if (!kvreg->online)
 			continue;
-		if (kvreg->uV > kvreg->ldo_threshold_uV
-			 || kvreg->uV > vmax - kvreg->headroom_uV) {
-			rc = switch_to_using_hs(kvreg);
+		if (kvreg->uV <= kvreg->ldo_threshold_uV
+			&& kvreg->uV - kvreg->ldo_delta_uV + kvreg->headroom_uV
+				<= vmax) {
+			rc = switch_to_using_ldo(kvreg);
 			if (rc < 0) {
-				pr_err("could not switch %s to hs rc = %d\n",
+				pr_err("could not switch %s to ldo rc = %d\n",
 							kvreg->name, rc);
 				return rc;
 			}
 		} else {
-			rc = switch_to_using_ldo(kvreg);
+			rc = switch_to_using_hs(kvreg);
 			if (rc < 0) {
-				pr_err("could not switch %s to ldo rc = %d\n",
+				pr_err("could not switch %s to hs rc = %d\n",
 							kvreg->name, rc);
 				return rc;
 			}
@@ -345,7 +485,7 @@
 }
 
 #define SLEW_RATE 2994
-static int pmic_gang_set_voltage_increase(struct krait_power_vreg *from,
+static int krait_voltage_increase(struct krait_power_vreg *from,
 							int vmax)
 {
 	struct pmic_gang_vreg *pvreg = from->pvreg;
@@ -353,20 +493,25 @@
 	int settling_us;
 
 	/*
-	 * since pmic gang voltage is increasing set the gang voltage
+	 * since krait voltage is increasing set the gang voltage
 	 * prior to changing ldo/hs states of the requesting krait
 	 */
-	rc = set_pmic_gang_voltage(vmax);
+	rc = set_pmic_gang_voltage(pvreg, vmax);
 	if (rc < 0) {
 		dev_err(&from->rdev->dev, "%s failed set voltage %d rc = %d\n",
 				pvreg->name, vmax, rc);
+		return rc;
 	}
 
+
+	/* complete the above writes before the delay */
+	mb();
+
 	/* delay until the voltage is settled when it is raised */
 	settling_us = DIV_ROUND_UP(vmax - pvreg->pmic_vmax_uV, SLEW_RATE);
 	udelay(settling_us);
 
-	rc = configure_ldo_or_hs(from, vmax);
+	rc = configure_ldo_or_hs_all(from, vmax);
 	if (rc < 0) {
 		dev_err(&from->rdev->dev, "%s failed ldo/hs conf %d rc = %d\n",
 				pvreg->name, vmax, rc);
@@ -375,25 +520,25 @@
 	return rc;
 }
 
-static int pmic_gang_set_voltage_decrease(struct krait_power_vreg *from,
+static int krait_voltage_decrease(struct krait_power_vreg *from,
 							int vmax)
 {
 	struct pmic_gang_vreg *pvreg = from->pvreg;
 	int rc = 0;
 
 	/*
-	 * since pmic gang voltage is decreasing ldos might get out of their
+	 * since krait voltage is decreasing ldos might get out of their
 	 * operating range. Hence configure such kraits to be in hs mode prior
 	 * to setting the pmic gang voltage
 	 */
-	rc = configure_ldo_or_hs(from, vmax);
+	rc = configure_ldo_or_hs_all(from, vmax);
 	if (rc < 0) {
 		dev_err(&from->rdev->dev, "%s failed ldo/hs conf %d rc = %d\n",
 				pvreg->name, vmax, rc);
 		return rc;
 	}
 
-	rc = set_pmic_gang_voltage(vmax);
+	rc = set_pmic_gang_voltage(pvreg, vmax);
 	if (rc < 0) {
 		dev_err(&from->rdev->dev, "%s failed set voltage %d rc = %d\n",
 				pvreg->name, vmax, rc);
@@ -402,32 +547,24 @@
 	return rc;
 }
 
-static int pmic_gang_set_voltage(struct krait_power_vreg *from,
-				 int vmax)
-{
-	struct pmic_gang_vreg *pvreg = from->pvreg;
-
-	if (pvreg->pmic_vmax_uV == vmax)
-		return 0;
-	else if (vmax < pvreg->pmic_vmax_uV)
-		return pmic_gang_set_voltage_decrease(from, vmax);
-
-	return pmic_gang_set_voltage_increase(from, vmax);
-}
-
 #define PHASE_SETTLING_TIME_US		10
 static unsigned int pmic_gang_set_phases(struct krait_power_vreg *from,
 				int load_uA)
 {
 	struct pmic_gang_vreg *pvreg = from->pvreg;
-	int phase_count = DIV_ROUND_UP(load_uA, LOAD_PER_PHASE) - 1;
+	int phase_count = DIV_ROUND_UP(load_uA, LOAD_PER_PHASE);
 	int rc = 0;
 
-	if (phase_count < 0)
-		phase_count = 0;
+	if (phase_count <= 0)
+		phase_count = 1;
+
+	 /* Increase phases if it is less than the number of cpus online */
+	if (phase_count < num_online_cpus()) {
+		phase_count = num_online_cpus();
+	}
 
 	if (phase_count != pvreg->pmic_phase_count) {
-		rc = set_pmic_gang_phases(phase_count);
+		rc = set_pmic_gang_phases(pvreg, phase_count);
 		if (rc < 0) {
 			dev_err(&from->rdev->dev,
 				"%s failed set phase %d rc = %d\n",
@@ -435,6 +572,9 @@
 			return rc;
 		}
 
+		/* complete the writes before the delay */
+		mb();
+
 		/*
 		 * delay until the phases are settled when
 		 * the count is raised
@@ -447,30 +587,6 @@
 	return rc;
 }
 
-static int __devinit pvreg_init(struct platform_device *pdev)
-{
-	struct pmic_gang_vreg *pvreg;
-
-	pvreg = devm_kzalloc(&pdev->dev,
-			sizeof(struct pmic_gang_vreg), GFP_KERNEL);
-	if (!pvreg) {
-		pr_err("kzalloc failed.\n");
-		return -ENOMEM;
-	}
-
-	pvreg->name = "pmic_gang";
-	pvreg->pmic_vmax_uV = PMIC_VOLTAGE_MIN;
-	pvreg->pmic_phase_count = 1;
-
-	mutex_init(&pvreg->krait_power_vregs_lock);
-	INIT_LIST_HEAD(&pvreg->krait_power_vregs);
-	the_gang = pvreg;
-
-	pr_debug("name=%s inited\n", pvreg->name);
-
-	return 0;
-}
-
 static int krait_power_get_voltage(struct regulator_dev *rdev)
 {
 	struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
@@ -478,12 +594,11 @@
 	return kvreg->uV;
 }
 
-static int get_vmax(struct krait_power_vreg *from, int min_uV)
+static int get_vmax(struct pmic_gang_vreg *pvreg)
 {
 	int vmax = 0;
 	int v;
 	struct krait_power_vreg *kvreg;
-	struct pmic_gang_vreg *pvreg = from->pvreg;
 
 	list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
 		if (!kvreg->online)
@@ -491,9 +606,6 @@
 
 		v = kvreg->uV;
 
-		if (kvreg == from)
-			v = min_uV;
-
 		if (vmax < v)
 			vmax = v;
 	}
@@ -518,28 +630,35 @@
 
 #define ROUND_UP_VOLTAGE(v, res) (DIV_ROUND_UP(v, res) * res)
 static int _set_voltage(struct regulator_dev *rdev,
-			int min_uV, int max_uV, unsigned *selector)
+			int orig_krait_uV, int requested_uV)
 {
 	struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
 	struct pmic_gang_vreg *pvreg = kvreg->pvreg;
 	int rc;
 	int vmax;
 
-	vmax = get_vmax(kvreg, min_uV);
+	pr_debug("%s: %d to %d\n", kvreg->name, orig_krait_uV, requested_uV);
+	/*
+	 * Assign the voltage before updating the gang voltage as we iterate
+	 * over all the core voltages and choose HS or LDO for each of them
+	 */
+	kvreg->uV = requested_uV;
+
+	vmax = get_vmax(pvreg);
 
 	/* round up the pmic voltage as per its resolution */
 	vmax = ROUND_UP_VOLTAGE(vmax, LV_RANGE_STEP);
 
-	rc = pmic_gang_set_voltage(kvreg, vmax);
+	if (requested_uV > orig_krait_uV)
+		rc = krait_voltage_increase(kvreg, vmax);
+	else
+		rc = krait_voltage_decrease(kvreg, vmax);
+
 	if (rc < 0) {
-		dev_err(&rdev->dev, "%s failed set voltage (%d, %d) rc = %d\n",
-				kvreg->name, min_uV, max_uV, rc);
-		goto out;
+		dev_err(&rdev->dev, "%s failed to set %duV from %duV rc = %d\n",
+				kvreg->name, requested_uV, orig_krait_uV, rc);
 	}
 
-	pvreg->pmic_vmax_uV = vmax;
-
-out:
 	return rc;
 }
 
@@ -562,14 +681,13 @@
 	}
 
 	mutex_lock(&pvreg->krait_power_vregs_lock);
-	kvreg->uV = min_uV;
-
 	if (!kvreg->online) {
+		kvreg->uV = min_uV;
 		mutex_unlock(&pvreg->krait_power_vregs_lock);
 		return 0;
 	}
 
-	rc = _set_voltage(rdev, min_uV, max_uV, selector);
+	rc = _set_voltage(rdev, kvreg->uV, min_uV);
 	mutex_unlock(&pvreg->krait_power_vregs_lock);
 
 	return rc;
@@ -672,13 +790,17 @@
 	int rc;
 
 	mutex_lock(&pvreg->krait_power_vregs_lock);
+	if (kvreg->mode == LDO_MODE)
+		__krait_power_mdd_enable(kvreg, true);
 	kvreg->online = true;
-	rc = _get_optimum_mode(rdev, kvreg->uV, kvreg->uV,
-							kvreg->load_uA);
+	rc = _get_optimum_mode(rdev, kvreg->uV, kvreg->uV, kvreg->load_uA);
 	if (rc < 0)
 		goto en_err;
-	rc = _set_voltage(rdev, kvreg->uV,
-					rdev->constraints->max_uV, NULL);
+	/*
+	 * since the core is being enabled, behave as if it is increasing
+	 * the core voltage
+	 */
+	rc = _set_voltage(rdev, 0, kvreg->uV);
 en_err:
 	mutex_unlock(&pvreg->krait_power_vregs_lock);
 	return rc;
@@ -698,8 +820,9 @@
 	if (rc < 0)
 		goto dis_err;
 
-	rc = _set_voltage(rdev, kvreg->uV,
-					rdev->constraints->max_uV, NULL);
+	rc = _set_voltage(rdev, kvreg->uV, kvreg->uV);
+	if (kvreg->mode == LDO_MODE)
+		__krait_power_mdd_enable(kvreg, false);
 dis_err:
 	mutex_unlock(&pvreg->krait_power_vregs_lock);
 	return rc;
@@ -716,24 +839,55 @@
 	.is_enabled		= krait_power_is_enabled,
 };
 
+static struct dentry *dent;
+static int get_retention_dbg_uV(void *data, u64 *val)
+{
+	struct pmic_gang_vreg *pvreg = data;
+	struct krait_power_vreg *kvreg;
+
+	mutex_lock(&pvreg->krait_power_vregs_lock);
+	if (!list_empty(&pvreg->krait_power_vregs)) {
+		/* return the retention voltage on just the first cpu */
+		kvreg = list_entry((&pvreg->krait_power_vregs)->next,
+			typeof(*kvreg), link);
+		*val = get_krait_retention_ldo_uv(kvreg);
+	}
+	mutex_unlock(&pvreg->krait_power_vregs_lock);
+	return 0;
+}
+
+static int set_retention_dbg_uV(void *data, u64 val)
+{
+	struct pmic_gang_vreg *pvreg = data;
+	struct krait_power_vreg *kvreg;
+	int retention_uV = val;
+
+	if (!is_between(LDO_UV_MIN, LDO_UV_MAX, retention_uV))
+		return -EINVAL;
+
+	mutex_lock(&pvreg->krait_power_vregs_lock);
+	list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
+		kvreg->retention_uV = retention_uV;
+		set_krait_retention_uv(kvreg, retention_uV);
+	}
+	mutex_unlock(&pvreg->krait_power_vregs_lock);
+	return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(retention_fops,
+			get_retention_dbg_uV, set_retention_dbg_uV, "%llu\n");
+
 static void kvreg_hw_init(struct krait_power_vreg *kvreg)
 {
 	/*
 	 * bhs_cnt value sets the ramp-up time from power collapse,
 	 * initialize the ramp up time
 	 */
-	krait_masked_write(kvreg, APC_PWR_GATE_CTL,
-		BHS_CNT_MASK, BHS_CNT_DEFAULT << BHS_CNT_BIT_POS);
-
-	krait_masked_write(kvreg, APC_PWR_GATE_CTL,
-		CLK_SRC_SEL_MASK, CLK_SRC_DEFAULT << CLK_SRC_SEL_BIT_POS);
-
-	/* BHS has six different segments, turn them all on */
-	krait_masked_write(kvreg, APC_PWR_GATE_CTL,
-		BHS_SEG_EN_MASK, BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS);
-
 	set_krait_retention_uv(kvreg, kvreg->retention_uV);
 	set_krait_ldo_uv(kvreg, kvreg->ldo_default_uV);
+
+	/* setup the bandgap that configures the reference to the LDO */
+	writel_relaxed(0x00000190, kvreg->mdd_base + MDD_CONFIG_CTL);
+	mb();
 }
 
 static void glb_init(struct platform_device *pdev)
@@ -745,43 +899,15 @@
 	pr_debug("version= 0x%x\n", version);
 }
 
-static int is_between(int left, int right, int value)
-{
-	if (left >= right && left >= value && value >= right)
-		return 1;
-	if (left <= right && left <= value && value <= right)
-		return 1;
-	return 0;
-}
-
-#define LDO_HDROOM_MIN		50000
-#define LDO_HDROOM_MAX		250000
-
-#define LDO_UV_MIN		465000
-#define LDO_UV_MAX		750000
-
-#define LDO_TH_MIN		600000
-#define LDO_TH_MAX		800000
-
 static int __devinit krait_power_probe(struct platform_device *pdev)
 {
 	struct krait_power_vreg *kvreg;
-	struct resource *res;
+	struct resource *res, *res_mdd;
 	struct regulator_init_data *init_data = pdev->dev.platform_data;
 	int rc = 0;
 	int headroom_uV, retention_uV, ldo_default_uV, ldo_threshold_uV;
-
-	/* Initialize the pmic gang if it hasn't been initialized already */
-	if (the_gang == NULL) {
-		rc = pvreg_init(pdev);
-		if (rc < 0) {
-			dev_err(&pdev->dev,
-				"failed to init pmic gang rc = %d\n", rc);
-			return rc;
-		}
-		/* global initializtion */
-		glb_init(pdev);
-	}
+	int ldo_delta_uV;
+	int cpu_num;
 
 	if (pdev->dev.of_node) {
 		/* Get init_data from device tree. */
@@ -845,6 +971,26 @@
 					ldo_threshold_uV);
 			return -EINVAL;
 		}
+
+		rc = of_property_read_u32(pdev->dev.of_node,
+					"qcom,ldo-delta-voltage",
+					&ldo_delta_uV);
+		if (rc < 0) {
+			pr_err("ldo-delta-voltage missing rc=%d\n", rc);
+			return rc;
+		}
+		if (!is_between(LDO_DELTA_MIN, LDO_DELTA_MAX, ldo_delta_uV)) {
+			pr_err("bad ldo-delta-voltage = %d specified\n",
+					ldo_delta_uV);
+			return -EINVAL;
+		}
+		rc = of_property_read_u32(pdev->dev.of_node,
+					"qcom,cpu-num",
+					&cpu_num);
+		if (cpu_num > num_possible_cpus()) {
+			pr_err("bad cpu-num= %d specified\n", cpu_num);
+			return -EINVAL;
+		}
 	}
 
 	if (!init_data) {
@@ -858,12 +1004,18 @@
 		return -EINVAL;
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acs");
 	if (!res) {
 		dev_err(&pdev->dev, "missing physical register addresses\n");
 		return -EINVAL;
 	}
 
+	res_mdd = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mdd");
+	if (!res_mdd) {
+		dev_err(&pdev->dev, "missing mdd register addresses\n");
+		return -EINVAL;
+	}
+
 	kvreg = devm_kzalloc(&pdev->dev,
 			sizeof(struct krait_power_vreg), GFP_KERNEL);
 	if (!kvreg) {
@@ -874,6 +1026,9 @@
 	kvreg->reg_base = devm_ioremap(&pdev->dev,
 				res->start, resource_size(res));
 
+	kvreg->mdd_base = devm_ioremap(&pdev->dev,
+				res_mdd->start, resource_size(res));
+
 	kvreg->pvreg		= the_gang;
 	kvreg->name		= init_data->constraints.name;
 	kvreg->desc.name	= kvreg->name;
@@ -887,10 +1042,15 @@
 	kvreg->retention_uV	= retention_uV;
 	kvreg->ldo_default_uV	= ldo_default_uV;
 	kvreg->ldo_threshold_uV = ldo_threshold_uV;
+	kvreg->ldo_delta_uV	= ldo_delta_uV;
+	kvreg->cpu_num		= cpu_num;
 
 	platform_set_drvdata(pdev, kvreg);
 
 	mutex_lock(&the_gang->krait_power_vregs_lock);
+	the_gang->pmic_min_uV_for_retention
+		= min(the_gang->pmic_min_uV_for_retention,
+			kvreg->retention_uV + kvreg->headroom_uV);
 	list_add_tail(&kvreg->link, &the_gang->krait_power_vregs);
 	mutex_unlock(&the_gang->krait_power_vregs_lock);
 
@@ -903,6 +1063,7 @@
 	}
 
 	kvreg_hw_init(kvreg);
+	per_cpu(krait_vregs, cpu_num) = kvreg;
 	dev_dbg(&pdev->dev, "id=%d, name=%s\n", pdev->id, kvreg->name);
 
 	return 0;
@@ -944,34 +1105,124 @@
 	},
 };
 
+static struct of_device_id krait_pdn_match_table[] = {
+	{ .compatible = "qcom,krait-pdn", },
+	{}
+};
+
+static int __devinit krait_pdn_probe(struct platform_device *pdev)
+{
+	int rc;
+	bool use_phase_switching = false;
+	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->of_node;
+	struct pmic_gang_vreg *pvreg;
+
+	if (!dev->of_node) {
+		dev_err(dev, "device tree information missing\n");
+		return -ENODEV;
+	}
+
+	use_phase_switching = of_property_read_bool(node,
+						"qcom,use-phase-switching");
+	pvreg = devm_kzalloc(&pdev->dev,
+			sizeof(struct pmic_gang_vreg), GFP_KERNEL);
+	if (!pvreg) {
+		pr_err("kzalloc failed.\n");
+		return 0;
+	}
+
+	pvreg->name = "pmic_gang";
+	pvreg->pmic_vmax_uV = PMIC_VOLTAGE_MIN;
+	pvreg->pmic_phase_count = -EINVAL;
+	pvreg->retention_enabled = true;
+	pvreg->pmic_min_uV_for_retention = INT_MAX;
+	pvreg->use_phase_switching = use_phase_switching;
+
+	mutex_init(&pvreg->krait_power_vregs_lock);
+	INIT_LIST_HEAD(&pvreg->krait_power_vregs);
+	the_gang = pvreg;
+
+	pr_debug("name=%s inited\n", pvreg->name);
+
+	/* global initializtion */
+	glb_init(pdev);
+
+	rc = of_platform_populate(node, NULL, NULL, dev);
+	if (rc) {
+		dev_err(dev, "failed to add child nodes, rc=%d\n", rc);
+		return rc;
+	}
+
+	dent = debugfs_create_dir(KRAIT_REGULATOR_DRIVER_NAME, NULL);
+	debugfs_create_file("retention_uV",
+			0644, dent, the_gang, &retention_fops);
+	return 0;
+}
+
+static int __devexit krait_pdn_remove(struct platform_device *pdev)
+{
+	the_gang = NULL;
+	debugfs_remove_recursive(dent);
+	return 0;
+}
+
+static struct platform_driver krait_pdn_driver = {
+	.probe	= krait_pdn_probe,
+	.remove	= __devexit_p(krait_pdn_remove),
+	.driver	= {
+		.name		= KRAIT_PDN_DRIVER_NAME,
+		.of_match_table	= krait_pdn_match_table,
+		.owner		= THIS_MODULE,
+	},
+};
+
 int __init krait_power_init(void)
 {
-	return platform_driver_register(&krait_power_driver);
+	int rc = platform_driver_register(&krait_power_driver);
+	if (rc) {
+		pr_err("failed to add %s driver rc = %d\n",
+				KRAIT_REGULATOR_DRIVER_NAME, rc);
+		return rc;
+	}
+	return platform_driver_register(&krait_pdn_driver);
 }
 
 static void __exit krait_power_exit(void)
 {
 	platform_driver_unregister(&krait_power_driver);
+	platform_driver_unregister(&krait_pdn_driver);
 }
-
 module_exit(krait_power_exit);
 
 void secondary_cpu_hs_init(void *base_ptr)
 {
-	/* 605mV retention and 705mV operational voltage */
-	writel_relaxed(0x1C30, base_ptr + APC_LDO_VREF_SET);
-	/* HS_EN_DLY=3; LDO_BYP_DLY=1; */
-	writel_relaxed(0x430000, base_ptr + APC_PWR_GATE_DLY);
-	/* MODE = BHS; EN=1; */
-	writel_relaxed(0x21, base_ptr + APC_PWR_GATE_MODE);
-
 	/* Turn on the BHS, turn off LDO Bypass and power down LDO */
-	writel_relaxed(0x403F007F, base_ptr + APC_PWR_GATE_CTL);
+	writel_relaxed(
+		BHS_CNT_DEFAULT << BHS_CNT_BIT_POS
+		| LDO_PWR_DWN_MASK
+		| CLK_SRC_DEFAULT << CLK_SRC_SEL_BIT_POS
+		| BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS
+		| BHS_EN_MASK,
+		base_ptr + APC_PWR_GATE_CTL);
+
+	/* complete the above write before the delay */
 	mb();
-	udelay(1);
+
+	/*
+	 * wait for the bhs to settle
+	 */
+	udelay(BHS_SETTLING_DELAY_US);
 
 	/* Finally turn on the bypass so that BHS supplies power */
-	writel_relaxed(0x403F3F7F, base_ptr + APC_PWR_GATE_CTL);
+	writel_relaxed(
+		BHS_CNT_DEFAULT << BHS_CNT_BIT_POS
+		| LDO_PWR_DWN_MASK
+		| CLK_SRC_DEFAULT << CLK_SRC_SEL_BIT_POS
+		| LDO_BYP_MASK
+		| BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS
+		| BHS_EN_MASK,
+		base_ptr + APC_PWR_GATE_CTL);
 }
 
 MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/krait-scm.c b/arch/arm/mach-msm/krait-scm.c
index eb48d35..a67c3df 100644
--- a/arch/arm/mach-msm/krait-scm.c
+++ b/arch/arm/mach-msm/krait-scm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/lpm_levels.c b/arch/arm/mach-msm/lpm_levels.c
index 61c2aa8..539a4fe 100644
--- a/arch/arm/mach-msm/lpm_levels.c
+++ b/arch/arm/mach-msm/lpm_levels.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
@@ -37,6 +37,10 @@
 static struct msm_rpmrs_level *msm_lpm_levels;
 static int msm_lpm_level_count;
 
+static DEFINE_PER_CPU(uint32_t , msm_lpm_sleep_time);
+static DEFINE_PER_CPU(int , lpm_permitted_level);
+static DEFINE_PER_CPU(struct atomic_notifier_head, lpm_notify_head);
+
 static void msm_lpm_level_update(void)
 {
 	unsigned int lpm_level;
@@ -55,19 +59,19 @@
 	int ret = 0;
 	int debug_mask;
 	struct msm_rpmrs_limits *l = (struct msm_rpmrs_limits *)limits;
+	struct msm_lpm_sleep_data sleep_data;
 
-	ret = msm_rpm_enter_sleep();
-	if (ret) {
-		pr_warn("%s(): RPM failed to enter sleep err:%d\n",
-				__func__, ret);
-		goto bail;
-	}
+	sleep_data.limits = limits;
+	sleep_data.kernel_sleep = __get_cpu_var(msm_lpm_sleep_time);
+	atomic_notifier_call_chain(&__get_cpu_var(lpm_notify_head),
+		MSM_LPM_STATE_ENTER, &sleep_data);
+
 	if (from_idle)
 		debug_mask = msm_lpm_lvl_dbg_msk &
-				MSM_LPM_LVL_DBG_IDLE_LIMITS;
+			MSM_LPM_LVL_DBG_IDLE_LIMITS;
 	else
 		debug_mask = msm_lpm_lvl_dbg_msk &
-				MSM_LPM_LVL_DBG_SUSPEND_LIMITS;
+			MSM_LPM_LVL_DBG_SUSPEND_LIMITS;
 
 	if (debug_mask)
 		pr_info("%s(): pxo:%d l2:%d mem:0x%x(0x%x) dig:0x%x(0x%x)\n",
@@ -78,6 +82,19 @@
 				l->vdd_dig_upper_bound);
 
 	ret = msm_lpmrs_enter_sleep(sclk_count, l, from_idle, notify_rpm);
+	if (ret) {
+		pr_warn("%s() LPM resources failed to enter sleep\n",
+				__func__);
+		goto bail;
+	}
+	if (notify_rpm) {
+		ret = msm_rpm_enter_sleep(debug_mask);
+		if (ret) {
+			pr_warn("%s(): RPM failed to enter sleep err:%d\n",
+					__func__, ret);
+			goto bail;
+		}
+	}
 bail:
 	return ret;
 }
@@ -85,9 +102,13 @@
 static void msm_lpm_exit_sleep(void *limits, bool from_idle,
 		bool notify_rpm, bool collapsed)
 {
-	msm_rpm_exit_sleep();
+
 	msm_lpmrs_exit_sleep((struct msm_rpmrs_limits *)limits,
 				from_idle, notify_rpm, collapsed);
+	if (notify_rpm)
+		msm_rpm_exit_sleep();
+	atomic_notifier_call_chain(&__get_cpu_var(lpm_notify_head),
+			MSM_LPM_STATE_EXIT, NULL);
 }
 
 void msm_lpm_show_resources(void)
@@ -96,6 +117,48 @@
 	return;
 }
 
+uint32_t msm_pm_get_pxo(struct msm_rpmrs_limits *limits)
+{
+	return limits->pxo;
+}
+
+uint32_t msm_pm_get_l2_cache(struct msm_rpmrs_limits *limits)
+{
+	return limits->l2_cache;
+}
+
+uint32_t msm_pm_get_vdd_mem(struct msm_rpmrs_limits *limits)
+{
+	return limits->vdd_mem_upper_bound;
+}
+
+uint32_t msm_pm_get_vdd_dig(struct msm_rpmrs_limits *limits)
+{
+	return limits->vdd_dig_upper_bound;
+}
+
+static bool lpm_level_permitted(int cur_level_count)
+{
+	if (__get_cpu_var(lpm_permitted_level) == msm_lpm_level_count + 1)
+		return true;
+	return (__get_cpu_var(lpm_permitted_level) == cur_level_count);
+}
+
+int msm_lpm_register_notifier(int cpu, int level_iter,
+			struct notifier_block *nb, bool is_latency_measure)
+{
+	per_cpu(lpm_permitted_level, cpu) = level_iter;
+	return atomic_notifier_chain_register(&per_cpu(lpm_notify_head,
+			cpu), nb);
+}
+
+int msm_lpm_unregister_notifier(int cpu, struct notifier_block *nb)
+{
+	per_cpu(lpm_permitted_level, cpu) = msm_lpm_level_count + 1;
+	return atomic_notifier_chain_unregister(&per_cpu(lpm_notify_head, cpu),
+				nb);
+}
+
 s32 msm_cpuidle_get_deep_idle_latency(void)
 {
 	int i;
@@ -118,6 +181,18 @@
 	}
 	return best->latency_us - 1;
 }
+static bool msm_lpm_irqs_detectable(struct msm_rpmrs_limits *limits,
+		bool irqs_detectable, bool gpio_detectable)
+{
+	if (!limits->irqs_detectable)
+		return irqs_detectable;
+
+	if (!limits->gpio_detectable)
+		return gpio_detectable;
+
+	return true;
+
+}
 
 static void *msm_lpm_lowest_limits(bool from_idle,
 		enum msm_pm_sleep_mode sleep_mode,
@@ -127,12 +202,20 @@
 	struct msm_rpmrs_level *best_level = NULL;
 	uint32_t pwr;
 	int i;
+	int best_level_iter = msm_lpm_level_count + 1;
+	bool irqs_detect = false;
+	bool gpio_detect = false;
 
 	if (!msm_lpm_levels)
 		return NULL;
 
 	msm_lpm_level_update();
 
+	if (sleep_mode == MSM_PM_SLEEP_MODE_POWER_COLLAPSE) {
+		irqs_detect = msm_mpm_irqs_detectable(from_idle);
+		gpio_detect = msm_mpm_gpio_irqs_detectable(from_idle);
+	}
+
 	for (i = 0; i < msm_lpm_level_count; i++) {
 		struct msm_rpmrs_level *level = &msm_lpm_levels[i];
 
@@ -145,6 +228,11 @@
 		if (time_param->latency_us < level->latency_us)
 			continue;
 
+		if ((sleep_mode == MSM_PM_SLEEP_MODE_POWER_COLLAPSE) &&
+			!msm_lpm_irqs_detectable(&level->rs_limits,
+				irqs_detect, gpio_detect))
+				continue;
+
 		if ((MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE == sleep_mode)
 			|| (MSM_PM_SLEEP_MODE_POWER_COLLAPSE == sleep_mode))
 			if (!cpu && msm_rpm_waiting_for_ack())
@@ -170,14 +258,31 @@
 			level->rs_limits.latency_us[cpu] = level->latency_us;
 			level->rs_limits.power[cpu] = pwr;
 			best_level = level;
-
+			best_level_iter = i;
 			if (power)
 				*power = pwr;
 		}
 	}
+	if (best_level && !lpm_level_permitted(best_level_iter))
+		best_level = NULL;
+	else
+		per_cpu(msm_lpm_sleep_time, cpu) =
+			time_param->modified_time_us ?
+			time_param->modified_time_us : time_param->sleep_us;
 
 	return best_level ? &best_level->rs_limits : NULL;
 }
+
+static struct lpm_test_platform_data lpm_test_pdata;
+
+static struct platform_device msm_lpm_test_device = {
+	.name		= "lpm_test",
+	.id		= -1,
+	.dev		= {
+		.platform_data = &lpm_test_pdata,
+	},
+};
+
 static struct msm_pm_sleep_ops msm_lpm_ops = {
 	.lowest_limits = msm_lpm_lowest_limits,
 	.enter_sleep = msm_lpm_enter_sleep,
@@ -194,6 +299,7 @@
 	int ret = 0;
 	uint32_t num_levels = 0;
 	int idx = 0;
+	unsigned int m_cpu = 0;
 
 	for_each_child_of_node(pdev->dev.of_node, node)
 		num_levels++;
@@ -249,6 +355,14 @@
 			goto fail;
 		level->rs_limits.vdd_mem_lower_bound = val;
 
+		key = "qcom,gpio-detectable";
+		level->rs_limits.gpio_detectable =
+				of_property_read_bool(node, key);
+
+		key = "qcom,irqs-detectable";
+		level->rs_limits.irqs_detectable =
+				of_property_read_bool(node, key);
+
 		key = "qcom,latency-us";
 		ret = of_property_read_u32(node, key, &val);
 		if (ret)
@@ -279,6 +393,17 @@
 	msm_lpm_levels = levels;
 	msm_lpm_level_count = idx;
 
+	lpm_test_pdata.msm_lpm_test_levels = msm_lpm_levels;
+	lpm_test_pdata.msm_lpm_test_level_count = msm_lpm_level_count;
+	key = "qcom,use-qtimer";
+	lpm_test_pdata.use_qtimer =
+			of_property_read_bool(pdev->dev.of_node, key);
+
+	for_each_possible_cpu(m_cpu)
+		per_cpu(lpm_permitted_level, m_cpu) =
+					msm_lpm_level_count + 1;
+
+	platform_device_register(&msm_lpm_test_device);
 	msm_pm_set_sleep_ops(&msm_lpm_ops);
 
 	return 0;
diff --git a/arch/arm/mach-msm/lpm_resources.c b/arch/arm/mach-msm/lpm_resources.c
index 5d7fc94..60184b4 100644
--- a/arch/arm/mach-msm/lpm_resources.c
+++ b/arch/arm/mach-msm/lpm_resources.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
@@ -108,6 +108,12 @@
 	MSM_LPM_LOCAL_RS_TYPE = 1,
 };
 
+enum {
+	MSM_SCM_L2_ON = 0,
+	MSM_SCM_L2_OFF = 1,
+	MSM_SCM_L2_GDHS = 3,
+};
+
 struct msm_lpm_resource {
 	struct msm_lpm_rs_data rs_data;
 	uint32_t sleep_value;
@@ -407,15 +413,16 @@
 {
 	int lpm, rc;
 
-	msm_pm_set_l2_flush_flag(0);
+	msm_pm_set_l2_flush_flag(MSM_SCM_L2_ON);
 
 	switch (sleep_mode) {
 	case MSM_LPM_L2_CACHE_HSFS_OPEN:
 		lpm = MSM_SPM_L2_MODE_POWER_COLLAPSE;
-		msm_pm_set_l2_flush_flag(1);
+		msm_pm_set_l2_flush_flag(MSM_SCM_L2_OFF);
 		break;
 	case MSM_LPM_L2_CACHE_GDHS:
 		lpm = MSM_SPM_L2_MODE_GDHS;
+		msm_pm_set_l2_flush_flag(MSM_SCM_L2_GDHS);
 		break;
 	case MSM_LPM_L2_CACHE_RETENTION:
 		lpm = MSM_SPM_L2_MODE_RETENTION;
@@ -668,7 +675,8 @@
 	}
 	msm_lpm_get_rpm_notif = true;
 
-	msm_mpm_enter_sleep(sclk_count, from_idle);
+	if (notify_rpm)
+		msm_mpm_enter_sleep(sclk_count, from_idle);
 
 	return ret;
 }
diff --git a/arch/arm/mach-msm/lpm_resources.h b/arch/arm/mach-msm/lpm_resources.h
index 120832f..1a2d72d 100644
--- a/arch/arm/mach-msm/lpm_resources.h
+++ b/arch/arm/mach-msm/lpm_resources.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -8,13 +8,13 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
  */
 
 #ifndef __ARCH_ARM_MACH_MSM_LPM_RESOURCES_H
 #define __ARCH_ARM_MACH_MSM_LPM_RESOURCES_H
 
 #include "pm.h"
+#include "test-lpm.h"
 
 enum {
 	MSM_LPM_PXO_OFF = 0,
@@ -35,6 +35,8 @@
 	uint32_t vdd_mem_lower_bound;
 	uint32_t vdd_dig_upper_bound;
 	uint32_t vdd_dig_lower_bound;
+	bool irqs_detectable;
+	bool gpio_detectable;
 
 	uint32_t latency_us[NR_CPUS];
 	uint32_t power[NR_CPUS];
@@ -50,6 +52,93 @@
 	uint32_t time_overhead_us;
 };
 
+enum {
+	MSM_LPM_STATE_ENTER = 0,
+	MSM_LPM_STATE_EXIT = 1,
+};
+
+#define MSM_PM(field) MSM_LPM_##field
+
+/**
+ * msm_pm_get_pxo() -  get the limits for pxo
+ * @limits:            pointer to the msm_rpmrs_limits structure
+ *
+ * This function gets the limits to the resource pxo on
+ * 8974
+ */
+
+uint32_t msm_pm_get_pxo(struct msm_rpmrs_limits *limits);
+
+/**
+ * msm_pm_get_l2_cache() -  get the limits for l2 cache
+ * @limits:            pointer to the msm_rpmrs_limits structure
+ *
+ * This function gets the limits to the resource l2 cache
+ * on 8974
+ */
+
+uint32_t msm_pm_get_l2_cache(struct msm_rpmrs_limits *limits);
+
+/**
+ * msm_pm_get_vdd_mem() -  get the limits for pxo
+ * @limits:            pointer to the msm_rpmrs_limits structure
+ *
+ * This function gets the limits to the resource vdd mem
+ * on 8974
+ */
+
+uint32_t msm_pm_get_vdd_mem(struct msm_rpmrs_limits *limits);
+
+/**
+ * msm_pm_get_vdd_dig() -  get the limits for vdd dig
+ * @limits:            pointer to the msm_rpmrs_limits structure
+ *
+ * This function gets the limits to the resource on 8974
+ */
+
+uint32_t msm_pm_get_vdd_dig(struct msm_rpmrs_limits *limits);
+
+/**
+ * struct msm_lpm_sleep_data - abstraction to get sleep data
+ * @limits:	pointer to the msm_rpmrs_limits structure
+ * @kernel_sleep:	kernel sleep time as decided by the power calculation
+ *			algorithm
+ *
+ * This structure is an abstraction to get the limits and kernel sleep time
+ * during enter sleep.
+ */
+
+struct msm_lpm_sleep_data {
+	struct msm_rpmrs_limits *limits;
+	uint32_t kernel_sleep;
+};
+
+/**
+ * msm_lpm_register_notifier() - register for notifications
+ * @cpu:               cpu to debug
+ * @level_iter:        low power level index to debug
+ * @nb:       notifier block to callback on notifications
+ * @is_latency_measure: is it latency measure
+ *
+ * This function sets the permitted level to the index of the
+ * level under test and registers notifier for callback.
+ */
+
+int msm_lpm_register_notifier(int cpu, int level_iter,
+		struct notifier_block *nb, bool is_latency_measure);
+
+/**
+ * msm_lpm_unregister_notifier() - unregister from notifications
+ * @cpu:               cpu to debug
+ * @nb:       notifier block to callback on notifications
+ *
+ * This function sets the permitted level to a value one more than
+ * available levels count which indicates that all levels are
+ * permitted and it also unregisters notifier for callback.
+ */
+
+int msm_lpm_unregister_notifier(int cpu, struct notifier_block *nb);
+
 #ifdef CONFIG_MSM_RPM_SMD
 
 /**
diff --git a/arch/arm/mach-msm/mdm.c b/arch/arm/mach-msm/mdm.c
index 8dd4bac..fd8c878 100644
--- a/arch/arm/mach-msm/mdm.c
+++ b/arch/arm/mach-msm/mdm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/mdm2.c b/arch/arm/mach-msm/mdm2.c
index 0e3e8e0..9f06cf6 100644
--- a/arch/arm/mach-msm/mdm2.c
+++ b/arch/arm/mach-msm/mdm2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/mdm_common.c b/arch/arm/mach-msm/mdm_common.c
index aef4ac9..03d158e 100644
--- a/arch/arm/mach-msm/mdm_common.c
+++ b/arch/arm/mach-msm/mdm_common.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -444,6 +444,10 @@
 {
 	gpio_direction_output(mdm_drv->ap2mdm_errfatal_gpio, 0);
 	gpio_direction_output(mdm_drv->ap2mdm_status_gpio, 1);
+
+	if (mdm_drv->pdata->ps_hold_delay_ms > 0)
+		msleep(mdm_drv->pdata->ps_hold_delay_ms);
+
 	mdm_drv->ops->power_on_mdm_cb(mdm_drv);
 	mdm_drv->boot_type = CHARM_NORMAL_BOOT;
 	complete(&mdm_needs_reload);
diff --git a/arch/arm/mach-msm/mdm_private.h b/arch/arm/mach-msm/mdm_private.h
index 9e865c5..92fb141 100644
--- a/arch/arm/mach-msm/mdm_private.h
+++ b/arch/arm/mach-msm/mdm_private.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/memory.c b/arch/arm/mach-msm/memory.c
index 9cc2a9d..806581d 100644
--- a/arch/arm/mach-msm/memory.c
+++ b/arch/arm/mach-msm/memory.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/memory.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -507,11 +507,10 @@
  */
 void adjust_meminfo(unsigned long start, unsigned long size)
 {
-	int i, j;
+	int i;
 
-	for (i = 0, j = 0; i < meminfo.nr_banks; i++) {
-		struct membank *bank = &meminfo.bank[j];
-		*bank = meminfo.bank[i];
+	for (i = 0; i < meminfo.nr_banks; i++) {
+		struct membank *bank = &meminfo.bank[i];
 
 		if (((start + size) <= (bank->start + bank->size)) &&
 			(start >= bank->start)) {
@@ -519,15 +518,15 @@
 				(meminfo.nr_banks - i) * sizeof(*bank));
 			meminfo.nr_banks++;
 			i++;
-			bank[1].size -= (start + size);
-			bank[1].start = (start + size);
-			bank[1].highmem = 0;
-			j++;
+
 			bank->size = start - bank->start;
+			bank[1].start = (start + size);
+			bank[1].size -= (bank->size + size);
+			bank[1].highmem = 0;
 		}
-		j++;
 	}
 }
+
 unsigned long get_ddr_size(void)
 {
 	unsigned int i;
diff --git a/arch/arm/mach-msm/memory_topology.c b/arch/arm/mach-msm/memory_topology.c
index 70aaf4a..772e63e 100644
--- a/arch/arm/mach-msm/memory_topology.c
+++ b/arch/arm/mach-msm/memory_topology.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/mkrpcsym.pl b/arch/arm/mach-msm/mkrpcsym.pl
index f4abb5f..52b6fcf 100644
--- a/arch/arm/mach-msm/mkrpcsym.pl
+++ b/arch/arm/mach-msm/mkrpcsym.pl
@@ -2,7 +2,7 @@
 #
 # Generate the smd_rpc_sym.c symbol file for ONCRPC SMEM Logging
 #
-# Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+# Copyright (c) 2009, The Linux Foundation. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are
@@ -13,7 +13,7 @@
 #       copyright notice, this list of conditions and the following
 #       disclaimer in the documentation and/or other materials provided
 #       with the distribution.
-#     * Neither the name of Code Aurora Forum, Inc. nor the names of its
+#     * Neither the name of The Linux Foundation nor the names of its
 #       contributors may be used to endorse or promote products derived
 #       from this software without specific prior written permission.
 #
diff --git a/arch/arm/mach-msm/modem_notifier.c b/arch/arm/mach-msm/modem_notifier.c
index 2f4f6af..56aedfd 100644
--- a/arch/arm/mach-msm/modem_notifier.c
+++ b/arch/arm/mach-msm/modem_notifier.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/arch/arm/mach-msm/modem_notifier.h b/arch/arm/mach-msm/modem_notifier.h
index e39c163..96ad047 100644
--- a/arch/arm/mach-msm/modem_notifier.h
+++ b/arch/arm/mach-msm/modem_notifier.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/arch/arm/mach-msm/mpm-8625.c b/arch/arm/mach-msm/mpm-8625.c
index aaac476..6c2ed76 100644
--- a/arch/arm/mach-msm/mpm-8625.c
+++ b/arch/arm/mach-msm/mpm-8625.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -101,7 +101,7 @@
 
 static uint16_t msm_bypassed_apps_irqs[] = {
 	MSM8625_INT_CPR_IRQ0,
-	MSM8625_INT_L2CC_INTR,
+	MSM8625_INT_SC_SICL2PERFMONIRPTREQ,
 };
 
 /* Check IRQ falls into bypassed list are not */
diff --git a/arch/arm/mach-msm/mpm-8625.h b/arch/arm/mach-msm/mpm-8625.h
index 1c28390..884f6c9 100644
--- a/arch/arm/mach-msm/mpm-8625.h
+++ b/arch/arm/mach-msm/mpm-8625.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/mpm-of.c b/arch/arm/mach-msm/mpm-of.c
index 430bda1..09f784d 100644
--- a/arch/arm/mach-msm/mpm-of.c
+++ b/arch/arm/mach-msm/mpm-of.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -51,11 +51,14 @@
 	unsigned long pin;
 	struct hlist_node node;
 };
+#define MAX_DOMAIN_NAME 5
 
 struct mpm_irqs {
 	struct irq_domain *domain;
 	unsigned long *enabled_irqs;
 	unsigned long *wakeup_irqs;
+	unsigned long size;
+	char domain_name[MAX_DOMAIN_NAME];
 };
 
 static struct mpm_irqs unlisted_irqs[MSM_MPM_NR_IRQ_DOMAINS];
@@ -437,28 +440,53 @@
 	return 0;
 }
 
-bool msm_mpm_irqs_detectable(bool from_idle)
+static bool msm_mpm_interrupts_detectable(int d, bool from_idle)
 {
-	/* TODO:
-	 * Return true if unlisted irqs is empty
-	 */
+	unsigned long *irq_bitmap;
+	bool debug_mask, ret = false;
+	struct mpm_irqs *unlisted = &unlisted_irqs[d];
 
 	if (!msm_mpm_is_initialized())
 		return false;
 
-	return true;
+	if (from_idle) {
+		irq_bitmap = unlisted->enabled_irqs;
+		debug_mask = msm_mpm_debug_mask &
+				MSM_MPM_DEBUG_NON_DETECTABLE_IRQ_IDLE;
+	} else {
+		irq_bitmap = unlisted->wakeup_irqs;
+		debug_mask = msm_mpm_debug_mask &
+				MSM_MPM_DEBUG_NON_DETECTABLE_IRQ;
+	}
+
+	ret = (bool) __bitmap_empty(irq_bitmap, unlisted->size);
+
+	if (debug_mask && !ret) {
+		int i = 0;
+		i = find_first_bit(irq_bitmap, unlisted->size);
+		pr_info("%s(): %s preventing system sleep modes during %s\n",
+				__func__, unlisted->domain_name,
+				from_idle ? "idle" : "suspend");
+
+		while (i < unlisted->size) {
+			pr_info("\thwirq: %d\n", i);
+			i = find_next_bit(irq_bitmap, unlisted->size, i + 1);
+		}
+	}
+
+	return ret;
 }
 
 bool msm_mpm_gpio_irqs_detectable(bool from_idle)
 {
-	/* TODO:
-	 * Return true if unlisted irqs is empty
-	 */
-	if (!msm_mpm_is_initialized())
-		return false;
-	return true;
+	return msm_mpm_interrupts_detectable(MSM_MPM_GPIO_IRQ_DOMAIN,
+			from_idle);
 }
-
+bool msm_mpm_irqs_detectable(bool from_idle)
+{
+	return msm_mpm_interrupts_detectable(MSM_MPM_GIC_IRQ_DOMAIN,
+			from_idle);
+}
 void msm_mpm_enter_sleep(uint32_t sclk_count, bool from_idle)
 {
 	cycle_t wakeup = (u64)sclk_count * ARCH_TIMER_HZ;
@@ -614,6 +642,7 @@
 	struct mpm_of {
 		char *pkey;
 		char *map;
+		char name[MAX_DOMAIN_NAME];
 		struct irq_chip *chip;
 		int (*get_max_irqs)(struct irq_domain *d);
 	};
@@ -623,12 +652,14 @@
 		{
 			"qcom,gic-parent",
 			"qcom,gic-map",
+			"gic",
 			&gic_arch_extn,
 			mpm_irq_domain_linear_size,
 		},
 		{
 			"qcom,gpio-parent",
 			"qcom,gpio-map",
+			"gpio",
 			&msm_gpio_irq_extn,
 			mpm_irq_domain_legacy_size,
 		},
@@ -665,6 +696,9 @@
 		}
 
 		size = mpm_of_map[i].get_max_irqs(domain);
+		unlisted_irqs[i].size = size;
+		memcpy(unlisted_irqs[i].domain_name, mpm_of_map[i].name,
+				MAX_DOMAIN_NAME);
 
 		unlisted_irqs[i].enabled_irqs =
 			kzalloc(BITS_TO_LONGS(size) * sizeof(unsigned long),
diff --git a/arch/arm/mach-msm/mpm.c b/arch/arm/mach-msm/mpm.c
index 5127607..5c9a950 100644
--- a/arch/arm/mach-msm/mpm.c
+++ b/arch/arm/mach-msm/mpm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/mpp.c b/arch/arm/mach-msm/mpp.c
index bd70e9a..82e0f34 100644
--- a/arch/arm/mach-msm/mpp.c
+++ b/arch/arm/mach-msm/mpp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/arch/arm/mach-msm/msm-buspm-dev.c b/arch/arm/mach-msm/msm-buspm-dev.c
index ec0f1bd..5fd9e46 100644
--- a/arch/arm/mach-msm/msm-buspm-dev.c
+++ b/arch/arm/mach-msm/msm-buspm-dev.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/msm-buspm-dev.h b/arch/arm/mach-msm/msm-buspm-dev.h
index 854626d..a951093 100644
--- a/arch/arm/mach-msm/msm-buspm-dev.h
+++ b/arch/arm/mach-msm/msm-buspm-dev.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/msm-keypad-devices.h b/arch/arm/mach-msm/msm-keypad-devices.h
index 469564a..153c69a 100644
--- a/arch/arm/mach-msm/msm-keypad-devices.h
+++ b/arch/arm/mach-msm/msm-keypad-devices.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/msm-krait-l2-accessors.c b/arch/arm/mach-msm/msm-krait-l2-accessors.c
index 2c66ea0..7498e7f 100644
--- a/arch/arm/mach-msm/msm-krait-l2-accessors.c
+++ b/arch/arm/mach-msm/msm-krait-l2-accessors.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/msm_bus/Makefile b/arch/arm/mach-msm/msm_bus/Makefile
index dde25ab..2ee07f3 100644
--- a/arch/arm/mach-msm/msm_bus/Makefile
+++ b/arch/arm/mach-msm/msm_bus/Makefile
@@ -2,7 +2,9 @@
 # Makefile for msm-bus driver specific files
 #
 obj-y += msm_bus_core.o msm_bus_fabric.o msm_bus_config.o msm_bus_arb.o
-obj-y += msm_bus_bimc.o msm_bus_noc.o msm_bus_of.o
+obj-y += msm_bus_bimc.o msm_bus_noc.o
+obj-$(CONFIG_CORESIGHT) +=  msm_buspm_coresight.o
+obj-$(CONFIG_OF) += msm_bus_of.o
 obj-$(CONFIG_MSM_RPM) += msm_bus_rpm.o
 obj-$(CONFIG_MSM_RPM_SMD) += msm_bus_rpm_smd.o
 obj-$(CONFIG_ARCH_MSM8X60) += msm_bus_board_8660.o
@@ -12,4 +14,5 @@
 obj-$(CONFIG_ARCH_MSM8930) += msm_bus_board_8930.o
 obj-$(CONFIG_ARCH_MSM8974) += msm_bus_board_8974.o
 obj-$(CONFIG_ARCH_MSM9625) += msm_bus_board_9625.o
+obj-$(CONFIG_ARCH_MSM8226) += msm_bus_id.o
 obj-$(CONFIG_DEBUG_FS) += msm_bus_dbg.o
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_arb.c b/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
index e61eb6d..4336945 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c b/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c
index ea17efe..d416c19 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -1932,17 +1932,18 @@
 	}
 
 	for (i = 0; i < info->node_info->num_mports; i++) {
-		/* If in bypass mode, update priority */
-		if (info->node_info->mode != BIMC_QOS_MODE_BYPASS)
+		/* If not in bypass mode, update priority */
+		if (info->node_info->mode != BIMC_QOS_MODE_BYPASS) {
 			msm_bus_bimc_set_qos_prio(binfo, info->node_info->
 				qport[i], info->node_info->mode, qmode);
 
-		/* If in fixed mode, update bandwidth */
-		if (info->node_info->mode != BIMC_QOS_MODE_FIXED) {
-			struct msm_bus_bimc_qos_bw qbw;
-			qbw.ws = info->node_info->ws;
-			msm_bus_bimc_set_qos_bw(binfo,
-				info->node_info->qport[i], &qbw);
+			/* If not in fixed mode, update bandwidth */
+			if (info->node_info->mode != BIMC_QOS_MODE_FIXED) {
+				struct msm_bus_bimc_qos_bw qbw;
+				qbw.ws = info->node_info->ws;
+				msm_bus_bimc_set_qos_bw(binfo,
+					info->node_info->qport[i], &qbw);
+			}
 		}
 
 		/* set mode */
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_bimc.h b/arch/arm/mach-msm/msm_bus/msm_bus_bimc.h
index 249e8bb..6df0bea 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_bimc.h
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_bimc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_8064.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_8064.c
index 5a3d722..b45efad 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_8064.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_8064.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_8660.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_8660.c
index 296c6dc..d3d1ffa 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_8660.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_8660.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
@@ -922,3 +922,7 @@
 {
 	return -ENXIO;
 }
+
+void msm_bus_board_init(struct msm_bus_fabric_registration *pdata)
+{
+}
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_8930.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_8930.c
index 0f37c6d..91d106e 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_8930.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_8930.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c
index d079e77..158dee3 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
@@ -1114,3 +1114,7 @@
 	id[1] = MSM_RPM_STATUS_ID_EBI1_CH1_RANGE;
 	return 0;
 }
+
+void msm_bus_board_init(struct msm_bus_fabric_registration *pdata)
+{
+}
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_8974.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_8974.c
index dbfa5ec..1f6e508 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_8974.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_8974.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -539,7 +539,6 @@
 static int qports_venus_p1[] = {5};
 static int qports_vfe[] = {6};
 static int qports_gemini_ocmem[] = {0};
-static int qports_mdp_ocmem[] = {1};
 static int qports_venus_p0_ocmem[] = {2};
 static int qports_venus_p1_ocmem[] = {3};
 static int qports_vfe_ocmem[] = {4};
@@ -1154,7 +1153,6 @@
 		.num_tiers = ARRAY_SIZE(tier2),
 		.perm_mode = NOC_QOS_PERM_MODE_FIXED,
 		.mode = NOC_QOS_MODE_FIXED,
-		.qport = qports_mdp_ocmem,
 		.mas_hw_id = MAS_MDP_OCMEM,
 		.hw_sel = MSM_BUS_NOC,
 	},
@@ -2009,3 +2007,8 @@
 	.virt = 1,
 	.rpm_enabled = 1,
 };
+
+void msm_bus_board_init(struct msm_bus_fabric_registration *pdata)
+{
+	pdata->board_algo = &msm_bus_board_algo;
+}
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_9615.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_9615.c
index 34cb2db..862bb46 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_9615.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_9615.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
@@ -311,3 +311,7 @@
 {
 	return -ENXIO;
 }
+
+void msm_bus_board_init(struct msm_bus_fabric_registration *pdata)
+{
+}
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_9625.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_9625.c
index 92cd255..65834eb 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_9625.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_9625.c
@@ -1301,3 +1301,7 @@
 	.hw_sel = MSM_BUS_NOC,
 	.rpm_enabled = 1,
 };
+
+void msm_bus_board_init(struct msm_bus_fabric_registration *pdata)
+{
+}
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_config.c b/arch/arm/mach-msm/msm_bus/msm_bus_config.c
index 28f3073..c6fa250 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_config.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_config.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_core.c b/arch/arm/mach-msm/msm_bus/msm_bus_core.c
index 4d73b03..20600bf 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_core.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -58,6 +58,8 @@
 	struct msm_bus_fabric_device *fabric;
 	dev = bus_find_device(&msm_bus_type, NULL, (void *)fabid,
 		msm_bus_device_match);
+	if (!dev)
+		return NULL;
 	fabric = to_msm_bus_fabric_device(dev);
 	return fabric;
 }
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_core.h b/arch/arm/mach-msm/msm_bus/msm_bus_core.h
index 2c6efb8..9201398 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_core.h
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_core.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -81,6 +81,7 @@
 	unsigned int prio_wr;
 	unsigned int prio1;
 	unsigned int prio0;
+	const char *name;
 };
 
 struct path_node {
@@ -205,20 +206,40 @@
 };
 
 uint64_t msm_bus_div64(unsigned int width, uint64_t bw);
-int msm_bus_remote_hw_commit(struct msm_bus_fabric_registration
-	*fab_pdata, void *hw_data, void **cdata);
 int msm_bus_fabric_device_register(struct msm_bus_fabric_device *fabric);
 void msm_bus_fabric_device_unregister(struct msm_bus_fabric_device *fabric);
 struct msm_bus_fabric_device *msm_bus_get_fabric_device(int fabid);
 int msm_bus_get_num_fab(void);
 
-void msm_bus_rpm_fill_cdata_buffer(int *curr, char *buf, const int max_size,
-	void *cdata, int nmasters, int nslaves, int ntslaves);
 
 int msm_bus_hw_fab_init(struct msm_bus_fabric_registration *pdata,
 	struct msm_bus_hw_algorithm *hw_algo);
+void msm_bus_board_init(struct msm_bus_fabric_registration *pdata);
+#if defined(CONFIG_MSM_RPM) || defined(CONFIG_MSM_RPM_SMD)
 int msm_bus_rpm_hw_init(struct msm_bus_fabric_registration *pdata,
 	struct msm_bus_hw_algorithm *hw_algo);
+int msm_bus_remote_hw_commit(struct msm_bus_fabric_registration
+	*fab_pdata, void *hw_data, void **cdata);
+void msm_bus_rpm_fill_cdata_buffer(int *curr, char *buf, const int max_size,
+	void *cdata, int nmasters, int nslaves, int ntslaves);
+#else
+static inline int msm_bus_rpm_hw_init(struct msm_bus_fabric_registration *pdata,
+	struct msm_bus_hw_algorithm *hw_algo)
+{
+	return 0;
+}
+static inline int msm_bus_remote_hw_commit(struct msm_bus_fabric_registration
+	*fab_pdata, void *hw_data, void **cdata)
+{
+	return 0;
+}
+static inline void msm_bus_rpm_fill_cdata_buffer(int *curr, char *buf,
+	const int max_size, void *cdata, int nmasters, int nslaves,
+	int ntslaves)
+{
+}
+#endif
+
 int msm_bus_noc_hw_init(struct msm_bus_fabric_registration *pdata,
 	struct msm_bus_hw_algorithm *hw_algo);
 int msm_bus_bimc_hw_init(struct msm_bus_fabric_registration *pdata,
@@ -240,4 +261,30 @@
 }
 #endif
 
+#ifdef CONFIG_CORESIGHT
+int msmbus_coresight_init(struct platform_device *pdev);
+void msmbus_coresight_remove(struct platform_device *pdev);
+#else
+static inline int msmbus_coresight_init(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static inline void msmbus_coresight_remove(struct platform_device *pdev)
+{
+}
+#endif
+
+
+#ifdef CONFIG_OF
+struct msm_bus_fabric_registration
+	*msm_bus_of_get_fab_data(struct platform_device *pdev);
+#else
+static inline struct msm_bus_fabric_registration
+	*msm_bus_of_get_fab_data(struct platform_device *pdev)
+{
+	return NULL;
+}
+#endif
+
 #endif /*_ARCH_ARM_MACH_MSM_BUS_CORE_H*/
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_dbg.c b/arch/arm/mach-msm/msm_bus/msm_bus_dbg.c
index a44c53a..001c733 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_dbg.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_dbg.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c b/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
index b6870c6..2c7ceab 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -679,7 +679,7 @@
 	return ret;
 }
 
-static int msm_bus_fabric_probe(struct platform_device *pdev)
+static int __devinit msm_bus_fabric_probe(struct platform_device *pdev)
 {
 	int ctx, ret = 0;
 	struct msm_bus_fabric *fabric;
@@ -694,7 +694,6 @@
 	INIT_LIST_HEAD(&fabric->gateways);
 	INIT_RADIX_TREE(&fabric->fab_tree, GFP_ATOMIC);
 	fabric->num_nodes = 0;
-	fabric->fabdev.id = pdev->id;
 	fabric->fabdev.visited = false;
 
 	fabric->info.node_info = kzalloc(sizeof(struct msm_bus_node_info),
@@ -704,18 +703,32 @@
 		kfree(fabric);
 		return -ENOMEM;
 	}
-	fabric->info.node_info->priv_id = fabric->fabdev.id;
-	fabric->info.node_info->id = fabric->fabdev.id;
+
 	fabric->info.num_pnodes = -1;
 	fabric->info.link_info.clk[DUAL_CTX] = 0;
 	fabric->info.link_info.bw[DUAL_CTX] = 0;
 	fabric->info.link_info.clk[ACTIVE_CTX] = 0;
 	fabric->info.link_info.bw[ACTIVE_CTX] = 0;
 
-	fabric->fabdev.id = pdev->id;
-	pdata = (struct msm_bus_fabric_registration *)pdev->dev.platform_data;
+	/* If possible, get pdata from device-tree */
+	if (pdev->dev.of_node) {
+		pdata = msm_bus_of_get_fab_data(pdev);
+		if (IS_ERR(pdata) || ZERO_OR_NULL_PTR(pdata)) {
+			pr_err("Null platform data\n");
+			return PTR_ERR(pdata);
+		}
+		msm_bus_board_init(pdata);
+		fabric->fabdev.id = pdata->id;
+	} else {
+		pdata = (struct msm_bus_fabric_registration *)pdev->
+			dev.platform_data;
+		fabric->fabdev.id = pdev->id;
+	}
+
 	fabric->fabdev.name = pdata->name;
 	fabric->fabdev.algo = &msm_bus_algo;
+	fabric->info.node_info->priv_id = fabric->fabdev.id;
+	fabric->info.node_info->id = fabric->fabdev.id;
 	ret = msm_bus_fabric_hw_init(pdata, &fabric->fabdev.hw_algo);
 	if (ret) {
 		MSM_BUS_ERR("Error initializing hardware for fabric: %d\n",
@@ -776,6 +789,9 @@
 		}
 	}
 
+	if (msmbus_coresight_init(pdev))
+		pr_warn("Coresight support absent for bus: %d\n", pdata->id);
+
 	return ret;
 err:
 	kfree(fabric->info.node_info);
@@ -791,6 +807,7 @@
 	int ret = 0;
 
 	fabdev = platform_get_drvdata(pdev);
+	msmbus_coresight_remove(pdev);
 	msm_bus_fabric_device_unregister(fabdev);
 	fabric = to_msm_bus_fabric(fabdev);
 	msm_bus_dbg_commit_data(fabric->fabdev.name, NULL, 0, 0, 0,
@@ -811,12 +828,18 @@
 	return ret;
 }
 
+static struct of_device_id fabric_match[] = {
+	{.compatible = "msm-bus-fabric"},
+	{}
+};
+
 static struct platform_driver msm_bus_fabric_driver = {
 	.probe = msm_bus_fabric_probe,
 	.remove = msm_bus_fabric_remove,
 	.driver = {
 		.name = "msm_bus_fabric",
 		.owner = THIS_MODULE,
+		.of_match_table = fabric_match,
 	},
 };
 
@@ -825,4 +848,4 @@
 	MSM_BUS_ERR("msm_bus_fabric_init_driver\n");
 	return platform_driver_register(&msm_bus_fabric_driver);
 }
-postcore_initcall(msm_bus_fabric_init_driver);
+subsys_initcall(msm_bus_fabric_init_driver);
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_id.c b/arch/arm/mach-msm/msm_bus/msm_bus_id.c
new file mode 100644
index 0000000..693c51e
--- /dev/null
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_id.c
@@ -0,0 +1,83 @@
+/* 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/init.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
+#include <mach/board.h>
+#include <mach/rpm.h>
+#include "msm_bus_core.h"
+#include "msm_bus_noc.h"
+#include "msm_bus_bimc.h"
+
+static uint32_t master_iids[MSM_BUS_MASTER_LAST];
+static uint32_t slave_iids[MSM_BUS_SLAVE_LAST - SLAVE_ID_KEY];
+
+static void msm_bus_assign_iids(struct msm_bus_fabric_registration
+	*fabreg, int fabid)
+{
+	int i;
+	for (i = 0; i < fabreg->len; i++) {
+		if (!fabreg->info[i].gateway) {
+			fabreg->info[i].priv_id = fabid + fabreg->info[i].id;
+			if (fabreg->info[i].id < SLAVE_ID_KEY) {
+				WARN(fabreg->info[i].id >= MSM_BUS_MASTER_LAST,
+					"id %d exceeds array size!\n",
+					fabreg->info[i].id);
+				master_iids[fabreg->info[i].id] =
+					fabreg->info[i].priv_id;
+			} else {
+				WARN((fabreg->info[i].id - SLAVE_ID_KEY) >=
+					(MSM_BUS_SLAVE_LAST - SLAVE_ID_KEY),
+					"id %d exceeds array size!\n",
+					fabreg->info[i].id);
+				slave_iids[fabreg->info[i].id - (SLAVE_ID_KEY)]
+					= fabreg->info[i].priv_id;
+			}
+		} else {
+			fabreg->info[i].priv_id = fabreg->info[i].id;
+		}
+	}
+}
+
+static int msm_bus_get_iid(int id)
+{
+	if ((id < SLAVE_ID_KEY && id >= MSM_BUS_MASTER_LAST) ||
+		id >= MSM_BUS_SLAVE_LAST) {
+		MSM_BUS_ERR("Cannot get iid. Invalid id %d passed\n", id);
+		return -EINVAL;
+	}
+
+	return CHECK_ID(((id < SLAVE_ID_KEY) ? master_iids[id] :
+		slave_iids[id - SLAVE_ID_KEY]), id);
+}
+
+
+static struct msm_bus_board_algorithm msm_bus_id_algo = {
+	.board_nfab = NFAB,
+	.get_iid = msm_bus_get_iid,
+	.assign_iids = msm_bus_assign_iids,
+};
+
+int msm_bus_board_rpm_get_il_ids(uint16_t *id)
+{
+	return -ENXIO;
+}
+
+void msm_bus_board_init(struct msm_bus_fabric_registration *pdata)
+{
+	pdata->board_algo = &msm_bus_id_algo;
+}
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_noc.c b/arch/arm/mach-msm/msm_bus/msm_bus_noc.c
index 9e89256..3ae37e4 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_noc.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_noc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_noc.h b/arch/arm/mach-msm/msm_bus/msm_bus_noc.h
index 35af884..00479c6 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_noc.h
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_noc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_of.c b/arch/arm/mach-msm/msm_bus/msm_bus_of.c
index 8ae1b46..489eb5c 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_of.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_of.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
@@ -14,12 +14,34 @@
 
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/string.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
+#include "msm_bus_core.h"
 
 #define KBTOMB(a) (a * 1000ULL)
+static const char * const hw_sel_name[] = {"RPM", "NoC", "BIMC", NULL};
+static const char * const mode_sel_name[] = {"Fixed", "Limiter", "Bypass",
+						"Regulator", NULL};
+
+static int get_num(const char *const str[], const char *name)
+{
+	int i = 0;
+
+	do {
+		if (!strcmp(name, str[i]))
+			return i;
+
+		i++;
+	} while (str[i] != NULL);
+
+	pr_err("Error: string %s not found\n", name);
+	return -EINVAL;
+}
+
 /**
  * msm_bus_cl_get_pdata() - Generate bus client data from device tree
  * provided by clients.
@@ -72,8 +94,8 @@
 	ret = of_property_read_u32(of_node, "qcom,msm-bus,active-only",
 		&pdata->active_only);
 	if (ret) {
-		pr_info("active_only flag absent.\n");
-		pr_info("Using dual context by default\n");
+		pr_debug("active_only flag absent.\n");
+		pr_debug("Using dual context by default\n");
 	}
 
 	usecase = devm_kzalloc(&pdev->dev, (sizeof(struct msm_bus_paths) *
@@ -149,3 +171,292 @@
 	kfree(pdata);
 }
 EXPORT_SYMBOL(msm_bus_cl_clear_pdata);
+
+static int *get_arr(struct platform_device *pdev,
+		const struct device_node *node, const char *prop,
+		int *nports)
+{
+	int size = 0, ret;
+	int *arr = NULL;
+
+	if (of_get_property(node, prop, &size)) {
+		*nports = size / sizeof(int);
+	} else {
+		pr_debug("Property %s not available\n", prop);
+		*nports = 0;
+		return NULL;
+	}
+
+	arr = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
+	if ((size > 0) && ZERO_OR_NULL_PTR(arr)) {
+		pr_err("Error: Failed to alloc mem for %s\n", prop);
+		return NULL;
+	}
+
+	ret = of_property_read_u32_array(node, prop, (u32 *)arr, *nports);
+	if (ret) {
+		pr_err("Error in reading property: %s\n", prop);
+		goto err;
+	}
+
+	return arr;
+err:
+	devm_kfree(&pdev->dev, arr);
+	return NULL;
+}
+
+static struct msm_bus_node_info *get_nodes(struct device_node *of_node,
+	struct platform_device *pdev,
+	struct msm_bus_fabric_registration *pdata)
+{
+	struct msm_bus_node_info *info;
+	struct device_node *child_node = NULL;
+	int i = 0, ret;
+
+	for_each_child_of_node(of_node, child_node) {
+		i++;
+	}
+
+	pdata->len = i;
+	info = (struct msm_bus_node_info *)
+		devm_kzalloc(&pdev->dev, sizeof(struct msm_bus_node_info) *
+			pdata->len, GFP_KERNEL);
+	if (ZERO_OR_NULL_PTR(info)) {
+		pr_err("Failed to alloc memory for nodes: %d\n", pdata->len);
+		goto err;
+	}
+
+	i = 0;
+	child_node = NULL;
+	for_each_child_of_node(of_node, child_node) {
+		const char *sel_str;
+
+		ret = of_property_read_string(child_node, "label",
+			&info[i].name);
+		if (ret)
+			pr_err("Error reading node label\n");
+
+		ret = of_property_read_u32(child_node, "cell-id", &info[i].id);
+		if (ret) {
+			pr_err("Error reading node id\n");
+			goto err;
+		}
+
+		if (of_property_read_bool(child_node, "qcom,gateway"))
+			info[i].gateway = 1;
+
+		of_property_read_u32(child_node, "qcom,mas-hw-id",
+			&info[i].mas_hw_id);
+
+		of_property_read_u32(child_node, "qcom,slv-hw-id",
+			&info[i].slv_hw_id);
+		info[i].masterp = get_arr(pdev, child_node,
+					"qcom,masterp", &info[i].num_mports);
+		/* No need to store number of qports */
+		info[i].qport = get_arr(pdev, child_node,
+					"qcom,qport", &ret);
+		pdata->nmasters += info[i].num_mports;
+
+
+		info[i].slavep = get_arr(pdev, child_node,
+					"qcom,slavep", &info[i].num_sports);
+		pdata->nslaves += info[i].num_sports;
+
+
+		info[i].tier = get_arr(pdev, child_node,
+					"qcom,tier", &info[i].num_tiers);
+
+		if (of_property_read_bool(child_node, "qcom,ahb"))
+			info[i].ahb = 1;
+
+		ret = of_property_read_string(child_node, "qcom,hw-sel",
+			&sel_str);
+		if (ret)
+			info[i].hw_sel = 0;
+		else {
+			ret =  get_num(hw_sel_name, sel_str);
+			if (ret < 0) {
+				pr_err("Invalid hw-sel\n");
+				goto err;
+			}
+
+			info[i].hw_sel = ret;
+		}
+
+		of_property_read_u32(child_node, "qcom,buswidth",
+			&info[i].buswidth);
+		of_property_read_u32(child_node, "qcom,ws", &info[i].ws);
+		ret = of_property_read_string(child_node, "qcom,mode",
+			&sel_str);
+		if (ret)
+			info[i].mode = 0;
+		else {
+			ret = get_num(mode_sel_name, sel_str);
+			if (ret < 0) {
+				pr_err("Unknown mode :%s\n", sel_str);
+				goto err;
+			}
+
+			info[i].mode = ret;
+		}
+
+		ret = of_property_read_string(child_node, "qcom,perm-mode",
+			&sel_str);
+		if (ret)
+			info[i].perm_mode = 0;
+		else {
+			ret = get_num(mode_sel_name, sel_str);
+			if (ret < 0)
+				goto err;
+
+			info[i].perm_mode = 1 << ret;
+		}
+
+		of_property_read_u32(child_node, "qcom,prio-lvl",
+			&info[i].prio_lvl);
+		of_property_read_u32(child_node, "qcom,prio-rd",
+			&info[i].prio_rd);
+		of_property_read_u32(child_node, "qcom,prio-wr",
+			&info[i].prio_wr);
+		of_property_read_u32(child_node, "qcom,prio0", &info[i].prio0);
+		of_property_read_u32(child_node, "qcom,prio1", &info[i].prio1);
+		ret = of_property_read_string(child_node, "qcom,slaveclk-dual",
+			&info[i].slaveclk[DUAL_CTX]);
+		if (!ret)
+			pr_debug("Got slaveclk_dual: %s\n",
+				info[i].slaveclk[DUAL_CTX]);
+		else
+			info[i].slaveclk[DUAL_CTX] = NULL;
+
+		ret = of_property_read_string(child_node,
+			"qcom,slaveclk-active", &info[i].slaveclk[ACTIVE_CTX]);
+		if (!ret)
+			pr_debug("Got slaveclk_active\n");
+		else
+			info[i].slaveclk[ACTIVE_CTX] = NULL;
+
+		ret = of_property_read_string(child_node, "qcom,memclk-dual",
+			&info[i].memclk[DUAL_CTX]);
+		if (!ret)
+			pr_debug("Got memclk_dual\n");
+		else
+			info[i].memclk[DUAL_CTX] = NULL;
+
+		ret = of_property_read_string(child_node, "qcom,memclk-active",
+			&info[i].memclk[ACTIVE_CTX]);
+		if (!ret)
+			pr_debug("Got memclk_active\n");
+		else
+			info[i].memclk[ACTIVE_CTX] = NULL;
+
+		ret = of_property_read_string(child_node, "qcom,iface-clk-node",
+			&info[i].iface_clk_node);
+		if (!ret)
+			pr_debug("Got iface_clk_node\n");
+		else
+			info[i].iface_clk_node = NULL;
+
+		pr_debug("Node name: %s\n", info[i].name);
+		of_node_put(child_node);
+		i++;
+	}
+
+	pr_debug("Bus %d added: %d masters\n", pdata->id, pdata->nmasters);
+	pr_debug("Bus %d added: %d slaves\n", pdata->id, pdata->nslaves);
+	return info;
+err:
+	return NULL;
+}
+
+struct msm_bus_fabric_registration
+	*msm_bus_of_get_fab_data(struct platform_device *pdev)
+{
+	struct device_node *of_node = pdev->dev.of_node;
+	struct msm_bus_fabric_registration *pdata;
+	bool mem_err = false;
+	int ret = 0;
+	const char *sel_str;
+
+	if (!pdev) {
+		pr_err("Error: Null platform device\n");
+		return NULL;
+	}
+
+	pdata = devm_kzalloc(&pdev->dev,
+			sizeof(struct msm_bus_fabric_registration), GFP_KERNEL);
+	if (!pdata) {
+		pr_err("Error: Memory allocation for pdata failed\n");
+		mem_err = true;
+		goto err;
+	}
+
+	ret = of_property_read_string(of_node, "label", &pdata->name);
+	if (ret) {
+		pr_err("Error: label not found\n");
+		goto err;
+	}
+	pr_debug("Fab_of: Read name: %s\n", pdata->name);
+
+	ret = of_property_read_u32(of_node, "cell-id",
+		&pdata->id);
+	if (ret) {
+		pr_err("Error: num-usecases not found\n");
+		goto err;
+	}
+	pr_debug("Fab_of: Read id: %u\n", pdata->id);
+
+	if (of_property_read_bool(of_node, "qcom,ahb"))
+		pdata->ahb = 1;
+
+	ret = of_property_read_string(of_node, "qcom,fabclk-dual",
+		&pdata->fabclk[DUAL_CTX]);
+	if (ret) {
+		pr_debug("fabclk_dual not available\n");
+		pdata->fabclk[DUAL_CTX] = NULL;
+	} else
+		pr_debug("Fab_of: Read clk dual ctx: %s\n",
+			pdata->fabclk[DUAL_CTX]);
+	ret = of_property_read_string(of_node, "qcom,fabclk-active",
+		&pdata->fabclk[ACTIVE_CTX]);
+	if (ret) {
+		pr_debug("Error: fabclk_active not available\n");
+		pdata->fabclk[ACTIVE_CTX] = NULL;
+	} else
+		pr_debug("Fab_of: Read clk act ctx: %s\n",
+			pdata->fabclk[ACTIVE_CTX]);
+
+	ret = of_property_read_u32(of_node, "qcom,ntieredslaves",
+		&pdata->ntieredslaves);
+	if (ret) {
+		pr_err("Error: ntieredslaves not found\n");
+		goto err;
+	}
+
+	ret = of_property_read_u32(of_node, "qcom,qos-freq", &pdata->qos_freq);
+	if (ret)
+		pr_debug("qos_freq not available\n");
+
+	ret = of_property_read_string(of_node, "qcom,hw-sel", &sel_str);
+	if (ret) {
+		pr_err("Error: hw_sel not found\n");
+		goto err;
+	} else {
+		ret = get_num(hw_sel_name, sel_str);
+		if (ret < 0)
+			goto err;
+
+		pdata->hw_sel = ret;
+	}
+
+	if (of_property_read_bool(of_node, "qcom,virt"))
+		pdata->virt = true;
+
+	if (of_property_read_bool(of_node, "qcom,rpm-en"))
+		pdata->rpm_enabled = 1;
+
+	pdata->info = get_nodes(of_node, pdev, pdata);
+	return pdata;
+err:
+	return NULL;
+}
+EXPORT_SYMBOL(msm_bus_of_get_fab_data);
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_rpm.c b/arch/arm/mach-msm/msm_bus/msm_bus_rpm.c
index fc38ef7..fd1aacd 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_rpm.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_rpm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_rpm_smd.c b/arch/arm/mach-msm/msm_bus/msm_bus_rpm_smd.c
index 88fab96..7c2b4c9 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_rpm_smd.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_rpm_smd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -101,7 +101,7 @@
 		if (ret) {
 			MSM_BUS_WARN("RPM: Add KVP failed for RPM Req:%u\n",
 				rsc_type);
-			return ret;
+			goto free_rpm_request;
 		}
 
 		MSM_BUS_DBG("Added Key: %d, Val: %llu, size: %d\n", key,
@@ -112,22 +112,26 @@
 		if (ret) {
 			MSM_BUS_WARN("RPM: Add KVP failed for RPM Req:%u\n",
 				rsc_type);
-			return ret;
+			goto free_rpm_request;
 		}
 	}
 
 	msg_id = msm_rpm_send_request(rpm_req);
 	if (!msg_id) {
 		MSM_BUS_WARN("RPM: No message ID for req\n");
-		return -ENXIO;
+		ret = -ENXIO;
+		goto free_rpm_request;
 	}
 
 	ret = msm_rpm_wait_for_ack(msg_id);
 	if (ret) {
 		MSM_BUS_WARN("RPM: Ack failed\n");
-		return ret;
+		goto free_rpm_request;
 	}
 
+free_rpm_request:
+	msm_rpm_free_request(rpm_req);
+
 	return ret;
 }
 
diff --git a/arch/arm/mach-msm/msm_bus/msm_buspm_coresight.c b/arch/arm/mach-msm/msm_bus/msm_buspm_coresight.c
new file mode 100644
index 0000000..6dbe954
--- /dev/null
+++ b/arch/arm/mach-msm/msm_bus/msm_buspm_coresight.c
@@ -0,0 +1,159 @@
+/* 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/clk.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/of_coresight.h>
+#include <linux/coresight.h>
+#include <linux/memory_alloc.h>
+#include <linux/io.h>
+#include <linux/of.h>
+
+struct msmbus_coresight_drvdata {
+	struct device			*dev;
+	struct coresight_device		*csdev;
+	struct clk			*clk;
+	const char			*clk_name;
+	const char			*clknode;
+};
+
+static int msmbus_coresight_enable(struct coresight_device *csdev)
+{
+	struct msmbus_coresight_drvdata *drvdata =
+		dev_get_drvdata(csdev->dev.parent);
+
+	return clk_prepare_enable(drvdata->clk);
+}
+
+static void msmbus_coresight_disable(struct coresight_device *csdev)
+{
+	struct msmbus_coresight_drvdata *drvdata =
+		dev_get_drvdata(csdev->dev.parent);
+
+	clk_disable_unprepare(drvdata->clk);
+}
+
+static const struct coresight_ops_source msmbus_coresight_source_ops = {
+	.enable		= msmbus_coresight_enable,
+	.disable	= msmbus_coresight_disable,
+};
+
+static const struct coresight_ops msmbus_coresight_cs_ops = {
+	.source_ops	= &msmbus_coresight_source_ops,
+};
+
+void msmbus_coresight_remove(struct platform_device *pdev)
+{
+	struct msmbus_coresight_drvdata *drvdata = platform_get_drvdata(pdev);
+
+	msmbus_coresight_disable(drvdata->csdev);
+	coresight_unregister(drvdata->csdev);
+	devm_kfree(&pdev->dev, drvdata);
+	platform_set_drvdata(pdev, NULL);
+}
+EXPORT_SYMBOL(msmbus_coresight_remove);
+
+static int buspm_of_get_clk(struct device_node *of_node,
+	struct msmbus_coresight_drvdata *drvdata)
+{
+	if (of_property_read_string(of_node, "qcom,fabclk-dual",
+						&drvdata->clk_name)) {
+		pr_err("Error: Unable to find clock from of_node\n");
+		return -EINVAL;
+	}
+
+	if (of_property_read_string(of_node, "label", &drvdata->clknode)) {
+		pr_err("Error: Unable to find clock-node from of_node\n");
+		return -EINVAL;
+	}
+
+	drvdata->clk = clk_get_sys(drvdata->clknode, drvdata->clk_name);
+	if (IS_ERR(drvdata->clk)) {
+		pr_err("Error: clk_get_sys failed for: %s\n",
+			drvdata->clknode);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int msmbus_coresight_init(struct platform_device *pdev)
+{
+	int ret;
+	struct device *dev = &pdev->dev;
+	struct coresight_platform_data *pdata;
+	struct msmbus_coresight_drvdata *drvdata;
+	struct coresight_desc *desc;
+
+	if (pdev->dev.of_node) {
+		pdata = of_get_coresight_platform_data(dev, pdev->dev.of_node);
+		if (IS_ERR(pdata))
+			return PTR_ERR(pdata);
+		pdev->dev.platform_data = pdata;
+	}
+
+	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata) {
+		pr_err("coresight: Alloc for drvdata failed\n");
+		return -ENOMEM;
+	}
+
+	drvdata->dev = &pdev->dev;
+	platform_set_drvdata(pdev, drvdata);
+	ret = buspm_of_get_clk(pdev->dev.of_node, drvdata);
+	if (ret) {
+		pr_err("Error getting clocks\n");
+		ret = -ENXIO;
+		goto err1;
+	}
+
+	desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
+	if (!desc) {
+		pr_err("coresight: Error allocating memory\n");
+		ret = -ENOMEM;
+		goto err1;
+	}
+
+	desc->type = CORESIGHT_DEV_TYPE_SOURCE;
+	desc->subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_BUS;
+	desc->ops = &msmbus_coresight_cs_ops;
+	desc->pdata = pdev->dev.platform_data;
+	desc->dev = &pdev->dev;
+	desc->owner = THIS_MODULE;
+	drvdata->csdev = coresight_register(desc);
+	if (IS_ERR(drvdata->csdev)) {
+		pr_err("coresight: Coresight register failed\n");
+		ret = PTR_ERR(drvdata->csdev);
+		goto err0;
+	}
+
+	dev_info(dev, "msmbus_coresight initialized\n");
+
+	return 0;
+err0:
+	devm_kfree(dev, desc);
+err1:
+	devm_kfree(dev, drvdata);
+	platform_set_drvdata(pdev, NULL);
+	return ret;
+}
+EXPORT_SYMBOL(msmbus_coresight_init);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MSM BusPM CoreSight Driver");
diff --git a/arch/arm/mach-msm/msm_cache_dump.c b/arch/arm/mach-msm/msm_cache_dump.c
index 8b4978f..7f6a9b1 100644
--- a/arch/arm/mach-msm/msm_cache_dump.c
+++ b/arch/arm/mach-msm/msm_cache_dump.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/msm_cpr-debug.c b/arch/arm/mach-msm/msm_cpr-debug.c
index 723423c..3564bbe 100644
--- a/arch/arm/mach-msm/msm_cpr-debug.c
+++ b/arch/arm/mach-msm/msm_cpr-debug.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/msm_cpr.h b/arch/arm/mach-msm/msm_cpr.h
index d9c8e9b..e9416c3 100644
--- a/arch/arm/mach-msm/msm_cpr.h
+++ b/arch/arm/mach-msm/msm_cpr.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/msm_dsps.c b/arch/arm/mach-msm/msm_dsps.c
index 0551130..db67f7d 100644
--- a/arch/arm/mach-msm/msm_dsps.c
+++ b/arch/arm/mach-msm/msm_dsps.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/msm_fault_handlers.c b/arch/arm/mach-msm/msm_fault_handlers.c
index c975856..7b2dc8c 100644
--- a/arch/arm/mach-msm/msm_fault_handlers.c
+++ b/arch/arm/mach-msm/msm_fault_handlers.c
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 1995  Linus Torvalds
  *  Modifications for ARM processor (c) 1995-2004 Russell King
- *  Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *  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 as
diff --git a/arch/arm/mach-msm/msm_ipc_router_security.c b/arch/arm/mach-msm/msm_ipc_router_security.c
index 27cf524..69efd13 100644
--- a/arch/arm/mach-msm/msm_ipc_router_security.c
+++ b/arch/arm/mach-msm/msm_ipc_router_security.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
@@ -29,6 +29,7 @@
 #include "ipc_router.h"
 #include "msm_ipc_router_security.h"
 
+#define IRSC_COMPLETION_TIMEOUT_MS 30000
 #define SEC_RULES_HASH_SZ 32
 struct security_rule {
 	struct list_head list;
@@ -36,11 +37,36 @@
 	uint32_t instance_id;
 	unsigned reserved;
 	int num_group_info;
-	int *group_id;
+	gid_t *group_id;
 };
 
 static DEFINE_MUTEX(security_rules_lock);
 static struct list_head security_rules[SEC_RULES_HASH_SZ];
+static DECLARE_COMPLETION(irsc_completion);
+
+/**
+ * wait_for_irsc_completion() - Wait for IPC Router Security Configuration
+ *                              (IRSC) to complete
+ */
+void wait_for_irsc_completion(void)
+{
+	unsigned long rem_jiffies;
+	do {
+		rem_jiffies = wait_for_completion_timeout(&irsc_completion,
+				msecs_to_jiffies(IRSC_COMPLETION_TIMEOUT_MS));
+		if (rem_jiffies)
+			return;
+		pr_err("%s: waiting for IPC Security Conf.\n", __func__);
+	} while (1);
+}
+
+/**
+ * signal_irsc_completion() - Signal the completion of IRSC
+ */
+void signal_irsc_completion(void)
+{
+	complete_all(&irsc_completion);
+}
 
 /**
  * check_permisions() - Check whether the process has permissions to
@@ -72,6 +98,7 @@
 	struct config_sec_rules_args sec_rules_arg;
 	struct security_rule *rule, *temp_rule;
 	int key;
+	int group_info_sz;
 	int ret;
 
 	if (current_euid())
@@ -85,14 +112,20 @@
 	if (sec_rules_arg.num_group_info <= 0)
 		return -EINVAL;
 
+	group_info_sz = sec_rules_arg.num_group_info * sizeof(gid_t);
+	if ((group_info_sz / sizeof(gid_t)) != sec_rules_arg.num_group_info) {
+		pr_err("%s: Integer Overflow %d * %d\n", __func__,
+			sizeof(gid_t), sec_rules_arg.num_group_info);
+		return -EINVAL;
+	}
+
 	rule = kzalloc(sizeof(struct security_rule), GFP_KERNEL);
 	if (!rule) {
 		pr_err("%s: security_rule alloc failed\n", __func__);
 		return -ENOMEM;
 	}
 
-	rule->group_id = kzalloc((sec_rules_arg.num_group_info * sizeof(int)),
-				 GFP_KERNEL);
+	rule->group_id = kzalloc(group_info_sz, GFP_KERNEL);
 	if (!rule->group_id) {
 		pr_err("%s: group_id alloc failed\n", __func__);
 		kfree(rule);
@@ -105,7 +138,7 @@
 	rule->num_group_info = sec_rules_arg.num_group_info;
 	ret = copy_from_user(rule->group_id,
 			     ((void *)(arg + sizeof(sec_rules_arg))),
-			     (rule->num_group_info * sizeof(uint32_t)));
+			     group_info_sz);
 	if (ret) {
 		kfree(rule->group_id);
 		kfree(rule);
diff --git a/arch/arm/mach-msm/msm_ipc_router_security.h b/arch/arm/mach-msm/msm_ipc_router_security.h
index 8701343..9cc61e9 100644
--- a/arch/arm/mach-msm/msm_ipc_router_security.h
+++ b/arch/arm/mach-msm/msm_ipc_router_security.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
@@ -73,6 +73,17 @@
  */
 int msm_ipc_router_security_init(void);
 
+/**
+ * wait_for_irsc_completion() - Wait for IPC Router Security Configuration
+ *                              (IRSC) to complete
+ */
+void wait_for_irsc_completion(void);
+
+/**
+ * signal_irsc_completion() - Signal the completion of IRSC
+ */
+void signal_irsc_completion(void);
+
 #else
 
 static inline int check_permissions(void)
@@ -100,5 +111,10 @@
 {
 	return 0;
 }
+
+static inline void wait_for_irsc_completion(void) { }
+
+static inline void signal_irsc_completion(void) { }
+
 #endif
 #endif
diff --git a/arch/arm/mach-msm/msm_kexec.c b/arch/arm/mach-msm/msm_kexec.c
index 4597cf0..a1b19ff 100644
--- a/arch/arm/mach-msm/msm_kexec.c
+++ b/arch/arm/mach-msm/msm_kexec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/msm_memory_dump.c b/arch/arm/mach-msm/msm_memory_dump.c
index 154b4fe..34f8f59 100644
--- a/arch/arm/mach-msm/msm_memory_dump.c
+++ b/arch/arm/mach-msm/msm_memory_dump.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -13,7 +13,6 @@
 #include <linux/slab.h>
 #include <linux/io.h>
 #include <linux/init.h>
-#include <linux/notifier.h>
 #include <linux/export.h>
 #include <mach/msm_iomap.h>
 #include <mach/msm_memory_dump.h>
@@ -25,17 +24,6 @@
 
 static struct msm_memory_dump mem_dump_data;
 
-static int msm_memory_dump_panic(struct notifier_block *this,
-				unsigned long event, void *ptr)
-{
-	writel_relaxed(0, MSM_IMEM_BASE + DUMP_TABLE_OFFSET);
-	return 0;
-}
-
-static struct notifier_block msm_memory_dump_blk = {
-	.notifier_call  = msm_memory_dump_panic,
-};
-
 int msm_dump_table_register(struct msm_client_dump *client_entry)
 {
 	struct msm_client_dump *entry;
@@ -69,14 +57,6 @@
 	mem_dump_data.dump_table_phys = virt_to_phys(table);
 	writel_relaxed(mem_dump_data.dump_table_phys,
 				MSM_IMEM_BASE + DUMP_TABLE_OFFSET);
-	/* TODO: Write to Debug image IMEM.
-	 * Once IMEM issues are resolved MSM_IMEM_BASE
-	 * will have actual mapping.
-	 */
-	writel_relaxed(mem_dump_data.dump_table_phys,
-				MSM_DBG_IMEM_BASE + DUMP_TABLE_OFFSET);
-	atomic_notifier_chain_register(&panic_notifier_list,
-						&msm_memory_dump_blk);
 	printk(KERN_INFO "MSM Memory Dump table set up\n");
 	return 0;
 }
diff --git a/arch/arm/mach-msm/msm_mpmctr.c b/arch/arm/mach-msm/msm_mpmctr.c
new file mode 100644
index 0000000..4ab82ab
--- /dev/null
+++ b/arch/arm/mach-msm/msm_mpmctr.c
@@ -0,0 +1,99 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/smp.h>
+#include <linux/clk.h>
+#include <linux/cpu.h>
+#include <linux/sched.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <mach/msm_mpmctr.h>
+
+static void __iomem *mpm_timer_base;
+
+uint32_t msm_mpm_get_count(void)
+{
+	uint32_t count;
+	if (!mpm_timer_base)
+		return 0;
+
+	count = __raw_readl_no_log(mpm_timer_base);
+	pr_debug("mpm sclk sync:(%u)", count);
+	return count;
+}
+EXPORT_SYMBOL(msm_mpm_get_count);
+
+static inline void msm_mpmctr_show_count(void)
+{
+	unsigned long long t;
+	unsigned long nsec_rem;
+
+	t = sched_clock();
+
+	nsec_rem = do_div(t, 1000000000)/1000;
+
+	printk(KERN_INFO "mpm_counter: [%5lu.%06lu]:(%u)\n",
+		   (unsigned long)t, nsec_rem,
+		   msm_mpm_get_count());
+
+}
+
+static struct of_device_id msm_mpmctr_of_match[] = {
+	{.compatible = "qcom,mpm-counter"},
+	{}
+};
+
+static struct platform_driver msm_mpmctr_driver = {
+	.driver         = {
+		.name = "msm_mpctr",
+		.owner = THIS_MODULE,
+		.of_match_table = msm_mpmctr_of_match,
+	},
+};
+
+static int __init mpmctr_set_register(struct device_node *np)
+{
+	if (of_get_address(np, 0, NULL, NULL)) {
+		mpm_timer_base = of_iomap(np, 0);
+		if (!mpm_timer_base) {
+			pr_err("%s: cannot map timer base\n", __func__);
+			return -ENOMEM;
+		}
+	}
+	return 0;
+}
+
+static int __init msm_mpmctr_probe(struct platform_device *pdev)
+{
+	if (!pdev->dev.of_node)
+		return -ENODEV;
+
+	if (mpmctr_set_register(pdev->dev.of_node))
+		return -ENODEV;
+
+	msm_mpmctr_show_count();
+
+	return 0;
+}
+
+static int __init mpmctr_init(void)
+{
+	return platform_driver_probe(&msm_mpmctr_driver, msm_mpmctr_probe);
+}
+
+module_init(mpmctr_init)
diff --git a/arch/arm/mach-msm/msm_rq_stats.c b/arch/arm/mach-msm/msm_rq_stats.c
index ea08f4b..d1538dd 100644
--- a/arch/arm/mach-msm/msm_rq_stats.c
+++ b/arch/arm/mach-msm/msm_rq_stats.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -30,6 +30,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/tick.h>
 #include <asm/smp_plat.h>
+#include "acpuclock.h"
 
 #define MAX_LONG_SIZE 24
 #define DEFAULT_RQ_POLL_JIFFIES 1
@@ -196,6 +197,8 @@
 
 	switch (val) {
 	case CPU_ONLINE:
+		if (!this_cpu->cur_freq)
+			this_cpu->cur_freq = acpuclk_get_rate(cpu);
 	case CPU_ONLINE_FROZEN:
 		this_cpu->avg_load_maxfreq = 0;
 	}
@@ -364,6 +367,8 @@
 		mutex_init(&pcpu->cpu_load_mutex);
 		cpufreq_get_policy(&cpu_policy, i);
 		pcpu->policy_max = cpu_policy.cpuinfo.max_freq;
+		if (cpu_online(i))
+			pcpu->cur_freq = acpuclk_get_rate(i);
 		cpumask_copy(pcpu->related_cpus, cpu_policy.cpus);
 	}
 	freq_transition.notifier_call = cpufreq_transition_handler;
diff --git a/arch/arm/mach-msm/msm_rtb.c b/arch/arm/mach-msm/msm_rtb.c
index a60c213..e797e2e 100644
--- a/arch/arm/mach-msm/msm_rtb.c
+++ b/arch/arm/mach-msm/msm_rtb.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/msm_show_resume_irq.c b/arch/arm/mach-msm/msm_show_resume_irq.c
index 8209367..6fc06d5 100644
--- a/arch/arm/mach-msm/msm_show_resume_irq.c
+++ b/arch/arm/mach-msm/msm_show_resume_irq.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/msm_smem_iface.c b/arch/arm/mach-msm/msm_smem_iface.c
index 5ae5772..d08eb5f 100644
--- a/arch/arm/mach-msm/msm_smem_iface.c
+++ b/arch/arm/mach-msm/msm_smem_iface.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/msm_smem_iface.h b/arch/arm/mach-msm/msm_smem_iface.h
index 2daf76d..bc3e73b 100644
--- a/arch/arm/mach-msm/msm_smem_iface.h
+++ b/arch/arm/mach-msm/msm_smem_iface.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/msm_vibrator.c b/arch/arm/mach-msm/msm_vibrator.c
index 5595ba0..9f811ac 100644
--- a/arch/arm/mach-msm/msm_vibrator.c
+++ b/arch/arm/mach-msm/msm_vibrator.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 HTC Corporation.
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/msm_vp.c b/arch/arm/mach-msm/msm_vp.c
index 4404f0a..211e43b 100644
--- a/arch/arm/mach-msm/msm_vp.c
+++ b/arch/arm/mach-msm/msm_vp.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/msm_watchdog.c b/arch/arm/mach-msm/msm_watchdog.c
index aca7667..b1c8b30 100644
--- a/arch/arm/mach-msm/msm_watchdog.c
+++ b/arch/arm/mach-msm/msm_watchdog.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/msm_watchdog.h b/arch/arm/mach-msm/msm_watchdog.h
index 7bf97d9..6818680 100644
--- a/arch/arm/mach-msm/msm_watchdog.h
+++ b/arch/arm/mach-msm/msm_watchdog.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/msm_watchdog_asm.S b/arch/arm/mach-msm/msm_watchdog_asm.S
index c0377d6..ea6cc38 100644
--- a/arch/arm/mach-msm/msm_watchdog_asm.S
+++ b/arch/arm/mach-msm/msm_watchdog_asm.S
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/msm_watchdog_v2.c b/arch/arm/mach-msm/msm_watchdog_v2.c
index f88c611..ef10cdc 100644
--- a/arch/arm/mach-msm/msm_watchdog_v2.c
+++ b/arch/arm/mach-msm/msm_watchdog_v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -41,6 +41,8 @@
 #define SCM_SET_REGSAVE_CMD	0x2
 #define SCM_SVC_SEC_WDOG_DIS	0x7
 
+static struct workqueue_struct *wdog_wq;
+
 struct msm_watchdog_data {
 	unsigned int __iomem phys_base;
 	size_t size;
@@ -50,7 +52,7 @@
 	unsigned int bark_time;
 	unsigned int bark_irq;
 	unsigned int bite_irq;
-	unsigned int do_ipi_ping;
+	bool do_ipi_ping;
 	unsigned long long last_pet;
 	unsigned min_slack_ticks;
 	unsigned long long min_slack_ns;
@@ -213,7 +215,7 @@
 		work_data.wdog_dd = wdog_dd;
 		init_completion(&work_data.complete);
 		INIT_WORK_ONSTACK(&work_data.work, wdog_disable_work);
-		schedule_work_on(0, &work_data.work);
+		queue_work_on(0, wdog_wq, &work_data.work);
 		wait_for_completion(&work_data.complete);
 		mutex_unlock(&wdog_dd->disable_lock);
 	} else {
@@ -288,8 +290,8 @@
 	/* Check again before scheduling *
 	 * Could have been changed on other cpu */
 	if (enable)
-		schedule_delayed_work_on(0, &wdog_dd->dogwork_struct,
-							delay_time);
+		queue_delayed_work_on(0, wdog_wq,
+				&wdog_dd->dogwork_struct, delay_time);
 }
 
 static int msm_watchdog_remove(struct platform_device *pdev)
@@ -303,7 +305,7 @@
 		work_data.wdog_dd = wdog_dd;
 		init_completion(&work_data.complete);
 		INIT_WORK_ONSTACK(&work_data.work, wdog_disable_work);
-		schedule_work_on(0, &work_data.work);
+		queue_work_on(0, wdog_wq, &work_data.work);
 		wait_for_completion(&work_data.complete);
 	}
 	mutex_unlock(&wdog_dd->disable_lock);
@@ -311,6 +313,7 @@
 	if (wdog_dd->irq_ppi)
 		free_percpu(wdog_dd->wdog_cpu_dd);
 	printk(KERN_INFO "MSM Watchdog Exit - Deactivated\n");
+	destroy_workqueue(wdog_wq);
 	kfree(wdog_dd);
 	return 0;
 }
@@ -330,7 +333,14 @@
 		wdog_dd->last_pet, nanosec_rem / 1000);
 	if (wdog_dd->do_ipi_ping)
 		dump_cpu_alive_mask(wdog_dd);
-	panic("Apps watchdog bark received!");
+	printk(KERN_INFO "Causing a watchdog bite!");
+	__raw_writel(1, wdog_dd->base + WDT0_BITE_TIME);
+	mb();
+	__raw_writel(1, wdog_dd->base + WDT0_RST);
+	mb();
+	/* Delay to make sure bite occurs */
+	mdelay(1);
+	panic("Failed to cause a watchdog bite! - Falling back to kernel panic!");
 	return IRQ_HANDLED;
 }
 
@@ -425,7 +435,8 @@
 	atomic_notifier_chain_register(&panic_notifier_list,
 				       &wdog_dd->panic_blk);
 	mutex_init(&wdog_dd->disable_lock);
-	schedule_delayed_work_on(0, &wdog_dd->dogwork_struct, delay_time);
+	queue_delayed_work_on(0, wdog_wq, &wdog_dd->dogwork_struct,
+			delay_time);
 	__raw_writel(1, wdog_dd->base + WDT0_EN);
 	__raw_writel(1, wdog_dd->base + WDT0_RST);
 	wdog_dd->last_pet = sched_clock();
@@ -488,11 +499,7 @@
 		dev_err(&pdev->dev, "reading pet time failed\n");
 		return -ENXIO;
 	}
-	ret = of_property_read_u32(node, "qcom,ipi-ping", &pdata->do_ipi_ping);
-	if (ret) {
-		dev_err(&pdev->dev, "reading do ipi failed\n");
-		return -ENXIO;
-	}
+	pdata->do_ipi_ping = of_property_read_bool(node, "qcom,ipi-ping");
 	if (!pdata->bark_time) {
 		dev_err(&pdev->dev, "%s watchdog bark time not setup\n",
 								__func__);
@@ -503,11 +510,6 @@
 								__func__);
 		return -ENXIO;
 	}
-	if (pdata->do_ipi_ping > 1) {
-		dev_err(&pdev->dev, "%s invalid watchdog ipi value\n",
-								__func__);
-		return -ENXIO;
-	}
 	pdata->irq_ppi = irq_is_per_cpu(pdata->bark_irq);
 	dump_pdata(pdata);
 	return 0;
@@ -518,6 +520,12 @@
 	int ret;
 	struct msm_watchdog_data *wdog_dd;
 
+	wdog_wq = alloc_workqueue("wdog", WQ_HIGHPRI, 0);
+	if (!wdog_wq) {
+		pr_err("Failed to allocate watchdog workqueue\n");
+		return -EIO;
+	}
+
 	if (!pdev->dev.of_node || !enable)
 		return -ENODEV;
 	wdog_dd = kzalloc(sizeof(struct msm_watchdog_data), GFP_KERNEL);
@@ -531,9 +539,10 @@
 	cpumask_clear(&wdog_dd->alive_mask);
 	INIT_WORK(&wdog_dd->init_dogwork_struct, init_watchdog_work);
 	INIT_DELAYED_WORK(&wdog_dd->dogwork_struct, pet_watchdog_work);
-	schedule_work_on(0, &wdog_dd->init_dogwork_struct);
+	queue_work_on(0, wdog_wq, &wdog_dd->init_dogwork_struct);
 	return 0;
 err:
+	destroy_workqueue(wdog_wq);
 	kzfree(wdog_dd);
 	return ret;
 }
diff --git a/arch/arm/mach-msm/msm_xo.c b/arch/arm/mach-msm/msm_xo.c
index 46d4a12..e7c4a6a 100644
--- a/arch/arm/mach-msm/msm_xo.c
+++ b/arch/arm/mach-msm/msm_xo.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/nand_partitions.c b/arch/arm/mach-msm/nand_partitions.c
index 499ad99..ea5fb9c 100644
--- a/arch/arm/mach-msm/nand_partitions.c
+++ b/arch/arm/mach-msm/nand_partitions.c
@@ -4,7 +4,7 @@
  * bootloader.
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2009,2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009,2011 The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/no-pm.c b/arch/arm/mach-msm/no-pm.c
index d460c70..a8d4fdb 100644
--- a/arch/arm/mach-msm/no-pm.c
+++ b/arch/arm/mach-msm/no-pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2010-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
@@ -37,14 +37,11 @@
 
 void msm_pm_set_irq_extns(struct msm_pm_irq_calls *irq_calls) {}
 
-int msm_pm_idle_prepare(struct cpuidle_device *dev,
+enum msm_pm_sleep_mode msm_pm_idle_enter(struct cpuidle_device *dev,
 			struct cpuidle_driver *drv, int index)
 {
 	return -ENOSYS;
 }
 
-int msm_pm_idle_enter(enum msm_pm_sleep_mode sleep_mode)
-{
-	return -ENOSYS;
-}
+void msm_pm_enable_retention(bool enable) {}
 
diff --git a/arch/arm/mach-msm/nohlt.c b/arch/arm/mach-msm/nohlt.c
index 532d57d..e598ed0 100644
--- a/arch/arm/mach-msm/nohlt.c
+++ b/arch/arm/mach-msm/nohlt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/ocmem.c b/arch/arm/mach-msm/ocmem.c
index 34fd8d2..4685f02 100644
--- a/arch/arm/mach-msm/ocmem.c
+++ b/arch/arm/mach-msm/ocmem.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
@@ -359,9 +359,13 @@
 int ocmem_enable_iface_clock(void)
 {
 	int ret;
+
+	if (!ocmem_pdata->iface_clk)
+		return 0;
+
 	ret = clk_prepare_enable(ocmem_pdata->iface_clk);
 	if (ret) {
-		pr_err("ocmem: Failed to disable branch clock\n");
+		pr_err("ocmem: Failed to disable iface clock\n");
 		return ret;
 	}
 	pr_debug("ocmem: Enabled iface clock\n");
@@ -370,31 +374,13 @@
 
 void ocmem_disable_iface_clock(void)
 {
+	if (!ocmem_pdata->iface_clk)
+		return;
+
 	clk_disable_unprepare(ocmem_pdata->iface_clk);
 	pr_debug("ocmem: Disabled iface clock\n");
 }
 
-/* Block-Remapper Clock Operations */
-int ocmem_enable_br_clock(void)
-{
-	int ret;
-
-	ret = clk_prepare_enable(ocmem_pdata->br_clk);
-
-	if (ret) {
-		pr_err("ocmem: Failed to enable br clock\n");
-		return ret;
-	}
-	pr_debug("ocmem: Enabled br clock\n");
-	return 0;
-}
-
-void ocmem_disable_br_clock(void)
-{
-	clk_disable_unprepare(ocmem_pdata->br_clk);
-	pr_debug("ocmem: Disabled br clock\n");
-}
-
 static struct ocmem_plat_data * __devinit parse_dt_config
 						(struct platform_device *pdev)
 {
@@ -411,6 +397,7 @@
 	struct resource *ocmem_mem_io;
 	unsigned nr_parts = 0;
 	unsigned nr_regions = 0;
+	unsigned nr_macros = 0;
 
 	pdata = devm_kzalloc(dev, sizeof(struct ocmem_plat_data),
 			GFP_KERNEL);
@@ -512,6 +499,16 @@
 		return NULL;
 	}
 
+	if (of_property_read_u32(node, "qcom,ocmem-num-macros",
+							 &nr_macros)) {
+		dev_err(dev, "No OCMEM macros specified\n");
+	}
+
+	if (nr_macros == 0) {
+		dev_err(dev, "No hardware macros found\n");
+		return NULL;
+	}
+
 	/* Figure out the number of partititons */
 	nr_parts = of_ocmem_parse_regions(dev, &parts);
 	if (nr_parts <= 0) {
@@ -528,6 +525,7 @@
 	pdata->nr_parts = nr_parts;
 	pdata->parts = parts;
 	pdata->nr_regions = nr_regions;
+	pdata->nr_macros = nr_macros;
 	pdata->ocmem_irq = ocmem_irq->start;
 	pdata->dm_irq = dm_irq->start;
 	return pdata;
@@ -695,7 +693,7 @@
 }
 
 /* Enable the ocmem graphics mpU as a workaround */
-/* This will be programmed by TZ after TZ support is integrated */
+#ifdef CONFIG_MSM_OCMEM_NONSECURE
 static int ocmem_init_gfx_mpu(struct platform_device *pdev)
 {
 	int rc;
@@ -716,6 +714,12 @@
 	ocmem_disable_core_clock();
 	return 0;
 }
+#else
+static int ocmem_init_gfx_mpu(struct platform_device *pdev)
+{
+	return 0;
+}
+#endif /* CONFIG_MSM_OCMEM_NONSECURE */
 
 static int __devinit ocmem_debugfs_init(struct platform_device *pdev)
 {
@@ -743,7 +747,6 @@
 	struct device   *dev = &pdev->dev;
 	struct clk *ocmem_core_clk = NULL;
 	struct clk *ocmem_iface_clk = NULL;
-	struct clk *ocmem_br_clk = NULL;
 
 	if (!pdev->dev.of_node) {
 		dev_info(dev, "Missing Configuration in Device Tree\n");
@@ -777,24 +780,20 @@
 
 	ocmem_iface_clk = devm_clk_get(dev, "iface_clk");
 
-	if (IS_ERR(ocmem_iface_clk)) {
-		dev_err(dev, "Unable to get the memory interface clock\n");
-		return PTR_ERR(ocmem_core_clk);
-	};
+	if (IS_ERR_OR_NULL(ocmem_iface_clk))
+		ocmem_iface_clk = NULL;
 
-	ocmem_br_clk = devm_clk_get(dev, "br_clk");
-
-	if (IS_ERR(ocmem_br_clk)) {
-		dev_err(dev, "Unable to get the BR clock\n");
-		return PTR_ERR(ocmem_br_clk);
-	}
 
 	ocmem_pdata->core_clk = ocmem_core_clk;
 	ocmem_pdata->iface_clk = ocmem_iface_clk;
-	ocmem_pdata->br_clk = ocmem_br_clk;
 
 	platform_set_drvdata(pdev, ocmem_pdata);
 
+	/* Parameter to be updated based on TZ */
+	/* Allow the OCMEM CSR to be programmed */
+	if (ocmem_enable_sec_program(OCMEM_SECURE_DEV_ID))
+		return -EBUSY;
+
 	if (ocmem_debugfs_init(pdev))
 		return -EBUSY;
 
diff --git a/arch/arm/mach-msm/ocmem_allocator.c b/arch/arm/mach-msm/ocmem_allocator.c
index 71cacda..203bb60 100644
--- a/arch/arm/mach-msm/ocmem_allocator.c
+++ b/arch/arm/mach-msm/ocmem_allocator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/ocmem_api.c b/arch/arm/mach-msm/ocmem_api.c
index 8b56775..16dd8b8 100644
--- a/arch/arm/mach-msm/ocmem_api.c
+++ b/arch/arm/mach-msm/ocmem_api.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -52,9 +52,10 @@
 	ret = process_free(id, handle);
 	mutex_unlock(&handle->handle_mutex);
 
-	if (ret)
-		return -EINVAL;
-
+	if (ret) {
+		pr_err("ocmem: Free failed for client %s\n", get_name(id));
+		return ret;
+	}
 	free_handle(handle);
 	return 0;
 }
@@ -400,6 +401,40 @@
 }
 EXPORT_SYMBOL(ocmem_unmap);
 
+int ocmem_drop(int client_id, struct ocmem_buf *buffer,
+			   struct ocmem_map_list *list)
+{
+	int ret = 0;
+	struct ocmem_handle *handle = NULL;
+
+	if (!check_id(client_id)) {
+		pr_err("ocmem: Invalid client id: %d\n", client_id);
+		return -EINVAL;
+	}
+
+	if (!zone_active(client_id)) {
+		pr_err("ocmem: Client id: %s (id: %d) not allowed to use OCMEM\n",
+					get_name(client_id), client_id);
+		return -EINVAL;
+	}
+
+	if (!buffer) {
+		pr_err("ocmem: Invalid buffer\n");
+		return -EINVAL;
+	}
+
+	if (pre_validate_chunk_list(list) != 0)
+		return -EINVAL;
+
+	handle = buffer_to_handle(buffer);
+	mutex_lock(&handle->handle_mutex);
+	ret = process_drop(client_id, handle, list);
+	mutex_unlock(&handle->handle_mutex);
+	return ret;
+}
+EXPORT_SYMBOL(ocmem_drop);
+
+
 int ocmem_dump(int client_id, struct ocmem_buf *buffer,
 			unsigned long dst_phys_addr)
 {
diff --git a/arch/arm/mach-msm/ocmem_core.c b/arch/arm/mach-msm/ocmem_core.c
index 3d9639f..4ea1de9 100644
--- a/arch/arm/mach-msm/ocmem_core.c
+++ b/arch/arm/mach-msm/ocmem_core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -17,6 +17,7 @@
 
 #include <mach/ocmem_priv.h>
 #include <mach/rpm-smd.h>
+#include <mach/scm.h>
 
 static unsigned num_regions;
 static unsigned num_macros;
@@ -49,7 +50,6 @@
 static struct mutex region_ctrl_lock;
 static void *ocmem_base;
 
-#define OCMEM_V1_REGIONS 3
 #define OCMEM_V1_MACROS 8
 #define OCMEM_V1_MACRO_SZ (SZ_64K)
 
@@ -488,7 +488,7 @@
 	if (mpu_start < 0)
 		/* Avoid underflow */
 		mpu_start = 0;
-	mpu_end = ((offset+len) >> GFX_MPU_SHIFT) - 1;
+	mpu_end = ((offset+len) >> GFX_MPU_SHIFT);
 	BUG_ON(mpu_end < 0);
 
 	pr_debug("ocmem: mpu: start %x end %x\n", mpu_start, mpu_end);
@@ -515,6 +515,23 @@
 	ocmem_clear(offset, len);
 	return 0;
 }
+
+int ocmem_enable_sec_program(int sec_id)
+{
+	return 0;
+}
+
+int ocmem_enable_dump(enum ocmem_client id, unsigned long offset,
+			unsigned long len)
+{
+	return 0;
+}
+
+int ocmem_disable_dump(enum ocmem_client id, unsigned long offset,
+			unsigned long len)
+{
+	return 0;
+}
 #else
 static int ocmem_gfx_mpu_set(unsigned long offset, unsigned long len)
 {
@@ -533,19 +550,117 @@
 static int do_lock(enum ocmem_client id, unsigned long offset,
 			unsigned long len, enum region_mode mode)
 {
-	return 0;
+	int rc;
+	struct ocmem_tz_lock {
+		u32 id;
+		u32 offset;
+		u32 size;
+	} request;
+
+	request.id = get_tz_id(id);
+	request.offset = offset;
+	request.size = len;
+
+	rc = scm_call(OCMEM_SVC_ID, OCMEM_LOCK_CMD_ID, &request,
+				sizeof(request), NULL, 0);
+	if (rc)
+		pr_err("ocmem: Failed to lock region %s[%lx -- %lx] ret = %d\n",
+				get_name(id), offset, offset + len - 1, rc);
+	return rc;
 }
 
 static int do_unlock(enum ocmem_client id, unsigned long offset,
 			unsigned long len)
 {
-	return 0;
+	int rc;
+	struct ocmem_tz_unlock {
+		u32 id;
+		u32 offset;
+		u32 size;
+	} request;
+
+	request.id = get_tz_id(id);
+	request.offset = offset;
+	request.size = len;
+
+	rc = scm_call(OCMEM_SVC_ID, OCMEM_UNLOCK_CMD_ID, &request,
+				sizeof(request), NULL, 0);
+	if (rc)
+		pr_err("ocmem: Failed to unlock region %s[%lx -- %lx] ret = %d\n",
+				get_name(id), offset, offset + len - 1, rc);
+	return rc;
+}
+
+int ocmem_enable_dump(enum ocmem_client id, unsigned long offset,
+			unsigned long len)
+{
+	int rc;
+	struct ocmem_tz_en_dump {
+		u32 id;
+		u32 offset;
+		u32 size;
+	} request;
+
+	request.id = get_tz_id(id);
+	request.offset = offset;
+	request.size = len;
+
+	rc = scm_call(OCMEM_SVC_ID, OCMEM_ENABLE_DUMP_CMD_ID, &request,
+				sizeof(request), NULL, 0);
+	if (rc)
+		pr_err("ocmem: Failed to enable dump %s[%lx -- %lx] ret = %d\n",
+				get_name(id), offset, offset + len - 1, rc);
+	return rc;
+}
+
+int ocmem_disable_dump(enum ocmem_client id, unsigned long offset,
+			unsigned long len)
+{
+	int rc;
+	struct ocmem_tz_dis_dump {
+		u32 id;
+		u32 offset;
+		u32 size;
+	} request;
+
+	request.id = get_tz_id(id);
+	request.offset = offset;
+	request.size = len;
+
+	rc = scm_call(OCMEM_SVC_ID, OCMEM_DISABLE_DUMP_CMD_ID, &request,
+				sizeof(request), NULL, 0);
+	if (rc)
+		pr_err("ocmem: Failed to disable dump %s[%lx -- %lx] ret = %d\n",
+				get_name(id), offset, offset + len - 1, rc);
+	return rc;
+}
+
+int ocmem_enable_sec_program(int sec_id)
+{
+	int rc, scm_ret = 0;
+	struct msm_scm_sec_cfg {
+		unsigned int id;
+		unsigned int spare;
+	} cfg;
+
+	cfg.id = sec_id;
+
+	rc = scm_call(OCMEM_SECURE_SVC_ID, OCMEM_SECURE_CFG_ID, &cfg,
+			sizeof(cfg), &scm_ret, sizeof(scm_ret));
+
+	if (rc || scm_ret) {
+		pr_err("ocmem: Failed to enable secure programming\n");
+		return rc ? rc : -EINVAL;
+	}
+
+	return rc;
 }
 #endif /* CONFIG_MSM_OCMEM_NONSECURE */
 
 int ocmem_lock(enum ocmem_client id, unsigned long offset, unsigned long len,
 					enum region_mode mode)
 {
+	int rc = 0;
 
 	if (len < OCMEM_MIN_ALLOC) {
 		pr_err("ocmem: Invalid len %lx for lock\n", len);
@@ -562,27 +677,38 @@
 
 	commit_region_modes();
 
-	do_lock(id, offset, len, mode);
+	rc = do_lock(id, offset, len, mode);
+	if (rc)
+		goto lock_fail;
 
 	mutex_unlock(&region_ctrl_lock);
 	return 0;
-
+lock_fail:
+	switch_region_mode(offset, len, MODE_DEFAULT);
 switch_region_fail:
+	ocmem_gfx_mpu_remove();
 	mutex_unlock(&region_ctrl_lock);
 	return -EINVAL;
 }
 
 int ocmem_unlock(enum ocmem_client id, unsigned long offset, unsigned long len)
 {
+	int rc = 0;
+
 	if (id == OCMEM_GRAPHICS)
 		ocmem_gfx_mpu_remove();
 
 	mutex_lock(&region_ctrl_lock);
-	do_unlock(id, offset, len);
+	rc = do_unlock(id, offset, len);
+	if (rc)
+		goto unlock_fail;
 	switch_region_mode(offset, len , MODE_DEFAULT);
 	commit_region_modes();
 	mutex_unlock(&region_ctrl_lock);
 	return 0;
+unlock_fail:
+	mutex_unlock(&region_ctrl_lock);
+	return -EINVAL;
 }
 
 #if defined(CONFIG_MSM_OCMEM_POWER_DISABLE)
@@ -599,9 +725,6 @@
 	if (rc < 0)
 		return rc;
 
-	rc = ocmem_enable_br_clock();
-	if (rc < 0)
-		return rc;
 	return 0;
 }
 
@@ -964,30 +1087,19 @@
 
 	hw_ver = ocmem_read(ocmem_base + OC_HW_PROFILE);
 
-	if (pdata->nr_regions != OCMEM_V1_REGIONS) {
-		pr_err("Invalid number of regions (%d)\n", pdata->nr_regions);
-		goto hw_not_supported;
-	}
-
 	num_macros = (hw_ver & NUM_MACROS_MASK) >> NUM_MACROS_SHIFT;
 	num_ports = (hw_ver & NUM_PORTS_MASK) >> NUM_PORTS_SHIFT;
 
-	if (num_macros != OCMEM_V1_MACROS) {
+	if (num_macros != pdata->nr_macros) {
 		pr_err("Invalid number of macros (%d)\n", pdata->nr_macros);
 		goto hw_not_supported;
 	}
 
 	interleaved = (hw_ver & INTERLEAVING_MASK) >> INTERLEAVING_SHIFT;
 
-	if (interleaved == false) {
-		pr_err("Interleaving is disabled\n");
-		goto hw_not_supported;
-	}
-
 	num_regions = pdata->nr_regions;
 
 	pdata->interleaved = true;
-	pdata->nr_macros = num_macros;
 	pdata->nr_ports = num_ports;
 	macro_size = OCMEM_V1_MACRO_SZ * 2;
 	num_banks = num_ports / 2;
diff --git a/arch/arm/mach-msm/ocmem_notifier.c b/arch/arm/mach-msm/ocmem_notifier.c
index 644c809..e7271a9 100644
--- a/arch/arm/mach-msm/ocmem_notifier.c
+++ b/arch/arm/mach-msm/ocmem_notifier.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/ocmem_rdm.c b/arch/arm/mach-msm/ocmem_rdm.c
index 8962729..4ff7212 100644
--- a/arch/arm/mach-msm/ocmem_rdm.c
+++ b/arch/arm/mach-msm/ocmem_rdm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -206,6 +206,11 @@
 		return rc;
 	}
 
+	/* Clear DM Mask */
+	ocmem_write(DM_MASK_RESET, dm_base + DM_INTR_MASK);
+	/* Clear DM Interrupts */
+	ocmem_write(DM_INTR_RESET, dm_base + DM_INTR_CLR);
+
 	for (i = 0, j = slot; i < num_chunks; i++, j++) {
 
 		struct ocmem_chunk *chunk = &clist->chunks[i];
@@ -296,10 +301,6 @@
 
 	init_completion(&dm_clear_event);
 	init_completion(&dm_transfer_event);
-	/* Clear DM Mask */
-	ocmem_write(DM_MASK_RESET, dm_base + DM_INTR_MASK);
-	/* enable dm interrupts */
-	ocmem_write(DM_INTR_RESET, dm_base + DM_INTR_CLR);
 	ocmem_disable_core_clock();
 	return 0;
 }
diff --git a/arch/arm/mach-msm/ocmem_sched.c b/arch/arm/mach-msm/ocmem_sched.c
index 37dec30..868fd1a 100644
--- a/arch/arm/mach-msm/ocmem_sched.c
+++ b/arch/arm/mach-msm/ocmem_sched.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -25,16 +25,19 @@
 #include <mach/ocmem_priv.h>
 
 enum request_states {
-	R_FREE = 0x0,	/* request is not allocated */
-	R_PENDING,	/* request has a pending operation */
-	R_ALLOCATED,	/* request has been allocated */
-	R_MUST_GROW,	/* request must grow as a part of pending operation */
-	R_MUST_SHRINK,	/* request must shrink as a part of pending operation */
-	R_MUST_MAP,	/* request must be mapped before being used */
-	R_MUST_UNMAP,	/* request must be unmapped when not being used */
-	R_MAPPED,	/* request is mapped and actively used by client */
-	R_UNMAPPED,	/* request is not mapped, so it's not in active use */
-	R_EVICTED,	/* request is evicted and must be restored */
+	R_FREE = 0x0,   /* request is not allocated */
+	R_PENDING,      /* request has a pending operation */
+	R_ALLOCATED,    /* request has been allocated */
+	R_ENQUEUED,     /* request has been enqueued for future retry */
+	R_MUST_GROW,    /* request must grow as a part of pending operation */
+	R_MUST_SHRINK,  /* request must shrink */
+	R_WF_SHRINK,    /* shrink must be ack'ed by a client */
+	R_SHRUNK,       /* request was shrunk */
+	R_MUST_MAP,     /* request must be mapped before being used */
+	R_MUST_UNMAP,   /* request must be unmapped when not being used */
+	R_MAPPED,       /* request is mapped and actively used by client */
+	R_UNMAPPED,     /* request is not mapped, so it's not in active use */
+	R_EVICTED,      /* request is evicted and must be restored */
 };
 
 #define SET_STATE(x, val) (set_bit((val), &(x)->state))
@@ -109,6 +112,16 @@
 	OCMEM_SYSNOC = 3,
 };
 
+enum ocmem_tz_client {
+	TZ_UNUSED = 0x0,
+	TZ_GRAPHICS,
+	TZ_VIDEO,
+	TZ_LP_AUDIO,
+	TZ_SENSORS,
+	TZ_OTHER_OS,
+	TZ_DEBUG,
+};
+
 /**
  * Primary OCMEM Arbitration Table
  **/
@@ -117,20 +130,30 @@
 	int priority;
 	int mode;
 	int hw_interconnect;
+	int tz_id;
 } ocmem_client_table[OCMEM_CLIENT_MAX] = {
-	{OCMEM_GRAPHICS, PRIO_GFX, OCMEM_PERFORMANCE, OCMEM_PORT},
-	{OCMEM_VIDEO, PRIO_VIDEO, OCMEM_PERFORMANCE, OCMEM_OCMEMNOC},
-	{OCMEM_CAMERA, NO_PRIO, OCMEM_PERFORMANCE, OCMEM_OCMEMNOC},
-	{OCMEM_HP_AUDIO, PRIO_HP_AUDIO, OCMEM_PASSIVE, OCMEM_BLOCKED},
-	{OCMEM_VOICE, PRIO_VOICE, OCMEM_PASSIVE, OCMEM_BLOCKED},
-	{OCMEM_LP_AUDIO, PRIO_LP_AUDIO, OCMEM_LOW_POWER, OCMEM_SYSNOC},
-	{OCMEM_SENSORS, PRIO_SENSORS, OCMEM_LOW_POWER, OCMEM_SYSNOC},
-	{OCMEM_OTHER_OS, PRIO_OTHER_OS, OCMEM_LOW_POWER, OCMEM_SYSNOC},
+	{OCMEM_GRAPHICS, PRIO_GFX, OCMEM_PERFORMANCE, OCMEM_PORT,
+								TZ_GRAPHICS},
+	{OCMEM_VIDEO, PRIO_VIDEO, OCMEM_PERFORMANCE, OCMEM_OCMEMNOC,
+								TZ_VIDEO},
+	{OCMEM_CAMERA, NO_PRIO, OCMEM_PERFORMANCE, OCMEM_OCMEMNOC,
+								TZ_UNUSED},
+	{OCMEM_HP_AUDIO, PRIO_HP_AUDIO, OCMEM_PASSIVE, OCMEM_BLOCKED,
+								TZ_UNUSED},
+	{OCMEM_VOICE, PRIO_VOICE, OCMEM_PASSIVE, OCMEM_BLOCKED,
+								TZ_UNUSED},
+	{OCMEM_LP_AUDIO, PRIO_LP_AUDIO, OCMEM_LOW_POWER, OCMEM_SYSNOC,
+								TZ_LP_AUDIO},
+	{OCMEM_SENSORS, PRIO_SENSORS, OCMEM_LOW_POWER, OCMEM_SYSNOC,
+								TZ_SENSORS},
+	{OCMEM_OTHER_OS, PRIO_OTHER_OS, OCMEM_LOW_POWER, OCMEM_SYSNOC,
+								TZ_OTHER_OS},
 };
 
 static struct rb_root sched_tree;
 static struct mutex sched_mutex;
 static struct mutex allocation_mutex;
+static struct mutex free_mutex;
 
 /* A region represents a continuous interval in OCMEM address space */
 struct ocmem_region {
@@ -225,6 +248,14 @@
 							WIDE_MODE : THIN_MODE;
 }
 
+inline int get_tz_id(int id)
+{
+	if (!check_id(id))
+		return TZ_UNUSED;
+	else
+		return ocmem_client_table[id].tz_id;
+}
+
 /* Returns the address that can be used by a device core to access OCMEM */
 static unsigned long device_address(int id, unsigned long addr)
 {
@@ -489,12 +520,21 @@
 	return TEST_STATE(req, R_MAPPED);
 }
 
+static inline int is_pending_shrink(struct ocmem_req *req)
+{
+	return TEST_STATE(req, R_MUST_SHRINK) ||
+		TEST_STATE(req, R_WF_SHRINK);
+}
+
 /* Must be called with sched_mutex held */
 static int __sched_unmap(struct ocmem_req *req)
 {
 	struct ocmem_req *matched_req = NULL;
 	struct ocmem_region *matched_region = NULL;
 
+	if (!TEST_STATE(req, R_MAPPED))
+		goto invalid_op_error;
+
 	matched_region = find_region_match(req->req_start, req->req_end);
 	matched_req = find_req_match(req->req_id, matched_region);
 
@@ -606,13 +646,6 @@
 			goto iface_clock_fail;
 	}
 
-	if (is_remapped_access(req->owner)) {
-		rc = ocmem_enable_br_clock();
-
-		if (rc < 0)
-			goto br_clock_fail;
-	}
-
 	rc = ocmem_lock(req->owner, phys_to_offset(req->req_start), req->req_sz,
 							get_mode(req->owner));
 
@@ -636,9 +669,6 @@
 process_map_fail:
 	ocmem_unlock(req->owner, phys_to_offset(req->req_start), req->req_sz);
 lock_failed:
-	if (is_remapped_access(req->owner))
-		ocmem_disable_br_clock();
-br_clock_fail:
 	if (is_iface_access(req->owner))
 		ocmem_disable_iface_clock();
 iface_clock_fail:
@@ -667,8 +697,6 @@
 		goto unlock_failed;
 	}
 
-	if (is_remapped_access(req->owner))
-		ocmem_disable_br_clock();
 	if (is_iface_access(req->owner))
 		ocmem_disable_iface_clock();
 	ocmem_disable_core_clock();
@@ -1036,8 +1064,8 @@
 
 	retry = false;
 
-	pr_debug("ocmem: do_allocate: %s request size %lx\n",
-						get_name(owner), sz);
+	pr_debug("ocmem: do_allocate: %s request %p size %lx\n",
+						get_name(owner), req, sz);
 
 retry_next_step:
 
@@ -1158,14 +1186,34 @@
 	return OP_FAIL;
 }
 
+/* Remove the request from eviction lists */
+static void cancel_restore(struct ocmem_req *e_handle,
+				struct ocmem_req *req)
+{
+	struct ocmem_eviction_data *edata = e_handle->edata;
+
+	if (!edata || !req)
+		return;
+
+	if (list_empty(&edata->req_list))
+		return;
+
+	list_del_init(&req->eviction_list);
+	req->e_handle = NULL;
+
+	return;
+}
+
 static int sched_enqueue(struct ocmem_req *priv)
 {
 	struct ocmem_req *next = NULL;
 	mutex_lock(&sched_queue_mutex);
+	SET_STATE(priv, R_ENQUEUED);
 	list_add_tail(&priv->sched_list, &sched_queue[priv->owner]);
 	pr_debug("enqueued req %p\n", priv);
 	list_for_each_entry(next, &sched_queue[priv->owner], sched_list) {
-		pr_debug("pending requests for client %p\n", next);
+		pr_debug("pending request %p for client %s\n", next,
+				get_name(next->owner));
 	}
 	mutex_unlock(&sched_queue_mutex);
 	return 0;
@@ -1190,13 +1238,13 @@
 	list_for_each_entry_safe(req, next, &sched_queue[id], sched_list)
 	{
 		if (req == victim_req) {
-			pr_debug("ocmem: Cancelling pending request %p\n",
-							req);
-			list_del(&req->sched_list);
-			goto dequeue_done;
+			pr_debug("ocmem: Cancelling pending request %p for %s\n",
+						req, get_name(req->owner));
+			list_del_init(&victim_req->sched_list);
+			CLEAR_STATE(victim_req, R_ENQUEUED);
+			break;
 		}
 	}
-
 dequeue_done:
 	mutex_unlock(&sched_queue_mutex);
 	return;
@@ -1218,7 +1266,8 @@
 				pr_debug("ocmem: Fetched pending request %p\n",
 									req);
 				list_del(&req->sched_list);
-			break;
+				CLEAR_STATE(req, R_ENQUEUED);
+				break;
 			}
 		}
 	}
@@ -1412,37 +1461,70 @@
 	unsigned long offset = 0;
 	int rc = 0;
 
+	mutex_lock(&free_mutex);
+
 	if (is_blocked(id)) {
 		pr_err("Client %d cannot request free\n", id);
-		return -EINVAL;
+		goto free_invalid;
 	}
 
 	req = handle_to_req(handle);
 	buffer = handle_to_buffer(handle);
 
-	if (!req)
-		return -EINVAL;
+	if (!req) {
+		pr_err("ocmem: No valid request to free\n");
+		goto free_invalid;
+	}
 
 	if (req->req_start != core_address(id, buffer->addr)) {
 		pr_err("Invalid buffer handle passed for free\n");
-		return -EINVAL;
+		goto free_invalid;
 	}
 
-	mutex_lock(&sched_mutex);
-	sched_dequeue(req);
-	mutex_unlock(&sched_mutex);
+	if (req->edata != NULL) {
+		pr_err("ocmem: Request %p(%2lx) yet to process eviction %p\n",
+					req, req->state, req->edata);
+		goto free_invalid;
+	}
+
+	if (is_pending_shrink(req)) {
+		pr_err("ocmem: Request %p(%2lx) yet to process eviction\n",
+					req, req->state);
+		goto pending_shrink;
+	}
+
+	/* Remove the request from any restore lists */
+	if (req->e_handle)
+		cancel_restore(req->e_handle, req);
+
+	/* Remove the request from any pending opreations */
+	if (TEST_STATE(req, R_ENQUEUED)) {
+		mutex_lock(&sched_mutex);
+		sched_dequeue(req);
+		mutex_unlock(&sched_mutex);
+	}
 
 	if (!TEST_STATE(req, R_FREE)) {
 
-		rc = process_unmap(req, req->req_start, req->req_end);
-		if (rc < 0)
-			return -EINVAL;
+		if (TEST_STATE(req, R_MAPPED)) {
+			/* unmap the interval and clear the memory */
+			rc = process_unmap(req, req->req_start, req->req_end);
 
-		rc = do_free(req);
-		if (rc < 0)
-			return -EINVAL;
+			if (rc < 0) {
+				pr_err("ocmem: Failed to unmap %p\n", req);
+				goto free_fail;
+			}
+
+			rc = do_free(req);
+			if (rc < 0) {
+				pr_err("ocmem: Failed to free %p\n", req);
+				goto free_fail;
+			}
+		} else
+			pr_debug("request %p was already shrunk to 0\n", req);
 	}
 
+	/* Turn off the memory */
 	if (req->req_sz != 0) {
 
 		offset = phys_to_offset(req->req_start);
@@ -1451,18 +1533,33 @@
 
 		if (rc < 0) {
 			pr_err("Failed to switch OFF memory macros\n");
-			return -EINVAL;
+			goto free_fail;
 		}
 
 	}
 
+	if (!TEST_STATE(req, R_FREE)) {
+		/* free the allocation */
+		rc = do_free(req);
+		if (rc < 0)
+			return -EINVAL;
+	}
+
 	inc_ocmem_stat(zone_of(req), NR_FREES);
 
 	ocmem_destroy_req(req);
 	handle->req = NULL;
 
 	ocmem_schedule_pending();
+	mutex_unlock(&free_mutex);
 	return 0;
+free_fail:
+free_invalid:
+	mutex_unlock(&free_mutex);
+	return -EINVAL;
+pending_shrink:
+	mutex_unlock(&free_mutex);
+	return -EAGAIN;
 }
 
 static void ocmem_rdm_worker(struct work_struct *work)
@@ -1512,6 +1609,42 @@
 	return 0;
 }
 
+int process_drop(int id, struct ocmem_handle *handle,
+				 struct ocmem_map_list *list)
+{
+	struct ocmem_req *req = NULL;
+	struct ocmem_buf *buffer = NULL;
+	int rc = 0;
+
+	if (is_blocked(id)) {
+		pr_err("Client %d cannot request drop\n", id);
+		return -EINVAL;
+	}
+
+	if (is_tcm(id))
+		pr_err("Client %d cannot request drop\n", id);
+
+	req = handle_to_req(handle);
+	buffer = handle_to_buffer(handle);
+
+	if (!req)
+		return -EINVAL;
+
+	if (req->req_start != core_address(id, buffer->addr)) {
+		pr_err("Invalid buffer handle passed for drop\n");
+		return -EINVAL;
+	}
+
+	if (TEST_STATE(req, R_MAPPED)) {
+		rc = process_unmap(req, req->req_start, req->req_end);
+		if (rc < 0)
+			return -EINVAL;
+	} else
+		return -EINVAL;
+
+	return 0;
+}
+
 int process_xfer_out(int id, struct ocmem_handle *handle,
 			struct ocmem_map_list *list)
 {
@@ -1560,7 +1693,6 @@
 		goto transfer_in_error;
 	}
 
-
 	inc_ocmem_stat(zone_of(req), NR_TRANSFERS_TO_OCMEM);
 	rc = queue_transfer(req, handle, list, TO_OCMEM);
 
@@ -1593,16 +1725,23 @@
 	if (!req)
 		return -EINVAL;
 
+	mutex_lock(&free_mutex);
+
 	if (req->req_start != core_address(id, buffer->addr)) {
 		pr_err("Invalid buffer handle passed for shrink\n");
-		return -EINVAL;
+		goto shrink_fail;
 	}
 
-	edata = req->edata;
+	if (!req->e_handle) {
+		pr_err("Unable to find evicting request\n");
+		goto shrink_fail;
+	}
+
+	edata = req->e_handle->edata;
 
 	if (!edata) {
 		pr_err("Unable to find eviction data\n");
-		return -EINVAL;
+		goto shrink_fail;
 	}
 
 	pr_debug("Found edata %p in request %p\n", edata, req);
@@ -1611,29 +1750,37 @@
 
 	if (size == 0) {
 		pr_debug("req %p being shrunk to zero\n", req);
-		if (is_mapped(req))
+		if (is_mapped(req)) {
 			rc = process_unmap(req, req->req_start, req->req_end);
 			if (rc < 0)
-				return -EINVAL;
+				goto shrink_fail;
+		}
 		rc = do_free(req);
 		if (rc < 0)
-			return -EINVAL;
+			goto shrink_fail;
+		SET_STATE(req, R_FREE);
 	} else {
 		rc = do_shrink(req, size);
 		if (rc < 0)
-			return -EINVAL;
+			goto shrink_fail;
 	}
 
-	req->edata = NULL;
 	CLEAR_STATE(req, R_ALLOCATED);
-	SET_STATE(req, R_FREE);
+	CLEAR_STATE(req, R_WF_SHRINK);
+	SET_STATE(req, R_SHRUNK);
 
 	if (atomic_dec_and_test(&edata->pending)) {
 		pr_debug("ocmem: All conflicting allocations were shrunk\n");
 		complete(&edata->completion);
 	}
 
+	mutex_unlock(&free_mutex);
 	return 0;
+shrink_fail:
+	pr_err("ocmem: Failed to shrink request %p of %s\n",
+			req, get_name(req->owner));
+	mutex_unlock(&free_mutex);
+	return -EINVAL;
 }
 
 int process_xfer(int id, struct ocmem_handle *handle,
@@ -1738,11 +1885,12 @@
 				if (needs_eviction) {
 					pr_debug("adding %p in region %p to eviction list\n",
 							e_req, tmp_region);
+					SET_STATE(e_req, R_MUST_SHRINK);
 					list_add_tail(
 						&e_req->eviction_list,
 						&edata->req_list);
 					atomic_inc(&edata->pending);
-					e_req->edata = edata;
+					e_req->e_handle = req;
 				}
 			}
 		} else {
@@ -1752,9 +1900,7 @@
 
 	pr_debug("%d requests will be evicted\n", atomic_read(&edata->pending));
 
-	if (!atomic_read(&edata->pending))
-		return -EINVAL;
-	return 0;
+	return atomic_read(&edata->pending);
 }
 
 static void trigger_eviction(struct ocmem_eviction_data *edata)
@@ -1776,8 +1922,10 @@
 			pr_debug("ocmem: Evicting request %p\n", req);
 			buffer.addr = req->req_start;
 			buffer.len = 0x0;
+			CLEAR_STATE(req, R_MUST_SHRINK);
 			dispatch_notification(req->owner, OCMEM_ALLOC_SHRINK,
 								&buffer);
+			SET_STATE(req, R_WF_SHRINK);
 		}
 	}
 	return;
@@ -1799,7 +1947,7 @@
 
 	rc = __evict_common(edata, NULL);
 
-	if (rc < 0)
+	if (rc == 0)
 		goto skip_eviction;
 
 	trigger_eviction(edata);
@@ -1833,9 +1981,10 @@
 
 	edata->passive = false;
 
+	mutex_lock(&free_mutex);
 	rc = __evict_common(edata, req);
 
-	if (rc < 0)
+	if (rc == 0)
 		goto skip_eviction;
 
 	trigger_eviction(edata);
@@ -1843,6 +1992,8 @@
 	pr_debug("ocmem: attaching eviction %p to request %p", edata, req);
 	req->edata = edata;
 
+	mutex_unlock(&free_mutex);
+
 	wait_for_completion(&edata->completion);
 
 	pr_debug("ocmem: eviction completed successfully\n");
@@ -1851,28 +2002,30 @@
 skip_eviction:
 	pr_err("ocmem: Unable to run eviction\n");
 	free_eviction(edata);
-	return -EINVAL;
+	req->edata = NULL;
+	mutex_unlock(&free_mutex);
+	return 0;
 }
 
 static int __restore_common(struct ocmem_eviction_data *edata)
 {
 
 	struct ocmem_req *req = NULL;
-	struct ocmem_req *next = NULL;
 
 	if (!edata)
 		return -EINVAL;
 
-	list_for_each_entry_safe(req, next, &edata->req_list, eviction_list)
-	{
-		if (req) {
-			pr_debug("ocmem: restoring evicted request %p\n",
-								req);
-			list_del(&req->eviction_list);
-			req->op = SCHED_ALLOCATE;
-			sched_enqueue(req);
-			inc_ocmem_stat(zone_of(req), NR_RESTORES);
-		}
+	while (!list_empty(&edata->req_list)) {
+		req = list_first_entry(&edata->req_list, struct ocmem_req,
+						eviction_list);
+		list_del_init(&req->eviction_list);
+		pr_debug("ocmem: restoring evicted request %p\n",
+							req);
+		req->edata = NULL;
+		req->e_handle = NULL;
+		req->op = SCHED_ALLOCATE;
+		inc_ocmem_stat(zone_of(req), NR_RESTORES);
+		sched_enqueue(req);
 	}
 
 	pr_debug("Scheduled all evicted regions\n");
@@ -1891,12 +2044,15 @@
 	if (!req->edata)
 		return 0;
 
+	mutex_lock(&free_mutex);
 	rc = __restore_common(req->edata);
+	mutex_unlock(&free_mutex);
 
 	if (rc < 0)
 		return -EINVAL;
 
 	free_eviction(req->edata);
+	req->edata = NULL;
 	return 0;
 }
 
@@ -1908,7 +2064,9 @@
 	if (!edata)
 		return -EINVAL;
 
+	mutex_lock(&free_mutex);
 	rc = __restore_common(edata);
+	mutex_unlock(&free_mutex);
 
 	if (rc < 0) {
 		pr_err("Failed to restore evicted requests\n");
@@ -1994,6 +2152,7 @@
 
 	void __iomem *req_vaddr;
 	unsigned long offset = 0x0;
+	int rc = 0;
 
 	down_write(&req->rw_sem);
 
@@ -2004,12 +2163,23 @@
 	if (!req_vaddr)
 		goto err_do_dump;
 
+	rc = ocmem_enable_dump(req->owner, offset, req->req_sz);
+
+	if (rc < 0)
+		goto err_do_dump;
+
 	pr_debug("Dumping client %s buffer ocmem p: %lx (v: %p) to ddr %lx\n",
 				get_name(req->owner), req->req_start,
 				req_vaddr, addr);
 
 	memcpy((void *)addr, req_vaddr, req->req_sz);
 
+	rc = ocmem_disable_dump(req->owner, offset, req->req_sz);
+
+	if (rc < 0)
+		pr_err("Failed to secure request %p of %s after dump\n",
+				req, get_name(req->owner));
+
 	up_write(&req->rw_sem);
 	return 0;
 err_do_dump:
@@ -2260,6 +2430,7 @@
 	sched_tree = RB_ROOT;
 	pdata = platform_get_drvdata(pdev);
 	mutex_init(&allocation_mutex);
+	mutex_init(&free_mutex);
 	mutex_init(&sched_mutex);
 	mutex_init(&sched_queue_mutex);
 	ocmem_vaddr = pdata->vbase;
diff --git a/arch/arm/mach-msm/oem_rapi_client.c b/arch/arm/mach-msm/oem_rapi_client.c
index bcf6e57..2e1e741 100644
--- a/arch/arm/mach-msm/oem_rapi_client.c
+++ b/arch/arm/mach-msm/oem_rapi_client.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/pcie.c b/arch/arm/mach-msm/pcie.c
index 709c8e8..6305abc 100644
--- a/arch/arm/mach-msm/pcie.c
+++ b/arch/arm/mach-msm/pcie.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -262,7 +262,7 @@
 	struct regulator *vreg;
 	struct msm_pcie_vreg_info_t *info;
 
-	for (i = 0; i < MSM_PCIE_MAX_VREG; i++) {
+	for (i = 0; i < msm_pcie_dev.vreg_n; i++) {
 		info = &msm_pcie_dev.vreg[i];
 
 		vreg = regulator_get(dev, info->name);
@@ -316,7 +316,7 @@
 {
 	int i;
 
-	for (i = 0; i < MSM_PCIE_MAX_VREG; i++) {
+	for (i = 0; i < msm_pcie_dev.vreg_n; i++) {
 		regulator_disable(msm_pcie_dev.vreg[i].hdl);
 		regulator_put(msm_pcie_dev.vreg[i].hdl);
 		msm_pcie_dev.vreg[i].hdl = NULL;
@@ -620,6 +620,7 @@
 	pdata = pdev->dev.platform_data;
 	msm_pcie_dev.gpio = pdata->gpio;
 	msm_pcie_dev.wake_n = pdata->wake_n;
+	msm_pcie_dev.vreg_n = pdata->vreg_n;
 	msm_pcie_dev.vreg = msm_pcie_vreg_info;
 	msm_pcie_dev.clk = msm_pcie_clk_info;
 	msm_pcie_dev.res = msm_pcie_res_info;
diff --git a/arch/arm/mach-msm/pcie.h b/arch/arm/mach-msm/pcie.h
index d7cce3e..31371c2 100644
--- a/arch/arm/mach-msm/pcie.h
+++ b/arch/arm/mach-msm/pcie.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -70,6 +70,7 @@
 	struct resource               dev_mem_res;
 
 	uint32_t                      wake_n;
+	uint32_t                      vreg_n;
 };
 
 extern uint32_t msm_pcie_irq_init(struct msm_pcie_dev_t *dev);
diff --git a/arch/arm/mach-msm/pcie_irq.c b/arch/arm/mach-msm/pcie_irq.c
index 5a44a17..f590827 100644
--- a/arch/arm/mach-msm/pcie_irq.c
+++ b/arch/arm/mach-msm/pcie_irq.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/perf_debug.c b/arch/arm/mach-msm/perf_debug.c
new file mode 100644
index 0000000..0579145
--- /dev/null
+++ b/arch/arm/mach-msm/perf_debug.c
@@ -0,0 +1,68 @@
+/* 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/types.h>
+#include <linux/uaccess.h>
+#include <linux/debugfs.h>
+
+/*
+ * Subsequent patches should add an entry to end of this string.
+ * Format is incrementing sequence number followed by text of
+ * patch commit title with newline.
+ * Note trailing ';' is on its own line to simplify addition of
+ * future strings.
+ */
+static char *descriptions =
+	"0  msm: perf: add debug patch logging framework\n"
+	"1  Perf: Restore counter after powercollapse for generic ARM PMU's\n"
+	"2  Perf: Toggle PMU IRQ when CPU's are hotplugged\n"
+	"3  Perf: Correct irq for CPU hotplug detection\n"
+	"4  Perf: Check perf activity on correct CPU\n"
+;
+
+static ssize_t desc_read(struct file *fp, char __user *buf,
+			 size_t count, loff_t *pos)
+{
+	return simple_read_from_buffer(buf, count, pos, descriptions,
+				       strlen(descriptions));
+}
+
+static const struct file_operations perf_debug_desc_fops = {
+	.read = desc_read,
+};
+
+static int msm_perf_debugfs_init(void)
+{
+	int ret = 0;
+	struct dentry *dir;
+	struct dentry *file;
+
+	dir = debugfs_create_dir("msm-perf-patches", NULL);
+	if (IS_ERR_OR_NULL(dir)) {
+		pr_err("failed to create msm-perf-patches dir in debugfs\n");
+		ret = PTR_ERR(dir);
+		goto init_exit;
+	}
+
+	file = debugfs_create_file("descriptions", 0444, dir, NULL,
+				   &perf_debug_desc_fops);
+	if (IS_ERR_OR_NULL(file)) {
+		debugfs_remove(dir);
+		pr_err("failed to create descriptions file for msm-perf-patches\n");
+		ret = PTR_ERR(file);
+		goto init_exit;
+	}
+
+init_exit:
+	return ret;
+}
+late_initcall(msm_perf_debugfs_init);
diff --git a/arch/arm/mach-msm/perf_event_msm_krait_l2.c b/arch/arm/mach-msm/perf_event_msm_krait_l2.c
index 26c5e58..34b9426 100644
--- a/arch/arm/mach-msm/perf_event_msm_krait_l2.c
+++ b/arch/arm/mach-msm/perf_event_msm_krait_l2.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, 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
diff --git a/arch/arm/mach-msm/perf_event_msm_l2.c b/arch/arm/mach-msm/perf_event_msm_l2.c
index c1b7d23..f78487a 100644
--- a/arch/arm/mach-msm/perf_event_msm_l2.c
+++ b/arch/arm/mach-msm/perf_event_msm_l2.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, 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
diff --git a/arch/arm/mach-msm/perf_event_msm_pl310.c b/arch/arm/mach-msm/perf_event_msm_pl310.c
new file mode 100644
index 0000000..e2a580f
--- /dev/null
+++ b/arch/arm/mach-msm/perf_event_msm_pl310.c
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2007 ARM Limited
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+
+#include <asm/pmu.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <mach/socinfo.h>
+
+static u32 rev1;
+
+/*
+ * Store dynamic PMU type after registration,
+ * to uniquely identify this PMU at runtime.
+ */
+static u32 pmu_type;
+
+/* This controller only supports 16 Events.*/
+PMU_FORMAT_ATTR(l2_config, "config:0-4");
+
+static struct attribute *arm_l2_ev_formats[] = {
+	&format_attr_l2_config.attr,
+	NULL,
+};
+
+/*
+ * Format group is essential to access PMU's from userspace
+ * via their .name field.
+ */
+static struct attribute_group arm_l2_pmu_format_group = {
+	.name = "format",
+	.attrs = arm_l2_ev_formats,
+};
+
+static const struct attribute_group *arm_l2_pmu_attr_grps[] = {
+	&arm_l2_pmu_format_group,
+	NULL,
+};
+
+#define L2X0_AUX_CTRL_EVENT_MONITOR_SHIFT	20
+#define L2X0_INTR_MASK_ECNTR		1
+
+/* L220/PL310 Event control register values */
+#define L2X0_EVENT_CNT_ENABLE_MASK		1
+#define L2X0_EVENT_CNT_ENABLE			1
+#define L2X0_EVENT_CNT_RESET(x)			(1 << (x+1))
+
+/* Bit-shifted event counter config values */
+enum l2x0_perf_types {
+	L2X0_EVENT_CNT_CFG_DISABLED		= 0x0,
+	L2X0_EVENT_CNT_CFG_CO			= 0x1,
+	L2X0_EVENT_CNT_CFG_DRHIT		= 0x2,
+	L2X0_EVENT_CNT_CFG_DRREQ		= 0x3,
+	L2X0_EVENT_CNT_CFG_DWHIT		= 0x4,
+	L2X0_EVENT_CNT_CFG_DWREQ		= 0x5,
+	L2X0_EVENT_CNT_CFG_DWTREQ		= 0x6,
+	L2X0_EVENT_CNT_CFG_IRHIT		= 0x7,
+	L2X0_EVENT_CNT_CFG_IRREQ		= 0x8,
+	L2X0_EVENT_CNT_CFG_WA			= 0x9,
+
+	/* PL310 only */
+	L2X0_EVENT_CNT_CFG_IPFALLOC		= 0xA,
+	L2X0_EVENT_CNT_CFG_EPFHIT		= 0xB,
+	L2X0_EVENT_CNT_CFG_EPFALLOC		= 0xC,
+	L2X0_EVENT_CNT_CFG_SRRCVD		= 0xD,
+	L2X0_EVENT_CNT_CFG_SRCONF		= 0xE,
+	L2X0_EVENT_CNT_CFG_EPFRCVD		= 0xF,
+};
+
+#define PL310_EVENT_CNT_CFG_MAX			L2X0_EVENT_CNT_CFG_EPFRCVD
+
+#define L2X0_EVENT_CNT_CFG_SHIFT		2
+#define L2X0_EVENT_CNT_CFG_MASK			(0xF << 2)
+
+#define L2X0_EVENT_CNT_CFG_INTR_MASK		0x3
+#define L2X0_EVENT_CNT_CFG_INTR_DISABLED	0x0
+#define L2X0_EVENT_CNT_CFG_INTR_INCREMENT	0x1
+#define L2X0_EVENT_CNT_CFG_INTR_OVERFLOW	0x2
+
+#define L2X0_NUM_COUNTERS			2
+static struct arm_pmu l2x0_pmu;
+
+static u32 l2x0pmu_max_event_id = 0xf;
+
+static struct perf_event *events[2];
+static unsigned long used_mask[BITS_TO_LONGS(2)];
+static struct pmu_hw_events l2x0pmu_hw_events = {
+	.events = events,
+	.used_mask = used_mask,
+	.pmu_lock = __RAW_SPIN_LOCK_UNLOCKED(l2x0pmu_hw_events.pmu_lock),
+};
+
+#define COUNTER_CFG_ADDR(idx)	(l2x0_base + L2X0_EVENT_CNT0_CFG - 4*idx)
+
+#define COUNTER_CTRL_ADDR	(l2x0_base + L2X0_EVENT_CNT_CTRL)
+
+#define COUNTER_ADDR(idx)	(l2x0_base + L2X0_EVENT_CNT0_VAL - 4*idx)
+
+static u32 l2x0_read_intr_mask(void)
+{
+	return readl_relaxed(l2x0_base + L2X0_INTR_MASK);
+}
+
+static void l2x0_write_intr_mask(u32 val)
+{
+	writel_relaxed(val, l2x0_base + L2X0_INTR_MASK);
+}
+
+static void l2x0_enable_counter_interrupt(void)
+{
+	u32 intr_mask = l2x0_read_intr_mask();
+	intr_mask |= L2X0_INTR_MASK_ECNTR;
+	l2x0_write_intr_mask(intr_mask);
+}
+
+static void l2x0_disable_counter_interrupt(void)
+{
+	u32 intr_mask = l2x0_read_intr_mask();
+	intr_mask &= ~L2X0_INTR_MASK_ECNTR;
+	l2x0_write_intr_mask(intr_mask);
+}
+
+static void l2x0_clear_interrupts(u32 flags)
+{
+	writel_relaxed(flags, l2x0_base + L2X0_INTR_CLEAR);
+}
+
+static struct pmu_hw_events *l2x0pmu_get_hw_events(void)
+{
+	return &l2x0pmu_hw_events;
+}
+
+static u32 l2x0pmu_read_ctrl(void)
+{
+	return readl_relaxed(COUNTER_CTRL_ADDR);
+}
+
+static void l2x0pmu_write_ctrl(u32 val)
+{
+	writel_relaxed(val, COUNTER_CTRL_ADDR);
+}
+
+static u32 l2x0pmu_read_cfg(int idx)
+{
+	return readl_relaxed(COUNTER_CFG_ADDR(idx));
+}
+
+static void l2x0pmu_write_cfg(u32 val, int idx)
+{
+	writel_relaxed(val, COUNTER_CFG_ADDR(idx));
+}
+
+static void l2x0pmu_enable_counter(u32 cfg, int idx)
+{
+	cfg |= L2X0_EVENT_CNT_CFG_INTR_OVERFLOW;
+	l2x0pmu_write_cfg(cfg, idx);
+}
+
+static u32 l2x0pmu_disable_counter(int idx)
+{
+	u32 cfg, oldcfg;
+
+	cfg = oldcfg = l2x0pmu_read_cfg(idx);
+
+	cfg &= ~L2X0_EVENT_CNT_CFG_MASK;
+	cfg &= ~L2X0_EVENT_CNT_CFG_INTR_MASK;
+	l2x0pmu_write_cfg(cfg, idx);
+
+	return oldcfg;
+}
+
+static u32 l2x0pmu_read_counter(int idx)
+{
+	u32 val = readl_relaxed(COUNTER_ADDR(idx));
+
+	return val;
+}
+
+static void l2x0pmu_write_counter(int idx, u32 val)
+{
+	/*
+	 * L2X0 counters can only be written to when they are disabled.
+	 * As perf core does not disable counters before writing to them
+	 * under interrupts, we must do so here.
+	 */
+	u32 cfg = l2x0pmu_disable_counter(idx);
+	writel_relaxed(val, COUNTER_ADDR(idx));
+	l2x0pmu_write_cfg(cfg, idx);
+}
+
+static int counter_is_saturated(int idx)
+{
+	return l2x0pmu_read_counter(idx) == 0xFFFFFFFF;
+}
+
+static void l2x0pmu_start(void)
+{
+	unsigned long flags;
+	u32 val;
+
+	raw_spin_lock_irqsave(&l2x0pmu_hw_events.pmu_lock, flags);
+
+	if (!rev1)
+		l2x0_enable_counter_interrupt();
+
+	val = l2x0pmu_read_ctrl();
+
+	val |= L2X0_EVENT_CNT_ENABLE;
+	l2x0pmu_write_ctrl(val);
+
+	raw_spin_unlock_irqrestore(&l2x0pmu_hw_events.pmu_lock, flags);
+}
+
+static void l2x0pmu_stop(void)
+{
+	unsigned long flags;
+	u32 val;
+
+	raw_spin_lock_irqsave(&l2x0pmu_hw_events.pmu_lock, flags);
+
+	val = l2x0pmu_read_ctrl();
+	val &= ~L2X0_EVENT_CNT_ENABLE_MASK;
+	l2x0pmu_write_ctrl(val);
+
+	if (!rev1)
+		l2x0_disable_counter_interrupt();
+
+	raw_spin_unlock_irqrestore(&l2x0pmu_hw_events.pmu_lock, flags);
+}
+
+static void l2x0pmu_enable(struct hw_perf_event *event, int idx, int cpu)
+{
+	unsigned long flags;
+	u32 cfg;
+
+	raw_spin_lock_irqsave(&l2x0pmu_hw_events.pmu_lock, flags);
+
+	cfg = (event->config_base << L2X0_EVENT_CNT_CFG_SHIFT) &
+						L2X0_EVENT_CNT_CFG_MASK;
+	l2x0pmu_enable_counter(cfg, idx);
+
+	raw_spin_unlock_irqrestore(&l2x0pmu_hw_events.pmu_lock, flags);
+}
+
+static void l2x0pmu_disable(struct hw_perf_event *event, int idx)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&l2x0pmu_hw_events.pmu_lock, flags);
+	l2x0pmu_disable_counter(idx);
+	raw_spin_unlock_irqrestore(&l2x0pmu_hw_events.pmu_lock, flags);
+}
+
+static int l2x0pmu_get_event_idx(struct pmu_hw_events *events,
+					struct hw_perf_event *hwc)
+{
+	int idx;
+
+	/* Counters are identical. Just grab a free one. */
+	for (idx = 0; idx < L2X0_NUM_COUNTERS; ++idx) {
+		if (!test_and_set_bit(idx, l2x0pmu_hw_events.used_mask))
+			return idx;
+	}
+
+	return -EAGAIN;
+}
+
+/*
+ * As System PMUs are affine to CPU0, the fact that interrupts are disabled
+ * during interrupt handling is enough to serialise our actions and make this
+ * safe. We do not need to grab our pmu_lock here.
+ */
+static irqreturn_t l2x0pmu_handle_irq(int irq, void *dev)
+{
+	irqreturn_t status = IRQ_NONE;
+	struct perf_sample_data data;
+	struct pt_regs *regs;
+	int idx;
+
+	regs = get_irq_regs();
+
+	for (idx = 0; idx < L2X0_NUM_COUNTERS; ++idx) {
+		struct perf_event *event = l2x0pmu_hw_events.events[idx];
+		struct hw_perf_event *hwc;
+
+		if (!counter_is_saturated(idx))
+			continue;
+
+		status = IRQ_HANDLED;
+
+		hwc = &event->hw;
+
+		/*
+		 * The armpmu_* functions expect counters to overflow, but
+		 * L220/PL310 counters saturate instead. Fake the overflow
+		 * here so the hardware is in sync with what the framework
+		 * expects.
+		 */
+		l2x0pmu_write_counter(idx, 0);
+
+		armpmu_event_update(event, hwc, idx);
+		data.period = event->hw.last_period;
+
+		if (!armpmu_event_set_period(event, hwc, idx))
+			continue;
+
+		if (perf_event_overflow(event, &data, regs))
+			l2x0pmu_disable_counter(idx);
+	}
+
+	l2x0_clear_interrupts(L2X0_INTR_MASK_ECNTR);
+
+	irq_work_run();
+
+	return status;
+}
+
+static int map_l2x0_raw_event(u64 config)
+{
+	return (config <= l2x0pmu_max_event_id) ? config : -ENOENT;
+}
+
+static int l2x0pmu_map_event(struct perf_event *event)
+{
+	u64 config = event->attr.config;
+	u64 supported_samples = (PERF_SAMPLE_TIME	|
+				 PERF_SAMPLE_ID		|
+				 PERF_SAMPLE_PERIOD	|
+				 PERF_SAMPLE_STREAM_ID	|
+				 PERF_SAMPLE_RAW);
+
+	if ((pmu_type == 0) || (pmu_type != event->attr.type))
+		return -ENOENT;
+
+	if (event->attr.sample_type & ~supported_samples)
+		return -ENOENT;
+
+	return map_l2x0_raw_event(config);
+}
+
+static int
+arm_l2_pmu_generic_request_irq(int irq, irq_handler_t *handle_irq)
+{
+	return request_irq(irq, *handle_irq,
+			IRQF_DISABLED | IRQF_NOBALANCING,
+			"arm-l2-armpmu", NULL);
+}
+
+static void
+arm_l2_pmu_generic_free_irq(int irq)
+{
+	if (irq >= 0)
+		free_irq(irq, NULL);
+}
+
+static struct arm_pmu l2x0_pmu = {
+	.id		= ARM_PERF_PMU_ID_L2X0,
+	.type		= ARM_PMU_DEVICE_L2CC,
+	.name		= "msm-l2",
+	.start		= l2x0pmu_start,
+	.stop		= l2x0pmu_stop,
+	.handle_irq	= l2x0pmu_handle_irq,
+	.enable		= l2x0pmu_enable,
+	.disable	= l2x0pmu_disable,
+	.get_event_idx	= l2x0pmu_get_event_idx,
+	.read_counter	= l2x0pmu_read_counter,
+	.write_counter	= l2x0pmu_write_counter,
+	.map_event	= l2x0pmu_map_event,
+	.num_events	= 2,
+	.max_period	= 0xFFFFFFFF,
+	.get_hw_events	= l2x0pmu_get_hw_events,
+	.pmu.attr_groups = arm_l2_pmu_attr_grps,
+	.request_pmu_irq = arm_l2_pmu_generic_request_irq,
+	.free_pmu_irq	= arm_l2_pmu_generic_free_irq,
+};
+
+static int __devinit l2x0pmu_device_probe(struct platform_device *pdev)
+{
+	u32 aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
+	u32 debug = readl_relaxed(l2x0_base + L2X0_DEBUG_CTRL);
+	l2x0_pmu.plat_device = pdev;
+
+	if (!(aux & (1 << L2X0_AUX_CTRL_EVENT_MONITOR_SHIFT))) {
+		pr_err("Ev Monitor is OFF. L2 counters disabled.\n");
+		return -EOPNOTSUPP;
+	}
+
+	pr_info("L2CC PMU device found. DEBUG_CTRL: %x\n", debug);
+
+	/* Get value of dynamically allocated PMU type. */
+	if (!armpmu_register(&l2x0_pmu, "msm-l2", -1))
+		pmu_type = l2x0_pmu.pmu.type;
+	else {
+		pr_err("l2x0_pmu registration failed\n");
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static struct platform_driver l2x0pmu_driver = {
+	.driver		= {
+		.name	= "l2-arm-pmu",
+	},
+	.probe		= l2x0pmu_device_probe,
+};
+
+static int __init register_pmu_driver(void)
+{
+	if (machine_is_msm9625())
+		rev1 = 1;
+
+	return platform_driver_register(&l2x0pmu_driver);
+}
+device_initcall(register_pmu_driver);
diff --git a/arch/arm/mach-msm/peripheral-loader.c b/arch/arm/mach-msm/peripheral-loader.c
index 88aae81..fc9a0fa 100644
--- a/arch/arm/mach-msm/peripheral-loader.c
+++ b/arch/arm/mach-msm/peripheral-loader.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -313,7 +313,7 @@
 	struct ion_handle *region;
 	int ret;
 	unsigned int mask;
-	size_t size = round_up(max_addr - min_addr, align);
+	size_t size = max_addr - min_addr;
 
 	if (!ion) {
 		WARN_ON_ONCE("No ION client, can't support relocation\n");
@@ -386,6 +386,13 @@
 
 	}
 
+	/*
+	 * Align the max address to the next 4K boundary to satisfy iommus and
+	 * XPUs that operate on 4K chunks.
+	 */
+	max_addr_n = ALIGN(max_addr_n, SZ_4K);
+	max_addr_r = ALIGN(max_addr_r, SZ_4K);
+
 	if (relocatable) {
 		ret = pil_alloc_region(priv, min_addr_r, max_addr_r, align);
 	} else {
@@ -649,7 +656,8 @@
 void pil_shutdown(struct pil_desc *desc)
 {
 	struct pil_priv *priv = desc->priv;
-	desc->ops->shutdown(desc);
+	if (desc->ops->shutdown)
+		desc->ops->shutdown(desc);
 	if (proxy_timeout_ms == 0 && desc->ops->proxy_unvote)
 		desc->ops->proxy_unvote(desc);
 	else
@@ -673,7 +681,7 @@
 	struct pil_priv *priv;
 	int id;
 	void __iomem *addr;
-	size_t len;
+	char buf[sizeof(priv->info->name)];
 
 	/* Ignore users who don't make any sense */
 	WARN(desc->ops->proxy_unvote && !desc->proxy_timeout,
@@ -696,9 +704,8 @@
 	addr = PIL_IMAGE_INFO_BASE + sizeof(struct pil_image_info) * id;
 	priv->info = (struct pil_image_info __iomem *)addr;
 
-	len = min(strlen(desc->name), sizeof(priv->info->name));
-	memset_io(priv->info->name, 0, sizeof(priv->info->name));
-	memcpy_toio(priv->info->name, desc->name, len);
+	strncpy(buf, desc->name, sizeof(buf));
+	__iowrite32_copy(priv->info->name, buf, sizeof(buf) / 4);
 
 	snprintf(priv->wname, sizeof(priv->wname), "pil-%s", desc->name);
 	wake_lock_init(&priv->wlock, WAKE_LOCK_SUSPEND, priv->wname);
diff --git a/arch/arm/mach-msm/peripheral-loader.h b/arch/arm/mach-msm/peripheral-loader.h
index 8442289..c1a4167 100644
--- a/arch/arm/mach-msm/peripheral-loader.h
+++ b/arch/arm/mach-msm/peripheral-loader.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/pil-dsps.c b/arch/arm/mach-msm/pil-dsps.c
index d315d82..0630e6a 100644
--- a/arch/arm/mach-msm/pil-dsps.c
+++ b/arch/arm/mach-msm/pil-dsps.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/pil-gss.c b/arch/arm/mach-msm/pil-gss.c
index f4d4449..c9e2e0d 100644
--- a/arch/arm/mach-msm/pil-gss.c
+++ b/arch/arm/mach-msm/pil-gss.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/pil-modem.c b/arch/arm/mach-msm/pil-modem.c
index 3546705..e95fae8 100644
--- a/arch/arm/mach-msm/pil-modem.c
+++ b/arch/arm/mach-msm/pil-modem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/pil-pronto.c b/arch/arm/mach-msm/pil-pronto.c
index b457599..6bd087c 100644
--- a/arch/arm/mach-msm/pil-pronto.c
+++ b/arch/arm/mach-msm/pil-pronto.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -235,6 +235,12 @@
 	return pas_init_image(PAS_WCNSS, metadata, size);
 }
 
+static int pil_pronto_mem_setup_trusted(struct pil_desc *pil, phys_addr_t addr,
+			       size_t size)
+{
+	return pas_mem_setup(PAS_WCNSS, addr, size);
+}
+
 static int pil_pronto_reset_trusted(struct pil_desc *pil)
 {
 	return pas_auth_and_reset(PAS_WCNSS);
@@ -247,6 +253,7 @@
 
 static struct pil_reset_ops pil_pronto_ops_trusted = {
 	.init_image = pil_pronto_init_image_trusted,
+	.mem_setup = pil_pronto_mem_setup_trusted,
 	.auth_and_reset = pil_pronto_reset_trusted,
 	.shutdown = pil_pronto_shutdown_trusted,
 	.proxy_vote = pil_pronto_make_proxy_vote,
diff --git a/arch/arm/mach-msm/pil-q6v3.c b/arch/arm/mach-msm/pil-q6v3.c
index 1f53f17..66adc2b 100644
--- a/arch/arm/mach-msm/pil-q6v3.c
+++ b/arch/arm/mach-msm/pil-q6v3.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/pil-q6v4.c b/arch/arm/mach-msm/pil-q6v4.c
index 7f04c64..29d14dd 100644
--- a/arch/arm/mach-msm/pil-q6v4.c
+++ b/arch/arm/mach-msm/pil-q6v4.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/pil-q6v4.h b/arch/arm/mach-msm/pil-q6v4.h
index 86e55ea..5ad3569 100644
--- a/arch/arm/mach-msm/pil-q6v4.h
+++ b/arch/arm/mach-msm/pil-q6v4.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/pil-q6v5-lpass.c b/arch/arm/mach-msm/pil-q6v5-lpass.c
index 5e03aa8..dfbda74 100644
--- a/arch/arm/mach-msm/pil-q6v5-lpass.c
+++ b/arch/arm/mach-msm/pil-q6v5-lpass.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. 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
@@ -21,6 +21,7 @@
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/sysfs.h>
 
 #include <mach/clk.h>
 #include <mach/subsystem_restart.h>
@@ -36,6 +37,9 @@
 #define QDSP6SS_RST_EVB			0x010
 #define PROXY_TIMEOUT_MS		10000
 
+static struct kobject *lpass_status;
+static char status[32];
+
 struct lpass_data {
 	struct q6v5_data *q6;
 	struct subsys_device *subsys;
@@ -153,6 +157,12 @@
 	return pas_init_image(PAS_Q6, metadata, size);
 }
 
+static int pil_lpass_mem_setup_trusted(struct pil_desc *pil, phys_addr_t addr,
+			       size_t size)
+{
+	return pas_mem_setup(PAS_Q6, addr, size);
+}
+
 static int pil_lpass_reset_trusted(struct pil_desc *pil)
 {
 	return pas_auth_and_reset(PAS_Q6);
@@ -165,6 +175,7 @@
 
 static struct pil_reset_ops pil_lpass_ops_trusted = {
 	.init_image = pil_lpass_init_image_trusted,
+	.mem_setup = pil_lpass_mem_setup_trusted,
 	.proxy_vote = pil_q6v5_make_proxy_votes,
 	.proxy_unvote = pil_q6v5_remove_proxy_votes,
 	.auth_and_reset = pil_lpass_reset_trusted,
@@ -271,6 +282,34 @@
 	pr_debug("%s: Q6 NMI was sent.\n", __func__);
 }
 
+/*
+ * The "status" file where a static variable is read from and written to.
+ */
+static ssize_t adsp_state_show(struct kobject *kobj,
+			struct kobj_attribute *attr,
+			char *buf)
+{
+	return snprintf(buf, sizeof(status), "%s\n", status);
+}
+
+static struct kobj_attribute adsp_state_attribute =
+	__ATTR(status, 0444, adsp_state_show, NULL);
+
+static struct attribute *attrs[] = {
+	&adsp_state_attribute.attr,
+	NULL,   /* need to NULL terminate the list of attributes */
+};
+
+static struct attribute_group attr_group = {
+	.attrs = attrs,
+};
+
+static void adsp_set_state(char *state)
+{
+	strlcpy(status, state, sizeof(status));
+	sysfs_notify(lpass_status, NULL, "status");
+}
+
 #define subsys_to_lpass(d) container_of(d, struct lpass_data, subsys_desc)
 
 static int adsp_shutdown(const struct subsys_desc *subsys)
@@ -283,6 +322,8 @@
 	pil_shutdown(&drv->q6->desc);
 	disable_irq_nosync(drv->wdog_irq);
 
+	pr_debug("ADSP is Down\n");
+	adsp_set_state("OFFLINE");
 	return 0;
 }
 
@@ -292,6 +333,9 @@
 	int ret = 0;
 	ret = pil_boot(&drv->q6->desc);
 	enable_irq(drv->wdog_irq);
+
+	pr_debug("ADSP is back online\n");
+	adsp_set_state("ONLINE");
 	return ret;
 }
 
@@ -434,7 +478,24 @@
 		ret = PTR_ERR(drv->modem_notif_hdle);
 		goto err_notif_modem;
 	}
+	lpass_status = kobject_create_and_add("audio_voice_service",
+						kernel_kobj);
+	if (!lpass_status) {
+		pr_err("%s: kobject create failed\n", __func__);
+		ret = -ENOMEM;
+		goto err_notif_modem;
+	}
+
+	ret = sysfs_create_group(lpass_status, &attr_group);
+	if (ret) {
+		pr_err("%s: sysfs create group failed\n", __func__);
+		goto err_kobj;
+	}
+
+	adsp_set_state("ONLINE");
 	return 0;
+err_kobj:
+	kobject_put(lpass_status);
 err_notif_modem:
 	subsys_notif_unregister_notifier(drv->riva_notif_hdle, &rnb);
 err_notif_riva:
@@ -447,7 +508,7 @@
 	destroy_ramdump_device(drv->ramdump_dev);
 err_ramdump:
 	pil_desc_release(desc);
-	return 0;
+	return ret;
 }
 
 static int __devexit pil_lpass_driver_exit(struct platform_device *pdev)
@@ -460,6 +521,8 @@
 	subsys_unregister(drv->subsys);
 	destroy_ramdump_device(drv->ramdump_dev);
 	pil_desc_release(&drv->q6->desc);
+	sysfs_remove_group(lpass_status, &attr_group);
+	kobject_del(lpass_status);
 	return 0;
 }
 
diff --git a/arch/arm/mach-msm/pil-q6v5-mss.c b/arch/arm/mach-msm/pil-q6v5-mss.c
index ed85c95..cd6aaf4 100644
--- a/arch/arm/mach-msm/pil-q6v5-mss.c
+++ b/arch/arm/mach-msm/pil-q6v5-mss.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -462,7 +462,7 @@
 
 	if (!drv->is_loadable)
 		return 0;
-	/* MBA doesn't support shutdown */
+	pil_shutdown(&drv->desc);
 	pil_shutdown(&drv->q6->desc);
 	return 0;
 }
@@ -512,7 +512,7 @@
 	if (ret)
 		return ret;
 
-	ret = pil_do_ramdump(&drv->q6->desc, drv->ramdump_dev);
+	ret = pil_do_ramdump(&drv->desc, drv->ramdump_dev);
 	if (ret < 0) {
 		pr_err("Unable to dump modem fw memory (rc = %d).\n", ret);
 		goto out;
@@ -578,7 +578,7 @@
 	if (!drv->is_loadable)
 		return;
 
-	/* MBA doesn't support shutdown */
+	pil_shutdown(&drv->desc);
 	pil_shutdown(&drv->q6->desc);
 }
 
diff --git a/arch/arm/mach-msm/pil-q6v5.c b/arch/arm/mach-msm/pil-q6v5.c
index ab88749..0263faf 100644
--- a/arch/arm/mach-msm/pil-q6v5.c
+++ b/arch/arm/mach-msm/pil-q6v5.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. 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
@@ -19,6 +19,8 @@
 #include <linux/err.h>
 #include <linux/of.h>
 #include <linux/clk.h>
+#include <linux/regulator/consumer.h>
+#include <mach/rpm-regulator-smd.h>
 #include <mach/clk.h>
 #include "peripheral-loader.h"
 #include "pil-q6v5.h"
@@ -27,7 +29,6 @@
 #define QDSP6SS_RESET			0x014
 #define QDSP6SS_GFMUX_CTL		0x020
 #define QDSP6SS_PWR_CTL			0x030
-#define QDSP6SS_CGC_OVERRIDE		0x034
 
 /* AXI Halt Register Offsets */
 #define AXI_HALTREQ			0x0
@@ -52,10 +53,7 @@
 #define Q6SS_SLP_RET_N			BIT(19)
 #define Q6SS_CLAMP_IO			BIT(20)
 #define QDSS_BHS_ON			BIT(21)
-
-/* QDSP6SS_CGC_OVERRIDE */
-#define Q6SS_CORE_CLK_EN		BIT(0)
-#define Q6SS_CORE_RCLK_EN		BIT(1)
+#define QDSS_LDO_BYP			BIT(22)
 
 int pil_q6v5_make_proxy_votes(struct pil_desc *pil)
 {
@@ -64,16 +62,63 @@
 
 	ret = clk_prepare_enable(drv->xo);
 	if (ret) {
-		dev_err(pil->dev, "Failed to enable XO\n");
-		return ret;
+		dev_err(pil->dev, "Failed to vote for XO\n");
+		goto out;
 	}
+
+	ret = regulator_set_voltage(drv->vreg_cx,
+				    RPM_REGULATOR_CORNER_SUPER_TURBO,
+				    RPM_REGULATOR_CORNER_SUPER_TURBO);
+	if (ret) {
+		dev_err(pil->dev, "Failed to request vdd_cx voltage.\n");
+		goto err_cx_voltage;
+	}
+
+	ret = regulator_set_optimum_mode(drv->vreg_cx, 100000);
+	if (ret < 0) {
+		dev_err(pil->dev, "Failed to set vdd_cx mode.\n");
+		goto err_cx_mode;
+	}
+
+	ret = regulator_enable(drv->vreg_cx);
+	if (ret) {
+		dev_err(pil->dev, "Failed to vote for vdd_cx\n");
+		goto err_cx_enable;
+	}
+
+	if (drv->vreg_pll) {
+		ret = regulator_enable(drv->vreg_pll);
+		if (ret) {
+			dev_err(pil->dev, "Failed to vote for vdd_pll\n");
+			goto err_vreg_pll;
+		}
+	}
+
 	return 0;
+
+err_vreg_pll:
+	regulator_disable(drv->vreg_cx);
+err_cx_enable:
+	regulator_set_optimum_mode(drv->vreg_cx, 0);
+err_cx_mode:
+	regulator_set_voltage(drv->vreg_cx, RPM_REGULATOR_CORNER_NONE,
+			      RPM_REGULATOR_CORNER_SUPER_TURBO);
+err_cx_voltage:
+	clk_disable_unprepare(drv->xo);
+out:
+	return ret;
 }
 EXPORT_SYMBOL(pil_q6v5_make_proxy_votes);
 
 void pil_q6v5_remove_proxy_votes(struct pil_desc *pil)
 {
 	struct q6v5_data *drv = container_of(pil, struct q6v5_data, desc);
+	if (drv->vreg_pll)
+		regulator_disable(drv->vreg_pll);
+	regulator_disable(drv->vreg_cx);
+	regulator_set_optimum_mode(drv->vreg_cx, 0);
+	regulator_set_voltage(drv->vreg_cx, RPM_REGULATOR_CORNER_NONE,
+			      RPM_REGULATOR_CORNER_SUPER_TURBO);
 	clk_disable_unprepare(drv->xo);
 }
 EXPORT_SYMBOL(pil_q6v5_remove_proxy_votes);
@@ -118,14 +163,14 @@
 	val &= ~(Q6SS_L2DATA_SLP_NRET_N | Q6SS_SLP_RET_N |
 		 Q6SS_L2TAG_SLP_NRET_N | Q6SS_ETB_SLP_NRET_N |
 		 Q6SS_L2DATA_STBY_N);
-	writel_relaxed(Q6SS_CLAMP_IO, drv->reg_base + QDSP6SS_PWR_CTL);
+	writel_relaxed(val, drv->reg_base + QDSP6SS_PWR_CTL);
 
 	/* Assert Q6 resets */
 	val = readl_relaxed(drv->reg_base + QDSP6SS_RESET);
-	val = (Q6SS_CORE_ARES | Q6SS_BUS_ARES_ENA);
+	val |= (Q6SS_CORE_ARES | Q6SS_BUS_ARES_ENA);
 	writel_relaxed(val, drv->reg_base + QDSP6SS_RESET);
 
-	/* Kill power at block headswitch (affects LPASS only) */
+	/* Kill power at block headswitch */
 	val = readl_relaxed(drv->reg_base + QDSP6SS_PWR_CTL);
 	val &= ~QDSS_BHS_ON;
 	writel_relaxed(val, drv->reg_base + QDSP6SS_PWR_CTL);
@@ -142,10 +187,12 @@
 	val |= (Q6SS_CORE_ARES | Q6SS_BUS_ARES_ENA | Q6SS_STOP_CORE);
 	writel_relaxed(val, drv->reg_base + QDSP6SS_RESET);
 
-	/* Enable power block headswitch (only affects LPASS) */
+	/* Enable power block headswitch, and wait for it to stabilize */
 	val = readl_relaxed(drv->reg_base + QDSP6SS_PWR_CTL);
-	val |= QDSS_BHS_ON;
+	val |= QDSS_BHS_ON | QDSS_LDO_BYP;
 	writel_relaxed(val, drv->reg_base + QDSP6SS_PWR_CTL);
+	mb();
+	udelay(1);
 
 	/* Turn on memories */
 	val = readl_relaxed(drv->reg_base + QDSP6SS_PWR_CTL);
@@ -163,11 +210,6 @@
 	val &= ~Q6SS_CORE_ARES;
 	writel_relaxed(val, drv->reg_base + QDSP6SS_RESET);
 
-	/* Disable clock gating for core and rclk */
-	val = readl_relaxed(drv->reg_base + QDSP6SS_CGC_OVERRIDE);
-	val |= Q6SS_CORE_RCLK_EN | Q6SS_CORE_CLK_EN;
-	writel_relaxed(val, drv->reg_base + QDSP6SS_CGC_OVERRIDE);
-
 	/* Turn on core clock */
 	val = readl_relaxed(drv->reg_base + QDSP6SS_GFMUX_CTL);
 	val |= Q6SS_CLK_ENA;
@@ -214,6 +256,35 @@
 	if (IS_ERR(drv->xo))
 		return ERR_CAST(drv->xo);
 
+	drv->vreg_cx = devm_regulator_get(&pdev->dev, "vdd_cx");
+	if (IS_ERR(drv->vreg_cx))
+		return ERR_CAST(drv->vreg_cx);
+
+	drv->vreg_pll = devm_regulator_get(&pdev->dev, "vdd_pll");
+	if (!IS_ERR(drv->vreg_pll)) {
+		int voltage;
+		ret = of_property_read_u32(pdev->dev.of_node, "qcom,vdd_pll",
+					   &voltage);
+		if (ret) {
+			dev_err(&pdev->dev, "Failed to find vdd_pll voltage.\n");
+			return ERR_PTR(ret);
+		}
+
+		ret = regulator_set_voltage(drv->vreg_pll, voltage, voltage);
+		if (ret) {
+			dev_err(&pdev->dev, "Failed to request vdd_pll voltage.\n");
+			return ERR_PTR(ret);
+		}
+
+		ret = regulator_set_optimum_mode(drv->vreg_pll, 10000);
+		if (ret < 0) {
+			dev_err(&pdev->dev, "Failed to set vdd_pll mode.\n");
+			return ERR_PTR(ret);
+		}
+	} else {
+		 drv->vreg_pll = NULL;
+	}
+
 	desc->dev = &pdev->dev;
 
 	return drv;
diff --git a/arch/arm/mach-msm/pil-q6v5.h b/arch/arm/mach-msm/pil-q6v5.h
index d9ad6ae..0d986a6 100644
--- a/arch/arm/mach-msm/pil-q6v5.h
+++ b/arch/arm/mach-msm/pil-q6v5.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -31,7 +31,9 @@
 	void __iomem *axi_halt_base;
 	void __iomem *restart_reg;
 	struct regulator *vreg;
+	struct regulator *vreg_cx;
 	struct regulator *vreg_mx;
+	struct regulator *vreg_pll;
 	bool is_booted;
 	struct pil_desc desc;
 };
diff --git a/arch/arm/mach-msm/pil-riva.c b/arch/arm/mach-msm/pil-riva.c
index 96b9882..33301de 100644
--- a/arch/arm/mach-msm/pil-riva.c
+++ b/arch/arm/mach-msm/pil-riva.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
@@ -349,6 +349,7 @@
 		panic("Watchdog bite received from Riva");
 
 	drv->rst_in_progress = 1;
+	wcnss_riva_log_debug_regs();
 	subsystem_restart_dev(drv->subsys);
 
 	return IRQ_HANDLED;
diff --git a/arch/arm/mach-msm/pil-tzapps.c b/arch/arm/mach-msm/pil-tzapps.c
index 8658e6e..1410117 100644
--- a/arch/arm/mach-msm/pil-tzapps.c
+++ b/arch/arm/mach-msm/pil-tzapps.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/pil-venus.c b/arch/arm/mach-msm/pil-venus.c
index eb222e3..b0150d4 100644
--- a/arch/arm/mach-msm/pil-venus.c
+++ b/arch/arm/mach-msm/pil-venus.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -36,22 +36,34 @@
 #include "ramdump.h"
 
 /* VENUS WRAPPER registers */
+#define VENUS_WRAPPER_HW_VERSION			0x0
 #define VENUS_WRAPPER_CLOCK_CONFIG			0x4
-#define VENUS_WRAPPER_VBIF_SS_SEC_CPA_START_ADDR	0x1018
-#define VENUS_WRAPPER_VBIF_SS_SEC_CPA_END_ADDR		0x101C
-#define VENUS_WRAPPER_VBIF_SS_SEC_FW_START_ADDR		0x1020
-#define VENUS_WRAPPER_VBIF_SS_SEC_FW_END_ADDR		0x1024
+
+#define VENUS_WRAPPER_VBIF_SS_SEC_CPA_START_ADDR_v1	0x1018
+#define VENUS_WRAPPER_VBIF_SS_SEC_CPA_END_ADDR_v1	0x101C
+#define VENUS_WRAPPER_VBIF_SS_SEC_FW_START_ADDR_v1	0x1020
+#define VENUS_WRAPPER_VBIF_SS_SEC_FW_END_ADDR_v1	0x1024
+
+#define VENUS_WRAPPER_VBIF_SS_SEC_CPA_START_ADDR_v2	0x1020
+#define VENUS_WRAPPER_VBIF_SS_SEC_CPA_END_ADDR_v2	0x1024
+#define VENUS_WRAPPER_VBIF_SS_SEC_FW_START_ADDR_v2	0x1028
+#define VENUS_WRAPPER_VBIF_SS_SEC_FW_END_ADDR_v2	0x102C
+
 #define VENUS_WRAPPER_CPU_CLOCK_CONFIG			0x2000
 #define VENUS_WRAPPER_SW_RESET				0x3000
 
 /* VENUS VBIF registers */
-#define VENUS_VBIF_AXI_HALT_CTRL0			0x0
+#define VENUS_VBIF_CLKON				0x4
+#define VENUS_VBIF_CLKON_FORCE_ON			BIT(0)
+
+#define VENUS_VBIF_AXI_HALT_CTRL0			0x208
 #define VENUS_VBIF_AXI_HALT_CTRL0_HALT_REQ		BIT(0)
 
-#define VENUS_VBIF_AXI_HALT_CTRL1			0x4
+#define VENUS_VBIF_AXI_HALT_CTRL1			0x20C
 #define VENUS_VBIF_AXI_HALT_CTRL1_HALT_ACK		BIT(0)
 #define VENUS_VBIF_AXI_HALT_ACK_TIMEOUT_US		500000
 
+
 /* PIL proxy vote timeout */
 #define VENUS_PROXY_TIMEOUT				10000
 
@@ -77,11 +89,14 @@
 	struct iommu_domain *iommu_fw_domain;
 	int venus_domain_num;
 	bool is_booted;
+	bool hw_ver_checked;
 	void *ramdump_dev;
 	u32 fw_sz;
 	u32 fw_min_paddr;
 	u32 fw_max_paddr;
 	u32 bus_perf_client;
+	u32 hw_ver_major;
+	u32 hw_ver_minor;
 };
 
 #define subsys_to_drv(d) container_of(d, struct venus_data, subsys_desc)
@@ -271,6 +286,7 @@
 	void __iomem *wrapper_base = drv->venus_wrapper_base;
 	phys_addr_t pa = pil_get_entry_addr(pil);
 	unsigned long iova;
+	u32 ver, cpa_start_addr, cpa_end_addr, fw_start_addr, fw_end_addr;
 
 	/*
 	 * GDSC needs to remain on till Venus is shutdown. So, enable
@@ -283,17 +299,34 @@
 		return rc;
 	}
 
+	/* Get Venus version number */
+	if (!drv->hw_ver_checked) {
+		ver = readl_relaxed(wrapper_base + VENUS_WRAPPER_HW_VERSION);
+		drv->hw_ver_minor = (ver & 0x0FFF0000) >> 16;
+		drv->hw_ver_major = (ver & 0xF0000000) >> 28;
+		drv->hw_ver_checked = 1;
+	}
+
+	/* Get the cpa and fw start/end addr based on Venus version */
+	if (drv->hw_ver_major == 0x1 && drv->hw_ver_minor <= 1) {
+		cpa_start_addr = VENUS_WRAPPER_VBIF_SS_SEC_CPA_START_ADDR_v1;
+		cpa_end_addr = VENUS_WRAPPER_VBIF_SS_SEC_CPA_END_ADDR_v1;
+		fw_start_addr = VENUS_WRAPPER_VBIF_SS_SEC_FW_START_ADDR_v1;
+		fw_end_addr = VENUS_WRAPPER_VBIF_SS_SEC_FW_END_ADDR_v1;
+	} else {
+		cpa_start_addr = VENUS_WRAPPER_VBIF_SS_SEC_CPA_START_ADDR_v2;
+		cpa_end_addr = VENUS_WRAPPER_VBIF_SS_SEC_CPA_END_ADDR_v2;
+		fw_start_addr = VENUS_WRAPPER_VBIF_SS_SEC_FW_START_ADDR_v2;
+		fw_end_addr = VENUS_WRAPPER_VBIF_SS_SEC_FW_END_ADDR_v2;
+	}
+
 	/* Program CPA start and end address */
-	writel_relaxed(0, wrapper_base +
-			VENUS_WRAPPER_VBIF_SS_SEC_CPA_START_ADDR);
-	writel_relaxed(drv->fw_sz, wrapper_base +
-			VENUS_WRAPPER_VBIF_SS_SEC_CPA_END_ADDR);
+	writel_relaxed(0, wrapper_base + cpa_start_addr);
+	writel_relaxed(drv->fw_sz, wrapper_base + cpa_end_addr);
 
 	/* Program FW start and end address */
-	writel_relaxed(0, wrapper_base +
-			VENUS_WRAPPER_VBIF_SS_SEC_FW_START_ADDR);
-	writel_relaxed(drv->fw_sz, wrapper_base +
-			VENUS_WRAPPER_VBIF_SS_SEC_FW_END_ADDR);
+	writel_relaxed(0, wrapper_base + fw_start_addr);
+	writel_relaxed(drv->fw_sz, wrapper_base + fw_end_addr);
 
 	/* Enable all Venus internal clocks */
 	writel_relaxed(0, wrapper_base + VENUS_WRAPPER_CLOCK_CONFIG);
@@ -365,6 +398,17 @@
 
 	iommu_detach_device(drv->iommu_fw_domain, drv->iommu_fw_ctx);
 
+	/*
+	 * Force the VBIF clk to be on to avoid AXI bridge halt ack failure
+	 * for certain Venus version.
+	 */
+	if (drv->hw_ver_major == 0x1 &&
+		(drv->hw_ver_minor == 0x2 || drv->hw_ver_minor == 0x3)) {
+		reg = readl_relaxed(vbif_base + VENUS_VBIF_CLKON);
+		reg |= VENUS_VBIF_CLKON_FORCE_ON;
+		writel_relaxed(reg, vbif_base + VENUS_VBIF_CLKON);
+	}
+
 	/* Halt AXI and AXI OCMEM VBIF Access */
 	reg = readl_relaxed(vbif_base + VENUS_VBIF_AXI_HALT_CTRL0);
 	reg |= VENUS_VBIF_AXI_HALT_CTRL0_HALT_REQ;
@@ -401,6 +445,12 @@
 	return pas_init_image(PAS_VIDC, metadata, size);
 }
 
+static int pil_venus_mem_setup_trusted(struct pil_desc *pil, phys_addr_t addr,
+			       size_t size)
+{
+	return pas_mem_setup(PAS_VIDC, addr, size);
+}
+
 static int pil_venus_reset_trusted(struct pil_desc *pil)
 {
 	int rc;
@@ -442,6 +492,7 @@
 
 static struct pil_reset_ops pil_venus_ops_trusted = {
 	.init_image = pil_venus_init_image_trusted,
+	.mem_setup =  pil_venus_mem_setup_trusted,
 	.auth_and_reset = pil_venus_reset_trusted,
 	.shutdown = pil_venus_shutdown_trusted,
 	.proxy_vote = pil_venus_make_proxy_vote,
@@ -537,6 +588,7 @@
 	if (rc)
 		return rc;
 
+
 	desc->dev = &pdev->dev;
 	desc->owner = THIS_MODULE;
 	desc->proxy_timeout = VENUS_PROXY_TIMEOUT;
diff --git a/arch/arm/mach-msm/pil-vidc.c b/arch/arm/mach-msm/pil-vidc.c
index 42bb51c..629907f 100644
--- a/arch/arm/mach-msm/pil-vidc.c
+++ b/arch/arm/mach-msm/pil-vidc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/ping_apps_server.c b/arch/arm/mach-msm/ping_apps_server.c
index 0a85600..4499f76 100644
--- a/arch/arm/mach-msm/ping_apps_server.c
+++ b/arch/arm/mach-msm/ping_apps_server.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/ping_mdm_rpc_client.c b/arch/arm/mach-msm/ping_mdm_rpc_client.c
index 57ac85d..4044836 100644
--- a/arch/arm/mach-msm/ping_mdm_rpc_client.c
+++ b/arch/arm/mach-msm/ping_mdm_rpc_client.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
index 80f6014..e7b4cea 100644
--- a/arch/arm/mach-msm/platsmp.c
+++ b/arch/arm/mach-msm/platsmp.c
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 2002 ARM Ltd.
  *  All Rights Reserved
- *  Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *  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 as
@@ -35,7 +35,6 @@
 #define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0
 #define SCSS_CPU1CORE_RESET 0xD80
 #define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64
-#define BOOT_REMAP_ENABLE 0x01
 
 /*
  * control for which core is the next to come out of the secondary
@@ -82,7 +81,7 @@
 	spin_unlock(&boot_lock);
 }
 
-static int __cpuinit release_secondary_sim(unsigned long base, int cpu)
+static int __cpuinit release_secondary_sim(unsigned long base, unsigned int cpu)
 {
 	void *base_ptr = ioremap_nocache(base + (cpu * 0x10000), SZ_4K);
 	if (!base_ptr)
@@ -112,7 +111,8 @@
 	return 0;
 }
 
-static int __cpuinit msm8960_release_secondary(unsigned long base, int cpu)
+static int __cpuinit msm8960_release_secondary(unsigned long base,
+						unsigned int cpu)
 {
 	void *base_ptr = ioremap_nocache(base + (cpu * 0x10000), SZ_4K);
 	if (!base_ptr)
@@ -143,7 +143,8 @@
 	return 0;
 }
 
-static int __cpuinit msm8974_release_secondary(unsigned long base, int cpu)
+static int __cpuinit msm8974_release_secondary(unsigned long base,
+						unsigned int cpu)
 {
 	void *base_ptr = ioremap_nocache(base + (cpu * 0x10000), SZ_4K);
 	if (!base_ptr)
@@ -168,6 +169,41 @@
 	return 0;
 }
 
+static int __cpuinit arm_release_secondary(unsigned long base, unsigned int cpu)
+{
+	void *base_ptr = ioremap_nocache(base + (cpu * 0x10000), SZ_4K);
+	if (!base_ptr)
+		return -ENODEV;
+
+	writel_relaxed(0x00000033, base_ptr+0x04);
+	mb();
+
+	writel_relaxed(0x10000001, base_ptr+0x14);
+	mb();
+	udelay(2);
+
+	writel_relaxed(0x00000031, base_ptr+0x04);
+	mb();
+
+	writel_relaxed(0x00000039, base_ptr+0x04);
+	mb();
+	udelay(2);
+
+	writel_relaxed(0x00020038, base_ptr+0x04);
+	mb();
+	udelay(2);
+
+
+	writel_relaxed(0x00020008, base_ptr+0x04);
+	mb();
+
+	writel_relaxed(0x00020088, base_ptr+0x04);
+	mb();
+
+	iounmap(base_ptr);
+	return 0;
+}
+
 static int __cpuinit release_from_pen(unsigned int cpu)
 {
 	unsigned long timeout;
@@ -248,9 +284,7 @@
 	if (per_cpu(cold_boot_done, cpu) == false) {
 		if (machine_is_msm8974_sim() || machine_is_mpq8092_sim())
 			release_secondary_sim(0xf9088000, cpu);
-		else if (machine_is_msm8974_rumi())
-			return 0;
-		else
+		else if (!machine_is_msm8974_rumi())
 			msm8974_release_secondary(0xf9088000, cpu);
 
 		per_cpu(cold_boot_done, cpu) = true;
@@ -263,8 +297,10 @@
 	pr_debug("Starting secondary CPU %d\n", cpu);
 
 	if (per_cpu(cold_boot_done, cpu) == false) {
-		if (machine_is_msm8226_sim() || machine_is_msm8910_sim())
+		if (machine_is_msm8226_sim() || machine_is_msm8610_sim())
 			release_secondary_sim(0xf9088000, cpu);
+		else if (!machine_is_msm8610_rumi())
+			arm_release_secondary(0xf9088000, cpu);
 
 		per_cpu(cold_boot_done, cpu) = true;
 	}
@@ -335,27 +371,9 @@
 		pr_warn("Failed to set CPU boot address\n");
 }
 
-static void __init arm_platform_smp_prepare_cpus(unsigned int max_cpus)
-{
-	void *remap_ptr = ioremap_nocache(0xF9010000, SZ_4K);
-	if (!remap_ptr) {
-		pr_err("Failed to ioremap for secondary cores\n");
-		return;
-	}
-
-	/*
-	 * Write the address of secondary startup into boot remapper
-	 * register and enable boot remapping.
-	 */
-	__raw_writel((virt_to_phys(msm_secondary_startup)|BOOT_REMAP_ENABLE),
-			(remap_ptr + 0x4));
-	mb();
-	iounmap(remap_ptr);
-}
-
 struct smp_operations arm_smp_ops __initdata = {
 	.smp_init_cpus = arm_smp_init_cpus,
-	.smp_prepare_cpus = arm_platform_smp_prepare_cpus,
+	.smp_prepare_cpus = msm_platform_smp_prepare_cpus,
 	.smp_secondary_init = platform_secondary_init,
 	.smp_boot_secondary = arm_boot_secondary,
 	.cpu_kill = platform_cpu_kill,
diff --git a/arch/arm/mach-msm/pm-8x60.c b/arch/arm/mach-msm/pm-8x60.c
index b42ad94..b52d284 100644
--- a/arch/arm/mach-msm/pm-8x60.c
+++ b/arch/arm/mach-msm/pm-8x60.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+/* 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
@@ -11,6 +11,7 @@
  *
  */
 
+#include <linux/debugfs.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -25,6 +26,7 @@
 #include <linux/suspend.h>
 #include <linux/tick.h>
 #include <linux/platform_device.h>
+#include <linux/regulator/krait-regulator.h>
 #include <mach/msm_iomap.h>
 #include <mach/socinfo.h>
 #include <mach/system.h>
@@ -39,7 +41,6 @@
 #ifdef CONFIG_VFP
 #include <asm/vfp.h>
 #endif
-
 #include "acpuclock.h"
 #include "clock.h"
 #include "avs.h"
@@ -53,9 +54,27 @@
 #include <mach/event_timer.h>
 #define CREATE_TRACE_POINTS
 #include "trace_msm_low_power.h"
-/******************************************************************************
- * Debug Definitions
- *****************************************************************************/
+
+#define SCM_L2_RETENTION	(0x2)
+#define SCM_CMD_TERMINATE_PC	(0x2)
+
+#define GET_CPU_OF_ATTR(attr) \
+	(container_of(attr, struct msm_pm_kobj_attribute, ka)->cpu)
+
+#define SCLK_HZ (32768)
+#define MSM_PM_SLEEP_TICK_LIMIT (0x6DDD000)
+
+#define NUM_OF_COUNTERS 3
+#define MAX_BUF_SIZE  512
+
+static int msm_pm_debug_mask = 1;
+module_param_named(
+	debug_mask, msm_pm_debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP
+);
+
+static int msm_pm_sleep_time_override;
+module_param_named(sleep_time_override,
+	msm_pm_sleep_time_override, int, S_IRUGO | S_IWUSR | S_IWGRP);
 
 enum {
 	MSM_PM_DEBUG_SUSPEND = BIT(0),
@@ -69,24 +88,12 @@
 	MSM_PM_DEBUG_HOTPLUG = BIT(8),
 };
 
-static int msm_pm_debug_mask = 1;
-module_param_named(
-	debug_mask, msm_pm_debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP
-);
-static int msm_pm_retention_tz_call;
-
-/******************************************************************************
- * Sleep Modes and Parameters
- *****************************************************************************/
 enum {
 	MSM_PM_MODE_ATTR_SUSPEND,
 	MSM_PM_MODE_ATTR_IDLE,
 	MSM_PM_MODE_ATTR_NR,
 };
 
-#define SCM_L2_RETENTION	(0x2)
-#define SCM_CMD_TERMINATE_PC	(0x2)
-
 static char *msm_pm_mode_attr_labels[MSM_PM_MODE_ATTR_NR] = {
 	[MSM_PM_MODE_ATTR_SUSPEND] = "suspend_enabled",
 	[MSM_PM_MODE_ATTR_IDLE] = "idle_enabled",
@@ -97,9 +104,6 @@
 	struct kobj_attribute ka;
 };
 
-#define GET_CPU_OF_ATTR(attr) \
-	(container_of(attr, struct msm_pm_kobj_attribute, ka)->cpu)
-
 struct msm_pm_sysfs_sleep_mode {
 	struct kobject *kobj;
 	struct attribute_group attr_group;
@@ -115,9 +119,15 @@
 		"standalone_power_collapse",
 };
 
-static struct msm_pm_init_data_type msm_pm_init_data;
 static struct hrtimer pm_hrtimer;
 static struct msm_pm_sleep_ops pm_sleep_ops;
+static bool msm_pm_ldo_retention_enabled = true;
+static bool msm_pm_use_sync_timer;
+static struct msm_pm_cp15_save_data cp15_data;
+static bool msm_pm_retention_calls_tz;
+static uint32_t msm_pm_max_sleep_time;
+static bool msm_no_ramp_down_pc;
+
 /*
  * Write out the attribute.
  */
@@ -164,9 +174,6 @@
 	return ret;
 }
 
-/*
- * Read in the new attribute value.
- */
 static ssize_t msm_pm_mode_attr_store(struct kobject *kobj,
 	struct kobj_attribute *attr, const char *buf, size_t count)
 {
@@ -203,10 +210,7 @@
 	return ret ? ret : count;
 }
 
-/*
- * Add sysfs entries for one cpu.
- */
-static int __init msm_pm_mode_sysfs_add_cpu(
+static int __devinit msm_pm_mode_sysfs_add_cpu(
 	unsigned int cpu, struct kobject *modes_kobj)
 {
 	char cpu_name[8];
@@ -289,10 +293,7 @@
 	return ret;
 }
 
-/*
- * Add sysfs entries for the sleep modes.
- */
-static int __init msm_pm_mode_sysfs_add(void)
+int __devinit msm_pm_mode_sysfs_add(void)
 {
 	struct kobject *module_kobj;
 	struct kobject *modes_kobj;
@@ -326,10 +327,6 @@
 	return ret;
 }
 
-/******************************************************************************
- * Configure Hardware before/after Low Power Mode
- *****************************************************************************/
-
 /*
  * Configure hardware registers in preparation for Apps power down.
  */
@@ -360,31 +357,18 @@
 static void msm_pm_config_hw_after_retention(void)
 {
 	int ret;
+
 	ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_CLOCK_GATING, false);
 	WARN_ON(ret);
+	krait_power_mdd_enable(smp_processor_id(), false);
 }
 
 static void msm_pm_config_hw_before_retention(void)
 {
+	krait_power_mdd_enable(smp_processor_id(), true);
 	return;
 }
 
-
-/******************************************************************************
- * Suspend Max Sleep Time
- *****************************************************************************/
-
-#ifdef CONFIG_MSM_SLEEP_TIME_OVERRIDE
-static int msm_pm_sleep_time_override;
-module_param_named(sleep_time_override,
-	msm_pm_sleep_time_override, int, S_IRUGO | S_IWUSR | S_IWGRP);
-#endif
-
-#define SCLK_HZ (32768)
-#define MSM_PM_SLEEP_TICK_LIMIT (0x6DDD000)
-
-static uint32_t msm_pm_max_sleep_time;
-
 /*
  * Convert time from nanoseconds to slow clock ticks, then cap it to the
  * specified limit
@@ -403,36 +387,21 @@
 	if (max_sleep_time_ns == 0) {
 		msm_pm_max_sleep_time = 0;
 	} else {
-		msm_pm_max_sleep_time = (uint32_t)msm_pm_convert_and_cap_time(
+		msm_pm_max_sleep_time =
+			(uint32_t)msm_pm_convert_and_cap_time(
 			max_sleep_time_ns, MSM_PM_SLEEP_TICK_LIMIT);
 
 		if (msm_pm_max_sleep_time == 0)
 			msm_pm_max_sleep_time = 1;
 	}
 
-	if (msm_pm_debug_mask & MSM_PM_DEBUG_SUSPEND)
+	if (MSM_PM_DEBUG_SUSPEND & msm_pm_debug_mask)
 		pr_info("%s: Requested %lld ns Giving %u sclk ticks\n",
-			__func__, max_sleep_time_ns, msm_pm_max_sleep_time);
+			__func__, max_sleep_time_ns,
+			msm_pm_max_sleep_time);
 }
 EXPORT_SYMBOL(msm_pm_set_max_sleep_time);
 
-struct reg_data {
-	uint32_t reg;
-	uint32_t val;
-};
-
-static struct reg_data reg_saved_state[] = {
-	{ .reg = 0x4501, },
-	{ .reg = 0x5501, },
-	{ .reg = 0x6501, },
-	{ .reg = 0x7501, },
-	{ .reg = 0x0500, },
-};
-
-static unsigned int active_vdd;
-static bool msm_pm_save_cp15;
-static const unsigned int pc_vdd = 0x98;
-
 static void msm_pm_save_cpu_reg(void)
 {
 	int i;
@@ -450,11 +419,12 @@
 	 * rate. Then restore the active vdd before switching the acpuclk rate.
 	 */
 	if (msm_pm_get_l2_flush_flag() == 1) {
-		active_vdd = msm_spm_get_vdd(0);
-		for (i = 0; i < ARRAY_SIZE(reg_saved_state); i++)
-			reg_saved_state[i].val =
-				get_l2_indirect_reg(reg_saved_state[i].reg);
-		msm_spm_set_vdd(0, pc_vdd);
+		cp15_data.active_vdd = msm_spm_get_vdd(0);
+		for (i = 0; i < cp15_data.reg_saved_state_size; i++)
+			cp15_data.reg_val[i] =
+				get_l2_indirect_reg(
+					cp15_data.reg_data[i]);
+		msm_spm_set_vdd(0, cp15_data.qsb_pc_vdd);
 	}
 }
 
@@ -467,22 +437,20 @@
 		return;
 
 	if (msm_pm_get_l2_flush_flag() == 1) {
-		for (i = 0; i < ARRAY_SIZE(reg_saved_state); i++)
-			set_l2_indirect_reg(reg_saved_state[i].reg,
-					reg_saved_state[i].val);
-		msm_spm_set_vdd(0, active_vdd);
+		for (i = 0; i < cp15_data.reg_saved_state_size; i++)
+			set_l2_indirect_reg(
+					cp15_data.reg_data[i],
+					cp15_data.reg_val[i]);
+		msm_spm_set_vdd(0, cp15_data.active_vdd);
 	}
 }
 
-static void *msm_pm_idle_rs_limits;
-
 static void msm_pm_swfi(void)
 {
 	msm_pm_config_hw_before_swfi();
 	msm_arch_idle();
 }
 
-
 static void msm_pm_retention(void)
 {
 	int ret = 0;
@@ -491,7 +459,7 @@
 	ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_POWER_RETENTION, false);
 	WARN_ON(ret);
 
-	if (msm_pm_retention_tz_call)
+	if (msm_pm_retention_calls_tz)
 		scm_call_atomic1(SCM_SVC_BOOT, SCM_CMD_TERMINATE_PC,
 					SCM_L2_RETENTION);
 	else
@@ -506,10 +474,6 @@
 	void *entry;
 	bool collapsed = 0;
 	int ret;
-	unsigned int saved_gic_cpu_ctrl;
-
-	saved_gic_cpu_ctrl = readl_relaxed(MSM_QGIC_CPU_BASE + GIC_CPU_CTRL);
-	mb();
 
 	if (MSM_PM_DEBUG_POWER_COLLAPSE & msm_pm_debug_mask)
 		pr_info("CPU%u: %s: notify_rpm %d\n",
@@ -527,22 +491,12 @@
 		pr_info("CPU%u: %s: program vector to %p\n",
 			cpu, __func__, entry);
 
-#ifdef CONFIG_VFP
-	vfp_pm_suspend();
-#endif
 	collapsed = msm_pm_collapse();
 
 	msm_pm_boot_config_after_pc(cpu);
 
 	if (collapsed) {
-#ifdef CONFIG_VFP
-		vfp_pm_resume();
-#endif
 		cpu_init();
-		writel(0xF0, MSM_QGIC_CPU_BASE + GIC_CPU_PRIMASK);
-		writel_relaxed(saved_gic_cpu_ctrl,
-				MSM_QGIC_CPU_BASE + GIC_CPU_CTRL);
-		mb();
 		local_fiq_enable();
 	}
 
@@ -576,7 +530,7 @@
 static bool msm_pm_power_collapse(bool from_idle)
 {
 	unsigned int cpu = smp_processor_id();
-	unsigned long saved_acpuclk_rate;
+	unsigned long saved_acpuclk_rate = 0;
 	unsigned int avsdscr;
 	unsigned int avscsr;
 	bool collapsed;
@@ -593,28 +547,28 @@
 	avscsr = avs_get_avscsr();
 	avs_set_avscsr(0); /* Disable AVS */
 
-	if (cpu_online(cpu))
+	if (cpu_online(cpu) && !msm_no_ramp_down_pc)
 		saved_acpuclk_rate = acpuclk_power_collapse();
-	else
-		saved_acpuclk_rate = 0;
 
 	if (MSM_PM_DEBUG_CLOCK & msm_pm_debug_mask)
 		pr_info("CPU%u: %s: change clock rate (old rate = %lu)\n",
 			cpu, __func__, saved_acpuclk_rate);
 
-	if (msm_pm_save_cp15)
+	if (cp15_data.save_cp15)
 		msm_pm_save_cpu_reg();
 
 	collapsed = msm_pm_spm_power_collapse(cpu, from_idle, true);
 
-	if (msm_pm_save_cp15)
+	if (cp15_data.save_cp15)
 		msm_pm_restore_cpu_reg();
 
 	if (cpu_online(cpu)) {
 		if (MSM_PM_DEBUG_CLOCK & msm_pm_debug_mask)
 			pr_info("CPU%u: %s: restore clock rate to %lu\n",
 				cpu, __func__, saved_acpuclk_rate);
-		if (acpuclk_set_rate(cpu, saved_acpuclk_rate, SETRATE_PC) < 0)
+		if (!msm_no_ramp_down_pc &&
+			acpuclk_set_rate(cpu, saved_acpuclk_rate, SETRATE_PC)
+				< 0)
 			pr_err("CPU%u: %s: failed to restore clock rate(%lu)\n",
 				cpu, __func__, saved_acpuclk_rate);
 	} else {
@@ -644,15 +598,9 @@
 	return collapsed;
 }
 
-static void msm_pm_target_init(void)
-{
-	if (cpu_is_apq8064())
-		msm_pm_save_cp15 = true;
-}
-
 static int64_t msm_pm_timer_enter_idle(void)
 {
-	if (msm_pm_init_data.use_sync_timer)
+	if (msm_pm_use_sync_timer)
 		return ktime_to_ns(tick_nohz_get_sleep_length());
 
 	return msm_timer_enter_idle();
@@ -660,7 +608,7 @@
 
 static void msm_pm_timer_exit_idle(bool timer_halted)
 {
-	if (msm_pm_init_data.use_sync_timer)
+	if (msm_pm_use_sync_timer)
 		return;
 
 	msm_timer_exit_idle((int) timer_halted);
@@ -670,8 +618,8 @@
 {
 	int64_t time = 0;
 
-	if (msm_pm_init_data.use_sync_timer)
-		return sched_clock();
+	if (msm_pm_use_sync_timer)
+		return ktime_to_ns(ktime_get());
 
 	time = msm_timer_get_sclk_time(period);
 	if (!time)
@@ -682,8 +630,8 @@
 
 static int64_t msm_pm_timer_exit_suspend(int64_t time, int64_t period)
 {
-	if (msm_pm_init_data.use_sync_timer)
-		return sched_clock() - time;
+	if (msm_pm_use_sync_timer)
+		return ktime_to_ns(ktime_get()) - time;
 
 	if (time != 0) {
 		int64_t end_time = msm_timer_get_sclk_time(NULL);
@@ -774,12 +722,13 @@
 	}
 }
 
-int msm_pm_idle_prepare(struct cpuidle_device *dev,
-		struct cpuidle_driver *drv, int index)
+static int msm_pm_idle_prepare(struct cpuidle_device *dev,
+		struct cpuidle_driver *drv, int index,
+		void **msm_pm_idle_rs_limits)
 {
 	int i;
 	unsigned int power_usage = -1;
-	int ret = 0;
+	int ret = MSM_PM_SLEEP_MODE_NOT_SELECTED;
 	uint32_t modified_time_us = 0;
 	struct msm_pm_time_params time_param;
 
@@ -802,9 +751,9 @@
 		struct cpuidle_state_usage *st_usage = &dev->states_usage[i];
 		enum msm_pm_sleep_mode mode;
 		bool allow;
-		void *rs_limits = NULL;
 		uint32_t power;
 		int idx;
+		void *rs_limits = NULL;
 
 		mode = (enum msm_pm_sleep_mode) cpuidle_get_statedata(st_usage);
 		idx = MSM_PM_MODE(dev->cpu, mode);
@@ -814,66 +763,51 @@
 
 		switch (mode) {
 		case MSM_PM_SLEEP_MODE_POWER_COLLAPSE:
-			if (num_online_cpus() > 1) {
-				allow = false;
-				break;
-			}
-			/* fall through */
-		case MSM_PM_SLEEP_MODE_RETENTION:
-			if (!allow)
-				break;
-
-			if (msm_pm_retention_tz_call &&
-				num_online_cpus() > 1) {
-				allow = false;
-				break;
-			}
-			/* fall through */
-
-		case MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE:
-			if (!allow)
-				break;
-			/* fall through */
-
-		case MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT:
-			if (!allow)
-				break;
-			/* fall through */
-
-			if (pm_sleep_ops.lowest_limits)
-				rs_limits = pm_sleep_ops.lowest_limits(true,
-						mode, &time_param, &power);
-
-			if (MSM_PM_DEBUG_IDLE & msm_pm_debug_mask)
-				pr_info("CPU%u: %s: %s, latency %uus, "
-					"sleep %uus, limit %p\n",
-					dev->cpu, __func__, state->desc,
-					time_param.latency_us,
-					time_param.sleep_us, rs_limits);
-
-			if (!rs_limits)
+			if (num_online_cpus() > 1)
 				allow = false;
 			break;
+		case MSM_PM_SLEEP_MODE_RETENTION:
+			/*
+			 * The Krait BHS regulator doesn't have enough head
+			 * room to drive the retention voltage on LDO and so
+			 * has disabled retention
+			 */
+			if (!msm_pm_ldo_retention_enabled)
+				allow = false;
 
+			if (msm_pm_retention_calls_tz && num_online_cpus() > 1)
+				allow = false;
+			break;
+		case MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE:
+		case MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT:
+			break;
 		default:
 			allow = false;
 			break;
 		}
 
+		if (!allow)
+			continue;
+
+		if (pm_sleep_ops.lowest_limits)
+			rs_limits = pm_sleep_ops.lowest_limits(true,
+					mode, &time_param, &power);
+
 		if (MSM_PM_DEBUG_IDLE & msm_pm_debug_mask)
-			pr_info("CPU%u: %s: allow %s: %d\n",
-				dev->cpu, __func__, state->desc, (int)allow);
+			pr_info("CPU%u:%s:%s, latency %uus, slp %uus, lim %p\n",
+					dev->cpu, __func__, state->desc,
+					time_param.latency_us,
+					time_param.sleep_us, rs_limits);
+		if (!rs_limits)
+			continue;
 
-		if (allow) {
-			if (power < power_usage) {
-				power_usage = power;
-				modified_time_us = time_param.modified_time_us;
-				ret = mode;
-			}
-
-			if (MSM_PM_SLEEP_MODE_POWER_COLLAPSE == mode)
-				msm_pm_idle_rs_limits = rs_limits;
+		if (power < power_usage) {
+			power_usage = power;
+			modified_time_us = time_param.modified_time_us;
+			ret = mode;
+			*msm_pm_idle_rs_limits = rs_limits;
 		}
+
 	}
 
 	if (modified_time_us && !dev->cpu)
@@ -886,11 +820,27 @@
 	return ret;
 }
 
-int msm_pm_idle_enter(enum msm_pm_sleep_mode sleep_mode)
+enum msm_pm_sleep_mode msm_pm_idle_enter(struct cpuidle_device *dev,
+	struct cpuidle_driver *drv, int index)
 {
 	int64_t time;
-	int exit_stat;
 	bool collapsed = 1;
+	int exit_stat = -1;
+	enum msm_pm_sleep_mode sleep_mode;
+	void *msm_pm_idle_rs_limits = NULL;
+	int sleep_delay = 1;
+	int ret = -ENODEV;
+	int64_t timer_expiration = 0;
+	int notify_rpm = false;
+	bool timer_halted = false;
+
+	sleep_mode = msm_pm_idle_prepare(dev, drv, index,
+		&msm_pm_idle_rs_limits);
+
+	if (!msm_pm_idle_rs_limits) {
+		sleep_mode = MSM_PM_SLEEP_MODE_NOT_SELECTED;
+		goto cpuidle_enter_bail;
+	}
 
 	if (MSM_PM_DEBUG_IDLE & msm_pm_debug_mask)
 		pr_info("CPU%u: %s: mode %d\n",
@@ -898,6 +848,22 @@
 
 	time = ktime_to_ns(ktime_get());
 
+	if (sleep_mode == MSM_PM_SLEEP_MODE_POWER_COLLAPSE) {
+		notify_rpm = true;
+		timer_expiration = msm_pm_timer_enter_idle();
+
+		sleep_delay = (uint32_t) msm_pm_convert_and_cap_time(
+			timer_expiration, MSM_PM_SLEEP_TICK_LIMIT);
+		if (sleep_delay == 0) /* 0 would mean infinite time */
+			sleep_delay = 1;
+	}
+
+	if (pm_sleep_ops.enter_sleep)
+		ret = pm_sleep_ops.enter_sleep(sleep_delay,
+			msm_pm_idle_rs_limits, true, notify_rpm);
+	if (ret)
+		goto cpuidle_enter_bail;
+
 	switch (sleep_mode) {
 	case MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT:
 		msm_pm_swfi();
@@ -914,55 +880,45 @@
 		exit_stat = MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE;
 		break;
 
-	case MSM_PM_SLEEP_MODE_POWER_COLLAPSE: {
-		int64_t timer_expiration = 0;
-		bool timer_halted = false;
-		uint32_t sleep_delay;
-		int ret = -ENODEV;
-		int notify_rpm =
-			(sleep_mode == MSM_PM_SLEEP_MODE_POWER_COLLAPSE);
-		timer_expiration = msm_pm_timer_enter_idle();
-
-		sleep_delay = (uint32_t) msm_pm_convert_and_cap_time(
-			timer_expiration, MSM_PM_SLEEP_TICK_LIMIT);
-		if (sleep_delay == 0) /* 0 would mean infinite time */
-			sleep_delay = 1;
-
+	case MSM_PM_SLEEP_MODE_POWER_COLLAPSE:
 		if (MSM_PM_DEBUG_IDLE_CLK & msm_pm_debug_mask)
 			clock_debug_print_enabled();
 
-		if (pm_sleep_ops.enter_sleep)
-			ret = pm_sleep_ops.enter_sleep(sleep_delay,
-					msm_pm_idle_rs_limits,
-					true, notify_rpm);
-		if (!ret) {
-			collapsed = msm_pm_power_collapse(true);
-			timer_halted = true;
+		collapsed = msm_pm_power_collapse(true);
+		timer_halted = true;
 
-			if (pm_sleep_ops.exit_sleep)
-				pm_sleep_ops.exit_sleep(msm_pm_idle_rs_limits,
-						true, notify_rpm, collapsed);
-		}
-		msm_pm_timer_exit_idle(timer_halted);
 		exit_stat = MSM_PM_STAT_IDLE_POWER_COLLAPSE;
+		msm_pm_timer_exit_idle(timer_halted);
 		break;
-	}
+
+	case MSM_PM_SLEEP_MODE_NOT_SELECTED:
+		goto cpuidle_enter_bail;
+		break;
 
 	default:
 		__WARN();
 		goto cpuidle_enter_bail;
+		break;
 	}
 
-	time = ktime_to_ns(ktime_get()) - time;
-	msm_pm_add_stat(exit_stat, time);
-	msm_pm_ftrace_lpm_exit(smp_processor_id(), sleep_mode,
-				collapsed);
+	if (pm_sleep_ops.exit_sleep)
+		pm_sleep_ops.exit_sleep(msm_pm_idle_rs_limits, true,
+				notify_rpm, collapsed);
 
+	time = ktime_to_ns(ktime_get()) - time;
+	msm_pm_ftrace_lpm_exit(smp_processor_id(), sleep_mode, collapsed);
+	if (exit_stat >= 0)
+		msm_pm_add_stat(exit_stat, time);
 	do_div(time, 1000);
-	return (int) time;
+	dev->last_residency = (int) time;
+	return sleep_mode;
 
 cpuidle_enter_bail:
-	return 0;
+	dev->last_residency = 0;
+	if (sleep_mode == MSM_PM_SLEEP_MODE_POWER_COLLAPSE)
+		msm_pm_timer_exit_idle(timer_halted);
+	sleep_mode = MSM_PM_SLEEP_MODE_NOT_SELECTED;
+	return sleep_mode;
 }
 
 void msm_pm_cpu_enter_lowpower(unsigned int cpu)
@@ -990,6 +946,34 @@
 		msm_pm_swfi();
 }
 
+static void msm_pm_ack_retention_disable(void *data)
+{
+	/*
+	 * This is a NULL function to ensure that the core has woken up
+	 * and is safe to disable retention.
+	 */
+}
+/**
+ * msm_pm_enable_retention() - Disable/Enable retention on all cores
+ * @enable: Enable/Disable retention
+ *
+ */
+void msm_pm_enable_retention(bool enable)
+{
+	msm_pm_ldo_retention_enabled = enable;
+	/*
+	 * If retention is being disabled, wakeup all online core to ensure
+	 * that it isn't executing retention. Offlined cores need not be woken
+	 * up as they enter the deepest sleep mode, namely RPM assited power
+	 * collapse
+	 */
+	if (!enable)
+		smp_call_function_many(cpu_online_mask,
+				msm_pm_ack_retention_disable,
+				NULL, true);
+}
+EXPORT_SYMBOL(msm_pm_enable_retention);
+
 static int msm_pm_enter(suspend_state_t state)
 {
 	bool allow[MSM_PM_SLEEP_MODE_NR];
@@ -1028,17 +1012,16 @@
 
 		clock_debug_print_enabled();
 
-#ifdef CONFIG_MSM_SLEEP_TIME_OVERRIDE
 		if (msm_pm_sleep_time_override > 0) {
 			int64_t ns = NSEC_PER_SEC *
 				(int64_t) msm_pm_sleep_time_override;
 			msm_pm_set_max_sleep_time(ns);
 			msm_pm_sleep_time_override = 0;
 		}
-#endif /* CONFIG_MSM_SLEEP_TIME_OVERRIDE */
+
 		if (pm_sleep_ops.lowest_limits)
 			rs_limits = pm_sleep_ops.lowest_limits(false,
-			MSM_PM_SLEEP_MODE_POWER_COLLAPSE, &time_param, &power);
+		MSM_PM_SLEEP_MODE_POWER_COLLAPSE, &time_param, &power);
 
 		if (rs_limits) {
 			if (pm_sleep_ops.enter_sleep)
@@ -1072,7 +1055,6 @@
 		msm_pm_swfi();
 	}
 
-
 enter_exit:
 	if (MSM_PM_DEBUG_SUSPEND & msm_pm_debug_mask)
 		pr_info("%s: return\n", __func__);
@@ -1080,66 +1062,18 @@
 	return 0;
 }
 
-static struct platform_suspend_ops msm_pm_ops = {
-	.enter = msm_pm_enter,
-	.valid = suspend_valid_only_mem,
-};
-
-/******************************************************************************
- * Initialization routine
- *****************************************************************************/
 void msm_pm_set_sleep_ops(struct msm_pm_sleep_ops *ops)
 {
 	if (ops)
 		pm_sleep_ops = *ops;
 }
 
-void __init msm_pm_set_tz_retention_flag(unsigned int flag)
-{
-	msm_pm_retention_tz_call = flag;
-}
-
-static int __devinit msm_pc_debug_probe(struct platform_device *pdev)
-{
-	struct resource *res = NULL;
-	int i ;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res)
-		goto fail;
-
-	msm_pc_debug_counters_phys = res->start;
-	WARN_ON(resource_size(res) < SZ_64);
-	msm_pc_debug_counters = devm_ioremap_nocache(&pdev->dev, res->start,
-					resource_size(res));
-
-	if (!msm_pc_debug_counters)
-		goto fail;
-
-	for (i = 0; i < resource_size(res)/4; i++)
-		__raw_writel(0, msm_pc_debug_counters + i * 4);
-	return 0;
-fail:
-	msm_pc_debug_counters = 0;
-	msm_pc_debug_counters_phys = 0;
-	return -EFAULT;
-}
-
-static struct of_device_id msm_pc_debug_table[] = {
-	{.compatible = "qcom,pc-cntr"},
-	{},
+static const struct platform_suspend_ops msm_pm_ops = {
+	.enter = msm_pm_enter,
+	.valid = suspend_valid_only_mem,
 };
 
-static struct platform_driver msm_pc_counter_driver = {
-	.probe = msm_pc_debug_probe,
-	.driver = {
-		.name = "pc-cntr",
-		.owner = THIS_MODULE,
-		.of_match_table = msm_pc_debug_table,
-	},
-};
-
-static int __init msm_pm_init(void)
+static int __devinit msm_pm_init(void)
 {
 	pgd_t *pc_pgd;
 	pmd_t *pmd;
@@ -1154,7 +1088,6 @@
 	unsigned long exit_phys;
 
 	/* Page table for cores to come back up safely. */
-
 	pc_pgd = pgd_alloc(&init_mm);
 	if (!pc_pgd)
 		return -ENOMEM;
@@ -1193,18 +1126,13 @@
 
 	msm_pm_mode_sysfs_add();
 	msm_pm_add_stats(enable_stats, ARRAY_SIZE(enable_stats));
-
 	suspend_set_ops(&msm_pm_ops);
-	msm_pm_target_init();
 	hrtimer_init(&pm_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
 	msm_cpuidle_init();
-	platform_driver_register(&msm_pc_counter_driver);
 
 	return 0;
 }
 
-late_initcall(msm_pm_init);
-
 static void __devinit msm_pm_set_flush_fn(uint32_t pc_mode)
 {
 	msm_pm_disable_l2_fn = NULL;
@@ -1217,41 +1145,203 @@
 	}
 }
 
+struct msm_pc_debug_counters_buffer {
+	void __iomem *reg;
+	u32 len;
+	char buf[MAX_BUF_SIZE];
+};
+
+static inline u32 msm_pc_debug_counters_read_register(
+		void __iomem *reg, int index , int offset)
+{
+	return readl_relaxed(reg + (index * 4 + offset) * 4);
+}
+
+static char *counter_name[] = {
+		"PC Entry Counter",
+		"Warmboot Entry Counter",
+		"PC Bailout Counter"
+};
+
+static int msm_pc_debug_counters_copy(
+		struct msm_pc_debug_counters_buffer *data)
+{
+	int j;
+	u32 stat;
+	unsigned int cpu;
+
+	for_each_possible_cpu(cpu) {
+		data->len += scnprintf(data->buf + data->len,
+				sizeof(data->buf)-data->len,
+				"CPU%d\n", cpu);
+
+			for (j = 0; j < NUM_OF_COUNTERS; j++) {
+				stat = msm_pc_debug_counters_read_register(
+						data->reg, cpu, j);
+				data->len += scnprintf(data->buf + data->len,
+					sizeof(data->buf)-data->len,
+					"\t%s : %d\n", counter_name[j],
+					stat);
+		}
+
+	}
+
+	return data->len;
+}
+
+static int msm_pc_debug_counters_file_read(struct file *file,
+		char __user *bufu, size_t count, loff_t *ppos)
+{
+	struct msm_pc_debug_counters_buffer *data;
+
+	data = file->private_data;
+
+	if (!data)
+		return -EINVAL;
+
+	if (!bufu || count < 0)
+		return -EINVAL;
+
+	if (!access_ok(VERIFY_WRITE, bufu, count))
+		return -EFAULT;
+
+	if (*ppos >= data->len && data->len == 0)
+		data->len = msm_pc_debug_counters_copy(data);
+
+	return simple_read_from_buffer(bufu, count, ppos,
+			data->buf, data->len);
+}
+
+static int msm_pc_debug_counters_file_open(struct inode *inode,
+		struct file *file)
+{
+	struct msm_pc_debug_counters_buffer *buf;
+	void __iomem *msm_pc_debug_counters_reg;
+
+	msm_pc_debug_counters_reg = inode->i_private;
+
+	if (!msm_pc_debug_counters_reg)
+		return -EINVAL;
+
+	file->private_data = kzalloc(
+		sizeof(struct msm_pc_debug_counters_buffer), GFP_KERNEL);
+
+	if (!file->private_data) {
+		pr_err("%s: ERROR kmalloc failed to allocate %d bytes\n",
+		__func__, sizeof(struct msm_pc_debug_counters_buffer));
+
+		return -ENOMEM;
+	}
+
+	buf = file->private_data;
+	buf->reg = msm_pc_debug_counters_reg;
+
+	return 0;
+}
+
+static int msm_pc_debug_counters_file_close(struct inode *inode,
+		struct file *file)
+{
+	kfree(file->private_data);
+	return 0;
+}
+
+static const struct file_operations msm_pc_debug_counters_fops = {
+	.open = msm_pc_debug_counters_file_open,
+	.read = msm_pc_debug_counters_file_read,
+	.release = msm_pc_debug_counters_file_close,
+	.llseek = no_llseek,
+};
+
 static int __devinit msm_pm_8x60_probe(struct platform_device *pdev)
 {
 	char *key = NULL;
+	struct dentry *dent = NULL;
 	uint32_t val = 0;
+	struct resource *res = NULL;
+	int i ;
+	struct msm_pm_init_data_type pdata_local;
 	int ret = 0;
 
+	memset(&pdata_local, 0, sizeof(struct msm_pm_init_data_type));
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res) {
+		msm_pc_debug_counters_phys = res->start;
+		WARN_ON(resource_size(res) < SZ_64);
+		msm_pc_debug_counters = devm_ioremap(&pdev->dev, res->start,
+					resource_size(res));
+		if (msm_pc_debug_counters)
+			for (i = 0; i < resource_size(res)/4; i++)
+				__raw_writel(0, msm_pc_debug_counters + i * 4);
+
+	}
+
+	if (!msm_pc_debug_counters) {
+		msm_pc_debug_counters = 0;
+		msm_pc_debug_counters_phys = 0;
+	} else {
+		dent = debugfs_create_file("pc_debug_counter", S_IRUGO, NULL,
+				msm_pc_debug_counters,
+				&msm_pc_debug_counters_fops);
+		if (!dent)
+			pr_err("%s: ERROR debugfs_create_file failed\n",
+					__func__);
+	}
+
 	if (!pdev->dev.of_node) {
 		struct msm_pm_init_data_type *d = pdev->dev.platform_data;
 
 		if (!d)
 			goto pm_8x60_probe_done;
 
-		msm_pm_init_data.pc_mode = d->pc_mode;
-		msm_pm_set_flush_fn(msm_pm_init_data.pc_mode);
-		msm_pm_init_data.use_sync_timer = d->use_sync_timer;
+		memcpy(&pdata_local, d, sizeof(struct msm_pm_init_data_type));
+
 	} else {
 		key = "qcom,pc-mode";
 		ret = of_property_read_u32(pdev->dev.of_node, key, &val);
-
 		if (ret) {
 			pr_debug("%s: Cannot read %s,defaulting to 0",
 					__func__, key);
 			val = MSM_PM_PC_TZ_L2_INT;
 			ret = 0;
 		}
-
-		msm_pm_init_data.pc_mode = val;
-		msm_pm_set_flush_fn(msm_pm_init_data.pc_mode);
+		pdata_local.pc_mode = val;
 
 		key = "qcom,use-sync-timer";
-		msm_pm_init_data.use_sync_timer =
+		pdata_local.use_sync_timer =
 			of_property_read_bool(pdev->dev.of_node, key);
+
+		key = "qcom,saw-turns-off-pll";
+		msm_no_ramp_down_pc = of_property_read_bool(pdev->dev.of_node,
+					key);
 	}
 
+	if (pdata_local.cp15_data.reg_data &&
+		pdata_local.cp15_data.reg_saved_state_size > 0) {
+		cp15_data.reg_data = kzalloc(sizeof(uint32_t) *
+				pdata_local.cp15_data.reg_saved_state_size,
+				GFP_KERNEL);
+		if (!cp15_data.reg_data)
+			return -ENOMEM;
+
+		cp15_data.reg_val = kzalloc(sizeof(uint32_t) *
+				pdata_local.cp15_data.reg_saved_state_size,
+				GFP_KERNEL);
+		if (cp15_data.reg_val)
+			return -ENOMEM;
+
+		memcpy(cp15_data.reg_data, pdata_local.cp15_data.reg_data,
+			pdata_local.cp15_data.reg_saved_state_size *
+			sizeof(uint32_t));
+	}
+
+	msm_pm_set_flush_fn(pdata_local.pc_mode);
+	msm_pm_use_sync_timer = pdata_local.use_sync_timer;
+	msm_pm_retention_calls_tz = pdata_local.retention_calls_tz;
+
 pm_8x60_probe_done:
+	msm_pm_init();
 	return ret;
 }
 
@@ -1273,4 +1363,4 @@
 {
 	return platform_driver_register(&msm_pm_8x60_driver);
 }
-module_init(msm_pm_8x60_init);
+device_initcall(msm_pm_8x60_init);
diff --git a/arch/arm/mach-msm/pm-boot.c b/arch/arm/mach-msm/pm-boot.c
index 53cc0f5..c77b19c 100644
--- a/arch/arm/mach-msm/pm-boot.c
+++ b/arch/arm/mach-msm/pm-boot.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/pm-boot.h b/arch/arm/mach-msm/pm-boot.h
index e39ca75..8ca3bb5 100644
--- a/arch/arm/mach-msm/pm-boot.h
+++ b/arch/arm/mach-msm/pm-boot.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/pm-data.c b/arch/arm/mach-msm/pm-data.c
index 6f4743f..ccc2519 100644
--- a/arch/arm/mach-msm/pm-data.c
+++ b/arch/arm/mach-msm/pm-data.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -30,7 +30,7 @@
 
 	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_RETENTION)] = {
 		.idle_supported = 1,
-		.suspend_supported = 1,
+		.suspend_supported = 0,
 		.idle_enabled = 0,
 		.suspend_enabled = 0,
 	},
diff --git a/arch/arm/mach-msm/pm-stats.c b/arch/arm/mach-msm/pm-stats.c
index 675febb..1bd9b46 100644
--- a/arch/arm/mach-msm/pm-stats.c
+++ b/arch/arm/mach-msm/pm-stats.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/pm.h b/arch/arm/mach-msm/pm.h
index bd61feb..c77304d 100644
--- a/arch/arm/mach-msm/pm.h
+++ b/arch/arm/mach-msm/pm.h
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/pm.h
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
  * Author: San Mehat <san@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -52,7 +52,8 @@
 	MSM_PM_SLEEP_MODE_RETENTION = MSM_PM_SLEEP_MODE_APPS_SLEEP,
 	MSM_PM_SLEEP_MODE_POWER_COLLAPSE_SUSPEND = 5,
 	MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN = 6,
-	MSM_PM_SLEEP_MODE_NR
+	MSM_PM_SLEEP_MODE_NR = 7,
+	MSM_PM_SLEEP_MODE_NOT_SELECTED,
 };
 
 #define MSM_PM_MODE(cpu, mode_nr)  ((cpu) * MSM_PM_SLEEP_MODE_NR + (mode_nr))
@@ -64,6 +65,12 @@
 	uint32_t modified_time_us;
 };
 
+struct msm_pm_sleep_status_data {
+	void *base_addr;
+	uint32_t cpu_offset;
+	uint32_t mask;
+};
+
 struct msm_pm_platform_data {
 	u8 idle_supported;   /* Allow device to enter mode during idle */
 	u8 suspend_supported; /* Allow device to enter mode during suspend */
@@ -96,8 +103,19 @@
 					external L2 cache controller */
 };
 
+struct msm_pm_cp15_save_data {
+	bool save_cp15;
+	uint32_t active_vdd;
+	uint32_t qsb_pc_vdd;
+	uint32_t reg_saved_state_size;
+	uint32_t *reg_data;
+	uint32_t *reg_val;
+};
+
 struct msm_pm_init_data_type {
 	enum msm_pm_pc_mode_type pc_mode;
+	bool retention_calls_tz;
+	struct msm_pm_cp15_save_data cp15_data;
 	bool use_sync_timer;
 };
 
@@ -107,12 +125,12 @@
 };
 
 void msm_pm_set_platform_data(struct msm_pm_platform_data *data, int count);
-int msm_pm_idle_prepare(struct cpuidle_device *dev,
+enum msm_pm_sleep_mode msm_pm_idle_enter(struct cpuidle_device *dev,
 			struct cpuidle_driver *drv, int index);
 void msm_pm_set_irq_extns(struct msm_pm_irq_calls *irq_calls);
-int msm_pm_idle_enter(enum msm_pm_sleep_mode sleep_mode);
 void msm_pm_cpu_enter_lowpower(unsigned int cpu);
 void __init msm_pm_set_tz_retention_flag(unsigned int flag);
+void msm_pm_enable_retention(bool enable);
 
 #ifdef CONFIG_MSM_PM8X60
 void msm_pm_set_rpm_wakeup_irq(unsigned int irq);
diff --git a/arch/arm/mach-msm/pm2.c b/arch/arm/mach-msm/pm2.c
index ec9f030..a2da8b0 100644
--- a/arch/arm/mach-msm/pm2.c
+++ b/arch/arm/mach-msm/pm2.c
@@ -894,12 +894,23 @@
 
 	msm_pm_irq_extns->enter_sleep1(true, from_idle,
 						&msm_pm_smem_data->irq_mask);
-	msm_sirc_enter_sleep();
-	msm_gpio_enter_sleep(from_idle);
 
 	msm_pm_smem_data->sleep_time = sleep_delay;
 	msm_pm_smem_data->resources_used = sleep_limit;
 
+	saved_acpuclk_rate = acpuclk_power_collapse();
+	MSM_PM_DPRINTK(MSM_PM_DEBUG_CLOCK, KERN_INFO,
+		"%s(): change clock rate (old rate = %lu)\n", __func__,
+		saved_acpuclk_rate);
+
+	if (saved_acpuclk_rate == 0) {
+		ret = -EAGAIN;
+		goto acpu_set_clock_fail;
+	}
+
+	msm_sirc_enter_sleep();
+	msm_gpio_enter_sleep(from_idle);
+
 	/* Enter PWRC/PWRC_SUSPEND */
 
 	if (from_idle)
@@ -952,16 +963,6 @@
 	msm_pm_config_hw_before_power_down();
 	MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): pre power down");
 
-	saved_acpuclk_rate = acpuclk_power_collapse();
-	MSM_PM_DPRINTK(MSM_PM_DEBUG_CLOCK, KERN_INFO,
-		"%s(): change clock rate (old rate = %lu)\n", __func__,
-		saved_acpuclk_rate);
-
-	if (saved_acpuclk_rate == 0) {
-		msm_pm_config_hw_after_power_up();
-		goto power_collapse_early_exit;
-	}
-
 	msm_pm_boot_config_before_pc(smp_processor_id(),
 			virt_to_phys(msm_pm_collapse_exit));
 
@@ -1052,14 +1053,6 @@
 		KERN_INFO,
 		"%s(): msm_pm_collapse returned %d\n", __func__, collapsed);
 
-	MSM_PM_DPRINTK(MSM_PM_DEBUG_CLOCK, KERN_INFO,
-		"%s(): restore clock rate to %lu\n", __func__,
-		saved_acpuclk_rate);
-	if (acpuclk_set_rate(smp_processor_id(), saved_acpuclk_rate,
-			SETRATE_PC) < 0)
-		printk(KERN_ERR "%s(): failed to restore clock rate(%lu)\n",
-			__func__, saved_acpuclk_rate);
-
 	msm_pm_irq_extns->exit_sleep1(msm_pm_smem_data->irq_mask,
 		msm_pm_smem_data->wakeup_reason,
 		msm_pm_smem_data->pending_irqs);
@@ -1132,6 +1125,14 @@
 		goto power_collapse_restore_gpio_bail;
 	}
 
+	MSM_PM_DPRINTK(MSM_PM_DEBUG_CLOCK, KERN_INFO,
+		"%s(): restore clock rate to %lu\n", __func__,
+		saved_acpuclk_rate);
+	if (acpuclk_set_rate(smp_processor_id(), saved_acpuclk_rate,
+			SETRATE_PC) < 0)
+		pr_err("%s(): failed to restore clock rate(%lu)\n",
+			__func__, saved_acpuclk_rate);
+
 	/* DEM Master == RUN */
 
 	MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): WFPI RUN");
@@ -1212,10 +1213,18 @@
 
 	MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): RUN");
 
+	MSM_PM_DPRINTK(MSM_PM_DEBUG_CLOCK, KERN_INFO,
+		"%s(): restore clock rate to %lu\n", __func__,
+		saved_acpuclk_rate);
+	if (acpuclk_set_rate(smp_processor_id(), saved_acpuclk_rate,
+			SETRATE_PC) < 0)
+		pr_err("%s(): failed to restore clock rate(%lu)\n",
+			__func__, saved_acpuclk_rate);
+
 	if (collapsed)
 		smd_sleep_exit();
 
-	/* Call CPR resume only for "idlePC" case */
+acpu_set_clock_fail:
 	if (msm_cpr_ops && from_idle)
 		msm_cpr_ops->cpr_resume();
 
diff --git a/arch/arm/mach-msm/pmic.c b/arch/arm/mach-msm/pmic.c
index 1e92710..dc0f7bf 100644
--- a/arch/arm/mach-msm/pmic.c
+++ b/arch/arm/mach-msm/pmic.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2011 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/pmic.h b/arch/arm/mach-msm/pmic.h
index e6ef960..b73e654 100644
--- a/arch/arm/mach-msm/pmic.h
+++ b/arch/arm/mach-msm/pmic.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/pmic_debugfs.c b/arch/arm/mach-msm/pmic_debugfs.c
index c52cf9b..b91eef5 100644
--- a/arch/arm/mach-msm/pmic_debugfs.c
+++ b/arch/arm/mach-msm/pmic_debugfs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/pmu.c b/arch/arm/mach-msm/pmu.c
index f0b83f9..febeb19 100644
--- a/arch/arm/mach-msm/pmu.c
+++ b/arch/arm/mach-msm/pmu.c
@@ -11,7 +11,6 @@
  */
 
 #include <linux/platform_device.h>
-#include <linux/irq.h>
 #include <asm/pmu.h>
 #include <mach/irqs.h>
 #include <mach/socinfo.h>
@@ -30,20 +29,9 @@
 #if defined(CONFIG_ARCH_MSM_KRAITMP) || defined(CONFIG_ARCH_MSM_SCORPIONMP) \
 	|| defined(CONFIG_ARCH_MSM8625) || \
 	(defined(CONFIG_ARCH_MSM_CORTEX_A5) && !defined(CONFIG_MSM_VIC))
+
 static DEFINE_PER_CPU(u32, pmu_irq_cookie);
 
-static void enable_irq_callback(void *info)
-{
-	int irq = *(unsigned int *)info;
-	enable_percpu_irq(irq, IRQ_TYPE_EDGE_RISING);
-}
-
-static void disable_irq_callback(void *info)
-{
-	int irq = *(unsigned int *)info;
-	disable_percpu_irq(irq);
-}
-
 static int
 multicore_request_irq(int irq, irq_handler_t *handle_irq)
 {
@@ -137,6 +125,21 @@
 	.resource	= msm8625_cpu_pmu_resource,
 	.num_resources	= ARRAY_SIZE(msm8625_cpu_pmu_resource),
 };
+
+static struct resource msm8625_l2_pmu_resource[] = {
+	{
+		.start = MSM8625_INT_SC_SICL2PERFMONIRPTREQ,
+		.end = MSM8625_INT_SC_SICL2PERFMONIRPTREQ,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device msm8625_l2_pmu_device = {
+	.name		= "l2-arm-pmu",
+	.id		= ARM_PMU_DEVICE_L2CC,
+	.resource	= msm8625_l2_pmu_resource,
+	.num_resources	= ARRAY_SIZE(msm8625_l2_pmu_resource),
+};
 #endif
 
 static struct platform_device *pmu_devices[] = {
@@ -166,8 +169,9 @@
 	 * and point to the appropriate 'struct resource'.
 	 */
 #ifdef CONFIG_ARCH_MSM8625
-	if (cpu_is_msm8625()) {
+	if (cpu_is_msm8625() || cpu_is_msm8625q()) {
 		pmu_devices[0] = &msm8625_cpu_pmu_device;
+		pmu_devices[1] = &msm8625_l2_pmu_device;
 		msm8625_cpu_pmu_device.dev.platform_data = &multicore_data;
 	}
 #endif
diff --git a/arch/arm/mach-msm/proc_comm.c b/arch/arm/mach-msm/proc_comm.c
index 421e7de..c7705e7 100644
--- a/arch/arm/mach-msm/proc_comm.c
+++ b/arch/arm/mach-msm/proc_comm.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/proc_comm.c
  *
  * Copyright (C) 2007-2008 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/proc_comm_test.c b/arch/arm/mach-msm/proc_comm_test.c
index e4eca11..7593ff2 100644
--- a/arch/arm/mach-msm/proc_comm_test.c
+++ b/arch/arm/mach-msm/proc_comm_test.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/proccomm-regulator.c b/arch/arm/mach-msm/proccomm-regulator.c
index 21a4f84..74d15dd 100644
--- a/arch/arm/mach-msm/proccomm-regulator.c
+++ b/arch/arm/mach-msm/proccomm-regulator.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/proccomm-regulator.h b/arch/arm/mach-msm/proccomm-regulator.h
index 46d3b13..8a08e3e 100644
--- a/arch/arm/mach-msm/proccomm-regulator.h
+++ b/arch/arm/mach-msm/proccomm-regulator.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/qdsp5/adsp.c b/arch/arm/mach-msm/qdsp5/adsp.c
index 81af66b..353de3d 100644
--- a/arch/arm/mach-msm/qdsp5/adsp.c
+++ b/arch/arm/mach-msm/qdsp5/adsp.c
@@ -3,7 +3,7 @@
  * Register/Interrupt access for userspace aDSP library.
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  * Author: Iliyan Malchev <ibm@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/qdsp5/adsp.h b/arch/arm/mach-msm/qdsp5/adsp.h
index 4e9d311..0922d88 100644
--- a/arch/arm/mach-msm/qdsp5/adsp.h
+++ b/arch/arm/mach-msm/qdsp5/adsp.h
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/qdsp5/adsp.h
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2010, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2010, 2012 The Linux Foundation. All rights reserved.
  * Author: Iliyan Malchev <ibm@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/qdsp5/adsp_6210.c b/arch/arm/mach-msm/qdsp5/adsp_6210.c
index 322ba68..bf69ce2 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_6210.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_6210.c
@@ -1,6 +1,6 @@
 /* arch/arm/mach-msm/qdsp5/adsp_6210.h
  *
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/adsp_6220.c b/arch/arm/mach-msm/qdsp5/adsp_6220.c
index f947cd7..0073790 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_6220.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_6220.c
@@ -1,6 +1,6 @@
 /* arch/arm/mach-msm/qdsp5/adsp_6220.h
  *
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/adsp_6225.c b/arch/arm/mach-msm/qdsp5/adsp_6225.c
index 6f8d3f4..6a402b7 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_6225.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_6225.c
@@ -1,6 +1,6 @@
 /* arch/arm/mach-msm/qdsp5/adsp_6225.h
  *
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/adsp_debug.c b/arch/arm/mach-msm/qdsp5/adsp_debug.c
index 03deab9..ccddd43 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_debug.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_debug.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp5/adsp_driver.c b/arch/arm/mach-msm/qdsp5/adsp_driver.c
index 6419bd0..d83a140 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_driver.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_driver.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/qdsp5/adsp_driver.c
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2009, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, 2012 The Linux Foundation. All rights reserved.
  * Author: Iliyan Malchev <ibm@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/qdsp5/adsp_info.c b/arch/arm/mach-msm/qdsp5/adsp_info.c
index dea52bb..69a2d18 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_info.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_info.c
@@ -1,6 +1,6 @@
 /* arch/arm/mach-msm/adsp_info.c
  *
- * Copyright (c) 2008-2009, 2011-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2011-2012 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/adsp_jpeg_patch_event.c b/arch/arm/mach-msm/qdsp5/adsp_jpeg_patch_event.c
index 8fb2e06..768ac31 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_jpeg_patch_event.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_jpeg_patch_event.c
@@ -3,7 +3,7 @@
  * Verification code for aDSP JPEG events.
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/adsp_jpeg_verify_cmd.c b/arch/arm/mach-msm/qdsp5/adsp_jpeg_verify_cmd.c
index 87d5dc3..a5dd4ad 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_jpeg_verify_cmd.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_jpeg_verify_cmd.c
@@ -3,7 +3,7 @@
  * Verification code for aDSP JPEG packets from userspace.
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/adsp_lpm_verify_cmd.c b/arch/arm/mach-msm/qdsp5/adsp_lpm_verify_cmd.c
index 06b70de..6424975 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_lpm_verify_cmd.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_lpm_verify_cmd.c
@@ -3,7 +3,7 @@
  * Verificion code for aDSP LPM packets from userspace.
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/adsp_rm.c b/arch/arm/mach-msm/qdsp5/adsp_rm.c
index f67946c..95489f8 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_rm.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_rm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp5/adsp_vfe_patch_event.c b/arch/arm/mach-msm/qdsp5/adsp_vfe_patch_event.c
index 68ae380..c89a37d 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_vfe_patch_event.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_vfe_patch_event.c
@@ -3,7 +3,7 @@
  * Verification code for aDSP VFE packets from userspace.
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/adsp_vfe_verify_cmd.c b/arch/arm/mach-msm/qdsp5/adsp_vfe_verify_cmd.c
index dcd3d96..dba012e 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_vfe_verify_cmd.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_vfe_verify_cmd.c
@@ -3,7 +3,7 @@
  * Verification code for aDSP VFE packets from userspace.
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c b/arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c
index af259b5..4d03dca 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c
@@ -3,7 +3,7 @@
  * Verificion code for aDSP VDEC packets from userspace.
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2010, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2010, 2012 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/adsp_videoenc_verify_cmd.c b/arch/arm/mach-msm/qdsp5/adsp_videoenc_verify_cmd.c
index 290a14c..1b16628 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_videoenc_verify_cmd.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_videoenc_verify_cmd.c
@@ -3,7 +3,7 @@
  * Verificion code for aDSP VENC packets from userspace.
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2012 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/audio_aac.c b/arch/arm/mach-msm/qdsp5/audio_aac.c
index c36cac7..b82df8d 100644
--- a/arch/arm/mach-msm/qdsp5/audio_aac.c
+++ b/arch/arm/mach-msm/qdsp5/audio_aac.c
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2008-2009, 2011-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2011-2012 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/audio_aac_in.c b/arch/arm/mach-msm/qdsp5/audio_aac_in.c
index c86c1dd..8cfa4e3 100644
--- a/arch/arm/mach-msm/qdsp5/audio_aac_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_aac_in.c
@@ -2,7 +2,7 @@
  *
  * aac audio input device
  *
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * This code is based in part on arch/arm/mach-msm/qdsp5v2/audio_aac_in.c,
  * Copyright (C) 2008 Google, Inc.
diff --git a/arch/arm/mach-msm/qdsp5/audio_ac3.c b/arch/arm/mach-msm/qdsp5/audio_ac3.c
index b5337bd..0363348 100644
--- a/arch/arm/mach-msm/qdsp5/audio_ac3.c
+++ b/arch/arm/mach-msm/qdsp5/audio_ac3.c
@@ -1,6 +1,6 @@
 /* arch/arm/mach-msm/audio_ac3.c
  *
- * Copyright (c) 2008-2009, 2011-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2011-2012 The Linux Foundation. All rights reserved.
  *
  * This code also borrows from audio_aac.c, which is
  * Copyright (C) 2008 Google, Inc.
diff --git a/arch/arm/mach-msm/qdsp5/audio_acdb.c b/arch/arm/mach-msm/qdsp5/audio_acdb.c
index d7a4607..7819395 100644
--- a/arch/arm/mach-msm/qdsp5/audio_acdb.c
+++ b/arch/arm/mach-msm/qdsp5/audio_acdb.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -97,11 +97,13 @@
 	u32 device_cb_compl;
 	u32 audpp_cb_compl;
 	u32 preproc_cb_compl;
+	u32 audpp_cb_reenable_compl;
 	u8 preproc_stream_id;
 	u8 audrec_applied;
 	u32 multiple_sessions;
 	u32 cur_tx_session;
 	struct acdb_result acdb_result;
+	uint32_t audpp_disabled_features;
 
 	spinlock_t dsp_lock;
 	int dec_id;
@@ -1301,6 +1303,15 @@
 }
 EXPORT_SYMBOL(acdb_get_calibration_data);
 
+int is_acdb_enabled()
+{
+	if (acdb_data.handle != NULL)
+		return 1;
+	else
+		return 0;
+}
+EXPORT_SYMBOL(is_acdb_enabled);
+
 static u8 check_device_info_already_present(
 		struct dev_evt_msg device_info,
 			struct acdb_cache_node *acdb_cache_free_node)
@@ -1522,7 +1533,7 @@
 			result = -EINVAL;
 			goto done;
 		} else
-			MM_DBG("AUDPP is calibrated with IIR parameters");
+			MM_DBG("AUDPP is calibrated with IIR parameters\n");
 	}
 	result = acdb_fill_audpp_mbadrc();
 	if (!IS_ERR_VALUE(result)) {
@@ -1541,6 +1552,40 @@
 	return result;
 }
 
+static s32 acdb_re_enable_audpp(void)
+{
+	s32	result = 0;
+
+	if ((acdb_data.audpp_disabled_features &
+			(1 << AUDPP_CMD_IIR_TUNING_FILTER))
+			== (1 << AUDPP_CMD_IIR_TUNING_FILTER)) {
+		result = audpp_dsp_set_rx_iir(COMMON_OBJ_ID,
+				acdb_data.pp_iir->active_flag,
+				acdb_data.pp_iir);
+		if (result) {
+			MM_ERR("ACDB=> Failed to send IIR data to postproc\n");
+			result = -EINVAL;
+		} else {
+			MM_DBG("Re-enable IIR parameters");
+		}
+	}
+	if ((acdb_data.audpp_disabled_features & (1 << AUDPP_CMD_MBADRC))
+			== (1 << AUDPP_CMD_MBADRC)) {
+		result = audpp_dsp_set_mbadrc(COMMON_OBJ_ID,
+				acdb_data.pp_mbadrc->enable,
+				acdb_data.pp_mbadrc);
+		if (result) {
+			MM_ERR("ACDB=> Failed to send MBADRC data to"\
+					" postproc\n");
+			result = -EINVAL;
+		} else {
+			MM_DBG("Re-enable MBADRC parameters");
+		}
+	}
+	acdb_data.audpp_disabled_features = 0;
+	return result;
+}
+
 static struct acdb_agc_block *get_audpreproc_agc_block(void)
 {
 	struct header *prs_hdr;
@@ -2270,13 +2315,9 @@
 		if (ret == 1) {
 			MM_DBG("got device ready call back for another "\
 					"audplay task sessions on same COPP\n");
-			/*stream_id is used to keep track of number of active*/
-			/*sessions active on this device*/
-			acdb_cache_free_node->stream_id++;
 			mutex_unlock(&acdb_data.acdb_mutex);
 			goto done;
 		}
-		acdb_cache_free_node->stream_id++;
 	}
 	update_acdb_data_struct(acdb_cache_free_node);
 	acdb_data.device_cb_compl = 1;
@@ -2306,6 +2347,22 @@
 static void audpp_cb(void *private, u32 id, u16 *msg)
 {
 	MM_DBG("\n");
+
+	if (id == AUDPP_MSG_PP_DISABLE_FEEDBACK) {
+		acdb_data.audpp_disabled_features |=
+			((uint32_t)(msg[AUDPP_DISABLE_FEATS_MSW] << 16) |
+			 msg[AUDPP_DISABLE_FEATS_LSW]);
+		MM_INFO("AUDPP disable feedback: %x",
+				acdb_data.audpp_disabled_features);
+		goto done;
+	} else if (id == AUDPP_MSG_PP_FEATS_RE_ENABLE) {
+		MM_INFO("AUDPP re-enable messaage: %x",
+				acdb_data.audpp_disabled_features);
+		acdb_data.audpp_cb_reenable_compl = 1;
+		wake_up(&acdb_data.wait);
+		return;
+	}
+
 	if (id != AUDPP_MSG_CFG_MSG)
 		goto done;
 
@@ -2317,6 +2374,9 @@
 		}
 		goto done;
 	}
+	/*stream_id is used to keep track of number of active*/
+	/*sessions active on this device*/
+	acdb_cache_rx.stream_id++;
 
 	acdb_data.acdb_state |= AUDPP_READY;
 	acdb_data.audpp_cb_compl = 1;
@@ -2496,6 +2556,7 @@
 		wait_event_interruptible(acdb_data.wait,
 					(acdb_data.device_cb_compl
 					| acdb_data.audpp_cb_compl
+					| acdb_data.audpp_cb_reenable_compl
 					| acdb_data.preproc_cb_compl));
 		mutex_lock(&acdb_data.acdb_mutex);
 		if (acdb_data.device_cb_compl) {
@@ -2526,6 +2587,11 @@
 			if (acdb_data.device_info->dev_type.tx_device)
 				handle_tx_device_ready_callback();
 			else {
+				if (acdb_data.audpp_cb_reenable_compl) {
+					MM_INFO("Reset disabled feature flag");
+					acdb_data.audpp_disabled_features = 0;
+					acdb_data.audpp_cb_reenable_compl = 0;
+				}
 				acdb_cache_rx.node_status =\
 						ACDB_VALUES_FILLED;
 				if (acdb_data.acdb_state &
@@ -2538,6 +2604,7 @@
 		}
 
 		if (!(acdb_data.audpp_cb_compl ||
+				acdb_data.audpp_cb_reenable_compl ||
 				acdb_data.preproc_cb_compl)) {
 			MM_DBG("need to wait for either AUDPP / AUDPREPROC "\
 					"Event\n");
@@ -2546,10 +2613,21 @@
 		} else {
 			MM_DBG("got audpp / preproc call back\n");
 			if (acdb_data.audpp_cb_compl) {
+				if (acdb_data.audpp_cb_reenable_compl) {
+					MM_INFO("Reset disabled feature flag");
+					acdb_data.audpp_disabled_features = 0;
+					acdb_data.audpp_cb_reenable_compl = 0;
+				}
 				send_acdb_values_for_active_devices();
 				acdb_data.audpp_cb_compl = 0;
 				mutex_unlock(&acdb_data.acdb_mutex);
 				continue;
+			} else if (acdb_data.audpp_cb_reenable_compl) {
+				acdb_re_enable_audpp();
+				acdb_data.audpp_disabled_features = 0;
+				acdb_data.audpp_cb_reenable_compl = 0;
+				mutex_unlock(&acdb_data.acdb_mutex);
+				continue;
 			} else {
 				result = handle_audpreproc_cb();
 				if (result < 0) {
diff --git a/arch/arm/mach-msm/qdsp5/audio_amrnb.c b/arch/arm/mach-msm/qdsp5/audio_amrnb.c
index 4aa7403..1f04e76 100644
--- a/arch/arm/mach-msm/qdsp5/audio_amrnb.c
+++ b/arch/arm/mach-msm/qdsp5/audio_amrnb.c
@@ -2,7 +2,7 @@
  *
  * amrnb audio decoder device
  *
- * Copyright (c) 2008-2009, 2011-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2011-2012 The Linux Foundation. All rights reserved.
  *
  * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5/audio_mp3.c
  *
diff --git a/arch/arm/mach-msm/qdsp5/audio_amrnb_in.c b/arch/arm/mach-msm/qdsp5/audio_amrnb_in.c
index 0742686..743eee2 100644
--- a/arch/arm/mach-msm/qdsp5/audio_amrnb_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_amrnb_in.c
@@ -2,7 +2,7 @@
  *
  * amrnb encoder device
  *
- * Copyright (c) 2009, 2011-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, 2011-2012 The Linux Foundation. All rights reserved.
  *
  * This code is based in part on arch/arm/mach-msm/qdsp5/audio_in.c, which is
  * Copyright (C) 2008 Google, Inc.
diff --git a/arch/arm/mach-msm/qdsp5/audio_amrwb.c b/arch/arm/mach-msm/qdsp5/audio_amrwb.c
index 57df4ad..db3a1ab 100644
--- a/arch/arm/mach-msm/qdsp5/audio_amrwb.c
+++ b/arch/arm/mach-msm/qdsp5/audio_amrwb.c
@@ -6,7 +6,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009, 2011-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, 2011-2012 The Linux Foundation. All rights reserved.
  *
  * All source code in this file is licensed under the following license except
  * where indicated.
diff --git a/arch/arm/mach-msm/qdsp5/audio_evrc.c b/arch/arm/mach-msm/qdsp5/audio_evrc.c
index 0799ee1..15612a3 100644
--- a/arch/arm/mach-msm/qdsp5/audio_evrc.c
+++ b/arch/arm/mach-msm/qdsp5/audio_evrc.c
@@ -1,6 +1,6 @@
 /* arch/arm/mach-msm/audio_evrc.c
  *
- * Copyright (c) 2008-2009, 2011-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2011-2012 The Linux Foundation. All rights reserved.
  *
  * This code also borrows from audio_aac.c, which is
  * Copyright (C) 2008 Google, Inc.
diff --git a/arch/arm/mach-msm/qdsp5/audio_evrc_in.c b/arch/arm/mach-msm/qdsp5/audio_evrc_in.c
index 89ad974..7a8c3e4 100644
--- a/arch/arm/mach-msm/qdsp5/audio_evrc_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_evrc_in.c
@@ -2,7 +2,7 @@
  *
  * evrc audio input device
  *
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * This code is based in part on arch/arm/mach-msm/qdsp5v2/audio_evrc_in.c,
  * Copyright (C) 2008 Google, Inc.
diff --git a/arch/arm/mach-msm/qdsp5/audio_fm.c b/arch/arm/mach-msm/qdsp5/audio_fm.c
index 2ab7cad..957a407 100644
--- a/arch/arm/mach-msm/qdsp5/audio_fm.c
+++ b/arch/arm/mach-msm/qdsp5/audio_fm.c
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/audio_in.c b/arch/arm/mach-msm/qdsp5/audio_in.c
index 6fc5d6b..6fc2ac0 100644
--- a/arch/arm/mach-msm/qdsp5/audio_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_in.c
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/audio_lpa.c b/arch/arm/mach-msm/qdsp5/audio_lpa.c
index e896e85..7f0d68a 100644
--- a/arch/arm/mach-msm/qdsp5/audio_lpa.c
+++ b/arch/arm/mach-msm/qdsp5/audio_lpa.c
@@ -1,7 +1,7 @@
 
 /* audio_lpa.c - low power audio driver
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * Based on the PCM decoder driver in arch/arm/mach-msm/qdsp5/audio_pcm.c
  *
diff --git a/arch/arm/mach-msm/qdsp5/audio_mp3.c b/arch/arm/mach-msm/qdsp5/audio_mp3.c
index a606bd5..c310e1e 100644
--- a/arch/arm/mach-msm/qdsp5/audio_mp3.c
+++ b/arch/arm/mach-msm/qdsp5/audio_mp3.c
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/audio_mvs.c b/arch/arm/mach-msm/qdsp5/audio_mvs.c
index d45043d..d1aba82 100644
--- a/arch/arm/mach-msm/qdsp5/audio_mvs.c
+++ b/arch/arm/mach-msm/qdsp5/audio_mvs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -335,6 +335,8 @@
 
 	struct wake_lock suspend_lock;
 	struct pm_qos_request pm_qos_req;
+
+	struct completion complete;
 };
 
 static struct audio_mvs_info_type audio_mvs_info;
@@ -1235,7 +1237,7 @@
 		kfree(rpc_hdr);
 		rpc_hdr = NULL;
 	}
-
+	complete_and_exit(&audio->complete, 0);
 	MM_DBG("MVS thread stopped\n");
 
 	return 0;
@@ -1360,6 +1362,7 @@
 		audio_mvs_stop(audio);
 	audio->state = AUDIO_MVS_CLOSED;
 	msm_rpc_read_wakeup(audio->rpc_endpt);
+	wait_for_completion(&audio->complete);
 	msm_rpc_close(audio->rpc_endpt);
 	audio->task = NULL;
 	audio_mvs_free_buf(audio);
@@ -1613,6 +1616,19 @@
 
 	MM_DBG("\n");
 
+	mutex_lock(&audio_mvs_info.lock);
+
+	if (audio_mvs_info.state != AUDIO_MVS_CLOSED) {
+		MM_ERR("MVS driver exists, state %d\n",
+				audio_mvs_info.state);
+
+		rc = -EBUSY;
+		mutex_unlock(&audio_mvs_info.lock);
+		goto done;
+	}
+
+	mutex_unlock(&audio_mvs_info.lock);
+
 	audio_mvs_info.rpc_endpt = msm_rpc_connect_compatible(MVS_PROG,
 					MVS_VERS_COMP_VER2,
 					MSM_RPC_UNINTERRUPTIBLE);
@@ -1652,26 +1668,18 @@
 
 	mutex_lock(&audio_mvs_info.lock);
 
-	if (audio_mvs_info.state == AUDIO_MVS_CLOSED) {
-
-		if (audio_mvs_info.task != NULL ||
+	if (audio_mvs_info.task != NULL ||
 			audio_mvs_info.rpc_endpt != NULL) {
-			rc = audio_mvs_alloc_buf(&audio_mvs_info);
+		rc = audio_mvs_alloc_buf(&audio_mvs_info);
 
-			if (rc == 0) {
-				audio_mvs_info.state = AUDIO_MVS_OPENED;
-				file->private_data = &audio_mvs_info;
-			}
-		}  else {
-			MM_ERR("MVS thread and RPC end point do not exist\n");
-
-			rc = -ENODEV;
+		if (rc == 0) {
+			audio_mvs_info.state = AUDIO_MVS_OPENED;
+			file->private_data = &audio_mvs_info;
 		}
-	} else {
-		MM_ERR("MVS driver exists, state %d\n",
-		       audio_mvs_info.state);
+	}  else {
+		MM_ERR("MVS thread and RPC end point do not exist\n");
 
-		rc = -EBUSY;
+		rc = -ENODEV;
 	}
 
 	mutex_unlock(&audio_mvs_info.lock);
@@ -1711,6 +1719,8 @@
 	INIT_LIST_HEAD(&audio_mvs_info.out_queue);
 	INIT_LIST_HEAD(&audio_mvs_info.free_out_queue);
 
+	init_completion(&audio_mvs_info.complete);
+
 	wake_lock_init(&audio_mvs_info.suspend_lock,
 		       WAKE_LOCK_SUSPEND,
 		       "audio_mvs_suspend");
@@ -1724,6 +1734,7 @@
 {
 	MM_DBG("\n");
 
+	wake_lock_destroy(&audio_mvs_info.suspend_lock);
 	misc_deregister(&audio_mvs_misc);
 }
 
diff --git a/arch/arm/mach-msm/qdsp5/audio_out.c b/arch/arm/mach-msm/qdsp5/audio_out.c
index 6f3bf91..07f9f4c 100644
--- a/arch/arm/mach-msm/qdsp5/audio_out.c
+++ b/arch/arm/mach-msm/qdsp5/audio_out.c
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -39,6 +39,7 @@
 
 #include "audmgr.h"
 
+#include <mach/qdsp5/audio_acdb_def.h>
 #include <mach/qdsp5/qdsp5audppcmdi.h>
 #include <mach/qdsp5/qdsp5audppmsg.h>
 #include <mach/qdsp5/qdsp5audpp.h>
@@ -188,6 +189,8 @@
 	int srs_needs_commit;
 	int srs_feature_mask;
 	audpp_cmd_cfg_object_params_qconcert qconcert_plus;
+	int srs_current_feature_mask;
+	uint32_t audpp_disabled_features;
 
 	int status;
 	int opened;
@@ -292,25 +295,94 @@
 {
 	struct audio_copp *audio_copp = priv;
 
-	if (AUDPP_MSG_CFG_MSG == id && msg[0] == AUDPP_MSG_ENA_DIS)
+	if (audio_copp == NULL) {
+		MM_ERR("NULL audio copp pointer\n");
 		return;
+	}
+
+	if (AUDPP_MSG_CFG_MSG == id && msg[0] == AUDPP_MSG_ENA_DIS) {
+		audio_copp->audpp_disabled_features = 0;
+		return;
+	}
+	if (AUDPP_MSG_CFG_MSG == id && msg[0] == AUDPP_MSG_ENA_ENA)
+		audio_copp->audpp_disabled_features = 0;
 
 	if (!audio_copp->status)
 		return;
 
-	audpp_dsp_set_mbadrc(COMMON_OBJ_ID, audio_copp->mbadrc_enable,
+	if (id == AUDPP_MSG_PP_DISABLE_FEEDBACK) {
+		audio_copp->audpp_disabled_features |=
+			((uint32_t)(msg[AUDPP_DISABLE_FEATS_MSW] << 16) |
+			 msg[AUDPP_DISABLE_FEATS_LSW]);
+		MM_DBG("AUDPP disable feedback: %x",
+				audio_copp->audpp_disabled_features);
+		return;
+	} else if (id == AUDPP_MSG_PP_FEATS_RE_ENABLE) {
+		MM_DBG("AUDPP re-enable messaage: %x, acdb_enabled %d",
+			audio_copp->audpp_disabled_features, is_acdb_enabled());
+		if (!is_acdb_enabled()) {
+			if ((audio_copp->audpp_disabled_features &
+				(1 << AUDPP_CMD_MBADRC)) ==
+				(1 << AUDPP_CMD_MBADRC)) {
+				audpp_dsp_set_mbadrc(COMMON_OBJ_ID,
+						audio_copp->mbadrc_enable,
+						&audio_copp->mbadrc);
+			}
+			if ((audio_copp->audpp_disabled_features &
+				(1 << AUDPP_CMD_EQUALIZER)) ==
+				(1 << AUDPP_CMD_EQUALIZER)) {
+				audpp_dsp_set_eq(COMMON_OBJ_ID,
+						audio_copp->eq_enable,
+						&audio_copp->eq);
+			}
+			if ((audio_copp->audpp_disabled_features &
+				(1 << AUDPP_CMD_IIR_TUNING_FILTER)) ==
+				(1 << AUDPP_CMD_IIR_TUNING_FILTER)) {
+				audpp_dsp_set_rx_iir(COMMON_OBJ_ID,
+						audio_copp->rx_iir_enable,
+						&audio_copp->iir);
+			}
+			if ((audio_copp->audpp_disabled_features &
+				(1 << AUDPP_CMD_QCONCERT)) ==
+					(1 << AUDPP_CMD_QCONCERT)) {
+				audpp_dsp_set_qconcert_plus(COMMON_OBJ_ID,
+					audio_copp->qconcert_plus_enable,
+					&audio_copp->qconcert_plus);
+			}
+		}
+		if ((audio_copp->audpp_disabled_features & (1 << AUDPP_CMD_SRS))
+			== (1 << AUDPP_CMD_SRS)) {
+			if (audio_copp->srs_current_feature_mask & SRS_MASK_W)
+				audpp_dsp_set_rx_srs_trumedia_w(&audio_copp->w);
+			if (audio_copp->srs_current_feature_mask & SRS_MASK_C)
+				audpp_dsp_set_rx_srs_trumedia_c(&audio_copp->c);
+			if (audio_copp->srs_current_feature_mask & SRS_MASK_HP)
+				audpp_dsp_set_rx_srs_trumedia_h(&audio_copp->h);
+			if (audio_copp->srs_current_feature_mask & SRS_MASK_P)
+				audpp_dsp_set_rx_srs_trumedia_p(&audio_copp->p);
+			if (audio_copp->srs_current_feature_mask & SRS_MASK_HL)
+				audpp_dsp_set_rx_srs_trumedia_l(&audio_copp->l);
+			if (audio_copp->srs_current_feature_mask & SRS_MASK_G)
+				audpp_dsp_set_rx_srs_trumedia_g(&audio_copp->g);
+		}
+		audio_copp->audpp_disabled_features = 0;
+		return;
+	}
+
+	if (!is_acdb_enabled()) {
+		audpp_dsp_set_mbadrc(COMMON_OBJ_ID, audio_copp->mbadrc_enable,
 						&audio_copp->mbadrc);
 
-	audpp_dsp_set_eq(COMMON_OBJ_ID, audio_copp->eq_enable,
+		audpp_dsp_set_eq(COMMON_OBJ_ID, audio_copp->eq_enable,
 						&audio_copp->eq);
-
-	audpp_dsp_set_rx_iir(COMMON_OBJ_ID, audio_copp->rx_iir_enable,
+		audpp_dsp_set_rx_iir(COMMON_OBJ_ID, audio_copp->rx_iir_enable,
 							&audio_copp->iir);
-	audpp_dsp_set_vol_pan(COMMON_OBJ_ID, &audio_copp->vol_pan);
+		audpp_dsp_set_vol_pan(COMMON_OBJ_ID, &audio_copp->vol_pan);
 
-	audpp_dsp_set_qconcert_plus(COMMON_OBJ_ID,
+		audpp_dsp_set_qconcert_plus(COMMON_OBJ_ID,
 				audio_copp->qconcert_plus_enable,
 				&audio_copp->qconcert_plus);
+	}
 	audio_enable_srs_trumedia(audio_copp, true);
 }
 EXPORT_SYMBOL(audio_commit_pending_pp_params);
@@ -506,6 +578,8 @@
 		if (audio_copp->srs_feature_mask & SRS_MASK_G)
 			audpp_dsp_set_rx_srs_trumedia_g(&audio_copp->g);
 
+		audio_copp->srs_current_feature_mask =
+			audio_copp->srs_feature_mask;
 		audio_copp->srs_needs_commit = 0;
 		audio_copp->srs_feature_mask = 0;
 	}
diff --git a/arch/arm/mach-msm/qdsp5/audio_pcm.c b/arch/arm/mach-msm/qdsp5/audio_pcm.c
index d19f80b..4ffc2be 100644
--- a/arch/arm/mach-msm/qdsp5/audio_pcm.c
+++ b/arch/arm/mach-msm/qdsp5/audio_pcm.c
@@ -1,7 +1,7 @@
 
 /* audio_pcm.c - pcm audio decoder driver
  *
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * Based on the mp3 decoder driver in arch/arm/mach-msm/qdsp5/audio_mp3.c
  *
diff --git a/arch/arm/mach-msm/qdsp5/audio_pcm_in.c b/arch/arm/mach-msm/qdsp5/audio_pcm_in.c
index 7b2090d..c5787fd 100644
--- a/arch/arm/mach-msm/qdsp5/audio_pcm_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_pcm_in.c
@@ -2,7 +2,7 @@
  *
  * pcm audio input device
  *
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This code is based in part on arch/arm/mach-msm/qdsp5v2/audio_pcm_in.c,
  * Copyright (C) 2008 Google, Inc.
@@ -42,6 +42,7 @@
 
 #include "audmgr.h"
 
+#include <mach/qdsp5/audio_acdb_def.h>
 #include <mach/qdsp5/qdsp5audpreproc.h>
 #include <mach/qdsp5/qdsp5audpreproccmdi.h>
 #include <mach/qdsp5/qdsp5audpreprocmsg.h>
@@ -346,6 +347,8 @@
 	case AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG: {
 		MM_INFO("PARAM CFG DONE\n");
 		audio->running = 1;
+		if (is_acdb_enabled())
+			break;
 		audio_dsp_set_tx_agc(audio);
 		audio_dsp_set_ns(audio);
 		audio_dsp_set_iir(audio);
@@ -914,6 +917,12 @@
 	mutex_lock(&audio->lock);
 	switch (cmd) {
 	case AUDIO_ENABLE_AUDPRE:
+
+		if (is_acdb_enabled()) {
+			MM_INFO("Audpp is supported via acdb\n");
+			rc = -EFAULT;
+			break;
+		}
 		if (copy_from_user(&enable_mask, (void *) arg,
 						sizeof(enable_mask))) {
 			rc = -EFAULT;
diff --git a/arch/arm/mach-msm/qdsp5/audio_qcelp.c b/arch/arm/mach-msm/qdsp5/audio_qcelp.c
index 3fc489c..50bde91 100644
--- a/arch/arm/mach-msm/qdsp5/audio_qcelp.c
+++ b/arch/arm/mach-msm/qdsp5/audio_qcelp.c
@@ -2,7 +2,7 @@
  *
  * qcelp 13k audio decoder device
  *
- * Copyright (c) 2008-2009, 2011-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2011-2012 The Linux Foundation. All rights reserved.
  *
  * This code is based in part on audio_mp3.c, which is
  * Copyright (C) 2008 Google, Inc.
diff --git a/arch/arm/mach-msm/qdsp5/audio_qcelp_in.c b/arch/arm/mach-msm/qdsp5/audio_qcelp_in.c
index 6ca3382..83a2633 100644
--- a/arch/arm/mach-msm/qdsp5/audio_qcelp_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_qcelp_in.c
@@ -2,7 +2,7 @@
  *
  * qcelp audio input device
  *
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * This code is based in part on arch/arm/mach-msm/qdsp5v2/audio_qcelp_in.c,
  * Copyright (C) 2008 Google, Inc.
diff --git a/arch/arm/mach-msm/qdsp5/audio_voice_lb.c b/arch/arm/mach-msm/qdsp5/audio_voice_lb.c
index 08fa487..a73defd 100644
--- a/arch/arm/mach-msm/qdsp5/audio_voice_lb.c
+++ b/arch/arm/mach-msm/qdsp5/audio_voice_lb.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp5/audio_voicememo.c b/arch/arm/mach-msm/qdsp5/audio_voicememo.c
index 34e5b81..ae63f0d 100644
--- a/arch/arm/mach-msm/qdsp5/audio_voicememo.c
+++ b/arch/arm/mach-msm/qdsp5/audio_voicememo.c
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This code is based in part on arch/arm/mach-msm/qdsp5/audio_mp3.c
  *
diff --git a/arch/arm/mach-msm/qdsp5/audio_wma.c b/arch/arm/mach-msm/qdsp5/audio_wma.c
index f7d54cc..839739f 100644
--- a/arch/arm/mach-msm/qdsp5/audio_wma.c
+++ b/arch/arm/mach-msm/qdsp5/audio_wma.c
@@ -1,6 +1,6 @@
 /* audio_wma.c - wma audio decoder driver
  *
- * Copyright (c) 2009, 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, 2011-2012, The Linux Foundation. All rights reserved.
  *
  * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5/audio_mp3.c
  *
diff --git a/arch/arm/mach-msm/qdsp5/audio_wmapro.c b/arch/arm/mach-msm/qdsp5/audio_wmapro.c
index 8dba4a6..6a1d1d6 100644
--- a/arch/arm/mach-msm/qdsp5/audio_wmapro.c
+++ b/arch/arm/mach-msm/qdsp5/audio_wmapro.c
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * All source code in this file is licensed under the following license except
  * where indicated.
diff --git a/arch/arm/mach-msm/qdsp5/audmgr.c b/arch/arm/mach-msm/qdsp5/audmgr.c
index 666323b..cc40585 100644
--- a/arch/arm/mach-msm/qdsp5/audmgr.c
+++ b/arch/arm/mach-msm/qdsp5/audmgr.c
@@ -3,7 +3,7 @@
  * interface to "audmgr" service on the baseband cpu
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2009, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, 2012, 2013 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -46,6 +46,8 @@
 	struct msm_rpc_endpoint *ept;
 	struct task_struct *task;
 	uint32_t rpc_version;
+	uint32_t rx_device;
+	uint32_t tx_device;
 	int cad;
 	struct device_info_callback *device_cb[MAX_DEVICE_INFO_CALLBACK];
 
@@ -156,6 +158,24 @@
 			return;
 		if (am->state != STATE_ENABLED)
 			am->state = STATE_ENABLED;
+		if (!amg->cad) {
+			wake_up(&am->wait);
+			break;
+		}
+
+		if (am->evt.session_info == SESSION_PLAYBACK &&
+			am->evt.dev_type.rx_device != amg->rx_device) {
+			am->evt.dev_type.rx_device = amg->rx_device;
+			am->evt.dev_type.tx_device = 0;
+			am->evt.acdb_id = am->evt.dev_type.rx_device;
+		}
+		if (am->evt.session_info == SESSION_RECORDING &&
+			am->evt.dev_type.tx_device != amg->tx_device) {
+			am->evt.dev_type.rx_device = 0;
+			am->evt.dev_type.tx_device = amg->tx_device;
+			am->evt.acdb_id = am->evt.dev_type.tx_device;
+		}
+
 		while ((amg->device_cb[i] != NULL) &&
 				(i < MAX_DEVICE_INFO_CALLBACK) &&
 				(amg->cad)) {
@@ -209,11 +229,13 @@
 					be32_to_cpu(temp->d.rx_device);
 			am->evt.dev_type.tx_device = 0;
 			am->evt.acdb_id = am->evt.dev_type.rx_device;
+			amg->rx_device = am->evt.dev_type.rx_device;
 		} else if (am->evt.session_info == SESSION_RECORDING) {
 			am->evt.dev_type.rx_device = 0;
 			am->evt.dev_type.tx_device =
 					be32_to_cpu(temp->d.tx_device);
 			am->evt.acdb_id = am->evt.dev_type.tx_device;
+			amg->tx_device = am->evt.dev_type.tx_device;
 		}
 		am->evt.dev_type.ear_mute =
 					be32_to_cpu(temp->d.ear_mute);
diff --git a/arch/arm/mach-msm/qdsp5/audmgr.h b/arch/arm/mach-msm/qdsp5/audmgr.h
index 15dd954..01a0890 100644
--- a/arch/arm/mach-msm/qdsp5/audmgr.h
+++ b/arch/arm/mach-msm/qdsp5/audmgr.h
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/qdsp5/audmgr.h
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2012 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/audmgr_new.h b/arch/arm/mach-msm/qdsp5/audmgr_new.h
index 20e27f1..d775a93 100644
--- a/arch/arm/mach-msm/qdsp5/audmgr_new.h
+++ b/arch/arm/mach-msm/qdsp5/audmgr_new.h
@@ -1,6 +1,6 @@
 /* arch/arm/mach-msm/qdsp5/audmgr.h
  *
- * Copyright 2008,2012 (c) Code Aurora Forum. All rights reserved.
+ * Copyright 2008,2012 (c) The Linux Foundation. All rights reserved.
  * Copyright (C) 2008 Google, Inc.
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/qdsp5/audpp.c b/arch/arm/mach-msm/qdsp5/audpp.c
index b4b7338f..bcc00a4 100644
--- a/arch/arm/mach-msm/qdsp5/audpp.c
+++ b/arch/arm/mach-msm/qdsp5/audpp.c
@@ -4,7 +4,7 @@
  * common code to deal with the AUDPP dsp task (audio postproc)
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2009-2010, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2010, 2012-2013 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -176,12 +176,15 @@
 	struct audpp_state *audpp = &the_audpp_state;
 	int i;
 
+	mutex_lock(audpp->lock);
 	for (i = 0; i < MAX_EVENT_CALLBACK_CLIENTS; ++i) {
 		if (NULL == audpp->cb_tbl[i]) {
 			audpp->cb_tbl[i] = ecb;
+			mutex_unlock(audpp->lock);
 			return 0;
 		}
 	}
+	mutex_unlock(audpp->lock);
 	return -1;
 }
 EXPORT_SYMBOL(audpp_register_event_callback);
@@ -191,12 +194,15 @@
 	struct audpp_state *audpp = &the_audpp_state;
 	int i;
 
+	mutex_lock(audpp->lock);
 	for (i = 0; i < MAX_EVENT_CALLBACK_CLIENTS; ++i) {
 		if (ecb == audpp->cb_tbl[i]) {
 			audpp->cb_tbl[i] = NULL;
+			mutex_unlock(audpp->lock);
 			return 0;
 		}
 	}
+	mutex_unlock(audpp->lock);
 	return -1;
 }
 EXPORT_SYMBOL(audpp_unregister_event_callback);
@@ -205,9 +211,13 @@
 			    uint16_t *msg)
 {
 	unsigned n;
-	for (n = 0; n < AUDPP_CLNT_MAX_COUNT; n++) {
-		if (audpp->func[n])
-			audpp->func[n] (audpp->private[n], id, msg);
+
+	if ((id != AUDPP_MSG_PP_DISABLE_FEEDBACK) &&
+		(id != AUDPP_MSG_PP_FEATS_RE_ENABLE)) {
+		for (n = 0; n < AUDPP_CLNT_MAX_COUNT; n++) {
+			if (audpp->func[n])
+				audpp->func[n] (audpp->private[n], id, msg);
+		}
 	}
 
 	for (n = 0; n < MAX_EVENT_CALLBACK_CLIENTS; ++n)
@@ -331,6 +341,14 @@
 			msg[1], msg[2]);
 		acdb_rtc_set_err(msg[2]);
 		break;
+	case AUDPP_MSG_PP_DISABLE_FEEDBACK:
+		MM_DBG("PP Disable feedback due to mips limitation");
+		audpp_broadcast(audpp, id, msg);
+		break;
+	case AUDPP_MSG_PP_FEATS_RE_ENABLE:
+		MM_DBG("Re-enable the disabled PP features");
+		audpp_broadcast(audpp, id, msg);
+		break;
 	default:
 		MM_ERR("unhandled msg id %x\n", id);
 	}
diff --git a/arch/arm/mach-msm/qdsp5/audpreproc.c b/arch/arm/mach-msm/qdsp5/audpreproc.c
index 92e54f8..45d9153 100644
--- a/arch/arm/mach-msm/qdsp5/audpreproc.c
+++ b/arch/arm/mach-msm/qdsp5/audpreproc.c
@@ -1,7 +1,7 @@
 /*
  * Common code to deal with the AUDPREPROC dsp task (audio preprocessing)
  *
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * Based on the audpp layer in arch/arm/mach-msm/qdsp5/audpp.c
  *
diff --git a/arch/arm/mach-msm/qdsp5/audrec.c b/arch/arm/mach-msm/qdsp5/audrec.c
index e238e32..0f34518 100644
--- a/arch/arm/mach-msm/qdsp5/audrec.c
+++ b/arch/arm/mach-msm/qdsp5/audrec.c
@@ -2,7 +2,7 @@
  *
  * common code to deal with the AUDREC dsp task (audio recording)
  *
- * Copyright (c) 2009,2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009,2012 The Linux Foundation. All rights reserved.
  *
  * Based on the audpp layer in arch/arm/mach-msm/qdsp5/audpp.c
  *
diff --git a/arch/arm/mach-msm/qdsp5/dsp_debug.c b/arch/arm/mach-msm/qdsp5/dsp_debug.c
index 331ba00..6e73a60 100644
--- a/arch/arm/mach-msm/qdsp5/dsp_debug.c
+++ b/arch/arm/mach-msm/qdsp5/dsp_debug.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/dsp_debug.h b/arch/arm/mach-msm/qdsp5/dsp_debug.h
index bd40682..15c14ca 100644
--- a/arch/arm/mach-msm/qdsp5/dsp_debug.h
+++ b/arch/arm/mach-msm/qdsp5/dsp_debug.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/snd.c b/arch/arm/mach-msm/qdsp5/snd.c
index f1db012..3f379dc 100644
--- a/arch/arm/mach-msm/qdsp5/snd.c
+++ b/arch/arm/mach-msm/qdsp5/snd.c
@@ -3,7 +3,7 @@
  * interface to "snd" service on the baseband cpu
  *
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/snd_adie.c b/arch/arm/mach-msm/qdsp5/snd_adie.c
index ba7efc3..160ed93 100644
--- a/arch/arm/mach-msm/qdsp5/snd_adie.c
+++ b/arch/arm/mach-msm/qdsp5/snd_adie.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/qdsp5/snd_cad.c b/arch/arm/mach-msm/qdsp5/snd_cad.c
index c0efa3b..0b92cef2 100644
--- a/arch/arm/mach-msm/qdsp5/snd_cad.c
+++ b/arch/arm/mach-msm/qdsp5/snd_cad.c
@@ -3,7 +3,7 @@
  * interface to "snd" service on the baseband cpu
  * This code also borrows from snd.c, which is
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, 2012 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -285,8 +285,9 @@
 		vmsg.args.device.rx_device = cpu_to_be32(dev.device.rx_device);
 		vmsg.args.device.tx_device = cpu_to_be32(dev.device.tx_device);
 		vmsg.args.method = cpu_to_be32(vol.method);
-		if (vol.method != SND_METHOD_VOICE) {
-			MM_ERR("set volume: invalid method\n");
+		if (vol.method != SND_METHOD_VOICE &&
+				vol.method != SND_METHOD_MIDI) {
+			MM_ERR("set volume: invalid method %d\n", vol.method);
 			rc = -EINVAL;
 			break;
 		}
@@ -437,7 +438,7 @@
 	vmsg.args.device.rx_device = cpu_to_be32(vol.device.rx_device);
 	vmsg.args.device.tx_device = cpu_to_be32(vol.device.tx_device);
 	vmsg.args.method = cpu_to_be32(vol.method);
-	if (vol.method != SND_METHOD_VOICE) {
+	if (vol.method != SND_METHOD_VOICE && vol.method != SND_METHOD_MIDI) {
 		MM_ERR("snd_cad_ioctl set volume: invalid method\n");
 		rc = -EINVAL;
 		return rc;
@@ -448,7 +449,7 @@
 	vmsg.args.client_data = 0;
 
 	MM_DBG("snd_cad_set_volume %d %d %d %d\n", vol.device.rx_device,
-			vol.device.rx_device, vol.method, vol.volume);
+			vol.device.tx_device, vol.method, vol.volume);
 
 	rc = msm_rpc_call(snd_cad_sys->ept,
 		SND_CAD_SET_VOLUME_PROC,
diff --git a/arch/arm/mach-msm/qdsp5/snd_pcm_client.c b/arch/arm/mach-msm/qdsp5/snd_pcm_client.c
index b58d3a2..5c59601 100644
--- a/arch/arm/mach-msm/qdsp5/snd_pcm_client.c
+++ b/arch/arm/mach-msm/qdsp5/snd_pcm_client.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp5v2/adsp.c b/arch/arm/mach-msm/qdsp5v2/adsp.c
index 8c1413c..371ef00 100644
--- a/arch/arm/mach-msm/qdsp5v2/adsp.c
+++ b/arch/arm/mach-msm/qdsp5v2/adsp.c
@@ -2,7 +2,7 @@
  * Register/Interrupt access for userspace aDSP library.
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2009,2011-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009,2011-2012 The Linux Foundation. All rights reserved.
  * Author: Iliyan Malchev <ibm@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/qdsp5v2/adsp.h b/arch/arm/mach-msm/qdsp5v2/adsp.h
index 5aceff9..b5a574b 100644
--- a/arch/arm/mach-msm/qdsp5v2/adsp.h
+++ b/arch/arm/mach-msm/qdsp5v2/adsp.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  * Author: Iliyan Malchev <ibm@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/qdsp5v2/adsp_driver.c b/arch/arm/mach-msm/qdsp5v2/adsp_driver.c
index 2a4e4ec..7249bb1 100644
--- a/arch/arm/mach-msm/qdsp5v2/adsp_driver.c
+++ b/arch/arm/mach-msm/qdsp5v2/adsp_driver.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  * Author: Iliyan Malchev <ibm@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/qdsp5v2/adsp_info.c b/arch/arm/mach-msm/qdsp5v2/adsp_info.c
index 4026367..03b810d 100644
--- a/arch/arm/mach-msm/qdsp5v2/adsp_info.c
+++ b/arch/arm/mach-msm/qdsp5v2/adsp_info.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2010, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5v2/afe.c b/arch/arm/mach-msm/qdsp5v2/afe.c
index 20c9898..1e856e5 100644
--- a/arch/arm/mach-msm/qdsp5v2/afe.c
+++ b/arch/arm/mach-msm/qdsp5v2/afe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_a2dp_in.c b/arch/arm/mach-msm/qdsp5v2/audio_a2dp_in.c
index e396186..8d644f0 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_a2dp_in.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_a2dp_in.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
  *
  * sbc/pcm audio input driver
  * Based on the pcm input driver in arch/arm/mach-msm/qdsp5v2/audio_pcm_in.c
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_aac.c b/arch/arm/mach-msm/qdsp5v2/audio_aac.c
index 05bca03..883da2b 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_aac.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_aac.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_aac_in.c b/arch/arm/mach-msm/qdsp5v2/audio_aac_in.c
index 8aee946..a878e12 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_aac_in.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_aac_in.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_acdb.c b/arch/arm/mach-msm/qdsp5v2/audio_acdb.c
index 89957a4..5d7cfd7 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_acdb.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_acdb.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_adpcm.c b/arch/arm/mach-msm/qdsp5v2/audio_adpcm.c
index 95f0547..7cc3e29 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_adpcm.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_adpcm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5v2/audio_mp3.c
  *
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_amrnb.c b/arch/arm/mach-msm/qdsp5v2/audio_amrnb.c
index 55c49b3..c8b4171 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_amrnb.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_amrnb.c
@@ -1,7 +1,7 @@
 /*
  * amrnb audio decoder device
  *
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5/audio_mp3.c
  *
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_amrnb_in.c b/arch/arm/mach-msm/qdsp5v2/audio_amrnb_in.c
index f1951f7..8e66939 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_amrnb_in.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_amrnb_in.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_amrwb.c b/arch/arm/mach-msm/qdsp5v2/audio_amrwb.c
index a653d5b..66d0a9e 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_amrwb.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_amrwb.c
@@ -1,6 +1,6 @@
 /* amrwb audio decoder device
  *
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5v2/audio_mp3.c
  *
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_dev_ctl.c b/arch/arm/mach-msm/qdsp5v2/audio_dev_ctl.c
index b6d6e5e..b1446e8 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_dev_ctl.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_dev_ctl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_evrc.c b/arch/arm/mach-msm/qdsp5v2/audio_evrc.c
index 7306e98..2d9327e 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_evrc.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_evrc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * This code also borrows from audio_aac.c, which is
  * Copyright (C) 2008 Google, Inc.
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_evrc_in.c b/arch/arm/mach-msm/qdsp5v2/audio_evrc_in.c
index 6e95dc5..7d9b1fa 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_evrc_in.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_evrc_in.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_fm.c b/arch/arm/mach-msm/qdsp5v2/audio_fm.c
index af65c80..cffa7e7 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_fm.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_fm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved.
  *
  * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5v2/audio_mp3.c
  *
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_interct.c b/arch/arm/mach-msm/qdsp5v2/audio_interct.c
index 785ed8e..4e4c5d6 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_interct.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_interct.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2011 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_mp3.c b/arch/arm/mach-msm/qdsp5v2/audio_mp3.c
index 53ae0a4..0390edf 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_mp3.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_mp3.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_mvs.c b/arch/arm/mach-msm/qdsp5v2/audio_mvs.c
index 1884b3c..f211fa0 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_mvs.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_mvs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_pcm.c b/arch/arm/mach-msm/qdsp5v2/audio_pcm.c
index 4b308b0..ea8fc83 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_pcm.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_pcm.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_qcelp.c b/arch/arm/mach-msm/qdsp5v2/audio_qcelp.c
index c53922b..bb360be 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_qcelp.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_qcelp.c
@@ -1,7 +1,7 @@
 /*
  * qcelp 13k audio decoder device
  *
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * This code is based in part on audio_mp3.c, which is
  * Copyright (C) 2008 Google, Inc.
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_qcelp_in.c b/arch/arm/mach-msm/qdsp5v2/audio_qcelp_in.c
index 8ad738e..0f8956f 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_qcelp_in.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_qcelp_in.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_wma.c b/arch/arm/mach-msm/qdsp5v2/audio_wma.c
index 8562020..4e5dcd3 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_wma.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_wma.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5v2/audio_mp3.c
  *
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_wmapro.c b/arch/arm/mach-msm/qdsp5v2/audio_wmapro.c
index ca072b3..84cfed6 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_wmapro.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_wmapro.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5v2/audio_mp3.c
  *
diff --git a/arch/arm/mach-msm/qdsp5v2/audpp.c b/arch/arm/mach-msm/qdsp5v2/audpp.c
index 31ce643..7a40156 100644
--- a/arch/arm/mach-msm/qdsp5v2/audpp.c
+++ b/arch/arm/mach-msm/qdsp5v2/audpp.c
@@ -3,7 +3,7 @@
  * common code to deal with the AUDPP dsp task (audio postproc)
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2011, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5v2/audpreproc.c b/arch/arm/mach-msm/qdsp5v2/audpreproc.c
index c9abdab..28eead0 100644
--- a/arch/arm/mach-msm/qdsp5v2/audpreproc.c
+++ b/arch/arm/mach-msm/qdsp5v2/audpreproc.c
@@ -1,7 +1,7 @@
 /*
  * Common code to deal with the AUDPREPROC dsp task (audio preprocessing)
  *
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2011, The Linux Foundation. All rights reserved.
  *
  * Based on the audpp layer in arch/arm/mach-msm/qdsp5/audpp.c
  *
diff --git a/arch/arm/mach-msm/qdsp5v2/aux_pcm.c b/arch/arm/mach-msm/qdsp5v2/aux_pcm.c
index 4cc834d..06318bc 100644
--- a/arch/arm/mach-msm/qdsp5v2/aux_pcm.c
+++ b/arch/arm/mach-msm/qdsp5v2/aux_pcm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/qdsp5v2/lpa.c b/arch/arm/mach-msm/qdsp5v2/lpa.c
index 98297e3..5ffda8a 100644
--- a/arch/arm/mach-msm/qdsp5v2/lpa.c
+++ b/arch/arm/mach-msm/qdsp5v2/lpa.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/qdsp5v2/mi2s.c b/arch/arm/mach-msm/qdsp5v2/mi2s.c
index e38f164..b649ec1 100644
--- a/arch/arm/mach-msm/qdsp5v2/mi2s.c
+++ b/arch/arm/mach-msm/qdsp5v2/mi2s.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009,2011 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009,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
diff --git a/arch/arm/mach-msm/qdsp5v2/mp3_funcs.c b/arch/arm/mach-msm/qdsp5v2/mp3_funcs.c
index 0b20be0..f857e5c 100644
--- a/arch/arm/mach-msm/qdsp5v2/mp3_funcs.c
+++ b/arch/arm/mach-msm/qdsp5v2/mp3_funcs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp5v2/pcm_funcs.c b/arch/arm/mach-msm/qdsp5v2/pcm_funcs.c
index d7935a7..866b71d 100644
--- a/arch/arm/mach-msm/qdsp5v2/pcm_funcs.c
+++ b/arch/arm/mach-msm/qdsp5v2/pcm_funcs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp5v2/snddev_data_marimba.c b/arch/arm/mach-msm/qdsp5v2/snddev_data_marimba.c
index b15d4c4..b11cdb0 100644
--- a/arch/arm/mach-msm/qdsp5v2/snddev_data_marimba.c
+++ b/arch/arm/mach-msm/qdsp5v2/snddev_data_marimba.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/qdsp5v2/snddev_data_timpani.c b/arch/arm/mach-msm/qdsp5v2/snddev_data_timpani.c
index c0a48c8..a4e4dad 100644
--- a/arch/arm/mach-msm/qdsp5v2/snddev_data_timpani.c
+++ b/arch/arm/mach-msm/qdsp5v2/snddev_data_timpani.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp5v2/snddev_ecodec.c b/arch/arm/mach-msm/qdsp5v2/snddev_ecodec.c
index 943489a..d8009aa 100644
--- a/arch/arm/mach-msm/qdsp5v2/snddev_ecodec.c
+++ b/arch/arm/mach-msm/qdsp5v2/snddev_ecodec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009,2011 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009,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
diff --git a/arch/arm/mach-msm/qdsp5v2/snddev_icodec.c b/arch/arm/mach-msm/qdsp5v2/snddev_icodec.c
index c416c07..cbb0587 100644
--- a/arch/arm/mach-msm/qdsp5v2/snddev_icodec.c
+++ b/arch/arm/mach-msm/qdsp5v2/snddev_icodec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/qdsp5v2/snddev_mi2s.c b/arch/arm/mach-msm/qdsp5v2/snddev_mi2s.c
index b5f3b66..7f4ee26 100644
--- a/arch/arm/mach-msm/qdsp5v2/snddev_mi2s.c
+++ b/arch/arm/mach-msm/qdsp5v2/snddev_mi2s.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp5v2/snddev_virtual.c b/arch/arm/mach-msm/qdsp5v2/snddev_virtual.c
index cd93345..aa1d557 100644
--- a/arch/arm/mach-msm/qdsp5v2/snddev_virtual.c
+++ b/arch/arm/mach-msm/qdsp5v2/snddev_virtual.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp5v2/timpani_profile_7x30.h b/arch/arm/mach-msm/qdsp5v2/timpani_profile_7x30.h
index d9003cd..e4cf131 100644
--- a/arch/arm/mach-msm/qdsp5v2/timpani_profile_7x30.h
+++ b/arch/arm/mach-msm/qdsp5v2/timpani_profile_7x30.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp5v2/voice.c b/arch/arm/mach-msm/qdsp5v2/voice.c
index 026acb3..1ac79d4 100644
--- a/arch/arm/mach-msm/qdsp5v2/voice.c
+++ b/arch/arm/mach-msm/qdsp5v2/voice.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/qdsp6/aac_in.c b/arch/arm/mach-msm/qdsp6/aac_in.c
index 9e1d5b6..6e3bf94 100644
--- a/arch/arm/mach-msm/qdsp6/aac_in.c
+++ b/arch/arm/mach-msm/qdsp6/aac_in.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6/amrnb_in.c b/arch/arm/mach-msm/qdsp6/amrnb_in.c
index e7756e1..e20bf5b 100644
--- a/arch/arm/mach-msm/qdsp6/amrnb_in.c
+++ b/arch/arm/mach-msm/qdsp6/amrnb_in.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6/analog_audio.c b/arch/arm/mach-msm/qdsp6/analog_audio.c
index 688f57e..d3a6baa 100644
--- a/arch/arm/mach-msm/qdsp6/analog_audio.c
+++ b/arch/arm/mach-msm/qdsp6/analog_audio.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/aac_in.c b/arch/arm/mach-msm/qdsp6/audiov2/aac_in.c
index fe6c049..ef566c9 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/aac_in.c
+++ b/arch/arm/mach-msm/qdsp6/audiov2/aac_in.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/amrnb_in.c b/arch/arm/mach-msm/qdsp6/audiov2/amrnb_in.c
index b877977..e552ada 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/amrnb_in.c
+++ b/arch/arm/mach-msm/qdsp6/audiov2/amrnb_in.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/analog_audio.c b/arch/arm/mach-msm/qdsp6/audiov2/analog_audio.c
index 1df4f5d..5bf2cea 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/analog_audio.c
+++ b/arch/arm/mach-msm/qdsp6/audiov2/analog_audio.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/audio_ctl.c b/arch/arm/mach-msm/qdsp6/audiov2/audio_ctl.c
index 286d85d..4ebfc02 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/audio_ctl.c
+++ b/arch/arm/mach-msm/qdsp6/audiov2/audio_ctl.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/dal_acdb.h b/arch/arm/mach-msm/qdsp6/audiov2/dal_acdb.h
index d88b7ad..b4949f9 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/dal_acdb.h
+++ b/arch/arm/mach-msm/qdsp6/audiov2/dal_acdb.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/dal_adie.h b/arch/arm/mach-msm/qdsp6/audiov2/dal_adie.h
index e828e9c..aac484c 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/dal_adie.h
+++ b/arch/arm/mach-msm/qdsp6/audiov2/dal_adie.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/dal_audio.h b/arch/arm/mach-msm/qdsp6/audiov2/dal_audio.h
index 52de785..2f9510b 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/dal_audio.h
+++ b/arch/arm/mach-msm/qdsp6/audiov2/dal_audio.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/dal_audio_format.h b/arch/arm/mach-msm/qdsp6/audiov2/dal_audio_format.h
index 348aad1..218fa53 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/dal_audio_format.h
+++ b/arch/arm/mach-msm/qdsp6/audiov2/dal_audio_format.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/dal_voice.h b/arch/arm/mach-msm/qdsp6/audiov2/dal_voice.h
index 62c1122..6836de4 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/dal_voice.h
+++ b/arch/arm/mach-msm/qdsp6/audiov2/dal_voice.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/evrc_in.c b/arch/arm/mach-msm/qdsp6/audiov2/evrc_in.c
index 88f19b7..9c54455 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/evrc_in.c
+++ b/arch/arm/mach-msm/qdsp6/audiov2/evrc_in.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/mp3.c b/arch/arm/mach-msm/qdsp6/audiov2/mp3.c
index 0781eda..7d9cfa2 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/mp3.c
+++ b/arch/arm/mach-msm/qdsp6/audiov2/mp3.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/pcm_in.c b/arch/arm/mach-msm/qdsp6/audiov2/pcm_in.c
index 6ef2195..4de2199 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/pcm_in.c
+++ b/arch/arm/mach-msm/qdsp6/audiov2/pcm_in.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/pcm_out.c b/arch/arm/mach-msm/qdsp6/audiov2/pcm_out.c
index 6743c6c..effd119 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/pcm_out.c
+++ b/arch/arm/mach-msm/qdsp6/audiov2/pcm_out.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/qdsp6/audiov2/pcm_out.c
  *
  * Copyright (C) 2009 Google, Inc.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * Author: Brian Swetland <swetland@google.com>
  *
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/q6audio.c b/arch/arm/mach-msm/qdsp6/audiov2/q6audio.c
index af411f1..5895867 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/q6audio.c
+++ b/arch/arm/mach-msm/qdsp6/audiov2/q6audio.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/qdsp6/audiov2/q6audio.c
  *
  * Copyright (C) 2009 Google, Inc.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * Author: Brian Swetland <swetland@google.com>
  *
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/q6audio_devices.h b/arch/arm/mach-msm/qdsp6/audiov2/q6audio_devices.h
index aa8a699..3786cca 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/q6audio_devices.h
+++ b/arch/arm/mach-msm/qdsp6/audiov2/q6audio_devices.h
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/qdsp6/audiov2/q6audio_devices.h
  *
  * Copyright (C) 2009 Google, Inc.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * Author: Brian Swetland <swetland@google.com>
  *
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/qcelp_in.c b/arch/arm/mach-msm/qdsp6/audiov2/qcelp_in.c
index a13084f..40ae37d 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/qcelp_in.c
+++ b/arch/arm/mach-msm/qdsp6/audiov2/qcelp_in.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * Author: Brian Swetland <swetland@google.com>
  *
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/routing.c b/arch/arm/mach-msm/qdsp6/audiov2/routing.c
index 1a2476b..1ba128c 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/routing.c
+++ b/arch/arm/mach-msm/qdsp6/audiov2/routing.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/qdsp6/audiov2/routing.c
  *
  * Copyright (C) 2009 Google, Inc.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * Author: Brian Swetland <swetland@google.com>
  *
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/voice.c b/arch/arm/mach-msm/qdsp6/audiov2/voice.c
index 906c534..ccb2bad 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/voice.c
+++ b/arch/arm/mach-msm/qdsp6/audiov2/voice.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp6/auxpcm_lb_in.c b/arch/arm/mach-msm/qdsp6/auxpcm_lb_in.c
index 4195454..ff254a6 100644
--- a/arch/arm/mach-msm/qdsp6/auxpcm_lb_in.c
+++ b/arch/arm/mach-msm/qdsp6/auxpcm_lb_in.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6/auxpcm_lb_out.c b/arch/arm/mach-msm/qdsp6/auxpcm_lb_out.c
index b680597..bba6b94 100644
--- a/arch/arm/mach-msm/qdsp6/auxpcm_lb_out.c
+++ b/arch/arm/mach-msm/qdsp6/auxpcm_lb_out.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2009 Google, Inc.
  * Author: Brian Swetland <swetland@google.com>
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, The Linux Foundation. All rights reserved.
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
  * may be copied, distributed, and modified under those terms.
diff --git a/arch/arm/mach-msm/qdsp6/dal_acdb.h b/arch/arm/mach-msm/qdsp6/dal_acdb.h
index dfb1fef..511879c 100644
--- a/arch/arm/mach-msm/qdsp6/dal_acdb.h
+++ b/arch/arm/mach-msm/qdsp6/dal_acdb.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/qdsp6/dal_adie.h b/arch/arm/mach-msm/qdsp6/dal_adie.h
index 6abc60c..78db05f 100644
--- a/arch/arm/mach-msm/qdsp6/dal_adie.h
+++ b/arch/arm/mach-msm/qdsp6/dal_adie.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/qdsp6/dal_audio.h b/arch/arm/mach-msm/qdsp6/dal_audio.h
index 25d1e4f..6c353db 100644
--- a/arch/arm/mach-msm/qdsp6/dal_audio.h
+++ b/arch/arm/mach-msm/qdsp6/dal_audio.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/qdsp6/dal_audio_format.h b/arch/arm/mach-msm/qdsp6/dal_audio_format.h
index 6382693..4223974 100644
--- a/arch/arm/mach-msm/qdsp6/dal_audio_format.h
+++ b/arch/arm/mach-msm/qdsp6/dal_audio_format.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/qdsp6/dtmf.c b/arch/arm/mach-msm/qdsp6/dtmf.c
index cf27488..30978df 100644
--- a/arch/arm/mach-msm/qdsp6/dtmf.c
+++ b/arch/arm/mach-msm/qdsp6/dtmf.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp6/evrc_in.c b/arch/arm/mach-msm/qdsp6/evrc_in.c
index 9fc412b..e059efa 100644
--- a/arch/arm/mach-msm/qdsp6/evrc_in.c
+++ b/arch/arm/mach-msm/qdsp6/evrc_in.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6/msm_q6vdec.c b/arch/arm/mach-msm/qdsp6/msm_q6vdec.c
index f285536..24d2117 100644
--- a/arch/arm/mach-msm/qdsp6/msm_q6vdec.c
+++ b/arch/arm/mach-msm/qdsp6/msm_q6vdec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/arch/arm/mach-msm/qdsp6/msm_q6venc.c b/arch/arm/mach-msm/qdsp6/msm_q6venc.c
index 0917c70..4704ae7 100644
--- a/arch/arm/mach-msm/qdsp6/msm_q6venc.c
+++ b/arch/arm/mach-msm/qdsp6/msm_q6venc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/arch/arm/mach-msm/qdsp6/q6audio.c b/arch/arm/mach-msm/qdsp6/q6audio.c
index 2d015fc..f660bdc 100644
--- a/arch/arm/mach-msm/qdsp6/q6audio.c
+++ b/arch/arm/mach-msm/qdsp6/q6audio.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2009 Google, Inc.
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/qdsp6/qcelp_in.c b/arch/arm/mach-msm/qdsp6/qcelp_in.c
index ca0ab1a..4289612 100644
--- a/arch/arm/mach-msm/qdsp6/qcelp_in.c
+++ b/arch/arm/mach-msm/qdsp6/qcelp_in.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, The Linux Foundation. All rights reserved.
  *
  * Author: Brian Swetland <swetland@google.com>
  *
diff --git a/arch/arm/mach-msm/qdsp6v2/Makefile b/arch/arm/mach-msm/qdsp6v2/Makefile
index 08a6de6..34d336e 100644
--- a/arch/arm/mach-msm/qdsp6v2/Makefile
+++ b/arch/arm/mach-msm/qdsp6v2/Makefile
@@ -13,17 +13,18 @@
 endif
 obj-$(CONFIG_MSM_QDSP6_APR) += apr.o apr_v1.o apr_tal.o q6core.o dsp_debug.o
 obj-$(CONFIG_MSM_QDSP6_APRV2) += apr.o apr_v2.o apr_tal.o q6core.o dsp_debug.o
-obj-y += audio_acdb.o
 ifdef CONFIG_ARCH_MSM9615
+obj-y += audio_acdb.o
 obj-y += rtac.o
 endif
 obj-$(CONFIG_MSM_QDSP6_CODECS) += aac_in.o qcelp_in.o evrc_in.o amrnb_in.o audio_utils.o
 obj-$(CONFIG_MSM_QDSP6_CODECS) += audio_wma.o audio_wmapro.o audio_aac.o audio_multi_aac.o audio_utils_aio.o
-obj-$(CONFIG_MSM_QDSP6_CODECS) += rtac.o q6audio_v1.o q6audio_v1_aio.o
+obj-$(CONFIG_MSM_QDSP6_CODECS) += audio_acdb.o rtac.o q6audio_v1.o q6audio_v1_aio.o
 obj-$(CONFIG_MSM_QDSP6_CODECS) += audio_mp3.o audio_amrnb.o audio_amrwb.o audio_amrwbplus.o audio_evrc.o audio_qcelp.o amrwb_in.o
 obj-$(CONFIG_MSM_QDSP6V2_CODECS) += aac_in.o qcelp_in.o evrc_in.o amrnb_in.o audio_utils.o
 obj-$(CONFIG_MSM_QDSP6V2_CODECS) += audio_wma.o audio_wmapro.o audio_aac.o audio_multi_aac.o audio_utils_aio.o
-obj-$(CONFIG_MSM_QDSP6V2_CODECS) += rtac_v2.o q6audio_v2.o q6audio_v2_aio.o
+obj-$(CONFIG_MSM_QDSP6V2_CODECS) += q6audio_v2.o q6audio_v2_aio.o
 obj-$(CONFIG_MSM_QDSP6V2_CODECS)  += audio_mp3.o audio_amrnb.o audio_amrwb.o audio_evrc.o audio_qcelp.o amrwb_in.o
 obj-$(CONFIG_MSM_ADSP_LOADER) += adsp-loader.o
 obj-$(CONFIG_MSM_ULTRASOUND_A) += ultrasound/version_a/
+obj-$(CONFIG_MSM_ULTRASOUND_B) += ultrasound/version_b/
diff --git a/arch/arm/mach-msm/qdsp6v2/aac_in.c b/arch/arm/mach-msm/qdsp6v2/aac_in.c
index 6e79a75..5e959b5 100644
--- a/arch/arm/mach-msm/qdsp6v2/aac_in.c
+++ b/arch/arm/mach-msm/qdsp6v2/aac_in.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/arm/mach-msm/qdsp6v2/adsp-loader.c b/arch/arm/mach-msm/qdsp6v2/adsp-loader.c
index 02dbece..7472b46 100644
--- a/arch/arm/mach-msm/qdsp6v2/adsp-loader.c
+++ b/arch/arm/mach-msm/qdsp6v2/adsp-loader.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/qdsp6v2/amrnb_in.c b/arch/arm/mach-msm/qdsp6v2/amrnb_in.c
index 63a0774..91c588c 100644
--- a/arch/arm/mach-msm/qdsp6v2/amrnb_in.c
+++ b/arch/arm/mach-msm/qdsp6v2/amrnb_in.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp6v2/amrwb_in.c b/arch/arm/mach-msm/qdsp6v2/amrwb_in.c
index d0462e0..ea3fe5b 100644
--- a/arch/arm/mach-msm/qdsp6v2/amrwb_in.c
+++ b/arch/arm/mach-msm/qdsp6v2/amrwb_in.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/qdsp6v2/apr.c b/arch/arm/mach-msm/qdsp6v2/apr.c
index 39bec8e..4c106c5 100644
--- a/arch/arm/mach-msm/qdsp6v2/apr.c
+++ b/arch/arm/mach-msm/qdsp6v2/apr.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -55,7 +55,7 @@
 	int client_id;
 };
 
-static const struct apr_svc_table svc_tbl_audio[] = {
+static const struct apr_svc_table svc_tbl_qdsp6[] = {
 	{
 		.name = "AFE",
 		.idx = 0,
@@ -110,6 +110,12 @@
 		.id = APR_SVC_USM,
 		.client_id = APR_CLIENT_AUDIO,
 	},
+	{
+		.name = "VIDC",
+		.idx = 9,
+		.id = APR_SVC_VIDC,
+		.client_id = APR_CLIENT_AUDIO,
+	},
 };
 
 static struct apr_svc_table svc_tbl_voice[] = {
@@ -387,6 +393,8 @@
 		    svc == APR_SVC_TEST_CLIENT || svc == APR_SVC_ADSP_MVM ||
 		    svc == APR_SVC_ADSP_CVS || svc == APR_SVC_ADSP_CVP)
 			clnt = APR_CLIENT_AUDIO;
+		else if (svc == APR_SVC_VIDC)
+			clnt = APR_CLIENT_AUDIO;
 		else {
 			pr_err("APR: Wrong svc :%d\n", svc);
 			return;
@@ -441,8 +449,8 @@
 	int ret = 0;
 
 	if (dest_id == APR_DEST_QDSP6) {
-		tbl = (struct apr_svc_table *)&svc_tbl_audio;
-		size = ARRAY_SIZE(svc_tbl_audio);
+		tbl = (struct apr_svc_table *)&svc_tbl_qdsp6;
+		size = ARRAY_SIZE(svc_tbl_qdsp6);
 	} else {
 		tbl = (struct apr_svc_table *)&svc_tbl_voice;
 		size = ARRAY_SIZE(svc_tbl_voice);
diff --git a/arch/arm/mach-msm/qdsp6v2/apr_tal.c b/arch/arm/mach-msm/qdsp6v2/apr_tal.c
index 03f0513..8826a35 100644
--- a/arch/arm/mach-msm/qdsp6v2/apr_tal.c
+++ b/arch/arm/mach-msm/qdsp6v2/apr_tal.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
@@ -133,12 +133,12 @@
 		spin_unlock_irqrestore(&apr_ch->lock, flags);
 		break;
 	case SMD_EVENT_OPEN:
-		pr_info("apr_tal: SMD_EVENT_OPEN\n");
+		pr_debug("apr_tal: SMD_EVENT_OPEN\n");
 		apr_ch->smd_state = 1;
 		wake_up(&apr_ch->wait);
 		break;
 	case SMD_EVENT_CLOSE:
-		pr_info("apr_tal: SMD_EVENT_CLOSE\n");
+		pr_debug("apr_tal: SMD_EVENT_CLOSE\n");
 		break;
 	}
 }
diff --git a/arch/arm/mach-msm/qdsp6v2/apr_v1.c b/arch/arm/mach-msm/qdsp6v2/apr_v1.c
index 870bbb4..d7ed919 100644
--- a/arch/arm/mach-msm/qdsp6v2/apr_v1.c
+++ b/arch/arm/mach-msm/qdsp6v2/apr_v1.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/qdsp6v2/apr_v2.c b/arch/arm/mach-msm/qdsp6v2/apr_v2.c
index ed494e4..fbb8713 100644
--- a/arch/arm/mach-msm/qdsp6v2/apr_v2.c
+++ b/arch/arm/mach-msm/qdsp6v2/apr_v2.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -50,16 +50,16 @@
 			pr_err("%s: adsp not up\n", __func__);
 			return NULL;
 		}
-		pr_info("%s: adsp Up\n", __func__);
+		pr_debug("%s: adsp Up\n", __func__);
 	} else if ((dest_id == APR_DEST_MODEM) &&
 		   (apr_get_modem_state() == APR_SUBSYS_DOWN)) {
-		pr_info("%s: Wait for modem to bootup\n", __func__);
+		pr_debug("%s: Wait for modem to bootup\n", __func__);
 		rc = apr_wait_for_device_up(dest_id);
 		if (rc == 0) {
 			pr_err("%s: Modem is not Up\n", __func__);
 			return NULL;
 		}
-		pr_info("%s: modem Up\n", __func__);
+		pr_debug("%s: modem Up\n", __func__);
 	}
 
 	if (apr_get_svc(svc_name, dest_id, &client_id, &svc_idx, &svc_id)) {
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_aac.c b/arch/arm/mach-msm/qdsp6v2/audio_aac.c
index 44ab611..f4eb318 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_aac.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_aac.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -104,6 +104,11 @@
 		audio->eos_rsp = 0;
 		audio->eos_flag = 0;
 		if (!rc) {
+			rc = enable_volume_ramp(audio);
+			if (rc < 0) {
+				pr_err("%s: Failed to enable volume ramp\n",
+					__func__);
+			}
 			audio->enabled = 1;
 		} else {
 			audio->enabled = 0;
@@ -135,10 +140,9 @@
 		} else {
 			uint16_t sce_left = 1, sce_right = 2;
 			aac_config = audio->codec_cfg;
-			if ((aac_config->dual_mono_mode <
-				AUDIO_AAC_DUAL_MONO_PL_PR) ||
-				(aac_config->dual_mono_mode >
-				AUDIO_AAC_DUAL_MONO_PL_SR)) {
+			/* PL_PR is 0 only need to check PL_SR */
+			if (aac_config->dual_mono_mode >
+			    AUDIO_AAC_DUAL_MONO_PL_SR) {
 				pr_err("%s:AUDIO_SET_AAC_CONFIG: Invalid"
 					"dual_mono mode =%d\n", __func__,
 					aac_config->dual_mono_mode);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_acdb.c b/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
index cad845f..ea22c12 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -64,15 +64,6 @@
 	atomic_t			vocstrm_total_cal_size;
 	atomic_t			vocvol_total_cal_size;
 
-	/* Voice Column data */
-	struct acdb_atomic_cal_block	vocproc_col_cal[MAX_VOCPROC_TYPES];
-	uint32_t			*col_data[MAX_VOCPROC_TYPES];
-
-	/* VocProc dev cfg cal*/
-	struct acdb_atomic_cal_block	vocproc_dev_cal[MAX_NETWORKS];
-	atomic_t			vocproc_dev_cal_size;
-	atomic_t			vocproc_dev_total_cal_size;
-
 	/* AFE cal */
 	struct acdb_atomic_cal_block	afe_cal[MAX_AUDPROC_TYPES];
 
@@ -203,45 +194,6 @@
 		atomic_read(&acdb_data.vocvol_total_cal_size);
 }
 
-void get_voice_col_data(uint32_t vocproc_type,
-			struct acdb_cal_block *cal_block)
-{
-	if (cal_block == NULL) {
-		pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
-		goto done;
-	}
-
-	cal_block->cal_kvaddr = atomic_read(&acdb_data.
-				vocproc_col_cal[vocproc_type].cal_kvaddr);
-	cal_block->cal_paddr = atomic_read(&acdb_data.
-				vocproc_col_cal[vocproc_type].cal_paddr);
-	cal_block->cal_size = atomic_read(&acdb_data.
-				vocproc_col_cal[vocproc_type].cal_size);
-done:
-	return;
-}
-
-void store_voice_col_data(uint32_t vocproc_type, uint32_t cal_size,
-			  uint32_t *cal_data)
-{
-	if (cal_size > MAX_COL_SIZE) {
-		pr_err("%s: col size is to big %d\n", __func__,
-				cal_size);
-		goto done;
-	}
-	if (copy_from_user(acdb_data.col_data[vocproc_type],
-			(void *)((uint8_t *)cal_data + sizeof(cal_size)),
-			cal_size)) {
-		pr_err("%s: fail to copy col size %d\n",
-			__func__, cal_size);
-		goto done;
-	}
-	atomic_set(&acdb_data.vocproc_col_cal[vocproc_type].cal_size,
-		cal_size);
-done:
-	return;
-}
-
 void get_anc_cal(struct acdb_cal_block *cal_block)
 {
 	pr_debug("%s\n", __func__);
@@ -482,7 +434,7 @@
 	return;
 }
 
-void store_vocproc_dev_cfg_cal(int32_t len, struct cal_block *cal_blocks)
+void store_vocproc_cal(int32_t len, struct cal_block *cal_blocks)
 {
 	int i;
 	pr_debug("%s\n", __func__);
@@ -493,57 +445,6 @@
 		goto done;
 	}
 
-	atomic_set(&acdb_data.vocproc_dev_total_cal_size, 0);
-	for (i = 0; i < len; i++) {
-		if (cal_blocks[i].cal_offset >
-					atomic64_read(&acdb_data.mem_len)) {
-			pr_err("%s: offset %d is > mem_len %ld\n",
-				__func__, cal_blocks[i].cal_offset,
-				(long)atomic64_read(&acdb_data.mem_len));
-			atomic_set(&acdb_data.vocproc_dev_cal[i].cal_size, 0);
-		} else {
-			atomic_add(cal_blocks[i].cal_size,
-				&acdb_data.vocproc_dev_total_cal_size);
-			atomic_set(&acdb_data.vocproc_dev_cal[i].cal_size,
-				cal_blocks[i].cal_size);
-			atomic_set(&acdb_data.vocproc_dev_cal[i].cal_paddr,
-				cal_blocks[i].cal_offset +
-				atomic64_read(&acdb_data.paddr));
-			atomic_set(&acdb_data.vocproc_dev_cal[i].cal_kvaddr,
-				cal_blocks[i].cal_offset +
-				atomic64_read(&acdb_data.kvaddr));
-		}
-	}
-	atomic_set(&acdb_data.vocproc_dev_cal_size, len);
-done:
-	return;
-}
-
-void get_vocproc_dev_cfg_cal(struct acdb_cal_block *cal_block)
-{
-	pr_debug("%s\n", __func__);
-
-	cal_block->cal_kvaddr =
-		atomic_read(&acdb_data.vocproc_dev_cal[0].cal_kvaddr);
-	cal_block->cal_paddr =
-		atomic_read(&acdb_data.vocproc_dev_cal[0].cal_paddr);
-	cal_block->cal_size =
-		atomic_read(&acdb_data.vocproc_dev_total_cal_size);
-}
-
-
-
-void store_vocproc_cal(int32_t len, struct cal_block *cal_blocks)
-{
-	int i;
-	pr_debug("%s\n", __func__);
-
-	if (len > MAX_NETWORKS) {
-		pr_err("%s: Calibration sent for %d networks, only %d are "
-			"supported!\n", __func__, len, MAX_NETWORKS);
-		goto done;
-	}
-
 	atomic_set(&acdb_data.vocproc_total_cal_size, 0);
 	for (i = 0; i < len; i++) {
 		if (cal_blocks[i].cal_offset >
@@ -591,8 +492,8 @@
 	pr_debug("%s\n", __func__);
 
 	if (len > MAX_NETWORKS) {
-		pr_err("%s: Calibration sent for %d networks, only %d are "
-			"supported!\n", __func__, len, MAX_NETWORKS);
+		pr_err("%s: Calibration sent for %d networks, only %d are supported!\n",
+			__func__, len, MAX_NETWORKS);
 		goto done;
 	}
 
@@ -643,8 +544,8 @@
 	pr_debug("%s\n", __func__);
 
 	if (len > MAX_NETWORKS) {
-		pr_err("%s: Calibration sent for %d networks, only %d are "
-			"supported!\n", __func__, len, MAX_NETWORKS);
+		pr_err("%s: Calibration sent for %d networks, only %d are supported!\n",
+			__func__, len, MAX_NETWORKS);
 		goto done;
 	}
 
@@ -719,8 +620,7 @@
 	pr_debug("%s\n", __func__);
 
 	if (atomic64_read(&acdb_data.mem_len)) {
-		pr_debug("%s: ACDB opened but memory allocated, "
-			"using existing allocation!\n",
+		pr_debug("%s: ACDB opened but memory allocated, using existing allocation!\n",
 			__func__);
 	}
 
@@ -730,19 +630,12 @@
 
 static int deregister_memory(void)
 {
-	int i;
-
 	if (atomic64_read(&acdb_data.mem_len)) {
 		mutex_lock(&acdb_data.acdb_mutex);
 		atomic64_set(&acdb_data.mem_len, 0);
 		atomic_set(&acdb_data.vocstrm_total_cal_size, 0);
 		atomic_set(&acdb_data.vocproc_total_cal_size, 0);
 		atomic_set(&acdb_data.vocvol_total_cal_size, 0);
-
-		for (i = 0; i < MAX_VOCPROC_TYPES; i++) {
-			kfree(acdb_data.col_data[i]);
-			acdb_data.col_data[i] = NULL;
-		}
 		ion_unmap_kernel(acdb_data.ion_client, acdb_data.ion_handle);
 		ion_free(acdb_data.ion_client, acdb_data.ion_handle);
 		ion_client_destroy(acdb_data.ion_client);
@@ -754,18 +647,12 @@
 static int register_memory(void)
 {
 	int			result;
-	int			i;
 	unsigned long		paddr;
 	void                    *kvptr;
 	unsigned long		kvaddr;
 	unsigned long		mem_len;
 
 	mutex_lock(&acdb_data.acdb_mutex);
-	for (i = 0; i < MAX_VOCPROC_TYPES; i++) {
-		acdb_data.col_data[i] = kmalloc(MAX_COL_SIZE, GFP_KERNEL);
-		atomic_set(&acdb_data.vocproc_col_cal[i].cal_kvaddr,
-			(uint32_t)acdb_data.col_data[i]);
-	}
 
 	acdb_data.ion_client =
 		msm_ion_client_create(UINT_MAX, "audio_acdb_client");
@@ -803,8 +690,7 @@
 	atomic64_set(&acdb_data.mem_len, mem_len);
 	mutex_unlock(&acdb_data.acdb_mutex);
 
-	pr_debug("%s done! paddr = 0x%lx, "
-		"kvaddr = 0x%lx, len = x%lx\n",
+	pr_debug("%s done! paddr = 0x%lx, kvaddr = 0x%lx, len = x%lx\n",
 		 __func__,
 		(long)atomic64_read(&acdb_data.paddr),
 		(long)atomic64_read(&acdb_data.kvaddr),
@@ -820,6 +706,7 @@
 	mutex_unlock(&acdb_data.acdb_mutex);
 	return result;
 }
+
 static long acdb_ioctl(struct file *f,
 		unsigned int cmd, unsigned long arg)
 {
@@ -906,18 +793,6 @@
 		goto done;
 	}
 
-	switch (cmd) {
-	case AUDIO_SET_VOCPROC_COL_CAL:
-		store_voice_col_data(VOCPROC_CAL, size, (uint32_t *)arg);
-		goto done;
-	case AUDIO_SET_VOCSTRM_COL_CAL:
-		store_voice_col_data(VOCSTRM_CAL, size, (uint32_t *)arg);
-		goto done;
-	case AUDIO_SET_VOCVOL_COL_CAL:
-		store_voice_col_data(VOCVOL_CAL, size, (uint32_t *)arg);
-		goto done;
-	}
-
 	if (copy_from_user(data, (void *)(arg + sizeof(size)), size)) {
 
 		pr_err("%s: fail to copy table size %d\n", __func__, size);
@@ -934,50 +809,50 @@
 	switch (cmd) {
 	case AUDIO_SET_AUDPROC_TX_CAL:
 		if (size > sizeof(struct cal_block))
-			pr_err("%s: More Audproc Cal then expected, "
-				"size received: %d\n", __func__, size);
+			pr_err("%s: More Audproc Cal then expected, size received: %d\n",
+				__func__, size);
 		store_audproc_cal(TX_CAL, (struct cal_block *)data);
 		break;
 	case AUDIO_SET_AUDPROC_RX_CAL:
 		if (size > sizeof(struct cal_block))
-			pr_err("%s: More Audproc Cal then expected, "
-				"size received: %d\n", __func__, size);
+			pr_err("%s: More Audproc Cal then expected, size received: %d\n",
+				__func__, size);
 		store_audproc_cal(RX_CAL, (struct cal_block *)data);
 		break;
 	case AUDIO_SET_AUDPROC_TX_STREAM_CAL:
 		if (size > sizeof(struct cal_block))
-			pr_err("%s: More Audproc Cal then expected, "
-				"size received: %d\n", __func__, size);
+			pr_err("%s: More Audproc Cal then expected, size received: %d\n",
+				__func__, size);
 		store_audstrm_cal(TX_CAL, (struct cal_block *)data);
 		break;
 	case AUDIO_SET_AUDPROC_RX_STREAM_CAL:
 		if (size > sizeof(struct cal_block))
-			pr_err("%s: More Audproc Cal then expected, "
-				"size received: %d\n", __func__, size);
+			pr_err("%s: More Audproc Cal then expected, size received: %d\n",
+				__func__, size);
 		store_audstrm_cal(RX_CAL, (struct cal_block *)data);
 		break;
 	case AUDIO_SET_AUDPROC_TX_VOL_CAL:
 		if (size > sizeof(struct cal_block))
-			pr_err("%s: More Audproc Cal then expected, "
-				"size received: %d\n", __func__, size);
+			pr_err("%s: More Audproc Cal then expected, size received: %d\n",
+				__func__, size);
 		store_audvol_cal(TX_CAL, (struct cal_block *)data);
 		break;
 	case AUDIO_SET_AUDPROC_RX_VOL_CAL:
 		if (size > sizeof(struct cal_block))
-			pr_err("%s: More Audproc Cal then expected, "
-				"size received: %d\n", __func__, size);
+			pr_err("%s: More Audproc Cal then expected, size received: %d\n",
+				__func__, size);
 		store_audvol_cal(RX_CAL, (struct cal_block *)data);
 		break;
 	case AUDIO_SET_AFE_TX_CAL:
 		if (size > sizeof(struct cal_block))
-			pr_err("%s: More AFE Cal then expected, "
-				"size received: %d\n", __func__, size);
+			pr_err("%s: More AFE Cal then expected, size received: %d\n",
+				__func__, size);
 		store_afe_cal(TX_CAL, (struct cal_block *)data);
 		break;
 	case AUDIO_SET_AFE_RX_CAL:
 		if (size > sizeof(struct cal_block))
-			pr_err("%s: More AFE Cal then expected, "
-				"size received: %d\n", __func__, size);
+			pr_err("%s: More AFE Cal then expected, size received: %d\n",
+				__func__, size);
 		store_afe_cal(RX_CAL, (struct cal_block *)data);
 		break;
 	case AUDIO_SET_VOCPROC_CAL:
@@ -992,14 +867,10 @@
 		store_vocvol_cal(size / sizeof(struct cal_block),
 						(struct cal_block *)data);
 		break;
-	case AUDIO_SET_VOCPROC_DEV_CFG_CAL:
-		store_vocproc_dev_cfg_cal(size / sizeof(struct cal_block),
-						(struct cal_block *)data);
-		break;
 	case AUDIO_SET_SIDETONE_CAL:
 		if (size > sizeof(struct sidetone_cal))
-			pr_err("%s: More sidetone cal then expected, "
-				"size received: %d\n", __func__, size);
+			pr_err("%s: More sidetone cal then expected, size received: %d\n",
+			       __func__, size);
 		store_sidetone_cal((struct sidetone_cal *)data);
 		break;
 	case AUDIO_SET_ANC_CAL:
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_amrnb.c b/arch/arm/mach-msm/qdsp6v2/audio_amrnb.c
index f4316d0..056a161 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_amrnb.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_amrnb.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_amrwb.c b/arch/arm/mach-msm/qdsp6v2/audio_amrwb.c
index 28c1732..54ca4e8 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_amrwb.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_amrwb.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_dev_ctl.c b/arch/arm/mach-msm/qdsp6v2/audio_dev_ctl.c
index aaae776..8aacb56 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_dev_ctl.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_dev_ctl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_evrc.c b/arch/arm/mach-msm/qdsp6v2/audio_evrc.c
index ec5162d..261642c 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_evrc.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_evrc.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_lpa.c b/arch/arm/mach-msm/qdsp6v2/audio_lpa.c
index edf8f77..f6dd9fab 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_lpa.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_lpa.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -744,8 +744,8 @@
 
 		pr_debug("%s: AUDIO_GET_STATS cmd\n", __func__);
 		memset(&stats, 0, sizeof(stats));
-		timestamp = q6asm_get_session_time(audio->ac);
-		if (timestamp < 0) {
+		rc = q6asm_get_session_time(audio->ac, &timestamp);
+		if (rc < 0) {
 			pr_err("%s: Get Session Time return value =%lld\n",
 				__func__, timestamp);
 			return -EAGAIN;
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_lpa.h b/arch/arm/mach-msm/qdsp6v2/audio_lpa.h
index 93588b3..c305967 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_lpa.h
+++ b/arch/arm/mach-msm/qdsp6v2/audio_lpa.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_mp3.c b/arch/arm/mach-msm/qdsp6v2/audio_mp3.c
index 93a8739..ebcca3c 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_mp3.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_mp3.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -47,6 +47,11 @@
 		audio->eos_rsp = 0;
 		audio->eos_flag = 0;
 		if (!rc) {
+			rc = enable_volume_ramp(audio);
+			if (rc < 0) {
+				pr_err("%s: Failed to enable volume ramp\n",
+					__func__);
+			}
 			audio->enabled = 1;
 		} else {
 			audio->enabled = 0;
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_multi_aac.c b/arch/arm/mach-msm/qdsp6v2/audio_multi_aac.c
index b53edd9..8153145 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_multi_aac.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_multi_aac.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -147,10 +147,8 @@
 		} else {
 			uint16_t sce_left = 1, sce_right = 2;
 			aac_config = audio->codec_cfg;
-			if ((aac_config->dual_mono_mode <
-				AUDIO_AAC_DUAL_MONO_PL_PR) ||
-				(aac_config->dual_mono_mode >
-				AUDIO_AAC_DUAL_MONO_PL_SR)) {
+			if (aac_config->dual_mono_mode >
+			    AUDIO_AAC_DUAL_MONO_PL_SR) {
 				pr_err("%s:AUDIO_SET_AAC_CONFIG: Invalid dual_mono mode =%d\n",
 					 __func__, aac_config->dual_mono_mode);
 			} else {
@@ -187,6 +185,25 @@
 		}
 		break;
 	}
+	case AUDIO_SET_AAC_MIX_CONFIG:	{
+		pr_debug("%s, AUDIO_SET_AAC_MIX_CONFIG", __func__);
+		if (copy_from_user(audio->codec_cfg, (void *)arg,
+			sizeof(unsigned long))) {
+			rc = -EFAULT;
+			break;
+		} else {
+			unsigned long *mix_coeff =
+					(unsigned long *)audio->codec_cfg;
+			pr_debug("%s, value of coeff = %lu",
+						__func__, *mix_coeff);
+			q6asm_cfg_aac_sel_mix_coef(audio->ac, *mix_coeff);
+			if (rc < 0)
+				pr_err("%s asm aac_sel_mix_coef failed rc=%d\n",
+								 __func__, rc);
+			break;
+		}
+		break;
+	}
 	default:
 		pr_debug("Calling utils ioctl\n");
 		rc = audio->codec_ioctl(file, cmd, arg);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_mvs.c b/arch/arm/mach-msm/qdsp6v2/audio_mvs.c
index d748304..f64e5ea 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_mvs.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_mvs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_qcelp.c b/arch/arm/mach-msm/qdsp6v2/audio_qcelp.c
index 37f6e6b..69a9fcb 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_qcelp.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_qcelp.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils.c b/arch/arm/mach-msm/qdsp6v2/audio_utils.c
index 6a23e37..33bbac0 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -19,7 +19,7 @@
 #include <linux/wait.h>
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
 #include <asm/ioctls.h>
 #include "audio_utils.h"
 
@@ -109,8 +109,8 @@
 
 		rc = q6asm_cmd(audio->ac, CMD_CLOSE);
 		if (rc < 0)
-			pr_err("%s:session id %d: Failed to close the"
-				"session rc=%d\n", __func__, audio->ac->session,
+			pr_err("%s:session id %d: Failed to close the session rc=%d\n",
+				__func__, audio->ac->session,
 				rc);
 		audio->stopped = 1;
 		memset(audio->out_frame_info, 0,
@@ -135,8 +135,8 @@
 				ALIGN_BUF_SIZE(audio->pcm_cfg.buffer_size),
 				audio->pcm_cfg.buffer_count);
 			if (rc < 0) {
-				pr_err("%s:session id %d: Buffer Alloc"
-						"failed\n", __func__,
+				pr_err("%s:session id %d: Buffer Alloc failed\n",
+						__func__,
 						audio->ac->session);
 				rc = -ENOMEM;
 				break;
@@ -172,8 +172,8 @@
 				ALIGN_BUF_SIZE(audio->pcm_cfg.buffer_size),
 				audio->pcm_cfg.buffer_count);
 			if (rc < 0) {
-				pr_err("%s:session id %d: Buffer Alloc"
-					"failed\n", __func__,
+				pr_err("%s:session id %d: Buffer Alloc failed\n",
+					__func__,
 					audio->ac->session);
 				rc = -ENOMEM;
 				break;
@@ -303,15 +303,15 @@
 		}
 		audio->buf_cfg.meta_info_enable = cfg.meta_info_enable;
 		audio->buf_cfg.frames_per_buf = cfg.frames_per_buf;
-		pr_debug("%s:session id %d: Set-buf-cfg: meta[%d]"
-				"framesperbuf[%d]\n", __func__,
+		pr_debug("%s:session id %d: Set-buf-cfg: meta[%d] framesperbuf[%d]\n",
+				__func__,
 				audio->ac->session, cfg.meta_info_enable,
 				cfg.frames_per_buf);
 		break;
 	}
 	case AUDIO_GET_BUF_CFG: {
-		pr_debug("%s:session id %d: Get-buf-cfg: meta[%d]"
-			"framesperbuf[%d]\n", __func__,
+		pr_debug("%s:session id %d: Get-buf-cfg: meta[%d] framesperbuf[%d]\n",
+			__func__,
 			audio->ac->session, audio->buf_cfg.meta_info_enable,
 			audio->buf_cfg.frames_per_buf);
 
@@ -334,8 +334,8 @@
 			break;
 		}
 		if (audio->feedback != NON_TUNNEL_MODE) {
-			pr_err("%s:session id %d: Not sufficient permission to"
-					"change the record mode\n", __func__,
+			pr_err("%s:session id %d: Not sufficient permission to change the record mode\n",
+					__func__,
 					audio->ac->session);
 			rc = -EACCES;
 			break;
@@ -399,15 +399,22 @@
 			audio->read_wait,
 			((atomic_read(&audio->out_count) > 0) ||
 			(audio->stopped) ||
-			 audio->rflush || audio->eos_rsp));
+			 audio->rflush || audio->eos_rsp ||
+			audio->event_abort));
+
+		if (audio->event_abort) {
+			rc = -EIO;
+			break;
+		}
+
 
 		if (rc < 0)
 			break;
 
 		if ((audio->stopped && !(atomic_read(&audio->out_count))) ||
 			audio->rflush) {
-			pr_debug("%s:session id %d: driver in stop state or"
-				"flush,No more buf to read", __func__,
+			pr_debug("%s:session id %d: driver in stop state or flush,No more buf to read",
+				__func__,
 				audio->ac->session);
 			rc = 0;/* End of File */
 			break;
@@ -473,8 +480,8 @@
 			count -= bytes_to_copy;
 			buf += bytes_to_copy;
 		} else {
-			pr_err("%s:session id %d: short read data[%p]"
-				"bytesavail[%d]bytesrequest[%d]\n", __func__,
+			pr_err("%s:session id %d: short read data[%p] bytesavail[%d]bytesrequest[%d]\n",
+				__func__,
 				audio->ac->session,
 				data, size, count);
 		}
@@ -529,7 +536,13 @@
 		rc = wait_event_interruptible(audio->write_wait,
 				     ((atomic_read(&audio->in_count) > 0) ||
 				      (audio->stopped) ||
-				      (audio->wflush)));
+				      (audio->wflush) || (audio->event_abort)));
+
+		if (audio->event_abort) {
+			rc = -EIO;
+			break;
+		}
+
 		if (rc < 0)
 			break;
 		if (audio->stopped || audio->wflush) {
@@ -554,8 +567,8 @@
 						&nflags);
 			buf += mfield_size;
 			/* send the EOS and return */
-			pr_debug("%s:session id %d: send EOS"
-				"0x%8x\n", __func__,
+			pr_debug("%s:session id %d: send EOS 0x%8x\n",
+				__func__,
 				audio->ac->session, nflags);
 			break;
 		}
@@ -582,8 +595,8 @@
 				buf += mfield_size;
 				count -= mfield_size;
 			} else {
-				pr_debug("%s:session id %d: continuous"
-				"buffer\n", __func__, audio->ac->session);
+				pr_debug("%s:session id %d: continuous buffer\n",
+						__func__, audio->ac->session);
 			}
 		}
 		xfer = (count > (audio->pcm_cfg.buffer_size)) ?
@@ -603,8 +616,8 @@
 		buf += xfer;
 	}
 	mutex_unlock(&audio->write_lock);
-	pr_debug("%s:session id %d: eos_condition 0x%8x buf[0x%x]"
-			"start[0x%x]\n", __func__, audio->ac->session,
+	pr_debug("%s:session id %d: eos_condition 0x%8x buf[0x%x] start[0x%x]\n",
+				__func__, audio->ac->session,
 				nflags,	(int) buf, (int) start);
 	if (nflags & AUD_EOS_SET) {
 		rc = q6asm_cmd(audio->ac, CMD_EOS);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils.h b/arch/arm/mach-msm/qdsp6v2/audio_utils.h
index df963f9..7209724 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils.h
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -30,13 +30,13 @@
 struct timestamp {
 	unsigned long lowpart;
 	unsigned long highpart;
-} __attribute__ ((packed));
+} __packed;
 
 struct meta_in {
 	unsigned short offset;
 	struct timestamp ntimestamp;
 	unsigned int nflags;
-} __attribute__ ((packed));
+} __packed;
 
 struct meta_out_dsp {
 	u32 offset_to_frame;
@@ -45,12 +45,12 @@
 	u32 msw_ts;
 	u32 lsw_ts;
 	u32 nflags;
-} __attribute__ ((packed));
+} __packed;
 
 struct meta_out {
 	unsigned char num_of_frames;
 	struct meta_out_dsp meta_out_dsp[];
-} __attribute__ ((packed));
+} __packed;
 
 struct q6audio_in {
 	spinlock_t			dsp_lock;
@@ -80,6 +80,7 @@
 	int				opened;
 	int				enabled;
 	int				stopped;
+	int				event_abort;
 	int				feedback; /* Flag indicates whether used
 							in Non Tunnel mode */
 	int				rflush;
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
index ad5f1b5..e6b9549 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
@@ -1,6 +1,6 @@
 /* Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -477,6 +477,57 @@
 {
 	auddev_unregister_evt_listner(AUDDEV_CLNT_DEC, audio->ac->session);
 }
+
+int enable_volume_ramp(struct q6audio_aio *audio)
+{
+	int rc = 0;
+	struct asm_softpause_params softpause;
+	struct asm_softvolume_params softvol;
+
+	if (audio->ac == NULL)
+		return -EINVAL;
+	pr_debug("%s[%p]\n", __func__, audio);
+	softpause.enable = SOFT_PAUSE_ENABLE;
+	softpause.period = SOFT_PAUSE_PERIOD;
+	softpause.step = SOFT_PAUSE_STEP;
+	softpause.rampingcurve = SOFT_PAUSE_CURVE_LINEAR;
+
+	softvol.period = SOFT_VOLUME_PERIOD;
+	softvol.step = SOFT_VOLUME_STEP;
+	softvol.rampingcurve = SOFT_VOLUME_CURVE_LINEAR;
+
+	if (softpause.rampingcurve == SOFT_PAUSE_CURVE_LINEAR)
+		softpause.step = SOFT_PAUSE_STEP_LINEAR;
+	if (softvol.rampingcurve == SOFT_VOLUME_CURVE_LINEAR)
+		softvol.step = SOFT_VOLUME_STEP_LINEAR;
+	rc = q6asm_set_volume(audio->ac, audio->volume);
+	if (rc < 0) {
+		pr_err("%s: Send Volume command failed rc=%d\n",
+			__func__, rc);
+		return rc;
+	}
+	rc = q6asm_set_softpause(audio->ac, &softpause);
+	if (rc < 0) {
+		pr_err("%s: Send SoftPause Param failed rc=%d\n",
+			__func__, rc);
+		return rc;
+	}
+	rc = q6asm_set_softvolume(audio->ac, &softvol);
+	if (rc < 0) {
+		pr_err("%s: Send SoftVolume Param failed rc=%d\n",
+		__func__, rc);
+		return rc;
+	}
+	/* disable mute by default */
+	rc = q6asm_set_mute(audio->ac, 0);
+	if (rc < 0) {
+		pr_err("%s: Send mute command failed rc=%d\n",
+			__func__, rc);
+		return rc;
+	}
+	return rc;
+}
+
 #else /*CONFIG_USE_DEV_CTRL_VOLUME*/
 int register_volume_listener(struct q6audio_aio *audio)
 {
@@ -486,6 +537,10 @@
 {
 	return;/* do nothing */
 }
+int enable_volume_ramp(struct q6audio_aio *audio)
+{
+	return 0; /* do nothing */
+}
 #endif /*CONFIG_USE_DEV_CTRL_VOLUME*/
 
 int audio_aio_release(struct inode *inode, struct file *file)
@@ -777,11 +832,12 @@
 				1);
 	if (rc < 0) {
 		pr_err("%s[%p]: memory map failed\n", __func__, audio);
-		goto ion_error;
+		goto mmap_error;
 	} else {
 		goto end;
 	}
-
+mmap_error:
+	list_del(&region->list);
 ion_error:
 	ion_unmap_kernel(audio->client, handle);
 map_error:
@@ -841,6 +897,11 @@
 	struct audio_client *ac;
 	struct audio_aio_write_param param;
 
+	if (!audio || !buf_node) {
+		pr_err("%s NULL pointer audio=[0x%p], buf_node=[0x%p]\n",
+			__func__, audio, buf_node);
+		return;
+	}
 	pr_debug("%s[%p]: Send write buff %p phy %lx len %d meta_enable = %d\n",
 		__func__, audio, buf_node, buf_node->paddr,
 		buf_node->buf.data_len,
@@ -861,14 +922,12 @@
 	}
 	param.msw_ts = buf_node->meta_info.meta_in.ntimestamp.highpart;
 	param.lsw_ts = buf_node->meta_info.meta_in.ntimestamp.lowpart;
+	param.flags  = buf_node->meta_info.meta_in.nflags;
 	/* If no meta_info enaled, indicate no time stamp valid */
-	if (audio->buf_cfg.meta_info_enable)
-		param.flags = 0;
-	else
+	if (!audio->buf_cfg.meta_info_enable)
 		param.flags = 0xFF00;
 
-	if ((buf_node != NULL) &&
-		(buf_node->meta_info.meta_in.nflags & AUDIO_DEC_EOF_SET))
+	if (buf_node->meta_info.meta_in.nflags & AUDIO_DEC_EOF_SET)
 		param.flags |= AUDIO_DEC_EOF_SET;
 
 	param.uid = param.paddr;
@@ -1031,7 +1090,7 @@
 	return 0;
 }
 
-static void audio_aio_ioport_reset(struct q6audio_aio *audio)
+void audio_aio_ioport_reset(struct q6audio_aio *audio)
 {
 	if (audio->drv_status & ADRV_STATUS_AIO_INTF) {
 		/* If fsync is in progress, make sure
@@ -1140,8 +1199,8 @@
 		uint64_t timestamp;
 		stats.byte_count = atomic_read(&audio->in_bytes);
 		stats.sample_count = atomic_read(&audio->in_samples);
-		timestamp = q6asm_get_session_time(audio->ac);
-		if (timestamp >= 0)
+		rc = q6asm_get_session_time(audio->ac, &timestamp);
+		if (rc >= 0)
 			memcpy(&stats.unused[0], &timestamp, sizeof(timestamp));
 		else
 			pr_debug("Error while getting timestamp\n");
@@ -1205,15 +1264,15 @@
 				audio, audio->ac->session);
 		mutex_lock(&audio->lock);
 		audio->stopped = 1;
-		audio_aio_flush(audio);
-		audio->enabled = 0;
-		audio->drv_status &= ~ADRV_STATUS_PAUSE;
+		rc = audio_aio_flush(audio);
 		if (rc < 0) {
 			pr_err("%s[%p]:Audio Stop procedure failed rc=%d\n",
 				__func__, audio, rc);
 			mutex_unlock(&audio->lock);
 			break;
 		}
+		audio->enabled = 0;
+		audio->drv_status &= ~ADRV_STATUS_PAUSE;
 		if (audio->drv_status & ADRV_STATUS_FSYNC) {
 			pr_debug("%s[%p] Waking up the audio_aio_fsync\n",
 					__func__, audio);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.h b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.h
index d518254..0efcd64 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.h
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.h
@@ -1,6 +1,6 @@
 /* Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -212,6 +212,8 @@
 int audio_aio_fsync(struct file *file, loff_t start, loff_t end, int datasync);
 void audio_aio_async_out_flush(struct q6audio_aio *audio);
 void audio_aio_async_in_flush(struct q6audio_aio *audio);
+void audio_aio_ioport_reset(struct q6audio_aio *audio);
+int enable_volume_ramp(struct q6audio_aio *audio);
 #ifdef CONFIG_DEBUG_FS
 ssize_t audio_aio_debug_open(struct inode *inode, struct file *file);
 ssize_t audio_aio_debug_read(struct file *file, char __user *buf,
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_wma.c b/arch/arm/mach-msm/qdsp6v2/audio_wma.c
index 021d58b..1d1da1a 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_wma.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_wma.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_wmapro.c b/arch/arm/mach-msm/qdsp6v2/audio_wmapro.c
index 4fcdcc1..2b2d772 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_wmapro.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_wmapro.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6v2/board-msm8x60-audio.c b/arch/arm/mach-msm/qdsp6v2/board-msm8x60-audio.c
index 0181cb5..0f35d1d 100644
--- a/arch/arm/mach-msm/qdsp6v2/board-msm8x60-audio.c
+++ b/arch/arm/mach-msm/qdsp6v2/board-msm8x60-audio.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp6v2/dsp_debug.c b/arch/arm/mach-msm/qdsp6v2/dsp_debug.c
index 3635fbd..26c8f75 100644
--- a/arch/arm/mach-msm/qdsp6v2/dsp_debug.c
+++ b/arch/arm/mach-msm/qdsp6v2/dsp_debug.c
@@ -38,12 +38,14 @@
 
 void q6audio_dsp_not_responding(void)
 {
+	int i;
+
 	if (cb_ptr)
 		cb_ptr(DSP_STATE_CRASHED);
 	if (atomic_add_return(1, &dsp_crash_count) != 1) {
 		pr_err("q6audio_dsp_not_responding() \
 			- parking additional crasher...\n");
-		for (;;)
+		for (i = 0; i < 600; i++)
 			msleep(1000);
 	}
 	if (dsp_wait_count) {
diff --git a/arch/arm/mach-msm/qdsp6v2/evrc_in.c b/arch/arm/mach-msm/qdsp6v2/evrc_in.c
index b95d659..a785266 100644
--- a/arch/arm/mach-msm/qdsp6v2/evrc_in.c
+++ b/arch/arm/mach-msm/qdsp6v2/evrc_in.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -20,7 +20,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 #include <linux/msm_audio_qcp.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
 #include <asm/ioctls.h>
 #include "audio_utils.h"
 
@@ -64,8 +64,8 @@
 			enc_cfg->max_bit_rate, 0);
 
 		if (rc < 0) {
-			pr_err("%s:session id %d: cmd evrc media format block"
-				"failed\n", __func__, audio->ac->session);
+			pr_err("%s:session id %d: cmd evrc media format block failed\n",
+					__func__, audio->ac->session);
 			break;
 		}
 		if (audio->feedback == NON_TUNNEL_MODE) {
@@ -74,8 +74,8 @@
 				audio->pcm_cfg.channel_count);
 
 			if (rc < 0) {
-				pr_err("%s:session id %d: media format block"
-				"failed\n", __func__, audio->ac->session);
+				pr_err("%s:session id %d: media format block failed\n",
+					__func__, audio->ac->session);
 				break;
 			}
 		}
@@ -86,8 +86,8 @@
 			audio->enabled = 1;
 		} else {
 			audio->enabled = 0;
-			pr_err("%s:session id %d: Audio Start procedure failed"
-				"rc=%d\n", __func__, audio->ac->session, rc);
+			pr_err("%s:session id %d: Audio Start procedure failed rc=%d\n",
+					__func__, audio->ac->session, rc);
 			break;
 		}
 		while (cnt++ < audio->str_cfg.buffer_count)
@@ -102,8 +102,8 @@
 				audio->ac->session);
 		rc = audio_in_disable(audio);
 		if (rc  < 0) {
-			pr_err("%s:session id %d: Audio Stop procedure failed"
-				"rc=%d\n", __func__, audio->ac->session, rc);
+			pr_err("%s:session id %d: Audio Stop procedure failed rc=%d\n",
+				__func__, audio->ac->session, rc);
 			break;
 		}
 		break;
@@ -143,8 +143,8 @@
 		}
 		enc_cfg->min_bit_rate = cfg.min_bit_rate;
 		enc_cfg->max_bit_rate = cfg.max_bit_rate;
-		pr_debug("%s:session id %d: min_bit_rate= 0x%x"
-			"max_bit_rate=0x%x\n", __func__,
+		pr_debug("%s:session id %d: min_bit_rate= 0x%x max_bit_rate=0x%x\n",
+			__func__,
 			audio->ac->session, enc_cfg->min_bit_rate,
 			enc_cfg->max_bit_rate);
 		break;
@@ -164,16 +164,16 @@
 	audio = kzalloc(sizeof(struct q6audio_in), GFP_KERNEL);
 
 	if (audio == NULL) {
-		pr_err("%s: Could not allocate memory for evrc"
-				"driver\n", __func__);
+		pr_err("%s: Could not allocate memory for evrc driver\n",
+				__func__);
 		return -ENOMEM;
 	}
 	/* Allocate memory for encoder config param */
 	audio->enc_cfg = kzalloc(sizeof(struct msm_audio_evrc_enc_config),
 				GFP_KERNEL);
 	if (audio->enc_cfg == NULL) {
-		pr_err("%s:session id %d: Could not allocate memory for aac"
-				"config param\n", __func__, audio->ac->session);
+		pr_err("%s:session id %d: Could not allocate memory for aac config param\n",
+				__func__, audio->ac->session);
 		kfree(audio);
 		return -ENOMEM;
 	}
@@ -200,13 +200,14 @@
 	audio->pcm_cfg.sample_rate = 8000;
 	audio->buf_cfg.meta_info_enable = 0x01;
 	audio->buf_cfg.frames_per_buf = 0x01;
+	audio->event_abort = 0;
 
 	audio->ac = q6asm_audio_client_alloc((app_cb)q6asm_in_cb,
 				(void *)audio);
 
 	if (!audio->ac) {
-		pr_err("%s: Could not allocate memory for audio"
-				"client\n", __func__);
+		pr_err("%s: Could not allocate memory for audio client\n",
+				__func__);
 		kfree(audio->enc_cfg);
 		kfree(audio);
 		return -ENOMEM;
@@ -239,8 +240,8 @@
 		/* register for tx overflow (valid for tunnel mode only) */
 		rc = q6asm_reg_tx_overflow(audio->ac, 0x01);
 		if (rc < 0) {
-			pr_err("%s:session id %d: TX Overflow registration"
-				"failed rc=%d\n", __func__,
+			pr_err("%s:session id %d: TX Overflow registration failed rc=%d\n",
+				__func__,
 				audio->ac->session, rc);
 			rc = -ENODEV;
 			goto fail;
diff --git a/arch/arm/mach-msm/qdsp6v2/fm.c b/arch/arm/mach-msm/qdsp6v2/fm.c
index 9cf2723..3d72b97 100644
--- a/arch/arm/mach-msm/qdsp6v2/fm.c
+++ b/arch/arm/mach-msm/qdsp6v2/fm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
  *
  * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5v2/audio_mp3.c
  *
diff --git a/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c b/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c
index 63b3064..c6def46 100644
--- a/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c
+++ b/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp6v2/pcm_in.c b/arch/arm/mach-msm/qdsp6v2/pcm_in.c
index 620c1ee..0db4894 100644
--- a/arch/arm/mach-msm/qdsp6v2/pcm_in.c
+++ b/arch/arm/mach-msm/qdsp6v2/pcm_in.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6v2/pcm_out.c b/arch/arm/mach-msm/qdsp6v2/pcm_out.c
index 733d5e3..4097b72 100644
--- a/arch/arm/mach-msm/qdsp6v2/pcm_out.c
+++ b/arch/arm/mach-msm/qdsp6v2/pcm_out.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2009 Google, Inc.
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/qdsp6v2/q6audio_common.h b/arch/arm/mach-msm/qdsp6v2/q6audio_common.h
index 3bc8454..06369c2 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6audio_common.h
+++ b/arch/arm/mach-msm/qdsp6v2/q6audio_common.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -11,11 +11,14 @@
  *
 */
 
+
 /* For Decoders */
 #ifndef __Q6_AUDIO_COMMON_H__
 #define __Q6_AUDIO_COMMON_H__
 
-#if defined(CONFIG_ARCH_MSM8974) || defined(CONFIG_ARCH_MSM9625)
+#if defined(CONFIG_ARCH_MSM8974) || defined(CONFIG_ARCH_MSM9625) \
+	|| defined(CONFIG_ARCH_MSM8226) || defined(CONFIG_ARCH_MSM8610)
+
 #include <sound/apr_audio-v2.h>
 #include <sound/q6asm-v2.h>
 #else
diff --git a/arch/arm/mach-msm/qdsp6v2/q6audio_v1.c b/arch/arm/mach-msm/qdsp6v2/q6audio_v1.c
index f49d6e0..c36d5a9 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6audio_v1.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6audio_v1.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/qdsp6v2/q6audio_v1_aio.c b/arch/arm/mach-msm/qdsp6v2/q6audio_v1_aio.c
index 96f823f..ffd14bd 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6audio_v1_aio.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6audio_v1_aio.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Code Aurora Forum. 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
@@ -39,6 +39,9 @@
 	case ASM_DATA_EVENT_ENC_SR_CM_NOTIFY:
 		audio_aio_cb(opcode, token, payload, audio);
 		break;
+	case APR_BASIC_RSP_RESULT:
+		audio_aio_cb(opcode, token, payload, audio);
+		break;
 	default:
 		pr_debug("%s:Unhandled event = 0x%8x\n", __func__, opcode);
 		break;
@@ -106,6 +109,26 @@
 		e_payload.stream_info.sample_rate = audio->pcm_cfg.sample_rate;
 		audio_aio_post_event(audio, AUDIO_EVENT_STREAM_INFO, e_payload);
 		break;
+	case APR_BASIC_RSP_RESULT:
+		switch (payload[0]) {
+		case ASM_STREAM_CMD_FLUSH:
+			if (payload[1] == ADSP_EOK) {
+				pr_debug("%s: FLUSH CMD success\n", __func__);
+				audio_aio_ioport_reset(audio);
+				audio->wflush = 0;
+				audio->rflush = 0;
+			} else {
+				pr_err("%s: FLUSH CMD failed with status:%d\n",
+					__func__, payload[1]);
+				audio_aio_ioport_reset(audio);
+				audio->wflush = 0;
+				audio->rflush = 0;
+			}
+			break;
+		default:
+			pr_debug("%s: cmd%x cmd_status:%d\n",
+				__func__, payload[0], payload[1]);
+		}
 	default:
 		break;
 	}
diff --git a/arch/arm/mach-msm/qdsp6v2/q6audio_v2.c b/arch/arm/mach-msm/qdsp6v2/q6audio_v2.c
index 0db1ef4..7786fc0 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6audio_v2.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6audio_v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -19,7 +19,7 @@
 #include <linux/wait.h>
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
 #include <asm/ioctls.h>
 #include "audio_utils.h"
 
@@ -51,6 +51,14 @@
 		pr_err("%s:session id %d: ASM_SESSION_EVENT_TX_OVERFLOW\n",
 			__func__, audio->ac->session);
 		break;
+	case RESET_EVENTS:
+		pr_debug("%s:received RESET EVENTS\n", __func__);
+		audio->enabled = 0;
+		audio->stopped = 1;
+		audio->event_abort = 1;
+		wake_up(&audio->read_wait);
+		wake_up(&audio->write_wait);
+		break;
 	default:
 		pr_debug("%s:session id %d: Ignore opcode[0x%x]\n", __func__,
 			audio->ac->session, opcode);
diff --git a/arch/arm/mach-msm/qdsp6v2/q6audio_v2_aio.c b/arch/arm/mach-msm/qdsp6v2/q6audio_v2_aio.c
index 10adc26..4610b97 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6audio_v2_aio.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6audio_v2_aio.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -37,6 +37,7 @@
 	case ASM_STREAM_CMD_SET_ENCDEC_PARAM:
 	case ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY:
 	case ASM_DATA_EVENT_ENC_SR_CM_CHANGE_NOTIFY:
+	case RESET_EVENTS:
 		audio_aio_cb(opcode, token, payload, audio);
 		break;
 	default:
@@ -105,6 +106,13 @@
 		e_payload.stream_info.sample_rate = audio->pcm_cfg.sample_rate;
 		audio_aio_post_event(audio, AUDIO_EVENT_STREAM_INFO, e_payload);
 		break;
+	case RESET_EVENTS:
+		pr_debug("%s: Received opcode:0x%x\n", __func__, opcode);
+		audio->event_abort = 1;
+		audio->stopped = 1;
+		audio->enabled = 0;
+		wake_up(&audio->event_wait);
+		break;
 	default:
 		break;
 	}
diff --git a/arch/arm/mach-msm/qdsp6v2/q6core.c b/arch/arm/mach-msm/qdsp6v2/q6core.c
index 9dd66e1..f23ba67 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6core.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
@@ -253,8 +253,6 @@
 	int len;
 	static int t_len;
 
-	if (count < 0)
-		return 0;
 	len = count > 63 ? 63 : count;
 	if (copy_from_user(l_buf + 20 , buf, len)) {
 		pr_info("Unable to copy data from user space\n");
diff --git a/arch/arm/mach-msm/qdsp6v2/q6voice.c b/arch/arm/mach-msm/qdsp6v2/q6voice.c
index 7464ed7..b0eeb52 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6voice.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6voice.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp6v2/qcelp_in.c b/arch/arm/mach-msm/qdsp6v2/qcelp_in.c
index a48df39..3a5411e 100644
--- a/arch/arm/mach-msm/qdsp6v2/qcelp_in.c
+++ b/arch/arm/mach-msm/qdsp6v2/qcelp_in.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -20,7 +20,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 #include <linux/msm_audio_qcp.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
 #include <asm/ioctls.h>
 #include "audio_utils.h"
 
@@ -64,8 +64,8 @@
 			enc_cfg->max_bit_rate, 0, 0);
 
 		if (rc < 0) {
-			pr_err("%s:session id %d: cmd qcelp media format block"
-				"failed\n", __func__, audio->ac->session);
+			pr_err("%s:session id %d: cmd qcelp media format block failed\n",
+					__func__, audio->ac->session);
 			break;
 		}
 		if (audio->feedback == NON_TUNNEL_MODE) {
@@ -74,8 +74,8 @@
 				audio->pcm_cfg.channel_count);
 
 			if (rc < 0) {
-				pr_err("%s:session id %d: media format block"
-				"failed\n", __func__, audio->ac->session);
+				pr_err("%s:session id %d: media format block failed\n",
+					__func__, audio->ac->session);
 				break;
 			}
 		}
@@ -86,8 +86,8 @@
 			audio->enabled = 1;
 		} else {
 			audio->enabled = 0;
-			pr_err("%s:session id %d: Audio Start procedure failed"
-				"rc=%d\n", __func__, audio->ac->session, rc);
+			pr_err("%s:session id %d: Audio Start procedure failed rc=%d\n",
+					__func__, audio->ac->session, rc);
 			break;
 		}
 		while (cnt++ < audio->str_cfg.buffer_count)
@@ -102,8 +102,8 @@
 				audio->ac->session);
 		rc = audio_in_disable(audio);
 		if (rc  < 0) {
-			pr_err("%s:session id %d: Audio Stop procedure failed"
-					"rc=%d\n", __func__, audio->ac->session,
+			pr_err("%s:session id %d: Audio Stop procedure failed rc=%d\n",
+				__func__, audio->ac->session,
 					rc);
 			break;
 		}
@@ -141,8 +141,8 @@
 		}
 		enc_cfg->min_bit_rate = cfg.min_bit_rate;
 		enc_cfg->max_bit_rate = cfg.max_bit_rate;
-		pr_debug("%s:session id %d: min_bit_rate= 0x%x"
-			"max_bit_rate=0x%x\n", __func__,
+		pr_debug("%s:session id %d: min_bit_rate= 0x%x max_bit_rate=0x%x\n",
+			__func__,
 			audio->ac->session, enc_cfg->min_bit_rate,
 			enc_cfg->max_bit_rate);
 		break;
@@ -162,16 +162,16 @@
 	audio = kzalloc(sizeof(struct q6audio_in), GFP_KERNEL);
 
 	if (audio == NULL) {
-		pr_err("%s: Could not allocate memory for qcelp"
-				"driver\n", __func__);
+		pr_err("%s: Could not allocate memory for qcelp driver\n",
+				__func__);
 		return -ENOMEM;
 	}
 	/* Allocate memory for encoder config param */
 	audio->enc_cfg = kzalloc(sizeof(struct msm_audio_qcelp_enc_config),
 				GFP_KERNEL);
 	if (audio->enc_cfg == NULL) {
-		pr_err("%s:session id %d: Could not allocate memory for aac"
-				"config param\n", __func__, audio->ac->session);
+		pr_err("%s:session id %d: Could not allocate memory for aac config param\n",
+				__func__, audio->ac->session);
 		kfree(audio);
 		return -ENOMEM;
 	}
@@ -199,13 +199,14 @@
 	audio->pcm_cfg.sample_rate = 8000;
 	audio->buf_cfg.meta_info_enable = 0x01;
 	audio->buf_cfg.frames_per_buf = 0x01;
+	audio->event_abort = 0;
 
 	audio->ac = q6asm_audio_client_alloc((app_cb)q6asm_in_cb,
 				(void *)audio);
 
 	if (!audio->ac) {
-		pr_err("%s: Could not allocate memory for audio"
-				"client\n", __func__);
+		pr_err("%s: Could not allocate memory for audio client\n",
+				__func__);
 		kfree(audio->enc_cfg);
 		kfree(audio);
 		return -ENOMEM;
@@ -238,8 +239,8 @@
 		/* register for tx overflow (valid for tunnel mode only) */
 		rc = q6asm_reg_tx_overflow(audio->ac, 0x01);
 		if (rc < 0) {
-			pr_err("%s:session id %d: TX Overflow registration"
-			"failed rc=%d\n", __func__, audio->ac->session, rc);
+			pr_err("%s:session id %d: TX Overflow registration failed rc=%d\n",
+				__func__, audio->ac->session, rc);
 			rc = -ENODEV;
 			goto fail;
 		}
diff --git a/arch/arm/mach-msm/qdsp6v2/rtac.c b/arch/arm/mach-msm/qdsp6v2/rtac.c
index cae0f3a..1881607 100644
--- a/arch/arm/mach-msm/qdsp6v2/rtac.c
+++ b/arch/arm/mach-msm/qdsp6v2/rtac.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp6v2/rtac_v2.c b/arch/arm/mach-msm/qdsp6v2/rtac_v2.c
deleted file mode 100644
index 409d796..0000000
--- a/arch/arm/mach-msm/qdsp6v2/rtac_v2.c
+++ /dev/null
@@ -1,1047 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/fs.h>
-#include <linux/module.h>
-#include <linux/miscdevice.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-#include <linux/mutex.h>
-#include <linux/sched.h>
-#include <linux/msm_audio_acdb.h>
-#include <asm/atomic.h>
-#include <mach/qdsp6v2/audio_acdb.h>
-#include <mach/qdsp6v2/rtac.h>
-#include "q6audio_common.h"
-#include <sound/q6afe-v2.h>
-#include <sound/apr_audio-v2.h>
-
-#ifndef CONFIG_RTAC
-
-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_popp_from_adm_devices(u32 popp_id) {}
-void rtac_set_adm_handle(void *handle) {}
-bool rtac_make_adm_callback(uint32_t *payload, u32 payload_size)
-	{return false; }
-void rtac_set_asm_handle(u32 session_id, void *handle) {}
-bool rtac_make_asm_callback(u32 session_id, uint32_t *payload,
-	u32 payload_size) {return false; }
-void rtac_add_voice(u32 cvs_handle, u32 cvp_handle, u32 rx_afe_port,
-	u32 tx_afe_port, u32 session_id) {}
-void rtac_remove_voice(u32 cvs_handle) {}
-void rtac_set_voice_handle(u32 mode, void *handle) {}
-bool rtac_make_voice_callback(u32 mode, uint32_t *payload,
-		u32 payload_size) {return false; }
-
-#else
-
-/* Max size of payload (buf size - apr header) */
-#define MAX_PAYLOAD_SIZE		4076
-#define RTAC_MAX_ACTIVE_DEVICES		4
-#define RTAC_MAX_ACTIVE_VOICE_COMBOS	2
-#define RTAC_MAX_ACTIVE_POPP		8
-#define RTAC_BUF_SIZE			4096
-
-#define TIMEOUT_MS	1000
-
-/* APR data */
-struct rtac_apr_data {
-	void			*apr_handle;
-	atomic_t		cmd_state;
-	wait_queue_head_t	cmd_wait;
-};
-
-static struct rtac_apr_data	rtac_adm_apr_data;
-static struct rtac_apr_data	rtac_asm_apr_data[SESSION_MAX+1];
-static struct rtac_apr_data	rtac_voice_apr_data[RTAC_VOICE_MODES];
-
-
-/* ADM info & APR */
-struct rtac_adm_data {
-	uint32_t	topology_id;
-	uint32_t	afe_port;
-	uint32_t	copp;
-	uint32_t	num_of_popp;
-	uint32_t	popp[RTAC_MAX_ACTIVE_POPP];
-};
-
-struct rtac_adm {
-	uint32_t		num_of_dev;
-	struct rtac_adm_data	device[RTAC_MAX_ACTIVE_DEVICES];
-};
-static struct rtac_adm		rtac_adm_data;
-static u32			rtac_adm_payload_size;
-static u32			rtac_adm_user_buf_size;
-static u8			*rtac_adm_buffer;
-
-
-/* ASM APR */
-static u32			rtac_asm_payload_size;
-static u32			rtac_asm_user_buf_size;
-static u8			*rtac_asm_buffer;
-
-
-/* Voice info & APR */
-struct rtac_voice_data {
-	uint32_t	tx_topology_id;
-	uint32_t	rx_topology_id;
-	uint32_t	tx_afe_port;
-	uint32_t	rx_afe_port;
-	uint16_t	cvs_handle;
-	uint16_t	cvp_handle;
-};
-
-struct rtac_voice {
-	uint32_t		num_of_voice_combos;
-	struct rtac_voice_data	voice[RTAC_MAX_ACTIVE_VOICE_COMBOS];
-};
-
-static struct rtac_voice	rtac_voice_data;
-static u32			rtac_voice_payload_size;
-static u32			rtac_voice_user_buf_size;
-static u8			*rtac_voice_buffer;
-static u32			voice_session_id[RTAC_MAX_ACTIVE_VOICE_COMBOS];
-
-
-struct mutex			rtac_adm_mutex;
-struct mutex			rtac_adm_apr_mutex;
-struct mutex			rtac_asm_apr_mutex;
-struct mutex			rtac_voice_mutex;
-struct mutex			rtac_voice_apr_mutex;
-
-static int rtac_open(struct inode *inode, struct file *f)
-{
-	pr_debug("%s\n", __func__);
-	return 0;
-}
-
-static int rtac_release(struct inode *inode, struct file *f)
-{
-	pr_debug("%s\n", __func__);
-	return 0;
-}
-
-/* ADM Info */
-void add_popp(u32 dev_idx, u32 port_id, u32 popp_id)
-{
-	u32 i = 0;
-
-	for (; i < rtac_adm_data.device[dev_idx].num_of_popp; i++)
-		if (rtac_adm_data.device[dev_idx].popp[i] == popp_id)
-			goto done;
-
-	if (rtac_adm_data.device[dev_idx].num_of_popp ==
-			RTAC_MAX_ACTIVE_POPP) {
-		pr_err("%s, Max POPP!\n", __func__);
-		goto done;
-	}
-	rtac_adm_data.device[dev_idx].popp[
-		rtac_adm_data.device[dev_idx].num_of_popp++] = popp_id;
-done:
-	return;
-}
-
-void rtac_add_adm_device(u32 port_id, u32 copp_id, u32 path_id, u32 popp_id)
-{
-	u32 i = 0;
-	pr_debug("%s: port_id = %d, popp_id = %d\n", __func__, port_id,
-		popp_id);
-
-	mutex_lock(&rtac_adm_mutex);
-	if (rtac_adm_data.num_of_dev == RTAC_MAX_ACTIVE_DEVICES) {
-		pr_err("%s, Can't add anymore RTAC devices!\n", __func__);
-		goto done;
-	}
-
-	/* 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) {
-				add_popp(i, port_id, popp_id);
-				goto done;
-			}
-			if (rtac_adm_data.device[i].num_of_popp ==
-						RTAC_MAX_ACTIVE_POPP) {
-				pr_err("%s, Max POPP!\n", __func__);
-				goto done;
-			}
-		}
-	}
-
-	/* Add device */
-	rtac_adm_data.num_of_dev++;
-
-	if (path_id == ADM_PATH_PLAYBACK)
-		rtac_adm_data.device[i].topology_id =
-						get_adm_rx_topology();
-	else
-		rtac_adm_data.device[i].topology_id =
-						get_adm_tx_topology();
-	rtac_adm_data.device[i].afe_port = port_id;
-	rtac_adm_data.device[i].copp = copp_id;
-	rtac_adm_data.device[i].popp[
-		rtac_adm_data.device[i].num_of_popp++] = popp_id;
-done:
-	mutex_unlock(&rtac_adm_mutex);
-	return;
-}
-
-static void shift_adm_devices(u32 dev_idx)
-{
-	for (; dev_idx < rtac_adm_data.num_of_dev; dev_idx++) {
-		memcpy(&rtac_adm_data.device[dev_idx],
-			&rtac_adm_data.device[dev_idx + 1],
-			sizeof(rtac_adm_data.device[dev_idx]));
-		memset(&rtac_adm_data.device[dev_idx + 1], 0,
-			   sizeof(rtac_adm_data.device[dev_idx]));
-	}
-}
-
-static void shift_popp(u32 copp_idx, u32 popp_idx)
-{
-	for (; popp_idx < rtac_adm_data.device[copp_idx].num_of_popp;
-							popp_idx++) {
-		memcpy(&rtac_adm_data.device[copp_idx].popp[popp_idx],
-			&rtac_adm_data.device[copp_idx].popp[popp_idx + 1],
-			sizeof(uint32_t));
-		memset(&rtac_adm_data.device[copp_idx].popp[popp_idx + 1], 0,
-			   sizeof(uint32_t));
-	}
-}
-
-void rtac_remove_adm_device(u32 port_id)
-{
-	s32 i;
-	pr_debug("%s: port_id = %d\n", __func__, port_id);
-
-	mutex_lock(&rtac_adm_mutex);
-	/* look for device */
-	for (i = 0; i < rtac_adm_data.num_of_dev; i++) {
-		if (rtac_adm_data.device[i].afe_port == port_id) {
-			memset(&rtac_adm_data.device[i], 0,
-				   sizeof(rtac_adm_data.device[i]));
-			rtac_adm_data.num_of_dev--;
-
-			if (rtac_adm_data.num_of_dev >= 1) {
-				shift_adm_devices(i);
-				break;
-			}
-		}
-	}
-
-	mutex_unlock(&rtac_adm_mutex);
-	return;
-}
-
-void rtac_remove_popp_from_adm_devices(u32 popp_id)
-{
-	s32 i, j;
-	pr_debug("%s: popp_id = %d\n", __func__, popp_id);
-
-	mutex_lock(&rtac_adm_mutex);
-
-	for (i = 0; i < rtac_adm_data.num_of_dev; i++) {
-		for (j = 0; j < rtac_adm_data.device[i].num_of_popp; j++) {
-			if (rtac_adm_data.device[i].popp[j] == popp_id) {
-				rtac_adm_data.device[i].popp[j] = 0;
-				rtac_adm_data.device[i].num_of_popp--;
-				shift_popp(i, j);
-			}
-		}
-	}
-
-	mutex_unlock(&rtac_adm_mutex);
-}
-
-/* Voice Info */
-static void set_rtac_voice_data(int idx, u32 cvs_handle, u32 cvp_handle,
-					u32 rx_afe_port, u32 tx_afe_port,
-					u32 session_id)
-{
-	rtac_voice_data.voice[idx].tx_topology_id = get_voice_tx_topology();
-	rtac_voice_data.voice[idx].rx_topology_id = get_voice_rx_topology();
-	rtac_voice_data.voice[idx].tx_afe_port = tx_afe_port;
-	rtac_voice_data.voice[idx].rx_afe_port = rx_afe_port;
-	rtac_voice_data.voice[idx].cvs_handle = cvs_handle;
-	rtac_voice_data.voice[idx].cvp_handle = cvp_handle;
-
-	/* Store session ID for voice RTAC */
-	voice_session_id[idx] = session_id;
-}
-
-void rtac_add_voice(u32 cvs_handle, u32 cvp_handle, u32 rx_afe_port,
-			u32 tx_afe_port, u32 session_id)
-{
-	u32 i = 0;
-	pr_debug("%s\n", __func__);
-	mutex_lock(&rtac_voice_mutex);
-
-	if (rtac_voice_data.num_of_voice_combos ==
-			RTAC_MAX_ACTIVE_VOICE_COMBOS) {
-		pr_err("%s, Can't add anymore RTAC devices!\n", __func__);
-		goto done;
-	}
-
-	/* Check if device already added */
-	if (rtac_voice_data.num_of_voice_combos != 0) {
-		for (; i < rtac_voice_data.num_of_voice_combos; i++) {
-			if (rtac_voice_data.voice[i].cvs_handle ==
-							cvs_handle) {
-				set_rtac_voice_data(i, cvs_handle, cvp_handle,
-					rx_afe_port, tx_afe_port,
-					session_id);
-				goto done;
-			}
-		}
-	}
-
-	/* Add device */
-	rtac_voice_data.num_of_voice_combos++;
-	set_rtac_voice_data(i, cvs_handle, cvp_handle,
-				rx_afe_port, tx_afe_port,
-				session_id);
-done:
-	mutex_unlock(&rtac_voice_mutex);
-	return;
-}
-
-static void shift_voice_devices(u32 idx)
-{
-	for (; idx < rtac_voice_data.num_of_voice_combos - 1; idx++) {
-		memcpy(&rtac_voice_data.voice[idx],
-			&rtac_voice_data.voice[idx + 1],
-			sizeof(rtac_voice_data.voice[idx]));
-		voice_session_id[idx] = voice_session_id[idx + 1];
-	}
-}
-
-void rtac_remove_voice(u32 cvs_handle)
-{
-	u32 i = 0;
-	pr_debug("%s\n", __func__);
-
-	mutex_lock(&rtac_voice_mutex);
-	/* look for device */
-	for (i = 0; i < rtac_voice_data.num_of_voice_combos; i++) {
-		if (rtac_voice_data.voice[i].cvs_handle == cvs_handle) {
-			shift_voice_devices(i);
-			rtac_voice_data.num_of_voice_combos--;
-			memset(&rtac_voice_data.voice[
-				rtac_voice_data.num_of_voice_combos], 0,
-				sizeof(rtac_voice_data.voice
-				[rtac_voice_data.num_of_voice_combos]));
-			voice_session_id[rtac_voice_data.num_of_voice_combos]
-				= 0;
-			break;
-		}
-	}
-	mutex_unlock(&rtac_voice_mutex);
-	return;
-}
-
-static int get_voice_index_cvs(u32 cvs_handle)
-{
-	u32 i;
-
-	for (i = 0; i < rtac_voice_data.num_of_voice_combos; i++) {
-		if (rtac_voice_data.voice[i].cvs_handle == cvs_handle)
-			return i;
-	}
-
-	pr_err("%s: No voice index for CVS handle %d found returning 0\n",
-	       __func__, cvs_handle);
-	return 0;
-}
-
-static int get_voice_index_cvp(u32 cvp_handle)
-{
-	u32 i;
-
-	for (i = 0; i < rtac_voice_data.num_of_voice_combos; i++) {
-		if (rtac_voice_data.voice[i].cvp_handle == cvp_handle)
-			return i;
-	}
-
-	pr_err("%s: No voice index for CVP handle %d found returning 0\n",
-	       __func__, cvp_handle);
-	return 0;
-}
-
-static int get_voice_index(u32 mode, u32 handle)
-{
-	if (mode == RTAC_CVP)
-		return get_voice_index_cvp(handle);
-	if (mode == RTAC_CVS)
-		return get_voice_index_cvs(handle);
-
-	pr_err("%s: Invalid mode %d, returning 0\n",
-	       __func__, mode);
-	return 0;
-}
-
-
-/* ADM APR */
-void rtac_set_adm_handle(void *handle)
-{
-	pr_debug("%s: handle = %d\n", __func__, (unsigned int)handle);
-
-	mutex_lock(&rtac_adm_apr_mutex);
-	rtac_adm_apr_data.apr_handle = handle;
-	mutex_unlock(&rtac_adm_apr_mutex);
-}
-
-bool rtac_make_adm_callback(uint32_t *payload, u32 payload_size)
-{
-	pr_debug("%s:cmd_state = %d\n", __func__,
-			atomic_read(&rtac_adm_apr_data.cmd_state));
-	if (atomic_read(&rtac_adm_apr_data.cmd_state) != 1)
-		return false;
-
-	/* Offset data for in-band payload */
-	rtac_copy_adm_payload_to_user(payload, payload_size);
-	atomic_set(&rtac_adm_apr_data.cmd_state, 0);
-	wake_up(&rtac_adm_apr_data.cmd_wait);
-	return true;
-}
-
-void rtac_copy_adm_payload_to_user(void *payload, u32 payload_size)
-{
-	pr_debug("%s\n", __func__);
-	rtac_adm_payload_size = payload_size;
-
-	memcpy(rtac_adm_buffer, &payload_size, sizeof(u32));
-	if (payload_size != 0) {
-		if (payload_size > rtac_adm_user_buf_size) {
-			pr_err("%s: Buffer set not big enough for returned data, buf size = %d, ret data = %d\n",
-			 __func__, rtac_adm_user_buf_size, payload_size);
-			rtac_adm_payload_size = 0;
-			goto done;
-		}
-		memcpy(rtac_adm_buffer + sizeof(u32), payload, payload_size);
-	}
-done:
-	return;
-}
-
-u32 send_adm_apr(void *buf, u32 opcode)
-{
-	s32	result;
-	u32	count = 0;
-	u32	bytes_returned = 0;
-	u32	port_index = 0;
-	u32	copp_id;
-	u32	payload_size;
-	struct apr_hdr	adm_params;
-	pr_debug("%s\n", __func__);
-
-	if (copy_from_user(&count, (void *)buf, sizeof(count))) {
-		pr_err("%s: Copy to user failed! buf = 0x%x\n",
-		       __func__, (unsigned int)buf);
-		result = -EFAULT;
-		goto done;
-	}
-
-	if (count <= 0) {
-		pr_err("%s: Invalid buffer size = %d\n", __func__, count);
-		goto done;
-	}
-
-	if (copy_from_user(&payload_size, buf + sizeof(u32), sizeof(u32))) {
-		pr_err("%s: Could not copy payload size from user buffer\n",
-			__func__);
-		goto done;
-	}
-
-
-	if (payload_size > MAX_PAYLOAD_SIZE) {
-		pr_err("%s: Invalid payload size = %d\n",
-			__func__, payload_size);
-		goto done;
-	}
-
-	if (copy_from_user(&copp_id, buf + 2 * sizeof(u32), sizeof(u32))) {
-		pr_err("%s: Could not copy port id from user buffer\n",
-			__func__);
-		goto done;
-	}
-
-	for (port_index = 0; port_index < AFE_MAX_PORTS; port_index++) {
-		if (adm_get_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",
-		       __func__, copp_id);
-		goto done;
-	}
-
-	mutex_lock(&rtac_adm_apr_mutex);
-	if (rtac_adm_apr_data.apr_handle == NULL) {
-		pr_err("%s: APR not initialized\n", __func__);
-		goto err;
-	}
-
-	/* Set globals for copy of returned payload */
-	rtac_adm_user_buf_size = count;
-
-	/* Copy buffer to in-band payload */
-	if (copy_from_user(rtac_adm_buffer + sizeof(adm_params),
-			buf + 3 * sizeof(u32), payload_size)) {
-		pr_err("%s: Could not copy payload from user buffer\n",
-			__func__);
-		goto err;
-	}
-
-	/* Pack header */
-	adm_params.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
-		APR_HDR_LEN(20), APR_PKT_VER);
-	adm_params.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
-		payload_size);
-	adm_params.src_svc = APR_SVC_ADM;
-	adm_params.src_domain = APR_DOMAIN_APPS;
-	adm_params.src_port = copp_id;
-	adm_params.dest_svc = APR_SVC_ADM;
-	adm_params.dest_domain = APR_DOMAIN_ADSP;
-	adm_params.dest_port = copp_id;
-	adm_params.token = copp_id;
-	adm_params.opcode = opcode;
-
-	memcpy(rtac_adm_buffer, &adm_params, sizeof(adm_params));
-	atomic_set(&rtac_adm_apr_data.cmd_state, 1);
-
-	pr_debug("%s: Sending RTAC command size = %d\n",
-		__func__, adm_params.pkt_size);
-
-	result = apr_send_pkt(rtac_adm_apr_data.apr_handle,
-		(uint32_t *)rtac_adm_buffer);
-	if (result < 0) {
-		pr_err("%s: Set params failed port = %d, copp = %d\n",
-			__func__, port_index, copp_id);
-		goto err;
-	}
-	/* Wait for the callback */
-	result = wait_event_timeout(rtac_adm_apr_data.cmd_wait,
-		(atomic_read(&rtac_adm_apr_data.cmd_state) == 0),
-		msecs_to_jiffies(TIMEOUT_MS));
-	mutex_unlock(&rtac_adm_apr_mutex);
-	if (!result) {
-		pr_err("%s: Set params timed out port = %d, copp = %d\n",
-			__func__, port_index, copp_id);
-		goto done;
-	}
-
-	if (rtac_adm_payload_size != 0) {
-		if (copy_to_user(buf, rtac_adm_buffer,
-			rtac_adm_payload_size + sizeof(u32))) {
-			pr_err("%s: Could not copy buffer to user,size = %d\n",
-				__func__, payload_size);
-			goto done;
-		}
-	}
-
-	/* Return data written for SET & data read for GET */
-	if (opcode == ADM_CMD_GET_PP_PARAMS_V5)
-		bytes_returned = rtac_adm_payload_size;
-	else
-		bytes_returned = payload_size;
-done:
-	return bytes_returned;
-err:
-	mutex_unlock(&rtac_adm_apr_mutex);
-	return bytes_returned;
-}
-
-
-/* ASM APR */
-void rtac_set_asm_handle(u32 session_id, void *handle)
-{
-	pr_debug("%s\n", __func__);
-
-	mutex_lock(&rtac_asm_apr_mutex);
-	rtac_asm_apr_data[session_id].apr_handle = handle;
-	mutex_unlock(&rtac_asm_apr_mutex);
-}
-
-bool rtac_make_asm_callback(u32 session_id, uint32_t *payload,
-	u32 payload_size)
-{
-	if (atomic_read(&rtac_asm_apr_data[session_id].cmd_state) != 1)
-		return false;
-
-	pr_debug("%s\n", __func__);
-	/* Offset data for in-band payload */
-	rtac_copy_asm_payload_to_user(payload, payload_size);
-	atomic_set(&rtac_asm_apr_data[session_id].cmd_state, 0);
-	wake_up(&rtac_asm_apr_data[session_id].cmd_wait);
-	return true;
-}
-
-void rtac_copy_asm_payload_to_user(void *payload, u32 payload_size)
-{
-	pr_debug("%s\n", __func__);
-	rtac_asm_payload_size = payload_size;
-
-	memcpy(rtac_asm_buffer, &payload_size, sizeof(u32));
-	if (payload_size) {
-		if (payload_size > rtac_asm_user_buf_size) {
-			pr_err("%s: Buffer set not big enough for returned data, buf size = %d, ret data = %d\n",
-			 __func__, rtac_asm_user_buf_size, payload_size);
-			rtac_asm_payload_size = 0;
-			goto done;
-		}
-		memcpy(rtac_asm_buffer + sizeof(u32), payload, payload_size);
-	}
-done:
-	return;
-}
-
-u32 send_rtac_asm_apr(void *buf, u32 opcode)
-{
-	s32	result;
-	u32	count = 0;
-	u32	bytes_returned = 0;
-	u32	session_id = 0;
-	u32	payload_size;
-	struct apr_hdr		asm_params;
-	pr_debug("%s\n", __func__);
-
-	if (copy_from_user(&count, (void *)buf, sizeof(count))) {
-		pr_err("%s: Copy to user failed! buf = 0x%x\n",
-		       __func__, (unsigned int)buf);
-		result = -EFAULT;
-		goto done;
-	}
-
-	if (count <= 0) {
-		pr_err("%s: Invalid buffer size = %d\n", __func__, count);
-		goto done;
-	}
-
-	if (copy_from_user(&payload_size, buf + sizeof(u32), sizeof(u32))) {
-		pr_err("%s: Could not copy payload size from user buffer\n",
-			__func__);
-		goto done;
-	}
-
-	if (payload_size > MAX_PAYLOAD_SIZE) {
-		pr_err("%s: Invalid payload size = %d\n",
-			__func__, payload_size);
-		goto done;
-	}
-
-	if (copy_from_user(&session_id, buf + 2 * sizeof(u32), sizeof(u32))) {
-		pr_err("%s: Could not copy session id from user buffer\n",
-			__func__);
-		goto done;
-	}
-
-	if (session_id > (SESSION_MAX + 1)) {
-		pr_err("%s: Invalid Session = %d\n", __func__, session_id);
-		goto done;
-	}
-
-	mutex_lock(&rtac_asm_apr_mutex);
-	if (session_id < SESSION_MAX+1) {
-		if (rtac_asm_apr_data[session_id].apr_handle == NULL) {
-			pr_err("%s: APR not initialized\n", __func__);
-			goto err;
-		}
-	}
-
-	/* Set globals for copy of returned payload */
-	rtac_asm_user_buf_size = count;
-
-	/* Copy buffer to in-band payload */
-	if (copy_from_user(rtac_asm_buffer + sizeof(asm_params),
-			buf + 3 * sizeof(u32), payload_size)) {
-		pr_err("%s: Could not copy payload from user buffer\n",
-			__func__);
-		goto err;
-	}
-
-	/* Pack header */
-	asm_params.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
-		APR_HDR_LEN(20), APR_PKT_VER);
-	asm_params.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
-		payload_size);
-	asm_params.src_svc = q6asm_get_apr_service_id(session_id);
-	asm_params.src_domain = APR_DOMAIN_APPS;
-	asm_params.src_port = (session_id << 8) | 0x0001;
-	asm_params.dest_svc = APR_SVC_ASM;
-	asm_params.dest_domain = APR_DOMAIN_ADSP;
-	asm_params.dest_port = (session_id << 8) | 0x0001;
-	asm_params.token = session_id;
-	asm_params.opcode = opcode;
-
-	memcpy(rtac_asm_buffer, &asm_params, sizeof(asm_params));
-	if (session_id < SESSION_MAX+1)
-		atomic_set(&rtac_asm_apr_data[session_id].cmd_state, 1);
-
-	pr_debug("%s: Sending RTAC command size = %d, session_id=%d\n",
-		__func__, asm_params.pkt_size, session_id);
-
-	result = apr_send_pkt(rtac_asm_apr_data[session_id].apr_handle,
-				(uint32_t *)rtac_asm_buffer);
-	if (result < 0) {
-		pr_err("%s: Set params failed session = %d\n",
-			__func__, session_id);
-		goto err;
-	}
-
-	/* Wait for the callback */
-	result = wait_event_timeout(rtac_asm_apr_data[session_id].cmd_wait,
-		(atomic_read(&rtac_asm_apr_data[session_id].cmd_state) == 0),
-		5 * HZ);
-	mutex_unlock(&rtac_asm_apr_mutex);
-	if (!result) {
-		pr_err("%s: Set params timed out session = %d\n",
-			__func__, session_id);
-		goto done;
-	}
-
-	if (rtac_asm_payload_size != 0) {
-		if (copy_to_user(buf, rtac_asm_buffer,
-			rtac_asm_payload_size + sizeof(u32))) {
-			pr_err("%s: Could not copy buffer to user,size = %d\n",
-				 __func__, payload_size);
-			goto done;
-		}
-	}
-
-	/* Return data written for SET & data read for GET */
-	if (opcode == ASM_STREAM_CMD_GET_PP_PARAMS_V2)
-		bytes_returned = rtac_asm_payload_size;
-	else
-		bytes_returned = payload_size;
-done:
-	return bytes_returned;
-err:
-	mutex_unlock(&rtac_asm_apr_mutex);
-	return bytes_returned;
-}
-
-
-/* Voice APR */
-void rtac_set_voice_handle(u32 mode, void *handle)
-{
-	pr_debug("%s\n", __func__);
-
-	mutex_lock(&rtac_voice_apr_mutex);
-	rtac_voice_apr_data[mode].apr_handle = handle;
-	mutex_unlock(&rtac_voice_apr_mutex);
-}
-
-bool rtac_make_voice_callback(u32 mode, uint32_t *payload, u32 payload_size)
-{
-	if ((atomic_read(&rtac_voice_apr_data[mode].cmd_state) != 1) ||
-		(mode >= RTAC_VOICE_MODES))
-		return false;
-
-	pr_debug("%s\n", __func__);
-	/* Offset data for in-band payload */
-	rtac_copy_voice_payload_to_user(payload, payload_size);
-	atomic_set(&rtac_voice_apr_data[mode].cmd_state, 0);
-	wake_up(&rtac_voice_apr_data[mode].cmd_wait);
-	return true;
-}
-
-void rtac_copy_voice_payload_to_user(void *payload, u32 payload_size)
-{
-	pr_debug("%s\n", __func__);
-	rtac_voice_payload_size = payload_size;
-
-	memcpy(rtac_voice_buffer, &payload_size, sizeof(u32));
-	if (payload_size) {
-		if (payload_size > rtac_voice_user_buf_size) {
-			pr_err("%s: Buffer set not big enough for returned data, buf size = %d, ret data = %d\n",
-			 __func__, rtac_voice_user_buf_size, payload_size);
-			rtac_voice_payload_size = 0;
-			goto done;
-		}
-		memcpy(rtac_voice_buffer + sizeof(u32), payload, payload_size);
-	}
-done:
-	return;
-}
-
-u32 send_voice_apr(u32 mode, void *buf, u32 opcode)
-{
-	s32	result;
-	u32	count = 0;
-	u32	bytes_returned = 0;
-	u32	payload_size;
-	u32	dest_port;
-	struct apr_hdr		voice_params;
-	pr_debug("%s\n", __func__);
-
-	if (copy_from_user(&count, (void *)buf, sizeof(count))) {
-		pr_err("%s: Copy to user failed! buf = 0x%x\n",
-		       __func__, (unsigned int)buf);
-		result = -EFAULT;
-		goto done;
-	}
-
-	if (count <= 0) {
-		pr_err("%s: Invalid buffer size = %d\n", __func__, count);
-		goto done;
-	}
-
-	if (copy_from_user(&payload_size, buf + sizeof(u32), sizeof(u32))) {
-		pr_err("%s: Could not copy payload size from user buffer\n",
-			__func__);
-		goto done;
-	}
-
-	if (payload_size > MAX_PAYLOAD_SIZE) {
-		pr_err("%s: Invalid payload size = %d\n",
-				__func__, payload_size);
-		goto done;
-	}
-
-	if (copy_from_user(&dest_port, buf + 2 * sizeof(u32), sizeof(u32))) {
-		pr_err("%s: Could not copy port id from user buffer\n",
-			__func__);
-		goto done;
-	}
-
-	if ((mode != RTAC_CVP) && (mode != RTAC_CVS)) {
-		pr_err("%s: Invalid Mode for APR, mode = %d\n",
-			__func__, mode);
-		goto done;
-	}
-
-	mutex_lock(&rtac_voice_apr_mutex);
-	if (rtac_voice_apr_data[mode].apr_handle == NULL) {
-		pr_err("%s: APR not initialized\n", __func__);
-		goto err;
-	}
-
-	/* Set globals for copy of returned payload */
-	rtac_voice_user_buf_size = count;
-
-	/* Copy buffer to in-band payload */
-	if (copy_from_user(rtac_voice_buffer + sizeof(voice_params),
-			buf + 3 * sizeof(u32), payload_size)) {
-		pr_err("%s: Could not copy payload from user buffer\n",
-			__func__);
-		goto err;
-	}
-
-	/* Pack header */
-	voice_params.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
-		APR_HDR_LEN(20), APR_PKT_VER);
-	voice_params.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
-		payload_size);
-	voice_params.src_svc = 0;
-	voice_params.src_domain = APR_DOMAIN_APPS;
-	voice_params.src_port = voice_session_id[
-					get_voice_index(mode, dest_port)];
-	voice_params.dest_svc = 0;
-	voice_params.dest_domain = APR_DOMAIN_MODEM;
-	voice_params.dest_port = (u16)dest_port;
-	voice_params.token = 0;
-	voice_params.opcode = opcode;
-
-	memcpy(rtac_voice_buffer, &voice_params, sizeof(voice_params));
-	atomic_set(&rtac_voice_apr_data[mode].cmd_state, 1);
-
-	pr_debug("%s: Sending RTAC command size = %d, opcode = %x\n",
-		__func__, voice_params.pkt_size, opcode);
-
-	result = apr_send_pkt(rtac_voice_apr_data[mode].apr_handle,
-					(uint32_t *)rtac_voice_buffer);
-	if (result < 0) {
-		pr_err("%s: apr_send_pkt failed opcode = %x\n",
-			__func__, opcode);
-		goto err;
-	}
-	/* Wait for the callback */
-	result = wait_event_timeout(rtac_voice_apr_data[mode].cmd_wait,
-		(atomic_read(&rtac_voice_apr_data[mode].cmd_state) == 0),
-		msecs_to_jiffies(TIMEOUT_MS));
-	mutex_unlock(&rtac_voice_apr_mutex);
-	if (!result) {
-		pr_err("%s: apr_send_pkt timed out opcode = %x\n",
-			__func__, opcode);
-		goto done;
-	}
-
-	if (rtac_voice_payload_size != 0) {
-		if (copy_to_user(buf, rtac_voice_buffer,
-			rtac_voice_payload_size + sizeof(u32))) {
-			pr_err("%s: Could not copy buffer to user, size = %d\n",
-				 __func__, payload_size);
-			goto done;
-		}
-	}
-
-	/* Return data written for SET & data read for GET */
-	if (opcode == VOICE_CMD_GET_PARAM)
-		bytes_returned = rtac_voice_payload_size;
-	else
-		bytes_returned = payload_size;
-done:
-	return bytes_returned;
-err:
-	mutex_unlock(&rtac_voice_apr_mutex);
-	return bytes_returned;
-}
-
-
-
-static long rtac_ioctl(struct file *f,
-		unsigned int cmd, unsigned long arg)
-{
-	s32 result = 0;
-	pr_debug("%s\n", __func__);
-
-	if (arg == 0) {
-		pr_err("%s: No data sent to driver!\n", __func__);
-		result = -EFAULT;
-		goto done;
-	}
-
-	switch (cmd) {
-	case AUDIO_GET_RTAC_ADM_INFO:
-		if (copy_to_user((void *)arg, &rtac_adm_data,
-						sizeof(rtac_adm_data)))
-			pr_err("%s: Could not copy to userspace!\n", __func__);
-		else
-			result = sizeof(rtac_adm_data);
-		break;
-	case AUDIO_GET_RTAC_VOICE_INFO:
-		if (copy_to_user((void *)arg, &rtac_voice_data,
-						sizeof(rtac_voice_data)))
-			pr_err("%s: Could not copy to userspace!\n", __func__);
-		else
-			result = sizeof(rtac_voice_data);
-		break;
-	case AUDIO_GET_RTAC_ADM_CAL:
-		result = send_adm_apr((void *)arg, ADM_CMD_GET_PP_PARAMS_V5);
-		break;
-	case AUDIO_SET_RTAC_ADM_CAL:
-		result = send_adm_apr((void *)arg, ADM_CMD_SET_PP_PARAMS_V5);
-		break;
-	case AUDIO_GET_RTAC_ASM_CAL:
-		result = send_rtac_asm_apr((void *)arg,
-			ASM_STREAM_CMD_GET_PP_PARAMS_V2);
-		break;
-	case AUDIO_SET_RTAC_ASM_CAL:
-		result = send_rtac_asm_apr((void *)arg,
-			ASM_STREAM_CMD_SET_PP_PARAMS_V2);
-		break;
-	case AUDIO_GET_RTAC_CVS_CAL:
-		result = send_voice_apr(RTAC_CVS, (void *)arg,
-			VOICE_CMD_GET_PARAM);
-		break;
-	case AUDIO_SET_RTAC_CVS_CAL:
-		result = send_voice_apr(RTAC_CVS, (void *)arg,
-			VOICE_CMD_SET_PARAM);
-		break;
-	case AUDIO_GET_RTAC_CVP_CAL:
-		result = send_voice_apr(RTAC_CVP, (void *)arg,
-			VOICE_CMD_GET_PARAM);
-		break;
-	case AUDIO_SET_RTAC_CVP_CAL:
-		result = send_voice_apr(RTAC_CVP, (void *)arg,
-			VOICE_CMD_SET_PARAM);
-		break;
-	default:
-		pr_err("%s: Invalid IOCTL, command = %d!\n",
-		       __func__, cmd);
-	}
-done:
-	return result;
-}
-
-
-static const struct file_operations rtac_fops = {
-	.owner = THIS_MODULE,
-	.open = rtac_open,
-	.release = rtac_release,
-	.unlocked_ioctl = rtac_ioctl,
-};
-
-struct miscdevice rtac_misc = {
-	.minor	= MISC_DYNAMIC_MINOR,
-	.name	= "msm_rtac",
-	.fops	= &rtac_fops,
-};
-
-static int __init rtac_init(void)
-{
-	int i = 0;
-	pr_debug("%s\n", __func__);
-
-	/* ADM */
-	memset(&rtac_adm_data, 0, sizeof(rtac_adm_data));
-	rtac_adm_apr_data.apr_handle = NULL;
-	atomic_set(&rtac_adm_apr_data.cmd_state, 0);
-	init_waitqueue_head(&rtac_adm_apr_data.cmd_wait);
-	mutex_init(&rtac_adm_mutex);
-	mutex_init(&rtac_adm_apr_mutex);
-
-	rtac_adm_buffer = kzalloc(RTAC_BUF_SIZE, GFP_KERNEL);
-	if (rtac_adm_buffer == NULL) {
-		pr_err("%s: Could not allocate payload of size = %d\n",
-			__func__, RTAC_BUF_SIZE);
-		goto nomem;
-	}
-
-	/* ASM */
-	for (i = 0; i < SESSION_MAX+1; i++) {
-		rtac_asm_apr_data[i].apr_handle = NULL;
-		atomic_set(&rtac_asm_apr_data[i].cmd_state, 0);
-		init_waitqueue_head(&rtac_asm_apr_data[i].cmd_wait);
-	}
-	mutex_init(&rtac_asm_apr_mutex);
-
-	rtac_asm_buffer = kzalloc(RTAC_BUF_SIZE, GFP_KERNEL);
-	if (rtac_asm_buffer == NULL) {
-		pr_err("%s: Could not allocate payload of size = %d\n",
-			__func__, RTAC_BUF_SIZE);
-		kzfree(rtac_adm_buffer);
-		goto nomem;
-	}
-
-	/* Voice */
-	memset(&rtac_voice_data, 0, sizeof(rtac_voice_data));
-	for (i = 0; i < RTAC_VOICE_MODES; i++) {
-		rtac_voice_apr_data[i].apr_handle = NULL;
-		atomic_set(&rtac_voice_apr_data[i].cmd_state, 0);
-		init_waitqueue_head(&rtac_voice_apr_data[i].cmd_wait);
-	}
-	mutex_init(&rtac_voice_mutex);
-	mutex_init(&rtac_voice_apr_mutex);
-
-	rtac_voice_buffer = kzalloc(RTAC_BUF_SIZE, GFP_KERNEL);
-	if (rtac_voice_buffer == NULL) {
-		pr_err("%s: Could not allocate payload of size = %d\n",
-			__func__, RTAC_BUF_SIZE);
-		kzfree(rtac_adm_buffer);
-		kzfree(rtac_asm_buffer);
-		goto nomem;
-	}
-
-	return misc_register(&rtac_misc);
-nomem:
-	return -ENOMEM;
-}
-
-module_init(rtac_init);
-
-MODULE_DESCRIPTION("MSM 8x60 Real-Time Audio Calibration driver");
-MODULE_LICENSE("GPL v2");
-
-#endif
diff --git a/arch/arm/mach-msm/qdsp6v2/snddev_ecodec.c b/arch/arm/mach-msm/qdsp6v2/snddev_ecodec.c
index 0b38ec2..804fa14 100644
--- a/arch/arm/mach-msm/qdsp6v2/snddev_ecodec.c
+++ b/arch/arm/mach-msm/qdsp6v2/snddev_ecodec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp6v2/snddev_ecodec.h b/arch/arm/mach-msm/qdsp6v2/snddev_ecodec.h
index b102de0..6eb6751 100644
--- a/arch/arm/mach-msm/qdsp6v2/snddev_ecodec.h
+++ b/arch/arm/mach-msm/qdsp6v2/snddev_ecodec.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp6v2/snddev_hdmi.c b/arch/arm/mach-msm/qdsp6v2/snddev_hdmi.c
index 9b8346d..f6af0ee 100644
--- a/arch/arm/mach-msm/qdsp6v2/snddev_hdmi.c
+++ b/arch/arm/mach-msm/qdsp6v2/snddev_hdmi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp6v2/snddev_hdmi.h b/arch/arm/mach-msm/qdsp6v2/snddev_hdmi.h
index cc69033..672bfa6 100644
--- a/arch/arm/mach-msm/qdsp6v2/snddev_hdmi.h
+++ b/arch/arm/mach-msm/qdsp6v2/snddev_hdmi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp6v2/snddev_icodec.c b/arch/arm/mach-msm/qdsp6v2/snddev_icodec.c
index e266d7a..38bb65a 100644
--- a/arch/arm/mach-msm/qdsp6v2/snddev_icodec.c
+++ b/arch/arm/mach-msm/qdsp6v2/snddev_icodec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp6v2/snddev_icodec.h b/arch/arm/mach-msm/qdsp6v2/snddev_icodec.h
index 8d5613f..3efa84b 100644
--- a/arch/arm/mach-msm/qdsp6v2/snddev_icodec.h
+++ b/arch/arm/mach-msm/qdsp6v2/snddev_icodec.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp6v2/snddev_mi2s.c b/arch/arm/mach-msm/qdsp6v2/snddev_mi2s.c
index 4cf18b3..f5b073a 100644
--- a/arch/arm/mach-msm/qdsp6v2/snddev_mi2s.c
+++ b/arch/arm/mach-msm/qdsp6v2/snddev_mi2s.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp6v2/snddev_mi2s.h b/arch/arm/mach-msm/qdsp6v2/snddev_mi2s.h
index d369c96..8ae45cd 100644
--- a/arch/arm/mach-msm/qdsp6v2/snddev_mi2s.h
+++ b/arch/arm/mach-msm/qdsp6v2/snddev_mi2s.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp6v2/snddev_virtual.c b/arch/arm/mach-msm/qdsp6v2/snddev_virtual.c
index f48aa0e..5ad49fe 100644
--- a/arch/arm/mach-msm/qdsp6v2/snddev_virtual.c
+++ b/arch/arm/mach-msm/qdsp6v2/snddev_virtual.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp6v2/snddev_virtual.h b/arch/arm/mach-msm/qdsp6v2/snddev_virtual.h
index dec4d07..e6da25f 100644
--- a/arch/arm/mach-msm/qdsp6v2/snddev_virtual.h
+++ b/arch/arm/mach-msm/qdsp6v2/snddev_virtual.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp6v2/timpani_profile_8x60.h b/arch/arm/mach-msm/qdsp6v2/timpani_profile_8x60.h
index f02e0a0..3410994 100644
--- a/arch/arm/mach-msm/qdsp6v2/timpani_profile_8x60.h
+++ b/arch/arm/mach-msm/qdsp6v2/timpani_profile_8x60.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.h b/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.h
index c68ad68..bf47366 100644
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.h
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -62,7 +62,7 @@
 	struct mutex	lock;
 	spinlock_t	dsp_lock;
 	/* extended parameters, related to q6 variants */
-	void			*ext;
+	void		*ext;
 };
 
 struct us_client {
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c b/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
index d00eae8..91ea1dc 100644
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.c b/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.c
index 94192cf..1299b96 100644
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.c
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.h b/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.h
index 042b293..03b62c5 100644
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.h
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/version_b/Makefile b/arch/arm/mach-msm/qdsp6v2/ultrasound/version_b/Makefile
new file mode 100644
index 0000000..23de73f
--- /dev/null
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/version_b/Makefile
@@ -0,0 +1,2 @@
+obj-y += q6usm_b.o ../usf.o ../usfcdev.o
+ccflags-y := -I$(src)/.. -I$(src)/../..
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
new file mode 100644
index 0000000..ff7ba33
--- /dev/null
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/version_b/q6usm_b.c
@@ -0,0 +1,1209 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/dma-mapping.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/msm_audio.h>
+#include <sound/apr_audio.h>
+#include <mach/qdsp6v2/apr_us_b.h>
+#include "q6usm.h"
+
+#define ADSP_MEMORY_MAP_SHMEM8_4K_POOL 3
+
+#define MEM_4K_OFFSET 4095
+#define MEM_4K_MASK 0xfffff000
+
+#define SESSION_MAX 0x02 /* aDSP:USM limit */
+
+#define READDONE_IDX_STATUS     0
+
+#define WRITEDONE_IDX_STATUS    0
+
+/* Standard timeout in the asynchronous ops */
+#define Q6USM_TIMEOUT_JIFFIES	(1*HZ) /* 1 sec */
+
+static DEFINE_MUTEX(session_lock);
+
+static struct us_client *session[SESSION_MAX];
+static int32_t q6usm_mmapcallback(struct apr_client_data *data, void *priv);
+static int32_t q6usm_callback(struct apr_client_data *data, void *priv);
+static void q6usm_add_hdr(struct us_client *usc, struct apr_hdr *hdr,
+			  uint32_t pkt_size, bool cmd_flg);
+
+struct usm_mmap {
+	atomic_t ref_cnt;
+	atomic_t cmd_state;
+	wait_queue_head_t cmd_wait;
+	void *apr;
+	int mem_handle;
+};
+
+static struct usm_mmap this_mmap;
+
+static void q6usm_add_mmaphdr(struct us_client *usc, struct apr_hdr *hdr,
+			      uint32_t pkt_size, bool cmd_flg, u32 token)
+{
+	hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, \
+				       APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+	hdr->src_port = 0;
+	hdr->dest_port = 0;
+	if (cmd_flg) {
+		hdr->token = token;
+		atomic_set(&this_mmap.cmd_state, 1);
+	}
+	hdr->pkt_size  = pkt_size;
+	return;
+}
+
+static int q6usm_memory_map(struct us_client *usc, uint32_t buf_add, int dir,
+		     uint32_t bufsz, uint32_t bufcnt)
+{
+	struct usm_cmd_memory_map_region mem_region_map;
+	int rc = 0;
+
+	if ((usc == NULL) || (usc->apr == NULL) || (this_mmap.apr == NULL)) {
+		pr_err("%s: APR handle NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	q6usm_add_mmaphdr(usc, &mem_region_map.hdr,
+			  sizeof(struct usm_cmd_memory_map_region), true,
+			  ((usc->session << 8) | dir));
+
+	mem_region_map.hdr.opcode = USM_CMD_SHARED_MEM_MAP_REGION;
+	mem_region_map.mempool_id = ADSP_MEMORY_MAP_SHMEM8_4K_POOL;
+
+	mem_region_map.num_regions = 1;
+	mem_region_map.flags = 0;
+
+	mem_region_map.shm_addr_lsw = buf_add;
+	mem_region_map.shm_addr_msw = 0;
+	mem_region_map.mem_size_bytes = bufsz * bufcnt;
+
+	rc = apr_send_pkt(this_mmap.apr, (uint32_t *) &mem_region_map);
+	if (rc < 0) {
+		pr_err("%s: mem_map op[0x%x]rc[%d]\n",
+		       __func__, mem_region_map.hdr.opcode, rc);
+		rc = -EINVAL;
+		goto fail_cmd;
+	}
+
+	rc = wait_event_timeout(this_mmap.cmd_wait,
+				(atomic_read(&this_mmap.cmd_state) == 0),
+				Q6USM_TIMEOUT_JIFFIES);
+	if (!rc) {
+		rc = -ETIME;
+		pr_err("%s: timeout. waited for memory_map\n", __func__);
+	} else {
+		struct us_port_data *port = &usc->port[dir];
+
+		*((uint32_t *)(port->ext)) = this_mmap.mem_handle;
+		rc = 0;
+	}
+fail_cmd:
+	return rc;
+}
+
+int q6usm_memory_unmap(struct us_client *usc, uint32_t buf_add, int dir)
+{
+	struct usm_cmd_memory_unmap_region mem_unmap;
+	struct us_port_data *port = &usc->port[dir];
+	int rc = 0;
+
+	if ((usc == NULL) || (usc->apr == NULL) || (this_mmap.apr == NULL)) {
+		pr_err("%s: APR handle NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	port = &usc->port[dir];
+	q6usm_add_mmaphdr(usc, &mem_unmap.hdr,
+			  sizeof(struct usm_cmd_memory_unmap_region), true,
+			  ((usc->session << 8) | dir));
+	mem_unmap.hdr.opcode = USM_CMD_SHARED_MEM_UNMAP_REGION;
+	mem_unmap.mem_map_handle = *((uint32_t *)(port->ext));
+
+	rc = apr_send_pkt(this_mmap.apr, (uint32_t *) &mem_unmap);
+	if (rc < 0) {
+		pr_err("%s: mem_unmap op[0x%x] rc[%d]\n",
+		       __func__, mem_unmap.hdr.opcode, rc);
+		goto fail_cmd;
+	}
+
+	rc = wait_event_timeout(this_mmap.cmd_wait,
+				(atomic_read(&this_mmap.cmd_state) == 0),
+				Q6USM_TIMEOUT_JIFFIES);
+	if (!rc) {
+		rc = -ETIME;
+		pr_err("%s: timeout. waited for memory_unmap\n", __func__);
+	} else
+		rc = 0;
+fail_cmd:
+	return rc;
+}
+
+static int q6usm_session_alloc(struct us_client *usc)
+{
+	int ind = 0;
+
+	mutex_lock(&session_lock);
+	for (ind = 0; ind < SESSION_MAX; ++ind) {
+		if (!session[ind]) {
+			session[ind] = usc;
+			mutex_unlock(&session_lock);
+			++ind; /* session id: 0 reserved */
+			pr_debug("%s: session[%d] was allocated\n",
+				  __func__, ind);
+			return ind;
+		}
+	}
+	mutex_unlock(&session_lock);
+	return -ENOMEM;
+}
+
+static void q6usm_session_free(struct us_client *usc)
+{
+	/* Session index was incremented during allocation */
+	uint16_t ind = (uint16_t)usc->session - 1;
+
+	pr_debug("%s: to free session[%d]\n", __func__, ind);
+	if (ind < SESSION_MAX) {
+		mutex_lock(&session_lock);
+		session[ind] = 0;
+		mutex_unlock(&session_lock);
+	}
+}
+
+int q6usm_us_client_buf_free(unsigned int dir,
+			     struct us_client *usc)
+{
+	struct us_port_data *port;
+	int rc = 0;
+	uint32_t size = 0;
+
+	if ((usc == NULL) ||
+	    ((dir != IN) && (dir != OUT)))
+		return -EINVAL;
+
+	mutex_lock(&usc->cmd_lock);
+	port = &usc->port[dir];
+	if (port == NULL) {
+		mutex_unlock(&usc->cmd_lock);
+		return -EINVAL;
+	}
+
+	if (port->data == NULL) {
+		mutex_unlock(&usc->cmd_lock);
+		return 0;
+	}
+
+	rc = q6usm_memory_unmap(usc, port->phys, dir);
+	pr_debug("%s: data[%p]phys[%p][%p]\n", __func__,
+		 (void *)port->data, (void *)port->phys, (void *)&port->phys);
+	/* 4K boundary is required by the API with QDSP6 */
+	size = (port->buf_size * port->buf_cnt + MEM_4K_OFFSET) & MEM_4K_MASK;
+	dma_free_coherent(NULL, size, port->data, port->phys);
+	port->data = NULL;
+	port->phys = 0;
+	port->buf_size = 0;
+	port->buf_cnt = 0;
+
+	mutex_unlock(&usc->cmd_lock);
+	return rc;
+}
+
+void q6usm_us_client_free(struct us_client *usc)
+{
+	int loopcnt = 0;
+	struct us_port_data *port;
+	uint32_t *p_mem_handle = NULL;
+
+	if ((usc == NULL) ||
+	    !(usc->session))
+		return;
+
+	for (loopcnt = 0; loopcnt <= OUT; ++loopcnt) {
+		port = &usc->port[loopcnt];
+		if (port->data == NULL)
+			continue;
+		pr_debug("%s: loopcnt = %d\n", __func__, loopcnt);
+		q6usm_us_client_buf_free(loopcnt, usc);
+	}
+	q6usm_session_free(usc);
+	apr_deregister(usc->apr);
+
+	pr_debug("%s: APR De-Register\n", __func__);
+
+	if (atomic_read(&this_mmap.ref_cnt) <= 0) {
+		pr_err("%s: APR Common Port Already Closed\n", __func__);
+		goto done;
+	}
+
+	atomic_dec(&this_mmap.ref_cnt);
+	if (atomic_read(&this_mmap.ref_cnt) == 0) {
+		apr_deregister(this_mmap.apr);
+		pr_debug("%s: APR De-Register common port\n", __func__);
+	}
+
+done:
+	p_mem_handle = (uint32_t *)usc->port[IN].ext;
+	kfree(p_mem_handle);
+	kfree(usc);
+	pr_debug("%s:\n", __func__);
+	return;
+}
+
+struct us_client *q6usm_us_client_alloc(
+	void (*cb)(uint32_t, uint32_t, uint32_t *, void *),
+	void *priv)
+{
+	struct us_client *usc;
+	uint32_t *p_mem_handle = NULL;
+	int n;
+	int lcnt = 0;
+
+	usc = kzalloc(sizeof(struct us_client), GFP_KERNEL);
+	if (usc == NULL) {
+		pr_err("%s: us_client allocation failed\n", __func__);
+		return NULL;
+	}
+	p_mem_handle = kzalloc(sizeof(uint32_t) * 2, GFP_KERNEL);
+	if (p_mem_handle == NULL) {
+		pr_err("%s: p_mem_handle allocation failed\n", __func__);
+		kfree(usc);
+		return NULL;
+	}
+
+	n = q6usm_session_alloc(usc);
+	if (n <= 0)
+		goto fail_session;
+	usc->session = n;
+	usc->cb = cb;
+	usc->priv = priv;
+	usc->apr = apr_register("ADSP", "USM", \
+				(apr_fn)q6usm_callback,\
+				((usc->session) << 8 | 0x0001),\
+				usc);
+
+	if (usc->apr == NULL) {
+		pr_err("%s: Registration with APR failed\n", __func__);
+		goto fail;
+	}
+	pr_debug("%s: Registering the common port with APR\n", __func__);
+	if (atomic_read(&this_mmap.ref_cnt) == 0) {
+		this_mmap.apr = apr_register("ADSP", "USM",
+					     (apr_fn)q6usm_mmapcallback,
+					     0x0FFFFFFFF, &this_mmap);
+		if (this_mmap.apr == NULL) {
+			pr_err("%s: USM port registration failed\n",
+			       __func__);
+			goto fail;
+		}
+	}
+
+	atomic_inc(&this_mmap.ref_cnt);
+	init_waitqueue_head(&usc->cmd_wait);
+	mutex_init(&usc->cmd_lock);
+	for (lcnt = 0; lcnt <= OUT; ++lcnt) {
+		mutex_init(&usc->port[lcnt].lock);
+		spin_lock_init(&usc->port[lcnt].dsp_lock);
+		usc->port[lcnt].ext = (void *)p_mem_handle++;
+		pr_err("%s: usc->port[%d].ext=%p;\n",
+		       __func__, lcnt, usc->port[lcnt].ext);
+	}
+	atomic_set(&usc->cmd_state, 0);
+
+	return usc;
+fail:
+	kfree(p_mem_handle);
+	q6usm_us_client_free(usc);
+	return NULL;
+fail_session:
+	kfree(p_mem_handle);
+	kfree(usc);
+	return NULL;
+}
+
+int q6usm_us_client_buf_alloc(unsigned int dir,
+			      struct us_client *usc,
+			      unsigned int bufsz,
+			      unsigned int bufcnt)
+{
+	int rc = 0;
+	struct us_port_data *port = NULL;
+	unsigned int size = bufsz*bufcnt;
+
+	if ((usc == NULL) ||
+	    ((dir != IN) && (dir != OUT)) || (size == 0) ||
+	    (usc->session <= 0 || usc->session > SESSION_MAX)) {
+		pr_err("%s: wrong parameters: size=%d; bufcnt=%d\n",
+		       __func__, size, bufcnt);
+		return -EINVAL;
+	}
+
+	mutex_lock(&usc->cmd_lock);
+
+	port = &usc->port[dir];
+
+	port->data = dma_alloc_coherent(NULL, size, &(port->phys), GFP_KERNEL);
+	if (port->data == NULL) {
+		pr_err("%s: US region allocation failed\n", __func__);
+		mutex_unlock(&usc->cmd_lock);
+		return -ENOMEM;
+	}
+
+	port->buf_cnt = bufcnt;
+	port->buf_size = bufsz;
+	pr_debug("%s: data[%p]; phys[%p]; [%p]\n", __func__,
+		 (void *)port->data,
+		 (void *)port->phys,
+		 (void *)&port->phys);
+
+	size = (size + MEM_4K_OFFSET) & MEM_4K_MASK;
+	rc = q6usm_memory_map(usc, port->phys, dir, size, 1);
+	if (rc < 0) {
+		pr_err("%s: CMD Memory_map failed\n", __func__);
+		mutex_unlock(&usc->cmd_lock);
+		q6usm_us_client_buf_free(dir, usc);
+	} else {
+		mutex_unlock(&usc->cmd_lock);
+		rc = 0;
+	}
+
+	return rc;
+}
+
+static int32_t q6usm_mmapcallback(struct apr_client_data *data, void *priv)
+{
+	uint32_t token;
+	uint32_t *payload = data->payload;
+
+	pr_debug("%s: ptr0[0x%x]; ptr1[0x%x]; opcode[0x%x]\n",
+		 __func__, payload[0], payload[1], data->opcode);
+	pr_debug("%s: token[0x%x]; payload_size[%d]; src[%d]; dest[%d];\n",
+		 __func__, data->token, data->payload_size,
+		 data->src_port, data->dest_port);
+
+	if (data->opcode == APR_BASIC_RSP_RESULT) {
+		/* status field check */
+		if (payload[1]) {
+			pr_err("%s: wrong response[%d] on cmd [%d]\n",
+			       __func__, payload[1], payload[0]);
+		} else {
+			token = data->token;
+			switch (payload[0]) {
+			case USM_CMD_SHARED_MEM_UNMAP_REGION:
+				if (atomic_read(&this_mmap.cmd_state)) {
+					atomic_set(&this_mmap.cmd_state, 0);
+					wake_up(&this_mmap.cmd_wait);
+				}
+			case USM_CMD_SHARED_MEM_MAP_REGION:
+				/* For MEM_MAP, additional answer is waited, */
+				/* therfore, no wake-up here */
+				pr_debug("%s: cmd[0x%x]; result[0x%x]\n",
+					 __func__, payload[0], payload[1]);
+				break;
+			default:
+				pr_debug("%s: wrong command[0x%x]\n",
+					 __func__, payload[0]);
+				break;
+			}
+		}
+	} else {
+		if (data->opcode == USM_CMDRSP_SHARED_MEM_MAP_REGION) {
+			this_mmap.mem_handle = payload[0];
+			pr_debug("%s: memory map handle = 0x%x",
+				__func__, payload[0]);
+			if (atomic_read(&this_mmap.cmd_state)) {
+				atomic_set(&this_mmap.cmd_state, 0);
+				wake_up(&this_mmap.cmd_wait);
+			}
+		}
+	}
+	return 0;
+}
+
+
+static int32_t q6usm_callback(struct apr_client_data *data, void *priv)
+{
+	struct us_client *usc = (struct us_client *)priv;
+	unsigned long dsp_flags;
+	uint32_t *payload = data->payload;
+	uint32_t token = data->token;
+	uint32_t opcode = Q6USM_EVENT_UNDEF;
+
+	if (usc == NULL) {
+		pr_err("%s: client info is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	if (data->opcode == APR_BASIC_RSP_RESULT) {
+		/* status field check */
+		if (payload[1]) {
+			pr_err("%s: wrong response[%d] on cmd [%d]\n",
+			       __func__, payload[1], payload[0]);
+			if (usc->cb)
+				usc->cb(data->opcode, token,
+					(uint32_t *)data->payload, usc->priv);
+		} else {
+			switch (payload[0]) {
+			case USM_SESSION_CMD_RUN:
+			case USM_STREAM_CMD_CLOSE:
+				if (token != usc->session) {
+					pr_err("%s: wrong token[%d]",
+					       __func__, token);
+					break;
+				}
+			case USM_STREAM_CMD_OPEN_READ:
+			case USM_STREAM_CMD_OPEN_WRITE:
+			case USM_STREAM_CMD_SET_ENC_PARAM:
+			case USM_DATA_CMD_MEDIA_FORMAT_UPDATE:
+			case USM_SESSION_CMD_SIGNAL_DETECT_MODE:
+				if (atomic_read(&usc->cmd_state)) {
+					atomic_set(&usc->cmd_state, 0);
+					wake_up(&usc->cmd_wait);
+				}
+				if (usc->cb)
+					usc->cb(data->opcode, token,
+						(uint32_t *)data->payload,
+						usc->priv);
+				break;
+			default:
+				break;
+			}
+		}
+		return 0;
+	}
+
+	switch (data->opcode) {
+	case USM_DATA_EVENT_READ_DONE: {
+		struct us_port_data *port = &usc->port[OUT];
+
+		opcode = Q6USM_EVENT_READ_DONE;
+		spin_lock_irqsave(&port->dsp_lock, dsp_flags);
+		if (payload[READDONE_IDX_STATUS]) {
+			pr_err("%s: wrong READDONE[%d]; token[%d]\n",
+			       __func__,
+			       payload[READDONE_IDX_STATUS],
+			       token);
+			token = USM_WRONG_TOKEN;
+			spin_unlock_irqrestore(&port->dsp_lock,
+					       dsp_flags);
+			break;
+		}
+
+		if (port->expected_token != token) {
+			u32 cpu_buf = port->cpu_buf;
+			pr_err("%s: expected[%d] != token[%d]\n",
+				__func__, port->expected_token, token);
+			pr_debug("%s: dsp_buf=%d; cpu_buf=%d;\n",
+				__func__,   port->dsp_buf, cpu_buf);
+
+			token = USM_WRONG_TOKEN;
+			/* To prevent data handle continiue */
+			port->expected_token = USM_WRONG_TOKEN;
+			spin_unlock_irqrestore(&port->dsp_lock,
+					       dsp_flags);
+			break;
+		} /* port->expected_token != data->token */
+
+		port->expected_token = token + 1;
+		if (port->expected_token == port->buf_cnt)
+			port->expected_token = 0;
+
+		/* gap support */
+		if (port->expected_token != port->cpu_buf) {
+			port->dsp_buf = port->expected_token;
+			token = port->dsp_buf; /* for callback */
+		} else
+			port->dsp_buf = token;
+
+		spin_unlock_irqrestore(&port->dsp_lock, dsp_flags);
+		break;
+	} /* case USM_DATA_EVENT_READ_DONE */
+
+	case USM_DATA_EVENT_WRITE_DONE: {
+		struct us_port_data *port = &usc->port[IN];
+
+		opcode = Q6USM_EVENT_WRITE_DONE;
+		if (payload[WRITEDONE_IDX_STATUS]) {
+			pr_err("%s: wrong WRITEDONE_IDX_STATUS[%d]\n",
+			       __func__,
+			       payload[WRITEDONE_IDX_STATUS]);
+			break;
+		}
+
+		spin_lock_irqsave(&port->dsp_lock, dsp_flags);
+		port->dsp_buf = token + 1;
+		if (port->dsp_buf == port->buf_cnt)
+			port->dsp_buf = 0;
+		spin_unlock_irqrestore(&port->dsp_lock, dsp_flags);
+
+		break;
+	} /* case USM_DATA_EVENT_WRITE_DONE */
+
+	case USM_SESSION_EVENT_SIGNAL_DETECT_RESULT: {
+		pr_debug("%s: US detect result: result=%d",
+			 __func__,
+			 payload[0]);
+		opcode = Q6USM_EVENT_SIGNAL_DETECT_RESULT;
+
+		break;
+	} /* case USM_SESSION_EVENT_SIGNAL_DETECT_RESULT */
+
+	default:
+		return 0;
+
+	} /* switch */
+
+	if (usc->cb)
+		usc->cb(opcode, token,
+			data->payload, usc->priv);
+
+	return 0;
+}
+
+uint32_t q6usm_get_virtual_address(int dir,
+				   struct us_client *usc,
+				   struct vm_area_struct *vms)
+{
+	uint32_t ret = 0xffffffff;
+
+	if (vms && (usc != NULL) && ((dir == IN) || (dir == OUT))) {
+		struct us_port_data *port = &usc->port[dir];
+		int size = (port->buf_size * port->buf_cnt + MEM_4K_OFFSET)
+								& MEM_4K_MASK;
+
+		ret = dma_mmap_coherent(NULL, vms,
+					port->data, port->phys,
+					size);
+	}
+	return ret;
+}
+
+static void q6usm_add_hdr(struct us_client *usc, struct apr_hdr *hdr,
+			  uint32_t pkt_size, bool cmd_flg)
+{
+	mutex_lock(&usc->cmd_lock);
+	hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, \
+				       APR_HDR_LEN(sizeof(struct apr_hdr)),\
+				       APR_PKT_VER);
+	hdr->src_svc = ((struct apr_svc *)usc->apr)->id;
+	hdr->src_domain = APR_DOMAIN_APPS;
+	hdr->dest_svc = APR_SVC_USM;
+	hdr->dest_domain = APR_DOMAIN_ADSP;
+	hdr->src_port = (usc->session << 8) | 0x0001;
+	hdr->dest_port = (usc->session << 8) | 0x0001;
+	if (cmd_flg) {
+		hdr->token = usc->session;
+		atomic_set(&usc->cmd_state, 1);
+	}
+	hdr->pkt_size  = APR_PKT_SIZE(APR_HDR_SIZE, pkt_size);
+	mutex_unlock(&usc->cmd_lock);
+	return;
+}
+
+static uint32_t q6usm_ext2int_format(uint32_t ext_format)
+{
+	uint32_t int_format = INVALID_FORMAT;
+	switch (ext_format) {
+	case FORMAT_USPS_EPOS:
+		int_format = US_POINT_EPOS_FORMAT;
+		break;
+	case FORMAT_USRAW:
+		int_format = US_RAW_FORMAT;
+		break;
+	case FORMAT_USPROX:
+		int_format = US_PROX_FORMAT;
+		break;
+	default:
+		pr_err("%s: Invalid format[%d]\n", __func__, ext_format);
+		break;
+	}
+
+	return int_format;
+}
+
+int q6usm_open_read(struct us_client *usc,
+		    uint32_t format)
+{
+	uint32_t int_format = INVALID_FORMAT;
+	int rc = 0x00;
+	struct usm_stream_cmd_open_read open;
+
+	pr_debug("%s: session[%d]", __func__, usc->session);
+
+	if ((usc == NULL) || (usc->apr == NULL)) {
+		pr_err("%s: client or its apr is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	q6usm_add_hdr(usc, &open.hdr, sizeof(open), true);
+	open.hdr.opcode = USM_STREAM_CMD_OPEN_READ;
+	open.src_endpoint = 0; /* AFE */
+	open.pre_proc_top = 0; /* No preprocessing required */
+
+	int_format = q6usm_ext2int_format(format);
+	if (int_format == INVALID_FORMAT)
+		return -EINVAL;
+
+	open.uMode = STREAM_PRIORITY_NORMAL;
+	open.format = int_format;
+
+	rc = apr_send_pkt(usc->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(usc->cmd_wait,
+				(atomic_read(&usc->cmd_state) == 0),
+				Q6USM_TIMEOUT_JIFFIES);
+	if (!rc) {
+		rc = -ETIME;
+		pr_err("%s: timeout, waited for OPEN_READ rc[%d]\n",
+		       __func__, rc);
+		goto fail_cmd;
+	} else
+		rc = 0;
+fail_cmd:
+	return rc;
+}
+
+
+int q6usm_enc_cfg_blk(struct us_client *usc, struct us_encdec_cfg *us_cfg)
+{
+	uint32_t int_format = INVALID_FORMAT;
+	struct usm_stream_cmd_encdec_cfg_blk  enc_cfg_obj;
+	struct usm_stream_cmd_encdec_cfg_blk  *enc_cfg = &enc_cfg_obj;
+	int rc = 0;
+	uint32_t total_cfg_size =
+		sizeof(struct usm_stream_cmd_encdec_cfg_blk);
+	uint32_t round_params_size = 0;
+	uint8_t  is_allocated = 0;
+
+
+	if ((usc == NULL) || (us_cfg == NULL)) {
+		pr_err("%s: wrong input", __func__);
+		return -EINVAL;
+	}
+
+	int_format = q6usm_ext2int_format(us_cfg->format_id);
+	if (int_format == INVALID_FORMAT) {
+		pr_err("%s: wrong input format[%d]",
+		       __func__, us_cfg->format_id);
+		return -EINVAL;
+	}
+
+	/* Transparent configuration data is after enc_cfg */
+	/* Integer number of u32s is requred */
+	round_params_size = ((us_cfg->params_size + 3)/4) * 4;
+	if (round_params_size > USM_MAX_CFG_DATA_SIZE) {
+		/* Dynamic allocated encdec_cfg_blk is required */
+		/* static part use */
+		round_params_size -= USM_MAX_CFG_DATA_SIZE;
+		total_cfg_size += round_params_size;
+		enc_cfg = kzalloc(total_cfg_size, GFP_KERNEL);
+		if (enc_cfg == NULL) {
+			pr_err("%s: enc_cfg[%d] allocation failed\n",
+			       __func__, total_cfg_size);
+			return -ENOMEM;
+		}
+		is_allocated = 1;
+	} else
+		round_params_size = 0;
+
+	q6usm_add_hdr(usc, &enc_cfg->hdr, total_cfg_size - APR_HDR_SIZE, true);
+
+	enc_cfg->hdr.opcode = USM_STREAM_CMD_SET_ENC_PARAM;
+	enc_cfg->param_id = USM_PARAM_ID_ENCDEC_ENC_CFG_BLK;
+	enc_cfg->param_size = sizeof(struct usm_encode_cfg_blk)+
+				round_params_size;
+	enc_cfg->enc_blk.frames_per_buf = 1;
+	enc_cfg->enc_blk.format_id = int_format;
+	enc_cfg->enc_blk.cfg_size = sizeof(struct usm_cfg_common)+
+				    USM_MAX_CFG_DATA_SIZE +
+				    round_params_size;
+	memcpy(&(enc_cfg->enc_blk.cfg_common), &(us_cfg->cfg_common),
+	       sizeof(struct usm_cfg_common));
+
+	/* Transparent data copy */
+	memcpy(enc_cfg->enc_blk.transp_data, us_cfg->params,
+	       us_cfg->params_size);
+	pr_debug("%s: cfg_size[%d], params_size[%d]\n",
+		__func__,
+		enc_cfg->enc_blk.cfg_size,
+		us_cfg->params_size);
+	pr_debug("%s: params[%d,%d,%d,%d, %d,%d,%d,%d]\n",
+		__func__,
+		enc_cfg->enc_blk.transp_data[0],
+		enc_cfg->enc_blk.transp_data[1],
+		enc_cfg->enc_blk.transp_data[2],
+		enc_cfg->enc_blk.transp_data[3],
+		enc_cfg->enc_blk.transp_data[4],
+		enc_cfg->enc_blk.transp_data[5],
+		enc_cfg->enc_blk.transp_data[6],
+		enc_cfg->enc_blk.transp_data[7]
+	       );
+	pr_debug("%s: srate:%d, ch=%d, bps= %d; dmap:0x%x; dev_id=0x%x\n",
+		__func__, enc_cfg->enc_blk.cfg_common.sample_rate,
+		enc_cfg->enc_blk.cfg_common.ch_cfg,
+		enc_cfg->enc_blk.cfg_common.bits_per_sample,
+		enc_cfg->enc_blk.cfg_common.data_map,
+		enc_cfg->enc_blk.cfg_common.dev_id);
+
+	rc = apr_send_pkt(usc->apr, (uint32_t *) enc_cfg);
+	if (rc < 0) {
+		pr_err("%s:Comamnd open failed\n", __func__);
+		rc = -EINVAL;
+		goto fail_cmd;
+	}
+	rc = wait_event_timeout(usc->cmd_wait,
+				(atomic_read(&usc->cmd_state) == 0),
+				Q6USM_TIMEOUT_JIFFIES);
+	if (!rc) {
+		rc = -ETIME;
+		pr_err("%s: timeout opcode[0x%x]\n",
+		       __func__, enc_cfg->hdr.opcode);
+	} else
+		rc = 0;
+
+fail_cmd:
+	if (is_allocated == 1)
+		kfree(enc_cfg);
+
+	return rc;
+}
+
+int q6usm_dec_cfg_blk(struct us_client *usc, struct us_encdec_cfg *us_cfg)
+{
+
+	uint32_t int_format = INVALID_FORMAT;
+	struct usm_stream_media_format_update dec_cfg_obj;
+	struct usm_stream_media_format_update *dec_cfg = &dec_cfg_obj;
+
+	int rc = 0;
+	uint32_t total_cfg_size = sizeof(struct usm_stream_media_format_update);
+	uint32_t round_params_size = 0;
+	uint8_t  is_allocated = 0;
+
+
+	if ((usc == NULL) || (us_cfg == NULL)) {
+		pr_err("%s: wrong input", __func__);
+		return -EINVAL;
+	}
+
+	int_format = q6usm_ext2int_format(us_cfg->format_id);
+	if (int_format == INVALID_FORMAT) {
+		pr_err("%s: wrong input format[%d]",
+		       __func__, us_cfg->format_id);
+		return -EINVAL;
+	}
+
+	/* Transparent configuration data is after enc_cfg */
+	/* Integer number of u32s is requred */
+	round_params_size = ((us_cfg->params_size + 3)/4) * 4;
+	if (round_params_size > USM_MAX_CFG_DATA_SIZE) {
+		/* Dynamic allocated encdec_cfg_blk is required */
+		/* static part use */
+		round_params_size -= USM_MAX_CFG_DATA_SIZE;
+		total_cfg_size += round_params_size;
+		dec_cfg = kzalloc(total_cfg_size, GFP_KERNEL);
+		if (dec_cfg == NULL) {
+			pr_err("%s:dec_cfg[%d] allocation failed\n",
+			       __func__, total_cfg_size);
+			return -ENOMEM;
+		}
+		is_allocated = 1;
+	} else { /* static transp_data is enough */
+		round_params_size = 0;
+	}
+
+	q6usm_add_hdr(usc, &dec_cfg->hdr, total_cfg_size - APR_HDR_SIZE, true);
+
+	dec_cfg->hdr.opcode = USM_DATA_CMD_MEDIA_FORMAT_UPDATE;
+	dec_cfg->format_id = int_format;
+	dec_cfg->cfg_size = sizeof(struct usm_cfg_common) +
+			    USM_MAX_CFG_DATA_SIZE +
+			    round_params_size;
+	memcpy(&(dec_cfg->cfg_common), &(us_cfg->cfg_common),
+	       sizeof(struct usm_cfg_common));
+	/* Transparent data copy */
+	memcpy(dec_cfg->transp_data, us_cfg->params, us_cfg->params_size);
+	pr_debug("%s: cfg_size[%d], params_size[%d]; parambytes[%d,%d,%d,%d]\n",
+		__func__,
+		dec_cfg->cfg_size,
+		us_cfg->params_size,
+		dec_cfg->transp_data[0],
+		dec_cfg->transp_data[1],
+		dec_cfg->transp_data[2],
+		dec_cfg->transp_data[3]
+	       );
+
+	rc = apr_send_pkt(usc->apr, (uint32_t *) dec_cfg);
+	if (rc < 0) {
+		pr_err("%s:Comamnd open failed\n", __func__);
+		rc = -EINVAL;
+		goto fail_cmd;
+	}
+	rc = wait_event_timeout(usc->cmd_wait,
+				(atomic_read(&usc->cmd_state) == 0),
+				Q6USM_TIMEOUT_JIFFIES);
+	if (!rc) {
+		rc = -ETIME;
+		pr_err("%s: timeout opcode[0x%x]\n",
+		       __func__, dec_cfg->hdr.opcode);
+	} else
+		rc = 0;
+
+fail_cmd:
+	if (is_allocated == 1)
+		kfree(dec_cfg);
+
+	return rc;
+}
+
+int q6usm_open_write(struct us_client *usc,
+		     uint32_t format)
+{
+	int rc = 0;
+	uint32_t int_format = INVALID_FORMAT;
+	struct usm_stream_cmd_open_write open;
+
+	pr_debug("%s: session[%d]", __func__, usc->session);
+
+	if ((usc == NULL) || (usc->apr == NULL)) {
+		pr_err("%s: APR handle NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	q6usm_add_hdr(usc, &open.hdr, sizeof(open), true);
+	open.hdr.opcode = USM_STREAM_CMD_OPEN_WRITE;
+
+	int_format = q6usm_ext2int_format(format);
+	if (int_format == INVALID_FORMAT) {
+		pr_err("%s: wrong format[%d]", __func__, format);
+		return -EINVAL;
+	}
+
+	open.format = int_format;
+
+	rc = apr_send_pkt(usc->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(usc->cmd_wait,
+				(atomic_read(&usc->cmd_state) == 0),
+				Q6USM_TIMEOUT_JIFFIES);
+	if (!rc) {
+		rc = -ETIME;
+		pr_err("%s:timeout. waited for OPEN_WRITR rc[%d]\n",
+		       __func__, rc);
+		goto fail_cmd;
+	} else
+		rc = 0;
+
+fail_cmd:
+	return rc;
+}
+
+int q6usm_run(struct us_client *usc, uint32_t flags,
+	      uint32_t msw_ts, uint32_t lsw_ts)
+{
+	struct usm_stream_cmd_run run;
+	int rc = 0;
+
+	if ((usc == NULL) || (usc->apr == NULL)) {
+		pr_err("%s: APR handle NULL\n", __func__);
+		return -EINVAL;
+	}
+	q6usm_add_hdr(usc, &run.hdr, sizeof(run), true);
+
+	run.hdr.opcode = USM_SESSION_CMD_RUN;
+	run.flags    = flags;
+	run.msw_ts   = msw_ts;
+	run.lsw_ts   = lsw_ts;
+
+	rc = apr_send_pkt(usc->apr, (uint32_t *) &run);
+	if (rc < 0) {
+		pr_err("%s: Commmand run failed[%d]\n", __func__, rc);
+		goto fail_cmd;
+	}
+
+	rc = wait_event_timeout(usc->cmd_wait,
+				(atomic_read(&usc->cmd_state) == 0),
+				Q6USM_TIMEOUT_JIFFIES);
+	if (!rc) {
+		rc = -ETIME;
+		pr_err("%s: timeout. waited for run success rc[%d]\n",
+		       __func__, rc);
+	} else
+		rc = 0;
+
+fail_cmd:
+	return rc;
+}
+
+
+
+int q6usm_read(struct us_client *usc, uint32_t read_ind)
+{
+	struct usm_stream_cmd_read read;
+	struct us_port_data *port = NULL;
+	int rc = 0;
+	u32 read_counter = 0;
+	u32 loop_ind = 0;
+
+	if ((usc == NULL) || (usc->apr == NULL)) {
+		pr_err("%s: APR handle NULL\n", __func__);
+		return -EINVAL;
+	}
+	port = &usc->port[OUT];
+
+	if (read_ind > port->buf_cnt) {
+		pr_err("%s: wrong read_ind[%d]\n",
+		       __func__, read_ind);
+		return -EINVAL;
+	}
+	if (read_ind == port->cpu_buf) {
+		pr_err("%s: no free region\n", __func__);
+		return 0;
+	}
+
+	if (read_ind > port->cpu_buf) { /* 1 range */
+		read_counter = read_ind - port->cpu_buf;
+	} else { /* 2 ranges */
+		read_counter = (port->buf_cnt - port->cpu_buf) + read_ind;
+	}
+
+	q6usm_add_hdr(usc, &read.hdr, (sizeof(read) - APR_HDR_SIZE), false);
+
+	read.hdr.opcode = USM_DATA_CMD_READ;
+	read.buf_size = port->buf_size;
+	read.buf_addr_msw = 0;
+	read.mem_map_handle = *((uint32_t *)(port->ext));
+
+	for (loop_ind = 0; loop_ind < read_counter; ++loop_ind) {
+		u32 temp_cpu_buf = port->cpu_buf;
+
+		read.buf_addr_lsw = (uint32_t)(port->phys) +
+			       port->buf_size * (port->cpu_buf);
+		read.seq_id = port->cpu_buf;
+		read.hdr.token = port->cpu_buf;
+		read.counter = 1;
+
+		++(port->cpu_buf);
+		if (port->cpu_buf == port->buf_cnt)
+			port->cpu_buf = 0;
+
+		rc = apr_send_pkt(usc->apr, (uint32_t *) &read);
+
+		if (rc < 0) {
+			port->cpu_buf = temp_cpu_buf;
+
+			pr_err("%s:read op[0x%x]rc[%d]\n",
+			       __func__, read.hdr.opcode, rc);
+			break;
+		} else
+			rc = 0;
+	} /* bufs loop */
+
+	return rc;
+}
+
+int q6usm_write(struct us_client *usc, uint32_t write_ind)
+{
+	int rc = 0;
+	struct usm_stream_cmd_write cmd_write;
+	struct us_port_data *port = NULL;
+	u32 current_dsp_buf = 0;
+
+	if ((usc == NULL) || (usc->apr == NULL)) {
+		pr_err("%s: APR handle NULL\n", __func__);
+		return -EINVAL;
+	}
+	port = &usc->port[IN];
+
+	current_dsp_buf = port->dsp_buf;
+	/* free region, caused by new dsp_buf report from DSP, */
+	/* can be only extended */
+	if (port->cpu_buf >= current_dsp_buf) {
+		/* 2 -part free region, including empty buffer */
+		if ((write_ind <= port->cpu_buf)  &&
+		    (write_ind > current_dsp_buf)) {
+			pr_err("%s: wrong w_ind[%d]; d_buf=%d; c_buf=%d\n",
+			       __func__, write_ind,
+			       current_dsp_buf, port->cpu_buf);
+			return -EINVAL;
+		}
+	} else {
+		/* 1 -part free region */
+		if ((write_ind <= port->cpu_buf)  ||
+		    (write_ind > current_dsp_buf)) {
+			pr_err("%s: wrong w_ind[%d]; d_buf=%d; c_buf=%d\n",
+			       __func__, write_ind,
+			       current_dsp_buf, port->cpu_buf);
+			return -EINVAL;
+		}
+	}
+
+	q6usm_add_hdr(usc, &cmd_write.hdr,
+		      (sizeof(cmd_write) - APR_HDR_SIZE), false);
+
+	cmd_write.hdr.opcode = USM_DATA_CMD_WRITE;
+	cmd_write.buf_size = port->buf_size;
+	cmd_write.buf_addr_msw = 0;
+	cmd_write.mem_map_handle = *((uint32_t *)(port->ext));
+	cmd_write.res0 = 0;
+	cmd_write.res1 = 0;
+	cmd_write.res2 = 0;
+
+	while (port->cpu_buf != write_ind) {
+		u32 temp_cpu_buf = port->cpu_buf;
+
+		cmd_write.buf_addr_lsw = (uint32_t)(port->phys) +
+				    port->buf_size * (port->cpu_buf);
+		cmd_write.seq_id = port->cpu_buf;
+		cmd_write.hdr.token = port->cpu_buf;
+
+		++(port->cpu_buf);
+		if (port->cpu_buf == port->buf_cnt)
+			port->cpu_buf = 0;
+
+		rc = apr_send_pkt(usc->apr, (uint32_t *) &cmd_write);
+
+		if (rc < 0) {
+			port->cpu_buf = temp_cpu_buf;
+			pr_err("%s:write op[0x%x];rc[%d];cpu_buf[%d]\n",
+			       __func__, cmd_write.hdr.opcode,
+			       rc, port->cpu_buf);
+			break;
+		}
+
+		rc = 0;
+	}
+
+	return rc;
+}
+
+bool q6usm_is_write_buf_full(struct us_client *usc, uint32_t *free_region)
+{
+	struct us_port_data *port = NULL;
+	u32 cpu_buf = 0;
+
+	if ((usc == NULL) || !free_region) {
+		pr_err("%s: input data wrong\n", __func__);
+		return false;
+	}
+	port = &usc->port[IN];
+	cpu_buf = port->cpu_buf + 1;
+	if (cpu_buf == port->buf_cnt)
+		cpu_buf = 0;
+
+	*free_region = port->dsp_buf;
+
+	return cpu_buf == *free_region;
+}
+
+int q6usm_cmd(struct us_client *usc, int cmd)
+{
+	struct apr_hdr hdr;
+	int rc = 0;
+	atomic_t *state;
+
+	if ((usc == NULL) || (usc->apr == NULL)) {
+		pr_err("%s: APR handle NULL\n", __func__);
+		return -EINVAL;
+	}
+	q6usm_add_hdr(usc, &hdr, (sizeof(hdr) - APR_HDR_SIZE), true);
+	switch (cmd) {
+	case CMD_CLOSE:
+		hdr.opcode = USM_STREAM_CMD_CLOSE;
+		state = &usc->cmd_state;
+		break;
+
+	default:
+		pr_err("%s:Invalid format[%d]\n", __func__, cmd);
+		goto fail_cmd;
+	}
+
+	rc = apr_send_pkt(usc->apr, (uint32_t *) &hdr);
+	if (rc < 0) {
+		pr_err("%s: Command 0x%x failed\n", __func__, hdr.opcode);
+		goto fail_cmd;
+	}
+	rc = wait_event_timeout(usc->cmd_wait, (atomic_read(state) == 0),
+				Q6USM_TIMEOUT_JIFFIES);
+	if (!rc) {
+		rc = -ETIME;
+		pr_err("%s:timeout. waited for response opcode[0x%x]\n",
+		       __func__, hdr.opcode);
+	} else
+		rc = 0;
+fail_cmd:
+	return rc;
+}
+
+int q6usm_set_us_detection(struct us_client *usc,
+			   struct usm_session_cmd_detect_info *detect_info,
+			   uint16_t detect_info_size)
+{
+	int rc = 0;
+
+	if ((usc == NULL) ||
+	    (detect_info_size == 0) ||
+	    (detect_info == NULL)) {
+		pr_err("%s: wrong input: usc=0x%p, inf_size=%d; info=0x%p",
+		       __func__,
+		       usc,
+		       detect_info_size,
+		       detect_info);
+		return -EINVAL;
+	}
+
+	q6usm_add_hdr(usc, &detect_info->hdr,
+		      detect_info_size - APR_HDR_SIZE, true);
+
+	detect_info->hdr.opcode = USM_SESSION_CMD_SIGNAL_DETECT_MODE;
+
+	rc = apr_send_pkt(usc->apr, (uint32_t *)detect_info);
+	if (rc < 0) {
+		pr_err("%s:Comamnd signal detect failed\n", __func__);
+		return -EINVAL;
+	}
+	rc = wait_event_timeout(usc->cmd_wait,
+				(atomic_read(&usc->cmd_state) == 0),
+				Q6USM_TIMEOUT_JIFFIES);
+	if (!rc) {
+		rc = -ETIME;
+		pr_err("%s: CMD_SIGNAL_DETECT_MODE: timeout=%d\n",
+		       __func__, Q6USM_TIMEOUT_JIFFIES);
+	} else
+		rc = 0;
+
+	return rc;
+}
+
+static int __init q6usm_init(void)
+{
+	pr_debug("%s\n", __func__);
+	init_waitqueue_head(&this_mmap.cmd_wait);
+	memset(session, 0, sizeof(session));
+	return 0;
+}
+
+device_initcall(q6usm_init);
diff --git a/arch/arm/mach-msm/ramdump.c b/arch/arm/mach-msm/ramdump.c
index aac49d0..7f09a56 100644
--- a/arch/arm/mach-msm/ramdump.c
+++ b/arch/arm/mach-msm/ramdump.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
@@ -104,6 +104,7 @@
 	unsigned long addr = 0;
 	size_t copy_size = 0;
 	int ret = 0;
+	loff_t orig_pos = *pos;
 
 	if ((filep->f_flags & O_NONBLOCK) && !rd_dev->data_ready)
 		return -EAGAIN;
@@ -113,9 +114,10 @@
 		return ret;
 
 	if (*pos < rd_dev->elfcore_size) {
-		copy_size = min(rd_dev->elfcore_size, count);
+		copy_size = rd_dev->elfcore_size - *pos;
+		copy_size = min(copy_size, count);
 
-		if (copy_to_user(buf, rd_dev->elfcore_buf, copy_size)) {
+		if (copy_to_user(buf, rd_dev->elfcore_buf + *pos, copy_size)) {
 			ret = -EFAULT;
 			goto ramdump_done;
 		}
@@ -165,7 +167,7 @@
 	pr_debug("Ramdump(%s): Read %d bytes from address %lx.",
 			rd_dev->name, copy_size, addr);
 
-	return copy_size;
+	return *pos - orig_pos;
 
 ramdump_done:
 	rd_dev->data_ready = 0;
diff --git a/arch/arm/mach-msm/ramdump.h b/arch/arm/mach-msm/ramdump.h
index 5fb41ec..e43ca12 100644
--- a/arch/arm/mach-msm/ramdump.h
+++ b/arch/arm/mach-msm/ramdump.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/remote_spinlock.c b/arch/arm/mach-msm/remote_spinlock.c
index 2480433..94923a0 100644
--- a/arch/arm/mach-msm/remote_spinlock.c
+++ b/arch/arm/mach-msm/remote_spinlock.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
@@ -15,6 +15,10 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 
 #include <asm/system.h>
 
@@ -22,68 +26,478 @@
 #include <mach/remote_spinlock.h>
 #include <mach/dal.h>
 #include "smd_private.h"
-#include <linux/module.h>
 
-static void remote_spin_release_all_locks(uint32_t pid, int count);
 
-#if defined(CONFIG_MSM_REMOTE_SPINLOCK_SFPB)
+#define SPINLOCK_PID_APPS 1
+
+#define AUTO_MODE -1
+#define DEKKERS_MODE 1
+#define SWP_MODE 2
+#define LDREX_MODE 3
+#define SFPB_MODE 4
+
+#if defined(CONFIG_MSM_REMOTE_SPINLOCK_DEKKERS) ||\
+		defined(CONFIG_MSM_REMOTE_SPINLOCK_SWP) ||\
+		defined(CONFIG_MSM_REMOTE_SPINLOCK_LDREX) ||\
+		defined(CONFIG_MSM_REMOTE_SPINLOCK_SFPB)
+
+#ifdef CONFIG_MSM_REMOTE_SPINLOCK_DEKKERS
+/*
+ * Use Dekker's algorithm when LDREX/STREX and SWP are unavailable for
+ * shared memory
+ */
+#define CURRENT_MODE_INIT DEKKERS_MODE;
+#endif
+
+#ifdef CONFIG_MSM_REMOTE_SPINLOCK_SWP
+/* Use SWP-based locks when LDREX/STREX are unavailable for shared memory. */
+#define CURRENT_MODE_INIT SWP_MODE;
+#endif
+
+#ifdef CONFIG_MSM_REMOTE_SPINLOCK_LDREX
+/* Use LDREX/STREX for shared memory locking, when available */
+#define CURRENT_MODE_INIT LDREX_MODE;
+#endif
+
+#ifdef CONFIG_MSM_REMOTE_SPINLOCK_SFPB
+/* Use SFPB Hardware Mutex Registers */
+#define CURRENT_MODE_INIT SFPB_MODE;
+#endif
+
+#else
+/* Use DT info to configure with a fallback to LDREX if DT is missing */
+#define CURRENT_MODE_INIT AUTO_MODE;
+#endif
+
+static int current_mode = CURRENT_MODE_INIT;
+
+static int is_hw_lock_type;
+static DEFINE_MUTEX(ops_init_lock);
+
+struct spinlock_ops {
+	void (*lock)(raw_remote_spinlock_t *lock);
+	void (*unlock)(raw_remote_spinlock_t *lock);
+	int (*trylock)(raw_remote_spinlock_t *lock);
+	int (*release)(raw_remote_spinlock_t *lock, uint32_t pid);
+	int (*owner)(raw_remote_spinlock_t *lock);
+};
+
+static struct spinlock_ops current_ops;
+
+static int remote_spinlock_init_address(int id, _remote_spinlock_t *lock);
+
+/* dekkers implementation --------------------------------------------------- */
+#define DEK_LOCK_REQUEST		1
+#define DEK_LOCK_YIELD			(!DEK_LOCK_REQUEST)
+#define DEK_YIELD_TURN_SELF		0
+static void __raw_remote_dek_spin_lock(raw_remote_spinlock_t *lock)
+{
+	lock->dek.self_lock = DEK_LOCK_REQUEST;
+
+	while (lock->dek.other_lock) {
+
+		if (lock->dek.next_yield == DEK_YIELD_TURN_SELF)
+			lock->dek.self_lock = DEK_LOCK_YIELD;
+
+		while (lock->dek.other_lock)
+			;
+
+		lock->dek.self_lock = DEK_LOCK_REQUEST;
+	}
+	lock->dek.next_yield = DEK_YIELD_TURN_SELF;
+
+	smp_mb();
+}
+
+static int __raw_remote_dek_spin_trylock(raw_remote_spinlock_t *lock)
+{
+	lock->dek.self_lock = DEK_LOCK_REQUEST;
+
+	if (lock->dek.other_lock) {
+		lock->dek.self_lock = DEK_LOCK_YIELD;
+		return 0;
+	}
+
+	lock->dek.next_yield = DEK_YIELD_TURN_SELF;
+
+	smp_mb();
+	return 1;
+}
+
+static void __raw_remote_dek_spin_unlock(raw_remote_spinlock_t *lock)
+{
+	smp_mb();
+
+	lock->dek.self_lock = DEK_LOCK_YIELD;
+}
+
+static int __raw_remote_dek_spin_release(raw_remote_spinlock_t *lock,
+		uint32_t pid)
+{
+	return -EPERM;
+}
+
+static int __raw_remote_dek_spin_owner(raw_remote_spinlock_t *lock)
+{
+	return -EPERM;
+}
+/* end dekkers implementation ----------------------------------------------- */
+
+/* swp implementation ------------------------------------------------------- */
+static void __raw_remote_swp_spin_lock(raw_remote_spinlock_t *lock)
+{
+	unsigned long tmp;
+
+	__asm__ __volatile__(
+"1:     swp     %0, %2, [%1]\n"
+"       teq     %0, #0\n"
+"       bne     1b"
+	: "=&r" (tmp)
+	: "r" (&lock->lock), "r" (1)
+	: "cc");
+
+	smp_mb();
+}
+
+static int __raw_remote_swp_spin_trylock(raw_remote_spinlock_t *lock)
+{
+	unsigned long tmp;
+
+	__asm__ __volatile__(
+"       swp     %0, %2, [%1]\n"
+	: "=&r" (tmp)
+	: "r" (&lock->lock), "r" (1)
+	: "cc");
+
+	if (tmp == 0) {
+		smp_mb();
+		return 1;
+	}
+	return 0;
+}
+
+static void __raw_remote_swp_spin_unlock(raw_remote_spinlock_t *lock)
+{
+	int lock_owner;
+
+	smp_mb();
+	lock_owner = readl_relaxed(&lock->lock);
+	if (lock_owner != SPINLOCK_PID_APPS) {
+		pr_err("%s: spinlock not owned by Apps (actual owner is %d)\n",
+				__func__, lock_owner);
+	}
+
+	__asm__ __volatile__(
+"       str     %1, [%0]"
+	:
+	: "r" (&lock->lock), "r" (0)
+	: "cc");
+}
+/* end swp implementation --------------------------------------------------- */
+
+/* ldrex implementation ----------------------------------------------------- */
+static char *ldrex_compatible_string = "qcom,ipc-spinlock-ldrex";
+
+static void __raw_remote_ex_spin_lock(raw_remote_spinlock_t *lock)
+{
+	unsigned long tmp;
+
+	__asm__ __volatile__(
+"1:     ldrex   %0, [%1]\n"
+"       teq     %0, #0\n"
+"       strexeq %0, %2, [%1]\n"
+"       teqeq   %0, #0\n"
+"       bne     1b"
+	: "=&r" (tmp)
+	: "r" (&lock->lock), "r" (SPINLOCK_PID_APPS)
+	: "cc");
+
+	smp_mb();
+}
+
+static int __raw_remote_ex_spin_trylock(raw_remote_spinlock_t *lock)
+{
+	unsigned long tmp;
+
+	__asm__ __volatile__(
+"       ldrex   %0, [%1]\n"
+"       teq     %0, #0\n"
+"       strexeq %0, %2, [%1]\n"
+	: "=&r" (tmp)
+	: "r" (&lock->lock), "r" (SPINLOCK_PID_APPS)
+	: "cc");
+
+	if (tmp == 0) {
+		smp_mb();
+		return 1;
+	}
+	return 0;
+}
+
+static void __raw_remote_ex_spin_unlock(raw_remote_spinlock_t *lock)
+{
+	int lock_owner;
+
+	smp_mb();
+	lock_owner = readl_relaxed(&lock->lock);
+	if (lock_owner != SPINLOCK_PID_APPS) {
+		pr_err("%s: spinlock not owned by Apps (actual owner is %d)\n",
+				__func__, lock_owner);
+	}
+
+	__asm__ __volatile__(
+"       str     %1, [%0]\n"
+	:
+	: "r" (&lock->lock), "r" (0)
+	: "cc");
+}
+/* end ldrex implementation ------------------------------------------------- */
+
+/* sfpb implementation ------------------------------------------------------ */
 #define SFPB_SPINLOCK_COUNT 8
 #define MSM_SFPB_MUTEX_REG_BASE 0x01200600
 #define MSM_SFPB_MUTEX_REG_SIZE	(33 * 4)
+#define SFPB_SPINLOCK_OFFSET 4
+#define SFPB_SPINLOCK_SIZE 4
+
+static uint32_t lock_count;
+static phys_addr_t reg_base;
+static uint32_t reg_size;
+static uint32_t lock_offset; /* offset into the hardware block before lock 0 */
+static uint32_t lock_size;
 
 static void *hw_mutex_reg_base;
 static DEFINE_MUTEX(hw_map_init_lock);
 
-static int remote_spinlock_init_address(int id, _remote_spinlock_t *lock)
-{
-	if (id >= SFPB_SPINLOCK_COUNT)
-		return -EINVAL;
+static char *sfpb_compatible_string = "qcom,ipc-spinlock-sfpb";
 
+static int init_hw_mutex(struct device_node *node)
+{
+	struct resource r;
+	int rc;
+
+	rc = of_address_to_resource(node, 0, &r);
+	if (rc)
+		BUG();
+
+	rc = of_property_read_u32(node, "qcom,num-locks", &lock_count);
+	if (rc)
+		BUG();
+
+	reg_base = r.start;
+	reg_size = (uint32_t)(resource_size(&r));
+	lock_offset = 0;
+	lock_size = reg_size / lock_count;
+
+	return 0;
+}
+
+static void find_and_init_hw_mutex(void)
+{
+	struct device_node *node;
+
+	node = of_find_compatible_node(NULL, NULL, sfpb_compatible_string);
+	if (node) {
+		init_hw_mutex(node);
+	} else {
+		lock_count = SFPB_SPINLOCK_COUNT;
+		reg_base = MSM_SFPB_MUTEX_REG_BASE;
+		reg_size = MSM_SFPB_MUTEX_REG_SIZE;
+		lock_offset = SFPB_SPINLOCK_OFFSET;
+		lock_size = SFPB_SPINLOCK_SIZE;
+	}
+	hw_mutex_reg_base = ioremap(reg_base, reg_size);
+	BUG_ON(hw_mutex_reg_base == NULL);
+}
+
+static int remote_spinlock_init_address_hw(int id, _remote_spinlock_t *lock)
+{
+	/*
+	 * Optimistic locking.  Init only needs to be done once by the first
+	 * caller.  After that, serializing inits between different callers
+	 * is unnecessary.  The second check after the lock ensures init
+	 * wasn't previously completed by someone else before the lock could
+	 * be grabbed.
+	 */
 	if (!hw_mutex_reg_base) {
 		mutex_lock(&hw_map_init_lock);
 		if (!hw_mutex_reg_base)
-			hw_mutex_reg_base = ioremap(MSM_SFPB_MUTEX_REG_BASE,
-				   MSM_SFPB_MUTEX_REG_SIZE);
+			find_and_init_hw_mutex();
 		mutex_unlock(&hw_map_init_lock);
-		BUG_ON(hw_mutex_reg_base == NULL);
 	}
 
-	*lock = hw_mutex_reg_base + 0x4 + id * 4;
-	return 0;
-}
-
-void _remote_spin_release_all(uint32_t pid)
-{
-	remote_spin_release_all_locks(pid, SFPB_SPINLOCK_COUNT);
-}
-
-#else
-#define SMEM_SPINLOCK_COUNT 8
-#define SMEM_SPINLOCK_ARRAY_SIZE (SMEM_SPINLOCK_COUNT * sizeof(uint32_t))
-
-static int remote_spinlock_init_address(int id, _remote_spinlock_t *lock)
-{
-	_remote_spinlock_t spinlock_start;
-
-	if (id >= SMEM_SPINLOCK_COUNT)
+	if (id >= lock_count)
 		return -EINVAL;
 
-	spinlock_start = smem_alloc(SMEM_SPINLOCK_ARRAY,
-				    SMEM_SPINLOCK_ARRAY_SIZE);
-	if (spinlock_start == NULL)
-		return -ENXIO;
+	*lock = hw_mutex_reg_base + lock_offset + id * lock_size;
+	return 0;
+}
 
-	*lock = spinlock_start + id;
+static void __raw_remote_sfpb_spin_lock(raw_remote_spinlock_t *lock)
+{
+	do {
+		writel_relaxed(SPINLOCK_PID_APPS, lock);
+		smp_mb();
+	} while (readl_relaxed(lock) != SPINLOCK_PID_APPS);
+}
+
+static int __raw_remote_sfpb_spin_trylock(raw_remote_spinlock_t *lock)
+{
+	writel_relaxed(SPINLOCK_PID_APPS, lock);
+	smp_mb();
+	return readl_relaxed(lock) == SPINLOCK_PID_APPS;
+}
+
+static void __raw_remote_sfpb_spin_unlock(raw_remote_spinlock_t *lock)
+{
+	int lock_owner;
+
+	lock_owner = readl_relaxed(lock);
+	if (lock_owner != SPINLOCK_PID_APPS) {
+		pr_err("%s: spinlock not owned by Apps (actual owner is %d)\n",
+				__func__, lock_owner);
+	}
+
+	writel_relaxed(0, lock);
+	smp_mb();
+}
+/* end sfpb implementation -------------------------------------------------- */
+
+/* common spinlock API ------------------------------------------------------ */
+/**
+ * Release spinlock if it is owned by @pid.
+ *
+ * This is only to be used for situations where the processor owning
+ * the spinlock has crashed and the spinlock must be released.
+ *
+ * @lock: lock structure
+ * @pid: processor ID of processor to release
+ */
+static int __raw_remote_gen_spin_release(raw_remote_spinlock_t *lock,
+		uint32_t pid)
+{
+	int ret = 1;
+
+	if (readl_relaxed(&lock->lock) == pid) {
+		writel_relaxed(0, &lock->lock);
+		wmb();
+		ret = 0;
+	}
+	return ret;
+}
+
+/**
+ * Return owner of the spinlock.
+ *
+ * @lock: pointer to lock structure
+ * @returns: >= 0 owned PID; < 0 for error case
+ *
+ * Used for testing.  PID's are assumed to be 31 bits or less.
+ */
+static int __raw_remote_gen_spin_owner(raw_remote_spinlock_t *lock)
+{
+	rmb();
+	return readl_relaxed(&lock->lock);
+}
+
+
+static int dt_node_is_valid(const struct device_node *node)
+{
+	const char *status;
+	int statlen;
+
+	status = of_get_property(node, "status", &statlen);
+	if (status == NULL)
+		return 1;
+
+	if (statlen > 0) {
+		if (!strcmp(status, "okay") || !strcmp(status, "ok"))
+			return 1;
+	}
 
 	return 0;
 }
 
-void _remote_spin_release_all(uint32_t pid)
+static void initialize_ops(void)
 {
-	remote_spin_release_all_locks(pid, SMEM_SPINLOCK_COUNT);
-}
+	struct device_node *node;
 
-#endif
+	switch (current_mode) {
+	case DEKKERS_MODE:
+		current_ops.lock = __raw_remote_dek_spin_lock;
+		current_ops.unlock = __raw_remote_dek_spin_unlock;
+		current_ops.trylock = __raw_remote_dek_spin_trylock;
+		current_ops.release = __raw_remote_dek_spin_release;
+		current_ops.owner = __raw_remote_dek_spin_owner;
+		is_hw_lock_type = 0;
+		break;
+	case SWP_MODE:
+		current_ops.lock = __raw_remote_swp_spin_lock;
+		current_ops.unlock = __raw_remote_swp_spin_unlock;
+		current_ops.trylock = __raw_remote_swp_spin_trylock;
+		current_ops.release = __raw_remote_gen_spin_release;
+		current_ops.owner = __raw_remote_gen_spin_owner;
+		is_hw_lock_type = 0;
+		break;
+	case LDREX_MODE:
+		current_ops.lock = __raw_remote_ex_spin_lock;
+		current_ops.unlock = __raw_remote_ex_spin_unlock;
+		current_ops.trylock = __raw_remote_ex_spin_trylock;
+		current_ops.release = __raw_remote_gen_spin_release;
+		current_ops.owner = __raw_remote_gen_spin_owner;
+		is_hw_lock_type = 0;
+		break;
+	case SFPB_MODE:
+		current_ops.lock = __raw_remote_sfpb_spin_lock;
+		current_ops.unlock = __raw_remote_sfpb_spin_unlock;
+		current_ops.trylock = __raw_remote_sfpb_spin_trylock;
+		current_ops.release = __raw_remote_gen_spin_release;
+		current_ops.owner = __raw_remote_gen_spin_owner;
+		is_hw_lock_type = 1;
+		break;
+	case AUTO_MODE:
+		/*
+		 * of_find_compatible_node() returns a valid pointer even if
+		 * the status property is "disabled", so the validity needs
+		 * to be checked
+		 */
+		node = of_find_compatible_node(NULL, NULL,
+						sfpb_compatible_string);
+		if (node && dt_node_is_valid(node)) {
+			current_ops.lock = __raw_remote_sfpb_spin_lock;
+			current_ops.unlock = __raw_remote_sfpb_spin_unlock;
+			current_ops.trylock = __raw_remote_sfpb_spin_trylock;
+			current_ops.release = __raw_remote_gen_spin_release;
+			current_ops.owner = __raw_remote_gen_spin_owner;
+			is_hw_lock_type = 1;
+			break;
+		}
+
+		node = of_find_compatible_node(NULL, NULL,
+						ldrex_compatible_string);
+		if (node && dt_node_is_valid(node)) {
+			current_ops.lock = __raw_remote_ex_spin_lock;
+			current_ops.unlock = __raw_remote_ex_spin_unlock;
+			current_ops.trylock = __raw_remote_ex_spin_trylock;
+			current_ops.release = __raw_remote_gen_spin_release;
+			current_ops.owner = __raw_remote_gen_spin_owner;
+			is_hw_lock_type = 0;
+			break;
+		}
+
+		current_ops.lock = __raw_remote_ex_spin_lock;
+		current_ops.unlock = __raw_remote_ex_spin_unlock;
+		current_ops.trylock = __raw_remote_ex_spin_trylock;
+		current_ops.release = __raw_remote_gen_spin_release;
+		current_ops.owner = __raw_remote_gen_spin_owner;
+		is_hw_lock_type = 0;
+		pr_warn("Falling back to LDREX remote spinlock implementation");
+		break;
+	default:
+		BUG();
+		break;
+	}
+}
 
 /**
  * Release all spinlocks owned by @pid.
@@ -104,6 +518,11 @@
 	}
 }
 
+void _remote_spin_release_all(uint32_t pid)
+{
+	remote_spin_release_all_locks(pid, lock_count);
+}
+
 static int
 remote_spinlock_dal_init(const char *chunk_name, _remote_spinlock_t *lock)
 {
@@ -141,10 +560,54 @@
 	return -EINVAL;
 }
 
+#define SMEM_SPINLOCK_COUNT 8
+#define SMEM_SPINLOCK_ARRAY_SIZE (SMEM_SPINLOCK_COUNT * sizeof(uint32_t))
+
+static int remote_spinlock_init_address_smem(int id, _remote_spinlock_t *lock)
+{
+	_remote_spinlock_t spinlock_start;
+
+	if (id >= SMEM_SPINLOCK_COUNT)
+		return -EINVAL;
+
+	spinlock_start = smem_alloc(SMEM_SPINLOCK_ARRAY,
+				    SMEM_SPINLOCK_ARRAY_SIZE);
+	if (spinlock_start == NULL)
+		return -ENXIO;
+
+	*lock = spinlock_start + id;
+
+	lock_count = SMEM_SPINLOCK_COUNT;
+
+	return 0;
+}
+
+static int remote_spinlock_init_address(int id, _remote_spinlock_t *lock)
+{
+	if (is_hw_lock_type)
+		return remote_spinlock_init_address_hw(id, lock);
+	else
+		return remote_spinlock_init_address_smem(id, lock);
+}
+
 int _remote_spin_lock_init(remote_spinlock_id_t id, _remote_spinlock_t *lock)
 {
 	BUG_ON(id == NULL);
 
+	/*
+	 * Optimistic locking.  Init only needs to be done once by the first
+	 * caller.  After that, serializing inits between different callers
+	 * is unnecessary.  The second check after the lock ensures init
+	 * wasn't previously completed by someone else before the lock could
+	 * be grabbed.
+	 */
+	if (!current_ops.lock) {
+		mutex_lock(&ops_init_lock);
+		if (!current_ops.lock)
+			initialize_ops();
+		mutex_unlock(&ops_init_lock);
+	}
+
 	if (id[0] == 'D' && id[1] == ':') {
 		/* DAL chunk name starts after "D:" */
 		return remote_spinlock_dal_init(&id[2], lock);
@@ -153,12 +616,59 @@
 		BUG_ON(id[3] != '\0');
 
 		return remote_spinlock_init_address((((uint8_t)id[2])-'0'),
-				lock);
+			lock);
 	} else {
 		return -EINVAL;
 	}
 }
 
+/*
+ * lock comes in as a pointer to a pointer to the lock location, so it must
+ * be dereferenced and casted to the right type for the actual lock
+ * implementation functions
+ */
+void _remote_spin_lock(_remote_spinlock_t *lock)
+{
+	if (unlikely(!current_ops.lock))
+		BUG();
+	current_ops.lock((raw_remote_spinlock_t *)(*lock));
+}
+EXPORT_SYMBOL(_remote_spin_lock);
+
+void _remote_spin_unlock(_remote_spinlock_t *lock)
+{
+	if (unlikely(!current_ops.unlock))
+		BUG();
+	current_ops.unlock((raw_remote_spinlock_t *)(*lock));
+}
+EXPORT_SYMBOL(_remote_spin_unlock);
+
+int _remote_spin_trylock(_remote_spinlock_t *lock)
+{
+	if (unlikely(!current_ops.trylock))
+		BUG();
+	return current_ops.trylock((raw_remote_spinlock_t *)(*lock));
+}
+EXPORT_SYMBOL(_remote_spin_trylock);
+
+int _remote_spin_release(_remote_spinlock_t *lock, uint32_t pid)
+{
+	if (unlikely(!current_ops.release))
+		BUG();
+	return current_ops.release((raw_remote_spinlock_t *)(*lock), pid);
+}
+EXPORT_SYMBOL(_remote_spin_release);
+
+int _remote_spin_owner(_remote_spinlock_t *lock)
+{
+	if (unlikely(!current_ops.owner))
+		BUG();
+	return current_ops.owner((raw_remote_spinlock_t *)(*lock));
+}
+EXPORT_SYMBOL(_remote_spin_owner);
+/* end common spinlock API -------------------------------------------------- */
+
+/* remote mutex implementation ---------------------------------------------- */
 int _remote_mutex_init(struct remote_mutex_id *id, _remote_mutex_t *lock)
 {
 	BUG_ON(id == NULL);
@@ -190,3 +700,4 @@
 	return _remote_spin_trylock(&(lock->r_spinlock));
 }
 EXPORT_SYMBOL(_remote_mutex_trylock);
+/* end remote mutex implementation ------------------------------------------ */
diff --git a/arch/arm/mach-msm/reset_modem.c b/arch/arm/mach-msm/reset_modem.c
index 8e92456..7003eb5 100644
--- a/arch/arm/mach-msm/reset_modem.c
+++ b/arch/arm/mach-msm/reset_modem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/arch/arm/mach-msm/restart-fsm9xxx.c b/arch/arm/mach-msm/restart-fsm9xxx.c
index 4c5892f..d2fd051 100644
--- a/arch/arm/mach-msm/restart-fsm9xxx.c
+++ b/arch/arm/mach-msm/restart-fsm9xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/restart.c b/arch/arm/mach-msm/restart.c
index 7966177..a67af45 100644
--- a/arch/arm/mach-msm/restart.c
+++ b/arch/arm/mach-msm/restart.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -266,6 +266,9 @@
 {
 	int rc;
 
+	if (use_restart_v2())
+		return 0;
+
 	if (pmic_reset_irq != 0) {
 		rc = request_any_context_irq(pmic_reset_irq,
 					resout_irq_handler, IRQF_TRIGGER_HIGH,
diff --git a/arch/arm/mach-msm/restart_7k.c b/arch/arm/mach-msm/restart_7k.c
index 9675b61..14f55f8 100644
--- a/arch/arm/mach-msm/restart_7k.c
+++ b/arch/arm/mach-msm/restart_7k.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/rfic-fsm9xxx.c b/arch/arm/mach-msm/rfic-fsm9xxx.c
index 32b654b..ef13631 100644
--- a/arch/arm/mach-msm/rfic-fsm9xxx.c
+++ b/arch/arm/mach-msm/rfic-fsm9xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/rmt_storage_client.c b/arch/arm/mach-msm/rmt_storage_client.c
index c4530a9..a4562e9 100644
--- a/arch/arm/mach-msm/rmt_storage_client.c
+++ b/arch/arm/mach-msm/rmt_storage_client.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Linux Foundation. All rights reserved.
+/* Copyright (c) 2009-2013, 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
@@ -1357,33 +1357,63 @@
  * for encryption and sync.
  */
 #define MAX_GET_SYNC_STATUS_TRIES 200
-#define GET_SYNC_STATUS_SLEEP_INTERVAL 20
+#define RMT_SLEEP_INTERVAL_MS 20
 static int rmt_storage_reboot_call(
 	struct notifier_block *this, unsigned long code, void *cmd)
 {
 	int ret, count = 0;
 
+	/*
+	 * In recovery mode RMT daemon is not available,
+	 * so return from reboot notifier without initiating
+	 * force sync.
+	 */
+	spin_lock(&rmc->lock);
+	if (!rmc->open_excl) {
+		spin_unlock(&rmc->lock);
+		msm_rpc_unregister_client(rmt_srv->rpc_client);
+		return NOTIFY_DONE;
+	}
+
+	spin_unlock(&rmc->lock);
 	switch (code) {
 	case SYS_RESTART:
 	case SYS_HALT:
 	case SYS_POWER_OFF:
-		pr_info("%s: Force RMT storage final sync...\n", __func__);
+		pr_info("%s: Sending force-sync RPC request\n", __func__);
 		ret = rmt_storage_force_sync(rmt_srv->rpc_client);
 		if (ret)
 			break;
 
 		do {
 			count++;
-			msleep(GET_SYNC_STATUS_SLEEP_INTERVAL);
+			msleep(RMT_SLEEP_INTERVAL_MS);
 			ret = rmt_storage_get_sync_status(rmt_srv->rpc_client);
 		} while (ret != 1 && count < MAX_GET_SYNC_STATUS_TRIES);
 
 		if (ret == 1)
-			pr_info("%s: RMT storage sync successful.\n", __func__);
+			pr_info("%s: Final-sync successful\n", __func__);
 		else
-			pr_err("%s: RMT storage sync failed.\n", __func__);
+			pr_err("%s: Final-sync failed\n", __func__);
 
-		pr_info("%s: Un register RMT storage client.\n", __func__);
+		/*
+		 * Check if any ongoing efs_sync triggered just before force
+		 * sync is pending. If so, wait for 4sec for completing efs_sync
+		 * before unregistring client.
+		 */
+		count = 0;
+		while (count < MAX_GET_SYNC_STATUS_TRIES) {
+			if (atomic_read(&rmc->wcount) == 0) {
+				break;
+			} else {
+				count++;
+				msleep(RMT_SLEEP_INTERVAL_MS);
+			}
+		}
+		if (atomic_read(&rmc->wcount))
+			pr_err("%s: Efs_sync still incomplete\n", __func__);
+
+		pr_info("%s: Un-register RMT storage client\n", __func__);
 		msm_rpc_unregister_client(rmt_srv->rpc_client);
 		break;
 
diff --git a/arch/arm/mach-msm/rpc_dog_keepalive.c b/arch/arm/mach-msm/rpc_dog_keepalive.c
index 609b125..0f5b217 100644
--- a/arch/arm/mach-msm/rpc_dog_keepalive.c
+++ b/arch/arm/mach-msm/rpc_dog_keepalive.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/rpc_fsusb.c b/arch/arm/mach-msm/rpc_fsusb.c
index 4692d94..39ccdc2 100644
--- a/arch/arm/mach-msm/rpc_fsusb.c
+++ b/arch/arm/mach-msm/rpc_fsusb.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/arch/arm/mach-msm/rpc_hsusb.c b/arch/arm/mach-msm/rpc_hsusb.c
index cd5f612..78666d7 100644
--- a/arch/arm/mach-msm/rpc_hsusb.c
+++ b/arch/arm/mach-msm/rpc_hsusb.c
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-msm/rpc_hsusb.c
  *
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * All source code in this file is licensed under the following license except
  * where indicated.
diff --git a/arch/arm/mach-msm/rpc_pmapp.c b/arch/arm/mach-msm/rpc_pmapp.c
index 0828bb4..0205da2 100644
--- a/arch/arm/mach-msm/rpc_pmapp.c
+++ b/arch/arm/mach-msm/rpc_pmapp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/rpc_server_dog_keepalive.c b/arch/arm/mach-msm/rpc_server_dog_keepalive.c
index 5e0f46d..24b3b33 100644
--- a/arch/arm/mach-msm/rpc_server_dog_keepalive.c
+++ b/arch/arm/mach-msm/rpc_server_dog_keepalive.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/rpc_server_dog_keepalive.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  * Author: Iliyan Malchev <ibm@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/rpc_server_handset.c b/arch/arm/mach-msm/rpc_server_handset.c
index 3a458c8..13953dd 100644
--- a/arch/arm/mach-msm/rpc_server_handset.c
+++ b/arch/arm/mach-msm/rpc_server_handset.c
@@ -1,6 +1,6 @@
 /* arch/arm/mach-msm/rpc_server_handset.c
  *
- * Copyright (c) 2008-2010,2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-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
diff --git a/arch/arm/mach-msm/rpc_server_time_remote.c b/arch/arm/mach-msm/rpc_server_time_remote.c
index a7e6854..df2af6f 100644
--- a/arch/arm/mach-msm/rpc_server_time_remote.c
+++ b/arch/arm/mach-msm/rpc_server_time_remote.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/rpc_server_time_remote.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2011 The Linux Foundation. All rights reserved.
  * Author: Iliyan Malchev <ibm@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/rpc_server_time_remote.h b/arch/arm/mach-msm/rpc_server_time_remote.h
index 056666f..ee97de7 100644
--- a/arch/arm/mach-msm/rpc_server_time_remote.h
+++ b/arch/arm/mach-msm/rpc_server_time_remote.h
@@ -1,6 +1,6 @@
 /* arch/arm/mach-msm/rpc_server_time_remote.h
  *
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/rpcrouter_sdio_xprt.c b/arch/arm/mach-msm/rpcrouter_sdio_xprt.c
index 94a2d26..e9818e5 100644
--- a/arch/arm/mach-msm/rpcrouter_sdio_xprt.c
+++ b/arch/arm/mach-msm/rpcrouter_sdio_xprt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/rpcrouter_smd_xprt.c b/arch/arm/mach-msm/rpcrouter_smd_xprt.c
index e974eb5..cf51d17 100644
--- a/arch/arm/mach-msm/rpcrouter_smd_xprt.c
+++ b/arch/arm/mach-msm/rpcrouter_smd_xprt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/rpm-notifier.h b/arch/arm/mach-msm/rpm-notifier.h
index b9815a5..16de77e 100644
--- a/arch/arm/mach-msm/rpm-notifier.h
+++ b/arch/arm/mach-msm/rpm-notifier.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
@@ -40,8 +40,12 @@
 
 /**
  * msm_rpm_enter_sleep - Notify RPM driver to prepare for entering sleep
+ *
+ * @bool - flag to enable print contents of sleep buffer.
+ *
+ * return 0 on success errno on failure.
  */
-int msm_rpm_enter_sleep(void);
+int msm_rpm_enter_sleep(bool print);
 
 /**
  * msm_rpm_exit_sleep - Notify RPM driver about resuming from power collapse
diff --git a/arch/arm/mach-msm/rpm-regulator-8660.c b/arch/arm/mach-msm/rpm-regulator-8660.c
index be590e1..5ba6ee6 100644
--- a/arch/arm/mach-msm/rpm-regulator-8660.c
+++ b/arch/arm/mach-msm/rpm-regulator-8660.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/rpm-regulator-8930.c b/arch/arm/mach-msm/rpm-regulator-8930.c
index 9133856..d7ba67b 100644
--- a/arch/arm/mach-msm/rpm-regulator-8930.c
+++ b/arch/arm/mach-msm/rpm-regulator-8930.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/rpm-regulator-8960.c b/arch/arm/mach-msm/rpm-regulator-8960.c
index c5c01c2..745cfe7 100644
--- a/arch/arm/mach-msm/rpm-regulator-8960.c
+++ b/arch/arm/mach-msm/rpm-regulator-8960.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/rpm-regulator-9615.c b/arch/arm/mach-msm/rpm-regulator-9615.c
index 4abdc52..1c2e817 100644
--- a/arch/arm/mach-msm/rpm-regulator-9615.c
+++ b/arch/arm/mach-msm/rpm-regulator-9615.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/rpm-regulator-private.h b/arch/arm/mach-msm/rpm-regulator-private.h
index 703335f..9836907 100644
--- a/arch/arm/mach-msm/rpm-regulator-private.h
+++ b/arch/arm/mach-msm/rpm-regulator-private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/rpm-regulator-smd.c b/arch/arm/mach-msm/rpm-regulator-smd.c
index bb33283..8c96b1a 100644
--- a/arch/arm/mach-msm/rpm-regulator-smd.c
+++ b/arch/arm/mach-msm/rpm-regulator-smd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/rpm-regulator.c b/arch/arm/mach-msm/rpm-regulator.c
index 4e5281d..12b1392 100644
--- a/arch/arm/mach-msm/rpm-regulator.c
+++ b/arch/arm/mach-msm/rpm-regulator.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/arm/mach-msm/rpm-smd.c b/arch/arm/mach-msm/rpm-smd.c
index 1db3d34..b84ade9 100644
--- a/arch/arm/mach-msm/rpm-smd.c
+++ b/arch/arm/mach-msm/rpm-smd.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
@@ -32,6 +32,7 @@
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
+#include <linux/rbtree.h>
 #include <mach/socinfo.h>
 #include <mach/msm_smd.h>
 #include <mach/rpm-smd.h>
@@ -62,6 +63,9 @@
 };
 
 #define DEFAULT_BUFFER_SIZE 256
+#define DEBUG_PRINT_BUFFER_SIZE 512
+#define MAX_SLEEP_BUFFER 128
+
 #define GFP_FLAG(noirq) (noirq ? GFP_ATOMIC : GFP_KERNEL)
 #define INV_RSC "resource does not exist"
 #define ERR "err\0"
@@ -106,6 +110,11 @@
 	uint32_t data_len;
 };
 
+struct kvp {
+	unsigned int k;
+	unsigned int s;
+};
+
 struct msm_rpm_kvp_data {
 	uint32_t key;
 	uint32_t nbytes; /* number of bytes */
@@ -113,6 +122,301 @@
 	bool valid;
 };
 
+struct slp_buf {
+	struct rb_node node;
+	char ubuf[MAX_SLEEP_BUFFER];
+	char *buf;
+	bool valid;
+};
+static struct rb_root tr_root = RB_ROOT;
+
+static int msm_rpm_send_smd_buffer(char *buf, int size, bool noirq);
+static uint32_t msm_rpm_get_next_msg_id(void);
+
+static inline unsigned int get_rsc_type(char *buf)
+{
+	struct rpm_message_header *h;
+	h = (struct rpm_message_header *)
+		(buf + sizeof(struct rpm_request_header));
+	return h->resource_type;
+}
+
+static inline unsigned int get_rsc_id(char *buf)
+{
+	struct rpm_message_header *h;
+	h = (struct rpm_message_header *)
+		(buf + sizeof(struct rpm_request_header));
+	return h->resource_id;
+}
+
+#define get_data_len(buf) \
+	(((struct rpm_message_header *) \
+	  (buf + sizeof(struct rpm_request_header)))->data_len)
+
+#define get_req_len(buf) \
+	(((struct rpm_request_header *)(buf))->request_len)
+
+#define get_msg_id(buf) \
+	(((struct rpm_message_header *) \
+	  (buf + sizeof(struct rpm_request_header)))->msg_id)
+
+
+static inline int get_buf_len(char *buf)
+{
+	return get_req_len(buf) + sizeof(struct rpm_request_header);
+}
+
+static inline struct kvp *get_first_kvp(char *buf)
+{
+	return (struct kvp *)(buf + sizeof(struct rpm_request_header)
+			+ sizeof(struct rpm_message_header));
+}
+
+static inline struct kvp *get_next_kvp(struct kvp *k)
+{
+	return (struct kvp *)((void *)k + sizeof(*k) + k->s);
+}
+
+static inline void *get_data(struct kvp *k)
+{
+	return (void *)k + sizeof(*k);
+}
+
+
+static void delete_kvp(char *msg, struct kvp *d)
+{
+	struct kvp *n;
+	int dec, size;
+
+	n = get_next_kvp(d);
+	dec = (void *)n - (void *)d;
+	size = get_data_len(msg) - ((void *)n - (void *)get_first_kvp(msg));
+
+	memcpy((void *)d, (void *)n, size);
+
+	get_data_len(msg) -= dec;
+	get_req_len(msg) -= dec;
+}
+
+static inline void update_kvp_data(struct kvp *dest, struct kvp *src)
+{
+	memcpy(get_data(dest), get_data(src), src->s);
+}
+
+static void add_kvp(char *buf, struct kvp *n)
+{
+	int inc = sizeof(*n) + n->s;
+	BUG_ON((get_req_len(buf) + inc) > MAX_SLEEP_BUFFER);
+
+	memcpy(buf + get_buf_len(buf), n, inc);
+
+	get_data_len(buf) += inc;
+	get_req_len(buf) += inc;
+}
+
+static struct slp_buf *tr_search(struct rb_root *root, char *slp)
+{
+	unsigned int type = get_rsc_type(slp);
+	unsigned int id = get_rsc_id(slp);
+
+	struct rb_node *node = root->rb_node;
+
+	while (node) {
+		struct slp_buf *cur = rb_entry(node, struct slp_buf, node);
+		unsigned int ctype = get_rsc_type(cur->buf);
+		unsigned int cid = get_rsc_id(cur->buf);
+
+		if (type < ctype)
+			node = node->rb_left;
+		else if (type > ctype)
+			node = node->rb_right;
+		else if (id < cid)
+			node = node->rb_left;
+		else if (id > cid)
+			node = node->rb_right;
+		else
+			return cur;
+	}
+	return NULL;
+}
+
+static int tr_insert(struct rb_root *root, struct slp_buf *slp)
+{
+	unsigned int type = get_rsc_type(slp->buf);
+	unsigned int id = get_rsc_id(slp->buf);
+
+	struct rb_node **node = &(root->rb_node), *parent = NULL;
+
+	while (*node) {
+		struct slp_buf *curr = rb_entry(*node, struct slp_buf, node);
+		unsigned int ctype = get_rsc_type(curr->buf);
+		unsigned int cid = get_rsc_id(curr->buf);
+
+		parent = *node;
+
+		if (type < ctype)
+			node = &((*node)->rb_left);
+		else if (type > ctype)
+			node = &((*node)->rb_right);
+		else if (id < cid)
+			node = &((*node)->rb_left);
+		else if (id > cid)
+			node = &((*node)->rb_right);
+		else
+			return -EINVAL;
+	}
+
+	rb_link_node(&slp->node, parent, node);
+	rb_insert_color(&slp->node, root);
+	slp->valid = true;
+	return 0;
+}
+
+#define for_each_kvp(buf, k) \
+	for (k = (struct kvp *)get_first_kvp(buf); \
+		((void *)k - (void *)get_first_kvp(buf)) < get_data_len(buf);\
+		k = get_next_kvp(k))
+
+
+static void tr_update(struct slp_buf *s, char *buf)
+{
+	struct kvp *e, *n;
+
+	for_each_kvp(buf, n) {
+		for_each_kvp(s->buf, e) {
+			if (n->k == e->k) {
+				if (n->s == e->s) {
+					void *e_data = get_data(e);
+					void *n_data = get_data(n);
+					if (memcmp(e_data, n_data, n->s)) {
+						update_kvp_data(e, n);
+						s->valid = true;
+					}
+				} else {
+					delete_kvp(s->buf, e);
+					add_kvp(s->buf, n);
+					s->valid = true;
+				}
+				break;
+			}
+		}
+	}
+}
+
+int msm_rpm_smd_buffer_request(char *buf, int size, gfp_t flag)
+{
+	struct slp_buf *slp;
+	static DEFINE_SPINLOCK(slp_buffer_lock);
+	unsigned long flags;
+
+	if (size > MAX_SLEEP_BUFFER)
+		return -ENOMEM;
+
+	spin_lock_irqsave(&slp_buffer_lock, flags);
+	slp = tr_search(&tr_root, buf);
+
+	if (!slp) {
+		slp = kzalloc(sizeof(struct slp_buf), GFP_ATOMIC);
+		if (!slp) {
+			spin_unlock_irqrestore(&slp_buffer_lock, flags);
+			return -ENOMEM;
+		}
+		slp->buf = PTR_ALIGN(&slp->ubuf[0], sizeof(u32));
+		memcpy(slp->buf, buf, size);
+		if (tr_insert(&tr_root, slp))
+			pr_err("%s(): Error updating sleep request\n",
+					__func__);
+	} else {
+		/* handle unsent requests */
+		tr_update(slp, buf);
+	}
+
+	spin_unlock_irqrestore(&slp_buffer_lock, flags);
+
+	return 0;
+}
+static void msm_rpm_print_sleep_buffer(struct slp_buf *s)
+{
+	char buf[DEBUG_PRINT_BUFFER_SIZE] = {0};
+	int pos;
+	int buflen = DEBUG_PRINT_BUFFER_SIZE;
+	char ch[5] = {0};
+	u32 type;
+	struct kvp *e;
+
+	if (!s)
+		return;
+
+	if (!s->valid)
+		return;
+
+	type = get_rsc_type(s->buf);
+	memcpy(ch, &type, sizeof(u32));
+
+	pos = scnprintf(buf, buflen,
+			"Sleep request type = 0x%08x(%s)",
+			get_rsc_type(s->buf), ch);
+	pos += scnprintf(buf + pos, buflen - pos, " id = 0%x",
+			get_rsc_id(s->buf));
+	for_each_kvp(s->buf, e) {
+		int i;
+		char *data = get_data(e);
+
+		memcpy(ch, &e->k, sizeof(u32));
+
+		pos += scnprintf(buf + pos, buflen - pos,
+				"\n\t\tkey = 0x%08x(%s)",
+				e->k, ch);
+		pos += scnprintf(buf + pos, buflen - pos,
+				" sz= %d data =", e->s);
+
+		for (i = 0; i < e->s; i++)
+			pos += scnprintf(buf + pos, buflen - pos,
+					" 0x%02X", data[i]);
+	}
+	pos += scnprintf(buf + pos, buflen - pos, "\n");
+	printk(buf);
+}
+
+static int msm_rpm_flush_requests(bool print)
+{
+	struct rb_node *t;
+	int ret;
+
+	for (t = rb_first(&tr_root); t; t = rb_next(t)) {
+
+		struct slp_buf *s = rb_entry(t, struct slp_buf, node);
+
+		if (!s->valid)
+			continue;
+
+		if (print)
+			msm_rpm_print_sleep_buffer(s);
+
+		get_msg_id(s->buf) = msm_rpm_get_next_msg_id();
+		ret = msm_rpm_send_smd_buffer(s->buf,
+				get_buf_len(s->buf), true);
+		/* By not adding the message to a wait list we can reduce
+		 * latency involved in waiting for a ACK from RPM. The ACK
+		 * messages will be processed when we wakeup from sleep but
+		 * processing should be minimal
+		 * msm_rpm_wait_for_ack_noirq(get_msg_id(s->buf));
+		 */
+
+		WARN_ON(ret != get_buf_len(s->buf));
+
+		trace_rpm_send_message(true, MSM_RPM_CTX_SLEEP_SET,
+				get_rsc_type(s->buf),
+				get_rsc_id(s->buf),
+				get_msg_id(s->buf));
+
+		s->valid = false;
+	}
+	return 0;
+
+}
+
+
 static atomic_t msm_rpm_msg_id = ATOMIC_INIT(0);
 
 static struct msm_rpm_driver_data msm_rpm_data;
@@ -450,7 +754,12 @@
 		}
 		elem = NULL;
 	}
-	WARN_ON(!elem);
+	/* Special case where the sleep driver doesn't
+	 * wait for ACKs. This would decrease the latency involved with
+	 * entering RPM assisted power collapse.
+	 */
+	if (!elem)
+		trace_rpm_ack_recd(0, msg_id);
 
 	spin_unlock_irqrestore(&msm_rpm_list_lock, flags);
 }
@@ -544,8 +853,6 @@
 	}
 }
 
-#define DEBUG_PRINT_BUFFER_SIZE 512
-
 static void msm_rpm_log_request(struct msm_rpm_request *cdata)
 {
 	char buf[DEBUG_PRINT_BUFFER_SIZE];
@@ -677,13 +984,42 @@
 	pos += scnprintf(buf + pos, buflen - pos, "\n");
 	printk(buf);
 }
+static int msm_rpm_send_smd_buffer(char *buf, int size, bool noirq)
+{
+	unsigned long flags;
+	int ret;
 
+	spin_lock_irqsave(&msm_rpm_data.smd_lock_write, flags);
+	ret = smd_write_avail(msm_rpm_data.ch_info);
+
+	while ((ret = smd_write_avail(msm_rpm_data.ch_info)) < size) {
+		if (ret < 0)
+			break;
+		if (!noirq) {
+			spin_unlock_irqrestore(&msm_rpm_data.smd_lock_write,
+					flags);
+			cpu_relax();
+			spin_lock_irqsave(&msm_rpm_data.smd_lock_write, flags);
+		} else
+			udelay(5);
+	}
+
+	if (ret < 0) {
+		pr_err("%s(): SMD not initialized\n", __func__);
+		spin_unlock_irqrestore(&msm_rpm_data.smd_lock_write, flags);
+		return ret;
+	}
+
+	ret = smd_write(msm_rpm_data.ch_info, buf, size);
+	spin_unlock_irqrestore(&msm_rpm_data.smd_lock_write, flags);
+	return ret;
+
+}
 static int msm_rpm_send_data(struct msm_rpm_request *cdata,
 		int msg_type, bool noirq)
 {
 	uint8_t *tmpbuff;
 	int i, ret, msg_size;
-	unsigned long flags;
 
 	int req_hdr_sz, msg_hdr_sz;
 
@@ -695,8 +1031,6 @@
 
 	cdata->req_hdr.service_type = msm_rpm_request_service[msg_type];
 
-	cdata->msg_hdr.msg_id = msm_rpm_get_next_msg_id();
-
 	cdata->req_hdr.request_len = cdata->msg_hdr.data_len + msg_hdr_sz;
 	msg_size = cdata->req_hdr.request_len + req_hdr_sz;
 
@@ -714,8 +1048,6 @@
 
 	tmpbuff = cdata->buf;
 
-	memcpy(tmpbuff, &cdata->req_hdr, req_hdr_sz + msg_hdr_sz);
-
 	tmpbuff += req_hdr_sz + msg_hdr_sz;
 
 	for (i = 0; (i < cdata->write_idx); i++) {
@@ -740,6 +1072,17 @@
 
 	}
 
+	memcpy(cdata->buf, &cdata->req_hdr, req_hdr_sz + msg_hdr_sz);
+
+	if ((cdata->msg_hdr.set == MSM_RPM_CTX_SLEEP_SET) &&
+		!msm_rpm_smd_buffer_request(cdata->buf, msg_size,
+			GFP_FLAG(noirq)))
+		return 1;
+
+	cdata->msg_hdr.msg_id = msm_rpm_get_next_msg_id();
+
+	memcpy(cdata->buf + req_hdr_sz, &cdata->msg_hdr, msg_hdr_sz);
+
 	if (msm_rpm_debug_mask
 	    & (MSM_RPM_LOG_REQUEST_PRETTY | MSM_RPM_LOG_REQUEST_RAW))
 		msm_rpm_log_request(cdata);
@@ -755,29 +1098,7 @@
 
 	msm_rpm_add_wait_list(cdata->msg_hdr.msg_id);
 
-	spin_lock_irqsave(&msm_rpm_data.smd_lock_write, flags);
-
-	ret = smd_write_avail(msm_rpm_data.ch_info);
-
-	if (ret < 0) {
-		pr_err("%s(): SMD not initialized\n", __func__);
-		spin_unlock_irqrestore(&msm_rpm_data.smd_lock_write, flags);
-		return 0;
-	}
-
-	while ((ret < msg_size)) {
-		if (!noirq) {
-			spin_unlock_irqrestore(&msm_rpm_data.smd_lock_write,
-					flags);
-			cpu_relax();
-			spin_lock_irqsave(&msm_rpm_data.smd_lock_write, flags);
-		} else
-			udelay(5);
-		ret = smd_write_avail(msm_rpm_data.ch_info);
-	}
-
-	ret = smd_write(msm_rpm_data.ch_info, &cdata->buf[0], msg_size);
-	spin_unlock_irqrestore(&msm_rpm_data.smd_lock_write, flags);
+	ret = msm_rpm_send_smd_buffer(&cdata->buf[0], msg_size, noirq);
 
 	if (ret == msg_size) {
 		trace_rpm_send_message(noirq, cdata->msg_hdr.set,
@@ -822,6 +1143,7 @@
 int msm_rpm_wait_for_ack(uint32_t msg_id)
 {
 	struct msm_rpm_wait_data *elem;
+	int rc = 0;
 
 	if (!msg_id) {
 		pr_err("%s(): Invalid msg id\n", __func__);
@@ -829,20 +1151,22 @@
 	}
 
 	if (msg_id == 1)
-		return 0;
+		return rc;
 
 	if (standalone)
-		return 0;
+		return rc;
 
 	elem = msm_rpm_get_entry_from_msg_id(msg_id);
 	if (!elem)
-		return 0;
+		return rc;
 
 	wait_for_completion(&elem->ack);
 	trace_rpm_ack_recd(0, msg_id);
 
+	rc = elem->errno;
 	msm_rpm_free_list_entry(elem);
-	return elem->errno;
+
+	return rc;
 }
 EXPORT_SYMBOL(msm_rpm_wait_for_ack);
 
@@ -955,8 +1279,13 @@
  * During power collapse, the rpm driver disables the SMD interrupts to make
  * sure that the interrupt doesn't wakes us from sleep.
  */
-int msm_rpm_enter_sleep(void)
+int msm_rpm_enter_sleep(bool print)
 {
+	if (standalone)
+		return 0;
+
+	msm_rpm_flush_requests(print);
+
 	return smd_mask_receive_interrupt(msm_rpm_data.ch_info, true);
 }
 EXPORT_SYMBOL(msm_rpm_enter_sleep);
@@ -967,20 +1296,13 @@
  */
 void msm_rpm_exit_sleep(void)
 {
+	if (standalone)
+		return;
+
 	smd_mask_receive_interrupt(msm_rpm_data.ch_info, false);
 }
 EXPORT_SYMBOL(msm_rpm_exit_sleep);
 
-static bool msm_rpm_set_standalone(void)
-{
-	if (machine_is_msm9625() || machine_is_msm8974_rumi()) {
-		pr_warn("%s(): Running in standalone mode, requests "
-				"will not be sent to RPM\n", __func__);
-		standalone = true;
-	}
-	return standalone;
-}
-
 static int __devinit msm_rpm_dev_probe(struct platform_device *pdev)
 {
 	char *key = NULL;
@@ -998,6 +1320,9 @@
 	if (ret)
 		goto fail;
 
+	key = "rpm-standalone";
+	standalone = of_property_read_bool(pdev->dev.of_node, key);
+
 	init_completion(&msm_rpm_data.smd_open);
 	spin_lock_init(&msm_rpm_data.smd_lock_write);
 	spin_lock_init(&msm_rpm_data.smd_lock_read);
@@ -1009,9 +1334,14 @@
 		pr_info("Cannot open RPM channel %s %d\n", msm_rpm_data.ch_name,
 				msm_rpm_data.ch_type);
 
-		msm_rpm_set_standalone();
 		BUG_ON(!standalone);
 		complete(&msm_rpm_data.smd_open);
+	} else {
+		/*
+		 * Override DT's suggestion to try standalone; since we have an
+		 * SMD channel.
+		 */
+		standalone = false;
 	}
 
 	wait_for_completion(&msm_rpm_data.smd_open);
@@ -1026,6 +1356,10 @@
 	}
 
 	of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+
+	if (standalone)
+		pr_info("%s(): RPM running in standalone mode\n", __func__);
+
 	return 0;
 fail:
 	pr_err("%s(): Failed to read node: %s, key=%s\n", __func__,
diff --git a/arch/arm/mach-msm/rpm.c b/arch/arm/mach-msm/rpm.c
index 5ab484e2..5128b44 100644
--- a/arch/arm/mach-msm/rpm.c
+++ b/arch/arm/mach-msm/rpm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/rpm_log.c b/arch/arm/mach-msm/rpm_log.c
index 4835cef..a2c74a5 100644
--- a/arch/arm/mach-msm/rpm_log.c
+++ b/arch/arm/mach-msm/rpm_log.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-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
@@ -15,6 +15,7 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/of.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
@@ -43,6 +44,10 @@
 /* number of ms to wait between checking for new messages in the RPM log */
 #define RECHECK_TIME (50)
 
+#define VERSION_8974 0x1000
+#define RPM_ULOG_LENGTH_SHIFT 16
+#define RPM_ULOG_LENGTH_MASK  0xFFFF0000
+
 struct msm_rpm_log_buffer {
 	char *data;
 	u32 len;
@@ -109,11 +114,14 @@
 	while (tail_idx - head_idx > 0 && tail_idx - *read_idx > 0) {
 		head_idx = msm_rpm_log_read(pdata, MSM_RPM_LOG_PAGE_INDICES,
 					    MSM_RPM_LOG_HEAD);
+		tail_idx = msm_rpm_log_read(pdata, MSM_RPM_LOG_PAGE_INDICES,
+				    MSM_RPM_LOG_TAIL);
 		/* check if the message to be read is valid */
 		if (tail_idx - *read_idx > tail_idx - head_idx) {
 			*read_idx = head_idx;
 			continue;
 		}
+
 		/*
 		 * Ensure that all indices are 4 byte aligned.
 		 * This conditions is required to interact with a ULog buffer
@@ -123,7 +131,16 @@
 			break;
 
 		msg_len = msm_rpm_log_read(pdata, MSM_RPM_LOG_PAGE_BUFFER,
-					(*read_idx >> 2) & pdata->log_len_mask);
+				((*read_idx) & pdata->log_len_mask) >> 2);
+
+		/* Message length for 8974 is first 2 bytes.
+		 * Exclude message length and format from message length.
+		 */
+		if (pdata->version == VERSION_8974) {
+			msg_len = (msg_len & RPM_ULOG_LENGTH_MASK) >>
+					RPM_ULOG_LENGTH_SHIFT;
+			msg_len -= 4;
+		}
 
 		/* handle messages that claim to be longer than the log */
 		if (PADDED_LENGTH(msg_len) > tail_idx - *read_idx - 4)
@@ -142,8 +159,8 @@
 			if (IS_ALIGNED(i, 4))
 				*((u32 *)temp) = msm_rpm_log_read(pdata,
 						MSM_RPM_LOG_PAGE_BUFFER,
-						((*read_idx + 4 + i) >> 2) &
-							pdata->log_len_mask);
+						((*read_idx + 4 + i) &
+						pdata->log_len_mask) >> 2);
 
 			pos += scnprintf(msg_buffer + pos, buf_len - pos,
 					 "0x%02X, ", temp[i & 0x03]);
@@ -153,6 +170,8 @@
 
 		head_idx = msm_rpm_log_read(pdata, MSM_RPM_LOG_PAGE_INDICES,
 					    MSM_RPM_LOG_HEAD);
+		tail_idx = msm_rpm_log_read(pdata, MSM_RPM_LOG_PAGE_INDICES,
+				    MSM_RPM_LOG_TAIL);
 
 		/* roll back if message that was read is not still valid */
 		if (tail_idx - *read_idx > tail_idx - head_idx)
@@ -226,7 +245,7 @@
 
 /*
  * msm_rpm_log_file_open() - Allows a new reader to open the RPM log virtual
- *                           file
+ *			      file
  *
  * One local buffer is kmalloc'ed for each reader, so no resource sharing has
  * to take place (besides the read only access to the RPM log buffer).
@@ -290,23 +309,158 @@
 {
 	struct dentry *dent;
 	struct msm_rpm_log_platform_data *pdata;
+	struct resource *res = NULL;
+	struct device_node *node = NULL;
+	phys_addr_t page_buffer_address, rpm_addr_phys;
+	int ret = 0;
+	char *key = NULL;
+	uint32_t val = 0;
 
-	pdata = pdev->dev.platform_data;
-	if (!pdata)
-		return -EINVAL;
+	node = pdev->dev.of_node;
 
-	pdata->reg_base = ioremap(pdata->phys_addr_base, pdata->phys_size);
-	if (!pdata->reg_base) {
-		pr_err("%s: ERROR could not ioremap: start=%p, len=%u\n",
-			__func__, (void *) pdata->phys_addr_base,
-			pdata->phys_size);
-		return -EBUSY;
+	if (node) {
+		pdata = kzalloc(sizeof(struct msm_rpm_log_platform_data),
+				GFP_KERNEL);
+		if (!pdata)
+			return -ENOMEM;
+
+		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+		if (!res) {
+			kfree(pdata);
+			return -EINVAL;
+		}
+
+		pdata->phys_addr_base = res->start;
+		pdata->phys_size = resource_size(res);
+
+		pdata->reg_base = ioremap_nocache(pdata->phys_addr_base,
+					pdata->phys_size);
+		if (!pdata->reg_base) {
+			pr_err("%s: ERROR could not ioremap: start=%p, len=%u\n",
+				__func__, (void *) pdata->phys_addr_base,
+				pdata->phys_size);
+			kfree(pdata);
+			return -EBUSY;
+		}
+		/* Read various parameters from the header if the
+		 * version of the RPM Ulog is 0x1000. This version
+		 * corresponds to the node in the rpm header which
+		 * holds RPM log on 8974.
+		 *
+		 * offset-page-buffer-addr: At this offset header
+		 * contains address of the location where raw log
+		 * starts
+		 * offset-log-len: At this offset header contains
+		 * the length of the log buffer.
+		 * offset-log-len-mask: At this offset header contains
+		 * the log length mask for the buffer.
+		 * offset-page-indices: At this offset header contains
+		 * the index for writer. */
+
+		key = "qcom,offset-version";
+		ret = of_property_read_u32(node, key, &val);
+		if (ret) {
+			pr_err("%s: Error in name %s key %s\n",
+				__func__, node->full_name, key);
+			ret = -EFAULT;
+			goto fail;
+		}
+
+		pdata->version = readl_relaxed(pdata->reg_base + val);
+		if (pdata->version == VERSION_8974) {
+			key = "qcom,rpm-addr-phys";
+			ret = of_property_read_u32(node, key, &val);
+			if (ret) {
+				pr_err("%s: Error in name %s key %s\n",
+					__func__, node->full_name, key);
+				ret = -EFAULT;
+				goto fail;
+			}
+
+			rpm_addr_phys = val;
+
+			key = "qcom,offset-page-buffer-addr";
+			ret = of_property_read_u32(node, key, &val);
+			if (ret) {
+				pr_err("%s: Error in name %s key %s\n",
+					__func__, node->full_name, key);
+				ret = -EFAULT;
+				goto fail;
+			}
+
+			page_buffer_address = rpm_addr_phys +
+				readl_relaxed(pdata->reg_base + val);
+			pdata->reg_offsets[MSM_RPM_LOG_PAGE_BUFFER] =
+				page_buffer_address - pdata->phys_addr_base;
+
+			key = "qcom,offset-log-len";
+			ret = of_property_read_u32(node, key, &val);
+			if (ret) {
+				pr_err("%s: Error in name %s key %s\n",
+					__func__, node->full_name, key);
+				ret = -EFAULT;
+				goto fail;
+			}
+			pdata->log_len = readl_relaxed(pdata->reg_base + val);
+
+			if (pdata->log_len > pdata->phys_size) {
+				pr_err("%s: Error phy size: %d should be atleast log length: %d\n",
+					__func__, pdata->phys_size,
+					pdata->log_len);
+
+				ret = -EINVAL;
+				goto fail;
+			}
+
+			key = "qcom,offset-log-len-mask";
+			ret = of_property_read_u32(node, key, &val);
+			if (ret) {
+				pr_err("%s: Error in name %s key %s\n",
+					__func__, node->full_name, key);
+				ret = -EFAULT;
+				goto fail;
+			}
+			pdata->log_len_mask = readl_relaxed(pdata->reg_base
+					+ val);
+
+			key = "qcom,offset-page-indices";
+			ret = of_property_read_u32(node, key, &val);
+			if (ret) {
+				pr_err("%s: Error in name %s key %s\n",
+					__func__, node->full_name, key);
+				ret = -EFAULT;
+				goto fail;
+			}
+			pdata->reg_offsets[MSM_RPM_LOG_PAGE_INDICES] =
+						val;
+		} else{
+			ret = -EINVAL;
+			goto fail;
+		}
+
+	} else{
+		pdata = pdev->dev.platform_data;
+		if (!pdata)
+			return -EINVAL;
+
+		pdata->reg_base = ioremap(pdata->phys_addr_base,
+				pdata->phys_size);
+		if (!pdata->reg_base) {
+			pr_err("%s: ERROR could not ioremap: start=%p, len=%u\n",
+				__func__, (void *) pdata->phys_addr_base,
+				pdata->phys_size);
+			return -EBUSY;
+		}
 	}
 
 	dent = debugfs_create_file("rpm_log", S_IRUGO, NULL,
-			pdev->dev.platform_data, &msm_rpm_log_file_fops);
+			pdata, &msm_rpm_log_file_fops);
 	if (!dent) {
 		pr_err("%s: ERROR debugfs_create_file failed\n", __func__);
+		if (pdata->version == VERSION_8974) {
+			ret = -ENOMEM;
+			goto fail;
+		}
 		return -ENOMEM;
 	}
 
@@ -314,6 +468,11 @@
 
 	pr_notice("%s: OK\n", __func__);
 	return 0;
+
+fail:
+	iounmap(pdata->reg_base);
+	kfree(pdata);
+	return ret;
 }
 
 static int __devexit msm_rpm_log_remove(struct platform_device *pdev)
@@ -333,12 +492,18 @@
 	return 0;
 }
 
+static struct of_device_id rpm_log_table[] = {
+	       {.compatible = "qcom,rpm-log"},
+	       {},
+};
+
 static struct platform_driver msm_rpm_log_driver = {
 	.probe		= msm_rpm_log_probe,
 	.remove		= __devexit_p(msm_rpm_log_remove),
 	.driver		= {
 		.name = "msm_rpm_log",
 		.owner = THIS_MODULE,
+		.of_match_table = rpm_log_table,
 	},
 };
 
diff --git a/arch/arm/mach-msm/rpm_log.h b/arch/arm/mach-msm/rpm_log.h
index 37349b6..f75937e 100644
--- a/arch/arm/mach-msm/rpm_log.h
+++ b/arch/arm/mach-msm/rpm_log.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
@@ -28,6 +28,7 @@
 	u32 log_len_mask;
 	phys_addr_t phys_addr_base;
 	u32 phys_size;
+	u32 version;
 	void __iomem *reg_base;
 };
 
diff --git a/arch/arm/mach-msm/rpm_master_stat.c b/arch/arm/mach-msm/rpm_master_stat.c
index 4dcf5eb..49a1039 100644
--- a/arch/arm/mach-msm/rpm_master_stat.c
+++ b/arch/arm/mach-msm/rpm_master_stat.c
@@ -130,7 +130,7 @@
 	if (!pdata)
 		return -EINVAL;
 
-	if (!bufu || count < 0)
+	if (!bufu || count == 0)
 		return -EINVAL;
 
 	if ((*ppos <= pdata->phys_size)) {
diff --git a/arch/arm/mach-msm/rpm_rbcpr_stats.c b/arch/arm/mach-msm/rpm_rbcpr_stats.c
index 7f27efc..14f77a3 100644
--- a/arch/arm/mach-msm/rpm_rbcpr_stats.c
+++ b/arch/arm/mach-msm/rpm_rbcpr_stats.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/rpm_rbcpr_stats.h b/arch/arm/mach-msm/rpm_rbcpr_stats.h
index 55644d0..2ceb4a0 100644
--- a/arch/arm/mach-msm/rpm_rbcpr_stats.h
+++ b/arch/arm/mach-msm/rpm_rbcpr_stats.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/rpm_resources.c b/arch/arm/mach-msm/rpm_resources.c
index 43073d3..78c5ae0 100644
--- a/arch/arm/mach-msm/rpm_resources.c
+++ b/arch/arm/mach-msm/rpm_resources.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -21,6 +21,7 @@
 #include <linux/spinlock.h>
 #include <linux/cpu.h>
 #include <linux/hrtimer.h>
+#include <linux/platform_device.h>
 #include <mach/rpm.h>
 #include <mach/msm_iomap.h>
 #include <asm/mach-types.h>
@@ -71,6 +72,10 @@
 static int vdd_mem_vlevels[MSM_RPMRS_VDD_MEM_LAST];
 static int vdd_mask;
 
+static DEFINE_PER_CPU(uint32_t , msm_lpm_sleep_time);
+static DEFINE_PER_CPU(int , lpm_permitted_level);
+static DEFINE_PER_CPU(struct atomic_notifier_head, lpm_notify_head);
+
 #define MSM_RPMRS_MAX_RS_REGISTER_COUNT 2
 
 #define RPMRS_ATTR(_name) \
@@ -869,6 +874,13 @@
 	spin_unlock_irqrestore(&msm_rpmrs_lock, flags);
 }
 
+static bool lpm_level_permitted(int cur_level_count)
+{
+	if (__get_cpu_var(lpm_permitted_level) == msm_rpmrs_level_count + 1)
+		return true;
+	return (__get_cpu_var(lpm_permitted_level) == cur_level_count);
+}
+
 s32 msm_cpuidle_get_deep_idle_latency(void)
 {
 	int i;
@@ -904,6 +916,7 @@
 	uint32_t pwr;
 	uint32_t next_wakeup_us = time_param->sleep_us;
 	bool modify_event_timer;
+	int best_level_iter = msm_rpmrs_level_count + 1;
 
 	if (sleep_mode == MSM_PM_SLEEP_MODE_POWER_COLLAPSE) {
 		irqs_detectable = msm_mpm_irqs_detectable(from_idle);
@@ -968,6 +981,7 @@
 			level->rs_limits.latency_us[cpu] = level->latency_us;
 			level->rs_limits.power[cpu] = pwr;
 			best_level = level;
+			best_level_iter = i;
 			if (power)
 				*power = pwr;
 			if (modify_event_timer && best_level->latency_us > 1)
@@ -978,6 +992,12 @@
 				time_param->modified_time_us = 0;
 		}
 	}
+	if (best_level && !lpm_level_permitted(best_level_iter))
+		best_level = NULL;
+	else
+		per_cpu(msm_lpm_sleep_time, cpu) =
+			time_param->modified_time_us ?
+			time_param->modified_time_us : time_param->sleep_us;
 
 	return best_level ? &best_level->rs_limits : NULL;
 }
@@ -986,6 +1006,12 @@
 		bool from_idle, bool notify_rpm)
 {
 	int rc = 0;
+	struct msm_lpm_sleep_data sleep_data;
+
+	sleep_data.limits = limits;
+	sleep_data.kernel_sleep = __get_cpu_var(msm_lpm_sleep_time);
+	atomic_notifier_call_chain(&__get_cpu_var(lpm_notify_head),
+		MSM_LPM_STATE_ENTER, &sleep_data);
 
 	if (notify_rpm) {
 		rc = msm_rpmrs_flush_buffer(sclk_count, limits, from_idle);
@@ -1009,6 +1035,9 @@
 
 	if (msm_rpmrs_use_mpm(limits))
 		msm_mpm_exit_sleep(from_idle);
+
+	atomic_notifier_call_chain(&__get_cpu_var(lpm_notify_head),
+			MSM_LPM_STATE_EXIT, NULL);
 }
 
 static int rpmrs_cpu_callback(struct notifier_block *nfb,
@@ -1033,6 +1062,16 @@
 	return NOTIFY_OK;
 }
 
+static struct lpm_test_platform_data lpm_test_pdata;
+
+static struct platform_device msm_lpm_test_device = {
+	.name		= "lpm_test",
+	.id		= -1,
+	.dev		= {
+		.platform_data = &lpm_test_pdata,
+	},
+};
+
 static struct notifier_block __refdata rpmrs_cpu_notifier = {
 	.notifier_call = rpmrs_cpu_callback,
 };
@@ -1041,6 +1080,7 @@
 {
 	int i, k;
 	struct msm_rpmrs_level *levels = data->levels;
+	unsigned int m_cpu = 0;
 
 	msm_rpmrs_level_count = data->num_levels;
 
@@ -1052,6 +1092,16 @@
 	memcpy(msm_rpmrs_levels, levels,
 			msm_rpmrs_level_count * sizeof(struct msm_rpmrs_level));
 
+	lpm_test_pdata.use_qtimer = 0;
+	lpm_test_pdata.msm_lpm_test_levels = msm_rpmrs_levels,
+	lpm_test_pdata.msm_lpm_test_level_count = msm_rpmrs_level_count;
+
+	for_each_possible_cpu(m_cpu)
+		per_cpu(lpm_permitted_level, m_cpu) =
+				msm_rpmrs_level_count + 1;
+
+	platform_device_register(&msm_lpm_test_device);
+
 	memcpy(vdd_dig_vlevels, data->vdd_dig_levels,
 		(MSM_RPMRS_VDD_DIG_MAX + 1) * sizeof(vdd_dig_vlevels[0]));
 
@@ -1087,6 +1137,41 @@
 	return 0;
 }
 
+uint32_t msm_pm_get_pxo(struct msm_rpmrs_limits *limits)
+{
+	return limits->pxo;
+}
+
+uint32_t msm_pm_get_l2_cache(struct msm_rpmrs_limits *limits)
+{
+	return limits->l2_cache;
+}
+
+uint32_t msm_pm_get_vdd_mem(struct msm_rpmrs_limits *limits)
+{
+	return limits->vdd_mem;
+}
+
+uint32_t msm_pm_get_vdd_dig(struct msm_rpmrs_limits *limits)
+{
+	return limits->vdd_dig;
+}
+
+int msm_lpm_register_notifier(int cpu, int level_iter,
+			struct notifier_block *nb, bool is_latency_measure)
+{
+	per_cpu(lpm_permitted_level, cpu) = level_iter;
+	return atomic_notifier_chain_register(&per_cpu(lpm_notify_head,
+			cpu), nb);
+}
+
+int msm_lpm_unregister_notifier(int cpu, struct notifier_block *nb)
+{
+	per_cpu(lpm_permitted_level, cpu) = msm_rpmrs_level_count + 1;
+	return atomic_notifier_chain_unregister(&per_cpu(lpm_notify_head, cpu),
+				nb);
+}
+
 static int __init msm_rpmrs_init(void)
 {
 	struct msm_rpm_iv_pair req;
diff --git a/arch/arm/mach-msm/rpm_resources.h b/arch/arm/mach-msm/rpm_resources.h
index 46d6d94..0a180fb 100644
--- a/arch/arm/mach-msm/rpm_resources.h
+++ b/arch/arm/mach-msm/rpm_resources.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -15,7 +15,9 @@
 #define __ARCH_ARM_MACH_MSM_RPM_RESOURCES_H
 
 #include <mach/rpm.h>
+#include <linux/notifier.h>
 #include "pm.h"
+#include "test-lpm.h"
 
 enum {
 	MSM_RPMRS_ID_PXO_CLK = 0,
@@ -102,6 +104,94 @@
 	unsigned int rpmrs_target_id[MSM_RPMRS_ID_LAST];
 };
 
+enum {
+	MSM_LPM_STATE_ENTER = 0,
+	MSM_LPM_STATE_EXIT = 1,
+};
+
+/**
+ * struct msm_lpm_sleep_data - abstraction to get sleep data
+ * @limits:	pointer to the msm_rpmrs_limits structure
+ * @kernel_sleep:	kernel sleep time as decided by the power calculation
+ *			algorithm
+ *
+ * This structure is an abstraction to get the limits and kernel sleep time
+ * during enter sleep.
+ */
+
+struct msm_lpm_sleep_data {
+	struct msm_rpmrs_limits *limits;
+	uint32_t kernel_sleep;
+};
+
+#define MSM_PM(field) MSM_RPMRS_##field
+
+/**
+ * msm_pm_get_pxo() -  get the limits for pxo
+ * @limits:            pointer to the msm_rpmrs_limits structure
+ *
+ * This function gets the limits to the resource pxo on
+ * 8960
+ */
+
+uint32_t msm_pm_get_pxo(struct msm_rpmrs_limits *limits);
+
+/**
+ * msm_pm_get_l2_cache() -  get the limits for l2 cache
+ * @limits:            pointer to the msm_rpmrs_limits structure
+ *
+ * This function gets the limits to the resource l2 cache
+ * on 8960
+ */
+
+uint32_t msm_pm_get_l2_cache(struct msm_rpmrs_limits *limits);
+
+/**
+ * msm_pm_get_vdd_mem() -  get the limits for pxo
+ * @limits:            pointer to the msm_rpmrs_limits structure
+ *
+ * This function gets the limits to the resource vdd mem
+ * on 8960
+ */
+
+uint32_t msm_pm_get_vdd_mem(struct msm_rpmrs_limits *limits);
+
+/**
+ * msm_pm_get_vdd_dig() -  get the limits for vdd dig
+ * @limits:            pointer to the msm_rpmrs_limits structure
+ *
+ * This function gets the limits to the resource vdd dig
+ * on 8960
+ */
+
+uint32_t msm_pm_get_vdd_dig(struct msm_rpmrs_limits *limits);
+
+/**
+ * msm_lpm_register_notifier() - register for notifications
+ * @cpu:               cpu to debug
+ * @level_iter:        low power level index to debug
+ * @nb:       notifier block to callback on notifications
+ * @is_latency_measure: is it latency measure
+ *
+ * This function sets the permitted level to the index of the
+ * level under test and registers notifier for callback.
+ */
+
+int msm_lpm_register_notifier(int cpu, int level_iter,
+		struct notifier_block *nb, bool is_latency_measure);
+
+/**
+ * msm_lpm_unregister_notifier() - unregister from notifications
+ * @cpu:               cpu to debug
+ * @nb:       notifier block to callback on notifications
+ *
+ * This function sets the permitted level to a value one more than
+ * available levels count which indicates that all levels are
+ * permitted and it also unregisters notifier for callback.
+ */
+
+int msm_lpm_unregister_notifier(int cpu, struct notifier_block *nb);
+
 #if defined(CONFIG_MSM_RPM)
 
 int msm_rpmrs_set(int ctx, struct msm_rpm_iv_pair *req, int count);
diff --git a/arch/arm/mach-msm/rpm_stats.c b/arch/arm/mach-msm/rpm_stats.c
index 9a8b8ec..176c3de 100644
--- a/arch/arm/mach-msm/rpm_stats.c
+++ b/arch/arm/mach-msm/rpm_stats.c
@@ -223,7 +223,7 @@
 	if (!prvdata)
 		return -EINVAL;
 
-	if (!bufu || count < 0)
+	if (!bufu || count == 0)
 		return -EINVAL;
 
 	if (prvdata->platform_data->version == 1) {
diff --git a/arch/arm/mach-msm/saw-regulator.c b/arch/arm/mach-msm/saw-regulator.c
index 0a81a33..ae1e273 100644
--- a/arch/arm/mach-msm/saw-regulator.c
+++ b/arch/arm/mach-msm/saw-regulator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/scm-boot.c b/arch/arm/mach-msm/scm-boot.c
index 01d0853..ae5bd04 100644
--- a/arch/arm/mach-msm/scm-boot.c
+++ b/arch/arm/mach-msm/scm-boot.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/scm-boot.h b/arch/arm/mach-msm/scm-boot.h
index 0d0e6aa..660cd05 100644
--- a/arch/arm/mach-msm/scm-boot.h
+++ b/arch/arm/mach-msm/scm-boot.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/scm-io.c b/arch/arm/mach-msm/scm-io.c
index 28614d3..a21ec36 100644
--- a/arch/arm/mach-msm/scm-io.c
+++ b/arch/arm/mach-msm/scm-io.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/scm-pas.c b/arch/arm/mach-msm/scm-pas.c
index e248917..f73055e 100644
--- a/arch/arm/mach-msm/scm-pas.c
+++ b/arch/arm/mach-msm/scm-pas.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/scm-pas.h b/arch/arm/mach-msm/scm-pas.h
index 6441a18..f13757c 100644
--- a/arch/arm/mach-msm/scm-pas.h
+++ b/arch/arm/mach-msm/scm-pas.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/scm.c b/arch/arm/mach-msm/scm.c
index f4dae89..d070efa 100644
--- a/arch/arm/mach-msm/scm.c
+++ b/arch/arm/mach-msm/scm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/sdio_al.c b/arch/arm/mach-msm/sdio_al.c
index 356ce90..bcfc556 100644
--- a/arch/arm/mach-msm/sdio_al.c
+++ b/arch/arm/mach-msm/sdio_al.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/sdio_al_dloader.c b/arch/arm/mach-msm/sdio_al_dloader.c
index f48c32b..b0cb88f 100644
--- a/arch/arm/mach-msm/sdio_al_dloader.c
+++ b/arch/arm/mach-msm/sdio_al_dloader.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
@@ -21,6 +21,7 @@
 #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>
@@ -87,6 +88,8 @@
 		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 {
@@ -224,6 +227,8 @@
 static DEFINE_SPINLOCK(lock2);
 static unsigned long lock_flags2;
 
+static atomic_t sdio_dld_in_use = 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
@@ -1108,6 +1113,10 @@
 		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;
@@ -1185,7 +1194,6 @@
   */
 static void sdio_dld_close(struct tty_struct *tty, struct file *file)
 {
-	int status = 0;
 	struct sdioc_reg_chunk *reg = &sdio_dld->sdio_dloader_data.sdioc_reg;
 
 	/* informing the SDIOC that it can exit boot phase */
@@ -1200,20 +1208,6 @@
 		   sdio_dld->dld_main_thread.exit_wait.wake_up_signal);
 	pr_debug(MODULE_NAME ": %s - CLOSING - WOKE UP...", __func__);
 
-	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__);
-	}
-
 #ifdef CONFIG_DEBUG_FS
 	gd.curr_i = curr_index;
 	gd.duration_ms = sdio_dld_info.time_msec;
@@ -1263,9 +1257,8 @@
 	if (sdio_dld->done_callback)
 		sdio_dld->done_callback();
 
-	pr_info(MODULE_NAME ": %s - Freeing sdio_dld data structure, and "
-		" returning...", __func__);
-	kfree(sdio_dld);
+	schedule_work(&cleanup);
+	pr_info(MODULE_NAME ": %s - Bootloader done, returning...", __func__);
 }
 
 /**
@@ -2392,6 +2385,9 @@
 	struct sdio_func *str_func = NULL;
 	struct device *tty_dev;
 
+	if (atomic_read(&sdio_dld_in_use) == 1)
+		return -EBUSY;
+
 	if (num_of_devices == 0 || num_of_devices > MAX_NUM_DEVICES) {
 		pr_err(MODULE_NAME ": %s - invalid number of devices\n",
 		       __func__);
@@ -2534,6 +2530,28 @@
 	return status;
 }
 
+static void sdio_dld_tear_down(struct work_struct *work)
+{
+	int status = 0;
+
+	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__);
+	}
+
+	kfree(sdio_dld);
+	atomic_set(&sdio_dld_in_use, 0);
+}
+
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("SDIO Downloader");
 MODULE_AUTHOR("Yaniv Gardi <ygardi@codeaurora.org>");
diff --git a/arch/arm/mach-msm/sdio_al_private.h b/arch/arm/mach-msm/sdio_al_private.h
index 36d9ec1..3a5ab79 100644
--- a/arch/arm/mach-msm/sdio_al_private.h
+++ b/arch/arm/mach-msm/sdio_al_private.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/sdio_al_test.c b/arch/arm/mach-msm/sdio_al_test.c
index c97588f..2c9f675 100644
--- a/arch/arm/mach-msm/sdio_al_test.c
+++ b/arch/arm/mach-msm/sdio_al_test.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/sdio_cmux.c b/arch/arm/mach-msm/sdio_cmux.c
index d04a0b0..48ca6b7 100644
--- a/arch/arm/mach-msm/sdio_cmux.c
+++ b/arch/arm/mach-msm/sdio_cmux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
@@ -68,6 +68,7 @@
 	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 *);
@@ -171,6 +172,7 @@
 	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;
@@ -197,8 +199,10 @@
 		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);
@@ -300,9 +304,10 @@
 	}
 	logical_ch[id].is_local_open = 1;
 	logical_ch[id].priv = priv;
-	logical_ch[id].receive_cb = receive_cb;
 	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,
@@ -319,6 +324,7 @@
 		}
 		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;
@@ -338,7 +344,9 @@
 
 	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);
@@ -564,12 +572,20 @@
 
 		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].lc_lock);
+		mutex_unlock(&logical_ch[id].rx_cb_lock);
 		break;
 
 	case STATUS:
diff --git a/arch/arm/mach-msm/sdio_ctl.c b/arch/arm/mach-msm/sdio_ctl.c
index ac16e77..cacdce9 100644
--- a/arch/arm/mach-msm/sdio_ctl.c
+++ b/arch/arm/mach-msm/sdio_ctl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/sdio_dmux.c b/arch/arm/mach-msm/sdio_dmux.c
index 71b4e9b..c6d665d 100644
--- a/arch/arm/mach-msm/sdio_dmux.c
+++ b/arch/arm/mach-msm/sdio_dmux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/sdio_smem.c b/arch/arm/mach-msm/sdio_smem.c
index 4416a79..edc0d23 100644
--- a/arch/arm/mach-msm/sdio_smem.c
+++ b/arch/arm/mach-msm/sdio_smem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/sdio_tty.c b/arch/arm/mach-msm/sdio_tty.c
index 41bc270..c4b7673 100644
--- a/arch/arm/mach-msm/sdio_tty.c
+++ b/arch/arm/mach-msm/sdio_tty.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/sensors_adsp.c b/arch/arm/mach-msm/sensors_adsp.c
index 0683bc5..1534358 100644
--- a/arch/arm/mach-msm/sensors_adsp.c
+++ b/arch/arm/mach-msm/sensors_adsp.c
@@ -43,9 +43,9 @@
 
 #define SNS_OCMEM_SMD_CHANNEL	"SENSOR"
 #define SNS_OCMEM_CLIENT_ID     OCMEM_SENSORS
-#define SNS_OCMEM_SIZE          SZ_256K
-#define SMD_BUF_SIZE		2048
-#define SNS_TIMEOUT_MS    1000
+#define SNS_OCMEM_SIZE		SZ_256K
+#define SMD_BUF_SIZE		1024
+#define SNS_TIMEOUT_MS		1000
 
 #define SNS_OCMEM_ALLOC_GROW    0x00000001
 #define SNS_OCMEM_ALLOC_SHRINK  0x00000002
@@ -60,7 +60,7 @@
 #define DSPS_BW_VOTE_OFF        0x00000800
 #define DSPS_PHYS_ADDR_SET      0x00001000
 
-/**
+/*
  *  Structure contains all state used by the sensors driver
  */
 struct sns_adsp_control_s {
@@ -68,6 +68,8 @@
 	spinlock_t sns_lock;
 	struct workqueue_struct *sns_workqueue;
 	struct work_struct sns_work;
+	struct workqueue_struct *smd_wq;
+	struct work_struct smd_read_work;
 	smd_channel_t *smd_ch;
 	uint32_t sns_ocmem_status;
 	uint32_t mem_segments_size;
@@ -88,14 +90,15 @@
 
 static struct sns_adsp_control_s sns_ctl;
 
-/* All asynchronous responses from the OCMEM driver are received
-by this function */
+/*
+ * All asynchronous responses from the OCMEM driver are received
+ * by this function
+ */
 int sns_ocmem_drv_cb(struct notifier_block *self,
 			unsigned long action,
 			void *dev)
 {
 	unsigned long flags;
-	pr_debug("%s\n", __func__);
 
 	spin_lock_irqsave(&sns_ctl.sns_lock, flags);
 
@@ -141,26 +144,22 @@
 		break;
 	}
 
-	pr_debug("%s: sns_ocmem_status: 0x%x\n", __func__,
-					sns_ctl.sns_ocmem_status);
 	spin_unlock_irqrestore(&sns_ctl.sns_lock, flags);
-
 	wake_up(&sns_ctl.sns_wait);
 
 	return 0;
 }
 
-/**
+/*
  * Processes messages received through SMD from the ADSP
  *
  * @param hdr The message header
  * @param msg Message pointer
  *
- * */
+ */
 void sns_ocmem_smd_process(struct sns_ocmem_hdr_s *hdr, void *msg)
 {
 	unsigned long flags;
-	pr_debug("%s\n", __func__);
 
 	spin_lock_irqsave(&sns_ctl.sns_lock, flags);
 
@@ -228,50 +227,58 @@
 					__func__, hdr->msg_id, hdr->msg_type);
 	}
 
-	pr_debug("%s: sns_ocmem_status: 0x%x\n",
-		__func__, sns_ctl.sns_ocmem_status);
-
 	spin_unlock_irqrestore(&sns_ctl.sns_lock, flags);
 
 	wake_up(&sns_ctl.sns_wait);
 }
 
-/**
+static void sns_ocmem_smd_read(struct work_struct *ws)
+{
+	struct smd_channel *ch = sns_ctl.smd_ch;
+	unsigned char *buf = NULL;
+	int sz, len;
+
+	for (;;) {
+		sz = smd_cur_packet_size(ch);
+		BUG_ON(sz > SMD_BUF_SIZE);
+		len = smd_read_avail(ch);
+		pr_debug("%s: sz=%d, len=%d\n", __func__, sz, len);
+		if (len == 0 || len < sz)
+			break;
+		buf = kzalloc(SMD_BUF_SIZE, GFP_KERNEL);
+		if (buf == NULL) {
+			pr_err("%s: malloc failed", __func__);
+			break;
+		}
+
+		if (smd_read(ch, buf, sz) != sz) {
+			pr_err("%s: not enough data?!\n", __func__);
+			kfree(buf);
+			continue;
+		}
+
+		sns_ocmem_smd_process((struct sns_ocmem_hdr_s *)buf,
+			(void *)((char *)buf +
+			sizeof(struct sns_ocmem_hdr_s)));
+
+		kfree(buf);
+
+	}
+}
+
+/*
  * All SMD notifications and messages from Sensors on ADSP are
  * received by this function
  *
- * */
-
+ */
 void sns_ocmem_smd_notify_data(void *data, unsigned int event)
 {
-	pr_debug("%s:\n", __func__);
-
 	if (event == SMD_EVENT_DATA) {
-		int len;
+		int sz;
 		pr_debug("%s: Received SMD event Data\n", __func__);
-		len = smd_read_avail(sns_ctl.smd_ch);
-		pr_debug("%s: len=%d\n", __func__, len);
-		if (len > 0) {
-			data = kzalloc(SMD_BUF_SIZE, GFP_ATOMIC);
-			if (data == NULL) {
-				pr_err("%s: malloc failed", __func__);
-				return;
-			}
-
-			len = smd_read_from_cb(sns_ctl.smd_ch,
-						data, SMD_BUF_SIZE);
-			if (len > 0) {
-				sns_ocmem_smd_process(
-					(struct sns_ocmem_hdr_s *) data,
-					(void *)((char *)data +
-					sizeof(struct sns_ocmem_hdr_s)));
-			} else {
-				pr_err("Failed to read event from smd %i", len);
-			}
-			kfree(data);
-		} else if (len < 0) {
-			pr_err("Failed to read event from smd %i", len);
-		}
+		sz = smd_cur_packet_size(sns_ctl.smd_ch);
+		if ((sz > 0) && (sz <= smd_read_avail(sns_ctl.smd_ch)))
+			queue_work(sns_ctl.smd_wq, &sns_ctl.smd_read_work);
 	} else if (event == SMD_EVENT_OPEN) {
 		pr_debug("%s: Received SMD event Open\n", __func__);
 	} else if (event == SMD_EVENT_CLOSE) {
@@ -283,16 +290,14 @@
 {
 	unsigned long flags;
 	bool is_set;
-	pr_debug("%s: status=0x%x\n", __func__, sns_ocmem_status);
 
 	spin_lock_irqsave(&sns_ctl.sns_lock, flags);
 	is_set = sns_ctl.sns_ocmem_status & sns_ocmem_status;
 	spin_unlock_irqrestore(&sns_ctl.sns_lock, flags);
-	pr_debug("%s: is_set=%d\n", __func__, is_set);
 	return is_set;
 }
 
-/**
+/*
  * Wait for a response from ADSP or OCMEM Driver, timeout if necessary
  *
  * @param sns_ocmem_status Status flags to wait for.
@@ -301,14 +306,11 @@
  *
  * @return 0 If any status flag is set at any time prior to a timeout.
  *	0 if success or timedout ; <0 for failures
- *
  */
 static int sns_ocmem_wait(uint32_t sns_ocmem_status,
 			  uint32_t timeout_ms)
 {
 	int err;
-	pr_debug("%s: status=0x%x, timeout_ms=%d\n", __func__,
-						sns_ocmem_status, timeout_ms);
 	if (timeout_ms) {
 		err = wait_event_interruptible_timeout(sns_ctl.sns_wait,
 			sns_ocmem_is_status_set(sns_ocmem_status),
@@ -331,7 +333,7 @@
 	return err;
 }
 
-/**
+/*
  * Sends a message to the ADSP via SMD.
  *
  * @param hdr Specifies message type and other meta data
@@ -350,8 +352,6 @@
 
 	temp = kzalloc(sizeof(struct sns_ocmem_hdr_s) + hdr->msg_size,
 			GFP_KERNEL);
-	pr_debug("%s size=%d\n", __func__, size);
-
 	if (temp == NULL) {
 		pr_err("%s: allocation failure\n", __func__);
 		rv = -ENOMEM;
@@ -390,14 +390,12 @@
 	return rv;
 }
 
-/**
- *  Load ADSP Firmware.
+/*
+ * Load ADSP Firmware.
  */
 
 static int sns_load_adsp(void)
 {
-	pr_debug("%s.\n", __func__);
-
 	sns_ctl.pil = subsystem_get("adsp");
 	if (IS_ERR(sns_ctl.pil)) {
 		pr_err("%s: fail to load ADSP firmware\n", __func__);
@@ -493,7 +491,7 @@
 }
 
 
-/**
+/*
  * Initialize all sensors ocmem driver data fields and register with the
  * ocmem driver.
  *
@@ -505,8 +503,6 @@
 	struct sns_ocmem_hdr_s addr_req_hdr;
 	struct msm_bus_scale_pdata *sns_ocmem_bus_scale_pdata = NULL;
 
-	pr_debug("%s\n", __func__);
-
 	/* register from OCMEM callack */
 	sns_ctl.ocmem_handle =
 		ocmem_notifier_register(SNS_OCMEM_CLIENT_ID,
@@ -541,9 +537,10 @@
 		return -EFAULT;
 	}
 
-	/* wait before open SMD channel from kernel to ensure
-	channel has been openned already from ADSP side */
-	pr_debug("%s: sleep for 1000 ms\n", __func__);
+	/*
+	 * wait before open SMD channel from kernel to ensure
+	 * channel has been openned already from ADSP side
+	 */
 	msleep(1000);
 
 	err = smd_named_open_on_edge(SNS_OCMEM_SMD_CHANNEL,
@@ -558,9 +555,7 @@
 
 	pr_debug("%s: SMD channel openned successfuly!\n", __func__);
 	/* wait for the channel ready before writing data */
-	pr_debug("%s: sleep for 1000 ms\n", __func__);
 	msleep(1000);
-	pr_debug("%s sending PHYS_ADDR_REQ\n", __func__);
 	addr_req_hdr.msg_id = SNS_OCMEM_PHYS_ADDR_REQ_V01;
 	addr_req_hdr.msg_type = SNS_OCMEM_MSG_TYPE_REQ;
 	addr_req_hdr.msg_size = 0;
@@ -596,16 +591,14 @@
 	return 0;
 }
 
-/**
- *  Unmaps memory in ocmem back to DDR, indicates to the ADSP its completion,
- *  and waits for it to finish removing its bandwidth vote.
- *
+/*
+ * Unmaps memory in ocmem back to DDR, indicates to the ADSP its completion,
+ * and waits for it to finish removing its bandwidth vote.
  */
 static void sns_ocmem_unmap(void)
 {
 	unsigned long flags;
 	int err = 0;
-	pr_debug("%s\n", __func__);
 
 	ocmem_set_power_state(SNS_OCMEM_CLIENT_ID,
 				sns_ctl.buf, OCMEM_ON);
@@ -644,7 +637,7 @@
 				sns_ctl.buf, OCMEM_OFF);
 }
 
-/**
+/*
  * Waits for allocation to succeed.  This may take considerable time if the device
  * is presently in a high-power use case.
  *
@@ -653,7 +646,6 @@
 static int sns_ocmem_wait_for_alloc(void)
 {
 	int err = 0;
-	pr_debug("%s\n", __func__);
 
 	err = sns_ocmem_wait(SNS_OCMEM_ALLOC_GROW |
 				DSPS_HAS_NO_CLIENT, 0);
@@ -674,7 +666,7 @@
 	return 0;
 }
 
-/**
+/*
  * Kicks-off the mapping of memory from DDR to ocmem.  Waits for the process
  * to complete, then indicates so to the ADSP.
  *
@@ -684,7 +676,6 @@
 {
 	int err = 0;
 	unsigned long flags;
-	pr_debug("%s\n", __func__);
 
 	spin_lock_irqsave(&sns_ctl.sns_lock, flags);
 	sns_ctl.sns_ocmem_status &=
@@ -753,7 +744,7 @@
 	return err;
 }
 
-/**
+/*
  * Allocates memory in ocmem and maps to it from DDR.
  *
  * @return 0 upon success; <0 upon failure;
@@ -762,7 +753,6 @@
 {
 	int err = 0;
 	unsigned long flags;
-	pr_debug("%s\n", __func__);
 
 	if (sns_ctl.buf == NULL) {
 		spin_lock_irqsave(&sns_ctl.sns_lock, flags);
@@ -827,7 +817,7 @@
 	return err;
 }
 
-/**
+/*
  * Indicate to the ADSP that unmapping has completed, and wait for the response
  * that its bandwidth vote has been removed.
  *
@@ -838,7 +828,6 @@
 	int err;
 	struct sns_ocmem_hdr_s msg_hdr;
 	struct sns_ocmem_bw_vote_req_msg_v01 msg;
-	pr_debug("%s\n", __func__);
 
 	memset(&msg, 0, sizeof(struct sns_ocmem_bw_vote_req_msg_v01));
 
@@ -863,7 +852,7 @@
 	return err;
 }
 
-/**
+/*
  * Indicate to the ADSP that mapping has completed, and wait for the response
  * that its bandwidth vote has been made.
  *
@@ -875,7 +864,6 @@
 	struct sns_ocmem_hdr_s msg_hdr;
 	struct sns_ocmem_bw_vote_req_msg_v01 msg;
 	struct ocmem_vectors *vectors;
-	pr_debug("%s\n", __func__);
 
 	memset(&msg, 0, sizeof(struct sns_ocmem_bw_vote_req_msg_v01));
 
@@ -906,7 +894,7 @@
 	return err;
 }
 
-/**
+/*
  * Perform the encessary operations to clean-up OCMEM after being notified that
  * there is no longer a client; if sensors was evicted; or if some error
  * has occurred.
@@ -917,7 +905,6 @@
 static void sns_ocmem_evicted(bool do_free)
 {
 	int err = 0;
-	pr_debug("%s\n", __func__);
 
 	sns_ocmem_unmap();
 	if (do_free) {
@@ -933,7 +920,7 @@
 		pr_err("sns_ocmem_unmap_send failed %i\n", err);
 }
 
-/**
+/*
  * After mapping has completed and the ADSP has reacted appropriately, wait
  * for a shrink command or word from the ADSP that it no longer has a client.
  *
@@ -944,8 +931,6 @@
 	int err = 0;
 	unsigned long flags;
 
-	pr_debug("%s\n", __func__);
-
 	err = sns_ocmem_map_send();
 	if (err != 0) {
 		pr_err("sns_ocmem_map_send failed %i\n", err);
@@ -983,10 +968,9 @@
 	return err;
 }
 
-/**
+/*
  * Main function.
  * Initializes sensors ocmem feature, and waits for an ADSP client.
- *
  */
 static void sns_ocmem_main(struct work_struct *work)
 {
@@ -1027,17 +1011,15 @@
 static int sensors_adsp_open(struct inode *ip, struct file *fp)
 {
 	int ret = 0;
-	pr_debug("%s\n", __func__);
 	return ret;
 }
 
 static int sensors_adsp_release(struct inode *inode, struct file *file)
 {
-	pr_debug("%s\n", __func__);
 	return 0;
 }
 
-/**
+/*
  * Read QTimer clock ticks and scale down to 32KHz clock as used
  * in DSPS
  */
@@ -1056,20 +1038,17 @@
 	val <<= 4;
 	do_div(val, 9375);
 
-	pr_debug("%s.count=%llu\n", __func__, val);
 	return (u32)val;
 }
 
-/**
+/*
  * IO Control - handle commands from client.
- *
  */
 static long sensors_adsp_ioctl(struct file *file,
 			unsigned int cmd, unsigned long arg)
 {
 	int ret = 0;
 	u32 val = 0;
-	pr_debug("%s\n", __func__);
 
 	switch (cmd) {
 	case DSPS_IOCTL_READ_SLOW_TIMER:
@@ -1085,9 +1064,8 @@
 	return ret;
 }
 
-/**
+/*
  * platform driver
- *
  */
 const struct file_operations sensors_adsp_fops = {
 	.owner = THIS_MODULE,
@@ -1099,7 +1077,6 @@
 static int sensors_adsp_probe(struct platform_device *pdev)
 {
 	int ret = 0;
-	pr_debug("%s.\n", __func__);
 	sns_ctl.dev_class = class_create(THIS_MODULE, DRV_NAME);
 	if (sns_ctl.dev_class == NULL) {
 		pr_err("%s: class_create fail.\n", __func__);
@@ -1142,6 +1119,14 @@
 		goto cdev_add_err;
 	}
 
+	sns_ctl.smd_wq =
+			alloc_workqueue("smd_wq", WQ_NON_REENTRANT, 0);
+	if (!sns_ctl.smd_wq) {
+		pr_err("%s: Failed to create work queue\n",
+			__func__);
+		goto cdev_add_err;
+	}
+
 	init_waitqueue_head(&sns_ctl.sns_wait);
 	spin_lock_init(&sns_ctl.sns_lock);
 
@@ -1154,6 +1139,8 @@
 	sns_ctl.pdev = pdev;
 
 	INIT_WORK(&sns_ctl.sns_work, sns_ocmem_main);
+	INIT_WORK(&sns_ctl.smd_read_work, sns_ocmem_smd_read);
+
 	queue_work(sns_ctl.sns_workqueue, &sns_ctl.sns_work);
 
 	return 0;
@@ -1173,7 +1160,6 @@
 static int sensors_adsp_remove(struct platform_device *pdev)
 {
 	struct msm_bus_scale_pdata *sns_ocmem_bus_scale_pdata = NULL;
-	pr_debug("%s.\n", __func__);
 
 	sns_ocmem_bus_scale_pdata = (struct msm_bus_scale_pdata *)
 					dev_get_drvdata(&pdev->dev);
@@ -1185,6 +1171,7 @@
 	ocmem_notifier_unregister(sns_ctl.ocmem_handle,
 					&sns_ctl.ocmem_nb);
 	destroy_workqueue(sns_ctl.sns_workqueue);
+	destroy_workqueue(sns_ctl.smd_wq);
 
 	cdev_del(sns_ctl.cdev);
 	kfree(sns_ctl.cdev);
@@ -1213,13 +1200,12 @@
 	.remove = sensors_adsp_remove,
 };
 
-/**
+/*
  * Module Init.
  */
 static int sensors_adsp_init(void)
 {
 	int rc;
-	pr_debug("%s.\n", __func__);
 	pr_debug("%s driver version %s.\n", DRV_NAME, DRV_VERSION);
 
 	rc = platform_driver_register(&sensors_adsp_driver);
@@ -1233,12 +1219,11 @@
 	return 0;
 }
 
-/**
+/*
  * Module Exit.
  */
 static void sensors_adsp_exit(void)
 {
-	pr_debug("%s.\n", __func__);
 	platform_driver_unregister(&sensors_adsp_driver);
 }
 
diff --git a/arch/arm/mach-msm/sirc-fsm9xxx.c b/arch/arm/mach-msm/sirc-fsm9xxx.c
index 71fa60a..2bd347a 100644
--- a/arch/arm/mach-msm/sirc-fsm9xxx.c
+++ b/arch/arm/mach-msm/sirc-fsm9xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/sirc.c b/arch/arm/mach-msm/sirc.c
index 04124c5..6008619 100644
--- a/arch/arm/mach-msm/sirc.c
+++ b/arch/arm/mach-msm/sirc.c
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-msm/irq.c
  *
- * Copyright (c) 2009-2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2011 The Linux Foundation. All rights reserved.
  * Copyright (C) 2009 Google, Inc.
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/sirc.h b/arch/arm/mach-msm/sirc.h
index f719969..8f5f83f 100644
--- a/arch/arm/mach-msm/sirc.h
+++ b/arch/arm/mach-msm/sirc.h
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/sirc.h
  *
  * Copyright (C) 2009 Google, Inc.
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index 7427899..10e40b4 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/smd.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2013, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -44,6 +44,7 @@
 #include <mach/subsystem_notif.h>
 #include <mach/socinfo.h>
 #include <mach/proc_comm.h>
+#include <mach/msm_ipc_logging.h>
 #include <asm/cacheflush.h>
 
 #include "smd_private.h"
@@ -71,6 +72,7 @@
 #define SMD_VERSION 0x00020000
 #define SMSM_SNAPSHOT_CNT 64
 #define SMSM_SNAPSHOT_SIZE ((SMSM_NUM_ENTRIES + 1) * 4)
+#define RSPIN_INIT_WAIT_MS 1000
 
 uint32_t SMSM_NUM_ENTRIES = 8;
 uint32_t SMSM_NUM_HOSTS = 3;
@@ -190,33 +192,42 @@
 	SMSM_APPS_DEM_I = 3,
 };
 
-static int msm_smd_debug_mask;
+static int msm_smd_debug_mask = MSM_SMx_POWER_INFO;
 module_param_named(debug_mask, msm_smd_debug_mask,
 		   int, S_IRUGO | S_IWUSR | S_IWGRP);
+static void *smd_log_ctx;
+#define NUM_LOG_PAGES 4
+
+#define IPC_LOG(level, x...) do { \
+	if (smd_log_ctx) \
+		ipc_log_string(smd_log_ctx, x); \
+	else \
+		printk(level x); \
+	} while (0)
 
 #if defined(CONFIG_MSM_SMD_DEBUG)
 #define SMD_DBG(x...) do {				\
 		if (msm_smd_debug_mask & MSM_SMD_DEBUG) \
-			printk(KERN_DEBUG x);		\
+			IPC_LOG(KERN_DEBUG, x);		\
 	} while (0)
 
 #define SMSM_DBG(x...) do {					\
 		if (msm_smd_debug_mask & MSM_SMSM_DEBUG)	\
-			printk(KERN_DEBUG x);			\
+			IPC_LOG(KERN_DEBUG, x);		\
 	} while (0)
 
 #define SMD_INFO(x...) do {			 	\
 		if (msm_smd_debug_mask & MSM_SMD_INFO)	\
-			printk(KERN_INFO x);		\
+			IPC_LOG(KERN_INFO, x);		\
 	} while (0)
 
 #define SMSM_INFO(x...) do {				\
 		if (msm_smd_debug_mask & MSM_SMSM_INFO) \
-			printk(KERN_INFO x);		\
+			IPC_LOG(KERN_INFO, x);		\
 	} while (0)
 #define SMx_POWER_INFO(x...) do {				\
 		if (msm_smd_debug_mask & MSM_SMx_POWER_INFO) \
-			printk(KERN_INFO x);		\
+			IPC_LOG(KERN_INFO, x);		\
 	} while (0)
 #else
 #define SMD_DBG(x...) do { } while (0)
@@ -373,6 +384,8 @@
 static RAW_NOTIFIER_HEAD(smd_module_init_notifier_list);
 static DEFINE_MUTEX(smd_module_init_notifier_lock);
 static void smd_module_init_notify(uint32_t state, void *data);
+static int smd_stream_write_avail(struct smd_channel *ch);
+static int smd_stream_read_avail(struct smd_channel *ch);
 
 static inline void smd_write_intr(unsigned int val,
 				const void __iomem *addr)
@@ -381,10 +394,34 @@
 	__raw_writel(val, addr);
 }
 
-static inline void notify_modem_smd(void)
+static inline void log_notify(uint32_t subsystem, smd_channel_t *ch)
+{
+	const char *subsys = smd_edge_to_subsystem(subsystem);
+
+	(void) subsys;
+
+	if (!ch)
+		SMx_POWER_INFO("Apps->%s\n", subsys);
+	else
+		SMx_POWER_INFO(
+			"Apps->%s ch%d '%s': tx%d/rx%d %dr/%dw : %dr/%dw\n",
+			subsys, ch->n, ch->name,
+			ch->fifo_size -
+				(smd_stream_write_avail(ch) + 1),
+			smd_stream_read_avail(ch),
+			ch->half_ch->get_tail(ch->send),
+			ch->half_ch->get_head(ch->send),
+			ch->half_ch->get_tail(ch->recv),
+			ch->half_ch->get_head(ch->recv)
+			);
+}
+
+static inline void notify_modem_smd(smd_channel_t *ch)
 {
 	static const struct interrupt_config_item *intr
 	   = &private_intr_config[SMD_MODEM].smd;
+
+	log_notify(SMD_APPS_MODEM, ch);
 	if (intr->out_base) {
 		++interrupt_stats[SMD_MODEM].smd_out_config_count;
 		smd_write_intr(intr->out_bit_pos,
@@ -395,10 +432,12 @@
 	}
 }
 
-static inline void notify_dsp_smd(void)
+static inline void notify_dsp_smd(smd_channel_t *ch)
 {
 	static const struct interrupt_config_item *intr
 		= &private_intr_config[SMD_Q6].smd;
+
+	log_notify(SMD_APPS_QDSP, ch);
 	if (intr->out_base) {
 		++interrupt_stats[SMD_Q6].smd_out_config_count;
 		smd_write_intr(intr->out_bit_pos,
@@ -409,10 +448,12 @@
 	}
 }
 
-static inline void notify_dsps_smd(void)
+static inline void notify_dsps_smd(smd_channel_t *ch)
 {
 	static const struct interrupt_config_item *intr
 		= &private_intr_config[SMD_DSPS].smd;
+
+	log_notify(SMD_APPS_DSPS, ch);
 	if (intr->out_base) {
 		++interrupt_stats[SMD_DSPS].smd_out_config_count;
 		smd_write_intr(intr->out_bit_pos,
@@ -423,11 +464,12 @@
 	}
 }
 
-static inline void notify_wcnss_smd(void)
+static inline void notify_wcnss_smd(struct smd_channel *ch)
 {
 	static const struct interrupt_config_item *intr
 		= &private_intr_config[SMD_WCNSS].smd;
 
+	log_notify(SMD_APPS_WCNSS, ch);
 	if (intr->out_base) {
 		++interrupt_stats[SMD_WCNSS].smd_out_config_count;
 		smd_write_intr(intr->out_bit_pos,
@@ -438,12 +480,13 @@
 	}
 }
 
-static inline void notify_rpm_smd(void)
+static inline void notify_rpm_smd(smd_channel_t *ch)
 {
 	static const struct interrupt_config_item *intr
 		= &private_intr_config[SMD_RPM].smd;
 
 	if (intr->out_base) {
+		log_notify(SMD_APPS_RPM, ch);
 		++interrupt_stats[SMD_RPM].smd_out_config_count;
 		smd_write_intr(intr->out_bit_pos,
 		intr->out_base + intr->out_offset);
@@ -656,47 +699,6 @@
 	struct smd_half_channel_word_access ch1;
 };
 
-struct smd_channel {
-	volatile void *send; /* some variant of smd_half_channel */
-	volatile void *recv; /* some variant of smd_half_channel */
-	unsigned char *send_data;
-	unsigned char *recv_data;
-	unsigned fifo_size;
-	unsigned fifo_mask;
-	struct list_head ch_list;
-
-	unsigned current_packet;
-	unsigned n;
-	void *priv;
-	void (*notify)(void *priv, unsigned flags);
-
-	int (*read)(smd_channel_t *ch, void *data, int len, int user_buf);
-	int (*write)(smd_channel_t *ch, const void *data, int len,
-			int user_buf);
-	int (*read_avail)(smd_channel_t *ch);
-	int (*write_avail)(smd_channel_t *ch);
-	int (*read_from_cb)(smd_channel_t *ch, void *data, int len,
-			int user_buf);
-
-	void (*update_state)(smd_channel_t *ch);
-	unsigned last_state;
-	void (*notify_other_cpu)(void);
-
-	char name[20];
-	struct platform_device pdev;
-	unsigned type;
-
-	int pending_pkt_sz;
-
-	char is_pkt_ch;
-
-	/*
-	 * private internal functions to access *send and *recv.
-	 * never to be exported outside of smd
-	 */
-	struct smd_half_channel_access *half_ch;
-};
-
 struct edge_to_pid {
 	uint32_t	local_pid;
 	uint32_t	remote_pid;
@@ -973,7 +975,7 @@
 	struct smd_alloc_elm *shared;
 	unsigned long flags;
 
-	SMD_DBG("%s: starting reset\n", __func__);
+	SMx_POWER_INFO("%s: starting reset\n", __func__);
 
 	/* release any held spinlocks */
 	remote_spin_release(&remote_spinlock, restart_pid);
@@ -1014,11 +1016,11 @@
 	/* notify SMD processors */
 	mb();
 	smd_fake_irq_handler(0);
-	notify_modem_smd();
-	notify_dsp_smd();
-	notify_dsps_smd();
-	notify_wcnss_smd();
-	notify_rpm_smd();
+	notify_modem_smd(NULL);
+	notify_dsp_smd(NULL);
+	notify_dsps_smd(NULL);
+	notify_wcnss_smd(NULL);
+	notify_rpm_smd(NULL);
 
 	/* change all remote states to CLOSED */
 	mutex_lock(&smd_probe_lock);
@@ -1030,13 +1032,13 @@
 	/* notify SMD processors */
 	mb();
 	smd_fake_irq_handler(0);
-	notify_modem_smd();
-	notify_dsp_smd();
-	notify_dsps_smd();
-	notify_wcnss_smd();
-	notify_rpm_smd();
+	notify_modem_smd(NULL);
+	notify_dsp_smd(NULL);
+	notify_dsps_smd(NULL);
+	notify_wcnss_smd(NULL);
+	notify_rpm_smd(NULL);
 
-	SMD_DBG("%s: finished reset\n", __func__);
+	SMx_POWER_INFO("%s: finished reset\n", __func__);
 }
 
 /* how many bytes are available for reading */
@@ -1214,7 +1216,7 @@
 	}
 	ch->half_ch->set_state(ch->send, n);
 	ch->half_ch->set_fSTATE(ch->send, 1);
-	ch->notify_other_cpu();
+	ch->notify_other_cpu(ch);
 }
 
 static void do_smd_probe(void)
@@ -1290,7 +1292,8 @@
 	spin_unlock_irqrestore(&smd_lock, flags);
 }
 
-static void handle_smd_irq(struct list_head *list, void (*notify)(void))
+static void handle_smd_irq(struct list_head *list,
+		void (*notify)(smd_channel_t *ch))
 {
 	unsigned long flags;
 	struct smd_channel *ch;
@@ -1325,10 +1328,18 @@
 		}
 		if (ch_flags & 0x3) {
 			ch->update_state(ch);
-			SMx_POWER_INFO("SMD ch%d '%s' Data event r%d/w%d\n",
-					ch->n, ch->name,
-					ch->read_avail(ch),
-					ch->fifo_size - ch->write_avail(ch));
+			SMx_POWER_INFO(
+				"SMD ch%d '%s' Data event 0x%x tx%d/rx%d %dr/%dw : %dr/%dw\n",
+				ch->n, ch->name,
+				ch_flags,
+				ch->fifo_size -
+					(smd_stream_write_avail(ch) + 1),
+				smd_stream_read_avail(ch),
+				ch->half_ch->get_tail(ch->send),
+				ch->half_ch->get_head(ch->send),
+				ch->half_ch->get_tail(ch->recv),
+				ch->half_ch->get_head(ch->recv)
+				);
 			ch->notify(ch->priv, SMD_EVENT_DATA);
 		}
 		if (ch_flags & 0x4 && !state_change) {
@@ -1341,9 +1352,18 @@
 	do_smd_probe();
 }
 
+static inline void log_irq(uint32_t subsystem)
+{
+	const char *subsys = smd_edge_to_subsystem(subsystem);
+
+	(void) subsys;
+
+	SMx_POWER_INFO("SMD Int %s->Apps\n", subsys);
+}
+
 static irqreturn_t smd_modem_irq_handler(int irq, void *data)
 {
-	SMx_POWER_INFO("SMD Int Modem->Apps\n");
+	log_irq(SMD_APPS_MODEM);
 	++interrupt_stats[SMD_MODEM].smd_in_count;
 	handle_smd_irq(&smd_ch_list_modem, notify_modem_smd);
 	handle_smd_irq_closing_list();
@@ -1352,7 +1372,7 @@
 
 static irqreturn_t smd_dsp_irq_handler(int irq, void *data)
 {
-	SMx_POWER_INFO("SMD Int LPASS->Apps\n");
+	log_irq(SMD_APPS_QDSP);
 	++interrupt_stats[SMD_Q6].smd_in_count;
 	handle_smd_irq(&smd_ch_list_dsp, notify_dsp_smd);
 	handle_smd_irq_closing_list();
@@ -1361,7 +1381,7 @@
 
 static irqreturn_t smd_dsps_irq_handler(int irq, void *data)
 {
-	SMx_POWER_INFO("SMD Int DSPS->Apps\n");
+	log_irq(SMD_APPS_DSPS);
 	++interrupt_stats[SMD_DSPS].smd_in_count;
 	handle_smd_irq(&smd_ch_list_dsps, notify_dsps_smd);
 	handle_smd_irq_closing_list();
@@ -1370,7 +1390,7 @@
 
 static irqreturn_t smd_wcnss_irq_handler(int irq, void *data)
 {
-	SMx_POWER_INFO("SMD Int WCNSS->Apps\n");
+	log_irq(SMD_APPS_WCNSS);
 	++interrupt_stats[SMD_WCNSS].smd_in_count;
 	handle_smd_irq(&smd_ch_list_wcnss, notify_wcnss_smd);
 	handle_smd_irq_closing_list();
@@ -1379,7 +1399,7 @@
 
 static irqreturn_t smd_rpm_irq_handler(int irq, void *data)
 {
-	SMx_POWER_INFO("SMD Int RPM->Apps\n");
+	log_irq(SMD_APPS_RPM);
 	++interrupt_stats[SMD_RPM].smd_in_count;
 	handle_smd_irq(&smd_ch_list_rpm, notify_rpm_smd);
 	handle_smd_irq_closing_list();
@@ -1514,7 +1534,7 @@
 	}
 
 	if (orig_len - len)
-		ch->notify_other_cpu();
+		ch->notify_other_cpu(ch);
 
 	return orig_len - len;
 }
@@ -1566,7 +1586,7 @@
 	r = ch_read(ch, data, len, user_buf);
 	if (r > 0)
 		if (!read_intr_blocked(ch))
-			ch->notify_other_cpu();
+			ch->notify_other_cpu(ch);
 
 	return r;
 }
@@ -1585,7 +1605,7 @@
 	r = ch_read(ch, data, len, user_buf);
 	if (r > 0)
 		if (!read_intr_blocked(ch))
-			ch->notify_other_cpu();
+			ch->notify_other_cpu(ch);
 
 	spin_lock_irqsave(&smd_lock, flags);
 	ch->current_packet -= r;
@@ -1609,7 +1629,7 @@
 	r = ch_read(ch, data, len, user_buf);
 	if (r > 0)
 		if (!read_intr_blocked(ch))
-			ch->notify_other_cpu();
+			ch->notify_other_cpu(ch);
 
 	ch->current_packet -= r;
 	update_packet_state(ch);
@@ -1767,7 +1787,7 @@
 	return 0;
 }
 
-static inline void notify_loopback_smd(void)
+static inline void notify_loopback_smd(smd_channel_t *ch_notif)
 {
 	unsigned long flags;
 	struct smd_channel *ch;
@@ -2290,7 +2310,7 @@
 
 	ch->half_ch->set_fSTATE(ch->send, 1);
 	barrier();
-	ch->notify_other_cpu();
+	ch->notify_other_cpu(ch);
 
 	return 0;
 }
@@ -2515,6 +2535,18 @@
 	struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
 	int i;
 	struct smsm_size_info_type *smsm_size_info;
+	unsigned long flags;
+	unsigned long j_start;
+
+	/* Verify that remote spinlock is not deadlocked */
+	j_start = jiffies;
+	while (!remote_spin_trylock_irqsave(&remote_spinlock, flags)) {
+		if (jiffies_to_msecs(jiffies - j_start) > RSPIN_INIT_WAIT_MS) {
+			panic("%s: Remote processor %d will not release spinlock\n",
+				__func__, remote_spin_owner(&remote_spinlock));
+		}
+	}
+	remote_spin_unlock_irqrestore(&remote_spinlock, flags);
 
 	smsm_size_info = smem_alloc(SMEM_SMSM_SIZE_INFO,
 				sizeof(struct smsm_size_info_type));
@@ -3153,6 +3185,17 @@
 }
 EXPORT_SYMBOL(smsm_state_cb_deregister);
 
+/**
+ * smem_get_remote_spinlock - Remote spinlock pointer for unit testing.
+ *
+ * @returns: pointer to SMEM remote spinlock
+ */
+remote_spinlock_t *smem_get_remote_spinlock(void)
+{
+	return &remote_spinlock;
+}
+EXPORT_SYMBOL(smem_get_remote_spinlock);
+
 int smd_module_init_notifier_register(struct notifier_block *nb)
 {
 	int ret;
@@ -3864,6 +3907,11 @@
 				  unsigned long code,
 				  void *data)
 {
+	/*
+	 * Some SMD or SMSM clients assume SMD/SMSM SSR handling will be
+	 * done in the AFTER_SHUTDOWN level.  If this ever changes, extra
+	 * care should be taken to verify no clients are broken.
+	 */
 	if (code == SUBSYS_AFTER_SHUTDOWN) {
 		struct restart_notifier_block *notifier;
 
@@ -3917,6 +3965,12 @@
 	if (registered)
 		return 0;
 
+	smd_log_ctx = ipc_log_context_create(NUM_LOG_PAGES, "smd");
+	if (!smd_log_ctx) {
+		pr_err("%s: unable to create logging context\n", __func__);
+		msm_smd_debug_mask = 0;
+	}
+
 	registered = true;
 	rc = remote_spin_lock_init(&remote_spinlock, SMEM_SPINLOCK_SMEM_ALLOC);
 	if (rc) {
diff --git a/arch/arm/mach-msm/smd_debug.c b/arch/arm/mach-msm/smd_debug.c
index cc82a01..4dcf72f 100644
--- a/arch/arm/mach-msm/smd_debug.c
+++ b/arch/arm/mach-msm/smd_debug.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/smd_debug.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -103,14 +103,14 @@
 	const char *subsys_name;
 
 	i += scnprintf(buf + i, max - i,
-		"   Subsystem    | Interrupt ID |     In    | Out (Hardcoded) |"
-		" Out (Configured) |\n");
+		"   Subsystem    | Interrupt ID |    In     | Out (Hardcoded) |"
+		" Out (Configured)|\n");
 
 	for (subsys = 0; subsys < NUM_SMD_SUBSYSTEMS; ++subsys) {
 		subsys_name = smd_pid_to_subsystem(subsys);
 		if (subsys_name) {
 			i += scnprintf(buf + i, max - i,
-				"%-10s %4s |    %9d | %9u |       %9u |        %9u |\n",
+				"%-10s %4s |    %9d | %9u |       %9u |       %9u |\n",
 				smd_pid_to_subsystem(subsys), "smd",
 				stats->smd_interrupt_id,
 				stats->smd_in_count,
@@ -118,7 +118,7 @@
 				stats->smd_out_config_count);
 
 			i += scnprintf(buf + i, max - i,
-				"%-10s %4s |    %9d | %9u |       %9u |        %9u |\n",
+				"%-10s %4s |    %9d | %9u |       %9u |       %9u |\n",
 				smd_pid_to_subsystem(subsys), "smsm",
 				stats->smsm_interrupt_id,
 				stats->smsm_in_count,
diff --git a/arch/arm/mach-msm/smd_nmea.c b/arch/arm/mach-msm/smd_nmea.c
index 1aedbf5..d1b2b2d 100644
--- a/arch/arm/mach-msm/smd_nmea.c
+++ b/arch/arm/mach-msm/smd_nmea.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/arch/arm/mach-msm/smd_pkt.c b/arch/arm/mach-msm/smd_pkt.c
index 73ebdf6..eb7aa8a 100644
--- a/arch/arm/mach-msm/smd_pkt.c
+++ b/arch/arm/mach-msm/smd_pkt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
@@ -41,7 +41,7 @@
 #ifdef CONFIG_ARCH_FSM9XXX
 #define NUM_SMD_PKT_PORTS 4
 #else
-#define NUM_SMD_PKT_PORTS 24
+#define NUM_SMD_PKT_PORTS 27
 #endif
 
 #define PDRIVER_NAME_MAX_SIZE 32
@@ -725,6 +725,9 @@
 	"smdcntl8",
 	"smd_sns_adsp",
 	"smd_cxm_qmi",
+	"smd_test_framework",
+	"smd_logging_0",
+	"smd_data_0",
 	"smd_pkt_loopback",
 };
 
@@ -752,6 +755,9 @@
 	"DATA40_CNTL",
 	"SENSOR",
 	"CXM_QMI_PORT_8064",
+	"TESTFRAMEWORK",
+	"LOGGING",
+	"DATA",
 	"LOOPBACK",
 };
 
@@ -779,6 +785,9 @@
 	SMD_APPS_MODEM,
 	SMD_APPS_QDSP,
 	SMD_APPS_WCNSS,
+	SMD_APPS_QDSP,
+	SMD_APPS_QDSP,
+	SMD_APPS_QDSP,
 	SMD_APPS_MODEM,
 };
 #endif
@@ -855,6 +864,12 @@
 				r = PTR_ERR(smd_pkt_devp->pil);
 				pr_err("%s failed on smd_pkt_dev id:%d - subsystem_get failed for %s\n",
 					__func__, smd_pkt_devp->i, peripheral);
+				/*
+				 * Sleep inorder to reduce the frequency of
+				 * retry by user-space modules and to avoid
+				 * possible watchdog bite.
+				 */
+				msleep((smd_pkt_devp->open_modem_wait * 1000));
 				goto release_pd;
 			}
 
diff --git a/arch/arm/mach-msm/smd_private.c b/arch/arm/mach-msm/smd_private.c
index 5a78b6f..94192d3 100644
--- a/arch/arm/mach-msm/smd_private.c
+++ b/arch/arm/mach-msm/smd_private.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -12,227 +12,256 @@
 
 #include "smd_private.h"
 
-void set_state(volatile void *half_channel, unsigned data)
+void set_state(volatile void __iomem *half_channel, unsigned data)
 {
-	((struct smd_half_channel *)(half_channel))->state = data;
+	((struct smd_half_channel __force *)(half_channel))->state = data;
 }
 
-unsigned get_state(volatile void *half_channel)
+unsigned get_state(volatile void __iomem *half_channel)
 {
-	return ((struct smd_half_channel *)(half_channel))->state;
+	return ((struct smd_half_channel __force *)(half_channel))->state;
 }
 
-void set_fDSR(volatile void *half_channel, unsigned char data)
+void set_fDSR(volatile void __iomem *half_channel, unsigned char data)
 {
-	((struct smd_half_channel *)(half_channel))->fDSR = data;
+	((struct smd_half_channel __force *)(half_channel))->fDSR = data;
 }
 
-unsigned get_fDSR(volatile void *half_channel)
+unsigned get_fDSR(volatile void __iomem *half_channel)
 {
-	return ((struct smd_half_channel *)(half_channel))->fDSR;
+	return ((struct smd_half_channel __force *)(half_channel))->fDSR;
 }
 
-void set_fCTS(volatile void *half_channel, unsigned char data)
+void set_fCTS(volatile void __iomem *half_channel, unsigned char data)
 {
-	((struct smd_half_channel *)(half_channel))->fCTS = data;
+	((struct smd_half_channel __force *)(half_channel))->fCTS = data;
 }
 
-unsigned get_fCTS(volatile void *half_channel)
+unsigned get_fCTS(volatile void __iomem *half_channel)
 {
-	return ((struct smd_half_channel *)(half_channel))->fCTS;
+	return ((struct smd_half_channel __force *)(half_channel))->fCTS;
 }
 
-void set_fCD(volatile void *half_channel, unsigned char data)
+void set_fCD(volatile void __iomem *half_channel, unsigned char data)
 {
-	((struct smd_half_channel *)(half_channel))->fCD = data;
+	((struct smd_half_channel __force *)(half_channel))->fCD = data;
 }
 
-unsigned get_fCD(volatile void *half_channel)
+unsigned get_fCD(volatile void __iomem *half_channel)
 {
-	return ((struct smd_half_channel *)(half_channel))->fCD;
+	return ((struct smd_half_channel __force *)(half_channel))->fCD;
 }
 
-void set_fRI(volatile void *half_channel, unsigned char data)
+void set_fRI(volatile void __iomem *half_channel, unsigned char data)
 {
-	((struct smd_half_channel *)(half_channel))->fRI = data;
+	((struct smd_half_channel __force *)(half_channel))->fRI = data;
 }
 
-unsigned get_fRI(volatile void *half_channel)
+unsigned get_fRI(volatile void __iomem *half_channel)
 {
-	return ((struct smd_half_channel *)(half_channel))->fRI;
+	return ((struct smd_half_channel __force *)(half_channel))->fRI;
 }
 
-void set_fHEAD(volatile void *half_channel, unsigned char data)
+void set_fHEAD(volatile void __iomem *half_channel, unsigned char data)
 {
-	((struct smd_half_channel *)(half_channel))->fHEAD = data;
+	((struct smd_half_channel __force *)(half_channel))->fHEAD = data;
 }
 
-unsigned get_fHEAD(volatile void *half_channel)
+unsigned get_fHEAD(volatile void __iomem *half_channel)
 {
-	return ((struct smd_half_channel *)(half_channel))->fHEAD;
+	return ((struct smd_half_channel __force *)(half_channel))->fHEAD;
 }
 
-void set_fTAIL(volatile void *half_channel, unsigned char data)
+void set_fTAIL(volatile void __iomem *half_channel, unsigned char data)
 {
-	((struct smd_half_channel *)(half_channel))->fTAIL = data;
+	((struct smd_half_channel __force *)(half_channel))->fTAIL = data;
 }
 
-unsigned get_fTAIL(volatile void *half_channel)
+unsigned get_fTAIL(volatile void __iomem *half_channel)
 {
-	return ((struct smd_half_channel *)(half_channel))->fTAIL;
+	return ((struct smd_half_channel __force *)(half_channel))->fTAIL;
 }
 
-void set_fSTATE(volatile void *half_channel, unsigned char data)
+void set_fSTATE(volatile void __iomem *half_channel, unsigned char data)
 {
-	((struct smd_half_channel *)(half_channel))->fSTATE = data;
+	((struct smd_half_channel __force *)(half_channel))->fSTATE = data;
 }
 
-unsigned get_fSTATE(volatile void *half_channel)
+unsigned get_fSTATE(volatile void __iomem *half_channel)
 {
-	return ((struct smd_half_channel *)(half_channel))->fSTATE;
+	return ((struct smd_half_channel __force *)(half_channel))->fSTATE;
 }
 
-void set_fBLOCKREADINTR(volatile void *half_channel, unsigned char data)
+void set_fBLOCKREADINTR(volatile void __iomem *half_channel, unsigned char data)
 {
-	((struct smd_half_channel *)(half_channel))->fBLOCKREADINTR = data;
+	((struct smd_half_channel __force *)
+				(half_channel))->fBLOCKREADINTR = data;
 }
 
-unsigned get_fBLOCKREADINTR(volatile void *half_channel)
+unsigned get_fBLOCKREADINTR(volatile void __iomem *half_channel)
 {
-	return ((struct smd_half_channel *)(half_channel))->fBLOCKREADINTR;
+	return ((struct smd_half_channel __force *)
+				(half_channel))->fBLOCKREADINTR;
 }
 
-void set_tail(volatile void *half_channel, unsigned data)
+void set_tail(volatile void __iomem *half_channel, unsigned data)
 {
-	((struct smd_half_channel *)(half_channel))->tail = data;
+	((struct smd_half_channel __force *)(half_channel))->tail = data;
 }
 
-unsigned get_tail(volatile void *half_channel)
+unsigned get_tail(volatile void __iomem *half_channel)
 {
-	return ((struct smd_half_channel *)(half_channel))->tail;
+	return ((struct smd_half_channel __force *)(half_channel))->tail;
 }
 
-void set_head(volatile void *half_channel, unsigned data)
+void set_head(volatile void __iomem *half_channel, unsigned data)
 {
-	((struct smd_half_channel *)(half_channel))->head = data;
+	((struct smd_half_channel __force *)(half_channel))->head = data;
 }
 
-unsigned get_head(volatile void *half_channel)
+unsigned get_head(volatile void __iomem *half_channel)
 {
-	return ((struct smd_half_channel *)(half_channel))->head;
+	return ((struct smd_half_channel __force *)(half_channel))->head;
 }
 
-void set_state_word_access(volatile void *half_channel, unsigned data)
+void set_state_word_access(volatile void __iomem *half_channel, unsigned data)
 {
-	((struct smd_half_channel_word_access *)(half_channel))->state = data;
+	((struct smd_half_channel_word_access __force *)
+					(half_channel))->state = data;
 }
 
-unsigned get_state_word_access(volatile void *half_channel)
+unsigned get_state_word_access(volatile void __iomem *half_channel)
 {
-	return ((struct smd_half_channel_word_access *)(half_channel))->state;
+	return ((struct smd_half_channel_word_access __force *)
+					(half_channel))->state;
 }
 
-void set_fDSR_word_access(volatile void *half_channel, unsigned char data)
+void set_fDSR_word_access(volatile void __iomem *half_channel,
+						unsigned char data)
 {
-	((struct smd_half_channel_word_access *)(half_channel))->fDSR = data;
+	((struct smd_half_channel_word_access __force *)
+					(half_channel))->fDSR = data;
 }
 
-unsigned get_fDSR_word_access(volatile void *half_channel)
+unsigned get_fDSR_word_access(volatile void __iomem *half_channel)
 {
-	return ((struct smd_half_channel_word_access *)(half_channel))->fDSR;
+	return ((struct smd_half_channel_word_access __force *)
+					(half_channel))->fDSR;
 }
 
-void set_fCTS_word_access(volatile void *half_channel, unsigned char data)
+void set_fCTS_word_access(volatile void __iomem *half_channel,
+						unsigned char data)
 {
-	((struct smd_half_channel_word_access *)(half_channel))->fCTS = data;
+	((struct smd_half_channel_word_access __force *)
+					(half_channel))->fCTS = data;
 }
 
-unsigned get_fCTS_word_access(volatile void *half_channel)
+unsigned get_fCTS_word_access(volatile void __iomem *half_channel)
 {
-	return ((struct smd_half_channel_word_access *)(half_channel))->fCTS;
+	return ((struct smd_half_channel_word_access __force *)
+					(half_channel))->fCTS;
 }
 
-void set_fCD_word_access(volatile void *half_channel, unsigned char data)
+void set_fCD_word_access(volatile void __iomem *half_channel,
+						unsigned char data)
 {
-	((struct smd_half_channel_word_access *)(half_channel))->fCD = data;
+	((struct smd_half_channel_word_access __force *)
+					(half_channel))->fCD = data;
 }
 
-unsigned get_fCD_word_access(volatile void *half_channel)
+unsigned get_fCD_word_access(volatile void __iomem *half_channel)
 {
-	return ((struct smd_half_channel_word_access *)(half_channel))->fCD;
+	return ((struct smd_half_channel_word_access __force *)
+					(half_channel))->fCD;
 }
 
-void set_fRI_word_access(volatile void *half_channel, unsigned char data)
+void set_fRI_word_access(volatile void __iomem *half_channel,
+						unsigned char data)
 {
-	((struct smd_half_channel_word_access *)(half_channel))->fRI = data;
+	((struct smd_half_channel_word_access __force *)
+					(half_channel))->fRI = data;
 }
 
-unsigned get_fRI_word_access(volatile void *half_channel)
+unsigned get_fRI_word_access(volatile void __iomem *half_channel)
 {
-	return ((struct smd_half_channel_word_access *)(half_channel))->fRI;
+	return ((struct smd_half_channel_word_access __force *)
+					(half_channel))->fRI;
 }
 
-void set_fHEAD_word_access(volatile void *half_channel, unsigned char data)
+void set_fHEAD_word_access(volatile void __iomem *half_channel,
+						unsigned char data)
 {
-	((struct smd_half_channel_word_access *)(half_channel))->fHEAD = data;
+	((struct smd_half_channel_word_access __force *)
+					(half_channel))->fHEAD = data;
 }
 
-unsigned get_fHEAD_word_access(volatile void *half_channel)
+unsigned get_fHEAD_word_access(volatile void __iomem *half_channel)
 {
-	return ((struct smd_half_channel_word_access *)(half_channel))->fHEAD;
+	return ((struct smd_half_channel_word_access __force *)
+					(half_channel))->fHEAD;
 }
 
-void set_fTAIL_word_access(volatile void *half_channel, unsigned char data)
+void set_fTAIL_word_access(volatile void __iomem *half_channel,
+						unsigned char data)
 {
-	((struct smd_half_channel_word_access *)(half_channel))->fTAIL = data;
+	((struct smd_half_channel_word_access __force *)
+					(half_channel))->fTAIL = data;
 }
 
-unsigned get_fTAIL_word_access(volatile void *half_channel)
+unsigned get_fTAIL_word_access(volatile void __iomem *half_channel)
 {
-	return ((struct smd_half_channel_word_access *)(half_channel))->fTAIL;
+	return ((struct smd_half_channel_word_access __force *)
+					(half_channel))->fTAIL;
 }
 
-void set_fSTATE_word_access(volatile void *half_channel, unsigned char data)
+void set_fSTATE_word_access(volatile void __iomem *half_channel,
+						unsigned char data)
 {
-	((struct smd_half_channel_word_access *)(half_channel))->fSTATE = data;
+	((struct smd_half_channel_word_access __force *)
+					(half_channel))->fSTATE = data;
 }
 
-unsigned get_fSTATE_word_access(volatile void *half_channel)
+unsigned get_fSTATE_word_access(volatile void __iomem *half_channel)
 {
-	return ((struct smd_half_channel_word_access *)(half_channel))->fSTATE;
+	return ((struct smd_half_channel_word_access __force *)
+					(half_channel))->fSTATE;
 }
 
-void set_fBLOCKREADINTR_word_access(volatile void *half_channel,
+void set_fBLOCKREADINTR_word_access(volatile void __iomem *half_channel,
 							unsigned char data)
 {
-	((struct smd_half_channel_word_access *)
+	((struct smd_half_channel_word_access __force *)
 					(half_channel))->fBLOCKREADINTR = data;
 }
 
-unsigned get_fBLOCKREADINTR_word_access(volatile void *half_channel)
+unsigned get_fBLOCKREADINTR_word_access(volatile void __iomem *half_channel)
 {
-	return ((struct smd_half_channel_word_access *)
-						(half_channel))->fBLOCKREADINTR;
+	return ((struct smd_half_channel_word_access __force *)
+					(half_channel))->fBLOCKREADINTR;
 }
 
-void set_tail_word_access(volatile void *half_channel, unsigned data)
+void set_tail_word_access(volatile void __iomem *half_channel, unsigned data)
 {
-	((struct smd_half_channel_word_access *)(half_channel))->tail = data;
+	((struct smd_half_channel_word_access __force *)
+					(half_channel))->tail = data;
 }
 
-unsigned get_tail_word_access(volatile void *half_channel)
+unsigned get_tail_word_access(volatile void __iomem *half_channel)
 {
-	return ((struct smd_half_channel_word_access *)(half_channel))->tail;
+	return ((struct smd_half_channel_word_access __force *)
+					(half_channel))->tail;
 }
 
-void set_head_word_access(volatile void *half_channel, unsigned data)
+void set_head_word_access(volatile void __iomem *half_channel, unsigned data)
 {
-	((struct smd_half_channel_word_access *)(half_channel))->head = data;
+	((struct smd_half_channel_word_access __force *)
+					(half_channel))->head = data;
 }
 
-unsigned get_head_word_access(volatile void *half_channel)
+unsigned get_head_word_access(volatile void __iomem *half_channel)
 {
-	return ((struct smd_half_channel_word_access *)(half_channel))->head;
+	return ((struct smd_half_channel_word_access __force *)
+					(half_channel))->head;
 }
 
 int is_word_access_ch(unsigned ch_type)
diff --git a/arch/arm/mach-msm/smd_private.h b/arch/arm/mach-msm/smd_private.h
index 7f39a24..4a6a509 100644
--- a/arch/arm/mach-msm/smd_private.h
+++ b/arch/arm/mach-msm/smd_private.h
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/smd_private.h
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -18,6 +18,9 @@
 
 #include <linux/types.h>
 #include <linux/spinlock.h>
+#include <linux/errno.h>
+#include <linux/remote_spinlock.h>
+#include <linux/platform_device.h>
 #include <mach/msm_smsm.h>
 #include <mach/msm_smd.h>
 
@@ -147,29 +150,36 @@
 };
 
 struct smd_half_channel_access {
-	void (*set_state)(volatile void *half_channel, unsigned data);
-	unsigned (*get_state)(volatile void *half_channel);
-	void (*set_fDSR)(volatile void *half_channel, unsigned char data);
-	unsigned (*get_fDSR)(volatile void *half_channel);
-	void (*set_fCTS)(volatile void *half_channel, unsigned char data);
-	unsigned (*get_fCTS)(volatile void *half_channel);
-	void (*set_fCD)(volatile void *half_channel, unsigned char data);
-	unsigned (*get_fCD)(volatile void *half_channel);
-	void (*set_fRI)(volatile void *half_channel, unsigned char data);
-	unsigned (*get_fRI)(volatile void *half_channel);
-	void (*set_fHEAD)(volatile void *half_channel, unsigned char data);
-	unsigned (*get_fHEAD)(volatile void *half_channel);
-	void (*set_fTAIL)(volatile void *half_channel, unsigned char data);
-	unsigned (*get_fTAIL)(volatile void *half_channel);
-	void (*set_fSTATE)(volatile void *half_channel, unsigned char data);
-	unsigned (*get_fSTATE)(volatile void *half_channel);
-	void (*set_fBLOCKREADINTR)(volatile void *half_channel,
+	void (*set_state)(volatile void __iomem *half_channel, unsigned data);
+	unsigned (*get_state)(volatile void __iomem *half_channel);
+	void (*set_fDSR)(volatile void __iomem *half_channel,
 					unsigned char data);
-	unsigned (*get_fBLOCKREADINTR)(volatile void *half_channel);
-	void (*set_tail)(volatile void *half_channel, unsigned data);
-	unsigned (*get_tail)(volatile void *half_channel);
-	void (*set_head)(volatile void *half_channel, unsigned data);
-	unsigned (*get_head)(volatile void *half_channel);
+	unsigned (*get_fDSR)(volatile void __iomem *half_channel);
+	void (*set_fCTS)(volatile void __iomem *half_channel,
+					unsigned char data);
+	unsigned (*get_fCTS)(volatile void __iomem *half_channel);
+	void (*set_fCD)(volatile void __iomem *half_channel,
+					unsigned char data);
+	unsigned (*get_fCD)(volatile void __iomem *half_channel);
+	void (*set_fRI)(volatile void __iomem *half_channel,
+					unsigned char data);
+	unsigned (*get_fRI)(volatile void __iomem *half_channel);
+	void (*set_fHEAD)(volatile void __iomem *half_channel,
+					unsigned char data);
+	unsigned (*get_fHEAD)(volatile void __iomem *half_channel);
+	void (*set_fTAIL)(volatile void __iomem *half_channel,
+					unsigned char data);
+	unsigned (*get_fTAIL)(volatile void __iomem *half_channel);
+	void (*set_fSTATE)(volatile void __iomem *half_channel,
+					unsigned char data);
+	unsigned (*get_fSTATE)(volatile void __iomem *half_channel);
+	void (*set_fBLOCKREADINTR)(volatile void __iomem *half_channel,
+					unsigned char data);
+	unsigned (*get_fBLOCKREADINTR)(volatile void __iomem *half_channel);
+	void (*set_tail)(volatile void __iomem *half_channel, unsigned data);
+	unsigned (*get_tail)(volatile void __iomem *half_channel);
+	void (*set_head)(volatile void __iomem *half_channel, unsigned data);
+	unsigned (*get_head)(volatile void __iomem *half_channel);
 };
 
 int is_word_access_ch(unsigned ch_type);
@@ -197,6 +207,46 @@
 	unsigned reserved2, reserved3, reserved4, reserved5;
 } __attribute__ ((__packed__));
 
+struct smd_channel {
+	volatile void __iomem *send; /* some variant of smd_half_channel */
+	volatile void __iomem *recv; /* some variant of smd_half_channel */
+	unsigned char *send_data;
+	unsigned char *recv_data;
+	unsigned fifo_size;
+	unsigned fifo_mask;
+	struct list_head ch_list;
+
+	unsigned current_packet;
+	unsigned n;
+	void *priv;
+	void (*notify)(void *priv, unsigned flags);
+
+	int (*read)(smd_channel_t *ch, void *data, int len, int user_buf);
+	int (*write)(smd_channel_t *ch, const void *data, int len,
+			int user_buf);
+	int (*read_avail)(smd_channel_t *ch);
+	int (*write_avail)(smd_channel_t *ch);
+	int (*read_from_cb)(smd_channel_t *ch, void *data, int len,
+			int user_buf);
+
+	void (*update_state)(smd_channel_t *ch);
+	unsigned last_state;
+	void (*notify_other_cpu)(smd_channel_t *ch);
+
+	char name[20];
+	struct platform_device pdev;
+	unsigned type;
+
+	int pending_pkt_sz;
+
+	char is_pkt_ch;
+
+	/*
+	 * private internal functions to access *send and *recv.
+	 * never to be exported outside of smd
+	 */
+	struct smd_half_channel_access *half_ch;
+};
 
 struct smem_ram_ptable {
 	#define _SMEM_RAM_PTABLE_MAGIC_1 0x9DA5E0A8
@@ -264,4 +314,6 @@
 };
 extern struct interrupt_stat interrupt_stats[NUM_SMD_SUBSYSTEMS];
 
+/* used for unit testing spinlocks */
+remote_spinlock_t *smem_get_remote_spinlock(void);
 #endif
diff --git a/arch/arm/mach-msm/smd_rpc_sym.h b/arch/arm/mach-msm/smd_rpc_sym.h
index e9a8b47..f476f49 100644
--- a/arch/arm/mach-msm/smd_rpc_sym.h
+++ b/arch/arm/mach-msm/smd_rpc_sym.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -9,7 +9,7 @@
  *       copyright notice, this list of conditions and the following
  *       disclaimer in the documentation and/or other materials provided
  *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *     * Neither the name of The Linux Foundation nor the names of its
  *       contributors may be used to endorse or promote products derived
  *       from this software without specific prior written permission.
  *
diff --git a/arch/arm/mach-msm/smd_rpcrouter_clients.c b/arch/arm/mach-msm/smd_rpcrouter_clients.c
index d94125e..6537846 100644
--- a/arch/arm/mach-msm/smd_rpcrouter_clients.c
+++ b/arch/arm/mach-msm/smd_rpcrouter_clients.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/arch/arm/mach-msm/smd_rpcrouter_device.c b/arch/arm/mach-msm/smd_rpcrouter_device.c
index 7b51beb..0525379 100644
--- a/arch/arm/mach-msm/smd_rpcrouter_device.c
+++ b/arch/arm/mach-msm/smd_rpcrouter_device.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/smd_rpcrouter_device.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
  * Author: San Mehat <san@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/smd_rpcrouter_servers.c b/arch/arm/mach-msm/smd_rpcrouter_servers.c
index 3561c21..478eb1f 100644
--- a/arch/arm/mach-msm/smd_rpcrouter_servers.c
+++ b/arch/arm/mach-msm/smd_rpcrouter_servers.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/rpc_servers.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2010, The Linux Foundation. All rights reserved.
  * Author: Iliyan Malchev <ibm@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/smd_rpcrouter_xdr.c b/arch/arm/mach-msm/smd_rpcrouter_xdr.c
index 1793516..107271c 100644
--- a/arch/arm/mach-msm/smd_rpcrouter_xdr.c
+++ b/arch/arm/mach-msm/smd_rpcrouter_xdr.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/smd_tty.c b/arch/arm/mach-msm/smd_tty.c
index 881da18..5969a3c 100644
--- a/arch/arm/mach-msm/smd_tty.c
+++ b/arch/arm/mach-msm/smd_tty.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/smd_tty.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -37,6 +37,7 @@
 
 #define MAX_SMD_TTYS 37
 #define MAX_TTY_BUF_SIZE 2048
+#define MAX_RA_WAKE_LOCK_NAME_LEN 32
 
 static DEFINE_MUTEX(smd_tty_lock);
 
@@ -46,7 +47,7 @@
 
 struct smd_tty_info {
 	smd_channel_t *ch;
-	struct tty_struct *tty;
+	struct tty_port port;
 	struct wake_lock wake_lock;
 	int open_count;
 	struct tasklet_struct tty_tsklt;
@@ -59,6 +60,9 @@
 	int is_open;
 	wait_queue_head_t ch_opened_wait_queue;
 	spinlock_t reset_lock;
+	spinlock_t ra_lock;		/* Read Available Lock*/
+	char ra_wake_lock_name[MAX_RA_WAKE_LOCK_NAME_LEN];
+	struct wake_lock ra_wake_lock;	/* Read Available Wakelock */
 	struct smd_config *smd;
 };
 
@@ -121,7 +125,8 @@
 	unsigned char *ptr;
 	int avail;
 	struct smd_tty_info *info = (struct smd_tty_info *)param;
-	struct tty_struct *tty = info->tty;
+	struct tty_struct *tty = tty_port_tty_get(&info->port);
+	unsigned long flags;
 
 	if (!tty)
 		return;
@@ -135,9 +140,14 @@
 		}
 
 		if (test_bit(TTY_THROTTLED, &tty->flags)) break;
+		spin_lock_irqsave(&info->ra_lock, flags);
 		avail = smd_read_avail(info->ch);
-		if (avail == 0)
+		if (avail == 0) {
+			wake_unlock(&info->ra_wake_lock);
+			spin_unlock_irqrestore(&info->ra_lock, flags);
 			break;
+		}
+		spin_unlock_irqrestore(&info->ra_lock, flags);
 
 		if (avail > MAX_TTY_BUF_SIZE)
 			avail = MAX_TTY_BUF_SIZE;
@@ -146,6 +156,7 @@
 		if (avail <= 0) {
 			mod_timer(&info->buf_req_timer,
 					jiffies + msecs_to_jiffies(30));
+			tty_kref_put(tty);
 			return;
 		}
 
@@ -163,11 +174,13 @@
 
 	/* XXX only when writable and necessary */
 	tty_wakeup(tty);
+	tty_kref_put(tty);
 }
 
 static void smd_tty_notify(void *priv, unsigned event)
 {
 	struct smd_tty_info *info = priv;
+	struct tty_struct *tty;
 	unsigned long flags;
 
 	switch (event) {
@@ -185,10 +198,17 @@
 		 */
 		if (smd_write_avail(info->ch)) {
 			smd_disable_read_intr(info->ch);
-			if (info->tty)
-				wake_up_interruptible(&info->tty->write_wait);
+			tty = tty_port_tty_get(&info->port);
+			if (tty)
+				wake_up_interruptible(&tty->write_wait);
+			tty_kref_put(tty);
 		}
-		tasklet_hi_schedule(&info->tty_tsklt);
+		spin_lock_irqsave(&info->ra_lock, flags);
+		if (smd_read_avail(info->ch)) {
+			wake_lock(&info->ra_wake_lock);
+			tasklet_hi_schedule(&info->tty_tsklt);
+		}
+		spin_unlock_irqrestore(&info->ra_lock, flags);
 		break;
 
 	case SMD_EVENT_OPEN:
@@ -210,9 +230,11 @@
 		/* schedule task to send TTY_BREAK */
 		tasklet_hi_schedule(&info->tty_tsklt);
 
-		if (info->tty->index == LOOPBACK_IDX)
+		tty = tty_port_tty_get(&info->port);
+		if (tty->index == LOOPBACK_IDX)
 			schedule_delayed_work(&loopback_work,
 					msecs_to_jiffies(1000));
+		tty_kref_put(tty);
 		break;
 	}
 }
@@ -226,7 +248,8 @@
 	return (modem_state & ready_state) == ready_state;
 }
 
-static int smd_tty_open(struct tty_struct *tty, struct file *f)
+static int smd_tty_port_activate(struct tty_port *tport,
+				 struct tty_struct *tty)
 {
 	int res = 0;
 	unsigned int n = tty->index;
@@ -291,12 +314,15 @@
 			}
 		}
 
-
-		info->tty = tty;
 		tasklet_init(&info->tty_tsklt, smd_tty_read,
 			     (unsigned long)info);
 		wake_lock_init(&info->wake_lock, WAKE_LOCK_SUSPEND,
 				smd_tty[n].smd->port_name);
+		scnprintf(info->ra_wake_lock_name,
+			  MAX_RA_WAKE_LOCK_NAME_LEN,
+			  "SMD_TTY_%s_RA", smd_tty[n].smd->port_name);
+		wake_lock_init(&info->ra_wake_lock, WAKE_LOCK_SUSPEND,
+				info->ra_wake_lock_name);
 		if (!info->ch) {
 			res = smd_named_open_on_edge(smd_tty[n].smd->port_name,
 							smd_tty[n].smd->edge,
@@ -334,23 +360,27 @@
 	return res;
 }
 
-static void smd_tty_close(struct tty_struct *tty, struct file *f)
+static void smd_tty_port_shutdown(struct tty_port *tport)
 {
-	struct smd_tty_info *info = tty->driver_data;
+	struct smd_tty_info *info;
+	struct tty_struct *tty = tty_port_tty_get(tport);
 	unsigned long flags;
 
-	if (info == 0)
+	info = tty->driver_data;
+	if (info == 0) {
+		tty_kref_put(tty);
 		return;
+	}
 
 	mutex_lock(&smd_tty_lock);
 	if (--info->open_count == 0) {
 		spin_lock_irqsave(&info->reset_lock, flags);
 		info->is_open = 0;
 		spin_unlock_irqrestore(&info->reset_lock, flags);
-		if (info->tty) {
+		if (tty) {
 			tasklet_kill(&info->tty_tsklt);
 			wake_lock_destroy(&info->wake_lock);
-			info->tty = 0;
+			wake_lock_destroy(&info->ra_wake_lock);
 		}
 		tty->driver_data = 0;
 		del_timer(&info->buf_req_timer);
@@ -361,6 +391,21 @@
 		}
 	}
 	mutex_unlock(&smd_tty_lock);
+	tty_kref_put(tty);
+}
+
+static int smd_tty_open(struct tty_struct *tty, struct file *f)
+{
+	struct smd_tty_info *info = smd_tty + tty->index;
+
+	return tty_port_open(&info->port, tty, f);
+}
+
+static void smd_tty_close(struct tty_struct *tty, struct file *f)
+{
+	struct smd_tty_info *info = tty->driver_data;
+
+	tty_port_close(&info->port, tty, f);
 }
 
 static int smd_tty_write(struct tty_struct *tty, const unsigned char *buf, int len)
@@ -461,6 +506,11 @@
 			  0, SMSM_SMD_LOOPBACK);
 }
 
+static const struct tty_port_operations smd_tty_port_ops = {
+	.shutdown = smd_tty_port_shutdown,
+	.activate = smd_tty_port_activate,
+};
+
 static struct tty_operations smd_tty_ops = {
 	.open = smd_tty_open,
 	.close = smd_tty_close,
@@ -502,6 +552,7 @@
 	int ret;
 	int n;
 	int idx;
+	struct tty_port *port;
 
 	smd_tty_driver = alloc_tty_driver(MAX_SMD_TTYS);
 	if (smd_tty_driver == 0)
@@ -557,6 +608,10 @@
 				continue;
 		}
 
+		port = &smd_tty[idx].port;
+		tty_port_init(port);
+		port->ops = &smd_tty_port_ops;
+		/* TODO: For kernel >= 3.7 use tty_port_register_device */
 		tty_register_device(smd_tty_driver, idx, 0);
 		init_completion(&smd_tty[idx].ch_allocated);
 
@@ -565,6 +620,7 @@
 		smd_tty[idx].driver.driver.name = smd_configs[n].dev_name;
 		smd_tty[idx].driver.driver.owner = THIS_MODULE;
 		spin_lock_init(&smd_tty[idx].reset_lock);
+		spin_lock_init(&smd_tty[idx].ra_lock);
 		smd_tty[idx].is_open = 0;
 		setup_timer(&smd_tty[idx].buf_req_timer, buf_req_retry,
 				(unsigned long)&smd_tty[idx]);
diff --git a/arch/arm/mach-msm/smem_log.c b/arch/arm/mach-msm/smem_log.c
index fd8144a..169df1e 100644
--- a/arch/arm/mach-msm/smem_log.c
+++ b/arch/arm/mach-msm/smem_log.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/arch/arm/mach-msm/smp2p.c b/arch/arm/mach-msm/smp2p.c
new file mode 100644
index 0000000..8066005
--- /dev/null
+++ b/arch/arm/mach-msm/smp2p.c
@@ -0,0 +1,1723 @@
+/* arch/arm/mach-msm/smp2p.c
+ *
+ * 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/list.h>
+#include <linux/ctype.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <mach/msm_smsm.h>
+#include <mach/msm_ipc_logging.h>
+#include "smp2p_private_api.h"
+#include "smp2p_private.h"
+
+#define NUM_LOG_PAGES 3
+
+/**
+ * struct msm_smp2p_out - This structure represents the outbound SMP2P entry.
+ *
+ * @remote_pid: Outbound processor ID.
+ * @name: Entry name.
+ * @out_edge_list: Adds this structure into smp2p_out_list_item::list.
+ * @msm_smp2p_notifier_list: Notifier block head used to notify for open event.
+ * @open_nb: Notifier block used to notify for open event.
+ * @l_smp2p_entry: Pointer to the actual entry in the SMEM item.
+ */
+struct msm_smp2p_out {
+	int remote_pid;
+	char name[SMP2P_MAX_ENTRY_NAME];
+	struct list_head out_edge_list;
+	struct raw_notifier_head msm_smp2p_notifier_list;
+	struct notifier_block *open_nb;
+	uint32_t __iomem *l_smp2p_entry;
+};
+
+/**
+ * struct smp2p_out_list_item - Maintains the state of outbound edge.
+ *
+ * @out_item_lock_lha1: Lock protecting all elements of the structure.
+ * @list: list of outbound entries (struct msm_smp2p_out).
+ * @smem_edge_out: Pointer to outbound smem item.
+ * @smem_edge_state: State of the outbound edge.
+ * @ops_ptr: Pointer to internal version-specific SMEM item access functions.
+ */
+struct smp2p_out_list_item {
+	spinlock_t out_item_lock_lha1;
+
+	struct list_head list;
+	struct smp2p_smem __iomem *smem_edge_out;
+	enum msm_smp2p_edge_state smem_edge_state;
+	struct smp2p_version_if *ops_ptr;
+};
+static struct smp2p_out_list_item out_list[SMP2P_NUM_PROCS];
+
+static void *log_ctx;
+static int smp2p_debug_mask = MSM_SMP2P_INFO;
+module_param_named(debug_mask, smp2p_debug_mask,
+		   int, S_IRUGO | S_IWUSR | S_IWGRP);
+
+/**
+ * struct smp2p_in - Represents the entry on remote processor.
+ *
+ * @name: Name of the entry.
+ * @remote_pid: Outbound processor ID.
+ * @in_edge_list: Adds this structure into smp2p_in_list_item::list.
+ * @in_notifier_list: List for notifier block for entry opening/updates.
+ * @prev_entry_val: Previous value of the entry.
+ * @entry_ptr: Points to the current value in smem item.
+ * @notifier_count: Counts the number of notifier registered per pid,entry.
+ */
+struct smp2p_in {
+	int remote_pid;
+	char name[SMP2P_MAX_ENTRY_NAME];
+	struct list_head in_edge_list;
+	struct raw_notifier_head in_notifier_list;
+	uint32_t prev_entry_val;
+	uint32_t __iomem *entry_ptr;
+	uint32_t notifier_count;
+};
+
+/**
+ * struct smp2p_in_list_item - Maintains the inbound edge state.
+ *
+ * @in_item_lock_lhb1: Lock protecting all elements of the structure.
+ * @list: List head for the entries on remote processor.
+ * @smem_edge_in: Pointer to the remote smem item.
+ */
+struct smp2p_in_list_item {
+	spinlock_t in_item_lock_lhb1;
+	struct list_head list;
+	struct smp2p_smem __iomem *smem_edge_in;
+	uint32_t item_size;
+	uint32_t safe_total_entries;
+};
+static struct smp2p_in_list_item in_list[SMP2P_NUM_PROCS];
+
+/**
+ * SMEM Item access function interface.
+ *
+ * This interface is used to help isolate the implementation of
+ * the functionality from any changes in the shared data structures
+ * that may happen as versions are changed.
+ *
+ * @is_supported: True if this version is supported by SMP2P
+ * @negotiate_features: Returns (sub)set of supported features
+ * @find_entry: Finds existing / next empty entry
+ * @create_entry: Creates a new entry
+ * @read_entry: Reads the value of an entry
+ * @write_entry: Writes a new value to an entry
+ * @modify_entry: Does a read/modify/write of an entry
+ * validate_size: Verifies the size of the remote SMEM item to ensure that
+ *                an invalid item size doesn't result in an out-of-bounds
+ *                memory access.
+ */
+struct smp2p_version_if {
+	/* common functions */
+	bool is_supported;
+	uint32_t (*negotiate_features)(uint32_t features);
+	void (*find_entry)(struct smp2p_smem __iomem *item,
+			uint32_t entries_total,	char *name,
+			uint32_t **entry_ptr, int *empty_spot);
+
+	/* outbound entry functions */
+	int (*create_entry)(struct msm_smp2p_out *);
+	int (*read_entry)(struct msm_smp2p_out *, uint32_t *);
+	int (*write_entry)(struct msm_smp2p_out *, uint32_t);
+	int (*modify_entry)(struct msm_smp2p_out *, uint32_t, uint32_t);
+
+	/* inbound entry functions */
+	struct smp2p_smem __iomem *(*validate_size)(int remote_pid,
+			struct smp2p_smem __iomem *, uint32_t);
+};
+
+static int smp2p_do_negotiation(int remote_pid, struct smp2p_out_list_item *p);
+static void smp2p_send_interrupt(int remote_pid);
+
+/* v0 (uninitialized SMEM item) interface functions */
+static uint32_t smp2p_negotiate_features_v0(uint32_t features);
+static void smp2p_find_entry_v0(struct smp2p_smem __iomem *item,
+		uint32_t entries_total, char *name, uint32_t **entry_ptr,
+		int *empty_spot);
+static int smp2p_out_create_v0(struct msm_smp2p_out *);
+static int smp2p_out_read_v0(struct msm_smp2p_out *, uint32_t *);
+static int smp2p_out_write_v0(struct msm_smp2p_out *, uint32_t);
+static int smp2p_out_modify_v0(struct msm_smp2p_out *, uint32_t, uint32_t);
+static struct smp2p_smem __iomem *smp2p_in_validate_size_v0(int remote_pid,
+		struct smp2p_smem __iomem *smem_item, uint32_t size);
+
+/* v1 interface functions */
+static uint32_t smp2p_negotiate_features_v1(uint32_t features);
+static void smp2p_find_entry_v1(struct smp2p_smem __iomem *item,
+		uint32_t entries_total, char *name, uint32_t **entry_ptr,
+		int *empty_spot);
+static int smp2p_out_create_v1(struct msm_smp2p_out *);
+static int smp2p_out_read_v1(struct msm_smp2p_out *, uint32_t *);
+static int smp2p_out_write_v1(struct msm_smp2p_out *, uint32_t);
+static int smp2p_out_modify_v1(struct msm_smp2p_out *, uint32_t, uint32_t);
+static struct smp2p_smem __iomem *smp2p_in_validate_size_v1(int remote_pid,
+		struct smp2p_smem __iomem *smem_item, uint32_t size);
+
+/* Version interface functions */
+static struct smp2p_version_if version_if[] = {
+	[0] = {
+		.negotiate_features = smp2p_negotiate_features_v0,
+		.find_entry = smp2p_find_entry_v0,
+		.create_entry = smp2p_out_create_v0,
+		.read_entry = smp2p_out_read_v0,
+		.write_entry = smp2p_out_write_v0,
+		.modify_entry = smp2p_out_modify_v0,
+		.validate_size = smp2p_in_validate_size_v0,
+	},
+	[1] = {
+		.is_supported = true,
+		.negotiate_features = smp2p_negotiate_features_v1,
+		.find_entry = smp2p_find_entry_v1,
+		.create_entry = smp2p_out_create_v1,
+		.read_entry = smp2p_out_read_v1,
+		.write_entry = smp2p_out_write_v1,
+		.modify_entry = smp2p_out_modify_v1,
+		.validate_size = smp2p_in_validate_size_v1,
+	},
+};
+
+/* interrupt configuration (filled by device tree) */
+static struct smp2p_interrupt_config smp2p_int_cfgs[SMP2P_NUM_PROCS] = {
+	[SMP2P_MODEM_PROC].name = "modem",
+	[SMP2P_AUDIO_PROC].name = "lpass",
+	[SMP2P_WIRELESS_PROC].name = "wcnss",
+	[SMP2P_REMOTE_MOCK_PROC].name = "mock",
+};
+
+/**
+ * smp2p_get_log_ctx - Return log context for other SMP2P modules.
+ *
+ * @returns: Log context or NULL if none.
+ */
+void *smp2p_get_log_ctx(void)
+{
+	return log_ctx;
+}
+
+/**
+ * smp2p_get_debug_mask - Return debug mask.
+ *
+ * @returns: Current debug mask.
+ */
+int smp2p_get_debug_mask(void)
+{
+	return smp2p_debug_mask;
+}
+
+/**
+ * smp2p_interrupt_config -  Return interrupt configuration.
+ *
+ * @returns interrupt configuration array for usage by debugfs.
+ */
+struct smp2p_interrupt_config *smp2p_get_interrupt_config(void)
+{
+	return smp2p_int_cfgs;
+}
+
+/**
+ * smp2p_pid_to_name -  Lookup name for remote pid.
+ *
+ * @returns: name (may be NULL).
+ */
+const char *smp2p_pid_to_name(int remote_pid)
+{
+	if (remote_pid >= SMP2P_NUM_PROCS)
+		return NULL;
+
+	return smp2p_int_cfgs[remote_pid].name;
+}
+
+/**
+ * smp2p_get_in_item - Return pointer to remote smem item.
+ *
+ * @remote_pid: Processor ID of the remote system.
+ * @returns:    Pointer to inbound SMEM item
+ *
+ * This is used by debugfs to print the smem items.
+ */
+struct smp2p_smem __iomem *smp2p_get_in_item(int remote_pid)
+{
+	void *ret = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&in_list[remote_pid].in_item_lock_lhb1, flags);
+	if (remote_pid < SMP2P_NUM_PROCS)
+		ret = in_list[remote_pid].smem_edge_in;
+	spin_unlock_irqrestore(&in_list[remote_pid].in_item_lock_lhb1,
+								flags);
+
+	return ret;
+}
+
+/**
+ * smp2p_get_out_item - Return pointer to outbound SMEM item.
+ *
+ * @remote_pid: Processor ID of remote system.
+ * @state:      Edge state of the outbound SMEM item.
+ * @returns:    Pointer to outbound (remote) SMEM item.
+ */
+struct smp2p_smem __iomem *smp2p_get_out_item(int remote_pid, int *state)
+{
+	void *ret = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&out_list[remote_pid].out_item_lock_lha1, flags);
+	if (remote_pid < SMP2P_NUM_PROCS) {
+		ret = out_list[remote_pid].smem_edge_out;
+		if (state)
+			*state = out_list[remote_pid].smem_edge_state;
+	}
+	spin_unlock_irqrestore(&out_list[remote_pid].out_item_lock_lha1, flags);
+
+	return ret;
+}
+
+/**
+ * smp2p_get_smem_item_id - Return the proper SMEM item ID.
+ *
+ * @write_id:	Processor that will write to the item.
+ * @read_id:    Processor that will read from the item.
+ * @returns:    SMEM ID
+ */
+static int smp2p_get_smem_item_id(int write_pid, int read_pid)
+{
+	int ret = -EINVAL;
+
+	switch (write_pid) {
+	case SMP2P_APPS_PROC:
+		ret = SMEM_SMP2P_APPS_BASE + read_pid;
+		break;
+	case SMP2P_MODEM_PROC:
+		ret = SMEM_SMP2P_MODEM_BASE + read_pid;
+		break;
+	case SMP2P_AUDIO_PROC:
+		ret = SMEM_SMP2P_AUDIO_BASE + read_pid;
+		break;
+	case SMP2P_WIRELESS_PROC:
+		ret = SMEM_SMP2P_WIRLESS_BASE + read_pid;
+		break;
+	case SMP2P_POWER_PROC:
+		ret = SMEM_SMP2P_POWER_BASE + read_pid;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * Return pointer to SMEM item owned by the local processor.
+ *
+ * @remote_pid: Remote processor ID
+ * @returns:    NULL for failure; otherwise pointer to SMEM item
+ *
+ * Must be called with out_item_lock_lha1 locked for mock proc.
+ */
+static void *smp2p_get_local_smem_item(int remote_pid)
+{
+	struct smp2p_smem __iomem *item_ptr = NULL;
+
+	if (remote_pid < SMP2P_REMOTE_MOCK_PROC) {
+		unsigned size;
+		int smem_id;
+
+		/* lookup or allocate SMEM item */
+		smem_id = smp2p_get_smem_item_id(SMP2P_APPS_PROC, remote_pid);
+		if (smem_id >= 0) {
+			item_ptr = smem_get_entry(smem_id, &size);
+
+			if (!item_ptr) {
+				size = sizeof(struct smp2p_smem_item);
+				item_ptr = smem_alloc2(smem_id, size);
+			}
+		}
+	} else if (remote_pid == SMP2P_REMOTE_MOCK_PROC) {
+		/*
+		 * This path is only used during unit testing so
+		 * the GFP_ATOMIC allocation should not be a
+		 * concern.
+		 */
+		if (!out_list[SMP2P_REMOTE_MOCK_PROC].smem_edge_out)
+			item_ptr = kzalloc(
+					sizeof(struct smp2p_smem_item),
+					GFP_ATOMIC);
+	}
+	return item_ptr;
+}
+
+/**
+ * smp2p_get_remote_smem_item - Return remote SMEM item.
+ *
+ * @remote_pid: Remote processor ID
+ * @out_item:   Pointer to the output item structure
+ * @returns:    NULL for failure; otherwise pointer to SMEM item
+ *
+ * Return pointer to SMEM item owned by the remote processor.
+ *
+ * Note that this function does an SMEM lookup which uses a remote spinlock,
+ * so this function should not be called more than necessary.
+ *
+ * Must be called with out_item_lock_lha1 and in_item_lock_lhb1 locked.
+ */
+static void *smp2p_get_remote_smem_item(int remote_pid,
+	struct smp2p_out_list_item *out_item)
+{
+	void *item_ptr = NULL;
+	unsigned size;
+
+	if (!out_item)
+		return item_ptr;
+
+	if (remote_pid < SMP2P_REMOTE_MOCK_PROC) {
+		int smem_id;
+
+		smem_id = smp2p_get_smem_item_id(remote_pid, SMP2P_APPS_PROC);
+		if (smem_id >= 0)
+			item_ptr = smem_get_entry(smem_id, &size);
+	} else if (remote_pid == SMP2P_REMOTE_MOCK_PROC) {
+		item_ptr = msm_smp2p_get_remote_mock_smem_item(&size);
+	}
+	item_ptr = out_item->ops_ptr->validate_size(remote_pid, item_ptr, size);
+
+	return item_ptr;
+}
+
+/**
+ * smp2p_negotiate_features_v0 - Initial feature negotiation.
+ *
+ * @features: Inbound feature set.
+ * @returns: Supported features (will be a same/subset of @features).
+ */
+static uint32_t smp2p_negotiate_features_v1(uint32_t features)
+{
+	/* no supported features */
+	return 0;
+}
+
+/**
+ * smp2p_find_entry_v1 - Search for an entry in SMEM item.
+ *
+ * @item: Pointer to the smem item.
+ * @entries_total: Total number of entries in @item.
+ * @name: Name of the entry.
+ * @entry_ptr: Set to pointer of entry if found, NULL otherwise.
+ * @empty_spot: If non-null, set to the value of the next empty entry.
+ *
+ * Searches for entry @name in the SMEM item.  If found, a pointer
+ * to the item is returned.  If it isn't found, the first empty
+ * index is returned in @empty_spot.
+ */
+static void smp2p_find_entry_v1(struct smp2p_smem __iomem *item,
+		uint32_t entries_total, char *name, uint32_t **entry_ptr,
+		int *empty_spot)
+{
+	int i;
+	struct smp2p_entry_v1 *pos;
+
+	if (!item || !name || !entry_ptr) {
+		SMP2P_ERR("%s: invalid arguments %p, %p, %p\n",
+				__func__, item, name, entry_ptr);
+		return;
+	}
+
+	*entry_ptr = NULL;
+	if (empty_spot)
+		*empty_spot = -1;
+
+	pos = (struct smp2p_entry_v1 *)(char *)(item + 1);
+	for (i = 0; i < entries_total; i++, ++pos) {
+		if (pos->name[0]) {
+			if (!strncmp(pos->name, name, SMP2P_MAX_ENTRY_NAME)) {
+				*entry_ptr = &pos->entry;
+				break;
+			}
+		} else if (empty_spot && *empty_spot < 0) {
+			*empty_spot = i;
+		}
+	}
+}
+
+/**
+ * smp2p_out_create_v1 - Creates a outbound SMP2P entry.
+ *
+ * @out_entry: Pointer to the SMP2P entry structure.
+ * @returns: 0 on success, standard Linux error code otherwise.
+ *
+ * Must be called with out_item_lock_lha1 locked.
+ */
+static int smp2p_out_create_v1(struct msm_smp2p_out *out_entry)
+{
+	struct smp2p_smem __iomem *smp2p_h_ptr;
+	struct smp2p_out_list_item *p_list;
+	uint32_t *state_entry_ptr;
+	uint32_t empty_spot;
+	uint32_t entries_total;
+	uint32_t entries_valid;
+
+	if (!out_entry)
+		return -EINVAL;
+
+	p_list = &out_list[out_entry->remote_pid];
+	if (p_list->smem_edge_state != SMP2P_EDGE_STATE_OPENED) {
+		SMP2P_ERR("%s: item '%s':%d opened - wrong create called\n",
+			__func__, out_entry->name, out_entry->remote_pid);
+		return -ENODEV;
+	}
+
+	smp2p_h_ptr = p_list->smem_edge_out;
+	entries_total = SMP2P_GET_ENT_TOTAL(smp2p_h_ptr->valid_total_ent);
+	entries_valid = SMP2P_GET_ENT_VALID(smp2p_h_ptr->valid_total_ent);
+
+	p_list->ops_ptr->find_entry(smp2p_h_ptr, entries_total,
+			out_entry->name, &state_entry_ptr, &empty_spot);
+	if (state_entry_ptr) {
+		/* re-use existing entry */
+		out_entry->l_smp2p_entry = state_entry_ptr;
+
+		SMP2P_DBG("%s: item '%s':%d reused\n", __func__,
+				out_entry->name, out_entry->remote_pid);
+	} else if (entries_valid >= entries_total) {
+		/* need to allocate entry, but not more space */
+		SMP2P_ERR("%s: no space for item '%s':%d\n",
+			__func__, out_entry->name, out_entry->remote_pid);
+		return -ENOMEM;
+	} else {
+		/* allocate a new entry */
+		struct smp2p_entry_v1 *entry_ptr;
+
+		entry_ptr = (struct smp2p_entry_v1 *)((char *)(smp2p_h_ptr + 1)
+			+ empty_spot * sizeof(struct smp2p_entry_v1));
+		strlcpy(entry_ptr->name, out_entry->name,
+				sizeof(entry_ptr->name));
+		out_entry->l_smp2p_entry = &entry_ptr->entry;
+		++entries_valid;
+		SMP2P_DBG("%s: item '%s':%d fully created as entry %d of %d\n",
+				__func__, out_entry->name,
+				out_entry->remote_pid,
+				entries_valid, entries_total);
+		SMP2P_SET_ENT_VALID(smp2p_h_ptr->valid_total_ent,
+				entries_valid);
+		smp2p_send_interrupt(out_entry->remote_pid);
+	}
+	raw_notifier_call_chain(&out_entry->msm_smp2p_notifier_list,
+		  SMP2P_OPEN, 0);
+
+	return 0;
+}
+
+/**
+ * smp2p_out_read_v1 -  Read the data from an outbound entry.
+ *
+ * @out_entry: Pointer to the SMP2P entry structure.
+ * @data: Out pointer, the data is available in this argument on success.
+ * @returns: 0 on success, standard Linux error code otherwise.
+ *
+ * Must be called with out_item_lock_lha1 locked.
+ */
+static int smp2p_out_read_v1(struct msm_smp2p_out *out_entry, uint32_t *data)
+{
+	struct smp2p_smem __iomem  *smp2p_h_ptr;
+	uint32_t remote_pid;
+
+	if (!out_entry)
+		return -EINVAL;
+
+	smp2p_h_ptr = out_list[out_entry->remote_pid].smem_edge_out;
+	remote_pid = SMP2P_GET_REMOTE_PID(smp2p_h_ptr->rem_loc_proc_id);
+
+	if (remote_pid != out_entry->remote_pid)
+		return -EINVAL;
+
+	if (out_entry->l_smp2p_entry) {
+		*data = readl_relaxed(out_entry->l_smp2p_entry);
+	} else {
+		SMP2P_ERR("%s: '%s':%d not yet OPEN\n", __func__,
+				out_entry->name, remote_pid);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+/**
+ * smp2p_out_write_v1 - Writes an outbound entry value.
+ *
+ * @out_entry: Pointer to the SMP2P entry structure.
+ * @data: The data to be written.
+ * @returns: 0 on success, standard Linux error code otherwise.
+ *
+ * Must be called with out_item_lock_lha1 locked.
+ */
+static int smp2p_out_write_v1(struct msm_smp2p_out *out_entry, uint32_t data)
+{
+	struct smp2p_smem __iomem  *smp2p_h_ptr;
+	uint32_t remote_pid;
+
+	if (!out_entry)
+		return -EINVAL;
+
+	smp2p_h_ptr = out_list[out_entry->remote_pid].smem_edge_out;
+	remote_pid = SMP2P_GET_REMOTE_PID(smp2p_h_ptr->rem_loc_proc_id);
+
+	if (remote_pid != out_entry->remote_pid)
+		return -EINVAL;
+
+	if (out_entry->l_smp2p_entry) {
+		writel_relaxed(data, out_entry->l_smp2p_entry);
+		smp2p_send_interrupt(remote_pid);
+	} else {
+		SMP2P_ERR("%s: '%s':%d not yet OPEN\n", __func__,
+				out_entry->name, remote_pid);
+		return -ENODEV;
+	}
+	return 0;
+}
+
+/**
+ * smp2p_out_modify_v1 - Modifies and outbound value.
+ *
+ * @set_mask:  Mask containing the bits that needs to be set.
+ * @clear_mask: Mask containing the bits that needs to be cleared.
+ * @returns: 0 on success, standard Linux error code otherwise.
+ *
+ * The clear mask is applied first, so  if a bit is set in both clear and
+ * set mask, the result will be that the bit is set.
+ *
+ * Must be called with out_item_lock_lha1 locked.
+ */
+static int smp2p_out_modify_v1(struct msm_smp2p_out *out_entry,
+		uint32_t set_mask, uint32_t clear_mask)
+{
+	struct smp2p_smem __iomem  *smp2p_h_ptr;
+	uint32_t remote_pid;
+
+	if (!out_entry)
+		return -EINVAL;
+
+	smp2p_h_ptr = out_list[out_entry->remote_pid].smem_edge_out;
+	remote_pid = SMP2P_GET_REMOTE_PID(smp2p_h_ptr->rem_loc_proc_id);
+
+	if (remote_pid != out_entry->remote_pid)
+			return -EINVAL;
+
+	if (out_entry->l_smp2p_entry) {
+		uint32_t curr_value;
+
+		curr_value = readl_relaxed(out_entry->l_smp2p_entry);
+		writel_relaxed((curr_value & ~clear_mask) | set_mask,
+			out_entry->l_smp2p_entry);
+	} else {
+		SMP2P_ERR("%s: '%s':%d not yet OPEN\n", __func__,
+				out_entry->name, remote_pid);
+		return -ENODEV;
+	}
+
+	smp2p_send_interrupt(remote_pid);
+	return 0;
+}
+
+/**
+ * smp2p_in_validate_size_v1 - Size validation for version 1.
+ *
+ * @remote_pid: Remote processor ID.
+ * @smem_item:  Pointer to the inbound SMEM item.
+ * @size:       Size of the SMEM item.
+ * @returns:    Validated smem_item pointer (or NULL if size is too small).
+ *
+ * Validates we don't end up with out-of-bounds array access due to invalid
+ * smem item size.  If out-of-bound array access can't be avoided, then an
+ * error message is printed and NULL is returned to prevent usage of the
+ * item.
+ *
+ * Must be called with in_item_lock_lhb1 locked.
+ */
+static struct smp2p_smem __iomem *smp2p_in_validate_size_v1(int remote_pid,
+		struct smp2p_smem __iomem *smem_item, uint32_t size)
+{
+	uint32_t total_entries;
+	unsigned expected_size;
+	struct smp2p_smem __iomem *item_ptr;
+	struct smp2p_in_list_item *in_item;
+
+	if (remote_pid >= SMP2P_NUM_PROCS || !smem_item)
+		return NULL;
+
+	in_item = &in_list[remote_pid];
+	item_ptr = (struct smp2p_smem __iomem *)smem_item;
+
+	total_entries = SMP2P_GET_ENT_TOTAL(item_ptr->valid_total_ent);
+	if (total_entries > 0) {
+		in_item->safe_total_entries = total_entries;
+		in_item->item_size = size;
+
+		expected_size =	sizeof(struct smp2p_smem) +
+			(total_entries * sizeof(struct smp2p_entry_v1));
+
+		if (size < expected_size) {
+			unsigned new_size;
+
+			new_size = size;
+			new_size -= sizeof(struct smp2p_smem);
+			new_size /= sizeof(struct smp2p_entry_v1);
+			in_item->safe_total_entries = new_size;
+
+			SMP2P_ERR(
+				"%s pid %d item too small for %d entries; expected: %d actual: %d; reduced to %d entries\n",
+				__func__, remote_pid, total_entries,
+				expected_size, size, new_size);
+		}
+	} else {
+		/*
+		 * Total entries is 0, so the entry is still being initialized
+		 * or is invalid.  Either way, treat it as if the item does
+		 * not exist yet.
+		 */
+		in_item->safe_total_entries = 0;
+		in_item->item_size = 0;
+	}
+	return item_ptr;
+}
+
+/**
+ * smp2p_negotiate_features_v0 - Initial feature negotiation.
+ *
+ * @features: Inbound feature set.
+ * @returns: 0 (no features supported for v0).
+ */
+static uint32_t smp2p_negotiate_features_v0(uint32_t features)
+{
+	/* no supported features */
+	return 0;
+}
+
+/**
+ * smp2p_find_entry_v0 - Stub function.
+ *
+ * @item: Pointer to the smem item.
+ * @entries_total: Total number of entries in @item.
+ * @name: Name of the entry.
+ * @entry_ptr: Set to pointer of entry if found, NULL otherwise.
+ * @empty_spot: If non-null, set to the value of the next empty entry.
+ *
+ * Entries cannot be searched for until item negotiation has been completed.
+ */
+static void smp2p_find_entry_v0(struct smp2p_smem __iomem *item,
+		uint32_t entries_total, char *name, uint32_t **entry_ptr,
+		int *empty_spot)
+{
+	if (entry_ptr)
+		*entry_ptr = NULL;
+
+	if (empty_spot)
+		*empty_spot = -1;
+
+	SMP2P_ERR("%s: invalid - item negotiation incomplete\n", __func__);
+}
+
+/**
+ * smp2p_out_create_v0 - Initial creation function.
+ *
+ * @out_entry: Pointer to the SMP2P entry structure.
+ * @returns: 0 on success, standard Linux error code otherwise.
+ *
+ * If the outbound SMEM item negotiation is not complete, then
+ * this function is called to start the negotiation process.
+ * Eventually when the negotiation process is complete, this
+ * function pointer is switched with the appropriate function
+ * for the version of SMP2P being created.
+ *
+ * Must be called with out_item_lock_lha1 locked.
+ */
+static int smp2p_out_create_v0(struct msm_smp2p_out *out_entry)
+{
+	int edge_state;
+	struct smp2p_out_list_item *item_ptr;
+
+	if (!out_entry)
+		return -EINVAL;
+
+	edge_state = out_list[out_entry->remote_pid].smem_edge_state;
+
+	switch (edge_state) {
+	case SMP2P_EDGE_STATE_CLOSED:
+		/* start negotiation */
+		item_ptr = &out_list[out_entry->remote_pid];
+		edge_state = smp2p_do_negotiation(out_entry->remote_pid,
+				item_ptr);
+		break;
+
+	case SMP2P_EDGE_STATE_OPENING:
+		/* still negotiating */
+		break;
+
+	case SMP2P_EDGE_STATE_OPENED:
+		SMP2P_ERR("%s: item '%s':%d opened - wrong create called\n",
+			__func__, out_entry->name, out_entry->remote_pid);
+		break;
+
+	default:
+		SMP2P_ERR("%s: item '%s':%d invalid SMEM item state %d\n",
+			__func__, out_entry->name, out_entry->remote_pid,
+			edge_state);
+		break;
+	}
+	return 0;
+}
+
+/**
+ * smp2p_out_read_v0 - Stub function.
+ *
+ * @out_entry: Pointer to the SMP2P entry structure.
+ * @data: Out pointer, the data is available in this argument on success.
+ * @returns: -ENODEV
+ */
+static int smp2p_out_read_v0(struct msm_smp2p_out *out_entry, uint32_t *data)
+{
+	SMP2P_ERR("%s: item '%s':%d not OPEN\n",
+		__func__, out_entry->name, out_entry->remote_pid);
+
+	return -ENODEV;
+}
+
+/**
+ * smp2p_out_write_v0 - Stub function.
+ *
+ * @out_entry: Pointer to the SMP2P entry structure.
+ * @data: The data to be written.
+ * @returns: -ENODEV
+ */
+static int smp2p_out_write_v0(struct msm_smp2p_out *out_entry, uint32_t data)
+{
+	SMP2P_ERR("%s: item '%s':%d not yet OPEN\n",
+		__func__, out_entry->name, out_entry->remote_pid);
+
+	return -ENODEV;
+}
+
+/**
+ * smp2p_out_modify_v0 - Stub function.
+ *
+ * @set_mask:  Mask containing the bits that needs to be set.
+ * @clear_mask: Mask containing the bits that needs to be cleared.
+ * @returns: -ENODEV
+ */
+static int smp2p_out_modify_v0(struct msm_smp2p_out *out_entry,
+		uint32_t set_mask, uint32_t clear_mask)
+{
+	SMP2P_ERR("%s: item '%s':%d not yet OPEN\n",
+		__func__, out_entry->name, out_entry->remote_pid);
+
+	return -ENODEV;
+}
+
+/**
+ * smp2p_in_validate_size_v0 - Stub function.
+ *
+ * @remote_pid: Remote processor ID.
+ * @smem_item:  Pointer to the inbound SMEM item.
+ * @size:       Size of the SMEM item.
+ * @returns:    Validated smem_item pointer (or NULL if size is too small).
+ *
+ * Validates we don't end up with out-of-bounds array access due to invalid
+ * smem item size.  If out-of-bound array access can't be avoided, then an
+ * error message is printed and NULL is returned to prevent usage of the
+ * item.
+ *
+ * Must be called with in_item_lock_lhb1 locked.
+ */
+static struct smp2p_smem __iomem *smp2p_in_validate_size_v0(int remote_pid,
+		struct smp2p_smem __iomem *smem_item, uint32_t size)
+{
+	struct smp2p_in_list_item *in_item;
+
+	if (remote_pid >= SMP2P_NUM_PROCS || !smem_item)
+		return NULL;
+
+	in_item = &in_list[remote_pid];
+
+	if (size < sizeof(struct smp2p_smem)) {
+		SMP2P_ERR(
+			"%s pid %d item size too small; expected: %d actual: %d\n",
+			__func__, remote_pid,
+			sizeof(struct smp2p_smem), size);
+		smem_item = NULL;
+		in_item->item_size = 0;
+	} else {
+		in_item->item_size = size;
+	}
+	return smem_item;
+}
+
+/**
+ * smp2p_init_header - Initializes the header of the smem item.
+ *
+ * @header_ptr: Pointer to the smp2p header.
+ * @local_pid: Local processor ID.
+ * @remote_pid: Remote processor ID.
+ * @feature: Features of smp2p implementation.
+ * @version: Version of smp2p implementation.
+ *
+ * Initializes the header as defined in the protocol specification.
+ */
+void smp2p_init_header(struct smp2p_smem __iomem *header_ptr,
+		int local_pid, int remote_pid,
+		uint32_t features, uint32_t version)
+{
+	header_ptr->magic = SMP2P_MAGIC;
+	SMP2P_SET_LOCAL_PID(header_ptr->rem_loc_proc_id, local_pid);
+	SMP2P_SET_REMOTE_PID(header_ptr->rem_loc_proc_id, remote_pid);
+	SMP2P_SET_FEATURES(header_ptr->feature_version, features);
+	SMP2P_SET_ENT_TOTAL(header_ptr->valid_total_ent, SMP2P_MAX_ENTRY);
+	SMP2P_SET_ENT_VALID(header_ptr->valid_total_ent, 0);
+	header_ptr->reserved = 0;
+
+	/* ensure that all fields are valid before version is written */
+	wmb();
+	SMP2P_SET_VERSION(header_ptr->feature_version, version);
+}
+
+/**
+ * smp2p_do_negotiation - Implements negotiation algorithm.
+ *
+ * @remote_pid: Remote processor ID.
+ * @out_item: Pointer to the outbound list item.
+ * @returns: 0 on success, standard Linux error code otherwise.
+ *
+ * Must be called with out_item_lock_lha1 locked.  Will internally lock
+ * in_item_lock_lhb1.
+ */
+static int smp2p_do_negotiation(int remote_pid,
+		struct smp2p_out_list_item *out_item)
+{
+	struct smp2p_smem __iomem *r_smem_ptr;
+	struct smp2p_smem __iomem *l_smem_ptr;
+	uint32_t r_version;
+	uint32_t r_feature;
+	uint32_t l_version, l_feature;
+	int prev_state;
+
+	if (remote_pid >= SMP2P_NUM_PROCS || !out_item)
+		return -EINVAL;
+	if (out_item->smem_edge_state == SMP2P_EDGE_STATE_FAILED)
+		return -EPERM;
+
+	prev_state = out_item->smem_edge_state;
+
+	/* create local item */
+	if (!out_item->smem_edge_out) {
+		out_item->smem_edge_out = smp2p_get_local_smem_item(remote_pid);
+		if (!out_item->smem_edge_out) {
+			SMP2P_ERR(
+				"%s unable to allocate SMEM item for pid %d\n",
+				__func__, remote_pid);
+			return -ENODEV;
+		}
+		out_item->smem_edge_state = SMP2P_EDGE_STATE_OPENING;
+	}
+	l_smem_ptr = out_item->smem_edge_out;
+
+	/* retrieve remote side and version */
+	spin_lock(&in_list[remote_pid].in_item_lock_lhb1);
+	r_smem_ptr = smp2p_get_remote_smem_item(remote_pid, out_item);
+	spin_unlock(&in_list[remote_pid].in_item_lock_lhb1);
+
+	r_version = 0;
+	if (r_smem_ptr) {
+		r_version = SMP2P_GET_VERSION(r_smem_ptr->feature_version);
+		r_feature = SMP2P_GET_FEATURES(r_smem_ptr->feature_version);
+	}
+
+	if (r_version == 0) {
+		/*
+		 * Either remote side doesn't exist, or is in the
+		 * process of being initialized (the version is set last).
+		 *
+		 * In either case, treat as if the other side doesn't exist
+		 * and write out our maximum supported version.
+		 */
+		r_smem_ptr = NULL;
+		r_version = ARRAY_SIZE(version_if) - 1;
+		r_feature = ~0U;
+	}
+
+	/* find maximum supported version and feature set */
+	l_version = min(r_version, ARRAY_SIZE(version_if) - 1);
+	for (; l_version > 0; --l_version) {
+		if (!version_if[l_version].is_supported)
+			continue;
+
+		/* found valid version */
+		l_feature = version_if[l_version].negotiate_features(~0U);
+		if (l_version == r_version)
+			l_feature &= r_feature;
+		break;
+	}
+
+	if (l_version == 0) {
+		SMP2P_ERR(
+			"%s: negotiation failure pid %d: RV %d RF %x\n",
+			__func__, remote_pid, r_version, r_feature
+			);
+		SMP2P_SET_VERSION(l_smem_ptr->feature_version,
+			SMP2P_EDGE_STATE_FAILED);
+		smp2p_send_interrupt(remote_pid);
+		out_item->smem_edge_state = SMP2P_EDGE_STATE_FAILED;
+		return -EPERM;
+	}
+
+	/* update header and notify remote side */
+	smp2p_init_header(l_smem_ptr, SMP2P_APPS_PROC, remote_pid,
+		l_feature, l_version);
+	smp2p_send_interrupt(remote_pid);
+
+	/* handle internal state changes */
+	if (r_smem_ptr && l_version == r_version &&
+			l_feature == r_feature) {
+		struct msm_smp2p_out *pos;
+
+		/* negotiation complete */
+		out_item->smem_edge_state = SMP2P_EDGE_STATE_OPENED;
+		out_item->ops_ptr = &version_if[l_version];
+		SMP2P_INFO(
+			"%s: negotiation complete pid %d: State %d->%d F0x%08x\n",
+			__func__, remote_pid, prev_state,
+			out_item->smem_edge_state, l_feature);
+
+		/* create any pending outbound entries */
+		list_for_each_entry(pos, &out_item->list, out_edge_list) {
+			out_item->ops_ptr->create_entry(pos);
+		}
+
+		/* update inbound edge */
+		spin_lock(&in_list[remote_pid].in_item_lock_lhb1);
+		(void)out_item->ops_ptr->validate_size(remote_pid, r_smem_ptr,
+				in_list[remote_pid].item_size);
+		in_list[remote_pid].smem_edge_in = r_smem_ptr;
+		spin_unlock(&in_list[remote_pid].in_item_lock_lhb1);
+	} else {
+		SMP2P_INFO("%s: negotiation pid %d: State %d->%d F0x%08x\n",
+			__func__, remote_pid, prev_state,
+			out_item->smem_edge_state, l_feature);
+	}
+	return 0;
+}
+
+/**
+ * msm_smp2p_out_open - Opens an outbound entry.
+ *
+ * @remote_pid: Outbound processor ID.
+ * @name: Name of the entry.
+ * @open_notifier: Notifier block for the open notification.
+ * @handle: Handle to the smem entry structure.
+ * @returns: 0 on success, standard Linux error code otherwise.
+ *
+ * Opens an outbound entry with the name specified by entry, from the
+ * local processor to the remote processor(remote_pid). If the entry, remote_pid
+ * and open_notifier are valid, then handle will be set and zero will be
+ * returned. The smem item that holds this entry will be created if it has
+ * not been created according to the version negotiation algorithm.
+ * The open_notifier will be used to notify the clients about the
+ * availability of the entry.
+ */
+int msm_smp2p_out_open(int remote_pid, const char *name,
+				   struct notifier_block *open_notifier,
+				   struct msm_smp2p_out **handle)
+{
+	struct msm_smp2p_out *out_entry;
+	struct msm_smp2p_out *pos;
+	int ret = 0;
+	unsigned long flags;
+
+	if (handle)
+		*handle = NULL;
+
+	if (remote_pid >= SMP2P_NUM_PROCS || !name || !open_notifier || !handle)
+		return -EINVAL;
+
+	/* Allocate the smp2p object and node */
+	out_entry = kzalloc(sizeof(*out_entry), GFP_KERNEL);
+	if (!out_entry)
+		return -ENOMEM;
+
+	/* Handle duplicate registration */
+	spin_lock_irqsave(&out_list[remote_pid].out_item_lock_lha1, flags);
+	list_for_each_entry(pos, &out_list[remote_pid].list,
+			out_edge_list) {
+		if (!strcmp(pos->name, name)) {
+			spin_unlock_irqrestore(
+				&out_list[remote_pid].out_item_lock_lha1,
+				flags);
+			kfree(out_entry);
+			SMP2P_ERR("%s: duplicate registration '%s':%d\n",
+				__func__, name, remote_pid);
+			return -EBUSY;
+		}
+	}
+
+	out_entry->remote_pid = remote_pid;
+	RAW_INIT_NOTIFIER_HEAD(&out_entry->msm_smp2p_notifier_list);
+	strlcpy(out_entry->name, name, SMP2P_MAX_ENTRY_NAME);
+	out_entry->open_nb = open_notifier;
+	raw_notifier_chain_register(&out_entry->msm_smp2p_notifier_list,
+		  out_entry->open_nb);
+	list_add(&out_entry->out_edge_list, &out_list[remote_pid].list);
+
+	ret = out_list[remote_pid].ops_ptr->create_entry(out_entry);
+	if (ret) {
+		list_del(&out_entry->out_edge_list);
+		raw_notifier_chain_unregister(
+			&out_entry->msm_smp2p_notifier_list,
+			out_entry->open_nb);
+		spin_unlock_irqrestore(
+			&out_list[remote_pid].out_item_lock_lha1, flags);
+		kfree(out_entry);
+		SMP2P_ERR("%s: unable to open '%s':%d error %d\n",
+				__func__, name, remote_pid, ret);
+		return ret;
+	}
+	spin_unlock_irqrestore(&out_list[remote_pid].out_item_lock_lha1,
+			flags);
+	*handle = out_entry;
+
+	return 0;
+}
+EXPORT_SYMBOL(msm_smp2p_out_open);
+
+/**
+ * msm_smp2p_out_close - Closes the handle to an outbound entry.
+ *
+ * @handle: Pointer to smp2p out entry handle.
+ * @returns: 0 on success, standard Linux error code otherwise.
+ *
+ * The actual entry will not be deleted and can be re-opened at a later
+ * time.  The handle will be set to NULL.
+ */
+int msm_smp2p_out_close(struct msm_smp2p_out **handle)
+{
+	unsigned long flags;
+	struct msm_smp2p_out *out_entry;
+	struct smp2p_out_list_item *out_item;
+
+	if (!handle || !*handle)
+		return -EINVAL;
+
+	out_entry = *handle;
+	*handle = NULL;
+
+	out_item = &out_list[out_entry->remote_pid];
+	spin_lock_irqsave(&out_item->out_item_lock_lha1, flags);
+	list_del(&out_entry->out_edge_list);
+	raw_notifier_chain_unregister(&out_entry->msm_smp2p_notifier_list,
+		out_entry->open_nb);
+	spin_unlock_irqrestore(&out_item->out_item_lock_lha1, flags);
+
+	kfree(out_entry);
+
+	return 0;
+}
+EXPORT_SYMBOL(msm_smp2p_out_close);
+
+/**
+ * msm_smp2p_out_read - Allows reading the entry.
+ *
+ * @handle: Handle to the smem entry structure.
+ * @data: Out pointer that holds the read data.
+ * @returns: 0 on success, standard Linux error code otherwise.
+ *
+ * Allows reading of the outbound entry for read-modify-write
+ * operation.
+ */
+int msm_smp2p_out_read(struct msm_smp2p_out *handle, uint32_t *data)
+{
+	int ret = -EINVAL;
+	unsigned long flags;
+	struct smp2p_out_list_item *out_item;
+
+	if (!handle || !data)
+		return ret;
+
+	out_item = &out_list[handle->remote_pid];
+	spin_lock_irqsave(&out_item->out_item_lock_lha1, flags);
+	ret = out_item->ops_ptr->read_entry(handle, data);
+	spin_unlock_irqrestore(&out_item->out_item_lock_lha1, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(msm_smp2p_out_read);
+
+/**
+ * msm_smp2p_out_write - Allows writing to the entry.
+ *
+ * @handle: Handle to smem entry structure.
+ * @data: Data that has to be written.
+ * @returns: 0 on success, standard Linux error code otherwise.
+ *
+ * Writes a new value to the output entry. Multiple back-to-back writes
+ * may overwrite previous writes before the remote processor get a chance
+ * to see them leading to ABA race condition. The client must implement
+ * their own synchronization mechanism (such as echo mechanism) if this is
+ * not acceptable.
+ */
+int msm_smp2p_out_write(struct msm_smp2p_out *handle, uint32_t data)
+{
+	int ret = -EINVAL;
+	unsigned long flags;
+	struct smp2p_out_list_item *out_item;
+
+	if (!handle)
+		return ret;
+
+	out_item = &out_list[handle->remote_pid];
+	spin_lock_irqsave(&out_item->out_item_lock_lha1, flags);
+	ret = out_item->ops_ptr->write_entry(handle, data);
+	spin_unlock_irqrestore(&out_item->out_item_lock_lha1, flags);
+
+	return ret;
+
+}
+EXPORT_SYMBOL(msm_smp2p_out_write);
+
+/**
+ * msm_smp2p_out_modify - Modifies the entry.
+ *
+ * @handle: Handle to the smem entry structure.
+ * @set_mask: Specifies the bits that needs to be set.
+ * @clear_mask: Specifies the bits that needs to be cleared.
+ * @returns: 0 on success, standard Linux error code otherwise.
+ *
+ * The modification is done by doing a bitwise AND of clear mask followed by
+ * the bit wise OR of set mask. The clear bit mask is applied first to the
+ * data, so if a bit is set in both the clear mask and the set mask, then in
+ * the result is a set bit.  Multiple back-to-back modifications may overwrite
+ * previous values before the remote processor gets a chance to see them
+ * leading to ABA race condition. The client must implement their own
+ * synchronization mechanism (such as echo mechanism) if this is not
+ * acceptable.
+ */
+int msm_smp2p_out_modify(struct msm_smp2p_out *handle, uint32_t set_mask,
+							uint32_t clear_mask)
+{
+	int ret = -EINVAL;
+	unsigned long flags;
+	struct smp2p_out_list_item *out_item;
+
+	if (!handle)
+		return ret;
+
+	out_item = &out_list[handle->remote_pid];
+	spin_lock_irqsave(&out_item->out_item_lock_lha1, flags);
+	ret = out_item->ops_ptr->modify_entry(handle, set_mask, clear_mask);
+	spin_unlock_irqrestore(&out_item->out_item_lock_lha1, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(msm_smp2p_out_modify);
+
+/**
+ * msm_smp2p_in_read - Read an entry on a remote processor.
+ *
+ * @remote_pid: Processor ID of the remote processor.
+ * @name: Name of the entry that is to be read.
+ * @data: Output pointer, the value will be placed here if successful.
+ * @returns: 0 on success, standard Linux error code otherwise.
+ */
+int msm_smp2p_in_read(int remote_pid, const char *name, uint32_t *data)
+{
+	unsigned long flags;
+	struct smp2p_out_list_item *out_item;
+	uint32_t *entry_ptr;
+
+	if (remote_pid >= SMP2P_NUM_PROCS)
+		return -EINVAL;
+
+	out_item = &out_list[remote_pid];
+	spin_lock_irqsave(&out_item->out_item_lock_lha1, flags);
+	spin_lock(&in_list[remote_pid].in_item_lock_lhb1);
+
+	if (in_list[remote_pid].smem_edge_in)
+		out_item->ops_ptr->find_entry(
+			in_list[remote_pid].smem_edge_in,
+			in_list[remote_pid].safe_total_entries,
+			(char *)name, &entry_ptr, NULL);
+
+	spin_unlock(&in_list[remote_pid].in_item_lock_lhb1);
+	spin_unlock_irqrestore(&out_item->out_item_lock_lha1, flags);
+
+	if (!entry_ptr)
+		return -ENODEV;
+
+	*data = readl_relaxed(entry_ptr);
+	return 0;
+}
+EXPORT_SYMBOL(msm_smp2p_in_read);
+
+/**
+ * msm_smp2p_in_register -  Notifies the change in value of the entry.
+ *
+ * @pid: Remote processor ID.
+ * @name: Name of the entry.
+ * @in_notifier: Notifier block used to notify about the event.
+ * @returns: 0 on success, standard Linux error code otherwise.
+ *
+ * Register for change notifications for a remote entry. If the remote entry
+ * does not exist yet, then the registration request will be held until the
+ * remote side opens. Once the entry is open, then the SMP2P_OPEN notification
+ * will be sent. Any changes to the entry will trigger a call to the notifier
+ * block with an SMP2P_ENTRY_UPDATE event and the data field will point to an
+ * msm_smp2p_update_notif structure containing the current and previous value.
+ */
+int msm_smp2p_in_register(int pid, const char *name,
+	struct notifier_block *in_notifier)
+{
+	struct smp2p_in *pos;
+	struct smp2p_in *in = NULL;
+	int ret;
+	unsigned long flags;
+	struct msm_smp2p_update_notif data;
+	uint32_t *entry_ptr;
+
+	if (pid >= SMP2P_NUM_PROCS || !name || !in_notifier)
+		return -EINVAL;
+
+	/* Pre-allocate before spinlock since we will likely needed it */
+	in = kzalloc(sizeof(*in), GFP_KERNEL);
+	if (!in)
+		return -ENOMEM;
+
+	/* Search for existing entry */
+	spin_lock_irqsave(&out_list[pid].out_item_lock_lha1, flags);
+	spin_lock(&in_list[pid].in_item_lock_lhb1);
+
+	list_for_each_entry(pos, &in_list[pid].list, in_edge_list) {
+		if (!strncmp(pos->name, name,
+					SMP2P_MAX_ENTRY_NAME)) {
+			kfree(in);
+			in = pos;
+			break;
+		}
+	}
+
+	/* Create and add it to the list */
+	if (!in->notifier_count) {
+		in->remote_pid = pid;
+		strlcpy(in->name, name, SMP2P_MAX_ENTRY_NAME);
+		RAW_INIT_NOTIFIER_HEAD(&in->in_notifier_list);
+		list_add(&in->in_edge_list, &in_list[pid].list);
+	}
+
+	ret = raw_notifier_chain_register(&in->in_notifier_list,
+			in_notifier);
+	if (ret) {
+		if (!in->notifier_count) {
+			list_del(&in->in_edge_list);
+			kfree(in);
+		}
+		SMP2P_DBG("%s: '%s':%d failed %d\n", __func__, name, pid, ret);
+		goto bail;
+	}
+	in->notifier_count++;
+
+	if (out_list[pid].smem_edge_state == SMP2P_EDGE_STATE_OPENED) {
+		out_list[pid].ops_ptr->find_entry(
+				in_list[pid].smem_edge_in,
+				in_list[pid].safe_total_entries, (char *)name,
+				&entry_ptr, NULL);
+		if (entry_ptr) {
+			in->entry_ptr = entry_ptr;
+			in->prev_entry_val = readl_relaxed(entry_ptr);
+
+			data.previous_value = in->prev_entry_val;
+			data.current_value = in->prev_entry_val;
+			in_notifier->notifier_call(in_notifier, SMP2P_OPEN,
+					(void *)&data);
+		}
+	}
+	SMP2P_DBG("%s: '%s':%d registered\n", __func__, name, pid);
+
+bail:
+	spin_unlock(&in_list[pid].in_item_lock_lhb1);
+	spin_unlock_irqrestore(&out_list[pid].out_item_lock_lha1, flags);
+	return ret;
+
+}
+EXPORT_SYMBOL(msm_smp2p_in_register);
+
+/**
+ * msm_smp2p_in_unregister - Unregister the notifier for remote entry.
+ *
+ * @remote_pid: Processor Id of the remote processor.
+ * @name: The name of the entry.
+ * @in_notifier: Notifier block passed during registration.
+ * @returns: 0 on success, standard Linux error code otherwise.
+ */
+int msm_smp2p_in_unregister(int remote_pid, const char *name,
+				struct notifier_block *in_notifier)
+{
+	struct smp2p_in *pos;
+	struct smp2p_in *in = NULL;
+	int ret = -ENODEV;
+	unsigned long flags;
+
+	if (remote_pid >= SMP2P_NUM_PROCS || !name || !in_notifier)
+		return -EINVAL;
+
+	spin_lock_irqsave(&in_list[remote_pid].in_item_lock_lhb1, flags);
+	list_for_each_entry(pos, &in_list[remote_pid].list,
+			in_edge_list) {
+		if (!strncmp(pos->name, name, SMP2P_MAX_ENTRY_NAME)) {
+			in = pos;
+			break;
+		}
+	}
+	if (!in)
+		goto fail;
+
+	ret = raw_notifier_chain_unregister(&pos->in_notifier_list,
+			in_notifier);
+	if (ret == 0) {
+		pos->notifier_count--;
+		if (!pos->notifier_count) {
+			list_del(&pos->in_edge_list);
+			kfree(pos);
+			ret = 0;
+		}
+	} else {
+		SMP2P_ERR("%s: unregister failure '%s':%d\n", __func__,
+			name, remote_pid);
+		ret = -ENODEV;
+	}
+
+fail:
+	spin_unlock_irqrestore(&in_list[remote_pid].in_item_lock_lhb1, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(msm_smp2p_in_unregister);
+
+/**
+ * smp2p_send_interrupt - Send interrupt to remote system.
+ *
+ * @remote_pid:  Processor ID of the remote system
+ *
+ * Must be called with out_item_lock_lha1 locked.
+ */
+static void smp2p_send_interrupt(int remote_pid)
+{
+	if (smp2p_int_cfgs[remote_pid].name)
+		SMP2P_DBG("SMP2P Int Apps->%s(%d)\n",
+			smp2p_int_cfgs[remote_pid].name, remote_pid);
+
+	++smp2p_int_cfgs[remote_pid].out_interrupt_count;
+	if (remote_pid != SMP2P_REMOTE_MOCK_PROC &&
+			smp2p_int_cfgs[remote_pid].out_int_mask) {
+		/* flush any pending writes before triggering interrupt */
+		wmb();
+		writel_relaxed(smp2p_int_cfgs[remote_pid].out_int_mask,
+			smp2p_int_cfgs[remote_pid].out_int_ptr);
+	} else {
+		smp2p_remote_mock_rx_interrupt();
+	}
+}
+
+/**
+ * smp2p_in_edge_notify - Notifies the entry changed on remote processor.
+ *
+ * @pid: Processor ID of the remote processor.
+ *
+ * This function is invoked on an incoming interrupt, it scans
+ * the list of the clients registered for the entries on the remote
+ * processor and notifies them if  the data changes.
+ *
+ * Note:  Edge state must be OPENED to avoid a race condition with
+ *        out_list[pid].ops_ptr->find_entry.
+ */
+static void smp2p_in_edge_notify(int pid)
+{
+	struct smp2p_in *pos;
+	uint32_t *entry_ptr;
+	unsigned long flags;
+	struct smp2p_smem __iomem *smem_h_ptr;
+	uint32_t curr_data;
+	struct  msm_smp2p_update_notif data;
+
+	spin_lock_irqsave(&in_list[pid].in_item_lock_lhb1, flags);
+	smem_h_ptr = in_list[pid].smem_edge_in;
+	if (!smem_h_ptr) {
+		SMP2P_DBG("%s: No remote SMEM item for pid %d\n",
+			__func__, pid);
+		spin_unlock_irqrestore(&in_list[pid].in_item_lock_lhb1, flags);
+		return;
+	}
+
+	list_for_each_entry(pos, &in_list[pid].list, in_edge_list) {
+		if (pos->entry_ptr == NULL) {
+			/* entry not open - try to open it */
+			out_list[pid].ops_ptr->find_entry(smem_h_ptr,
+				in_list[pid].safe_total_entries, pos->name,
+				&entry_ptr, NULL);
+
+			if (entry_ptr) {
+				pos->entry_ptr = entry_ptr;
+				pos->prev_entry_val = 0;
+				data.previous_value = 0;
+				data.current_value = readl_relaxed(entry_ptr);
+				raw_notifier_call_chain(
+					    &pos->in_notifier_list,
+					    SMP2P_OPEN, (void *)&data);
+			}
+		}
+
+		if (pos->entry_ptr != NULL) {
+			/* send update notification */
+			curr_data = readl_relaxed(pos->entry_ptr);
+			if (curr_data != pos->prev_entry_val) {
+				data.previous_value = pos->prev_entry_val;
+				data.current_value = curr_data;
+				pos->prev_entry_val = curr_data;
+				raw_notifier_call_chain(
+					&pos->in_notifier_list,
+					SMP2P_ENTRY_UPDATE, (void *)&data);
+			}
+		}
+	}
+	spin_unlock_irqrestore(&in_list[pid].in_item_lock_lhb1, flags);
+}
+
+/**
+ * smp2p_interrupt_handler - Incoming interrupt handler.
+ *
+ * @irq: Interrupt ID
+ * @data: Edge
+ * @returns: IRQ_HANDLED or IRQ_NONE for invalid interrupt
+ */
+static irqreturn_t smp2p_interrupt_handler(int irq, void *data)
+{
+	unsigned long flags;
+	uint32_t remote_pid = (uint32_t)data;
+
+	if (remote_pid >= SMP2P_NUM_PROCS) {
+		SMP2P_ERR("%s: invalid interrupt pid %d\n",
+			__func__, remote_pid);
+		return IRQ_NONE;
+	}
+
+	if (smp2p_int_cfgs[remote_pid].name)
+		SMP2P_DBG("SMP2P Int %s(%d)->Apps\n",
+			smp2p_int_cfgs[remote_pid].name, remote_pid);
+
+	spin_lock_irqsave(&out_list[remote_pid].out_item_lock_lha1, flags);
+	++smp2p_int_cfgs[remote_pid].in_interrupt_count;
+
+	if (out_list[remote_pid].smem_edge_state != SMP2P_EDGE_STATE_OPENED)
+		smp2p_do_negotiation(remote_pid, &out_list[remote_pid]);
+
+	if (out_list[remote_pid].smem_edge_state == SMP2P_EDGE_STATE_OPENED) {
+		spin_unlock_irqrestore(&out_list[remote_pid].out_item_lock_lha1,
+			flags);
+		smp2p_in_edge_notify(remote_pid);
+	} else {
+		spin_unlock_irqrestore(&out_list[remote_pid].out_item_lock_lha1,
+			flags);
+	}
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * smp2p_reset_mock_edge - Reinitializes the mock edge.
+ *
+ * @returns: 0 on success, -EAGAIN to retry later.
+ *
+ * Reinitializes the mock edge to initial power-up state values.
+ */
+int smp2p_reset_mock_edge(void)
+{
+	const int rpid = SMP2P_REMOTE_MOCK_PROC;
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(&out_list[rpid].out_item_lock_lha1, flags);
+	spin_lock(&in_list[rpid].in_item_lock_lhb1);
+
+	if (!list_empty(&out_list[rpid].list) ||
+			!list_empty(&in_list[rpid].list)) {
+		ret = -EAGAIN;
+		goto fail;
+	}
+
+	kfree(out_list[rpid].smem_edge_out);
+	out_list[rpid].smem_edge_out = NULL;
+	out_list[rpid].ops_ptr = &version_if[0];
+	out_list[rpid].smem_edge_state = SMP2P_EDGE_STATE_CLOSED;
+
+	in_list[rpid].smem_edge_in = NULL;
+	in_list[rpid].item_size = 0;
+	in_list[rpid].safe_total_entries = 0;
+
+fail:
+	spin_unlock(&in_list[rpid].in_item_lock_lhb1);
+	spin_unlock_irqrestore(&out_list[rpid].out_item_lock_lha1, flags);
+
+	return ret;
+}
+
+/**
+ * msm_smp2p_interrupt_handler - Triggers incoming interrupt.
+ *
+ * @remote_pid: Remote processor ID
+ *
+ * This function is used with the remote mock infrastructure
+ * used for testing. It simulates triggering of interrupt in
+ * a testing environment.
+ */
+void msm_smp2p_interrupt_handler(int remote_pid)
+{
+	smp2p_interrupt_handler(0, (void *)remote_pid);
+}
+
+/**
+ * msm_smp2p_probe - Device tree probe function.
+ *
+ * @pdev: Pointer to device tree data.
+ * @returns: 0 on success; -ENODEV otherwise
+ */
+static int __devinit msm_smp2p_probe(struct platform_device *pdev)
+{
+	struct resource *irq_out_base;
+	struct resource *irq_offset;
+	char *key;
+	uint32_t edge;
+	int ret;
+	struct device_node *node;
+	uint32_t irq_bitmask;
+	uint32_t irq_line;
+
+	node = pdev->dev.of_node;
+
+	key = "qcom,remote-pid";
+	ret = of_property_read_u32(node, key, &edge);
+	if (ret) {
+		SMP2P_ERR("%s: missing edge '%s'\n", __func__, key);
+		goto fail;
+	}
+
+	key = "irq-reg-base";
+	irq_out_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, key);
+	if (!irq_out_base)
+		goto missing_key;
+
+	key = "irq-reg-offset";
+	irq_offset = platform_get_resource_byname(pdev, IORESOURCE_MEM, key);
+	if (!irq_offset)
+		goto missing_key;
+
+	key = "qcom,irq-bitmask";
+	ret = of_property_read_u32(node, key, &irq_bitmask);
+	if (ret)
+		goto missing_key;
+
+	key = "interrupts";
+	irq_line = platform_get_irq(pdev, 0);
+	if (irq_line == -ENXIO)
+		goto missing_key;
+
+	ret = request_irq(irq_line, smp2p_interrupt_handler,
+			IRQF_TRIGGER_RISING, "smp2p", (void *)edge);
+	if (ret < 0) {
+		SMP2P_ERR("%s: request_irq() failed on %d (edge %d)\n",
+				__func__, irq_line, edge);
+		goto fail;
+	}
+
+	ret = enable_irq_wake(irq_line);
+	if (ret < 0)
+		SMP2P_ERR("%s: enable_irq_wake() failed on %d (edge %d)\n",
+				__func__, irq_line, edge);
+
+	/*
+	 * Set entry (keep is_configured last to prevent usage before
+	 * initialization).
+	 */
+	smp2p_int_cfgs[edge].in_int_id = irq_line;
+	smp2p_int_cfgs[edge].out_int_mask = irq_bitmask;
+	smp2p_int_cfgs[edge].out_int_ptr =
+		(uint32_t *)((uint32_t)irq_out_base->start +
+				(uint32_t)irq_offset->start);
+	smp2p_int_cfgs[edge].is_configured = true;
+	return 0;
+
+missing_key:
+	SMP2P_ERR("%s: missing '%s' for edge %d\n", __func__, key, edge);
+fail:
+	return -ENODEV;
+}
+
+static struct of_device_id msm_smp2p_match_table[] = {
+	{ .compatible = "qcom,smp2p" },
+	{},
+};
+
+static struct platform_driver msm_smp2p_driver = {
+	.probe = msm_smp2p_probe,
+	.driver = {
+		.name = "msm_smp2p",
+		.owner = THIS_MODULE,
+		.of_match_table = msm_smp2p_match_table,
+	},
+};
+
+/**
+ * msm_smp2p_init -  Initialization function for the module.
+ *
+ * @returns: 0 on success, standard Linux error code otherwise.
+ */
+static int __init msm_smp2p_init(void)
+{
+	int i;
+	int rc;
+
+	for (i = 0; i < SMP2P_NUM_PROCS; i++) {
+		spin_lock_init(&out_list[i].out_item_lock_lha1);
+		INIT_LIST_HEAD(&out_list[i].list);
+		out_list[i].smem_edge_out = NULL;
+		out_list[i].smem_edge_state = SMP2P_EDGE_STATE_CLOSED;
+		out_list[i].ops_ptr = &version_if[0];
+
+		spin_lock_init(&in_list[i].in_item_lock_lhb1);
+		INIT_LIST_HEAD(&in_list[i].list);
+		in_list[i].smem_edge_in = NULL;
+	}
+
+	log_ctx = ipc_log_context_create(NUM_LOG_PAGES, "smp2p");
+	if (!log_ctx)
+		SMP2P_ERR("%s: unable to create log context\n", __func__);
+
+	rc = platform_driver_register(&msm_smp2p_driver);
+	if (rc) {
+		SMP2P_ERR("%s: msm_smp2p_driver register failed %d\n",
+			__func__, rc);
+		return rc;
+	}
+
+	return 0;
+}
+module_init(msm_smp2p_init);
+
+MODULE_DESCRIPTION("MSM Shared Memory Point to Point");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/smp2p_debug.c b/arch/arm/mach-msm/smp2p_debug.c
new file mode 100644
index 0000000..a493cbe
--- /dev/null
+++ b/arch/arm/mach-msm/smp2p_debug.c
@@ -0,0 +1,328 @@
+/* arch/arm/mach-msm/smp2p_debug.c
+ *
+ * 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/ctype.h>
+#include <linux/list.h>
+#include <linux/debugfs.h>
+#include "smp2p_private.h"
+
+#if defined(CONFIG_DEBUG_FS)
+
+/**
+ * Dump interrupt statistics.
+ *
+ * @s:   pointer to output file
+ */
+static void smp2p_int_stats(struct seq_file *s)
+{
+	struct smp2p_interrupt_config *int_cfg;
+	int pid;
+
+	int_cfg = smp2p_get_interrupt_config();
+	if (!int_cfg)
+		return;
+
+	seq_printf(s, "| Processor | Incoming Id | Incoming # |");
+	seq_printf(s, " Outgoing # | Base Ptr |   Mask   |\n");
+
+	for (pid = 0; pid < SMP2P_NUM_PROCS; ++pid) {
+		if (!int_cfg[pid].is_configured &&
+				pid != SMP2P_REMOTE_MOCK_PROC)
+			continue;
+
+		seq_printf(s,
+			"| %5s (%d) | %11u | %10u | %10u | %p | %08x |\n",
+			int_cfg[pid].name,
+			pid, int_cfg[pid].in_int_id,
+			int_cfg[pid].in_interrupt_count,
+			int_cfg[pid].out_interrupt_count,
+			int_cfg[pid].out_int_ptr,
+			int_cfg[pid].out_int_mask);
+	}
+}
+
+/**
+ * Dump item header line 1.
+ *
+ * @buf:      output buffer
+ * @max:      length of output buffer
+ * @item_ptr: SMEM item pointer
+ * @state:    item state
+ * @returns: Number of bytes written to output buffer
+ */
+static int smp2p_item_header1(char *buf, int max, struct smp2p_smem *item_ptr,
+	enum msm_smp2p_edge_state state)
+{
+	int i = 0;
+	const char *state_text;
+
+	if (!item_ptr) {
+		i += scnprintf(buf + i, max - i, "None");
+		return i;
+	}
+
+	switch (state) {
+	case SMP2P_EDGE_STATE_CLOSED:
+		state_text = "State: Closed";
+		break;
+	case SMP2P_EDGE_STATE_OPENING:
+		state_text = "State: Opening";
+		break;
+	case SMP2P_EDGE_STATE_OPENED:
+		state_text = "State: Opened";
+		break;
+	default:
+		state_text = "";
+		break;
+	}
+
+	i += scnprintf(buf + i, max - i,
+		"%-14s LPID %d RPID %d",
+		state_text,
+		SMP2P_GET_LOCAL_PID(item_ptr->rem_loc_proc_id),
+		SMP2P_GET_REMOTE_PID(item_ptr->rem_loc_proc_id)
+		);
+
+	return i;
+}
+
+/**
+ * Dump item header line 2.
+ *
+ * @buf:      output buffer
+ * @max:      length of output buffer
+ * @item_ptr: SMEM item pointer
+ * @returns: Number of bytes written to output buffer
+ */
+static int smp2p_item_header2(char *buf, int max, struct smp2p_smem *item_ptr)
+{
+	int i = 0;
+
+	if (!item_ptr) {
+		i += scnprintf(buf + i, max - i, "None");
+		return i;
+	}
+
+	i += scnprintf(buf + i, max - i,
+		"Version: %08x Features: %08x",
+		SMP2P_GET_VERSION(item_ptr->feature_version),
+		SMP2P_GET_FEATURES(item_ptr->feature_version)
+		);
+
+	return i;
+}
+
+/**
+ * Dump item header line 3.
+ *
+ * @buf:      output buffer
+ * @max:      length of output buffer
+ * @item_ptr: SMEM item pointer
+ * @state:    item state
+ * @returns: Number of bytes written to output buffer
+ */
+static int smp2p_item_header3(char *buf, int max, struct smp2p_smem *item_ptr)
+{
+	int i = 0;
+
+	if (!item_ptr) {
+		i += scnprintf(buf + i, max - i, "None");
+		return i;
+	}
+
+	i += scnprintf(buf + i, max - i,
+		"Entries Valid/Max: %d/%d",
+		SMP2P_GET_ENT_VALID(item_ptr->valid_total_ent),
+		SMP2P_GET_ENT_TOTAL(item_ptr->valid_total_ent)
+		);
+
+	return i;
+}
+
+/**
+ * Dump individual input/output item pair.
+ *
+ * @s:   pointer to output file
+ */
+static void smp2p_item(struct seq_file *s, int remote_pid)
+{
+	struct smp2p_smem *out_ptr;
+	struct smp2p_smem *in_ptr;
+	struct smp2p_interrupt_config *int_cfg;
+	char tmp_buff[64];
+	int state;
+	int entry;
+	struct smp2p_entry_v1 *out_entries = NULL;
+	struct smp2p_entry_v1 *in_entries = NULL;
+	int out_valid = 0;
+	int in_valid = 0;
+
+	int_cfg = smp2p_get_interrupt_config();
+	if (!int_cfg)
+		return;
+	if (!int_cfg[remote_pid].is_configured &&
+			remote_pid != SMP2P_REMOTE_MOCK_PROC)
+		return;
+
+	out_ptr = smp2p_get_out_item(remote_pid, &state);
+	in_ptr = smp2p_get_in_item(remote_pid);
+
+	if (!out_ptr && !in_ptr)
+		return;
+
+	/* print item headers */
+	seq_printf(s, "%s%s\n",
+		" ====================================== ",
+		"======================================");
+	scnprintf(tmp_buff, sizeof(tmp_buff),
+		"Apps(%d)->%s(%d)",
+		SMP2P_APPS_PROC, int_cfg[remote_pid].name, remote_pid);
+	seq_printf(s, "| %-37s", tmp_buff);
+
+	scnprintf(tmp_buff, sizeof(tmp_buff),
+		"%s(%d)->Apps(%d)",
+		int_cfg[remote_pid].name, remote_pid, SMP2P_APPS_PROC);
+	seq_printf(s, "| %-37s|\n", tmp_buff);
+	seq_printf(s, "%s%s\n",
+		" ====================================== ",
+		"======================================");
+
+	smp2p_item_header1(tmp_buff, sizeof(tmp_buff), out_ptr, state);
+	seq_printf(s, "| %-37s", tmp_buff);
+	smp2p_item_header1(tmp_buff, sizeof(tmp_buff), in_ptr, -1);
+	seq_printf(s, "| %-37s|\n", tmp_buff);
+
+	smp2p_item_header2(tmp_buff, sizeof(tmp_buff), out_ptr);
+	seq_printf(s, "| %-37s", tmp_buff);
+	smp2p_item_header2(tmp_buff, sizeof(tmp_buff), in_ptr);
+	seq_printf(s, "| %-37s|\n", tmp_buff);
+
+	smp2p_item_header3(tmp_buff, sizeof(tmp_buff), out_ptr);
+	seq_printf(s, "| %-37s", tmp_buff);
+	smp2p_item_header3(tmp_buff, sizeof(tmp_buff), in_ptr);
+	seq_printf(s, "| %-37s|\n", tmp_buff);
+
+	seq_printf(s, " %s%s\n",
+		"-------------------------------------- ",
+		"--------------------------------------");
+	seq_printf(s, "| %-37s",
+		"Entry Name       Value");
+	seq_printf(s, "| %-37s|\n",
+		"Entry Name       Value");
+	seq_printf(s, " %s%s\n",
+		"-------------------------------------- ",
+		"--------------------------------------");
+
+	/* print entries */
+	if (out_ptr) {
+		out_entries = (struct smp2p_entry_v1 *)((void *)out_ptr +
+				sizeof(struct smp2p_smem));
+		out_valid = SMP2P_GET_ENT_VALID(out_ptr->valid_total_ent);
+	}
+
+	if (in_ptr) {
+		in_entries = (struct smp2p_entry_v1 *)((void *)in_ptr +
+				sizeof(struct smp2p_smem));
+		in_valid = SMP2P_GET_ENT_VALID(in_ptr->valid_total_ent);
+	}
+
+	for (entry = 0; out_entries || in_entries; ++entry) {
+		if (out_entries && entry < out_valid) {
+			scnprintf(tmp_buff, sizeof(tmp_buff),
+					"%-16s 0x%08x",
+					out_entries->name,
+					out_entries->entry);
+			++out_entries;
+		} else {
+			out_entries = NULL;
+			scnprintf(tmp_buff, sizeof(tmp_buff), "None");
+		}
+		seq_printf(s, "| %-37s", tmp_buff);
+
+		if (in_entries && entry < in_valid) {
+			scnprintf(tmp_buff, sizeof(tmp_buff),
+					"%-16s 0x%08x",
+					in_entries->name,
+					in_entries->entry);
+			++in_entries;
+		} else {
+			in_entries = NULL;
+			scnprintf(tmp_buff, sizeof(tmp_buff), "None");
+		}
+		seq_printf(s, "| %-37s|\n", tmp_buff);
+	}
+	seq_printf(s, " %s%s\n\n",
+		"-------------------------------------- ",
+		"--------------------------------------");
+}
+
+/**
+ * Dump item state.
+ *
+ * @s:   pointer to output file
+ */
+static void smp2p_items(struct seq_file *s)
+{
+	int pid;
+
+	for (pid = 0; pid < SMP2P_NUM_PROCS; ++pid)
+		smp2p_item(s, pid);
+}
+
+static struct dentry *dent;
+
+static int debugfs_show(struct seq_file *s, void *data)
+{
+	void (*show)(struct seq_file *) = s->private;
+
+	show(s);
+
+	return 0;
+}
+
+static int debug_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, debugfs_show, inode->i_private);
+}
+
+static const struct file_operations debug_ops = {
+	.open = debug_open,
+	.release = single_release,
+	.read = seq_read,
+	.llseek = seq_lseek,
+};
+
+void debug_create(const char *name,
+			 void (*show)(struct seq_file *))
+{
+	struct dentry *file;
+
+	file = debugfs_create_file(name, 0444, dent, show, &debug_ops);
+	if (!file)
+		pr_err("%s: unable to create file '%s'\n", __func__, name);
+}
+
+static int __init smp2p_debugfs_init(void)
+{
+	dent = debugfs_create_dir("smp2p", 0);
+	if (IS_ERR(dent))
+		return PTR_ERR(dent);
+
+	debug_create("int_stats", smp2p_int_stats);
+	debug_create("items", smp2p_items);
+
+	return 0;
+}
+
+late_initcall(smp2p_debugfs_init);
+#endif /* CONFIG_DEBUG_FS */
diff --git a/arch/arm/mach-msm/smp2p_gpio.c b/arch/arm/mach-msm/smp2p_gpio.c
new file mode 100644
index 0000000..2a85e5f
--- /dev/null
+++ b/arch/arm/mach-msm/smp2p_gpio.c
@@ -0,0 +1,757 @@
+/* arch/arm/mach-msm/smp2p_gpio.c
+ *
+ * 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/platform_device.h>
+#include <linux/bitmap.h>
+#include <linux/of.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <mach/msm_ipc_logging.h>
+#include "smp2p_private_api.h"
+#include "smp2p_private.h"
+
+/* GPIO device - one per SMP2P entry. */
+struct smp2p_chip_dev {
+	struct list_head entry_list;
+	char name[SMP2P_MAX_ENTRY_NAME];
+	int remote_pid;
+	bool is_inbound;
+	bool is_open;
+	struct notifier_block out_notifier;
+	struct notifier_block in_notifier;
+	struct msm_smp2p_out *out_handle;
+
+	struct gpio_chip gpio;
+	struct irq_domain *irq_domain;
+	int irq_base;
+
+	spinlock_t irq_lock;
+	DECLARE_BITMAP(irq_enabled, SMP2P_BITS_PER_ENTRY);
+	DECLARE_BITMAP(irq_rising_edge, SMP2P_BITS_PER_ENTRY);
+	DECLARE_BITMAP(irq_falling_edge, SMP2P_BITS_PER_ENTRY);
+};
+
+static struct platform_driver smp2p_gpio_driver;
+static struct lock_class_key smp2p_gpio_lock_class;
+static struct irq_chip smp2p_gpio_irq_chip;
+static DEFINE_SPINLOCK(smp2p_entry_lock_lha1);
+static LIST_HEAD(smp2p_entry_list);
+
+/* Used for mapping edge to name for logging. */
+static const char * const edge_names[] = {
+	"-",
+	"0->1",
+	"1->0",
+	"-",
+};
+
+/* Used for mapping edge to value for logging. */
+static const char * const edge_name_rising[] = {
+	"-",
+	"0->1",
+};
+
+/* Used for mapping edge to value for logging. */
+static const char * const edge_name_falling[] = {
+	"-",
+	"1->0",
+};
+
+static int smp2p_gpio_to_irq(struct gpio_chip *cp,
+	unsigned offset);
+
+/**
+ * smp2p_get_value - Retrieves GPIO value.
+ *
+ * @cp:      GPIO chip pointer
+ * @offset:  Pin offset
+ * @returns: >=0: value of GPIO Pin; < 0 for error
+ *
+ * Error codes:
+ *   -ENODEV - chip/entry invalid
+ *   -ENETDOWN - valid entry, but entry not yet created
+ */
+static int smp2p_get_value(struct gpio_chip *cp,
+	unsigned offset)
+{
+	struct smp2p_chip_dev *chip;
+	int ret = 0;
+	uint32_t data;
+
+	if (!cp)
+		return -ENODEV;
+
+	chip = container_of(cp, struct smp2p_chip_dev, gpio);
+	if (!chip->is_open)
+		return -ENETDOWN;
+
+	if (chip->is_inbound)
+		ret = msm_smp2p_in_read(chip->remote_pid, chip->name, &data);
+	else
+		ret = msm_smp2p_out_read(chip->out_handle, &data);
+
+	if (!ret)
+		ret = (data & (1 << offset)) ? 1 : 0;
+
+	return ret;
+}
+
+/**
+ * smp2p_set_value - Sets GPIO value.
+ *
+ * @cp:     GPIO chip pointer
+ * @offset: Pin offset
+ * @value:  New value
+ */
+static void smp2p_set_value(struct gpio_chip *cp, unsigned offset, int value)
+{
+	struct smp2p_chip_dev *chip;
+	uint32_t data_set;
+	uint32_t data_clear;
+	int ret;
+
+	if (!cp)
+		return;
+
+	chip = container_of(cp, struct smp2p_chip_dev, gpio);
+	if (!chip->is_open)
+		return;
+
+	if (chip->is_inbound) {
+		SMP2P_ERR("%s: '%s':%d virq %d invalid operation\n",
+			__func__, chip->name, chip->remote_pid,
+			chip->irq_base + offset);
+		return;
+	}
+
+	if (value) {
+		data_set = 1 << offset;
+		data_clear = 0;
+	} else {
+		data_set = 0;
+		data_clear = 1 << offset;
+	}
+
+	ret = msm_smp2p_out_modify(chip->out_handle,
+			data_set, data_clear);
+
+	if (ret)
+		SMP2P_GPIO("'%s':%d gpio %d set to %d failed (%d)\n",
+			chip->name, chip->remote_pid,
+			chip->gpio.base + offset, value, ret);
+	else
+		SMP2P_GPIO("'%s':%d gpio %d set to %d\n",
+			chip->name, chip->remote_pid,
+			chip->gpio.base + offset, value);
+}
+
+/**
+ * smp2p_direction_input - Sets GPIO direction to input.
+ *
+ * @cp:      GPIO chip pointer
+ * @offset:  Pin offset
+ * @returns: 0 for success; < 0 for failure
+ */
+static int smp2p_direction_input(struct gpio_chip *cp, unsigned offset)
+{
+	struct smp2p_chip_dev *chip;
+
+	if (!cp)
+		return -ENODEV;
+
+	chip = container_of(cp, struct smp2p_chip_dev, gpio);
+	if (!chip->is_inbound)
+		return -EPERM;
+
+	return 0;
+}
+
+/**
+ * smp2p_direction_output - Sets GPIO direction to output.
+ *
+ * @cp:      GPIO chip pointer
+ * @offset:  Pin offset
+ * @value:   Direction
+ * @returns: 0 for success; < 0 for failure
+ */
+static int smp2p_direction_output(struct gpio_chip *cp,
+	unsigned offset, int value)
+{
+	struct smp2p_chip_dev *chip;
+
+	if (!cp)
+		return -ENODEV;
+
+	chip = container_of(cp, struct smp2p_chip_dev, gpio);
+	if (chip->is_inbound)
+		return -EPERM;
+
+	return 0;
+}
+
+/**
+ * smp2p_gpio_to_irq - Convert GPIO pin to virtual IRQ pin.
+ *
+ * @cp:      GPIO chip pointer
+ * @offset:  Pin offset
+ * @returns: >0 for virtual irq value; < 0 for failure
+ */
+static int smp2p_gpio_to_irq(struct gpio_chip *cp, unsigned offset)
+{
+	struct smp2p_chip_dev *chip;
+
+	chip = container_of(cp, struct smp2p_chip_dev, gpio);
+	if (!cp || chip->irq_base <= 0)
+		return -ENODEV;
+
+	return chip->irq_base + offset;
+}
+
+/**
+ * smp2p_gpio_irq_mask_helper - Mask/Unmask interrupt.
+ *
+ * @d:    IRQ data
+ * @mask: true to mask (disable), false to unmask (enable)
+ */
+static void smp2p_gpio_irq_mask_helper(struct irq_data *d, bool mask)
+{
+	struct smp2p_chip_dev *chip;
+	int offset;
+	unsigned long flags;
+
+	chip = (struct smp2p_chip_dev *)irq_get_chip_data(d->irq);
+	if (!chip || chip->irq_base <= 0)
+		return;
+
+	offset = d->irq - chip->irq_base;
+	spin_lock_irqsave(&chip->irq_lock, flags);
+	if (mask)
+		clear_bit(offset, chip->irq_enabled);
+	else
+		set_bit(offset, chip->irq_enabled);
+	spin_unlock_irqrestore(&chip->irq_lock, flags);
+}
+
+/**
+ * smp2p_gpio_irq_mask - Mask interrupt.
+ *
+ * @d: IRQ data
+ */
+static void smp2p_gpio_irq_mask(struct irq_data *d)
+{
+	smp2p_gpio_irq_mask_helper(d, true);
+}
+
+/**
+ * smp2p_gpio_irq_unmask - Unmask interrupt.
+ *
+ * @d: IRQ data
+ */
+static void smp2p_gpio_irq_unmask(struct irq_data *d)
+{
+	smp2p_gpio_irq_mask_helper(d, false);
+}
+
+/**
+ * smp2p_gpio_irq_set_type - Set interrupt edge type.
+ *
+ * @d:      IRQ data
+ * @type:   Edge type for interrupt
+ * @returns 0 for success; < 0 for failure
+ */
+static int smp2p_gpio_irq_set_type(struct irq_data *d, unsigned int type)
+{
+	struct smp2p_chip_dev *chip;
+	int offset;
+	unsigned long flags;
+	int ret = 0;
+
+	chip = (struct smp2p_chip_dev *)irq_get_chip_data(d->irq);
+	if (!chip)
+		return -ENODEV;
+
+	if (chip->irq_base <= 0) {
+		SMP2P_ERR("%s: '%s':%d virqbase %d invalid\n",
+			__func__, chip->name, chip->remote_pid,
+			chip->irq_base);
+		return -ENODEV;
+	}
+
+	offset = d->irq - chip->irq_base;
+
+	spin_lock_irqsave(&chip->irq_lock, flags);
+	clear_bit(offset, chip->irq_rising_edge);
+	clear_bit(offset, chip->irq_falling_edge);
+	switch (type) {
+	case IRQ_TYPE_EDGE_RISING:
+		set_bit(offset, chip->irq_rising_edge);
+		break;
+
+	case IRQ_TYPE_EDGE_FALLING:
+		set_bit(offset, chip->irq_falling_edge);
+		break;
+
+	case IRQ_TYPE_NONE:
+	case IRQ_TYPE_DEFAULT:
+	case IRQ_TYPE_EDGE_BOTH:
+		set_bit(offset, chip->irq_rising_edge);
+		set_bit(offset, chip->irq_falling_edge);
+		break;
+
+	default:
+		SMP2P_ERR("%s: unsupported interrupt type 0x%x\n",
+				__func__, type);
+		ret = -EINVAL;
+		break;
+	}
+	spin_unlock_irqrestore(&chip->irq_lock, flags);
+	return ret;
+}
+
+/**
+ * smp2p_irq_map - Creates or updates binding of virtual IRQ
+ *
+ * @domain_ptr: Interrupt domain pointer
+ * @virq:       Virtual IRQ
+ * @hw:         Hardware IRQ (same as virq for nomap)
+ * @returns:    0 for success
+ */
+static int smp2p_irq_map(struct irq_domain *domain_ptr, unsigned int virq,
+	irq_hw_number_t hw)
+{
+	struct smp2p_chip_dev *chip;
+
+	chip = domain_ptr->host_data;
+	if (!chip) {
+		SMP2P_ERR("%s: invalid domain ptr %p\n", __func__, domain_ptr);
+		return -ENODEV;
+	}
+
+	/* map chip structures to device */
+	irq_set_lockdep_class(virq, &smp2p_gpio_lock_class);
+	irq_set_chip_and_handler(virq, &smp2p_gpio_irq_chip,
+				 handle_level_irq);
+	irq_set_chip_data(virq, chip);
+	set_irq_flags(virq, IRQF_VALID);
+
+	return 0;
+}
+
+static struct irq_chip smp2p_gpio_irq_chip = {
+	.name = "smp2p_gpio",
+	.irq_mask = smp2p_gpio_irq_mask,
+	.irq_unmask = smp2p_gpio_irq_unmask,
+	.irq_set_type = smp2p_gpio_irq_set_type,
+};
+
+/* No-map interrupt Domain */
+static const struct irq_domain_ops smp2p_irq_domain_ops = {
+	.map = smp2p_irq_map,
+};
+
+/**
+ * msm_summary_irq_handler - Handles inbound entry change notification.
+ *
+ * @chip:  GPIO chip pointer
+ * @entry: Change notification data
+ *
+ * Whenever an entry changes, this callback is triggered to determine
+ * which bits changed and if the corresponding interrupts need to be
+ * triggered.
+ */
+static void msm_summary_irq_handler(struct smp2p_chip_dev *chip,
+	struct msm_smp2p_update_notif *entry)
+{
+	int i;
+	uint32_t cur_val;
+	uint32_t prev_val;
+	uint32_t edge;
+	unsigned long flags;
+	bool trigger_interrrupt;
+	bool irq_rising;
+	bool irq_falling;
+
+	cur_val = entry->current_value;
+	prev_val = entry->previous_value;
+
+	if (chip->irq_base <= 0)
+		return;
+
+	SMP2P_GPIO("'%s':%d GPIO Summary IRQ Change %08x->%08x\n",
+			chip->name, chip->remote_pid, prev_val, cur_val);
+
+	for (i = 0; i < SMP2P_BITS_PER_ENTRY; ++i) {
+		spin_lock_irqsave(&chip->irq_lock, flags);
+		trigger_interrrupt = false;
+		edge = (prev_val & 0x1) << 1 | (cur_val & 0x1);
+		irq_rising = test_bit(i, chip->irq_rising_edge);
+		irq_falling = test_bit(i, chip->irq_falling_edge);
+
+		if (test_bit(i, chip->irq_enabled)) {
+			if (edge == 0x1 && irq_rising)
+				/* 0->1 transition */
+				trigger_interrrupt = true;
+			else if (edge == 0x2 && irq_falling)
+				/* 1->0 transition */
+				trigger_interrrupt = true;
+		} else {
+			SMP2P_GPIO(
+				"'%s':%d GPIO bit %d virq %d (%s,%s) - edge %s disabled\n",
+				chip->name, chip->remote_pid, i,
+				chip->irq_base + i,
+				edge_name_rising[irq_rising],
+				edge_name_falling[irq_falling],
+				edge_names[edge]);
+		}
+		spin_unlock_irqrestore(&chip->irq_lock, flags);
+
+		if (trigger_interrrupt) {
+			SMP2P_GPIO(
+				"'%s':%d GPIO bit %d virq %d (%s,%s) - edge %s triggering\n",
+				chip->name, chip->remote_pid, i,
+				chip->irq_base + i,
+				edge_name_rising[irq_rising],
+				edge_name_falling[irq_falling],
+				edge_names[edge]);
+			(void)generic_handle_irq(chip->irq_base + i);
+		}
+
+		cur_val >>= 1;
+		prev_val >>= 1;
+	}
+}
+
+/**
+ * Adds an interrupt domain based upon the DT node.
+ *
+ * @chip: pointer to GPIO chip
+ * @node: pointer to Device Tree node
+ */
+static void smp2p_add_irq_domain(struct smp2p_chip_dev *chip,
+	struct device_node *node)
+{
+	int i;
+
+	/* map GPIO pins to interrupts */
+	chip->irq_domain = irq_domain_add_nomap(node, 0,
+			&smp2p_irq_domain_ops, chip);
+	if (!chip->irq_domain) {
+		SMP2P_ERR("%s: unable to create interrupt domain '%s':%d\n",
+				__func__, chip->name, chip->remote_pid);
+		return;
+	}
+
+	for (i = 0; i < SMP2P_BITS_PER_ENTRY; ++i) {
+		unsigned int virt_irq;
+
+		virt_irq = irq_create_direct_mapping(chip->irq_domain);
+		if (virt_irq == NO_IRQ) {
+			SMP2P_ERR("%s: gpio->virt IRQ mapping failed '%s':%d\n",
+					__func__, chip->name, chip->remote_pid);
+		} else if (!chip->irq_base) {
+			chip->irq_base = virt_irq;
+		}
+	}
+}
+
+/**
+ * Notifier function passed into smp2p API for out bound entries.
+ *
+ * @self:       Pointer to calling notifier block
+ * @event:	    Event
+ * @data:       Event-specific data
+ * @returns:    0
+ */
+static int smp2p_gpio_out_notify(struct notifier_block *self,
+		unsigned long event, void *data)
+{
+	struct smp2p_chip_dev *chip;
+
+	chip = container_of(self, struct smp2p_chip_dev, out_notifier);
+
+	switch (event) {
+	case SMP2P_OPEN:
+		chip->is_open = 1;
+		SMP2P_GPIO("%s: Opened out '%s':%d\n", __func__,
+				chip->name, chip->remote_pid);
+		break;
+	case SMP2P_ENTRY_UPDATE:
+		break;
+	default:
+		SMP2P_ERR("%s: Unknown event\n", __func__);
+		break;
+	}
+	return 0;
+}
+
+/**
+ * Notifier function passed into smp2p API for in bound entries.
+ *
+ * @self:       Pointer to calling notifier block
+ * @event:	    Event
+ * @data:       Event-specific data
+ * @returns:    0
+ */
+static int smp2p_gpio_in_notify(struct notifier_block *self,
+		unsigned long event, void *data)
+{
+	struct smp2p_chip_dev *chip;
+
+	chip = container_of(self, struct smp2p_chip_dev, in_notifier);
+
+	switch (event) {
+	case SMP2P_OPEN:
+		chip->is_open = 1;
+		SMP2P_GPIO("%s: Opened in '%s':%d\n", __func__,
+				chip->name, chip->remote_pid);
+		break;
+	case SMP2P_ENTRY_UPDATE:
+		msm_summary_irq_handler(chip, data);
+		break;
+	default:
+		SMP2P_ERR("%s: Unknown event\n", __func__);
+		break;
+	}
+	return 0;
+}
+
+/**
+ * Device tree probe function.
+ *
+ * @pdev:	 Pointer to device tree data.
+ * @returns: 0 on success; -ENODEV otherwise
+ *
+ * Called for each smp2pgpio entry in the device tree.
+ */
+static int __devinit smp2p_gpio_probe(struct platform_device *pdev)
+{
+	struct device_node *node;
+	char *key;
+	struct smp2p_chip_dev *chip;
+	const char *name_tmp;
+	unsigned long flags;
+	bool is_test_entry = false;
+	int ret;
+
+	chip = kzalloc(sizeof(struct smp2p_chip_dev), GFP_KERNEL);
+	if (!chip) {
+		SMP2P_ERR("%s: out of memory\n", __func__);
+		ret = -ENOMEM;
+		goto fail;
+	}
+	spin_lock_init(&chip->irq_lock);
+
+	/* parse device tree */
+	node = pdev->dev.of_node;
+	key = "qcom,entry-name";
+	ret = of_property_read_string(node, key, &name_tmp);
+	if (ret) {
+		SMP2P_ERR("%s: missing DT key '%s'\n", __func__, key);
+		goto fail;
+	}
+	strlcpy(chip->name, name_tmp, sizeof(chip->name));
+
+	key = "qcom,remote-pid";
+	ret = of_property_read_u32(node, key, &chip->remote_pid);
+	if (ret) {
+		SMP2P_ERR("%s: missing DT key '%s'\n", __func__, key);
+		goto fail;
+	}
+
+	key = "qcom,is-inbound";
+	chip->is_inbound = of_property_read_bool(node, key);
+
+	/* create virtual GPIO controller */
+	chip->gpio.label = chip->name;
+	chip->gpio.dev = &pdev->dev;
+	chip->gpio.owner = THIS_MODULE;
+	chip->gpio.direction_input	= smp2p_direction_input,
+	chip->gpio.get = smp2p_get_value;
+	chip->gpio.direction_output = smp2p_direction_output,
+	chip->gpio.set = smp2p_set_value;
+	chip->gpio.to_irq = smp2p_gpio_to_irq,
+	chip->gpio.base = -1;	/* use dynamic GPIO pin allocation */
+	chip->gpio.ngpio = SMP2P_BITS_PER_ENTRY;
+	ret = gpiochip_add(&chip->gpio);
+	if (ret) {
+		SMP2P_ERR("%s: unable to register GPIO '%s' ret %d\n",
+				__func__, chip->name, ret);
+		goto fail;
+	}
+
+	/*
+	 * Test entries opened by GPIO Test conflict with loopback
+	 * support, so the test entries must be explicitly opened
+	 * in the unit test framework.
+	 */
+	if (strncmp("smp2p", chip->name, SMP2P_MAX_ENTRY_NAME) == 0)
+		is_test_entry = true;
+
+	if (!chip->is_inbound)	{
+		chip->out_notifier.notifier_call = smp2p_gpio_out_notify;
+		if (!is_test_entry) {
+			ret = msm_smp2p_out_open(chip->remote_pid, chip->name,
+					   &chip->out_notifier,
+					   &chip->out_handle);
+			if (ret < 0)
+				goto fail;
+		}
+	} else {
+		chip->in_notifier.notifier_call = smp2p_gpio_in_notify;
+		if (!is_test_entry) {
+			ret = msm_smp2p_in_register(chip->remote_pid,
+					chip->name,
+					&chip->in_notifier);
+			if (ret < 0)
+				goto fail;
+		}
+	}
+
+	spin_lock_irqsave(&smp2p_entry_lock_lha1, flags);
+	list_add(&chip->entry_list, &smp2p_entry_list);
+	spin_unlock_irqrestore(&smp2p_entry_lock_lha1, flags);
+
+	/*
+	 * Create interrupt domain - note that chip can't be removed from the
+	 * interrupt domain, so chip cannot be deleted after this point.
+	 */
+	if (chip->is_inbound)
+		smp2p_add_irq_domain(chip, node);
+	else
+		chip->irq_base = -1;
+
+	SMP2P_GPIO("%s: added %s%s entry '%s':%d gpio %d irq %d",
+			__func__,
+			is_test_entry ? "test " : "",
+			chip->is_inbound ? "in" : "out",
+			chip->name, chip->remote_pid,
+			chip->gpio.base, chip->irq_base);
+
+	return 0;
+
+fail:
+	kfree(chip);
+	return ret;
+}
+
+/**
+ * smp2p_gpio_open_close - Opens or closes entry.
+ *
+ * @entry:   Entry to open or close
+ * @do_open: true = open port; false = close
+ */
+static void smp2p_gpio_open_close(struct smp2p_chip_dev *entry,
+	bool do_open)
+{
+	int ret;
+
+	if (do_open) {
+		/* open entry */
+		if (entry->is_inbound)
+			ret = msm_smp2p_in_register(entry->remote_pid,
+					entry->name, &entry->in_notifier);
+		else
+			ret = msm_smp2p_out_open(entry->remote_pid,
+					entry->name, &entry->out_notifier,
+					&entry->out_handle);
+		SMP2P_GPIO("%s: opened %s '%s':%d ret %d\n",
+				__func__,
+				entry->is_inbound ? "in" : "out",
+				entry->name, entry->remote_pid,
+				ret);
+	} else {
+		/* close entry */
+		if (entry->is_inbound)
+			ret = msm_smp2p_in_unregister(entry->remote_pid,
+					entry->name, &entry->in_notifier);
+		else
+			ret = msm_smp2p_out_close(&entry->out_handle);
+		entry->is_open = false;
+		SMP2P_GPIO("%s: closed %s '%s':%d ret %d\n",
+				__func__,
+				entry->is_inbound ? "in" : "out",
+				entry->name, entry->remote_pid, ret);
+	}
+}
+
+/**
+ * smp2p_gpio_open_test_entry - Opens or closes test entries for unit testing.
+ *
+ * @name:       Name of the entry
+ * @remote_pid: Remote processor ID
+ * @do_open:    true = open port; false = close
+ */
+void smp2p_gpio_open_test_entry(const char *name, int remote_pid, bool do_open)
+{
+	struct smp2p_chip_dev *entry;
+	struct smp2p_chip_dev *start_entry;
+	unsigned long flags;
+
+	spin_lock_irqsave(&smp2p_entry_lock_lha1, flags);
+	if (list_empty(&smp2p_entry_list)) {
+		spin_unlock_irqrestore(&smp2p_entry_lock_lha1, flags);
+		return;
+	}
+	start_entry = list_first_entry(&smp2p_entry_list,
+					struct smp2p_chip_dev,
+					entry_list);
+	entry = start_entry;
+	do {
+		if (!strncmp(entry->name, name, SMP2P_MAX_ENTRY_NAME)
+				&& entry->remote_pid == remote_pid) {
+			/* found entry to change */
+			spin_unlock_irqrestore(&smp2p_entry_lock_lha1, flags);
+			smp2p_gpio_open_close(entry, do_open);
+			spin_lock_irqsave(&smp2p_entry_lock_lha1, flags);
+		}
+		list_rotate_left(&smp2p_entry_list);
+		entry = list_first_entry(&smp2p_entry_list,
+						struct smp2p_chip_dev,
+						entry_list);
+	} while (entry != start_entry);
+	spin_unlock_irqrestore(&smp2p_entry_lock_lha1, flags);
+}
+
+static struct of_device_id msm_smp2p_match_table[] __devinitdata = {
+	{.compatible = "qcom,smp2pgpio", },
+	{},
+};
+
+static struct platform_driver smp2p_gpio_driver = {
+	.probe = smp2p_gpio_probe,
+	.driver = {
+		.name = "smp2pgpio",
+		.owner = THIS_MODULE,
+		.of_match_table = msm_smp2p_match_table,
+	},
+};
+
+static int __devinit smp2p_init(void)
+{
+	INIT_LIST_HEAD(&smp2p_entry_list);
+	return platform_driver_register(&smp2p_gpio_driver);
+}
+module_init(smp2p_init);
+
+static void __exit smp2p_exit(void)
+{
+	platform_driver_unregister(&smp2p_gpio_driver);
+}
+module_exit(smp2p_exit);
+
+MODULE_DESCRIPTION("SMP2P GPIO");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/smp2p_gpio_test.c b/arch/arm/mach-msm/smp2p_gpio_test.c
new file mode 100644
index 0000000..1f6f479
--- /dev/null
+++ b/arch/arm/mach-msm/smp2p_gpio_test.c
@@ -0,0 +1,735 @@
+/* arch/arm/mach-msm/smp2p_gpio_test.c
+ *
+ * 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/platform_device.h>
+#include <linux/of_gpio.h>
+#include <linux/of_irq.h>
+#include <linux/gpio.h>
+#include <linux/debugfs.h>
+#include <linux/completion.h>
+#include <linux/irq.h>
+#include <linux/bitmap.h>
+#include "smp2p_private.h"
+#include "smp2p_test_common.h"
+
+/* Interrupt callback data */
+struct gpio_info {
+	int gpio_base_id;
+	int irq_base_id;
+
+	bool initialized;
+	struct completion cb_completion;
+	int cb_count;
+	DECLARE_BITMAP(triggered_irqs, SMP2P_BITS_PER_ENTRY);
+};
+
+/* GPIO Inbound/Outbound callback info */
+struct gpio_inout {
+	struct gpio_info in;
+	struct gpio_info out;
+};
+
+static struct gpio_inout gpio_info[SMP2P_NUM_PROCS];
+
+/**
+ * Init/reset the callback data.
+ *
+ * @info: Pointer to callback data
+ */
+static void cb_data_reset(struct gpio_info *info)
+{
+	int n;
+
+	if (!info)
+		return;
+
+	if (!info->initialized) {
+		init_completion(&info->cb_completion);
+		info->initialized = true;
+	}
+	info->cb_count = 0;
+
+	for (n = 0; n < SMP2P_BITS_PER_ENTRY; ++n)
+		clear_bit(n,  info->triggered_irqs);
+
+	INIT_COMPLETION(info->cb_completion);
+}
+
+static int __devinit smp2p_gpio_test_probe(struct platform_device *pdev)
+{
+	int id;
+	int cnt;
+	struct device_node *node = pdev->dev.of_node;
+	struct gpio_info *gpio_info_ptr = NULL;
+
+	/*
+	 * NOTE:  This does a string-lookup of the GPIO pin name and doesn't
+	 * actually directly link to the SMP2P GPIO driver since all
+	 * GPIO/Interrupt access must be through standard
+	 * Linux GPIO / Interrupt APIs.
+	 */
+	if (strcmp("qcom,smp2pgpio_test_smp2p_1_in", node->name) == 0) {
+		gpio_info_ptr = &gpio_info[SMP2P_MODEM_PROC].in;
+	} else if (strcmp("qcom,smp2pgpio_test_smp2p_1_out", node->name) == 0) {
+		gpio_info_ptr = &gpio_info[SMP2P_MODEM_PROC].out;
+	} else if (strcmp("qcom,smp2pgpio_test_smp2p_2_in", node->name) == 0) {
+		gpio_info_ptr = &gpio_info[SMP2P_AUDIO_PROC].in;
+	} else if (strcmp("qcom,smp2pgpio_test_smp2p_2_out", node->name) == 0) {
+		gpio_info_ptr = &gpio_info[SMP2P_AUDIO_PROC].out;
+	} else if (strcmp("qcom,smp2pgpio_test_smp2p_4_in", node->name) == 0) {
+		gpio_info_ptr = &gpio_info[SMP2P_WIRELESS_PROC].in;
+	} else if (strcmp("qcom,smp2pgpio_test_smp2p_4_out", node->name) == 0) {
+		gpio_info_ptr = &gpio_info[SMP2P_WIRELESS_PROC].out;
+	} else if (strcmp("qcom,smp2pgpio_test_smp2p_7_in", node->name) == 0) {
+		gpio_info_ptr = &gpio_info[SMP2P_REMOTE_MOCK_PROC].in;
+	} else if (strcmp("qcom,smp2pgpio_test_smp2p_7_out", node->name) == 0) {
+		gpio_info_ptr = &gpio_info[SMP2P_REMOTE_MOCK_PROC].out;
+	} else {
+		pr_err("%s: unable to match device type '%s'\n",
+				__func__, node->name);
+		return -ENODEV;
+	}
+
+	/* retrieve the GPIO and interrupt ID's */
+	cnt = of_gpio_count(node);
+	if (cnt && gpio_info_ptr) {
+		/*
+		 * Instead of looping through all 32-bits, we can just get the
+		 * first pin to get the base IDs.  This saves on the verbosity
+		 * of the device tree nodes as well.
+		 */
+		id = of_get_gpio(node, 0);
+		gpio_info_ptr->gpio_base_id = id;
+		gpio_info_ptr->irq_base_id = gpio_to_irq(id);
+	}
+	return 0;
+}
+
+/*
+ * NOTE:  Instead of match table and device driver, you may be able to just
+ * call of_find_compatible_node() in your init function.
+ */
+static struct of_device_id msm_smp2p_match_table[] __devinitdata = {
+	/* modem */
+	{.compatible = "qcom,smp2pgpio_test_smp2p_1_out", },
+	{.compatible = "qcom,smp2pgpio_test_smp2p_1_in", },
+
+	/* audio (adsp) */
+	{.compatible = "qcom,smp2pgpio_test_smp2p_2_out", },
+	{.compatible = "qcom,smp2pgpio_test_smp2p_2_in", },
+
+	/* wcnss */
+	{.compatible = "qcom,smp2pgpio_test_smp2p_4_out", },
+	{.compatible = "qcom,smp2pgpio_test_smp2p_4_in", },
+
+	/* mock loopback */
+	{.compatible = "qcom,smp2pgpio_test_smp2p_7_out", },
+	{.compatible = "qcom,smp2pgpio_test_smp2p_7_in", },
+	{},
+};
+
+static struct platform_driver smp2p_gpio_driver = {
+	.probe = smp2p_gpio_test_probe,
+	.driver = {
+		.name = "smp2pgpio_test",
+		.owner = THIS_MODULE,
+		.of_match_table = msm_smp2p_match_table,
+	},
+};
+
+/**
+ * smp2p_ut_local_gpio_out - Verify outbound functionality.
+ *
+ * @s:   pointer to output file
+ */
+static void smp2p_ut_local_gpio_out(struct seq_file *s)
+{
+	int failed = 0;
+	struct gpio_info *cb_info = &gpio_info[SMP2P_REMOTE_MOCK_PROC].out;
+	int ret;
+	int id;
+	struct msm_smp2p_remote_mock *mock;
+
+	seq_printf(s, "Running %s\n", __func__);
+	do {
+		/* initialize mock edge */
+		ret = smp2p_reset_mock_edge();
+		UT_ASSERT_INT(ret, ==, 0);
+
+		mock = msm_smp2p_get_remote_mock();
+		UT_ASSERT_PTR(mock, !=, NULL);
+
+		mock->rx_interrupt_count = 0;
+		memset(&mock->remote_item, 0,
+			sizeof(struct smp2p_smem_item));
+		smp2p_init_header((struct smp2p_smem *)&mock->remote_item,
+			SMP2P_REMOTE_MOCK_PROC, SMP2P_APPS_PROC,
+			0, 1);
+		strlcpy(mock->remote_item.entries[0].name, "smp2p",
+			SMP2P_MAX_ENTRY_NAME);
+		SMP2P_SET_ENT_VALID(
+			mock->remote_item.header.valid_total_ent, 1);
+		msm_smp2p_set_remote_mock_exists(true);
+		mock->tx_interrupt();
+
+		/* open GPIO entry */
+		smp2p_gpio_open_test_entry("smp2p",
+				SMP2P_REMOTE_MOCK_PROC, true);
+
+		/* verify set/get functions */
+		UT_ASSERT_INT(0, <, cb_info->gpio_base_id);
+		for (id = 0; id < SMP2P_BITS_PER_ENTRY && !failed; ++id) {
+			int pin = cb_info->gpio_base_id + id;
+
+			mock->rx_interrupt_count = 0;
+			gpio_set_value(pin, 1);
+			UT_ASSERT_INT(1, ==, mock->rx_interrupt_count);
+			UT_ASSERT_INT(1, ==, gpio_get_value(pin));
+
+			gpio_set_value(pin, 0);
+			UT_ASSERT_INT(2, ==, mock->rx_interrupt_count);
+			UT_ASSERT_INT(0, ==, gpio_get_value(pin));
+		}
+		if (failed)
+			break;
+
+		seq_printf(s, "\tOK\n");
+	} while (0);
+
+	if (failed) {
+		pr_err("%s: Failed\n", __func__);
+		seq_printf(s, "\tFailed\n");
+	}
+
+	smp2p_gpio_open_test_entry("smp2p",
+			SMP2P_REMOTE_MOCK_PROC, false);
+}
+
+/**
+ * smp2p_gpio_irq - Interrupt handler for inbound entries.
+ *
+ * @irq:         Virtual IRQ being triggered
+ * @data:        Cookie data (struct gpio_info * in this case)
+ * @returns:     Number of bytes written
+ */
+static irqreturn_t smp2p_gpio_irq(int irq, void *data)
+{
+	struct gpio_info *gpio_ptr = (struct gpio_info *)data;
+	int offset;
+
+	if (!gpio_ptr) {
+		pr_err("%s: gpio_ptr is NULL for irq %d\n", __func__, irq);
+		return IRQ_HANDLED;
+	}
+
+	offset = irq - gpio_ptr->irq_base_id;
+	if (offset >= 0 &&  offset < SMP2P_BITS_PER_ENTRY)
+		set_bit(offset, gpio_ptr->triggered_irqs);
+	else
+		pr_err("%s: invalid irq offset base %d; irq %d\n",
+			__func__, gpio_ptr->irq_base_id, irq);
+
+	++gpio_ptr->cb_count;
+	complete(&gpio_ptr->cb_completion);
+	return IRQ_HANDLED;
+}
+
+/**
+ * smp2p_ut_local_gpio_in - Verify inbound functionality.
+ *
+ * @s:   pointer to output file
+ */
+static void smp2p_ut_local_gpio_in(struct seq_file *s)
+{
+	int failed = 0;
+	struct gpio_info *cb_info = &gpio_info[SMP2P_REMOTE_MOCK_PROC].in;
+	int id;
+	int ret;
+	int virq;
+	struct msm_smp2p_remote_mock *mock;
+
+	seq_printf(s, "Running %s\n", __func__);
+
+	cb_data_reset(cb_info);
+	do {
+		/* initialize mock edge */
+		ret = smp2p_reset_mock_edge();
+		UT_ASSERT_INT(ret, ==, 0);
+
+		mock = msm_smp2p_get_remote_mock();
+		UT_ASSERT_PTR(mock, !=, NULL);
+
+		mock->rx_interrupt_count = 0;
+		memset(&mock->remote_item, 0,
+			sizeof(struct smp2p_smem_item));
+		smp2p_init_header((struct smp2p_smem *)&mock->remote_item,
+			SMP2P_REMOTE_MOCK_PROC, SMP2P_APPS_PROC,
+			0, 1);
+		strlcpy(mock->remote_item.entries[0].name, "smp2p",
+			SMP2P_MAX_ENTRY_NAME);
+		SMP2P_SET_ENT_VALID(
+			mock->remote_item.header.valid_total_ent, 1);
+		msm_smp2p_set_remote_mock_exists(true);
+		mock->tx_interrupt();
+
+		smp2p_gpio_open_test_entry("smp2p",
+				SMP2P_REMOTE_MOCK_PROC, true);
+
+		/* verify set/get functions locally */
+		UT_ASSERT_INT(0, <, cb_info->gpio_base_id);
+		for (id = 0; id < SMP2P_BITS_PER_ENTRY && !failed; ++id) {
+			int pin;
+			int current_value;
+
+			/* verify pin value cannot be set */
+			pin = cb_info->gpio_base_id + id;
+			current_value = gpio_get_value(pin);
+
+			gpio_set_value(pin, 0);
+			UT_ASSERT_INT(current_value, ==, gpio_get_value(pin));
+			gpio_set_value(pin, 1);
+			UT_ASSERT_INT(current_value, ==, gpio_get_value(pin));
+
+			/* verify no interrupts */
+			UT_ASSERT_INT(0, ==, cb_info->cb_count);
+		}
+		if (failed)
+			break;
+
+		/* register for interrupts */
+		UT_ASSERT_INT(0, <, cb_info->irq_base_id);
+		for (id = 0; id < SMP2P_BITS_PER_ENTRY && !failed; ++id) {
+			virq = cb_info->irq_base_id + id;
+			UT_ASSERT_INT(0, >, (unsigned int)irq_to_desc(virq));
+			ret = request_irq(virq,
+					smp2p_gpio_irq,	IRQF_TRIGGER_RISING,
+					"smp2p_test", cb_info);
+			UT_ASSERT_INT(0, ==, ret);
+		}
+		if (failed)
+			break;
+
+		/* verify both rising and falling edge interrupts */
+		for (id = 0; id < SMP2P_BITS_PER_ENTRY && !failed; ++id) {
+			virq = cb_info->irq_base_id + id;
+			irq_set_irq_type(virq, IRQ_TYPE_EDGE_BOTH);
+			cb_data_reset(cb_info);
+
+			/* verify rising-edge interrupt */
+			mock->remote_item.entries[0].entry = 1 << id;
+			mock->tx_interrupt();
+			UT_ASSERT_INT(cb_info->cb_count, ==, 1);
+			UT_ASSERT_INT(0, <,
+				test_bit(id, cb_info->triggered_irqs));
+			test_bit(id, cb_info->triggered_irqs);
+
+			/* verify falling-edge interrupt */
+			mock->remote_item.entries[0].entry = 0;
+			mock->tx_interrupt();
+			UT_ASSERT_INT(cb_info->cb_count, ==, 2);
+			UT_ASSERT_INT(0, <,
+					test_bit(id, cb_info->triggered_irqs));
+		}
+		if (failed)
+			break;
+
+		/* verify rising-edge interrupts */
+		for (id = 0; id < SMP2P_BITS_PER_ENTRY && !failed; ++id) {
+			virq = cb_info->irq_base_id + id;
+			irq_set_irq_type(virq, IRQ_TYPE_EDGE_RISING);
+			cb_data_reset(cb_info);
+
+			/* verify only rising-edge interrupt is triggered */
+			mock->remote_item.entries[0].entry = 1 << id;
+			mock->tx_interrupt();
+			UT_ASSERT_INT(cb_info->cb_count, ==, 1);
+			UT_ASSERT_INT(0, <,
+				test_bit(id, cb_info->triggered_irqs));
+			test_bit(id, cb_info->triggered_irqs);
+
+			mock->remote_item.entries[0].entry = 0;
+			mock->tx_interrupt();
+			UT_ASSERT_INT(cb_info->cb_count, ==, 1);
+			UT_ASSERT_INT(0, <,
+				test_bit(id, cb_info->triggered_irqs));
+		}
+		if (failed)
+			break;
+
+		/* verify falling-edge interrupts */
+		for (id = 0; id < SMP2P_BITS_PER_ENTRY && !failed; ++id) {
+			virq = cb_info->irq_base_id + id;
+			irq_set_irq_type(virq, IRQ_TYPE_EDGE_FALLING);
+			cb_data_reset(cb_info);
+
+			/* verify only rising-edge interrupt is triggered */
+			mock->remote_item.entries[0].entry = 1 << id;
+			mock->tx_interrupt();
+			UT_ASSERT_INT(cb_info->cb_count, ==, 0);
+			UT_ASSERT_INT(0, ==,
+				test_bit(id, cb_info->triggered_irqs));
+
+			mock->remote_item.entries[0].entry = 0;
+			mock->tx_interrupt();
+			UT_ASSERT_INT(cb_info->cb_count, ==, 1);
+			UT_ASSERT_INT(0, <,
+				test_bit(id, cb_info->triggered_irqs));
+		}
+		if (failed)
+			break;
+
+		seq_printf(s, "\tOK\n");
+	} while (0);
+
+	if (failed) {
+		pr_err("%s: Failed\n", __func__);
+		seq_printf(s, "\tFailed\n");
+	}
+
+	/* unregister for interrupts */
+	if (cb_info->irq_base_id) {
+		for (id = 0; id < SMP2P_BITS_PER_ENTRY; ++id)
+			free_irq(cb_info->irq_base_id + id, cb_info);
+	}
+
+	smp2p_gpio_open_test_entry("smp2p",
+			SMP2P_REMOTE_MOCK_PROC, false);
+}
+
+/**
+ * smp2p_ut_local_gpio_in_update_open - Verify combined open/update.
+ *
+ * @s:   pointer to output file
+ *
+ * If the remote side updates the SMP2P bits and sends before negotiation is
+ * complete, then the UPDATE event will have to be delayed until negotiation is
+ * complete.  This should result in both the OPEN and UPDATE events coming in
+ * right after each other and the behavior should be transparent to the clients
+ * of SMP2P GPIO.
+ */
+static void smp2p_ut_local_gpio_in_update_open(struct seq_file *s)
+{
+	int failed = 0;
+	struct gpio_info *cb_info = &gpio_info[SMP2P_REMOTE_MOCK_PROC].in;
+	int id;
+	int ret;
+	int virq;
+	struct msm_smp2p_remote_mock *mock;
+
+	seq_printf(s, "Running %s\n", __func__);
+
+	cb_data_reset(cb_info);
+	do {
+		/* initialize mock edge */
+		ret = smp2p_reset_mock_edge();
+		UT_ASSERT_INT(ret, ==, 0);
+
+		mock = msm_smp2p_get_remote_mock();
+		UT_ASSERT_PTR(mock, !=, NULL);
+
+		mock->rx_interrupt_count = 0;
+		memset(&mock->remote_item, 0,
+			sizeof(struct smp2p_smem_item));
+		smp2p_init_header((struct smp2p_smem *)&mock->remote_item,
+			SMP2P_REMOTE_MOCK_PROC, SMP2P_APPS_PROC,
+			0, 1);
+		strlcpy(mock->remote_item.entries[0].name, "smp2p",
+			SMP2P_MAX_ENTRY_NAME);
+		SMP2P_SET_ENT_VALID(
+			mock->remote_item.header.valid_total_ent, 1);
+
+		/* register for interrupts */
+		smp2p_gpio_open_test_entry("smp2p",
+				SMP2P_REMOTE_MOCK_PROC, true);
+
+		UT_ASSERT_INT(0, <, cb_info->irq_base_id);
+		for (id = 0; id < SMP2P_BITS_PER_ENTRY && !failed; ++id) {
+			virq = cb_info->irq_base_id + id;
+			UT_ASSERT_INT(0, >, (unsigned int)irq_to_desc(virq));
+			ret = request_irq(virq,
+					smp2p_gpio_irq,	IRQ_TYPE_EDGE_BOTH,
+					"smp2p_test", cb_info);
+			UT_ASSERT_INT(0, ==, ret);
+		}
+		if (failed)
+			break;
+
+		/* update the state value and complete negotiation */
+		mock->remote_item.entries[0].entry = 0xDEADDEAD;
+		msm_smp2p_set_remote_mock_exists(true);
+		mock->tx_interrupt();
+
+		/* verify delayed state updates were processed */
+		for (id = 0; id < SMP2P_BITS_PER_ENTRY && !failed; ++id) {
+			virq = cb_info->irq_base_id + id;
+
+			UT_ASSERT_INT(cb_info->cb_count, >, 0);
+			if (0x1 & (0xDEADDEAD >> id)) {
+				/* rising edge should have been triggered */
+				if (!test_bit(id, cb_info->triggered_irqs)) {
+					seq_printf(s,
+						"%s:%d bit %d clear, expected set\n",
+						__func__, __LINE__, id);
+					failed = 1;
+					break;
+				}
+			} else {
+				/* edge should not have been triggered */
+				if (test_bit(id, cb_info->triggered_irqs)) {
+					seq_printf(s,
+						"%s:%d bit %d set, expected clear\n",
+						__func__, __LINE__, id);
+					failed = 1;
+					break;
+				}
+			}
+		}
+		if (failed)
+			break;
+
+		seq_printf(s, "\tOK\n");
+	} while (0);
+
+	if (failed) {
+		pr_err("%s: Failed\n", __func__);
+		seq_printf(s, "\tFailed\n");
+	}
+
+	/* unregister for interrupts */
+	if (cb_info->irq_base_id) {
+		for (id = 0; id < SMP2P_BITS_PER_ENTRY; ++id)
+			free_irq(cb_info->irq_base_id + id, cb_info);
+	}
+
+	smp2p_gpio_open_test_entry("smp2p",
+			SMP2P_REMOTE_MOCK_PROC, false);
+}
+
+/**
+ * smp2p_gpio_write_bits - writes value to each GPIO pin specified in mask.
+ *
+ * @gpio: gpio test structure
+ * @mask: 1 = write gpio_value to this GPIO pin
+ * @gpio_value: value to write to GPIO pin
+ */
+static void smp2p_gpio_write_bits(struct gpio_info *gpio, uint32_t mask,
+	int gpio_value)
+{
+	int n;
+
+	for (n = 0; n < SMP2P_BITS_PER_ENTRY; ++n) {
+		if (mask & 0x1)
+			gpio_set_value(gpio->gpio_base_id + n, gpio_value);
+		mask >>= 1;
+	}
+}
+
+static void smp2p_gpio_set_bits(struct gpio_info *gpio, uint32_t mask)
+{
+	smp2p_gpio_write_bits(gpio, mask, 1);
+}
+
+static void smp2p_gpio_clr_bits(struct gpio_info *gpio, uint32_t mask)
+{
+	smp2p_gpio_write_bits(gpio, mask, 0);
+}
+
+/**
+ * smp2p_gpio_get_value - reads entire 32-bits of GPIO
+ *
+ * @gpio: gpio structure
+ * @returns: 32 bit value of GPIO pins
+ */
+static uint32_t smp2p_gpio_get_value(struct gpio_info *gpio)
+{
+	int n;
+	uint32_t value = 0;
+
+	for (n = 0; n < SMP2P_BITS_PER_ENTRY; ++n) {
+		if (gpio_get_value(gpio->gpio_base_id + n))
+			value |= 1 << n;
+	}
+	return value;
+}
+
+/**
+ * smp2p_ut_remote_inout_core - Verify inbound/outbound functionality.
+ *
+ * @s:   pointer to output file
+ * @remote_pid:  Remote processor to test
+ * @name:        Name of the test for reporting
+ *
+ * This test verifies inbound/outbound functionality for the remote processor.
+ */
+static void smp2p_ut_remote_inout_core(struct seq_file *s, int remote_pid,
+		const char *name)
+{
+	int failed = 0;
+	uint32_t request;
+	uint32_t response;
+	struct gpio_info *cb_in;
+	struct gpio_info *cb_out;
+	int id;
+	int ret;
+
+	seq_printf(s, "Running %s for '%s' remote pid %d\n",
+		   __func__, smp2p_pid_to_name(remote_pid), remote_pid);
+
+	cb_in = &gpio_info[remote_pid].in;
+	cb_out = &gpio_info[remote_pid].out;
+	cb_data_reset(cb_in);
+	cb_data_reset(cb_out);
+	do {
+		/* open test entries */
+		msm_smp2p_deinit_rmt_lpb_proc(remote_pid);
+		smp2p_gpio_open_test_entry("smp2p", remote_pid, true);
+
+		/* register for interrupts */
+		UT_ASSERT_INT(0, <, cb_in->gpio_base_id);
+		UT_ASSERT_INT(0, <, cb_in->irq_base_id);
+		for (id = 0; id < SMP2P_BITS_PER_ENTRY && !failed; ++id) {
+			int virq = cb_in->irq_base_id + id;
+			UT_ASSERT_INT(0, >, (unsigned int)irq_to_desc(virq));
+			ret = request_irq(virq,
+				smp2p_gpio_irq,
+				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+				"smp2p_test", cb_in);
+			UT_ASSERT_INT(0, ==, ret);
+		}
+		if (failed)
+			break;
+
+		/* write echo of data value 0 */
+		UT_ASSERT_INT(0, <, cb_out->gpio_base_id);
+		request = 0x0;
+		SMP2P_SET_RMT_CMD_TYPE(request, 1);
+		SMP2P_SET_RMT_CMD(request, SMP2P_LB_CMD_ECHO);
+		SMP2P_SET_RMT_DATA(request, 0x0);
+
+		smp2p_gpio_set_bits(cb_out, SMP2P_RMT_IGNORE_MASK);
+		smp2p_gpio_clr_bits(cb_out, ~SMP2P_RMT_IGNORE_MASK);
+		smp2p_gpio_set_bits(cb_out, request);
+
+		UT_ASSERT_INT(cb_in->cb_count, ==, 0);
+		smp2p_gpio_clr_bits(cb_out, SMP2P_RMT_IGNORE_MASK);
+
+		/* verify response */
+		do {
+			/* wait for up to 32 changes */
+			if (wait_for_completion_timeout(
+					&cb_in->cb_completion, HZ / 2) == 0)
+				break;
+			INIT_COMPLETION(cb_in->cb_completion);
+		} while (cb_in->cb_count < 32);
+		UT_ASSERT_INT(cb_in->cb_count, >, 0);
+		response = smp2p_gpio_get_value(cb_in);
+		SMP2P_SET_RMT_CMD_TYPE(request, 0);
+		UT_ASSERT_HEX(request, ==, response);
+
+		/* write echo of data value of all 1's */
+		request = 0x0;
+		SMP2P_SET_RMT_CMD_TYPE(request, 1);
+		SMP2P_SET_RMT_CMD(request, SMP2P_LB_CMD_ECHO);
+		SMP2P_SET_RMT_DATA(request, ~0);
+
+		smp2p_gpio_set_bits(cb_out, SMP2P_RMT_IGNORE_MASK);
+		cb_data_reset(cb_in);
+		smp2p_gpio_clr_bits(cb_out, ~SMP2P_RMT_IGNORE_MASK);
+		smp2p_gpio_set_bits(cb_out, request);
+
+		UT_ASSERT_INT(cb_in->cb_count, ==, 0);
+		smp2p_gpio_clr_bits(cb_out, SMP2P_RMT_IGNORE_MASK);
+
+		/* verify response including 24 interrupts */
+		do {
+			UT_ASSERT_INT(
+				(int)wait_for_completion_timeout(
+					&cb_in->cb_completion, HZ / 2),
+			   >, 0);
+			INIT_COMPLETION(cb_in->cb_completion);
+		} while (cb_in->cb_count < 24);
+		response = smp2p_gpio_get_value(cb_in);
+		SMP2P_SET_RMT_CMD_TYPE(request, 0);
+		UT_ASSERT_HEX(request, ==, response);
+		UT_ASSERT_INT(24, ==, cb_in->cb_count);
+
+		seq_printf(s, "\tOK\n");
+	} while (0);
+
+	if (failed) {
+		pr_err("%s: Failed\n", name);
+		seq_printf(s, "\tFailed\n");
+	}
+
+	/* unregister for interrupts */
+	if (cb_in->irq_base_id) {
+		for (id = 0; id < SMP2P_BITS_PER_ENTRY; ++id)
+			free_irq(cb_in->irq_base_id + id, cb_in);
+	}
+
+	smp2p_gpio_open_test_entry("smp2p",	remote_pid, false);
+	msm_smp2p_init_rmt_lpb_proc(remote_pid);
+}
+
+/**
+ * smp2p_ut_remote_inout - Verify inbound/outbound functionality for all.
+ *
+ * @s:   pointer to output file
+ *
+ * This test verifies inbound and outbound functionality for all
+ * configured remote processor.
+ */
+static void smp2p_ut_remote_inout(struct seq_file *s)
+{
+	struct smp2p_interrupt_config *int_cfg;
+	int pid;
+
+	int_cfg = smp2p_get_interrupt_config();
+	if (!int_cfg) {
+		seq_printf(s, "Remote processor config unavailable\n");
+		return;
+	}
+
+	for (pid = 0; pid < SMP2P_NUM_PROCS; ++pid) {
+		if (!int_cfg[pid].is_configured)
+			continue;
+
+		smp2p_ut_remote_inout_core(s, pid, __func__);
+	}
+}
+
+static int __init smp2p_debugfs_init(void)
+{
+	/* register GPIO pins */
+	(void)platform_driver_register(&smp2p_gpio_driver);
+
+	/*
+	 * Add Unit Test entries.
+	 *
+	 * The idea with unit tests is that you can run all of them
+	 * from ADB shell by doing:
+	 *  adb shell
+	 *  cat ut*
+	 *
+	 * And if particular tests fail, you can then repeatedly run the
+	 * failing tests as you debug and resolve the failing test.
+	 */
+	smp2p_debug_create("ut_local_gpio_out", smp2p_ut_local_gpio_out);
+	smp2p_debug_create("ut_local_gpio_in", smp2p_ut_local_gpio_in);
+	smp2p_debug_create("ut_local_gpio_in_update_open",
+		smp2p_ut_local_gpio_in_update_open);
+	smp2p_debug_create("ut_remote_gpio_inout", smp2p_ut_remote_inout);
+	return 0;
+}
+late_initcall(smp2p_debugfs_init);
diff --git a/arch/arm/mach-msm/smp2p_loopback.c b/arch/arm/mach-msm/smp2p_loopback.c
new file mode 100644
index 0000000..d95c93f
--- /dev/null
+++ b/arch/arm/mach-msm/smp2p_loopback.c
@@ -0,0 +1,440 @@
+/* arch/arm/mach-msm/smp2p_loopback.c
+ *
+ * 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/debugfs.h>
+#include <linux/list.h>
+#include <linux/ctype.h>
+#include <linux/jiffies.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/completion.h>
+#include <linux/termios.h>
+#include <linux/module.h>
+#include <linux/remote_spinlock.h>
+#include "smd_private.h"
+#include "smp2p_private.h"
+
+/**
+ * struct smp2p_loopback_ctx - Representation of remote loopback object.
+ *
+ * @proc_id: Processor id of the processor that sends the loopback commands.
+ * @out: Handle to the  smem entry structure for providing the response.
+ * @out_nb: Notifies the opening of local entry.
+ * @out_is_active: Outbound entry events should be processed.
+ * @in_nb: Notifies changes in the remote entry.
+ * @in_is_active: Inbound entry events should be processed.
+ * @rmt_lpb_work: Work item that handles the incoming loopback commands.
+ * @rmt_cmd: Structure that holds the current and previous value of the entry.
+ */
+struct smp2p_loopback_ctx {
+	int proc_id;
+	struct msm_smp2p_out *out;
+	struct notifier_block out_nb;
+	bool out_is_active;
+	struct notifier_block in_nb;
+	bool in_is_active;
+	struct work_struct  rmt_lpb_work;
+	struct msm_smp2p_update_notif rmt_cmd;
+};
+
+static struct smp2p_loopback_ctx  remote_loopback[SMP2P_NUM_PROCS];
+static struct msm_smp2p_remote_mock remote_mock;
+
+/**
+ * remote_spinlock_test - Handles remote spinlock test.
+ *
+ * @ctx: Loopback context
+ */
+static void remote_spinlock_test(struct smp2p_loopback_ctx *ctx)
+{
+	uint32_t test_request;
+	uint32_t test_response;
+	unsigned long flags;
+	int n;
+	unsigned lock_count = 0;
+	remote_spinlock_t *smem_spinlock;
+
+	test_request = 0x0;
+	SMP2P_SET_RMT_CMD_TYPE_REQ(test_request);
+	smem_spinlock = smem_get_remote_spinlock();
+	if (!smem_spinlock) {
+		pr_err("%s: unable to get remote spinlock\n", __func__);
+		return;
+	}
+
+	for (;;) {
+		remote_spin_lock_irqsave(smem_spinlock, flags);
+		++lock_count;
+		SMP2P_SET_RMT_CMD(test_request, SMP2P_LB_CMD_RSPIN_LOCKED);
+		(void)msm_smp2p_out_write(ctx->out, test_request);
+
+		for (n = 0; n < 10000; ++n) {
+			(void)msm_smp2p_in_read(ctx->proc_id,
+					"smp2p", &test_response);
+			test_response = SMP2P_GET_RMT_CMD(test_response);
+
+			if (test_response == SMP2P_LB_CMD_RSPIN_END)
+				break;
+
+			if (test_response != SMP2P_LB_CMD_RSPIN_UNLOCKED)
+				SMP2P_ERR("%s: invalid spinlock command %x\n",
+					__func__, test_response);
+		}
+
+		if (test_response == SMP2P_LB_CMD_RSPIN_END) {
+			SMP2P_SET_RMT_CMD_TYPE_RESP(test_request);
+			SMP2P_SET_RMT_CMD(test_request,
+					SMP2P_LB_CMD_RSPIN_END);
+			SMP2P_SET_RMT_DATA(test_request, lock_count);
+			(void)msm_smp2p_out_write(ctx->out, test_request);
+			break;
+		}
+
+		SMP2P_SET_RMT_CMD(test_request, SMP2P_LB_CMD_RSPIN_UNLOCKED);
+		(void)msm_smp2p_out_write(ctx->out, test_request);
+		remote_spin_unlock_irqrestore(smem_spinlock, flags);
+	}
+	remote_spin_unlock_irqrestore(smem_spinlock, flags);
+}
+
+/**
+ * smp2p_rmt_lpb_worker - Handles incoming remote loopback commands.
+ *
+ * @work: Work Item scheduled to handle the incoming commands.
+ */
+static void smp2p_rmt_lpb_worker(struct work_struct *work)
+{
+	struct smp2p_loopback_ctx *ctx;
+	int lpb_cmd;
+	int lpb_cmd_type;
+	int lpb_data;
+
+	ctx = container_of(work, struct smp2p_loopback_ctx, rmt_lpb_work);
+
+	if (!ctx->in_is_active || !ctx->out_is_active)
+		return;
+
+	if (ctx->rmt_cmd.previous_value == ctx->rmt_cmd.current_value)
+		return;
+
+	lpb_cmd_type =  SMP2P_GET_RMT_CMD_TYPE(ctx->rmt_cmd.current_value);
+	lpb_cmd = SMP2P_GET_RMT_CMD(ctx->rmt_cmd.current_value);
+	lpb_data = SMP2P_GET_RMT_DATA(ctx->rmt_cmd.current_value);
+
+	if (lpb_cmd & SMP2P_RLPB_IGNORE)
+		return;
+
+	switch (lpb_cmd) {
+	case SMP2P_LB_CMD_NOOP:
+	    /* Do nothing */
+	    break;
+
+	case SMP2P_LB_CMD_ECHO:
+		SMP2P_SET_RMT_CMD_TYPE(ctx->rmt_cmd.current_value, 0);
+		SMP2P_SET_RMT_DATA(ctx->rmt_cmd.current_value,
+							lpb_data);
+		(void)msm_smp2p_out_write(ctx->out,
+					ctx->rmt_cmd.current_value);
+	    break;
+
+	case SMP2P_LB_CMD_CLEARALL:
+		ctx->rmt_cmd.current_value = 0;
+		(void)msm_smp2p_out_write(ctx->out,
+					ctx->rmt_cmd.current_value);
+	    break;
+
+	case SMP2P_LB_CMD_PINGPONG:
+		SMP2P_SET_RMT_CMD_TYPE(ctx->rmt_cmd.current_value, 0);
+		if (lpb_data) {
+			lpb_data--;
+			SMP2P_SET_RMT_DATA(ctx->rmt_cmd.current_value,
+					lpb_data);
+			(void)msm_smp2p_out_write(ctx->out,
+					ctx->rmt_cmd.current_value);
+		}
+	    break;
+
+	case SMP2P_LB_CMD_RSPIN_START:
+		remote_spinlock_test(ctx);
+		break;
+
+	case SMP2P_LB_CMD_RSPIN_LOCKED:
+	case SMP2P_LB_CMD_RSPIN_UNLOCKED:
+	case SMP2P_LB_CMD_RSPIN_END:
+		/* not used for remote spinlock test */
+		break;
+
+	default:
+		SMP2P_DBG("%s: Unknown loopback command %x\n",
+				__func__, lpb_cmd);
+		break;
+	}
+}
+
+/**
+ * smp2p_rmt_in_edge_notify -  Schedules a work item to handle the commands.
+ *
+ * @nb: Notifier block, this is called when the value in remote entry changes.
+ * @event: Takes value SMP2P_ENTRY_UPDATE or SMP2P_OPEN based on the event.
+ * @data: Consists of previous and current value in case of entry update.
+ * @returns: 0 for success (return value required for notifier chains).
+ */
+static int smp2p_rmt_in_edge_notify(struct notifier_block *nb,
+				unsigned long event, void *data)
+{
+	struct smp2p_loopback_ctx *ctx;
+
+	if (!(event == SMP2P_ENTRY_UPDATE || event == SMP2P_OPEN))
+		return 0;
+
+	ctx = container_of(nb, struct smp2p_loopback_ctx, in_nb);
+	if (data && ctx->in_is_active) {
+			ctx->rmt_cmd =
+			    *(struct msm_smp2p_update_notif *)data;
+			schedule_work(&ctx->rmt_lpb_work);
+	}
+
+	return 0;
+}
+
+/**
+ * smp2p_rmt_out_edge_notify - Notifies on the opening of the outbound entry.
+ *
+ * @nb: Notifier block, this is called when the local entry is open.
+ * @event: Takes on value SMP2P_OPEN when the local entry is open.
+ * @data: Consist of current value of the remote entry, if entry is open.
+ * @returns: 0 for success (return value required for notifier chains).
+ */
+static int smp2p_rmt_out_edge_notify(struct notifier_block  *nb,
+				unsigned long event, void *data)
+{
+	struct smp2p_loopback_ctx *ctx;
+
+	ctx = container_of(nb, struct smp2p_loopback_ctx, out_nb);
+	if (event == SMP2P_OPEN)
+		SMP2P_DBG("%s: 'smp2p':%d opened\n", __func__,
+				ctx->proc_id);
+
+	return 0;
+}
+
+/**
+ * msm_smp2p_init_rmt_lpb -  Initializes the remote loopback object.
+ *
+ * @ctx: Pointer to remote loopback object that needs to be initialized.
+ * @pid: Processor id  of the processor that is sending the commands.
+ * @entry: Name of the entry that needs to be opened locally.
+ * @returns: 0 on success, standard Linux error code otherwise.
+ */
+static int msm_smp2p_init_rmt_lpb(struct  smp2p_loopback_ctx *ctx,
+			int pid, const char *entry)
+{
+	int ret = 0;
+	int tmp;
+
+	if (!ctx || !entry || pid > SMP2P_NUM_PROCS)
+		return -EINVAL;
+
+	ctx->in_nb.notifier_call = smp2p_rmt_in_edge_notify;
+	ctx->out_nb.notifier_call = smp2p_rmt_out_edge_notify;
+	ctx->proc_id = pid;
+	ctx->in_is_active = true;
+	ctx->out_is_active = true;
+	tmp = msm_smp2p_out_open(pid, entry, &ctx->out_nb,
+						&ctx->out);
+	if (tmp) {
+		SMP2P_ERR("%s: open failed outbound entry '%s':%d - ret %d\n",
+				__func__, entry, pid, tmp);
+		ret = tmp;
+	}
+
+	tmp = msm_smp2p_in_register(ctx->proc_id,
+				SMP2P_RLPB_ENTRY_NAME,
+				&ctx->in_nb);
+	if (tmp) {
+		SMP2P_ERR("%s: unable to open inbound entry '%s':%d - ret %d\n",
+				__func__, entry, pid, tmp);
+		ret = tmp;
+	}
+
+	return ret;
+}
+
+/**
+ * msm_smp2p_init_rmt_lpb_proc - Wrapper over msm_smp2p_init_rmt_lpb
+ *
+ * @remote_pid: Processor ID of the processor that sends loopback command.
+ * @returns: Pointer to outbound entry handle.
+ */
+void *msm_smp2p_init_rmt_lpb_proc(int remote_pid)
+{
+	int tmp;
+	void *ret = NULL;
+
+	tmp = msm_smp2p_init_rmt_lpb(&remote_loopback[remote_pid],
+			remote_pid, SMP2P_RLPB_ENTRY_NAME);
+	if (!tmp)
+		ret = remote_loopback[remote_pid].out;
+
+	return ret;
+}
+EXPORT_SYMBOL(msm_smp2p_init_rmt_lpb_proc);
+
+/**
+ * msm_smp2p_deinit_rmt_lpb_proc - Unregister support for remote processor.
+ *
+ * @remote_pid:  Processor ID of the remote system.
+ * @returns: 0 on success, standard Linux error code otherwise.
+ *
+ * Unregister loopback support for remote processor.
+ */
+int msm_smp2p_deinit_rmt_lpb_proc(int remote_pid)
+{
+	int ret = 0;
+	int tmp;
+	struct smp2p_loopback_ctx *ctx;
+
+	if (remote_pid >= SMP2P_NUM_PROCS)
+		return -EINVAL;
+
+	ctx = &remote_loopback[remote_pid];
+
+	/* abort any pending notifications */
+	remote_loopback[remote_pid].out_is_active = false;
+	remote_loopback[remote_pid].in_is_active = false;
+	flush_work(&ctx->rmt_lpb_work);
+
+	/* unregister entries */
+	tmp = msm_smp2p_out_close(&remote_loopback[remote_pid].out);
+	remote_loopback[remote_pid].out = NULL;
+	if (tmp) {
+		SMP2P_ERR("%s: outbound 'smp2p':%d close failed %d\n",
+				__func__, remote_pid, tmp);
+		ret = tmp;
+	}
+
+	tmp = msm_smp2p_in_unregister(remote_pid,
+		SMP2P_RLPB_ENTRY_NAME, &remote_loopback[remote_pid].in_nb);
+	if (tmp) {
+		SMP2P_ERR("%s: inbound 'smp2p':%d close failed %d\n",
+				__func__, remote_pid, tmp);
+		ret = tmp;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(msm_smp2p_deinit_rmt_lpb_proc);
+
+/**
+ * msm_smp2p_set_remote_mock_exists - Sets the remote mock configuration.
+ *
+ * @item_exists: true = Remote mock SMEM item exists
+ *
+ * This is used in the testing environment to simulate the existence of the
+ * remote smem item in order to test the negotiation algorithm.
+ */
+void msm_smp2p_set_remote_mock_exists(bool item_exists)
+{
+	remote_mock.item_exists = item_exists;
+}
+EXPORT_SYMBOL(msm_smp2p_set_remote_mock_exists);
+
+/**
+ * msm_smp2p_get_remote_mock - Get remote mock object.
+ *
+ * @returns: Point to the remote mock object.
+ */
+void *msm_smp2p_get_remote_mock(void)
+{
+	return &remote_mock;
+}
+EXPORT_SYMBOL(msm_smp2p_get_remote_mock);
+
+/**
+ * msm_smp2p_get_remote_mock_smem_item - Returns a pointer to remote item.
+ *
+ * @size:    Size of item.
+ * @returns: Pointer to mock remote smem item.
+ */
+void *msm_smp2p_get_remote_mock_smem_item(uint32_t *size)
+{
+	void *ptr = NULL;
+	if (remote_mock.item_exists) {
+		*size = sizeof(remote_mock.remote_item);
+		ptr = &(remote_mock.remote_item);
+	}
+
+	return ptr;
+}
+EXPORT_SYMBOL(msm_smp2p_get_remote_mock_smem_item);
+
+/**
+ * smp2p_remote_mock_rx_interrupt - Triggers receive interrupt for mock proc.
+ *
+ * @returns: 0 for success
+ *
+ * This function simulates the receiving of interrupt by the mock remote
+ * processor in a testing environment.
+ */
+int smp2p_remote_mock_rx_interrupt(void)
+{
+	remote_mock.rx_interrupt_count++;
+	if (remote_mock.initialized)
+		complete(&remote_mock.cb_completion);
+	return 0;
+}
+EXPORT_SYMBOL(smp2p_remote_mock_rx_interrupt);
+
+/**
+ * smp2p_remote_mock_tx_interrupt - Calls the SMP2P interrupt handler.
+ *
+ * This function calls the interrupt handler of the Apps processor to simulate
+ * receiving interrupts from a remote processor.
+ */
+static void smp2p_remote_mock_tx_interrupt(void)
+{
+	msm_smp2p_interrupt_handler(SMP2P_REMOTE_MOCK_PROC);
+}
+
+/**
+ * smp2p_remote_mock_init - Initialize the remote mock and loopback objects.
+ *
+ * @returns: 0 for success
+ */
+static int __init smp2p_remote_mock_init(void)
+{
+	int i;
+
+	smp2p_init_header(&remote_mock.remote_item.header,
+			SMP2P_REMOTE_MOCK_PROC, SMP2P_APPS_PROC,
+			0, 0);
+	remote_mock.rx_interrupt_count = 0;
+	remote_mock.rx_interrupt = smp2p_remote_mock_rx_interrupt;
+	remote_mock.tx_interrupt = smp2p_remote_mock_tx_interrupt;
+	remote_mock.item_exists = false;
+	init_completion(&remote_mock.cb_completion);
+	remote_mock.initialized = true;
+
+	for (i = 0; i < SMP2P_NUM_PROCS; i++) {
+		INIT_WORK(&(remote_loopback[i].rmt_lpb_work),
+				smp2p_rmt_lpb_worker);
+		if (i == SMP2P_REMOTE_MOCK_PROC)
+			/* do not register loopback for remote mock proc */
+			continue;
+
+		msm_smp2p_init_rmt_lpb(&remote_loopback[i],
+			i, SMP2P_RLPB_ENTRY_NAME);
+	}
+	return 0;
+}
+module_init(smp2p_remote_mock_init);
diff --git a/arch/arm/mach-msm/smp2p_private.h b/arch/arm/mach-msm/smp2p_private.h
new file mode 100644
index 0000000..b9a5cfe
--- /dev/null
+++ b/arch/arm/mach-msm/smp2p_private.h
@@ -0,0 +1,226 @@
+/* arch/arm/mach-msm/smp2p_private.h
+ *
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef _ARCH_ARM_MACH_MSM_MSM_SMP2P_PRIVATE_H_
+#define _ARCH_ARM_MACH_MSM_MSM_SMP2P_PRIVATE_H_
+
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <mach/msm_ipc_logging.h>
+#include "smp2p_private_api.h"
+
+#define SMP2P_MAX_ENTRY 16
+#define SMP2P_LOCAL_VERSION 1
+#define SMP2P_LOCAL_FEATURE  0x0
+
+/* SMEM Item Header Macros */
+#define SMP2P_MAGIC 0x504D5324
+#define SMP2P_LOCAL_PID_MASK 0x0000ffff
+#define SMP2P_LOCAL_PID_BIT 0
+#define SMP2P_REMOTE_PID_MASK 0xffff0000
+#define SMP2P_REMOTE_PID_BIT 16
+#define SMP2P_VERSION_MASK 0x000000ff
+#define SMP2P_VERSION_BIT 0
+#define SMP2P_FEATURE_MASK 0xffffff00
+#define SMP2P_FEATURE_BIT 8
+#define SMP2P_ENT_TOTAL_MASK 0x0000ffff
+#define SMP2P_ENT_TOTAL_BIT 0
+#define SMP2P_ENT_VALID_MASK 0xffff0000
+#define SMP2P_ENT_VALID_BIT 16
+
+#define SMP2P_GET_BITS(hdr_val, mask, bit) \
+	(((hdr_val) & (mask)) >> (bit))
+#define SMP2P_SET_BITS(hdr_val, mask, bit, new_value) \
+	do {\
+		hdr_val = (hdr_val & ~(mask)) \
+		| (((new_value) << (bit)) & (mask)); \
+	} while (0)
+
+#define SMP2P_GET_LOCAL_PID(hdr) \
+	SMP2P_GET_BITS(hdr, SMP2P_LOCAL_PID_MASK, SMP2P_LOCAL_PID_BIT)
+#define SMP2P_SET_LOCAL_PID(hdr, pid) \
+	SMP2P_SET_BITS(hdr, SMP2P_LOCAL_PID_MASK, SMP2P_LOCAL_PID_BIT, pid)
+
+#define SMP2P_GET_REMOTE_PID(hdr) \
+	SMP2P_GET_BITS(hdr, SMP2P_REMOTE_PID_MASK, SMP2P_REMOTE_PID_BIT)
+#define SMP2P_SET_REMOTE_PID(hdr, pid) \
+	SMP2P_SET_BITS(hdr, SMP2P_REMOTE_PID_MASK, SMP2P_REMOTE_PID_BIT, pid)
+
+#define SMP2P_GET_VERSION(hdr) \
+	SMP2P_GET_BITS(hdr, SMP2P_VERSION_MASK, SMP2P_VERSION_BIT)
+#define SMP2P_SET_VERSION(hdr, version) \
+	SMP2P_SET_BITS(hdr, SMP2P_VERSION_MASK, SMP2P_VERSION_BIT, version)
+
+#define SMP2P_GET_FEATURES(hdr) \
+	SMP2P_GET_BITS(hdr, SMP2P_FEATURE_MASK, SMP2P_FEATURE_BIT)
+#define SMP2P_SET_FEATURES(hdr, features) \
+	SMP2P_SET_BITS(hdr, SMP2P_FEATURE_MASK, SMP2P_FEATURE_BIT, features)
+
+#define SMP2P_GET_ENT_TOTAL(hdr) \
+	SMP2P_GET_BITS(hdr, SMP2P_ENT_TOTAL_MASK, SMP2P_ENT_TOTAL_BIT)
+#define SMP2P_SET_ENT_TOTAL(hdr, entries) \
+	SMP2P_SET_BITS(hdr, SMP2P_ENT_TOTAL_MASK, SMP2P_ENT_TOTAL_BIT, entries)
+
+#define SMP2P_GET_ENT_VALID(hdr) \
+	SMP2P_GET_BITS(hdr, SMP2P_ENT_VALID_MASK, SMP2P_ENT_VALID_BIT)
+#define SMP2P_SET_ENT_VALID(hdr, entries) \
+	SMP2P_SET_BITS(hdr,  SMP2P_ENT_VALID_MASK, SMP2P_ENT_VALID_BIT,\
+		entries)
+
+/* Loopback Command Macros */
+#define SMP2P_RMT_CMD_TYPE_MASK 0x80000000
+#define SMP2P_RMT_CMD_TYPE_BIT 31
+#define SMP2P_RMT_IGNORE_MASK 0x40000000
+#define SMP2P_RMT_IGNORE_BIT 30
+#define SMP2P_RMT_CMD_MASK 0x3f000000
+#define SMP2P_RMT_CMD_BIT 24
+#define SMP2P_RMT_DATA_MASK 0x00ffffff
+#define SMP2P_RMT_DATA_BIT 0
+
+#define SMP2P_GET_RMT_CMD_TYPE(val) \
+	SMP2P_GET_BITS(val, SMP2P_RMT_CMD_TYPE_MASK, SMP2P_RMT_CMD_TYPE_BIT)
+#define SMP2P_GET_RMT_CMD(val) \
+	SMP2P_GET_BITS(val, SMP2P_RMT_CMD_MASK, SMP2P_RMT_CMD_BIT)
+
+#define SMP2P_GET_RMT_DATA(val) \
+	SMP2P_GET_BITS(val, SMP2P_RMT_DATA_MASK, SMP2P_RMT_DATA_BIT)
+
+#define SMP2P_SET_RMT_CMD_TYPE(val, cmd_type) \
+	SMP2P_SET_BITS(val, SMP2P_RMT_CMD_TYPE_MASK, SMP2P_RMT_CMD_TYPE_BIT, \
+		cmd_type)
+#define SMP2P_SET_RMT_CMD_TYPE_REQ(val) \
+	SMP2P_SET_RMT_CMD_TYPE(val, 1)
+#define SMP2P_SET_RMT_CMD_TYPE_RESP(val) \
+	SMP2P_SET_RMT_CMD_TYPE(val, 0)
+
+#define SMP2P_SET_RMT_CMD(val, cmd) \
+	SMP2P_SET_BITS(val, SMP2P_RMT_CMD_MASK, SMP2P_RMT_CMD_BIT, \
+		cmd)
+#define SMP2P_SET_RMT_DATA(val, data) \
+	SMP2P_SET_BITS(val, SMP2P_RMT_DATA_MASK, SMP2P_RMT_DATA_BIT, data)
+
+enum {
+	SMP2P_LB_CMD_NOOP = 0x0,
+	SMP2P_LB_CMD_ECHO,
+	SMP2P_LB_CMD_CLEARALL,
+	SMP2P_LB_CMD_PINGPONG,
+	SMP2P_LB_CMD_RSPIN_START,
+	SMP2P_LB_CMD_RSPIN_LOCKED,
+	SMP2P_LB_CMD_RSPIN_UNLOCKED,
+	SMP2P_LB_CMD_RSPIN_END,
+};
+#define SMP2P_RLPB_IGNORE 0x40
+#define SMP2P_RLPB_ENTRY_NAME "smp2p"
+
+/* Debug Logging Macros */
+enum {
+	MSM_SMP2P_INFO = 1U << 0,
+	MSM_SMP2P_DEBUG = 1U << 1,
+	MSM_SMP2P_GPIO = 1U << 2,
+};
+
+#define SMP2P_IPC_LOG_STR(x...) do { \
+	if (smp2p_get_log_ctx()) \
+		ipc_log_string(smp2p_get_log_ctx(), x); \
+} while (0)
+
+#define SMP2P_DBG(x...) do {                              \
+	if (smp2p_get_debug_mask() & MSM_SMP2P_DEBUG) \
+			SMP2P_IPC_LOG_STR(x);  \
+} while (0)
+
+#define SMP2P_INFO(x...) do {                              \
+	if (smp2p_get_debug_mask() & MSM_SMP2P_INFO) \
+			SMP2P_IPC_LOG_STR(x);  \
+} while (0)
+
+#define SMP2P_ERR(x...) do {                              \
+	pr_err(x); \
+	SMP2P_IPC_LOG_STR(x);  \
+} while (0)
+
+#define SMP2P_GPIO(x...) do {                              \
+	if (smp2p_get_debug_mask() & MSM_SMP2P_GPIO) \
+			SMP2P_IPC_LOG_STR(x);  \
+} while (0)
+
+
+enum msm_smp2p_edge_state {
+	SMP2P_EDGE_STATE_CLOSED,
+	SMP2P_EDGE_STATE_OPENING,
+	SMP2P_EDGE_STATE_OPENED,
+	SMP2P_EDGE_STATE_FAILED = 0xff,
+};
+
+struct smp2p_smem {
+	uint32_t magic;
+	uint32_t feature_version;
+	uint32_t rem_loc_proc_id;
+	uint32_t valid_total_ent;
+	uint32_t reserved;
+};
+
+struct smp2p_entry_v1 {
+	char name[SMP2P_MAX_ENTRY_NAME];
+	uint32_t entry;
+};
+
+struct smp2p_smem_item {
+	struct smp2p_smem header;
+	struct smp2p_entry_v1 entries[SMP2P_MAX_ENTRY];
+};
+
+/* Mock object for internal loopback testing. */
+struct msm_smp2p_remote_mock {
+	struct smp2p_smem_item remote_item;
+	int rx_interrupt_count;
+	int (*rx_interrupt)(void);
+	void (*tx_interrupt)(void);
+
+	bool item_exists;
+	bool initialized;
+	struct completion cb_completion;
+};
+
+void smp2p_init_header(struct smp2p_smem *header_ptr, int local_pid,
+		int remote_pid, uint32_t features, uint32_t version);
+void *msm_smp2p_get_remote_mock(void);
+int smp2p_remote_mock_rx_interrupt(void);
+int smp2p_reset_mock_edge(void);
+void msm_smp2p_interrupt_handler(int);
+void msm_smp2p_set_remote_mock_exists(bool item_exists);
+void *msm_smp2p_get_remote_mock_smem_item(uint32_t *size);
+void *msm_smp2p_init_rmt_lpb_proc(int remote_pid);
+int msm_smp2p_deinit_rmt_lpb_proc(int remote_pid);
+void *smp2p_get_log_ctx(void);
+int smp2p_get_debug_mask(void);
+
+/* Inbound / outbound Interrupt configuration. */
+struct smp2p_interrupt_config {
+	bool is_configured;
+	uint32_t *out_int_ptr;
+	uint32_t out_int_mask;
+	int in_int_id;
+	const char *name;
+
+	/* interrupt stats */
+	unsigned in_interrupt_count;
+	unsigned out_interrupt_count;
+};
+
+struct smp2p_interrupt_config *smp2p_get_interrupt_config(void);
+const char *smp2p_pid_to_name(int remote_pid);
+struct smp2p_smem *smp2p_get_in_item(int remote_pid);
+struct smp2p_smem *smp2p_get_out_item(int remote_pid, int *state);
+void smp2p_gpio_open_test_entry(const char *name, int remote_pid, bool do_open);
+#endif
diff --git a/arch/arm/mach-msm/smp2p_private_api.h b/arch/arm/mach-msm/smp2p_private_api.h
new file mode 100644
index 0000000..c757eec
--- /dev/null
+++ b/arch/arm/mach-msm/smp2p_private_api.h
@@ -0,0 +1,79 @@
+/* arch/arm/mach-msm/smp2p_private_api.h
+ *
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef _ARCH_ARM_MACH_MSM_SMP2P_PRIVATE_API_H_
+#define _ARCH_ARM_MACH_MSM_SMP2P_PRIVATE_API_H_
+
+#include <linux/notifier.h>
+
+struct msm_smp2p_out;
+
+/* Maximum size of the entry name and trailing null. */
+#define SMP2P_MAX_ENTRY_NAME 16
+
+/* Bits per entry */
+#define SMP2P_BITS_PER_ENTRY 32
+
+/* Processor ID's */
+enum {
+	SMP2P_APPS_PROC       = 0,
+	SMP2P_MODEM_PROC      = 1,
+	SMP2P_AUDIO_PROC      = 2,
+	SMP2P_RESERVED_PROC_1 = 3,
+	SMP2P_WIRELESS_PROC   = 4,
+	SMP2P_RESERVED_PROC_2 = 5,
+	SMP2P_POWER_PROC      = 6,
+	/* add new processors here */
+
+	SMP2P_REMOTE_MOCK_PROC,
+	SMP2P_NUM_PROCS,
+};
+
+/**
+ * Notification events that are passed to notifier for incoming and outgoing
+ * entries.
+ *
+ * If the @metadata argument in the notifier is non-null, then it will
+ * point to the associated struct smux_meta_* structure.
+ */
+enum msm_smp2p_events {
+	SMP2P_OPEN,         /* data is NULL */
+	SMP2P_ENTRY_UPDATE, /* data => struct msm_smp2p_update_notif */
+};
+
+/**
+ * Passed in response to a SMP2P_ENTRY_UPDATE event.
+ *
+ * @prev_value:     previous value of entry
+ * @current_value:  latest value of entry
+ */
+struct msm_smp2p_update_notif {
+	uint32_t previous_value;
+	uint32_t current_value;
+};
+
+int msm_smp2p_out_open(int remote_pid, const char *entry,
+	struct notifier_block *open_notifier,
+	struct msm_smp2p_out **handle);
+int msm_smp2p_out_close(struct msm_smp2p_out **handle);
+int msm_smp2p_out_read(struct msm_smp2p_out *handle, uint32_t *data);
+int msm_smp2p_out_write(struct msm_smp2p_out *handle, uint32_t data);
+int msm_smp2p_out_modify(struct msm_smp2p_out *handle, uint32_t set_mask,
+	uint32_t clear_mask);
+int msm_smp2p_in_read(int remote_pid, const char *entry, uint32_t *data);
+int msm_smp2p_in_register(int remote_pid, const char *entry,
+	struct notifier_block *in_notifier);
+int msm_smp2p_in_unregister(int remote_pid, const char *entry,
+	struct notifier_block *in_notifier);
+
+#endif /* _ARCH_ARM_MACH_MSM_SMP2P_PRIVATE_API_H_ */
diff --git a/arch/arm/mach-msm/smp2p_spinlock_test.c b/arch/arm/mach-msm/smp2p_spinlock_test.c
new file mode 100644
index 0000000..09d7c0d
--- /dev/null
+++ b/arch/arm/mach-msm/smp2p_spinlock_test.c
@@ -0,0 +1,487 @@
+/* arch/arm/mach-msm/smp2p_spinlock_test.c
+ *
+ * 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/debugfs.h>
+#include <linux/ctype.h>
+#include <linux/jiffies.h>
+#include <linux/delay.h>
+#include <linux/completion.h>
+#include <linux/remote_spinlock.h>
+#include <mach/msm_smsm.h>
+#include "smd_private.h"
+#include "smp2p_private.h"
+#include "smp2p_test_common.h"
+
+#define REMOTE_SPIN_PID 1
+#define RS_END_THIEF_PID_BIT 20
+#define RS_END_THIEF_MASK 0x00f00000
+
+/* Spinlock commands used for testing Apps<->RPM spinlocks. */
+enum RPM_SPINLOCK_CMDS {
+	RPM_CMD_INVALID,
+	RPM_CMD_START,
+	RPM_CMD_LOCKED,
+	RPM_CMD_UNLOCKED,
+	RPM_CMD_END,
+};
+
+/* Shared structure for testing Apps<->RPM spinlocks. */
+struct rpm_spinlock_test {
+	uint32_t apps_cmd;
+	uint32_t apps_lock_count;
+	uint32_t rpm_cmd;
+	uint32_t rpm_lock_count;
+};
+
+/**
+ * smp2p_ut_remote_spinlock_core - Verify remote spinlock.
+ *
+ * @s:           Pointer to output file
+ * @remote_pid:  Remote processor to test
+ * @use_trylock: Use trylock to prevent an Apps deadlock if the
+ *               remote spinlock fails.
+ */
+static void smp2p_ut_remote_spinlock_core(struct seq_file *s, int remote_pid,
+		bool use_trylock)
+{
+	int failed = 0;
+	unsigned lock_count = 0;
+	struct msm_smp2p_out *handle = NULL;
+	int ret;
+	uint32_t test_request;
+	uint32_t test_response;
+	struct mock_cb_data cb_out;
+	struct mock_cb_data cb_in;
+	unsigned long flags;
+	unsigned n;
+	unsigned test_num;
+	bool have_lock;
+	bool timeout;
+	int failed_tmp;
+	int spinlock_owner;
+	remote_spinlock_t *smem_spinlock;
+
+	seq_printf(s, "Running %s for '%s' remote pid %d\n",
+		   __func__, smp2p_pid_to_name(remote_pid), remote_pid);
+
+	cb_out.initialized = false;
+	cb_in.initialized = false;
+	mock_cb_data_init(&cb_out);
+	mock_cb_data_init(&cb_in);
+	do {
+		smem_spinlock = smem_get_remote_spinlock();
+		UT_ASSERT_PTR(smem_spinlock, !=, NULL);
+
+		/* Open output entry */
+		ret = msm_smp2p_out_open(remote_pid, SMP2P_RLPB_ENTRY_NAME,
+			&cb_out.nb, &handle);
+		UT_ASSERT_INT(ret, ==, 0);
+		UT_ASSERT_INT(
+			(int)wait_for_completion_timeout(
+					&cb_out.cb_completion, HZ * 2),
+			>, 0);
+		UT_ASSERT_INT(cb_out.cb_count, ==, 1);
+		UT_ASSERT_INT(cb_out.event_open, ==, 1);
+
+		/* Open inbound entry */
+		ret = msm_smp2p_in_register(remote_pid, SMP2P_RLPB_ENTRY_NAME,
+				&cb_in.nb);
+		UT_ASSERT_INT(ret, ==, 0);
+		UT_ASSERT_INT(
+			(int)wait_for_completion_timeout(
+					&cb_in.cb_completion, HZ * 2),
+			>, 0);
+		UT_ASSERT_INT(cb_in.cb_count, ==, 1);
+		UT_ASSERT_INT(cb_in.event_open, ==, 1);
+
+		/* Send start */
+		mock_cb_data_reset(&cb_in);
+		mock_cb_data_reset(&cb_out);
+		test_request = 0x0;
+		SMP2P_SET_RMT_CMD_TYPE_REQ(test_request);
+		SMP2P_SET_RMT_CMD(test_request, SMP2P_LB_CMD_RSPIN_START);
+		SMP2P_SET_RMT_DATA(test_request, 0x0);
+		ret = msm_smp2p_out_write(handle, test_request);
+		UT_ASSERT_INT(ret, ==, 0);
+
+		UT_ASSERT_INT(
+			(int)wait_for_completion_timeout(
+					&cb_in.cb_completion, HZ * 2),
+			>, 0);
+		UT_ASSERT_INT(cb_in.cb_count, ==, 1);
+		UT_ASSERT_INT(cb_in.event_entry_update, ==, 1);
+		ret = msm_smp2p_in_read(remote_pid, SMP2P_RLPB_ENTRY_NAME,
+				&test_response);
+		UT_ASSERT_INT(ret, ==, 0);
+
+		test_response = SMP2P_GET_RMT_CMD(test_response);
+		if (test_response != SMP2P_LB_CMD_RSPIN_LOCKED &&
+				test_response != SMP2P_LB_CMD_RSPIN_UNLOCKED) {
+			/* invalid response from remote - abort test */
+			test_request = 0x0;
+			SMP2P_SET_RMT_CMD_TYPE(test_request, 1);
+			SMP2P_SET_RMT_CMD(test_request, SMP2P_LB_CMD_RSPIN_END);
+			SMP2P_SET_RMT_DATA(test_request, 0x0);
+			ret = msm_smp2p_out_write(handle, test_request);
+			UT_ASSERT_HEX(SMP2P_LB_CMD_RSPIN_LOCKED, ==,
+					test_response);
+		}
+
+		/* Run spinlock test */
+		if (use_trylock)
+			seq_printf(s, "\tUsing remote_spin_trylock\n");
+		else
+			seq_printf(s, "\tUsing remote_spin_lock\n");
+
+		flags = 0;
+		have_lock = false;
+		timeout = false;
+		spinlock_owner = 0;
+		test_request = 0x0;
+		SMP2P_SET_RMT_CMD_TYPE_REQ(test_request);
+		for (test_num = 0; !failed && test_num < 10000; ++test_num) {
+			/* try to acquire spinlock */
+			if (use_trylock) {
+				unsigned long j_start = jiffies;
+				while (!remote_spin_trylock_irqsave(
+						smem_spinlock, flags)) {
+					if (jiffies_to_msecs(jiffies - j_start)
+							> 1000) {
+						seq_printf(s,
+							"\tFail: Timeout trying to get the lock\n");
+						timeout = true;
+						break;
+					}
+				}
+				if (timeout)
+					break;
+			} else {
+				remote_spin_lock_irqsave(smem_spinlock, flags);
+			}
+			have_lock = true;
+			++lock_count;
+
+			/* tell the remote side that we have the lock */
+			SMP2P_SET_RMT_DATA(test_request, lock_count);
+			SMP2P_SET_RMT_CMD(test_request,
+					SMP2P_LB_CMD_RSPIN_LOCKED);
+			ret = msm_smp2p_out_write(handle, test_request);
+			UT_ASSERT_INT(ret, ==, 0);
+
+			/* verify the other side doesn't say it has the lock */
+			for (n = 0; n < 1000; ++n) {
+				spinlock_owner =
+					remote_spin_owner(smem_spinlock);
+				if (spinlock_owner != REMOTE_SPIN_PID) {
+					/* lock stolen by remote side */
+					seq_printf(s,
+						"\tFail: Remote side (%d) stole lock (pid %d)\n",
+						remote_pid, spinlock_owner);
+					failed = true;
+					break;
+				}
+				spinlock_owner = 0;
+
+				ret = msm_smp2p_in_read(remote_pid,
+					SMP2P_RLPB_ENTRY_NAME, &test_response);
+				UT_ASSERT_INT(ret, ==, 0);
+				test_response =
+					SMP2P_GET_RMT_CMD(test_response);
+				UT_ASSERT_HEX(SMP2P_LB_CMD_RSPIN_UNLOCKED, ==,
+					test_response);
+			}
+			if (failed)
+				break;
+
+			/* tell remote side we are unlocked and release lock */
+			SMP2P_SET_RMT_CMD(test_request,
+					SMP2P_LB_CMD_RSPIN_UNLOCKED);
+			(void)msm_smp2p_out_write(handle, test_request);
+			have_lock = false;
+			remote_spin_unlock_irqrestore(smem_spinlock, flags);
+		}
+		if (have_lock)
+			remote_spin_unlock_irqrestore(smem_spinlock, flags);
+
+		/* End test */
+		mock_cb_data_reset(&cb_in);
+		SMP2P_SET_RMT_CMD(test_request, SMP2P_LB_CMD_RSPIN_END);
+		SMP2P_SET_RMT_DATA(test_request, lock_count |
+				(spinlock_owner << RS_END_THIEF_PID_BIT));
+		(void)msm_smp2p_out_write(handle, test_request);
+
+		failed_tmp = failed;
+		failed = false;
+		do {
+			UT_ASSERT_INT(
+				(int)wait_for_completion_timeout(
+					&cb_in.cb_completion, HZ * 2),
+				>, 0);
+			INIT_COMPLETION(cb_in.cb_completion);
+			ret = msm_smp2p_in_read(remote_pid,
+					SMP2P_RLPB_ENTRY_NAME, &test_response);
+			UT_ASSERT_INT(ret, ==, 0);
+		} while (!failed &&
+			SMP2P_GET_RMT_CMD(test_response) !=
+			SMP2P_LB_CMD_RSPIN_END);
+		if (failed)
+			break;
+		failed = failed_tmp;
+
+		test_response = SMP2P_GET_RMT_DATA(test_response);
+		seq_printf(s,
+			"\tLocked spinlock local %u times; remote %u times",
+			lock_count,
+			test_response & ((1 << RS_END_THIEF_PID_BIT) - 1)
+			);
+		if (test_response & RS_END_THIEF_MASK) {
+			seq_printf(s,
+				"Remote side reporting lock stolen by pid %d.\n",
+				SMP2P_GET_BITS(test_response,
+					RS_END_THIEF_MASK,
+					RS_END_THIEF_PID_BIT));
+			failed = 1;
+		}
+		seq_printf(s, "\n");
+
+		/* Cleanup */
+		ret = msm_smp2p_out_close(&handle);
+		UT_ASSERT_INT(ret, ==, 0);
+		UT_ASSERT_PTR(handle, ==, NULL);
+		ret = msm_smp2p_in_unregister(remote_pid,
+				SMP2P_RLPB_ENTRY_NAME, &cb_in.nb);
+		UT_ASSERT_INT(ret, ==, 0);
+
+		if (!failed && !timeout)
+			seq_printf(s, "\tOK\n");
+	} while (0);
+
+	if (failed) {
+		if (handle) {
+			/* send end command */
+			test_request = 0;
+			SMP2P_SET_RMT_CMD(test_request, SMP2P_LB_CMD_RSPIN_END);
+			SMP2P_SET_RMT_DATA(test_request, lock_count);
+			(void)msm_smp2p_out_write(handle, test_request);
+			(void)msm_smp2p_out_close(&handle);
+		}
+		(void)msm_smp2p_in_unregister(remote_pid,
+				SMP2P_RLPB_ENTRY_NAME, &cb_in.nb);
+
+		pr_err("%s: Failed\n", __func__);
+		seq_printf(s, "\tFailed\n");
+	}
+}
+
+/**
+ * smp2p_ut_remote_spinlock_pid - Verify remote spinlock for a processor.
+ *
+ * @s:           Pointer to output file
+ * @pid:         Processor to test
+ * @use_trylock: Use trylock to prevent an Apps deadlock if the
+ *               remote spinlock fails.
+ */
+static void smp2p_ut_remote_spinlock_pid(struct seq_file *s, int pid,
+		bool use_trylock)
+{
+	struct smp2p_interrupt_config *int_cfg;
+
+	int_cfg = smp2p_get_interrupt_config();
+	if (!int_cfg) {
+		seq_printf(s, "Remote processor config unavailable\n");
+		return;
+	}
+
+	if (pid >= SMP2P_NUM_PROCS || !int_cfg[pid].is_configured)
+		return;
+
+	msm_smp2p_deinit_rmt_lpb_proc(pid);
+	smp2p_ut_remote_spinlock_core(s, pid, use_trylock);
+	msm_smp2p_init_rmt_lpb_proc(pid);
+}
+
+/**
+ * smp2p_ut_remote_spinlock - Verify remote spinlock for all processors.
+ *
+ * @s:   pointer to output file
+ */
+static void smp2p_ut_remote_spinlock(struct seq_file *s)
+{
+	int pid;
+
+	for (pid = 0; pid < SMP2P_NUM_PROCS; ++pid)
+		smp2p_ut_remote_spinlock_pid(s, pid, false);
+}
+
+/**
+ * smp2p_ut_remote_spin_trylock - Verify remote trylock for all processors.
+ *
+ * @s:   Pointer to output file
+ */
+static void smp2p_ut_remote_spin_trylock(struct seq_file *s)
+{
+	int pid;
+
+	for (pid = 0; pid < SMP2P_NUM_PROCS; ++pid)
+		smp2p_ut_remote_spinlock_pid(s, pid, true);
+}
+
+/**
+ * smp2p_ut_remote_spinlock - Verify remote spinlock for all processors.
+ *
+ * @s:   pointer to output file
+ *
+ * This test verifies inbound and outbound functionality for all
+ * configured remote processor.
+ */
+static void smp2p_ut_remote_spinlock_modem(struct seq_file *s)
+{
+	smp2p_ut_remote_spinlock_pid(s, SMP2P_MODEM_PROC, false);
+}
+
+static void smp2p_ut_remote_spinlock_adsp(struct seq_file *s)
+{
+	smp2p_ut_remote_spinlock_pid(s, SMP2P_AUDIO_PROC, false);
+}
+
+static void smp2p_ut_remote_spinlock_wcnss(struct seq_file *s)
+{
+	smp2p_ut_remote_spinlock_pid(s, SMP2P_WIRELESS_PROC, false);
+}
+
+/**
+ * smp2p_ut_remote_spinlock_rpm - Verify remote spinlock.
+ *
+ * @s:   pointer to output file
+ * @remote_pid:  Remote processor to test
+ */
+static void smp2p_ut_remote_spinlock_rpm(struct seq_file *s)
+{
+	int failed = 0;
+	unsigned long flags;
+	unsigned n;
+	unsigned test_num;
+	struct rpm_spinlock_test *data_ptr;
+	remote_spinlock_t *smem_spinlock;
+	bool have_lock;
+
+	seq_printf(s, "Running %s for Apps<->RPM Test\n",
+		   __func__);
+	do {
+		smem_spinlock = smem_get_remote_spinlock();
+		UT_ASSERT_PTR(smem_spinlock, !=, NULL);
+
+		data_ptr = smem_alloc2(SMEM_ID_VENDOR0,
+				sizeof(struct rpm_spinlock_test));
+		UT_ASSERT_PTR(0, !=, data_ptr);
+
+		/* Send start */
+		writel_relaxed(0, &data_ptr->apps_lock_count);
+		writel_relaxed(RPM_CMD_START, &data_ptr->apps_cmd);
+
+		seq_printf(s, "\tWaiting for RPM to start test\n");
+		for (n = 0; n < 1000; ++n) {
+			if (readl_relaxed(&data_ptr->rpm_cmd) !=
+					RPM_CMD_INVALID)
+				break;
+			usleep(1000);
+		}
+		if (readl_relaxed(&data_ptr->rpm_cmd) == RPM_CMD_INVALID) {
+			/* timeout waiting for RPM */
+			writel_relaxed(RPM_CMD_INVALID, &data_ptr->apps_cmd);
+			UT_ASSERT_INT(RPM_CMD_LOCKED, !=, RPM_CMD_INVALID);
+		}
+
+		/* Run spinlock test */
+		flags = 0;
+		have_lock = false;
+		for (test_num = 0; !failed && test_num < 10000; ++test_num) {
+			/* acquire spinlock */
+			remote_spin_lock_irqsave(smem_spinlock, flags);
+			have_lock = true;
+			writel_relaxed(++data_ptr->apps_lock_count,
+				&data_ptr->apps_lock_count);
+			writel_relaxed(RPM_CMD_LOCKED, &data_ptr->apps_cmd);
+			/*
+			 * Ensure that the remote side sees our lock has
+			 * been acquired before we start polling their status.
+			 */
+			wmb();
+
+			/* verify the other side doesn't say it has the lock */
+			for (n = 0; n < 1000; ++n) {
+				UT_ASSERT_HEX(RPM_CMD_UNLOCKED, ==,
+					readl_relaxed(&data_ptr->rpm_cmd));
+			}
+			if (failed)
+				break;
+
+			/* release spinlock */
+			have_lock = false;
+			writel_relaxed(RPM_CMD_UNLOCKED, &data_ptr->apps_cmd);
+			/*
+			 * Ensure that our status-update write was committed
+			 * before we unlock the spinlock.
+			 */
+			wmb();
+			remote_spin_unlock_irqrestore(smem_spinlock, flags);
+		}
+		if (have_lock)
+			remote_spin_unlock_irqrestore(smem_spinlock, flags);
+
+		/* End test */
+		writel_relaxed(RPM_CMD_INVALID, &data_ptr->apps_cmd);
+		seq_printf(s,
+				"\tLocked spinlock local %u remote %u\n",
+				readl_relaxed(&data_ptr->apps_lock_count),
+				readl_relaxed(&data_ptr->rpm_lock_count));
+
+		if (!failed)
+			seq_printf(s, "\tOK\n");
+	} while (0);
+
+	if (failed) {
+		pr_err("%s: Failed\n", __func__);
+		seq_printf(s, "\tFailed\n");
+	}
+}
+
+static int __init smp2p_debugfs_init(void)
+{
+	/*
+	 * Add Unit Test entries.
+	 *
+	 * The idea with unit tests is that you can run all of them
+	 * from ADB shell by doing:
+	 *  adb shell
+	 *  cat ut*
+	 *
+	 * And if particular tests fail, you can then repeatedly run the
+	 * failing tests as you debug and resolve the failing test.
+	 */
+	smp2p_debug_create("ut_remote_spinlock",
+		smp2p_ut_remote_spinlock);
+	smp2p_debug_create("ut_remote_spin_trylock",
+		smp2p_ut_remote_spin_trylock);
+	smp2p_debug_create("ut_remote_spinlock_modem",
+		smp2p_ut_remote_spinlock_modem);
+	smp2p_debug_create("ut_remote_spinlock_adsp",
+		smp2p_ut_remote_spinlock_adsp);
+	smp2p_debug_create("ut_remote_spinlock_wcnss",
+		smp2p_ut_remote_spinlock_wcnss);
+	smp2p_debug_create("ut_remote_spinlock_rpm",
+		smp2p_ut_remote_spinlock_rpm);
+
+	return 0;
+}
+module_init(smp2p_debugfs_init);
diff --git a/arch/arm/mach-msm/smp2p_test.c b/arch/arm/mach-msm/smp2p_test.c
new file mode 100644
index 0000000..18c9bfd
--- /dev/null
+++ b/arch/arm/mach-msm/smp2p_test.c
@@ -0,0 +1,1025 @@
+/* arch/arm/mach-msm/smp2p_test.c
+ *
+ * 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/debugfs.h>
+#include <linux/ctype.h>
+#include <linux/jiffies.h>
+#include <linux/delay.h>
+#include <linux/completion.h>
+#include "smp2p_private.h"
+#include "smp2p_test_common.h"
+
+/**
+ * smp2p_ut_local_basic - Basic sanity test using local loopback.
+ *
+ * @s: pointer to output file
+ *
+ * This test simulates a simple write and read
+ * when remote processor does not exist.
+ */
+static void smp2p_ut_local_basic(struct seq_file *s)
+{
+	int failed = 0;
+	struct msm_smp2p_out *smp2p_obj;
+	struct msm_smp2p_remote_mock *rmp = NULL;
+	int ret;
+	uint32_t test_request;
+	uint32_t test_response = 0;
+	static struct mock_cb_data cb_data;
+
+	seq_printf(s, "Running %s\n", __func__);
+	mock_cb_data_init(&cb_data);
+	do {
+		/* initialize mock edge and start opening */
+		ret = smp2p_reset_mock_edge();
+		UT_ASSERT_INT(ret, ==, 0);
+
+		rmp = msm_smp2p_get_remote_mock();
+		UT_ASSERT_PTR(rmp, !=, NULL);
+
+		rmp->rx_interrupt_count = 0;
+		memset(&rmp->remote_item, 0,
+			sizeof(struct smp2p_smem_item));
+
+		msm_smp2p_set_remote_mock_exists(false);
+
+		ret = msm_smp2p_out_open(SMP2P_REMOTE_MOCK_PROC, "smp2p",
+			&cb_data.nb, &smp2p_obj);
+		UT_ASSERT_INT(ret, ==, 0);
+
+		UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 1);
+		UT_ASSERT_INT(cb_data.cb_count, ==, 0);
+		rmp->rx_interrupt_count = 0;
+
+		/* simulate response from remote side */
+		rmp->remote_item.header.magic = SMP2P_MAGIC;
+		SMP2P_SET_LOCAL_PID(
+		rmp->remote_item.header.rem_loc_proc_id,
+					SMP2P_REMOTE_MOCK_PROC);
+		SMP2P_SET_REMOTE_PID(
+		rmp->remote_item.header.rem_loc_proc_id,
+					SMP2P_APPS_PROC);
+		SMP2P_SET_VERSION(
+		rmp->remote_item.header.feature_version, 1);
+		SMP2P_SET_FEATURES(
+		rmp->remote_item.header.feature_version, 0);
+		SMP2P_SET_ENT_TOTAL(
+		rmp->remote_item.header.valid_total_ent, SMP2P_MAX_ENTRY);
+		SMP2P_SET_ENT_VALID(
+		rmp->remote_item.header.valid_total_ent, 0);
+		rmp->remote_item.header.reserved = 0x0;
+		msm_smp2p_set_remote_mock_exists(true);
+		rmp->tx_interrupt();
+
+		/* verify port was opened */
+		UT_ASSERT_INT(
+			(int)wait_for_completion_timeout(
+					&cb_data.cb_completion, HZ / 2), >, 0);
+		UT_ASSERT_INT(cb_data.cb_count, ==, 1);
+		UT_ASSERT_INT(cb_data.event_open, ==, 1);
+		UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 2);
+
+		/* do write (test outbound entries) */
+		rmp->rx_interrupt_count = 0;
+		test_request = 0xC0DE;
+		ret = msm_smp2p_out_write(smp2p_obj, test_request);
+		UT_ASSERT_INT(ret, ==, 0);
+		UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 1);
+
+		/* do read (test inbound entries) */
+		ret = msm_smp2p_out_read(smp2p_obj, &test_response);
+		UT_ASSERT_INT(ret, ==, 0);
+		UT_ASSERT_INT(test_request, ==, test_response);
+
+		ret = msm_smp2p_out_close(&smp2p_obj);
+		UT_ASSERT_INT(ret, ==, 0);
+		UT_ASSERT_PTR(smp2p_obj, ==, 0);
+
+		seq_printf(s, "\tOK\n");
+	} while (0);
+
+	if (failed) {
+		pr_err("%s: Failed\n", __func__);
+		seq_printf(s, "\tFailed\n");
+		(void)msm_smp2p_out_close(&smp2p_obj);
+	}
+}
+
+/**
+ * smp2p_ut_local_late_open - Verify post-negotiation opening.
+ *
+ * @s: pointer to output file
+ *
+ * Verify entry creation for opening entries after negotiation is complete.
+ */
+static void smp2p_ut_local_late_open(struct seq_file *s)
+{
+	int failed = 0;
+	struct msm_smp2p_out *smp2p_obj;
+	struct msm_smp2p_remote_mock *rmp = NULL;
+	int ret;
+	uint32_t test_request;
+	uint32_t test_response = 0;
+	static struct mock_cb_data cb_data;
+
+	seq_printf(s, "Running %s\n", __func__);
+	mock_cb_data_init(&cb_data);
+	do {
+		/* initialize mock edge */
+		ret = smp2p_reset_mock_edge();
+		UT_ASSERT_INT(ret, ==, 0);
+
+		rmp = msm_smp2p_get_remote_mock();
+		UT_ASSERT_PTR(rmp, !=, NULL);
+
+		rmp->rx_interrupt_count = 0;
+		memset(&rmp->remote_item, 0,
+			sizeof(struct smp2p_smem_item));
+		rmp->remote_item.header.magic = SMP2P_MAGIC;
+		SMP2P_SET_LOCAL_PID(
+		rmp->remote_item.header.rem_loc_proc_id,
+						SMP2P_REMOTE_MOCK_PROC);
+		SMP2P_SET_REMOTE_PID(
+		rmp->remote_item.header.rem_loc_proc_id,
+						SMP2P_APPS_PROC);
+		SMP2P_SET_VERSION(
+			rmp->remote_item.header.feature_version, 1);
+		SMP2P_SET_FEATURES(
+			rmp->remote_item.header.feature_version, 0);
+		SMP2P_SET_ENT_TOTAL(
+			rmp->remote_item.header.valid_total_ent,
+			SMP2P_MAX_ENTRY);
+		SMP2P_SET_ENT_VALID(
+		rmp->remote_item.header.valid_total_ent, 0);
+		rmp->remote_item.header.reserved = 0x0;
+
+		msm_smp2p_set_remote_mock_exists(true);
+
+		ret = msm_smp2p_out_open(SMP2P_REMOTE_MOCK_PROC, "smp2p",
+			&cb_data.nb, &smp2p_obj);
+		UT_ASSERT_INT(ret, ==, 0);
+
+		/* verify port was opened */
+		UT_ASSERT_INT(
+			(int)wait_for_completion_timeout(
+					&cb_data.cb_completion, HZ / 2),
+			>, 0);
+		UT_ASSERT_INT(cb_data.cb_count, ==, 1);
+		UT_ASSERT_INT(cb_data.event_open, ==, 1);
+		UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 2);
+
+		/* do write (test outbound entries) */
+		rmp->rx_interrupt_count = 0;
+		test_request = 0xC0DE;
+		ret = msm_smp2p_out_write(smp2p_obj, test_request);
+		UT_ASSERT_INT(ret, ==, 0);
+		UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 1);
+
+		/* do read (test inbound entries) */
+		ret = msm_smp2p_out_read(smp2p_obj, &test_response);
+		UT_ASSERT_INT(ret, ==, 0);
+		UT_ASSERT_INT(test_request, ==, test_response);
+
+		ret = msm_smp2p_out_close(&smp2p_obj);
+		UT_ASSERT_INT(ret, ==, 0);
+		UT_ASSERT_PTR(smp2p_obj, ==, 0);
+
+		seq_printf(s, "\tOK\n");
+	} while (0);
+
+	if (failed) {
+		pr_err("%s: Failed\n", __func__);
+		seq_printf(s, "\tFailed\n");
+		(void)msm_smp2p_out_close(&smp2p_obj);
+	}
+}
+
+/**
+ * smp2p_ut_local_early_open - Verify pre-negotiation opening.
+ *
+ * @s: pointer to output file
+ *
+ * Verify entry creation for opening entries before negotiation is complete.
+ */
+static void smp2p_ut_local_early_open(struct seq_file *s)
+{
+	int failed = 0;
+	struct msm_smp2p_out *smp2p_obj;
+	struct msm_smp2p_remote_mock *rmp = NULL;
+	struct smp2p_smem *outbound_item;
+	int negotiation_state;
+	int ret;
+	uint32_t test_request;
+	uint32_t test_response = 0;
+	static struct mock_cb_data cb_data;
+
+	seq_printf(s, "Running %s\n", __func__);
+	mock_cb_data_init(&cb_data);
+	do {
+		/* initialize mock edge, but don't enable, yet */
+		ret = smp2p_reset_mock_edge();
+		UT_ASSERT_INT(ret, ==, 0);
+
+		rmp = msm_smp2p_get_remote_mock();
+		UT_ASSERT_PTR(rmp, !=, NULL);
+
+		rmp->rx_interrupt_count = 0;
+		memset(&rmp->remote_item, 0,
+			sizeof(struct smp2p_smem_item));
+		rmp->remote_item.header.magic = SMP2P_MAGIC;
+		SMP2P_SET_LOCAL_PID(
+		rmp->remote_item.header.rem_loc_proc_id,
+						SMP2P_REMOTE_MOCK_PROC);
+		SMP2P_SET_REMOTE_PID(
+		rmp->remote_item.header.rem_loc_proc_id,
+						SMP2P_APPS_PROC);
+		SMP2P_SET_VERSION(
+		rmp->remote_item.header.feature_version, 1);
+		SMP2P_SET_FEATURES(
+		rmp->remote_item.header.feature_version, 0);
+		SMP2P_SET_ENT_TOTAL(
+		rmp->remote_item.header.valid_total_ent, SMP2P_MAX_ENTRY);
+		SMP2P_SET_ENT_VALID(
+		rmp->remote_item.header.valid_total_ent, 0);
+		rmp->remote_item.header.reserved = 0x0;
+
+		msm_smp2p_set_remote_mock_exists(false);
+		UT_ASSERT_PTR(NULL, ==,
+				smp2p_get_in_item(SMP2P_REMOTE_MOCK_PROC));
+
+		/* initiate open, but verify it doesn't complete */
+		ret = msm_smp2p_out_open(SMP2P_REMOTE_MOCK_PROC, "smp2p",
+			&cb_data.nb, &smp2p_obj);
+		UT_ASSERT_INT(ret, ==, 0);
+
+		UT_ASSERT_INT(
+			(int)wait_for_completion_timeout(
+					&cb_data.cb_completion, HZ / 8),
+			==, 0);
+		UT_ASSERT_INT(cb_data.cb_count, ==, 0);
+		UT_ASSERT_INT(cb_data.event_open, ==, 0);
+		UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 1);
+
+		outbound_item = smp2p_get_out_item(SMP2P_REMOTE_MOCK_PROC,
+				&negotiation_state);
+		UT_ASSERT_PTR(outbound_item, !=, NULL);
+		UT_ASSERT_INT(negotiation_state, ==, SMP2P_EDGE_STATE_OPENING);
+		UT_ASSERT_INT(0, ==,
+			SMP2P_GET_ENT_VALID(outbound_item->valid_total_ent));
+
+		/* verify that read/write don't work yet */
+		rmp->rx_interrupt_count = 0;
+		test_request = 0x0;
+		ret = msm_smp2p_out_write(smp2p_obj, test_request);
+		UT_ASSERT_INT(ret, ==, -ENODEV);
+		UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 0);
+
+		ret = msm_smp2p_out_read(smp2p_obj, &test_response);
+		UT_ASSERT_INT(ret, ==, -ENODEV);
+
+		/* allocate remote entry and verify open */
+		msm_smp2p_set_remote_mock_exists(true);
+		rmp->tx_interrupt();
+
+		UT_ASSERT_INT(
+			(int)wait_for_completion_timeout(
+					&cb_data.cb_completion, HZ / 2),
+			>, 0);
+		UT_ASSERT_INT(cb_data.cb_count, ==, 1);
+		UT_ASSERT_INT(cb_data.event_open, ==, 1);
+		UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 2);
+
+		/* do write (test outbound entries) */
+		rmp->rx_interrupt_count = 0;
+		test_request = 0xC0DE;
+		ret = msm_smp2p_out_write(smp2p_obj, test_request);
+		UT_ASSERT_INT(ret, ==, 0);
+		UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 1);
+
+		/* do read (test inbound entries) */
+		ret = msm_smp2p_out_read(smp2p_obj, &test_response);
+		UT_ASSERT_INT(ret, ==, 0);
+		UT_ASSERT_INT(test_request, ==, test_response);
+
+		ret = msm_smp2p_out_close(&smp2p_obj);
+		UT_ASSERT_INT(ret, ==, 0);
+		UT_ASSERT_PTR(smp2p_obj, ==, 0);
+
+		seq_printf(s, "\tOK\n");
+	} while (0);
+
+	if (failed) {
+		pr_err("%s: Failed\n", __func__);
+		seq_printf(s, "\tFailed\n");
+		(void)msm_smp2p_out_close(&smp2p_obj);
+	}
+}
+
+/**
+ * smp2p_ut_mock_loopback - Exercise the remote loopback using remote mock.
+ *
+ * @s: pointer to output file
+ *
+ * This test exercises the remote loopback code using
+ * remote mock object. The remote mock object simulates the remote
+ * processor sending remote loopback commands to the local processor.
+ */
+static void smp2p_ut_mock_loopback(struct seq_file *s)
+{
+	int failed = 0;
+	struct msm_smp2p_remote_mock *rmp = NULL;
+	int ret;
+	uint32_t test_request = 0;
+	uint32_t test_response = 0;
+	struct msm_smp2p_out  *local;
+
+	seq_printf(s, "Running %s\n", __func__);
+	do {
+		/* Initialize the mock edge */
+		ret = smp2p_reset_mock_edge();
+		UT_ASSERT_INT(ret, ==, 0);
+
+		rmp = msm_smp2p_get_remote_mock();
+		UT_ASSERT_PTR(rmp, !=, NULL);
+
+		memset(&rmp->remote_item, 0,
+			sizeof(struct smp2p_smem_item));
+		rmp->remote_item.header.magic = SMP2P_MAGIC;
+		SMP2P_SET_LOCAL_PID(
+		rmp->remote_item.header.rem_loc_proc_id,
+						SMP2P_REMOTE_MOCK_PROC);
+		SMP2P_SET_REMOTE_PID(
+		rmp->remote_item.header.rem_loc_proc_id,
+						SMP2P_APPS_PROC);
+		SMP2P_SET_VERSION(
+		rmp->remote_item.header.feature_version, 1);
+		SMP2P_SET_FEATURES(
+		rmp->remote_item.header.feature_version, 0);
+		SMP2P_SET_ENT_TOTAL(
+		rmp->remote_item.header.valid_total_ent, SMP2P_MAX_ENTRY);
+		SMP2P_SET_ENT_VALID(
+		rmp->remote_item.header.valid_total_ent, 1);
+		rmp->remote_item.header.reserved = 0x0;
+		msm_smp2p_set_remote_mock_exists(true);
+
+		/* Create test entry and attach loopback server */
+		rmp->rx_interrupt_count = 0;
+		INIT_COMPLETION(rmp->cb_completion);
+		strlcpy(rmp->remote_item.entries[0].name, "smp2p",
+							SMP2P_MAX_ENTRY_NAME);
+		rmp->remote_item.entries[0].entry = 0;
+		rmp->tx_interrupt();
+
+		local = msm_smp2p_init_rmt_lpb_proc(SMP2P_REMOTE_MOCK_PROC);
+		UT_ASSERT_INT(
+			(int)wait_for_completion_timeout(
+					&rmp->cb_completion, HZ / 2),
+			>, 0);
+		UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 2);
+
+		/* Send Echo Command */
+		rmp->rx_interrupt_count = 0;
+		INIT_COMPLETION(rmp->cb_completion);
+		SMP2P_SET_RMT_CMD_TYPE(test_request, 1);
+		SMP2P_SET_RMT_CMD(test_request, SMP2P_LB_CMD_ECHO);
+		SMP2P_SET_RMT_DATA(test_request, 10);
+		rmp->remote_item.entries[0].entry = test_request;
+		rmp->tx_interrupt();
+		UT_ASSERT_INT(
+			(int)wait_for_completion_timeout(
+					&rmp->cb_completion, HZ / 2),
+			>, 0);
+
+		/* Verify Echo Response */
+		UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 1);
+		ret = msm_smp2p_out_read(local,
+							&test_response);
+		UT_ASSERT_INT(ret, ==, 0);
+		test_response = SMP2P_GET_RMT_DATA(test_response);
+		UT_ASSERT_INT(test_response, ==, 10);
+
+		/* Send PINGPONG command */
+		test_request = 0;
+		test_response = 0;
+		rmp->rx_interrupt_count = 0;
+		INIT_COMPLETION(rmp->cb_completion);
+		SMP2P_SET_RMT_CMD_TYPE(test_request, 1);
+		SMP2P_SET_RMT_CMD(test_request, SMP2P_LB_CMD_PINGPONG);
+		SMP2P_SET_RMT_DATA(test_request, 10);
+		rmp->remote_item.entries[0].entry = test_request;
+		rmp->tx_interrupt();
+		UT_ASSERT_INT(
+			(int)wait_for_completion_timeout(
+					&rmp->cb_completion, HZ / 2),
+			>, 0);
+
+		/* Verify PINGPONG Response */
+		UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 1);
+		ret = msm_smp2p_out_read(local, &test_response);
+		UT_ASSERT_INT(ret, ==, 0);
+		test_response = SMP2P_GET_RMT_DATA(test_response);
+		UT_ASSERT_INT(test_response, ==, 9);
+
+		/* Send CLEARALL command */
+		test_request = 0;
+		test_response = 0;
+		rmp->rx_interrupt_count = 0;
+		INIT_COMPLETION(rmp->cb_completion);
+		SMP2P_SET_RMT_CMD_TYPE(test_request, 1);
+		SMP2P_SET_RMT_CMD(test_request, SMP2P_LB_CMD_CLEARALL);
+		SMP2P_SET_RMT_DATA(test_request, 10);
+		rmp->remote_item.entries[0].entry = test_request;
+		rmp->tx_interrupt();
+		UT_ASSERT_INT(
+			(int)wait_for_completion_timeout(
+					&rmp->cb_completion, HZ / 2),
+			>, 0);
+
+		/* Verify CLEARALL response */
+		UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 1);
+		ret = msm_smp2p_out_read(local, &test_response);
+		UT_ASSERT_INT(ret, ==, 0);
+		test_response = SMP2P_GET_RMT_DATA(test_response);
+		UT_ASSERT_INT(test_response, ==, 0);
+
+		ret = msm_smp2p_deinit_rmt_lpb_proc(SMP2P_REMOTE_MOCK_PROC);
+		UT_ASSERT_INT(ret, ==, 0);
+		seq_printf(s, "\tOK\n");
+	} while (0);
+
+	if (failed) {
+		pr_err("%s: Failed\n", __func__);
+		seq_printf(s, "\tFailed\n");
+		msm_smp2p_deinit_rmt_lpb_proc(SMP2P_REMOTE_MOCK_PROC);
+	}
+}
+
+/**
+ * smp2p_ut_remote_inout_core - Verify inbound/outbound functionality.
+ *
+ * @s: pointer to output file
+ * @remote_pid:  Remote processor to test
+ *
+ * This test verifies inbound/outbound functionality for the remote processor.
+ */
+static void smp2p_ut_remote_inout_core(struct seq_file *s, int remote_pid)
+{
+	int failed = 0;
+	struct msm_smp2p_out *handle;
+	int ret;
+	uint32_t test_request;
+	uint32_t test_response = 0;
+	static struct mock_cb_data cb_out;
+	static struct mock_cb_data cb_in;
+
+	seq_printf(s, "Running %s for '%s' remote pid %d\n",
+		   __func__, smp2p_pid_to_name(remote_pid), remote_pid);
+	mock_cb_data_init(&cb_out);
+	mock_cb_data_init(&cb_in);
+	do {
+		/* Open output entry */
+		ret = msm_smp2p_out_open(remote_pid, "smp2p",
+			&cb_out.nb, &handle);
+		UT_ASSERT_INT(ret, ==, 0);
+		UT_ASSERT_INT(
+			(int)wait_for_completion_timeout(
+					&cb_out.cb_completion, HZ / 2),
+			>, 0);
+		UT_ASSERT_INT(cb_out.cb_count, ==, 1);
+		UT_ASSERT_INT(cb_out.event_open, ==, 1);
+
+		/* Open inbound entry */
+		ret = msm_smp2p_in_register(remote_pid, "smp2p",
+				&cb_in.nb);
+		UT_ASSERT_INT(ret, ==, 0);
+		UT_ASSERT_INT(
+			(int)wait_for_completion_timeout(
+					&cb_in.cb_completion, HZ / 2),
+			>, 0);
+		UT_ASSERT_INT(cb_in.cb_count, ==, 1);
+		UT_ASSERT_INT(cb_in.event_open, ==, 1);
+
+		/* Write an echo request */
+		mock_cb_data_reset(&cb_out);
+		mock_cb_data_reset(&cb_in);
+		test_request = 0x0;
+		SMP2P_SET_RMT_CMD_TYPE(test_request, 1);
+		SMP2P_SET_RMT_CMD(test_request, SMP2P_LB_CMD_ECHO);
+		SMP2P_SET_RMT_DATA(test_request, 0xAA55);
+		ret = msm_smp2p_out_write(handle, test_request);
+		UT_ASSERT_INT(ret, ==, 0);
+
+		/* Verify inbound reply */
+		UT_ASSERT_INT(
+			(int)wait_for_completion_timeout(
+					&cb_in.cb_completion, HZ / 2),
+			>, 0);
+		UT_ASSERT_INT(cb_in.cb_count, ==, 1);
+		UT_ASSERT_INT(cb_in.event_entry_update, ==, 1);
+		UT_ASSERT_INT(SMP2P_GET_RMT_DATA(
+			    cb_in.entry_data.current_value), ==, 0xAA55);
+
+		ret = msm_smp2p_in_read(remote_pid, "smp2p", &test_response);
+		UT_ASSERT_INT(ret, ==, 0);
+		UT_ASSERT_INT(0, ==, SMP2P_GET_RMT_CMD_TYPE(test_response));
+		UT_ASSERT_INT(SMP2P_LB_CMD_ECHO, ==,
+				SMP2P_GET_RMT_CMD(test_response));
+		UT_ASSERT_INT(0xAA55, ==, SMP2P_GET_RMT_DATA(test_response));
+
+		/* Write a clear all request */
+		mock_cb_data_reset(&cb_in);
+		test_request = 0x0;
+		SMP2P_SET_RMT_CMD_TYPE(test_request, 1);
+		SMP2P_SET_RMT_CMD(test_request, SMP2P_LB_CMD_CLEARALL);
+		SMP2P_SET_RMT_DATA(test_request, 0xAA55);
+		ret = msm_smp2p_out_write(handle, test_request);
+		UT_ASSERT_INT(ret, ==, 0);
+
+		/* Verify inbound reply */
+		UT_ASSERT_INT(
+			(int)wait_for_completion_timeout(
+					&cb_in.cb_completion, HZ / 2),
+			>, 0);
+		UT_ASSERT_INT(cb_in.cb_count, ==, 1);
+		UT_ASSERT_INT(cb_in.event_entry_update, ==, 1);
+		UT_ASSERT_INT(SMP2P_GET_RMT_DATA(
+			    cb_in.entry_data.current_value), ==, 0x0000);
+
+		ret = msm_smp2p_in_read(remote_pid, "smp2p", &test_response);
+		UT_ASSERT_INT(ret, ==, 0);
+		UT_ASSERT_INT(0, ==, SMP2P_GET_RMT_CMD_TYPE(test_response));
+		UT_ASSERT_INT(0x0000, ==, SMP2P_GET_RMT_DATA(test_response));
+
+		/* Write a decrement request */
+		mock_cb_data_reset(&cb_in);
+		test_request = 0x0;
+		SMP2P_SET_RMT_CMD_TYPE(test_request, 1);
+		SMP2P_SET_RMT_CMD(test_request, SMP2P_LB_CMD_PINGPONG);
+		SMP2P_SET_RMT_DATA(test_request, 0xAA55);
+		ret = msm_smp2p_out_write(handle, test_request);
+		UT_ASSERT_INT(ret, ==, 0);
+
+		/* Verify inbound reply */
+		UT_ASSERT_INT(
+			(int)wait_for_completion_timeout(
+					&cb_in.cb_completion, HZ / 2),
+			>, 0);
+		UT_ASSERT_INT(cb_in.cb_count, ==, 1);
+		UT_ASSERT_INT(cb_in.event_entry_update, ==, 1);
+		UT_ASSERT_INT(SMP2P_GET_RMT_DATA(
+			    cb_in.entry_data.current_value), ==, 0xAA54);
+
+		ret = msm_smp2p_in_read(remote_pid, "smp2p", &test_response);
+		UT_ASSERT_INT(ret, ==, 0);
+		UT_ASSERT_INT(0, ==, SMP2P_GET_RMT_CMD_TYPE(test_response));
+		UT_ASSERT_INT(SMP2P_LB_CMD_PINGPONG, ==,
+				SMP2P_GET_RMT_CMD(test_response));
+		UT_ASSERT_INT(0xAA54, ==, SMP2P_GET_RMT_DATA(test_response));
+
+		/* Test the ignore flag */
+		mock_cb_data_reset(&cb_in);
+		test_request = 0x0;
+		SMP2P_SET_RMT_CMD_TYPE(test_request, 1);
+		SMP2P_SET_RMT_CMD(test_request, SMP2P_RLPB_IGNORE);
+		SMP2P_SET_RMT_DATA(test_request, 0xAA55);
+		ret = msm_smp2p_out_write(handle, test_request);
+		UT_ASSERT_INT(ret, ==, 0);
+
+		UT_ASSERT_INT(
+			(int)wait_for_completion_timeout(
+					&cb_in.cb_completion, HZ / 2),
+			==, 0);
+		UT_ASSERT_INT(cb_in.cb_count, ==, 0);
+		UT_ASSERT_INT(cb_in.event_entry_update, ==, 0);
+		ret = msm_smp2p_in_read(remote_pid, "smp2p", &test_response);
+		UT_ASSERT_INT(ret, ==, 0);
+		UT_ASSERT_INT(0xAA54, ==, SMP2P_GET_RMT_DATA(test_response));
+
+		/* Cleanup */
+		ret = msm_smp2p_out_close(&handle);
+		UT_ASSERT_INT(ret, ==, 0);
+		UT_ASSERT_PTR(handle, ==, 0);
+		ret = msm_smp2p_in_unregister(remote_pid, "smp2p", &cb_in.nb);
+		UT_ASSERT_INT(ret, ==, 0);
+
+		seq_printf(s, "\tOK\n");
+	} while (0);
+
+	if (failed) {
+		if (handle)
+			(void)msm_smp2p_out_close(&handle);
+		(void)msm_smp2p_in_unregister(remote_pid, "smp2p", &cb_in.nb);
+
+		pr_err("%s: Failed\n", __func__);
+		seq_printf(s, "\tFailed\n");
+	}
+}
+
+/**
+ * smp2p_ut_remote_inout - Verify inbound/outbound functionality for all.
+ *
+ * @s: pointer to output file
+ *
+ * This test verifies inbound and outbound functionality for all
+ * configured remote processor.
+ */
+static void smp2p_ut_remote_inout(struct seq_file *s)
+{
+	struct smp2p_interrupt_config *int_cfg;
+	int pid;
+
+	int_cfg = smp2p_get_interrupt_config();
+	if (!int_cfg) {
+		seq_printf(s,
+			"Remote processor config unavailable\n");
+		return;
+	}
+
+	for (pid = 0; pid < SMP2P_NUM_PROCS; ++pid) {
+		if (!int_cfg[pid].is_configured)
+			continue;
+
+		msm_smp2p_deinit_rmt_lpb_proc(pid);
+		smp2p_ut_remote_inout_core(s, pid);
+		msm_smp2p_init_rmt_lpb_proc(pid);
+	}
+}
+
+/**
+ * smp2p_ut_remote_out_max_entries_core - Verify open functionality.
+ *
+ * @s: pointer to output file
+ * @remote_pid:  Remote processor for which the test is executed.
+ *
+ * This test verifies open functionality by creating maximum outbound entries.
+ */
+static void smp2p_ut_remote_out_max_entries_core(struct seq_file *s,
+	int remote_pid)
+{
+	int j = 0;
+	int failed = 0;
+	struct msm_smp2p_out *handle[SMP2P_MAX_ENTRY];
+	int ret;
+	static struct mock_cb_data cb_out[SMP2P_MAX_ENTRY];
+	char entry_name[SMP2P_MAX_ENTRY_NAME];
+	int num_created;
+
+	seq_printf(s, "Running %s for '%s' remote pid %d\n",
+		   __func__, smp2p_pid_to_name(remote_pid), remote_pid);
+
+	for (j = 0; j < SMP2P_MAX_ENTRY; j++) {
+		handle[j] = NULL;
+		mock_cb_data_init(&cb_out[j]);
+	}
+
+	do {
+		num_created = 0;
+		for (j = 0; j < SMP2P_MAX_ENTRY; j++) {
+			/* Open as many output entries as possible */
+			scnprintf((char *)entry_name, SMP2P_MAX_ENTRY_NAME,
+				"smp2p%d", j);
+			ret = msm_smp2p_out_open(remote_pid, entry_name,
+				&cb_out[j].nb, &handle[j]);
+			if (ret == -ENOMEM)
+				/* hit max number */
+				break;
+			UT_ASSERT_INT(ret, ==, 0);
+			++num_created;
+		}
+		if (failed)
+			break;
+
+		/* verify we created more than 1 entry */
+		UT_ASSERT_INT(num_created, <=, SMP2P_MAX_ENTRY);
+		UT_ASSERT_INT(num_created, >, 0);
+
+		seq_printf(s, "\tOK\n");
+	} while (0);
+
+	if (failed) {
+		pr_err("%s: Failed\n", __func__);
+		seq_printf(s, "\tFailed\n");
+	}
+
+	/* cleanup */
+	for (j = 0; j < SMP2P_MAX_ENTRY; j++)
+		ret = msm_smp2p_out_close(&handle[j]);
+}
+
+/**
+ * smp2p_ut_remote_out_max_entries - Verify open for all configured processors.
+ *
+ * @s: pointer to output file
+ *
+ * This test verifies creating max number of entries for
+ * all configured remote processor.
+ */
+static void smp2p_ut_remote_out_max_entries(struct seq_file *s)
+{
+	struct smp2p_interrupt_config *int_cfg;
+	int pid;
+
+	int_cfg = smp2p_get_interrupt_config();
+	if (!int_cfg) {
+		seq_printf(s,
+			"Remote processor config unavailable\n");
+		return;
+	}
+
+	for (pid = 0; pid < SMP2P_NUM_PROCS; ++pid) {
+		if (!int_cfg[pid].is_configured)
+			continue;
+
+		smp2p_ut_remote_out_max_entries_core(s, pid);
+	}
+}
+
+/**
+ * smp2p_ut_local_in_max_entries - Verify registering and unregistering.
+ *
+ * @s: pointer to output file
+ *
+ * This test verifies registering and unregistering for inbound entries using
+ * the remote mock processor.
+ */
+static void smp2p_ut_local_in_max_entries(struct seq_file *s)
+{
+	int j = 0;
+	int failed = 0;
+	struct msm_smp2p_remote_mock *rmp = NULL;
+	int ret;
+	static struct mock_cb_data cb_in[SMP2P_MAX_ENTRY];
+	static struct mock_cb_data cb_out;
+
+	seq_printf(s, "Running %s\n", __func__);
+
+	for (j = 0; j < SMP2P_MAX_ENTRY; j++)
+		mock_cb_data_init(&cb_in[j]);
+
+	mock_cb_data_init(&cb_out);
+
+	do {
+		/* Initialize mock edge */
+		ret = smp2p_reset_mock_edge();
+		UT_ASSERT_INT(ret, ==, 0);
+
+		rmp = msm_smp2p_get_remote_mock();
+		UT_ASSERT_PTR(rmp, !=, NULL);
+
+		rmp->rx_interrupt_count = 0;
+		memset(&rmp->remote_item, 0,
+			sizeof(struct smp2p_smem_item));
+		rmp->remote_item.header.magic = SMP2P_MAGIC;
+		SMP2P_SET_LOCAL_PID(
+		rmp->remote_item.header.rem_loc_proc_id,
+						SMP2P_REMOTE_MOCK_PROC);
+		SMP2P_SET_REMOTE_PID(
+		rmp->remote_item.header.rem_loc_proc_id,
+						SMP2P_APPS_PROC);
+		SMP2P_SET_VERSION(
+		rmp->remote_item.header.feature_version, 1);
+		SMP2P_SET_FEATURES(
+		rmp->remote_item.header.feature_version, 0);
+		SMP2P_SET_ENT_TOTAL(
+		rmp->remote_item.header.valid_total_ent, SMP2P_MAX_ENTRY);
+		SMP2P_SET_ENT_VALID(
+		rmp->remote_item.header.valid_total_ent, 0);
+		rmp->remote_item.header.reserved = 0x0;
+		msm_smp2p_set_remote_mock_exists(true);
+
+		/* Create Max Entries in the remote mock object */
+		for (j = 0; j < SMP2P_MAX_ENTRY; j++) {
+			scnprintf(rmp->remote_item.entries[j].name,
+				SMP2P_MAX_ENTRY_NAME, "smp2p%d", j);
+			rmp->remote_item.entries[j].entry = 0;
+			rmp->tx_interrupt();
+		}
+
+		/* Register for in entries */
+		for (j = 0; j < SMP2P_MAX_ENTRY; j++) {
+			ret = msm_smp2p_in_register(SMP2P_REMOTE_MOCK_PROC,
+				rmp->remote_item.entries[j].name,
+				&(cb_in[j].nb));
+			UT_ASSERT_INT(ret, ==, 0);
+			UT_ASSERT_INT(
+				(int)wait_for_completion_timeout(
+					&(cb_in[j].cb_completion), HZ / 2),
+				>, 0);
+			UT_ASSERT_INT(cb_in[j].cb_count, ==, 1);
+			UT_ASSERT_INT(cb_in[j].event_entry_update, ==, 0);
+		}
+		UT_ASSERT_INT(j, ==, SMP2P_MAX_ENTRY);
+
+		/* Unregister */
+		for (j = 0; j < SMP2P_MAX_ENTRY; j++) {
+			ret = msm_smp2p_in_unregister(SMP2P_REMOTE_MOCK_PROC,
+				rmp->remote_item.entries[j].name,
+				&(cb_in[j].nb));
+		    UT_ASSERT_INT(ret, ==, 0);
+		}
+		UT_ASSERT_INT(j, ==, SMP2P_MAX_ENTRY);
+
+		seq_printf(s, "\tOK\n");
+	} while (0);
+
+	if (failed) {
+		pr_err("%s: Failed\n", __func__);
+		seq_printf(s, "\tFailed\n");
+
+		for (j = 0; j < SMP2P_MAX_ENTRY; j++)
+			ret = msm_smp2p_in_unregister(SMP2P_REMOTE_MOCK_PROC,
+				rmp->remote_item.entries[j].name,
+				&(cb_in[j].nb));
+	}
+}
+
+/**
+ * smp2p_ut_local_in_multiple - Verify Multiple Inbound Registration.
+ *
+ * @s: pointer to output file
+ *
+ * This test verifies multiple clients registering for same inbound entries
+ * using the remote mock processor.
+ */
+static void smp2p_ut_local_in_multiple(struct seq_file *s)
+{
+	int failed = 0;
+	struct msm_smp2p_remote_mock *rmp = NULL;
+	int ret;
+	static struct mock_cb_data cb_in_1;
+	static struct mock_cb_data cb_in_2;
+	static struct mock_cb_data cb_out;
+
+	seq_printf(s, "Running %s\n", __func__);
+
+	mock_cb_data_init(&cb_in_1);
+	mock_cb_data_init(&cb_in_2);
+	mock_cb_data_init(&cb_out);
+
+	do {
+		/* Initialize mock edge */
+		ret = smp2p_reset_mock_edge();
+		UT_ASSERT_INT(ret, ==, 0);
+
+		rmp = msm_smp2p_get_remote_mock();
+		UT_ASSERT_PTR(rmp, !=, NULL);
+
+		rmp->rx_interrupt_count = 0;
+		memset(&rmp->remote_item, 0,
+			sizeof(struct smp2p_smem_item));
+		rmp->remote_item.header.magic = SMP2P_MAGIC;
+		SMP2P_SET_LOCAL_PID(
+		rmp->remote_item.header.rem_loc_proc_id,
+						SMP2P_REMOTE_MOCK_PROC);
+		SMP2P_SET_REMOTE_PID(
+		rmp->remote_item.header.rem_loc_proc_id,
+						SMP2P_APPS_PROC);
+		SMP2P_SET_VERSION(
+		rmp->remote_item.header.feature_version, 1);
+		SMP2P_SET_FEATURES(
+		rmp->remote_item.header.feature_version, 0);
+		SMP2P_SET_ENT_TOTAL(
+		rmp->remote_item.header.valid_total_ent, 1);
+		SMP2P_SET_ENT_VALID(
+		rmp->remote_item.header.valid_total_ent, 0);
+		rmp->remote_item.header.reserved = 0x0;
+		msm_smp2p_set_remote_mock_exists(true);
+
+		/* Create an Entry in the remote mock object */
+		scnprintf(rmp->remote_item.entries[0].name,
+				SMP2P_MAX_ENTRY_NAME, "smp2p%d", 1);
+		rmp->remote_item.entries[0].entry = 0;
+		rmp->tx_interrupt();
+
+		/* Register multiple clients for the inbound entry */
+		ret = msm_smp2p_in_register(SMP2P_REMOTE_MOCK_PROC,
+				rmp->remote_item.entries[0].name,
+				&cb_in_1.nb);
+		UT_ASSERT_INT(ret, ==, 0);
+		UT_ASSERT_INT(
+				(int)wait_for_completion_timeout(
+				&(cb_in_1.cb_completion), HZ / 2),
+				>, 0);
+		UT_ASSERT_INT(cb_in_1.cb_count, ==, 1);
+		UT_ASSERT_INT(cb_in_1.event_entry_update, ==, 0);
+
+		ret = msm_smp2p_in_register(SMP2P_REMOTE_MOCK_PROC,
+				rmp->remote_item.entries[0].name,
+				&cb_in_2.nb);
+		UT_ASSERT_INT(ret, ==, 0);
+		UT_ASSERT_INT(
+				(int)wait_for_completion_timeout(
+				&(cb_in_2.cb_completion), HZ / 2),
+				>, 0);
+		UT_ASSERT_INT(cb_in_2.cb_count, ==, 1);
+		UT_ASSERT_INT(cb_in_2.event_entry_update, ==, 0);
+
+
+		/* Unregister the clients */
+		ret = msm_smp2p_in_unregister(SMP2P_REMOTE_MOCK_PROC,
+				rmp->remote_item.entries[0].name,
+				&(cb_in_1.nb));
+		UT_ASSERT_INT(ret, ==, 0);
+
+		ret = msm_smp2p_in_unregister(SMP2P_REMOTE_MOCK_PROC,
+				rmp->remote_item.entries[0].name,
+				&(cb_in_2.nb));
+		UT_ASSERT_INT(ret, ==, 0);
+
+		seq_printf(s, "\tOK\n");
+	} while (0);
+
+	if (failed) {
+		pr_err("%s: Failed\n", __func__);
+		seq_printf(s, "\tFailed\n");
+
+		ret = msm_smp2p_in_unregister(SMP2P_REMOTE_MOCK_PROC,
+				rmp->remote_item.entries[0].name,
+				&(cb_in_1.nb));
+
+		ret = msm_smp2p_in_unregister(SMP2P_REMOTE_MOCK_PROC,
+				rmp->remote_item.entries[0].name,
+				&(cb_in_2.nb));
+	}
+}
+
+static struct dentry *dent;
+
+static int debugfs_show(struct seq_file *s, void *data)
+{
+	void (*show)(struct seq_file *) = s->private;
+
+	show(s);
+
+	return 0;
+}
+
+static int debug_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, debugfs_show, inode->i_private);
+}
+
+static const struct file_operations debug_ops = {
+	.open = debug_open,
+	.release = single_release,
+	.read = seq_read,
+	.llseek = seq_lseek,
+};
+
+void smp2p_debug_create(const char *name,
+			 void (*show)(struct seq_file *))
+{
+	struct dentry *file;
+
+	file = debugfs_create_file(name, 0444, dent, show, &debug_ops);
+	if (!file)
+		pr_err("%s: unable to create file '%s'\n", __func__, name);
+}
+
+static int __init smp2p_debugfs_init(void)
+{
+	dent = debugfs_create_dir("smp2p_test", 0);
+	if (IS_ERR(dent))
+		return PTR_ERR(dent);
+
+	/*
+	 * Add Unit Test entries.
+	 *
+	 * The idea with unit tests is that you can run all of them
+	 * from ADB shell by doing:
+	 *  adb shell
+	 *  cat ut*
+	 *
+	 * And if particular tests fail, you can then repeatedly run the
+	 * failing tests as you debug and resolve the failing test.
+	 */
+	smp2p_debug_create("ut_local_basic",
+			smp2p_ut_local_basic);
+	smp2p_debug_create("ut_local_late_open",
+			smp2p_ut_local_late_open);
+	smp2p_debug_create("ut_local_early_open",
+			smp2p_ut_local_early_open);
+	smp2p_debug_create("ut_mock_loopback",
+			smp2p_ut_mock_loopback);
+	smp2p_debug_create("ut_remote_inout",
+			smp2p_ut_remote_inout);
+	smp2p_debug_create("ut_local_in_max_entries",
+		smp2p_ut_local_in_max_entries);
+	smp2p_debug_create("ut_remote_out_max_entries",
+			smp2p_ut_remote_out_max_entries);
+	smp2p_debug_create("ut_local_in_multiple",
+			smp2p_ut_local_in_multiple);
+
+	return 0;
+}
+module_init(smp2p_debugfs_init);
diff --git a/arch/arm/mach-msm/smp2p_test_common.h b/arch/arm/mach-msm/smp2p_test_common.h
new file mode 100644
index 0000000..b9cddc4
--- /dev/null
+++ b/arch/arm/mach-msm/smp2p_test_common.h
@@ -0,0 +1,217 @@
+/* arch/arm/mach-msm/smp2p_test_common.h
+ *
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef _ARCH_ARM_MACH_MSM_SMP2P_TEST_COMMON_H_
+#define _ARCH_ARM_MACH_MSM_SMP2P_TEST_COMMON_H_
+
+#include <linux/debugfs.h>
+
+/**
+ * Unit test assertion for logging test cases.
+ *
+ * @a lval
+ * @b rval
+ * @cmp comparison operator
+ *
+ * Assertion fails if (@a cmp @b) is not true which then
+ * logs the function and line number where the error occurred
+ * along with the values of @a and @b.
+ *
+ * Assumes that the following local variables exist:
+ * @s - sequential output file pointer
+ * @failed - set to true if test fails
+ */
+#define UT_ASSERT_INT(a, cmp, b) \
+	{ \
+	int a_tmp = (a); \
+	int b_tmp = (b); \
+	if (!((a_tmp)cmp(b_tmp))) { \
+		seq_printf(s, \
+			"%s:%d Fail: " #a "(%d) " #cmp " " #b "(%d)\n", \
+				__func__, __LINE__, \
+				a_tmp, b_tmp); \
+		failed = 1; \
+		break; \
+	} \
+	}
+
+#define UT_ASSERT_PTR(a, cmp, b) \
+	{ \
+	void *a_tmp = (a); \
+	void *b_tmp = (b); \
+	if (!((a_tmp)cmp(b_tmp))) { \
+		seq_printf(s, \
+			"%s:%d Fail: " #a "(%p) " #cmp " " #b "(%p)\n", \
+				__func__, __LINE__, \
+				a_tmp, b_tmp); \
+		failed = 1; \
+		break; \
+	} \
+	}
+
+#define UT_ASSERT_UINT(a, cmp, b) \
+	{ \
+	unsigned a_tmp = (a); \
+	unsigned b_tmp = (b); \
+	if (!((a_tmp)cmp(b_tmp))) { \
+		seq_printf(s, \
+			"%s:%d Fail: " #a "(%u) " #cmp " " #b "(%u)\n", \
+				__func__, __LINE__, \
+				a_tmp, b_tmp); \
+		failed = 1; \
+		break; \
+	} \
+	}
+
+#define UT_ASSERT_HEX(a, cmp, b) \
+	{ \
+	unsigned a_tmp = (a); \
+	unsigned b_tmp = (b); \
+	if (!((a_tmp)cmp(b_tmp))) { \
+		seq_printf(s, \
+			"%s:%d Fail: " #a "(%x) " #cmp " " #b "(%x)\n", \
+				__func__, __LINE__, \
+				a_tmp, b_tmp); \
+		failed = 1; \
+		break; \
+	} \
+	}
+
+/**
+ * In-range unit test assertion for test cases.
+ *
+ * @a lval
+ * @minv Minimum value
+ * @maxv Maximum value
+ *
+ * Assertion fails if @a is not on the exclusive range minv, maxv
+ * ((@a < @minv) or (@a > @maxv)).  In the failure case, the macro
+ * logs the function and line number where the error occurred along
+ * with the values of @a and @minv, @maxv.
+ *
+ * Assumes that the following local variables exist:
+ * @s - sequential output file pointer
+ * @failed - set to true if test fails
+ */
+#define UT_ASSERT_INT_IN_RANGE(a, minv, maxv) \
+	{ \
+	int a_tmp = (a); \
+	int minv_tmp = (minv); \
+	int maxv_tmp = (maxv); \
+	if (((a_tmp) < (minv_tmp)) || ((a_tmp) > (maxv_tmp))) { \
+		seq_printf(s, \
+			"%s:%d Fail: " #a "(%d) < " #minv "(%d) or " \
+				 #a "(%d) > " #maxv "(%d)\n", \
+				__func__, __LINE__, \
+				a_tmp, minv_tmp, a_tmp, maxv_tmp); \
+		failed = 1; \
+		break; \
+	} \
+	}
+
+/* Structure to track state changes for the notifier callback. */
+struct mock_cb_data {
+	bool initialized;
+	spinlock_t lock;
+	struct notifier_block nb;
+
+	/* events */
+	struct completion cb_completion;
+	int cb_count;
+	int event_open;
+	int event_entry_update;
+	struct msm_smp2p_update_notif entry_data;
+};
+
+void smp2p_debug_create(const char *name, void (*show)(struct seq_file *));
+static inline int smp2p_test_notify(struct notifier_block *self,
+	unsigned long event, void *data);
+
+/**
+ * Reset mock callback data to default values.
+ *
+ * @cb:  Mock callback data
+ */
+static inline void mock_cb_data_reset(struct mock_cb_data *cb)
+{
+	INIT_COMPLETION(cb->cb_completion);
+	cb->cb_count = 0;
+	cb->event_open = 0;
+	cb->event_entry_update = 0;
+	memset(&cb->entry_data, 0,
+		sizeof(struct msm_smp2p_update_notif));
+}
+
+
+/**
+ * Initialize mock callback data.
+ *
+ * @cb:  Mock callback data
+ */
+static inline void mock_cb_data_init(struct mock_cb_data *cb)
+{
+	if (!cb->initialized) {
+		init_completion(&cb->cb_completion);
+		spin_lock_init(&cb->lock);
+		cb->initialized = true;
+		cb->nb.notifier_call = smp2p_test_notify;
+		memset(&cb->entry_data, 0,
+			sizeof(struct msm_smp2p_update_notif));
+	}
+	mock_cb_data_reset(cb);
+}
+
+/**
+ * Notifier function passed into SMP2P for testing.
+ *
+ * @self:       Pointer to calling notifier block
+ * @event:	    Event
+ * @data:       Event-specific data
+ * @returns:    0
+ */
+static inline int smp2p_test_notify(struct notifier_block *self,
+		unsigned long event, void *data)
+{
+	struct mock_cb_data *cb_data_ptr;
+	unsigned long flags;
+
+	cb_data_ptr = container_of(self, struct mock_cb_data, nb);
+
+	spin_lock_irqsave(&cb_data_ptr->lock, flags);
+
+	switch (event) {
+	case SMP2P_OPEN:
+		++cb_data_ptr->event_open;
+		if (data) {
+			cb_data_ptr->entry_data =
+			*(struct msm_smp2p_update_notif *)(data);
+		}
+		break;
+	case SMP2P_ENTRY_UPDATE:
+		++cb_data_ptr->event_entry_update;
+		if (data) {
+			cb_data_ptr->entry_data =
+			*(struct msm_smp2p_update_notif *)(data);
+		}
+		break;
+	default:
+		pr_err("%s Unknown event\n", __func__);
+		break;
+	}
+
+	++cb_data_ptr->cb_count;
+	complete(&cb_data_ptr->cb_completion);
+	spin_unlock_irqrestore(&cb_data_ptr->lock, flags);
+	return 0;
+}
+#endif /* _ARCH_ARM_MACH_MSM_SMP2P_TEST_COMMON_H_ */
diff --git a/arch/arm/mach-msm/socinfo.c b/arch/arm/mach-msm/socinfo.c
index 2743547..56623c9 100644
--- a/arch/arm/mach-msm/socinfo.c
+++ b/arch/arm/mach-msm/socinfo.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
@@ -15,9 +15,17 @@
  *
  */
 
-#include <linux/types.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/sys_soc.h>
+#include <linux/slab.h>
+#include <linux/stat.h>
 #include <linux/sysdev.h>
+#include <linux/types.h>
+
 #include <asm/mach-types.h>
+
 #include <mach/socinfo.h>
 
 #include "smd_private.h"
@@ -126,6 +134,16 @@
 	uint32_t pmic_die_revision;
 };
 
+struct socinfo_v8 {
+	struct socinfo_v7 v7;
+
+	/* only valid when format==8*/
+	uint32_t pmic_model_1;
+	uint32_t pmic_die_revision_1;
+	uint32_t pmic_model_2;
+	uint32_t pmic_die_revision_2;
+};
+
 static union {
 	struct socinfo_v1 v1;
 	struct socinfo_v2 v2;
@@ -134,6 +152,7 @@
 	struct socinfo_v5 v5;
 	struct socinfo_v6 v6;
 	struct socinfo_v7 v7;
+	struct socinfo_v8 v8;
 } *socinfo;
 
 static enum msm_cpu cpu_of_id[] = {
@@ -238,6 +257,7 @@
 	[117] = MSM_CPU_8930,
 	[118] = MSM_CPU_8930,
 	[119] = MSM_CPU_8930,
+	[179] = MSM_CPU_8930,
 
 	/* 8627 IDs */
 	[120] = MSM_CPU_8627,
@@ -273,7 +293,14 @@
 
 	/* 9625 IDs */
 	[134] = MSM_CPU_9625,
+	[148] = MSM_CPU_9625,
+	[149] = MSM_CPU_9625,
+	[150] = MSM_CPU_9625,
+	[151] = MSM_CPU_9625,
 	[152] = MSM_CPU_9625,
+	[173] = MSM_CPU_9625,
+	[174] = MSM_CPU_9625,
+	[175] = MSM_CPU_9625,
 
 	/* 8960AB IDs */
 	[138] = MSM_CPU_8960AB,
@@ -286,6 +313,7 @@
 	[143] = MSM_CPU_8930AA,
 	[144] = MSM_CPU_8930AA,
 	[160] = MSM_CPU_8930AA,
+	[180] = MSM_CPU_8930AA,
 
 	/* 8226 IDs */
 	[145] = MSM_CPU_8226,
@@ -293,8 +321,8 @@
 	/* 8092 IDs */
 	[146] = MSM_CPU_8092,
 
-	/* 8910 IDs */
-	[147] = MSM_CPU_8910,
+	/* 8610 IDs */
+	[147] = MSM_CPU_8610,
 
 	/* 8064AB IDs */
 	[153] = MSM_CPU_8064AB,
@@ -304,12 +332,15 @@
 	[155] = MSM_CPU_8930AB,
 	[156] = MSM_CPU_8930AB,
 	[157] = MSM_CPU_8930AB,
+	[181] = MSM_CPU_8930AB,
 
 	/* 8625Q IDs */
 	[168] = MSM_CPU_8625Q,
 	[169] = MSM_CPU_8625Q,
 	[170] = MSM_CPU_8625Q,
 
+	/* 8064AA IDs */
+	[172] = MSM_CPU_8064AA,
 
 	/* Uninitialized IDs are not known to run Linux.
 	   MSM_CPU_UNKNOWN is set to 0 to ensure these IDs are
@@ -399,6 +430,11 @@
 		: 0;
 }
 
+static uint32_t socinfo_get_format(void)
+{
+	return socinfo ? socinfo->v1.format : 0;
+}
+
 enum msm_cpu socinfo_get_msm_cpu(void)
 {
 	return cur_cpu;
@@ -607,6 +643,100 @@
 		socinfo_get_pmic_die_revision());
 }
 
+static ssize_t
+msm_get_vendor(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "Qualcomm\n");
+}
+
+static ssize_t
+msm_get_raw_id(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+		socinfo_get_raw_id());
+}
+
+static ssize_t
+msm_get_raw_version(struct device *dev,
+		     struct device_attribute *attr,
+		     char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+		socinfo_get_raw_version());
+}
+
+static ssize_t
+msm_get_build_id(struct device *dev,
+		   struct device_attribute *attr,
+		   char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%-.32s\n",
+			socinfo_get_build_id());
+}
+
+static ssize_t
+msm_get_hw_platform(struct device *dev,
+			struct device_attribute *attr,
+			char *buf)
+{
+	uint32_t hw_type;
+	hw_type = socinfo_get_platform_type();
+
+	return snprintf(buf, PAGE_SIZE, "%-.32s\n",
+			hw_platform[hw_type]);
+}
+
+static ssize_t
+msm_get_platform_version(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+		socinfo_get_platform_version());
+}
+
+static ssize_t
+msm_get_accessory_chip(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+		socinfo_get_accessory_chip());
+}
+
+static ssize_t
+msm_get_platform_subtype(struct device *dev,
+			struct device_attribute *attr,
+			char *buf)
+{
+	uint32_t hw_subtype;
+	hw_subtype = socinfo_get_platform_subtype();
+	return snprintf(buf, PAGE_SIZE, "%-.32s\n",
+		hw_platform_subtype[hw_subtype]);
+}
+
+static ssize_t
+msm_get_pmic_model(struct device *dev,
+			struct device_attribute *attr,
+			char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+		socinfo_get_pmic_model());
+}
+
+static ssize_t
+msm_get_pmic_die_revision(struct device *dev,
+			       struct device_attribute *attr,
+			       char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+			 socinfo_get_pmic_die_revision());
+}
+
 static struct sysdev_attribute socinfo_v1_files[] = {
 	_SYSDEV_ATTR(id, 0444, socinfo_show_id, NULL),
 	_SYSDEV_ATTR(version, 0444, socinfo_show_version, NULL),
@@ -644,6 +774,42 @@
 			socinfo_show_pmic_die_revision, NULL),
 };
 
+static struct device_attribute msm_soc_attr_raw_version =
+	__ATTR(raw_version, S_IRUGO, msm_get_raw_version,  NULL);
+
+static struct device_attribute msm_soc_attr_raw_id =
+	__ATTR(raw_id, S_IRUGO, msm_get_raw_id,  NULL);
+
+static struct device_attribute msm_soc_attr_vendor =
+	__ATTR(vendor, S_IRUGO, msm_get_vendor,  NULL);
+
+static struct device_attribute msm_soc_attr_build_id =
+	__ATTR(build_id, S_IRUGO, msm_get_build_id, NULL);
+
+static struct device_attribute msm_soc_attr_hw_platform =
+	__ATTR(hw_platform, S_IRUGO, msm_get_hw_platform, NULL);
+
+
+static struct device_attribute msm_soc_attr_platform_version =
+	__ATTR(platform_version, S_IRUGO,
+			msm_get_platform_version, NULL);
+
+static struct device_attribute msm_soc_attr_accessory_chip =
+	__ATTR(accessory_chip, S_IRUGO,
+			msm_get_accessory_chip, NULL);
+
+static struct device_attribute msm_soc_attr_platform_subtype =
+	__ATTR(platform_subtype, S_IRUGO,
+			msm_get_platform_subtype, NULL);
+
+static struct device_attribute msm_soc_attr_pmic_model =
+	__ATTR(pmic_model, S_IRUGO,
+			msm_get_pmic_model, NULL);
+
+static struct device_attribute msm_soc_attr_pmic_die_revision =
+	__ATTR(pmic_die_revision, S_IRUGO,
+			msm_get_pmic_die_revision, NULL);
+
 static struct sysdev_class soc_sysdev_class = {
 	.name = "soc",
 };
@@ -669,15 +835,124 @@
 	return 0;
 }
 
+static void * __init setup_dummy_socinfo(void)
+{
+	if (machine_is_msm8960_cdp())
+		dummy_socinfo.id = 87;
+	else if (machine_is_msm9615_mtp() || machine_is_msm9615_cdp())
+		dummy_socinfo.id = 104;
+	else if (early_machine_is_msm8974()) {
+		dummy_socinfo.id = 126;
+		strlcpy(dummy_socinfo.build_id, "msm8974 - ",
+			sizeof(dummy_socinfo.build_id));
+	} else if (early_machine_is_msm9625()) {
+		dummy_socinfo.id = 134;
+		strlcpy(dummy_socinfo.build_id, "msm9625 - ",
+			sizeof(dummy_socinfo.build_id));
+	} else if (early_machine_is_msm8226()) {
+		dummy_socinfo.id = 145;
+		strlcpy(dummy_socinfo.build_id, "msm8226 - ",
+			sizeof(dummy_socinfo.build_id));
+	} else if (machine_is_msm8625_rumi3())
+		dummy_socinfo.id = 127;
+	else if (early_machine_is_mpq8092()) {
+		dummy_socinfo.id = 146;
+		strlcpy(dummy_socinfo.build_id, "mpq8092 - ",
+		sizeof(dummy_socinfo.build_id));
+	} else if (early_machine_is_msm8610()) {
+		dummy_socinfo.id = 147;
+		strlcpy(dummy_socinfo.build_id, "msm8610 - ",
+			sizeof(dummy_socinfo.build_id));
+	}
+	strlcat(dummy_socinfo.build_id, "Dummy socinfo",
+		sizeof(dummy_socinfo.build_id));
+	return (void *) &dummy_socinfo;
+}
+
+static void __init populate_soc_sysfs_files(struct device *msm_soc_device)
+{
+	uint32_t legacy_format = socinfo_get_format();
+
+	device_create_file(msm_soc_device, &msm_soc_attr_vendor);
+
+	switch (legacy_format) {
+	case 8:
+	case 7:
+		device_create_file(msm_soc_device,
+					&msm_soc_attr_pmic_model);
+		device_create_file(msm_soc_device,
+					&msm_soc_attr_pmic_die_revision);
+	case 6:
+		device_create_file(msm_soc_device,
+					&msm_soc_attr_platform_subtype);
+	case 5:
+		device_create_file(msm_soc_device,
+					&msm_soc_attr_accessory_chip);
+	case 4:
+		device_create_file(msm_soc_device,
+					&msm_soc_attr_platform_version);
+	case 3:
+		device_create_file(msm_soc_device,
+					&msm_soc_attr_hw_platform);
+	case 2:
+		device_create_file(msm_soc_device,
+					&msm_soc_attr_raw_id);
+		device_create_file(msm_soc_device,
+					&msm_soc_attr_raw_version);
+	case 1:
+		device_create_file(msm_soc_device,
+					&msm_soc_attr_build_id);
+		break;
+	default:
+		pr_err("%s:Unknown socinfo format:%u\n", __func__,
+				legacy_format);
+		break;
+	}
+
+	return;
+}
+
+static void  __init soc_info_populate(struct soc_device_attribute *soc_dev_attr)
+{
+	uint32_t soc_version = socinfo_get_version();
+
+	soc_dev_attr->soc_id   = kasprintf(GFP_KERNEL, "%d", socinfo_get_id());
+	soc_dev_attr->machine  = "Snapdragon";
+	soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%u.%u",
+			SOCINFO_VERSION_MAJOR(soc_version),
+			SOCINFO_VERSION_MINOR(soc_version));
+	return;
+
+}
+
 static int __init socinfo_init_sysdev(void)
 {
 	int err;
+	struct device *msm_soc_device;
+	struct soc_device *soc_dev;
+	struct soc_device_attribute *soc_dev_attr;
 
 	if (!socinfo) {
 		pr_err("%s: No socinfo found!\n", __func__);
 		return -ENODEV;
 	}
 
+	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+	if (!soc_dev_attr) {
+		pr_err("%s: Soc Device alloc failed!\n", __func__);
+		return -ENOMEM;
+	}
+
+	soc_info_populate(soc_dev_attr);
+	soc_dev = soc_device_register(soc_dev_attr);
+	if (IS_ERR_OR_NULL(soc_dev)) {
+		kfree(soc_dev_attr);
+		 pr_err("%s: Soc device register failed\n", __func__);
+		 return -EIO;
+	}
+
+	msm_soc_device = soc_device_to_device(soc_dev);
+	populate_soc_sysfs_files(msm_soc_device);
 	err = sysdev_class_register(&soc_sysdev_class);
 	if (err) {
 		pr_err("%s: sysdev_class_register fail (%d)\n",
@@ -724,87 +999,16 @@
 	if (socinfo->v1.format < 7)
 		return err;
 
-	return socinfo_create_files(&soc_sys_device, socinfo_v7_files,
+	socinfo_create_files(&soc_sys_device, socinfo_v7_files,
 				ARRAY_SIZE(socinfo_v7_files));
+
+	return 0;
 }
 
 arch_initcall(socinfo_init_sysdev);
 
-static void * __init setup_dummy_socinfo(void)
+static void socinfo_print(void)
 {
-	if (machine_is_msm8960_cdp())
-		dummy_socinfo.id = 87;
-	else if (machine_is_msm9615_mtp() || machine_is_msm9615_cdp())
-		dummy_socinfo.id = 104;
-	else if (early_machine_is_msm8974()) {
-		dummy_socinfo.id = 126;
-		strlcpy(dummy_socinfo.build_id, "msm8974 - ",
-			sizeof(dummy_socinfo.build_id));
-	} else if (early_machine_is_msm9625()) {
-		dummy_socinfo.id = 134;
-		strlcpy(dummy_socinfo.build_id, "msm9625 - ",
-			sizeof(dummy_socinfo.build_id));
-	} else if (early_machine_is_msm8226()) {
-		dummy_socinfo.id = 145;
-		strlcpy(dummy_socinfo.build_id, "msm8226 - ",
-			sizeof(dummy_socinfo.build_id));
-	} else if (machine_is_msm8625_rumi3())
-		dummy_socinfo.id = 127;
-	else if (early_machine_is_mpq8092()) {
-		dummy_socinfo.id = 146;
-		strlcpy(dummy_socinfo.build_id, "mpq8092 - ",
-		sizeof(dummy_socinfo.build_id));
-	} else if (early_machine_is_msm8910()) {
-		dummy_socinfo.id = 147;
-		strlcpy(dummy_socinfo.build_id, "msm8910 - ",
-			sizeof(dummy_socinfo.build_id));
-	}
-	strlcat(dummy_socinfo.build_id, "Dummy socinfo",
-		sizeof(dummy_socinfo.build_id));
-	return (void *) &dummy_socinfo;
-}
-
-int __init socinfo_init(void)
-{
-	socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID, sizeof(struct socinfo_v7));
-
-	if (!socinfo)
-		socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
-				sizeof(struct socinfo_v6));
-
-	if (!socinfo)
-		socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
-				sizeof(struct socinfo_v5));
-
-	if (!socinfo)
-		socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
-				sizeof(struct socinfo_v4));
-
-	if (!socinfo)
-		socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
-				sizeof(struct socinfo_v3));
-
-	if (!socinfo)
-		socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
-				sizeof(struct socinfo_v2));
-
-	if (!socinfo)
-		socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
-				sizeof(struct socinfo_v1));
-
-	if (!socinfo) {
-		pr_warn("%s: Can't find SMEM_HW_SW_BUILD_ID; falling back on "
-			"dummy values.\n", __func__);
-		socinfo = setup_dummy_socinfo();
-	}
-
-	WARN(!socinfo_get_id(), "Unknown SOC ID!\n");
-	WARN(socinfo_get_id() >= ARRAY_SIZE(cpu_of_id),
-		"New IDs added! ID => CPU mapping might need an update.\n");
-
-	if (socinfo->v1.id < ARRAY_SIZE(cpu_of_id))
-		cur_cpu = cpu_of_id[socinfo->v1.id];
-
 	switch (socinfo->v1.format) {
 	case 1:
 		pr_info("%s: v%u, id=%u, ver=%u.%u\n",
@@ -862,6 +1066,7 @@
 			socinfo->v5.accessory_chip,
 			socinfo->v6.hw_platform_subtype);
 		break;
+	case 8:
 	case 7:
 		pr_info("%s: v%u, id=%u, ver=%u.%u, raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n accessory_chip=%u, hw_plat_subtype=%u, pmic_model=%u, pmic_die_revision=%u\n",
 			__func__,
@@ -880,6 +1085,54 @@
 		pr_err("%s: Unknown format found\n", __func__);
 		break;
 	}
+}
+
+int __init socinfo_init(void)
+{
+	socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID, sizeof(struct socinfo_v8));
+
+	if (!socinfo)
+		socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
+				sizeof(struct socinfo_v7));
+
+	if (!socinfo)
+		socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
+				sizeof(struct socinfo_v6));
+
+	if (!socinfo)
+		socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
+				sizeof(struct socinfo_v5));
+
+	if (!socinfo)
+		socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
+				sizeof(struct socinfo_v4));
+
+	if (!socinfo)
+		socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
+				sizeof(struct socinfo_v3));
+
+	if (!socinfo)
+		socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
+				sizeof(struct socinfo_v2));
+
+	if (!socinfo)
+		socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
+				sizeof(struct socinfo_v1));
+
+	if (!socinfo) {
+		pr_warn("%s: Can't find SMEM_HW_SW_BUILD_ID; falling back on dummy values.\n",
+				__func__);
+		socinfo = setup_dummy_socinfo();
+	}
+
+	WARN(!socinfo_get_id(), "Unknown SOC ID!\n");
+	WARN(socinfo_get_id() >= ARRAY_SIZE(cpu_of_id),
+		"New IDs added! ID => CPU mapping might need an update.\n");
+
+	if (socinfo->v1.id < ARRAY_SIZE(cpu_of_id))
+		cur_cpu = cpu_of_id[socinfo->v1.id];
+
+	socinfo_print();
 
 	return 0;
 }
@@ -921,6 +1174,7 @@
 		return MSM_CPU_8064;
 
 	case 0x511F06F1:
+	case 0x511F06F2:
 	case 0x512F06F0:
 		return MSM_CPU_8974;
 
@@ -972,6 +1226,7 @@
 	case 0x512F04D0:
 	case 0x511F06F0:
 	case 0x511F06F1:
+	case 0x511F06F2:
 	case 0x510F05D0:
 		return 1;
 
diff --git a/arch/arm/mach-msm/spm-v2.c b/arch/arm/mach-msm/spm-v2.c
index 620aa1d..5fd5443 100644
--- a/arch/arm/mach-msm/spm-v2.c
+++ b/arch/arm/mach-msm/spm-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
@@ -358,11 +358,13 @@
 int msm_spm_drv_set_vdd(struct msm_spm_driver_data *dev, unsigned int vlevel)
 {
 	uint32_t timeout_us, new_level;
-	bool avs_enabled = msm_spm_drv_is_avs_enabled(dev);
+	bool avs_enabled;
 
 	if (!dev)
 		return -EINVAL;
 
+	avs_enabled  = msm_spm_drv_is_avs_enabled(dev);
+
 	if (!msm_spm_pmic_arb_present(dev))
 		return -ENOSYS;
 
diff --git a/arch/arm/mach-msm/spm.h b/arch/arm/mach-msm/spm.h
index 01f6787..77b7bf7 100644
--- a/arch/arm/mach-msm/spm.h
+++ b/arch/arm/mach-msm/spm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/spm_devices.c b/arch/arm/mach-msm/spm_devices.c
index e77a7ac..97e1c17 100644
--- a/arch/arm/mach-msm/spm_devices.c
+++ b/arch/arm/mach-msm/spm_devices.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/spm_driver.h b/arch/arm/mach-msm/spm_driver.h
index 1beaffb..295075f 100644
--- a/arch/arm/mach-msm/spm_driver.h
+++ b/arch/arm/mach-msm/spm_driver.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/subsystem_map.c b/arch/arm/mach-msm/subsystem_map.c
index 5f5a02b..116fc2e 100644
--- a/arch/arm/mach-msm/subsystem_map.c
+++ b/arch/arm/mach-msm/subsystem_map.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -256,6 +256,8 @@
 
 	subsys_domain = msm_get_iommu_domain(msm_subsystem_get_domain_no
 								(subsys_id));
+	if (!subsys_domain)
+		return -EINVAL;
 
 	return iommu_iova_to_phys(subsys_domain, iova);
 }
@@ -410,8 +412,8 @@
 
 			if (flags & MSM_SUBSYSTEM_MAP_IOMMU_2X)
 				msm_iommu_map_extra
-					(d, temp_va, length, SZ_4K,
-					(IOMMU_READ | IOMMU_WRITE));
+					(d, temp_va, phys, length, SZ_4K,
+					IOMMU_READ);
 		}
 
 	}
@@ -429,15 +431,18 @@
 	return buf;
 
 outiova:
-	if (flags & MSM_SUBSYSTEM_MAP_IOVA)
-		iommu_unmap(d, temp_va, SZ_4K);
+	if (flags & MSM_SUBSYSTEM_MAP_IOVA) {
+		if (d)
+			iommu_unmap(d, temp_va, SZ_4K);
+	}
 outdomain:
 	if (flags & MSM_SUBSYSTEM_MAP_IOVA) {
 		/* Unmap the rest of the current domain, i */
-		for (j -= SZ_4K, temp_va -= SZ_4K;
-			j > 0; temp_va -= SZ_4K, j -= SZ_4K)
-			iommu_unmap(d, temp_va, SZ_4K);
-
+		if (d) {
+			for (j -= SZ_4K, temp_va -= SZ_4K;
+				j > 0; temp_va -= SZ_4K, j -= SZ_4K)
+				iommu_unmap(d, temp_va, SZ_4K);
+		}
 		/* Unmap all the other domains */
 		for (i--; i >= 0; i--) {
 			unsigned int domain_no, partition_no;
@@ -447,10 +452,14 @@
 			partition_no = msm_subsystem_get_partition_no(
 								subsys_ids[i]);
 
-			temp_va = buf->iova[i];
-			for (j = length; j > 0; j -= SZ_4K,
-						temp_va += SZ_4K)
-				iommu_unmap(d, temp_va, SZ_4K);
+			d = msm_get_iommu_domain(domain_no);
+
+			if (d) {
+				temp_va = buf->iova[i];
+				for (j = length; j > 0; j -= SZ_4K,
+							temp_va += SZ_4K)
+					iommu_unmap(d, temp_va, SZ_4K);
+			}
 			msm_free_iova_address(buf->iova[i], domain_no,
 					partition_no, length);
 		}
@@ -506,6 +515,9 @@
 						msm_subsystem_get_domain_no(
 						node->subsystems[i]));
 
+				if (!subsys_domain)
+					continue;
+
 				domain_no = msm_subsystem_get_domain_no(
 							node->subsystems[i]);
 				partition_no = msm_subsystem_get_partition_no(
diff --git a/arch/arm/mach-msm/subsystem_notif.c b/arch/arm/mach-msm/subsystem_notif.c
index f7db54c..f0db0e9 100644
--- a/arch/arm/mach-msm/subsystem_notif.c
+++ b/arch/arm/mach-msm/subsystem_notif.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, 2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -147,7 +147,8 @@
 EXPORT_SYMBOL(subsys_notif_add_subsys);
 
 int subsys_notif_queue_notification(void *subsys_handle,
-					enum subsys_notif_type notif_type)
+					enum subsys_notif_type notif_type,
+					void *data)
 {
 	int ret = 0;
 	struct subsys_notif_info *subsys =
@@ -159,10 +160,9 @@
 	if (notif_type < 0 || notif_type >= SUBSYS_NOTIF_TYPE_COUNT)
 		return -EINVAL;
 
-	ret = srcu_notifier_call_chain(
-		&subsys->subsys_notif_rcvr_list, notif_type,
-		(void *)subsys);
-
+		ret = srcu_notifier_call_chain(
+			&subsys->subsys_notif_rcvr_list, notif_type,
+			data);
 	return ret;
 }
 EXPORT_SYMBOL(subsys_notif_queue_notification);
diff --git a/arch/arm/mach-msm/subsystem_restart.c b/arch/arm/mach-msm/subsystem_restart.c
index d862e0f..29481d3 100644
--- a/arch/arm/mach-msm/subsystem_restart.c
+++ b/arch/arm/mach-msm/subsystem_restart.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -30,6 +30,7 @@
 #include <linux/device.h>
 #include <linux/idr.h>
 #include <linux/debugfs.h>
+#include <linux/miscdevice.h>
 
 #include <asm/current.h>
 
@@ -144,6 +145,8 @@
 	struct dentry *dentry;
 #endif
 	bool do_ramdump_on_put;
+	struct miscdevice misc_dev;
+	char miscdevice_name[32];
 };
 
 static struct subsys_device *to_subsys(struct device *d)
@@ -398,17 +401,17 @@
 	}
 }
 
-static void __send_notification_to_order(struct subsys_device *dev, void *data)
+static void notify_each_subsys_device(struct subsys_device **list,
+		unsigned count,
+		enum subsys_notif_type notif, void *data)
 {
-	enum subsys_notif_type type = (enum subsys_notif_type)data;
-
-	subsys_notif_queue_notification(dev->notify, type);
-}
-
-static void send_notification_to_order(struct subsys_device **l, unsigned n,
-		enum subsys_notif_type t)
-{
-	for_each_subsys_device(l, n, (void *)t, __send_notification_to_order);
+	while (count--) {
+		enum subsys_notif_type type = (enum subsys_notif_type)type;
+		struct subsys_device *dev = *list++;
+		if (!dev)
+			continue;
+		subsys_notif_queue_notification(dev->notify, notif, data);
+	}
 }
 
 static void subsystem_shutdown(struct subsys_device *dev, void *data)
@@ -622,9 +625,12 @@
 
 	pr_debug("[%p]: Starting restart sequence for %s\n", current,
 			desc->name);
-	send_notification_to_order(list, count, SUBSYS_BEFORE_SHUTDOWN);
+	notify_each_subsys_device(list, count, SUBSYS_BEFORE_SHUTDOWN, NULL);
 	for_each_subsys_device(list, count, NULL, subsystem_shutdown);
-	send_notification_to_order(list, count, SUBSYS_AFTER_SHUTDOWN);
+	notify_each_subsys_device(list, count, SUBSYS_AFTER_SHUTDOWN, NULL);
+
+	notify_each_subsys_device(list, count, SUBSYS_RAMDUMP_NOTIFICATION,
+							  &enable_ramdumps);
 
 	spin_lock_irqsave(&track->s_lock, flags);
 	track->p_state = SUBSYS_RESTARTING;
@@ -633,9 +639,9 @@
 	/* Collect ram dumps for all subsystems in order here */
 	for_each_subsys_device(list, count, NULL, subsystem_ramdump);
 
-	send_notification_to_order(list, count, SUBSYS_BEFORE_POWERUP);
+	notify_each_subsys_device(list, count, SUBSYS_BEFORE_POWERUP, NULL);
 	for_each_subsys_device(list, count, NULL, subsystem_powerup);
-	send_notification_to_order(list, count, SUBSYS_AFTER_POWERUP);
+	notify_each_subsys_device(list, count, SUBSYS_AFTER_POWERUP, NULL);
 
 	pr_info("[%p]: Restart sequence for %s completed.\n",
 			current, desc->name);
@@ -847,6 +853,41 @@
 static void subsys_debugfs_remove(struct subsys_device *subsys) { }
 #endif
 
+static int subsys_device_open(struct inode *inode, struct file *file)
+{
+	void *retval;
+	struct subsys_device *subsys_dev = container_of(file->private_data,
+		struct subsys_device, misc_dev);
+
+	if (!file->private_data)
+		return -EINVAL;
+
+	retval = subsystem_get(subsys_dev->desc->name);
+	if (IS_ERR(retval))
+		return PTR_ERR(retval);
+
+	return 0;
+}
+
+static int subsys_device_close(struct inode *inode, struct file *file)
+{
+	struct subsys_device *subsys_dev = container_of(file->private_data,
+		struct subsys_device, misc_dev);
+
+	if (!file->private_data)
+		return -EINVAL;
+
+	subsystem_put(subsys_dev);
+
+	return 0;
+}
+
+static const struct file_operations subsys_device_fops = {
+		.owner = THIS_MODULE,
+		.open = subsys_device_open,
+		.release = subsys_device_close,
+};
+
 static void subsys_device_release(struct device *dev)
 {
 	struct subsys_device *subsys = to_subsys(dev);
@@ -857,6 +898,33 @@
 	kfree(subsys);
 }
 
+static int subsys_misc_device_add(struct subsys_device *subsys_dev)
+{
+	int ret;
+	memset(subsys_dev->miscdevice_name, 0,
+			ARRAY_SIZE(subsys_dev->miscdevice_name));
+	snprintf(subsys_dev->miscdevice_name,
+			 ARRAY_SIZE(subsys_dev->miscdevice_name), "subsys_%s",
+			 subsys_dev->desc->name);
+
+	subsys_dev->misc_dev.minor = MISC_DYNAMIC_MINOR;
+	subsys_dev->misc_dev.name = subsys_dev->miscdevice_name;
+	subsys_dev->misc_dev.fops = &subsys_device_fops;
+	subsys_dev->misc_dev.parent = &subsys_dev->dev;
+
+	ret = misc_register(&subsys_dev->misc_dev);
+	if (ret) {
+		pr_err("%s: misc_register() failed for %s (%d)", __func__,
+				subsys_dev->miscdevice_name, ret);
+	}
+	return ret;
+}
+
+static void subsys_misc_device_remove(struct subsys_device *subsys_dev)
+{
+	misc_deregister(&subsys_dev->misc_dev);
+}
+
 struct subsys_device *subsys_register(struct subsys_desc *desc)
 {
 	struct subsys_device *subsys;
@@ -895,6 +963,12 @@
 
 	ret = device_register(&subsys->dev);
 	if (ret) {
+		device_unregister(&subsys->dev);
+		goto err_register;
+	}
+
+	ret = subsys_misc_device_add(subsys);
+	if (ret) {
 		put_device(&subsys->dev);
 		goto err_register;
 	}
@@ -924,6 +998,7 @@
 		device_unregister(&subsys->dev);
 		mutex_unlock(&subsys->track.lock);
 		subsys_debugfs_remove(subsys);
+		subsys_misc_device_remove(subsys);
 		put_device(&subsys->dev);
 	}
 }
@@ -981,9 +1056,6 @@
 		spin_lock_init(&restart_orders[i]->track.s_lock);
 	}
 
-	if (restart_orders == NULL || n_restart_orders < 1)
-		WARN_ON(1);
-
 	return 0;
 }
 
diff --git a/arch/arm/mach-msm/sysmon.c b/arch/arm/mach-msm/sysmon.c
index 112daca..4b151cc 100644
--- a/arch/arm/mach-msm/sysmon.c
+++ b/arch/arm/mach-msm/sysmon.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/sysmon.h b/arch/arm/mach-msm/sysmon.h
index 8c2f6ea..3f122cd 100644
--- a/arch/arm/mach-msm/sysmon.h
+++ b/arch/arm/mach-msm/sysmon.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/arch/arm/mach-msm/test-lpm.c b/arch/arm/mach-msm/test-lpm.c
new file mode 100644
index 0000000..031b2dc
--- /dev/null
+++ b/arch/arm/mach-msm/test-lpm.c
@@ -0,0 +1,699 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pm.h>
+#include <linux/mutex.h>
+#include <linux/uaccess.h>
+#include <linux/debugfs.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/ctype.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+#include <mach/socinfo.h>
+#if defined(CONFIG_MSM_RPM)
+#include "rpm_resources.h"
+#endif
+#if defined(CONFIG_MSM_RPM_SMD)
+#include "lpm_resources.h"
+#endif
+#include "timer.h"
+#include "test-lpm.h"
+
+#define LPM_STATS_RESET "reset"
+#define LPM_TEST_ALL_LEVELS "lpm"
+#define LPM_TEST_LATENCIES "latency"
+#define LPM_TEST_CLEAR "clear"
+#define BUF_SIZE 200
+#define STAT_BUF_EXTRA_SIZE 500
+#define WAIT_FOR_XO 1
+#define COMM_BUF_SIZE 15
+#define INPUT_COUNT_BUF 10
+#define LPM_DEFAULT_CPU 0
+
+#define SNPRINTF(buf, size, format, ...) \
+{ \
+	if (size > 0) { \
+		int ret; \
+		ret = snprintf(buf, size, format, ## __VA_ARGS__); \
+		if (ret > size) { \
+			buf += size; \
+			size = 0; \
+		} else { \
+			buf += ret; \
+			size -= ret; \
+		} \
+	} \
+} \
+
+static DEFINE_MUTEX(lpm_stats_mutex);
+
+struct lpm_level_stat {
+	char level_name[BUF_SIZE];
+	int64_t min_time;
+	int64_t max_time;
+	int64_t avg_time;
+	int64_t exit_early;
+	int64_t count;
+	unsigned long min_threshold;
+	uint32_t kernel_sleep_time;
+	bool entered;
+};
+
+static DEFINE_PER_CPU(struct lpm_level_stat *, lpm_levels);
+
+static struct dentry *lpm_stat;
+static struct dentry *lpm_ext_comm;
+static struct msm_rpmrs_level *lpm_supp_level;
+static int lpm_level_count;
+static int lpm_level_iter;
+static bool msm_lpm_use_qtimer;
+static unsigned long lpm_sleep_time;
+static bool lpm_latency_test;
+
+static unsigned int timer_interval = 5000;
+module_param_named(lpm_timer_interval_msec, timer_interval, uint,
+	S_IRUGO | S_IWUSR | S_IWGRP);
+
+static unsigned int latency_test_interval = 50;
+module_param_named(lpm_latency_timer_interval_usec, latency_test_interval, uint,
+	S_IRUGO | S_IWUSR | S_IWGRP);
+
+static unsigned int cpu_to_debug = LPM_DEFAULT_CPU;
+static int lpm_cpu_update(const char *val, const struct kernel_param *kp)
+{
+	int ret = 0;
+	unsigned int debug_val;
+
+	ret = kstrtouint(val, 10, &debug_val);
+	if ((ret < 0) || (debug_val >= num_possible_cpus()))
+		return -EINVAL;
+	cpu_to_debug = debug_val;
+	return ret;
+}
+
+static struct kernel_param_ops cpu_debug_events = {
+	.set = lpm_cpu_update,
+};
+
+module_param_cb(cpu_to_debug, &cpu_debug_events, &cpu_to_debug,
+			S_IRUGO | S_IWUSR | S_IWGRP);
+
+static void lpm_populate_name(struct lpm_level_stat *stat,
+		struct msm_rpmrs_level *supp)
+{
+	char nm[BUF_SIZE] = {0};
+	char default_buf[20];
+
+	switch (supp->sleep_mode) {
+	case MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT:
+		strlcat(nm, "WFI ", BUF_SIZE);
+		break;
+	case MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT:
+		strlcat(nm, "WFI voltage Rampdown ", BUF_SIZE);
+		break;
+	case MSM_PM_SLEEP_MODE_RETENTION:
+		strlcat(nm, "Retention ", BUF_SIZE);
+		break;
+	case MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE:
+		strlcat(nm, "Standalone Power collapse ", BUF_SIZE);
+		break;
+	case MSM_PM_SLEEP_MODE_POWER_COLLAPSE:
+		strlcat(nm, "Idle Power collapse ", BUF_SIZE);
+		break;
+	case MSM_PM_SLEEP_MODE_POWER_COLLAPSE_SUSPEND:
+		strlcat(nm, "Suspend Power collapse ", BUF_SIZE);
+		break;
+	default:
+		strlcat(nm, "Invalid Mode ", BUF_SIZE);
+		break;
+	}
+
+	switch (msm_pm_get_pxo(&(supp->rs_limits))) {
+	case MSM_PM(PXO_OFF):
+		strlcat(nm, "XO: OFF ", BUF_SIZE);
+		break;
+	case MSM_PM(PXO_ON):
+		strlcat(nm, "XO: ON ", BUF_SIZE);
+		break;
+	default:
+		snprintf(default_buf, sizeof(default_buf),
+			"XO : %d ", msm_pm_get_pxo(&(supp->rs_limits)));
+		strlcat(nm, default_buf , BUF_SIZE);
+		break;
+	}
+
+	switch (msm_pm_get_l2_cache(&(supp->rs_limits))) {
+	case MSM_PM(L2_CACHE_HSFS_OPEN):
+		strlcat(nm, "L2: HSFS ", BUF_SIZE);
+		break;
+	case MSM_PM(L2_CACHE_GDHS):
+		strlcat(nm, "L2: GDHS ", BUF_SIZE);
+		break;
+	case MSM_PM(L2_CACHE_RETENTION):
+		strlcat(nm, "L2: Retention ", BUF_SIZE);
+		break;
+	case MSM_PM(L2_CACHE_ACTIVE):
+		strlcat(nm, "L2: Active ", BUF_SIZE);
+		break;
+	default:
+		snprintf(default_buf, sizeof(default_buf),
+			"L2 : %d ", msm_pm_get_l2_cache(&(supp->rs_limits)));
+		strlcat(nm, default_buf , BUF_SIZE);
+		break;
+	}
+
+	snprintf(default_buf, sizeof(default_buf),
+		"Vdd_mem : %d ", msm_pm_get_vdd_mem(&(supp->rs_limits)));
+	strlcat(nm, default_buf , BUF_SIZE);
+
+	snprintf(default_buf, sizeof(default_buf),
+		"Vdd_dig : %d ", msm_pm_get_vdd_dig(&(supp->rs_limits)));
+	strlcat(nm, default_buf , BUF_SIZE);
+
+	strlcpy(stat->level_name, nm, strnlen(nm, BUF_SIZE));
+}
+
+static int64_t msm_lpm_get_time(void)
+{
+	if (msm_lpm_use_qtimer)
+		return ktime_to_ns(ktime_get());
+
+	return msm_timer_get_sclk_time(NULL);
+}
+
+static bool lpm_get_level(void *v, unsigned int *ct)
+{
+	bool ret = false;
+	int it;
+	struct msm_rpmrs_level *level_enter;
+
+	level_enter = container_of(((struct msm_lpm_sleep_data *)v)->limits,
+			struct msm_rpmrs_level, rs_limits);
+	if (level_enter) {
+		for (it = 0; it < lpm_level_count; it++)
+			if (!memcmp(level_enter , lpm_supp_level + it,
+					sizeof(struct msm_rpmrs_level))) {
+				*ct = it;
+				ret = true;
+				break;
+			}
+	}
+	return ret;
+}
+
+static int lpm_callback(struct notifier_block *self, unsigned long cmd,
+				void *sleep_data)
+{
+	static int64_t time;
+	unsigned int ct;
+	struct lpm_level_stat *stats;
+	stats = per_cpu(lpm_levels, cpu_to_debug);
+	/* Update the stats and get the start/stop time */
+	if (cmd == MSM_LPM_STATE_ENTER && !lpm_latency_test) {
+		time = msm_lpm_get_time();
+		stats[lpm_level_iter].entered = true;
+	} else if ((cmd == MSM_LPM_STATE_EXIT) && (time)
+			&& (!lpm_latency_test)) {
+		int64_t time1;
+		time1 = msm_lpm_get_time();
+		time = time1 - time;
+
+		if ((time < stats[lpm_level_iter].min_time) ||
+			(!stats[lpm_level_iter].min_time))
+			stats[lpm_level_iter].min_time = time;
+
+		if (time > stats[lpm_level_iter].max_time)
+			stats[lpm_level_iter].max_time = time;
+
+		time1 = stats[lpm_level_iter].avg_time *
+			stats[lpm_level_iter].count + time;
+		do_div(time1, ++(stats[lpm_level_iter].count));
+
+		stats[lpm_level_iter].avg_time = time1;
+		do_div(time, NSEC_PER_USEC);
+		if (time < lpm_supp_level[lpm_level_iter].
+				time_overhead_us)
+			stats[lpm_level_iter].exit_early++;
+		time = 0;
+	} else if (cmd == MSM_LPM_STATE_ENTER && lpm_latency_test) {
+
+		struct msm_lpm_sleep_data *data = sleep_data;
+		if ((lpm_get_level(sleep_data, &ct)) &&
+		(stats[ct].min_threshold == 0) &&
+		data->kernel_sleep <= lpm_sleep_time) {
+
+			stats[ct].min_threshold = lpm_sleep_time;
+			stats[ct].kernel_sleep_time =
+				data->kernel_sleep;
+		}
+	}
+	return 0;
+}
+
+static struct notifier_block lpm_idle_nb = {
+	.notifier_call = lpm_callback,
+};
+
+static void lpm_test_initiate(int lpm_level_test)
+{
+	int test_ret;
+
+	/* This will communicate to 'stat' debugfs to skip latency printing*/
+	lpm_sleep_time = 0;
+	lpm_latency_test = false;
+	/* Unregister any infinitely registered level*/
+	msm_lpm_unregister_notifier(cpu_to_debug, &lpm_idle_nb);
+
+	/* Register/Unregister for Notification */
+	while (lpm_level_iter < lpm_level_count) {
+		test_ret = msm_lpm_register_notifier(cpu_to_debug,
+				lpm_level_iter, &lpm_idle_nb, false);
+		if (test_ret < 0) {
+			pr_err("%s: Registering notifier failed\n", __func__);
+			return;
+		}
+		if (!timer_interval)
+			break;
+		msleep(timer_interval);
+		msm_lpm_unregister_notifier(cpu_to_debug, &lpm_idle_nb);
+		if (lpm_level_test == lpm_level_count)
+			lpm_level_iter++;
+		else
+			break;
+	}
+}
+
+static void lpm_latency_test_initiate(unsigned long max_time)
+{
+	int test_ret;
+	lpm_latency_test = true;
+	lpm_sleep_time = latency_test_interval;
+
+	msm_lpm_unregister_notifier(cpu_to_debug, &lpm_idle_nb);
+	if (max_time > lpm_sleep_time) {
+
+		do {
+			test_ret = msm_lpm_register_notifier(cpu_to_debug,
+					lpm_level_count + 1,
+					&lpm_idle_nb, true);
+			if (test_ret) {
+				pr_err("%s: Registering notifier failed\n",
+						__func__);
+				return;
+			}
+			usleep(lpm_sleep_time);
+			/*Unregister to ensure that we dont update the latency
+			during the timer value transistion*/
+			msm_lpm_unregister_notifier(cpu_to_debug,
+				&lpm_idle_nb);
+			lpm_sleep_time += latency_test_interval;
+		} while (lpm_sleep_time < max_time);
+	} else
+		pr_err("%s: Invalid time interval specified\n", __func__);
+
+	lpm_latency_test = false;
+}
+
+static ssize_t lpm_test_comm_read(struct file *fp, char __user *user_buffer,
+				size_t buffer_length, loff_t *position)
+{
+	int i = 0;
+	int count = buffer_length;
+	int alloc_size = 100 * lpm_level_count;
+	char *temp_buf;
+	char *comm_buf;
+	ssize_t ret;
+
+	comm_buf = kzalloc(alloc_size, GFP_KERNEL);
+	if (!comm_buf) {
+		pr_err("%s:Memory alloc failed\n", __func__);
+		ret = 0;
+		goto com_read_failed;
+	}
+	temp_buf = comm_buf;
+
+	SNPRINTF(temp_buf, count, "Low power modes available:\n");
+
+	for (i = 0; i < lpm_level_count; i++)
+		SNPRINTF(temp_buf, count, "%d. %s\n", i,
+			per_cpu(lpm_levels, cpu_to_debug)[i].level_name);
+
+	SNPRINTF(temp_buf, count, "%d. MSM test all lpm\n", i++);
+	SNPRINTF(temp_buf, count, "%d. MSM determine latency\n", i);
+
+	ret = simple_read_from_buffer(user_buffer, buffer_length - count,
+					position, comm_buf, alloc_size);
+	kfree(comm_buf);
+
+com_read_failed:
+	return ret;
+}
+
+char *trimspaces(char *time_buf)
+{
+	int len;
+	char *tail;
+
+	len = strnlen(time_buf, INPUT_COUNT_BUF);
+	tail = time_buf + len;
+	while (isspace(*time_buf) && (time_buf != tail))
+		time_buf++;
+	if (time_buf == tail) {
+		time_buf = NULL;
+		goto exit_trim_spaces;
+	}
+	len = strnlen(time_buf, INPUT_COUNT_BUF);
+	tail = time_buf + len - 1;
+	while (isspace(*tail) && tail != time_buf) {
+		*tail = '\0';
+		tail--;
+	}
+exit_trim_spaces:
+	return time_buf;
+}
+
+static ssize_t lpm_test_comm_write(struct file *fp, const char __user
+			*user_buffer, size_t count, loff_t *position)
+{
+	ssize_t ret;
+	int str_ret;
+	int lpm_level_test;
+	char *new_ptr;
+	char *comm_buf;
+
+	comm_buf = kzalloc(COMM_BUF_SIZE, GFP_KERNEL);
+	if (!comm_buf) {
+		pr_err("\'%s\': kzalloc failed\n", __func__);
+		return -EINVAL;
+	}
+
+	memset(comm_buf, '\0', COMM_BUF_SIZE);
+
+	ret = simple_write_to_buffer(comm_buf, COMM_BUF_SIZE, position,
+					user_buffer, count);
+	new_ptr = trimspaces(comm_buf);
+	if (!new_ptr) {
+		pr_err("%s: Test case number input invalid\n", __func__);
+		goto write_com_failed;
+	}
+
+	if (!memcmp(comm_buf, LPM_TEST_ALL_LEVELS,
+			sizeof(LPM_TEST_ALL_LEVELS) - 1)) {
+		lpm_level_test = lpm_level_count;
+		lpm_level_iter = 0;
+		lpm_test_initiate(lpm_level_test);
+		goto write_com_success;
+	} else if (!memcmp(comm_buf, LPM_TEST_LATENCIES,
+			sizeof(LPM_TEST_LATENCIES) - 1)) {
+		lpm_level_test = lpm_level_count + 1;
+		lpm_latency_test_initiate(timer_interval * USEC_PER_MSEC);
+		goto write_com_success;
+	} else if (!memcmp(comm_buf, LPM_TEST_CLEAR,
+			sizeof(LPM_TEST_CLEAR) - 1)) {
+		msm_lpm_unregister_notifier(cpu_to_debug, &lpm_idle_nb);
+		goto write_com_success;
+	}
+
+	str_ret = kstrtoint(new_ptr, 10, &lpm_level_test);
+	if ((str_ret) || (lpm_level_test > (lpm_level_count + 1)) ||
+		(lpm_level_test < 0))
+		goto write_com_failed;
+
+	lpm_level_iter = lpm_level_test;
+	lpm_test_initiate(lpm_level_test);
+	goto write_com_success;
+
+write_com_failed:
+	ret = -EINVAL;
+write_com_success:
+	kfree(comm_buf);
+	return ret;
+}
+
+static ssize_t lpm_test_stat_read(struct file *fp, char __user *user_buffer,
+				size_t buffer_length, loff_t *position)
+{
+	int i = 0;
+	int j = 0;
+	int count = buffer_length;
+	char *stat_buf;
+	char *stat_buf_start;
+	size_t stat_buf_size;
+	ssize_t ret;
+	int64_t min_ns;
+	int64_t max_ns;
+	int64_t avg_ns;
+	uint32_t min_ms;
+	uint32_t max_ms;
+	uint32_t avg_ms;
+
+	stat_buf_size = ((sizeof(struct lpm_level_stat) * lpm_level_count) +
+				STAT_BUF_EXTRA_SIZE);
+	stat_buf = kzalloc(stat_buf_size, GFP_KERNEL);
+	if (!stat_buf) {
+		pr_err("\'%s\': kzalloc failed\n", __func__);
+		return -EINVAL;
+	}
+	stat_buf_start = stat_buf;
+	mutex_lock(&lpm_stats_mutex);
+	memset(stat_buf, '\0', stat_buf_size);
+	SNPRINTF(stat_buf, count, "\n\nStats for CPU: %d\nTotal Levels: %d\n",
+			cpu_to_debug, lpm_level_count);
+	if (!lpm_sleep_time) {
+		SNPRINTF(stat_buf, count, "Level(s) failed: ");
+		for (i = 0 ; i < lpm_level_count; i++) {
+			if (per_cpu(lpm_levels, cpu_to_debug)[i].entered)
+				continue;
+			else {
+				SNPRINTF(stat_buf, count,
+					"\n%d. %s", ++j, per_cpu(lpm_levels,
+					cpu_to_debug)[i].level_name);
+			}
+		}
+		SNPRINTF(stat_buf, count, "\n\nSTATS:");
+		for (i = 0; i < lpm_level_count; i++) {
+			min_ns = per_cpu(lpm_levels, cpu_to_debug)[i].min_time;
+			min_ms = do_div(min_ns, NSEC_PER_MSEC);
+			max_ns = per_cpu(lpm_levels, cpu_to_debug)[i].max_time;
+			max_ms = do_div(max_ns, NSEC_PER_MSEC);
+			avg_ns = per_cpu(lpm_levels, cpu_to_debug)[i].avg_time;
+			avg_ms = do_div(avg_ns, NSEC_PER_MSEC);
+			SNPRINTF(stat_buf, count, "\nLEVEL: %s\n"
+				"Entered : %lld\n"
+				"Early wakeup : %lld\n"
+				"Min Time (mSec): %lld.%06u\n"
+				"Max Time (mSec): %lld.%06u\n"
+				"Avg Time (mSec): %lld.%06u\n",
+				per_cpu(lpm_levels, cpu_to_debug)[i].level_name,
+				per_cpu(lpm_levels, cpu_to_debug)[i].count,
+				per_cpu(lpm_levels, cpu_to_debug)[i].exit_early,
+				min_ns, min_ms,
+				max_ns, max_ms,
+				avg_ns, avg_ms);
+		}
+	} else {
+		for (i = 0; i < lpm_level_count; i++) {
+			SNPRINTF(stat_buf, count, "\nLEVEL: %s\n"
+				"Min Timer value (uSec): %lu\n"
+				"Kernel sleep time (uSec): %u\n",
+				per_cpu(lpm_levels, cpu_to_debug)[i].level_name,
+				per_cpu(lpm_levels, cpu_to_debug)[i].
+				min_threshold,
+				per_cpu(lpm_levels,
+				cpu_to_debug)[i].kernel_sleep_time);
+		}
+	}
+
+	ret = simple_read_from_buffer(user_buffer, buffer_length - count,
+				position, stat_buf_start, stat_buf_size);
+
+	mutex_unlock(&lpm_stats_mutex);
+	kfree(stat_buf_start);
+	return ret;
+}
+
+static ssize_t lpm_test_stat_write(struct file *fp, const char __user
+				*user_buffer, size_t count, loff_t *position)
+{
+	char buf[sizeof(LPM_STATS_RESET)];
+	int ret;
+	int i;
+	struct lpm_level_stat *stats;
+
+	if (count > sizeof(LPM_STATS_RESET)) {
+		ret = -EINVAL;
+		goto write_debug_failed;
+	}
+
+	simple_write_to_buffer(buf, sizeof(LPM_STATS_RESET), position,
+				user_buffer, count);
+
+	if (memcmp(buf, LPM_STATS_RESET, sizeof(LPM_STATS_RESET) - 1)) {
+		ret = -EINVAL;
+		goto write_debug_failed;
+	}
+
+	mutex_lock(&lpm_stats_mutex);
+	stats = per_cpu(lpm_levels, cpu_to_debug);
+	for (i = 0 ; i < lpm_level_count; i++) {
+		stats[i].entered = 0;
+		stats[i].min_time = 0;
+		stats[i].max_time = 0;
+		stats[i].avg_time = 0;
+		stats[i].count = 0;
+		stats[i].exit_early = 0;
+		stats[i].min_threshold = 0;
+		stats[i].kernel_sleep_time = 0;
+	}
+	mutex_unlock(&lpm_stats_mutex);
+	return count;
+write_debug_failed:
+	return ret;
+}
+
+static void lpm_init_rpm_levels(int test_lpm_level_count,
+		struct msm_rpmrs_level *test_levels)
+{
+	int i = 0;
+	unsigned int m_cpu = 0;
+	struct lpm_level_stat *stat_levels = NULL;
+
+	if (test_lpm_level_count < 0)
+		return;
+
+	lpm_level_count = test_lpm_level_count;
+
+	lpm_supp_level = test_levels;
+	for_each_possible_cpu(m_cpu) {
+		stat_levels = kzalloc(sizeof(struct lpm_level_stat) *
+				lpm_level_count, GFP_KERNEL);
+		if (!stat_levels) {
+			for (i = m_cpu - 1; i >= 0; i--)
+				kfree(per_cpu(lpm_levels, i));
+			return;
+		}
+
+		for (i = 0; i < lpm_level_count; i++)
+			lpm_populate_name(&stat_levels[i], &lpm_supp_level[i]);
+
+		per_cpu(lpm_levels, m_cpu) = stat_levels;
+	}
+}
+
+static const struct file_operations fops_stat = {
+	.read = lpm_test_stat_read,
+	.write = lpm_test_stat_write,
+};
+
+static const struct file_operations fops_comm = {
+	.read = lpm_test_comm_read,
+	.write = lpm_test_comm_write,
+};
+
+static int __devinit lpm_test_init(int test_lpm_level_count,
+		struct msm_rpmrs_level *test_levels)
+{
+	int filevalue;
+	int lpm_comm;
+	int ret = -EINVAL;
+	struct dentry *parent_dir = NULL;
+
+	parent_dir = debugfs_create_dir("msm_lpm_debug", NULL);
+	if (!parent_dir) {
+		pr_err("%s: debugfs directory creation failed\n",
+				__func__);
+		goto init_err;
+	}
+
+	lpm_stat = debugfs_create_file("stat",
+			S_IRUGO | S_IWUSR | S_IWGRP, parent_dir,
+			&filevalue, &fops_stat);
+	if (!lpm_stat) {
+		pr_err("%s: lpm_stats debugfs creation failed\n",
+				__func__);
+		goto init_err;
+	}
+
+	lpm_ext_comm = debugfs_create_file("comm",
+			S_IRUGO | S_IWUSR | S_IWGRP, parent_dir, &lpm_comm,
+			&fops_comm);
+	if (!lpm_ext_comm) {
+		pr_err("%s: lpm_comm debugfs creation failed\n",
+			__func__);
+		debugfs_remove(lpm_stat);
+		goto init_err;
+	}
+
+	/*Query RPM resources and allocate the data sturctures*/
+	lpm_init_rpm_levels(test_lpm_level_count, test_levels);
+	ret = 0;
+
+init_err:
+	return ret;
+}
+
+static int  __devexit lpm_test_exit(struct platform_device *pdev)
+{
+	unsigned int m_cpu = 0;
+
+	kfree(lpm_supp_level);
+	for_each_possible_cpu(m_cpu)
+		kfree(per_cpu(lpm_levels, m_cpu));
+	debugfs_remove(lpm_stat);
+	debugfs_remove(lpm_ext_comm);
+	return 0;
+}
+
+static int __devinit lpm_test_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct lpm_test_platform_data *pdata;
+	struct msm_rpmrs_level *test_levels;
+	int test_lpm_level_count;
+
+	pdata = pdev->dev.platform_data;
+
+	if (!pdata) {
+		dev_err(dev, "no platform data specified\n");
+		return -EINVAL;
+	}
+
+	test_levels = pdata->msm_lpm_test_levels;
+	test_lpm_level_count = pdata->msm_lpm_test_level_count;
+
+	if (pdata->use_qtimer)
+		msm_lpm_use_qtimer = true;
+
+	lpm_test_init(test_lpm_level_count, test_levels);
+
+	return 0;
+}
+
+static struct platform_driver lpm_test_driver = {
+	.probe = lpm_test_probe,
+	.remove = lpm_test_exit,
+	.driver = {
+		.name = "lpm_test",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init lpm_test_platform_driver_init(void)
+{
+	return platform_driver_register(&lpm_test_driver);
+}
+
+late_initcall(lpm_test_platform_driver_init);
diff --git a/arch/arm/mach-msm/test-lpm.h b/arch/arm/mach-msm/test-lpm.h
new file mode 100644
index 0000000..1486f88
--- /dev/null
+++ b/arch/arm/mach-msm/test-lpm.h
@@ -0,0 +1,22 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_TEST_LPM_H
+#define __ARCH_ARM_MACH_MSM_TEST_LPM_H
+
+struct lpm_test_platform_data {
+	struct msm_rpmrs_level *msm_lpm_test_levels;
+	int msm_lpm_test_level_count;
+	bool use_qtimer;
+};
+#endif
diff --git a/arch/arm/mach-msm/test_qmi_client.c b/arch/arm/mach-msm/test_qmi_client.c
new file mode 100644
index 0000000..d070e37
--- /dev/null
+++ b/arch/arm/mach-msm/test_qmi_client.c
@@ -0,0 +1,344 @@
+/* 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/slab.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/debugfs.h>
+#include <linux/qmi_encdec.h>
+
+#include <asm/uaccess.h>
+
+#include <mach/msm_qmi_interface.h>
+
+#include "kernel_test_service_v01.h"
+
+#define TEST_SERVICE_SVC_ID 0x0000000f
+#define TEST_SERVICE_INS_ID 1
+
+static int test_rep_cnt = 10;
+module_param_named(rep_cnt, test_rep_cnt, int, S_IRUGO | S_IWUSR | S_IWGRP);
+
+static int test_data_sz = 50;
+module_param_named(data_sz, test_data_sz, int, S_IRUGO | S_IWUSR | S_IWGRP);
+
+static int test_clnt_debug_mask;
+module_param_named(debug_mask, test_clnt_debug_mask,
+		   int, S_IRUGO | S_IWUSR | S_IWGRP);
+
+#define D(x...) do { \
+	if (test_clnt_debug_mask) \
+		pr_debug(x); \
+} while (0)
+
+/* Variable to initiate the test through debugfs interface */
+static struct dentry *test_dent;
+
+/* Test client port for IPC Router */
+static struct qmi_handle *test_clnt;
+static int test_clnt_reset;
+
+/* Reader thread to receive responses & indications */
+static void test_clnt_recv_msg(struct work_struct *work);
+static DECLARE_DELAYED_WORK(work_recv_msg, test_clnt_recv_msg);
+static void test_clnt_svc_arrive(struct work_struct *work);
+static DECLARE_DELAYED_WORK(work_svc_arrive, test_clnt_svc_arrive);
+static void test_clnt_svc_exit(struct work_struct *work);
+static DECLARE_DELAYED_WORK(work_svc_exit, test_clnt_svc_exit);
+static struct workqueue_struct *test_clnt_workqueue;
+
+/* Variable to hold the test result */
+static int test_res;
+
+static int test_qmi_ping_pong_send_sync_msg(void)
+{
+	struct test_ping_req_msg_v01 req;
+	struct test_ping_resp_msg_v01 resp;
+	struct msg_desc req_desc, resp_desc;
+	int rc;
+
+	memcpy(req.ping, "ping", sizeof(req.ping));
+	req.client_name_valid = 0;
+
+	req_desc.max_msg_len = TEST_PING_REQ_MAX_MSG_LEN_V01;
+	req_desc.msg_id = TEST_PING_REQ_MSG_ID_V01;
+	req_desc.ei_array = test_ping_req_msg_v01_ei;
+
+	resp_desc.max_msg_len = TEST_PING_REQ_MAX_MSG_LEN_V01;
+	resp_desc.msg_id = TEST_PING_REQ_MSG_ID_V01;
+	resp_desc.ei_array = test_ping_resp_msg_v01_ei;
+
+	rc = qmi_send_req_wait(test_clnt, &req_desc, &req, sizeof(req),
+			       &resp_desc, &resp, sizeof(resp), 0);
+	if (rc < 0) {
+		pr_err("%s: send req failed %d\n", __func__, rc);
+		return rc;
+	}
+
+	D("%s: Received %s response\n", __func__, resp.pong);
+	return rc;
+}
+
+static int test_qmi_data_send_sync_msg(unsigned int data_len)
+{
+	struct test_data_req_msg_v01 *req;
+	struct test_data_resp_msg_v01 *resp;
+	struct msg_desc req_desc, resp_desc;
+	int rc, i;
+
+	req = kzalloc(sizeof(struct test_data_req_msg_v01), GFP_KERNEL);
+	if (!req) {
+		pr_err("%s: Data req msg alloc failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	resp = kzalloc(sizeof(struct test_data_resp_msg_v01), GFP_KERNEL);
+	if (!resp) {
+		pr_err("%s: Data resp msg alloc failed\n", __func__);
+		kfree(req);
+		return -ENOMEM;
+	}
+
+	req->data_len = data_len;
+	for (i = 0; i < data_len; i = i + sizeof(int))
+		memcpy(req->data + i, (uint8_t *)&i, sizeof(int));
+	req->client_name_valid = 0;
+
+	req_desc.max_msg_len = TEST_DATA_REQ_MAX_MSG_LEN_V01;
+	req_desc.msg_id = TEST_DATA_REQ_MSG_ID_V01;
+	req_desc.ei_array = test_data_req_msg_v01_ei;
+
+	resp_desc.max_msg_len = TEST_DATA_REQ_MAX_MSG_LEN_V01;
+	resp_desc.msg_id = TEST_DATA_REQ_MSG_ID_V01;
+	resp_desc.ei_array = test_data_resp_msg_v01_ei;
+
+	rc = qmi_send_req_wait(test_clnt, &req_desc, req, sizeof(*req),
+			       &resp_desc, resp, sizeof(*resp), 0);
+	if (rc < 0) {
+		pr_err("%s: send req failed\n", __func__);
+		goto data_send_err;
+	}
+
+	D("%s: data_valid %d\n", __func__, resp->data_valid);
+	D("%s: data_len %d\n", __func__, resp->data_len);
+data_send_err:
+	kfree(resp);
+	kfree(req);
+	return rc;
+}
+
+static void test_clnt_recv_msg(struct work_struct *work)
+{
+	int rc;
+
+	rc = qmi_recv_msg(test_clnt);
+	if (rc < 0)
+		pr_err("%s: Error receiving message\n", __func__);
+}
+
+static void test_clnt_notify(struct qmi_handle *handle,
+			     enum qmi_event_type event, void *notify_priv)
+{
+	switch (event) {
+	case QMI_RECV_MSG:
+		queue_delayed_work(test_clnt_workqueue,
+				   &work_recv_msg, 0);
+		break;
+	default:
+		break;
+	}
+}
+
+static void test_clnt_svc_arrive(struct work_struct *work)
+{
+	int rc;
+
+	D("%s begins\n", __func__);
+
+	/* Create a Local client port for QMI communication */
+	test_clnt = qmi_handle_create(test_clnt_notify, NULL);
+	if (!test_clnt) {
+		pr_err("%s: QMI client handle alloc failed\n", __func__);
+		return;
+	}
+
+	D("%s: Lookup server name\n", __func__);
+	rc = qmi_connect_to_service(test_clnt, TEST_SERVICE_SVC_ID,
+				    TEST_SERVICE_INS_ID);
+	if (rc < 0) {
+		pr_err("%s: Server not found\n", __func__);
+		qmi_handle_destroy(test_clnt);
+		test_clnt = NULL;
+		return;
+	}
+	test_clnt_reset = 0;
+	D("%s complete\n", __func__);
+}
+
+static void test_clnt_svc_exit(struct work_struct *work)
+{
+	D("%s begins\n", __func__);
+
+	qmi_handle_destroy(test_clnt);
+	test_clnt_reset = 1;
+	test_clnt = NULL;
+
+	D("%s complete\n", __func__);
+}
+
+static int test_clnt_svc_event_notify(struct notifier_block *this,
+				      unsigned long code,
+				      void *_cmd)
+{
+	D("%s: event %ld\n", __func__, code);
+	switch (code) {
+	case QMI_SERVER_ARRIVE:
+		queue_delayed_work(test_clnt_workqueue,
+				   &work_svc_arrive, 0);
+		break;
+	case QMI_SERVER_EXIT:
+		queue_delayed_work(test_clnt_workqueue,
+				   &work_svc_exit, 0);
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+static int test_qmi_open(struct inode *ip, struct file *fp)
+{
+	if (!test_clnt) {
+		pr_err("%s Test client is not initialized\n", __func__);
+		return -ENODEV;
+	}
+	return 0;
+}
+
+static ssize_t test_qmi_read(struct file *fp, char __user *buf,
+		size_t count, loff_t *pos)
+{
+	char _buf[16];
+	snprintf(_buf, sizeof(_buf), "%d\n", test_res);
+	test_res = 0;
+	return simple_read_from_buffer(buf, count, pos,
+				       _buf, strnlen(_buf, 16));
+}
+
+static int test_qmi_release(struct inode *ip, struct file *fp)
+{
+	return 0;
+}
+
+static ssize_t test_qmi_write(struct file *fp, const char __user *buf,
+			size_t count, loff_t *pos)
+{
+	unsigned char cmd[64];
+	int len;
+	int i;
+
+	if (count < 1)
+		return 0;
+
+	len = min(count, (sizeof(cmd) - 1));
+
+	if (copy_from_user(cmd, buf, len))
+		return -EFAULT;
+
+	cmd[len] = 0;
+	if (cmd[len-1] == '\n') {
+		cmd[len-1] = 0;
+		len--;
+	}
+
+	if (!strncmp(cmd, "ping_pong", sizeof(cmd))) {
+		for (i = 0; i < test_rep_cnt; i++) {
+			test_res = test_qmi_ping_pong_send_sync_msg();
+			if (test_res == -ENETRESET || test_clnt_reset) {
+				do {
+					msleep(50);
+				} while (test_clnt_reset);
+			}
+		}
+	} else if (!strncmp(cmd, "data", sizeof(cmd))) {
+		for (i = 0; i < test_rep_cnt; i++) {
+			test_res = test_qmi_data_send_sync_msg(test_data_sz);
+			if (test_res == -ENETRESET || test_clnt_reset) {
+				do {
+					msleep(50);
+				} while (test_clnt_reset);
+			}
+		}
+	} else {
+		test_res = -EINVAL;
+	}
+	return count;
+}
+
+static struct notifier_block test_clnt_nb = {
+	.notifier_call = test_clnt_svc_event_notify,
+};
+
+static const struct file_operations debug_ops = {
+	.owner = THIS_MODULE,
+	.open = test_qmi_open,
+	.read = test_qmi_read,
+	.write = test_qmi_write,
+	.release = test_qmi_release,
+};
+
+static int __init test_qmi_init(void)
+{
+	int rc;
+
+	test_clnt_workqueue = create_singlethread_workqueue("test_clnt");
+	if (!test_clnt_workqueue)
+		return -EFAULT;
+
+	rc = qmi_svc_event_notifier_register(TEST_SERVICE_SVC_ID,
+				TEST_SERVICE_INS_ID, &test_clnt_nb);
+	if (rc < 0) {
+		pr_err("%s: notifier register failed\n", __func__);
+		destroy_workqueue(test_clnt_workqueue);
+		return rc;
+	}
+
+	test_dent = debugfs_create_file("test_qmi_client", 0444, 0,
+					 NULL, &debug_ops);
+	if (IS_ERR(test_dent)) {
+		pr_err("%s: unable to create debugfs %ld\n",
+			__func__, IS_ERR(test_dent));
+		test_dent = NULL;
+		qmi_svc_event_notifier_unregister(TEST_SERVICE_SVC_ID,
+					TEST_SERVICE_INS_ID, &test_clnt_nb);
+		destroy_workqueue(test_clnt_workqueue);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+static void __exit test_qmi_exit(void)
+{
+	qmi_svc_event_notifier_unregister(TEST_SERVICE_SVC_ID,
+					TEST_SERVICE_INS_ID, &test_clnt_nb);
+	destroy_workqueue(test_clnt_workqueue);
+	debugfs_remove(test_dent);
+}
+
+module_init(test_qmi_init);
+module_exit(test_qmi_exit);
+
+MODULE_DESCRIPTION("TEST QMI Client Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index e360906..f410e7f 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -942,11 +942,12 @@
 	return cs->read(NULL);
 }
 
-int read_current_timer(unsigned long *timer_val)
+static struct delay_timer msm_delay_timer;
+
+static unsigned long msm_read_current_timer(void)
 {
 	struct msm_clock *dgt = &msm_clocks[MSM_CLOCK_DGT];
-	*timer_val = msm_read_timer_count(dgt, GLOBAL_TIMER);
-	return 0;
+	return msm_read_timer_count(dgt, GLOBAL_TIMER);
 }
 
 static void __init msm_sched_clock_init(void)
@@ -1184,13 +1185,13 @@
 		}
 	}
 
-#ifdef ARCH_HAS_READ_CURRENT_TIMER
 	if (is_smp()) {
 		__raw_writel(1,
 			msm_clocks[MSM_CLOCK_DGT].regbase + TIMER_ENABLE);
-		set_delay_fn(read_current_timer_delay_loop);
+		msm_delay_timer.freq = dgt->freq;
+		msm_delay_timer.read_current_timer = &msm_read_current_timer;
+		register_current_timer_delay(&msm_delay_timer);
 	}
-#endif
 
 #ifdef CONFIG_LOCAL_TIMERS
 	local_timer_register(&msm_lt_ops);
diff --git a/arch/arm/mach-msm/timer.h b/arch/arm/mach-msm/timer.h
index ebe1819..9a213e5 100644
--- a/arch/arm/mach-msm/timer.h
+++ b/arch/arm/mach-msm/timer.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, 2011-2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 2011-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
diff --git a/arch/arm/mach-msm/tz_log.c b/arch/arm/mach-msm/tz_log.c
index 5a7ec69..11dc436 100644
--- a/arch/arm/mach-msm/tz_log.c
+++ b/arch/arm/mach-msm/tz_log.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -12,16 +12,27 @@
  */
 #include <linux/debugfs.h>
 #include <linux/errno.h>
+#include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/msm_ion.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <linux/string.h>
 #include <linux/types.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
+#include <mach/scm.h>
+#include <mach/qseecomi.h>
 
 #define DEBUG_MAX_RW_BUF 4096
 
+/* QSEE_LOG_BUF_SIZE = 32K */
+#define QSEE_LOG_BUF_SIZE 0x8000
+
+
+/* TZ Diagnostic Area legacy version number */
+#define TZBSP_DIAG_MAJOR_VERSION_LEGACY	2
 /*
  * Preprocessor Definitions and Constants
  */
@@ -96,6 +107,24 @@
 	uint8_t int_desc[TZBSP_MAX_INT_DESC];
 	uint64_t int_count[TZBSP_CPU_COUNT]; /* # of times seen per CPU */
 };
+
+/*
+ * Log ring buffer position
+ */
+struct tzdbg_log_pos_t {
+	uint16_t wrap;
+	uint16_t offset;
+};
+
+ /*
+ * Log ring buffer
+ */
+struct tzdbg_log_t {
+	struct tzdbg_log_pos_t	log_pos;
+	/* open ended array to the end of the 4K IMEM buffer */
+	uint8_t					log_buf[];
+};
+
 /*
  * Diagnostic Table
  */
@@ -147,7 +176,7 @@
 	/*
 	 * We need at least 2K for the ring buffer
 	 */
-	uint8_t *ring_buffer;	/* TZ Ring Buffer */
+	struct tzdbg_log_t ring_buffer;	/* TZ Ring Buffer */
 };
 
 /*
@@ -160,7 +189,8 @@
 	TZDBG_VMID,
 	TZDBG_GENERAL,
 	TZDBG_LOG,
-	TZDBG_STATS_MAX,
+	TZDBG_QSEE_LOG,
+	TZDBG_STATS_MAX
 };
 
 struct tzdbg_stat {
@@ -184,8 +214,10 @@
 	.stat[TZDBG_VMID].name = "vmid",
 	.stat[TZDBG_GENERAL].name = "general",
 	.stat[TZDBG_LOG].name = "log",
+	.stat[TZDBG_QSEE_LOG].name = "qsee_log",
 };
 
+static struct tzdbg_log_t *g_qsee_log;
 
 /*
  * Debugfs data structure and functions
@@ -346,7 +378,7 @@
 	return len;
 }
 
-static int _disp_tz_log_stats(void)
+static int _disp_tz_log_stats_legacy(void)
 {
 	int len = 0;
 	unsigned char *ptr;
@@ -360,6 +392,97 @@
 	return len;
 }
 
+static int _disp_log_stats(struct tzdbg_log_t *log,
+			struct tzdbg_log_pos_t *log_start, uint32_t log_len,
+			size_t count, uint32_t buf_idx)
+{
+	uint32_t wrap_start;
+	uint32_t wrap_end;
+	uint32_t wrap_cnt;
+	int max_len;
+	int len = 0;
+	int i = 0;
+
+	wrap_start = log_start->wrap;
+	wrap_end = log->log_pos.wrap;
+
+	/* Calculate difference in # of buffer wrap-arounds */
+	if (wrap_end >= wrap_start) {
+		wrap_cnt = wrap_end - wrap_start;
+	} else {
+		/* wrap counter has wrapped around, invalidate start position */
+		wrap_cnt = 2;
+	}
+
+	if (wrap_cnt > 1) {
+		/* end position has wrapped around more than once, */
+		/* current start no longer valid                   */
+		log_start->wrap = log->log_pos.wrap - 1;
+		log_start->offset = (log->log_pos.offset + 1) % log_len;
+	} else if ((wrap_cnt == 1) &&
+		(log->log_pos.offset > log_start->offset)) {
+		/* end position has overwritten start */
+		log_start->offset = (log->log_pos.offset + 1) % log_len;
+	}
+
+	while (log_start->offset == log->log_pos.offset) {
+		/*
+		 * No data in ring buffer,
+		 * so we'll hang around until something happens
+		 */
+		unsigned long t = msleep_interruptible(50);
+		if (t != 0) {
+			/* Some event woke us up, so let's quit */
+			return 0;
+		}
+
+		if (buf_idx == TZDBG_LOG)
+			memcpy_fromio((void *)tzdbg.diag_buf, tzdbg.virt_iobase,
+						DEBUG_MAX_RW_BUF);
+
+	}
+
+	max_len = (count > DEBUG_MAX_RW_BUF) ? DEBUG_MAX_RW_BUF : count;
+
+	/*
+	 *  Read from ring buff while there is data and space in return buff
+	 */
+	while ((log_start->offset != log->log_pos.offset) && (len < max_len)) {
+		tzdbg.disp_buf[i++] = log->log_buf[log_start->offset];
+		log_start->offset = (log_start->offset + 1) % log_len;
+		if (0 == log_start->offset)
+			++log_start->wrap;
+		++len;
+	}
+
+	/*
+	 * return buffer to caller
+	 */
+	tzdbg.stat[buf_idx].data = tzdbg.disp_buf;
+	return len;
+}
+
+static int _disp_tz_log_stats(size_t count)
+{
+	static struct tzdbg_log_pos_t log_start = {0};
+	struct tzdbg_log_t *log_ptr;
+	log_ptr = (struct tzdbg_log_t *)((unsigned char *)tzdbg.diag_buf +
+				tzdbg.diag_buf->ring_off -
+				offsetof(struct tzdbg_log_t, log_buf));
+
+	return _disp_log_stats(log_ptr, &log_start,
+				tzdbg.diag_buf->ring_len, count, TZDBG_LOG);
+}
+
+static int _disp_qsee_log_stats(size_t count)
+{
+	static struct tzdbg_log_pos_t log_start = {0};
+
+	return _disp_log_stats(g_qsee_log, &log_start,
+			QSEE_LOG_BUF_SIZE - sizeof(struct tzdbg_log_pos_t),
+			count, TZDBG_QSEE_LOG);
+}
+
 static ssize_t tzdbgfs_read(struct file *file, char __user *buf,
 	size_t count, loff_t *offp)
 {
@@ -385,7 +508,17 @@
 		len = _disp_tz_vmid_stats();
 		break;
 	case TZDBG_LOG:
-		len = _disp_tz_log_stats();
+		if (TZBSP_DIAG_MAJOR_VERSION_LEGACY <
+				(tzdbg.diag_buf->version >> 16)) {
+			len = _disp_tz_log_stats(count);
+			*offp = 0;
+		} else {
+			len = _disp_tz_log_stats_legacy();
+		}
+		break;
+	case TZDBG_QSEE_LOG:
+		len = _disp_qsee_log_stats(count);
+		*offp = 0;
 		break;
 	default:
 		break;
@@ -410,6 +543,78 @@
 	.open    = tzdbgfs_open,
 };
 
+static struct ion_client  *g_ion_clnt;
+static struct ion_handle *g_ihandle;
+
+/*
+ * Allocates log buffer from ION, registers the buffer at TZ
+ */
+static void tzdbg_register_qsee_log_buf(void)
+{
+	/* register log buffer scm request */
+	struct qseecom_reg_log_buf_ireq req;
+
+	/* scm response */
+	struct qseecom_command_scm_resp resp;
+	ion_phys_addr_t pa = 0;
+	uint32_t len;
+	int ret = 0;
+
+	/* Create ION msm client */
+	g_ion_clnt = msm_ion_client_create(ION_HEAP_CARVEOUT_MASK, "qsee_log");
+	if (g_ion_clnt == NULL) {
+		pr_err("%s: Ion client cannot be created\n", __func__);
+		return;
+	}
+
+	g_ihandle = ion_alloc(g_ion_clnt, QSEE_LOG_BUF_SIZE,
+			4096, ION_HEAP(ION_QSECOM_HEAP_ID), 0);
+	if (IS_ERR_OR_NULL(g_ihandle)) {
+		pr_err("%s: Ion client could not retrieve the handle\n",
+			__func__);
+		goto err1;
+	}
+
+	ret = ion_phys(g_ion_clnt, g_ihandle, &pa, &len);
+	if (ret) {
+		pr_err("%s: Ion conversion to physical address failed\n",
+			__func__);
+		goto err2;
+	}
+
+	req.qsee_cmd_id = QSEOS_REGISTER_LOG_BUF_COMMAND;
+	req.phy_addr = pa;
+	req.len = len;
+
+	/*  SCM_CALL  to register the log buffer */
+	ret = scm_call(SCM_SVC_TZSCHEDULER, 1,  &req, sizeof(req),
+		&resp, sizeof(resp));
+	if (ret) {
+		pr_err("%s: scm_call to register log buffer failed\n",
+			__func__);
+		goto err2;
+	}
+
+	if (resp.result != QSEOS_RESULT_SUCCESS) {
+		pr_err(
+		"%s: scm_call to register log buf failed, resp result =%d\n",
+		__func__, resp.result);
+		goto err2;
+	}
+
+	g_qsee_log =
+		(struct tzdbg_log_t *)ion_map_kernel(g_ion_clnt, g_ihandle);
+	g_qsee_log->log_pos.wrap = g_qsee_log->log_pos.offset = 0;
+	return;
+
+err2:
+	ion_free(g_ion_clnt, g_ihandle);
+	g_ihandle = NULL;
+err1:
+	ion_client_destroy(g_ion_clnt);
+	g_ion_clnt = NULL;
+}
+
 static int  tzdbgfs_init(struct platform_device *pdev)
 {
 	int rc = 0;
@@ -456,6 +661,13 @@
 	kzfree(tzdbg.disp_buf);
 	dent_dir = platform_get_drvdata(pdev);
 	debugfs_remove_recursive(dent_dir);
+	if (g_ion_clnt != NULL) {
+		if (!IS_ERR_OR_NULL(g_ihandle)) {
+			ion_unmap_kernel(g_ion_clnt, g_ihandle);
+			ion_free(g_ion_clnt, g_ihandle);
+		}
+	ion_client_destroy(g_ion_clnt);
+}
 }
 
 /*
@@ -527,6 +739,7 @@
 	if (tzdbgfs_init(pdev))
 		goto err;
 
+	tzdbg_register_qsee_log_buf();
 	return 0;
 err:
 	kfree(tzdbg.diag_buf);
diff --git a/arch/arm/mach-msm/vreg.c b/arch/arm/mach-msm/vreg.c
index 271da86..c3298b4 100644
--- a/arch/arm/mach-msm/vreg.c
+++ b/arch/arm/mach-msm/vreg.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/vreg.c
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2009-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012 The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/xo-fsm9xxx.c b/arch/arm/mach-msm/xo-fsm9xxx.c
index cbf3b7a..34c9688 100644
--- a/arch/arm/mach-msm/xo-fsm9xxx.c
+++ b/arch/arm/mach-msm/xo-fsm9xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-sa1100/sleep.S b/arch/arm/mach-sa1100/sleep.S
index 30cc672..8586374 100644
--- a/arch/arm/mach-sa1100/sleep.S
+++ b/arch/arm/mach-sa1100/sleep.S
@@ -38,9 +38,9 @@
 	orr     r4, r4, #MDREFR_K1DB2
 	ldr	r5, =PPCR
 
-	@ Pre-load __udelay into the I-cache
+	@ Pre-load __loop_udelay into the I-cache
 	mov	r0, #1
-	bl	__udelay
+	bl	__loop_udelay
 	mov	r0, r0
 
 	@ The following must all exist in a single cache line to
@@ -53,11 +53,11 @@
 	@ delay 90us and set CPU PLL to lowest speed
 	@ fixes resume problem on high speed SA1110
 	mov	r0, #90
-	bl	__udelay
+	bl	__loop_udelay
 	mov	r1, #0
 	str	r1, [r5]
 	mov	r0, #90
-	bl	__udelay
+	bl	__loop_udelay
 
 	/*
 	 * SA1110 SDRAM controller workaround.  register values:
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 6314e94..d177b05 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -7,7 +7,6 @@
 
 obj-$(CONFIG_MMU)		+= fault-armv.o flush.o idmap.o ioremap.o \
 				   mmap.o pgd.o mmu.o vmregion.o
-obj-$(CONFIG_DEBUG_RODATA)	+= rodata.o
 
 ifneq ($(CONFIG_MMU),y)
 obj-y				+= nommu.o
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index bb4da0f..2ec87b8 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -2,7 +2,7 @@
  * arch/arm/mm/cache-l2x0.c - L210/L220 cache controller support
  *
  * Copyright (C) 2007 ARM Limited
- * Copyright (c) 2009, 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, 2011-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 as
@@ -29,7 +29,7 @@
 
 #define CACHE_LINE_SIZE		32
 
-static void __iomem *l2x0_base;
+void __iomem *l2x0_base;
 static DEFINE_RAW_SPINLOCK(l2x0_lock);
 static u32 l2x0_way_mask;	/* Bitmask of active ways */
 static u32 l2x0_size;
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index afaa39d..f6fb3b8 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -165,16 +165,29 @@
 
 static void __dma_clear_buffer(struct page *page, size_t size)
 {
-	void *ptr;
 	/*
 	 * Ensure that the allocated pages are zeroed, and that any data
 	 * lurking in the kernel direct-mapped region is invalidated.
 	 */
-	ptr = page_address(page);
-	if (ptr) {
-		memset(ptr, 0, size);
-		dmac_flush_range(ptr, ptr + size);
-		outer_flush_range(__pa(ptr), __pa(ptr) + size);
+	if (!PageHighMem(page)) {
+		void *ptr = page_address(page);
+		if (ptr) {
+			memset(ptr, 0, size);
+			dmac_flush_range(ptr, ptr + size);
+			outer_flush_range(__pa(ptr), __pa(ptr) + size);
+		}
+	} else {
+		phys_addr_t base = __pfn_to_phys(page_to_pfn(page));
+		phys_addr_t end = base + size;
+		while (size > 0) {
+			void *ptr = kmap_atomic(page);
+			memset(ptr, 0, PAGE_SIZE);
+			dmac_flush_range(ptr, ptr + PAGE_SIZE);
+			kunmap_atomic(ptr);
+			page++;
+			size -= PAGE_SIZE;
+		}
+		outer_flush_range(base, end);
 	}
 }
 
@@ -315,7 +328,7 @@
 
 static void *__alloc_from_contiguous(struct device *dev, size_t size,
 				     pgprot_t prot, struct page **ret_page,
-				     bool no_kernel_mapping);
+				     bool no_kernel_mapping, const void *caller);
 
 static struct arm_vmregion_head coherent_head = {
 	.vm_lock	= __SPIN_LOCK_UNLOCKED(&coherent_head.vm_lock),
@@ -344,7 +357,8 @@
 	if (!IS_ENABLED(CONFIG_CMA))
 		return 0;
 
-	ptr = __alloc_from_contiguous(NULL, size, prot, &page, false);
+	ptr = __alloc_from_contiguous(NULL, size, prot, &page, false,
+						coherent_init);
 	if (ptr) {
 		coherent_head.vm_start = (unsigned long) ptr;
 		coherent_head.vm_end = (unsigned long) ptr + size;
@@ -465,7 +479,7 @@
 	return NULL;
 }
 
-static void __dma_free_remap(void *cpu_addr, size_t size)
+static void __dma_free_remap(void *cpu_addr, size_t size, bool no_warn)
 {
 	struct arm_vmregion *c;
 	unsigned long addr;
@@ -475,9 +489,11 @@
 
 	c = arm_vmregion_find_remove(&consistent_head, (unsigned long)cpu_addr);
 	if (!c) {
-		pr_err("%s: trying to free invalid coherent area: %p\n",
-		       __func__, cpu_addr);
-		dump_stack();
+		if (!no_warn) {
+			pr_err("%s: trying to free invalid coherent area: %p\n",
+			       __func__, cpu_addr);
+			dump_stack();
+		}
 		return;
 	}
 
@@ -619,29 +635,54 @@
 	return 1;
 }
 
+#define NO_KERNEL_MAPPING_DUMMY	0x2222
 static void *__alloc_from_contiguous(struct device *dev, size_t size,
 				     pgprot_t prot, struct page **ret_page,
-				     bool no_kernel_mapping)
+				     bool no_kernel_mapping,
+				     const void *caller)
 {
 	unsigned long order = get_order(size);
 	size_t count = size >> PAGE_SHIFT;
 	struct page *page;
+	void *ptr;
 
 	page = dma_alloc_from_contiguous(dev, count, order);
 	if (!page)
 		return NULL;
 
 	__dma_clear_buffer(page, size);
-	__dma_remap(page, size, prot, no_kernel_mapping);
 
+	if (!PageHighMem(page)) {
+		__dma_remap(page, size, prot, no_kernel_mapping);
+		ptr = page_address(page);
+	} else {
+		if (no_kernel_mapping) {
+			/*
+			 * Something non-NULL needs to be returned here. Give
+			 * back a dummy address that is unmapped to catch
+			 * clients trying to use the address incorrectly
+			 */
+			ptr = (void *)NO_KERNEL_MAPPING_DUMMY;
+		} else {
+			ptr = __dma_alloc_remap(page, size, GFP_KERNEL, prot,
+						caller);
+			if (!ptr) {
+				dma_release_from_contiguous(dev, page, count);
+				return NULL;
+			}
+		}
+	}
 	*ret_page = page;
-	return page_address(page);
+	return ptr;
 }
 
 static void __free_from_contiguous(struct device *dev, struct page *page,
-				   size_t size)
+				   void *cpu_addr, size_t size)
 {
-	__dma_remap(page, size, pgprot_kernel, false);
+	if (!PageHighMem(page))
+		__dma_remap(page, size, pgprot_kernel, false);
+	else
+		__dma_free_remap(cpu_addr, size, true);
 	dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
 }
 
@@ -731,7 +772,7 @@
 		addr = __alloc_from_pool(dev, size, &page, caller);
 	else
 		addr = __alloc_from_contiguous(dev, size, prot, &page,
-						no_kernel_mapping);
+						no_kernel_mapping, caller);
 
 	if (addr)
 		*handle = pfn_to_dma(dev, page_to_pfn(page));
@@ -798,7 +839,7 @@
 	if (arch_is_coherent() || nommu()) {
 		__dma_free_buffer(page, size);
 	} else if (!IS_ENABLED(CONFIG_CMA)) {
-		__dma_free_remap(cpu_addr, size);
+		__dma_free_remap(cpu_addr, size, false);
 		__dma_free_buffer(page, size);
 	} else {
 		if (__free_from_pool(cpu_addr, size))
@@ -807,7 +848,7 @@
 		 * Non-atomic allocations cannot be freed with IRQs disabled
 		 */
 		WARN_ON(irqs_disabled());
-		__free_from_contiguous(dev, page, size);
+		__free_from_contiguous(dev, page, cpu_addr, size);
 	}
 }
 
@@ -815,25 +856,27 @@
 	size_t size, enum dma_data_direction dir,
 	void (*op)(const void *, size_t, int))
 {
+	unsigned long pfn;
+	size_t left = size;
+
+	pfn = page_to_pfn(page) + offset / PAGE_SIZE;
+	offset %= PAGE_SIZE;
+
 	/*
 	 * A single sg entry may refer to multiple physically contiguous
 	 * pages.  But we still need to process highmem pages individually.
 	 * If highmem is not configured then the bulk of this loop gets
 	 * optimized out.
 	 */
-	size_t left = size;
 	do {
 		size_t len = left;
 		void *vaddr;
 
+		page = pfn_to_page(pfn);
+
 		if (PageHighMem(page)) {
-			if (len + offset > PAGE_SIZE) {
-				if (offset >= PAGE_SIZE) {
-					page += offset / PAGE_SIZE;
-					offset %= PAGE_SIZE;
-				}
+			if (len + offset > PAGE_SIZE)
 				len = PAGE_SIZE - offset;
-			}
 			vaddr = kmap_high_get(page);
 			if (vaddr) {
 				vaddr += offset;
@@ -850,7 +893,7 @@
 			op(vaddr, len, dir);
 		}
 		offset = 0;
-		page++;
+		pfn++;
 		left -= len;
 	} while (left);
 }
@@ -1332,7 +1375,7 @@
 	c = arm_vmregion_find(&consistent_head, (unsigned long)cpu_addr);
 	if (c) {
 		struct page **pages = c->priv;
-		__dma_free_remap(cpu_addr, size);
+		__dma_free_remap(cpu_addr, size, false);
 		__iommu_remove_mapping(dev, handle, size);
 		__iommu_free_buffer(dev, pages, size);
 	}
diff --git a/arch/arm/mm/emulate_domain_manager-v7.c b/arch/arm/mm/emulate_domain_manager-v7.c
index 3797e21..86b5278 100644
--- a/arch/arm/mm/emulate_domain_manager-v7.c
+++ b/arch/arm/mm/emulate_domain_manager-v7.c
@@ -4,7 +4,7 @@
  *
  * Requires hooks to be alerted to any runtime changes of dacr or MMU context.
  *
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, 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
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 0ebc2b9..bf59a9d 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -224,7 +224,7 @@
  * allocations.  This must be the smallest DMA mask in the system,
  * so a successful GFP_DMA allocation will always satisfy this.
  */
-u32 arm_dma_limit;
+phys_addr_t arm_dma_limit;
 
 static void __init arm_adjust_dma_zone(unsigned long *size, unsigned long *hole,
 	unsigned long dma_size)
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index 8877ddd..21653f2 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -65,9 +65,9 @@
 #endif
 
 #ifdef CONFIG_ZONE_DMA
-extern u32 arm_dma_limit;
+extern phys_addr_t arm_dma_limit;
 #else
-#define arm_dma_limit ((u32)~0)
+#define arm_dma_limit ((phys_addr_t)~0)
 #endif
 
 struct map_desc;
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 8575f78..25cb67c 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -604,53 +604,30 @@
 	return early_alloc_aligned(sz, sz);
 }
 
-static pte_t * __init early_pte_alloc(pmd_t *pmd)
-{
-	if (pmd_none(*pmd) || pmd_bad(*pmd))
-		return early_alloc(PTE_HWTABLE_OFF + PTE_HWTABLE_SIZE);
-	return pmd_page_vaddr(*pmd);
-}
-
-static void __init early_pte_install(pmd_t *pmd, pte_t *pte, unsigned long prot)
-{
-	__pmd_populate(pmd, __pa(pte), prot);
-	BUG_ON(pmd_bad(*pmd));
-}
-
-#ifdef CONFIG_HIGHMEM
-static pte_t * __init early_pte_alloc_and_install(pmd_t *pmd,
-	unsigned long addr, unsigned long prot)
+static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned long prot)
 {
 	if (pmd_none(*pmd)) {
-		pte_t *pte = early_pte_alloc(pmd);
-		early_pte_install(pmd, pte, prot);
+		pte_t *pte = early_alloc(PTE_HWTABLE_OFF + PTE_HWTABLE_SIZE);
+		__pmd_populate(pmd, __pa(pte), prot);
 	}
 	BUG_ON(pmd_bad(*pmd));
 	return pte_offset_kernel(pmd, addr);
 }
-#endif
 
 static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
 				  unsigned long end, unsigned long pfn,
 				  const struct mem_type *type)
 {
-	pte_t *start_pte = early_pte_alloc(pmd);
-	pte_t *pte = start_pte + pte_index(addr);
-
-	/* If replacing a section mapping, the whole section must be replaced */
-	BUG_ON(pmd_bad(*pmd) && ((addr | end) & ~PMD_MASK));
-
+	pte_t *pte = early_pte_alloc(pmd, addr, type->prot_l1);
 	do {
 		set_pte_ext(pte, pfn_pte(pfn, __pgprot(type->prot_pte)), 0);
 		pfn++;
 	} while (pte++, addr += PAGE_SIZE, addr != end);
-	early_pte_install(pmd, start_pte, type->prot_l1);
 }
 
 static void __init alloc_init_section(pud_t *pud, unsigned long addr,
 				      unsigned long end, phys_addr_t phys,
-				      const struct mem_type *type,
-				      bool force_pages)
+				      const struct mem_type *type)
 {
 	pmd_t *pmd = pmd_offset(pud, addr);
 
@@ -660,7 +637,7 @@
 	 * L1 entries, whereas PGDs refer to a group of L1 entries making
 	 * up one logical pointer to an L2 table.
 	 */
-	if (type->prot_sect && ((addr | end | phys) & ~SECTION_MASK) == 0 && !force_pages) {
+	if (type->prot_sect && ((addr | end | phys) & ~SECTION_MASK) == 0) {
 		pmd_t *p = pmd;
 
 #ifndef CONFIG_ARM_LPAE
@@ -684,15 +661,14 @@
 }
 
 static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
-	unsigned long end, unsigned long phys, const struct mem_type *type,
-	bool force_pages)
+	unsigned long end, unsigned long phys, const struct mem_type *type)
 {
 	pud_t *pud = pud_offset(pgd, addr);
 	unsigned long next;
 
 	do {
 		next = pud_addr_end(addr, end);
-		alloc_init_section(pud, addr, next, phys, type, force_pages);
+		alloc_init_section(pud, addr, next, phys, type);
 		phys += next - addr;
 	} while (pud++, addr = next, addr != end);
 }
@@ -766,7 +742,7 @@
  * offsets, and we take full advantage of sections and
  * supersections.
  */
-static void __init create_mapping(struct map_desc *md, bool force_pages)
+static void __init create_mapping(struct map_desc *md)
 {
 	unsigned long addr, length, end;
 	phys_addr_t phys;
@@ -818,7 +794,7 @@
 	do {
 		unsigned long next = pgd_addr_end(addr, end);
 
-		alloc_init_pud(pgd, addr, next, phys, type, force_pages);
+		alloc_init_pud(pgd, addr, next, phys, type);
 
 		phys += next - addr;
 		addr = next;
@@ -839,7 +815,7 @@
 	vm = early_alloc_aligned(sizeof(*vm) * nr, __alignof__(*vm));
 
 	for (md = io_desc; nr; md++, nr--) {
-		create_mapping(md, false);
+		create_mapping(md);
 		vm->addr = (void *)(md->virtual & PAGE_MASK);
 		vm->size = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK));
 		vm->phys_addr = __pfn_to_phys(md->pfn); 
@@ -1199,12 +1175,12 @@
 	map.virtual = 0xffff0000;
 	map.length = PAGE_SIZE;
 	map.type = MT_HIGH_VECTORS;
-	create_mapping(&map, false);
+	create_mapping(&map);
 
 	if (!vectors_high()) {
 		map.virtual = 0;
 		map.type = MT_LOW_VECTORS;
-		create_mapping(&map, false);
+		create_mapping(&map);
 	}
 
 	/*
@@ -1224,7 +1200,7 @@
 			map.virtual = CONFIG_ARM_USER_ACCESSIBLE_TIMER_BASE;
 			map.length = PAGE_SIZE;
 			map.type = MT_DEVICE_USER_ACCESSIBLE;
-			create_mapping(&map, false);
+			create_mapping(&map);
 		}
 	}
 
@@ -1241,7 +1217,7 @@
 static void __init kmap_init(void)
 {
 #ifdef CONFIG_HIGHMEM
-	pkmap_page_table = early_pte_alloc_and_install(pmd_off_k(PKMAP_BASE),
+	pkmap_page_table = early_pte_alloc(pmd_off_k(PKMAP_BASE),
 		PKMAP_BASE, _PAGE_KERNEL_TABLE);
 #endif
 }
@@ -1349,14 +1325,12 @@
 static void __init map_lowmem(void)
 {
 	struct memblock_region *reg;
-	phys_addr_t start;
-	phys_addr_t end;
-	struct map_desc map;
 
 	/* Map all the lowmem memory banks. */
 	for_each_memblock(memory, reg) {
-		start = reg->base;
-		end = start + reg->size;
+		phys_addr_t start = reg->base;
+		phys_addr_t end = start + reg->size;
+		struct map_desc map;
 
 		if (end > arm_lowmem_limit)
 			end = arm_lowmem_limit;
@@ -1370,28 +1344,28 @@
 			map.length = SECTION_SIZE;
 			map.type = MT_MEMORY;
 
-			create_mapping(&map, false);
+			create_mapping(&map);
 
 			map.pfn = __phys_to_pfn(start + SECTION_SIZE);
 			map.virtual = __phys_to_virt(start + SECTION_SIZE);
 			map.length = (unsigned long)RX_AREA_END - map.virtual;
 			map.type = MT_MEMORY_RX;
 
-			create_mapping(&map, false);
+			create_mapping(&map);
 
 			map.pfn = __phys_to_pfn(__pa(__start_rodata));
 			map.virtual = (unsigned long)__start_rodata;
 			map.length = __init_begin - __start_rodata;
 			map.type = MT_MEMORY_R;
 
-			create_mapping(&map, false);
+			create_mapping(&map);
 
 			map.pfn = __phys_to_pfn(__pa(__init_begin));
 			map.virtual = (unsigned long)__init_begin;
 			map.length = __init_data - __init_begin;
 			map.type = MT_MEMORY;
 
-			create_mapping(&map, false);
+			create_mapping(&map);
 
 			map.pfn = __phys_to_pfn(__pa(__init_data));
 			map.virtual = (unsigned long)__init_data;
@@ -1406,20 +1380,8 @@
 		map.type = MT_MEMORY;
 #endif
 
-		create_mapping(&map, false);
+		create_mapping(&map);
 	}
-
-#ifdef CONFIG_DEBUG_RODATA
-	start = __pa(_stext) & PMD_MASK;
-	end = ALIGN(__pa(__end_rodata), PMD_SIZE);
-
-	map.pfn = __phys_to_pfn(start);
-	map.virtual = __phys_to_virt(start);
-	map.length = end - start;
-	map.type = MT_MEMORY;
-
-	create_mapping(&map, true);
-#endif
 }
 
 /*
diff --git a/arch/arm/mm/rodata.c b/arch/arm/mm/rodata.c
deleted file mode 100644
index 9a8eb84..0000000
--- a/arch/arm/mm/rodata.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- *  linux/arch/arm/mm/rodata.c
- *
- *  Copyright (C) 2011 Google, Inc.
- *
- *  Author: Colin Cross <ccross@android.com>
- *
- *  Based on x86 implementation in arch/x86/mm/init_32.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-
-#include <asm/cache.h>
-#include <asm/pgtable.h>
-#include <asm/rodata.h>
-#include <asm/sections.h>
-#include <asm/tlbflush.h>
-
-#include "mm.h"
-
-static int kernel_set_to_readonly __read_mostly;
-
-#ifdef CONFIG_DEBUG_RODATA_TEST
-static const int rodata_test_data = 0xC3;
-
-static noinline void rodata_test(void)
-{
-	int result;
-
-	pr_info("%s: attempting to write to read-only section:\n", __func__);
-
-	if (*(volatile int *)&rodata_test_data != 0xC3) {
-		pr_err("read only data changed before test\n");
-		return;
-	}
-
-	/*
-	 * Attempt to to write to rodata_test_data, trapping the expected
-	 * data abort.  If the trap executed, result will be 1.  If it didn't,
-	 * result will be 0xFF.
-	 */
-	asm volatile(
-		"0:	str	%[zero], [%[rodata_test_data]]\n"
-		"	mov	%[result], #0xFF\n"
-		"	b	2f\n"
-		"1:	mov	%[result], #1\n"
-		"2:\n"
-
-		/* Exception fixup - if store at label 0 faults, jumps to 1 */
-		".pushsection __ex_table, \"a\"\n"
-		"	.long	0b, 1b\n"
-		".popsection\n"
-
-		: [result] "=r" (result)
-		: [rodata_test_data] "r" (&rodata_test_data), [zero] "r" (0)
-		: "memory"
-	);
-
-	if (result == 1)
-		pr_info("write to read-only section trapped, success\n");
-	else
-		pr_err("write to read-only section NOT trapped, test failed\n");
-
-	if (*(volatile int *)&rodata_test_data != 0xC3)
-		pr_err("read only data changed during write\n");
-}
-#else
-static inline void rodata_test(void) { }
-#endif
-
-static int set_page_attributes(unsigned long virt, int numpages,
-	pte_t (*f)(pte_t))
-{
-	pmd_t *pmd;
-	pte_t *pte;
-	unsigned long start = virt;
-	unsigned long end = virt + (numpages << PAGE_SHIFT);
-	unsigned long pmd_end;
-
-	while (virt < end) {
-		pmd = pmd_off_k(virt);
-		pmd_end = min(ALIGN(virt + 1, PMD_SIZE), end);
-
-		if ((pmd_val(*pmd) & PMD_TYPE_MASK) != PMD_TYPE_TABLE) {
-			pr_err("%s: pmd %p=%08lx for %08lx not page table\n",
-				__func__, pmd, pmd_val(*pmd), virt);
-			virt = pmd_end;
-			continue;
-		}
-
-		while (virt < pmd_end) {
-			pte = pte_offset_kernel(pmd, virt);
-			set_pte_ext(pte, f(*pte), 0);
-			virt += PAGE_SIZE;
-		}
-	}
-
-	flush_tlb_kernel_range(start, end);
-
-	return 0;
-}
-
-int set_memory_ro(unsigned long virt, int numpages)
-{
-	return set_page_attributes(virt, numpages, pte_wrprotect);
-}
-EXPORT_SYMBOL(set_memory_ro);
-
-int set_memory_rw(unsigned long virt, int numpages)
-{
-	return set_page_attributes(virt, numpages, pte_mkwrite);
-}
-EXPORT_SYMBOL(set_memory_rw);
-
-void set_kernel_text_rw(void)
-{
-	unsigned long start = PAGE_ALIGN((unsigned long)_text);
-	unsigned long size = PAGE_ALIGN((unsigned long)__end_rodata) - start;
-
-	if (!kernel_set_to_readonly)
-		return;
-
-	pr_debug("Set kernel text: %lx - %lx to read-write\n",
-		 start, start + size);
-
-	set_memory_rw(start, size >> PAGE_SHIFT);
-}
-
-void set_kernel_text_ro(void)
-{
-	unsigned long start = PAGE_ALIGN((unsigned long)_text);
-	unsigned long size = PAGE_ALIGN((unsigned long)__end_rodata) - start;
-
-	if (!kernel_set_to_readonly)
-		return;
-
-	pr_info_once("Write protecting the kernel text section %lx - %lx\n",
-		start, start + size);
-
-	pr_debug("Set kernel text: %lx - %lx to read only\n",
-		 start, start + size);
-
-	set_memory_ro(start, size >> PAGE_SHIFT);
-}
-
-void mark_rodata_ro(void)
-{
-	kernel_set_to_readonly = 1;
-
-	set_kernel_text_ro();
-
-	rodata_test();
-}
diff --git a/arch/arm/mm/vcm.c b/arch/arm/mm/vcm.c
index f2d9457..c4dc1db 100644
--- a/arch/arm/mm/vcm.c
+++ b/arch/arm/mm/vcm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mm/vcm_alloc.c b/arch/arm/mm/vcm_alloc.c
index 5f3c024..2106ebb 100644
--- a/arch/arm/mm/vcm_alloc.c
+++ b/arch/arm/mm/vcm_alloc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mm/vcm_mm.c b/arch/arm/mm/vcm_mm.c
index dee51fa..2642390 100644
--- a/arch/arm/mm/vcm_mm.c
+++ b/arch/arm/mm/vcm_mm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/perfmon/cp15_registers.h b/arch/arm/perfmon/cp15_registers.h
index 3de4d8b..f5ba84e 100644
--- a/arch/arm/perfmon/cp15_registers.h
+++ b/arch/arm/perfmon/cp15_registers.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/perfmon/l2_cp15_registers.h b/arch/arm/perfmon/l2_cp15_registers.h
index 796dc8b..0cf1acd 100644
--- a/arch/arm/perfmon/l2_cp15_registers.h
+++ b/arch/arm/perfmon/l2_cp15_registers.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/perfmon/mcrmrc.h b/arch/arm/perfmon/mcrmrc.h
index 29f9ac0..875c564 100644
--- a/arch/arm/perfmon/mcrmrc.h
+++ b/arch/arm/perfmon/mcrmrc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/perfmon/per-axi.c b/arch/arm/perfmon/per-axi.c
index 48309be..e8bf3e6 100644
--- a/arch/arm/perfmon/per-axi.c
+++ b/arch/arm/perfmon/per-axi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/perfmon/per-axi.h b/arch/arm/perfmon/per-axi.h
index 89f67fc..080079c 100644
--- a/arch/arm/perfmon/per-axi.h
+++ b/arch/arm/perfmon/per-axi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/perfmon/per-process-perf.c b/arch/arm/perfmon/per-process-perf.c
index c8bebd8..57450d9 100644
--- a/arch/arm/perfmon/per-process-perf.c
+++ b/arch/arm/perfmon/per-process-perf.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/perfmon/per.c b/arch/arm/perfmon/per.c
index 4222844..11cdbce 100644
--- a/arch/arm/perfmon/per.c
+++ b/arch/arm/perfmon/per.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/perfmon/perf-function-hooks.c b/arch/arm/perfmon/perf-function-hooks.c
index aacc353..bfe504a 100644
--- a/arch/arm/perfmon/perf-function-hooks.c
+++ b/arch/arm/perfmon/perf-function-hooks.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/perfmon/perf-smp.c b/arch/arm/perfmon/perf-smp.c
index 5417fc7..849658a 100644
--- a/arch/arm/perfmon/perf-smp.c
+++ b/arch/arm/perfmon/perf-smp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/perfmon/perf-v7.c b/arch/arm/perfmon/perf-v7.c
index 614eedc..5810ba7 100644
--- a/arch/arm/perfmon/perf-v7.c
+++ b/arch/arm/perfmon/perf-v7.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/perfmon/perf.h b/arch/arm/perfmon/perf.h
index 1a9bb8b..f02405e 100644
--- a/arch/arm/perfmon/perf.h
+++ b/arch/arm/perfmon/perf.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 2b31f47..2d1494d 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -1190,6 +1190,7 @@
 mpq8064_cdp		MACH_MPQ8064_CDP	MPQ8064_CDP		3993
 mpq8064_hrd		MACH_MPQ8064_HRD	MPQ8064_HRD		3994
 mpq8064_dtv		MACH_MPQ8064_DTV	MPQ8064_DTV		3995
+fsm8064_ep		MACH_FSM8064_EP		FSM8064_EP		3996
 msm7627a_qrd3		MACH_MSM7627A_QRD3	MSM7627A_QRD3		4005
 msm8625_surf		MACH_MSM8625_SURF	MSM8625_SURF		4037
 msm8625_evb		MACH_MSM8625_EVB	MSM8625_EVB		4042
diff --git a/arch/hexagon/include/asm/atomic.h b/arch/hexagon/include/asm/atomic.h
index 3e25804..468fbb0 100644
--- a/arch/hexagon/include/asm/atomic.h
+++ b/arch/hexagon/include/asm/atomic.h
@@ -1,7 +1,7 @@
 /*
  * Atomic operations for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
  *
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/arch/hexagon/include/asm/barrier.h b/arch/hexagon/include/asm/barrier.h
index a4ed6e2..1041a8e 100644
--- a/arch/hexagon/include/asm/barrier.h
+++ b/arch/hexagon/include/asm/barrier.h
@@ -1,7 +1,7 @@
 /*
  * Memory barrier definitions for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/bitops.h b/arch/hexagon/include/asm/bitops.h
index 4caa649..9b1e4af 100644
--- a/arch/hexagon/include/asm/bitops.h
+++ b/arch/hexagon/include/asm/bitops.h
@@ -1,7 +1,7 @@
 /*
  * Bit operations for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
  *
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/arch/hexagon/include/asm/bitsperlong.h b/arch/hexagon/include/asm/bitsperlong.h
index 2701cae..4a65815 100644
--- a/arch/hexagon/include/asm/bitsperlong.h
+++ b/arch/hexagon/include/asm/bitsperlong.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/byteorder.h b/arch/hexagon/include/asm/byteorder.h
index 0e19b9f..e31f3f7 100644
--- a/arch/hexagon/include/asm/byteorder.h
+++ b/arch/hexagon/include/asm/byteorder.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/cache.h b/arch/hexagon/include/asm/cache.h
index 0f01de2..f4ca594 100644
--- a/arch/hexagon/include/asm/cache.h
+++ b/arch/hexagon/include/asm/cache.h
@@ -1,7 +1,7 @@
 /*
  * Cache definitions for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/cacheflush.h b/arch/hexagon/include/asm/cacheflush.h
index 6865c1b..49e0896 100644
--- a/arch/hexagon/include/asm/cacheflush.h
+++ b/arch/hexagon/include/asm/cacheflush.h
@@ -1,7 +1,7 @@
 /*
  * Cache flush operations for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/checksum.h b/arch/hexagon/include/asm/checksum.h
index 3ce4ecd..46ec8a7 100644
--- a/arch/hexagon/include/asm/checksum.h
+++ b/arch/hexagon/include/asm/checksum.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/cmpxchg.h b/arch/hexagon/include/asm/cmpxchg.h
index c5f9527..9e78029 100644
--- a/arch/hexagon/include/asm/cmpxchg.h
+++ b/arch/hexagon/include/asm/cmpxchg.h
@@ -1,7 +1,7 @@
 /*
  * xchg/cmpxchg operations for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
  *
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/arch/hexagon/include/asm/delay.h b/arch/hexagon/include/asm/delay.h
index 9ab12e9..5307971 100644
--- a/arch/hexagon/include/asm/delay.h
+++ b/arch/hexagon/include/asm/delay.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/dma-mapping.h b/arch/hexagon/include/asm/dma-mapping.h
index 233ed3d..85e9935 100644
--- a/arch/hexagon/include/asm/dma-mapping.h
+++ b/arch/hexagon/include/asm/dma-mapping.h
@@ -1,7 +1,7 @@
 /*
  * DMA operations for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/dma.h b/arch/hexagon/include/asm/dma.h
index da6d2f6..9e34ff4 100644
--- a/arch/hexagon/include/asm/dma.h
+++ b/arch/hexagon/include/asm/dma.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/elf.h b/arch/hexagon/include/asm/elf.h
index 37976a0..6ed2364 100644
--- a/arch/hexagon/include/asm/elf.h
+++ b/arch/hexagon/include/asm/elf.h
@@ -1,7 +1,7 @@
 /*
  * ELF definitions for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/exec.h b/arch/hexagon/include/asm/exec.h
index 350e6d4..c32b213 100644
--- a/arch/hexagon/include/asm/exec.h
+++ b/arch/hexagon/include/asm/exec.h
@@ -1,7 +1,7 @@
 /*
  * Process execution related definitions for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/fixmap.h b/arch/hexagon/include/asm/fixmap.h
index b27f494..b75b6bf 100644
--- a/arch/hexagon/include/asm/fixmap.h
+++ b/arch/hexagon/include/asm/fixmap.h
@@ -1,7 +1,7 @@
 /*
  * Fixmap support for Hexagon - enough to support highmem features
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/hexagon_vm.h b/arch/hexagon/include/asm/hexagon_vm.h
index 182cb9d..c144bee 100644
--- a/arch/hexagon/include/asm/hexagon_vm.h
+++ b/arch/hexagon/include/asm/hexagon_vm.h
@@ -1,7 +1,7 @@
 /*
  * Declarations for to Hexagon Virtal Machine.
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/intrinsics.h b/arch/hexagon/include/asm/intrinsics.h
index 1c02186..ca58773 100644
--- a/arch/hexagon/include/asm/intrinsics.h
+++ b/arch/hexagon/include/asm/intrinsics.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/io.h b/arch/hexagon/include/asm/io.h
index b3acc2c..e527cfe 100644
--- a/arch/hexagon/include/asm/io.h
+++ b/arch/hexagon/include/asm/io.h
@@ -1,7 +1,7 @@
 /*
  * IO definitions for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/irq.h b/arch/hexagon/include/asm/irq.h
index ded8c15..51661db 100644
--- a/arch/hexagon/include/asm/irq.h
+++ b/arch/hexagon/include/asm/irq.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/irqflags.h b/arch/hexagon/include/asm/irqflags.h
index ec15236..e5fd949 100644
--- a/arch/hexagon/include/asm/irqflags.h
+++ b/arch/hexagon/include/asm/irqflags.h
@@ -1,7 +1,7 @@
 /*
  * IRQ support for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/kgdb.h b/arch/hexagon/include/asm/kgdb.h
index 9e87797..32a6fb6 100644
--- a/arch/hexagon/include/asm/kgdb.h
+++ b/arch/hexagon/include/asm/kgdb.h
@@ -1,7 +1,7 @@
 /*
  * arch/hexagon/include/asm/kgdb.h - Hexagon KGDB Support
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/linkage.h b/arch/hexagon/include/asm/linkage.h
index a00b85f..31b4cbe 100644
--- a/arch/hexagon/include/asm/linkage.h
+++ b/arch/hexagon/include/asm/linkage.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/mem-layout.h b/arch/hexagon/include/asm/mem-layout.h
index 72e5dcd..af16e97 100644
--- a/arch/hexagon/include/asm/mem-layout.h
+++ b/arch/hexagon/include/asm/mem-layout.h
@@ -1,7 +1,7 @@
 /*
  * Memory layout definitions for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/mmu.h b/arch/hexagon/include/asm/mmu.h
index 30a5d8d..2288b19 100644
--- a/arch/hexagon/include/asm/mmu.h
+++ b/arch/hexagon/include/asm/mmu.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/mmu_context.h b/arch/hexagon/include/asm/mmu_context.h
index b4fe5a5..d423d2e 100644
--- a/arch/hexagon/include/asm/mmu_context.h
+++ b/arch/hexagon/include/asm/mmu_context.h
@@ -1,7 +1,7 @@
 /*
  * MM context support for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/module.h b/arch/hexagon/include/asm/module.h
index 72ba494..6b4323a 100644
--- a/arch/hexagon/include/asm/module.h
+++ b/arch/hexagon/include/asm/module.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/page.h b/arch/hexagon/include/asm/page.h
index edd9762..692adc213 100644
--- a/arch/hexagon/include/asm/page.h
+++ b/arch/hexagon/include/asm/page.h
@@ -1,7 +1,7 @@
 /*
  * Page management definitions for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/param.h b/arch/hexagon/include/asm/param.h
index 285344b..5cec8c0 100644
--- a/arch/hexagon/include/asm/param.h
+++ b/arch/hexagon/include/asm/param.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/perf_event.h b/arch/hexagon/include/asm/perf_event.h
index 8b8526b..430978b 100644
--- a/arch/hexagon/include/asm/perf_event.h
+++ b/arch/hexagon/include/asm/perf_event.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/pgalloc.h b/arch/hexagon/include/asm/pgalloc.h
index 13443c7..679bf6d 100644
--- a/arch/hexagon/include/asm/pgalloc.h
+++ b/arch/hexagon/include/asm/pgalloc.h
@@ -1,7 +1,7 @@
 /*
  * Page table support for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/pgtable.h b/arch/hexagon/include/asm/pgtable.h
index ca619bf..20d55f6 100644
--- a/arch/hexagon/include/asm/pgtable.h
+++ b/arch/hexagon/include/asm/pgtable.h
@@ -1,7 +1,7 @@
 /*
  * Page table support for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/processor.h b/arch/hexagon/include/asm/processor.h
index 20c5dda..9b3aea9 100644
--- a/arch/hexagon/include/asm/processor.h
+++ b/arch/hexagon/include/asm/processor.h
@@ -1,7 +1,7 @@
 /*
  * Process/processor support for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/ptrace.h b/arch/hexagon/include/asm/ptrace.h
index 3d2f607..8ef7840 100644
--- a/arch/hexagon/include/asm/ptrace.h
+++ b/arch/hexagon/include/asm/ptrace.h
@@ -1,7 +1,7 @@
 /*
  * Ptrace definitions for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/registers.h b/arch/hexagon/include/asm/registers.h
index 4dd741b..2bfd64d 100644
--- a/arch/hexagon/include/asm/registers.h
+++ b/arch/hexagon/include/asm/registers.h
@@ -1,7 +1,7 @@
 /*
  * Register definitions for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/setup.h b/arch/hexagon/include/asm/setup.h
index 3b754c5..e48285e 100644
--- a/arch/hexagon/include/asm/setup.h
+++ b/arch/hexagon/include/asm/setup.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/sigcontext.h b/arch/hexagon/include/asm/sigcontext.h
index ce6dcd9..b6ba536 100644
--- a/arch/hexagon/include/asm/sigcontext.h
+++ b/arch/hexagon/include/asm/sigcontext.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/signal.h b/arch/hexagon/include/asm/signal.h
index 471c056..9395568 100644
--- a/arch/hexagon/include/asm/signal.h
+++ b/arch/hexagon/include/asm/signal.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/smp.h b/arch/hexagon/include/asm/smp.h
index 87c869a..2b9b974 100644
--- a/arch/hexagon/include/asm/smp.h
+++ b/arch/hexagon/include/asm/smp.h
@@ -1,7 +1,7 @@
 /*
  * SMP definitions for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/spinlock.h b/arch/hexagon/include/asm/spinlock.h
index 168a920..12ca4eb 100644
--- a/arch/hexagon/include/asm/spinlock.h
+++ b/arch/hexagon/include/asm/spinlock.h
@@ -1,7 +1,7 @@
 /*
  * Spinlock support for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
  *
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/arch/hexagon/include/asm/spinlock_types.h b/arch/hexagon/include/asm/spinlock_types.h
index 5e937af..2ae9ecc 100644
--- a/arch/hexagon/include/asm/spinlock_types.h
+++ b/arch/hexagon/include/asm/spinlock_types.h
@@ -1,7 +1,7 @@
 /*
  * Spinlock support for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/string.h b/arch/hexagon/include/asm/string.h
index f4489c1..7d37f47 100644
--- a/arch/hexagon/include/asm/string.h
+++ b/arch/hexagon/include/asm/string.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/suspend.h b/arch/hexagon/include/asm/suspend.h
index 089dd82..18b44b5 100644
--- a/arch/hexagon/include/asm/suspend.h
+++ b/arch/hexagon/include/asm/suspend.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/swab.h b/arch/hexagon/include/asm/swab.h
index 99cf0be..9069e92 100644
--- a/arch/hexagon/include/asm/swab.h
+++ b/arch/hexagon/include/asm/swab.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/switch_to.h b/arch/hexagon/include/asm/switch_to.h
index 28ca0df..96745e7 100644
--- a/arch/hexagon/include/asm/switch_to.h
+++ b/arch/hexagon/include/asm/switch_to.h
@@ -1,7 +1,7 @@
 /*
  * Task switching definitions for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/syscall.h b/arch/hexagon/include/asm/syscall.h
index 3e7d61d..fb0e9d4 100644
--- a/arch/hexagon/include/asm/syscall.h
+++ b/arch/hexagon/include/asm/syscall.h
@@ -1,7 +1,7 @@
 /*
  * Syscall support for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/thread_info.h b/arch/hexagon/include/asm/thread_info.h
index 9c2934f..e369c1d 100644
--- a/arch/hexagon/include/asm/thread_info.h
+++ b/arch/hexagon/include/asm/thread_info.h
@@ -1,7 +1,7 @@
 /*
  * Thread support for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/time.h b/arch/hexagon/include/asm/time.h
index 081b82c..deda170 100644
--- a/arch/hexagon/include/asm/time.h
+++ b/arch/hexagon/include/asm/time.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/timer-regs.h b/arch/hexagon/include/asm/timer-regs.h
index d80db23..79912b8 100644
--- a/arch/hexagon/include/asm/timer-regs.h
+++ b/arch/hexagon/include/asm/timer-regs.h
@@ -1,7 +1,7 @@
 /*
  * Timer support for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/timex.h b/arch/hexagon/include/asm/timex.h
index b11c62b..f63fe13 100644
--- a/arch/hexagon/include/asm/timex.h
+++ b/arch/hexagon/include/asm/timex.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/tlb.h b/arch/hexagon/include/asm/tlb.h
index 473abde..2f00772 100644
--- a/arch/hexagon/include/asm/tlb.h
+++ b/arch/hexagon/include/asm/tlb.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/tlbflush.h b/arch/hexagon/include/asm/tlbflush.h
index b89a902..62d95a9 100644
--- a/arch/hexagon/include/asm/tlbflush.h
+++ b/arch/hexagon/include/asm/tlbflush.h
@@ -1,7 +1,7 @@
 /*
  * TLB flush support for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/traps.h b/arch/hexagon/include/asm/traps.h
index 6a407f6..ec11285 100644
--- a/arch/hexagon/include/asm/traps.h
+++ b/arch/hexagon/include/asm/traps.h
@@ -1,7 +1,7 @@
 /*
  * Trap support for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/uaccess.h b/arch/hexagon/include/asm/uaccess.h
index 7e706ea..e4127e4 100644
--- a/arch/hexagon/include/asm/uaccess.h
+++ b/arch/hexagon/include/asm/uaccess.h
@@ -1,7 +1,7 @@
 /*
  * User memory access support for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/unistd.h b/arch/hexagon/include/asm/unistd.h
index 4d0ecde..7ac1ef4 100644
--- a/arch/hexagon/include/asm/unistd.h
+++ b/arch/hexagon/include/asm/unistd.h
@@ -1,7 +1,7 @@
 /*
  * Syscall support for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/user.h b/arch/hexagon/include/asm/user.h
index 3a55078..6cbcdf7 100644
--- a/arch/hexagon/include/asm/user.h
+++ b/arch/hexagon/include/asm/user.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/vdso.h b/arch/hexagon/include/asm/vdso.h
index 2d95cbb..ed08e6c 100644
--- a/arch/hexagon/include/asm/vdso.h
+++ b/arch/hexagon/include/asm/vdso.h
@@ -1,7 +1,7 @@
 /*
  * vDSO implementation for Hexagon
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/vm_fault.h b/arch/hexagon/include/asm/vm_fault.h
index cacda36..9b0e9c5 100644
--- a/arch/hexagon/include/asm/vm_fault.h
+++ b/arch/hexagon/include/asm/vm_fault.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/include/asm/vm_mmu.h b/arch/hexagon/include/asm/vm_mmu.h
index 580462d..9a94de7 100644
--- a/arch/hexagon/include/asm/vm_mmu.h
+++ b/arch/hexagon/include/asm/vm_mmu.h
@@ -1,7 +1,7 @@
 /*
  * Hexagon VM page table entry definitions
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/asm-offsets.c b/arch/hexagon/kernel/asm-offsets.c
index 89ffa51..2d5e84d 100644
--- a/arch/hexagon/kernel/asm-offsets.c
+++ b/arch/hexagon/kernel/asm-offsets.c
@@ -5,7 +5,7 @@
  * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
  * Copyright (C) 2000 MIPS Technologies, Inc.
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/dma.c b/arch/hexagon/kernel/dma.c
index 0f2367c..9c3712e 100644
--- a/arch/hexagon/kernel/dma.c
+++ b/arch/hexagon/kernel/dma.c
@@ -1,7 +1,7 @@
 /*
  * DMA implementation for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/head.S b/arch/hexagon/kernel/head.S
index 8e6b819..d859402 100644
--- a/arch/hexagon/kernel/head.S
+++ b/arch/hexagon/kernel/head.S
@@ -1,7 +1,7 @@
 /*
  * Early kernel startup code for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
  *
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/arch/hexagon/kernel/hexagon_ksyms.c b/arch/hexagon/kernel/hexagon_ksyms.c
index 7f18924..32b1379 100644
--- a/arch/hexagon/kernel/hexagon_ksyms.c
+++ b/arch/hexagon/kernel/hexagon_ksyms.c
@@ -1,7 +1,7 @@
 /*
  * Export of symbols defined in assembly files and/or libgcc.
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/init_task.c b/arch/hexagon/kernel/init_task.c
index 73283d3..b4068e3 100644
--- a/arch/hexagon/kernel/init_task.c
+++ b/arch/hexagon/kernel/init_task.c
@@ -1,7 +1,7 @@
 /*
  * Init task definition
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/irq_cpu.c b/arch/hexagon/kernel/irq_cpu.c
index d4416a1..4de9943 100644
--- a/arch/hexagon/kernel/irq_cpu.c
+++ b/arch/hexagon/kernel/irq_cpu.c
@@ -1,7 +1,7 @@
 /*
  * First-level interrupt controller model for Hexagon.
  *
- * Copyright (c) 2010-2011 Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/kgdb.c b/arch/hexagon/kernel/kgdb.c
index fe4aa1b..3446453 100644
--- a/arch/hexagon/kernel/kgdb.c
+++ b/arch/hexagon/kernel/kgdb.c
@@ -1,7 +1,7 @@
 /*
  * arch/hexagon/kernel/kgdb.c - Hexagon KGDB Support
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/module.c b/arch/hexagon/kernel/module.c
index 61a76ba..477d07a 100644
--- a/arch/hexagon/kernel/module.c
+++ b/arch/hexagon/kernel/module.c
@@ -1,7 +1,7 @@
 /*
  * Kernel module loader for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/process.c b/arch/hexagon/kernel/process.c
index ff02821..2bc16a5 100644
--- a/arch/hexagon/kernel/process.c
+++ b/arch/hexagon/kernel/process.c
@@ -1,7 +1,7 @@
 /*
  * Process creation support for Hexagon
  *
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/ptrace.c b/arch/hexagon/kernel/ptrace.c
index 96c3b2c..670b1b0 100644
--- a/arch/hexagon/kernel/ptrace.c
+++ b/arch/hexagon/kernel/ptrace.c
@@ -1,7 +1,7 @@
 /*
  * Ptrace support for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/reset.c b/arch/hexagon/kernel/reset.c
index 4d72fc5..6aeabc9 100644
--- a/arch/hexagon/kernel/reset.c
+++ b/arch/hexagon/kernel/reset.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/setup.c b/arch/hexagon/kernel/setup.c
index 1202f78..94a3878 100644
--- a/arch/hexagon/kernel/setup.c
+++ b/arch/hexagon/kernel/setup.c
@@ -1,7 +1,7 @@
 /*
  * Arch related setup for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/signal.c b/arch/hexagon/kernel/signal.c
index ecbab34..3d1017d 100644
--- a/arch/hexagon/kernel/signal.c
+++ b/arch/hexagon/kernel/signal.c
@@ -1,7 +1,7 @@
 /*
  * Signal support for Hexagon processor
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/smp.c b/arch/hexagon/kernel/smp.c
index 1298141..6fa1dc2 100644
--- a/arch/hexagon/kernel/smp.c
+++ b/arch/hexagon/kernel/smp.c
@@ -1,7 +1,7 @@
 /*
  * SMP support for Hexagon
  *
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/stacktrace.c b/arch/hexagon/kernel/stacktrace.c
index 11c597b..f94918b 100644
--- a/arch/hexagon/kernel/stacktrace.c
+++ b/arch/hexagon/kernel/stacktrace.c
@@ -1,7 +1,7 @@
 /*
  * Stacktrace support for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/syscall.c b/arch/hexagon/kernel/syscall.c
index 620dd18..2fd0764 100644
--- a/arch/hexagon/kernel/syscall.c
+++ b/arch/hexagon/kernel/syscall.c
@@ -1,7 +1,7 @@
 /*
  * Hexagon system calls
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/syscalltab.c b/arch/hexagon/kernel/syscalltab.c
index c550f41..7024b1d 100644
--- a/arch/hexagon/kernel/syscalltab.c
+++ b/arch/hexagon/kernel/syscalltab.c
@@ -1,7 +1,7 @@
 /*
  * System call table for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/time.c b/arch/hexagon/kernel/time.c
index 5d9b33b..6f80a4f 100644
--- a/arch/hexagon/kernel/time.c
+++ b/arch/hexagon/kernel/time.c
@@ -1,7 +1,7 @@
 /*
  * Time related functions for Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/topology.c b/arch/hexagon/kernel/topology.c
index ba44751..352f27e 100644
--- a/arch/hexagon/kernel/topology.c
+++ b/arch/hexagon/kernel/topology.c
@@ -1,7 +1,7 @@
 /*
  * CPU topology for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/trampoline.S b/arch/hexagon/kernel/trampoline.S
index 06c36c0..18110a9 100644
--- a/arch/hexagon/kernel/trampoline.S
+++ b/arch/hexagon/kernel/trampoline.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/traps.c b/arch/hexagon/kernel/traps.c
index f08857d..a41eeb8 100644
--- a/arch/hexagon/kernel/traps.c
+++ b/arch/hexagon/kernel/traps.c
@@ -1,7 +1,7 @@
 /*
  * Kernel traps/events for Hexagon processor
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/vdso.c b/arch/hexagon/kernel/vdso.c
index 5d39f42..0bf5a87 100644
--- a/arch/hexagon/kernel/vdso.c
+++ b/arch/hexagon/kernel/vdso.c
@@ -1,7 +1,7 @@
 /*
  * vDSO implementation for Hexagon
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/vm_entry.S b/arch/hexagon/kernel/vm_entry.S
index 5b99066..cd71673 100644
--- a/arch/hexagon/kernel/vm_entry.S
+++ b/arch/hexagon/kernel/vm_entry.S
@@ -1,7 +1,7 @@
 /*
  * Event entry/exit for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/vm_events.c b/arch/hexagon/kernel/vm_events.c
index 591fc1b..9b5a4a2 100644
--- a/arch/hexagon/kernel/vm_events.c
+++ b/arch/hexagon/kernel/vm_events.c
@@ -1,7 +1,7 @@
 /*
  * Mostly IRQ support for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/vm_init_segtable.S b/arch/hexagon/kernel/vm_init_segtable.S
index aebb35b..80967f2 100644
--- a/arch/hexagon/kernel/vm_init_segtable.S
+++ b/arch/hexagon/kernel/vm_init_segtable.S
@@ -1,7 +1,7 @@
 /*
  * Initial page table for Linux kernel under Hexagon VM,
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/vm_ops.S b/arch/hexagon/kernel/vm_ops.S
index 24d7fca..9fb77b3 100644
--- a/arch/hexagon/kernel/vm_ops.S
+++ b/arch/hexagon/kernel/vm_ops.S
@@ -1,7 +1,7 @@
 /*
  * Hexagon VM instruction support
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/vm_switch.S b/arch/hexagon/kernel/vm_switch.S
index 0decf2f..62c6df9 100644
--- a/arch/hexagon/kernel/vm_switch.S
+++ b/arch/hexagon/kernel/vm_switch.S
@@ -1,7 +1,7 @@
 /*
  * Context switch support for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/vm_vectors.S b/arch/hexagon/kernel/vm_vectors.S
index 97a4b50..620f42c 100644
--- a/arch/hexagon/kernel/vm_vectors.S
+++ b/arch/hexagon/kernel/vm_vectors.S
@@ -1,7 +1,7 @@
 /*
  * Event jump tables
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/kernel/vmlinux.lds.S b/arch/hexagon/kernel/vmlinux.lds.S
index 071d3c3..14e793f 100644
--- a/arch/hexagon/kernel/vmlinux.lds.S
+++ b/arch/hexagon/kernel/vmlinux.lds.S
@@ -1,7 +1,7 @@
 /*
  * Linker script for Hexagon kernel
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/lib/checksum.c b/arch/hexagon/lib/checksum.c
index 9300552..8169f78 100644
--- a/arch/hexagon/lib/checksum.c
+++ b/arch/hexagon/lib/checksum.c
@@ -1,7 +1,7 @@
 /*
  * Checksum functions for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/lib/io.c b/arch/hexagon/lib/io.c
index 8ae47ba..885c962 100644
--- a/arch/hexagon/lib/io.c
+++ b/arch/hexagon/lib/io.c
@@ -1,7 +1,7 @@
 /*
  * I/O access functions for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/lib/memcpy.S b/arch/hexagon/lib/memcpy.S
index 2101c33..81c561c 100644
--- a/arch/hexagon/lib/memcpy.S
+++ b/arch/hexagon/lib/memcpy.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
  *
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/arch/hexagon/lib/memset.S b/arch/hexagon/lib/memset.S
index 26d9614..1da2712 100644
--- a/arch/hexagon/lib/memset.S
+++ b/arch/hexagon/lib/memset.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011 Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/mm/cache.c b/arch/hexagon/mm/cache.c
index c5cf6ee..fe14ccf 100644
--- a/arch/hexagon/mm/cache.c
+++ b/arch/hexagon/mm/cache.c
@@ -1,7 +1,7 @@
 /*
  * Cache management functions for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/mm/copy_from_user.S b/arch/hexagon/mm/copy_from_user.S
index 8eb1d4d..7fc94f3 100644
--- a/arch/hexagon/mm/copy_from_user.S
+++ b/arch/hexagon/mm/copy_from_user.S
@@ -1,7 +1,7 @@
 /*
  * User memory copy functions for kernel
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/mm/copy_to_user.S b/arch/hexagon/mm/copy_to_user.S
index cb9740e..0cfbcc0 100644
--- a/arch/hexagon/mm/copy_to_user.S
+++ b/arch/hexagon/mm/copy_to_user.S
@@ -1,7 +1,7 @@
 /*
  * User memory copying routines for the Hexagon Kernel
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/mm/copy_user_template.S b/arch/hexagon/mm/copy_user_template.S
index 08d7d7b..254d8cc 100644
--- a/arch/hexagon/mm/copy_user_template.S
+++ b/arch/hexagon/mm/copy_user_template.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/mm/init.c b/arch/hexagon/mm/init.c
index b57d741..69ffcfd 100644
--- a/arch/hexagon/mm/init.c
+++ b/arch/hexagon/mm/init.c
@@ -1,7 +1,7 @@
 /*
  * Memory subsystem initialization for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/mm/ioremap.c b/arch/hexagon/mm/ioremap.c
index 3a37bc3..5905fd5 100644
--- a/arch/hexagon/mm/ioremap.c
+++ b/arch/hexagon/mm/ioremap.c
@@ -1,7 +1,7 @@
 /*
  * I/O remap functions for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/mm/pgalloc.c b/arch/hexagon/mm/pgalloc.c
index b175e2d..19760a4 100644
--- a/arch/hexagon/mm/pgalloc.c
+++ b/arch/hexagon/mm/pgalloc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/mm/strnlen_user.S b/arch/hexagon/mm/strnlen_user.S
index 5c6a16c..0eecb7a 100644
--- a/arch/hexagon/mm/strnlen_user.S
+++ b/arch/hexagon/mm/strnlen_user.S
@@ -1,7 +1,7 @@
 /*
  * User string length functions for kernel
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/mm/uaccess.c b/arch/hexagon/mm/uaccess.c
index e748108..3412726 100644
--- a/arch/hexagon/mm/uaccess.c
+++ b/arch/hexagon/mm/uaccess.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/mm/vm_fault.c b/arch/hexagon/mm/vm_fault.c
index c10b76f..ed8bf67 100644
--- a/arch/hexagon/mm/vm_fault.c
+++ b/arch/hexagon/mm/vm_fault.c
@@ -1,7 +1,7 @@
 /*
  * Memory fault handling for Hexagon
  *
- * Copyright (c) 2010-2011 Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/arch/hexagon/mm/vm_tlb.c b/arch/hexagon/mm/vm_tlb.c
index c6ff415..9647d00 100644
--- a/arch/hexagon/mm/vm_tlb.c
+++ b/arch/hexagon/mm/vm_tlb.c
@@ -1,7 +1,7 @@
 /*
  * Hexagon Virtual Machine TLB functions
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/block/Kconfig.iosched b/block/Kconfig.iosched
index 5751d28..5fd98ea 100644
--- a/block/Kconfig.iosched
+++ b/block/Kconfig.iosched
@@ -15,7 +15,7 @@
 config IOSCHED_TEST
 	tristate "Test I/O scheduler"
 	depends on DEBUG_FS
-	default y
+	default m
 	---help---
 	  The test I/O scheduler is a duplicate of the noop scheduler with
 	  addition of test utlity.
diff --git a/block/blk-merge.c b/block/blk-merge.c
index 4fced1b..5d74cc3 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -42,6 +42,9 @@
 					goto new_segment;
 				if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bv))
 					goto new_segment;
+				if ((bvprv->bv_page != bv->bv_page) &&
+				    (bvprv->bv_page + 1) != bv->bv_page)
+					goto new_segment;
 
 				seg_size += bv->bv_len;
 				bvprv = bv;
@@ -141,6 +144,9 @@
 				goto new_segment;
 			if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bvec))
 				goto new_segment;
+			if ((bvprv->bv_page != bvec->bv_page) &&
+			    ((bvprv->bv_page + 1) != bvec->bv_page))
+				goto new_segment;
 
 			sg->length += nbytes;
 		} else {
diff --git a/block/row-iosched.c b/block/row-iosched.c
index 483d97f..bdb6abd 100644
--- a/block/row-iosched.c
+++ b/block/row-iosched.c
@@ -1,7 +1,7 @@
 /*
  * ROW (Read Over Write) I/O scheduler.
  *
- * 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
@@ -25,21 +25,22 @@
 #include <linux/init.h>
 #include <linux/compiler.h>
 #include <linux/blktrace_api.h>
-#include <linux/jiffies.h>
+#include <linux/hrtimer.h>
 
 /*
  * enum row_queue_prio - Priorities of the ROW queues
  *
  * This enum defines the priorities (and the number of queues)
- * the requests will be disptributed to. The higher priority -
- * the bigger is the dispatch quantum given to that queue.
+ * the requests will be distributed to. The higher priority -
+ * the bigger is the "bus time" (or the dispatch quantum) given
+ * to that queue.
  * ROWQ_PRIO_HIGH_READ - is the higher priority queue.
  *
  */
 enum row_queue_prio {
 	ROWQ_PRIO_HIGH_READ = 0,
-	ROWQ_PRIO_REG_READ,
 	ROWQ_PRIO_HIGH_SWRITE,
+	ROWQ_PRIO_REG_READ,
 	ROWQ_PRIO_REG_SWRITE,
 	ROWQ_PRIO_REG_WRITE,
 	ROWQ_PRIO_LOW_READ,
@@ -47,26 +48,51 @@
 	ROWQ_MAX_PRIO,
 };
 
-/* Flags indicating whether idling is enabled on the queue */
-static const bool queue_idling_enabled[] = {
-	true,	/* ROWQ_PRIO_HIGH_READ */
-	true,	/* ROWQ_PRIO_REG_READ */
-	false,	/* ROWQ_PRIO_HIGH_SWRITE */
-	false,	/* ROWQ_PRIO_REG_SWRITE */
-	false,	/* ROWQ_PRIO_REG_WRITE */
-	false,	/* ROWQ_PRIO_LOW_READ */
-	false,	/* ROWQ_PRIO_LOW_SWRITE */
+/*
+ * The following indexes define the distribution of ROW queues according to
+ * priorities. Each index defines the first queue in that priority group.
+ */
+#define ROWQ_HIGH_PRIO_IDX	ROWQ_PRIO_HIGH_READ
+#define ROWQ_REG_PRIO_IDX	ROWQ_PRIO_REG_READ
+#define ROWQ_LOW_PRIO_IDX	ROWQ_PRIO_LOW_READ
+
+/**
+ * struct row_queue_params - ROW queue parameters
+ * @idling_enabled: Flag indicating whether idling is enable on
+ *			the queue
+ * @quantum: Number of requests to be dispatched from this queue
+ *			in a dispatch cycle
+ * @is_urgent: Flags indicating whether the queue can notify on
+ *			urgent requests
+ *
+ */
+struct row_queue_params {
+	bool idling_enabled;
+	int quantum;
+	bool is_urgent;
 };
 
-/* Default values for row queues quantums in each dispatch cycle */
-static const int queue_quantum[] = {
-	100,	/* ROWQ_PRIO_HIGH_READ */
-	100,	/* ROWQ_PRIO_REG_READ */
-	2,	/* ROWQ_PRIO_HIGH_SWRITE */
-	1,	/* ROWQ_PRIO_REG_SWRITE */
-	1,	/* ROWQ_PRIO_REG_WRITE */
-	1,	/* ROWQ_PRIO_LOW_READ */
-	1	/* ROWQ_PRIO_LOW_SWRITE */
+/*
+ * This array holds the default values of the different configurables
+ * for each ROW queue. Each row of the array holds the following values:
+ * {idling_enabled, quantum, is_urgent}
+ * Each row corresponds to a queue with the same index (according to
+ * enum row_queue_prio)
+ * Note: The quantums are valid inside their priority type. For example:
+ *       For every 10 high priority read requests, 1 high priority sync
+ *       write will be dispatched.
+ *       For every 100 regular read requests 1 regular write request will
+ *       be dispatched.
+ */
+static const struct row_queue_params row_queues_def[] = {
+/* idling_enabled, quantum, is_urgent */
+	{true, 10, true},	/* ROWQ_PRIO_HIGH_READ */
+	{false, 1, true},	/* ROWQ_PRIO_HIGH_SWRITE */
+	{true, 100, true},	/* ROWQ_PRIO_REG_READ */
+	{false, 1, false},	/* ROWQ_PRIO_REG_SWRITE */
+	{false, 1, false},	/* ROWQ_PRIO_REG_WRITE */
+	{false, 1, false},	/* ROWQ_PRIO_LOW_READ */
+	{false, 1, false}	/* ROWQ_PRIO_LOW_SWRITE */
 };
 
 /* Default values for idling on read queues (in msec) */
@@ -92,7 +118,9 @@
  * @prio:		queue priority (enum row_queue_prio)
  * @nr_dispatched:	number of requests already dispatched in
  *			the current dispatch cycle
- * @slice:		number of requests to dispatch in a cycle
+ * @nr_req:		number of requests in queue
+ * @dispatch quantum:	number of requests this queue may
+ *			dispatch in a dispatch cycle
  * @idle_data:		data for idling on queues
  *
  */
@@ -102,7 +130,9 @@
 	enum row_queue_prio	prio;
 
 	unsigned int		nr_dispatched;
-	unsigned int		slice;
+
+	unsigned int		nr_req;
+	int			disp_quantum;
 
 	/* used only for READ queues */
 	struct rowq_idling_data	idle_data;
@@ -110,46 +140,44 @@
 
 /**
  * struct idling_data - data for idling on empty rqueue
- * @idle_time:		idling duration (jiffies)
- * @freq:		min time between two requests that
+ * @idle_time_ms:		idling duration (msec)
+ * @freq_ms:		min time between two requests that
  *			triger idling (msec)
- * @idle_work:		pointer to struct delayed_work
+ * @hr_timer:	idling timer
+ * @idle_work:	the work to be scheduled when idling timer expires
+ * @idling_queue_idx:	index of the queues we're idling on
  *
  */
 struct idling_data {
-	unsigned long			idle_time;
-	u32				freq;
+	s64				idle_time_ms;
+	s64				freq_ms;
 
-	struct workqueue_struct	*idle_workqueue;
-	struct delayed_work		idle_work;
+	struct hrtimer			hr_timer;
+	struct work_struct		idle_work;
+	enum row_queue_prio		idling_queue_idx;
 };
 
 /**
  * struct row_queue - Per block device rqueue structure
  * @dispatch_queue:	dispatch rqueue
- * @row_queues:		array of priority request queues with
- *			dispatch quantum per rqueue
- * @curr_queue:		index in the row_queues array of the
- *			currently serviced rqueue
- * @read_idle:		data for idling after READ request
+ * @row_queues:		array of priority request queues
+ * @rd_idle_data:		data for idling after READ request
  * @nr_reqs: nr_reqs[0] holds the number of all READ requests in
  *			scheduler, nr_reqs[1] holds the number of all WRITE
  *			requests in scheduler
+ * @nr_urgent_in_flight: number of uncompleted urgent requests
+ *			(both reads and writes)
  * @cycle_flags:	used for marking unserved queueus
  *
  */
 struct row_data {
 	struct request_queue		*dispatch_queue;
 
-	struct {
-		struct row_queue	rqueue;
-		int			disp_quantum;
-	} row_queues[ROWQ_MAX_PRIO];
+	struct row_queue row_queues[ROWQ_MAX_PRIO];
 
-	enum row_queue_prio		curr_queue;
-
-	struct idling_data		read_idle;
+	struct idling_data		rd_idle_data;
 	unsigned int			nr_reqs[2];
+	unsigned int			nr_urgent_in_flight;
 
 	unsigned int			cycle_flags;
 };
@@ -180,61 +208,50 @@
 	return rd->cycle_flags & (1 << qnum);
 }
 
-/******************** Static helper functions ***********************/
-/*
- * kick_queue() - Wake up device driver queue thread
- * @work:	pointer to struct work_struct
- *
- * This is a idling delayed work function. It's purpose is to wake up the
- * device driver in order for it to start fetching requests.
- *
- */
-static void kick_queue(struct work_struct *work)
-{
-	struct delayed_work *idle_work = to_delayed_work(work);
-	struct idling_data *read_data =
-		container_of(idle_work, struct idling_data, idle_work);
-	struct row_data *rd =
-		container_of(read_data, struct row_data, read_idle);
-
-	row_log_rowq(rd, rd->curr_queue, "Performing delayed work");
-	/* Mark idling process as done */
-	rd->row_queues[rd->curr_queue].rqueue.idle_data.begin_idling = false;
-
-	if (!(rd->nr_reqs[0] + rd->nr_reqs[1]))
-		row_log(rd->dispatch_queue, "No requests in scheduler");
-	else {
-		spin_lock_irq(rd->dispatch_queue->queue_lock);
-		__blk_run_queue(rd->dispatch_queue);
-		spin_unlock_irq(rd->dispatch_queue->queue_lock);
-	}
-}
-
-/*
- * row_restart_disp_cycle() - Restart the dispatch cycle
- * @rd:	pointer to struct row_data
- *
- * This function restarts the dispatch cycle by:
- * - Setting current queue to ROWQ_PRIO_HIGH_READ
- * - For each queue: reset the number of requests dispatched in
- *   the cycle
- */
-static inline void row_restart_disp_cycle(struct row_data *rd)
+static inline void __maybe_unused row_dump_queues_stat(struct row_data *rd)
 {
 	int i;
 
+	row_log(rd->dispatch_queue, " Queues status:");
 	for (i = 0; i < ROWQ_MAX_PRIO; i++)
-		rd->row_queues[i].rqueue.nr_dispatched = 0;
-
-	rd->curr_queue = ROWQ_PRIO_HIGH_READ;
-	row_log(rd->dispatch_queue, "Restarting cycle");
+		row_log(rd->dispatch_queue,
+			"queue%d: dispatched= %d, nr_req=%d", i,
+			rd->row_queues[i].nr_dispatched,
+			rd->row_queues[i].nr_req);
 }
 
-static inline void row_get_next_queue(struct row_data *rd)
+/******************** Static helper functions ***********************/
+static void kick_queue(struct work_struct *work)
 {
-	rd->curr_queue++;
-	if (rd->curr_queue == ROWQ_MAX_PRIO)
-		row_restart_disp_cycle(rd);
+	struct idling_data *read_data =
+		container_of(work, struct idling_data, idle_work);
+	struct row_data *rd =
+		container_of(read_data, struct row_data, rd_idle_data);
+
+	blk_run_queue(rd->dispatch_queue);
+}
+
+
+static enum hrtimer_restart row_idle_hrtimer_fn(struct hrtimer *hr_timer)
+{
+	struct idling_data *read_data =
+		container_of(hr_timer, struct idling_data, hr_timer);
+	struct row_data *rd =
+		container_of(read_data, struct row_data, rd_idle_data);
+
+	row_log_rowq(rd, rd->rd_idle_data.idling_queue_idx,
+			 "Performing delayed work");
+	/* Mark idling process as done */
+	rd->row_queues[rd->rd_idle_data.idling_queue_idx].
+			idle_data.begin_idling = false;
+	rd->rd_idle_data.idling_queue_idx = ROWQ_MAX_PRIO;
+
+	if (!rd->nr_reqs[READ] && !rd->nr_reqs[WRITE])
+		row_log(rd->dispatch_queue, "No requests in scheduler");
+	else
+		kblockd_schedule_work(rd->dispatch_queue,
+			&read_data->idle_work);
+	return HRTIMER_NORESTART;
 }
 
 /******************* Elevator callback functions *********************/
@@ -250,31 +267,132 @@
 {
 	struct row_data *rd = (struct row_data *)q->elevator->elevator_data;
 	struct row_queue *rqueue = RQ_ROWQ(rq);
+	s64 diff_ms;
 
 	list_add_tail(&rq->queuelist, &rqueue->fifo);
 	rd->nr_reqs[rq_data_dir(rq)]++;
+	rqueue->nr_req++;
 	rq_set_fifo_time(rq, jiffies); /* for statistics*/
 
-	if (queue_idling_enabled[rqueue->prio]) {
-		if (delayed_work_pending(&rd->read_idle.idle_work))
-			(void)cancel_delayed_work(
-				&rd->read_idle.idle_work);
-		if (ktime_to_ms(ktime_sub(ktime_get(),
-				rqueue->idle_data.last_insert_time)) <
-				rd->read_idle.freq) {
+	if (row_queues_def[rqueue->prio].idling_enabled) {
+		if (rd->rd_idle_data.idling_queue_idx == rqueue->prio &&
+		    hrtimer_active(&rd->rd_idle_data.hr_timer)) {
+			(void)hrtimer_cancel(&rd->rd_idle_data.hr_timer);
+			row_log_rowq(rd, rqueue->prio,
+				"Canceled delayed work on %d",
+				rd->rd_idle_data.idling_queue_idx);
+			rd->rd_idle_data.idling_queue_idx = ROWQ_MAX_PRIO;
+		}
+		diff_ms = ktime_to_ms(ktime_sub(ktime_get(),
+				rqueue->idle_data.last_insert_time));
+		if (unlikely(diff_ms < 0)) {
+			pr_err("ROW BUG: %s diff_ms < 0", __func__);
+			rqueue->idle_data.begin_idling = false;
+			return;
+		}
+		if (diff_ms < rd->rd_idle_data.freq_ms) {
 			rqueue->idle_data.begin_idling = true;
 			row_log_rowq(rd, rqueue->prio, "Enable idling");
 		} else {
 			rqueue->idle_data.begin_idling = false;
-			row_log_rowq(rd, rqueue->prio, "Disable idling");
+			row_log_rowq(rd, rqueue->prio, "Disable idling (%ldms)",
+				(long)diff_ms);
 		}
 
 		rqueue->idle_data.last_insert_time = ktime_get();
 	}
-	row_log_rowq(rd, rqueue->prio, "added request");
+	if (row_queues_def[rqueue->prio].is_urgent &&
+	    row_rowq_unserved(rd, rqueue->prio)) {
+		row_log_rowq(rd, rqueue->prio,
+			"added urgent request (total on queue=%d)",
+			rqueue->nr_req);
+		rq->cmd_flags |= REQ_URGENT;
+	} else
+		row_log_rowq(rd, rqueue->prio,
+			"added request (total on queue=%d)", rqueue->nr_req);
 }
 
-/*
+/**
+ * row_reinsert_req() - Reinsert request back to the scheduler
+ * @q:	requests queue
+ * @rq:	request to add
+ *
+ * Reinsert the given request back to the queue it was
+ * dispatched from as if it was never dispatched.
+ *
+ * Returns 0 on success, error code otherwise
+ */
+static int row_reinsert_req(struct request_queue *q,
+			    struct request *rq)
+{
+	struct row_data    *rd = q->elevator->elevator_data;
+	struct row_queue   *rqueue = RQ_ROWQ(rq);
+
+	if (rqueue->prio >= ROWQ_MAX_PRIO) {
+		pr_err("\n\n%s:ROW BUG: row_reinsert_req() rqueue->prio = %d\n",
+			   rq->rq_disk->disk_name, rqueue->prio);
+		blk_dump_rq_flags(rq, "");
+		return -EIO;
+	}
+
+	list_add(&rq->queuelist, &rqueue->fifo);
+	rd->nr_reqs[rq_data_dir(rq)]++;
+	rqueue->nr_req++;
+
+	row_log_rowq(rd, rqueue->prio,
+		"request reinserted (total on queue=%d)", rqueue->nr_req);
+
+	return 0;
+}
+
+static void row_completed_req(struct request_queue *q, struct request *rq)
+{
+	struct row_data *rd = q->elevator->elevator_data;
+
+	 if (rq->cmd_flags & REQ_URGENT) {
+		if (!rd->nr_urgent_in_flight) {
+			pr_err("ROW BUG: %s() nr_urgent_in_flight = 0",
+				__func__);
+			return;
+		}
+		rd->nr_urgent_in_flight--;
+	}
+}
+
+/**
+ * row_urgent_pending() - Return TRUE if there is an urgent
+ *			  request on scheduler
+ * @q:	requests queue
+ */
+static bool row_urgent_pending(struct request_queue *q)
+{
+	struct row_data *rd = q->elevator->elevator_data;
+	int i;
+
+	if (rd->nr_urgent_in_flight) {
+		row_log(rd->dispatch_queue, "%d urgent requests in flight",
+			rd->nr_urgent_in_flight);
+		return false;
+	}
+
+	for (i = ROWQ_HIGH_PRIO_IDX; i < ROWQ_REG_PRIO_IDX; i++)
+		if (!list_empty(&rd->row_queues[i].fifo)) {
+			row_log_rowq(rd, i,
+				"Urgent (high prio) request pending");
+			return true;
+		}
+
+	for (i = ROWQ_REG_PRIO_IDX; i < ROWQ_MAX_PRIO; i++)
+		if (row_queues_def[i].is_urgent && row_rowq_unserved(rd, i) &&
+		    !list_empty(&rd->row_queues[i].fifo)) {
+			row_log_rowq(rd, i, "Urgent request pending");
+			return true;
+		}
+
+	return false;
+}
+
+/**
  * row_remove_request() -  Remove given request from scheduler
  * @q:	requests queue
  * @rq:	request to remove
@@ -284,69 +402,181 @@
 			       struct request *rq)
 {
 	struct row_data *rd = (struct row_data *)q->elevator->elevator_data;
+	struct row_queue *rqueue = RQ_ROWQ(rq);
 
 	rq_fifo_clear(rq);
+	rqueue->nr_req--;
 	rd->nr_reqs[rq_data_dir(rq)]--;
 }
 
 /*
  * row_dispatch_insert() - move request to dispatch queue
- * @rd:	pointer to struct row_data
+ * @rd:		pointer to struct row_data
+ * @queue_idx:	index of the row_queue to dispatch from
  *
  * This function moves the next request to dispatch from
- * rd->curr_queue to the dispatch queue
+ * the given queue (row_queues[queue_idx]) to the dispatch queue
  *
  */
-static void row_dispatch_insert(struct row_data *rd)
+static void row_dispatch_insert(struct row_data *rd, int queue_idx)
 {
 	struct request *rq;
 
-	rq = rq_entry_fifo(rd->row_queues[rd->curr_queue].rqueue.fifo.next);
+	rq = rq_entry_fifo(rd->row_queues[queue_idx].fifo.next);
 	row_remove_request(rd->dispatch_queue, rq);
 	elv_dispatch_add_tail(rd->dispatch_queue, rq);
-	rd->row_queues[rd->curr_queue].rqueue.nr_dispatched++;
-	row_clear_rowq_unserved(rd, rd->curr_queue);
-	row_log_rowq(rd, rd->curr_queue, " Dispatched request nr_disp = %d",
-		     rd->row_queues[rd->curr_queue].rqueue.nr_dispatched);
+	rd->row_queues[queue_idx].nr_dispatched++;
+	row_clear_rowq_unserved(rd, queue_idx);
+	row_log_rowq(rd, queue_idx, " Dispatched request nr_disp = %d",
+		     rd->row_queues[queue_idx].nr_dispatched);
+	if (rq->cmd_flags & REQ_URGENT)
+		rd->nr_urgent_in_flight++;
 }
 
 /*
- * row_choose_queue() -  choose the next queue to dispatch from
+ * row_get_ioprio_class_to_serve() - Return the next I/O priority
+ *				      class to dispatch requests from
  * @rd:	pointer to struct row_data
+ * @force:	flag indicating if forced dispatch
  *
- * Updates rd->curr_queue. Returns 1 if there are requests to
- * dispatch, 0 if there are no requests in scheduler
+ * This function returns the next I/O priority class to serve
+ * {IOPRIO_CLASS_NONE, IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE}.
+ * If there are no more requests in scheduler or if we're idling on some queue
+ * IOPRIO_CLASS_NONE will be returned.
+ * If idling is scheduled on a lower priority queue than the one that needs
+ * to be served, it will be canceled.
  *
  */
-static int row_choose_queue(struct row_data *rd)
+static int row_get_ioprio_class_to_serve(struct row_data *rd, int force)
 {
-	int prev_curr_queue = rd->curr_queue;
+	int i;
+	int ret = IOPRIO_CLASS_NONE;
 
-	if (!(rd->nr_reqs[0] + rd->nr_reqs[1])) {
+	if (!rd->nr_reqs[READ] && !rd->nr_reqs[WRITE]) {
 		row_log(rd->dispatch_queue, "No more requests in scheduler");
-		return 0;
+		goto check_idling;
 	}
 
-	row_get_next_queue(rd);
+	/* First, go over the high priority queues */
+	for (i = 0; i < ROWQ_REG_PRIO_IDX; i++) {
+		if (!list_empty(&rd->row_queues[i].fifo)) {
+			if (hrtimer_active(&rd->rd_idle_data.hr_timer)) {
+				(void)hrtimer_cancel(
+					&rd->rd_idle_data.hr_timer);
+				row_log_rowq(rd,
+					rd->rd_idle_data.idling_queue_idx,
+					"Canceling delayed work on %d. RT pending",
+					rd->rd_idle_data.idling_queue_idx);
+				rd->rd_idle_data.idling_queue_idx =
+					ROWQ_MAX_PRIO;
+			}
+			ret = IOPRIO_CLASS_RT;
+			goto done;
+		}
+	}
 
 	/*
-	 * Loop over all queues to find the next queue that is not empty.
-	 * Stop when you get back to curr_queue
+	 * At the moment idling is implemented only for READ queues.
+	 * If enabled on WRITE, this needs updating
 	 */
-	while (list_empty(&rd->row_queues[rd->curr_queue].rqueue.fifo)
-	       && rd->curr_queue != prev_curr_queue) {
-		/* Mark rqueue as unserved */
-		row_mark_rowq_unserved(rd, rd->curr_queue);
-		row_get_next_queue(rd);
+	if (hrtimer_active(&rd->rd_idle_data.hr_timer)) {
+		row_log(rd->dispatch_queue, "Delayed work pending. Exiting");
+		goto done;
+	}
+check_idling:
+	/* Check for (high priority) idling and enable if needed */
+	for (i = 0; i < ROWQ_REG_PRIO_IDX && !force; i++) {
+		if (rd->row_queues[i].idle_data.begin_idling &&
+		    row_queues_def[i].idling_enabled)
+			goto initiate_idling;
 	}
 
-	return 1;
+	/* Regular priority queues */
+	for (i = ROWQ_REG_PRIO_IDX; i < ROWQ_LOW_PRIO_IDX; i++) {
+		if (list_empty(&rd->row_queues[i].fifo)) {
+			/* We can idle only if this is not a forced dispatch */
+			if (rd->row_queues[i].idle_data.begin_idling &&
+			    !force && row_queues_def[i].idling_enabled)
+				goto initiate_idling;
+		} else {
+			ret = IOPRIO_CLASS_BE;
+			goto done;
+		}
+	}
+
+	if (rd->nr_reqs[READ] || rd->nr_reqs[WRITE])
+		ret = IOPRIO_CLASS_IDLE;
+	goto done;
+
+initiate_idling:
+	hrtimer_start(&rd->rd_idle_data.hr_timer,
+		ktime_set(0, rd->rd_idle_data.idle_time_ms * NSEC_PER_MSEC),
+		HRTIMER_MODE_REL);
+
+	rd->rd_idle_data.idling_queue_idx = i;
+	row_log_rowq(rd, i, "Scheduled delayed work on %d. exiting", i);
+
+done:
+	return ret;
+}
+
+static void row_restart_cycle(struct row_data *rd,
+				int start_idx, int end_idx)
+{
+	int i;
+
+	row_dump_queues_stat(rd);
+	for (i = start_idx; i < end_idx; i++) {
+		if (rd->row_queues[i].nr_dispatched <
+		    rd->row_queues[i].disp_quantum)
+			row_mark_rowq_unserved(rd, i);
+		rd->row_queues[i].nr_dispatched = 0;
+	}
+	row_log(rd->dispatch_queue, "Restarting cycle for class @ %d-%d",
+		start_idx, end_idx);
+}
+
+/*
+ * row_get_next_queue() - selects the next queue to dispatch from
+ * @q:		requests queue
+ * @rd:		pointer to struct row_data
+ * @start_idx/end_idx: indexes in the row_queues array to select a queue
+ *                 from.
+ *
+ * Return index of the queues to dispatch from. Error code if fails.
+ *
+ */
+static int row_get_next_queue(struct request_queue *q, struct row_data *rd,
+				int start_idx, int end_idx)
+{
+	int i = start_idx;
+	bool restart = true;
+	int ret = -EIO;
+
+	do {
+		if (list_empty(&rd->row_queues[i].fifo) ||
+		    rd->row_queues[i].nr_dispatched >=
+		    rd->row_queues[i].disp_quantum) {
+			i++;
+			if (i == end_idx && restart) {
+				/* Restart cycle for this priority class */
+				row_restart_cycle(rd, start_idx, end_idx);
+				i = start_idx;
+				restart = false;
+			}
+		} else {
+			ret = i;
+			break;
+		}
+	} while (i < end_idx);
+
+	return ret;
 }
 
 /*
  * row_dispatch_requests() - selects the next request to dispatch
  * @q:		requests queue
- * @force:	ignored
+ * @force:		flag indicating if forced dispatch
  *
  * Return 0 if no requests were moved to the dispatch queue.
  *	  1 otherwise
@@ -355,76 +585,47 @@
 static int row_dispatch_requests(struct request_queue *q, int force)
 {
 	struct row_data *rd = (struct row_data *)q->elevator->elevator_data;
-	int ret = 0, currq, i;
+	int ret = 0, currq, ioprio_class_to_serve, start_idx, end_idx;
 
-	currq = rd->curr_queue;
-
-	/*
-	 * Find the first unserved queue (with higher priority then currq)
-	 * that is not empty
-	 */
-	for (i = 0; i < currq; i++) {
-		if (row_rowq_unserved(rd, i) &&
-		    !list_empty(&rd->row_queues[i].rqueue.fifo)) {
-			row_log_rowq(rd, currq,
-				" Preemting for unserved rowq%d", i);
-			rd->curr_queue = i;
-			row_dispatch_insert(rd);
-			ret = 1;
-			goto done;
-		}
+	if (force && hrtimer_active(&rd->rd_idle_data.hr_timer)) {
+		(void)hrtimer_cancel(&rd->rd_idle_data.hr_timer);
+		row_log_rowq(rd, rd->rd_idle_data.idling_queue_idx,
+			"Canceled delayed work on %d - forced dispatch",
+			rd->rd_idle_data.idling_queue_idx);
+		rd->rd_idle_data.idling_queue_idx = ROWQ_MAX_PRIO;
 	}
 
-	if (rd->row_queues[currq].rqueue.nr_dispatched >=
-	    rd->row_queues[currq].disp_quantum) {
-		rd->row_queues[currq].rqueue.nr_dispatched = 0;
-		row_log_rowq(rd, currq, "Expiring rqueue");
-		ret = row_choose_queue(rd);
-		if (ret)
-			row_dispatch_insert(rd);
+	ioprio_class_to_serve = row_get_ioprio_class_to_serve(rd, force);
+	row_log(rd->dispatch_queue, "Dispatching from %d priority class",
+		ioprio_class_to_serve);
+
+	switch (ioprio_class_to_serve) {
+	case IOPRIO_CLASS_NONE:
+		goto done;
+	case IOPRIO_CLASS_RT:
+		start_idx = ROWQ_HIGH_PRIO_IDX;
+		end_idx = ROWQ_REG_PRIO_IDX;
+		break;
+	case IOPRIO_CLASS_BE:
+		start_idx = ROWQ_REG_PRIO_IDX;
+		end_idx = ROWQ_LOW_PRIO_IDX;
+		break;
+	case IOPRIO_CLASS_IDLE:
+		start_idx = ROWQ_LOW_PRIO_IDX;
+		end_idx = ROWQ_MAX_PRIO;
+		break;
+	default:
+		pr_err("%s(): Invalid I/O priority class", __func__);
 		goto done;
 	}
 
-	/* Dispatch from curr_queue */
-	if (list_empty(&rd->row_queues[currq].rqueue.fifo)) {
-		/* check idling */
-		if (delayed_work_pending(&rd->read_idle.idle_work)) {
-			if (force) {
-				(void)cancel_delayed_work(
-				&rd->read_idle.idle_work);
-				row_log_rowq(rd, currq,
-					"Canceled delayed work - forced dispatch");
-			} else {
-				row_log_rowq(rd, currq,
-						 "Delayed work pending. Exiting");
-				goto done;
-			}
-		}
+	currq = row_get_next_queue(q, rd, start_idx, end_idx);
 
-		if (!force && queue_idling_enabled[currq] &&
-		    rd->row_queues[currq].rqueue.idle_data.begin_idling) {
-			if (!queue_delayed_work(rd->read_idle.idle_workqueue,
-						&rd->read_idle.idle_work,
-						rd->read_idle.idle_time)) {
-				row_log_rowq(rd, currq,
-					     "Work already on queue!");
-				pr_err("ROW_BUG: Work already on queue!");
-			} else
-				row_log_rowq(rd, currq,
-				     "Scheduled delayed work. exiting");
-			goto done;
-		} else {
-			row_log_rowq(rd, currq,
-				     "Currq empty. Choose next queue");
-			ret = row_choose_queue(rd);
-			if (!ret)
-				goto done;
-		}
+	/* Dispatch */
+	if (currq >= 0) {
+		row_dispatch_insert(rd, currq);
+		ret = 1;
 	}
-
-	ret = 1;
-	row_dispatch_insert(rd);
-
 done:
 	return ret;
 }
@@ -448,13 +649,14 @@
 	if (!rdata)
 		return NULL;
 
+	memset(rdata, 0, sizeof(*rdata));
 	for (i = 0; i < ROWQ_MAX_PRIO; i++) {
-		INIT_LIST_HEAD(&rdata->row_queues[i].rqueue.fifo);
-		rdata->row_queues[i].disp_quantum = queue_quantum[i];
-		rdata->row_queues[i].rqueue.rdata = rdata;
-		rdata->row_queues[i].rqueue.prio = i;
-		rdata->row_queues[i].rqueue.idle_data.begin_idling = false;
-		rdata->row_queues[i].rqueue.idle_data.last_insert_time =
+		INIT_LIST_HEAD(&rdata->row_queues[i].fifo);
+		rdata->row_queues[i].disp_quantum = row_queues_def[i].quantum;
+		rdata->row_queues[i].rdata = rdata;
+		rdata->row_queues[i].prio = i;
+		rdata->row_queues[i].idle_data.begin_idling = false;
+		rdata->row_queues[i].idle_data.last_insert_time =
 			ktime_set(0, 0);
 	}
 
@@ -463,22 +665,17 @@
 	 * enable it for write queues also, note that idling frequency will
 	 * be the same in both cases
 	 */
-	rdata->read_idle.idle_time = msecs_to_jiffies(ROW_IDLE_TIME_MSEC);
-	/* Maybe 0 on some platforms */
-	if (!rdata->read_idle.idle_time)
-		rdata->read_idle.idle_time = 1;
-	rdata->read_idle.freq = ROW_READ_FREQ_MSEC;
-	rdata->read_idle.idle_workqueue = alloc_workqueue("row_idle_work",
-					    WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
-	if (!rdata->read_idle.idle_workqueue)
-		panic("Failed to create idle workqueue\n");
-	INIT_DELAYED_WORK(&rdata->read_idle.idle_work, kick_queue);
+	rdata->rd_idle_data.idle_time_ms = ROW_IDLE_TIME_MSEC;
+	rdata->rd_idle_data.freq_ms = ROW_READ_FREQ_MSEC;
+	hrtimer_init(&rdata->rd_idle_data.hr_timer,
+		CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+	rdata->rd_idle_data.hr_timer.function = &row_idle_hrtimer_fn;
 
-	rdata->curr_queue = ROWQ_PRIO_HIGH_READ;
+	INIT_WORK(&rdata->rd_idle_data.idle_work, kick_queue);
+
+	rdata->rd_idle_data.idling_queue_idx = ROWQ_MAX_PRIO;
 	rdata->dispatch_queue = q;
 
-	rdata->nr_reqs[READ] = rdata->nr_reqs[WRITE] = 0;
-
 	return rdata;
 }
 
@@ -493,10 +690,10 @@
 	int i;
 
 	for (i = 0; i < ROWQ_MAX_PRIO; i++)
-		BUG_ON(!list_empty(&rd->row_queues[i].rqueue.fifo));
-	(void)cancel_delayed_work_sync(&rd->read_idle.idle_work);
-	BUG_ON(delayed_work_pending(&rd->read_idle.idle_work));
-	destroy_workqueue(rd->read_idle.idle_workqueue);
+		BUG_ON(!list_empty(&rd->row_queues[i].fifo));
+	if (hrtimer_cancel(&rd->rd_idle_data.hr_timer))
+		pr_err("ROW BUG: idle timer was active!");
+	rd->rd_idle_data.idling_queue_idx = ROWQ_MAX_PRIO;
 	kfree(rd);
 }
 
@@ -512,31 +709,63 @@
 	struct row_queue   *rqueue = RQ_ROWQ(next);
 
 	list_del_init(&next->queuelist);
+	rqueue->nr_req--;
 
 	rqueue->rdata->nr_reqs[rq_data_dir(rq)]--;
 }
 
 /*
- * get_queue_type() - Get queue type for a given request
+ * row_get_queue_prio() - Get queue priority for a given request
  *
  * This is a helping function which purpose is to determine what
  * ROW queue the given request should be added to (and
- * dispatched from leter on)
+ * dispatched from later on)
  *
- * TODO: Right now only 3 queues are used REG_READ, REG_WRITE
- * and REG_SWRITE
  */
-static enum row_queue_prio get_queue_type(struct request *rq)
+static enum row_queue_prio row_get_queue_prio(struct request *rq)
 {
 	const int data_dir = rq_data_dir(rq);
 	const bool is_sync = rq_is_sync(rq);
+	enum row_queue_prio q_type = ROWQ_MAX_PRIO;
+	int ioprio_class = IOPRIO_PRIO_CLASS(rq->elv.icq->ioc->ioprio);
 
-	if (data_dir == READ)
-		return ROWQ_PRIO_REG_READ;
-	else if (is_sync)
-		return ROWQ_PRIO_REG_SWRITE;
-	else
-		return ROWQ_PRIO_REG_WRITE;
+	switch (ioprio_class) {
+	case IOPRIO_CLASS_RT:
+		if (data_dir == READ)
+			q_type = ROWQ_PRIO_HIGH_READ;
+		else if (is_sync)
+			q_type = ROWQ_PRIO_HIGH_SWRITE;
+		else {
+			pr_err("%s:%s(): got a simple write from RT_CLASS. How???",
+				rq->rq_disk->disk_name, __func__);
+			q_type = ROWQ_PRIO_REG_WRITE;
+		}
+		rq->cmd_flags |= REQ_URGENT;
+		break;
+	case IOPRIO_CLASS_IDLE:
+		if (data_dir == READ)
+			q_type = ROWQ_PRIO_LOW_READ;
+		else if (is_sync)
+			q_type = ROWQ_PRIO_LOW_SWRITE;
+		else {
+			pr_err("%s:%s(): got a simple write from IDLE_CLASS. How???",
+				rq->rq_disk->disk_name, __func__);
+			q_type = ROWQ_PRIO_REG_WRITE;
+		}
+		break;
+	case IOPRIO_CLASS_NONE:
+	case IOPRIO_CLASS_BE:
+	default:
+		if (data_dir == READ)
+			q_type = ROWQ_PRIO_REG_READ;
+		else if (is_sync)
+			q_type = ROWQ_PRIO_REG_SWRITE;
+		else
+			q_type = ROWQ_PRIO_REG_WRITE;
+		break;
+	}
+
+	return q_type;
 }
 
 /*
@@ -554,7 +783,7 @@
 
 	spin_lock_irqsave(q->queue_lock, flags);
 	rq->elv.priv[0] =
-		(void *)(&rd->row_queues[get_queue_type(rq)]);
+		(void *)(&rd->row_queues[row_get_queue_prio(rq)]);
 	spin_unlock_irqrestore(q->queue_lock, flags);
 
 	return 0;
@@ -597,8 +826,8 @@
 	rowd->row_queues[ROWQ_PRIO_LOW_READ].disp_quantum, 0);
 SHOW_FUNCTION(row_lp_swrite_quantum_show,
 	rowd->row_queues[ROWQ_PRIO_LOW_SWRITE].disp_quantum, 0);
-SHOW_FUNCTION(row_read_idle_show, rowd->read_idle.idle_time, 1);
-SHOW_FUNCTION(row_read_idle_freq_show, rowd->read_idle.freq, 0);
+SHOW_FUNCTION(row_rd_idle_data_show, rowd->rd_idle_data.idle_time_ms, 0);
+SHOW_FUNCTION(row_rd_idle_data_freq_show, rowd->rd_idle_data.freq_ms, 0);
 #undef SHOW_FUNCTION
 
 #define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV)			\
@@ -636,9 +865,11 @@
 			1, INT_MAX, 0);
 STORE_FUNCTION(row_lp_swrite_quantum_store,
 			&rowd->row_queues[ROWQ_PRIO_LOW_SWRITE].disp_quantum,
-			1, INT_MAX, 1);
-STORE_FUNCTION(row_read_idle_store, &rowd->read_idle.idle_time, 1, INT_MAX, 1);
-STORE_FUNCTION(row_read_idle_freq_store, &rowd->read_idle.freq, 1, INT_MAX, 0);
+			1, INT_MAX, 0);
+STORE_FUNCTION(row_rd_idle_data_store, &rowd->rd_idle_data.idle_time_ms,
+			1, INT_MAX, 0);
+STORE_FUNCTION(row_rd_idle_data_freq_store, &rowd->rd_idle_data.freq_ms,
+			1, INT_MAX, 0);
 
 #undef STORE_FUNCTION
 
@@ -654,8 +885,8 @@
 	ROW_ATTR(rp_write_quantum),
 	ROW_ATTR(lp_read_quantum),
 	ROW_ATTR(lp_swrite_quantum),
-	ROW_ATTR(read_idle),
-	ROW_ATTR(read_idle_freq),
+	ROW_ATTR(rd_idle_data),
+	ROW_ATTR(rd_idle_data_freq),
 	__ATTR_NULL
 };
 
@@ -664,13 +895,17 @@
 		.elevator_merge_req_fn		= row_merged_requests,
 		.elevator_dispatch_fn		= row_dispatch_requests,
 		.elevator_add_req_fn		= row_add_request,
+		.elevator_reinsert_req_fn	= row_reinsert_req,
+		.elevator_is_urgent_fn		= row_urgent_pending,
+		.elevator_completed_req_fn	= row_completed_req,
 		.elevator_former_req_fn		= elv_rb_former_request,
 		.elevator_latter_req_fn		= elv_rb_latter_request,
 		.elevator_set_req_fn		= row_set_request,
 		.elevator_init_fn		= row_init_queue,
 		.elevator_exit_fn		= row_exit_queue,
 	},
-
+	.icq_size = sizeof(struct io_cq),
+	.icq_align = __alignof__(struct io_cq),
 	.elevator_attrs = row_attrs,
 	.elevator_name = "row",
 	.elevator_owner = THIS_MODULE,
diff --git a/block/test-iosched.c b/block/test-iosched.c
index 71e8669..c4cfb17 100644
--- a/block/test-iosched.c
+++ b/block/test-iosched.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -43,18 +43,6 @@
 static LIST_HEAD(blk_dev_test_list);
 static struct test_data *ptd;
 
-/* Get the request after `test_rq' in the test requests list */
-static struct test_request *
-latter_test_request(struct request_queue *q,
-				 struct test_request *test_rq)
-{
-	struct test_data *td = q->elevator->elevator_data;
-
-	if (test_rq->queuelist.next == &td->test_queue)
-		return NULL;
-	return list_entry(test_rq->queuelist.next, struct test_request,
-			  queuelist);
-}
 
 /**
  * test_iosched_get_req_queue() - returns the request queue
@@ -77,31 +65,56 @@
 {
 	if (!ptd)
 		return;
+	test_pr_info("%s: mark test is completed, test_count=%d,",
+			__func__, ptd->test_count);
+	test_pr_info("%s: reinsert_count=%d, dispatched_count=%d",
+		     __func__, ptd->reinsert_count, ptd->dispatched_count);
 
 	ptd->test_state = TEST_COMPLETED;
 	wake_up(&ptd->wait_q);
 }
 EXPORT_SYMBOL(test_iosched_mark_test_completion);
 
-/* Check if all the queued test requests were completed */
-static void check_test_completion(void)
+/**
+ *  check_test_completion() - Check if all the queued test
+ *  requests were completed
+ */
+void check_test_completion(void)
 {
 	struct test_request *test_rq;
-	struct request *rq;
 
-	list_for_each_entry(test_rq, &ptd->test_queue, queuelist) {
-		rq = test_rq->rq;
+	if (!ptd)
+		goto exit;
+
+	list_for_each_entry(test_rq, &ptd->dispatched_queue, queuelist)
 		if (!test_rq->req_completed)
-			return;
+			goto exit;
+
+	if (!list_empty(&ptd->test_queue)
+			|| !list_empty(&ptd->reinsert_queue)
+			|| !list_empty(&ptd->urgent_queue)) {
+		test_pr_info("%s: Test still not completed,", __func__);
+		test_pr_info("%s: test_count=%d, reinsert_count=%d",
+			     __func__, ptd->test_count, ptd->reinsert_count);
+		test_pr_info("%s: dispatched_count=%d, urgent_count=%d",
+			    __func__, ptd->dispatched_count, ptd->urgent_count);
+		goto exit;
 	}
 
 	ptd->test_info.test_duration = jiffies -
 				ptd->test_info.test_duration;
 
-	test_pr_info("%s: Test is completed", __func__);
+	test_pr_info("%s: Test is completed, test_count=%d, reinsert_count=%d,",
+			__func__, ptd->test_count, ptd->reinsert_count);
+	test_pr_info("%s: dispatched_count=%d",
+		      __func__, ptd->dispatched_count);
 
 	test_iosched_mark_test_completion();
+
+exit:
+	return;
 }
+EXPORT_SYMBOL(check_test_completion);
 
 /*
  * A callback to be called per bio completion.
@@ -111,7 +124,6 @@
 {
 	if (err)
 		clear_bit(BIO_UPTODATE, &bio->bi_flags);
-
 	bio_put(bio);
 }
 
@@ -221,7 +233,10 @@
 		"%s: added request %d to the test requests list, type = %d",
 		__func__, test_rq->req_id, req_unique);
 
+	spin_lock_irq(ptd->req_q->queue_lock);
 	list_add_tail(&test_rq->queuelist, &ptd->test_queue);
+	ptd->test_count++;
+	spin_unlock_irq(ptd->req_q->queue_lock);
 
 	return 0;
 }
@@ -253,8 +268,7 @@
 }
 
 /**
- * test_iosched_add_wr_rd_test_req() - Create and queue a
- * read/write request.
+ * test_iosched_create_test_req() - Create a read/write request.
  * @is_err_expcted:	A flag to indicate if this request
  *			should succeed or not
  * @direction:		READ/WRITE
@@ -278,34 +292,33 @@
  * request memory is freed at the end of the test and the
  * allocated BIO memory is freed by end_test_bio.
  */
-int test_iosched_add_wr_rd_test_req(int is_err_expcted,
+struct test_request *test_iosched_create_test_req(int is_err_expcted,
 		      int direction, int start_sec,
 		      int num_bios, int pattern, rq_end_io_fn *end_req_io)
 {
-	struct request *rq = NULL;
-	struct test_request *test_rq = NULL;
-	int rw_flags = 0;
-	int buf_size = 0;
-	int ret = 0, i = 0;
+	struct request *rq;
+	struct test_request *test_rq;
+	int rw_flags, buf_size;
+	int ret = 0, i;
 	unsigned int *bio_ptr = NULL;
 	struct bio *bio = NULL;
 
 	if (!ptd)
-		return -ENODEV;
+		return NULL;
 
 	rw_flags = direction;
 
 	rq = blk_get_request(ptd->req_q, rw_flags, GFP_KERNEL);
 	if (!rq) {
 		test_pr_err("%s: Failed to allocate a request", __func__);
-		return -ENODEV;
+		return NULL;
 	}
 
 	test_rq = kzalloc(sizeof(struct test_request), GFP_KERNEL);
 	if (!test_rq) {
 		test_pr_err("%s: Failed to allocate test request", __func__);
 		blk_put_request(rq);
-		return -ENODEV;
+		return NULL;
 	}
 
 	buf_size = sizeof(unsigned int) * BIO_U32_SIZE * num_bios;
@@ -341,6 +354,7 @@
 		rq->end_io = end_test_req;
 	rq->__sector = start_sec;
 	rq->cmd_type |= REQ_TYPE_FS;
+	rq->cmd_flags |= REQ_SORTED;
 
 	if (rq->bio) {
 		rq->bio->bi_sector = start_sec;
@@ -356,19 +370,66 @@
 	test_rq->req_completed = false;
 	test_rq->req_result = -EINVAL;
 	test_rq->rq = rq;
+	if (ptd->test_info.get_rq_disk_fn)
+		test_rq->rq->rq_disk = ptd->test_info.get_rq_disk_fn();
 	test_rq->is_err_expected = is_err_expcted;
 	rq->elv.priv[0] = (void *)test_rq;
 
-	test_pr_debug(
-		"%s: added request %d to the test requests list, buf_size=%d",
-		__func__, test_rq->req_id, buf_size);
+	test_pr_debug("%s: created test request %d, buf_size=%d",
+			__func__, test_rq->req_id, buf_size);
 
-	list_add_tail(&test_rq->queuelist, &ptd->test_queue);
-
-	return 0;
+	return test_rq;
 err:
 	blk_put_request(rq);
 	kfree(test_rq->bios_buffer);
+	return NULL;
+}
+EXPORT_SYMBOL(test_iosched_create_test_req);
+
+
+/**
+ * test_iosched_add_wr_rd_test_req() - Create and queue a
+ * read/write request.
+ * @is_err_expcted:	A flag to indicate if this request
+ *			should succeed or not
+ * @direction:		READ/WRITE
+ * @start_sec:		start address of the first bio
+ * @num_bios:		number of BIOs to be allocated for the
+ *			request
+ * @pattern:		A pattern, to be written into the write
+ *			requests data buffer. In case of READ
+ *			request, the given pattern is kept as
+ *			the expected pattern. The expected
+ *			pattern will be compared in the test
+ *			check result function. If no comparisson
+ *			is required, set pattern to
+ *			TEST_NO_PATTERN.
+ * @end_req_io:		specific completion callback. When not
+ *			set,the default callback will be used
+ *
+ * This function allocates the test request and the block
+ * request and calls blk_rq_map_kern which allocates the
+ * required BIO. Upon success the new request is added to the
+ * test_queue. The allocated test request and the block request
+ * memory is freed at the end of the test and the allocated BIO
+ * memory is freed by end_test_bio.
+ */
+int test_iosched_add_wr_rd_test_req(int is_err_expcted,
+		      int direction, int start_sec,
+		      int num_bios, int pattern, rq_end_io_fn *end_req_io)
+{
+	struct test_request *test_rq = NULL;
+
+	test_rq = test_iosched_create_test_req(is_err_expcted,
+			direction, start_sec,
+			num_bios, pattern, end_req_io);
+	if (test_rq) {
+		spin_lock_irq(ptd->req_q->queue_lock);
+		list_add_tail(&test_rq->queuelist, &ptd->test_queue);
+		ptd->test_count++;
+		spin_unlock_irq(ptd->req_q->queue_lock);
+		return 0;
+	}
 	return -ENODEV;
 }
 EXPORT_SYMBOL(test_iosched_add_wr_rd_test_req);
@@ -431,12 +492,18 @@
 static int check_test_result(struct test_data *td)
 {
 	struct test_request *test_rq;
-	struct request *rq;
 	int res = 0;
 	static int run;
 
-	list_for_each_entry(test_rq, &ptd->test_queue, queuelist) {
-		rq = test_rq->rq;
+	if (!ptd)
+		goto err;
+
+	list_for_each_entry(test_rq, &ptd->dispatched_queue, queuelist) {
+		if (!test_rq->rq) {
+			test_pr_info("%s: req_id %d is contains empty req",
+					__func__, test_rq->req_id);
+			continue;
+		}
 		if (!test_rq->req_completed) {
 			test_pr_err("%s: rq %d not completed", __func__,
 				    test_rq->req_id);
@@ -509,27 +576,25 @@
 		return ret;
 	}
 
-	/*
-	 * Set the next_req pointer to the first request in the test requests
-	 * list
-	 */
-	if (!list_empty(&td->test_queue))
-		td->next_req = list_entry(td->test_queue.next,
-					  struct test_request, queuelist);
-	__blk_run_queue(td->req_q);
+	blk_run_queue(td->req_q);
 
 	return 0;
 }
 
-/* Free the allocated test requests, their requests and BIOs buffer */
-static void free_test_requests(struct test_data *td)
+/*
+ * free_test_queue() - Free all allocated test requests in the given test_queue:
+ * free their requests and BIOs buffer
+ * @test_queue		the test queue to be freed
+ */
+static void free_test_queue(struct list_head *test_queue)
 {
 	struct test_request *test_rq;
 	struct bio *bio;
 
-	while (!list_empty(&td->test_queue)) {
-		test_rq = list_entry(td->test_queue.next, struct test_request,
-				     queuelist);
+	while (!list_empty(test_queue)) {
+		test_rq = list_entry(test_queue->next, struct test_request,
+				queuelist);
+
 		list_del_init(&test_rq->queuelist);
 		/*
 		 * If the request was not completed we need to free its BIOs
@@ -538,7 +603,7 @@
 		if (!test_rq->req_completed) {
 			test_pr_info(
 				"%s: Freeing memory of an uncompleted request",
-				__func__);
+					__func__);
 			list_del_init(&test_rq->rq->queuelist);
 			while ((bio = test_rq->rq->bio) != NULL) {
 				test_rq->rq->bio = bio->bi_next;
@@ -552,8 +617,39 @@
 }
 
 /*
- * Do post test operations.
- * Free the allocated test requests, their requests and BIOs buffer.
+ * free_test_requests() - Free all allocated test requests in
+ * all test queues in given test_data.
+ * @td		The test_data struct whos test requests will be
+ *		freed.
+ */
+static void free_test_requests(struct test_data *td)
+{
+	if (!td)
+		return;
+
+	if (td->urgent_count) {
+		free_test_queue(&td->urgent_queue);
+		td->urgent_count = 0;
+	}
+	if (td->test_count) {
+		free_test_queue(&td->test_queue);
+		td->test_count = 0;
+	}
+	if (td->dispatched_count) {
+		free_test_queue(&td->dispatched_queue);
+		td->dispatched_count = 0;
+	}
+	if (td->reinsert_count) {
+		free_test_queue(&td->reinsert_queue);
+		td->reinsert_count = 0;
+	}
+}
+
+/*
+ * post_test() - Do post test operations. Free the allocated
+ * test requests, their requests and BIOs buffer.
+ * @td		The test_data struct for the test that has
+ *		ended.
  */
 static int post_test(struct test_data *td)
 {
@@ -594,6 +690,8 @@
 
 /**
  * test_iosched_start_test() - Prepares and runs the test.
+ * The members test_duration and test_byte_count of the input
+ * parameter t_info are modified by this function.
  * @t_info:	the current test testcase and callbacks
  *		functions
  *
@@ -641,7 +739,6 @@
 
 		memcpy(&ptd->test_info, t_info, sizeof(struct test_info));
 
-		ptd->next_req = NULL;
 		ptd->test_result = TEST_NO_RESULT;
 		ptd->num_of_write_bios = 0;
 
@@ -683,6 +780,7 @@
 
 		wait_event(ptd->wait_q, ptd->test_state == TEST_COMPLETED);
 		t_info->test_duration = ptd->test_info.test_duration;
+		t_info->test_byte_count = ptd->test_info.test_byte_count;
 		del_timer_sync(&ptd->timeout_timer);
 
 		ret = check_test_result(ptd);
@@ -702,7 +800,7 @@
 		 * Wakeup the queue thread to fetch FS requests that might got
 		 * postponded due to the test
 		 */
-		__blk_run_queue(ptd->req_q);
+		blk_run_queue(ptd->req_q);
 
 		if (ptd->ignore_round)
 			test_pr_info(
@@ -886,6 +984,46 @@
 {
 	list_del_init(&next->queuelist);
 }
+/*
+ * test_dispatch_from(): Dispatch request from @queue to the @dispatched_queue.
+ * Also update th dispatched_count counter.
+ */
+static int test_dispatch_from(struct request_queue *q,
+		struct list_head *queue, unsigned int *count)
+{
+	struct test_request *test_rq;
+	struct request *rq;
+	int ret = 0;
+
+	if (!ptd)
+		goto err;
+
+	spin_lock_irq(&ptd->lock);
+	if (!list_empty(queue)) {
+		test_rq = list_entry(queue->next, struct test_request,
+				queuelist);
+		rq = test_rq->rq;
+		if (!rq) {
+			pr_err("%s: null request,return", __func__);
+			spin_unlock_irq(&ptd->lock);
+			goto err;
+		}
+		list_move_tail(&test_rq->queuelist, &ptd->dispatched_queue);
+		ptd->dispatched_count++;
+		(*count)--;
+		spin_unlock_irq(&ptd->lock);
+
+		print_req(rq);
+		elv_dispatch_sort(q, rq);
+		ptd->test_info.test_byte_count += test_rq->buf_size;
+		ret = 1;
+		goto err;
+	}
+	spin_unlock_irq(&ptd->lock);
+
+err:
+	return ret;
+}
 
 /*
  * Dispatch a test request in case there is a running test Otherwise, dispatch
@@ -895,6 +1033,7 @@
 {
 	struct test_data *td = q->elevator->elevator_data;
 	struct request *rq = NULL;
+	int ret = 0;
 
 	switch (td->test_state) {
 	case TEST_IDLE:
@@ -903,27 +1042,39 @@
 					queuelist);
 			list_del_init(&rq->queuelist);
 			elv_dispatch_sort(q, rq);
-			return 1;
+			ret = 1;
+			goto exit;
 		}
 		break;
 	case TEST_RUNNING:
-		if (td->next_req) {
-			rq = td->next_req->rq;
-			td->next_req =
-				latter_test_request(td->req_q, td->next_req);
-			if (!rq)
-				return 0;
-			print_req(rq);
-			elv_dispatch_sort(q, rq);
-			return 1;
+		if (test_dispatch_from(q, &td->urgent_queue,
+				       &td->urgent_count)) {
+			test_pr_debug("%s: Dispatched from urgent_count=%d",
+					__func__, ptd->urgent_count);
+			ret = 1;
+			goto exit;
+		}
+		if (test_dispatch_from(q, &td->reinsert_queue,
+				       &td->reinsert_count)) {
+			test_pr_debug("%s: Dispatched from reinsert_count=%d",
+					__func__, ptd->reinsert_count);
+			ret = 1;
+			goto exit;
+		}
+		if (test_dispatch_from(q, &td->test_queue, &td->test_count)) {
+			test_pr_debug("%s: Dispatched from test_count=%d",
+					__func__, ptd->test_count);
+			ret = 1;
+			goto exit;
 		}
 		break;
 	case TEST_COMPLETED:
 	default:
-		return 0;
+		break;
 	}
 
-	return 0;
+exit:
+	return ret;
 }
 
 static void test_add_request(struct request_queue *q, struct request *rq)
@@ -976,6 +1127,9 @@
 	memset((void *)ptd, 0, sizeof(struct test_data));
 	INIT_LIST_HEAD(&ptd->queue);
 	INIT_LIST_HEAD(&ptd->test_queue);
+	INIT_LIST_HEAD(&ptd->dispatched_queue);
+	INIT_LIST_HEAD(&ptd->reinsert_queue);
+	INIT_LIST_HEAD(&ptd->urgent_queue);
 	init_waitqueue_head(&ptd->wait_q);
 	ptd->req_q = q;
 
@@ -1010,7 +1164,79 @@
 	kfree(td);
 }
 
+/**
+ * test_get_test_data() - Returns a pointer to the test_data
+ * struct which keeps the current test data.
+ *
+ */
+struct test_data *test_get_test_data(void)
+{
+	return ptd;
+}
+EXPORT_SYMBOL(test_get_test_data);
+
+static bool test_urgent_pending(struct request_queue *q)
+{
+	return !list_empty(&ptd->urgent_queue);
+}
+
+/**
+ * test_iosched_add_urgent_req() - Add an urgent test_request.
+ * First mark the request as urgent, then add it to the
+ * urgent_queue test queue.
+ * @test_rq:		pointer to the urgent test_request to be
+ *			added.
+ *
+ */
+void test_iosched_add_urgent_req(struct test_request *test_rq)
+{
+	spin_lock_irq(&ptd->lock);
+	blk_mark_rq_urgent(test_rq->rq);
+	list_add_tail(&test_rq->queuelist, &ptd->urgent_queue);
+	ptd->urgent_count++;
+	spin_unlock_irq(&ptd->lock);
+}
+EXPORT_SYMBOL(test_iosched_add_urgent_req);
+
+/**
+ * test_reinsert_req() - Moves the @rq request from
+ *			@dispatched_queue into @reinsert_queue.
+ *			The @rq must be in @dispatched_queue
+ * @q:		request queue
+ * @rq:		request to be inserted
+ *
+ *
+ */
+static int test_reinsert_req(struct request_queue *q,
+			     struct request *rq)
+{
+	struct test_request *test_rq;
+	int ret = -EINVAL;
+
+	if (!ptd)
+		goto exit;
+
+	if (list_empty(&ptd->dispatched_queue)) {
+			test_pr_err("%s: dispatched_queue is empty", __func__);
+			goto exit;
+	}
+
+	list_for_each_entry(test_rq, &ptd->dispatched_queue, queuelist) {
+		if (test_rq->rq == rq) {
+			list_move(&test_rq->queuelist, &ptd->reinsert_queue);
+			ptd->dispatched_count--;
+			ptd->reinsert_count++;
+			ret = 0;
+			break;
+		}
+	}
+
+exit:
+	return ret;
+}
+
 static struct elevator_type elevator_test_iosched = {
+
 	.ops = {
 		.elevator_merge_req_fn = test_merged_requests,
 		.elevator_dispatch_fn = test_dispatch_requests,
@@ -1019,6 +1245,8 @@
 		.elevator_latter_req_fn = test_latter_request,
 		.elevator_init_fn = test_init_queue,
 		.elevator_exit_fn = test_exit_queue,
+		.elevator_is_urgent_fn = test_urgent_pending,
+		.elevator_reinsert_req_fn = test_reinsert_req,
 	},
 	.elevator_name = "test-iosched",
 	.elevator_owner = THIS_MODULE,
diff --git a/drivers/Kconfig b/drivers/Kconfig
index a73d713..adead10 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -150,4 +150,6 @@
 
 source "drivers/coresight/Kconfig"
 
+source "drivers/bif/Kconfig"
+
 endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index bd18a62..d55b035 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -141,4 +141,6 @@
 #MobiCore
 obj-$(CONFIG_MOBICORE_SUPPORT)  += gud/
 
-obj-$(CONFIG_MSM_QDSS)		+= coresight/
+obj-$(CONFIG_CORESIGHT)		+= coresight/
+
+obj-$(CONFIG_BIF)		+= bif/
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 6bdedd7..83ef121 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -83,6 +83,17 @@
 
 	  If unsure, say N.
 
+config SATA_AHCI_MSM
+	tristate "Qualcomm MSM AHCI SATA support"
+	depends on ARCH_MSM
+	select SATA_AHCI_PLATFORM
+	help
+	  This option enables support for AHCI SATA controller
+	  integrated into Qualcomm MSM chipsets. For more
+	  information please refer to http://www.qualcomm.com/chipsets.
+
+	  If unsure, say N.
+
 config SATA_FSL
 	tristate "Freescale 3.0Gbps SATA support"
 	depends on FSL_SOC
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index 6ece5b7..bc40152 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -9,6 +9,7 @@
 obj-$(CONFIG_SATA_INIC162X)	+= sata_inic162x.o
 obj-$(CONFIG_SATA_SIL24)	+= sata_sil24.o
 obj-$(CONFIG_SATA_DWC)		+= sata_dwc_460ex.o
+obj-$(CONFIG_SATA_AHCI_MSM)	+= ahci_msm.o
 
 # SFF w/ custom DMA
 obj-$(CONFIG_PDC_ADMA)		+= pdc_adma.o
diff --git a/drivers/ata/ahci_msm.c b/drivers/ata/ahci_msm.c
new file mode 100644
index 0000000..8536040
--- /dev/null
+++ b/drivers/ata/ahci_msm.c
@@ -0,0 +1,778 @@
+/*
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * SATA init module.
+ * To be used with SATA interface on MSM targets.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/iopoll.h>
+#include <linux/regulator/consumer.h>
+#include <linux/ahci_platform.h>
+#include <mach/clk.h>
+
+/* PHY registers */
+#define UNIPHY_PLL_REFCLK_CFG		0x000
+#define UNIPHY_PLL_POSTDIV1_CFG		0x004
+#define UNIPHY_PLL_CHGPUMP_CFG		0x008
+#define UNIPHY_PLL_VCOLPF_CFG		0x00C
+#define UNIPHY_PLL_VREG_CFG		0x010
+#define UNIPHY_PLL_PWRGEN_CFG		0x014
+#define UNIPHY_PLL_DMUX_CFG		0x018
+#define UNIPHY_PLL_AMUX_CFG		0x01C
+#define UNIPHY_PLL_GLB_CFG		0x020
+#define UNIPHY_PLL_POSTDIV2_CFG		0x024
+#define UNIPHY_PLL_POSTDIV3_CFG		0x028
+#define UNIPHY_PLL_LPFR_CFG		0x02C
+#define UNIPHY_PLL_LPFC1_CFG		0x030
+#define UNIPHY_PLL_LPFC2_CFG		0x034
+#define UNIPHY_PLL_SDM_CFG0		0x038
+#define UNIPHY_PLL_SDM_CFG1		0x03C
+#define UNIPHY_PLL_SDM_CFG2		0x040
+#define UNIPHY_PLL_SDM_CFG3		0x044
+#define UNIPHY_PLL_SDM_CFG4		0x048
+#define UNIPHY_PLL_SSC_CFG0		0x04C
+#define UNIPHY_PLL_SSC_CFG1		0x050
+#define UNIPHY_PLL_SSC_CFG2		0x054
+#define UNIPHY_PLL_SSC_CFG3		0x058
+#define UNIPHY_PLL_LKDET_CFG0		0x05C
+#define UNIPHY_PLL_LKDET_CFG1		0x060
+#define UNIPHY_PLL_LKDET_CFG2		0x064
+#define UNIPHY_PLL_TEST_CFG		0x068
+#define UNIPHY_PLL_CAL_CFG0		0x06C
+#define UNIPHY_PLL_CAL_CFG1		0x070
+#define UNIPHY_PLL_CAL_CFG2		0x074
+#define UNIPHY_PLL_CAL_CFG3		0x078
+#define UNIPHY_PLL_CAL_CFG4		0x07C
+#define UNIPHY_PLL_CAL_CFG5		0x080
+#define UNIPHY_PLL_CAL_CFG6		0x084
+#define UNIPHY_PLL_CAL_CFG7		0x088
+#define UNIPHY_PLL_CAL_CFG8		0x08C
+#define UNIPHY_PLL_CAL_CFG9		0x090
+#define UNIPHY_PLL_CAL_CFG10		0x094
+#define UNIPHY_PLL_CAL_CFG11		0x098
+#define UNIPHY_PLL_EFUSE_CFG		0x09C
+#define UNIPHY_PLL_DEBUG_BUS_SEL	0x0A0
+#define UNIPHY_PLL_CTRL_42		0x0A4
+#define UNIPHY_PLL_CTRL_43		0x0A8
+#define UNIPHY_PLL_CTRL_44		0x0AC
+#define UNIPHY_PLL_CTRL_45		0x0B0
+#define UNIPHY_PLL_CTRL_46		0x0B4
+#define UNIPHY_PLL_CTRL_47		0x0B8
+#define UNIPHY_PLL_CTRL_48		0x0BC
+#define UNIPHY_PLL_STATUS		0x0C0
+#define UNIPHY_PLL_DEBUG_BUS0		0x0C4
+#define UNIPHY_PLL_DEBUG_BUS1		0x0C8
+#define UNIPHY_PLL_DEBUG_BUS2		0x0CC
+#define UNIPHY_PLL_DEBUG_BUS3		0x0D0
+#define UNIPHY_PLL_CTRL_54		0x0D4
+
+#define SATA_PHY_SER_CTRL		0x100
+#define SATA_PHY_TX_DRIV_CTRL0		0x104
+#define SATA_PHY_TX_DRIV_CTRL1		0x108
+#define SATA_PHY_TX_DRIV_CTRL2		0x10C
+#define SATA_PHY_TX_DRIV_CTRL3		0x110
+#define SATA_PHY_TX_RESV0		0x114
+#define SATA_PHY_TX_RESV1		0x118
+#define SATA_PHY_TX_IMCAL0		0x11C
+#define SATA_PHY_TX_IMCAL1		0x120
+#define SATA_PHY_TX_IMCAL2		0x124
+#define SATA_PHY_RX_IMCAL0		0x128
+#define SATA_PHY_RX_IMCAL1		0x12C
+#define SATA_PHY_RX_IMCAL2		0x130
+#define SATA_PHY_RX_TERM		0x134
+#define SATA_PHY_RX_TERM_RESV		0x138
+#define SATA_PHY_EQUAL			0x13C
+#define SATA_PHY_EQUAL_RESV		0x140
+#define SATA_PHY_OOB_TERM		0x144
+#define SATA_PHY_CDR_CTRL0		0x148
+#define SATA_PHY_CDR_CTRL1		0x14C
+#define SATA_PHY_CDR_CTRL2		0x150
+#define SATA_PHY_CDR_CTRL3		0x154
+#define SATA_PHY_CDR_CTRL4		0x158
+#define SATA_PHY_FA_LOAD0		0x15C
+#define SATA_PHY_FA_LOAD1		0x160
+#define SATA_PHY_CDR_CTRL_RESV		0x164
+#define SATA_PHY_PI_CTRL0		0x168
+#define SATA_PHY_PI_CTRL1		0x16C
+#define SATA_PHY_DESER_RESV		0x170
+#define SATA_PHY_RX_RESV0		0x174
+#define SATA_PHY_AD_TPA_CTRL		0x178
+#define SATA_PHY_REFCLK_CTRL		0x17C
+#define SATA_PHY_POW_DWN_CTRL0		0x180
+#define SATA_PHY_POW_DWN_CTRL1		0x184
+#define SATA_PHY_TX_DATA_CTRL		0x188
+#define SATA_PHY_BIST_GEN0		0x18C
+#define SATA_PHY_BIST_GEN1		0x190
+#define SATA_PHY_BIST_GEN2		0x194
+#define SATA_PHY_BIST_GEN3		0x198
+#define SATA_PHY_LBK_CTRL		0x19C
+#define SATA_PHY_TEST_DEBUG_CTRL	0x1A0
+#define SATA_PHY_ALIGNP			0x1A4
+#define SATA_PHY_PRBS_CFG0		0x1A8
+#define SATA_PHY_PRBS_CFG1		0x1AC
+#define SATA_PHY_PRBS_CFG2		0x1B0
+#define SATA_PHY_PRBS_CFG3		0x1B4
+#define SATA_PHY_CHAN_COMP_CHK_CNT	0x1B8
+#define SATA_PHY_RESET_CTRL		0x1BC
+#define SATA_PHY_RX_CLR			0x1C0
+#define SATA_PHY_RX_EBUF_CTRL		0x1C4
+#define SATA_PHY_ID0			0x1C8
+#define SATA_PHY_ID1			0x1CC
+#define SATA_PHY_ID2			0x1D0
+#define SATA_PHY_ID3			0x1D4
+#define SATA_PHY_RX_CHK_ERR_CNT0	0x1D8
+#define SATA_PHY_RX_CHK_ERR_CNT1	0x1DC
+#define SATA_PHY_RX_CHK_STAT		0x1E0
+#define SATA_PHY_TX_IMCAL_STAT		0x1E4
+#define SATA_PHY_RX_IMCAL_STAT		0x1E8
+#define SATA_PHY_RX_EBUF_STAT		0x1EC
+#define SATA_PHY_DEBUG_BUS_STAT0	0x1F0
+#define SATA_PHY_DEBUG_BUS_STAT1	0x1F4
+#define SATA_PHY_DEBUG_BUS_STAT2	0x1F8
+#define SATA_PHY_DEBUG_BUS_STAT3	0x1FC
+
+#define AHCI_HOST_CAP		0x00
+#define AHCI_HOST_CAP_MASK	0x1F
+#define AHCI_HOST_CAP_PMP	(1 << 17)
+
+struct msm_sata_hba {
+	struct platform_device *ahci_pdev;
+	struct clk *slave_iface_clk;
+	struct clk *bus_clk;
+	struct clk *iface_clk;
+	struct clk *src_clk;
+	struct clk *rxoob_clk;
+	struct clk *pmalive_clk;
+	struct clk *cfg_clk;
+	struct regulator *clk_pwr;
+	struct regulator *pmp_pwr;
+	void __iomem *phy_base;
+	void __iomem *ahci_base;
+};
+
+static inline void msm_sata_delay_us(unsigned int delay)
+{
+	/* sleep for max. 50us more to combine processor wakeups */
+	usleep_range(delay, delay + 50);
+}
+
+static int msm_sata_clk_get_prepare_enable_set_rate(struct device *dev,
+		const char *name, struct clk **out_clk, int rate)
+{
+	int ret = 0;
+	struct clk *clk;
+
+	clk = devm_clk_get(dev, name);
+	if (IS_ERR(clk)) {
+		ret = PTR_ERR(clk);
+		dev_err(dev, "failed to get clk: %s err = %d\n", name, ret);
+		goto out;
+	}
+
+	if (rate >= 0) {
+		ret = clk_set_rate(clk, rate);
+		if (ret) {
+			dev_err(dev, "failed to set rate: %d clk: %s err = %d\n",
+					rate, name, ret);
+			goto out;
+		}
+	}
+
+	ret = clk_prepare_enable(clk);
+	if (ret)
+		dev_err(dev, "failed to enable clk: %s err = %d\n", name, ret);
+out:
+	if (!ret)
+		*out_clk = clk;
+
+	return ret;
+}
+
+static int msm_sata_clk_get_prepare_enable(struct device *dev,
+		const char *name, struct clk **out_clk)
+{
+	return msm_sata_clk_get_prepare_enable_set_rate(dev, name, out_clk, -1);
+}
+
+static void msm_sata_clk_put_unprepare_disable(struct clk **clk)
+{
+	if (*clk) {
+		clk_disable_unprepare(*clk);
+		clk_put(*clk);
+		*clk = NULL;
+	}
+}
+
+static int msm_sata_hard_reset(struct device *dev)
+{
+	int ret;
+	struct msm_sata_hba *hba = dev_get_drvdata(dev);
+
+	ret = clk_reset(hba->iface_clk, CLK_RESET_ASSERT);
+	if (ret) {
+		dev_err(dev, "iface_clk assert failed %d\n", ret);
+		goto out;
+	}
+
+	ret = clk_reset(hba->iface_clk, CLK_RESET_DEASSERT);
+	if (ret) {
+		dev_err(dev, "iface_clk de-assert failed %d\n", ret);
+		goto out;
+	}
+out:
+	return ret;
+}
+
+static int msm_sata_clk_init(struct device *dev)
+{
+	int ret = 0;
+	struct msm_sata_hba *hba = dev_get_drvdata(dev);
+
+	/* Enable AHB clock for system fabric slave port connected to SATA */
+	ret = msm_sata_clk_get_prepare_enable(dev,
+			"slave_iface_clk", &hba->slave_iface_clk);
+	if (ret)
+		goto out;
+
+	/* Enable AHB clock for system fabric and SATA core interface */
+	ret = msm_sata_clk_get_prepare_enable(dev,
+			"iface_clk", &hba->iface_clk);
+	if (ret)
+		goto put_dis_slave_iface_clk;
+
+	/* Enable AXI clock for SATA AXI master and slave interfaces */
+	ret = msm_sata_clk_get_prepare_enable(dev,
+			"bus_clk", &hba->bus_clk);
+	if (ret)
+		goto put_dis_iface_clk;
+
+	/* Enable the source clock for pmalive, rxoob and phy ref clocks */
+	ret = msm_sata_clk_get_prepare_enable_set_rate(dev,
+			"src_clk", &hba->src_clk, 100000000);
+	if (ret)
+		goto put_dis_bus_clk;
+
+	/*
+	 * Enable RX OOB detection clock. The clock rate is
+	 * same as PHY reference clock (100MHz).
+	 */
+	ret = msm_sata_clk_get_prepare_enable(dev,
+			"core_rxoob_clk", &hba->rxoob_clk);
+	if (ret)
+		goto put_dis_src_clk;
+
+	/*
+	 * Enable power management always-on clock. The clock rate
+	 * is same as PHY reference clock (100MHz).
+	 */
+	ret = msm_sata_clk_get_prepare_enable(dev,
+			"core_pmalive_clk", &hba->pmalive_clk);
+	if (ret)
+		goto put_dis_rxoob_clk;
+
+	/* Enable PHY configuration AHB clock, fixed 64MHz clock */
+	ret = msm_sata_clk_get_prepare_enable(dev,
+			"cfg_clk", &hba->cfg_clk);
+	if (ret)
+		goto put_dis_pmalive_clk;
+
+	return ret;
+
+put_dis_pmalive_clk:
+	msm_sata_clk_put_unprepare_disable(&hba->pmalive_clk);
+put_dis_rxoob_clk:
+	msm_sata_clk_put_unprepare_disable(&hba->rxoob_clk);
+put_dis_src_clk:
+	msm_sata_clk_put_unprepare_disable(&hba->src_clk);
+put_dis_bus_clk:
+	msm_sata_clk_put_unprepare_disable(&hba->bus_clk);
+put_dis_iface_clk:
+	msm_sata_clk_put_unprepare_disable(&hba->iface_clk);
+put_dis_slave_iface_clk:
+	msm_sata_clk_put_unprepare_disable(&hba->slave_iface_clk);
+out:
+	return ret;
+}
+
+static void msm_sata_clk_deinit(struct device *dev)
+{
+	struct msm_sata_hba *hba = dev_get_drvdata(dev);
+
+	msm_sata_clk_put_unprepare_disable(&hba->cfg_clk);
+	msm_sata_clk_put_unprepare_disable(&hba->pmalive_clk);
+	msm_sata_clk_put_unprepare_disable(&hba->rxoob_clk);
+	msm_sata_clk_put_unprepare_disable(&hba->src_clk);
+	msm_sata_clk_put_unprepare_disable(&hba->bus_clk);
+	msm_sata_clk_put_unprepare_disable(&hba->iface_clk);
+	msm_sata_clk_put_unprepare_disable(&hba->slave_iface_clk);
+}
+
+static int msm_sata_vreg_get_enable_set_vdd(struct device *dev,
+			const char *name, struct regulator **out_vreg,
+			int min_uV, int max_uV, int hpm_uA)
+{
+	int ret = 0;
+	struct regulator *vreg;
+
+	vreg = devm_regulator_get(dev, name);
+	if (IS_ERR(vreg)) {
+		ret = PTR_ERR(vreg);
+		dev_err(dev, "Regulator: %s get failed, err=%d\n", name, ret);
+		goto out;
+	}
+
+	if (regulator_count_voltages(vreg) > 0) {
+		ret = regulator_set_voltage(vreg, min_uV, max_uV);
+		if (ret) {
+			dev_err(dev, "Regulator: %s set voltage failed, err=%d\n",
+					name, ret);
+			goto err;
+		}
+
+		ret = regulator_set_optimum_mode(vreg, hpm_uA);
+		if (ret < 0) {
+			dev_err(dev, "Regulator: %s set optimum mode(uA_load=%d) failed, err=%d\n",
+					name, hpm_uA, ret);
+			goto err;
+		} else {
+			/*
+			 * regulator_set_optimum_mode() can return non zero
+			 * value even for success case.
+			 */
+			ret = 0;
+		}
+	}
+
+	ret = regulator_enable(vreg);
+	if (ret)
+		dev_err(dev, "Regulator: %s enable failed, err=%d\n",
+				name, ret);
+err:
+	if (!ret)
+		*out_vreg = vreg;
+	else
+		devm_regulator_put(vreg);
+out:
+	return ret;
+}
+
+static int msm_sata_vreg_put_disable(struct device *dev,
+		struct regulator *reg, const char *name, int max_uV)
+{
+	int ret;
+
+	if (!reg)
+		return 0;
+
+	ret = regulator_disable(reg);
+	if (ret) {
+		dev_err(dev, "Regulator: %s disable failed err=%d\n",
+				name, ret);
+		goto err;
+	}
+
+	if (regulator_count_voltages(reg) > 0) {
+		ret = regulator_set_voltage(reg, 0, max_uV);
+		if (ret < 0) {
+			dev_err(dev, "Regulator: %s set voltage to 0 failed, err=%d\n",
+					name, ret);
+			goto err;
+		}
+
+		ret = regulator_set_optimum_mode(reg, 0);
+		if (ret < 0) {
+			dev_err(dev, "Regulator: %s set optimum mode(uA_load = 0) failed, err=%d\n",
+					name, ret);
+			goto err;
+		} else {
+			/*
+			 * regulator_set_optimum_mode() can return non zero
+			 * value even for success case.
+			 */
+			ret = 0;
+		}
+	}
+
+err:
+	devm_regulator_put(reg);
+	return ret;
+}
+
+static int msm_sata_vreg_init(struct device *dev)
+{
+	int ret = 0;
+	struct msm_sata_hba *hba = dev_get_drvdata(dev);
+
+	/*
+	 * The SATA clock generator needs 3.3V supply and can consume
+	 * max. 850mA during functional mode.
+	 */
+	ret = msm_sata_vreg_get_enable_set_vdd(dev, "sata_ext_3p3v",
+				&hba->clk_pwr, 3300000, 3300000, 850000);
+	if (ret)
+		goto out;
+
+	/* Add 1ms regulator ramp-up delay */
+	msm_sata_delay_us(1000);
+
+	/* Read AHCI capability register to check if PMP is supported.*/
+	if (readl_relaxed(hba->ahci_base +
+				AHCI_HOST_CAP) & AHCI_HOST_CAP_PMP) {
+		/* Power up port-multiplier */
+		ret = msm_sata_vreg_get_enable_set_vdd(dev, "sata_pmp_pwr",
+				&hba->pmp_pwr, 1800000, 1800000, 200000);
+		if (ret) {
+			msm_sata_vreg_put_disable(dev, hba->clk_pwr,
+					"sata_ext_3p3v", 3300000);
+			goto out;
+		}
+
+		/* Add 1ms regulator ramp-up delay */
+		msm_sata_delay_us(1000);
+	}
+
+out:
+	return ret;
+}
+
+static void msm_sata_vreg_deinit(struct device *dev)
+{
+	struct msm_sata_hba *hba = dev_get_drvdata(dev);
+
+	msm_sata_vreg_put_disable(dev, hba->clk_pwr,
+			"sata_ext_3p3v", 3300000);
+
+	if (hba->pmp_pwr)
+		msm_sata_vreg_put_disable(dev, hba->pmp_pwr,
+				"sata_pmp_pwr", 1800000);
+}
+
+static void msm_sata_phy_deinit(struct device *dev)
+{
+	struct msm_sata_hba *hba = dev_get_drvdata(dev);
+
+	/* Power down PHY */
+	writel_relaxed(0xF8, hba->phy_base + SATA_PHY_POW_DWN_CTRL0);
+	writel_relaxed(0xFE, hba->phy_base + SATA_PHY_POW_DWN_CTRL1);
+
+	/* Power down PLL block */
+	writel_relaxed(0x00, hba->phy_base + UNIPHY_PLL_GLB_CFG);
+	mb();
+
+	devm_iounmap(dev, hba->phy_base);
+}
+
+static int msm_sata_phy_init(struct device *dev)
+{
+	int ret = 0;
+	u32 reg = 0;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct msm_sata_hba *hba = dev_get_drvdata(dev);
+	struct resource *mem;
+
+	mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_mem");
+	if (!mem) {
+		dev_err(dev, "no mmio space\n");
+		return -EINVAL;
+	}
+
+	hba->phy_base = devm_ioremap(dev, mem->start, resource_size(mem));
+	if (!hba->phy_base) {
+		dev_err(dev, "failed to allocate memory for SATA PHY\n");
+		return -ENOMEM;
+	}
+
+	/* SATA phy initialization */
+
+	writel_relaxed(0x01, hba->phy_base + SATA_PHY_SER_CTRL);
+
+	writel_relaxed(0xB1, hba->phy_base + SATA_PHY_POW_DWN_CTRL0);
+	mb();
+	msm_sata_delay_us(10);
+
+	writel_relaxed(0x01, hba->phy_base + SATA_PHY_POW_DWN_CTRL0);
+	writel_relaxed(0x3E, hba->phy_base + SATA_PHY_POW_DWN_CTRL1);
+	writel_relaxed(0x01, hba->phy_base + SATA_PHY_RX_IMCAL0);
+	writel_relaxed(0x01, hba->phy_base + SATA_PHY_TX_IMCAL0);
+	writel_relaxed(0x02, hba->phy_base + SATA_PHY_TX_IMCAL2);
+
+	/* Write UNIPHYPLL registers to configure PLL */
+	writel_relaxed(0x04, hba->phy_base + UNIPHY_PLL_REFCLK_CFG);
+	writel_relaxed(0x00, hba->phy_base + UNIPHY_PLL_PWRGEN_CFG);
+
+	writel_relaxed(0x0A, hba->phy_base + UNIPHY_PLL_CAL_CFG0);
+	writel_relaxed(0xF3, hba->phy_base + UNIPHY_PLL_CAL_CFG8);
+	writel_relaxed(0x01, hba->phy_base + UNIPHY_PLL_CAL_CFG9);
+	writel_relaxed(0xED, hba->phy_base + UNIPHY_PLL_CAL_CFG10);
+	writel_relaxed(0x02, hba->phy_base + UNIPHY_PLL_CAL_CFG11);
+
+	writel_relaxed(0x36, hba->phy_base + UNIPHY_PLL_SDM_CFG0);
+	writel_relaxed(0x0D, hba->phy_base + UNIPHY_PLL_SDM_CFG1);
+	writel_relaxed(0xA3, hba->phy_base + UNIPHY_PLL_SDM_CFG2);
+	writel_relaxed(0xF0, hba->phy_base + UNIPHY_PLL_SDM_CFG3);
+	writel_relaxed(0x00, hba->phy_base + UNIPHY_PLL_SDM_CFG4);
+
+	writel_relaxed(0x19, hba->phy_base + UNIPHY_PLL_SSC_CFG0);
+	writel_relaxed(0xE1, hba->phy_base + UNIPHY_PLL_SSC_CFG1);
+	writel_relaxed(0x00, hba->phy_base + UNIPHY_PLL_SSC_CFG2);
+	writel_relaxed(0x11, hba->phy_base + UNIPHY_PLL_SSC_CFG3);
+
+	writel_relaxed(0x04, hba->phy_base + UNIPHY_PLL_LKDET_CFG0);
+	writel_relaxed(0xFF, hba->phy_base + UNIPHY_PLL_LKDET_CFG1);
+
+	writel_relaxed(0x02, hba->phy_base + UNIPHY_PLL_GLB_CFG);
+	mb();
+	msm_sata_delay_us(40);
+
+	writel_relaxed(0x03, hba->phy_base + UNIPHY_PLL_GLB_CFG);
+	mb();
+	msm_sata_delay_us(400);
+
+	writel_relaxed(0x05, hba->phy_base + UNIPHY_PLL_LKDET_CFG2);
+	mb();
+
+	/* poll for ready status, timeout after 1 sec */
+	ret = readl_poll_timeout(hba->phy_base + UNIPHY_PLL_STATUS, reg,
+			(reg & 1 << 0), 100, 1000000);
+	if (ret) {
+		dev_err(dev, "poll timeout UNIPHY_PLL_STATUS\n");
+		goto out;
+	}
+
+	ret = readl_poll_timeout(hba->phy_base + SATA_PHY_TX_IMCAL_STAT, reg,
+			(reg & 1 << 0), 100, 1000000);
+	if (ret) {
+		dev_err(dev, "poll timeout SATA_PHY_TX_IMCAL_STAT\n");
+		goto out;
+	}
+
+	ret = readl_poll_timeout(hba->phy_base + SATA_PHY_RX_IMCAL_STAT, reg,
+			(reg & 1 << 0), 100, 1000000);
+	if (ret) {
+		dev_err(dev, "poll timeout SATA_PHY_RX_IMCAL_STAT\n");
+		goto out;
+	}
+
+	/* SATA phy calibrated succesfully, power up to functional mode */
+	writel_relaxed(0x3E, hba->phy_base + SATA_PHY_POW_DWN_CTRL1);
+	writel_relaxed(0x01, hba->phy_base + SATA_PHY_RX_IMCAL0);
+	writel_relaxed(0x01, hba->phy_base + SATA_PHY_TX_IMCAL0);
+
+	writel_relaxed(0x00, hba->phy_base + SATA_PHY_POW_DWN_CTRL1);
+	writel_relaxed(0x59, hba->phy_base + SATA_PHY_CDR_CTRL0);
+	writel_relaxed(0x04, hba->phy_base + SATA_PHY_CDR_CTRL1);
+	writel_relaxed(0x00, hba->phy_base + SATA_PHY_CDR_CTRL2);
+	writel_relaxed(0x00, hba->phy_base + SATA_PHY_PI_CTRL0);
+	writel_relaxed(0x00, hba->phy_base + SATA_PHY_CDR_CTRL3);
+	writel_relaxed(0x01, hba->phy_base + SATA_PHY_POW_DWN_CTRL0);
+
+	writel_relaxed(0x11, hba->phy_base + SATA_PHY_TX_DATA_CTRL);
+	writel_relaxed(0x43, hba->phy_base + SATA_PHY_ALIGNP);
+	writel_relaxed(0x04, hba->phy_base + SATA_PHY_OOB_TERM);
+
+	writel_relaxed(0x01, hba->phy_base + SATA_PHY_EQUAL);
+	writel_relaxed(0x09, hba->phy_base + SATA_PHY_TX_DRIV_CTRL0);
+	writel_relaxed(0x09, hba->phy_base + SATA_PHY_TX_DRIV_CTRL1);
+	mb();
+
+	dev_dbg(dev, "SATA PHY powered up in functional mode\n");
+
+out:
+	/* power down PHY in case of failure */
+	if (ret)
+		msm_sata_phy_deinit(dev);
+
+	return ret;
+}
+
+int msm_sata_init(struct device *ahci_dev, void __iomem *mmio)
+{
+	int ret;
+	struct device *dev = ahci_dev->parent;
+	struct msm_sata_hba *hba = dev_get_drvdata(dev);
+
+	/* Save ahci mmio to access vendor specific registers */
+	hba->ahci_base = mmio;
+
+	ret = msm_sata_clk_init(dev);
+	if (ret) {
+		dev_err(dev, "SATA clk init failed with err=%d\n", ret);
+		goto out;
+	}
+
+	ret = msm_sata_vreg_init(dev);
+	if (ret) {
+		dev_err(dev, "SATA vreg init failed with err=%d\n", ret);
+		msm_sata_clk_deinit(dev);
+		goto out;
+	}
+
+	ret = msm_sata_phy_init(dev);
+	if (ret) {
+		dev_err(dev, "SATA PHY init failed with err=%d\n", ret);
+		msm_sata_vreg_deinit(dev);
+		msm_sata_clk_deinit(dev);
+		goto out;
+	}
+
+out:
+	return ret;
+}
+
+void msm_sata_deinit(struct device *ahci_dev)
+{
+	struct device *dev = ahci_dev->parent;
+
+	msm_sata_phy_deinit(dev);
+	msm_sata_vreg_deinit(dev);
+	msm_sata_clk_deinit(dev);
+}
+
+static int msm_sata_suspend(struct device *ahci_dev)
+{
+	msm_sata_deinit(ahci_dev);
+
+	return 0;
+}
+
+static int msm_sata_resume(struct device *ahci_dev)
+{
+	int ret;
+	struct device *dev = ahci_dev->parent;
+
+	ret = msm_sata_clk_init(dev);
+	if (ret) {
+		dev_err(dev, "SATA clk init failed with err=%d\n", ret);
+		/*
+		 * If clock initialization failed, that means ahci driver
+		 * cannot access any register going further. Since there is
+		 * no check within ahci driver to check for clock failures,
+		 * panic here instead of making an unclocked register access.
+		 */
+		BUG();
+	}
+
+	/* Issue asynchronous reset to reset PHY */
+	ret = msm_sata_hard_reset(dev);
+	if (ret)
+		goto out;
+
+	ret = msm_sata_vreg_init(dev);
+	if (ret) {
+		dev_err(dev, "SATA vreg init failed with err=%d\n", ret);
+		/* Do not turn off clks, AHCI driver might do register access */
+		goto out;
+	}
+
+	ret = msm_sata_phy_init(dev);
+	if (ret) {
+		dev_err(dev, "SATA PHY init failed with err=%d\n", ret);
+		/* Do not turn off clks, AHCI driver might do register access */
+		msm_sata_vreg_deinit(dev);
+		goto out;
+	}
+out:
+	return ret;
+}
+
+static struct ahci_platform_data msm_ahci_pdata = {
+	.init = msm_sata_init,
+	.exit = msm_sata_deinit,
+	.suspend = msm_sata_suspend,
+	.resume = msm_sata_resume,
+};
+
+static int __devinit msm_sata_probe(struct platform_device *pdev)
+{
+	struct platform_device *ahci;
+	struct msm_sata_hba *hba;
+	int ret = 0;
+
+	hba = devm_kzalloc(&pdev->dev, sizeof(struct msm_sata_hba), GFP_KERNEL);
+	if (!hba) {
+		dev_err(&pdev->dev, "no memory\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	platform_set_drvdata(pdev, hba);
+
+	ahci = platform_device_alloc("ahci", pdev->id);
+	if (!ahci) {
+		dev_err(&pdev->dev, "couldn't allocate ahci device\n");
+		ret = -ENOMEM;
+		goto err_free;
+	}
+
+	dma_set_coherent_mask(&ahci->dev, pdev->dev.coherent_dma_mask);
+
+	ahci->dev.parent = &pdev->dev;
+	ahci->dev.dma_mask = pdev->dev.dma_mask;
+	ahci->dev.dma_parms = pdev->dev.dma_parms;
+	hba->ahci_pdev = ahci;
+
+	ret = platform_device_add_resources(ahci, pdev->resource,
+			pdev->num_resources);
+	if (ret) {
+		dev_err(&pdev->dev, "couldn't add resources to ahci device\n");
+		goto err_put_device;
+	}
+
+	ahci->dev.platform_data = &msm_ahci_pdata;
+	ret = platform_device_add(ahci);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register ahci device\n");
+		goto err_put_device;
+	}
+
+	return 0;
+
+err_put_device:
+	platform_device_put(ahci);
+err_free:
+	devm_kfree(&pdev->dev, hba);
+err:
+	return ret;
+}
+
+static int __devexit msm_sata_remove(struct platform_device *pdev)
+{
+	struct msm_sata_hba *hba = platform_get_drvdata(pdev);
+
+	platform_device_unregister(hba->ahci_pdev);
+
+	return 0;
+}
+
+static struct platform_driver msm_sata_driver = {
+	.probe		= msm_sata_probe,
+	.remove		= __devexit_p(msm_sata_remove),
+	.driver		= {
+		.name	= "msm_sata",
+	},
+};
+
+module_platform_driver(msm_sata_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("AHCI platform MSM Glue Layer");
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index 82d19e0..ae685da 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -21,6 +21,7 @@
 #include <linux/platform_device.h>
 #include <linux/libata.h>
 #include <linux/ahci_platform.h>
+#include <linux/pm_runtime.h>
 #include "ahci.h"
 
 enum ahci_type {
@@ -73,7 +74,7 @@
 	AHCI_SHT("ahci_platform"),
 };
 
-static int __init ahci_probe(struct platform_device *pdev)
+static int __devinit ahci_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct ahci_platform_data *pdata = dev_get_platdata(dev);
@@ -192,6 +193,14 @@
 	if (rc)
 		goto err0;
 
+	rc = pm_runtime_set_active(dev);
+	if (rc) {
+		dev_warn(dev, "Unable to set runtime pm active err=%d\n", rc);
+	} else {
+		pm_runtime_enable(dev);
+		pm_runtime_forbid(dev);
+	}
+
 	return 0;
 err0:
 	if (pdata && pdata->exit)
@@ -223,6 +232,9 @@
 	u32 ctl;
 	int rc;
 
+	if (pm_runtime_suspended(dev))
+		return 0;
+
 	if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
 		dev_err(dev, "firmware update required for suspend/resume\n");
 		return -EIO;
@@ -247,7 +259,7 @@
 	return 0;
 }
 
-static int ahci_resume(struct device *dev)
+static int ahci_resume_common(struct device *dev)
 {
 	struct ahci_platform_data *pdata = dev_get_platdata(dev);
 	struct ata_host *host = dev_get_drvdata(dev);
@@ -272,9 +284,25 @@
 	return 0;
 }
 
+static int ahci_resume(struct device *dev)
+{
+	int rc;
+
+	rc = ahci_resume_common(dev);
+	if (!rc) {
+		pm_runtime_disable(dev);
+		pm_runtime_set_active(dev);
+		pm_runtime_enable(dev);
+	}
+
+	return rc;
+}
+
 static struct dev_pm_ops ahci_pm_ops = {
 	.suspend		= &ahci_suspend,
 	.resume			= &ahci_resume,
+	.runtime_suspend	= &ahci_suspend,
+	.runtime_resume		= &ahci_resume_common,
 };
 #endif
 
@@ -287,6 +315,7 @@
 MODULE_DEVICE_TABLE(of, ahci_of_match);
 
 static struct platform_driver ahci_driver = {
+	.probe	= ahci_probe,
 	.remove = __devexit_p(ahci_remove),
 	.driver = {
 		.name = "ahci",
@@ -301,7 +330,7 @@
 
 static int __init ahci_init(void)
 {
-	return platform_driver_probe(&ahci_driver, ahci_probe);
+	return platform_driver_register(&ahci_driver);
 }
 module_init(ahci_init);
 
diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
index 78efb03..3a8bbc5 100644
--- a/drivers/base/dma-contiguous.c
+++ b/drivers/base/dma-contiguous.c
@@ -9,6 +9,9 @@
  * modify it under the terms of the GNU General Public License as
  * published by the Free Software Foundation; either version 2 of the
  * License or (at your optional) any later version of the license.
+ *
+ * The Linux Foundation chooses to take subject only to the GPLv2 license
+ * terms, and distributes only under these terms.
  */
 
 #define pr_fmt(fmt) "cma: " fmt
@@ -24,6 +27,9 @@
 
 #include <linux/memblock.h>
 #include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
 #include <linux/mm.h>
 #include <linux/mutex.h>
 #include <linux/page-isolation.h>
@@ -31,6 +37,7 @@
 #include <linux/swap.h>
 #include <linux/mm_types.h>
 #include <linux/dma-contiguous.h>
+#include <trace/events/kmem.h>
 
 #ifndef SZ_1M
 #define SZ_1M (1 << 20)
@@ -42,7 +49,48 @@
 	unsigned long	*bitmap;
 };
 
-struct cma *dma_contiguous_default_area;
+static DEFINE_MUTEX(cma_mutex);
+
+struct cma *dma_contiguous_def_area;
+phys_addr_t dma_contiguous_def_base;
+
+static struct cma_area {
+	phys_addr_t base;
+	unsigned long size;
+	struct cma *cma;
+	const char *name;
+} cma_areas[MAX_CMA_AREAS];
+static unsigned cma_area_count;
+
+
+static struct cma_map {
+	phys_addr_t base;
+	struct device *dev;
+} cma_maps[MAX_CMA_AREAS] __initdata;
+static unsigned cma_map_count __initdata;
+
+static struct cma *cma_get_area(phys_addr_t base)
+{
+	int i;
+	for (i = 0; i < cma_area_count; i++)
+		if (cma_areas[i].base == base)
+			return cma_areas[i].cma;
+	return NULL;
+}
+
+static struct cma *cma_get_area_by_name(const char *name)
+{
+	int i;
+	if (!name)
+		return NULL;
+
+	for (i = 0; i < cma_area_count; i++)
+		if (cma_areas[i].name && strcmp(cma_areas[i].name, name) == 0)
+			return cma_areas[i].cma;
+	return NULL;
+}
+
+
 
 #ifdef CONFIG_CMA_SIZE_MBYTES
 #define CMA_SIZE_MBYTES CONFIG_CMA_SIZE_MBYTES
@@ -60,8 +108,8 @@
  * Users, who want to set the size of global CMA area for their system
  * should use cma= kernel parameter.
  */
-static const unsigned long size_bytes = CMA_SIZE_MBYTES * SZ_1M;
-static long size_cmdline = -1;
+static const phys_addr_t size_bytes = CMA_SIZE_MBYTES * SZ_1M;
+static phys_addr_t size_cmdline = -1;
 
 static int __init early_cma(char *p)
 {
@@ -73,7 +121,7 @@
 
 #ifdef CONFIG_CMA_SIZE_PERCENTAGE
 
-static unsigned long __init __maybe_unused cma_early_percent_memory(void)
+static phys_addr_t __init __maybe_unused cma_early_percent_memory(void)
 {
 	struct memblock_region *reg;
 	unsigned long total_pages = 0;
@@ -91,52 +139,13 @@
 
 #else
 
-static inline __maybe_unused unsigned long cma_early_percent_memory(void)
+static inline __maybe_unused phys_addr_t cma_early_percent_memory(void)
 {
 	return 0;
 }
 
 #endif
 
-/**
- * dma_contiguous_reserve() - reserve area for contiguous memory handling
- * @limit: End address of the reserved memory (optional, 0 for any).
- *
- * This function reserves memory from early allocator. It should be
- * called by arch specific code once the early allocator (memblock or bootmem)
- * has been activated and all other subsystems have already allocated/reserved
- * memory.
- */
-void __init dma_contiguous_reserve(phys_addr_t limit)
-{
-	unsigned long selected_size = 0;
-
-	pr_debug("%s(limit %08lx)\n", __func__, (unsigned long)limit);
-
-	if (size_cmdline != -1) {
-		selected_size = size_cmdline;
-	} else {
-#ifdef CONFIG_CMA_SIZE_SEL_MBYTES
-		selected_size = size_bytes;
-#elif defined(CONFIG_CMA_SIZE_SEL_PERCENTAGE)
-		selected_size = cma_early_percent_memory();
-#elif defined(CONFIG_CMA_SIZE_SEL_MIN)
-		selected_size = min(size_bytes, cma_early_percent_memory());
-#elif defined(CONFIG_CMA_SIZE_SEL_MAX)
-		selected_size = max(size_bytes, cma_early_percent_memory());
-#endif
-	}
-
-	if (selected_size) {
-		pr_debug("%s: reserving %ld MiB for global area\n", __func__,
-			 selected_size / SZ_1M);
-
-		dma_declare_contiguous(NULL, selected_size, 0, limit);
-	}
-};
-
-static DEFINE_MUTEX(cma_mutex);
-
 static __init int cma_activate_area(unsigned long base_pfn, unsigned long count)
 {
 	unsigned long pfn = base_pfn;
@@ -193,55 +202,109 @@
 	return ERR_PTR(ret);
 }
 
-static struct cma_reserved {
-	phys_addr_t start;
-	unsigned long size;
-	struct device *dev;
-} cma_reserved[MAX_CMA_AREAS] __initdata;
-static unsigned cma_reserved_count __initdata;
+/*****************************************************************************/
 
-static int __init cma_init_reserved_areas(void)
+#ifdef CONFIG_OF
+int __init cma_fdt_scan(unsigned long node, const char *uname,
+				int depth, void *data)
 {
-	struct cma_reserved *r = cma_reserved;
-	unsigned i = cma_reserved_count;
+	phys_addr_t base, size;
+	unsigned long len;
+	__be32 *prop;
+	char *name;
 
-	pr_debug("%s()\n", __func__);
+	if (strncmp(uname, "region@", 7) != 0 || depth != 2 ||
+	    !of_get_flat_dt_prop(node, "linux,contiguous-region", NULL))
+		return 0;
 
-	for (; i; --i, ++r) {
-		struct cma *cma;
-		cma = cma_create_area(PFN_DOWN(r->start),
-				      r->size >> PAGE_SHIFT);
-		if (!IS_ERR(cma))
-			dev_set_cma_area(r->dev, cma);
-	}
+	prop = of_get_flat_dt_prop(node, "reg", &len);
+	if (!prop || (len != 2 * sizeof(unsigned long)))
+		return 0;
+
+	base = be32_to_cpu(prop[0]);
+	size = be32_to_cpu(prop[1]);
+
+	name = of_get_flat_dt_prop(node, "label", NULL);
+
+	pr_info("Found %s, memory base %lx, size %ld MiB\n", uname,
+		(unsigned long)base, (unsigned long)size / SZ_1M);
+	dma_contiguous_reserve_area(size, &base, 0, name);
+
 	return 0;
 }
-core_initcall(cma_init_reserved_areas);
+#endif
 
 /**
- * dma_declare_contiguous() - reserve area for contiguous memory handling
- *			      for particular device
- * @dev:   Pointer to device structure.
- * @size:  Size of the reserved memory.
- * @base:  Start address of the reserved memory (optional, 0 for any).
+ * dma_contiguous_reserve() - reserve area for contiguous memory handling
  * @limit: End address of the reserved memory (optional, 0 for any).
  *
- * This function reserves memory for specified device. It should be
- * called by board specific code when early allocator (memblock or bootmem)
- * is still activate.
+ * This function reserves memory from early allocator. It should be
+ * called by arch specific code once the early allocator (memblock or bootmem)
+ * has been activated and all other subsystems have already allocated/reserved
+ * memory. It reserves contiguous areas for global, device independent
+ * allocations and (optionally) all areas defined in device tree structures.
  */
-int __init dma_declare_contiguous(struct device *dev, unsigned long size,
-				  phys_addr_t base, phys_addr_t limit)
+void __init dma_contiguous_reserve(phys_addr_t limit)
 {
-	struct cma_reserved *r = &cma_reserved[cma_reserved_count];
-	unsigned long alignment;
+	phys_addr_t sel_size = 0;
+
+	pr_debug("%s(limit %08lx)\n", __func__, (unsigned long)limit);
+
+	if (size_cmdline != -1) {
+		sel_size = size_cmdline;
+	} else {
+#ifdef CONFIG_CMA_SIZE_SEL_MBYTES
+		sel_size = size_bytes;
+#elif defined(CONFIG_CMA_SIZE_SEL_PERCENTAGE)
+		sel_size = cma_early_percent_memory();
+#elif defined(CONFIG_CMA_SIZE_SEL_MIN)
+		sel_size = min(size_bytes, cma_early_percent_memory());
+#elif defined(CONFIG_CMA_SIZE_SEL_MAX)
+		sel_size = max(size_bytes, cma_early_percent_memory());
+#endif
+	}
+
+	if (sel_size) {
+		phys_addr_t base = 0;
+		pr_debug("%s: reserving %ld MiB for global area\n", __func__,
+			 (unsigned long)sel_size / SZ_1M);
+
+		if (dma_contiguous_reserve_area(sel_size, &base, limit, NULL)
+		    == 0)
+			dma_contiguous_def_base = base;
+	}
+#ifdef CONFIG_OF
+	of_scan_flat_dt(cma_fdt_scan, NULL);
+#endif
+};
+
+/**
+ * dma_contiguous_reserve_area() - reserve custom contiguous area
+ * @size: Size of the reserved area (in bytes),
+ * @base: Pointer to the base address of the reserved area, also used to return
+ * 	  base address of the actually reserved area, optional, use pointer to
+ *	  0 for any
+ * @limit: End address of the reserved memory (optional, 0 for any).
+ *
+ * This function reserves memory from early allocator. It should be
+ * called by arch specific code once the early allocator (memblock or bootmem)
+ * has been activated and all other subsystems have already allocated/reserved
+ * memory. This function allows to create custom reserved areas for specific
+ * devices.
+ */
+int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t *res_base,
+				       phys_addr_t limit, const char *name)
+{
+	phys_addr_t base = *res_base;
+	phys_addr_t alignment;
+	int ret = 0;
 
 	pr_debug("%s(size %lx, base %08lx, limit %08lx)\n", __func__,
 		 (unsigned long)size, (unsigned long)base,
 		 (unsigned long)limit);
 
 	/* Sanity checks */
-	if (cma_reserved_count == ARRAY_SIZE(cma_reserved)) {
+	if (cma_area_count == ARRAY_SIZE(cma_areas)) {
 		pr_err("Not enough slots for CMA reserved regions!\n");
 		return -ENOSPC;
 	}
@@ -250,7 +313,7 @@
 		return -EINVAL;
 
 	/* Sanitise input arguments */
-	alignment = PAGE_SIZE << max(MAX_ORDER, pageblock_order);
+	alignment = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order);
 	base = ALIGN(base, alignment);
 	size = ALIGN(size, alignment);
 	limit &= ~(alignment - 1);
@@ -259,7 +322,7 @@
 	if (base) {
 		if (memblock_is_region_reserved(base, size) ||
 		    memblock_reserve(base, size) < 0) {
-			base = -EBUSY;
+			ret = -EBUSY;
 			goto err;
 		}
 	} else {
@@ -269,11 +332,7 @@
 		 */
 		phys_addr_t addr = __memblock_alloc_base(size, alignment, limit);
 		if (!addr) {
-			base = -ENOMEM;
-			goto err;
-		} else if (addr + size > ~(unsigned long)0) {
-			memblock_free(addr, size);
-			base = -EINVAL;
+			ret = -ENOMEM;
 			goto err;
 		} else {
 			base = addr;
@@ -284,22 +343,112 @@
 	 * Each reserved area must be initialised later, when more kernel
 	 * subsystems (like slab allocator) are available.
 	 */
-	r->start = base;
-	r->size = size;
-	r->dev = dev;
-	cma_reserved_count++;
-	pr_info("CMA: reserved %ld MiB at %08lx\n", size / SZ_1M,
+	cma_areas[cma_area_count].base = base;
+	cma_areas[cma_area_count].size = size;
+	cma_areas[cma_area_count].name = name;
+	cma_area_count++;
+	*res_base = base;
+
+	pr_info("CMA: reserved %ld MiB at %08lx\n", (unsigned long)size / SZ_1M,
 		(unsigned long)base);
 
 	/* Architecture specific contiguous memory fixup. */
 	dma_contiguous_early_fixup(base, size);
 	return 0;
 err:
-	pr_err("CMA: failed to reserve %ld MiB\n", size / SZ_1M);
-	return base;
+	pr_err("CMA: failed to reserve %ld MiB\n", (unsigned long)size / SZ_1M);
+	return ret;
 }
 
 /**
+ * dma_contiguous_add_device() - add device to custom contiguous reserved area
+ * @dev:   Pointer to device structure.
+ * @base: Pointer to the base address of the reserved area returned by
+ *        dma_contiguous_reserve_area() function, also used to return
+ *
+ * This function assigns the given device to the contiguous memory area
+ * reserved earlier by dma_contiguous_reserve_area() function.
+ */
+int __init dma_contiguous_add_device(struct device *dev, phys_addr_t base)
+{
+	if (cma_map_count == ARRAY_SIZE(cma_maps)) {
+		pr_err("Not enough slots for CMA reserved regions!\n");
+		return -ENOSPC;
+	}
+	cma_maps[cma_map_count].dev = dev;
+	cma_maps[cma_map_count].base = base;
+	cma_map_count++;
+	return 0;
+}
+
+#ifdef CONFIG_OF
+static void cma_assign_device_from_dt(struct device *dev)
+{
+	struct device_node *node;
+	struct cma *cma;
+	const char *name;
+	u32 value;
+
+	node = of_parse_phandle(dev->of_node, "linux,contiguous-region", 0);
+	if (!node)
+		return;
+	if (of_property_read_u32(node, "reg", &value) && !value)
+		return;
+
+	if (of_property_read_string(node, "label", &name))
+		return;
+
+	cma = cma_get_area_by_name(name);
+	if (!cma)
+		return;
+
+	dev_set_cma_area(dev, cma);
+	pr_info("Assigned CMA region at %lx to %s device\n", (unsigned long)value, dev_name(dev));
+}
+
+static int cma_device_init_notifier_call(struct notifier_block *nb,
+					 unsigned long event, void *data)
+{
+	struct device *dev = data;
+	if (event == BUS_NOTIFY_ADD_DEVICE && dev->of_node)
+		cma_assign_device_from_dt(dev);
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block cma_dev_init_nb = {
+	.notifier_call = cma_device_init_notifier_call,
+};
+#endif
+
+static int __init cma_init_reserved_areas(void)
+{
+	struct cma *cma;
+	int i;
+
+	for (i = 0; i < cma_area_count; i++) {
+		phys_addr_t base = PFN_DOWN(cma_areas[i].base);
+		unsigned int count = cma_areas[i].size >> PAGE_SHIFT;
+
+		cma = cma_create_area(base, count);
+		if (!IS_ERR(cma))
+			cma_areas[i].cma = cma;
+	}
+
+	dma_contiguous_def_area = cma_get_area(dma_contiguous_def_base);
+
+	for (i = 0; i < cma_map_count; i++) {
+		cma = cma_get_area(cma_maps[i].base);
+		dev_set_cma_area(cma_maps[i].dev, cma);
+	}
+
+#ifdef CONFIG_OF
+	bus_register_notifier(&platform_bus_type, &cma_dev_init_nb);
+#endif
+	return 0;
+}
+core_initcall(cma_init_reserved_areas);
+
+/**
  * dma_alloc_from_contiguous() - allocate pages from contiguous area
  * @dev:   Pointer to device for which the allocation is performed.
  * @count: Requested number of pages.
@@ -315,7 +464,9 @@
 {
 	unsigned long mask, pfn, pageno, start = 0;
 	struct cma *cma = dev_get_cma_area(dev);
+	struct page *page = NULL;
 	int ret;
+	int tries = 0;
 
 	if (!cma || !cma->count)
 		return NULL;
@@ -336,19 +487,21 @@
 	for (;;) {
 		pageno = bitmap_find_next_zero_area(cma->bitmap, cma->count,
 						    start, count, mask);
-		if (pageno >= cma->count) {
-			ret = -ENOMEM;
-			goto error;
-		}
+		if (pageno >= cma->count)
+			break;
 
 		pfn = cma->base_pfn + pageno;
 		ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA);
 		if (ret == 0) {
 			bitmap_set(cma->bitmap, pageno, count);
+			page = pfn_to_page(pfn);
 			break;
 		} else if (ret != -EBUSY) {
-			goto error;
+			break;
 		}
+		tries++;
+		trace_dma_alloc_contiguous_retry(tries);
+
 		pr_debug("%s(): memory range at %p is busy, retrying\n",
 			 __func__, pfn_to_page(pfn));
 		/* try again with a bit different memory target */
@@ -356,12 +509,8 @@
 	}
 
 	mutex_unlock(&cma_mutex);
-
-	pr_debug("%s(): returned %p\n", __func__, pfn_to_page(pfn));
-	return pfn_to_page(pfn);
-error:
-	mutex_unlock(&cma_mutex);
-	return NULL;
+	pr_debug("%s(): returned %p\n", __func__, page);
+	return page;
 }
 
 /**
diff --git a/drivers/base/genlock.c b/drivers/base/genlock.c
index f54d820..8b7259a 100644
--- a/drivers/base/genlock.c
+++ b/drivers/base/genlock.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/drivers/base/sw_sync.c b/drivers/base/sw_sync.c
index 935769c7..14d3f39 100644
--- a/drivers/base/sw_sync.c
+++ b/drivers/base/sw_sync.c
@@ -71,23 +71,6 @@
 	return sw_sync_cmp(pt_a->value, pt_b->value);
 }
 
-static void sw_sync_print_obj(struct seq_file *s,
-			      struct sync_timeline *sync_timeline)
-{
-	struct sw_sync_timeline *obj = (struct sw_sync_timeline *)sync_timeline;
-
-	seq_printf(s, "%d", obj->value);
-}
-
-static void sw_sync_print_pt(struct seq_file *s, struct sync_pt *sync_pt)
-{
-	struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt;
-	struct sw_sync_timeline *obj =
-		(struct sw_sync_timeline *)sync_pt->parent;
-
-	seq_printf(s, "%d / %d", pt->value, obj->value);
-}
-
 static int sw_sync_fill_driver_data(struct sync_pt *sync_pt,
 				    void *data, int size)
 {
@@ -101,14 +84,29 @@
 	return sizeof(pt->value);
 }
 
+static void sw_sync_timeline_value_str(struct sync_timeline *sync_timeline,
+				       char *str, int size)
+{
+	struct sw_sync_timeline *timeline =
+		(struct sw_sync_timeline *)sync_timeline;
+	snprintf(str, size, "%d", timeline->value);
+}
+
+static void sw_sync_pt_value_str(struct sync_pt *sync_pt,
+				       char *str, int size)
+{
+	struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt;
+	snprintf(str, size, "%d", pt->value);
+}
+
 struct sync_timeline_ops sw_sync_timeline_ops = {
 	.driver_name = "sw_sync",
 	.dup = sw_sync_pt_dup,
 	.has_signaled = sw_sync_pt_has_signaled,
 	.compare = sw_sync_pt_compare,
-	.print_obj = sw_sync_print_obj,
-	.print_pt = sw_sync_print_pt,
 	.fill_driver_data = sw_sync_fill_driver_data,
+	.timeline_value_str = sw_sync_timeline_value_str,
+	.pt_value_str = sw_sync_pt_value_str,
 };
 
 
diff --git a/drivers/base/sync.c b/drivers/base/sync.c
index c0690c8..2e35996 100644
--- a/drivers/base/sync.c
+++ b/drivers/base/sync.c
@@ -28,8 +28,13 @@
 
 #include <linux/anon_inodes.h>
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/sync.h>
+
 static void sync_fence_signal_pt(struct sync_pt *pt);
 static int _sync_pt_has_signaled(struct sync_pt *pt);
+static void sync_fence_free(struct kref *kref);
+static void sync_dump(void);
 
 static LIST_HEAD(sync_timeline_list_head);
 static DEFINE_SPINLOCK(sync_timeline_list_lock);
@@ -50,6 +55,7 @@
 	if (obj == NULL)
 		return NULL;
 
+	kref_init(&obj->kref);
 	obj->ops = ops;
 	strlcpy(obj->name, name, sizeof(obj->name));
 
@@ -67,8 +73,10 @@
 }
 EXPORT_SYMBOL(sync_timeline_create);
 
-static void sync_timeline_free(struct sync_timeline *obj)
+static void sync_timeline_free(struct kref *kref)
 {
+	struct sync_timeline *obj =
+		container_of(kref, struct sync_timeline, kref);
 	unsigned long flags;
 
 	if (obj->ops->release_obj)
@@ -83,17 +91,14 @@
 
 void sync_timeline_destroy(struct sync_timeline *obj)
 {
-	unsigned long flags;
-	bool needs_freeing;
-
-	spin_lock_irqsave(&obj->child_list_lock, flags);
 	obj->destroyed = true;
-	needs_freeing = list_empty(&obj->child_list_head);
-	spin_unlock_irqrestore(&obj->child_list_lock, flags);
 
-	if (needs_freeing)
-		sync_timeline_free(obj);
-	else
+	/*
+	 * If this is not the last reference, signal any children
+	 * that their parent is going away.
+	 */
+
+	if (!kref_put(&obj->kref, sync_timeline_free))
 		sync_timeline_signal(obj);
 }
 EXPORT_SYMBOL(sync_timeline_destroy);
@@ -113,7 +118,6 @@
 {
 	struct sync_timeline *obj = pt->parent;
 	unsigned long flags;
-	bool needs_freeing;
 
 	spin_lock_irqsave(&obj->active_list_lock, flags);
 	if (!list_empty(&pt->active_list))
@@ -121,12 +125,10 @@
 	spin_unlock_irqrestore(&obj->active_list_lock, flags);
 
 	spin_lock_irqsave(&obj->child_list_lock, flags);
-	list_del(&pt->child_list);
-	needs_freeing = obj->destroyed && list_empty(&obj->child_list_head);
+	if (!list_empty(&pt->child_list)) {
+		list_del_init(&pt->child_list);
+	}
 	spin_unlock_irqrestore(&obj->child_list_lock, flags);
-
-	if (needs_freeing)
-		sync_timeline_free(obj);
 }
 
 void sync_timeline_signal(struct sync_timeline *obj)
@@ -135,24 +137,30 @@
 	LIST_HEAD(signaled_pts);
 	struct list_head *pos, *n;
 
+	trace_sync_timeline(obj);
+
 	spin_lock_irqsave(&obj->active_list_lock, flags);
 
 	list_for_each_safe(pos, n, &obj->active_list_head) {
 		struct sync_pt *pt =
 			container_of(pos, struct sync_pt, active_list);
 
-		if (_sync_pt_has_signaled(pt))
-			list_move(pos, &signaled_pts);
+		if (_sync_pt_has_signaled(pt)) {
+			list_del_init(pos);
+			list_add(&pt->signaled_list, &signaled_pts);
+			kref_get(&pt->fence->kref);
+		}
 	}
 
 	spin_unlock_irqrestore(&obj->active_list_lock, flags);
 
 	list_for_each_safe(pos, n, &signaled_pts) {
 		struct sync_pt *pt =
-			container_of(pos, struct sync_pt, active_list);
+			container_of(pos, struct sync_pt, signaled_list);
 
 		list_del_init(pos);
 		sync_fence_signal_pt(pt);
+		kref_put(&pt->fence->kref, sync_fence_free);
 	}
 }
 EXPORT_SYMBOL(sync_timeline_signal);
@@ -169,6 +177,7 @@
 		return NULL;
 
 	INIT_LIST_HEAD(&pt->active_list);
+	kref_get(&parent->kref);
 	sync_timeline_add_pt(parent, pt);
 
 	return pt;
@@ -182,6 +191,8 @@
 
 	sync_timeline_remove_pt(pt);
 
+	kref_put(&pt->parent->kref, sync_timeline_free);
+
 	kfree(pt);
 }
 EXPORT_SYMBOL(sync_pt_free);
@@ -218,10 +229,8 @@
 	spin_lock_irqsave(&obj->active_list_lock, flags);
 
 	err = _sync_pt_has_signaled(pt);
-	if (err != 0) {
-		sync_fence_signal_pt(pt);
+	if (err != 0)
 		goto out;
-	}
 
 	list_add_tail(&pt->active_list, &obj->active_list_head);
 
@@ -255,6 +264,7 @@
 	if (fence->file == NULL)
 		goto err;
 
+	kref_init(&fence->kref);
 	strlcpy(fence->name, name, sizeof(fence->name));
 
 	INIT_LIST_HEAD(&fence->pt_list_head);
@@ -290,6 +300,12 @@
 	list_add(&pt->pt_list, &fence->pt_list_head);
 	sync_pt_activate(pt);
 
+	/*
+	 * signal the fence in case pt was activated before
+	 * sync_pt_activate(pt) was called
+	 */
+	sync_fence_signal_pt(pt);
+
 	return fence;
 }
 EXPORT_SYMBOL(sync_fence_create);
@@ -308,12 +324,68 @@
 
 		new_pt->fence = dst;
 		list_add(&new_pt->pt_list, &dst->pt_list_head);
-		sync_pt_activate(new_pt);
 	}
 
 	return 0;
 }
 
+static int sync_fence_merge_pts(struct sync_fence *dst, struct sync_fence *src)
+{
+	struct list_head *src_pos, *dst_pos, *n;
+
+	list_for_each(src_pos, &src->pt_list_head) {
+		struct sync_pt *src_pt =
+			container_of(src_pos, struct sync_pt, pt_list);
+		bool collapsed = false;
+
+		list_for_each_safe(dst_pos, n, &dst->pt_list_head) {
+			struct sync_pt *dst_pt =
+				container_of(dst_pos, struct sync_pt, pt_list);
+			/* collapse two sync_pts on the same timeline
+			 * to a single sync_pt that will signal at
+			 * the later of the two
+			 */
+			if (dst_pt->parent == src_pt->parent) {
+				if (dst_pt->parent->ops->compare(dst_pt, src_pt) == -1) {
+					struct sync_pt *new_pt =
+						sync_pt_dup(src_pt);
+					if (new_pt == NULL)
+						return -ENOMEM;
+
+					new_pt->fence = dst;
+					list_replace(&dst_pt->pt_list,
+						     &new_pt->pt_list);
+					sync_pt_free(dst_pt);
+				}
+				collapsed = true;
+				break;
+			}
+		}
+
+		if (!collapsed) {
+			struct sync_pt *new_pt = sync_pt_dup(src_pt);
+
+			if (new_pt == NULL)
+				return -ENOMEM;
+
+			new_pt->fence = dst;
+			list_add(&new_pt->pt_list, &dst->pt_list_head);
+		}
+	}
+
+	return 0;
+}
+
+static void sync_fence_detach_pts(struct sync_fence *fence)
+{
+	struct list_head *pos, *n;
+
+	list_for_each_safe(pos, n, &fence->pt_list_head) {
+		struct sync_pt *pt = container_of(pos, struct sync_pt, pt_list);
+		sync_timeline_remove_pt(pt);
+	}
+}
+
 static void sync_fence_free_pts(struct sync_fence *fence)
 {
 	struct list_head *pos, *n;
@@ -378,6 +450,7 @@
 				    struct sync_fence *a, struct sync_fence *b)
 {
 	struct sync_fence *fence;
+	struct list_head *pos;
 	int err;
 
 	fence = sync_fence_alloc(name);
@@ -388,11 +461,23 @@
 	if (err < 0)
 		goto err;
 
-	err = sync_fence_copy_pts(fence, b);
+	err = sync_fence_merge_pts(fence, b);
 	if (err < 0)
 		goto err;
 
-	fence->status = sync_fence_get_status(fence);
+	list_for_each(pos, &fence->pt_list_head) {
+		struct sync_pt *pt =
+			container_of(pos, struct sync_pt, pt_list);
+		sync_pt_activate(pt);
+	}
+
+	/*
+	 * signal the fence in case one of it's pts were activated before
+	 * they were activated
+	 */
+	sync_fence_signal_pt(list_first_entry(&fence->pt_list_head,
+					      struct sync_pt,
+					      pt_list));
 
 	return fence;
 err:
@@ -491,44 +576,89 @@
 }
 EXPORT_SYMBOL(sync_fence_cancel_async);
 
+static bool sync_fence_check(struct sync_fence *fence)
+{
+	/*
+	 * Make sure that reads to fence->status are ordered with the
+	 * wait queue event triggering
+	 */
+	smp_rmb();
+	return fence->status != 0;
+}
+
 int sync_fence_wait(struct sync_fence *fence, long timeout)
 {
-	int err;
+	int err = 0;
+	struct sync_pt *pt;
 
-	if (timeout) {
+	trace_sync_wait(fence, 1);
+	list_for_each_entry(pt, &fence->pt_list_head, pt_list)
+		trace_sync_pt(pt);
+
+	if (timeout > 0) {
 		timeout = msecs_to_jiffies(timeout);
 		err = wait_event_interruptible_timeout(fence->wq,
-						       fence->status != 0,
+						       sync_fence_check(fence),
 						       timeout);
-	} else {
-		err = wait_event_interruptible(fence->wq, fence->status != 0);
+	} else if (timeout < 0) {
+		err = wait_event_interruptible(fence->wq,
+					       sync_fence_check(fence));
 	}
+	trace_sync_wait(fence, 0);
 
 	if (err < 0)
 		return err;
 
-	if (fence->status < 0)
+	if (fence->status < 0) {
+		pr_info("fence error %d on [%p]\n", fence->status, fence);
+		sync_dump();
 		return fence->status;
+	}
 
-	if (fence->status == 0)
+	if (fence->status == 0) {
+		if (timeout > 0) {
+			pr_info("fence timeout on [%p] after %dms\n", fence,
+				jiffies_to_msecs(timeout));
+			sync_dump();
+		}
 		return -ETIME;
+	}
 
 	return 0;
 }
 EXPORT_SYMBOL(sync_fence_wait);
 
+static void sync_fence_free(struct kref *kref)
+{
+	struct sync_fence *fence = container_of(kref, struct sync_fence, kref);
+
+	sync_fence_free_pts(fence);
+
+	kfree(fence);
+}
+
 static int sync_fence_release(struct inode *inode, struct file *file)
 {
 	struct sync_fence *fence = file->private_data;
 	unsigned long flags;
 
-	sync_fence_free_pts(fence);
-
+	/*
+	 * We need to remove all ways to access this fence before droping
+	 * our ref.
+	 *
+	 * start with its membership in the global fence list
+	 */
 	spin_lock_irqsave(&sync_fence_list_lock, flags);
 	list_del(&fence->sync_fence_list);
 	spin_unlock_irqrestore(&sync_fence_list_lock, flags);
 
-	kfree(fence);
+	/*
+	 * remove its pts from their parents so that sync_timeline_signal()
+	 * can't reference the fence.
+	 */
+	sync_fence_detach_pts(fence);
+
+	kref_put(&fence->kref, sync_fence_free);
 
 	return 0;
 }
@@ -539,6 +669,12 @@
 
 	poll_wait(file, &fence->wq, wait);
 
+	/*
+	 * Make sure that reads to fence->status are ordered with the
+	 * wait queue event triggering
+	 */
+	smp_rmb();
+
 	if (fence->status == 1)
 		return POLLIN;
 	else if (fence->status < 0)
@@ -549,7 +685,7 @@
 
 static long sync_fence_ioctl_wait(struct sync_fence *fence, unsigned long arg)
 {
-	__u32 value;
+	__s32 value;
 
 	if (copy_from_user(&value, (void __user *)arg, sizeof(value)))
 		return -EFAULT;
@@ -564,8 +700,13 @@
 	struct sync_fence *fence2, *fence3;
 	struct sync_merge_data data;
 
-	if (copy_from_user(&data, (void __user *)arg, sizeof(data)))
-		return -EFAULT;
+	if (fd < 0)
+		return fd;
+
+	if (copy_from_user(&data, (void __user *)arg, sizeof(data))) {
+		err = -EFAULT;
+		goto err_put_fd;
+	}
 
 	fence2 = sync_fence_fdget(data.fd2);
 	if (fence2 == NULL) {
@@ -722,7 +863,17 @@
 		seq_printf(s, "@%ld.%06ld", tv.tv_sec, tv.tv_usec);
 	}
 
-	if (pt->parent->ops->print_pt) {
+	if (pt->parent->ops->timeline_value_str &&
+	    pt->parent->ops->pt_value_str) {
+		char value[64];
+		pt->parent->ops->pt_value_str(pt, value, sizeof(value));
+		seq_printf(s, ": %s", value);
+		if (fence) {
+			pt->parent->ops->timeline_value_str(pt->parent, value,
+						    sizeof(value));
+			seq_printf(s, " / %s", value);
+		}
+	} else if (pt->parent->ops->print_pt) {
 		seq_printf(s, ": ");
 		pt->parent->ops->print_pt(s, pt);
 	}
@@ -737,7 +888,11 @@
 
 	seq_printf(s, "%s %s", obj->name, obj->ops->driver_name);
 
-	if (obj->ops->print_obj) {
+	if (obj->ops->timeline_value_str) {
+		char value[64];
+		obj->ops->timeline_value_str(obj, value, sizeof(value));
+		seq_printf(s, ": %s", value);
+	} else if (obj->ops->print_obj) {
 		seq_printf(s, ": ");
 		obj->ops->print_obj(s, obj);
 	}
@@ -758,7 +913,8 @@
 	struct list_head *pos;
 	unsigned long flags;
 
-	seq_printf(s, "%s: %s\n", fence->name, sync_status_str(fence->status));
+	seq_printf(s, "[%p] %s: %s\n", fence, fence->name,
+		   sync_status_str(fence->status));
 
 	list_for_each(pos, &fence->pt_list_head) {
 		struct sync_pt *pt =
@@ -826,7 +982,34 @@
 	debugfs_create_file("sync", S_IRUGO, NULL, NULL, &sync_debugfs_fops);
 	return 0;
 }
-
 late_initcall(sync_debugfs_init);
 
+#define DUMP_CHUNK 256
+static char sync_dump_buf[64 * 1024];
+void sync_dump(void)
+{
+       struct seq_file s = {
+               .buf = sync_dump_buf,
+               .size = sizeof(sync_dump_buf) - 1,
+       };
+       int i;
+
+       sync_debugfs_show(&s, NULL);
+
+       for (i = 0; i < s.count; i += DUMP_CHUNK) {
+               if ((s.count - i) > DUMP_CHUNK) {
+                       char c = s.buf[i + DUMP_CHUNK];
+                       s.buf[i + DUMP_CHUNK] = 0;
+                       pr_cont("%s", s.buf + i);
+                       s.buf[i + DUMP_CHUNK] = c;
+               } else {
+                       s.buf[s.count] = 0;
+                       pr_cont("%s", s.buf + i);
+               }
+       }
+}
+#else
+static void sync_dump(void)
+{
+}
 #endif
diff --git a/drivers/bif/Kconfig b/drivers/bif/Kconfig
new file mode 100644
index 0000000..502b92b
--- /dev/null
+++ b/drivers/bif/Kconfig
@@ -0,0 +1,12 @@
+#
+# BIF framework and drivers
+#
+menuconfig BIF
+	bool "MIPI-BIF support"
+	select CRC_CCITT
+	select BITREVERSE
+	help
+	  MIPI-BIF (battery interface) is a one-wire serial interface between a
+	  host master device and one or more slave devices which are located in
+	  a battery pack or also on the host.  Enabling this option allows for
+	  BIF consumer drivers to issue transactions via BIF controller drivers.
diff --git a/drivers/bif/Makefile b/drivers/bif/Makefile
new file mode 100644
index 0000000..02528c1
--- /dev/null
+++ b/drivers/bif/Makefile
@@ -0,0 +1,4 @@
+#
+# Makefile for kernel BIF framework.
+#
+obj-$(CONFIG_BIF)			+= bif-core.o
diff --git a/drivers/bif/bif-core.c b/drivers/bif/bif-core.c
new file mode 100644
index 0000000..e11e6ba4
--- /dev/null
+++ b/drivers/bif/bif-core.c
@@ -0,0 +1,2934 @@
+/* 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) "%s: " fmt, __func__
+
+#include <linux/bitrev.h>
+#include <linux/crc-ccitt.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/workqueue.h>
+#include <linux/bif/consumer.h>
+#include <linux/bif/driver.h>
+
+/**
+ * struct bif_ctrl_dev - holds controller device specific information
+ * @list:			Doubly-linked list parameter linking to other
+ *				BIF controllers registered in the system
+ * @desc:			Description structure for this BIF controller
+ * @mutex:			Mutex lock that is used to ensure mutual
+ *				exclusion between transactions performed on the
+ *				BIF bus for this controller
+ * @ctrl_dev:			Device pointer to the BIF controller device
+ * @driver_data:		Private data used by the BIF controller
+ * @selected_sdev:		Slave device that is currently selected on
+ *				the BIF bus of this controller
+ * @bus_change_notifier:	Head of a notifier list containing notifier
+ *				blocks that are notified when the battery
+ *				presence changes
+ * @enter_irq_mode_work:	Work task that is scheduled after a transaction
+ *				completes when there are consumers that are
+ *				actively monitoring BIF slave interrupts
+ * @irq_count:			This is a count of the total number of BIF slave
+ *				interrupts that are currently being monitored
+ *				for the BIF slaves connected to this BIF
+ *				controller
+ * @irq_mode_delay_jiffies:	Number of jiffies to wait before scheduling the
+ *				enter IRQ mode task.  Using a larger value
+ *				helps to improve the performance of BIF
+ *				consumers that perform many BIF transactions.
+ *				Using a smaller value reduces the latency of
+ *				BIF slave interrupts.
+ * @battery_present:		Cached value of the battery presence.  This is
+ *				used to filter out spurious presence update
+ *				calls when the battery presence state has not
+ *				changed.
+ */
+struct bif_ctrl_dev {
+	struct list_head		list;
+	struct bif_ctrl_desc		*desc;
+	struct mutex			mutex;
+	struct device			*ctrl_dev;
+	void				*driver_data;
+	struct bif_slave_dev		*selected_sdev;
+	struct blocking_notifier_head	bus_change_notifier;
+	struct delayed_work		enter_irq_mode_work;
+	int				irq_count;
+	int				irq_mode_delay_jiffies;
+	bool				battery_present;
+};
+
+/**
+ * struct bif_ctrl - handle used by BIF consumers for bus oriented BIF
+ *			operations
+ * @bdev:		Pointer to BIF controller device
+ * @exclusive_lock:	Flag which indicates that the BIF consumer responsible
+ *			for this handle has locked the BIF bus of this
+ *			controller.  BIF transactions from other consumers are
+ *			blocked until the bus is unlocked.
+ */
+struct bif_ctrl {
+	struct bif_ctrl_dev	*bdev;
+	bool			exclusive_lock;
+};
+
+/**
+ * struct bif_slave_dev - holds BIF slave device information
+ * @list:			Doubly-linked list parameter linking to other
+ *				BIF slaves that have been enumerated
+ * @bdev:			Pointer to the BIF controller device that this
+ *				slave is physically connected to
+ * @slave_addr:			8-bit BIF DEV_ADR assigned to this slave
+ * @unique_id:			80-bit BIF unique ID of the slave
+ * @unique_id_bits_known:	Number of bits of the UID that are currently
+ *				known.  This number starts is incremented during
+ *				a UID search and must end at 80 if the slave
+ *				responds to the search properly.
+ * @present:			Boolean value showing if this slave is
+*				physically present in the system at a given
+*				point in time.  The value is set to false if the
+*				battery pack containing the slave is
+*				disconnected.
+ * @l1_data:			BIF DDB L1 data of the slave as read from the
+ *				slave's memory
+ * @function_directory:		Pointer to the BIF DDB L2 function directory
+ *				list as read from the slave's memory
+ * @protocol_function:		Pointer to constant protocol function data as
+ *				well as software state information if the slave
+ *				has a protocol function
+ * @slave_ctrl_function:	Pointer to constant slave control function data
+ *				as well as software state information if the
+ *				slave has a slave control function
+ * @nvm_function:		Pointer to constant non-volatile memory function
+ *				data as well as software state information if
+ *				the slave has a non-volatile memory function
+ *
+ * bif_slave_dev objects are stored indefinitely after enumeration in order to
+ * speed up battery reinsertion.  Only a UID check is needed after inserting a
+ * battery assuming it has been enumerated before.
+ *
+ * unique_id bytes are stored such that unique_id[0] = MSB and
+ * unique_id[BIF_UNIQUE_ID_BYTE_LENGTH - 1] = LSB
+ */
+struct bif_slave_dev {
+	struct list_head			list;
+	struct bif_ctrl_dev			*bdev;
+	u8					slave_addr;
+	u8				unique_id[BIF_UNIQUE_ID_BYTE_LENGTH];
+	int					unique_id_bits_known;
+	bool					present;
+	struct bif_ddb_l1_data			l1_data;
+	struct bif_ddb_l2_data			*function_directory;
+	struct bif_protocol_function		*protocol_function;
+	struct bif_slave_control_function	*slave_ctrl_function;
+	struct bif_nvm_function			*nvm_function;
+};
+
+/**
+ * struct bif_slave - handle used by BIF consumers for slave oriented BIF
+ *			operations
+ * @ctrl:		Consumer BIF controller handle data
+ * @sdev:		Pointer to BIF slave device
+ */
+struct bif_slave {
+	struct bif_ctrl				ctrl;
+	struct bif_slave_dev			*sdev;
+};
+
+/* Number of times to retry a full BIF transaction before returning an error. */
+#define BIF_TRANSACTION_RETRY_COUNT	5
+
+static DEFINE_MUTEX(bif_ctrl_list_mutex);
+static LIST_HEAD(bif_ctrl_list);
+static DEFINE_MUTEX(bif_sdev_list_mutex);
+static LIST_HEAD(bif_sdev_list);
+
+static u8 next_dev_addr = 0x02;
+
+#define DEBUG_PRINT_BUFFER_SIZE 256
+static void fill_string(char *str, size_t str_len, u8 *buf, int buf_len)
+{
+	int pos = 0;
+	int i;
+
+	for (i = 0; i < buf_len; i++) {
+		pos += scnprintf(str + pos, str_len - pos, "0x%02X", buf[i]);
+		if (i < buf_len - 1)
+			pos += scnprintf(str + pos, str_len - pos, ", ");
+	}
+}
+
+static void bif_print_slave_data(struct bif_slave_dev *sdev)
+{
+	char str[DEBUG_PRINT_BUFFER_SIZE];
+	u8 *uid;
+	int i, j;
+	struct bif_object *object;
+
+	if (sdev->unique_id_bits_known != BIF_UNIQUE_ID_BIT_LENGTH)
+		return;
+
+	uid = sdev->unique_id;
+	pr_debug("BIF slave: 0x%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n",
+		uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6],
+		uid[7], uid[8], uid[9]);
+	pr_debug("  present=%d, dev_adr=0x%02X\n", sdev->present,
+		sdev->slave_addr);
+	pr_debug("  revision=0x%02X, level=0x%02X, device class=0x%04X\n",
+		sdev->l1_data.revision, sdev->l1_data.level,
+		sdev->l1_data.device_class);
+	pr_debug("  manufacturer ID=0x%04X, product ID=0x%04X\n",
+		sdev->l1_data.manufacturer_id, sdev->l1_data.product_id);
+	pr_debug("  function directory length=%d\n", sdev->l1_data.length);
+
+	for (i = 0; i < sdev->l1_data.length / 4; i++) {
+		pr_debug("  Function %d: type=0x%02X, version=0x%02X, pointer=0x%04X\n",
+			i, sdev->function_directory[i].function_type,
+			sdev->function_directory[i].function_version,
+			sdev->function_directory[i].function_pointer);
+	}
+
+	if (sdev->nvm_function) {
+		pr_debug("  NVM function: pointer=0x%04X, task=%d, wr_buf_size=%d, nvm_base=0x%04X, nvm_size=%d\n",
+			sdev->nvm_function->nvm_pointer,
+			sdev->nvm_function->slave_control_channel,
+			(sdev->nvm_function->write_buffer_size
+				? sdev->nvm_function->write_buffer_size : 0),
+			sdev->nvm_function->nvm_base_address,
+			sdev->nvm_function->nvm_size);
+		if (sdev->nvm_function->object_count)
+			pr_debug("  NVM objects:\n");
+		i = 0;
+		list_for_each_entry(object, &sdev->nvm_function->object_list,
+					list) {
+			pr_debug("    Object %d - addr=0x%04X, data len=%d, type=0x%02X, version=0x%02X, manufacturer ID=0x%04X, crc=0x%04X\n",
+				i, object->addr, object->length - 8,
+				object->type, object->version,
+				object->manufacturer_id, object->crc);
+			for (j = 0; j < DIV_ROUND_UP(object->length - 8, 16);
+					j++) {
+				fill_string(str, DEBUG_PRINT_BUFFER_SIZE,
+					object->data + j * 16,
+					min(16, object->length - 8 - (j * 16)));
+				pr_debug("      data(0x%04X): %s\n", j * 16,
+					str);
+			}
+			i++;
+		}
+	}
+}
+
+static void bif_print_slaves(void)
+{
+	struct bif_slave_dev *sdev;
+
+	mutex_lock(&bif_sdev_list_mutex);
+
+	list_for_each_entry(sdev, &bif_sdev_list, list) {
+		/* Skip slaves without fully known UIDs. */
+		if (sdev->unique_id_bits_known != BIF_UNIQUE_ID_BIT_LENGTH)
+			continue;
+		bif_print_slave_data(sdev);
+	}
+
+	mutex_unlock(&bif_sdev_list_mutex);
+}
+
+static struct bif_slave_dev *bif_add_slave(struct bif_ctrl_dev *bdev)
+{
+	struct bif_slave_dev *sdev;
+
+	sdev = kzalloc(sizeof(struct bif_slave_dev), GFP_KERNEL);
+	if (sdev == NULL) {
+		pr_err("Memory allocation failed for bif_slave_dev\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	sdev->bdev = bdev;
+	INIT_LIST_HEAD(&sdev->list);
+	list_add_tail(&sdev->list, &bif_sdev_list);
+
+	return sdev;
+}
+
+static void bif_remove_slave(struct bif_slave_dev *sdev)
+{
+	list_del(&sdev->list);
+	if (sdev->bdev->selected_sdev == sdev)
+		sdev->bdev->selected_sdev = NULL;
+
+	if (sdev->slave_ctrl_function)
+		kfree(sdev->slave_ctrl_function->irq_notifier_list);
+	kfree(sdev->slave_ctrl_function);
+	kfree(sdev->protocol_function);
+	kfree(sdev->function_directory);
+
+	kfree(sdev);
+}
+
+/* This function assumes that the uid array is all 0 to start with. */
+static void set_uid_bit(u8 uid[BIF_UNIQUE_ID_BYTE_LENGTH], unsigned int bit,
+			unsigned int value)
+{
+	u8 mask;
+
+	if (bit >= BIF_UNIQUE_ID_BIT_LENGTH)
+		return;
+
+	mask = 1 << (7 - (bit % 8));
+
+	uid[bit / 8] &= ~mask;
+	uid[bit / 8] |= value << (7 - (bit % 8));
+}
+
+static unsigned int get_uid_bit(u8 uid[BIF_UNIQUE_ID_BYTE_LENGTH],
+			unsigned int bit)
+{
+	if (bit >= BIF_UNIQUE_ID_BIT_LENGTH)
+		return 0;
+
+	return (uid[bit / 8] & (1 << (7 - (bit % 8)))) ? 1 : 0;
+}
+
+static void bif_enter_irq_mode_work(struct work_struct *work)
+{
+	struct delayed_work *dwork = to_delayed_work(work);
+	struct bif_ctrl_dev *bdev
+		= container_of(dwork, struct bif_ctrl_dev, enter_irq_mode_work);
+	int rc, i;
+
+	mutex_lock(&bdev->mutex);
+	for (i = 0; i < BIF_TRANSACTION_RETRY_COUNT; i++) {
+		rc = bdev->desc->ops->set_bus_state(bdev,
+					BIF_BUS_STATE_INTERRUPT);
+		if (rc == 0)
+			break;
+	}
+	mutex_unlock(&bdev->mutex);
+
+	/* Reschedule the task if the transaction failed. */
+	if (rc) {
+		pr_err("Could not set BIF bus to interrupt mode, rc=%d\n", rc);
+		schedule_delayed_work(&bdev->enter_irq_mode_work,
+					bdev->irq_mode_delay_jiffies);
+	}
+}
+
+static void bif_cancel_irq_mode_work(struct bif_ctrl_dev *bdev)
+{
+	cancel_delayed_work(&bdev->enter_irq_mode_work);
+}
+
+static void bif_schedule_irq_mode_work(struct bif_ctrl_dev *bdev)
+{
+	if (bdev->irq_count > 0 &&
+	    bdev->desc->ops->get_bus_state(bdev) != BIF_BUS_STATE_INTERRUPT)
+		schedule_delayed_work(&bdev->enter_irq_mode_work,
+					bdev->irq_mode_delay_jiffies);
+}
+
+static int _bif_select_slave_no_retry(struct bif_slave_dev *sdev)
+{
+	struct bif_ctrl_dev *bdev = sdev->bdev;
+	int rc = 0;
+	int i;
+
+	/* Check if the slave is already selected. */
+	if (sdev->bdev->selected_sdev == sdev)
+		return 0;
+
+	if (sdev->slave_addr) {
+		/* Select using DEV_ADR. */
+		rc = bdev->desc->ops->bus_transaction(bdev, BIF_TRANS_SDA,
+							sdev->slave_addr);
+		if (!rc)
+			sdev->bdev->selected_sdev = sdev;
+	} else if (sdev->unique_id_bits_known == BIF_UNIQUE_ID_BIT_LENGTH) {
+		/* Select using full UID. */
+		for (i = 0; i < BIF_UNIQUE_ID_BYTE_LENGTH - 1; i++) {
+			rc = bdev->desc->ops->bus_transaction(bdev,
+				BIF_TRANS_EDA, sdev->unique_id[i]);
+			if (rc)
+				goto out;
+		}
+
+		rc = bdev->desc->ops->bus_transaction(bdev, BIF_TRANS_SDA,
+			sdev->unique_id[BIF_UNIQUE_ID_BYTE_LENGTH - 1]);
+		if (rc)
+			goto out;
+	} else {
+		pr_err("Cannot select slave because it has neither UID nor DEV_ADR.\n");
+		return -EINVAL;
+	}
+
+	sdev->bdev->selected_sdev = sdev;
+
+	return 0;
+out:
+	pr_err("bus_transaction failed, rc=%d\n", rc);
+	return rc;
+}
+
+static int bif_select_slave(struct bif_slave_dev *sdev)
+{
+	int rc = -EPERM;
+	int i;
+
+	for (i = 0; i < BIF_TRANSACTION_RETRY_COUNT; i++) {
+		rc = _bif_select_slave_no_retry(sdev);
+		if (rc == 0)
+			break;
+		/* Force slave reselection. */
+		sdev->bdev->selected_sdev = NULL;
+	}
+
+	return rc;
+}
+
+/*
+ * Returns 1 if slave is selected, 0 if slave is not selected, or errno if
+ * error.
+ */
+static int bif_is_slave_selected(struct bif_ctrl_dev *bdev)
+{
+	int rc = -EPERM;
+	int tack, i;
+
+	for (i = 0; i < BIF_TRANSACTION_RETRY_COUNT; i++) {
+		/* Attempt a transaction query. */
+		rc = bdev->desc->ops->bus_transaction_read(bdev, BIF_TRANS_BC,
+						BIF_CMD_TQ, &tack);
+		if (rc == 0 || rc == -ETIMEDOUT)
+			break;
+	}
+
+	if (rc == 0)
+		rc = 1;
+	else if (rc == -ETIMEDOUT)
+		rc = 0;
+	else
+		pr_err("BIF bus_transaction_read failed, rc=%d\n", rc);
+
+	return rc;
+}
+
+/* Read from a specified number of consecutive registers. */
+static int _bif_slave_read_no_retry(struct bif_slave_dev *sdev, u16 addr,
+			u8 *buf, int len)
+{
+	struct bif_ctrl_dev *bdev = sdev->bdev;
+	int rc = 0;
+	int i, response;
+
+	rc = bif_select_slave(sdev);
+	if (rc)
+		return rc;
+
+	if (bdev->desc->ops->read_slave_registers) {
+		/*
+		 * Use low level slave register read implementation in order to
+		 * receive the benefits of BIF burst reads.
+		 */
+		rc = bdev->desc->ops->read_slave_registers(bdev, addr, buf,
+							   len);
+		if (rc)
+			pr_err("read_slave_registers failed, rc=%d\n", rc);
+		return rc;
+	}
+
+	for (i = 0; i < len; i++) {
+		rc = bdev->desc->ops->bus_transaction(bdev, BIF_TRANS_ERA,
+							addr >> 8);
+		if (rc) {
+			pr_err("bus_transaction failed, rc=%d\n", rc);
+			return rc;
+		}
+
+		rc = bdev->desc->ops->bus_transaction_read(bdev, BIF_TRANS_RRA,
+							addr & 0xFF, &response);
+		if (rc) {
+			pr_err("bus_transaction_read failed, rc=%d\n", rc);
+			return rc;
+		}
+
+		if (!(response & BIF_SLAVE_RD_ACK)) {
+			pr_err("BIF register read error=0x%02X\n",
+				response & BIF_SLAVE_RD_ERR);
+			return -EIO;
+		}
+
+		buf[i] = response & BIF_SLAVE_RD_DATA;
+		addr++;
+	}
+
+	return rc;
+}
+
+/*
+ * Read from a specified number of consecutive registers.  Retry the transaction
+ * several times in case of communcation failures.
+ */
+static int _bif_slave_read(struct bif_slave_dev *sdev, u16 addr, u8 *buf,
+			int len)
+{
+	int rc = -EPERM;
+	int i;
+
+	for (i = 0; i < BIF_TRANSACTION_RETRY_COUNT; i++) {
+		rc = _bif_slave_read_no_retry(sdev, addr, buf, len);
+		if (rc == 0)
+			break;
+		/* Force slave reselection. */
+		sdev->bdev->selected_sdev = NULL;
+	}
+
+	return rc;
+}
+
+/* Write to a specified number of consecutive registers. */
+static int _bif_slave_write_no_retry(struct bif_slave_dev *sdev, u16 addr,
+			u8 *buf, int len)
+{
+	struct bif_ctrl_dev *bdev = sdev->bdev;
+	int rc = 0;
+	int i;
+
+	rc = bif_select_slave(sdev);
+	if (rc)
+		return rc;
+
+	if (bdev->desc->ops->write_slave_registers) {
+		/*
+		 * Use low level slave register write implementation in order to
+		 * receive the benefits of BIF burst writes.
+		 */
+		rc = bdev->desc->ops->write_slave_registers(bdev, addr, buf,
+							    len);
+		if (rc)
+			pr_err("write_slave_registers failed, rc=%d\n", rc);
+		return rc;
+	}
+
+	rc = bdev->desc->ops->bus_transaction(bdev, BIF_TRANS_ERA, addr >> 8);
+	if (rc)
+		goto out;
+
+	rc = bdev->desc->ops->bus_transaction(bdev, BIF_TRANS_WRA, addr & 0xFF);
+	if (rc)
+		goto out;
+
+	for (i = 0; i < len; i++) {
+		rc = bdev->desc->ops->bus_transaction(bdev, BIF_TRANS_WD,
+							buf[i]);
+		if (rc)
+			goto out;
+	}
+
+	return 0;
+out:
+	pr_err("bus_transaction failed, rc=%d\n", rc);
+	return rc;
+}
+
+/*
+ * Write to a specified number of consecutive registers.  Retry the transaction
+ * several times in case of communcation failures.
+ */
+static int _bif_slave_write(struct bif_slave_dev *sdev, u16 addr, u8 *buf,
+			int len)
+{
+	int rc = -EPERM;
+	int i;
+
+	for (i = 0; i < BIF_TRANSACTION_RETRY_COUNT; i++) {
+		rc = _bif_slave_write_no_retry(sdev, addr, buf, len);
+		if (rc == 0)
+			break;
+		/* Force slave reselection. */
+		sdev->bdev->selected_sdev = NULL;
+	}
+
+	return rc;
+}
+
+/* Takes a mutex if this consumer is not an exclusive bus user. */
+static void bif_ctrl_lock(struct bif_ctrl *ctrl)
+{
+	if (!ctrl->exclusive_lock) {
+		mutex_lock(&ctrl->bdev->mutex);
+		bif_cancel_irq_mode_work(ctrl->bdev);
+	}
+}
+
+/* Releases a mutex if this consumer is not an exclusive bus user. */
+static void bif_ctrl_unlock(struct bif_ctrl *ctrl)
+{
+	if (!ctrl->exclusive_lock) {
+		bif_schedule_irq_mode_work(ctrl->bdev);
+		mutex_unlock(&ctrl->bdev->mutex);
+	}
+}
+
+static void bif_slave_ctrl_lock(struct bif_slave *slave)
+{
+	bif_ctrl_lock(&slave->ctrl);
+}
+
+static void bif_slave_ctrl_unlock(struct bif_slave *slave)
+{
+	bif_ctrl_unlock(&slave->ctrl);
+}
+
+static int bif_check_task(struct bif_slave *slave, unsigned int task)
+{
+	if (IS_ERR_OR_NULL(slave)) {
+		pr_err("Invalid slave handle.\n");
+		return -EINVAL;
+	} else if (!slave->sdev->bdev) {
+		pr_err("BIF controller has been removed.\n");
+		return -ENXIO;
+	} else if (!slave->sdev->slave_ctrl_function
+			|| slave->sdev->slave_ctrl_function->task_count == 0) {
+		pr_err("BIF slave does not support slave control.\n");
+		return -ENODEV;
+	} else if (task >= slave->sdev->slave_ctrl_function->task_count) {
+		pr_err("Requested task: %u greater than max: %u for this slave\n",
+			task, slave->sdev->slave_ctrl_function->task_count);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * bif_request_irq() - request a BIF slave IRQ by slave task number
+ * @slave:	BIF slave handle
+ * @task:	BIF task number of the IRQ inside of the slave.  This
+ *		corresponds to the slave control channel specified for a given
+ *		BIF function inside of the slave.
+ * @nb:		Notifier block to call when the IRQ fires
+ *
+ * This function registers a notifier block to call when the BIF slave interrupt
+ * is triggered and also enables the interrupt.  The interrupt is enabled inside
+ * of the BIF slave's slave control function and also the BIF bus is put into
+ * interrupt mode.
+ *
+ * Returns 0 for success or errno if an error occurred.
+ */
+int bif_request_irq(struct bif_slave *slave, unsigned int task,
+			struct notifier_block *nb)
+{
+	int rc;
+	u16 addr;
+	u8 reg, mask;
+
+	rc = bif_check_task(slave, task);
+	if (rc) {
+		pr_err("Invalid slave or task, rc=%d\n", rc);
+		return rc;
+	}
+
+	bif_slave_ctrl_lock(slave);
+
+	rc = blocking_notifier_chain_register(
+		&slave->sdev->slave_ctrl_function->irq_notifier_list[task], nb);
+	if (rc) {
+		pr_err("Notifier registration failed, rc=%d\n", rc);
+		goto done;
+	}
+
+	/* Enable the interrupt within the slave */
+	mask = BIT(task % SLAVE_CTRL_TASKS_PER_SET);
+	addr = SLAVE_CTRL_FUNC_IRQ_EN_ADDR(
+		slave->sdev->slave_ctrl_function->slave_ctrl_pointer, task);
+	if (task / SLAVE_CTRL_TASKS_PER_SET == 0) {
+		/* Set global interrupt enable. */
+		mask |= BIT(0);
+	}
+	rc = _bif_slave_read(slave->sdev, addr, &reg, 1);
+	if (rc) {
+		pr_err("BIF slave register read failed, rc=%d\n", rc);
+		goto notifier_unregister;
+	}
+	reg |= mask;
+	rc = _bif_slave_write(slave->sdev, addr, &reg, 1);
+	if (rc) {
+		pr_err("BIF slave register write failed, rc=%d\n", rc);
+		goto notifier_unregister;
+	}
+
+	/* Set global interrupt enable if task not in set 0. */
+	if (task / SLAVE_CTRL_TASKS_PER_SET != 0) {
+		mask = BIT(0);
+		addr = SLAVE_CTRL_FUNC_IRQ_EN_ADDR(
+		       slave->sdev->slave_ctrl_function->slave_ctrl_pointer, 0);
+		rc = _bif_slave_read(slave->sdev, addr, &reg, 1);
+		if (rc) {
+			pr_err("BIF slave register read failed, rc=%d\n", rc);
+			goto notifier_unregister;
+		}
+		reg |= mask;
+		rc = _bif_slave_write(slave->sdev, addr, &reg, 1);
+		if (rc) {
+			pr_err("BIF slave register write failed, rc=%d\n", rc);
+			goto notifier_unregister;
+		}
+	}
+
+	rc = slave->sdev->bdev->desc->ops->set_bus_state(slave->sdev->bdev,
+		BIF_BUS_STATE_INTERRUPT);
+	if (rc) {
+		pr_err("Could not set BIF bus to interrupt mode, rc=%d\n", rc);
+		goto notifier_unregister;
+	}
+
+	slave->sdev->bdev->irq_count++;
+done:
+	bif_slave_ctrl_unlock(slave);
+
+	return rc;
+
+notifier_unregister:
+	blocking_notifier_chain_unregister(
+		&slave->sdev->slave_ctrl_function->irq_notifier_list[task],
+		nb);
+	bif_slave_ctrl_unlock(slave);
+
+	return rc;
+
+}
+EXPORT_SYMBOL(bif_request_irq);
+
+/**
+ * bif_free_irq() - free a BIF slave IRQ by slave task number
+ * @slave:	BIF slave handle
+ * @task:	BIF task number of the IRQ inside of the slave.  This
+ *		corresponds to the slave control channel specified for a given
+ *		BIF function inside of the slave.
+ * @nb:		Notifier block previously registered with this interrupt
+ *
+ * This function unregisters a notifier block that was previously registered
+ * with bif_request_irq().
+ *
+ * Returns 0 for success or errno if an error occurred.
+ */
+int bif_free_irq(struct bif_slave *slave, unsigned int task,
+			struct notifier_block *nb)
+{
+	int rc;
+	u16 addr;
+	u8 reg;
+
+	rc = bif_check_task(slave, task);
+	if (rc) {
+		pr_err("Invalid slave or task, rc=%d\n", rc);
+		return rc;
+	}
+
+	bif_slave_ctrl_lock(slave);
+
+	/* Disable the interrupt within the slave */
+	reg = BIT(task % SLAVE_CTRL_TASKS_PER_SET);
+	addr = SLAVE_CTRL_FUNC_IRQ_CLEAR_ADDR(
+		slave->sdev->slave_ctrl_function->slave_ctrl_pointer, task);
+	rc = _bif_slave_write(slave->sdev, addr, &reg, 1);
+	if (rc) {
+		pr_err("BIF slave register write failed, rc=%d\n", rc);
+		goto done;
+	}
+
+	rc = blocking_notifier_chain_unregister(
+		&slave->sdev->slave_ctrl_function->irq_notifier_list[task], nb);
+	if (rc) {
+		pr_err("Notifier unregistration failed, rc=%d\n", rc);
+		goto done;
+	}
+
+	slave->sdev->bdev->irq_count--;
+
+	if (slave->sdev->bdev->irq_count == 0) {
+		bif_cancel_irq_mode_work(slave->sdev->bdev);
+	} else if (slave->sdev->bdev->irq_count < 0) {
+		pr_err("Unbalanced IRQ free.\n");
+		rc = -EINVAL;
+		slave->sdev->bdev->irq_count = 0;
+	}
+done:
+	bif_slave_ctrl_unlock(slave);
+
+	return rc;
+}
+EXPORT_SYMBOL(bif_free_irq);
+
+/**
+ * bif_trigger_task() - trigger a task within a BIF slave
+ * @slave:	BIF slave handle
+ * @task:	BIF task inside of the slave to trigger.  This corresponds to
+ *		the slave control channel specified for a given BIF function
+ *		inside of the slave.
+ *
+ * Returns 0 for success or errno if an error occurred.
+ */
+int bif_trigger_task(struct bif_slave *slave, unsigned int task)
+{
+	int rc;
+	u16 addr;
+	u8 reg;
+
+	rc = bif_check_task(slave, task);
+	if (rc) {
+		pr_err("Invalid slave or task, rc=%d\n", rc);
+		return rc;
+	}
+
+	bif_slave_ctrl_lock(slave);
+
+	/* Trigger the task within the slave. */
+	reg = BIT(task % SLAVE_CTRL_TASKS_PER_SET);
+	addr = SLAVE_CTRL_FUNC_TASK_TRIGGER_ADDR(
+		slave->sdev->slave_ctrl_function->slave_ctrl_pointer, task);
+	rc = _bif_slave_write(slave->sdev, addr, &reg, 1);
+	if (rc) {
+		pr_err("BIF slave register write failed, rc=%d\n", rc);
+		goto done;
+	}
+
+done:
+	bif_slave_ctrl_unlock(slave);
+
+	return rc;
+}
+EXPORT_SYMBOL(bif_trigger_task);
+
+/**
+ * bif_task_is_busy() - checks the state of a BIF slave task
+ * @slave:	BIF slave handle
+ * @task:	BIF task inside of the slave to trigger.  This corresponds to
+ *		the slave control channel specified for a given	BIF function
+ *		inside of the slave.
+ *
+ * Returns 1 if the task is busy, 0 if it is not busy, and errno on error.
+ */
+int bif_task_is_busy(struct bif_slave *slave, unsigned int task)
+{
+	int rc;
+	u16 addr;
+	u8 reg;
+
+	rc = bif_check_task(slave, task);
+	if (rc) {
+		pr_err("Invalid slave or task, rc=%d\n", rc);
+		return rc;
+	}
+
+	bif_slave_ctrl_lock(slave);
+
+	/* Check the task busy state. */
+	addr = SLAVE_CTRL_FUNC_TASK_BUSY_ADDR(
+		slave->sdev->slave_ctrl_function->slave_ctrl_pointer, task);
+	rc = _bif_slave_read(slave->sdev, addr, &reg, 1);
+	if (rc) {
+		pr_err("BIF slave register read failed, rc=%d\n", rc);
+		goto done;
+	}
+
+	rc = (reg & BIT(task % SLAVE_CTRL_TASKS_PER_SET)) ? 1 : 0;
+done:
+	bif_slave_ctrl_unlock(slave);
+
+	return rc;
+}
+EXPORT_SYMBOL(bif_task_is_busy);
+
+static int bif_slave_notify_irqs(struct bif_slave_dev *sdev, int set, u8 val)
+{
+	int rc = 0;
+	int i, task;
+
+	for (i = 0; i < SLAVE_CTRL_TASKS_PER_SET; i++) {
+		if (val & (1 << i)) {
+			task = set * SLAVE_CTRL_TASKS_PER_SET + i;
+
+			rc = blocking_notifier_call_chain(
+			    &sdev->slave_ctrl_function->irq_notifier_list[task],
+			    task, sdev->bdev);
+			rc = notifier_to_errno(rc);
+			if (rc)
+				pr_err("Notification failed for task %d\n",
+					task);
+		}
+	}
+
+	return rc;
+}
+
+static int bif_slave_handle_irq(struct bif_slave_dev *sdev)
+{
+	struct bif_ctrl_dev *bdev = sdev->bdev;
+	bool resp = false;
+	int rc = 0;
+	int i;
+	u16 addr;
+	u8 reg;
+
+	mutex_lock(&sdev->bdev->mutex);
+	bif_cancel_irq_mode_work(sdev->bdev);
+
+	rc = bif_select_slave(sdev);
+	if (rc) {
+		pr_err("Could not select slave, rc=%d\n", rc);
+		goto done;
+	}
+
+	/* Check overall slave interrupt status. */
+	rc = bdev->desc->ops->bus_transaction_query(bdev, BIF_TRANS_BC,
+						    BIF_CMD_ISTS, &resp);
+	if (rc) {
+		pr_err("Could not query slave interrupt status, rc=%d\n", rc);
+		goto done;
+	}
+
+	if (resp) {
+		for (i = 0; i < sdev->slave_ctrl_function->task_count
+					/ SLAVE_CTRL_TASKS_PER_SET; i++) {
+			addr = sdev->slave_ctrl_function->slave_ctrl_pointer
+				+ 4 * i + 1;
+			rc = _bif_slave_read(sdev, addr, &reg, 1);
+			if (rc) {
+				pr_err("BIF slave register read failed, rc=%d\n",
+					rc);
+				goto done;
+			}
+
+			/* Ensure that interrupts are pending in the set. */
+			if (reg != 0x00) {
+				/*
+				 * Release mutex before notifying consumers so
+				 * that they can use the bus.
+				 */
+				mutex_unlock(&sdev->bdev->mutex);
+				rc = bif_slave_notify_irqs(sdev, i, reg);
+				if (rc) {
+					pr_err("BIF slave irq notification failed, rc=%d\n",
+						rc);
+					goto notification_failed;
+				}
+				mutex_lock(&sdev->bdev->mutex);
+
+				rc = bif_select_slave(sdev);
+				if (rc) {
+					pr_err("Could not select slave, rc=%d\n",
+						rc);
+					goto done;
+				}
+
+				/* Clear all interrupts in this set. */
+				rc = _bif_slave_write(sdev, addr, &reg, 1);
+				if (rc) {
+					pr_err("BIF slave register write failed, rc=%d\n",
+						rc);
+					goto done;
+				}
+			}
+		}
+	}
+
+done:
+	bif_schedule_irq_mode_work(sdev->bdev);
+	mutex_unlock(&sdev->bdev->mutex);
+notification_failed:
+	if (rc == 0)
+		rc = resp;
+	return rc;
+}
+
+/**
+ * bif_ctrl_notify_slave_irq() - notify the BIF framework that a slave interrupt
+ *				was received by a BIF controller
+ * @bdev:	BIF controller device pointer
+ *
+ * This function should only be called from a BIF controller driver.
+ *
+ * Returns 0 for success or errno if an error occurred.
+ */
+int bif_ctrl_notify_slave_irq(struct bif_ctrl_dev *bdev)
+{
+	struct bif_slave_dev *sdev;
+	int rc = 0, handled = 0;
+
+	if (IS_ERR_OR_NULL(bdev))
+		return -EINVAL;
+
+	mutex_lock(&bif_sdev_list_mutex);
+
+	list_for_each_entry(sdev, &bif_sdev_list, list) {
+		if (sdev->bdev == bdev && sdev->present) {
+			rc = bif_slave_handle_irq(sdev);
+			if (rc < 0) {
+				pr_err("Could not handle BIF slave irq, rc=%d\n",
+					rc);
+				break;
+			}
+			handled += rc;
+		}
+	}
+
+	mutex_unlock(&bif_sdev_list_mutex);
+
+	if (handled == 0)
+		pr_info("Spurious BIF slave interrupt detected.\n");
+
+	if (rc > 0)
+		rc = 0;
+
+	return rc;
+}
+EXPORT_SYMBOL(bif_ctrl_notify_slave_irq);
+
+/**
+ * bif_ctrl_notify_battery_changed() - notify the BIF framework that a battery
+ *				pack has been inserted or removed
+ * @bdev:	BIF controller device pointer
+ *
+ * This function should only be called from a BIF controller driver.
+ *
+ * Returns 0 for success or errno if an error occurred.
+ */
+int bif_ctrl_notify_battery_changed(struct bif_ctrl_dev *bdev)
+{
+	int rc = 0;
+	int present;
+
+	if (IS_ERR_OR_NULL(bdev))
+		return -EINVAL;
+
+	if (bdev->desc->ops->get_battery_presence) {
+		present = bdev->desc->ops->get_battery_presence(bdev);
+		if (present < 0) {
+			pr_err("Could not determine battery presence, rc=%d\n",
+				rc);
+			return rc;
+		}
+
+		if (bdev->battery_present == !!present)
+			return 0;
+
+		bdev->battery_present = present;
+
+		rc = blocking_notifier_call_chain(&bdev->bus_change_notifier,
+			present ? BIF_BUS_EVENT_BATTERY_INSERTED
+				: BIF_BUS_EVENT_BATTERY_REMOVED, bdev);
+		if (rc)
+			pr_err("Call chain noification failed, rc=%d\n", rc);
+	}
+
+	return rc;
+}
+EXPORT_SYMBOL(bif_ctrl_notify_battery_changed);
+
+/**
+ * bif_ctrl_signal_battery_changed() - notify the BIF framework that a battery
+ *				pack has been inserted or removed
+ * @ctrl:	BIF controller consumer handle
+ *
+ * This function should only be called by a BIF consumer driver on systems where
+ * the BIF controller driver is unable to determine when a battery is inserted
+ * or removed.
+ *
+ * Returns 0 for success or errno if an error occurred.
+ */
+int bif_ctrl_signal_battery_changed(struct bif_ctrl *ctrl)
+{
+	if (IS_ERR_OR_NULL(ctrl))
+		return -EINVAL;
+
+	return bif_ctrl_notify_battery_changed(ctrl->bdev);
+}
+EXPORT_SYMBOL(bif_ctrl_signal_battery_changed);
+
+/**
+ * bif_ctrl_notifier_register() - register a notifier block to be called when
+ *				a battery pack is inserted or removed
+ * @ctrl:	BIF controller consumer handle
+ *
+ * The value passed into the notifier when it is called is one of
+ * enum bif_bus_event.
+ *
+ * Returns 0 for success or errno if an error occurred.
+ */
+int bif_ctrl_notifier_register(struct bif_ctrl *ctrl, struct notifier_block *nb)
+{
+	int rc;
+
+	if (IS_ERR_OR_NULL(ctrl))
+		return -EINVAL;
+
+	rc = blocking_notifier_chain_register(&ctrl->bdev->bus_change_notifier,
+					      nb);
+	if (rc)
+		pr_err("Notifier registration failed, rc=%d\n", rc);
+
+	return rc;
+}
+EXPORT_SYMBOL(bif_ctrl_notifier_register);
+
+/**
+ * bif_ctrl_notifier_unregister() - unregister a battery status change notifier
+ *				block that was previously registered
+ * @ctrl:	BIF controller consumer handle
+ *
+ * Returns 0 for success or errno if an error occurred.
+ */
+int bif_ctrl_notifier_unregister(struct bif_ctrl *ctrl,
+				 struct notifier_block *nb)
+{
+	int rc;
+
+	if (IS_ERR_OR_NULL(ctrl))
+		return -EINVAL;
+
+	rc =
+	    blocking_notifier_chain_unregister(&ctrl->bdev->bus_change_notifier,
+						nb);
+	if (rc)
+		pr_err("Notifier unregistration failed, rc=%d\n", rc);
+
+	return rc;
+}
+EXPORT_SYMBOL(bif_ctrl_notifier_unregister);
+
+/**
+ * bif_get_bus_handle() - returns the BIF controller consumer handle associated
+ *			with a BIF slave handle
+ * @slave:	BIF slave handle
+ *
+ * Note, bif_ctrl_put() should never be called for the pointer output by
+ * bif_get_bus_handle().
+ */
+struct bif_ctrl *bif_get_bus_handle(struct bif_slave *slave)
+{
+	if (IS_ERR_OR_NULL(slave))
+		return ERR_PTR(-EINVAL);
+
+	return &slave->ctrl;
+}
+EXPORT_SYMBOL(bif_get_bus_handle);
+
+/**
+ * bif_ctrl_count() - returns the number of registered BIF controllers
+ */
+int bif_ctrl_count(void)
+{
+	struct bif_ctrl_dev *bdev;
+	int count = 0;
+
+	mutex_lock(&bif_ctrl_list_mutex);
+
+	list_for_each_entry(bdev, &bif_ctrl_list, list) {
+		count++;
+	}
+	mutex_unlock(&bif_ctrl_list_mutex);
+
+	return count;
+}
+EXPORT_SYMBOL(bif_ctrl_count);
+
+/**
+ * bif_ctrl_get_by_id() - get a handle for the id'th BIF controller registered
+ *			in the system
+ * @id:	Arbitrary number associated with the BIF bus in the system
+ *
+ * id must be in the range [0, bif_ctrl_count() - 1].  This function should only
+ * need to be called by a BIF consumer that is unable to link to a given BIF
+ * controller via a device tree binding.
+ *
+ * Returns a BIF controller consumer handle if successful or an ERR_PTR if not.
+ */
+struct bif_ctrl *bif_ctrl_get_by_id(unsigned int id)
+{
+	struct bif_ctrl_dev *bdev;
+	struct bif_ctrl_dev *bdev_found = NULL;
+	struct bif_ctrl *ctrl = ERR_PTR(-ENODEV);
+
+	mutex_lock(&bif_ctrl_list_mutex);
+
+	list_for_each_entry(bdev, &bif_ctrl_list, list) {
+		if (id == 0) {
+			bdev_found = bdev;
+			break;
+		}
+		id--;
+	}
+	mutex_unlock(&bif_ctrl_list_mutex);
+
+	if (bdev_found) {
+		ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
+		if (!ctrl) {
+			pr_err("Bus handle allocation failed\n");
+			ctrl = ERR_PTR(-ENOMEM);
+		} else {
+			ctrl->bdev = bdev_found;
+		}
+	}
+
+	return ctrl;
+}
+EXPORT_SYMBOL(bif_ctrl_get_by_id);
+
+/**
+ * bif_ctrl_get() - get a handle for the BIF controller that is linked to the
+ *			consumer device in the device tree
+ * @consumer_dev:	Pointer to the consumer's device
+ *
+ * In order to use this function, the BIF consumer's device must specify the
+ * "qcom,bif-ctrl" property in its device tree node which points to a BIF
+ * controller device node.
+ *
+ * Returns a BIF controller consumer handle if successful or an ERR_PTR if not.
+ * If the BIF controller linked to the consumer device has not yet probed, then
+ * ERR_PTR(-EPROBE_DEFER) is returned.
+ */
+struct bif_ctrl *bif_ctrl_get(struct device *consumer_dev)
+{
+	struct device_node *ctrl_node = NULL;
+	struct bif_ctrl_dev *bdev_found = NULL;
+	struct bif_ctrl *ctrl = ERR_PTR(-EPROBE_DEFER);
+	struct bif_ctrl_dev *bdev = NULL;
+
+	if (!consumer_dev || !consumer_dev->of_node) {
+		pr_err("Invalid device node\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	ctrl_node = of_parse_phandle(consumer_dev->of_node, "qcom,bif-ctrl", 0);
+	if (!ctrl_node) {
+		pr_err("Could not find qcom,bif-ctrl property in %s\n",
+			consumer_dev->of_node->full_name);
+		return ERR_PTR(-ENXIO);
+	}
+
+	mutex_lock(&bif_ctrl_list_mutex);
+	list_for_each_entry(bdev, &bif_ctrl_list, list) {
+		if (bdev->ctrl_dev && bdev->ctrl_dev->of_node == ctrl_node) {
+			bdev_found = bdev;
+			break;
+		}
+	}
+	mutex_unlock(&bif_ctrl_list_mutex);
+
+	if (bdev_found) {
+		ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
+		if (!ctrl) {
+			pr_err("Bus handle allocation failed\n");
+			ctrl = ERR_PTR(-ENOMEM);
+		} else {
+			ctrl->bdev = bdev_found;
+		}
+	}
+
+	return ctrl;
+}
+EXPORT_SYMBOL(bif_ctrl_get);
+
+/**
+ * bif_ctrl_put() - frees a BIF controller handle
+ * @ctrl:	BIF controller consumer handle
+ */
+void bif_ctrl_put(struct bif_ctrl *ctrl)
+{
+	if (!IS_ERR_OR_NULL(ctrl) && ctrl->exclusive_lock)
+		mutex_unlock(&ctrl->bdev->mutex);
+	kfree(ctrl);
+}
+EXPORT_SYMBOL(bif_ctrl_put);
+
+/*
+ * Returns true if all parameters are matched, otherwise false.
+ * function_type and function_version mean that their exists some function in
+ * the slave which has the specified type and subtype.  ctrl == NULL is treated
+ * as a wildcard.
+ */
+static bool bif_slave_match(const struct bif_ctrl *ctrl,
+	struct bif_slave_dev *sdev, const struct bif_match_criteria *criteria)
+{
+	int i, type, version;
+
+	if (ctrl && (ctrl->bdev != sdev->bdev))
+		return false;
+
+	if (!sdev->present
+	    && (!(criteria->match_mask & BIF_MATCH_IGNORE_PRESENCE)
+		|| ((criteria->match_mask & BIF_MATCH_IGNORE_PRESENCE)
+		    && !criteria->ignore_presence)))
+		return false;
+
+	if ((criteria->match_mask & BIF_MATCH_MANUFACTURER_ID)
+	    && sdev->l1_data.manufacturer_id != criteria->manufacturer_id)
+		return false;
+
+	if ((criteria->match_mask & BIF_MATCH_PRODUCT_ID)
+	    && sdev->l1_data.product_id != criteria->product_id)
+		return false;
+
+	if (criteria->match_mask & BIF_MATCH_FUNCTION_TYPE) {
+		if (!sdev->function_directory)
+			return false;
+		for (i = 0; i < sdev->l1_data.length / 4; i++) {
+			type = sdev->function_directory[i].function_type;
+			version = sdev->function_directory[i].function_version;
+			if (type == criteria->function_type &&
+				(version == criteria->function_version
+					|| !(criteria->match_mask
+						& BIF_MATCH_FUNCTION_VERSION)))
+				return true;
+		}
+		return false;
+	}
+
+	return true;
+}
+
+/**
+ * bif_slave_match_count() - returns the number of slaves associated with the
+ *			specified BIF controller which fit the matching
+ *			criteria
+ * @ctrl:		BIF controller consumer handle
+ * @match_criteria:	Matching criteria used to filter slaves
+ */
+int bif_slave_match_count(const struct bif_ctrl *ctrl,
+			const struct bif_match_criteria *match_criteria)
+{
+	struct bif_slave_dev *sdev;
+	int count = 0;
+
+	mutex_lock(&bif_sdev_list_mutex);
+
+	list_for_each_entry(sdev, &bif_sdev_list, list) {
+		if (bif_slave_match(ctrl, sdev, match_criteria))
+			count++;
+	}
+
+	mutex_unlock(&bif_sdev_list_mutex);
+
+	return count;
+}
+EXPORT_SYMBOL(bif_slave_match_count);
+
+/**
+ * bif_slave_match_get() - get a slave handle for the id'th slave associated
+ *			with the specified BIF controller which fits the
+ *			matching criteria
+ * @ctrl:		BIF controller consumer handle
+ * @id:			Index into the set of matching slaves
+ * @match_criteria:	Matching criteria used to filter slaves
+ *
+ * id must be in the range [0, bif_slave_match_count(ctrl, match_criteria) - 1].
+ *
+ * Returns a BIF slave handle if successful or an ERR_PTR if not.
+ */
+struct bif_slave *bif_slave_match_get(const struct bif_ctrl *ctrl,
+	unsigned int id, const struct bif_match_criteria *match_criteria)
+{
+	struct bif_slave_dev *sdev;
+	struct bif_slave *slave = ERR_PTR(-ENODEV);
+	struct bif_slave_dev *sdev_found = NULL;
+	int count = 0;
+
+	mutex_lock(&bif_sdev_list_mutex);
+
+	list_for_each_entry(sdev, &bif_sdev_list, list) {
+		if (bif_slave_match(ctrl, sdev, match_criteria))
+			count++;
+		if (count == id + 1) {
+			sdev_found = sdev;
+			break;
+		}
+	}
+
+	mutex_unlock(&bif_sdev_list_mutex);
+
+	if (sdev_found) {
+		slave = kzalloc(sizeof(*slave), GFP_KERNEL);
+		if (!slave) {
+			pr_err("Slave allocation failed\n");
+			slave = ERR_PTR(-ENOMEM);
+		} else {
+			slave->sdev = sdev_found;
+			slave->ctrl.bdev = sdev_found->bdev;
+		}
+	}
+
+	return slave;
+}
+EXPORT_SYMBOL(bif_slave_match_get);
+
+/**
+ * bif_slave_put() - frees a BIF slave handle
+ * @slave:	BIF slave handle
+ */
+void bif_slave_put(struct bif_slave *slave)
+{
+	if (!IS_ERR_OR_NULL(slave) && slave->ctrl.exclusive_lock)
+		mutex_unlock(&slave->sdev->bdev->mutex);
+	kfree(slave);
+}
+EXPORT_SYMBOL(bif_slave_put);
+
+/**
+ * bif_slave_find_function() - get the function pointer and version of a
+ *			BIF function if it is present on the specified slave
+ * @slave:		BIF slave handle
+ * @function:		BIF function to search for inside of the slave
+ * @version:		If the function is found, then 'version' is set to the
+ *			version value of the function
+ * @function_pointer:	If the function is found, then 'function_pointer' is set
+ *			to the BIF slave address of the function
+ *
+ * Returns 0 for success or errno if an error occurred.  If the function is not
+ * found in the slave, then -ENODEV is returned.
+ */
+int bif_slave_find_function(struct bif_slave *slave, u8 function, u8 *version,
+				u16 *function_pointer)
+{
+	int rc = -ENODEV;
+	struct bif_ddb_l2_data *func;
+	int i;
+
+	if (IS_ERR_OR_NULL(slave) || IS_ERR_OR_NULL(version)
+	    || IS_ERR_OR_NULL(function_pointer)) {
+		pr_err("Invalid pointer input.\n");
+		return -EINVAL;
+	}
+
+	func = slave->sdev->function_directory;
+
+	for (i = 0; i < slave->sdev->l1_data.length / 4; i++) {
+		if (function == func[i].function_type) {
+			*version = func[i].function_version;
+			*function_pointer = func[i].function_pointer;
+			rc = 0;
+			break;
+		}
+	}
+
+	return rc;
+}
+EXPORT_SYMBOL(bif_slave_find_function);
+
+/**
+ * bif_slave_read() - read contiguous memory values from a BIF slave
+ * @slave:	BIF slave handle
+ * @addr:	BIF slave address to begin reading at
+ * @buf:	Buffer to fill with memory values
+ * @len:	Number of byte to read
+ *
+ * Returns 0 for success or errno if an error occurred.
+ */
+int bif_slave_read(struct bif_slave *slave, u16 addr, u8 *buf, int len)
+{
+	int rc;
+
+	if (IS_ERR_OR_NULL(slave) || IS_ERR_OR_NULL(buf)) {
+		pr_err("Invalid pointer input.\n");
+		return -EINVAL;
+	}
+
+	bif_slave_ctrl_lock(slave);
+
+	rc = _bif_slave_read(slave->sdev, addr, buf, len);
+	if (rc)
+		pr_err("BIF slave read failed, rc=%d\n", rc);
+
+	bif_slave_ctrl_unlock(slave);
+
+	return rc;
+}
+EXPORT_SYMBOL(bif_slave_read);
+
+/**
+ * bif_slave_write() - write contiguous memory values to a BIF slave
+ * @slave:	BIF slave handle
+ * @addr:	BIF slave address to begin writing at
+ * @buf:	Buffer containing values to write
+ * @len:	Number of byte to write
+ *
+ * Returns 0 for success or errno if an error occurred.
+ */
+int bif_slave_write(struct bif_slave *slave, u16 addr, u8 *buf, int len)
+{
+	int rc;
+
+	if (IS_ERR_OR_NULL(slave) || IS_ERR_OR_NULL(buf)) {
+		pr_err("Invalid pointer input.\n");
+		return -EINVAL;
+	}
+
+	bif_slave_ctrl_lock(slave);
+
+	rc = _bif_slave_write(slave->sdev, addr, buf, len);
+	if (rc)
+		pr_err("BIF slave write failed, rc=%d\n", rc);
+
+	bif_slave_ctrl_unlock(slave);
+
+	return rc;
+}
+EXPORT_SYMBOL(bif_slave_write);
+
+/**
+ * bif_slave_is_present() - check if a slave is currently physically present
+ *		in the system
+ * @slave:	BIF slave handle
+ *
+ * Returns 1 if the slave is present, 0 if the slave is not present, or errno
+ * if an error occurred.
+ *
+ * This function can be used by BIF consumer drivers to check if their slave
+ * handles are still meaningful after battery reinsertion.
+ */
+int bif_slave_is_present(struct bif_slave *slave)
+{
+	if (IS_ERR_OR_NULL(slave)) {
+		pr_err("Invalid pointer input.\n");
+		return -EINVAL;
+	}
+
+	return slave->sdev->present;
+}
+EXPORT_SYMBOL(bif_slave_is_present);
+
+/**
+ * bif_slave_is_selected() - check if a slave is currently selected on the BIF
+ *		bus
+ * @slave:	BIF slave handle
+ *
+ * Returns 1 if the slave is selected, 0 if the slave is not selected, or errno
+ * if an error occurred.
+ *
+ * This function should not be required under normal circumstances since the
+ * bif-core framework ensures that slaves are always selected when needed.
+ * It would be most useful when used as a helper in conjunction with
+ * bif_ctrl_bus_lock() and the raw transaction functions.
+ */
+int bif_slave_is_selected(struct bif_slave *slave)
+{
+	int rc;
+
+	if (IS_ERR_OR_NULL(slave)) {
+		pr_err("Invalid pointer input.\n");
+		return -EINVAL;
+	}
+
+	if (slave->sdev->bdev->selected_sdev != slave->sdev)
+		return false;
+
+	bif_slave_ctrl_lock(slave);
+	rc = bif_is_slave_selected(slave->sdev->bdev);
+	bif_slave_ctrl_unlock(slave);
+
+	return rc;
+}
+EXPORT_SYMBOL(bif_slave_is_selected);
+
+/**
+ * bif_slave_select() - select a slave on the BIF bus
+ * @slave:	BIF slave handle
+ *
+ * Returns 0 on success or errno if an error occurred.
+ *
+ * This function should not be required under normal circumstances since the
+ * bif-core framework ensures that slaves are always selected when needed.
+ * It would be most useful when used as a helper in conjunction with
+ * bif_ctrl_bus_lock() and the raw transaction functions.
+ */
+int bif_slave_select(struct bif_slave *slave)
+{
+	int rc;
+
+	if (IS_ERR_OR_NULL(slave)) {
+		pr_err("Invalid pointer input.\n");
+		return -EINVAL;
+	}
+
+	bif_slave_ctrl_lock(slave);
+	slave->sdev->bdev->selected_sdev = NULL;
+	rc = bif_select_slave(slave->sdev);
+	bif_slave_ctrl_unlock(slave);
+
+	return rc;
+}
+EXPORT_SYMBOL(bif_slave_select);
+
+/**
+ * bif_ctrl_raw_transaction() - perform a raw BIF transaction on the bus which
+ *			expects no slave response
+ * @ctrl:		BIF controller consumer handle
+ * @transaction:	BIF transaction to carry out.  This should be one of the
+ *			values in enum bif_transaction.
+ * @data:		8-bit data to use in the transaction.  The meaning of
+ *			this data depends upon the transaction that is to be
+ *			performed.
+ *
+ * When performing a bus command (BC) transaction, values in enum
+ * bif_bus_command may be used for the data parameter.  Additional manufacturer
+ * specific values may also be used in a BC transaction.
+ *
+ * Returns 0 on success or errno if an error occurred.
+ *
+ * This function should only need to be used when BIF transactions are required
+ * that are not handled by the bif-core directly.
+ */
+int bif_ctrl_raw_transaction(struct bif_ctrl *ctrl, int transaction, u8 data)
+{
+	int rc;
+
+	if (IS_ERR_OR_NULL(ctrl)) {
+		pr_err("Invalid pointer input.\n");
+		return -EINVAL;
+	}
+
+	bif_ctrl_lock(ctrl);
+
+	rc = ctrl->bdev->desc->ops->bus_transaction(ctrl->bdev, transaction,
+							data);
+	if (rc)
+		pr_err("BIF bus transaction failed, rc=%d\n", rc);
+
+	bif_ctrl_unlock(ctrl);
+
+	return rc;
+}
+EXPORT_SYMBOL(bif_ctrl_raw_transaction);
+
+/**
+ * bif_ctrl_raw_transaction_read() - perform a raw BIF transaction on the bus
+ *			which expects an RD or TACK slave response word
+ * @ctrl:		BIF controller consumer handle
+ * @transaction:	BIF transaction to carry out.  This should be one of the
+ *			values in enum bif_transaction.
+ * @data:		8-bit data to use in the transaction.  The meaning of
+ *			this data depends upon the transaction that is to be
+ *			performed.
+ * @response:		Pointer to an integer which is filled with the 11-bit
+ *			slave response word upon success.  The 11-bit format is
+ *			(MSB to LSB) BCF, ACK, EOT, D7-D0.
+ *
+ * When performing a bus command (BC) transaction, values in enum
+ * bif_bus_command may be used for the data parameter.  Additional manufacturer
+ * specific values may also be used in a BC transaction.
+ *
+ * Returns 0 on success or errno if an error occurred.
+ *
+ * This function should only need to be used when BIF transactions are required
+ * that are not handled by the bif-core directly.
+ */
+int bif_ctrl_raw_transaction_read(struct bif_ctrl *ctrl, int transaction,
+					u8 data, int *response)
+{
+	int rc;
+
+	if (IS_ERR_OR_NULL(ctrl) || IS_ERR_OR_NULL(response)) {
+		pr_err("Invalid pointer input.\n");
+		return -EINVAL;
+	}
+
+	bif_ctrl_lock(ctrl);
+
+	rc = ctrl->bdev->desc->ops->bus_transaction_read(ctrl->bdev,
+					transaction, data, response);
+	if (rc)
+		pr_err("BIF bus transaction failed, rc=%d\n", rc);
+
+	bif_ctrl_unlock(ctrl);
+
+	return rc;
+}
+EXPORT_SYMBOL(bif_ctrl_raw_transaction_read);
+
+/**
+ * bif_ctrl_raw_transaction_query() - perform a raw BIF transaction on the bus
+ *			which expects a BQ slave response
+ * @ctrl:		BIF controller consumer handle
+ * @transaction:	BIF transaction to carry out.  This should be one of the
+ *			values in enum bif_transaction.
+ * @data:		8-bit data to use in the transaction.  The meaning of
+ *			this data depends upon the transaction that is to be
+ *			performed.
+ * @query_response:	Pointer to boolean which is set to true if a BQ pulse
+ *			is receieved, or false if no BQ pulse is received before
+ *			timing out.
+ *
+ * When performing a bus command (BC) transaction, values in enum
+ * bif_bus_command may be used for the data parameter.  Additional manufacturer
+ * specific values may also be used in a BC transaction.
+ *
+ * Returns 0 on success or errno if an error occurred.
+ *
+ * This function should only need to be used when BIF transactions are required
+ * that are not handled by the bif-core directly.
+ */
+int bif_ctrl_raw_transaction_query(struct bif_ctrl *ctrl, int transaction,
+		u8 data, bool *query_response)
+{
+	int rc;
+
+	if (IS_ERR_OR_NULL(ctrl) || IS_ERR_OR_NULL(query_response)) {
+		pr_err("Invalid pointer input.\n");
+		return -EINVAL;
+	}
+
+	bif_ctrl_lock(ctrl);
+
+	rc = ctrl->bdev->desc->ops->bus_transaction_query(ctrl->bdev,
+					transaction, data, query_response);
+	if (rc)
+		pr_err("BIF bus transaction failed, rc=%d\n", rc);
+
+	bif_ctrl_unlock(ctrl);
+
+	return rc;
+}
+EXPORT_SYMBOL(bif_ctrl_raw_transaction_query);
+
+/**
+ * bif_ctrl_bus_lock() - lock the BIF bus of a controller for exclusive access
+ * @ctrl:	BIF controller consumer handle
+ *
+ * This function should only need to be called in circumstances where a BIF
+ * consumer is issuing special BIF bus commands that have strict ordering
+ * requirements.
+ */
+void bif_ctrl_bus_lock(struct bif_ctrl *ctrl)
+{
+	if (IS_ERR_OR_NULL(ctrl)) {
+		pr_err("Invalid controller handle.\n");
+		return;
+	}
+
+	if (ctrl->exclusive_lock) {
+		pr_err("BIF bus exclusive lock already held\n");
+		return;
+	}
+
+	mutex_lock(&ctrl->bdev->mutex);
+	ctrl->exclusive_lock = true;
+	bif_cancel_irq_mode_work(ctrl->bdev);
+}
+EXPORT_SYMBOL(bif_ctrl_bus_lock);
+
+/**
+ * bif_ctrl_bus_unlock() - lock the BIF bus of a controller that was previously
+ *		locked for exclusive access
+ * @ctrl:	BIF controller consumer handle
+ *
+ * This function must only be called after first calling bif_ctrl_bus_lock().
+ */
+void bif_ctrl_bus_unlock(struct bif_ctrl *ctrl)
+{
+	if (IS_ERR_OR_NULL(ctrl)) {
+		pr_err("Invalid controller handle.\n");
+		return;
+	}
+
+	if (!ctrl->exclusive_lock) {
+		pr_err("BIF bus exclusive lock not already held\n");
+		return;
+	}
+
+	ctrl->exclusive_lock = false;
+	bif_schedule_irq_mode_work(ctrl->bdev);
+	mutex_unlock(&ctrl->bdev->mutex);
+}
+EXPORT_SYMBOL(bif_ctrl_bus_unlock);
+
+/**
+ * bif_ctrl_measure_rid() - measure the battery pack Rid pull-down resistance
+ *		in ohms
+ * @ctrl:	BIF controller consumer handle
+ *
+ * Returns the resistance of the Rid resistor in ohms if successful or errno
+ * if an error occurred.
+ */
+int bif_ctrl_measure_rid(struct bif_ctrl *ctrl)
+{
+	int rc;
+
+	if (IS_ERR_OR_NULL(ctrl)) {
+		pr_err("Invalid controller handle.\n");
+		return -ENODEV;
+	}
+
+	if (!ctrl->bdev->desc->ops->get_battery_rid) {
+		pr_err("Cannot measure Rid.\n");
+		return -ENXIO;
+	}
+
+	bif_ctrl_lock(ctrl);
+
+	rc = ctrl->bdev->desc->ops->get_battery_rid(ctrl->bdev);
+	if (rc < 0)
+		pr_err("Error during Rid measurement, rc=%d\n", rc);
+
+	bif_ctrl_unlock(ctrl);
+
+	return rc;
+}
+EXPORT_SYMBOL(bif_ctrl_measure_rid);
+
+/**
+ * bif_ctrl_get_bus_period() - get the BIF bus period (tau_bif) in nanoseconds
+ * @ctrl:	BIF controller consumer handle
+ *
+ * Returns the currently configured bus period in nanoseconds if successful or
+ * errno if an error occurred.
+ */
+int bif_ctrl_get_bus_period(struct bif_ctrl *ctrl)
+{
+	int rc;
+
+	if (IS_ERR_OR_NULL(ctrl)) {
+		pr_err("Invalid controller handle.\n");
+		return -ENODEV;
+	}
+
+	if (!ctrl->bdev->desc->ops->get_bus_period) {
+		pr_err("Cannot get the BIF bus period.\n");
+		return -ENXIO;
+	}
+
+	rc = ctrl->bdev->desc->ops->get_bus_period(ctrl->bdev);
+	if (rc < 0)
+		pr_err("Error during bus period retrieval, rc=%d\n", rc);
+
+	return rc;
+}
+EXPORT_SYMBOL(bif_ctrl_get_bus_period);
+
+/**
+ * bif_ctrl_set_bus_period() - set the BIF bus period (tau_bif) in nanoseconds
+ * @ctrl:	BIF controller consumer handle
+ * @period_ns:	BIF bus period in nanoseconds to use
+ *
+ * If the exact period is not supported by the BIF controller hardware, then the
+ * next larger supported period will be used.
+ *
+ * Returns 0 on success or errno if an error occurred.
+ */
+int bif_ctrl_set_bus_period(struct bif_ctrl *ctrl, int period_ns)
+{
+	int rc;
+
+	if (IS_ERR_OR_NULL(ctrl)) {
+		pr_err("Invalid controller handle.\n");
+		return -ENODEV;
+	}
+
+	if (!ctrl->bdev->desc->ops->set_bus_period) {
+		pr_err("Cannot set the BIF bus period.\n");
+		return -ENXIO;
+	}
+
+	bif_ctrl_lock(ctrl);
+	rc = ctrl->bdev->desc->ops->set_bus_period(ctrl->bdev, period_ns);
+	if (rc)
+		pr_err("Error during bus period configuration, rc=%d\n", rc);
+	bif_ctrl_unlock(ctrl);
+
+	return rc;
+}
+EXPORT_SYMBOL(bif_ctrl_set_bus_period);
+
+/**
+ * bif_ctrl_get_bus_state() - get the current state of the BIF bus
+ * @ctrl:	BIF controller consumer handle
+ *
+ * Returns a bus state from enum bif_bus_state if successful or errno if an
+ * error occurred.
+ */
+int bif_ctrl_get_bus_state(struct bif_ctrl *ctrl)
+{
+	int rc;
+
+	if (IS_ERR_OR_NULL(ctrl)) {
+		pr_err("Invalid controller handle.\n");
+		return -ENODEV;
+	}
+
+	rc = ctrl->bdev->desc->ops->get_bus_state(ctrl->bdev);
+	if (rc < 0)
+		pr_err("Error during bus state retrieval, rc=%d\n", rc);
+
+	return rc;
+}
+EXPORT_SYMBOL(bif_ctrl_get_bus_state);
+
+/**
+ * bif_ctrl_set_bus_state() - set the state of the BIF bus
+ * @ctrl:	BIF controller consumer handle
+ * @state:	State for the BIF bus to enter
+ *
+ * Returns 0 on success or errno if an error occurred.
+ */
+int bif_ctrl_set_bus_state(struct bif_ctrl *ctrl, enum bif_bus_state state)
+{
+	int rc;
+
+	if (IS_ERR_OR_NULL(ctrl)) {
+		pr_err("Invalid controller handle.\n");
+		return -ENODEV;
+	}
+
+	bif_ctrl_lock(ctrl);
+
+	rc = ctrl->bdev->desc->ops->set_bus_state(ctrl->bdev, state);
+	if (rc < 0)
+		pr_err("Error during bus state configuration, rc=%d\n", rc);
+
+	/*
+	 * Uncache the selected slave if the new bus state results in the slave
+	 * becoming unselected.
+	 */
+	if (state == BIF_BUS_STATE_MASTER_DISABLED
+	    || state == BIF_BUS_STATE_POWER_DOWN
+	    || state == BIF_BUS_STATE_STANDBY)
+		ctrl->bdev->selected_sdev = NULL;
+
+	bif_ctrl_unlock(ctrl);
+
+	return rc;
+}
+EXPORT_SYMBOL(bif_ctrl_set_bus_state);
+
+/*
+ * Check if the specified function is a protocol function and if it is, then
+ * instantiate protocol function data for the slave.
+ */
+static int bif_initialize_protocol_function(struct bif_slave_dev *sdev,
+		struct bif_ddb_l2_data *func)
+{
+	int rc = 0;
+	u8 buf[4];
+
+	/* Ensure that this is a protocol function. */
+	if (func->function_type != BIF_FUNC_PROTOCOL)
+		return 0;
+
+	if (sdev->protocol_function) {
+		pr_err("Duplicate protocol function found for BIF slave; DEV_ADR=0x%02X\n",
+			sdev->slave_addr);
+		return -EPERM;
+	}
+
+	sdev->protocol_function = kzalloc(sizeof(struct bif_protocol_function),
+						GFP_KERNEL);
+	if (!sdev->protocol_function) {
+		pr_err("out of memory\n");
+		return -ENOMEM;
+	}
+
+	rc = _bif_slave_read(sdev, func->function_pointer, buf, 4);
+	if (rc) {
+		pr_err("Protocol function data read failed, rc=%d\n", rc);
+		return rc;
+	}
+
+	sdev->protocol_function->protocol_pointer  = buf[0] << 8 | buf[1];
+	sdev->protocol_function->device_id_pointer = buf[2] << 8 | buf[3];
+	sdev->protocol_function->l2_entry = func;
+
+	rc = _bif_slave_read(sdev, sdev->protocol_function->device_id_pointer,
+		sdev->protocol_function->device_id, BIF_DEVICE_ID_BYTE_LENGTH);
+	if (rc) {
+		pr_err("Device ID read failed, rc=%d\n", rc);
+		return rc;
+	}
+
+	/* Check if this slave does not have a UID value stored. */
+	if (sdev->unique_id_bits_known == 0) {
+		sdev->unique_id_bits_known = BIF_UNIQUE_ID_BIT_LENGTH;
+		/* Fill in UID using manufacturer ID and device ID. */
+		sdev->unique_id[0] = sdev->l1_data.manufacturer_id >> 8;
+		sdev->unique_id[1] = sdev->l1_data.manufacturer_id;
+		memcpy(&sdev->unique_id[2],
+			sdev->protocol_function->device_id,
+			BIF_DEVICE_ID_BYTE_LENGTH);
+	}
+
+	return rc;
+}
+
+/*
+ * Check if the specified function is a slave control function and if it is,
+ * then instantiate slave control function data for the slave.
+ */
+static int bif_initialize_slave_control_function(struct bif_slave_dev *sdev,
+		struct bif_ddb_l2_data *func)
+{
+	int rc = 0;
+	int i;
+	u8 buf[3];
+
+	/* Ensure that this is a slave control function. */
+	if (func->function_type != BIF_FUNC_SLAVE_CONTROL)
+		return 0;
+
+	if (sdev->slave_ctrl_function) {
+		pr_err("Duplicate slave control function found for BIF slave; DEV_ADR=0x%02X\n",
+			sdev->slave_addr);
+		return -EPERM;
+	}
+
+	sdev->slave_ctrl_function
+		= kzalloc(sizeof(struct bif_protocol_function), GFP_KERNEL);
+	if (!sdev->slave_ctrl_function) {
+		pr_err("out of memory\n");
+		return -ENOMEM;
+	}
+
+	rc = _bif_slave_read(sdev, func->function_pointer, buf, 3);
+	if (rc) {
+		pr_err("Slave control function data read failed, rc=%d\n", rc);
+		return rc;
+	}
+
+	sdev->slave_ctrl_function->slave_ctrl_pointer = buf[0] << 8 | buf[1];
+	sdev->slave_ctrl_function->task_count
+		= buf[2] * SLAVE_CTRL_TASKS_PER_SET;
+	sdev->slave_ctrl_function->l2_entry = func;
+
+	if (sdev->slave_ctrl_function->task_count > 0) {
+		sdev->slave_ctrl_function->irq_notifier_list =
+			kzalloc(sizeof(struct blocking_notifier_head)
+			    * sdev->slave_ctrl_function->task_count,
+			    GFP_KERNEL);
+		if (!sdev->slave_ctrl_function->irq_notifier_list) {
+			pr_err("out of memory\n");
+			kfree(sdev->slave_ctrl_function);
+			return -ENOMEM;
+		}
+
+		for (i = 0; i < sdev->slave_ctrl_function->task_count; i++) {
+			BLOCKING_INIT_NOTIFIER_HEAD(
+			    &sdev->slave_ctrl_function->irq_notifier_list[i]);
+		}
+	}
+
+	return rc;
+}
+
+/**
+ * bif_crc_ccitt() - calculate the CRC-CCITT CRC value of the data specified
+ * @buffer:	Data to calculate the CRC of
+ * @len:	Length of the data buffer in bytes
+ *
+ * MIPI-BIF specifies the usage of CRC-CCITT for BIF data objects.  This
+ * function performs the CRC calculation while taking into account the bit
+ * ordering used by BIF.
+ */
+u16 bif_crc_ccitt(const u8 *buffer, unsigned int len)
+{
+	u16 crc = 0xFFFF;
+
+	while (len--) {
+		crc = crc_ccitt_byte(crc, bitrev8(*buffer));
+		buffer++;
+	}
+	return bitrev16(crc);
+}
+EXPORT_SYMBOL(bif_crc_ccitt);
+
+static u16 bif_object_crc_ccitt(const struct bif_object *object)
+{
+	u16 crc = 0xFFFF;
+	int i;
+
+	crc = crc_ccitt_byte(crc, bitrev8(object->type));
+	crc = crc_ccitt_byte(crc, bitrev8(object->version));
+	crc = crc_ccitt_byte(crc, bitrev8(object->manufacturer_id >> 8));
+	crc = crc_ccitt_byte(crc, bitrev8(object->manufacturer_id));
+	crc = crc_ccitt_byte(crc, bitrev8(object->length >> 8));
+	crc = crc_ccitt_byte(crc, bitrev8(object->length));
+
+	for (i = 0; i < object->length - 8; i++)
+		crc = crc_ccitt_byte(crc, bitrev8(object->data[i]));
+
+	return bitrev16(crc);
+}
+
+/*
+ * Check if the specified function is an NVM function and if it is, then
+ * instantiate NVM function data for the slave and read all objects.
+ */
+static int bif_initialize_nvm_function(struct bif_slave_dev *sdev,
+		struct bif_ddb_l2_data *func)
+{
+	int rc = 0;
+	int data_len;
+	u8 buf[8], object_type;
+	struct bif_object *object;
+	struct bif_object *temp;
+	u16 addr;
+	u16 crc;
+
+	/* Ensure that this is an NVM function. */
+	if (func->function_type != BIF_FUNC_NVM)
+		return 0;
+
+	if (sdev->nvm_function) {
+		pr_err("Duplicate NVM function found for BIF slave; DEV_ADR=0x%02X\n",
+			sdev->slave_addr);
+		return -EPERM;
+	}
+
+	sdev->nvm_function
+		= kzalloc(sizeof(*sdev->nvm_function), GFP_KERNEL);
+	if (!sdev->nvm_function) {
+		pr_err("out of memory\n");
+		return -ENOMEM;
+	}
+
+	rc = _bif_slave_read(sdev, func->function_pointer, buf, 8);
+	if (rc) {
+		pr_err("NVM function data read failed, rc=%d\n", rc);
+		return rc;
+	}
+
+	sdev->nvm_function->nvm_pointer		= buf[0] << 8 | buf[1];
+	sdev->nvm_function->slave_control_channel	= buf[2];
+	sdev->nvm_function->write_buffer_size		= buf[3];
+	sdev->nvm_function->nvm_base_address		= buf[4] << 8 | buf[5];
+	sdev->nvm_function->nvm_size			= buf[6] << 8 | buf[7];
+
+	INIT_LIST_HEAD(&sdev->nvm_function->object_list);
+
+	/* Read object list */
+	addr = sdev->nvm_function->nvm_base_address;
+	rc = _bif_slave_read(sdev, addr, &object_type, 1);
+	if (rc) {
+		pr_err("Slave memory read failed, rc=%d\n", rc);
+		return rc;
+	}
+
+	/* Object type == 0x00 corresponds to the end of the object list. */
+	while (object_type != 0x00) {
+		object = kzalloc(sizeof(*object), GFP_KERNEL);
+		if (!object) {
+			pr_err("out of memory\n");
+			rc = -ENOMEM;
+			goto free_data;
+		}
+		list_add_tail(&object->list, &sdev->nvm_function->object_list);
+
+		rc = _bif_slave_read(sdev, addr + 1, buf + 1, 5);
+		if (rc) {
+			pr_err("Slave memory read of object header failed; addr=0x%04X, len=%d, rc=%d\n",
+				addr + 1, 5, rc);
+			goto free_data;
+		}
+
+		object->addr		= addr;
+		object->type		= object_type;
+		object->version		= buf[1];
+		object->manufacturer_id	= buf[2] << 8 | buf[3];
+		object->length		= buf[4] << 8 | buf[5];
+
+		if ((object->addr + object->length)
+		    > (sdev->nvm_function->nvm_base_address
+				+ sdev->nvm_function->nvm_size)) {
+			pr_warn("warning: BIF slave object is not formatted correctly; NVM base=0x%04X, NVM len=%d, object addr=0x%04X, object len=%d\n",
+				sdev->nvm_function->nvm_base_address,
+				sdev->nvm_function->nvm_size,
+				object->addr,
+				object->length);
+			/* Limit object size to remaining NVM size. */
+			object->length = sdev->nvm_function->nvm_size
+				+ sdev->nvm_function->nvm_base_address
+				- object->addr;
+		}
+
+		/* Object header + CRC takes up 8 bytes. */
+		data_len = object->length - 8;
+		object->data = kmalloc(data_len, GFP_KERNEL);
+		if (!object->data) {
+			pr_err("out of memory\n");
+			rc = -ENOMEM;
+			goto free_data;
+		}
+
+		rc = _bif_slave_read(sdev, addr + 6, object->data, data_len);
+		if (rc) {
+			pr_err("Slave memory read of object data failed; addr=0x%04X, len=%d, rc=%d\n",
+				addr + 6, data_len, rc);
+			goto free_data;
+		}
+
+		rc = _bif_slave_read(sdev, addr + 6 + data_len, buf, 3);
+		if (rc) {
+			pr_err("Slave memory read of object CRC failed; addr=0x%04X, len=%d, rc=%d\n",
+				addr + 6 + data_len, 3, rc);
+			goto free_data;
+		}
+
+		object->crc = buf[0] << 8 | buf[1];
+		object_type = buf[2];
+		sdev->nvm_function->object_count++;
+
+		crc = bif_object_crc_ccitt(object);
+		if (crc != object->crc)
+			pr_info("BIF object at addr=0x%04X has invalid CRC; crc calc=0x%04X, crc exp=0x%04X\n",
+				object->addr, crc, object->crc);
+
+		addr += object->length;
+	}
+
+	return rc;
+
+free_data:
+	list_for_each_entry_safe(object, temp,
+				&sdev->nvm_function->object_list, list) {
+		list_del(&object->list);
+		kfree(object->data);
+		kfree(object);
+	}
+	kfree(sdev->nvm_function);
+	sdev->nvm_function = NULL;
+	return rc;
+}
+
+static int bif_parse_slave_data(struct bif_slave_dev *sdev)
+{
+	int rc = 0;
+	u8 buf[10];
+	u8 *func_buf;
+	struct bif_ddb_l2_data *func;
+	int function_count, i;
+
+	rc = _bif_slave_read(sdev, BIF_DDB_L1_BASE_ADDR, buf, 10);
+	if (rc) {
+		pr_err("DDB L1 data read failed, rc=%d\n", rc);
+		return rc;
+	}
+
+	sdev->l1_data.revision		= buf[0];
+	sdev->l1_data.level		= buf[1];
+	sdev->l1_data.device_class	= buf[2] << 8 | buf[3];
+	sdev->l1_data.manufacturer_id	= buf[4] << 8 | buf[5];
+	sdev->l1_data.product_id	= buf[6] << 8 | buf[7];
+	sdev->l1_data.length		= buf[8] << 8 | buf[9];
+
+	function_count = sdev->l1_data.length / 4;
+	if (sdev->l1_data.length % 4) {
+		pr_err("Function directory length=%d is invalid\n",
+				sdev->l1_data.length);
+		return -EPROTO;
+	}
+
+	/* No DDB L2 function directory */
+	if (function_count == 0)
+		return 0;
+
+	func_buf = kmalloc(sdev->l1_data.length, GFP_KERNEL);
+	if (!func_buf) {
+		pr_err("out of memory\n");
+		return -ENOMEM;
+	}
+
+	sdev->function_directory = kzalloc(
+		function_count * sizeof(struct bif_ddb_l2_data), GFP_KERNEL);
+	if (!sdev->function_directory) {
+		pr_err("out of memory\n");
+		return -ENOMEM;
+	}
+
+	rc = _bif_slave_read(sdev, BIF_DDB_L2_BASE_ADDR, func_buf,
+				sdev->l1_data.length);
+	if (rc) {
+		pr_err("DDB L2 data read failed, rc=%d\n", rc);
+		return rc;
+	}
+
+	for (i = 0; i < function_count; i++) {
+		func = &sdev->function_directory[i];
+		func->function_type	= func_buf[i * 4];
+		func->function_version	= func_buf[i * 4 + 1];
+		func->function_pointer	= func_buf[i * 4 + 2] << 8
+					  | func_buf[i * 4 + 3];
+		rc = bif_initialize_protocol_function(sdev, func);
+		if (rc)
+			goto done;
+		rc = bif_initialize_slave_control_function(sdev, func);
+		if (rc)
+			goto done;
+		rc = bif_initialize_nvm_function(sdev, func);
+		if (rc)
+			goto done;
+	}
+done:
+	kfree(func_buf);
+	return rc;
+}
+
+static int bif_add_secondary_slaves(struct bif_slave_dev *primary_slave)
+{
+	int rc = 0;
+	int data_len, i;
+	u16 crc;
+	struct bif_slave_dev *sdev;
+	struct bif_object *object;
+
+	list_for_each_entry(object, &primary_slave->nvm_function->object_list,
+				list) {
+		if (object->type != BIF_OBJ_SEC_SLAVE)
+			continue;
+
+		data_len = object->length - 8;
+		if (data_len % BIF_UNIQUE_ID_BYTE_LENGTH) {
+			pr_info("Invalid secondary slave object found, addr=0x%04X, data len=%d\n",
+				object->addr, data_len);
+			continue;
+		}
+
+		crc = bif_object_crc_ccitt(object);
+		if (crc != object->crc) {
+			pr_info("BIF object at addr=0x%04X has invalid CRC; crc calc=0x%04X, crc exp=0x%04X\n",
+				object->addr, crc, object->crc);
+			continue;
+		}
+
+		for (i = 0; i < data_len / BIF_UNIQUE_ID_BYTE_LENGTH; i++) {
+			sdev = bif_add_slave(primary_slave->bdev);
+			if (IS_ERR(sdev)) {
+				rc = PTR_ERR(sdev);
+				pr_err("bif_add_slave failed, rc=%d\n", rc);
+				return rc;
+			}
+			memcpy(sdev->unique_id,
+				&object->data[i * BIF_UNIQUE_ID_BYTE_LENGTH],
+				BIF_UNIQUE_ID_BYTE_LENGTH);
+			sdev->unique_id_bits_known = BIF_UNIQUE_ID_BIT_LENGTH;
+
+			rc = bif_select_slave(sdev);
+			if (rc) {
+				pr_err("Could not select slave, rc=%d\n", rc);
+				goto free_slave;
+			}
+
+			rc = bif_is_slave_selected(sdev->bdev);
+			if (rc < 0) {
+				pr_err("Transaction failed, rc=%d\n", rc);
+				goto free_slave;
+			} else if (rc == 1) {
+				sdev->present = true;
+				sdev->bdev->selected_sdev = sdev;
+			} else {
+				sdev->present = false;
+				sdev->bdev->selected_sdev = NULL;
+			}
+		}
+	}
+
+	return rc;
+
+free_slave:
+	bif_remove_slave(sdev);
+	return rc;
+}
+
+/*
+ * Performs UID search to identify all slaves attached to the bus. Assumes that
+ * all necessary locks are held.
+ */
+static int bif_perform_uid_search(struct bif_ctrl_dev *bdev)
+{
+	struct bif_slave_dev *sdev;
+	struct bif_slave_dev *new_slave;
+	bool resp[2], resp_dilc;
+	int i;
+	int rc = 0;
+	u8 cmd_probe[2] = {BIF_CMD_DIP0, BIF_CMD_DIP1};
+	u8 cmd_enter[2] = {BIF_CMD_DIE0, BIF_CMD_DIE1};
+
+	/*
+	 * Iterate over all partially known UIDs adding new ones as they are
+	 * found.
+	 */
+	list_for_each_entry(sdev, &bif_sdev_list, list) {
+		/* Skip slaves with fully known UIDs. */
+		if (sdev->unique_id_bits_known == BIF_UNIQUE_ID_BIT_LENGTH
+		    || sdev->bdev != bdev)
+			continue;
+
+		/* Begin a new UID search. */
+		rc = bdev->desc->ops->bus_transaction(bdev, BIF_TRANS_BC,
+							BIF_CMD_DISS);
+		if (rc) {
+			pr_err("bus_transaction failed, rc=%d\n", rc);
+			return rc;
+		}
+
+		/* Step through all known UID bits (MSB to LSB). */
+		for (i = 0; i < sdev->unique_id_bits_known; i++) {
+			rc = bdev->desc->ops->bus_transaction(bdev,
+				BIF_TRANS_BC,
+				cmd_enter[get_uid_bit(sdev->unique_id, i)]);
+			if (rc) {
+				pr_err("bus_transaction failed, rc=%d\n", rc);
+				return rc;
+			}
+		}
+
+		/* Step through unknown UID bits. */
+		for (i = sdev->unique_id_bits_known;
+				i < BIF_UNIQUE_ID_BIT_LENGTH; i++) {
+			rc = bdev->desc->ops->bus_transaction_query(bdev,
+				BIF_TRANS_BC, cmd_probe[0], &resp[0]);
+			if (rc) {
+				pr_err("bus_transaction failed, rc=%d\n", rc);
+				return rc;
+			}
+
+			rc = bdev->desc->ops->bus_transaction_query(bdev,
+				BIF_TRANS_BC, cmd_probe[1], &resp[1]);
+			if (rc) {
+				pr_err("bus_transaction failed, rc=%d\n", rc);
+				return rc;
+			}
+
+			if (resp[0] && resp[1]) {
+				/* Create an entry for the new UID branch. */
+				new_slave = bif_add_slave(bdev);
+				if (IS_ERR(new_slave)) {
+					rc = PTR_ERR(sdev);
+					pr_err("bif_add_slave failed, rc=%d\n",
+						rc);
+					return rc;
+				}
+				memcpy(new_slave->unique_id, sdev->unique_id,
+					BIF_UNIQUE_ID_BYTE_LENGTH);
+				new_slave->bdev = sdev->bdev;
+
+				set_uid_bit(sdev->unique_id, i, 0);
+				sdev->unique_id_bits_known = i + 1;
+
+				set_uid_bit(new_slave->unique_id, i, 1);
+				new_slave->unique_id_bits_known = i + 1;
+			} else if (resp[0]) {
+				set_uid_bit(sdev->unique_id, i, 0);
+				sdev->unique_id_bits_known = i + 1;
+			} else if (resp[1]) {
+				set_uid_bit(sdev->unique_id, i, 1);
+				sdev->unique_id_bits_known = i + 1;
+			} else {
+				pr_debug("no bus query response received\n");
+				rc = -ENXIO;
+				return rc;
+			}
+
+			rc = bdev->desc->ops->bus_transaction(bdev,
+				BIF_TRANS_BC, cmd_enter[resp[0] ? 0 : 1]);
+			if (rc) {
+				pr_err("bus_transaction failed, rc=%d\n", rc);
+				return rc;
+			}
+		}
+
+		rc = bdev->desc->ops->bus_transaction_query(bdev,
+			BIF_TRANS_BC, BIF_CMD_DILC, &resp_dilc);
+		if (rc) {
+			pr_err("bus_transaction failed, rc=%d\n", rc);
+			return rc;
+		}
+
+		if (resp_dilc) {
+			sdev->present = true;
+			sdev->bdev->selected_sdev = sdev;
+			rc = bif_parse_slave_data(sdev);
+		} else {
+			pr_err("Slave failed to respond to DILC bus command; its UID is thus unverified.\n");
+			sdev->unique_id_bits_known = 0;
+			rc = -ENXIO;
+			return rc;
+		}
+	}
+
+	return rc;
+}
+
+/*
+ * Removes slaves from the bif_sdev_list which have the same UID as previous
+ * slaves in the list.
+ */
+static int bif_remove_duplicate_slaves(struct bif_ctrl_dev *bdev)
+{
+	struct bif_slave_dev *sdev;
+	struct bif_slave_dev *last_slave;
+	struct bif_slave_dev *temp;
+
+	list_for_each_entry_safe(last_slave, temp, &bif_sdev_list, list) {
+		list_for_each_entry(sdev, &bif_sdev_list, list) {
+			if (last_slave == sdev) {
+				break;
+			} else if (memcmp(last_slave->unique_id,
+					sdev->unique_id,
+					BIF_UNIQUE_ID_BYTE_LENGTH) == 0) {
+				bif_remove_slave(last_slave);
+				break;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int bif_add_all_slaves(struct bif_ctrl_dev *bdev)
+{
+	struct bif_slave_dev *sdev;
+	int rc = 0;
+	int i;
+	bool has_slave = false, is_primary_slave = false;
+
+	mutex_lock(&bif_sdev_list_mutex);
+	mutex_lock(&bdev->mutex);
+
+	list_for_each_entry(sdev, &bif_sdev_list, list) {
+		if (sdev->bdev == bdev) {
+			has_slave = true;
+			break;
+		}
+	}
+
+	if (!has_slave) {
+		/* Create a single empty slave to start the search algorithm. */
+		sdev = bif_add_slave(bdev);
+		if (IS_ERR(sdev)) {
+			rc = PTR_ERR(sdev);
+			pr_err("bif_add_slave failed, rc=%d\n", rc);
+			goto out;
+		}
+
+		for (i = 0; i < BIF_TRANSACTION_RETRY_COUNT; i++) {
+			/* Attempt to select primary slave in battery pack. */
+			rc = bdev->desc->ops->bus_transaction(bdev,
+				BIF_TRANS_SDA, BIF_PRIMARY_SLAVE_DEV_ADR);
+			if (rc == 0)
+				break;
+		}
+		if (rc) {
+			pr_err("BIF bus_transaction failed, rc=%d\n", rc);
+			goto out;
+		}
+
+		/* Check if a slave is selected. */
+		rc = bif_is_slave_selected(bdev);
+		if (rc < 0) {
+			pr_err("BIF bus_transaction failed, rc=%d\n", rc);
+			goto out;
+		} else {
+			is_primary_slave = rc;
+		}
+	}
+
+	if (is_primary_slave) {
+		pr_debug("Using primary slave at DEV_ADR==0x%02X\n",
+			BIF_PRIMARY_SLAVE_DEV_ADR);
+		sdev->bdev->selected_sdev = sdev;
+		sdev->present = true;
+		sdev->slave_addr = BIF_PRIMARY_SLAVE_DEV_ADR;
+		rc = bif_parse_slave_data(sdev);
+		if (rc) {
+			pr_err("Failed to parse primary slave data, rc=%d\n",
+				rc);
+			goto out;
+		}
+		rc = bif_add_secondary_slaves(sdev);
+		if (rc) {
+			pr_err("Failed to add secondary slaves, rc=%d\n", rc);
+			goto out;
+		}
+	} else {
+		pr_debug("Falling back on full UID search.\n");
+		for (i = 0; i < BIF_TRANSACTION_RETRY_COUNT; i++) {
+			rc = bif_perform_uid_search(bdev);
+			if (rc == 0)
+				break;
+		}
+		if (rc) {
+			pr_debug("BIF UID search failed, rc=%d\n", rc);
+			goto out;
+		}
+	}
+
+	bif_remove_duplicate_slaves(bdev);
+
+	mutex_unlock(&bdev->mutex);
+	mutex_unlock(&bif_sdev_list_mutex);
+
+	return rc;
+
+out:
+	mutex_unlock(&bdev->mutex);
+	mutex_unlock(&bif_sdev_list_mutex);
+	pr_debug("BIF slave search failed, rc=%d\n", rc);
+	return rc;
+}
+
+static int bif_add_known_slave(struct bif_ctrl_dev *bdev, u8 slave_addr)
+{
+	struct bif_slave_dev *sdev;
+	int rc = 0;
+	int i;
+
+	for (i = 0; i < BIF_TRANSACTION_RETRY_COUNT; i++) {
+		/* Attempt to select the slave. */
+		rc = bdev->desc->ops->bus_transaction(bdev, BIF_TRANS_SDA,
+							slave_addr);
+		if (rc == 0)
+			break;
+	}
+	if (rc) {
+		pr_err("BIF bus_transaction failed, rc=%d\n", rc);
+		return rc;
+	}
+
+	/* Check if a slave is selected. */
+	rc = bif_is_slave_selected(bdev);
+	if (rc < 0) {
+		pr_err("BIF bus_transaction failed, rc=%d\n", rc);
+		return rc;
+	}
+
+	sdev = bif_add_slave(bdev);
+	if (IS_ERR(sdev)) {
+		rc = PTR_ERR(sdev);
+		pr_err("bif_add_slave failed, rc=%d\n", rc);
+		return rc;
+	}
+
+	sdev->bdev->selected_sdev = sdev;
+	sdev->present = true;
+	sdev->slave_addr = slave_addr;
+	rc = bif_parse_slave_data(sdev);
+	if (rc) {
+		pr_err("Failed to parse slave data, addr=0x%02X, rc=%d\n",
+			slave_addr, rc);
+		return rc;
+	}
+
+	return rc;
+}
+
+static int bif_add_known_slaves_from_dt(struct bif_ctrl_dev *bdev,
+					struct device_node *of_node)
+{
+	int len = 0;
+	int rc, i;
+	u32 addr;
+	const __be32 *val;
+
+	mutex_lock(&bif_sdev_list_mutex);
+	mutex_lock(&bdev->mutex);
+
+	val = of_get_property(of_node, "qcom,known-device-addresses", &len);
+	len /= sizeof(u32);
+	if (val && len == 0) {
+		pr_err("qcom,known-device-addresses property is invalid\n");
+		rc = -EINVAL;
+		goto out;
+	}
+
+	for (i = 0; i < len; i++) {
+		addr = be32_to_cpup(val++);
+		if (addr == 0x00 || addr > 0xFF) {
+			rc = -EINVAL;
+			pr_err("qcom,known-device-addresses property contains invalid address=0x%X\n",
+				addr);
+			goto out;
+		}
+		rc = bif_add_known_slave(bdev, addr);
+		if (rc) {
+			pr_err("bif_add_known_slave() failed, rc=%d\n", rc);
+			goto out;
+		}
+	}
+
+out:
+	if (len > 0)
+		bif_remove_duplicate_slaves(bdev);
+
+	mutex_unlock(&bdev->mutex);
+	mutex_unlock(&bif_sdev_list_mutex);
+
+	return rc;
+}
+
+/*
+ * Programs a device address for the specified slave in order to simplify
+ * slave selection in the future.
+ */
+static int bif_assign_slave_dev_addr(struct bif_slave_dev *sdev, u8 dev_addr)
+{
+	int rc;
+	u16 addr;
+
+	if (!sdev->protocol_function) {
+		pr_err("Protocol function not present; cannot set device address.\n");
+		return -ENODEV;
+	}
+
+	addr = PROTOCOL_FUNC_DEV_ADR_ADDR(
+			sdev->protocol_function->protocol_pointer);
+
+	rc = _bif_slave_write(sdev, addr, &dev_addr, 1);
+	if (rc)
+		pr_err("Failed to set slave device address.\n");
+	else
+		sdev->slave_addr = dev_addr;
+
+	return rc;
+}
+
+/* Assigns a unique device address to all slaves which do not have one. */
+static int bif_assign_all_slaves_dev_addr(struct bif_ctrl_dev *bdev)
+{
+	struct bif_slave_dev *sdev;
+	struct bif_slave_dev *sibling;
+	bool duplicate;
+	int rc = 0;
+	u8 dev_addr, first_dev_addr;
+
+	mutex_lock(&bif_sdev_list_mutex);
+	mutex_lock(&bdev->mutex);
+
+	first_dev_addr = next_dev_addr;
+	/*
+	 * Iterate over all partially known UIDs adding new ones as they are
+	 * found.
+	 */
+	list_for_each_entry(sdev, &bif_sdev_list, list) {
+		/*
+		 * Skip slaves without known UIDs, which already have a device
+		 * address or which aren't present.
+		 */
+		if (sdev->unique_id_bits_known != BIF_UNIQUE_ID_BIT_LENGTH
+		    || sdev->slave_addr != 0x00 || !sdev->present)
+			continue;
+
+		do {
+			dev_addr = next_dev_addr;
+			duplicate = false;
+			list_for_each_entry(sibling, &bif_sdev_list, list) {
+				if (sibling->slave_addr == dev_addr) {
+					duplicate = true;
+					break;
+				}
+			}
+
+			next_dev_addr = dev_addr + 1;
+		} while (duplicate && (next_dev_addr != first_dev_addr));
+
+		if (next_dev_addr == first_dev_addr) {
+			pr_err("No more BIF slave device addresses available.\n");
+			rc = -ENODEV;
+			goto out;
+		}
+
+		rc =  bif_assign_slave_dev_addr(sdev, dev_addr);
+		if (rc) {
+			pr_err("Failed to set slave address.\n");
+			goto out;
+		}
+	}
+
+	mutex_unlock(&bdev->mutex);
+	mutex_unlock(&bif_sdev_list_mutex);
+
+	return rc;
+
+out:
+	mutex_unlock(&bdev->mutex);
+	mutex_unlock(&bif_sdev_list_mutex);
+	pr_err("BIF slave device address setting failed, rc=%d\n", rc);
+	return rc;
+}
+
+/**
+ * bdev_get_drvdata() - get the private BIF controller driver data
+ * @bdev:	BIF controller device pointer
+ */
+void *bdev_get_drvdata(struct bif_ctrl_dev *bdev)
+{
+	return bdev->driver_data;
+}
+EXPORT_SYMBOL(bdev_get_drvdata);
+
+static const char * const battery_label[] = {
+	"unknown",
+	"none",
+	"special 1",
+	"special 2",
+	"special 3",
+	"low cost",
+	"smart",
+};
+
+static const char *bif_get_battery_pack_type(int rid_ohm)
+{
+	const char *label = battery_label[0];
+
+	if (rid_ohm > BIF_BATT_RID_SMART_MAX)
+		label = battery_label[1];
+	else if (rid_ohm >= BIF_BATT_RID_SMART_MIN)
+		label = battery_label[6];
+	else if (rid_ohm >= BIF_BATT_RID_LOW_COST_MIN
+			&& rid_ohm <= BIF_BATT_RID_LOW_COST_MAX)
+		label = battery_label[5];
+	else if (rid_ohm >= BIF_BATT_RID_SPECIAL3_MIN
+			&& rid_ohm <= BIF_BATT_RID_SPECIAL3_MAX)
+		label = battery_label[4];
+	else if (rid_ohm >= BIF_BATT_RID_SPECIAL2_MIN
+			&& rid_ohm <= BIF_BATT_RID_SPECIAL2_MAX)
+		label = battery_label[3];
+	else if (rid_ohm >= BIF_BATT_RID_SPECIAL1_MIN
+			&& rid_ohm <= BIF_BATT_RID_SPECIAL1_MAX)
+		label = battery_label[2];
+
+	return label;
+}
+
+/**
+ * bif_ctrl_register() - register a BIF controller with the BIF framework
+ * @bif_desc:		Pointer to BIF controller descriptor
+ * @dev:		Device pointer of the BIF controller
+ * @driver_data:	Private driver data to associate with the BIF controller
+ * @of_node		Pointer to the device tree node of the BIF controller
+ *
+ * Returns a BIF controller device pointer for the controller if registration
+ * is successful or an ERR_PTR if an error occurred.
+ */
+struct bif_ctrl_dev *bif_ctrl_register(struct bif_ctrl_desc *bif_desc,
+	struct device *dev, void *driver_data, struct device_node *of_node)
+{
+	struct bif_ctrl_dev *bdev = ERR_PTR(-EINVAL);
+	struct bif_slave_dev *sdev;
+	bool battery_present = false;
+	int rc, rid_ohm;
+
+	if (!bif_desc) {
+		pr_err("Invalid bif_desc specified\n");
+		return bdev;
+	} else if (!bif_desc->name) {
+		pr_err("BIF name missing\n");
+		return bdev;
+	} else if (!bif_desc->ops) {
+		pr_err("BIF operations missing\n");
+		return bdev;
+	} else if (!bif_desc->ops->bus_transaction
+			|| !bif_desc->ops->bus_transaction_query
+			|| !bif_desc->ops->bus_transaction_read
+			|| !bif_desc->ops->get_bus_state
+			|| !bif_desc->ops->set_bus_state) {
+		pr_err("BIF operation callback function(s) missing\n");
+		return bdev;
+	}
+
+	bdev = kzalloc(sizeof(struct bif_ctrl_dev), GFP_KERNEL);
+	if (bdev == NULL) {
+		pr_err("Memory allocation failed for bif_ctrl_dev\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	mutex_init(&bdev->mutex);
+	INIT_LIST_HEAD(&bdev->list);
+	INIT_DELAYED_WORK(&bdev->enter_irq_mode_work, bif_enter_irq_mode_work);
+	bdev->desc			= bif_desc;
+	bdev->ctrl_dev			= dev;
+	bdev->driver_data		= driver_data;
+	bdev->irq_mode_delay_jiffies	= 2;
+
+	mutex_lock(&bif_ctrl_list_mutex);
+	list_add_tail(&bdev->list, &bif_ctrl_list);
+	mutex_unlock(&bif_ctrl_list_mutex);
+
+	rc = bif_add_all_slaves(bdev);
+	if (rc)
+		pr_debug("Search for all slaves failed, rc=%d\n", rc);
+	rc = bif_add_known_slaves_from_dt(bdev, of_node);
+	if (rc)
+		pr_err("Adding slaves based on device tree addressed failed, rc=%d.\n",
+			rc);
+	rc = bif_assign_all_slaves_dev_addr(bdev);
+	if (rc)
+		pr_err("Failed to set slave device address, rc=%d\n", rc);
+
+	bif_print_slaves();
+
+	if (bdev->desc->ops->get_battery_presence) {
+		rc = bdev->desc->ops->get_battery_presence(bdev);
+		if (rc < 0) {
+			pr_err("Could not determine battery presence, rc=%d\n",
+				rc);
+		} else {
+			battery_present = rc;
+			pr_info("Battery pack present = %c\n", rc ? 'Y' : 'N');
+		}
+	}
+
+	if (bdev->desc->ops->get_battery_rid) {
+		rid_ohm = bdev->desc->ops->get_battery_rid(bdev);
+		if (rid_ohm >= 0)
+			pr_info("Battery pack type = %s (Rid=%d ohm)\n",
+				bif_get_battery_pack_type(rid_ohm), rid_ohm);
+		else
+			pr_err("Could not read Rid, rc=%d\n", rid_ohm);
+	}
+
+	list_for_each_entry(sdev, &bif_sdev_list, list) {
+		if (sdev->present) {
+			battery_present = true;
+			break;
+		}
+	}
+
+	BLOCKING_INIT_NOTIFIER_HEAD(&bdev->bus_change_notifier);
+
+	if (battery_present) {
+		bdev->battery_present = true;
+		rc = blocking_notifier_call_chain(&bdev->bus_change_notifier,
+			BIF_BUS_EVENT_BATTERY_INSERTED, bdev);
+		if (rc)
+			pr_err("Call chain noification failed, rc=%d\n", rc);
+	}
+
+	return bdev;
+}
+EXPORT_SYMBOL(bif_ctrl_register);
+
+/**
+ * bif_ctrl_unregister() - unregisters a BIF controller
+ * @bdev:	BIF controller device pointer
+ */
+void bif_ctrl_unregister(struct bif_ctrl_dev *bdev)
+{
+	if (bdev) {
+		mutex_lock(&bif_ctrl_list_mutex);
+		list_del(&bdev->list);
+		mutex_unlock(&bif_ctrl_list_mutex);
+	}
+}
+EXPORT_SYMBOL(bif_ctrl_unregister);
diff --git a/drivers/bluetooth/bluesleep.c b/drivers/bluetooth/bluesleep.c
index 0d11141..6dc9862 100644
--- a/drivers/bluetooth/bluesleep.c
+++ b/drivers/bluetooth/bluesleep.c
@@ -15,7 +15,7 @@
 
 
    Copyright (C) 2006-2007 - Motorola
-   Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+   Copyright (c) 2008-2010, The Linux Foundation. All rights reserved.
 
    Date         Author           Comment
    -----------  --------------   --------------------------------
diff --git a/drivers/bluetooth/bluetooth-power.c b/drivers/bluetooth/bluetooth-power.c
index 3bf49d1..d7c69db 100644
--- a/drivers/bluetooth/bluetooth-power.c
+++ b/drivers/bluetooth/bluetooth-power.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
@@ -20,9 +20,43 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/rfkill.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/delay.h>
+
+static struct of_device_id ar3002_match_table[] = {
+	{	.compatible = "qca,ar3002" },
+	{}
+};
+
+static int bt_reset_gpio;
 
 static bool previous;
 
+static int bluetooth_power(int on)
+{
+	int rc;
+
+	pr_debug("%s  bt_gpio= %d\n", __func__, bt_reset_gpio);
+	if (on) {
+		rc = gpio_direction_output(bt_reset_gpio, 1);
+		if (rc) {
+			pr_err("%s: Unable to set direction\n", __func__);
+			return rc;
+		}
+		msleep(100);
+	} else {
+		gpio_set_value(bt_reset_gpio, 0);
+		rc = gpio_direction_input(bt_reset_gpio);
+		if (rc) {
+			pr_err("%s: Unable to set direction\n", __func__);
+			return rc;
+		}
+		msleep(100);
+	}
+	return 0;
+}
+
 static int bluetooth_toggle_radio(void *data, bool blocked)
 {
 	int ret = 0;
@@ -90,8 +124,36 @@
 	dev_dbg(&pdev->dev, "%s\n", __func__);
 
 	if (!pdev->dev.platform_data) {
-		dev_err(&pdev->dev, "platform data not initialized\n");
-		return -ENOSYS;
+		/* Update the platform data if the
+		device node exists as part of device tree.*/
+		if (pdev->dev.of_node) {
+			pdev->dev.platform_data = bluetooth_power;
+		} else {
+			dev_err(&pdev->dev, "device node not set\n");
+			return -ENOSYS;
+		}
+	}
+	if (pdev->dev.of_node) {
+		bt_reset_gpio = of_get_named_gpio(pdev->dev.of_node,
+							"qca,bt-reset-gpio", 0);
+		if (bt_reset_gpio < 0) {
+			pr_err("bt-reset-gpio not available");
+			return bt_reset_gpio;
+		}
+	}
+
+	ret = gpio_request(bt_reset_gpio, "bt sys_rst_n");
+	if (ret) {
+		pr_err("%s: unable to request gpio %d (%d)\n",
+			__func__, bt_reset_gpio, ret);
+		return ret;
+	}
+
+	/* When booting up, de-assert BT reset pin */
+	ret = gpio_direction_output(bt_reset_gpio, 0);
+	if (ret) {
+		pr_err("%s: Unable to set direction\n", __func__);
+		return ret;
 	}
 
 	ret = bluetooth_power_rfkill_probe(pdev);
@@ -114,6 +176,7 @@
 	.driver = {
 		.name = "bt_power",
 		.owner = THIS_MODULE,
+		.of_match_table = ar3002_match_table,
 	},
 };
 
diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c
index b5531d6..b6d90d4 100644
--- a/drivers/bluetooth/hci_ath.c
+++ b/drivers/bluetooth/hci_ath.c
@@ -5,7 +5,7 @@
  *  power management protocol extension to H4 to support AR300x Bluetooth Chip.
  *
  *  Copyright (c) 2009-2010 Atheros Communications Inc.
- *  Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  *  Acknowledgements:
  *  This file is based on hci_h4.c, which was written
diff --git a/drivers/bluetooth/hci_ibs.c b/drivers/bluetooth/hci_ibs.c
index acff5a5..84b253b 100644
--- a/drivers/bluetooth/hci_ibs.c
+++ b/drivers/bluetooth/hci_ibs.c
@@ -5,7 +5,7 @@
  *  protocol extension to H4.
  *
  *  Copyright (C) 2007 Texas Instruments, Inc.
- *  Copyright (c) 2010, 2012 Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2010, 2012 The Linux Foundation. All rights reserved.
  *
  *  Acknowledgements:
  *  This file is based on hci_ll.c, which was...
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 5c04693..81f5d32 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -4,7 +4,7 @@
  *
  *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
  *  Copyright (C) 2004-2005  Marcel Holtmann <marcel@holtmann.org>
- *  Copyright (c) 2000-2001, 2010-2012, Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2000-2001, 2010-2012, The Linux Foundation. All rights reserved.
  *
  *
  *  This program is free software; you can redistribute it and/or modify
diff --git a/drivers/bluetooth/hci_smd.c b/drivers/bluetooth/hci_smd.c
index 6030520..90e7263 100644
--- a/drivers/bluetooth/hci_smd.c
+++ b/drivers/bluetooth/hci_smd.c
@@ -2,7 +2,7 @@
  *  HCI_SMD (HCI Shared Memory Driver) is Qualcomm's Shared memory driver
  *  for the BT HCI protocol.
  *
- *  Copyright (c) 2000-2001, 2011-2012 Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2000-2001, 2011-2012 The Linux Foundation. All rights reserved.
  *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
  *  Copyright (C) 2004-2006  Marcel Holtmann <marcel@holtmann.org>
  *
@@ -44,6 +44,19 @@
 #define RX_Q_MONITOR		(500)	/* 500 milli second */
 #define HCI_REGISTER_SET	0
 
+/* SSR state machine to take care of back to back SSR requests
+ * and handling the incomming BT on/off,Airplane mode toggling and
+ * also spuriour SMD open notification while one SSr is in progress
+ */
+#define STATE_SSR_ON 0x1
+#define STATE_SSR_START 0x02
+#define STATE_SSR_CHANNEL_OPEN_PENDING 0x04
+#define STATE_SSR_PENDING_INIT  0x08
+#define STATE_SSR_COMPLETE 0x00
+#define STATE_SSR_OFF STATE_SSR_COMPLETE
+
+static int ssr_state = STATE_SSR_OFF;
+
 
 static int hcismd_set;
 static DEFINE_SEMAPHORE(hci_smd_enable);
@@ -341,25 +354,47 @@
 		break;
 	case SMD_EVENT_OPEN:
 		BT_INFO("opening HCI-SMD channel :%s", EVENT_CHANNEL);
-		hci_smd_open(hdev);
-		open_worker = kzalloc(sizeof(*open_worker), GFP_ATOMIC);
-		if (!open_worker) {
-			BT_ERR("Out of memory");
-			break;
+		BT_DBG("SSR state is : %x", ssr_state);
+		if ((ssr_state == STATE_SSR_OFF) ||
+			(ssr_state == STATE_SSR_CHANNEL_OPEN_PENDING)) {
+
+			hci_smd_open(hdev);
+			open_worker = kzalloc(sizeof(*open_worker), GFP_ATOMIC);
+			if (!open_worker) {
+				BT_ERR("Out of memory");
+				break;
+			}
+			if (ssr_state == STATE_SSR_CHANNEL_OPEN_PENDING) {
+				ssr_state = STATE_SSR_PENDING_INIT;
+				BT_INFO("SSR state is : %x", ssr_state);
+			}
+			INIT_WORK(open_worker, hci_dev_smd_open);
+			schedule_work(open_worker);
+
 		}
-		INIT_WORK(open_worker, hci_dev_smd_open);
-		schedule_work(open_worker);
 		break;
 	case SMD_EVENT_CLOSE:
 		BT_INFO("Closing HCI-SMD channel :%s", EVENT_CHANNEL);
-		hci_smd_close(hdev);
-		reset_worker = kzalloc(sizeof(*reset_worker), GFP_ATOMIC);
-		if (!reset_worker) {
-			BT_ERR("Out of memory");
-			break;
+		BT_DBG("SSR state is : %x", ssr_state);
+		if ((ssr_state == STATE_SSR_OFF) ||
+			(ssr_state == (STATE_SSR_PENDING_INIT))) {
+
+			hci_smd_close(hdev);
+			reset_worker = kzalloc(sizeof(*reset_worker),
+							GFP_ATOMIC);
+			if (!reset_worker) {
+				BT_ERR("Out of memory");
+				break;
+			}
+			ssr_state = STATE_SSR_ON;
+			BT_INFO("SSR state is : %x", ssr_state);
+			INIT_WORK(reset_worker, hci_dev_restart);
+			schedule_work(reset_worker);
+
+		} else if (ssr_state & STATE_SSR_ON) {
+				BT_ERR("SSR state is : %x", ssr_state);
 		}
-		INIT_WORK(reset_worker, hci_dev_restart);
-		schedule_work(reset_worker);
+
 		break;
 	default:
 		break;
@@ -403,19 +438,37 @@
 {
 	struct hci_dev *hdev;
 
-	hdev = hsmd->hdev;
-	if (test_and_set_bit(HCI_REGISTER_SET, &hsmd->flags)) {
-		BT_ERR("HCI device registered already");
+	if (hsmd->hdev)
+		hdev = hsmd->hdev;
+	else {
+		BT_ERR("hdev is NULL");
 		return 0;
-	} else
-		BT_INFO("HCI device registration is starting");
-	if (hci_register_dev(hdev) < 0) {
-		BT_ERR("Can't register HCI device");
-		hci_free_dev(hdev);
-		hsmd->hdev = NULL;
-		clear_bit(HCI_REGISTER_SET, &hsmd->flags);
-		return -ENODEV;
 	}
+	/* Allow the incomming SSR even the prev one at PENDING INIT STATE
+	 * since clenup need to be started again from the beging and ignore
+	 *  or bypass the prev one
+	 */
+	if ((ssr_state == STATE_SSR_OFF) ||
+			(ssr_state == STATE_SSR_PENDING_INIT)) {
+
+		if (test_and_set_bit(HCI_REGISTER_SET, &hsmd->flags)) {
+			BT_ERR("HCI device registered already");
+			return 0;
+		} else
+			BT_INFO("HCI device registration is starting");
+		if (hci_register_dev(hdev) < 0) {
+			BT_ERR("Can't register HCI device");
+			hci_free_dev(hdev);
+			hsmd->hdev = NULL;
+			clear_bit(HCI_REGISTER_SET, &hsmd->flags);
+			return -ENODEV;
+		}
+		if (ssr_state == STATE_SSR_PENDING_INIT) {
+			ssr_state = STATE_SSR_COMPLETE;
+			BT_INFO("SSR state is : %x", ssr_state);
+		}
+	} else if (ssr_state)
+		BT_ERR("Registration called in invalid context");
 	return 0;
 }
 
@@ -449,7 +502,10 @@
 	 */
 	setup_timer(&hsmd->rx_q_timer, schedule_timer,
 			(unsigned long) hsmd->hdev);
-
+	if (ssr_state == STATE_SSR_START) {
+		ssr_state = STATE_SSR_CHANNEL_OPEN_PENDING;
+		BT_INFO("SSR state is : %x", ssr_state);
+	}
 	/* Open the SMD Channel and device and register the callback function */
 	rc = smd_named_open_on_edge(EVENT_CHANNEL, SMD_APPS_WCNSS,
 			&hsmd->event_channel, hdev, hci_smd_notify_event);
@@ -478,21 +534,25 @@
 static void hci_smd_deregister_dev(struct hci_smd_data *hsmd)
 {
 	tasklet_kill(&hs.rx_task);
-
+	if (ssr_state)
+		BT_DBG("SSR state is : %x", ssr_state);
+	/* Though the hci_smd driver is not registered with the hci
+	 * need to close the opened channels as a part of cleaup
+	 */
 	if (!test_and_clear_bit(HCI_REGISTER_SET, &hsmd->flags)) {
 		BT_ERR("HCI device un-registered already");
-		return;
-	} else
+	} else {
 		BT_INFO("HCI device un-registration going on");
-	if (hsmd->hdev) {
-		if (hci_unregister_dev(hsmd->hdev) < 0)
-			BT_ERR("Can't unregister HCI device %s",
-				hsmd->hdev->name);
 
-		hci_free_dev(hsmd->hdev);
-		hsmd->hdev = NULL;
+		if (hsmd->hdev) {
+			if (hci_unregister_dev(hsmd->hdev) < 0)
+				BT_ERR("Can't unregister HCI device %s",
+					hsmd->hdev->name);
+
+			hci_free_dev(hsmd->hdev);
+			hsmd->hdev = NULL;
+		}
 	}
-
 	smd_close(hs.event_channel);
 	smd_close(hs.data_channel);
 
@@ -513,23 +573,47 @@
 {
 	down(&hci_smd_enable);
 	restart_in_progress = 1;
+	BT_DBG("SSR state is : %x", ssr_state);
+
+	if (ssr_state == STATE_SSR_ON) {
+		ssr_state = STATE_SSR_START;
+		BT_INFO("SSR state is : %x", ssr_state);
+	} else {
+		BT_ERR("restart triggered in wrong context");
+		up(&hci_smd_enable);
+		kfree(worker);
+		return;
+	}
 	hci_smd_deregister_dev(&hs);
 	hci_smd_register_smd(&hs);
 	up(&hci_smd_enable);
 	kfree(worker);
+
 }
 
 static void hci_dev_smd_open(struct work_struct *worker)
 {
 	down(&hci_smd_enable);
+	if (ssr_state)
+		BT_DBG("SSR state is : %x", ssr_state);
+
+	if ((ssr_state != STATE_SSR_OFF) &&
+			(ssr_state  !=  (STATE_SSR_PENDING_INIT))) {
+		up(&hci_smd_enable);
+		kfree(worker);
+		return;
+	}
+
 	if (restart_in_progress == 1) {
 		/* Allow wcnss to initialize */
 		restart_in_progress = 0;
 		msleep(10000);
 	}
+
 	hci_smd_hci_register_dev(&hs);
 	up(&hci_smd_enable);
 	kfree(worker);
+
 }
 
 static int hcismd_set_enable(const char *val, struct kernel_param *kp)
@@ -545,14 +629,23 @@
 	if (ret)
 		goto done;
 
+	/* Ignore the all incomming register de-register requests in case of
+	 * SSR is in-progress
+	 */
 	switch (hcismd_set) {
 
 	case 1:
-		if (hs.hdev == NULL)
+		if ((hs.hdev == NULL) && (ssr_state == STATE_SSR_OFF))
 			hci_smd_register_smd(&hs);
+		else if (ssr_state)
+			BT_ERR("SSR is in progress,state is : %x", ssr_state);
+
 	break;
 	case 0:
-		hci_smd_deregister_dev(&hs);
+		if (ssr_state == STATE_SSR_OFF)
+			hci_smd_deregister_dev(&hs);
+		else if (ssr_state)
+			BT_ERR("SSR is in progress,state is : %x", ssr_state);
 	break;
 	default:
 		ret = -EFAULT;
@@ -569,6 +662,7 @@
 	wake_lock_init(&hs.wake_lock_tx, WAKE_LOCK_SUSPEND,
 			 "msm_smd_Tx");
 	restart_in_progress = 0;
+	ssr_state = STATE_SSR_OFF;
 	hs.hdev = NULL;
 	return 0;
 }
diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h
index 123fc24..b9efe30 100644
--- a/drivers/bluetooth/hci_uart.h
+++ b/drivers/bluetooth/hci_uart.h
@@ -4,7 +4,7 @@
  *
  *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
  *  Copyright (C) 2004-2005  Marcel Holtmann <marcel@holtmann.org>
- *  Copyright (c) 2000-2001, 2010, 2012 Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2000-2001, 2010, 2012 The Linux Foundation. All rights reserved.
  *
  *
  *  This program is free software; you can redistribute it and/or modify
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index 822da91..73fe5d6 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -11,8 +11,106 @@
  * GNU General Public License for more details.
  *
  */
+#include "adsprpc_shared.h"
+
+#include <linux/slab.h>
+#include <linux/completion.h>
+#include <linux/pagemap.h>
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/cdev.h>
+#include <linux/list.h>
+#include <linux/hash.h>
+#include <linux/msm_ion.h>
+#include <mach/msm_smd.h>
+#include <mach/ion.h>
 #include <linux/scatterlist.h>
-#include "adsprpc.h"
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <linux/device.h>
+
+#ifndef ION_ADSPRPC_HEAP_ID
+#define ION_ADSPRPC_HEAP_ID ION_AUDIO_HEAP_ID
+#endif /*ION_ADSPRPC_HEAP_ID*/
+
+#define RPC_TIMEOUT	(5 * HZ)
+#define RPC_HASH_BITS	5
+#define RPC_HASH_SZ	(1 << RPC_HASH_BITS)
+#define BALIGN		32
+
+#define LOCK_MMAP(kernel)\
+		do {\
+			if (!kernel)\
+				down_read(&current->mm->mmap_sem);\
+		} while (0)
+
+#define UNLOCK_MMAP(kernel)\
+		do {\
+			if (!kernel)\
+				up_read(&current->mm->mmap_sem);\
+		} while (0)
+
+
+static inline uint32_t buf_page_start(void *buf)
+{
+	uint32_t start = (uint32_t) buf & PAGE_MASK;
+	return start;
+}
+
+static inline uint32_t buf_page_offset(void *buf)
+{
+	uint32_t offset = (uint32_t) buf & (PAGE_SIZE - 1);
+	return offset;
+}
+
+static inline int buf_num_pages(void *buf, int len)
+{
+	uint32_t start = buf_page_start(buf) >> PAGE_SHIFT;
+	uint32_t end = (((uint32_t) buf + len - 1) & PAGE_MASK) >> PAGE_SHIFT;
+	int nPages = end - start + 1;
+	return nPages;
+}
+
+static inline uint32_t buf_page_size(uint32_t size)
+{
+	uint32_t sz = (size + (PAGE_SIZE - 1)) & PAGE_MASK;
+	return sz > PAGE_SIZE ? sz : PAGE_SIZE;
+}
+
+static inline int buf_get_pages(void *addr, int sz, int nr_pages, int access,
+				  struct smq_phy_page *pages, int nr_elems)
+{
+	struct vm_area_struct *vma;
+	uint32_t start = buf_page_start(addr);
+	uint32_t len = nr_pages << PAGE_SHIFT;
+	unsigned long pfn;
+	int n = -1, err = 0;
+
+	VERIFY(err, 0 != access_ok(access ? VERIFY_WRITE : VERIFY_READ,
+			      (void __user *)start, len));
+	if (err)
+		goto bail;
+	VERIFY(err, 0 != (vma = find_vma(current->mm, start)));
+	if (err)
+		goto bail;
+	VERIFY(err, ((uint32_t)addr + sz) <= vma->vm_end);
+	if (err)
+		goto bail;
+	n = 0;
+	VERIFY(err, 0 == follow_pfn(vma, start, &pfn));
+	if (err)
+		goto bail;
+	VERIFY(err, nr_elems > 0);
+	if (err)
+		goto bail;
+	pages->addr = __pfn_to_phys(pfn);
+	pages->size = len;
+	n++;
+ bail:
+	return n;
+}
 
 struct smq_invoke_ctx {
 	struct completion work;
@@ -32,6 +130,8 @@
 	struct completion work;
 	struct ion_client *iclient;
 	struct cdev cdev;
+	struct class *class;
+	struct device *dev;
 	dev_t dev_no;
 	spinlock_t wrlock;
 	spinlock_t hlock;
@@ -249,7 +349,6 @@
 	args = (void *)((char *)pbuf->virt + used);
 	rlen = pbuf->size - used;
 	for (i = 0; i < inbufs + outbufs; ++i) {
-		int num;
 
 		rpra[i].buf.len = pra[i].buf.len;
 		if (!rpra[i].buf.len)
@@ -276,18 +375,12 @@
 			args = pbuf->virt;
 			rlen = pbuf->size;
 		}
-		num = buf_num_pages(args, pra[i].buf.len);
-		if (pbuf == ibuf) {
-			list[i].num = num;
-			list[i].pgidx = 0;
-		} else {
-			list[i].num = 1;
-			pages[list[i].pgidx].addr =
-				buf_page_start((void *)(pbuf->phys +
-							 (pbuf->size - rlen)));
-			pages[list[i].pgidx].size =
-				buf_page_size(pra[i].buf.len);
-		}
+		list[i].num = 1;
+		pages[list[i].pgidx].addr =
+			buf_page_start((void *)(pbuf->phys +
+						 (pbuf->size - rlen)));
+		pages[list[i].pgidx].size =
+			buf_page_size(pra[i].buf.len);
 		if (i < inbufs) {
 			if (!kernel) {
 				VERIFY(err, 0 == copy_from_user(args,
@@ -485,9 +578,9 @@
 static void free_dev(struct fastrpc_device *dev)
 {
 	if (dev) {
-		module_put(THIS_MODULE);
 		free_mem(&dev->buf);
 		kfree(dev);
+		module_put(THIS_MODULE);
 	}
 }
 
@@ -609,8 +702,10 @@
 		wait_for_completion(&ctx->work);
 	}
 	context_free(ctx);
+
 	for (i = 0, b = abufs; i < nbufs; ++i, ++b)
 		free_mem(b);
+
 	kfree(abufs);
 	if (dev) {
 		add_dev(me, dev);
@@ -768,11 +863,24 @@
 	VERIFY(err, 0 == cdev_add(&me->cdev, MKDEV(MAJOR(me->dev_no), 0), 1));
 	if (err)
 		goto bail;
-	pr_info("'mknod /dev/%s c %d 0'\n", DEVICE_NAME, MAJOR(me->dev_no));
+	me->class = class_create(THIS_MODULE, "chardrv");
+	VERIFY(err, !IS_ERR(me->class));
+	if (err)
+		goto bail;
+	me->dev = device_create(me->class, NULL, MKDEV(MAJOR(me->dev_no), 0),
+				NULL, DEVICE_NAME);
+	VERIFY(err, !IS_ERR(me->dev));
+	if (err)
+		goto bail;
+	pr_info("'created /dev/%s c %d 0'\n", DEVICE_NAME, MAJOR(me->dev_no));
  bail:
 	if (err) {
 		if (me->dev_no)
 			unregister_chrdev_region(me->dev_no, 1);
+		if (me->class)
+			class_destroy(me->class);
+		if (me->cdev.owner)
+			cdev_del(&me->cdev);
 		fastrpc_deinit();
 	}
 	return err;
@@ -783,6 +891,8 @@
 	struct fastrpc_apps *me = &gfa;
 
 	fastrpc_deinit();
+	device_destroy(me->class, MKDEV(MAJOR(me->dev_no), 0));
+	class_destroy(me->class);
 	cdev_del(&me->cdev);
 	unregister_chrdev_region(me->dev_no, 1);
 }
diff --git a/drivers/char/adsprpc.h b/drivers/char/adsprpc.h
deleted file mode 100644
index 3f1b4a7..0000000
--- a/drivers/char/adsprpc.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-#ifndef ADSPRPC_H
-#define ADSPRPC_H
-
-#include <linux/slab.h>
-#include <linux/completion.h>
-#include <linux/pagemap.h>
-#include <linux/mm.h>
-#include <linux/fs.h>
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/cdev.h>
-#include <linux/list.h>
-#include <linux/hash.h>
-#include <linux/msm_ion.h>
-#include <mach/msm_smd.h>
-#include <mach/ion.h>
-#include "adsprpc_shared.h"
-
-#ifndef ION_ADSPRPC_HEAP_ID
-#define ION_ADSPRPC_HEAP_ID ION_AUDIO_HEAP_ID
-#endif
-
-#define RPC_TIMEOUT	(5 * HZ)
-#define RPC_HASH_BITS	5
-#define RPC_HASH_SZ	(1 << RPC_HASH_BITS)
-#define BALIGN		32
-
-#define LOCK_MMAP(kernel)\
-		do {\
-			if (!kernel)\
-				down_read(&current->mm->mmap_sem);\
-		} while (0)
-
-#define UNLOCK_MMAP(kernel)\
-		do {\
-			if (!kernel)\
-				up_read(&current->mm->mmap_sem);\
-		} while (0)
-
-
-static inline uint32_t buf_page_start(void *buf)
-{
-	uint32_t start = (uint32_t) buf & PAGE_MASK;
-	return start;
-}
-
-static inline uint32_t buf_page_offset(void *buf)
-{
-	uint32_t offset = (uint32_t) buf & (PAGE_SIZE - 1);
-	return offset;
-}
-
-static inline int buf_num_pages(void *buf, int len)
-{
-	uint32_t start = buf_page_start(buf) >> PAGE_SHIFT;
-	uint32_t end = (((uint32_t) buf + len - 1) & PAGE_MASK) >> PAGE_SHIFT;
-	int nPages = end - start + 1;
-	return nPages;
-}
-
-static inline uint32_t buf_page_size(uint32_t size)
-{
-	uint32_t sz = (size + (PAGE_SIZE - 1)) & PAGE_MASK;
-	return sz > PAGE_SIZE ? sz : PAGE_SIZE;
-}
-
-static inline int buf_get_pages(void *addr, int sz, int nr_pages, int access,
-				  struct smq_phy_page *pages, int nr_elems)
-{
-	struct vm_area_struct *vma;
-	uint32_t start = buf_page_start(addr);
-	uint32_t len = nr_pages << PAGE_SHIFT;
-	unsigned long pfn;
-	int n = -1, err = 0;
-
-	VERIFY(err, 0 != access_ok(access ? VERIFY_WRITE : VERIFY_READ,
-			      (void __user *)start, len));
-	if (err)
-		goto bail;
-	VERIFY(err, 0 != (vma = find_vma(current->mm, start)));
-	if (err)
-		goto bail;
-	VERIFY(err, ((uint32_t)addr + sz) <= vma->vm_end);
-	if (err)
-		goto bail;
-	n = 0;
-	VERIFY(err, 0 == follow_pfn(vma, start, &pfn));
-	if (err)
-		goto bail;
-	VERIFY(err, nr_elems > 0);
-	if (err)
-		goto bail;
-	pages->addr = __pfn_to_phys(pfn);
-	pages->size = len;
-	n++;
- bail:
-	return n;
-}
-
-#endif
diff --git a/drivers/char/adsprpc_shared.h b/drivers/char/adsprpc_shared.h
index dc6ab6f..8932d3c 100644
--- a/drivers/char/adsprpc_shared.h
+++ b/drivers/char/adsprpc_shared.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -14,6 +14,8 @@
 #ifndef ADSPRPC_SHARED_H
 #define ADSPRPC_SHARED_H
 
+#include <linux/types.h>
+
 #define FASTRPC_IOCTL_INVOKE _IOWR('R', 1, struct fastrpc_ioctl_invoke)
 #define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp"
 #define DEVICE_NAME      "adsprpc-smd"
diff --git a/drivers/char/csdio.c b/drivers/char/csdio.c
index ca7e986..85306d3 100644
--- a/drivers/char/csdio.c
+++ b/drivers/char/csdio.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * 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
@@ -1068,7 +1068,7 @@
 module_init(csdio_init);
 module_exit(csdio_exit);
 
-MODULE_AUTHOR("Code Aurora Forum");
+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 d4b1856..23dd5a1 100644
--- a/drivers/char/diag/diag_dci.c
+++ b/drivers/char/diag/diag_dci.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -152,7 +152,8 @@
 	uint16_t event_id, event_id_packet;
 	uint8_t *event_mask_ptr, byte_mask, payload_len;
 	uint8_t event_data[MAX_EVENT_SIZE], timestamp[8];
-	int i, byte_index, bit_index, length, temp_len;
+	unsigned int byte_index;
+	int i, bit_index, length, temp_len;
 	int total_event_len, payload_len_field, timestamp_len;
 	struct diag_dci_client_tbl *entry;
 
@@ -227,7 +228,8 @@
 {
 	uint16_t log_code, item_num;
 	uint8_t equip_id, *log_mask_ptr, byte_mask;
-	int i, byte_index, found = 0;
+	unsigned int byte_index;
+	int i, found = 0;
 	struct diag_dci_client_tbl *entry;
 
 	log_code = *(uint16_t *)(buf+6);
@@ -385,6 +387,10 @@
 
 	/* remove UID from user space pkt before sending to peripheral */
 	buf = buf + 4;
+	if (len > APPS_BUF_SIZE - 10) {
+		pr_err("diag: dci: buffer overwrite possible since payload bigger than buf size\n");
+		return -EIO;
+	}
 	len = len - 4;
 	mutex_lock(&driver->dci_mutex);
 	/* prepare DCI packet */
@@ -396,7 +402,6 @@
 		driver->req_tracking_tbl[index].tag;
 	for (i = 0; i < len; i++)
 		driver->apps_dci_buf[i+9] = *(buf+i);
-
 	driver->apps_dci_buf[9+len] = CONTROL_CHAR; /* end */
 
 	for (i = 0; i < NUM_SMD_DCI_CHANNELS; i++) {
@@ -448,12 +453,12 @@
 {
 	unsigned char *temp = buf;
 	uint16_t subsys_cmd_code, log_code, item_num;
-	int subsys_id, cmd_code, i, ret = -1, index = -1, found = 0;
+	int subsys_id, cmd_code, ret = -1, index = -1, found = 0, read_len = 0;
 	struct diag_master_table entry;
-	int count, set_mask, num_codes, byte_index, bit_index, event_id;
+	int count, set_mask, num_codes, bit_index, event_id, offset = 0, i;
+	unsigned int byte_index;
 	uint8_t equip_id, *log_mask_ptr, *head_log_mask_ptr, byte_mask;
 	uint8_t *event_mask_ptr;
-	int offset = 0;
 
 	if (!driver->smd_dci[MODEM_DATA].ch) {
 		pr_err("diag: DCI smd channel for peripheral %d not valid for dci updates\n",
@@ -529,19 +534,30 @@
 		}
 		/* Extract each log code and put in client table */
 		temp += 4;
+		read_len += 4;
 		set_mask = *(int *)temp;
 		temp += 4;
+		read_len += 4;
 		num_codes = *(int *)temp;
 		temp += 4;
+		read_len += 4;
 
 		head_log_mask_ptr = driver->dci_client_tbl[i].dci_log_mask;
 		pr_debug("diag: head of dci log mask %p\n", head_log_mask_ptr);
 		count = 0; /* iterator for extracting log codes */
 		while (count < num_codes) {
+			if (read_len >= USER_SPACE_DATA) {
+				pr_err("diag: dci: Log type, possible buffer overflow\n");
+				return -EIO;
+			}
 			log_code = *(uint16_t *)temp;
 			equip_id = LOG_GET_EQUIP_ID(log_code);
 			item_num = LOG_GET_ITEM_NUM(log_code);
 			byte_index = item_num/8 + 2;
+			if (byte_index >= (DCI_MAX_ITEMS_PER_LOG_CODE+2)) {
+				pr_err("diag: dci: Log type, invalid byte index\n");
+				return ret;
+			}
 			byte_mask = 0x01 << (item_num % 8);
 			/*
 			 * Parse through log mask table and find
@@ -550,7 +566,7 @@
 			log_mask_ptr = head_log_mask_ptr;
 			found = 0;
 			offset = 0;
-			while (log_mask_ptr) {
+			while (log_mask_ptr && (offset < DCI_LOG_MASK_SIZE)) {
 				if (*log_mask_ptr == equip_id) {
 					found = 1;
 					pr_debug("diag: find equip id = %x at %p\n",
@@ -578,6 +594,7 @@
 				offset, byte_index,
 				byte_mask);
 			temp += 2;
+			read_len += 2;
 			count++;
 			ret = DIAG_DCI_NO_ERROR;
 		}
@@ -600,17 +617,28 @@
 		}
 		/* Extract each log code and put in client table */
 		temp += 4;
+		read_len += 4;
 		set_mask = *(int *)temp;
 		temp += 4;
+		read_len += 4;
 		num_codes = *(int *)temp;
 		temp += 4;
+		read_len += 4;
 
 		event_mask_ptr = driver->dci_client_tbl[i].dci_event_mask;
 		pr_debug("diag: head of dci event mask %p\n", event_mask_ptr);
 		count = 0; /* iterator for extracting log codes */
 		while (count < num_codes) {
+			if (read_len >= USER_SPACE_DATA) {
+				pr_err("diag: dci: Event type, possible buffer overflow\n");
+				return -EIO;
+			}
 			event_id = *(int *)temp;
 			byte_index = event_id/8;
+			if (byte_index >= DCI_EVENT_MASK_SIZE) {
+				pr_err("diag: dci: Event type, invalid byte index\n");
+				return ret;
+			}
 			bit_index = event_id % 8;
 			byte_mask = 0x1 << bit_index;
 			/*
@@ -624,6 +652,7 @@
 			/* add to cumulative mask */
 			update_dci_cumulative_event_mask(byte_index, byte_mask);
 			temp += sizeof(int);
+			read_len += sizeof(int);
 			count++;
 			ret = DIAG_DCI_NO_ERROR;
 		}
@@ -704,7 +733,7 @@
 	return ret;
 }
 
-void update_dci_cumulative_log_mask(int offset, int byte_index,
+void update_dci_cumulative_log_mask(int offset, unsigned int byte_index,
 						uint8_t byte_mask)
 {
 	int i;
diff --git a/drivers/char/diag/diag_dci.h b/drivers/char/diag/diag_dci.h
index af89ac8..56d1b91 100644
--- a/drivers/char/diag/diag_dci.h
+++ b/drivers/char/diag/diag_dci.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -88,7 +88,7 @@
 void extract_dci_pkt_rsp(unsigned char *buf);
 /* DCI Log streaming functions */
 void create_dci_log_mask_tbl(unsigned char *tbl_buf);
-void update_dci_cumulative_log_mask(int offset, int byte_index,
+void update_dci_cumulative_log_mask(int offset, unsigned int byte_index,
 						uint8_t byte_mask);
 int diag_send_dci_log_mask(smd_channel_t *ch);
 void extract_dci_log(unsigned char *buf);
diff --git a/drivers/char/diag/diag_debugfs.c b/drivers/char/diag/diag_debugfs.c
index d852d75..76490c8 100644
--- a/drivers/char/diag/diag_debugfs.c
+++ b/drivers/char/diag/diag_debugfs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -17,10 +17,12 @@
 #include "diagchar.h"
 #include "diagfwd.h"
 #include "diagfwd_bridge.h"
+#include "diagfwd_hsic.h"
 
 #define DEBUG_BUF_SIZE	4096
 static struct dentry *diag_dbgfs_dent;
 static int diag_dbgfs_table_index;
+static int diag_dbgfs_finished;
 
 static ssize_t diag_dbgfs_read_status(struct file *file, char __user *ubuf,
 				      size_t count, loff_t *ppos)
@@ -233,61 +235,115 @@
 {
 	char *buf;
 	int ret;
+	int i;
+	int bytes_remaining;
+	int bytes_in_buffer = 0;
+	int bytes_written;
+	int buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
+	int bytes_hsic_inited = 45;
+	int bytes_hsic_not_inited = 410;
 
-	buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
+	if (diag_dbgfs_finished) {
+		diag_dbgfs_finished = 0;
+		return 0;
+	}
+
+	buf = kzalloc(sizeof(char) * buf_size, GFP_KERNEL);
 	if (!buf) {
 		pr_err("diag: %s, Error allocating memory\n", __func__);
 		return -ENOMEM;
 	}
 
-	ret = scnprintf(buf, DEBUG_BUF_SIZE,
-		"hsic ch: %d\n"
-		"hsic_inited: %d\n"
-		"hsic enabled: %d\n"
-		"hsic_opened: %d\n"
-		"hsic_suspend: %d\n"
-		"in_busy_hsic_read_on_device: %d\n"
-		"in_busy_hsic_write: %d\n"
-		"count_hsic_pool: %d\n"
-		"count_hsic_write_pool: %d\n"
-		"diag_hsic_pool: %x\n"
-		"diag_hsic_write_pool: %x\n"
-		"HSIC write_len: %d\n"
-		"num_hsic_buf_tbl_entries: %d\n"
-		"HSIC usb_connected: %d\n"
-		"HSIC diag_read_work: %d\n"
-		"diag_read_hsic_work: %d\n"
-		"diag_disconnect_work: %d\n"
-		"diag_usb_read_complete_work: %d\n"
+	bytes_remaining = buf_size;
+
+	/* Only one smux for now */
+	bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining,
+		"Values for SMUX instance: 0\n"
 		"smux ch: %d\n"
 		"smux enabled %d\n"
 		"smux in busy %d\n"
-		"smux connected %d\n",
-		driver->hsic_ch,
-		driver->hsic_inited,
-		driver->hsic_device_enabled,
-		driver->hsic_device_opened,
-		driver->hsic_suspend,
-		driver->in_busy_hsic_read_on_device,
-		driver->in_busy_hsic_write,
-		driver->count_hsic_pool,
-		driver->count_hsic_write_pool,
-		(unsigned int)driver->diag_hsic_pool,
-		(unsigned int)driver->diag_hsic_write_pool,
-			diag_bridge[HSIC].write_len,
-		driver->num_hsic_buf_tbl_entries,
-			diag_bridge[HSIC].usb_connected,
-			work_pending(&(diag_bridge[HSIC].diag_read_work)),
-		work_pending(&(driver->diag_read_hsic_work)),
-		work_pending(&(driver->diag_disconnect_work)),
-		work_pending(&(diag_bridge[HSIC].usb_read_complete_work)),
+		"smux connected %d\n\n",
 		driver->lcid,
 		driver->diag_smux_enabled,
 		driver->in_busy_smux,
 		driver->smux_connected);
 
-	ret = simple_read_from_buffer(ubuf, count, ppos, buf, ret);
+	bytes_in_buffer += bytes_written;
+	bytes_remaining = buf_size - bytes_in_buffer;
 
+	bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining,
+		"HSIC diag_disconnect_work: %d\n",
+		work_pending(&(driver->diag_disconnect_work)));
+
+	bytes_in_buffer += bytes_written;
+	bytes_remaining = buf_size - bytes_in_buffer;
+
+	for (i = 0; i < MAX_HSIC_CH; i++) {
+		if (diag_hsic[i].hsic_inited) {
+			/* Check if there is room to add another HSIC entry */
+			if (bytes_remaining < bytes_hsic_inited)
+				break;
+			bytes_written = scnprintf(buf+bytes_in_buffer,
+							bytes_remaining,
+			"Values for HSIC Instance: %d\n"
+			"hsic ch: %d\n"
+			"hsic_inited: %d\n"
+			"hsic enabled: %d\n"
+			"hsic_opened: %d\n"
+			"hsic_suspend: %d\n"
+			"in_busy_hsic_read_on_device: %d\n"
+			"in_busy_hsic_write: %d\n"
+			"count_hsic_pool: %d\n"
+			"count_hsic_write_pool: %d\n"
+			"diag_hsic_pool: %x\n"
+			"diag_hsic_write_pool: %x\n"
+			"HSIC write_len: %d\n"
+			"num_hsic_buf_tbl_entries: %d\n"
+			"HSIC usb_connected: %d\n"
+			"HSIC diag_read_work: %d\n"
+			"diag_read_hsic_work: %d\n"
+			"diag_usb_read_complete_work: %d\n\n",
+			i,
+			diag_hsic[i].hsic_ch,
+			diag_hsic[i].hsic_inited,
+			diag_hsic[i].hsic_device_enabled,
+			diag_hsic[i].hsic_device_opened,
+			diag_hsic[i].hsic_suspend,
+			diag_hsic[i].in_busy_hsic_read_on_device,
+			diag_hsic[i].in_busy_hsic_write,
+			diag_hsic[i].count_hsic_pool,
+			diag_hsic[i].count_hsic_write_pool,
+			(unsigned int)diag_hsic[i].diag_hsic_pool,
+			(unsigned int)diag_hsic[i].diag_hsic_write_pool,
+			diag_bridge[i].write_len,
+			diag_hsic[i].num_hsic_buf_tbl_entries,
+			diag_bridge[i].usb_connected,
+			work_pending(&(diag_bridge[i].diag_read_work)),
+			work_pending(&(diag_hsic[i].diag_read_hsic_work)),
+			work_pending(&(diag_bridge[i].usb_read_complete_work)));
+			if (bytes_written > bytes_hsic_inited)
+				bytes_hsic_inited = bytes_written;
+		} else {
+			/* Check if there is room to add another HSIC entry */
+			if (bytes_remaining < bytes_hsic_not_inited)
+				break;
+			bytes_written = scnprintf(buf+bytes_in_buffer,
+				bytes_remaining,
+				"HSIC Instance: %d has not been initialized\n\n",
+				i);
+			if (bytes_written > bytes_hsic_not_inited)
+				bytes_hsic_not_inited = bytes_written;
+		}
+
+		bytes_in_buffer += bytes_written;
+
+		bytes_remaining = buf_size - bytes_in_buffer;
+	}
+
+	*ppos = 0;
+	ret = simple_read_from_buffer(ubuf, count, ppos, buf, bytes_in_buffer);
+
+	diag_dbgfs_finished = 1;
 	kfree(buf);
 	return ret;
 }
@@ -330,6 +386,7 @@
 #endif
 
 	diag_dbgfs_table_index = 0;
+	diag_dbgfs_finished = 0;
 }
 
 void diag_debugfs_cleanup(void)
diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c
index 2a85a00..0c93101 100644
--- a/drivers/char/diag/diag_masks.c
+++ b/drivers/char/diag/diag_masks.c
@@ -26,6 +26,9 @@
 #define ALL_SSID		-1
 #define MAX_SSID_PER_RANGE	100
 
+#define FEATURE_MASK_LEN_BYTES		1
+#define APPS_RESPOND_LOG_ON_DEMAND	0x04
+
 struct mask_info {
 	int equip_id;
 	int num_items;
@@ -309,6 +312,7 @@
 						smd_info->peripheral);
 	diag_send_log_mask_update(smd_info->ch, ALL_EQUIP_ID);
 	diag_send_event_mask_update(smd_info->ch, diag_event_num_bytes);
+	diag_send_feature_mask_update(smd_info->ch, smd_info->peripheral);
 
 	smd_info->notify_context = 0;
 }
@@ -461,6 +465,42 @@
 	mutex_unlock(&driver->diag_cntl_mutex);
 }
 
+void diag_send_feature_mask_update(smd_channel_t *ch, int proc)
+{
+	void *buf = driver->buf_feature_mask_update;
+	int header_size = sizeof(struct diag_ctrl_feature_mask);
+	int wr_size = -ENOMEM, retry_count = 0, timer;
+	uint8_t feature_byte = 0;
+
+	mutex_lock(&driver->diag_cntl_mutex);
+	/* send feature mask update */
+	driver->feature_mask->ctrl_pkt_id = DIAG_CTRL_MSG_FEATURE;
+	driver->feature_mask->ctrl_pkt_data_len = 4 + FEATURE_MASK_LEN_BYTES;
+	driver->feature_mask->feature_mask_len = FEATURE_MASK_LEN_BYTES;
+	memcpy(buf, driver->feature_mask, header_size);
+	feature_byte |= APPS_RESPOND_LOG_ON_DEMAND;
+	memcpy(buf+header_size, &feature_byte, FEATURE_MASK_LEN_BYTES);
+
+	if (ch) {
+		while (retry_count < 3) {
+			wr_size = smd_write(ch, buf, header_size +
+						FEATURE_MASK_LEN_BYTES);
+			if (wr_size == -ENOMEM) {
+				retry_count++;
+				for (timer = 0; timer < 5; timer++)
+					udelay(2000);
+			} else
+				break;
+		}
+		if (wr_size != header_size + FEATURE_MASK_LEN_BYTES)
+			pr_err("diag: proc %d fail feature update %d, tried %d",
+			   proc, wr_size, header_size + FEATURE_MASK_LEN_BYTES);
+	} else
+		pr_err("diag: ch invalid, feature update on proc %d\n", proc);
+	mutex_unlock(&driver->diag_cntl_mutex);
+
+}
+
 int diag_process_apps_masks(unsigned char *buf, int len)
 {
 	int packet_type = 1;
@@ -485,6 +525,10 @@
 			*(int *)(driver->apps_rsp_buf + 4) = 0x3; /* op. ID */
 			*(int *)(driver->apps_rsp_buf + 8) = 0x0; /* success */
 			payload_length = 8 + ((*(int *)(buf + 4)) + 7)/8;
+			if (payload_length > APPS_BUF_SIZE - 12) {
+				pr_err("diag: log masks: buffer overflow\n");
+				return -EIO;
+			}
 			for (i = 0; i < payload_length; i++)
 				*(int *)(driver->apps_rsp_buf+12+i) = *(buf+i);
 
@@ -568,6 +612,10 @@
 					rt_last_ssid) {
 					rt_mask_size = 4 * (rt_last_ssid -
 						rt_first_ssid + 1);
+					if (rt_mask_size > APPS_BUF_SIZE - 8) {
+						pr_err("diag: rt masks: buffer overflow\n");
+						return -EIO;
+					}
 					memcpy(driver->apps_rsp_buf+8,
 						rt_mask_ptr, rt_mask_size);
 					encode_rsp_and_send(8+rt_mask_size-1);
@@ -581,7 +629,17 @@
 	else if ((*buf == 0x7d) && (*(buf+1) == 0x4)) {
 		ssid_first = *(uint16_t *)(buf + 2);
 		ssid_last = *(uint16_t *)(buf + 4);
+		if (ssid_last < ssid_first) {
+			pr_err("diag: Invalid msg mask ssid values, first: %d, last: %d\n",
+				ssid_first, ssid_last);
+			return -EIO;
+		}
 		ssid_range = 4 * (ssid_last - ssid_first + 1);
+		if (ssid_range > APPS_BUF_SIZE - 8) {
+			pr_err("diag: Not enough space for message mask, ssid_range: %d\n",
+				ssid_range);
+			return -EIO;
+		}
 		pr_debug("diag: received mask update for ssid_first = %d, ssid_last = %d",
 			ssid_first, ssid_last);
 		diag_update_msg_mask(ssid_first, ssid_last , buf + 8);
@@ -671,6 +729,16 @@
 			return 0;
 		}
 #endif
+	} else if (*buf == 0x78) {
+		if (!(driver->smd_cntl[MODEM_DATA].ch) ||
+					(driver->log_on_demand_support)) {
+			driver->apps_rsp_buf[0] = 0x78;
+			/* Copy log code received */
+			*(uint16_t *)(driver->apps_rsp_buf+1) =
+							 *(uint16_t *)buf;
+			driver->apps_rsp_buf[3] = 0x1;/* Unknown */
+			encode_rsp_and_send(3);
+		}
 	}
 
 	return  packet_type;
@@ -727,6 +795,21 @@
 			goto err;
 		kmemleak_not_leak(driver->msg_masks);
 	}
+	if (driver->buf_feature_mask_update == NULL) {
+		driver->buf_feature_mask_update = kzalloc(sizeof(
+					struct diag_ctrl_feature_mask) +
+					FEATURE_MASK_LEN_BYTES, GFP_KERNEL);
+		if (driver->buf_feature_mask_update == NULL)
+			goto err;
+		kmemleak_not_leak(driver->buf_feature_mask_update);
+	}
+	if (driver->feature_mask == NULL) {
+		driver->feature_mask = kzalloc(sizeof(
+			struct diag_ctrl_feature_mask), GFP_KERNEL);
+		if (driver->feature_mask == NULL)
+			goto err;
+		kmemleak_not_leak(driver->feature_mask);
+	}
 	diag_create_msg_mask_table();
 	diag_event_num_bytes = 0;
 	if (driver->log_masks == NULL) {
@@ -751,6 +834,8 @@
 	kfree(driver->msg_masks);
 	kfree(driver->log_masks);
 	kfree(driver->event_masks);
+	kfree(driver->feature_mask);
+	kfree(driver->buf_feature_mask_update);
 }
 
 void diag_masks_exit(void)
@@ -761,4 +846,6 @@
 	kfree(driver->msg_masks);
 	kfree(driver->log_masks);
 	kfree(driver->event_masks);
+	kfree(driver->feature_mask);
+	kfree(driver->buf_feature_mask_update);
 }
diff --git a/drivers/char/diag/diag_masks.h b/drivers/char/diag/diag_masks.h
index f144774..53f72e8 100644
--- a/drivers/char/diag/diag_masks.h
+++ b/drivers/char/diag/diag_masks.h
@@ -21,6 +21,7 @@
 					 int ssid_last, int proc);
 void diag_send_log_mask_update(smd_channel_t *, int);
 void diag_mask_update_fn(struct work_struct *work);
+void diag_send_feature_mask_update(smd_channel_t *ch, int proc);
 int diag_process_apps_masks(unsigned char *buf, int len);
 void diag_masks_init(void);
 void diag_masks_exit(void);
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index 77f9dd6..df28dab 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
@@ -38,16 +38,19 @@
 #define POOL_TYPE_COPY		1
 #define POOL_TYPE_HDLC		2
 #define POOL_TYPE_WRITE_STRUCT	4
-#define POOL_TYPE_HSIC		8
-#define POOL_TYPE_HSIC_WRITE	16
-#define POOL_TYPE_ALL		7
+#define POOL_TYPE_HSIC		5
+#define POOL_TYPE_HSIC_2	6
+#define POOL_TYPE_HSIC_WRITE	11
+#define POOL_TYPE_HSIC_2_WRITE	12
+#define POOL_TYPE_ALL		10
 #define MODEM_DATA		0
 #define LPASS_DATA		1
 #define WCNSS_DATA		2
 #define APPS_DATA		3
 #define SDIO_DATA		4
 #define HSIC_DATA		5
-#define SMUX_DATA		6
+#define HSIC_2_DATA		6
+#define SMUX_DATA		10
 #define APPS_PROC		1
 #define MSG_MASK_SIZE 10000
 #define LOG_MASK_SIZE 8000
@@ -93,6 +96,15 @@
 	(diag_debug_buf_idx++) : (diag_debug_buf_idx = 0); \
 } while (0)
 
+/* List of remote processor supported */
+enum remote_procs {
+	MDM = 1,
+	MDM2 = 2,
+	MDM3 = 3,
+	MDM4 = 4,
+	QSC = 5,
+};
+
 struct diag_master_table {
 	uint16_t cmd_code;
 	uint16_t subsys_id;
@@ -224,6 +236,7 @@
 	struct diag_ctrl_event_mask *event_mask;
 	struct diag_ctrl_log_mask *log_mask;
 	struct diag_ctrl_msg_mask *msg_mask;
+	struct diag_ctrl_feature_mask *feature_mask;
 	/* State for diag forwarding */
 	struct diag_smd_info smd_data[NUM_SMD_DATA_CHANNELS];
 	struct diag_smd_info smd_cntl[NUM_SMD_CONTROL_CHANNELS];
@@ -235,6 +248,7 @@
 	unsigned char *buf_msg_mask_update;
 	unsigned char *buf_log_mask_update;
 	unsigned char *buf_event_mask_update;
+	unsigned char *buf_feature_mask_update;
 	int read_len_legacy;
 	unsigned char *hdlc_buf;
 	unsigned hdlc_count;
@@ -252,6 +266,7 @@
 	uint8_t *log_masks;
 	int log_masks_length;
 	uint8_t *event_masks;
+	uint8_t log_on_demand_support;
 	struct diag_master_table *table;
 	uint8_t *pkt_buf;
 	int pkt_length;
@@ -286,29 +301,14 @@
 	int diag_smux_enabled;
 	int smux_connected;
 	struct diag_request *write_ptr_mdm;
-	/* HSIC variables */
-	int hsic_ch;
-	int hsic_inited;
-	int hsic_device_enabled;
-	int hsic_device_opened;
-	int hsic_suspend;
-	int in_busy_hsic_read_on_device;
-	int in_busy_hsic_write;
-	struct work_struct diag_read_hsic_work;
-	int count_hsic_pool;
-	int count_hsic_write_pool;
-	unsigned int poolsize_hsic;
-	unsigned int poolsize_hsic_write;
-	unsigned int itemsize_hsic;
-	unsigned int itemsize_hsic_write;
-	mempool_t *diag_hsic_pool;
-	mempool_t *diag_hsic_write_pool;
-	int num_hsic_buf_tbl_entries;
-	struct diag_write_device *hsic_buf_tbl;
-	spinlock_t hsic_spinlock;
 #endif
 };
 
 extern struct diag_bridge_dev *diag_bridge;
+extern struct diag_hsic_dev *diag_hsic;
 extern struct diagchar_dev *driver;
+
+extern int wrap_enabled;
+extern uint16_t wrap_count;
+
 #endif
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 9bd8950..13e52df 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
@@ -18,6 +18,7 @@
 #include <linux/device.h>
 #include <linux/uaccess.h>
 #include <linux/diagchar.h>
+#include <linux/platform_device.h>
 #include <linux/sched.h>
 #ifdef CONFIG_DIAG_OVER_USB
 #include <mach/usbdiag.h>
@@ -79,12 +80,25 @@
 /* delayed_rsp_id 0 represents no delay in the response. Any other number
     means that the diag packet has a delayed response. */
 static uint16_t delayed_rsp_id = 1;
-#define DIAGPKT_MAX_DELAYED_RSP 0xFFFF
-/* This macro gets the next delayed respose id. Once it reaches
- DIAGPKT_MAX_DELAYED_RSP, it stays at DIAGPKT_MAX_DELAYED_RSP */
 
-#define DIAGPKT_NEXT_DELAYED_RSP_ID(x) 				\
-((x < DIAGPKT_MAX_DELAYED_RSP) ? x++ : DIAGPKT_MAX_DELAYED_RSP)
+#define DIAGPKT_MAX_DELAYED_RSP 0xFFFF
+
+/* returns the next delayed rsp id - rollsover the id if wrapping is
+   enabled. */
+uint16_t diagpkt_next_delayed_rsp_id(uint16_t rspid)
+{
+	if (rspid < DIAGPKT_MAX_DELAYED_RSP)
+		rspid++;
+	else {
+		if (wrap_enabled) {
+			rspid = 1;
+			wrap_count++;
+		} else
+			rspid = DIAGPKT_MAX_DELAYED_RSP;
+	}
+	delayed_rsp_id = rspid;
+	return delayed_rsp_id;
+}
 
 #define COPY_USER_SPACE_OR_EXIT(buf, data, length)		\
 do {								\
@@ -96,9 +110,6 @@
 	ret += length;						\
 } while (0)
 
-/* Identifier for data from MDM */
-#define MDM_TOKEN	-1
-
 static void drain_timer_func(unsigned long data)
 {
 	queue_work(driver->diag_wq , &(driver->diag_drain_work));
@@ -131,18 +142,23 @@
 #ifdef CONFIG_DIAGFWD_BRIDGE_CODE
 void diag_clear_hsic_tbl(void)
 {
-	int i;
+	int i, j;
 
-	driver->num_hsic_buf_tbl_entries = 0;
-	for (i = 0; i < driver->poolsize_hsic_write; i++) {
-		if (driver->hsic_buf_tbl[i].buf) {
-			/* Return the buffer to the pool */
-			diagmem_free(driver, (unsigned char *)
-				(driver->hsic_buf_tbl[i].buf),
-				POOL_TYPE_HSIC);
-			driver->hsic_buf_tbl[i].buf = 0;
+	/* Clear for all active HSIC bridges */
+	for (j = 0; j < MAX_HSIC_CH; j++) {
+		if (diag_hsic[j].hsic_ch) {
+			diag_hsic[j].num_hsic_buf_tbl_entries = 0;
+			for (i = 0; i < diag_hsic[j].poolsize_hsic_write; i++) {
+				if (diag_hsic[j].hsic_buf_tbl[i].buf) {
+					/* Return the buffer to the pool */
+					diagmem_free(driver, (unsigned char *)
+						(diag_hsic[j].hsic_buf_tbl[i].
+						 buf), j+POOL_TYPE_HSIC);
+					diag_hsic[j].hsic_buf_tbl[i].buf = 0;
+				}
+				diag_hsic[j].hsic_buf_tbl[i].length = 0;
+			}
 		}
-		driver->hsic_buf_tbl[i].length = 0;
 	}
 }
 #else
@@ -237,6 +253,10 @@
 		pr_alert("diag: Invalid file pointer");
 		return -ENOMEM;
 	}
+
+	if (!driver)
+		return -ENOMEM;
+
 	/* clean up any DCI registrations, if this is a DCI client
 	* This will specially help in case of ungraceful exit of any DCI client
 	* This call will remove any pending registrations of such client
@@ -276,26 +296,23 @@
 			if (driver->table[i].process_id == current->tgid)
 					driver->table[i].process_id = 0;
 
-	if (driver) {
-		mutex_lock(&driver->diagchar_mutex);
-		driver->ref_count--;
-		/* On Client exit, try to destroy all 3 pools */
-		diagmem_exit(driver, POOL_TYPE_COPY);
-		diagmem_exit(driver, POOL_TYPE_HDLC);
-		diagmem_exit(driver, POOL_TYPE_WRITE_STRUCT);
-		for (i = 0; i < driver->num_clients; i++) {
-			if (NULL != diagpriv_data && diagpriv_data->pid ==
-				 driver->client_map[i].pid) {
-				driver->client_map[i].pid = 0;
-				kfree(diagpriv_data);
-				diagpriv_data = NULL;
-				break;
-			}
+	mutex_lock(&driver->diagchar_mutex);
+	driver->ref_count--;
+	/* On Client exit, try to destroy all 3 pools */
+	diagmem_exit(driver, POOL_TYPE_COPY);
+	diagmem_exit(driver, POOL_TYPE_HDLC);
+	diagmem_exit(driver, POOL_TYPE_WRITE_STRUCT);
+	for (i = 0; i < driver->num_clients; i++) {
+		if (NULL != diagpriv_data && diagpriv_data->pid ==
+						driver->client_map[i].pid) {
+			driver->client_map[i].pid = 0;
+			kfree(diagpriv_data);
+			diagpriv_data = NULL;
+			break;
 		}
-		mutex_unlock(&driver->diagchar_mutex);
-		return 0;
 	}
-	return -ENOMEM;
+	mutex_unlock(&driver->diagchar_mutex);
+	return 0;
 }
 
 int diag_find_polling_reg(int i)
@@ -365,20 +382,149 @@
 	(*count_entries)++;
 }
 
-#ifdef CONFIG_DIAG_BRIDGE_CODE
+static int diag_get_remote(int remote_info)
+{
+	int val = (remote_info < 0) ? -remote_info : remote_info;
+	int remote_val;
+
+	switch (val) {
+	case MDM:
+	case MDM2:
+	case MDM3:
+	case MDM4:
+	case QSC:
+		remote_val = -remote_info;
+		break;
+	default:
+		remote_val = 0;
+		break;
+	}
+
+	return remote_val;
+}
+
+#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
 uint16_t diag_get_remote_device_mask(void)
 {
 	uint16_t remote_dev = 0;
+	int i;
 
-	if (driver->hsic_inited)
-		remote_dev |= (1 << 0);
+	/* Check for MDM processor */
+	for (i = 0; i < MAX_HSIC_CH; i++)
+		if (diag_hsic[i].hsic_inited)
+			remote_dev |= 1 << i;
+
+	/* Check for QSC processor */
 	if (driver->diag_smux_enabled)
-		remote_dev |= (1 << 1);
+		remote_dev |= 1 << SMUX;
 
 	return remote_dev;
 }
+
+int diag_copy_remote(char __user *buf, size_t count, int *pret, int *pnum_data)
+{
+	int i;
+	int index;
+	int exit_stat = 1;
+	int ret = *pret;
+	int num_data = *pnum_data;
+	int remote_token;
+	unsigned long spin_lock_flags;
+	struct diag_write_device hsic_buf_tbl[NUM_HSIC_BUF_TBL_ENTRIES];
+
+	remote_token = diag_get_remote(MDM);
+	for (index = 0; index < MAX_HSIC_CH; index++) {
+		if (!diag_hsic[index].hsic_inited) {
+			remote_token--;
+			continue;
+		}
+
+		spin_lock_irqsave(&diag_hsic[index].hsic_spinlock,
+			spin_lock_flags);
+		for (i = 0; i < diag_hsic[index].poolsize_hsic_write; i++) {
+			hsic_buf_tbl[i].buf =
+				diag_hsic[index].hsic_buf_tbl[i].buf;
+			diag_hsic[index].hsic_buf_tbl[i].buf = 0;
+			hsic_buf_tbl[i].length =
+				diag_hsic[index].hsic_buf_tbl[i].length;
+			diag_hsic[index].hsic_buf_tbl[i].length = 0;
+		}
+		diag_hsic[index].num_hsic_buf_tbl_entries = 0;
+		spin_unlock_irqrestore(&diag_hsic[index].hsic_spinlock,
+			spin_lock_flags);
+
+		for (i = 0; i < diag_hsic[index].poolsize_hsic_write; i++) {
+			if (hsic_buf_tbl[i].length > 0) {
+				pr_debug("diag: HSIC copy to user, i: %d, buf: %x, len: %d\n",
+					i, (unsigned int)hsic_buf_tbl[i].buf,
+					hsic_buf_tbl[i].length);
+				num_data++;
+
+				/* Copy the negative token */
+				if (copy_to_user(buf+ret,
+					&remote_token, 4)) {
+						num_data--;
+						goto drop_hsic;
+				}
+				ret += 4;
+
+				/* Copy the length of data being passed */
+				if (copy_to_user(buf+ret,
+					(void *)&(hsic_buf_tbl[i].length),
+					4)) {
+						num_data--;
+						goto drop_hsic;
+				}
+				ret += 4;
+
+				/* Copy the actual data being passed */
+				if (copy_to_user(buf+ret,
+					(void *)hsic_buf_tbl[i].buf,
+					hsic_buf_tbl[i].length)) {
+						ret -= 4;
+						num_data--;
+						goto drop_hsic;
+				}
+				ret += hsic_buf_tbl[i].length;
+drop_hsic:
+				/* Return the buffer to the pool */
+				diagmem_free(driver,
+					(unsigned char *)(hsic_buf_tbl[i].buf),
+					index+POOL_TYPE_HSIC);
+
+				/* Call the write complete function */
+				diagfwd_write_complete_hsic(NULL, index);
+			}
+		}
+		remote_token--;
+	}
+	if (driver->in_busy_smux == 1) {
+		remote_token = diag_get_remote(QSC);
+		num_data++;
+
+		/* Copy the negative  token of data being passed */
+		COPY_USER_SPACE_OR_EXIT(buf+ret,
+			remote_token, 4);
+		/* Copy the length of data being passed */
+		COPY_USER_SPACE_OR_EXIT(buf+ret,
+			(driver->write_ptr_mdm->length), 4);
+		/* Copy the actual data being passed */
+		COPY_USER_SPACE_OR_EXIT(buf+ret,
+			*(driver->buf_in_smux),
+			driver->write_ptr_mdm->length);
+		pr_debug("diag: SMUX  data copied\n");
+		driver->in_busy_smux = 0;
+	}
+	exit_stat = 0;
+exit:
+	*pret = ret;
+	*pnum_data = num_data;
+	return exit_stat;
+}
 #else
 inline uint16_t diag_get_remote_device_mask(void) { return 0; }
+inline int diag_copy_remote(char __user *buf, size_t count, int *pret,
+			    int *pnum_data) { return 0; }
 #endif
 
 long diagchar_ioctl(struct file *filp,
@@ -522,7 +668,7 @@
 		if ((delay_params.rsp_ptr) &&
 		 (delay_params.size == sizeof(delayed_rsp_id)) &&
 				 (delay_params.num_bytes_ptr)) {
-			interim_rsp_id = DIAGPKT_NEXT_DELAYED_RSP_ID(
+			interim_rsp_id = diagpkt_next_delayed_rsp_id(
 							delayed_rsp_id);
 			if (copy_to_user((void *)delay_params.rsp_ptr,
 					 &interim_rsp_id, sizeof(uint16_t)))
@@ -545,8 +691,10 @@
 			return -ENOMEM;
 		}
 		if (copy_from_user(dci_params, (void *)ioarg,
-				 sizeof(struct diag_dci_client_tbl)))
+				 sizeof(struct diag_dci_client_tbl))) {
+			kfree(dci_params);
 			return -EFAULT;
+		}
 		mutex_lock(&driver->dci_mutex);
 		if (!(driver->num_dci_client))
 			for (i = 0; i < NUM_SMD_DCI_CHANNELS; i++)
@@ -578,8 +726,8 @@
 				break;
 			}
 		}
-		mutex_unlock(&driver->dci_mutex);
 		kfree(dci_params);
+		mutex_unlock(&driver->dci_mutex);
 		return driver->dci_client_id;
 	} else if (iocmd == DIAG_IOCTL_DCI_DEINIT) {
 		success = -1;
@@ -771,7 +919,6 @@
 		success = 1;
 	} else if (iocmd == DIAG_IOCTL_REMOTE_DEV) {
 		uint16_t remote_dev = diag_get_remote_device_mask();
-
 		if (copy_to_user((void *)ioarg, &remote_dev, sizeof(uint16_t)))
 			success = -EFAULT;
 		else
@@ -787,9 +934,8 @@
 	struct diag_dci_client_tbl *entry;
 	int index = -1, i = 0, ret = 0;
 	int num_data = 0, data_type;
-#if defined(CONFIG_DIAG_SDIO_PIPE) || defined(CONFIG_DIAGFWD_BRIDGE_CODE)
-	int mdm_token = MDM_TOKEN;
-#endif
+	int remote_token;
+	int exit_stat;
 
 	for (i = 0; i < driver->num_clients; i++)
 		if (driver->client_map[i].pid == current->tgid)
@@ -806,11 +952,7 @@
 
 	if ((driver->data_ready[index] & USER_SPACE_DATA_TYPE) && (driver->
 					logging_mode == MEMORY_DEVICE_MODE)) {
-#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
-		unsigned long spin_lock_flags;
-		struct diag_write_device hsic_buf_tbl[NUM_HSIC_BUF_TBL_ENTRIES];
-#endif
-
+		remote_token = 0;
 		pr_debug("diag: process woken up\n");
 		/*Copy the type of data being passed*/
 		data_type = driver->data_ready[index] & USER_SPACE_DATA_TYPE;
@@ -886,9 +1028,12 @@
 #ifdef CONFIG_DIAG_SDIO_PIPE
 		/* copy 9K data over SDIO */
 		if (driver->in_busy_sdio == 1) {
+			remote_token = diag_get_remote(MDM);
 			num_data++;
-			/*Copy the negative  token of data being passed*/
-			COPY_USER_SPACE_OR_EXIT(buf+ret, mdm_token, 4);
+
+			/*Copy the negative token of data being passed*/
+			COPY_USER_SPACE_OR_EXIT(buf+ret,
+						remote_token, 4);
 			/*Copy the length of data being passed*/
 			COPY_USER_SPACE_OR_EXIT(buf+ret,
 				 (driver->write_ptr_mdm->length), 4);
@@ -899,77 +1044,11 @@
 			driver->in_busy_sdio = 0;
 		}
 #endif
-#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
-		spin_lock_irqsave(&driver->hsic_spinlock, spin_lock_flags);
-		for (i = 0; i < driver->poolsize_hsic_write; i++) {
-			hsic_buf_tbl[i].buf = driver->hsic_buf_tbl[i].buf;
-			driver->hsic_buf_tbl[i].buf = 0;
-			hsic_buf_tbl[i].length =
-					driver->hsic_buf_tbl[i].length;
-			driver->hsic_buf_tbl[i].length = 0;
-		}
-		driver->num_hsic_buf_tbl_entries = 0;
-		spin_unlock_irqrestore(&driver->hsic_spinlock,
-					spin_lock_flags);
+		/* Copy date from remote processors */
+		exit_stat = diag_copy_remote(buf, count, &ret, &num_data);
+		if (exit_stat == 1)
+			goto exit;
 
-		for (i = 0; i < driver->poolsize_hsic_write; i++) {
-			if (hsic_buf_tbl[i].length > 0) {
-				pr_debug("diag: HSIC copy to user, i: %d, buf: %x, len: %d\n",
-					 i, (unsigned int)hsic_buf_tbl[i].buf,
-					hsic_buf_tbl[i].length);
-				num_data++;
-
-				/* Copy the negative token */
-				if (copy_to_user(buf+ret, &mdm_token, 4)) {
-					num_data--;
-					goto drop_hsic;
-				}
-				ret += 4;
-
-				/* Copy the length of data being passed */
-				if (copy_to_user(buf+ret,
-					(void *)&(hsic_buf_tbl[i].length),
-					4)) {
-					num_data--;
-					goto drop_hsic;
-				}
-				ret += 4;
-
-				/* Copy the actual data being passed */
-				if (copy_to_user(buf+ret,
-						(void *)hsic_buf_tbl[i].buf,
-						hsic_buf_tbl[i].length)) {
-					ret -= 4;
-					num_data--;
-					goto drop_hsic;
-				}
-				ret += hsic_buf_tbl[i].length;
-drop_hsic:
-				/* Return the buffer to the pool */
-				diagmem_free(driver,
-					(unsigned char *)(hsic_buf_tbl[i].buf),
-					POOL_TYPE_HSIC);
-
-				/* Call the write complete function */
-				diagfwd_write_complete_hsic(NULL);
-			}
-		}
-		if (driver->in_busy_smux == 1) {
-			num_data++;
-
-			/* Copy the negative  token of data being passed */
-			COPY_USER_SPACE_OR_EXIT(buf+ret, mdm_token, 4);
-			/* Copy the length of data being passed */
-			COPY_USER_SPACE_OR_EXIT(buf+ret,
-					(driver->write_ptr_mdm->length), 4);
-			/* Copy the actual data being passed */
-			COPY_USER_SPACE_OR_EXIT(buf+ret,
-					*(driver->buf_in_smux),
-					driver->write_ptr_mdm->length);
-			pr_debug("diag: SMUX  data copied\n");
-			driver->in_busy_smux = 0;
-		}
-#endif
 		/* copy number of data fields */
 		COPY_USER_SPACE_OR_EXIT(buf+4, num_data, 4);
 		ret -= 4;
@@ -1046,10 +1125,9 @@
 		COPY_USER_SPACE_OR_EXIT(buf, data_type, 4);
 		/* check the current client and copy its data */
 		for (i = 0; i < MAX_DCI_CLIENTS; i++) {
-			if (driver->dci_client_tbl[i].client != NULL) {
-				entry = &(driver->dci_client_tbl[i]);
-				if (entry && (current->tgid ==
-						entry->client->tgid)) {
+			entry = &(driver->dci_client_tbl[i]);
+			if (entry && entry->client) {
+				if (current->tgid == entry->client->tgid) {
 					COPY_USER_SPACE_OR_EXIT(buf+4,
 							entry->data_len, 4);
 					COPY_USER_SPACE_OR_EXIT(buf+8,
@@ -1077,7 +1155,7 @@
 				size_t count, loff_t *ppos)
 {
 	int err, ret = 0, pkt_type, token_offset = 0;
-	bool remote_data = false;
+	int remote_proc = 0, index;
 #ifdef DIAG_DEBUG
 	int length = 0, i;
 #endif
@@ -1092,6 +1170,7 @@
 		return -EIO;
 	}
 #endif /* DIAG over USB */
+	index = 0;
 	/* Get the packet type F3/log/event/Pkt response */
 	err = copy_from_user((&pkt_type), buf, 4);
 	/* First 4 bytes indicate the type of payload - ignore these */
@@ -1120,9 +1199,14 @@
 	if (pkt_type == USER_SPACE_DATA_TYPE) {
 		err = copy_from_user(driver->user_space_data, buf + 4,
 							 payload_size);
+		if (err) {
+			pr_err("diag: copy failed for user space data\n");
+			return -EIO;
+		}
 		/* Check for proc_type */
-		if (*(int *)driver->user_space_data == MDM_TOKEN) {
-			remote_data = true;
+		remote_proc = diag_get_remote(*(int *)driver->user_space_data);
+
+		if (remote_proc) {
 			token_offset = 4;
 			payload_size -= 4;
 			buf += 4;
@@ -1145,7 +1229,7 @@
 #endif
 #ifdef CONFIG_DIAG_SDIO_PIPE
 		/* send masks to 9k too */
-		if (driver->sdio_ch && remote_data) {
+		if (driver->sdio_ch && (remote_proc == MDM)) {
 			wait_event_interruptible(driver->wait_q,
 				 (sdio_write_avail(driver->sdio_ch) >=
 					 payload_size));
@@ -1157,31 +1241,39 @@
 		}
 #endif
 #ifdef CONFIG_DIAGFWD_BRIDGE_CODE
-		/* send masks to 9k too */
-		if (driver->hsic_ch && (payload_size > 0) && remote_data) {
-			/* wait sending mask updates if HSIC ch not ready */
-			if (driver->in_busy_hsic_write)
-				wait_event_interruptible(driver->wait_q,
-					(driver->in_busy_hsic_write != 1));
-			driver->in_busy_hsic_write = 1;
-			driver->in_busy_hsic_read_on_device = 0;
-			err = diag_bridge_write(
-					driver->user_space_data + token_offset,
-					payload_size);
-			if (err) {
-				pr_err("diag: err sending mask to MDM: %d\n",
-									 err);
-				/*
-				* If the error is recoverable, then clear
-				* the write flag, so we will resubmit a
-				* write on the next frame.  Otherwise, don't
-				* resubmit a write on the next frame.
-				*/
-				if ((-ESHUTDOWN) != err)
-					driver->in_busy_hsic_write = 0;
-			}
+		/* send masks to All 9k */
+		if ((remote_proc >= MDM) && (remote_proc <= MDM4)) {
+			index = remote_proc - MDM;
+			if (diag_hsic[index].hsic_ch && (payload_size > 0)) {
+				/* wait sending mask updates
+				 * if HSIC ch not ready */
+				if (diag_hsic[index].in_busy_hsic_write)
+					wait_event_interruptible(driver->wait_q,
+						(diag_hsic[index].
+						 in_busy_hsic_write != 1));
+				diag_hsic[index].in_busy_hsic_write = 1;
+				diag_hsic[index].in_busy_hsic_read_on_device =
+									0;
+				err = diag_bridge_write(index,
+						driver->user_space_data +
+						token_offset, payload_size);
+				if (err) {
+					pr_err("diag: err sending mask to MDM: %d\n",
+					       err);
+					/*
+					* If the error is recoverable, then
+					* clear the write flag, so we will
+					* resubmit a write on the next frame.
+					* Otherwise, don't resubmit a write
+					* on the next frame.
+					*/
+					if ((-ESHUTDOWN) != err)
+						diag_hsic[index].
+							in_busy_hsic_write = 0;
+				 }
+			 }
 		}
-		if (driver->diag_smux_enabled && remote_data
+		if (driver->diag_smux_enabled && (remote_proc == QSC)
 						&& driver->lcid) {
 			if (payload_size > 0) {
 				err = msm_smux_write(driver->lcid, NULL,
@@ -1196,7 +1288,7 @@
 		}
 #endif
 		/* send masks to 8k now */
-		if (!remote_data)
+		if (!remote_proc)
 			diag_process_hdlc((void *)
 				(driver->user_space_data + token_offset),
 				 payload_size);
@@ -1250,6 +1342,13 @@
 		ret = -ENOMEM;
 		goto fail_free_hdlc;
 	}
+	if (HDLC_OUT_BUF_SIZE < (2*payload_size) + 3) {
+		pr_err("diag: Dropping packet, HDLC encoded packet payload size crosses buffer limit. Current payload size %d\n",
+				((2*payload_size) + 3));
+		driver->dropped_count++;
+		ret = -EBADMSG;
+		goto fail_free_hdlc;
+	}
 	if (HDLC_OUT_BUF_SIZE - driver->used <= (2*payload_size) + 3) {
 		err = diag_device_write(buf_hdlc, APPS_DATA, NULL);
 		if (err) {
@@ -1320,8 +1419,8 @@
 		driver->used = 0;
 	}
 
-	mutex_unlock(&driver->diagchar_mutex);
 	diagmem_free(driver, buf_copy, POOL_TYPE_COPY);
+	mutex_unlock(&driver->diagchar_mutex);
 	if (!timer_in_progress)	{
 		timer_in_progress = 1;
 		ret = mod_timer(&drain_timer, jiffies + msecs_to_jiffies(500));
@@ -1496,15 +1595,20 @@
 static int __init diagchar_init(void)
 {
 	dev_t dev;
-	int error;
+	int error, ret;
 
 	pr_debug("diagfwd initializing ..\n");
+	ret = 0;
 	driver = kzalloc(sizeof(struct diagchar_dev) + 5, GFP_KERNEL);
 #ifdef CONFIG_DIAGFWD_BRIDGE_CODE
 	diag_bridge = kzalloc(MAX_BRIDGES * sizeof(struct diag_bridge_dev),
-								 GFP_KERNEL);
+								GFP_KERNEL);
 	if (!diag_bridge)
-		pr_warning("diag: could not allocate memory for bridge\n");
+		pr_warn("diag: could not allocate memory for bridges\n");
+	diag_hsic = kzalloc(MAX_HSIC_CH * sizeof(struct diag_hsic_dev),
+								GFP_KERNEL);
+	if (!diag_hsic)
+		pr_warn("diag: could not allocate memory for hsic ch\n");
 #endif
 
 	if (driver) {
@@ -1533,6 +1637,12 @@
 		diagfwd_init();
 #ifdef CONFIG_DIAGFWD_BRIDGE_CODE
 		diagfwd_bridge_init(HSIC);
+		diagfwd_bridge_init(HSIC_2);
+		/* register HSIC device */
+		ret = platform_driver_register(&msm_hsic_ch_driver);
+		if (ret)
+			pr_err("diag: could not register HSIC device, ret: %d\n",
+				ret);
 		diagfwd_bridge_init(SMUX);
 		INIT_WORK(&(driver->diag_disconnect_work),
 						 diag_disconnect_work_fn);
diff --git a/drivers/char/diag/diagchar_hdlc.c b/drivers/char/diag/diagchar_hdlc.c
index 74dcb6b..2369c4d 100644
--- a/drivers/char/diag/diagchar_hdlc.c
+++ b/drivers/char/diag/diagchar_hdlc.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2008-2009, 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
@@ -172,11 +173,14 @@
 	uint8_t src_byte;
 
 	int pkt_bnd = 0;
+	int msg_start;
 
 	if (hdlc && hdlc->src_ptr && hdlc->dest_ptr &&
 	    (hdlc->src_size - hdlc->src_idx > 0) &&
 	    (hdlc->dest_size - hdlc->dest_idx > 0)) {
 
+		msg_start = (hdlc->src_idx == 0) ? 1 : 0;
+
 		src_ptr = hdlc->src_ptr;
 		src_ptr = &src_ptr[hdlc->src_idx];
 		src_length = hdlc->src_size - hdlc->src_idx;
@@ -203,8 +207,16 @@
 				}
 			} else if (src_byte == CONTROL_CHAR) {
 				dest_ptr[len++] = src_byte;
-				pkt_bnd = 1;
+				/*
+				 * If this is the first byte in the message,
+				 * then it is part of the command. Otherwise,
+				 * consider it as the last byte of the
+				 * message.
+				 */
+				if (msg_start && i == 0 && src_length > 1)
+					continue;
 				i++;
+				pkt_bnd = 1;
 				break;
 			} else {
 				dest_ptr[len++] = src_byte;
diff --git a/drivers/char/diag/diagchar_hdlc.h b/drivers/char/diag/diagchar_hdlc.h
index 116c980..e3378ac 100644
--- a/drivers/char/diag/diagchar_hdlc.h
+++ b/drivers/char/diag/diagchar_hdlc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 6b4c337..2aca8cf 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
@@ -34,6 +34,7 @@
 #include "diagchar.h"
 #include "diagfwd.h"
 #include "diagfwd_cntl.h"
+#include "diagfwd_hsic.h"
 #include "diagchar_hdlc.h"
 #ifdef CONFIG_DIAG_SDIO_PIPE
 #include "diagfwd_sdio.h"
@@ -51,6 +52,8 @@
 struct diag_master_table entry;
 struct diag_send_desc_type send = { NULL, NULL, DIAG_STATE_START, 0 };
 struct diag_hdlc_dest_type enc = { NULL, NULL, 0 };
+int wrap_enabled;
+uint16_t wrap_count;
 
 void encode_rsp_and_send(int buf_length)
 {
@@ -95,7 +98,7 @@
 
 int chk_config_get_id(void)
 {
-	/* For all Fusion targets, Modem will always be present */
+	/* For all Fusion targets,  Modem will always be present */
 	if (machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa())
 		return 0;
 
@@ -113,6 +116,7 @@
 			return AO8960_TOOLS_ID;
 		case MSM_CPU_8064:
 		case MSM_CPU_8064AB:
+		case MSM_CPU_8064AA:
 			return APQ8064_TOOLS_ID;
 		case MSM_CPU_8930:
 		case MSM_CPU_8930AA:
@@ -142,6 +146,7 @@
 	case MSM_CPU_8960AB:
 	case MSM_CPU_8064:
 	case MSM_CPU_8064AB:
+	case MSM_CPU_8064AA:
 	case MSM_CPU_8930:
 	case MSM_CPU_8930AA:
 	case MSM_CPU_8930AB:
@@ -348,7 +353,8 @@
 
 int diag_device_write(void *buf, int data_type, struct diag_request *write_ptr)
 {
-	int i, err = 0;
+	int i, err = 0, index;
+	index = 0;
 
 	if (driver->logging_mode == MEMORY_DEVICE_MODE) {
 		if (data_type == APPS_DATA) {
@@ -368,28 +374,34 @@
 		}
 
 #ifdef CONFIG_DIAGFWD_BRIDGE_CODE
-		else if (data_type == HSIC_DATA) {
+		else if (data_type == HSIC_DATA || data_type == HSIC_2_DATA) {
 			unsigned long flags;
 			int foundIndex = -1;
-
-			spin_lock_irqsave(&driver->hsic_spinlock, flags);
-			for (i = 0; i < driver->poolsize_hsic_write; i++) {
-				if (driver->hsic_buf_tbl[i].length == 0) {
-					driver->hsic_buf_tbl[i].buf = buf;
-					driver->hsic_buf_tbl[i].length =
-						diag_bridge[HSIC].write_len;
-					driver->num_hsic_buf_tbl_entries++;
+			index = data_type - HSIC_DATA;
+			spin_lock_irqsave(&diag_hsic[index].hsic_spinlock,
+									flags);
+			for (i = 0; i < diag_hsic[index].poolsize_hsic_write;
+									i++) {
+				if (diag_hsic[index].hsic_buf_tbl[i].length
+									== 0) {
+					diag_hsic[index].hsic_buf_tbl[i].buf
+									= buf;
+					diag_hsic[index].hsic_buf_tbl[i].length
+						= diag_bridge[index].write_len;
+					diag_hsic[index].
+						num_hsic_buf_tbl_entries++;
 					foundIndex = i;
 					break;
 				}
 			}
-			spin_unlock_irqrestore(&driver->hsic_spinlock, flags);
+			spin_unlock_irqrestore(&diag_hsic[index].hsic_spinlock,
+									flags);
 			if (foundIndex == -1)
 				err = -1;
 			else
-				pr_debug("diag: ENQUEUE HSIC buf ptr and length is %x , %d\n",
+				pr_debug("diag: ENQUEUE HSIC buf ptr and length is %x , %d, ch %d\n",
 					(unsigned int)buf,
-					 diag_bridge[HSIC].write_len);
+					 diag_bridge[index].write_len, index);
 		}
 #endif
 		for (i = 0; i < driver->num_clients; i++)
@@ -418,10 +430,12 @@
 		}
 #endif
 #ifdef CONFIG_DIAGFWD_BRIDGE_CODE
-		else if (data_type == HSIC_DATA) {
-			if (driver->hsic_ch)
-				queue_work(diag_bridge[HSIC].wq,
-					&(driver->diag_read_hsic_work));
+		else if (data_type == HSIC_DATA || data_type == HSIC_2_DATA) {
+			index = data_type - HSIC_DATA;
+			if (diag_hsic[index].hsic_ch)
+				queue_work(diag_bridge[index].wq,
+					   &(diag_hsic[index].
+					     diag_read_hsic_work));
 		}
 #endif
 		err = -1;
@@ -463,27 +477,30 @@
 		}
 #endif
 #ifdef CONFIG_DIAGFWD_BRIDGE_CODE
-		else if (data_type == HSIC_DATA) {
-			if (driver->hsic_device_enabled) {
+		else if (data_type == HSIC_DATA || data_type == HSIC_2_DATA) {
+			index = data_type - HSIC_DATA;
+			if (diag_hsic[index].hsic_device_enabled) {
 				struct diag_request *write_ptr_mdm;
 				write_ptr_mdm = (struct diag_request *)
 						diagmem_alloc(driver,
 						sizeof(struct diag_request),
+							index +
 							POOL_TYPE_HSIC_WRITE);
 				if (write_ptr_mdm) {
 					write_ptr_mdm->buf = buf;
 					write_ptr_mdm->length =
-					   diag_bridge[HSIC].write_len;
-					write_ptr_mdm->context = (void *)HSIC;
+					   diag_bridge[index].write_len;
+					write_ptr_mdm->context = (void *)index;
 					err = usb_diag_write(
-					diag_bridge[HSIC].ch, write_ptr_mdm);
+					diag_bridge[index].ch, write_ptr_mdm);
 					/* Return to the pool immediately */
 					if (err) {
 						diagmem_free(driver,
 							write_ptr_mdm,
+							index +
 							POOL_TYPE_HSIC_WRITE);
-						pr_err_ratelimited("diag: HSIC write failure, err: %d\n",
-							err);
+						pr_err_ratelimited("diag: HSIC write failure, err: %d, ch %d\n",
+							err, index);
 					}
 				} else {
 					pr_err("diag: allocate write fail\n");
@@ -594,13 +611,15 @@
 	int packet_type = 1, i, cmd_code;
 	unsigned char *temp = buf;
 	int data_type;
+	int mask_ret;
 #if defined(CONFIG_DIAG_OVER_USB)
 	unsigned char *ptr;
 #endif
 
 	/* Check if the command is a supported mask command */
-	if (diag_process_apps_masks(buf, len) == 0)
-		return 0;
+	mask_ret = diag_process_apps_masks(buf, len);
+	if (mask_ret <= 0)
+		return mask_ret;
 
 	/* Check for registered clients and forward packet to apropriate proc */
 	cmd_code = (int)(*(char *)buf);
@@ -896,6 +915,23 @@
 			return 0;
 		}
 	}
+	/* Return the Delayed Response Wrap Status */
+	else if ((*buf == 0x4b) && (*(buf+1) == 0x32) &&
+		(*(buf+2) == 0x04) && (*(buf+3) == 0x0)) {
+		memcpy(driver->apps_rsp_buf, buf, 4);
+		driver->apps_rsp_buf[4] = wrap_enabled;
+		encode_rsp_and_send(4);
+		return 0;
+	}
+	/* Wrap the Delayed Rsp ID */
+	else if ((*buf == 0x4b) && (*(buf+1) == 0x32) &&
+		(*(buf+2) == 0x05) && (*(buf+3) == 0x0)) {
+		wrap_enabled = true;
+		memcpy(driver->apps_rsp_buf, buf, 4);
+		driver->apps_rsp_buf[4] = wrap_count;
+		encode_rsp_and_send(5);
+		return 0;
+	}
 	 /* Check for ID for NO MODEM present */
 	else if (chk_polling_response()) {
 		/* respond to 0x0 command */
@@ -957,10 +993,24 @@
 
 	ret = diag_hdlc_decode(&hdlc);
 
-	if (ret)
+	/*
+	 * If the message is 3 bytes or less in length then the message is
+	 * too short. A message will need 4 bytes minimum, since there are
+	 * 2 bytes for the CRC and 1 byte for the ending 0x7e for the hdlc
+	 * encoding
+	 */
+	if (hdlc.dest_idx < 4) {
+		pr_err_ratelimited("diag: In %s, message is too short, len: %d, dest len: %d\n",
+			__func__, len, hdlc.dest_idx);
+		return;
+	}
+
+	if (ret) {
 		type = diag_process_apps_pkt(driver->hdlc_buf,
 							  hdlc.dest_idx - 3);
-	else if (driver->debug_flag) {
+		if (type < 0)
+			return;
+	} else if (driver->debug_flag) {
 		printk(KERN_ERR "Packet dropped due to bad HDLC coding/CRC"
 				" errors or partial packet received, packet"
 				" length = %d\n", len);
@@ -1449,6 +1499,8 @@
 	int success;
 	int i;
 
+	wrap_enabled = 0;
+	wrap_count = 0;
 	diag_debug_buf_idx = 0;
 	driver->read_len_legacy = 0;
 	driver->use_device_tree = has_device_tree();
diff --git a/drivers/char/diag/diagfwd.h b/drivers/char/diag/diagfwd.h
index 14e2dd5..5a67b0c 100644
--- a/drivers/char/diag/diagfwd.h
+++ b/drivers/char/diag/diagfwd.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/drivers/char/diag/diagfwd_bridge.c b/drivers/char/diag/diagfwd_bridge.c
index 75fdeb4..b934805 100644
--- a/drivers/char/diag/diagfwd_bridge.c
+++ b/drivers/char/diag/diagfwd_bridge.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
@@ -55,8 +55,8 @@
 		err = usb_diag_alloc_req(diag_bridge[index].ch, N_MDM_WRITE,
 			       N_MDM_READ);
 		if (err)
-			pr_err("diag: unable to alloc USB req on mdm ch err:%d\n",
-							 err);
+			pr_err("diag: unable to alloc USB req for ch %d err:%d\n",
+							 index, err);
 
 		diag_bridge[index].usb_connected = 1;
 	}
@@ -64,35 +64,45 @@
 	if (index == SMUX && driver->diag_smux_enabled) {
 		driver->in_busy_smux = 0;
 		diagfwd_connect_smux();
-	} else if (index == HSIC && driver->hsic_device_enabled) {
-		driver->in_busy_hsic_read_on_device = 0;
-		driver->in_busy_hsic_write = 0;
-		/* If the HSIC (diag_bridge) platform device is not open */
-		if (!driver->hsic_device_opened) {
-			err = diag_bridge_open(&hsic_diag_bridge_ops);
-			if (err) {
-				pr_err("diag: HSIC channel open error: %d\n",
-					  err);
+	} else {
+		if (diag_hsic[index].hsic_device_enabled) {
+			diag_hsic[index].in_busy_hsic_read_on_device = 0;
+			diag_hsic[index].in_busy_hsic_write = 0;
+			/* If the HSIC (diag_bridge) platform
+			 * device is not open */
+			if (!diag_hsic[index].hsic_device_opened) {
+				hsic_diag_bridge_ops[index].ctxt =
+							(void *)(index);
+				err = diag_bridge_open(index,
+						 &hsic_diag_bridge_ops[index]);
+				if (err) {
+					pr_err("diag: HSIC channel open error: %d\n",
+						   err);
+				} else {
+					pr_debug("diag: opened HSIC channel\n");
+					diag_hsic[index].hsic_device_opened =
+									1;
+				}
 			} else {
-				pr_debug("diag: opened HSIC channel\n");
-				driver->hsic_device_opened = 1;
+				pr_debug("diag: HSIC channel already open\n");
 			}
-		} else {
-			pr_debug("diag: HSIC channel already open\n");
-		}
-		/*
-		 * Turn on communication over usb mdm and HSIC, if the HSIC
-		 * device driver is enabled and opened
-		 */
-		if (driver->hsic_device_opened) {
-			driver->hsic_ch = 1;
-			/* Poll USB mdm channel to check for data */
-			if (driver->logging_mode == USB_MODE)
-				queue_work(diag_bridge[HSIC].wq,
-					  &diag_bridge[HSIC].diag_read_work);
-			/* Poll HSIC channel to check for data */
-			queue_work(diag_bridge[HSIC].wq,
-				   &driver->diag_read_hsic_work);
+			/*
+			 * Turn on communication over usb mdm and HSIC,
+			 * if the HSIC device driver is enabled
+			 * and opened
+			 */
+			if (diag_hsic[index].hsic_device_opened) {
+				diag_hsic[index].hsic_ch = 1;
+				/* Poll USB mdm channel to check for data */
+				if (driver->logging_mode == USB_MODE)
+					queue_work(diag_bridge[index].wq,
+						   &diag_bridge[index].
+							diag_read_work);
+				/* Poll HSIC channel to check for data */
+				queue_work(diag_bridge[index].wq,
+					   &diag_hsic[index].
+					   diag_read_hsic_work);
+			}
 		}
 	}
 	mutex_unlock(&diag_bridge[index].bridge_mutex);
@@ -116,19 +126,25 @@
 				usb_diag_free_req(diag_bridge[i].ch);
 			}
 
-			if (i == HSIC && driver->hsic_device_enabled &&
-				 driver->logging_mode != MEMORY_DEVICE_MODE) {
-				driver->in_busy_hsic_read_on_device = 1;
-				driver->in_busy_hsic_write = 1;
-				/* Turn off communication over usb and HSIC */
-				diag_hsic_close();
-			} else if (i == SMUX && driver->diag_smux_enabled &&
+			if (i == SMUX && driver->diag_smux_enabled &&
 					driver->logging_mode == USB_MODE) {
 				driver->in_busy_smux = 1;
 				driver->lcid = LCID_INVALID;
 				driver->smux_connected = 0;
 				/* Turn off communication over usb and smux */
 				msm_smux_close(LCID_VALID);
+			}  else {
+				if (diag_hsic[i].hsic_device_enabled &&
+				     driver->logging_mode !=
+							MEMORY_DEVICE_MODE) {
+					diag_hsic[i].
+						in_busy_hsic_read_on_device
+						= 1;
+					diag_hsic[i].in_busy_hsic_write = 1;
+					/* Turn off communication over usb
+					 * and HSIC */
+					diag_hsic_close(i);
+				}
 			}
 			mutex_unlock(&diag_bridge[i].bridge_mutex);
 		}
@@ -154,9 +170,9 @@
 	}
 
 	/* If SMUX not enabled, check for HSIC */
-	driver->in_busy_hsic_read_on_device = 0;
-	if (!driver->hsic_ch) {
-		pr_err("DIAG in %s: driver->hsic_ch == 0\n", __func__);
+	diag_hsic[index].in_busy_hsic_read_on_device = 0;
+	if (!diag_hsic[index].hsic_ch) {
+		pr_err("DIAG in %s: hsic_ch == 0, ch %d\n", __func__, index);
 		return 0;
 	}
 
@@ -166,8 +182,9 @@
 	 * read has data to pass on to the HSIC. If so, pass the usb
 	 * mdm data on to the HSIC.
 	 */
-	if (!driver->in_busy_hsic_write && diag_bridge[HSIC].usb_buf_out &&
-		(diag_bridge[HSIC].read_len > 0)) {
+	if (!diag_hsic[index].in_busy_hsic_write &&
+		diag_bridge[index].usb_buf_out &&
+		(diag_bridge[index].read_len > 0)) {
 
 		/*
 		 * Initiate the HSIC write. The HSIC write is
@@ -175,9 +192,9 @@
 		 * complete callback function will be called
 		 */
 		int err;
-		driver->in_busy_hsic_write = 1;
-		err = diag_bridge_write(diag_bridge[HSIC].usb_buf_out,
-					diag_bridge[HSIC].read_len);
+		diag_hsic[index].in_busy_hsic_write = 1;
+		err = diag_bridge_write(index, diag_bridge[index].usb_buf_out,
+					diag_bridge[index].read_len);
 		if (err) {
 			pr_err_ratelimited("diag: mdm data on HSIC write err: %d\n",
 					err);
@@ -188,7 +205,7 @@
 			 * resubmit a write on the next frame.
 			 */
 			if ((-ENODEV) != err)
-				driver->in_busy_hsic_write = 0;
+				diag_hsic[index].in_busy_hsic_write = 0;
 		}
 	}
 
@@ -196,9 +213,9 @@
 	 * If there is no write of the usb mdm data on the
 	 * HSIC channel
 	 */
-	if (!driver->in_busy_hsic_write)
-		queue_work(diag_bridge[HSIC].wq,
-			 &diag_bridge[HSIC].diag_read_work);
+	if (!diag_hsic[index].in_busy_hsic_write)
+		queue_work(diag_bridge[index].wq,
+			 &diag_bridge[index].diag_read_work);
 
 	return 0;
 }
@@ -223,10 +240,10 @@
 		break;
 	case USB_DIAG_WRITE_DONE:
 		index = (int)(d_req->context);
-		if (index == HSIC &&  driver->hsic_device_enabled)
-			diagfwd_write_complete_hsic(d_req);
-		else if (index == SMUX && driver->diag_smux_enabled)
+		if (index == SMUX && driver->diag_smux_enabled)
 			diagfwd_write_complete_smux();
+		else if (diag_hsic[index].hsic_device_enabled)
+			diagfwd_write_complete_hsic(d_req, index);
 		break;
 	default:
 		pr_err("diag: in %s: Unknown event from USB diag:%u\n",
@@ -240,14 +257,21 @@
 	int ret;
 	unsigned char name[20];
 
-	if (index == HSIC)
+	if (index == HSIC) {
 		strlcpy(name, "hsic", sizeof(name));
-	else
+	} else if (index == HSIC_2) {
+		strlcpy(name, "hsic_2", sizeof(name));
+	} else if (index == SMUX) {
 		strlcpy(name, "smux", sizeof(name));
+	} else {
+		pr_err("diag: incorrect bridge init, instance: %d\n", index);
+		return;
+	}
 
-	strlcpy(diag_bridge[index].name, name, sizeof(diag_bridge[index].name));
+	strlcpy(diag_bridge[index].name, name,
+				sizeof(diag_bridge[index].name));
 	strlcat(name, "_diag_wq", sizeof(diag_bridge[index].name));
-	diag_bridge[index].enabled = 1;
+	diag_bridge[index].id = index;
 	diag_bridge[index].wq = create_singlethread_workqueue(name);
 	diag_bridge[index].read_len = 0;
 	diag_bridge[index].write_len = 0;
@@ -268,24 +292,24 @@
 		goto err;
 	mutex_init(&diag_bridge[index].bridge_mutex);
 
-	if (index == HSIC) {
+	if (index == HSIC || index == HSIC_2) {
 		INIT_WORK(&(diag_bridge[index].usb_read_complete_work),
 				 diag_usb_read_complete_hsic_fn);
 #ifdef CONFIG_DIAG_OVER_USB
 		INIT_WORK(&(diag_bridge[index].diag_read_work),
 		      diag_read_usb_hsic_work_fn);
-		diag_bridge[index].ch = usb_diag_open(DIAG_MDM, (void *)index,
-						  diagfwd_bridge_notifier);
+		if (index == HSIC)
+			diag_bridge[index].ch = usb_diag_open(DIAG_MDM,
+				 (void *)index, diagfwd_bridge_notifier);
+		else if (index == HSIC_2)
+			diag_bridge[index].ch = usb_diag_open(DIAG_MDM2,
+				 (void *)index, diagfwd_bridge_notifier);
 		if (IS_ERR(diag_bridge[index].ch)) {
-			pr_err("diag: Unable to open USB diag MDM channel\n");
+			pr_err("diag: Unable to open USB MDM ch = %d\n", index);
 			goto err;
-		}
+		} else
+			diag_bridge[index].enabled = 1;
 #endif
-		/* register HSIC device */
-		ret = platform_driver_register(&msm_hsic_ch_driver);
-		if (ret)
-			pr_err("diag: could not register HSIC device, ret: %d\n",
-									 ret);
 	} else if (index == SMUX) {
 		INIT_WORK(&(diag_bridge[index].usb_read_complete_work),
 					 diag_usb_read_complete_smux_fn);
@@ -297,7 +321,8 @@
 		if (IS_ERR(diag_bridge[index].ch)) {
 			pr_err("diag: Unable to open USB diag QSC channel\n");
 			goto err;
-		}
+		} else
+			diag_bridge[index].enabled = 1;
 #endif
 		ret = platform_driver_register(&msm_diagfwd_smux_driver);
 		if (ret)
@@ -308,7 +333,7 @@
 err:
 	pr_err("diag: Could not initialize for bridge forwarding\n");
 	kfree(diag_bridge[index].usb_buf_out);
-	kfree(driver->hsic_buf_tbl);
+	kfree(diag_hsic[index].hsic_buf_tbl);
 	kfree(driver->write_ptr_mdm);
 	kfree(diag_bridge[index].usb_read_ptr);
 	if (diag_bridge[index].wq)
@@ -321,12 +346,15 @@
 	int i;
 	pr_debug("diag: in %s\n", __func__);
 
-	if (driver->hsic_device_enabled) {
-		diag_hsic_close();
-		driver->hsic_device_enabled = 0;
-		diag_bridge[HSIC].enabled = 0;
+	for (i = 0; i < MAX_HSIC_CH; i++) {
+		if (diag_hsic[i].hsic_device_enabled) {
+			diag_hsic_close(i);
+			diag_hsic[i].hsic_device_enabled = 0;
+			diag_bridge[i].enabled = 0;
+		}
+		diag_hsic[i].hsic_inited = 0;
+		kfree(diag_hsic[i].hsic_buf_tbl);
 	}
-	driver->hsic_inited = 0;
 	diagmem_exit(driver, POOL_TYPE_ALL);
 	if (driver->diag_smux_enabled) {
 		driver->lcid = LCID_INVALID;
@@ -350,6 +378,5 @@
 			diag_bridge[i].enabled = 0;
 		}
 	}
-	kfree(driver->hsic_buf_tbl);
 	kfree(driver->write_ptr_mdm);
 }
diff --git a/drivers/char/diag/diagfwd_bridge.h b/drivers/char/diag/diagfwd_bridge.h
index 06e6a96..88c96ab 100644
--- a/drivers/char/diag/diagfwd_bridge.h
+++ b/drivers/char/diag/diagfwd_bridge.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
@@ -17,7 +17,8 @@
 
 #define MAX_BRIDGES	5
 #define HSIC	0
-#define SMUX	1
+#define HSIC_2	1
+#define SMUX	4
 
 int diagfwd_connect_bridge(int);
 void connect_bridge(int, int);
@@ -30,6 +31,7 @@
  * for instance SMUX, HSIC working at same time
  */
 struct diag_bridge_dev {
+	int id;
 	char name[20];
 	int enabled;
 	struct mutex bridge_mutex;
diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c
index a900d97..7e58249 100644
--- a/drivers/char/diag/diagfwd_cntl.c
+++ b/drivers/char/diag/diagfwd_cntl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
@@ -44,6 +44,7 @@
 								int total_recd)
 {
 	int data_len = 0, type = -1, count_bytes = 0, j, flag = 0;
+	int feature_mask_len;
 	struct bindpkt_params_per_process *pkt_params =
 		kzalloc(sizeof(struct bindpkt_params_per_process), GFP_KERNEL);
 	struct diag_ctrl_msg *msg;
@@ -115,6 +116,11 @@
 				pr_err("diag: drop reg proc %d\n",
 						smd_info->peripheral);
 			kfree(temp);
+		} else if ((type == DIAG_CTRL_MSG_FEATURE) &&
+				(smd_info->peripheral == MODEM_DATA)) {
+			feature_mask_len = *(int *)(buf + 8);
+			driver->log_on_demand_support = (*(uint8_t *)
+							 (buf + 12)) & 0x04;
 		} else if (type != DIAG_CTRL_MSG_REG) {
 			flag = 1;
 		}
@@ -209,6 +215,7 @@
 
 	reg_dirty = 0;
 	driver->polling_reg_flag = 0;
+	driver->log_on_demand_support = 1;
 	driver->diag_cntl_wq = create_singlethread_workqueue("diag_cntl_wq");
 
 	success = diag_smd_constructor(&driver->smd_cntl[MODEM_DATA],
diff --git a/drivers/char/diag/diagfwd_cntl.h b/drivers/char/diag/diagfwd_cntl.h
index aeb4ba1..c28b06d 100644
--- a/drivers/char/diag/diagfwd_cntl.h
+++ b/drivers/char/diag/diagfwd_cntl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
@@ -77,6 +77,13 @@
 	/* Copy msg mask here */
 } __packed;
 
+struct diag_ctrl_feature_mask {
+	uint32_t ctrl_pkt_id;
+	uint32_t ctrl_pkt_data_len;
+	uint32_t feature_mask_len;
+	/* Copy feature mask here */
+} __packed;
+
 void diagfwd_cntl_init(void);
 void diagfwd_cntl_exit(void);
 void diag_read_smd_cntl_work_fn(struct work_struct *);
diff --git a/drivers/char/diag/diagfwd_hsic.c b/drivers/char/diag/diagfwd_hsic.c
index 3d5eea5..616c498 100644
--- a/drivers/char/diag/diagfwd_hsic.c
+++ b/drivers/char/diag/diagfwd_hsic.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -34,6 +34,7 @@
 #include "diagfwd_bridge.h"
 
 #define READ_HSIC_BUF_SIZE 2048
+struct diag_hsic_dev *diag_hsic;
 
 static void diag_read_hsic_work_fn(struct work_struct *work)
 {
@@ -41,9 +42,13 @@
 	int num_reads_submitted = 0;
 	int err = 0;
 	int write_ptrs_available;
+	struct diag_hsic_dev *hsic_struct = container_of(work,
+				struct diag_hsic_dev, diag_read_hsic_work);
+	int index = hsic_struct->id;
+	static DEFINE_RATELIMIT_STATE(rl, 10*HZ, 1);
 
-	if (!driver->hsic_ch) {
-		pr_err("DIAG in %s: driver->hsic_ch == 0\n", __func__);
+	if (!diag_hsic[index].hsic_ch) {
+		pr_err("DIAG in %s: diag_hsic[index].hsic_ch == 0\n", __func__);
 		return;
 	}
 
@@ -52,11 +57,12 @@
 	 * reading from the HSIC has completed.
 	 */
 	if (driver->logging_mode == MEMORY_DEVICE_MODE)
-		write_ptrs_available = driver->poolsize_hsic_write -
-					driver->num_hsic_buf_tbl_entries;
+		write_ptrs_available = diag_hsic[index].poolsize_hsic_write -
+					diag_hsic[index].
+						num_hsic_buf_tbl_entries;
 	else
-		write_ptrs_available = driver->poolsize_hsic_write -
-					driver->count_hsic_write_pool;
+		write_ptrs_available = diag_hsic[index].poolsize_hsic_write -
+					diag_hsic[index].count_hsic_write_pool;
 
 	/*
 	 * Queue up a read on the HSIC for all available buffers in the
@@ -76,11 +82,11 @@
 		 * No sense queuing a read if the HSIC bridge was
 		 * closed in another thread
 		 */
-		if (!driver->hsic_ch)
+		if (!diag_hsic[index].hsic_ch)
 			break;
 
 		buf_in_hsic = diagmem_alloc(driver, READ_HSIC_BUF_SIZE,
-							POOL_TYPE_HSIC);
+							index+POOL_TYPE_HSIC);
 		if (buf_in_hsic) {
 			/*
 			 * Initiate the read from the HSIC.  The HSIC read is
@@ -89,16 +95,17 @@
 			 */
 			pr_debug("diag: read from HSIC\n");
 			num_reads_submitted++;
-			err = diag_bridge_read((char *)buf_in_hsic,
+			err = diag_bridge_read(index, (char *)buf_in_hsic,
 							READ_HSIC_BUF_SIZE);
 			if (err) {
 				num_reads_submitted--;
 
 				/* Return the buffer to the pool */
 				diagmem_free(driver, buf_in_hsic,
-						POOL_TYPE_HSIC);
+						index+POOL_TYPE_HSIC);
 
-				pr_err_ratelimited("diag: Error initiating HSIC read, err: %d\n",
+				if (__ratelimit(&rl))
+					pr_err("diag: Error initiating HSIC read, err: %d\n",
 					err);
 				/*
 				 * An error occurred, discontinue queuing
@@ -114,25 +121,28 @@
 	 * read was not queued, and if no unrecoverable error occurred
 	 * (-ENODEV is an unrecoverable error), then set up the next read
 	 */
-	if ((driver->count_hsic_pool < driver->poolsize_hsic) &&
+	if ((diag_hsic[index].count_hsic_pool <
+		diag_hsic[index].poolsize_hsic) &&
 		(num_reads_submitted == 0) && (err != -ENODEV) &&
-		(driver->hsic_ch != 0))
-		queue_work(diag_bridge[HSIC].wq,
-				 &driver->diag_read_hsic_work);
+		(diag_hsic[index].hsic_ch != 0))
+		queue_work(diag_bridge[index].wq,
+				 &diag_hsic[index].diag_read_hsic_work);
 }
 
 static void diag_hsic_read_complete_callback(void *ctxt, char *buf,
 					int buf_size, int actual_size)
 {
 	int err = -2;
+	int index = (int)ctxt;
+	static DEFINE_RATELIMIT_STATE(rl, 10*HZ, 1);
 
-	if (!driver->hsic_ch) {
+	if (!diag_hsic[index].hsic_ch) {
 		/*
 		 * The HSIC channel is closed. Return the buffer to
 		 * the pool.  Do not send it on.
 		 */
-		diagmem_free(driver, buf, POOL_TYPE_HSIC);
-		pr_debug("diag: In %s: driver->hsic_ch == 0, actual_size: %d\n",
+		diagmem_free(driver, buf, index+POOL_TYPE_HSIC);
+		pr_debug("diag: In %s: hsic_ch == 0, actual_size: %d\n",
 			__func__, actual_size);
 		return;
 	}
@@ -150,12 +160,15 @@
 			 * Send data in buf to be written on the
 			 * appropriate device, e.g. USB MDM channel
 			 */
-			diag_bridge[HSIC].write_len = actual_size;
-			err = diag_device_write((void *)buf, HSIC_DATA, NULL);
+			diag_bridge[index].write_len = actual_size;
+			err = diag_device_write((void *)buf, index+HSIC_DATA,
+									NULL);
 			/* If an error, return buffer to the pool */
 			if (err) {
-				diagmem_free(driver, buf, POOL_TYPE_HSIC);
-				pr_err_ratelimited("diag: In %s, error calling diag_device_write, err: %d\n",
+				diagmem_free(driver, buf, index +
+							POOL_TYPE_HSIC);
+				if (__ratelimit(&rl))
+					pr_err("diag: In %s, error calling diag_device_write, err: %d\n",
 					__func__, err);
 			}
 		}
@@ -165,7 +178,7 @@
 		 * pass it on. Note that -ENOENT is sent when the diag bridge
 		 * is closed.
 		 */
-		diagmem_free(driver, buf, POOL_TYPE_HSIC);
+		diagmem_free(driver, buf, index+POOL_TYPE_HSIC);
 		pr_debug("diag: In %s: error status: %d\n", __func__,
 			actual_size);
 	}
@@ -176,108 +189,135 @@
 	 */
 	if (err &&
 		((driver->logging_mode == MEMORY_DEVICE_MODE) ||
-		(diag_bridge[HSIC].usb_connected && !driver->hsic_suspend))) {
-		queue_work(diag_bridge[HSIC].wq,
-				 &driver->diag_read_hsic_work);
+		(diag_bridge[index].usb_connected &&
+		!diag_hsic[index].hsic_suspend))) {
+		queue_work(diag_bridge[index].wq,
+				 &diag_hsic[index].diag_read_hsic_work);
 	}
 }
 
 static void diag_hsic_write_complete_callback(void *ctxt, char *buf,
 					int buf_size, int actual_size)
 {
-	/* The write of the data to the HSIC bridge is complete */
-	driver->in_busy_hsic_write = 0;
+	int index = (int)ctxt;
 
-	if (!driver->hsic_ch) {
-		pr_err("DIAG in %s: driver->hsic_ch == 0\n", __func__);
+	/* The write of the data to the HSIC bridge is complete */
+	diag_hsic[index].in_busy_hsic_write = 0;
+
+	if (!diag_hsic[index].hsic_ch) {
+		pr_err("DIAG in %s: hsic_ch == 0, ch = %d\n", __func__, index);
 		return;
 	}
 
 	if (actual_size < 0)
 		pr_err("DIAG in %s: actual_size: %d\n", __func__, actual_size);
 
-	if (diag_bridge[HSIC].usb_connected &&
+	if (diag_bridge[index].usb_connected &&
 				 (driver->logging_mode == USB_MODE))
-		queue_work(diag_bridge[HSIC].wq,
-				 &diag_bridge[HSIC].diag_read_work);
+		queue_work(diag_bridge[index].wq,
+				 &diag_bridge[index].diag_read_work);
 }
 
 static int diag_hsic_suspend(void *ctxt)
 {
+	int index = (int)ctxt;
 	pr_debug("diag: hsic_suspend\n");
 
 	/* Don't allow suspend if a write in the HSIC is in progress */
-	if (driver->in_busy_hsic_write)
+	if (diag_hsic[index].in_busy_hsic_write)
 		return -EBUSY;
 
 	/* Don't allow suspend if in MEMORY_DEVICE_MODE */
 	if (driver->logging_mode == MEMORY_DEVICE_MODE)
 		return -EBUSY;
 
-	driver->hsic_suspend = 1;
+	diag_hsic[index].hsic_suspend = 1;
 
 	return 0;
 }
 
 static void diag_hsic_resume(void *ctxt)
 {
-	pr_debug("diag: hsic_resume\n");
-	driver->hsic_suspend = 0;
+	 int index = (int)ctxt;
 
-	if ((driver->count_hsic_pool < driver->poolsize_hsic) &&
+	pr_debug("diag: hsic_resume\n");
+	diag_hsic[index].hsic_suspend = 0;
+
+	if ((diag_hsic[index].count_hsic_pool <
+		diag_hsic[index].poolsize_hsic) &&
 		((driver->logging_mode == MEMORY_DEVICE_MODE) ||
-				(diag_bridge[HSIC].usb_connected)))
-		queue_work(diag_bridge[HSIC].wq,
-			 &driver->diag_read_hsic_work);
+				(diag_bridge[index].usb_connected)))
+		queue_work(diag_bridge[index].wq,
+			 &diag_hsic[index].diag_read_hsic_work);
 }
 
-struct diag_bridge_ops hsic_diag_bridge_ops = {
+struct diag_bridge_ops hsic_diag_bridge_ops[MAX_HSIC_CH] = {
+	{
 	.ctxt = NULL,
 	.read_complete_cb = diag_hsic_read_complete_callback,
 	.write_complete_cb = diag_hsic_write_complete_callback,
 	.suspend = diag_hsic_suspend,
 	.resume = diag_hsic_resume,
+	},
+	{
+	.ctxt = NULL,
+	.read_complete_cb = diag_hsic_read_complete_callback,
+	.write_complete_cb = diag_hsic_write_complete_callback,
+	.suspend = diag_hsic_suspend,
+	.resume = diag_hsic_resume,
+	}
 };
 
-void diag_hsic_close(void)
+void diag_hsic_close(int ch_id)
 {
-	if (driver->hsic_device_enabled) {
-		driver->hsic_ch = 0;
-		if (driver->hsic_device_opened) {
-			driver->hsic_device_opened = 0;
-			diag_bridge_close();
-			pr_debug("diag: %s: closed successfully\n", __func__);
+	if (diag_hsic[ch_id].hsic_device_enabled) {
+		diag_hsic[ch_id].hsic_ch = 0;
+		if (diag_hsic[ch_id].hsic_device_opened) {
+			diag_hsic[ch_id].hsic_device_opened = 0;
+			diag_bridge_close(ch_id);
+			pr_debug("diag: %s: closed successfully ch %d\n",
+							__func__, ch_id);
 		} else {
-			pr_debug("diag: %s: already closed\n", __func__);
+			pr_debug("diag: %s: already closed ch %d\n",
+							__func__, ch_id);
 		}
 	} else {
-		pr_debug("diag: %s: HSIC device already removed\n", __func__);
+		pr_debug("diag: %s: HSIC device already removed ch %d\n",
+							__func__, ch_id);
 	}
 }
 
 /* diagfwd_cancel_hsic is called to cancel outstanding read/writes */
 int diagfwd_cancel_hsic(void)
 {
-	int err;
+	int err, i;
 
-	mutex_lock(&diag_bridge[HSIC].bridge_mutex);
-	if (driver->hsic_device_enabled) {
-		if (driver->hsic_device_opened) {
-			driver->hsic_ch = 0;
-			driver->hsic_device_opened = 0;
-			diag_bridge_close();
-			err = diag_bridge_open(&hsic_diag_bridge_ops);
-			if (err) {
-				pr_err("diag: HSIC channel open error: %d\n",
-					err);
-			} else {
-				pr_debug("diag: opened HSIC channel\n");
-				driver->hsic_device_opened = 1;
-				driver->hsic_ch = 1;
+	/* Cancel it for all active HSIC bridges */
+	for (i = 0; i < MAX_HSIC_CH; i++) {
+		if (!diag_bridge[i].enabled)
+			continue;
+		mutex_lock(&diag_bridge[i].bridge_mutex);
+		if (diag_hsic[i].hsic_device_enabled) {
+			if (diag_hsic[i].hsic_device_opened) {
+				diag_hsic[i].hsic_ch = 0;
+				diag_hsic[i].hsic_device_opened = 0;
+				diag_bridge_close(i);
+				hsic_diag_bridge_ops[i].ctxt = (void *)(i);
+				err = diag_bridge_open(i,
+						   &hsic_diag_bridge_ops[i]);
+				if (err) {
+					pr_err("diag: HSIC %d channel open error: %d\n",
+						 i, err);
+				} else {
+					pr_debug("diag: opened HSIC channel: %d\n",
+						i);
+					diag_hsic[i].hsic_device_opened = 1;
+					diag_hsic[i].hsic_ch = 1;
+				}
 			}
 		}
+		mutex_unlock(&diag_bridge[i].bridge_mutex);
 	}
-	mutex_unlock(&diag_bridge[HSIC].bridge_mutex);
 	return 0;
 }
 
@@ -285,38 +325,48 @@
  * diagfwd_write_complete_hsic is called after the asynchronous
  * usb_diag_write() on mdm channel is complete
  */
-int diagfwd_write_complete_hsic(struct diag_request *diag_write_ptr)
+int diagfwd_write_complete_hsic(struct diag_request *diag_write_ptr, int index)
 {
 	unsigned char *buf = (diag_write_ptr) ? diag_write_ptr->buf : NULL;
 
 	if (buf) {
 		/* Return buffers to their pools */
-		diagmem_free(driver, (unsigned char *)buf, POOL_TYPE_HSIC);
+		diagmem_free(driver, (unsigned char *)buf, index +
+							POOL_TYPE_HSIC);
 		diagmem_free(driver, (unsigned char *)diag_write_ptr,
+							index +
 							POOL_TYPE_HSIC_WRITE);
 	}
 
-	if (!driver->hsic_ch) {
-		pr_err("diag: In %s: driver->hsic_ch == 0\n", __func__);
+	if (!diag_hsic[index].hsic_ch) {
+		pr_err("diag: In %s: hsic_ch == 0\n", __func__);
 		return 0;
 	}
 
 	/* Read data from the HSIC */
-	queue_work(diag_bridge[HSIC].wq, &driver->diag_read_hsic_work);
+	queue_work(diag_bridge[index].wq,
+				&diag_hsic[index].diag_read_hsic_work);
 
 	return 0;
 }
 
 void diag_usb_read_complete_hsic_fn(struct work_struct *w)
 {
-	diagfwd_read_complete_bridge(diag_bridge[HSIC].usb_read_ptr);
-}
+	struct diag_bridge_dev *bridge_struct = container_of(w,
+			struct diag_bridge_dev, usb_read_complete_work);
 
+	diagfwd_read_complete_bridge(
+			diag_bridge[bridge_struct->id].usb_read_ptr);
+}
 
 void diag_read_usb_hsic_work_fn(struct work_struct *work)
 {
-	if (!driver->hsic_ch) {
-		pr_err("diag: in %s: driver->hsic_ch == 0\n", __func__);
+	struct diag_bridge_dev *bridge_struct = container_of(work,
+				struct diag_bridge_dev, diag_read_work);
+	int index = bridge_struct->id;
+
+	if (!diag_hsic[index].hsic_ch) {
+		pr_err("diag: in %s: hsic_ch == 0\n", __func__);
 		return;
 	}
 	/*
@@ -324,104 +374,114 @@
 	 * and there is no mdm channel data currently being written
 	 * to the HSIC
 	 */
-	if (!driver->in_busy_hsic_read_on_device &&
-	     !driver->in_busy_hsic_write) {
+	if (!diag_hsic[index].in_busy_hsic_read_on_device &&
+	     !diag_hsic[index].in_busy_hsic_write) {
 		APPEND_DEBUG('x');
 		/* Setup the next read from usb mdm channel */
-		driver->in_busy_hsic_read_on_device = 1;
-		diag_bridge[HSIC].usb_read_ptr->buf =
-				 diag_bridge[HSIC].usb_buf_out;
-		diag_bridge[HSIC].usb_read_ptr->length = USB_MAX_OUT_BUF;
-		diag_bridge[HSIC].usb_read_ptr->context = (void *)HSIC;
-		usb_diag_read(diag_bridge[HSIC].ch,
-				 diag_bridge[HSIC].usb_read_ptr);
+		diag_hsic[index].in_busy_hsic_read_on_device = 1;
+		diag_bridge[index].usb_read_ptr->buf =
+				 diag_bridge[index].usb_buf_out;
+		diag_bridge[index].usb_read_ptr->length = USB_MAX_OUT_BUF;
+		diag_bridge[index].usb_read_ptr->context = (void *)index;
+		usb_diag_read(diag_bridge[index].ch,
+				 diag_bridge[index].usb_read_ptr);
 		APPEND_DEBUG('y');
 	}
 	/* If for some reason there was no mdm channel read initiated,
 	 * queue up the reading of data from the mdm channel
 	 */
 
-	if (!driver->in_busy_hsic_read_on_device &&
+	if (!diag_hsic[index].in_busy_hsic_read_on_device &&
 		(driver->logging_mode == USB_MODE))
-		queue_work(diag_bridge[HSIC].wq,
-			 &(diag_bridge[HSIC].diag_read_work));
+		queue_work(diag_bridge[index].wq,
+			 &(diag_bridge[index].diag_read_work));
 }
 
 static int diag_hsic_probe(struct platform_device *pdev)
 {
 	int err = 0;
 
-	pr_debug("diag: in %s\n", __func__);
-	mutex_lock(&diag_bridge[HSIC].bridge_mutex);
-	if (!driver->hsic_inited) {
-		spin_lock_init(&driver->hsic_spinlock);
-		driver->num_hsic_buf_tbl_entries = 0;
-		if (driver->hsic_buf_tbl == NULL)
-			driver->hsic_buf_tbl = kzalloc(NUM_HSIC_BUF_TBL_ENTRIES
-				* sizeof(struct diag_write_device), GFP_KERNEL);
-		if (driver->hsic_buf_tbl == NULL) {
-			mutex_unlock(&diag_bridge[HSIC].bridge_mutex);
+	/* pdev->Id will indicate which HSIC is working. 0 stands for HSIC
+	 *  or CP1 1 indicates HS-USB or CP2
+	 */
+	pr_debug("diag: in %s, ch = %d\n", __func__, pdev->id);
+	mutex_lock(&diag_bridge[pdev->id].bridge_mutex);
+	if (!diag_hsic[pdev->id].hsic_inited) {
+		spin_lock_init(&diag_hsic[pdev->id].hsic_spinlock);
+		diag_hsic[pdev->id].num_hsic_buf_tbl_entries = 0;
+		if (diag_hsic[pdev->id].hsic_buf_tbl == NULL)
+			diag_hsic[pdev->id].hsic_buf_tbl =
+				kzalloc(NUM_HSIC_BUF_TBL_ENTRIES *
+				sizeof(struct diag_write_device), GFP_KERNEL);
+		if (diag_hsic[pdev->id].hsic_buf_tbl == NULL) {
+			mutex_unlock(&diag_bridge[pdev->id].bridge_mutex);
 			return -ENOMEM;
 		}
-		driver->count_hsic_pool = 0;
-		driver->count_hsic_write_pool = 0;
-		driver->itemsize_hsic = READ_HSIC_BUF_SIZE;
-		driver->poolsize_hsic = N_MDM_WRITE;
-		driver->itemsize_hsic_write = sizeof(struct diag_request);
-		driver->poolsize_hsic_write = N_MDM_WRITE;
-		diagmem_hsic_init(driver);
-		INIT_WORK(&(driver->diag_read_hsic_work),
+		diag_hsic[pdev->id].id = pdev->id;
+		diag_hsic[pdev->id].count_hsic_pool = 0;
+		diag_hsic[pdev->id].count_hsic_write_pool = 0;
+		diag_hsic[pdev->id].itemsize_hsic = READ_HSIC_BUF_SIZE;
+		diag_hsic[pdev->id].poolsize_hsic = N_MDM_WRITE;
+		diag_hsic[pdev->id].itemsize_hsic_write =
+					sizeof(struct diag_request);
+		diag_hsic[pdev->id].poolsize_hsic_write = N_MDM_WRITE;
+		diagmem_hsic_init(pdev->id);
+		INIT_WORK(&(diag_hsic[pdev->id].diag_read_hsic_work),
 			    diag_read_hsic_work_fn);
-		driver->hsic_inited = 1;
+		diag_hsic[pdev->id].hsic_inited = 1;
 	}
 	/*
 	 * The probe function was called after the usb was connected
 	 * on the legacy channel OR ODL is turned on. Communication over usb
 	 * mdm and HSIC needs to be turned on.
 	 */
-	if (diag_bridge[HSIC].usb_connected || (driver->logging_mode ==
+	if (diag_bridge[pdev->id].usb_connected || (driver->logging_mode ==
 						   MEMORY_DEVICE_MODE)) {
-		if (driver->hsic_device_opened) {
+		if (diag_hsic[pdev->id].hsic_device_opened) {
 			/* should not happen. close it before re-opening */
 			pr_warn("diag: HSIC channel already opened in probe\n");
-			diag_bridge_close();
+			diag_bridge_close(pdev->id);
 		}
-		err = diag_bridge_open(&hsic_diag_bridge_ops);
+		hsic_diag_bridge_ops[pdev->id].ctxt = (void *)(pdev->id);
+		err = diag_bridge_open(pdev->id,
+				       &hsic_diag_bridge_ops[pdev->id]);
 		if (err) {
 			pr_err("diag: could not open HSIC, err: %d\n", err);
-			driver->hsic_device_opened = 0;
-			mutex_unlock(&diag_bridge[HSIC].bridge_mutex);
+			diag_hsic[pdev->id].hsic_device_opened = 0;
+			mutex_unlock(&diag_bridge[pdev->id].bridge_mutex);
 			return err;
 		}
 
-		pr_info("diag: opened HSIC channel\n");
-		driver->hsic_device_opened = 1;
-		driver->hsic_ch = 1;
-		driver->in_busy_hsic_read_on_device = 0;
-		driver->in_busy_hsic_write = 0;
+		pr_info("diag: opened HSIC bridge, ch = %d\n", pdev->id);
+		diag_hsic[pdev->id].hsic_device_opened = 1;
+		diag_hsic[pdev->id].hsic_ch = 1;
+		diag_hsic[pdev->id].in_busy_hsic_read_on_device = 0;
+		diag_hsic[pdev->id].in_busy_hsic_write = 0;
 
-		if (diag_bridge[HSIC].usb_connected) {
+		if (diag_bridge[pdev->id].usb_connected) {
 			/* Poll USB mdm channel to check for data */
-			queue_work(diag_bridge[HSIC].wq,
-			     &diag_bridge[HSIC].diag_read_work);
+			queue_work(diag_bridge[pdev->id].wq,
+			     &diag_bridge[pdev->id].diag_read_work);
 		}
 		/* Poll HSIC channel to check for data */
-		queue_work(diag_bridge[HSIC].wq,
-			  &driver->diag_read_hsic_work);
+		queue_work(diag_bridge[pdev->id].wq,
+			  &diag_hsic[pdev->id].diag_read_hsic_work);
 	}
 	/* The HSIC (diag_bridge) platform device driver is enabled */
-	driver->hsic_device_enabled = 1;
-	mutex_unlock(&diag_bridge[HSIC].bridge_mutex);
+	diag_hsic[pdev->id].hsic_device_enabled = 1;
+	mutex_unlock(&diag_bridge[pdev->id].bridge_mutex);
 	return err;
 }
 
 static int diag_hsic_remove(struct platform_device *pdev)
 {
 	pr_debug("diag: %s called\n", __func__);
-	mutex_lock(&diag_bridge[HSIC].bridge_mutex);
-	diag_hsic_close();
-	driver->hsic_device_enabled = 0;
-	mutex_unlock(&diag_bridge[HSIC].bridge_mutex);
+	if (diag_hsic[pdev->id].hsic_device_enabled) {
+		mutex_lock(&diag_bridge[pdev->id].bridge_mutex);
+		diag_hsic_close(pdev->id);
+		diag_hsic[pdev->id].hsic_device_enabled = 0;
+		mutex_unlock(&diag_bridge[pdev->id].bridge_mutex);
+	}
 
 	return 0;
 }
diff --git a/drivers/char/diag/diagfwd_hsic.h b/drivers/char/diag/diagfwd_hsic.h
index 2190fff..d171efa 100644
--- a/drivers/char/diag/diagfwd_hsic.h
+++ b/drivers/char/diag/diagfwd_hsic.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -18,13 +18,39 @@
 #define N_MDM_WRITE	8
 #define N_MDM_READ	1
 #define NUM_HSIC_BUF_TBL_ENTRIES N_MDM_WRITE
-
-int diagfwd_write_complete_hsic(struct diag_request *);
+#define MAX_HSIC_CH	4
+int diagfwd_write_complete_hsic(struct diag_request *, int index);
 int diagfwd_cancel_hsic(void);
 void diag_read_usb_hsic_work_fn(struct work_struct *work);
 void diag_usb_read_complete_hsic_fn(struct work_struct *w);
-extern struct diag_bridge_ops hsic_diag_bridge_ops;
+extern struct diag_bridge_ops hsic_diag_bridge_ops[MAX_HSIC_CH];
 extern struct platform_driver msm_hsic_ch_driver;
-void diag_hsic_close(void);
+void diag_hsic_close(int);
+
+/* Diag-HSIC structure, n HSIC bridges can be used at same time
+ * for instance HSIC(0), HS-USB(1) working at same time
+ */
+struct diag_hsic_dev {
+	int id;
+	int hsic_ch;
+	int hsic_inited;
+	int hsic_device_enabled;
+	int hsic_device_opened;
+	int hsic_suspend;
+	int in_busy_hsic_read_on_device;
+	int in_busy_hsic_write;
+	struct work_struct diag_read_hsic_work;
+	int count_hsic_pool;
+	int count_hsic_write_pool;
+	unsigned int poolsize_hsic;
+	unsigned int poolsize_hsic_write;
+	unsigned int itemsize_hsic;
+	unsigned int itemsize_hsic_write;
+	mempool_t *diag_hsic_pool;
+	mempool_t *diag_hsic_write_pool;
+	int num_hsic_buf_tbl_entries;
+	struct diag_write_device *hsic_buf_tbl;
+	spinlock_t hsic_spinlock;
+};
 
 #endif
diff --git a/drivers/char/diag/diagfwd_sdio.c b/drivers/char/diag/diagfwd_sdio.c
index a145c06..7d4e0d5 100644
--- a/drivers/char/diag/diagfwd_sdio.c
+++ b/drivers/char/diag/diagfwd_sdio.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
@@ -105,8 +105,8 @@
 {
 	int err;
 
-	err = usb_diag_alloc_req(driver->mdm_ch, N_MDM_WRITE,
-							 N_MDM_READ);
+	err = usb_diag_alloc_req(driver->mdm_ch, N_MDM_SDIO_WRITE,
+							 N_MDM_SDIO_READ);
 	if (err)
 		pr_err("diag: unable to alloc USB req on mdm ch\n");
 
diff --git a/drivers/char/diag/diagfwd_sdio.h b/drivers/char/diag/diagfwd_sdio.h
index 40982c3..bde4776 100644
--- a/drivers/char/diag/diagfwd_sdio.h
+++ b/drivers/char/diag/diagfwd_sdio.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
@@ -14,8 +14,8 @@
 #define DIAGFWD_SDIO_H
 
 #include <mach/sdio_al.h>
-#define N_MDM_WRITE	1 /* Upgrade to 2 with ping pong buffer */
-#define N_MDM_READ	1
+#define N_MDM_SDIO_WRITE	1 /* Upgrade to 2 with ping pong buffer */
+#define N_MDM_SDIO_READ	1
 
 void diagfwd_sdio_init(void);
 void diagfwd_sdio_exit(void);
diff --git a/drivers/char/diag/diagfwd_smux.c b/drivers/char/diag/diagfwd_smux.c
index 0a97baf..a775983 100644
--- a/drivers/char/diag/diagfwd_smux.c
+++ b/drivers/char/diag/diagfwd_smux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/char/diag/diagfwd_smux.h b/drivers/char/diag/diagfwd_smux.h
index b45fd5d..fcf19d2 100644
--- a/drivers/char/diag/diagfwd_smux.h
+++ b/drivers/char/diag/diagfwd_smux.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/char/diag/diagmem.c b/drivers/char/diag/diagmem.c
index ab1aa75..0cd8267 100644
--- a/drivers/char/diag/diagmem.c
+++ b/drivers/char/diag/diagmem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
@@ -17,11 +17,15 @@
 #include <linux/mutex.h>
 #include <asm/atomic.h>
 #include "diagchar.h"
+#include "diagfwd_bridge.h"
+#include "diagfwd_hsic.h"
 
 void *diagmem_alloc(struct diagchar_dev *driver, int size, int pool_type)
 {
 	void *buf = NULL;
+	int index;
 
+	index = 0;
 	if (pool_type == POOL_TYPE_COPY) {
 		if (driver->diagpool) {
 			mutex_lock(&driver->diagmem_mutex);
@@ -52,23 +56,30 @@
 			}
 		}
 #ifdef CONFIG_DIAGFWD_BRIDGE_CODE
-	} else if (pool_type == POOL_TYPE_HSIC) {
-		if (driver->diag_hsic_pool) {
-			if (driver->count_hsic_pool < driver->poolsize_hsic) {
-				atomic_add(1,
-					(atomic_t *)&driver->count_hsic_pool);
-				buf = mempool_alloc(driver->diag_hsic_pool,
-								GFP_ATOMIC);
+	} else if (pool_type == POOL_TYPE_HSIC ||
+				pool_type == POOL_TYPE_HSIC_2) {
+		index = pool_type - POOL_TYPE_HSIC;
+		if (diag_hsic[index].diag_hsic_pool) {
+			if (diag_hsic[index].count_hsic_pool <
+					diag_hsic[index].poolsize_hsic) {
+				atomic_add(1, (atomic_t *)
+					&diag_hsic[index].count_hsic_pool);
+				buf = mempool_alloc(
+					diag_hsic[index].diag_hsic_pool,
+					GFP_ATOMIC);
 			}
 		}
-	} else if (pool_type == POOL_TYPE_HSIC_WRITE) {
-		if (driver->diag_hsic_write_pool) {
-			if (driver->count_hsic_write_pool <
-				driver->poolsize_hsic_write) {
+	} else if (pool_type == POOL_TYPE_HSIC_WRITE ||
+					pool_type == POOL_TYPE_HSIC_2_WRITE) {
+		index = pool_type - POOL_TYPE_HSIC_WRITE;
+		if (diag_hsic[index].diag_hsic_write_pool) {
+			if (diag_hsic[index].count_hsic_write_pool <
+				diag_hsic[index].poolsize_hsic_write) {
 				atomic_add(1, (atomic_t *)
-					&driver->count_hsic_write_pool);
+					&diag_hsic[index].
+					count_hsic_write_pool);
 				buf = mempool_alloc(
-					driver->diag_hsic_write_pool,
+					diag_hsic[index].diag_hsic_write_pool,
 					GFP_ATOMIC);
 			}
 		}
@@ -79,11 +90,15 @@
 
 void diagmem_exit(struct diagchar_dev *driver, int pool_type)
 {
+	int index;
+	index = 0;
+
 	if (driver->diagpool) {
 		if (driver->count == 0 && driver->ref_count == 0) {
 			mempool_destroy(driver->diagpool);
 			driver->diagpool = NULL;
-		} else if (driver->ref_count == 0 && pool_type == POOL_TYPE_ALL)
+		} else if (driver->ref_count == 0 && pool_type ==
+							POOL_TYPE_ALL)
 			printk(KERN_ALERT "Unable to destroy COPY mempool");
 	}
 
@@ -91,7 +106,8 @@
 		if (driver->count_hdlc_pool == 0 && driver->ref_count == 0) {
 			mempool_destroy(driver->diag_hdlc_pool);
 			driver->diag_hdlc_pool = NULL;
-		} else if (driver->ref_count == 0 && pool_type == POOL_TYPE_ALL)
+		} else if (driver->ref_count == 0 && pool_type ==
+							POOL_TYPE_ALL)
 			printk(KERN_ALERT "Unable to destroy HDLC mempool");
 	}
 
@@ -102,35 +118,46 @@
 		 driver->count_hdlc_pool == 0 && driver->ref_count == 0) {
 			mempool_destroy(driver->diag_write_struct_pool);
 			driver->diag_write_struct_pool = NULL;
-		} else if (driver->ref_count == 0 && pool_type == POOL_TYPE_ALL)
+		} else if (driver->ref_count == 0 && pool_type ==
+								POOL_TYPE_ALL)
 			printk(KERN_ALERT "Unable to destroy STRUCT mempool");
 	}
 #ifdef CONFIG_DIAGFWD_BRIDGE_CODE
-	if (driver->diag_hsic_pool && (driver->hsic_inited == 0)) {
-		if (driver->count_hsic_pool == 0) {
-			mempool_destroy(driver->diag_hdlc_pool);
-			driver->diag_hdlc_pool = NULL;
-		} else if (pool_type == POOL_TYPE_ALL)
-			pr_err("Unable to destroy HDLC mempool");
-	}
+	for (index = 0; index < MAX_HSIC_CH; index++) {
+		if (diag_hsic[index].diag_hsic_pool &&
+				(diag_hsic[index].hsic_inited == 0)) {
+			if (diag_hsic[index].count_hsic_pool == 0) {
+				mempool_destroy(driver->diag_hdlc_pool);
+				driver->diag_hdlc_pool = NULL;
+			} else if (pool_type == POOL_TYPE_ALL)
+				pr_err("Unable to destroy HDLC mempool for ch %d"
+								, index);
+		}
 
-	if (driver->diag_hsic_write_pool && (driver->hsic_inited == 0)) {
-		/*
-		 * Free up struct pool ONLY if there are no outstanding
-		 * transactions(aggregation buffer) with USB
-		 */
-		if (driver->count_hsic_write_pool == 0 &&
-			driver->count_hsic_pool == 0) {
-			mempool_destroy(driver->diag_hsic_write_pool);
-			driver->diag_hsic_write_pool = NULL;
-		} else if (pool_type == POOL_TYPE_ALL)
-			pr_err("Unable to destroy HSIC USB struct mempool");
+		if (diag_hsic[index].diag_hsic_write_pool &&
+					(diag_hsic[index].hsic_inited == 0)) {
+			/*
+			 * Free up struct pool ONLY if there are no outstanding
+			 * transactions(aggregation buffer) with USB
+			 */
+			if (diag_hsic[index].count_hsic_write_pool == 0 &&
+				diag_hsic[index].count_hsic_pool == 0) {
+				mempool_destroy(
+					diag_hsic[index].diag_hsic_write_pool);
+				diag_hsic[index].diag_hsic_write_pool = NULL;
+			} else if (pool_type == POOL_TYPE_ALL)
+				pr_err("Unable to destroy HSIC USB struct mempool for ch %d"
+								, index);
+		}
 	}
 #endif
 }
 
 void diagmem_free(struct diagchar_dev *driver, void *buf, int pool_type)
 {
+	int index;
+
+	index = 0;
 	if (pool_type == POOL_TYPE_COPY) {
 		if (driver->diagpool != NULL && driver->count > 0) {
 			mempool_free(buf, driver->diagpool);
@@ -157,23 +184,29 @@
 			   "USB structure mempool which is already free %d ",
 				    driver->count_write_struct_pool);
 #ifdef CONFIG_DIAGFWD_BRIDGE_CODE
-	} else if (pool_type == POOL_TYPE_HSIC) {
-		if (driver->diag_hsic_pool != NULL &&
-			driver->count_hsic_pool > 0) {
-			mempool_free(buf, driver->diag_hsic_pool);
-			atomic_add(-1, (atomic_t *)&driver->count_hsic_pool);
+	} else if (pool_type == POOL_TYPE_HSIC ||
+				pool_type == POOL_TYPE_HSIC_2) {
+		index = pool_type - POOL_TYPE_HSIC;
+		if (diag_hsic[index].diag_hsic_pool != NULL &&
+			diag_hsic[index].count_hsic_pool > 0) {
+			mempool_free(buf, diag_hsic[index].diag_hsic_pool);
+			atomic_add(-1, (atomic_t *)
+				   &diag_hsic[index].count_hsic_pool);
 		} else
-			pr_err("diag: Attempt to free up DIAG driver HSIC mempool which is already free %d ",
-				driver->count_hsic_pool);
-	} else if (pool_type == POOL_TYPE_HSIC_WRITE) {
-		if (driver->diag_hsic_write_pool != NULL &&
-			driver->count_hsic_write_pool > 0) {
-			mempool_free(buf, driver->diag_hsic_write_pool);
-			atomic_add(-1,
-				(atomic_t *)&driver->count_hsic_write_pool);
+			pr_err("diag: Attempt to free up DIAG driver HSIC mempool which is already free %d, ch = %d",
+				diag_hsic[index].count_hsic_pool, index);
+	} else if (pool_type == POOL_TYPE_HSIC_WRITE ||
+				pool_type == POOL_TYPE_HSIC_2_WRITE) {
+		index = pool_type - POOL_TYPE_HSIC_WRITE;
+		if (diag_hsic[index].diag_hsic_write_pool != NULL &&
+			diag_hsic[index].count_hsic_write_pool > 0) {
+			mempool_free(buf,
+					diag_hsic[index].diag_hsic_write_pool);
+			atomic_add(-1, (atomic_t *)
+				&diag_hsic[index].count_hsic_write_pool);
 		} else
-			pr_err("diag: Attempt to free up DIAG driver HSIC USB structure mempool which is already free %d ",
-				driver->count_write_struct_pool);
+			pr_err("diag: Attempt to free up DIAG driver HSIC USB structure mempool which is already free %d, ch = %d",
+				driver->count_write_struct_pool, index);
 #endif
 	} else {
 		pr_err("diag: In %s, unknown pool type: %d\n",
@@ -211,23 +244,25 @@
 }
 
 #ifdef CONFIG_DIAGFWD_BRIDGE_CODE
-void diagmem_hsic_init(struct diagchar_dev *driver)
+void diagmem_hsic_init(int index)
 {
-	if (driver->count_hsic_pool == 0)
-		driver->diag_hsic_pool = mempool_create_kmalloc_pool(
-					driver->poolsize_hsic,
-					driver->itemsize_hsic);
+	if (diag_hsic[index].count_hsic_pool == 0)
+		diag_hsic[index].diag_hsic_pool = mempool_create_kmalloc_pool(
+					diag_hsic[index].poolsize_hsic,
+					diag_hsic[index].itemsize_hsic);
 
-	if (driver->count_hsic_write_pool == 0)
-		driver->diag_hsic_write_pool = mempool_create_kmalloc_pool(
-					driver->poolsize_hsic_write,
-					driver->itemsize_hsic_write);
+	if (diag_hsic[index].count_hsic_write_pool == 0)
+		diag_hsic[index].diag_hsic_write_pool =
+				mempool_create_kmalloc_pool(
+					diag_hsic[index].poolsize_hsic_write,
+					diag_hsic[index].itemsize_hsic_write);
 
-	if (!driver->diag_hsic_pool)
-		pr_err("Cannot allocate diag HSIC mempool\n");
+	if (!diag_hsic[index].diag_hsic_pool)
+		pr_err("Cannot allocate diag HSIC mempool for ch %d\n", index);
 
-	if (!driver->diag_hsic_write_pool)
-		pr_err("Cannot allocate diag HSIC struct mempool\n");
+	if (!diag_hsic[index].diag_hsic_write_pool)
+		pr_err("Cannot allocate diag HSIC struct mempool for ch %d\n",
+									index);
 
 }
 #endif
diff --git a/drivers/char/diag/diagmem.h b/drivers/char/diag/diagmem.h
index 36def72f..f478263 100644
--- a/drivers/char/diag/diagmem.h
+++ b/drivers/char/diag/diagmem.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
@@ -19,6 +19,6 @@
 void diagmem_init(struct diagchar_dev *driver);
 void diagmem_exit(struct diagchar_dev *driver, int pool_type);
 #ifdef CONFIG_DIAGFWD_BRIDGE_CODE
-void diagmem_hsic_init(struct diagchar_dev *driver);
+void diagmem_hsic_init(int index);
 #endif
 #endif
diff --git a/drivers/char/hw_random/msm_rng.c b/drivers/char/hw_random/msm_rng.c
index f2e5439..261af7d 100644
--- a/drivers/char/hw_random/msm_rng.c
+++ b/drivers/char/hw_random/msm_rng.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
@@ -266,6 +266,6 @@
 
 module_exit(msm_rng_exit);
 
-MODULE_AUTHOR("Code Aurora Forum");
+MODULE_AUTHOR("The Linux Foundation");
 MODULE_DESCRIPTION("Qualcomm MSM Random Number Driver");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/char/msm_rotator.c b/drivers/char/msm_rotator.c
index b3843fa..2f87803 100644
--- a/drivers/char/msm_rotator.c
+++ b/drivers/char/msm_rotator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/drivers/char/msm_smd_pkt.c b/drivers/char/msm_smd_pkt.c
index adb2926..cc85fa1 100644
--- a/drivers/char/msm_smd_pkt.c
+++ b/drivers/char/msm_smd_pkt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/drivers/char/tpm/tpm_st_i2c.c b/drivers/char/tpm/tpm_st_i2c.c
index 3a6e8c4f..333548e 100644
--- a/drivers/char/tpm/tpm_st_i2c.c
+++ b/drivers/char/tpm/tpm_st_i2c.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/coresight/Kconfig b/drivers/coresight/Kconfig
index ea4ad4f..5e00570 100644
--- a/drivers/coresight/Kconfig
+++ b/drivers/coresight/Kconfig
@@ -1,51 +1,144 @@
-config MSM_QDSS
-	bool "CoreSight tracing"
+menuconfig CORESIGHT
+	bool "CoreSight Tracing Support"
 	help
-	  Enables support for CoreSight tracing. This uses CoreSight trace
-	  components and buses to support both hardware (eg. processor ETM)
-	  and hardware assisted software instrumentation based (eg. STM)
-	  tracing.
+	  CoreSight components are compliant with the ARM CoreSight
+	  architecture specification and can be connected in various
+	  topologies to suite a particular SoCs tracing needs. These trace
+	  components can generally be classified as sources, links and
+	  sinks. Trace data produced by one or more sources flows through
+	  the intermediate links connecting the source to the currently
+	  selected sink.
 
-	  For production builds, you should probably say 'N' here to avoid
-	  potential power, performance and memory penalty.
+	  This framework provides an interface for the CoreSight debug and
+	  trace drivers to register themselves with. It's intended to build
+	  up a topological view of the CoreSight components and configure
+	  the right series of components on user input via sysfs. It also
+	  provides status information to user space applications through
+	  sysfs interface.
 
-config MSM_QDSS_STM_DEFAULT_ENABLE
-	bool "Turn on CoreSight STM tracing by default"
-	depends on MSM_QDSS
+	  If unsure, say 'N' here to avoid potential power, performance and
+	  memory penalty.
+
+if CORESIGHT
+
+config HAVE_CORESIGHT_SINK
+	bool
+
+config CORESIGHT_CTI
+	bool "CoreSight Cross Trigger Interface driver"
+	help
+	  This driver provides support for Cross Trigger Interface that is
+	  used to input or output i.e. pass cross trigger events from one
+	  hardware component to another. It can also be used to pass
+	  software generated events.
+
+config CORESIGHT_CSR
+	bool "CoreSight Slave Register driver"
+	help
+	  This driver provides support for CoreSight Slave Register block
+	  that hosts miscellaneous configuration registers.
+
+config CORESIGHT_TMC
+	bool "CoreSight Trace Memory Controller driver"
+	select CORESIGHT_CTI
+	select CORESIGHT_CSR
+	select HAVE_CORESIGHT_SINK
+	help
+	  This driver provides support for Trace Memory Controller which
+	  can be configured as either an ETB (Embedded Trace Buffer),
+	  ETR (Embedded Trace Router) or ETF (Embedded Trace Fifo). It acts
+	  as sink when configured as ETB, ETR or ETF in circular buffer mode
+	  whereas it is a link when configured as ETF in hardware fifo mode.
+
+	  ETB collects trace data in a circular buffer whereas ETR can be
+	  used to route trace data to memory allocated in RAM. ETF in
+	  circular buffer mode is like an ETB whereas in hardware fifo mode
+	  it is a fifo link.
+
+config CORESIGHT_TPIU
+	bool "CoreSight Trace Port Interface Unit driver"
+	select HAVE_CORESIGHT_SINK
+	help
+	  This driver provides support for Trace Port Interface Unit which
+	  acts as a conduit for offchip trace collection.
+
+config CORESIGHT_ETB
+	bool "CoreSight Embedded Trace Buffer driver"
+	select HAVE_CORESIGHT_SINK
+	help
+	  This driver provides support for the legacy Embedded Trace Buffer
+	  which is a circular buffer.
+
+if HAVE_CORESIGHT_SINK
+
+config CORESIGHT_FUNNEL
+	bool "CoreSight Funnel driver"
+	help
+	  This driver provides support for Funnel which is a link that
+	  typically has multiple input ports and a single output port. Input
+	  trace data streams from the input ports are interleaved into a
+	  single output trace data stream coming out of the output port.
+
+config CORESIGHT_REPLICATOR
+	bool "CoreSight Replicator driver"
+	help
+	  This driver provides support for Replicator that typically has
+	  a single input port and two output ports. Single trace data
+	  stream on the input port is replicated to produce two identical
+	  trace data output streams coming out of the two output ports.
+
+config CORESIGHT_STM
+	bool "CoreSight System Trace Macrocell driver"
+	help
+	  This driver provides support for hardware assisted software
+	  instrumentation based tracing. This is primarily useful for
+	  logging useful software events or data.
+
+config CORESIGHT_STM_DEFAULT_ENABLE
+	bool "Turn on STM tracing by default"
+	depends on CORESIGHT_STM
 	help
 	  Turns on CoreSight STM tracing (hardware assisted software
 	  instrumentation based tracing) by default. Otherwise, tracing is
 	  disabled by default but can be enabled via sysfs.
 
-	  For production builds, you should probably say 'N' here to avoid
-	  potential power, performance and memory penalty.
+	  If unsure, say 'N' here to avoid potential power and performance
+	  penalty.
 
-config MSM_QDSS_ETM_DEFAULT_ENABLE
-	bool "Turn on CoreSight ETM tracing by default"
-	depends on MSM_QDSS
+config CORESIGHT_ETM
+	bool "CoreSight Embedded Trace Macrocell driver"
+	help
+	  This driver provides support for processor tracing which allows
+	  tracing the instructions that the processor is executing. This is
+	  primarily useful for instruction level tracing.
+
+config CORESIGHT_ETM_DEFAULT_ENABLE
+	bool "Turn on ETM tracing by default"
+	depends on CORESIGHT_ETM
 	help
 	  Turns on CoreSight ETM tracing (processor tracing) by default.
 	  Otherwise, tracing is disabled by default but can be enabled via
 	  sysfs.
 
-	  For production builds, you should probably say 'N' here to avoid
-	  potential power, performance and memory penalty.
+	  If unsure, say 'N' here to avoid potential power and performance
+	  penalty.
 
-config MSM_QDSS_ETM_PCSAVE_DEFAULT_ENABLE
+config CORESIGHT_ETM_PCSAVE_DEFAULT_ENABLE
 	bool "Turn on PC saving by default"
-	depends on MSM_QDSS
+	depends on CORESIGHT_ETM
 	help
 	  Turns on program counter saving on reset by default. Otherwise,
 	  PC saving is disabled by default but can be enabled via sysfs.
 
-	  For production builds, you should probably say 'N' here to avoid
-	  potential power penalty.
+	  If unsure, say 'N' here to avoid potential power penalty.
 
-config CONTROL_TRACE
-	tristate "Turn on to control tracing"
+endif
+
+config CORESIGHT_EVENT
+	tristate "CoreSight Event driver"
 	help
-	  Builds module to abort tracing on a user space data, instruction
-	  or prefetch abort.
+	  This driver provides support for registering with various events
+	  and performing CoreSight actions like aborting trace on their
+	  occurrence.
 
-	  For production builds, you should probably say 'N' here to avoid
-	  potential power, performance and memory penalty.
+endif
diff --git a/drivers/coresight/Makefile b/drivers/coresight/Makefile
index 033e5a0..0595064 100644
--- a/drivers/coresight/Makefile
+++ b/drivers/coresight/Makefile
@@ -1,3 +1,15 @@
-obj-$(CONFIG_CONTROL_TRACE) += control_trace.o
+#
+# Makefile for CoreSight drivers.
+#
+obj-$(CONFIG_CORESIGHT) += coresight.o
 obj-$(CONFIG_OF) += of_coresight.o
-obj-$(CONFIG_MSM_QDSS) += coresight.o coresight-csr.o coresight-tmc.o coresight-tpiu.o coresight-etb.o coresight-funnel.o coresight-replicator.o coresight-stm.o coresight-etm.o coresight-etm-cp14.o
+obj-$(CONFIG_CORESIGHT_CTI) += coresight-cti.o
+obj-$(CONFIG_CORESIGHT_CSR) += coresight-csr.o
+obj-$(CONFIG_CORESIGHT_TMC) += coresight-tmc.o
+obj-$(CONFIG_CORESIGHT_TPIU) += coresight-tpiu.o
+obj-$(CONFIG_CORESIGHT_ETB) += coresight-etb.o
+obj-$(CONFIG_CORESIGHT_FUNNEL) += coresight-funnel.o
+obj-$(CONFIG_CORESIGHT_REPLICATOR) += coresight-replicator.o
+obj-$(CONFIG_CORESIGHT_STM) += coresight-stm.o
+obj-$(CONFIG_CORESIGHT_ETM) += coresight-etm.o coresight-etm-cp14.o
+obj-$(CONFIG_CORESIGHT_EVENT) += coresight-event.o
diff --git a/drivers/coresight/coresight-csr.c b/drivers/coresight/coresight-csr.c
index 1f6bd1d..4774c76 100644
--- a/drivers/coresight/coresight-csr.c
+++ b/drivers/coresight/coresight-csr.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
@@ -18,6 +18,7 @@
 #include <linux/io.h>
 #include <linux/err.h>
 #include <linux/slab.h>
+#include <linux/of.h>
 #include <linux/of_coresight.h>
 #include <linux/coresight.h>
 
@@ -74,6 +75,7 @@
 	void __iomem		*base;
 	struct device		*dev;
 	struct coresight_device	*csdev;
+	uint32_t		blksize;
 };
 
 static struct csr_drvdata *csrdrvdata;
@@ -86,7 +88,7 @@
 	CSR_UNLOCK(drvdata);
 
 	usbbamctrl = csr_readl(drvdata, CSR_USBBAMCTRL);
-	usbbamctrl = (usbbamctrl & ~0x3) | BLKSIZE_2048;
+	usbbamctrl = (usbbamctrl & ~0x3) | drvdata->blksize;
 	csr_writel(drvdata, usbbamctrl, CSR_USBBAMCTRL);
 
 	usbflshctrl = csr_readl(drvdata, CSR_USBFLSHCTRL);
@@ -117,8 +119,24 @@
 }
 EXPORT_SYMBOL_GPL(msm_qdss_csr_disable_bam_to_usb);
 
+void msm_qdss_csr_disable_flush(void)
+{
+	struct csr_drvdata *drvdata = csrdrvdata;
+	uint32_t usbflshctrl;
+
+	CSR_UNLOCK(drvdata);
+
+	usbflshctrl = csr_readl(drvdata, CSR_USBFLSHCTRL);
+	usbflshctrl &= ~0x2;
+	csr_writel(drvdata, usbflshctrl, CSR_USBFLSHCTRL);
+
+	CSR_LOCK(drvdata);
+}
+EXPORT_SYMBOL_GPL(msm_qdss_csr_disable_flush);
+
 static int __devinit csr_probe(struct platform_device *pdev)
 {
+	int ret;
 	struct device *dev = &pdev->dev;
 	struct coresight_platform_data *pdata;
 	struct csr_drvdata *drvdata;
@@ -148,6 +166,13 @@
 	if (!drvdata->base)
 		return -ENOMEM;
 
+	if (pdev->dev.of_node) {
+		ret = of_property_read_u32(pdev->dev.of_node, "qcom,blk-size",
+					   &drvdata->blksize);
+		if (ret)
+			drvdata->blksize = BLKSIZE_256;
+	}
+
 	desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
 	if (!desc)
 		return -ENOMEM;
diff --git a/drivers/coresight/coresight-cti.c b/drivers/coresight/coresight-cti.c
new file mode 100644
index 0000000..e077edf
--- /dev/null
+++ b/drivers/coresight/coresight-cti.c
@@ -0,0 +1,481 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/clk.h>
+#include <linux/of_coresight.h>
+#include <linux/coresight.h>
+#include <linux/coresight-cti.h>
+
+#include "coresight-priv.h"
+
+#define cti_writel(drvdata, val, off)	__raw_writel((val), drvdata->base + off)
+#define cti_readl(drvdata, off)		__raw_readl(drvdata->base + off)
+
+#define CTI_LOCK(drvdata)						\
+do {									\
+	mb();								\
+	cti_writel(drvdata, 0x0, CORESIGHT_LAR);			\
+} while (0)
+#define CTI_UNLOCK(drvdata)						\
+do {									\
+	cti_writel(drvdata, CORESIGHT_UNLOCK, CORESIGHT_LAR);		\
+	mb();								\
+} while (0)
+
+#define CTICONTROL		(0x000)
+#define CTIINTACK		(0x010)
+#define CTIAPPSET		(0x014)
+#define CTIAPPCLEAR		(0x018)
+#define CTIAPPPULSE		(0x01C)
+#define CTIINEN(n)		(0x020 + (n * 4))
+#define CTIOUTEN(n)		(0x0A0 + (n * 4))
+#define CTITRIGINSTATUS		(0x130)
+#define CTITRIGOUTSTATUS	(0x134)
+#define CTICHINSTATUS		(0x138)
+#define CTICHOUTSTATUS		(0x13C)
+#define CTIGATE			(0x140)
+#define ASICCTL			(0x144)
+#define ITCHINACK		(0xEDC)
+#define ITTRIGINACK		(0xEE0)
+#define ITCHOUT			(0xEE4)
+#define ITTRIGOUT		(0xEE8)
+#define ITCHOUTACK		(0xEEC)
+#define ITTRIGOUTACK		(0xEF0)
+#define ITCHIN			(0xEF4)
+#define ITTRIGIN		(0xEF8)
+
+#define CTI_MAX_TRIGGERS	(8)
+#define CTI_MAX_CHANNELS	(4)
+
+#define to_cti_drvdata(c) container_of(c, struct cti_drvdata, cti)
+
+struct cti_drvdata {
+	void __iomem			*base;
+	struct device			*dev;
+	struct coresight_device		*csdev;
+	struct clk			*clk;
+	struct mutex			mutex;
+	struct coresight_cti		cti;
+	int				refcnt;
+};
+
+static LIST_HEAD(cti_list);
+static DEFINE_MUTEX(cti_lock);
+
+static int cti_verify_bounds(int trig, int ch)
+{
+	if (trig >= CTI_MAX_TRIGGERS)
+		return -EINVAL;
+
+	if (ch >= CTI_MAX_CHANNELS)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int cti_enable(struct cti_drvdata *drvdata)
+{
+	int ret;
+
+	ret = clk_prepare_enable(drvdata->clk);
+	if (ret)
+		return ret;
+
+	CTI_UNLOCK(drvdata);
+
+	cti_writel(drvdata, 0x1, CTICONTROL);
+
+	CTI_LOCK(drvdata);
+	return 0;
+}
+
+static void __cti_map_trigin(struct cti_drvdata *drvdata, int trig, int ch)
+{
+	uint32_t ctien;
+
+	CTI_UNLOCK(drvdata);
+
+	ctien = cti_readl(drvdata, CTIINEN(trig));
+	cti_writel(drvdata, (ctien | 0x1 << ch), CTIINEN(trig));
+
+	CTI_LOCK(drvdata);
+}
+
+int coresight_cti_map_trigin(struct coresight_cti *cti, int trig, int ch)
+{
+	struct cti_drvdata *drvdata;
+	int ret = 0;
+
+	if (IS_ERR_OR_NULL(cti))
+		return -EINVAL;
+
+	ret = cti_verify_bounds(trig, ch);
+	if (ret)
+		return ret;
+
+	drvdata = to_cti_drvdata(cti);
+
+	mutex_lock(&drvdata->mutex);
+	if (drvdata->refcnt == 0) {
+		ret = cti_enable(drvdata);
+		if (ret)
+			goto err;
+	}
+	drvdata->refcnt++;
+
+	__cti_map_trigin(drvdata, trig, ch);
+err:
+	mutex_unlock(&drvdata->mutex);
+	return ret;
+}
+EXPORT_SYMBOL(coresight_cti_map_trigin);
+
+static void __cti_map_trigout(struct cti_drvdata *drvdata, int trig, int ch)
+{
+	uint32_t ctien;
+
+	CTI_UNLOCK(drvdata);
+
+	ctien = cti_readl(drvdata, CTIOUTEN(trig));
+	cti_writel(drvdata, (ctien | 0x1 << ch), CTIOUTEN(trig));
+
+	CTI_LOCK(drvdata);
+}
+
+int coresight_cti_map_trigout(struct coresight_cti *cti, int trig, int ch)
+{
+	struct cti_drvdata *drvdata;
+	int ret = 0;
+
+	if (IS_ERR_OR_NULL(cti))
+		return -EINVAL;
+
+	ret = cti_verify_bounds(trig, ch);
+	if (ret)
+		return ret;
+
+	drvdata = to_cti_drvdata(cti);
+
+	mutex_lock(&drvdata->mutex);
+	if (drvdata->refcnt == 0) {
+		ret = cti_enable(drvdata);
+		if (ret)
+			goto err;
+	}
+	drvdata->refcnt++;
+
+	__cti_map_trigout(drvdata, trig, ch);
+err:
+	mutex_unlock(&drvdata->mutex);
+	return ret;
+}
+EXPORT_SYMBOL(coresight_cti_map_trigout);
+
+static void cti_disable(struct cti_drvdata *drvdata)
+{
+	CTI_UNLOCK(drvdata);
+
+	cti_writel(drvdata, 0x1, CTICONTROL);
+
+	CTI_LOCK(drvdata);
+}
+
+static void __cti_unmap_trigin(struct cti_drvdata *drvdata, int trig, int ch)
+{
+	uint32_t ctien;
+
+	CTI_UNLOCK(drvdata);
+
+	ctien = cti_readl(drvdata, CTIINEN(trig));
+	cti_writel(drvdata, (ctien & ~(0x1 << ch)), CTIINEN(trig));
+
+	CTI_LOCK(drvdata);
+}
+
+void coresight_cti_unmap_trigin(struct coresight_cti *cti, int trig, int ch)
+{
+	struct cti_drvdata *drvdata;
+
+	if (IS_ERR_OR_NULL(cti))
+		return;
+
+	if (cti_verify_bounds(trig, ch))
+		return;
+
+	drvdata = to_cti_drvdata(cti);
+
+	mutex_lock(&drvdata->mutex);
+	__cti_unmap_trigin(drvdata, trig, ch);
+
+	if (drvdata->refcnt == 1)
+		cti_disable(drvdata);
+	drvdata->refcnt--;
+	mutex_unlock(&drvdata->mutex);
+
+	clk_disable_unprepare(drvdata->clk);
+}
+EXPORT_SYMBOL(coresight_cti_unmap_trigin);
+
+static void __cti_unmap_trigout(struct cti_drvdata *drvdata, int trig, int ch)
+{
+	uint32_t ctien;
+
+	CTI_UNLOCK(drvdata);
+
+	ctien = cti_readl(drvdata, CTIOUTEN(trig));
+	cti_writel(drvdata, (ctien & ~(0x1 << ch)), CTIOUTEN(trig));
+
+	CTI_LOCK(drvdata);
+}
+
+void coresight_cti_unmap_trigout(struct coresight_cti *cti, int trig, int ch)
+{
+	struct cti_drvdata *drvdata;
+
+	if (IS_ERR_OR_NULL(cti))
+		return;
+
+	if (cti_verify_bounds(trig, ch))
+		return;
+
+	drvdata = to_cti_drvdata(cti);
+
+	mutex_lock(&drvdata->mutex);
+	__cti_unmap_trigout(drvdata, trig, ch);
+
+	if (drvdata->refcnt == 1)
+		cti_disable(drvdata);
+	drvdata->refcnt--;
+	mutex_unlock(&drvdata->mutex);
+
+	clk_disable_unprepare(drvdata->clk);
+}
+EXPORT_SYMBOL(coresight_cti_unmap_trigout);
+
+struct coresight_cti *coresight_cti_get(const char *name)
+{
+	struct coresight_cti *cti;
+
+	mutex_lock(&cti_lock);
+	list_for_each_entry(cti, &cti_list, link) {
+		if (!strncmp(cti->name, name, strlen(cti->name) + 1)) {
+			mutex_unlock(&cti_lock);
+			return cti;
+		}
+	}
+	mutex_unlock(&cti_lock);
+
+	return ERR_PTR(-EINVAL);
+}
+EXPORT_SYMBOL(coresight_cti_get);
+
+void coresight_cti_put(struct coresight_cti *cti)
+{
+}
+EXPORT_SYMBOL(coresight_cti_put);
+
+static ssize_t cti_store_map_trigin(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t size)
+{
+	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val1, val2;
+	int ret;
+
+	if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
+		return -EINVAL;
+
+	ret = coresight_cti_map_trigin(&drvdata->cti, val1, val2);
+
+	if (ret)
+		return ret;
+	return size;
+}
+static DEVICE_ATTR(map_trigin, S_IWUSR, NULL, cti_store_map_trigin);
+
+static ssize_t cti_store_map_trigout(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t size)
+{
+	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val1, val2;
+	int ret;
+
+	if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
+		return -EINVAL;
+
+	ret = coresight_cti_map_trigout(&drvdata->cti, val1, val2);
+
+	if (ret)
+		return ret;
+	return size;
+}
+static DEVICE_ATTR(map_trigout, S_IWUSR, NULL, cti_store_map_trigout);
+
+static ssize_t cti_store_unmap_trigin(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf, size_t size)
+{
+	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val1, val2;
+
+	if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
+		return -EINVAL;
+
+	coresight_cti_unmap_trigin(&drvdata->cti, val1, val2);
+
+	return size;
+}
+static DEVICE_ATTR(unmap_trigin, S_IWUSR, NULL, cti_store_unmap_trigin);
+
+static ssize_t cti_store_unmap_trigout(struct device *dev,
+				       struct device_attribute *attr,
+				       const char *buf, size_t size)
+{
+	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val1, val2;
+
+	if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
+		return -EINVAL;
+
+	coresight_cti_unmap_trigout(&drvdata->cti, val1, val2);
+
+	return size;
+}
+static DEVICE_ATTR(unmap_trigout, S_IWUSR, NULL, cti_store_unmap_trigout);
+
+static struct attribute *cti_attrs[] = {
+	&dev_attr_map_trigin.attr,
+	&dev_attr_map_trigout.attr,
+	&dev_attr_unmap_trigin.attr,
+	&dev_attr_unmap_trigout.attr,
+	NULL,
+};
+
+static struct attribute_group cti_attr_grp = {
+	.attrs = cti_attrs,
+};
+
+static const struct attribute_group *cti_attr_grps[] = {
+	&cti_attr_grp,
+	NULL,
+};
+
+static int __devinit cti_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct device *dev = &pdev->dev;
+	struct coresight_platform_data *pdata;
+	struct cti_drvdata *drvdata;
+	struct resource *res;
+	struct coresight_desc *desc;
+
+	if (pdev->dev.of_node) {
+		pdata = of_get_coresight_platform_data(dev, pdev->dev.of_node);
+		if (IS_ERR(pdata))
+			return PTR_ERR(pdata);
+		pdev->dev.platform_data = pdata;
+	}
+
+	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata)
+		return -ENOMEM;
+	/* Store the driver data pointer for use in exported functions */
+	drvdata->dev = &pdev->dev;
+	platform_set_drvdata(pdev, drvdata);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	drvdata->base = devm_ioremap(dev, res->start, resource_size(res));
+	if (!drvdata->base)
+		return -ENOMEM;
+
+	mutex_init(&drvdata->mutex);
+
+	drvdata->clk = devm_clk_get(dev, "core_clk");
+	if (IS_ERR(drvdata->clk))
+		return PTR_ERR(drvdata->clk);
+
+	ret = clk_set_rate(drvdata->clk, CORESIGHT_CLK_RATE_TRACE);
+	if (ret)
+		return ret;
+
+	mutex_lock(&cti_lock);
+	drvdata->cti.name = ((struct coresight_platform_data *)
+			     (pdev->dev.platform_data))->name;
+	list_add_tail(&drvdata->cti.link, &cti_list);
+	mutex_unlock(&cti_lock);
+
+	desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
+	if (!desc)
+		return -ENOMEM;
+	desc->type = CORESIGHT_DEV_TYPE_NONE;
+	desc->pdata = pdev->dev.platform_data;
+	desc->dev = &pdev->dev;
+	desc->groups = cti_attr_grps;
+	desc->owner = THIS_MODULE;
+	drvdata->csdev = coresight_register(desc);
+	if (IS_ERR(drvdata->csdev))
+		return PTR_ERR(drvdata->csdev);
+
+	dev_info(dev, "CTI initialized\n");
+	return 0;
+}
+
+static int __devexit cti_remove(struct platform_device *pdev)
+{
+	struct cti_drvdata *drvdata = platform_get_drvdata(pdev);
+
+	coresight_unregister(drvdata->csdev);
+	return 0;
+}
+
+static struct of_device_id cti_match[] = {
+	{.compatible = "arm,coresight-cti"},
+	{}
+};
+
+static struct platform_driver cti_driver = {
+	.probe          = cti_probe,
+	.remove         = __devexit_p(cti_remove),
+	.driver         = {
+		.name   = "coresight-cti",
+		.owner	= THIS_MODULE,
+		.of_match_table = cti_match,
+	},
+};
+
+static int __init cti_init(void)
+{
+	return platform_driver_register(&cti_driver);
+}
+module_init(cti_init);
+
+static void __exit cti_exit(void)
+{
+	platform_driver_unregister(&cti_driver);
+}
+module_exit(cti_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("CoreSight CTI driver");
diff --git a/drivers/coresight/coresight-etb.c b/drivers/coresight/coresight-etb.c
index bd5bf8e..d52ab28 100644
--- a/drivers/coresight/coresight-etb.c
+++ b/drivers/coresight/coresight-etb.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/drivers/coresight/coresight-etm.c b/drivers/coresight/coresight-etm.c
index 9f96b19..2ae54ea 100644
--- a/drivers/coresight/coresight-etm.c
+++ b/drivers/coresight/coresight-etm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -91,75 +91,89 @@
  */
 
 /* Trace registers (0x000-0x2FC) */
-#define ETMCR			(0x000)
-#define ETMCCR			(0x004)
-#define ETMTRIGGER		(0x008)
-#define ETMSR			(0x010)
-#define ETMSCR			(0x014)
-#define ETMTSSCR		(0x018)
-#define ETMTEEVR		(0x020)
-#define ETMTECR1		(0x024)
-#define ETMFFLR			(0x02C)
-#define ETMACVRn(n)		(0x040 + (n * 4))
-#define ETMACTRn(n)		(0x080 + (n * 4))
-#define ETMCNTRLDVRn(n)		(0x140 + (n * 4))
-#define ETMCNTENRn(n)		(0x150 + (n * 4))
-#define ETMCNTRLDEVRn(n)	(0x160 + (n * 4))
-#define ETMCNTVRn(n)		(0x170 + (n * 4))
-#define ETMSQ12EVR		(0x180)
-#define ETMSQ21EVR		(0x184)
-#define ETMSQ23EVR		(0x188)
-#define ETMSQ31EVR		(0x18C)
-#define ETMSQ32EVR		(0x190)
-#define ETMSQ13EVR		(0x194)
-#define ETMSQR			(0x19C)
-#define ETMEXTOUTEVRn(n)	(0x1A0 + (n * 4))
-#define ETMCIDCVRn(n)		(0x1B0 + (n * 4))
-#define ETMCIDCMR		(0x1BC)
-#define ETMIMPSPEC0		(0x1C0)
-#define ETMIMPSPEC1		(0x1C4)
-#define ETMIMPSPEC2		(0x1C8)
-#define ETMIMPSPEC3		(0x1CC)
-#define ETMIMPSPEC4		(0x1D0)
-#define ETMIMPSPEC5		(0x1D4)
-#define ETMIMPSPEC6		(0x1D8)
-#define ETMIMPSPEC7		(0x1DC)
-#define ETMSYNCFR		(0x1E0)
-#define ETMIDR			(0x1E4)
-#define ETMCCER			(0x1E8)
-#define ETMEXTINSELR		(0x1EC)
-#define ETMTESSEICR		(0x1F0)
-#define ETMEIBCR		(0x1F4)
-#define ETMTSEVR		(0x1F8)
-#define ETMAUXCR		(0x1FC)
-#define ETMTRACEIDR		(0x200)
-#define ETMVMIDCVR		(0x240)
+#define ETMCR				(0x000)
+#define ETMCCR				(0x004)
+#define ETMTRIGGER			(0x008)
+#define ETMASSICCTLR			(0x00C)
+#define ETMSR				(0x010)
+#define ETMSCR				(0x014)
+#define ETMTSSCR			(0x018)
+#define ETMTECR2			(0x01C)
+#define ETMTEEVR			(0x020)
+#define ETMTECR1			(0x024)
+#define ETMFFLR				(0x02C)
+#define ETMVDEVR			(0x030)
+#define ETMVDCR1			(0x034)
+#define ETMVDCR3			(0x03C)
+#define ETMACVRn(n)			(0x040 + (n * 4))
+#define ETMACTRn(n)			(0x080 + (n * 4))
+#define ETMDCVRn(n)			(0x0C0 + (n * 8))
+#define ETMDCMRn(n)			(0x100 + (n * 8))
+#define ETMCNTRLDVRn(n)			(0x140 + (n * 4))
+#define ETMCNTENRn(n)			(0x150 + (n * 4))
+#define ETMCNTRLDEVRn(n)		(0x160 + (n * 4))
+#define ETMCNTVRn(n)			(0x170 + (n * 4))
+#define ETMSQ12EVR			(0x180)
+#define ETMSQ21EVR			(0x184)
+#define ETMSQ23EVR			(0x188)
+#define ETMSQ31EVR			(0x18C)
+#define ETMSQ32EVR			(0x190)
+#define ETMSQ13EVR			(0x194)
+#define ETMSQR				(0x19C)
+#define ETMEXTOUTEVRn(n)		(0x1A0 + (n * 4))
+#define ETMCIDCVRn(n)			(0x1B0 + (n * 4))
+#define ETMCIDCMR			(0x1BC)
+#define ETMIMPSPEC0			(0x1C0)
+#define ETMIMPSPEC1			(0x1C4)
+#define ETMIMPSPEC2			(0x1C8)
+#define ETMIMPSPEC3			(0x1CC)
+#define ETMIMPSPEC4			(0x1D0)
+#define ETMIMPSPEC5			(0x1D4)
+#define ETMIMPSPEC6			(0x1D8)
+#define ETMIMPSPEC7			(0x1DC)
+#define ETMSYNCFR			(0x1E0)
+#define ETMIDR				(0x1E4)
+#define ETMCCER				(0x1E8)
+#define ETMEXTINSELR			(0x1EC)
+#define ETMTESSEICR			(0x1F0)
+#define ETMEIBCR			(0x1F4)
+#define ETMTSEVR			(0x1F8)
+#define ETMAUXCR			(0x1FC)
+#define ETMTRACEIDR			(0x200)
+#define ETMIDR2				(0x208)
+#define ETMVMIDCVR			(0x240)
 /* Management registers (0x300-0x314) */
-#define ETMOSLAR		(0x300)
-#define ETMOSLSR		(0x304)
-#define ETMOSSRR		(0x308)
-#define ETMPDCR			(0x310)
-#define ETMPDSR			(0x314)
+#define ETMOSLAR			(0x300)
+#define ETMOSLSR			(0x304)
+#define ETMOSSRR			(0x308)
+#define ETMPDCR				(0x310)
+#define ETMPDSR				(0x314)
 
-#define ETM_MAX_ADDR_CMP	(16)
-#define ETM_MAX_CNTR		(4)
-#define ETM_MAX_CTXID_CMP	(3)
+#define ETM_MAX_ADDR_CMP		(16)
+#define ETM_MAX_CNTR			(4)
+#define ETM_MAX_CTXID_CMP		(3)
 
-#define ETM_MODE_EXCLUDE	BIT(0)
-#define ETM_MODE_CYCACC		BIT(1)
-#define ETM_MODE_STALL		BIT(2)
-#define ETM_MODE_TIMESTAMP	BIT(3)
-#define ETM_MODE_CTXID		BIT(4)
-#define ETM_MODE_ALL		(0x1F)
+#define ETM_MODE_EXCLUDE		BIT(0)
+#define ETM_MODE_CYCACC			BIT(1)
+#define ETM_MODE_STALL			BIT(2)
+#define ETM_MODE_TIMESTAMP		BIT(3)
+#define ETM_MODE_CTXID			BIT(4)
+#define ETM_MODE_DATA_TRACE_VAL		BIT(5)
+#define ETM_MODE_DATA_TRACE_ADDR	BIT(6)
+#define ETM_MODE_ALL			(0x7F)
 
-#define ETM_EVENT_MASK		(0x1FFFF)
-#define ETM_SYNC_MASK		(0xFFF)
-#define ETM_ALL_MASK		(0xFFFFFFFF)
+#define ETM_DATACMP_ENABLE		(0x2)
 
-#define ETM_SEQ_STATE_MAX_VAL	(0x2)
+#define ETM_EVENT_MASK			(0x1FFFF)
+#define ETM_SYNC_MASK			(0xFFF)
+#define ETM_ALL_MASK			(0xFFFFFFFF)
 
-#define ETM_REG_DUMP_VER_OFF	(4)
-#define ETM_REG_DUMP_VER	(1)
+#define ETM_SEQ_STATE_MAX_VAL		(0x2)
+
+#define ETM_REG_DUMP_VER_OFF		(4)
+#define ETM_REG_DUMP_VER		(1)
+
+#define CPMR_ETMCLKEN			(8)
 
 enum etm_addr_type {
 	ETM_ADDR_TYPE_NONE,
@@ -169,7 +183,7 @@
 	ETM_ADDR_TYPE_STOP,
 };
 
-#ifdef CONFIG_MSM_QDSS_ETM_DEFAULT_ENABLE
+#ifdef CONFIG_CORESIGHT_ETM_DEFAULT_ENABLE
 static int boot_enable = 1;
 #else
 static int boot_enable;
@@ -178,7 +192,7 @@
 	boot_enable, boot_enable, int, S_IRUGO
 );
 
-#ifdef CONFIG_MSM_QDSS_ETM_PCSAVE_DEFAULT_ENABLE
+#ifdef CONFIG_CORESIGHT_ETM_PCSAVE_DEFAULT_ENABLE
 static int boot_pcsave_enable = 1;
 #else
 static int boot_pcsave_enable;
@@ -197,12 +211,15 @@
 	int				cpu;
 	uint8_t				arch;
 	bool				enable;
+	bool				sticky_enable;
+	bool				boot_enable;
 	bool				os_unlock;
 	uint8_t				nr_addr_cmp;
 	uint8_t				nr_cntr;
 	uint8_t				nr_ext_inp;
 	uint8_t				nr_ext_out;
 	uint8_t				nr_ctxid_cmp;
+	uint8_t				nr_data_cmp;
 	uint8_t				reset;
 	uint32_t			mode;
 	uint32_t			ctrl;
@@ -210,11 +227,18 @@
 	uint32_t			startstop_ctrl;
 	uint32_t			enable_event;
 	uint32_t			enable_ctrl1;
+	uint32_t			enable_ctrl2;
 	uint32_t			fifofull_level;
 	uint8_t				addr_idx;
 	uint32_t			addr_val[ETM_MAX_ADDR_CMP];
 	uint32_t			addr_acctype[ETM_MAX_ADDR_CMP];
 	uint32_t			addr_type[ETM_MAX_ADDR_CMP];
+	bool				data_trace_support;
+	uint32_t			data_val[ETM_MAX_ADDR_CMP];
+	uint32_t			data_mask[ETM_MAX_ADDR_CMP];
+	uint32_t			viewdata_event;
+	uint32_t			viewdata_ctrl1;
+	uint32_t			viewdata_ctrl3;
 	uint8_t				cntr_idx;
 	uint32_t			cntr_rld_val[ETM_MAX_CNTR];
 	uint32_t			cntr_event[ETM_MAX_CNTR];
@@ -236,6 +260,7 @@
 	bool				pcsave_enable;
 	bool				pcsave_sticky_enable;
 	bool				pcsave_boot_enable;
+	bool				round_robin;
 };
 
 static struct etm_drvdata *etmdrvdata[NR_CPUS];
@@ -247,8 +272,10 @@
  */
 static void etm_os_unlock(void *info)
 {
-	etm_writel_cp14(0x0, ETMOSLAR);
-	isb();
+	if (cpu_is_krait()) {
+		etm_writel_cp14(0x0, ETMOSLAR);
+		isb();
+	}
 }
 
 /*
@@ -293,11 +320,21 @@
 
 static void etm_set_pwrup(struct etm_drvdata *drvdata)
 {
+	uint32_t cpmr;
 	uint32_t etmpdcr;
 
-	etmpdcr = etm_readl_mm(drvdata, ETMPDCR);
-	etmpdcr |= BIT(3);
-	etm_writel_mm(drvdata, etmpdcr, ETMPDCR);
+	 /* For Krait, use cp15 CPMR_ETMCLKEN instead of ETMPDCR since ETMPDCR
+	  * is not supported for this purpose on Krait v4.
+	  */
+	if (cpu_is_krait()) {
+		asm volatile("mrc p15, 7, %0, c15, c0, 5" : "=r" (cpmr));
+		cpmr  |= CPMR_ETMCLKEN;
+		asm volatile("mcr p15, 7, %0, c15, c0, 5" : : "r" (cpmr));
+	} else {
+		etmpdcr = etm_readl_mm(drvdata, ETMPDCR);
+		etmpdcr |= BIT(3);
+		etm_writel_mm(drvdata, etmpdcr, ETMPDCR);
+	}
 	/* ensure pwrup completes before subsequent cp14 accesses */
 	mb();
 	isb();
@@ -305,14 +342,24 @@
 
 static void etm_clr_pwrup(struct etm_drvdata *drvdata)
 {
+	uint32_t cpmr;
 	uint32_t etmpdcr;
 
 	/* ensure pending cp14 accesses complete before clearing pwrup */
 	mb();
 	isb();
-	etmpdcr = etm_readl_mm(drvdata, ETMPDCR);
-	etmpdcr &= ~BIT(3);
-	etm_writel_mm(drvdata, etmpdcr, ETMPDCR);
+	 /* For Krait, use cp15 CPMR_ETMCLKEN instead of ETMPDCR since ETMPDCR
+	  * is not supported for this purpose on Krait v4.
+	  */
+	if (cpu_is_krait()) {
+		asm volatile("mrc p15, 7, %0, c15, c0, 5" : "=r" (cpmr));
+		cpmr  &= ~CPMR_ETMCLKEN;
+		asm volatile("mcr p15, 7, %0, c15, c0, 5" : : "r" (cpmr));
+	} else {
+		etmpdcr = etm_readl_mm(drvdata, ETMPDCR);
+		etmpdcr &= ~BIT(3);
+		etm_writel_mm(drvdata, etmpdcr, ETMPDCR);
+	}
 }
 
 static void etm_set_prog(struct etm_drvdata *drvdata)
@@ -382,6 +429,14 @@
 	ETM_LOCK(drvdata);
 }
 
+static bool etm_version_gte(uint8_t arch, uint8_t base_arch)
+{
+	if (arch >= base_arch && ((arch & PFT_ARCH_MAJOR) != PFT_ARCH_MAJOR))
+		return true;
+	else
+		return false;
+}
+
 static void __etm_enable(void *info)
 {
 	int i;
@@ -409,13 +464,24 @@
 	etm_writel(drvdata, drvdata->ctrl | etmcr, ETMCR);
 	etm_writel(drvdata, drvdata->trigger_event, ETMTRIGGER);
 	etm_writel(drvdata, drvdata->startstop_ctrl, ETMTSSCR);
+	if (etm_version_gte(drvdata->arch, ETM_ARCH_V1_2))
+		etm_writel(drvdata, drvdata->enable_ctrl2, ETMTECR2);
 	etm_writel(drvdata, drvdata->enable_event, ETMTEEVR);
 	etm_writel(drvdata, drvdata->enable_ctrl1, ETMTECR1);
 	etm_writel(drvdata, drvdata->fifofull_level, ETMFFLR);
+	if (drvdata->data_trace_support == true) {
+		etm_writel(drvdata, drvdata->viewdata_event, ETMVDEVR);
+		etm_writel(drvdata, drvdata->viewdata_ctrl1, ETMVDCR1);
+		etm_writel(drvdata, drvdata->viewdata_ctrl3, ETMVDCR3);
+	}
 	for (i = 0; i < drvdata->nr_addr_cmp; i++) {
 		etm_writel(drvdata, drvdata->addr_val[i], ETMACVRn(i));
 		etm_writel(drvdata, drvdata->addr_acctype[i], ETMACTRn(i));
 	}
+	for (i = 0; i < drvdata->nr_data_cmp; i++) {
+		etm_writel(drvdata, drvdata->data_val[i], ETMDCVRn(i));
+		etm_writel(drvdata, drvdata->data_mask[i], ETMDCMRn(i));
+	}
 	for (i = 0; i < drvdata->nr_cntr; i++) {
 		etm_writel(drvdata, drvdata->cntr_rld_val[i], ETMCNTRLDVRn(i));
 		etm_writel(drvdata, drvdata->cntr_event[i], ETMCNTENRn(i));
@@ -459,7 +525,6 @@
 	if (ret)
 		goto err_clk;
 
-	get_online_cpus();
 	spin_lock(&drvdata->spinlock);
 
 	/*
@@ -470,9 +535,9 @@
 	if (ret)
 		goto err;
 	drvdata->enable = true;
+	drvdata->sticky_enable = true;
 
 	spin_unlock(&drvdata->spinlock);
-	put_online_cpus();
 
 	wake_unlock(&drvdata->wake_lock);
 
@@ -480,7 +545,6 @@
 	return 0;
 err:
 	spin_unlock(&drvdata->spinlock);
-	put_online_cpus();
 	clk_disable_unprepare(drvdata->clk);
 err_clk:
 	wake_unlock(&drvdata->wake_lock);
@@ -510,6 +574,12 @@
 
 	wake_lock(&drvdata->wake_lock);
 
+	/*
+	 * Taking hotplug lock here protects from clocks getting disabled
+	 * with tracing being left on (crash scenario) if user disable occurs
+	 * after cpu online mask indicates the cpu is offline but before the
+	 * DYING hotplug callback is serviced by the ETM driver.
+	 */
 	get_online_cpus();
 	spin_lock(&drvdata->spinlock);
 
@@ -594,21 +664,37 @@
 	if (val) {
 		drvdata->mode = ETM_MODE_EXCLUDE;
 		drvdata->ctrl = 0x0;
+		if (etm_version_gte(drvdata->arch, ETM_ARCH_V1_0))
+			drvdata->ctrl |= BIT(11);
 		if (cpu_is_krait_v1()) {
 			drvdata->mode |= ETM_MODE_CYCACC;
 			drvdata->ctrl |= BIT(12);
 		}
 		drvdata->trigger_event = 0x406F;
 		drvdata->startstop_ctrl = 0x0;
+		if (etm_version_gte(drvdata->arch, ETM_ARCH_V1_2))
+			drvdata->enable_ctrl2 = 0x0;
 		drvdata->enable_event = 0x6F;
 		drvdata->enable_ctrl1 = 0x1000000;
 		drvdata->fifofull_level = 0x28;
+		if (drvdata->data_trace_support == true) {
+			drvdata->mode |= (ETM_MODE_DATA_TRACE_VAL |
+						ETM_MODE_DATA_TRACE_ADDR);
+			drvdata->ctrl |= BIT(2) | BIT(3);
+			drvdata->viewdata_event = 0x6F;
+			drvdata->viewdata_ctrl1 = 0x0;
+			drvdata->viewdata_ctrl3 = 0x10000;
+		}
 		drvdata->addr_idx = 0x0;
 		for (i = 0; i < drvdata->nr_addr_cmp; i++) {
 			drvdata->addr_val[i] = 0x0;
 			drvdata->addr_acctype[i] = 0x0;
 			drvdata->addr_type[i] = ETM_ADDR_TYPE_NONE;
 		}
+		for (i = 0; i < drvdata->nr_data_cmp; i++) {
+			drvdata->data_val[i] = 0;
+			drvdata->data_mask[i] = ~(0);
+		}
 		drvdata->cntr_idx = 0x0;
 		for (i = 0; i < drvdata->nr_cntr; i++) {
 			drvdata->cntr_rld_val[i] = 0x0;
@@ -684,6 +770,17 @@
 		drvdata->ctrl |= (BIT(14) | BIT(15));
 	else
 		drvdata->ctrl &= ~(BIT(14) | BIT(15));
+	if (etm_version_gte(drvdata->arch, ETM_ARCH_V1_0)) {
+		if (drvdata->mode & ETM_MODE_DATA_TRACE_VAL)
+			drvdata->ctrl |= BIT(2);
+		else
+			drvdata->ctrl &= ~(BIT(2));
+
+		if (drvdata->mode & ETM_MODE_DATA_TRACE_ADDR)
+			drvdata->ctrl |= (BIT(3));
+		else
+			drvdata->ctrl &= ~(BIT(3));
+	}
 	spin_unlock(&drvdata->spinlock);
 
 	return size;
@@ -839,6 +936,8 @@
 
 	drvdata->addr_val[idx] = val;
 	drvdata->addr_type[idx] = ETM_ADDR_TYPE_SINGLE;
+	if (etm_version_gte(drvdata->arch, ETM_ARCH_V1_2))
+		drvdata->enable_ctrl2 |= (1 << idx);
 	spin_unlock(&drvdata->spinlock);
 	return size;
 }
@@ -1039,6 +1138,138 @@
 static DEVICE_ATTR(addr_acctype, S_IRUGO | S_IWUSR, etm_show_addr_acctype,
 		   etm_store_addr_acctype);
 
+static ssize_t etm_show_data_val(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val;
+	uint8_t idx;
+
+	spin_lock(&drvdata->spinlock);
+	idx = drvdata->addr_idx;
+	if (idx % 2 != 0) {
+		spin_unlock(&drvdata->spinlock);
+		return -EPERM;
+	}
+	idx = idx >> 1;
+	if (idx >= drvdata->nr_data_cmp) {
+		spin_unlock(&drvdata->spinlock);
+		return -EPERM;
+	}
+
+	val = drvdata->data_val[idx];
+	spin_unlock(&drvdata->spinlock);
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_data_val(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t size)
+{
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val;
+	uint8_t idx, data_idx;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	spin_lock(&drvdata->spinlock);
+	idx = drvdata->addr_idx;
+	/* Adjust index to use the correct data comparator */
+	data_idx = idx >> 1;
+	/* Only idx = 0, 2, 4, 6... are valid */
+	if (idx % 2 != 0) {
+		spin_unlock(&drvdata->spinlock);
+		return -EPERM;
+	}
+	if (data_idx >= drvdata->nr_data_cmp) {
+		spin_unlock(&drvdata->spinlock);
+		return -EPERM;
+	}
+	if (!BVAL(drvdata->addr_acctype[idx], ETM_DATACMP_ENABLE)) {
+		spin_unlock(&drvdata->spinlock);
+		return -EPERM;
+	}
+	if (drvdata->addr_type[idx] == ETM_ADDR_TYPE_RANGE) {
+		if (!BVAL(drvdata->addr_acctype[idx + 1], ETM_DATACMP_ENABLE)) {
+			spin_unlock(&drvdata->spinlock);
+			return -EPERM;
+		}
+	}
+
+	drvdata->data_val[data_idx] = val;
+	spin_unlock(&drvdata->spinlock);
+	return size;
+}
+static DEVICE_ATTR(data_val, S_IRUGO | S_IWUSR, etm_show_data_val,
+			etm_store_data_val);
+
+static ssize_t etm_show_data_mask(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long mask;
+	uint8_t idx;
+
+	spin_lock(&drvdata->spinlock);
+	idx = drvdata->addr_idx;
+	if (idx % 2 != 0) {
+		spin_unlock(&drvdata->spinlock);
+		return -EPERM;
+	}
+	idx = idx >> 1;
+	if (idx >= drvdata->nr_data_cmp) {
+		spin_unlock(&drvdata->spinlock);
+		return -EPERM;
+	}
+
+	mask = drvdata->data_mask[idx];
+	spin_unlock(&drvdata->spinlock);
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", mask);
+}
+
+static ssize_t etm_store_data_mask(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t size)
+{
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long mask;
+	uint8_t idx, data_idx;
+
+	if (sscanf(buf, "%lx", &mask) != 1)
+		return -EINVAL;
+
+	spin_lock(&drvdata->spinlock);
+	idx = drvdata->addr_idx;
+	/* Adjust index to use the correct data comparator */
+	data_idx = idx >> 1;
+	/* Only idx = 0, 2, 4, 6... are valid */
+	if (idx % 2 != 0) {
+		spin_unlock(&drvdata->spinlock);
+		return -EPERM;
+	}
+	if (data_idx >= drvdata->nr_data_cmp) {
+		spin_unlock(&drvdata->spinlock);
+		return -EPERM;
+	}
+	if (!BVAL(drvdata->addr_acctype[idx], ETM_DATACMP_ENABLE)) {
+		spin_unlock(&drvdata->spinlock);
+		return -EPERM;
+	}
+	if (drvdata->addr_type[idx] == ETM_ADDR_TYPE_RANGE) {
+		if (!BVAL(drvdata->addr_acctype[idx + 1], ETM_DATACMP_ENABLE)) {
+			spin_unlock(&drvdata->spinlock);
+			return -EPERM;
+		}
+	}
+
+	drvdata->data_mask[data_idx] = mask;
+	spin_unlock(&drvdata->spinlock);
+	return size;
+}
+static DEVICE_ATTR(data_mask, S_IRUGO | S_IWUSR, etm_show_data_mask,
+			etm_store_data_mask);
+
 static ssize_t etm_show_cntr_idx(struct device *dev,
 				 struct device_attribute *attr, char *buf)
 {
@@ -1518,7 +1749,7 @@
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
-static int ____etm_store_pcsave(struct etm_drvdata *drvdata, unsigned long val)
+static int __etm_store_pcsave(struct etm_drvdata *drvdata, unsigned long val)
 {
 	int ret = 0;
 
@@ -1558,17 +1789,6 @@
 	return ret;
 }
 
-static int __etm_store_pcsave(struct etm_drvdata *drvdata, unsigned long val)
-{
-	int ret;
-
-	get_online_cpus();
-	ret = ____etm_store_pcsave(drvdata, val);
-	put_online_cpus();
-
-	return ret;
-}
-
 static ssize_t etm_store_pcsave(struct device *dev,
 				struct device_attribute *attr,
 				const char *buf, size_t size)
@@ -1604,6 +1824,8 @@
 	&dev_attr_addr_start.attr,
 	&dev_attr_addr_stop.attr,
 	&dev_attr_addr_acctype.attr,
+	&dev_attr_data_val.attr,
+	&dev_attr_data_mask.attr,
 	&dev_attr_cntr_idx.attr,
 	&dev_attr_cntr_rld_val.attr,
 	&dev_attr_cntr_event.attr,
@@ -1638,37 +1860,40 @@
 {
 	unsigned int cpu = (unsigned long)hcpu;
 
+	if (!etmdrvdata[cpu])
+		goto out;
+
 	switch (action & (~CPU_TASKS_FROZEN)) {
 	case CPU_STARTING:
-		if (etmdrvdata[cpu] && !etmdrvdata[cpu]->os_unlock) {
-			spin_lock(&etmdrvdata[cpu]->spinlock);
+		spin_lock(&etmdrvdata[cpu]->spinlock);
+		if (!etmdrvdata[cpu]->os_unlock) {
 			etm_os_unlock(etmdrvdata[cpu]);
 			etmdrvdata[cpu]->os_unlock = true;
-			spin_unlock(&etmdrvdata[cpu]->spinlock);
 		}
 
-		if (etmdrvdata[cpu] && etmdrvdata[cpu]->enable) {
-			spin_lock(&etmdrvdata[cpu]->spinlock);
+		if (etmdrvdata[cpu]->enable && etmdrvdata[cpu]->round_robin)
 			__etm_enable(etmdrvdata[cpu]);
-			spin_unlock(&etmdrvdata[cpu]->spinlock);
-		}
+		spin_unlock(&etmdrvdata[cpu]->spinlock);
 		break;
 
 	case CPU_ONLINE:
-		if (etmdrvdata[cpu] && etmdrvdata[cpu]->pcsave_boot_enable &&
-		    !etmdrvdata[cpu]->pcsave_sticky_enable) {
-			____etm_store_pcsave(etmdrvdata[cpu], 1);
-		}
+		if (etmdrvdata[cpu]->boot_enable &&
+		    !etmdrvdata[cpu]->sticky_enable)
+			coresight_enable(etmdrvdata[cpu]->csdev);
+
+		if (etmdrvdata[cpu]->pcsave_boot_enable &&
+		    !etmdrvdata[cpu]->pcsave_sticky_enable)
+			__etm_store_pcsave(etmdrvdata[cpu], 1);
 		break;
 
 	case CPU_DYING:
-		if (etmdrvdata[cpu] && etmdrvdata[cpu]->enable) {
-			spin_lock(&etmdrvdata[cpu]->spinlock);
+		spin_lock(&etmdrvdata[cpu]->spinlock);
+		if (etmdrvdata[cpu]->enable && etmdrvdata[cpu]->round_robin)
 			__etm_disable(etmdrvdata[cpu]);
-			spin_unlock(&etmdrvdata[cpu]->spinlock);
-		}
+		spin_unlock(&etmdrvdata[cpu]->spinlock);
 		break;
 	}
+out:
 	return NOTIFY_OK;
 }
 
@@ -1681,6 +1906,8 @@
 	switch (arch) {
 	case PFT_ARCH_V1_1:
 		break;
+	case ETM_ARCH_V3_5:
+		break;
 	default:
 		return false;
 	}
@@ -1691,6 +1918,7 @@
 {
 	uint32_t etmidr;
 	uint32_t etmccr;
+	uint32_t etmcr;
 	struct etm_drvdata *drvdata = info;
 
 	ETM_UNLOCK(drvdata);
@@ -1721,6 +1949,19 @@
 	drvdata->nr_ext_inp = BMVAL(etmccr, 17, 19);
 	drvdata->nr_ext_out = BMVAL(etmccr, 20, 22);
 	drvdata->nr_ctxid_cmp = BMVAL(etmccr, 24, 25);
+	drvdata->nr_data_cmp = BMVAL(etmccr, 4, 7);
+
+	if (etm_version_gte(drvdata->arch, ETM_ARCH_V1_0)) {
+		etmcr = etm_readl(drvdata, ETMCR);
+		etmcr |= (BIT(2) | BIT(3));
+		etm_writel(drvdata, etmcr, ETMCR);
+		etmcr = etm_readl(drvdata, ETMCR);
+		if (BVAL(etmcr, 2) || BVAL(etmcr, 3))
+			drvdata->data_trace_support = true;
+		else
+			drvdata->data_trace_support = false;
+	} else
+		drvdata->data_trace_support = false;
 
 	etm_set_pwrdwn(drvdata);
 	ETM_LOCK(drvdata);
@@ -1734,6 +1975,8 @@
 	drvdata->nr_ext_inp = etmdrvdata[0]->nr_ext_inp;
 	drvdata->nr_ext_out = etmdrvdata[0]->nr_ext_out;
 	drvdata->nr_ctxid_cmp = etmdrvdata[0]->nr_ctxid_cmp;
+	drvdata->nr_data_cmp = etmdrvdata[0]->nr_data_cmp;
+	drvdata->data_trace_support = etmdrvdata[0]->data_trace_support;
 }
 
 static void __devinit etm_init_default_data(struct etm_drvdata *drvdata)
@@ -1749,6 +1992,10 @@
 		drvdata->addr_val[1] = (uint32_t) _etext;
 		drvdata->addr_type[0] = ETM_ADDR_TYPE_RANGE;
 		drvdata->addr_type[1] = ETM_ADDR_TYPE_RANGE;
+		if (etm_version_gte(drvdata->arch, ETM_ARCH_V1_0)) {
+			drvdata->addr_acctype[0] = 0x19;
+			drvdata->addr_acctype[1] = 0x19;
+		}
 	}
 	for (i = 0; i < drvdata->nr_cntr; i++) {
 		drvdata->cntr_event[i] = 0x406F;
@@ -1781,6 +2028,23 @@
 			drvdata->addr_type[i] = ETM_ADDR_TYPE_NONE;
 		}
 	}
+
+	if (etm_version_gte(drvdata->arch, ETM_ARCH_V1_0))
+		drvdata->ctrl |= BIT(11);
+	if (etm_version_gte(drvdata->arch, ETM_ARCH_V1_2))
+		drvdata->enable_ctrl2 = 0x0;
+	if (drvdata->data_trace_support == true) {
+		drvdata->mode |= (ETM_MODE_DATA_TRACE_VAL |
+						ETM_MODE_DATA_TRACE_ADDR);
+		drvdata->ctrl |= BIT(2) | BIT(3);
+		drvdata->viewdata_ctrl1 = 0x0;
+		drvdata->viewdata_ctrl3 = 0x10000;
+		drvdata->viewdata_event = 0x6F;
+	}
+	for (i = 0; i < drvdata->nr_data_cmp; i++) {
+		drvdata->data_val[i] = 0;
+		drvdata->data_mask[i] = ~(0);
+	}
 }
 
 static int __devinit etm_probe(struct platform_device *pdev)
@@ -1865,6 +2129,10 @@
 
 	clk_disable_unprepare(drvdata->clk);
 
+	if (pdev->dev.of_node)
+		drvdata->round_robin = of_property_read_bool(pdev->dev.of_node,
+							"qcom,round-robin");
+
 	baddr = devm_kzalloc(dev, PAGE_SIZE + reg_size, GFP_KERNEL);
 	if (baddr) {
 		*(uint32_t *)(baddr + ETM_REG_DUMP_VER_OFF) = ETM_REG_DUMP_VER;
@@ -1910,8 +2178,10 @@
 
 	dev_info(dev, "ETM initialized\n");
 
-	if (boot_enable)
+	if (boot_enable) {
 		coresight_enable(drvdata->csdev);
+		drvdata->boot_enable = true;
+	}
 
 	if (drvdata->pcsave_impl && boot_pcsave_enable) {
 		__etm_store_pcsave(drvdata, 1);
diff --git a/drivers/coresight/control_trace.c b/drivers/coresight/coresight-event.c
similarity index 100%
rename from drivers/coresight/control_trace.c
rename to drivers/coresight/coresight-event.c
diff --git a/drivers/coresight/coresight-funnel.c b/drivers/coresight/coresight-funnel.c
index 3d5c0c2..7f39a3e 100644
--- a/drivers/coresight/coresight-funnel.c
+++ b/drivers/coresight/coresight-funnel.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/drivers/coresight/coresight-priv.h b/drivers/coresight/coresight-priv.h
index 0cf2b3d..258ff09 100644
--- a/drivers/coresight/coresight-priv.h
+++ b/drivers/coresight/coresight-priv.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -36,14 +36,19 @@
 #define BMVAL(val, lsb, msb)	((val & BM(lsb, msb)) >> lsb)
 #define BVAL(val, n)		((val & BIT(n)) >> n)
 
-#ifdef CONFIG_MSM_QDSS
+#ifdef CONFIG_CORESIGHT_CSR
 extern void msm_qdss_csr_enable_bam_to_usb(void);
 extern void msm_qdss_csr_disable_bam_to_usb(void);
-extern unsigned int etm_readl_cp14(uint32_t off);
-extern void etm_writel_cp14(uint32_t val, uint32_t off);
+extern void msm_qdss_csr_disable_flush(void);
 #else
 static inline void msm_qdss_csr_enable_bam_to_usb(void) {}
 static inline void msm_qdss_csr_disable_bam_to_usb(void) {}
+static inline void msm_qdss_csr_disable_flush(void) {}
+#endif
+#ifdef CONFIG_CORESIGHT_ETM
+extern unsigned int etm_readl_cp14(uint32_t off);
+extern void etm_writel_cp14(uint32_t val, uint32_t off);
+#else
 static inline unsigned int etm_readl_cp14(uint32_t off) { return 0; }
 static inline void etm_writel_cp14(uint32_t val, uint32_t off) {}
 #endif
diff --git a/drivers/coresight/coresight-replicator.c b/drivers/coresight/coresight-replicator.c
index fec76c5..fe37e5e 100644
--- a/drivers/coresight/coresight-replicator.c
+++ b/drivers/coresight/coresight-replicator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/drivers/coresight/coresight-stm.c b/drivers/coresight/coresight-stm.c
index 1379c55..1db499b 100644
--- a/drivers/coresight/coresight-stm.c
+++ b/drivers/coresight/coresight-stm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -25,6 +25,7 @@
 #include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/bitmap.h>
+#include <linux/of.h>
 #include <linux/of_coresight.h>
 #include <linux/coresight.h>
 #include <linux/coresight-stm.h>
@@ -35,6 +36,10 @@
 #define stm_writel(drvdata, val, off)	__raw_writel((val), drvdata->base + off)
 #define stm_readl(drvdata, off)		__raw_readl(drvdata->base + off)
 
+#define stm_data_writeb(val, addr)	__raw_writeb_no_log(val, addr)
+#define stm_data_writew(val, addr)	__raw_writew_no_log(val, addr)
+#define stm_data_writel(val, addr)	__raw_writel_no_log(val, addr)
+
 #define STM_LOCK(drvdata)						\
 do {									\
 	mb();								\
@@ -85,8 +90,10 @@
 #define STM_USERSPACE_MAGIC1_VAL	(0xf0)
 #define STM_USERSPACE_MAGIC2_VAL	(0xf1)
 
-#define OST_START_TOKEN			(0x30)
-#define OST_VERSION			(0x1)
+#define OST_TOKEN_STARTSIMPLE		(0x10)
+#define OST_TOKEN_STARTBASE		(0x30)
+#define OST_VERSION_PROP		(1)
+#define OST_VERSION_MIPI1		(16)
 
 enum stm_pkt_type {
 	STM_PKT_TYPE_DATA	= 0x98,
@@ -102,7 +109,7 @@
 					(ch * BYTES_PER_CHANNEL))
 #define stm_channel_off(type, opts)	(type & ~opts)
 
-#ifdef CONFIG_MSM_QDSS_STM_DEFAULT_ENABLE
+#ifdef CONFIG_CORESIGHT_STM_DEFAULT_ENABLE
 static int boot_enable = 1;
 #else
 static int boot_enable;
@@ -133,6 +140,7 @@
 	struct channel_space	chs;
 	bool			enable;
 	DECLARE_BITMAP(entities, OST_ENTITY_MAX);
+	bool			write_64bit;
 };
 
 static struct stm_drvdata *stmdrvdata;
@@ -342,7 +350,7 @@
 	clear_bit(ch, drvdata->chs.bitmap);
 }
 
-static int stm_send(void *addr, const void *data, uint32_t size)
+static int stm_send_64bit(void *addr, const void *data, uint32_t size)
 {
 	uint64_t prepad = 0;
 	uint64_t postpad = 0;
@@ -376,7 +384,10 @@
 		size -= 8;
 	}
 
+	endoff = 0;
+
 	if (size) {
+		endoff = 8 - (uint8_t)size;
 		pad = (char *)&postpad;
 
 		while (size) {
@@ -386,12 +397,13 @@
 		*(volatile uint64_t __force *)addr = postpad;
 	}
 
-	return roundup(len + off, 8);
+	return len + off + endoff;
 }
 
-static int stm_trace_ost_header(unsigned long ch_addr, uint32_t options,
-				uint8_t entity_id, uint8_t proto_id,
-				const void *payload_data, uint32_t payload_size)
+static int stm_trace_ost_header_64bit(unsigned long ch_addr, uint32_t options,
+				      uint8_t entity_id, uint8_t proto_id,
+				      const void *payload_data,
+				      uint32_t payload_size)
 {
 	void *addr;
 	uint8_t prepad_size;
@@ -400,14 +412,92 @@
 
 	hdr = (char *)&header;
 
-	hdr[0] = OST_START_TOKEN;
-	hdr[1] = OST_VERSION;
+	hdr[0] = OST_TOKEN_STARTBASE;
+	hdr[1] = OST_VERSION_PROP;
 	hdr[2] = entity_id;
 	hdr[3] = proto_id;
 	prepad_size = (unsigned long)payload_data & 0x7;
 	*(uint32_t *)(hdr + 4) = (prepad_size << 24) | payload_size;
 
-	/* for 64bit writes, header is expected to be of the D32M, D32M */
+	/* for 64bit writes, header is expected to be D32M, D32M type */
+	options |= STM_OPTION_MARKED;
+	options &= ~STM_OPTION_TIMESTAMPED;
+	addr =  (void *)(ch_addr | stm_channel_off(STM_PKT_TYPE_DATA, options));
+
+	return stm_send_64bit(addr, &header, sizeof(header));
+}
+
+static int stm_trace_data_64bit(unsigned long ch_addr, uint32_t options,
+				const void *data, uint32_t size)
+{
+	void *addr;
+
+	options &= ~STM_OPTION_TIMESTAMPED;
+	addr = (void *)(ch_addr | stm_channel_off(STM_PKT_TYPE_DATA, options));
+
+	return stm_send_64bit(addr, data, size);
+}
+
+static int stm_trace_ost_tail_64bit(unsigned long ch_addr, uint32_t options)
+{
+	void *addr;
+	uint64_t tail = 0x0;
+
+	addr = (void *)(ch_addr | stm_channel_off(STM_PKT_TYPE_FLAG, options));
+
+	return stm_send_64bit(addr, &tail, sizeof(tail));
+}
+
+static int stm_send(void *addr, const void *data, uint32_t size)
+{
+	if (((unsigned long)data & 0x1) && (size >= 1)) {
+		stm_data_writeb(*(uint8_t *)data, addr);
+		data++;
+		size--;
+	}
+	if (((unsigned long)data & 0x2) && (size >= 2)) {
+		stm_data_writew(*(uint16_t *)data, addr);
+		data += 2;
+		size -= 2;
+	}
+
+	/* now we are 32bit aligned */
+	while (size >= 4) {
+		stm_data_writel(*(uint32_t *)data, addr);
+		data += 4;
+		size -= 4;
+	}
+
+	if (size >= 2) {
+		stm_data_writew(*(uint16_t *)data, addr);
+		data += 2;
+		size -= 2;
+	}
+	if (size >= 1) {
+		stm_data_writeb(*(uint8_t *)data, addr);
+		data++;
+		size--;
+	}
+
+	return size;
+}
+
+static int stm_trace_ost_header(unsigned long ch_addr, uint32_t options,
+				uint8_t entity_id, uint8_t proto_id,
+				const void *payload_data, uint32_t payload_size)
+{
+	void *addr;
+	uint32_t header;
+	char *hdr;
+
+	hdr = (char *)&header;
+
+	hdr[0] = OST_TOKEN_STARTSIMPLE;
+	hdr[1] = OST_VERSION_MIPI1;
+	hdr[2] = entity_id;
+	hdr[3] = proto_id;
+
+	/* header is expected to be D32M type */
 	options |= STM_OPTION_MARKED;
 	options &= ~STM_OPTION_TIMESTAMPED;
 	addr =  (void *)(ch_addr | stm_channel_off(STM_PKT_TYPE_DATA, options));
@@ -429,7 +519,7 @@
 static int stm_trace_ost_tail(unsigned long ch_addr, uint32_t options)
 {
 	void *addr;
-	uint64_t tail = 0x0;
+	uint32_t tail = 0x0;
 
 	addr = (void *)(ch_addr | stm_channel_off(STM_PKT_TYPE_FLAG, options));
 
@@ -448,15 +538,27 @@
 	ch = stm_channel_alloc(0);
 	ch_addr = (unsigned long)stm_channel_addr(drvdata, ch);
 
-	/* send the ost header */
-	len += stm_trace_ost_header(ch_addr, options, entity_id, proto_id, data,
-				    size);
+	if (drvdata->write_64bit) {
+		/* send the ost header */
+		len += stm_trace_ost_header_64bit(ch_addr, options, entity_id,
+						  proto_id, data, size);
 
-	/* send the payload data */
-	len += stm_trace_data(ch_addr, options, data, size);
+		/* send the payload data */
+		len += stm_trace_data_64bit(ch_addr, options, data, size);
 
-	/* send the ost tail */
-	len += stm_trace_ost_tail(ch_addr, options);
+		/* send the ost tail */
+		len += stm_trace_ost_tail_64bit(ch_addr, options);
+	} else {
+		/* send the ost header */
+		len += stm_trace_ost_header(ch_addr, options, entity_id,
+					    proto_id, data, size);
+
+		/* send the payload data */
+		len += stm_trace_data(ch_addr, options, data, size);
+
+		/* send the ost tail */
+		len += stm_trace_ost_tail(ch_addr, options);
+	}
 
 	/* we are done, free the channel */
 	stm_channel_free(ch);
@@ -744,6 +846,10 @@
 
 	bitmap_fill(drvdata->entities, OST_ENTITY_MAX);
 
+	if (pdev->dev.of_node)
+		drvdata->write_64bit = of_property_read_bool(pdev->dev.of_node,
+							"qcom,write-64bit");
+
 	desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
 	if (!desc)
 		return -ENOMEM;
@@ -768,13 +874,6 @@
 
 	dev_info(drvdata->dev, "STM initialized\n");
 
-	/*
-	 * Enable and disable STM to undo the temporary default STM enable
-	 * done by RPM.
-	 */
-	coresight_enable(drvdata->csdev);
-	coresight_disable(drvdata->csdev);
-
 	if (boot_enable)
 		coresight_enable(drvdata->csdev);
 
diff --git a/drivers/coresight/coresight-tmc.c b/drivers/coresight/coresight-tmc.c
index 3bb9ec7..0afb5a2 100644
--- a/drivers/coresight/coresight-tmc.c
+++ b/drivers/coresight/coresight-tmc.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
@@ -26,8 +26,10 @@
 #include <linux/delay.h>
 #include <linux/spinlock.h>
 #include <linux/clk.h>
+#include <linux/of.h>
 #include <linux/of_coresight.h>
 #include <linux/coresight.h>
+#include <linux/coresight-cti.h>
 #include <linux/usb/usb_qdss.h>
 #include <mach/memory.h>
 #include <mach/sps.h>
@@ -50,41 +52,45 @@
 	mb();								\
 } while (0)
 
-#define TMC_RSZ			(0x004)
-#define TMC_STS			(0x00C)
-#define TMC_RRD			(0x010)
-#define TMC_RRP			(0x014)
-#define TMC_RWP			(0x018)
-#define TMC_TRG			(0x01C)
-#define TMC_CTL			(0x020)
-#define TMC_RWD			(0x024)
-#define TMC_MODE		(0x028)
-#define TMC_LBUFLEVEL		(0x02C)
-#define TMC_CBUFLEVEL		(0x030)
-#define TMC_BUFWM		(0x034)
-#define TMC_RRPHI		(0x038)
-#define TMC_RWPHI		(0x03C)
-#define TMC_AXICTL		(0x110)
-#define TMC_DBALO		(0x118)
-#define TMC_DBAHI		(0x11C)
-#define TMC_FFSR		(0x300)
-#define TMC_FFCR		(0x304)
-#define TMC_PSCR		(0x308)
-#define TMC_ITMISCOP0		(0xEE0)
-#define TMC_ITTRFLIN		(0xEE8)
-#define TMC_ITATBDATA0		(0xEEC)
-#define TMC_ITATBCTR2		(0xEF0)
-#define TMC_ITATBCTR1		(0xEF4)
-#define TMC_ITATBCTR0		(0xEF8)
+#define TMC_RSZ				(0x004)
+#define TMC_STS				(0x00C)
+#define TMC_RRD				(0x010)
+#define TMC_RRP				(0x014)
+#define TMC_RWP				(0x018)
+#define TMC_TRG				(0x01C)
+#define TMC_CTL				(0x020)
+#define TMC_RWD				(0x024)
+#define TMC_MODE			(0x028)
+#define TMC_LBUFLEVEL			(0x02C)
+#define TMC_CBUFLEVEL			(0x030)
+#define TMC_BUFWM			(0x034)
+#define TMC_RRPHI			(0x038)
+#define TMC_RWPHI			(0x03C)
+#define TMC_AXICTL			(0x110)
+#define TMC_DBALO			(0x118)
+#define TMC_DBAHI			(0x11C)
+#define TMC_FFSR			(0x300)
+#define TMC_FFCR			(0x304)
+#define TMC_PSCR			(0x308)
+#define TMC_ITMISCOP0			(0xEE0)
+#define TMC_ITTRFLIN			(0xEE8)
+#define TMC_ITATBDATA0			(0xEEC)
+#define TMC_ITATBCTR2			(0xEF0)
+#define TMC_ITATBCTR1			(0xEF4)
+#define TMC_ITATBCTR0			(0xEF8)
 
-#define BYTES_PER_WORD		4
-#define TMC_ETR_BAM_PIPE_INDEX	0
-#define TMC_ETR_BAM_NR_PIPES	2
+#define BYTES_PER_WORD			4
+#define TMC_ETR_BAM_PIPE_INDEX		0
+#define TMC_ETR_BAM_NR_PIPES		2
 
-#define TMC_ETFETB_DUMP_VER_OFF	(4)
-#define TMC_ETFETB_DUMP_VER	(1)
-#define TMC_REG_DUMP_VER_OFF	(4)
-#define TMC_REG_DUMP_VER	(1)
+#define TMC_ETFETB_DUMP_MAGIC_OFF	(0)
+#define TMC_ETFETB_DUMP_MAGIC		(0x5D1DB1BF)
+#define TMC_ETFETB_DUMP_VER_OFF		(4)
+#define TMC_ETFETB_DUMP_VER		(1)
+#define TMC_REG_DUMP_MAGIC_OFF		(0)
+#define TMC_REG_DUMP_MAGIC		(0x5D1DB1BF)
+#define TMC_REG_DUMP_VER_OFF		(4)
+#define TMC_REG_DUMP_VER		(1)
 
 enum tmc_config_type {
 	TMC_CONFIG_TYPE_ETB,
@@ -131,9 +137,14 @@
 	struct miscdevice	miscdev;
 	struct clk		*clk;
 	spinlock_t		spinlock;
+	bool			reset_flush_race;
+	struct coresight_cti	*cti_flush;
+	struct coresight_cti	*cti_reset;
 	struct mutex		read_lock;
 	int			read_count;
 	bool			reading;
+	bool			aborting;
+	char			*reg_buf;
 	char			*buf;
 	unsigned long		paddr;
 	void __iomem		*vaddr;
@@ -148,6 +159,18 @@
 	uint32_t		trigger_cntr;
 };
 
+static void tmc_wait_for_flush(struct tmc_drvdata *drvdata)
+{
+	int count;
+
+	/* Ensure no flush is in progress */
+	for (count = TIMEOUT_US; BVAL(tmc_readl(drvdata, TMC_FFSR), 0) != 0
+				&& count > 0; count--)
+		udelay(1);
+	WARN(count == 0, "timeout while waiting for TMC flush, TMC_FFSR: %#x\n",
+	     tmc_readl(drvdata, TMC_FFSR));
+}
+
 static void tmc_wait_for_ready(struct tmc_drvdata *drvdata)
 {
 	int count;
@@ -231,7 +254,7 @@
 
 	tmc_writel(drvdata, bamdata->data_fifo.phys_base, TMC_DBALO);
 	tmc_writel(drvdata, 0x0, TMC_DBAHI);
-	tmc_writel(drvdata, 0x133, TMC_FFCR);
+	tmc_writel(drvdata, 0x103, TMC_FFCR);
 	tmc_writel(drvdata, drvdata->trigger_cntr, TMC_TRG);
 	__tmc_enable(drvdata);
 
@@ -248,7 +271,12 @@
 	if (bamdata->enable)
 		return 0;
 
-	/* Configure and enable ndp bam */
+	/* Reset bam to start with */
+	ret = sps_device_reset(bamdata->handle);
+	if (ret)
+		goto err0;
+
+	/* Now configure and enable bam */
 
 	bamdata->pipe = sps_alloc_endpoint();
 	if (!bamdata->pipe)
@@ -256,7 +284,7 @@
 
 	ret = sps_get_config(bamdata->pipe, &bamdata->connect);
 	if (ret)
-		goto err;
+		goto err1;
 
 	bamdata->connect.mode = SPS_MODE_SRC;
 	bamdata->connect.source = bamdata->handle;
@@ -271,12 +299,13 @@
 
 	ret = sps_connect(bamdata->pipe, &bamdata->connect);
 	if (ret)
-		goto err;
+		goto err1;
 
 	bamdata->enable = true;
 	return 0;
-err:
+err1:
 	sps_free_endpoint(bamdata->pipe);
+err0:
 	return ret;
 }
 
@@ -285,14 +314,18 @@
 	if (!drvdata->enable_to_bam)
 		return;
 
+	/* Ensure periodic flush is disabled in CSR block */
+	msm_qdss_csr_disable_flush();
+
 	TMC_UNLOCK(drvdata);
 
+	tmc_wait_for_flush(drvdata);
 	tmc_flush_and_stop(drvdata);
 	__tmc_disable(drvdata);
 
 	TMC_LOCK(drvdata);
 
-	/* Disable CSR registers */
+	/* Disable CSR configuration */
 	msm_qdss_csr_disable_bam_to_usb();
 	drvdata->enable_to_bam = false;
 }
@@ -343,7 +376,7 @@
 	TMC_UNLOCK(drvdata);
 
 	tmc_writel(drvdata, TMC_MODE_CIRCULAR_BUFFER, TMC_MODE);
-	tmc_writel(drvdata, 0x133, TMC_FFCR);
+	tmc_writel(drvdata, 0x1133, TMC_FFCR);
 	tmc_writel(drvdata, drvdata->trigger_cntr, TMC_TRG);
 	__tmc_enable(drvdata);
 
@@ -372,7 +405,7 @@
 
 	tmc_writel(drvdata, drvdata->paddr, TMC_DBALO);
 	tmc_writel(drvdata, 0x0, TMC_DBAHI);
-	tmc_writel(drvdata, 0x133, TMC_FFCR);
+	tmc_writel(drvdata, 0x1133, TMC_FFCR);
 	tmc_writel(drvdata, drvdata->trigger_cntr, TMC_TRG);
 	__tmc_enable(drvdata);
 
@@ -401,8 +434,15 @@
 		return ret;
 
 	mutex_lock(&drvdata->usb_lock);
-	if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) {
-		if (drvdata->out_mode == TMC_ETR_OUT_MODE_USB) {
+	if (drvdata->config_type == TMC_CONFIG_TYPE_ETB) {
+		coresight_cti_map_trigout(drvdata->cti_flush, 1, 0);
+		coresight_cti_map_trigin(drvdata->cti_reset, 0, 0);
+	} else if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) {
+		if (drvdata->out_mode == TMC_ETR_OUT_MODE_MEM &&
+		    !drvdata->reset_flush_race) {
+			coresight_cti_map_trigout(drvdata->cti_flush, 3, 0);
+			coresight_cti_map_trigin(drvdata->cti_reset, 0, 0);
+		} else if (drvdata->out_mode == TMC_ETR_OUT_MODE_USB) {
 			drvdata->usbch = usb_qdss_open("qdss", drvdata,
 						       usb_notifier);
 			if (IS_ERR(drvdata->usbch)) {
@@ -411,6 +451,11 @@
 				goto err0;
 			}
 		}
+	} else {
+		if (mode == TMC_MODE_CIRCULAR_BUFFER) {
+			coresight_cti_map_trigout(drvdata->cti_flush, 1, 0);
+			coresight_cti_map_trigin(drvdata->cti_reset, 0, 0);
+		}
 	}
 
 	spin_lock_irqsave(&drvdata->spinlock, flags);
@@ -462,10 +507,64 @@
 	return tmc_enable(drvdata, TMC_MODE_HARDWARE_FIFO);
 }
 
+static void __tmc_reg_dump(struct tmc_drvdata *drvdata)
+{
+	char *reg_hdr;
+	uint32_t *reg_buf;
+
+	if (!drvdata->reg_buf || !drvdata->aborting)
+		return;
+
+	reg_hdr = drvdata->reg_buf - PAGE_SIZE;
+	reg_buf = (uint32_t *)drvdata->reg_buf;
+
+	reg_buf[1] = tmc_readl(drvdata, TMC_RSZ);
+	reg_buf[3] = tmc_readl(drvdata, TMC_STS);
+	reg_buf[5] = tmc_readl(drvdata, TMC_RRP);
+	reg_buf[6] = tmc_readl(drvdata, TMC_RWP);
+	reg_buf[7] = tmc_readl(drvdata, TMC_TRG);
+	reg_buf[8] = tmc_readl(drvdata, TMC_CTL);
+	reg_buf[10] = tmc_readl(drvdata, TMC_MODE);
+	reg_buf[11] = tmc_readl(drvdata, TMC_LBUFLEVEL);
+	reg_buf[12] = tmc_readl(drvdata, TMC_CBUFLEVEL);
+	reg_buf[13] = tmc_readl(drvdata, TMC_BUFWM);
+	if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) {
+		reg_buf[14] = tmc_readl(drvdata, TMC_RRPHI);
+		reg_buf[15] = tmc_readl(drvdata, TMC_RWPHI);
+		reg_buf[68] = tmc_readl(drvdata, TMC_AXICTL);
+		reg_buf[70] = tmc_readl(drvdata, TMC_DBALO);
+		reg_buf[71] = tmc_readl(drvdata, TMC_DBAHI);
+	}
+	reg_buf[192] = tmc_readl(drvdata, TMC_FFSR);
+	reg_buf[193] = tmc_readl(drvdata, TMC_FFCR);
+	reg_buf[194] = tmc_readl(drvdata, TMC_PSCR);
+	reg_buf[1000] = tmc_readl(drvdata, CORESIGHT_CLAIMSET);
+	reg_buf[1001] = tmc_readl(drvdata, CORESIGHT_CLAIMCLR);
+	reg_buf[1005] = tmc_readl(drvdata, CORESIGHT_LSR);
+	reg_buf[1006] = tmc_readl(drvdata, CORESIGHT_AUTHSTATUS);
+	reg_buf[1010] = tmc_readl(drvdata, CORESIGHT_DEVID);
+	reg_buf[1011] = tmc_readl(drvdata, CORESIGHT_DEVTYPE);
+	reg_buf[1012] = tmc_readl(drvdata, CORESIGHT_PERIPHIDR4);
+	reg_buf[1013] = tmc_readl(drvdata, CORESIGHT_PERIPHIDR5);
+	reg_buf[1014] = tmc_readl(drvdata, CORESIGHT_PERIPHIDR6);
+	reg_buf[1015] = tmc_readl(drvdata, CORESIGHT_PERIPHIDR7);
+	reg_buf[1016] = tmc_readl(drvdata, CORESIGHT_PERIPHIDR0);
+	reg_buf[1017] = tmc_readl(drvdata, CORESIGHT_PERIPHIDR1);
+	reg_buf[1018] = tmc_readl(drvdata, CORESIGHT_PERIPHIDR2);
+	reg_buf[1019] = tmc_readl(drvdata, CORESIGHT_PERIPHIDR3);
+	reg_buf[1020] = tmc_readl(drvdata, CORESIGHT_COMPIDR0);
+	reg_buf[1021] = tmc_readl(drvdata, CORESIGHT_COMPIDR1);
+	reg_buf[1022] = tmc_readl(drvdata, CORESIGHT_COMPIDR2);
+	reg_buf[1023] = tmc_readl(drvdata, CORESIGHT_COMPIDR3);
+
+	*(uint32_t *)(reg_hdr + TMC_REG_DUMP_MAGIC_OFF) = TMC_REG_DUMP_MAGIC;
+}
+
 static void __tmc_etb_dump(struct tmc_drvdata *drvdata)
 {
 	enum tmc_mem_intf_width memwidth;
 	uint8_t memwords;
+	char *hdr;
 	char *bufp;
 	uint32_t read_data;
 	int i;
@@ -485,11 +584,18 @@
 		for (i = 0; i < memwords; i++) {
 			read_data = tmc_readl(drvdata, TMC_RRD);
 			if (read_data == 0xFFFFFFFF)
-				return;
+				goto out;
 			memcpy(bufp, &read_data, BYTES_PER_WORD);
 			bufp += BYTES_PER_WORD;
 		}
 	}
+
+out:
+	if (drvdata->aborting) {
+		hdr = drvdata->buf - PAGE_SIZE;
+		*(uint32_t *)(hdr + TMC_ETFETB_DUMP_MAGIC_OFF) =
+							TMC_ETFETB_DUMP_MAGIC;
+	}
 }
 
 static void __tmc_etb_disable(struct tmc_drvdata *drvdata)
@@ -498,6 +604,7 @@
 
 	tmc_flush_and_stop(drvdata);
 	__tmc_etb_dump(drvdata);
+	__tmc_reg_dump(drvdata);
 	__tmc_disable(drvdata);
 
 	TMC_LOCK(drvdata);
@@ -522,6 +629,7 @@
 
 	tmc_flush_and_stop(drvdata);
 	__tmc_etr_dump(drvdata);
+	__tmc_reg_dump(drvdata);
 	__tmc_disable(drvdata);
 
 	TMC_LOCK(drvdata);
@@ -540,7 +648,6 @@
 static void tmc_disable(struct tmc_drvdata *drvdata, enum tmc_mode mode)
 {
 	unsigned long flags;
-	bool etr_bam_disable = false;
 
 	mutex_lock(&drvdata->usb_lock);
 	spin_lock_irqsave(&drvdata->spinlock, flags);
@@ -553,27 +660,32 @@
 		if (drvdata->out_mode == TMC_ETR_OUT_MODE_MEM)
 			__tmc_etr_disable_to_mem(drvdata);
 		else if (drvdata->out_mode == TMC_ETR_OUT_MODE_USB)
-			etr_bam_disable = true;
+			__tmc_etr_disable_to_bam(drvdata);
 	} else {
 		if (mode == TMC_MODE_CIRCULAR_BUFFER)
 			__tmc_etb_disable(drvdata);
 		else
 			__tmc_etf_disable(drvdata);
 	}
-out:
 	drvdata->enable = false;
 	spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
-	if (etr_bam_disable) {
-		if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) {
-			if (drvdata->out_mode == TMC_ETR_OUT_MODE_USB) {
-				spin_lock_irqsave(&drvdata->spinlock, flags);
-				__tmc_etr_disable_to_bam(drvdata);
-				spin_unlock_irqrestore(&drvdata->spinlock,
-						       flags);
-				tmc_etr_bam_disable(drvdata);
-				usb_qdss_close(drvdata->usbch);
-			}
+	if (drvdata->config_type == TMC_CONFIG_TYPE_ETB) {
+		coresight_cti_unmap_trigin(drvdata->cti_reset, 0, 0);
+		coresight_cti_unmap_trigout(drvdata->cti_flush, 1, 0);
+	} else if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) {
+		if (drvdata->out_mode == TMC_ETR_OUT_MODE_MEM &&
+		    !drvdata->reset_flush_race) {
+			coresight_cti_unmap_trigin(drvdata->cti_reset, 0, 0);
+			coresight_cti_unmap_trigout(drvdata->cti_flush, 3, 0);
+		} else if (drvdata->out_mode == TMC_ETR_OUT_MODE_USB) {
+			tmc_etr_bam_disable(drvdata);
+			usb_qdss_close(drvdata->usbch);
+		}
+	} else {
+		if (mode == TMC_MODE_CIRCULAR_BUFFER) {
+			coresight_cti_unmap_trigin(drvdata->cti_reset, 0, 0);
+			coresight_cti_unmap_trigout(drvdata->cti_flush, 1, 0);
 		}
 	}
 	mutex_unlock(&drvdata->usb_lock);
@@ -581,6 +693,15 @@
 	clk_disable_unprepare(drvdata->clk);
 
 	dev_info(drvdata->dev, "TMC disabled\n");
+	return;
+out:
+	drvdata->enable = false;
+	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	mutex_unlock(&drvdata->usb_lock);
+
+	clk_disable_unprepare(drvdata->clk);
+
+	dev_info(drvdata->dev, "TMC disabled\n");
 }
 
 static void tmc_disable_sink(struct coresight_device *csdev)
@@ -604,6 +725,8 @@
 	unsigned long flags;
 	enum tmc_mode mode;
 
+	drvdata->aborting = true;
+
 	spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (drvdata->reading)
 		goto out0;
@@ -613,6 +736,8 @@
 	} else if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) {
 		if (drvdata->out_mode == TMC_ETR_OUT_MODE_MEM)
 			__tmc_etr_disable_to_mem(drvdata);
+		else if (drvdata->out_mode == TMC_ETR_OUT_MODE_USB)
+			__tmc_etr_disable_to_bam(drvdata);
 	} else {
 		mode = tmc_readl(drvdata, TMC_MODE);
 		if (mode == TMC_MODE_CIRCULAR_BUFFER)
@@ -846,7 +971,6 @@
 	struct tmc_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	char str[10] = "";
 	unsigned long flags;
-	bool etr_bam_flag = false;
 	int ret;
 
 	if (strlen(buf) >= 10)
@@ -860,42 +984,52 @@
 			goto out;
 
 		spin_lock_irqsave(&drvdata->spinlock, flags);
-		if (drvdata->enable) {
-			__tmc_etr_disable_to_bam(drvdata);
-			__tmc_etr_enable_to_mem(drvdata);
-			etr_bam_flag = true;
+		if (!drvdata->enable) {
+			drvdata->out_mode = TMC_ETR_OUT_MODE_MEM;
+			spin_unlock_irqrestore(&drvdata->spinlock, flags);
+			goto out;
 		}
+		__tmc_etr_disable_to_bam(drvdata);
+		__tmc_etr_enable_to_mem(drvdata);
 		drvdata->out_mode = TMC_ETR_OUT_MODE_MEM;
 		spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
-		if (etr_bam_flag) {
-			tmc_etr_bam_disable(drvdata);
-			usb_qdss_close(drvdata->usbch);
+		if (!drvdata->reset_flush_race) {
+			coresight_cti_map_trigout(drvdata->cti_flush, 3, 0);
+			coresight_cti_map_trigin(drvdata->cti_reset, 0, 0);
 		}
+
+		tmc_etr_bam_disable(drvdata);
+		usb_qdss_close(drvdata->usbch);
 	} else if (!strcmp(str, "usb")) {
 		if (drvdata->out_mode == TMC_ETR_OUT_MODE_USB)
 			goto out;
 
 		spin_lock_irqsave(&drvdata->spinlock, flags);
-		if (drvdata->enable) {
-			if (drvdata->reading) {
-				ret = -EBUSY;
-				goto err1;
-			}
-			__tmc_etr_disable_to_mem(drvdata);
-			etr_bam_flag = true;
+		if (!drvdata->enable) {
+			drvdata->out_mode = TMC_ETR_OUT_MODE_USB;
+			spin_unlock_irqrestore(&drvdata->spinlock, flags);
+			goto out;
 		}
+		if (drvdata->reading) {
+			ret = -EBUSY;
+			goto err1;
+		}
+		__tmc_etr_disable_to_mem(drvdata);
 		drvdata->out_mode = TMC_ETR_OUT_MODE_USB;
 		spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
-		if (etr_bam_flag) {
-			drvdata->usbch = usb_qdss_open("qdss", drvdata,
-						       usb_notifier);
-			if (IS_ERR(drvdata->usbch)) {
-				dev_err(drvdata->dev, "usb_qdss_open failed\n");
-				ret = PTR_ERR(drvdata->usbch);
-				goto err0;
-			}
+		if (!drvdata->reset_flush_race) {
+			coresight_cti_unmap_trigin(drvdata->cti_reset, 0, 0);
+			coresight_cti_unmap_trigout(drvdata->cti_flush, 3, 0);
+		}
+
+		drvdata->usbch = usb_qdss_open("qdss", drvdata,
+					       usb_notifier);
+		if (IS_ERR(drvdata->usbch)) {
+			dev_err(drvdata->dev, "usb_qdss_open failed\n");
+			ret = PTR_ERR(drvdata->usbch);
+			goto err0;
 		}
 	}
 out:
@@ -997,6 +1131,7 @@
 	static int count;
 	void *baddr;
 	struct msm_client_dump dump;
+	struct coresight_cti_data *ctidata;
 	struct coresight_desc *desc;
 
 	if (pdev->dev.of_node) {
@@ -1040,10 +1175,18 @@
 	devid = tmc_readl(drvdata, CORESIGHT_DEVID);
 	drvdata->config_type = BMVAL(devid, 6, 7);
 
-	if (drvdata->config_type == TMC_CONFIG_TYPE_ETR)
-		drvdata->size = SZ_1M;
-	else
+	if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) {
+		if (pdev->dev.of_node) {
+			ret = of_property_read_u32(pdev->dev.of_node,
+				"qcom,memory-reservation-size", &drvdata->size);
+			if (ret) {
+				clk_disable_unprepare(drvdata->clk);
+				return ret;
+			}
+		}
+	} else {
 		drvdata->size = tmc_readl(drvdata, TMC_RSZ) * BYTES_PER_WORD;
+	}
 
 	clk_disable_unprepare(drvdata->clk);
 
@@ -1077,8 +1220,10 @@
 		dump.start_addr = virt_to_phys(baddr);
 		dump.end_addr = dump.start_addr + PAGE_SIZE + drvdata->size;
 		ret = msm_dump_table_register(&dump);
-		/* Don't free the buffer in case of error since it can still
-		 * be used to provide dump collection via the device node
+		/*
+		 * Don't free the buffer in case of error since it can still
+		 * be used to provide dump collection via the device node or
+		 * as part of abort.
 		 */
 		if (ret)
 			dev_info(dev, "TMC ETF-ETB dump setup failed\n");
@@ -1087,20 +1232,45 @@
 
 	baddr = devm_kzalloc(dev, PAGE_SIZE + reg_size, GFP_KERNEL);
 	if (baddr) {
+		drvdata->reg_buf = baddr + PAGE_SIZE;
 		*(uint32_t *)(baddr + TMC_REG_DUMP_VER_OFF) = TMC_REG_DUMP_VER;
 		dump.id = MSM_TMC0_REG + count;
 		dump.start_addr = virt_to_phys(baddr);
 		dump.end_addr = dump.start_addr + PAGE_SIZE + reg_size;
 		ret = msm_dump_table_register(&dump);
-		if (ret) {
-			devm_kfree(dev, baddr);
+		/*
+		 * Don't free the buffer in case of error since it can still
+		 * be used to dump registers as part of abort to aid post crash
+		 * parsing.
+		 */
+		if (ret)
 			dev_info(dev, "TMC REG dump setup failed\n");
-		}
 	} else {
 		dev_info(dev, "TMC REG dump space allocation failed\n");
 	}
 	count++;
 
+	if (pdev->dev.of_node) {
+		drvdata->reset_flush_race = of_property_read_bool(
+						pdev->dev.of_node,
+						"qcom,reset-flush-race");
+
+		ctidata = of_get_coresight_cti_data(dev, pdev->dev.of_node);
+		if (IS_ERR(ctidata)) {
+			dev_err(dev, "invalid cti data\n");
+		} else if (ctidata && ctidata->nr_ctis == 2) {
+			drvdata->cti_flush = coresight_cti_get(
+							ctidata->names[0]);
+			if (IS_ERR(drvdata->cti_flush))
+				dev_err(dev, "failed to get flush cti\n");
+
+			drvdata->cti_reset = coresight_cti_get(
+							ctidata->names[1]);
+			if (IS_ERR(drvdata->cti_reset))
+				dev_err(dev, "failed to get reset cti\n");
+		}
+	}
+
 	desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
 	if (!desc) {
 		ret = -ENOMEM;
diff --git a/drivers/coresight/coresight-tpiu.c b/drivers/coresight/coresight-tpiu.c
index 290ae7f..3726a0d 100644
--- a/drivers/coresight/coresight-tpiu.c
+++ b/drivers/coresight/coresight-tpiu.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/drivers/coresight/coresight.c b/drivers/coresight/coresight.c
index 3974f2e..aef3d26 100644
--- a/drivers/coresight/coresight.c
+++ b/drivers/coresight/coresight.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
@@ -196,6 +196,9 @@
 	struct list_head *p;
 	struct coresight_connection *conn;
 
+	if (!csdev)
+		return NULL;
+
 	if (csdev->id == curr_sink) {
 		list_add_tail(&csdev->path_link, path);
 		return path;
@@ -273,9 +276,9 @@
 
 static int coresight_switch_sink(struct coresight_device *csdev)
 {
-	int ret = 0;
+	int ret, prev_sink;
 	LIST_HEAD(path);
-	struct coresight_device *cd;
+	struct coresight_device *cd, *err_cd;
 
 	if (IS_ERR_OR_NULL(csdev))
 		return -EINVAL;
@@ -291,10 +294,15 @@
 			coresight_release_path(&path);
 		}
 	}
+	prev_sink = curr_sink;
 	curr_sink = csdev->id;
 	list_for_each_entry(cd, &coresight_devs, dev_link) {
 		if (cd->type == CORESIGHT_DEV_TYPE_SOURCE && cd->enable) {
-			coresight_build_path(cd, &path);
+			if (!coresight_build_path(cd, &path)) {
+				ret = -EINVAL;
+				pr_err("coresight: build path failed\n");
+				goto err;
+			}
 			ret = coresight_enable_path(&path, false);
 			coresight_release_path(&path);
 			if (ret)
@@ -305,17 +313,30 @@
 	up(&coresight_mutex);
 	return 0;
 err:
-	list_for_each_entry(cd, &coresight_devs, dev_link) {
+	err_cd = cd;
+	list_for_each_entry_continue_reverse(cd, &coresight_devs, dev_link) {
+		if (cd->type == CORESIGHT_DEV_TYPE_SOURCE && cd->enable) {
+			coresight_build_path(cd, &path);
+			coresight_disable_path(&path, true);
+			coresight_release_path(&path);
+		}
+	}
+	cd = err_cd;
+	/* This should be an enabled source, so we can disable it directly */
+	coresight_disable_source(cd);
+	list_for_each_entry_continue(cd, &coresight_devs, dev_link) {
 		if (cd->type == CORESIGHT_DEV_TYPE_SOURCE && cd->enable)
 			coresight_disable_source(cd);
 	}
+	curr_sink = prev_sink;
+	up(&coresight_mutex);
 	pr_err("coresight: sink switch failed, sources disabled; try again\n");
 	return ret;
 }
 
 int coresight_enable(struct coresight_device *csdev)
 {
-	int ret = 0;
+	int ret;
 	LIST_HEAD(path);
 
 	if (IS_ERR_OR_NULL(csdev))
@@ -325,18 +346,26 @@
 	if (csdev->type != CORESIGHT_DEV_TYPE_SOURCE) {
 		ret = -EINVAL;
 		pr_err("coresight: wrong device type in %s\n", __func__);
-		goto out;
+		goto err;
 	}
 	if (csdev->enable)
 		goto out;
 
-	coresight_build_path(csdev, &path);
+	if (!coresight_build_path(csdev, &path)) {
+		ret = -EINVAL;
+		pr_err("coresight: build path failed\n");
+		goto err;
+	}
 	ret = coresight_enable_path(&path, true);
 	coresight_release_path(&path);
 	if (ret)
-		pr_err("coresight: enable failed\n");
+		goto err;
 out:
 	up(&coresight_mutex);
+	return 0;
+err:
+	up(&coresight_mutex);
+	pr_err("coresight: enable failed\n");
 	return ret;
 }
 EXPORT_SYMBOL_GPL(coresight_enable);
@@ -566,6 +595,9 @@
 	struct coresight_device *csdev;
 	struct coresight_connection *conns;
 
+	if (IS_ERR_OR_NULL(desc))
+		return ERR_PTR(-EINVAL);
+
 	csdev = kzalloc(sizeof(*csdev), GFP_KERNEL);
 	if (!csdev) {
 		ret = -ENOMEM;
@@ -667,7 +699,7 @@
 {
 	return bus_register(&coresight_bus_type);
 }
-subsys_initcall(coresight_init);
+core_initcall(coresight_init);
 
 static void __exit coresight_exit(void)
 {
diff --git a/drivers/coresight/of_coresight.c b/drivers/coresight/of_coresight.c
index 5c2c525..1eccd09 100644
--- a/drivers/coresight/of_coresight.c
+++ b/drivers/coresight/of_coresight.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -16,6 +16,7 @@
 #include <linux/slab.h>
 #include <linux/of.h>
 #include <linux/coresight.h>
+#include <linux/coresight-cti.h>
 
 struct coresight_platform_data *of_get_coresight_platform_data(
 				struct device *dev, struct device_node *node)
@@ -97,3 +98,45 @@
 	return pdata;
 }
 EXPORT_SYMBOL_GPL(of_get_coresight_platform_data);
+
+struct coresight_cti_data *of_get_coresight_cti_data(
+				struct device *dev, struct device_node *node)
+{
+	int i, ret;
+	uint32_t ctis_len;
+	struct device_node *child_node;
+	struct coresight_cti_data *ctidata;
+
+	ctidata = devm_kzalloc(dev, sizeof(*ctidata), GFP_KERNEL);
+	if (!ctidata)
+		return ERR_PTR(-ENOMEM);
+
+	if (of_get_property(node, "coresight-ctis", &ctis_len))
+		ctidata->nr_ctis = ctis_len/sizeof(uint32_t);
+	else
+		return ERR_PTR(-EINVAL);
+
+	if (ctidata->nr_ctis) {
+		ctidata->names = devm_kzalloc(dev, ctidata->nr_ctis *
+					      sizeof(*ctidata->names),
+					      GFP_KERNEL);
+		if (!ctidata->names)
+			return ERR_PTR(-ENOMEM);
+
+		for (i = 0; i < ctidata->nr_ctis; i++) {
+			child_node = of_parse_phandle(node, "coresight-ctis",
+						      i);
+			if (!child_node)
+				return ERR_PTR(-EINVAL);
+
+			ret = of_property_read_string(child_node,
+						      "coresight-name",
+						      &ctidata->names[i]);
+			of_node_put(child_node);
+			if (ret)
+				return ERR_PTR(ret);
+		}
+	}
+	return ctidata;
+}
+EXPORT_SYMBOL(of_get_coresight_cti_data);
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 8a75cd9..bf022ac 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -999,10 +999,14 @@
 	}
 
 	if (policy->cur < policy->max) {
-		policy->cur = policy->max;
+		/*
+		 * Arch specific cpufreq driver may fail.
+		 * Don't update governor frequency upon failure.
+		 */
+		if (__cpufreq_driver_target(policy, policy->max,
+					CPUFREQ_RELATION_L) >= 0)
+			policy->cur = policy->max;
 
-		__cpufreq_driver_target(policy, policy->max,
-					CPUFREQ_RELATION_L);
 		this_dbs_info->prev_cpu_idle = get_cpu_idle_time(cpu,
 				&this_dbs_info->prev_cpu_wall);
 	}
@@ -1166,10 +1170,10 @@
 		this_dbs_info->cur_policy = NULL;
 		if (!cpu)
 			input_unregister_handler(&dbs_input_handler);
-		mutex_unlock(&dbs_mutex);
 		if (!dbs_enable)
 			sysfs_remove_group(cpufreq_global_kobject,
 					   &dbs_attr_group);
+		mutex_unlock(&dbs_mutex);
 
 		break;
 
diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
index 78a666d..a76b689 100644
--- a/drivers/cpuidle/Kconfig
+++ b/drivers/cpuidle/Kconfig
@@ -18,3 +18,6 @@
 	bool
 	depends on CPU_IDLE && NO_HZ
 	default y
+
+config ARCH_NEEDS_CPU_IDLE_COUPLED
+	def_bool n
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index 5634f88..38c8f69 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -3,3 +3,4 @@
 #
 
 obj-y += cpuidle.o driver.o governor.o sysfs.o governors/
+obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
diff --git a/drivers/cpuidle/coupled.c b/drivers/cpuidle/coupled.c
new file mode 100644
index 0000000..c24dda0
--- /dev/null
+++ b/drivers/cpuidle/coupled.c
@@ -0,0 +1,727 @@
+/*
+ * coupled.c - helper functions to enter the same idle state on multiple cpus
+ *
+ * Copyright (c) 2011 Google, Inc.
+ *
+ * Author: Colin Cross <ccross@android.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/cpu.h>
+#include <linux/cpuidle.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include "cpuidle.h"
+
+/**
+ * DOC: Coupled cpuidle states
+ *
+ * On some ARM SMP SoCs (OMAP4460, Tegra 2, and probably more), the
+ * cpus cannot be independently powered down, either due to
+ * sequencing restrictions (on Tegra 2, cpu 0 must be the last to
+ * power down), or due to HW bugs (on OMAP4460, a cpu powering up
+ * will corrupt the gic state unless the other cpu runs a work
+ * around).  Each cpu has a power state that it can enter without
+ * coordinating with the other cpu (usually Wait For Interrupt, or
+ * WFI), and one or more "coupled" power states that affect blocks
+ * shared between the cpus (L2 cache, interrupt controller, and
+ * sometimes the whole SoC).  Entering a coupled power state must
+ * be tightly controlled on both cpus.
+ *
+ * This file implements a solution, where each cpu will wait in the
+ * WFI state until all cpus are ready to enter a coupled state, at
+ * which point the coupled state function will be called on all
+ * cpus at approximately the same time.
+ *
+ * Once all cpus are ready to enter idle, they are woken by an smp
+ * cross call.  At this point, there is a chance that one of the
+ * cpus will find work to do, and choose not to enter idle.  A
+ * final pass is needed to guarantee that all cpus will call the
+ * power state enter function at the same time.  During this pass,
+ * each cpu will increment the ready counter, and continue once the
+ * ready counter matches the number of online coupled cpus.  If any
+ * cpu exits idle, the other cpus will decrement their counter and
+ * retry.
+ *
+ * requested_state stores the deepest coupled idle state each cpu
+ * is ready for.  It is assumed that the states are indexed from
+ * shallowest (highest power, lowest exit latency) to deepest
+ * (lowest power, highest exit latency).  The requested_state
+ * variable is not locked.  It is only written from the cpu that
+ * it stores (or by the on/offlining cpu if that cpu is offline),
+ * and only read after all the cpus are ready for the coupled idle
+ * state are are no longer updating it.
+ *
+ * Three atomic counters are used.  alive_count tracks the number
+ * of cpus in the coupled set that are currently or soon will be
+ * online.  waiting_count tracks the number of cpus that are in
+ * the waiting loop, in the ready loop, or in the coupled idle state.
+ * ready_count tracks the number of cpus that are in the ready loop
+ * or in the coupled idle state.
+ *
+ * To use coupled cpuidle states, a cpuidle driver must:
+ *
+ *    Set struct cpuidle_device.coupled_cpus to the mask of all
+ *    coupled cpus, usually the same as cpu_possible_mask if all cpus
+ *    are part of the same cluster.  The coupled_cpus mask must be
+ *    set in the struct cpuidle_device for each cpu.
+ *
+ *    Set struct cpuidle_device.safe_state to a state that is not a
+ *    coupled state.  This is usually WFI.
+ *
+ *    Set CPUIDLE_FLAG_COUPLED in struct cpuidle_state.flags for each
+ *    state that affects multiple cpus.
+ *
+ *    Provide a struct cpuidle_state.enter function for each state
+ *    that affects multiple cpus.  This function is guaranteed to be
+ *    called on all cpus at approximately the same time.  The driver
+ *    should ensure that the cpus all abort together if any cpu tries
+ *    to abort once the function is called.  The function should return
+ *    with interrupts still disabled.
+ */
+
+/**
+ * struct cpuidle_coupled - data for set of cpus that share a coupled idle state
+ * @coupled_cpus: mask of cpus that are part of the coupled set
+ * @requested_state: array of requested states for cpus in the coupled set
+ * @ready_waiting_counts: combined count of cpus  in ready or waiting loops
+ * @online_count: count of cpus that are online
+ * @refcnt: reference count of cpuidle devices that are using this struct
+ * @prevent: flag to prevent coupled idle while a cpu is hotplugging
+ */
+struct cpuidle_coupled {
+	cpumask_t coupled_cpus;
+	int requested_state[NR_CPUS];
+	atomic_t ready_waiting_counts;
+	int online_count;
+	int refcnt;
+	int prevent;
+};
+
+#define WAITING_BITS 16
+#define MAX_WAITING_CPUS (1 << WAITING_BITS)
+#define WAITING_MASK (MAX_WAITING_CPUS - 1)
+#define READY_MASK (~WAITING_MASK)
+
+#define CPUIDLE_COUPLED_NOT_IDLE	(-1)
+
+static DEFINE_MUTEX(cpuidle_coupled_lock);
+static DEFINE_PER_CPU(struct call_single_data, cpuidle_coupled_poke_cb);
+
+/*
+ * The cpuidle_coupled_poked_mask mask is used to avoid calling
+ * __smp_call_function_single with the per cpu call_single_data struct already
+ * in use.  This prevents a deadlock where two cpus are waiting for each others
+ * call_single_data struct to be available
+ */
+static cpumask_t cpuidle_coupled_poked_mask;
+
+/**
+ * cpuidle_coupled_parallel_barrier - synchronize all online coupled cpus
+ * @dev: cpuidle_device of the calling cpu
+ * @a:   atomic variable to hold the barrier
+ *
+ * No caller to this function will return from this function until all online
+ * cpus in the same coupled group have called this function.  Once any caller
+ * has returned from this function, the barrier is immediately available for
+ * reuse.
+ *
+ * The atomic variable a must be initialized to 0 before any cpu calls
+ * this function, will be reset to 0 before any cpu returns from this function.
+ *
+ * Must only be called from within a coupled idle state handler
+ * (state.enter when state.flags has CPUIDLE_FLAG_COUPLED set).
+ *
+ * Provides full smp barrier semantics before and after calling.
+ */
+void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev, atomic_t *a)
+{
+	int n = dev->coupled->online_count;
+
+	smp_mb__before_atomic_inc();
+	atomic_inc(a);
+
+	while (atomic_read(a) < n)
+		cpu_relax();
+
+	if (atomic_inc_return(a) == n * 2) {
+		atomic_set(a, 0);
+		return;
+	}
+
+	while (atomic_read(a) > n)
+		cpu_relax();
+}
+
+/**
+ * cpuidle_state_is_coupled - check if a state is part of a coupled set
+ * @dev: struct cpuidle_device for the current cpu
+ * @drv: struct cpuidle_driver for the platform
+ * @state: index of the target state in drv->states
+ *
+ * Returns true if the target state is coupled with cpus besides this one
+ */
+bool cpuidle_state_is_coupled(struct cpuidle_device *dev,
+	struct cpuidle_driver *drv, int state)
+{
+	return drv->states[state].flags & CPUIDLE_FLAG_COUPLED;
+}
+
+/**
+ * cpuidle_coupled_set_ready - mark a cpu as ready
+ * @coupled: the struct coupled that contains the current cpu
+ */
+static inline void cpuidle_coupled_set_ready(struct cpuidle_coupled *coupled)
+{
+	atomic_add(MAX_WAITING_CPUS, &coupled->ready_waiting_counts);
+}
+
+/**
+ * cpuidle_coupled_set_not_ready - mark a cpu as not ready
+ * @coupled: the struct coupled that contains the current cpu
+ *
+ * Decrements the ready counter, unless the ready (and thus the waiting) counter
+ * is equal to the number of online cpus.  Prevents a race where one cpu
+ * decrements the waiting counter and then re-increments it just before another
+ * cpu has decremented its ready counter, leading to the ready counter going
+ * down from the number of online cpus without going through the coupled idle
+ * state.
+ *
+ * Returns 0 if the counter was decremented successfully, -EINVAL if the ready
+ * counter was equal to the number of online cpus.
+ */
+static
+inline int cpuidle_coupled_set_not_ready(struct cpuidle_coupled *coupled)
+{
+	int all;
+	int ret;
+
+	all = coupled->online_count || (coupled->online_count << WAITING_BITS);
+	ret = atomic_add_unless(&coupled->ready_waiting_counts,
+		-MAX_WAITING_CPUS, all);
+
+	return ret ? 0 : -EINVAL;
+}
+
+/**
+ * cpuidle_coupled_no_cpus_ready - check if no cpus in a coupled set are ready
+ * @coupled: the struct coupled that contains the current cpu
+ *
+ * Returns true if all of the cpus in a coupled set are out of the ready loop.
+ */
+static inline int cpuidle_coupled_no_cpus_ready(struct cpuidle_coupled *coupled)
+{
+	int r = atomic_read(&coupled->ready_waiting_counts) >> WAITING_BITS;
+	return r == 0;
+}
+
+/**
+ * cpuidle_coupled_cpus_ready - check if all cpus in a coupled set are ready
+ * @coupled: the struct coupled that contains the current cpu
+ *
+ * Returns true if all cpus coupled to this target state are in the ready loop
+ */
+static inline bool cpuidle_coupled_cpus_ready(struct cpuidle_coupled *coupled)
+{
+	int r = atomic_read(&coupled->ready_waiting_counts) >> WAITING_BITS;
+	return r == coupled->online_count;
+}
+
+/**
+ * cpuidle_coupled_cpus_waiting - check if all cpus in a coupled set are waiting
+ * @coupled: the struct coupled that contains the current cpu
+ *
+ * Returns true if all cpus coupled to this target state are in the wait loop
+ */
+static inline bool cpuidle_coupled_cpus_waiting(struct cpuidle_coupled *coupled)
+{
+	int w = atomic_read(&coupled->ready_waiting_counts) & WAITING_MASK;
+	return w == coupled->online_count;
+}
+
+/**
+ * cpuidle_coupled_no_cpus_waiting - check if no cpus in coupled set are waiting
+ * @coupled: the struct coupled that contains the current cpu
+ *
+ * Returns true if all of the cpus in a coupled set are out of the waiting loop.
+ */
+static inline int cpuidle_coupled_no_cpus_waiting(struct cpuidle_coupled *coupled)
+{
+	int w = atomic_read(&coupled->ready_waiting_counts) & WAITING_MASK;
+	return w == 0;
+}
+
+/**
+ * cpuidle_coupled_get_state - determine the deepest idle state
+ * @dev: struct cpuidle_device for this cpu
+ * @coupled: the struct coupled that contains the current cpu
+ *
+ * Returns the deepest idle state that all coupled cpus can enter
+ */
+static inline int cpuidle_coupled_get_state(struct cpuidle_device *dev,
+		struct cpuidle_coupled *coupled)
+{
+	int i;
+	int state = INT_MAX;
+
+	/*
+	 * Read barrier ensures that read of requested_state is ordered after
+	 * reads of ready_count.  Matches the write barriers
+	 * cpuidle_set_state_waiting.
+	 */
+	smp_rmb();
+
+	for_each_cpu_mask(i, coupled->coupled_cpus)
+		if (cpu_online(i) && coupled->requested_state[i] < state)
+			state = coupled->requested_state[i];
+
+	return state;
+}
+
+static void cpuidle_coupled_poked(void *info)
+{
+	int cpu = (unsigned long)info;
+	cpumask_clear_cpu(cpu, &cpuidle_coupled_poked_mask);
+}
+
+/**
+ * cpuidle_coupled_poke - wake up a cpu that may be waiting
+ * @cpu: target cpu
+ *
+ * Ensures that the target cpu exits it's waiting idle state (if it is in it)
+ * and will see updates to waiting_count before it re-enters it's waiting idle
+ * state.
+ *
+ * If cpuidle_coupled_poked_mask is already set for the target cpu, that cpu
+ * either has or will soon have a pending IPI that will wake it out of idle,
+ * or it is currently processing the IPI and is not in idle.
+ */
+static void cpuidle_coupled_poke(int cpu)
+{
+	struct call_single_data *csd = &per_cpu(cpuidle_coupled_poke_cb, cpu);
+
+	if (!cpumask_test_and_set_cpu(cpu, &cpuidle_coupled_poked_mask))
+		__smp_call_function_single(cpu, csd, 0);
+}
+
+/**
+ * cpuidle_coupled_poke_others - wake up all other cpus that may be waiting
+ * @dev: struct cpuidle_device for this cpu
+ * @coupled: the struct coupled that contains the current cpu
+ *
+ * Calls cpuidle_coupled_poke on all other online cpus.
+ */
+static void cpuidle_coupled_poke_others(int this_cpu,
+		struct cpuidle_coupled *coupled)
+{
+	int cpu;
+
+	for_each_cpu_mask(cpu, coupled->coupled_cpus)
+		if (cpu != this_cpu && cpu_online(cpu))
+			cpuidle_coupled_poke(cpu);
+}
+
+/**
+ * cpuidle_coupled_set_waiting - mark this cpu as in the wait loop
+ * @dev: struct cpuidle_device for this cpu
+ * @coupled: the struct coupled that contains the current cpu
+ * @next_state: the index in drv->states of the requested state for this cpu
+ *
+ * Updates the requested idle state for the specified cpuidle device,
+ * poking all coupled cpus out of idle if necessary to let them see the new
+ * state.
+ */
+static void cpuidle_coupled_set_waiting(int cpu,
+		struct cpuidle_coupled *coupled, int next_state)
+{
+	int w;
+
+	coupled->requested_state[cpu] = next_state;
+
+	/*
+	 * If this is the last cpu to enter the waiting state, poke
+	 * all the other cpus out of their waiting state so they can
+	 * enter a deeper state.  This can race with one of the cpus
+	 * exiting the waiting state due to an interrupt and
+	 * decrementing waiting_count, see comment below.
+	 *
+	 * The atomic_inc_return provides a write barrier to order the write
+	 * to requested_state with the later write that increments ready_count.
+	 */
+	w = atomic_inc_return(&coupled->ready_waiting_counts) & WAITING_MASK;
+	if (w == coupled->online_count)
+		cpuidle_coupled_poke_others(cpu, coupled);
+}
+
+/**
+ * cpuidle_coupled_set_not_waiting - mark this cpu as leaving the wait loop
+ * @dev: struct cpuidle_device for this cpu
+ * @coupled: the struct coupled that contains the current cpu
+ *
+ * Removes the requested idle state for the specified cpuidle device.
+ */
+static void cpuidle_coupled_set_not_waiting(int cpu,
+		struct cpuidle_coupled *coupled)
+{
+	/*
+	 * Decrementing waiting count can race with incrementing it in
+	 * cpuidle_coupled_set_waiting, but that's OK.  Worst case, some
+	 * cpus will increment ready_count and then spin until they
+	 * notice that this cpu has cleared it's requested_state.
+	 */
+	atomic_dec(&coupled->ready_waiting_counts);
+
+	coupled->requested_state[cpu] = CPUIDLE_COUPLED_NOT_IDLE;
+}
+
+/**
+ * cpuidle_coupled_set_done - mark this cpu as leaving the ready loop
+ * @cpu: the current cpu
+ * @coupled: the struct coupled that contains the current cpu
+ *
+ * Marks this cpu as no longer in the ready and waiting loops.  Decrements
+ * the waiting count first to prevent another cpu looping back in and seeing
+ * this cpu as waiting just before it exits idle.
+ */
+static void cpuidle_coupled_set_done(int cpu, struct cpuidle_coupled *coupled)
+{
+	cpuidle_coupled_set_not_waiting(cpu, coupled);
+	atomic_sub(MAX_WAITING_CPUS, &coupled->ready_waiting_counts);
+}
+
+/**
+ * cpuidle_coupled_clear_pokes - spin until the poke interrupt is processed
+ * @cpu - this cpu
+ *
+ * Turns on interrupts and spins until any outstanding poke interrupts have
+ * been processed and the poke bit has been cleared.
+ *
+ * Other interrupts may also be processed while interrupts are enabled, so
+ * need_resched() must be tested after turning interrupts off again to make sure
+ * the interrupt didn't schedule work that should take the cpu out of idle.
+ *
+ * Returns 0 if need_resched was false, -EINTR if need_resched was true.
+ */
+static int cpuidle_coupled_clear_pokes(int cpu)
+{
+	local_irq_enable();
+	while (cpumask_test_cpu(cpu, &cpuidle_coupled_poked_mask))
+		cpu_relax();
+	local_irq_disable();
+
+	return need_resched() ? -EINTR : 0;
+}
+
+/**
+ * cpuidle_enter_state_coupled - attempt to enter a state with coupled cpus
+ * @dev: struct cpuidle_device for the current cpu
+ * @drv: struct cpuidle_driver for the platform
+ * @next_state: index of the requested state in drv->states
+ *
+ * Coordinate with coupled cpus to enter the target state.  This is a two
+ * stage process.  In the first stage, the cpus are operating independently,
+ * and may call into cpuidle_enter_state_coupled at completely different times.
+ * To save as much power as possible, the first cpus to call this function will
+ * go to an intermediate state (the cpuidle_device's safe state), and wait for
+ * all the other cpus to call this function.  Once all coupled cpus are idle,
+ * the second stage will start.  Each coupled cpu will spin until all cpus have
+ * guaranteed that they will call the target_state.
+ *
+ * This function must be called with interrupts disabled.  It may enable
+ * interrupts while preparing for idle, and it will always return with
+ * interrupts enabled.
+ */
+int cpuidle_enter_state_coupled(struct cpuidle_device *dev,
+		struct cpuidle_driver *drv, int next_state)
+{
+	int entered_state = -1;
+	struct cpuidle_coupled *coupled = dev->coupled;
+
+	if (!coupled)
+		return -EINVAL;
+
+	while (coupled->prevent) {
+		if (cpuidle_coupled_clear_pokes(dev->cpu)) {
+			local_irq_enable();
+			return entered_state;
+		}
+		entered_state = cpuidle_enter_state(dev, drv,
+			dev->safe_state_index);
+	}
+
+	/* Read barrier ensures online_count is read after prevent is cleared */
+	smp_rmb();
+
+	cpuidle_coupled_set_waiting(dev->cpu, coupled, next_state);
+
+retry:
+	/*
+	 * Wait for all coupled cpus to be idle, using the deepest state
+	 * allowed for a single cpu.
+	 */
+	while (!cpuidle_coupled_cpus_waiting(coupled)) {
+		if (cpuidle_coupled_clear_pokes(dev->cpu)) {
+			cpuidle_coupled_set_not_waiting(dev->cpu, coupled);
+			goto out;
+		}
+
+		if (coupled->prevent) {
+			cpuidle_coupled_set_not_waiting(dev->cpu, coupled);
+			goto out;
+		}
+
+		entered_state = cpuidle_enter_state(dev, drv,
+			dev->safe_state_index);
+	}
+
+	if (cpuidle_coupled_clear_pokes(dev->cpu)) {
+		cpuidle_coupled_set_not_waiting(dev->cpu, coupled);
+		goto out;
+	}
+
+	/*
+	 * All coupled cpus are probably idle.  There is a small chance that
+	 * one of the other cpus just became active.  Increment the ready count,
+	 * and spin until all coupled cpus have incremented the counter. Once a
+	 * cpu has incremented the ready counter, it cannot abort idle and must
+	 * spin until either all cpus have incremented the ready counter, or
+	 * another cpu leaves idle and decrements the waiting counter.
+	 */
+
+	cpuidle_coupled_set_ready(coupled);
+	while (!cpuidle_coupled_cpus_ready(coupled)) {
+		/* Check if any other cpus bailed out of idle. */
+		if (!cpuidle_coupled_cpus_waiting(coupled))
+			if (!cpuidle_coupled_set_not_ready(coupled))
+				goto retry;
+
+		cpu_relax();
+	}
+
+	/* all cpus have acked the coupled state */
+	next_state = cpuidle_coupled_get_state(dev, coupled);
+
+	entered_state = cpuidle_enter_state(dev, drv, next_state);
+
+	cpuidle_coupled_set_done(dev->cpu, coupled);
+
+out:
+	/*
+	 * Normal cpuidle states are expected to return with irqs enabled.
+	 * That leads to an inefficiency where a cpu receiving an interrupt
+	 * that brings it out of idle will process that interrupt before
+	 * exiting the idle enter function and decrementing ready_count.  All
+	 * other cpus will need to spin waiting for the cpu that is processing
+	 * the interrupt.  If the driver returns with interrupts disabled,
+	 * all other cpus will loop back into the safe idle state instead of
+	 * spinning, saving power.
+	 *
+	 * Calling local_irq_enable here allows coupled states to return with
+	 * interrupts disabled, but won't cause problems for drivers that
+	 * exit with interrupts enabled.
+	 */
+	local_irq_enable();
+
+	/*
+	 * Wait until all coupled cpus have exited idle.  There is no risk that
+	 * a cpu exits and re-enters the ready state because this cpu has
+	 * already decremented its waiting_count.
+	 */
+	while (!cpuidle_coupled_no_cpus_ready(coupled))
+		cpu_relax();
+
+	return entered_state;
+}
+
+static void cpuidle_coupled_update_online_cpus(struct cpuidle_coupled *coupled)
+{
+	cpumask_t cpus;
+	cpumask_and(&cpus, cpu_online_mask, &coupled->coupled_cpus);
+	coupled->online_count = cpumask_weight(&cpus);
+}
+
+/**
+ * cpuidle_coupled_register_device - register a coupled cpuidle device
+ * @dev: struct cpuidle_device for the current cpu
+ *
+ * Called from cpuidle_register_device to handle coupled idle init.  Finds the
+ * cpuidle_coupled struct for this set of coupled cpus, or creates one if none
+ * exists yet.
+ */
+int cpuidle_coupled_register_device(struct cpuidle_device *dev)
+{
+	int cpu;
+	struct cpuidle_device *other_dev;
+	struct call_single_data *csd;
+	struct cpuidle_coupled *coupled;
+
+	if (cpumask_empty(&dev->coupled_cpus))
+		return 0;
+
+	for_each_cpu_mask(cpu, dev->coupled_cpus) {
+		other_dev = per_cpu(cpuidle_devices, cpu);
+		if (other_dev && other_dev->coupled) {
+			coupled = other_dev->coupled;
+			goto have_coupled;
+		}
+	}
+
+	/* No existing coupled info found, create a new one */
+	coupled = kzalloc(sizeof(struct cpuidle_coupled), GFP_KERNEL);
+	if (!coupled)
+		return -ENOMEM;
+
+	coupled->coupled_cpus = dev->coupled_cpus;
+
+have_coupled:
+	dev->coupled = coupled;
+	if (WARN_ON(!cpumask_equal(&dev->coupled_cpus, &coupled->coupled_cpus)))
+		coupled->prevent++;
+
+	cpuidle_coupled_update_online_cpus(coupled);
+
+	coupled->refcnt++;
+
+	csd = &per_cpu(cpuidle_coupled_poke_cb, dev->cpu);
+	csd->func = cpuidle_coupled_poked;
+	csd->info = (void *)(unsigned long)dev->cpu;
+
+	return 0;
+}
+
+/**
+ * cpuidle_coupled_unregister_device - unregister a coupled cpuidle device
+ * @dev: struct cpuidle_device for the current cpu
+ *
+ * Called from cpuidle_unregister_device to tear down coupled idle.  Removes the
+ * cpu from the coupled idle set, and frees the cpuidle_coupled_info struct if
+ * this was the last cpu in the set.
+ */
+void cpuidle_coupled_unregister_device(struct cpuidle_device *dev)
+{
+	struct cpuidle_coupled *coupled = dev->coupled;
+
+	if (cpumask_empty(&dev->coupled_cpus))
+		return;
+
+	if (--coupled->refcnt)
+		kfree(coupled);
+	dev->coupled = NULL;
+}
+
+/**
+ * cpuidle_coupled_prevent_idle - prevent cpus from entering a coupled state
+ * @coupled: the struct coupled that contains the cpu that is changing state
+ *
+ * Disables coupled cpuidle on a coupled set of cpus.  Used to ensure that
+ * cpu_online_mask doesn't change while cpus are coordinating coupled idle.
+ */
+static void cpuidle_coupled_prevent_idle(struct cpuidle_coupled *coupled)
+{
+	int cpu = get_cpu();
+
+	/* Force all cpus out of the waiting loop. */
+	coupled->prevent++;
+	cpuidle_coupled_poke_others(cpu, coupled);
+	put_cpu();
+	while (!cpuidle_coupled_no_cpus_waiting(coupled))
+		cpu_relax();
+}
+
+/**
+ * cpuidle_coupled_allow_idle - allows cpus to enter a coupled state
+ * @coupled: the struct coupled that contains the cpu that is changing state
+ *
+ * Enables coupled cpuidle on a coupled set of cpus.  Used to ensure that
+ * cpu_online_mask doesn't change while cpus are coordinating coupled idle.
+ */
+static void cpuidle_coupled_allow_idle(struct cpuidle_coupled *coupled)
+{
+	int cpu = get_cpu();
+
+	/*
+	 * Write barrier ensures readers see the new online_count when they
+	 * see prevent == 0.
+	 */
+	smp_wmb();
+	coupled->prevent--;
+	/* Force cpus out of the prevent loop. */
+	cpuidle_coupled_poke_others(cpu, coupled);
+	put_cpu();
+}
+
+/**
+ * cpuidle_coupled_cpu_notify - notifier called during hotplug transitions
+ * @nb: notifier block
+ * @action: hotplug transition
+ * @hcpu: target cpu number
+ *
+ * Called when a cpu is brought on or offline using hotplug.  Updates the
+ * coupled cpu set appropriately
+ */
+static int cpuidle_coupled_cpu_notify(struct notifier_block *nb,
+		unsigned long action, void *hcpu)
+{
+	int cpu = (unsigned long)hcpu;
+	struct cpuidle_device *dev;
+
+	switch (action & ~CPU_TASKS_FROZEN) {
+	case CPU_UP_PREPARE:
+	case CPU_DOWN_PREPARE:
+	case CPU_ONLINE:
+	case CPU_DEAD:
+	case CPU_UP_CANCELED:
+	case CPU_DOWN_FAILED:
+		break;
+	default:
+		return NOTIFY_OK;
+	}
+
+	mutex_lock(&cpuidle_lock);
+
+	dev = per_cpu(cpuidle_devices, cpu);
+	if (!dev->coupled)
+		goto out;
+
+	switch (action & ~CPU_TASKS_FROZEN) {
+	case CPU_UP_PREPARE:
+	case CPU_DOWN_PREPARE:
+		cpuidle_coupled_prevent_idle(dev->coupled);
+		break;
+	case CPU_ONLINE:
+	case CPU_DEAD:
+		cpuidle_coupled_update_online_cpus(dev->coupled);
+		/* Fall through */
+	case CPU_UP_CANCELED:
+	case CPU_DOWN_FAILED:
+		cpuidle_coupled_allow_idle(dev->coupled);
+		break;
+	}
+
+out:
+	mutex_unlock(&cpuidle_lock);
+	return NOTIFY_OK;
+}
+
+static struct notifier_block cpuidle_coupled_cpu_notifier = {
+	.notifier_call = cpuidle_coupled_cpu_notify,
+};
+
+static int __init cpuidle_coupled_init(void)
+{
+	return register_cpu_notifier(&cpuidle_coupled_cpu_notifier);
+}
+core_initcall(cpuidle_coupled_init);
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index 2f0083a..e81cfda 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -103,6 +103,34 @@
 }
 
 /**
+ * cpuidle_enter_state - enter the state and update stats
+ * @dev: cpuidle device for this cpu
+ * @drv: cpuidle driver for this cpu
+ * @next_state: index into drv->states of the state to enter
+ */
+int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
+		int next_state)
+{
+	int entered_state;
+
+	entered_state = cpuidle_enter_ops(dev, drv, next_state);
+
+	if (entered_state >= 0) {
+		/* Update cpuidle counters */
+		/* This can be moved to within driver enter routine
+		 * but that results in multiple copies of same code.
+		 */
+		dev->states_usage[entered_state].time +=
+				(unsigned long long)dev->last_residency;
+		dev->states_usage[entered_state].usage++;
+	} else {
+		dev->last_residency = 0;
+	}
+
+	return entered_state;
+}
+
+/**
  * cpuidle_idle_call - the main idle loop
  *
  * NOTE: no locks or semaphores should be used here
@@ -143,23 +171,15 @@
 	trace_power_start_rcuidle(POWER_CSTATE, next_state, dev->cpu);
 	trace_cpu_idle_rcuidle(next_state, dev->cpu);
 
-	entered_state = cpuidle_enter_ops(dev, drv, next_state);
+	if (cpuidle_state_is_coupled(dev, drv, next_state))
+		entered_state = cpuidle_enter_state_coupled(dev, drv,
+							    next_state);
+	else
+		entered_state = cpuidle_enter_state(dev, drv, next_state);
 
 	trace_power_end_rcuidle(dev->cpu);
 	trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);
 
-	if (entered_state >= 0) {
-		/* Update cpuidle counters */
-		/* This can be moved to within driver enter routine
-		 * but that results in multiple copies of same code.
-		 */
-		dev->states_usage[entered_state].time +=
-				(unsigned long long)dev->last_residency;
-		dev->states_usage[entered_state].usage++;
-	} else {
-		dev->last_residency = 0;
-	}
-
 	/* give the governor an opportunity to reflect on the outcome */
 	if (cpuidle_curr_governor->reflect)
 		cpuidle_curr_governor->reflect(dev, entered_state);
@@ -387,13 +407,25 @@
 
 	per_cpu(cpuidle_devices, dev->cpu) = dev;
 	list_add(&dev->device_list, &cpuidle_detected_devices);
-	if ((ret = cpuidle_add_sysfs(cpu_dev))) {
-		module_put(cpuidle_driver->owner);
-		return ret;
-	}
+	ret = cpuidle_add_sysfs(cpu_dev);
+	if (ret)
+		goto err_sysfs;
+
+	ret = cpuidle_coupled_register_device(dev);
+	if (ret)
+		goto err_coupled;
 
 	dev->registered = 1;
 	return 0;
+
+err_coupled:
+	cpuidle_remove_sysfs(cpu_dev);
+	wait_for_completion(&dev->kobj_unregister);
+err_sysfs:
+	list_del(&dev->device_list);
+	per_cpu(cpuidle_devices, dev->cpu) = NULL;
+	module_put(cpuidle_driver->owner);
+	return ret;
 }
 
 /**
@@ -443,6 +475,8 @@
 	wait_for_completion(&dev->kobj_unregister);
 	per_cpu(cpuidle_devices, dev->cpu) = NULL;
 
+	cpuidle_coupled_unregister_device(dev);
+
 	cpuidle_resume_and_unlock();
 
 	module_put(cpuidle_driver->owner);
diff --git a/drivers/cpuidle/cpuidle.h b/drivers/cpuidle/cpuidle.h
index 7db1866..76e7f69 100644
--- a/drivers/cpuidle/cpuidle.h
+++ b/drivers/cpuidle/cpuidle.h
@@ -14,6 +14,8 @@
 extern struct mutex cpuidle_lock;
 extern spinlock_t cpuidle_driver_lock;
 extern int cpuidle_disabled(void);
+extern int cpuidle_enter_state(struct cpuidle_device *dev,
+		struct cpuidle_driver *drv, int next_state);
 
 /* idle loop */
 extern void cpuidle_install_idle_handler(void);
@@ -30,4 +32,34 @@
 extern int cpuidle_add_sysfs(struct device *dev);
 extern void cpuidle_remove_sysfs(struct device *dev);
 
+#ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
+bool cpuidle_state_is_coupled(struct cpuidle_device *dev,
+		struct cpuidle_driver *drv, int state);
+int cpuidle_enter_state_coupled(struct cpuidle_device *dev,
+		struct cpuidle_driver *drv, int next_state);
+int cpuidle_coupled_register_device(struct cpuidle_device *dev);
+void cpuidle_coupled_unregister_device(struct cpuidle_device *dev);
+#else
+static inline bool cpuidle_state_is_coupled(struct cpuidle_device *dev,
+		struct cpuidle_driver *drv, int state)
+{
+	return false;
+}
+
+static inline int cpuidle_enter_state_coupled(struct cpuidle_device *dev,
+		struct cpuidle_driver *drv, int next_state)
+{
+	return -1;
+}
+
+static inline int cpuidle_coupled_register_device(struct cpuidle_device *dev)
+{
+	return 0;
+}
+
+static inline void cpuidle_coupled_unregister_device(struct cpuidle_device *dev)
+{
+}
+#endif
+
 #endif /* __DRIVER_CPUIDLE_H */
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 4657c37..c758b3a 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -306,7 +306,7 @@
 config CRYPTO_DEV_QCE
 	tristate "Qualcomm Crypto Engine (QCE) module"
 	select  CRYPTO_DEV_QCE40 if ARCH_MSM8960 || ARCH_MSM9615
-	select  CRYPTO_DEV_QCE50 if ARCH_MSM8974
+	select  CRYPTO_DEV_QCE50 if ARCH_MSM8974 || ARCH_MSM9625
 	default n
 	help
           This driver supports Qualcomm Crypto Engine in MSM7x30, MSM8660
diff --git a/drivers/crypto/msm/ota_crypto.c b/drivers/crypto/msm/ota_crypto.c
index b129c05..af53543 100644
--- a/drivers/crypto/msm/ota_crypto.c
+++ b/drivers/crypto/msm/ota_crypto.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/crypto/msm/qce.c b/drivers/crypto/msm/qce.c
index 4a9729c..7f8460b 100644
--- a/drivers/crypto/msm/qce.c
+++ b/drivers/crypto/msm/qce.c
@@ -1,6 +1,6 @@
 /* Qualcomm Crypto Engine driver.
  *
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * 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
@@ -474,11 +474,37 @@
 {
 	int i;
 
-	for (i = 0; nbytes > 0; i++, sg = sg_next(sg))
+	for (i = 0; nbytes > 0; i++, sg = scatterwalk_sg_next(sg))
 		nbytes -= sg->length;
 	return i;
 }
 
+static int qce_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+	enum dma_data_direction direction)
+{
+	int i;
+
+	for (i = 0; i < nents; ++i) {
+		dma_map_sg(dev, sg, 1, direction);
+		sg = scatterwalk_sg_next(sg);
+	}
+
+	return nents;
+}
+
+static int qce_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+	int nents, enum dma_data_direction direction)
+{
+	int i;
+
+	for (i = 0; i < nents; ++i) {
+		dma_unmap_sg(dev, sg, 1, direction);
+		sg = scatterwalk_sg_next(sg);
+	}
+
+	return nents;
+}
+
 static int dma_map_pmem_sg(struct buf_info *pmem, unsigned entries,
 						struct scatterlist *sg)
 {
@@ -917,15 +943,15 @@
 	ivsize = crypto_aead_ivsize(aead);
 
 	if (areq->src != areq->dst) {
-		dma_unmap_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
+		qce_dma_unmap_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
 					DMA_FROM_DEVICE);
 	}
-	dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
+	qce_dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
 			(areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
 							DMA_TO_DEVICE);
 	dma_unmap_single(pce_dev->pdev, pce_dev->phy_iv_in,
 			ivsize, DMA_TO_DEVICE);
-	dma_unmap_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
+	qce_dma_unmap_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
 			DMA_TO_DEVICE);
 
 	/* check ce error status */
@@ -975,7 +1001,7 @@
 	uint32_t status;
 
 	areq = (struct ahash_request *) pce_dev->areq;
-	dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
+	qce_dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
 				DMA_TO_DEVICE);
 
 	/* check ce error status */
@@ -1014,10 +1040,10 @@
 	areq = (struct ablkcipher_request *) pce_dev->areq;
 
 	if (areq->src != areq->dst) {
-		dma_unmap_sg(pce_dev->pdev, areq->dst,
+		qce_dma_unmap_sg(pce_dev->pdev, areq->dst,
 			pce_dev->dst_nents, DMA_FROM_DEVICE);
 	}
-	dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
+	qce_dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
 		(areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
 						DMA_TO_DEVICE);
 
@@ -1178,7 +1204,7 @@
 			}
 		}
 		if (nbytes > 0)
-			sg = sg_next(sg);
+			sg = scatterwalk_sg_next(sg);
 	}
 	return 0;
 }
@@ -1341,7 +1367,7 @@
 			}
 		}
 		if (nbytes > 0)
-			sg = sg_next(sg);
+			sg = scatterwalk_sg_next(sg);
 	}
 	return 0;
 }
@@ -2041,7 +2067,7 @@
 	pce_dev->dst_nents = 0;
 
 	pce_dev->assoc_nents = count_sg(areq->assoc, areq->assoclen);
-	dma_map_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
+	qce_dma_map_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
 					 DMA_TO_DEVICE);
 	if (_chain_sg_buffer_in(pce_dev, areq->assoc, areq->assoclen) < 0) {
 		rc = -ENOMEM;
@@ -2065,7 +2091,7 @@
 
 	/* cipher input       */
 	pce_dev->src_nents = count_sg(areq->src, q_req->cryptlen);
-	dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
+	qce_dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
 			(areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
 							DMA_TO_DEVICE);
 	if (_chain_sg_buffer_in(pce_dev, areq->src, q_req->cryptlen) < 0) {
@@ -2076,7 +2102,7 @@
 	/* cipher output      */
 	if (areq->src != areq->dst) {
 		pce_dev->dst_nents = count_sg(areq->dst, q_req->cryptlen);
-		dma_map_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
+		qce_dma_map_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
 				DMA_FROM_DEVICE);
 	};
 	if (_chain_sg_buffer_out(pce_dev, areq->dst, q_req->cryptlen) < 0) {
@@ -2119,20 +2145,20 @@
 		return 0;
 bad:
 	if (pce_dev->assoc_nents) {
-		dma_unmap_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
-				DMA_TO_DEVICE);
+		qce_dma_unmap_sg(pce_dev->pdev, areq->assoc,
+				pce_dev->assoc_nents, DMA_TO_DEVICE);
 	}
 	if (pce_dev->phy_iv_in) {
 		dma_unmap_single(pce_dev->pdev, pce_dev->phy_iv_in,
 				ivsize, DMA_TO_DEVICE);
 	}
 	if (pce_dev->src_nents) {
-		dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
+		qce_dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
 				(areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
 								DMA_TO_DEVICE);
 	}
 	if (pce_dev->dst_nents) {
-		dma_unmap_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
+		qce_dma_unmap_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
 				DMA_FROM_DEVICE);
 	}
 	return rc;
@@ -2158,7 +2184,7 @@
 	pce_dev->src_nents = count_sg(areq->src, areq->nbytes);
 
 	if (c_req->use_pmem != 1)
-		dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
+		qce_dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
 			(areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
 								DMA_TO_DEVICE);
 	else
@@ -2174,8 +2200,8 @@
 	if (areq->src != areq->dst) {
 		pce_dev->dst_nents = count_sg(areq->dst, areq->nbytes);
 		if (c_req->use_pmem != 1)
-			dma_map_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
-							DMA_FROM_DEVICE);
+			qce_dma_map_sg(pce_dev->pdev, areq->dst,
+					pce_dev->dst_nents, DMA_FROM_DEVICE);
 		else
 			dma_map_pmem_sg(&c_req->pmem->dst[0],
 					pce_dev->dst_nents, areq->dst);
@@ -2233,11 +2259,11 @@
 bad:
 	if (c_req->use_pmem != 1) {
 		if (pce_dev->dst_nents) {
-			dma_unmap_sg(pce_dev->pdev, areq->dst,
+			qce_dma_unmap_sg(pce_dev->pdev, areq->dst,
 				pce_dev->dst_nents, DMA_FROM_DEVICE);
 		}
 		if (pce_dev->src_nents) {
-			dma_unmap_sg(pce_dev->pdev, areq->src,
+			qce_dma_unmap_sg(pce_dev->pdev, areq->src,
 					pce_dev->src_nents,
 					(areq->src == areq->dst) ?
 						DMA_BIDIRECTIONAL :
@@ -2257,7 +2283,7 @@
 
 	_chain_buffer_in_init(pce_dev);
 	pce_dev->src_nents = count_sg(sreq->src, sreq->size);
-	dma_map_sg(pce_dev->pdev, sreq->src, pce_dev->src_nents,
+	qce_dma_map_sg(pce_dev->pdev, sreq->src, pce_dev->src_nents,
 							DMA_TO_DEVICE);
 
 	if (_chain_sg_buffer_in(pce_dev, sreq->src, sreq->size) < 0) {
@@ -2293,7 +2319,7 @@
 		return 0;
 bad:
 	if (pce_dev->src_nents) {
-		dma_unmap_sg(pce_dev->pdev, sreq->src,
+		qce_dma_unmap_sg(pce_dev->pdev, sreq->src,
 				pce_dev->src_nents, DMA_TO_DEVICE);
 	}
 
diff --git a/drivers/crypto/msm/qce.h b/drivers/crypto/msm/qce.h
index 037861c..8a31003 100644
--- a/drivers/crypto/msm/qce.h
+++ b/drivers/crypto/msm/qce.h
@@ -1,6 +1,6 @@
 /* Qualcomm Crypto Engine driver API
  *
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/drivers/crypto/msm/qce40.c b/drivers/crypto/msm/qce40.c
index de060cc..84d41da 100644
--- a/drivers/crypto/msm/qce40.c
+++ b/drivers/crypto/msm/qce40.c
@@ -1,6 +1,6 @@
 /* Qualcomm Crypto Engine driver.
  *
- * Copyright (c) 2011 - 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011 - 2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -107,11 +107,37 @@
 {
 	int i;
 
-	for (i = 0; nbytes > 0; i++, sg = sg_next(sg))
+	for (i = 0; nbytes > 0; i++, sg = scatterwalk_sg_next(sg))
 		nbytes -= sg->length;
 	return i;
 }
 
+static int qce_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+	enum dma_data_direction direction)
+{
+	int i;
+
+	for (i = 0; i < nents; ++i) {
+		dma_map_sg(dev, sg, 1, direction);
+		sg = scatterwalk_sg_next(sg);
+	}
+
+	return nents;
+}
+
+static int qce_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+	int nents, enum dma_data_direction direction)
+{
+	int i;
+
+	for (i = 0; i < nents; ++i) {
+		dma_unmap_sg(dev, sg, 1, direction);
+		sg = scatterwalk_sg_next(sg);
+	}
+
+	return nents;
+}
+
 static int dma_map_pmem_sg(struct buf_info *pmem, unsigned entries,
 						struct scatterlist *sg)
 {
@@ -670,14 +696,14 @@
 	areq = (struct aead_request *) pce_dev->areq;
 
 	if (areq->src != areq->dst) {
-		dma_unmap_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
+		qce_dma_unmap_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
 					DMA_FROM_DEVICE);
 	}
-	dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
+	qce_dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
 			(areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
 							DMA_TO_DEVICE);
 
-	dma_unmap_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
+	qce_dma_unmap_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
 			DMA_TO_DEVICE);
 
 	/* check MAC */
@@ -700,7 +726,7 @@
 	struct ahash_request *areq;
 
 	areq = (struct ahash_request *) pce_dev->areq;
-	dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
+	qce_dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
 				DMA_TO_DEVICE);
 
 	pce_dev->qce_cb(areq,  pce_dev->ce_dm.buffer.auth_result,
@@ -716,10 +742,10 @@
 	areq = (struct ablkcipher_request *) pce_dev->areq;
 
 	if (areq->src != areq->dst) {
-		dma_unmap_sg(pce_dev->pdev, areq->dst,
+		qce_dma_unmap_sg(pce_dev->pdev, areq->dst,
 			pce_dev->dst_nents, DMA_FROM_DEVICE);
 	}
-	dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
+	qce_dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
 		(areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
 						DMA_TO_DEVICE);
 
@@ -826,7 +852,7 @@
 					&pce_dev->ce_dm.ce_in_src_desc_index);
 		}
 		if (nbytes > 0)
-			sg = sg_next(sg);
+			sg = scatterwalk_sg_next(sg);
 	}
 	return 0;
 }
@@ -989,7 +1015,7 @@
 
 		}
 		if (nbytes > 0)
-			sg = sg_next(sg);
+			sg = scatterwalk_sg_next(sg);
 	}
 	return 0;
 }
@@ -2149,7 +2175,7 @@
 
 	/* associated data input */
 	pce_dev->assoc_nents = count_sg(areq->assoc, areq->assoclen);
-	dma_map_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
+	qce_dma_map_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
 					 DMA_TO_DEVICE);
 	if (_chain_sg_buffer_in(pce_dev, areq->assoc, areq->assoclen) < 0) {
 		rc = -ENOMEM;
@@ -2157,7 +2183,7 @@
 	}
 	/* cipher input */
 	pce_dev->src_nents = count_sg(areq->src, areq->cryptlen);
-	dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
+	qce_dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
 			(areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
 							DMA_TO_DEVICE);
 	if (_chain_sg_buffer_in(pce_dev, areq->src, areq->cryptlen) < 0) {
@@ -2182,7 +2208,7 @@
 	/* cipher + mac output  for encryption    */
 	if (areq->src != areq->dst) {
 		pce_dev->dst_nents = count_sg(areq->dst, out_len);
-		dma_map_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
+		qce_dma_map_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
 				DMA_FROM_DEVICE);
 	};
 	if (_chain_sg_buffer_out(pce_dev, areq->dst, out_len) < 0) {
@@ -2222,17 +2248,17 @@
 		return 0;
 bad:
 	if (pce_dev->assoc_nents) {
-		dma_unmap_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
-				DMA_TO_DEVICE);
+		qce_dma_unmap_sg(pce_dev->pdev, areq->assoc,
+				pce_dev->assoc_nents, DMA_TO_DEVICE);
 	}
 
 	if (pce_dev->src_nents) {
-		dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
+		qce_dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
 				(areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
 								DMA_TO_DEVICE);
 	}
 	if (pce_dev->dst_nents) {
-		dma_unmap_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
+		qce_dma_unmap_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
 				DMA_FROM_DEVICE);
 	}
 	return rc;
@@ -2259,7 +2285,7 @@
 	pce_dev->src_nents = count_sg(areq->src, areq->nbytes);
 
 	if (c_req->use_pmem != 1)
-		dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
+		qce_dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
 			(areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
 								DMA_TO_DEVICE);
 	else
@@ -2275,8 +2301,8 @@
 	if (areq->src != areq->dst) {
 		pce_dev->dst_nents = count_sg(areq->dst, areq->nbytes);
 		if (c_req->use_pmem != 1)
-			dma_map_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
-							DMA_FROM_DEVICE);
+			qce_dma_map_sg(pce_dev->pdev, areq->dst,
+					pce_dev->dst_nents, DMA_FROM_DEVICE);
 		else
 			dma_map_pmem_sg(&c_req->pmem->dst[0],
 					pce_dev->dst_nents, areq->dst);
@@ -2333,11 +2359,11 @@
 bad:
 	if (c_req->use_pmem != 1) {
 			if (pce_dev->dst_nents) {
-				dma_unmap_sg(pce_dev->pdev, areq->dst,
+				qce_dma_unmap_sg(pce_dev->pdev, areq->dst,
 				pce_dev->dst_nents, DMA_FROM_DEVICE);
 			}
 		if (pce_dev->src_nents) {
-			dma_unmap_sg(pce_dev->pdev, areq->src,
+			qce_dma_unmap_sg(pce_dev->pdev, areq->src,
 					pce_dev->src_nents,
 					(areq->src == areq->dst) ?
 						DMA_BIDIRECTIONAL :
@@ -2358,7 +2384,7 @@
 
 	_chain_buffer_in_init(pce_dev);
 	pce_dev->src_nents = count_sg(sreq->src, sreq->size);
-	dma_map_sg(pce_dev->pdev, sreq->src, pce_dev->src_nents,
+	qce_dma_map_sg(pce_dev->pdev, sreq->src, pce_dev->src_nents,
 							DMA_TO_DEVICE);
 
 	if (_chain_sg_buffer_in(pce_dev, sreq->src, sreq->size) < 0) {
@@ -2392,7 +2418,7 @@
 		return 0;
 bad:
 	if (pce_dev->src_nents) {
-		dma_unmap_sg(pce_dev->pdev, sreq->src,
+		qce_dma_unmap_sg(pce_dev->pdev, sreq->src,
 				pce_dev->src_nents, DMA_TO_DEVICE);
 	}
 
diff --git a/drivers/crypto/msm/qce40.h b/drivers/crypto/msm/qce40.h
index 809ba7f..0d19106 100644
--- a/drivers/crypto/msm/qce40.h
+++ b/drivers/crypto/msm/qce40.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c
index d605a61..3da06a5 100644
--- a/drivers/crypto/msm/qce50.c
+++ b/drivers/crypto/msm/qce50.c
@@ -1,6 +1,6 @@
 /* Qualcomm Crypto Engine driver.
  *
- * Copyright (c) 2012, Code Aurora Forum. 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
@@ -39,6 +39,8 @@
 #include "qcryptohw_50.h"
 
 #define CRYPTO_CONFIG_RESET 0xE001F
+#define QCE_MAX_NUM_DSCR    0x400
+#define QCE_SIZE_BAM_DSCR   0x08
 
 static DEFINE_MUTEX(bam_register_cnt);
 struct bam_registration_info {
@@ -139,11 +141,37 @@
 {
 	int i;
 
-	for (i = 0; nbytes > 0; i++, sg = sg_next(sg))
+	for (i = 0; nbytes > 0; i++, sg = scatterwalk_sg_next(sg))
 		nbytes -= sg->length;
 	return i;
 }
 
+static int qce_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+	enum dma_data_direction direction)
+{
+	int i;
+
+	for (i = 0; i < nents; ++i) {
+		dma_map_sg(dev, sg, 1, direction);
+		sg = scatterwalk_sg_next(sg);
+	}
+
+	return nents;
+}
+
+static int qce_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+	int nents, enum dma_data_direction direction)
+{
+	int i;
+
+	for (i = 0; i < nents; ++i) {
+		dma_unmap_sg(dev, sg, 1, direction);
+		sg = scatterwalk_sg_next(sg);
+	}
+
+	return nents;
+}
+
 static int _probe_ce_engine(struct qce_device *pce_dev)
 {
 	unsigned int rev;
@@ -675,13 +703,13 @@
 
 	areq = (struct aead_request *) pce_dev->areq;
 	if (areq->src != areq->dst) {
-		dma_unmap_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
+		qce_dma_unmap_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
 					DMA_FROM_DEVICE);
 	}
-	dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
+	qce_dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
 			(areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
 							DMA_TO_DEVICE);
-	dma_unmap_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
+	qce_dma_unmap_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
 			DMA_TO_DEVICE);
 	/* check MAC */
 	memcpy(mac, (char *)(&pce_dev->ce_sps.result->auth_iv[0]),
@@ -721,7 +749,7 @@
 	uint32_t bytecount32[2];
 
 	areq = (struct ahash_request *) pce_dev->areq;
-	dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
+	qce_dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
 				DMA_TO_DEVICE);
 	memcpy(digest, (char *)(&pce_dev->ce_sps.result->auth_iv[0]),
 						SHA256_DIGEST_SIZE);
@@ -743,10 +771,10 @@
 	areq = (struct ablkcipher_request *) pce_dev->areq;
 
 	if (areq->src != areq->dst) {
-		dma_unmap_sg(pce_dev->pdev, areq->dst,
+		qce_dma_unmap_sg(pce_dev->pdev, areq->dst,
 			pce_dev->dst_nents, DMA_FROM_DEVICE);
 	}
-	dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
+	qce_dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
 		(areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
 						DMA_TO_DEVICE);
 	if (_qce_unlock_other_pipes(pce_dev))
@@ -910,7 +938,7 @@
 			addr += data_cnt;
 			len -= data_cnt;
 		}
-		sg_src++;
+		sg_src = scatterwalk_sg_next(sg_src);
 	}
 	return 0;
 }
@@ -1042,7 +1070,7 @@
 	 * descriptor memory (256 bytes + 8 bytes). But in order to be
 	 * in power of 2, we are allocating 512 bytes of memory.
 	 */
-	sps_connect_info->desc.size = 512;
+	sps_connect_info->desc.size = QCE_MAX_NUM_DSCR * QCE_SIZE_BAM_DSCR;
 	sps_connect_info->desc.base = dma_alloc_coherent(pce_dev->pdev,
 					sps_connect_info->desc.size,
 					&sps_connect_info->desc.phys_base,
@@ -1248,8 +1276,27 @@
 			notify->data.transfer.iovec.addr,
 			notify->data.transfer.iovec.size,
 			notify->data.transfer.iovec.flags);
-	/* done */
-	_aead_complete(pce_dev);
+
+	if (pce_dev->ce_sps.producer_state == QCE_PIPE_STATE_COMP) {
+		pce_dev->ce_sps.producer_state = QCE_PIPE_STATE_IDLE;
+		/* done */
+		_aead_complete(pce_dev);
+	} else {
+		int rc = 0;
+		pce_dev->ce_sps.producer_state = QCE_PIPE_STATE_COMP;
+		pce_dev->ce_sps.out_transfer.iovec_count = 0;
+		_qce_sps_add_data(GET_PHYS_ADDR(pce_dev->ce_sps.result_dump),
+					CRYPTO_RESULT_DUMP_SIZE,
+					  &pce_dev->ce_sps.out_transfer);
+		_qce_set_flag(&pce_dev->ce_sps.out_transfer,
+				SPS_IOVEC_FLAG_EOT|SPS_IOVEC_FLAG_INT);
+		rc = sps_transfer(pce_dev->ce_sps.producer.pipe,
+					  &pce_dev->ce_sps.out_transfer);
+		if (rc) {
+			pr_err("sps_xfr() fail (producer pipe=0x%x) rc = %d,",
+				(u32)pce_dev->ce_sps.producer.pipe, rc);
+		}
+	}
 };
 
 static void _aead_sps_consumer_callback(struct sps_event_notify *notify)
@@ -1304,8 +1351,27 @@
 			notify->data.transfer.iovec.addr,
 			notify->data.transfer.iovec.size,
 			notify->data.transfer.iovec.flags);
-	/* done */
-	_ablk_cipher_complete(pce_dev);
+
+	if (pce_dev->ce_sps.producer_state == QCE_PIPE_STATE_COMP) {
+		pce_dev->ce_sps.producer_state = QCE_PIPE_STATE_IDLE;
+		/* done */
+		_ablk_cipher_complete(pce_dev);
+	} else {
+		int rc = 0;
+		pce_dev->ce_sps.producer_state = QCE_PIPE_STATE_COMP;
+		pce_dev->ce_sps.out_transfer.iovec_count = 0;
+		_qce_sps_add_data(GET_PHYS_ADDR(pce_dev->ce_sps.result_dump),
+					CRYPTO_RESULT_DUMP_SIZE,
+					  &pce_dev->ce_sps.out_transfer);
+		_qce_set_flag(&pce_dev->ce_sps.out_transfer,
+				SPS_IOVEC_FLAG_EOT|SPS_IOVEC_FLAG_INT);
+		rc = sps_transfer(pce_dev->ce_sps.producer.pipe,
+					  &pce_dev->ce_sps.out_transfer);
+		if (rc) {
+			pr_err("sps_xfr() fail (producer pipe=0x%x) rc = %d,",
+				(u32)pce_dev->ce_sps.producer.pipe, rc);
+		}
+	}
 };
 
 static void _ablk_cipher_sps_consumer_callback(struct sps_event_notify *notify)
@@ -2210,16 +2276,16 @@
 	pce_dev->phy_iv_in = 0;
 
 	/* associated data input */
-	dma_map_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
+	qce_dma_map_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
 					 DMA_TO_DEVICE);
 	/* cipher input */
-	dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
+	qce_dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
 			(areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
 							DMA_TO_DEVICE);
 	/* cipher + mac output  for encryption    */
 	if (areq->src != areq->dst) {
 		pce_dev->dst_nents = count_sg(areq->dst, out_len);
-		dma_map_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
+		qce_dma_map_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
 				DMA_FROM_DEVICE);
 	} else {
 		pce_dev->dst_nents = pce_dev->src_nents;
@@ -2255,7 +2321,6 @@
 		pr_err("Producer callback registration failed rc = %d\n", rc);
 		goto bad;
 	}
-
 	/* Register callback event for EOT (End of transfer) event. */
 	pce_dev->ce_sps.consumer.event.callback = _aead_sps_consumer_callback;
 	rc = sps_register_event(pce_dev->ce_sps.consumer.pipe,
@@ -2280,11 +2345,21 @@
 		_qce_sps_add_sg_data(pce_dev, areq->dst, out_len +
 					areq->assoclen + hw_pad_out,
 				&pce_dev->ce_sps.out_transfer);
-		_qce_sps_add_data(GET_PHYS_ADDR(pce_dev->ce_sps.result_dump),
+		if (totallen_in > SPS_MAX_PKT_SIZE) {
+			_qce_set_flag(&pce_dev->ce_sps.out_transfer,
+							SPS_IOVEC_FLAG_INT);
+			pce_dev->ce_sps.producer.event.options =
+							SPS_O_DESC_DONE;
+			pce_dev->ce_sps.producer_state = QCE_PIPE_STATE_IDLE;
+		} else {
+			_qce_sps_add_data(GET_PHYS_ADDR(
+					pce_dev->ce_sps.result_dump),
 					CRYPTO_RESULT_DUMP_SIZE,
-					&pce_dev->ce_sps.out_transfer);
-		_qce_set_flag(&pce_dev->ce_sps.out_transfer,
-					SPS_IOVEC_FLAG_INT);
+					  &pce_dev->ce_sps.out_transfer);
+			_qce_set_flag(&pce_dev->ce_sps.out_transfer,
+							SPS_IOVEC_FLAG_INT);
+			pce_dev->ce_sps.producer_state = QCE_PIPE_STATE_COMP;
+		}
 	} else {
 		_qce_sps_add_sg_data(pce_dev, areq->assoc, areq->assoclen,
 					 &pce_dev->ce_sps.in_transfer);
@@ -2304,11 +2379,21 @@
 		/* Pass through to ignore hw_pad (padding of the MAC data) */
 		_qce_sps_add_data(GET_PHYS_ADDR(pce_dev->ce_sps.ignore_buffer),
 				hw_pad_out, &pce_dev->ce_sps.out_transfer);
-
-		_qce_sps_add_data(GET_PHYS_ADDR(pce_dev->ce_sps.result_dump),
-			CRYPTO_RESULT_DUMP_SIZE, &pce_dev->ce_sps.out_transfer);
-		_qce_set_flag(&pce_dev->ce_sps.out_transfer,
-					SPS_IOVEC_FLAG_INT);
+		if (totallen_in > SPS_MAX_PKT_SIZE) {
+			_qce_set_flag(&pce_dev->ce_sps.out_transfer,
+							SPS_IOVEC_FLAG_INT);
+			pce_dev->ce_sps.producer.event.options =
+							SPS_O_DESC_DONE;
+			pce_dev->ce_sps.producer_state = QCE_PIPE_STATE_IDLE;
+		} else {
+			_qce_sps_add_data(
+				GET_PHYS_ADDR(pce_dev->ce_sps.result_dump),
+					CRYPTO_RESULT_DUMP_SIZE,
+					  &pce_dev->ce_sps.out_transfer);
+			_qce_set_flag(&pce_dev->ce_sps.out_transfer,
+							SPS_IOVEC_FLAG_INT);
+			pce_dev->ce_sps.producer_state = QCE_PIPE_STATE_COMP;
+		}
 	}
 	rc = _qce_sps_transfer(pce_dev);
 	if (rc)
@@ -2317,16 +2402,16 @@
 
 bad:
 	if (pce_dev->assoc_nents) {
-		dma_unmap_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
-				DMA_TO_DEVICE);
+		qce_dma_unmap_sg(pce_dev->pdev, areq->assoc,
+				pce_dev->assoc_nents, DMA_TO_DEVICE);
 	}
 	if (pce_dev->src_nents) {
-		dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
+		qce_dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
 				(areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
 								DMA_TO_DEVICE);
 	}
 	if (areq->src != areq->dst) {
-		dma_unmap_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
+		qce_dma_unmap_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
 				DMA_FROM_DEVICE);
 	}
 	if (pce_dev->phy_iv_in) {
@@ -2353,14 +2438,14 @@
 	/* cipher input */
 	pce_dev->src_nents = count_sg(areq->src, areq->nbytes);
 
-	dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
+	qce_dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
 		(areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
 							DMA_TO_DEVICE);
 	/* cipher output */
 	if (areq->src != areq->dst) {
 		pce_dev->dst_nents = count_sg(areq->dst, areq->nbytes);
-			dma_map_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
-							DMA_FROM_DEVICE);
+			qce_dma_map_sg(pce_dev->pdev, areq->dst,
+				pce_dev->dst_nents, DMA_FROM_DEVICE);
 	} else {
 		pce_dev->dst_nents = pce_dev->src_nents;
 	}
@@ -2392,7 +2477,6 @@
 		pr_err("Producer callback registration failed rc = %d\n", rc);
 		goto bad;
 	}
-
 	/* Register callback event for EOT (End of transfer) event. */
 	pce_dev->ce_sps.consumer.event.callback =
 			_ablk_cipher_sps_consumer_callback;
@@ -2414,21 +2498,32 @@
 
 	_qce_sps_add_sg_data(pce_dev, areq->dst, areq->nbytes,
 					&pce_dev->ce_sps.out_transfer);
-	_qce_sps_add_data(GET_PHYS_ADDR(pce_dev->ce_sps.result_dump),
+	if (areq->nbytes > SPS_MAX_PKT_SIZE) {
+		_qce_set_flag(&pce_dev->ce_sps.out_transfer,
+							SPS_IOVEC_FLAG_INT);
+		pce_dev->ce_sps.producer.event.options = SPS_O_DESC_DONE;
+		pce_dev->ce_sps.producer_state = QCE_PIPE_STATE_IDLE;
+	} else {
+		pce_dev->ce_sps.producer_state = QCE_PIPE_STATE_COMP;
+		_qce_sps_add_data(GET_PHYS_ADDR(pce_dev->ce_sps.result_dump),
 					CRYPTO_RESULT_DUMP_SIZE,
 					  &pce_dev->ce_sps.out_transfer);
-	_qce_set_flag(&pce_dev->ce_sps.out_transfer, SPS_IOVEC_FLAG_INT);
+		_qce_set_flag(&pce_dev->ce_sps.out_transfer,
+							SPS_IOVEC_FLAG_INT);
+	}
 	rc = _qce_sps_transfer(pce_dev);
 	if (rc)
 		goto bad;
 		return 0;
 bad:
-	if (pce_dev->dst_nents) {
-		dma_unmap_sg(pce_dev->pdev, areq->dst,
-		pce_dev->dst_nents, DMA_FROM_DEVICE);
+	if (areq->src != areq->dst) {
+		if (pce_dev->dst_nents) {
+			qce_dma_unmap_sg(pce_dev->pdev, areq->dst,
+			pce_dev->dst_nents, DMA_FROM_DEVICE);
+		}
 	}
 	if (pce_dev->src_nents) {
-		dma_unmap_sg(pce_dev->pdev, areq->src,
+		qce_dma_unmap_sg(pce_dev->pdev, areq->src,
 				pce_dev->src_nents,
 				(areq->src == areq->dst) ?
 				DMA_BIDIRECTIONAL : DMA_TO_DEVICE);
@@ -2447,7 +2542,7 @@
 
 	pce_dev->src_nents = count_sg(sreq->src, sreq->size);
 	_ce_get_hash_cmdlistinfo(pce_dev, sreq, &cmdlistinfo);
-	dma_map_sg(pce_dev->pdev, sreq->src, pce_dev->src_nents,
+	qce_dma_map_sg(pce_dev->pdev, sreq->src, pce_dev->src_nents,
 							DMA_TO_DEVICE);
 	rc = _ce_setup_hash(pce_dev, sreq, cmdlistinfo);
 	if (rc < 0)
@@ -2493,7 +2588,7 @@
 		return 0;
 bad:
 	if (pce_dev->src_nents) {
-		dma_unmap_sg(pce_dev->pdev, sreq->src,
+		qce_dma_unmap_sg(pce_dev->pdev, sreq->src,
 				pce_dev->src_nents, DMA_TO_DEVICE);
 	}
 	return rc;
diff --git a/drivers/crypto/msm/qce50.h b/drivers/crypto/msm/qce50.h
index 8533636..dc4ccf7 100644
--- a/drivers/crypto/msm/qce50.h
+++ b/drivers/crypto/msm/qce50.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/crypto/msm/qce_ota.h b/drivers/crypto/msm/qce_ota.h
index 72af585..8778ca5 100644
--- a/drivers/crypto/msm/qce_ota.h
+++ b/drivers/crypto/msm/qce_ota.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c
index f1c31c1..50d454c 100644
--- a/drivers/crypto/msm/qcedev.c
+++ b/drivers/crypto/msm/qcedev.c
@@ -1,6 +1,6 @@
 /* Qualcomm CE device driver.
  *
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * 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
@@ -721,11 +721,11 @@
 
 
 static int qcedev_sha_update_max_xfer(struct qcedev_async_req *qcedev_areq,
-				struct qcedev_handle *handle)
+				struct qcedev_handle *handle,
+				struct scatterlist *sg_src)
 {
 	int err = 0;
 	int i = 0;
-	struct scatterlist sg_src[2];
 	uint32_t total;
 
 	uint8_t *user_src = NULL;
@@ -814,7 +814,7 @@
 	sha_pad_len = ALIGN(total, CE_SHA_BLOCK_SIZE) - total;
 	trailing_buf_len =  CE_SHA_BLOCK_SIZE - sha_pad_len;
 
-	qcedev_areq->sha_req.sreq.src = (struct scatterlist *) &sg_src[0];
+	qcedev_areq->sha_req.sreq.src = sg_src;
 	sg_set_buf(qcedev_areq->sha_req.sreq.src, k_align_src,
 						total-trailing_buf_len);
 	sg_mark_end(qcedev_areq->sha_req.sreq.src);
@@ -840,7 +840,8 @@
 }
 
 static int qcedev_sha_update(struct qcedev_async_req *qcedev_areq,
-				struct qcedev_handle *handle)
+				struct qcedev_handle *handle,
+				struct scatterlist *sg_src)
 {
 	int err = 0;
 	int i = 0;
@@ -887,7 +888,7 @@
 				sreq->entries = 1;
 
 				err = qcedev_sha_update_max_xfer(qcedev_areq,
-									handle);
+								handle, sg_src);
 
 				sreq->data[i].len = req.data[i].len -
 							QCE_MAX_OPER_DATA;
@@ -921,7 +922,7 @@
 
 				i = j;
 				err = qcedev_sha_update_max_xfer(qcedev_areq,
-									handle);
+								handle, sg_src);
 				num_entries = 0;
 
 				sreq->data[i].vaddr = req.data[i].vaddr +
@@ -945,7 +946,7 @@
 		sreq->data_len = saved_req->data_len;
 		kfree(saved_req);
 	} else
-		err = qcedev_sha_update_max_xfer(qcedev_areq, handle);
+		err = qcedev_sha_update_max_xfer(qcedev_areq, handle, sg_src);
 
 	return err;
 }
@@ -997,11 +998,11 @@
 }
 
 static int qcedev_hash_cmac(struct qcedev_async_req *qcedev_areq,
-					struct qcedev_handle *handle)
+					struct qcedev_handle *handle,
+					struct scatterlist *sg_src)
 {
 	int err = 0;
 	int i = 0;
-	struct scatterlist sg_src[2];
 	uint32_t total;
 
 	uint8_t *user_src = NULL;
@@ -1050,7 +1051,7 @@
 		k_src += qcedev_areq->sha_op_req.data[i].len;
 	}
 
-	qcedev_areq->sha_req.sreq.src = (struct scatterlist *) &sg_src[0];
+	qcedev_areq->sha_req.sreq.src = sg_src;
 	sg_set_buf(qcedev_areq->sha_req.sreq.src, k_buf_src, total);
 	sg_mark_end(qcedev_areq->sha_req.sreq.src);
 
@@ -1063,7 +1064,8 @@
 }
 
 static int qcedev_set_hmac_auth_key(struct qcedev_async_req *areq,
-					struct qcedev_handle *handle)
+					struct qcedev_handle *handle,
+					struct scatterlist *sg_src)
 {
 	int err = 0;
 
@@ -1102,7 +1104,7 @@
 		authkey_areq.op_type = QCEDEV_CRYPTO_OPER_SHA;
 
 		qcedev_sha_init(&authkey_areq, handle);
-		err = qcedev_sha_update(&authkey_areq, handle);
+		err = qcedev_sha_update(&authkey_areq, handle, sg_src);
 		if (!err)
 			err = qcedev_sha_final(&authkey_areq, handle);
 		else
@@ -1208,12 +1210,13 @@
 }
 
 static int qcedev_hmac_init(struct qcedev_async_req *areq,
-				struct qcedev_handle *handle)
+				struct qcedev_handle *handle,
+				struct scatterlist *sg_src)
 {
 	int err;
 	struct qcedev_control *podev = handle->cntl;
 
-	err = qcedev_set_hmac_auth_key(areq, handle);
+	err = qcedev_set_hmac_auth_key(areq, handle, sg_src);
 	if (err)
 		return err;
 	if (!podev->ce_support.sha_hmac)
@@ -1241,19 +1244,21 @@
 }
 
 static int qcedev_hash_init(struct qcedev_async_req *areq,
-				struct qcedev_handle *handle)
+				struct qcedev_handle *handle,
+				struct scatterlist *sg_src)
 {
 	if ((areq->sha_op_req.alg == QCEDEV_ALG_SHA1) ||
 			(areq->sha_op_req.alg == QCEDEV_ALG_SHA256))
 		return qcedev_sha_init(areq, handle);
 	else
-		return qcedev_hmac_init(areq, handle);
+		return qcedev_hmac_init(areq, handle, sg_src);
 }
 
 static int qcedev_hash_update(struct qcedev_async_req *qcedev_areq,
-				struct qcedev_handle *handle)
+				struct qcedev_handle *handle,
+				struct scatterlist *sg_src)
 {
-	return qcedev_sha_update(qcedev_areq, handle);
+	return qcedev_sha_update(qcedev_areq, handle, sg_src);
 }
 
 static int qcedev_hash_final(struct qcedev_async_req *areq,
@@ -1895,7 +1900,8 @@
 		break;
 
 	case QCEDEV_IOCTL_SHA_INIT_REQ:
-
+		{
+		struct scatterlist sg_src;
 		if (!access_ok(VERIFY_WRITE, (void __user *)arg,
 				sizeof(struct qcedev_sha_op_req)))
 			return -EFAULT;
@@ -1907,17 +1913,20 @@
 		if (qcedev_check_sha_params(&qcedev_areq.sha_op_req, podev))
 			return -EINVAL;
 		qcedev_areq.op_type = QCEDEV_CRYPTO_OPER_SHA;
-		err = qcedev_hash_init(&qcedev_areq, handle);
+		err = qcedev_hash_init(&qcedev_areq, handle, &sg_src);
 		if (err)
 			return err;
 		if (__copy_to_user((void __user *)arg, &qcedev_areq.sha_op_req,
 					sizeof(struct qcedev_sha_op_req)))
 				return -EFAULT;
+		}
 		break;
 	case QCEDEV_IOCTL_GET_CMAC_REQ:
 		if (!podev->ce_support.cmac)
 			return -ENOTTY;
 	case QCEDEV_IOCTL_SHA_UPDATE_REQ:
+		{
+		struct scatterlist sg_src;
 		if (!access_ok(VERIFY_WRITE, (void __user *)arg,
 				sizeof(struct qcedev_sha_op_req)))
 			return -EFAULT;
@@ -1931,11 +1940,11 @@
 		qcedev_areq.op_type = QCEDEV_CRYPTO_OPER_SHA;
 
 		if (qcedev_areq.sha_op_req.alg == QCEDEV_ALG_AES_CMAC) {
-			err = qcedev_hash_cmac(&qcedev_areq, handle);
+			err = qcedev_hash_cmac(&qcedev_areq, handle, &sg_src);
 			if (err)
 				return err;
 		} else {
-			err = qcedev_hash_update(&qcedev_areq, handle);
+			err = qcedev_hash_update(&qcedev_areq, handle, &sg_src);
 			if (err)
 				return err;
 		}
@@ -1946,6 +1955,7 @@
 		if (__copy_to_user((void __user *)arg, &qcedev_areq.sha_op_req,
 					sizeof(struct qcedev_sha_op_req)))
 			return -EFAULT;
+		}
 		break;
 
 	case QCEDEV_IOCTL_SHA_FINAL_REQ:
@@ -1974,7 +1984,8 @@
 		break;
 
 	case QCEDEV_IOCTL_GET_SHA_REQ:
-
+		{
+		struct scatterlist sg_src;
 		if (!access_ok(VERIFY_WRITE, (void __user *)arg,
 				sizeof(struct qcedev_sha_op_req)))
 			return -EFAULT;
@@ -1986,8 +1997,8 @@
 		if (qcedev_check_sha_params(&qcedev_areq.sha_op_req, podev))
 			return -EINVAL;
 		qcedev_areq.op_type = QCEDEV_CRYPTO_OPER_SHA;
-		qcedev_hash_init(&qcedev_areq, handle);
-		err = qcedev_hash_update(&qcedev_areq, handle);
+		qcedev_hash_init(&qcedev_areq, handle, &sg_src);
+		err = qcedev_hash_update(&qcedev_areq, handle, &sg_src);
 		if (err)
 			return err;
 		err = qcedev_hash_final(&qcedev_areq, handle);
@@ -2000,6 +2011,7 @@
 		if (__copy_to_user((void __user *)arg, &qcedev_areq.sha_op_req,
 					sizeof(struct qcedev_sha_op_req)))
 			return -EFAULT;
+		}
 		break;
 
 	default:
@@ -2126,6 +2138,10 @@
 	struct qcedev_stat *pstat;
 	int len = 0;
 
+	if (id < 0) {
+		pr_err("Crypto id is %d, cannot be negative\n", id);
+		return len;
+	}
 	pstat = &_qcedev_stat[id];
 	len = snprintf(_debug_read_buf, DEBUG_MAX_RW_BUF - 1,
 			"\nQualcomm QCE dev driver %d Statistics:\n",
diff --git a/drivers/crypto/msm/qcrypto.c b/drivers/crypto/msm/qcrypto.c
index 10f83f3..7e063ca 100644
--- a/drivers/crypto/msm/qcrypto.c
+++ b/drivers/crypto/msm/qcrypto.c
@@ -1,6 +1,6 @@
 /* Qualcomm Crypto driver
  *
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * 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
@@ -367,7 +367,17 @@
 	mutex_unlock(&sent_bw_req);
 }
 
-static void _start_qcrypto_process(struct crypto_priv *cp);
+static int _start_qcrypto_process(struct crypto_priv *cp);
+
+static int qcrypto_count_sg(struct scatterlist *sg, int nbytes)
+{
+	int i;
+
+	for (i = 0; nbytes > 0; i++, sg = scatterwalk_sg_next(sg))
+		nbytes -= sg->length;
+
+	return i;
+}
 
 static struct qcrypto_alg *_qcrypto_sha_alg_alloc(struct crypto_priv *cp,
 		struct ahash_alg *template)
@@ -545,6 +555,10 @@
 	struct crypto_stat *pstat;
 	int len = 0;
 
+	if (id < 0) {
+		pr_err("Crypto id is %d, cannot be negative\n", id);
+		return len;
+	}
 	pstat = &_qcrypto_stat[id];
 	len = snprintf(_debug_read_buf, DEBUG_MAX_RW_BUF - 1,
 			"\nQualcomm crypto accelerator %d Statistics:\n",
@@ -865,18 +879,19 @@
 
 	if (cp->ce_support.aligned_only)  {
 		struct qcrypto_cipher_req_ctx *rctx;
-		struct scatterlist *sg;
+		uint32_t num_sg = 0;
 		uint32_t bytes = 0;
 
 		rctx = ablkcipher_request_ctx(areq);
 		areq->src = rctx->orig_src;
 		areq->dst = rctx->orig_dst;
 
-		for (sg = areq->dst; bytes != areq->nbytes; sg++) {
-			memcpy(sg_virt(sg), ((char *)rctx->data + bytes),
-								sg->length);
-			bytes += sg->length;
-		}
+		num_sg = qcrypto_count_sg(areq->dst, areq->nbytes);
+		bytes = sg_copy_from_buffer(areq->dst, num_sg,
+			rctx->data, areq->nbytes);
+		if (bytes != areq->nbytes)
+			pr_warn("bytes copied=0x%x bytes to copy= 0x%x", bytes,
+								areq->nbytes);
 		kfree(rctx->data);
 	}
 
@@ -903,9 +918,9 @@
 	if (rctx->mode == QCE_MODE_CCM) {
 		if (cp->ce_support.aligned_only)  {
 			struct qcrypto_cipher_req_ctx *rctx;
-			struct scatterlist *sg;
 			uint32_t bytes = 0;
 			uint32_t nbytes = 0;
+			uint32_t num_sg = 0;
 
 			rctx = aead_request_ctx(areq);
 			areq->src = rctx->orig_src;
@@ -916,13 +931,13 @@
 			else
 				nbytes = areq->cryptlen -
 						crypto_aead_authsize(aead);
-
-			for (sg = areq->dst; bytes != nbytes; sg++) {
-				memcpy(sg_virt(sg),
-				((char *)rctx->data + areq->assoclen + bytes),
-								sg->length);
-				bytes += sg->length;
-			}
+			num_sg = qcrypto_count_sg(areq->dst, nbytes);
+			bytes = sg_copy_from_buffer(areq->dst, num_sg,
+					((char *)rctx->data + areq->assoclen),
+					nbytes);
+			if (bytes != nbytes)
+				pr_warn("bytes copied=0x%x bytes to copy= 0x%x",
+						bytes, nbytes);
 			kfree(rctx->data);
 		}
 		kzfree(rctx->assoc);
@@ -1014,7 +1029,9 @@
 						struct scatterlist *sg)
 {
 	unsigned char *adata;
-	uint32_t len, l;
+	uint32_t len;
+	uint32_t bytes = 0;
+	uint32_t num_sg = 0;
 
 	qreq->assoc = kzalloc((alen + 0x64), (GFP_KERNEL | __GFP_DMA));
 	if (!qreq->assoc) {
@@ -1043,11 +1060,12 @@
 	}
 	adata += len;
 	qreq->assoclen = ALIGN((alen + len), 16);
-	for (l = alen; l > 0; sg = sg_next(sg)) {
-		memcpy(adata, sg_virt(sg), sg->length);
-		l -= sg->length;
-		adata += sg->length;
-	}
+
+	num_sg = qcrypto_count_sg(sg, alen);
+	bytes = sg_copy_to_buffer(sg, num_sg, adata, alen);
+	if (bytes != alen)
+		pr_warn("bytes copied=0x%x bytes to copy= 0x%x", bytes, alen);
+
 	return 0;
 }
 
@@ -1067,23 +1085,29 @@
 	tfm = crypto_ablkcipher_reqtfm(req);
 	if (cp->ce_support.aligned_only) {
 		uint32_t bytes = 0;
-		struct scatterlist *sg = req->src;
+		uint32_t num_sg = 0;
 
 		rctx->orig_src = req->src;
 		rctx->orig_dst = req->dst;
 		rctx->data = kzalloc((req->nbytes + 64), GFP_KERNEL);
-		for (sg = req->src; bytes != req->nbytes; sg++) {
-			memcpy(((char *)rctx->data + bytes),
-					sg_virt(sg), sg->length);
-			bytes += sg->length;
+
+		if (rctx->data == NULL) {
+			pr_err("Mem Alloc fail rctx->data, err %ld for 0x%x\n",
+				PTR_ERR(rctx->data), (req->nbytes + 64));
+			return -ENOMEM;
 		}
+		num_sg = qcrypto_count_sg(req->src, req->nbytes);
+		bytes = sg_copy_to_buffer(req->src, num_sg, rctx->data,
+								req->nbytes);
+		if (bytes != req->nbytes)
+			pr_warn("bytes copied=0x%x bytes to copy= 0x%x", bytes,
+								req->nbytes);
 		sg_set_buf(&rctx->dsg, rctx->data, req->nbytes);
 		sg_mark_end(&rctx->dsg);
 		rctx->iv = req->info;
 
 		req->src = &rctx->dsg;
 		req->dst = &rctx->dsg;
-
 	}
 	qreq.op = QCE_REQ_ABLK_CIPHER;
 	qreq.qce_cb = _qce_ablk_cipher_complete;
@@ -1207,20 +1231,26 @@
 
 		if (cp->ce_support.aligned_only) {
 			uint32_t bytes = 0;
-			struct scatterlist *sg = req->src;
+			uint32_t num_sg = 0;
 
 			rctx->orig_src = req->src;
 			rctx->orig_dst = req->dst;
 			rctx->data = kzalloc((req->cryptlen + qreq.assoclen +
 					qreq.authsize + 64*2), GFP_KERNEL);
+			if (rctx->data == NULL) {
+				pr_err("Mem Alloc fail rctx->data, err %ld\n",
+							PTR_ERR(rctx->data));
+				return -ENOMEM;
+			}
 
 			memcpy((char *)rctx->data, qreq.assoc, qreq.assoclen);
 
-			for (sg = req->src; bytes != req->cryptlen; sg++) {
-				memcpy((rctx->data + bytes + qreq.assoclen),
-						sg_virt(sg), sg->length);
-				bytes += sg->length;
-			}
+			num_sg = qcrypto_count_sg(req->src, req->cryptlen);
+			bytes = sg_copy_to_buffer(req->src, num_sg,
+				rctx->data + qreq.assoclen , req->cryptlen);
+			if (bytes != req->cryptlen)
+				pr_warn("bytes copied=0x%x bytes to copy= 0x%x",
+							bytes, req->cryptlen);
 			sg_set_buf(&rctx->ssg, rctx->data, req->cryptlen +
 							qreq.assoclen);
 			sg_mark_end(&rctx->ssg);
@@ -1260,13 +1290,13 @@
 	return ret;
 }
 
-static void _start_qcrypto_process(struct crypto_priv *cp)
+static int _start_qcrypto_process(struct crypto_priv *cp)
 {
 	struct crypto_async_request *async_req = NULL;
 	struct crypto_async_request *backlog = NULL;
 	unsigned long flags;
 	u32 type;
-	int ret;
+	int ret = 0;
 	struct crypto_stat *pstat;
 
 	pstat = &_qcrypto_stat[cp->pdev->id];
@@ -1280,7 +1310,7 @@
 	}
 	spin_unlock_irqrestore(&cp->lock, flags);
 	if (!async_req)
-		return;
+		return ret;
 	if (backlog)
 		backlog->complete(backlog, -EINPROGRESS);
 	type = crypto_tfm_alg_type(async_req->tfm);
@@ -1315,6 +1345,7 @@
 		async_req->complete(async_req, ret);
 		goto again;
 	};
+	return ret;
 };
 
 static int _qcrypto_queue_req(struct crypto_priv *cp,
@@ -2114,16 +2145,6 @@
 	return _qcrypto_queue_req(cp, &areq->base);
 }
 
-static int qcrypto_count_sg(struct scatterlist *sg, int nbytes)
-{
-	int i;
-
-	for (i = 0; nbytes > 0; i++, sg = sg_next(sg))
-		nbytes -= sg->length;
-
-	return i;
-}
-
 static int _sha_init(struct qcrypto_sha_ctx *ctx)
 {
 	ctx->first_blk = 1;
@@ -2259,25 +2280,32 @@
 	return 0;
 }
 
-static void _copy_source(struct ahash_request  *req)
+static int _copy_source(struct ahash_request  *req)
 {
 	struct qcrypto_sha_req_ctx *srctx = NULL;
 	uint32_t bytes = 0;
-	struct scatterlist *sg = req->src;
+	uint32_t num_sg = 0;
 
 	srctx = ahash_request_ctx(req);
 	srctx->orig_src = req->src;
 	srctx->data = kzalloc((req->nbytes + 64), GFP_KERNEL);
-	for (sg = req->src; bytes != req->nbytes;
-						sg++) {
-		memcpy(((char *)srctx->data + bytes),
-			sg_virt(sg), sg->length);
-		bytes += sg->length;
+	if (srctx->data == NULL) {
+		pr_err("Mem Alloc fail rctx->data, err %ld for 0x%x\n",
+				PTR_ERR(srctx->data), (req->nbytes + 64));
+		return -ENOMEM;
 	}
+
+	num_sg = qcrypto_count_sg(req->src, req->nbytes);
+	bytes = sg_copy_to_buffer(req->src, num_sg, srctx->data, req->nbytes);
+	if (bytes != req->nbytes)
+		pr_warn("bytes copied=0x%x bytes to copy= 0x%x", bytes,
+							req->nbytes);
 	sg_set_buf(&srctx->dsg, srctx->data,
 				req->nbytes);
 	sg_mark_end(&srctx->dsg);
 	req->src = &srctx->dsg;
+
+	return 0;
 }
 
 static int _sha_update(struct ahash_request  *req, uint32_t sha_block_size)
@@ -2285,13 +2313,15 @@
 	struct qcrypto_sha_ctx *sha_ctx = crypto_tfm_ctx(req->base.tfm);
 	struct crypto_priv *cp = sha_ctx->cp;
 	struct qcrypto_sha_req_ctx *rctx = ahash_request_ctx(req);
-	uint32_t total, len, i, num_sg;
+	uint32_t total, len, num_sg;
+	struct scatterlist *sg_last;
 	uint8_t *k_src = NULL;
 	uint32_t sha_pad_len = 0;
-	uint32_t end_src = 0;
 	uint32_t trailing_buf_len = 0;
-	uint32_t nbytes, index = 0;
-	uint32_t saved_length = 0;
+	uint32_t nbytes;
+	uint32_t offset = 0;
+	uint32_t bytes = 0;
+
 	int ret = 0;
 
 	/* check for trailing buffer from previous updates and append it */
@@ -2299,16 +2329,10 @@
 	len = req->nbytes;
 
 	if (total <= sha_block_size) {
-		i = 0;
-
 		k_src = &sha_ctx->trailing_buf[sha_ctx->trailing_buf_len];
-		while (len > 0) {
-			memcpy(k_src, sg_virt(&req->src[i]),
-							req->src[i].length);
-			len -= req->src[i].length;
-			k_src += req->src[i].length;
-			i++;
-		}
+		num_sg = qcrypto_count_sg(req->src, len);
+		bytes = sg_copy_to_buffer(req->src, num_sg, k_src, len);
+
 		sha_ctx->trailing_buf_len = total;
 		if (sha_ctx->alg == QCE_HASH_SHA1)
 			_update_sha1_ctx(req);
@@ -2327,37 +2351,24 @@
 	/*  get new trailing buffer */
 	sha_pad_len = ALIGN(total, sha_block_size) - total;
 	trailing_buf_len =  sha_block_size - sha_pad_len;
+	offset = req->nbytes - trailing_buf_len;
+
+	if (offset != req->nbytes)
+		scatterwalk_map_and_copy(k_src, req->src, offset,
+						trailing_buf_len, 0);
+
 	nbytes = total - trailing_buf_len;
 	num_sg = qcrypto_count_sg(req->src, req->nbytes);
 
 	len = sha_ctx->trailing_buf_len;
-	i = 0;
+	sg_last = req->src;
 
 	while (len < nbytes) {
-		if ((len + req->src[i].length) > nbytes)
+		if ((len + sg_last->length) > nbytes)
 			break;
-		len += req->src[i].length;
-		i++;
+		len += sg_last->length;
+		sg_last = scatterwalk_sg_next(sg_last);
 	}
-
-	end_src = i;
-	if (len < nbytes) {
-		uint32_t remnant = (nbytes - len);
-		memcpy(k_src, (sg_virt(&req->src[i]) + remnant),
-				(req->src[i].length - remnant));
-		k_src += (req->src[i].length - remnant);
-		saved_length = req->src[i].length;
-		index = i;
-		req->src[i].length = remnant;
-		i++;
-	}
-
-	while (i < num_sg) {
-		memcpy(k_src, sg_virt(&req->src[i]), req->src[i].length);
-		k_src += req->src[i].length;
-		i++;
-	}
-
 	if (sha_ctx->trailing_buf_len) {
 		if (cp->ce_support.aligned_only)  {
 			sha_ctx->sg = kzalloc(sizeof(struct scatterlist),
@@ -2377,20 +2388,18 @@
 			memcpy(rctx->data2, sha_ctx->tmp_tbuf,
 						sha_ctx->trailing_buf_len);
 			memcpy((rctx->data2 + sha_ctx->trailing_buf_len),
-					rctx->data, req->src[i-1].length);
+					rctx->data, req->src->length);
 			kfree(rctx->data);
 			rctx->data = rctx->data2;
 			sg_set_buf(&sha_ctx->sg[0], rctx->data,
 					(sha_ctx->trailing_buf_len +
-							req->src[i-1].length));
+							req->src->length));
 			req->src = sha_ctx->sg;
 			sg_mark_end(&sha_ctx->sg[0]);
-
 		} else {
-			num_sg = end_src + 2;
-
-			sha_ctx->sg = kzalloc(num_sg *
-				(sizeof(struct scatterlist)), GFP_KERNEL);
+			sg_mark_end(sg_last);
+			sha_ctx->sg = kzalloc(2 * (sizeof(struct scatterlist)),
+								GFP_KERNEL);
 			if (sha_ctx->sg == NULL) {
 				pr_err("MEMalloc fail sha_ctx->sg, error %ld\n",
 							PTR_ERR(sha_ctx->sg));
@@ -2399,21 +2408,14 @@
 
 			sg_set_buf(&sha_ctx->sg[0], sha_ctx->tmp_tbuf,
 						sha_ctx->trailing_buf_len);
-			for (i = 1; i < num_sg; i++)
-				sg_set_buf(&sha_ctx->sg[i],
-						sg_virt(&req->src[i-1]),
-						req->src[i-1].length);
-
+			sg_mark_end(&sha_ctx->sg[1]);
+			sg_chain(sha_ctx->sg, 2, req->src);
 			req->src = sha_ctx->sg;
-			sg_mark_end(&sha_ctx->sg[num_sg - 1]);
-
 		}
 	} else
-		sg_mark_end(&req->src[end_src]);
+		sg_mark_end(sg_last);
 
 	req->nbytes = nbytes;
-	if (saved_length > 0)
-		rctx->src[index].length = saved_length;
 	sha_ctx->trailing_buf_len = trailing_buf_len;
 
 	ret =  _qcrypto_queue_req(cp, &req->base);
@@ -2428,9 +2430,10 @@
 	struct qcrypto_sha_ctx *sha_ctx = crypto_tfm_ctx(req->base.tfm);
 	struct crypto_priv *cp = sha_ctx->cp;
 
-	if (cp->ce_support.aligned_only)
-		_copy_source(req);
-
+	if (cp->ce_support.aligned_only) {
+		if (_copy_source(req))
+			return -ENOMEM;
+	}
 	sha_state_ctx->count += req->nbytes;
 	return _sha_update(req, SHA1_BLOCK_SIZE);
 }
@@ -2442,8 +2445,10 @@
 	struct qcrypto_sha_ctx *sha_ctx = crypto_tfm_ctx(req->base.tfm);
 	struct crypto_priv *cp = sha_ctx->cp;
 
-	if (cp->ce_support.aligned_only)
-		_copy_source(req);
+	if (cp->ce_support.aligned_only) {
+		if (_copy_source(req))
+			return -ENOMEM;
+	}
 
 	sha_state_ctx->count += req->nbytes;
 	return _sha_update(req, SHA256_BLOCK_SIZE);
@@ -2456,8 +2461,10 @@
 	struct qcrypto_sha_req_ctx *rctx = ahash_request_ctx(req);
 	int ret = 0;
 
-	if (cp->ce_support.aligned_only)
-		_copy_source(req);
+	if (cp->ce_support.aligned_only) {
+		if (_copy_source(req))
+			return -ENOMEM;
+	}
 
 	sha_ctx->last_blk = 1;
 
@@ -2494,8 +2501,10 @@
 	struct crypto_priv *cp = sha_ctx->cp;
 	int ret = 0;
 
-	if (cp->ce_support.aligned_only)
-		_copy_source(req);
+	if (cp->ce_support.aligned_only) {
+		if (_copy_source(req))
+			return -ENOMEM;
+	}
 
 	/* save the original req structure fields*/
 	rctx->src = req->src;
diff --git a/drivers/crypto/msm/qcryptohw_30.h b/drivers/crypto/msm/qcryptohw_30.h
index edbee71..3c18ed2 100644
--- a/drivers/crypto/msm/qcryptohw_30.h
+++ b/drivers/crypto/msm/qcryptohw_30.h
@@ -1,4 +1,4 @@
-/* Copyright (c)2009- 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c)2009- 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
diff --git a/drivers/crypto/msm/qcryptohw_40.h b/drivers/crypto/msm/qcryptohw_40.h
index 367bdaa..f2102c6 100644
--- a/drivers/crypto/msm/qcryptohw_40.h
+++ b/drivers/crypto/msm/qcryptohw_40.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/crypto/msm/qcryptohw_50.h b/drivers/crypto/msm/qcryptohw_50.h
index d77311d..245d737 100644
--- a/drivers/crypto/msm/qcryptohw_50.h
+++ b/drivers/crypto/msm/qcryptohw_50.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -59,77 +59,78 @@
 #define CRYPTO_ENCR_XTS_KEY6_REG		0x1D038
 #define CRYPTO_ENCR_XTS_KEY7_REG		0x1D03C
 
-#define CRYPTO_ENCR_PIP0_KEY0_REG		0x1E000
-#define CRYPTO_ENCR_PIP0_KEY1_REG		0x1E004
-#define CRYPTO_ENCR_PIP0_KEY2_REG		0x1E008
-#define CRYPTO_ENCR_PIP0_KEY3_REG		0x1E00C
-#define CRYPTO_ENCR_PIP0_KEY4_REG		0x1E010
-#define CRYPTO_ENCR_PIP0_KEY5_REG		0x1E004
-#define CRYPTO_ENCR_PIP0_KEY6_REG		0x1E008
-#define CRYPTO_ENCR_PIP0_KEY7_REG		0x1E00C
+#define CRYPTO_ENCR_PIPE0_KEY0_REG		0x1E000
+#define CRYPTO_ENCR_PIPE0_KEY1_REG		0x1E004
+#define CRYPTO_ENCR_PIPE0_KEY2_REG		0x1E008
+#define CRYPTO_ENCR_PIPE0_KEY3_REG		0x1E00C
+#define CRYPTO_ENCR_PIPE0_KEY4_REG		0x1E010
+#define CRYPTO_ENCR_PIPE0_KEY5_REG		0x1E004
+#define CRYPTO_ENCR_PIPE0_KEY6_REG		0x1E008
+#define CRYPTO_ENCR_PIPE0_KEY7_REG		0x1E00C
 
-#define CRYPTO_ENCR_PIP1_KEY0_REG		0x1E000
-#define CRYPTO_ENCR_PIP1_KEY1_REG		0x1E004
-#define CRYPTO_ENCR_PIP1_KEY2_REG		0x1E008
-#define CRYPTO_ENCR_PIP1_KEY3_REG		0x1E00C
-#define CRYPTO_ENCR_PIP1_KEY4_REG		0x1E010
-#define CRYPTO_ENCR_PIP1_KEY5_REG		0x1E014
-#define CRYPTO_ENCR_PIP1_KEY6_REG		0x1E018
-#define CRYPTO_ENCR_PIP1_KEY7_REG		0x1E01C
+#define CRYPTO_ENCR_PIPE1_KEY0_REG		0x1E020
+#define CRYPTO_ENCR_PIPE1_KEY1_REG		0x1E024
+#define CRYPTO_ENCR_PIPE1_KEY2_REG		0x1E028
+#define CRYPTO_ENCR_PIPE1_KEY3_REG		0x1E02C
+#define CRYPTO_ENCR_PIPE1_KEY4_REG		0x1E030
+#define CRYPTO_ENCR_PIPE1_KEY5_REG		0x1E034
+#define CRYPTO_ENCR_PIPE1_KEY6_REG		0x1E038
+#define CRYPTO_ENCR_PIPE1_KEY7_REG		0x1E03C
 
-#define CRYPTO_ENCR_PIP2_KEY0_REG		0x1E020
-#define CRYPTO_ENCR_PIP2_KEY1_REG		0x1E024
-#define CRYPTO_ENCR_PIP2_KEY2_REG		0x1E028
-#define CRYPTO_ENCR_PIP2_KEY3_REG		0x1E02C
-#define CRYPTO_ENCR_PIP2_KEY4_REG		0x1E030
-#define CRYPTO_ENCR_PIP2_KEY5_REG		0x1E034
-#define CRYPTO_ENCR_PIP2_KEY6_REG		0x1E038
-#define CRYPTO_ENCR_PIP2_KEY7_REG		0x1E03C
+#define CRYPTO_ENCR_PIPE2_KEY0_REG		0x1E040
+#define CRYPTO_ENCR_PIPE2_KEY1_REG		0x1E044
+#define CRYPTO_ENCR_PIPE2_KEY2_REG		0x1E048
+#define CRYPTO_ENCR_PIPE2_KEY3_REG		0x1E04C
+#define CRYPTO_ENCR_PIPE2_KEY4_REG		0x1E050
+#define CRYPTO_ENCR_PIPE2_KEY5_REG		0x1E054
+#define CRYPTO_ENCR_PIPE2_KEY6_REG		0x1E058
+#define CRYPTO_ENCR_PIPE2_KEY7_REG		0x1E05C
 
-#define CRYPTO_ENCR_PIP3_KEY0_REG		0x1E040
-#define CRYPTO_ENCR_PIP3_KEY1_REG		0x1E044
-#define CRYPTO_ENCR_PIP3_KEY2_REG		0x1E048
-#define CRYPTO_ENCR_PIP3_KEY3_REG		0x1E04C
-#define CRYPTO_ENCR_PIP3_KEY4_REG		0x1E050
-#define CRYPTO_ENCR_PIP3_KEY5_REG		0x1E054
-#define CRYPTO_ENCR_PIP3_KEY6_REG		0x1E058
-#define CRYPTO_ENCR_PIP3_KEY7_REG		0x1E05C
+#define CRYPTO_ENCR_PIPE3_KEY0_REG		0x1E060
+#define CRYPTO_ENCR_PIPE3_KEY1_REG		0x1E064
+#define CRYPTO_ENCR_PIPE3_KEY2_REG		0x1E068
+#define CRYPTO_ENCR_PIPE3_KEY3_REG		0x1E06C
+#define CRYPTO_ENCR_PIPE3_KEY4_REG		0x1E070
+#define CRYPTO_ENCR_PIPE3_KEY5_REG		0x1E074
+#define CRYPTO_ENCR_PIPE3_KEY6_REG		0x1E078
+#define CRYPTO_ENCR_PIPE3_KEY7_REG		0x1E07C
 
-#define CRYPTO_ENCR_PIP0_XTS_KEY0_REG		0x1E200
-#define CRYPTO_ENCR_PIP0_XTS_KEY1_REG		0x1E204
-#define CRYPTO_ENCR_PIP0_XTS_KEY2_REG		0x1E208
-#define CRYPTO_ENCR_PIP0_XTS_KEY3_REG		0x1E20C
-#define CRYPTO_ENCR_PIP0_XTS_KEY4_REG		0x1E210
-#define CRYPTO_ENCR_PIP0_XTS_KEY5_REG		0x1E214
-#define CRYPTO_ENCR_PIP0_XTS_KEY6_REG		0x1E218
-#define CRYPTO_ENCR_PIP0_XTS_KEY7_REG		0x1E21C
 
-#define CRYPTO_ENCR_PIP1_XTS_KEY0_REG		0x1E220
-#define CRYPTO_ENCR_PIP1_XTS_KEY1_REG		0x1E224
-#define CRYPTO_ENCR_PIP1_XTS_KEY2_REG		0x1E228
-#define CRYPTO_ENCR_PIP1_XTS_KEY3_REG		0x1E22C
-#define CRYPTO_ENCR_PIP1_XTS_KEY4_REG		0x1E230
-#define CRYPTO_ENCR_PIP1_XTS_KEY5_REG		0x1E234
-#define CRYPTO_ENCR_PIP1_XTS_KEY6_REG		0x1E238
-#define CRYPTO_ENCR_PIP1_XTS_KEY7_REG		0x1E23C
+#define CRYPTO_ENCR_PIPE0_XTS_KEY0_REG		0x1E200
+#define CRYPTO_ENCR_PIPE0_XTS_KEY1_REG		0x1E204
+#define CRYPTO_ENCR_PIPE0_XTS_KEY2_REG		0x1E208
+#define CRYPTO_ENCR_PIPE0_XTS_KEY3_REG		0x1E20C
+#define CRYPTO_ENCR_PIPE0_XTS_KEY4_REG		0x1E210
+#define CRYPTO_ENCR_PIPE0_XTS_KEY5_REG		0x1E214
+#define CRYPTO_ENCR_PIPE0_XTS_KEY6_REG		0x1E218
+#define CRYPTO_ENCR_PIPE0_XTS_KEY7_REG		0x1E21C
 
-#define CRYPTO_ENCR_PIP2_XTS_KEY0_REG		0x1E240
-#define CRYPTO_ENCR_PIP2_XTS_KEY1_REG		0x1E244
-#define CRYPTO_ENCR_PIP2_XTS_KEY2_REG		0x1E248
-#define CRYPTO_ENCR_PIP2_XTS_KEY3_REG		0x1E24C
-#define CRYPTO_ENCR_PIP2_XTS_KEY4_REG		0x1E250
-#define CRYPTO_ENCR_PIP2_XTS_KEY5_REG		0x1E254
-#define CRYPTO_ENCR_PIP2_XTS_KEY6_REG		0x1E258
-#define CRYPTO_ENCR_PIP2_XTS_KEY7_REG		0x1E25C
+#define CRYPTO_ENCR_PIPE1_XTS_KEY0_REG		0x1E220
+#define CRYPTO_ENCR_PIPE1_XTS_KEY1_REG		0x1E224
+#define CRYPTO_ENCR_PIPE1_XTS_KEY2_REG		0x1E228
+#define CRYPTO_ENCR_PIPE1_XTS_KEY3_REG		0x1E22C
+#define CRYPTO_ENCR_PIPE1_XTS_KEY4_REG		0x1E230
+#define CRYPTO_ENCR_PIPE1_XTS_KEY5_REG		0x1E234
+#define CRYPTO_ENCR_PIPE1_XTS_KEY6_REG		0x1E238
+#define CRYPTO_ENCR_PIPE1_XTS_KEY7_REG		0x1E23C
 
-#define CRYPTO_ENCR_PIP3_XTS_KEY0_REG		0x1E260
-#define CRYPTO_ENCR_PIP3_XTS_KEY1_REG		0x1E264
-#define CRYPTO_ENCR_PIP3_XTS_KEY2_REG		0x1E268
-#define CRYPTO_ENCR_PIP3_XTS_KEY3_REG		0x1E26C
-#define CRYPTO_ENCR_PIP3_XTS_KEY4_REG		0x1E270
-#define CRYPTO_ENCR_PIP3_XTS_KEY5_REG		0x1E274
-#define CRYPTO_ENCR_PIP3_XTS_KEY6_REG		0x1E278
-#define CRYPTO_ENCR_PIP3_XTS_KEY7_REG		0x1E27C
+#define CRYPTO_ENCR_PIPE2_XTS_KEY0_REG		0x1E240
+#define CRYPTO_ENCR_PIPE2_XTS_KEY1_REG		0x1E244
+#define CRYPTO_ENCR_PIPE2_XTS_KEY2_REG		0x1E248
+#define CRYPTO_ENCR_PIPE2_XTS_KEY3_REG		0x1E24C
+#define CRYPTO_ENCR_PIPE2_XTS_KEY4_REG		0x1E250
+#define CRYPTO_ENCR_PIPE2_XTS_KEY5_REG		0x1E254
+#define CRYPTO_ENCR_PIPE2_XTS_KEY6_REG		0x1E258
+#define CRYPTO_ENCR_PIPE2_XTS_KEY7_REG		0x1E25C
+
+#define CRYPTO_ENCR_PIPE3_XTS_KEY0_REG		0x1E260
+#define CRYPTO_ENCR_PIPE3_XTS_KEY1_REG		0x1E264
+#define CRYPTO_ENCR_PIPE3_XTS_KEY2_REG		0x1E268
+#define CRYPTO_ENCR_PIPE3_XTS_KEY3_REG		0x1E26C
+#define CRYPTO_ENCR_PIPE3_XTS_KEY4_REG		0x1E270
+#define CRYPTO_ENCR_PIPE3_XTS_KEY5_REG		0x1E274
+#define CRYPTO_ENCR_PIPE3_XTS_KEY6_REG		0x1E278
+#define CRYPTO_ENCR_PIPE3_XTS_KEY7_REG		0x1E27C
 
 
 #define CRYPTO_CNTR0_IV0_REG			0x1A20C
diff --git a/drivers/gpio/gpio-fsm9xxx.c b/drivers/gpio/gpio-fsm9xxx.c
index ad7e1fd..496e97e 100644
--- a/drivers/gpio/gpio-fsm9xxx.c
+++ b/drivers/gpio/gpio-fsm9xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/gpio/gpio-msm-common.c b/drivers/gpio/gpio-msm-common.c
index 150c434..05b2e0d 100644
--- a/drivers/gpio/gpio-msm-common.c
+++ b/drivers/gpio/gpio-msm-common.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -24,6 +24,7 @@
 #include <linux/of.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <asm/mach/irq.h>
 
@@ -48,7 +49,7 @@
 };
 #endif
 
-static int tlmm_msm_summary_irq;
+static int tlmm_msm_summary_irq, nr_direct_connect_irqs;
 
 struct tlmm_field_cfg {
 	enum msm_tlmm_register reg;
@@ -117,9 +118,9 @@
  */
 struct msm_gpio_dev {
 	struct gpio_chip gpio_chip;
-	DECLARE_BITMAP(enabled_irqs, NR_MSM_GPIOS);
-	DECLARE_BITMAP(wake_irqs, NR_MSM_GPIOS);
-	DECLARE_BITMAP(dual_edge_irqs, NR_MSM_GPIOS);
+	unsigned long *enabled_irqs;
+	unsigned long *wake_irqs;
+	unsigned long *dual_edge_irqs;
 	struct irq_domain *domain;
 };
 
@@ -207,7 +208,6 @@
 	.gpio_chip = {
 		.label		  = "msmgpio",
 		.base             = 0,
-		.ngpio            = NR_MSM_GPIOS,
 		.direction_input  = msm_gpio_direction_input,
 		.direction_output = msm_gpio_direction_output,
 		.get              = msm_gpio_get,
@@ -345,8 +345,10 @@
 	mb();
 	spin_unlock_irqrestore(&tlmm_lock, irq_flags);
 
-	if (msm_gpio_irq_extn.irq_set_type)
-		msm_gpio_irq_extn.irq_set_type(d, flow_type);
+	if ((flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH) {
+		if (msm_gpio_irq_extn.irq_set_type)
+			msm_gpio_irq_extn.irq_set_type(d, flow_type);
+	}
 
 	return 0;
 }
@@ -362,12 +364,13 @@
 	unsigned long i;
 	struct irq_desc *desc = irq_to_desc(irq);
 	struct irq_chip *chip = irq_desc_get_chip(desc);
+	int ngpio = msm_gpio.gpio_chip.ngpio;
 
 	chained_irq_enter(chip, desc);
 
-	for (i = find_first_bit(msm_gpio.enabled_irqs, NR_MSM_GPIOS);
-	     i < NR_MSM_GPIOS;
-	     i = find_next_bit(msm_gpio.enabled_irqs, NR_MSM_GPIOS, i + 1)) {
+	for (i = find_first_bit(msm_gpio.enabled_irqs, ngpio);
+	     i < ngpio;
+	     i = find_next_bit(msm_gpio.enabled_irqs, ngpio, i + 1)) {
 		if (__msm_gpio_get_intr_status(i))
 			generic_handle_irq(msm_gpio_to_irq(&msm_gpio.gpio_chip,
 							   i));
@@ -380,14 +383,15 @@
 static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
 {
 	int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq);
+	int ngpio = msm_gpio.gpio_chip.ngpio;
 
 	if (on) {
-		if (bitmap_empty(msm_gpio.wake_irqs, NR_MSM_GPIOS))
+		if (bitmap_empty(msm_gpio.wake_irqs, ngpio))
 			irq_set_irq_wake(tlmm_msm_summary_irq, 1);
 		set_bit(gpio, msm_gpio.wake_irqs);
 	} else {
 		clear_bit(gpio, msm_gpio.wake_irqs);
-		if (bitmap_empty(msm_gpio.wake_irqs, NR_MSM_GPIOS))
+		if (bitmap_empty(msm_gpio.wake_irqs, ngpio))
 			irq_set_irq_wake(tlmm_msm_summary_irq, 0);
 	}
 
@@ -412,12 +416,13 @@
 {
 	unsigned long irq_flags;
 	unsigned long i;
+	int ngpio = msm_gpio.gpio_chip.ngpio;
 
 	spin_lock_irqsave(&tlmm_lock, irq_flags);
-	for_each_set_bit(i, msm_gpio.enabled_irqs, NR_MSM_GPIOS)
+	for_each_set_bit(i, msm_gpio.enabled_irqs, ngpio)
 		__msm_gpio_set_intr_cfg_enable(i, 0);
 
-	for_each_set_bit(i, msm_gpio.wake_irqs, NR_MSM_GPIOS)
+	for_each_set_bit(i, msm_gpio.wake_irqs, ngpio)
 		__msm_gpio_set_intr_cfg_enable(i, 1);
 	mb();
 	spin_unlock_irqrestore(&tlmm_lock, irq_flags);
@@ -428,12 +433,13 @@
 {
 	unsigned long irq_flags;
 	int i, irq, intstat;
+	int ngpio = msm_gpio.gpio_chip.ngpio;
 
 	if (!msm_show_resume_irq_mask)
 		return;
 
 	spin_lock_irqsave(&tlmm_lock, irq_flags);
-	for_each_set_bit(i, msm_gpio.wake_irqs, NR_MSM_GPIOS) {
+	for_each_set_bit(i, msm_gpio.wake_irqs, ngpio) {
 		intstat = __msm_gpio_get_intr_status(i);
 		if (intstat) {
 			irq = msm_gpio_to_irq(&msm_gpio.gpio_chip, i);
@@ -448,14 +454,15 @@
 {
 	unsigned long irq_flags;
 	unsigned long i;
+	int ngpio = msm_gpio.gpio_chip.ngpio;
 
 	msm_gpio_show_resume_irq();
 
 	spin_lock_irqsave(&tlmm_lock, irq_flags);
-	for_each_set_bit(i, msm_gpio.wake_irqs, NR_MSM_GPIOS)
+	for_each_set_bit(i, msm_gpio.wake_irqs, ngpio)
 		__msm_gpio_set_intr_cfg_enable(i, 0);
 
-	for_each_set_bit(i, msm_gpio.enabled_irqs, NR_MSM_GPIOS)
+	for_each_set_bit(i, msm_gpio.enabled_irqs, ngpio)
 		__msm_gpio_set_intr_cfg_enable(i, 1);
 	mb();
 	spin_unlock_irqrestore(&tlmm_lock, irq_flags);
@@ -502,8 +509,9 @@
 int gpio_tlmm_config(unsigned config, unsigned disable)
 {
 	unsigned gpio = GPIO_PIN(config);
+	int ngpio = msm_gpio.gpio_chip.ngpio;
 
-	if (gpio > NR_MSM_GPIOS)
+	if (gpio > ngpio)
 		return -EINVAL;
 
 	__gpio_tlmm_config(config);
@@ -517,8 +525,9 @@
 					unsigned int input_polarity)
 {
 	unsigned long irq_flags;
+	int ngpio = msm_gpio.gpio_chip.ngpio;
 
-	if (gpio >= NR_MSM_GPIOS || irq >= NR_TLMM_MSM_DIR_CONN_IRQ)
+	if (gpio >= ngpio || irq >= nr_direct_connect_irqs)
 		return -EINVAL;
 
 	spin_lock_irqsave(&tlmm_lock, irq_flags);
@@ -536,37 +545,89 @@
  */
 static struct lock_class_key msm_gpio_lock_class;
 
+static inline void msm_gpio_set_irq_handler(struct device *dev)
+{
+	int irq, i;
+
+	if (!dev->of_node) {
+		for (i = 0; i < msm_gpio.gpio_chip.ngpio; ++i) {
+			irq = msm_gpio_to_irq(&msm_gpio.gpio_chip, i);
+			irq_set_lockdep_class(irq, &msm_gpio_lock_class);
+			irq_set_chip_and_handler(irq, &msm_gpio_irq_chip,
+						 handle_level_irq);
+			set_irq_flags(irq, IRQF_VALID);
+		}
+	}
+}
+
 static int __devinit msm_gpio_probe(struct platform_device *pdev)
 {
-	int ret;
-#ifndef CONFIG_OF
-	int irq, i;
-#endif
+	int ret, ngpio = 0;
+	struct msm_gpio_pdata *pdata = pdev->dev.platform_data;
+
+	if (pdev->dev.of_node) {
+		ret = of_property_read_u32(pdev->dev.of_node, "ngpio", &ngpio);
+		if (ret) {
+			pr_err("%s: Failed to find ngpio property\n", __func__);
+			return ret;
+		}
+		ret = of_property_read_u32(pdev->dev.of_node,
+					"qcom,direct-connect-irqs",
+					&nr_direct_connect_irqs);
+		if (ret) {
+			pr_err("%s: Failed to find qcom,direct-connect-irqs property\n"
+				, __func__);
+			return ret;
+		}
+	} else {
+		ngpio = pdata->ngpio;
+		nr_direct_connect_irqs = pdata->direct_connect_irqs;
+	}
+
 	tlmm_msm_summary_irq = platform_get_irq(pdev, 0);
 	if (tlmm_msm_summary_irq < 0) {
 		pr_err("%s: No interrupt defined for msmgpio\n", __func__);
 		return -ENXIO;
 	}
+
 	msm_gpio.gpio_chip.dev = &pdev->dev;
+	msm_gpio.gpio_chip.ngpio = ngpio;
 	spin_lock_init(&tlmm_lock);
-	bitmap_zero(msm_gpio.enabled_irqs, NR_MSM_GPIOS);
-	bitmap_zero(msm_gpio.wake_irqs, NR_MSM_GPIOS);
-	bitmap_zero(msm_gpio.dual_edge_irqs, NR_MSM_GPIOS);
+	msm_gpio.enabled_irqs = devm_kzalloc(&pdev->dev, sizeof(unsigned long)
+					* BITS_TO_LONGS(ngpio), GFP_KERNEL);
+	if (!msm_gpio.enabled_irqs) {
+		dev_err(&pdev->dev, "%s failed to allocated enabled_irqs bitmap\n"
+				, __func__);
+		return -ENOMEM;
+	}
+
+	msm_gpio.wake_irqs = devm_kzalloc(&pdev->dev, sizeof(unsigned long) *
+					BITS_TO_LONGS(ngpio), GFP_KERNEL);
+	if (!msm_gpio.wake_irqs) {
+		dev_err(&pdev->dev, "%s failed to allocated wake_irqs bitmap\n"
+				, __func__);
+		return -ENOMEM;
+	}
+	msm_gpio.dual_edge_irqs = devm_kzalloc(&pdev->dev, sizeof(unsigned long)
+					* BITS_TO_LONGS(ngpio), GFP_KERNEL);
+	if (!msm_gpio.dual_edge_irqs) {
+		dev_err(&pdev->dev, "%s failed to allocated dual_edge_irqs bitmap\n"
+				, __func__);
+		return -ENOMEM;
+	}
+
+	bitmap_zero(msm_gpio.enabled_irqs, ngpio);
+	bitmap_zero(msm_gpio.wake_irqs, ngpio);
+	bitmap_zero(msm_gpio.dual_edge_irqs, ngpio);
 	ret = gpiochip_add(&msm_gpio.gpio_chip);
 	if (ret < 0)
 		return ret;
 
-#ifndef CONFIG_OF
-	for (i = 0; i < msm_gpio.gpio_chip.ngpio; ++i) {
-		irq = msm_gpio_to_irq(&msm_gpio.gpio_chip, i);
-		irq_set_lockdep_class(irq, &msm_gpio_lock_class);
-		irq_set_chip_and_handler(irq, &msm_gpio_irq_chip,
-					 handle_level_irq);
-		set_irq_flags(irq, IRQF_VALID);
-	}
-#endif
-	ret = request_irq(tlmm_msm_summary_irq, msm_summary_irq_handler,
-			IRQF_TRIGGER_HIGH, "msmgpio", NULL);
+	msm_gpio_set_irq_handler(&pdev->dev);
+
+	ret = devm_request_irq(&pdev->dev, tlmm_msm_summary_irq,
+			msm_summary_irq_handler, IRQF_TRIGGER_HIGH,
+			"msmgpio", NULL);
 	if (ret) {
 		pr_err("Request_irq failed for tlmm_msm_summary_irq - %d\n",
 				ret);
@@ -658,7 +719,14 @@
 int __init msm_gpio_of_init(struct device_node *node,
 			    struct device_node *parent)
 {
-	msm_gpio.domain = irq_domain_add_linear(node, NR_MSM_GPIOS,
+	int ngpio, ret;
+
+	ret = of_property_read_u32(node, "ngpio", &ngpio);
+	if (ret) {
+		WARN(1, "Cannot get numgpios from device tree\n");
+		return ret;
+	}
+	msm_gpio.domain = irq_domain_add_linear(node, ngpio,
 			&msm_gpio_irq_domain_ops, &msm_gpio);
 	if (!msm_gpio.domain) {
 		WARN(1, "Cannot allocate irq_domain\n");
diff --git a/drivers/gpio/gpio-msm-common.h b/drivers/gpio/gpio-msm-common.h
index b1590ef..67c9569 100644
--- a/drivers/gpio/gpio-msm-common.h
+++ b/drivers/gpio/gpio-msm-common.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/gpio/gpio-msm-v1.c b/drivers/gpio/gpio-msm-v1.c
index 8718c9a..f28ebb4 100644
--- a/drivers/gpio/gpio-msm-v1.c
+++ b/drivers/gpio/gpio-msm-v1.c
@@ -1,7 +1,7 @@
 /* linux/arch/arm/mach-msm/gpio.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/gpio/gpio-msm-v2.c b/drivers/gpio/gpio-msm-v2.c
index 592391e..8c42bd6 100644
--- a/drivers/gpio/gpio-msm-v2.c
+++ b/drivers/gpio/gpio-msm-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/gpio/gpio-msm-v3.c b/drivers/gpio/gpio-msm-v3.c
index 1da276f..b395a4c 100644
--- a/drivers/gpio/gpio-msm-v3.c
+++ b/drivers/gpio/gpio-msm-v3.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/gpio/gpio-pm8xxx-rpc.c b/drivers/gpio/gpio-pm8xxx-rpc.c
index 1acc741..5cbbe26 100644
--- a/drivers/gpio/gpio-pm8xxx-rpc.c
+++ b/drivers/gpio/gpio-pm8xxx-rpc.c
@@ -1,7 +1,7 @@
 /*
  * Qualcomm PMIC8XXX GPIO driver based on RPC
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/drivers/gpio/gpio-sx150x.c b/drivers/gpio/gpio-sx150x.c
index 93b94bd..d24bd8f 100644
--- a/drivers/gpio/gpio-sx150x.c
+++ b/drivers/gpio/gpio-sx150x.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/gpio/pm8xxx-gpio.c b/drivers/gpio/pm8xxx-gpio.c
index cb874e8..a972714 100644
--- a/drivers/gpio/pm8xxx-gpio.c
+++ b/drivers/gpio/pm8xxx-gpio.c
@@ -1,7 +1,4 @@
-/*
- * Qualcomm PMIC8XXX GPIO driver
- *
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -85,9 +82,6 @@
 {
 	int	mode;
 
-	if (gpio >= pm_gpio_chip->gpio_chip.ngpio || pm_gpio_chip == NULL)
-		return -EINVAL;
-
 	/* Get gpio value from config bank 1 if output gpio.
 	   Get gpio value from IRQ RT status register for all other gpio modes.
 	 */
@@ -107,9 +101,6 @@
 	u8	bank1;
 	unsigned long flags;
 
-	if (gpio >= pm_gpio_chip->gpio_chip.ngpio || pm_gpio_chip == NULL)
-		return -EINVAL;
-
 	spin_lock_irqsave(&pm_gpio_chip->pm_lock, flags);
 	bank1 = PM_GPIO_WRITE
 			| (pm_gpio_chip->bank1[gpio] & ~PM_GPIO_OUT_INVERT);
diff --git a/drivers/gpio/pm8xxx-mpp.c b/drivers/gpio/pm8xxx-mpp.c
index affe980..9b2ac74 100644
--- a/drivers/gpio/pm8xxx-mpp.c
+++ b/drivers/gpio/pm8xxx-mpp.c
@@ -1,7 +1,7 @@
 /*
  * Qualcomm PM8XXX Multi-Purpose Pin (MPP) driver
  *
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/drivers/gpio/qpnp-pin.c b/drivers/gpio/qpnp-pin.c
index 527fd1b..f0c12f9 100644
--- a/drivers/gpio/qpnp-pin.c
+++ b/drivers/gpio/qpnp-pin.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c
index 82431dc..fa67ca2 100644
--- a/drivers/gpu/drm/drm_platform.c
+++ b/drivers/gpu/drm/drm_platform.c
@@ -3,7 +3,7 @@
  *
  * Copyright 2003 José Fonseca.
  * Copyright 2003 Leif Delgass.
- * Copyright (c) 2009, Code Aurora Forum.
+ * Copyright (c) 2009, The Linux Foundation.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
diff --git a/drivers/gpu/ion/Kconfig b/drivers/gpu/ion/Kconfig
index 5bb254b..39133b5 100644
--- a/drivers/gpu/ion/Kconfig
+++ b/drivers/gpu/ion/Kconfig
@@ -16,3 +16,12 @@
 	depends on ARCH_MSM && ION
 	help
 	  Choose this option if you wish to use ion on an MSM target.
+
+config ION_LEAK_CHECK
+	bool "Check for leaked Ion buffers (debugging)"
+	depends on ION
+	help
+	  Choose this option if you wish to enable checking for leaked
+	  ion buffers at runtime. Choosing this option will also add a
+	  debugfs node under the ion directory that can be used to
+	  enable/disable the leak checking.
diff --git a/drivers/gpu/ion/Makefile b/drivers/gpu/ion/Makefile
index 51349f6..60a6b81 100644
--- a/drivers/gpu/ion/Makefile
+++ b/drivers/gpu/ion/Makefile
@@ -1,4 +1,4 @@
 obj-$(CONFIG_ION) +=	ion.o ion_heap.o ion_system_heap.o ion_carveout_heap.o ion_iommu_heap.o ion_cp_heap.o
-obj-$(CONFIG_CMA) += ion_cma_heap.o
+obj-$(CONFIG_CMA) += ion_cma_heap.o ion_cma_secure_heap.o
 obj-$(CONFIG_ION_TEGRA) += tegra/
 obj-$(CONFIG_ION_MSM) += msm/
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index b3df752..0904f9fe 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -2,7 +2,7 @@
  * drivers/gpu/ion/ion.c
  *
  * Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -34,6 +34,8 @@
 #include <linux/debugfs.h>
 #include <linux/dma-buf.h>
 #include <linux/msm_ion.h>
+#include <trace/events/kmem.h>
+
 
 #include <mach/iommu_domains.h>
 #include "ion_priv.h"
@@ -438,11 +440,18 @@
 			continue;
 		/* Do not allow un-secure heap if secure is specified */
 		if (secure_allocation &&
-			(heap->type != (enum ion_heap_type) ION_HEAP_TYPE_CP))
+		    !ion_heap_allow_secure_allocation(heap->type))
 			continue;
+		trace_ion_alloc_buffer_start(client->name, heap->name, len,
+					     heap_mask, flags);
 		buffer = ion_buffer_create(heap, dev, len, align, flags);
+		trace_ion_alloc_buffer_end(client->name, heap->name, len,
+					   heap_mask, flags);
 		if (!IS_ERR_OR_NULL(buffer))
 			break;
+
+		trace_ion_alloc_buffer_fallback(client->name, heap->name, len,
+					    heap_mask, flags, PTR_ERR(buffer));
 		if (dbg_str_idx < MAX_DBG_STR_LEN) {
 			unsigned int len_left = MAX_DBG_STR_LEN-dbg_str_idx-1;
 			int ret_value = snprintf(&dbg_str[dbg_str_idx],
@@ -461,10 +470,15 @@
 	}
 	mutex_unlock(&dev->lock);
 
-	if (buffer == NULL)
+	if (buffer == NULL) {
+		trace_ion_alloc_buffer_fail(client->name, dbg_str, len,
+					    heap_mask, flags, -ENODEV);
 		return ERR_PTR(-ENODEV);
+	}
 
 	if (IS_ERR(buffer)) {
+		trace_ion_alloc_buffer_fail(client->name, dbg_str, len,
+					    heap_mask, flags, PTR_ERR(buffer));
 		pr_debug("ION is unable to allocate 0x%x bytes (alignment: "
 			 "0x%x) from heap(s) %sfor client %s with heap "
 			 "mask 0x%x\n",
@@ -634,6 +648,19 @@
 	struct ion_iommu_map *iommu_map;
 	int ret = 0;
 
+	if (IS_ERR_OR_NULL(client)) {
+		pr_err("%s: client pointer is invalid\n", __func__);
+		return -EINVAL;
+	}
+	if (IS_ERR_OR_NULL(handle)) {
+		pr_err("%s: handle pointer is invalid\n", __func__);
+		return -EINVAL;
+	}
+	if (IS_ERR_OR_NULL(handle->buffer)) {
+		pr_err("%s: buffer pointer is invalid\n", __func__);
+		return -EINVAL;
+	}
+
 	if (ION_IS_CACHED(flags)) {
 		pr_err("%s: Cannot map iommu as cached.\n", __func__);
 		return -EINVAL;
@@ -741,6 +768,19 @@
 	struct ion_iommu_map *iommu_map;
 	struct ion_buffer *buffer;
 
+	if (IS_ERR_OR_NULL(client)) {
+		pr_err("%s: client pointer is invalid\n", __func__);
+		return;
+	}
+	if (IS_ERR_OR_NULL(handle)) {
+		pr_err("%s: handle pointer is invalid\n", __func__);
+		return;
+	}
+	if (IS_ERR_OR_NULL(handle->buffer)) {
+		pr_err("%s: buffer pointer is invalid\n", __func__);
+		return;
+	}
+
 	mutex_lock(&client->lock);
 	buffer = handle->buffer;
 
@@ -984,10 +1024,91 @@
 	return client;
 }
 
+/**
+ * ion_mark_dangling_buffers_locked() - Mark dangling buffers
+ * @dev:	the ion device whose buffers will be searched
+ *
+ * Sets marked=1 for all known buffers associated with `dev' that no
+ * longer have a handle pointing to them. dev->lock should be held
+ * across a call to this function (and should only be unlocked after
+ * checking for marked buffers).
+ */
+static void ion_mark_dangling_buffers_locked(struct ion_device *dev)
+{
+	struct rb_node *n, *n2;
+	/* mark all buffers as 1 */
+	for (n = rb_first(&dev->buffers); n; n = rb_next(n)) {
+		struct ion_buffer *buf = rb_entry(n, struct ion_buffer,
+						node);
+
+		buf->marked = 1;
+	}
+
+	/* now see which buffers we can access */
+	for (n = rb_first(&dev->clients); n; n = rb_next(n)) {
+		struct ion_client *client = rb_entry(n, struct ion_client,
+						node);
+
+		mutex_lock(&client->lock);
+		for (n2 = rb_first(&client->handles); n2; n2 = rb_next(n2)) {
+			struct ion_handle *handle
+				= rb_entry(n2, struct ion_handle, node);
+
+			handle->buffer->marked = 0;
+
+		}
+		mutex_unlock(&client->lock);
+
+	}
+}
+
+#ifdef CONFIG_ION_LEAK_CHECK
+static u32 ion_debug_check_leaks_on_destroy;
+
+static int ion_check_for_and_print_leaks(struct ion_device *dev)
+{
+	struct rb_node *n;
+	int num_leaks = 0;
+
+	if (!ion_debug_check_leaks_on_destroy)
+		return 0;
+
+	/* check for leaked buffers (those that no longer have a
+	 * handle pointing to them) */
+	ion_mark_dangling_buffers_locked(dev);
+
+	/* Anyone still marked as a 1 means a leaked handle somewhere */
+	for (n = rb_first(&dev->buffers); n; n = rb_next(n)) {
+		struct ion_buffer *buf = rb_entry(n, struct ion_buffer,
+						node);
+
+		if (buf->marked == 1) {
+			pr_info("Leaked ion buffer at %p\n", buf);
+			num_leaks++;
+		}
+	}
+	return num_leaks;
+}
+static void setup_ion_leak_check(struct dentry *debug_root)
+{
+	debugfs_create_bool("check_leaks_on_destroy", 0664, debug_root,
+			&ion_debug_check_leaks_on_destroy);
+}
+#else
+static int ion_check_for_and_print_leaks(struct ion_device *dev)
+{
+	return 0;
+}
+static void setup_ion_leak_check(struct dentry *debug_root)
+{
+}
+#endif
+
 void ion_client_destroy(struct ion_client *client)
 {
 	struct ion_device *dev = client->dev;
 	struct rb_node *n;
+	int num_leaks;
 
 	pr_debug("%s: %d\n", __func__, __LINE__);
 	while ((n = rb_first(&client->handles))) {
@@ -1000,8 +1121,21 @@
 		put_task_struct(client->task);
 	rb_erase(&client->node, &dev->clients);
 	debugfs_remove_recursive(client->debug_root);
+
+	num_leaks = ion_check_for_and_print_leaks(dev);
+
 	mutex_unlock(&dev->lock);
 
+	if (num_leaks) {
+		struct task_struct *current_task = current;
+		char current_task_name[TASK_COMM_LEN];
+		get_task_comm(current_task_name, current_task);
+		WARN(1, "%s: Detected %d leaked ion buffer%s.\n",
+			__func__, num_leaks, num_leaks == 1 ? "" : "s");
+		pr_info("task name at time of leak: %s, pid: %d\n",
+			current_task_name, current_task->pid);
+	}
+
 	kfree(client->name);
 	kfree(client);
 }
@@ -1086,33 +1220,17 @@
 {
 }
 
-static void ion_vma_open(struct vm_area_struct *vma)
-{
-	struct ion_buffer *buffer = vma->vm_private_data;
-
-	pr_debug("%s: %d\n", __func__, __LINE__);
-
-	mutex_lock(&buffer->lock);
-	buffer->umap_cnt++;
-	mutex_unlock(&buffer->lock);
-}
-
 static void ion_vma_close(struct vm_area_struct *vma)
 {
 	struct ion_buffer *buffer = vma->vm_private_data;
 
 	pr_debug("%s: %d\n", __func__, __LINE__);
 
-	mutex_lock(&buffer->lock);
-	buffer->umap_cnt--;
-	mutex_unlock(&buffer->lock);
-
 	if (buffer->heap->ops->unmap_user)
 		buffer->heap->ops->unmap_user(buffer->heap, buffer);
 }
 
 static struct vm_operations_struct ion_vm_ops = {
-	.open = ion_vma_open,
 	.close = ion_vma_close,
 };
 
@@ -1136,7 +1254,6 @@
 		pr_err("%s: failure mapping buffer to userspace\n",
 		       __func__);
 	} else {
-		buffer->umap_cnt++;
 		mutex_unlock(&buffer->lock);
 
 		vma->vm_ops = &ion_vm_ops;
@@ -1374,9 +1491,6 @@
 	case ION_IOC_CLEAN_INV_CACHES:
 		return client->dev->custom_ioctl(client,
 						ION_IOC_CLEAN_INV_CACHES, arg);
-	case ION_IOC_GET_FLAGS:
-		return client->dev->custom_ioctl(client,
-						ION_IOC_GET_FLAGS, arg);
 	default:
 		return -ENOTTY;
 	}
@@ -1519,6 +1633,10 @@
 {
 	struct ion_device *dev = heap->dev;
 	struct rb_node *n;
+	size_t size;
+
+	if (!heap->ops->phys)
+		return;
 
 	for (n = rb_first(&dev->buffers); n; n = rb_next(n)) {
 		struct ion_buffer *buffer =
@@ -1531,9 +1649,11 @@
 					   "Part of memory map will not be logged\n");
 				break;
 			}
-			data->addr = buffer->priv_phys;
-			data->addr_end = buffer->priv_phys + buffer->size-1;
-			data->size = buffer->size;
+
+			buffer->heap->ops->phys(buffer->heap, buffer,
+						&(data->addr), &size);
+			data->size = (unsigned long) size;
+			data->addr_end = data->addr + data->size - 1;
 			data->client_name = ion_debug_locate_owner(dev, buffer);
 			ion_debug_mem_map_add(mem_map, data);
 		}
@@ -1667,7 +1787,7 @@
 	buffer = handle->buffer;
 	heap = buffer->heap;
 
-	if (heap->type != (enum ion_heap_type) ION_HEAP_TYPE_CP) {
+	if (!ion_heap_allow_handle_secure(heap->type)) {
 		pr_err("%s: cannot secure buffer from non secure heap\n",
 			__func__);
 		goto out_unlock;
@@ -1700,7 +1820,7 @@
 	buffer = handle->buffer;
 	heap = buffer->heap;
 
-	if (heap->type != (enum ion_heap_type) ION_HEAP_TYPE_CP) {
+	if (!ion_heap_allow_handle_secure(heap->type)) {
 		pr_err("%s: cannot secure buffer from non secure heap\n",
 			__func__);
 		goto out_unlock;
@@ -1731,7 +1851,7 @@
 	mutex_lock(&dev->lock);
 	for (n = rb_first(&dev->heaps); n != NULL; n = rb_next(n)) {
 		struct ion_heap *heap = rb_entry(n, struct ion_heap, node);
-		if (heap->type != (enum ion_heap_type) ION_HEAP_TYPE_CP)
+		if (!ion_heap_allow_heap_secure(heap->type))
 			continue;
 		if (ION_HEAP(heap->id) != heap_id)
 			continue;
@@ -1759,7 +1879,7 @@
 	mutex_lock(&dev->lock);
 	for (n = rb_first(&dev->heaps); n != NULL; n = rb_next(n)) {
 		struct ion_heap *heap = rb_entry(n, struct ion_heap, node);
-		if (heap->type != (enum ion_heap_type) ION_HEAP_TYPE_CP)
+		if (!ion_heap_allow_heap_secure(heap->type))
 			continue;
 		if (ION_HEAP(heap->id) != heap_id)
 			continue;
@@ -1778,37 +1898,14 @@
 {
 	struct ion_device *dev = s->private;
 	struct rb_node *n;
-	struct rb_node *n2;
 
-	/* mark all buffers as 1 */
 	seq_printf(s, "%16.s %16.s %16.s %16.s\n", "buffer", "heap", "size",
 		"ref cnt");
+
 	mutex_lock(&dev->lock);
-	for (n = rb_first(&dev->buffers); n; n = rb_next(n)) {
-		struct ion_buffer *buf = rb_entry(n, struct ion_buffer,
-						     node);
+	ion_mark_dangling_buffers_locked(dev);
 
-		buf->marked = 1;
-	}
-
-	/* now see which buffers we can access */
-	for (n = rb_first(&dev->clients); n; n = rb_next(n)) {
-		struct ion_client *client = rb_entry(n, struct ion_client,
-						     node);
-
-		mutex_lock(&client->lock);
-		for (n2 = rb_first(&client->handles); n2; n2 = rb_next(n2)) {
-			struct ion_handle *handle = rb_entry(n2,
-						struct ion_handle, node);
-
-			handle->buffer->marked = 0;
-
-		}
-		mutex_unlock(&client->lock);
-
-	}
-
-	/* And anyone still marked as a 1 means a leaked handle somewhere */
+	/* Anyone still marked as a 1 means a leaked handle somewhere */
 	for (n = rb_first(&dev->buffers); n; n = rb_next(n)) {
 		struct ion_buffer *buf = rb_entry(n, struct ion_buffer,
 						     node);
@@ -1869,6 +1966,8 @@
 	idev->clients = RB_ROOT;
 	debugfs_create_file("check_leaked_fds", 0664, idev->debug_root, idev,
 			    &debug_leak_fops);
+
+	setup_ion_leak_check(idev->debug_root);
 	return idev;
 }
 
diff --git a/drivers/gpu/ion/ion_carveout_heap.c b/drivers/gpu/ion/ion_carveout_heap.c
index 7d7ea36..3e55a57 100644
--- a/drivers/gpu/ion/ion_carveout_heap.c
+++ b/drivers/gpu/ion/ion_carveout_heap.c
@@ -2,7 +2,7 @@
  * drivers/gpu/ion/ion_carveout_heap.c
  *
  * Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -377,8 +377,9 @@
 
 	if (extra) {
 		unsigned long extra_iova_addr = data->iova_addr + buffer->size;
-		ret = msm_iommu_map_extra(domain, extra_iova_addr, extra,
-					  SZ_4K, prot);
+		unsigned long phys_addr = sg_phys(sglist);
+		ret = msm_iommu_map_extra(domain, extra_iova_addr, phys_addr,
+					extra, SZ_4K, prot);
 		if (ret)
 			goto out2;
 	}
diff --git a/drivers/gpu/ion/ion_cma_heap.c b/drivers/gpu/ion/ion_cma_heap.c
index bef6b6f..4f5ac75 100644
--- a/drivers/gpu/ion/ion_cma_heap.c
+++ b/drivers/gpu/ion/ion_cma_heap.c
@@ -228,8 +228,9 @@
 
 	extra_iova_addr = data->iova_addr + buffer->size;
 	if (extra) {
-		ret = msm_iommu_map_extra(domain, extra_iova_addr, extra, SZ_4K,
-						prot);
+		unsigned long phys_addr = sg_phys(table->sgl);
+		ret = msm_iommu_map_extra(domain, extra_iova_addr, phys_addr,
+					extra, SZ_4K, prot);
 		if (ret)
 			goto out2;
 	}
@@ -304,6 +305,35 @@
 	return 0;
 }
 
+static int ion_cma_print_debug(struct ion_heap *heap, struct seq_file *s,
+			const struct rb_root *mem_map)
+{
+	if (mem_map) {
+		struct rb_node *n;
+
+		seq_printf(s, "\nMemory Map\n");
+		seq_printf(s, "%16.s %14.s %14.s %14.s\n",
+			   "client", "start address", "end address",
+			   "size (hex)");
+
+		for (n = rb_first(mem_map); n; n = rb_next(n)) {
+			struct mem_map_data *data =
+					rb_entry(n, struct mem_map_data, node);
+			const char *client_name = "(null)";
+
+
+			if (data->client_name)
+				client_name = data->client_name;
+
+			seq_printf(s, "%16.s %14lx %14lx %14lu (%lx)\n",
+				   client_name, data->addr,
+				   data->addr_end,
+				   data->size, data->size);
+		}
+	}
+	return 0;
+}
+
 static struct ion_heap_ops ion_cma_ops = {
 	.allocate = ion_cma_allocate,
 	.free = ion_cma_free,
@@ -316,6 +346,7 @@
 	.map_iommu = ion_cma_map_iommu,
 	.unmap_iommu = ion_cma_unmap_iommu,
 	.cache_op = ion_cma_cache_ops,
+	.print_debug = ion_cma_print_debug,
 };
 
 struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *data)
diff --git a/drivers/gpu/ion/ion_cma_secure_heap.c b/drivers/gpu/ion/ion_cma_secure_heap.c
new file mode 100644
index 0000000..2c0e5ae
--- /dev/null
+++ b/drivers/gpu/ion/ion_cma_secure_heap.c
@@ -0,0 +1,409 @@
+/*
+ * drivers/gpu/ion/ion_secure_cma_heap.c
+ *
+ * Copyright (C) Linaro 2012
+ * Author: <benjamin.gaignard@linaro.org> for ST-Ericsson.
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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/device.h>
+#include <linux/ion.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/dma-mapping.h>
+#include <linux/msm_ion.h>
+#include <mach/iommu_domains.h>
+
+#include <asm/cacheflush.h>
+
+/* for ion_heap_ops structure */
+#include "ion_priv.h"
+#include "msm/ion_cp_common.h"
+
+#define ION_CMA_ALLOCATE_FAILED NULL
+
+struct ion_secure_cma_buffer_info {
+	/*
+	 * This needs to come first for compatibility with the secure buffer API
+	 */
+	struct ion_cp_buffer secure;
+	void *cpu_addr;
+	dma_addr_t handle;
+	struct sg_table *table;
+	bool is_cached;
+};
+
+static int cma_heap_has_outer_cache;
+/*
+ * Create scatter-list for the already allocated DMA buffer.
+ * This function could be replace by dma_common_get_sgtable
+ * as soon as it will avalaible.
+ */
+int ion_secure_cma_get_sgtable(struct device *dev, struct sg_table *sgt,
+			void *cpu_addr, dma_addr_t handle, size_t size)
+{
+	struct page *page = virt_to_page(cpu_addr);
+	int ret;
+
+	ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
+	if (unlikely(ret))
+		return ret;
+
+	sg_set_page(sgt->sgl, page, PAGE_ALIGN(size), 0);
+	sg_dma_address(sgt->sgl) = handle;
+	return 0;
+}
+
+/* ION CMA heap operations functions */
+static struct ion_secure_cma_buffer_info *__ion_secure_cma_allocate(
+			    struct ion_heap *heap, struct ion_buffer *buffer,
+			    unsigned long len, unsigned long align,
+			    unsigned long flags)
+{
+	struct device *dev = heap->priv;
+	struct ion_secure_cma_buffer_info *info;
+
+	dev_dbg(dev, "Request buffer allocation len %ld\n", len);
+
+	info = kzalloc(sizeof(struct ion_secure_cma_buffer_info), GFP_KERNEL);
+	if (!info) {
+		dev_err(dev, "Can't allocate buffer info\n");
+		return ION_CMA_ALLOCATE_FAILED;
+	}
+
+	if (!ION_IS_CACHED(flags))
+		info->cpu_addr = dma_alloc_writecombine(dev, len,
+					&(info->handle), 0);
+	else
+		info->cpu_addr = dma_alloc_nonconsistent(dev, len,
+					&(info->handle), 0);
+
+	if (!info->cpu_addr) {
+		dev_err(dev, "Fail to allocate buffer\n");
+		goto err;
+	}
+
+	info->table = kmalloc(sizeof(struct sg_table), GFP_KERNEL);
+	if (!info->table) {
+		dev_err(dev, "Fail to allocate sg table\n");
+		goto err;
+	}
+
+	info->is_cached = ION_IS_CACHED(flags);
+
+	ion_secure_cma_get_sgtable(dev,
+			info->table, info->cpu_addr, info->handle, len);
+
+	info->secure.buffer = info->handle;
+
+	/* keep this for memory release */
+	buffer->priv_virt = info;
+	dev_dbg(dev, "Allocate buffer %p\n", buffer);
+	return info;
+
+err:
+	kfree(info);
+	return ION_CMA_ALLOCATE_FAILED;
+}
+
+static int ion_secure_cma_allocate(struct ion_heap *heap,
+			    struct ion_buffer *buffer,
+			    unsigned long len, unsigned long align,
+			    unsigned long flags)
+{
+	unsigned long secure_allocation = flags & ION_SECURE;
+	struct ion_secure_cma_buffer_info *buf = NULL;
+
+	if (!secure_allocation) {
+		pr_err("%s: non-secure allocation disallowed from heap %s %lx\n",
+			__func__, heap->name, flags);
+		return -ENOMEM;
+	}
+
+	buf = __ion_secure_cma_allocate(heap, buffer, len, align, flags);
+
+	if (buf) {
+		buf->secure.want_delayed_unsecure = 0;
+		atomic_set(&buf->secure.secure_cnt, 0);
+		mutex_init(&buf->secure.lock);
+		buf->secure.is_secure = 1;
+		return 0;
+	} else {
+		return -ENOMEM;
+	}
+}
+
+
+static void ion_secure_cma_free(struct ion_buffer *buffer)
+{
+	struct device *dev = buffer->heap->priv;
+	struct ion_secure_cma_buffer_info *info = buffer->priv_virt;
+
+	dev_dbg(dev, "Release buffer %p\n", buffer);
+	/* release memory */
+	dma_free_coherent(dev, buffer->size, info->cpu_addr, info->handle);
+	/* release sg table */
+	kfree(info->table);
+	kfree(info);
+}
+
+static int ion_secure_cma_phys(struct ion_heap *heap, struct ion_buffer *buffer,
+			ion_phys_addr_t *addr, size_t *len)
+{
+	struct device *dev = heap->priv;
+	struct ion_secure_cma_buffer_info *info = buffer->priv_virt;
+
+	dev_dbg(dev, "Return buffer %p physical address 0x%x\n", buffer,
+		info->handle);
+
+	*addr = info->handle;
+	*len = buffer->size;
+
+	return 0;
+}
+
+struct sg_table *ion_secure_cma_heap_map_dma(struct ion_heap *heap,
+					 struct ion_buffer *buffer)
+{
+	struct ion_secure_cma_buffer_info *info = buffer->priv_virt;
+
+	return info->table;
+}
+
+void ion_secure_cma_heap_unmap_dma(struct ion_heap *heap,
+			       struct ion_buffer *buffer)
+{
+	return;
+}
+
+static int ion_secure_cma_mmap(struct ion_heap *mapper,
+			struct ion_buffer *buffer,
+			struct vm_area_struct *vma)
+{
+	return -EINVAL;
+}
+
+static void *ion_secure_cma_map_kernel(struct ion_heap *heap,
+				struct ion_buffer *buffer)
+{
+	struct ion_secure_cma_buffer_info *info = buffer->priv_virt;
+
+	atomic_inc(&info->secure.map_cnt);
+	return info->cpu_addr;
+}
+
+static void ion_secure_cma_unmap_kernel(struct ion_heap *heap,
+				 struct ion_buffer *buffer)
+{
+	struct ion_secure_cma_buffer_info *info = buffer->priv_virt;
+
+	atomic_dec(&info->secure.map_cnt);
+	return;
+}
+
+int ion_secure_cma_map_iommu(struct ion_buffer *buffer,
+				struct ion_iommu_map *data,
+				unsigned int domain_num,
+				unsigned int partition_num,
+				unsigned long align,
+				unsigned long iova_length,
+				unsigned long flags)
+{
+	int ret = 0;
+	struct iommu_domain *domain;
+	unsigned long extra;
+	unsigned long extra_iova_addr;
+	struct ion_secure_cma_buffer_info *info = buffer->priv_virt;
+	struct sg_table *table = info->table;
+	int prot = IOMMU_WRITE | IOMMU_READ;
+
+	data->mapped_size = iova_length;
+
+	if (!msm_use_iommu()) {
+		data->iova_addr = info->handle;
+		return 0;
+	}
+
+	extra = iova_length - buffer->size;
+
+	ret = msm_allocate_iova_address(domain_num, partition_num,
+						data->mapped_size, align,
+						&data->iova_addr);
+
+	if (ret)
+		goto out;
+
+	domain = msm_get_iommu_domain(domain_num);
+
+	if (!domain) {
+		ret = -EINVAL;
+		goto out1;
+	}
+
+	ret = iommu_map_range(domain, data->iova_addr, table->sgl,
+				buffer->size, prot);
+
+	if (ret) {
+		pr_err("%s: could not map %lx in domain %p\n",
+			__func__, data->iova_addr, domain);
+		goto out1;
+	}
+
+	extra_iova_addr = data->iova_addr + buffer->size;
+	if (extra) {
+		unsigned long phys_addr = sg_phys(table->sgl);
+		ret = msm_iommu_map_extra(domain, extra_iova_addr, phys_addr,
+					extra, SZ_4K, prot);
+		if (ret)
+			goto out2;
+	}
+	return ret;
+
+out2:
+	iommu_unmap_range(domain, data->iova_addr, buffer->size);
+out1:
+	msm_free_iova_address(data->iova_addr, domain_num, partition_num,
+				data->mapped_size);
+out:
+	return ret;
+}
+
+
+void ion_secure_cma_unmap_iommu(struct ion_iommu_map *data)
+{
+	unsigned int domain_num;
+	unsigned int partition_num;
+	struct iommu_domain *domain;
+
+	if (!msm_use_iommu())
+		return;
+
+	domain_num = iommu_map_domain(data);
+	partition_num = iommu_map_partition(data);
+
+	domain = msm_get_iommu_domain(domain_num);
+
+	if (!domain) {
+		WARN(1, "Could not get domain %d. Corruption?\n", domain_num);
+		return;
+	}
+
+	iommu_unmap_range(domain, data->iova_addr, data->mapped_size);
+	msm_free_iova_address(data->iova_addr, domain_num, partition_num,
+				data->mapped_size);
+
+	return;
+}
+
+int ion_secure_cma_cache_ops(struct ion_heap *heap,
+			struct ion_buffer *buffer, void *vaddr,
+			unsigned int offset, unsigned int length,
+			unsigned int cmd)
+{
+	void (*outer_cache_op)(phys_addr_t, phys_addr_t);
+
+	switch (cmd) {
+	case ION_IOC_CLEAN_CACHES:
+		dmac_clean_range(vaddr, vaddr + length);
+		outer_cache_op = outer_clean_range;
+		break;
+	case ION_IOC_INV_CACHES:
+		dmac_inv_range(vaddr, vaddr + length);
+		outer_cache_op = outer_inv_range;
+		break;
+	case ION_IOC_CLEAN_INV_CACHES:
+		dmac_flush_range(vaddr, vaddr + length);
+		outer_cache_op = outer_flush_range;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (cma_heap_has_outer_cache) {
+		struct ion_secure_cma_buffer_info *info = buffer->priv_virt;
+
+		outer_cache_op(info->handle, info->handle + length);
+	}
+
+	return 0;
+}
+
+static int ion_secure_cma_print_debug(struct ion_heap *heap, struct seq_file *s,
+			const struct rb_root *mem_map)
+{
+	if (mem_map) {
+		struct rb_node *n;
+
+		seq_printf(s, "\nMemory Map\n");
+		seq_printf(s, "%16.s %14.s %14.s %14.s\n",
+			   "client", "start address", "end address",
+			   "size (hex)");
+
+		for (n = rb_first(mem_map); n; n = rb_next(n)) {
+			struct mem_map_data *data =
+					rb_entry(n, struct mem_map_data, node);
+			const char *client_name = "(null)";
+
+
+			if (data->client_name)
+				client_name = data->client_name;
+
+			seq_printf(s, "%16.s %14lx %14lx %14lu (%lx)\n",
+				   client_name, data->addr,
+				   data->addr_end,
+				   data->size, data->size);
+		}
+	}
+	return 0;
+}
+
+static struct ion_heap_ops ion_secure_cma_ops = {
+	.allocate = ion_secure_cma_allocate,
+	.free = ion_secure_cma_free,
+	.map_dma = ion_secure_cma_heap_map_dma,
+	.unmap_dma = ion_secure_cma_heap_unmap_dma,
+	.phys = ion_secure_cma_phys,
+	.map_user = ion_secure_cma_mmap,
+	.map_kernel = ion_secure_cma_map_kernel,
+	.unmap_kernel = ion_secure_cma_unmap_kernel,
+	.map_iommu = ion_secure_cma_map_iommu,
+	.unmap_iommu = ion_secure_cma_unmap_iommu,
+	.cache_op = ion_secure_cma_cache_ops,
+	.print_debug = ion_secure_cma_print_debug,
+	.secure_buffer = ion_cp_secure_buffer,
+	.unsecure_buffer = ion_cp_unsecure_buffer,
+};
+
+struct ion_heap *ion_secure_cma_heap_create(struct ion_platform_heap *data)
+{
+	struct ion_heap *heap;
+
+	heap = kzalloc(sizeof(struct ion_heap), GFP_KERNEL);
+
+	if (!heap)
+		return ERR_PTR(-ENOMEM);
+
+	heap->ops = &ion_secure_cma_ops;
+	/* set device as private heaps data, later it will be
+	 * used to make the link with reserved CMA memory */
+	heap->priv = data->priv;
+	heap->type = ION_HEAP_TYPE_SECURE_DMA;
+	cma_heap_has_outer_cache = data->has_outer_cache;
+	return heap;
+}
+
+void ion_secure_cma_heap_destroy(struct ion_heap *heap)
+{
+	kfree(heap);
+}
diff --git a/drivers/gpu/ion/ion_cp_heap.c b/drivers/gpu/ion/ion_cp_heap.c
index d96b755..56ccc8f 100644
--- a/drivers/gpu/ion/ion_cp_heap.c
+++ b/drivers/gpu/ion/ion_cp_heap.c
@@ -2,7 +2,7 @@
  * drivers/gpu/ion/ion_cp_heap.c
  *
  * Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -29,6 +29,7 @@
 #include <linux/fmem.h>
 #include <linux/iommu.h>
 #include <linux/dma-mapping.h>
+#include <trace/events/kmem.h>
 
 #include <asm/mach/map.h>
 
@@ -104,7 +105,7 @@
 	size_t heap_size;
 	dma_addr_t handle;
 	int cma;
-	int disallow_non_secure_allocation;
+	int allow_non_secure_allocation;
 };
 
 enum {
@@ -112,36 +113,8 @@
 	HEAP_PROTECTED = 1,
 };
 
-struct ion_cp_buffer {
-	phys_addr_t buffer;
-	atomic_t secure_cnt;
-	int is_secure;
-	int want_delayed_unsecure;
-	/*
-	 * Currently all user/kernel mapping is protected by the heap lock.
-	 * This is sufficient to protect the map count as well. The lock
-	 * should be used to protect map_cnt if the whole heap lock is
-	 * ever removed.
-	 */
-	atomic_t map_cnt;
-	/*
-	 * protects secure_cnt for securing.
-	 */
-	struct mutex lock;
-	int version;
-	void *data;
-};
-
 #define DMA_ALLOC_TRIES	5
 
-static int ion_cp_protect_mem(unsigned int phy_base, unsigned int size,
-			unsigned int permission_type, int version,
-			void *data);
-
-static int ion_cp_unprotect_mem(unsigned int phy_base, unsigned int size,
-				unsigned int permission_type, int version,
-				void *data);
-
 static int allocate_heap_memory(struct ion_heap *heap)
 {
 	struct device *dev = heap->priv;
@@ -162,8 +135,10 @@
 						&(cp_heap->handle),
 						0,
 						&attrs);
-		if (!cp_heap->cpu_addr)
+		if (!cp_heap->cpu_addr) {
+			trace_ion_cp_alloc_retry(tries);
 			msleep(20);
+		}
 	}
 
 	if (!cp_heap->cpu_addr)
@@ -251,145 +226,6 @@
 		free_heap_memory(heap);
 }
 
-/* Must be protected by ion_cp_buffer lock */
-static int __ion_cp_protect_buffer(struct ion_buffer *buffer, int version,
-					void *data, int flags)
-{
-	struct ion_cp_buffer *buf = buffer->priv_virt;
-	int ret_value = 0;
-
-	if (atomic_inc_return(&buf->secure_cnt) == 1) {
-		ret_value = ion_cp_protect_mem(buf->buffer,
-				buffer->size, 0,
-				version, data);
-
-		if (ret_value) {
-			pr_err("Failed to secure buffer %p, error %d\n",
-				buffer, ret_value);
-			atomic_dec(&buf->secure_cnt);
-		} else {
-			pr_debug("Protected buffer %p from %x-%x\n",
-				buffer, buf->buffer,
-				buf->buffer + buffer->size);
-			buf->want_delayed_unsecure |=
-				flags & ION_UNSECURE_DELAYED ? 1 : 0;
-			buf->data = data;
-			buf->version = version;
-		}
-	}
-	pr_debug("buffer %p protect count %d\n", buffer,
-		atomic_read(&buf->secure_cnt));
-	BUG_ON(atomic_read(&buf->secure_cnt) < 0);
-	return ret_value;
-}
-
-/* Must be protected by ion_cp_buffer lock */
-static int __ion_cp_unprotect_buffer(struct ion_buffer *buffer, int version,
-					void *data, int force_unsecure)
-{
-	struct ion_cp_buffer *buf = buffer->priv_virt;
-	int ret_value = 0;
-
-	if (force_unsecure) {
-		if (!buf->is_secure || atomic_read(&buf->secure_cnt) == 0)
-			return 0;
-
-		if (atomic_read(&buf->secure_cnt) != 1) {
-			WARN(1, "Forcing unsecure of buffer with outstanding secure count %d!\n",
-				atomic_read(&buf->secure_cnt));
-			atomic_set(&buf->secure_cnt, 1);
-		}
-	}
-
-	if (atomic_dec_and_test(&buf->secure_cnt)) {
-		ret_value = ion_cp_unprotect_mem(
-			buf->buffer, buffer->size,
-			0, version, data);
-
-		if (ret_value) {
-			pr_err("Failed to unsecure buffer %p, error %d\n",
-				buffer, ret_value);
-			/*
-			 * If the force unsecure is happening, the buffer
-			 * is being destroyed. We failed to unsecure the
-			 * buffer even though the memory is given back.
-			 * Just die now rather than discovering later what
-			 * happens when trying to use the secured memory as
-			 * unsecured...
-			 */
-			BUG_ON(force_unsecure);
-			/* Bump the count back up one to try again later */
-			atomic_inc(&buf->secure_cnt);
-		} else {
-			buf->version = -1;
-			buf->data = NULL;
-		}
-	}
-	pr_debug("buffer %p unprotect count %d\n", buffer,
-		atomic_read(&buf->secure_cnt));
-	BUG_ON(atomic_read(&buf->secure_cnt) < 0);
-	return ret_value;
-}
-
-int ion_cp_secure_buffer(struct ion_buffer *buffer, int version, void *data,
-				int flags)
-{
-	int ret_value;
-	struct ion_cp_buffer *buf = buffer->priv_virt;
-
-	mutex_lock(&buf->lock);
-	if (!buf->is_secure) {
-		pr_err("%s: buffer %p was not allocated as secure\n",
-			__func__, buffer);
-		ret_value = -EINVAL;
-		goto out_unlock;
-	}
-
-	if (ION_IS_CACHED(buffer->flags)) {
-		pr_err("%s: buffer %p was allocated as cached\n",
-			__func__, buffer);
-		ret_value = -EINVAL;
-		goto out_unlock;
-	}
-
-	if (atomic_read(&buf->map_cnt)) {
-		pr_err("%s: cannot secure buffer %p with outstanding mappings. Total count: %d",
-			__func__, buffer, atomic_read(&buf->map_cnt));
-		ret_value = -EINVAL;
-		goto out_unlock;
-	}
-
-	if (atomic_read(&buf->secure_cnt)) {
-		if (buf->version != version || buf->data != data) {
-			pr_err("%s: Trying to re-secure buffer with different values",
-				__func__);
-			pr_err("Last secured version: %d Currrent %d\n",
-				buf->version, version);
-			pr_err("Last secured data: %p current %p\n",
-				buf->data, data);
-			ret_value = -EINVAL;
-			goto out_unlock;
-		}
-	}
-	ret_value = __ion_cp_protect_buffer(buffer, version, data, flags);
-
-out_unlock:
-	mutex_unlock(&buf->lock);
-	return ret_value;
-}
-
-int ion_cp_unsecure_buffer(struct ion_buffer *buffer, int force_unsecure)
-{
-	int ret_value = 0;
-	struct ion_cp_buffer *buf = buffer->priv_virt;
-
-	mutex_lock(&buf->lock);
-	ret_value = __ion_cp_unprotect_buffer(buffer, buf->version, buf->data,
-						force_unsecure);
-	mutex_unlock(&buf->lock);
-	return ret_value;
-}
-
 /**
  * Protects memory if heap is unsecured heap. Also ensures that we are in
  * the correct FMEM state if this heap is a reusable heap.
@@ -469,6 +305,7 @@
 {
 	unsigned long offset;
 	unsigned long secure_allocation = flags & ION_SECURE;
+	unsigned long force_contig = flags & ION_FORCE_CONTIGUOUS;
 
 	struct ion_cp_heap *cp_heap =
 		container_of(heap, struct ion_cp_heap, heap);
@@ -481,7 +318,8 @@
 		return ION_CP_ALLOCATE_FAIL;
 	}
 
-	if (!secure_allocation && cp_heap->disallow_non_secure_allocation) {
+	if (!force_contig && !secure_allocation &&
+	     !cp_heap->allow_non_secure_allocation) {
 		mutex_unlock(&cp_heap->lock);
 		pr_debug("%s: non-secure allocation disallowed from this heap\n",
 			__func__);
@@ -652,39 +490,31 @@
 
 struct sg_table *ion_cp_heap_create_sg_table(struct ion_buffer *buffer)
 {
+	size_t chunk_size = buffer->size;
 	struct sg_table *table;
-	int ret;
+	int ret, i, n_chunks;
+	struct scatterlist *sg;
 	struct ion_cp_buffer *buf = buffer->priv_virt;
 
+	if (ION_IS_CACHED(buffer->flags))
+		chunk_size = PAGE_SIZE;
+	else if (buf->is_secure && IS_ALIGNED(buffer->size, SZ_1M))
+		chunk_size = SZ_1M;
+
 	table = kzalloc(sizeof(struct sg_table), GFP_KERNEL);
 	if (!table)
 		return ERR_PTR(-ENOMEM);
 
-	if (buf->is_secure && IS_ALIGNED(buffer->size, SZ_1M)) {
-		int n_chunks;
-		int i;
-		struct scatterlist *sg;
+	n_chunks = DIV_ROUND_UP(buffer->size, chunk_size);
 
-		/* Count number of 1MB chunks. Alignment is already checked. */
-		n_chunks = buffer->size >> 20;
+	ret = sg_alloc_table(table, n_chunks, GFP_KERNEL);
+	if (ret)
+		goto err0;
 
-		ret = sg_alloc_table(table, n_chunks, GFP_KERNEL);
-		if (ret)
-			goto err0;
-
-		for_each_sg(table->sgl, sg, table->nents, i) {
-			sg_dma_address(sg) = buf->buffer + i * SZ_1M;
-			sg->length = SZ_1M;
-			sg->offset = 0;
-		}
-	} else {
-		ret = sg_alloc_table(table, 1, GFP_KERNEL);
-		if (ret)
-			goto err0;
-
-		table->sgl->length = buffer->size;
-		table->sgl->offset = 0;
-		table->sgl->dma_address = buf->buffer;
+	for_each_sg(table->sgl, sg, table->nents, i) {
+		sg_dma_address(sg) = buf->buffer + i * chunk_size;
+		sg->length = chunk_size;
+		sg->offset = 0;
 	}
 
 	return table;
@@ -856,7 +686,7 @@
 	struct ion_cp_buffer *buf = buffer->priv_virt;
 
 	mutex_lock(&cp_heap->lock);
-	if (cp_heap->heap_protected == HEAP_NOT_PROTECTED) {
+	if (cp_heap->heap_protected == HEAP_NOT_PROTECTED && !buf->is_secure) {
 		if (ion_cp_request_region(cp_heap)) {
 			mutex_unlock(&cp_heap->lock);
 			return -EINVAL;
@@ -1081,6 +911,7 @@
 		}
 		if (domain_num == cp_heap->iommu_2x_map_domain)
 			ret_value = msm_iommu_map_extra(domain, temp_iova,
+							cp_heap->base,
 							cp_heap->total_size,
 							SZ_64K, prot);
 		if (ret_value)
@@ -1174,8 +1005,9 @@
 
 	if (extra) {
 		unsigned long extra_iova_addr = data->iova_addr + buffer->size;
-		ret = msm_iommu_map_extra(domain, extra_iova_addr, extra,
-					  SZ_4K, prot);
+		unsigned long phys_addr = sg_phys(buffer->sg_table->sgl);
+		ret = msm_iommu_map_extra(domain, extra_iova_addr, phys_addr,
+					extra, SZ_4K, prot);
 		if (ret)
 			goto out2;
 	}
@@ -1294,8 +1126,8 @@
 		cp_heap->iommu_2x_map_domain =
 				extra_data->iommu_2x_map_domain;
 		cp_heap->cma = extra_data->is_cma;
-		cp_heap->disallow_non_secure_allocation =
-			extra_data->no_nonsecure_alloc;
+		cp_heap->allow_non_secure_allocation =
+			extra_data->allow_nonsecure_alloc;
 
 	}
 
@@ -1345,108 +1177,4 @@
 	*size = cp_heap->total_size;
 }
 
-/*  SCM related code for locking down memory for content protection */
 
-#define SCM_CP_LOCK_CMD_ID	0x1
-#define SCM_CP_PROTECT		0x1
-#define SCM_CP_UNPROTECT	0x0
-
-struct cp_lock_msg {
-	unsigned int start;
-	unsigned int end;
-	unsigned int permission_type;
-	unsigned char lock;
-} __attribute__ ((__packed__));
-
-static int ion_cp_protect_mem_v1(unsigned int phy_base, unsigned int size,
-			      unsigned int permission_type)
-{
-	struct cp_lock_msg cmd;
-	cmd.start = phy_base;
-	cmd.end = phy_base + size;
-	cmd.permission_type = permission_type;
-	cmd.lock = SCM_CP_PROTECT;
-
-	return scm_call(SCM_SVC_CP, SCM_CP_LOCK_CMD_ID,
-			&cmd, sizeof(cmd), NULL, 0);
-}
-
-static int ion_cp_unprotect_mem_v1(unsigned int phy_base, unsigned int size,
-				unsigned int permission_type)
-{
-	struct cp_lock_msg cmd;
-	cmd.start = phy_base;
-	cmd.end = phy_base + size;
-	cmd.permission_type = permission_type;
-	cmd.lock = SCM_CP_UNPROTECT;
-
-	return scm_call(SCM_SVC_CP, SCM_CP_LOCK_CMD_ID,
-			&cmd, sizeof(cmd), NULL, 0);
-}
-
-#define V2_CHUNK_SIZE	SZ_1M
-
-static int ion_cp_change_mem_v2(unsigned int phy_base, unsigned int size,
-			      void *data, int lock)
-{
-	enum cp_mem_usage usage = (enum cp_mem_usage) data;
-	unsigned long *chunk_list;
-	int nchunks;
-	int ret;
-	int i;
-
-	if (usage < 0 || usage >= MAX_USAGE)
-		return -EINVAL;
-
-	if (!IS_ALIGNED(size, V2_CHUNK_SIZE)) {
-		pr_err("%s: heap size is not aligned to %x\n",
-			__func__, V2_CHUNK_SIZE);
-		return -EINVAL;
-	}
-
-	nchunks = size / V2_CHUNK_SIZE;
-
-	chunk_list = allocate_contiguous_ebi(sizeof(unsigned long)*nchunks,
-						SZ_4K, 0);
-	if (!chunk_list)
-		return -ENOMEM;
-
-	for (i = 0; i < nchunks; i++)
-		chunk_list[i] = phy_base + i * V2_CHUNK_SIZE;
-
-	ret = ion_cp_change_chunks_state(memory_pool_node_paddr(chunk_list),
-					nchunks, V2_CHUNK_SIZE, usage, lock);
-
-	free_contiguous_memory(chunk_list);
-	return ret;
-}
-
-static int ion_cp_protect_mem(unsigned int phy_base, unsigned int size,
-			      unsigned int permission_type, int version,
-			      void *data)
-{
-	switch (version) {
-	case ION_CP_V1:
-		return ion_cp_protect_mem_v1(phy_base, size, permission_type);
-	case ION_CP_V2:
-		return ion_cp_change_mem_v2(phy_base, size, data,
-						SCM_CP_PROTECT);
-	default:
-		return -EINVAL;
-	}
-}
-
-static int ion_cp_unprotect_mem(unsigned int phy_base, unsigned int size,
-			      unsigned int permission_type, int version,
-			      void *data)
-{
-	switch (version) {
-	case ION_CP_V1:
-		return ion_cp_unprotect_mem_v1(phy_base, size, permission_type);
-	case ION_CP_V2:
-		return ion_cp_change_mem_v2(phy_base, size, data,
-						SCM_CP_UNPROTECT);
-	default:
-		return -EINVAL;
-	}
-}
diff --git a/drivers/gpu/ion/ion_heap.c b/drivers/gpu/ion/ion_heap.c
index 0670468..ff2b8dd 100644
--- a/drivers/gpu/ion/ion_heap.c
+++ b/drivers/gpu/ion/ion_heap.c
@@ -2,7 +2,7 @@
  * drivers/gpu/ion/ion_heap.c
  *
  * Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -44,6 +44,10 @@
 	case ION_HEAP_TYPE_DMA:
 		heap = ion_cma_heap_create(heap_data);
 		break;
+
+	case ION_HEAP_TYPE_SECURE_DMA:
+		heap = ion_secure_cma_heap_create(heap_data);
+		break;
 #endif
 	default:
 		pr_err("%s: Invalid heap type %d\n", __func__,
@@ -89,6 +93,9 @@
 	case ION_HEAP_TYPE_DMA:
 		ion_cma_heap_destroy(heap);
 		break;
+	case ION_HEAP_TYPE_SECURE_DMA:
+		ion_secure_cma_heap_destroy(heap);
+		break;
 #endif
 	default:
 		pr_err("%s: Invalid heap type %d\n", __func__,
diff --git a/drivers/gpu/ion/ion_iommu_heap.c b/drivers/gpu/ion/ion_iommu_heap.c
index 5483054..761fdde 100644
--- a/drivers/gpu/ion/ion_iommu_heap.c
+++ b/drivers/gpu/ion/ion_iommu_heap.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -14,6 +14,7 @@
 #include <linux/io.h>
 #include <linux/msm_ion.h>
 #include <linux/mm.h>
+#include <linux/highmem.h>
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
@@ -32,36 +33,109 @@
 	unsigned int has_outer_cache;
 };
 
+/*
+ * We will attempt to allocate high-order pages and store those in an
+ * sg_list. However, some APIs expect an array of struct page * where
+ * each page is of size PAGE_SIZE. We use this extra structure to
+ * carry around an array of such pages (derived from the high-order
+ * pages with nth_page).
+ */
 struct ion_iommu_priv_data {
 	struct page **pages;
 	int nrpages;
 	unsigned long size;
 };
 
+#define MAX_VMAP_RETRIES 10
+
+static const unsigned int orders[] = {8, 4, 0};
+static const int num_orders = ARRAY_SIZE(orders);
+
+struct page_info {
+	struct page *page;
+	unsigned int order;
+	struct list_head list;
+};
+
+static unsigned int order_to_size(int order)
+{
+	return PAGE_SIZE << order;
+}
+
+static struct page_info *alloc_largest_available(unsigned long size,
+						unsigned int max_order)
+{
+	struct page *page;
+	struct page_info *info;
+	int i;
+
+	for (i = 0; i < num_orders; i++) {
+		gfp_t gfp;
+		if (size < order_to_size(orders[i]))
+			continue;
+		if (max_order < orders[i])
+			continue;
+
+		gfp = GFP_KERNEL | __GFP_HIGHMEM | __GFP_COMP;
+		if (orders[i])
+			gfp |= __GFP_NOWARN;
+
+		page = alloc_pages(gfp, orders[i]);
+		if (!page)
+			continue;
+
+		info = kmalloc(sizeof(struct page_info), GFP_KERNEL);
+		info->page = page;
+		info->order = orders[i];
+		return info;
+	}
+	return NULL;
+}
+
 static int ion_iommu_heap_allocate(struct ion_heap *heap,
 				      struct ion_buffer *buffer,
 				      unsigned long size, unsigned long align,
 				      unsigned long flags)
 {
 	int ret, i;
+	struct list_head pages_list;
+	struct page_info *info, *tmp_info;
 	struct ion_iommu_priv_data *data = NULL;
 
 	if (msm_use_iommu()) {
 		struct scatterlist *sg;
 		struct sg_table *table;
-		unsigned int i;
+		int j;
+		void *ptr = NULL;
+		unsigned int npages_to_vmap, total_pages, num_large_pages = 0;
+		long size_remaining = PAGE_ALIGN(size);
+		unsigned int max_order = ION_IS_CACHED(flags) ? 0 : orders[0];
 
 		data = kmalloc(sizeof(*data), GFP_KERNEL);
 		if (!data)
 			return -ENOMEM;
 
+		INIT_LIST_HEAD(&pages_list);
+		while (size_remaining > 0) {
+			info = alloc_largest_available(size_remaining,
+						max_order);
+			if (!info) {
+				ret = -ENOMEM;
+				goto err_free_data;
+			}
+			list_add_tail(&info->list, &pages_list);
+			size_remaining -= order_to_size(info->order);
+			max_order = info->order;
+			num_large_pages++;
+		}
+
 		data->size = PFN_ALIGN(size);
 		data->nrpages = data->size >> PAGE_SHIFT;
 		data->pages = kzalloc(sizeof(struct page *)*data->nrpages,
 				GFP_KERNEL);
 		if (!data->pages) {
 			ret = -ENOMEM;
-			goto err1;
+			goto err_free_data;
 		}
 
 		table = buffer->sg_table =
@@ -71,18 +145,55 @@
 			ret = -ENOMEM;
 			goto err1;
 		}
-		ret = sg_alloc_table(table, data->nrpages, GFP_KERNEL);
+		ret = sg_alloc_table(table, num_large_pages, GFP_KERNEL);
 		if (ret)
 			goto err2;
 
-		for_each_sg(table->sgl, sg, table->nents, i) {
-			data->pages[i] = alloc_page(
-				GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO);
-			if (!data->pages[i])
-				goto err3;
-
-			sg_set_page(sg, data->pages[i], PAGE_SIZE, 0);
+		i = 0;
+		sg = table->sgl;
+		list_for_each_entry_safe(info, tmp_info, &pages_list, list) {
+			struct page *page = info->page;
+			sg_set_page(sg, page, order_to_size(info->order), 0);
 			sg_dma_address(sg) = sg_phys(sg);
+			sg = sg_next(sg);
+			for (j = 0; j < (1 << info->order); ++j)
+				data->pages[i++] = nth_page(page, j);
+			list_del(&info->list);
+			kfree(info);
+		}
+
+		/*
+		 * As an optimization, we omit __GFP_ZERO from
+		 * alloc_page above and manually zero out all of the
+		 * pages in one fell swoop here. To safeguard against
+		 * insufficient vmalloc space, we only vmap
+		 * `npages_to_vmap' at a time, starting with a
+		 * conservative estimate of 1/8 of the total number of
+		 * vmalloc pages available. Note that the `pages'
+		 * array is composed of all 4K pages, irrespective of
+		 * the size of the pages on the sg list.
+		 */
+		npages_to_vmap = ((VMALLOC_END - VMALLOC_START)/8)
+			>> PAGE_SHIFT;
+		total_pages = data->nrpages;
+		for (i = 0; i < total_pages; i += npages_to_vmap) {
+			npages_to_vmap = min(npages_to_vmap, total_pages - i);
+			for (j = 0; j < MAX_VMAP_RETRIES && npages_to_vmap;
+			     ++j) {
+				ptr = vmap(&data->pages[i], npages_to_vmap,
+					VM_IOREMAP, pgprot_kernel);
+				if (ptr)
+					break;
+				else
+					npages_to_vmap >>= 1;
+			}
+			if (!ptr) {
+				pr_err("Couldn't vmap the pages for zeroing\n");
+				ret = -ENOMEM;
+				goto err3;
+			}
+			memset(ptr, 0, npages_to_vmap * PAGE_SIZE);
+			vunmap(ptr);
 		}
 
 		if (!ION_IS_CACHED(flags))
@@ -102,28 +213,38 @@
 err2:
 	kfree(buffer->sg_table);
 	buffer->sg_table = 0;
-
-	for (i = 0; i < data->nrpages; i++) {
-		if (data->pages[i])
-			__free_page(data->pages[i]);
-	}
-	kfree(data->pages);
 err1:
+	kfree(data->pages);
+err_free_data:
 	kfree(data);
+
+	list_for_each_entry_safe(info, tmp_info, &pages_list, list) {
+		if (info->page)
+			__free_pages(info->page, info->order);
+		list_del(&info->list);
+		kfree(info);
+	}
 	return ret;
 }
 
 static void ion_iommu_heap_free(struct ion_buffer *buffer)
 {
-	struct ion_iommu_priv_data *data = buffer->priv_virt;
 	int i;
+	struct scatterlist *sg;
+	struct sg_table *table = buffer->sg_table;
+	struct ion_iommu_priv_data *data = buffer->priv_virt;
 
+	if (!table)
+		return;
 	if (!data)
 		return;
 
-	for (i = 0; i < data->nrpages; i++)
-		__free_page(data->pages[i]);
+	for_each_sg(table->sgl, sg, table->nents, i)
+		__free_pages(sg_page(sg), get_order(sg_dma_len(sg)));
 
+	sg_free_table(table);
+	kfree(table);
+	table = 0;
 	kfree(data->pages);
 	kfree(data);
 }
@@ -138,7 +259,7 @@
 		return NULL;
 
 	if (!ION_IS_CACHED(buffer->flags))
-		page_prot = pgprot_noncached(page_prot);
+		page_prot = pgprot_writecombine(page_prot);
 
 	buffer->vaddr = vmap(data->pages, data->nrpages, VM_IOREMAP, page_prot);
 
@@ -158,25 +279,34 @@
 int ion_iommu_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer,
 			       struct vm_area_struct *vma)
 {
-	struct ion_iommu_priv_data *data = buffer->priv_virt;
+	struct sg_table *table = buffer->sg_table;
+	unsigned long addr = vma->vm_start;
+	unsigned long offset = vma->vm_pgoff * PAGE_SIZE;
+	struct scatterlist *sg;
 	int i;
-	unsigned long curr_addr;
-	if (!data)
-		return -EINVAL;
 
 	if (!ION_IS_CACHED(buffer->flags))
 		vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
 
-	curr_addr = vma->vm_start;
-	for (i = 0; i < data->nrpages && curr_addr < vma->vm_end; i++) {
-		if (vm_insert_page(vma, curr_addr, data->pages[i])) {
-			/*
-			 * This will fail the mmap which will
-			 * clean up the vma space properly.
-			 */
-			return -EINVAL;
+	for_each_sg(table->sgl, sg, table->nents, i) {
+		struct page *page = sg_page(sg);
+		unsigned long remainder = vma->vm_end - addr;
+		unsigned long len = sg_dma_len(sg);
+
+		if (offset >= sg_dma_len(sg)) {
+			offset -= sg_dma_len(sg);
+			continue;
+		} else if (offset) {
+			page += offset / PAGE_SIZE;
+			len = sg_dma_len(sg) - offset;
+			offset = 0;
 		}
-		curr_addr += PAGE_SIZE;
+		len = min(len, remainder);
+		remap_pfn_range(vma, addr, page_to_pfn(page), len,
+				vma->vm_page_prot);
+		addr += len;
+		if (addr >= vma->vm_end)
+			return 0;
 	}
 	return 0;
 }
@@ -225,8 +355,9 @@
 
 	if (extra) {
 		unsigned long extra_iova_addr = data->iova_addr + buffer->size;
-		ret = msm_iommu_map_extra(domain, extra_iova_addr, extra, SZ_4K,
-					  prot);
+		unsigned long phys_addr = sg_phys(buffer->sg_table->sgl);
+		ret = msm_iommu_map_extra(domain, extra_iova_addr, phys_addr,
+					extra, SZ_4K, prot);
 		if (ret)
 			goto out2;
 	}
@@ -317,10 +448,6 @@
 static void ion_iommu_heap_unmap_dma(struct ion_heap *heap,
 				 struct ion_buffer *buffer)
 {
-	if (buffer->sg_table)
-		sg_free_table(buffer->sg_table);
-	kfree(buffer->sg_table);
-	buffer->sg_table = 0;
 }
 
 static struct ion_heap_ops iommu_heap_ops = {
diff --git a/drivers/gpu/ion/ion_priv.h b/drivers/gpu/ion/ion_priv.h
index 7713875..9d1e90e 100644
--- a/drivers/gpu/ion/ion_priv.h
+++ b/drivers/gpu/ion/ion_priv.h
@@ -2,7 +2,7 @@
  * drivers/gpu/ion/ion_priv.h
  *
  * Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -98,7 +98,6 @@
 	void *vaddr;
 	int dmap_cnt;
 	struct sg_table *sg_table;
-	int umap_cnt;
 	unsigned int iommu_map_cnt;
 	struct rb_root iommu_maps;
 	int marked;
@@ -262,6 +261,9 @@
 #ifdef CONFIG_CMA
 struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *);
 void ion_cma_heap_destroy(struct ion_heap *);
+
+struct ion_heap *ion_secure_cma_heap_create(struct ion_platform_heap *);
+void ion_secure_cma_heap_destroy(struct ion_heap *);
 #endif
 
 struct ion_heap *msm_get_contiguous_heap(void);
@@ -322,4 +324,10 @@
 			int version, void *data, int flags);
 
 int ion_unsecure_handle(struct ion_client *client, struct ion_handle *handle);
+
+int ion_heap_allow_secure_allocation(enum ion_heap_type type);
+
+int ion_heap_allow_heap_secure(enum ion_heap_type type);
+
+int ion_heap_allow_handle_secure(enum ion_heap_type type);
 #endif /* _ION_PRIV_H */
diff --git a/drivers/gpu/ion/ion_system_heap.c b/drivers/gpu/ion/ion_system_heap.c
index 8b63216..f33fc18 100644
--- a/drivers/gpu/ion/ion_system_heap.c
+++ b/drivers/gpu/ion/ion_system_heap.c
@@ -2,7 +2,7 @@
  * drivers/gpu/ion/ion_system_heap.c
  *
  * Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -280,8 +280,9 @@
 
 	extra_iova_addr = data->iova_addr + buffer->size;
 	if (extra) {
-		ret = msm_iommu_map_extra(domain, extra_iova_addr, extra, SZ_4K,
-					  prot);
+		unsigned long phys_addr = sg_phys(table->sgl);
+		ret = msm_iommu_map_extra(domain, extra_iova_addr, phys_addr,
+					extra, SZ_4K, prot);
 		if (ret)
 			goto out2;
 	}
@@ -500,8 +501,9 @@
 
 	if (extra) {
 		unsigned long extra_iova_addr = data->iova_addr + buffer->size;
-		ret = msm_iommu_map_extra(domain, extra_iova_addr, extra, SZ_4K,
-					  prot);
+		unsigned long phys_addr = sg_phys(sglist);
+		ret = msm_iommu_map_extra(domain, extra_iova_addr, phys_addr,
+					extra, SZ_4K, prot);
 		if (ret)
 			goto out2;
 	}
diff --git a/drivers/gpu/ion/msm/ion_cp_common.c b/drivers/gpu/ion/msm/ion_cp_common.c
index 803b04a..8c9b95d 100644
--- a/drivers/gpu/ion/msm/ion_cp_common.c
+++ b/drivers/gpu/ion/msm/ion_cp_common.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2011 Google, Inc
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
@@ -12,9 +12,11 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/memory_alloc.h>
 #include <linux/types.h>
 #include <mach/scm.h>
 
+#include "../ion_priv.h"
 #include "ion_cp_common.h"
 
 #define MEM_PROTECT_LOCK_ID	0x05
@@ -31,6 +33,112 @@
 	unsigned int lock;
 } __attribute__ ((__packed__));
 
+/*  SCM related code for locking down memory for content protection */
+
+#define SCM_CP_LOCK_CMD_ID	0x1
+#define SCM_CP_PROTECT		0x1
+#define SCM_CP_UNPROTECT	0x0
+
+struct cp_lock_msg {
+	unsigned int start;
+	unsigned int end;
+	unsigned int permission_type;
+	unsigned char lock;
+} __attribute__ ((__packed__));
+
+static int ion_cp_protect_mem_v1(unsigned int phy_base, unsigned int size,
+			      unsigned int permission_type)
+{
+	struct cp_lock_msg cmd;
+	cmd.start = phy_base;
+	cmd.end = phy_base + size;
+	cmd.permission_type = permission_type;
+	cmd.lock = SCM_CP_PROTECT;
+
+	return scm_call(SCM_SVC_CP, SCM_CP_LOCK_CMD_ID,
+			&cmd, sizeof(cmd), NULL, 0);
+}
+
+static int ion_cp_unprotect_mem_v1(unsigned int phy_base, unsigned int size,
+				unsigned int permission_type)
+{
+	struct cp_lock_msg cmd;
+	cmd.start = phy_base;
+	cmd.end = phy_base + size;
+	cmd.permission_type = permission_type;
+	cmd.lock = SCM_CP_UNPROTECT;
+
+	return scm_call(SCM_SVC_CP, SCM_CP_LOCK_CMD_ID,
+			&cmd, sizeof(cmd), NULL, 0);
+}
+
+#define V2_CHUNK_SIZE	SZ_1M
+
+static int ion_cp_change_mem_v2(unsigned int phy_base, unsigned int size,
+			      void *data, int lock)
+{
+	enum cp_mem_usage usage = (enum cp_mem_usage) data;
+	unsigned long *chunk_list;
+	int nchunks;
+	int ret;
+	int i;
+
+	if (usage < 0 || usage >= MAX_USAGE)
+		return -EINVAL;
+
+	if (!IS_ALIGNED(size, V2_CHUNK_SIZE)) {
+		pr_err("%s: heap size is not aligned to %x\n",
+			__func__, V2_CHUNK_SIZE);
+		return -EINVAL;
+	}
+
+	nchunks = size / V2_CHUNK_SIZE;
+
+	chunk_list = allocate_contiguous_ebi(sizeof(unsigned long)*nchunks,
+						SZ_4K, 0);
+	if (!chunk_list)
+		return -ENOMEM;
+
+	for (i = 0; i < nchunks; i++)
+		chunk_list[i] = phy_base + i * V2_CHUNK_SIZE;
+
+	ret = ion_cp_change_chunks_state(memory_pool_node_paddr(chunk_list),
+					nchunks, V2_CHUNK_SIZE, usage, lock);
+
+	free_contiguous_memory(chunk_list);
+	return ret;
+}
+
+int ion_cp_protect_mem(unsigned int phy_base, unsigned int size,
+			      unsigned int permission_type, int version,
+			      void *data)
+{
+	switch (version) {
+	case ION_CP_V1:
+		return ion_cp_protect_mem_v1(phy_base, size, permission_type);
+	case ION_CP_V2:
+		return ion_cp_change_mem_v2(phy_base, size, data,
+						SCM_CP_PROTECT);
+	default:
+		return -EINVAL;
+	}
+}
+
+int ion_cp_unprotect_mem(unsigned int phy_base, unsigned int size,
+			      unsigned int permission_type, int version,
+			      void *data)
+{
+	switch (version) {
+	case ION_CP_V1:
+		return ion_cp_unprotect_mem_v1(phy_base, size, permission_type);
+	case ION_CP_V2:
+		return ion_cp_change_mem_v2(phy_base, size, data,
+						SCM_CP_UNPROTECT);
+	default:
+		return -EINVAL;
+	}
+}
+
 int ion_cp_change_chunks_state(unsigned long chunks, unsigned int nchunks,
 				unsigned int chunk_size,
 				enum cp_mem_usage usage,
@@ -51,3 +159,141 @@
 
 }
 
+/* Must be protected by ion_cp_buffer lock */
+static int __ion_cp_protect_buffer(struct ion_buffer *buffer, int version,
+					void *data, int flags)
+{
+	struct ion_cp_buffer *buf = buffer->priv_virt;
+	int ret_value = 0;
+
+	if (atomic_inc_return(&buf->secure_cnt) == 1) {
+		ret_value = ion_cp_protect_mem(buf->buffer,
+				buffer->size, 0,
+				version, data);
+
+		if (ret_value) {
+			pr_err("Failed to secure buffer %p, error %d\n",
+				buffer, ret_value);
+			atomic_dec(&buf->secure_cnt);
+		} else {
+			pr_debug("Protected buffer %p from %pa (size %x)\n",
+				buffer, &buf->buffer,
+				buffer->size);
+			buf->want_delayed_unsecure |=
+				flags & ION_UNSECURE_DELAYED ? 1 : 0;
+			buf->data = data;
+			buf->version = version;
+		}
+	}
+	pr_debug("buffer %p protect count %d\n", buffer,
+		atomic_read(&buf->secure_cnt));
+	BUG_ON(atomic_read(&buf->secure_cnt) < 0);
+	return ret_value;
+}
+
+/* Must be protected by ion_cp_buffer lock */
+static int __ion_cp_unprotect_buffer(struct ion_buffer *buffer, int version,
+					void *data, int force_unsecure)
+{
+	struct ion_cp_buffer *buf = buffer->priv_virt;
+	int ret_value = 0;
+
+	if (force_unsecure) {
+		if (!buf->is_secure || atomic_read(&buf->secure_cnt) == 0)
+			return 0;
+
+		if (atomic_read(&buf->secure_cnt) != 1) {
+			WARN(1, "Forcing unsecure of buffer with outstanding secure count %d!\n",
+				atomic_read(&buf->secure_cnt));
+			atomic_set(&buf->secure_cnt, 1);
+		}
+	}
+
+	if (atomic_dec_and_test(&buf->secure_cnt)) {
+		ret_value = ion_cp_unprotect_mem(
+			buf->buffer, buffer->size,
+			0, version, data);
+
+		if (ret_value) {
+			pr_err("Failed to unsecure buffer %p, error %d\n",
+				buffer, ret_value);
+			/*
+			 * If the force unsecure is happening, the buffer
+			 * is being destroyed. We failed to unsecure the
+			 * buffer even though the memory is given back.
+			 * Just die now rather than discovering later what
+			 * happens when trying to use the secured memory as
+			 * unsecured...
+			 */
+			BUG_ON(force_unsecure);
+			/* Bump the count back up one to try again later */
+			atomic_inc(&buf->secure_cnt);
+		} else {
+			buf->version = -1;
+			buf->data = NULL;
+		}
+	}
+	pr_debug("buffer %p unprotect count %d\n", buffer,
+		atomic_read(&buf->secure_cnt));
+	BUG_ON(atomic_read(&buf->secure_cnt) < 0);
+	return ret_value;
+}
+
+int ion_cp_secure_buffer(struct ion_buffer *buffer, int version, void *data,
+				int flags)
+{
+	int ret_value;
+	struct ion_cp_buffer *buf = buffer->priv_virt;
+
+	mutex_lock(&buf->lock);
+	if (!buf->is_secure) {
+		pr_err("%s: buffer %p was not allocated as secure\n",
+			__func__, buffer);
+		ret_value = -EINVAL;
+		goto out_unlock;
+	}
+
+	if (ION_IS_CACHED(buffer->flags)) {
+		pr_err("%s: buffer %p was allocated as cached\n",
+			__func__, buffer);
+		ret_value = -EINVAL;
+		goto out_unlock;
+	}
+
+	if (atomic_read(&buf->map_cnt)) {
+		pr_err("%s: cannot secure buffer %p with outstanding mappings. Total count: %d",
+			__func__, buffer, atomic_read(&buf->map_cnt));
+		ret_value = -EINVAL;
+		goto out_unlock;
+	}
+
+	if (atomic_read(&buf->secure_cnt)) {
+		if (buf->version != version || buf->data != data) {
+			pr_err("%s: Trying to re-secure buffer with different values",
+				__func__);
+			pr_err("Last secured version: %d Currrent %d\n",
+				buf->version, version);
+			pr_err("Last secured data: %p current %p\n",
+				buf->data, data);
+			ret_value = -EINVAL;
+			goto out_unlock;
+		}
+	}
+	ret_value = __ion_cp_protect_buffer(buffer, version, data, flags);
+
+out_unlock:
+	mutex_unlock(&buf->lock);
+	return ret_value;
+}
+
+int ion_cp_unsecure_buffer(struct ion_buffer *buffer, int force_unsecure)
+{
+	int ret_value = 0;
+	struct ion_cp_buffer *buf = buffer->priv_virt;
+
+	mutex_lock(&buf->lock);
+	ret_value = __ion_cp_unprotect_buffer(buffer, buf->version, buf->data,
+						force_unsecure);
+	mutex_unlock(&buf->lock);
+	return ret_value;
+}
diff --git a/drivers/gpu/ion/msm/ion_cp_common.h b/drivers/gpu/ion/msm/ion_cp_common.h
index 634473f..8ae19be 100644
--- a/drivers/gpu/ion/msm/ion_cp_common.h
+++ b/drivers/gpu/ion/msm/ion_cp_common.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -20,6 +20,26 @@
 #define ION_CP_V1	1
 #define ION_CP_V2	2
 
+struct ion_cp_buffer {
+	phys_addr_t buffer;
+	atomic_t secure_cnt;
+	int is_secure;
+	int want_delayed_unsecure;
+	/*
+	 * Currently all user/kernel mapping is protected by the heap lock.
+	 * This is sufficient to protect the map count as well. The lock
+	 * should be used to protect map_cnt if the whole heap lock is
+	 * ever removed.
+	 */
+	atomic_t map_cnt;
+	/*
+	 * protects secure_cnt for securing.
+	 */
+	struct mutex lock;
+	int version;
+	void *data;
+};
+
 #if defined(CONFIG_ION_MSM)
 /*
  * ion_cp2_protect_mem - secures memory via trustzone
@@ -37,6 +57,18 @@
 			unsigned int chunk_size, enum cp_mem_usage usage,
 			int lock);
 
+int ion_cp_protect_mem(unsigned int phy_base, unsigned int size,
+			unsigned int permission_type, int version,
+			void *data);
+
+int ion_cp_unprotect_mem(unsigned int phy_base, unsigned int size,
+				unsigned int permission_type, int version,
+				void *data);
+
+int ion_cp_secure_buffer(struct ion_buffer *buffer, int version, void *data,
+				int flags);
+
+int ion_cp_unsecure_buffer(struct ion_buffer *buffer, int force_unsecure);
 #else
 static inline int ion_cp_change_chunks_state(unsigned long chunks,
 			unsigned int nchunks, unsigned int chunk_size,
@@ -44,6 +76,32 @@
 {
 	return -ENODEV;
 }
+
+static inline int ion_cp_protect_mem(unsigned int phy_base, unsigned int size,
+			unsigned int permission_type, int version,
+			void *data)
+{
+	return -ENODEV;
+}
+
+static inline int ion_cp_unprotect_mem(unsigned int phy_base, unsigned int size,
+				unsigned int permission_type, int version,
+				void *data)
+{
+	return -ENODEV;
+}
+
+static inline int ion_cp_secure_buffer(struct ion_buffer *buffer, int version,
+				void *data, int flags)
+{
+	return -ENODEV;
+}
+
+static inline int ion_cp_unsecure_buffer(struct ion_buffer *buffer,
+				int force_unsecure)
+{
+	return -ENODEV;
+}
 #endif
 
 #endif
diff --git a/drivers/gpu/ion/msm/msm_ion.c b/drivers/gpu/ion/msm/msm_ion.c
index 697587b..832a9a1 100644
--- a/drivers/gpu/ion/msm/msm_ion.c
+++ b/drivers/gpu/ion/msm/msm_ion.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -19,6 +19,7 @@
 #include <linux/memory_alloc.h>
 #include <linux/fmem.h>
 #include <linux/of.h>
+#include <linux/of_platform.h>
 #include <linux/mm.h>
 #include <linux/mm_types.h>
 #include <linux/sched.h>
@@ -45,6 +46,7 @@
 };
 
 
+#ifdef CONFIG_OF
 static struct ion_heap_desc ion_heap_meta[] = {
 	{
 		.id	= ION_SYSTEM_HEAP_ID,
@@ -53,7 +55,7 @@
 	},
 	{
 		.id	= ION_CP_MM_HEAP_ID,
-		.type	= ION_HEAP_TYPE_CP,
+		.type	= ION_HEAP_TYPE_SECURE_DMA,
 		.name	= ION_MM_HEAP_NAME,
 		.permission_type = IPT_TYPE_MM_CARVEOUT,
 	},
@@ -109,6 +111,7 @@
 		.name	= ION_CAMERA_HEAP_NAME,
 	},
 };
+#endif
 
 struct ion_client *msm_ion_client_create(unsigned int heap_mask,
 					const char *name)
@@ -368,6 +371,7 @@
 	}
 }
 
+#ifdef CONFIG_OF
 static int msm_init_extra_data(struct ion_platform_heap *heap,
 			       const struct ion_heap_desc *heap_desc)
 {
@@ -550,12 +554,13 @@
 	}
 }
 
-static struct ion_platform_data *msm_ion_parse_dt(
-					const struct device_node *dt_node)
+static struct ion_platform_data *msm_ion_parse_dt(struct platform_device *pdev)
 {
 	struct ion_platform_data *pdata = 0;
 	struct ion_platform_heap *heaps = NULL;
 	struct device_node *node;
+	struct platform_device *new_dev = NULL;
+	const struct device_node *dt_node = pdev->dev.of_node;
 	uint32_t val = 0;
 	int ret = 0;
 	uint32_t num_heaps = 0;
@@ -581,6 +586,13 @@
 	pdata->nr = num_heaps;
 
 	for_each_child_of_node(dt_node, node) {
+		new_dev = of_platform_device_create(node, NULL, &pdev->dev);
+		if (!new_dev) {
+			pr_err("Failed to create device %s\n", node->name);
+			goto free_heaps;
+		}
+
+		pdata->heaps[idx].priv = &new_dev->dev;
 		/**
 		 * TODO: Replace this with of_get_address() when this patch
 		 * gets merged: http://
@@ -614,6 +626,17 @@
 	free_pdata(pdata);
 	return ERR_PTR(ret);
 }
+#else
+static struct ion_platform_data *msm_ion_parse_dt(struct platform_device *pdev)
+{
+	return NULL;
+}
+
+static void free_pdata(const struct ion_platform_data *pdata)
+{
+
+}
+#endif
 
 static int check_vaddr_bounds(unsigned long start, unsigned long end)
 {
@@ -637,6 +660,23 @@
 	return ret;
 }
 
+int ion_heap_allow_secure_allocation(enum ion_heap_type type)
+{
+	return type == ((enum ion_heap_type) ION_HEAP_TYPE_CP) ||
+		type == ((enum ion_heap_type) ION_HEAP_TYPE_SECURE_DMA);
+}
+
+int ion_heap_allow_handle_secure(enum ion_heap_type type)
+{
+	return type == ((enum ion_heap_type) ION_HEAP_TYPE_CP) ||
+		type == ((enum ion_heap_type) ION_HEAP_TYPE_SECURE_DMA);
+}
+
+int ion_heap_allow_heap_secure(enum ion_heap_type type)
+{
+	return type == ((enum ion_heap_type) ION_HEAP_TYPE_CP);
+}
+
 static long msm_ion_custom_ioctl(struct ion_client *client,
 				unsigned int cmd,
 				unsigned long arg)
@@ -694,22 +734,6 @@
 		break;
 
 	}
-	case ION_IOC_GET_FLAGS:
-	{
-		struct ion_flag_data data;
-		int ret;
-		if (copy_from_user(&data, (void __user *)arg,
-					sizeof(struct ion_flag_data)))
-			return -EFAULT;
-
-		ret = ion_handle_get_flags(client, data.handle, &data.flags);
-		if (ret < 0)
-			return ret;
-		if (copy_to_user((void __user *)arg, &data,
-					sizeof(struct ion_flag_data)))
-			return -EFAULT;
-		break;
-	}
 	default:
 		return -ENOTTY;
 	}
@@ -723,7 +747,7 @@
 	int err = -1;
 	int i;
 	if (pdev->dev.of_node) {
-		pdata = msm_ion_parse_dt(pdev->dev.of_node);
+		pdata = msm_ion_parse_dt(pdev);
 		if (IS_ERR(pdata)) {
 			err = PTR_ERR(pdata);
 			goto out;
@@ -774,10 +798,10 @@
 
 		ion_device_add_heap(idev, heaps[i]);
 	}
+	check_for_heap_overlap(pdata->heaps, num_heaps);
 	if (pdata_needs_to_be_freed)
 		free_pdata(pdata);
 
-	check_for_heap_overlap(pdata->heaps, num_heaps);
 	platform_set_drvdata(pdev, idev);
 	return 0;
 
diff --git a/drivers/gpu/msm/Makefile b/drivers/gpu/msm/Makefile
index aacd355..3441afa 100644
--- a/drivers/gpu/msm/Makefile
+++ b/drivers/gpu/msm/Makefile
@@ -1,4 +1,4 @@
-ccflags-y := -Iinclude/drm -Idrivers/gpu/msm
+ccflags-y := -Iinclude/uapi/drm -Iinclude/drm -Idrivers/gpu/msm
 
 msm_kgsl_core-y = \
 	kgsl.o \
@@ -9,7 +9,8 @@
 	kgsl_mmu.o \
 	kgsl_gpummu.o \
 	kgsl_iommu.o \
-	kgsl_snapshot.o
+	kgsl_snapshot.o \
+	kgsl_events.o
 
 msm_kgsl_core-$(CONFIG_DEBUG_FS) += kgsl_debugfs.o
 msm_kgsl_core-$(CONFIG_MSM_KGSL_CFF_DUMP) += kgsl_cffdump.o
diff --git a/drivers/gpu/msm/a2xx_reg.h b/drivers/gpu/msm/a2xx_reg.h
index 41cb601..c70c4eb 100644
--- a/drivers/gpu/msm/a2xx_reg.h
+++ b/drivers/gpu/msm/a2xx_reg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-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
diff --git a/drivers/gpu/msm/a3xx_reg.h b/drivers/gpu/msm/a3xx_reg.h
index 90f14e6..e245cfc 100644
--- a/drivers/gpu/msm/a3xx_reg.h
+++ b/drivers/gpu/msm/a3xx_reg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -67,6 +67,10 @@
 #define A3XX_RBBM_INT_0_STATUS 0x064
 #define A3XX_RBBM_PERFCTR_CTL 0x80
 #define A3XX_RBBM_GPU_BUSY_MASKED 0x88
+#define A3XX_RBBM_PERFCTR_SP_5_LO 0xDC
+#define A3XX_RBBM_PERFCTR_SP_5_HI 0xDD
+#define A3XX_RBBM_PERFCTR_SP_6_LO 0xDE
+#define A3XX_RBBM_PERFCTR_SP_6_HI 0xDF
 #define A3XX_RBBM_PERFCTR_SP_7_LO 0xE0
 #define A3XX_RBBM_PERFCTR_SP_7_HI 0xE1
 #define A3XX_RBBM_RBBM_CTL 0x100
@@ -164,6 +168,8 @@
 #define A3XX_VPC_VPC_DEBUG_RAM_READ 0xE62
 #define A3XX_UCHE_CACHE_MODE_CONTROL_REG 0xE82
 #define A3XX_UCHE_CACHE_INVALIDATE0_REG 0xEA0
+#define A3XX_SP_PERFCOUNTER5_SELECT 0xEC9
+#define A3XX_SP_PERFCOUNTER6_SELECT 0xECA
 #define A3XX_SP_PERFCOUNTER7_SELECT 0xECB
 #define A3XX_GRAS_CL_CLIP_CNTL 0x2040
 #define A3XX_GRAS_CL_GB_CLIP_ADJ 0x2044
@@ -531,13 +537,19 @@
 #define RBBM_BLOCK_ID_MARB_3           0x2b
 
 /* RBBM_CLOCK_CTL default value */
-#define A305_RBBM_CLOCK_CTL_DEFAULT 0xAAAAAAAA
-#define A320_RBBM_CLOCK_CTL_DEFAULT 0xBFFFFFFF
-#define A330_RBBM_CLOCK_CTL_DEFAULT 0xBFFCFFFF
+#define A305_RBBM_CLOCK_CTL_DEFAULT   0xAAAAAAAA
+#define A320_RBBM_CLOCK_CTL_DEFAULT   0xBFFFFFFF
+#define A330_RBBM_CLOCK_CTL_DEFAULT   0xBFFCFFFF
+#define A330v2_RBBM_CLOCK_CTL_DEFAULT 0xBFFCFFFF
+#define A305B_RBBM_CLOCK_CTL_DEFAULT  0xAAAAAAAA
 
-#define A330_RBBM_GPR0_CTL_DEFAULT  0x00000000
+#define A330_RBBM_GPR0_CTL_DEFAULT    0x00000000
+#define A330v2_RBBM_GPR0_CTL_DEFAULT  0x00000000
 
 /* COUNTABLE FOR SP PERFCOUNTER */
 #define SP_FS_FULL_ALU_INSTRUCTIONS    0x0E
+#define SP_ALU_ACTIVE_CYCLES           0x1D
+#define SP0_ICL1_MISSES                0x1A
+#define SP_FS_CFLOW_INSTRUCTIONS       0x0C
 
 #endif
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 24be1b0..b1a45bf 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2002,2007-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
@@ -130,6 +130,10 @@
 	REG_CP_IB2_BASE,
 	REG_CP_IB2_BUFSZ,
 	0,
+	0,
+	0,
+	0,
+	0,
 	0
 };
 
@@ -156,10 +160,10 @@
 	/* size of gmem for gpu*/
 	unsigned int gmem_size;
 	/* version of pm4 microcode that supports sync_lock
-	   between CPU and GPU for SMMU-v1 programming */
+	   between CPU and GPU for IOMMU-v0 programming */
 	unsigned int sync_lock_pm4_ver;
 	/* version of pfp microcode that supports sync_lock
-	   between CPU and GPU for SMMU-v1 programming */
+	   between CPU and GPU for IOMMU-v0 programming */
 	unsigned int sync_lock_pfp_ver;
 } adreno_gpulist[] = {
 	{ ADRENO_REV_A200, 0, 2, ANY_ID, ANY_ID,
@@ -188,16 +192,19 @@
 		"a225_pm4.fw", "a225_pfp.fw", &adreno_a2xx_gpudev,
 		1536, 768, 3, SZ_512K, 0x225011, 0x225002 },
 	/* A3XX doesn't use the pix_shader_start */
-	{ ADRENO_REV_A305, 3, 0, 5, ANY_ID,
+	{ ADRENO_REV_A305, 3, 0, 5, 0,
 		"a300_pm4.fw", "a300_pfp.fw", &adreno_a3xx_gpudev,
 		512, 0, 2, SZ_256K, 0x3FF037, 0x3FF016 },
 	/* A3XX doesn't use the pix_shader_start */
 	{ ADRENO_REV_A320, 3, 2, ANY_ID, ANY_ID,
 		"a300_pm4.fw", "a300_pfp.fw", &adreno_a3xx_gpudev,
 		512, 0, 2, SZ_512K, 0x3FF037, 0x3FF016 },
-	{ ADRENO_REV_A330, 3, 3, 0, 0,
+	{ ADRENO_REV_A330, 3, 3, 0, ANY_ID,
 		"a330_pm4.fw", "a330_pfp.fw", &adreno_a3xx_gpudev,
 		512, 0, 2, SZ_1M, NO_VER, NO_VER },
+	{ ADRENO_REV_A305B, 3, 0, 5, 0x10,
+		"a330_pm4.fw", "a330_pfp.fw", &adreno_a3xx_gpudev,
+		512, 0, 2, SZ_128K, NO_VER, NO_VER },
 };
 
 static irqreturn_t adreno_irq_handler(struct kgsl_device *device)
@@ -291,7 +298,7 @@
 					uint32_t flags)
 {
 	unsigned int pt_val, reg_pt_val;
-	unsigned int link[250];
+	unsigned int link[230];
 	unsigned int *cmds = &link[0];
 	int sizedwords = 0;
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
@@ -304,6 +311,8 @@
 	num_iommu_units = kgsl_mmu_get_num_iommu_units(&device->mmu);
 
 	context = idr_find(&device->context_idr, context_id);
+	if (context == NULL)
+		return;
 	adreno_ctx = context->devctxt;
 
 	if (kgsl_mmu_enable_clk(&device->mmu,
@@ -454,6 +463,8 @@
 	 */
 	if (!kgsl_cff_dump_enable && adreno_dev->drawctxt_active) {
 		context = idr_find(&device->context_idr, context_id);
+		if (context == NULL)
+			return;
 		adreno_ctx = context->devctxt;
 
 		if (flags & KGSL_MMUFLAGS_PTUPDATE) {
@@ -748,6 +759,10 @@
 		&pdata->init_level))
 		pdata->init_level = 1;
 
+	if (adreno_of_read_property(parent, "qcom,step-pwrlevel",
+		&pdata->step_mul))
+		pdata->step_mul = 1;
+
 	if (pdata->init_level < 0 || pdata->init_level > pdata->num_levels) {
 		KGSL_CORE_ERR("Initial power level out of range\n");
 		pdata->init_level = 1;
@@ -973,9 +988,17 @@
 			goto err;
 		}
 
-		if (adreno_of_read_property(child, "qcom,iommu-ctx-sids",
-			&ctxs[ctx_index].ctx_id))
+		ret = of_property_read_u32_array(child, "reg", reg_val, 2);
+		if (ret) {
+			KGSL_CORE_ERR("Unable to read KGSL IOMMU 'reg'\n");
 			goto err;
+		}
+		if (msm_soc_version_supports_iommu_v0())
+			ctxs[ctx_index].ctx_id = (reg_val[0] -
+				data->physstart) >> KGSL_IOMMU_CTX_SHIFT;
+		else
+			ctxs[ctx_index].ctx_id = ((reg_val[0] -
+				data->physstart) >> KGSL_IOMMU_CTX_SHIFT) - 8;
 
 		ctx_index++;
 	}
@@ -1030,10 +1053,9 @@
 	if (ret)
 		goto err;
 
-	/* Default value is 83, if not found in DT */
 	if (adreno_of_read_property(pdev->dev.of_node, "qcom,idle-timeout",
 		&pdata->idle_timeout))
-		pdata->idle_timeout = 83;
+		pdata->idle_timeout = HZ/12;
 
 	if (adreno_of_read_property(pdev->dev.of_node, "qcom,nap-allowed",
 		&pdata->nap_allowed))
@@ -1093,7 +1115,8 @@
 static int
 adreno_ocmem_gmem_malloc(struct adreno_device *adreno_dev)
 {
-	if (!adreno_is_a330(adreno_dev))
+	if (!(adreno_is_a330(adreno_dev) ||
+		adreno_is_a305b(adreno_dev)))
 		return 0;
 
 	/* OCMEM is only needed once, do not support consective allocation */
@@ -1114,7 +1137,8 @@
 static void
 adreno_ocmem_gmem_free(struct adreno_device *adreno_dev)
 {
-	if (!adreno_is_a330(adreno_dev))
+	if (!(adreno_is_a330(adreno_dev) ||
+		adreno_is_a305b(adreno_dev)))
 		return;
 
 	if (adreno_dev->ocmem_hdl == NULL)
@@ -1263,6 +1287,10 @@
 	if (adreno_is_a3xx(adreno_dev)) {
 		hang_detect_regs[6] = A3XX_RBBM_PERFCTR_SP_7_LO;
 		hang_detect_regs[7] = A3XX_RBBM_PERFCTR_SP_7_HI;
+		hang_detect_regs[8] = A3XX_RBBM_PERFCTR_SP_6_LO;
+		hang_detect_regs[9] = A3XX_RBBM_PERFCTR_SP_6_HI;
+		hang_detect_regs[10] = A3XX_RBBM_PERFCTR_SP_5_LO;
+		hang_detect_regs[11] = A3XX_RBBM_PERFCTR_SP_5_HI;
 	}
 
 	status = kgsl_mmu_start(device);
@@ -1282,14 +1310,22 @@
 	device->ftbl->irqctrl(device, 1);
 
 	status = adreno_ringbuffer_start(&adreno_dev->ringbuffer, init_ram);
-	if (status == 0) {
-		/* While recovery is on we do not want timer to
-		 * fire and attempt to change any device state */
-		if (KGSL_STATE_DUMP_AND_RECOVER != device->state)
-			mod_timer(&device->idle_timer, jiffies + FIRST_TIMEOUT);
-		return 0;
-	}
+	if (status)
+		goto error_irq_off;
 
+	/*
+	 * While recovery is on we do not want timer to
+	 * fire and attempt to change any device state
+	 */
+
+	if (KGSL_STATE_DUMP_AND_RECOVER != device->state)
+		mod_timer(&device->idle_timer, jiffies + FIRST_TIMEOUT);
+
+	device->reset_counter++;
+
+	return 0;
+
+error_irq_off:
 	kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
 
 error_mmu_off:
@@ -1342,7 +1378,7 @@
 			adreno_context->flags |= CTXT_FLAGS_GPU_HANG;
 		} else if (KGSL_CTX_STAT_GUILTY_CONTEXT_RESET_EXT !=
 			context->reset_status) {
-			if (adreno_context->flags & (CTXT_FLAGS_GPU_HANG ||
+			if (adreno_context->flags & (CTXT_FLAGS_GPU_HANG |
 				CTXT_FLAGS_GPU_HANG_RECOVERED))
 				context->reset_status =
 				KGSL_CTX_STAT_GUILTY_CONTEXT_RESET_EXT;
@@ -1622,6 +1658,11 @@
 			KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
 			eoptimestamp),
 			rb->timestamp[KGSL_MEMSTORE_GLOBAL]);
+
+	/* switch to NULL ctxt */
+	if (adreno_dev->drawctxt_active != NULL)
+		adreno_drawctxt_switch(adreno_dev, NULL, 0);
+
 done:
 	adreno_set_max_ts_for_bad_ctxs(device);
 	adreno_mark_context_status(device, ret);
@@ -1784,6 +1825,7 @@
 				unsigned int sizebytes)
 {
 	int status = -EINVAL;
+	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
 
 	switch (type) {
 	case KGSL_PROP_PWRCTRL: {
@@ -1803,10 +1845,11 @@
 			if (enable) {
 				if (pdata->nap_allowed)
 					device->pwrctrl.nap_allowed = true;
-
+				adreno_dev->fast_hang_detect = 1;
 				kgsl_pwrscale_enable(device);
 			} else {
 				device->pwrctrl.nap_allowed = false;
+				adreno_dev->fast_hang_detect = 0;
 				kgsl_pwrscale_disable(device);
 			}
 
@@ -1957,8 +2000,17 @@
 		/* Is the ring buffer is empty? */
 		GSL_RB_GET_READPTR(rb, &rb->rptr);
 		if (!device->active_cnt && (rb->rptr == rb->wptr)) {
-			/* Is the core idle? */
-			status = is_adreno_rbbm_status_idle(device);
+			/*
+			 * Are there interrupts pending? If so then pretend we
+			 * are not idle - this avoids the possiblity that we go
+			 * to a lower power state without handling interrupts
+			 * first.
+			 */
+
+			if (!adreno_dev->gpudev->irq_pending(adreno_dev)) {
+				/* Is the core idle? */
+				status = is_adreno_rbbm_status_idle(device);
+			}
 		}
 	} else {
 		status = true;
@@ -2142,125 +2194,90 @@
 	return context_id;
 }
 
-static void adreno_next_event(struct kgsl_device *device,
-		struct kgsl_event *event)
-{
-	int status;
-	unsigned int ref_ts, enableflag;
-	unsigned int context_id = _get_context_id(event->context);
-	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
-
-	status = kgsl_check_timestamp(device, event->context, event->timestamp);
-	if (!status) {
-		kgsl_sharedmem_readl(&device->memstore, &enableflag,
-			KGSL_MEMSTORE_OFFSET(context_id, ts_cmp_enable));
-		/*
-		 * Barrier is needed here to make sure the read from memstore
-		 * has posted
-		 */
-
-		mb();
-
-		if (enableflag) {
-			kgsl_sharedmem_readl(&device->memstore, &ref_ts,
-				KGSL_MEMSTORE_OFFSET(context_id,
-					ref_wait_ts));
-
-			/* Make sure the memstore read has posted */
-			mb();
-			if (timestamp_cmp(ref_ts, event->timestamp) >= 0) {
-				kgsl_sharedmem_writel(&device->memstore,
-				KGSL_MEMSTORE_OFFSET(context_id,
-					ref_wait_ts), event->timestamp);
-				/* Make sure the memstore write is posted */
-				wmb();
-			}
-		} else {
-			unsigned int cmds[2];
-			kgsl_sharedmem_writel(&device->memstore,
-				KGSL_MEMSTORE_OFFSET(context_id,
-					ref_wait_ts), event->timestamp);
-			enableflag = 1;
-			kgsl_sharedmem_writel(&device->memstore,
-				KGSL_MEMSTORE_OFFSET(context_id,
-					ts_cmp_enable), enableflag);
-
-			/* Make sure the memstore write gets posted */
-			wmb();
-
-			/*
-			 * submit a dummy packet so that even if all
-			 * commands upto timestamp get executed we will still
-			 * get an interrupt
-			 */
-			cmds[0] = cp_type3_packet(CP_NOP, 1);
-			cmds[1] = 0;
-
-			if (adreno_dev->drawctxt_active)
-				adreno_ringbuffer_issuecmds_intr(device,
-						event->context, &cmds[0], 2);
-		}
-	}
-}
-
-static int kgsl_check_interrupt_timestamp(struct kgsl_device *device,
+static unsigned int adreno_check_hw_ts(struct kgsl_device *device,
 		struct kgsl_context *context, unsigned int timestamp)
 {
-	int status;
+	int status = 0;
 	unsigned int ref_ts, enableflag;
-	unsigned int context_id;
+	unsigned int context_id = _get_context_id(context);
 
-	mutex_lock(&device->mutex);
-	context_id = _get_context_id(context);
 	/*
 	 * If the context ID is invalid, we are in a race with
 	 * the context being destroyed by userspace so bail.
 	 */
 	if (context_id == KGSL_CONTEXT_INVALID) {
 		KGSL_DRV_WARN(device, "context was detached");
-		status = -EINVAL;
-		goto unlock;
+		return -EINVAL;
 	}
 
 	status = kgsl_check_timestamp(device, context, timestamp);
-	if (!status) {
-		kgsl_sharedmem_readl(&device->memstore, &enableflag,
-			KGSL_MEMSTORE_OFFSET(context_id, ts_cmp_enable));
-		mb();
+	if (status)
+		return status;
 
-		if (enableflag) {
-			kgsl_sharedmem_readl(&device->memstore, &ref_ts,
+	kgsl_sharedmem_readl(&device->memstore, &enableflag,
+			KGSL_MEMSTORE_OFFSET(context_id, ts_cmp_enable));
+	/*
+	 * Barrier is needed here to make sure the read from memstore
+	 * has posted
+	 */
+
+	mb();
+
+	if (enableflag) {
+		kgsl_sharedmem_readl(&device->memstore, &ref_ts,
 				KGSL_MEMSTORE_OFFSET(context_id,
 					ref_wait_ts));
-			mb();
-			if (timestamp_cmp(ref_ts, timestamp) >= 0) {
-				kgsl_sharedmem_writel(&device->memstore,
+
+		/* Make sure the memstore read has posted */
+		mb();
+		if (timestamp_cmp(ref_ts, timestamp) >= 0) {
+			kgsl_sharedmem_writel(&device->memstore,
+					KGSL_MEMSTORE_OFFSET(context_id,
+						ref_wait_ts), timestamp);
+			/* Make sure the memstore write is posted */
+			wmb();
+		}
+	} else {
+		kgsl_sharedmem_writel(&device->memstore,
 				KGSL_MEMSTORE_OFFSET(context_id,
 					ref_wait_ts), timestamp);
-				wmb();
-			}
-		} else {
-			unsigned int cmds[2];
-			kgsl_sharedmem_writel(&device->memstore,
-				KGSL_MEMSTORE_OFFSET(context_id,
-					ref_wait_ts), timestamp);
-			enableflag = 1;
-			kgsl_sharedmem_writel(&device->memstore,
+		enableflag = 1;
+		kgsl_sharedmem_writel(&device->memstore,
 				KGSL_MEMSTORE_OFFSET(context_id,
 					ts_cmp_enable), enableflag);
-			wmb();
-			/* submit a dummy packet so that even if all
-			* commands upto timestamp get executed we will still
-			* get an interrupt */
-			cmds[0] = cp_type3_packet(CP_NOP, 1);
-			cmds[1] = 0;
 
-			if (context)
-				adreno_ringbuffer_issuecmds_intr(device,
-						context, &cmds[0], 2);
+		/* Make sure the memstore write gets posted */
+		wmb();
+
+		/*
+		 * submit a dummy packet so that even if all
+		 * commands upto timestamp get executed we will still
+		 * get an interrupt
+		 */
+
+		if (context && device->state != KGSL_STATE_SLUMBER) {
+			adreno_ringbuffer_issuecmds(device, context->devctxt,
+					KGSL_CMD_FLAGS_NONE, NULL, 0);
 		}
 	}
-unlock:
+
+	return 0;
+}
+
+/* Return 1 if the event timestmp has already passed, 0 if it was marked */
+static int adreno_next_event(struct kgsl_device *device,
+		struct kgsl_event *event)
+{
+	return adreno_check_hw_ts(device, event->context, event->timestamp);
+}
+
+static int adreno_check_interrupt_timestamp(struct kgsl_device *device,
+		struct kgsl_context *context, unsigned int timestamp)
+{
+	int status;
+
+	mutex_lock(&device->mutex);
+	status = adreno_check_hw_ts(device, context, timestamp);
 	mutex_unlock(&device->mutex);
 
 	return status;
@@ -2291,6 +2308,7 @@
 	unsigned int curr_reg_val[hang_detect_regs_count];
 	unsigned int hang_detected = 1;
 	unsigned int i;
+	static unsigned long next_hang_detect_time;
 
 	if (!adreno_dev->fast_hang_detect)
 		return 0;
@@ -2314,6 +2332,18 @@
 		return 0;
 	}
 
+	/*
+	 * Time interval between hang detection should be KGSL_TIMEOUT_PART
+	 * or more, if next hang detection is requested < KGSL_TIMEOUT_PART
+	 * from the last time do nothing.
+	 */
+	if ((next_hang_detect_time) &&
+		(time_before(jiffies, next_hang_detect_time)))
+			return 0;
+	else
+		next_hang_detect_time = (jiffies +
+			msecs_to_jiffies(KGSL_TIMEOUT_PART-1));
+
 	for (i = 0; i < hang_detect_regs_count; i++) {
 
 		if (hang_detect_regs[i] == 0)
@@ -2458,9 +2488,6 @@
 	do {
 		long status;
 
-		if (wait > (msecs - time_elapsed))
-			wait = msecs - time_elapsed;
-
 		/*
 		 * if the timestamp happens while we're not
 		 * waiting, there's a chance that an interrupt
@@ -2497,7 +2524,7 @@
 		/* Wait for a timestamp event */
 		status = kgsl_wait_event_interruptible_timeout(
 			device->wait_queue,
-			kgsl_check_interrupt_timestamp(device, context,
+			adreno_check_interrupt_timestamp(device, context,
 				timestamp), msecs_to_jiffies(wait), io);
 
 		mutex_lock(&device->mutex);
@@ -2512,7 +2539,6 @@
 			ret = (status > 0) ? 0 : (int) status;
 			break;
 		}
-
 		time_elapsed += wait;
 
 		/* If user specified timestamps are being used, wait at least
@@ -2541,10 +2567,14 @@
 		}
 
 		/*
-		 * all subsequent trips through the loop wait the full
-		 * KGSL_TIMEOUT_PART interval
+		 * We want to wait the floor of KGSL_TIMEOUT_PART
+		 * and (msecs - time_elapsed).
 		 */
-		wait = KGSL_TIMEOUT_PART;
+
+		if (KGSL_TIMEOUT_PART < (msecs - time_elapsed))
+			wait = KGSL_TIMEOUT_PART;
+		else
+			wait = (msecs - time_elapsed);
 
 	} while (!msecs || time_elapsed < msecs);
 
@@ -2574,7 +2604,8 @@
 		break;
 	}
 	case KGSL_TIMESTAMP_CONSUMED:
-		adreno_regread(device, REG_CP_TIMESTAMP, &timestamp);
+		kgsl_sharedmem_readl(&device->memstore, &timestamp,
+			KGSL_MEMSTORE_OFFSET(context_id, soptimestamp));
 		break;
 	case KGSL_TIMESTAMP_RETIRED:
 		kgsl_sharedmem_readl(&device->memstore, &timestamp,
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 836192c..b1cab9b 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
@@ -72,6 +72,7 @@
 	ADRENO_REV_A305 = 305,
 	ADRENO_REV_A320 = 320,
 	ADRENO_REV_A330 = 330,
+	ADRENO_REV_A305B = 335,
 };
 
 struct adreno_gpudev;
@@ -124,6 +125,7 @@
 					struct adreno_context *);
 	irqreturn_t (*irq_handler)(struct adreno_device *);
 	void (*irq_control)(struct adreno_device *, int);
+	unsigned int (*irq_pending)(struct adreno_device *);
 	void * (*snapshot)(struct adreno_device *, void *, int *, int);
 	void (*rb_init)(struct adreno_device *, struct adreno_ringbuffer *);
 	void (*start)(struct adreno_device *);
@@ -265,6 +267,11 @@
 	return (adreno_dev->gpurev == ADRENO_REV_A305);
 }
 
+static inline int adreno_is_a305b(struct adreno_device *adreno_dev)
+{
+	return (adreno_dev->gpurev == ADRENO_REV_A305B);
+}
+
 static inline int adreno_is_a320(struct adreno_device *adreno_dev)
 {
 	return (adreno_dev->gpurev == ADRENO_REV_A320);
@@ -275,6 +282,12 @@
 	return (adreno_dev->gpurev == ADRENO_REV_A330);
 }
 
+static inline int adreno_is_a330v2(struct adreno_device *adreno_dev)
+{
+	return ((adreno_dev->gpurev == ADRENO_REV_A330) &&
+		(ADRENO_CHIPID_PATCH(adreno_dev->chip_id) > 0));
+}
+
 static inline int adreno_rb_ctxtswitch(unsigned int *cmd)
 {
 	return (cmd[0] == cp_nop_packet(1) &&
diff --git a/drivers/gpu/msm/adreno_a2xx.c b/drivers/gpu/msm/adreno_a2xx.c
index 4e4843b..6db6e7b 100644
--- a/drivers/gpu/msm/adreno_a2xx.c
+++ b/drivers/gpu/msm/adreno_a2xx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-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
@@ -1706,34 +1706,6 @@
 		return;
 	}
 
-	if (status & CP_INT_CNTL__RB_INT_MASK) {
-		/* signal intr completion event */
-		unsigned int context_id, timestamp;
-		kgsl_sharedmem_readl(&device->memstore, &context_id,
-				KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
-					current_context));
-
-		kgsl_sharedmem_readl(&device->memstore, &timestamp,
-				KGSL_MEMSTORE_OFFSET(context_id,
-					eoptimestamp));
-
-		if (context_id < KGSL_MEMSTORE_MAX) {
-			/* reset per context ts_cmp_enable */
-			kgsl_sharedmem_writel(&device->memstore,
-					KGSL_MEMSTORE_OFFSET(context_id,
-						ts_cmp_enable), 0);
-			/* Always reset global timestamp ts_cmp_enable */
-			kgsl_sharedmem_writel(&device->memstore,
-					KGSL_MEMSTORE_OFFSET(
-						KGSL_MEMSTORE_GLOBAL,
-						ts_cmp_enable), 0);
-			wmb();
-		}
-
-		KGSL_CMD_WARN(device, "<%d:0x%x> ringbuffer interrupt\n",
-				context_id, timestamp);
-	}
-
 	for (i = 0; i < ARRAY_SIZE(kgsl_cp_error_irqs); i++) {
 		if (status & kgsl_cp_error_irqs[i].mask) {
 			KGSL_CMD_CRIT(rb->device, "%s\n",
@@ -1840,6 +1812,19 @@
 	wmb();
 }
 
+static unsigned int a2xx_irq_pending(struct adreno_device *adreno_dev)
+{
+	struct kgsl_device *device = &adreno_dev->dev;
+	unsigned int rbbm, cp, mh;
+
+	adreno_regread(device, REG_RBBM_INT_CNTL, &rbbm);
+	adreno_regread(device, REG_CP_INT_CNTL, &cp);
+	adreno_regread(device, MH_INTERRUPT_MASK, &mh);
+
+	return ((rbbm & RBBM_INT_MASK) || (cp & CP_INT_MASK) ||
+		(mh & kgsl_mmu_get_int_mask())) ? 1 : 0;
+}
+
 static void a2xx_rb_init(struct adreno_device *adreno_dev,
 			struct adreno_ringbuffer *rb)
 {
@@ -2035,6 +2020,7 @@
 	.ctxt_draw_workaround = a2xx_drawctxt_draw_workaround,
 	.irq_handler = a2xx_irq_handler,
 	.irq_control = a2xx_irq_control,
+	.irq_pending = a2xx_irq_pending,
 	.snapshot = a2xx_snapshot,
 	.rb_init = a2xx_rb_init,
 	.busy_cycles = a2xx_busy_cycles,
diff --git a/drivers/gpu/msm/adreno_a2xx_snapshot.c b/drivers/gpu/msm/adreno_a2xx_snapshot.c
index ce74c1b..2c86f82 100644
--- a/drivers/gpu/msm/adreno_a2xx_snapshot.c
+++ b/drivers/gpu/msm/adreno_a2xx_snapshot.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/gpu/msm/adreno_a2xx_trace.c b/drivers/gpu/msm/adreno_a2xx_trace.c
index c91d1a0..87c930b 100644
--- a/drivers/gpu/msm/adreno_a2xx_trace.c
+++ b/drivers/gpu/msm/adreno_a2xx_trace.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/gpu/msm/adreno_a2xx_trace.h b/drivers/gpu/msm/adreno_a2xx_trace.h
index 2528e15..af355d6 100644
--- a/drivers/gpu/msm/adreno_a2xx_trace.h
+++ b/drivers/gpu/msm/adreno_a2xx_trace.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index 2466a5c..73a7f52 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -452,8 +452,12 @@
 		return A305_RBBM_CLOCK_CTL_DEFAULT;
 	else if (adreno_is_a320(adreno_dev))
 		return A320_RBBM_CLOCK_CTL_DEFAULT;
+	else if (adreno_is_a330v2(adreno_dev))
+		return A330v2_RBBM_CLOCK_CTL_DEFAULT;
 	else if (adreno_is_a330(adreno_dev))
 		return A330_RBBM_CLOCK_CTL_DEFAULT;
+	else if (adreno_is_a305b(adreno_dev))
+		return A305B_RBBM_CLOCK_CTL_DEFAULT;
 
 	BUG_ON(1);
 }
@@ -2587,33 +2591,7 @@
 {
 	struct kgsl_device *device = &adreno_dev->dev;
 
-	if (irq == A3XX_INT_CP_RB_INT) {
-		unsigned int context_id, timestamp;
-		kgsl_sharedmem_readl(&device->memstore, &context_id,
-				KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
-					current_context));
-
-		kgsl_sharedmem_readl(&device->memstore, &timestamp,
-				KGSL_MEMSTORE_OFFSET(context_id,
-					eoptimestamp));
-
-		if (context_id < KGSL_MEMSTORE_MAX) {
-			/* reset per context ts_cmp_enable */
-			kgsl_sharedmem_writel(&device->memstore,
-					KGSL_MEMSTORE_OFFSET(context_id,
-						ts_cmp_enable), 0);
-			/* Always reset global timestamp ts_cmp_enable */
-			kgsl_sharedmem_writel(&device->memstore,
-					KGSL_MEMSTORE_OFFSET(
-						KGSL_MEMSTORE_GLOBAL,
-						ts_cmp_enable), 0);
-			wmb();
-		}
-
-		KGSL_CMD_WARN(device, "<%d:0x%x> ringbuffer interrupt\n",
-				context_id, timestamp);
-	}
-
+	/* Wake up everybody waiting for the interrupt */
 	wake_up_interruptible_all(&device->wait_queue);
 
 	/* Schedule work to free mem and issue ibs */
@@ -2709,6 +2687,15 @@
 		adreno_regwrite(device, A3XX_RBBM_INT_0_MASK, 0);
 }
 
+static unsigned int a3xx_irq_pending(struct adreno_device *adreno_dev)
+{
+	unsigned int status;
+
+	adreno_regread(&adreno_dev->dev, A3XX_RBBM_INT_0_STATUS, &status);
+
+	return (status & A3XX_INT_MASK) ? 1 : 0;
+}
+
 static unsigned int a3xx_busy_cycles(struct adreno_device *adreno_dev)
 {
 	struct kgsl_device *device = &adreno_dev->dev;
@@ -2759,6 +2746,16 @@
 	{0, 0},
 };
 
+static struct a3xx_vbif_data a305b_vbif[] = {
+	{ A3XX_VBIF_IN_RD_LIM_CONF0, 0x00181818 },
+	{ A3XX_VBIF_IN_WR_LIM_CONF0, 0x00181818 },
+	{ A3XX_VBIF_OUT_RD_LIM_CONF0, 0x00000018 },
+	{ A3XX_VBIF_OUT_WR_LIM_CONF0, 0x00000018 },
+	{ A3XX_VBIF_DDR_OUT_MAX_BURST, 0x00000303 },
+	{ A3XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x0003 },
+	{0, 0},
+};
+
 static struct a3xx_vbif_data a320_vbif[] = {
 	/* Set up 16 deep read/write request queues */
 	{ A3XX_VBIF_IN_RD_LIM_CONF0, 0x10101010 },
@@ -2809,17 +2806,50 @@
 	{0, 0},
 };
 
+/*
+ * Most of the VBIF registers on 8974v2 have the correct values at power on, so
+ * we won't modify those if we don't need to
+ */
+static struct a3xx_vbif_data a330v2_vbif[] = {
+	/* Enable 1k sort */
+	{ A3XX_VBIF_ABIT_SORT, 0x0001003F },
+	{ A3XX_VBIF_ABIT_SORT_CONF, 0x000000A4 },
+	/* Enable WR-REQ */
+	{ A3XX_VBIF_GATE_OFF_WRREQ_EN, 0x00003F },
+	{ A3XX_VBIF_DDR_OUT_MAX_BURST, 0x0000303 },
+	/* Set up VBIF_ROUND_ROBIN_QOS_ARB */
+	{ A3XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x0003 },
+	/* Disable VBIF clock gating. This is to enable AXI running
+	 * higher frequency than GPU.
+	 */
+	{ A3XX_VBIF_CLKON, 1 },
+	{0, 0},
+};
+
+static struct {
+	int(*devfunc)(struct adreno_device *);
+	struct a3xx_vbif_data *vbif;
+} a3xx_vbif_platforms[] = {
+	{ adreno_is_a305, a305_vbif },
+	{ adreno_is_a320, a320_vbif },
+	/* A330v2 needs to be ahead of A330 so the right device matches */
+	{ adreno_is_a330v2, a330v2_vbif },
+	{ adreno_is_a330, a330_vbif },
+	{ adreno_is_a305b, a305b_vbif },
+};
+
 static void a3xx_start(struct adreno_device *adreno_dev)
 {
 	struct kgsl_device *device = &adreno_dev->dev;
 	struct a3xx_vbif_data *vbif = NULL;
+	int i;
 
-	if (adreno_is_a305(adreno_dev))
-		vbif = a305_vbif;
-	else if (adreno_is_a320(adreno_dev))
-		vbif = a320_vbif;
-	else if (adreno_is_a330(adreno_dev))
-		vbif = a330_vbif;
+	for (i = 0; i < ARRAY_SIZE(a3xx_vbif_platforms); i++) {
+		if (a3xx_vbif_platforms[i].devfunc(adreno_dev)) {
+			vbif = a3xx_vbif_platforms[i].vbif;
+			break;
+		}
+	}
 
 	BUG_ON(vbif == NULL);
 
@@ -2859,12 +2889,16 @@
 	adreno_regwrite(device, A3XX_RBBM_CLOCK_CTL,
 		adreno_a3xx_rbbm_clock_ctl_default(adreno_dev));
 
-	if (adreno_is_a330(adreno_dev))
+	if (adreno_is_a330v2(adreno_dev))
 		adreno_regwrite(device, A3XX_RBBM_GPR0_CTL,
-		A330_RBBM_GPR0_CTL_DEFAULT);
+			A330v2_RBBM_GPR0_CTL_DEFAULT);
+	else if (adreno_is_a330(adreno_dev))
+		adreno_regwrite(device, A3XX_RBBM_GPR0_CTL,
+			A330_RBBM_GPR0_CTL_DEFAULT);
 
 	/* Set the OCMEM base address for A330 */
-	if (adreno_is_a330(adreno_dev)) {
+	if (adreno_is_a330(adreno_dev) ||
+		adreno_is_a305b(adreno_dev)) {
 		adreno_regwrite(device, A3XX_RB_GMEM_BASE_ADDR,
 			(unsigned int)(adreno_dev->ocmem_base >> 14));
 	}
@@ -2873,12 +2907,22 @@
 	adreno_regwrite(device, A3XX_RBBM_PERFCTR_CTL, 0x01);
 
 	/*
-	 * Set SP perfcounter 7 to count SP_FS_FULL_ALU_INSTRUCTIONS
+	 * Set SP perfcounter 5 to count SP_ALU_ACTIVE_CYCLES, it includes
+	 * all ALU instruction execution regardless precision or shader ID.
+	 * Set SP perfcounter 6 to count SP0_ICL1_MISSES, It counts
+	 * USP L1 instruction miss request.
+	 * Set SP perfcounter 7 to count SP_FS_FULL_ALU_INSTRUCTIONS, it
+	 * counts USP flow control instruction execution.
 	 * we will use this to augment our hang detection
 	 */
-
-	adreno_regwrite(device, A3XX_SP_PERFCOUNTER7_SELECT,
-		SP_FS_FULL_ALU_INSTRUCTIONS);
+	if (adreno_dev->fast_hang_detect) {
+		adreno_regwrite(device, A3XX_SP_PERFCOUNTER5_SELECT,
+			SP_ALU_ACTIVE_CYCLES);
+		adreno_regwrite(device, A3XX_SP_PERFCOUNTER6_SELECT,
+			SP0_ICL1_MISSES);
+		adreno_regwrite(device, A3XX_SP_PERFCOUNTER7_SELECT,
+			SP_FS_CFLOW_INSTRUCTIONS);
+	}
 }
 
 /* Defined in adreno_a3xx_snapshot.c */
@@ -2897,6 +2941,7 @@
 	.rb_init = a3xx_rb_init,
 	.irq_control = a3xx_irq_control,
 	.irq_handler = a3xx_irq_handler,
+	.irq_pending = a3xx_irq_pending,
 	.busy_cycles = a3xx_busy_cycles,
 	.start = a3xx_start,
 	.snapshot = a3xx_snapshot,
diff --git a/drivers/gpu/msm/adreno_a3xx_snapshot.c b/drivers/gpu/msm/adreno_a3xx_snapshot.c
index de95951..58e3126 100644
--- a/drivers/gpu/msm/adreno_a3xx_snapshot.c
+++ b/drivers/gpu/msm/adreno_a3xx_snapshot.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -24,6 +24,22 @@
 #define SHADER_MEMORY_SIZE 0x4000
 
 /**
+ * _rbbm_debug_bus_read - Helper function to read data from the RBBM
+ * debug bus.
+ * @device - GPU device to read/write registers
+ * @block_id - Debug bus block to read from
+ * @index - Index in the debug bus block to read
+ * @ret - Value of the register read
+ */
+static void _rbbm_debug_bus_read(struct kgsl_device *device,
+	unsigned int block_id, unsigned int index, unsigned int *val)
+{
+	unsigned int block = (block_id << 8) | 1 << 16;
+	adreno_regwrite(device, A3XX_RBBM_DEBUG_BUS_CTL, block | index);
+	adreno_regread(device, A3XX_RBBM_DEBUG_BUS_DATA_STATUS, val);
+}
+
+/**
  * a3xx_snapshot_shader_memory - Helper function to dump the GPU shader
  * memory to the snapshot buffer.
  * @device - GPU device whose shader memory is to be dumped
@@ -198,7 +214,8 @@
 	int i, size;
 
 	/* The size of the ROQ buffer is core dependent */
-	size = adreno_is_a330(adreno_dev) ?
+	size = (adreno_is_a330(adreno_dev) ||
+		adreno_is_a305b(adreno_dev)) ?
 		A330_CP_ROQ_SIZE : A320_CP_ROQ_SIZE;
 
 	if (remain < DEBUG_SECTION_SZ(size)) {
@@ -260,7 +277,6 @@
 
 	struct kgsl_snapshot_debugbus *header = snapshot;
 	struct debugbus_block *block = priv;
-	unsigned int val;
 	int i;
 	unsigned int *data = snapshot + sizeof(*header);
 	unsigned int dwords;
@@ -272,7 +288,8 @@
 	 * like CP are larger
 	 */
 
-	dwords = adreno_is_a330(adreno_dev) ?
+	dwords = (adreno_is_a330(adreno_dev) ||
+		adreno_is_a305b(adreno_dev)) ?
 		block->dwords : 0x40;
 
 	size = (dwords * sizeof(unsigned int)) + sizeof(*header);
@@ -282,16 +299,11 @@
 		return 0;
 	}
 
-	val = (block->block_id << 8) | (1 << 16);
-
 	header->id = block->block_id;
 	header->count = dwords;
 
-	for (i = 0; i < dwords; i++) {
-		adreno_regwrite(device, A3XX_RBBM_DEBUG_BUS_CTL, val | i);
-		adreno_regread(device, A3XX_RBBM_DEBUG_BUS_DATA_STATUS,
-			&data[i]);
-	}
+	for (i = 0; i < dwords; i++)
+		_rbbm_debug_bus_read(device, block->block_id, i, &data[i]);
 
 	return size;
 }
@@ -353,18 +365,58 @@
 	struct kgsl_snapshot_registers_list *list,
 	struct adreno_device *adreno_dev)
 {
-	/* HLSQ specific registers */
+	struct kgsl_device *device = &adreno_dev->dev;
+
 	/*
-	 * Don't dump any a3xx HLSQ registers just yet.  Reading the HLSQ
-	 * registers can cause the device to hang if the HLSQ block is
-	 * busy.  Add specific checks for each a3xx core as the requirements
-	 * are discovered.  Disable by default for now.
+	 * Trying to read HLSQ registers when the HLSQ block is busy
+	 * will cause the device to hang.  The RBBM_DEBUG_BUS has information
+	 * that will tell us if the HLSQ block is busy or not.  Read values
+	 * from the debug bus to ensure the HLSQ block is not busy (this
+	 * is hardware dependent).  If the HLSQ block is busy do not
+	 * dump the registers, otherwise dump the HLSQ registers.
 	 */
-	if (!adreno_is_a3xx(adreno_dev)) {
-		regs[list->count].regs = (unsigned int *) a3xx_hlsq_registers;
-		regs[list->count].count = a3xx_hlsq_registers_count;
-		list->count++;
+
+	if (adreno_is_a330(adreno_dev)) {
+		/*
+		 * stall_ctxt_full status bit: RBBM_BLOCK_ID_HLSQ index 49 [27]
+		 *
+		 * if (!stall_context_full)
+		 * then dump HLSQ registers
+		 */
+		unsigned int stall_context_full = 0;
+
+		_rbbm_debug_bus_read(device, RBBM_BLOCK_ID_HLSQ, 49,
+				&stall_context_full);
+		stall_context_full &= 0x08000000;
+
+		if (stall_context_full)
+			return;
+	} else {
+		/*
+		 * tpif status bits: RBBM_BLOCK_ID_HLSQ index 4 [4:0]
+		 * spif status bits: RBBM_BLOCK_ID_HLSQ index 7 [5:0]
+		 *
+		 * if ((tpif == 0, 1, 28) && (spif == 0, 1, 10))
+		 * then dump HLSQ registers
+		 */
+		unsigned int next_pif = 0;
+
+		/* check tpif */
+		_rbbm_debug_bus_read(device, RBBM_BLOCK_ID_HLSQ, 4, &next_pif);
+		next_pif &= 0x1f;
+		if (next_pif != 0 && next_pif != 1 && next_pif != 28)
+			return;
+
+		/* check spif */
+		_rbbm_debug_bus_read(device, RBBM_BLOCK_ID_HLSQ, 7, &next_pif);
+		next_pif &= 0x3f;
+		if (next_pif != 0 && next_pif != 1 && next_pif != 10)
+			return;
 	}
+
+	regs[list->count].regs = (unsigned int *) a3xx_hlsq_registers;
+	regs[list->count].count = a3xx_hlsq_registers_count;
+	list->count++;
 }
 
 static void _snapshot_a330_regs(struct kgsl_snapshot_registers *regs,
@@ -397,7 +449,7 @@
 	/* Store relevant registers in list to snapshot */
 	_snapshot_a3xx_regs(regs, &list);
 	_snapshot_hlsq_regs(regs, &list, adreno_dev);
-	if (adreno_is_a330(adreno_dev))
+	if (adreno_is_a330(adreno_dev) || adreno_is_a305b(adreno_dev))
 		_snapshot_a330_regs(regs, &list);
 
 	/* Master set of (non debug) registers */
@@ -408,7 +460,8 @@
 	/*
 	 * CP_STATE_DEBUG indexed registers - 20 on 305 and 320 and 46 on A330
 	 */
-	size = adreno_is_a330(adreno_dev) ? 0x2E : 0x14;
+	size = (adreno_is_a330(adreno_dev) ||
+		adreno_is_a305b(adreno_dev)) ? 0x2E : 0x14;
 
 	snapshot = kgsl_snapshot_indexed_registers(device, snapshot,
 			remain, REG_CP_STATE_DEBUG_INDEX,
@@ -453,7 +506,8 @@
 			KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain,
 			a3xx_snapshot_cp_roq, NULL);
 
-	if (adreno_is_a330(adreno_dev)) {
+	if (adreno_is_a330(adreno_dev) ||
+		adreno_is_a305b(adreno_dev)) {
 		snapshot = kgsl_snapshot_add_section(device,
 			KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain,
 			a330_snapshot_cp_merciu, NULL);
diff --git a/drivers/gpu/msm/adreno_a3xx_trace.c b/drivers/gpu/msm/adreno_a3xx_trace.c
index 8b4a80d..325b068 100644
--- a/drivers/gpu/msm/adreno_a3xx_trace.c
+++ b/drivers/gpu/msm/adreno_a3xx_trace.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/gpu/msm/adreno_a3xx_trace.h b/drivers/gpu/msm/adreno_a3xx_trace.h
index 44483a8..d48faf4 100644
--- a/drivers/gpu/msm/adreno_a3xx_trace.h
+++ b/drivers/gpu/msm/adreno_a3xx_trace.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c
index bb3da40..1989ff5 100644
--- a/drivers/gpu/msm/adreno_debugfs.c
+++ b/drivers/gpu/msm/adreno_debugfs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2008-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
diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c
index a107a27..b109e14 100644
--- a/drivers/gpu/msm/adreno_drawctxt.c
+++ b/drivers/gpu/msm/adreno_drawctxt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-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
diff --git a/drivers/gpu/msm/adreno_drawctxt.h b/drivers/gpu/msm/adreno_drawctxt.h
index 58e4791..65dbd4c 100644
--- a/drivers/gpu/msm/adreno_drawctxt.h
+++ b/drivers/gpu/msm/adreno_drawctxt.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-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
diff --git a/drivers/gpu/msm/adreno_pm4types.h b/drivers/gpu/msm/adreno_pm4types.h
index 6ec11ea..f449870 100644
--- a/drivers/gpu/msm/adreno_pm4types.h
+++ b/drivers/gpu/msm/adreno_pm4types.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-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
diff --git a/drivers/gpu/msm/adreno_postmortem.c b/drivers/gpu/msm/adreno_postmortem.c
index 6e0d6ad..2b9c286 100644
--- a/drivers/gpu/msm/adreno_postmortem.c
+++ b/drivers/gpu/msm/adreno_postmortem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -912,7 +912,8 @@
 			adreno_dump_regs(device, a3xx_registers,
 					a3xx_registers_count);
 
-			if (adreno_is_a330(adreno_dev))
+			if (adreno_is_a330(adreno_dev) ||
+				adreno_is_a305b(adreno_dev))
 				adreno_dump_regs(device, a330_registers,
 					a330_registers_count);
 		}
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index 97b35b0..1d25646 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-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
@@ -435,6 +435,8 @@
 	/* CP ROQ queue sizes (bytes) - RB:16, ST:16, IB1:32, IB2:64 */
 	if (adreno_is_a305(adreno_dev) || adreno_is_a320(adreno_dev))
 		adreno_regwrite(device, REG_CP_QUEUE_THRESHOLDS, 0x000E0602);
+	else if (adreno_is_a330(adreno_dev) || adreno_is_a305b(adreno_dev))
+		adreno_regwrite(device, REG_CP_QUEUE_THRESHOLDS, 0x003E2008);
 
 	rb->rptr = 0;
 	rb->wptr = 0;
@@ -568,7 +570,7 @@
 	total_sizedwords += (flags & KGSL_CMD_FLAGS_INTERNAL_ISSUE) ? 2 : 0;
 
 	/* Add CP_COND_EXEC commands to generate CP_INTERRUPT */
-	total_sizedwords += context ? 7 : 0;
+	total_sizedwords += context ? 13 : 0;
 
 	if (adreno_is_a3xx(adreno_dev))
 		total_sizedwords += 7;
@@ -577,14 +579,13 @@
 		total_sizedwords += 2; /* CP_WAIT_FOR_IDLE */
 
 	total_sizedwords += 2; /* scratchpad ts for recovery */
+	total_sizedwords += 3; /* sop timestamp */
+	total_sizedwords += 4; /* eop timestamp */
+
 	if (context && context->flags & CTXT_FLAGS_PER_CONTEXT_TS &&
 			!(flags & KGSL_CMD_FLAGS_INTERNAL_ISSUE)) {
-		total_sizedwords += 3; /* sop timestamp */
-		total_sizedwords += 4; /* eop timestamp */
 		total_sizedwords += 3; /* global timestamp without cache
 					* flush for non-zero context */
-	} else {
-		total_sizedwords += 4; /* global timestamp for recovery*/
 	}
 
 	if (adreno_is_a20x(adreno_dev))
@@ -610,6 +611,31 @@
 		GSL_RB_WRITE(ringcmds, rcmd_gpu, KGSL_CMD_INTERNAL_IDENTIFIER);
 	}
 
+	/* always increment the global timestamp. once. */
+	rb->timestamp[KGSL_MEMSTORE_GLOBAL]++;
+
+	/* Do not update context's timestamp for internal submissions */
+	if (context && !(flags & KGSL_CMD_FLAGS_INTERNAL_ISSUE)) {
+		if (context_id == KGSL_MEMSTORE_GLOBAL)
+			rb->timestamp[context->id] =
+				rb->timestamp[KGSL_MEMSTORE_GLOBAL];
+		else if (context->flags & CTXT_FLAGS_USER_GENERATED_TS)
+			rb->timestamp[context_id] = timestamp;
+		else
+			rb->timestamp[context_id]++;
+	}
+	timestamp = rb->timestamp[context_id];
+
+	/* scratchpad ts for recovery */
+	GSL_RB_WRITE(ringcmds, rcmd_gpu, cp_type0_packet(REG_CP_TIMESTAMP, 1));
+	GSL_RB_WRITE(ringcmds, rcmd_gpu, rb->timestamp[KGSL_MEMSTORE_GLOBAL]);
+
+	/* start-of-pipeline timestamp */
+	GSL_RB_WRITE(ringcmds, rcmd_gpu, cp_type3_packet(CP_MEM_WRITE, 2));
+	GSL_RB_WRITE(ringcmds, rcmd_gpu, (gpuaddr +
+		KGSL_MEMSTORE_OFFSET(context_id, soptimestamp)));
+	GSL_RB_WRITE(ringcmds, rcmd_gpu, timestamp);
+
 	if (flags & KGSL_CMD_FLAGS_PMODE) {
 		/* disable protected mode error checking */
 		GSL_RB_WRITE(ringcmds, rcmd_gpu,
@@ -629,21 +655,6 @@
 		GSL_RB_WRITE(ringcmds, rcmd_gpu, 1);
 	}
 
-	/* always increment the global timestamp. once. */
-	rb->timestamp[KGSL_MEMSTORE_GLOBAL]++;
-
-	/* Do not update context's timestamp for internal submissions */
-	if (context && !(flags & KGSL_CMD_FLAGS_INTERNAL_ISSUE)) {
-		if (context_id == KGSL_MEMSTORE_GLOBAL)
-			rb->timestamp[context->id] =
-				rb->timestamp[KGSL_MEMSTORE_GLOBAL];
-		else if (context->flags & CTXT_FLAGS_USER_GENERATED_TS)
-			rb->timestamp[context_id] = timestamp;
-		else
-			rb->timestamp[context_id]++;
-	}
-	timestamp = rb->timestamp[context_id];
-
 	/* HW Workaround for MMU Page fault
 	* due to memory getting free early before
 	* GPU completes it.
@@ -654,14 +665,10 @@
 		GSL_RB_WRITE(ringcmds, rcmd_gpu, 0x00);
 	}
 
-	/* scratchpad ts for recovery */
-	GSL_RB_WRITE(ringcmds, rcmd_gpu, cp_type0_packet(REG_CP_TIMESTAMP, 1));
-	GSL_RB_WRITE(ringcmds, rcmd_gpu, rb->timestamp[KGSL_MEMSTORE_GLOBAL]);
-
 	if (adreno_is_a3xx(adreno_dev)) {
 		/*
-		 * FLush HLSQ lazy updates to make sure there are no
-		 * rsources pending for indirect loads after the timestamp
+		 * Flush HLSQ lazy updates to make sure there are no
+		 * resources pending for indirect loads after the timestamp
 		 */
 
 		GSL_RB_WRITE(ringcmds, rcmd_gpu,
@@ -672,22 +679,19 @@
 		GSL_RB_WRITE(ringcmds, rcmd_gpu, 0x00);
 	}
 
+	/*
+	 * end-of-pipeline timestamp.  If per context timestamps is not
+	 * enabled, then context_id will be KGSL_MEMSTORE_GLOBAL so all
+	 * eop timestamps will work out.
+	 */
+	GSL_RB_WRITE(ringcmds, rcmd_gpu, cp_type3_packet(CP_EVENT_WRITE, 3));
+	GSL_RB_WRITE(ringcmds, rcmd_gpu, CACHE_FLUSH_TS);
+	GSL_RB_WRITE(ringcmds, rcmd_gpu, (gpuaddr +
+		KGSL_MEMSTORE_OFFSET(context_id, eoptimestamp)));
+	GSL_RB_WRITE(ringcmds, rcmd_gpu, timestamp);
+
 	if (context && context->flags & CTXT_FLAGS_PER_CONTEXT_TS
 			&& !(flags & KGSL_CMD_FLAGS_INTERNAL_ISSUE)) {
-		/* start-of-pipeline timestamp */
-		GSL_RB_WRITE(ringcmds, rcmd_gpu,
-			cp_type3_packet(CP_MEM_WRITE, 2));
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, (gpuaddr +
-			KGSL_MEMSTORE_OFFSET(context_id, soptimestamp)));
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, timestamp);
-
-		/* end-of-pipeline timestamp */
-		GSL_RB_WRITE(ringcmds, rcmd_gpu,
-			cp_type3_packet(CP_EVENT_WRITE, 3));
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, CACHE_FLUSH_TS);
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, (gpuaddr +
-			KGSL_MEMSTORE_OFFSET(context_id, eoptimestamp)));
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, timestamp);
 
 		GSL_RB_WRITE(ringcmds, rcmd_gpu,
 			cp_type3_packet(CP_MEM_WRITE, 2));
@@ -696,15 +700,6 @@
 				eoptimestamp)));
 		GSL_RB_WRITE(ringcmds, rcmd_gpu,
 			rb->timestamp[KGSL_MEMSTORE_GLOBAL]);
-	} else {
-		GSL_RB_WRITE(ringcmds, rcmd_gpu,
-			cp_type3_packet(CP_EVENT_WRITE, 3));
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, CACHE_FLUSH_TS);
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, (gpuaddr +
-			KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
-						eoptimestamp)));
-		GSL_RB_WRITE(ringcmds, rcmd_gpu,
-				rb->timestamp[KGSL_MEMSTORE_GLOBAL]);
 	}
 
 	if (adreno_is_a20x(adreno_dev)) {
@@ -725,7 +720,25 @@
 				context_id, ref_wait_ts)) >> 2);
 		GSL_RB_WRITE(ringcmds, rcmd_gpu, timestamp);
 		/* # of conditional command DWORDs */
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, 2);
+		GSL_RB_WRITE(ringcmds, rcmd_gpu, 8);
+
+		/* Clear the ts_cmp_enable for the context */
+		GSL_RB_WRITE(ringcmds, rcmd_gpu,
+			cp_type3_packet(CP_MEM_WRITE, 2));
+		GSL_RB_WRITE(ringcmds, rcmd_gpu, gpuaddr +
+			KGSL_MEMSTORE_OFFSET(
+				context_id, ts_cmp_enable));
+		GSL_RB_WRITE(ringcmds, rcmd_gpu, 0x0);
+
+		/* Clear the ts_cmp_enable for the global timestamp */
+		GSL_RB_WRITE(ringcmds, rcmd_gpu,
+			cp_type3_packet(CP_MEM_WRITE, 2));
+		GSL_RB_WRITE(ringcmds, rcmd_gpu, gpuaddr +
+			KGSL_MEMSTORE_OFFSET(
+				KGSL_MEMSTORE_GLOBAL, ts_cmp_enable));
+		GSL_RB_WRITE(ringcmds, rcmd_gpu, 0x0);
+
+		/* Trigger the interrupt */
 		GSL_RB_WRITE(ringcmds, rcmd_gpu,
 			cp_type3_packet(CP_INTERRUPT, 1));
 		GSL_RB_WRITE(ringcmds, rcmd_gpu, CP_INT_CNTL__RB_INT_MASK);
@@ -745,30 +758,6 @@
 	return timestamp;
 }
 
-void
-adreno_ringbuffer_issuecmds_intr(struct kgsl_device *device,
-						struct kgsl_context *k_ctxt,
-						unsigned int *cmds,
-						int sizedwords)
-{
-	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
-	struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
-	struct adreno_context *a_ctxt = NULL;
-
-	if (!k_ctxt)
-		return;
-
-	a_ctxt = k_ctxt->devctxt;
-
-	if (k_ctxt->id == KGSL_CONTEXT_INVALID ||
-		a_ctxt == NULL ||
-		device->state & KGSL_STATE_HUNG)
-		return;
-
-	adreno_ringbuffer_addcmds(rb, a_ctxt, KGSL_CMD_FLAGS_INTERNAL_ISSUE,
-					cmds, sizedwords, 0);
-}
-
 unsigned int
 adreno_ringbuffer_issuecmds(struct kgsl_device *device,
 						struct adreno_context *drawctxt,
@@ -1071,10 +1060,6 @@
 					0,
 					&link[0], (cmds - link), *timestamp);
 
-	KGSL_CMD_INFO(device, "<%d:0x%x> g %08x numibs %d\n",
-		context->id, *timestamp, (unsigned int)ibdesc, numibs);
-
-
 #ifdef CONFIG_MSM_KGSL_CFF_DUMP
 	/*
 	 * insert wait for idle after every IB1
diff --git a/drivers/gpu/msm/adreno_ringbuffer.h b/drivers/gpu/msm/adreno_ringbuffer.h
index 50d9c25..e87b506 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.h
+++ b/drivers/gpu/msm/adreno_ringbuffer.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-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
@@ -110,11 +110,6 @@
 					unsigned int *cmdaddr,
 					int sizedwords);
 
-void adreno_ringbuffer_issuecmds_intr(struct kgsl_device *device,
-					struct kgsl_context *k_ctxt,
-					unsigned int *cmdaddr,
-					int sizedwords);
-
 void adreno_ringbuffer_submit(struct adreno_ringbuffer *rb);
 
 void kgsl_cp_intrcallback(struct kgsl_device *device);
diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c
index 696073f..26be9da 100644
--- a/drivers/gpu/msm/adreno_snapshot.c
+++ b/drivers/gpu/msm/adreno_snapshot.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index deafa7a..7ed0b10 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
@@ -53,147 +53,6 @@
 
 static struct ion_client *kgsl_ion_client;
 
-/**
- * kgsl_add_event - Add a new timstamp event for the KGSL device
- * @device - KGSL device for the new event
- * @ts - the timestamp to trigger the event on
- * @cb - callback function to call when the timestamp expires
- * @priv - private data for the specific event type
- * @owner - driver instance that owns this event
- *
- * @returns - 0 on success or error code on failure
- */
-
-int kgsl_add_event(struct kgsl_device *device, u32 id, u32 ts,
-	void (*cb)(struct kgsl_device *, void *, u32, u32), void *priv,
-	void *owner)
-{
-	struct kgsl_event *event;
-	struct list_head *n;
-	unsigned int cur_ts;
-	struct kgsl_context *context = NULL;
-
-	if (cb == NULL)
-		return -EINVAL;
-
-	if (id != KGSL_MEMSTORE_GLOBAL) {
-		context = idr_find(&device->context_idr, id);
-		if (context == NULL)
-			return -EINVAL;
-	}
-	cur_ts = kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_RETIRED);
-
-	/* Check to see if the requested timestamp has already fired */
-
-	if (timestamp_cmp(cur_ts, ts) >= 0) {
-		cb(device, priv, id, cur_ts);
-		return 0;
-	}
-
-	event = kzalloc(sizeof(*event), GFP_KERNEL);
-	if (event == NULL)
-		return -ENOMEM;
-
-	event->context = context;
-	event->timestamp = ts;
-	event->priv = priv;
-	event->func = cb;
-	event->owner = owner;
-
-	/*
-	 * Add the event in order to the list.  Order is by context id
-	 * first and then by timestamp for that context.
-	 */
-
-	for (n = device->events.next ; n != &device->events; n = n->next) {
-		struct kgsl_event *e =
-			list_entry(n, struct kgsl_event, list);
-
-		if (e->context != context)
-			continue;
-
-		if (timestamp_cmp(e->timestamp, ts) > 0) {
-			list_add(&event->list, n->prev);
-			break;
-		}
-	}
-
-	if (n == &device->events)
-		list_add_tail(&event->list, &device->events);
-
-	queue_work(device->work_queue, &device->ts_expired_ws);
-	return 0;
-}
-EXPORT_SYMBOL(kgsl_add_event);
-
-/**
- * kgsl_cancel_events_ctxt - Cancel all events for a context
- * @device - KGSL device for the events to cancel
- * @ctxt - context whose events we want to cancel
- *
- */
-static void kgsl_cancel_events_ctxt(struct kgsl_device *device,
-	struct kgsl_context *context)
-{
-	struct kgsl_event *event, *event_tmp;
-	unsigned int id, cur;
-
-	cur = kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_RETIRED);
-	id = context->id;
-
-	list_for_each_entry_safe(event, event_tmp, &device->events, list) {
-		if (event->context != context)
-			continue;
-
-		/*
-		 * "cancel" the events by calling their callback.
-		 * Currently, events are used for lock and memory
-		 * management, so if the process is dying the right
-		 * thing to do is release or free.
-		 */
-		if (event->func)
-			event->func(device, event->priv, id, cur);
-
-		list_del(&event->list);
-		kfree(event);
-	}
-}
-
-/**
- * kgsl_cancel_events - Cancel all events for a process
- * @device - KGSL device for the events to cancel
- * @owner - driver instance that owns the events to cancel
- *
- */
-void kgsl_cancel_events(struct kgsl_device *device,
-	void *owner)
-{
-	struct kgsl_event *event, *event_tmp;
-	unsigned int id, cur;
-
-	list_for_each_entry_safe(event, event_tmp, &device->events, list) {
-		if (event->owner != owner)
-			continue;
-
-		cur = kgsl_readtimestamp(device, event->context,
-					 KGSL_TIMESTAMP_RETIRED);
-
-		id = event->context ? event->context->id : KGSL_MEMSTORE_GLOBAL;
-		/*
-		 * "cancel" the events by calling their callback.
-		 * Currently, events are used for lock and memory
-		 * management, so if the process is dying the right
-		 * thing to do is release or free.
-		 */
-		if (event->func)
-			event->func(device, event->priv, id, cur);
-
-		list_del(&event->list);
-		kfree(event);
-	}
-}
-EXPORT_SYMBOL(kgsl_cancel_events);
-
 int kgsl_memfree_hist_init(void)
 {
 	void *base;
@@ -486,6 +345,20 @@
 		goto func_end;
 	}
 
+	/* Initialize the pending event list */
+	INIT_LIST_HEAD(&context->events);
+
+	/*
+	 * Initialize the node that is used to maintain the master list of
+	 * contexts with pending events in the device structure. Normally we
+	 * wouldn't take the time to initalize a node but at event add time we
+	 * call list_empty() on the node as a quick way of determining if the
+	 * context is already in the master list so it needs to always be either
+	 * active or in an unused but initialized state
+	 */
+
+	INIT_LIST_HEAD(&context->events_list);
+
 func_end:
 	if (ret) {
 		kfree(context);
@@ -540,59 +413,13 @@
 	kfree(context);
 }
 
-void kgsl_timestamp_expired(struct work_struct *work)
-{
-	struct kgsl_device *device = container_of(work, struct kgsl_device,
-		ts_expired_ws);
-	struct kgsl_event *event, *event_tmp;
-	uint32_t ts_processed;
-	unsigned int id;
-
-	mutex_lock(&device->mutex);
-
-	/* Process expired events */
-	list_for_each_entry_safe(event, event_tmp, &device->events, list) {
-		ts_processed = kgsl_readtimestamp(device, event->context,
-						  KGSL_TIMESTAMP_RETIRED);
-		if (timestamp_cmp(ts_processed, event->timestamp) < 0)
-			continue;
-
-		id = event->context ? event->context->id : KGSL_MEMSTORE_GLOBAL;
-
-		if (event->func)
-			event->func(device, event->priv, id, ts_processed);
-
-		list_del(&event->list);
-		kfree(event);
-	}
-
-	/* Send the next pending event for each context to the device */
-	if (device->ftbl->next_event) {
-		unsigned int id = KGSL_MEMSTORE_GLOBAL;
-
-		list_for_each_entry(event, &device->events, list) {
-
-			if (!event->context)
-				continue;
-
-			if (event->context->id != id) {
-				device->ftbl->next_event(device, event);
-				id = event->context->id;
-			}
-		}
-	}
-
-	mutex_unlock(&device->mutex);
-}
-EXPORT_SYMBOL(kgsl_timestamp_expired);
-
 static void kgsl_check_idle_locked(struct kgsl_device *device)
 {
 	if (device->pwrctrl.nap_allowed == true &&
 	    device->state == KGSL_STATE_ACTIVE &&
 		device->requested_state == KGSL_STATE_NONE) {
 		kgsl_pwrctrl_request_state(device, KGSL_STATE_NAP);
-		kgsl_pwrscale_idle(device, 1);
+		kgsl_pwrscale_idle(device);
 		if (kgsl_pwrctrl_sleep(device) != 0)
 			mod_timer(&device->idle_timer,
 				  jiffies +
@@ -690,7 +517,7 @@
 			INIT_COMPLETION(device->hwaccess_gate);
 			device->ftbl->suspend_context(device);
 			device->ftbl->stop(device);
-			pm_qos_update_request(&device->pm_qos_req_dma,
+			pm_qos_update_request(&device->pwrctrl.pm_qos_req_dma,
 						PM_QOS_DEFAULT_VALUE);
 			kgsl_pwrctrl_set_state(device, KGSL_STATE_SUSPEND);
 			break;
@@ -1261,10 +1088,7 @@
 				      result);
 
 	/* Fire off any pending suspend operations that are in flight */
-
-	INIT_COMPLETION(dev_priv->device->suspend_gate);
-	dev_priv->device->active_cnt--;
-	complete(&dev_priv->device->suspend_gate);
+	kgsl_active_count_put(dev_priv->device);
 
 	return result;
 }
@@ -1939,6 +1763,8 @@
 		entry->memdesc.sglen++;
 	}
 
+	entry->memdesc.size = PAGE_ALIGN(entry->memdesc.size);
+
 	return 0;
 err:
 	ion_free(kgsl_ion_client, handle);
@@ -2121,8 +1947,10 @@
 
 	mode = kgsl_memdesc_get_cachemode(&entry->memdesc);
 	if (mode != KGSL_CACHEMODE_UNCACHED
-		&& mode != KGSL_CACHEMODE_WRITECOMBINE)
+		&& mode != KGSL_CACHEMODE_WRITECOMBINE) {
+		trace_kgsl_mem_sync_cache(entry, op);
 		kgsl_cache_range_op(&entry->memdesc, cacheop);
+	}
 
 done:
 	return ret;
@@ -2497,34 +2325,48 @@
 typedef long (*kgsl_ioctl_func_t)(struct kgsl_device_private *,
 	unsigned int, void *);
 
-#define KGSL_IOCTL_FUNC(_cmd, _func, _lock) \
-	[_IOC_NR(_cmd)] = { .cmd = _cmd, .func = _func, .lock = _lock }
+#define KGSL_IOCTL_FUNC(_cmd, _func, _flags) \
+	[_IOC_NR((_cmd))] = \
+		{ .cmd = (_cmd), .func = (_func), .flags = (_flags) }
+
+#define KGSL_IOCTL_LOCK		BIT(0)
+#define KGSL_IOCTL_WAKE		BIT(1)
 
 static const struct {
 	unsigned int cmd;
 	kgsl_ioctl_func_t func;
-	int lock;
+	unsigned int flags;
 } kgsl_ioctl_funcs[] = {
 	KGSL_IOCTL_FUNC(IOCTL_KGSL_DEVICE_GETPROPERTY,
-			kgsl_ioctl_device_getproperty, 1),
+			kgsl_ioctl_device_getproperty,
+			KGSL_IOCTL_LOCK | KGSL_IOCTL_WAKE),
 	KGSL_IOCTL_FUNC(IOCTL_KGSL_DEVICE_WAITTIMESTAMP,
-			kgsl_ioctl_device_waittimestamp, 1),
+			kgsl_ioctl_device_waittimestamp,
+			KGSL_IOCTL_LOCK | KGSL_IOCTL_WAKE),
 	KGSL_IOCTL_FUNC(IOCTL_KGSL_DEVICE_WAITTIMESTAMP_CTXTID,
-			kgsl_ioctl_device_waittimestamp_ctxtid, 1),
+			kgsl_ioctl_device_waittimestamp_ctxtid,
+			KGSL_IOCTL_LOCK | KGSL_IOCTL_WAKE),
 	KGSL_IOCTL_FUNC(IOCTL_KGSL_RINGBUFFER_ISSUEIBCMDS,
-			kgsl_ioctl_rb_issueibcmds, 1),
+			kgsl_ioctl_rb_issueibcmds,
+			KGSL_IOCTL_LOCK | KGSL_IOCTL_WAKE),
 	KGSL_IOCTL_FUNC(IOCTL_KGSL_CMDSTREAM_READTIMESTAMP,
-			kgsl_ioctl_cmdstream_readtimestamp, 1),
+			kgsl_ioctl_cmdstream_readtimestamp,
+			KGSL_IOCTL_LOCK),
 	KGSL_IOCTL_FUNC(IOCTL_KGSL_CMDSTREAM_READTIMESTAMP_CTXTID,
-			kgsl_ioctl_cmdstream_readtimestamp_ctxtid, 1),
+			kgsl_ioctl_cmdstream_readtimestamp_ctxtid,
+			KGSL_IOCTL_LOCK),
 	KGSL_IOCTL_FUNC(IOCTL_KGSL_CMDSTREAM_FREEMEMONTIMESTAMP,
-			kgsl_ioctl_cmdstream_freememontimestamp, 1),
+			kgsl_ioctl_cmdstream_freememontimestamp,
+			KGSL_IOCTL_LOCK | KGSL_IOCTL_WAKE),
 	KGSL_IOCTL_FUNC(IOCTL_KGSL_CMDSTREAM_FREEMEMONTIMESTAMP_CTXTID,
-			kgsl_ioctl_cmdstream_freememontimestamp_ctxtid, 1),
+			kgsl_ioctl_cmdstream_freememontimestamp_ctxtid,
+			KGSL_IOCTL_LOCK | KGSL_IOCTL_WAKE),
 	KGSL_IOCTL_FUNC(IOCTL_KGSL_DRAWCTXT_CREATE,
-			kgsl_ioctl_drawctxt_create, 1),
+			kgsl_ioctl_drawctxt_create,
+			KGSL_IOCTL_LOCK | KGSL_IOCTL_WAKE),
 	KGSL_IOCTL_FUNC(IOCTL_KGSL_DRAWCTXT_DESTROY,
-			kgsl_ioctl_drawctxt_destroy, 1),
+			kgsl_ioctl_drawctxt_destroy,
+			KGSL_IOCTL_LOCK | KGSL_IOCTL_WAKE),
 	KGSL_IOCTL_FUNC(IOCTL_KGSL_MAP_USER_MEM,
 			kgsl_ioctl_map_user_mem, 0),
 	KGSL_IOCTL_FUNC(IOCTL_KGSL_SHAREDMEM_FROM_PMEM,
@@ -2540,9 +2382,11 @@
 	KGSL_IOCTL_FUNC(IOCTL_KGSL_CFF_USER_EVENT,
 			kgsl_ioctl_cff_user_event, 0),
 	KGSL_IOCTL_FUNC(IOCTL_KGSL_TIMESTAMP_EVENT,
-			kgsl_ioctl_timestamp_event, 1),
+			kgsl_ioctl_timestamp_event,
+			KGSL_IOCTL_LOCK),
 	KGSL_IOCTL_FUNC(IOCTL_KGSL_SETPROPERTY,
-			kgsl_ioctl_device_setproperty, 1),
+			kgsl_ioctl_device_setproperty,
+			KGSL_IOCTL_LOCK | KGSL_IOCTL_WAKE),
 	KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUMEM_ALLOC_ID,
 			kgsl_ioctl_gpumem_alloc_id, 0),
 	KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUMEM_FREE_ID,
@@ -2558,7 +2402,7 @@
 	struct kgsl_device_private *dev_priv = filep->private_data;
 	unsigned int nr;
 	kgsl_ioctl_func_t func;
-	int lock, ret;
+	int lock, ret, use_hw;
 	char ustack[64];
 	void *uptr = NULL;
 
@@ -2615,7 +2459,8 @@
 		}
 
 		func = kgsl_ioctl_funcs[nr].func;
-		lock = kgsl_ioctl_funcs[nr].lock;
+		lock = kgsl_ioctl_funcs[nr].flags & KGSL_IOCTL_LOCK;
+		use_hw = kgsl_ioctl_funcs[nr].flags & KGSL_IOCTL_WAKE;
 	} else {
 		func = dev_priv->device->ftbl->ioctl;
 		if (!func) {
@@ -2625,11 +2470,13 @@
 			goto done;
 		}
 		lock = 1;
+		use_hw = 1;
 	}
 
 	if (lock) {
 		mutex_lock(&dev_priv->device->mutex);
-		kgsl_check_suspended(dev_priv->device);
+		if (use_hw)
+			kgsl_check_suspended(dev_priv->device);
 	}
 
 	ret = func(dev_priv, cmd, uptr);
@@ -3136,7 +2983,8 @@
 		goto error_close_mmu;
 	}
 
-	pm_qos_add_request(&device->pm_qos_req_dma, PM_QOS_CPU_DMA_LATENCY,
+	pm_qos_add_request(&device->pwrctrl.pm_qos_req_dma,
+				PM_QOS_CPU_DMA_LATENCY,
 				PM_QOS_DEFAULT_VALUE);
 
 	/* Initalize the snapshot engine */
@@ -3247,7 +3095,7 @@
 	kgsl_cffdump_close(device->id);
 	kgsl_pwrctrl_uninit_sysfs(device);
 
-	pm_qos_remove_request(&device->pm_qos_req_dma);
+	pm_qos_remove_request(&device->pwrctrl.pm_qos_req_dma);
 
 	idr_destroy(&device->context_idr);
 
diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h
index 72e7776..3eb8831 100644
--- a/drivers/gpu/msm/kgsl.h
+++ b/drivers/gpu/msm/kgsl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
@@ -89,6 +89,7 @@
 
 
 struct kgsl_device;
+struct kgsl_context;
 
 struct kgsl_driver {
 	struct cdev cdev;
@@ -217,6 +218,9 @@
 void kgsl_cancel_events(struct kgsl_device *device,
 	void *owner);
 
+void kgsl_cancel_events_ctxt(struct kgsl_device *device,
+	struct kgsl_context *context);
+
 extern const struct dev_pm_ops kgsl_pm_ops;
 
 struct early_suspend;
diff --git a/drivers/gpu/msm/kgsl_cffdump.c b/drivers/gpu/msm/kgsl_cffdump.c
index 4e354d0..e06c94d 100644
--- a/drivers/gpu/msm/kgsl_cffdump.c
+++ b/drivers/gpu/msm/kgsl_cffdump.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/gpu/msm/kgsl_cffdump.h b/drivers/gpu/msm/kgsl_cffdump.h
index 140e486..2733cc3 100644
--- a/drivers/gpu/msm/kgsl_cffdump.h
+++ b/drivers/gpu/msm/kgsl_cffdump.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/gpu/msm/kgsl_debugfs.c b/drivers/gpu/msm/kgsl_debugfs.c
index 3bc107f..f967cd2 100644
--- a/drivers/gpu/msm/kgsl_debugfs.c
+++ b/drivers/gpu/msm/kgsl_debugfs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2008-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
diff --git a/drivers/gpu/msm/kgsl_debugfs.h b/drivers/gpu/msm/kgsl_debugfs.h
index 898c4e9..ae5601f 100644
--- a/drivers/gpu/msm/kgsl_debugfs.h
+++ b/drivers/gpu/msm/kgsl_debugfs.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2008-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2008-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
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index ce3820c..66390fc 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-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
@@ -26,7 +26,7 @@
 
 #define KGSL_TIMEOUT_NONE       0
 #define KGSL_TIMEOUT_DEFAULT    0xFFFFFFFF
-#define KGSL_TIMEOUT_PART       2000 /* 2 sec */
+#define KGSL_TIMEOUT_PART       50 /* 50 msec */
 
 #define FIRST_TIMEOUT (HZ / 2)
 
@@ -113,7 +113,7 @@
 		enum kgsl_property_type type, void *value,
 		unsigned int sizebytes);
 	int (*postmortem_dump) (struct kgsl_device *device, int manual);
-	void (*next_event)(struct kgsl_device *device,
+	int (*next_event)(struct kgsl_device *device,
 		struct kgsl_event *event);
 };
 
@@ -133,6 +133,7 @@
 	void *priv;
 	struct list_head list;
 	void *owner;
+	unsigned int created;
 };
 
 
@@ -212,17 +213,19 @@
 	int pwr_log;
 	struct kgsl_pwrscale pwrscale;
 	struct kobject pwrscale_kobj;
-	struct pm_qos_request pm_qos_req_dma;
 	struct work_struct ts_expired_ws;
 	struct list_head events;
+	struct list_head events_pending_list;
 	s64 on_time;
 
 	/* Postmortem Control switches */
 	int pm_regs_enabled;
 	int pm_ib_enabled;
+
+	int reset_counter; /* Track how many GPU core resets have occured */
 };
 
-void kgsl_timestamp_expired(struct work_struct *work);
+void kgsl_process_events(struct work_struct *work);
 
 #define KGSL_DEVICE_COMMON_INIT(_dev) \
 	.hwaccess_gate = COMPLETION_INITIALIZER((_dev).hwaccess_gate),\
@@ -231,36 +234,42 @@
 	.idle_check_ws = __WORK_INITIALIZER((_dev).idle_check_ws,\
 			kgsl_idle_check),\
 	.ts_expired_ws  = __WORK_INITIALIZER((_dev).ts_expired_ws,\
-			kgsl_timestamp_expired),\
+			kgsl_process_events),\
 	.context_idr = IDR_INIT((_dev).context_idr),\
 	.events = LIST_HEAD_INIT((_dev).events),\
+	.events_pending_list = LIST_HEAD_INIT((_dev).events_pending_list), \
 	.wait_queue = __WAIT_QUEUE_HEAD_INITIALIZER((_dev).wait_queue),\
 	.mutex = __MUTEX_INITIALIZER((_dev).mutex),\
 	.state = KGSL_STATE_INIT,\
 	.ver_major = DRIVER_VERSION_MAJOR,\
 	.ver_minor = DRIVER_VERSION_MINOR
 
+
+/**
+ * struct kgsl_context - Master structure for a KGSL context object
+ * @refcount - kref object for reference counting the context
+ * @id - integer identifier for the context
+ * @dev_priv - pointer to the owning device instance
+ * @devctxt - pointer to the device specific context information
+ * @reset_status - status indication whether a gpu reset occured and whether
+ * this context was responsible for causing it
+ * @wait_on_invalid_ts - flag indicating if this context has tried to wait on a
+ * bad timestamp
+ * @timeline - sync timeline used to create fences that can be signaled when a
+ * sync_pt timestamp expires
+ * @events - list head of pending events for this context
+ * @events_list - list node for the list of all contexts that have pending events
+ */
 struct kgsl_context {
 	struct kref refcount;
 	uint32_t id;
-
-	/* Pointer to the owning device instance */
 	struct kgsl_device_private *dev_priv;
-
-	/* Pointer to the device specific context information */
 	void *devctxt;
-	/*
-	 * Status indicating whether a gpu reset occurred and whether this
-	 * context was responsible for causing it
-	 */
 	unsigned int reset_status;
-	/* Flag indicating if we tried to wait for bad timestamp for this ctx */
 	bool wait_on_invalid_ts;
-	/*
-	 * Timeline used to create fences that can be signaled when a
-	 * sync_pt timestamp expires.
-	 */
 	struct sync_timeline *timeline;
+	struct list_head events;
+	struct list_head events_list;
 };
 
 struct kgsl_process_private {
@@ -441,4 +450,23 @@
 	kref_put(&context->refcount, kgsl_context_destroy);
 }
 
+/**
+ * kgsl_active_count_put - Decrease the device active count
+ * @device: Pointer to a KGSL device
+ *
+ * Decrease the active count for the KGSL device and trigger the suspend_gate
+ * completion if it hits zero
+ */
+static inline void
+kgsl_active_count_put(struct kgsl_device *device)
+{
+	if (device->active_cnt == 1)
+		INIT_COMPLETION(device->suspend_gate);
+
+	device->active_cnt--;
+
+	if (device->active_cnt == 0)
+		complete(&device->suspend_gate);
+}
+
 #endif  /* __KGSL_DEVICE_H */
diff --git a/drivers/gpu/msm/kgsl_drm.c b/drivers/gpu/msm/kgsl_drm.c
index 98c7434..ba88a42 100644
--- a/drivers/gpu/msm/kgsl_drm.c
+++ b/drivers/gpu/msm/kgsl_drm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
@@ -131,88 +131,18 @@
 	struct list_head wait_list;
 };
 
-static struct ion_client *kgsl_drm_ion_phys_client;
+static struct ion_client *kgsl_drm_ion_client;
 
 static int kgsl_drm_inited = DRM_KGSL_NOT_INITED;
 
 /* This is a global list of all the memory currently mapped in the MMU */
 static struct list_head kgsl_mem_list;
 
-static void kgsl_gem_mem_flush(struct kgsl_memdesc *memdesc, int type, int op)
-{
-	int cacheop = 0;
-
-	switch (op) {
-	case DRM_KGSL_GEM_CACHE_OP_TO_DEV:
-		if (type & (DRM_KGSL_GEM_CACHE_WBACK |
-			    DRM_KGSL_GEM_CACHE_WBACKWA))
-			cacheop = KGSL_CACHE_OP_CLEAN;
-
-		break;
-
-	case DRM_KGSL_GEM_CACHE_OP_FROM_DEV:
-		if (type & (DRM_KGSL_GEM_CACHE_WBACK |
-			    DRM_KGSL_GEM_CACHE_WBACKWA |
-			    DRM_KGSL_GEM_CACHE_WTHROUGH))
-			cacheop = KGSL_CACHE_OP_INV;
-	}
-
-	kgsl_cache_range_op(memdesc, cacheop);
-}
-
-/* TODO:
- * Add vsync wait */
-
-static int kgsl_drm_load(struct drm_device *dev, unsigned long flags)
-{
-	return 0;
-}
-
-static int kgsl_drm_unload(struct drm_device *dev)
-{
-	return 0;
-}
-
 struct kgsl_drm_device_priv {
 	struct kgsl_device *device[KGSL_DEVICE_MAX];
 	struct kgsl_device_private *devpriv[KGSL_DEVICE_MAX];
 };
 
-void kgsl_drm_preclose(struct drm_device *dev, struct drm_file *file_priv)
-{
-}
-
-static int kgsl_drm_suspend(struct drm_device *dev, pm_message_t state)
-{
-	return 0;
-}
-
-static int kgsl_drm_resume(struct drm_device *dev)
-{
-	return 0;
-}
-
-static void
-kgsl_gem_free_mmap_offset(struct drm_gem_object *obj)
-{
-	struct drm_device *dev = obj->dev;
-	struct drm_gem_mm *mm = dev->mm_private;
-	struct drm_kgsl_gem_object *priv = obj->driver_private;
-	struct drm_map_list *list;
-
-	list = &obj->map_list;
-	drm_ht_remove_item(&mm->offset_hash, &list->hash);
-	if (list->file_offset_node) {
-		drm_mm_put_block(list->file_offset_node);
-		list->file_offset_node = NULL;
-	}
-
-	kfree(list->map);
-	list->map = NULL;
-
-	priv->mmap_offset = 0;
-}
-
 static int
 kgsl_gem_memory_allocated(struct drm_gem_object *obj)
 {
@@ -224,6 +154,8 @@
 kgsl_gem_alloc_memory(struct drm_gem_object *obj)
 {
 	struct drm_kgsl_gem_object *priv = obj->driver_private;
+	struct sg_table *sg_table;
+	struct scatterlist *s;
 	int index;
 	int result = 0;
 
@@ -241,13 +173,10 @@
 		}
 	}
 
-	/* Set the flags for the memdesc (probably 0, unless it is cached) */
-	priv->memdesc.priv = 0;
-
 	if (TYPE_IS_PMEM(priv->type)) {
 		if (priv->type == DRM_KGSL_GEM_TYPE_EBI ||
 		    priv->type & DRM_KGSL_GEM_PMEM_EBI) {
-			priv->ion_handle = ion_alloc(kgsl_drm_ion_phys_client,
+			priv->ion_handle = ion_alloc(kgsl_drm_ion_client,
 				obj->size * priv->bufcount, PAGE_SIZE,
 				ION_HEAP(ION_SF_HEAP_ID), 0);
 			if (IS_ERR_OR_NULL(priv->ion_handle)) {
@@ -258,13 +187,13 @@
 
 			priv->memdesc.pagetable = priv->pagetable;
 
-			result = ion_phys(kgsl_drm_ion_phys_client,
+			result = ion_phys(kgsl_drm_ion_client,
 				priv->ion_handle, (ion_phys_addr_t *)
 				&priv->memdesc.physaddr, &priv->memdesc.size);
 			if (result) {
 				DRM_ERROR(
 				"Unable to get ION Physical memory address\n");
-				ion_free(kgsl_drm_ion_phys_client,
+				ion_free(kgsl_drm_ion_client,
 					priv->ion_handle);
 				priv->ion_handle = NULL;
 				return result;
@@ -275,7 +204,7 @@
 			if (result) {
 				DRM_ERROR(
 				"Unable to get sg list\n");
-				ion_free(kgsl_drm_ion_phys_client,
+				ion_free(kgsl_drm_ion_client,
 					priv->ion_handle);
 				priv->ion_handle = NULL;
 				return result;
@@ -285,8 +214,8 @@
 					GSL_PT_PAGE_RV | GSL_PT_PAGE_WV);
 			if (result) {
 				DRM_ERROR(
-				"Unable to map GPU\n");
-				ion_free(kgsl_drm_ion_phys_client,
+				"kgsl_mmu_map failed.  result = %d\n", result);
+				ion_free(kgsl_drm_ion_client,
 					priv->ion_handle);
 				priv->ion_handle = NULL;
 				return result;
@@ -301,15 +230,44 @@
 			priv->type & DRM_KGSL_GEM_CACHE_MASK)
 				list_add(&priv->list, &kgsl_mem_list);
 
-		result = kgsl_sharedmem_page_alloc_user(&priv->memdesc,
-					priv->pagetable,
-					obj->size * priv->bufcount);
+		priv->memdesc.pagetable = priv->pagetable;
 
-		if (result != 0) {
-				DRM_ERROR(
-				"Unable to allocate Vmalloc user memory\n");
-				return result;
+		priv->ion_handle = ion_alloc(kgsl_drm_ion_client,
+				obj->size * priv->bufcount, PAGE_SIZE,
+				ION_HEAP(ION_IOMMU_HEAP_ID), 0);
+		if (IS_ERR_OR_NULL(priv->ion_handle)) {
+			DRM_ERROR(
+				"Unable to allocate ION IOMMU memory handle\n");
+				return -ENOMEM;
 		}
+
+		sg_table = ion_sg_table(kgsl_drm_ion_client,
+				priv->ion_handle);
+		if (IS_ERR_OR_NULL(priv->ion_handle)) {
+			DRM_ERROR(
+			"Unable to get ION sg table\n");
+			goto memerr;
+		}
+
+		priv->memdesc.sg = sg_table->sgl;
+
+		/* Calculate the size of the memdesc from the sglist */
+
+		priv->memdesc.sglen = 0;
+
+		for (s = priv->memdesc.sg; s != NULL; s = sg_next(s)) {
+			priv->memdesc.size += s->length;
+			priv->memdesc.sglen++;
+		}
+
+		result = kgsl_mmu_map(priv->pagetable, &priv->memdesc,
+				GSL_PT_PAGE_RV | GSL_PT_PAGE_WV);
+		if (result) {
+			DRM_ERROR(
+			"kgsl_mmu_map failed.  result = %d\n", result);
+			goto memerr;
+		}
+
 	} else
 		return -EINVAL;
 
@@ -321,7 +279,15 @@
 	}
 	priv->flags |= DRM_KGSL_GEM_FLAG_MAPPED;
 
+
 	return 0;
+
+memerr:
+	ion_free(kgsl_drm_ion_client,
+		priv->ion_handle);
+	priv->ion_handle = NULL;
+	return -ENOMEM;
+
 }
 
 static void
@@ -332,16 +298,16 @@
 	if (!kgsl_gem_memory_allocated(obj) || TYPE_IS_FD(priv->type))
 		return;
 
-	kgsl_gem_mem_flush(&priv->memdesc,  priv->type,
-			   DRM_KGSL_GEM_CACHE_OP_FROM_DEV);
-
 	if (priv->memdesc.gpuaddr)
 		kgsl_mmu_unmap(priv->memdesc.pagetable, &priv->memdesc);
 
-	kgsl_sg_free(priv->memdesc.sg, priv->memdesc.sglen);
+	/* ION will take care of freeing the sg table. */
+	priv->memdesc.sg = NULL;
+	priv->memdesc.sglen = 0;
 
 	if (priv->ion_handle)
-		ion_free(kgsl_drm_ion_phys_client, priv->ion_handle);
+		ion_free(kgsl_drm_ion_client, priv->ion_handle);
+
 	priv->ion_handle = NULL;
 
 	memset(&priv->memdesc, 0, sizeof(priv->memdesc));
@@ -377,66 +343,10 @@
 kgsl_gem_free_object(struct drm_gem_object *obj)
 {
 	kgsl_gem_free_memory(obj);
-	kgsl_gem_free_mmap_offset(obj);
 	drm_gem_object_release(obj);
 	kfree(obj->driver_private);
 }
 
-static int
-kgsl_gem_create_mmap_offset(struct drm_gem_object *obj)
-{
-	struct drm_device *dev = obj->dev;
-	struct drm_gem_mm *mm = dev->mm_private;
-	struct drm_kgsl_gem_object *priv = obj->driver_private;
-	struct drm_map_list *list;
-	int msize;
-
-	list = &obj->map_list;
-	list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL);
-	if (list->map == NULL) {
-		DRM_ERROR("Unable to allocate drm_map_list\n");
-		return -ENOMEM;
-	}
-
-	msize = obj->size * priv->bufcount;
-
-	list->map->type = _DRM_GEM;
-	list->map->size = msize;
-	list->map->handle = obj;
-
-	/* Allocate a mmap offset */
-	list->file_offset_node = drm_mm_search_free(&mm->offset_manager,
-						    msize / PAGE_SIZE,
-						    0, 0);
-
-	if (!list->file_offset_node) {
-		DRM_ERROR("Failed to allocate offset for %d\n", obj->name);
-		kfree(list->map);
-		return -ENOMEM;
-	}
-
-	list->file_offset_node = drm_mm_get_block(list->file_offset_node,
-						  msize / PAGE_SIZE, 0);
-
-	if (!list->file_offset_node) {
-		DRM_ERROR("Unable to create the file_offset_node\n");
-		kfree(list->map);
-		return -ENOMEM;
-	}
-
-	list->hash.key = list->file_offset_node->start;
-	if (drm_ht_insert_item(&mm->offset_hash, &list->hash)) {
-		DRM_ERROR("Failed to add to map hash\n");
-		drm_mm_put_block(list->file_offset_node);
-		kfree(list->map);
-		return -ENOMEM;
-	}
-
-	priv->mmap_offset = ((uint64_t) list->hash.key) << PAGE_SHIFT;
-
-	return 0;
-}
-
 int
 kgsl_gem_obj_addr(int drm_fd, int handle, unsigned long *start,
 			unsigned long *len)
@@ -483,9 +393,6 @@
 			priv->bufs[priv->active].offset;
 
 		*len = priv->memdesc.size;
-
-		kgsl_gem_mem_flush(&priv->memdesc,
-				   priv->type, DRM_KGSL_GEM_CACHE_OP_TO_DEV);
 	} else {
 		*start = 0;
 		*len = 0;
@@ -516,10 +423,7 @@
 	priv->active = 0;
 	priv->bound = 0;
 
-	/* To preserve backwards compatability, the default memory source
-	   is EBI */
-
-	priv->type = DRM_KGSL_GEM_TYPE_PMEM | DRM_KGSL_GEM_PMEM_EBI;
+	priv->type = DRM_KGSL_GEM_TYPE_KMEM;
 
 	ret = drm_gem_handle_create(file_priv, obj, handle);
 
@@ -561,8 +465,11 @@
 	}
 
 	ret = kgsl_gem_init_obj(dev, file_priv, obj, &handle);
-	if (ret)
+	if (ret) {
+		drm_gem_object_release(obj);
+		DRM_ERROR("Unable to initialize GEM object ret = %d\n", ret);
 		return ret;
+	}
 
 	create->handle = handle;
 	return 0;
@@ -635,6 +542,106 @@
 }
 
 int
+kgsl_gem_create_from_ion_ioctl(struct drm_device *dev, void *data,
+		      struct drm_file *file_priv)
+{
+	struct drm_kgsl_gem_create_from_ion *args = data;
+	struct drm_gem_object *obj;
+	struct ion_handle *ion_handle;
+	struct drm_kgsl_gem_object *priv;
+	struct sg_table *sg_table;
+	struct scatterlist *s;
+	int ret, handle;
+	unsigned long size;
+
+	ion_handle = ion_import_dma_buf(kgsl_drm_ion_client, args->ion_fd);
+	if (IS_ERR_OR_NULL(ion_handle)) {
+		DRM_ERROR("Unable to import dmabuf.  Error number = %d\n",
+			(int)PTR_ERR(ion_handle));
+		return -EINVAL;
+	}
+
+	ion_handle_get_size(kgsl_drm_ion_client, ion_handle, &size);
+
+	if (size == 0) {
+		ion_free(kgsl_drm_ion_client, ion_handle);
+		DRM_ERROR(
+		"cannot create GEM object from zero size ION buffer\n");
+		return -EINVAL;
+	}
+
+	obj = drm_gem_object_alloc(dev, size);
+
+	if (obj == NULL) {
+		ion_free(kgsl_drm_ion_client, ion_handle);
+		DRM_ERROR("Unable to allocate the GEM object\n");
+		return -ENOMEM;
+	}
+
+	ret = kgsl_gem_init_obj(dev, file_priv, obj, &handle);
+	if (ret) {
+		ion_free(kgsl_drm_ion_client, ion_handle);
+		drm_gem_object_release(obj);
+		DRM_ERROR("Unable to initialize GEM object ret = %d\n", ret);
+		return ret;
+	}
+
+	priv = obj->driver_private;
+	priv->ion_handle = ion_handle;
+
+	priv->type = DRM_KGSL_GEM_TYPE_KMEM;
+	list_add(&priv->list, &kgsl_mem_list);
+
+	priv->pagetable = kgsl_mmu_getpagetable(KGSL_MMU_GLOBAL_PT);
+
+	priv->memdesc.pagetable = priv->pagetable;
+
+	sg_table = ion_sg_table(kgsl_drm_ion_client,
+		priv->ion_handle);
+	if (IS_ERR_OR_NULL(priv->ion_handle)) {
+		DRM_ERROR("Unable to get ION sg table\n");
+		ion_free(kgsl_drm_ion_client,
+			priv->ion_handle);
+		priv->ion_handle = NULL;
+		kgsl_mmu_putpagetable(priv->pagetable);
+		drm_gem_object_release(obj);
+		kfree(priv);
+		return -ENOMEM;
+	}
+
+	priv->memdesc.sg = sg_table->sgl;
+
+	/* Calculate the size of the memdesc from the sglist */
+
+	priv->memdesc.sglen = 0;
+
+	for (s = priv->memdesc.sg; s != NULL; s = sg_next(s)) {
+		priv->memdesc.size += s->length;
+		priv->memdesc.sglen++;
+	}
+
+	ret = kgsl_mmu_map(priv->pagetable, &priv->memdesc,
+		GSL_PT_PAGE_RV | GSL_PT_PAGE_WV);
+	if (ret) {
+		DRM_ERROR("kgsl_mmu_map failed.  ret = %d\n", ret);
+		ion_free(kgsl_drm_ion_client,
+			priv->ion_handle);
+		priv->ion_handle = NULL;
+		kgsl_mmu_putpagetable(priv->pagetable);
+		drm_gem_object_release(obj);
+		kfree(priv);
+		return -ENOMEM;
+	}
+
+	priv->bufs[0].offset = 0;
+	priv->bufs[0].gpuaddr = priv->memdesc.gpuaddr;
+	priv->flags |= DRM_KGSL_GEM_FLAG_MAPPED;
+
+	args->handle = handle;
+	return 0;
+}
+
+int
 kgsl_gem_get_ion_fd_ioctl(struct drm_device *dev, void *data,
 			struct drm_file *file_priv)
 {
@@ -655,10 +662,16 @@
 
 	if (TYPE_IS_FD(priv->type))
 		ret = -EINVAL;
-	else {
+	else if (TYPE_IS_PMEM(priv->type) || TYPE_IS_MEM(priv->type)) {
 		if (priv->ion_handle) {
 			args->ion_fd = ion_share_dma_buf(
-			kgsl_drm_ion_phys_client, priv->ion_handle);
+				kgsl_drm_ion_client, priv->ion_handle);
+			if (args->ion_fd < 0) {
+				DRM_ERROR(
+				"Could not share ion buffer. Error = %d\n",
+					args->ion_fd);
+				ret = -EINVAL;
+			}
 		} else {
 			DRM_ERROR("GEM object has no ion memory allocated.\n");
 			ret = -EINVAL;
@@ -770,13 +783,9 @@
 
 	if (ret) {
 		DRM_ERROR("Unable to allocate object memory\n");
-	} else if (!priv->mmap_offset) {
-		ret = kgsl_gem_create_mmap_offset(obj);
-		if (ret)
-			DRM_ERROR("Unable to create a mmap offset\n");
 	}
 
-	args->offset = priv->mmap_offset;
+	args->offset = 0;
 
 	drm_gem_object_unreference(obj);
 	mutex_unlock(&dev->struct_mutex);
@@ -788,33 +797,7 @@
 kgsl_gem_mmap_ioctl(struct drm_device *dev, void *data,
 			struct drm_file *file_priv)
 {
-	struct drm_kgsl_gem_mmap *args = data;
-	struct drm_gem_object *obj;
-	unsigned long addr;
-
-	obj = drm_gem_object_lookup(dev, file_priv, args->handle);
-
-	if (obj == NULL) {
-		DRM_ERROR("Invalid GEM handle %x\n", args->handle);
-		return -EBADF;
-	}
-
-	down_write(&current->mm->mmap_sem);
-
-	addr = do_mmap(obj->filp, 0, args->size,
-		       PROT_READ | PROT_WRITE, MAP_SHARED,
-		       args->offset);
-
-	up_write(&current->mm->mmap_sem);
-
-	mutex_lock(&dev->struct_mutex);
-	drm_gem_object_unreference(obj);
-	mutex_unlock(&dev->struct_mutex);
-
-	if (IS_ERR((void *) addr))
-		return addr;
-
-	args->hostptr = (uint32_t) addr;
+	/* Ion is used for mmap at this time */
 	return 0;
 }
 
@@ -847,18 +830,6 @@
 		return ret;
 	}
 
-	if (priv->mmap_offset == 0) {
-		ret = kgsl_gem_create_mmap_offset(obj);
-		if (ret) {
-			drm_gem_object_unreference(obj);
-			mutex_unlock(&dev->struct_mutex);
-			return ret;
-		}
-	}
-
-	args->offset = priv->mmap_offset;
-	args->phys = priv->memdesc.physaddr;
-
 	drm_gem_object_unreference(obj);
 	mutex_unlock(&dev->struct_mutex);
 
@@ -1042,122 +1013,6 @@
 	}
 }
 
-static struct vm_operations_struct kgsl_gem_kmem_vm_ops = {
-	.fault = kgsl_gem_kmem_fault,
-	.open = drm_gem_vm_open,
-	.close = drm_gem_vm_close,
-};
-
-static struct vm_operations_struct kgsl_gem_phys_vm_ops = {
-	.fault = kgsl_gem_phys_fault,
-	.open = drm_gem_vm_open,
-	.close = drm_gem_vm_close,
-};
-
-/* This is a clone of the standard drm_gem_mmap function modified to allow
-   us to properly map KMEM regions as well as the PMEM regions */
-
-int msm_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
-{
-	struct drm_file *priv = filp->private_data;
-	struct drm_device *dev = priv->minor->dev;
-	struct drm_gem_mm *mm = dev->mm_private;
-	struct drm_local_map *map = NULL;
-	struct drm_gem_object *obj;
-	struct drm_hash_item *hash;
-	struct drm_kgsl_gem_object *gpriv;
-	int ret = 0;
-
-	mutex_lock(&dev->struct_mutex);
-
-	if (drm_ht_find_item(&mm->offset_hash, vma->vm_pgoff, &hash)) {
-		mutex_unlock(&dev->struct_mutex);
-		return drm_mmap(filp, vma);
-	}
-
-	map = drm_hash_entry(hash, struct drm_map_list, hash)->map;
-	if (!map ||
-	    ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN))) {
-		ret =  -EPERM;
-		goto out_unlock;
-	}
-
-	/* Check for valid size. */
-	if (map->size < vma->vm_end - vma->vm_start) {
-		ret = -EINVAL;
-		goto out_unlock;
-	}
-
-	obj = map->handle;
-
-	gpriv = obj->driver_private;
-
-	/* VM_PFNMAP is only for memory that doesn't use struct page
-	 * in other words, not "normal" memory.  If you try to use it
-	 * with "normal" memory then the mappings don't get flushed. */
-
-	if (TYPE_IS_MEM(gpriv->type)) {
-		vma->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
-		vma->vm_ops = &kgsl_gem_kmem_vm_ops;
-	} else {
-		vma->vm_flags |= VM_RESERVED | VM_IO | VM_PFNMAP |
-			VM_DONTEXPAND;
-		vma->vm_ops = &kgsl_gem_phys_vm_ops;
-	}
-
-	vma->vm_private_data = map->handle;
-
-
-	/* Take care of requested caching policy */
-	if (gpriv->type == DRM_KGSL_GEM_TYPE_KMEM ||
-	    gpriv->type & DRM_KGSL_GEM_CACHE_MASK) {
-		if (gpriv->type & DRM_KGSL_GEM_CACHE_WBACKWA)
-			vma->vm_page_prot =
-			pgprot_writebackwacache(vma->vm_page_prot);
-		else if (gpriv->type & DRM_KGSL_GEM_CACHE_WBACK)
-				vma->vm_page_prot =
-				pgprot_writebackcache(vma->vm_page_prot);
-		else if (gpriv->type & DRM_KGSL_GEM_CACHE_WTHROUGH)
-				vma->vm_page_prot =
-				pgprot_writethroughcache(vma->vm_page_prot);
-		else
-			vma->vm_page_prot =
-			pgprot_writecombine(vma->vm_page_prot);
-	} else {
-		if (gpriv->type == DRM_KGSL_GEM_TYPE_KMEM_NOCACHE)
-			vma->vm_page_prot =
-			pgprot_noncached(vma->vm_page_prot);
-		else
-			/* default pmem is WC */
-			vma->vm_page_prot =
-			pgprot_writecombine(vma->vm_page_prot);
-	}
-
-	/* flush out existing KMEM cached mappings if new ones are
-	 * of uncached type */
-	if (IS_MEM_UNCACHED(gpriv->type))
-		kgsl_cache_range_op(&gpriv->memdesc,
-				    KGSL_CACHE_OP_FLUSH);
-
-	/* Add the other memory types here */
-
-	/* Take a ref for this mapping of the object, so that the fault
-	 * handler can dereference the mmap offset's pointer to the object.
-	 * This reference is cleaned up by the corresponding vm_close
-	 * (which should happen whether the vma was created by this call, or
-	 * by a vm_open due to mremap or partial unmap or whatever).
-	 */
-	drm_gem_object_reference(obj);
-
-	vma->vm_file = filp;	/* Needed for drm_vm_open() */
-	drm_vm_open_locked(vma);
-
-out_unlock:
-	mutex_unlock(&dev->struct_mutex);
-
-	return ret;
-}
-
 void
 cleanup_fence(struct drm_kgsl_gem_object_fence *fence, int check_waiting)
 {
@@ -1520,6 +1375,8 @@
 	DRM_IOCTL_DEF_DRV(KGSL_GEM_MMAP, kgsl_gem_mmap_ioctl, 0),
 	DRM_IOCTL_DEF_DRV(KGSL_GEM_GET_BUFINFO, kgsl_gem_get_bufinfo_ioctl, 0),
 	DRM_IOCTL_DEF_DRV(KGSL_GEM_GET_ION_FD, kgsl_gem_get_ion_fd_ioctl, 0),
+	DRM_IOCTL_DEF_DRV(KGSL_GEM_CREATE_FROM_ION,
+		kgsl_gem_create_from_ion_ioctl, 0),
 	DRM_IOCTL_DEF_DRV(KGSL_GEM_SET_BUFCOUNT,
 		      kgsl_gem_set_bufcount_ioctl, 0),
 	DRM_IOCTL_DEF_DRV(KGSL_GEM_SET_ACTIVE, kgsl_gem_set_active_ioctl, 0),
@@ -1538,19 +1395,13 @@
 	.open = drm_open,
 	.release = drm_release,
 	.unlocked_ioctl = drm_ioctl,
-	.mmap = msm_drm_gem_mmap,
+	.mmap = drm_gem_mmap,
 	.poll = drm_poll,
 	.fasync = drm_fasync,
 };
 
 static struct drm_driver driver = {
 	.driver_features = DRIVER_GEM,
-	.load = kgsl_drm_load,
-	.unload = kgsl_drm_unload,
-	.preclose = kgsl_drm_preclose,
-	.suspend = kgsl_drm_suspend,
-	.resume = kgsl_drm_resume,
-	.reclaim_buffers = drm_core_reclaim_buffers,
 	.gem_init_object = kgsl_gem_init_object,
 	.gem_free_object = kgsl_gem_free_object,
 	.ioctls = kgsl_drm_ioctls,
@@ -1584,9 +1435,9 @@
 	}
 
 	/* Create ION Client */
-	kgsl_drm_ion_phys_client = msm_ion_client_create(
-			ION_HEAP_CARVEOUT_MASK, "kgsl_drm");
-	if (!kgsl_drm_ion_phys_client) {
+	kgsl_drm_ion_client = msm_ion_client_create(
+			0xffffffff, "kgsl_drm");
+	if (!kgsl_drm_ion_client) {
 		DRM_ERROR("Unable to create ION client\n");
 		return -ENOMEM;
 	}
@@ -1598,9 +1449,9 @@
 {
 	kgsl_drm_inited = DRM_KGSL_NOT_INITED;
 
-	if (kgsl_drm_ion_phys_client)
-		ion_client_destroy(kgsl_drm_ion_phys_client);
-	kgsl_drm_ion_phys_client = NULL;
+	if (kgsl_drm_ion_client)
+		ion_client_destroy(kgsl_drm_ion_client);
+	kgsl_drm_ion_client = NULL;
 
 	drm_platform_exit(&driver, driver.kdriver.platform_device);
 }
diff --git a/drivers/gpu/msm/kgsl_events.c b/drivers/gpu/msm/kgsl_events.c
new file mode 100644
index 0000000..6798eed
--- /dev/null
+++ b/drivers/gpu/msm/kgsl_events.c
@@ -0,0 +1,324 @@
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <kgsl_device.h>
+
+#include "kgsl_trace.h"
+
+static void _add_event_to_list(struct list_head *head, struct kgsl_event *event)
+{
+	struct list_head *n;
+
+	for (n = head->next; n != head; n = n->next) {
+		struct kgsl_event *e =
+			list_entry(n, struct kgsl_event, list);
+
+		if (timestamp_cmp(e->timestamp, event->timestamp) > 0) {
+			list_add(&event->list, n->prev);
+			break;
+		}
+	}
+
+	if (n == head)
+		list_add_tail(&event->list, head);
+}
+
+/**
+ * kgsl_add_event - Add a new timstamp event for the KGSL device
+ * @device - KGSL device for the new event
+ * @id - the context ID that the event should be added to
+ * @ts - the timestamp to trigger the event on
+ * @cb - callback function to call when the timestamp expires
+ * @priv - private data for the specific event type
+ * @owner - driver instance that owns this event
+ *
+ * @returns - 0 on success or error code on failure
+ */
+int kgsl_add_event(struct kgsl_device *device, u32 id, u32 ts,
+	void (*cb)(struct kgsl_device *, void *, u32, u32), void *priv,
+	void *owner)
+{
+	struct kgsl_event *event;
+	unsigned int cur_ts;
+	struct kgsl_context *context = NULL;
+
+	if (cb == NULL)
+		return -EINVAL;
+
+	if (id != KGSL_MEMSTORE_GLOBAL) {
+		context = idr_find(&device->context_idr, id);
+		if (context == NULL)
+			return -EINVAL;
+	}
+	cur_ts = kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_RETIRED);
+
+	/*
+	 * Check to see if the requested timestamp has already fired.  If it
+	 * did do the callback right away.  Make sure to send the timestamp that
+	 * the event expected instead of the current timestamp because sometimes
+	 * the event handlers can get confused.
+	 */
+
+	if (timestamp_cmp(cur_ts, ts) >= 0) {
+		trace_kgsl_fire_event(id, ts, 0);
+		cb(device, priv, id, ts);
+		return 0;
+	}
+
+	event = kzalloc(sizeof(*event), GFP_KERNEL);
+	if (event == NULL)
+		return -ENOMEM;
+
+	event->context = context;
+	event->timestamp = ts;
+	event->priv = priv;
+	event->func = cb;
+	event->owner = owner;
+	event->created = jiffies;
+
+	trace_kgsl_register_event(id, ts);
+
+	/* inc refcount to avoid race conditions in cleanup */
+	if (context)
+		kgsl_context_get(context);
+
+	/* Add the event to either the owning context or the global list */
+
+	if (context) {
+		_add_event_to_list(&context->events, event);
+
+		/*
+		 * Add it to the master list of contexts with pending events if
+		 * it isn't already there
+		 */
+
+		if (list_empty(&context->events_list))
+			list_add_tail(&context->events_list,
+				&device->events_pending_list);
+
+	} else
+		_add_event_to_list(&device->events, event);
+
+	/*
+	 * Increase the active count on the device to avoid going into power
+	 * saving modes while events are pending
+	 */
+
+	device->active_cnt++;
+
+	queue_work(device->work_queue, &device->ts_expired_ws);
+	return 0;
+}
+EXPORT_SYMBOL(kgsl_add_event);
+
+/**
+ * kgsl_cancel_events_ctxt - Cancel all events for a context
+ * @device - KGSL device for the events to cancel
+ * @context - context whose events we want to cancel
+ *
+ */
+void kgsl_cancel_events_ctxt(struct kgsl_device *device,
+	struct kgsl_context *context)
+{
+	struct kgsl_event *event, *event_tmp;
+	unsigned int id, cur;
+
+	cur = kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_RETIRED);
+	id = context->id;
+
+	list_for_each_entry_safe(event, event_tmp, &context->events, list) {
+		/*
+		 * "cancel" the events by calling their callback.
+		 * Currently, events are used for lock and memory
+		 * management, so if the process is dying the right
+		 * thing to do is release or free.
+		 *
+		 * Send the current timestamp so the event knows how far the
+		 * system got before the event was canceled
+		 */
+
+		trace_kgsl_fire_event(id, cur, jiffies - event->created);
+
+		if (event->func)
+			event->func(device, event->priv, id, cur);
+
+		kgsl_context_put(context);
+		list_del(&event->list);
+		kfree(event);
+
+		kgsl_active_count_put(device);
+	}
+
+	/* Remove ourselves from the master pending list */
+	list_del_init(&context->events_list);
+}
+
+/**
+ * kgsl_cancel_events - Cancel all generic events for a process
+ * @device - KGSL device for the events to cancel
+ * @owner - driver instance that owns the events to cancel
+ *
+ */
+void kgsl_cancel_events(struct kgsl_device *device,
+	void *owner)
+{
+	struct kgsl_event *event, *event_tmp;
+	unsigned int cur;
+
+	cur = kgsl_readtimestamp(device, NULL, KGSL_TIMESTAMP_RETIRED);
+
+	list_for_each_entry_safe(event, event_tmp, &device->events, list) {
+		if (event->owner != owner)
+			continue;
+
+		/*
+		 * "cancel" the events by calling their callback.
+		 * Currently, events are used for lock and memory
+		 * management, so if the process is dying the right
+		 * thing to do is release or free. Send the current timestamp so
+		 * the callback knows how far the GPU made it before things went
+		 * explosion
+		 */
+
+		trace_kgsl_fire_event(KGSL_MEMSTORE_GLOBAL, cur,
+			jiffies - event->created);
+
+		if (event->func)
+			event->func(device, event->priv, KGSL_MEMSTORE_GLOBAL,
+				cur);
+
+		if (event->context)
+			kgsl_context_put(event->context);
+
+		list_del(&event->list);
+		kfree(event);
+
+		kgsl_active_count_put(device);
+	}
+}
+EXPORT_SYMBOL(kgsl_cancel_events);
+
+static void _process_event_list(struct kgsl_device *device,
+		struct list_head *head, unsigned int timestamp)
+{
+	struct kgsl_event *event, *tmp;
+	unsigned int id;
+
+	list_for_each_entry_safe(event, tmp, head, list) {
+		if (timestamp_cmp(timestamp, event->timestamp) < 0)
+			break;
+
+		id = event->context ? event->context->id : KGSL_MEMSTORE_GLOBAL;
+
+		/*
+		 * Send the timestamp of the expired event, not the current
+		 * timestamp.  This prevents the event handlers from getting
+		 * confused if they don't bother comparing the current timetamp
+		 * to the timestamp they wanted
+		 */
+
+		trace_kgsl_fire_event(id, event->timestamp,
+			jiffies - event->created);
+
+		if (event->func)
+			event->func(device, event->priv, id, event->timestamp);
+
+		if (event->context)
+			kgsl_context_put(event->context);
+
+		list_del(&event->list);
+		kfree(event);
+
+		kgsl_active_count_put(device);
+	}
+}
+
+static inline int _mark_next_event(struct kgsl_device *device,
+		struct list_head *head)
+{
+	struct kgsl_event *event;
+
+	if (!list_empty(head)) {
+		event = list_first_entry(head, struct kgsl_event, list);
+
+		/*
+		 * Next event will return 0 if the event was marked or 1 if the
+		 * timestamp on the event has passed - return that up a layer
+		 */
+
+		return device->ftbl->next_event(device, event);
+	}
+
+	return 0;
+}
+
+static int kgsl_process_context_events(struct kgsl_device *device,
+		struct kgsl_context *context)
+{
+	while (1) {
+		unsigned int timestamp = kgsl_readtimestamp(device, context,
+			KGSL_TIMESTAMP_RETIRED);
+
+		_process_event_list(device, &context->events, timestamp);
+
+		/*
+		 * _mark_next event will return 1 as long as the next event
+		 * timestamp has expired - this is to cope with an unavoidable
+		 * race condition with the GPU that is still processing events.
+		 */
+
+		if (!_mark_next_event(device, &context->events))
+			break;
+	}
+
+	/*
+	 * Return 0 if the list is empty so the calling function can remove the
+	 * context from the pending list
+	 */
+
+	return list_empty(&context->events) ? 0 : 1;
+}
+
+void kgsl_process_events(struct work_struct *work)
+{
+	struct kgsl_device *device = container_of(work, struct kgsl_device,
+		ts_expired_ws);
+	struct kgsl_context *context, *tmp;
+	uint32_t timestamp;
+
+	mutex_lock(&device->mutex);
+
+	/* Process expired global events */
+	timestamp = kgsl_readtimestamp(device, NULL, KGSL_TIMESTAMP_RETIRED);
+	_process_event_list(device, &device->events, timestamp);
+	_mark_next_event(device, &device->events);
+
+	/* Now process all of the pending contexts */
+	list_for_each_entry_safe(context, tmp, &device->events_pending_list,
+		events_list) {
+
+		/*
+		 * If kgsl_timestamp_expired_context returns 0 then it no longer
+		 * has any pending events and can be removed from the list
+		 */
+
+		if (kgsl_process_context_events(device, context) == 0)
+			list_del_init(&context->events_list);
+	}
+
+	mutex_unlock(&device->mutex);
+}
+EXPORT_SYMBOL(kgsl_process_events);
diff --git a/drivers/gpu/msm/kgsl_gpummu.c b/drivers/gpu/msm/kgsl_gpummu.c
index 326e79d..8f28505 100644
--- a/drivers/gpu/msm/kgsl_gpummu.c
+++ b/drivers/gpu/msm/kgsl_gpummu.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/drivers/gpu/msm/kgsl_gpummu.h b/drivers/gpu/msm/kgsl_gpummu.h
index caa5df1..99e7d5f 100644
--- a/drivers/gpu/msm/kgsl_gpummu.h
+++ b/drivers/gpu/msm/kgsl_gpummu.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index 818bd63..df8e1d0 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -11,6 +11,7 @@
  *
  */
 #include <linux/types.h>
+#include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/spinlock.h>
 #include <linux/genalloc.h>
@@ -33,16 +34,18 @@
 #include "z180.h"
 
 
-static struct kgsl_iommu_register_list kgsl_iommuv1_reg[KGSL_IOMMU_REG_MAX] = {
+static struct kgsl_iommu_register_list kgsl_iommuv0_reg[KGSL_IOMMU_REG_MAX] = {
 	{ 0, 0, 0 },				/* GLOBAL_BASE */
 	{ 0x10, 0x0003FFFF, 14 },		/* TTBR0 */
 	{ 0x14, 0x0003FFFF, 14 },		/* TTBR1 */
 	{ 0x20, 0, 0 },				/* FSR */
 	{ 0x800, 0, 0 },			/* TLBIALL */
 	{ 0x820, 0, 0 },			/* RESUME */
+	{ 0x03C, 0, 0 },			/* TLBLKCR */
+	{ 0x818, 0, 0 },			/* V2PUR */
 };
 
-static struct kgsl_iommu_register_list kgsl_iommuv2_reg[KGSL_IOMMU_REG_MAX] = {
+static struct kgsl_iommu_register_list kgsl_iommuv1_reg[KGSL_IOMMU_REG_MAX] = {
 	{ 0, 0, 0 },				/* GLOBAL_BASE */
 	{ 0x20, 0x00FFFFFF, 14 },		/* TTBR0 */
 	{ 0x28, 0x00FFFFFF, 14 },		/* TTBR1 */
@@ -562,8 +565,8 @@
 				sizeof(struct kgsl_iommu_pt));
 		return NULL;
 	}
-	/* L2 redirect is not stable on IOMMU v2 */
-	if (msm_soc_version_supports_iommu_v1())
+	/* L2 redirect is not stable on IOMMU v1 */
+	if (msm_soc_version_supports_iommu_v0())
 		iommu_pt->domain = iommu_domain_alloc(&platform_bus_type,
 					MSM_IOMMU_DOMAIN_PT_CACHEABLE);
 	else
@@ -746,7 +749,7 @@
 	uint32_t lock_gpu_addr = 0;
 
 	if (KGSL_DEVICE_3D0 != mmu->device->id ||
-		!msm_soc_version_supports_iommu_v1() ||
+		!msm_soc_version_supports_iommu_v0() ||
 		!kgsl_mmu_is_perprocess() ||
 		iommu->sync_lock_vars)
 		return 0;
@@ -782,16 +785,26 @@
  */
 static int kgsl_iommu_init_sync_lock(struct kgsl_mmu *mmu)
 {
-	struct kgsl_iommu *iommu = mmu->device->mmu.priv;
+	struct kgsl_iommu *iommu = mmu->priv;
 	int status = 0;
 	uint32_t lock_phy_addr = 0;
 	uint32_t page_offset = 0;
 
-	if (KGSL_DEVICE_3D0 != mmu->device->id ||
-		!msm_soc_version_supports_iommu_v1() ||
+	if (!msm_soc_version_supports_iommu_v0() ||
 		!kgsl_mmu_is_perprocess())
 		return status;
 
+	/*
+	 * For 2D devices cpu side sync lock is required. For 3D device,
+	 * since we only have a single 3D core and we always ensure that
+	 * 3D core is idle while writing to IOMMU register using CPU this
+	 * lock is not required
+	 */
+	if (KGSL_DEVICE_2D0 == mmu->device->id ||
+		KGSL_DEVICE_2D1 == mmu->device->id) {
+		return status;
+	}
+
 	/* Return if already initialized */
 	if (iommu->sync_lock_initialized)
 		return status;
@@ -1100,7 +1113,7 @@
 	int i = 0;
 	struct kgsl_iommu *iommu = mmu->priv;
 
-	if (!msm_soc_version_supports_iommu_v1())
+	if (!msm_soc_version_supports_iommu_v0())
 		return 0;
 
 	for (i = 0; i < iommu->unit_count; i++) {
@@ -1178,15 +1191,15 @@
 	if (status)
 		goto done;
 
-	iommu->iommu_reg_list = kgsl_iommuv1_reg;
-	iommu->ctx_offset = KGSL_IOMMU_CTX_OFFSET_V1;
+	iommu->iommu_reg_list = kgsl_iommuv0_reg;
+	iommu->ctx_offset = KGSL_IOMMU_CTX_OFFSET_V0;
 
-	if (msm_soc_version_supports_iommu_v1()) {
+	if (msm_soc_version_supports_iommu_v0()) {
+		iommu->iommu_reg_list = kgsl_iommuv0_reg;
+		iommu->ctx_offset = KGSL_IOMMU_CTX_OFFSET_V0;
+	} else {
 		iommu->iommu_reg_list = kgsl_iommuv1_reg;
 		iommu->ctx_offset = KGSL_IOMMU_CTX_OFFSET_V1;
-	} else {
-		iommu->iommu_reg_list = kgsl_iommuv2_reg;
-		iommu->ctx_offset = KGSL_IOMMU_CTX_OFFSET_V2;
 	}
 
 	/* A nop is required in an indirect buffer when switching
@@ -1229,7 +1242,7 @@
 
 	/* If chip is not 8960 then we use the 2nd context bank for pagetable
 	 * switching on the 3D side for which a separate table is allocated */
-	if (!cpu_is_msm8960() && msm_soc_version_supports_iommu_v1()) {
+	if (!cpu_is_msm8960() && msm_soc_version_supports_iommu_v0()) {
 		mmu->priv_bank_table =
 			kgsl_mmu_getpagetable(KGSL_MMU_PRIV_BANK_TABLE_NAME);
 		if (mmu->priv_bank_table == NULL) {
@@ -1260,6 +1273,111 @@
 	return status;
 }
 
+/*
+ * kgsl_iommu_lock_rb_in_tlb - Allocates tlb entries and locks the
+ * virtual to physical address translation of ringbuffer for 3D
+ * device into tlb.
+ * @mmu - Pointer to mmu structure
+ *
+ * Return - void
+ */
+static void kgsl_iommu_lock_rb_in_tlb(struct kgsl_mmu *mmu)
+{
+	struct kgsl_device *device = mmu->device;
+	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+	struct adreno_ringbuffer *rb;
+	struct kgsl_iommu *iommu = mmu->priv;
+	unsigned int num_tlb_entries;
+	unsigned int tlblkcr = 0;
+	unsigned int v2pxx = 0;
+	unsigned int vaddr = 0;
+	int i, j, k, l;
+
+	if (!iommu->sync_lock_initialized)
+		return;
+
+	rb = &adreno_dev->ringbuffer;
+	num_tlb_entries = rb->buffer_desc.size / PAGE_SIZE;
+
+	for (i = 0; i < iommu->unit_count; i++) {
+		struct kgsl_iommu_unit *iommu_unit = &iommu->iommu_units[i];
+		for (j = 0; j < iommu_unit->dev_count; j++) {
+			tlblkcr = 0;
+			if (cpu_is_msm8960())
+				tlblkcr |= ((num_tlb_entries &
+					KGSL_IOMMU_TLBLKCR_FLOOR_MASK) <<
+					KGSL_IOMMU_TLBLKCR_FLOOR_SHIFT);
+			else
+				tlblkcr |= (((num_tlb_entries *
+					iommu_unit->dev_count) &
+					KGSL_IOMMU_TLBLKCR_FLOOR_MASK) <<
+					KGSL_IOMMU_TLBLKCR_FLOOR_SHIFT);
+			/* Do not invalidate locked entries on tlbiall flush */
+			tlblkcr	|= ((1 & KGSL_IOMMU_TLBLKCR_TLBIALLCFG_MASK)
+				<< KGSL_IOMMU_TLBLKCR_TLBIALLCFG_SHIFT);
+			tlblkcr	|= ((1 & KGSL_IOMMU_TLBLKCR_TLBIASIDCFG_MASK)
+				<< KGSL_IOMMU_TLBLKCR_TLBIASIDCFG_SHIFT);
+			tlblkcr	|= ((1 & KGSL_IOMMU_TLBLKCR_TLBIVAACFG_MASK)
+				<< KGSL_IOMMU_TLBLKCR_TLBIVAACFG_SHIFT);
+			/* Enable tlb locking */
+			tlblkcr |= ((1 & KGSL_IOMMU_TLBLKCR_LKE_MASK)
+				<< KGSL_IOMMU_TLBLKCR_LKE_SHIFT);
+			KGSL_IOMMU_SET_CTX_REG(iommu, iommu_unit,
+					iommu_unit->dev[j].ctx_id,
+					TLBLKCR, tlblkcr);
+		}
+		for (j = 0; j < iommu_unit->dev_count; j++) {
+			/* skip locking entries for private bank on 8960 */
+			if (cpu_is_msm8960() &&  KGSL_IOMMU_CONTEXT_PRIV == j)
+				continue;
+			/* Lock the ringbuffer virtual address into tlb */
+			vaddr = rb->buffer_desc.gpuaddr;
+			for (k = 0; k < num_tlb_entries; k++) {
+				v2pxx = 0;
+				v2pxx |= (((k + j * num_tlb_entries) &
+					KGSL_IOMMU_V2PXX_INDEX_MASK)
+					<< KGSL_IOMMU_V2PXX_INDEX_SHIFT);
+				v2pxx |= vaddr & (KGSL_IOMMU_V2PXX_VA_MASK <<
+						KGSL_IOMMU_V2PXX_VA_SHIFT);
+
+				KGSL_IOMMU_SET_CTX_REG(iommu, iommu_unit,
+						iommu_unit->dev[j].ctx_id,
+						V2PUR, v2pxx);
+				vaddr += PAGE_SIZE;
+				for (l = 0; l < iommu_unit->dev_count; l++) {
+					tlblkcr = KGSL_IOMMU_GET_CTX_REG(iommu,
+						iommu_unit,
+						iommu_unit->dev[l].ctx_id,
+						TLBLKCR);
+					mb();
+					tlblkcr &=
+					~(KGSL_IOMMU_TLBLKCR_VICTIM_MASK
+					<< KGSL_IOMMU_TLBLKCR_VICTIM_SHIFT);
+					tlblkcr |= (((k + 1 +
+					(j * num_tlb_entries)) &
+					KGSL_IOMMU_TLBLKCR_VICTIM_MASK) <<
+					KGSL_IOMMU_TLBLKCR_VICTIM_SHIFT);
+					KGSL_IOMMU_SET_CTX_REG(iommu,
+						iommu_unit,
+						iommu_unit->dev[l].ctx_id,
+						TLBLKCR, tlblkcr);
+				}
+			}
+		}
+		for (j = 0; j < iommu_unit->dev_count; j++) {
+			tlblkcr = KGSL_IOMMU_GET_CTX_REG(iommu, iommu_unit,
+						iommu_unit->dev[j].ctx_id,
+						TLBLKCR);
+			mb();
+			/* Disable tlb locking */
+			tlblkcr &= ~(KGSL_IOMMU_TLBLKCR_LKE_MASK
+				<< KGSL_IOMMU_TLBLKCR_LKE_SHIFT);
+			KGSL_IOMMU_SET_CTX_REG(iommu, iommu_unit,
+				iommu_unit->dev[j].ctx_id, TLBLKCR, tlblkcr);
+		}
+	}
+}
+
 static int kgsl_iommu_start(struct kgsl_mmu *mmu)
 {
 	int status;
@@ -1280,7 +1398,7 @@
 
 	/* We use the GPU MMU to control access to IOMMU registers on 8960 with
 	 * a225, hence we still keep the MMU active on 8960 */
-	if (cpu_is_msm8960()) {
+	if (cpu_is_msm8960() && KGSL_DEVICE_3D0 == mmu->device->id) {
 		struct kgsl_mh *mh = &(mmu->device->mh);
 		BUG_ON(iommu->iommu_units[0].reg_map.gpuaddr != 0 &&
 			mh->mpu_base > iommu->iommu_units[0].reg_map.gpuaddr);
@@ -1312,6 +1430,7 @@
 	 * changing pagetables we can use this lsb value of the pagetable w/o
 	 * having to read it again
 	 */
+	msm_iommu_lock();
 	for (i = 0; i < iommu->unit_count; i++) {
 		struct kgsl_iommu_unit *iommu_unit = &iommu->iommu_units[i];
 		for (j = 0; j < iommu_unit->dev_count; j++) {
@@ -1322,6 +1441,9 @@
 						TTBR0));
 		}
 	}
+	kgsl_iommu_lock_rb_in_tlb(mmu);
+	msm_iommu_unlock();
+
 
 	kgsl_iommu_disable_clk_on_ts(mmu, 0, false);
 	mmu->flags |= KGSL_FLAGS_STARTED;
@@ -1408,7 +1530,6 @@
 	 *
 	 *  call this with the global lock held
 	 */
-
 	if (mmu->flags & KGSL_FLAGS_STARTED) {
 		/* detach iommu attachment */
 		kgsl_detach_pagetable_iommu_domain(mmu);
@@ -1423,10 +1544,12 @@
 				for (j = 0; j < iommu_unit->dev_count; j++) {
 					if (iommu_unit->dev[j].fault) {
 						kgsl_iommu_enable_clk(mmu, j);
+						msm_iommu_lock();
 						KGSL_IOMMU_SET_CTX_REG(iommu,
 						iommu_unit,
 						iommu_unit->dev[j].ctx_id,
 						RESUME, 1);
+						msm_iommu_unlock();
 						iommu_unit->dev[j].fault = 0;
 					}
 				}
@@ -1521,15 +1644,15 @@
 	pt_base &= (iommu->iommu_reg_list[KGSL_IOMMU_CTX_TTBR0].reg_mask <<
 			iommu->iommu_reg_list[KGSL_IOMMU_CTX_TTBR0].reg_shift);
 
-	/* For v1 SMMU GPU needs to be idle for tlb invalidate as well */
-	if (msm_soc_version_supports_iommu_v1())
+	/* For v0 SMMU GPU needs to be idle for tlb invalidate as well */
+	if (msm_soc_version_supports_iommu_v0())
 		kgsl_idle(mmu->device);
 
 	/* Acquire GPU-CPU sync Lock here */
 	msm_iommu_lock();
 
 	if (flags & KGSL_MMUFLAGS_PTUPDATE) {
-		if (!msm_soc_version_supports_iommu_v1())
+		if (!msm_soc_version_supports_iommu_v0())
 			kgsl_idle(mmu->device);
 		for (i = 0; i < iommu->unit_count; i++) {
 			/* get the lsb value which should not change when
diff --git a/drivers/gpu/msm/kgsl_iommu.h b/drivers/gpu/msm/kgsl_iommu.h
index f539b07..bf40113 100644
--- a/drivers/gpu/msm/kgsl_iommu.h
+++ b/drivers/gpu/msm/kgsl_iommu.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -15,10 +15,30 @@
 
 #include <mach/iommu.h>
 
-#define KGSL_IOMMU_CTX_OFFSET_V1	0
-#define KGSL_IOMMU_CTX_OFFSET_V2	0x8000
+#define KGSL_IOMMU_CTX_OFFSET_V0	0
+#define KGSL_IOMMU_CTX_OFFSET_V1	0x8000
 #define KGSL_IOMMU_CTX_SHIFT		12
 
+/* TLBLKCR feilds */
+#define KGSL_IOMMU_TLBLKCR_LKE_MASK		0x00000001
+#define KGSL_IOMMU_TLBLKCR_LKE_SHIFT		0
+#define KGSL_IOMMU_TLBLKCR_TLBIALLCFG_MASK	0x00000001
+#define KGSL_IOMMU_TLBLKCR_TLBIALLCFG_SHIFT	1
+#define KGSL_IOMMU_TLBLKCR_TLBIASIDCFG_MASK	0x00000001
+#define KGSL_IOMMU_TLBLKCR_TLBIASIDCFG_SHIFT	2
+#define KGSL_IOMMU_TLBLKCR_TLBIVAACFG_MASK	0x00000001
+#define KGSL_IOMMU_TLBLKCR_TLBIVAACFG_SHIFT	3
+#define KGSL_IOMMU_TLBLKCR_FLOOR_MASK		0x000000FF
+#define KGSL_IOMMU_TLBLKCR_FLOOR_SHIFT		8
+#define KGSL_IOMMU_TLBLKCR_VICTIM_MASK		0x000000FF
+#define KGSL_IOMMU_TLBLKCR_VICTIM_SHIFT		16
+
+/* V2PXX feilds */
+#define KGSL_IOMMU_V2PXX_INDEX_MASK		0x000000FF
+#define KGSL_IOMMU_V2PXX_INDEX_SHIFT		0
+#define KGSL_IOMMU_V2PXX_VA_MASK		0x000FFFFF
+#define KGSL_IOMMU_V2PXX_VA_SHIFT		12
+
 enum kgsl_iommu_reg_map {
 	KGSL_IOMMU_GLOBAL_BASE = 0,
 	KGSL_IOMMU_CTX_TTBR0,
@@ -26,6 +46,8 @@
 	KGSL_IOMMU_CTX_FSR,
 	KGSL_IOMMU_CTX_TLBIALL,
 	KGSL_IOMMU_CTX_RESUME,
+	KGSL_IOMMU_CTX_TLBLKCR,
+	KGSL_IOMMU_CTX_V2PUR,
 	KGSL_IOMMU_REG_MAX
 };
 
diff --git a/drivers/gpu/msm/kgsl_log.h b/drivers/gpu/msm/kgsl_log.h
index 6fd28ab..81a35e0 100644
--- a/drivers/gpu/msm/kgsl_log.h
+++ b/drivers/gpu/msm/kgsl_log.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2008-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2008-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
diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c
index 533f02f..18aed14 100644
--- a/drivers/gpu/msm/kgsl_mmu.c
+++ b/drivers/gpu/msm/kgsl_mmu.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-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
diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h
index 9d96633..2b33baf 100644
--- a/drivers/gpu/msm/kgsl_mmu.h
+++ b/drivers/gpu/msm/kgsl_mmu.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-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
@@ -341,9 +341,9 @@
 static inline int kgsl_mmu_is_perprocess(void)
 {
 
-	/* We presently do not support per-process for IOMMU-v2 */
+	/* We presently do not support per-process for IOMMU-v1 */
 	return (kgsl_mmu_get_mmutype() != KGSL_MMU_TYPE_IOMMU)
-		|| msm_soc_version_supports_iommu_v1();
+		|| msm_soc_version_supports_iommu_v0();
 }
 #else
 static inline int kgsl_mmu_is_perprocess(void)
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index d33df60..0dcbfdf 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -30,7 +30,6 @@
 #define KGSL_PWRFLAGS_AXI_ON   2
 #define KGSL_PWRFLAGS_IRQ_ON   3
 
-#define GPU_SWFI_LATENCY	3
 #define UPDATE_BUSY_VAL		1000000
 #define UPDATE_BUSY		50
 
@@ -358,13 +357,13 @@
 	return snprintf(buf, PAGE_SIZE, "%d\n", pwr->num_pwrlevels - 1);
 }
 
-/* Given a GPU clock value, return the nearest powerlevel */
+/* Given a GPU clock value, return the lowest matching powerlevel */
 
 static int _get_nearest_pwrlevel(struct kgsl_pwrctrl *pwr, unsigned int clock)
 {
 	int i;
 
-	for (i = 0; i < pwr->num_pwrlevels - 1; i++) {
+	for (i = pwr->num_pwrlevels - 1; i >= 0; i--) {
 		if (abs(pwr->pwrlevels[i].gpu_freq - clock) < 5000000)
 			return i;
 	}
@@ -516,7 +515,6 @@
 	struct kgsl_device *device = kgsl_device_from_dev(dev);
 	struct kgsl_pwrctrl *pwr;
 	const long div = 1000/HZ;
-	static unsigned int org_interval_timeout = 1;
 	int rc;
 
 	if (device == NULL)
@@ -529,15 +527,11 @@
 	if (rc)
 		return rc;
 
-	if (org_interval_timeout == 1)
-		org_interval_timeout = pwr->interval_timeout;
-
 	mutex_lock(&device->mutex);
 
 	/* Let the timeout be requested in ms, but convert to jiffies. */
 	val /= div;
-	if (val >= org_interval_timeout)
-		pwr->interval_timeout = val;
+	pwr->interval_timeout = val;
 
 	mutex_unlock(&device->mutex);
 
@@ -549,10 +543,48 @@
 					char *buf)
 {
 	struct kgsl_device *device = kgsl_device_from_dev(dev);
+	int mul = 1000/HZ;
+	if (device == NULL)
+		return 0;
+	/* Show the idle_timeout converted to msec */
+	return snprintf(buf, PAGE_SIZE, "%d\n",
+		device->pwrctrl.interval_timeout * mul);
+}
+
+static int kgsl_pwrctrl_pmqos_latency_store(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf, size_t count)
+{
+	char temp[20];
+	unsigned long val;
+	struct kgsl_device *device = kgsl_device_from_dev(dev);
+	int rc;
+
+	if (device == NULL)
+		return 0;
+
+	snprintf(temp, sizeof(temp), "%.*s",
+			(int)min(count, sizeof(temp) - 1), buf);
+	rc = kstrtoul(temp, 0, &val);
+	if (rc)
+		return rc;
+
+	mutex_lock(&device->mutex);
+	device->pwrctrl.pm_qos_latency = val;
+	mutex_unlock(&device->mutex);
+
+	return count;
+}
+
+static int kgsl_pwrctrl_pmqos_latency_show(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf)
+{
+	struct kgsl_device *device = kgsl_device_from_dev(dev);
 	if (device == NULL)
 		return 0;
 	return snprintf(buf, PAGE_SIZE, "%d\n",
-		device->pwrctrl.interval_timeout);
+		device->pwrctrl.pm_qos_latency);
 }
 
 static int kgsl_pwrctrl_gpubusy_show(struct device *dev,
@@ -616,6 +648,14 @@
 	return num_chars;
 }
 
+static int kgsl_pwrctrl_reset_count_show(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
+{
+	struct kgsl_device *device = kgsl_device_from_dev(dev);
+	return snprintf(buf, PAGE_SIZE, "%d\n", device->reset_counter);
+}
+
 DEVICE_ATTR(gpuclk, 0644, kgsl_pwrctrl_gpuclk_show, kgsl_pwrctrl_gpuclk_store);
 DEVICE_ATTR(max_gpuclk, 0644, kgsl_pwrctrl_max_gpuclk_show,
 	kgsl_pwrctrl_max_gpuclk_store);
@@ -641,6 +681,12 @@
 DEVICE_ATTR(num_pwrlevels, 0444,
 	kgsl_pwrctrl_num_pwrlevels_show,
 	NULL);
+DEVICE_ATTR(pmqos_latency, 0644,
+	kgsl_pwrctrl_pmqos_latency_show,
+	kgsl_pwrctrl_pmqos_latency_store);
+DEVICE_ATTR(reset_count, 0444,
+	kgsl_pwrctrl_reset_count_show,
+	NULL);
 
 static const struct device_attribute *pwrctrl_attr_list[] = {
 	&dev_attr_gpuclk,
@@ -654,6 +700,8 @@
 	&dev_attr_min_pwrlevel,
 	&dev_attr_thermal_pwrlevel,
 	&dev_attr_num_pwrlevels,
+	&dev_attr_pmqos_latency,
+	&dev_attr_reset_count,
 	NULL
 };
 
@@ -718,23 +766,23 @@
 			/* High latency clock maintenance. */
 			if ((pwr->pwrlevels[0].gpu_freq > 0) &&
 				(requested_state != KGSL_STATE_NAP)) {
-				clk_set_rate(pwr->grp_clks[0],
-					pwr->pwrlevels[pwr->num_pwrlevels - 1].
-					gpu_freq);
 				for (i = KGSL_MAX_CLKS - 1; i > 0; i--)
 					if (pwr->grp_clks[i])
 						clk_unprepare(pwr->grp_clks[i]);
+				clk_set_rate(pwr->grp_clks[0],
+					pwr->pwrlevels[pwr->num_pwrlevels - 1].
+					gpu_freq);
 			}
 			kgsl_pwrctrl_busy_time(device, true);
 		} else if (requested_state == KGSL_STATE_SLEEP) {
 			/* High latency clock maintenance. */
+			for (i = KGSL_MAX_CLKS - 1; i > 0; i--)
+				if (pwr->grp_clks[i])
+					clk_unprepare(pwr->grp_clks[i]);
 			if ((pwr->pwrlevels[0].gpu_freq > 0))
 				clk_set_rate(pwr->grp_clks[0],
 					pwr->pwrlevels[pwr->num_pwrlevels - 1].
 					gpu_freq);
-			for (i = KGSL_MAX_CLKS - 1; i > 0; i--)
-				if (pwr->grp_clks[i])
-					clk_unprepare(pwr->grp_clks[i]);
 		}
 	} else if (state == KGSL_PWRFLAGS_ON) {
 		if (!test_and_set_bit(KGSL_PWRFLAGS_CLK_ON,
@@ -742,15 +790,14 @@
 			trace_kgsl_clk(device, state);
 			/* High latency clock maintenance. */
 			if (device->state != KGSL_STATE_NAP) {
-				for (i = KGSL_MAX_CLKS - 1; i > 0; i--)
-					if (pwr->grp_clks[i])
-						clk_prepare(pwr->grp_clks[i]);
-
 				if (pwr->pwrlevels[0].gpu_freq > 0)
 					clk_set_rate(pwr->grp_clks[0],
 						pwr->pwrlevels
 						[pwr->active_pwrlevel].
 						gpu_freq);
+				for (i = KGSL_MAX_CLKS - 1; i > 0; i--)
+					if (pwr->grp_clks[i])
+						clk_prepare(pwr->grp_clks[i]);
 			}
 			/* as last step, enable grp_clk
 			   this is to let GPU interrupt to come */
@@ -882,7 +929,8 @@
 	if (pdata->set_grp_async != NULL)
 		pdata->set_grp_async();
 
-	if (pdata->num_levels > KGSL_MAX_PWRLEVELS) {
+	if (pdata->num_levels > KGSL_MAX_PWRLEVELS ||
+	    pdata->num_levels < 1) {
 		KGSL_PWR_ERR(device, "invalid power level count: %d\n",
 					 pdata->num_levels);
 		result = -EINVAL;
@@ -951,6 +999,11 @@
 		}
 	}
 
+	/* Set the power level step multiplier with 1 as the default */
+	pwr->step_mul = pdata->step_mul ? pdata->step_mul : 1;
+
+	/* Set the CPU latency to 501usec to allow low latency PC modes */
+	pwr->pm_qos_latency = 501;
 
 	pm_runtime_enable(device->parentdev);
 	register_early_suspend(&device->display_off);
@@ -1012,7 +1065,7 @@
 
 	mutex_lock(&device->mutex);
 	if (device->state & (KGSL_STATE_ACTIVE | KGSL_STATE_NAP)) {
-		kgsl_pwrscale_idle(device, 0);
+		kgsl_pwrscale_idle(device);
 
 		if (kgsl_pwrctrl_sleep(device) != 0) {
 			mod_timer(&device->idle_timer,
@@ -1147,7 +1200,7 @@
 		_sleep_accounting(device);
 		kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_OFF, KGSL_STATE_SLEEP);
 		kgsl_pwrctrl_set_state(device, KGSL_STATE_SLEEP);
-		pm_qos_update_request(&device->pm_qos_req_dma,
+		pm_qos_update_request(&device->pwrctrl.pm_qos_req_dma,
 					PM_QOS_DEFAULT_VALUE);
 		break;
 	case KGSL_STATE_SLEEP:
@@ -1181,7 +1234,7 @@
 		device->ftbl->stop(device);
 		_sleep_accounting(device);
 		kgsl_pwrctrl_set_state(device, KGSL_STATE_SLUMBER);
-		pm_qos_update_request(&device->pm_qos_req_dma,
+		pm_qos_update_request(&device->pwrctrl.pm_qos_req_dma,
 						PM_QOS_DEFAULT_VALUE);
 		break;
 	case KGSL_STATE_SLUMBER:
@@ -1267,8 +1320,8 @@
 		/* Re-enable HW access */
 		mod_timer(&device->idle_timer,
 				jiffies + device->pwrctrl.interval_timeout);
-		pm_qos_update_request(&device->pm_qos_req_dma,
-					GPU_SWFI_LATENCY);
+		pm_qos_update_request(&device->pwrctrl.pm_qos_req_dma,
+				device->pwrctrl.pm_qos_latency);
 	case KGSL_STATE_ACTIVE:
 		kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
 		break;
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.h b/drivers/gpu/msm/kgsl_pwrctrl.h
index e51ec54..ced52e1 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.h
+++ b/drivers/gpu/msm/kgsl_pwrctrl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -60,6 +60,9 @@
  * @irq_name - resource name for the IRQ
  * @restore_slumber - Flag to indicate that we are in a suspend/restore sequence
  * @clk_stats - structure of clock statistics
+ * @pm_qos_req_dma - the power management quality of service structure
+ * @pm_qos_latency - allowed CPU latency in microseconds
+ * @step_mul - multiplier for moving between power levels
  */
 
 struct kgsl_pwrctrl {
@@ -85,6 +88,9 @@
 	s64 time;
 	unsigned int restore_slumber;
 	struct kgsl_clk_stats clk_stats;
+	struct pm_qos_request pm_qos_req_dma;
+	unsigned int pm_qos_latency;
+	unsigned int step_mul;
 };
 
 void kgsl_pwrctrl_irq(struct kgsl_device *device, int state);
diff --git a/drivers/gpu/msm/kgsl_pwrscale.c b/drivers/gpu/msm/kgsl_pwrscale.c
index aad1a8d..dffae70 100644
--- a/drivers/gpu/msm/kgsl_pwrscale.c
+++ b/drivers/gpu/msm/kgsl_pwrscale.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -242,13 +242,13 @@
 					&device->pwrscale);
 }
 
-void kgsl_pwrscale_idle(struct kgsl_device *device, unsigned int ignore_idle)
+void kgsl_pwrscale_idle(struct kgsl_device *device)
 {
 	if (PWRSCALE_ACTIVE(device) && device->pwrscale.policy->idle)
 		if (device->requested_state != KGSL_STATE_SLUMBER &&
 			device->requested_state != KGSL_STATE_SLEEP)
 			device->pwrscale.policy->idle(device,
-					&device->pwrscale, ignore_idle);
+					&device->pwrscale);
 }
 EXPORT_SYMBOL(kgsl_pwrscale_idle);
 
diff --git a/drivers/gpu/msm/kgsl_pwrscale.h b/drivers/gpu/msm/kgsl_pwrscale.h
index ba9b1af..f17b394 100644
--- a/drivers/gpu/msm/kgsl_pwrscale.h
+++ b/drivers/gpu/msm/kgsl_pwrscale.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -23,8 +23,7 @@
 	void (*close)(struct kgsl_device *device,
 		struct kgsl_pwrscale *pwrscale);
 	void (*idle)(struct kgsl_device *device,
-		struct kgsl_pwrscale *pwrscale,
-		unsigned int ignore_idle);
+		struct kgsl_pwrscale *pwrscale);
 	void (*busy)(struct kgsl_device *device,
 		struct kgsl_pwrscale *pwrscale);
 	void (*sleep)(struct kgsl_device *device,
@@ -64,8 +63,7 @@
 	struct kgsl_pwrscale_policy *policy);
 void kgsl_pwrscale_detach_policy(struct kgsl_device *device);
 
-void kgsl_pwrscale_idle(struct kgsl_device *device,
-				unsigned int ignore_idle);
+void kgsl_pwrscale_idle(struct kgsl_device *device);
 void kgsl_pwrscale_busy(struct kgsl_device *device);
 void kgsl_pwrscale_sleep(struct kgsl_device *device);
 void kgsl_pwrscale_wake(struct kgsl_device *device);
diff --git a/drivers/gpu/msm/kgsl_pwrscale_idlestats.c b/drivers/gpu/msm/kgsl_pwrscale_idlestats.c
index fc58dd1..c3188a5 100644
--- a/drivers/gpu/msm/kgsl_pwrscale_idlestats.c
+++ b/drivers/gpu/msm/kgsl_pwrscale_idlestats.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
@@ -131,7 +131,7 @@
 }
 
 static void idlestats_idle(struct kgsl_device *device,
-		struct kgsl_pwrscale *pwrscale, unsigned int ignore_idle)
+		struct kgsl_pwrscale *pwrscale)
 {
 	int i, nr_cpu;
 	struct idlestats_priv *priv = pwrscale->priv;
diff --git a/drivers/gpu/msm/kgsl_pwrscale_msm.c b/drivers/gpu/msm/kgsl_pwrscale_msm.c
index c680d57..073e474 100644
--- a/drivers/gpu/msm/kgsl_pwrscale_msm.c
+++ b/drivers/gpu/msm/kgsl_pwrscale_msm.c
@@ -132,7 +132,7 @@
 }
 
 static void msm_idle(struct kgsl_device *device,
-		struct kgsl_pwrscale *pwrscale, unsigned int ignore_idle)
+		struct kgsl_pwrscale *pwrscale)
 {
 	struct msm_priv *priv = pwrscale->priv;
 
diff --git a/drivers/gpu/msm/kgsl_pwrscale_trustzone.c b/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
index e01932b..9b2ac70 100644
--- a/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
+++ b/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -30,9 +30,18 @@
 	int governor;
 	unsigned int no_switch_cnt;
 	unsigned int skip_cnt;
+	struct kgsl_power_stats bin;
 };
 spinlock_t tz_lock;
 
+/* FLOOR is 5msec to capture up to 3 re-draws
+ * per frame for 60fps content.
+ */
+#define FLOOR			5000
+/* CEILING is 50msec, larger than any standard
+ * frame length, but less than the idle timer.
+ */
+#define CEILING			50000
 #define SWITCH_OFF		200
 #define SWITCH_OFF_RESET_TH	40
 #define SKIP_COUNTER		500
@@ -119,24 +128,27 @@
 					device->pwrctrl.default_pwrlevel);
 }
 
-static void tz_idle(struct kgsl_device *device, struct kgsl_pwrscale *pwrscale,
-						unsigned int ignore_idle)
+static void tz_idle(struct kgsl_device *device, struct kgsl_pwrscale *pwrscale)
 {
 	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
 	struct tz_priv *priv = pwrscale->priv;
 	struct kgsl_power_stats stats;
 	int val, idle;
 
-	if (ignore_idle)
-		return;
-
 	/* In "performance" mode the clock speed always stays
 	   the same */
 	if (priv->governor == TZ_GOVERNOR_PERFORMANCE)
 		return;
 
 	device->ftbl->power_stats(device, &stats);
-	if (stats.total_time == 0)
+	priv->bin.total_time += stats.total_time;
+	priv->bin.busy_time += stats.busy_time;
+	/* Do not waste CPU cycles running this algorithm if
+	 * the GPU just started, or if less than FLOOR time
+	 * has passed since the last run.
+	 */
+	if ((stats.total_time == 0) ||
+		(priv->bin.total_time < FLOOR))
 		return;
 
 	/* If the GPU has stayed in turbo mode for a while, *
@@ -155,9 +167,24 @@
 		priv->no_switch_cnt = 0;
 	}
 
-	idle = stats.total_time - stats.busy_time;
-	idle = (idle > 0) ? idle : 0;
-	val = __secure_tz_entry(TZ_UPDATE_ID, idle, device->id);
+	/* If there is an extended block of busy processing,
+	 * increase frequency.  Otherwise run the normal algorithm.
+	 */
+	if (priv->bin.busy_time > CEILING) {
+		val = -1;
+	} else {
+		idle = priv->bin.total_time - priv->bin.busy_time;
+		idle = (idle > 0) ? idle : 0;
+		val = __secure_tz_entry(TZ_UPDATE_ID, idle, device->id);
+	}
+	priv->bin.total_time = 0;
+	priv->bin.busy_time = 0;
+
+	/* If the decision is to move to a lower level, make sure the GPU
+	 * frequency drops.
+	 */
+	if (val > 0)
+		val *= pwr->step_mul;
 	if (val)
 		kgsl_pwrctrl_pwrlevel_change(device,
 					     pwr->active_pwrlevel + val);
@@ -176,6 +203,8 @@
 
 	__secure_tz_entry(TZ_RESET_ID, 0, device->id);
 	priv->no_switch_cnt = 0;
+	priv->bin.total_time = 0;
+	priv->bin.busy_time = 0;
 }
 
 #ifdef CONFIG_MSM_SCM
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index 08353ee..b97004a 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-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
@@ -549,6 +549,7 @@
 	pgprot_t page_prot = pgprot_writecombine(PAGE_KERNEL);
 	void *ptr;
 	unsigned int align;
+	int step = ((VMALLOC_END - VMALLOC_START)/8) >> PAGE_SHIFT;
 
 	align = (memdesc->flags & KGSL_MEMALIGN_MASK) >> KGSL_MEMALIGN_SHIFT;
 
@@ -676,30 +677,36 @@
 	 * zeroed and unmaped each individual page, and then we had to turn
 	 * around and call flush_dcache_page() on that page to clear the caches.
 	 * This was killing us for performance. Instead, we found it is much
-	 * faster to allocate the pages without GFP_ZERO, map the entire range,
-	 * memset it, flush the range and then unmap - this results in a factor
-	 * of 4 improvement for speed for large buffers.  There is a small
-	 * increase in speed for small buffers, but only on the order of a few
-	 * microseconds at best.  The only downside is that there needs to be
-	 * enough temporary space in vmalloc to accomodate the map. This
-	 * shouldn't be a problem, but if it happens, fall back to a much slower
-	 * path
+	 * faster to allocate the pages without GFP_ZERO, map a chunk of the
+	 * range ('step' pages), memset it, flush it and then unmap
+	 * - this results in a factor of 4 improvement for speed for large
+	 * buffers. There is a small decrease in speed for small buffers,
+	 * but only on the order of a few microseconds at best. The 'step'
+	 * size is based on a guess at the amount of free vmalloc space, but
+	 * will scale down if there's not enough free space.
 	 */
+	for (j = 0; j < pcount; j += step) {
+		step = min(step, pcount - j);
 
-	ptr = vmap(pages, pcount, VM_IOREMAP, page_prot);
+		ptr = vmap(&pages[j], step, VM_IOREMAP, page_prot);
 
-	if (ptr != NULL) {
-		memset(ptr, 0, memdesc->size);
-		dmac_flush_range(ptr, ptr + memdesc->size);
-		vunmap(ptr);
-	} else {
-		/* Very, very, very slow path */
+		if (ptr != NULL) {
+			memset(ptr, 0, step * PAGE_SIZE);
+			dmac_flush_range(ptr, ptr + step * PAGE_SIZE);
+			vunmap(ptr);
+		} else {
+			int k;
+			/* Very, very, very slow path */
 
-		for (j = 0; j < pcount; j++) {
-			ptr = kmap_atomic(pages[j]);
-			memset(ptr, 0, PAGE_SIZE);
-			dmac_flush_range(ptr, ptr + PAGE_SIZE);
-			kunmap_atomic(ptr);
+			for (k = j; k < j + step; k++) {
+				ptr = kmap_atomic(pages[k]);
+				memset(ptr, 0, PAGE_SIZE);
+				dmac_flush_range(ptr, ptr + PAGE_SIZE);
+				kunmap_atomic(ptr);
+			}
+			/* scale down the step size to avoid this path */
+			if (step > 1)
+				step >>= 1;
 		}
 	}
 
diff --git a/drivers/gpu/msm/kgsl_sharedmem.h b/drivers/gpu/msm/kgsl_sharedmem.h
index d937699..27b9151 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.h
+++ b/drivers/gpu/msm/kgsl_sharedmem.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-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
diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c
index 0bfcfd8..e9bbac8 100644
--- a/drivers/gpu/msm/kgsl_snapshot.c
+++ b/drivers/gpu/msm/kgsl_snapshot.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/gpu/msm/kgsl_snapshot.h b/drivers/gpu/msm/kgsl_snapshot.h
index bc29863..327d18a 100644
--- a/drivers/gpu/msm/kgsl_snapshot.h
+++ b/drivers/gpu/msm/kgsl_snapshot.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/gpu/msm/kgsl_sync.c b/drivers/gpu/msm/kgsl_sync.c
index a2dfe3b..98edb83 100644
--- a/drivers/gpu/msm/kgsl_sync.c
+++ b/drivers/gpu/msm/kgsl_sync.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
@@ -179,6 +179,7 @@
 }
 
 static const struct sync_timeline_ops kgsl_sync_timeline_ops = {
+	.driver_name = "kgsl-timeline",
 	.dup = kgsl_sync_pt_dup,
 	.has_signaled = kgsl_sync_pt_has_signaled,
 	.compare = kgsl_sync_pt_compare,
@@ -204,7 +205,9 @@
 {
 	struct kgsl_sync_timeline *ktimeline =
 		(struct kgsl_sync_timeline *) timeline;
-	ktimeline->last_timestamp = timestamp;
+
+	if (timestamp_cmp(timestamp, ktimeline->last_timestamp > 0))
+		ktimeline->last_timestamp = timestamp;
 	sync_timeline_signal(timeline);
 }
 
diff --git a/drivers/gpu/msm/kgsl_trace.c b/drivers/gpu/msm/kgsl_trace.c
index 2bcca15..e432729 100644
--- a/drivers/gpu/msm/kgsl_trace.c
+++ b/drivers/gpu/msm/kgsl_trace.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/gpu/msm/kgsl_trace.h b/drivers/gpu/msm/kgsl_trace.h
index bbef139..8c4811e 100644
--- a/drivers/gpu/msm/kgsl_trace.h
+++ b/drivers/gpu/msm/kgsl_trace.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -494,6 +494,40 @@
 	)
 );
 
+TRACE_EVENT(kgsl_mem_sync_cache,
+
+	TP_PROTO(struct kgsl_mem_entry *mem_entry, unsigned int op),
+
+	TP_ARGS(mem_entry, op),
+
+	TP_STRUCT__entry(
+		__field(unsigned int, gpuaddr)
+		__field(unsigned int, size)
+		__array(char, usage, 16)
+		__field(unsigned int, tgid)
+		__field(unsigned int, id)
+		__field(unsigned int, op)
+	),
+
+	TP_fast_assign(
+		__entry->gpuaddr = mem_entry->memdesc.gpuaddr;
+		__entry->size = mem_entry->memdesc.size;
+		__entry->tgid = mem_entry->priv->pid;
+		__entry->id = mem_entry->id;
+		kgsl_get_memory_usage(__entry->usage, sizeof(__entry->usage),
+				     mem_entry->memdesc.flags);
+		__entry->op = op;
+	),
+
+	TP_printk(
+		"gpuaddr=0x%08x size=%d tgid=%d usage=%s id=%d op=%c%c",
+		__entry->gpuaddr, __entry->size, __entry->tgid, __entry->usage,
+		__entry->id,
+		(__entry->op & KGSL_GPUMEM_CACHE_CLEAN) ? 'c' : '.',
+		(__entry->op & KGSL_GPUMEM_CACHE_INV) ? 'i' : '.'
+	)
+);
+
 DECLARE_EVENT_CLASS(kgsl_mem_timestamp_template,
 
 	TP_PROTO(struct kgsl_device *device, struct kgsl_mem_entry *mem_entry,
@@ -628,7 +662,7 @@
 	),
 
 	TP_printk(
-		"d_name=%s page=0x%08x pt=%d op=%s\n",
+		"d_name=%s page=0x%08x pt=%d op=%s",
 		__get_str(device_name), __entry->page, __entry->pt,
 		__get_str(op)
 	)
@@ -659,6 +693,41 @@
 	)
 );
 
+TRACE_EVENT(kgsl_register_event,
+		TP_PROTO(unsigned int id, unsigned int timestamp),
+		TP_ARGS(id, timestamp),
+		TP_STRUCT__entry(
+			__field(unsigned int, id)
+			__field(unsigned int, timestamp)
+		),
+		TP_fast_assign(
+			__entry->id = id;
+			__entry->timestamp = timestamp;
+		),
+		TP_printk(
+			"ctx=%d ts=%d",
+			__entry->id, __entry->timestamp)
+);
+
+TRACE_EVENT(kgsl_fire_event,
+		TP_PROTO(unsigned int id, unsigned int ts,
+			unsigned int age),
+		TP_ARGS(id, ts, age),
+		TP_STRUCT__entry(
+			__field(unsigned int, id)
+			__field(unsigned int, ts)
+			__field(unsigned int, age)
+		),
+		TP_fast_assign(
+			__entry->id = id;
+			__entry->ts = ts;
+			__entry->age = age;
+		),
+		TP_printk(
+			"ctx=%d ts=%d age=%u",
+			__entry->id, __entry->ts, __entry->age)
+);
+
 #endif /* _KGSL_TRACE_H */
 
 /* This part must be outside protection */
diff --git a/drivers/gpu/msm/z180.c b/drivers/gpu/msm/z180.c
index 258dcfa..8f03ccb 100644
--- a/drivers/gpu/msm/z180.c
+++ b/drivers/gpu/msm/z180.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-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
@@ -576,6 +576,9 @@
 	mod_timer(&device->idle_timer, jiffies + FIRST_TIMEOUT);
 	kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON);
 	device->ftbl->irqctrl(device, 1);
+
+	device->reset_counter++;
+
 	return 0;
 
 error_clk_off:
diff --git a/drivers/gpu/msm/z180.h b/drivers/gpu/msm/z180.h
index a8973d2..268aac3 100644
--- a/drivers/gpu/msm/z180.h
+++ b/drivers/gpu/msm/z180.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/drivers/gpu/msm/z180_postmortem.c b/drivers/gpu/msm/z180_postmortem.c
index 7cf3799..c1e5f07 100644
--- a/drivers/gpu/msm/z180_postmortem.c
+++ b/drivers/gpu/msm/z180_postmortem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/gpu/msm/z180_reg.h b/drivers/gpu/msm/z180_reg.h
index 07d60b9..81f1fdc 100644
--- a/drivers/gpu/msm/z180_reg.h
+++ b/drivers/gpu/msm/z180_reg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-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
diff --git a/drivers/gpu/msm/z180_trace.c b/drivers/gpu/msm/z180_trace.c
index 29b519c..9d971ee 100644
--- a/drivers/gpu/msm/z180_trace.c
+++ b/drivers/gpu/msm/z180_trace.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/gpu/msm/z180_trace.h b/drivers/gpu/msm/z180_trace.h
index fbe1fe5..4f65b9b 100644
--- a/drivers/gpu/msm/z180_trace.h
+++ b/drivers/gpu/msm/z180_trace.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/gud/mobicore_driver/api.c b/drivers/gud/mobicore_driver/api.c
index 2506bc2..871f6cc 100644
--- a/drivers/gud/mobicore_driver/api.c
+++ b/drivers/gud/mobicore_driver/api.c
@@ -2,6 +2,7 @@
  * MobiCore Driver Kernel Module.
  *
  * <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
diff --git a/drivers/gud/mobicore_driver/debug.h b/drivers/gud/mobicore_driver/debug.h
index f166605..0195877 100644
--- a/drivers/gud/mobicore_driver/debug.h
+++ b/drivers/gud/mobicore_driver/debug.h
@@ -14,8 +14,7 @@
 extern struct device *mcd;
 
 #define MCDRV_DBG_ERROR(dev, txt, ...) \
-	dev_err(dev, "[%d] %s() ### ERROR: " txt, \
-		task_pid_vnr(current), \
+	dev_err(dev, "MobiCore %s() ### ERROR: " txt, \
 		__func__, \
 		##__VA_ARGS__)
 
@@ -32,15 +31,12 @@
 #endif
 
 #define MCDRV_DBG(dev, txt, ...) \
-	dev_info(dev, "[%d on CPU%d] %s(): " txt, \
-		 task_pid_vnr(current), \
-		 raw_smp_processor_id(), \
+	dev_info(dev, "MobiCore %s(): " txt, \
 		 __func__, \
 		 ##__VA_ARGS__)
 
 #define MCDRV_DBG_WARN(dev, txt, ...) \
-	dev_warn(dev, "[%d] %s() WARNING: " txt, \
-		 task_pid_vnr(current), \
+	dev_warn(dev, "MobiCore %s() WARNING: " txt, \
 		 __func__, \
 		 ##__VA_ARGS__)
 
diff --git a/drivers/gud/mobicore_driver/fastcall.h b/drivers/gud/mobicore_driver/fastcall.h
index 9f360c1..d5f9abc 100644
--- a/drivers/gud/mobicore_driver/fastcall.h
+++ b/drivers/gud/mobicore_driver/fastcall.h
@@ -15,6 +15,15 @@
 
 #include "debug.h"
 
+/* Use the arch_extension sec pseudo op before switching to secure world */
+#if defined(__GNUC__) && \
+	defined(__GNUC_MINOR__) && \
+	defined(__GNUC_PATCHLEVEL__) && \
+	((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)) \
+	>= 40502
+#define MC_ARCH_EXTENSION_SEC
+#endif
+
 /*
  * MobiCore SMCs
  */
@@ -93,16 +102,18 @@
  */
 static inline long _smc(void *data)
 {
+	int ret = 0;
 	union fc_generic fc_generic;
-	memcpy(&fc_generic, data, sizeof(union fc_generic));
+
 	if (data == NULL)
 		return -EPERM;
+
 #ifdef MC_SMC_FASTCALL
 	{
-		int ret = 0;
-		ret = smc_fastcall(data, sizeof(union fc_generic));
+		ret = smc_fastcall(data, sizeof(fc_generic));
 	}
 #else
+	memcpy(&fc_generic, data, sizeof(union fc_generic));
 	{
 		/* SVC expect values in r0-r3 */
 		register u32 reg0 __asm__("r0") = fc_generic.as_in.cmd;
@@ -128,7 +139,7 @@
 		memcpy(data, &fc_generic, sizeof(union fc_generic));
 	}
 #endif
-	return 0;
+	return ret;
 }
 
 /*
diff --git a/drivers/gud/mobicore_driver/logging.c b/drivers/gud/mobicore_driver/logging.c
index 089b91c..4160292 100644
--- a/drivers/gud/mobicore_driver/logging.c
+++ b/drivers/gud/mobicore_driver/logging.c
@@ -5,6 +5,7 @@
  * buffer and the Linux log
  *
  * <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -51,17 +52,27 @@
 	uint32_t log_data;		/* Value, if any */
 };
 
+static bool prev_eol;			/* Previous char was a EOL */
+static uint16_t prev_source;		/* Previous Log source */
 static uint32_t log_pos;		/* MobiCore log previous position */
 static struct mc_trace_buf *log_buf;	/* MobiCore log buffer structure */
 struct task_struct *log_thread;		/* Log Thread task structure */
 static char *log_line;			/* Log Line buffer */
 static uint32_t log_line_len;		/* Log Line buffer current length */
+static int thread_err;
 
-static void log_eol(void)
+static void log_eol(uint16_t source)
 {
 	if (!strnlen(log_line, LOG_LINE_SIZE))
 		return;
-	dev_info(mcd, "%s\n", log_line);
+	prev_eol = true;
+	/* MobiCore Userspace */
+	if (prev_source)
+		dev_info(mcd, "%03x|%s\n", prev_source, log_line);
+	/* MobiCore kernel */
+	else
+		dev_info(mcd, "%s\n", log_line);
+
 	log_line_len = 0;
 	log_line[0] = 0;
 }
@@ -70,53 +81,29 @@
  * Collect chars in log_line buffer and output the buffer when it is full.
  * No locking needed because only "mobicore_log" thread updates this buffer.
  */
-static void log_char(char ch)
+static void log_char(char ch, uint16_t source)
 {
 	if (ch == '\n' || ch == '\r') {
-		log_eol();
+		log_eol(source);
 		return;
 	}
 
-	if (log_line_len >= LOG_LINE_SIZE - 1) {
-		dev_info(mcd, "%s\n", log_line);
-		log_line_len = 0;
-		log_line[0] = 0;
-	}
+	if (log_line_len >= LOG_LINE_SIZE - 1 || source != prev_source)
+		log_eol(source);
+
 
 	log_line[log_line_len] = ch;
 	log_line[log_line_len + 1] = 0;
 	log_line_len++;
-}
-
-/*
- * Put a string to the log line.
- */
-static void log_str(const char *s)
-{
-	int i;
-
-	for (i = 0; i < strnlen(s, LOG_LINE_SIZE); i++)
-		log_char(s[i]);
-}
-
-static uint32_t process_v1log(void)
-{
-	char *last_char = log_buf->buff + log_buf->write_pos;
-	char *buff = log_buf->buff + log_pos;
-	while (buff != last_char) {
-		log_char(*(buff++));
-		/* Wrap around */
-		if (buff - (char *)log_buf >= log_size)
-			buff = log_buf->buff;
-	}
-	return buff - log_buf->buff;
+	prev_eol = false;
+	prev_source = source;
 }
 
 static const uint8_t HEX2ASCII[16] = {
 	'0', '1', '2', '3', '4', '5', '6', '7',
 	'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
 
-static void dbg_raw_nro(uint32_t format, uint32_t value)
+static void dbg_raw_nro(uint32_t format, uint32_t value, uint16_t source)
 {
 	int digits = 1;
 	uint32_t base = (format & LOG_INTEGER_DECIMAL) ? 10 : 16;
@@ -139,17 +126,17 @@
 	if (width > digits) {
 		char ch = (base == 10) ? ' ' : '0';
 		while (width > digits) {
-			log_char(ch);
+			log_char(ch, source);
 			width--;
 		}
 	}
 
 	if (negative)
-		log_char('-');
+		log_char('-', source);
 
 	while (digits-- > 0) {
 		uint32_t d = value / digit_base;
-		log_char(HEX2ASCII[d]);
+		log_char(HEX2ASCII[d], source);
 		value = value - d * digit_base;
 		digit_base /= base;
 	}
@@ -157,36 +144,32 @@
 
 static void log_msg(struct logmsg_struct *msg)
 {
-	unsigned char msgtxt[5];
-	int mpos = 0;
-
 	switch (msg->ctrl & LOG_TYPE_MASK) {
 	case LOG_TYPE_CHAR: {
 		uint32_t ch;
 		ch = msg->log_data;
 		while (ch != 0) {
-			msgtxt[mpos++] = ch&0xFF;
+			log_char(ch & 0xFF, msg->source);
 			ch >>= 8;
 		}
-		msgtxt[mpos] = 0;
-		log_str(msgtxt);
 		break;
 	}
 	case LOG_TYPE_INTEGER: {
-		dbg_raw_nro(msg->ctrl, msg->log_data);
+		dbg_raw_nro(msg->ctrl, msg->log_data, msg->source);
 		break;
 	}
 	default:
 		break;
 	}
 	if (msg->ctrl & LOG_EOL)
-		log_eol();
+		log_eol(msg->source);
 }
 
-static uint32_t process_v2log(void)
+static uint32_t process_log(void)
 {
 	char *last_msg = log_buf->buff + log_buf->write_pos;
 	char *buff = log_buf->buff + log_pos;
+
 	while (buff != last_msg) {
 		log_msg((struct logmsg_struct *)buff);
 		buff += sizeof(struct logmsg_struct);
@@ -201,19 +184,19 @@
 /* log_worker() - Worker thread processing the log_buf buffer. */
 static int log_worker(void *p)
 {
-	if (log_buf == NULL)
-		return -EFAULT;
+	int ret = 0;
+	if (log_buf == NULL) {
+		ret = -EFAULT;
+		goto err_kthread;
+	}
 
 	while (!kthread_should_stop()) {
 		if (log_buf->write_pos == log_pos)
 			schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT);
 
 		switch (log_buf->version) {
-		case 1:
-			log_pos = process_v1log();
-			break;
 		case 2:
-			log_pos = process_v2log();
+			log_pos = process_log();
 			break;
 		default:
 			MCDRV_DBG_ERROR(mcd, "Unknown Mobicore log data");
@@ -222,11 +205,23 @@
 			 * Stop the thread as we have no idea what
 			 * happens next
 			 */
-			return -EFAULT;
+			ret = -EFAULT;
+			goto err_kthread;
 		}
 	}
+err_kthread:
 	MCDRV_DBG(mcd, "Logging thread stopped!");
-	return 0;
+	thread_err = ret;
+	/* Wait until the next kthread_stop() is called, if it was already
+	 * called we just slip through, if there is an error signal it and
+	 * wait to get the signal */
+	set_current_state(TASK_INTERRUPTIBLE);
+	while (!kthread_should_stop()) {
+		schedule();
+		set_current_state(TASK_INTERRUPTIBLE);
+	}
+	set_current_state(TASK_RUNNING);
+	return ret;
 }
 
 /*
@@ -239,6 +234,14 @@
 	if (log_thread == NULL || IS_ERR(log_thread))
 		return;
 
+	/* The thread itself is in some error condition so just get
+	 * rid of it */
+	if (thread_err != 0) {
+		kthread_stop(log_thread);
+		log_thread = NULL;
+		return;
+	}
+
 	wake_up_process(log_thread);
 }
 
@@ -258,6 +261,9 @@
 	log_thread = NULL;
 	log_line = NULL;
 	log_line_len = 0;
+	prev_eol = false;
+	prev_source = 0;
+	thread_err = 0;
 
 	/* Sanity check for the log size */
 	if (log_size < PAGE_SIZE)
@@ -271,11 +277,11 @@
 		return -ENOMEM;
 	}
 
-	log_thread = kthread_create(log_worker, NULL, "mobicore_log");
+	log_thread = kthread_create(log_worker, NULL, "mc_log");
 	if (IS_ERR(log_thread)) {
 		MCDRV_DBG_ERROR(mcd, "MobiCore log thread creation failed!");
 		ret = -EFAULT;
-		goto mobicore_log_setup_log_line;
+		goto err_free_line;
 	}
 
 	sched_setscheduler(log_thread, SCHED_IDLE, &param);
@@ -288,7 +294,7 @@
 	if (!log_buf) {
 		MCDRV_DBG_ERROR(mcd, "Failed to get page for logger!");
 		ret = -ENOMEM;
-		goto mobicore_log_setup_kthread;
+		goto err_stop_kthread;
 	}
 	phys_log_buf = virt_to_phys(log_buf);
 
@@ -308,16 +314,17 @@
 		free_pages((unsigned long)log_buf, get_order(log_size));
 		log_buf = NULL;
 		ret = -EIO;
-		goto mobicore_log_setup_kthread;
+		goto err_stop_kthread;
 	}
+	set_task_state(log_thread, TASK_INTERRUPTIBLE);
 
 	MCDRV_DBG(mcd, "fc_log Logger version %u\n", log_buf->version);
 	return 0;
 
-mobicore_log_setup_kthread:
+err_stop_kthread:
 	kthread_stop(log_thread);
 	log_thread = NULL;
-mobicore_log_setup_log_line:
+err_free_line:
 	kfree(log_line);
 	log_line = NULL;
 	return ret;
diff --git a/drivers/gud/mobicore_driver/main.c b/drivers/gud/mobicore_driver/main.c
index 1a745b3..df5675e 100644
--- a/drivers/gud/mobicore_driver/main.c
+++ b/drivers/gud/mobicore_driver/main.c
@@ -11,6 +11,7 @@
  * fd = open(/dev/mobicore-user)
  *
  * <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -81,7 +82,7 @@
 }
 
 /* Frees the memory associated with a buffer */
-static int free_buffer(struct mc_buffer *buffer)
+static int free_buffer(struct mc_buffer *buffer, bool unlock)
 {
 	if (buffer->handle == 0)
 		return -EINVAL;
@@ -89,16 +90,15 @@
 	if (buffer->addr == 0)
 		return -EINVAL;
 
-	if (!atomic_dec_and_test(&buffer->usage)) {
+	MCDRV_DBG_VERBOSE(mcd,
+			  "handle=%u phys_addr=0x%p, virt_addr=0x%p len=%u\n",
+		  buffer->handle, buffer->phys, buffer->addr, buffer->len);
 
-		MCDRV_DBG_VERBOSE(mcd, "Could not free buffer h=%u",
-				  buffer->handle);
+	if (!atomic_dec_and_test(&buffer->usage)) {
+		MCDRV_DBG_VERBOSE(mcd, "Could not free %u", buffer->handle);
 		return 0;
 	}
 
-	MCDRV_DBG(mcd, "handle=%u phys_addr=0x%p, virt_addr=0x%p\n",
-		  buffer->handle, buffer->phys, buffer->addr);
-
 	list_del(&buffer->list);
 
 	free_continguous_pages(buffer->addr, buffer->order);
@@ -106,6 +106,37 @@
 	return 0;
 }
 
+static uint32_t mc_find_cont_wsm_addr(struct mc_instance *instance, void *uaddr,
+	uint32_t *addr, uint32_t len)
+{
+	int ret = 0;
+	struct mc_buffer *buffer;
+
+	if (WARN(!instance, "No instance data available"))
+		return -EFAULT;
+
+	mutex_lock(&instance->lock);
+
+	mutex_lock(&ctx.bufs_lock);
+
+	/* search for the given handle in the buffers list */
+	list_for_each_entry(buffer, &ctx.cont_bufs, list) {
+		if (buffer->uaddr == uaddr && buffer->len == len) {
+			*addr = (uint32_t)buffer->addr;
+			goto found;
+		}
+	}
+
+	/* Coundn't find the buffer */
+	ret = -EINVAL;
+
+found:
+	mutex_unlock(&ctx.bufs_lock);
+	mutex_unlock(&instance->lock);
+
+	return ret;
+}
+
 static uint32_t mc_find_cont_wsm(struct mc_instance *instance, uint32_t handle,
 	uint32_t *phys, uint32_t *len)
 {
@@ -152,10 +183,16 @@
  * Returns 0 if no error
  *
  */
-static int __free_buffer(struct mc_instance *instance, uint32_t handle)
+static int __free_buffer(struct mc_instance *instance, uint32_t handle,
+		bool unlock)
 {
 	int ret = 0;
 	struct mc_buffer *buffer;
+	void *uaddr = NULL;
+	size_t len = 0;
+#ifndef MC_VM_UNMAP
+	struct mm_struct *mm = current->mm;
+#endif
 
 	if (WARN(!instance, "No instance data available"))
 		return -EFAULT;
@@ -163,6 +200,46 @@
 	mutex_lock(&ctx.bufs_lock);
 	/* search for the given handle in the buffers list */
 	list_for_each_entry(buffer, &ctx.cont_bufs, list) {
+		if (buffer->handle == handle) {
+			uaddr = buffer->uaddr;
+			len = buffer->len;
+			goto found_buffer;
+		}
+	}
+	goto err;
+found_buffer:
+	if (!is_daemon(instance) || buffer->instance != instance)
+		goto err;
+	mutex_unlock(&ctx.bufs_lock);
+	/* Only unmap if the request is comming from the user space and
+	 * it hasn't already been unmapped */
+	if (unlock == false && uaddr != NULL)
+#ifndef MC_VM_UNMAP
+		/* do_munmap must be done with mm->mmap_sem taken */
+		down_write(&mm->mmap_sem);
+		ret = do_munmap(mm, (long unsigned int)uaddr, len);
+		if (ret < 0) {
+			/* Something is not right if we end up here, better not
+			 * clean the buffer so we just leak memory instead of
+			 * creating security issues */
+			MCDRV_DBG_ERROR(mcd, "Memory can't be unmapped\n");
+		}
+		up_write(&mm->mmap_sem);
+		if (ret < 0)
+			return -EINVAL;
+#else
+		if (vm_munmap((long unsigned int)uaddr, len) < 0) {
+			/* Something is not right if we end up here, better not
+			 * clean the buffer so we just leak memory instead of
+			 * creating security issues */
+			MCDRV_DBG_ERROR(mcd, "Memory can't be unmapped\n");
+			return -EINVAL;
+		}
+#endif
+
+	mutex_lock(&ctx.bufs_lock);
+	/* search for the given handle in the buffers list */
+	list_for_each_entry(buffer, &ctx.cont_bufs, list) {
 		if (buffer->handle == handle)
 			goto del_buffer;
 	}
@@ -170,7 +247,7 @@
 	goto err;
 
 del_buffer:
-	ret = free_buffer(buffer);
+	ret = free_buffer(buffer, unlock);
 err:
 	mutex_unlock(&ctx.bufs_lock);
 	return ret;
@@ -185,7 +262,7 @@
 
 	mutex_lock(&instance->lock);
 
-	ret = __free_buffer(instance, handle);
+	ret = __free_buffer(instance, handle, false);
 	mutex_unlock(&instance->lock);
 	return ret;
 }
@@ -253,8 +330,8 @@
 	INIT_LIST_HEAD(&cbuffer->list);
 	list_add(&cbuffer->list, &ctx.cont_bufs);
 
-	MCDRV_DBG(mcd,
-		  "allocated phys=0x%p - 0x%p, size=%ld, kvirt=0x%p, h=%d\n",
+	MCDRV_DBG_VERBOSE(mcd,
+			  "allocated phys=0x%p - 0x%p, size=%ld, kvirt=0x%p, h=%d\n",
 		  phys, (void *)((unsigned int)phys+allocated_size),
 		  allocated_size, addr, cbuffer->handle);
 	*buffer = cbuffer;
@@ -332,6 +409,7 @@
 	int ret = 0;
 	struct mc_l2_table *table = NULL;
 	struct task_struct *task = current;
+	uint32_t kbuff = 0x0;
 
 	if (WARN(!instance, "No instance data available"))
 		return -EFAULT;
@@ -341,7 +419,12 @@
 		return -EINVAL;
 	}
 
-	table = mc_alloc_l2_table(instance, task, (void *)buffer, len);
+	MCDRV_DBG_VERBOSE(mcd, "buffer: %p, len=%08x\n", (void *)buffer, len);
+
+	if (!mc_find_cont_wsm_addr(instance, (void *)buffer, &kbuff, len))
+		table = mc_alloc_l2_table(instance, NULL, (void *)kbuff, len);
+	else
+		table = mc_alloc_l2_table(instance, task, (void *)buffer, len);
 
 	if (IS_ERR(table)) {
 		MCDRV_DBG_ERROR(mcd, "new_used_l2_table() failed\n");
@@ -421,7 +504,7 @@
 	/* Not a l2 table, then it must be a buffer */
 	if (ret == -EINVAL) {
 		/* Call the non locking variant! */
-		ret = __free_buffer(instance, handle);
+		ret = __free_buffer(instance, handle, true);
 	}
 	mutex_unlock(&instance->lock);
 
@@ -471,8 +554,8 @@
 	struct mc_buffer *buffer = 0;
 	int ret = 0;
 
-	MCDRV_DBG(mcd, "enter (vma start=0x%p, size=%ld, mci=%p)\n",
-		  (void *)vmarea->vm_start, len, ctx.mci_base.phys);
+	MCDRV_DBG_VERBOSE(mcd, "enter (vma start=0x%p, size=%ld, mci=%p)\n",
+			  (void *)vmarea->vm_start, len, ctx.mci_base.phys);
 
 	if (WARN(!instance, "No instance data available"))
 		return -EFAULT;
@@ -496,7 +579,8 @@
 		return -EINVAL;
 
 found:
-		vmarea->vm_flags |= VM_RESERVED;
+		buffer->uaddr = (void *)vmarea->vm_start;
+		vmarea->vm_flags |= VM_IO;
 		/*
 		 * Convert kernel address to user address. Kernel address begins
 		 * at PAGE_OFFSET, user address range is below PAGE_OFFSET.
@@ -507,6 +591,10 @@
 		pfn = (unsigned int)paddr >> PAGE_SHIFT;
 		ret = (int)remap_pfn_range(vmarea, vmarea->vm_start, pfn,
 			buffer->len, vmarea->vm_page_prot);
+		/* If the remap failed then don't mark this buffer as marked
+		 * since the unmaping will also fail */
+		if (ret)
+			buffer->uaddr = NULL;
 		mutex_unlock(&ctx.bufs_lock);
 	} else {
 		if (!is_daemon(instance))
@@ -516,7 +604,7 @@
 		if (!paddr)
 			return -EFAULT;
 
-		vmarea->vm_flags |= VM_RESERVED;
+		vmarea->vm_flags |= VM_IO;
 		/*
 		 * Convert kernel address to user address. Kernel address begins
 		 * at PAGE_OFFSET, user address range is below PAGE_OFFSET.
@@ -614,8 +702,8 @@
 		map.reused = 0;
 		if (copy_to_user(uarg, &map, sizeof(map)))
 			ret = -EFAULT;
-
-		ret = 0;
+		else
+			ret = 0;
 		break;
 	}
 	default:
@@ -754,6 +842,13 @@
 		break;
 	}
 
+	case MC_IO_LOG_SETUP: {
+#ifdef MC_MEM_TRACES
+		ret = mobicore_log_setup();
+#endif
+		break;
+	}
+
 	/* The rest is handled commonly by user IOCTL */
 	default:
 		ret = mc_fd_user_ioctl(file, cmd, arg);
@@ -887,7 +982,7 @@
 	list_for_each_entry_safe(buffer, tmp, &ctx.cont_bufs, list) {
 		if (buffer->instance == instance) {
 			buffer->instance = NULL;
-			free_buffer(buffer);
+			free_buffer(buffer, false);
 		}
 	}
 	mutex_unlock(&ctx.bufs_lock);
@@ -1017,7 +1112,7 @@
 static struct miscdevice mc_admin_device = {
 	.name	= MC_ADMIN_DEVNODE,
 	.mode	= (S_IRWXU),
-	.minor	= MISC_DYNAMIC_MINOR,
+	.minor	= 253,
 	.fops	= &mc_admin_fops,
 };
 
@@ -1033,7 +1128,7 @@
 static struct miscdevice mc_user_device = {
 	.name	= MC_USER_DEVNODE,
 	.mode	= (S_IRWXU | S_IRWXG | S_IRWXO),
-	.minor	= MISC_DYNAMIC_MINOR,
+	.minor	= 254,
 	.fops	= &mc_user_fops,
 };
 
@@ -1097,10 +1192,6 @@
 		goto free_admin;
 	}
 
-#ifdef MC_MEM_TRACES
-	mobicore_log_setup();
-#endif
-
 	/* initialize event counter for signaling of an IRQ to zero */
 	atomic_set(&ctx.isr_counter, 0);
 
@@ -1159,6 +1250,7 @@
 module_init(mobicore_init);
 module_exit(mobicore_exit);
 MODULE_AUTHOR("Giesecke & Devrient GmbH");
+MODULE_AUTHOR("Trustonic Limited");
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("MobiCore driver");
 
diff --git a/drivers/gud/mobicore_driver/main.h b/drivers/gud/mobicore_driver/main.h
index e23c516..2c316bc 100644
--- a/drivers/gud/mobicore_driver/main.h
+++ b/drivers/gud/mobicore_driver/main.h
@@ -27,7 +27,7 @@
 
 /* Instance data for MobiCore Daemon and TLCs. */
 struct mc_instance {
-	/* Instance lock */
+	/* lock for the instance */
 	struct mutex lock;
 	/* unique handle */
 	unsigned int handle;
@@ -48,6 +48,8 @@
 	atomic_t		usage;
 	/* virtual Kernel start address */
 	void			*addr;
+	/* virtual Userspace start address */
+	void			*uaddr;
 	/* physical start address */
 	void			*phys;
 	/* order of number of pages */
diff --git a/drivers/gud/mobicore_driver/mem.c b/drivers/gud/mobicore_driver/mem.c
index da711ce..1fe351b 100644
--- a/drivers/gud/mobicore_driver/mem.c
+++ b/drivers/gud/mobicore_driver/mem.c
@@ -11,6 +11,7 @@
  * which has to be created by the fd = open(/dev/mobicore) command.
  *
  * <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -355,14 +356,6 @@
 	MCDRV_DBG_VERBOSE(mcd, "WSM addr=0x%p, len=0x%08x\n", wsm_buffer,
 			  wsm_len);
 
-	/*
-	 * Check if called from kernel space and if
-	 * wsm_buffer is actually vmalloced or not
-	 */
-	if (task == NULL && !is_vmalloc_addr(wsm_buffer)) {
-		MCDRV_DBG_ERROR(mcd, "WSM addr is not a vmalloc address");
-		return -EINVAL;
-	}
 
 	/* calculate page usage */
 	virt_addr_page = (void *)(((unsigned long)(wsm_buffer)) & PAGE_MASK);
@@ -405,6 +398,20 @@
 			return ret;
 		}
 	}
+	/* Request comes from kernel space(cont buffer) */
+	else if (task == NULL && !is_vmalloc_addr(wsm_buffer)) {
+		void *uaddr = wsm_buffer;
+		for (i = 0; i < nr_of_pages; i++) {
+			page = virt_to_page(uaddr);
+			if (!page) {
+				MCDRV_DBG_ERROR(mcd, "failed to map address");
+				return -EINVAL;
+			}
+			get_page(page);
+			l2table_as_array_of_pointers_to_page[i] = page;
+			uaddr += PAGE_SIZE;
+		}
+	}
 	/* Request comes from kernel space(vmalloc buffer) */
 	else {
 		void *uaddr = wsm_buffer;
diff --git a/drivers/gud/mobicore_driver/ops.c b/drivers/gud/mobicore_driver/ops.c
index 509b4e9..b44a842 100644
--- a/drivers/gud/mobicore_driver/ops.c
+++ b/drivers/gud/mobicore_driver/ops.c
@@ -11,6 +11,7 @@
  * which has to be created by the fd = open(/dev/mobicore) command.
  *
  * <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -20,6 +21,8 @@
 #include <linux/kthread.h>
 #include <linux/module.h>
 #include <linux/device.h>
+#include <linux/workqueue.h>
+#include <linux/cpu.h>
 
 #include "main.h"
 #include "fastcall.h"
@@ -27,6 +30,29 @@
 #include "mem.h"
 #include "debug.h"
 
+struct fastcall_work_struct {
+	struct work_struct work;
+	void *data;
+};
+
+static void fastcall_work_func(struct work_struct *work)
+{
+	struct fastcall_work_struct *fc_work =
+		container_of(work, struct fastcall_work_struct, work);
+	_smc(fc_work->data);
+}
+
+void mc_fastcall(void *data)
+{
+	struct fastcall_work_struct work = {
+		.data = data,
+	};
+	INIT_WORK(&work.work, fastcall_work_func);
+	schedule_work_on(0, &work.work);
+
+	flush_work(&work.work);
+}
+
 int mc_info(uint32_t ext_info_id, uint32_t *state, uint32_t *ext_info)
 {
 	int ret = 0;
diff --git a/drivers/gud/mobicore_driver/ops.h b/drivers/gud/mobicore_driver/ops.h
index 673399f..efe5f05 100644
--- a/drivers/gud/mobicore_driver/ops.h
+++ b/drivers/gud/mobicore_driver/ops.h
@@ -22,9 +22,6 @@
 int mc_init(uint32_t base, uint32_t  nq_offset, uint32_t  nq_length,
 	    uint32_t mcp_offset, uint32_t  mcp_length);
 
-static inline void mc_fastcall(void *data)
-{
-	work_on_cpu(0, _smc, data);
-}
+void mc_fastcall(void *data);
 
 #endif /* _MC_OPS_H_ */
diff --git a/drivers/gud/mobicore_driver/platforms/msm8960_surf_std/platform.h b/drivers/gud/mobicore_driver/platforms/msm8960_surf_std/platform.h
index 9efa026..7febcb6 100644
--- a/drivers/gud/mobicore_driver/platforms/msm8960_surf_std/platform.h
+++ b/drivers/gud/mobicore_driver/platforms/msm8960_surf_std/platform.h
@@ -3,6 +3,7 @@
  * its internal structures and defines.
  *
  * <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -35,6 +36,11 @@
 }
 
 /* Enable mobicore mem traces */
-#define MC_MEM_TRACES
+/* #define MC_MEM_TRACES */
+
+/* Enable the use of vm_unamp instead of the deprecated do_munmap
+ * and other 3.7 features
+ */
+#define MC_VM_UNMAP
 
 #endif /* _MC_PLATFORM_H_ */
diff --git a/drivers/gud/mobicore_driver/public/mc_kernel_api.h b/drivers/gud/mobicore_driver/public/mc_kernel_api.h
index 7a038c4..cca0636 100644
--- a/drivers/gud/mobicore_driver/public/mc_kernel_api.h
+++ b/drivers/gud/mobicore_driver/public/mc_kernel_api.h
@@ -2,6 +2,7 @@
  * Interface to be used by module MobiCoreKernelAPI.
  *
  * <-- Copyright Giesecke & Devrient GmbH 2010-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
diff --git a/drivers/gud/mobicore_driver/public/mc_linux.h b/drivers/gud/mobicore_driver/public/mc_linux.h
index 99b7769..bb95c26 100644
--- a/drivers/gud/mobicore_driver/public/mc_linux.h
+++ b/drivers/gud/mobicore_driver/public/mc_linux.h
@@ -11,6 +11,7 @@
  * "insmod mcDrvModule.ko".
  *
  * <-- Copyright Giesecke & Devrient GmbH 2010-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -206,4 +207,9 @@
  * Only available to the daemon */
 #define MC_IO_RESOLVE_CONT_WSM	_IOWR(MC_IOC_MAGIC, 16, struct mc_ioctl_execute)
 
+/*
+ * Setup the mem traces when called.
+ * Only available to the daemon */
+#define MC_IO_LOG_SETUP		_IO(MC_IOC_MAGIC, 17)
+
 #endif /* _MC_LINUX_H_ */
diff --git a/drivers/gud/mobicore_driver/public/version.h b/drivers/gud/mobicore_driver/public/version.h
index b08dd95..591ca3d 100644
--- a/drivers/gud/mobicore_driver/public/version.h
+++ b/drivers/gud/mobicore_driver/public/version.h
@@ -1,5 +1,6 @@
 /*
  * <-- Copyright Giesecke & Devrient GmbH 2010-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
diff --git a/drivers/gud/mobicore_kernelapi/include/mcinq.h b/drivers/gud/mobicore_kernelapi/include/mcinq.h
index b874925..34216a7 100644
--- a/drivers/gud/mobicore_kernelapi/include/mcinq.h
+++ b/drivers/gud/mobicore_kernelapi/include/mcinq.h
@@ -112,6 +112,6 @@
 	struct notification_queue_header hdr;
 	/* Notification elements. */
 	struct notification notification[MIN_NQ_ELEM];
-} ;
+};
 
 #endif /* _MCINQ_H_ */
diff --git a/drivers/gud/mobicore_kernelapi/main.c b/drivers/gud/mobicore_kernelapi/main.c
index 50359b1..73de93a 100644
--- a/drivers/gud/mobicore_kernelapi/main.c
+++ b/drivers/gud/mobicore_kernelapi/main.c
@@ -139,13 +139,27 @@
 
 static int __init mcapi_init(void)
 {
+	/* struct netlink_kernel_cfg netlink_cfg; */
+
 	dev_set_name(mc_kapi, "mcapi");
 
 	dev_info(mc_kapi, "Mobicore API module initialized!\n");
 
+	/*
+	 * netlink_cfg.groups = 0;
+	 * netlink_cfg.flags = 0;
+	 * netlink_cfg.input = mcapi_callback;
+	 * netlink_cfg.cb_mutex = NULL;
+	 * netlink_cfg.bind = NULL;
+	 */
 	mod_ctx = kzalloc(sizeof(struct mc_kernelapi_ctx), GFP_KERNEL);
 
 	/* start kernel thread */
+
+	/*
+	 * mod_ctx->sk = netlink_kernel_create(&init_net, MC_DAEMON_NETLINK,
+	 *					    &netlink_cfg);
+	 */
 	mod_ctx->sk = netlink_kernel_create(&init_net, MC_DAEMON_NETLINK, 0,
 					    mcapi_callback, NULL, THIS_MODULE);
 
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index ffddcba..1283fa3 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -55,6 +55,27 @@
 
 	If unsure, say Y.
 
+config UHID
+	tristate "User-space I/O driver support for HID subsystem"
+	depends on HID
+	default n
+	---help---
+	Say Y here if you want to provide HID I/O Drivers from user-space.
+	This allows to write I/O drivers in user-space and feed the data from
+	the device into the kernel. The kernel parses the HID reports, loads the
+	corresponding HID Device Driver or provides input devices on top of your
+	user-space device.
+
+	This driver cannot be used to parse HID-reports in user-space and write
+	special HID-drivers. You should use hidraw for that.
+	Instead, this driver allows to write the transport-layer driver in
+	user-space like USB-HID and Bluetooth-HID do in kernel-space.
+
+	If unsure, say N.
+
+	To compile this driver as a module, choose M here: the
+	module will be called uhid.
+
 source "drivers/hid/usbhid/Kconfig"
 
 menu "Special HID drivers"
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 22f1d16..9dca845 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -8,6 +8,7 @@
 endif
 
 obj-$(CONFIG_HID)		+= hid.o
+obj-$(CONFIG_UHID)		+= uhid.o
 
 hid-$(CONFIG_HIDRAW)		+= hidraw.o
 
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c
new file mode 100644
index 0000000..05ef4b0
--- /dev/null
+++ b/drivers/hid/uhid.c
@@ -0,0 +1,153 @@
+/*
+ * User-space I/O driver support for HID subsystem
+ * Copyright (c) 2012 David Herrmann
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <linux/atomic.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/hid.h>
+#include <linux/input.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/poll.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/uhid.h>
+#include <linux/wait.h>
+
+#define UHID_NAME	"uhid"
+#define UHID_BUFSIZE	32
+
+struct uhid_device {
+	struct hid_device *hid;
+
+	wait_queue_head_t waitq;
+	spinlock_t qlock;
+	__u8 head;
+	__u8 tail;
+	struct uhid_event *outq[UHID_BUFSIZE];
+};
+
+static struct miscdevice uhid_misc;
+
+static void uhid_queue(struct uhid_device *uhid, struct uhid_event *ev)
+{
+	__u8 newhead;
+
+	newhead = (uhid->head + 1) % UHID_BUFSIZE;
+
+	if (newhead != uhid->tail) {
+		uhid->outq[uhid->head] = ev;
+		uhid->head = newhead;
+		wake_up_interruptible(&uhid->waitq);
+	} else {
+		hid_warn(uhid->hid, "Output queue is full\n");
+		kfree(ev);
+	}
+}
+
+static int uhid_queue_event(struct uhid_device *uhid, __u32 event)
+{
+	unsigned long flags;
+	struct uhid_event *ev;
+
+	ev = kzalloc(sizeof(*ev), GFP_KERNEL);
+	if (!ev)
+		return -ENOMEM;
+
+	ev->type = event;
+
+	spin_lock_irqsave(&uhid->qlock, flags);
+	uhid_queue(uhid, ev);
+	spin_unlock_irqrestore(&uhid->qlock, flags);
+
+	return 0;
+}
+
+static int uhid_char_open(struct inode *inode, struct file *file)
+{
+	struct uhid_device *uhid;
+
+	uhid = kzalloc(sizeof(*uhid), GFP_KERNEL);
+	if (!uhid)
+		return -ENOMEM;
+
+	spin_lock_init(&uhid->qlock);
+	init_waitqueue_head(&uhid->waitq);
+
+	file->private_data = uhid;
+	nonseekable_open(inode, file);
+
+	return 0;
+}
+
+static int uhid_char_release(struct inode *inode, struct file *file)
+{
+	struct uhid_device *uhid = file->private_data;
+	unsigned int i;
+
+	for (i = 0; i < UHID_BUFSIZE; ++i)
+		kfree(uhid->outq[i]);
+
+	kfree(uhid);
+
+	return 0;
+}
+
+static ssize_t uhid_char_read(struct file *file, char __user *buffer,
+				size_t count, loff_t *ppos)
+{
+	return 0;
+}
+
+static ssize_t uhid_char_write(struct file *file, const char __user *buffer,
+				size_t count, loff_t *ppos)
+{
+	return 0;
+}
+
+static unsigned int uhid_char_poll(struct file *file, poll_table *wait)
+{
+	return 0;
+}
+
+static const struct file_operations uhid_fops = {
+	.owner		= THIS_MODULE,
+	.open		= uhid_char_open,
+	.release	= uhid_char_release,
+	.read		= uhid_char_read,
+	.write		= uhid_char_write,
+	.poll		= uhid_char_poll,
+	.llseek		= no_llseek,
+};
+
+static struct miscdevice uhid_misc = {
+	.fops		= &uhid_fops,
+	.minor		= MISC_DYNAMIC_MINOR,
+	.name		= UHID_NAME,
+};
+
+static int __init uhid_init(void)
+{
+	return misc_register(&uhid_misc);
+}
+
+static void __exit uhid_exit(void)
+{
+	misc_deregister(&uhid_misc);
+}
+
+module_init(uhid_init);
+module_exit(uhid_exit);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>");
+MODULE_DESCRIPTION("User-space I/O driver support for HID subsystem");
diff --git a/drivers/hwmon/epm_adc.c b/drivers/hwmon/epm_adc.c
index a526f24..c2b5f38 100644
--- a/drivers/hwmon/epm_adc.c
+++ b/drivers/hwmon/epm_adc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/hwmon/m_adcproc.c b/drivers/hwmon/m_adcproc.c
index 70e505e..fe12492 100644
--- a/drivers/hwmon/m_adcproc.c
+++ b/drivers/hwmon/m_adcproc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/hwmon/msm_adc.c b/drivers/hwmon/msm_adc.c
index 018ce79..ca6fae7 100644
--- a/drivers/hwmon/msm_adc.c
+++ b/drivers/hwmon/msm_adc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/hwmon/pm8xxx-adc-scale.c b/drivers/hwmon/pm8xxx-adc-scale.c
index 4a1f58c..56c352a 100644
--- a/drivers/hwmon/pm8xxx-adc-scale.c
+++ b/drivers/hwmon/pm8xxx-adc-scale.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -271,172 +271,174 @@
 };
 
 static const struct pm8xxx_adc_map_pt adcmap_ntcg_104ef_104fb[] = {
-	{696483,	-40960},
-	{649148,	-39936},
-	{605368,	-38912},
-	{564809,	-37888},
-	{527215,	-36864},
-	{492322,	-35840},
-	{460007,	-34816},
-	{429982,	-33792},
-	{402099,	-32768},
-	{376192,	-31744},
-	{352075,	-30720},
-	{329714,	-29696},
-	{308876,	-28672},
-	{289480,	-27648},
-	{271417,	-26624},
-	{254574,	-25600},
-	{238903,	-24576},
-	{224276,	-23552},
-	{210631,	-22528},
-	{197896,	-21504},
-	{186007,	-20480},
-	{174899,	-19456},
-	{164521,	-18432},
-	{154818,	-17408},
-	{145744,	-16384},
-	{137265,	-15360},
-	{129307,	-14336},
-	{121866,	-13312},
-	{114896,	-12288},
-	{108365,	-11264},
-	{102252,	-10240},
-	{96499,		-9216},
-	{91111,		-8192},
-	{86055,		-7168},
-	{81308,		-6144},
-	{76857,		-5120},
-	{72660,		-4096},
-	{68722,		-3072},
-	{65020,		-2048},
-	{61538,		-1024},
-	{58261,		0},
-	{55177,		1024},
-	{52274,		2048},
-	{49538,		3072},
-	{46962,		4096},
-	{44531,		5120},
-	{42243,		6144},
-	{40083,		7168},
-	{38045,		8192},
-	{36122,		9216},
-	{34308,		10240},
-	{32592,		11264},
-	{30972,		12288},
-	{29442,		13312},
-	{27995,		14336},
-	{26624,		15360},
-	{25333,		16384},
-	{24109,		17408},
-	{22951,		18432},
-	{21854,		19456},
-	{20807,		20480},
-	{19831,		21504},
-	{18899,		22528},
-	{18016,		23552},
-	{17178,		24576},
-	{16384,		25600},
-	{15631,		26624},
-	{14916,		27648},
-	{14237,		28672},
-	{13593,		29696},
-	{12976,		30720},
-	{12400,		31744},
-	{11848,		32768},
-	{11324,		33792},
-	{10825,		34816},
-	{10354,		35840},
-	{9900,		36864},
-	{9471,		37888},
-	{9062,		38912},
-	{8674,		39936},
-	{8306,		40960},
-	{7951,		41984},
-	{7616,		43008},
-	{7296,		44032},
-	{6991,		45056},
-	{6701,		46080},
-	{6424,		47104},
-	{6160,		48128},
-	{5908,		49152},
-	{5667,		50176},
-	{5439,		51200},
-	{5219,		52224},
-	{5010,		53248},
-	{4810,		54272},
-	{4619,		55296},
-	{4440,		56320},
-	{4263,		57344},
-	{4097,		58368},
-	{3938,		59392},
-	{3785,		60416},
-	{3637,		61440},
-	{3501,		62464},
-	{3368,		63488},
-	{3240,		64512},
-	{3118,		65536},
-	{2998,		66560},
-	{2889,		67584},
-	{2782,		68608},
-	{2680,		69632},
-	{2581,		70656},
-	{2490,		71680},
-	{2397,		72704},
-	{2310,		73728},
-	{2227,		74752},
-	{2147,		75776},
-	{2064,		76800},
-	{1998,		77824},
-	{1927,		78848},
-	{1860,		79872},
-	{1795,		80896},
-	{1736,		81920},
-	{1673,		82944},
-	{1615,		83968},
-	{1560,		84992},
-	{1507,		86016},
-	{1456,		87040},
-	{1407,		88064},
-	{1360,		89088},
-	{1314,		90112},
-	{1271,		91136},
-	{1228,		92160},
-	{1189,		93184},
-	{1150,		94208},
-	{1112,		95232},
-	{1076,		96256},
-	{1042,		97280},
-	{1008,		98304},
-	{976,		99328},
-	{945,		100352},
-	{915,		101376},
+	{374682,	-40960},
+	{360553,	-39936},
+	{346630,	-38912},
+	{332940,	-37888},
+	{319510,	-36864},
+	{306363,	-35840},
+	{293521,	-34816},
+	{281001,	-33792},
+	{268818,	-32768},
+	{256987,	-31744},
+	{245516,	-30720},
+	{234413,	-29696},
+	{223685,	-28672},
+	{213333,	-27648},
+	{203360,	-26624},
+	{193763,	-25600},
+	{184541,	-24576},
+	{175691,	-23552},
+	{167205,	-22528},
+	{159079,	-21504},
+	{151304,	-20480},
+	{143872,	-19456},
+	{136775,	-18432},
+	{130001,	-17408},
+	{123542,	-16384},
+	{117387,	-15360},
+	{111526,	-14336},
+	{105946,	-13312},
+	{100639,	-12288},
+	{95592,		-11264},
+	{90795,		-10240},
+	{86238,		-9216},
+	{81909,		-8192},
+	{77800,		-7168},
+	{73899,		-6144},
+	{70197,		-5120},
+	{66685,		-4096},
+	{63354,		-3072},
+	{60194,		-2048},
+	{57198,		-1024},
+	{54356,		0},
+	{51662,		1024},
+	{49108,		2048},
+	{46687,		3072},
+	{44391,		4096},
+	{42215,		5120},
+	{40151,		6144},
+	{38195,		7168},
+	{36340,		8192},
+	{34582,		9216},
+	{32914,		10240},
+	{31333,		11264},
+	{29833,		12288},
+	{28410,		13312},
+	{27061,		14336},
+	{25781,		15360},
+	{24566,		16384},
+	{23413,		17408},
+	{22319,		18432},
+	{21280,		19456},
+	{20294,		20480},
+	{19358,		21504},
+	{18469,		22528},
+	{17624,		23552},
+	{16822,		24576},
+	{16060,		25600},
+	{15335,		26624},
+	{14646,		27648},
+	{13992,		28672},
+	{13369,		29696},
+	{12777,		30720},
+	{12214,		31744},
+	{11678,		32768},
+	{11168,		33792},
+	{10682,		34816},
+	{10220,		35840},
+	{9780,		36864},
+	{9361,		37888},
+	{8962,		38912},
+	{8582,		39936},
+	{8219,		40960},
+	{7874,		41984},
+	{7545,		43008},
+	{7231,		44032},
+	{6931,		45056},
+	{6646,		46080},
+	{6373,		47104},
+	{6113,		48128},
+	{5865,		49152},
+	{5628,		50176},
+	{5402,		51200},
+	{5185,		52224},
+	{4979,		53248},
+	{4782,		54272},
+	{4593,		55296},
+	{4413,		56320},
+	{4241,		57344},
+	{4076,		58368},
+	{3919,		59392},
+	{3768,		60416},
+	{3624,		61440},
+	{3486,		62464},
+	{3354,		63488},
+	{3227,		64512},
+	{3106,		65536},
+	{2990,		66560},
+	{2879,		67584},
+	{2773,		68608},
+	{2671,		69632},
+	{2573,		70656},
+	{2479,		71680},
+	{2390,		72704},
+	{2303,		73728},
+	{2221,		74752},
+	{2142,		75776},
+	{2066,		76800},
+	{1993,		77824},
+	{1923,		78848},
+	{1855,		79872},
+	{1791,		80896},
+	{1729,		81920},
+	{1669,		82944},
+	{1612,		83968},
+	{1557,		84992},
+	{1504,		86016},
+	{1453,		87040},
+	{1404,		88064},
+	{1357,		89088},
+	{1312,		90112},
+	{1269,		91136},
+	{1227,		92160},
+	{1187,		93184},
+	{1148,		94208},
+	{1111,		95232},
+	{1075,		96256},
+	{1040,		97280},
+	{1007,		98304},
+	{975,		99328},
+	{944,		100352},
+	{914,		101376},
 	{886,		102400},
-	{859,		103424},
-	{832,		104448},
-	{807,		105472},
-	{782,		106496},
-	{756,		107520},
-	{735,		108544},
+	{858,		103424},
+	{831,		104448},
+	{806,		105472},
+	{781,		106496},
+	{757,		107520},
+	{734,		108544},
 	{712,		109568},
-	{691,		110592},
+	{690,		110592},
 	{670,		111616},
 	{650,		112640},
-	{631,		113664},
+	{630,		113664},
 	{612,		114688},
 	{594,		115712},
-	{577,		116736},
-	{560,		117760},
-	{544,		118784},
-	{528,		119808},
-	{513,		120832},
+	{576,		116736},
+	{559,		117760},
+	{543,		118784},
+	{527,		119808},
+	{512,		120832},
 	{498,		121856},
 	{483,		122880},
 	{470,		123904},
-	{457,		124928},
+	{456,		124928},
 	{444,		125952},
 	{431,		126976},
-	{419,		128000}
+	{419,		128000},
+	{408,		129024},
+	{396,		130048}
 };
 
 static int32_t pm8xxx_adc_map_linear(const struct pm8xxx_adc_map_pt *pts,
@@ -716,6 +718,10 @@
 		struct pm8xxx_adc_chan_result *adc_chan_result)
 {
 	int64_t xo_thm = 0;
+	uint32_t num1 = 0;
+	uint32_t num2 = 0;
+	uint32_t dnum = 0;
+	uint32_t rt_r25 = 0;
 
 	if (!chan_properties || !chan_properties->offset_gain_numerator ||
 		!chan_properties->offset_gain_denominator || !adc_properties
@@ -724,10 +730,21 @@
 
 	xo_thm = pm8xxx_adc_scale_ratiometric_calib(adc_code,
 			adc_properties, chan_properties);
-	xo_thm <<= 4;
+	if (xo_thm < 0)
+		xo_thm = -xo_thm;
+
+	num1 = xo_thm << 14;
+	num2 = (adc_properties->adc_vdd_reference - xo_thm) >> 1;
+	dnum = (adc_properties->adc_vdd_reference - xo_thm);
+
+	if (dnum == 0)
+		rt_r25 = 0x7FFFFFFF ;
+	else
+		rt_r25 = (num1 + num2)/dnum ;
+
 	pm8xxx_adc_map_linear(adcmap_ntcg_104ef_104fb,
 		ARRAY_SIZE(adcmap_ntcg_104ef_104fb),
-		xo_thm, &adc_chan_result->physical);
+		rt_r25, &adc_chan_result->physical);
 
 	return 0;
 }
diff --git a/drivers/hwmon/pm8xxx-adc.c b/drivers/hwmon/pm8xxx-adc.c
index 181a97e..1a163a4 100644
--- a/drivers/hwmon/pm8xxx-adc.c
+++ b/drivers/hwmon/pm8xxx-adc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -1075,7 +1075,7 @@
 
 	return 0;
 }
-DEFINE_SIMPLE_ATTRIBUTE(reg_fops, get_adc, NULL, "%llu\n");
+DEFINE_SIMPLE_ATTRIBUTE(reg_fops, get_adc, NULL, "%lld\n");
 
 #ifdef CONFIG_DEBUG_FS
 static void create_debugfs_entries(void)
diff --git a/drivers/hwmon/qpnp-adc-common.c b/drivers/hwmon/qpnp-adc-common.c
index 440dc42..ecd4bbb 100644
--- a/drivers/hwmon/qpnp-adc-common.c
+++ b/drivers/hwmon/qpnp-adc-common.c
@@ -130,175 +130,6 @@
 	{790,	203}
 };
 
-static const struct qpnp_vadc_map_pt adcmap_ntcg_104ef_104fb[] = {
-	{696483,	-40960},
-	{649148,	-39936},
-	{605368,	-38912},
-	{564809,	-37888},
-	{527215,	-36864},
-	{492322,	-35840},
-	{460007,	-34816},
-	{429982,	-33792},
-	{402099,	-32768},
-	{376192,	-31744},
-	{352075,	-30720},
-	{329714,	-29696},
-	{308876,	-28672},
-	{289480,	-27648},
-	{271417,	-26624},
-	{254574,	-25600},
-	{238903,	-24576},
-	{224276,	-23552},
-	{210631,	-22528},
-	{197896,	-21504},
-	{186007,	-20480},
-	{174899,	-19456},
-	{164521,	-18432},
-	{154818,	-17408},
-	{145744,	-16384},
-	{137265,	-15360},
-	{129307,	-14336},
-	{121866,	-13312},
-	{114896,	-12288},
-	{108365,	-11264},
-	{102252,	-10240},
-	{96499,		-9216},
-	{91111,		-8192},
-	{86055,		-7168},
-	{81308,		-6144},
-	{76857,		-5120},
-	{72660,		-4096},
-	{68722,		-3072},
-	{65020,		-2048},
-	{61538,		-1024},
-	{58261,		0},
-	{55177,		1024},
-	{52274,		2048},
-	{49538,		3072},
-	{46962,		4096},
-	{44531,		5120},
-	{42243,		6144},
-	{40083,		7168},
-	{38045,		8192},
-	{36122,		9216},
-	{34308,		10240},
-	{32592,		11264},
-	{30972,		12288},
-	{29442,		13312},
-	{27995,		14336},
-	{26624,		15360},
-	{25333,		16384},
-	{24109,		17408},
-	{22951,		18432},
-	{21854,		19456},
-	{20807,		20480},
-	{19831,		21504},
-	{18899,		22528},
-	{18016,		23552},
-	{17178,		24576},
-	{16384,		25600},
-	{15631,		26624},
-	{14916,		27648},
-	{14237,		28672},
-	{13593,		29696},
-	{12976,		30720},
-	{12400,		31744},
-	{11848,		32768},
-	{11324,		33792},
-	{10825,		34816},
-	{10354,		35840},
-	{9900,		36864},
-	{9471,		37888},
-	{9062,		38912},
-	{8674,		39936},
-	{8306,		40960},
-	{7951,		41984},
-	{7616,		43008},
-	{7296,		44032},
-	{6991,		45056},
-	{6701,		46080},
-	{6424,		47104},
-	{6160,		48128},
-	{5908,		49152},
-	{5667,		50176},
-	{5439,		51200},
-	{5219,		52224},
-	{5010,		53248},
-	{4810,		54272},
-	{4619,		55296},
-	{4440,		56320},
-	{4263,		57344},
-	{4097,		58368},
-	{3938,		59392},
-	{3785,		60416},
-	{3637,		61440},
-	{3501,		62464},
-	{3368,		63488},
-	{3240,		64512},
-	{3118,		65536},
-	{2998,		66560},
-	{2889,		67584},
-	{2782,		68608},
-	{2680,		69632},
-	{2581,		70656},
-	{2490,		71680},
-	{2397,		72704},
-	{2310,		73728},
-	{2227,		74752},
-	{2147,		75776},
-	{2064,		76800},
-	{1998,		77824},
-	{1927,		78848},
-	{1860,		79872},
-	{1795,		80896},
-	{1736,		81920},
-	{1673,		82944},
-	{1615,		83968},
-	{1560,		84992},
-	{1507,		86016},
-	{1456,		87040},
-	{1407,		88064},
-	{1360,		89088},
-	{1314,		90112},
-	{1271,		91136},
-	{1228,		92160},
-	{1189,		93184},
-	{1150,		94208},
-	{1112,		95232},
-	{1076,		96256},
-	{1042,		97280},
-	{1008,		98304},
-	{976,		99328},
-	{945,		100352},
-	{915,		101376},
-	{886,		102400},
-	{859,		103424},
-	{832,		104448},
-	{807,		105472},
-	{782,		106496},
-	{756,		107520},
-	{735,		108544},
-	{712,		109568},
-	{691,		110592},
-	{670,		111616},
-	{650,		112640},
-	{631,		113664},
-	{612,		114688},
-	{594,		115712},
-	{577,		116736},
-	{560,		117760},
-	{544,		118784},
-	{528,		119808},
-	{513,		120832},
-	{498,		121856},
-	{483,		122880},
-	{470,		123904},
-	{457,		124928},
-	{444,		125952},
-	{431,		126976},
-	{419,		128000}
-};
-
 /* Voltage to temperature */
 static const struct qpnp_vadc_map_pt adcmap_100k_104ef_104fb[] = {
 	{1758,	-40},
@@ -553,9 +384,9 @@
 
 	xo_thm = qpnp_adc_scale_ratiometric_calib(adc_code,
 			adc_properties, chan_properties);
-	xo_thm <<= 4;
-	qpnp_adc_map_voltage_temp(adcmap_ntcg_104ef_104fb,
-		ARRAY_SIZE(adcmap_ntcg_104ef_104fb),
+
+	qpnp_adc_map_voltage_temp(adcmap_100k_104ef_104fb,
+		ARRAY_SIZE(adcmap_100k_104ef_104fb),
 		xo_thm, &adc_chan_result->physical);
 
 	return 0;
@@ -751,7 +582,7 @@
 {
 	struct qpnp_vadc_linear_graph usb_param;
 
-	qpnp_get_vadc_gain_and_offset(&usb_param, CALIB_ABSOLUTE);
+	qpnp_get_vadc_gain_and_offset(&usb_param, CALIB_RATIOMETRIC);
 
 	*low_threshold = param->low_thr * usb_param.dy;
 	do_div(*low_threshold, usb_param.adc_vref);
diff --git a/drivers/hwmon/qpnp-adc-current.c b/drivers/hwmon/qpnp-adc-current.c
index 8071687e..2017c8d 100644
--- a/drivers/hwmon/qpnp-adc-current.c
+++ b/drivers/hwmon/qpnp-adc-current.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
@@ -125,15 +125,18 @@
 #define QPNP_BIT_SHIFT_8				8
 #define QPNP_RSENSE_MSB_SIGN_CHECK			0x80
 #define QPNP_ADC_COMPLETION_TIMEOUT			HZ
+#define QPNP_IADC_ERR_CHK_RATELIMIT			3
 
 struct qpnp_iadc_drv {
 	struct qpnp_adc_drv			*adc;
 	int32_t					rsense;
 	struct device				*iadc_hwmon;
-	bool					iadc_init_calib;
 	bool					iadc_initialized;
 	int64_t					die_temp_calib_offset;
 	struct delayed_work			iadc_work;
+	struct mutex				iadc_vadc_lock;
+	bool					iadc_mode_sel;
+	uint32_t				iadc_err_cnt;
 	struct sensor_device_attribute		sens_attr[0];
 };
 
@@ -171,6 +174,51 @@
 	return 0;
 }
 
+static void trigger_iadc_completion(struct work_struct *work)
+{
+	struct qpnp_iadc_drv *iadc = qpnp_iadc;
+
+	if (!iadc || !iadc->iadc_initialized)
+		return;
+
+	complete(&iadc->adc->adc_rslt_completion);
+
+	return;
+}
+DECLARE_WORK(trigger_iadc_completion_work, trigger_iadc_completion);
+
+static irqreturn_t qpnp_iadc_isr(int irq, void *dev_id)
+{
+	schedule_work(&trigger_iadc_completion_work);
+
+	return IRQ_HANDLED;
+}
+
+static int32_t qpnp_iadc_enable(bool state)
+{
+	int rc = 0;
+	u8 data = 0;
+
+	data = QPNP_IADC_ADC_EN;
+	if (state) {
+		rc = qpnp_iadc_write_reg(QPNP_IADC_EN_CTL1,
+					data);
+		if (rc < 0) {
+			pr_err("IADC enable failed\n");
+			return rc;
+		}
+	} else {
+		rc = qpnp_iadc_write_reg(QPNP_IADC_EN_CTL1,
+					(~data & QPNP_IADC_ADC_EN));
+		if (rc < 0) {
+			pr_err("IADC disable failed\n");
+			return rc;
+		}
+	}
+
+	return 0;
+}
+
 static int32_t qpnp_iadc_status_debug(void)
 {
 	int rc = 0;
@@ -209,46 +257,10 @@
 	pr_err("EOC not set with status:%x, dig:%x, ch:%x, mode:%x, en:%x\n",
 			status1, dig, chan, mode, en);
 
-	return 0;
-}
-
-static void trigger_iadc_completion(struct work_struct *work)
-{
-	struct qpnp_iadc_drv *iadc = qpnp_iadc;
-
-	complete(&iadc->adc->adc_rslt_completion);
-
-	return;
-}
-DECLARE_WORK(trigger_iadc_completion_work, trigger_iadc_completion);
-
-static irqreturn_t qpnp_iadc_isr(int irq, void *dev_id)
-{
-	schedule_work(&trigger_iadc_completion_work);
-
-	return IRQ_HANDLED;
-}
-
-static int32_t qpnp_iadc_enable(bool state)
-{
-	int rc = 0;
-	u8 data = 0;
-
-	data = QPNP_IADC_ADC_EN;
-	if (state) {
-		rc = qpnp_iadc_write_reg(QPNP_IADC_EN_CTL1,
-					data);
-		if (rc < 0) {
-			pr_err("IADC enable failed\n");
-			return rc;
-		}
-	} else {
-		rc = qpnp_iadc_write_reg(QPNP_IADC_EN_CTL1,
-					(~data & QPNP_IADC_ADC_EN));
-		if (rc < 0) {
-			pr_err("IADC disable failed\n");
-			return rc;
-		}
+	rc = qpnp_iadc_enable(false);
+	if (rc < 0) {
+		pr_err("IADC disable failed with %d\n", rc);
+		return rc;
 	}
 
 	return 0;
@@ -283,7 +295,7 @@
 }
 
 static int32_t qpnp_iadc_configure(enum qpnp_iadc_channels channel,
-						uint16_t *raw_code)
+					uint16_t *raw_code, uint32_t mode_sel)
 {
 	struct qpnp_iadc_drv *iadc = qpnp_iadc;
 	u8 qpnp_iadc_mode_reg = 0, qpnp_iadc_ch_sel_reg = 0;
@@ -294,7 +306,11 @@
 
 	qpnp_iadc_dig_param_reg |= iadc->adc->amux_prop->decimation <<
 					QPNP_IADC_DEC_RATIO_SEL;
-	qpnp_iadc_mode_reg |= QPNP_ADC_TRIM_EN;
+	if (iadc->iadc_mode_sel)
+		qpnp_iadc_mode_reg |= (QPNP_ADC_TRIM_EN | QPNP_VADC_SYNCH_EN);
+	else
+		qpnp_iadc_mode_reg |= QPNP_ADC_TRIM_EN;
+
 	qpnp_iadc_conv_req = QPNP_IADC_CONV_REQ;
 
 	rc = qpnp_iadc_write_reg(QPNP_IADC_MODE_CTL, qpnp_iadc_mode_reg);
@@ -375,10 +391,13 @@
 	struct qpnp_iadc_drv *iadc = qpnp_iadc;
 	uint32_t num = 0;
 
-	num = iadc->adc->calib.offset_raw - iadc->adc->calib.offset_raw;
+	if ((iadc->adc->calib.gain_raw - iadc->adc->calib.offset_raw) == 0) {
+		pr_err("raw offset errors! raw_gain:0x%x and raw_offset:0x%x\n",
+			iadc->adc->calib.gain_raw, iadc->adc->calib.offset_raw);
+		return -EINVAL;
+	}
 
-	iadc->adc->calib.offset_uv = (num * QPNP_ADC_GAIN_NV)/
-		(iadc->adc->calib.gain_raw - iadc->adc->calib.offset_raw);
+	iadc->adc->calib.offset_uv = 0;
 
 	num = iadc->adc->calib.gain_raw - iadc->adc->calib.offset_raw;
 
@@ -394,8 +413,12 @@
 	uint8_t rslt_lsb, rslt_msb;
 	int32_t rc = 0;
 	uint16_t raw_data;
+	uint32_t mode_sel = 0;
 
-	rc = qpnp_iadc_configure(GAIN_CALIBRATION_17P857MV, &raw_data);
+	mutex_lock(&iadc->adc->adc_lock);
+
+	rc = qpnp_iadc_configure(GAIN_CALIBRATION_17P857MV,
+						&raw_data, mode_sel);
 	if (rc < 0) {
 		pr_err("qpnp adc result read failed with %d\n", rc);
 		goto fail;
@@ -403,8 +426,8 @@
 
 	iadc->adc->calib.gain_raw = raw_data;
 
-	rc = qpnp_iadc_configure(OFFSET_CALIBRATION_SHORT_CADC_LEADS,
-								&raw_data);
+	rc = qpnp_iadc_configure(OFFSET_CALIBRATION_CSP2_CSN2,
+						&raw_data, mode_sel);
 	if (rc < 0) {
 		pr_err("qpnp adc result read failed with %d\n", rc);
 		goto fail;
@@ -417,6 +440,10 @@
 	}
 
 	rc = qpnp_convert_raw_offset_voltage();
+	if (rc < 0) {
+		pr_err("qpnp raw_voltage conversion failed\n");
+		goto fail;
+	}
 
 	rslt_msb = (raw_data & QPNP_RAW_CODE_16_BIT_MSB_MASK) >>
 							QPNP_BIT_SHIFT_8;
@@ -450,6 +477,7 @@
 		goto fail;
 	}
 fail:
+	mutex_unlock(&iadc->adc->adc_lock);
 	return rc;
 }
 
@@ -458,15 +486,14 @@
 	struct qpnp_iadc_drv *iadc = qpnp_iadc;
 	int rc = 0;
 
-	mutex_lock(&iadc->adc->adc_lock);
-
 	rc = qpnp_iadc_calibrate_for_trim();
-	if (rc)
+	if (rc) {
 		pr_err("periodic IADC calibration failed\n");
+		iadc->iadc_err_cnt++;
+	}
 
-	mutex_unlock(&iadc->adc->adc_lock);
-
-	schedule_delayed_work(&iadc->iadc_work,
+	if (iadc->iadc_err_cnt < QPNP_IADC_ERR_CHK_RATELIMIT)
+		schedule_delayed_work(&iadc->iadc_work,
 			round_jiffies_relative(msecs_to_jiffies
 					(QPNP_IADC_CALIB_SECONDS)));
 
@@ -505,9 +532,13 @@
 
 int32_t qpnp_iadc_get_rsense(int32_t *rsense)
 {
+	struct qpnp_iadc_drv *iadc = qpnp_iadc;
 	uint8_t	rslt_rsense;
 	int32_t	rc, sign_bit = 0;
 
+	if (!iadc || !iadc->iadc_initialized)
+		return -EPROBE_DEFER;
+
 	rc = qpnp_iadc_read_reg(QPNP_IADC_NOMINAL_RSENSE, &rslt_rsense);
 	if (rc < 0) {
 		pr_err("qpnp adc rsense read failed with %d\n", rc);
@@ -528,12 +559,13 @@
 
 	return rc;
 }
+EXPORT_SYMBOL(qpnp_iadc_get_rsense);
 
-int32_t qpnp_check_pmic_temp(void)
+static int32_t qpnp_check_pmic_temp(void)
 {
 	struct qpnp_iadc_drv *iadc = qpnp_iadc;
 	struct qpnp_vadc_result result_pmic_therm;
-	int rc;
+	int rc = 0;
 
 	rc = qpnp_vadc_read(DIE_TEMP, &result_pmic_therm);
 	if (rc < 0)
@@ -542,38 +574,36 @@
 	if (((uint64_t) (result_pmic_therm.physical -
 				iadc->die_temp_calib_offset))
 			> QPNP_IADC_DIE_TEMP_CALIB_OFFSET) {
-		mutex_lock(&iadc->adc->adc_lock);
-
 		rc = qpnp_iadc_calibrate_for_trim();
 		if (rc)
 			pr_err("periodic IADC calibration failed\n");
-
-		mutex_unlock(&iadc->adc->adc_lock);
 	}
 
-	return 0;
+	return rc;
 }
 
 int32_t qpnp_iadc_read(enum qpnp_iadc_channels channel,
 				struct qpnp_iadc_result *result)
 {
 	struct qpnp_iadc_drv *iadc = qpnp_iadc;
-	int32_t rc, rsense_n_ohms, sign = 0, num;
+	int32_t rc, rsense_n_ohms, sign = 0, num, mode_sel = 0;
 	int64_t result_current;
 	uint16_t raw_data;
 
 	if (!iadc || !iadc->iadc_initialized)
 		return -EPROBE_DEFER;
 
-	rc = qpnp_check_pmic_temp();
-	if (rc) {
-		pr_err("Error checking pmic therm temp\n");
-		return rc;
+	if (!iadc->iadc_mode_sel) {
+		rc = qpnp_check_pmic_temp();
+		if (rc) {
+			pr_err("Error checking pmic therm temp\n");
+			return rc;
+		}
 	}
 
 	mutex_lock(&iadc->adc->adc_lock);
 
-	rc = qpnp_iadc_configure(channel, &raw_data);
+	rc = qpnp_iadc_configure(channel, &raw_data, mode_sel);
 	if (rc < 0) {
 		pr_err("qpnp adc result read failed with %d\n", rc);
 		goto fail;
@@ -634,6 +664,50 @@
 }
 EXPORT_SYMBOL(qpnp_iadc_get_gain_and_offset);
 
+int32_t qpnp_iadc_vadc_sync_read(
+	enum qpnp_iadc_channels i_channel, struct qpnp_iadc_result *i_result,
+	enum qpnp_vadc_channels v_channel, struct qpnp_vadc_result *v_result)
+{
+	struct qpnp_iadc_drv *iadc = qpnp_iadc;
+	int rc = 0;
+
+	if (!iadc || !iadc->iadc_initialized)
+		return -EPROBE_DEFER;
+
+	mutex_lock(&iadc->iadc_vadc_lock);
+
+	rc = qpnp_check_pmic_temp();
+	if (rc) {
+		pr_err("PMIC die temp check failed\n");
+		goto fail;
+	}
+
+	iadc->iadc_mode_sel = true;
+
+	rc = qpnp_vadc_iadc_sync_request(v_channel);
+	if (rc) {
+		pr_err("Configuring VADC failed\n");
+		goto fail;
+	}
+
+	rc = qpnp_iadc_read(i_channel, i_result);
+	if (rc)
+		pr_err("Configuring IADC failed\n");
+	/* Intentional fall through to release VADC */
+
+	rc = qpnp_vadc_iadc_sync_complete_request(v_channel,
+							v_result);
+	if (rc)
+		pr_err("Releasing VADC failed\n");
+fail:
+	iadc->iadc_mode_sel = false;
+
+	mutex_unlock(&iadc->iadc_vadc_lock);
+
+	return rc;
+}
+EXPORT_SYMBOL(qpnp_iadc_vadc_sync_read);
+
 static ssize_t qpnp_iadc_show(struct device *dev,
 			struct device_attribute *devattr, char *buf)
 {
@@ -721,7 +795,8 @@
 			GFP_KERNEL);
 	if (!adc_qpnp) {
 		dev_err(&spmi->dev, "Unable to allocate memory\n");
-		return -ENOMEM;
+		rc = -ENOMEM;
+		goto fail;
 	}
 
 	iadc->adc = adc_qpnp;
@@ -729,14 +804,14 @@
 	rc = qpnp_adc_get_devicetree_data(spmi, iadc->adc);
 	if (rc) {
 		dev_err(&spmi->dev, "failed to read device tree\n");
-		return rc;
+		goto fail;
 	}
 
 	rc = of_property_read_u32(node, "qcom,rsense",
 			&iadc->rsense);
 	if (rc) {
 		pr_err("Invalid rsens reference property\n");
-		return -EINVAL;
+		goto fail;
 	}
 
 	rc = devm_request_irq(&spmi->dev, iadc->adc->adc_irq_eoc,
@@ -744,40 +819,41 @@
 	IRQF_TRIGGER_RISING, "qpnp_iadc_interrupt", iadc);
 	if (rc) {
 		dev_err(&spmi->dev, "failed to request adc irq\n");
-		return rc;
+		goto fail;
 	} else
 		enable_irq_wake(iadc->adc->adc_irq_eoc);
 
-	iadc->iadc_init_calib = false;
 	dev_set_drvdata(&spmi->dev, iadc);
 	qpnp_iadc = iadc;
 
 	rc = qpnp_iadc_init_hwmon(spmi);
 	if (rc) {
 		dev_err(&spmi->dev, "failed to initialize qpnp hwmon adc\n");
-		return rc;
+		goto fail;
 	}
 	iadc->iadc_hwmon = hwmon_device_register(&iadc->adc->spmi->dev);
 
 	rc = qpnp_iadc_version_check();
 	if (rc) {
 		dev_err(&spmi->dev, "IADC version not supported\n");
-		return rc;
+		goto fail;
 	}
 
-	rc = qpnp_iadc_calibrate_for_trim();
-	if (rc) {
-		dev_err(&spmi->dev, "failed to calibrate for USR trim\n");
-		return rc;
-	}
-	iadc->iadc_init_calib = true;
+	mutex_init(&iadc->iadc_vadc_lock);
 	INIT_DELAYED_WORK(&iadc->iadc_work, qpnp_iadc_work);
+	iadc->iadc_err_cnt = 0;
+	iadc->iadc_initialized = true;
+
+	rc = qpnp_iadc_calibrate_for_trim();
+	if (rc)
+		dev_err(&spmi->dev, "failed to calibrate for USR trim\n");
 	schedule_delayed_work(&iadc->iadc_work,
 			round_jiffies_relative(msecs_to_jiffies
 					(QPNP_IADC_CALIB_SECONDS)));
-	iadc->iadc_initialized = true;
-
 	return 0;
+fail:
+	qpnp_iadc = NULL;
+	return rc;
 }
 
 static int __devexit qpnp_iadc_remove(struct spmi_device *spmi)
@@ -787,6 +863,8 @@
 	struct device_node *child;
 	int i = 0;
 
+	cancel_delayed_work(&iadc->iadc_work);
+	mutex_destroy(&iadc->iadc_vadc_lock);
 	for_each_child_of_node(node, child) {
 		device_remove_file(&spmi->dev,
 			&iadc->sens_attr[i].dev_attr);
diff --git a/drivers/hwmon/qpnp-adc-voltage.c b/drivers/hwmon/qpnp-adc-voltage.c
index d8d5b53..edbde44 100644
--- a/drivers/hwmon/qpnp-adc-voltage.c
+++ b/drivers/hwmon/qpnp-adc-voltage.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
@@ -98,6 +98,7 @@
 	bool				vadc_init_calib;
 	bool				vadc_initialized;
 	int				max_channels_available;
+	bool				vadc_iadc_sync_lock;
 	struct sensor_device_attribute		sens_attr[0];
 };
 
@@ -170,6 +171,58 @@
 	return 0;
 }
 
+static int32_t qpnp_vadc_status_debug(void)
+{
+	int rc = 0;
+	u8 mode = 0, status1 = 0, chan = 0, dig = 0, en = 0, status2 = 0;
+
+	rc = qpnp_vadc_read_reg(QPNP_VADC_MODE_CTL, &mode);
+	if (rc < 0) {
+		pr_err("mode ctl register read failed with %d\n", rc);
+		return rc;
+	}
+
+	rc = qpnp_vadc_read_reg(QPNP_VADC_ADC_DIG_PARAM, &dig);
+	if (rc < 0) {
+		pr_err("digital param read failed with %d\n", rc);
+		return rc;
+	}
+
+	rc = qpnp_vadc_read_reg(QPNP_VADC_ADC_CH_SEL_CTL, &chan);
+	if (rc < 0) {
+		pr_err("channel read failed with %d\n", rc);
+		return rc;
+	}
+
+	rc = qpnp_vadc_read_reg(QPNP_VADC_STATUS1, &status1);
+	if (rc < 0) {
+		pr_err("status1 read failed with %d\n", rc);
+		return rc;
+	}
+
+	rc = qpnp_vadc_read_reg(QPNP_VADC_STATUS2, &status2);
+	if (rc < 0) {
+		pr_err("status2 read failed with %d\n", rc);
+		return rc;
+	}
+
+	rc = qpnp_vadc_read_reg(QPNP_VADC_EN_CTL1, &en);
+	if (rc < 0) {
+		pr_err("en read failed with %d\n", rc);
+		return rc;
+	}
+
+	pr_err("EOC not set - status1/2:%x/%x, dig:%x, ch:%x, mode:%x, en:%x\n",
+			status1, status2, dig, chan, mode, en);
+
+	rc = qpnp_vadc_enable(false);
+	if (rc < 0) {
+		pr_err("VADC disable failed with %d\n", rc);
+		return rc;
+	}
+
+	return 0;
+}
 static int32_t qpnp_vadc_configure(
 			struct qpnp_adc_amux_properties *chan_prop)
 {
@@ -252,11 +305,14 @@
 	if (rc)
 		return rc;
 
-	/* Request conversion */
-	rc = qpnp_vadc_write_reg(QPNP_VADC_CONV_REQ, QPNP_VADC_CONV_REQ_SET);
-	if (rc < 0) {
-		pr_err("Request conversion failed\n");
-		return rc;
+	if (!vadc->vadc_iadc_sync_lock) {
+		/* Request conversion */
+		rc = qpnp_vadc_write_reg(QPNP_VADC_CONV_REQ,
+					QPNP_VADC_CONV_REQ_SET);
+		if (rc < 0) {
+			pr_err("Request conversion failed\n");
+			return rc;
+		}
 	}
 
 	return 0;
@@ -339,6 +395,9 @@
 {
 	struct qpnp_vadc_drv *vadc = qpnp_vadc;
 
+	if (!vadc || !vadc->vadc_initialized)
+		return;
+
 	complete(&vadc->adc->adc_rslt_completion);
 
 	return;
@@ -563,20 +622,21 @@
 	if (!vadc || !vadc->vadc_initialized)
 		return -EPROBE_DEFER;
 
+	mutex_lock(&vadc->adc->adc_lock);
+
 	if (!vadc->vadc_init_calib) {
 		rc = qpnp_vadc_version_check();
 		if (rc)
-			return rc;
+			goto fail_unlock;
+
 		rc = qpnp_vadc_calib_device();
 		if (rc) {
 			pr_err("Calibration failed\n");
-			return rc;
+			goto fail_unlock;
 		} else
 			vadc->vadc_init_calib = true;
 	}
 
-	mutex_lock(&vadc->adc->adc_lock);
-
 	vadc->adc->amux_prop->amux_channel = channel;
 
 	while ((vadc->adc->adc_channels[dt_index].channel_num
@@ -626,7 +686,9 @@
 		if (status1 == QPNP_VADC_STATUS1_EOC)
 			pr_debug("End of conversion status set\n");
 		else {
-			pr_err("EOC interrupt not received\n");
+			rc = qpnp_vadc_status_debug();
+			if (rc < 0)
+				pr_err("VADC disable failed\n");
 			rc = -EINVAL;
 			goto fail_unlock;
 		}
@@ -676,6 +738,121 @@
 }
 EXPORT_SYMBOL_GPL(qpnp_vadc_read);
 
+static void qpnp_vadc_lock(void)
+{
+	struct qpnp_vadc_drv *vadc = qpnp_vadc;
+
+	mutex_lock(&vadc->adc->adc_lock);
+}
+
+static void qpnp_vadc_unlock(void)
+{
+	struct qpnp_vadc_drv *vadc = qpnp_vadc;
+
+	mutex_unlock(&vadc->adc->adc_lock);
+}
+
+int32_t qpnp_vadc_iadc_sync_request(enum qpnp_vadc_channels channel)
+{
+	struct qpnp_vadc_drv *vadc = qpnp_vadc;
+	int rc = 0, dt_index = 0;
+
+	if (!vadc || !vadc->vadc_initialized)
+		return -EPROBE_DEFER;
+
+	qpnp_vadc_lock();
+
+	if (!vadc->vadc_init_calib) {
+		rc = qpnp_vadc_version_check();
+		if (rc)
+			goto fail;
+
+		rc = qpnp_vadc_calib_device();
+		if (rc) {
+			pr_err("Calibration failed\n");
+			goto fail;
+		} else
+			vadc->vadc_init_calib = true;
+	}
+
+	vadc->adc->amux_prop->amux_channel = channel;
+
+	while ((vadc->adc->adc_channels[dt_index].channel_num
+		!= channel) && (dt_index < vadc->max_channels_available))
+		dt_index++;
+
+	if (dt_index >= vadc->max_channels_available) {
+		pr_err("not a valid VADC channel\n");
+		rc = -EINVAL;
+		goto fail;
+	}
+
+	vadc->adc->amux_prop->decimation =
+			vadc->adc->adc_channels[dt_index].adc_decimation;
+	vadc->adc->amux_prop->hw_settle_time =
+			vadc->adc->adc_channels[dt_index].hw_settle_time;
+	vadc->adc->amux_prop->fast_avg_setup =
+			vadc->adc->adc_channels[dt_index].fast_avg_setup;
+	vadc->adc->amux_prop->mode_sel = (ADC_OP_NORMAL_MODE
+					<< QPNP_VADC_OP_MODE_SHIFT);
+	vadc->vadc_iadc_sync_lock = true;
+
+	rc = qpnp_vadc_configure(vadc->adc->amux_prop);
+	if (rc) {
+		pr_err("qpnp vadc configure failed with %d\n", rc);
+		goto fail;
+	}
+
+	return rc;
+fail:
+	vadc->vadc_iadc_sync_lock = false;
+	qpnp_vadc_unlock();
+	return rc;
+}
+EXPORT_SYMBOL(qpnp_vadc_iadc_sync_request);
+
+int32_t qpnp_vadc_iadc_sync_complete_request(enum qpnp_vadc_channels channel,
+						struct qpnp_vadc_result *result)
+{
+	struct qpnp_vadc_drv *vadc = qpnp_vadc;
+	int rc = 0, scale_type, amux_prescaling, dt_index = 0;
+
+	vadc->adc->amux_prop->amux_channel = channel;
+
+	while ((vadc->adc->adc_channels[dt_index].channel_num
+		!= channel) && (dt_index < vadc->max_channels_available))
+		dt_index++;
+
+	rc = qpnp_vadc_read_conversion_result(&result->adc_code);
+	if (rc) {
+		pr_err("qpnp vadc read adc code failed with %d\n", rc);
+		goto fail;
+	}
+
+	amux_prescaling =
+		vadc->adc->adc_channels[dt_index].chan_path_prescaling;
+
+	vadc->adc->amux_prop->chan_prop->offset_gain_numerator =
+		qpnp_vadc_amux_scaling_ratio[amux_prescaling].num;
+	vadc->adc->amux_prop->chan_prop->offset_gain_denominator =
+		 qpnp_vadc_amux_scaling_ratio[amux_prescaling].den;
+
+	scale_type = vadc->adc->adc_channels[dt_index].adc_scale_fn;
+	if (scale_type >= SCALE_NONE) {
+		rc = -EBADF;
+		goto fail;
+	}
+
+	vadc_scale_fn[scale_type].chan(result->adc_code,
+		vadc->adc->adc_prop, vadc->adc->amux_prop->chan_prop, result);
+
+fail:
+	vadc->vadc_iadc_sync_lock = false;
+	qpnp_vadc_unlock();
+	return rc;
+}
+EXPORT_SYMBOL(qpnp_vadc_iadc_sync_complete_request);
+
 static ssize_t qpnp_adc_show(struct device *dev,
 			struct device_attribute *devattr, char *buf)
 {
@@ -765,7 +942,8 @@
 			GFP_KERNEL);
 	if (!adc_qpnp) {
 		dev_err(&spmi->dev, "Unable to allocate memory\n");
-		return -ENOMEM;
+		rc = -ENOMEM;
+		goto fail;
 	}
 
 	vadc->adc = adc_qpnp;
@@ -773,7 +951,7 @@
 	rc = qpnp_adc_get_devicetree_data(spmi, vadc->adc);
 	if (rc) {
 		dev_err(&spmi->dev, "failed to read device tree\n");
-		return rc;
+		goto fail;
 	}
 
 	rc = devm_request_irq(&spmi->dev, vadc->adc->adc_irq_eoc,
@@ -782,7 +960,7 @@
 	if (rc) {
 		dev_err(&spmi->dev,
 			"failed to request adc irq with error %d\n", rc);
-		return rc;
+		goto fail;
 	} else {
 		enable_irq_wake(vadc->adc->adc_irq_eoc);
 	}
@@ -792,14 +970,18 @@
 	rc = qpnp_vadc_init_hwmon(spmi);
 	if (rc) {
 		dev_err(&spmi->dev, "failed to initialize qpnp hwmon adc\n");
-		return rc;
+		goto fail;
 	}
 	vadc->vadc_hwmon = hwmon_device_register(&vadc->adc->spmi->dev);
 	vadc->vadc_init_calib = false;
 	vadc->max_channels_available = count_adc_channel_list;
 	vadc->vadc_initialized = true;
+	vadc->vadc_iadc_sync_lock = false;
 
 	return 0;
+fail:
+	qpnp_vadc = NULL;
+	return rc;
 }
 
 static int __devexit qpnp_vadc_remove(struct spmi_device *spmi)
diff --git a/drivers/i2c/busses/i2c-msm.c b/drivers/i2c/busses/i2c-msm.c
index 4b48a69..bceec78 100644
--- a/drivers/i2c/busses/i2c-msm.c
+++ b/drivers/i2c/busses/i2c-msm.c
@@ -1,7 +1,7 @@
 /* drivers/i2c/busses/i2c-msm.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index 92d162b..ca0a439 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -128,6 +128,9 @@
 };
 
 #define QUP_MAX_CLK_STATE_RETRIES	300
+#define DEFAULT_CLK_RATE		(19200000)
+#define I2C_STATUS_CLK_STATE		13
+#define QUP_OUT_FIFO_NOT_EMPTY		0x10
 
 static char const * const i2c_rsrcs[] = {"i2c_clk", "i2c_sda"};
 
@@ -163,7 +166,7 @@
 	int                          wr_sz;
 	struct msm_i2c_platform_data *pdata;
 	int                          suspended;
-	int                          clk_state;
+	int                          pwr_state;
 	struct mutex                 mlock;
 	void                         *complete;
 	int                          i2c_gpios[ARRAY_SIZE(i2c_rsrcs)];
@@ -191,14 +194,18 @@
 qup_i2c_interrupt(int irq, void *devid)
 {
 	struct qup_i2c_dev *dev = devid;
-	uint32_t status = readl_relaxed(dev->base + QUP_I2C_STATUS);
-	uint32_t status1 = readl_relaxed(dev->base + QUP_ERROR_FLAGS);
-	uint32_t op_flgs = readl_relaxed(dev->base + QUP_OPERATIONAL);
+	uint32_t status = 0;
+	uint32_t status1 = 0;
+	uint32_t op_flgs = 0;
 	int err = 0;
 
 	if (pm_runtime_suspended(dev->dev))
 		return IRQ_NONE;
 
+	status = readl_relaxed(dev->base + QUP_I2C_STATUS);
+	status1 = readl_relaxed(dev->base + QUP_ERROR_FLAGS);
+	op_flgs = readl_relaxed(dev->base + QUP_OPERATIONAL);
+
 	if (!dev->msg || !dev->complete) {
 		/* Clear Error interrupt if it's a level triggered interrupt*/
 		if (dev->num_irqs == 1) {
@@ -327,7 +334,7 @@
 static void
 qup_i2c_pwr_mgmt(struct qup_i2c_dev *dev, unsigned int state)
 {
-	dev->clk_state = state;
+	dev->pwr_state = state;
 	if (state != 0) {
 		clk_prepare_enable(dev->clk);
 		if (!dev->pdata->keep_ahb_clk_on)
@@ -375,6 +382,7 @@
 static int qup_i2c_poll_clock_ready(struct qup_i2c_dev *dev)
 {
 	uint32_t retries = 0;
+	uint32_t op_flgs = -1, clk_state = -1;
 
 	/*
 	 * Wait for the clock state to transition to either IDLE or FORCED
@@ -383,16 +391,32 @@
 
 	while (retries++ < QUP_MAX_CLK_STATE_RETRIES) {
 		uint32_t status = readl_relaxed(dev->base + QUP_I2C_STATUS);
-		uint32_t clk_state = (status >> 13) & 0x7;
+		clk_state = (status >> I2C_STATUS_CLK_STATE) & 0x7;
+		/* Read the operational register */
+		op_flgs = readl_relaxed(dev->base +
+			QUP_OPERATIONAL) & QUP_OUT_FIFO_NOT_EMPTY;
 
-		if (clk_state == I2C_CLK_RESET_BUSIDLE_STATE ||
-				clk_state == I2C_CLK_FORCED_LOW_STATE)
+		/*
+		 * In very corner case when slave do clock stretching and
+		 * output fifo will have 1 block of data space empty at
+		 * the same time.  So i2c qup will get output service
+		 * interrupt and as it doesn't have more data to be written.
+		 * This can lead to issue where output fifo is not empty.
+		*/
+		if (op_flgs == 0 &&
+			(clk_state == I2C_CLK_RESET_BUSIDLE_STATE ||
+			clk_state == I2C_CLK_FORCED_LOW_STATE)){
+			dev_dbg(dev->dev, "clk_state 0x%x op_flgs [%x]\n",
+				clk_state, op_flgs);
 			return 0;
+		}
+
 		/* 1-bit delay before we check again */
 		udelay(dev->one_bit_t);
 	}
 
-	dev_err(dev->dev, "Error waiting for clk ready\n");
+	dev_err(dev->dev, "Error waiting for clk ready clk_state: 0x%x op_flgs: 0x%x\n",
+		clk_state, op_flgs);
 	return -ETIMEDOUT;
 }
 
@@ -670,7 +694,7 @@
 	int gpio_dat;
 	bool gpio_clk_status = false;
 	uint32_t status = readl_relaxed(dev->base + QUP_I2C_STATUS);
-	struct gpiomux_setting old_gpio_setting;
+	struct gpiomux_setting old_gpio_setting[ARRAY_SIZE(i2c_rsrcs)];
 
 	if (dev->pdata->msm_i2c_config_gpio)
 		return;
@@ -690,7 +714,7 @@
 	disable_irq(dev->err_irq);
 	for (i = 0; i < ARRAY_SIZE(i2c_rsrcs); ++i) {
 		if (msm_gpiomux_write(dev->i2c_gpios[i], GPIOMUX_ACTIVE,
-				&recovery_config, &old_gpio_setting)) {
+				&recovery_config, &old_gpio_setting[i])) {
 			dev_err(dev->dev, "GPIO pins have no active setting\n");
 			goto recovery_end;
 		}
@@ -720,7 +744,7 @@
 	/* Configure ALT funciton to QUP I2C*/
 	for (i = 0; i < ARRAY_SIZE(i2c_rsrcs); ++i) {
 		msm_gpiomux_write(dev->i2c_gpios[i], GPIOMUX_ACTIVE,
-				&old_gpio_setting, NULL);
+				&old_gpio_setting[i], NULL);
 	}
 
 	udelay(10);
@@ -1228,10 +1252,6 @@
 		dev->i2c_gpios[i] = res ? res->start : -1;
 	}
 
-	ret = qup_i2c_request_gpios(dev);
-	if (ret)
-		goto err_request_gpio_failed;
-
 	platform_set_drvdata(pdev, dev);
 
 	dev->one_bit_t = (USEC_PER_SEC/pdata->clk_freq) + 1;
@@ -1239,18 +1259,26 @@
 	dev->clk_ctl = 0;
 	dev->pos = 0;
 
+	if (dev->pdata->src_clk_rate <= 0) {
+		dev_info(&pdev->dev,
+			"No src_clk_rate specified in platfrom data or "
+						"qcom,i2c-src-freq in DT\n");
+		dev_info(&pdev->dev, "Using default clock rate %dHz\n",
+							DEFAULT_CLK_RATE);
+		dev->pdata->src_clk_rate = DEFAULT_CLK_RATE;
+	}
+
+	ret = clk_set_rate(dev->clk, dev->pdata->src_clk_rate);
+	if (ret)
+		dev_info(&pdev->dev, "clk_set_rate(core_clk, %dHz):%d\n",
+					dev->pdata->src_clk_rate, ret);
+
+	clk_prepare_enable(dev->clk);
+	clk_prepare_enable(dev->pclk);
 	/*
 	 * If bootloaders leave a pending interrupt on certain GSBI's,
 	 * then we reset the core before registering for interrupts.
 	 */
-
-	if (dev->pdata->src_clk_rate > 0)
-		clk_set_rate(dev->clk, dev->pdata->src_clk_rate);
-	else
-		dev->pdata->src_clk_rate = 19200000;
-
-	clk_prepare_enable(dev->clk);
-	clk_prepare_enable(dev->pclk);
 	writel_relaxed(1, dev->base + QUP_SW_RESET);
 	if (qup_i2c_poll_state(dev, 0, true) != 0)
 		goto err_reset_failed;
@@ -1309,11 +1337,12 @@
 		"QUP I2C adapter",
 		sizeof(dev->adapter.name));
 	dev->adapter.nr = pdev->id;
+	dev->adapter.dev.parent = &pdev->dev;
 	if (pdata->msm_i2c_config_gpio)
 		pdata->msm_i2c_config_gpio(dev->adapter.nr, 1);
 
 	mutex_init(&dev->mlock);
-	dev->clk_state = 0;
+	dev->pwr_state = 0;
 	/* If the same AHB clock is used on Modem side
 	 * switch it on here itself and don't switch it
 	 * on and off during suspend and resume.
@@ -1343,13 +1372,11 @@
 
 
 err_request_irq_failed:
-	qup_i2c_free_gpios(dev);
 	if (dev->gsbi)
 		iounmap(dev->gsbi);
 err_reset_failed:
 	clk_disable_unprepare(dev->clk);
 	clk_disable_unprepare(dev->pclk);
-err_request_gpio_failed:
 err_gsbi_failed:
 	iounmap(dev->base);
 err_ioremap_failed:
@@ -1380,8 +1407,10 @@
 	dev->suspended = 1;
 	mutex_unlock(&dev->mlock);
 	mutex_destroy(&dev->mlock);
-	if (dev->clk_state != 0)
+	if (dev->pwr_state != 0) {
 		qup_i2c_pwr_mgmt(dev, 0);
+		qup_i2c_free_gpios(dev);
+	}
 	platform_set_drvdata(pdev, NULL);
 	if (dev->num_irqs == 3) {
 		free_irq(dev->out_irq, dev);
@@ -1393,7 +1422,6 @@
 		clk_put(dev->pclk);
 	}
 	clk_put(dev->clk);
-	qup_i2c_free_gpios(dev);
 	if (dev->gsbi)
 		iounmap(dev->gsbi);
 	iounmap(dev->base);
@@ -1425,9 +1453,10 @@
 	mutex_lock(&dev->mlock);
 	dev->suspended = 1;
 	mutex_unlock(&dev->mlock);
-	if (dev->clk_state != 0)
+	if (dev->pwr_state != 0) {
 		qup_i2c_pwr_mgmt(dev, 0);
-	qup_i2c_free_gpios(dev);
+		qup_i2c_free_gpios(dev);
+	}
 	return 0;
 }
 
@@ -1435,10 +1464,14 @@
 {
 	struct platform_device *pdev = to_platform_device(device);
 	struct qup_i2c_dev *dev = platform_get_drvdata(pdev);
+	int ret = 0;
 	dev_dbg(device, "pm_runtime: resuming...\n");
-	BUG_ON(qup_i2c_request_gpios(dev) != 0);
-	if (dev->clk_state == 0)
+	if (dev->pwr_state == 0) {
+		ret = qup_i2c_request_gpios(dev);
+		if (ret != 0)
+			return ret;
 		qup_i2c_pwr_mgmt(dev, 1);
+	}
 	dev->suspended = 0;
 	return 0;
 }
@@ -1454,11 +1487,15 @@
 
 static int qup_i2c_resume(struct device *device)
 {
+	int ret = 0;
 	if (!pm_runtime_enabled(device) || !pm_runtime_suspended(device)) {
 		dev_dbg(device, "system resume");
-		i2c_qup_pm_resume_runtime(device);
-		pm_runtime_mark_last_busy(device);
-		pm_request_autosuspend(device);
+		ret = i2c_qup_pm_resume_runtime(device);
+		if (!ret) {
+			pm_runtime_mark_last_busy(device);
+			pm_request_autosuspend(device);
+		}
+		return ret;
 	}
 	return 0;
 }
diff --git a/drivers/i2c/busses/i2c-ssbi.c b/drivers/i2c/busses/i2c-ssbi.c
index c803402..3022a802 100644
--- a/drivers/i2c/busses/i2c-ssbi.c
+++ b/drivers/i2c/busses/i2c-ssbi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/drivers/input/joystick/tdisc_vtd518_shinetsu.c b/drivers/input/joystick/tdisc_vtd518_shinetsu.c
index efbe974..5faaf72 100644
--- a/drivers/input/joystick/tdisc_vtd518_shinetsu.c
+++ b/drivers/input/joystick/tdisc_vtd518_shinetsu.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index badbc2b..4c72b65 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -447,6 +447,17 @@
 	  To compile this driver as a module, choose M here: the module will
 	  be called pmic8xxx-keypad.
 
+config KEYBOARD_QPNP
+	tristate "Qualcomm QPNP PMIC keypad support"
+	depends on OF_SPMI && SPMI && MSM_QPNP_INT
+	help
+	  Say Y here if you want to enable the driver for the QPNP PMIC
+	  keypad provided as a reference design from Qualcomm. This is intended
+	  to support upto 10 x 8 matrix based keypad design.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called qpnp-keypad.
+
 config KEYBOARD_SAMSUNG
 	tristate "Samsung keypad support"
 	depends on HAVE_CLK
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 61b57ef..833904a 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -36,6 +36,7 @@
 obj-$(CONFIG_KEYBOARD_OMAP4)		+= omap4-keypad.o
 obj-$(CONFIG_KEYBOARD_OPENCORES)	+= opencores-kbd.o
 obj-$(CONFIG_KEYBOARD_PMIC8XXX)		+= pmic8xxx-keypad.o
+obj-$(CONFIG_KEYBOARD_QPNP)		+= qpnp-keypad.o
 obj-$(CONFIG_KEYBOARD_PXA27x)		+= pxa27x_keypad.o
 obj-$(CONFIG_KEYBOARD_PXA930_ROTARY)	+= pxa930_rotary.o
 obj-$(CONFIG_KEYBOARD_QT1070)           += qt1070.o
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index dd05cca..f7b5558 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -2,7 +2,7 @@
  *  GPIO driven matrix keyboard driver
  *
  *  Copyright (c) 2008 Marek Vasut <marek.vasut@gmail.com>
- *  Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  *  Based on corgikbd.c
  *
diff --git a/drivers/input/keyboard/pmic8xxx-keypad.c b/drivers/input/keyboard/pmic8xxx-keypad.c
index d529ea4..26e26e2 100644
--- a/drivers/input/keyboard/pmic8xxx-keypad.c
+++ b/drivers/input/keyboard/pmic8xxx-keypad.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/drivers/input/keyboard/qci_kbd.c b/drivers/input/keyboard/qci_kbd.c
index d735012..d43e81c 100644
--- a/drivers/input/keyboard/qci_kbd.c
+++ b/drivers/input/keyboard/qci_kbd.c
@@ -1,7 +1,7 @@
 /* Quanta I2C Keyboard Driver
  *
  * Copyright (C) 2009 Quanta Computer Inc.
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, The Linux Foundation. All rights reserved.
  * Author: Hsin Wu <hsin.wu@quantatw.com>
  * Author: Austin Lai <austin.lai@quantatw.com>
  *
diff --git a/drivers/input/keyboard/qpnp-keypad.c b/drivers/input/keyboard/qpnp-keypad.c
new file mode 100644
index 0000000..a46e3b5
--- /dev/null
+++ b/drivers/input/keyboard/qpnp-keypad.c
@@ -0,0 +1,852 @@
+/* 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/interrupt.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/spmi.h>
+
+#define QPNP_MAX_ROWS			10
+#define QPNP_MAX_COLS			8
+#define QPNP_MIN_ROWS			2
+#define QPNP_MIN_COLS			1
+#define QPNP_ROW_SHIFT			3
+#define QPNP_MATRIX_MAX_SIZE		(QPNP_MAX_ROWS * QPNP_MAX_COLS)
+
+/* in ms */
+#define MAX_SCAN_DELAY			128
+#define MIN_SCAN_DELAY			1
+#define KEYP_DEFAULT_SCAN_DELAY		32
+
+/* in ns */
+#define MAX_ROW_HOLD_DELAY		250000
+#define MIN_ROW_HOLD_DELAY		31250
+
+/* in ms */
+#define MAX_DEBOUNCE_TIME		20
+#define MIN_DEBOUNCE_TIME		5
+#define KEYP_DEFAULT_DEBOUNCE		15
+
+/* register offsets */
+#define KEYP_STATUS(base)		(base + 0x08)
+#define KEYP_SIZE_CTRL(base)		(base + 0x40)
+#define KEYP_SCAN_CTRL(base)		(base + 0x42)
+#define KEYP_FSM_CNTL(base)		(base + 0x44)
+#define KEYP_EN_CTRL(base)		(base + 0x46)
+
+#define KEYP_CTRL_KEYP_EN		BIT(7)
+#define KEYP_CTRL_EVNTS			BIT(0)
+#define KEYP_CTRL_EVNTS_MASK		0x3
+
+#define KEYP_SIZE_COLS_SHIFT		4
+#define KEYP_SIZE_COLS_MASK		0x70
+#define KEYP_SIZE_ROWS_MASK		0x0F
+
+#define KEYP_SCAN_DBC_MASK		0x03
+#define KEYP_SCAN_SCNP_MASK		0x38
+#define KEYP_SCAN_ROWP_MASK		0xC0
+#define KEYP_SCAN_SCNP_SHIFT		3
+#define KEYP_SCAN_ROWP_SHIFT		6
+
+#define KEYP_CTRL_SCAN_ROWS_BITS	0x7
+
+#define KEYP_SCAN_DBOUNCE_SHIFT		1
+#define KEYP_SCAN_PAUSE_SHIFT		3
+#define KEYP_SCAN_ROW_HOLD_SHIFT	6
+
+#define KEYP_FSM_READ_EN		BIT(0)
+
+/* bits of these registers represent
+ * '0' for key press
+ * '1' for key release
+ */
+#define KEYP_RECENT_DATA(base)		(base + 0x7C)
+#define KEYP_OLD_DATA(base)		(base + 0x5C)
+
+#define KEYP_CLOCK_FREQ			32768
+
+struct qpnp_kp {
+	const struct matrix_keymap_data *keymap_data;
+	struct input_dev *input;
+	struct spmi_device *spmi;
+
+	int key_sense_irq;
+	int key_stuck_irq;
+	u16 base;
+
+	u32 num_rows;
+	u32 num_cols;
+	u32 debounce_ms;
+	u32 row_hold_ns;
+	u32 scan_delay_ms;
+	bool wakeup;
+	bool rep;
+
+	unsigned short keycodes[QPNP_MATRIX_MAX_SIZE];
+
+	u16 keystate[QPNP_MAX_ROWS];
+	u16 stuckstate[QPNP_MAX_ROWS];
+};
+
+static int qpnp_kp_write_u8(struct qpnp_kp *kp, u8 data, u16 reg)
+{
+	int rc;
+
+	rc = spmi_ext_register_writel(kp->spmi->ctrl, kp->spmi->sid,
+							reg, &data, 1);
+	if (rc < 0)
+		dev_err(&kp->spmi->dev,
+			"Error writing to address: %X - ret %d\n", reg, rc);
+
+	return rc;
+}
+
+static int qpnp_kp_read(struct qpnp_kp *kp,
+				u8 *data, u16 reg, unsigned num_bytes)
+{
+	int rc;
+
+	rc = spmi_ext_register_readl(kp->spmi->ctrl, kp->spmi->sid,
+						reg, data, num_bytes);
+	if (rc < 0)
+		dev_err(&kp->spmi->dev,
+			"Error reading from address : %X - ret %d\n", reg, rc);
+
+	return rc;
+}
+
+static int qpnp_kp_read_u8(struct qpnp_kp *kp, u8 *data, u16 reg)
+{
+	int rc;
+
+	rc = qpnp_kp_read(kp, data, reg, 1);
+	if (rc < 0)
+		dev_err(&kp->spmi->dev, "Error reading qpnp: %X - ret %d\n",
+				reg, rc);
+	return rc;
+}
+
+static u8 qpnp_col_state(struct qpnp_kp *kp, u8 col)
+{
+	/* all keys pressed on that particular row? */
+	if (col == 0x00)
+		return 1 << kp->num_cols;
+	else
+		return col & ((1 << kp->num_cols) - 1);
+}
+
+/*
+ * Synchronous read protocol
+ *
+ * 1. Write '1' to ReadState bit in KEYP_FSM_CNTL register
+ * 2. Wait 2*32KHz clocks, so that HW can successfully enter read mode
+ *    synchronously
+ * 3. Read rows in old array first if events are more than one
+ * 4. Read rows in recent array
+ * 5. Wait 4*32KHz clocks
+ * 6. Write '0' to ReadState bit of KEYP_FSM_CNTL register so that hw can
+ *    synchronously exit read mode.
+ */
+static int qpnp_sync_read(struct qpnp_kp *kp, bool enable)
+{
+	int rc;
+	u8 fsm_ctl;
+
+	rc = qpnp_kp_read_u8(kp, &fsm_ctl, KEYP_FSM_CNTL(kp->base));
+	if (rc < 0) {
+		dev_err(&kp->spmi->dev,
+				"Error reading KEYP_FSM_CNTL reg, rc=%d\n", rc);
+		return rc;
+	}
+
+	if (enable)
+		fsm_ctl |= KEYP_FSM_READ_EN;
+	else
+		fsm_ctl &= ~KEYP_FSM_READ_EN;
+
+	rc = qpnp_kp_write_u8(kp, fsm_ctl, KEYP_FSM_CNTL(kp->base));
+	if (rc < 0) {
+		dev_err(&kp->spmi->dev,
+				"Error writing KEYP_FSM_CNTL reg, rc=%d\n", rc);
+		return rc;
+	}
+
+	/* 2 * 32KHz clocks */
+	udelay((2 * DIV_ROUND_UP(USEC_PER_SEC, KEYP_CLOCK_FREQ)) + 1);
+
+	return rc;
+}
+
+static int qpnp_kp_read_data(struct qpnp_kp *kp, u16 *state,
+					u16 data_reg, int read_rows)
+{
+	int rc, row;
+	u8 new_data[QPNP_MAX_ROWS];
+
+	/*
+	 * Check if last row will be scanned. If not, scan to clear key event
+	 * counter
+	 */
+	if (kp->num_rows < QPNP_MAX_ROWS) {
+		rc = qpnp_kp_read_u8(kp, &new_data[QPNP_MAX_ROWS - 1],
+					data_reg + (QPNP_MAX_ROWS - 1) * 2);
+		if (rc)
+			return rc;
+	}
+
+	for (row = 0; row < kp->num_rows; row++) {
+		rc = qpnp_kp_read_u8(kp, &new_data[row], data_reg + row * 2);
+		if (rc)
+			return rc;
+
+		dev_dbg(&kp->spmi->dev, "new_data[%d] = %d\n", row,
+					new_data[row]);
+		state[row] = qpnp_col_state(kp, new_data[row]);
+	}
+
+	return 0;
+}
+
+static int qpnp_kp_read_matrix(struct qpnp_kp *kp, u16 *new_state,
+					 u16 *old_state)
+{
+	int rc, read_rows;
+
+	read_rows = kp->num_rows;
+
+	rc = qpnp_sync_read(kp, true);
+	if (rc < 0) {
+		dev_err(&kp->spmi->dev,
+			"Error setting the FSM read enable bit rc=%d\n", rc);
+		return rc;
+	}
+
+	if (old_state) {
+		rc = qpnp_kp_read_data(kp, old_state, KEYP_OLD_DATA(kp->base),
+							read_rows);
+		if (rc < 0) {
+			dev_err(&kp->spmi->dev,
+				"Error reading KEYP_OLD_DATA, rc=%d\n", rc);
+			return rc;
+		}
+	}
+
+	rc = qpnp_kp_read_data(kp, new_state, KEYP_RECENT_DATA(kp->base),
+						 read_rows);
+	if (rc < 0) {
+		dev_err(&kp->spmi->dev,
+			"Error reading KEYP_RECENT_DATA, rc=%d\n", rc);
+		return rc;
+	}
+
+	/* 4 * 32KHz clocks */
+	udelay((4 * DIV_ROUND_UP(USEC_PER_SEC, KEYP_CLOCK_FREQ)) + 1);
+
+	rc = qpnp_sync_read(kp, false);
+	if (rc < 0) {
+		dev_err(&kp->spmi->dev,
+			"Error resetting the FSM read enable bit rc=%d\n", rc);
+		return rc;
+	}
+
+	return rc;
+}
+
+static void __qpnp_kp_scan_matrix(struct qpnp_kp *kp, u16 *new_state,
+					 u16 *old_state)
+{
+	int row, col, code;
+
+	for (row = 0; row < kp->num_rows; row++) {
+		int bits_changed = new_state[row] ^ old_state[row];
+
+		if (!bits_changed)
+			continue;
+
+		for (col = 0; col < kp->num_cols; col++) {
+			if (!(bits_changed & (1 << col)))
+				continue;
+
+			dev_dbg(&kp->spmi->dev, "key [%d:%d] %s\n", row, col,
+					!(new_state[row] & (1 << col)) ?
+					"pressed" : "released");
+			code = MATRIX_SCAN_CODE(row, col, QPNP_ROW_SHIFT);
+			input_event(kp->input, EV_MSC, MSC_SCAN, code);
+			input_report_key(kp->input,
+					kp->keycodes[code],
+					!(new_state[row] & (1 << col)));
+			input_sync(kp->input);
+		}
+	}
+}
+
+static bool qpnp_detect_ghost_keys(struct qpnp_kp *kp, u16 *new_state)
+{
+	int row, found_first = -1;
+	u16 check, row_state;
+
+	check = 0;
+	for (row = 0; row < kp->num_rows; row++) {
+		row_state = (~new_state[row]) &
+				 ((1 << kp->num_cols) - 1);
+
+		if (hweight16(row_state) > 1) {
+			if (found_first == -1)
+				found_first = row;
+			if (check & row_state) {
+				dev_dbg(&kp->spmi->dev,
+					"detected ghost key row[%d],row[%d]\n",
+					found_first, row);
+				return true;
+			}
+		}
+		check |= row_state;
+	}
+	return false;
+}
+
+static int qpnp_kp_scan_matrix(struct qpnp_kp *kp, unsigned int events)
+{
+	u16 new_state[QPNP_MAX_ROWS];
+	u16 old_state[QPNP_MAX_ROWS];
+	int rc;
+	switch (events) {
+	case 0x1:
+		rc = qpnp_kp_read_matrix(kp, new_state, NULL);
+		if (rc < 0)
+			return rc;
+
+		/* detecting ghost key is not an error */
+		if (qpnp_detect_ghost_keys(kp, new_state))
+			return 0;
+		__qpnp_kp_scan_matrix(kp, new_state, kp->keystate);
+		memcpy(kp->keystate, new_state, sizeof(new_state));
+	break;
+	case 0x3: /* two events - eventcounter is gray-coded */
+		rc = qpnp_kp_read_matrix(kp, new_state, old_state);
+		if (rc < 0)
+			return rc;
+
+		__qpnp_kp_scan_matrix(kp, old_state, kp->keystate);
+		__qpnp_kp_scan_matrix(kp, new_state, old_state);
+		memcpy(kp->keystate, new_state, sizeof(new_state));
+	break;
+	case 0x2:
+		dev_dbg(&kp->spmi->dev, "Some key events were lost\n");
+		rc = qpnp_kp_read_matrix(kp, new_state, old_state);
+		if (rc < 0)
+			return rc;
+		__qpnp_kp_scan_matrix(kp, old_state, kp->keystate);
+		__qpnp_kp_scan_matrix(kp, new_state, old_state);
+		memcpy(kp->keystate, new_state, sizeof(new_state));
+	break;
+	default:
+		rc = -EINVAL;
+	}
+	return rc;
+}
+
+/*
+ * NOTE: We are reading recent and old data registers blindly
+ * whenever key-stuck interrupt happens, because events counter doesn't
+ * get updated when this interrupt happens due to key stuck doesn't get
+ * considered as key state change.
+ *
+ * We are not using old data register contents after they are being read
+ * because it might report the key which was pressed before the key being stuck
+ * as stuck key because it's pressed status is stored in the old data
+ * register.
+ */
+static irqreturn_t qpnp_kp_stuck_irq(int irq, void *data)
+{
+	u16 new_state[QPNP_MAX_ROWS];
+	u16 old_state[QPNP_MAX_ROWS];
+	int rc;
+	struct qpnp_kp *kp = data;
+
+	rc = qpnp_kp_read_matrix(kp, new_state, old_state);
+	if (rc < 0) {
+		dev_err(&kp->spmi->dev, "failed to read keypad matrix\n");
+		return IRQ_HANDLED;
+	}
+
+	__qpnp_kp_scan_matrix(kp, new_state, kp->stuckstate);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t qpnp_kp_irq(int irq, void *data)
+{
+	struct qpnp_kp *kp = data;
+	u8 ctrl_val, events;
+	int rc;
+
+	rc = qpnp_kp_read_u8(kp, &ctrl_val, KEYP_STATUS(kp->base));
+	if (rc < 0) {
+		dev_err(&kp->spmi->dev,
+			"Error reading KEYP_STATUS register\n");
+		return IRQ_HANDLED;
+	}
+
+	events = ctrl_val & KEYP_CTRL_EVNTS_MASK;
+
+	rc = qpnp_kp_scan_matrix(kp, events);
+	if (rc < 0)
+		dev_err(&kp->spmi->dev, "failed to scan matrix\n");
+
+	return IRQ_HANDLED;
+}
+
+static int __devinit qpnp_kpd_init(struct qpnp_kp *kp)
+{
+	int bits, rc, cycles;
+	u8 kpd_scan_cntl, kpd_size_cntl;
+
+	/* Configure the SIZE register, #rows and #columns */
+	rc = qpnp_kp_read_u8(kp, &kpd_size_cntl, KEYP_SIZE_CTRL(kp->base));
+	if (rc < 0) {
+		dev_err(&kp->spmi->dev,
+			"Error reading KEYP_SIZE_CTRL reg, rc=%d\n", rc);
+		return rc;
+	}
+
+	kpd_size_cntl &= (~KEYP_SIZE_COLS_MASK | ~KEYP_SIZE_ROWS_MASK);
+	kpd_size_cntl |= (((kp->num_cols - 1) << KEYP_SIZE_COLS_SHIFT) &
+							KEYP_SIZE_COLS_MASK);
+	kpd_size_cntl |= ((kp->num_rows - 1) & KEYP_SIZE_ROWS_MASK);
+
+	rc = qpnp_kp_write_u8(kp, kpd_size_cntl, KEYP_SIZE_CTRL(kp->base));
+	if (rc < 0) {
+		dev_err(&kp->spmi->dev,
+			"Error writing to KEYP_SIZE_CTRL reg, rc=%d\n", rc);
+		return rc;
+	}
+
+	/* Configure the SCAN CTL register, debounce, row pause, scan delay */
+	rc = qpnp_kp_read_u8(kp, &kpd_scan_cntl, KEYP_SCAN_CTRL(kp->base));
+	if (rc < 0) {
+		dev_err(&kp->spmi->dev,
+			"Error reading KEYP_SCAN_CTRL reg, rc=%d\n", rc);
+		return rc;
+	}
+
+	kpd_scan_cntl &= (~KEYP_SCAN_DBC_MASK | ~KEYP_SCAN_SCNP_MASK |
+						~KEYP_SCAN_ROWP_MASK);
+	kpd_scan_cntl |= (((kp->debounce_ms / 5) - 1) & KEYP_SCAN_DBC_MASK);
+
+	bits = fls(kp->scan_delay_ms) - 1;
+	kpd_scan_cntl |= ((bits << KEYP_SCAN_SCNP_SHIFT) & KEYP_SCAN_SCNP_MASK);
+
+	/* Row hold time is a multiple of 32KHz cycles. */
+	cycles = (kp->row_hold_ns * KEYP_CLOCK_FREQ) / NSEC_PER_SEC;
+	if (cycles)
+		cycles = ilog2(cycles);
+	kpd_scan_cntl |= ((cycles << KEYP_SCAN_ROW_HOLD_SHIFT) &
+							KEYP_SCAN_ROWP_MASK);
+
+	rc = qpnp_kp_write_u8(kp, kpd_scan_cntl, KEYP_SCAN_CTRL(kp->base));
+	if (rc)
+		dev_err(&kp->spmi->dev,
+			"Error writing KEYP_SCAN reg, rc=%d\n", rc);
+
+	return rc;
+}
+
+static int qpnp_kp_enable(struct qpnp_kp *kp)
+{
+	int rc;
+	u8 kpd_cntl;
+
+	rc = qpnp_kp_read_u8(kp, &kpd_cntl, KEYP_EN_CTRL(kp->base));
+	if (rc < 0) {
+		dev_err(&kp->spmi->dev,
+			"Error reading KEYP_EN_CTRL reg, rc=%d\n", rc);
+		return rc;
+	}
+
+	kpd_cntl |= KEYP_CTRL_KEYP_EN;
+
+	rc = qpnp_kp_write_u8(kp, kpd_cntl, KEYP_EN_CTRL(kp->base));
+	if (rc < 0)
+		dev_err(&kp->spmi->dev,
+			"Error writing KEYP_CTRL reg, rc=%d\n", rc);
+
+	return rc;
+}
+
+static int qpnp_kp_disable(struct qpnp_kp *kp)
+{
+	int rc;
+	u8 kpd_cntl;
+
+	rc = qpnp_kp_read_u8(kp, &kpd_cntl, KEYP_EN_CTRL(kp->base));
+	if (rc < 0) {
+		dev_err(&kp->spmi->dev,
+			"Error reading KEYP_EN_CTRL reg, rc=%d\n", rc);
+		return rc;
+	}
+
+	kpd_cntl &= ~KEYP_CTRL_KEYP_EN;
+
+	rc = qpnp_kp_write_u8(kp, kpd_cntl, KEYP_EN_CTRL(kp->base));
+	if (rc < 0)
+		dev_err(&kp->spmi->dev,
+			"Error writing KEYP_CTRL reg, rc=%d\n", rc);
+
+	return rc;
+}
+
+static int qpnp_kp_open(struct input_dev *dev)
+{
+	struct qpnp_kp *kp = input_get_drvdata(dev);
+
+	return qpnp_kp_enable(kp);
+}
+
+static void qpnp_kp_close(struct input_dev *dev)
+{
+	struct qpnp_kp *kp = input_get_drvdata(dev);
+
+	qpnp_kp_disable(kp);
+}
+
+static int __devinit qpnp_keypad_parse_dt(struct qpnp_kp *kp)
+{
+	struct matrix_keymap_data *keymap_data;
+	int rc, keymap_len, i;
+	u32 *keymap;
+	const __be32 *map;
+
+	rc = of_property_read_u32(kp->spmi->dev.of_node,
+				"keypad,num-rows", &kp->num_rows);
+	if (rc) {
+		dev_err(&kp->spmi->dev, "Unable to parse 'num-rows'\n");
+		return rc;
+	}
+
+	rc = of_property_read_u32(kp->spmi->dev.of_node,
+				"keypad,num-cols", &kp->num_cols);
+	if (rc) {
+		dev_err(&kp->spmi->dev, "Unable to parse 'num-cols'\n");
+		return rc;
+	}
+
+	rc = of_property_read_u32(kp->spmi->dev.of_node,
+				"qcom,scan-delay-ms", &kp->scan_delay_ms);
+	if (rc && rc != -EINVAL) {
+		dev_err(&kp->spmi->dev, "Unable to parse 'scan-delay-ms'\n");
+		return rc;
+	}
+
+	rc = of_property_read_u32(kp->spmi->dev.of_node,
+				"qcom,row-hold-ns", &kp->row_hold_ns);
+	if (rc && rc != -EINVAL) {
+		dev_err(&kp->spmi->dev, "Unable to parse 'row-hold-ns'\n");
+		return rc;
+	}
+
+	rc = of_property_read_u32(kp->spmi->dev.of_node,
+					"qcom,debounce-ms", &kp->debounce_ms);
+	if (rc && rc != -EINVAL) {
+		dev_err(&kp->spmi->dev, "Unable to parse 'debounce-ms'\n");
+		return rc;
+	}
+
+	kp->wakeup = of_property_read_bool(kp->spmi->dev.of_node,
+							"qcom,wakeup");
+
+	kp->rep = !of_property_read_bool(kp->spmi->dev.of_node,
+					"linux,keypad-no-autorepeat");
+
+	map = of_get_property(kp->spmi->dev.of_node,
+					"linux,keymap", &keymap_len);
+	if (!map) {
+		dev_err(&kp->spmi->dev, "Keymap not specified\n");
+		return -EINVAL;
+	}
+
+	keymap_data = devm_kzalloc(&kp->spmi->dev,
+					sizeof(*keymap_data), GFP_KERNEL);
+	if (!keymap_data) {
+		dev_err(&kp->spmi->dev, "Unable to allocate memory\n");
+		return -ENOMEM;
+	}
+
+	keymap_data->keymap_size = keymap_len / sizeof(u32);
+
+	keymap = devm_kzalloc(&kp->spmi->dev,
+		sizeof(uint32_t) * keymap_data->keymap_size, GFP_KERNEL);
+	if (!keymap) {
+		dev_err(&kp->spmi->dev, "could not allocate memory for keymap\n");
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < keymap_data->keymap_size; i++) {
+		unsigned int key = be32_to_cpup(map + i);
+		int keycode, row, col;
+
+		row = (key >> 24) & 0xff;
+		col = (key >> 16) & 0xff;
+		keycode = key & 0xffff;
+		keymap[i] = KEY(row, col, keycode);
+	}
+	keymap_data->keymap = keymap;
+	kp->keymap_data = keymap_data;
+
+	return 0;
+}
+
+static int __devinit qpnp_kp_probe(struct spmi_device *spmi)
+{
+	struct qpnp_kp *kp;
+	struct resource *keypad_base;
+	int rc = 0;
+
+	kp = devm_kzalloc(&spmi->dev, sizeof(struct qpnp_kp), GFP_KERNEL);
+	if (!kp) {
+		dev_err(&spmi->dev, "%s: Can't allocate qpnp_kp\n",
+			__func__);
+		return -ENOMEM;
+	}
+
+	kp->spmi = spmi;
+
+	rc = qpnp_keypad_parse_dt(kp);
+	if (rc < 0) {
+		dev_err(&spmi->dev, "Error parsing device tree\n");
+		return rc;
+	}
+
+	/* the #rows and #columns are compulsary */
+	if (!kp->num_cols || !kp->num_rows ||
+		kp->num_cols > QPNP_MAX_COLS ||
+		kp->num_rows > QPNP_MAX_ROWS ||
+		kp->num_cols < QPNP_MIN_COLS ||
+		kp->num_rows < QPNP_MIN_ROWS) {
+		dev_err(&spmi->dev, "invalid rows/cols input data\n");
+		return -EINVAL;
+	}
+
+	if (!kp->keymap_data) {
+		dev_err(&spmi->dev, "keymap not specified\n");
+		return -EINVAL;
+	}
+
+	/* the below parameters are optional*/
+	if (!kp->scan_delay_ms) {
+		kp->scan_delay_ms = KEYP_DEFAULT_SCAN_DELAY;
+	} else {
+		if (kp->scan_delay_ms > MAX_SCAN_DELAY ||
+			kp->scan_delay_ms < MIN_SCAN_DELAY) {
+			dev_err(&spmi->dev,
+				"invalid keypad scan time supplied\n");
+			return -EINVAL;
+		}
+	}
+
+	if (!kp->row_hold_ns) {
+		kp->row_hold_ns = MIN_ROW_HOLD_DELAY;
+	} else {
+		if (kp->row_hold_ns > MAX_ROW_HOLD_DELAY ||
+			kp->row_hold_ns < MIN_ROW_HOLD_DELAY) {
+			dev_err(&spmi->dev,
+				"invalid keypad row hold time supplied\n");
+			return -EINVAL;
+		}
+	}
+
+	if (!kp->debounce_ms) {
+		kp->debounce_ms = KEYP_DEFAULT_DEBOUNCE;
+	} else {
+		if (kp->debounce_ms > MAX_DEBOUNCE_TIME ||
+			kp->debounce_ms < MIN_DEBOUNCE_TIME ||
+			(kp->debounce_ms % 5 != 0)) {
+			dev_err(&spmi->dev,
+				"invalid debounce time supplied\n");
+			return -EINVAL;
+		}
+	}
+
+	kp->input = input_allocate_device();
+	if (!kp->input) {
+		dev_err(&spmi->dev, "Can't allocate keypad input device\n");
+		return -ENOMEM;
+	}
+
+	kp->key_sense_irq = spmi_get_irq_byname(spmi, NULL, "kp-sense");
+	if (kp->key_sense_irq < 0) {
+		dev_err(&spmi->dev, "Unable to get keypad sense irq\n");
+		return kp->key_sense_irq;
+	}
+
+	kp->key_stuck_irq = spmi_get_irq_byname(spmi, NULL, "kp-stuck");
+	if (kp->key_stuck_irq < 0) {
+		dev_err(&spmi->dev, "Unable to get stuck irq\n");
+		return kp->key_stuck_irq;
+	}
+
+	keypad_base = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0);
+	if (!keypad_base) {
+		dev_err(&spmi->dev, "Unable to get keypad base address\n");
+		return -ENXIO;
+	}
+	kp->base = keypad_base->start;
+
+	kp->input->name = "qpnp_keypad";
+	kp->input->phys = "qpnp_keypad/input0";
+	kp->input->id.version	= 0x0001;
+	kp->input->id.product	= 0x0001;
+	kp->input->id.vendor	= 0x0001;
+
+	kp->input->evbit[0]	= BIT_MASK(EV_KEY);
+
+	if (kp->rep)
+		set_bit(EV_REP, kp->input->evbit);
+
+	kp->input->keycode	= kp->keycodes;
+	kp->input->keycodemax	= QPNP_MATRIX_MAX_SIZE;
+	kp->input->keycodesize	= sizeof(kp->keycodes);
+	kp->input->open		= qpnp_kp_open;
+	kp->input->close	= qpnp_kp_close;
+
+	matrix_keypad_build_keymap(kp->keymap_data, QPNP_ROW_SHIFT,
+					kp->keycodes, kp->input->keybit);
+
+	input_set_capability(kp->input, EV_MSC, MSC_SCAN);
+	input_set_drvdata(kp->input, kp);
+
+	/* initialize keypad state */
+	memset(kp->keystate, 0xff, sizeof(kp->keystate));
+	memset(kp->stuckstate, 0xff, sizeof(kp->stuckstate));
+
+	rc = qpnp_kpd_init(kp);
+	if (rc < 0) {
+		dev_err(&spmi->dev, "unable to initialize keypad controller\n");
+		return rc;
+	}
+
+	rc = input_register_device(kp->input);
+	if (rc < 0) {
+		dev_err(&spmi->dev, "unable to register keypad input device\n");
+		return rc;
+	}
+
+	rc = devm_request_irq(&spmi->dev, kp->key_sense_irq, qpnp_kp_irq,
+				 IRQF_TRIGGER_RISING, "qpnp-keypad-sense", kp);
+	if (rc < 0) {
+		dev_err(&spmi->dev, "failed to request keypad sense irq\n");
+		return rc;
+	}
+
+	rc = devm_request_irq(&spmi->dev, kp->key_stuck_irq, qpnp_kp_stuck_irq,
+				 IRQF_TRIGGER_RISING, "qpnp-keypad-stuck", kp);
+	if (rc < 0) {
+		dev_err(&spmi->dev, "failed to request keypad stuck irq\n");
+		return rc;
+	}
+
+	device_init_wakeup(&spmi->dev, kp->wakeup);
+
+	return rc;
+}
+
+static int qpnp_kp_remove(struct spmi_device *spmi)
+{
+	struct qpnp_kp *kp = dev_get_drvdata(&spmi->dev);
+
+	device_init_wakeup(&spmi->dev, 0);
+	input_unregister_device(kp->input);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int qpnp_kp_suspend(struct device *dev)
+{
+	struct qpnp_kp *kp = dev_get_drvdata(dev);
+	struct input_dev *input_dev = kp->input;
+
+	if (device_may_wakeup(dev)) {
+		enable_irq_wake(kp->key_sense_irq);
+	} else {
+		mutex_lock(&input_dev->mutex);
+
+		if (input_dev->users)
+			qpnp_kp_disable(kp);
+
+		mutex_unlock(&input_dev->mutex);
+	}
+
+	return 0;
+}
+
+static int qpnp_kp_resume(struct device *dev)
+{
+	struct qpnp_kp *kp = dev_get_drvdata(dev);
+	struct input_dev *input_dev = kp->input;
+
+	if (device_may_wakeup(dev)) {
+		disable_irq_wake(kp->key_sense_irq);
+	} else {
+		mutex_lock(&input_dev->mutex);
+
+		if (input_dev->users)
+			qpnp_kp_enable(kp);
+
+		mutex_unlock(&input_dev->mutex);
+	}
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(qpnp_kp_pm_ops,
+			 qpnp_kp_suspend, qpnp_kp_resume);
+
+static struct of_device_id spmi_match_table[] = {
+	{	.compatible = "qcom,qpnp-keypad",
+	},
+	{}
+};
+
+static struct spmi_driver qpnp_kp_driver = {
+	.probe		= qpnp_kp_probe,
+	.remove		= __devexit_p(qpnp_kp_remove),
+	.driver		= {
+		.name = "qcom,qpnp-keypad",
+		.of_match_table = spmi_match_table,
+		.owner = THIS_MODULE,
+		.pm = &qpnp_kp_pm_ops,
+	},
+};
+
+static int __init qpnp_kp_init(void)
+{
+	return spmi_driver_register(&qpnp_kp_driver);
+}
+module_init(qpnp_kp_init);
+
+static void __exit qpnp_kp_exit(void)
+{
+	spmi_driver_unregister(&qpnp_kp_driver);
+}
+module_exit(qpnp_kp_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("QPNP keypad driver");
diff --git a/drivers/input/misc/isa1200-ff-memless.c b/drivers/input/misc/isa1200-ff-memless.c
index f4e2c35..61f07d0 100644
--- a/drivers/input/misc/isa1200-ff-memless.c
+++ b/drivers/input/misc/isa1200-ff-memless.c
@@ -2,7 +2,7 @@
  * Copyright (C) 2009 Samsung Electronics
  * Kyungmin Park <kyungmin.park@samsung.com>
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/drivers/input/misc/pm8xxx-vibrator.c b/drivers/input/misc/pm8xxx-vibrator.c
index dfbfb46..14d2fdd 100644
--- a/drivers/input/misc/pm8xxx-vibrator.c
+++ b/drivers/input/misc/pm8xxx-vibrator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/input/misc/pmic8058-othc.c b/drivers/input/misc/pmic8058-othc.c
index cac748a..d50dbc3 100644
--- a/drivers/input/misc/pmic8058-othc.c
+++ b/drivers/input/misc/pmic8058-othc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/input/misc/pmic8058-vib-memless.c b/drivers/input/misc/pmic8058-vib-memless.c
index ba05400..455b289 100644
--- a/drivers/input/misc/pmic8058-vib-memless.c
+++ b/drivers/input/misc/pmic8058-vib-memless.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 77a0aff..b43c13e 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -946,4 +946,66 @@
          To compile this driver as a module, choose M here: the
          module will be called ft5x06_ts.
 
+config TOUCHSCREEN_GEN_VKEYS
+       tristate "Touchscreen Virtual Keys Driver"
+       help
+         Say Y here if you want to generate a sysfs entry for virtual
+	 keys on Android.
+
+         If unsure, say N.
+
+         To compile this driver as a module, choose M here: the
+         module will be called gen_vkeys.
+
+config TOUCHSCREEN_SYNAPTICS_I2C_RMI4
+	tristate "Synaptics DSX I2C touchscreen"
+	depends on I2C
+	help
+	  Say Y here if you have a Synaptics DSX I2C touchscreen
+	  connected to your system.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called synaptics_i2c_rmi4.
+
+config TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV
+	tristate "Synaptics I2C touchscreen rmi device"
+	depends on TOUCHSCREEN_SYNAPTICS_I2C_RMI4
+	help
+	  This enables support for character device channel for Synaptics
+	  RMI4 touchscreens.
+
+	  Say Y here if you have a Synaptics DSX I2C touchscreen
+	  connected to your system.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called synaptics_dsx_rmi4_dev.
+
+config TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE
+	tristate "Synaptics I2C touchscreen firmware update"
+	depends on TOUCHSCREEN_SYNAPTICS_I2C_RMI4
+	help
+	  This enables support for firmware update for Synaptics RMI4
+	  touchscreens.
+
+	  Say Y here if you have a Synaptics DSX I2C touchscreen
+	  connected to your system.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called synaptics_dsx_fw_update.
+
+config SECURE_TOUCH
+	bool "Secure Touch"
+	depends on TOUCHSCREEN_ATMEL_MXT
+	help
+	  Say Y here to enable Secure Touch support in the Atmel MXT
+	  driver.
+
+	  If unsure, say N.
+
 endif
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 7b28e9d..ad43bbf 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -33,6 +33,7 @@
 obj-$(CONFIG_TOUCHSCREEN_ELO)		+= elo.o
 obj-$(CONFIG_TOUCHSCREEN_EGALAX)	+= egalax_ts.o
 obj-$(CONFIG_TOUCHSCREEN_FUJITSU)	+= fujitsu_ts.o
+obj-$(CONFIG_TOUCHSCREEN_GEN_VKEYS)	+= gen_vkeys.o
 obj-$(CONFIG_TOUCHSCREEN_ILI210X)	+= ili210x.o
 obj-$(CONFIG_TOUCHSCREEN_INEXIO)	+= inexio.o
 obj-$(CONFIG_TOUCHSCREEN_INTEL_MID)	+= intel-mid-touch.o
@@ -80,3 +81,6 @@
 obj-$(CONFIG_TOUCHSCREEN_CY8C_TS)	+= cy8c_ts.o
 obj-$(CONFIG_TOUCHSCREEN_CYTTSP_I2C_QC)       += cyttsp-i2c-qc.o
 obj-$(CONFIG_TOUCHSCREEN_FT5X06)	+= ft5x06_ts.o
+obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4)		+= synaptics_i2c_rmi4.o
+obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV)	+= synaptics_rmi_dev.o
+obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE) 	+= synaptics_fw_update.o
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index bb505d8..0ea230a 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2010 Samsung Electronics Co.Ltd
  * Author: Joonyoung Shim <jy0922.shim@samsung.com>
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -27,12 +27,25 @@
 #include <linux/regulator/consumer.h>
 #include <linux/string.h>
 #include <linux/of_gpio.h>
-#if defined(CONFIG_HAS_EARLYSUSPEND)
+
+#if defined(CONFIG_FB)
+#include <linux/notifier.h>
+#include <linux/fb.h>
+
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
 #include <linux/earlysuspend.h>
 /* Early-suspend level */
 #define MXT_SUSPEND_LEVEL 1
 #endif
 
+#if defined(CONFIG_SECURE_TOUCH)
+#include <linux/completion.h>
+#include <linux/pm_runtime.h>
+#include <linux/errno.h>
+#include <asm/system.h>
+#include <linux/atomic.h>
+#endif
+
 /* Family ID */
 #define MXT224_ID	0x80
 #define MXT224E_ID	0x81
@@ -233,14 +246,26 @@
 #define MXT_BOOT_VALUE		0xa5
 #define MXT_BACKUP_VALUE	0x55
 #define MXT_BACKUP_TIME		25	/* msec */
-#define MXT224_RESET_TIME	65	/* msec */
-#define MXT224E_RESET_TIME	150	/* msec */
-#define MXT1386_RESET_TIME	250	/* msec */
+
+/* Software reset delay */
+#define MXT224_RESET_TIME	64	/* msec */
+#define MXT224E_RESET_TIME	21	/* msec */
 #define MXT336S_RESET_TIME	25	/* msec */
-#define MXT1664S_RESET_TIME	65	/* msec */
+#define MXT1386_RESET_TIME	250	/* msec */
+#define MXT1386E_RESET_TIME	229	/* msec */
+#define MXT1664S_RESET_TIME	280	/* msec */
 #define MXT_RESET_TIME		250	/* msec */
 #define MXT_RESET_NOCHGREAD	400	/* msec */
 
+/* Power on delay */
+#define MXT224_POWER_ON_TIME	40	/* msec */
+#define MXT224E_POWER_ON_TIME	21	/* msec */
+#define MXT336S_POWER_ON_TIME	25	/* msec */
+#define MXT1386_POWER_ON_TIME	90	/* msec */
+#define MXT1386E_POWER_ON_TIME	81	/* msec */
+#define MXT1664S_POWER_ON_TIME	65	/* msec */
+#define MXT_POWER_ON_TIME	100	/* msec */
+
 #define MXT_FWRESET_TIME	1000	/* msec */
 
 #define MXT_WAKE_TIME		25
@@ -344,7 +369,10 @@
 	struct regulator *vcc_ana;
 	struct regulator *vcc_dig;
 	struct regulator *vcc_i2c;
-#if defined(CONFIG_HAS_EARLYSUSPEND)
+	struct mxt_address_pair addr_pair;
+#if defined(CONFIG_FB)
+	struct notifier_block fb_notif;
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
 	struct early_suspend early_suspend;
 #endif
 
@@ -364,6 +392,11 @@
 	bool update_cfg;
 	const char *fw_name;
 	bool no_force_update;
+#if defined(CONFIG_SECURE_TOUCH)
+	atomic_t st_enabled;
+	atomic_t st_pending_irqs;
+	struct completion st_completion;
+#endif
 };
 
 static struct dentry *debug_base;
@@ -458,9 +491,27 @@
 	dev_dbg(dev, "checksum:\t0x%x\n", message->checksum);
 }
 
-static int mxt_switch_to_bootloader_address(struct mxt_data *data)
+static int mxt_lookup_bootloader_address(struct mxt_data *data)
 {
 	int i;
+
+	for (i = 0; mxt_slave_addresses[i].application != 0;  i++) {
+		if (mxt_slave_addresses[i].application ==
+				data->client->addr) {
+			data->addr_pair.bootloader =
+				mxt_slave_addresses[i].bootloader;
+			return 0;
+		}
+	}
+
+	dev_err(&data->client->dev, "Address 0x%02x not found in address table",
+			data->client->addr);
+	return -EINVAL;
+
+};
+
+static int mxt_switch_to_bootloader_address(struct mxt_data *data)
+{
 	struct i2c_client *client = data->client;
 
 	if (data->state == BOOTLOADER) {
@@ -468,27 +519,16 @@
 		return -EINVAL;
 	}
 
-	for (i = 0; mxt_slave_addresses[i].application != 0;  i++) {
-		if (mxt_slave_addresses[i].application == client->addr) {
-			dev_info(&client->dev, "Changing to bootloader address: "
-				"%02x -> %02x",
-				client->addr,
-				mxt_slave_addresses[i].bootloader);
+	dev_info(&client->dev, "Changing to bootloader address: 0x%02x -> 0x%02x",
+			client->addr, data->addr_pair.bootloader);
 
-			client->addr = mxt_slave_addresses[i].bootloader;
-			data->state = BOOTLOADER;
-			return 0;
-		}
-	}
-
-	dev_err(&client->dev, "Address 0x%02x not found in address table",
-								client->addr);
-	return -EINVAL;
+	client->addr = data->addr_pair.bootloader;
+	data->state = BOOTLOADER;
+	return 0;
 }
 
 static int mxt_switch_to_appmode_address(struct mxt_data *data)
 {
-	int i;
 	struct i2c_client *client = data->client;
 
 	if (data->state == APPMODE) {
@@ -496,23 +536,13 @@
 		return -EINVAL;
 	}
 
-	for (i = 0; mxt_slave_addresses[i].application != 0;  i++) {
-		if (mxt_slave_addresses[i].bootloader == client->addr) {
-			dev_info(&client->dev,
-				"Changing to application mode address: "
-							"0x%02x -> 0x%02x",
-				client->addr,
-				mxt_slave_addresses[i].application);
+	dev_info(&client->dev, "Changing to application mode address: " \
+			"0x%02x -> 0x%02x", client->addr,
+			data->addr_pair.application);
 
-			client->addr = mxt_slave_addresses[i].application;
-			data->state = APPMODE;
-			return 0;
-		}
-	}
-
-	dev_err(&client->dev, "Address 0x%02x not found in address table",
-								client->addr);
-	return -EINVAL;
+	client->addr = data->addr_pair.application;
+	data->state = APPMODE;
+	return 0;
 }
 
 static int mxt_get_bootloader_version(struct i2c_client *client, u8 val)
@@ -856,6 +886,17 @@
 	input_sync(input_dev);
 }
 
+static void mxt_release_all(struct mxt_data *data)
+{
+	int id;
+
+	for (id = 0; id < MXT_MAX_FINGER; id++)
+		if (data->finger[id].status)
+			data->finger[id].status = MXT_RELEASE;
+
+	mxt_input_report(data, 0);
+}
+
 static void mxt_input_touchevent(struct mxt_data *data,
 				      struct mxt_message *message, int id)
 {
@@ -867,6 +908,10 @@
 	int area;
 	int pressure;
 
+	if (status & MXT_SUPPRESS) {
+		mxt_release_all(data);
+		return;
+	}
 	/* Check the touch is present on the screen */
 	if (!(status & MXT_DETECT)) {
 		if (status & MXT_RELEASE) {
@@ -941,18 +986,7 @@
 	data->keyarray_old = data->keyarray_new;
 }
 
-static void mxt_release_all(struct mxt_data *data)
-{
-	int id;
-
-	for (id = 0; id < MXT_MAX_FINGER; id++)
-		if (data->finger[id].status)
-			data->finger[id].status = MXT_RELEASE;
-
-	mxt_input_report(data, 0);
-}
-
-static void mxt_handle_touch_supression(struct mxt_data *data, u8 status)
+static void mxt_handle_touch_suppression(struct mxt_data *data, u8 status)
 {
 	dev_dbg(&data->client->dev, "touch suppression\n");
 	/* release all touches */
@@ -960,6 +994,23 @@
 		mxt_release_all(data);
 }
 
+#if defined(CONFIG_SECURE_TOUCH)
+static irqreturn_t mxt_filter_interrupt(struct mxt_data *data)
+{
+	if (atomic_read(&data->st_enabled)) {
+		atomic_cmpxchg(&data->st_pending_irqs, 0, 1);
+		complete(&data->st_completion);
+		return IRQ_HANDLED;
+	}
+	return IRQ_NONE;
+}
+#else
+static irqreturn_t mxt_filter_interrupt(struct mxt_data *data)
+{
+	return IRQ_NONE;
+}
+#endif
+
 static irqreturn_t mxt_interrupt(int irq, void *dev_id)
 {
 	struct mxt_data *data = dev_id;
@@ -973,6 +1024,9 @@
 		return IRQ_HANDLED;
 	}
 
+	if (IRQ_HANDLED == mxt_filter_interrupt(data))
+		goto end;
+
 	do {
 		if (mxt_read_message(data, &message)) {
 			dev_err(dev, "Failed to read message\n");
@@ -987,7 +1041,7 @@
 
 		id = reportid - data->t9_min_reportid;
 
-		 /* check whether report id is part of T9,T15 or T42*/
+		 /* check whether report id is part of T9, T15 or T42 */
 		if (reportid >= data->t9_min_reportid &&
 					reportid <= data->t9_max_reportid)
 			mxt_input_touchevent(data, &message, id);
@@ -995,8 +1049,9 @@
 					reportid <= data->t15_max_reportid)
 			mxt_handle_key_array(data, &message);
 		else if (reportid >= data->t42_min_reportid &&
-					reportid <= data->t42_max_reportid)
-			mxt_handle_touch_supression(data, message.message[0]);
+				reportid <= data->t42_max_reportid)
+			mxt_handle_touch_suppression(data,
+					message.message[0]);
 		else
 			mxt_dump_message(dev, &message);
 	} while (reportid != 0xff);
@@ -1291,6 +1346,42 @@
 	return 0;
 }
 
+static void mxt_power_on_delay(struct mxt_data *data)
+{
+	const struct mxt_platform_data *pdata = data->pdata;
+	const struct mxt_config_info *cfg_info;
+	u32 delay = 0;
+	int i;
+
+	for (i = 0; i < pdata->config_array_size; i++) {
+		cfg_info = &pdata->config_array[i];
+
+		switch (cfg_info->family_id) {
+		case MXT224_ID:
+			delay = max_t(u32, delay, MXT224_POWER_ON_TIME);
+			break;
+		case MXT224E_ID:
+			delay = max_t(u32, delay, MXT224E_POWER_ON_TIME);
+			break;
+		case MXT336S_ID:
+			delay = max_t(u32, delay, MXT336S_POWER_ON_TIME);
+			break;
+		case MXT1386_ID:
+			delay = max_t(u32, delay,
+					max_t(u32, MXT1386_POWER_ON_TIME,
+						MXT1386E_POWER_ON_TIME));
+			break;
+		case MXT1664S_ID:
+			delay = max_t(u32, delay, MXT1664S_POWER_ON_TIME);
+			break;
+		default:
+			delay = max_t(u32, delay, MXT_POWER_ON_TIME);
+		}
+	}
+
+	msleep(delay);
+}
+
 static void mxt_reset_delay(struct mxt_data *data)
 {
 	struct mxt_info *info = &data->info;
@@ -1304,8 +1395,10 @@
 		break;
 	case MXT336S_ID:
 		msleep(MXT336S_RESET_TIME);
+		break;
 	case MXT1386_ID:
-		msleep(MXT1386_RESET_TIME);
+		msleep(max_t(u32, MXT1386_RESET_TIME, MXT1386E_RESET_TIME));
+		break;
 	case MXT1664S_ID:
 		msleep(MXT1664S_RESET_TIME);
 		break;
@@ -1605,9 +1698,11 @@
 	switch (data->info.family_id) {
 	case MXT224_ID:
 	case MXT224E_ID:
+	case MXT336S_ID:
 		max_frame_size = MXT_SINGLE_FW_MAX_FRAME_SIZE;
 		break;
 	case MXT1386_ID:
+	case MXT1664S_ID:
 		max_frame_size = MXT_CHIPSET_FW_MAX_FRAME_SIZE;
 		break;
 	default:
@@ -1853,6 +1948,100 @@
 	return count;
 }
 
+#if defined(CONFIG_SECURE_TOUCH)
+
+static ssize_t mxt_secure_touch_enable_show(struct device *dev,
+				    struct device_attribute *attr, char *buf)
+{
+	struct mxt_data *data = dev_get_drvdata(dev);
+	return scnprintf(buf, PAGE_SIZE, "%d", atomic_read(&data->st_enabled));
+}
+/*
+ * Accept only "0" and "1" valid values.
+ * "0" will reset the st_enabled flag, then wake up the reading process.
+ * The bus driver is notified via pm_runtime that it is not required to stay
+ * awake anymore.
+ * It will also make sure the queue of events is emptied in the controller,
+ * in case a touch happened in between the secure touch being disabled and
+ * the local ISR being ungated.
+ * "1" will set the st_enabled flag and clear the st_pending_irqs flag.
+ * The bus driver is requested via pm_runtime to stay awake.
+ */
+static ssize_t mxt_secure_touch_enable_store(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t count)
+{
+	struct mxt_data *data = dev_get_drvdata(dev);
+	unsigned long value;
+	int err = 0;
+
+	if (count > 2)
+		return -EINVAL;
+
+	err = kstrtoul(buf, 10, &value);
+	if (err != 0)
+		return err;
+
+	err = count;
+
+	switch (value) {
+	case 0:
+		if (atomic_read(&data->st_enabled) == 0)
+			break;
+
+		pm_runtime_put(&data->client->adapter->dev);
+		atomic_set(&data->st_enabled, 0);
+		complete(&data->st_completion);
+		mxt_interrupt(data->client->irq, data);
+		break;
+	case 1:
+		if (atomic_read(&data->st_enabled)) {
+			err = -EBUSY;
+			break;
+		}
+
+		if (pm_runtime_get(data->client->adapter->dev.parent) < 0) {
+			dev_err(&data->client->dev, "pm_runtime_get failed\n");
+			err = -EIO;
+			break;
+		}
+		atomic_set(&data->st_pending_irqs, 0);
+		atomic_set(&data->st_enabled, 1);
+		break;
+	default:
+		dev_err(&data->client->dev, "unsupported value: %lu\n", value);
+		err = -EINVAL;
+		break;
+	}
+
+	return err;
+}
+
+static ssize_t mxt_secure_touch_show(struct device *dev,
+				    struct device_attribute *attr, char *buf)
+{
+	struct mxt_data *data = dev_get_drvdata(dev);
+	int err;
+
+	if (atomic_read(&data->st_enabled) == 0)
+		return -EBADF;
+
+	err = wait_for_completion_interruptible(&data->st_completion);
+
+	if (err)
+		return err;
+
+	if (atomic_cmpxchg(&data->st_pending_irqs, 1, 0) != 1)
+		return -EBADF;
+
+	return scnprintf(buf, PAGE_SIZE, "%u", 1);
+}
+
+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);
+#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);
@@ -1861,6 +2050,10 @@
 	&dev_attr_object.attr,
 	&dev_attr_update_fw.attr,
 	&dev_attr_force_cfg_update.attr,
+#if defined(CONFIG_SECURE_TOUCH)
+	&dev_attr_secure_touch_enable.attr,
+	&dev_attr_secure_touch.attr,
+#endif
 	NULL
 };
 
@@ -2280,24 +2473,8 @@
 	return 0;
 }
 
-#if defined(CONFIG_HAS_EARLYSUSPEND)
-static void mxt_early_suspend(struct early_suspend *h)
-{
-	struct mxt_data *data = container_of(h, struct mxt_data, early_suspend);
-
-	mxt_suspend(&data->client->dev);
-}
-
-static void mxt_late_resume(struct early_suspend *h)
-{
-	struct mxt_data *data = container_of(h, struct mxt_data, early_suspend);
-
-	mxt_resume(&data->client->dev);
-}
-#endif
-
 static const struct dev_pm_ops mxt_pm_ops = {
-#ifndef CONFIG_HAS_EARLYSUSPEND
+#if (!defined(CONFIG_FB) && !defined(CONFIG_HAS_EARLYSUSPEND))
 	.suspend	= mxt_suspend,
 	.resume		= mxt_resume,
 #endif
@@ -2514,6 +2691,12 @@
 		return -ENOMEM;
 	}
 
+	rc = of_property_read_u32(np, "atmel,bl-addr", &temp_val);
+	if (rc && (rc != -EINVAL))
+		dev_err(dev, "Unable to read bootloader address\n");
+	else if (rc != -EINVAL)
+		pdata->bl_addr = (u8) temp_val;
+
 	pdata->config_array  = info;
 
 	for_each_child_of_node(np, temp) {
@@ -2552,12 +2735,11 @@
 		} else
 			info->build = (u8) temp_val;
 
-		info->bootldr_id = of_property_read_u32(temp,
+		rc = of_property_read_u32(temp,
 					"atmel,bootldr-id", &temp_val);
-		if (rc) {
+		if (rc && (rc != -EINVAL))
 			dev_err(dev, "Unable to read bootldr-id\n");
-			return rc;
-		} else
+		else if (rc != -EINVAL)
 			info->bootldr_id = (u8) temp_val;
 
 		rc = mxt_parse_config(dev, temp, info);
@@ -2577,6 +2759,54 @@
 }
 #endif
 
+#if defined(CONFIG_FB)
+static int fb_notifier_callback(struct notifier_block *self,
+				 unsigned long event, void *data)
+{
+	struct fb_event *evdata = data;
+	int *blank;
+	struct mxt_data *mxt_dev_data =
+		container_of(self, struct mxt_data, fb_notif);
+
+	if (evdata && evdata->data && event == FB_EVENT_BLANK && mxt_dev_data &&
+			mxt_dev_data->client) {
+		blank = evdata->data;
+		if (*blank == FB_BLANK_UNBLANK)
+			mxt_resume(&mxt_dev_data->client->dev);
+		else if (*blank == FB_BLANK_POWERDOWN)
+			mxt_suspend(&mxt_dev_data->client->dev);
+	}
+
+	return 0;
+}
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+static void mxt_early_suspend(struct early_suspend *h)
+{
+	struct mxt_data *data = container_of(h, struct mxt_data,
+						early_suspend);
+	mxt_suspend(&data->client->dev);
+}
+
+static void mxt_late_resume(struct early_suspend *h)
+{
+	struct mxt_data *data = container_of(h, struct mxt_data,
+						early_suspend);
+	mxt_resume(&data->client->dev);
+}
+
+#endif
+
+#if defined(CONFIG_SECURE_TOUCH)
+static void __devinit secure_touch_init(struct mxt_data *data)
+{
+	init_completion(&data->st_completion);
+}
+#else
+static void __devinit secure_touch_init(struct mxt_data *data)
+{
+}
+#endif
+
 static int __devinit mxt_probe(struct i2c_client *client,
 		const struct i2c_device_id *id)
 {
@@ -2715,10 +2945,19 @@
 		}
 	}
 
-	mxt_reset_delay(data);
+	mxt_power_on_delay(data);
+
+	data->addr_pair.application = data->client->addr;
+
+	if (pdata->bl_addr)
+		data->addr_pair.bootloader = pdata->bl_addr;
+	else
+		mxt_lookup_bootloader_address(data);
+
 	error = mxt_initialize(data);
 	if (error)
 		goto err_reset_gpio_req;
+
 	error = request_threaded_irq(client->irq, NULL, mxt_interrupt,
 			pdata->irqflags, client->dev.driver->name, data);
 	if (error) {
@@ -2742,7 +2981,15 @@
 	if (error)
 		goto err_unregister_device;
 
-#if defined(CONFIG_HAS_EARLYSUSPEND)
+#if defined(CONFIG_FB)
+	data->fb_notif.notifier_call = fb_notifier_callback;
+
+	error = fb_register_client(&data->fb_notif);
+
+	if (error)
+		dev_err(&client->dev, "Unable to register fb_notifier: %d\n",
+			error);
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
 	data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN +
 						MXT_SUSPEND_LEVEL;
 	data->early_suspend.suspend = mxt_early_suspend;
@@ -2752,6 +2999,8 @@
 
 	mxt_debugfs_init(data);
 
+	secure_touch_init(data);
+
 	return 0;
 
 err_unregister_device:
@@ -2790,7 +3039,10 @@
 	sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
 	free_irq(data->irq, data);
 	input_unregister_device(data->input_dev);
-#if defined(CONFIG_HAS_EARLYSUSPEND)
+#if defined(CONFIG_FB)
+	if (fb_unregister_client(&data->fb_notif))
+		dev_err(&client->dev, "Error occurred while unregistering fb_notifier.\n");
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
 	unregister_early_suspend(&data->early_suspend);
 #endif
 
diff --git a/drivers/input/touchscreen/cy8c_ts.c b/drivers/input/touchscreen/cy8c_ts.c
index 88f7d1b..2ee4797 100644
--- a/drivers/input/touchscreen/cy8c_ts.c
+++ b/drivers/input/touchscreen/cy8c_ts.c
@@ -3,7 +3,7 @@
  * drivers/input/touchscreen/cy8c_ts.c
  *
  * Copyright (C) 2009, 2010 Cypress Semiconductor, Inc.
- * Copyright (c) 2010-2012 Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/drivers/input/touchscreen/cyttsp-i2c-qc.c b/drivers/input/touchscreen/cyttsp-i2c-qc.c
index 6eba5d1..6c4e6b7 100644
--- a/drivers/input/touchscreen/cyttsp-i2c-qc.c
+++ b/drivers/input/touchscreen/cyttsp-i2c-qc.c
@@ -2881,17 +2881,17 @@
 
 	cyttsp_debug("Wake Up\n");
 
-	if (ts->is_suspended == false) {
-		pr_err("%s: in wakeup state\n", __func__);
-		return 0;
-	}
-
 	if (device_may_wakeup(dev)) {
 		if (ts->client->irq)
 			disable_irq_wake(ts->client->irq);
 		return 0;
 	}
 
+	if (ts->is_suspended == false) {
+		pr_err("%s: in wakeup state\n", __func__);
+		return 0;
+	}
+
 	/* re-enable the interrupt prior to wake device */
 	if (ts->client->irq)
 		enable_irq(ts->client->irq);
@@ -2952,6 +2952,12 @@
 
 	cyttsp_debug("Enter Sleep\n");
 
+	if (device_may_wakeup(dev)) {
+		if (ts->client->irq)
+			enable_irq_wake(ts->client->irq);
+		return 0;
+	}
+
 	if (ts->is_suspended == true) {
 		pr_err("%s: in sleep state\n", __func__);
 		return 0;
@@ -2966,11 +2972,6 @@
 	}
 	mutex_unlock(&ts->mutex);
 
-	if (device_may_wakeup(dev)) {
-		if (ts->client->irq)
-			enable_irq_wake(ts->client->irq);
-		return 0;
-	}
 
 	if (ts->client->irq == 0)
 		del_timer(&ts->timer);
diff --git a/drivers/input/touchscreen/ft5x06_ts.c b/drivers/input/touchscreen/ft5x06_ts.c
index ffeb8fe..f74f2d5 100644
--- a/drivers/input/touchscreen/ft5x06_ts.c
+++ b/drivers/input/touchscreen/ft5x06_ts.c
@@ -3,7 +3,7 @@
  * FocalTech ft5x06 TouchScreen driver.
  *
  * Copyright (c) 2010  Focal tech Ltd.
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/input/touchscreen/gen_vkeys.c b/drivers/input/touchscreen/gen_vkeys.c
new file mode 100644
index 0000000..fcda6c9
--- /dev/null
+++ b/drivers/input/touchscreen/gen_vkeys.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.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/input.h>
+#include <linux/input/gen_vkeys.h>
+
+#define MAX_BUF_SIZE	256
+#define VKEY_VER_CODE	"0x01"
+
+#define HEIGHT_SCALE_NUM 8
+#define HEIGHT_SCALE_DENOM 10
+
+/* numerator and denomenator for border equations */
+#define BORDER_ADJUST_NUM 3
+#define BORDER_ADJUST_DENOM 4
+
+static struct kobject *vkey_obj;
+static char *vkey_buf;
+
+static ssize_t vkey_show(struct kobject  *obj,
+		struct kobj_attribute *attr, char *buf)
+{
+	strlcpy(buf, vkey_buf, MAX_BUF_SIZE);
+	return strnlen(buf, MAX_BUF_SIZE);
+}
+
+static struct kobj_attribute vkey_obj_attr = {
+	.attr = {
+		.mode = S_IRUGO,
+	},
+	.show = vkey_show,
+};
+
+static struct attribute *vkey_attr[] = {
+	&vkey_obj_attr.attr,
+	NULL,
+};
+
+static struct attribute_group vkey_grp = {
+	.attrs = vkey_attr,
+};
+
+static int __devinit vkey_parse_dt(struct device *dev,
+			struct vkeys_platform_data *pdata)
+{
+	struct device_node *np = dev->of_node;
+	struct property *prop;
+	int rc;
+
+	rc = of_property_read_string(np, "label", &pdata->name);
+	if (rc) {
+		dev_err(dev, "Failed to read label\n");
+		return -EINVAL;
+	}
+
+	rc = of_property_read_u32(np, "qcom,disp-maxx", &pdata->disp_maxx);
+	if (rc) {
+		dev_err(dev, "Failed to read display max x\n");
+		return -EINVAL;
+	}
+
+	rc = of_property_read_u32(np, "qcom,disp-maxy", &pdata->disp_maxy);
+	if (rc) {
+		dev_err(dev, "Failed to read display max y\n");
+		return -EINVAL;
+	}
+
+	rc = of_property_read_u32(np, "qcom,panel-maxx", &pdata->panel_maxx);
+	if (rc) {
+		dev_err(dev, "Failed to read panel max x\n");
+		return -EINVAL;
+	}
+
+	rc = of_property_read_u32(np, "qcom,panel-maxy", &pdata->panel_maxy);
+	if (rc) {
+		dev_err(dev, "Failed to read panel max y\n");
+		return -EINVAL;
+	}
+
+	prop = of_find_property(np, "qcom,key-codes", NULL);
+	if (prop) {
+		pdata->num_keys = prop->length / sizeof(u32);
+		pdata->keycodes = devm_kzalloc(dev,
+			sizeof(u32) * pdata->num_keys, GFP_KERNEL);
+		if (!pdata->keycodes)
+			return -ENOMEM;
+		rc = of_property_read_u32_array(np, "qcom,key-codes",
+				pdata->keycodes, pdata->num_keys);
+		if (rc) {
+			dev_err(dev, "Failed to read key codes\n");
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+static int __devinit vkeys_probe(struct platform_device *pdev)
+{
+	struct vkeys_platform_data *pdata;
+	int width, height, center_x, center_y;
+	int x1 = 0, x2 = 0, i, c = 0, ret, border;
+	char *name;
+
+	vkey_buf = devm_kzalloc(&pdev->dev, MAX_BUF_SIZE, GFP_KERNEL);
+	if (!vkey_buf) {
+		dev_err(&pdev->dev, "Failed to allocate memory\n");
+		return -ENOMEM;
+	}
+
+	if (pdev->dev.of_node) {
+		pdata = devm_kzalloc(&pdev->dev,
+			sizeof(struct vkeys_platform_data), GFP_KERNEL);
+		if (!pdata) {
+			dev_err(&pdev->dev, "Failed to allocate memory\n");
+			return -ENOMEM;
+		}
+
+		ret = vkey_parse_dt(&pdev->dev, pdata);
+		if (ret) {
+			dev_err(&pdev->dev, "Parsing DT failed(%d)", ret);
+			return ret;
+		}
+	} else
+		pdata = pdev->dev.platform_data;
+
+	if (!pdata || !pdata->name || !pdata->keycodes || !pdata->num_keys ||
+		!pdata->disp_maxx || !pdata->disp_maxy || !pdata->panel_maxy) {
+		dev_err(&pdev->dev, "pdata is invalid\n");
+		return -EINVAL;
+	}
+
+	border = (pdata->panel_maxx - pdata->disp_maxx) * 2;
+	width = ((pdata->disp_maxx - (border * (pdata->num_keys - 1)))
+			/ pdata->num_keys);
+	height = (pdata->panel_maxy - pdata->disp_maxy);
+	center_y = pdata->disp_maxy + (height / 2);
+	height = height * HEIGHT_SCALE_NUM / HEIGHT_SCALE_DENOM;
+
+	x2 -= border * BORDER_ADJUST_NUM / BORDER_ADJUST_DENOM;
+
+	for (i = 0; i < pdata->num_keys; i++) {
+		x1 = x2 + border;
+		x2 = x2 + border + width;
+		center_x = x1 + (x2 - x1) / 2;
+		c += snprintf(vkey_buf + c, MAX_BUF_SIZE - c,
+				"%s:%d:%d:%d:%d:%d\n",
+				VKEY_VER_CODE, pdata->keycodes[i],
+				center_x, center_y, width, height);
+	}
+
+	vkey_buf[c] = '\0';
+
+	name = devm_kzalloc(&pdev->dev, sizeof(*name) * MAX_BUF_SIZE,
+					GFP_KERNEL);
+	if (!name)
+		return -ENOMEM;
+
+	snprintf(name, MAX_BUF_SIZE,
+				"virtualkeys.%s", pdata->name);
+	vkey_obj_attr.attr.name = name;
+
+	vkey_obj = kobject_create_and_add("board_properties", NULL);
+	if (!vkey_obj) {
+		dev_err(&pdev->dev, "unable to create kobject\n");
+		return -ENOMEM;
+	}
+
+	ret = sysfs_create_group(vkey_obj, &vkey_grp);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to create attributes\n");
+		goto destroy_kobj;
+	}
+	return 0;
+
+destroy_kobj:
+	kobject_put(vkey_obj);
+
+	return ret;
+}
+
+static int __devexit vkeys_remove(struct platform_device *pdev)
+{
+	sysfs_remove_group(vkey_obj, &vkey_grp);
+	kobject_put(vkey_obj);
+
+	return 0;
+}
+
+static struct of_device_id vkey_match_table[] = {
+	{ .compatible = "qcom,gen-vkeys",},
+	{ },
+};
+
+static struct platform_driver vkeys_driver = {
+	.probe = vkeys_probe,
+	.remove = __devexit_p(vkeys_remove),
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "gen_vkeys",
+		.of_match_table = vkey_match_table,
+	},
+};
+
+module_platform_driver(vkeys_driver);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/input/touchscreen/msm_touch.c b/drivers/input/touchscreen/msm_touch.c
index 7ba896a..16cda8d 100644
--- a/drivers/input/touchscreen/msm_touch.c
+++ b/drivers/input/touchscreen/msm_touch.c
@@ -1,6 +1,6 @@
 /* drivers/input/touchscreen/msm_touch.c
  *
- * Copyright (c) 2008-2009, 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2011, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/input/touchscreen/msm_ts.c b/drivers/input/touchscreen/msm_ts.c
index e66120e..5d6f90d 100644
--- a/drivers/input/touchscreen/msm_ts.c
+++ b/drivers/input/touchscreen/msm_ts.c
@@ -1,7 +1,7 @@
 /* drivers/input/touchscreen/msm_ts.c
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/input/touchscreen/synaptics_fw_update.c b/drivers/input/touchscreen/synaptics_fw_update.c
new file mode 100644
index 0000000..7452587
--- /dev/null
+++ b/drivers/input/touchscreen/synaptics_fw_update.c
@@ -0,0 +1,1717 @@
+/*
+ * Synaptics RMI4 touchscreen driver
+ *
+ * Copyright (C) 2012 Synaptics Incorporated
+ *
+ * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
+ * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/firmware.h>
+#include <linux/input/synaptics_dsx.h>
+#include "synaptics_i2c_rmi4.h"
+
+#define DEBUG_FW_UPDATE
+#define SHOW_PROGRESS
+#define FW_IMAGE_NAME "PR1063486-s7301_00000000.img"
+#define MAX_FIRMWARE_ID_LEN 10
+#define FORCE_UPDATE false
+#define INSIDE_FIRMWARE_UPDATE
+
+#define CHECKSUM_OFFSET 0x00
+#define BOOTLOADER_VERSION_OFFSET 0x07
+#define IMAGE_SIZE_OFFSET 0x08
+#define CONFIG_SIZE_OFFSET 0x0C
+#define PRODUCT_ID_OFFSET 0x10
+#define PRODUCT_INFO_OFFSET 0x1E
+#define FW_IMAGE_OFFSET 0x100
+#define PRODUCT_ID_SIZE 10
+
+#define BOOTLOADER_ID_OFFSET 0
+#define FLASH_PROPERTIES_OFFSET 2
+#define BLOCK_SIZE_OFFSET 3
+#define FW_BLOCK_COUNT_OFFSET 5
+
+#define REG_MAP (1 << 0)
+#define UNLOCKED (1 << 1)
+#define HAS_CONFIG_ID (1 << 2)
+#define HAS_PERM_CONFIG (1 << 3)
+#define HAS_BL_CONFIG (1 << 4)
+#define HAS_DISP_CONFIG (1 << 5)
+#define HAS_CTRL1 (1 << 6)
+
+#define BLOCK_NUMBER_OFFSET 0
+#define BLOCK_DATA_OFFSET 2
+
+#define UI_CONFIG_AREA 0x00
+#define PERM_CONFIG_AREA 0x01
+#define BL_CONFIG_AREA 0x02
+#define DISP_CONFIG_AREA 0x03
+
+enum flash_command {
+	CMD_WRITE_FW_BLOCK		= 0x2,
+	CMD_ERASE_ALL			= 0x3,
+	CMD_READ_CONFIG_BLOCK	= 0x5,
+	CMD_WRITE_CONFIG_BLOCK	= 0x6,
+	CMD_ERASE_CONFIG		= 0x7,
+	CMD_ERASE_BL_CONFIG		= 0x9,
+	CMD_ERASE_DISP_CONFIG	= 0xA,
+	CMD_ENABLE_FLASH_PROG	= 0xF,
+};
+
+enum flash_area {
+	NONE,
+	UI_FIRMWARE,
+	CONFIG_AREA
+};
+
+#define SLEEP_MODE_NORMAL (0x00)
+#define SLEEP_MODE_SENSOR_SLEEP (0x01)
+#define SLEEP_MODE_RESERVED0 (0x02)
+#define SLEEP_MODE_RESERVED1 (0x03)
+
+#define ENABLE_WAIT_MS (1 * 1000)
+#define WRITE_WAIT_MS (3 * 1000)
+#define ERASE_WAIT_MS (5 * 1000)
+#define RESET_WAIT_MS (500)
+
+#define SLEEP_TIME_US 50
+
+static ssize_t fwu_sysfs_show_image(struct file *data_file,
+		struct kobject *kobj, struct bin_attribute *attributes,
+		char *buf, loff_t pos, size_t count);
+
+static ssize_t fwu_sysfs_store_image(struct file *data_file,
+		struct kobject *kobj, struct bin_attribute *attributes,
+		char *buf, loff_t pos, size_t count);
+
+static ssize_t fwu_sysfs_do_reflash_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+static ssize_t fwu_sysfs_write_config_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+static ssize_t fwu_sysfs_read_config_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+static ssize_t fwu_sysfs_config_area_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+static ssize_t fwu_sysfs_image_size_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+static ssize_t fwu_sysfs_block_size_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static ssize_t fwu_sysfs_firmware_block_count_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static ssize_t fwu_sysfs_configuration_block_count_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static ssize_t fwu_sysfs_perm_config_block_count_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static ssize_t fwu_sysfs_bl_config_block_count_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static ssize_t fwu_sysfs_disp_config_block_count_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static ssize_t fwu_sysfs_config_id_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static int fwu_wait_for_idle(int timeout_ms);
+
+struct image_header {
+	unsigned int checksum;
+	unsigned int image_size;
+	unsigned int config_size;
+	unsigned char options;
+	unsigned char bootloader_version;
+	unsigned char product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1];
+	unsigned char product_info[SYNAPTICS_RMI4_PRODUCT_INFO_SIZE];
+};
+
+struct pdt_properties {
+	union {
+		struct {
+			unsigned char reserved_1:6;
+			unsigned char has_bsr:1;
+			unsigned char reserved_2:1;
+		} __packed;
+		unsigned char data[1];
+	};
+};
+
+struct f01_device_status {
+	union {
+		struct {
+			unsigned char status_code:4;
+			unsigned char reserved:2;
+			unsigned char flash_prog:1;
+			unsigned char unconfigured:1;
+		} __packed;
+		unsigned char data[1];
+	};
+};
+
+struct f01_device_control {
+	union {
+		struct {
+			unsigned char sleep_mode:2;
+			unsigned char nosleep:1;
+			unsigned char reserved:2;
+			unsigned char charger_connected:1;
+			unsigned char report_rate:1;
+			unsigned char configured:1;
+		} __packed;
+		unsigned char data[1];
+	};
+};
+
+struct f34_flash_control {
+	union {
+		struct {
+			unsigned char command:4;
+			unsigned char status:3;
+			unsigned char program_enabled:1;
+		} __packed;
+		unsigned char data[1];
+	};
+};
+
+struct f34_flash_properties {
+	union {
+		struct {
+			unsigned char regmap:1;
+			unsigned char unlocked:1;
+			unsigned char has_configid:1;
+			unsigned char has_perm_config:1;
+			unsigned char has_bl_config:1;
+			unsigned char has_display_config:1;
+			unsigned char has_blob_config:1;
+			unsigned char reserved:1;
+		} __packed;
+		unsigned char data[1];
+	};
+};
+
+struct synaptics_rmi4_fwu_handle {
+	bool initialized;
+	bool force_update;
+	char product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1];
+	unsigned int image_size;
+	unsigned int data_pos;
+	unsigned char intr_mask;
+	unsigned char bootloader_id[2];
+	unsigned char productinfo1;
+	unsigned char productinfo2;
+	unsigned char *ext_data_source;
+	unsigned char *read_config_buf;
+	const unsigned char *firmware_data;
+	const unsigned char *config_data;
+	unsigned short block_size;
+	unsigned short fw_block_count;
+	unsigned short config_block_count;
+	unsigned short perm_config_block_count;
+	unsigned short bl_config_block_count;
+	unsigned short disp_config_block_count;
+	unsigned short config_size;
+	unsigned short config_area;
+	unsigned short addr_f34_flash_control;
+	unsigned short addr_f01_interrupt_register;
+	struct synaptics_rmi4_fn_desc f01_fd;
+	struct synaptics_rmi4_fn_desc f34_fd;
+	struct synaptics_rmi4_exp_fn_ptr *fn_ptr;
+	struct synaptics_rmi4_data *rmi4_data;
+	struct f34_flash_control flash_control;
+	struct f34_flash_properties flash_properties;
+	struct workqueue_struct *fwu_workqueue;
+	struct delayed_work fwu_work;
+};
+
+static struct bin_attribute dev_attr_data = {
+	.attr = {
+		.name = "data",
+		.mode = (S_IRUGO | S_IWUGO),
+	},
+	.size = 0,
+	.read = fwu_sysfs_show_image,
+	.write = fwu_sysfs_store_image,
+};
+
+static struct device_attribute attrs[] = {
+	__ATTR(doreflash, S_IWUGO,
+			synaptics_rmi4_show_error,
+			fwu_sysfs_do_reflash_store),
+	__ATTR(writeconfig, S_IWUGO,
+			synaptics_rmi4_show_error,
+			fwu_sysfs_write_config_store),
+	__ATTR(readconfig, S_IWUGO,
+			synaptics_rmi4_show_error,
+			fwu_sysfs_read_config_store),
+	__ATTR(configarea, S_IWUGO,
+			synaptics_rmi4_show_error,
+			fwu_sysfs_config_area_store),
+	__ATTR(imagesize, S_IWUGO,
+			synaptics_rmi4_show_error,
+			fwu_sysfs_image_size_store),
+	__ATTR(blocksize, S_IRUGO,
+			fwu_sysfs_block_size_show,
+			synaptics_rmi4_store_error),
+	__ATTR(fwblockcount, S_IRUGO,
+			fwu_sysfs_firmware_block_count_show,
+			synaptics_rmi4_store_error),
+	__ATTR(configblockcount, S_IRUGO,
+			fwu_sysfs_configuration_block_count_show,
+			synaptics_rmi4_store_error),
+	__ATTR(permconfigblockcount, S_IRUGO,
+			fwu_sysfs_perm_config_block_count_show,
+			synaptics_rmi4_store_error),
+	__ATTR(blconfigblockcount, S_IRUGO,
+			fwu_sysfs_bl_config_block_count_show,
+			synaptics_rmi4_store_error),
+	__ATTR(dispconfigblockcount, S_IRUGO,
+			fwu_sysfs_disp_config_block_count_show,
+			synaptics_rmi4_store_error),
+	__ATTR(config_id, S_IRUGO,
+			fwu_sysfs_config_id_show,
+			synaptics_rmi4_store_error),
+};
+
+static struct synaptics_rmi4_fwu_handle *fwu;
+
+static struct completion remove_complete;
+
+static unsigned int extract_uint(const unsigned char *ptr)
+{
+	return (unsigned int)ptr[0] +
+			(unsigned int)ptr[1] * 0x100 +
+			(unsigned int)ptr[2] * 0x10000 +
+			(unsigned int)ptr[3] * 0x1000000;
+}
+
+static void parse_header(struct image_header *header,
+		const unsigned char *fw_image)
+{
+	header->checksum = extract_uint(&fw_image[CHECKSUM_OFFSET]);
+	header->bootloader_version = fw_image[BOOTLOADER_VERSION_OFFSET];
+	header->image_size = extract_uint(&fw_image[IMAGE_SIZE_OFFSET]);
+	header->config_size = extract_uint(&fw_image[CONFIG_SIZE_OFFSET]);
+	memcpy(header->product_id, &fw_image[PRODUCT_ID_OFFSET],
+			SYNAPTICS_RMI4_PRODUCT_ID_SIZE);
+	header->product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE] = 0;
+	memcpy(header->product_info, &fw_image[PRODUCT_INFO_OFFSET],
+			SYNAPTICS_RMI4_PRODUCT_INFO_SIZE);
+
+#ifdef DEBUG_FW_UPDATE
+	dev_info(&fwu->rmi4_data->i2c_client->dev,
+		"Firwmare size %d, config size %d\n",
+		header->image_size,
+		header->config_size);
+#endif
+	return;
+}
+
+static int fwu_read_f01_device_status(struct f01_device_status *status)
+{
+	int retval;
+
+	retval = fwu->fn_ptr->read(fwu->rmi4_data,
+			fwu->f01_fd.data_base_addr,
+			status->data,
+			sizeof(status->data));
+	if (retval < 0) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Failed to read F01 device status\n",
+				__func__);
+		return retval;
+	}
+
+	return 0;
+}
+
+static int fwu_read_f34_queries(void)
+{
+	int retval;
+	unsigned char count = 4;
+	unsigned char buf[10];
+	struct i2c_client *i2c_client = fwu->rmi4_data->i2c_client;
+
+	retval = fwu->fn_ptr->read(fwu->rmi4_data,
+			fwu->f34_fd.query_base_addr + BOOTLOADER_ID_OFFSET,
+			fwu->bootloader_id,
+			sizeof(fwu->bootloader_id));
+	if (retval < 0) {
+		dev_err(&i2c_client->dev,
+				"%s: Failed to read bootloader ID\n",
+				__func__);
+		return retval;
+	}
+
+	retval = fwu->fn_ptr->read(fwu->rmi4_data,
+			fwu->f34_fd.query_base_addr + FLASH_PROPERTIES_OFFSET,
+			fwu->flash_properties.data,
+			sizeof(fwu->flash_properties.data));
+	if (retval < 0) {
+		dev_err(&i2c_client->dev,
+				"%s: Failed to read flash properties\n",
+				__func__);
+		return retval;
+	}
+
+	dev_info(&i2c_client->dev, "%s perm:%d, bl:%d, display:%d\n",
+				__func__,
+				fwu->flash_properties.has_perm_config,
+				fwu->flash_properties.has_bl_config,
+				fwu->flash_properties.has_display_config);
+
+	if (fwu->flash_properties.has_perm_config)
+		count += 2;
+
+	if (fwu->flash_properties.has_bl_config)
+		count += 2;
+
+	if (fwu->flash_properties.has_display_config)
+		count += 2;
+
+	retval = fwu->fn_ptr->read(fwu->rmi4_data,
+			fwu->f34_fd.query_base_addr + BLOCK_SIZE_OFFSET,
+			buf,
+			2);
+	if (retval < 0) {
+		dev_err(&i2c_client->dev,
+				"%s: Failed to read block size info\n",
+				__func__);
+		return retval;
+	}
+
+	batohs(&fwu->block_size, &(buf[0]));
+
+	retval = fwu->fn_ptr->read(fwu->rmi4_data,
+			fwu->f34_fd.query_base_addr + FW_BLOCK_COUNT_OFFSET,
+			buf,
+			count);
+	if (retval < 0) {
+		dev_err(&i2c_client->dev,
+				"%s: Failed to read block count info\n",
+				__func__);
+		return retval;
+	}
+
+	batohs(&fwu->fw_block_count, &(buf[0]));
+	batohs(&fwu->config_block_count, &(buf[2]));
+
+	count = 4;
+
+	if (fwu->flash_properties.has_perm_config) {
+		batohs(&fwu->perm_config_block_count, &(buf[count]));
+		count += 2;
+	}
+
+	if (fwu->flash_properties.has_bl_config) {
+		batohs(&fwu->bl_config_block_count, &(buf[count]));
+		count += 2;
+	}
+
+	if (fwu->flash_properties.has_display_config)
+		batohs(&fwu->disp_config_block_count, &(buf[count]));
+
+	fwu->addr_f34_flash_control = fwu->f34_fd.data_base_addr +
+					BLOCK_DATA_OFFSET +
+					fwu->block_size;
+	return 0;
+}
+
+static int fwu_read_interrupt_status(void)
+{
+	int retval;
+	unsigned char interrupt_status;
+	retval = fwu->fn_ptr->read(fwu->rmi4_data,
+			fwu->addr_f01_interrupt_register,
+			&interrupt_status,
+			sizeof(interrupt_status));
+	if (retval < 0) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Failed to read flash status\n",
+				__func__);
+		return retval;
+	}
+	return interrupt_status;
+}
+
+static int fwu_read_f34_flash_status(void)
+{
+	int retval;
+	retval = fwu->fn_ptr->read(fwu->rmi4_data,
+			fwu->addr_f34_flash_control,
+			fwu->flash_control.data,
+			sizeof(fwu->flash_control.data));
+	if (retval < 0) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Failed to read flash status\n",
+				__func__);
+		return retval;
+	}
+	return 0;
+}
+
+static int fwu_reset_device(void)
+{
+	int retval;
+
+#ifdef DEBUG_FW_UPDATE
+	dev_info(&fwu->rmi4_data->i2c_client->dev,
+			"%s: Reset device\n",
+			__func__);
+#endif
+
+	retval = fwu->rmi4_data->reset_device(fwu->rmi4_data);
+	if (retval < 0) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Failed to reset core driver after reflash\n",
+				__func__);
+		return retval;
+	}
+	return 0;
+}
+
+static int fwu_write_f34_command(unsigned char cmd)
+{
+	int retval;
+
+	fwu->flash_control.data[0] = cmd;
+	retval = fwu->fn_ptr->write(fwu->rmi4_data,
+			fwu->addr_f34_flash_control,
+			fwu->flash_control.data,
+			sizeof(fwu->flash_control.data));
+	if (retval < 0) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Failed to write command 0x%02x\n",
+				__func__, fwu->flash_control.data[0]);
+		return retval;
+	}
+	return 0;
+}
+
+static int fwu_wait_for_idle(int timeout_ms)
+{
+	int count = 0;
+	int timeout_count = ((timeout_ms * 1000) / SLEEP_TIME_US) + 1;
+	do {
+		if (fwu->flash_control.command == 0x00)
+			return 0;
+
+		usleep_range(SLEEP_TIME_US, SLEEP_TIME_US + 100);
+	} while (count++ < timeout_count);
+
+	fwu_read_f34_flash_status();
+	if (fwu->flash_control.command == 0x00)
+		return 0;
+
+	dev_err(&fwu->rmi4_data->i2c_client->dev,
+			"%s: Timed out waiting for idle status\n",
+			__func__);
+
+	return -ETIMEDOUT;
+}
+
+static enum flash_area fwu_go_nogo(void)
+{
+	int retval = 0;
+	int index = 0;
+	int deviceFirmwareID;
+	int imageConfigID;
+	int deviceConfigID;
+	unsigned long imageFirmwareID;
+	unsigned char firmware_id[4];
+	unsigned char config_id[4];
+	char *strptr;
+	char *imagePR = kzalloc(sizeof(MAX_FIRMWARE_ID_LEN), GFP_KERNEL);
+	enum flash_area flash_area = NONE;
+	struct i2c_client *i2c_client = fwu->rmi4_data->i2c_client;
+	struct f01_device_status f01_device_status;
+
+	if (fwu->force_update) {
+		flash_area = UI_FIRMWARE;
+		goto exit;
+	}
+
+	retval = fwu_read_f01_device_status(&f01_device_status);
+	if (retval < 0) {
+		flash_area = NONE;
+		goto exit;
+	}
+
+	imagePR = kzalloc(sizeof(MAX_FIRMWARE_ID_LEN), GFP_KERNEL);
+
+	/* Force update firmware when device is in bootloader mode */
+	if (f01_device_status.flash_prog) {
+		dev_info(&i2c_client->dev,
+			"%s: In flash prog mode\n",
+			__func__);
+		flash_area = UI_FIRMWARE;
+		goto exit;
+	}
+
+
+	/* device firmware id */
+	retval = fwu->fn_ptr->read(fwu->rmi4_data,
+				fwu->f01_fd.query_base_addr + 18,
+				firmware_id,
+				sizeof(firmware_id));
+	if (retval < 0) {
+		dev_err(&i2c_client->dev,
+			"Failed to read firmware ID (code %d).\n", retval);
+		goto exit;
+	}
+	firmware_id[3] = 0;
+	deviceFirmwareID = extract_uint(firmware_id);
+
+	/* .img firmware id */
+	strptr = strstr(FW_IMAGE_NAME, "PR");
+	if (!strptr) {
+		dev_err(&i2c_client->dev,
+			"No valid PR number (PRxxxxxxx)" \
+			"found in image file name...\n");
+		goto exit;
+	}
+
+	strptr += 2;
+	while (strptr[index] >= '0' && strptr[index] <= '9') {
+		imagePR[index] = strptr[index];
+		index++;
+	}
+	imagePR[index] = 0;
+
+	retval = kstrtoul(imagePR, 10, &imageFirmwareID);
+	if (retval ==  -EINVAL) {
+		dev_err(&i2c_client->dev,
+			"invalid image firmware id...\n");
+		goto exit;
+	}
+
+	dev_info(&i2c_client->dev,
+			"Device firmware id %d, .img firmware id %d\n",
+			deviceFirmwareID,
+			(unsigned int)imageFirmwareID);
+	if (imageFirmwareID > deviceFirmwareID) {
+		flash_area = UI_FIRMWARE;
+		goto exit;
+	}
+
+	/* device config id */
+	retval = fwu->fn_ptr->read(fwu->rmi4_data,
+				fwu->f34_fd.ctrl_base_addr,
+				config_id,
+				sizeof(config_id));
+	if (retval < 0) {
+		dev_err(&i2c_client->dev,
+			"Failed to read config ID (code %d).\n", retval);
+		flash_area = NONE;
+		goto exit;
+	}
+	deviceConfigID =  extract_uint(config_id);
+
+	dev_info(&i2c_client->dev,
+		"Device config ID 0x%02X, 0x%02X, 0x%02X, 0x%02X\n",
+		config_id[0], config_id[1], config_id[2], config_id[3]);
+
+	/* .img config id */
+	dev_info(&i2c_client->dev,
+			".img config ID 0x%02X, 0x%02X, 0x%02X, 0x%02X\n",
+			fwu->config_data[0],
+			fwu->config_data[1],
+			fwu->config_data[2],
+			fwu->config_data[3]);
+	imageConfigID =  extract_uint(fwu->config_data);
+
+	if (imageConfigID > deviceConfigID) {
+		flash_area = CONFIG_AREA;
+		goto exit;
+	}
+
+exit:
+	kfree(imagePR);
+	if (flash_area == NONE)
+		dev_info(&i2c_client->dev,
+			"Nothing needs to be updated\n");
+	else
+		dev_info(&i2c_client->dev,
+			"Update %s block\n",
+			flash_area == UI_FIRMWARE ? "UI FW" : "CONFIG");
+	return flash_area;
+}
+
+static int fwu_scan_pdt(void)
+{
+	int retval;
+	unsigned char ii;
+	unsigned char intr_count = 0;
+	unsigned char intr_off;
+	unsigned char intr_src;
+	unsigned short addr;
+	bool f01found = false;
+	bool f34found = false;
+	struct synaptics_rmi4_fn_desc rmi_fd;
+
+#ifdef DEBUG_FW_UPDATE
+	dev_info(&fwu->rmi4_data->i2c_client->dev, "Scan PDT\n");
+#endif
+
+	for (addr = PDT_START; addr > PDT_END; addr -= PDT_ENTRY_SIZE) {
+		retval = fwu->fn_ptr->read(fwu->rmi4_data,
+					addr,
+					(unsigned char *)&rmi_fd,
+					sizeof(rmi_fd));
+		if (retval < 0)
+			return retval;
+
+		if (rmi_fd.fn_number) {
+			dev_dbg(&fwu->rmi4_data->i2c_client->dev,
+					"%s: Found F%02x\n",
+					__func__, rmi_fd.fn_number);
+			switch (rmi_fd.fn_number) {
+			case SYNAPTICS_RMI4_F01:
+				f01found = true;
+				fwu->f01_fd = rmi_fd;
+				fwu->addr_f01_interrupt_register =
+					fwu->f01_fd.data_base_addr + 1;
+				break;
+			case SYNAPTICS_RMI4_F34:
+				f34found = true;
+				fwu->f34_fd = rmi_fd;
+				fwu->intr_mask = 0;
+				intr_src = rmi_fd.intr_src_count;
+				intr_off = intr_count % 8;
+				for (ii = intr_off;
+						ii < ((intr_src & MASK_3BIT) +
+						intr_off);
+						ii++)
+					fwu->intr_mask |= 1 << ii;
+				break;
+			}
+		} else
+		break;
+
+		intr_count += (rmi_fd.intr_src_count & MASK_3BIT);
+	}
+
+	if (!f01found || !f34found) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Failed to find both F01 and F34\n",
+				__func__);
+		return -EINVAL;
+	}
+
+	fwu_read_interrupt_status();
+	return 0;
+}
+
+static int fwu_write_blocks(unsigned char *block_ptr, unsigned short block_cnt,
+		unsigned char command)
+{
+	int retval;
+	unsigned char block_offset[] = {0, 0};
+	unsigned short block_num;
+	struct i2c_client *i2c_client = fwu->rmi4_data->i2c_client;
+#ifdef SHOW_PROGRESS
+	unsigned int progress = (command == CMD_WRITE_CONFIG_BLOCK) ?
+				10 : 100;
+#endif
+
+#ifdef DEBUG_FW_UPDATE
+	dev_info(&i2c_client->dev,
+			"%s: Start to update %s blocks\n",
+			__func__,
+			command == CMD_WRITE_CONFIG_BLOCK ?
+			"config" : "firmware");
+#endif
+	retval = fwu->fn_ptr->write(fwu->rmi4_data,
+			fwu->f34_fd.data_base_addr + BLOCK_NUMBER_OFFSET,
+			block_offset,
+			sizeof(block_offset));
+	if (retval < 0) {
+		dev_err(&i2c_client->dev,
+				"%s: Failed to write to block number registers\n",
+				__func__);
+		return retval;
+	}
+
+	for (block_num = 0; block_num < block_cnt; block_num++) {
+#ifdef SHOW_PROGRESS
+		if (block_num % progress == 0)
+			dev_info(&i2c_client->dev,
+					"%s: update %s %3d / %3d\n",
+					__func__,
+					command == CMD_WRITE_CONFIG_BLOCK ?
+					"config" : "firmware",
+					block_num, block_cnt);
+#endif
+		retval = fwu->fn_ptr->write(fwu->rmi4_data,
+			fwu->f34_fd.data_base_addr + BLOCK_DATA_OFFSET,
+			block_ptr,
+			fwu->block_size);
+		if (retval < 0) {
+			dev_err(&i2c_client->dev,
+				"%s: Failed to write block data (block %d)\n",
+				__func__, block_num);
+			return retval;
+		}
+
+		retval = fwu_write_f34_command(command);
+		if (retval < 0) {
+			dev_err(&i2c_client->dev,
+					"%s: Failed to write command for block %d\n",
+					__func__, block_num);
+			return retval;
+		}
+
+		retval = fwu_wait_for_idle(WRITE_WAIT_MS);
+		if (retval < 0) {
+			dev_err(&i2c_client->dev,
+					"%s: Failed to wait for idle status (block %d)\n",
+					__func__, block_num);
+			return retval;
+		}
+
+		if (fwu->flash_control.status != 0x00) {
+			dev_err(&i2c_client->dev,
+					"%s: Flash block %d failed, status 0x%02X\n",
+					__func__, block_num, retval);
+			return retval;
+		}
+
+		block_ptr += fwu->block_size;
+	}
+#ifdef SHOW_PROGRESS
+	dev_info(&i2c_client->dev,
+			"%s: update %s %3d / %3d\n",
+			__func__,
+			command == CMD_WRITE_CONFIG_BLOCK ?
+			"config" : "firmware",
+			block_cnt, block_cnt);
+#endif
+	return 0;
+}
+
+static int fwu_write_firmware(void)
+{
+	return fwu_write_blocks((unsigned char *)fwu->firmware_data,
+		fwu->fw_block_count, CMD_WRITE_FW_BLOCK);
+}
+
+static int fwu_write_configuration(void)
+{
+	return fwu_write_blocks((unsigned char *)fwu->config_data,
+		fwu->config_block_count, CMD_WRITE_CONFIG_BLOCK);
+}
+
+static int fwu_write_bootloader_id(void)
+{
+	int retval;
+
+#ifdef DEBUG_FW_UPDATE
+	dev_info(&fwu->rmi4_data->i2c_client->dev,
+			"Write bootloader ID 0x%02X 0x%02X\n",
+			fwu->bootloader_id[0],
+			fwu->bootloader_id[1]);
+#endif
+	retval = fwu->fn_ptr->write(fwu->rmi4_data,
+			fwu->f34_fd.data_base_addr + BLOCK_DATA_OFFSET,
+			fwu->bootloader_id,
+			sizeof(fwu->bootloader_id));
+	if (retval < 0) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Failed to write bootloader ID\n",
+				__func__);
+		return retval;
+	}
+
+	return 0;
+}
+
+static int fwu_enter_flash_prog(void)
+{
+	int retval;
+	struct f01_device_status f01_device_status;
+	struct f01_device_control f01_device_control;
+
+#ifdef DEBUG_FW_UPDATE
+	dev_info(&fwu->rmi4_data->i2c_client->dev, "Enter bootloader mode\n");
+#endif
+	retval = fwu_read_f01_device_status(&f01_device_status);
+	if (retval < 0)
+		return retval;
+
+	if (f01_device_status.flash_prog) {
+		dev_info(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Already in flash prog mode\n",
+				__func__);
+		return 0;
+	}
+
+	retval = fwu_write_bootloader_id();
+	if (retval < 0)
+		return retval;
+
+	retval = fwu_write_f34_command(CMD_ENABLE_FLASH_PROG);
+	if (retval < 0)
+		return retval;
+
+	retval = fwu_wait_for_idle(ENABLE_WAIT_MS);
+	if (retval < 0)
+		return retval;
+
+	retval = fwu_scan_pdt();
+	if (retval < 0)
+		return retval;
+
+	retval = fwu_read_f01_device_status(&f01_device_status);
+	if (retval < 0)
+		return retval;
+
+	if (!f01_device_status.flash_prog) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Not in flash prog mode\n",
+				__func__);
+		return -EINVAL;
+	}
+
+	retval = fwu_read_f34_queries();
+	if (retval < 0)
+		return retval;
+
+	retval = fwu->fn_ptr->read(fwu->rmi4_data,
+			fwu->f01_fd.ctrl_base_addr,
+			f01_device_control.data,
+			sizeof(f01_device_control.data));
+	if (retval < 0) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Failed to read F01 device control\n",
+				__func__);
+		return retval;
+	}
+
+	f01_device_control.nosleep = true;
+	f01_device_control.sleep_mode = SLEEP_MODE_NORMAL;
+
+	retval = fwu->fn_ptr->write(fwu->rmi4_data,
+			fwu->f01_fd.ctrl_base_addr,
+			f01_device_control.data,
+			sizeof(f01_device_control.data));
+	if (retval < 0) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Failed to write F01 device control\n",
+				__func__);
+		return retval;
+	}
+
+	return retval;
+}
+
+static int fwu_do_reflash(void)
+{
+	int retval;
+
+	retval = fwu_enter_flash_prog();
+	if (retval < 0)
+		return retval;
+
+	dev_dbg(&fwu->rmi4_data->i2c_client->dev,
+			"%s: Entered flash prog mode\n",
+			__func__);
+
+	retval = fwu_write_bootloader_id();
+	if (retval < 0)
+		return retval;
+
+	dev_dbg(&fwu->rmi4_data->i2c_client->dev,
+			"%s: Bootloader ID written\n",
+			__func__);
+
+	retval = fwu_write_f34_command(CMD_ERASE_ALL);
+	if (retval < 0)
+		return retval;
+
+	dev_dbg(&fwu->rmi4_data->i2c_client->dev,
+			"%s: Erase all command written\n",
+			__func__);
+
+	retval = fwu_wait_for_idle(ERASE_WAIT_MS);
+	if (retval < 0)
+		return retval;
+
+	if (fwu->flash_control.status != 0x00) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Erase all command failed, status 0x%02X\n",
+				__func__, retval);
+		return -1;
+	}
+
+	if (fwu->firmware_data) {
+		retval = fwu_write_firmware();
+		if (retval < 0)
+			return retval;
+		pr_notice("%s: Firmware programmed\n", __func__);
+	}
+
+	if (fwu->config_data) {
+		retval = fwu_write_configuration();
+		if (retval < 0)
+			return retval;
+		pr_notice("%s: Configuration programmed\n", __func__);
+	}
+
+	return retval;
+}
+
+static int fwu_do_write_config(void)
+{
+	int retval;
+
+	retval = fwu_enter_flash_prog();
+	if (retval < 0)
+		return retval;
+
+	dev_dbg(&fwu->rmi4_data->i2c_client->dev,
+			"%s: Entered flash prog mode\n",
+			__func__);
+
+	if (fwu->config_area == PERM_CONFIG_AREA) {
+		fwu->config_block_count = fwu->perm_config_block_count;
+		goto write_config;
+	}
+
+	retval = fwu_write_bootloader_id();
+	if (retval < 0)
+		return retval;
+
+	dev_dbg(&fwu->rmi4_data->i2c_client->dev,
+			"%s: Bootloader ID written\n",
+			__func__);
+
+	switch (fwu->config_area) {
+	case UI_CONFIG_AREA:
+		retval = fwu_write_f34_command(CMD_ERASE_CONFIG);
+		break;
+	case BL_CONFIG_AREA:
+		retval = fwu_write_f34_command(CMD_ERASE_BL_CONFIG);
+		fwu->config_block_count = fwu->bl_config_block_count;
+		break;
+	case DISP_CONFIG_AREA:
+		retval = fwu_write_f34_command(CMD_ERASE_DISP_CONFIG);
+		fwu->config_block_count = fwu->disp_config_block_count;
+		break;
+	}
+	if (retval < 0)
+		return retval;
+
+	dev_dbg(&fwu->rmi4_data->i2c_client->dev,
+			"%s: Erase command written\n",
+			__func__);
+
+	retval = fwu_wait_for_idle(ERASE_WAIT_MS);
+	if (retval < 0)
+		return retval;
+
+	dev_dbg(&fwu->rmi4_data->i2c_client->dev,
+			"%s: Idle status detected\n",
+			__func__);
+
+write_config:
+	retval = fwu_write_configuration();
+	if (retval < 0)
+		return retval;
+
+	pr_notice("%s: Config written\n", __func__);
+
+	return retval;
+}
+
+static int fwu_start_write_config(void)
+{
+	int retval;
+	struct image_header header;
+
+	switch (fwu->config_area) {
+	case UI_CONFIG_AREA:
+		break;
+	case PERM_CONFIG_AREA:
+		if (!fwu->flash_properties.has_perm_config)
+			return -EINVAL;
+		break;
+	case BL_CONFIG_AREA:
+		if (!fwu->flash_properties.has_bl_config)
+			return -EINVAL;
+		break;
+	case DISP_CONFIG_AREA:
+		if (!fwu->flash_properties.has_display_config)
+			return -EINVAL;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (fwu->ext_data_source)
+		fwu->config_data = fwu->ext_data_source;
+	else
+		return -EINVAL;
+
+	if (fwu->config_area == UI_CONFIG_AREA) {
+		parse_header(&header, fwu->ext_data_source);
+
+		if (header.config_size) {
+			fwu->config_data = fwu->ext_data_source +
+					FW_IMAGE_OFFSET +
+					header.image_size;
+		} else {
+			return -EINVAL;
+		}
+	}
+
+	pr_notice("%s: Start of write config process\n", __func__);
+
+	retval = fwu_do_write_config();
+	if (retval < 0) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Failed to write config\n",
+				__func__);
+	}
+
+	fwu->rmi4_data->reset_device(fwu->rmi4_data);
+
+	pr_notice("%s: End of write config process\n", __func__);
+
+	return retval;
+}
+
+static int fwu_do_read_config(void)
+{
+	int retval;
+	unsigned char block_offset[] = {0, 0};
+	unsigned short block_num;
+	unsigned short block_count;
+	unsigned short index = 0;
+
+	retval = fwu_enter_flash_prog();
+	if (retval < 0)
+		goto exit;
+
+	dev_dbg(&fwu->rmi4_data->i2c_client->dev,
+			"%s: Entered flash prog mode\n",
+			__func__);
+
+	switch (fwu->config_area) {
+	case UI_CONFIG_AREA:
+		block_count = fwu->config_block_count;
+		break;
+	case PERM_CONFIG_AREA:
+		if (!fwu->flash_properties.has_perm_config) {
+			retval = -EINVAL;
+			goto exit;
+		}
+		block_count = fwu->perm_config_block_count;
+		break;
+	case BL_CONFIG_AREA:
+		if (!fwu->flash_properties.has_bl_config) {
+			retval = -EINVAL;
+			goto exit;
+		}
+		block_count = fwu->bl_config_block_count;
+		break;
+	case DISP_CONFIG_AREA:
+		if (!fwu->flash_properties.has_display_config) {
+			retval = -EINVAL;
+			goto exit;
+		}
+		block_count = fwu->disp_config_block_count;
+		break;
+	default:
+		retval = -EINVAL;
+		goto exit;
+	}
+
+	fwu->config_size = fwu->block_size * block_count;
+
+	kfree(fwu->read_config_buf);
+	fwu->read_config_buf = kzalloc(fwu->config_size, GFP_KERNEL);
+
+	block_offset[1] |= (fwu->config_area << 5);
+
+	retval = fwu->fn_ptr->write(fwu->rmi4_data,
+			fwu->f34_fd.data_base_addr + BLOCK_NUMBER_OFFSET,
+			block_offset,
+			sizeof(block_offset));
+	if (retval < 0) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Failed to write to block number registers\n",
+				__func__);
+		goto exit;
+	}
+
+	for (block_num = 0; block_num < block_count; block_num++) {
+		retval = fwu_write_f34_command(CMD_READ_CONFIG_BLOCK);
+		if (retval < 0) {
+			dev_err(&fwu->rmi4_data->i2c_client->dev,
+					"%s: Failed to write read config command\n",
+					__func__);
+			goto exit;
+		}
+
+		retval = fwu_wait_for_idle(WRITE_WAIT_MS);
+		if (retval < 0) {
+			dev_err(&fwu->rmi4_data->i2c_client->dev,
+					"%s: Failed to wait for idle status\n",
+					__func__);
+			goto exit;
+		}
+
+		retval = fwu->fn_ptr->read(fwu->rmi4_data,
+				fwu->f34_fd.data_base_addr + BLOCK_DATA_OFFSET,
+				&fwu->read_config_buf[index],
+				fwu->block_size);
+		if (retval < 0) {
+			dev_err(&fwu->rmi4_data->i2c_client->dev,
+					"%s: Failed to read block data (block %d)\n",
+					__func__, block_num);
+			goto exit;
+		}
+
+		index += fwu->block_size;
+	}
+
+exit:
+	fwu->rmi4_data->reset_device(fwu->rmi4_data);
+
+	return retval;
+}
+
+static int fwu_start_reflash(void)
+{
+	int retval;
+	struct image_header header;
+	const unsigned char *fw_image;
+	const struct firmware *fw_entry = NULL;
+	struct f01_device_status f01_device_status;
+	enum flash_area flash_area;
+
+	pr_notice("%s: Start of reflash process\n", __func__);
+
+	if (fwu->ext_data_source)
+		fw_image = fwu->ext_data_source;
+	else {
+		dev_dbg(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Requesting firmware image %s\n",
+				__func__, FW_IMAGE_NAME);
+
+		retval = request_firmware(&fw_entry, FW_IMAGE_NAME,
+				&fwu->rmi4_data->i2c_client->dev);
+		if (retval != 0) {
+			dev_err(&fwu->rmi4_data->i2c_client->dev,
+					"%s: Firmware image %s not available\n",
+					__func__, FW_IMAGE_NAME);
+			retval = -EINVAL;
+			goto exit;
+		}
+
+		dev_dbg(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Firmware image size = %d\n",
+				__func__, fw_entry->size);
+
+		fw_image = fw_entry->data;
+	}
+
+	parse_header(&header, fw_image);
+
+	if (header.image_size)
+		fwu->firmware_data = fw_image + FW_IMAGE_OFFSET;
+	if (header.config_size) {
+		fwu->config_data = fw_image + FW_IMAGE_OFFSET +
+				header.image_size;
+	}
+
+	if (fwu->ext_data_source)
+		flash_area = UI_FIRMWARE;
+	else
+		flash_area = fwu_go_nogo();
+
+	switch (flash_area) {
+	case NONE:
+		dev_info(&fwu->rmi4_data->i2c_client->dev,
+		"%s: No need to do reflash.\n",
+		__func__);
+		goto exit;
+	case UI_FIRMWARE:
+		retval = fwu_do_reflash();
+		break;
+	case CONFIG_AREA:
+		retval = fwu_do_write_config();
+		break;
+	default:
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Unknown flash area\n",
+				__func__);
+		goto exit;
+	}
+
+	if (retval < 0) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Failed to do reflash\n",
+				__func__);
+	}
+
+	/* reset device */
+	fwu_reset_device();
+
+	/* check device status */
+	retval = fwu_read_f01_device_status(&f01_device_status);
+	if (retval < 0)
+		goto exit;
+
+	dev_info(&fwu->rmi4_data->i2c_client->dev, "Device is in %s mode\n",
+		f01_device_status.flash_prog == 1 ? "bootloader" : "UI");
+	if (f01_device_status.flash_prog)
+		dev_info(&fwu->rmi4_data->i2c_client->dev, "Flash status %d\n",
+				f01_device_status.status_code);
+
+	if (f01_device_status.flash_prog) {
+		dev_info(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Device is in flash prog mode 0x%02X\n",
+				__func__, f01_device_status.status_code);
+		retval = 0;
+		goto exit;
+	}
+
+	if (fw_entry)
+		release_firmware(fw_entry);
+
+	pr_notice("%s: End of reflash process\n", __func__);
+exit:
+	return retval;
+}
+
+int synaptics_fw_updater(unsigned char *fw_data)
+{
+	int retval;
+
+	if (!fwu)
+		return -ENODEV;
+
+	if (!fwu->initialized)
+		return -ENODEV;
+
+	fwu->ext_data_source = fw_data;
+	fwu->config_area = UI_CONFIG_AREA;
+
+	retval = fwu_start_reflash();
+
+	return retval;
+}
+EXPORT_SYMBOL(synaptics_fw_updater);
+
+static ssize_t fwu_sysfs_show_image(struct file *data_file,
+		struct kobject *kobj, struct bin_attribute *attributes,
+		char *buf, loff_t pos, size_t count)
+{
+	struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
+
+	if (count < fwu->config_size) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Not enough space (%d bytes) in buffer\n",
+				__func__, count);
+		return -EINVAL;
+	}
+
+	memcpy(buf, fwu->read_config_buf, fwu->config_size);
+
+	return fwu->config_size;
+}
+
+static ssize_t fwu_sysfs_store_image(struct file *data_file,
+		struct kobject *kobj, struct bin_attribute *attributes,
+		char *buf, loff_t pos, size_t count)
+{
+	memcpy((void *)(&fwu->ext_data_source[fwu->data_pos]),
+			(const void *)buf,
+			count);
+
+	fwu->data_pos += count;
+
+	return count;
+}
+
+static ssize_t fwu_sysfs_do_reflash_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	int retval;
+	unsigned int input;
+	struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
+
+	if (sscanf(buf, "%u", &input) != 1) {
+		retval = -EINVAL;
+		goto exit;
+	}
+
+	if (input != 1) {
+		retval = -EINVAL;
+		goto exit;
+	}
+
+	retval = synaptics_fw_updater(fwu->ext_data_source);
+	if (retval < 0) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to do reflash\n",
+				__func__);
+		goto exit;
+	}
+
+	retval = count;
+
+exit:
+	kfree(fwu->ext_data_source);
+	fwu->ext_data_source = NULL;
+	return retval;
+}
+
+static ssize_t fwu_sysfs_write_config_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	int retval;
+	unsigned int input;
+	struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
+
+	if (sscanf(buf, "%u", &input) != 1) {
+		retval = -EINVAL;
+		goto exit;
+	}
+
+	if (input != 1) {
+		retval = -EINVAL;
+		goto exit;
+	}
+
+	retval = fwu_start_write_config();
+	if (retval < 0) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to write config\n",
+				__func__);
+		goto exit;
+	}
+
+	retval = count;
+
+exit:
+	kfree(fwu->ext_data_source);
+	fwu->ext_data_source = NULL;
+	return retval;
+}
+
+static ssize_t fwu_sysfs_read_config_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	int retval;
+	unsigned int input;
+	struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
+
+	if (sscanf(buf, "%u", &input) != 1)
+		return -EINVAL;
+
+	if (input != 1)
+		return -EINVAL;
+
+	retval = fwu_do_read_config();
+	if (retval < 0) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to read config\n",
+				__func__);
+		return retval;
+	}
+
+	return count;
+}
+
+static ssize_t fwu_sysfs_config_area_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	int retval;
+	unsigned long config_area;
+
+	retval = kstrtoul(buf, 10, &config_area);
+	if (retval)
+		return retval;
+
+	fwu->config_area = config_area;
+
+	return count;
+}
+
+static ssize_t fwu_sysfs_image_size_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	int retval;
+	unsigned long size;
+	struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
+
+	retval = kstrtoul(buf, 10, &size);
+	if (retval)
+		return retval;
+
+	fwu->image_size = size;
+	fwu->data_pos = 0;
+
+	kfree(fwu->ext_data_source);
+	fwu->ext_data_source = kzalloc(fwu->image_size, GFP_KERNEL);
+	if (!fwu->ext_data_source) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to alloc mem for image data\n",
+				__func__);
+		return -ENOMEM;
+	}
+
+	return count;
+}
+
+static ssize_t fwu_sysfs_block_size_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n", fwu->block_size);
+}
+
+static ssize_t fwu_sysfs_firmware_block_count_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n", fwu->fw_block_count);
+}
+
+static ssize_t fwu_sysfs_configuration_block_count_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n", fwu->config_block_count);
+}
+
+static ssize_t fwu_sysfs_perm_config_block_count_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n", fwu->perm_config_block_count);
+}
+
+static ssize_t fwu_sysfs_bl_config_block_count_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n", fwu->bl_config_block_count);
+}
+
+static ssize_t fwu_sysfs_disp_config_block_count_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n", fwu->disp_config_block_count);
+}
+
+static ssize_t fwu_sysfs_config_id_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	unsigned char config_id[4];
+	/* device config id */
+	fwu->fn_ptr->read(fwu->rmi4_data,
+				fwu->f34_fd.ctrl_base_addr,
+				config_id,
+				sizeof(config_id));
+
+	return snprintf(buf, PAGE_SIZE, "%d.%d.%d.%d\n",
+		config_id[0], config_id[1], config_id[2], config_id[3]);
+}
+
+static void synaptics_rmi4_fwu_attn(struct synaptics_rmi4_data *rmi4_data,
+		unsigned char intr_mask)
+{
+	if (fwu->intr_mask & intr_mask)
+		fwu_read_f34_flash_status();
+
+	return;
+}
+
+static void synaptics_rmi4_fwu_work(struct work_struct *work)
+{
+	fwu_start_reflash();
+}
+
+static int synaptics_rmi4_fwu_init(struct synaptics_rmi4_data *rmi4_data)
+{
+	int retval;
+	unsigned char attr_count;
+	struct pdt_properties pdt_props;
+
+	fwu = kzalloc(sizeof(*fwu), GFP_KERNEL);
+	if (!fwu) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to alloc mem for fwu\n",
+				__func__);
+		goto exit;
+	}
+
+	fwu->fn_ptr = kzalloc(sizeof(*(fwu->fn_ptr)), GFP_KERNEL);
+	if (!fwu->fn_ptr) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to alloc mem for fn_ptr\n",
+				__func__);
+		retval = -ENOMEM;
+		goto exit_free_fwu;
+	}
+
+	fwu->rmi4_data = rmi4_data;
+	fwu->fn_ptr->read = rmi4_data->i2c_read;
+	fwu->fn_ptr->write = rmi4_data->i2c_write;
+	fwu->fn_ptr->enable = rmi4_data->irq_enable;
+
+	retval = fwu->fn_ptr->read(rmi4_data,
+			PDT_PROPS,
+			pdt_props.data,
+			sizeof(pdt_props.data));
+	if (retval < 0) {
+		dev_dbg(&rmi4_data->i2c_client->dev,
+				"%s: Failed to read PDT properties, assuming 0x00\n",
+				__func__);
+	} else if (pdt_props.has_bsr) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Reflash for LTS not currently supported\n",
+				__func__);
+		goto exit_free_mem;
+	}
+
+	retval = fwu_scan_pdt();
+	if (retval < 0)
+		goto exit_free_mem;
+
+	fwu->productinfo1 = rmi4_data->rmi4_mod_info.product_info[0];
+	fwu->productinfo2 = rmi4_data->rmi4_mod_info.product_info[1];
+
+	memcpy(fwu->product_id, rmi4_data->rmi4_mod_info.product_id_string,
+			SYNAPTICS_RMI4_PRODUCT_ID_SIZE);
+	fwu->product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE] = 0;
+
+	dev_dbg(&rmi4_data->i2c_client->dev,
+			"%s: F01 product info: 0x%04x 0x%04x\n",
+			__func__, fwu->productinfo1, fwu->productinfo2);
+	dev_dbg(&rmi4_data->i2c_client->dev,
+			"%s: F01 product ID: %s\n",
+			__func__, fwu->product_id);
+
+	retval = fwu_read_f34_queries();
+	if (retval < 0)
+		goto exit_free_mem;
+
+	fwu->initialized = true;
+	fwu->force_update = FORCE_UPDATE;
+
+	retval = sysfs_create_bin_file(&rmi4_data->input_dev->dev.kobj,
+			&dev_attr_data);
+	if (retval < 0) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to create sysfs bin file\n",
+				__func__);
+		goto exit_free_mem;
+	}
+
+	for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
+		retval = sysfs_create_file(&rmi4_data->input_dev->dev.kobj,
+				&attrs[attr_count].attr);
+		if (retval < 0) {
+			dev_err(&rmi4_data->i2c_client->dev,
+					"%s: Failed to create sysfs attributes\n",
+					__func__);
+			retval = -ENODEV;
+			goto exit_remove_attrs;
+		}
+	}
+
+#ifdef INSIDE_FIRMWARE_UPDATE
+	fwu->fwu_workqueue = create_singlethread_workqueue("fwu_workqueue");
+	INIT_DELAYED_WORK(&fwu->fwu_work, synaptics_rmi4_fwu_work);
+	queue_delayed_work(fwu->fwu_workqueue,
+			&fwu->fwu_work,
+			msecs_to_jiffies(1000));
+#endif
+	return 0;
+
+exit_remove_attrs:
+for (attr_count--; attr_count >= 0; attr_count--) {
+	sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
+			&attrs[attr_count].attr);
+}
+
+sysfs_remove_bin_file(&rmi4_data->input_dev->dev.kobj, &dev_attr_data);
+
+exit_free_mem:
+	kfree(fwu->fn_ptr);
+
+exit_free_fwu:
+	kfree(fwu);
+
+exit:
+	return 0;
+}
+
+static void synaptics_rmi4_fwu_remove(struct synaptics_rmi4_data *rmi4_data)
+{
+	unsigned char attr_count;
+
+	sysfs_remove_bin_file(&rmi4_data->input_dev->dev.kobj, &dev_attr_data);
+
+	for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
+		sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
+				&attrs[attr_count].attr);
+	}
+
+	kfree(fwu->fn_ptr);
+	kfree(fwu);
+
+	complete(&remove_complete);
+
+	return;
+}
+
+static int __init rmi4_fw_update_module_init(void)
+{
+	synaptics_rmi4_new_function(RMI_FW_UPDATER, true,
+			synaptics_rmi4_fwu_init,
+			synaptics_rmi4_fwu_remove,
+			synaptics_rmi4_fwu_attn);
+	return 0;
+}
+
+static void __exit rmi4_fw_update_module_exit(void)
+{
+	init_completion(&remove_complete);
+	synaptics_rmi4_new_function(RMI_FW_UPDATER, false,
+			synaptics_rmi4_fwu_init,
+			synaptics_rmi4_fwu_remove,
+			synaptics_rmi4_fwu_attn);
+	wait_for_completion(&remove_complete);
+	return;
+}
+
+module_init(rmi4_fw_update_module_init);
+module_exit(rmi4_fw_update_module_exit);
+
+MODULE_AUTHOR("Synaptics, Inc.");
+MODULE_DESCRIPTION("RMI4 FW Update Module");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi4.c b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
new file mode 100644
index 0000000..2c79276
--- /dev/null
+++ b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
@@ -0,0 +1,2354 @@
+/*
+ * Synaptics RMI4 touchscreen driver
+ *
+ * Copyright (C) 2012 Synaptics Incorporated
+ *
+ * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
+ * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/input/synaptics_dsx.h>
+#include "synaptics_i2c_rmi4.h"
+#ifdef KERNEL_ABOVE_2_6_38
+#include <linux/input/mt.h>
+#endif
+
+#define DRIVER_NAME "synaptics_rmi4_i2c"
+#define INPUT_PHYS_NAME "synaptics_rmi4_i2c/input0"
+
+#ifdef KERNEL_ABOVE_2_6_38
+#define TYPE_B_PROTOCOL
+#endif
+
+#define NO_0D_WHILE_2D
+/*
+#define REPORT_2D_Z
+*/
+#define REPORT_2D_W
+
+#define RPT_TYPE (1 << 0)
+#define RPT_X_LSB (1 << 1)
+#define RPT_X_MSB (1 << 2)
+#define RPT_Y_LSB (1 << 3)
+#define RPT_Y_MSB (1 << 4)
+#define RPT_Z (1 << 5)
+#define RPT_WX (1 << 6)
+#define RPT_WY (1 << 7)
+#define RPT_DEFAULT (RPT_TYPE | RPT_X_LSB | RPT_X_MSB | RPT_Y_LSB | RPT_Y_MSB)
+
+#define EXP_FN_DET_INTERVAL 1000 /* ms */
+#define POLLING_PERIOD 1 /* ms */
+#define SYN_I2C_RETRY_TIMES 10
+#define MAX_ABS_MT_TOUCH_MAJOR 15
+
+#define F01_STD_QUERY_LEN 21
+#define F01_BUID_ID_OFFSET 18
+#define F11_STD_QUERY_LEN 9
+#define F11_STD_CTRL_LEN 10
+#define F11_STD_DATA_LEN 12
+
+#define NORMAL_OPERATION (0 << 0)
+#define SENSOR_SLEEP (1 << 0)
+#define NO_SLEEP_OFF (0 << 3)
+#define NO_SLEEP_ON (1 << 3)
+
+#define RMI4_VTG_MIN_UV		2700000
+#define RMI4_VTG_MAX_UV		3300000
+#define RMI4_ACTIVE_LOAD_UA	15000
+#define RMI4_LPM_LOAD_UA	10
+
+#define RMI4_I2C_VTG_MIN_UV	1800000
+#define RMI4_I2C_VTG_MAX_UV	1800000
+#define RMI4_I2C_LOAD_UA	10000
+#define RMI4_I2C_LPM_LOAD_UA	10
+
+#define RMI4_GPIO_SLEEP_LOW_US 10000
+#define RMI4_GPIO_WAIT_HIGH_MS 25
+
+static int synaptics_rmi4_i2c_read(struct synaptics_rmi4_data *rmi4_data,
+		unsigned short addr, unsigned char *data,
+		unsigned short length);
+
+static int synaptics_rmi4_i2c_write(struct synaptics_rmi4_data *rmi4_data,
+		unsigned short addr, unsigned char *data,
+		unsigned short length);
+
+static int synaptics_rmi4_reset_device(struct synaptics_rmi4_data *rmi4_data);
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static ssize_t synaptics_rmi4_full_pm_cycle_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static ssize_t synaptics_rmi4_full_pm_cycle_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+static void synaptics_rmi4_early_suspend(struct early_suspend *h);
+
+static void synaptics_rmi4_late_resume(struct early_suspend *h);
+
+static int synaptics_rmi4_suspend(struct device *dev);
+
+static int synaptics_rmi4_resume(struct device *dev);
+#endif
+
+static ssize_t synaptics_rmi4_f01_reset_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+static ssize_t synaptics_rmi4_f01_productinfo_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static ssize_t synaptics_rmi4_f01_buildid_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static ssize_t synaptics_rmi4_f01_flashprog_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static ssize_t synaptics_rmi4_0dbutton_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static ssize_t synaptics_rmi4_0dbutton_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+struct synaptics_rmi4_f01_device_status {
+	union {
+		struct {
+			unsigned char status_code:4;
+			unsigned char reserved:2;
+			unsigned char flash_prog:1;
+			unsigned char unconfigured:1;
+		} __packed;
+		unsigned char data[1];
+	};
+};
+
+struct synaptics_rmi4_f1a_query {
+	union {
+		struct {
+			unsigned char max_button_count:3;
+			unsigned char reserved:5;
+			unsigned char has_general_control:1;
+			unsigned char has_interrupt_enable:1;
+			unsigned char has_multibutton_select:1;
+			unsigned char has_tx_rx_map:1;
+			unsigned char has_perbutton_threshold:1;
+			unsigned char has_release_threshold:1;
+			unsigned char has_strongestbtn_hysteresis:1;
+			unsigned char has_filter_strength:1;
+		} __packed;
+		unsigned char data[2];
+	};
+};
+
+struct synaptics_rmi4_f1a_control_0 {
+	union {
+		struct {
+			unsigned char multibutton_report:2;
+			unsigned char filter_mode:2;
+			unsigned char reserved:4;
+		} __packed;
+		unsigned char data[1];
+	};
+};
+
+struct synaptics_rmi4_f1a_control_3_4 {
+	unsigned char transmitterbutton;
+	unsigned char receiverbutton;
+};
+
+struct synaptics_rmi4_f1a_control {
+	struct synaptics_rmi4_f1a_control_0 general_control;
+	unsigned char *button_int_enable;
+	unsigned char *multi_button;
+	struct synaptics_rmi4_f1a_control_3_4 *electrode_map;
+	unsigned char *button_threshold;
+	unsigned char button_release_threshold;
+	unsigned char strongest_button_hysteresis;
+	unsigned char filter_strength;
+};
+
+struct synaptics_rmi4_f1a_handle {
+	int button_bitmask_size;
+	unsigned char button_count;
+	unsigned char valid_button_count;
+	unsigned char *button_data_buffer;
+	unsigned char *button_map;
+	struct synaptics_rmi4_f1a_query button_query;
+	struct synaptics_rmi4_f1a_control button_control;
+};
+
+struct synaptics_rmi4_exp_fn {
+	enum exp_fn fn_type;
+	bool inserted;
+	int (*func_init)(struct synaptics_rmi4_data *rmi4_data);
+	void (*func_remove)(struct synaptics_rmi4_data *rmi4_data);
+	void (*func_attn)(struct synaptics_rmi4_data *rmi4_data,
+			unsigned char intr_mask);
+	struct list_head link;
+};
+
+static struct device_attribute attrs[] = {
+#ifdef CONFIG_HAS_EARLYSUSPEND
+	__ATTR(full_pm_cycle, (S_IRUGO | S_IWUGO),
+			synaptics_rmi4_full_pm_cycle_show,
+			synaptics_rmi4_full_pm_cycle_store),
+#endif
+	__ATTR(reset, S_IWUGO,
+			synaptics_rmi4_show_error,
+			synaptics_rmi4_f01_reset_store),
+	__ATTR(productinfo, S_IRUGO,
+			synaptics_rmi4_f01_productinfo_show,
+			synaptics_rmi4_store_error),
+	__ATTR(buildid, S_IRUGO,
+			synaptics_rmi4_f01_buildid_show,
+			synaptics_rmi4_store_error),
+	__ATTR(flashprog, S_IRUGO,
+			synaptics_rmi4_f01_flashprog_show,
+			synaptics_rmi4_store_error),
+	__ATTR(0dbutton, (S_IRUGO | S_IWUGO),
+			synaptics_rmi4_0dbutton_show,
+			synaptics_rmi4_0dbutton_store),
+};
+
+static bool exp_fn_inited;
+static struct mutex exp_fn_list_mutex;
+static struct list_head exp_fn_list;
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static ssize_t synaptics_rmi4_full_pm_cycle_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+			rmi4_data->full_pm_cycle);
+}
+
+static ssize_t synaptics_rmi4_full_pm_cycle_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	unsigned int input;
+	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+	if (sscanf(buf, "%u", &input) != 1)
+		return -EINVAL;
+
+	rmi4_data->full_pm_cycle = input > 0 ? 1 : 0;
+
+	return count;
+}
+#endif
+
+static ssize_t synaptics_rmi4_f01_reset_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	int retval;
+	unsigned int reset;
+	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+	if (sscanf(buf, "%u", &reset) != 1)
+		return -EINVAL;
+
+	if (reset != 1)
+		return -EINVAL;
+
+	retval = synaptics_rmi4_reset_device(rmi4_data);
+	if (retval < 0) {
+		dev_err(dev,
+				"%s: Failed to issue reset command, error = %d\n",
+				__func__, retval);
+		return retval;
+	}
+
+	return count;
+}
+
+static ssize_t synaptics_rmi4_f01_productinfo_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+	return snprintf(buf, PAGE_SIZE, "0x%02x 0x%02x\n",
+			(rmi4_data->rmi4_mod_info.product_info[0]),
+			(rmi4_data->rmi4_mod_info.product_info[1]));
+}
+
+static ssize_t synaptics_rmi4_f01_buildid_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	unsigned int build_id;
+	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+	struct synaptics_rmi4_device_info *rmi;
+
+	rmi = &(rmi4_data->rmi4_mod_info);
+
+	build_id = (unsigned int)rmi->build_id[0] +
+			(unsigned int)rmi->build_id[1] * 0x100 +
+			(unsigned int)rmi->build_id[2] * 0x10000;
+
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+			build_id);
+}
+
+static ssize_t synaptics_rmi4_f01_flashprog_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	int retval;
+	struct synaptics_rmi4_f01_device_status device_status;
+	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+	retval = synaptics_rmi4_i2c_read(rmi4_data,
+			rmi4_data->f01_data_base_addr,
+			device_status.data,
+			sizeof(device_status.data));
+	if (retval < 0) {
+		dev_err(dev,
+				"%s: Failed to read device status, error = %d\n",
+				__func__, retval);
+		return retval;
+	}
+
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+			device_status.flash_prog);
+}
+
+static ssize_t synaptics_rmi4_0dbutton_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+			rmi4_data->button_0d_enabled);
+}
+
+static ssize_t synaptics_rmi4_0dbutton_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	int retval;
+	unsigned int input;
+	unsigned char ii;
+	unsigned char intr_enable;
+	struct synaptics_rmi4_fn *fhandler;
+	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+	struct synaptics_rmi4_device_info *rmi;
+
+	rmi = &(rmi4_data->rmi4_mod_info);
+
+	if (sscanf(buf, "%u", &input) != 1)
+		return -EINVAL;
+
+	input = input > 0 ? 1 : 0;
+
+	if (rmi4_data->button_0d_enabled == input)
+		return count;
+
+	if (!list_empty(&rmi->support_fn_list)) {
+		list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
+			if (fhandler->fn_number == SYNAPTICS_RMI4_F1A) {
+				ii = fhandler->intr_reg_num;
+
+				retval = synaptics_rmi4_i2c_read(rmi4_data,
+						rmi4_data->f01_ctrl_base_addr +
+						1 + ii,
+						&intr_enable,
+						sizeof(intr_enable));
+				if (retval < 0)
+					return retval;
+
+				if (input == 1)
+					intr_enable |= fhandler->intr_mask;
+				else
+					intr_enable &= ~fhandler->intr_mask;
+
+				retval = synaptics_rmi4_i2c_write(rmi4_data,
+						rmi4_data->f01_ctrl_base_addr +
+						1 + ii,
+						&intr_enable,
+						sizeof(intr_enable));
+				if (retval < 0)
+					return retval;
+			}
+		}
+	}
+
+	rmi4_data->button_0d_enabled = input;
+
+	return count;
+}
+
+ /**
+ * synaptics_rmi4_set_page()
+ *
+ * Called by synaptics_rmi4_i2c_read() and synaptics_rmi4_i2c_write().
+ *
+ * This function writes to the page select register to switch to the
+ * assigned page.
+ */
+static int synaptics_rmi4_set_page(struct synaptics_rmi4_data *rmi4_data,
+		unsigned int address)
+{
+	int retval = 0;
+	unsigned char retry;
+	unsigned char buf[PAGE_SELECT_LEN];
+	unsigned char page;
+	struct i2c_client *i2c = rmi4_data->i2c_client;
+
+	page = ((address >> 8) & MASK_8BIT);
+	if (page != rmi4_data->current_page) {
+		buf[0] = MASK_8BIT;
+		buf[1] = page;
+		for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) {
+			retval = i2c_master_send(i2c, buf, PAGE_SELECT_LEN);
+			if (retval != PAGE_SELECT_LEN) {
+				dev_err(&i2c->dev,
+						"%s: I2C retry %d\n",
+						__func__, retry + 1);
+				msleep(20);
+			} else {
+				rmi4_data->current_page = page;
+				break;
+			}
+		}
+	} else
+		return PAGE_SELECT_LEN;
+	return (retval == PAGE_SELECT_LEN) ? retval : -EIO;
+}
+
+ /**
+ * synaptics_rmi4_i2c_read()
+ *
+ * Called by various functions in this driver, and also exported to
+ * other expansion Function modules such as rmi_dev.
+ *
+ * This function reads data of an arbitrary length from the sensor,
+ * starting from an assigned register address of the sensor, via I2C
+ * with a retry mechanism.
+ */
+static int synaptics_rmi4_i2c_read(struct synaptics_rmi4_data *rmi4_data,
+		unsigned short addr, unsigned char *data, unsigned short length)
+{
+	int retval;
+	unsigned char retry;
+	unsigned char buf;
+	struct i2c_msg msg[] = {
+		{
+			.addr = rmi4_data->i2c_client->addr,
+			.flags = 0,
+			.len = 1,
+			.buf = &buf,
+		},
+		{
+			.addr = rmi4_data->i2c_client->addr,
+			.flags = I2C_M_RD,
+			.len = length,
+			.buf = data,
+		},
+	};
+
+	buf = addr & MASK_8BIT;
+
+	mutex_lock(&(rmi4_data->rmi4_io_ctrl_mutex));
+
+	retval = synaptics_rmi4_set_page(rmi4_data, addr);
+	if (retval != PAGE_SELECT_LEN)
+		goto exit;
+
+	for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) {
+		if (i2c_transfer(rmi4_data->i2c_client->adapter, msg, 2) == 2) {
+			retval = length;
+			break;
+		}
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: I2C retry %d\n",
+				__func__, retry + 1);
+		msleep(20);
+	}
+
+	if (retry == SYN_I2C_RETRY_TIMES) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: I2C read over retry limit\n",
+				__func__);
+		retval = -EIO;
+	}
+
+exit:
+	mutex_unlock(&(rmi4_data->rmi4_io_ctrl_mutex));
+
+	return retval;
+}
+
+ /**
+ * synaptics_rmi4_i2c_write()
+ *
+ * Called by various functions in this driver, and also exported to
+ * other expansion Function modules such as rmi_dev.
+ *
+ * This function writes data of an arbitrary length to the sensor,
+ * starting from an assigned register address of the sensor, via I2C with
+ * a retry mechanism.
+ */
+static int synaptics_rmi4_i2c_write(struct synaptics_rmi4_data *rmi4_data,
+		unsigned short addr, unsigned char *data, unsigned short length)
+{
+	int retval;
+	unsigned char retry;
+	unsigned char buf[length + 1];
+	struct i2c_msg msg[] = {
+		{
+			.addr = rmi4_data->i2c_client->addr,
+			.flags = 0,
+			.len = length + 1,
+			.buf = buf,
+		}
+	};
+
+	mutex_lock(&(rmi4_data->rmi4_io_ctrl_mutex));
+
+	retval = synaptics_rmi4_set_page(rmi4_data, addr);
+	if (retval != PAGE_SELECT_LEN)
+		goto exit;
+
+	buf[0] = addr & MASK_8BIT;
+	memcpy(&buf[1], &data[0], length);
+
+	for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) {
+		if (i2c_transfer(rmi4_data->i2c_client->adapter, msg, 1) == 1) {
+			retval = length;
+			break;
+		}
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: I2C retry %d\n",
+				__func__, retry + 1);
+		msleep(20);
+	}
+
+	if (retry == SYN_I2C_RETRY_TIMES) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: I2C write over retry limit\n",
+				__func__);
+		retval = -EIO;
+	}
+
+exit:
+	mutex_unlock(&(rmi4_data->rmi4_io_ctrl_mutex));
+
+	return retval;
+}
+
+ /**
+ * synaptics_rmi4_f11_abs_report()
+ *
+ * Called by synaptics_rmi4_report_touch() when valid Function $11
+ * finger data has been detected.
+ *
+ * This function reads the Function $11 data registers, determines the
+ * status of each finger supported by the Function, processes any
+ * necessary coordinate manipulation, reports the finger data to
+ * the input subsystem, and returns the number of fingers detected.
+ */
+static int synaptics_rmi4_f11_abs_report(struct synaptics_rmi4_data *rmi4_data,
+		struct synaptics_rmi4_fn *fhandler)
+{
+	int retval;
+	unsigned char touch_count = 0; /* number of touch points */
+	unsigned char reg_index;
+	unsigned char finger;
+	unsigned char fingers_supported;
+	unsigned char num_of_finger_status_regs;
+	unsigned char finger_shift;
+	unsigned char finger_status;
+	unsigned char data_reg_blk_size;
+	unsigned char finger_status_reg[3];
+	unsigned char data[F11_STD_DATA_LEN];
+	unsigned short data_addr;
+	unsigned short data_offset;
+	int x;
+	int y;
+	int wx;
+	int wy;
+
+	/*
+	 * The number of finger status registers is determined by the
+	 * maximum number of fingers supported - 2 bits per finger. So
+	 * the number of finger status registers to read is:
+	 * register_count = ceil(max_num_of_fingers / 4)
+	 */
+	fingers_supported = fhandler->num_of_data_points;
+	num_of_finger_status_regs = (fingers_supported + 3) / 4;
+	data_addr = fhandler->full_addr.data_base;
+	data_reg_blk_size = fhandler->size_of_data_register_block;
+
+	retval = synaptics_rmi4_i2c_read(rmi4_data,
+			data_addr,
+			finger_status_reg,
+			num_of_finger_status_regs);
+	if (retval < 0)
+		return 0;
+
+	for (finger = 0; finger < fingers_supported; finger++) {
+		reg_index = finger / 4;
+		finger_shift = (finger % 4) * 2;
+		finger_status = (finger_status_reg[reg_index] >> finger_shift)
+				& MASK_2BIT;
+
+		/*
+		 * Each 2-bit finger status field represents the following:
+		 * 00 = finger not present
+		 * 01 = finger present and data accurate
+		 * 10 = finger present but data may be inaccurate
+		 * 11 = reserved
+		 */
+#ifdef TYPE_B_PROTOCOL
+		input_mt_slot(rmi4_data->input_dev, finger);
+		input_mt_report_slot_state(rmi4_data->input_dev,
+				MT_TOOL_FINGER, finger_status != 0);
+#endif
+
+		if (finger_status) {
+			data_offset = data_addr +
+					num_of_finger_status_regs +
+					(finger * data_reg_blk_size);
+			retval = synaptics_rmi4_i2c_read(rmi4_data,
+					data_offset,
+					data,
+					data_reg_blk_size);
+			if (retval < 0)
+				return 0;
+
+			x = (data[0] << 4) | (data[2] & MASK_4BIT);
+			y = (data[1] << 4) | ((data[2] >> 4) & MASK_4BIT);
+			wx = (data[3] & MASK_4BIT);
+			wy = (data[3] >> 4) & MASK_4BIT;
+
+			if (rmi4_data->board->x_flip)
+				x = rmi4_data->sensor_max_x - x;
+			if (rmi4_data->board->y_flip)
+				y = rmi4_data->sensor_max_y - y;
+
+			dev_dbg(&rmi4_data->i2c_client->dev,
+					"%s: Finger %d:\n"
+					"status = 0x%02x\n"
+					"x = %d\n"
+					"y = %d\n"
+					"wx = %d\n"
+					"wy = %d\n",
+					__func__, finger,
+					finger_status,
+					x, y, wx, wy);
+
+			input_report_key(rmi4_data->input_dev,
+					BTN_TOUCH, 1);
+			input_report_key(rmi4_data->input_dev,
+					BTN_TOOL_FINGER, 1);
+			input_report_abs(rmi4_data->input_dev,
+					ABS_MT_POSITION_X, x);
+			input_report_abs(rmi4_data->input_dev,
+					ABS_MT_POSITION_Y, y);
+
+#ifdef REPORT_2D_W
+			input_report_abs(rmi4_data->input_dev,
+					ABS_MT_TOUCH_MAJOR, max(wx, wy));
+			input_report_abs(rmi4_data->input_dev,
+					ABS_MT_TOUCH_MINOR, min(wx, wy));
+#endif
+#ifndef TYPE_B_PROTOCOL
+			input_mt_sync(rmi4_data->input_dev);
+#endif
+			touch_count++;
+		}
+	}
+
+#ifndef TYPE_B_PROTOCOL
+	if (!touch_count)
+		input_mt_sync(rmi4_data->input_dev);
+#else
+	/* sync after groups of events */
+	#ifdef KERNEL_ABOVE_3_7
+	input_mt_sync_frame(rmi4_data->input_dev);
+	#endif
+#endif
+
+	input_sync(rmi4_data->input_dev);
+
+	return touch_count;
+}
+
+static void synaptics_rmi4_f1a_report(struct synaptics_rmi4_data *rmi4_data,
+		struct synaptics_rmi4_fn *fhandler)
+{
+	int retval;
+	unsigned char button;
+	unsigned char index;
+	unsigned char shift;
+	unsigned char status;
+	unsigned char *data;
+	unsigned short data_addr = fhandler->full_addr.data_base;
+	struct synaptics_rmi4_f1a_handle *f1a = fhandler->data;
+	static unsigned char do_once = 1;
+	static bool current_status[MAX_NUMBER_OF_BUTTONS];
+#ifdef NO_0D_WHILE_2D
+	static bool before_2d_status[MAX_NUMBER_OF_BUTTONS];
+	static bool while_2d_status[MAX_NUMBER_OF_BUTTONS];
+#endif
+
+	if (do_once) {
+		memset(current_status, 0, sizeof(current_status));
+#ifdef NO_0D_WHILE_2D
+		memset(before_2d_status, 0, sizeof(before_2d_status));
+		memset(while_2d_status, 0, sizeof(while_2d_status));
+#endif
+		do_once = 0;
+	}
+
+	retval = synaptics_rmi4_i2c_read(rmi4_data,
+			data_addr,
+			f1a->button_data_buffer,
+			f1a->button_bitmask_size);
+	if (retval < 0) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to read button data registers\n",
+				__func__);
+		return;
+	}
+
+	data = f1a->button_data_buffer;
+
+	for (button = 0; button < f1a->valid_button_count; button++) {
+		index = button / 8;
+		shift = button % 8;
+		status = ((data[index] >> shift) & MASK_1BIT);
+
+		if (current_status[button] == status)
+			continue;
+		else
+			current_status[button] = status;
+
+		dev_dbg(&rmi4_data->i2c_client->dev,
+				"%s: Button %d (code %d) ->%d\n",
+				__func__, button,
+				f1a->button_map[button],
+				status);
+#ifdef NO_0D_WHILE_2D
+		if (rmi4_data->fingers_on_2d == false) {
+			if (status == 1) {
+				before_2d_status[button] = 1;
+			} else {
+				if (while_2d_status[button] == 1) {
+					while_2d_status[button] = 0;
+					continue;
+				} else {
+					before_2d_status[button] = 0;
+				}
+			}
+			input_report_key(rmi4_data->input_dev,
+					f1a->button_map[button],
+					status);
+		} else {
+			if (before_2d_status[button] == 1) {
+				before_2d_status[button] = 0;
+				input_report_key(rmi4_data->input_dev,
+						f1a->button_map[button],
+						status);
+			} else {
+				if (status == 1)
+					while_2d_status[button] = 1;
+				else
+					while_2d_status[button] = 0;
+			}
+		}
+#else
+		input_report_key(rmi4_data->input_dev,
+				f1a->button_map[button],
+				status);
+#endif
+	}
+
+	input_sync(rmi4_data->input_dev);
+
+	return;
+}
+
+ /**
+ * synaptics_rmi4_report_touch()
+ *
+ * Called by synaptics_rmi4_sensor_report().
+ *
+ * This function calls the appropriate finger data reporting function
+ * based on the function handler it receives and returns the number of
+ * fingers detected.
+ */
+static void synaptics_rmi4_report_touch(struct synaptics_rmi4_data *rmi4_data,
+		struct synaptics_rmi4_fn *fhandler,
+		unsigned char *touch_count)
+{
+	unsigned char touch_count_2d;
+
+	dev_dbg(&rmi4_data->i2c_client->dev,
+			"%s: Function %02x reporting\n",
+			__func__, fhandler->fn_number);
+
+	switch (fhandler->fn_number) {
+	case SYNAPTICS_RMI4_F11:
+		touch_count_2d = synaptics_rmi4_f11_abs_report(rmi4_data,
+				fhandler);
+
+		*touch_count += touch_count_2d;
+
+		if (touch_count_2d)
+			rmi4_data->fingers_on_2d = true;
+		else
+			rmi4_data->fingers_on_2d = false;
+		break;
+
+	case SYNAPTICS_RMI4_F1A:
+		synaptics_rmi4_f1a_report(rmi4_data, fhandler);
+		break;
+
+	default:
+		break;
+	}
+
+	return;
+}
+
+ /**
+ * synaptics_rmi4_sensor_report()
+ *
+ * Called by synaptics_rmi4_irq().
+ *
+ * This function determines the interrupt source(s) from the sensor
+ * and calls synaptics_rmi4_report_touch() with the appropriate
+ * function handler for each function with valid data inputs.
+ */
+static int synaptics_rmi4_sensor_report(struct synaptics_rmi4_data *rmi4_data)
+{
+	int retval;
+	unsigned char touch_count = 0;
+	unsigned char intr[MAX_INTR_REGISTERS];
+	struct synaptics_rmi4_fn *fhandler;
+	struct synaptics_rmi4_exp_fn *exp_fhandler;
+	struct synaptics_rmi4_device_info *rmi;
+
+	rmi = &(rmi4_data->rmi4_mod_info);
+
+	/*
+	 * Get interrupt status information from F01 Data1 register to
+	 * determine the source(s) that are flagging the interrupt.
+	 */
+	retval = synaptics_rmi4_i2c_read(rmi4_data,
+			rmi4_data->f01_data_base_addr + 1,
+			intr,
+			rmi4_data->num_of_intr_regs);
+	if (retval < 0)
+		return retval;
+
+	/*
+	 * Traverse the function handler list and service the source(s)
+	 * of the interrupt accordingly.
+	 */
+	if (!list_empty(&rmi->support_fn_list)) {
+		list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
+			if (fhandler->num_of_data_sources) {
+				if (fhandler->intr_mask &
+						intr[fhandler->intr_reg_num]) {
+					synaptics_rmi4_report_touch(rmi4_data,
+							fhandler, &touch_count);
+				}
+			}
+		}
+	}
+
+	mutex_lock(&exp_fn_list_mutex);
+	if (!list_empty(&exp_fn_list)) {
+		list_for_each_entry(exp_fhandler, &exp_fn_list, link) {
+			if (exp_fhandler->inserted &&
+					(exp_fhandler->func_attn != NULL))
+				exp_fhandler->func_attn(rmi4_data, intr[0]);
+		}
+	}
+	mutex_unlock(&exp_fn_list_mutex);
+
+	return touch_count;
+}
+
+ /**
+ * synaptics_rmi4_irq()
+ *
+ * Called by the kernel when an interrupt occurs (when the sensor
+ * asserts the attention irq).
+ *
+ * This function is the ISR thread and handles the acquisition
+ * and the reporting of finger data when the presence of fingers
+ * is detected.
+ */
+static irqreturn_t synaptics_rmi4_irq(int irq, void *data)
+{
+	struct synaptics_rmi4_data *rmi4_data = data;
+
+	synaptics_rmi4_sensor_report(rmi4_data);
+
+	return IRQ_HANDLED;
+}
+
+ /**
+ * synaptics_rmi4_irq_enable()
+ *
+ * Called by synaptics_rmi4_probe() and the power management functions
+ * in this driver and also exported to other expansion Function modules
+ * such as rmi_dev.
+ *
+ * This function handles the enabling and disabling of the attention
+ * irq including the setting up of the ISR thread.
+ */
+static int synaptics_rmi4_irq_enable(struct synaptics_rmi4_data *rmi4_data,
+		bool enable)
+{
+	int retval = 0;
+	unsigned char intr_status;
+	const struct synaptics_rmi4_platform_data *platform_data =
+			rmi4_data->i2c_client->dev.platform_data;
+
+	if (enable) {
+		if (rmi4_data->irq_enabled)
+			return retval;
+
+		/* Clear interrupts first */
+		retval = synaptics_rmi4_i2c_read(rmi4_data,
+				rmi4_data->f01_data_base_addr + 1,
+				&intr_status,
+				rmi4_data->num_of_intr_regs);
+		if (retval < 0)
+			return retval;
+
+		retval = request_threaded_irq(rmi4_data->irq, NULL,
+				synaptics_rmi4_irq, platform_data->irq_flags,
+				DRIVER_NAME, rmi4_data);
+		if (retval < 0) {
+			dev_err(&rmi4_data->i2c_client->dev,
+					"%s: Failed to create irq thread\n",
+					__func__);
+			return retval;
+		}
+
+		rmi4_data->irq_enabled = true;
+	} else {
+		if (rmi4_data->irq_enabled) {
+			disable_irq(rmi4_data->irq);
+			free_irq(rmi4_data->irq, rmi4_data);
+			rmi4_data->irq_enabled = false;
+		}
+	}
+
+	return retval;
+}
+
+ /**
+ * synaptics_rmi4_f11_init()
+ *
+ * Called by synaptics_rmi4_query_device().
+ *
+ * This funtion parses information from the Function 11 registers
+ * and determines the number of fingers supported, x and y data ranges,
+ * offset to the associated interrupt status register, interrupt bit
+ * mask, and gathers finger data acquisition capabilities from the query
+ * registers.
+ */
+static int synaptics_rmi4_f11_init(struct synaptics_rmi4_data *rmi4_data,
+		struct synaptics_rmi4_fn *fhandler,
+		struct synaptics_rmi4_fn_desc *fd,
+		unsigned int intr_count)
+{
+	int retval;
+	unsigned char ii;
+	unsigned char intr_offset;
+	unsigned char abs_data_size;
+	unsigned char abs_data_blk_size;
+	unsigned char query[F11_STD_QUERY_LEN];
+	unsigned char control[F11_STD_CTRL_LEN];
+
+	fhandler->fn_number = fd->fn_number;
+	fhandler->num_of_data_sources = fd->intr_src_count;
+
+	retval = synaptics_rmi4_i2c_read(rmi4_data,
+			fhandler->full_addr.query_base,
+			query,
+			sizeof(query));
+	if (retval < 0)
+		return retval;
+
+	/* Maximum number of fingers supported */
+	if ((query[1] & MASK_3BIT) <= 4)
+		fhandler->num_of_data_points = (query[1] & MASK_3BIT) + 1;
+	else if ((query[1] & MASK_3BIT) == 5)
+		fhandler->num_of_data_points = 10;
+
+	rmi4_data->num_of_fingers = fhandler->num_of_data_points;
+
+	retval = synaptics_rmi4_i2c_read(rmi4_data,
+			fhandler->full_addr.ctrl_base,
+			control,
+			sizeof(control));
+	if (retval < 0)
+		return retval;
+
+	/* Maximum x and y */
+	rmi4_data->sensor_max_x = ((control[6] & MASK_8BIT) << 0) |
+			((control[7] & MASK_4BIT) << 8);
+	rmi4_data->sensor_max_y = ((control[8] & MASK_8BIT) << 0) |
+			((control[9] & MASK_4BIT) << 8);
+	dev_dbg(&rmi4_data->i2c_client->dev,
+			"%s: Function %02x max x = %d max y = %d\n",
+			__func__, fhandler->fn_number,
+			rmi4_data->sensor_max_x,
+			rmi4_data->sensor_max_y);
+
+	fhandler->intr_reg_num = (intr_count + 7) / 8;
+	if (fhandler->intr_reg_num != 0)
+		fhandler->intr_reg_num -= 1;
+
+	/* Set an enable bit for each data source */
+	intr_offset = intr_count % 8;
+	fhandler->intr_mask = 0;
+	for (ii = intr_offset;
+			ii < ((fd->intr_src_count & MASK_3BIT) +
+			intr_offset);
+			ii++)
+		fhandler->intr_mask |= 1 << ii;
+
+	abs_data_size = query[5] & MASK_2BIT;
+	abs_data_blk_size = 3 + (2 * (abs_data_size == 0 ? 1 : 0));
+	fhandler->size_of_data_register_block = abs_data_blk_size;
+
+	return retval;
+}
+
+static int synaptics_rmi4_f1a_alloc_mem(struct synaptics_rmi4_data *rmi4_data,
+		struct synaptics_rmi4_fn *fhandler)
+{
+	int retval;
+	struct synaptics_rmi4_f1a_handle *f1a;
+
+	f1a = kzalloc(sizeof(*f1a), GFP_KERNEL);
+	if (!f1a) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to alloc mem for function handle\n",
+				__func__);
+		return -ENOMEM;
+	}
+
+	fhandler->data = (void *)f1a;
+
+	retval = synaptics_rmi4_i2c_read(rmi4_data,
+			fhandler->full_addr.query_base,
+			f1a->button_query.data,
+			sizeof(f1a->button_query.data));
+	if (retval < 0) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to read query registers\n",
+				__func__);
+		return retval;
+	}
+
+	f1a->button_count = f1a->button_query.max_button_count + 1;
+	f1a->button_bitmask_size = (f1a->button_count + 7) / 8;
+
+	f1a->button_data_buffer = kcalloc(f1a->button_bitmask_size,
+			sizeof(*(f1a->button_data_buffer)), GFP_KERNEL);
+	if (!f1a->button_data_buffer) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to alloc mem for data buffer\n",
+				__func__);
+		return -ENOMEM;
+	}
+
+	f1a->button_map = kcalloc(f1a->button_count,
+			sizeof(*(f1a->button_map)), GFP_KERNEL);
+	if (!f1a->button_map) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to alloc mem for button map\n",
+				__func__);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static int synaptics_rmi4_capacitance_button_map(
+				struct synaptics_rmi4_data *rmi4_data,
+				struct synaptics_rmi4_fn *fhandler)
+{
+	unsigned char ii;
+	struct synaptics_rmi4_f1a_handle *f1a = fhandler->data;
+	const struct synaptics_rmi4_platform_data *pdata = rmi4_data->board;
+
+	if (!pdata->capacitance_button_map) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: capacitance_button_map is" \
+				"NULL in board file\n",
+				__func__);
+		return -ENODEV;
+	} else if (!pdata->capacitance_button_map->map) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Button map is missing in board file\n",
+				__func__);
+		return -ENODEV;
+	} else {
+		if (pdata->capacitance_button_map->nbuttons !=
+			f1a->button_count) {
+			f1a->valid_button_count = min(f1a->button_count,
+				pdata->capacitance_button_map->nbuttons);
+		} else {
+			f1a->valid_button_count = f1a->button_count;
+		}
+
+		for (ii = 0; ii < f1a->valid_button_count; ii++)
+			f1a->button_map[ii] =
+					pdata->capacitance_button_map->map[ii];
+	}
+
+	return 0;
+}
+
+static void synaptics_rmi4_f1a_kfree(struct synaptics_rmi4_fn *fhandler)
+{
+	struct synaptics_rmi4_f1a_handle *f1a = fhandler->data;
+
+	if (f1a) {
+		kfree(f1a->button_data_buffer);
+		kfree(f1a->button_map);
+		kfree(f1a);
+		fhandler->data = NULL;
+	}
+
+	return;
+}
+
+static int synaptics_rmi4_f1a_init(struct synaptics_rmi4_data *rmi4_data,
+		struct synaptics_rmi4_fn *fhandler,
+		struct synaptics_rmi4_fn_desc *fd,
+		unsigned int intr_count)
+{
+	int retval;
+	unsigned char ii;
+	unsigned short intr_offset;
+
+	fhandler->fn_number = fd->fn_number;
+	fhandler->num_of_data_sources = fd->intr_src_count;
+
+	fhandler->intr_reg_num = (intr_count + 7) / 8;
+	if (fhandler->intr_reg_num != 0)
+		fhandler->intr_reg_num -= 1;
+
+	/* Set an enable bit for each data source */
+	intr_offset = intr_count % 8;
+	fhandler->intr_mask = 0;
+	for (ii = intr_offset;
+			ii < ((fd->intr_src_count & MASK_3BIT) +
+			intr_offset);
+			ii++)
+		fhandler->intr_mask |= 1 << ii;
+
+	retval = synaptics_rmi4_f1a_alloc_mem(rmi4_data, fhandler);
+	if (retval < 0)
+		goto error_exit;
+
+	retval = synaptics_rmi4_capacitance_button_map(rmi4_data, fhandler);
+	if (retval < 0)
+		goto error_exit;
+
+	rmi4_data->button_0d_enabled = 1;
+
+	return 0;
+
+error_exit:
+	synaptics_rmi4_f1a_kfree(fhandler);
+
+	return retval;
+}
+
+static int synaptics_rmi4_alloc_fh(struct synaptics_rmi4_fn **fhandler,
+		struct synaptics_rmi4_fn_desc *rmi_fd, int page_number)
+{
+	*fhandler = kmalloc(sizeof(**fhandler), GFP_KERNEL);
+	if (!(*fhandler))
+		return -ENOMEM;
+
+	(*fhandler)->full_addr.data_base =
+			(rmi_fd->data_base_addr |
+			(page_number << 8));
+	(*fhandler)->full_addr.ctrl_base =
+			(rmi_fd->ctrl_base_addr |
+			(page_number << 8));
+	(*fhandler)->full_addr.cmd_base =
+			(rmi_fd->cmd_base_addr |
+			(page_number << 8));
+	(*fhandler)->full_addr.query_base =
+			(rmi_fd->query_base_addr |
+			(page_number << 8));
+
+	return 0;
+}
+
+
+ /**
+ * synaptics_rmi4_query_device_info()
+ *
+ * Called by synaptics_rmi4_query_device().
+ *
+ */
+static int synaptics_rmi4_query_device_info(
+					struct synaptics_rmi4_data *rmi4_data)
+{
+	int retval;
+	unsigned char f01_query[F01_STD_QUERY_LEN];
+	struct synaptics_rmi4_device_info *rmi = &(rmi4_data->rmi4_mod_info);
+
+	retval = synaptics_rmi4_i2c_read(rmi4_data,
+			rmi4_data->f01_query_base_addr,
+			f01_query,
+			sizeof(f01_query));
+	if (retval < 0)
+		return retval;
+
+	/* RMI Version 4.0 currently supported */
+	rmi->version_major = 4;
+	rmi->version_minor = 0;
+
+	rmi->manufacturer_id = f01_query[0];
+	rmi->product_props = f01_query[1];
+	rmi->product_info[0] = f01_query[2] & MASK_7BIT;
+	rmi->product_info[1] = f01_query[3] & MASK_7BIT;
+	rmi->date_code[0] = f01_query[4] & MASK_5BIT;
+	rmi->date_code[1] = f01_query[5] & MASK_4BIT;
+	rmi->date_code[2] = f01_query[6] & MASK_5BIT;
+	rmi->tester_id = ((f01_query[7] & MASK_7BIT) << 8) |
+			(f01_query[8] & MASK_7BIT);
+	rmi->serial_number = ((f01_query[9] & MASK_7BIT) << 8) |
+			(f01_query[10] & MASK_7BIT);
+	memcpy(rmi->product_id_string, &f01_query[11], 10);
+
+	if (rmi->manufacturer_id != 1) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Non-Synaptics device found, manufacturer ID = %d\n",
+				__func__, rmi->manufacturer_id);
+	}
+
+	retval = synaptics_rmi4_i2c_read(rmi4_data,
+			rmi4_data->f01_query_base_addr + F01_BUID_ID_OFFSET,
+			rmi->build_id,
+			sizeof(rmi->build_id));
+	if (retval < 0) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to read firmware build id (code %d)\n",
+				__func__, retval);
+		return retval;
+	}
+	return retval;
+}
+
+ /**
+ * synaptics_rmi4_query_device()
+ *
+ * Called by synaptics_rmi4_probe().
+ *
+ * This funtion scans the page description table, records the offsets
+ * to the register types of Function $01, sets up the function handlers
+ * for Function $11 and Function $12, determines the number of interrupt
+ * sources from the sensor, adds valid Functions with data inputs to the
+ * Function linked list, parses information from the query registers of
+ * Function $01, and enables the interrupt sources from the valid Functions
+ * with data inputs.
+ */
+static int synaptics_rmi4_query_device(struct synaptics_rmi4_data *rmi4_data)
+{
+	int retval;
+	unsigned char ii;
+	unsigned char page_number;
+	unsigned char intr_count = 0;
+	unsigned char data_sources = 0;
+	unsigned short pdt_entry_addr;
+	unsigned short intr_addr;
+	struct synaptics_rmi4_f01_device_status status;
+	struct synaptics_rmi4_fn_desc rmi_fd;
+	struct synaptics_rmi4_fn *fhandler;
+	struct synaptics_rmi4_device_info *rmi;
+
+	rmi = &(rmi4_data->rmi4_mod_info);
+
+	INIT_LIST_HEAD(&rmi->support_fn_list);
+
+	/* Scan the page description tables of the pages to service */
+	for (page_number = 0; page_number < PAGES_TO_SERVICE; page_number++) {
+		for (pdt_entry_addr = PDT_START; pdt_entry_addr > PDT_END;
+				pdt_entry_addr -= PDT_ENTRY_SIZE) {
+			pdt_entry_addr |= (page_number << 8);
+
+			retval = synaptics_rmi4_i2c_read(rmi4_data,
+					pdt_entry_addr,
+					(unsigned char *)&rmi_fd,
+					sizeof(rmi_fd));
+			if (retval < 0)
+				return retval;
+
+			fhandler = NULL;
+
+			if (rmi_fd.fn_number == 0) {
+				dev_dbg(&rmi4_data->i2c_client->dev,
+						"%s: Reached end of PDT\n",
+						__func__);
+				break;
+			}
+
+			dev_dbg(&rmi4_data->i2c_client->dev,
+					"%s: F%02x found (page %d)\n",
+					__func__, rmi_fd.fn_number,
+					page_number);
+
+			switch (rmi_fd.fn_number) {
+			case SYNAPTICS_RMI4_F01:
+				rmi4_data->f01_query_base_addr =
+						rmi_fd.query_base_addr;
+				rmi4_data->f01_ctrl_base_addr =
+						rmi_fd.ctrl_base_addr;
+				rmi4_data->f01_data_base_addr =
+						rmi_fd.data_base_addr;
+				rmi4_data->f01_cmd_base_addr =
+						rmi_fd.cmd_base_addr;
+
+				retval =
+				synaptics_rmi4_query_device_info(rmi4_data);
+				if (retval < 0)
+					return retval;
+
+				retval = synaptics_rmi4_i2c_read(rmi4_data,
+						rmi4_data->f01_data_base_addr,
+						status.data,
+						sizeof(status.data));
+				if (retval < 0)
+					return retval;
+
+				if (status.flash_prog == 1) {
+					pr_notice("%s: In flash prog mode, status = 0x%02x\n",
+							__func__,
+							status.status_code);
+					goto flash_prog_mode;
+				}
+				break;
+
+			case SYNAPTICS_RMI4_F34:
+				retval = synaptics_rmi4_i2c_read(rmi4_data,
+						rmi_fd.ctrl_base_addr,
+						rmi->config_id,
+						sizeof(rmi->config_id));
+				if (retval < 0)
+					return retval;
+				break;
+
+			case SYNAPTICS_RMI4_F11:
+				if (rmi_fd.intr_src_count == 0)
+					break;
+
+				retval = synaptics_rmi4_alloc_fh(&fhandler,
+						&rmi_fd, page_number);
+				if (retval < 0) {
+					dev_err(&rmi4_data->i2c_client->dev,
+							"%s: Failed to alloc for F%d\n",
+							__func__,
+							rmi_fd.fn_number);
+					return retval;
+				}
+
+				retval = synaptics_rmi4_f11_init(rmi4_data,
+						fhandler, &rmi_fd, intr_count);
+				if (retval < 0)
+					return retval;
+				break;
+
+			case SYNAPTICS_RMI4_F1A:
+				if (rmi_fd.intr_src_count == 0)
+					break;
+
+				retval = synaptics_rmi4_alloc_fh(&fhandler,
+						&rmi_fd, page_number);
+				if (retval < 0) {
+					dev_err(&rmi4_data->i2c_client->dev,
+							"%s: Failed to alloc for F%d\n",
+							__func__,
+							rmi_fd.fn_number);
+					return retval;
+				}
+
+				retval = synaptics_rmi4_f1a_init(rmi4_data,
+						fhandler, &rmi_fd, intr_count);
+				if (retval < 0)
+					return retval;
+				break;
+			}
+
+			/* Accumulate the interrupt count */
+			intr_count += (rmi_fd.intr_src_count & MASK_3BIT);
+
+			if (fhandler && rmi_fd.intr_src_count) {
+				list_add_tail(&fhandler->link,
+						&rmi->support_fn_list);
+			}
+		}
+	}
+
+flash_prog_mode:
+	rmi4_data->num_of_intr_regs = (intr_count + 7) / 8;
+	dev_dbg(&rmi4_data->i2c_client->dev,
+			"%s: Number of interrupt registers = %d\n",
+			__func__, rmi4_data->num_of_intr_regs);
+
+	memset(rmi4_data->intr_mask, 0x00, sizeof(rmi4_data->intr_mask));
+
+	/*
+	 * Map out the interrupt bit masks for the interrupt sources
+	 * from the registered function handlers.
+	 */
+	if (!list_empty(&rmi->support_fn_list)) {
+		list_for_each_entry(fhandler, &rmi->support_fn_list, link)
+			data_sources += fhandler->num_of_data_sources;
+	}
+	if (data_sources) {
+		if (!list_empty(&rmi->support_fn_list)) {
+			list_for_each_entry(fhandler,
+						&rmi->support_fn_list, link) {
+				if (fhandler->num_of_data_sources) {
+					rmi4_data->intr_mask[fhandler->intr_reg_num] |=
+							fhandler->intr_mask;
+				}
+			}
+		}
+	}
+
+	/* Enable the interrupt sources */
+	for (ii = 0; ii < rmi4_data->num_of_intr_regs; ii++) {
+		if (rmi4_data->intr_mask[ii] != 0x00) {
+			dev_dbg(&rmi4_data->i2c_client->dev,
+					"%s: Interrupt enable mask %d = 0x%02x\n",
+					__func__, ii, rmi4_data->intr_mask[ii]);
+			intr_addr = rmi4_data->f01_ctrl_base_addr + 1 + ii;
+			retval = synaptics_rmi4_i2c_write(rmi4_data,
+					intr_addr,
+					&(rmi4_data->intr_mask[ii]),
+					sizeof(rmi4_data->intr_mask[ii]));
+			if (retval < 0)
+				return retval;
+		}
+	}
+
+	return 0;
+}
+
+static int synaptics_rmi4_reset_device(struct synaptics_rmi4_data *rmi4_data)
+{
+	int retval;
+	unsigned char command = 0x01;
+	struct synaptics_rmi4_fn *fhandler;
+	struct synaptics_rmi4_device_info *rmi;
+
+	rmi = &(rmi4_data->rmi4_mod_info);
+
+	retval = synaptics_rmi4_i2c_write(rmi4_data,
+			rmi4_data->f01_cmd_base_addr,
+			&command,
+			sizeof(command));
+	if (retval < 0) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to issue reset command, error = %d\n",
+				__func__, retval);
+		return retval;
+	}
+
+	msleep(100);
+
+	if (!list_empty(&rmi->support_fn_list)) {
+		list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
+			if (fhandler->fn_number == SYNAPTICS_RMI4_F1A)
+				synaptics_rmi4_f1a_kfree(fhandler);
+			else
+				kfree(fhandler->data);
+			kfree(fhandler);
+		}
+	}
+
+	retval = synaptics_rmi4_query_device(rmi4_data);
+	if (retval < 0) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to query device\n",
+				__func__);
+		return retval;
+	}
+
+	return 0;
+}
+
+/**
+* synaptics_rmi4_detection_work()
+*
+* Called by the kernel at the scheduled time.
+*
+* This function is a self-rearming work thread that checks for the
+* insertion and removal of other expansion Function modules such as
+* rmi_dev and calls their initialization and removal callback functions
+* accordingly.
+*/
+static void synaptics_rmi4_detection_work(struct work_struct *work)
+{
+	struct synaptics_rmi4_exp_fn *exp_fhandler, *next_list_entry;
+	struct synaptics_rmi4_data *rmi4_data =
+			container_of(work, struct synaptics_rmi4_data,
+			det_work.work);
+
+	mutex_lock(&exp_fn_list_mutex);
+	if (!list_empty(&exp_fn_list)) {
+		list_for_each_entry_safe(exp_fhandler,
+				next_list_entry,
+				&exp_fn_list,
+				link) {
+			if ((exp_fhandler->func_init != NULL) &&
+					(exp_fhandler->inserted == false)) {
+				exp_fhandler->func_init(rmi4_data);
+				exp_fhandler->inserted = true;
+			} else if ((exp_fhandler->func_init == NULL) &&
+					(exp_fhandler->inserted == true)) {
+				exp_fhandler->func_remove(rmi4_data);
+				list_del(&exp_fhandler->link);
+				kfree(exp_fhandler);
+			}
+		}
+	}
+	mutex_unlock(&exp_fn_list_mutex);
+
+	return;
+}
+
+/**
+* synaptics_rmi4_new_function()
+*
+* Called by other expansion Function modules in their module init and
+* module exit functions.
+*
+* This function is used by other expansion Function modules such as
+* rmi_dev to register themselves with the driver by providing their
+* initialization and removal callback function pointers so that they
+* can be inserted or removed dynamically at module init and exit times,
+* respectively.
+*/
+void synaptics_rmi4_new_function(enum exp_fn fn_type, bool insert,
+		int (*func_init)(struct synaptics_rmi4_data *rmi4_data),
+		void (*func_remove)(struct synaptics_rmi4_data *rmi4_data),
+		void (*func_attn)(struct synaptics_rmi4_data *rmi4_data,
+		unsigned char intr_mask))
+{
+	struct synaptics_rmi4_exp_fn *exp_fhandler;
+
+	if (!exp_fn_inited) {
+		mutex_init(&exp_fn_list_mutex);
+		INIT_LIST_HEAD(&exp_fn_list);
+		exp_fn_inited = 1;
+	}
+
+	mutex_lock(&exp_fn_list_mutex);
+	if (insert) {
+		exp_fhandler = kzalloc(sizeof(*exp_fhandler), GFP_KERNEL);
+		if (!exp_fhandler) {
+			pr_err("%s: Failed to alloc mem for expansion function\n",
+					__func__);
+			goto exit;
+		}
+		exp_fhandler->fn_type = fn_type;
+		exp_fhandler->func_init = func_init;
+		exp_fhandler->func_attn = func_attn;
+		exp_fhandler->func_remove = func_remove;
+		exp_fhandler->inserted = false;
+		list_add_tail(&exp_fhandler->link, &exp_fn_list);
+	} else {
+		if (!list_empty(&exp_fn_list)) {
+			list_for_each_entry(exp_fhandler, &exp_fn_list, link) {
+				if (exp_fhandler->func_init == func_init) {
+					exp_fhandler->inserted = false;
+					exp_fhandler->func_init = NULL;
+					exp_fhandler->func_attn = NULL;
+					goto exit;
+				}
+			}
+		}
+	}
+
+exit:
+	mutex_unlock(&exp_fn_list_mutex);
+
+	return;
+}
+EXPORT_SYMBOL(synaptics_rmi4_new_function);
+
+
+static int reg_set_optimum_mode_check(struct regulator *reg, int load_uA)
+{
+	return (regulator_count_voltages(reg) > 0) ?
+		regulator_set_optimum_mode(reg, load_uA) : 0;
+}
+
+static int synaptics_rmi4_regulator_configure(struct synaptics_rmi4_data
+						*rmi4_data, bool on)
+{
+	int retval;
+
+	if (on == false)
+		goto hw_shutdown;
+
+	if (rmi4_data->board->regulator_en) {
+		rmi4_data->vdd = regulator_get(&rmi4_data->i2c_client->dev,
+						"vdd");
+		if (IS_ERR(rmi4_data->vdd)) {
+			dev_err(&rmi4_data->i2c_client->dev,
+					"%s: Failed to get vdd regulator\n",
+					__func__);
+			return PTR_ERR(rmi4_data->vdd);
+		}
+
+		if (regulator_count_voltages(rmi4_data->vdd) > 0) {
+			retval = regulator_set_voltage(rmi4_data->vdd,
+				RMI4_VTG_MIN_UV, RMI4_VTG_MAX_UV);
+			if (retval) {
+				dev_err(&rmi4_data->i2c_client->dev,
+					"regulator set_vtg failed retval=%d\n",
+					retval);
+				goto err_set_vtg_vdd;
+			}
+		}
+	}
+
+	if (rmi4_data->board->i2c_pull_up) {
+		rmi4_data->vcc_i2c = regulator_get(&rmi4_data->i2c_client->dev,
+						"vcc_i2c");
+		if (IS_ERR(rmi4_data->vcc_i2c)) {
+			dev_err(&rmi4_data->i2c_client->dev,
+					"%s: Failed to get i2c regulator\n",
+					__func__);
+			retval = PTR_ERR(rmi4_data->vcc_i2c);
+			goto err_get_vtg_i2c;
+		}
+
+		if (regulator_count_voltages(rmi4_data->vcc_i2c) > 0) {
+			retval = regulator_set_voltage(rmi4_data->vcc_i2c,
+				RMI4_I2C_VTG_MIN_UV, RMI4_I2C_VTG_MAX_UV);
+			if (retval) {
+				dev_err(&rmi4_data->i2c_client->dev,
+					"reg set i2c vtg failed retval=%d\n",
+					retval);
+			goto err_set_vtg_i2c;
+			}
+		}
+	}
+
+err_set_vtg_i2c:
+	if (rmi4_data->board->i2c_pull_up)
+		regulator_put(rmi4_data->vcc_i2c);
+err_get_vtg_i2c:
+	if (rmi4_data->board->regulator_en)
+		if (regulator_count_voltages(rmi4_data->vdd) > 0)
+			regulator_set_voltage(rmi4_data->vdd, 0,
+				RMI4_VTG_MAX_UV);
+err_set_vtg_vdd:
+	if (rmi4_data->board->regulator_en)
+		regulator_put(rmi4_data->vdd);
+	return retval;
+
+hw_shutdown:
+	if (rmi4_data->board->regulator_en) {
+		if (regulator_count_voltages(rmi4_data->vdd) > 0)
+			regulator_set_voltage(rmi4_data->vdd, 0,
+				RMI4_VTG_MAX_UV);
+		regulator_put(rmi4_data->vdd);
+	}
+	if (rmi4_data->board->i2c_pull_up) {
+		if (regulator_count_voltages(rmi4_data->vcc_i2c) > 0)
+			regulator_set_voltage(rmi4_data->vcc_i2c, 0,
+					RMI4_I2C_VTG_MAX_UV);
+		regulator_put(rmi4_data->vcc_i2c);
+	}
+	return 0;
+};
+
+static int synaptics_rmi4_power_on(struct synaptics_rmi4_data *rmi4_data,
+					bool on) {
+	int retval;
+
+	if (on == false)
+		goto power_off;
+
+	if (rmi4_data->board->regulator_en) {
+		retval = reg_set_optimum_mode_check(rmi4_data->vdd,
+			RMI4_ACTIVE_LOAD_UA);
+		if (retval < 0) {
+			dev_err(&rmi4_data->i2c_client->dev,
+				"Regulator vdd set_opt failed rc=%d\n",
+				retval);
+			return retval;
+		}
+
+		retval = regulator_enable(rmi4_data->vdd);
+		if (retval) {
+			dev_err(&rmi4_data->i2c_client->dev,
+				"Regulator vdd enable failed rc=%d\n",
+				retval);
+			goto error_reg_en_vdd;
+		}
+	}
+
+	if (rmi4_data->board->i2c_pull_up) {
+		retval = reg_set_optimum_mode_check(rmi4_data->vcc_i2c,
+			RMI4_I2C_LOAD_UA);
+		if (retval < 0) {
+			dev_err(&rmi4_data->i2c_client->dev,
+				"Regulator vcc_i2c set_opt failed rc=%d\n",
+				retval);
+			goto error_reg_opt_i2c;
+		}
+
+		retval = regulator_enable(rmi4_data->vcc_i2c);
+		if (retval) {
+			dev_err(&rmi4_data->i2c_client->dev,
+				"Regulator vcc_i2c enable failed rc=%d\n",
+				retval);
+			goto error_reg_en_vcc_i2c;
+		}
+	}
+	return 0;
+
+error_reg_en_vcc_i2c:
+	if (rmi4_data->board->i2c_pull_up)
+		reg_set_optimum_mode_check(rmi4_data->vdd, 0);
+error_reg_opt_i2c:
+	if (rmi4_data->board->regulator_en)
+		regulator_disable(rmi4_data->vdd);
+error_reg_en_vdd:
+	if (rmi4_data->board->regulator_en)
+		reg_set_optimum_mode_check(rmi4_data->vdd, 0);
+	return retval;
+
+power_off:
+	if (rmi4_data->board->regulator_en) {
+		reg_set_optimum_mode_check(rmi4_data->vdd, 0);
+		regulator_disable(rmi4_data->vdd);
+	}
+	if (rmi4_data->board->i2c_pull_up) {
+		reg_set_optimum_mode_check(rmi4_data->vcc_i2c, 0);
+		regulator_disable(rmi4_data->vcc_i2c);
+	}
+	return 0;
+}
+
+ /**
+ * synaptics_rmi4_probe()
+ *
+ * Called by the kernel when an association with an I2C device of the
+ * same name is made (after doing i2c_add_driver).
+ *
+ * This funtion allocates and initializes the resources for the driver
+ * as an input driver, turns on the power to the sensor, queries the
+ * sensor for its supported Functions and characteristics, registers
+ * the driver to the input subsystem, sets up the interrupt, handles
+ * the registration of the early_suspend and late_resume functions,
+ * and creates a work queue for detection of other expansion Function
+ * modules.
+ */
+static int __devinit synaptics_rmi4_probe(struct i2c_client *client,
+		const struct i2c_device_id *dev_id)
+{
+	int retval = 0;
+	unsigned char ii;
+	unsigned char attr_count;
+	struct synaptics_rmi4_f1a_handle *f1a;
+	struct synaptics_rmi4_fn *fhandler;
+	struct synaptics_rmi4_data *rmi4_data;
+	struct synaptics_rmi4_device_info *rmi;
+	const struct synaptics_rmi4_platform_data *platform_data =
+			client->dev.platform_data;
+
+	if (!i2c_check_functionality(client->adapter,
+			I2C_FUNC_SMBUS_BYTE_DATA)) {
+		dev_err(&client->dev,
+				"%s: SMBus byte data not supported\n",
+				__func__);
+		return -EIO;
+	}
+
+	if (!platform_data) {
+		dev_err(&client->dev,
+				"%s: No platform data found\n",
+				__func__);
+		return -EINVAL;
+	}
+
+	rmi4_data = kzalloc(sizeof(*rmi4_data) * 2, GFP_KERNEL);
+	if (!rmi4_data) {
+		dev_err(&client->dev,
+				"%s: Failed to alloc mem for rmi4_data\n",
+				__func__);
+		return -ENOMEM;
+	}
+
+	rmi = &(rmi4_data->rmi4_mod_info);
+
+	rmi4_data->input_dev = input_allocate_device();
+	if (rmi4_data->input_dev == NULL) {
+		dev_err(&client->dev,
+				"%s: Failed to allocate input device\n",
+				__func__);
+		retval = -ENOMEM;
+		goto err_input_device;
+	}
+
+	rmi4_data->i2c_client = client;
+	rmi4_data->current_page = MASK_8BIT;
+	rmi4_data->board = platform_data;
+	rmi4_data->touch_stopped = false;
+	rmi4_data->sensor_sleep = false;
+	rmi4_data->irq_enabled = false;
+
+	rmi4_data->i2c_read = synaptics_rmi4_i2c_read;
+	rmi4_data->i2c_write = synaptics_rmi4_i2c_write;
+	rmi4_data->irq_enable = synaptics_rmi4_irq_enable;
+	rmi4_data->reset_device = synaptics_rmi4_reset_device;
+
+	rmi4_data->input_dev->name = DRIVER_NAME;
+	rmi4_data->input_dev->phys = INPUT_PHYS_NAME;
+	rmi4_data->input_dev->id.bustype = BUS_I2C;
+	rmi4_data->input_dev->id.product = SYNAPTICS_DSX_DRIVER_PRODUCT;
+	rmi4_data->input_dev->id.version = SYNAPTICS_DSX_DRIVER_VERSION;
+	rmi4_data->input_dev->dev.parent = &client->dev;
+	input_set_drvdata(rmi4_data->input_dev, rmi4_data);
+
+	set_bit(EV_SYN, rmi4_data->input_dev->evbit);
+	set_bit(EV_KEY, rmi4_data->input_dev->evbit);
+	set_bit(EV_ABS, rmi4_data->input_dev->evbit);
+	set_bit(BTN_TOUCH, rmi4_data->input_dev->keybit);
+	set_bit(BTN_TOOL_FINGER, rmi4_data->input_dev->keybit);
+
+#ifdef INPUT_PROP_DIRECT
+	set_bit(INPUT_PROP_DIRECT, rmi4_data->input_dev->propbit);
+#endif
+
+	input_set_abs_params(rmi4_data->input_dev,
+			ABS_MT_POSITION_X, 0,
+			rmi4_data->sensor_max_x, 0, 0);
+	input_set_abs_params(rmi4_data->input_dev,
+			ABS_MT_POSITION_Y, 0,
+			rmi4_data->sensor_max_y, 0, 0);
+#ifdef REPORT_2D_W
+	input_set_abs_params(rmi4_data->input_dev,
+			ABS_MT_TOUCH_MAJOR, 0,
+			MAX_ABS_MT_TOUCH_MAJOR, 0, 0);
+#endif
+
+#ifdef TYPE_B_PROTOCOL
+	input_mt_init_slots(rmi4_data->input_dev,
+			rmi4_data->num_of_fingers);
+#endif
+
+	retval = synaptics_rmi4_regulator_configure(rmi4_data, true);
+	if (retval < 0) {
+		dev_err(&client->dev, "Failed to configure regulators\n");
+		goto err_reg_configure;
+	}
+
+	retval = synaptics_rmi4_power_on(rmi4_data, true);
+	if (retval < 0) {
+		dev_err(&client->dev, "Failed to power on\n");
+		goto err_power_device;
+	}
+
+	if (gpio_is_valid(platform_data->irq_gpio)) {
+		/* configure touchscreen irq gpio */
+		retval = gpio_request(platform_data->irq_gpio, "rmi4_irq_gpio");
+		if (retval) {
+			dev_err(&client->dev, "unable to request gpio [%d]\n",
+						platform_data->irq_gpio);
+			goto err_query_device;
+		}
+		retval = gpio_direction_input(platform_data->irq_gpio);
+		if (retval) {
+			dev_err(&client->dev,
+				"unable to set direction for gpio [%d]\n",
+				platform_data->irq_gpio);
+			goto err_irq_gpio_req;
+		}
+	} else {
+		dev_err(&client->dev, "irq gpio not provided\n");
+		goto err_query_device;
+	}
+
+	if (gpio_is_valid(platform_data->reset_gpio)) {
+		/* configure touchscreen reset out gpio */
+		retval = gpio_request(platform_data->reset_gpio,
+				"rmi4_reset_gpio");
+		if (retval) {
+			dev_err(&client->dev, "unable to request gpio [%d]\n",
+						platform_data->reset_gpio);
+			goto err_irq_gpio_req;
+		}
+
+		retval = gpio_direction_output(platform_data->reset_gpio, 1);
+		if (retval) {
+			dev_err(&client->dev,
+				"unable to set direction for gpio [%d]\n",
+				platform_data->reset_gpio);
+			goto err_reset_gpio_req;
+		}
+
+		gpio_set_value(platform_data->reset_gpio, 0);
+		usleep(RMI4_GPIO_SLEEP_LOW_US);
+		gpio_set_value(platform_data->reset_gpio, 1);
+		msleep(RMI4_GPIO_WAIT_HIGH_MS);
+	}
+
+
+	init_waitqueue_head(&rmi4_data->wait);
+	mutex_init(&(rmi4_data->rmi4_io_ctrl_mutex));
+
+	retval = synaptics_rmi4_query_device(rmi4_data);
+	if (retval < 0) {
+		dev_err(&client->dev,
+				"%s: Failed to query device\n",
+				__func__);
+		goto err_reset_gpio_req;
+	}
+
+	i2c_set_clientdata(client, rmi4_data);
+
+	f1a = NULL;
+	if (!list_empty(&rmi->support_fn_list)) {
+		list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
+			if (fhandler->fn_number == SYNAPTICS_RMI4_F1A)
+				f1a = fhandler->data;
+		}
+	}
+
+	if (f1a) {
+		for (ii = 0; ii < f1a->valid_button_count; ii++) {
+			set_bit(f1a->button_map[ii],
+					rmi4_data->input_dev->keybit);
+			input_set_capability(rmi4_data->input_dev,
+					EV_KEY, f1a->button_map[ii]);
+		}
+	}
+
+	retval = input_register_device(rmi4_data->input_dev);
+	if (retval) {
+		dev_err(&client->dev,
+				"%s: Failed to register input device\n",
+				__func__);
+		goto err_register_input;
+	}
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+	rmi4_data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
+	rmi4_data->early_suspend.suspend = synaptics_rmi4_early_suspend;
+	rmi4_data->early_suspend.resume = synaptics_rmi4_late_resume;
+	register_early_suspend(&rmi4_data->early_suspend);
+#endif
+
+	if (!exp_fn_inited) {
+		mutex_init(&exp_fn_list_mutex);
+		INIT_LIST_HEAD(&exp_fn_list);
+		exp_fn_inited = 1;
+	}
+
+	rmi4_data->det_workqueue =
+			create_singlethread_workqueue("rmi_det_workqueue");
+	INIT_DELAYED_WORK(&rmi4_data->det_work,
+			synaptics_rmi4_detection_work);
+	queue_delayed_work(rmi4_data->det_workqueue,
+			&rmi4_data->det_work,
+			msecs_to_jiffies(EXP_FN_DET_INTERVAL));
+
+	rmi4_data->irq = gpio_to_irq(platform_data->irq_gpio);
+
+	retval = synaptics_rmi4_irq_enable(rmi4_data, true);
+	if (retval < 0) {
+		dev_err(&client->dev,
+				"%s: Failed to enable attention interrupt\n",
+				__func__);
+		goto err_enable_irq;
+	}
+
+	for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
+		retval = sysfs_create_file(&rmi4_data->input_dev->dev.kobj,
+				&attrs[attr_count].attr);
+		if (retval < 0) {
+			dev_err(&client->dev,
+					"%s: Failed to create sysfs attributes\n",
+					__func__);
+			goto err_sysfs;
+		}
+	}
+
+	return retval;
+
+err_sysfs:
+	for (attr_count--; attr_count >= 0; attr_count--) {
+		sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
+				&attrs[attr_count].attr);
+	}
+
+err_enable_irq:
+	input_unregister_device(rmi4_data->input_dev);
+
+err_register_input:
+	if (!list_empty(&rmi->support_fn_list)) {
+		list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
+			if (fhandler->fn_number == SYNAPTICS_RMI4_F1A)
+				synaptics_rmi4_f1a_kfree(fhandler);
+			else
+				kfree(fhandler->data);
+			kfree(fhandler);
+		}
+	}
+err_reset_gpio_req:
+	if (gpio_is_valid(platform_data->reset_gpio))
+		gpio_free(platform_data->reset_gpio);
+err_irq_gpio_req:
+	if (gpio_is_valid(platform_data->irq_gpio))
+		gpio_free(platform_data->irq_gpio);
+err_query_device:
+	synaptics_rmi4_power_on(rmi4_data, false);
+err_power_device:
+	synaptics_rmi4_regulator_configure(rmi4_data, false);
+err_reg_configure:
+	input_free_device(rmi4_data->input_dev);
+	rmi4_data->input_dev = NULL;
+err_input_device:
+	kfree(rmi4_data);
+
+	return retval;
+}
+
+ /**
+ * synaptics_rmi4_remove()
+ *
+ * Called by the kernel when the association with an I2C device of the
+ * same name is broken (when the driver is unloaded).
+ *
+ * This funtion terminates the work queue, stops sensor data acquisition,
+ * frees the interrupt, unregisters the driver from the input subsystem,
+ * turns off the power to the sensor, and frees other allocated resources.
+ */
+static int __devexit synaptics_rmi4_remove(struct i2c_client *client)
+{
+	unsigned char attr_count;
+	struct synaptics_rmi4_fn *fhandler;
+	struct synaptics_rmi4_data *rmi4_data = i2c_get_clientdata(client);
+	struct synaptics_rmi4_device_info *rmi;
+
+	rmi = &(rmi4_data->rmi4_mod_info);
+
+	cancel_delayed_work_sync(&rmi4_data->det_work);
+	flush_workqueue(rmi4_data->det_workqueue);
+	destroy_workqueue(rmi4_data->det_workqueue);
+
+	rmi4_data->touch_stopped = true;
+	wake_up(&rmi4_data->wait);
+
+	synaptics_rmi4_irq_enable(rmi4_data, false);
+
+	for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
+		sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
+				&attrs[attr_count].attr);
+	}
+
+	input_unregister_device(rmi4_data->input_dev);
+
+	if (!list_empty(&rmi->support_fn_list)) {
+		list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
+			if (fhandler->fn_number == SYNAPTICS_RMI4_F1A)
+				synaptics_rmi4_f1a_kfree(fhandler);
+			else
+				kfree(fhandler->data);
+			kfree(fhandler);
+		}
+	}
+
+	if (gpio_is_valid(rmi4_data->board->reset_gpio))
+		gpio_free(rmi4_data->board->reset_gpio);
+	if (gpio_is_valid(rmi4_data->board->irq_gpio))
+		gpio_free(rmi4_data->board->irq_gpio);
+
+	synaptics_rmi4_power_on(rmi4_data, false);
+	synaptics_rmi4_regulator_configure(rmi4_data, false);
+
+	kfree(rmi4_data);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+ /**
+ * synaptics_rmi4_sensor_sleep()
+ *
+ * Called by synaptics_rmi4_early_suspend() and synaptics_rmi4_suspend().
+ *
+ * This function stops finger data acquisition and puts the sensor to sleep.
+ */
+static void synaptics_rmi4_sensor_sleep(struct synaptics_rmi4_data *rmi4_data)
+{
+	int retval;
+	unsigned char device_ctrl;
+
+	retval = synaptics_rmi4_i2c_read(rmi4_data,
+			rmi4_data->f01_ctrl_base_addr,
+			&device_ctrl,
+			sizeof(device_ctrl));
+	if (retval < 0) {
+		dev_err(&(rmi4_data->input_dev->dev),
+				"%s: Failed to enter sleep mode\n",
+				__func__);
+		rmi4_data->sensor_sleep = false;
+		return;
+	}
+
+	device_ctrl = (device_ctrl & ~MASK_3BIT);
+	device_ctrl = (device_ctrl | NO_SLEEP_OFF | SENSOR_SLEEP);
+
+	retval = synaptics_rmi4_i2c_write(rmi4_data,
+			rmi4_data->f01_ctrl_base_addr,
+			&device_ctrl,
+			sizeof(device_ctrl));
+	if (retval < 0) {
+		dev_err(&(rmi4_data->input_dev->dev),
+				"%s: Failed to enter sleep mode\n",
+				__func__);
+		rmi4_data->sensor_sleep = false;
+		return;
+	} else {
+		rmi4_data->sensor_sleep = true;
+	}
+
+	return;
+}
+
+ /**
+ * synaptics_rmi4_sensor_wake()
+ *
+ * Called by synaptics_rmi4_resume() and synaptics_rmi4_late_resume().
+ *
+ * This function wakes the sensor from sleep.
+ */
+static void synaptics_rmi4_sensor_wake(struct synaptics_rmi4_data *rmi4_data)
+{
+	int retval;
+	unsigned char device_ctrl;
+
+	retval = synaptics_rmi4_i2c_read(rmi4_data,
+			rmi4_data->f01_ctrl_base_addr,
+			&device_ctrl,
+			sizeof(device_ctrl));
+	if (retval < 0) {
+		dev_err(&(rmi4_data->input_dev->dev),
+				"%s: Failed to wake from sleep mode\n",
+				__func__);
+		rmi4_data->sensor_sleep = true;
+		return;
+	}
+
+	device_ctrl = (device_ctrl & ~MASK_3BIT);
+	device_ctrl = (device_ctrl | NO_SLEEP_OFF | NORMAL_OPERATION);
+
+	retval = synaptics_rmi4_i2c_write(rmi4_data,
+			rmi4_data->f01_ctrl_base_addr,
+			&device_ctrl,
+			sizeof(device_ctrl));
+	if (retval < 0) {
+		dev_err(&(rmi4_data->input_dev->dev),
+				"%s: Failed to wake from sleep mode\n",
+				__func__);
+		rmi4_data->sensor_sleep = true;
+		return;
+	} else {
+		rmi4_data->sensor_sleep = false;
+	}
+
+	return;
+}
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ /**
+ * synaptics_rmi4_early_suspend()
+ *
+ * Called by the kernel during the early suspend phase when the system
+ * enters suspend.
+ *
+ * This function calls synaptics_rmi4_sensor_sleep() to stop finger
+ * data acquisition and put the sensor to sleep.
+ */
+static void synaptics_rmi4_early_suspend(struct early_suspend *h)
+{
+	struct synaptics_rmi4_data *rmi4_data =
+			container_of(h, struct synaptics_rmi4_data,
+			early_suspend);
+
+	rmi4_data->touch_stopped = true;
+	wake_up(&rmi4_data->wait);
+	synaptics_rmi4_irq_enable(rmi4_data, false);
+	synaptics_rmi4_sensor_sleep(rmi4_data);
+
+	if (rmi4_data->full_pm_cycle)
+		synaptics_rmi4_suspend(&(rmi4_data->input_dev->dev));
+
+	return;
+}
+
+ /**
+ * synaptics_rmi4_late_resume()
+ *
+ * Called by the kernel during the late resume phase when the system
+ * wakes up from suspend.
+ *
+ * This function goes through the sensor wake process if the system wakes
+ * up from early suspend (without going into suspend).
+ */
+static void synaptics_rmi4_late_resume(struct early_suspend *h)
+{
+	struct synaptics_rmi4_data *rmi4_data =
+			container_of(h, struct synaptics_rmi4_data,
+			early_suspend);
+
+	if (rmi4_data->full_pm_cycle)
+		synaptics_rmi4_resume(&(rmi4_data->input_dev->dev));
+
+	if (rmi4_data->sensor_sleep == true) {
+		synaptics_rmi4_sensor_wake(rmi4_data);
+		rmi4_data->touch_stopped = false;
+		synaptics_rmi4_irq_enable(rmi4_data, true);
+	}
+
+	return;
+}
+#endif
+
+ /**
+ * synaptics_rmi4_suspend()
+ *
+ * Called by the kernel during the suspend phase when the system
+ * enters suspend.
+ *
+ * This function stops finger data acquisition and puts the sensor to
+ * sleep (if not already done so during the early suspend phase),
+ * disables the interrupt, and turns off the power to the sensor.
+ */
+static int synaptics_rmi4_suspend(struct device *dev)
+{
+	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+	if (!rmi4_data->sensor_sleep) {
+		rmi4_data->touch_stopped = true;
+		wake_up(&rmi4_data->wait);
+		synaptics_rmi4_irq_enable(rmi4_data, false);
+		synaptics_rmi4_sensor_sleep(rmi4_data);
+	}
+
+	return 0;
+}
+
+ /**
+ * synaptics_rmi4_resume()
+ *
+ * Called by the kernel during the resume phase when the system
+ * wakes up from suspend.
+ *
+ * This function turns on the power to the sensor, wakes the sensor
+ * from sleep, enables the interrupt, and starts finger data
+ * acquisition.
+ */
+static int synaptics_rmi4_resume(struct device *dev)
+{
+	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+	synaptics_rmi4_sensor_wake(rmi4_data);
+	rmi4_data->touch_stopped = false;
+	synaptics_rmi4_irq_enable(rmi4_data, true);
+
+	return 0;
+}
+
+static const struct dev_pm_ops synaptics_rmi4_dev_pm_ops = {
+	.suspend = synaptics_rmi4_suspend,
+	.resume  = synaptics_rmi4_resume,
+};
+#endif
+
+static const struct i2c_device_id synaptics_rmi4_id_table[] = {
+	{DRIVER_NAME, 0},
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, synaptics_rmi4_id_table);
+
+static struct i2c_driver synaptics_rmi4_driver = {
+	.driver = {
+		.name = DRIVER_NAME,
+		.owner = THIS_MODULE,
+#ifdef CONFIG_PM
+		.pm = &synaptics_rmi4_dev_pm_ops,
+#endif
+	},
+	.probe = synaptics_rmi4_probe,
+	.remove = __devexit_p(synaptics_rmi4_remove),
+	.id_table = synaptics_rmi4_id_table,
+};
+
+ /**
+ * synaptics_rmi4_init()
+ *
+ * Called by the kernel during do_initcalls (if built-in)
+ * or when the driver is loaded (if a module).
+ *
+ * This function registers the driver to the I2C subsystem.
+ *
+ */
+static int __init synaptics_rmi4_init(void)
+{
+	return i2c_add_driver(&synaptics_rmi4_driver);
+}
+
+ /**
+ * synaptics_rmi4_exit()
+ *
+ * Called by the kernel when the driver is unloaded.
+ *
+ * This funtion unregisters the driver from the I2C subsystem.
+ *
+ */
+static void __exit synaptics_rmi4_exit(void)
+{
+	i2c_del_driver(&synaptics_rmi4_driver);
+}
+
+module_init(synaptics_rmi4_init);
+module_exit(synaptics_rmi4_exit);
+
+MODULE_AUTHOR("Synaptics, Inc.");
+MODULE_DESCRIPTION("Synaptics RMI4 I2C Touch Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi4.h b/drivers/input/touchscreen/synaptics_i2c_rmi4.h
new file mode 100644
index 0000000..d13f172
--- /dev/null
+++ b/drivers/input/touchscreen/synaptics_i2c_rmi4.h
@@ -0,0 +1,274 @@
+/*
+ * Synaptics RMI4 touchscreen driver
+ *
+ * Copyright (C) 2012 Synaptics Incorporated
+ *
+ * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
+ * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SYNAPTICS_DSX_RMI4_H_
+#define _SYNAPTICS_DSX_RMI4_H_
+
+#define SYNAPTICS_DS4 (1 << 0)
+#define SYNAPTICS_DS5 (1 << 1)
+#define SYNAPTICS_DSX_DRIVER_PRODUCT SYNAPTICS_DS4
+#define SYNAPTICS_DSX_DRIVER_VERSION 0x1002
+
+#include <linux/version.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+
+#define PDT_PROPS (0x00EF)
+#define PDT_START (0x00E9)
+#define PDT_END (0x000A)
+#define PDT_ENTRY_SIZE (0x0006)
+#define PAGES_TO_SERVICE (10)
+#define PAGE_SELECT_LEN (2)
+
+#define SYNAPTICS_RMI4_F01 (0x01)
+#define SYNAPTICS_RMI4_F11 (0x11)
+#define SYNAPTICS_RMI4_F1A (0x1a)
+#define SYNAPTICS_RMI4_F34 (0x34)
+#define SYNAPTICS_RMI4_F54 (0x54)
+#define SYNAPTICS_RMI4_F55 (0x55)
+
+#define SYNAPTICS_RMI4_PRODUCT_INFO_SIZE 2
+#define SYNAPTICS_RMI4_DATE_CODE_SIZE 3
+#define SYNAPTICS_RMI4_PRODUCT_ID_SIZE 10
+#define SYNAPTICS_RMI4_BUILD_ID_SIZE 3
+
+#define MAX_NUMBER_OF_FINGERS 10
+#define MAX_NUMBER_OF_BUTTONS 4
+#define MAX_INTR_REGISTERS 4
+
+#define MASK_16BIT 0xFFFF
+#define MASK_8BIT 0xFF
+#define MASK_7BIT 0x7F
+#define MASK_6BIT 0x3F
+#define MASK_5BIT 0x1F
+#define MASK_4BIT 0x0F
+#define MASK_3BIT 0x07
+#define MASK_2BIT 0x03
+#define MASK_1BIT 0x01
+
+/*
+ * struct synaptics_rmi4_fn_desc - function descriptor fields in PDT
+ * @query_base_addr: base address for query registers
+ * @cmd_base_addr: base address for command registers
+ * @ctrl_base_addr: base address for control registers
+ * @data_base_addr: base address for data registers
+ * @intr_src_count: number of interrupt sources
+ * @fn_number: function number
+ */
+struct synaptics_rmi4_fn_desc {
+	unsigned char query_base_addr;
+	unsigned char cmd_base_addr;
+	unsigned char ctrl_base_addr;
+	unsigned char data_base_addr;
+	unsigned char intr_src_count;
+	unsigned char fn_number;
+};
+
+/*
+ * synaptics_rmi4_fn_full_addr - full 16-bit base addresses
+ * @query_base: 16-bit base address for query registers
+ * @cmd_base: 16-bit base address for data registers
+ * @ctrl_base: 16-bit base address for command registers
+ * @data_base: 16-bit base address for control registers
+ */
+struct synaptics_rmi4_fn_full_addr {
+	unsigned short query_base;
+	unsigned short cmd_base;
+	unsigned short ctrl_base;
+	unsigned short data_base;
+};
+
+/*
+ * struct synaptics_rmi4_fn - function handler data structure
+ * @fn_number: function number
+ * @num_of_data_sources: number of data sources
+ * @num_of_data_points: maximum number of fingers supported
+ * @size_of_data_register_block: data register block size
+ * @data1_offset: offset to data1 register from data base address
+ * @intr_reg_num: index to associated interrupt register
+ * @intr_mask: interrupt mask
+ * @full_addr: full 16-bit base addresses of function registers
+ * @link: linked list for function handlers
+ * @data_size: size of private data
+ * @data: pointer to private data
+ */
+struct synaptics_rmi4_fn {
+	unsigned char fn_number;
+	unsigned char num_of_data_sources;
+	unsigned char num_of_data_points;
+	unsigned char size_of_data_register_block;
+	unsigned char data1_offset;
+	unsigned char intr_reg_num;
+	unsigned char intr_mask;
+	struct synaptics_rmi4_fn_full_addr full_addr;
+	struct list_head link;
+	int data_size;
+	void *data;
+};
+
+/*
+ * struct synaptics_rmi4_device_info - device information
+ * @version_major: rmi protocol major version number
+ * @version_minor: rmi protocol minor version number
+ * @manufacturer_id: manufacturer id
+ * @product_props: product properties information
+ * @product_info: product info array
+ * @date_code: device manufacture date
+ * @tester_id: tester id array
+ * @serial_number: device serial number
+ * @product_id_string: device product id
+ * @support_fn_list: linked list for function handlers
+ */
+struct synaptics_rmi4_device_info {
+	unsigned int version_major;
+	unsigned int version_minor;
+	unsigned char manufacturer_id;
+	unsigned char product_props;
+	unsigned char product_info[SYNAPTICS_RMI4_PRODUCT_INFO_SIZE];
+	unsigned char date_code[SYNAPTICS_RMI4_DATE_CODE_SIZE];
+	unsigned short tester_id;
+	unsigned short serial_number;
+	unsigned char product_id_string[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1];
+	unsigned char build_id[SYNAPTICS_RMI4_BUILD_ID_SIZE];
+	unsigned char config_id[3];
+	struct list_head support_fn_list;
+};
+
+/*
+ * struct synaptics_rmi4_data - rmi4 device instance data
+ * @i2c_client: pointer to associated i2c client
+ * @input_dev: pointer to associated input device
+ * @board: constant pointer to platform data
+ * @rmi4_mod_info: device information
+ * @regulator: pointer to associated regulator
+ * @rmi4_io_ctrl_mutex: mutex for i2c i/o control
+ * @det_work: work thread instance for expansion function detection
+ * @det_workqueue: pointer to work queue for work thread instance
+ * @early_suspend: instance to support early suspend power management
+ * @current_page: current page in sensor to acess
+ * @button_0d_enabled: flag for 0d button support
+ * @full_pm_cycle: flag for full power management cycle in early suspend stage
+ * @num_of_intr_regs: number of interrupt registers
+ * @f01_query_base_addr: query base address for f01
+ * @f01_cmd_base_addr: command base address for f01
+ * @f01_ctrl_base_addr: control base address for f01
+ * @f01_data_base_addr: data base address for f01
+ * @irq: attention interrupt
+ * @sensor_max_x: sensor maximum x value
+ * @sensor_max_y: sensor maximum y value
+ * @irq_enabled: flag for indicating interrupt enable status
+ * @touch_stopped: flag to stop interrupt thread processing
+ * @fingers_on_2d: flag to indicate presence of fingers in 2d area
+ * @sensor_sleep: flag to indicate sleep state of sensor
+ * @wait: wait queue for touch data polling in interrupt thread
+ * @i2c_read: pointer to i2c read function
+ * @i2c_write: pointer to i2c write function
+ * @irq_enable: pointer to irq enable function
+ */
+struct synaptics_rmi4_data {
+	struct i2c_client *i2c_client;
+	struct input_dev *input_dev;
+	const struct synaptics_rmi4_platform_data *board;
+	struct synaptics_rmi4_device_info rmi4_mod_info;
+	struct regulator *vdd;
+	struct regulator *vcc_i2c;
+	struct mutex rmi4_io_ctrl_mutex;
+	struct delayed_work det_work;
+	struct workqueue_struct *det_workqueue;
+	struct early_suspend early_suspend;
+	unsigned char current_page;
+	unsigned char button_0d_enabled;
+	unsigned char full_pm_cycle;
+	unsigned char num_of_rx;
+	unsigned char num_of_tx;
+	unsigned char num_of_fingers;
+	unsigned char intr_mask[MAX_INTR_REGISTERS];
+	unsigned short num_of_intr_regs;
+	unsigned short f01_query_base_addr;
+	unsigned short f01_cmd_base_addr;
+	unsigned short f01_ctrl_base_addr;
+	unsigned short f01_data_base_addr;
+	int irq;
+	int sensor_max_x;
+	int sensor_max_y;
+	bool irq_enabled;
+	bool touch_stopped;
+	bool fingers_on_2d;
+	bool sensor_sleep;
+	wait_queue_head_t wait;
+	int (*i2c_read)(struct synaptics_rmi4_data *pdata, unsigned short addr,
+			unsigned char *data, unsigned short length);
+	int (*i2c_write)(struct synaptics_rmi4_data *pdata, unsigned short addr,
+			unsigned char *data, unsigned short length);
+	int (*irq_enable)(struct synaptics_rmi4_data *rmi4_data, bool enable);
+	int (*reset_device)(struct synaptics_rmi4_data *rmi4_data);
+};
+
+enum exp_fn {
+	RMI_DEV = 0,
+	RMI_F34,
+	RMI_F54,
+	RMI_FW_UPDATER,
+	RMI_LAST,
+};
+
+struct synaptics_rmi4_exp_fn_ptr {
+	int (*read)(struct synaptics_rmi4_data *rmi4_data, unsigned short addr,
+			unsigned char *data, unsigned short length);
+	int (*write)(struct synaptics_rmi4_data *rmi4_data, unsigned short addr,
+			unsigned char *data, unsigned short length);
+	int (*enable)(struct synaptics_rmi4_data *rmi4_data, bool enable);
+};
+
+void synaptics_rmi4_new_function(enum exp_fn fn_type, bool insert,
+		int (*func_init)(struct synaptics_rmi4_data *rmi4_data),
+		void (*func_remove)(struct synaptics_rmi4_data *rmi4_data),
+		void (*func_attn)(struct synaptics_rmi4_data *rmi4_data,
+				unsigned char intr_mask));
+
+static inline ssize_t synaptics_rmi4_show_error(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	dev_warn(dev, "%s Attempted to read from write-only attribute %s\n",
+			__func__, attr->attr.name);
+	return -EPERM;
+}
+
+static inline ssize_t synaptics_rmi4_store_error(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	dev_warn(dev, "%s Attempted to write to read-only attribute %s\n",
+			__func__, attr->attr.name);
+	return -EPERM;
+}
+
+static inline void batohs(unsigned short *dest, unsigned char *src)
+{
+	*dest = src[1] * 0x100 + src[0];
+}
+
+static inline void hstoba(unsigned char *dest, unsigned short src)
+{
+	dest[0] = src % 0x100;
+	dest[1] = src / 0x100;
+}
+
+#endif
diff --git a/drivers/input/touchscreen/synaptics_rmi_dev.c b/drivers/input/touchscreen/synaptics_rmi_dev.c
new file mode 100644
index 0000000..7f1aac5
--- /dev/null
+++ b/drivers/input/touchscreen/synaptics_rmi_dev.c
@@ -0,0 +1,709 @@
+/*
+ * Synaptics RMI4 touchscreen driver
+ *
+ * Copyright (C) 2012 Synaptics Incorporated
+ *
+ * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
+ * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/uaccess.h>
+#include <linux/cdev.h>
+#include <linux/input/synaptics_dsx.h>
+#include "synaptics_i2c_rmi4.h"
+
+#define CHAR_DEVICE_NAME "rmi"
+#define DEVICE_CLASS_NAME "rmidev"
+#define DEV_NUMBER 1
+#define REG_ADDR_LIMIT 0xFFFF
+
+static ssize_t rmidev_sysfs_open_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+static ssize_t rmidev_sysfs_release_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+static ssize_t rmidev_sysfs_address_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+static ssize_t rmidev_sysfs_length_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+static ssize_t rmidev_sysfs_data_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static ssize_t rmidev_sysfs_data_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+struct rmidev_handle {
+	dev_t dev_no;
+	unsigned short address;
+	unsigned int length;
+	struct device dev;
+	struct synaptics_rmi4_data *rmi4_data;
+	struct synaptics_rmi4_exp_fn_ptr *fn_ptr;
+	struct kobject *sysfs_dir;
+	void *data;
+};
+
+struct rmidev_data {
+	int ref_count;
+	struct cdev main_dev;
+	struct class *device_class;
+	struct mutex file_mutex;
+	struct rmidev_handle *rmi_dev;
+};
+
+static struct device_attribute attrs[] = {
+	__ATTR(open, S_IWUGO,
+			synaptics_rmi4_show_error,
+			rmidev_sysfs_open_store),
+	__ATTR(release, S_IWUGO,
+			synaptics_rmi4_show_error,
+			rmidev_sysfs_release_store),
+	__ATTR(address, S_IWUGO,
+			synaptics_rmi4_show_error,
+			rmidev_sysfs_address_store),
+	__ATTR(length, S_IWUGO,
+			synaptics_rmi4_show_error,
+			rmidev_sysfs_length_store),
+	__ATTR(data, (S_IRUGO | S_IWUGO),
+			rmidev_sysfs_data_show,
+			rmidev_sysfs_data_store),
+};
+
+static int rmidev_major_num;
+
+static struct class *rmidev_device_class;
+
+static struct rmidev_handle *rmidev;
+
+static struct completion remove_complete;
+
+static ssize_t rmidev_sysfs_open_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	unsigned int input;
+
+	if (sscanf(buf, "%u", &input) != 1)
+			return -EINVAL;
+
+	if (input != 1)
+		return -EINVAL;
+
+	rmidev->fn_ptr->enable(rmidev->rmi4_data, false);
+	dev_dbg(&rmidev->rmi4_data->i2c_client->dev,
+			"%s: Attention interrupt disabled\n",
+			__func__);
+
+	return count;
+}
+
+static ssize_t rmidev_sysfs_release_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	unsigned int input;
+
+	if (sscanf(buf, "%u", &input) != 1)
+			return -EINVAL;
+
+	if (input != 1)
+		return -EINVAL;
+
+	rmidev->fn_ptr->enable(rmidev->rmi4_data, true);
+	dev_dbg(&rmidev->rmi4_data->i2c_client->dev,
+			"%s: Attention interrupt enabled\n",
+			__func__);
+
+	return count;
+}
+
+static ssize_t rmidev_sysfs_address_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	unsigned int input;
+
+	if (sscanf(buf, "%u", &input) != 1)
+			return -EINVAL;
+
+	if (input > REG_ADDR_LIMIT)
+		return -EINVAL;
+
+	rmidev->address = (unsigned short)input;
+
+	return count;
+}
+
+static ssize_t rmidev_sysfs_length_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	unsigned int input;
+
+	if (sscanf(buf, "%u", &input) != 1)
+			return -EINVAL;
+
+	if (input > REG_ADDR_LIMIT)
+		return -EINVAL;
+
+	rmidev->length = input;
+
+	return count;
+}
+
+static ssize_t rmidev_sysfs_data_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	int retval;
+	unsigned int data_length = rmidev->length;
+
+	if (data_length > (REG_ADDR_LIMIT - rmidev->address))
+		data_length = REG_ADDR_LIMIT - rmidev->address;
+
+	if (data_length) {
+		retval = rmidev->fn_ptr->read(rmidev->rmi4_data,
+				rmidev->address,
+				(unsigned char *)buf,
+				data_length);
+		if (retval < 0) {
+			dev_err(&rmidev->rmi4_data->i2c_client->dev,
+					"%s: Failed to read data\n",
+					__func__);
+			return retval;
+		}
+	} else {
+		return -EINVAL;
+	}
+
+	return data_length;
+}
+
+static ssize_t rmidev_sysfs_data_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	int retval;
+	unsigned int data_length = rmidev->length;
+
+	if (data_length > (REG_ADDR_LIMIT - rmidev->address))
+		data_length = REG_ADDR_LIMIT - rmidev->address;
+
+	if (data_length) {
+		retval = rmidev->fn_ptr->write(rmidev->rmi4_data,
+				rmidev->address,
+				(unsigned char *)buf,
+				data_length);
+		if (retval < 0) {
+			dev_err(&rmidev->rmi4_data->i2c_client->dev,
+					"%s: Failed to write data\n",
+					__func__);
+			return retval;
+		}
+	} else {
+		return -EINVAL;
+	}
+
+	return data_length;
+}
+
+/*
+ * rmidev_llseek - used to set up register address
+ *
+ * @filp: file structure for seek
+ * @off: offset
+ *   if whence == SEEK_SET,
+ *     high 16 bits: page address
+ *     low 16 bits: register address
+ *   if whence == SEEK_CUR,
+ *     offset from current position
+ *   if whence == SEEK_END,
+ *     offset from end position (0xFFFF)
+ * @whence: SEEK_SET, SEEK_CUR, or SEEK_END
+ */
+static loff_t rmidev_llseek(struct file *filp, loff_t off, int whence)
+{
+	loff_t newpos;
+	struct rmidev_data *dev_data = filp->private_data;
+
+	if (IS_ERR(dev_data)) {
+		pr_err("%s: Pointer of char device data is invalid", __func__);
+		return -EBADF;
+	}
+
+	mutex_lock(&(dev_data->file_mutex));
+
+	switch (whence) {
+	case SEEK_SET:
+		newpos = off;
+		break;
+	case SEEK_CUR:
+		newpos = filp->f_pos + off;
+		break;
+	case SEEK_END:
+		newpos = REG_ADDR_LIMIT + off;
+		break;
+	default:
+		newpos = -EINVAL;
+		goto clean_up;
+	}
+
+	if (newpos < 0 || newpos > REG_ADDR_LIMIT) {
+		dev_err(&rmidev->rmi4_data->i2c_client->dev,
+				"%s: New position 0x%04x is invalid\n",
+				__func__, (unsigned int)newpos);
+		newpos = -EINVAL;
+		goto clean_up;
+	}
+
+	filp->f_pos = newpos;
+
+clean_up:
+	mutex_unlock(&(dev_data->file_mutex));
+
+	return newpos;
+}
+
+/*
+ * rmidev_read: - use to read data from rmi device
+ *
+ * @filp: file structure for read
+ * @buf: user space buffer pointer
+ * @count: number of bytes to read
+ * @f_pos: offset (starting register address)
+ */
+static ssize_t rmidev_read(struct file *filp, char __user *buf,
+		size_t count, loff_t *f_pos)
+{
+	ssize_t retval;
+	unsigned char tmpbuf[count + 1];
+	struct rmidev_data *dev_data = filp->private_data;
+
+	if (IS_ERR(dev_data)) {
+		pr_err("%s: Pointer of char device data is invalid", __func__);
+		return -EBADF;
+	}
+
+	if (count == 0)
+		return 0;
+
+	if (count > (REG_ADDR_LIMIT - *f_pos))
+		count = REG_ADDR_LIMIT - *f_pos;
+
+	mutex_lock(&(dev_data->file_mutex));
+
+	retval = rmidev->fn_ptr->read(rmidev->rmi4_data,
+			*f_pos,
+			tmpbuf,
+			count);
+	if (retval < 0)
+		goto clean_up;
+
+	if (copy_to_user(buf, tmpbuf, count))
+		retval = -EFAULT;
+	else
+		*f_pos += retval;
+
+clean_up:
+	mutex_unlock(&(dev_data->file_mutex));
+
+	return retval;
+}
+
+/*
+ * rmidev_write: - used to write data to rmi device
+ *
+ * @filep: file structure for write
+ * @buf: user space buffer pointer
+ * @count: number of bytes to write
+ * @f_pos: offset (starting register address)
+ */
+static ssize_t rmidev_write(struct file *filp, const char __user *buf,
+		size_t count, loff_t *f_pos)
+{
+	ssize_t retval;
+	unsigned char tmpbuf[count + 1];
+	struct rmidev_data *dev_data = filp->private_data;
+
+	if (IS_ERR(dev_data)) {
+		pr_err("%s: Pointer of char device data is invalid", __func__);
+		return -EBADF;
+	}
+
+	if (count == 0)
+		return 0;
+
+	if (count > (REG_ADDR_LIMIT - *f_pos))
+		count = REG_ADDR_LIMIT - *f_pos;
+
+	if (copy_from_user(tmpbuf, buf, count))
+		return -EFAULT;
+
+	mutex_lock(&(dev_data->file_mutex));
+
+	retval = rmidev->fn_ptr->write(rmidev->rmi4_data,
+			*f_pos,
+			tmpbuf,
+			count);
+	if (retval >= 0)
+		*f_pos += retval;
+
+	mutex_unlock(&(dev_data->file_mutex));
+
+	return retval;
+}
+
+/*
+ * rmidev_open: enable access to rmi device
+ * @inp: inode struture
+ * @filp: file structure
+ */
+static int rmidev_open(struct inode *inp, struct file *filp)
+{
+	int retval = 0;
+	struct rmidev_data *dev_data =
+			container_of(inp->i_cdev, struct rmidev_data, main_dev);
+
+	if (!dev_data)
+		return -EACCES;
+
+	filp->private_data = dev_data;
+
+	mutex_lock(&(dev_data->file_mutex));
+
+	rmidev->fn_ptr->enable(rmidev->rmi4_data, false);
+	dev_dbg(&rmidev->rmi4_data->i2c_client->dev,
+			"%s: Attention interrupt disabled\n",
+			__func__);
+
+	if (dev_data->ref_count < 1)
+		dev_data->ref_count++;
+	else
+		retval = -EACCES;
+
+	mutex_unlock(&(dev_data->file_mutex));
+
+	return retval;
+}
+
+/*
+ * rmidev_release: - release access to rmi device
+ * @inp: inode structure
+ * @filp: file structure
+ */
+static int rmidev_release(struct inode *inp, struct file *filp)
+{
+	struct rmidev_data *dev_data =
+			container_of(inp->i_cdev, struct rmidev_data, main_dev);
+
+	if (!dev_data)
+		return -EACCES;
+
+	mutex_lock(&(dev_data->file_mutex));
+
+	dev_data->ref_count--;
+	if (dev_data->ref_count < 0)
+		dev_data->ref_count = 0;
+
+	rmidev->fn_ptr->enable(rmidev->rmi4_data, true);
+	dev_dbg(&rmidev->rmi4_data->i2c_client->dev,
+			"%s: Attention interrupt enabled\n",
+			__func__);
+
+	mutex_unlock(&(dev_data->file_mutex));
+
+	return 0;
+}
+
+static const struct file_operations rmidev_fops = {
+	.owner = THIS_MODULE,
+	.llseek = rmidev_llseek,
+	.read = rmidev_read,
+	.write = rmidev_write,
+	.open = rmidev_open,
+	.release = rmidev_release,
+};
+
+static void rmidev_device_cleanup(struct rmidev_data *dev_data)
+{
+	dev_t devno;
+
+	if (dev_data) {
+		devno = dev_data->main_dev.dev;
+
+		if (dev_data->device_class)
+			device_destroy(dev_data->device_class, devno);
+
+		cdev_del(&dev_data->main_dev);
+
+		unregister_chrdev_region(devno, 1);
+
+		dev_dbg(&rmidev->rmi4_data->i2c_client->dev,
+				"%s: rmidev device removed\n",
+				__func__);
+	}
+
+	return;
+}
+
+static char *rmi_char_devnode(struct device *dev, mode_t *mode)
+{
+	if (!mode)
+		return NULL;
+
+	*mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
+
+	return kasprintf(GFP_KERNEL, "rmi/%s", dev_name(dev));
+}
+
+static int rmidev_create_device_class(void)
+{
+	rmidev_device_class = class_create(THIS_MODULE, DEVICE_CLASS_NAME);
+
+	if (IS_ERR(rmidev_device_class)) {
+		pr_err("%s: Failed to create /dev/%s\n",
+				__func__, CHAR_DEVICE_NAME);
+		return -ENODEV;
+	}
+
+	rmidev_device_class->devnode = rmi_char_devnode;
+
+	return 0;
+}
+
+static int rmidev_init_device(struct synaptics_rmi4_data *rmi4_data)
+{
+	int retval;
+	dev_t dev_no;
+	unsigned char attr_count;
+	struct rmidev_data *dev_data;
+	struct device *device_ptr;
+
+	rmidev = kzalloc(sizeof(*rmidev), GFP_KERNEL);
+	if (!rmidev) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to alloc mem for rmidev\n",
+				__func__);
+		retval = -ENOMEM;
+		goto err_rmidev;
+	}
+
+	rmidev->fn_ptr =  kzalloc(sizeof(*(rmidev->fn_ptr)), GFP_KERNEL);
+	if (!rmidev) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to alloc mem for fn_ptr\n",
+				__func__);
+		retval = -ENOMEM;
+		goto err_fn_ptr;
+	}
+
+	rmidev->fn_ptr->read = rmi4_data->i2c_read;
+	rmidev->fn_ptr->write = rmi4_data->i2c_write;
+	rmidev->fn_ptr->enable = rmi4_data->irq_enable;
+	rmidev->rmi4_data = rmi4_data;
+
+	retval = rmidev_create_device_class();
+	if (retval < 0) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to create device class\n",
+				__func__);
+		goto err_device_class;
+	}
+
+	if (rmidev_major_num) {
+		dev_no = MKDEV(rmidev_major_num, DEV_NUMBER);
+		retval = register_chrdev_region(dev_no, 1, CHAR_DEVICE_NAME);
+	} else {
+		retval = alloc_chrdev_region(&dev_no, 0, 1, CHAR_DEVICE_NAME);
+		if (retval < 0) {
+			dev_err(&rmi4_data->i2c_client->dev,
+					"%s: Failed to allocate char device region\n",
+					__func__);
+			goto err_device_region;
+		}
+
+		rmidev_major_num = MAJOR(dev_no);
+		dev_dbg(&rmi4_data->i2c_client->dev,
+				"%s: Major number of rmidev = %d\n",
+				__func__, rmidev_major_num);
+	}
+
+	dev_data = kzalloc(sizeof(*dev_data), GFP_KERNEL);
+	if (!dev_data) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to alloc mem for dev_data\n",
+				__func__);
+		retval = -ENOMEM;
+		goto err_dev_data;
+	}
+
+	mutex_init(&dev_data->file_mutex);
+	dev_data->rmi_dev = rmidev;
+	rmidev->data = dev_data;
+
+	cdev_init(&dev_data->main_dev, &rmidev_fops);
+
+	retval = cdev_add(&dev_data->main_dev, dev_no, 1);
+	if (retval < 0) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to add rmi char device\n",
+				__func__);
+		goto err_char_device;
+	}
+
+	dev_set_name(&rmidev->dev, "rmidev%d", MINOR(dev_no));
+	dev_data->device_class = rmidev_device_class;
+
+	device_ptr = device_create(dev_data->device_class, NULL, dev_no,
+			NULL, CHAR_DEVICE_NAME"%d", MINOR(dev_no));
+	if (IS_ERR(device_ptr)) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to create rmi char device\n",
+				__func__);
+		retval = -ENODEV;
+		goto err_char_device;
+	}
+
+	retval = gpio_export(rmi4_data->board->irq_gpio, false);
+	if (retval < 0) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to export attention gpio\n",
+				__func__);
+	} else {
+		retval = gpio_export_link(&(rmi4_data->input_dev->dev),
+				"attn", rmi4_data->board->irq_gpio);
+		if (retval < 0) {
+			dev_err(&rmi4_data->input_dev->dev,
+					"%s Failed to create gpio symlink\n",
+					__func__);
+		} else {
+			dev_dbg(&rmi4_data->input_dev->dev,
+					"%s: Exported attention gpio %d\n",
+					__func__, rmi4_data->board->irq_gpio);
+		}
+	}
+
+	rmidev->sysfs_dir = kobject_create_and_add("rmidev",
+			&rmi4_data->input_dev->dev.kobj);
+	if (!rmidev->sysfs_dir) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to create sysfs directory\n",
+				__func__);
+		goto err_sysfs_dir;
+	}
+
+	for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
+		retval = sysfs_create_file(rmidev->sysfs_dir,
+				&attrs[attr_count].attr);
+		if (retval < 0) {
+			dev_err(&rmi4_data->input_dev->dev,
+					"%s: Failed to create sysfs attributes\n",
+					__func__);
+			retval = -ENODEV;
+			goto err_sysfs_attrs;
+		}
+	}
+
+	return 0;
+
+err_sysfs_attrs:
+	for (attr_count--; attr_count >= 0; attr_count--) {
+		sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
+				&attrs[attr_count].attr);
+	}
+
+	kobject_put(rmidev->sysfs_dir);
+
+err_sysfs_dir:
+err_char_device:
+	rmidev_device_cleanup(dev_data);
+	kfree(dev_data);
+
+err_dev_data:
+	unregister_chrdev_region(dev_no, 1);
+
+err_device_region:
+	class_destroy(rmidev_device_class);
+
+err_device_class:
+	kfree(rmidev->fn_ptr);
+
+err_fn_ptr:
+	kfree(rmidev);
+
+err_rmidev:
+	return retval;
+}
+
+static void rmidev_remove_device(struct synaptics_rmi4_data *rmi4_data)
+{
+	unsigned char attr_count;
+	struct rmidev_data *dev_data;
+
+	if (!rmidev)
+		return;
+
+	for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++)
+		sysfs_remove_file(rmidev->sysfs_dir, &attrs[attr_count].attr);
+
+	kobject_put(rmidev->sysfs_dir);
+
+	dev_data = rmidev->data;
+	if (dev_data) {
+		rmidev_device_cleanup(dev_data);
+		kfree(dev_data);
+	}
+
+	unregister_chrdev_region(rmidev->dev_no, 1);
+
+	class_destroy(rmidev_device_class);
+
+	kfree(rmidev->fn_ptr);
+	kfree(rmidev);
+
+	complete(&remove_complete);
+
+	return;
+}
+
+static int __init rmidev_module_init(void)
+{
+	synaptics_rmi4_new_function(RMI_DEV, true,
+			rmidev_init_device,
+			rmidev_remove_device,
+			NULL);
+	return 0;
+}
+
+static void __exit rmidev_module_exit(void)
+{
+	init_completion(&remove_complete);
+	synaptics_rmi4_new_function(RMI_DEV, false,
+			rmidev_init_device,
+			rmidev_remove_device,
+			NULL);
+	wait_for_completion(&remove_complete);
+	return;
+}
+
+module_init(rmidev_module_init);
+module_exit(rmidev_module_exit);
+
+MODULE_AUTHOR("Synaptics, Inc.");
+MODULE_DESCRIPTION("RMI4 RMI_Dev Module");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 86703e0..db4ec9d 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -16,7 +16,7 @@
 # MSM IOMMU support
 config MSM_IOMMU
 	bool "MSM IOMMU Support"
-	depends on ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_APQ8064 || ARCH_MSM8974 || ARCH_MPQ8092 || ARCH_MSM8910
+	depends on ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_APQ8064 || ARCH_MSM8974 || ARCH_MPQ8092 || ARCH_MSM8610 || ARCH_MSM8226
 	select IOMMU_API
 	help
 	  Support for the IOMMUs found on certain Qualcomm SOCs.
@@ -36,6 +36,16 @@
 
 	  If unsure, say N here.
 
+config MSM_IOMMU_PMON
+	bool "MSM IOMMU Perfomance Monitoring Support"
+	depends on (ARCH_MSM8974 || ARCH_MSM8610 || ARCH_MSM8226) && MSM_IOMMU
+	help
+	  Support for monitoring IOMMUs performance on certain Qualcomm SOCs.
+	  It captures TLB statistics per context bank of the IOMMU as an
+	  indication of its performance metric.
+
+	  If unsure, say N here.
+
 config IOMMU_PGTABLES_L2
 	bool "Allow SMMU page tables in the L2 cache (Experimental)"
 	depends on MSM_IOMMU && MMU && SMP && CPU_DCACHE_DISABLE=n
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 11d50c1..096b53e 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -1,8 +1,9 @@
 obj-$(CONFIG_IOMMU_API) += iommu.o
-obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o msm_iommu_dev.o
+obj-$(CONFIG_MSM_IOMMU) += msm_iommu-v0.o msm_iommu_dev-v0.o
 ifdef CONFIG_OF
-obj-$(CONFIG_MSM_IOMMU) += msm_iommu-v2.o msm_iommu_dev-v2.o msm_iommu_pagetable.o msm_iommu_sec.o
+obj-$(CONFIG_MSM_IOMMU) += msm_iommu-v1.o msm_iommu_dev-v1.o msm_iommu_pagetable.o msm_iommu_sec.o
 endif
+obj-$(CONFIG_MSM_IOMMU_PMON) += msm_iommu_perfmon.o msm_iommu_perfmon-v0.o msm_iommu_perfmon-v1.o
 obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
 obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
 obj-$(CONFIG_DMAR_TABLE) += dmar.o
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index d07fb96..a6eae7e 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -32,7 +32,7 @@
 #include <linux/err.h>
 
 static struct kset *iommu_group_kset;
-static struct ida iommu_group_ida;
+static struct idr iommu_group_idr;
 static struct mutex iommu_group_mutex;
 
 struct iommu_group {
@@ -126,7 +126,7 @@
 		group->iommu_data_release(group->iommu_data);
 
 	mutex_lock(&iommu_group_mutex);
-	ida_remove(&iommu_group_ida, group->id);
+	idr_remove(&iommu_group_idr, group->id);
 	mutex_unlock(&iommu_group_mutex);
 
 	kfree(group->name);
@@ -167,22 +167,27 @@
 	mutex_lock(&iommu_group_mutex);
 
 again:
-	if (unlikely(0 == ida_pre_get(&iommu_group_ida, GFP_KERNEL))) {
+	if (unlikely(0 == idr_pre_get(&iommu_group_idr, GFP_KERNEL))) {
 		kfree(group);
 		mutex_unlock(&iommu_group_mutex);
 		return ERR_PTR(-ENOMEM);
 	}
 
-	if (-EAGAIN == ida_get_new(&iommu_group_ida, &group->id))
+	ret = idr_get_new_above(&iommu_group_idr, group, 1, &group->id);
+	if (ret == -EAGAIN)
 		goto again;
-
 	mutex_unlock(&iommu_group_mutex);
 
+	if (ret == -ENOSPC) {
+		kfree(group);
+		return ERR_PTR(ret);
+	}
+
 	ret = kobject_init_and_add(&group->kobj, &iommu_group_ktype,
 				   NULL, "%d", group->id);
 	if (ret) {
 		mutex_lock(&iommu_group_mutex);
-		ida_remove(&iommu_group_ida, group->id);
+		idr_remove(&iommu_group_idr, group->id);
 		mutex_unlock(&iommu_group_mutex);
 		kfree(group);
 		return ERR_PTR(ret);
@@ -426,6 +431,37 @@
 EXPORT_SYMBOL_GPL(iommu_group_get);
 
 /**
+ * iommu_group_find - Find and return the group based on the group name.
+ * Also increment the reference count.
+ * @name: the name of the group
+ *
+ * This function is called by iommu drivers and clients to get the group
+ * by the specified name.  If found, the group is returned and the group
+ * reference is incremented, else NULL.
+ */
+struct iommu_group *iommu_group_find(const char *name)
+{
+	struct iommu_group *group;
+	int next = 0;
+
+	mutex_lock(&iommu_group_mutex);
+	while ((group = idr_get_next(&iommu_group_idr, &next))) {
+		if (group->name) {
+			if (strcmp(group->name, name) == 0)
+				break;
+		}
+		++next;
+	}
+	mutex_unlock(&iommu_group_mutex);
+
+	if (group)
+		kobject_get(group->devices_kobj);
+
+	return group;
+}
+EXPORT_SYMBOL_GPL(iommu_group_find);
+
+/**
  * iommu_group_put - Decrement group reference
  * @group: the group to use
  *
@@ -888,7 +924,7 @@
 {
 	iommu_group_kset = kset_create_and_add("iommu_groups",
 					       NULL, kernel_kobj);
-	ida_init(&iommu_group_ida);
+	idr_init(&iommu_group_idr);
 	mutex_init(&iommu_group_mutex);
 
 	BUG_ON(!iommu_group_kset);
diff --git a/drivers/iommu/msm_iommu-v0.c b/drivers/iommu/msm_iommu-v0.c
new file mode 100644
index 0000000..6bf0220
--- /dev/null
+++ b/drivers/iommu/msm_iommu-v0.c
@@ -0,0 +1,1414 @@
+/* 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 pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/iommu.h>
+#include <linux/clk.h>
+#include <linux/scatterlist.h>
+
+#include <asm/cacheflush.h>
+#include <asm/sizes.h>
+
+#include <mach/iommu_perfmon.h>
+#include <mach/iommu_hw-v0.h>
+#include <mach/iommu.h>
+#include <mach/msm_smsm.h>
+
+#define MRC(reg, processor, op1, crn, crm, op2)				\
+__asm__ __volatile__ (							\
+"   mrc   "   #processor "," #op1 ", %0,"  #crn "," #crm "," #op2 "\n"  \
+: "=r" (reg))
+
+#define RCP15_PRRR(reg)		MRC(reg, p15, 0, c10, c2, 0)
+#define RCP15_NMRR(reg)		MRC(reg, p15, 0, c10, c2, 1)
+
+/* Sharability attributes of MSM IOMMU mappings */
+#define MSM_IOMMU_ATTR_NON_SH		0x0
+#define MSM_IOMMU_ATTR_SH		0x4
+
+/* Cacheability attributes of MSM IOMMU mappings */
+#define MSM_IOMMU_ATTR_NONCACHED	0x0
+#define MSM_IOMMU_ATTR_CACHED_WB_WA	0x1
+#define MSM_IOMMU_ATTR_CACHED_WB_NWA	0x2
+#define MSM_IOMMU_ATTR_CACHED_WT	0x3
+
+struct bus_type msm_iommu_sec_bus_type = {
+	.name = "msm_iommu_sec_bus",
+};
+
+static inline void clean_pte(unsigned long *start, unsigned long *end,
+			     int redirect)
+{
+	if (!redirect)
+		dmac_flush_range(start, end);
+}
+
+/* bitmap of the page sizes currently supported */
+#define MSM_IOMMU_PGSIZES	(SZ_4K | SZ_64K | SZ_1M | SZ_16M)
+
+static int msm_iommu_tex_class[4];
+
+DEFINE_MUTEX(msm_iommu_lock);
+
+/**
+ * Remote spinlock implementation based on Peterson's algorithm to be used
+ * to synchronize IOMMU config port access between CPU and GPU.
+ * This implements Process 0 of the spin lock algorithm. GPU implements
+ * Process 1. Flag and turn is stored in shared memory to allow GPU to
+ * access these.
+ */
+struct msm_iommu_remote_lock {
+	int initialized;
+	struct remote_iommu_petersons_spinlock *lock;
+};
+
+static struct msm_iommu_remote_lock msm_iommu_remote_lock;
+
+#ifdef CONFIG_MSM_IOMMU_GPU_SYNC
+static void _msm_iommu_remote_spin_lock_init(void)
+{
+	msm_iommu_remote_lock.lock = smem_alloc(SMEM_SPINLOCK_ARRAY, 32);
+	memset(msm_iommu_remote_lock.lock, 0,
+			sizeof(*msm_iommu_remote_lock.lock));
+}
+
+void msm_iommu_remote_p0_spin_lock(void)
+{
+	msm_iommu_remote_lock.lock->flag[PROC_APPS] = 1;
+	msm_iommu_remote_lock.lock->turn = 1;
+
+	smp_mb();
+
+	while (msm_iommu_remote_lock.lock->flag[PROC_GPU] == 1 &&
+	       msm_iommu_remote_lock.lock->turn == 1)
+		cpu_relax();
+}
+
+void msm_iommu_remote_p0_spin_unlock(void)
+{
+	smp_mb();
+
+	msm_iommu_remote_lock.lock->flag[PROC_APPS] = 0;
+}
+#endif
+
+inline void msm_iommu_mutex_lock(void)
+{
+	mutex_lock(&msm_iommu_lock);
+}
+
+inline void msm_iommu_mutex_unlock(void)
+{
+	mutex_unlock(&msm_iommu_lock);
+}
+
+void *msm_iommu_lock_initialize(void)
+{
+	mutex_lock(&msm_iommu_lock);
+	if (!msm_iommu_remote_lock.initialized) {
+		msm_iommu_remote_lock_init();
+		msm_iommu_remote_lock.initialized = 1;
+	}
+	mutex_unlock(&msm_iommu_lock);
+	return msm_iommu_remote_lock.lock;
+}
+
+struct msm_priv {
+	unsigned long *pgtable;
+	int redirect;
+	struct list_head list_attached;
+};
+
+static int __enable_clocks(struct msm_iommu_drvdata *drvdata)
+{
+	int ret;
+
+	ret = clk_prepare_enable(drvdata->pclk);
+	if (ret)
+		goto fail;
+
+	if (drvdata->clk) {
+		ret = clk_prepare_enable(drvdata->clk);
+		if (ret)
+			clk_disable_unprepare(drvdata->pclk);
+	}
+fail:
+	return ret;
+}
+
+static void __disable_clocks(struct msm_iommu_drvdata *drvdata)
+{
+	if (drvdata->clk)
+		clk_disable_unprepare(drvdata->clk);
+	clk_disable_unprepare(drvdata->pclk);
+}
+
+static int _iommu_power_on(void *data)
+{
+	struct msm_iommu_drvdata *drvdata;
+
+	drvdata = (struct msm_iommu_drvdata *)data;
+	return __enable_clocks(drvdata);
+}
+
+static int _iommu_power_off(void *data)
+{
+	struct msm_iommu_drvdata *drvdata;
+
+	drvdata = (struct msm_iommu_drvdata *)data;
+	__disable_clocks(drvdata);
+	return 0;
+}
+
+static void _iommu_lock_acquire(void)
+{
+	msm_iommu_lock();
+}
+
+static void _iommu_lock_release(void)
+{
+	msm_iommu_unlock();
+}
+
+struct iommu_access_ops iommu_access_ops_v0 = {
+	.iommu_power_on = _iommu_power_on,
+	.iommu_power_off = _iommu_power_off,
+	.iommu_lock_acquire = _iommu_lock_acquire,
+	.iommu_lock_release = _iommu_lock_release,
+};
+EXPORT_SYMBOL(iommu_access_ops_v0);
+
+static int __flush_iotlb_va(struct iommu_domain *domain, unsigned int va)
+{
+	struct msm_priv *priv = domain->priv;
+	struct msm_iommu_drvdata *iommu_drvdata;
+	struct msm_iommu_ctx_drvdata *ctx_drvdata;
+	int ret = 0;
+	int asid;
+
+	list_for_each_entry(ctx_drvdata, &priv->list_attached, attached_elm) {
+		if (!ctx_drvdata->pdev || !ctx_drvdata->pdev->dev.parent)
+			BUG();
+
+		iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent);
+		if (!iommu_drvdata)
+			BUG();
+
+		ret = __enable_clocks(iommu_drvdata);
+		if (ret)
+			goto fail;
+
+		msm_iommu_remote_spin_lock();
+
+		asid = GET_CONTEXTIDR_ASID(iommu_drvdata->base,
+					   ctx_drvdata->num);
+
+		SET_TLBIVA(iommu_drvdata->base, ctx_drvdata->num,
+			   asid | (va & TLBIVA_VA));
+		mb();
+
+		msm_iommu_remote_spin_unlock();
+
+		__disable_clocks(iommu_drvdata);
+	}
+fail:
+	return ret;
+}
+
+static int __flush_iotlb(struct iommu_domain *domain)
+{
+	struct msm_priv *priv = domain->priv;
+	struct msm_iommu_drvdata *iommu_drvdata;
+	struct msm_iommu_ctx_drvdata *ctx_drvdata;
+	int ret = 0;
+	int asid;
+
+	list_for_each_entry(ctx_drvdata, &priv->list_attached, attached_elm) {
+		if (!ctx_drvdata->pdev || !ctx_drvdata->pdev->dev.parent)
+			BUG();
+
+		iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent);
+		if (!iommu_drvdata)
+			BUG();
+
+		ret = __enable_clocks(iommu_drvdata);
+		if (ret)
+			goto fail;
+
+		msm_iommu_remote_spin_lock();
+
+		asid = GET_CONTEXTIDR_ASID(iommu_drvdata->base,
+					   ctx_drvdata->num);
+
+		SET_TLBIASID(iommu_drvdata->base, ctx_drvdata->num, asid);
+		mb();
+
+		msm_iommu_remote_spin_unlock();
+
+		__disable_clocks(iommu_drvdata);
+	}
+fail:
+	return ret;
+}
+
+static void __reset_context(void __iomem *base, void __iomem *glb_base, int ctx)
+{
+	SET_BPRCOSH(glb_base, ctx, 0);
+	SET_BPRCISH(glb_base, ctx, 0);
+	SET_BPRCNSH(glb_base, ctx, 0);
+	SET_BPSHCFG(glb_base, ctx, 0);
+	SET_BPMTCFG(glb_base, ctx, 0);
+	SET_ACTLR(base, ctx, 0);
+	SET_SCTLR(base, ctx, 0);
+	SET_FSRRESTORE(base, ctx, 0);
+	SET_TTBR0(base, ctx, 0);
+	SET_TTBR1(base, ctx, 0);
+	SET_TTBCR(base, ctx, 0);
+	SET_BFBCR(base, ctx, 0);
+	SET_PAR(base, ctx, 0);
+	SET_FAR(base, ctx, 0);
+	SET_TLBFLPTER(base, ctx, 0);
+	SET_TLBSLPTER(base, ctx, 0);
+	SET_TLBLKCR(base, ctx, 0);
+	SET_PRRR(base, ctx, 0);
+	SET_NMRR(base, ctx, 0);
+	mb();
+}
+
+static void __program_context(void __iomem *base, void __iomem *glb_base,
+			      int ctx, int ncb, phys_addr_t pgtable,
+			      int redirect, int ttbr_split)
+{
+	unsigned int prrr, nmrr;
+	int i, j, found;
+	msm_iommu_remote_spin_lock();
+
+	__reset_context(base, glb_base, ctx);
+
+	/* Set up HTW mode */
+	/* TLB miss configuration: perform HTW on miss */
+	SET_TLBMCFG(base, ctx, 0x3);
+
+	/* V2P configuration: HTW for access */
+	SET_V2PCFG(base, ctx, 0x3);
+
+	SET_TTBCR(base, ctx, ttbr_split);
+	SET_TTBR0_PA(base, ctx, (pgtable >> TTBR0_PA_SHIFT));
+	if (ttbr_split)
+		SET_TTBR1_PA(base, ctx, (pgtable >> TTBR1_PA_SHIFT));
+
+	/* Enable context fault interrupt */
+	SET_CFEIE(base, ctx, 1);
+
+	/* Stall access on a context fault and let the handler deal with it */
+	SET_CFCFG(base, ctx, 1);
+
+	/* Redirect all cacheable requests to L2 slave port. */
+	SET_RCISH(base, ctx, 1);
+	SET_RCOSH(base, ctx, 1);
+	SET_RCNSH(base, ctx, 1);
+
+	/* Turn on TEX Remap */
+	SET_TRE(base, ctx, 1);
+
+	/* Set TEX remap attributes */
+	RCP15_PRRR(prrr);
+	RCP15_NMRR(nmrr);
+	SET_PRRR(base, ctx, prrr);
+	SET_NMRR(base, ctx, nmrr);
+
+	/* Turn on BFB prefetch */
+	SET_BFBDFE(base, ctx, 1);
+
+	/* Configure page tables as inner-cacheable and shareable to reduce
+	 * the TLB miss penalty.
+	 */
+	if (redirect) {
+		SET_TTBR0_SH(base, ctx, 1);
+		SET_TTBR1_SH(base, ctx, 1);
+
+		SET_TTBR0_NOS(base, ctx, 1);
+		SET_TTBR1_NOS(base, ctx, 1);
+
+		SET_TTBR0_IRGNH(base, ctx, 0); /* WB, WA */
+		SET_TTBR0_IRGNL(base, ctx, 1);
+
+		SET_TTBR1_IRGNH(base, ctx, 0); /* WB, WA */
+		SET_TTBR1_IRGNL(base, ctx, 1);
+
+		SET_TTBR0_ORGN(base, ctx, 1); /* WB, WA */
+		SET_TTBR1_ORGN(base, ctx, 1); /* WB, WA */
+	}
+
+	/* Find if this page table is used elsewhere, and re-use ASID */
+	found = 0;
+	for (i = 0; i < ncb; i++)
+		if (GET_TTBR0_PA(base, i) == (pgtable >> TTBR0_PA_SHIFT) &&
+		    i != ctx) {
+			SET_CONTEXTIDR_ASID(base, ctx, \
+					    GET_CONTEXTIDR_ASID(base, i));
+			found = 1;
+			break;
+		}
+
+	/* If page table is new, find an unused ASID */
+	if (!found) {
+		for (i = 0; i < ncb; i++) {
+			found = 0;
+			for (j = 0; j < ncb; j++) {
+				if (GET_CONTEXTIDR_ASID(base, j) == i &&
+				    j != ctx)
+					found = 1;
+			}
+
+			if (!found) {
+				SET_CONTEXTIDR_ASID(base, ctx, i);
+				break;
+			}
+		}
+		BUG_ON(found);
+	}
+
+	/* Enable the MMU */
+	SET_M(base, ctx, 1);
+	mb();
+
+	msm_iommu_remote_spin_unlock();
+}
+
+static int msm_iommu_domain_init(struct iommu_domain *domain, int flags)
+{
+	struct msm_priv *priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+
+	if (!priv)
+		goto fail_nomem;
+
+	INIT_LIST_HEAD(&priv->list_attached);
+	priv->pgtable = (unsigned long *)__get_free_pages(GFP_KERNEL,
+							  get_order(SZ_16K));
+
+	if (!priv->pgtable)
+		goto fail_nomem;
+
+#ifdef CONFIG_IOMMU_PGTABLES_L2
+	priv->redirect = flags & MSM_IOMMU_DOMAIN_PT_CACHEABLE;
+#endif
+
+	memset(priv->pgtable, 0, SZ_16K);
+	domain->priv = priv;
+
+	clean_pte(priv->pgtable, priv->pgtable + NUM_FL_PTE, priv->redirect);
+
+	return 0;
+
+fail_nomem:
+	kfree(priv);
+	return -ENOMEM;
+}
+
+static void msm_iommu_domain_destroy(struct iommu_domain *domain)
+{
+	struct msm_priv *priv;
+	unsigned long *fl_table;
+	int i;
+
+	mutex_lock(&msm_iommu_lock);
+	priv = domain->priv;
+	domain->priv = NULL;
+
+	if (priv) {
+		fl_table = priv->pgtable;
+
+		for (i = 0; i < NUM_FL_PTE; i++)
+			if ((fl_table[i] & 0x03) == FL_TYPE_TABLE)
+				free_page((unsigned long) __va(((fl_table[i]) &
+								FL_BASE_MASK)));
+
+		free_pages((unsigned long)priv->pgtable, get_order(SZ_16K));
+		priv->pgtable = NULL;
+	}
+
+	kfree(priv);
+	mutex_unlock(&msm_iommu_lock);
+}
+
+static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
+{
+	struct msm_priv *priv;
+	struct msm_iommu_drvdata *iommu_drvdata;
+	struct msm_iommu_ctx_drvdata *ctx_drvdata;
+	struct msm_iommu_ctx_drvdata *tmp_drvdata;
+	int ret = 0;
+
+	mutex_lock(&msm_iommu_lock);
+
+	priv = domain->priv;
+
+	if (!priv || !dev) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	iommu_drvdata = dev_get_drvdata(dev->parent);
+	ctx_drvdata = dev_get_drvdata(dev);
+
+	if (!iommu_drvdata || !ctx_drvdata) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	++ctx_drvdata->attach_count;
+
+	if (ctx_drvdata->attach_count > 1)
+		goto unlock;
+
+	if (!list_empty(&ctx_drvdata->attached_elm)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	list_for_each_entry(tmp_drvdata, &priv->list_attached, attached_elm)
+		if (tmp_drvdata == ctx_drvdata) {
+			ret = -EBUSY;
+			goto unlock;
+		}
+
+	ret = __enable_clocks(iommu_drvdata);
+	if (ret)
+		goto unlock;
+
+	__program_context(iommu_drvdata->base, iommu_drvdata->glb_base,
+			  ctx_drvdata->num, iommu_drvdata->ncb,
+			  __pa(priv->pgtable), priv->redirect,
+			  iommu_drvdata->ttbr_split);
+
+	__disable_clocks(iommu_drvdata);
+	list_add(&(ctx_drvdata->attached_elm), &priv->list_attached);
+
+	ctx_drvdata->attached_domain = domain;
+
+	mutex_unlock(&msm_iommu_lock);
+
+	msm_iommu_attached(dev->parent);
+	return ret;
+unlock:
+	mutex_unlock(&msm_iommu_lock);
+	return ret;
+}
+
+static void msm_iommu_detach_dev(struct iommu_domain *domain,
+				 struct device *dev)
+{
+	struct msm_priv *priv;
+	struct msm_iommu_drvdata *iommu_drvdata;
+	struct msm_iommu_ctx_drvdata *ctx_drvdata;
+	int ret;
+
+	msm_iommu_detached(dev->parent);
+
+	mutex_lock(&msm_iommu_lock);
+	priv = domain->priv;
+
+	if (!priv || !dev)
+		goto unlock;
+
+	iommu_drvdata = dev_get_drvdata(dev->parent);
+	ctx_drvdata = dev_get_drvdata(dev);
+
+	if (!iommu_drvdata || !ctx_drvdata)
+		goto unlock;
+
+	--ctx_drvdata->attach_count;
+	BUG_ON(ctx_drvdata->attach_count < 0);
+
+	if (ctx_drvdata->attach_count > 0)
+		goto unlock;
+
+	ret = __enable_clocks(iommu_drvdata);
+	if (ret)
+		goto unlock;
+
+	msm_iommu_remote_spin_lock();
+
+	SET_TLBIASID(iommu_drvdata->base, ctx_drvdata->num,
+		    GET_CONTEXTIDR_ASID(iommu_drvdata->base, ctx_drvdata->num));
+
+	__reset_context(iommu_drvdata->base, iommu_drvdata->glb_base,
+			ctx_drvdata->num);
+
+	msm_iommu_remote_spin_unlock();
+
+	__disable_clocks(iommu_drvdata);
+	list_del_init(&ctx_drvdata->attached_elm);
+	ctx_drvdata->attached_domain = NULL;
+unlock:
+	mutex_unlock(&msm_iommu_lock);
+}
+
+static int __get_pgprot(int prot, int len)
+{
+	unsigned int pgprot;
+	int tex;
+
+	if (!(prot & (IOMMU_READ | IOMMU_WRITE))) {
+		prot |= IOMMU_READ | IOMMU_WRITE;
+		WARN_ONCE(1, "No attributes in iommu mapping; assuming RW\n");
+	}
+
+	if ((prot & IOMMU_WRITE) && !(prot & IOMMU_READ)) {
+		prot |= IOMMU_READ;
+		WARN_ONCE(1, "Write-only iommu mappings unsupported; falling back to RW\n");
+	}
+
+	if (prot & IOMMU_CACHE)
+		tex = (pgprot_kernel >> 2) & 0x07;
+	else
+		tex = msm_iommu_tex_class[MSM_IOMMU_ATTR_NONCACHED];
+
+	if (tex < 0 || tex > NUM_TEX_CLASS - 1)
+		return 0;
+
+	if (len == SZ_16M || len == SZ_1M) {
+		pgprot = FL_SHARED;
+		pgprot |= tex & 0x01 ? FL_BUFFERABLE : 0;
+		pgprot |= tex & 0x02 ? FL_CACHEABLE : 0;
+		pgprot |= tex & 0x04 ? FL_TEX0 : 0;
+		pgprot |= FL_AP0 | FL_AP1;
+		pgprot |= prot & IOMMU_WRITE ? 0 : FL_AP2;
+	} else	{
+		pgprot = SL_SHARED;
+		pgprot |= tex & 0x01 ? SL_BUFFERABLE : 0;
+		pgprot |= tex & 0x02 ? SL_CACHEABLE : 0;
+		pgprot |= tex & 0x04 ? SL_TEX0 : 0;
+		pgprot |= SL_AP0 | SL_AP1;
+		pgprot |= prot & IOMMU_WRITE ? 0 : SL_AP2;
+	}
+
+	return pgprot;
+}
+
+static unsigned long *make_second_level(struct msm_priv *priv,
+					unsigned long *fl_pte)
+{
+	unsigned long *sl;
+	sl = (unsigned long *) __get_free_pages(GFP_KERNEL,
+			get_order(SZ_4K));
+
+	if (!sl) {
+		pr_debug("Could not allocate second level table\n");
+		goto fail;
+	}
+	memset(sl, 0, SZ_4K);
+	clean_pte(sl, sl + NUM_SL_PTE, priv->redirect);
+
+	*fl_pte = ((((int)__pa(sl)) & FL_BASE_MASK) | \
+			FL_TYPE_TABLE);
+
+	clean_pte(fl_pte, fl_pte + 1, priv->redirect);
+fail:
+	return sl;
+}
+
+static int sl_4k(unsigned long *sl_pte, phys_addr_t pa, unsigned int pgprot)
+{
+	int ret = 0;
+
+	if (*sl_pte) {
+		ret = -EBUSY;
+		goto fail;
+	}
+
+	*sl_pte = (pa & SL_BASE_MASK_SMALL) | SL_NG | SL_SHARED
+		| SL_TYPE_SMALL | pgprot;
+fail:
+	return ret;
+}
+
+static int sl_64k(unsigned long *sl_pte, phys_addr_t pa, unsigned int pgprot)
+{
+	int ret = 0;
+
+	int i;
+
+	for (i = 0; i < 16; i++)
+		if (*(sl_pte+i)) {
+			ret = -EBUSY;
+			goto fail;
+		}
+
+	for (i = 0; i < 16; i++)
+		*(sl_pte+i) = (pa & SL_BASE_MASK_LARGE) | SL_NG
+				| SL_SHARED | SL_TYPE_LARGE | pgprot;
+
+fail:
+	return ret;
+}
+
+
+static inline int fl_1m(unsigned long *fl_pte, phys_addr_t pa, int pgprot)
+{
+	if (*fl_pte)
+		return -EBUSY;
+
+	*fl_pte = (pa & 0xFFF00000) | FL_NG | FL_TYPE_SECT | FL_SHARED
+		| pgprot;
+
+	return 0;
+}
+
+
+static inline int fl_16m(unsigned long *fl_pte, phys_addr_t pa, int pgprot)
+{
+	int i;
+	int ret = 0;
+	for (i = 0; i < 16; i++)
+		if (*(fl_pte+i)) {
+			ret = -EBUSY;
+			goto fail;
+		}
+	for (i = 0; i < 16; i++)
+		*(fl_pte+i) = (pa & 0xFF000000) | FL_SUPERSECTION
+			| FL_TYPE_SECT | FL_SHARED | FL_NG | pgprot;
+fail:
+	return ret;
+}
+
+static int msm_iommu_map(struct iommu_domain *domain, unsigned long va,
+			 phys_addr_t pa, size_t len, int prot)
+{
+	struct msm_priv *priv;
+	unsigned long *fl_table;
+	unsigned long *fl_pte;
+	unsigned long fl_offset;
+	unsigned long *sl_table;
+	unsigned long *sl_pte;
+	unsigned long sl_offset;
+	unsigned int pgprot;
+	int ret = 0;
+
+	mutex_lock(&msm_iommu_lock);
+
+	priv = domain->priv;
+	if (!priv) {
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	fl_table = priv->pgtable;
+
+	if (len != SZ_16M && len != SZ_1M &&
+	    len != SZ_64K && len != SZ_4K) {
+		pr_debug("Bad size: %d\n", len);
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	if (!fl_table) {
+		pr_debug("Null page table\n");
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	pgprot = __get_pgprot(prot, len);
+
+	if (!pgprot) {
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	fl_offset = FL_OFFSET(va);	/* Upper 12 bits */
+	fl_pte = fl_table + fl_offset;	/* int pointers, 4 bytes */
+
+	if (len == SZ_16M) {
+		ret = fl_16m(fl_pte, pa, pgprot);
+		if (ret)
+			goto fail;
+		clean_pte(fl_pte, fl_pte + 16, priv->redirect);
+	}
+
+	if (len == SZ_1M) {
+		ret = fl_1m(fl_pte, pa, pgprot);
+		if (ret)
+			goto fail;
+		clean_pte(fl_pte, fl_pte + 1, priv->redirect);
+	}
+
+	/* Need a 2nd level table */
+	if (len == SZ_4K || len == SZ_64K) {
+
+		if (*fl_pte == 0) {
+			if (make_second_level(priv, fl_pte) == NULL) {
+				ret = -ENOMEM;
+				goto fail;
+			}
+		}
+
+		if (!(*fl_pte & FL_TYPE_TABLE)) {
+			ret = -EBUSY;
+			goto fail;
+		}
+	}
+
+	sl_table = (unsigned long *) __va(((*fl_pte) & FL_BASE_MASK));
+	sl_offset = SL_OFFSET(va);
+	sl_pte = sl_table + sl_offset;
+
+	if (len == SZ_4K) {
+		ret = sl_4k(sl_pte, pa, pgprot);
+		if (ret)
+			goto fail;
+
+		clean_pte(sl_pte, sl_pte + 1, priv->redirect);
+	}
+
+	if (len == SZ_64K) {
+		ret = sl_64k(sl_pte, pa, pgprot);
+		if (ret)
+			goto fail;
+		clean_pte(sl_pte, sl_pte + 16, priv->redirect);
+	}
+
+	ret = __flush_iotlb_va(domain, va);
+fail:
+	mutex_unlock(&msm_iommu_lock);
+	return ret;
+}
+
+static size_t msm_iommu_unmap(struct iommu_domain *domain, unsigned long va,
+			    size_t len)
+{
+	struct msm_priv *priv;
+	unsigned long *fl_table;
+	unsigned long *fl_pte;
+	unsigned long fl_offset;
+	unsigned long *sl_table;
+	unsigned long *sl_pte;
+	unsigned long sl_offset;
+	int i, ret = 0;
+
+	mutex_lock(&msm_iommu_lock);
+
+	priv = domain->priv;
+
+	if (!priv)
+		goto fail;
+
+	fl_table = priv->pgtable;
+
+	if (len != SZ_16M && len != SZ_1M &&
+	    len != SZ_64K && len != SZ_4K) {
+		pr_debug("Bad length: %d\n", len);
+		goto fail;
+	}
+
+	if (!fl_table) {
+		pr_debug("Null page table\n");
+		goto fail;
+	}
+
+	fl_offset = FL_OFFSET(va);	/* Upper 12 bits */
+	fl_pte = fl_table + fl_offset;	/* int pointers, 4 bytes */
+
+	if (*fl_pte == 0) {
+		pr_debug("First level PTE is 0\n");
+		goto fail;
+	}
+
+	/* Unmap supersection */
+	if (len == SZ_16M) {
+		for (i = 0; i < 16; i++)
+			*(fl_pte+i) = 0;
+
+		clean_pte(fl_pte, fl_pte + 16, priv->redirect);
+	}
+
+	if (len == SZ_1M) {
+		*fl_pte = 0;
+
+		clean_pte(fl_pte, fl_pte + 1, priv->redirect);
+	}
+
+	sl_table = (unsigned long *) __va(((*fl_pte) & FL_BASE_MASK));
+	sl_offset = SL_OFFSET(va);
+	sl_pte = sl_table + sl_offset;
+
+	if (len == SZ_64K) {
+		for (i = 0; i < 16; i++)
+			*(sl_pte+i) = 0;
+
+		clean_pte(sl_pte, sl_pte + 16, priv->redirect);
+	}
+
+	if (len == SZ_4K) {
+		*sl_pte = 0;
+
+		clean_pte(sl_pte, sl_pte + 1, priv->redirect);
+	}
+
+	if (len == SZ_4K || len == SZ_64K) {
+		int used = 0;
+
+		for (i = 0; i < NUM_SL_PTE; i++)
+			if (sl_table[i])
+				used = 1;
+		if (!used) {
+			free_page((unsigned long)sl_table);
+			*fl_pte = 0;
+
+			clean_pte(fl_pte, fl_pte + 1, priv->redirect);
+		}
+	}
+
+	ret = __flush_iotlb_va(domain, va);
+
+fail:
+	mutex_unlock(&msm_iommu_lock);
+
+	/* the IOMMU API requires us to return how many bytes were unmapped */
+	len = ret ? 0 : len;
+	return len;
+}
+
+static unsigned int get_phys_addr(struct scatterlist *sg)
+{
+	/*
+	 * Try sg_dma_address first so that we can
+	 * map carveout regions that do not have a
+	 * struct page associated with them.
+	 */
+	unsigned int pa = sg_dma_address(sg);
+	if (pa == 0)
+		pa = sg_phys(sg);
+	return pa;
+}
+
+static inline int is_fully_aligned(unsigned int va, phys_addr_t pa, size_t len,
+				   int align)
+{
+	return  IS_ALIGNED(va, align) && IS_ALIGNED(pa, align)
+		&& (len >= align);
+}
+
+static int check_range(unsigned long *fl_table, unsigned int va,
+				 unsigned int len)
+{
+	unsigned int offset = 0;
+	unsigned long *fl_pte;
+	unsigned long fl_offset;
+	unsigned long *sl_table;
+	unsigned long sl_start, sl_end;
+	int i;
+
+	fl_offset = FL_OFFSET(va);	/* Upper 12 bits */
+	fl_pte = fl_table + fl_offset;	/* int pointers, 4 bytes */
+
+	while (offset < len) {
+		if (*fl_pte & FL_TYPE_TABLE) {
+			sl_start = SL_OFFSET(va);
+			sl_table =  __va(((*fl_pte) & FL_BASE_MASK));
+			sl_end = ((len - offset) / SZ_4K) + sl_start;
+
+			if (sl_end > NUM_SL_PTE)
+				sl_end = NUM_SL_PTE;
+
+			for (i = sl_start; i < sl_end; i++) {
+				if (sl_table[i] != 0) {
+					pr_err("%08x - %08x already mapped\n",
+						va, va + SZ_4K);
+					return -EBUSY;
+				}
+				offset += SZ_4K;
+				va += SZ_4K;
+			}
+
+
+			sl_start = 0;
+		} else {
+			if (*fl_pte != 0) {
+				pr_err("%08x - %08x already mapped\n",
+				       va, va + SZ_1M);
+				return -EBUSY;
+			}
+			va += SZ_1M;
+			offset += SZ_1M;
+			sl_start = 0;
+		}
+		fl_pte++;
+	}
+	return 0;
+}
+
+static int msm_iommu_map_range(struct iommu_domain *domain, unsigned int va,
+			       struct scatterlist *sg, unsigned int len,
+			       int prot)
+{
+	unsigned int pa;
+	unsigned int offset = 0;
+	unsigned long *fl_table;
+	unsigned long *fl_pte;
+	unsigned long fl_offset;
+	unsigned long *sl_table = NULL;
+	unsigned long sl_offset, sl_start;
+	unsigned int chunk_size, chunk_offset = 0;
+	int ret = 0;
+	struct msm_priv *priv;
+	unsigned int pgprot4k, pgprot64k, pgprot1m, pgprot16m;
+
+	mutex_lock(&msm_iommu_lock);
+
+	BUG_ON(len & (SZ_4K - 1));
+
+	priv = domain->priv;
+	fl_table = priv->pgtable;
+
+	pgprot4k = __get_pgprot(prot, SZ_4K);
+	pgprot64k = __get_pgprot(prot, SZ_64K);
+	pgprot1m = __get_pgprot(prot, SZ_1M);
+	pgprot16m = __get_pgprot(prot, SZ_16M);
+
+	if (!pgprot4k || !pgprot64k || !pgprot1m || !pgprot16m) {
+		ret = -EINVAL;
+		goto fail;
+	}
+	ret = check_range(fl_table, va, len);
+	if (ret)
+		goto fail;
+
+	fl_offset = FL_OFFSET(va);	/* Upper 12 bits */
+	fl_pte = fl_table + fl_offset;	/* int pointers, 4 bytes */
+	pa = get_phys_addr(sg);
+
+	while (offset < len) {
+		chunk_size = SZ_4K;
+
+		if (is_fully_aligned(va, pa, sg->length - chunk_offset,
+				     SZ_16M))
+			chunk_size = SZ_16M;
+		else if (is_fully_aligned(va, pa, sg->length - chunk_offset,
+					  SZ_1M))
+			chunk_size = SZ_1M;
+		/* 64k or 4k determined later */
+
+		/* for 1M and 16M, only first level entries are required */
+		if (chunk_size >= SZ_1M) {
+			if (chunk_size == SZ_16M) {
+				ret = fl_16m(fl_pte, pa, pgprot16m);
+				if (ret)
+					goto fail;
+				clean_pte(fl_pte, fl_pte + 16, priv->redirect);
+				fl_pte += 16;
+			} else if (chunk_size == SZ_1M) {
+				ret = fl_1m(fl_pte, pa, pgprot1m);
+				if (ret)
+					goto fail;
+				clean_pte(fl_pte, fl_pte + 1, priv->redirect);
+				fl_pte++;
+			}
+
+			offset += chunk_size;
+			chunk_offset += chunk_size;
+			va += chunk_size;
+			pa += chunk_size;
+
+			if (chunk_offset >= sg->length && offset < len) {
+				chunk_offset = 0;
+				sg = sg_next(sg);
+				pa = get_phys_addr(sg);
+				if (pa == 0) {
+					pr_debug("No dma address for sg %p\n",
+							sg);
+					ret = -EINVAL;
+					goto fail;
+				}
+			}
+			continue;
+		}
+		/* for 4K or 64K, make sure there is a second level table */
+		if (*fl_pte == 0) {
+			if (!make_second_level(priv, fl_pte)) {
+				ret = -ENOMEM;
+				goto fail;
+			}
+		}
+		if (!(*fl_pte & FL_TYPE_TABLE)) {
+			ret = -EBUSY;
+			goto fail;
+		}
+		sl_table = __va(((*fl_pte) & FL_BASE_MASK));
+		sl_offset = SL_OFFSET(va);
+		/* Keep track of initial position so we
+		 * don't clean more than we have to
+		 */
+		sl_start = sl_offset;
+
+		/* Build the 2nd level page table */
+		while (offset < len && sl_offset < NUM_SL_PTE) {
+
+			/* Map a large 64K page if the chunk is large enough and
+			 * the pa and va are aligned
+			 */
+
+			if (is_fully_aligned(va, pa, sg->length - chunk_offset,
+					     SZ_64K))
+				chunk_size = SZ_64K;
+			else
+				chunk_size = SZ_4K;
+
+			if (chunk_size == SZ_4K) {
+				sl_4k(&sl_table[sl_offset], pa, pgprot4k);
+				sl_offset++;
+			} else {
+				BUG_ON(sl_offset + 16 > NUM_SL_PTE);
+				sl_64k(&sl_table[sl_offset], pa, pgprot64k);
+				sl_offset += 16;
+			}
+
+
+			offset += chunk_size;
+			chunk_offset += chunk_size;
+			va += chunk_size;
+			pa += chunk_size;
+
+			if (chunk_offset >= sg->length && offset < len) {
+				chunk_offset = 0;
+				sg = sg_next(sg);
+				pa = get_phys_addr(sg);
+				if (pa == 0) {
+					pr_debug("No dma address for sg %p\n",
+							sg);
+					ret = -EINVAL;
+					goto fail;
+				}
+			}
+		}
+
+		clean_pte(sl_table + sl_start, sl_table + sl_offset,
+				priv->redirect);
+
+		fl_pte++;
+		sl_offset = 0;
+	}
+	__flush_iotlb(domain);
+fail:
+	mutex_unlock(&msm_iommu_lock);
+	return ret;
+}
+
+
+static int msm_iommu_unmap_range(struct iommu_domain *domain, unsigned int va,
+				 unsigned int len)
+{
+	unsigned int offset = 0;
+	unsigned long *fl_table;
+	unsigned long *fl_pte;
+	unsigned long fl_offset;
+	unsigned long *sl_table;
+	unsigned long sl_start, sl_end;
+	int used, i;
+	struct msm_priv *priv;
+
+	mutex_lock(&msm_iommu_lock);
+
+	BUG_ON(len & (SZ_4K - 1));
+
+	priv = domain->priv;
+	fl_table = priv->pgtable;
+
+	fl_offset = FL_OFFSET(va);	/* Upper 12 bits */
+	fl_pte = fl_table + fl_offset;	/* int pointers, 4 bytes */
+
+	while (offset < len) {
+		if (*fl_pte & FL_TYPE_TABLE) {
+			sl_start = SL_OFFSET(va);
+			sl_table =  __va(((*fl_pte) & FL_BASE_MASK));
+			sl_end = ((len - offset) / SZ_4K) + sl_start;
+
+			if (sl_end > NUM_SL_PTE)
+				sl_end = NUM_SL_PTE;
+
+			memset(sl_table + sl_start, 0, (sl_end - sl_start) * 4);
+			clean_pte(sl_table + sl_start, sl_table + sl_end,
+					priv->redirect);
+
+			offset += (sl_end - sl_start) * SZ_4K;
+			va += (sl_end - sl_start) * SZ_4K;
+
+			/* Unmap and free the 2nd level table if all mappings
+			 * in it were removed. This saves memory, but the table
+			 * will need to be re-allocated the next time someone
+			 * tries to map these VAs.
+			 */
+			used = 0;
+
+			/* If we just unmapped the whole table, don't bother
+			 * seeing if there are still used entries left.
+			 */
+			if (sl_end - sl_start != NUM_SL_PTE)
+				for (i = 0; i < NUM_SL_PTE; i++)
+					if (sl_table[i]) {
+						used = 1;
+						break;
+					}
+			if (!used) {
+				free_page((unsigned long)sl_table);
+				*fl_pte = 0;
+
+				clean_pte(fl_pte, fl_pte + 1, priv->redirect);
+			}
+
+			sl_start = 0;
+		} else {
+			*fl_pte = 0;
+			clean_pte(fl_pte, fl_pte + 1, priv->redirect);
+			va += SZ_1M;
+			offset += SZ_1M;
+			sl_start = 0;
+		}
+		fl_pte++;
+	}
+
+	__flush_iotlb(domain);
+	mutex_unlock(&msm_iommu_lock);
+	return 0;
+}
+
+static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain,
+					  unsigned long va)
+{
+	struct msm_priv *priv;
+	struct msm_iommu_drvdata *iommu_drvdata;
+	struct msm_iommu_ctx_drvdata *ctx_drvdata;
+	unsigned int par;
+	void __iomem *base;
+	phys_addr_t ret = 0;
+	int ctx;
+
+	mutex_lock(&msm_iommu_lock);
+
+	priv = domain->priv;
+	if (list_empty(&priv->list_attached))
+		goto fail;
+
+	ctx_drvdata = list_entry(priv->list_attached.next,
+				 struct msm_iommu_ctx_drvdata, attached_elm);
+	iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent);
+
+	base = iommu_drvdata->base;
+	ctx = ctx_drvdata->num;
+
+	ret = __enable_clocks(iommu_drvdata);
+	if (ret)
+		goto fail;
+
+	msm_iommu_remote_spin_lock();
+
+	SET_V2PPR(base, ctx, va & V2Pxx_VA);
+
+	mb();
+	par = GET_PAR(base, ctx);
+
+	/* We are dealing with a supersection */
+	if (GET_NOFAULT_SS(base, ctx))
+		ret = (par & 0xFF000000) | (va & 0x00FFFFFF);
+	else	/* Upper 20 bits from PAR, lower 12 from VA */
+		ret = (par & 0xFFFFF000) | (va & 0x00000FFF);
+
+	if (GET_FAULT(base, ctx))
+		ret = 0;
+
+	msm_iommu_remote_spin_unlock();
+
+	__disable_clocks(iommu_drvdata);
+fail:
+	mutex_unlock(&msm_iommu_lock);
+	return ret;
+}
+
+static int msm_iommu_domain_has_cap(struct iommu_domain *domain,
+				    unsigned long cap)
+{
+	return 0;
+}
+
+static void print_ctx_regs(void __iomem *base, int ctx)
+{
+	unsigned int fsr = GET_FSR(base, ctx);
+	pr_err("FAR    = %08x    PAR    = %08x\n",
+	       GET_FAR(base, ctx), GET_PAR(base, ctx));
+	pr_err("FSR    = %08x [%s%s%s%s%s%s%s%s%s%s]\n", fsr,
+			(fsr & 0x02) ? "TF " : "",
+			(fsr & 0x04) ? "AFF " : "",
+			(fsr & 0x08) ? "APF " : "",
+			(fsr & 0x10) ? "TLBMF " : "",
+			(fsr & 0x20) ? "HTWDEEF " : "",
+			(fsr & 0x40) ? "HTWSEEF " : "",
+			(fsr & 0x80) ? "MHF " : "",
+			(fsr & 0x10000) ? "SL " : "",
+			(fsr & 0x40000000) ? "SS " : "",
+			(fsr & 0x80000000) ? "MULTI " : "");
+
+	pr_err("FSYNR0 = %08x    FSYNR1 = %08x\n",
+	       GET_FSYNR0(base, ctx), GET_FSYNR1(base, ctx));
+	pr_err("TTBR0  = %08x    TTBR1  = %08x\n",
+	       GET_TTBR0(base, ctx), GET_TTBR1(base, ctx));
+	pr_err("SCTLR  = %08x    ACTLR  = %08x\n",
+	       GET_SCTLR(base, ctx), GET_ACTLR(base, ctx));
+	pr_err("PRRR   = %08x    NMRR   = %08x\n",
+	       GET_PRRR(base, ctx), GET_NMRR(base, ctx));
+}
+
+irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id)
+{
+	struct msm_iommu_ctx_drvdata *ctx_drvdata = dev_id;
+	struct msm_iommu_drvdata *drvdata;
+	void __iomem *base;
+	unsigned int fsr, num;
+	int ret;
+
+	mutex_lock(&msm_iommu_lock);
+	BUG_ON(!ctx_drvdata);
+
+	drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent);
+	BUG_ON(!drvdata);
+
+	base = drvdata->base;
+	num = ctx_drvdata->num;
+
+	ret = __enable_clocks(drvdata);
+	if (ret)
+		goto fail;
+
+	msm_iommu_remote_spin_lock();
+
+	fsr = GET_FSR(base, num);
+
+	if (fsr) {
+		if (!ctx_drvdata->attached_domain) {
+			pr_err("Bad domain in interrupt handler\n");
+			ret = -ENOSYS;
+		} else
+			ret = report_iommu_fault(ctx_drvdata->attached_domain,
+						&ctx_drvdata->pdev->dev,
+						GET_FAR(base, num), 0);
+
+		if (ret == -ENOSYS) {
+			pr_err("Unexpected IOMMU page fault!\n");
+			pr_err("name    = %s\n", drvdata->name);
+			pr_err("context = %s (%d)\n", ctx_drvdata->name, num);
+			pr_err("Interesting registers:\n");
+			print_ctx_regs(base, num);
+		}
+
+		SET_FSR(base, num, fsr);
+		/*
+		 * Only resume fetches if the registered fault handler
+		 * allows it
+		 */
+		if (ret != -EBUSY)
+			SET_RESUME(base, num, 1);
+
+		ret = IRQ_HANDLED;
+	} else
+		ret = IRQ_NONE;
+
+	msm_iommu_remote_spin_unlock();
+
+	__disable_clocks(drvdata);
+fail:
+	mutex_unlock(&msm_iommu_lock);
+	return ret;
+}
+
+static phys_addr_t msm_iommu_get_pt_base_addr(struct iommu_domain *domain)
+{
+	struct msm_priv *priv = domain->priv;
+	return __pa(priv->pgtable);
+}
+
+static struct iommu_ops msm_iommu_ops = {
+	.domain_init = msm_iommu_domain_init,
+	.domain_destroy = msm_iommu_domain_destroy,
+	.attach_dev = msm_iommu_attach_dev,
+	.detach_dev = msm_iommu_detach_dev,
+	.map = msm_iommu_map,
+	.unmap = msm_iommu_unmap,
+	.map_range = msm_iommu_map_range,
+	.unmap_range = msm_iommu_unmap_range,
+	.iova_to_phys = msm_iommu_iova_to_phys,
+	.domain_has_cap = msm_iommu_domain_has_cap,
+	.get_pt_base_addr = msm_iommu_get_pt_base_addr,
+	.pgsize_bitmap = MSM_IOMMU_PGSIZES,
+};
+
+static int __init get_tex_class(int icp, int ocp, int mt, int nos)
+{
+	int i = 0;
+	unsigned int prrr = 0;
+	unsigned int nmrr = 0;
+	int c_icp, c_ocp, c_mt, c_nos;
+
+	RCP15_PRRR(prrr);
+	RCP15_NMRR(nmrr);
+
+	for (i = 0; i < NUM_TEX_CLASS; i++) {
+		c_nos = PRRR_NOS(prrr, i);
+		c_mt = PRRR_MT(prrr, i);
+		c_icp = NMRR_ICP(nmrr, i);
+		c_ocp = NMRR_OCP(nmrr, i);
+
+		if (icp == c_icp && ocp == c_ocp && c_mt == mt && c_nos == nos)
+			return i;
+	}
+
+	return -ENODEV;
+}
+
+static void __init setup_iommu_tex_classes(void)
+{
+	msm_iommu_tex_class[MSM_IOMMU_ATTR_NONCACHED] =
+			get_tex_class(CP_NONCACHED, CP_NONCACHED, MT_NORMAL, 1);
+
+	msm_iommu_tex_class[MSM_IOMMU_ATTR_CACHED_WB_WA] =
+			get_tex_class(CP_WB_WA, CP_WB_WA, MT_NORMAL, 1);
+
+	msm_iommu_tex_class[MSM_IOMMU_ATTR_CACHED_WB_NWA] =
+			get_tex_class(CP_WB_NWA, CP_WB_NWA, MT_NORMAL, 1);
+
+	msm_iommu_tex_class[MSM_IOMMU_ATTR_CACHED_WT] =
+			get_tex_class(CP_WT, CP_WT, MT_NORMAL, 1);
+}
+
+static int __init msm_iommu_init(void)
+{
+	if (!msm_soc_version_supports_iommu_v0())
+		return -ENODEV;
+
+	msm_iommu_lock_initialize();
+
+	setup_iommu_tex_classes();
+	bus_set_iommu(&platform_bus_type, &msm_iommu_ops);
+	return 0;
+}
+
+subsys_initcall(msm_iommu_init);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");
diff --git a/drivers/iommu/msm_iommu-v1.c b/drivers/iommu/msm_iommu-v1.c
new file mode 100644
index 0000000..15a81ed
--- /dev/null
+++ b/drivers/iommu/msm_iommu-v1.c
@@ -0,0 +1,954 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/iommu.h>
+#include <linux/clk.h>
+#include <linux/scatterlist.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/regulator/consumer.h>
+#include <asm/sizes.h>
+
+#include <mach/iommu_hw-v1.h>
+#include <mach/iommu.h>
+#include <mach/iommu_perfmon.h>
+#include "msm_iommu_pagetable.h"
+
+/* bitmap of the page sizes currently supported */
+#define MSM_IOMMU_PGSIZES	(SZ_4K | SZ_64K | SZ_1M | SZ_16M)
+
+static DEFINE_MUTEX(msm_iommu_lock);
+
+struct msm_priv {
+	struct iommu_pt pt;
+	struct list_head list_attached;
+};
+
+static int __enable_regulators(struct msm_iommu_drvdata *drvdata)
+{
+	int ret = regulator_enable(drvdata->gdsc);
+	if (ret)
+		goto fail;
+
+	if (drvdata->alt_gdsc)
+		ret = regulator_enable(drvdata->alt_gdsc);
+
+	if (ret)
+		regulator_disable(drvdata->gdsc);
+fail:
+	return ret;
+}
+
+static void __disable_regulators(struct msm_iommu_drvdata *drvdata)
+{
+	if (drvdata->alt_gdsc)
+		regulator_disable(drvdata->alt_gdsc);
+
+	regulator_disable(drvdata->gdsc);
+}
+
+static int __enable_clocks(struct msm_iommu_drvdata *drvdata)
+{
+	int ret;
+
+	ret = clk_prepare_enable(drvdata->pclk);
+	if (ret)
+		goto fail;
+
+	ret = clk_prepare_enable(drvdata->clk);
+	if (ret)
+		clk_disable_unprepare(drvdata->pclk);
+
+	if (drvdata->aclk) {
+		ret = clk_prepare_enable(drvdata->aclk);
+		if (ret) {
+			clk_disable_unprepare(drvdata->clk);
+			clk_disable_unprepare(drvdata->pclk);
+		}
+	}
+
+	if (drvdata->clk_reg_virt) {
+		unsigned int value;
+
+		value = readl_relaxed(drvdata->clk_reg_virt);
+		value &= ~0x1;
+		writel_relaxed(value, drvdata->clk_reg_virt);
+		/* Ensure clock is on before continuing */
+		mb();
+	}
+fail:
+	return ret;
+}
+
+static void __disable_clocks(struct msm_iommu_drvdata *drvdata)
+{
+	if (drvdata->aclk)
+		clk_disable_unprepare(drvdata->aclk);
+	clk_disable_unprepare(drvdata->clk);
+	clk_disable_unprepare(drvdata->pclk);
+}
+
+static int _iommu_power_off(void *data)
+{
+	struct msm_iommu_drvdata *drvdata;
+
+	drvdata = (struct msm_iommu_drvdata *)data;
+	__disable_clocks(drvdata);
+	__disable_regulators(drvdata);
+	return 0;
+}
+
+static int _iommu_power_on(void *data)
+{
+	int ret;
+	struct msm_iommu_drvdata *drvdata;
+
+	drvdata = (struct msm_iommu_drvdata *)data;
+	ret = __enable_regulators(drvdata);
+	if (ret)
+		goto fail;
+
+	ret = __enable_clocks(drvdata);
+	if (ret) {
+		__disable_regulators(drvdata);
+		goto fail;
+	}
+	return 0;
+fail:
+	return -EIO;
+}
+
+static void _iommu_lock_acquire(void)
+{
+	mutex_lock(&msm_iommu_lock);
+}
+
+static void _iommu_lock_release(void)
+{
+	mutex_unlock(&msm_iommu_lock);
+}
+
+struct iommu_access_ops iommu_access_ops_v1 = {
+	.iommu_power_on = _iommu_power_on,
+	.iommu_power_off = _iommu_power_off,
+	.iommu_lock_acquire = _iommu_lock_acquire,
+	.iommu_lock_release = _iommu_lock_release,
+};
+EXPORT_SYMBOL(iommu_access_ops_v1);
+
+void iommu_halt(const struct msm_iommu_drvdata *iommu_drvdata)
+{
+	if (iommu_drvdata->halt_enabled) {
+		SET_MICRO_MMU_CTRL_HALT_REQ(iommu_drvdata->base, 1);
+
+		while (GET_MICRO_MMU_CTRL_IDLE(iommu_drvdata->base) == 0)
+			cpu_relax();
+		/* Ensure device is idle before continuing */
+		mb();
+	}
+}
+
+void iommu_resume(const struct msm_iommu_drvdata *iommu_drvdata)
+{
+	if (iommu_drvdata->halt_enabled) {
+		/*
+		 * Ensure transactions have completed before releasing
+		 * the halt
+		 */
+		mb();
+		SET_MICRO_MMU_CTRL_HALT_REQ(iommu_drvdata->base, 0);
+		/*
+		 * Ensure write is complete before continuing to ensure
+		 * we don't turn off clocks while transaction is still
+		 * pending.
+		 */
+		mb();
+	}
+}
+
+static void __sync_tlb(void __iomem *base, int ctx)
+{
+	SET_TLBSYNC(base, ctx, 0);
+
+	/* No barrier needed due to register proximity */
+	while (GET_CB_TLBSTATUS_SACTIVE(base, ctx))
+		cpu_relax();
+
+	/* No barrier needed due to read dependency */
+}
+
+static int __flush_iotlb_va(struct iommu_domain *domain, unsigned int va)
+{
+	struct msm_priv *priv = domain->priv;
+	struct msm_iommu_drvdata *iommu_drvdata;
+	struct msm_iommu_ctx_drvdata *ctx_drvdata;
+	int ret = 0;
+	int asid;
+
+	list_for_each_entry(ctx_drvdata, &priv->list_attached, attached_elm) {
+		BUG_ON(!ctx_drvdata->pdev || !ctx_drvdata->pdev->dev.parent);
+
+		iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent);
+		BUG_ON(!iommu_drvdata);
+
+
+		ret = __enable_clocks(iommu_drvdata);
+		if (ret)
+			goto fail;
+
+		asid = GET_CB_CONTEXTIDR_ASID(iommu_drvdata->base,
+					   ctx_drvdata->num);
+
+		SET_TLBIVA(iommu_drvdata->base, ctx_drvdata->num,
+			   asid | (va & CB_TLBIVA_VA));
+		mb();
+		__sync_tlb(iommu_drvdata->base, ctx_drvdata->num);
+		__disable_clocks(iommu_drvdata);
+	}
+fail:
+	return ret;
+}
+
+static int __flush_iotlb(struct iommu_domain *domain)
+{
+	struct msm_priv *priv = domain->priv;
+	struct msm_iommu_drvdata *iommu_drvdata;
+	struct msm_iommu_ctx_drvdata *ctx_drvdata;
+	int ret = 0;
+	int asid;
+
+	list_for_each_entry(ctx_drvdata, &priv->list_attached, attached_elm) {
+		BUG_ON(!ctx_drvdata->pdev || !ctx_drvdata->pdev->dev.parent);
+
+		iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent);
+		BUG_ON(!iommu_drvdata);
+
+		ret = __enable_clocks(iommu_drvdata);
+		if (ret)
+			goto fail;
+
+		asid = GET_CB_CONTEXTIDR_ASID(iommu_drvdata->base,
+					   ctx_drvdata->num);
+
+		SET_TLBIASID(iommu_drvdata->base, ctx_drvdata->num, asid);
+		mb();
+		__sync_tlb(iommu_drvdata->base, ctx_drvdata->num);
+		__disable_clocks(iommu_drvdata);
+	}
+
+fail:
+	return ret;
+}
+
+/*
+ * May only be called for non-secure iommus
+ */
+static void __reset_iommu(void __iomem *base)
+{
+	int i, smt_size;
+
+	SET_ACR(base, 0);
+	SET_CR2(base, 0);
+	SET_GFAR(base, 0);
+	SET_GFSRRESTORE(base, 0);
+	SET_TLBIALLNSNH(base, 0);
+	SET_SCR1(base, 0);
+	SET_SSDR_N(base, 0, 0);
+	smt_size = GET_IDR0_NUMSMRG(base);
+
+	for (i = 0; i < smt_size; i++)
+		SET_SMR_VALID(base, i, 0);
+
+	mb();
+}
+
+/*
+ * May only be called for non-secure iommus
+ */
+static void __program_iommu(void __iomem *base)
+{
+	__reset_iommu(base);
+
+	SET_CR0_SMCFCFG(base, 1);
+	SET_CR0_USFCFG(base, 1);
+	SET_CR0_STALLD(base, 1);
+	SET_CR0_GCFGFIE(base, 1);
+	SET_CR0_GCFGFRE(base, 1);
+	SET_CR0_GFIE(base, 1);
+	SET_CR0_GFRE(base, 1);
+	SET_CR0_CLIENTPD(base, 0);
+
+	mb(); /* Make sure writes complete before returning */
+}
+
+void program_iommu_bfb_settings(void __iomem *base,
+			const struct msm_iommu_bfb_settings *bfb_settings)
+{
+	unsigned int i;
+	if (bfb_settings)
+		for (i = 0; i < bfb_settings->length; i++)
+			SET_GLOBAL_REG(base, bfb_settings->regs[i],
+					     bfb_settings->data[i]);
+
+	mb(); /* Make sure writes complete before returning */
+}
+
+static void __reset_context(void __iomem *base, int ctx)
+{
+	SET_ACTLR(base, ctx, 0);
+	SET_FAR(base, ctx, 0);
+	SET_FSRRESTORE(base, ctx, 0);
+	SET_NMRR(base, ctx, 0);
+	SET_PAR(base, ctx, 0);
+	SET_PRRR(base, ctx, 0);
+	SET_SCTLR(base, ctx, 0);
+	SET_TLBIALL(base, ctx, 0);
+	SET_TTBCR(base, ctx, 0);
+	SET_TTBR0(base, ctx, 0);
+	SET_TTBR1(base, ctx, 0);
+	mb();
+}
+
+static void __release_smg(void __iomem *base, int ctx)
+{
+	int i, smt_size;
+	smt_size = GET_IDR0_NUMSMRG(base);
+
+	/* Invalidate any SMGs associated with this context */
+	for (i = 0; i < smt_size; i++)
+		if (GET_SMR_VALID(base, i) &&
+		    GET_S2CR_CBNDX(base, i) == ctx)
+			SET_SMR_VALID(base, i, 0);
+}
+
+static void msm_iommu_assign_ASID(const struct msm_iommu_drvdata *iommu_drvdata,
+				  struct msm_iommu_ctx_drvdata *curr_ctx,
+				  phys_addr_t pgtable)
+{
+	struct platform_device *pdev;
+	struct device_node *child;
+	struct msm_iommu_ctx_drvdata *ctx;
+	unsigned int found = 0;
+	void __iomem *base = iommu_drvdata->base;
+	struct device_node *iommu_node = iommu_drvdata->dev->of_node;
+	unsigned int asid;
+	unsigned int ncb = iommu_drvdata->ncb;
+
+	/* Find if this page table is used elsewhere, and re-use ASID */
+	for_each_child_of_node(iommu_node, child) {
+		pdev = of_find_device_by_node(child);
+		ctx = dev_get_drvdata(&pdev->dev);
+
+		if (ctx->secure_context) {
+			of_dev_put(pdev);
+			continue;
+		}
+
+		if ((ctx != curr_ctx) &&
+		    (GET_CB_TTBR0_ADDR(base, ctx->num) == pgtable)) {
+			SET_CB_CONTEXTIDR_ASID(base, curr_ctx->num, ctx->asid);
+			curr_ctx->asid = ctx->asid;
+			found = 1;
+			of_dev_put(pdev);
+			of_node_put(child);
+			break;
+		}
+		of_dev_put(pdev);
+	}
+
+	/* If page table is new, find an unused ASID */
+	if (!found) {
+		for (asid = 1; asid < ncb + 1; ++asid) {
+			found = 0;
+			for_each_child_of_node(iommu_node, child) {
+				pdev = of_find_device_by_node(child);
+				ctx = dev_get_drvdata(&pdev->dev);
+
+				if (ctx != curr_ctx && ctx->asid == asid) {
+					found = 1;
+					of_dev_put(pdev);
+					of_node_put(child);
+					break;
+				}
+				of_dev_put(pdev);
+			}
+			if (!found) {
+				SET_CB_CONTEXTIDR_ASID(base, curr_ctx->num,
+						       asid);
+				curr_ctx->asid = asid;
+				break;
+			}
+		}
+		BUG_ON(found);
+	}
+}
+
+static void __program_context(struct msm_iommu_drvdata *iommu_drvdata,
+			      struct msm_iommu_ctx_drvdata *ctx_drvdata,
+			      phys_addr_t pgtable, int redirect, bool is_secure)
+{
+	unsigned int prrr, nmrr;
+	unsigned int pn;
+	int num = 0, i, smt_size;
+	void __iomem *base = iommu_drvdata->base;
+	unsigned int ctx = ctx_drvdata->num;
+	u32 *sids = ctx_drvdata->sids;
+	int len = ctx_drvdata->nsid;
+
+	__reset_context(base, ctx);
+
+	pn = pgtable >> CB_TTBR0_ADDR_SHIFT;
+	SET_TTBCR(base, ctx, 0);
+	SET_CB_TTBR0_ADDR(base, ctx, pn);
+
+	/* Enable context fault interrupt */
+	SET_CB_SCTLR_CFIE(base, ctx, 1);
+
+	/* Redirect all cacheable requests to L2 slave port. */
+	SET_CB_ACTLR_BPRCISH(base, ctx, 1);
+	SET_CB_ACTLR_BPRCOSH(base, ctx, 1);
+	SET_CB_ACTLR_BPRCNSH(base, ctx, 1);
+
+	/* Turn on TEX Remap */
+	SET_CB_SCTLR_TRE(base, ctx, 1);
+
+	/* Enable private ASID namespace */
+	SET_CB_SCTLR_ASIDPNE(base, ctx, 1);
+
+	/* Set TEX remap attributes */
+	RCP15_PRRR(prrr);
+	RCP15_NMRR(nmrr);
+	SET_PRRR(base, ctx, prrr);
+	SET_NMRR(base, ctx, nmrr);
+
+	/* Configure page tables as inner-cacheable and shareable to reduce
+	 * the TLB miss penalty.
+	 */
+	if (redirect) {
+		SET_CB_TTBR0_S(base, ctx, 1);
+		SET_CB_TTBR0_NOS(base, ctx, 1);
+		SET_CB_TTBR0_IRGN1(base, ctx, 0); /* WB, WA */
+		SET_CB_TTBR0_IRGN0(base, ctx, 1);
+		SET_CB_TTBR0_RGN(base, ctx, 1);   /* WB, WA */
+	}
+
+	if (!is_secure) {
+		smt_size = GET_IDR0_NUMSMRG(base);
+		/* Program the M2V tables for this context */
+		for (i = 0; i < len / sizeof(*sids); i++) {
+			for (; num < smt_size; num++)
+				if (GET_SMR_VALID(base, num) == 0)
+					break;
+			BUG_ON(num >= smt_size);
+
+			SET_SMR_VALID(base, num, 1);
+			SET_SMR_MASK(base, num, 0);
+			SET_SMR_ID(base, num, sids[i]);
+
+			SET_S2CR_N(base, num, 0);
+			SET_S2CR_CBNDX(base, num, ctx);
+			SET_S2CR_MEMATTR(base, num, 0x0A);
+			/* Set security bit override to be Non-secure */
+			SET_S2CR_NSCFG(base, num, 3);
+		}
+		SET_CBAR_N(base, ctx, 0);
+
+		/* Stage 1 Context with Stage 2 bypass */
+		SET_CBAR_TYPE(base, ctx, 1);
+
+		/* Route page faults to the non-secure interrupt */
+		SET_CBAR_IRPTNDX(base, ctx, 1);
+
+		/* Set VMID to non-secure HLOS */
+		SET_CBAR_VMID(base, ctx, 3);
+
+		/* Bypass is treated as inner-shareable */
+		SET_CBAR_BPSHCFG(base, ctx, 2);
+
+		/* Do not downgrade memory attributes */
+		SET_CBAR_MEMATTR(base, ctx, 0x0A);
+
+	}
+
+	msm_iommu_assign_ASID(iommu_drvdata, ctx_drvdata, pn);
+
+	/* Enable the MMU */
+	SET_CB_SCTLR_M(base, ctx, 1);
+	mb();
+}
+
+static int msm_iommu_domain_init(struct iommu_domain *domain, int flags)
+{
+	struct msm_priv *priv;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		goto fail_nomem;
+
+#ifdef CONFIG_IOMMU_PGTABLES_L2
+	priv->pt.redirect = flags & MSM_IOMMU_DOMAIN_PT_CACHEABLE;
+#endif
+
+	INIT_LIST_HEAD(&priv->list_attached);
+	if (msm_iommu_pagetable_alloc(&priv->pt))
+		goto fail_nomem;
+
+	domain->priv = priv;
+	return 0;
+
+fail_nomem:
+	kfree(priv);
+	return -ENOMEM;
+}
+
+static void msm_iommu_domain_destroy(struct iommu_domain *domain)
+{
+	struct msm_priv *priv;
+
+	mutex_lock(&msm_iommu_lock);
+	priv = domain->priv;
+	domain->priv = NULL;
+
+	if (priv)
+		msm_iommu_pagetable_free(&priv->pt);
+
+	kfree(priv);
+	mutex_unlock(&msm_iommu_lock);
+}
+
+static int msm_iommu_ctx_attached(struct device *dev)
+{
+	struct platform_device *pdev;
+	struct device_node *child;
+	struct msm_iommu_ctx_drvdata *ctx;
+
+	for_each_child_of_node(dev->of_node, child) {
+		pdev = of_find_device_by_node(child);
+
+		ctx = dev_get_drvdata(&pdev->dev);
+		if (ctx->attached_domain) {
+			of_dev_put(pdev);
+			of_node_put(child);
+			return 1;
+		}
+		of_dev_put(pdev);
+	}
+
+	return 0;
+}
+
+static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
+{
+	struct msm_priv *priv;
+	struct msm_iommu_drvdata *iommu_drvdata;
+	struct msm_iommu_ctx_drvdata *ctx_drvdata;
+	struct msm_iommu_ctx_drvdata *tmp_drvdata;
+	int ret;
+	int is_secure;
+
+	mutex_lock(&msm_iommu_lock);
+
+	priv = domain->priv;
+	if (!priv || !dev) {
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	iommu_drvdata = dev_get_drvdata(dev->parent);
+	ctx_drvdata = dev_get_drvdata(dev);
+	if (!iommu_drvdata || !ctx_drvdata) {
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	if (!list_empty(&ctx_drvdata->attached_elm)) {
+		ret = -EBUSY;
+		goto fail;
+	}
+
+	list_for_each_entry(tmp_drvdata, &priv->list_attached, attached_elm)
+		if (tmp_drvdata == ctx_drvdata) {
+			ret = -EBUSY;
+			goto fail;
+		}
+
+	is_secure = iommu_drvdata->sec_id != -1;
+
+	ret = __enable_regulators(iommu_drvdata);
+	if (ret)
+		goto fail;
+
+	ret = __enable_clocks(iommu_drvdata);
+	if (ret) {
+		__disable_regulators(iommu_drvdata);
+		goto fail;
+	}
+
+
+	if (!msm_iommu_ctx_attached(dev->parent)) {
+		if (!is_secure) {
+			iommu_halt(iommu_drvdata);
+			__program_iommu(iommu_drvdata->base);
+			iommu_resume(iommu_drvdata);
+		} else {
+			ret = msm_iommu_sec_program_iommu(
+				iommu_drvdata->sec_id);
+			if (ret) {
+				__disable_regulators(iommu_drvdata);
+				__disable_clocks(iommu_drvdata);
+				goto fail;
+			}
+		}
+		program_iommu_bfb_settings(iommu_drvdata->base,
+					   iommu_drvdata->bfb_settings);
+	}
+
+	iommu_halt(iommu_drvdata);
+
+	__program_context(iommu_drvdata, ctx_drvdata, __pa(priv->pt.fl_table),
+			  priv->pt.redirect, is_secure);
+
+	iommu_resume(iommu_drvdata);
+
+	__disable_clocks(iommu_drvdata);
+
+	list_add(&(ctx_drvdata->attached_elm), &priv->list_attached);
+	ctx_drvdata->attached_domain = domain;
+
+	mutex_unlock(&msm_iommu_lock);
+
+	msm_iommu_attached(dev->parent);
+	return ret;
+fail:
+	mutex_unlock(&msm_iommu_lock);
+	return ret;
+}
+
+static void msm_iommu_detach_dev(struct iommu_domain *domain,
+				 struct device *dev)
+{
+	struct msm_priv *priv;
+	struct msm_iommu_drvdata *iommu_drvdata;
+	struct msm_iommu_ctx_drvdata *ctx_drvdata;
+	int ret;
+	int is_secure;
+
+	msm_iommu_detached(dev->parent);
+
+	mutex_lock(&msm_iommu_lock);
+	priv = domain->priv;
+	if (!priv || !dev)
+		goto fail;
+
+	iommu_drvdata = dev_get_drvdata(dev->parent);
+	ctx_drvdata = dev_get_drvdata(dev);
+	if (!iommu_drvdata || !ctx_drvdata || !ctx_drvdata->attached_domain)
+		goto fail;
+
+	ret = __enable_clocks(iommu_drvdata);
+	if (ret)
+		goto fail;
+
+	is_secure = iommu_drvdata->sec_id != -1;
+
+	SET_TLBIASID(iommu_drvdata->base, ctx_drvdata->num, ctx_drvdata->asid);
+	ctx_drvdata->asid = -1;
+
+	iommu_halt(iommu_drvdata);
+
+	__reset_context(iommu_drvdata->base, ctx_drvdata->num);
+	if (!is_secure)
+		__release_smg(iommu_drvdata->base, ctx_drvdata->num);
+
+	iommu_resume(iommu_drvdata);
+
+	__disable_clocks(iommu_drvdata);
+
+	__disable_regulators(iommu_drvdata);
+
+	list_del_init(&ctx_drvdata->attached_elm);
+	ctx_drvdata->attached_domain = NULL;
+
+fail:
+	mutex_unlock(&msm_iommu_lock);
+}
+
+static int msm_iommu_map(struct iommu_domain *domain, unsigned long va,
+			 phys_addr_t pa, size_t len, int prot)
+{
+	struct msm_priv *priv;
+	int ret = 0;
+
+	mutex_lock(&msm_iommu_lock);
+
+	priv = domain->priv;
+	if (!priv) {
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	ret = msm_iommu_pagetable_map(&priv->pt, va, pa, len, prot);
+	if (ret)
+		goto fail;
+
+	ret = __flush_iotlb_va(domain, va);
+fail:
+	mutex_unlock(&msm_iommu_lock);
+	return ret;
+}
+
+static size_t msm_iommu_unmap(struct iommu_domain *domain, unsigned long va,
+			    size_t len)
+{
+	struct msm_priv *priv;
+	int ret = -ENODEV;
+
+	mutex_lock(&msm_iommu_lock);
+
+	priv = domain->priv;
+	if (!priv)
+		goto fail;
+
+	ret = msm_iommu_pagetable_unmap(&priv->pt, va, len);
+	if (ret < 0)
+		goto fail;
+
+	ret = __flush_iotlb_va(domain, va);
+fail:
+	mutex_unlock(&msm_iommu_lock);
+
+	/* the IOMMU API requires us to return how many bytes were unmapped */
+	len = ret ? 0 : len;
+	return len;
+}
+
+static int msm_iommu_map_range(struct iommu_domain *domain, unsigned int va,
+			       struct scatterlist *sg, unsigned int len,
+			       int prot)
+{
+	int ret;
+	struct msm_priv *priv;
+
+	mutex_lock(&msm_iommu_lock);
+
+	priv = domain->priv;
+	if (!priv) {
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	ret = msm_iommu_pagetable_map_range(&priv->pt, va, sg, len, prot);
+	if (ret)
+		goto fail;
+
+	__flush_iotlb(domain);
+fail:
+	mutex_unlock(&msm_iommu_lock);
+	return ret;
+}
+
+
+static int msm_iommu_unmap_range(struct iommu_domain *domain, unsigned int va,
+				 unsigned int len)
+{
+	struct msm_priv *priv;
+
+	mutex_lock(&msm_iommu_lock);
+
+	priv = domain->priv;
+	msm_iommu_pagetable_unmap_range(&priv->pt, va, len);
+
+	__flush_iotlb(domain);
+	mutex_unlock(&msm_iommu_lock);
+	return 0;
+}
+
+static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain,
+					  unsigned long va)
+{
+	struct msm_priv *priv;
+	struct msm_iommu_drvdata *iommu_drvdata;
+	struct msm_iommu_ctx_drvdata *ctx_drvdata;
+	unsigned int par;
+	void __iomem *base;
+	phys_addr_t ret = 0;
+	int ctx;
+
+	mutex_lock(&msm_iommu_lock);
+
+	priv = domain->priv;
+	if (list_empty(&priv->list_attached))
+		goto fail;
+
+	ctx_drvdata = list_entry(priv->list_attached.next,
+				 struct msm_iommu_ctx_drvdata, attached_elm);
+	iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent);
+
+	base = iommu_drvdata->base;
+	ctx = ctx_drvdata->num;
+
+	ret = __enable_clocks(iommu_drvdata);
+	if (ret) {
+		ret = 0;	/* 0 indicates translation failed */
+		goto fail;
+	}
+
+	SET_ATS1PR(base, ctx, va & CB_ATS1PR_ADDR);
+	mb();
+	while (GET_CB_ATSR_ACTIVE(base, ctx))
+		cpu_relax();
+
+	par = GET_PAR(base, ctx);
+	__disable_clocks(iommu_drvdata);
+
+	if (par & CB_PAR_F) {
+		ret = 0;
+	} else {
+		/* We are dealing with a supersection */
+		if (ret & CB_PAR_SS)
+			ret = (par & 0xFF000000) | (va & 0x00FFFFFF);
+		else /* Upper 20 bits from PAR, lower 12 from VA */
+			ret = (par & 0xFFFFF000) | (va & 0x00000FFF);
+	}
+
+fail:
+	mutex_unlock(&msm_iommu_lock);
+	return ret;
+}
+
+static int msm_iommu_domain_has_cap(struct iommu_domain *domain,
+				    unsigned long cap)
+{
+	return 0;
+}
+
+static void print_ctx_regs(void __iomem *base, int ctx, unsigned int fsr)
+{
+	pr_err("FAR    = %08x    PAR    = %08x\n",
+		 GET_FAR(base, ctx), GET_PAR(base, ctx));
+	pr_err("FSR    = %08x [%s%s%s%s%s%s%s%s%s]\n", fsr,
+			(fsr & 0x02) ? "TF " : "",
+			(fsr & 0x04) ? "AFF " : "",
+			(fsr & 0x08) ? "PF " : "",
+			(fsr & 0x10) ? "EF " : "",
+			(fsr & 0x20) ? "TLBMCF " : "",
+			(fsr & 0x40) ? "TLBLKF " : "",
+			(fsr & 0x80) ? "MHF " : "",
+			(fsr & 0x40000000) ? "SS " : "",
+			(fsr & 0x80000000) ? "MULTI " : "");
+
+	pr_err("FSYNR0 = %08x    FSYNR1 = %08x\n",
+		 GET_FSYNR0(base, ctx), GET_FSYNR1(base, ctx));
+	pr_err("TTBR0  = %08x    TTBR1  = %08x\n",
+		 GET_TTBR0(base, ctx), GET_TTBR1(base, ctx));
+	pr_err("SCTLR  = %08x    ACTLR  = %08x\n",
+		 GET_SCTLR(base, ctx), GET_ACTLR(base, ctx));
+	pr_err("PRRR   = %08x    NMRR   = %08x\n",
+		 GET_PRRR(base, ctx), GET_NMRR(base, ctx));
+}
+
+irqreturn_t msm_iommu_fault_handler_v2(int irq, void *dev_id)
+{
+	struct platform_device *pdev = dev_id;
+	struct msm_iommu_drvdata *drvdata;
+	struct msm_iommu_ctx_drvdata *ctx_drvdata;
+	unsigned int fsr;
+	int ret;
+
+	mutex_lock(&msm_iommu_lock);
+
+	BUG_ON(!pdev);
+
+	drvdata = dev_get_drvdata(pdev->dev.parent);
+	BUG_ON(!drvdata);
+
+	ctx_drvdata = dev_get_drvdata(&pdev->dev);
+	BUG_ON(!ctx_drvdata);
+
+	ret = __enable_clocks(drvdata);
+	if (ret) {
+		ret = IRQ_NONE;
+		goto fail;
+	}
+
+	fsr = GET_FSR(drvdata->base, ctx_drvdata->num);
+	if (fsr) {
+		if (!ctx_drvdata->attached_domain) {
+			pr_err("Bad domain in interrupt handler\n");
+			ret = -ENOSYS;
+		} else
+			ret = report_iommu_fault(ctx_drvdata->attached_domain,
+				&ctx_drvdata->pdev->dev,
+				GET_FAR(drvdata->base, ctx_drvdata->num), 0);
+
+		if (ret == -ENOSYS) {
+			pr_err("Unexpected IOMMU page fault!\n");
+			pr_err("name = %s\n", drvdata->name);
+			pr_err("context = %s (%d)\n", ctx_drvdata->name,
+							ctx_drvdata->num);
+			pr_err("Interesting registers:\n");
+			print_ctx_regs(drvdata->base, ctx_drvdata->num, fsr);
+		}
+
+		SET_FSR(drvdata->base, ctx_drvdata->num, fsr);
+		ret = IRQ_HANDLED;
+	} else
+		ret = IRQ_NONE;
+
+	__disable_clocks(drvdata);
+fail:
+	mutex_unlock(&msm_iommu_lock);
+	return ret;
+}
+
+static phys_addr_t msm_iommu_get_pt_base_addr(struct iommu_domain *domain)
+{
+	struct msm_priv *priv = domain->priv;
+	return __pa(priv->pt.fl_table);
+}
+
+static struct iommu_ops msm_iommu_ops = {
+	.domain_init = msm_iommu_domain_init,
+	.domain_destroy = msm_iommu_domain_destroy,
+	.attach_dev = msm_iommu_attach_dev,
+	.detach_dev = msm_iommu_detach_dev,
+	.map = msm_iommu_map,
+	.unmap = msm_iommu_unmap,
+	.map_range = msm_iommu_map_range,
+	.unmap_range = msm_iommu_unmap_range,
+	.iova_to_phys = msm_iommu_iova_to_phys,
+	.domain_has_cap = msm_iommu_domain_has_cap,
+	.get_pt_base_addr = msm_iommu_get_pt_base_addr,
+	.pgsize_bitmap = MSM_IOMMU_PGSIZES,
+};
+
+static int __init msm_iommu_init(void)
+{
+	msm_iommu_pagetable_init();
+	bus_set_iommu(&platform_bus_type, &msm_iommu_ops);
+	return 0;
+}
+
+subsys_initcall(msm_iommu_init);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MSM SMMU v2 Driver");
diff --git a/drivers/iommu/msm_iommu-v2.c b/drivers/iommu/msm_iommu-v2.c
deleted file mode 100644
index 567b9ba..0000000
--- a/drivers/iommu/msm_iommu-v2.c
+++ /dev/null
@@ -1,780 +0,0 @@
-/* Copyright (c) 2012 Code Aurora Forum. 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)	KBUILD_MODNAME ": " fmt
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/errno.h>
-#include <linux/io.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-#include <linux/iommu.h>
-#include <linux/clk.h>
-#include <linux/scatterlist.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/regulator/consumer.h>
-#include <asm/sizes.h>
-
-#include <mach/iommu_hw-v2.h>
-#include <mach/iommu.h>
-
-#include "msm_iommu_pagetable.h"
-
-/* bitmap of the page sizes currently supported */
-#define MSM_IOMMU_PGSIZES	(SZ_4K | SZ_64K | SZ_1M | SZ_16M)
-
-static DEFINE_MUTEX(msm_iommu_lock);
-
-struct msm_priv {
-	struct iommu_pt pt;
-	struct list_head list_attached;
-};
-
-static int __enable_clocks(struct msm_iommu_drvdata *drvdata)
-{
-	int ret;
-
-	ret = clk_prepare_enable(drvdata->pclk);
-	if (ret)
-		goto fail;
-
-	ret = clk_prepare_enable(drvdata->clk);
-	if (ret)
-		clk_disable_unprepare(drvdata->pclk);
-
-	if (drvdata->aclk) {
-		ret = clk_prepare_enable(drvdata->aclk);
-		if (ret) {
-			clk_disable_unprepare(drvdata->clk);
-			clk_disable_unprepare(drvdata->pclk);
-		}
-	}
-fail:
-	return ret;
-}
-
-static void __disable_clocks(struct msm_iommu_drvdata *drvdata)
-{
-	if (drvdata->aclk)
-		clk_disable_unprepare(drvdata->aclk);
-	clk_disable_unprepare(drvdata->clk);
-	clk_disable_unprepare(drvdata->pclk);
-}
-
-static void __sync_tlb(void __iomem *base, int ctx)
-{
-	SET_TLBSYNC(base, ctx, 0);
-
-	/* No barrier needed due to register proximity */
-	while (GET_CB_TLBSTATUS_SACTIVE(base, ctx))
-		cpu_relax();
-
-	/* No barrier needed due to read dependency */
-}
-
-static int __flush_iotlb_va(struct iommu_domain *domain, unsigned int va)
-{
-	struct msm_priv *priv = domain->priv;
-	struct msm_iommu_drvdata *iommu_drvdata;
-	struct msm_iommu_ctx_drvdata *ctx_drvdata;
-	int ret = 0;
-	int asid;
-
-	list_for_each_entry(ctx_drvdata, &priv->list_attached, attached_elm) {
-		BUG_ON(!ctx_drvdata->pdev || !ctx_drvdata->pdev->dev.parent);
-
-		iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent);
-		BUG_ON(!iommu_drvdata);
-
-
-		ret = __enable_clocks(iommu_drvdata);
-		if (ret)
-			goto fail;
-
-		asid = GET_CB_CONTEXTIDR_ASID(iommu_drvdata->base,
-					   ctx_drvdata->num);
-
-		SET_TLBIVA(iommu_drvdata->base, ctx_drvdata->num,
-			   asid | (va & CB_TLBIVA_VA));
-		mb();
-		__sync_tlb(iommu_drvdata->base, ctx_drvdata->num);
-		__disable_clocks(iommu_drvdata);
-	}
-fail:
-	return ret;
-}
-
-static int __flush_iotlb(struct iommu_domain *domain)
-{
-	struct msm_priv *priv = domain->priv;
-	struct msm_iommu_drvdata *iommu_drvdata;
-	struct msm_iommu_ctx_drvdata *ctx_drvdata;
-	int ret = 0;
-	int asid;
-
-	list_for_each_entry(ctx_drvdata, &priv->list_attached, attached_elm) {
-		BUG_ON(!ctx_drvdata->pdev || !ctx_drvdata->pdev->dev.parent);
-
-		iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent);
-		BUG_ON(!iommu_drvdata);
-
-		ret = __enable_clocks(iommu_drvdata);
-		if (ret)
-			goto fail;
-
-		asid = GET_CB_CONTEXTIDR_ASID(iommu_drvdata->base,
-					   ctx_drvdata->num);
-
-		SET_TLBIASID(iommu_drvdata->base, ctx_drvdata->num, asid);
-		mb();
-		__sync_tlb(iommu_drvdata->base, ctx_drvdata->num);
-		__disable_clocks(iommu_drvdata);
-	}
-
-fail:
-	return ret;
-}
-
-/*
- * May only be called for non-secure iommus
- */
-static void __reset_iommu(void __iomem *base)
-{
-	int i, smt_size;
-
-	SET_ACR(base, 0);
-	SET_CR2(base, 0);
-	SET_GFAR(base, 0);
-	SET_GFSRRESTORE(base, 0);
-	SET_TLBIALLNSNH(base, 0);
-	SET_PMCR(base, 0);
-	SET_SCR1(base, 0);
-	SET_SSDR_N(base, 0, 0);
-	smt_size = GET_IDR0_NUMSMRG(base);
-
-	for (i = 0; i < smt_size; i++)
-		SET_SMR_VALID(base, i, 0);
-
-	mb();
-}
-
-/*
- * May only be called for non-secure iommus
- */
-static void __program_iommu(void __iomem *base,
-			    struct msm_iommu_bfb_settings *bfb_settings)
-{
-	int i;
-	__reset_iommu(base);
-
-	SET_CR0_SMCFCFG(base, 1);
-	SET_CR0_USFCFG(base, 1);
-	SET_CR0_STALLD(base, 1);
-	SET_CR0_GCFGFIE(base, 1);
-	SET_CR0_GCFGFRE(base, 1);
-	SET_CR0_GFIE(base, 1);
-	SET_CR0_GFRE(base, 1);
-	SET_CR0_CLIENTPD(base, 0);
-
-	if (bfb_settings)
-		for (i = 0; i < bfb_settings->length; i++)
-			SET_GLOBAL_REG(base, bfb_settings->regs[i],
-					     bfb_settings->data[i]);
-
-	mb();	/* Make sure writes complete before returning */
-}
-
-static void __reset_context(void __iomem *base, int ctx)
-{
-	SET_ACTLR(base, ctx, 0);
-	SET_FAR(base, ctx, 0);
-	SET_FSRRESTORE(base, ctx, 0);
-	SET_NMRR(base, ctx, 0);
-	SET_PAR(base, ctx, 0);
-	SET_PRRR(base, ctx, 0);
-	SET_SCTLR(base, ctx, 0);
-	SET_TLBIALL(base, ctx, 0);
-	SET_TTBCR(base, ctx, 0);
-	SET_TTBR0(base, ctx, 0);
-	SET_TTBR1(base, ctx, 0);
-	mb();
-}
-
-static void __release_smg(void __iomem *base, int ctx)
-{
-	int i, smt_size;
-	smt_size = GET_IDR0_NUMSMRG(base);
-
-	/* Invalidate any SMGs associated with this context */
-	for (i = 0; i < smt_size; i++)
-		if (GET_SMR_VALID(base, i) &&
-		    GET_S2CR_CBNDX(base, i) == ctx)
-			SET_SMR_VALID(base, i, 0);
-}
-
-static void __program_context(void __iomem *base, int ctx, int ncb,
-				phys_addr_t pgtable, int redirect,
-				u32 *sids, int len, bool is_secure)
-{
-	unsigned int prrr, nmrr;
-	unsigned int pn;
-	int i, j, found, num = 0, smt_size;
-
-	__reset_context(base, ctx);
-
-	pn = pgtable >> CB_TTBR0_ADDR_SHIFT;
-	SET_TTBCR(base, ctx, 0);
-	SET_CB_TTBR0_ADDR(base, ctx, pn);
-
-	/* Enable context fault interrupt */
-	SET_CB_SCTLR_CFIE(base, ctx, 1);
-
-	/* Redirect all cacheable requests to L2 slave port. */
-	SET_CB_ACTLR_BPRCISH(base, ctx, 1);
-	SET_CB_ACTLR_BPRCOSH(base, ctx, 1);
-	SET_CB_ACTLR_BPRCNSH(base, ctx, 1);
-
-	/* Turn on TEX Remap */
-	SET_CB_SCTLR_TRE(base, ctx, 1);
-
-	/* Enable private ASID namespace */
-	SET_CB_SCTLR_ASIDPNE(base, ctx, 1);
-
-	/* Set TEX remap attributes */
-	RCP15_PRRR(prrr);
-	RCP15_NMRR(nmrr);
-	SET_PRRR(base, ctx, prrr);
-	SET_NMRR(base, ctx, nmrr);
-
-	/* Configure page tables as inner-cacheable and shareable to reduce
-	 * the TLB miss penalty.
-	 */
-	if (redirect) {
-		SET_CB_TTBR0_S(base, ctx, 1);
-		SET_CB_TTBR0_NOS(base, ctx, 1);
-		SET_CB_TTBR0_IRGN1(base, ctx, 0); /* WB, WA */
-		SET_CB_TTBR0_IRGN0(base, ctx, 1);
-		SET_CB_TTBR0_RGN(base, ctx, 1);   /* WB, WA */
-	}
-
-	if (!is_secure) {
-		smt_size = GET_IDR0_NUMSMRG(base);
-		/* Program the M2V tables for this context */
-		for (i = 0; i < len / sizeof(*sids); i++) {
-			for (; num < smt_size; num++)
-				if (GET_SMR_VALID(base, num) == 0)
-					break;
-			BUG_ON(num >= smt_size);
-
-			SET_SMR_VALID(base, num, 1);
-			SET_SMR_MASK(base, num, 0);
-			SET_SMR_ID(base, num, sids[i]);
-
-			SET_S2CR_N(base, num, 0);
-			SET_S2CR_CBNDX(base, num, ctx);
-			SET_S2CR_MEMATTR(base, num, 0x0A);
-			/* Set security bit override to be Non-secure */
-			SET_S2CR_NSCFG(base, num, 3);
-		}
-		SET_CBAR_N(base, ctx, 0);
-
-		/* Stage 1 Context with Stage 2 bypass */
-		SET_CBAR_TYPE(base, ctx, 1);
-
-		/* Route page faults to the non-secure interrupt */
-		SET_CBAR_IRPTNDX(base, ctx, 1);
-
-		/* Set VMID to non-secure HLOS */
-		SET_CBAR_VMID(base, ctx, 3);
-
-		/* Bypass is treated as inner-shareable */
-		SET_CBAR_BPSHCFG(base, ctx, 2);
-
-		/* Do not downgrade memory attributes */
-		SET_CBAR_MEMATTR(base, ctx, 0x0A);
-
-	}
-
-       /* Find if this page table is used elsewhere, and re-use ASID */
-	found = 0;
-	for (i = 0; i < ncb; i++)
-		if ((GET_CB_TTBR0_ADDR(base, i) == pn) && (i != ctx)) {
-			SET_CB_CONTEXTIDR_ASID(base, ctx, \
-					GET_CB_CONTEXTIDR_ASID(base, i));
-			found = 1;
-			break;
-		}
-
-	/* If page table is new, find an unused ASID */
-	if (!found) {
-		for (i = 0; i < ncb; i++) {
-			found = 0;
-			for (j = 0; j < ncb; j++) {
-				if (GET_CB_CONTEXTIDR_ASID(base, j) == i &&
-				    j != ctx)
-					found = 1;
-			}
-
-			if (!found) {
-				SET_CB_CONTEXTIDR_ASID(base, ctx, i);
-				break;
-			}
-		}
-		BUG_ON(found);
-	}
-
-	/* Enable the MMU */
-	SET_CB_SCTLR_M(base, ctx, 1);
-	mb();
-}
-
-static int msm_iommu_domain_init(struct iommu_domain *domain, int flags)
-{
-	struct msm_priv *priv;
-
-	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-	if (!priv)
-		goto fail_nomem;
-
-#ifdef CONFIG_IOMMU_PGTABLES_L2
-	priv->pt.redirect = flags & MSM_IOMMU_DOMAIN_PT_CACHEABLE;
-#endif
-
-	INIT_LIST_HEAD(&priv->list_attached);
-	if (msm_iommu_pagetable_alloc(&priv->pt))
-		goto fail_nomem;
-
-	domain->priv = priv;
-	return 0;
-
-fail_nomem:
-	kfree(priv);
-	return -ENOMEM;
-}
-
-static void msm_iommu_domain_destroy(struct iommu_domain *domain)
-{
-	struct msm_priv *priv;
-
-	mutex_lock(&msm_iommu_lock);
-	priv = domain->priv;
-	domain->priv = NULL;
-
-	if (priv)
-		msm_iommu_pagetable_free(&priv->pt);
-
-	kfree(priv);
-	mutex_unlock(&msm_iommu_lock);
-}
-
-static int msm_iommu_ctx_attached(struct device *dev)
-{
-	struct platform_device *pdev;
-	struct device_node *child;
-	struct msm_iommu_ctx_drvdata *ctx;
-
-	for_each_child_of_node(dev->of_node, child) {
-		pdev = of_find_device_by_node(child);
-
-		ctx = dev_get_drvdata(&pdev->dev);
-		if (ctx->attached_domain) {
-			of_node_put(child);
-			return 1;
-		}
-	}
-
-	return 0;
-}
-
-static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
-{
-	struct msm_priv *priv;
-	struct msm_iommu_drvdata *iommu_drvdata;
-	struct msm_iommu_ctx_drvdata *ctx_drvdata;
-	struct msm_iommu_ctx_drvdata *tmp_drvdata;
-	int ret;
-	int is_secure;
-
-	mutex_lock(&msm_iommu_lock);
-
-	priv = domain->priv;
-	if (!priv || !dev) {
-		ret = -EINVAL;
-		goto fail;
-	}
-
-	iommu_drvdata = dev_get_drvdata(dev->parent);
-	ctx_drvdata = dev_get_drvdata(dev);
-	if (!iommu_drvdata || !ctx_drvdata) {
-		ret = -EINVAL;
-		goto fail;
-	}
-
-	if (!list_empty(&ctx_drvdata->attached_elm)) {
-		ret = -EBUSY;
-		goto fail;
-	}
-
-	list_for_each_entry(tmp_drvdata, &priv->list_attached, attached_elm)
-		if (tmp_drvdata == ctx_drvdata) {
-			ret = -EBUSY;
-			goto fail;
-		}
-
-	is_secure = iommu_drvdata->sec_id != -1;
-
-	ret = regulator_enable(iommu_drvdata->gdsc);
-	if (ret)
-		goto fail;
-
-	ret = __enable_clocks(iommu_drvdata);
-	if (ret) {
-		regulator_disable(iommu_drvdata->gdsc);
-		goto fail;
-	}
-
-	if (!msm_iommu_ctx_attached(dev->parent)) {
-		if (!is_secure) {
-			__program_iommu(iommu_drvdata->base,
-				iommu_drvdata->bfb_settings);
-		} else {
-			ret = msm_iommu_sec_program_iommu(
-				iommu_drvdata->sec_id);
-			if (ret) {
-				regulator_disable(iommu_drvdata->gdsc);
-				__disable_clocks(iommu_drvdata);
-				goto fail;
-			}
-		}
-	}
-
-	__program_context(iommu_drvdata->base, ctx_drvdata->num,
-		iommu_drvdata->ncb, __pa(priv->pt.fl_table),
-		priv->pt.redirect, ctx_drvdata->sids, ctx_drvdata->nsid,
-		is_secure);
-	__disable_clocks(iommu_drvdata);
-
-	list_add(&(ctx_drvdata->attached_elm), &priv->list_attached);
-	ctx_drvdata->attached_domain = domain;
-
-fail:
-	mutex_unlock(&msm_iommu_lock);
-	return ret;
-}
-
-static void msm_iommu_detach_dev(struct iommu_domain *domain,
-				 struct device *dev)
-{
-	struct msm_priv *priv;
-	struct msm_iommu_drvdata *iommu_drvdata;
-	struct msm_iommu_ctx_drvdata *ctx_drvdata;
-	int ret;
-	int is_secure;
-
-	mutex_lock(&msm_iommu_lock);
-	priv = domain->priv;
-	if (!priv || !dev)
-		goto fail;
-
-	iommu_drvdata = dev_get_drvdata(dev->parent);
-	ctx_drvdata = dev_get_drvdata(dev);
-	if (!iommu_drvdata || !ctx_drvdata || !ctx_drvdata->attached_domain)
-		goto fail;
-
-	ret = __enable_clocks(iommu_drvdata);
-	if (ret)
-		goto fail;
-
-	is_secure = iommu_drvdata->sec_id != -1;
-
-	SET_TLBIASID(iommu_drvdata->base, ctx_drvdata->num,
-		GET_CB_CONTEXTIDR_ASID(iommu_drvdata->base, ctx_drvdata->num));
-
-	__reset_context(iommu_drvdata->base, ctx_drvdata->num);
-	if (!is_secure)
-		__release_smg(iommu_drvdata->base, ctx_drvdata->num);
-
-	__disable_clocks(iommu_drvdata);
-
-	regulator_disable(iommu_drvdata->gdsc);
-
-	list_del_init(&ctx_drvdata->attached_elm);
-	ctx_drvdata->attached_domain = NULL;
-
-fail:
-	mutex_unlock(&msm_iommu_lock);
-}
-
-static int msm_iommu_map(struct iommu_domain *domain, unsigned long va,
-			 phys_addr_t pa, size_t len, int prot)
-{
-	struct msm_priv *priv;
-	int ret = 0;
-
-	mutex_lock(&msm_iommu_lock);
-
-	priv = domain->priv;
-	if (!priv) {
-		ret = -EINVAL;
-		goto fail;
-	}
-
-	ret = msm_iommu_pagetable_map(&priv->pt, va, pa, len, prot);
-	if (ret)
-		goto fail;
-
-	ret = __flush_iotlb_va(domain, va);
-fail:
-	mutex_unlock(&msm_iommu_lock);
-	return ret;
-}
-
-static size_t msm_iommu_unmap(struct iommu_domain *domain, unsigned long va,
-			    size_t len)
-{
-	struct msm_priv *priv;
-	int ret = -ENODEV;
-
-	mutex_lock(&msm_iommu_lock);
-
-	priv = domain->priv;
-	if (!priv)
-		goto fail;
-
-	ret = msm_iommu_pagetable_unmap(&priv->pt, va, len);
-	if (ret < 0)
-		goto fail;
-
-	ret = __flush_iotlb_va(domain, va);
-fail:
-	mutex_unlock(&msm_iommu_lock);
-
-	/* the IOMMU API requires us to return how many bytes were unmapped */
-	len = ret ? 0 : len;
-	return len;
-}
-
-static int msm_iommu_map_range(struct iommu_domain *domain, unsigned int va,
-			       struct scatterlist *sg, unsigned int len,
-			       int prot)
-{
-	int ret;
-	struct msm_priv *priv;
-
-	mutex_lock(&msm_iommu_lock);
-
-	priv = domain->priv;
-	if (!priv) {
-		ret = -EINVAL;
-		goto fail;
-	}
-
-	ret = msm_iommu_pagetable_map_range(&priv->pt, va, sg, len, prot);
-	if (ret)
-		goto fail;
-
-	__flush_iotlb(domain);
-fail:
-	mutex_unlock(&msm_iommu_lock);
-	return ret;
-}
-
-
-static int msm_iommu_unmap_range(struct iommu_domain *domain, unsigned int va,
-				 unsigned int len)
-{
-	struct msm_priv *priv;
-
-	mutex_lock(&msm_iommu_lock);
-
-	priv = domain->priv;
-	msm_iommu_pagetable_unmap_range(&priv->pt, va, len);
-
-	__flush_iotlb(domain);
-	mutex_unlock(&msm_iommu_lock);
-	return 0;
-}
-
-static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain,
-					  unsigned long va)
-{
-	struct msm_priv *priv;
-	struct msm_iommu_drvdata *iommu_drvdata;
-	struct msm_iommu_ctx_drvdata *ctx_drvdata;
-	unsigned int par;
-	void __iomem *base;
-	phys_addr_t ret = 0;
-	int ctx;
-
-	mutex_lock(&msm_iommu_lock);
-
-	priv = domain->priv;
-	if (list_empty(&priv->list_attached))
-		goto fail;
-
-	ctx_drvdata = list_entry(priv->list_attached.next,
-				 struct msm_iommu_ctx_drvdata, attached_elm);
-	iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent);
-
-	base = iommu_drvdata->base;
-	ctx = ctx_drvdata->num;
-
-	ret = __enable_clocks(iommu_drvdata);
-	if (ret) {
-		ret = 0;	/* 0 indicates translation failed */
-		goto fail;
-	}
-
-	SET_ATS1PR(base, ctx, va & CB_ATS1PR_ADDR);
-	mb();
-	while (GET_CB_ATSR_ACTIVE(base, ctx))
-		cpu_relax();
-
-	par = GET_PAR(base, ctx);
-	__disable_clocks(iommu_drvdata);
-
-	if (par & CB_PAR_F) {
-		ret = 0;
-	} else {
-		/* We are dealing with a supersection */
-		if (ret & CB_PAR_SS)
-			ret = (par & 0xFF000000) | (va & 0x00FFFFFF);
-		else /* Upper 20 bits from PAR, lower 12 from VA */
-			ret = (par & 0xFFFFF000) | (va & 0x00000FFF);
-	}
-
-fail:
-	mutex_unlock(&msm_iommu_lock);
-	return ret;
-}
-
-static int msm_iommu_domain_has_cap(struct iommu_domain *domain,
-				    unsigned long cap)
-{
-	return 0;
-}
-
-static void print_ctx_regs(void __iomem *base, int ctx, unsigned int fsr)
-{
-	pr_err("FAR    = %08x    PAR    = %08x\n",
-		 GET_FAR(base, ctx), GET_PAR(base, ctx));
-	pr_err("FSR    = %08x [%s%s%s%s%s%s%s%s%s]\n", fsr,
-			(fsr & 0x02) ? "TF " : "",
-			(fsr & 0x04) ? "AFF " : "",
-			(fsr & 0x08) ? "PF " : "",
-			(fsr & 0x10) ? "EF " : "",
-			(fsr & 0x20) ? "TLBMCF " : "",
-			(fsr & 0x40) ? "TLBLKF " : "",
-			(fsr & 0x80) ? "MHF " : "",
-			(fsr & 0x40000000) ? "SS " : "",
-			(fsr & 0x80000000) ? "MULTI " : "");
-
-	pr_err("FSYNR0 = %08x    FSYNR1 = %08x\n",
-		 GET_FSYNR0(base, ctx), GET_FSYNR1(base, ctx));
-	pr_err("TTBR0  = %08x    TTBR1  = %08x\n",
-		 GET_TTBR0(base, ctx), GET_TTBR1(base, ctx));
-	pr_err("SCTLR  = %08x    ACTLR  = %08x\n",
-		 GET_SCTLR(base, ctx), GET_ACTLR(base, ctx));
-	pr_err("PRRR   = %08x    NMRR   = %08x\n",
-		 GET_PRRR(base, ctx), GET_NMRR(base, ctx));
-}
-
-irqreturn_t msm_iommu_fault_handler_v2(int irq, void *dev_id)
-{
-	struct platform_device *pdev = dev_id;
-	struct msm_iommu_drvdata *drvdata;
-	struct msm_iommu_ctx_drvdata *ctx_drvdata;
-	unsigned int fsr;
-	int ret;
-
-	mutex_lock(&msm_iommu_lock);
-
-	BUG_ON(!pdev);
-
-	drvdata = dev_get_drvdata(pdev->dev.parent);
-	BUG_ON(!drvdata);
-
-	ctx_drvdata = dev_get_drvdata(&pdev->dev);
-	BUG_ON(!ctx_drvdata);
-
-	ret = __enable_clocks(drvdata);
-	if (ret) {
-		ret = IRQ_NONE;
-		goto fail;
-	}
-
-	fsr = GET_FSR(drvdata->base, ctx_drvdata->num);
-	if (fsr) {
-		if (!ctx_drvdata->attached_domain) {
-			pr_err("Bad domain in interrupt handler\n");
-			ret = -ENOSYS;
-		} else
-			ret = report_iommu_fault(ctx_drvdata->attached_domain,
-				&ctx_drvdata->pdev->dev,
-				GET_FAR(drvdata->base, ctx_drvdata->num), 0);
-
-		if (ret == -ENOSYS) {
-			pr_err("Unexpected IOMMU page fault!\n");
-			pr_err("name = %s\n", drvdata->name);
-			pr_err("context = %s (%d)\n", ctx_drvdata->name,
-							ctx_drvdata->num);
-			pr_err("Interesting registers:\n");
-			print_ctx_regs(drvdata->base, ctx_drvdata->num, fsr);
-		}
-
-		SET_FSR(drvdata->base, ctx_drvdata->num, fsr);
-		ret = IRQ_HANDLED;
-	} else
-		ret = IRQ_NONE;
-
-	__disable_clocks(drvdata);
-fail:
-	mutex_unlock(&msm_iommu_lock);
-	return ret;
-}
-
-static phys_addr_t msm_iommu_get_pt_base_addr(struct iommu_domain *domain)
-{
-	struct msm_priv *priv = domain->priv;
-	return __pa(priv->pt.fl_table);
-}
-
-static struct iommu_ops msm_iommu_ops = {
-	.domain_init = msm_iommu_domain_init,
-	.domain_destroy = msm_iommu_domain_destroy,
-	.attach_dev = msm_iommu_attach_dev,
-	.detach_dev = msm_iommu_detach_dev,
-	.map = msm_iommu_map,
-	.unmap = msm_iommu_unmap,
-	.map_range = msm_iommu_map_range,
-	.unmap_range = msm_iommu_unmap_range,
-	.iova_to_phys = msm_iommu_iova_to_phys,
-	.domain_has_cap = msm_iommu_domain_has_cap,
-	.get_pt_base_addr = msm_iommu_get_pt_base_addr,
-	.pgsize_bitmap = MSM_IOMMU_PGSIZES,
-};
-
-static int __init msm_iommu_init(void)
-{
-	msm_iommu_pagetable_init();
-	bus_set_iommu(&platform_bus_type, &msm_iommu_ops);
-	return 0;
-}
-
-subsys_initcall(msm_iommu_init);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("MSM SMMU v2 Driver");
diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
deleted file mode 100644
index 1ce1cf8..0000000
--- a/drivers/iommu/msm_iommu.c
+++ /dev/null
@@ -1,1362 +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.
- */
-
-#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/errno.h>
-#include <linux/io.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/iommu.h>
-#include <linux/clk.h>
-#include <linux/scatterlist.h>
-
-#include <asm/cacheflush.h>
-#include <asm/sizes.h>
-
-#include <mach/iommu_hw-8xxx.h>
-#include <mach/iommu.h>
-#include <mach/msm_smsm.h>
-
-#define MRC(reg, processor, op1, crn, crm, op2)				\
-__asm__ __volatile__ (							\
-"   mrc   "   #processor "," #op1 ", %0,"  #crn "," #crm "," #op2 "\n"  \
-: "=r" (reg))
-
-#define RCP15_PRRR(reg)		MRC(reg, p15, 0, c10, c2, 0)
-#define RCP15_NMRR(reg)		MRC(reg, p15, 0, c10, c2, 1)
-
-/* Sharability attributes of MSM IOMMU mappings */
-#define MSM_IOMMU_ATTR_NON_SH		0x0
-#define MSM_IOMMU_ATTR_SH		0x4
-
-/* Cacheability attributes of MSM IOMMU mappings */
-#define MSM_IOMMU_ATTR_NONCACHED	0x0
-#define MSM_IOMMU_ATTR_CACHED_WB_WA	0x1
-#define MSM_IOMMU_ATTR_CACHED_WB_NWA	0x2
-#define MSM_IOMMU_ATTR_CACHED_WT	0x3
-
-struct bus_type msm_iommu_sec_bus_type = {
-	.name = "msm_iommu_sec_bus",
-};
-
-static inline void clean_pte(unsigned long *start, unsigned long *end,
-			     int redirect)
-{
-	if (!redirect)
-		dmac_flush_range(start, end);
-}
-
-/* bitmap of the page sizes currently supported */
-#define MSM_IOMMU_PGSIZES	(SZ_4K | SZ_64K | SZ_1M | SZ_16M)
-
-static int msm_iommu_tex_class[4];
-
-DEFINE_MUTEX(msm_iommu_lock);
-
-/**
- * Remote spinlock implementation based on Peterson's algorithm to be used
- * to synchronize IOMMU config port access between CPU and GPU.
- * This implements Process 0 of the spin lock algorithm. GPU implements
- * Process 1. Flag and turn is stored in shared memory to allow GPU to
- * access these.
- */
-struct msm_iommu_remote_lock {
-	int initialized;
-	struct remote_iommu_petersons_spinlock *lock;
-};
-
-static struct msm_iommu_remote_lock msm_iommu_remote_lock;
-
-#ifdef CONFIG_MSM_IOMMU_GPU_SYNC
-static void _msm_iommu_remote_spin_lock_init(void)
-{
-	msm_iommu_remote_lock.lock = smem_alloc(SMEM_SPINLOCK_ARRAY, 32);
-	memset(msm_iommu_remote_lock.lock, 0,
-			sizeof(*msm_iommu_remote_lock.lock));
-}
-
-void msm_iommu_remote_p0_spin_lock(void)
-{
-	msm_iommu_remote_lock.lock->flag[PROC_APPS] = 1;
-	msm_iommu_remote_lock.lock->turn = 1;
-
-	smp_mb();
-
-	while (msm_iommu_remote_lock.lock->flag[PROC_GPU] == 1 &&
-	       msm_iommu_remote_lock.lock->turn == 1)
-		cpu_relax();
-}
-
-void msm_iommu_remote_p0_spin_unlock(void)
-{
-	smp_mb();
-
-	msm_iommu_remote_lock.lock->flag[PROC_APPS] = 0;
-}
-#endif
-
-inline void msm_iommu_mutex_lock(void)
-{
-	mutex_lock(&msm_iommu_lock);
-}
-
-inline void msm_iommu_mutex_unlock(void)
-{
-	mutex_unlock(&msm_iommu_lock);
-}
-
-void *msm_iommu_lock_initialize(void)
-{
-	mutex_lock(&msm_iommu_lock);
-	if (!msm_iommu_remote_lock.initialized) {
-		msm_iommu_remote_lock_init();
-		msm_iommu_remote_lock.initialized = 1;
-	}
-	mutex_unlock(&msm_iommu_lock);
-	return msm_iommu_remote_lock.lock;
-}
-
-struct msm_priv {
-	unsigned long *pgtable;
-	int redirect;
-	struct list_head list_attached;
-};
-
-static int __enable_clocks(struct msm_iommu_drvdata *drvdata)
-{
-	int ret;
-
-	ret = clk_prepare_enable(drvdata->pclk);
-	if (ret)
-		goto fail;
-
-	if (drvdata->clk) {
-		ret = clk_prepare_enable(drvdata->clk);
-		if (ret)
-			clk_disable_unprepare(drvdata->pclk);
-	}
-fail:
-	return ret;
-}
-
-static void __disable_clocks(struct msm_iommu_drvdata *drvdata)
-{
-	if (drvdata->clk)
-		clk_disable_unprepare(drvdata->clk);
-	clk_disable_unprepare(drvdata->pclk);
-}
-
-static int __flush_iotlb_va(struct iommu_domain *domain, unsigned int va)
-{
-	struct msm_priv *priv = domain->priv;
-	struct msm_iommu_drvdata *iommu_drvdata;
-	struct msm_iommu_ctx_drvdata *ctx_drvdata;
-	int ret = 0;
-	int asid;
-
-	list_for_each_entry(ctx_drvdata, &priv->list_attached, attached_elm) {
-		if (!ctx_drvdata->pdev || !ctx_drvdata->pdev->dev.parent)
-			BUG();
-
-		iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent);
-		if (!iommu_drvdata)
-			BUG();
-
-		ret = __enable_clocks(iommu_drvdata);
-		if (ret)
-			goto fail;
-
-		msm_iommu_remote_spin_lock();
-
-		asid = GET_CONTEXTIDR_ASID(iommu_drvdata->base,
-					   ctx_drvdata->num);
-
-		SET_TLBIVA(iommu_drvdata->base, ctx_drvdata->num,
-			   asid | (va & TLBIVA_VA));
-		mb();
-
-		msm_iommu_remote_spin_unlock();
-
-		__disable_clocks(iommu_drvdata);
-	}
-fail:
-	return ret;
-}
-
-static int __flush_iotlb(struct iommu_domain *domain)
-{
-	struct msm_priv *priv = domain->priv;
-	struct msm_iommu_drvdata *iommu_drvdata;
-	struct msm_iommu_ctx_drvdata *ctx_drvdata;
-	int ret = 0;
-	int asid;
-
-	list_for_each_entry(ctx_drvdata, &priv->list_attached, attached_elm) {
-		if (!ctx_drvdata->pdev || !ctx_drvdata->pdev->dev.parent)
-			BUG();
-
-		iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent);
-		if (!iommu_drvdata)
-			BUG();
-
-		ret = __enable_clocks(iommu_drvdata);
-		if (ret)
-			goto fail;
-
-		msm_iommu_remote_spin_lock();
-
-		asid = GET_CONTEXTIDR_ASID(iommu_drvdata->base,
-					   ctx_drvdata->num);
-
-		SET_TLBIASID(iommu_drvdata->base, ctx_drvdata->num, asid);
-		mb();
-
-		msm_iommu_remote_spin_unlock();
-
-		__disable_clocks(iommu_drvdata);
-	}
-fail:
-	return ret;
-}
-
-static void __reset_context(void __iomem *base, void __iomem *glb_base, int ctx)
-{
-	SET_BPRCOSH(glb_base, ctx, 0);
-	SET_BPRCISH(glb_base, ctx, 0);
-	SET_BPRCNSH(glb_base, ctx, 0);
-	SET_BPSHCFG(glb_base, ctx, 0);
-	SET_BPMTCFG(glb_base, ctx, 0);
-	SET_ACTLR(base, ctx, 0);
-	SET_SCTLR(base, ctx, 0);
-	SET_FSRRESTORE(base, ctx, 0);
-	SET_TTBR0(base, ctx, 0);
-	SET_TTBR1(base, ctx, 0);
-	SET_TTBCR(base, ctx, 0);
-	SET_BFBCR(base, ctx, 0);
-	SET_PAR(base, ctx, 0);
-	SET_FAR(base, ctx, 0);
-	SET_TLBFLPTER(base, ctx, 0);
-	SET_TLBSLPTER(base, ctx, 0);
-	SET_TLBLKCR(base, ctx, 0);
-	SET_PRRR(base, ctx, 0);
-	SET_NMRR(base, ctx, 0);
-	mb();
-}
-
-static void __program_context(void __iomem *base, void __iomem *glb_base,
-			      int ctx, int ncb, phys_addr_t pgtable,
-			      int redirect, int ttbr_split)
-{
-	unsigned int prrr, nmrr;
-	int i, j, found;
-	msm_iommu_remote_spin_lock();
-
-	__reset_context(base, glb_base, ctx);
-
-	/* Set up HTW mode */
-	/* TLB miss configuration: perform HTW on miss */
-	SET_TLBMCFG(base, ctx, 0x3);
-
-	/* V2P configuration: HTW for access */
-	SET_V2PCFG(base, ctx, 0x3);
-
-	SET_TTBCR(base, ctx, ttbr_split);
-	SET_TTBR0_PA(base, ctx, (pgtable >> TTBR0_PA_SHIFT));
-	if (ttbr_split)
-		SET_TTBR1_PA(base, ctx, (pgtable >> TTBR1_PA_SHIFT));
-
-	/* Enable context fault interrupt */
-	SET_CFEIE(base, ctx, 1);
-
-	/* Stall access on a context fault and let the handler deal with it */
-	SET_CFCFG(base, ctx, 1);
-
-	/* Redirect all cacheable requests to L2 slave port. */
-	SET_RCISH(base, ctx, 1);
-	SET_RCOSH(base, ctx, 1);
-	SET_RCNSH(base, ctx, 1);
-
-	/* Turn on TEX Remap */
-	SET_TRE(base, ctx, 1);
-
-	/* Set TEX remap attributes */
-	RCP15_PRRR(prrr);
-	RCP15_NMRR(nmrr);
-	SET_PRRR(base, ctx, prrr);
-	SET_NMRR(base, ctx, nmrr);
-
-	/* Turn on BFB prefetch */
-	SET_BFBDFE(base, ctx, 1);
-
-	/* Configure page tables as inner-cacheable and shareable to reduce
-	 * the TLB miss penalty.
-	 */
-	if (redirect) {
-		SET_TTBR0_SH(base, ctx, 1);
-		SET_TTBR1_SH(base, ctx, 1);
-
-		SET_TTBR0_NOS(base, ctx, 1);
-		SET_TTBR1_NOS(base, ctx, 1);
-
-		SET_TTBR0_IRGNH(base, ctx, 0); /* WB, WA */
-		SET_TTBR0_IRGNL(base, ctx, 1);
-
-		SET_TTBR1_IRGNH(base, ctx, 0); /* WB, WA */
-		SET_TTBR1_IRGNL(base, ctx, 1);
-
-		SET_TTBR0_ORGN(base, ctx, 1); /* WB, WA */
-		SET_TTBR1_ORGN(base, ctx, 1); /* WB, WA */
-	}
-
-	/* Find if this page table is used elsewhere, and re-use ASID */
-	found = 0;
-	for (i = 0; i < ncb; i++)
-		if (GET_TTBR0_PA(base, i) == (pgtable >> TTBR0_PA_SHIFT) &&
-		    i != ctx) {
-			SET_CONTEXTIDR_ASID(base, ctx, \
-					    GET_CONTEXTIDR_ASID(base, i));
-			found = 1;
-			break;
-		}
-
-	/* If page table is new, find an unused ASID */
-	if (!found) {
-		for (i = 0; i < ncb; i++) {
-			found = 0;
-			for (j = 0; j < ncb; j++) {
-				if (GET_CONTEXTIDR_ASID(base, j) == i &&
-				    j != ctx)
-					found = 1;
-			}
-
-			if (!found) {
-				SET_CONTEXTIDR_ASID(base, ctx, i);
-				break;
-			}
-		}
-		BUG_ON(found);
-	}
-
-	/* Enable the MMU */
-	SET_M(base, ctx, 1);
-	mb();
-
-	msm_iommu_remote_spin_unlock();
-}
-
-static int msm_iommu_domain_init(struct iommu_domain *domain, int flags)
-{
-	struct msm_priv *priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-
-	if (!priv)
-		goto fail_nomem;
-
-	INIT_LIST_HEAD(&priv->list_attached);
-	priv->pgtable = (unsigned long *)__get_free_pages(GFP_KERNEL,
-							  get_order(SZ_16K));
-
-	if (!priv->pgtable)
-		goto fail_nomem;
-
-#ifdef CONFIG_IOMMU_PGTABLES_L2
-	priv->redirect = flags & MSM_IOMMU_DOMAIN_PT_CACHEABLE;
-#endif
-
-	memset(priv->pgtable, 0, SZ_16K);
-	domain->priv = priv;
-
-	clean_pte(priv->pgtable, priv->pgtable + NUM_FL_PTE, priv->redirect);
-
-	return 0;
-
-fail_nomem:
-	kfree(priv);
-	return -ENOMEM;
-}
-
-static void msm_iommu_domain_destroy(struct iommu_domain *domain)
-{
-	struct msm_priv *priv;
-	unsigned long *fl_table;
-	int i;
-
-	mutex_lock(&msm_iommu_lock);
-	priv = domain->priv;
-	domain->priv = NULL;
-
-	if (priv) {
-		fl_table = priv->pgtable;
-
-		for (i = 0; i < NUM_FL_PTE; i++)
-			if ((fl_table[i] & 0x03) == FL_TYPE_TABLE)
-				free_page((unsigned long) __va(((fl_table[i]) &
-								FL_BASE_MASK)));
-
-		free_pages((unsigned long)priv->pgtable, get_order(SZ_16K));
-		priv->pgtable = NULL;
-	}
-
-	kfree(priv);
-	mutex_unlock(&msm_iommu_lock);
-}
-
-static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
-{
-	struct msm_priv *priv;
-	struct msm_iommu_drvdata *iommu_drvdata;
-	struct msm_iommu_ctx_drvdata *ctx_drvdata;
-	struct msm_iommu_ctx_drvdata *tmp_drvdata;
-	int ret = 0;
-
-	mutex_lock(&msm_iommu_lock);
-
-	priv = domain->priv;
-
-	if (!priv || !dev) {
-		ret = -EINVAL;
-		goto fail;
-	}
-
-	iommu_drvdata = dev_get_drvdata(dev->parent);
-	ctx_drvdata = dev_get_drvdata(dev);
-
-	if (!iommu_drvdata || !ctx_drvdata) {
-		ret = -EINVAL;
-		goto fail;
-	}
-
-	if (!list_empty(&ctx_drvdata->attached_elm)) {
-		ret = -EBUSY;
-		goto fail;
-	}
-
-	list_for_each_entry(tmp_drvdata, &priv->list_attached, attached_elm)
-		if (tmp_drvdata == ctx_drvdata) {
-			ret = -EBUSY;
-			goto fail;
-		}
-
-	ret = __enable_clocks(iommu_drvdata);
-	if (ret)
-		goto fail;
-
-	__program_context(iommu_drvdata->base, iommu_drvdata->glb_base,
-			  ctx_drvdata->num, iommu_drvdata->ncb,
-			  __pa(priv->pgtable), priv->redirect,
-			  iommu_drvdata->ttbr_split);
-
-	__disable_clocks(iommu_drvdata);
-	list_add(&(ctx_drvdata->attached_elm), &priv->list_attached);
-
-	ctx_drvdata->attached_domain = domain;
-fail:
-	mutex_unlock(&msm_iommu_lock);
-	return ret;
-}
-
-static void msm_iommu_detach_dev(struct iommu_domain *domain,
-				 struct device *dev)
-{
-	struct msm_priv *priv;
-	struct msm_iommu_ctx_dev *ctx_dev;
-	struct msm_iommu_drvdata *iommu_drvdata;
-	struct msm_iommu_ctx_drvdata *ctx_drvdata;
-	int ret;
-
-	mutex_lock(&msm_iommu_lock);
-	priv = domain->priv;
-
-	if (!priv || !dev)
-		goto fail;
-
-	iommu_drvdata = dev_get_drvdata(dev->parent);
-	ctx_drvdata = dev_get_drvdata(dev);
-	ctx_dev = dev->platform_data;
-
-	if (!iommu_drvdata || !ctx_drvdata || !ctx_dev)
-		goto fail;
-
-	ret = __enable_clocks(iommu_drvdata);
-	if (ret)
-		goto fail;
-
-	msm_iommu_remote_spin_lock();
-
-	SET_TLBIASID(iommu_drvdata->base, ctx_dev->num,
-		     GET_CONTEXTIDR_ASID(iommu_drvdata->base, ctx_dev->num));
-
-	__reset_context(iommu_drvdata->base, iommu_drvdata->glb_base,
-			ctx_dev->num);
-
-	msm_iommu_remote_spin_unlock();
-
-	__disable_clocks(iommu_drvdata);
-	list_del_init(&ctx_drvdata->attached_elm);
-	ctx_drvdata->attached_domain = NULL;
-fail:
-	mutex_unlock(&msm_iommu_lock);
-}
-
-static int __get_pgprot(int prot, int len)
-{
-	unsigned int pgprot;
-	int tex;
-
-	if (!(prot & (IOMMU_READ | IOMMU_WRITE))) {
-		prot |= IOMMU_READ | IOMMU_WRITE;
-		WARN_ONCE(1, "No attributes in iommu mapping; assuming RW\n");
-	}
-
-	if ((prot & IOMMU_WRITE) && !(prot & IOMMU_READ)) {
-		prot |= IOMMU_READ;
-		WARN_ONCE(1, "Write-only iommu mappings unsupported; falling back to RW\n");
-	}
-
-	if (prot & IOMMU_CACHE)
-		tex = (pgprot_kernel >> 2) & 0x07;
-	else
-		tex = msm_iommu_tex_class[MSM_IOMMU_ATTR_NONCACHED];
-
-	if (tex < 0 || tex > NUM_TEX_CLASS - 1)
-		return 0;
-
-	if (len == SZ_16M || len == SZ_1M) {
-		pgprot = FL_SHARED;
-		pgprot |= tex & 0x01 ? FL_BUFFERABLE : 0;
-		pgprot |= tex & 0x02 ? FL_CACHEABLE : 0;
-		pgprot |= tex & 0x04 ? FL_TEX0 : 0;
-		pgprot |= FL_AP0 | FL_AP1;
-		pgprot |= prot & IOMMU_WRITE ? 0 : FL_AP2;
-	} else	{
-		pgprot = SL_SHARED;
-		pgprot |= tex & 0x01 ? SL_BUFFERABLE : 0;
-		pgprot |= tex & 0x02 ? SL_CACHEABLE : 0;
-		pgprot |= tex & 0x04 ? SL_TEX0 : 0;
-		pgprot |= SL_AP0 | SL_AP1;
-		pgprot |= prot & IOMMU_WRITE ? 0 : SL_AP2;
-	}
-
-	return pgprot;
-}
-
-static unsigned long *make_second_level(struct msm_priv *priv,
-					unsigned long *fl_pte)
-{
-	unsigned long *sl;
-	sl = (unsigned long *) __get_free_pages(GFP_KERNEL,
-			get_order(SZ_4K));
-
-	if (!sl) {
-		pr_debug("Could not allocate second level table\n");
-		goto fail;
-	}
-	memset(sl, 0, SZ_4K);
-	clean_pte(sl, sl + NUM_SL_PTE, priv->redirect);
-
-	*fl_pte = ((((int)__pa(sl)) & FL_BASE_MASK) | \
-			FL_TYPE_TABLE);
-
-	clean_pte(fl_pte, fl_pte + 1, priv->redirect);
-fail:
-	return sl;
-}
-
-static int sl_4k(unsigned long *sl_pte, phys_addr_t pa, unsigned int pgprot)
-{
-	int ret = 0;
-
-	if (*sl_pte) {
-		ret = -EBUSY;
-		goto fail;
-	}
-
-	*sl_pte = (pa & SL_BASE_MASK_SMALL) | SL_NG | SL_SHARED
-		| SL_TYPE_SMALL | pgprot;
-fail:
-	return ret;
-}
-
-static int sl_64k(unsigned long *sl_pte, phys_addr_t pa, unsigned int pgprot)
-{
-	int ret = 0;
-
-	int i;
-
-	for (i = 0; i < 16; i++)
-		if (*(sl_pte+i)) {
-			ret = -EBUSY;
-			goto fail;
-		}
-
-	for (i = 0; i < 16; i++)
-		*(sl_pte+i) = (pa & SL_BASE_MASK_LARGE) | SL_NG
-				| SL_SHARED | SL_TYPE_LARGE | pgprot;
-
-fail:
-	return ret;
-}
-
-
-static inline int fl_1m(unsigned long *fl_pte, phys_addr_t pa, int pgprot)
-{
-	if (*fl_pte)
-		return -EBUSY;
-
-	*fl_pte = (pa & 0xFFF00000) | FL_NG | FL_TYPE_SECT | FL_SHARED
-		| pgprot;
-
-	return 0;
-}
-
-
-static inline int fl_16m(unsigned long *fl_pte, phys_addr_t pa, int pgprot)
-{
-	int i;
-	int ret = 0;
-	for (i = 0; i < 16; i++)
-		if (*(fl_pte+i)) {
-			ret = -EBUSY;
-			goto fail;
-		}
-	for (i = 0; i < 16; i++)
-		*(fl_pte+i) = (pa & 0xFF000000) | FL_SUPERSECTION
-			| FL_TYPE_SECT | FL_SHARED | FL_NG | pgprot;
-fail:
-	return ret;
-}
-
-static int msm_iommu_map(struct iommu_domain *domain, unsigned long va,
-			 phys_addr_t pa, size_t len, int prot)
-{
-	struct msm_priv *priv;
-	unsigned long *fl_table;
-	unsigned long *fl_pte;
-	unsigned long fl_offset;
-	unsigned long *sl_table;
-	unsigned long *sl_pte;
-	unsigned long sl_offset;
-	unsigned int pgprot;
-	int ret = 0;
-
-	mutex_lock(&msm_iommu_lock);
-
-	priv = domain->priv;
-	if (!priv) {
-		ret = -EINVAL;
-		goto fail;
-	}
-
-	fl_table = priv->pgtable;
-
-	if (len != SZ_16M && len != SZ_1M &&
-	    len != SZ_64K && len != SZ_4K) {
-		pr_debug("Bad size: %d\n", len);
-		ret = -EINVAL;
-		goto fail;
-	}
-
-	if (!fl_table) {
-		pr_debug("Null page table\n");
-		ret = -EINVAL;
-		goto fail;
-	}
-
-	pgprot = __get_pgprot(prot, len);
-
-	if (!pgprot) {
-		ret = -EINVAL;
-		goto fail;
-	}
-
-	fl_offset = FL_OFFSET(va);	/* Upper 12 bits */
-	fl_pte = fl_table + fl_offset;	/* int pointers, 4 bytes */
-
-	if (len == SZ_16M) {
-		ret = fl_16m(fl_pte, pa, pgprot);
-		if (ret)
-			goto fail;
-		clean_pte(fl_pte, fl_pte + 16, priv->redirect);
-	}
-
-	if (len == SZ_1M) {
-		ret = fl_1m(fl_pte, pa, pgprot);
-		if (ret)
-			goto fail;
-		clean_pte(fl_pte, fl_pte + 1, priv->redirect);
-	}
-
-	/* Need a 2nd level table */
-	if (len == SZ_4K || len == SZ_64K) {
-
-		if (*fl_pte == 0) {
-			if (make_second_level(priv, fl_pte) == NULL) {
-				ret = -ENOMEM;
-				goto fail;
-			}
-		}
-
-		if (!(*fl_pte & FL_TYPE_TABLE)) {
-			ret = -EBUSY;
-			goto fail;
-		}
-	}
-
-	sl_table = (unsigned long *) __va(((*fl_pte) & FL_BASE_MASK));
-	sl_offset = SL_OFFSET(va);
-	sl_pte = sl_table + sl_offset;
-
-	if (len == SZ_4K) {
-		ret = sl_4k(sl_pte, pa, pgprot);
-		if (ret)
-			goto fail;
-
-		clean_pte(sl_pte, sl_pte + 1, priv->redirect);
-	}
-
-	if (len == SZ_64K) {
-		ret = sl_64k(sl_pte, pa, pgprot);
-		if (ret)
-			goto fail;
-		clean_pte(sl_pte, sl_pte + 16, priv->redirect);
-	}
-
-	ret = __flush_iotlb_va(domain, va);
-fail:
-	mutex_unlock(&msm_iommu_lock);
-	return ret;
-}
-
-static size_t msm_iommu_unmap(struct iommu_domain *domain, unsigned long va,
-			    size_t len)
-{
-	struct msm_priv *priv;
-	unsigned long *fl_table;
-	unsigned long *fl_pte;
-	unsigned long fl_offset;
-	unsigned long *sl_table;
-	unsigned long *sl_pte;
-	unsigned long sl_offset;
-	int i, ret = 0;
-
-	mutex_lock(&msm_iommu_lock);
-
-	priv = domain->priv;
-
-	if (!priv)
-		goto fail;
-
-	fl_table = priv->pgtable;
-
-	if (len != SZ_16M && len != SZ_1M &&
-	    len != SZ_64K && len != SZ_4K) {
-		pr_debug("Bad length: %d\n", len);
-		goto fail;
-	}
-
-	if (!fl_table) {
-		pr_debug("Null page table\n");
-		goto fail;
-	}
-
-	fl_offset = FL_OFFSET(va);	/* Upper 12 bits */
-	fl_pte = fl_table + fl_offset;	/* int pointers, 4 bytes */
-
-	if (*fl_pte == 0) {
-		pr_debug("First level PTE is 0\n");
-		goto fail;
-	}
-
-	/* Unmap supersection */
-	if (len == SZ_16M) {
-		for (i = 0; i < 16; i++)
-			*(fl_pte+i) = 0;
-
-		clean_pte(fl_pte, fl_pte + 16, priv->redirect);
-	}
-
-	if (len == SZ_1M) {
-		*fl_pte = 0;
-
-		clean_pte(fl_pte, fl_pte + 1, priv->redirect);
-	}
-
-	sl_table = (unsigned long *) __va(((*fl_pte) & FL_BASE_MASK));
-	sl_offset = SL_OFFSET(va);
-	sl_pte = sl_table + sl_offset;
-
-	if (len == SZ_64K) {
-		for (i = 0; i < 16; i++)
-			*(sl_pte+i) = 0;
-
-		clean_pte(sl_pte, sl_pte + 16, priv->redirect);
-	}
-
-	if (len == SZ_4K) {
-		*sl_pte = 0;
-
-		clean_pte(sl_pte, sl_pte + 1, priv->redirect);
-	}
-
-	if (len == SZ_4K || len == SZ_64K) {
-		int used = 0;
-
-		for (i = 0; i < NUM_SL_PTE; i++)
-			if (sl_table[i])
-				used = 1;
-		if (!used) {
-			free_page((unsigned long)sl_table);
-			*fl_pte = 0;
-
-			clean_pte(fl_pte, fl_pte + 1, priv->redirect);
-		}
-	}
-
-	ret = __flush_iotlb_va(domain, va);
-
-fail:
-	mutex_unlock(&msm_iommu_lock);
-
-	/* the IOMMU API requires us to return how many bytes were unmapped */
-	len = ret ? 0 : len;
-	return len;
-}
-
-static unsigned int get_phys_addr(struct scatterlist *sg)
-{
-	/*
-	 * Try sg_dma_address first so that we can
-	 * map carveout regions that do not have a
-	 * struct page associated with them.
-	 */
-	unsigned int pa = sg_dma_address(sg);
-	if (pa == 0)
-		pa = sg_phys(sg);
-	return pa;
-}
-
-static inline int is_fully_aligned(unsigned int va, phys_addr_t pa, size_t len,
-				   int align)
-{
-	return  IS_ALIGNED(va, align) && IS_ALIGNED(pa, align)
-		&& (len >= align);
-}
-
-static int check_range(unsigned long *fl_table, unsigned int va,
-				 unsigned int len)
-{
-	unsigned int offset = 0;
-	unsigned long *fl_pte;
-	unsigned long fl_offset;
-	unsigned long *sl_table;
-	unsigned long sl_start, sl_end;
-	int i;
-
-	fl_offset = FL_OFFSET(va);	/* Upper 12 bits */
-	fl_pte = fl_table + fl_offset;	/* int pointers, 4 bytes */
-
-	while (offset < len) {
-		if (*fl_pte & FL_TYPE_TABLE) {
-			sl_start = SL_OFFSET(va);
-			sl_table =  __va(((*fl_pte) & FL_BASE_MASK));
-			sl_end = ((len - offset) / SZ_4K) + sl_start;
-
-			if (sl_end > NUM_SL_PTE)
-				sl_end = NUM_SL_PTE;
-
-			for (i = sl_start; i < sl_end; i++) {
-				if (sl_table[i] != 0) {
-					pr_err("%08x - %08x already mapped\n",
-						va, va + SZ_4K);
-					return -EBUSY;
-				}
-				offset += SZ_4K;
-				va += SZ_4K;
-			}
-
-
-			sl_start = 0;
-		} else {
-			if (*fl_pte != 0) {
-				pr_err("%08x - %08x already mapped\n",
-				       va, va + SZ_1M);
-				return -EBUSY;
-			}
-			va += SZ_1M;
-			offset += SZ_1M;
-			sl_start = 0;
-		}
-		fl_pte++;
-	}
-	return 0;
-}
-
-static int msm_iommu_map_range(struct iommu_domain *domain, unsigned int va,
-			       struct scatterlist *sg, unsigned int len,
-			       int prot)
-{
-	unsigned int pa;
-	unsigned int offset = 0;
-	unsigned long *fl_table;
-	unsigned long *fl_pte;
-	unsigned long fl_offset;
-	unsigned long *sl_table = NULL;
-	unsigned long sl_offset, sl_start;
-	unsigned int chunk_size, chunk_offset = 0;
-	int ret = 0;
-	struct msm_priv *priv;
-	unsigned int pgprot4k, pgprot64k, pgprot1m, pgprot16m;
-
-	mutex_lock(&msm_iommu_lock);
-
-	BUG_ON(len & (SZ_4K - 1));
-
-	priv = domain->priv;
-	fl_table = priv->pgtable;
-
-	pgprot4k = __get_pgprot(prot, SZ_4K);
-	pgprot64k = __get_pgprot(prot, SZ_64K);
-	pgprot1m = __get_pgprot(prot, SZ_1M);
-	pgprot16m = __get_pgprot(prot, SZ_16M);
-
-	if (!pgprot4k || !pgprot64k || !pgprot1m || !pgprot16m) {
-		ret = -EINVAL;
-		goto fail;
-	}
-	ret = check_range(fl_table, va, len);
-	if (ret)
-		goto fail;
-
-	fl_offset = FL_OFFSET(va);	/* Upper 12 bits */
-	fl_pte = fl_table + fl_offset;	/* int pointers, 4 bytes */
-	pa = get_phys_addr(sg);
-
-	while (offset < len) {
-		chunk_size = SZ_4K;
-
-		if (is_fully_aligned(va, pa, sg->length - chunk_offset,
-				     SZ_16M))
-			chunk_size = SZ_16M;
-		else if (is_fully_aligned(va, pa, sg->length - chunk_offset,
-					  SZ_1M))
-			chunk_size = SZ_1M;
-		/* 64k or 4k determined later */
-
-		/* for 1M and 16M, only first level entries are required */
-		if (chunk_size >= SZ_1M) {
-			if (chunk_size == SZ_16M) {
-				ret = fl_16m(fl_pte, pa, pgprot16m);
-				if (ret)
-					goto fail;
-				clean_pte(fl_pte, fl_pte + 16, priv->redirect);
-				fl_pte += 16;
-			} else if (chunk_size == SZ_1M) {
-				ret = fl_1m(fl_pte, pa, pgprot1m);
-				if (ret)
-					goto fail;
-				clean_pte(fl_pte, fl_pte + 1, priv->redirect);
-				fl_pte++;
-			}
-
-			offset += chunk_size;
-			chunk_offset += chunk_size;
-			va += chunk_size;
-			pa += chunk_size;
-
-			if (chunk_offset >= sg->length && offset < len) {
-				chunk_offset = 0;
-				sg = sg_next(sg);
-				pa = get_phys_addr(sg);
-				if (pa == 0) {
-					pr_debug("No dma address for sg %p\n",
-							sg);
-					ret = -EINVAL;
-					goto fail;
-				}
-			}
-			continue;
-		}
-		/* for 4K or 64K, make sure there is a second level table */
-		if (*fl_pte == 0) {
-			if (!make_second_level(priv, fl_pte)) {
-				ret = -ENOMEM;
-				goto fail;
-			}
-		}
-		if (!(*fl_pte & FL_TYPE_TABLE)) {
-			ret = -EBUSY;
-			goto fail;
-		}
-		sl_table = __va(((*fl_pte) & FL_BASE_MASK));
-		sl_offset = SL_OFFSET(va);
-		/* Keep track of initial position so we
-		 * don't clean more than we have to
-		 */
-		sl_start = sl_offset;
-
-		/* Build the 2nd level page table */
-		while (offset < len && sl_offset < NUM_SL_PTE) {
-
-			/* Map a large 64K page if the chunk is large enough and
-			 * the pa and va are aligned
-			 */
-
-			if (is_fully_aligned(va, pa, sg->length - chunk_offset,
-					     SZ_64K))
-				chunk_size = SZ_64K;
-			else
-				chunk_size = SZ_4K;
-
-			if (chunk_size == SZ_4K) {
-				sl_4k(&sl_table[sl_offset], pa, pgprot4k);
-				sl_offset++;
-			} else {
-				BUG_ON(sl_offset + 16 > NUM_SL_PTE);
-				sl_64k(&sl_table[sl_offset], pa, pgprot64k);
-				sl_offset += 16;
-			}
-
-
-			offset += chunk_size;
-			chunk_offset += chunk_size;
-			va += chunk_size;
-			pa += chunk_size;
-
-			if (chunk_offset >= sg->length && offset < len) {
-				chunk_offset = 0;
-				sg = sg_next(sg);
-				pa = get_phys_addr(sg);
-				if (pa == 0) {
-					pr_debug("No dma address for sg %p\n",
-							sg);
-					ret = -EINVAL;
-					goto fail;
-				}
-			}
-		}
-
-		clean_pte(sl_table + sl_start, sl_table + sl_offset,
-				priv->redirect);
-
-		fl_pte++;
-		sl_offset = 0;
-	}
-	__flush_iotlb(domain);
-fail:
-	mutex_unlock(&msm_iommu_lock);
-	return ret;
-}
-
-
-static int msm_iommu_unmap_range(struct iommu_domain *domain, unsigned int va,
-				 unsigned int len)
-{
-	unsigned int offset = 0;
-	unsigned long *fl_table;
-	unsigned long *fl_pte;
-	unsigned long fl_offset;
-	unsigned long *sl_table;
-	unsigned long sl_start, sl_end;
-	int used, i;
-	struct msm_priv *priv;
-
-	mutex_lock(&msm_iommu_lock);
-
-	BUG_ON(len & (SZ_4K - 1));
-
-	priv = domain->priv;
-	fl_table = priv->pgtable;
-
-	fl_offset = FL_OFFSET(va);	/* Upper 12 bits */
-	fl_pte = fl_table + fl_offset;	/* int pointers, 4 bytes */
-
-	while (offset < len) {
-		if (*fl_pte & FL_TYPE_TABLE) {
-			sl_start = SL_OFFSET(va);
-			sl_table =  __va(((*fl_pte) & FL_BASE_MASK));
-			sl_end = ((len - offset) / SZ_4K) + sl_start;
-
-			if (sl_end > NUM_SL_PTE)
-				sl_end = NUM_SL_PTE;
-
-			memset(sl_table + sl_start, 0, (sl_end - sl_start) * 4);
-			clean_pte(sl_table + sl_start, sl_table + sl_end,
-					priv->redirect);
-
-			offset += (sl_end - sl_start) * SZ_4K;
-			va += (sl_end - sl_start) * SZ_4K;
-
-			/* Unmap and free the 2nd level table if all mappings
-			 * in it were removed. This saves memory, but the table
-			 * will need to be re-allocated the next time someone
-			 * tries to map these VAs.
-			 */
-			used = 0;
-
-			/* If we just unmapped the whole table, don't bother
-			 * seeing if there are still used entries left.
-			 */
-			if (sl_end - sl_start != NUM_SL_PTE)
-				for (i = 0; i < NUM_SL_PTE; i++)
-					if (sl_table[i]) {
-						used = 1;
-						break;
-					}
-			if (!used) {
-				free_page((unsigned long)sl_table);
-				*fl_pte = 0;
-
-				clean_pte(fl_pte, fl_pte + 1, priv->redirect);
-			}
-
-			sl_start = 0;
-		} else {
-			*fl_pte = 0;
-			clean_pte(fl_pte, fl_pte + 1, priv->redirect);
-			va += SZ_1M;
-			offset += SZ_1M;
-			sl_start = 0;
-		}
-		fl_pte++;
-	}
-
-	__flush_iotlb(domain);
-	mutex_unlock(&msm_iommu_lock);
-	return 0;
-}
-
-static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain,
-					  unsigned long va)
-{
-	struct msm_priv *priv;
-	struct msm_iommu_drvdata *iommu_drvdata;
-	struct msm_iommu_ctx_drvdata *ctx_drvdata;
-	unsigned int par;
-	void __iomem *base;
-	phys_addr_t ret = 0;
-	int ctx;
-
-	mutex_lock(&msm_iommu_lock);
-
-	priv = domain->priv;
-	if (list_empty(&priv->list_attached))
-		goto fail;
-
-	ctx_drvdata = list_entry(priv->list_attached.next,
-				 struct msm_iommu_ctx_drvdata, attached_elm);
-	iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent);
-
-	base = iommu_drvdata->base;
-	ctx = ctx_drvdata->num;
-
-	ret = __enable_clocks(iommu_drvdata);
-	if (ret)
-		goto fail;
-
-	msm_iommu_remote_spin_lock();
-
-	SET_V2PPR(base, ctx, va & V2Pxx_VA);
-
-	mb();
-	par = GET_PAR(base, ctx);
-
-	/* We are dealing with a supersection */
-	if (GET_NOFAULT_SS(base, ctx))
-		ret = (par & 0xFF000000) | (va & 0x00FFFFFF);
-	else	/* Upper 20 bits from PAR, lower 12 from VA */
-		ret = (par & 0xFFFFF000) | (va & 0x00000FFF);
-
-	if (GET_FAULT(base, ctx))
-		ret = 0;
-
-	msm_iommu_remote_spin_unlock();
-
-	__disable_clocks(iommu_drvdata);
-fail:
-	mutex_unlock(&msm_iommu_lock);
-	return ret;
-}
-
-static int msm_iommu_domain_has_cap(struct iommu_domain *domain,
-				    unsigned long cap)
-{
-	return 0;
-}
-
-static void print_ctx_regs(void __iomem *base, int ctx)
-{
-	unsigned int fsr = GET_FSR(base, ctx);
-	pr_err("FAR    = %08x    PAR    = %08x\n",
-	       GET_FAR(base, ctx), GET_PAR(base, ctx));
-	pr_err("FSR    = %08x [%s%s%s%s%s%s%s%s%s%s]\n", fsr,
-			(fsr & 0x02) ? "TF " : "",
-			(fsr & 0x04) ? "AFF " : "",
-			(fsr & 0x08) ? "APF " : "",
-			(fsr & 0x10) ? "TLBMF " : "",
-			(fsr & 0x20) ? "HTWDEEF " : "",
-			(fsr & 0x40) ? "HTWSEEF " : "",
-			(fsr & 0x80) ? "MHF " : "",
-			(fsr & 0x10000) ? "SL " : "",
-			(fsr & 0x40000000) ? "SS " : "",
-			(fsr & 0x80000000) ? "MULTI " : "");
-
-	pr_err("FSYNR0 = %08x    FSYNR1 = %08x\n",
-	       GET_FSYNR0(base, ctx), GET_FSYNR1(base, ctx));
-	pr_err("TTBR0  = %08x    TTBR1  = %08x\n",
-	       GET_TTBR0(base, ctx), GET_TTBR1(base, ctx));
-	pr_err("SCTLR  = %08x    ACTLR  = %08x\n",
-	       GET_SCTLR(base, ctx), GET_ACTLR(base, ctx));
-	pr_err("PRRR   = %08x    NMRR   = %08x\n",
-	       GET_PRRR(base, ctx), GET_NMRR(base, ctx));
-}
-
-irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id)
-{
-	struct msm_iommu_ctx_drvdata *ctx_drvdata = dev_id;
-	struct msm_iommu_drvdata *drvdata;
-	void __iomem *base;
-	unsigned int fsr, num;
-	int ret;
-
-	mutex_lock(&msm_iommu_lock);
-	BUG_ON(!ctx_drvdata);
-
-	drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent);
-	BUG_ON(!drvdata);
-
-	base = drvdata->base;
-	num = ctx_drvdata->num;
-
-	ret = __enable_clocks(drvdata);
-	if (ret)
-		goto fail;
-
-	msm_iommu_remote_spin_lock();
-
-	fsr = GET_FSR(base, num);
-
-	if (fsr) {
-		if (!ctx_drvdata->attached_domain) {
-			pr_err("Bad domain in interrupt handler\n");
-			ret = -ENOSYS;
-		} else
-			ret = report_iommu_fault(ctx_drvdata->attached_domain,
-						&ctx_drvdata->pdev->dev,
-						GET_FAR(base, num), 0);
-
-		if (ret == -ENOSYS) {
-			pr_err("Unexpected IOMMU page fault!\n");
-			pr_err("name    = %s\n", drvdata->name);
-			pr_err("context = %s (%d)\n", ctx_drvdata->name, num);
-			pr_err("Interesting registers:\n");
-			print_ctx_regs(base, num);
-		}
-
-		SET_FSR(base, num, fsr);
-		/*
-		 * Only resume fetches if the registered fault handler
-		 * allows it
-		 */
-		if (ret != -EBUSY)
-			SET_RESUME(base, num, 1);
-
-		ret = IRQ_HANDLED;
-	} else
-		ret = IRQ_NONE;
-
-	msm_iommu_remote_spin_unlock();
-
-	__disable_clocks(drvdata);
-fail:
-	mutex_unlock(&msm_iommu_lock);
-	return ret;
-}
-
-static phys_addr_t msm_iommu_get_pt_base_addr(struct iommu_domain *domain)
-{
-	struct msm_priv *priv = domain->priv;
-	return __pa(priv->pgtable);
-}
-
-static struct iommu_ops msm_iommu_ops = {
-	.domain_init = msm_iommu_domain_init,
-	.domain_destroy = msm_iommu_domain_destroy,
-	.attach_dev = msm_iommu_attach_dev,
-	.detach_dev = msm_iommu_detach_dev,
-	.map = msm_iommu_map,
-	.unmap = msm_iommu_unmap,
-	.map_range = msm_iommu_map_range,
-	.unmap_range = msm_iommu_unmap_range,
-	.iova_to_phys = msm_iommu_iova_to_phys,
-	.domain_has_cap = msm_iommu_domain_has_cap,
-	.get_pt_base_addr = msm_iommu_get_pt_base_addr,
-	.pgsize_bitmap = MSM_IOMMU_PGSIZES,
-};
-
-static int __init get_tex_class(int icp, int ocp, int mt, int nos)
-{
-	int i = 0;
-	unsigned int prrr = 0;
-	unsigned int nmrr = 0;
-	int c_icp, c_ocp, c_mt, c_nos;
-
-	RCP15_PRRR(prrr);
-	RCP15_NMRR(nmrr);
-
-	for (i = 0; i < NUM_TEX_CLASS; i++) {
-		c_nos = PRRR_NOS(prrr, i);
-		c_mt = PRRR_MT(prrr, i);
-		c_icp = NMRR_ICP(nmrr, i);
-		c_ocp = NMRR_OCP(nmrr, i);
-
-		if (icp == c_icp && ocp == c_ocp && c_mt == mt && c_nos == nos)
-			return i;
-	}
-
-	return -ENODEV;
-}
-
-static void __init setup_iommu_tex_classes(void)
-{
-	msm_iommu_tex_class[MSM_IOMMU_ATTR_NONCACHED] =
-			get_tex_class(CP_NONCACHED, CP_NONCACHED, MT_NORMAL, 1);
-
-	msm_iommu_tex_class[MSM_IOMMU_ATTR_CACHED_WB_WA] =
-			get_tex_class(CP_WB_WA, CP_WB_WA, MT_NORMAL, 1);
-
-	msm_iommu_tex_class[MSM_IOMMU_ATTR_CACHED_WB_NWA] =
-			get_tex_class(CP_WB_NWA, CP_WB_NWA, MT_NORMAL, 1);
-
-	msm_iommu_tex_class[MSM_IOMMU_ATTR_CACHED_WT] =
-			get_tex_class(CP_WT, CP_WT, MT_NORMAL, 1);
-}
-
-static int __init msm_iommu_init(void)
-{
-	if (!msm_soc_version_supports_iommu_v1())
-		return -ENODEV;
-
-	msm_iommu_lock_initialize();
-
-	setup_iommu_tex_classes();
-	bus_set_iommu(&platform_bus_type, &msm_iommu_ops);
-	return 0;
-}
-
-subsys_initcall(msm_iommu_init);
-
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");
diff --git a/drivers/iommu/msm_iommu_dev-v0.c b/drivers/iommu/msm_iommu_dev-v0.c
new file mode 100644
index 0000000..549800f
--- /dev/null
+++ b/drivers/iommu/msm_iommu_dev-v0.c
@@ -0,0 +1,695 @@
+/* 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 pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/iommu.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+
+#include <mach/iommu_perfmon.h>
+#include <mach/iommu_hw-v0.h>
+#include <mach/iommu.h>
+
+static DEFINE_MUTEX(iommu_list_lock);
+static LIST_HEAD(iommu_list);
+
+void msm_iommu_add_drv(struct msm_iommu_drvdata *drv)
+{
+	mutex_lock(&iommu_list_lock);
+	list_add(&drv->list, &iommu_list);
+	mutex_unlock(&iommu_list_lock);
+}
+
+void msm_iommu_remove_drv(struct msm_iommu_drvdata *drv)
+{
+	mutex_lock(&iommu_list_lock);
+	list_del(&drv->list);
+	mutex_unlock(&iommu_list_lock);
+}
+
+static int find_iommu_ctx(struct device *dev, void *data)
+{
+	struct msm_iommu_ctx_drvdata *c;
+
+	c = dev_get_drvdata(dev);
+	if (!c || !c->name)
+		return 0;
+
+	return !strcmp(data, c->name);
+}
+
+static struct device *find_context(struct device *dev, const char *name)
+{
+	return device_find_child(dev, (void *)name, find_iommu_ctx);
+}
+
+struct device *msm_iommu_get_ctx(const char *ctx_name)
+{
+	struct msm_iommu_drvdata *drv;
+	struct device *dev = NULL;
+
+	mutex_lock(&iommu_list_lock);
+	list_for_each_entry(drv, &iommu_list, list) {
+		dev = find_context(drv->dev, ctx_name);
+		if (dev)
+			break;
+	}
+	mutex_unlock(&iommu_list_lock);
+
+	if (!dev || !dev_get_drvdata(dev))
+		pr_err("Could not find context <%s>\n", ctx_name);
+	put_device(dev);
+
+	return dev;
+}
+EXPORT_SYMBOL(msm_iommu_get_ctx);
+
+static void msm_iommu_reset(void __iomem *base, void __iomem *glb_base, int ncb)
+{
+	int ctx;
+
+	SET_RPUE(glb_base, 0);
+	SET_RPUEIE(glb_base, 0);
+	SET_ESRRESTORE(glb_base, 0);
+	SET_TBE(glb_base, 0);
+	SET_CR(glb_base, 0);
+	SET_SPDMBE(glb_base, 0);
+	SET_TESTBUSCR(glb_base, 0);
+	SET_TLBRSW(glb_base, 0);
+	SET_GLOBAL_TLBIALL(glb_base, 0);
+	SET_RPU_ACR(glb_base, 0);
+	SET_TLBLKCRWE(glb_base, 1);
+
+	for (ctx = 0; ctx < ncb; ctx++) {
+		SET_BPRCOSH(glb_base, ctx, 0);
+		SET_BPRCISH(glb_base, ctx, 0);
+		SET_BPRCNSH(glb_base, ctx, 0);
+		SET_BPSHCFG(glb_base, ctx, 0);
+		SET_BPMTCFG(glb_base, ctx, 0);
+		SET_ACTLR(base, ctx, 0);
+		SET_SCTLR(base, ctx, 0);
+		SET_FSRRESTORE(base, ctx, 0);
+		SET_TTBR0(base, ctx, 0);
+		SET_TTBR1(base, ctx, 0);
+		SET_TTBCR(base, ctx, 0);
+		SET_BFBCR(base, ctx, 0);
+		SET_PAR(base, ctx, 0);
+		SET_FAR(base, ctx, 0);
+		SET_TLBFLPTER(base, ctx, 0);
+		SET_TLBSLPTER(base, ctx, 0);
+		SET_TLBLKCR(base, ctx, 0);
+		SET_CTX_TLBIALL(base, ctx, 0);
+		SET_TLBIVA(base, ctx, 0);
+		SET_PRRR(base, ctx, 0);
+		SET_NMRR(base, ctx, 0);
+		SET_CONTEXTIDR(base, ctx, 0);
+	}
+	mb();
+}
+
+static int msm_iommu_parse_dt(struct platform_device *pdev,
+				struct msm_iommu_drvdata *drvdata)
+{
+#ifdef CONFIG_OF_DEVICE
+	struct device_node *child;
+	struct resource *r;
+	u32 glb_offset = 0;
+	int ret;
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!r) {
+		pr_err("%s: Missing property reg\n", __func__);
+		return -EINVAL;
+	}
+	drvdata->base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
+	if (!drvdata->base) {
+		pr_err("%s: Unable to ioremap %pr\n", __func__, r);
+		return -ENOMEM;
+	}
+	drvdata->glb_base = drvdata->base;
+
+	if (!of_property_read_u32(pdev->dev.of_node, "qcom,glb-offset",
+			&glb_offset)) {
+		drvdata->glb_base += glb_offset;
+	} else {
+		pr_err("%s: Missing property qcom,glb-offset\n", __func__);
+		return -EINVAL;
+	}
+
+	for_each_child_of_node(pdev->dev.of_node, child) {
+		drvdata->ncb++;
+		if (!of_platform_device_create(child, NULL, &pdev->dev))
+			pr_err("Failed to create %s device\n", child->name);
+	}
+
+	ret = of_property_read_string(pdev->dev.of_node, "label",
+			&drvdata->name);
+	if (ret) {
+		pr_err("%s: Missing property label\n", __func__);
+		return -EINVAL;
+	}
+	drvdata->sec_id = -1;
+	drvdata->ttbr_split = 0;
+#endif
+	return 0;
+}
+
+static int __get_clocks(struct platform_device *pdev,
+				 struct msm_iommu_drvdata *drvdata)
+{
+	int ret = 0;
+
+	drvdata->pclk = clk_get(&pdev->dev, "iface_clk");
+	if (IS_ERR(drvdata->pclk)) {
+		ret = PTR_ERR(drvdata->pclk);
+		drvdata->pclk = NULL;
+		pr_err("Unable to get %s clock for %s IOMMU device\n",
+			dev_name(&pdev->dev), drvdata->name);
+		goto fail;
+	}
+
+	drvdata->clk = clk_get(&pdev->dev, "core_clk");
+
+	if (!IS_ERR(drvdata->clk)) {
+		if (clk_get_rate(drvdata->clk) == 0) {
+			ret = clk_round_rate(drvdata->clk, 1000);
+			clk_set_rate(drvdata->clk, ret);
+		}
+	} else {
+		drvdata->clk = NULL;
+	}
+	return 0;
+fail:
+	return ret;
+}
+
+static void __put_clocks(struct msm_iommu_drvdata *drvdata)
+{
+	if (drvdata->clk)
+		clk_put(drvdata->clk);
+	clk_put(drvdata->pclk);
+}
+
+static int __enable_clocks(struct msm_iommu_drvdata *drvdata)
+{
+	int ret;
+
+	ret = clk_prepare_enable(drvdata->pclk);
+	if (ret)
+		goto fail;
+
+	if (drvdata->clk) {
+		ret = clk_prepare_enable(drvdata->clk);
+		if (ret)
+			clk_disable_unprepare(drvdata->pclk);
+	}
+fail:
+	return ret;
+}
+
+static void __disable_clocks(struct msm_iommu_drvdata *drvdata)
+{
+	if (drvdata->clk)
+		clk_disable_unprepare(drvdata->clk);
+	clk_disable_unprepare(drvdata->pclk);
+}
+
+/*
+ * Do a basic check of the IOMMU by performing an ATS operation
+ * on context bank 0.
+ */
+static int iommu_sanity_check(struct msm_iommu_drvdata *drvdata)
+{
+	int par;
+	int ret = 0;
+
+	SET_M(drvdata->base, 0, 1);
+	SET_PAR(drvdata->base, 0, 0);
+	SET_V2PCFG(drvdata->base, 0, 1);
+	SET_V2PPR(drvdata->base, 0, 0);
+	mb();
+	par = GET_PAR(drvdata->base, 0);
+	SET_V2PCFG(drvdata->base, 0, 0);
+	SET_M(drvdata->base, 0, 0);
+	mb();
+
+	if (!par) {
+		pr_err("%s: Invalid PAR value detected\n", drvdata->name);
+		ret = -ENODEV;
+	}
+	return ret;
+}
+
+static int msm_iommu_pmon_parse_dt(struct platform_device *pdev,
+					struct iommu_pmon *pmon_info)
+{
+	int ret = 0;
+	int irq = platform_get_irq(pdev, 0);
+	unsigned int cls_prop_size;
+
+	if (irq > 0) {
+		pmon_info->iommu.evt_irq = platform_get_irq(pdev, 0);
+
+		ret = of_property_read_u32(pdev->dev.of_node,
+					   "qcom,iommu-pmu-ngroups",
+					   &pmon_info->num_groups);
+		if (ret) {
+			pr_err("Error reading qcom,iommu-pmu-ngroups\n");
+			goto fail;
+		}
+		ret = of_property_read_u32(pdev->dev.of_node,
+					   "qcom,iommu-pmu-ncounters",
+					   &pmon_info->num_counters);
+		if (ret) {
+			pr_err("Error reading qcom,iommu-pmu-ncounters\n");
+			goto fail;
+		}
+
+		if (!of_get_property(pdev->dev.of_node,
+				     "qcom,iommu-pmu-event-classes",
+				     &cls_prop_size)) {
+			pr_err("Error reading qcom,iommu-pmu-event-classes\n");
+			return -EINVAL;
+		}
+
+		pmon_info->event_cls_supported =
+			   devm_kzalloc(&pdev->dev, cls_prop_size, GFP_KERNEL);
+
+		if (!pmon_info->event_cls_supported) {
+			pr_err("Unable to get memory for event class array\n");
+			return -ENOMEM;
+		}
+
+		pmon_info->nevent_cls_supported = cls_prop_size / sizeof(u32);
+
+		ret = of_property_read_u32_array(pdev->dev.of_node,
+					"qcom,iommu-pmu-event-classes",
+					pmon_info->event_cls_supported,
+					pmon_info->nevent_cls_supported);
+		if (ret) {
+			pr_err("Error reading qcom,iommu-pmu-event-classes\n");
+			return ret;
+		}
+	} else {
+		pmon_info->iommu.evt_irq = -1;
+		ret = irq;
+	}
+
+fail:
+	return ret;
+}
+
+static int msm_iommu_probe(struct platform_device *pdev)
+{
+	struct iommu_pmon *pmon_info;
+	struct msm_iommu_drvdata *drvdata;
+	struct msm_iommu_dev *iommu_dev = pdev->dev.platform_data;
+	int ret;
+
+	drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
+
+	if (!drvdata) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	if (pdev->dev.of_node) {
+		ret = msm_iommu_parse_dt(pdev, drvdata);
+		if (ret)
+			goto fail;
+	} else if (pdev->dev.platform_data) {
+		struct resource *r, *r2;
+		resource_size_t	len;
+
+		r = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+						"physbase");
+
+		if (!r) {
+			ret = -ENODEV;
+			goto fail;
+		}
+
+		len = resource_size(r);
+
+		r2 = request_mem_region(r->start, len, r->name);
+		if (!r2) {
+			pr_err("Could not request memory region: %pr\n", r);
+			ret = -EBUSY;
+			goto fail;
+		}
+
+		drvdata->base = devm_ioremap(&pdev->dev, r2->start, len);
+
+		if (!drvdata->base) {
+			pr_err("Could not ioremap: %pr\n", r);
+			ret = -EBUSY;
+			goto fail;
+		}
+		/*
+		 * Global register space offset for legacy IOMMUv1 hardware
+		 * is always 0xFF000
+		 */
+		drvdata->glb_base = drvdata->base + 0xFF000;
+		drvdata->name = iommu_dev->name;
+		drvdata->dev = &pdev->dev;
+		drvdata->ncb = iommu_dev->ncb;
+		drvdata->ttbr_split = iommu_dev->ttbr_split;
+	} else {
+		ret = -ENODEV;
+		goto fail;
+	}
+
+	drvdata->dev = &pdev->dev;
+
+	ret = __get_clocks(pdev, drvdata);
+
+	if (ret)
+		goto fail;
+
+	__enable_clocks(drvdata);
+
+	msm_iommu_reset(drvdata->base, drvdata->glb_base, drvdata->ncb);
+
+	ret = iommu_sanity_check(drvdata);
+	if (ret)
+		goto fail_clk;
+
+	pr_info("device %s mapped at %p, with %d ctx banks\n",
+		drvdata->name, drvdata->base, drvdata->ncb);
+
+	msm_iommu_add_drv(drvdata);
+	platform_set_drvdata(pdev, drvdata);
+
+	__disable_clocks(drvdata);
+
+	pmon_info = msm_iommu_pm_alloc(&pdev->dev);
+	if (pmon_info != NULL) {
+		ret = msm_iommu_pmon_parse_dt(pdev, pmon_info);
+		if (ret) {
+			msm_iommu_pm_free(&pdev->dev);
+			pr_info("%s: pmon not available.\n", drvdata->name);
+		} else {
+			pmon_info->iommu.base = drvdata->base;
+			pmon_info->iommu.ops = &iommu_access_ops_v0;
+			pmon_info->iommu.hw_ops = iommu_pm_get_hw_ops_v0();
+			pmon_info->iommu.iommu_name = drvdata->name;
+			ret = msm_iommu_pm_iommu_register(pmon_info);
+			if (ret) {
+				pr_err("%s iommu register fail\n",
+								drvdata->name);
+				msm_iommu_pm_free(&pdev->dev);
+			} else {
+				pr_debug("%s iommu registered for pmon\n",
+						pmon_info->iommu.iommu_name);
+			}
+		}
+	}
+
+	return 0;
+
+fail_clk:
+	__disable_clocks(drvdata);
+	__put_clocks(drvdata);
+fail:
+	return ret;
+}
+
+static int msm_iommu_remove(struct platform_device *pdev)
+{
+	struct msm_iommu_drvdata *drv = NULL;
+
+	drv = platform_get_drvdata(pdev);
+	if (drv) {
+		msm_iommu_remove_drv(drv);
+		if (drv->clk)
+			clk_put(drv->clk);
+		clk_put(drv->pclk);
+		platform_set_drvdata(pdev, NULL);
+	}
+	return 0;
+}
+
+static int msm_iommu_ctx_parse_dt(struct platform_device *pdev,
+				struct msm_iommu_ctx_drvdata *ctx_drvdata)
+{
+	struct resource *r, rp;
+	int irq, ret;
+	u32 nmid_array_size;
+	u32 nmid;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq > 0) {
+		ret = request_threaded_irq(irq, NULL,
+				msm_iommu_fault_handler,
+				IRQF_ONESHOT | IRQF_SHARED,
+				"msm_iommu_nonsecure_irq", ctx_drvdata);
+		if (ret) {
+			pr_err("Request IRQ %d failed with ret=%d\n", irq, ret);
+			return ret;
+		}
+	}
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!r) {
+		pr_err("Could not find reg property for context bank\n");
+		return -EINVAL;
+	}
+
+	ret = of_address_to_resource(pdev->dev.parent->of_node, 0, &rp);
+	if (ret) {
+		pr_err("of_address_to_resource failed\n");
+		return -EINVAL;
+	}
+
+	/* Calculate the context bank number using the base addresses. CB0
+	 * starts at the base address.
+	 */
+	ctx_drvdata->num = ((r->start - rp.start) >> CTX_SHIFT);
+
+	if (of_property_read_string(pdev->dev.of_node, "label",
+					&ctx_drvdata->name)) {
+		pr_err("Could not find label property\n");
+		return -EINVAL;
+	}
+
+	if (!of_get_property(pdev->dev.of_node, "qcom,iommu-ctx-mids",
+			     &nmid_array_size)) {
+		pr_err("Could not find iommu-ctx-mids property\n");
+		return -EINVAL;
+	}
+	if (nmid_array_size >= sizeof(ctx_drvdata->sids)) {
+		pr_err("Too many mids defined - array size: %u, mids size: %u\n",
+			nmid_array_size, sizeof(ctx_drvdata->sids));
+		return -EINVAL;
+	}
+	nmid = nmid_array_size / sizeof(*ctx_drvdata->sids);
+
+	if (of_property_read_u32_array(pdev->dev.of_node, "qcom,iommu-ctx-mids",
+				       ctx_drvdata->sids, nmid)) {
+		pr_err("Could not find iommu-ctx-mids property\n");
+		return -EINVAL;
+	}
+	ctx_drvdata->nsid = nmid;
+
+	return 0;
+}
+
+static void __program_m2v_tables(struct msm_iommu_drvdata *drvdata,
+				struct msm_iommu_ctx_drvdata *ctx_drvdata)
+{
+	int i;
+
+	/* Program the M2V tables for this context */
+	for (i = 0; i < ctx_drvdata->nsid; i++) {
+		int sid = ctx_drvdata->sids[i];
+		int num = ctx_drvdata->num;
+
+		SET_M2VCBR_N(drvdata->glb_base, sid, 0);
+		SET_CBACR_N(drvdata->glb_base, num, 0);
+
+		/* Route page faults to the non-secure interrupt */
+		SET_IRPTNDX(drvdata->glb_base, num, 1);
+
+		/* Set VMID = 0 */
+		SET_VMID(drvdata->glb_base, sid, 0);
+
+		/* Set the context number for that SID to this context */
+		SET_CBNDX(drvdata->glb_base, sid, num);
+
+		/* Set SID associated with this context bank to 0 */
+		SET_CBVMID(drvdata->glb_base, num, 0);
+
+		/* Set the ASID for TLB tagging for this context to 0 */
+		SET_CONTEXTIDR_ASID(drvdata->base, num, 0);
+
+		/* Set security bit override to be Non-secure */
+		SET_NSCFG(drvdata->glb_base, sid, 3);
+	}
+	mb();
+}
+
+static int msm_iommu_ctx_probe(struct platform_device *pdev)
+{
+	struct msm_iommu_drvdata *drvdata;
+	struct msm_iommu_ctx_drvdata *ctx_drvdata = NULL;
+	int i, ret, irq;
+	if (!pdev->dev.parent) {
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	drvdata = dev_get_drvdata(pdev->dev.parent);
+
+	if (!drvdata) {
+		ret = -ENODEV;
+		goto fail;
+	}
+
+	ctx_drvdata = devm_kzalloc(&pdev->dev, sizeof(*ctx_drvdata),
+					GFP_KERNEL);
+	if (!ctx_drvdata) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	ctx_drvdata->pdev = pdev;
+	INIT_LIST_HEAD(&ctx_drvdata->attached_elm);
+	platform_set_drvdata(pdev, ctx_drvdata);
+	ctx_drvdata->attach_count = 0;
+
+	if (pdev->dev.of_node) {
+		ret = msm_iommu_ctx_parse_dt(pdev, ctx_drvdata);
+		if (ret)
+			goto fail;
+	} else if (pdev->dev.platform_data) {
+		struct msm_iommu_ctx_dev *c = pdev->dev.platform_data;
+
+		ctx_drvdata->num = c->num;
+		ctx_drvdata->name = c->name;
+
+		for (i = 0;  i < MAX_NUM_MIDS; ++i) {
+			if (c->mids[i] == -1) {
+				ctx_drvdata->nsid = i;
+				break;
+			}
+			ctx_drvdata->sids[i] = c->mids[i];
+		}
+		irq = platform_get_irq_byname(
+					to_platform_device(pdev->dev.parent),
+					"nonsecure_irq");
+		if (irq < 0) {
+			ret = -ENODEV;
+			goto fail;
+		}
+
+		ret = request_threaded_irq(irq, NULL, msm_iommu_fault_handler,
+					IRQF_ONESHOT | IRQF_SHARED,
+					"msm_iommu_nonsecure_irq", ctx_drvdata);
+
+		if (ret) {
+			pr_err("request_threaded_irq %d failed: %d\n", irq,
+								       ret);
+			goto fail;
+		}
+	} else {
+		ret = -ENODEV;
+		goto fail;
+	}
+
+	__enable_clocks(drvdata);
+	__program_m2v_tables(drvdata, ctx_drvdata);
+	__disable_clocks(drvdata);
+
+	dev_info(&pdev->dev, "context %s using bank %d\n", ctx_drvdata->name,
+							   ctx_drvdata->num);
+	return 0;
+fail:
+	return ret;
+}
+
+static int __devexit msm_iommu_ctx_remove(struct platform_device *pdev)
+{
+	platform_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+
+static struct of_device_id msm_iommu_match_table[] = {
+	{ .compatible = "qcom,msm-smmu-v0", },
+	{}
+};
+
+static struct platform_driver msm_iommu_driver = {
+	.driver = {
+		.name	= "msm_iommu-v0",
+		.of_match_table = msm_iommu_match_table,
+	},
+	.probe		= msm_iommu_probe,
+	.remove		= __devexit_p(msm_iommu_remove),
+};
+
+static struct of_device_id msm_iommu_ctx_match_table[] = {
+	{ .name = "qcom,iommu-ctx", },
+	{}
+};
+
+static struct platform_driver msm_iommu_ctx_driver = {
+	.driver = {
+		.name	= "msm_iommu_ctx",
+		.of_match_table = msm_iommu_ctx_match_table,
+	},
+	.probe		= msm_iommu_ctx_probe,
+	.remove		= __devexit_p(msm_iommu_ctx_remove),
+};
+
+static int __init msm_iommu_driver_init(void)
+{
+	int ret;
+	ret = platform_driver_register(&msm_iommu_driver);
+	if (ret != 0) {
+		pr_err("Failed to register IOMMU driver\n");
+		goto error;
+	}
+
+	ret = platform_driver_register(&msm_iommu_ctx_driver);
+	if (ret != 0) {
+		pr_err("Failed to register IOMMU context driver\n");
+		goto error;
+	}
+
+error:
+	return ret;
+}
+
+static void __exit msm_iommu_driver_exit(void)
+{
+	platform_driver_unregister(&msm_iommu_ctx_driver);
+	platform_driver_unregister(&msm_iommu_driver);
+}
+
+subsys_initcall(msm_iommu_driver_init);
+module_exit(msm_iommu_driver_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");
diff --git a/drivers/iommu/msm_iommu_dev-v1.c b/drivers/iommu/msm_iommu_dev-v1.c
new file mode 100644
index 0000000..3f9f1c4
--- /dev/null
+++ b/drivers/iommu/msm_iommu_dev-v1.c
@@ -0,0 +1,451 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/iommu.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+
+#include <mach/iommu_hw-v1.h>
+#include <mach/iommu.h>
+#include <mach/iommu_perfmon.h>
+
+static int msm_iommu_parse_bfb_settings(struct platform_device *pdev,
+				    struct msm_iommu_drvdata *drvdata)
+{
+	struct msm_iommu_bfb_settings *bfb_settings;
+	u32 nreg, nval;
+	int ret;
+
+	/*
+	 * It is not valid for a device to have the qcom,iommu-bfb-regs
+	 * property but not the qcom,iommu-bfb-data property, and vice versa.
+	 */
+	if (!of_get_property(pdev->dev.of_node, "qcom,iommu-bfb-regs", &nreg)) {
+		if (of_get_property(pdev->dev.of_node, "qcom,iommu-bfb-data",
+				    &nval))
+			return -EINVAL;
+		return 0;
+	}
+
+	if (!of_get_property(pdev->dev.of_node, "qcom,iommu-bfb-data", &nval))
+		return -EINVAL;
+
+	if (nreg >= sizeof(bfb_settings->regs))
+		return -EINVAL;
+
+	if (nval >= sizeof(bfb_settings->data))
+		return -EINVAL;
+
+	if (nval != nreg)
+		return -EINVAL;
+
+	bfb_settings = devm_kzalloc(&pdev->dev, sizeof(*bfb_settings),
+				    GFP_KERNEL);
+	if (!bfb_settings)
+		return -ENOMEM;
+
+	ret = of_property_read_u32_array(pdev->dev.of_node,
+					 "qcom,iommu-bfb-regs",
+					 bfb_settings->regs,
+					 nreg / sizeof(*bfb_settings->regs));
+	if (ret)
+		return ret;
+
+	ret = of_property_read_u32_array(pdev->dev.of_node,
+					 "qcom,iommu-bfb-data",
+					 bfb_settings->data,
+					 nval / sizeof(*bfb_settings->data));
+	if (ret)
+		return ret;
+
+	bfb_settings->length = nreg / sizeof(*bfb_settings->regs);
+
+	drvdata->bfb_settings = bfb_settings;
+	return 0;
+}
+
+static int msm_iommu_parse_dt(struct platform_device *pdev,
+				struct msm_iommu_drvdata *drvdata)
+{
+	struct device_node *child;
+	int ret = 0;
+	struct resource *r;
+
+	drvdata->dev = &pdev->dev;
+	msm_iommu_add_drv(drvdata);
+
+	ret = msm_iommu_parse_bfb_settings(pdev, drvdata);
+	if (ret)
+		goto fail;
+
+	for_each_child_of_node(pdev->dev.of_node, child) {
+		drvdata->ncb++;
+		if (!of_platform_device_create(child, NULL, &pdev->dev))
+			pr_err("Failed to create %s device\n", child->name);
+	}
+
+	ret = of_property_read_string(pdev->dev.of_node, "label",
+				      &drvdata->name);
+	if (ret)
+		goto fail;
+
+	drvdata->sec_id = -1;
+	of_property_read_u32(pdev->dev.of_node, "qcom,iommu-secure-id",
+				&drvdata->sec_id);
+
+	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "clk_base");
+	if (r) {
+		drvdata->clk_reg_virt = devm_ioremap(&pdev->dev, r->start,
+						     resource_size(r));
+		if (!drvdata->clk_reg_virt) {
+			pr_err("Failed to map resource for iommu clk: %pr\n",
+				r);
+			ret = -ENOMEM;
+			goto fail;
+		}
+	}
+
+	drvdata->halt_enabled = of_property_read_bool(pdev->dev.of_node,
+						      "qcom,iommu-enable-halt");
+
+	return 0;
+fail:
+	return ret;
+}
+
+static int msm_iommu_pmon_parse_dt(struct platform_device *pdev,
+					struct iommu_pmon *pmon_info)
+{
+	int ret = 0;
+	int irq = platform_get_irq(pdev, 0);
+	unsigned int cls_prop_size;
+
+	if (irq > 0) {
+		pmon_info->iommu.evt_irq = platform_get_irq(pdev, 0);
+
+		ret = of_property_read_u32(pdev->dev.of_node,
+					   "qcom,iommu-pmu-ngroups",
+					   &pmon_info->num_groups);
+		if (ret) {
+			pr_err("Error reading qcom,iommu-pmu-ngroups\n");
+			goto fail;
+		}
+		ret = of_property_read_u32(pdev->dev.of_node,
+					   "qcom,iommu-pmu-ncounters",
+					   &pmon_info->num_counters);
+		if (ret) {
+			pr_err("Error reading qcom,iommu-pmu-ncounters\n");
+			goto fail;
+		}
+
+		if (!of_get_property(pdev->dev.of_node,
+				     "qcom,iommu-pmu-event-classes",
+				     &cls_prop_size)) {
+			pr_err("Error reading qcom,iommu-pmu-event-classes\n");
+			return -EINVAL;
+		}
+
+		pmon_info->event_cls_supported =
+			   devm_kzalloc(&pdev->dev, cls_prop_size, GFP_KERNEL);
+
+		if (!pmon_info->event_cls_supported) {
+			pr_err("Unable to get memory for event class array\n");
+			return -ENOMEM;
+		}
+
+		pmon_info->nevent_cls_supported = cls_prop_size / sizeof(u32);
+
+		ret = of_property_read_u32_array(pdev->dev.of_node,
+					"qcom,iommu-pmu-event-classes",
+					pmon_info->event_cls_supported,
+					pmon_info->nevent_cls_supported);
+		if (ret) {
+			pr_err("Error reading qcom,iommu-pmu-event-classes\n");
+			return ret;
+		}
+	} else {
+		pmon_info->iommu.evt_irq = -1;
+		ret = irq;
+	}
+
+fail:
+	return ret;
+}
+
+static int __devinit msm_iommu_probe(struct platform_device *pdev)
+{
+	struct iommu_pmon *pmon_info;
+	struct msm_iommu_drvdata *drvdata;
+	struct resource *r;
+	int ret, needs_alt_core_clk;
+
+	drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata)
+		return -ENOMEM;
+
+	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iommu_base");
+	if (!r)
+		return -EINVAL;
+
+	drvdata->base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
+	if (!drvdata->base)
+		return -ENOMEM;
+
+	drvdata->glb_base = drvdata->base;
+
+	drvdata->gdsc = devm_regulator_get(&pdev->dev, "vdd");
+	if (IS_ERR(drvdata->gdsc))
+		return -EINVAL;
+
+	drvdata->alt_gdsc = devm_regulator_get(&pdev->dev, "qcom,alt-vdd");
+	if (IS_ERR(drvdata->alt_gdsc))
+		drvdata->alt_gdsc = NULL;
+
+	drvdata->pclk = devm_clk_get(&pdev->dev, "iface_clk");
+	if (IS_ERR(drvdata->pclk))
+		return PTR_ERR(drvdata->pclk);
+
+	drvdata->clk = devm_clk_get(&pdev->dev, "core_clk");
+	if (IS_ERR(drvdata->clk))
+		return PTR_ERR(drvdata->clk);
+
+	needs_alt_core_clk = of_property_read_bool(pdev->dev.of_node,
+						   "qcom,needs-alt-core-clk");
+	if (needs_alt_core_clk) {
+		drvdata->aclk = devm_clk_get(&pdev->dev, "alt_core_clk");
+		if (IS_ERR(drvdata->aclk))
+			return PTR_ERR(drvdata->aclk);
+	}
+
+	if (clk_get_rate(drvdata->clk) == 0) {
+		ret = clk_round_rate(drvdata->clk, 1000);
+		clk_set_rate(drvdata->clk, ret);
+	}
+
+	if (drvdata->aclk && clk_get_rate(drvdata->aclk) == 0) {
+		ret = clk_round_rate(drvdata->aclk, 1000);
+		clk_set_rate(drvdata->aclk, ret);
+	}
+
+	ret = msm_iommu_parse_dt(pdev, drvdata);
+	if (ret)
+		return ret;
+
+	dev_info(&pdev->dev, "device %s mapped at %p, with %d ctx banks\n",
+		drvdata->name, drvdata->base, drvdata->ncb);
+
+	platform_set_drvdata(pdev, drvdata);
+
+	pmon_info = msm_iommu_pm_alloc(&pdev->dev);
+	if (pmon_info != NULL) {
+		ret = msm_iommu_pmon_parse_dt(pdev, pmon_info);
+		if (ret) {
+			msm_iommu_pm_free(&pdev->dev);
+			pr_info("%s: pmon not available.\n", drvdata->name);
+		} else {
+			pmon_info->iommu.base = drvdata->base;
+			pmon_info->iommu.ops = &iommu_access_ops_v1;
+			pmon_info->iommu.hw_ops = iommu_pm_get_hw_ops_v1();
+			pmon_info->iommu.iommu_name = drvdata->name;
+			ret = msm_iommu_pm_iommu_register(pmon_info);
+			if (ret) {
+				pr_err("%s iommu register fail\n",
+								drvdata->name);
+				msm_iommu_pm_free(&pdev->dev);
+			} else {
+				pr_debug("%s iommu registered for pmon\n",
+						pmon_info->iommu.iommu_name);
+			}
+		}
+	}
+	return 0;
+}
+
+static int __devexit msm_iommu_remove(struct platform_device *pdev)
+{
+	struct msm_iommu_drvdata *drv = NULL;
+
+	msm_iommu_pm_iommu_unregister(&pdev->dev);
+	msm_iommu_pm_free(&pdev->dev);
+
+	drv = platform_get_drvdata(pdev);
+	if (drv) {
+		msm_iommu_remove_drv(drv);
+		if (drv->clk)
+			clk_put(drv->clk);
+		clk_put(drv->pclk);
+		platform_set_drvdata(pdev, NULL);
+	}
+	return 0;
+}
+
+static int msm_iommu_ctx_parse_dt(struct platform_device *pdev,
+				struct msm_iommu_ctx_drvdata *ctx_drvdata)
+{
+	struct resource *r, rp;
+	int irq, ret;
+	u32 nsid;
+
+	ctx_drvdata->secure_context = of_property_read_bool(pdev->dev.of_node,
+							"qcom,secure-context");
+
+	if (!ctx_drvdata->secure_context) {
+		irq = platform_get_irq(pdev, 0);
+		if (irq > 0) {
+			ret = request_threaded_irq(irq, NULL,
+					msm_iommu_fault_handler_v2,
+					IRQF_ONESHOT | IRQF_SHARED,
+					"msm_iommu_nonsecure_irq", pdev);
+			if (ret) {
+				pr_err("Request IRQ %d failed with ret=%d\n",
+					irq, ret);
+				return ret;
+			}
+		}
+	}
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!r)
+		return -EINVAL;
+
+	ret = of_address_to_resource(pdev->dev.parent->of_node, 0, &rp);
+	if (ret)
+		return -EINVAL;
+
+	/* Calculate the context bank number using the base addresses. The
+	 * first 8 pages belong to the global address space which is followed
+	 * by the context banks, hence subtract by 8 to get the context bank
+	 * number.
+	 */
+	ctx_drvdata->num = ((r->start - rp.start) >> CTX_SHIFT) - 8;
+
+	if (of_property_read_string(pdev->dev.of_node, "label",
+					&ctx_drvdata->name))
+		ctx_drvdata->name = dev_name(&pdev->dev);
+
+	if (!of_get_property(pdev->dev.of_node, "qcom,iommu-ctx-sids", &nsid))
+		return -EINVAL;
+
+	if (nsid >= sizeof(ctx_drvdata->sids))
+		return -EINVAL;
+
+	if (of_property_read_u32_array(pdev->dev.of_node, "qcom,iommu-ctx-sids",
+				       ctx_drvdata->sids,
+				       nsid / sizeof(*ctx_drvdata->sids))) {
+		return -EINVAL;
+	}
+	ctx_drvdata->nsid = nsid;
+
+	ctx_drvdata->asid = -1;
+	return 0;
+}
+
+static int __devinit msm_iommu_ctx_probe(struct platform_device *pdev)
+{
+	struct msm_iommu_ctx_drvdata *ctx_drvdata = NULL;
+	int ret;
+
+	if (!pdev->dev.parent)
+		return -EINVAL;
+
+	ctx_drvdata = devm_kzalloc(&pdev->dev, sizeof(*ctx_drvdata),
+					GFP_KERNEL);
+	if (!ctx_drvdata)
+		return -ENOMEM;
+
+	ctx_drvdata->pdev = pdev;
+	INIT_LIST_HEAD(&ctx_drvdata->attached_elm);
+	platform_set_drvdata(pdev, ctx_drvdata);
+
+	ret = msm_iommu_ctx_parse_dt(pdev, ctx_drvdata);
+	if (!ret)
+		dev_info(&pdev->dev, "context %s using bank %d\n",
+			 ctx_drvdata->name, ctx_drvdata->num);
+
+	return ret;
+}
+
+static int __devexit msm_iommu_ctx_remove(struct platform_device *pdev)
+{
+	platform_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+static struct of_device_id msm_iommu_match_table[] = {
+	{ .compatible = "qcom,msm-smmu-v1", },
+	{}
+};
+
+static struct platform_driver msm_iommu_driver = {
+	.driver = {
+		.name	= "msm_iommu_v1",
+		.of_match_table = msm_iommu_match_table,
+	},
+	.probe		= msm_iommu_probe,
+	.remove		= __devexit_p(msm_iommu_remove),
+};
+
+static struct of_device_id msm_iommu_ctx_match_table[] = {
+	{ .name = "qcom,iommu-ctx", },
+	{}
+};
+
+static struct platform_driver msm_iommu_ctx_driver = {
+	.driver = {
+		.name	= "msm_iommu_ctx_v1",
+		.of_match_table = msm_iommu_ctx_match_table,
+	},
+	.probe		= msm_iommu_ctx_probe,
+	.remove		= __devexit_p(msm_iommu_ctx_remove),
+};
+
+static int __init msm_iommu_driver_init(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&msm_iommu_driver);
+	if (ret != 0) {
+		pr_err("Failed to register IOMMU driver\n");
+		goto error;
+	}
+
+	ret = platform_driver_register(&msm_iommu_ctx_driver);
+	if (ret != 0) {
+		pr_err("Failed to register IOMMU context driver\n");
+		goto error;
+	}
+
+error:
+	return ret;
+}
+
+static void __exit msm_iommu_driver_exit(void)
+{
+	platform_driver_unregister(&msm_iommu_ctx_driver);
+	platform_driver_unregister(&msm_iommu_driver);
+}
+
+subsys_initcall(msm_iommu_driver_init);
+module_exit(msm_iommu_driver_exit);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iommu/msm_iommu_dev-v2.c b/drivers/iommu/msm_iommu_dev-v2.c
deleted file mode 100644
index cf30500..0000000
--- a/drivers/iommu/msm_iommu_dev-v2.c
+++ /dev/null
@@ -1,338 +0,0 @@
-/* Copyright (c) 2012 The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/clk.h>
-#include <linux/iommu.h>
-#include <linux/interrupt.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_device.h>
-
-#include <mach/iommu_hw-v2.h>
-#include <mach/iommu.h>
-
-static int msm_iommu_parse_bfb_settings(struct platform_device *pdev,
-				    struct msm_iommu_drvdata *drvdata)
-{
-	struct msm_iommu_bfb_settings *bfb_settings;
-	u32 nreg, nval;
-	int ret, i;
-
-	/*
-	 * It is not valid for a device to have the qcom,iommu-bfb-regs
-	 * property but not the qcom,iommu-bfb-data property, and vice versa.
-	 */
-	if (!of_get_property(pdev->dev.of_node, "qcom,iommu-bfb-regs", &nreg)) {
-		if (of_get_property(pdev->dev.of_node, "qcom,iommu-bfb-data",
-				    &nval))
-			return -EINVAL;
-		return 0;
-	}
-
-	if (!of_get_property(pdev->dev.of_node, "qcom,iommu-bfb-data", &nval))
-		return -EINVAL;
-
-	if (nreg >= sizeof(bfb_settings->regs))
-		return -EINVAL;
-
-	if (nval >= sizeof(bfb_settings->data))
-		return -EINVAL;
-
-	if (nval != nreg)
-		return -EINVAL;
-
-	bfb_settings = devm_kzalloc(&pdev->dev, sizeof(*bfb_settings),
-				    GFP_KERNEL);
-	if (!bfb_settings)
-		return -ENOMEM;
-
-	ret = of_property_read_u32_array(pdev->dev.of_node,
-					 "qcom,iommu-bfb-regs",
-					 bfb_settings->regs,
-					 nreg / sizeof(*bfb_settings->regs));
-	if (ret)
-		return ret;
-
-	ret = of_property_read_u32_array(pdev->dev.of_node,
-					 "qcom,iommu-bfb-data",
-					 bfb_settings->data,
-					 nval / sizeof(*bfb_settings->data));
-	if (ret)
-		return ret;
-
-	bfb_settings->length = nreg / sizeof(*bfb_settings->regs);
-
-	for (i = 0; i < bfb_settings->length; i++)
-		if (bfb_settings->regs[i] < IMPLDEF_OFFSET ||
-		    bfb_settings->regs[i] >= IMPLDEF_OFFSET + IMPLDEF_LENGTH)
-			return -EINVAL;
-
-	drvdata->bfb_settings = bfb_settings;
-	return 0;
-}
-
-static int msm_iommu_parse_dt(struct platform_device *pdev,
-				struct msm_iommu_drvdata *drvdata)
-{
-	struct device_node *child;
-	int ret = 0;
-
-	drvdata->dev = &pdev->dev;
-	msm_iommu_add_drv(drvdata);
-
-	ret = msm_iommu_parse_bfb_settings(pdev, drvdata);
-	if (ret)
-		goto fail;
-
-	for_each_child_of_node(pdev->dev.of_node, child) {
-		drvdata->ncb++;
-		if (!of_platform_device_create(child, NULL, &pdev->dev))
-			pr_err("Failed to create %s device\n", child->name);
-	}
-
-	drvdata->name = dev_name(&pdev->dev);
-	drvdata->sec_id = -1;
-	of_property_read_u32(pdev->dev.of_node, "qcom,iommu-secure-id",
-				&drvdata->sec_id);
-	return 0;
-fail:
-	return ret;
-}
-
-static int __devinit msm_iommu_probe(struct platform_device *pdev)
-{
-	struct msm_iommu_drvdata *drvdata;
-	struct resource *r;
-	int ret, needs_alt_core_clk;
-
-	drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
-	if (!drvdata)
-		return -ENOMEM;
-
-	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!r)
-		return -EINVAL;
-
-	drvdata->base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
-	if (!drvdata->base)
-		return -ENOMEM;
-
-	drvdata->glb_base = drvdata->base;
-
-	drvdata->gdsc = devm_regulator_get(&pdev->dev, "vdd");
-	if (IS_ERR(drvdata->gdsc))
-		return -EINVAL;
-
-	drvdata->pclk = devm_clk_get(&pdev->dev, "iface_clk");
-	if (IS_ERR(drvdata->pclk))
-		return PTR_ERR(drvdata->pclk);
-
-	drvdata->clk = devm_clk_get(&pdev->dev, "core_clk");
-	if (IS_ERR(drvdata->clk))
-		return PTR_ERR(drvdata->clk);
-
-	needs_alt_core_clk = of_property_read_bool(pdev->dev.of_node,
-						   "qcom,needs-alt-core-clk");
-	if (needs_alt_core_clk) {
-		drvdata->aclk = devm_clk_get(&pdev->dev, "alt_core_clk");
-		if (IS_ERR(drvdata->aclk))
-			return PTR_ERR(drvdata->aclk);
-	}
-
-	if (clk_get_rate(drvdata->clk) == 0) {
-		ret = clk_round_rate(drvdata->clk, 1);
-		clk_set_rate(drvdata->clk, ret);
-	}
-
-	if (drvdata->aclk && clk_get_rate(drvdata->aclk) == 0) {
-		ret = clk_round_rate(drvdata->aclk, 1);
-		clk_set_rate(drvdata->aclk, ret);
-	}
-
-	ret = msm_iommu_parse_dt(pdev, drvdata);
-	if (ret)
-		return ret;
-
-	pr_info("device %s mapped at %p, with %d ctx banks\n",
-		drvdata->name, drvdata->base, drvdata->ncb);
-
-	platform_set_drvdata(pdev, drvdata);
-
-	return 0;
-}
-
-static int __devexit msm_iommu_remove(struct platform_device *pdev)
-{
-	struct msm_iommu_drvdata *drv = NULL;
-
-	drv = platform_get_drvdata(pdev);
-	if (drv) {
-		msm_iommu_remove_drv(drv);
-		if (drv->clk)
-			clk_put(drv->clk);
-		clk_put(drv->pclk);
-		platform_set_drvdata(pdev, NULL);
-	}
-	return 0;
-}
-
-static int msm_iommu_ctx_parse_dt(struct platform_device *pdev,
-				struct msm_iommu_ctx_drvdata *ctx_drvdata)
-{
-	struct resource *r, rp;
-	int irq, ret;
-	u32 nsid;
-
-	irq = platform_get_irq(pdev, 0);
-	if (irq > 0) {
-		ret = request_threaded_irq(irq, NULL,
-				msm_iommu_fault_handler_v2,
-				IRQF_ONESHOT | IRQF_SHARED,
-				"msm_iommu_nonsecure_irq", pdev);
-		if (ret) {
-			pr_err("Request IRQ %d failed with ret=%d\n", irq, ret);
-			return ret;
-		}
-	}
-
-	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!r)
-		return -EINVAL;
-
-	ret = of_address_to_resource(pdev->dev.parent->of_node, 0, &rp);
-	if (ret)
-		return -EINVAL;
-
-	/* Calculate the context bank number using the base addresses. The
-	 * first 8 pages belong to the global address space which is followed
-	 * by the context banks, hence subtract by 8 to get the context bank
-	 * number.
-	 */
-	ctx_drvdata->num = ((r->start - rp.start) >> CTX_SHIFT) - 8;
-
-	if (of_property_read_string(pdev->dev.of_node, "label",
-					&ctx_drvdata->name))
-		ctx_drvdata->name = dev_name(&pdev->dev);
-
-	if (!of_get_property(pdev->dev.of_node, "qcom,iommu-ctx-sids", &nsid))
-		return -EINVAL;
-
-	if (nsid >= sizeof(ctx_drvdata->sids))
-		return -EINVAL;
-
-	if (of_property_read_u32_array(pdev->dev.of_node, "qcom,iommu-ctx-sids",
-				       ctx_drvdata->sids,
-				       nsid / sizeof(*ctx_drvdata->sids))) {
-		return -EINVAL;
-	}
-	ctx_drvdata->nsid = nsid;
-
-	return 0;
-}
-
-static int __devinit msm_iommu_ctx_probe(struct platform_device *pdev)
-{
-	struct msm_iommu_ctx_drvdata *ctx_drvdata = NULL;
-	int ret;
-
-	if (!pdev->dev.parent)
-		return -EINVAL;
-
-	ctx_drvdata = devm_kzalloc(&pdev->dev, sizeof(*ctx_drvdata),
-					GFP_KERNEL);
-	if (!ctx_drvdata)
-		return -ENOMEM;
-
-	ctx_drvdata->pdev = pdev;
-	INIT_LIST_HEAD(&ctx_drvdata->attached_elm);
-	platform_set_drvdata(pdev, ctx_drvdata);
-
-	ret = msm_iommu_ctx_parse_dt(pdev, ctx_drvdata);
-	if (!ret)
-		dev_info(&pdev->dev, "context %s using bank %d\n",
-			 ctx_drvdata->name, ctx_drvdata->num);
-
-	return ret;
-}
-
-static int __devexit msm_iommu_ctx_remove(struct platform_device *pdev)
-{
-	platform_set_drvdata(pdev, NULL);
-	return 0;
-}
-
-static struct of_device_id msm_iommu_match_table[] = {
-	{ .compatible = "qcom,msm-smmu-v2", },
-	{}
-};
-
-static struct platform_driver msm_iommu_driver = {
-	.driver = {
-		.name	= "msm_iommu_v2",
-		.of_match_table = msm_iommu_match_table,
-	},
-	.probe		= msm_iommu_probe,
-	.remove		= __devexit_p(msm_iommu_remove),
-};
-
-static struct of_device_id msm_iommu_ctx_match_table[] = {
-	{ .name = "qcom,iommu-ctx", },
-	{}
-};
-
-static struct platform_driver msm_iommu_ctx_driver = {
-	.driver = {
-		.name	= "msm_iommu_ctx_v2",
-		.of_match_table = msm_iommu_ctx_match_table,
-	},
-	.probe		= msm_iommu_ctx_probe,
-	.remove		= __devexit_p(msm_iommu_ctx_remove),
-};
-
-static int __init msm_iommu_driver_init(void)
-{
-	int ret;
-
-	ret = platform_driver_register(&msm_iommu_driver);
-	if (ret != 0) {
-		pr_err("Failed to register IOMMU driver\n");
-		goto error;
-	}
-
-	ret = platform_driver_register(&msm_iommu_ctx_driver);
-	if (ret != 0) {
-		pr_err("Failed to register IOMMU context driver\n");
-		goto error;
-	}
-
-error:
-	return ret;
-}
-
-static void __exit msm_iommu_driver_exit(void)
-{
-	platform_driver_unregister(&msm_iommu_ctx_driver);
-	platform_driver_unregister(&msm_iommu_driver);
-}
-
-subsys_initcall(msm_iommu_driver_init);
-module_exit(msm_iommu_driver_exit);
-
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/iommu/msm_iommu_dev.c b/drivers/iommu/msm_iommu_dev.c
deleted file mode 100644
index 44fe454..0000000
--- a/drivers/iommu/msm_iommu_dev.c
+++ /dev/null
@@ -1,607 +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.
- */
-
-#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/clk.h>
-#include <linux/iommu.h>
-#include <linux/interrupt.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-#include <linux/list.h>
-#include <linux/mutex.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_device.h>
-
-#include <mach/iommu_hw-8xxx.h>
-#include <mach/iommu.h>
-
-static DEFINE_MUTEX(iommu_list_lock);
-static LIST_HEAD(iommu_list);
-
-void msm_iommu_add_drv(struct msm_iommu_drvdata *drv)
-{
-	mutex_lock(&iommu_list_lock);
-	list_add(&drv->list, &iommu_list);
-	mutex_unlock(&iommu_list_lock);
-}
-
-void msm_iommu_remove_drv(struct msm_iommu_drvdata *drv)
-{
-	mutex_lock(&iommu_list_lock);
-	list_del(&drv->list);
-	mutex_unlock(&iommu_list_lock);
-}
-
-static int find_iommu_ctx(struct device *dev, void *data)
-{
-	struct msm_iommu_ctx_drvdata *c;
-
-	c = dev_get_drvdata(dev);
-	if (!c || !c->name)
-		return 0;
-
-	return !strcmp(data, c->name);
-}
-
-static struct device *find_context(struct device *dev, const char *name)
-{
-	return device_find_child(dev, (void *)name, find_iommu_ctx);
-}
-
-struct device *msm_iommu_get_ctx(const char *ctx_name)
-{
-	struct msm_iommu_drvdata *drv;
-	struct device *dev = NULL;
-
-	mutex_lock(&iommu_list_lock);
-	list_for_each_entry(drv, &iommu_list, list) {
-		dev = find_context(drv->dev, ctx_name);
-		if (dev)
-			break;
-	}
-	mutex_unlock(&iommu_list_lock);
-
-	if (!dev || !dev_get_drvdata(dev))
-		pr_err("Could not find context <%s>\n", ctx_name);
-	put_device(dev);
-
-	return dev;
-}
-EXPORT_SYMBOL(msm_iommu_get_ctx);
-
-static void msm_iommu_reset(void __iomem *base, void __iomem *glb_base, int ncb)
-{
-	int ctx;
-
-	SET_RPUE(glb_base, 0);
-	SET_RPUEIE(glb_base, 0);
-	SET_ESRRESTORE(glb_base, 0);
-	SET_TBE(glb_base, 0);
-	SET_CR(glb_base, 0);
-	SET_SPDMBE(glb_base, 0);
-	SET_TESTBUSCR(glb_base, 0);
-	SET_TLBRSW(glb_base, 0);
-	SET_GLOBAL_TLBIALL(glb_base, 0);
-	SET_RPU_ACR(glb_base, 0);
-	SET_TLBLKCRWE(glb_base, 1);
-
-	for (ctx = 0; ctx < ncb; ctx++) {
-		SET_BPRCOSH(glb_base, ctx, 0);
-		SET_BPRCISH(glb_base, ctx, 0);
-		SET_BPRCNSH(glb_base, ctx, 0);
-		SET_BPSHCFG(glb_base, ctx, 0);
-		SET_BPMTCFG(glb_base, ctx, 0);
-		SET_ACTLR(base, ctx, 0);
-		SET_SCTLR(base, ctx, 0);
-		SET_FSRRESTORE(base, ctx, 0);
-		SET_TTBR0(base, ctx, 0);
-		SET_TTBR1(base, ctx, 0);
-		SET_TTBCR(base, ctx, 0);
-		SET_BFBCR(base, ctx, 0);
-		SET_PAR(base, ctx, 0);
-		SET_FAR(base, ctx, 0);
-		SET_TLBFLPTER(base, ctx, 0);
-		SET_TLBSLPTER(base, ctx, 0);
-		SET_TLBLKCR(base, ctx, 0);
-		SET_CTX_TLBIALL(base, ctx, 0);
-		SET_TLBIVA(base, ctx, 0);
-		SET_PRRR(base, ctx, 0);
-		SET_NMRR(base, ctx, 0);
-		SET_CONTEXTIDR(base, ctx, 0);
-	}
-	mb();
-}
-
-static int msm_iommu_parse_dt(struct platform_device *pdev,
-				struct msm_iommu_drvdata *drvdata)
-{
-#ifdef CONFIG_OF_DEVICE
-	struct device_node *child;
-	struct resource *r;
-	u32 glb_offset = 0;
-
-	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!r) {
-		pr_err("%s: Missing property reg\n", __func__);
-		return -EINVAL;
-	}
-	drvdata->base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
-	if (!drvdata->base) {
-		pr_err("%s: Unable to ioremap address %x size %x\n", __func__,
-			r->start, resource_size(r));
-		return -ENOMEM;
-	}
-	drvdata->glb_base = drvdata->base;
-
-	if (!of_property_read_u32(pdev->dev.of_node, "qcom,glb-offset",
-			&glb_offset)) {
-		drvdata->glb_base += glb_offset;
-	} else {
-		pr_err("%s: Missing property qcom,glb-offset\n", __func__);
-		return -EINVAL;
-	}
-
-	for_each_child_of_node(pdev->dev.of_node, child) {
-		drvdata->ncb++;
-		if (!of_platform_device_create(child, NULL, &pdev->dev))
-			pr_err("Failed to create %s device\n", child->name);
-	}
-
-	drvdata->name = dev_name(&pdev->dev);
-	drvdata->sec_id = -1;
-	drvdata->ttbr_split = 0;
-#endif
-	return 0;
-}
-
-static int __get_clocks(struct platform_device *pdev,
-				 struct msm_iommu_drvdata *drvdata)
-{
-	int ret = 0;
-
-	drvdata->pclk = clk_get(&pdev->dev, "iface_clk");
-	if (IS_ERR(drvdata->pclk)) {
-		ret = PTR_ERR(drvdata->pclk);
-		drvdata->pclk = NULL;
-		pr_err("Unable to get %s clock for %s IOMMU device\n",
-			dev_name(&pdev->dev), drvdata->name);
-		goto fail;
-	}
-
-	drvdata->clk = clk_get(&pdev->dev, "core_clk");
-
-	if (!IS_ERR(drvdata->clk)) {
-		if (clk_get_rate(drvdata->clk) == 0) {
-			ret = clk_round_rate(drvdata->clk, 1000);
-			clk_set_rate(drvdata->clk, ret);
-		}
-	} else {
-		drvdata->clk = NULL;
-	}
-	return 0;
-fail:
-	return ret;
-}
-
-static void __put_clocks(struct msm_iommu_drvdata *drvdata)
-{
-	if (drvdata->clk)
-		clk_put(drvdata->clk);
-	clk_put(drvdata->pclk);
-}
-
-static int __enable_clocks(struct msm_iommu_drvdata *drvdata)
-{
-	int ret;
-
-	ret = clk_prepare_enable(drvdata->pclk);
-	if (ret)
-		goto fail;
-
-	if (drvdata->clk) {
-		ret = clk_prepare_enable(drvdata->clk);
-		if (ret)
-			clk_disable_unprepare(drvdata->pclk);
-	}
-fail:
-	return ret;
-}
-
-static void __disable_clocks(struct msm_iommu_drvdata *drvdata)
-{
-	if (drvdata->clk)
-		clk_disable_unprepare(drvdata->clk);
-	clk_disable_unprepare(drvdata->pclk);
-}
-
-/*
- * Do a basic check of the IOMMU by performing an ATS operation
- * on context bank 0.
- */
-static int iommu_sanity_check(struct msm_iommu_drvdata *drvdata)
-{
-	int par;
-	int ret = 0;
-
-	SET_M(drvdata->base, 0, 1);
-	SET_PAR(drvdata->base, 0, 0);
-	SET_V2PCFG(drvdata->base, 0, 1);
-	SET_V2PPR(drvdata->base, 0, 0);
-	mb();
-	par = GET_PAR(drvdata->base, 0);
-	SET_V2PCFG(drvdata->base, 0, 0);
-	SET_M(drvdata->base, 0, 0);
-	mb();
-
-	if (!par) {
-		pr_err("%s: Invalid PAR value detected\n", drvdata->name);
-		ret = -ENODEV;
-	}
-	return ret;
-}
-
-static int msm_iommu_probe(struct platform_device *pdev)
-{
-	struct msm_iommu_drvdata *drvdata;
-	struct msm_iommu_dev *iommu_dev = pdev->dev.platform_data;
-	int ret;
-
-	drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
-
-	if (!drvdata) {
-		ret = -ENOMEM;
-		goto fail;
-	}
-
-	if (pdev->dev.of_node) {
-		ret = msm_iommu_parse_dt(pdev, drvdata);
-		if (ret)
-			goto fail;
-	} else if (pdev->dev.platform_data) {
-		struct resource *r, *r2;
-		resource_size_t	len;
-
-		r = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-						"physbase");
-
-		if (!r) {
-			ret = -ENODEV;
-			goto fail;
-		}
-
-		len = resource_size(r);
-
-		r2 = request_mem_region(r->start, len, r->name);
-		if (!r2) {
-			pr_err("Could not request memory region: start=%p, len=%d\n",
-							(void *) r->start, len);
-			ret = -EBUSY;
-			goto fail;
-		}
-
-		drvdata->base = devm_ioremap(&pdev->dev, r2->start, len);
-
-		if (!drvdata->base) {
-			pr_err("Could not ioremap: start=%p, len=%d\n",
-				 (void *) r2->start, len);
-			ret = -EBUSY;
-			goto fail;
-		}
-		/*
-		 * Global register space offset for legacy IOMMUv1 hardware
-		 * is always 0xFF000
-		 */
-		drvdata->glb_base = drvdata->base + 0xFF000;
-		drvdata->name = iommu_dev->name;
-		drvdata->dev = &pdev->dev;
-		drvdata->ncb = iommu_dev->ncb;
-		drvdata->ttbr_split = iommu_dev->ttbr_split;
-	} else {
-		ret = -ENODEV;
-		goto fail;
-	}
-
-	drvdata->dev = &pdev->dev;
-
-	ret = __get_clocks(pdev, drvdata);
-
-	if (ret)
-		goto fail;
-
-	__enable_clocks(drvdata);
-
-	msm_iommu_reset(drvdata->base, drvdata->glb_base, drvdata->ncb);
-
-	ret = iommu_sanity_check(drvdata);
-	if (ret)
-		goto fail_clk;
-
-	pr_info("device %s mapped at %p, with %d ctx banks\n",
-		drvdata->name, drvdata->base, drvdata->ncb);
-
-	msm_iommu_add_drv(drvdata);
-	platform_set_drvdata(pdev, drvdata);
-
-	__disable_clocks(drvdata);
-
-	return 0;
-
-fail_clk:
-	__disable_clocks(drvdata);
-	__put_clocks(drvdata);
-fail:
-	return ret;
-}
-
-static int msm_iommu_remove(struct platform_device *pdev)
-{
-	struct msm_iommu_drvdata *drv = NULL;
-
-	drv = platform_get_drvdata(pdev);
-	if (drv) {
-		msm_iommu_remove_drv(drv);
-		if (drv->clk)
-			clk_put(drv->clk);
-		clk_put(drv->pclk);
-		platform_set_drvdata(pdev, NULL);
-	}
-	return 0;
-}
-
-static int msm_iommu_ctx_parse_dt(struct platform_device *pdev,
-				struct msm_iommu_ctx_drvdata *ctx_drvdata)
-{
-	struct resource *r, rp;
-	int irq, ret;
-	u32 nmid_array_size;
-	u32 nmid;
-
-	irq = platform_get_irq(pdev, 0);
-	if (irq > 0) {
-		ret = request_threaded_irq(irq, NULL,
-				msm_iommu_fault_handler,
-				IRQF_ONESHOT | IRQF_SHARED,
-				"msm_iommu_nonsecure_irq", pdev);
-		if (ret) {
-			pr_err("Request IRQ %d failed with ret=%d\n", irq, ret);
-			return ret;
-		}
-	}
-
-	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!r) {
-		pr_err("Could not find reg property for context bank\n");
-		return -EINVAL;
-	}
-
-	ret = of_address_to_resource(pdev->dev.parent->of_node, 0, &rp);
-	if (ret) {
-		pr_err("of_address_to_resource failed\n");
-		return -EINVAL;
-	}
-
-	/* Calculate the context bank number using the base addresses. CB0
-	 * starts at the base address.
-	 */
-	ctx_drvdata->num = ((r->start - rp.start) >> CTX_SHIFT);
-
-	if (of_property_read_string(pdev->dev.of_node, "label",
-					&ctx_drvdata->name)) {
-		pr_err("Could not find label property\n");
-		return -EINVAL;
-	}
-
-	if (!of_get_property(pdev->dev.of_node, "qcom,iommu-ctx-mids",
-			     &nmid_array_size)) {
-		pr_err("Could not find iommu-ctx-mids property\n");
-		return -EINVAL;
-	}
-	if (nmid_array_size >= sizeof(ctx_drvdata->sids)) {
-		pr_err("Too many mids defined - array size: %u, mids size: %u\n",
-			nmid_array_size, sizeof(ctx_drvdata->sids));
-		return -EINVAL;
-	}
-	nmid = nmid_array_size / sizeof(*ctx_drvdata->sids);
-
-	if (of_property_read_u32_array(pdev->dev.of_node, "qcom,iommu-ctx-mids",
-				       ctx_drvdata->sids, nmid)) {
-		pr_err("Could not find iommu-ctx-mids property\n");
-		return -EINVAL;
-	}
-	ctx_drvdata->nsid = nmid;
-
-	return 0;
-}
-
-static void __program_m2v_tables(struct msm_iommu_drvdata *drvdata,
-				struct msm_iommu_ctx_drvdata *ctx_drvdata)
-{
-	int i;
-
-	/* Program the M2V tables for this context */
-	for (i = 0; i < ctx_drvdata->nsid; i++) {
-		int sid = ctx_drvdata->sids[i];
-		int num = ctx_drvdata->num;
-
-		SET_M2VCBR_N(drvdata->glb_base, sid, 0);
-		SET_CBACR_N(drvdata->glb_base, num, 0);
-
-		/* Route page faults to the non-secure interrupt */
-		SET_IRPTNDX(drvdata->glb_base, num, 1);
-
-		/* Set VMID = 0 */
-		SET_VMID(drvdata->glb_base, sid, 0);
-
-		/* Set the context number for that SID to this context */
-		SET_CBNDX(drvdata->glb_base, sid, num);
-
-		/* Set SID associated with this context bank to 0 */
-		SET_CBVMID(drvdata->glb_base, num, 0);
-
-		/* Set the ASID for TLB tagging for this context to 0 */
-		SET_CONTEXTIDR_ASID(drvdata->base, num, 0);
-
-		/* Set security bit override to be Non-secure */
-		SET_NSCFG(drvdata->glb_base, sid, 3);
-	}
-	mb();
-}
-
-static int msm_iommu_ctx_probe(struct platform_device *pdev)
-{
-	struct msm_iommu_drvdata *drvdata;
-	struct msm_iommu_ctx_drvdata *ctx_drvdata = NULL;
-	int i, ret, irq;
-	if (!pdev->dev.parent) {
-		ret = -EINVAL;
-		goto fail;
-	}
-
-	drvdata = dev_get_drvdata(pdev->dev.parent);
-
-	if (!drvdata) {
-		ret = -ENODEV;
-		goto fail;
-	}
-
-	ctx_drvdata = devm_kzalloc(&pdev->dev, sizeof(*ctx_drvdata),
-					GFP_KERNEL);
-	if (!ctx_drvdata) {
-		ret = -ENOMEM;
-		goto fail;
-	}
-
-	ctx_drvdata->pdev = pdev;
-	INIT_LIST_HEAD(&ctx_drvdata->attached_elm);
-	platform_set_drvdata(pdev, ctx_drvdata);
-
-	if (pdev->dev.of_node) {
-		ret = msm_iommu_ctx_parse_dt(pdev, ctx_drvdata);
-		if (ret)
-			goto fail;
-	} else if (pdev->dev.platform_data) {
-		struct msm_iommu_ctx_dev *c = pdev->dev.platform_data;
-
-		ctx_drvdata->num = c->num;
-		ctx_drvdata->name = c->name;
-
-		for (i = 0;  i < MAX_NUM_MIDS; ++i) {
-			if (c->mids[i] == -1) {
-				ctx_drvdata->nsid = i;
-				break;
-			}
-			ctx_drvdata->sids[i] = c->mids[i];
-		}
-		irq = platform_get_irq_byname(
-					to_platform_device(pdev->dev.parent),
-					"nonsecure_irq");
-		if (irq < 0) {
-			ret = -ENODEV;
-			goto fail;
-		}
-
-		ret = request_threaded_irq(irq, NULL, msm_iommu_fault_handler,
-					IRQF_ONESHOT | IRQF_SHARED,
-					"msm_iommu_nonsecure_irq", ctx_drvdata);
-
-		if (ret) {
-			pr_err("request_threaded_irq %d failed: %d\n", irq,
-								       ret);
-			goto fail;
-		}
-	} else {
-		ret = -ENODEV;
-		goto fail;
-	}
-
-	__enable_clocks(drvdata);
-	__program_m2v_tables(drvdata, ctx_drvdata);
-	__disable_clocks(drvdata);
-
-	dev_info(&pdev->dev, "context %s using bank %d\n", ctx_drvdata->name,
-							   ctx_drvdata->num);
-	return 0;
-fail:
-	return ret;
-}
-
-static int __devexit msm_iommu_ctx_remove(struct platform_device *pdev)
-{
-	platform_set_drvdata(pdev, NULL);
-	return 0;
-}
-
-
-static struct of_device_id msm_iommu_match_table[] = {
-	{ .compatible = "qcom,msm-smmu-v1", },
-	{}
-};
-
-static struct platform_driver msm_iommu_driver = {
-	.driver = {
-		.name	= "msm_iommu",
-		.of_match_table = msm_iommu_match_table,
-	},
-	.probe		= msm_iommu_probe,
-	.remove		= __devexit_p(msm_iommu_remove),
-};
-
-static struct of_device_id msm_iommu_ctx_match_table[] = {
-	{ .name = "qcom,iommu-ctx", },
-	{}
-};
-
-static struct platform_driver msm_iommu_ctx_driver = {
-	.driver = {
-		.name	= "msm_iommu_ctx",
-		.of_match_table = msm_iommu_ctx_match_table,
-	},
-	.probe		= msm_iommu_ctx_probe,
-	.remove		= __devexit_p(msm_iommu_ctx_remove),
-};
-
-static int __init msm_iommu_driver_init(void)
-{
-	int ret;
-	ret = platform_driver_register(&msm_iommu_driver);
-	if (ret != 0) {
-		pr_err("Failed to register IOMMU driver\n");
-		goto error;
-	}
-
-	ret = platform_driver_register(&msm_iommu_ctx_driver);
-	if (ret != 0) {
-		pr_err("Failed to register IOMMU context driver\n");
-		goto error;
-	}
-
-error:
-	return ret;
-}
-
-static void __exit msm_iommu_driver_exit(void)
-{
-	platform_driver_unregister(&msm_iommu_ctx_driver);
-	platform_driver_unregister(&msm_iommu_driver);
-}
-
-subsys_initcall(msm_iommu_driver_init);
-module_exit(msm_iommu_driver_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");
diff --git a/drivers/iommu/msm_iommu_pagetable.c b/drivers/iommu/msm_iommu_pagetable.c
index b93860e..99841cd 100644
--- a/drivers/iommu/msm_iommu_pagetable.c
+++ b/drivers/iommu/msm_iommu_pagetable.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 Code Aurora Forum. 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
@@ -110,6 +110,90 @@
 	return pgprot;
 }
 
+static unsigned long *make_second_level(struct iommu_pt *pt,
+					unsigned long *fl_pte)
+{
+	unsigned long *sl;
+	sl = (unsigned long *) __get_free_pages(GFP_KERNEL,
+			get_order(SZ_4K));
+
+	if (!sl) {
+		pr_debug("Could not allocate second level table\n");
+		goto fail;
+	}
+	memset(sl, 0, SZ_4K);
+	clean_pte(sl, sl + NUM_SL_PTE, pt->redirect);
+
+	*fl_pte = ((((int)__pa(sl)) & FL_BASE_MASK) | \
+			FL_TYPE_TABLE);
+
+	clean_pte(fl_pte, fl_pte + 1, pt->redirect);
+fail:
+	return sl;
+}
+
+static int sl_4k(unsigned long *sl_pte, phys_addr_t pa, unsigned int pgprot)
+{
+	int ret = 0;
+
+	if (*sl_pte) {
+		ret = -EBUSY;
+		goto fail;
+	}
+
+	*sl_pte = (pa & SL_BASE_MASK_SMALL) | SL_NG | SL_SHARED
+		| SL_TYPE_SMALL | pgprot;
+fail:
+	return ret;
+}
+
+static int sl_64k(unsigned long *sl_pte, phys_addr_t pa, unsigned int pgprot)
+{
+	int ret = 0;
+
+	int i;
+
+	for (i = 0; i < 16; i++)
+		if (*(sl_pte+i)) {
+			ret = -EBUSY;
+			goto fail;
+		}
+
+	for (i = 0; i < 16; i++)
+		*(sl_pte+i) = (pa & SL_BASE_MASK_LARGE) | SL_NG
+				| SL_SHARED | SL_TYPE_LARGE | pgprot;
+
+fail:
+	return ret;
+}
+
+static inline int fl_1m(unsigned long *fl_pte, phys_addr_t pa, int pgprot)
+{
+	if (*fl_pte)
+		return -EBUSY;
+
+	*fl_pte = (pa & 0xFFF00000) | FL_NG | FL_TYPE_SECT | FL_SHARED
+		| pgprot;
+
+	return 0;
+}
+
+static inline int fl_16m(unsigned long *fl_pte, phys_addr_t pa, int pgprot)
+{
+	int i;
+	int ret = 0;
+	for (i = 0; i < 16; i++)
+		if (*(fl_pte+i)) {
+			ret = -EBUSY;
+			goto fail;
+		}
+	for (i = 0; i < 16; i++)
+		*(fl_pte+i) = (pa & 0xFF000000) | FL_SUPERSECTION
+			| FL_TYPE_SECT | FL_SHARED | FL_NG | pgprot;
+fail:
+	return ret;
+}
+
 int msm_iommu_pagetable_map(struct iommu_pt *pt, unsigned long va,
 			phys_addr_t pa, size_t len, int prot)
 {
@@ -144,28 +228,16 @@
 	fl_pte = pt->fl_table + fl_offset;	/* int pointers, 4 bytes */
 
 	if (len == SZ_16M) {
-		int i = 0;
-
-		for (i = 0; i < 16; i++)
-			if (*(fl_pte+i)) {
-				ret = -EBUSY;
-				goto fail;
-			}
-
-		for (i = 0; i < 16; i++)
-			*(fl_pte+i) = (pa & 0xFF000000) | FL_SUPERSECTION |
-				  FL_TYPE_SECT | FL_SHARED | FL_NG | pgprot;
+		ret = fl_16m(fl_pte, pa, pgprot);
+		if (ret)
+			goto fail;
 		clean_pte(fl_pte, fl_pte + 16, pt->redirect);
 	}
 
 	if (len == SZ_1M) {
-		if (*fl_pte) {
-			ret = -EBUSY;
+		ret = fl_1m(fl_pte, pa, pgprot);
+		if (ret)
 			goto fail;
-		}
-
-		*fl_pte = (pa & 0xFFF00000) | FL_NG | FL_TYPE_SECT
-					| FL_SHARED | pgprot;
 		clean_pte(fl_pte, fl_pte + 1, pt->redirect);
 	}
 
@@ -173,21 +245,10 @@
 	if (len == SZ_4K || len == SZ_64K) {
 
 		if (*fl_pte == 0) {
-			unsigned long *sl;
-			sl = (unsigned long *) __get_free_pages(GFP_KERNEL,
-							get_order(SZ_4K));
-
-			if (!sl) {
-				pr_debug("Could not allocate second level table\n");
+			if (make_second_level(pt, fl_pte) == NULL) {
 				ret = -ENOMEM;
 				goto fail;
 			}
-			memset(sl, 0, SZ_4K);
-			clean_pte(sl, sl + NUM_SL_PTE, pt->redirect);
-
-			*fl_pte = ((((int)__pa(sl)) & FL_BASE_MASK) | \
-						      FL_TYPE_TABLE);
-			clean_pte(fl_pte, fl_pte + 1, pt->redirect);
 		}
 
 		if (!(*fl_pte & FL_TYPE_TABLE)) {
@@ -201,29 +262,16 @@
 	sl_pte = sl_table + sl_offset;
 
 	if (len == SZ_4K) {
-		if (*sl_pte) {
-			ret = -EBUSY;
+		ret = sl_4k(sl_pte, pa, pgprot);
+		if (ret)
 			goto fail;
-		}
-
-		*sl_pte = (pa & SL_BASE_MASK_SMALL) | SL_NG | SL_SHARED
-						| SL_TYPE_SMALL | pgprot;
 		clean_pte(sl_pte, sl_pte + 1, pt->redirect);
 	}
 
 	if (len == SZ_64K) {
-		int i;
-
-		for (i = 0; i < 16; i++)
-			if (*(sl_pte+i)) {
-				ret = -EBUSY;
-				goto fail;
-			}
-
-		for (i = 0; i < 16; i++)
-			*(sl_pte+i) = (pa & SL_BASE_MASK_LARGE) | SL_NG
-					| SL_SHARED | SL_TYPE_LARGE | pgprot;
-
+		ret = sl_64k(sl_pte, pa, pgprot);
+		if (ret)
+			goto fail;
 		clean_pte(sl_pte, sl_pte + 16, pt->redirect);
 	}
 
@@ -322,64 +370,99 @@
 	return pa;
 }
 
+static inline int is_fully_aligned(unsigned int va, phys_addr_t pa, size_t len,
+				   int align)
+{
+	return  IS_ALIGNED(va, align) && IS_ALIGNED(pa, align)
+		&& (len >= align);
+}
+
 int msm_iommu_pagetable_map_range(struct iommu_pt *pt, unsigned int va,
 		       struct scatterlist *sg, unsigned int len, int prot)
 {
 	unsigned int pa;
 	unsigned int offset = 0;
-	unsigned int pgprot;
 	unsigned long *fl_pte;
 	unsigned long fl_offset;
-	unsigned long *sl_table;
+	unsigned long *sl_table = NULL;
 	unsigned long sl_offset, sl_start;
-	unsigned int chunk_offset = 0;
-	unsigned int chunk_pa;
+	unsigned int chunk_size, chunk_offset = 0;
 	int ret = 0;
+	unsigned int pgprot4k, pgprot64k, pgprot1m, pgprot16m;
 
 	BUG_ON(len & (SZ_4K - 1));
 
-	pgprot = __get_pgprot(prot, SZ_4K);
-	if (!pgprot) {
+	pgprot4k = __get_pgprot(prot, SZ_4K);
+	pgprot64k = __get_pgprot(prot, SZ_64K);
+	pgprot1m = __get_pgprot(prot, SZ_1M);
+	pgprot16m = __get_pgprot(prot, SZ_16M);
+	if (!pgprot4k || !pgprot64k || !pgprot1m || !pgprot16m) {
 		ret = -EINVAL;
 		goto fail;
 	}
 
 	fl_offset = FL_OFFSET(va);		/* Upper 12 bits */
 	fl_pte = pt->fl_table + fl_offset;	/* int pointers, 4 bytes */
-
-	sl_table = (unsigned long *) __va(((*fl_pte) & FL_BASE_MASK));
-	sl_offset = SL_OFFSET(va);
-
-	chunk_pa = get_phys_addr(sg);
-	if (chunk_pa == 0) {
-		pr_debug("No dma address for sg %p\n", sg);
-		ret = -EINVAL;
-		goto fail;
-	}
+	pa = get_phys_addr(sg);
 
 	while (offset < len) {
-		/* Set up a 2nd level page table if one doesn't exist */
-		if (*fl_pte == 0) {
-			sl_table = (unsigned long *)
-				 __get_free_pages(GFP_KERNEL, get_order(SZ_4K));
+		chunk_size = SZ_4K;
 
-			if (!sl_table) {
-				pr_debug("Could not allocate second level table\n");
+		if (is_fully_aligned(va, pa, sg->length - chunk_offset,
+				     SZ_16M))
+			chunk_size = SZ_16M;
+		else if (is_fully_aligned(va, pa, sg->length - chunk_offset,
+					  SZ_1M))
+			chunk_size = SZ_1M;
+		/* 64k or 4k determined later */
+
+		/* for 1M and 16M, only first level entries are required */
+		if (chunk_size >= SZ_1M) {
+			if (chunk_size == SZ_16M) {
+				ret = fl_16m(fl_pte, pa, pgprot16m);
+				if (ret)
+					goto fail;
+				clean_pte(fl_pte, fl_pte + 16, pt->redirect);
+				fl_pte += 16;
+			} else if (chunk_size == SZ_1M) {
+				ret = fl_1m(fl_pte, pa, pgprot1m);
+				if (ret)
+					goto fail;
+				clean_pte(fl_pte, fl_pte + 1, pt->redirect);
+				fl_pte++;
+			}
+
+			offset += chunk_size;
+			chunk_offset += chunk_size;
+			va += chunk_size;
+			pa += chunk_size;
+
+			if (chunk_offset >= sg->length && offset < len) {
+				chunk_offset = 0;
+				sg = sg_next(sg);
+				pa = get_phys_addr(sg);
+				if (pa == 0) {
+					pr_debug("No dma address for sg %p\n",
+							sg);
+					ret = -EINVAL;
+					goto fail;
+				}
+			}
+			continue;
+		}
+		/* for 4K or 64K, make sure there is a second level table */
+		if (*fl_pte == 0) {
+			if (!make_second_level(pt, fl_pte)) {
 				ret = -ENOMEM;
 				goto fail;
 			}
-
-			memset(sl_table, 0, SZ_4K);
-			clean_pte(sl_table, sl_table + NUM_SL_PTE,
-					pt->redirect);
-
-			*fl_pte = ((((int)__pa(sl_table)) & FL_BASE_MASK) |
-							    FL_TYPE_TABLE);
-			clean_pte(fl_pte, fl_pte + 1, pt->redirect);
-		} else
-			sl_table = (unsigned long *)
-					       __va(((*fl_pte) & FL_BASE_MASK));
-
+		}
+		if (!(*fl_pte & FL_TYPE_TABLE)) {
+			ret = -EBUSY;
+			goto fail;
+		}
+		sl_table = __va(((*fl_pte) & FL_BASE_MASK));
+		sl_offset = SL_OFFSET(va);
 		/* Keep track of initial position so we
 		 * don't clean more than we have to
 		 */
@@ -387,21 +470,38 @@
 
 		/* Build the 2nd level page table */
 		while (offset < len && sl_offset < NUM_SL_PTE) {
-			pa = chunk_pa + chunk_offset;
-			sl_table[sl_offset] = (pa & SL_BASE_MASK_SMALL) |
-			      pgprot | SL_NG | SL_SHARED | SL_TYPE_SMALL;
-			sl_offset++;
-			offset += SZ_4K;
+			/* Map a large 64K page if the chunk is large enough and
+			 * the pa and va are aligned
+			 */
 
-			chunk_offset += SZ_4K;
+			if (is_fully_aligned(va, pa, sg->length - chunk_offset,
+					     SZ_64K))
+				chunk_size = SZ_64K;
+			else
+				chunk_size = SZ_4K;
+
+			if (chunk_size == SZ_4K) {
+				sl_4k(&sl_table[sl_offset], pa, pgprot4k);
+				sl_offset++;
+			} else {
+				BUG_ON(sl_offset + 16 > NUM_SL_PTE);
+				sl_64k(&sl_table[sl_offset], pa, pgprot64k);
+				sl_offset += 16;
+			}
+
+
+			offset += chunk_size;
+			chunk_offset += chunk_size;
+			va += chunk_size;
+			pa += chunk_size;
 
 			if (chunk_offset >= sg->length && offset < len) {
 				chunk_offset = 0;
 				sg = sg_next(sg);
-				chunk_pa = get_phys_addr(sg);
-				if (chunk_pa == 0) {
+				pa = get_phys_addr(sg);
+				if (pa == 0) {
 					pr_debug("No dma address for sg %p\n",
-						sg);
+							sg);
 					ret = -EINVAL;
 					goto fail;
 				}
@@ -433,44 +533,53 @@
 	fl_offset = FL_OFFSET(va);		/* Upper 12 bits */
 	fl_pte = pt->fl_table + fl_offset;	/* int pointers, 4 bytes */
 
-	sl_start = SL_OFFSET(va);
-
 	while (offset < len) {
-		sl_table = (unsigned long *) __va(((*fl_pte) & FL_BASE_MASK));
-		sl_end = ((len - offset) / SZ_4K) + sl_start;
+		if (*fl_pte & FL_TYPE_TABLE) {
+			sl_start = SL_OFFSET(va);
+			sl_table =  __va(((*fl_pte) & FL_BASE_MASK));
+			sl_end = ((len - offset) / SZ_4K) + sl_start;
 
-		if (sl_end > NUM_SL_PTE)
-			sl_end = NUM_SL_PTE;
+			if (sl_end > NUM_SL_PTE)
+				sl_end = NUM_SL_PTE;
 
-		memset(sl_table + sl_start, 0, (sl_end - sl_start) * 4);
-		clean_pte(sl_table + sl_start, sl_table + sl_end,
-				pt->redirect);
+			memset(sl_table + sl_start, 0, (sl_end - sl_start) * 4);
+			clean_pte(sl_table + sl_start, sl_table + sl_end,
+					pt->redirect);
 
-		offset += (sl_end - sl_start) * SZ_4K;
+			offset += (sl_end - sl_start) * SZ_4K;
+			va += (sl_end - sl_start) * SZ_4K;
 
-		/* Unmap and free the 2nd level table if all mappings in it
-		 * were removed. This saves memory, but the table will need
-		 * to be re-allocated the next time someone tries to map these
-		 * VAs.
-		 */
-		used = 0;
+			/* Unmap and free the 2nd level table if all mappings
+			 * in it were removed. This saves memory, but the table
+			 * will need to be re-allocated the next time someone
+			 * tries to map these VAs.
+			 */
+			used = 0;
 
-		/* If we just unmapped the whole table, don't bother
-		 * seeing if there are still used entries left.
-		 */
-		if (sl_end - sl_start != NUM_SL_PTE)
-			for (i = 0; i < NUM_SL_PTE; i++)
-				if (sl_table[i]) {
-					used = 1;
-					break;
-				}
-		if (!used) {
-			free_page((unsigned long)sl_table);
+			/* If we just unmapped the whole table, don't bother
+			 * seeing if there are still used entries left.
+			 */
+			if (sl_end - sl_start != NUM_SL_PTE)
+				for (i = 0; i < NUM_SL_PTE; i++)
+					if (sl_table[i]) {
+						used = 1;
+						break;
+					}
+			if (!used) {
+				free_page((unsigned long)sl_table);
+				*fl_pte = 0;
+
+				clean_pte(fl_pte, fl_pte + 1, pt->redirect);
+			}
+
+			sl_start = 0;
+		} else {
 			*fl_pte = 0;
 			clean_pte(fl_pte, fl_pte + 1, pt->redirect);
+			va += SZ_1M;
+			offset += SZ_1M;
+			sl_start = 0;
 		}
-
-		sl_start = 0;
 		fl_pte++;
 	}
 }
diff --git a/drivers/iommu/msm_iommu_pagetable.h b/drivers/iommu/msm_iommu_pagetable.h
index b943084..3266681 100644
--- a/drivers/iommu/msm_iommu_pagetable.h
+++ b/drivers/iommu/msm_iommu_pagetable.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012 The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/iommu/msm_iommu_perfmon-v0.c b/drivers/iommu/msm_iommu_perfmon-v0.c
new file mode 100644
index 0000000..c80d1e5
--- /dev/null
+++ b/drivers/iommu/msm_iommu_perfmon-v0.c
@@ -0,0 +1,310 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/**
+ * This file contains the part of the IOMMUv0 PMU driver that actually touches
+ * IOMMU PMU registers.
+ */
+
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <mach/iommu_hw-v0.h>
+#include <mach/iommu_perfmon.h>
+
+#define PM_RESET_MASK		(0xF)
+#define PM_RESET_SHIFT		(0x8)
+#define PM_RESET		(PM_RESET_MASK << PM_RESET_SHIFT)
+
+#define PM_ENABLE_MASK		(0x1)
+#define PM_ENABLE_SHIFT		(0x0)
+#define PM_ENABLE		(PM_ENABLE_MASK << PM_ENABLE_SHIFT)
+
+#define PM_OVFL_FLAG_MASK	(0xF)
+#define PM_OVFL_FLAG_SHIFT	(0x0)
+#define PM_OVFL_FLAG		(PM_OVFL_FLAG_MASK << PM_OVFL_FLAG_SHIFT)
+
+#define PM_EVENT_TYPE_MASK	(0x1F)
+#define PM_EVENT_TYPE_SHIFT	(0x2)
+#define PM_EVENT_TYPE		(PM_EVENT_TYPE_MASK << PM_EVENT_TYPE_SHIFT)
+
+#define PM_INT_EN_MASK		(0x1)
+#define PM_INT_EN_SHIFT		(0x0)
+#define PM_INT_EN		(PM_INT_EN_MASK << PM_INT_EN_SHIFT)
+
+#define PM_INT_POL_MASK		(0x1)
+#define PM_INT_POL_SHIFT	(0x2)
+#define PM_INT_ACTIVE_HIGH	(0x1)
+
+#define PMEVCNTR_(n)		(EMC_N + n*4)
+#define PMEVTYPER_(n)		(EMCC_N + n*4)
+
+/**
+ * Translate between SMMUv0 event classes and standard ARM SMMU event classes
+ */
+static int iommu_pm_event_class_translation_table[] = {
+	MSM_IOMMU_PMU_NO_EVENT_CLASS,
+	MSM_IOMMU_PMU_NO_EVENT_CLASS,
+	MSM_IOMMU_PMU_NO_EVENT_CLASS,
+	0x8,
+	0x9,
+	MSM_IOMMU_PMU_NO_EVENT_CLASS,
+	0x80,
+	MSM_IOMMU_PMU_NO_EVENT_CLASS,
+	0x12,
+	MSM_IOMMU_PMU_NO_EVENT_CLASS,
+	MSM_IOMMU_PMU_NO_EVENT_CLASS,
+	MSM_IOMMU_PMU_NO_EVENT_CLASS,
+	MSM_IOMMU_PMU_NO_EVENT_CLASS,
+	MSM_IOMMU_PMU_NO_EVENT_CLASS,
+	MSM_IOMMU_PMU_NO_EVENT_CLASS,
+	0x10,
+};
+
+static int iommu_pm_translate_event_class(int event_class)
+{
+	const unsigned int TBL_LEN =
+			ARRAY_SIZE(iommu_pm_event_class_translation_table);
+	unsigned int i;
+
+	if (event_class < 0)
+		return event_class;
+
+	for (i = 0; i < TBL_LEN; ++i) {
+		if (iommu_pm_event_class_translation_table[i] == event_class)
+			return i;
+	}
+	return MSM_IOMMU_PMU_NO_EVENT_CLASS;
+}
+
+static unsigned int iommu_pm_is_hw_access_OK(const struct iommu_pmon *pmon)
+{
+	/*
+	 * IOMMUv0 is in always ON domain so we don't care whether we are
+	 * attached or not. We only care whether the PMU is enabled or
+	 * not meaning clocks are turned on.
+	 */
+	return pmon->enabled;
+}
+
+static void iommu_pm_grp_enable(struct iommu_info *iommu, unsigned int grp_no)
+{
+	/* No group concept in v0. */
+}
+
+static void iommu_pm_grp_disable(struct iommu_info *iommu, unsigned int grp_no)
+{
+	/* No group concept in v0. */
+}
+
+static void iommu_pm_set_int_active_high(const struct iommu_info *iommu)
+{
+	unsigned int emmc;
+	emmc = readl_relaxed(iommu->base + EMMC);
+	emmc |= (PM_INT_ACTIVE_HIGH & PM_INT_POL_MASK) << PM_INT_POL_SHIFT;
+	writel_relaxed(emmc, iommu->base + EMMC);
+}
+
+static void iommu_pm_enable(struct iommu_info *iommu)
+{
+	unsigned int emmc;
+	emmc = readl_relaxed(iommu->base + EMMC);
+	emmc |= PM_ENABLE;
+	writel_relaxed(emmc, iommu->base + EMMC);
+}
+
+static void iommu_pm_disable(struct iommu_info *iommu)
+{
+	unsigned int emmc;
+	emmc = readl_relaxed(iommu->base + EMMC);
+	emmc &= ~PM_ENABLE;
+	writel_relaxed(emmc, iommu->base + EMMC);
+}
+
+static void iommu_pm_reset_counters(const struct iommu_info *iommu)
+{
+	unsigned int emmc;
+	emmc = readl_relaxed(iommu->base + EMMC);
+	emmc |= PM_RESET;
+	writel_relaxed(emmc, iommu->base + EMMC);
+}
+
+static void iommu_pm_check_for_overflow(struct iommu_pmon *pmon)
+{
+	struct iommu_pmon_counter *counter;
+	struct iommu_info *iommu = &pmon->iommu;
+	unsigned int reg_value;
+	unsigned int j;
+	struct iommu_pmon_cnt_group *cnt_grp = &pmon->cnt_grp[0];
+
+	reg_value = readl_relaxed(iommu->base + EMCS);
+	reg_value &= PM_OVFL_FLAG;
+
+	for (j = 0; j < cnt_grp->num_counters; ++j) {
+		counter = &cnt_grp->counters[j];
+
+		if (counter->enabled) {
+			if (reg_value & (1 << counter->absolute_counter_no))
+				counter->overflow_count++;
+		}
+	}
+
+	/* Clear overflow */
+	writel_relaxed(reg_value, iommu->base + EMCS);
+}
+
+static irqreturn_t iommu_pm_evt_ovfl_int_handler(int irq, void *dev_id)
+{
+	struct iommu_pmon *pmon = dev_id;
+	struct iommu_info *iommu = &pmon->iommu;
+
+	mutex_lock(&pmon->lock);
+
+	if (!iommu_pm_is_hw_access_OK(pmon)) {
+		mutex_unlock(&pmon->lock);
+		goto out;
+	}
+
+	iommu->ops->iommu_lock_acquire();
+	iommu_pm_check_for_overflow(pmon);
+	iommu->ops->iommu_lock_release();
+
+	mutex_unlock(&pmon->lock);
+
+out:
+	return IRQ_HANDLED;
+}
+
+static void iommu_pm_counter_enable(struct iommu_info *iommu,
+				    struct iommu_pmon_counter *counter)
+{
+	unsigned int bit_no = counter->absolute_counter_no;
+	unsigned int reg_value;
+
+	/* Clear overflow of counter */
+	reg_value = readl_relaxed(iommu->base + EMCS);
+	reg_value &= (1 << bit_no);
+	writel_relaxed(reg_value, iommu->base + EMCS);
+
+	/* Enable counter */
+	counter->enabled = 1;
+}
+
+static void iommu_pm_counter_disable(struct iommu_info *iommu,
+				     struct iommu_pmon_counter *counter)
+{
+	unsigned int bit_no = counter->absolute_counter_no;
+	unsigned int reg_value;
+
+	/* Disable counter */
+	counter->enabled = 0;
+
+	/* Clear overflow of counter */
+	reg_value = readl_relaxed(iommu->base + EMCS);
+	reg_value &= (1 << bit_no);
+	writel_relaxed(reg_value, iommu->base + EMCS);
+}
+
+/*
+ * Must be called after iommu_start_access() is called
+ */
+static void iommu_pm_ovfl_int_enable(struct iommu_info *iommu,
+				     const struct iommu_pmon_counter *counter)
+{
+	unsigned int reg_no = counter->absolute_counter_no;
+	unsigned int reg_value;
+
+	/* Enable overflow interrupt for counter */
+	reg_value = readl_relaxed(iommu->base + PMEVTYPER_(reg_no));
+	reg_value |= PM_INT_EN;
+	writel_relaxed(reg_value, iommu->base + PMEVTYPER_(reg_no));
+}
+
+/*
+ * Must be called after iommu_start_access() is called
+ */
+static void iommu_pm_ovfl_int_disable(struct iommu_info *iommu,
+				      const struct iommu_pmon_counter *counter)
+{
+	unsigned int reg_no = counter->absolute_counter_no;
+	unsigned int reg_value;
+
+	/* Disable overflow interrupt for counter */
+	reg_value = readl_relaxed(iommu->base + PMEVTYPER_(reg_no));
+	reg_value &= ~PM_INT_EN;
+	writel_relaxed(reg_value, iommu->base + PMEVTYPER_(reg_no));
+}
+
+static void iommu_pm_set_event_class(struct iommu_pmon *pmon,
+				    unsigned int count_no,
+				    unsigned int event_class)
+{
+	unsigned int reg_no = count_no;
+	unsigned int reg_value;
+	int event = iommu_pm_translate_event_class(event_class);
+
+	if (event == MSM_IOMMU_PMU_NO_EVENT_CLASS)
+		event = 0;
+
+	reg_value = readl_relaxed(pmon->iommu.base + PMEVTYPER_(reg_no));
+	reg_value &= ~(PM_EVENT_TYPE_MASK << PM_EVENT_TYPE_SHIFT);
+	reg_value |= (event & PM_EVENT_TYPE_MASK) << PM_EVENT_TYPE_SHIFT;
+	writel_relaxed(reg_value, pmon->iommu.base + PMEVTYPER_(reg_no));
+}
+
+static unsigned int iommu_pm_read_counter(struct iommu_pmon_counter *counter)
+{
+	struct iommu_pmon *pmon = counter->cnt_group->pmon;
+	struct iommu_info *info = &pmon->iommu;
+	unsigned int cnt_no = counter->absolute_counter_no;
+	return readl_relaxed(info->base + PMEVCNTR_(cnt_no));
+}
+
+static void iommu_pm_initialize_hw(const struct iommu_pmon *pmon)
+{
+	const struct iommu_info *iommu = &pmon->iommu;
+	struct msm_iommu_drvdata *iommu_drvdata =
+					dev_get_drvdata(iommu->iommu_dev);
+
+	/* This is called during bootup device initialization so no need
+	 * for locking here.
+	 */
+	iommu->ops->iommu_power_on(iommu_drvdata);
+	iommu_pm_set_int_active_high(iommu);
+	iommu->ops->iommu_power_off(iommu_drvdata);
+}
+
+static struct iommu_pm_hw_ops iommu_pm_hw_ops = {
+	.initialize_hw = iommu_pm_initialize_hw,
+	.is_hw_access_OK = iommu_pm_is_hw_access_OK,
+	.grp_enable = iommu_pm_grp_enable,
+	.grp_disable = iommu_pm_grp_disable,
+	.enable_pm = iommu_pm_enable,
+	.disable_pm = iommu_pm_disable,
+	.reset_counters = iommu_pm_reset_counters,
+	.check_for_overflow = iommu_pm_check_for_overflow,
+	.evt_ovfl_int_handler = iommu_pm_evt_ovfl_int_handler,
+	.counter_enable = iommu_pm_counter_enable,
+	.counter_disable = iommu_pm_counter_disable,
+	.ovfl_int_enable = iommu_pm_ovfl_int_enable,
+	.ovfl_int_disable = iommu_pm_ovfl_int_disable,
+	.set_event_class = iommu_pm_set_event_class,
+	.read_counter = iommu_pm_read_counter,
+};
+
+struct iommu_pm_hw_ops *iommu_pm_get_hw_ops_v0(void)
+{
+	return &iommu_pm_hw_ops;
+}
+EXPORT_SYMBOL(iommu_pm_get_hw_ops_v0);
+
diff --git a/drivers/iommu/msm_iommu_perfmon-v1.c b/drivers/iommu/msm_iommu_perfmon-v1.c
new file mode 100644
index 0000000..d76ee7f
--- /dev/null
+++ b/drivers/iommu/msm_iommu_perfmon-v1.c
@@ -0,0 +1,269 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/**
+ * This file contains the part of the IOMMUv1 PMU driver that actually touches
+ * IOMMU PMU registers.
+ */
+
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <mach/iommu_hw-v1.h>
+#include <mach/iommu_perfmon.h>
+
+#define PMCR_P_MASK		(0x1)
+#define PMCR_P_SHIFT		(1)
+#define PMCR_P			(PMCR_P_MASK << PMCR_P_SHIFT)
+#define PMCFGR_NCG_MASK		(0xFF)
+#define PMCFGR_NCG_SHIFT	(24)
+#define PMCFGR_NCG		(PMCFGR_NCG_MASK << PMCFGR_NCG_SHIFT)
+#define PMCFGR_N_MASK		(0xFF)
+#define PMCFGR_N_SHIFT		(0)
+#define PMCFGR_N		(PMCFGR_N_MASK << PMCFGR_N_SHIFT)
+#define CR_E			0x1
+#define CGCR_CEN		0x800
+#define CGCR_CEN_SHFT		(1 << 11)
+#define PMCGCR_CGNC_MASK	(0x0F)
+#define PMCGCR_CGNC_SHIFT	(24)
+#define PMCGCR_CGNC		(PMCGCR_CGNC_MASK << PMCGCR_CGNC_SHIFT)
+#define PMCGCR_(group)		(PMCGCR_N + group*4)
+
+#define PMOVSCLR_(n)		(PMOVSCLR_N + n*4)
+#define PMCNTENSET_(n)		(PMCNTENSET_N + n*4)
+#define PMCNTENCLR_(n)		(PMCNTENCLR_N + n*4)
+#define PMINTENSET_(n)		(PMINTENSET_N + n*4)
+#define PMINTENCLR_(n)		(PMINTENCLR_N + n*4)
+
+#define PMEVCNTR_(n)		(PMEVCNTR_N + n*4)
+#define PMEVTYPER_(n)		(PMEVTYPER_N + n*4)
+
+
+static unsigned int iommu_pm_is_hw_access_OK(const struct iommu_pmon *pmon)
+{
+	/*
+	 * IOMMUv1 is not in the always on domain so we need to make sure
+	 * the regulators are turned on in addition to clocks before we allow
+	 * access to the hardware thus we check if we have attached to the
+	 * IOMMU in addition to checking if we have enabled PMU.
+	 */
+	return pmon->enabled && (pmon->iommu_attach_count > 0);
+}
+
+static void iommu_pm_grp_enable(struct iommu_info *iommu, unsigned int grp_no)
+{
+	unsigned int pmcgcr;
+	pmcgcr = readl_relaxed(iommu->base + PMCGCR_(grp_no));
+	pmcgcr |= CGCR_CEN;
+	writel_relaxed(pmcgcr, iommu->base + PMCGCR_(grp_no));
+}
+
+static void iommu_pm_grp_disable(struct iommu_info *iommu, unsigned int grp_no)
+{
+	unsigned int pmcgcr;
+	pmcgcr = readl_relaxed(iommu->base + PMCGCR_(grp_no));
+	pmcgcr &= ~CGCR_CEN;
+	writel_relaxed(pmcgcr, iommu->base + PMCGCR_(grp_no));
+}
+
+static void iommu_pm_enable(struct iommu_info *iommu)
+{
+	unsigned int pmcr;
+	pmcr = readl_relaxed(iommu->base + PMCR);
+	pmcr |= CR_E;
+	writel_relaxed(pmcr, iommu->base + PMCR);
+}
+
+static void iommu_pm_disable(struct iommu_info *iommu)
+{
+	unsigned int pmcr;
+	pmcr = readl_relaxed(iommu->base + PMCR);
+	pmcr &= ~CR_E;
+	writel_relaxed(pmcr, iommu->base + PMCR);
+}
+
+static void iommu_pm_reset_counters(const struct iommu_info *iommu)
+{
+	unsigned int pmcr;
+	pmcr = readl_relaxed(iommu->base + PMCR);
+	pmcr |= PMCR_P;
+	writel_relaxed(pmcr, iommu->base + PMCR);
+}
+
+static void iommu_pm_check_for_overflow(struct iommu_pmon *pmon)
+{
+	struct iommu_pmon_counter *counter;
+	struct iommu_info *iommu = &pmon->iommu;
+	unsigned int reg_no = 0;
+	unsigned int bit_no;
+	unsigned int reg_value;
+	unsigned int i;
+	unsigned int j;
+	unsigned int curr_reg = 0;
+
+	reg_value = readl_relaxed(iommu->base + PMOVSCLR_(curr_reg));
+
+	for (i = 0; i < pmon->num_groups; ++i) {
+		struct iommu_pmon_cnt_group *cnt_grp = &pmon->cnt_grp[i];
+		for (j = 0; j < cnt_grp->num_counters; ++j) {
+			counter = &cnt_grp->counters[j];
+			reg_no = counter->absolute_counter_no / 32;
+			bit_no = counter->absolute_counter_no % 32;
+			if (reg_no != curr_reg) {
+				/* Clear overflow bits */
+				writel_relaxed(reg_value, iommu->base +
+					       PMOVSCLR_(reg_no));
+				curr_reg = reg_no;
+				reg_value = readl_relaxed(iommu->base +
+							  PMOVSCLR_(curr_reg));
+			}
+
+			if (counter->enabled) {
+				if (reg_value & (1 << bit_no))
+					counter->overflow_count++;
+			}
+		}
+	}
+
+	/* Clear overflow */
+	writel_relaxed(reg_value, iommu->base + PMOVSCLR_(reg_no));
+}
+
+static irqreturn_t iommu_pm_evt_ovfl_int_handler(int irq, void *dev_id)
+{
+	struct iommu_pmon *pmon = dev_id;
+	struct iommu_info *iommu = &pmon->iommu;
+
+	mutex_lock(&pmon->lock);
+
+	if (!iommu_pm_is_hw_access_OK(pmon)) {
+		mutex_unlock(&pmon->lock);
+		goto out;
+	}
+
+	iommu->ops->iommu_lock_acquire();
+	iommu_pm_check_for_overflow(pmon);
+	iommu->ops->iommu_lock_release();
+
+	mutex_unlock(&pmon->lock);
+
+out:
+	return IRQ_HANDLED;
+}
+
+static void iommu_pm_counter_enable(struct iommu_info *iommu,
+				    struct iommu_pmon_counter *counter)
+{
+	unsigned int reg_no = counter->absolute_counter_no / 32;
+	unsigned int bit_no = counter->absolute_counter_no % 32;
+	unsigned int reg_value;
+
+	/* Clear overflow of counter */
+	reg_value = 1 << bit_no;
+	writel_relaxed(reg_value, iommu->base + PMOVSCLR_(reg_no));
+
+	/* Enable counter */
+	writel_relaxed(reg_value, iommu->base + PMCNTENSET_(reg_no));
+	counter->enabled = 1;
+}
+
+static void iommu_pm_counter_disable(struct iommu_info *iommu,
+				     struct iommu_pmon_counter *counter)
+{
+	unsigned int reg_no = counter->absolute_counter_no / 32;
+	unsigned int bit_no = counter->absolute_counter_no % 32;
+	unsigned int reg_value;
+
+	counter->enabled = 0;
+
+	/* Disable counter */
+	reg_value = 1 << bit_no;
+	writel_relaxed(reg_value, iommu->base + PMCNTENCLR_(reg_no));
+
+	/* Clear overflow of counter */
+	writel_relaxed(reg_value, iommu->base + PMOVSCLR_(reg_no));
+}
+
+/*
+ * Must be called after iommu_start_access() is called
+ */
+static void iommu_pm_ovfl_int_enable(struct iommu_info *iommu,
+				     const struct iommu_pmon_counter *counter)
+{
+	unsigned int reg_no = counter->absolute_counter_no / 32;
+	unsigned int bit_no = counter->absolute_counter_no % 32;
+	unsigned int reg_value;
+
+	/* Enable overflow interrupt for counter */
+	reg_value = (1 << bit_no);
+	writel_relaxed(reg_value, iommu->base + PMINTENSET_(reg_no));
+}
+
+/*
+ * Must be called after iommu_start_access() is called
+ */
+static void iommu_pm_ovfl_int_disable(struct iommu_info *iommu,
+				      const struct iommu_pmon_counter *counter)
+{
+	unsigned int reg_no = counter->absolute_counter_no / 32;
+	unsigned int bit_no = counter->absolute_counter_no % 32;
+	unsigned int reg_value;
+
+	/* Disable overflow interrupt for counter */
+	reg_value = 1 << bit_no;
+	writel_relaxed(reg_value, iommu->base + PMINTENCLR_(reg_no));
+}
+
+static void iommu_pm_set_event_class(struct iommu_pmon *pmon,
+				    unsigned int count_no,
+				    unsigned int event_class)
+{
+	writel_relaxed(event_class, pmon->iommu.base + PMEVTYPER_(count_no));
+}
+
+static unsigned int iommu_pm_read_counter(struct iommu_pmon_counter *counter)
+{
+	struct iommu_pmon *pmon = counter->cnt_group->pmon;
+	struct iommu_info *info = &pmon->iommu;
+	unsigned int cnt_no = counter->absolute_counter_no;
+	return readl_relaxed(info->base + PMEVCNTR_(cnt_no));
+}
+
+static void iommu_pm_initialize_hw(const struct iommu_pmon *pmon)
+{
+	/* No initialization needed */
+}
+
+static struct iommu_pm_hw_ops iommu_pm_hw_ops = {
+	.initialize_hw = iommu_pm_initialize_hw,
+	.is_hw_access_OK = iommu_pm_is_hw_access_OK,
+	.grp_enable = iommu_pm_grp_enable,
+	.grp_disable = iommu_pm_grp_disable,
+	.enable_pm = iommu_pm_enable,
+	.disable_pm = iommu_pm_disable,
+	.reset_counters = iommu_pm_reset_counters,
+	.check_for_overflow = iommu_pm_check_for_overflow,
+	.evt_ovfl_int_handler = iommu_pm_evt_ovfl_int_handler,
+	.counter_enable = iommu_pm_counter_enable,
+	.counter_disable = iommu_pm_counter_disable,
+	.ovfl_int_enable = iommu_pm_ovfl_int_enable,
+	.ovfl_int_disable = iommu_pm_ovfl_int_disable,
+	.set_event_class = iommu_pm_set_event_class,
+	.read_counter = iommu_pm_read_counter,
+};
+
+struct iommu_pm_hw_ops *iommu_pm_get_hw_ops_v1(void)
+{
+	return &iommu_pm_hw_ops;
+}
+EXPORT_SYMBOL(iommu_pm_get_hw_ops_v1);
+
diff --git a/drivers/iommu/msm_iommu_perfmon.c b/drivers/iommu/msm_iommu_perfmon.c
new file mode 100644
index 0000000..41df1ed
--- /dev/null
+++ b/drivers/iommu/msm_iommu_perfmon.c
@@ -0,0 +1,817 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/iommu.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/bitops.h>
+#include <linux/debugfs.h>
+#include <mach/iommu.h>
+#include <mach/iommu_perfmon.h>
+
+static LIST_HEAD(iommu_list);
+static struct dentry *msm_iommu_root_debugfs_dir;
+static const char *NO_EVENT_CLASS_NAME = "none";
+static const unsigned int MAX_EVEN_CLASS_NAME_LEN = 36;
+
+struct event_class {
+	unsigned int event_number;
+	const char *desc;
+};
+
+static struct event_class pmu_event_classes[] = {
+	{ 0x00, "cycle_count"      },
+	{ 0x01, "cycle_count64"    },
+	{ 0x08, "tlb_refill"       },
+	{ 0x09, "tlb_refill_read"  },
+	{ 0x0A, "tlb_refill_write" },
+	{ 0x10, "access"           },
+	{ 0x11, "access_read"      },
+	{ 0x12, "access_write"     },
+	{ 0x80, "full_misses"      },
+	{ 0x81, "partial_miss_1lbfb_hit" },
+	{ 0x82, "partial_miss_2lbfb_hit" },
+	{ 0x83, "full_hit" },
+	{ 0x90, "pred_req_full_miss" },
+	{ 0x91, "pred_req_partial_miss_1lbfb_hit" },
+	{ 0x92, "pred_req_partial_miss_2lbfb_hit" },
+	{ 0xb0, "tot_num_miss_axi_htw_read_req" },
+	{ 0xb1, "tot_num_pred_axi_htw_read_req" },
+};
+
+static unsigned int iommu_pm_create_sup_cls_str(char **buf,
+						struct iommu_pmon *pmon)
+{
+	unsigned long buf_size = ARRAY_SIZE(pmu_event_classes) *
+				 MAX_EVEN_CLASS_NAME_LEN;
+	unsigned int pos = 0;
+	unsigned int nevent_cls = pmon->nevent_cls_supported;
+
+	*buf = kzalloc(buf_size, GFP_KERNEL);
+	if (*buf) {
+		unsigned int j;
+		int i;
+		struct event_class *ptr;
+		size_t array_len = ARRAY_SIZE(pmu_event_classes);
+		ptr = pmu_event_classes;
+
+		for (j = 0; j < nevent_cls; ++j) {
+			for (i = 0; i < array_len; ++i) {
+
+				if (ptr[i].event_number !=
+						pmon->event_cls_supported[j])
+					continue;
+
+				if (pos < buf_size) {
+					pos += snprintf(&(*buf)[pos],
+							buf_size-pos,
+							"[%u] %s\n",
+							ptr[i].event_number,
+							ptr[i].desc);
+				}
+				break;
+			}
+		}
+	}
+	return pos;
+}
+
+static const char *iommu_pm_find_event_class_name(int event_class)
+{
+	size_t array_len;
+	struct event_class *ptr;
+	int i;
+	const char *event_class_name = NO_EVENT_CLASS_NAME;
+	if (event_class < 0)
+		goto out;
+
+	array_len = ARRAY_SIZE(pmu_event_classes);
+	ptr = pmu_event_classes;
+
+	for (i = 0; i < array_len; ++i) {
+		if (ptr[i].event_number == event_class) {
+			event_class_name =  ptr[i].desc;
+			break;
+		}
+	}
+
+out:
+	return event_class_name;
+}
+
+static int iommu_pm_find_event_class(const char *event_class_name)
+{
+	size_t array_len;
+	struct event_class *ptr;
+	int i;
+	int event_class = MSM_IOMMU_PMU_NO_EVENT_CLASS;
+
+	if (strcmp(event_class_name, NO_EVENT_CLASS_NAME) == 0)
+		goto out;
+
+	array_len = ARRAY_SIZE(pmu_event_classes);
+	ptr = pmu_event_classes;
+
+	for (i = 0; i < array_len; ++i) {
+		if (strcmp(ptr[i].desc, event_class_name) == 0) {
+			event_class =  ptr[i].event_number;
+			goto out;
+		}
+	}
+
+out:
+	return event_class;
+}
+
+static inline void iommu_pm_add_to_iommu_list(struct iommu_pmon *iommu_pmon)
+{
+	list_add(&iommu_pmon->iommu_list, &iommu_list);
+}
+
+static inline void iommu_pm_del_from_iommu_list(struct iommu_pmon *iommu_pmon)
+{
+	list_del(&iommu_pmon->iommu_list);
+}
+
+static struct iommu_pmon *iommu_pm_get_pm_by_dev(struct device *dev)
+{
+	struct iommu_pmon *pmon;
+	struct iommu_info *info;
+	struct list_head *ent;
+	list_for_each(ent, &iommu_list) {
+		pmon = list_entry(ent, struct iommu_pmon, iommu_list);
+		info = &pmon->iommu;
+		if (dev == info->iommu_dev)
+			return pmon;
+	}
+	return NULL;
+}
+
+static void iommu_pm_set_event_type(struct iommu_pmon *pmon,
+				    struct iommu_pmon_counter *counter)
+{
+	int event_class;
+	unsigned int count_no;
+	struct iommu_info *iommu = &pmon->iommu;
+
+	event_class = counter->current_event_class;
+	count_no = counter->absolute_counter_no;
+
+	if (event_class == MSM_IOMMU_PMU_NO_EVENT_CLASS) {
+		if (iommu->hw_ops->is_hw_access_OK(pmon)) {
+			iommu->ops->iommu_lock_acquire();
+			iommu->hw_ops->counter_disable(iommu, counter);
+			iommu->hw_ops->ovfl_int_disable(iommu, counter);
+			iommu->hw_ops->set_event_class(pmon, count_no, 0);
+			iommu->ops->iommu_lock_release();
+		}
+		counter->overflow_count = 0;
+		counter->value = 0;
+	} else {
+		counter->overflow_count = 0;
+		counter->value = 0;
+		if (iommu->hw_ops->is_hw_access_OK(pmon)) {
+			iommu->ops->iommu_lock_acquire();
+			iommu->hw_ops->set_event_class(pmon, count_no,
+					event_class);
+			iommu->hw_ops->ovfl_int_enable(iommu, counter);
+			iommu->hw_ops->counter_enable(iommu, counter);
+			iommu->ops->iommu_lock_release();
+		}
+	}
+}
+
+static void iommu_pm_reset_counts(struct iommu_pmon *pmon)
+{
+	unsigned int i;
+	unsigned int j;
+	for (i = 0; i < pmon->num_groups; ++i) {
+		struct iommu_pmon_cnt_group *cnt_grp = &pmon->cnt_grp[i];
+		for (j = 0; j < cnt_grp->num_counters; ++j) {
+			cnt_grp->counters[j].value = 0;
+			cnt_grp->counters[j].overflow_count = 0;
+		}
+	}
+}
+
+static void iommu_pm_set_all_counters(struct iommu_pmon *pmon)
+{
+	unsigned int i;
+	unsigned int j;
+	for (i = 0; i < pmon->num_groups; ++i) {
+		struct iommu_pmon_cnt_group *cnt_grp = &pmon->cnt_grp[i];
+		for (j = 0; j < cnt_grp->num_counters; ++j)
+			iommu_pm_set_event_type(pmon, &cnt_grp->counters[j]);
+	}
+}
+
+static void iommu_pm_read_all_counters(struct iommu_pmon *pmon)
+{
+	unsigned int i;
+	unsigned int j;
+	struct iommu_info *iommu = &pmon->iommu;
+	for (i = 0; i < pmon->num_groups; ++i) {
+		struct iommu_pmon_cnt_group *cnt_grp = &pmon->cnt_grp[i];
+		for (j = 0; j < cnt_grp->num_counters; ++j) {
+			struct iommu_pmon_counter *counter;
+			counter = &cnt_grp->counters[j];
+			counter->value = iommu->hw_ops->read_counter(counter);
+		}
+	}
+}
+
+static void iommu_pm_on(struct iommu_pmon *pmon)
+{
+	unsigned int i;
+	struct iommu_info *iommu = &pmon->iommu;
+	struct msm_iommu_drvdata *iommu_drvdata =
+					dev_get_drvdata(iommu->iommu_dev);
+
+	iommu->ops->iommu_power_on(iommu_drvdata);
+
+	/* Reset counters in HW */
+	iommu->ops->iommu_lock_acquire();
+	iommu->hw_ops->reset_counters(&pmon->iommu);
+	iommu->ops->iommu_lock_release();
+
+	/* Reset SW counters */
+	iommu_pm_reset_counts(pmon);
+
+	pmon->enabled = 1;
+
+	iommu_pm_set_all_counters(pmon);
+
+	iommu->ops->iommu_lock_acquire();
+
+	/* enable all counter group */
+	for (i = 0; i < pmon->num_groups; ++i)
+		iommu->hw_ops->grp_enable(iommu, i);
+
+	/* enable global counters */
+	iommu->hw_ops->enable_pm(iommu);
+	iommu->ops->iommu_lock_release();
+
+	pr_info("%s: TLB performance monitoring turned ON\n",
+		pmon->iommu.iommu_name);
+}
+
+static void iommu_pm_off(struct iommu_pmon *pmon)
+{
+	unsigned int i;
+	struct iommu_info *iommu = &pmon->iommu;
+	struct msm_iommu_drvdata *iommu_drvdata =
+					dev_get_drvdata(iommu->iommu_dev);
+
+	pmon->enabled = 0;
+
+	iommu->ops->iommu_lock_acquire();
+
+	/* disable global counters */
+	iommu->hw_ops->disable_pm(iommu);
+
+	/* Check if we overflowed just before turning off pmon */
+	iommu->hw_ops->check_for_overflow(pmon);
+
+	/* disable all counter group */
+	for (i = 0; i < pmon->num_groups; ++i)
+		iommu->hw_ops->grp_disable(iommu, i);
+
+	/* Update cached copy of counters before turning off power */
+	iommu_pm_read_all_counters(pmon);
+
+	iommu->ops->iommu_lock_release();
+	iommu->ops->iommu_power_off(iommu_drvdata);
+
+	pr_info("%s: TLB performance monitoring turned OFF\n",
+		pmon->iommu.iommu_name);
+}
+
+static int iommu_pm_debug_open(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return 0;
+}
+
+static ssize_t iommu_pm_count_value_read(struct file *fp,
+					 char __user *user_buff,
+					 size_t count, loff_t *pos)
+{
+	size_t rd_cnt;
+	unsigned long long full_count;
+
+	struct iommu_pmon_counter *counter = fp->private_data;
+	struct iommu_pmon *pmon = counter->cnt_group->pmon;
+	struct iommu_info *iommu = &pmon->iommu;
+	char buf[50];
+	size_t len;
+
+	mutex_lock(&pmon->lock);
+
+	if (iommu->hw_ops->is_hw_access_OK(pmon)) {
+		iommu->ops->iommu_lock_acquire();
+		counter->value = iommu->hw_ops->read_counter(counter);
+		iommu->ops->iommu_lock_release();
+	}
+	full_count = (unsigned long long) counter->value +
+		     ((unsigned long long)counter->overflow_count *
+			0x100000000ULL);
+
+	len = snprintf(buf, 50, "%llu\n", full_count);
+	rd_cnt = simple_read_from_buffer(user_buff, count, pos, buf, len);
+	mutex_unlock(&pmon->lock);
+
+	return rd_cnt;
+}
+
+static const struct file_operations cnt_value_file_ops = {
+	.open = iommu_pm_debug_open,
+	.read = iommu_pm_count_value_read,
+};
+
+static ssize_t iommu_pm_event_class_read(struct file *fp,
+					 char __user *user_buff,
+					 size_t count, loff_t *pos)
+{
+	size_t rd_cnt;
+	struct iommu_pmon_counter *counter = fp->private_data;
+	struct iommu_pmon *pmon = counter->cnt_group->pmon;
+	char buf[50];
+	const char *event_class_name;
+	size_t len;
+
+	mutex_lock(&pmon->lock);
+	event_class_name = iommu_pm_find_event_class_name(
+						counter->current_event_class);
+	len = snprintf(buf, 50, "%s\n", event_class_name);
+
+	rd_cnt = simple_read_from_buffer(user_buff, count, pos, buf, len);
+	mutex_unlock(&pmon->lock);
+	return rd_cnt;
+}
+
+static ssize_t iommu_pm_event_class_write(struct file *fp,
+					  const char __user *user_buff,
+					  size_t count, loff_t *pos)
+{
+	size_t wr_cnt;
+	char buf[50];
+	size_t buf_size = sizeof(buf);
+	struct iommu_pmon_counter *counter = fp->private_data;
+	struct iommu_pmon *pmon = counter->cnt_group->pmon;
+	int current_event_class;
+
+	if ((count + *pos) >= buf_size)
+		return -EINVAL;
+
+	mutex_lock(&pmon->lock);
+	current_event_class = counter->current_event_class;
+	wr_cnt = simple_write_to_buffer(buf, buf_size, pos, user_buff, count);
+	if (wr_cnt >= 1) {
+		int rv;
+		long value;
+		buf[wr_cnt-1] = '\0';
+		rv = kstrtol(buf, 10, &value);
+		if (!rv) {
+			counter->current_event_class =
+				iommu_pm_find_event_class(
+					iommu_pm_find_event_class_name(value));
+		} else {
+			counter->current_event_class =
+						iommu_pm_find_event_class(buf);
+	}	}
+
+	if (current_event_class != counter->current_event_class)
+		iommu_pm_set_event_type(pmon, counter);
+
+	mutex_unlock(&pmon->lock);
+	return wr_cnt;
+}
+
+static const struct file_operations event_class_file_ops = {
+	.open = iommu_pm_debug_open,
+	.read = iommu_pm_event_class_read,
+	.write = iommu_pm_event_class_write,
+};
+
+static ssize_t iommu_reset_counters_write(struct file *fp,
+				    const char __user *user_buff,
+				    size_t count, loff_t *pos)
+{
+	size_t wr_cnt;
+	char buf[10];
+	size_t buf_size = sizeof(buf);
+	struct iommu_pmon *pmon = fp->private_data;
+	struct iommu_info *iommu = &pmon->iommu;
+
+	if ((count + *pos) >= buf_size)
+		return -EINVAL;
+
+	mutex_lock(&pmon->lock);
+	wr_cnt = simple_write_to_buffer(buf, buf_size, pos, user_buff, count);
+	if (wr_cnt >= 1) {
+		unsigned long cmd = 0;
+		int rv;
+		buf[wr_cnt-1] = '\0';
+		rv = kstrtoul(buf, 10, &cmd);
+		if (!rv && (cmd == 1)) {
+			if (iommu->hw_ops->is_hw_access_OK(pmon)) {
+				iommu->ops->iommu_lock_acquire();
+				iommu->hw_ops->reset_counters(&pmon->iommu);
+				iommu->ops->iommu_lock_release();
+			}
+			iommu_pm_reset_counts(pmon);
+			pr_info("TLB performance counters reset\n");
+		} else {
+			pr_err("Unknown performance monitor command: %lu\n",
+				cmd);
+		}
+	}
+	mutex_unlock(&pmon->lock);
+	return wr_cnt;
+}
+
+static const struct file_operations reset_file_ops = {
+	.open = iommu_pm_debug_open,
+	.write = iommu_reset_counters_write,
+};
+
+static ssize_t iommu_pm_enable_counters_read(struct file *fp,
+					     char __user *user_buff,
+					     size_t count, loff_t *pos)
+{
+	size_t rd_cnt;
+	char buf[5];
+	size_t len;
+	struct iommu_pmon *pmon = fp->private_data;
+
+	mutex_lock(&pmon->lock);
+	len = snprintf(buf, 5, "%u\n", pmon->enabled);
+	rd_cnt = simple_read_from_buffer(user_buff, count, pos, buf, len);
+	mutex_unlock(&pmon->lock);
+	return rd_cnt;
+}
+
+static ssize_t iommu_pm_enable_counters_write(struct file *fp,
+				     const char __user *user_buff,
+				     size_t count, loff_t *pos)
+{
+	size_t wr_cnt;
+	char buf[10];
+	size_t buf_size = sizeof(buf);
+	struct iommu_pmon *pmon = fp->private_data;
+
+	if ((count + *pos) >= buf_size)
+		return -EINVAL;
+
+	mutex_lock(&pmon->lock);
+	wr_cnt = simple_write_to_buffer(buf, buf_size, pos, user_buff, count);
+	if (wr_cnt >= 1) {
+		unsigned long cmd;
+		int rv;
+		buf[wr_cnt-1] = '\0';
+		rv = kstrtoul(buf, 10, &cmd);
+		if (!rv && (cmd < 2)) {
+			if (pmon->enabled == 1 && cmd == 0) {
+				if (pmon->iommu_attach_count > 0)
+					iommu_pm_off(pmon);
+			} else if (pmon->enabled == 0 && cmd == 1) {
+				/* We can only turn on perf. monitoring if
+				 * iommu is attached. Delay turning on perf.
+				 * monitoring until we are attached.
+				 */
+				if (pmon->iommu_attach_count > 0)
+					iommu_pm_on(pmon);
+				else
+					pmon->enabled = 1;
+			}
+		} else {
+			pr_err("Unknown performance monitor command: %lu\n",
+				cmd);
+		}
+	}
+	mutex_unlock(&pmon->lock);
+	return wr_cnt;
+}
+
+static const struct file_operations event_enable_file_ops = {
+	.open = iommu_pm_debug_open,
+	.read = iommu_pm_enable_counters_read,
+	.write = iommu_pm_enable_counters_write,
+};
+
+static ssize_t iommu_pm_avail_event_cls_read(struct file *fp,
+					     char __user *user_buff,
+					     size_t count, loff_t *pos)
+{
+	size_t rd_cnt = 0;
+	struct iommu_pmon *pmon = fp->private_data;
+	char *buf;
+	size_t len;
+
+	mutex_lock(&pmon->lock);
+
+	len = iommu_pm_create_sup_cls_str(&buf, pmon);
+	if (buf) {
+		rd_cnt = simple_read_from_buffer(user_buff, count, pos,
+						 buf, len);
+		kfree(buf);
+	}
+	mutex_unlock(&pmon->lock);
+	return rd_cnt;
+}
+
+static const struct file_operations available_event_cls_file_ops = {
+	.open = iommu_pm_debug_open,
+	.read = iommu_pm_avail_event_cls_read,
+};
+
+
+
+static int iommu_pm_create_grp_debugfs_counters_hierarchy(
+					struct iommu_pmon_cnt_group *cnt_grp,
+					unsigned int *abs_counter_no)
+{
+	int ret = 0;
+	int j;
+	char name[20];
+
+	for (j = 0; j < cnt_grp->num_counters; ++j) {
+		struct dentry *grp_dir = cnt_grp->group_dir;
+		struct dentry *counter_dir;
+		cnt_grp->counters[j].cnt_group = cnt_grp;
+		cnt_grp->counters[j].counter_no = j;
+		cnt_grp->counters[j].absolute_counter_no = *abs_counter_no;
+		(*abs_counter_no)++;
+		cnt_grp->counters[j].value = 0;
+		cnt_grp->counters[j].overflow_count = 0;
+		cnt_grp->counters[j].current_event_class =
+						MSM_IOMMU_PMU_NO_EVENT_CLASS;
+
+		snprintf(name, 20, "counter%u", j);
+
+		counter_dir = debugfs_create_dir(name, grp_dir);
+
+		if (IS_ERR_OR_NULL(counter_dir)) {
+			pr_err("unable to create counter debugfs dir %s\n",
+				name);
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		cnt_grp->counters[j].counter_dir = counter_dir;
+
+		if (!debugfs_create_file("value", 0644, counter_dir,
+					 &cnt_grp->counters[j],
+					 &cnt_value_file_ops)) {
+			ret = -EIO;
+			goto out;
+		}
+
+		if (!debugfs_create_file("current_event_class", 0644,
+				counter_dir, &cnt_grp->counters[j],
+				&event_class_file_ops)) {
+			ret = -EIO;
+			goto out;
+		}
+	}
+out:
+	return ret;
+}
+
+static int iommu_pm_create_group_debugfs_hierarchy(struct iommu_info *iommu,
+				   struct iommu_pmon *pmon_entry)
+{
+	int i;
+	int ret = 0;
+	char name[20];
+	unsigned int abs_counter_no = 0;
+
+	for (i = 0; i < pmon_entry->num_groups; ++i) {
+		pmon_entry->cnt_grp[i].pmon = pmon_entry;
+		pmon_entry->cnt_grp[i].grp_no = i;
+		pmon_entry->cnt_grp[i].num_counters = pmon_entry->num_counters;
+		pmon_entry->cnt_grp[i].counters =
+			kzalloc(sizeof(*pmon_entry->cnt_grp[i].counters)
+			* pmon_entry->cnt_grp[i].num_counters, GFP_KERNEL);
+
+		if (!pmon_entry->cnt_grp[i].counters) {
+			pr_err("Unable to allocate memory for counters\n");
+			ret = -ENOMEM;
+			goto out;
+		}
+		snprintf(name, 20, "group%u", i);
+		pmon_entry->cnt_grp[i].group_dir = debugfs_create_dir(name,
+							pmon_entry->iommu_dir);
+		if (IS_ERR_OR_NULL(pmon_entry->cnt_grp[i].group_dir)) {
+			pr_err("unable to create group debugfs dir %s\n", name);
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		ret = iommu_pm_create_grp_debugfs_counters_hierarchy(
+						&pmon_entry->cnt_grp[i],
+						&abs_counter_no);
+		if (ret)
+			goto out;
+	}
+out:
+	return ret;
+}
+
+int msm_iommu_pm_iommu_register(struct iommu_pmon *pmon_entry)
+{
+	int ret = 0;
+	struct iommu_info *iommu = &pmon_entry->iommu;
+	int i;
+
+	if (!iommu->ops || !iommu->iommu_name || !iommu->base
+					|| !iommu->iommu_dev) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (!msm_iommu_root_debugfs_dir) {
+		msm_iommu_root_debugfs_dir = debugfs_create_dir("iommu", NULL);
+		if (IS_ERR_OR_NULL(msm_iommu_root_debugfs_dir)) {
+			pr_err("Failed creating iommu debugfs dir \"iommu\"\n");
+			ret = -EIO;
+			goto out;
+		}
+	}
+
+	pmon_entry->cnt_grp = kzalloc(sizeof(*pmon_entry->cnt_grp)
+				      * pmon_entry->num_groups, GFP_KERNEL);
+	if (!pmon_entry->cnt_grp) {
+		pr_err("Unable to allocate memory for counter groups\n");
+		ret = -ENOMEM;
+		goto file_err;
+	}
+	pmon_entry->iommu_dir = debugfs_create_dir(iommu->iommu_name,
+						   msm_iommu_root_debugfs_dir);
+	if (IS_ERR_OR_NULL(pmon_entry->iommu_dir)) {
+		pr_err("unable to create iommu debugfs dir %s\n",
+							iommu->iommu_name);
+		ret = -ENOMEM;
+		goto free_mem;
+	}
+
+	if (!debugfs_create_file("reset_counters", 0644,
+			pmon_entry->iommu_dir, pmon_entry, &reset_file_ops)) {
+		ret = -EIO;
+		goto free_mem;
+	}
+
+	if (!debugfs_create_file("enable_counters", 0644,
+		pmon_entry->iommu_dir, pmon_entry, &event_enable_file_ops)) {
+		ret = -EIO;
+		goto free_mem;
+	}
+
+	if (!debugfs_create_file("available_event_classes", 0644,
+			pmon_entry->iommu_dir, pmon_entry,
+			&available_event_cls_file_ops)) {
+		ret = -EIO;
+		goto free_mem;
+	}
+
+	ret = iommu_pm_create_group_debugfs_hierarchy(iommu, pmon_entry);
+	if (ret)
+		goto free_mem;
+
+	iommu->hw_ops->initialize_hw(pmon_entry);
+
+	if (iommu->evt_irq > 0) {
+		ret = request_threaded_irq(iommu->evt_irq, NULL,
+				iommu->hw_ops->evt_ovfl_int_handler,
+				IRQF_ONESHOT | IRQF_SHARED,
+				"msm_iommu_pmon_nonsecure_irq", pmon_entry);
+		if (ret) {
+			pr_err("Request IRQ %d failed with ret=%d\n",
+								iommu->evt_irq,
+								ret);
+			goto free_mem;
+		}
+	} else {
+		pr_info("%s: Overflow interrupt not available\n", __func__);
+	}
+
+	dev_dbg(iommu->iommu_dev, "%s iommu registered\n", iommu->iommu_name);
+
+	goto out;
+free_mem:
+	if (pmon_entry->cnt_grp) {
+		for (i = 0; i < pmon_entry->num_groups; ++i) {
+			kfree(pmon_entry->cnt_grp[i].counters);
+			pmon_entry->cnt_grp[i].counters = 0;
+		}
+	}
+	kfree(pmon_entry->cnt_grp);
+	pmon_entry->cnt_grp = 0;
+file_err:
+	debugfs_remove_recursive(msm_iommu_root_debugfs_dir);
+out:
+	return ret;
+}
+EXPORT_SYMBOL(msm_iommu_pm_iommu_register);
+
+void msm_iommu_pm_iommu_unregister(struct device *dev)
+{
+	int i;
+	struct iommu_pmon *pmon_entry = iommu_pm_get_pm_by_dev(dev);
+
+	if (!pmon_entry)
+		return;
+
+	free_irq(pmon_entry->iommu.evt_irq, pmon_entry->iommu.iommu_dev);
+
+	if (!pmon_entry)
+		goto remove_debugfs;
+
+	if (pmon_entry->cnt_grp) {
+		for (i = 0; i < pmon_entry->num_groups; ++i)
+			kfree(pmon_entry->cnt_grp[i].counters);
+	}
+
+	kfree(pmon_entry->cnt_grp);
+
+remove_debugfs:
+	debugfs_remove_recursive(msm_iommu_root_debugfs_dir);
+
+	return;
+}
+EXPORT_SYMBOL(msm_iommu_pm_iommu_unregister);
+
+struct iommu_pmon *msm_iommu_pm_alloc(struct device *dev)
+{
+	struct iommu_pmon *pmon_entry;
+	struct iommu_info *info;
+	pmon_entry = devm_kzalloc(dev, sizeof(*pmon_entry), GFP_KERNEL);
+	if (!pmon_entry)
+		return NULL;
+	info = &pmon_entry->iommu;
+	info->iommu_dev = dev;
+	mutex_init(&pmon_entry->lock);
+	iommu_pm_add_to_iommu_list(pmon_entry);
+	return pmon_entry;
+}
+EXPORT_SYMBOL(msm_iommu_pm_alloc);
+
+void msm_iommu_pm_free(struct device *dev)
+{
+	struct iommu_pmon *pmon = iommu_pm_get_pm_by_dev(dev);
+	if (pmon)
+		iommu_pm_del_from_iommu_list(pmon);
+}
+EXPORT_SYMBOL(msm_iommu_pm_free);
+
+void msm_iommu_attached(struct device *dev)
+{
+	struct iommu_pmon *pmon = iommu_pm_get_pm_by_dev(dev);
+	if (pmon) {
+		mutex_lock(&pmon->lock);
+		++pmon->iommu_attach_count;
+		if (pmon->iommu_attach_count == 1) {
+			/* If perf. mon was enabled before we attached we do
+			 * the actual after we attach.
+			 */
+			if (pmon->enabled)
+				iommu_pm_on(pmon);
+		}
+		mutex_unlock(&pmon->lock);
+	}
+}
+EXPORT_SYMBOL(msm_iommu_attached);
+
+void msm_iommu_detached(struct device *dev)
+{
+	struct iommu_pmon *pmon = iommu_pm_get_pm_by_dev(dev);
+	if (pmon) {
+		mutex_lock(&pmon->lock);
+		if (pmon->iommu_attach_count == 1) {
+			/* If perf. mon is still enabled we have to disable
+			 * before we do the detach.
+			 */
+			if (pmon->enabled)
+				iommu_pm_off(pmon);
+		}
+		BUG_ON(pmon->iommu_attach_count == 0);
+		--pmon->iommu_attach_count;
+		mutex_unlock(&pmon->lock);
+	}
+}
+EXPORT_SYMBOL(msm_iommu_detached);
+
diff --git a/drivers/iommu/msm_iommu_sec.c b/drivers/iommu/msm_iommu_sec.c
index a6483b9..4e55bd6 100644
--- a/drivers/iommu/msm_iommu_sec.c
+++ b/drivers/iommu/msm_iommu_sec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 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
@@ -25,10 +25,12 @@
 #include <linux/scatterlist.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/kmemleak.h>
 
 #include <asm/sizes.h>
 
-#include <mach/iommu_hw-v2.h>
+#include <mach/iommu_perfmon.h>
+#include <mach/iommu_hw-v1.h>
 #include <mach/iommu.h>
 #include <mach/scm.h>
 
@@ -78,7 +80,7 @@
 	unsigned int spare;
 	int ret, ptbl_ret = 0;
 
-	for_each_compatible_node(np, NULL, "qcom,msm-smmu-v2")
+	for_each_compatible_node(np, NULL, "qcom,msm-smmu-v1")
 		if (of_find_property(np, "qcom,iommu-secure-id", NULL))
 			break;
 
@@ -120,6 +122,8 @@
 		goto fail_mem;
 	}
 
+	kmemleak_not_leak(buf);
+
 	return 0;
 
 fail_mem:
@@ -362,6 +366,11 @@
 	}
 
 	ret = msm_iommu_sec_program_iommu(iommu_drvdata->sec_id);
+
+	/* bfb settings are always programmed by HLOS */
+	program_iommu_bfb_settings(iommu_drvdata->base,
+				   iommu_drvdata->bfb_settings);
+
 	__disable_clocks(iommu_drvdata);
 	if (ret) {
 		regulator_disable(iommu_drvdata->gdsc);
@@ -371,6 +380,10 @@
 	list_add(&(ctx_drvdata->attached_elm), &priv->list_attached);
 	ctx_drvdata->attached_domain = domain;
 
+	mutex_unlock(&msm_iommu_lock);
+
+	msm_iommu_attached(dev->parent);
+	return ret;
 fail:
 	mutex_unlock(&msm_iommu_lock);
 	return ret;
@@ -382,6 +395,8 @@
 	struct msm_iommu_drvdata *iommu_drvdata;
 	struct msm_iommu_ctx_drvdata *ctx_drvdata;
 
+	msm_iommu_detached(dev->parent);
+
 	mutex_lock(&msm_iommu_lock);
 	if (!dev)
 		goto fail;
diff --git a/drivers/leds/leds-msm-pdm.c b/drivers/leds/leds-msm-pdm.c
index 467026b..9660cd2 100644
--- a/drivers/leds/leds-msm-pdm.c
+++ b/drivers/leds/leds-msm-pdm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/leds/leds-msm-pmic.c b/drivers/leds/leds-msm-pmic.c
index b9c6a53..35be94e 100644
--- a/drivers/leds/leds-msm-pmic.c
+++ b/drivers/leds/leds-msm-pmic.c
@@ -1,7 +1,7 @@
 /*
  * leds-msm-pmic.c - MSM PMIC LEDs driver.
  *
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, 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
diff --git a/drivers/leds/leds-msm-tricolor.c b/drivers/leds/leds-msm-tricolor.c
index d0715ce..60ceb26 100644
--- a/drivers/leds/leds-msm-tricolor.c
+++ b/drivers/leds/leds-msm-tricolor.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/leds/leds-pm8xxx.c b/drivers/leds/leds-pm8xxx.c
index f493129..c3a5564 100644
--- a/drivers/leds/leds-pm8xxx.c
+++ b/drivers/leds/leds-pm8xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -53,6 +53,9 @@
 #define WLED_BOOST_CFG_REG		SSBI_REG_ADDR_WLED_CTRL(14)
 #define WLED_HIGH_POLE_CAP_REG		SSBI_REG_ADDR_WLED_CTRL(16)
 
+#define WLED_STRING_ONE			0	/* Rightmost string */
+#define WLED_STRING_TWO			1	/* Middle string */
+#define WLED_STRING_THREE		2	/* Leftmost string */
 #define WLED_STRINGS			0x03
 #define WLED_OVP_VAL_MASK		0x30
 #define WLED_OVP_VAL_BIT_SHFT		0x04
@@ -87,10 +90,6 @@
 #define TWO_WLED_STRINGS		2
 #define THREE_WLED_STRINGS		3
 
-#define WLED_CABC_ONE_STRING		0x01
-#define WLED_CABC_TWO_STRING		0x03
-#define WLED_CABC_THREE_STRING		0x07
-
 #define WLED_CABC_SHIFT			3
 
 #define SSBI_REG_ADDR_RGB_CNTL1		0x12D
@@ -247,7 +246,7 @@
 led_wled_set(struct pm8xxx_led_data *led, enum led_brightness value)
 {
 	int rc, duty;
-	u8 val, i, num_wled_strings;
+	u8 val, i;
 
 	if (value > WLED_MAX_LEVEL)
 		value = WLED_MAX_LEVEL;
@@ -272,36 +271,41 @@
 
 	duty = (WLED_MAX_DUTY_CYCLE * value) / WLED_MAX_LEVEL;
 
-	num_wled_strings = led->wled_cfg->num_strings;
-
 	/* program brightness control registers */
-	for (i = 0; i < num_wled_strings; i++) {
-		rc = pm8xxx_readb(led->dev->parent,
-				WLED_BRIGHTNESS_CNTL_REG1(i), &val);
-		if (rc) {
-			dev_err(led->dev->parent, "can't read wled brightnes ctrl"
-				" register1 rc=%d\n", rc);
-			return rc;
-		}
+	for (i = 0; i < WLED_STRINGS; i++) {
+		if (led->wled_cfg->strings && (1 << i)) {
+			rc = pm8xxx_readb(led->dev->parent,
+					WLED_BRIGHTNESS_CNTL_REG1(i), &val);
+			if (rc) {
+				dev_err(led->dev->parent,
+					"can't read wled brightnes ctrl"
+					" register1 rc=%d\n", rc);
+				return rc;
+			}
 
-		val = (val & ~WLED_BRIGHTNESS_MSB_MASK) |
-			(duty >> WLED_8_BIT_SHFT);
-		rc = pm8xxx_writeb(led->dev->parent,
-				WLED_BRIGHTNESS_CNTL_REG1(i), val);
-		if (rc) {
-			dev_err(led->dev->parent, "can't write wled brightness ctrl"
-				" register1 rc=%d\n", rc);
-			return rc;
-		}
+			val = (val & ~WLED_MAX_CURR_MASK) |
+				(duty >> WLED_8_BIT_SHFT);
 
-		val = duty & WLED_8_BIT_MASK;
-		rc = pm8xxx_writeb(led->dev->parent,
-				WLED_BRIGHTNESS_CNTL_REG2(i), val);
-		if (rc) {
-			dev_err(led->dev->parent, "can't write wled brightness ctrl"
-				" register2 rc=%d\n", rc);
-			return rc;
-		}
+			rc = pm8xxx_writeb(led->dev->parent,
+					WLED_BRIGHTNESS_CNTL_REG1(i), val);
+			if (rc) {
+				dev_err(led->dev->parent,
+					"can't write wled brightness ctrl"
+					" register1 rc=%d\n", rc);
+				return rc;
+			}
+
+			val = duty & WLED_8_BIT_MASK;
+			rc = pm8xxx_writeb(led->dev->parent,
+					WLED_BRIGHTNESS_CNTL_REG2(i), val);
+			if (rc) {
+				dev_err(led->dev->parent,
+					"can't write wled brightness ctrl"
+					" register2 rc=%d\n", rc);
+				return rc;
+			}
+		} else
+			continue;
 	}
 	rc = pm8xxx_readb(led->dev->parent, WLED_SYNC_REG, &val);
 	if (rc) {
@@ -564,9 +568,7 @@
 static int __devinit init_wled(struct pm8xxx_led_data *led)
 {
 	int rc, i;
-	u8 val, num_wled_strings;
-
-	num_wled_strings = led->wled_cfg->num_strings;
+	u8 val, string_max_current;
 
 	/* program over voltage protection threshold */
 	if (led->wled_cfg->ovp_val > WLED_OVP_37V) {
@@ -640,38 +642,61 @@
 	}
 
 	/* program activation delay and maximum current */
-	for (i = 0; i < num_wled_strings; i++) {
-		rc = pm8xxx_readb(led->dev->parent,
-				WLED_MAX_CURR_CFG_REG(i), &val);
-		if (rc) {
-			dev_err(led->dev->parent, "can't read wled max current"
-				" config register rc=%d\n", rc);
-			return rc;
-		}
+	for (i = 0; i < WLED_STRINGS; i++) {
+		if (led->wled_cfg->strings && (1 << i)) {
+			rc = pm8xxx_readb(led->dev->parent,
+					WLED_MAX_CURR_CFG_REG(i), &val);
+			if (rc) {
+				dev_err(led->dev->parent,
+					"can't read wled max current"
+					" config register rc=%d\n", rc);
+				return rc;
+			}
 
-		if ((led->wled_cfg->ctrl_delay_us % WLED_CTL_DLY_STEP) ||
-			(led->wled_cfg->ctrl_delay_us > WLED_CTL_DLY_MAX)) {
-			dev_err(led->dev->parent, "Invalid control delay\n");
-			return rc;
-		}
+			if ((led->wled_cfg->ctrl_delay_us % WLED_CTL_DLY_STEP)
+				|| (led->wled_cfg->ctrl_delay_us >
+					WLED_CTL_DLY_MAX)) {
+				dev_err(led->dev->parent,
+					"Invalid control delay\n");
+				return rc;
+			}
 
-		val = val / WLED_CTL_DLY_STEP;
-		val = (val & ~WLED_CTL_DLY_MASK) |
-			(led->wled_cfg->ctrl_delay_us << WLED_CTL_DLY_BIT_SHFT);
+			val = val / WLED_CTL_DLY_STEP;
+			val = (val & ~WLED_CTL_DLY_MASK) |
+				(led->wled_cfg->ctrl_delay_us <<
+					WLED_CTL_DLY_BIT_SHFT);
 
-		if ((led->max_current > WLED_MAX_CURR)) {
-			dev_err(led->dev->parent, "Invalid max current\n");
-			return -EINVAL;
-		}
+			if ((led->max_current > WLED_MAX_CURR)) {
+				dev_err(led->dev->parent,
+					"Invalid max current\n");
+				return -EINVAL;
+			}
+		if (led->wled_cfg->max_current_ind) {
+			switch (i) {
+			case WLED_STRING_ONE:
+				string_max_current = led->wled_cfg->max_one;
+				break;
+			case WLED_STRING_TWO:
+				string_max_current = led->wled_cfg->max_two;
+				break;
+			case WLED_STRING_THREE:
+				string_max_current = led->wled_cfg->max_three;
+				break;
+			default:
+				return -EINVAL;
+			}
+			val = (val & ~WLED_MAX_CURR_MASK) | string_max_current;
+		} else
+			val = (val & ~WLED_MAX_CURR_MASK) | led->max_current;
 
-		val = (val & ~WLED_MAX_CURR_MASK) | led->max_current;
-
-		rc = pm8xxx_writeb(led->dev->parent,
-				WLED_MAX_CURR_CFG_REG(i), val);
-		if (rc) {
-			dev_err(led->dev->parent, "can't write wled max current"
-				" config register rc=%d\n", rc);
-			return rc;
+			rc = pm8xxx_writeb(led->dev->parent,
+					WLED_MAX_CURR_CFG_REG(i), val);
+			if (rc) {
+				dev_err(led->dev->parent,
+					"can't write wled max current"
+					" config register rc=%d\n", rc);
+				return rc;
+			}
 		}
 	}
 
@@ -683,19 +708,7 @@
 			return rc;
 		}
 
-		switch (num_wled_strings) {
-		case ONE_WLED_STRING:
-			val |= (WLED_CABC_ONE_STRING << WLED_CABC_SHIFT);
-			break;
-		case TWO_WLED_STRINGS:
-			val |= (WLED_CABC_TWO_STRING << WLED_CABC_SHIFT);
-			break;
-		case THREE_WLED_STRINGS:
-			val |= (WLED_CABC_THREE_STRING << WLED_CABC_SHIFT);
-			break;
-		default:
-			break;
-		}
+		val |= (led->wled_cfg->strings << WLED_CABC_SHIFT);
 
 		rc = pm8xxx_writeb(led->dev->parent, WLED_SYNC_REG, val);
 		if (rc) {
diff --git a/drivers/leds/leds-pmic-mpp.c b/drivers/leds/leds-pmic-mpp.c
index a3762be..62ea96b 100644
--- a/drivers/leds/leds-pmic-mpp.c
+++ b/drivers/leds/leds-pmic-mpp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/leds/leds-pmic8058.c b/drivers/leds/leds-pmic8058.c
index 0ba3f58..0af3ba2 100644
--- a/drivers/leds/leds-pmic8058.c
+++ b/drivers/leds/leds-pmic8058.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/leds/leds-qpnp.c b/drivers/leds/leds-qpnp.c
index e7d514e..fb1882c 100644
--- a/drivers/leds/leds-qpnp.c
+++ b/drivers/leds/leds-qpnp.c
@@ -1,5 +1,5 @@
 
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -22,10 +22,12 @@
 #include <linux/of_device.h>
 #include <linux/spmi.h>
 #include <linux/qpnp/pwm.h>
+#include <linux/workqueue.h>
 
 #define WLED_MOD_EN_REG(base, n)	(base + 0x60 + n*0x10)
 #define WLED_IDAC_DLY_REG(base, n)	(WLED_MOD_EN_REG(base, n) + 0x01)
 #define WLED_FULL_SCALE_REG(base, n)	(WLED_IDAC_DLY_REG(base, n) + 0x01)
+#define WLED_MOD_SRC_SEL_REG(base, n)	(WLED_FULL_SCALE_REG(base, n) + 0x01)
 
 /* wled control registers */
 #define WLED_BRIGHTNESS_CNTL_LSB(base, n)	(base + 0x40 + 2*n)
@@ -82,7 +84,7 @@
 #define FLASH_LED_1_CURR(base)		(base + 0x43)
 #define FLASH_CLAMP_CURR(base)		(base + 0x44)
 #define FLASH_LED_TMR_CTRL(base)	(base + 0x48)
-#define FLASH_HEADROOM(base)		(base + 0x49)
+#define FLASH_HEADROOM(base)		(base + 0x4A)
 #define FLASH_STARTUP_DELAY(base)	(base + 0x4B)
 #define FLASH_MASK_ENABLE(base)		(base + 0x4C)
 #define FLASH_VREG_OK_FORCE(base)	(base + 0x4F)
@@ -110,7 +112,7 @@
 #define FLASH_ENABLE_MODULE		0x80
 #define FLASH_ENABLE_MODULE_MASK	0x80
 #define FLASH_DISABLE_ALL		0x00
-#define FLASH_ENABLE_MASK		0x60
+#define FLASH_ENABLE_MASK		0xE0
 #define FLASH_ENABLE_LED_0		0x40
 #define FLASH_ENABLE_LED_1		0x20
 #define FLASH_INIT_MASK			0xE0
@@ -294,6 +296,7 @@
 /**
  * struct qpnp_led_data - internal led data structure
  * @led_classdev - led class device
+ * @delayed_work - delayed work for turning off the LED
  * @id - led index
  * @base_reg - base register given in device tree
  * @lock - to protect the transactions
@@ -301,10 +304,12 @@
  * @num_leds - number of leds in the module
  * @max_current - maximum current supported by LED
  * @default_on - true: default state max, false, default state 0
+ * @turn_off_delay_ms - number of msec before turning off the LED
  */
 struct qpnp_led_data {
 	struct led_classdev	cdev;
 	struct spmi_device	*spmi_dev;
+	struct delayed_work	dwork;
 	int			id;
 	u16			base;
 	u8			reg;
@@ -315,6 +320,7 @@
 	struct rgb_config_data	*rgb_cfg;
 	int			max_current;
 	bool			default_on;
+	int			turn_off_delay_ms;
 };
 
 static int
@@ -449,6 +455,14 @@
 
 	/* Set led current */
 	if (val > 0) {
+		rc = qpnp_led_masked_write(led, FLASH_ENABLE_CONTROL(led->base),
+			FLASH_ENABLE_MODULE_MASK, FLASH_ENABLE_MODULE);
+		if (rc) {
+			dev_err(&led->spmi_dev->dev,
+				"Enable reg write failed(%d)\n", rc);
+			return rc;
+		}
+
 		rc = qpnp_led_masked_write(led, led->flash_cfg->current_addr,
 			FLASH_CURRENT_MASK, led->flash_cfg->current_prgm);
 		if (rc) {
@@ -482,6 +496,13 @@
 				"LED %d flash write failed(%d)\n", led->id, rc);
 			return rc;
 		}
+		rc = qpnp_led_masked_write(led, FLASH_VREG_OK_FORCE(led->base),
+			FLASH_VREG_MASK, FLASH_HW_VREG_OK);
+		if (rc) {
+			dev_err(&led->spmi_dev->dev,
+				"Vreg OK reg write failed(%d)\n", rc);
+			return rc;
+		}
 	} else {
 		rc = qpnp_led_masked_write(led, FLASH_ENABLE_CONTROL(led->base),
 			FLASH_ENABLE_MASK,
@@ -627,6 +648,23 @@
 	return led->cdev.brightness;
 }
 
+static void qpnp_led_turn_off_delayed(struct work_struct *work)
+{
+	struct delayed_work *dwork = to_delayed_work(work);
+	struct qpnp_led_data *led
+		= container_of(dwork, struct qpnp_led_data, dwork);
+
+	led->cdev.brightness = LED_OFF;
+	qpnp_led_set(&led->cdev, led->cdev.brightness);
+}
+
+static void qpnp_led_turn_off(struct qpnp_led_data *led)
+{
+	INIT_DELAYED_WORK(&led->dwork, qpnp_led_turn_off_delayed);
+	schedule_delayed_work(&led->dwork,
+		msecs_to_jiffies(led->turn_off_delay_ms));
+}
+
 static int __devinit qpnp_wled_init(struct qpnp_led_data *led)
 {
 	int rc, i;
@@ -703,7 +741,8 @@
 	if (led->wled_cfg->cs_out_en) {
 		rc = qpnp_led_masked_write(led, WLED_CURR_SINK_REG(led->base),
 			WLED_CURR_SINK_MASK,
-			(led->wled_cfg->num_strings << WLED_CURR_SINK_SHFT));
+			(((1 << led->wled_cfg->num_strings) - 1)
+			<< WLED_CURR_SINK_SHFT));
 		if (rc) {
 			dev_err(&led->spmi_dev->dev,
 				"WLED curr sink reg write failed(%d)\n", rc);
@@ -732,7 +771,7 @@
 
 		if (led->wled_cfg->dig_mod_gen_en) {
 			rc = qpnp_led_masked_write(led,
-				WLED_MOD_EN_REG(led->base, i),
+				WLED_MOD_SRC_SEL_REG(led->base, i),
 				WLED_NO_MASK, WLED_USE_EXT_GEN_MOD_SRC);
 			if (rc) {
 				dev_err(&led->spmi_dev->dev,
@@ -860,7 +899,7 @@
 	}
 
 	rc = qpnp_led_masked_write(led, FLASH_ENABLE_CONTROL(led->base),
-		FLASH_ENABLE_MODULE_MASK, FLASH_ENABLE_MODULE);
+		FLASH_ENABLE_MODULE_MASK, FLASH_DISABLE_ALL);
 	if (rc) {
 		dev_err(&led->spmi_dev->dev,
 			"Enable reg write failed(%d)\n", rc);
@@ -978,6 +1017,7 @@
 				struct device_node *node)
 {
 	int rc;
+	u32 val;
 	const char *temp_string;
 
 	led->cdev.default_trigger = LED_TRIGGER_DEFAULT;
@@ -997,6 +1037,13 @@
 	} else if (rc != -EINVAL)
 		return rc;
 
+	led->turn_off_delay_ms = 0;
+	rc = of_property_read_u32(node, "qcom,turn-off-delay-ms", &val);
+	if (!rc)
+		led->turn_off_delay_ms = val;
+	else if (rc != -EINVAL)
+		return rc;
+
 	return 0;
 }
 
@@ -1383,9 +1430,11 @@
 			goto fail_id_check;
 		}
 		/* configure default state */
-		if (led->default_on)
+		if (led->default_on) {
 			led->cdev.brightness = led->cdev.max_brightness;
-		else
+			if (led->turn_off_delay_ms > 0)
+				qpnp_led_turn_off(led);
+		} else
 			led->cdev.brightness = LED_OFF;
 
 		qpnp_led_set(&led->cdev, led->cdev.brightness);
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index 9575db4..890037a 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -106,6 +106,8 @@
 source "drivers/media/common/Kconfig"
 source "drivers/media/rc/Kconfig"
 
+source "drivers/media/platform/Kconfig"
+
 #
 # Tuner drivers for DVB and V4L
 #
diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index 64755c9..133a74f 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -8,7 +8,7 @@
   obj-$(CONFIG_MEDIA_SUPPORT) += media.o
 endif
 
-obj-y += common/ rc/ video/
+obj-y += common/ platform/ rc/ video/
 
 obj-$(CONFIG_VIDEO_DEV) += radio/
 obj-$(CONFIG_DVB_CORE)  += dvb/
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
index 915dcaa..f6e40b3 100644
--- a/drivers/media/dvb/Kconfig
+++ b/drivers/media/dvb/Kconfig
@@ -88,8 +88,4 @@
 	depends on DVB_CORE
 source "drivers/media/dvb/frontends/Kconfig"
 
-comment "Qualcomm MPQ adapter"
-	depends on ARCH_MSM && DVB_CORE
-source "drivers/media/dvb/mpq/Kconfig"
-
 endif # DVB_CAPTURE_DRIVERS
diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile
index d3438d6..b2cefe6 100644
--- a/drivers/media/dvb/Makefile
+++ b/drivers/media/dvb/Makefile
@@ -19,5 +19,3 @@
 		ddbridge/
 
 obj-$(CONFIG_DVB_FIREDTV)	+= firewire/
-obj-$(CONFIG_DVB_MPQ)		+= mpq/
-
diff --git a/drivers/media/dvb/dvb-core/demux.h b/drivers/media/dvb/dvb-core/demux.h
index f802a38..1c15a41 100644
--- a/drivers/media/dvb/dvb-core/demux.h
+++ b/drivers/media/dvb/dvb-core/demux.h
@@ -7,7 +7,7 @@
  * Copyright (c) 2000 Nokia Research Center
  *                    Tampere, FINLAND
  *
- * Copyright (c) 2012, Code Aurora Forum. 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 Lesser General Public License
@@ -64,14 +64,15 @@
 
 enum dmx_success {
 	DMX_OK = 0, /* Received Ok */
-	DMX_OK_PES_END, /* Received ok, data reached end of PES packet */
+	DMX_OK_PES_END, /* Received OK, data reached end of PES packet */
 	DMX_OK_PCR, /* Received OK, data with new PCR/STC pair */
 	DMX_LENGTH_ERROR, /* Incorrect length */
 	DMX_OVERRUN_ERROR, /* Receiver ring buffer overrun */
 	DMX_CRC_ERROR, /* Incorrect CRC */
 	DMX_FRAME_ERROR, /* Frame alignment error */
 	DMX_FIFO_ERROR, /* Receiver FIFO overrun */
-	DMX_MISSED_ERROR /* Receiver missed packet */
+	DMX_MISSED_ERROR, /* Receiver missed packet */
+	DMX_OK_DECODER_BUF /* Received OK, new ES data in decoder buffer */
 } ;
 
 
@@ -99,6 +100,9 @@
 			int disc_indicator_set;
 			int pes_length_mismatch;
 			u64 stc;
+			u32 tei_counter;
+			u32 cont_err_counter;
+			u32 ts_packets_num;
 		} pes_end;
 
 		struct {
@@ -106,6 +110,21 @@
 			u64 stc;
 			int disc_indicator_set;
 		} pcr;
+
+		struct {
+			int handle;
+			int cookie;
+			u32 offset;
+			u32 len;
+			int pts_exists;
+			u64 pts;
+			int dts_exists;
+			u64 dts;
+			u32 tei_counter;
+			u32 cont_err_counter;
+			u32 ts_packets_num;
+			u32 ts_dropped_bytes;
+		} buf;
 	};
 };
 
@@ -188,6 +207,7 @@
 	struct dmx_demux *parent; /* Back-pointer */
 	struct data_buffer buffer;
 	void *priv; /* Pointer to private data of the API client */
+	struct dmx_decoder_buffers *decoder_buffers;
 	int (*set) (struct dmx_ts_feed *feed,
 		    u16 pid,
 		    int type,
@@ -201,12 +221,17 @@
 	int (*get_decoder_buff_status)(
 			struct dmx_ts_feed *feed,
 			struct dmx_buffer_status *dmx_buffer_status);
+	int (*reuse_decoder_buffer)(
+			struct dmx_ts_feed *feed,
+			int cookie);
 	int (*data_ready_cb)(struct dmx_ts_feed *feed,
 			dmx_ts_data_ready_cb callback);
 	int (*notify_data_read)(struct dmx_ts_feed *feed,
 			u32 bytes_num);
-	int (*set_tsp_out_format) (struct dmx_ts_feed *feed,
+	int (*set_tsp_out_format)(struct dmx_ts_feed *feed,
 				enum dmx_tsp_format_t tsp_format);
+	int (*set_secure_mode)(struct dmx_ts_feed *feed,
+				struct dmx_secure_mode *sec_mode);
 };
 
 /*--------------------------------------------------------------------------*/
@@ -253,6 +278,8 @@
 			dmx_section_data_ready_cb callback);
 	int (*notify_data_read)(struct dmx_section_filter *filter,
 			u32 bytes_num);
+	int (*set_secure_mode)(struct dmx_section_feed *feed,
+				struct dmx_secure_mode *sec_mode);
 };
 
 /*--------------------------------------------------------------------------*/
@@ -337,7 +364,6 @@
 	struct dmx_frontend* frontend;    /* Front-end connected to the demux */
 	void* priv;                  /* Pointer to private data of the API client */
 	struct data_buffer dvr_input; /* DVR input buffer */
-
 	struct dentry *debugfs_demux_dir; /* debugfs dir */
 
 	int (*open) (struct dmx_demux* demux);
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index 507c014..52b7994 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -4,7 +4,7 @@
  * Copyright (C) 2000 Ralph Metzler & Marcus Metzler
  *		      for convergence integrated media GmbH
  *
- * Copyright (c) 2012, Code Aurora Forum. 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 Lesser General Public License
@@ -31,7 +31,7 @@
 #include <linux/ioctl.h>
 #include <linux/wait.h>
 #include <linux/mm.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 #include "dmxdev.h"
@@ -41,6 +41,8 @@
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
 
+#define DMX_DEFAULT_DECODER_BUFFER_SIZE (32768)
+
 #define dprintk	if (debug) printk
 
 static int dvb_dmxdev_buffer_write(struct dvb_ringbuffer *buf,
@@ -69,8 +71,8 @@
 		return;
 
 	if (filter->type == DMXDEV_TYPE_SEC) {
-		if (filter->feed.sec->notify_data_read)
-			filter->feed.sec->notify_data_read(
+		if (filter->feed.sec.feed->notify_data_read)
+			filter->feed.sec.feed->notify_data_read(
 						filter->filter.sec,
 						bytes_read);
 	} else {
@@ -312,7 +314,7 @@
 		if (data_event) {
 			if (res) {
 				/*
-				 * Data relevent to this event was
+				 * Data relevant to this event was
 				 * fully consumed, remove it from the queue.
 				 */
 				bytes_read -= res;
@@ -471,18 +473,19 @@
 	struct dvb_ringbuffer *src = &dmxdev->dvr_input_buffer;
 	int ret;
 	size_t todo;
+	int bytes_written;
 	size_t split;
 
 	while (1) {
 		/* wait for input */
-		ret = wait_event_interruptible(src->queue,
-						   (!src->data) ||
-					       (dvb_ringbuffer_avail(src)) ||
-					       (src->error != 0) ||
-					       (dmxdev->dvr_in_exit) ||
-					       kthread_should_stop());
+		ret = wait_event_interruptible(
+			src->queue,
+			(!src->data) ||
+			(dvb_ringbuffer_avail(src) > 188) ||
+			(src->error != 0) ||
+			dmxdev->dvr_in_exit);
 
-		if ((ret < 0) || kthread_should_stop())
+		if (ret < 0)
 			break;
 
 		spin_lock(&dmxdev->dvr_in_lock);
@@ -511,40 +514,66 @@
 		 * In DVR PULL mode, write might block.
 		 * Lock on DVR buffer is released before calling to
 		 * write, if DVR was released meanwhile, dvr_in_exit is
-		 * prompted. Lock is aquired when updating the read pointer
-		 * again to preserve read/write pointers consistancy
+		 * prompted. Lock is acquired when updating the read pointer
+		 * again to preserve read/write pointers consistency
 		 */
 		if (split > 0) {
 			spin_unlock(&dmxdev->dvr_in_lock);
-			dmxdev->demux->write(dmxdev->demux,
+			bytes_written = dmxdev->demux->write(dmxdev->demux,
 						src->data + src->pread,
 						split);
 
+			if (bytes_written < 0) {
+				printk(KERN_ERR "dmxdev: dvr write error %d\n",
+					bytes_written);
+				continue;
+			}
+
 			if (dmxdev->dvr_in_exit)
 				break;
 
 			spin_lock(&dmxdev->dvr_in_lock);
 
-			todo -= split;
-			DVB_RINGBUFFER_SKIP(src, split);
+			todo -= bytes_written;
+			DVB_RINGBUFFER_SKIP(src, bytes_written);
+			if (bytes_written < split) {
+				dmxdev->dvr_processing_input = 0;
+				spin_unlock(&dmxdev->dvr_in_lock);
+				wake_up_all(&src->queue);
+				continue;
+			}
+
 		}
 
 		spin_unlock(&dmxdev->dvr_in_lock);
-		dmxdev->demux->write(dmxdev->demux,
+		bytes_written = dmxdev->demux->write(dmxdev->demux,
 					src->data + src->pread, todo);
 
+		if (bytes_written < 0) {
+			printk(KERN_ERR "dmxdev: dvr write error %d\n",
+				bytes_written);
+			continue;
+		}
+
 		if (dmxdev->dvr_in_exit)
 			break;
 
 		spin_lock(&dmxdev->dvr_in_lock);
 
-		DVB_RINGBUFFER_SKIP(src, todo);
+		DVB_RINGBUFFER_SKIP(src, bytes_written);
 		dmxdev->dvr_processing_input = 0;
 		spin_unlock(&dmxdev->dvr_in_lock);
 
 		wake_up_all(&src->queue);
 	}
 
+	set_current_state(TASK_INTERRUPTIBLE);
+	while (!kthread_should_stop()) {
+		schedule();
+		set_current_state(TASK_INTERRUPTIBLE);
+	}
+	set_current_state(TASK_RUNNING);
+
 	return 0;
 }
 
@@ -880,6 +909,7 @@
 	ssize_t res;
 	struct dvb_device *dvbdev = file->private_data;
 	struct dmxdev *dmxdev = dvbdev->priv;
+	ssize_t flush_len;
 
 	if (dmxdev->exit)
 		return -ENODEV;
@@ -902,16 +932,16 @@
 			wake_up_all(&dmxdev->dvr_buffer.queue);
 	} else if (res == -EOVERFLOW) {
 		/*
-		 * When buffer overflowed, demux-dev flushed the
-		 * buffer and marked the buffer in error state.
+		 * When buffer overflowed, demux-dev marked the buffer in
+		 * error state.
 		 * Data from underlying driver is discarded until
 		 * user gets notified that buffer has overflowed.
 		 * Now that the user is notified, notify underlying
 		 * driver that data was flushed from output buffer.
 		 */
-		dvb_dmxdev_notify_data_read(dmxdev->dvr_feed,
-			dmxdev->dvr_flush_data_len);
-		dmxdev->dvr_flush_data_len = 0;
+		flush_len = dvb_ringbuffer_avail(&dmxdev->dvr_buffer);
+		dvb_ringbuffer_flush(&dmxdev->dvr_buffer);
+		dvb_dmxdev_notify_data_read(dmxdev->dvr_feed, flush_len);
 	}
 
 	return res;
@@ -1081,6 +1111,7 @@
 				struct dmx_filter_event *event)
 {
 	int res;
+	ssize_t flush_len;
 
 	if (!((f_flags & O_ACCMODE) == O_RDONLY))
 		return -EINVAL;
@@ -1091,16 +1122,16 @@
 
 	if (event->type == DMX_EVENT_BUFFER_OVERFLOW) {
 		/*
-		 * When buffer overflowed, demux-dev flushed the
-		 * buffer and marked the buffer in error state.
+		 * When buffer overflowed, demux-dev marked the buffer in
+		 * error state.
 		 * Data from underlying driver is discarded until
 		 * user gets notified that buffer has overflowed.
 		 * Now that the user is notified, notify underlying
 		 * driver that data was flushed from output buffer.
 		 */
-		dvb_dmxdev_notify_data_read(dmxdev->dvr_feed,
-			dmxdev->dvr_flush_data_len);
-		dmxdev->dvr_flush_data_len = 0;
+		flush_len = dvb_ringbuffer_avail(&dmxdev->dvr_buffer);
+		dvb_ringbuffer_flush(&dmxdev->dvr_buffer);
+		dvb_dmxdev_notify_data_read(dmxdev->dvr_feed, flush_len);
 		dmxdev->dvr_buffer.error = 0;
 	}
 
@@ -1122,6 +1153,7 @@
 {
 	struct dvb_ringbuffer *buf;
 	spinlock_t *lock;
+	ssize_t flush_len;
 
 	if ((f_flags & O_ACCMODE) == O_RDONLY) {
 		buf = &dmxdev->dvr_buffer;
@@ -1144,9 +1176,10 @@
 			 * Now that the user is notified, notify underlying
 			 * driver that data was flushed from output buffer.
 			 */
+			flush_len = dvb_ringbuffer_avail(buf);
+			dvb_ringbuffer_flush(buf);
 			dvb_dmxdev_notify_data_read(dmxdev->dvr_feed,
-				dmxdev->dvr_flush_data_len);
-			dmxdev->dvr_flush_data_len = 0;
+				flush_len);
 		}
 
 		buf->error = 0;
@@ -1351,18 +1384,27 @@
 	return 0;
 }
 
-static int dvb_dmxdev_set_pes_buffer_size(struct dmxdev_filter *dmxdevfilter,
-					unsigned long size)
+static int dvb_dmxdev_set_decoder_buffer_size(
+	struct dmxdev_filter *dmxdevfilter,
+	unsigned long size)
 {
-	if (dmxdevfilter->pes_buffer_size == size)
-		return 0;
-	if (!size)
+	if (0 == size)
 		return -EINVAL;
+
+	if (dmxdevfilter->decoder_buffers.buffers_size == size)
+		return 0;
+
 	if (dmxdevfilter->state >= DMXDEV_STATE_GO)
 		return -EBUSY;
 
-	dmxdevfilter->pes_buffer_size = size;
-
+	/*
+	 * In case decoder buffers were already set before to some external
+	 * buffers, setting the decoder buffer size alone implies transition
+	 * to internal buffer mode.
+	 */
+	dmxdevfilter->decoder_buffers.buffers_size = size;
+	dmxdevfilter->decoder_buffers.buffers_num = 0;
+	dmxdevfilter->decoder_buffers.is_linear = 0;
 	return 0;
 }
 
@@ -1384,6 +1426,29 @@
 	return 0;
 }
 
+static int dvb_dmxdev_reuse_decoder_buf(struct dmxdev_filter *dmxdevfilter,
+						int cookie)
+{
+	if ((dmxdevfilter->type == DMXDEV_TYPE_PES) &&
+		(dmxdevfilter->params.pes.output == DMX_OUT_DECODER)) {
+		struct dmxdev_feed *feed;
+		int ret = -ENODEV;
+
+		/* Only one feed should be in the list in case of decoder */
+		feed = list_first_entry(&dmxdevfilter->feed.ts,
+					struct dmxdev_feed, next);
+
+		if (feed->ts->reuse_decoder_buffer)
+			ret = feed->ts->reuse_decoder_buffer(
+							feed->ts,
+							cookie);
+
+		return ret;
+	}
+
+	return -EPERM;
+}
+
 static int dvb_dmxdev_ts_fullness_callback(
 				struct dmx_ts_feed *filter,
 				int required_space)
@@ -1393,8 +1458,7 @@
 	struct dmxdev_events_queue *events;
 	int ret;
 
-	if (dmxdevfilter->params.pes.output == DMX_OUT_TAP
-		|| dmxdevfilter->params.pes.output == DMX_OUT_TSDEMUX_TAP) {
+	if (dmxdevfilter->params.pes.output != DMX_OUT_TS_TAP) {
 		src = &dmxdevfilter->buffer;
 		events = &dmxdevfilter->events;
 	} else {
@@ -1523,12 +1587,14 @@
 		struct dmx_buffer_status *dmx_buffer_status)
 {
 	struct dvb_ringbuffer *buf = &dmxdevfilter->buffer;
+	ssize_t flush_len;
 
-	if (!buf->data)
-		return -EINVAL;
-
-	spin_lock_irq(&dmxdevfilter->dev->lock);
-
+	/*
+	 * Note: Taking the dmxdevfilter->dev->lock spinlock is required only
+	 * when getting the status of the Demux-userspace data ringbuffer .
+	 * In case we are getting the status of a decoder buffer, taking this
+	 * spinlock is not required and in fact might lead to a deadlock.
+	 */
 	if ((dmxdevfilter->type == DMXDEV_TYPE_PES) &&
 		(dmxdevfilter->params.pes.output == DMX_OUT_DECODER)) {
 		struct dmxdev_feed *feed;
@@ -1546,24 +1612,30 @@
 		else
 			ret = -ENODEV;
 
-		spin_unlock_irq(&dmxdevfilter->dev->lock);
 		return ret;
 	}
 
+	spin_lock_irq(&dmxdevfilter->dev->lock);
+
+	if (!buf->data) {
+		spin_unlock_irq(&dmxdevfilter->dev->lock);
+		return -EINVAL;
+	}
+
 	dmx_buffer_status->error = buf->error;
 	if (buf->error) {
 		if (buf->error == -EOVERFLOW) {
 			/*
-			 * When buffer overflowed, demux-dev flushed the
-			 * buffer and marked the buffer in error state.
+			 * When buffer overflowed, demux-dev marked the buffer
+			 * in error state.
 			 * Data from underlying driver is discarded until
 			 * user gets notified that buffer has overflowed.
 			 * Now that the user is notified, notify underlying
 			 * driver that data was flushed from output buffer.
 			 */
-			dvb_dmxdev_notify_data_read(dmxdevfilter,
-				dmxdevfilter->flush_data_len);
-			dmxdevfilter->flush_data_len = 0;
+			flush_len = dvb_ringbuffer_avail(buf);
+			dvb_ringbuffer_flush(buf);
+			dvb_dmxdev_notify_data_read(dmxdevfilter, flush_len);
 		}
 		buf->error = 0;
 	}
@@ -1611,26 +1683,40 @@
 					struct dmx_filter_event *event)
 {
 	int res;
-
+	ssize_t flush_len;
 	spin_lock_irq(&dmxdevfilter->dev->lock);
 
 	res = dvb_dmxdev_remove_event(&dmxdevfilter->events, event);
+	if (res) {
+		spin_unlock_irq(&dmxdevfilter->dev->lock);
+		return res;
+	}
 
 	if (event->type == DMX_EVENT_BUFFER_OVERFLOW) {
 		/*
-		 * When buffer overflowed, demux-dev flushed the
-		 * buffer and marked the buffer in error state.
+		 * When buffer overflowed, demux-dev marked the buffer in
+		 * error state.
 		 * Data from underlying driver is discarded until
 		 * user gets notified that buffer has overflowed.
 		 * Now that the user is notified, notify underlying
 		 * driver that data was flushed from output buffer.
 		 */
-		dvb_dmxdev_notify_data_read(dmxdevfilter,
-			dmxdevfilter->flush_data_len);
-		dmxdevfilter->flush_data_len = 0;
+		flush_len = dvb_ringbuffer_avail(&dmxdevfilter->buffer);
+		dvb_ringbuffer_flush(&dmxdevfilter->buffer);
+		dvb_dmxdev_notify_data_read(dmxdevfilter, flush_len);
 		dmxdevfilter->buffer.error = 0;
 	}
 
+	/*
+	 * Decoder filters have no data in the data buffer and their
+	 * events can be removed now from the queue.
+	 */
+	if ((dmxdevfilter->type == DMXDEV_TYPE_PES) &&
+		(dmxdevfilter->params.pes.output == DMX_OUT_DECODER))
+		dmxdevfilter->events.read_index =
+			dvb_dmxdev_advance_event_idx(
+				dmxdevfilter->events.read_index);
+
 	spin_unlock_irq(&dmxdevfilter->dev->lock);
 
 	/*
@@ -1707,9 +1793,6 @@
 	event.params.section.start_offset = dmxdevfilter->buffer.pwrite;
 
 	del_timer(&dmxdevfilter->timer);
-	dprintk("dmxdev: section callback %02x %02x %02x %02x %02x %02x\n",
-		buffer1[0], buffer1[1],
-		buffer1[2], buffer1[3], buffer1[4], buffer1[5]);
 	ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer1,
 				      buffer1_len);
 	if (ret == buffer1_len)
@@ -1717,10 +1800,7 @@
 					      buffer2_len);
 
 	if (ret < 0) {
-		dmxdevfilter->flush_data_len =
-			dvb_ringbuffer_avail(&dmxdevfilter->buffer);
-		dvb_dmxdev_flush_output(&dmxdevfilter->buffer,
-			&dmxdevfilter->events);
+		dvb_dmxdev_flush_events(&dmxdevfilter->events);
 		dmxdevfilter->buffer.error = ret;
 
 		event.type = DMX_EVENT_BUFFER_OVERFLOW;
@@ -1757,7 +1837,6 @@
 	struct dmxdev_events_queue *events;
 	struct dmx_filter_event event;
 	int ret;
-	u32 *flush_data_len;
 
 	spin_lock(&dmxdevfilter->dev->lock);
 	if (dmxdevfilter->params.pes.output == DMX_OUT_DECODER) {
@@ -1769,11 +1848,9 @@
 	    || dmxdevfilter->params.pes.output == DMX_OUT_TSDEMUX_TAP) {
 		buffer = &dmxdevfilter->buffer;
 		events = &dmxdevfilter->events;
-		flush_data_len = &dmxdevfilter->flush_data_len;
 	} else {
 		buffer = &dmxdevfilter->dev->dvr_buffer;
 		events = &dmxdevfilter->dev->dvr_output_events;
-		flush_data_len = &dmxdevfilter->dev->dvr_flush_data_len;
 	}
 
 	if (buffer->error) {
@@ -1806,6 +1883,9 @@
 
 			event.params.pes.flags = 0;
 			event.params.pes.stc = 0;
+			event.params.pes.transport_error_indicator_counter = 0;
+			event.params.pes.continuity_error_counter = 0;
+			event.params.pes.ts_packets_num = 0;
 
 			dvb_dmxdev_add_event(events, &event);
 			events->current_event_data_size = 0;
@@ -1823,11 +1903,10 @@
 			ret = dvb_dmxdev_buffer_write(buffer, buffer2,
 								buffer2_len);
 		if (ret < 0) {
-			*flush_data_len =
-				dvb_ringbuffer_avail(&dmxdevfilter->buffer);
-			dvb_dmxdev_flush_output(buffer, events);
+			/* Enter buffer overflow state */
+			dprintk("dmxdev: buffer overflow\n");
 			buffer->error = ret;
-
+			dvb_dmxdev_flush_events(events);
 			event.type = DMX_EVENT_BUFFER_OVERFLOW;
 			dvb_dmxdev_add_event(events, &event);
 		} else {
@@ -1897,15 +1976,11 @@
 
 	if ((DMX_OVERRUN_ERROR == dmx_data_ready->status) ||
 		(dmx_data_ready->data_length > free)) {
-		dmxdevfilter->flush_data_len =
-			dvb_ringbuffer_avail(&dmxdevfilter->buffer);
-		dvb_dmxdev_flush_output(&dmxdevfilter->buffer,
-				&dmxdevfilter->events);
 
 		dprintk("dmxdev: buffer overflow\n");
 
 		dmxdevfilter->buffer.error = -EOVERFLOW;
-
+		dvb_dmxdev_flush_events(&dmxdevfilter->events);
 		event.type = DMX_EVENT_BUFFER_OVERFLOW;
 		dvb_dmxdev_add_event(&dmxdevfilter->events, &event);
 		spin_unlock(&dmxdevfilter->dev->lock);
@@ -1940,7 +2015,6 @@
 	struct dvb_ringbuffer *buffer;
 	struct dmxdev_events_queue *events;
 	struct dmx_filter_event event;
-	u32 *flush_data_len;
 	int free;
 
 	spin_lock(&dmxdevfilter->dev->lock);
@@ -1953,20 +2027,19 @@
 	if (dmxdevfilter->params.pes.output != DMX_OUT_TS_TAP) {
 		buffer = &dmxdevfilter->buffer;
 		events = &dmxdevfilter->events;
-		flush_data_len = &dmxdevfilter->flush_data_len;
 	} else {
 		buffer = &dmxdevfilter->dev->dvr_buffer;
 		events = &dmxdevfilter->dev->dvr_output_events;
-		flush_data_len = &dmxdevfilter->dev->dvr_flush_data_len;
 	}
 
 	if (dmx_data_ready->status == DMX_OK_PCR) {
+		dprintk("dmxdev: event callback DMX_OK_PCR\n");
 		event.type = DMX_EVENT_NEW_PCR;
 		event.params.pcr.pcr = dmx_data_ready->pcr.pcr;
 		event.params.pcr.stc = dmx_data_ready->pcr.stc;
 		if (dmx_data_ready->pcr.disc_indicator_set)
 			event.params.pcr.flags =
-				DMX_FILTER_DISCONTINUITY_INDEICATOR;
+				DMX_FILTER_DISCONTINUITY_INDICATOR;
 		else
 			event.params.pcr.flags = 0;
 
@@ -1976,6 +2049,30 @@
 		return 0;
 	}
 
+	if (dmx_data_ready->status == DMX_OK_DECODER_BUF) {
+		event.type = DMX_EVENT_NEW_ES_DATA;
+		event.params.es_data.buf_handle = dmx_data_ready->buf.handle;
+		event.params.es_data.cookie = dmx_data_ready->buf.cookie;
+		event.params.es_data.offset = dmx_data_ready->buf.offset;
+		event.params.es_data.data_len = dmx_data_ready->buf.len;
+		event.params.es_data.pts_valid = dmx_data_ready->buf.pts_exists;
+		event.params.es_data.pts = dmx_data_ready->buf.pts;
+		event.params.es_data.dts_valid = dmx_data_ready->buf.dts_exists;
+		event.params.es_data.dts = dmx_data_ready->buf.dts;
+		event.params.es_data.transport_error_indicator_counter =
+				dmx_data_ready->buf.tei_counter;
+		event.params.es_data.continuity_error_counter =
+				dmx_data_ready->buf.cont_err_counter;
+		event.params.es_data.ts_packets_num =
+				dmx_data_ready->buf.ts_packets_num;
+		event.params.es_data.ts_dropped_bytes =
+				dmx_data_ready->buf.ts_dropped_bytes;
+		dvb_dmxdev_add_event(events, &event);
+		spin_unlock(&dmxdevfilter->dev->lock);
+		wake_up_all(&buffer->queue);
+		return 0;
+	}
+
 	if ((dmxdevfilter->params.pes.output == DMX_OUT_DECODER) ||
 		(buffer->error)) {
 		spin_unlock(&dmxdevfilter->dev->lock);
@@ -1987,14 +2084,17 @@
 
 	if ((DMX_OVERRUN_ERROR == dmx_data_ready->status) ||
 		(dmx_data_ready->data_length > free)) {
-		*flush_data_len =
-				dvb_ringbuffer_avail(&dmxdevfilter->buffer);
-		dvb_dmxdev_flush_output(buffer, events);
 
+		/*
+		 * Enter buffer overflow state:
+		 * Set buffer overflow error state, flush all pending demux
+		 * device events to ensure user can receive the overflow event
+		 * and report the event to user
+		 */
 		dprintk("dmxdev: buffer overflow\n");
 
 		buffer->error = -EOVERFLOW;
-
+		dvb_dmxdev_flush_events(events);
 		event.type = DMX_EVENT_BUFFER_OVERFLOW;
 		dvb_dmxdev_add_event(&dmxdevfilter->events, &event);
 
@@ -2024,12 +2124,19 @@
 			event.params.pes.flags = 0;
 			if (dmx_data_ready->pes_end.disc_indicator_set)
 				event.params.pes.flags |=
-					DMX_FILTER_DISCONTINUITY_INDEICATOR;
+					DMX_FILTER_DISCONTINUITY_INDICATOR;
 			if (dmx_data_ready->pes_end.pes_length_mismatch)
 				event.params.pes.flags |=
 					DMX_FILTER_PES_LENGTH_ERROR;
 
 			event.params.pes.stc = dmx_data_ready->pes_end.stc;
+			event.params.pes.transport_error_indicator_counter =
+				dmx_data_ready->pes_end.tei_counter;
+			event.params.pes.continuity_error_counter =
+				dmx_data_ready->pes_end.cont_err_counter;
+			event.params.pes.ts_packets_num =
+				dmx_data_ready->pes_end.ts_packets_num;
+
 			dvb_dmxdev_add_event(events, &event);
 
 			events->current_event_data_size = 0;
@@ -2074,11 +2181,18 @@
 	switch (dmxdevfilter->type) {
 	case DMXDEV_TYPE_SEC:
 		del_timer(&dmxdevfilter->timer);
-		dmxdevfilter->feed.sec->stop_filtering(dmxdevfilter->feed.sec);
+		dmxdevfilter->feed.sec.feed->stop_filtering(
+			dmxdevfilter->feed.sec.feed);
 		break;
 	case DMXDEV_TYPE_PES:
-		list_for_each_entry(feed, &dmxdevfilter->feed.ts, next)
+		list_for_each_entry(feed, &dmxdevfilter->feed.ts, next) {
+			if (dmxdevfilter->params.pes.output == DMX_OUT_TS_TAP) {
+				dmxdevfilter->dev->dvr_feeds_count--;
+				if (!dmxdevfilter->dev->dvr_feeds_count)
+					dmxdevfilter->dev->dvr_feed = NULL;
+			}
 			feed->ts->stop_filtering(feed->ts);
+		}
 		break;
 	default:
 		return -EINVAL;
@@ -2096,7 +2210,8 @@
 
 	switch (filter->type) {
 	case DMXDEV_TYPE_SEC:
-		return filter->feed.sec->start_filtering(filter->feed.sec);
+		return filter->feed.sec.feed->start_filtering(
+			filter->feed.sec.feed);
 	case DMXDEV_TYPE_PES:
 		list_for_each_entry(feed, &filter->feed.ts, next) {
 			ret = feed->ts->start_filtering(feed->ts);
@@ -2130,7 +2245,7 @@
 		}
 
 	filter->dev->demux->release_section_feed(dmxdev->demux,
-						 filter->feed.sec);
+						 filter->feed.sec.feed);
 
 	return 0;
 }
@@ -2145,25 +2260,19 @@
 
 	switch (dmxdevfilter->type) {
 	case DMXDEV_TYPE_SEC:
-		if (!dmxdevfilter->feed.sec)
+		if (!dmxdevfilter->feed.sec.feed)
 			break;
 		dvb_dmxdev_feed_stop(dmxdevfilter);
 		if (dmxdevfilter->filter.sec)
-			dmxdevfilter->feed.sec->
-			    release_filter(dmxdevfilter->feed.sec,
+			dmxdevfilter->feed.sec.feed->
+			    release_filter(dmxdevfilter->feed.sec.feed,
 					   dmxdevfilter->filter.sec);
 		dvb_dmxdev_feed_restart(dmxdevfilter);
-		dmxdevfilter->feed.sec = NULL;
+		dmxdevfilter->feed.sec.feed = NULL;
 		break;
 	case DMXDEV_TYPE_PES:
 		dvb_dmxdev_feed_stop(dmxdevfilter);
 		demux = dmxdevfilter->dev->demux;
-		if (dmxdevfilter->params.pes.output == DMX_OUT_TS_TAP) {
-			dmxdevfilter->dev->dvr_feeds_count--;
-			if (!dmxdevfilter->dev->dvr_feeds_count)
-				dmxdevfilter->dev->dvr_feed = NULL;
-		}
-
 		list_for_each_entry(feed, &dmxdevfilter->feed.ts, next) {
 			demux->release_ts_feed(demux, feed->ts);
 			feed->ts = NULL;
@@ -2177,6 +2286,7 @@
 
 	spin_lock_irq(&dmxdevfilter->dev->lock);
 	dvb_dmxdev_flush_output(&dmxdevfilter->buffer, &dmxdevfilter->events);
+	dvb_ringbuffer_reset(&dmxdevfilter->buffer);
 	spin_unlock_irq(&dmxdevfilter->dev->lock);
 
 	wake_up_all(&dmxdevfilter->buffer.queue);
@@ -2253,6 +2363,10 @@
 		if (!dmxdev->dvr_feeds_count)
 			dmxdev->dvr_feed = filter;
 		dmxdev->dvr_feeds_count++;
+	} else if (filter->params.pes.output == DMX_OUT_DECODER) {
+		tsfeed->buffer.ringbuff = &filter->buffer;
+		tsfeed->decoder_buffers = &filter->decoder_buffers;
+		tsfeed->buffer.priv_handle = filter->priv_buff_handle;
 	} else {
 		tsfeed->buffer.ringbuff = &filter->buffer;
 		tsfeed->buffer.priv_handle = filter->priv_buff_handle;
@@ -2269,7 +2383,8 @@
 
 	ret = tsfeed->set(tsfeed, feed->pid,
 					ts_type, ts_pes,
-					filter->pes_buffer_size, timeout);
+					filter->decoder_buffers.buffers_size,
+					timeout);
 	if (ret < 0) {
 		dmxdev->demux->release_ts_feed(dmxdev->demux, tsfeed);
 		return ret;
@@ -2278,6 +2393,9 @@
 	if (tsfeed->set_tsp_out_format)
 		tsfeed->set_tsp_out_format(tsfeed, filter->dmx_tsp_format);
 
+	if (tsfeed->set_secure_mode)
+		tsfeed->set_secure_mode(tsfeed, &feed->sec_mode);
+
 	/* Support indexing for video PES */
 	if ((para->pes_type == DMX_PES_VIDEO0) ||
 	    (para->pes_type == DMX_PES_VIDEO1) ||
@@ -2339,7 +2457,7 @@
 	{
 		struct dmx_sct_filter_params *para = &filter->params.sec;
 		struct dmx_section_filter **secfilter = &filter->filter.sec;
-		struct dmx_section_feed **secfeed = &filter->feed.sec;
+		struct dmx_section_feed **secfeed = &filter->feed.sec.feed;
 
 		*secfilter = NULL;
 		*secfeed = NULL;
@@ -2349,7 +2467,7 @@
 			if (dmxdev->filter[i].state >= DMXDEV_STATE_GO &&
 			    dmxdev->filter[i].type == DMXDEV_TYPE_SEC &&
 			    dmxdev->filter[i].params.sec.pid == para->pid) {
-				*secfeed = dmxdev->filter[i].feed.sec;
+				*secfeed = dmxdev->filter[i].feed.sec.feed;
 				break;
 			}
 		}
@@ -2386,6 +2504,10 @@
 				dvb_dmxdev_feed_restart(filter);
 				return ret;
 			}
+
+			if ((*secfeed)->set_secure_mode)
+				(*secfeed)->set_secure_mode(*secfeed,
+					&filter->feed.sec.sec_mode);
 		} else {
 			dvb_dmxdev_feed_stop(filter);
 		}
@@ -2393,7 +2515,7 @@
 		ret = (*secfeed)->allocate_filter(*secfeed, secfilter);
 		if (ret < 0) {
 			dvb_dmxdev_feed_restart(filter);
-			filter->feed.sec->start_filtering(*secfeed);
+			filter->feed.sec.feed->start_filtering(*secfeed);
 			dprintk("could not get filter\n");
 			return ret;
 		}
@@ -2417,7 +2539,8 @@
 
 		filter->todo = 0;
 
-		ret = filter->feed.sec->start_filtering(filter->feed.sec);
+		ret = filter->feed.sec.feed->start_filtering(
+				filter->feed.sec.feed);
 		if (ret < 0)
 			return ret;
 
@@ -2435,14 +2558,32 @@
 			filter->params.pes.rec_chunk_size =
 				filter->buffer.size >> 2;
 
+		ret = 0;
 		list_for_each_entry(feed, &filter->feed.ts, next) {
 			ret = dvb_dmxdev_start_feed(dmxdev, filter, feed);
-			if (ret < 0) {
-				dvb_dmxdev_filter_stop(filter);
-				return ret;
+			if (ret)
+				break;
+		}
+
+		if (!ret)
+			break;
+
+		/* cleanup feeds that were started before the failure */
+		list_for_each_entry(feed, &filter->feed.ts, next) {
+			if (!feed->ts)
+				continue;
+			feed->ts->stop_filtering(feed->ts);
+			dmxdev->demux->release_ts_feed(dmxdev->demux, feed->ts);
+			feed->ts = NULL;
+
+			if (filter->params.pes.output == DMX_OUT_TS_TAP) {
+				filter->dev->dvr_feeds_count--;
+				if (!filter->dev->dvr_feeds_count)
+					filter->dev->dvr_feed = NULL;
 			}
 		}
-		break;
+		return ret;
+
 	default:
 		return -EINVAL;
 	}
@@ -2477,6 +2618,11 @@
 	mutex_init(&dmxdevfilter->mutex);
 	file->private_data = dmxdevfilter;
 
+	memset(&dmxdevfilter->decoder_buffers,
+			0,
+			sizeof(dmxdevfilter->decoder_buffers));
+	dmxdevfilter->decoder_buffers.buffers_size =
+		DMX_DEFAULT_DECODER_BUFFER_SIZE;
 	dmxdevfilter->buffer_mode = DMX_BUFFER_MODE_INTERNAL;
 	dmxdevfilter->priv_buff_handle = NULL;
 	dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192);
@@ -2486,10 +2632,7 @@
 	dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
 	init_timer(&dmxdevfilter->timer);
 
-	dmxdevfilter->pes_buffer_size = 32768;
-
 	dmxdevfilter->dmx_tsp_format = DMX_TSP_FORMAT_188;
-
 	dvbdev->users++;
 
 	mutex_unlock(&dmxdev->mutex);
@@ -2503,6 +2646,7 @@
 	mutex_lock(&dmxdevfilter->mutex);
 
 	dvb_dmxdev_filter_stop(dmxdevfilter);
+
 	dvb_dmxdev_filter_reset(dmxdevfilter);
 
 	if (dmxdevfilter->buffer.data) {
@@ -2516,7 +2660,7 @@
 	}
 
 	if ((dmxdevfilter->buffer_mode == DMX_BUFFER_MODE_EXTERNAL) &&
-		(dmxdevfilter->priv_buff_handle)) {
+		dmxdevfilter->priv_buff_handle) {
 		dmxdev->demux->unmap_buffer(dmxdev->demux,
 			dmxdevfilter->priv_buff_handle);
 		dmxdevfilter->priv_buff_handle = NULL;
@@ -2556,6 +2700,7 @@
 		return -ENOMEM;
 
 	feed->pid = pid;
+	feed->sec_mode.is_secured = 0;
 	list_add(&feed->next, &filter->feed.ts);
 
 	if (filter->state >= DMXDEV_STATE_GO)
@@ -2574,10 +2719,13 @@
 		return -EINVAL;
 
 	list_for_each_entry_safe(feed, tmp, &filter->feed.ts, next) {
-		if ((feed->pid == pid) && (feed->ts != NULL)) {
-			feed->ts->stop_filtering(feed->ts);
-			filter->dev->demux->release_ts_feed(filter->dev->demux,
-							    feed->ts);
+		if (feed->pid == pid) {
+			if (feed->ts != NULL) {
+				feed->ts->stop_filtering(feed->ts);
+				filter->dev->demux->release_ts_feed(
+							filter->dev->demux,
+							feed->ts);
+			}
 			list_del(&feed->next);
 			kfree(feed);
 		}
@@ -2598,6 +2746,7 @@
 	memcpy(&dmxdevfilter->params.sec,
 	       params, sizeof(struct dmx_sct_filter_params));
 	invert_mode(&dmxdevfilter->params.sec.filter);
+	dmxdevfilter->feed.sec.sec_mode.is_secured = 0;
 	dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
 
 	if (params->flags & DMX_IMMEDIATE_START)
@@ -2606,6 +2755,64 @@
 	return 0;
 }
 
+static int dvb_dmxdev_set_secure_mode(
+	struct dmxdev *dmxdev,
+	struct dmxdev_filter *filter,
+	struct dmx_secure_mode *sec_mode)
+{
+	struct dmxdev_feed *feed;
+	struct dmxdev_feed *ts_feed = NULL;
+	struct dmxdev_sec_feed *sec_feed = NULL;
+
+	if (NULL == dmxdev || NULL == filter || NULL == sec_mode)
+		return -EINVAL;
+
+	if (filter->state < DMXDEV_STATE_SET ||
+		filter->state > DMXDEV_STATE_GO) {
+		printk(KERN_ERR "%s: invalid filter state\n", __func__);
+		return -EPERM;
+	}
+	dprintk(KERN_DEBUG "%s: key_id=%d, secure=%d, looking for pid=%d\n",
+		__func__, sec_mode->key_ladder_id, sec_mode->is_secured,
+		sec_mode->pid);
+	switch (filter->type) {
+	case DMXDEV_TYPE_PES:
+		list_for_each_entry(feed, &filter->feed.ts, next) {
+			if (feed->pid == sec_mode->pid) {
+				ts_feed = feed;
+				ts_feed->sec_mode = *sec_mode;
+				if (filter->state == DMXDEV_STATE_GO &&
+					ts_feed->ts->set_secure_mode)
+					ts_feed->ts->set_secure_mode(
+						ts_feed->ts, sec_mode);
+				break;
+			}
+		}
+		break;
+	case DMXDEV_TYPE_SEC:
+		if (filter->params.sec.pid == sec_mode->pid) {
+			sec_feed = &filter->feed.sec;
+			sec_feed->sec_mode = *sec_mode;
+			if (filter->state == DMXDEV_STATE_GO &&
+				sec_feed->feed->set_secure_mode)
+				sec_feed->feed->set_secure_mode(sec_feed->feed,
+						sec_mode);
+		}
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	if (!ts_feed && !sec_feed) {
+		printk(KERN_ERR "%s: pid %d is undefined for this filter\n",
+			__func__, sec_mode->pid);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int dvb_dmxdev_pes_filter_set(struct dmxdev *dmxdev,
 				     struct dmxdev_filter *dmxdevfilter,
 				     struct dmx_pes_filter_params *params)
@@ -2653,6 +2860,49 @@
 	return 0;
 }
 
+static int dvb_dmxdev_set_decoder_buffer(struct dmxdev *dmxdev,
+		struct dmxdev_filter *filter,
+		struct dmx_decoder_buffers *buffs)
+{
+	int i;
+	struct dmx_decoder_buffers *dec_buffs;
+	struct dmx_caps caps;
+
+	if (NULL == dmxdev || NULL == filter || NULL == buffs)
+		return -EINVAL;
+
+	dec_buffs = &filter->decoder_buffers;
+	dmxdev->demux->get_caps(dmxdev->demux, &caps);
+
+	if ((buffs->buffers_size == 0) ||
+		(buffs->is_linear &&
+		 ((buffs->buffers_num <= 1) ||
+		  (buffs->buffers_num > DMX_MAX_DECODER_BUFFER_NUM))))
+		return -EINVAL;
+
+	if (0 == buffs->buffers_num) {
+		/* Internal mode - linear buffers not supported in this mode */
+		if (!(caps.decoder.flags & DMX_BUFFER_INTERNAL_SUPPORT) ||
+			buffs->is_linear)
+			return -EINVAL;
+	} else {
+		/* External buffer(s) mode */
+		if ((!(caps.decoder.flags & DMX_BUFFER_LINEAR_GROUP_SUPPORT) &&
+			buffs->buffers_num > 1) ||
+			!(caps.decoder.flags & DMX_BUFFER_EXTERNAL_SUPPORT) ||
+			buffs->buffers_num > caps.decoder.max_buffer_num)
+			return -EINVAL;
+
+		dec_buffs->is_linear = buffs->is_linear;
+		dec_buffs->buffers_num = buffs->buffers_num;
+		dec_buffs->buffers_size = buffs->buffers_size;
+		for (i = 0; i < dec_buffs->buffers_num; i++)
+			dec_buffs->handles[i] = buffs->handles[i];
+	}
+
+	return 0;
+}
+
 static ssize_t dvb_dmxdev_read_sec(struct dmxdev_filter *dfil,
 				   struct file *file, char __user *buf,
 				   size_t count, loff_t *ppos)
@@ -2700,6 +2950,7 @@
 {
 	struct dmxdev_filter *dmxdevfilter = file->private_data;
 	int ret;
+	ssize_t flush_len;
 
 	if (mutex_lock_interruptible(&dmxdevfilter->mutex))
 		return -ERESTARTSYS;
@@ -2725,16 +2976,17 @@
 			wake_up_all(&dmxdevfilter->buffer.queue);
 	} else if (ret == -EOVERFLOW) {
 		/*
-		 * When buffer overflowed, demux-dev flushed the
-		 * buffer and marked the buffer in error state.
+		 * When buffer overflowed, demux-dev marked the buffer in
+		 * error state.
 		 * Data from underlying driver is discarded until
 		 * user gets notified that buffer has overflowed.
 		 * Now that the user is notified, notify underlying
 		 * driver that data was flushed from output buffer.
 		 */
+		flush_len = dvb_ringbuffer_avail(&dmxdevfilter->buffer);
+		dvb_ringbuffer_flush(&dmxdevfilter->buffer);
 		dvb_dmxdev_notify_data_read(dmxdevfilter->dev->dvr_feed,
-			dmxdevfilter->flush_data_len);
-		dmxdevfilter->flush_data_len = 0;
+			flush_len);
 	}
 
 	mutex_unlock(&dmxdevfilter->mutex);
@@ -2896,7 +3148,7 @@
 			return -ERESTARTSYS;
 		}
 
-		ret = dvb_dmxdev_set_pes_buffer_size(dmxdevfilter, arg);
+		ret = dvb_dmxdev_set_decoder_buffer_size(dmxdevfilter, arg);
 		mutex_unlock(&dmxdevfilter->mutex);
 		break;
 
@@ -2944,6 +3196,33 @@
 		mutex_unlock(&dmxdevfilter->mutex);
 		break;
 
+	case DMX_SET_DECODER_BUFFER:
+		if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+			ret = -ERESTARTSYS;
+			break;
+		}
+		ret = dvb_dmxdev_set_decoder_buffer(dmxdev, dmxdevfilter, parg);
+		mutex_unlock(&dmxdevfilter->mutex);
+		break;
+
+	case DMX_SET_SECURE_MODE:
+		if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+			ret = -ERESTARTSYS;
+			break;
+		}
+		ret = dvb_dmxdev_set_secure_mode(dmxdev, dmxdevfilter, parg);
+		mutex_unlock(&dmxdevfilter->mutex);
+		break;
+
+	case DMX_REUSE_DECODER_BUFFER:
+		if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+			mutex_unlock(&dmxdev->mutex);
+			return -ERESTARTSYS;
+		}
+		ret = dvb_dmxdev_reuse_decoder_buf(dmxdevfilter, arg);
+		mutex_unlock(&dmxdevfilter->mutex);
+		break;
+
 	default:
 		ret = -EINVAL;
 		break;
@@ -3045,9 +3324,7 @@
 {
 	struct dmxdev_filter *dmxdevfilter = file->private_data;
 	struct dmxdev *dmxdev = dmxdevfilter->dev;
-
 	int ret;
-
 	ret = dvb_dmxdev_filter_free(dmxdev, dmxdevfilter);
 
 	mutex_lock(&dmxdev->mutex);
@@ -3210,25 +3487,27 @@
 
 			seq_printf(s, "filter_%02d - ", i);
 
-		    if (filter->type == DMXDEV_TYPE_SEC) {
+			if (filter->type == DMXDEV_TYPE_SEC) {
 				seq_printf(s, "type: SEC, ");
 				seq_printf(s, "PID %04d ",
 						filter->params.sec.pid);
-		    } else {
+			} else {
 				seq_printf(s, "type: %s, ",
 					pes_feeds[filter->params.pes.output]);
 				seq_printf(s, "PID: %04d ",
 						filter->params.pes.pid);
-		    }
+			}
 
 			if (0 == dvb_dmxdev_get_buffer_status(
 						filter, &buffer_status)) {
-				seq_printf(s, "buffer size: %08d, ",
+				seq_printf(s, "size: %08d, ",
 					buffer_status.size);
-				seq_printf(s, "buffer fullness: %08d\n",
+				seq_printf(s, "fullness: %08d, ",
 					buffer_status.fullness);
-				seq_printf(s, "buffer error: %08d\n",
+				seq_printf(s, "error: %d\n",
 					buffer_status.error);
+			} else {
+				seq_printf(s, "\n");
 			}
 		}
 	}
@@ -3236,8 +3515,6 @@
 	if (!active_count)
 		seq_printf(s, "No active filters\n");
 
-	seq_printf(s, "\n");
-
 	return 0;
 }
 
diff --git a/drivers/media/dvb/dvb-core/dmxdev.h b/drivers/media/dvb/dvb-core/dmxdev.h
index d1c1cc3..a55b4f0 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.h
+++ b/drivers/media/dvb/dvb-core/dmxdev.h
@@ -4,7 +4,7 @@
  * Copyright (C) 2000 Ralph Metzler & Marcus Metzler
  *                    for convergence integrated media GmbH
  *
- * Copyright (c) 2012, Code Aurora Forum. 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 Lesser General Public License
@@ -58,10 +58,16 @@
 
 struct dmxdev_feed {
 	u16 pid;
+	struct dmx_secure_mode sec_mode;
 	struct dmx_ts_feed *ts;
 	struct list_head next;
 };
 
+struct dmxdev_sec_feed {
+	struct dmx_secure_mode sec_mode;
+	struct dmx_section_feed *feed;
+};
+
 struct dmxdev_events_queue {
 #define DMX_EVENT_QUEUE_SIZE	500 /* number of events */
 	/*
@@ -99,7 +105,7 @@
 	union {
 		/* list of TS and PES feeds (struct dmxdev_feed) */
 		struct list_head ts;
-		struct dmx_section_feed *sec;
+		struct dmxdev_sec_feed sec;
 	} feed;
 
 	union {
@@ -115,13 +121,9 @@
 	struct dvb_ringbuffer buffer;
 	void *priv_buff_handle;
 	enum dmx_buffer_mode buffer_mode;
-	u32 flush_data_len;
 
 	struct mutex mutex;
 
-	/* relevent for decoder PES */
-	unsigned long pes_buffer_size;
-
 	/* for recording output */
 	enum dmx_tsp_format_t dmx_tsp_format;
 	u32 rec_chunk_size;
@@ -130,6 +132,9 @@
 	struct timer_list timer;
 	int todo;
 	u8 secheader[3];
+
+	/* Decoder buffer(s) related */
+	struct dmx_decoder_buffers decoder_buffers;
 };
 
 struct dmxdev {
@@ -160,7 +165,6 @@
 	enum dmx_buffer_mode dvr_buffer_mode;
 	struct dmxdev_events_queue dvr_output_events;
 	struct dmxdev_filter *dvr_feed;
-	u32 dvr_flush_data_len;
 	int dvr_feeds_count;
 
 	struct dvb_ringbuffer dvr_input_buffer;
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index 978cb38d..dfb8d58 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -5,7 +5,7 @@
  *		       & Marcus Metzler <marcus@convergence.de>
  *			 for convergence integrated media GmbH
  *
- * Copyright (c) 2012, Code Aurora Forum. 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 Lesser General Public License
@@ -127,15 +127,15 @@
 {
 	int count = payload(buf);
 	int p;
-	//int ccok;
-	//u8 cc;
+	int ccok;
+	u8 cc;
+	struct dmx_data_ready data;
 
 	if (count == 0)
 		return -1;
 
 	p = 188 - count;
 
-	/*
 	cc = buf[3] & 0x0f;
 	if (feed->first_cc)
 		ccok = 1;
@@ -144,26 +144,41 @@
 
 	feed->first_cc = 0;
 	feed->cc = cc;
-	if (!ccok)
-		printk("missed packet!\n");
-	*/
 
 	/* PUSI ? */
 	if (buf[1] & 0x40) {
-		if (feed->pusi_seen)
+		if (feed->pusi_seen) {
 			/* We had seen PUSI before, this means
 			 * that previous PES can be closed now.
 			 */
-			feed->cb.ts(NULL, 0, NULL, 0,
-						&feed->feed.ts, DMX_OK_PES_END);
+			data.status = DMX_OK_PES_END;
+			data.data_length = 0;
+			data.pes_end.start_gap = 0;
+			data.pes_end.actual_length = feed->peslen;
+			data.pes_end.disc_indicator_set = 0;
+			data.pes_end.pes_length_mismatch = 0;
+			data.pes_end.stc = 0;
+			data.pes_end.tei_counter = feed->pes_tei_counter;
+			data.pes_end.cont_err_counter =
+				feed->pes_cont_err_counter;
+			data.pes_end.ts_packets_num = feed->pes_ts_packets_num;
+			feed->data_ready_cb.ts(&feed->feed.ts, &data);
+		}
 
 		feed->pusi_seen = 1;
 		feed->peslen = 0;
+		feed->pes_tei_counter = 0;
+		feed->pes_ts_packets_num = 0;
+		feed->pes_cont_err_counter = 0;
 	}
 
 	if (feed->pusi_seen == 0)
 		return 0;
 
+	feed->pes_ts_packets_num++;
+	feed->pes_cont_err_counter += !ccok;
+	feed->pes_tei_counter += (buf[1] & 0x80) ? 1 : 0;
+
 	feed->peslen += count;
 
 	return feed->cb.ts(&buf[p], count, NULL, 0, &feed->feed.ts, DMX_OK);
@@ -1128,21 +1143,47 @@
 	struct dvb_demux *demux = feed->demux;
 	int ret;
 
-	spin_lock_irq(&demux->lock);
+	mutex_lock(&demux->mutex);
 
 	if (feed->state < DMX_STATE_GO) {
-		spin_unlock_irq(&demux->lock);
+		mutex_unlock(&demux->mutex);
 		return -EINVAL;
 	}
 
 	if (!demux->decoder_buffer_status) {
-		spin_unlock_irq(&demux->lock);
+		mutex_unlock(&demux->mutex);
 		return -ENODEV;
 	}
 
 	ret = demux->decoder_buffer_status(feed, dmx_buffer_status);
 
-	spin_unlock_irq(&demux->lock);
+	mutex_unlock(&demux->mutex);
+
+	return ret;
+}
+
+static int dmx_ts_feed_reuse_decoder_buffer(struct dmx_ts_feed *ts_feed,
+						int cookie)
+{
+	struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed;
+	struct dvb_demux *demux = feed->demux;
+	int ret;
+
+	mutex_lock(&demux->mutex);
+
+	if (feed->state < DMX_STATE_GO) {
+		mutex_unlock(&demux->mutex);
+		return -EINVAL;
+	}
+
+	if (!demux->reuse_decoder_buffer) {
+		mutex_unlock(&demux->mutex);
+		return -ENODEV;
+	}
+
+	ret = demux->reuse_decoder_buffer(feed, cookie);
+
+	mutex_unlock(&demux->mutex);
 
 	return ret;
 }
@@ -1166,6 +1207,24 @@
 	return 0;
 }
 
+static int dmx_ts_set_secure_mode(struct dmx_ts_feed *feed,
+				struct dmx_secure_mode *secure_mode)
+{
+	struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
+	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
+
+	mutex_lock(&dvbdmx->mutex);
+
+	dvbdmxfeed->secure_mode = *secure_mode;
+
+	if ((dvbdmxfeed->state == DMX_STATE_GO) &&
+		dvbdmxfeed->demux->set_secure_mode)
+		dvbdmxfeed->demux->set_secure_mode(dvbdmxfeed, secure_mode);
+
+	mutex_unlock(&dvbdmx->mutex);
+	return 0;
+}
+
 static int dmx_ts_set_indexing_params(
 	struct dmx_ts_feed *ts_feed,
 	struct dmx_indexing_video_params *params)
@@ -1217,6 +1276,10 @@
 	feed->demux = demux;
 	feed->pid = 0xffff;
 	feed->peslen = 0;
+	feed->pes_tei_counter = 0;
+	feed->pes_ts_packets_num = 0;
+	feed->pes_cont_err_counter = 0;
+	feed->secure_mode.is_secured = 0;
 	feed->buffer = NULL;
 	feed->tsp_out_format = DMX_TSP_FORMAT_188;
 	memset(&feed->indexing_params, 0,
@@ -1239,8 +1302,10 @@
 	(*ts_feed)->set_indexing_params = dmx_ts_set_indexing_params;
 	(*ts_feed)->set_tsp_out_format = dmx_ts_set_tsp_out_format;
 	(*ts_feed)->get_decoder_buff_status = dmx_ts_feed_decoder_buff_status;
+	(*ts_feed)->reuse_decoder_buffer = dmx_ts_feed_reuse_decoder_buffer;
 	(*ts_feed)->data_ready_cb = dmx_ts_feed_data_ready_cb;
 	(*ts_feed)->notify_data_read = NULL;
+	(*ts_feed)->set_secure_mode = dmx_ts_set_secure_mode;
 
 	if (!(feed->filter = dvb_dmx_filter_alloc(demux))) {
 		feed->state = DMX_STATE_FREE;
@@ -1469,6 +1534,23 @@
 	return 0;
 }
 
+static int dmx_section_set_secure_mode(struct dmx_section_feed *feed,
+				struct dmx_secure_mode *secure_mode)
+{
+	struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
+	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
+
+	mutex_lock(&dvbdmx->mutex);
+
+	dvbdmxfeed->secure_mode = *secure_mode;
+	if ((dvbdmxfeed->state == DMX_STATE_GO) &&
+		dvbdmxfeed->demux->set_secure_mode)
+		dvbdmxfeed->demux->set_secure_mode(dvbdmxfeed, secure_mode);
+
+	mutex_unlock(&dvbdmx->mutex);
+	return 0;
+}
+
 static int dmx_section_feed_release_filter(struct dmx_section_feed *feed,
 					   struct dmx_section_filter *filter)
 {
@@ -1522,6 +1604,7 @@
 	dvbdmxfeed->cb.sec = callback;
 	dvbdmxfeed->demux = dvbdmx;
 	dvbdmxfeed->pid = 0xffff;
+	dvbdmxfeed->secure_mode.is_secured = 0;
 	dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base;
 	dvbdmxfeed->feed.sec.secbufp = dvbdmxfeed->feed.sec.seclen = 0;
 	dvbdmxfeed->feed.sec.tsfeedp = 0;
@@ -1540,6 +1623,7 @@
 	(*feed)->release_filter = dmx_section_feed_release_filter;
 	(*feed)->data_ready_cb = dmx_section_feed_data_ready_cb;
 	(*feed)->notify_data_read = NULL;
+	(*feed)->set_secure_mode = dmx_section_set_secure_mode;
 
 	mutex_unlock(&dvbdmx->mutex);
 	return 0;
@@ -1730,6 +1814,19 @@
 	mutex_lock(&dvbdemux->mutex);
 
 	dvbdemux->tsp_format = tsp_format;
+	switch (tsp_format) {
+	case DMX_TSP_FORMAT_188:
+		dvbdemux->ts_packet_size = 188;
+		break;
+	case DMX_TSP_FORMAT_192_TAIL:
+	case DMX_TSP_FORMAT_192_HEAD:
+		dvbdemux->ts_packet_size = 192;
+		break;
+	case DMX_TSP_FORMAT_204:
+		dvbdemux->ts_packet_size = 204;
+		break;
+	}
+
 	mutex_unlock(&dvbdemux->mutex);
 	return 0;
 }
@@ -1804,6 +1901,7 @@
 	dvbdemux->tsbufp = 0;
 
 	dvbdemux->tsp_format = DMX_TSP_FORMAT_188;
+	dvbdemux->ts_packet_size = 188;
 
 	if (!dvbdemux->check_crc32)
 		dvbdemux->check_crc32 = dvb_dmx_crc32;
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h
index f89367b..f5f6039 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.h
+++ b/drivers/media/dvb/dvb-core/dvb_demux.h
@@ -4,7 +4,7 @@
  * Copyright (C) 2000-2001 Marcus Metzler & Ralph Metzler
  *                         for convergence integrated media GmbH
  *
- * Copyright (c) 2012, Code Aurora Forum. 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 Lesser General Public License
@@ -93,6 +93,7 @@
 	u8 *buffer;
 	int buffer_size;
 	enum dmx_tsp_format_t tsp_out_format;
+	struct dmx_secure_mode secure_mode;
 
 	struct timespec timeout;
 	struct dvb_demux_filter *filter;
@@ -105,6 +106,9 @@
 	int pusi_seen;		/* prevents feeding of garbage from previous section */
 
 	u32 peslen;
+	u32 pes_tei_counter;
+	u32 pes_cont_err_counter;
+	u32 pes_ts_packets_num;
 
 	struct list_head list_head;
 	unsigned int index;	/* a unique index for each feed (can be used as hardware pid filter index) */
@@ -127,6 +131,10 @@
 	int (*decoder_fullness_abort)(struct dvb_demux_feed *feed);
 	int (*decoder_buffer_status)(struct dvb_demux_feed *feed,
 				struct dmx_buffer_status *dmx_buffer_status);
+	int (*reuse_decoder_buffer)(struct dvb_demux_feed *feed,
+				int cookie);
+	int (*set_secure_mode)(struct dvb_demux_feed *feed,
+				struct dmx_secure_mode *secure_mode);
 	u32 (*check_crc32)(struct dvb_demux_feed *feed,
 			    const u8 *buf, size_t len);
 	void (*memcopy)(struct dvb_demux_feed *feed, u8 *dst,
@@ -158,6 +166,7 @@
 	uint32_t speed_pkts_cnt; /* for TS speed check */
 
 	enum dmx_tsp_format_t tsp_format;
+	size_t ts_packet_size;
 
 	enum dmx_playback_mode_t playback_mode;
 	int sw_filter_abort;
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
index 36cc475..92f7463 100644
--- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
+++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
@@ -5,7 +5,7 @@
  * Copyright (C) 2003 Oliver Endriss
  * Copyright (C) 2004 Andrew de Quincey
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * based on code originally found in av7110.c & dvb_ci.c:
  * Copyright (C) 1999-2003 Ralph  Metzler
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
index 4093fa5..10de856 100644
--- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
+++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
@@ -5,7 +5,7 @@
  * Copyright (C) 2003 Oliver Endriss
  * Copyright (C) 2004 Andrew de Quincey
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * based on code originally found in av7110.c & dvb_ci.c:
  * Copyright (C) 1999-2003 Ralph Metzler & Marcus Metzler
diff --git a/drivers/media/dvb/mpq/Kconfig b/drivers/media/dvb/mpq/Kconfig
deleted file mode 100644
index 766312c..0000000
--- a/drivers/media/dvb/mpq/Kconfig
+++ /dev/null
@@ -1,12 +0,0 @@
-config DVB_MPQ
-	tristate "Qualcomm Multimedia Processor DVB Adapter"
-	depends on ARCH_MSM && DVB_CORE
-	default n
-
-	help
-	  Support for Qualcomm MPQ based DVB adapter.
-	  Say Y or M if you own such a device and want to use it.
-
-source "drivers/media/dvb/mpq/demux/Kconfig"
-source "drivers/media/dvb/mpq/video/Kconfig"
-
diff --git a/drivers/media/dvb/mpq/adapter/Makefile b/drivers/media/dvb/mpq/adapter/Makefile
deleted file mode 100644
index ed664da..0000000
--- a/drivers/media/dvb/mpq/adapter/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-
-EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/
-EXTRA_CFLAGS += -Idrivers/media/dvb/mpq/include/
-
-obj-$(CONFIG_DVB_MPQ) += mpq-adapter.o
-
-mpq-adapter-y := mpq_adapter.o mpq_stream_buffer.o
-
diff --git a/drivers/media/dvb/mpq/adapter/mpq_adapter.c b/drivers/media/dvb/mpq/adapter/mpq_adapter.c
deleted file mode 100644
index 9664f04..0000000
--- a/drivers/media/dvb/mpq/adapter/mpq_adapter.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/module.h>
-
-#include "mpq_adapter.h"
-#include "mpq_dvb_debug.h"
-
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-/* data-structure holding MPQ adapter information */
-static struct
-{
-	/* MPQ adapter registered to dvb-core */
-	struct dvb_adapter adapter;
-
-	/* mutex protect against the data-structure */
-	struct mutex mutex;
-
-	/* List of stream interfaces registered to the MPQ adapter */
-	struct {
-		/* pointer to the stream buffer using for data tunneling */
-		struct mpq_streambuffer *stream_buffer;
-
-		/* callback triggered when the stream interface is registered */
-		mpq_adapter_stream_if_callback callback;
-
-		/* parameter passed to the callback function */
-		void *user_param;
-	} interfaces[MPQ_ADAPTER_MAX_NUM_OF_INTERFACES];
-} mpq_info;
-
-
-/**
- * Initialize MPQ DVB adapter module.
- *
- * Return     error status
- */
-static int __init mpq_adapter_init(void)
-{
-	int i;
-	int result;
-
-	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
-
-	mutex_init(&mpq_info.mutex);
-
-	/* reset stream interfaces list */
-	for (i = 0; i < MPQ_ADAPTER_MAX_NUM_OF_INTERFACES; i++) {
-		mpq_info.interfaces[i].stream_buffer = NULL;
-		mpq_info.interfaces[i].callback = NULL;
-	}
-
-	/* regsiter a new dvb-adapter to dvb-core */
-	result = dvb_register_adapter(&mpq_info.adapter,
-								  "Qualcomm DVB adapter",
-								  THIS_MODULE,
-								  NULL,
-								  adapter_nr);
-
-	if (result < 0) {
-		MPQ_DVB_ERR_PRINT(
-			"%s: dvb_register_adapter failed, errno %d\n",
-			__func__,
-			result);
-	}
-
-	return result;
-}
-
-
-/**
- * Cleanup MPQ DVB adapter module.
- */
-static void __exit mpq_adapter_exit(void)
-{
-	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
-
-	/* un-regsiter adapter from dvb-core */
-	dvb_unregister_adapter(&mpq_info.adapter);
-	mutex_destroy(&mpq_info.mutex);
-}
-
-struct dvb_adapter *mpq_adapter_get(void)
-{
-	return &mpq_info.adapter;
-}
-EXPORT_SYMBOL(mpq_adapter_get);
-
-
-int mpq_adapter_register_stream_if(
-		enum mpq_adapter_stream_if interface_id,
-		struct mpq_streambuffer *stream_buffer)
-{
-	int ret;
-
-	if (interface_id >= MPQ_ADAPTER_MAX_NUM_OF_INTERFACES) {
-		ret = -EINVAL;
-		goto register_failed;
-	}
-
-	if (mutex_lock_interruptible(&mpq_info.mutex)) {
-		ret = -ERESTARTSYS;
-		goto register_failed;
-	}
-
-	if (mpq_info.interfaces[interface_id].stream_buffer != NULL) {
-		/* already registered interface */
-		ret = -EINVAL;
-		goto register_failed_unlock_mutex;
-	}
-
-	mpq_info.interfaces[interface_id].stream_buffer = stream_buffer;
-	mutex_unlock(&mpq_info.mutex);
-
-	/*
-	 * If callback is installed, trigger it to notify that
-	 * stream interface was registered.
-	 */
-	if (mpq_info.interfaces[interface_id].callback != NULL) {
-		mpq_info.interfaces[interface_id].callback(
-				interface_id,
-				mpq_info.interfaces[interface_id].user_param);
-	}
-
-	return 0;
-
-register_failed_unlock_mutex:
-	mutex_unlock(&mpq_info.mutex);
-register_failed:
-	return ret;
-}
-EXPORT_SYMBOL(mpq_adapter_register_stream_if);
-
-
-int mpq_adapter_unregister_stream_if(
-		enum mpq_adapter_stream_if interface_id)
-{
-	if (interface_id >= MPQ_ADAPTER_MAX_NUM_OF_INTERFACES)
-		return -EINVAL;
-
-	if (mutex_lock_interruptible(&mpq_info.mutex))
-		return -ERESTARTSYS;
-
-	/* clear the registered interface */
-	mpq_info.interfaces[interface_id].stream_buffer = NULL;
-
-	mutex_unlock(&mpq_info.mutex);
-
-	return 0;
-}
-EXPORT_SYMBOL(mpq_adapter_unregister_stream_if);
-
-
-int mpq_adapter_get_stream_if(
-		enum mpq_adapter_stream_if interface_id,
-		struct mpq_streambuffer **stream_buffer)
-{
-	if ((interface_id >= MPQ_ADAPTER_MAX_NUM_OF_INTERFACES) ||
-		(stream_buffer == NULL))
-		return -EINVAL;
-
-	if (mutex_lock_interruptible(&mpq_info.mutex))
-		return -ERESTARTSYS;
-
-	*stream_buffer = mpq_info.interfaces[interface_id].stream_buffer;
-
-	mutex_unlock(&mpq_info.mutex);
-
-	return 0;
-}
-EXPORT_SYMBOL(mpq_adapter_get_stream_if);
-
-
-int mpq_adapter_notify_stream_if(
-		enum mpq_adapter_stream_if interface_id,
-		mpq_adapter_stream_if_callback callback,
-		void *user_param)
-{
-	if (interface_id >= MPQ_ADAPTER_MAX_NUM_OF_INTERFACES)
-		return -EINVAL;
-
-	if (mutex_lock_interruptible(&mpq_info.mutex))
-		return -ERESTARTSYS;
-
-	mpq_info.interfaces[interface_id].callback = callback;
-	mpq_info.interfaces[interface_id].user_param = user_param;
-
-	mutex_unlock(&mpq_info.mutex);
-
-	return 0;
-}
-EXPORT_SYMBOL(mpq_adapter_notify_stream_if);
-
-
-module_init(mpq_adapter_init);
-module_exit(mpq_adapter_exit);
-
-MODULE_DESCRIPTION("Qualcomm MPQ adapter");
-MODULE_LICENSE("GPL v2");
-
diff --git a/drivers/media/dvb/mpq/adapter/mpq_stream_buffer.c b/drivers/media/dvb/mpq/adapter/mpq_stream_buffer.c
deleted file mode 100644
index f779851..0000000
--- a/drivers/media/dvb/mpq/adapter/mpq_stream_buffer.c
+++ /dev/null
@@ -1,528 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/module.h>
-#include <linux/sched.h>
-#include <linux/wait.h>
-#include <linux/uaccess.h>
-#include "mpq_dvb_debug.h"
-#include "mpq_stream_buffer.h"
-
-
-
-
-int mpq_streambuffer_init(
-		struct mpq_streambuffer *sbuff,
-		enum mpq_streambuffer_mode mode,
-		struct mpq_streambuffer_buffer_desc *data_buffers,
-		u32 data_buff_num,
-		void *packet_buff,
-		size_t packet_buff_size)
-{
-	if ((NULL == sbuff) || (NULL == data_buffers) || (NULL == packet_buff))
-		return -EINVAL;
-
-	if (data_buff_num > 1) {
-		if (mode != MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR)
-			return -EINVAL;
-		/* Linear buffer group */
-		dvb_ringbuffer_init(
-			&sbuff->raw_data,
-			data_buffers,
-			data_buff_num *
-			sizeof(struct mpq_streambuffer_buffer_desc));
-	} else if (data_buff_num == 1) {
-		if (mode != MPQ_STREAMBUFFER_BUFFER_MODE_RING)
-			return -EINVAL;
-		/* Single ring-buffer */
-		dvb_ringbuffer_init(&sbuff->raw_data,
-			data_buffers[0].base, data_buffers[0].size);
-	}
-	sbuff->mode = mode;
-	sbuff->buffers = data_buffers;
-	sbuff->pending_buffers_count = 0;
-	sbuff->buffers_num = data_buff_num;
-	dvb_ringbuffer_init(&sbuff->packet_data, packet_buff, packet_buff_size);
-
-	return 0;
-}
-EXPORT_SYMBOL(mpq_streambuffer_init);
-
-
-ssize_t mpq_streambuffer_pkt_next(
-		struct mpq_streambuffer *sbuff,
-		ssize_t idx, size_t *pktlen)
-{
-	return dvb_ringbuffer_pkt_next(&sbuff->packet_data, idx, pktlen);
-}
-EXPORT_SYMBOL(mpq_streambuffer_pkt_next);
-
-
-ssize_t mpq_streambuffer_pkt_read(
-		struct mpq_streambuffer *sbuff,
-		size_t idx,
-		struct mpq_streambuffer_packet_header *packet,
-		u8 *user_data)
-{
-	size_t ret;
-	size_t read_len;
-
-	/* read-out the packet header first */
-	ret = dvb_ringbuffer_pkt_read(
-				&sbuff->packet_data, idx, 0,
-				(u8 *)packet,
-				sizeof(struct mpq_streambuffer_packet_header));
-
-	/* verify length, at least packet header should exist */
-	if (ret != sizeof(struct mpq_streambuffer_packet_header))
-		return -EINVAL;
-
-	read_len = ret;
-
-	/* read-out private user-data if there are such */
-	if ((packet->user_data_len) && (user_data != NULL)) {
-		ret = dvb_ringbuffer_pkt_read(
-				&sbuff->packet_data,
-				idx,
-				sizeof(struct mpq_streambuffer_packet_header),
-				user_data,
-				packet->user_data_len);
-
-		if (ret < 0)
-			return ret;
-
-		read_len += ret;
-	}
-
-	return read_len;
-}
-EXPORT_SYMBOL(mpq_streambuffer_pkt_read);
-
-
-int mpq_streambuffer_pkt_dispose(
-			struct mpq_streambuffer *sbuff,
-			size_t idx,
-			int dispose_data)
-{
-	int ret;
-	struct mpq_streambuffer_packet_header packet;
-
-	if (NULL == sbuff)
-		return -EINVAL;
-
-	/* read-out the packet header first */
-	ret = dvb_ringbuffer_pkt_read(&sbuff->packet_data, idx,
-			0,
-			(u8 *)&packet,
-			sizeof(struct mpq_streambuffer_packet_header));
-
-	if (ret != sizeof(struct mpq_streambuffer_packet_header))
-		return -EINVAL;
-
-	if ((MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR == sbuff->mode) ||
-		(dispose_data)) {
-		/* Advance the read pointer in the raw-data buffer first */
-		ret = mpq_streambuffer_data_read_dispose(sbuff,
-				packet.raw_data_len);
-		if (ret != 0)
-			return ret;
-	}
-
-	/* Move read pointer to the next linear buffer for subsequent reads */
-	if ((MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR == sbuff->mode) &&
-		(packet.raw_data_len > 0)) {
-		struct mpq_streambuffer_buffer_desc *desc;
-
-		desc = (struct mpq_streambuffer_buffer_desc *)
-				&sbuff->raw_data.data[sbuff->raw_data.pread];
-
-		desc->write_ptr = 0;
-		desc->read_ptr = 0;
-
-		DVB_RINGBUFFER_SKIP(&sbuff->raw_data,
-				sizeof(struct mpq_streambuffer_buffer_desc));
-		sbuff->pending_buffers_count--;
-
-		wake_up_all(&sbuff->raw_data.queue);
-	}
-
-	/* Now clear the packet from the packet header */
-	dvb_ringbuffer_pkt_dispose(&sbuff->packet_data, idx);
-
-	if (sbuff->cb)
-		sbuff->cb(sbuff, sbuff->cb_user_data);
-
-	return 0;
-}
-EXPORT_SYMBOL(mpq_streambuffer_pkt_dispose);
-
-int mpq_streambuffer_pkt_write(
-			struct mpq_streambuffer *sbuff,
-			struct mpq_streambuffer_packet_header *packet,
-			u8 *user_data)
-{
-	ssize_t idx;
-	size_t len;
-
-	if ((NULL == sbuff) || (NULL == packet))
-		return -EINVAL;
-
-	MPQ_DVB_DBG_PRINT(
-		"%s: handle=%d, offset=%d, len=%d\n",
-		__func__,
-		packet->raw_data_handle,
-		packet->raw_data_offset,
-		packet->raw_data_len);
-
-	len = sizeof(struct mpq_streambuffer_packet_header) +
-		packet->user_data_len;
-
-	/* Make sure enough space available for packet header */
-	if (dvb_ringbuffer_free(&sbuff->packet_data) < len)
-		return -ENOSPC;
-
-	/* Starting writing packet header */
-	idx = dvb_ringbuffer_pkt_start(&sbuff->packet_data, len);
-
-	/* Write non-user private data header */
-	dvb_ringbuffer_write(&sbuff->packet_data,
-		(u8 *)packet,
-		sizeof(struct mpq_streambuffer_packet_header));
-
-	/* Write user's own private data header */
-	dvb_ringbuffer_write(&sbuff->packet_data,
-		user_data,
-		packet->user_data_len);
-
-	dvb_ringbuffer_pkt_close(&sbuff->packet_data, idx);
-
-	/* Move write pointer to next linear buffer for subsequent writes */
-	if ((MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR == sbuff->mode) &&
-		(packet->raw_data_len > 0)) {
-		if (sbuff->pending_buffers_count == sbuff->buffers_num)
-			return -ENOSPC;
-		DVB_RINGBUFFER_PUSH(&sbuff->raw_data,
-				sizeof(struct mpq_streambuffer_buffer_desc));
-		sbuff->pending_buffers_count++;
-	}
-
-	wake_up_all(&sbuff->packet_data.queue);
-
-	return 0;
-}
-EXPORT_SYMBOL(mpq_streambuffer_pkt_write);
-
-
-ssize_t mpq_streambuffer_data_write(
-			struct mpq_streambuffer *sbuff,
-			const u8 *buf, size_t len)
-{
-	int res;
-
-	if ((NULL == sbuff) || (NULL == buf))
-		return -EINVAL;
-
-	if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
-		if (unlikely(dvb_ringbuffer_free(&sbuff->raw_data) < len))
-			return -ENOSPC;
-		/*
-		 * Secure buffers are not permitted to be mapped into kernel
-		 * memory, and so buffer base address may be NULL
-		 */
-		if (NULL == sbuff->raw_data.data)
-			return -EPERM;
-		res = dvb_ringbuffer_write(&sbuff->raw_data, buf, len);
-		wake_up_all(&sbuff->raw_data.queue);
-	} else {
-		/* Linear buffer group */
-		struct mpq_streambuffer_buffer_desc *desc;
-
-		desc = (struct mpq_streambuffer_buffer_desc *)
-				&sbuff->raw_data.data[sbuff->raw_data.pwrite];
-
-		/*
-		 * Secure buffers are not permitted to be mapped into kernel
-		 * memory, and so buffer base address may be NULL
-		 */
-		if (NULL == desc->base)
-			return -EPERM;
-
-		if ((sbuff->pending_buffers_count == sbuff->buffers_num) ||
-			((desc->size - desc->write_ptr) < len)) {
-			MPQ_DVB_ERR_PRINT(
-				"%s: No space available! %d pending buffers out of %d total buffers. write_ptr=%d, size=%d\n",
-				__func__,
-				sbuff->pending_buffers_count,
-				sbuff->buffers_num,
-				desc->write_ptr,
-				desc->size);
-			return -ENOSPC;
-		}
-		memcpy(desc->base + desc->write_ptr, buf, len);
-		desc->write_ptr += len;
-		MPQ_DVB_DBG_PRINT(
-			"%s: copied %d data bytes. handle=%d, write_ptr=%d\n",
-			__func__, len, desc->handle, desc->write_ptr);
-		res = len;
-	}
-
-	return res;
-}
-EXPORT_SYMBOL(mpq_streambuffer_data_write);
-
-
-int mpq_streambuffer_data_write_deposit(
-				struct mpq_streambuffer *sbuff,
-				size_t len)
-{
-	if (NULL == sbuff)
-		return -EINVAL;
-
-	if (unlikely(dvb_ringbuffer_free(&sbuff->raw_data) < len))
-		return -ENOSPC;
-
-	if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
-		DVB_RINGBUFFER_PUSH(&sbuff->raw_data, len);
-		wake_up_all(&sbuff->raw_data.queue);
-	} else {
-		/* Linear buffer group */
-		struct mpq_streambuffer_buffer_desc *desc;
-		desc = (struct mpq_streambuffer_buffer_desc *)
-				&sbuff->raw_data.data[sbuff->raw_data.pwrite];
-
-		if ((sbuff->pending_buffers_count == sbuff->buffers_num) ||
-			 ((desc->size - desc->write_ptr) < len)) {
-			MPQ_DVB_ERR_PRINT(
-				"%s: No space available!\n",
-				__func__);
-			return -ENOSPC;
-		}
-		desc->write_ptr += len;
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL(mpq_streambuffer_data_write_deposit);
-
-
-ssize_t mpq_streambuffer_data_read(
-				struct mpq_streambuffer *sbuff,
-				u8 *buf, size_t len)
-{
-	ssize_t actual_len = 0;
-
-	if ((NULL == sbuff) || (NULL == buf))
-		return -EINVAL;
-
-	if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
-		/*
-		 * Secure buffers are not permitted to be mapped into kernel
-		 * memory, and so buffer base address may be NULL
-		 */
-		if (NULL == sbuff->raw_data.data)
-			return -EPERM;
-
-		actual_len = dvb_ringbuffer_avail(&sbuff->raw_data);
-		if (actual_len < len)
-			len = actual_len;
-		if (len)
-			dvb_ringbuffer_read(&sbuff->raw_data, buf, len);
-
-		wake_up_all(&sbuff->raw_data.queue);
-	} else {
-		/* Linear buffer group */
-		struct mpq_streambuffer_buffer_desc *desc;
-
-		desc = (struct mpq_streambuffer_buffer_desc *)
-				&sbuff->raw_data.data[sbuff->raw_data.pread];
-
-		/*
-		 * Secure buffers are not permitted to be mapped into kernel
-		 * memory, and so buffer base address may be NULL
-		 */
-		if (NULL == desc->base)
-			return -EPERM;
-
-		actual_len = (desc->write_ptr - desc->read_ptr);
-		if (actual_len < len)
-			len = actual_len;
-		memcpy(buf, desc->base + desc->read_ptr, len);
-		desc->read_ptr += len;
-	}
-
-	return len;
-}
-EXPORT_SYMBOL(mpq_streambuffer_data_read);
-
-
-ssize_t mpq_streambuffer_data_read_user(
-		struct mpq_streambuffer *sbuff,
-		u8 __user *buf, size_t len)
-{
-	ssize_t actual_len = 0;
-
-	if ((NULL == sbuff) || (NULL == buf))
-		return -EINVAL;
-
-	if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
-		/*
-		 * Secure buffers are not permitted to be mapped into kernel
-		 * memory, and so buffer base address may be NULL
-		 */
-		if (NULL == sbuff->raw_data.data)
-			return -EPERM;
-
-		actual_len = dvb_ringbuffer_avail(&sbuff->raw_data);
-		if (actual_len < len)
-			len = actual_len;
-		if (len)
-			dvb_ringbuffer_read_user(&sbuff->raw_data, buf, len);
-		wake_up_all(&sbuff->raw_data.queue);
-	} else {
-		/* Linear buffer group */
-		struct mpq_streambuffer_buffer_desc *desc;
-
-		desc = (struct mpq_streambuffer_buffer_desc *)
-				&sbuff->raw_data.data[sbuff->raw_data.pread];
-
-		/*
-		 * Secure buffers are not permitted to be mapped into kernel
-		 * memory, and so buffer base address may be NULL
-		 */
-		if (NULL == desc->base)
-			return -EPERM;
-
-		actual_len = (desc->write_ptr - desc->read_ptr);
-		if (actual_len < len)
-			len = actual_len;
-		if (copy_to_user(buf, desc->base + desc->read_ptr, len))
-			return -EFAULT;
-		desc->read_ptr += len;
-	}
-
-	return len;
-}
-EXPORT_SYMBOL(mpq_streambuffer_data_read_user);
-
-
-int mpq_streambuffer_data_read_dispose(
-			struct mpq_streambuffer *sbuff,
-			size_t len)
-{
-	if (NULL == sbuff)
-		return -EINVAL;
-
-	if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
-		if (unlikely(dvb_ringbuffer_avail(&sbuff->raw_data) < len))
-			return -EINVAL;
-
-		DVB_RINGBUFFER_SKIP(&sbuff->raw_data, len);
-		wake_up_all(&sbuff->raw_data.queue);
-	} else {
-		struct mpq_streambuffer_buffer_desc *desc;
-
-		desc = (struct mpq_streambuffer_buffer_desc *)
-				&sbuff->raw_data.data[sbuff->raw_data.pread];
-		if ((desc->read_ptr + len) > desc->size)
-			desc->read_ptr = desc->size;
-		else
-			desc->read_ptr += len;
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL(mpq_streambuffer_data_read_dispose);
-
-
-int mpq_streambuffer_get_buffer_handle(
-	struct mpq_streambuffer *sbuff,
-	int read_buffer,
-	int *handle)
-{
-	struct mpq_streambuffer_buffer_desc *desc = NULL;
-
-	if ((NULL == sbuff) || (NULL == handle))
-		return -EINVAL;
-
-	if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
-		*handle = sbuff->buffers[0].handle;
-	} else {
-		if (read_buffer)
-			desc = (struct mpq_streambuffer_buffer_desc *)
-				&sbuff->raw_data.data[sbuff->raw_data.pread];
-		else
-			desc = (struct mpq_streambuffer_buffer_desc *)
-				&sbuff->raw_data.data[sbuff->raw_data.pwrite];
-		*handle = desc->handle;
-	}
-	return 0;
-}
-EXPORT_SYMBOL(mpq_streambuffer_get_buffer_handle);
-
-
-int mpq_streambuffer_register_pkt_dispose(
-	struct mpq_streambuffer *sbuff,
-	mpq_streambuffer_pkt_dispose_cb cb_func,
-	void *user_data)
-{
-	if ((NULL == sbuff) || (NULL == cb_func))
-		return -EINVAL;
-
-	sbuff->cb = cb_func;
-	sbuff->cb_user_data = user_data;
-
-	return 0;
-}
-EXPORT_SYMBOL(mpq_streambuffer_register_pkt_dispose);
-
-
-ssize_t mpq_streambuffer_data_free(
-	struct mpq_streambuffer *sbuff)
-{
-	struct mpq_streambuffer_buffer_desc *desc;
-
-	if (NULL == sbuff)
-		return -EINVAL;
-
-	if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode)
-		return dvb_ringbuffer_free(&sbuff->raw_data);
-
-	if (sbuff->pending_buffers_count == sbuff->buffers_num)
-		return 0;
-
-	desc = (struct mpq_streambuffer_buffer_desc *)
-		&sbuff->raw_data.data[sbuff->raw_data.pwrite];
-
-	return desc->size - desc->write_ptr;
-}
-EXPORT_SYMBOL(mpq_streambuffer_data_free);
-
-
-ssize_t mpq_streambuffer_data_avail(
-	struct mpq_streambuffer *sbuff)
-{
-	struct mpq_streambuffer_buffer_desc *desc;
-
-	if (NULL == sbuff)
-		return -EINVAL;
-
-	if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode)
-		return dvb_ringbuffer_avail(&sbuff->raw_data);
-
-	desc = (struct mpq_streambuffer_buffer_desc *)
-		&sbuff->raw_data.data[sbuff->raw_data.pread];
-
-	return desc->write_ptr - desc->read_ptr;
-}
-EXPORT_SYMBOL(mpq_streambuffer_data_avail);
-
diff --git a/drivers/media/dvb/mpq/demux/Makefile b/drivers/media/dvb/mpq/demux/Makefile
deleted file mode 100644
index b9310c3..0000000
--- a/drivers/media/dvb/mpq/demux/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-
-EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/
-EXTRA_CFLAGS += -Idrivers/media/dvb/mpq/include/
-
-obj-$(CONFIG_DVB_MPQ_DEMUX) += mpq-dmx-hw-plugin.o
-
-mpq-dmx-hw-plugin-y := mpq_dmx_plugin_common.o
-
-mpq-dmx-hw-plugin-$(CONFIG_DVB_MPQ_TSPP1) += mpq_dmx_plugin_tspp_v1.o
-
-mpq-dmx-hw-plugin-$(CONFIG_DVB_MPQ_TSPP2) += mpq_dmx_plugin_tspp_v2.o
-
-mpq-dmx-hw-plugin-$(CONFIG_DVB_MPQ_TSIF) += mpq_dmx_plugin_tsif.o
-
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c
deleted file mode 100644
index 2a60840..0000000
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c
+++ /dev/null
@@ -1,2135 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/module.h>
-#include <linux/vmalloc.h>
-#include <linux/file.h>
-#include "mpq_dvb_debug.h"
-#include "mpq_dmx_plugin_common.h"
-
-
-/* Length of mandatory fields that must exist in header of video PES */
-#define PES_MANDATORY_FIELDS_LEN			9
-
-
-/*
- * 500 PES header packets in the meta-data buffer,
- * should be more than enough
- */
-#define VIDEO_NUM_OF_PES_PACKETS			500
-
-#define VIDEO_META_DATA_BUFFER_SIZE              \
-	(VIDEO_NUM_OF_PES_PACKETS *                  \
-	  (DVB_RINGBUFFER_PKTHDRSIZE +               \
-	   sizeof(struct mpq_streambuffer_packet_header) + \
-	   sizeof(struct mpq_adapter_video_meta_data)))
-
-
-/* Number of demux devices, has default of linux configuration */
-static int mpq_demux_device_num = CONFIG_DVB_MPQ_NUM_DMX_DEVICES;
-module_param(mpq_demux_device_num, int, S_IRUGO);
-
-/**
- * Maximum allowed framing pattern size
- */
-#define MPQ_MAX_PATTERN_SIZE				6
-
-/**
- * Number of patterns to look for when doing framing, per video standard
- */
-#define MPQ_MPEG2_PATTERN_NUM				5
-#define MPQ_H264_PATTERN_NUM				5
-#define MPQ_VC1_PATTERN_NUM				3
-
-/*
- * mpq_framing_pattern_lookup_params - framing pattern lookup parameters.
- *
- * @pattern: the byte pattern to look for.
- * @mask: the byte mask to use (same length as pattern).
- * @size: the length of the pattern, in bytes.
- * @type: the type of the pattern.
- */
-struct mpq_framing_pattern_lookup_params {
-	u8 pattern[MPQ_MAX_PATTERN_SIZE];
-	u8 mask[MPQ_MAX_PATTERN_SIZE];
-	size_t size;
-	enum dmx_framing_pattern_type type;
-};
-
-/*
- * Pre-defined video framing lookup pattern information.
- * Note: the first pattern in each patterns database must
- * be the Sequence Header (or equivalent SPS in H.264).
- * The code assumes this is the case when prepending
- * Sequence Header data in case it is required.
- */
-static const struct mpq_framing_pattern_lookup_params
-		mpeg2_patterns[MPQ_MPEG2_PATTERN_NUM] = {
-	{{0x00, 0x00, 0x01, 0xB3}, {0xFF, 0xFF, 0xFF, 0xFF}, 4,
-			DMX_FRM_MPEG2_SEQUENCE_HEADER},
-	{{0x00, 0x00, 0x01, 0xB8}, {0xFF, 0xFF, 0xFF, 0xFF}, 4,
-			DMX_FRM_MPEG2_GOP_HEADER},
-	{{0x00, 0x00, 0x01, 0x00, 0x00, 0x08},
-			{0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x38}, 6,
-			DMX_FRM_MPEG2_I_PIC},
-	{{0x00, 0x00, 0x01, 0x00, 0x00, 0x10},
-			{0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x38}, 6,
-			DMX_FRM_MPEG2_P_PIC},
-	{{0x00, 0x00, 0x01, 0x00, 0x00, 0x18},
-			{0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x38}, 6,
-			DMX_FRM_MPEG2_B_PIC}
-};
-
-static const struct mpq_framing_pattern_lookup_params
-		h264_patterns[MPQ_H264_PATTERN_NUM] = {
-	{{0x00, 0x00, 0x01, 0x07}, {0xFF, 0xFF, 0xFF, 0x1F}, 4,
-			DMX_FRM_H264_SPS},
-	{{0x00, 0x00, 0x01, 0x08}, {0xFF, 0xFF, 0xFF, 0x1F}, 4,
-			DMX_FRM_H264_PPS},
-	{{0x00, 0x00, 0x01, 0x05, 0x80}, {0xFF, 0xFF, 0xFF, 0x1F, 0x80}, 5,
-			DMX_FRM_H264_IDR_PIC},
-	{{0x00, 0x00, 0x01, 0x01, 0x80}, {0xFF, 0xFF, 0xFF, 0x1F, 0x80}, 5,
-			DMX_FRM_H264_NON_IDR_PIC}
-};
-
-static const struct mpq_framing_pattern_lookup_params
-		vc1_patterns[MPQ_VC1_PATTERN_NUM] = {
-	{{0x00, 0x00, 0x01, 0x0F}, {0xFF, 0xFF, 0xFF, 0xFF}, 4,
-			DMX_FRM_VC1_SEQUENCE_HEADER},
-	{{0x00, 0x00, 0x01, 0x0E}, {0xFF, 0xFF, 0xFF, 0xFF}, 4,
-			DMX_FRM_VC1_ENTRY_POINT_HEADER},
-	{{0x00, 0x00, 0x01, 0x0D}, {0xFF, 0xFF, 0xFF, 0xFF}, 4,
-			DMX_FRM_VC1_FRAME_START_CODE}
-};
-
-/* Global data-structure for managing demux devices */
-static struct
-{
-	/* ION demux client used for memory allocation */
-	struct ion_client *ion_client;
-
-	/* demux devices array */
-	struct mpq_demux *devices;
-
-	/* Stream buffers objects used for tunneling to decoders */
-	struct mpq_streambuffer
-		decoder_buffers[MPQ_ADAPTER_MAX_NUM_OF_INTERFACES];
-
-	/*
-	 * Indicates whether the video decoder handles framing
-	 * or we are required to provide framing information
-	 * in the meta-data passed to the decoder.
-	 */
-	int decoder_framing;
-} mpq_dmx_info;
-
-/* Check that PES header is valid and that it is a video PES */
-static int mpq_dmx_is_valid_video_pes(struct pes_packet_header *pes_header)
-{
-	/* start-code valid? */
-	if ((pes_header->packet_start_code_prefix_1 != 0) ||
-		(pes_header->packet_start_code_prefix_2 != 0) ||
-		(pes_header->packet_start_code_prefix_3 != 1))
-		return -EINVAL;
-
-	/* stream_id is video? */
-	if ((pes_header->stream_id & 0xF0) != 0xE0)
-		return -EINVAL;
-
-	return 0;
-}
-
-/* Check if a framing pattern is a video frame pattern or a header pattern */
-static inline int mpq_dmx_is_video_frame(
-				enum dmx_indexing_video_standard standard,
-				enum dmx_framing_pattern_type pattern_type)
-{
-	switch (standard) {
-	case DMX_INDEXING_MPEG2:
-		if ((pattern_type == DMX_FRM_MPEG2_I_PIC) ||
-			(pattern_type == DMX_FRM_MPEG2_P_PIC) ||
-			(pattern_type == DMX_FRM_MPEG2_B_PIC))
-			return 1;
-		return 0;
-	case DMX_INDEXING_H264:
-		if ((pattern_type == DMX_FRM_H264_IDR_PIC) ||
-			(pattern_type == DMX_FRM_H264_NON_IDR_PIC))
-			return 1;
-		return 0;
-	case DMX_INDEXING_VC1:
-		if (pattern_type == DMX_FRM_VC1_FRAME_START_CODE)
-			return 1;
-		return 0;
-	default:
-		return -EINVAL;
-	}
-}
-
-/*
- * mpq_framing_pattern_lookup_results - framing lookup results
- *
- * @offset: The offset in the buffer where the pattern was found.
- * If a pattern is found using a prefix (i.e. started on the
- * previous buffer), offset is zero.
- * @type: the type of the pattern found.
- * @used_prefix_size: the prefix size that was used to find this pattern
- */
-struct mpq_framing_pattern_lookup_results {
-	struct {
-		u32 offset;
-		enum dmx_framing_pattern_type type;
-		u32 used_prefix_size;
-	} info[MPQ_MAX_FOUND_PATTERNS];
-};
-
-/*
- * Check if two patterns are identical, taking mask into consideration.
- * @pattern1: the first byte pattern to compare.
- * @pattern2: the second byte pattern to compare.
- * @mask: the bit mask to use.
- * @pattern_size: the length of both patterns and the mask, in bytes.
- *
- * Return: 1 if patterns match, 0 otherwise.
- */
-static inline int mpq_dmx_patterns_match(const u8 *pattern1, const u8 *pattern2,
-					const u8 *mask, size_t pattern_size)
-{
-	int i;
-
-	/*
-	 * Assumption: it is OK to access pattern1, pattern2 and mask.
-	 * This function performs no sanity checks to keep things fast.
-	 */
-
-	for (i = 0; i < pattern_size; i++)
-		if ((pattern1[i] & mask[i]) != (pattern2[i] & mask[i]))
-			return 0;
-
-	return 1;
-}
-
-/*
- * mpq_dmx_framing_pattern_search -
- * search for framing patterns in a given buffer.
- *
- * Optimized version: first search for a common substring, e.g. 0x00 0x00 0x01.
- * If this string is found, go over all the given patterns (all must start
- * with this string) and search for their ending in the buffer.
- *
- * Assumption: the patterns we look for do not spread over more than two
- * buffers.
- *
- * @paterns: the full patterns information to look for.
- * @patterns_num: the number of patterns to look for.
- * @buf: the buffer to search.
- * @buf_size: the size of the buffer to search. we search the entire buffer.
- * @prefix_size_masks: a bit mask (per pattern) of possible prefix sizes to use
- * when searching for a pattern that started at the last buffer.
- * Updated in this function for use in the next lookup.
- * @results: lookup results (offset, type, used_prefix_size) per found pattern,
- * up to MPQ_MAX_FOUND_PATTERNS.
- *
- * Return:
- *   Number of patterns found (up to MPQ_MAX_FOUND_PATTERNS).
- *   0 if pattern was not found.
- *   Negative error value on failure.
- */
-static int mpq_dmx_framing_pattern_search(
-		const struct mpq_framing_pattern_lookup_params *patterns,
-		int patterns_num,
-		const u8 *buf,
-		size_t buf_size,
-		struct mpq_framing_prefix_size_masks *prefix_size_masks,
-		struct mpq_framing_pattern_lookup_results *results)
-{
-	int i, j;
-	unsigned int current_size;
-	u32 prefix;
-	int found = 0;
-	int start_offset = 0;
-	/* the starting common substring to look for */
-	u8 string[] = {0x00, 0x00, 0x01};
-	/* the mask for the starting string */
-	u8 string_mask[] = {0xFF, 0xFF, 0xFF};
-	/* the size of the starting string (in bytes) */
-	size_t string_size = 3;
-
-	/* sanity checks - can be commented out for optimization purposes */
-	if ((patterns == NULL) || (patterns_num <= 0) || (buf == NULL)) {
-		MPQ_DVB_ERR_PRINT("%s: invalid parameters\n", __func__);
-		return -EINVAL;
-	}
-
-	memset(results, 0, sizeof(struct mpq_framing_pattern_lookup_results));
-
-	/*
-	 * handle prefix - disregard string, simply check all patterns,
-	 * looking for a matching suffix at the very beginning of the buffer.
-	 */
-	for (j = 0; (j < patterns_num) && !found; j++) {
-		prefix = prefix_size_masks->size_mask[j];
-		current_size = 32;
-		while (prefix) {
-			if (prefix & (0x1 << (current_size - 1))) {
-				/*
-				 * check that we don't look further
-				 * than buf_size boundary
-				 */
-				if ((int)(patterns[j].size - current_size) >
-						buf_size)
-					break;
-
-				if (mpq_dmx_patterns_match(
-					(patterns[j].pattern + current_size),
-					buf, (patterns[j].mask + current_size),
-					(patterns[j].size - current_size))) {
-
-					MPQ_DVB_DBG_PRINT(
-						"%s: Found matching pattern"
-						"using prefix of size %d\n",
-						__func__, current_size);
-					/*
-					 * pattern found using prefix at the
-					 * very beginning of the buffer, so
-					 * offset is 0, but we already zeroed
-					 * everything in the beginning of the
-					 * function. that's why the next line
-					 * is commented.
-					 */
-					/* results->info[found].offset = 0; */
-					results->info[found].type =
-							patterns[j].type;
-					results->info[found].used_prefix_size =
-							current_size;
-					found++;
-					/*
-					 * save offset to start looking from
-					 * in the buffer, to avoid reusing the
-					 * data of a pattern we already found.
-					 */
-					start_offset = (patterns[j].size -
-							current_size);
-
-					if (found >= MPQ_MAX_FOUND_PATTERNS)
-						goto next_prefix_lookup;
-					/*
-					 * we don't want to search for the same
-					 * pattern with several possible prefix
-					 * sizes if we have already found it,
-					 * so we break from the inner loop.
-					 * since we incremented 'found', we
-					 * will not search for additional
-					 * patterns using a prefix - that would
-					 * imply ambiguous patterns where one
-					 * pattern can be included in another.
-					 * the for loop will exit.
-					 */
-					break;
-				}
-			}
-			current_size--;
-			prefix &= ~(0x1 << (current_size - 1));
-		}
-	}
-
-	/*
-	 * Search buffer for entire pattern, starting with the string.
-	 * Note the external for loop does not execute if buf_size is
-	 * smaller than string_size (the cast to int is required, since
-	 * size_t is unsigned).
-	 */
-	for (i = start_offset; i < (int)(buf_size - string_size + 1); i++) {
-		if (mpq_dmx_patterns_match(string, (buf + i), string_mask,
-							string_size)) {
-			/* now search for patterns: */
-			for (j = 0; j < patterns_num; j++) {
-				/* avoid overflow to next buffer */
-				if ((i + patterns[j].size) > buf_size)
-					continue;
-
-				if (mpq_dmx_patterns_match(
-					(patterns[j].pattern + string_size),
-					(buf + i + string_size),
-					(patterns[j].mask + string_size),
-					(patterns[j].size - string_size))) {
-
-					results->info[found].offset = i;
-					results->info[found].type =
-						patterns[j].type;
-					/*
-					 * save offset to start next prefix
-					 * lookup, to avoid reusing the data
-					 * of any pattern we already found.
-					 */
-					if ((i + patterns[j].size) >
-							start_offset)
-						start_offset = (i +
-							patterns[j].size);
-					/*
-					 * did not use a prefix to find this
-					 * pattern, but we zeroed everything
-					 * in the beginning of the function.
-					 * So no need to zero used_prefix_size
-					 * for results->info[found]
-					 */
-
-					found++;
-					if (found >= MPQ_MAX_FOUND_PATTERNS)
-						goto next_prefix_lookup;
-					/*
-					 * theoretically we don't have to break
-					 * here, but we don't want to search
-					 * for the other matching patterns on
-					 * the very same same place in the
-					 * buffer. That would mean the
-					 * (pattern & mask) combinations are
-					 * not unique. So we break from inner
-					 * loop and move on to the next place
-					 * in the buffer.
-					 */
-					break;
-				}
-			}
-		}
-	}
-
-next_prefix_lookup:
-	/* check for possible prefix sizes for the next buffer */
-	for (j = 0; j < patterns_num; j++) {
-		prefix_size_masks->size_mask[j] = 0;
-		for (i = 1; i < patterns[j].size; i++) {
-			/*
-			 * avoid looking outside of the buffer
-			 * or reusing previously used data.
-			 */
-			if (i > (buf_size - start_offset))
-				break;
-
-			if (mpq_dmx_patterns_match(patterns[j].pattern,
-					(buf + buf_size - i),
-					patterns[j].mask, i)) {
-				prefix_size_masks->size_mask[j] |=
-						(1 << (i - 1));
-			}
-		}
-	}
-
-	return found;
-}
-
-/*
- * mpq_dmx_get_pattern_params -
- * get a pointer to the relevant pattern parameters structure,
- * based on the video parameters.
- *
- * @video_params: the video parameters (e.g. video standard).
- * @patterns: a pointer to a pointer to the pattern parameters,
- * updated by this function.
- * @patterns_num: number of patterns, updated by this function.
- */
-static inline int mpq_dmx_get_pattern_params(
-		struct dmx_indexing_video_params *video_params,
-		const struct mpq_framing_pattern_lookup_params **patterns,
-		int *patterns_num)
-{
-	switch (video_params->standard) {
-	case DMX_INDEXING_MPEG2:
-		*patterns = mpeg2_patterns;
-		*patterns_num = MPQ_MPEG2_PATTERN_NUM;
-		break;
-	case DMX_INDEXING_H264:
-		*patterns = h264_patterns;
-		*patterns_num = MPQ_H264_PATTERN_NUM;
-		break;
-	case DMX_INDEXING_VC1:
-		*patterns = vc1_patterns;
-		*patterns_num = MPQ_VC1_PATTERN_NUM;
-		break;
-	default:
-		MPQ_DVB_ERR_PRINT("%s: invalid parameters\n", __func__);
-		*patterns = NULL;
-		*patterns_num = 0;
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-/* Extend dvb-demux debugfs with HW statistics */
-void mpq_dmx_init_hw_statistics(struct mpq_demux *mpq_demux)
-{
-	/*
-	 * Extend dvb-demux debugfs with HW statistics.
-	 * Note that destruction of debugfs directory is done
-	 * when dvb-demux is terminated.
-	 */
-	mpq_demux->hw_notification_count = 0;
-	mpq_demux->hw_notification_interval = 0;
-	mpq_demux->hw_notification_size = 0;
-	mpq_demux->decoder_tsp_drop_count = 0;
-	mpq_demux->hw_notification_min_size = 0xFFFFFFFF;
-
-	if (mpq_demux->demux.dmx.debugfs_demux_dir != NULL) {
-		debugfs_create_u32(
-			"hw_notification_interval",
-			S_IRUGO|S_IWUGO,
-			mpq_demux->demux.dmx.debugfs_demux_dir,
-			&mpq_demux->hw_notification_interval);
-
-		debugfs_create_u32(
-			"hw_notification_min_interval",
-			S_IRUGO|S_IWUGO,
-			mpq_demux->demux.dmx.debugfs_demux_dir,
-			&mpq_demux->hw_notification_min_interval);
-
-		debugfs_create_u32(
-			"hw_notification_count",
-			S_IRUGO|S_IWUGO,
-			mpq_demux->demux.dmx.debugfs_demux_dir,
-			&mpq_demux->hw_notification_count);
-
-		debugfs_create_u32(
-			"hw_notification_size",
-			S_IRUGO|S_IWUGO,
-			mpq_demux->demux.dmx.debugfs_demux_dir,
-			&mpq_demux->hw_notification_size);
-
-		debugfs_create_u32(
-			"hw_notification_min_size",
-			S_IRUGO|S_IWUGO,
-			mpq_demux->demux.dmx.debugfs_demux_dir,
-			&mpq_demux->hw_notification_min_size);
-
-		debugfs_create_u32(
-			"decoder_tsp_drop_count",
-			S_IRUGO|S_IWUGO,
-			mpq_demux->demux.dmx.debugfs_demux_dir,
-			&mpq_demux->decoder_tsp_drop_count);
-	}
-}
-EXPORT_SYMBOL(mpq_dmx_init_hw_statistics);
-
-
-/* Update dvb-demux debugfs with HW notification statistics */
-void mpq_dmx_update_hw_statistics(struct mpq_demux *mpq_demux)
-{
-	struct timespec curr_time, delta_time;
-	u64 delta_time_ms;
-
-	curr_time = current_kernel_time();
-	if (likely(mpq_demux->hw_notification_count)) {
-		/* calculate time-delta between notifications */
-		delta_time =
-			timespec_sub(
-					curr_time,
-					mpq_demux->last_notification_time);
-
-		delta_time_ms = ((u64)delta_time.tv_sec * MSEC_PER_SEC) +
-					delta_time.tv_nsec / NSEC_PER_MSEC;
-
-		mpq_demux->hw_notification_interval = delta_time_ms;
-
-		if ((mpq_demux->hw_notification_count == 1) ||
-			(mpq_demux->hw_notification_interval &&
-			 mpq_demux->hw_notification_interval <
-				mpq_demux->hw_notification_min_interval))
-			mpq_demux->hw_notification_min_interval =
-				mpq_demux->hw_notification_interval;
-	}
-
-	mpq_demux->hw_notification_count++;
-	mpq_demux->last_notification_time = curr_time;
-}
-EXPORT_SYMBOL(mpq_dmx_update_hw_statistics);
-
-
-int mpq_dmx_plugin_init(mpq_dmx_init dmx_init_func)
-{
-	int i;
-	int result;
-	struct mpq_demux *mpq_demux;
-	struct dvb_adapter *mpq_adapter;
-
-	MPQ_DVB_DBG_PRINT("%s executed, device num %d\n",
-					  __func__,
-					  mpq_demux_device_num);
-
-	mpq_adapter = mpq_adapter_get();
-
-	if (mpq_adapter == NULL) {
-		MPQ_DVB_ERR_PRINT(
-			"%s: mpq_adapter is not valid\n",
-			__func__);
-		result = -EPERM;
-		goto init_failed;
-	}
-
-	if (mpq_demux_device_num == 0) {
-		MPQ_DVB_ERR_PRINT(
-			"%s: mpq_demux_device_num set to 0\n",
-			__func__);
-
-		result = -EPERM;
-		goto init_failed;
-	}
-
-	mpq_dmx_info.devices = NULL;
-	mpq_dmx_info.ion_client = NULL;
-
-	/*
-	 * TODO: the following should be set based on the decoder:
-	 * 0 means the decoder doesn't handle framing, so framing
-	 * is done by demux. 1 means the decoder handles framing.
-	 */
-	mpq_dmx_info.decoder_framing = 0;
-
-	/* Allocate memory for all MPQ devices */
-	mpq_dmx_info.devices =
-		vmalloc(mpq_demux_device_num*sizeof(struct mpq_demux));
-
-	if (!mpq_dmx_info.devices) {
-		MPQ_DVB_ERR_PRINT(
-				"%s: failed to allocate devices memory\n",
-				__func__);
-
-		result = -ENOMEM;
-		goto init_failed;
-	}
-
-	/* Zero allocated memory */
-	memset(mpq_dmx_info.devices,
-		   0,
-		   mpq_demux_device_num*sizeof(struct mpq_demux));
-
-	/*
-	 * Create a new ION client used by demux to allocate memory
-	 * for decoder's buffers.
-	 */
-	mpq_dmx_info.ion_client =
-		msm_ion_client_create(UINT_MAX, "demux_client");
-
-	if (IS_ERR_OR_NULL(mpq_dmx_info.ion_client)) {
-		MPQ_DVB_ERR_PRINT(
-				"%s: msm_ion_client_create\n",
-				__func__);
-
-		result = PTR_ERR(mpq_dmx_info.ion_client);
-		if (!result)
-			result = -ENOMEM;
-		mpq_dmx_info.ion_client = NULL;
-		goto init_failed_free_demux_devices;
-	}
-
-	/* Initialize and register all demux devices to the system */
-	for (i = 0; i < mpq_demux_device_num; i++) {
-		mpq_demux = mpq_dmx_info.devices+i;
-
-		/* initialize demux source to memory by default */
-		mpq_demux->source = DMX_SOURCE_DVR0 + i;
-
-		/*
-		 * Give the plugin pointer to the ion client so
-		 * that it can allocate memory from ION if it requires so
-		 */
-		mpq_demux->ion_client = mpq_dmx_info.ion_client;
-
-		spin_lock_init(&mpq_demux->feed_lock);
-
-		/*
-		 * mpq_demux_plugin_hw_init should be implemented
-		 * by the specific plugin
-		 */
-		result = dmx_init_func(mpq_adapter, mpq_demux);
-		if (result < 0) {
-			MPQ_DVB_ERR_PRINT(
-				"%s: dmx_init_func (errno=%d)\n",
-				__func__,
-				result);
-
-			goto init_failed_free_demux_devices;
-		}
-
-		mpq_demux->is_initialized = 1;
-
-		/*
-		 * Add capability of receiving input from memory.
-		 * Every demux in our system may be connected to memory input,
-		 * or any live input.
-		 */
-		mpq_demux->fe_memory.source = DMX_MEMORY_FE;
-		result =
-			mpq_demux->demux.dmx.add_frontend(
-					&mpq_demux->demux.dmx,
-					&mpq_demux->fe_memory);
-
-		if (result < 0) {
-			MPQ_DVB_ERR_PRINT(
-				"%s: add_frontend (mem) failed (errno=%d)\n",
-				__func__,
-				result);
-
-			goto init_failed_free_demux_devices;
-		}
-	}
-
-	return 0;
-
-init_failed_free_demux_devices:
-	mpq_dmx_plugin_exit();
-init_failed:
-	return result;
-}
-EXPORT_SYMBOL(mpq_dmx_plugin_init);
-
-
-void mpq_dmx_plugin_exit(void)
-{
-	int i;
-	struct mpq_demux *mpq_demux;
-
-	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
-
-	if (mpq_dmx_info.ion_client != NULL) {
-		ion_client_destroy(mpq_dmx_info.ion_client);
-		mpq_dmx_info.ion_client = NULL;
-	}
-
-	if (mpq_dmx_info.devices != NULL) {
-		for (i = 0; i < mpq_demux_device_num; i++) {
-			mpq_demux = mpq_dmx_info.devices + i;
-
-			if (mpq_demux->is_initialized) {
-				mpq_demux->demux.dmx.remove_frontend(
-							&mpq_demux->demux.dmx,
-							&mpq_demux->fe_memory);
-
-				dvb_dmxdev_release(&mpq_demux->dmxdev);
-				dvb_dmx_release(&mpq_demux->demux);
-			}
-		}
-
-		vfree(mpq_dmx_info.devices);
-		mpq_dmx_info.devices = NULL;
-	}
-}
-EXPORT_SYMBOL(mpq_dmx_plugin_exit);
-
-
-int mpq_dmx_set_source(
-		struct dmx_demux *demux,
-		const dmx_source_t *src)
-{
-	int i;
-	int dvr_index;
-	int dmx_index;
-	struct dvb_demux *dvb_demux = demux->priv;
-	struct mpq_demux *mpq_demux;
-
-	if ((mpq_dmx_info.devices == NULL) || (dvb_demux == NULL)) {
-		MPQ_DVB_ERR_PRINT("%s: invalid parameters\n", __func__);
-		return -EINVAL;
-	}
-
-	mpq_demux = dvb_demux->priv;
-	if (mpq_demux == NULL) {
-		MPQ_DVB_ERR_PRINT("%s: invalid parameters\n", __func__);
-		return -EINVAL;
-	}
-
-	/*
-	 * For dvr sources,
-	 * verify that this source is connected to the respective demux
-	 */
-	dmx_index = mpq_demux - mpq_dmx_info.devices;
-
-	if (*src >= DMX_SOURCE_DVR0) {
-		dvr_index = *src - DMX_SOURCE_DVR0;
-
-		if (dvr_index != dmx_index) {
-			MPQ_DVB_ERR_PRINT(
-				"%s: can't connect demux%d to dvr%d\n",
-				__func__,
-				dmx_index,
-				dvr_index);
-			return -EINVAL;
-		}
-	}
-
-	/*
-	 * For front-end sources,
-	 * verify that this source is not already set to different demux
-	 */
-	for (i = 0; i < mpq_demux_device_num; i++) {
-		if ((&mpq_dmx_info.devices[i] != mpq_demux) &&
-			(mpq_dmx_info.devices[i].source == *src)) {
-			MPQ_DVB_ERR_PRINT(
-				"%s: demux%d source can't be set,\n"
-				"demux%d occupies this source already\n",
-				__func__,
-				dmx_index,
-				i);
-			return -EBUSY;
-		}
-	}
-
-	mpq_demux->source = *src;
-	return 0;
-}
-EXPORT_SYMBOL(mpq_dmx_set_source);
-
-int mpq_dmx_map_buffer(struct dmx_demux *demux, struct dmx_buffer *dmx_buffer,
-		void **priv_handle, void **kernel_mem)
-{
-	struct dvb_demux *dvb_demux = demux->priv;
-	struct mpq_demux *mpq_demux;
-	struct ion_handle *ion_handle;
-	unsigned long ionflag = 0;
-	int ret;
-
-	if ((mpq_dmx_info.devices == NULL) || (dvb_demux == NULL) ||
-		(priv_handle == NULL) || (kernel_mem == NULL)) {
-		MPQ_DVB_ERR_PRINT("%s: invalid parameters\n", __func__);
-		return -EINVAL;
-	}
-
-	mpq_demux = dvb_demux->priv;
-	if (mpq_demux == NULL) {
-		MPQ_DVB_ERR_PRINT("%s: invalid parameters\n", __func__);
-		return -EINVAL;
-	}
-
-	ion_handle = ion_import_dma_buf(mpq_demux->ion_client,
-					dmx_buffer->handle);
-	if (IS_ERR_OR_NULL(ion_handle)) {
-		ret = PTR_ERR(ion_handle);
-		if (!ret)
-			ret = -ENOMEM;
-
-		MPQ_DVB_ERR_PRINT("%s: ion_import_dma_buf failed %d\n",
-			__func__, ret);
-		goto map_buffer_failed;
-	}
-
-	ret = ion_handle_get_flags(mpq_demux->ion_client, ion_handle, &ionflag);
-	if (ret) {
-		MPQ_DVB_ERR_PRINT("%s: ion_handle_get_flags failed %d\n",
-			__func__, ret);
-		goto map_buffer_failed_free_buff;
-	}
-
-	if (ionflag & ION_SECURE) {
-		MPQ_DVB_DBG_PRINT("%s: secured buffer\n", __func__);
-		/* TBD: Set buffer as secured */
-		*kernel_mem = NULL;
-	} else {
-		*kernel_mem = ion_map_kernel(mpq_demux->ion_client,
-						ion_handle);
-		if (*kernel_mem == NULL) {
-			MPQ_DVB_ERR_PRINT("%s: ion_map_kernel failed\n",
-				__func__);
-			ret = -ENOMEM;
-			goto map_buffer_failed_free_buff;
-		}
-	}
-
-	*priv_handle = (void *)ion_handle;
-	return 0;
-
-map_buffer_failed_free_buff:
-	ion_free(mpq_demux->ion_client, ion_handle);
-map_buffer_failed:
-	return ret;
-}
-EXPORT_SYMBOL(mpq_dmx_map_buffer);
-
-int mpq_dmx_unmap_buffer(struct dmx_demux *demux,
-		void *priv_handle)
-{
-	struct dvb_demux *dvb_demux = demux->priv;
-	struct ion_handle *ion_handle = priv_handle;
-	struct mpq_demux *mpq_demux;
-	unsigned long ionflag = 0;
-	int ret;
-
-	if ((mpq_dmx_info.devices == NULL) || (dvb_demux == NULL) ||
-		(priv_handle == NULL)) {
-		MPQ_DVB_ERR_PRINT("%s: invalid parameters\n", __func__);
-		return -EINVAL;
-	}
-
-	mpq_demux = dvb_demux->priv;
-	if (mpq_demux == NULL) {
-		MPQ_DVB_ERR_PRINT("%s: invalid parameters\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = ion_handle_get_flags(mpq_demux->ion_client, ion_handle, &ionflag);
-	if (ret) {
-		MPQ_DVB_ERR_PRINT("%s: ion_handle_get_flags failed %d\n",
-			__func__, ret);
-		return -EINVAL;
-	}
-
-	if (!(ionflag & ION_SECURE))
-		ion_unmap_kernel(mpq_demux->ion_client, ion_handle);
-
-	ion_free(mpq_demux->ion_client, ion_handle);
-
-	return 0;
-}
-EXPORT_SYMBOL(mpq_dmx_unmap_buffer);
-
-int mpq_dmx_init_video_feed(struct dvb_demux_feed *feed)
-{
-	int ret;
-	void *packet_buffer;
-	void *payload_buffer;
-	struct mpq_video_feed_info *feed_data;
-	struct mpq_demux *mpq_demux = feed->demux->priv;
-	struct mpq_streambuffer *stream_buffer;
-	int actual_buffer_size;
-
-	/* Allocate memory for private feed data */
-	feed_data = vmalloc(sizeof(struct mpq_video_feed_info));
-
-	if (feed_data == NULL) {
-		MPQ_DVB_ERR_PRINT(
-			"%s: FAILED to allocate private video feed data\n",
-			__func__);
-
-		ret = -ENOMEM;
-		goto init_failed;
-	}
-
-	/* get and store framing information if required */
-	if (!mpq_dmx_info.decoder_framing) {
-		mpq_dmx_get_pattern_params(&feed->indexing_params,
-				&feed_data->patterns, &feed_data->patterns_num);
-		if (feed_data->patterns == NULL) {
-			MPQ_DVB_ERR_PRINT(
-				"%s: FAILED to get framing pattern parameters\n",
-				__func__);
-
-			ret = -EINVAL;
-			goto init_failed_free_priv_data;
-		}
-	}
-
-	/* Allocate packet buffer holding the meta-data */
-	packet_buffer = vmalloc(VIDEO_META_DATA_BUFFER_SIZE);
-
-	if (packet_buffer == NULL) {
-		MPQ_DVB_ERR_PRINT(
-			"%s: FAILED to allocate packets buffer\n",
-			__func__);
-
-		ret = -ENOMEM;
-		goto init_failed_free_priv_data;
-	}
-
-	/*
-	 * Allocate payload buffer through ION.
-	 * TODO: for scrambling support, need to check if the
-	 * stream is scrambled and allocate the buffer with secure
-	 * flag set.
-	 */
-
-	actual_buffer_size = feed->buffer_size;
-
-	actual_buffer_size += (SZ_4K - 1);
-	actual_buffer_size &= ~(SZ_4K - 1);
-
-	feed_data->payload_buff_handle =
-		ion_alloc(mpq_demux->ion_client,
-				  actual_buffer_size,
-				  SZ_4K,
-				  ION_HEAP(ION_CP_MM_HEAP_ID),
-				  ION_FLAG_CACHED);
-
-	if (IS_ERR_OR_NULL(feed_data->payload_buff_handle)) {
-		ret = PTR_ERR(feed_data->payload_buff_handle);
-
-		MPQ_DVB_ERR_PRINT(
-			"%s: FAILED to allocate payload buffer %d\n",
-			__func__, ret);
-
-		if (!ret)
-			ret = -ENOMEM;
-		goto init_failed_free_packet_buffer;
-	}
-
-	payload_buffer =
-		ion_map_kernel(mpq_demux->ion_client,
-					   feed_data->payload_buff_handle);
-
-	if (IS_ERR_OR_NULL(payload_buffer)) {
-		ret = PTR_ERR(payload_buffer);
-
-		MPQ_DVB_ERR_PRINT(
-			"%s: FAILED to map payload buffer %d\n",
-			__func__, ret);
-
-		if (!ret)
-			ret = -ENOMEM;
-		goto init_failed_free_payload_buffer;
-	}
-
-	feed_data->buffer_desc.read_ptr = 0;
-	feed_data->buffer_desc.write_ptr = 0;
-	feed_data->buffer_desc.base = payload_buffer;
-	feed_data->buffer_desc.size = actual_buffer_size;
-	feed_data->buffer_desc.handle =
-		ion_share_dma_buf(
-			mpq_demux->ion_client,
-			feed_data->payload_buff_handle);
-	if (feed_data->buffer_desc.handle < 0) {
-		ret = -EFAULT;
-		goto init_failed_unmap_payload_buffer;
-	}
-
-	/* Register the new stream-buffer interface to MPQ adapter */
-	switch (feed->pes_type) {
-	case DMX_TS_PES_VIDEO0:
-		feed_data->stream_interface =
-			MPQ_ADAPTER_VIDEO0_STREAM_IF;
-		break;
-
-	case DMX_TS_PES_VIDEO1:
-		feed_data->stream_interface =
-			MPQ_ADAPTER_VIDEO1_STREAM_IF;
-		break;
-
-	case DMX_TS_PES_VIDEO2:
-		feed_data->stream_interface =
-			MPQ_ADAPTER_VIDEO2_STREAM_IF;
-		break;
-
-	case DMX_TS_PES_VIDEO3:
-		feed_data->stream_interface =
-			MPQ_ADAPTER_VIDEO3_STREAM_IF;
-		break;
-
-	default:
-		MPQ_DVB_ERR_PRINT(
-			"%s: Invalid pes type %d\n",
-			__func__,
-			feed->pes_type);
-		ret = -EINVAL;
-		goto init_failed_unshare_payload_buffer;
-	}
-
-	/* make sure not occupied already */
-	stream_buffer = NULL;
-	mpq_adapter_get_stream_if(
-			feed_data->stream_interface,
-			&stream_buffer);
-	if (stream_buffer != NULL) {
-		MPQ_DVB_ERR_PRINT(
-			"%s: Video interface %d already occupied!\n",
-			__func__,
-			feed_data->stream_interface);
-		ret = -EBUSY;
-		goto init_failed_unshare_payload_buffer;
-	}
-
-	feed_data->video_buffer =
-		&mpq_dmx_info.decoder_buffers[feed_data->stream_interface];
-
-	ret = mpq_streambuffer_init(
-		feed_data->video_buffer,
-		MPQ_STREAMBUFFER_BUFFER_MODE_RING,
-		&feed_data->buffer_desc,
-		1,
-		packet_buffer,
-		VIDEO_META_DATA_BUFFER_SIZE);
-	if (ret < 0) {
-		MPQ_DVB_ERR_PRINT(
-			"%s: mpq_streambuffer_init failed, err = %d\n",
-			__func__, ret);
-		goto init_failed_unshare_payload_buffer;
-	}
-
-	ret = mpq_adapter_register_stream_if(
-		feed_data->stream_interface,
-		feed_data->video_buffer);
-
-	if (ret < 0) {
-		MPQ_DVB_ERR_PRINT(
-			"%s: mpq_adapter_register_stream_if failed, "
-			"err = %d\n",
-			__func__, ret);
-		goto init_failed_unshare_payload_buffer;
-	}
-
-	feed->buffer_size = actual_buffer_size;
-	feed_data->pes_payload_address =
-		(u32)feed_data->video_buffer->raw_data.data;
-
-	feed_data->pes_header_left_bytes = PES_MANDATORY_FIELDS_LEN;
-	feed_data->pes_header_offset = 0;
-	feed->pusi_seen = 0;
-	feed->peslen = 0;
-	feed_data->fullness_wait_cancel = 0;
-	feed_data->last_framing_match_address = 0;
-	feed_data->last_framing_match_type = DMX_FRM_UNKNOWN;
-	feed_data->found_sequence_header_pattern = 0;
-	memset(&feed_data->prefix_size, 0,
-			sizeof(struct mpq_framing_prefix_size_masks));
-	feed_data->first_pattern_offset = 0;
-	feed_data->first_prefix_size = 0;
-	feed_data->saved_pts_dts_info.pts_exist = 0;
-	feed_data->saved_pts_dts_info.dts_exist = 0;
-	feed_data->new_pts_dts_info.pts_exist = 0;
-	feed_data->new_pts_dts_info.dts_exist = 0;
-	feed_data->saved_info_used = 1;
-	feed_data->new_info_exists = 0;
-	feed_data->first_pts_dts_copy = 1;
-
-	spin_lock(&mpq_demux->feed_lock);
-	feed->priv = (void *)feed_data;
-	spin_unlock(&mpq_demux->feed_lock);
-
-	return 0;
-
-init_failed_unshare_payload_buffer:
-	put_unused_fd(feed_data->buffer_desc.handle);
-init_failed_unmap_payload_buffer:
-	ion_unmap_kernel(mpq_demux->ion_client,
-					 feed_data->payload_buff_handle);
-init_failed_free_payload_buffer:
-	ion_free(mpq_demux->ion_client,
-			feed_data->payload_buff_handle);
-init_failed_free_packet_buffer:
-	vfree(packet_buffer);
-init_failed_free_priv_data:
-	vfree(feed_data);
-	feed->priv = NULL;
-init_failed:
-
-	return ret;
-}
-EXPORT_SYMBOL(mpq_dmx_init_video_feed);
-
-
-int mpq_dmx_terminate_video_feed(struct dvb_demux_feed *feed)
-{
-	struct mpq_video_feed_info *feed_data;
-	struct mpq_demux *mpq_demux;
-
-	if (feed->priv == NULL) {
-		MPQ_DVB_ERR_PRINT(
-			"%s: invalid feed, feed->priv is NULL\n",
-			__func__);
-
-		return -EINVAL;
-	}
-
-	mpq_demux = feed->demux->priv;
-	feed_data = feed->priv;
-
-	spin_lock(&mpq_demux->feed_lock);
-	feed->priv = NULL;
-	spin_unlock(&mpq_demux->feed_lock);
-
-	wake_up_all(&feed_data->video_buffer->raw_data.queue);
-
-	mpq_adapter_unregister_stream_if(feed_data->stream_interface);
-
-	vfree(feed_data->video_buffer->packet_data.data);
-
-	put_unused_fd(feed_data->buffer_desc.handle);
-
-	ion_unmap_kernel(mpq_demux->ion_client,
-					 feed_data->payload_buff_handle);
-
-	ion_free(mpq_demux->ion_client,
-			 feed_data->payload_buff_handle);
-
-	vfree(feed_data);
-
-	return 0;
-}
-EXPORT_SYMBOL(mpq_dmx_terminate_video_feed);
-
-int mpq_dmx_decoder_fullness_init(struct dvb_demux_feed *feed)
-{
-	struct mpq_demux *mpq_demux = feed->demux->priv;
-
-	if (mpq_dmx_is_video_feed(feed)) {
-		struct mpq_video_feed_info *feed_data;
-
-		spin_lock(&mpq_demux->feed_lock);
-
-		if (feed->priv == NULL) {
-			MPQ_DVB_ERR_PRINT(
-				"%s: invalid feed, feed->priv is NULL\n",
-				__func__);
-			spin_unlock(&mpq_demux->feed_lock);
-			return -EINVAL;
-		}
-
-		feed_data = feed->priv;
-		feed_data->fullness_wait_cancel = 0;
-
-		spin_unlock(&mpq_demux->feed_lock);
-
-		return 0;
-	}
-
-	/* else */
-	MPQ_DVB_DBG_PRINT(
-		"%s: Invalid feed type %d\n",
-		__func__,
-		feed->pes_type);
-
-	return -EINVAL;
-}
-EXPORT_SYMBOL(mpq_dmx_decoder_fullness_init);
-
-int mpq_dmx_decoder_fullness_wait(
-		struct dvb_demux_feed *feed,
-		size_t required_space)
-{
-	struct mpq_demux *mpq_demux = feed->demux->priv;
-
-	if (mpq_dmx_is_video_feed(feed)) {
-		int ret;
-		struct mpq_video_feed_info *feed_data;
-		struct dvb_ringbuffer *video_buff;
-
-		spin_lock(&mpq_demux->feed_lock);
-
-		if (feed->priv == NULL) {
-			spin_unlock(&mpq_demux->feed_lock);
-			return -EINVAL;
-		}
-
-		feed_data = feed->priv;
-		video_buff = &feed_data->video_buffer->raw_data;
-
-		ret = 0;
-		if ((feed_data != NULL) &&
-			(!feed_data->fullness_wait_cancel) &&
-			(dvb_ringbuffer_free(video_buff) < required_space)) {
-			DEFINE_WAIT(__wait);
-			for (;;) {
-				prepare_to_wait(
-					&video_buff->queue,
-					&__wait,
-					TASK_INTERRUPTIBLE);
-
-				if ((feed->priv == NULL) ||
-					(feed_data->fullness_wait_cancel) ||
-					(dvb_ringbuffer_free(video_buff) >=
-					required_space))
-					break;
-
-				if (!signal_pending(current)) {
-					spin_unlock(&mpq_demux->feed_lock);
-					schedule();
-					spin_lock(&mpq_demux->feed_lock);
-					continue;
-				}
-				ret = -ERESTARTSYS;
-				break;
-			}
-			finish_wait(&video_buff->queue, &__wait);
-		}
-
-		if (ret < 0) {
-			spin_unlock(&mpq_demux->feed_lock);
-			return ret;
-		}
-
-		if ((feed->priv == NULL) ||
-			(feed_data->fullness_wait_cancel)) {
-			spin_unlock(&mpq_demux->feed_lock);
-			return -EINVAL;
-		}
-
-		spin_unlock(&mpq_demux->feed_lock);
-		return 0;
-	}
-
-	/* else */
-	MPQ_DVB_DBG_PRINT(
-		"%s: Invalid feed type %d\n",
-		__func__,
-		feed->pes_type);
-
-	return -EINVAL;
-}
-EXPORT_SYMBOL(mpq_dmx_decoder_fullness_wait);
-
-int mpq_dmx_decoder_fullness_abort(struct dvb_demux_feed *feed)
-{
-	struct mpq_demux *mpq_demux = feed->demux->priv;
-
-	if (mpq_dmx_is_video_feed(feed)) {
-		struct mpq_video_feed_info *feed_data;
-		struct dvb_ringbuffer *video_buff;
-
-		spin_lock(&mpq_demux->feed_lock);
-
-		if (feed->priv == NULL) {
-			MPQ_DVB_ERR_PRINT(
-				"%s: invalid feed, feed->priv is NULL\n",
-				__func__);
-			spin_unlock(&mpq_demux->feed_lock);
-			return -EINVAL;
-		}
-
-		feed_data = feed->priv;
-
-		video_buff = &feed_data->video_buffer->raw_data;
-
-		feed_data->fullness_wait_cancel = 1;
-		spin_unlock(&mpq_demux->feed_lock);
-
-		wake_up_all(&video_buff->queue);
-
-		return 0;
-	}
-
-	/* else */
-	MPQ_DVB_ERR_PRINT(
-		"%s: Invalid feed type %d\n",
-		__func__,
-		feed->pes_type);
-
-	return -EINVAL;
-}
-EXPORT_SYMBOL(mpq_dmx_decoder_fullness_abort);
-
-
-static inline int mpq_dmx_parse_mandatory_pes_header(
-				struct dvb_demux_feed *feed,
-				struct mpq_video_feed_info *feed_data,
-				struct pes_packet_header *pes_header,
-				const u8 *buf,
-				u32 *ts_payload_offset,
-				int *bytes_avail)
-{
-	int left_size, copy_len;
-
-	if (feed_data->pes_header_offset < PES_MANDATORY_FIELDS_LEN) {
-		left_size =
-			PES_MANDATORY_FIELDS_LEN -
-			feed_data->pes_header_offset;
-
-		copy_len = (left_size > *bytes_avail) ?
-					*bytes_avail :
-					left_size;
-
-		memcpy((u8 *)((u8 *)pes_header + feed_data->pes_header_offset),
-				(buf + *ts_payload_offset),
-				copy_len);
-
-		feed_data->pes_header_offset += copy_len;
-
-		if (left_size > *bytes_avail)
-			return -EINVAL;
-
-		/* else - we have beginning of PES header */
-		*bytes_avail -= left_size;
-		*ts_payload_offset += left_size;
-
-		/* Make sure the PES packet is valid */
-		if (mpq_dmx_is_valid_video_pes(pes_header) < 0) {
-			/*
-			 * Since the new PES header parsing
-			 * failed, reset pusi_seen to drop all
-			 * data until next PUSI
-			 */
-			feed->pusi_seen = 0;
-			feed_data->pes_header_offset = 0;
-
-			MPQ_DVB_ERR_PRINT(
-				"%s: invalid packet\n",
-				__func__);
-
-			return -EINVAL;
-		}
-
-		feed_data->pes_header_left_bytes =
-			pes_header->pes_header_data_length;
-	}
-
-	return 0;
-}
-
-static inline void mpq_dmx_save_pts_dts(struct mpq_video_feed_info *feed_data)
-{
-	if (feed_data->new_info_exists) {
-		feed_data->saved_pts_dts_info.pts_exist =
-			feed_data->new_pts_dts_info.pts_exist;
-		feed_data->saved_pts_dts_info.pts =
-			feed_data->new_pts_dts_info.pts;
-		feed_data->saved_pts_dts_info.dts_exist =
-			feed_data->new_pts_dts_info.dts_exist;
-		feed_data->saved_pts_dts_info.dts =
-			feed_data->new_pts_dts_info.dts;
-
-		feed_data->new_info_exists = 0;
-		feed_data->saved_info_used = 0;
-	}
-}
-
-static inline void mpq_dmx_write_pts_dts(struct mpq_video_feed_info *feed_data,
-					struct dmx_pts_dts_info *info)
-{
-	if (!feed_data->saved_info_used) {
-		info->pts_exist = feed_data->saved_pts_dts_info.pts_exist;
-		info->pts = feed_data->saved_pts_dts_info.pts;
-		info->dts_exist = feed_data->saved_pts_dts_info.dts_exist;
-		info->dts = feed_data->saved_pts_dts_info.dts;
-
-		feed_data->saved_info_used = 1;
-	} else {
-		info->pts_exist = 0;
-		info->dts_exist = 0;
-	}
-}
-
-static inline void mpq_dmx_get_pts_dts(struct mpq_video_feed_info *feed_data,
-				struct pes_packet_header *pes_header)
-{
-	struct dmx_pts_dts_info *info = &(feed_data->new_pts_dts_info);
-
-	/* Get PTS/DTS information from PES header */
-
-	if ((pes_header->pts_dts_flag == 2) ||
-		(pes_header->pts_dts_flag == 3)) {
-		info->pts_exist = 1;
-
-		info->pts =
-			((u64)pes_header->pts_1 << 30) |
-			((u64)pes_header->pts_2 << 22) |
-			((u64)pes_header->pts_3 << 15) |
-			((u64)pes_header->pts_4 << 7) |
-			(u64)pes_header->pts_5;
-	} else {
-		info->pts_exist = 0;
-		info->pts = 0;
-	}
-
-	if (pes_header->pts_dts_flag == 3) {
-		info->dts_exist = 1;
-
-		info->dts =
-			((u64)pes_header->dts_1 << 30) |
-			((u64)pes_header->dts_2 << 22) |
-			((u64)pes_header->dts_3 << 15) |
-			((u64)pes_header->dts_4 << 7) |
-			(u64)pes_header->dts_5;
-	} else {
-		info->dts_exist = 0;
-		info->dts = 0;
-	}
-
-	feed_data->new_info_exists = 1;
-
-	if (feed_data->first_pts_dts_copy) {
-		mpq_dmx_save_pts_dts(feed_data);
-		feed_data->first_pts_dts_copy = 0;
-	}
-}
-
-static inline int mpq_dmx_parse_remaining_pes_header(
-				struct dvb_demux_feed *feed,
-				struct mpq_video_feed_info *feed_data,
-				struct pes_packet_header *pes_header,
-				const u8 *buf,
-				u32 *ts_payload_offset,
-				int *bytes_avail)
-{
-	int left_size, copy_len;
-
-	/* Remainning header bytes that need to be processed? */
-	if (!feed_data->pes_header_left_bytes)
-		return 0;
-
-	/* Did we capture the PTS value (if exists)? */
-	if ((*bytes_avail != 0) &&
-		(feed_data->pes_header_offset <
-		 (PES_MANDATORY_FIELDS_LEN+5)) &&
-		((pes_header->pts_dts_flag == 2) ||
-		 (pes_header->pts_dts_flag == 3))) {
-
-		/* 5 more bytes should be there */
-		left_size =
-			PES_MANDATORY_FIELDS_LEN + 5 -
-			feed_data->pes_header_offset;
-
-		copy_len = (left_size > *bytes_avail) ?
-					*bytes_avail :
-					left_size;
-
-		memcpy((u8 *)((u8 *)pes_header + feed_data->pes_header_offset),
-			(buf + *ts_payload_offset),
-			copy_len);
-
-		feed_data->pes_header_offset += copy_len;
-		feed_data->pes_header_left_bytes -= copy_len;
-
-		if (left_size > *bytes_avail)
-			return -EINVAL;
-
-		/* else - we have the PTS */
-		*bytes_avail -= copy_len;
-		*ts_payload_offset += copy_len;
-	}
-
-	/* Did we capture the DTS value (if exist)? */
-	if ((*bytes_avail != 0) &&
-		(feed_data->pes_header_offset <
-		 (PES_MANDATORY_FIELDS_LEN+10)) &&
-		(pes_header->pts_dts_flag == 3)) {
-
-		/* 5 more bytes should be there */
-		left_size =
-			PES_MANDATORY_FIELDS_LEN + 10 -
-			feed_data->pes_header_offset;
-
-		copy_len = (left_size > *bytes_avail) ?
-					*bytes_avail :
-					left_size;
-
-		memcpy((u8 *)((u8 *)pes_header + feed_data->pes_header_offset),
-			(buf + *ts_payload_offset),
-			copy_len);
-
-		feed_data->pes_header_offset += copy_len;
-		feed_data->pes_header_left_bytes -= copy_len;
-
-		if (left_size > *bytes_avail)
-			return -EINVAL;
-
-		/* else - we have the DTS */
-		*bytes_avail -= copy_len;
-		*ts_payload_offset += copy_len;
-	}
-
-	/* Any more header bytes?! */
-	if (feed_data->pes_header_left_bytes >= *bytes_avail) {
-		feed_data->pes_header_left_bytes -= *bytes_avail;
-		return -EINVAL;
-	}
-
-	/* get PTS/DTS information from PES header to be written later */
-	mpq_dmx_get_pts_dts(feed_data, pes_header);
-
-	/* Got PES header, process payload */
-	*bytes_avail -= feed_data->pes_header_left_bytes;
-	*ts_payload_offset += feed_data->pes_header_left_bytes;
-	feed_data->pes_header_left_bytes = 0;
-
-	return 0;
-}
-
-static int mpq_dmx_process_video_packet_framing(
-			struct dvb_demux_feed *feed,
-			const u8 *buf)
-{
-	int bytes_avail;
-	u32 ts_payload_offset;
-	struct mpq_video_feed_info *feed_data;
-	const struct ts_packet_header *ts_header;
-	struct mpq_streambuffer *stream_buffer;
-	struct pes_packet_header *pes_header;
-	struct mpq_demux *mpq_demux;
-
-	struct mpq_framing_pattern_lookup_results framing_res;
-	int found_patterns = 0;
-	int first_pattern = 0;
-	int i;
-	u32 pattern_addr = 0;
-	int is_video_frame = 0;
-
-	mpq_demux = feed->demux->priv;
-
-	spin_lock(&mpq_demux->feed_lock);
-
-	feed_data = feed->priv;
-	if (unlikely(feed_data == NULL)) {
-		spin_unlock(&mpq_demux->feed_lock);
-		return 0;
-	}
-
-	ts_header = (const struct ts_packet_header *)buf;
-
-	stream_buffer = feed_data->video_buffer;
-
-	pes_header = &feed_data->pes_header;
-
-	/* MPQ_DVB_DBG_PRINT("TS packet: %X %X %X %X %X%X %X %X %X\n",
-		ts_header->sync_byte,
-		ts_header->transport_error_indicator,
-		ts_header->payload_unit_start_indicator,
-		ts_header->transport_priority,
-		ts_header->pid_msb,
-		ts_header->pid_lsb,
-		ts_header->transport_scrambling_control,
-		ts_header->adaptation_field_control,
-		ts_header->continuity_counter); */
-
-	/* Make sure this TS packet has a payload and not scrambled */
-	if ((ts_header->sync_byte != 0x47) ||
-		(ts_header->adaptation_field_control == 0) ||
-		(ts_header->adaptation_field_control == 2) ||
-		(ts_header->transport_scrambling_control)) {
-		/* continue to next packet */
-		spin_unlock(&mpq_demux->feed_lock);
-		return 0;
-	}
-
-	if (ts_header->payload_unit_start_indicator) { /* PUSI? */
-		if (feed->pusi_seen) { /* Did we see PUSI before? */
-			/*
-			 * Double check that we are not in middle of
-			 * previous PES header parsing.
-			 */
-			if (feed_data->pes_header_left_bytes != 0) {
-				MPQ_DVB_ERR_PRINT(
-					"%s: received PUSI"
-					"while handling PES header"
-					"of previous PES\n",
-					__func__);
-			}
-
-			feed->peslen = 0;
-			feed_data->pes_header_offset = 0;
-			feed_data->pes_header_left_bytes =
-				PES_MANDATORY_FIELDS_LEN;
-		} else {
-			feed->pusi_seen = 1;
-		}
-	}
-
-	/*
-	 * Parse PES data only if PUSI was encountered,
-	 * otherwise the data is dropped
-	 */
-	if (!feed->pusi_seen) {
-		spin_unlock(&mpq_demux->feed_lock);
-		return 0; /* drop and wait for next packets */
-	}
-
-	ts_payload_offset = sizeof(struct ts_packet_header);
-
-	/* Skip adaptation field if exists */
-	if (ts_header->adaptation_field_control == 3)
-		ts_payload_offset += buf[ts_payload_offset] + 1;
-
-	/* 188 bytes: the size of a TS packet including the TS packet header */
-	bytes_avail = 188 - ts_payload_offset;
-
-	/* Get the mandatory fields of the video PES header */
-	if (mpq_dmx_parse_mandatory_pes_header(feed, feed_data,
-						pes_header, buf,
-						&ts_payload_offset,
-						&bytes_avail)) {
-		spin_unlock(&mpq_demux->feed_lock);
-		return 0;
-	}
-
-	if (mpq_dmx_parse_remaining_pes_header(feed, feed_data,
-						pes_header, buf,
-						&ts_payload_offset,
-						&bytes_avail)) {
-		spin_unlock(&mpq_demux->feed_lock);
-		return 0;
-	}
-
-	/*
-	 * If we reached here,
-	 * then we are now at the PES payload data
-	 */
-	if (bytes_avail == 0) {
-		spin_unlock(&mpq_demux->feed_lock);
-		return 0;
-	}
-
-	/*
-	 * the decoder requires demux to do framing,
-	 * so search for the patterns now.
-	 */
-	found_patterns = mpq_dmx_framing_pattern_search(
-				feed_data->patterns,
-				feed_data->patterns_num,
-				(buf + ts_payload_offset),
-				bytes_avail,
-				&feed_data->prefix_size,
-				&framing_res);
-
-	if (!(feed_data->found_sequence_header_pattern)) {
-		for (i = 0; i < found_patterns; i++) {
-			if ((framing_res.info[i].type ==
-				DMX_FRM_MPEG2_SEQUENCE_HEADER) ||
-			    (framing_res.info[i].type ==
-				DMX_FRM_H264_SPS) ||
-			    (framing_res.info[i].type ==
-				DMX_FRM_VC1_SEQUENCE_HEADER)) {
-
-				MPQ_DVB_DBG_PRINT(
-					"%s: Found Sequence Pattern, buf %p, "
-					"i = %d, offset = %d, type = %d\n",
-					__func__, buf, i,
-					framing_res.info[i].offset,
-					framing_res.info[i].type);
-
-				first_pattern = i;
-				feed_data->found_sequence_header_pattern = 1;
-				ts_payload_offset +=
-					framing_res.info[i].offset;
-				bytes_avail -= framing_res.info[i].offset;
-
-				if (framing_res.info[i].used_prefix_size) {
-					feed_data->first_prefix_size =
-						framing_res.info[i].
-							used_prefix_size;
-				}
-				/*
-				 * if this is the first pattern we write,
-				 * no need to take offset into account since we
-				 * dropped all data before it (so effectively
-				 * offset is 0).
-				 * we save the first pattern offset and take
-				 * it into consideration for the rest of the
-				 * patterns found in this buffer.
-				 */
-				feed_data->first_pattern_offset =
-					framing_res.info[i].offset;
-				break;
-			}
-		}
-	}
-
-	/*
-	 * If decoder requires demux to do framing,
-	 * pass data to decoder only after sequence header
-	 * or equivalent is found. Otherwise the data is dropped.
-	 */
-	if (!(feed_data->found_sequence_header_pattern)) {
-		spin_unlock(&mpq_demux->feed_lock);
-		return 0;
-	}
-
-	/*
-	 * write prefix used to find first Sequence pattern, if needed.
-	 * feed_data->patterns[0].pattern always contains the Sequence
-	 * pattern.
-	 */
-	if (feed_data->first_prefix_size) {
-		if (mpq_streambuffer_data_write(stream_buffer,
-					(feed_data->patterns[0].pattern),
-					feed_data->first_prefix_size) < 0) {
-			mpq_demux->decoder_tsp_drop_count++;
-			spin_unlock(&mpq_demux->feed_lock);
-			return 0;
-		}
-		feed_data->first_prefix_size = 0;
-	}
-	/* write data to payload buffer */
-	if (mpq_streambuffer_data_write(stream_buffer,
-					(buf + ts_payload_offset),
-					bytes_avail) < 0) {
-		mpq_demux->decoder_tsp_drop_count++;
-	} else {
-		struct mpq_streambuffer_packet_header packet;
-		struct mpq_adapter_video_meta_data meta_data;
-
-		feed->peslen += bytes_avail;
-
-		meta_data.packet_type = DMX_FRAMING_INFO_PACKET;
-		packet.raw_data_handle = feed_data->buffer_desc.handle;
-		packet.raw_data_offset = 0;
-		packet.user_data_len =
-				sizeof(struct mpq_adapter_video_meta_data);
-
-		for (i = first_pattern; i < found_patterns; i++) {
-			if (feed_data->last_framing_match_address) {
-				is_video_frame = mpq_dmx_is_video_frame(
-					feed->indexing_params.standard,
-					feed_data->last_framing_match_type);
-				if (is_video_frame == 1) {
-					mpq_dmx_write_pts_dts(feed_data,
-						&(meta_data.info.framing.
-							pts_dts_info));
-					mpq_dmx_save_pts_dts(feed_data);
-				} else {
-					meta_data.info.framing.
-						pts_dts_info.pts_exist = 0;
-					meta_data.info.framing.
-						pts_dts_info.dts_exist = 0;
-				}
-				/*
-				 * writing meta-data that includes
-				 * framing information
-				 */
-				meta_data.info.framing.pattern_type =
-					feed_data->last_framing_match_type;
-
-				pattern_addr = feed_data->pes_payload_address +
-					framing_res.info[i].offset -
-					framing_res.info[i].used_prefix_size;
-
-				if ((pattern_addr -
-					feed_data->first_pattern_offset) <
-					feed_data->last_framing_match_address) {
-					/* wraparound case */
-					packet.raw_data_len =
-						(pattern_addr -
-						feed_data->
-						   last_framing_match_address +
-						stream_buffer->raw_data.size) -
-						feed_data->first_pattern_offset;
-				} else {
-					packet.raw_data_len =
-					  pattern_addr -
-					  feed_data->
-						last_framing_match_address -
-					  feed_data->first_pattern_offset;
-				}
-
-				MPQ_DVB_DBG_PRINT(
-					"Writing Packet: len = %d, type = %d, isPts = %d, isDts = %d\n",
-					packet.raw_data_len,
-					meta_data.info.framing.pattern_type,
-					meta_data.info.framing.
-						pts_dts_info.pts_exist,
-					meta_data.info.framing.
-						pts_dts_info.dts_exist);
-
-				if (mpq_streambuffer_pkt_write(stream_buffer,
-					&packet,
-					(u8 *)&meta_data) < 0) {
-						MPQ_DVB_ERR_PRINT(
-							"%s: Couldn't write packet. Should never happen\n",
-								__func__);
-				}
-			}
-
-			/* save the last match for next time */
-			feed_data->last_framing_match_type =
-					framing_res.info[i].type;
-
-			feed_data->last_framing_match_address =
-				(feed_data->pes_payload_address +
-				framing_res.info[i].offset -
-				framing_res.info[i].used_prefix_size -
-				feed_data->first_pattern_offset);
-		}
-		/*
-		 * the first pattern offset is needed only for the group of
-		 * patterns that are found and written with the first pattern.
-		 */
-		feed_data->first_pattern_offset = 0;
-
-		feed_data->pes_payload_address =
-			(u32)stream_buffer->raw_data.data +
-			stream_buffer->raw_data.pwrite;
-	}
-
-	spin_unlock(&mpq_demux->feed_lock);
-
-	return 0;
-}
-
-static int mpq_dmx_process_video_packet_no_framing(
-			struct dvb_demux_feed *feed,
-			const u8 *buf)
-{
-	int bytes_avail;
-	u32 ts_payload_offset;
-	struct mpq_video_feed_info *feed_data;
-	const struct ts_packet_header *ts_header;
-	struct mpq_streambuffer *stream_buffer;
-	struct pes_packet_header *pes_header;
-	struct mpq_demux *mpq_demux;
-
-	mpq_demux = feed->demux->priv;
-
-	spin_lock(&mpq_demux->feed_lock);
-
-	feed_data = feed->priv;
-	if (unlikely(feed_data == NULL)) {
-		spin_unlock(&mpq_demux->feed_lock);
-		return 0;
-	}
-
-	ts_header = (const struct ts_packet_header *)buf;
-
-	stream_buffer =	feed_data->video_buffer;
-
-	pes_header = &feed_data->pes_header;
-
-	/* MPQ_DVB_DBG_PRINT("TS packet: %X %X %X %X %X%X %X %X %X\n",
-		ts_header->sync_byte,
-		ts_header->transport_error_indicator,
-		ts_header->payload_unit_start_indicator,
-		ts_header->transport_priority,
-		ts_header->pid_msb,
-		ts_header->pid_lsb,
-		ts_header->transport_scrambling_control,
-		ts_header->adaptation_field_control,
-		ts_header->continuity_counter); */
-
-	/* Make sure this TS packet has a payload and not scrambled */
-	if ((ts_header->sync_byte != 0x47) ||
-		(ts_header->adaptation_field_control == 0) ||
-		(ts_header->adaptation_field_control == 2) ||
-		(ts_header->transport_scrambling_control)) {
-		/* continue to next packet */
-		spin_unlock(&mpq_demux->feed_lock);
-		return 0;
-	}
-
-	if (ts_header->payload_unit_start_indicator) { /* PUSI? */
-		if (feed->pusi_seen) { /* Did we see PUSI before? */
-			struct mpq_streambuffer_packet_header packet;
-			struct mpq_adapter_video_meta_data meta_data;
-
-			/*
-			 * Close previous PES.
-			 * Push new packet to the meta-data buffer.
-			 * Double check that we are not in middle of
-			 * previous PES header parsing.
-			 */
-
-			if (0 == feed_data->pes_header_left_bytes) {
-				packet.raw_data_len = feed->peslen;
-				packet.raw_data_handle =
-					feed_data->buffer_desc.handle;
-				packet.raw_data_offset = 0;
-				packet.user_data_len =
-					sizeof(struct
-						mpq_adapter_video_meta_data);
-
-				mpq_dmx_write_pts_dts(feed_data,
-					&(meta_data.info.pes.pts_dts_info));
-				mpq_dmx_save_pts_dts(feed_data);
-
-				meta_data.packet_type = DMX_PES_PACKET;
-
-				if (mpq_streambuffer_pkt_write(
-						stream_buffer,
-						&packet,
-						(u8 *)&meta_data) < 0)
-					MPQ_DVB_ERR_PRINT(
-						"%s: "
-						"Couldn't write packet. "
-						"Should never happen\n",
-						__func__);
-			} else {
-				MPQ_DVB_ERR_PRINT(
-					"%s: received PUSI"
-					"while handling PES header"
-					"of previous PES\n",
-					__func__);
-			}
-
-			/* Reset PES info */
-			feed_data->pes_payload_address =
-				(u32)stream_buffer->raw_data.data +
-				stream_buffer->raw_data.pwrite;
-
-			feed->peslen = 0;
-			feed_data->pes_header_offset = 0;
-			feed_data->pes_header_left_bytes =
-				PES_MANDATORY_FIELDS_LEN;
-		} else {
-			feed->pusi_seen = 1;
-		}
-	}
-
-	/*
-	 * Parse PES data only if PUSI was encountered,
-	 * otherwise the data is dropped
-	 */
-	if (!feed->pusi_seen) {
-		spin_unlock(&mpq_demux->feed_lock);
-		return 0; /* drop and wait for next packets */
-	}
-
-	ts_payload_offset = sizeof(struct ts_packet_header);
-
-	/* Skip adaptation field if exists */
-	if (ts_header->adaptation_field_control == 3)
-		ts_payload_offset += buf[ts_payload_offset] + 1;
-
-	/* 188 bytes: size of a TS packet including the TS packet header */
-	bytes_avail = 188 - ts_payload_offset;
-
-	/* Get the mandatory fields of the video PES header */
-	if (mpq_dmx_parse_mandatory_pes_header(feed, feed_data,
-						pes_header, buf,
-						&ts_payload_offset,
-						&bytes_avail)) {
-		spin_unlock(&mpq_demux->feed_lock);
-		return 0;
-	}
-
-	if (mpq_dmx_parse_remaining_pes_header(feed, feed_data,
-						pes_header, buf,
-						&ts_payload_offset,
-						&bytes_avail)) {
-		spin_unlock(&mpq_demux->feed_lock);
-		return 0;
-	}
-
-	/*
-	 * If we reached here,
-	 * then we are now at the PES payload data
-	 */
-	if (bytes_avail == 0) {
-		spin_unlock(&mpq_demux->feed_lock);
-		return 0;
-	}
-
-	if (mpq_streambuffer_data_write(
-				stream_buffer,
-				buf+ts_payload_offset,
-				bytes_avail) < 0)
-		mpq_demux->decoder_tsp_drop_count++;
-	else
-		feed->peslen += bytes_avail;
-
-	spin_unlock(&mpq_demux->feed_lock);
-
-	return 0;
-}
-
-int mpq_dmx_decoder_buffer_status(struct dvb_demux_feed *feed,
-		struct dmx_buffer_status *dmx_buffer_status)
-{
-	struct mpq_demux *mpq_demux = feed->demux->priv;
-
-	if (mpq_dmx_is_video_feed(feed)) {
-		struct mpq_video_feed_info *feed_data;
-		struct dvb_ringbuffer *video_buff;
-
-		spin_lock(&mpq_demux->feed_lock);
-
-		if (feed->priv == NULL) {
-			MPQ_DVB_ERR_PRINT(
-				"%s: invalid feed, feed->priv is NULL\n",
-				__func__);
-			spin_unlock(&mpq_demux->feed_lock);
-			return -EINVAL;
-		}
-
-		feed_data = feed->priv;
-		video_buff = &feed_data->video_buffer->raw_data;
-
-		dmx_buffer_status->error = video_buff->error;
-		dmx_buffer_status->fullness = dvb_ringbuffer_avail(video_buff);
-		dmx_buffer_status->free_bytes = dvb_ringbuffer_free(video_buff);
-		dmx_buffer_status->read_offset = video_buff->pread;
-		dmx_buffer_status->write_offset = video_buff->pwrite;
-		dmx_buffer_status->size = video_buff->size;
-
-		spin_unlock(&mpq_demux->feed_lock);
-
-		return 0;
-	}
-
-	/* else */
-	MPQ_DVB_ERR_PRINT(
-		"%s: Invalid feed type %d\n",
-		__func__,
-		feed->pes_type);
-
-	return -EINVAL;
-}
-EXPORT_SYMBOL(mpq_dmx_decoder_buffer_status);
-
-int mpq_dmx_process_video_packet(
-			struct dvb_demux_feed *feed,
-			const u8 *buf)
-{
-	if (mpq_dmx_info.decoder_framing)
-		return mpq_dmx_process_video_packet_no_framing(feed, buf);
-	else
-		return mpq_dmx_process_video_packet_framing(feed, buf);
-}
-EXPORT_SYMBOL(mpq_dmx_process_video_packet);
-
-int mpq_dmx_process_pcr_packet(
-			struct dvb_demux_feed *feed,
-			const u8 *buf)
-{
-	u64 pcr;
-	u64 stc;
-	struct dmx_data_ready data;
-	struct mpq_demux *mpq_demux = feed->demux->priv;
-	const struct ts_packet_header *ts_header;
-	const struct ts_adaptation_field *adaptation_field;
-
-	/*
-	 * When we play from front-end, we configure HW
-	 * to output the extra timestamp, if we are playing
-	 * from DVR, make sure the format is 192 packet.
-	 */
-	if ((mpq_demux->source >= DMX_SOURCE_DVR0) &&
-		(mpq_demux->demux.tsp_format != DMX_TSP_FORMAT_192_TAIL)) {
-		MPQ_DVB_ERR_PRINT(
-			"%s: invalid packet format %d for PCR extraction\n",
-			__func__,
-			mpq_demux->demux.tsp_format);
-
-		 return -EINVAL;
-	}
-
-	ts_header = (const struct ts_packet_header *)buf;
-
-	/* Make sure this TS packet has a adaptation field */
-	if ((ts_header->sync_byte != 0x47) ||
-		(ts_header->adaptation_field_control == 0) ||
-		(ts_header->adaptation_field_control == 1)) {
-		return 0;
-	}
-
-	adaptation_field = (const struct ts_adaptation_field *)
-			(buf + sizeof(struct ts_packet_header));
-
-	if ((!adaptation_field->adaptation_field_length) ||
-		(!adaptation_field->PCR_flag))
-		return 0; /* 0 adaptation field or no PCR */
-
-	pcr = ((u64)adaptation_field->program_clock_reference_base_1) << 25;
-	pcr += ((u64)adaptation_field->program_clock_reference_base_2) << 17;
-	pcr += ((u64)adaptation_field->program_clock_reference_base_3) << 9;
-	pcr += ((u64)adaptation_field->program_clock_reference_base_4) << 1;
-	pcr += adaptation_field->program_clock_reference_base_5;
-	pcr *= 300;
-	pcr +=
-		(((u64)adaptation_field->program_clock_reference_ext_1) << 8) +
-		adaptation_field->program_clock_reference_ext_2;
-
-	stc = buf[190] << 16;
-	stc += buf[189] << 8;
-	stc += buf[188];
-	stc *= 256; /* convert from 105.47 KHZ to 27MHz */
-
-	data.data_length = 0;
-	data.pcr.pcr = pcr;
-	data.pcr.stc = stc;
-	data.pcr.disc_indicator_set = adaptation_field->discontinuity_indicator;
-	data.status = DMX_OK_PCR;
-	feed->data_ready_cb.ts(&feed->feed.ts, &data);
-
-	return 0;
-}
-EXPORT_SYMBOL(mpq_dmx_process_pcr_packet);
-
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h
deleted file mode 100644
index f7af1ef..0000000
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h
+++ /dev/null
@@ -1,591 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 _MPQ_DMX_PLUGIN_COMMON_H
-#define _MPQ_DMX_PLUGIN_COMMON_H
-
-#include <linux/msm_ion.h>
-
-#include "dvbdev.h"
-#include "dmxdev.h"
-#include "demux.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "mpq_adapter.h"
-
-
-/* Max number open() request can be done on demux device */
-#define MPQ_MAX_DMX_FILES				128
-
-
-/**
- * TSIF alias name length
- */
-#define TSIF_NAME_LENGTH				20
-
-#define MPQ_MAX_FOUND_PATTERNS				5
-
-/**
- * struct mpq_demux - mpq demux information
- * @demux: The dvb_demux instance used by mpq_demux
- * @dmxdev: The dmxdev instance used by mpq_demux
- * @fe_memory: Handle of front-end memory source to mpq_demux
- * @source: The current source connected to the demux
- * @is_initialized: Indicates whether this demux device was
- *                  initialized or not.
- * @ion_client: ION demux client used to allocate memory from ION.
- * @feed_lock: Lock used to protect against private feed data
- * @hw_notification_interval: Notification interval in msec,
- *                            exposed in debugfs.
- * @hw_notification_min_interval: Minimum notification internal in msec,
- * exposed in debugfs.
- * @hw_notification_count: Notification count, exposed in debugfs.
- * @hw_notification_size: Notification size in bytes, exposed in debugfs.
- * @hw_notification_min_size: Minimum notification size in bytes,
- *                            exposed in debugfs.
- * @decoder_tsp_drop_count: Counter of number of dropped TS packets
- * due to decoder buffer fullness, exposed in debugfs.
- * @last_notification_time: Time of last HW notification.
- */
-struct mpq_demux {
-	struct dvb_demux demux;
-	struct dmxdev dmxdev;
-	struct dmx_frontend fe_memory;
-	dmx_source_t source;
-	int is_initialized;
-	struct ion_client *ion_client;
-	spinlock_t feed_lock;
-
-	/* debug-fs */
-	u32 hw_notification_interval;
-	u32 hw_notification_min_interval;
-	u32 hw_notification_count;
-	u32 hw_notification_size;
-	u32 hw_notification_min_size;
-	u32 decoder_tsp_drop_count;
-	struct timespec last_notification_time;
-};
-
-/**
- * mpq_dmx_init - initialization and registration function of
- * single MPQ demux device
- *
- * @adapter: The adapter to register mpq_demux to
- * @mpq_demux: The mpq demux to initialize
- *
- * Every HW pluging need to provide implementation of such
- * function that will be called for each demux device on the
- * module initialization. The function mpq_demux_plugin_init
- * should be called during the HW plugin module initialization.
- */
-typedef int (*mpq_dmx_init)(
-				struct dvb_adapter *mpq_adapter,
-				struct mpq_demux *demux);
-
-/**
- * struct ts_packet_header - Transport packet header
- * as defined in MPEG2 transport stream standard.
- */
-struct ts_packet_header {
-#if defined(__BIG_ENDIAN_BITFIELD)
-	unsigned sync_byte:8;
-	unsigned transport_error_indicator:1;
-	unsigned payload_unit_start_indicator:1;
-	unsigned transport_priority:1;
-	unsigned pid_msb:5;
-	unsigned pid_lsb:8;
-	unsigned transport_scrambling_control:2;
-	unsigned adaptation_field_control:2;
-	unsigned continuity_counter:4;
-#elif defined(__LITTLE_ENDIAN_BITFIELD)
-	unsigned sync_byte:8;
-	unsigned pid_msb:5;
-	unsigned transport_priority:1;
-	unsigned payload_unit_start_indicator:1;
-	unsigned transport_error_indicator:1;
-	unsigned pid_lsb:8;
-	unsigned continuity_counter:4;
-	unsigned adaptation_field_control:2;
-	unsigned transport_scrambling_control:2;
-#else
-#error "Please fix <asm/byteorder.h>"
-#endif
-} __packed;
-
-/**
- * struct ts_adaptation_field - Adaptation field prefix
- * as defined in MPEG2 transport stream standard.
- */
-struct ts_adaptation_field {
-#if defined(__BIG_ENDIAN_BITFIELD)
-	unsigned adaptation_field_length:8;
-	unsigned discontinuity_indicator:1;
-	unsigned random_access_indicator:1;
-	unsigned elementary_stream_priority_indicator:1;
-	unsigned PCR_flag:1;
-	unsigned OPCR_flag:1;
-	unsigned splicing_point_flag:1;
-	unsigned transport_private_data_flag:1;
-	unsigned adaptation_field_extension_flag:1;
-	unsigned program_clock_reference_base_1:8;
-	unsigned program_clock_reference_base_2:8;
-	unsigned program_clock_reference_base_3:8;
-	unsigned program_clock_reference_base_4:8;
-	unsigned program_clock_reference_base_5:1;
-	unsigned reserved:6;
-	unsigned program_clock_reference_ext_1:1;
-	unsigned program_clock_reference_ext_2:8;
-#elif defined(__LITTLE_ENDIAN_BITFIELD)
-	unsigned adaptation_field_length:8;
-	unsigned adaptation_field_extension_flag:1;
-	unsigned transport_private_data_flag:1;
-	unsigned splicing_point_flag:1;
-	unsigned OPCR_flag:1;
-	unsigned PCR_flag:1;
-	unsigned elementary_stream_priority_indicator:1;
-	unsigned random_access_indicator:1;
-	unsigned discontinuity_indicator:1;
-	unsigned program_clock_reference_base_1:8;
-	unsigned program_clock_reference_base_2:8;
-	unsigned program_clock_reference_base_3:8;
-	unsigned program_clock_reference_base_4:8;
-	unsigned program_clock_reference_ext_1:1;
-	unsigned reserved:6;
-	unsigned program_clock_reference_base_5:1;
-	unsigned program_clock_reference_ext_2:8;
-#else
-#error "Please fix <asm/byteorder.h>"
-#endif
-} __packed;
-
-
-/*
- * PES packet header containing dts and/or pts values
- * as defined in MPEG2 transport stream standard.
- */
-struct pes_packet_header {
-#if defined(__BIG_ENDIAN_BITFIELD)
-	unsigned packet_start_code_prefix_1:8;
-	unsigned packet_start_code_prefix_2:8;
-	unsigned packet_start_code_prefix_3:8;
-	unsigned stream_id:8;
-	unsigned pes_packet_length_msb:8;
-	unsigned pes_packet_length_lsb:8;
-	unsigned reserved_bits0:2;
-	unsigned pes_scrambling_control:2;
-	unsigned pes_priority:1;
-	unsigned data_alignment_indicator:1;
-	unsigned copyright:1;
-	unsigned original_or_copy:1;
-	unsigned pts_dts_flag:2;
-	unsigned escr_flag:1;
-	unsigned es_rate_flag:1;
-	unsigned dsm_trick_mode_flag:1;
-	unsigned additional_copy_info_flag:1;
-	unsigned pes_crc_flag:1;
-	unsigned pes_extension_flag:1;
-	unsigned pes_header_data_length:8;
-	unsigned reserved_bits1:4;
-	unsigned pts_1:3;
-	unsigned marker_bit0:1;
-	unsigned pts_2:8;
-	unsigned pts_3:7;
-	unsigned marker_bit1:1;
-	unsigned pts_4:8;
-	unsigned pts_5:7;
-	unsigned marker_bit2:1;
-	unsigned reserved_bits2:4;
-	unsigned dts_1:3;
-	unsigned marker_bit3:1;
-	unsigned dts_2:8;
-	unsigned dts_3:7;
-	unsigned marker_bit4:1;
-	unsigned dts_4:8;
-	unsigned dts_5:7;
-	unsigned marker_bit5:1;
-	unsigned reserved_bits3:4;
-#elif defined(__LITTLE_ENDIAN_BITFIELD)
-	unsigned packet_start_code_prefix_1:8;
-	unsigned packet_start_code_prefix_2:8;
-	unsigned packet_start_code_prefix_3:8;
-	unsigned stream_id:8;
-	unsigned pes_packet_length_lsb:8;
-	unsigned pes_packet_length_msb:8;
-	unsigned original_or_copy:1;
-	unsigned copyright:1;
-	unsigned data_alignment_indicator:1;
-	unsigned pes_priority:1;
-	unsigned pes_scrambling_control:2;
-	unsigned reserved_bits0:2;
-	unsigned pes_extension_flag:1;
-	unsigned pes_crc_flag:1;
-	unsigned additional_copy_info_flag:1;
-	unsigned dsm_trick_mode_flag:1;
-	unsigned es_rate_flag:1;
-	unsigned escr_flag:1;
-	unsigned pts_dts_flag:2;
-	unsigned pes_header_data_length:8;
-	unsigned marker_bit0:1;
-	unsigned pts_1:3;
-	unsigned reserved_bits1:4;
-	unsigned pts_2:8;
-	unsigned marker_bit1:1;
-	unsigned pts_3:7;
-	unsigned pts_4:8;
-	unsigned marker_bit2:1;
-	unsigned pts_5:7;
-	unsigned marker_bit3:1;
-	unsigned dts_1:3;
-	unsigned reserved_bits2:4;
-	unsigned dts_2:8;
-	unsigned marker_bit4:1;
-	unsigned dts_3:7;
-	unsigned dts_4:8;
-	unsigned marker_bit5:1;
-	unsigned dts_5:7;
-	unsigned reserved_bits3:4;
-#else
-#error "Please fix <asm/byteorder.h>"
-#endif
-} __packed;
-
-/*
- * mpq_framing_prefix_size_masks - possible prefix sizes.
- *
- * @size_mask: a bit mask (per pattern) of possible prefix sizes to use
- * when searching for a pattern that started in the last buffer.
- * Updated in mpq_dmx_framing_pattern_search for use in the next lookup
- */
-struct mpq_framing_prefix_size_masks {
-	u32 size_mask[MPQ_MAX_FOUND_PATTERNS];
-};
-
-/*
- * mpq_video_feed_info - private data used for video feed.
- *
- * @plugin_data: Underlying plugin's own private data.
- * @video_buffer: Holds the streamer buffer shared with
- * the decoder for feeds having the data going to the decoder.
- * @buffer_desc: Holds decoder buffer(s) information used for stream buffer.
- * @pes_header: Used for feeds that output data to decoder,
- * holds PES header of current processed PES.
- * @pes_header_left_bytes: Used for feeds that output data to decoder,
- * holds remainning PES header bytes of current processed PES.
- * @pes_header_offset: Holds the offset within the current processed
- * pes header.
- * @fullness_wait_cancel: Flag used to signal to abort waiting for
- * decoder's fullness.
- * @pes_payload_address: Used for feeds that output data to decoder,
- * holds current PES payload start address.
- * @payload_buff_handle: ION handle for the allocated payload buffer
- * @stream_interface: The ID of the video stream interface registered
- * with this stream buffer.
- * @patterns: pointer to the framing patterns to look for.
- * @patterns_num: number of framing patterns.
- * @last_framing_match_address: Used for saving the raw data address of
- * the previous pattern match found in this video feed.
- * @last_framing_match_type: Used for saving the type of
- * the previous pattern match found in this video feed.
- * @found_sequence_header_pattern: Flag used to note that an MPEG-2
- * Sequence Header, H.264 SPS or VC-1 Sequence Header pattern
- * (whichever is relevant according to the video standard) had already
- * been found.
- * @prefix_size: a bit mask representing the size(s) of possible prefixes
- * to the pattern, already found in the previous buffer. If bit 0 is set,
- * a prefix of size 1 was found. If bit 1 is set, a prefix of size 2 was
- * found, etc. This supports a prefix size of up to 32, which is more
- * than we need. The search function updates prefix_size as needed
- * for the next buffer search.
- * @first_pattern_offset: used to save the offset of the first pattern written
- * to the stream buffer.
- * @first_prefix_size: used to save the prefix size used to find the first
- * pattern written to the stream buffer.
- * @saved_pts_dts_info: used to save PTS/DTS information until it is written.
- * @new_pts_dts_info: used to store PTS/DTS information from current PES header.
- * @saved_info_used: indicates if saved PTS/DTS information was used.
- * @new_info_exists: indicates if new PTS/DTS information exists in
- * new_pts_dts_info that should be saved to saved_pts_dts_info.
- * @first_pts_dts_copy: a flag used to indicate if PTS/DTS information needs
- * to be copied from the currently parsed PES header to the saved_pts_dts_info.
- */
-struct mpq_video_feed_info {
-	void *plugin_data;
-	struct mpq_streambuffer *video_buffer;
-	struct mpq_streambuffer_buffer_desc buffer_desc;
-	struct pes_packet_header pes_header;
-	u32 pes_header_left_bytes;
-	u32 pes_header_offset;
-	u32 pes_payload_address;
-	int fullness_wait_cancel;
-	struct ion_handle *payload_buff_handle;
-	enum mpq_adapter_stream_if stream_interface;
-	const struct mpq_framing_pattern_lookup_params *patterns;
-	int patterns_num;
-	u32 last_framing_match_address;
-	enum dmx_framing_pattern_type last_framing_match_type;
-	int found_sequence_header_pattern;
-	struct mpq_framing_prefix_size_masks prefix_size;
-	u32 first_pattern_offset;
-	u32 first_prefix_size;
-	struct dmx_pts_dts_info saved_pts_dts_info;
-	struct dmx_pts_dts_info new_pts_dts_info;
-	int saved_info_used;
-	int new_info_exists;
-	int first_pts_dts_copy;
-};
-
-/**
- * mpq_demux_plugin_init - Initialize demux devices and register
- * them to the dvb adapter.
- *
- * @dmx_init_func: Pointer to the function to be used
- *  to initialize demux of the underlying HW plugin.
- *
- * Return     error code
- *
- * Should be called at the HW plugin module initialization.
- */
-int mpq_dmx_plugin_init(mpq_dmx_init dmx_init_func);
-
-/**
- * mpq_demux_plugin_exit - terminate demux devices.
- *
- * Should be called at the HW plugin module termination.
- */
-void mpq_dmx_plugin_exit(void);
-
-/**
- * mpq_dmx_set_source - implmenetation of set_source routine.
- *
- * @demux: The demux device to set its source.
- * @src: The source to be set.
- *
- * Return     error code
- *
- * Can be used by the underlying plugins to implement kernel
- * demux API set_source routine.
- */
-int mpq_dmx_set_source(struct dmx_demux *demux, const dmx_source_t *src);
-
-/**
- * mpq_dmx_map_buffer - map user-space buffer into kernel space.
- *
- * @demux: The demux device.
- * @dmx_buffer: The demux buffer from user-space, assumes that
- * buffer handle is ION file-handle.
- * @priv_handle: Saves ION-handle of the buffer imported by this function.
- * @kernel_mem: Saves kernel mapped address of the buffer.
- *
- * Return     error code
- *
- * The function maps the buffer into kernel memory only if the buffer
- * was not allocated with secure flag, otherwise the returned kernel
- * memory address is set to NULL.
- */
-int mpq_dmx_map_buffer(struct dmx_demux *demux, struct dmx_buffer *dmx_buffer,
-		void **priv_handle, void **kernel_mem);
-
-/**
- * mpq_dmx_unmap_buffer - unmap user-space buffer from kernel space memory.
- *
- * @demux: The demux device.
- * @priv_handle: ION-handle of the buffer returned from mpq_dmx_map_buffer.
- *
- * Return     error code
- *
- * The function unmaps the buffer from kernel memory only if the buffer
- * was not allocated with secure flag.
- */
-int mpq_dmx_unmap_buffer(struct dmx_demux *demux,
-		void *priv_handle);
-
-/**
- * mpq_dmx_init_video_feed - Initializes video feed
- * used to pass data to decoder directly.
- *
- * @feed: The feed used for the video TS packets
- *
- * Return     error code.
- *
- * If the underlying plugin wishes to perform SW PES assmebly
- * for the video data and stream it to the decoder, it should
- * call this function when video feed is initialized before
- * using mpq_dmx_process_video_packet.
- *
- * The function allocates mpq_video_feed_info and saves in
- * feed->priv.
- */
-int mpq_dmx_init_video_feed(struct dvb_demux_feed *feed);
-
-/**
- * mpq_dmx_terminate_video_feed - Free private data of
- * video feed allocated in mpq_dmx_init_video_feed
- *
- * @feed: The feed used for the video TS packets
- *
- * Return     error code.
- */
-int mpq_dmx_terminate_video_feed(struct dvb_demux_feed *feed);
-
-/**
- * mpq_dmx_decoder_fullness_init - Initialize waiting
- * mechanism on decoder's buffer fullness.
- *
- * @feed: The decoder's feed
- *
- * Return     error code.
- */
-int mpq_dmx_decoder_fullness_init(struct dvb_demux_feed *feed);
-
-/**
- * mpq_dmx_decoder_fullness_wait - Checks whether decoder buffer
- * have free space as required, if not, wait for it.
- *
- * @feed: The decoder's feed
- * @required_space: the required free space to wait for
- *
- * Return     error code.
- */
-int mpq_dmx_decoder_fullness_wait(struct dvb_demux_feed *feed,
-		size_t required_space);
-
-/**
- * mpq_dmx_decoder_fullness_abort - Aborts waiting
- * on decoder's buffer fullness if any waiting is done
- * now. After calling this, to wait again the user must
- * call mpq_dmx_decoder_fullness_init.
- *
- * @feed: The decoder's feed
- *
- * Return     error code.
- */
-int mpq_dmx_decoder_fullness_abort(struct dvb_demux_feed *feed);
-
-/**
- * mpq_dmx_decoder_buffer_status - Returns the
- * status of the decoder's buffer.
- *
- * @feed: The decoder's feed
- * @dmx_buffer_status: Status of decoder's buffer
- *
- * Return     error code.
- */
-int mpq_dmx_decoder_buffer_status(struct dvb_demux_feed *feed,
-		struct dmx_buffer_status *dmx_buffer_status);
-
-/**
- * mpq_dmx_process_video_packet - Assemble PES data and output it
- * to the stream-buffer connected to the decoder.
- *
- * @feed: The feed used for the video TS packets
- * @buf: The buffer holding video TS packet.
- *
- * Return     error code.
- *
- * The function assumes it receives buffer with single TS packet
- * of the relevant PID.
- * If the output buffer is full while assembly, the function drops
- * the packet and does not write them to the output buffer.
- * Scrambled packets are bypassed.
- */
-int mpq_dmx_process_video_packet(struct dvb_demux_feed *feed, const u8 *buf);
-
-/**
- * mpq_dmx_process_pcr_packet - Extract PCR/STC pairs from
- * a 192 bytes packet.
- *
- * @feed: The feed used for the PCR TS packets
- * @buf: The buffer holding pcr/stc packet.
- *
- * Return     error code.
- *
- * The function assumes it receives buffer with single TS packet
- * of the relevant PID, and that it has 4 bytes
- * suffix as extra timestamp in the following format:
- *
- * Byte3: TSIF flags
- * Byte0-2: TTS, 0..2^24-1 at 105.47 Khz (27*10^6/256).
- *
- * The function callbacks dmxdev after extraction of the pcr/stc
- * pair.
- */
-int mpq_dmx_process_pcr_packet(struct dvb_demux_feed *feed, const u8 *buf);
-
-/**
- * mpq_dmx_is_video_feed - Returns whether the PES feed
- * is video one.
- *
- * @feed: The feed to be checked.
- *
- * Return     1 if feed is video feed, 0 otherwise.
- */
-static inline int mpq_dmx_is_video_feed(struct dvb_demux_feed *feed)
-{
-	if (feed->type != DMX_TYPE_TS)
-		return 0;
-
-	if (feed->ts_type & (~TS_DECODER))
-		return 0;
-
-	if ((feed->pes_type == DMX_TS_PES_VIDEO0) ||
-		(feed->pes_type == DMX_TS_PES_VIDEO1) ||
-		(feed->pes_type == DMX_TS_PES_VIDEO2) ||
-		(feed->pes_type == DMX_TS_PES_VIDEO3))
-		return 1;
-
-	return 0;
-}
-
-/**
- * mpq_dmx_is_pcr_feed - Returns whether the PES feed
- * is PCR one.
- *
- * @feed: The feed to be checked.
- *
- * Return     1 if feed is PCR feed, 0 otherwise.
- */
-static inline int mpq_dmx_is_pcr_feed(struct dvb_demux_feed *feed)
-{
-	if (feed->type != DMX_TYPE_TS)
-		return 0;
-
-	if (feed->ts_type & (~TS_DECODER))
-		return 0;
-
-	if ((feed->pes_type == DMX_TS_PES_PCR0) ||
-		(feed->pes_type == DMX_TS_PES_PCR1) ||
-		(feed->pes_type == DMX_TS_PES_PCR2) ||
-		(feed->pes_type == DMX_TS_PES_PCR3))
-		return 1;
-
-	return 0;
-}
-
-/**
- * mpq_dmx_init_hw_statistics -
- * Extend dvb-demux debugfs with HW statistics.
- *
- * @mpq_demux: The mpq_demux device to initialize.
- */
-void mpq_dmx_init_hw_statistics(struct mpq_demux *mpq_demux);
-
-
-/**
- * mpq_dmx_update_hw_statistics -
- * Update dvb-demux debugfs with HW notification statistics.
- *
- * @mpq_demux: The mpq_demux device to update.
- */
-void mpq_dmx_update_hw_statistics(struct mpq_demux *mpq_demux);
-
-#endif /* _MPQ_DMX_PLUGIN_COMMON_H */
-
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tsif.c b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tsif.c
deleted file mode 100644
index bbf9d0a..0000000
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tsif.c
+++ /dev/null
@@ -1,798 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/module.h>
-#include <linux/tsif_api.h>
-#include <linux/kthread.h>
-#include <linux/moduleparam.h>
-#include "mpq_dvb_debug.h"
-#include "mpq_dmx_plugin_common.h"
-
-
-/* TSIF HW configuration: */
-#define TSIF_COUNT				2
-
-/* Max number of section filters */
-#define DMX_TSIF_MAX_SECTION_FILTER_NUM	64
-
-/* When TSIF driver notifies demux that new packets are received */
-#define DMX_TSIF_PACKETS_IN_CHUNK_DEF		512
-#define DMX_TSIF_CHUNKS_IN_BUF			16
-#define DMX_TSIF_TIME_LIMIT			10000
-
-/* TSIF_DRIVER_MODE: 3 means manual control from debugfs. use 2 normally. */
-#define DMX_TSIF_DRIVER_MODE_DEF		2
-
-/* module parameters for load time configuration: */
-static int threshold = DMX_TSIF_PACKETS_IN_CHUNK_DEF;
-static int tsif_mode = DMX_TSIF_DRIVER_MODE_DEF;
-static int clock_inv;
-module_param(threshold, int, S_IRUGO);
-module_param(tsif_mode, int, S_IRUGO | S_IWUSR);
-module_param(clock_inv, int, S_IRUGO | S_IWUSR);
-
-
-/*
- * TSIF driver information
- */
-struct tsif_driver_info {
-	/* handler to TSIF driver */
-	void *tsif_handler;
-	/* TSIF driver data buffer pointer */
-	void *data_buffer;
-	/* TSIF driver data buffer size, in packets */
-	int buffer_size;
-	/* TSIF driver read pointer */
-	int ri;
-	/* TSIF driver write pointer */
-	int wi;
-	/* TSIF driver state */
-	enum tsif_state state;
-};
-
-
-/*
- * The following structure hold singelton information
- * required for dmx implementation on top of TSIF.
- */
-static struct
-{
-	/* Information for each TSIF input processing */
-	struct {
-		/* thread processing TS packets from TSIF */
-		struct task_struct *thread;
-		wait_queue_head_t wait_queue;
-
-		/* Counter for data notifications from TSIF */
-		atomic_t data_cnt;
-
-		/* TSIF alias */
-		char name[TSIF_NAME_LENGTH];
-
-		/* TSIF driver information */
-		struct tsif_driver_info tsif_driver;
-
-		/* TSIF reference count (counts start/stop operations */
-		int ref_count;
-
-		/* Pointer to the demux connected to this TSIF */
-		struct mpq_demux *mpq_demux;
-
-		/* mutex protecting the data-structure */
-		struct mutex mutex;
-	} tsif[TSIF_COUNT];
-} mpq_dmx_tsif_info;
-
-
-/**
- * Demux thread function handling data from specific TSIF.
- *
- * @arg: TSIF number
- */
-static int mpq_dmx_tsif_thread(void *arg)
-{
-	struct mpq_demux *mpq_demux;
-	struct tsif_driver_info *tsif_driver;
-	size_t packets = 0;
-	int tsif = (int)arg;
-	int ret;
-
-	do {
-		ret = wait_event_interruptible(
-			mpq_dmx_tsif_info.tsif[tsif].wait_queue,
-			(atomic_read(
-				&mpq_dmx_tsif_info.tsif[tsif].data_cnt) != 0) ||
-			kthread_should_stop());
-
-		if ((ret < 0) || kthread_should_stop()) {
-			MPQ_DVB_DBG_PRINT("%s: exit\n", __func__);
-			break;
-		}
-
-		if (mutex_lock_interruptible(
-			&mpq_dmx_tsif_info.tsif[tsif].mutex))
-			return -ERESTARTSYS;
-
-		tsif_driver = &(mpq_dmx_tsif_info.tsif[tsif].tsif_driver);
-		mpq_demux = mpq_dmx_tsif_info.tsif[tsif].mpq_demux;
-
-		/* Check if driver handler is still valid */
-		if (tsif_driver->tsif_handler == NULL) {
-			mutex_unlock(&mpq_dmx_tsif_info.tsif[tsif].mutex);
-			MPQ_DVB_DBG_PRINT(
-				"%s: tsif was detached\n",
-				__func__);
-			continue;
-		}
-
-		tsif_get_state(
-			tsif_driver->tsif_handler, &(tsif_driver->ri),
-			&(tsif_driver->wi), &(tsif_driver->state));
-
-		if ((tsif_driver->wi == tsif_driver->ri) ||
-			(tsif_driver->state == tsif_state_stopped) ||
-			(tsif_driver->state == tsif_state_error)) {
-
-			mpq_demux->hw_notification_size = 0;
-
-			mutex_unlock(&mpq_dmx_tsif_info.tsif[tsif].mutex);
-
-			MPQ_DVB_DBG_PRINT(
-				"%s: TSIF invalid state %d, %d, %d\n",
-				__func__,
-				tsif_driver->state,
-				tsif_driver->wi,
-				tsif_driver->ri);
-			continue;
-		}
-
-		atomic_dec(&mpq_dmx_tsif_info.tsif[tsif].data_cnt);
-
-		if (tsif_driver->wi > tsif_driver->ri) {
-			packets = (tsif_driver->wi - tsif_driver->ri);
-			mpq_demux->hw_notification_size = packets;
-
-			dvb_dmx_swfilter_format(
-				&mpq_demux->demux,
-				(tsif_driver->data_buffer +
-				(tsif_driver->ri * TSIF_PKT_SIZE)),
-				(packets * TSIF_PKT_SIZE),
-				DMX_TSP_FORMAT_192_TAIL);
-
-			tsif_driver->ri =
-				(tsif_driver->ri + packets) %
-				tsif_driver->buffer_size;
-
-			tsif_reclaim_packets(
-				tsif_driver->tsif_handler,
-					tsif_driver->ri);
-		} else {
-			/*
-			 * wi < ri, means wraparound on cyclic buffer.
-			 * Handle in two stages.
-			 */
-			packets = (tsif_driver->buffer_size - tsif_driver->ri);
-			mpq_demux->hw_notification_size = packets;
-
-			dvb_dmx_swfilter_format(
-				&mpq_demux->demux,
-				(tsif_driver->data_buffer +
-				(tsif_driver->ri * TSIF_PKT_SIZE)),
-				(packets * TSIF_PKT_SIZE),
-				DMX_TSP_FORMAT_192_TAIL);
-
-			/* tsif_driver->ri should be 0 after this */
-			tsif_driver->ri =
-				(tsif_driver->ri + packets) %
-				tsif_driver->buffer_size;
-
-			packets = tsif_driver->wi;
-			if (packets > 0) {
-				mpq_demux->hw_notification_size += packets;
-
-				dvb_dmx_swfilter_format(
-					&mpq_demux->demux,
-					(tsif_driver->data_buffer +
-					(tsif_driver->ri * TSIF_PKT_SIZE)),
-					(packets * TSIF_PKT_SIZE),
-					DMX_TSP_FORMAT_192_TAIL);
-
-				tsif_driver->ri =
-					(tsif_driver->ri + packets) %
-					tsif_driver->buffer_size;
-			}
-
-			tsif_reclaim_packets(
-				tsif_driver->tsif_handler,
-				tsif_driver->ri);
-		}
-
-		mutex_unlock(&mpq_dmx_tsif_info.tsif[tsif].mutex);
-	} while (1);
-
-	return 0;
-}
-
-
-/**
- * Callback function from TSIF driver when new data is ready.
- *
- * @user: user-data holding TSIF number
- */
-static void mpq_tsif_callback(void *user)
-{
-	int tsif = (int)user;
-	struct mpq_demux *mpq_demux;
-
-	MPQ_DVB_DBG_PRINT("%s executed, tsif = %d\n", __func__,	tsif);
-
-	/* Save statistics on TSIF notifications */
-	mpq_demux = mpq_dmx_tsif_info.tsif[tsif].mpq_demux;
-	mpq_dmx_update_hw_statistics(mpq_demux);
-
-	atomic_inc(&mpq_dmx_tsif_info.tsif[tsif].data_cnt);
-	wake_up(&mpq_dmx_tsif_info.tsif[tsif].wait_queue);
-}
-
-
-/**
- * Attach to TSIF driver and start TSIF operation.
- *
- * @mpq_demux: the mpq_demux we are working on.
- *
- * Return	error code.
- */
-static int mpq_tsif_dmx_start(struct mpq_demux *mpq_demux)
-{
-	int ret = 0;
-	int tsif;
-	struct tsif_driver_info *tsif_driver;
-
-	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
-
-	/* determine the TSIF we are reading from */
-	if (mpq_demux->source == DMX_SOURCE_FRONT0) {
-		tsif = 0;
-	} else if (mpq_demux->source == DMX_SOURCE_FRONT1) {
-		tsif = 1;
-	} else {
-		/* invalid source */
-		MPQ_DVB_ERR_PRINT(
-			"%s: invalid input source (%d)\n",
-			__func__,
-			mpq_demux->source);
-
-		return -EINVAL;
-	}
-
-	if (mutex_lock_interruptible(&mpq_dmx_tsif_info.tsif[tsif].mutex))
-		return -ERESTARTSYS;
-
-	if (mpq_dmx_tsif_info.tsif[tsif].ref_count == 0) {
-		tsif_driver = &(mpq_dmx_tsif_info.tsif[tsif].tsif_driver);
-
-		/* Attach to TSIF driver */
-		tsif_driver->tsif_handler =
-			tsif_attach(tsif, mpq_tsif_callback, (void *)tsif);
-		if (IS_ERR_OR_NULL(tsif_driver->tsif_handler)) {
-			tsif_driver->tsif_handler = NULL;
-			mutex_unlock(&mpq_dmx_tsif_info.tsif[tsif].mutex);
-			MPQ_DVB_DBG_PRINT("%s: tsif_attach(%d) failed\n",
-					__func__, tsif);
-			return -ENODEV;
-		}
-
-		ret = tsif_set_clk_inverse(tsif_driver->tsif_handler,
-					clock_inv);
-		if (ret < 0) {
-			MPQ_DVB_ERR_PRINT(
-				"%s: tsif_set_clk_inverse (%d) failed\n",
-				__func__, clock_inv);
-		}
-
-		/* Set TSIF driver mode */
-		ret = tsif_set_mode(tsif_driver->tsif_handler, tsif_mode);
-		if (ret < 0) {
-			MPQ_DVB_ERR_PRINT("%s: tsif_set_mode (%d) failed\n",
-				__func__, tsif_mode);
-		}
-
-		/* Set TSIF buffer configuration */
-		ret = tsif_set_buf_config(tsif_driver->tsif_handler,
-						threshold,
-						DMX_TSIF_CHUNKS_IN_BUF);
-		if (ret < 0) {
-			MPQ_DVB_ERR_PRINT(
-				"%s: tsif_set_buf_config (%d, %d) failed\n",
-				__func__, threshold,
-				DMX_TSIF_CHUNKS_IN_BUF);
-			MPQ_DVB_ERR_PRINT("Using default TSIF driver values\n");
-		}
-
-		/* Start TSIF driver */
-		ret = tsif_start(tsif_driver->tsif_handler);
-		if (ret < 0) {
-			mutex_unlock(&mpq_dmx_tsif_info.tsif[tsif].mutex);
-			MPQ_DVB_ERR_PRINT("%s: tsif_start failed\n", __func__);
-			return ret;
-		}
-
-		/*
-		 * Get data buffer information from TSIF driver
-		 * (must be called after tsif_start)
-		 */
-		tsif_get_info(tsif_driver->tsif_handler,
-				&(tsif_driver->data_buffer),
-				&(tsif_driver->buffer_size));
-
-		/* save pointer to the mpq_demux we are working on */
-		mpq_dmx_tsif_info.tsif[tsif].mpq_demux = mpq_demux;
-	}
-	mpq_dmx_tsif_info.tsif[tsif].ref_count++;
-
-	mutex_unlock(&mpq_dmx_tsif_info.tsif[tsif].mutex);
-
-	return ret;
-}
-
-
-/**
- * Stop TSIF operation and detach from TSIF driver.
- *
- * @mpq_demux: the mpq_demux we are working on.
- *
- * Return	error code.
- */
-static int mpq_tsif_dmx_stop(struct mpq_demux *mpq_demux)
-{
-	int tsif;
-	struct tsif_driver_info *tsif_driver;
-
-	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
-
-	/* determine the TSIF we are reading from */
-	if (mpq_demux->source == DMX_SOURCE_FRONT0) {
-		tsif = 0;
-	} else if (mpq_demux->source == DMX_SOURCE_FRONT1) {
-		tsif = 1;
-	} else {
-		/* invalid source */
-		MPQ_DVB_ERR_PRINT(
-			"%s: invalid input source (%d)\n",
-			__func__,
-			mpq_demux->source);
-
-		return -EINVAL;
-	}
-
-	if (mutex_lock_interruptible(&mpq_dmx_tsif_info.tsif[tsif].mutex))
-		return -ERESTARTSYS;
-
-	mpq_dmx_tsif_info.tsif[tsif].ref_count--;
-
-	if (mpq_dmx_tsif_info.tsif[tsif].ref_count == 0) {
-		tsif_driver = &(mpq_dmx_tsif_info.tsif[tsif].tsif_driver);
-		tsif_stop(tsif_driver->tsif_handler);
-		tsif_detach(tsif_driver->tsif_handler);
-		tsif_driver->tsif_handler = NULL;
-		tsif_driver->data_buffer = NULL;
-		tsif_driver->buffer_size = 0;
-		atomic_set(&mpq_dmx_tsif_info.tsif[tsif].data_cnt, 0);
-		mpq_dmx_tsif_info.tsif[tsif].mpq_demux = NULL;
-	}
-
-	mutex_unlock(&mpq_dmx_tsif_info.tsif[tsif].mutex);
-
-	return 0;
-}
-
-
-/**
- * Start filtering according to feed parameter.
- *
- * @feed: the feed we are working on.
- *
- * Return	error code.
- */
-static int mpq_tsif_dmx_start_filtering(struct dvb_demux_feed *feed)
-{
-	int ret = 0;
-	struct mpq_demux *mpq_demux = feed->demux->priv;
-
-	MPQ_DVB_DBG_PRINT(
-		"%s(%d) executed\n",
-		__func__,
-		feed->pid);
-
-	if (mpq_demux == NULL) {
-		MPQ_DVB_ERR_PRINT(
-			"%s: invalid mpq_demux handle\n",
-			__func__);
-
-		return -EINVAL;
-	}
-
-	if (mpq_demux->source < DMX_SOURCE_DVR0) {
-		/* Source from TSIF, need to configure TSIF hardware */
-		ret = mpq_tsif_dmx_start(mpq_demux);
-
-		if (ret < 0) {
-			MPQ_DVB_DBG_PRINT(
-				"%s: mpq_tsif_dmx_start failed(%d)\n",
-				__func__,
-				ret);
-			return ret;
-		}
-	}
-
-	/* Always feed sections/PES starting from a new one and
-	 * do not partial transfer data from older one
-	 */
-	feed->pusi_seen = 0;
-
-	/*
-	 * For video PES, data is tunneled to the decoder,
-	 * initialize tunneling and pes parsing.
-	 */
-	if (mpq_dmx_is_video_feed(feed)) {
-		ret = mpq_dmx_init_video_feed(feed);
-
-		if (ret < 0) {
-			MPQ_DVB_DBG_PRINT(
-				"%s: mpq_dmx_init_video_feed failed(%d)\n",
-				__func__,
-				ret);
-
-			if (mpq_demux->source < DMX_SOURCE_DVR0)
-				mpq_tsif_dmx_stop(mpq_demux);
-
-			return ret;
-		}
-	}
-
-	return ret;
-}
-
-
-/**
- * Stop filtering according to feed parameter.
- *
- * @feed: the feed we are working on.
- *
- * Return	error code.
- */
-static int mpq_tsif_dmx_stop_filtering(struct dvb_demux_feed *feed)
-{
-	int ret = 0;
-	struct mpq_demux *mpq_demux = feed->demux->priv;
-
-	MPQ_DVB_DBG_PRINT(
-		"%s(%d) executed\n",
-		__func__,
-		feed->pid);
-
-	if (mpq_demux == NULL) {
-		MPQ_DVB_ERR_PRINT(
-			"%s: invalid mpq_demux handle\n",
-			__func__);
-
-		return -EINVAL;
-	}
-
-	/*
-	 * For video PES, data is tunneled to the decoder,
-	 * terminate tunnel and pes parsing.
-	 */
-	if (mpq_dmx_is_video_feed(feed))
-		mpq_dmx_terminate_video_feed(feed);
-
-	if (mpq_demux->source < DMX_SOURCE_DVR0) {
-		/* Source from TSIF, need to configure TSIF hardware */
-		ret = mpq_tsif_dmx_stop(mpq_demux);
-	}
-
-	return ret;
-}
-
-
-/**
- * TSIF demux plugin write-to-decoder function.
- *
- * @feed: The feed we are working on.
- * @buf: The data buffer to process.
- * @len: The data buffer length.
- *
- * Return	error code
- */
-static int mpq_tsif_dmx_write_to_decoder(
-					struct dvb_demux_feed *feed,
-					const u8 *buf,
-					size_t len)
-{
-	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
-
-	/*
-	 * It is assumed that this function is called once for each
-	 * TS packet of the relevant feed.
-	 */
-	if (len > TSIF_PKT_SIZE)
-		MPQ_DVB_DBG_PRINT(
-				"%s: warnning - len larger than one packet\n",
-				__func__);
-
-	if (mpq_dmx_is_video_feed(feed))
-		return mpq_dmx_process_video_packet(feed, buf);
-
-	if (mpq_dmx_is_pcr_feed(feed))
-		return mpq_dmx_process_pcr_packet(feed, buf);
-
-	return 0;
-}
-
-/**
- * Returns demux capabilities of TSIF plugin
- *
- * @demux: demux device
- * @caps: Returned capbabilities
- *
- * Return     error code
- */
-static int mpq_tsif_dmx_get_caps(struct dmx_demux *demux,
-				struct dmx_caps *caps)
-{
-	struct dvb_demux *dvb_demux = demux->priv;
-
-	if ((dvb_demux == NULL) || (caps == NULL)) {
-		MPQ_DVB_ERR_PRINT(
-			"%s: invalid parameters\n",
-			__func__);
-
-		return -EINVAL;
-	}
-
-	caps->caps = DMX_CAP_PULL_MODE | DMX_CAP_VIDEO_DECODER_DATA;
-	caps->num_decoders = MPQ_ADAPTER_MAX_NUM_OF_INTERFACES;
-	caps->num_demux_devices = CONFIG_DVB_MPQ_NUM_DMX_DEVICES;
-	caps->num_pid_filters = dvb_demux->feednum;
-	caps->num_section_filters = dvb_demux->filternum;
-	caps->num_section_filters_per_pid = dvb_demux->filternum;
-	caps->section_filter_length = DMX_FILTER_SIZE;
-	caps->num_demod_inputs = TSIF_COUNT;
-	caps->num_memory_inputs = CONFIG_DVB_MPQ_NUM_DMX_DEVICES;
-	caps->max_bitrate = 144;
-	caps->demod_input_max_bitrate = 72;
-	caps->memory_input_max_bitrate = 72;
-	caps->section.flags = 0;
-	caps->section.max_size = 0xFFFFFFFF;
-	caps->section.size_alignment = 0;
-	caps->pes.flags = 0;
-	caps->pes.max_size = 0xFFFFFFFF;
-	caps->pes.size_alignment = 0;
-	caps->recording_188_tsp.flags = 0;
-	caps->recording_188_tsp.max_size = 0xFFFFFFFF;
-	caps->recording_188_tsp.size_alignment = 0;
-	caps->recording_192_tsp.flags = 0;
-	caps->recording_192_tsp.max_size = 0xFFFFFFFF;
-	caps->recording_192_tsp.size_alignment = 0;
-	caps->playback_188_tsp.flags = 0;
-	caps->playback_188_tsp.max_size = 0xFFFFFFFF;
-	caps->playback_188_tsp.size_alignment = 0;
-	caps->playback_192_tsp.flags = 0;
-	caps->playback_192_tsp.max_size = 0xFFFFFFFF;
-	caps->playback_192_tsp.size_alignment = 0;
-
-	return 0;
-}
-
-/**
- * Initialize a single demux device.
- *
- * @mpq_adapter: MPQ DVB adapter
- * @mpq_demux: The demux device to initialize
- *
- * Return	error code
- */
-static int mpq_tsif_dmx_init(
-		struct dvb_adapter *mpq_adapter,
-		struct mpq_demux *mpq_demux)
-{
-	int result;
-
-	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
-
-	/* Set the kernel-demux object capabilities */
-	mpq_demux->demux.dmx.capabilities =
-		DMX_TS_FILTERING		|
-		DMX_PES_FILTERING		|
-		DMX_SECTION_FILTERING		|
-		DMX_MEMORY_BASED_FILTERING	|
-		DMX_CRC_CHECKING		|
-		DMX_TS_DESCRAMBLING;
-
-	/* Set dvb-demux "virtual" function pointers */
-	mpq_demux->demux.priv = (void *)mpq_demux;
-	mpq_demux->demux.filternum = DMX_TSIF_MAX_SECTION_FILTER_NUM;
-	mpq_demux->demux.feednum = MPQ_MAX_DMX_FILES;
-	mpq_demux->demux.start_feed = mpq_tsif_dmx_start_filtering;
-	mpq_demux->demux.stop_feed = mpq_tsif_dmx_stop_filtering;
-	mpq_demux->demux.write_to_decoder = mpq_tsif_dmx_write_to_decoder;
-
-	mpq_demux->demux.decoder_fullness_init =
-		mpq_dmx_decoder_fullness_init;
-
-	mpq_demux->demux.decoder_fullness_wait =
-		mpq_dmx_decoder_fullness_wait;
-
-	mpq_demux->demux.decoder_fullness_abort =
-		mpq_dmx_decoder_fullness_abort;
-
-	mpq_demux->demux.decoder_buffer_status =
-		mpq_dmx_decoder_buffer_status;
-
-	/* Initialize dvb_demux object */
-	result = dvb_dmx_init(&mpq_demux->demux);
-	if (result < 0) {
-		MPQ_DVB_ERR_PRINT("%s: dvb_dmx_init failed\n", __func__);
-		goto init_failed;
-	}
-
-	/* Now initailize the dmx-dev object */
-	mpq_demux->dmxdev.filternum = MPQ_MAX_DMX_FILES;
-	mpq_demux->dmxdev.demux = &mpq_demux->demux.dmx;
-	mpq_demux->dmxdev.capabilities =
-		DMXDEV_CAP_DUPLEX |
-		DMXDEV_CAP_PULL_MODE |
-		DMXDEV_CAP_INDEXING;
-
-	mpq_demux->dmxdev.demux->set_source = mpq_dmx_set_source;
-	mpq_demux->dmxdev.demux->get_caps = mpq_tsif_dmx_get_caps;
-	mpq_demux->dmxdev.demux->map_buffer = mpq_dmx_map_buffer;
-	mpq_demux->dmxdev.demux->unmap_buffer = mpq_dmx_unmap_buffer;
-
-	result = dvb_dmxdev_init(&mpq_demux->dmxdev, mpq_adapter);
-	if (result < 0) {
-		MPQ_DVB_ERR_PRINT("%s: dvb_dmxdev_init failed (errno=%d)\n",
-						  __func__,
-						  result);
-		goto init_failed_dmx_release;
-	}
-
-	/* Extend dvb-demux debugfs with TSIF statistics. */
-	mpq_dmx_init_hw_statistics(mpq_demux);
-
-	return 0;
-
-init_failed_dmx_release:
-	dvb_dmx_release(&mpq_demux->demux);
-init_failed:
-	return result;
-}
-
-
-/**
- * Module initialization function.
- *
- * Return	error code
- */
-static int __init mpq_dmx_tsif_plugin_init(void)
-{
-	int i;
-	int ret;
-
-	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
-
-	/* check module parameters validity */
-	if (threshold < 1) {
-		MPQ_DVB_ERR_PRINT(
-			"%s: invalid threshold parameter, using %d instead\n",
-			__func__, DMX_TSIF_PACKETS_IN_CHUNK_DEF);
-		threshold = DMX_TSIF_PACKETS_IN_CHUNK_DEF;
-	}
-	if ((tsif_mode < 1) || (tsif_mode > 3)) {
-		MPQ_DVB_ERR_PRINT(
-			"%s: invalid mode parameter, using %d instead\n",
-			__func__, DMX_TSIF_DRIVER_MODE_DEF);
-		tsif_mode = DMX_TSIF_DRIVER_MODE_DEF;
-	}
-
-	for (i = 0; i < TSIF_COUNT; i++) {
-		snprintf(mpq_dmx_tsif_info.tsif[i].name,
-				TSIF_NAME_LENGTH,
-				"dmx_tsif%d",
-				i);
-
-		atomic_set(&mpq_dmx_tsif_info.tsif[i].data_cnt, 0);
-		init_waitqueue_head(&mpq_dmx_tsif_info.tsif[i].wait_queue);
-		mpq_dmx_tsif_info.tsif[i].thread =
-			kthread_run(
-				mpq_dmx_tsif_thread, (void *)i,
-				mpq_dmx_tsif_info.tsif[i].name);
-
-		if (IS_ERR(mpq_dmx_tsif_info.tsif[i].thread)) {
-			int j;
-
-			for (j = 0; j < i; j++) {
-				kthread_stop(mpq_dmx_tsif_info.tsif[j].thread);
-				mutex_destroy(&mpq_dmx_tsif_info.tsif[j].mutex);
-			}
-
-			MPQ_DVB_ERR_PRINT(
-				"%s: kthread_run failed\n",
-				__func__);
-
-			return -ENOMEM;
-		}
-
-		mutex_init(&mpq_dmx_tsif_info.tsif[i].mutex);
-
-		mpq_dmx_tsif_info.tsif[i].tsif_driver.tsif_handler = NULL;
-		mpq_dmx_tsif_info.tsif[i].ref_count = 0;
-	}
-
-	ret = mpq_dmx_plugin_init(mpq_tsif_dmx_init);
-
-	if (ret < 0) {
-		MPQ_DVB_ERR_PRINT(
-			"%s: mpq_dmx_plugin_init failed (errno=%d)\n",
-			__func__,
-			ret);
-
-		for (i = 0; i < TSIF_COUNT; i++) {
-			kthread_stop(mpq_dmx_tsif_info.tsif[i].thread);
-			mutex_destroy(&mpq_dmx_tsif_info.tsif[i].mutex);
-		}
-	}
-
-	return ret;
-}
-
-
-/**
- * Module exit function.
- */
-static void __exit mpq_dmx_tsif_plugin_exit(void)
-{
-	int i;
-	struct tsif_driver_info *tsif_driver;
-
-	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
-
-	for (i = 0; i < TSIF_COUNT; i++) {
-		mutex_lock(&mpq_dmx_tsif_info.tsif[i].mutex);
-
-		tsif_driver = &(mpq_dmx_tsif_info.tsif[i].tsif_driver);
-		if (mpq_dmx_tsif_info.tsif[i].ref_count > 0) {
-			mpq_dmx_tsif_info.tsif[i].ref_count = 0;
-			if (tsif_driver->tsif_handler)
-				tsif_stop(tsif_driver->tsif_handler);
-		}
-
-		/* Detach from TSIF driver to avoid further notifications. */
-		if (tsif_driver->tsif_handler)
-			tsif_detach(tsif_driver->tsif_handler);
-
-		mutex_unlock(&mpq_dmx_tsif_info.tsif[i].mutex);
-		kthread_stop(mpq_dmx_tsif_info.tsif[i].thread);
-		mutex_destroy(&mpq_dmx_tsif_info.tsif[i].mutex);
-	}
-
-	mpq_dmx_plugin_exit();
-}
-
-
-module_init(mpq_dmx_tsif_plugin_init);
-module_exit(mpq_dmx_tsif_plugin_exit);
-
-MODULE_DESCRIPTION("Qualcomm demux TSIF HW Plugin");
-MODULE_LICENSE("GPL v2");
-
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v1.c b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v1.c
deleted file mode 100644
index ac03e43..0000000
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v1.c
+++ /dev/null
@@ -1,1226 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/module.h>
-#include <linux/kthread.h>
-#include <mach/msm_tspp.h>
-#include "mpq_dvb_debug.h"
-#include "mpq_dmx_plugin_common.h"
-
-#define TSIF_COUNT			2
-
-#define TSPP_MAX_PID_FILTER_NUM		16
-
-/* Max number of section filters */
-#define TSPP_MAX_SECTION_FILTER_NUM	64
-
-/* For each TSIF we allocate two pipes, one for PES and one for sections */
-#define TSPP_PES_CHANNEL			0
-#define TSPP_SECTION_CHANNEL			1
-#define TSPP_CHANNEL_COUNT			2
-
-/* the channel_id set to TSPP driver based on TSIF number and channel type */
-#define TSPP_CHANNEL_ID(tsif, ch)		((tsif << 1) + ch)
-#define TSPP_IS_PES_CHANNEL(ch_id)		((ch_id & 0x1) == 0)
-#define TSPP_GET_TSIF_NUM(ch_id)		(ch_id >> 1)
-
-/* mask that set to care for all bits in pid filter */
-#define TSPP_PID_MASK			0x1FFF
-
-/* dvb-demux defines pid 0x2000 as full capture pid */
-#define TSPP_PASS_THROUGH_PID		0x2000
-
-#define TSPP_RAW_TTS_SIZE		192
-#define TSPP_RAW_SIZE			188
-
-#define MAX_BAM_DESCRIPTOR_SIZE	(32*1024 - 1)
-
-#define TSPP_BUFFER_SIZE		(500 * 1024) /* 500KB */
-
-#define TSPP_PES_BUFFER_SIZE		(TSPP_RAW_TTS_SIZE)
-
-#define TSPP_SECTION_BUFFER_SIZE	(TSPP_RAW_TTS_SIZE)
-
-#define TSPP_BUFFER_COUNT(buffer_size)	\
-	((buffer_size) / TSPP_RAW_TTS_SIZE)
-
-/* When TSPP notifies demux that new packets are received.
- * Using max descriptor size (170 packets).
- * Assuming 20MBit/sec stream, with 170 packets
- * per descriptor there would be about 82 descriptors,
- * Meanning about 82 notifications per second.
- */
-#define TSPP_NOTIFICATION_SIZE(desc_size)		\
-	(MAX_BAM_DESCRIPTOR_SIZE / (desc_size))
-
-/* Channel timeout in msec */
-#define TSPP_CHANNEL_TIMEOUT			100
-
-enum mem_buffer_allocation_mode {
-	MPQ_DMX_TSPP_INTERNAL_ALLOC = 0,
-	MPQ_DMX_TSPP_CONTIGUOUS_PHYS_ALLOC = 1
-};
-
-/* module parameters for load time configuration */
-static int clock_inv;
-static int tsif_mode = 2;
-static int allocation_mode = MPQ_DMX_TSPP_INTERNAL_ALLOC;
-static int tspp_out_buffer_size = TSPP_BUFFER_SIZE;
-static int tspp_notification_size = TSPP_NOTIFICATION_SIZE(TSPP_RAW_TTS_SIZE);
-static int tspp_channel_timeout = TSPP_CHANNEL_TIMEOUT;
-
-module_param(tsif_mode, int, S_IRUGO | S_IWUSR);
-module_param(clock_inv, int, S_IRUGO | S_IWUSR);
-module_param(allocation_mode, int, S_IRUGO);
-module_param(tspp_out_buffer_size, int, S_IRUGO);
-module_param(tspp_notification_size, int, S_IRUGO | S_IWUSR);
-module_param(tspp_channel_timeout, int, S_IRUGO | S_IWUSR);
-
-
-/* The following structure hold singelton information
- * required for dmx implementation on top of TSPP.
- */
-static struct
-{
-	/* Information for each TSIF input processing */
-	struct {
-		/*
-		 * TSPP pipe holding all TS packets with PES data.
-		 * The following is reference count for number of feeds
-		 * allocated on that pipe.
-		 */
-		int pes_channel_ref;
-
-		/* Counter for data notifications on PES pipe */
-		atomic_t pes_data_cnt;
-
-		/* ION handle used for TSPP data buffer allocation */
-		struct ion_handle *pes_mem_heap_handle;
-		/* TSPP data buffer heap virtual base address */
-		void *pes_mem_heap_virt_base;
-		/* TSPP data buffer heap physical base address */
-		ion_phys_addr_t pes_mem_heap_phys_base;
-		/* buffer allocation index */
-		int pes_index;
-
-		/*
-		 * TSPP pipe holding all TS packets with section data.
-		 * The following is reference count for number of feeds
-		 * allocated on that pipe.
-		 */
-		int section_channel_ref;
-
-		/* Counter for data notifications on section pipe */
-		atomic_t section_data_cnt;
-
-		/* ION handle used for TSPP data buffer allocation */
-		struct ion_handle *section_mem_heap_handle;
-		/* TSPP data buffer heap virtual base address */
-		void *section_mem_heap_virt_base;
-		/* TSPP data buffer heap physical base address */
-		ion_phys_addr_t section_mem_heap_phys_base;
-		/* buffer allocation index */
-		int section_index;
-
-		u32 buffer_count;
-
-		/*
-		 * Holds PIDs of allocated TSPP filters along with
-		 * how many feeds are opened on same PID.
-		 */
-		struct {
-			int pid;
-			int ref_count;
-		} filters[TSPP_MAX_PID_FILTER_NUM];
-
-		/* thread processing TS packets from TSPP */
-		struct task_struct *thread;
-		wait_queue_head_t wait_queue;
-
-		/* TSIF alias */
-		char name[TSIF_NAME_LENGTH];
-
-		/* Pointer to the demux connected to this TSIF */
-		struct mpq_demux *mpq_demux;
-
-		/* mutex protecting the data-structure */
-		struct mutex mutex;
-	} tsif[TSIF_COUNT];
-
-	/* ION client used for TSPP data buffer allocation */
-	struct ion_client *ion_client;
-} mpq_dmx_tspp_info;
-
-static void *tspp_mem_allocator(int channel_id, u32 size,
-				u32 *phys_base, void *user)
-{
-	void *virt_addr = NULL;
-	int i = TSPP_GET_TSIF_NUM(channel_id);
-
-	if (TSPP_IS_PES_CHANNEL(channel_id)) {
-		if (mpq_dmx_tspp_info.tsif[i].pes_index ==
-			mpq_dmx_tspp_info.tsif[i].buffer_count)
-			return NULL;
-		virt_addr =
-			(mpq_dmx_tspp_info.tsif[i].pes_mem_heap_virt_base +
-			(mpq_dmx_tspp_info.tsif[i].pes_index * size));
-		*phys_base =
-			(mpq_dmx_tspp_info.tsif[i].pes_mem_heap_phys_base +
-			(mpq_dmx_tspp_info.tsif[i].pes_index * size));
-		mpq_dmx_tspp_info.tsif[i].pes_index++;
-	} else {
-		if (mpq_dmx_tspp_info.tsif[i].section_index ==
-			mpq_dmx_tspp_info.tsif[i].buffer_count)
-			return NULL;
-		virt_addr =
-			(mpq_dmx_tspp_info.tsif[i].section_mem_heap_virt_base +
-			(mpq_dmx_tspp_info.tsif[i].section_index * size));
-		*phys_base =
-			(mpq_dmx_tspp_info.tsif[i].section_mem_heap_phys_base +
-			(mpq_dmx_tspp_info.tsif[i].section_index * size));
-		mpq_dmx_tspp_info.tsif[i].section_index++;
-	}
-
-	return virt_addr;
-}
-
-static void tspp_mem_free(int channel_id, u32 size,
-			void *virt_base, u32 phys_base, void *user)
-{
-	int i = TSPP_GET_TSIF_NUM(channel_id);
-
-	/*
-	 * actual buffer heap free is done in mpq_dmx_tspp_plugin_exit().
-	 * we update index here, so if this function is called repetitively
-	 * for all the buffers, then afterwards tspp_mem_allocator()
-	 * can be called again.
-	 * Note: it would be incorrect to call tspp_mem_allocator()
-	 * a few times, then call tspp_mem_free(), then call
-	 * tspp_mem_allocator() again.
-	 */
-	if (TSPP_IS_PES_CHANNEL(channel_id)) {
-		if (mpq_dmx_tspp_info.tsif[i].pes_index > 0)
-			mpq_dmx_tspp_info.tsif[i].pes_index--;
-	} else {
-		if (mpq_dmx_tspp_info.tsif[i].section_index > 0)
-			mpq_dmx_tspp_info.tsif[i].section_index--;
-	}
-}
-
-/**
- * Returns a free filter slot that can be used.
- *
- * @tsif: The TSIF to allocate filter from
- * @channel_id: The channel allocating filter to
- *
- * Return  filter index or -1 if no filters available
- *
- * To give priority to PES data, for pes filters
- * the table is scanned from high to low priority,
- * and sections from low to high priority. This way TSPP
- * would get a match on PES data filters faster as they
- * are scanned first.
- */
-static int mpq_tspp_get_free_filter_slot(int tsif, int channel_id)
-{
-	int i;
-
-	if (TSPP_IS_PES_CHANNEL(channel_id)) {
-		for (i = 0; i < TSPP_MAX_PID_FILTER_NUM; i++)
-			if (mpq_dmx_tspp_info.tsif[tsif].filters[i].pid == -1)
-				return i;
-	} else {
-		for (i = TSPP_MAX_PID_FILTER_NUM-1; i >= 0; i--)
-			if (mpq_dmx_tspp_info.tsif[tsif].filters[i].pid == -1)
-				return i;
-	}
-
-	return -ENOMEM;
-}
-
-/**
- * Returns filter index of specific pid.
- *
- * @tsif: The TSIF to which the pid is allocated
- * @pid: The pid to search for
- *
- * Return  filter index or -1 if no filter available
- */
-static int mpq_tspp_get_filter_slot(int tsif, int pid)
-{
-	int i;
-
-	for (i = 0; i < TSPP_MAX_PID_FILTER_NUM; i++)
-		if (mpq_dmx_tspp_info.tsif[tsif].filters[i].pid == pid)
-			return i;
-
-	return -EINVAL;
-}
-
-/**
- * Demux thread function handling data from specific TSIF.
- *
- * @arg: TSIF number
- */
-static int mpq_dmx_tspp_thread(void *arg)
-{
-	int tsif = (int)arg;
-	struct mpq_demux *mpq_demux;
-	const struct tspp_data_descriptor *tspp_data_desc;
-	atomic_t *data_cnt;
-	u32 notif_size;
-	int ref_count;
-	int ret;
-	int i;
-	int j;
-
-	do {
-		ret = wait_event_interruptible(
-			mpq_dmx_tspp_info.tsif[tsif].wait_queue,
-			(atomic_read(
-			 &mpq_dmx_tspp_info.tsif[tsif].pes_data_cnt)) ||
-			(atomic_read(
-			 &mpq_dmx_tspp_info.tsif[tsif].section_data_cnt)) ||
-			kthread_should_stop());
-
-		if ((ret < 0) || kthread_should_stop()) {
-			MPQ_DVB_ERR_PRINT("%s: exit\n", __func__);
-			break;
-		}
-
-		/* Lock against the TSPP filters data-structure */
-		if (mutex_lock_interruptible(
-			&mpq_dmx_tspp_info.tsif[tsif].mutex))
-			return -ERESTARTSYS;
-
-		for (i = 0; i < TSPP_CHANNEL_COUNT; i++) {
-			int channel_id = TSPP_CHANNEL_ID(tsif, i);
-
-			if (TSPP_IS_PES_CHANNEL(channel_id)) {
-				ref_count =
-				 mpq_dmx_tspp_info.tsif[tsif].pes_channel_ref;
-				data_cnt =
-				 &mpq_dmx_tspp_info.tsif[tsif].pes_data_cnt;
-			} else {
-				ref_count =
-				 mpq_dmx_tspp_info.tsif[tsif].
-					section_channel_ref;
-				data_cnt =
-				 &mpq_dmx_tspp_info.tsif[tsif].section_data_cnt;
-			}
-
-			/* Make sure channel is still active */
-			if (ref_count == 0)
-				continue;
-
-			atomic_dec(data_cnt);
-
-			mpq_demux = mpq_dmx_tspp_info.tsif[tsif].mpq_demux;
-			mpq_demux->hw_notification_size = 0;
-
-			/*
-			 * Go through all filled descriptors
-			 * and perform demuxing on them
-			 */
-			while ((tspp_data_desc =
-				tspp_get_buffer(0, channel_id)) != NULL) {
-				notif_size =
-					tspp_data_desc->size /
-					TSPP_RAW_TTS_SIZE;
-
-				mpq_demux->hw_notification_size +=
-					notif_size;
-
-				for (j = 0; j < notif_size; j++)
-					dvb_dmx_swfilter_packet(
-					 &mpq_demux->demux,
-					 ((u8 *)tspp_data_desc->virt_base) +
-					 j * TSPP_RAW_TTS_SIZE,
-					 ((u8 *)tspp_data_desc->virt_base) +
-					 j * TSPP_RAW_TTS_SIZE + TSPP_RAW_SIZE);
-				/*
-				 * Notify TSPP that the buffer
-				 * is no longer needed
-				 */
-				tspp_release_buffer(0,
-					channel_id, tspp_data_desc->id);
-			}
-
-			if (mpq_demux->hw_notification_size &&
-				(mpq_demux->hw_notification_size <
-				mpq_demux->hw_notification_min_size))
-				mpq_demux->hw_notification_min_size =
-					mpq_demux->hw_notification_size;
-		}
-
-		mutex_unlock(&mpq_dmx_tspp_info.tsif[tsif].mutex);
-	} while (1);
-
-	return 0;
-}
-
-/**
- * Callback function from TSPP when new data is ready.
- *
- * @channel_id: Channel with new TS packets
- * @user: user-data holding TSIF number
- */
-static void mpq_tspp_callback(int channel_id, void *user)
-{
-	int tsif = (int)user;
-	struct mpq_demux *mpq_demux;
-
-	/* Save statistics on TSPP notifications */
-	mpq_demux = mpq_dmx_tspp_info.tsif[tsif].mpq_demux;
-	mpq_dmx_update_hw_statistics(mpq_demux);
-
-	if (TSPP_IS_PES_CHANNEL(channel_id))
-		atomic_inc(&mpq_dmx_tspp_info.tsif[tsif].pes_data_cnt);
-	else
-		atomic_inc(&mpq_dmx_tspp_info.tsif[tsif].section_data_cnt);
-
-	wake_up(&mpq_dmx_tspp_info.tsif[tsif].wait_queue);
-}
-
-/**
- * Configure TSPP channel to filter the PID of new feed.
- *
- * @feed: The feed to configure the channel with
- *
- * Return  error status
- *
- * The function checks if the new PID can be added to an already
- * allocated channel, if not, a new channel is allocated and configured.
- */
-static int mpq_tspp_dmx_add_channel(struct dvb_demux_feed *feed)
-{
-	struct mpq_demux *mpq_demux = feed->demux->priv;
-	struct tspp_select_source tspp_source;
-	struct tspp_filter tspp_filter;
-	int tsif;
-	int ret;
-	int channel_id;
-	int *channel_ref_count;
-	u32 buffer_size;
-
-	tspp_source.clk_inverse = clock_inv;
-	tspp_source.data_inverse = 0;
-	tspp_source.sync_inverse = 0;
-	tspp_source.enable_inverse = 0;
-
-	switch (tsif_mode) {
-	case 1:
-		tspp_source.mode = TSPP_TSIF_MODE_1;
-		break;
-	case 2:
-		tspp_source.mode = TSPP_TSIF_MODE_2;
-		break;
-	default:
-		tspp_source.mode = TSPP_TSIF_MODE_LOOPBACK;
-		break;
-	}
-
-	/* determine the TSIF we are reading from */
-	if (mpq_demux->source == DMX_SOURCE_FRONT0) {
-		tsif = 0;
-		tspp_source.source = TSPP_SOURCE_TSIF0;
-	} else if (mpq_demux->source == DMX_SOURCE_FRONT1) {
-		tsif = 1;
-		tspp_source.source = TSPP_SOURCE_TSIF1;
-	} else {
-		/* invalid source */
-		MPQ_DVB_ERR_PRINT(
-			"%s: invalid input source (%d)\n",
-			__func__,
-			mpq_demux->source);
-
-		return -EINVAL;
-	}
-
-	if (mutex_lock_interruptible(&mpq_dmx_tspp_info.tsif[tsif].mutex))
-		return -ERESTARTSYS;
-
-	/*
-	 * It is possible that this PID was already requested before.
-	 * Can happen if we play and record same PES or PCR
-	 * piggypacked on video packet.
-	 */
-	ret = mpq_tspp_get_filter_slot(tsif, feed->pid);
-	if (ret >= 0) {
-		/* PID already configured */
-		mpq_dmx_tspp_info.tsif[tsif].filters[ret].ref_count++;
-		mutex_unlock(&mpq_dmx_tspp_info.tsif[tsif].mutex);
-		return 0;
-	}
-
-	/* determine to which pipe the feed should be routed: section or pes */
-	if ((feed->type == DMX_TYPE_PES) || (feed->type == DMX_TYPE_TS)) {
-		channel_id = TSPP_CHANNEL_ID(tsif, TSPP_PES_CHANNEL);
-		channel_ref_count =
-			&mpq_dmx_tspp_info.tsif[tsif].pes_channel_ref;
-		buffer_size = TSPP_PES_BUFFER_SIZE;
-	} else {
-		channel_id = TSPP_CHANNEL_ID(tsif, TSPP_SECTION_CHANNEL);
-		channel_ref_count =
-			&mpq_dmx_tspp_info.tsif[tsif].section_channel_ref;
-		buffer_size = TSPP_SECTION_BUFFER_SIZE;
-	}
-
-	/* check if required TSPP pipe is already allocated or not */
-	if (*channel_ref_count == 0) {
-		ret = tspp_open_channel(0, channel_id);
-		if (ret < 0) {
-			MPQ_DVB_ERR_PRINT(
-				"%s: tspp_open_channel(%d) failed (%d)\n",
-				__func__,
-				channel_id,
-				ret);
-
-			goto add_channel_failed;
-		}
-
-		/* set TSPP source */
-		ret = tspp_open_stream(0, channel_id, &tspp_source);
-		if (ret < 0) {
-			MPQ_DVB_ERR_PRINT(
-				"%s: tspp_select_source(%d,%d) failed (%d)\n",
-				__func__,
-				channel_id,
-				tspp_source.source,
-				ret);
-
-			goto add_channel_close_ch;
-		}
-
-		/* register notification on TS packets */
-		tspp_register_notification(0,
-					   channel_id,
-					   mpq_tspp_callback,
-					   (void *)tsif,
-					   tspp_channel_timeout);
-
-		/* register allocater and provide allocation function
-		 * that allocates from continous memory so that we can have
-		 * big notification size, smallest descriptor, and still provide
-		 * TZ with single big buffer based on notification size.
-		 */
-
-		/* set buffer/descriptor size and count,
-		 * allocate TSPP data buffers
-		 */
-		if (allocation_mode == MPQ_DMX_TSPP_CONTIGUOUS_PHYS_ALLOC) {
-			ret = tspp_allocate_buffers(0, channel_id,
-				   mpq_dmx_tspp_info.tsif[tsif].buffer_count,
-				   buffer_size, tspp_notification_size,
-				   tspp_mem_allocator, tspp_mem_free, NULL);
-		} else {
-			ret = tspp_allocate_buffers(0, channel_id,
-				   mpq_dmx_tspp_info.tsif[tsif].buffer_count,
-				   buffer_size, tspp_notification_size,
-				   NULL, NULL, NULL);
-		}
-		if (ret < 0) {
-			MPQ_DVB_ERR_PRINT(
-				"%s: tspp_allocate_buffers(%d) failed (%d)\n",
-				__func__,
-				channel_id,
-				ret);
-
-			goto add_channel_unregister_notif;
-		}
-
-		mpq_dmx_tspp_info.tsif[tsif].mpq_demux = mpq_demux;
-	}
-
-	/* add new PID to the existing pipe */
-	ret = mpq_tspp_get_free_filter_slot(tsif, channel_id);
-	if (ret < 0) {
-		MPQ_DVB_ERR_PRINT(
-			"%s: mpq_allocate_filter_slot(%d, %d) failed\n",
-			__func__,
-			tsif,
-			channel_id);
-
-		goto add_channel_unregister_notif;
-	}
-
-	mpq_dmx_tspp_info.tsif[tsif].filters[ret].pid = feed->pid;
-	mpq_dmx_tspp_info.tsif[tsif].filters[ret].ref_count++;
-
-	tspp_filter.priority = ret;
-	if (feed->pid == TSPP_PASS_THROUGH_PID) {
-		/* pass all pids */
-		tspp_filter.pid = 0;
-		tspp_filter.mask = 0;
-	} else {
-		tspp_filter.pid = feed->pid;
-		tspp_filter.mask = TSPP_PID_MASK;
-	}
-
-	/*
-	 * Include TTS in RAW packets, if you change this to
-	 * TSPP_MODE_RAW_NO_SUFFIX you must also change TSPP_RAW_TTS_SIZE
-	 * accordingly.
-	 */
-	tspp_filter.mode = TSPP_MODE_RAW;
-	tspp_filter.source = tspp_source.source;
-	tspp_filter.decrypt = 0;
-	ret = tspp_add_filter(0, channel_id, &tspp_filter);
-	if (ret < 0) {
-		MPQ_DVB_ERR_PRINT(
-			"%s: tspp_add_filter(%d) failed (%d)\n",
-			__func__,
-			channel_id,
-			ret);
-
-		goto add_channel_free_filter_slot;
-	}
-
-	(*channel_ref_count)++;
-
-	mutex_unlock(&mpq_dmx_tspp_info.tsif[tsif].mutex);
-	return 0;
-
-add_channel_free_filter_slot:
-	mpq_dmx_tspp_info.tsif[tsif].filters[tspp_filter.priority].pid = -1;
-	mpq_dmx_tspp_info.tsif[tsif].filters[tspp_filter.priority].ref_count--;
-add_channel_unregister_notif:
-	tspp_unregister_notification(0, channel_id);
-add_channel_close_ch:
-	tspp_close_channel(0, channel_id);
-add_channel_failed:
-	mutex_unlock(&mpq_dmx_tspp_info.tsif[tsif].mutex);
-	return ret;
-}
-
-/**
- * Removes filter from TSPP.
- *
- * @feed: The feed to remove
- *
- * Return  error status
- *
- * The function checks if this is the only PID allocated within
- * the channel, if so, the channel is closed as well.
- */
-static int mpq_tspp_dmx_remove_channel(struct dvb_demux_feed *feed)
-{
-	int tsif;
-	int ret;
-	int channel_id;
-	atomic_t *data_cnt;
-	int *channel_ref_count;
-	struct tspp_filter tspp_filter;
-	struct mpq_demux *mpq_demux = feed->demux->priv;
-
-	/* determine the TSIF we are reading from */
-	if (mpq_demux->source == DMX_SOURCE_FRONT0) {
-		tsif = 0;
-	} else if (mpq_demux->source == DMX_SOURCE_FRONT1) {
-		tsif = 1;
-	} else {
-		/* invalid source */
-		MPQ_DVB_ERR_PRINT(
-			"%s: invalid input source (%d)\n",
-			__func__,
-			mpq_demux->source);
-
-		return -EINVAL;
-	}
-
-	if (mutex_lock_interruptible(&mpq_dmx_tspp_info.tsif[tsif].mutex))
-		return -ERESTARTSYS;
-
-	/* determine to which pipe the feed should be routed: section or pes */
-	if ((feed->type == DMX_TYPE_PES) || (feed->type == DMX_TYPE_TS)) {
-		channel_id = TSPP_CHANNEL_ID(tsif, TSPP_PES_CHANNEL);
-		channel_ref_count =
-			&mpq_dmx_tspp_info.tsif[tsif].pes_channel_ref;
-		data_cnt = &mpq_dmx_tspp_info.tsif[tsif].pes_data_cnt;
-	} else {
-		channel_id = TSPP_CHANNEL_ID(tsif, TSPP_SECTION_CHANNEL);
-		channel_ref_count =
-			&mpq_dmx_tspp_info.tsif[tsif].section_channel_ref;
-		data_cnt = &mpq_dmx_tspp_info.tsif[tsif].section_data_cnt;
-	}
-
-	/* check if required TSPP pipe is already allocated or not */
-	if (*channel_ref_count == 0) {
-		/* invalid feed provided as the channel is not allocated */
-		MPQ_DVB_ERR_PRINT(
-			"%s: invalid feed (%d)\n",
-			__func__,
-			channel_id);
-
-		ret = -EINVAL;
-		goto remove_channel_failed;
-	}
-
-	tspp_filter.priority = mpq_tspp_get_filter_slot(tsif, feed->pid);
-
-	if (tspp_filter.priority < 0) {
-		/* invalid feed provided as it has no filter allocated */
-		MPQ_DVB_ERR_PRINT(
-			"%s: mpq_tspp_get_filter_slot failed (%d,%d)\n",
-			__func__,
-			feed->pid,
-			tsif);
-
-		ret = -EINVAL;
-		goto remove_channel_failed;
-	}
-
-	mpq_dmx_tspp_info.tsif[tsif].filters[tspp_filter.priority].ref_count--;
-
-	if (mpq_dmx_tspp_info.tsif[tsif].
-		filters[tspp_filter.priority].ref_count) {
-		/*
-		 * there are still references to this pid, do not
-		 * remove the filter yet
-		 */
-		mutex_unlock(&mpq_dmx_tspp_info.tsif[tsif].mutex);
-		return 0;
-	}
-
-	ret = tspp_remove_filter(0, channel_id, &tspp_filter);
-	if (ret < 0) {
-		/* invalid feed provided as it has no filter allocated */
-		MPQ_DVB_ERR_PRINT(
-			"%s: tspp_remove_filter failed (%d,%d)\n",
-			__func__,
-			channel_id,
-			tspp_filter.priority);
-
-		goto remove_channel_failed_restore_count;
-	}
-
-	mpq_dmx_tspp_info.tsif[tsif].filters[tspp_filter.priority].pid = -1;
-	(*channel_ref_count)--;
-
-	if (*channel_ref_count == 0) {
-		/* channel is not used any more, release it */
-		tspp_unregister_notification(0, channel_id);
-		tspp_close_channel(0, channel_id);
-		tspp_close_stream(0, channel_id);
-		atomic_set(data_cnt, 0);
-	}
-
-	mutex_unlock(&mpq_dmx_tspp_info.tsif[tsif].mutex);
-	return 0;
-
-remove_channel_failed_restore_count:
-	mpq_dmx_tspp_info.tsif[tsif].filters[tspp_filter.priority].ref_count++;
-
-remove_channel_failed:
-	mutex_unlock(&mpq_dmx_tspp_info.tsif[tsif].mutex);
-	return ret;
-}
-
-static int mpq_tspp_dmx_start_filtering(struct dvb_demux_feed *feed)
-{
-	int ret;
-	struct mpq_demux *mpq_demux = feed->demux->priv;
-
-	MPQ_DVB_DBG_PRINT(
-		"%s(%d) executed\n",
-		__func__,
-		feed->pid);
-
-	if (mpq_demux == NULL) {
-		MPQ_DVB_ERR_PRINT(
-			"%s: invalid mpq_demux handle\n",
-			__func__);
-
-		return -EINVAL;
-	}
-
-	if (mpq_demux->source < DMX_SOURCE_DVR0) {
-		/* source from TSPP, need to configure tspp pipe */
-		ret = mpq_tspp_dmx_add_channel(feed);
-
-		if (ret < 0) {
-			MPQ_DVB_DBG_PRINT(
-				"%s: mpq_tspp_dmx_add_channel failed(%d)\n",
-				__func__,
-				ret);
-			return ret;
-		}
-	}
-
-	/*
-	 * Always feed sections/PES starting from a new one and
-	 * do not partial transfer data from older one
-	 */
-	feed->pusi_seen = 0;
-
-	/*
-	 * For video PES, data is tunneled to the decoder,
-	 * initialize tunneling and pes parsing.
-	 */
-	if (mpq_dmx_is_video_feed(feed)) {
-		ret = mpq_dmx_init_video_feed(feed);
-
-		if (ret < 0) {
-			MPQ_DVB_ERR_PRINT(
-				"%s: mpq_dmx_init_video_feed failed(%d)\n",
-				__func__,
-				ret);
-
-			if (mpq_demux->source < DMX_SOURCE_DVR0)
-				mpq_tspp_dmx_remove_channel(feed);
-
-			return ret;
-		}
-	}
-
-	return 0;
-}
-
-static int mpq_tspp_dmx_stop_filtering(struct dvb_demux_feed *feed)
-{
-	int ret = 0;
-	struct mpq_demux *mpq_demux = feed->demux->priv;
-
-	MPQ_DVB_DBG_PRINT(
-		"%s(%d) executed\n",
-		__func__,
-		feed->pid);
-
-	/*
-	 * For video PES, data is tunneled to the decoder,
-	 * terminate tunnel and pes parsing.
-	 */
-	if (mpq_dmx_is_video_feed(feed))
-		mpq_dmx_terminate_video_feed(feed);
-
-	if (mpq_demux->source < DMX_SOURCE_DVR0) {
-		/* source from TSPP, need to configure tspp pipe */
-		ret = mpq_tspp_dmx_remove_channel(feed);
-	}
-
-	return ret;
-}
-
-static int mpq_tspp_dmx_write_to_decoder(
-					struct dvb_demux_feed *feed,
-					const u8 *buf,
-					size_t len)
-{
-
-	/*
-	 * It is assumed that this function is called once for each
-	 * TS packet of the relevant feed.
-	 */
-	if (len > TSPP_RAW_TTS_SIZE)
-		MPQ_DVB_DBG_PRINT(
-				"%s: warnning - len larger than one packet\n",
-				__func__);
-
-	if (mpq_dmx_is_video_feed(feed))
-		return mpq_dmx_process_video_packet(feed, buf);
-
-	if (mpq_dmx_is_pcr_feed(feed))
-		return mpq_dmx_process_pcr_packet(feed, buf);
-
-	return 0;
-}
-
-/**
- * Returns demux capabilities of TSPPv1 plugin
- *
- * @demux: demux device
- * @caps: Returned capbabilities
- *
- * Return     error code
- */
-static int mpq_tspp_dmx_get_caps(struct dmx_demux *demux,
-				struct dmx_caps *caps)
-{
-	struct dvb_demux *dvb_demux = demux->priv;
-
-	if ((dvb_demux == NULL) || (caps == NULL)) {
-		MPQ_DVB_ERR_PRINT(
-			"%s: invalid parameters\n",
-			__func__);
-
-		return -EINVAL;
-	}
-
-	caps->caps = DMX_CAP_PULL_MODE | DMX_CAP_VIDEO_DECODER_DATA;
-	caps->num_decoders = MPQ_ADAPTER_MAX_NUM_OF_INTERFACES;
-	caps->num_demux_devices = CONFIG_DVB_MPQ_NUM_DMX_DEVICES;
-	caps->num_pid_filters = TSPP_MAX_PID_FILTER_NUM;
-	caps->num_section_filters = dvb_demux->filternum;
-	caps->num_section_filters_per_pid = dvb_demux->filternum;
-	caps->section_filter_length = DMX_FILTER_SIZE;
-	caps->num_demod_inputs = TSIF_COUNT;
-	caps->num_memory_inputs = CONFIG_DVB_MPQ_NUM_DMX_DEVICES;
-	caps->max_bitrate = 144;
-	caps->demod_input_max_bitrate = 72;
-	caps->memory_input_max_bitrate = 72;
-	caps->section.flags = 0;
-	caps->section.max_size = 0xFFFFFFFF;
-	caps->section.size_alignment = 0;
-	caps->pes.flags = 0;
-	caps->pes.max_size = 0xFFFFFFFF;
-	caps->pes.size_alignment = 0;
-	caps->recording_188_tsp.flags = 0;
-	caps->recording_188_tsp.max_size = 0xFFFFFFFF;
-	caps->recording_188_tsp.size_alignment = 0;
-	caps->recording_192_tsp.flags = 0;
-	caps->recording_192_tsp.max_size = 0xFFFFFFFF;
-	caps->recording_192_tsp.size_alignment = 0;
-	caps->playback_188_tsp.flags = 0;
-	caps->playback_188_tsp.max_size = 0xFFFFFFFF;
-	caps->playback_188_tsp.size_alignment = 0;
-	caps->playback_192_tsp.flags = 0;
-	caps->playback_192_tsp.max_size = 0xFFFFFFFF;
-	caps->playback_192_tsp.size_alignment = 0;
-
-	return 0;
-}
-
-static void mpq_dmx_tsif_ion_cleanup(int i)
-{
-	mpq_dmx_tspp_info.tsif[i].pes_mem_heap_phys_base = 0;
-	mpq_dmx_tspp_info.tsif[i].section_mem_heap_phys_base = 0;
-
-	if (!IS_ERR_OR_NULL(mpq_dmx_tspp_info.tsif[i].pes_mem_heap_handle)) {
-		if (!IS_ERR_OR_NULL(mpq_dmx_tspp_info.tsif[i].
-				pes_mem_heap_virt_base))
-			ion_unmap_kernel(mpq_dmx_tspp_info.ion_client,
-				mpq_dmx_tspp_info.tsif[i].pes_mem_heap_handle);
-
-		ion_free(mpq_dmx_tspp_info.ion_client,
-			mpq_dmx_tspp_info.tsif[i].pes_mem_heap_handle);
-	}
-
-	if (!IS_ERR_OR_NULL(mpq_dmx_tspp_info.tsif[i].
-			section_mem_heap_handle)) {
-		if (!IS_ERR_OR_NULL(mpq_dmx_tspp_info.tsif[i].
-					section_mem_heap_virt_base))
-			ion_unmap_kernel(mpq_dmx_tspp_info.ion_client,
-					mpq_dmx_tspp_info.tsif[i].
-						section_mem_heap_handle);
-
-		ion_free(mpq_dmx_tspp_info.ion_client,
-			mpq_dmx_tspp_info.tsif[i].section_mem_heap_handle);
-	}
-
-	mpq_dmx_tspp_info.tsif[i].pes_mem_heap_virt_base = NULL;
-	mpq_dmx_tspp_info.tsif[i].section_mem_heap_virt_base = NULL;
-	mpq_dmx_tspp_info.tsif[i].pes_mem_heap_handle = NULL;
-	mpq_dmx_tspp_info.tsif[i].section_mem_heap_handle = NULL;
-}
-
-static void mpq_dmx_tspp_ion_cleanup(void)
-{
-	int i;
-
-	for (i = 0; i < TSIF_COUNT; i++)
-		mpq_dmx_tsif_ion_cleanup(i);
-}
-
-static int mpq_tspp_dmx_init(
-			struct dvb_adapter *mpq_adapter,
-			struct mpq_demux *mpq_demux)
-{
-	int i, result;
-	size_t len;
-
-	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
-
-	if (allocation_mode == MPQ_DMX_TSPP_CONTIGUOUS_PHYS_ALLOC) {
-		/*
-		 * Save ION client, used to allocate memory
-		 * for TSPP's buffers.
-		 */
-		mpq_dmx_tspp_info.ion_client = mpq_demux->ion_client;
-
-		if (IS_ERR_OR_NULL(mpq_dmx_tspp_info.ion_client))
-			return -EINVAL;
-
-		for (i = 0; i < TSIF_COUNT; i++) {
-			mpq_dmx_tspp_info.tsif[i].pes_mem_heap_handle =
-				ion_alloc(mpq_dmx_tspp_info.ion_client,
-				 (mpq_dmx_tspp_info.tsif[i].buffer_count *
-				  TSPP_PES_BUFFER_SIZE),
-				 TSPP_RAW_TTS_SIZE,
-				 ION_HEAP(ION_CP_MM_HEAP_ID),
-				 0); /* non-cached */
-			if (IS_ERR_OR_NULL(mpq_dmx_tspp_info.tsif[i].
-						pes_mem_heap_handle)) {
-				MPQ_DVB_ERR_PRINT("%s: ion_alloc() failed\n",
-						__func__);
-				mpq_dmx_tspp_ion_cleanup();
-				return -ENOMEM;
-			}
-			/* save virtual base address of heap */
-			mpq_dmx_tspp_info.tsif[i].pes_mem_heap_virt_base =
-				ion_map_kernel(mpq_dmx_tspp_info.ion_client,
-					mpq_dmx_tspp_info.tsif[i].
-						pes_mem_heap_handle);
-			if (IS_ERR_OR_NULL(mpq_dmx_tspp_info.tsif[i].
-						pes_mem_heap_virt_base)) {
-				MPQ_DVB_ERR_PRINT(
-					"%s: ion_map_kernel() failed\n",
-					__func__);
-				mpq_dmx_tspp_ion_cleanup();
-				return -ENOMEM;
-			}
-			/* save physical base address of heap */
-			result = ion_phys(mpq_dmx_tspp_info.ion_client,
-				mpq_dmx_tspp_info.tsif[i].pes_mem_heap_handle,
-				&(mpq_dmx_tspp_info.tsif[i].
-					pes_mem_heap_phys_base), &len);
-			if (result < 0) {
-				MPQ_DVB_ERR_PRINT("%s: ion_phys() failed\n",
-						__func__);
-				mpq_dmx_tspp_ion_cleanup();
-				return -ENOMEM;
-			}
-
-			mpq_dmx_tspp_info.tsif[i].section_mem_heap_handle =
-				ion_alloc(mpq_dmx_tspp_info.ion_client,
-				 (mpq_dmx_tspp_info.tsif[i].buffer_count *
-				  TSPP_SECTION_BUFFER_SIZE),
-				 TSPP_RAW_TTS_SIZE,
-				 ION_HEAP(ION_CP_MM_HEAP_ID),
-				 0); /* non-cached */
-			if (IS_ERR_OR_NULL(mpq_dmx_tspp_info.tsif[i].
-						section_mem_heap_handle)) {
-				MPQ_DVB_ERR_PRINT("%s: ion_alloc() failed\n",
-						__func__);
-				mpq_dmx_tspp_ion_cleanup();
-				return -ENOMEM;
-			}
-			/* save virtual base address of heap */
-			mpq_dmx_tspp_info.tsif[i].section_mem_heap_virt_base =
-				ion_map_kernel(mpq_dmx_tspp_info.ion_client,
-				mpq_dmx_tspp_info.tsif[i].
-					section_mem_heap_handle);
-			if (IS_ERR_OR_NULL(mpq_dmx_tspp_info.tsif[i].
-					section_mem_heap_virt_base)) {
-				MPQ_DVB_ERR_PRINT(
-					"%s: ion_map_kernel() failed\n",
-					__func__);
-				mpq_dmx_tspp_ion_cleanup();
-				return -ENOMEM;
-			}
-			/* save physical base address of heap */
-			result = ion_phys(mpq_dmx_tspp_info.ion_client,
-				mpq_dmx_tspp_info.tsif[i].
-					section_mem_heap_handle,
-				&(mpq_dmx_tspp_info.tsif[i].
-					section_mem_heap_phys_base), &len);
-			if (result < 0) {
-				MPQ_DVB_ERR_PRINT("%s: ion_phys() failed\n",
-						__func__);
-				mpq_dmx_tspp_ion_cleanup();
-				return -ENOMEM;
-			}
-		}
-	}
-
-	/* Set the kernel-demux object capabilities */
-	mpq_demux->demux.dmx.capabilities =
-		DMX_TS_FILTERING			|
-		DMX_PES_FILTERING			|
-		DMX_SECTION_FILTERING			|
-		DMX_MEMORY_BASED_FILTERING		|
-		DMX_CRC_CHECKING			|
-		DMX_TS_DESCRAMBLING;
-
-	/* Set dvb-demux "virtual" function pointers */
-	mpq_demux->demux.priv = (void *)mpq_demux;
-	mpq_demux->demux.filternum = TSPP_MAX_SECTION_FILTER_NUM;
-	mpq_demux->demux.feednum = MPQ_MAX_DMX_FILES;
-	mpq_demux->demux.start_feed = mpq_tspp_dmx_start_filtering;
-	mpq_demux->demux.stop_feed = mpq_tspp_dmx_stop_filtering;
-	mpq_demux->demux.write_to_decoder = mpq_tspp_dmx_write_to_decoder;
-
-	mpq_demux->demux.decoder_fullness_init =
-		mpq_dmx_decoder_fullness_init;
-
-	mpq_demux->demux.decoder_fullness_wait =
-		mpq_dmx_decoder_fullness_wait;
-
-	mpq_demux->demux.decoder_fullness_abort =
-		mpq_dmx_decoder_fullness_abort;
-
-	mpq_demux->demux.decoder_buffer_status =
-		mpq_dmx_decoder_buffer_status;
-
-	/* Initialize dvb_demux object */
-	result = dvb_dmx_init(&mpq_demux->demux);
-	if (result < 0) {
-		MPQ_DVB_ERR_PRINT("%s: dvb_dmx_init failed\n", __func__);
-		goto init_failed;
-	}
-
-	/* Now initailize the dmx-dev object */
-	mpq_demux->dmxdev.filternum = MPQ_MAX_DMX_FILES;
-	mpq_demux->dmxdev.demux = &mpq_demux->demux.dmx;
-	mpq_demux->dmxdev.capabilities =
-		DMXDEV_CAP_DUPLEX |
-		DMXDEV_CAP_PULL_MODE |
-		DMXDEV_CAP_INDEXING;
-
-	mpq_demux->dmxdev.demux->set_source = mpq_dmx_set_source;
-	mpq_demux->dmxdev.demux->get_caps = mpq_tspp_dmx_get_caps;
-	mpq_demux->dmxdev.demux->map_buffer = mpq_dmx_map_buffer;
-	mpq_demux->dmxdev.demux->unmap_buffer = mpq_dmx_unmap_buffer;
-
-	result = dvb_dmxdev_init(&mpq_demux->dmxdev, mpq_adapter);
-	if (result < 0) {
-		MPQ_DVB_ERR_PRINT("%s: dvb_dmxdev_init failed (errno=%d)\n",
-						  __func__,
-						  result);
-		goto init_failed_dmx_release;
-	}
-
-	/* Extend dvb-demux debugfs with TSPP statistics. */
-	mpq_dmx_init_hw_statistics(mpq_demux);
-
-	return 0;
-
-init_failed_dmx_release:
-	dvb_dmx_release(&mpq_demux->demux);
-init_failed:
-	mpq_dmx_tspp_ion_cleanup();
-	return result;
-}
-
-static int __init mpq_dmx_tspp_plugin_init(void)
-{
-	int i;
-	int j;
-	int ret;
-
-	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
-
-	for (i = 0; i < TSIF_COUNT; i++) {
-		mpq_dmx_tspp_info.tsif[i].buffer_count =
-				TSPP_BUFFER_COUNT(tspp_out_buffer_size);
-
-		mpq_dmx_tspp_info.tsif[i].pes_channel_ref = 0;
-		mpq_dmx_tspp_info.tsif[i].pes_index = 0;
-		mpq_dmx_tspp_info.tsif[i].pes_mem_heap_handle = NULL;
-		mpq_dmx_tspp_info.tsif[i].pes_mem_heap_virt_base = NULL;
-		mpq_dmx_tspp_info.tsif[i].pes_mem_heap_phys_base = 0;
-		atomic_set(&mpq_dmx_tspp_info.tsif[i].pes_data_cnt, 0);
-
-		mpq_dmx_tspp_info.tsif[i].section_channel_ref = 0;
-		mpq_dmx_tspp_info.tsif[i].section_index = 0;
-		mpq_dmx_tspp_info.tsif[i].section_mem_heap_handle = NULL;
-		mpq_dmx_tspp_info.tsif[i].section_mem_heap_virt_base = NULL;
-		mpq_dmx_tspp_info.tsif[i].section_mem_heap_phys_base = 0;
-		atomic_set(&mpq_dmx_tspp_info.tsif[i].section_data_cnt, 0);
-
-		for (j = 0; j < TSPP_MAX_PID_FILTER_NUM; j++) {
-			mpq_dmx_tspp_info.tsif[i].filters[j].pid = -1;
-			mpq_dmx_tspp_info.tsif[i].filters[j].ref_count = 0;
-		}
-
-		snprintf(mpq_dmx_tspp_info.tsif[i].name,
-				TSIF_NAME_LENGTH,
-				"dmx_tsif%d",
-				i);
-
-		init_waitqueue_head(&mpq_dmx_tspp_info.tsif[i].wait_queue);
-		mpq_dmx_tspp_info.tsif[i].thread =
-			kthread_run(
-				mpq_dmx_tspp_thread, (void *)i,
-				mpq_dmx_tspp_info.tsif[i].name);
-
-		if (IS_ERR(mpq_dmx_tspp_info.tsif[i].thread)) {
-			for (j = 0; j < i; j++) {
-				kthread_stop(mpq_dmx_tspp_info.tsif[j].thread);
-				mutex_destroy(&mpq_dmx_tspp_info.tsif[j].mutex);
-			}
-
-			MPQ_DVB_ERR_PRINT(
-				"%s: kthread_run failed\n",
-				__func__);
-
-			return -ENOMEM;
-		}
-
-		mutex_init(&mpq_dmx_tspp_info.tsif[i].mutex);
-	}
-
-	ret = mpq_dmx_plugin_init(mpq_tspp_dmx_init);
-
-	if (ret < 0) {
-		MPQ_DVB_ERR_PRINT(
-			"%s: mpq_dmx_plugin_init failed (errno=%d)\n",
-			__func__,
-			ret);
-
-		for (i = 0; i < TSIF_COUNT; i++) {
-			kthread_stop(mpq_dmx_tspp_info.tsif[i].thread);
-			mutex_destroy(&mpq_dmx_tspp_info.tsif[i].mutex);
-		}
-	}
-
-	return ret;
-}
-
-static void __exit mpq_dmx_tspp_plugin_exit(void)
-{
-	int i;
-
-	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
-
-	for (i = 0; i < TSIF_COUNT; i++) {
-		mutex_lock(&mpq_dmx_tspp_info.tsif[i].mutex);
-
-		/*
-		 * Note: tspp_close_channel will also free the TSPP buffers
-		 * even if we allocated them ourselves,
-		 * using our free function.
-		 */
-		if (mpq_dmx_tspp_info.tsif[i].pes_channel_ref) {
-			tspp_unregister_notification(0, TSPP_PES_CHANNEL);
-			tspp_close_channel(0,
-				TSPP_CHANNEL_ID(i, TSPP_PES_CHANNEL));
-		}
-
-		if (mpq_dmx_tspp_info.tsif[i].section_channel_ref) {
-			tspp_unregister_notification(0, TSPP_SECTION_CHANNEL);
-			tspp_close_channel(0,
-				TSPP_CHANNEL_ID(i, TSPP_SECTION_CHANNEL));
-		}
-
-		/* if we allocated buffer pools
-		 * to TSPP, need to free those as well
-		 */
-		if (allocation_mode == MPQ_DMX_TSPP_CONTIGUOUS_PHYS_ALLOC)
-			mpq_dmx_tsif_ion_cleanup(i);
-
-		mutex_unlock(&mpq_dmx_tspp_info.tsif[i].mutex);
-		kthread_stop(mpq_dmx_tspp_info.tsif[i].thread);
-		mutex_destroy(&mpq_dmx_tspp_info.tsif[i].mutex);
-	}
-
-	mpq_dmx_plugin_exit();
-}
-
-
-module_init(mpq_dmx_tspp_plugin_init);
-module_exit(mpq_dmx_tspp_plugin_exit);
-
-MODULE_DESCRIPTION("Qualcomm demux TSPP version 1 HW Plugin");
-MODULE_LICENSE("GPL v2");
-
-
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v2.c b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v2.c
deleted file mode 100644
index e4858fa..0000000
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v2.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/module.h>
-#include "mpq_dvb_debug.h"
-#include "mpq_dmx_plugin_common.h"
-
-
-#define TSIF_COUNT				2
-
-#define BAM_INPUT_COUNT			4
-
-/* Max number of PID filters */
-#define TSPP_MAX_PID_FILTER_NUM		128
-
-/* Max number of section filters */
-#define TSPP_MAX_SECTION_FILTER_NUM		64
-
-
-static int mpq_tspp_dmx_start_filtering(struct dvb_demux_feed *feed)
-{
-	MPQ_DVB_DBG_PRINT(
-		"%s(%d) executed\n",
-		__func__,
-		feed->pid);
-
-	/* Always feed sections/PES starting from a new one and
-	 * do not partial transfer data from older one
-	 */
-	feed->pusi_seen = 0;
-	return 0;
-}
-
-static int mpq_tspp_dmx_stop_filtering(struct dvb_demux_feed *feed)
-{
-	MPQ_DVB_DBG_PRINT(
-		"%s(%d) executed\n",
-		__func__,
-		feed->pid);
-
-	return 0;
-}
-
-/**
- * Returns demux capabilities of TSPPv2 plugin
- *
- * @demux: demux device
- * @caps: Returned capbabilities
- *
- * Return     error code
- */
-static int mpq_tspp_dmx_get_caps(struct dmx_demux *demux,
-				struct dmx_caps *caps)
-{
-	struct dvb_demux *dvb_demux = demux->priv;
-
-	if ((dvb_demux == NULL) || (caps == NULL)) {
-		MPQ_DVB_ERR_PRINT(
-			"%s: invalid parameters\n",
-			__func__);
-
-		return -EINVAL;
-	}
-
-	caps->caps = DMX_CAP_PULL_MODE | DMX_CAP_VIDEO_INDEXING |
-		DMX_CAP_VIDEO_DECODER_DATA;
-	caps->num_decoders = MPQ_ADAPTER_MAX_NUM_OF_INTERFACES;
-	caps->num_demux_devices = CONFIG_DVB_MPQ_NUM_DMX_DEVICES;
-	caps->num_pid_filters = TSPP_MAX_PID_FILTER_NUM;
-	caps->num_section_filters = dvb_demux->filternum;
-	caps->num_section_filters_per_pid = dvb_demux->filternum;
-	caps->section_filter_length = DMX_FILTER_SIZE;
-	caps->num_demod_inputs = TSIF_COUNT;
-	caps->num_memory_inputs = BAM_INPUT_COUNT;
-	caps->max_bitrate = 320;
-	caps->demod_input_max_bitrate = 96;
-	caps->memory_input_max_bitrate = 80;
-
-	return 0;
-}
-
-/**
- * Initialize a single demux device.
- *
- * @mpq_adapter: MPQ DVB adapter
- * @mpq_demux: The demux device to initialize
- *
- * Return     error code
- */
-static int mpq_tspp_dmx_init(
-				struct dvb_adapter *mpq_adapter,
-				struct mpq_demux *mpq_demux)
-{
-	int result;
-
-	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
-
-	/* Set the kernel-demux object capabilities */
-	mpq_demux->demux.dmx.capabilities =
-		DMX_TS_FILTERING			|
-		DMX_PES_FILTERING			|
-		DMX_SECTION_FILTERING		|
-		DMX_MEMORY_BASED_FILTERING	|
-		DMX_CRC_CHECKING			|
-		DMX_TS_DESCRAMBLING;
-
-	/* Set dvb-demux "virtual" function pointers */
-	mpq_demux->demux.priv = (void *)mpq_demux;
-	mpq_demux->demux.filternum = TSPP_MAX_SECTION_FILTER_NUM;
-	mpq_demux->demux.feednum = MPQ_MAX_DMX_FILES;
-	mpq_demux->demux.start_feed = mpq_tspp_dmx_start_filtering;
-	mpq_demux->demux.stop_feed = mpq_tspp_dmx_stop_filtering;
-	mpq_demux->demux.write_to_decoder = NULL;
-	mpq_demux->demux.decoder_fullness_init = NULL;
-	mpq_demux->demux.decoder_fullness_wait = NULL;
-	mpq_demux->demux.decoder_fullness_abort = NULL;
-	mpq_demux->demux.decoder_buffer_status = NULL;
-
-	/* Initialize dvb_demux object */
-	result = dvb_dmx_init(&mpq_demux->demux);
-	if (result < 0) {
-		MPQ_ERR_PRINT("%s: dvb_dmx_init failed\n", __func__);
-		goto init_failed;
-	}
-
-	/* Now initailize the dmx-dev object */
-	mpq_demux->dmxdev.filternum = MPQ_MAX_DMX_FILES;
-	mpq_demux->dmxdev.demux = &mpq_demux->demux.dmx;
-	mpq_demux->dmxdev.capabilities =
-		DMXDEV_CAP_DUPLEX |
-		DMXDEV_CAP_PULL_MODE |
-		DMXDEV_CAP_INDEXING;
-
-	mpq_demux->dmxdev.demux->set_source = mpq_dmx_set_source;
-	mpq_demux->dmxdev.demux->get_caps = mpq_tspp_dmx_get_caps;
-
-	result = dvb_dmxdev_init(&mpq_demux->dmxdev, mpq_adapter);
-	if (result < 0) {
-		MPQ_DVB_ERR_PRINT("%s: dvb_dmxdev_init failed (errno=%d)\n",
-						  __func__,
-						  result);
-
-		goto init_failed_dmx_release;
-	}
-
-	return 0;
-
-init_failed_dmx_release:
-	dvb_dmx_release(&mpq_demux->demux);
-init_failed:
-	return result;
-}
-
-static int __init mpq_dmx_tspp_plugin_init(void)
-{
-	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
-
-	return mpq_dmx_plugin_init(mpq_tspp_dmx_init);
-}
-
-static void __exit mpq_dmx_tspp_plugin_exit(void)
-{
-	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
-	mpq_dmx_plugin_exit();
-}
-
-
-module_init(mpq_dmx_tspp_plugin_init);
-module_exit(mpq_dmx_tspp_plugin_exit);
-
-MODULE_DESCRIPTION("Qualcomm demux TSPP version2 HW Plugin");
-MODULE_LICENSE("GPL v2");
-
diff --git a/drivers/media/dvb/mpq/include/mpq_adapter.h b/drivers/media/dvb/mpq/include/mpq_adapter.h
deleted file mode 100644
index c9b2441..0000000
--- a/drivers/media/dvb/mpq/include/mpq_adapter.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 _MPQ_ADAPTER_H
-#define _MPQ_ADAPTER_H
-
-#include "dvbdev.h"
-#include "mpq_stream_buffer.h"
-
-
-
-/** IDs of interfaces holding stream-buffers */
-enum mpq_adapter_stream_if {
-	/** Interface holding stream-buffer for video0 stream */
-	MPQ_ADAPTER_VIDEO0_STREAM_IF = 0,
-
-	/** Interface holding stream-buffer for video1 stream */
-	MPQ_ADAPTER_VIDEO1_STREAM_IF = 1,
-
-	/** Interface holding stream-buffer for video1 stream */
-	MPQ_ADAPTER_VIDEO2_STREAM_IF = 2,
-
-	/** Interface holding stream-buffer for video1 stream */
-	MPQ_ADAPTER_VIDEO3_STREAM_IF = 3,
-
-	/** Maximum number of interfaces holding stream-buffers */
-	MPQ_ADAPTER_MAX_NUM_OF_INTERFACES,
-};
-
-
-enum dmx_framing_pattern_type {
-	/* MPEG-2 */
-	DMX_FRM_MPEG2_SEQUENCE_HEADER,
-	DMX_FRM_MPEG2_GOP_HEADER,
-	DMX_FRM_MPEG2_I_PIC,
-	DMX_FRM_MPEG2_P_PIC,
-	DMX_FRM_MPEG2_B_PIC,
-	/* H.264 */
-	DMX_FRM_H264_SPS,
-	DMX_FRM_H264_PPS,
-	/* H.264 First Coded slice of an IDR Picture */
-	DMX_FRM_H264_IDR_PIC,
-	/* H.264 First Coded slice of a non-IDR Picture */
-	DMX_FRM_H264_NON_IDR_PIC,
-	/* VC-1 Sequence Header*/
-	DMX_FRM_VC1_SEQUENCE_HEADER,
-	/* VC-1 Entry Point Header (Advanced Profile only) */
-	DMX_FRM_VC1_ENTRY_POINT_HEADER,
-	/* VC-1 Frame Start Code */
-	DMX_FRM_VC1_FRAME_START_CODE,
-	/* Unknown or invalid framing information */
-	DMX_FRM_UNKNOWN
-};
-
-enum dmx_packet_type {
-	DMX_PADDING_PACKET,
-	DMX_PES_PACKET,
-	DMX_FRAMING_INFO_PACKET,
-	DMX_EOS_PACKET
-};
-
-struct dmx_pts_dts_info {
-	/** Indication whether PTS exist */
-	int pts_exist;
-
-	/** Indication whether DTS exist */
-	int dts_exist;
-
-	/** PTS value associated with the PES data if any */
-	u64 pts;
-
-	/** DTS value associated with the PES data if any */
-	u64 dts;
-};
-
-struct dmx_framing_packet_info {
-	/** framing pattern type */
-	enum dmx_framing_pattern_type pattern_type;
-	/** PTS/DTS information */
-	struct dmx_pts_dts_info pts_dts_info;
-};
-
-struct dmx_pes_packet_info {
-	/** PTS/DTS information */
-	struct dmx_pts_dts_info pts_dts_info;
-};
-
-/** The meta-data used for video interface */
-struct mpq_adapter_video_meta_data {
-	/** meta-data packet type */
-	enum dmx_packet_type packet_type;
-
-	/** packet-type specific information */
-	union {
-		struct dmx_framing_packet_info framing;
-		struct dmx_pes_packet_info pes;
-	} info;
-} __packed;
-
-
-/** Callback function to notify on registrations of specific interfaces */
-typedef void (*mpq_adapter_stream_if_callback)(
-				enum mpq_adapter_stream_if interface_id,
-				void *user_param);
-
-
-/**
- * mpq_adapter_get - Returns pointer to Qualcomm DVB adapter
- *
- * Return     dvb adapter or NULL if not exist.
- */
-struct dvb_adapter *mpq_adapter_get(void);
-
-
-/**
- * mpq_adapter_register_stream_if - Register a stream interface.
- *
- * @interface_id: The interface id
- * @stream_buffer: The buffer used for the interface
- *
- * Return     error status
- *
- * Stream interface used to connect between two units in tunneling
- * mode using mpq_streambuffer implementation.
- * The producer of the interface should register the new interface,
- * consumer may get the interface using mpq_adapter_get_stream_if.
- *
- * Note that the function holds a pointer to this interface,
- * stream_buffer pointer assumed to be valid as long as interface
- * is active.
- */
-int mpq_adapter_register_stream_if(
-		enum mpq_adapter_stream_if interface_id,
-		struct mpq_streambuffer *stream_buffer);
-
-
-/**
- * mpq_adapter_unregister_stream_if - Un-register a stream interface.
- *
- * @interface_id: The interface id
- *
- * Return     error status
- */
-int mpq_adapter_unregister_stream_if(
-		enum mpq_adapter_stream_if interface_id);
-
-
-/**
- * mpq_adapter_get_stream_if - Get buffer used for a stream interface.
- *
- * @interface_id: The interface id
- * @stream_buffer: The returned stream buffer
- *
- * Return     error status
- */
-int mpq_adapter_get_stream_if(
-		enum mpq_adapter_stream_if interface_id,
-		struct mpq_streambuffer **stream_buffer);
-
-
-/**
- * mpq_adapter_notify_stream_if - Register notification
- * to be triggered when a stream interface is registered.
- *
- * @interface_id: The interface id
- * @callback: The callback to be triggered when the interface is registered
- * @user_param: A parameter that is passed back to the callback function
- *				when triggered.
- *
- * Return     error status
- *
- * Producer may use this to register notification when desired
- * interface registered in the system and query its information
- * afterwards using mpq_adapter_get_stream_if.
- * To remove the callback, this function should be called with NULL
- * value in callback parameter.
- */
-int mpq_adapter_notify_stream_if(
-		enum mpq_adapter_stream_if interface_id,
-		mpq_adapter_stream_if_callback callback,
-		void *user_param);
-
-#endif /* _MPQ_ADAPTER_H */
-
diff --git a/drivers/media/dvb/mpq/include/mpq_dvb_debug.h b/drivers/media/dvb/mpq/include/mpq_dvb_debug.h
deleted file mode 100644
index 4890b85..0000000
--- a/drivers/media/dvb/mpq/include/mpq_dvb_debug.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 _MPQ_DVB_DEBUG_H
-#define _MPQ_DVB_DEBUG_H
-
-/* Enable this line if you want to output debug printouts */
-#define MPG_DVB_DEBUG_ENABLE
-
-#undef MPQ_DVB_DBG_PRINT		/* undef it, just in case */
-
-#ifdef MPG_DVB_DEBUG_ENABLE
-#define MPQ_DVB_DBG_PRINT(fmt, args...) pr_debug(fmt, ## args)
-#define MPQ_DVB_ERR_PRINT(fmt, args...) pr_err(fmt, ## args)
-#else  /* MPG_DVB_DEBUG_ENABLE */
-#define MPQ_DVB_DBG_PRINT(fmt, args...)
-#define MPQ_DVB_ERR_PRINT(fmt, args...)
-#endif /* MPG_DVB_DEBUG_ENABLE */
-
-
-/*
- * The following can be used to disable specific printout
- * by adding a letter to the end of MPQ_DVB_DBG_PRINT
- */
-#undef MPQ_DVB_DBG_PRINTT
-#define MPQ_DVB_DBG_PRINTT(fmt, args...)
-
-#endif /* _MPQ_DVB_DEBUG_H */
-
diff --git a/drivers/media/dvb/mpq/include/mpq_stream_buffer.h b/drivers/media/dvb/mpq/include/mpq_stream_buffer.h
deleted file mode 100644
index 9476c73..0000000
--- a/drivers/media/dvb/mpq/include/mpq_stream_buffer.h
+++ /dev/null
@@ -1,419 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 _MPQ_STREAM_BUFFER_H
-#define _MPQ_STREAM_BUFFER_H
-
-#include "dvb_ringbuffer.h"
-
-
-/**
- * DOC: MPQ Stream Buffer
- *
- * A stream buffer implementation is used to transfer data between two units
- * such as demux and decoders. The implementation relies on dvb_ringbuffer
- * implementation. Refer to dvb_ringbuffer.h for details.
- *
- * The implementation uses two dvb_ringbuffers, one to pass the
- * raw-data (PES payload for example) and the other to pass
- * meta-data (information from PES header for example).
- *
- * The meta-data uses dvb_ringbuffer packet interface. Each meta-data
- * packet points to the data buffer, and includes the offset to the data in the
- * buffer, the size of raw-data described by the meta-data packet, and also the
- * size of user's own parameters if any required.
- *
- * Data can be managed in two ways: ring-buffer & linear buffers, as specified
- * in initialization when calling the mpq_streambuffer_init function.
- * For managing data as a ring buffer exactly 1 data buffer descriptor must be
- * specified in initialization. For this mode, dvb_ringbuffer is used "as-is".
- * For managing data in several linear buffers, an array of buffer descriptors
- * must be passed.
- * For both modes, data descriptor(s) must be remain valid throughout the life
- * span of the mpq_streambuffer object.
- * Apart from initialization API remains the same for both modes.
- *
- * Contrary to dvb_ringbuffer implementation, this API makes sure there's
- * enough data to read/write when making read/write operations.
- * Users interested to flush/reset specific buffer, check for bytes
- * ready or space available for write should use the respective services
- * in dvb_ringbuffer (dvb_ringbuffer_avail, dvb_ringbuffer_free,
- * dvb_ringbuffer_reset, dvb_ringbuffer_flush,
- * dvb_ringbuffer_flush_spinlock_wakeup).
- *
- * Concurrency protection is handled in the same manner as in
- * dvb_ringbuffer implementation.
- *
- * Typical call flow from producer:
- *
- * - Start writing the raw-data of new packet, the following call is
- *   repeated until end of data of the specific packet
- *
- *      mpq_streambuffer_data_write(...)
- *
- * - Now write a new packet describing the new available raw-data
- *      mpq_streambuffer_pkt_write(...)
- *
- *   For linear buffer mode, writing a new packet with data size > 0, causes the
- *   current buffer to be marked as pending for reading, and triggers moving to
- *   the next available buffer, that shall now be the current write buffer.
- *
- * Typical call flow from consumer:
- *
- * - Poll for next available packet:
- *      mpq_streambuffer_pkt_next(&streambuff,-1,&len)
- *
- *   In different approach, consumer can wait on event for new data and then
- *   call mpq_streambuffer_pkt_next, waiting for data can be done as follows:
- *
- *      wait_event_interruptible(
- *			streambuff->packet_data->queue,
- *			!dvb_ringbuffer_empty(&streambuff->packet_data) ||
- *			(streambuff->packet_data.error != 0);
- *
- * - Get the new packet information:
- *      mpq_streambuffer_pkt_read(..)
- *
- * - Read the raw-data of the new packet. Here you can use two methods:
- *
- *   1. Read the data to a user supplied buffer:
- *         mpq_streambuffer_data_read()
- *
- *      In this case memory copy is done, read pointer is updated in the raw
- *      data buffer, the amount of raw-data is provided part of the
- *      packet's information. User should then call mpq_streambuffer_pkt_dispose
- *      with dispose_data set to 0 as the raw-data was already disposed.
- *      Note that secure buffer cannot be accessed directly and an error will
- *      occur.
- *
- *   2. Access the data directly using the raw-data address. The address
- *      of the raw data is provided part of the packet's information. User
- *      then should call mpq_streambuffer_pkt_dispose with dispose_data set
- *      to 1 to dispose the packet along with it's raw-data.
- *
- * - Disposal of packets:
- *      mpq_streambuffer_pkt_dispose(...)
- *
- *   For linear buffer mode, disposing of a packet with data size > 0, causes
- *   the current buffer to be marked as free for writing, and triggers moving to
- *   the next available buffer, that shall now be the current read buffer.
-
- *
- */
-
-struct mpq_streambuffer;
-
-typedef void (*mpq_streambuffer_pkt_dispose_cb) (
-	struct mpq_streambuffer *sbuff,
-	void *user_data);
-
-enum mpq_streambuffer_mode {
-	MPQ_STREAMBUFFER_BUFFER_MODE_RING,
-	MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR
-};
-
-/**
- * struct mpq_streambuffer - mpq stream buffer representation
- *
- * @raw_data: The buffer used to hold raw-data, or linear buffer descriptors
- * @packet_data: The buffer user to hold the meta-data
- * @buffers: array of buffer descriptor(s) holding buffer initial & dynamic
- *	     buffer information
- * @mode: mpq_streambuffer buffer management work mode - Ring-buffer or Linear
- *	  buffers
- * @buffers_num: number of data buffers to manage
- * @pending_buffers_count: for linear buffer management, counts the number of
- * buffer that has been
- */
-struct mpq_streambuffer {
-	struct dvb_ringbuffer raw_data;
-	struct dvb_ringbuffer packet_data;
-	struct mpq_streambuffer_buffer_desc *buffers;
-	enum mpq_streambuffer_mode mode;
-	u32 buffers_num;
-	u32 pending_buffers_count;
-	mpq_streambuffer_pkt_dispose_cb cb;
-	void *cb_user_data;
-};
-
-/**
- * mpq_streambuffer_linear_desc
- * @handle:	ION handle's file descriptor of buffer
- * @base:	kernel mapped address to start of buffer.
- *		Can be NULL for secured buffers
- * @size:	size of buffer
- * @read_ptr:	initial read pointer value (should normally be 0)
- * @write_ptr:	initial write pointer value (should normally be 0)
- */
-struct mpq_streambuffer_buffer_desc {
-	int	handle;
-	void	*base;
-	u32	size;
-	u32	read_ptr;
-	u32	write_ptr;
-};
-
-/**
- * struct mpq_streambuffer_packet_header - packet header saved in packet buffer
- * @user_data_len: length of private user (meta) data
- * @raw_data_handle: ION handle's file descriptor of raw-data buffer
- * @raw_data_offset: offset of raw-data from start of buffer (0 for linear)
- * @raw_data_len: size of raw-data in the raw-data buffer (can be 0)
- *
- * The packet structure that is saved in each packet-buffer:
- * user_data_len
- * raw_data_handle
- * raw_data_offset
- * raw_data_len
- * private user-data bytes
- */
-struct mpq_streambuffer_packet_header {
-	u32 user_data_len;
-	int raw_data_handle;
-	u32 raw_data_offset;
-	u32 raw_data_len;
-} __packed;
-
-/**
- * mpq_streambuffer_init - Initialize a new stream buffer
- *
- * @sbuff: The buffer to initialize
- * @data_buffers: array of data buffer descriptor(s).
- *		  Data descriptor(s) must be remain valid throughout the life
- *		  span of the mpq_streambuffer object
- * @data_buff_num: number of data buffer in array
- * @packet_buff: The buffer holding meta-data
- * @packet_buff_size: Size of meta-data buffer
- *
- * Return	Error status, -EINVAL if any of the arguments are invalid
- *
- * Note:
- * for data_buff_num > 1, mpq_streambuffer object manages these buffers as a
- * separated set of linear buffers. A linear buffer cannot wrap-around and one
- * can only write as many data bytes as the buffer's size. Data will not be
- * written to the next free buffer.
- */
-int mpq_streambuffer_init(
-		struct mpq_streambuffer *sbuff,
-		enum mpq_streambuffer_mode mode,
-		struct mpq_streambuffer_buffer_desc *data_buffers,
-		u32 data_buff_num,
-		void *packet_buff,
-		size_t packet_buff_size);
-
-/**
- * mpq_streambuffer_packet_next - Returns index of next available packet.
- *
- * @sbuff: The stream buffer
- * @idx: Previous packet index or -1 to return index of the the first
- *       available packet.
- * @pktlen: The length of the ready packet
- *
- * Return index to the packet-buffer, -1 if buffer is empty
- *
- * After getting the index, the user of this function can either
- * access the packet buffer directly using the returned index
- * or ask to read the data back from the buffer using mpq_ringbuffer_pkt_read
- */
-ssize_t mpq_streambuffer_pkt_next(
-		struct mpq_streambuffer *sbuff,
-		ssize_t idx, size_t *pktlen);
-
-/**
- * mpq_streambuffer_pkt_read - Reads out the packet from the provided index.
- *
- * @sbuff: The stream buffer
- * @idx: The index of the packet to be read
- * @packet: The read packet's header
- * @user_data: The read private user data
- *
- * Return  The actual number of bytes read, -EINVAL if the packet is
- * already disposed or the packet-data is invalid.
- *
- * The packet is not disposed after this function is called, to dispose it
- * along with the raw-data it points to use mpq_streambuffer_pkt_dispose.
- * If there are no private user-data, the user-data pointer can be NULL.
- * The caller of this function must make sure that the private user-data
- * buffer has enough space for the private user-data length
- */
-ssize_t mpq_streambuffer_pkt_read(
-		struct mpq_streambuffer *sbuff,
-		size_t idx,
-		struct mpq_streambuffer_packet_header *packet,
-		u8 *user_data);
-
-/**
- * mpq_streambuffer_pkt_dispose - Disposes a packet from the packet buffer
- *
- * @sbuff: The stream buffer
- * @idx: The index of the packet to be disposed
- * @dispose_data: Indicates whether to update the read pointer inside the
- * raw-data buffer for the respective data pointed by the packet.
- *
- * Return  error status, -EINVAL if the packet-data is invalid
- *
- * The function updates the read pointer inside the raw-data buffer
- * for the respective data pointed by the packet if dispose_data is set.
- */
-int mpq_streambuffer_pkt_dispose(
-		struct mpq_streambuffer *sbuff,
-		size_t idx,
-		int dispose_data);
-
-/**
- * mpq_streambuffer_pkt_write - Write a new packet to the packet buffer.
- *
- * @sbuff: The stream buffer
- * @packet: The packet header to write
- * @user_data: The private user-data to be written
- *
- * Return  error status, -ENOSPC if there's no space to write the packet
- */
-int mpq_streambuffer_pkt_write(
-		struct mpq_streambuffer *sbuff,
-		struct mpq_streambuffer_packet_header *packet,
-		u8 *user_data);
-
-/**
- * mpq_streambuffer_data_write - Write data to raw-data buffer
- *
- * @sbuff: The stream buffer
- * @buf: The buffer holding the data to be written
- * @len: The length of the data buffer
- *
- * Return  The actual number of bytes written or -ENOSPC if
- *			no space to write the data
- */
-ssize_t mpq_streambuffer_data_write(
-		struct mpq_streambuffer *sbuff,
-		const u8 *buf, size_t len);
-
-/**
- * mpq_streambuffer_data_write_deposit - Advances the raw-buffer write pointer.
- * Assumes the raw-data was written by the user directly
- *
- * @sbuff: The stream buffer
- * @len: The length of the raw-data that was already written
- *
- * Return  error status
- */
-int mpq_streambuffer_data_write_deposit(
-		struct mpq_streambuffer *sbuff,
-		size_t len);
-
-/**
- * mpq_streambuffer_data_read - Reads out raw-data to the provided buffer.
- *
- * @sbuff: The stream buffer
- * @buf: The buffer to read the raw-data data to
- * @len: The length of the buffer that will hold the raw-data
- *
- * Return  The actual number of bytes read or error code
- *
- * This function copies the data from the ring-buffer to the
- * provided buf parameter. The user can save the extra copy by accessing
- * the data pointer directly and reading from it, then update the
- * read pointer by the amount of data that was read using
- * mpq_streambuffer_data_read_dispose
- */
-ssize_t mpq_streambuffer_data_read(
-		struct mpq_streambuffer *sbuff,
-		u8 *buf, size_t len);
-
-/**
- * mpq_streambuffer_data_read_user
- *
- * Same as mpq_streambuffer_data_read except data can be copied to user-space
- * buffer.
- */
-ssize_t mpq_streambuffer_data_read_user(
-		struct mpq_streambuffer *sbuff,
-		u8 __user *buf, size_t len);
-
-/**
- * mpq_streambuffer_data_read_dispose - Advances the raw-buffer read pointer.
- * Assumes the raw-data was read by the user directly.
- *
- * @sbuff: The stream buffer
- * @len: The length of the raw-data to be disposed
- *
- * Return  error status, -EINVAL if buffer there's no enough data to
- *			be disposed
- *
- * The user can instead dispose a packet along with the data in the
- * raw-data buffer using mpq_streambuffer_pkt_dispose.
- */
-int mpq_streambuffer_data_read_dispose(
-		struct mpq_streambuffer *sbuff,
-		size_t len);
-/**
- * mpq_streambuffer_get_buffer_handle - Returns the current linear buffer
- * ION handle.
- * @sbuff: The stream buffer
- * @read_buffer: specifies if a read buffer handle is requested (when set),
- *		 or a write buffer handle is requested.
- *		 For linear buffer mode read & write buffers may be different
- *		 buffers. For ring buffer mode, the same (single) buffer handle
- *		 is returned.
- * buffer handle
- * @handle: returned handle
- *
- * Return error status
- * -EINVAL is arguments are invalid.
- * -EPERM if stream buffer specified was not initialized with linear support.
- */
-int mpq_streambuffer_get_buffer_handle(
-	struct mpq_streambuffer *sbuff,
-	int read_buffer,
-	int *handle);
-
-/**
- * mpq_streambuffer_data_free - Returns number of free bytes in data buffer.
- * @sbuff: The stream buffer object
- *
- * Note: for linear buffer management this return number of free bytes in the
- * current write buffer only.
- */
-ssize_t mpq_streambuffer_data_free(
-	struct mpq_streambuffer *sbuff);
-
-/**
- * mpq_streambuffer_data_avail - Returns number of bytes in data buffer that
- * can be read.
- * @sbuff: The stream buffer object
- *
- * Note: for linear buffer management this return number of data bytes in the
- * current read buffer only.
- */
-ssize_t mpq_streambuffer_data_avail(
-	struct mpq_streambuffer *sbuff);
-
-/**
- * mpq_streambuffer_register_pkt_dispose - Registers a callback to notify on
- * packet disposal events.
- * can be read.
- * @sbuff: The stream buffer object
- * @cb_func: user callback function
- * @user_data: user data to be passed to callback function.
- *
- * Returns error status
- * -EINVAL if arguments are invalid
- */
-int mpq_streambuffer_register_pkt_dispose(
-	struct mpq_streambuffer *sbuff,
-	mpq_streambuffer_pkt_dispose_cb cb_func,
-	void *user_data);
-
-
-
-#endif /* _MPQ_STREAM_BUFFER_H */
-
diff --git a/drivers/media/dvb/mpq/video/Makefile b/drivers/media/dvb/mpq/video/Makefile
deleted file mode 100644
index 38c1091..0000000
--- a/drivers/media/dvb/mpq/video/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-
-ccflags-y += -Idrivers/media/dvb/dvb-core/
-ccflags-y += -Idrivers/media/dvb/mpq/include/
-
-obj-$(CONFIG_DVB_MPQ_VIDEO) += mpq_dvb_video.o
diff --git a/drivers/media/dvb/mpq/video/mpq_dvb_video.c b/drivers/media/dvb/mpq/video/mpq_dvb_video.c
deleted file mode 100644
index 229a81a..0000000
--- a/drivers/media/dvb/mpq/video/mpq_dvb_video.c
+++ /dev/null
@@ -1,2467 +0,0 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. 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/cdev.h>
-#include <linux/device.h>
-#include <linux/firmware.h>
-#include <linux/fs.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/list.h>
-#include <linux/poll.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/kthread.h>
-#include <linux/uaccess.h>
-#include <linux/wait.h>
-#include <linux/workqueue.h>
-#include <linux/android_pmem.h>
-#include <linux/clk.h>
-#include <linux/timer.h>
-#include <mach/msm_subsystem_map.h>
-#include <media/msm/vidc_type.h>
-#include <media/msm/vcd_api.h>
-#include <media/msm/vidc_init.h>
-#include "mpq_dvb_video_internal.h"
-
-
-#define DBG(x...) pr_debug(x)
-#define INFO(x...) pr_info(x)
-#define ERR(x...) pr_err(x)
-
-#define MPQ_VID_DEC_NAME "mpq_vidc_dec"
-static unsigned int vidc_mmu_subsystem[] = {
-	MSM_SUBSYSTEM_VIDEO};
-
-static char vid_thread_names[DVB_MPQ_NUM_VIDEO_DEVICES][10] = {
-				"dvb-vid-0",
-				"dvb-vid-1",
-				"dvb-vid-2",
-				"dvb-vid-3",
-};
-
-static enum scan_format map_scan_type(enum vdec_interlaced_format type);
-static int mpq_int_vid_dec_decode_frame(struct video_client_ctx *client_ctx,
-				struct video_data_buffer *input_frame);
-static int mpq_int_vid_dec_get_buffer_req(struct video_client_ctx *client_ctx,
-				  struct video_buffer_req *vdec_buf_req);
-
-static struct mpq_dvb_video_dev *mpq_dvb_video_device;
-
-static int mpq_get_dev_frm_client(struct video_client_ctx *client_ctx,
-				struct mpq_dvb_video_inst **dev_inst)
-{
-	int i;
-
-	for (i = 0; i < DVB_MPQ_NUM_VIDEO_DEVICES; i++) {
-		if (mpq_dvb_video_device->dev_inst[i].client_ctx ==
-						client_ctx) {
-			*dev_inst = &mpq_dvb_video_device->dev_inst[i];
-			break;
-		}
-	}
-
-	if (i == DVB_MPQ_NUM_VIDEO_DEVICES)
-		return -ENODEV;
-
-	return 0;
-}
-
-static u32 mpq_int_check_bcast_mq(struct mpq_dmx_src_data *dmx_data)
-{
-	u32 islist_empty = 0;
-	mutex_lock(&dmx_data->msg_queue_lock);
-	islist_empty = list_empty(&dmx_data->msg_queue);
-	mutex_unlock(&dmx_data->msg_queue_lock);
-
-	return !islist_empty;
-}
-
-static void mpq_get_frame_and_write(struct mpq_dvb_video_inst *dev_inst,
-				unsigned int free_buf)
-{
-	struct mpq_dmx_src_data *dmx_data = dev_inst->dmx_src_data;
-	struct mpq_streambuffer *streambuff = dmx_data->stream_buffer;
-	struct mpq_streambuffer_packet_header pkt_hdr;
-	struct mpq_adapter_video_meta_data meta_data;
-	ssize_t indx = -1;
-	ssize_t bytes_read = 0;
-	size_t pktlen = 0;
-	int frame_found = true;
-	unsigned long kernel_vaddr, phy_addr, user_vaddr;
-	int pmem_fd;
-	struct file *file;
-	s32 buffer_index = -1;
-	size_t size = 0;
-
-	do {
-		wait_event_interruptible(streambuff->packet_data.queue,
-			(!dvb_ringbuffer_empty(&streambuff->packet_data) ||
-			streambuff->packet_data.error != 0) ||
-			kthread_should_stop());
-
-		if (kthread_should_stop()) {
-			DBG("STOP signal Received\n");
-			return;
-		}
-
-		DBG("Received Free Buffer : %d\n", free_buf);
-
-		indx = mpq_streambuffer_pkt_next(streambuff, -1, &pktlen);
-
-		if (-1 == indx) {
-			DBG("Invalid Index -1\n");
-			return;
-		}
-
-		bytes_read = mpq_streambuffer_pkt_read(streambuff, indx,
-			&pkt_hdr, (u8 *)&meta_data);
-
-		switch (meta_data.packet_type) {
-		case DMX_FRAMING_INFO_PACKET:
-			switch (meta_data.info.framing.pattern_type) {
-			case DMX_FRM_H264_SPS:
-			case DMX_FRM_MPEG2_SEQUENCE_HEADER:
-			case DMX_FRM_VC1_SEQUENCE_HEADER:
-				DBG("SPS FOUND\n");
-				frame_found = false;
-				break;
-			case DMX_FRM_H264_PPS:
-			case DMX_FRM_MPEG2_GOP_HEADER:
-			case DMX_FRM_VC1_ENTRY_POINT_HEADER:
-				DBG("PPS FOUND\n");
-				frame_found = false;
-				break;
-			case DMX_FRM_H264_IDR_PIC:
-			case DMX_FRM_H264_NON_IDR_PIC:
-			case DMX_FRM_MPEG2_I_PIC:
-			case DMX_FRM_MPEG2_P_PIC:
-			case DMX_FRM_MPEG2_B_PIC:
-			case DMX_FRM_VC1_FRAME_START_CODE:
-				DBG("FRAME FOUND\n");
-				frame_found = true;
-				break;
-			default:
-				break;
-			}
-			user_vaddr = (unsigned long)
-				dmx_data->in_buffer[free_buf].bufferaddr;
-			vidc_lookup_addr_table(dev_inst->client_ctx,
-				BUFFER_TYPE_INPUT, true, &user_vaddr,
-				&kernel_vaddr,	&phy_addr, &pmem_fd, &file,
-				&buffer_index);
-			bytes_read = 0;
-			bytes_read = mpq_streambuffer_data_read(streambuff,
-						(u8 *)(kernel_vaddr + size),
-						pkt_hdr.raw_data_len);
-			DBG("Data Read : %d from Packet Size : %d\n",
-				bytes_read, pkt_hdr.raw_data_len);
-			mpq_streambuffer_pkt_dispose(streambuff, indx, 0);
-			size +=	pkt_hdr.raw_data_len;
-			dmx_data->in_buffer[free_buf].pts =
-			(meta_data.info.framing.pts_dts_info.pts_exist) ?
-			(meta_data.info.framing.pts_dts_info.pts) : 0;
-			if (frame_found) {
-				dmx_data->in_buffer[free_buf].buffer_len =
-									size;
-				dmx_data->in_buffer[free_buf].client_data =
-							(void *)free_buf;
-				DBG("Size of Data Submitted : %d\n", size);
-				mpq_int_vid_dec_decode_frame(
-						dev_inst->client_ctx,
-						&dmx_data->in_buffer[free_buf]);
-			}
-			break;
-		case DMX_EOS_PACKET:
-			break;
-		case DMX_PES_PACKET:
-		case DMX_PADDING_PACKET:
-			break;
-		}
-	} while (!frame_found);
-
-}
-
-static int mpq_bcast_data_handler(void *arg)
-{
-	struct mpq_dvb_video_inst *dev_inst = arg;
-	struct mpq_dmx_src_data *dmx_data = dev_inst->dmx_src_data;
-	struct mpq_bcast_msg *pMesg;
-	struct mpq_bcast_msg_info msg = {0};
-
-	do {
-		wait_event_interruptible(dmx_data->msg_wait,
-					((dmx_data->stream_buffer != NULL) &&
-					mpq_int_check_bcast_mq(dmx_data)) ||
-					kthread_should_stop());
-
-		if (kthread_should_stop()) {
-			DBG("STOP signal Received\n");
-			break;
-		}
-
-		mutex_lock(&dmx_data->msg_queue_lock);
-		if (!list_empty(&dmx_data->msg_queue)) {
-			pMesg = list_first_entry(&dmx_data->msg_queue,
-					struct mpq_bcast_msg, list);
-			list_del(&pMesg->list);
-			memcpy(&msg, &pMesg->info,
-				sizeof(struct mpq_bcast_msg_info));
-			kfree(pMesg);
-		}
-		mutex_unlock(&dmx_data->msg_queue_lock);
-
-		switch (msg.code) {
-		case MPQ_BCAST_MSG_IBD:
-			DBG("Received IBD Mesg for :%d\n", msg.data);
-			mpq_get_frame_and_write(dev_inst, msg.data);
-			break;
-		default:
-			DBG("Received Mesg : %d\n", msg.code);
-		}
-	} while (1);
-
-	return 0;
-}
-
-static s32 mpq_int_vid_dec_get_empty_client_index(void)
-{
-	u32 i, found = false;
-
-	for (i = 0; i < VIDC_MAX_NUM_CLIENTS; i++) {
-		if (!mpq_dvb_video_device->vdec_clients[i].vcd_handle) {
-			found = true;
-			break;
-		}
-	}
-	if (!found) {
-		ERR("%s():ERROR No space for new client\n", __func__);
-		return -ENOMEM;
-	} else {
-		DBG("%s(): available client index = %u\n", __func__, i);
-		return i;
-	}
-}
-
-static u32 mpq_int_vid_dec_get_status(u32 status)
-{
-	u32 vdec_status;
-
-	switch (status) {
-	case VCD_ERR_SEQHDR_PARSE_FAIL:
-	case VCD_ERR_BITSTREAM_ERR:
-		vdec_status = VIDEO_STATUS_BITSTREAM_ERROR;
-		break;
-	case VCD_S_SUCCESS:
-		vdec_status = VIDEO_STATUS_SUCESS;
-		break;
-	case VCD_ERR_FAIL:
-		vdec_status = VIDEO_STATUS_FAILED;
-		break;
-	case VCD_ERR_ALLOC_FAIL:
-	case VCD_ERR_MAX_CLIENT:
-		vdec_status = VIDEO_STATUS_NORESOURCE;
-		break;
-	case VCD_ERR_ILLEGAL_OP:
-		vdec_status = VIDEO_STATUS_INVALID_CMD;
-		break;
-	case VCD_ERR_ILLEGAL_PARM:
-		vdec_status = VIDEO_STATUS_INVALID_PARAM;
-		break;
-	case VCD_ERR_BAD_POINTER:
-	case VCD_ERR_BAD_HANDLE:
-		vdec_status = VIDEO_STATUS_INVALID_HANDLE;
-		break;
-	case VCD_ERR_NOT_SUPPORTED:
-		vdec_status = VIDEO_STATUS_NO_SUPPORT;
-		break;
-	case VCD_ERR_BAD_STATE:
-		vdec_status = VIDEO_STATUS_INVALID_STATE;
-		break;
-	case VCD_ERR_BUSY:
-		vdec_status = VIDEO_STATUS_BUSY;
-		break;
-	default:
-		vdec_status = VIDEO_STATUS_FAILED;
-		break;
-	}
-
-	return vdec_status;
-}
-
-static void mpq_int_vid_dec_notify_client(struct video_client_ctx *client_ctx)
-{
-	if (client_ctx)
-		complete(&client_ctx->event);
-}
-
-static void mpq_int_vid_dec_vcd_open_done(struct video_client_ctx *client_ctx,
-			   struct vcd_handle_container *handle_container)
-{
-	if (client_ctx) {
-		if (handle_container)
-			client_ctx->vcd_handle = handle_container->handle;
-		else
-			DBG("%s(): ERROR. handle_container is NULL\n",
-			    __func__);
-
-		mpq_int_vid_dec_notify_client(client_ctx);
-	} else
-		DBG("%s(): ERROR. client_ctx is NULL\n", __func__);
-}
-
-static void mpq_int_vid_dec_handle_field_drop(
-	struct video_client_ctx *client_ctx,
-	u32 event, u32 status, int64_t time_stamp)
-{
-	struct vid_dec_msg *vdec_msg;
-
-	if (!client_ctx) {
-		DBG("%s() NULL pointer\n", __func__);
-		return;
-	}
-
-	vdec_msg = kzalloc(sizeof(struct vid_dec_msg), GFP_KERNEL);
-	if (!vdec_msg) {
-		DBG("%s(): cannot allocate vid_dec_msg "\
-			" buffer\n", __func__);
-		return;
-	}
-	vdec_msg->vdec_msg_info.status_code =
-		mpq_int_vid_dec_get_status(status);
-	if (event == VCD_EVT_IND_INFO_FIELD_DROPPED) {
-		vdec_msg->vdec_msg_info.msgcode =
-			VDEC_MSG_EVT_INFO_FIELD_DROPPED;
-		vdec_msg->vdec_msg_info.msgdata.output_frame.time_stamp
-		= time_stamp;
-		DBG("Send FIELD_DROPPED message to client = %p\n",
-						client_ctx);
-	} else {
-		DBG("mpq_int_vid_dec_input_frame_done(): "\
-			"invalid event type: %d\n", event);
-		vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_INVALID;
-	}
-	vdec_msg->vdec_msg_info.msgdatasize =
-		sizeof(struct vdec_output_frameinfo);
-	mutex_lock(&client_ctx->msg_queue_lock);
-	list_add_tail(&vdec_msg->list, &client_ctx->msg_queue);
-	mutex_unlock(&client_ctx->msg_queue_lock);
-	wake_up(&client_ctx->msg_wait);
-}
-
-static void mpq_int_vid_dec_input_frame_done(
-			struct video_client_ctx *client_ctx, u32 event,
-			u32 status, struct vcd_frame_data *vcd_frame_data)
-{
-	struct vid_dec_msg *vdec_msg;
-	struct mpq_bcast_msg *bcast_msg;
-	struct mpq_dvb_video_inst *dev_inst;
-	struct mpq_dmx_src_data *dmx_data;
-	int rc = 0;
-
-	if (!client_ctx || !vcd_frame_data) {
-		DBG("mpq_int_vid_dec_input_frame_done() NULL pointer\n");
-		return;
-	}
-
-	kfree(vcd_frame_data->desc_buf);
-	vcd_frame_data->desc_buf = NULL;
-	vcd_frame_data->desc_size = 0;
-
-	rc = mpq_get_dev_frm_client(client_ctx, &dev_inst);
-	if (rc) {
-		DBG("Failed to obtain device instance\n");
-		return;
-	}
-
-	if (dev_inst->source == VIDEO_SOURCE_MEMORY) {
-		vdec_msg = kzalloc(sizeof(struct vid_dec_msg), GFP_KERNEL);
-		if (!vdec_msg) {
-			DBG("mpq_int_vid_dec_input_frame_done(): "\
-			"cannot allocate vid_dec_msg buffer\n");
-			return;
-		}
-
-		vdec_msg->vdec_msg_info.status_code =
-				mpq_int_vid_dec_get_status(status);
-
-		if (event == VCD_EVT_RESP_INPUT_DONE) {
-			vdec_msg->vdec_msg_info.msgcode =
-			VDEC_MSG_RESP_INPUT_BUFFER_DONE;
-			DBG("Send INPUT_DON message to client = %p\n",
-						client_ctx);
-
-		} else if (event == VCD_EVT_RESP_INPUT_FLUSHED) {
-			vdec_msg->vdec_msg_info.msgcode =
-					VDEC_MSG_RESP_INPUT_FLUSHED;
-			DBG("Send INPUT_FLUSHED message to client = %p\n",
-						client_ctx);
-		} else {
-			DBG("mpq_int_vid_dec_input_frame_done(): "\
-				"invalid event type: %d\n", event);
-			vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_INVALID;
-		}
-
-		vdec_msg->vdec_msg_info.msgdata.input_frame_clientdata =
-			(void *)vcd_frame_data->frm_clnt_data;
-		vdec_msg->vdec_msg_info.msgdatasize = sizeof(void *);
-
-		mutex_lock(&client_ctx->msg_queue_lock);
-		list_add_tail(&vdec_msg->list, &client_ctx->msg_queue);
-		mutex_unlock(&client_ctx->msg_queue_lock);
-		wake_up(&client_ctx->msg_wait);
-	} else {
-		if (event == VCD_EVT_RESP_INPUT_DONE) {
-			bcast_msg = kzalloc(sizeof(struct mpq_bcast_msg),
-						GFP_KERNEL);
-			if (!bcast_msg) {
-				DBG("mpq_int_vid_dec_input_frame_done(): "\
-				"cannot allocate mpq_bcast_msg buffer\n");
-				return;
-			}
-
-			bcast_msg->info.code = MPQ_BCAST_MSG_IBD;
-			bcast_msg->info.data =
-				(unsigned int)vcd_frame_data->frm_clnt_data;
-
-			dmx_data = dev_inst->dmx_src_data;
-
-			mutex_lock(&dmx_data->msg_queue_lock);
-			list_add_tail(&bcast_msg->list, &dmx_data->msg_queue);
-			mutex_unlock(&dmx_data->msg_queue_lock);
-			wake_up(&dmx_data->msg_wait);
-		}
-	}
-}
-
-static void mpq_int_vid_dec_output_frame_done(
-			struct video_client_ctx *client_ctx,
-			u32 event, u32 status,
-			struct vcd_frame_data *vcd_frame_data)
-{
-	struct vid_dec_msg *vdec_msg;
-
-	unsigned long kernel_vaddr = 0, phy_addr = 0, user_vaddr = 0;
-	int pmem_fd;
-	struct file *file;
-	s32 buffer_index = -1;
-	enum vdec_picture pic_type;
-	u32 ion_flag = 0;
-	struct ion_handle *buff_handle = NULL;
-	struct vdec_output_frameinfo  *output_frame;
-
-	if (!client_ctx || !vcd_frame_data) {
-		DBG("mpq_int_vid_dec_input_frame_done() NULL pointer\n");
-		return;
-	}
-
-	vdec_msg = kzalloc(sizeof(struct vid_dec_msg), GFP_KERNEL);
-	if (!vdec_msg) {
-		DBG("mpq_int_vid_dec_input_frame_done(): "\
-		    "cannot allocate vid_dec_msg buffer\n");
-		return;
-	}
-
-	vdec_msg->vdec_msg_info.status_code =
-			mpq_int_vid_dec_get_status(status);
-
-	if (event == VCD_EVT_RESP_OUTPUT_DONE)
-		vdec_msg->vdec_msg_info.msgcode =
-		    VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
-	else if (event == VCD_EVT_RESP_OUTPUT_FLUSHED)
-		vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_OUTPUT_FLUSHED;
-	else {
-		DBG("QVD: mpq_int_vid_dec_output_frame_done"\
-			"invalid cmd type : %d\n", event);
-		vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_INVALID;
-	}
-
-	kernel_vaddr = (unsigned long)vcd_frame_data->virtual;
-
-	if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT,
-				      false, &user_vaddr, &kernel_vaddr,
-				      &phy_addr, &pmem_fd, &file,
-				      &buffer_index) ||
-		(vcd_frame_data->flags & VCD_FRAME_FLAG_EOS)) {
-		/* Buffer address in user space */
-		vdec_msg->vdec_msg_info.msgdata.output_frame.bufferaddr =
-		    (u8 *) user_vaddr;
-		/* Data length */
-		vdec_msg->vdec_msg_info.msgdata.output_frame.len =
-		    vcd_frame_data->data_len;
-		vdec_msg->vdec_msg_info.msgdata.output_frame.flags =
-		    vcd_frame_data->flags;
-		/* Timestamp pass-through from input frame */
-		vdec_msg->vdec_msg_info.msgdata.output_frame.time_stamp =
-		    vcd_frame_data->time_stamp;
-		/* Output frame client data */
-		vdec_msg->vdec_msg_info.msgdata.output_frame.client_data =
-		    (void *)vcd_frame_data->frm_clnt_data;
-		/* Associated input frame client data */
-		vdec_msg->vdec_msg_info.msgdata.output_frame.
-		    input_frame_clientdata =
-		    (void *)vcd_frame_data->ip_frm_tag;
-		/* Decoded picture width and height */
-		vdec_msg->vdec_msg_info.msgdata.output_frame.framesize.
-		bottom =
-		    vcd_frame_data->dec_op_prop.disp_frm.bottom;
-		vdec_msg->vdec_msg_info.msgdata.output_frame.framesize.left =
-		    vcd_frame_data->dec_op_prop.disp_frm.left;
-		vdec_msg->vdec_msg_info.msgdata.output_frame.framesize.right =
-			vcd_frame_data->dec_op_prop.disp_frm.right;
-		vdec_msg->vdec_msg_info.msgdata.output_frame.framesize.top =
-			vcd_frame_data->dec_op_prop.disp_frm.top;
-		if (vcd_frame_data->interlaced) {
-			vdec_msg->vdec_msg_info.msgdata.
-				output_frame.interlaced_format =
-				VDEC_InterlaceInterleaveFrameTopFieldFirst;
-		} else {
-			vdec_msg->vdec_msg_info.msgdata.
-				output_frame.interlaced_format =
-				VDEC_InterlaceFrameProgressive;
-		}
-		/* Decoded picture type */
-		switch (vcd_frame_data->frame) {
-		case VCD_FRAME_I:
-			pic_type = PICTURE_TYPE_I;
-			break;
-		case VCD_FRAME_P:
-			pic_type = PICTURE_TYPE_P;
-			break;
-		case VCD_FRAME_B:
-			pic_type = PICTURE_TYPE_B;
-			break;
-		case VCD_FRAME_NOTCODED:
-			pic_type = PICTURE_TYPE_SKIP;
-			break;
-		case VCD_FRAME_IDR:
-			pic_type = PICTURE_TYPE_IDR;
-			break;
-		default:
-			pic_type = PICTURE_TYPE_UNKNOWN;
-		}
-		vdec_msg->vdec_msg_info.msgdata.output_frame.pic_type =
-			pic_type;
-		output_frame = &vdec_msg->vdec_msg_info.msgdata.output_frame;
-		output_frame->aspect_ratio_info.aspect_ratio =
-			vcd_frame_data->aspect_ratio_info.aspect_ratio;
-		output_frame->aspect_ratio_info.par_width =
-			vcd_frame_data->aspect_ratio_info.par_width;
-		output_frame->aspect_ratio_info.par_height =
-			vcd_frame_data->aspect_ratio_info.par_height;
-		vdec_msg->vdec_msg_info.msgdatasize =
-		    sizeof(struct vdec_output_frameinfo);
-	} else {
-		DBG("mpq_int_vid_dec_output_frame_done UVA"\
-				"can not be found\n");
-		vdec_msg->vdec_msg_info.status_code = VDEC_S_EFATAL;
-	}
-	if (vcd_frame_data->data_len > 0) {
-		ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_OUTPUT,
-				pmem_fd, kernel_vaddr, buffer_index,
-				&buff_handle);
-		if (ion_flag == ION_FLAG_CACHED && buff_handle) {
-			msm_ion_do_cache_op(
-				client_ctx->user_ion_client,
-				buff_handle,
-				(unsigned long *) kernel_vaddr,
-				(unsigned long)vcd_frame_data->data_len,
-				ION_IOC_INV_CACHES);
-		}
-	}
-	mutex_lock(&client_ctx->msg_queue_lock);
-	list_add_tail(&vdec_msg->list, &client_ctx->msg_queue);
-	mutex_unlock(&client_ctx->msg_queue_lock);
-	wake_up(&client_ctx->msg_wait);
-}
-
-static void mpq_int_vid_dec_lean_event(struct video_client_ctx *client_ctx,
-			       u32 event, u32 status)
-{
-	struct vid_dec_msg *vdec_msg;
-
-	if (!client_ctx) {
-		DBG("%s(): !client_ctx pointer\n", __func__);
-		return;
-	}
-
-	vdec_msg = kzalloc(sizeof(struct vid_dec_msg), GFP_KERNEL);
-	if (!vdec_msg) {
-		DBG("%s(): cannot allocate vid_dec_msg buffer\n",
-					__func__);
-		return;
-	}
-
-	vdec_msg->vdec_msg_info.status_code =
-			mpq_int_vid_dec_get_status(status);
-
-	switch (event) {
-	case VCD_EVT_IND_OUTPUT_RECONFIG:
-		DBG("msm_vidc_dec: Sending VDEC_MSG_EVT_CONFIG_CHANGED"\
-			 " to client");
-		vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_EVT_CONFIG_CHANGED;
-		break;
-	case VCD_EVT_IND_RESOURCES_LOST:
-		DBG("msm_vidc_dec: Sending VDEC_EVT_RESOURCES_LOST"\
-			 " to client");
-		vdec_msg->vdec_msg_info.msgcode = VDEC_EVT_RESOURCES_LOST;
-		break;
-	case VCD_EVT_RESP_FLUSH_INPUT_DONE:
-		DBG("msm_vidc_dec: Sending VDEC_MSG_RESP_FLUSH_INPUT_DONE"\
-			 " to client");
-		vdec_msg->vdec_msg_info.msgcode =
-		    VDEC_MSG_RESP_FLUSH_INPUT_DONE;
-		break;
-	case VCD_EVT_RESP_FLUSH_OUTPUT_DONE:
-		DBG("msm_vidc_dec: Sending VDEC_MSG_RESP_FLUSH_OUTPUT_DONE"\
-			 " to client");
-		vdec_msg->vdec_msg_info.msgcode =
-		    VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
-		break;
-	case VCD_EVT_IND_HWERRFATAL:
-		DBG("msm_vidc_dec: Sending VDEC_MSG_EVT_HW_ERROR"\
-			 " to client");
-		vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_EVT_HW_ERROR;
-		break;
-	case VCD_EVT_RESP_START:
-		DBG("msm_vidc_dec: Sending VDEC_MSG_RESP_START_DONE"\
-			 " to client");
-		vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_START_DONE;
-		break;
-	case VCD_EVT_RESP_STOP:
-		DBG("msm_vidc_dec: Sending VDEC_MSG_RESP_STOP_DONE"\
-			 " to client");
-		vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_STOP_DONE;
-		break;
-	case VCD_EVT_RESP_PAUSE:
-		DBG("msm_vidc_dec: Sending VDEC_MSG_RESP_PAUSE_DONE"\
-			 " to client");
-		vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_PAUSE_DONE;
-		break;
-	case VCD_EVT_IND_INFO_OUTPUT_RECONFIG:
-		DBG("msm_vidc_dec: Sending VDEC_MSG_EVT_INFO_CONFIG_CHANGED"\
-			 " to client");
-		vdec_msg->vdec_msg_info.msgcode =
-			 VDEC_MSG_EVT_INFO_CONFIG_CHANGED;
-		break;
-	default:
-		DBG("%s() : unknown event type\n", __func__);
-		break;
-	}
-
-	vdec_msg->vdec_msg_info.msgdatasize = 0;
-	if (client_ctx->stop_sync_cb &&
-	   (event == VCD_EVT_RESP_STOP || event == VCD_EVT_IND_HWERRFATAL)) {
-		client_ctx->stop_sync_cb = false;
-		complete(&client_ctx->event);
-		kfree(vdec_msg);
-		return;
-	}
-	mutex_lock(&client_ctx->msg_queue_lock);
-	list_add_tail(&vdec_msg->list, &client_ctx->msg_queue);
-	mutex_unlock(&client_ctx->msg_queue_lock);
-	wake_up(&client_ctx->msg_wait);
-}
-
-static void mpq_int_state_play(struct video_client_ctx *client_ctx,
-			       u32 event, u32 status)
-{
-	struct mpq_bcast_msg *bcast_msg;
-	struct mpq_dvb_video_inst *dev_inst;
-	int i;
-	int rc = 0;
-	struct mpq_dmx_src_data *dmx_data = NULL;
-
-	if (!client_ctx->seq_header_set) {
-		rc = mpq_get_dev_frm_client(client_ctx, &dev_inst);
-		if (rc) {
-			DBG("Failed to get dev_instance in %s\n", __func__);
-			return;
-		}
-
-		if (VIDEO_SOURCE_DEMUX == dev_inst->source) {
-			dmx_data = dev_inst->dmx_src_data;
-			for (i = 0; i < DVB_VID_NUM_IN_BUFFERS; i++) {
-				bcast_msg = kzalloc(
-						sizeof(struct mpq_bcast_msg),
-						GFP_KERNEL);
-				if (!bcast_msg) {
-					DBG("cannot allocate mpq_bcast_msg"\
-						"buffer\n");
-					return;
-				}
-
-				bcast_msg->info.code = MPQ_BCAST_MSG_IBD;
-				bcast_msg->info.data = (unsigned int)i;
-
-				mutex_lock(&dmx_data->msg_queue_lock);
-				list_add_tail(&bcast_msg->list,
-						&dmx_data->msg_queue);
-				mutex_unlock(&dmx_data->msg_queue_lock);
-				wake_up(&dmx_data->msg_wait);
-			}
-		}
-		mpq_int_vid_dec_lean_event(client_ctx, event, status);
-	} else
-		mpq_int_vid_dec_notify_client(client_ctx);
-
-}
-
-static void mpq_int_vid_dec_vcd_cb(u32 event, u32 status,
-		   void *info, size_t sz, void *handle,
-		   void *const client_data)
-{
-	struct video_client_ctx *client_ctx = client_data;
-
-	DBG("Entering %s()\n", __func__);
-
-	if (!client_ctx) {
-		DBG("%s(): client_ctx is NULL\n", __func__);
-		return;
-	}
-
-	client_ctx->event_status = status;
-
-	switch (event) {
-	case VCD_EVT_RESP_OPEN:
-		mpq_int_vid_dec_vcd_open_done(client_ctx,
-				      (struct vcd_handle_container *)
-				      info);
-		break;
-	case VCD_EVT_RESP_INPUT_DONE:
-	case VCD_EVT_RESP_INPUT_FLUSHED:
-		mpq_int_vid_dec_input_frame_done(client_ctx, event, status,
-					 (struct vcd_frame_data *)info);
-		break;
-	case VCD_EVT_IND_INFO_FIELD_DROPPED:
-		if (info)
-			mpq_int_vid_dec_handle_field_drop(client_ctx, event,
-			status,	*((int64_t *)info));
-		else
-			DBG("Wrong Payload for Field dropped\n");
-		break;
-	case VCD_EVT_RESP_OUTPUT_DONE:
-	case VCD_EVT_RESP_OUTPUT_FLUSHED:
-		mpq_int_vid_dec_output_frame_done(client_ctx, event, status,
-					  (struct vcd_frame_data *)info);
-		break;
-	case VCD_EVT_RESP_PAUSE:
-	case VCD_EVT_RESP_STOP:
-	case VCD_EVT_RESP_FLUSH_INPUT_DONE:
-	case VCD_EVT_RESP_FLUSH_OUTPUT_DONE:
-	case VCD_EVT_IND_OUTPUT_RECONFIG:
-	case VCD_EVT_IND_HWERRFATAL:
-	case VCD_EVT_IND_RESOURCES_LOST:
-	case VCD_EVT_IND_INFO_OUTPUT_RECONFIG:
-		mpq_int_vid_dec_lean_event(client_ctx, event, status);
-		break;
-	case VCD_EVT_RESP_START:
-		mpq_int_state_play(client_ctx, event, status);
-		break;
-	default:
-		DBG("%s() :  Error - Invalid event type =%u\n", __func__,
-		    event);
-		break;
-	}
-}
-
-static int mpq_int_vid_dec_set_cont_on_reconfig(
-			struct video_client_ctx *client_ctx)
-{
-	struct vcd_property_hdr vcd_property_hdr;
-	u32 vcd_status = VCD_ERR_FAIL;
-	u32 enable = true;
-	if (!client_ctx)
-		return -EINVAL;
-	vcd_property_hdr.prop_id = VCD_I_CONT_ON_RECONFIG;
-	vcd_property_hdr.sz = sizeof(u32);
-	vcd_status = vcd_set_property(client_ctx->vcd_handle,
-		&vcd_property_hdr, &enable);
-	if (vcd_status)
-		return -EIO;
-	return 0;
-}
-
-static int mpq_int_vid_dec_set_frame_resolution(
-				struct video_client_ctx *client_ctx,
-				struct vdec_picsize *video_resoultion)
-{
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_frame_size frame_resolution;
-	u32 vcd_status = VCD_ERR_FAIL;
-
-	if (!client_ctx || !video_resoultion)
-		return -EINVAL;
-
-	vcd_property_hdr.prop_id = VCD_I_FRAME_SIZE;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_frame_size);
-	frame_resolution.width = video_resoultion->frame_width;
-	frame_resolution.height = video_resoultion->frame_height;
-	frame_resolution.stride = video_resoultion->stride;
-	frame_resolution.scan_lines = video_resoultion->scan_lines;
-
-	vcd_status = vcd_set_property(client_ctx->vcd_handle,
-				      &vcd_property_hdr, &frame_resolution);
-
-	if (vcd_status)
-		return -EIO;
-	else
-		return 0;
-}
-
-static int mpq_int_set_out_buffer_req(struct video_client_ctx *client_ctx,
-					struct video_buffer_req *vdec_buf_req)
-{
-	struct vcd_buffer_requirement buffer_req;
-	u32 vcd_status = VCD_ERR_FAIL;
-
-	buffer_req.actual_count = vdec_buf_req->num_output_buffers;
-	buffer_req.align = vdec_buf_req->output_buf_prop.alignment;
-	buffer_req.max_count = vdec_buf_req->num_output_buffers;
-	buffer_req.min_count = vdec_buf_req->num_output_buffers;
-	buffer_req.sz = vdec_buf_req->output_buf_prop.buf_size;
-
-	vcd_status = vcd_set_buffer_requirements(client_ctx->vcd_handle,
-			VCD_BUFFER_OUTPUT, &buffer_req);
-	if (vcd_status)
-		return -EFAULT;
-	else
-		return 0;
-}
-
-static int mpq_int_set_full_hd_frame_resolution(
-				struct video_client_ctx *client_ctx)
-{
-	struct vdec_picsize pic_res;
-	int rc;
-
-	pic_res.frame_height = 1080;
-	pic_res.frame_width  = 1920;
-	pic_res.scan_lines   = 1080;
-	pic_res.stride       = 1920;
-
-	rc = mpq_int_vid_dec_set_frame_resolution(client_ctx,
-						&pic_res);
-	if (rc)
-		DBG("Failed in mpq_int_vid_dec_set_frame_resolution : %d\n",\
-			rc);
-
-	rc = mpq_int_vid_dec_set_cont_on_reconfig(client_ctx);
-	if (rc)
-		DBG("Failed in mpq_int_vid_dec_set_cont_on_reconfig : %d\n",\
-			rc);
-
-	return rc;
-
-}
-
-static int mpq_int_vid_dec_get_frame_resolution(
-			struct video_client_ctx *client_ctx,
-			struct video_pic_res *video_resoultion)
-{
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_frame_size frame_resolution;
-	u32 vcd_status = VCD_ERR_FAIL;
-
-	if (!client_ctx || !video_resoultion)
-		return -EINVAL;
-
-	vcd_property_hdr.prop_id = VCD_I_FRAME_SIZE;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_frame_size);
-
-	vcd_status = vcd_get_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &frame_resolution);
-
-	video_resoultion->width  = frame_resolution.width;
-	video_resoultion->height = frame_resolution.height;
-	video_resoultion->scan_lines = frame_resolution.scan_lines;
-	video_resoultion->stride = frame_resolution.stride;
-
-	if (vcd_status)
-		return -EINVAL;
-	else
-		return 0;
-}
-
-static int mpq_int_vid_dec_get_codec(struct video_client_ctx *client_ctx,
-					enum video_codec_t *video_codec)
-{
-	unsigned int result = 0;
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_codec codec;
-
-	if ((client_ctx == NULL) || (video_codec == NULL))
-		return -EINVAL;
-
-	vcd_property_hdr.prop_id = VCD_I_CODEC;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
-
-	result = vcd_get_property(client_ctx->vcd_handle,
-					&vcd_property_hdr, &codec);
-	if (result)
-		return -EINVAL;
-
-	switch (codec.codec) {
-	case VCD_CODEC_MPEG4:
-		*video_codec = VIDEO_CODECTYPE_MPEG4;
-		break;
-	case VCD_CODEC_H264:
-		*video_codec = VIDEO_CODECTYPE_H264;
-		break;
-	case VCD_CODEC_MPEG2:
-		*video_codec = VIDEO_CODECTYPE_MPEG2;
-		break;
-	case VCD_CODEC_VC1:
-		*video_codec = VIDEO_CODECTYPE_VC1;
-		break;
-	default:
-		*video_codec = VIDEO_CODECTYPE_NONE;
-		break;
-	}
-
-	return result;
-}
-
-static int mpq_int_vid_dec_set_codec(struct video_client_ctx *client_ctx,
-				enum video_codec_t video_codec)
-{
-	unsigned int result = 0;
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_codec codec;
-	unsigned int vcd_status = VCD_ERR_FAIL;
-
-	if (client_ctx == NULL)
-		return -EINVAL;
-
-	vcd_property_hdr.prop_id = VCD_I_CODEC;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
-
-	switch (video_codec) {
-	case VIDEO_CODECTYPE_MPEG4:
-		codec.codec = VCD_CODEC_MPEG4;
-		break;
-	case VIDEO_CODECTYPE_H264:
-		codec.codec = VCD_CODEC_H264;
-		break;
-	case VIDEO_CODECTYPE_MPEG2:
-		codec.codec = VCD_CODEC_MPEG2;
-		break;
-	case VIDEO_CODECTYPE_VC1:
-		codec.codec = VCD_CODEC_VC1;
-		break;
-	default:
-		result = -EINVAL;
-		break;
-	}
-
-	if (!result) {
-		vcd_status = vcd_set_property(client_ctx->vcd_handle,
-					      &vcd_property_hdr, &codec);
-		if (vcd_status)
-			result = -EINVAL;
-	}
-
-	result = mpq_int_set_full_hd_frame_resolution(client_ctx);
-
-	return result;
-}
-
-static int mpq_int_vid_dec_set_output_format(
-		struct video_client_ctx *client_ctx,
-		enum video_out_format_t format)
-{
-	unsigned int result = 0;
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_buffer_format vcd_prop_buffer_format;
-	unsigned int vcd_status = VCD_ERR_FAIL;
-
-	if (client_ctx == NULL)
-		return -EINVAL;
-
-	vcd_property_hdr.prop_id = VCD_I_BUFFER_FORMAT;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_format);
-
-	switch (format) {
-	case VIDEO_YUV_FORMAT_NV12:
-		vcd_prop_buffer_format.buffer_format = VCD_BUFFER_FORMAT_NV12;
-		break;
-	case VIDEO_YUV_FORMAT_TILE_4x2:
-		vcd_prop_buffer_format.buffer_format =
-					VCD_BUFFER_FORMAT_TILE_4x2;
-		break;
-	default:
-		result = -EINVAL;
-		break;
-	}
-
-	if (!result)
-		vcd_status = vcd_set_property(client_ctx->vcd_handle,
-					      &vcd_property_hdr,
-					      &vcd_prop_buffer_format);
-
-	if (vcd_status)
-		return -EINVAL;
-
-	return 0;
-
-}
-
-static int mpq_int_vid_dec_get_output_format(
-			struct video_client_ctx *client_ctx,
-			enum video_out_format_t *format)
-{
-	unsigned int result = 0;
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_buffer_format vcd_prop_buffer_format;
-
-	if ((client_ctx == NULL) || (format == NULL))
-		return -EINVAL;
-
-	vcd_property_hdr.prop_id = VCD_I_BUFFER_FORMAT;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_format);
-
-	result = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
-					&vcd_prop_buffer_format);
-
-	if (result)
-		return -EINVAL;
-
-	switch (vcd_prop_buffer_format.buffer_format) {
-	case VCD_BUFFER_FORMAT_NV12:
-		*format = VIDEO_YUV_FORMAT_NV12;
-		break;
-	case VCD_BUFFER_FORMAT_TILE_4x2:
-		*format = VIDEO_YUV_FORMAT_TILE_4x2;
-		break;
-	default:
-		result = -EINVAL;
-		break;
-	}
-
-	return result;
-}
-
-static int mpq_int_vid_dec_set_h264_mv_buffers(
-				struct video_client_ctx *client_ctx,
-				struct video_h264_mv *mv_data)
-{
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_h264_mv_buffer *vcd_h264_mv_buffer = NULL;
-	struct msm_mapped_buffer *mapped_buffer = NULL;
-	u32 vcd_status = VCD_ERR_FAIL;
-	u32 len = 0, flags = 0;
-	struct file *file;
-	int rc = 0;
-	unsigned long ionflag = 0;
-	unsigned long buffer_size = 0;
-	unsigned long iova = 0;
-
-	if (!client_ctx || !mv_data)
-		return -EINVAL;
-
-	vcd_property_hdr.prop_id = VCD_I_H264_MV_BUFFER;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_h264_mv_buffer);
-	vcd_h264_mv_buffer = &client_ctx->vcd_h264_mv_buffer;
-
-	memset(&client_ctx->vcd_h264_mv_buffer, 0,
-		   sizeof(struct vcd_property_h264_mv_buffer));
-	vcd_h264_mv_buffer->size = mv_data->size;
-	vcd_h264_mv_buffer->count = mv_data->count;
-	vcd_h264_mv_buffer->pmem_fd = mv_data->ion_fd;
-	vcd_h264_mv_buffer->offset = mv_data->offset;
-
-	if (!vcd_get_ion_status()) {
-		if (get_pmem_file(vcd_h264_mv_buffer->pmem_fd,
-			(unsigned long *) (&(vcd_h264_mv_buffer->
-			physical_addr)),
-			(unsigned long *) (&vcd_h264_mv_buffer->
-						kernel_virtual_addr),
-			(unsigned long *) (&len), &file)) {
-			ERR("%s(): get_pmem_file failed\n", __func__);
-			return -EIO;
-		}
-		put_pmem_file(file);
-		flags = MSM_SUBSYSTEM_MAP_IOVA;
-		mapped_buffer = msm_subsystem_map_buffer(
-			(unsigned long)vcd_h264_mv_buffer->physical_addr, len,
-				flags, vidc_mmu_subsystem,
-				sizeof(vidc_mmu_subsystem)/
-				sizeof(unsigned int));
-		if (IS_ERR(mapped_buffer)) {
-			ERR("buffer map failed");
-			return PTR_ERR(mapped_buffer);
-		}
-		vcd_h264_mv_buffer->client_data = (void *) mapped_buffer;
-		vcd_h264_mv_buffer->dev_addr = (u8 *)mapped_buffer->iova[0];
-	} else {
-		client_ctx->h264_mv_ion_handle = ion_import_dma_buf(
-					client_ctx->user_ion_client,
-					vcd_h264_mv_buffer->pmem_fd);
-		if (IS_ERR_OR_NULL(client_ctx->h264_mv_ion_handle)) {
-			DBG("%s(): get_ION_handle failed\n", __func__);
-			goto import_ion_error;
-		}
-		rc = ion_handle_get_flags(client_ctx->user_ion_client,
-					client_ctx->h264_mv_ion_handle,
-					&ionflag);
-		if (rc) {
-			DBG("%s():get_ION_flags fail\n",
-					 __func__);
-			goto import_ion_error;
-		}
-		vcd_h264_mv_buffer->kernel_virtual_addr =
-			(u8 *) ion_map_kernel(client_ctx->user_ion_client,
-					client_ctx->h264_mv_ion_handle);
-		if (!vcd_h264_mv_buffer->kernel_virtual_addr) {
-			DBG("%s(): get_ION_kernel virtual addr failed\n",
-				 __func__);
-			goto import_ion_error;
-		}
-
-		rc = ion_map_iommu(client_ctx->user_ion_client,
-				client_ctx->h264_mv_ion_handle,
-				VIDEO_DOMAIN, VIDEO_MAIN_POOL,
-				SZ_4K, 0, (unsigned long *)&iova,
-				(unsigned long *)&buffer_size,
-				0, 0);
-		if (rc) {
-			DBG("%s():get_ION_kernel physical addr fail\n",
-						 __func__);
-			goto ion_map_error;
-		}
-		vcd_h264_mv_buffer->physical_addr = (u8 *) iova;
-		vcd_h264_mv_buffer->client_data = NULL;
-		vcd_h264_mv_buffer->dev_addr = (u8 *) iova;
-
-	}
-	DBG("Virt: %p, Phys %p, fd: %d", vcd_h264_mv_buffer->
-		kernel_virtual_addr, vcd_h264_mv_buffer->physical_addr,
-		vcd_h264_mv_buffer->pmem_fd);
-	DBG("Dev addr %p", vcd_h264_mv_buffer->dev_addr);
-	vcd_status = vcd_set_property(client_ctx->vcd_handle,
-				      &vcd_property_hdr, vcd_h264_mv_buffer);
-
-	if (vcd_status)
-		return -EIO;
-	else
-		return 0;
-ion_map_error:
-	if (vcd_h264_mv_buffer->kernel_virtual_addr) {
-		ion_unmap_kernel(client_ctx->user_ion_client,
-				client_ctx->h264_mv_ion_handle);
-		vcd_h264_mv_buffer->kernel_virtual_addr = NULL;
-	}
-	if (!IS_ERR_OR_NULL(client_ctx->h264_mv_ion_handle)) {
-		ion_free(client_ctx->user_ion_client,
-			client_ctx->h264_mv_ion_handle);
-		 client_ctx->h264_mv_ion_handle = NULL;
-	}
-import_ion_error:
-	return -EIO;
-}
-
-static int mpq_int_vid_dec_get_h264_mv_buffer_size(
-				struct video_client_ctx *client_ctx,
-				struct video_mv_buff_size *mv_buff)
-{
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_buffer_size h264_mv_buffer_size;
-	u32 vcd_status = VCD_ERR_FAIL;
-
-	if (!client_ctx || !mv_buff)
-		return -EINVAL;
-
-	vcd_property_hdr.prop_id = VCD_I_GET_H264_MV_SIZE;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size);
-
-	h264_mv_buffer_size.width = mv_buff->width;
-	h264_mv_buffer_size.height = mv_buff->height;
-
-	vcd_status = vcd_get_property(client_ctx->vcd_handle,
-				      &vcd_property_hdr, &h264_mv_buffer_size);
-
-	mv_buff->width = h264_mv_buffer_size.width;
-	mv_buff->height = h264_mv_buffer_size.height;
-	mv_buff->size = h264_mv_buffer_size.size;
-	mv_buff->alignment = h264_mv_buffer_size.alignment;
-
-	if (vcd_status)
-		return -EIO;
-	else
-		return 0;
-}
-
-static int mpq_int_vid_dec_free_h264_mv_buffers(
-				struct video_client_ctx *client_ctx)
-{
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_buffer_size h264_mv_buffer_size;
-	u32 vcd_status = VCD_ERR_FAIL;
-
-	if (!client_ctx)
-		return -EINVAL;
-	if (client_ctx->vcd_h264_mv_buffer.client_data)
-		msm_subsystem_unmap_buffer((struct msm_mapped_buffer *)
-		client_ctx->vcd_h264_mv_buffer.client_data);
-
-	vcd_property_hdr.prop_id = VCD_I_FREE_H264_MV_BUFFER;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size);
-
-	vcd_status = vcd_set_property(client_ctx->vcd_handle,
-				      &vcd_property_hdr, &h264_mv_buffer_size);
-
-	if (!IS_ERR_OR_NULL(client_ctx->h264_mv_ion_handle)) {
-		ion_unmap_kernel(client_ctx->user_ion_client,
-					client_ctx->h264_mv_ion_handle);
-		ion_unmap_iommu(client_ctx->user_ion_client,
-				client_ctx->h264_mv_ion_handle,
-				VIDEO_DOMAIN,
-				VIDEO_MAIN_POOL);
-		ion_free(client_ctx->user_ion_client,
-					client_ctx->h264_mv_ion_handle);
-		 client_ctx->h264_mv_ion_handle = NULL;
-	}
-
-	if (vcd_status)
-		return -EIO;
-	else
-		return 0;
-}
-
-
-static int mpq_int_vid_dec_get_buffer_req(struct video_client_ctx *client_ctx,
-				  struct video_buffer_req *vdec_buf_req)
-{
-	u32 vcd_status = VCD_ERR_FAIL;
-	struct vcd_buffer_requirement vcd_buf_req;
-
-	if (!client_ctx || !vdec_buf_req)
-		return -EINVAL;
-
-	vcd_status = vcd_get_buffer_requirements(client_ctx->vcd_handle,
-					VCD_BUFFER_INPUT, &vcd_buf_req);
-
-	if (vcd_status)
-		return -EINVAL;
-
-	vdec_buf_req->input_buf_prop.alignment  = vcd_buf_req.align;
-	vdec_buf_req->input_buf_prop.buf_poolid = vcd_buf_req.buf_pool_id;
-	vdec_buf_req->input_buf_prop.buf_size   = vcd_buf_req.sz;
-	vdec_buf_req->num_input_buffers         = vcd_buf_req.actual_count;
-
-	vcd_status = vcd_get_buffer_requirements(client_ctx->vcd_handle,
-					VCD_BUFFER_OUTPUT, &vcd_buf_req);
-
-	if (vcd_status)
-		return -EINVAL;
-
-	vdec_buf_req->output_buf_prop.alignment  = vcd_buf_req.align;
-	vdec_buf_req->output_buf_prop.buf_poolid = vcd_buf_req.buf_pool_id;
-	vdec_buf_req->output_buf_prop.buf_size   = vcd_buf_req.sz;
-	vdec_buf_req->num_output_buffers         = vcd_buf_req.actual_count;
-
-	return 0;
-}
-
-static int mpq_int_vid_dec_set_buffer_req(struct video_client_ctx *client_ctx,
-				  struct video_buffer_req vdec_buf_req)
-{
-	int rc = 0;
-	struct video_buffer_req vdec_req;
-
-	rc = mpq_int_vid_dec_get_buffer_req(client_ctx, &vdec_req);
-	if (rc)
-		DBG("Failed in mpq_int_vid_dec_get_buffer_req : %d\n", rc);
-
-	vdec_req.num_output_buffers = vdec_buf_req.num_output_buffers;
-	DBG(" num_output_buffers Set to %u\n", vdec_buf_req.num_output_buffers);
-	if (!vdec_buf_req.num_output_buffers)
-		return -EINVAL;
-	rc = mpq_int_set_out_buffer_req(client_ctx, &vdec_req);
-	if (rc)
-		DBG("Failed in mpq_int_set_out_buffer_req  %d\n", rc);
-
-	return 0;
-}
-
-static int mpq_int_vid_dec_set_buffer(struct mpq_dvb_video_inst *dev_inst,
-			      struct video_data_buffer *data_buffer,
-			      enum buffer_dir dir_buffer)
-{
-	struct video_client_ctx *client_ctx =
-		(struct video_client_ctx *)dev_inst->client_ctx;
-	enum vcd_buffer_type buffer = VCD_BUFFER_INPUT;
-	u32 vcd_status = VCD_ERR_FAIL;
-	unsigned long kernel_vaddr, buf_adr_offset = 0, length;
-	int buffer_num = 0;
-
-	if (!client_ctx || !data_buffer)
-		return -EINVAL;
-
-	if (dir_buffer == BUFFER_TYPE_OUTPUT) {
-		buffer = VCD_BUFFER_OUTPUT;
-		buf_adr_offset = (unsigned long)data_buffer->offset;
-	}
-	length = data_buffer->buffer_len;
-	/*If buffer cannot be set, ignore */
-	if (!vidc_insert_addr_table(client_ctx, dir_buffer,
-		(unsigned long)data_buffer->bufferaddr,
-		&kernel_vaddr, data_buffer->ion_fd,
-		buf_adr_offset, MAX_VIDEO_NUM_OF_BUFF, length)) {
-		ERR("%s() : user_virt_addr = %p cannot be set.",
-		    __func__, data_buffer->bufferaddr);
-		return -EINVAL;
-	}
-
-	vcd_status = vcd_set_buffer(client_ctx->vcd_handle,
-		buffer, (u8 *) kernel_vaddr, data_buffer->buffer_len);
-
-	if (!vcd_status) {
-		mutex_lock(&client_ctx->enrty_queue_lock);
-		if ((VIDEO_SOURCE_DEMUX == dev_inst->source) &&
-			(BUFFER_TYPE_INPUT == dir_buffer)) {
-			buffer_num = client_ctx->num_of_input_buffers - 1;
-			memcpy(&dev_inst->dmx_src_data->in_buffer[buffer_num],
-				data_buffer,
-				sizeof(struct video_data_buffer));
-		}
-		mutex_unlock(&client_ctx->enrty_queue_lock);
-		return 0;
-	} else
-		return -EINVAL;
-}
-
-static int mpq_int_vid_dec_free_buffer(struct video_client_ctx *client_ctx,
-				struct video_data_buffer *data_buffer,
-				enum buffer_dir dir_buffer)
-
-{
-	enum vcd_buffer_type buffer = VCD_BUFFER_INPUT;
-	u32 vcd_status = VCD_ERR_FAIL;
-	unsigned long kernel_vaddr;
-
-	if (!client_ctx || !data_buffer)
-		return -EINVAL;
-
-	if (dir_buffer == BUFFER_TYPE_OUTPUT)
-		buffer = VCD_BUFFER_OUTPUT;
-
-	/*If buffer NOT set, ignore */
-	if (!vidc_delete_addr_table(client_ctx, dir_buffer,
-				(unsigned long)data_buffer->bufferaddr,
-				&kernel_vaddr)) {
-		DBG("%s() : user_virt_addr = %p has not been set.",
-		    __func__, data_buffer->bufferaddr);
-		return 0;
-	}
-	vcd_status = vcd_free_buffer(client_ctx->vcd_handle, buffer,
-					 (u8 *)kernel_vaddr);
-
-	if (vcd_status)
-		return -EIO;
-	else
-		return 0;
-}
-
-static int mpq_int_vid_dec_pause_resume(struct video_client_ctx *client_ctx,
-					u32 pause)
-{
-	u32 vcd_status;
-
-	if (!client_ctx) {
-		DBG("%s(): Invalid client_ctx\n", __func__);
-		return -EINVAL;
-	}
-
-	if (pause) {
-		DBG("msm_vidc_dec: PAUSE command from client = %p\n",
-			 client_ctx);
-		vcd_status = vcd_pause(client_ctx->vcd_handle);
-	} else {
-		DBG("msm_vidc_dec: RESUME command from client = %p\n",
-			 client_ctx);
-		vcd_status = vcd_resume(client_ctx->vcd_handle);
-	}
-
-	if (vcd_status)
-		return -EIO;
-	else
-		return 0;
-}
-
-static int mpq_int_vid_dec_start_stop(struct video_client_ctx *client_ctx,
-					u32 start)
-{
-	struct vid_dec_msg *vdec_msg = NULL;
-	u32 vcd_status;
-
-	DBG("Inside %s()", __func__);
-	if (!client_ctx) {
-		DBG("Invalid client_ctx\n");
-		return -EINVAL;
-	}
-
-	if (start) {
-		if (client_ctx->seq_header_set) {
-			DBG("%s(): Seq Hdr set: Send START_DONE to client",
-				 __func__);
-			vdec_msg = kzalloc(sizeof(*vdec_msg), GFP_KERNEL);
-			if (!vdec_msg) {
-				DBG("mpq_int_vid_dec_start_stop:"\
-				    " cannot allocate buffer\n");
-				return -ENOMEM;
-			}
-			vdec_msg->vdec_msg_info.msgcode =
-			    VDEC_MSG_RESP_START_DONE;
-			vdec_msg->vdec_msg_info.status_code = VDEC_S_SUCCESS;
-			vdec_msg->vdec_msg_info.msgdatasize = 0;
-			mutex_lock(&client_ctx->msg_queue_lock);
-			list_add_tail(&vdec_msg->list, &client_ctx->msg_queue);
-			mutex_unlock(&client_ctx->msg_queue_lock);
-
-			wake_up(&client_ctx->msg_wait);
-
-			DBG("Send START_DONE message to client = %p\n",
-			    client_ctx);
-
-		} else {
-			DBG("%s(): Calling decode_start()", __func__);
-			vcd_status =
-			    vcd_decode_start(client_ctx->vcd_handle, NULL);
-
-			if (vcd_status) {
-				DBG("%s(): vcd_decode_start failed."\
-				    " vcd_status = %u\n", __func__,
-				    vcd_status);
-				return -EIO;
-			}
-		}
-	} else {
-		DBG("%s(): Calling vcd_stop()", __func__);
-		mutex_lock(&mpq_dvb_video_device->lock);
-		vcd_status = VCD_ERR_FAIL;
-		if (!client_ctx->stop_called) {
-			client_ctx->stop_called = true;
-			vcd_status = vcd_stop(client_ctx->vcd_handle);
-		}
-		if (vcd_status) {
-			DBG("%s(): vcd_stop failed.  vcd_status = %u\n",
-				__func__, vcd_status);
-			mutex_unlock(&mpq_dvb_video_device->lock);
-			return -EIO;
-		}
-		DBG("Send STOP_DONE message to client = %p\n", client_ctx);
-		mutex_unlock(&mpq_dvb_video_device->lock);
-	}
-	return 0;
-}
-
-static int mpq_int_vid_dec_decode_frame(struct video_client_ctx *client_ctx,
-				struct video_data_buffer *input_frame)
-{
-	struct vcd_frame_data vcd_input_buffer;
-	unsigned long kernel_vaddr, phy_addr, user_vaddr;
-	int pmem_fd;
-	struct file *file;
-	s32 buffer_index = -1;
-	u32 vcd_status = VCD_ERR_FAIL;
-	u32 ion_flag = 0;
-	struct ion_handle *buff_handle = NULL;
-
-	if (!client_ctx || !input_frame)
-		return -EINVAL;
-
-	user_vaddr = (unsigned long)input_frame->bufferaddr;
-
-	if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_INPUT,
-				      true, &user_vaddr, &kernel_vaddr,
-				      &phy_addr, &pmem_fd, &file,
-				      &buffer_index)) {
-
-		/* kernel_vaddr  is found. send the frame to VCD */
-		memset((void *)&vcd_input_buffer, 0,
-		       sizeof(struct vcd_frame_data));
-		vcd_input_buffer.virtual =
-		    (u8 *) (kernel_vaddr + input_frame->offset);
-		vcd_input_buffer.offset = 0;
-		vcd_input_buffer.frm_clnt_data =
-		    (u32) input_frame->client_data;
-		vcd_input_buffer.ip_frm_tag =
-		    (u32) input_frame->client_data;
-		vcd_input_buffer.data_len = input_frame->buffer_len;
-		vcd_input_buffer.time_stamp = input_frame->pts;
-		/* Rely on VCD using the same flags as OMX */
-		vcd_input_buffer.flags = 0;
-		vcd_input_buffer.desc_buf = NULL;
-		vcd_input_buffer.desc_size = 0;
-		if (vcd_input_buffer.data_len > 0) {
-			ion_flag = vidc_get_fd_info(client_ctx,
-						BUFFER_TYPE_INPUT,
-						pmem_fd,
-						kernel_vaddr,
-						buffer_index,
-						&buff_handle);
-			if (ion_flag == ION_FLAG_CACHED && buff_handle) {
-				msm_ion_do_cache_op(
-				client_ctx->user_ion_client,
-				buff_handle,
-				(unsigned long *)kernel_vaddr,
-				(unsigned long) vcd_input_buffer.data_len,
-				ION_IOC_CLEAN_CACHES);
-			}
-		}
-		vcd_status = vcd_decode_frame(client_ctx->vcd_handle,
-					      &vcd_input_buffer);
-		if (!vcd_status)
-			return 0;
-		else {
-			DBG("%s(): vcd_decode_frame failed = %u\n", __func__,
-			    vcd_status);
-			return -EIO;
-		}
-
-	} else {
-		DBG("%s(): kernel_vaddr not found\n", __func__);
-		return -EIO;
-	}
-}
-
-static int mpq_int_vid_dec_fill_output_buffer(
-		struct video_client_ctx *client_ctx,
-		struct video_data_buffer *fill_buffer)
-{
-	unsigned long kernel_vaddr, phy_addr, user_vaddr;
-	int pmem_fd;
-	struct file *file;
-	s32 buffer_index = -1;
-	u32 vcd_status = VCD_ERR_FAIL;
-	struct ion_handle *buff_handle = NULL;
-
-	struct vcd_frame_data vcd_frame;
-
-	if (!client_ctx || !fill_buffer)
-		return -EINVAL;
-
-	user_vaddr = (unsigned long)fill_buffer->bufferaddr;
-
-	if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT,
-				      true, &user_vaddr, &kernel_vaddr,
-				      &phy_addr, &pmem_fd, &file,
-				      &buffer_index)) {
-
-		memset((void *)&vcd_frame, 0,
-		       sizeof(struct vcd_frame_data));
-		vcd_frame.virtual = (u8 *) kernel_vaddr;
-		vcd_frame.frm_clnt_data = (u32) fill_buffer->client_data;
-		vcd_frame.alloc_len = fill_buffer->buffer_len;
-		vcd_frame.ion_flag = vidc_get_fd_info(client_ctx,
-						 BUFFER_TYPE_OUTPUT,
-						pmem_fd, kernel_vaddr,
-						buffer_index,
-						&buff_handle);
-		vcd_frame.buff_ion_handle = buff_handle;
-		vcd_status = vcd_fill_output_buffer(client_ctx->vcd_handle,
-						    &vcd_frame);
-		if (!vcd_status)
-			return 0;
-		else {
-			DBG("%s(): vcd_fill_output_buffer failed = %u\n",
-			    __func__, vcd_status);
-			return -EINVAL;
-		}
-	} else {
-		DBG("%s(): kernel_vaddr not found\n", __func__);
-		return -EIO;
-	}
-}
-
-
-static int mpq_int_vid_dec_flush(struct video_client_ctx *client_ctx,
-			 enum vdec_bufferflush flush_dir)
-{
-	u32 vcd_status = VCD_ERR_FAIL;
-
-	DBG("msm_vidc_dec: %s() called with dir = %u", __func__,
-		 flush_dir);
-	if (!client_ctx) {
-		DBG("Invalid client_ctx\n");
-		return -EINVAL;
-	}
-
-	switch (flush_dir) {
-	case VDEC_FLUSH_TYPE_INPUT:
-		vcd_status = vcd_flush(client_ctx->vcd_handle,
-					VCD_FLUSH_INPUT);
-		break;
-	case VDEC_FLUSH_TYPE_OUTPUT:
-		vcd_status = vcd_flush(client_ctx->vcd_handle,
-				       VCD_FLUSH_OUTPUT);
-		break;
-	case VDEC_FLUSH_TYPE_ALL:
-		vcd_status = vcd_flush(client_ctx->vcd_handle, VCD_FLUSH_ALL);
-		break;
-	default:
-		ERR("%s(): Inavlid flush cmd. flush_dir = %u\n", __func__,
-		    flush_dir);
-		return -EINVAL;
-		break;
-	}
-
-	if (!vcd_status)
-		return 0;
-	else {
-		DBG("%s(): vcd_flush failed. vcd_status = %u "\
-		    " flush_dir = %u\n", __func__, vcd_status, flush_dir);
-		return -EIO;
-	}
-}
-
-static u32 mpq_int_vid_dec_msg_pending(struct video_client_ctx *client_ctx)
-{
-	u32 islist_empty = 0;
-	mutex_lock(&client_ctx->msg_queue_lock);
-	islist_empty = list_empty(&client_ctx->msg_queue);
-	mutex_unlock(&client_ctx->msg_queue_lock);
-
-	if (islist_empty) {
-		DBG("%s(): vid_dec msg queue empty\n", __func__);
-		if (client_ctx->stop_msg) {
-			DBG("%s(): List empty and Stop Msg set\n",
-				__func__);
-			return client_ctx->stop_msg;
-		}
-	} else {
-		DBG("%s(): vid_dec msg queue Not empty\n", __func__);
-	}
-
-	return !islist_empty;
-}
-
-static int mpq_int_vid_dec_get_next_msg(struct video_client_ctx *client_ctx,
-				struct vdec_msginfo *vdec_msg_info)
-{
-	struct vid_dec_msg *vid_dec_msg = NULL;
-
-	if (!client_ctx)
-		return -EINVAL;
-
-	mutex_lock(&client_ctx->msg_queue_lock);
-	if (!list_empty(&client_ctx->msg_queue)) {
-		DBG("%s(): After Wait\n", __func__);
-		vid_dec_msg = list_first_entry(&client_ctx->msg_queue,
-					       struct vid_dec_msg, list);
-		list_del(&vid_dec_msg->list);
-		memcpy(vdec_msg_info, &vid_dec_msg->vdec_msg_info,
-		       sizeof(struct vdec_msginfo));
-		kfree(vid_dec_msg);
-	}
-	mutex_unlock(&client_ctx->msg_queue_lock);
-	return 0;
-}
-
-static u32 mpq_int_vid_dec_close_client(struct video_client_ctx *client_ctx)
-{
-	struct vid_dec_msg *vdec_msg;
-	u32 vcd_status;
-
-	DBG("msm_vidc_dec: Inside %s()", __func__);
-	if (!client_ctx || (!client_ctx->vcd_handle)) {
-		DBG("Invalid client_ctx\n");
-		return false;
-	}
-
-	mutex_lock(&mpq_dvb_video_device->lock);
-	if (!client_ctx->stop_called) {
-		client_ctx->stop_called = true;
-		client_ctx->stop_sync_cb = true;
-		vcd_status = vcd_stop(client_ctx->vcd_handle);
-		DBG("Stuck at the stop call\n");
-		if (!vcd_status)
-			wait_for_completion(&client_ctx->event);
-		DBG("Came out of wait event\n");
-	}
-	mutex_lock(&client_ctx->msg_queue_lock);
-	while (!list_empty(&client_ctx->msg_queue)) {
-		DBG("%s(): Delete remaining entries\n", __func__);
-		vdec_msg = list_first_entry(&client_ctx->msg_queue,
-						   struct vid_dec_msg, list);
-		if (vdec_msg) {
-			list_del(&vdec_msg->list);
-			kfree(vdec_msg);
-		}
-	}
-	mutex_unlock(&client_ctx->msg_queue_lock);
-	vcd_status = vcd_close(client_ctx->vcd_handle);
-
-	if (vcd_status) {
-		mutex_unlock(&mpq_dvb_video_device->lock);
-		return false;
-	}
-	client_ctx->user_ion_client = NULL;
-	mutex_destroy(&client_ctx->msg_queue_lock);
-	mutex_destroy(&client_ctx->enrty_queue_lock);
-	memset((void *)client_ctx, 0, sizeof(struct video_client_ctx));
-	mpq_dvb_video_device->num_clients--;
-	mutex_unlock(&mpq_dvb_video_device->lock);
-	return true;
-}
-
-static int mpq_int_vid_dec_open_client(struct video_client_ctx **vid_clnt_ctx,
-					int flags)
-{
-	int rc = 0;
-	s32 client_index;
-	struct video_client_ctx *client_ctx = NULL;
-	u8 client_count;
-
-	if (!vid_clnt_ctx) {
-		DBG("Invalid input\n");
-		return -EINVAL;
-	}
-	*vid_clnt_ctx = NULL;
-	client_count = vcd_get_num_of_clients();
-	if (client_count == VIDC_MAX_NUM_CLIENTS) {
-		ERR("ERROR : vid_dec_open() max number of clients"\
-			"limit reached\n");
-		return -ENOMEM;
-	}
-
-	DBG(" Virtual Address of ioremap is %p\n",
-				mpq_dvb_video_device->virt_base);
-	if (!mpq_dvb_video_device->num_clients)
-		if (!vidc_load_firmware())
-			return -ENOMEM;
-
-	client_index = mpq_int_vid_dec_get_empty_client_index();
-	if (client_index == -1) {
-		DBG("%s() : No free clients client_index == -1\n", __func__);
-		vidc_release_firmware();
-		return -ENOMEM;
-	}
-	client_ctx = &mpq_dvb_video_device->vdec_clients[client_index];
-	mpq_dvb_video_device->num_clients++;
-	init_completion(&client_ctx->event);
-	mutex_init(&client_ctx->msg_queue_lock);
-	mutex_init(&client_ctx->enrty_queue_lock);
-	INIT_LIST_HEAD(&client_ctx->msg_queue);
-	init_waitqueue_head(&client_ctx->msg_wait);
-	client_ctx->stop_msg = 0;
-	client_ctx->stop_called = false;
-	client_ctx->stop_sync_cb = false;
-	client_ctx->dmx_disable = 0;
-	if (vcd_get_ion_status()) {
-		client_ctx->user_ion_client = vcd_get_ion_client();
-		if (!client_ctx->user_ion_client) {
-			ERR("vcd_open ion client get failed");
-			rc = -ENOMEM;
-			goto client_failure;
-		}
-	}
-	rc = vcd_open(mpq_dvb_video_device->device_handle, true,
-				  mpq_int_vid_dec_vcd_cb, client_ctx, flags);
-	if (!rc) {
-		wait_for_completion(&client_ctx->event);
-		if (client_ctx->event_status) {
-			DBG("callback for vcd_open returned error: %u",
-				client_ctx->event_status);
-			rc = -ENODEV;
-			goto client_failure;
-		}
-	} else {
-		DBG("vcd_open returned error: %u", rc);
-		goto client_failure;
-	}
-	client_ctx->seq_header_set = false;
-	*vid_clnt_ctx = client_ctx;
-
-	return 0;
-
-client_failure:
-	vidc_release_firmware();
-	mpq_dvb_video_device->num_clients--;
-	mutex_destroy(&client_ctx->msg_queue_lock);
-	mutex_destroy(&client_ctx->enrty_queue_lock);
-	memset((void *)client_ctx, 0, sizeof(struct video_client_ctx));
-	return rc;
-}
-
-static int mpq_dvb_video_open(struct inode *inode, struct file *file)
-{
-	int rc;
-	struct mpq_dvb_video_inst *dev_inst   = NULL;
-	struct dvb_device         *device     = NULL;
-
-	DBG("Inside %s()", __func__);
-	mutex_lock(&mpq_dvb_video_device->lock);
-
-	/* Open the dvb/video instance */
-	rc = dvb_generic_open(inode, file);
-	if (rc) {
-		DBG("Failed in dvb_generic_open with return value :%d\n",
-					rc);
-		mutex_unlock(&mpq_dvb_video_device->lock);
-		return rc;
-
-	}
-
-	device   = (struct dvb_device *)file->private_data;
-	dev_inst = (struct mpq_dvb_video_inst *)device->priv;
-
-	if (dev_inst->client_ctx) {
-		dvb_generic_release(inode, file);
-		mutex_unlock(&mpq_dvb_video_device->lock);
-		return -EEXIST;
-	}
-
-	rc = mpq_int_vid_dec_open_client(&dev_inst->client_ctx, 0);
-	if (rc) {
-		dvb_generic_release(inode, file);
-		mutex_unlock(&mpq_dvb_video_device->lock);
-		return rc;
-	}
-
-	if (!dev_inst->client_ctx) {
-		dvb_generic_release(inode, file);
-		mutex_unlock(&mpq_dvb_video_device->lock);
-		return -ENOMEM;
-	}
-
-	/* Set default source to memory for easier handling */
-	dev_inst->source = VIDEO_SOURCE_MEMORY;
-
-	mutex_unlock(&mpq_dvb_video_device->lock);
-
-	return rc;
-}
-
-static int mpq_dvb_video_term_dmx_src(struct mpq_dvb_video_inst *dev_inst)
-{
-
-	struct mpq_dmx_src_data *dmx_data = dev_inst->dmx_src_data;
-
-	if (NULL == dmx_data)
-		return 0;
-
-	kthread_stop(dmx_data->data_task);
-	mutex_destroy(&dmx_data->msg_queue_lock);
-
-	kfree(dmx_data);
-	dev_inst->dmx_src_data = NULL;
-
-	return 0;
-
-}
-
-static int mpq_dvb_video_release(struct inode *inode, struct file *file)
-{
-	struct dvb_device *device = file->private_data;
-	struct mpq_dvb_video_inst *dev_inst = device->priv;
-
-	vidc_cleanup_addr_table(dev_inst->client_ctx, BUFFER_TYPE_OUTPUT);
-	vidc_cleanup_addr_table(dev_inst->client_ctx, BUFFER_TYPE_INPUT);
-	if (dev_inst->source == VIDEO_SOURCE_DEMUX)
-		mpq_dvb_video_term_dmx_src(dev_inst);
-	mpq_int_vid_dec_close_client(dev_inst->client_ctx);
-	memset((void *)dev_inst, 0, sizeof(struct mpq_dvb_video_inst));
-	vidc_release_firmware();
-	dvb_generic_release(inode, file);
-	return 0;
-}
-
-static void *mpq_int_vid_dec_map_dev_base_addr(void *device_name)
-{
-	return mpq_dvb_video_device->virt_base;
-}
-
-static int mpq_int_vid_dec_vcd_init(void)
-{
-	int rc;
-	struct vcd_init_config vcd_init_config;
-	u32 i;
-
-	/* init_timer(&hw_timer); */
-	DBG("msm_vidc_dec: Inside %s()", __func__);
-	mpq_dvb_video_device->num_clients = 0;
-
-	for (i = 0; i < VIDC_MAX_NUM_CLIENTS; i++) {
-		memset((void *)&mpq_dvb_video_device->vdec_clients[i], 0,
-		       sizeof(mpq_dvb_video_device->vdec_clients[i]));
-	}
-
-	mutex_init(&mpq_dvb_video_device->lock);
-	mpq_dvb_video_device->virt_base = vidc_get_ioaddr();
-	DBG("%s() : base address for VIDC core %u\n", __func__, \
-		(int)mpq_dvb_video_device->virt_base);
-
-	if (!mpq_dvb_video_device->virt_base) {
-		DBG("%s() : ioremap failed\n", __func__);
-		return -ENOMEM;
-	}
-
-	vcd_init_config.device_name = "MPQ_VIDC";
-	vcd_init_config.map_dev_base_addr = mpq_int_vid_dec_map_dev_base_addr;
-	vcd_init_config.interrupt_clr = NULL;
-	vcd_init_config.register_isr = NULL;
-	vcd_init_config.deregister_isr = NULL;
-	vcd_init_config.timer_create = vidc_timer_create;
-	vcd_init_config.timer_release = vidc_timer_release;
-	vcd_init_config.timer_start = vidc_timer_start;
-	vcd_init_config.timer_stop = vidc_timer_stop;
-
-	rc = vcd_init(&vcd_init_config,
-			&mpq_dvb_video_device->device_handle);
-
-	if (rc) {
-		DBG("%s() : vcd_init failed\n", __func__);
-		mutex_destroy(&mpq_dvb_video_device->lock);
-		return -ENODEV;
-	}
-	return 0;
-}
-
-static int mpq_int_vdec_get_fps(struct video_client_ctx *client_ctx,
-				unsigned int *fps)
-{
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_frame_rate vcd_frame_rate;
-	u32 vcd_status = VCD_ERR_FAIL;
-
-	if (NULL == fps)
-		return -EINVAL;
-
-	vcd_property_hdr.prop_id = VCD_I_FRAME_RATE;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_frame_rate);
-	vcd_frame_rate.fps_numerator = 0;
-	vcd_frame_rate.fps_denominator = 1;
-
-	*fps = 0;
-	vcd_status = vcd_get_property(client_ctx->vcd_handle,
-				      &vcd_property_hdr, &vcd_frame_rate);
-
-	if (vcd_status)
-		return -EINVAL;
-	else {
-		*fps = (vcd_frame_rate.fps_numerator * 1000)
-			/(vcd_frame_rate.fps_denominator);
-		return 0;
-	}
-}
-
-static int mpq_dvb_video_command_handler(struct mpq_dvb_video_inst *dev_inst,
-					void *parg)
-{
-	struct video_client_ctx *client_ctx = dev_inst->client_ctx;
-	struct video_command *cmd = parg;
-	int rc = 0;
-
-	if (cmd == NULL)
-		return -EINVAL;
-
-	switch (cmd->cmd) {
-	case VIDEO_CMD_SET_CODEC:
-		DBG("cmd : VIDEO_CMD_SET_CODEC\n");
-		rc = mpq_int_vid_dec_set_codec(client_ctx, cmd->codec);
-		break;
-	case VIDEO_CMD_GET_CODEC:
-		DBG("cmd : VIDEO_CMD_GET_CODEC\n");
-		rc = mpq_int_vid_dec_get_codec(client_ctx, &cmd->codec);
-		break;
-	case VIDEO_CMD_SET_OUTPUT_FORMAT:
-		DBG("cmd : VIDEO_CMD_SET_OUTPUT_FORMAT\n");
-		rc = mpq_int_vid_dec_set_output_format(client_ctx,
-							cmd->format);
-		break;
-	case VIDEO_CMD_GET_OUTPUT_FORMAT:
-		DBG("cmd : VIDEO_CMD_GET_OUTPUT_FORMAT\n");
-		rc = mpq_int_vid_dec_get_output_format(client_ctx,
-							&cmd->format);
-		break;
-	case VIDEO_CMD_GET_PIC_RES:
-		DBG("cmd : VIDEO_CMD_GET_PIC_RES\n");
-		rc = mpq_int_vid_dec_get_frame_resolution(client_ctx,
-						&cmd->frame_res);
-		break;
-	case VIDEO_CMD_SET_INPUT_BUFFERS:
-		DBG("cmd : VIDEO_CMD_SET_INPUT_BUFFERS\n");
-		rc = mpq_int_vid_dec_set_buffer(dev_inst, &cmd->buffer,
-						BUFFER_TYPE_INPUT);
-		break;
-	case VIDEO_CMD_SET_OUTPUT_BUFFERS:
-		DBG("cmd : VIDEO_CMD_SET_OUTPUT_BUFFERS\n");
-		rc = mpq_int_vid_dec_set_buffer(dev_inst, &cmd->buffer,
-						BUFFER_TYPE_OUTPUT);
-		break;
-	case VIDEO_CMD_FREE_INPUT_BUFFERS:
-		DBG("cmd : VIDEO_CMD_FREE_INPUT_BUFFERS\n");
-		rc = mpq_int_vid_dec_free_buffer(client_ctx, &cmd->buffer,
-						BUFFER_TYPE_INPUT);
-		break;
-	case VIDEO_CMD_FREE_OUTPUT_BUFFERS:
-		DBG("cmd : VIDEO_CMD_FREE_OUTPUT_BUFFERS\n");
-		rc = mpq_int_vid_dec_free_buffer(client_ctx, &cmd->buffer,
-							BUFFER_TYPE_OUTPUT);
-		break;
-	case VIDEO_CMD_GET_BUFFER_REQ:
-		DBG("cmd : VIDEO_CMD_GET_BUFFER_REQ\n");
-		rc = mpq_int_vid_dec_get_buffer_req(client_ctx, &cmd->buf_req);
-		break;
-	case VIDEO_CMD_SET_BUFFER_COUNT:
-		DBG("cmd : VIDEO_CMD_SET_BUFFER_COUNT\n");
-		rc = mpq_int_vid_dec_set_buffer_req(client_ctx, cmd->buf_req);
-		break;
-	case VIDEO_CMD_READ_RAW_OUTPUT:
-		DBG("cmd : VIDEO_CMD_READ_RAW_OUTPUT\n");
-		rc = mpq_int_vid_dec_fill_output_buffer(client_ctx,
-							&cmd->buffer);
-		break;
-	case VIDEO_CMD_SET_H264_MV_BUFFER:
-		DBG("cmd : VIDEO_CMD_SET_H264_MV_BUFFER\n");
-		rc = mpq_int_vid_dec_set_h264_mv_buffers(client_ctx,
-							&cmd->mv_buffer_prop);
-		break;
-	case VIDEO_CMD_GET_H264_MV_BUFFER:
-		DBG("cmd : VIDEO_CMD_GET_H264_MV_BUFFER\n");
-		rc = mpq_int_vid_dec_get_h264_mv_buffer_size(client_ctx,
-							&cmd->mv_buffer_req);
-		break;
-	case VIDEO_CMD_FREE_H264_MV_BUFFER:
-		DBG("cmd : VIDEO_CMD_FREE_H264_MV_BUFFER\n");
-		rc = mpq_int_vid_dec_free_h264_mv_buffers(client_ctx);
-		break;
-	case VIDEO_CMD_CLEAR_INPUT_BUFFER:
-		DBG("cmd : VIDEO_CMD_CLEAR_INPUT_BUFFER\n");
-		rc = mpq_int_vid_dec_flush(client_ctx, VDEC_FLUSH_TYPE_INPUT);
-		break;
-	case VIDEO_CMD_CLEAR_OUTPUT_BUFFER:
-		DBG("cmd : VIDEO_CMD_CLEAR_OUTPUT_BUFFER\n");
-		rc = mpq_int_vid_dec_flush(client_ctx, VDEC_FLUSH_TYPE_OUTPUT);
-		break;
-	default:
-		rc = -EINVAL;
-		break;
-	}
-
-	return rc;
-}
-
-
-static ssize_t mpq_dvb_video_write(struct file *file, const char __user *buf,
-					size_t count, loff_t *ppos)
-{
-	int rc = 0;
-	struct dvb_device *device = file->private_data;
-	struct mpq_dvb_video_inst *dev_inst = NULL;
-
-	struct video_data_buffer *input_frame =
-				(struct video_data_buffer *)buf;
-
-	if ((device == NULL) || (input_frame == NULL))
-		return -EINVAL;
-
-	dev_inst = device->priv;
-	if (dev_inst == NULL)
-		return -EINVAL;
-
-	rc = mpq_int_vid_dec_decode_frame(dev_inst->client_ctx, input_frame);
-	if (rc)
-		return -EIO;
-
-	return input_frame->buffer_len;
-}
-
-static int mpq_dvb_video_get_event(struct video_client_ctx *client_ctx,
-				struct video_event *ev)
-{
-	int rc;
-	struct vdec_msginfo vdec_msg_info = {};
-
-	memset(ev, 0, sizeof(struct video_event));
-
-	rc = mpq_int_vid_dec_get_next_msg(client_ctx, &vdec_msg_info);
-	if (rc)
-		return rc;
-
-	ev->status = vdec_msg_info.status_code;
-	/* Map the Message here */
-	switch (vdec_msg_info.msgcode) {
-	case VDEC_MSG_INVALID:
-		DBG("VDEC_MSG_INVALID\n");
-		break;
-	case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
-		DBG("VIDEO_EVENT_INPUT_BUFFER_DONE\n");
-		ev->type = VIDEO_EVENT_INPUT_BUFFER_DONE;
-		ev->u.buffer.client_data =
-				vdec_msg_info.msgdata.input_frame_clientdata;
-		break;
-	case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
-		DBG("VIDEO_EVENT_OUTPUT_BUFFER_DONE\n");
-		ev->type = VIDEO_EVENT_OUTPUT_BUFFER_DONE;
-		ev->u.buffer.bufferaddr  =
-				vdec_msg_info.msgdata.output_frame.bufferaddr;
-		ev->u.buffer.buffer_len  =
-				vdec_msg_info.msgdata.output_frame.len;
-		ev->u.buffer.ip_buffer_tag = vdec_msg_info.msgdata.\
-					output_frame.input_frame_clientdata;
-		ev->u.buffer.client_data = vdec_msg_info.msgdata.\
-					output_frame.client_data;
-		ev->u.buffer.pts         =
-				vdec_msg_info.msgdata.output_frame.time_stamp;
-		ev->u.buffer.offset      =
-				vdec_msg_info.msgdata.output_frame.offset;
-		ev->u.buffer.interlaced_format = map_scan_type(vdec_msg_info.\
-				msgdata.output_frame.interlaced_format);
-		break;
-	case VDEC_MSG_RESP_START_DONE:
-		DBG("VIDEO_EVENT_DECODER_PLAYING\n");
-		ev->type = VIDEO_EVENT_DECODER_PLAYING;
-		break;
-	case VDEC_MSG_RESP_STOP_DONE:
-		DBG("VIDEO_EVENT_DECODER_FREEZED\n");
-		ev->type = VIDEO_EVENT_DECODER_STOPPED;
-		break;
-	case VDEC_MSG_RESP_PAUSE_DONE:
-		DBG("VDEC_MSG_RESP_PAUSE_DONE\n");
-		ev->type = VIDEO_EVENT_DECODER_FREEZED;
-		break;
-	case VDEC_MSG_RESP_RESUME_DONE:
-		DBG("VIDEO_EVENT_DECODER_RESUMED\n");
-		ev->type = VIDEO_EVENT_DECODER_RESUMED;
-		break;
-	case VDEC_MSG_EVT_CONFIG_CHANGED:
-	case VDEC_MSG_EVT_INFO_CONFIG_CHANGED:
-		DBG("VIDEO_EVENT_SEQ_HDR_FOUND\n");
-		ev->type = VIDEO_EVENT_SEQ_HDR_FOUND;
-		break;
-	case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
-		DBG("VIDEO_EVENT_OUTPUT_FLUSH_DONE\n");
-		ev->type = VIDEO_EVENT_OUTPUT_FLUSH_DONE;
-		break;
-	case VDEC_MSG_RESP_OUTPUT_FLUSHED:
-		DBG("VIDEO_EVENT_OUTPUT_FLUSHED\n");
-		ev->type = VIDEO_EVENT_OUTPUT_FLUSHED;
-		ev->u.buffer.bufferaddr  =
-				vdec_msg_info.msgdata.output_frame.bufferaddr;
-		ev->u.buffer.buffer_len  =
-				vdec_msg_info.msgdata.output_frame.len;
-		ev->u.buffer.ip_buffer_tag = vdec_msg_info.msgdata.\
-				output_frame.input_frame_clientdata;
-		ev->u.buffer.client_data = vdec_msg_info.msgdata.\
-				output_frame.client_data;
-		ev->u.buffer.pts         =
-				vdec_msg_info.msgdata.output_frame.time_stamp;
-		ev->u.buffer.offset      =
-				vdec_msg_info.msgdata.output_frame.offset;
-		ev->u.buffer.interlaced_format = map_scan_type(vdec_msg_info.\
-				msgdata.output_frame.interlaced_format);
-		break;
-	case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
-		DBG("VIDEO_EVENT_INPUT_FLUSH_DONE\n");
-		ev->type = VIDEO_EVENT_INPUT_FLUSH_DONE;
-		break;
-	case VDEC_MSG_RESP_INPUT_FLUSHED:
-		DBG("VIDEO_EVENT_INPUT_FLUSHED\n");
-		ev->type = VIDEO_EVENT_INPUT_FLUSHED;
-		ev->u.buffer.client_data =
-				vdec_msg_info.msgdata.input_frame_clientdata;
-		break;
-	}
-	return 0;
-}
-
-static enum scan_format map_scan_type(enum vdec_interlaced_format type)
-{
-	if (type == VDEC_InterlaceFrameProgressive)
-		return INTERLACE_FRAME_PROGRESSIVE;
-	if (type == VDEC_InterlaceInterleaveFrameTopFieldFirst)
-		return INTERLACE_INTERLEAVE_FRAME_TOP_FIELD_FIRST;
-	if (type == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
-		return INTERLACE_INTERLEAVE_FRAME_BOTTOM_FIELD_FIRST;
-	return INTERLACE_FRAME_PROGRESSIVE;
-}
-
-static int mpq_dvb_video_play(struct mpq_dvb_video_inst *dev_inst)
-{
-	return mpq_int_vid_dec_start_stop(dev_inst->client_ctx, true);
-}
-
-static int mpq_dvb_video_stop(struct video_client_ctx *client_ctx)
-{
-	return mpq_int_vid_dec_start_stop(client_ctx, false);
-}
-
-static void mpq_dvb_video_get_stream_if(
-				enum mpq_adapter_stream_if interface_id,
-				void *arg)
-{
-	struct mpq_dvb_video_inst *dev_inst = arg;
-
-	DBG("In mpq_dvb_video_get_stream_if : %d\n", interface_id);
-
-	mpq_adapter_get_stream_if(interface_id,
-			&dev_inst->dmx_src_data->stream_buffer);
-
-	wake_up(&dev_inst->dmx_src_data->msg_wait);
-}
-
-static int mpq_dvb_video_init_dmx_src(struct mpq_dvb_video_inst *dev_inst,
-					int device_id)
-{
-	int rc;
-
-	dev_inst->dmx_src_data =  kzalloc(sizeof(struct mpq_dmx_src_data),
-						GFP_KERNEL);
-	if (dev_inst->dmx_src_data == NULL)
-		return -ENOMEM;
-
-	rc = mpq_adapter_get_stream_if(
-		(enum mpq_adapter_stream_if)device_id,
-		&dev_inst->dmx_src_data->stream_buffer);
-
-	if (rc) {
-		kfree(dev_inst->dmx_src_data);
-		return -ENODEV;
-	} else if (dev_inst->dmx_src_data->stream_buffer == NULL) {
-		DBG("Stream Buffer is NULL. Resigtering Notifier.\n");
-		rc = mpq_adapter_notify_stream_if(
-			(enum mpq_adapter_stream_if)device_id,
-			mpq_dvb_video_get_stream_if,
-			(void *)dev_inst);
-		if (rc) {
-			kfree(dev_inst->dmx_src_data);
-			return -ENODEV;
-		}
-	}
-
-	mutex_init(&dev_inst->dmx_src_data->msg_queue_lock);
-	INIT_LIST_HEAD(&dev_inst->dmx_src_data->msg_queue);
-	init_waitqueue_head(&dev_inst->dmx_src_data->msg_wait);
-
-	dev_inst->dmx_src_data->data_task = kthread_run(
-			mpq_bcast_data_handler,	(void *)dev_inst,
-			vid_thread_names[device_id]);
-
-	return 0;
-}
-
-static int mpq_dvb_video_set_source(struct dvb_device *device,
-				video_stream_source_t source)
-{
-	int rc = 0;
-	struct mpq_dvb_video_inst *dev_inst =
-			(struct mpq_dvb_video_inst *)device->priv;
-
-	if (dev_inst->source == source)
-		return rc;
-
-	if ((VIDEO_SOURCE_MEMORY == source) &&
-		(VIDEO_SOURCE_DEMUX == dev_inst->source))
-		mpq_dvb_video_term_dmx_src(dev_inst);
-
-	dev_inst->source = source;
-	if (VIDEO_SOURCE_DEMUX == source)
-		rc = mpq_dvb_video_init_dmx_src(dev_inst, device->id);
-
-	return rc;
-}
-
-static int mpq_dvb_video_ioctl(struct file *file,
-				unsigned int cmd, void *parg)
-{
-	int rc;
-	struct dvb_device *device = (struct dvb_device *)file->private_data;
-	struct video_client_ctx *client_ctx = NULL;
-	struct mpq_dvb_video_inst *dev_inst = NULL;
-
-	if (device == NULL)
-		return -EINVAL;
-
-	dev_inst = (struct mpq_dvb_video_inst *)device->priv;
-	if (dev_inst == NULL)
-		return -EINVAL;
-
-	client_ctx = (struct video_client_ctx *)dev_inst->client_ctx;
-	if (client_ctx == NULL)
-		return -EINVAL;
-
-	switch (cmd) {
-	case VIDEO_PLAY:
-		DBG("ioctl : VIDEO_PLAY\n");
-		rc = mpq_dvb_video_play(dev_inst);
-		break;
-	case VIDEO_STOP:
-		DBG("ioctl : VIDEO_STOP\n");
-		rc = mpq_dvb_video_stop(client_ctx);
-		break;
-	case VIDEO_FREEZE:
-		DBG("ioctl : VIDEO_FREEZE\n");
-		rc = mpq_int_vid_dec_pause_resume(client_ctx, true);
-		break;
-	case VIDEO_CONTINUE:
-		DBG("ioctl : VIDEO_CONTINUE\n");
-		rc = mpq_int_vid_dec_pause_resume(client_ctx, false);
-		break;
-	case VIDEO_CLEAR_BUFFER:
-		DBG("ioctl : VIDEO_CLEAR_BUFFER\n");
-		rc = mpq_int_vid_dec_flush(client_ctx,
-				VDEC_FLUSH_TYPE_ALL);
-		break;
-	case VIDEO_COMMAND:
-	case VIDEO_TRY_COMMAND:
-		DBG("ioctl : VIDEO_COMMAND\n");
-		rc = mpq_dvb_video_command_handler(dev_inst, parg);
-		break;
-	case VIDEO_GET_FRAME_RATE:
-		DBG("ioctl : VIDEO_GET_FRAME_RATE\n");
-		rc = mpq_int_vdec_get_fps(client_ctx,
-				(unsigned int *)parg);
-		break;
-	case VIDEO_GET_EVENT:
-		DBG("ioctl : VIDEO_GET_EVENT\n");
-		rc = mpq_dvb_video_get_event(client_ctx,
-				(struct video_event *)parg);
-		break;
-	case VIDEO_SELECT_SOURCE:
-		DBG("ioctl : VIDEO_SELECT_SOURCE\n");
-		rc = mpq_dvb_video_set_source(device,
-				(video_stream_source_t)parg);
-		break;
-	default:
-		ERR("Invalid IOCTL\n");
-		rc = -EINVAL;
-	}
-
-	return rc;
-
-}
-
-static unsigned int mpq_dvb_video_poll(struct file *file, poll_table *wait)
-{
-	struct dvb_device *device = file->private_data;
-	struct video_client_ctx *client_ctx = NULL;
-	struct mpq_dvb_video_inst *dev_inst = NULL;
-	unsigned int mask = 0;
-
-	DBG("In %s\n", __func__);
-
-	if (device == NULL)
-		return -EINVAL;
-
-	dev_inst = device->priv;
-	if (dev_inst == NULL)
-		return -EINVAL;
-
-	client_ctx = dev_inst->client_ctx;
-	if (client_ctx == NULL)
-		return -EINVAL;
-
-	poll_wait(file, &client_ctx->msg_wait, wait);
-	if (mpq_int_vid_dec_msg_pending(client_ctx))
-		mask |= POLLIN;
-	else
-		mask = 0;
-
-	return mask;
-}
-
-/*
- * Driver Registration.
- */
-static const struct file_operations mpq_dvb_video_fops = {
-	.owner		= THIS_MODULE,
-	.write		= mpq_dvb_video_write,
-	.unlocked_ioctl	= dvb_generic_ioctl,
-	.open		= mpq_dvb_video_open,
-	.release	= mpq_dvb_video_release,
-	.poll		= mpq_dvb_video_poll,
-	.llseek		= noop_llseek,
-};
-
-static const struct dvb_device mpq_dvb_video_device_ctrl = {
-	.priv		= NULL,
-	.users		= 4,
-	.readers	= 4,	/* arbitrary */
-	.writers	= 4,
-	.fops		= &mpq_dvb_video_fops,
-	.kernel_ioctl	= mpq_dvb_video_ioctl,
-};
-
-static int __init mpq_dvb_video_init(void)
-{
-	int rc, i = 0, j;
-
-	mpq_dvb_video_device = kzalloc(sizeof(struct mpq_dvb_video_dev),
-				GFP_KERNEL);
-	if (!mpq_dvb_video_device) {
-		ERR("%s Unable to allocate memory for mpq_dvb_video_dev\n",
-		       __func__);
-		return -ENOMEM;
-	}
-
-	mpq_dvb_video_device->mpq_adapter = mpq_adapter_get();
-	if (!mpq_dvb_video_device->mpq_adapter) {
-		ERR("%s Unable to get MPQ Adapter\n", __func__);
-		rc = -ENODEV;
-		goto free_region;
-	}
-
-	rc = mpq_int_vid_dec_vcd_init();
-	if (rc)
-		goto free_region;
-
-	for (i = 0; i < DVB_MPQ_NUM_VIDEO_DEVICES; i++) {
-
-		rc = dvb_register_device(mpq_dvb_video_device->mpq_adapter,
-				&mpq_dvb_video_device->dev_inst[i].video_dev,
-				&mpq_dvb_video_device_ctrl,
-				&mpq_dvb_video_device->dev_inst[i],
-				DVB_DEVICE_VIDEO);
-
-		if (rc) {
-			ERR("Failed in %s with at %d return value :%d\n",
-				__func__, i, rc);
-			goto free_region;
-		}
-
-	}
-
-	return 0;
-
-free_region:
-	for (j = 0; j < i; j++)
-		dvb_unregister_device(
-			mpq_dvb_video_device->dev_inst[j].video_dev);
-
-	kfree(mpq_dvb_video_device);
-	return rc;
-}
-
-static void __exit mpq_dvb_video_exit(void)
-{
-	int i;
-
-	for (i = 0; i < DVB_MPQ_NUM_VIDEO_DEVICES; i++)
-		dvb_unregister_device(
-			mpq_dvb_video_device->dev_inst[i].video_dev);
-
-	mutex_destroy(&mpq_dvb_video_device->lock);
-	kfree(mpq_dvb_video_device);
-}
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("MPQ DVB Video driver");
-
-module_init(mpq_dvb_video_init);
-module_exit(mpq_dvb_video_exit);
diff --git a/drivers/media/dvb/mpq/video/mpq_dvb_video_internal.h b/drivers/media/dvb/mpq/video/mpq_dvb_video_internal.h
deleted file mode 100644
index df337b9..0000000
--- a/drivers/media/dvb/mpq/video/mpq_dvb_video_internal.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/* Copyright (c) 2010,2012, Code Aurora Forum. 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 MPQ_DVB_VIDEO_INTERNAL_H
-#define MPQ_DVB_VIDEO_INTERNAL_H
-
-#include <linux/msm_vidc_dec.h>
-#include <media/msm/vidc_init.h>
-#include <linux/dvb/video.h>
-
-/*
- * MPQ Specific Includes.
- */
-#include "mpq_dvb_debug.h"
-#include "mpq_adapter.h"
-#include "mpq_stream_buffer.h"
-
-#define DVB_MPQ_NUM_VIDEO_DEVICES CONFIG_DVB_MPQ_NUM_VIDEO_DEVICES
-
-/*
- * Input Buffer Requirements for Video Decoder.
- */
-#define DVB_VID_NUM_IN_BUFFERS (2)
-#define DVB_VID_IN_BUFFER_SIZE (2*1024*1024)
-#define DVB_VID_IN_BUFFER_ALGN (8*1024)
-
-struct vid_dec_msg {
-	struct list_head list;
-	struct vdec_msginfo vdec_msg_info;
-};
-
-enum mpq_bcast_msgcode {
-	MPQ_BCAST_MSG_START,
-	MPQ_BCAST_MSG_IBD,
-	MPQ_BCAST_MSG_FLUSH,
-	MPQ_BCAST_MSG_TERM
-};
-
-struct mpq_bcast_msg_info {
-	enum mpq_bcast_msgcode code;
-	unsigned int data;
-};
-
-struct mpq_bcast_msg {
-	struct list_head list;
-	struct mpq_bcast_msg_info info;
-};
-
-struct mpq_dmx_src_data {
-	struct mpq_streambuffer *stream_buffer;
-	struct video_data_buffer in_buffer[DVB_VID_NUM_IN_BUFFERS];
-	struct list_head msg_queue;
-	wait_queue_head_t msg_wait;
-	struct mutex msg_queue_lock;
-	struct task_struct *data_task;
-};
-
-struct mpq_dvb_video_inst {
-	struct dvb_device  *video_dev;
-	video_stream_source_t source;
-	struct mpq_dmx_src_data *dmx_src_data;
-	struct video_client_ctx *client_ctx;
-};
-
-struct mpq_dvb_video_dev {
-
-	resource_size_t phys_base;
-	void __iomem *virt_base;
-	unsigned int irq;
-	struct clk *hclk;
-	struct clk *hclk_div2;
-	struct clk *pclk;
-	unsigned long hclk_rate;
-	struct mutex lock;
-	s32 device_handle;
-	struct dvb_adapter *mpq_adapter;
-	struct mpq_dvb_video_inst dev_inst[DVB_MPQ_NUM_VIDEO_DEVICES];
-	struct video_client_ctx vdec_clients[DVB_MPQ_NUM_VIDEO_DEVICES];
-	u32 num_clients;
-	void(*timer_handler)(void *);
-};
-
-#endif /* MPQ_DVB_VIDEO_INTERNAL_H */
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
new file mode 100644
index 0000000..10c803e
--- /dev/null
+++ b/drivers/media/platform/Kconfig
@@ -0,0 +1 @@
+source "drivers/media/platform/msm/Kconfig"
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
new file mode 100644
index 0000000..3d080b7
--- /dev/null
+++ b/drivers/media/platform/Makefile
@@ -0,0 +1 @@
+obj-y += msm/
diff --git a/drivers/media/platform/msm/Kconfig b/drivers/media/platform/msm/Kconfig
new file mode 100644
index 0000000..e344719
--- /dev/null
+++ b/drivers/media/platform/msm/Kconfig
@@ -0,0 +1,48 @@
+#
+# MSM camera configuration
+#
+
+comment "Qualcomm MSM Camera And Video"
+
+menuconfig MSM_CAMERA
+	bool "Qualcomm MSM camera and video capture support"
+	depends on ARCH_MSM && VIDEO_V4L2 && I2C
+	default y
+	help
+	  Say Y here to enable selecting the video adapters for
+	  Qualcomm msm camera and video encoding
+
+config MSM_CAMERA_DEBUG
+	bool "Qualcomm MSM camera debugging with printk"
+	depends on MSM_CAMERA
+	default n
+	help
+	  Enable printk() debug for msm camera
+
+if MSM_CAMERA
+source "drivers/media/platform/msm/camera_v1/Kconfig"
+endif # MSM_CAMERA
+
+menuconfig MSMB_CAMERA
+	bool "Qualcomm MSM camera and video capture 2.0 support"
+	depends on ARCH_MSM && VIDEO_V4L2 && I2C
+	---help---
+	  Say Y here to enable selecting the video adapters for
+	  Qualcomm msm camera and video capture 2.0, enabling this
+	  adds support for the camera driver stack including sensor, isp
+	  and postprocessing drivers.
+
+config MSMB_CAMERA_DEBUG
+	bool "Qualcomm MSM camera 2.0 debugging with printk"
+	depends on MSMB_CAMERA
+	---help---
+	  Enable printk() debug for msm camera 2.0
+
+if MSMB_CAMERA
+source "drivers/media/platform/msm/camera_v2/Kconfig"
+endif # MSMB_CAMERA
+
+source "drivers/media/platform/msm/vidc/Kconfig"
+source "drivers/media/platform/msm/wfd/Kconfig"
+source "drivers/media/platform/msm/dvb/Kconfig"
+source "drivers/media/platform/msm/vcap/Kconfig"
diff --git a/drivers/media/platform/msm/Makefile b/drivers/media/platform/msm/Makefile
new file mode 100644
index 0000000..c1d86df
--- /dev/null
+++ b/drivers/media/platform/msm/Makefile
@@ -0,0 +1,6 @@
+obj-$(CONFIG_MSM_VIDC_V4L2) += vidc/
+obj-$(CONFIG_MSM_WFD) += wfd/
+obj-$(CONFIG_DVB_MPQ) += dvb/
+obj-$(CONFIG_MSM_CAMERA) += camera_v1/
+obj-$(CONFIG_MSMB_CAMERA) += camera_v2/
+obj-y += vcap/
diff --git a/drivers/media/platform/msm/camera_v1/Kconfig b/drivers/media/platform/msm/camera_v1/Kconfig
new file mode 100644
index 0000000..ac449cc
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/Kconfig
@@ -0,0 +1,409 @@
+config MSM_CAMERA_V4L2
+        bool "MSM Camera V4L2 Interface"
+        depends on MSM_CAMERA
+        default n
+        ---help---
+          This flag enables V4L2 interface of MSM
+          camera driver. If enabled, application interacts
+          with /dev/video0 through V4L2 APIs. Otherwise,
+          native APIs are used through /dev/config0, /dev/frame0,
+          and /dev/control0.
+
+comment "Camera Sensor Selection"
+config MT9T013
+	bool "Sensor mt9t013 (BAYER 3M)"
+	depends on MSM_CAMERA && !ARCH_MSM8X60 && !ARCH_MSM8960 && !MSM_CAMERA_V4L2
+	default y
+	---help---
+	  MICRON 3M Bayer Sensor with AutoFocus
+config MT9D113
+	bool "Sensor mt9d113 (YUV 2M)"
+	depends on MSM_CAMERA && ARCH_MSM8X60 && !MSM_CAMERA_V4L2
+	default y
+	---help---
+	  MICRON 2M YUV Sensor
+	  This sensor is the front camera on QT8660.
+	  This uses csi mipi interface.
+	  This sensor is used only on QT device.
+config MT9D112
+	bool "Sensor mt9d112 (YUV 2M)"
+	depends on MSM_CAMERA && !ARCH_MSM8X60 && !ARCH_MSM8960 && !MSM_CAMERA_V4L2
+	default y
+	---help---
+	  MICRON 2M YUV Sensor
+config IMX074
+	bool "Sensor IMX074 (BAYER 13.5M)"
+	depends on MSM_CAMERA
+	---help---
+	SONY 13.5 MP Bayer Sensor
+config OV5640
+	bool "Sensor OV5640 (YUV 5M)"
+	depends on MSM_CAMERA && !MSM_CAMERA_V4L2
+	default n
+	---help---
+	Omni 5M YUV Sensor
+
+config OV5647
+	bool "Sensor ov5647 (BAYER 5M)"
+	depends on MSM_CAMERA
+	---help---
+	  OV 5M Bayer Sensor with AutoFocus
+
+config AD5046_ACT
+	bool "Lens actuator ad5046"
+	depends on MSM_CAMERA && OV5647
+	---help---
+	  ad5046 lens actuator driver for ov5647.
+	  Say Y here if this is msm7627A variant platform.
+config WEBCAM_OV7692_QRD
+	bool "Sensor OV7692 QRD(VGA YUV)"
+	depends on MSM_CAMERA && (ARCH_MSM7X27A || ARCH_MSM8X60)
+	default n
+	---help---
+	  Omni Vision VGA YUV Sensor for QRD Devices
+config MT9M114
+        bool "Sensor MT9M114 (YUV 1.26M)"
+        depends on MSM_CAMERA
+        ---help---
+        APTINA 1.26 MP yuv Sensor
+config WEBCAM_OV7692
+	bool "Sensor OV7692 (VGA YUV)"
+	depends on MSM_CAMERA && ARCH_MSM8X60 && !MSM_CAMERA_V4L2
+	default y
+	---help---
+	  Omni Vision VGA YUV Sensor.
+config WEBCAM_OV9726
+	bool "Sensor OV9726 (VGA Bayer)"
+	depends on MSM_CAMERA && (ARCH_MSM8X60 || ARCH_MSM7X30 || ARCH_MSM7X27A)
+	default n
+	---help---
+	  Omni Vision VGA Bayer Sensor.
+#	This Senosr is used as a webcam.
+#	This uses the CSI interface.
+config VX6953
+	bool "Sensor VX6953 (BAYER 5M)"
+	depends on MSM_CAMERA && (ARCH_MSM7X30 || ARCH_MSM8X60) && !MSM_CAMERA_V4L2
+	default y
+	---help---
+	STM 5M Bayer Sensor with EDOF
+config SN12M0PZ
+	bool "Sensor sn12m0pz (Bayer 12 MP)"
+	depends on MSM_CAMERA && ARCH_MSM7X30 && !MSM_CAMERA_V4L2
+	default y
+	---help---
+	  Sony 12 MP Bayer Sensor
+config MT9P012
+	bool "Sensor mt9p012 (BAYER 5M)"
+	depends on MSM_CAMERA && !ARCH_MSM8X60 && !MSM_CAMERA_V4L2
+	default y
+	---help---
+	  MICRON 5M Bayer Sensor with Autofocus
+
+choice
+	prompt "AF module"
+	depends on MT9P012 && !ARCH_MSM8X60 && !MSM_CAMERA_V4L2
+	default MSM_CAMERA_AF_FOXCONN
+
+config MSM_CAMERA_AF_FOXCONN
+	bool "FOXCONN Module"
+	help
+	  This driver supports FOXCONN AF module for 5M Bayer sensor
+
+config MSM_CAMERA_AF_BAM
+	bool "BAM Module"
+	help
+	  This driver supports BAM AF module for 5M Bayer sensor
+
+endchoice
+
+config MT9P012_KM
+	bool "Sensor mt9p012 KM module (BAYER 5M)"
+	depends on MSM_CAMERA && !ARCH_MSM8X60 && !MSM_CAMERA_V4L2
+	default y
+	---help---
+	  MICRON 5M Bayer Sensor KM modules with Autofocus
+
+config MT9E013
+	bool "Sensor mt9e013 module (BAYER 8M)"
+	depends on MSM_CAMERA && (ARCH_MSM7X30 || ARCH_MSM8X60 || ARCH_MSM7X27A)
+	default n
+	---help---
+	  Aptina 8M Bayer Sensor modules with Autofocus
+
+config IMX074_ACT
+	bool "Actuator IMX074 (BAYER 13.5M)"
+	depends on MSM_CAMERA
+	---help---
+	Actuator for SONY 13.5 MP Bayer Sensor
+
+config S5K3E2FX
+	bool "Sensor s5k3e2fx (Samsung 5M)"
+	depends on MSM_CAMERA && !ARCH_MSM8X60 && !MSM_CAMERA_V4L2
+	default y
+	---help---
+	  Samsung 5M with Autofocus
+
+config QS_S5K4E1
+	bool "Sensor qs_s5k4e1 (Samsung 5M)"
+	depends on MSM_CAMERA && ARCH_MSM8X60 && !MSM_CAMERA_V4L2
+	default y
+	---help---
+	  Samsung 5M with Autofocus
+
+config S5K4E1
+	bool "Sensor Sensor s5k4e1 (Samsung 5M)"
+	depends on MSM_CAMERA
+	default n
+	---help---
+	  Support for S5k4E1 samsung sensor driver.
+	  It is a Bayer 5MP sensor with auto focus and it supports
+	  two mipi lanes, required for msm7x2xA platform.
+	  Say Y here if this is msm7x2xA variant platform.
+
+config DW9712_ACT
+	bool "Lens actuator dw9721"
+	depends on MSM_CAMERA && S5K4E1
+	---help---
+	  dw9721 lens actuator driver for S5K4E1.
+	  Say Y here if this is msm7627A variant platform.
+
+config MSM_CAMERA_FLASH_SC628A
+	bool "Qualcomm MSM camera sc628a flash support"
+	depends on MSM_CAMERA
+	default n
+	---help---
+	  Enable support for LED flash for msm camera.
+	  It is a samtech charge pump flash driver and it
+	  supports spotlight and flash light modes with
+	  differrent current levels.
+
+config MSM_CAMERA_FLASH_TPS61310
+	bool "Qualcomm MSM camera tps61310 flash support"
+	depends on MSM_CAMERA
+	default n
+	---help---
+	  Enable support for LED flash for msm camera.
+	  It is a Texas Instruments multiple LED Flash
+	  for camera flash and video light applications.
+
+config MSM_CAMERA_LED_TRIGGER_FLASH
+	bool "Qualcomm MSM LED trigger flash support"
+	depends on MSM_CAMERA
+	default n
+	---help---
+	  Enable support for LED flash for msm camera.
+	  It creates LED trigger client, reads LED flash
+	  hardware properties provided in board file /
+	  device tree and uses these information to configure
+	  LED flash using LED trigger event function.
+
+config IMX072
+	bool "Sensor imx072 (Sony 5M)"
+	default n
+	---help---
+	  Support for IMX072 sony sensor driver.
+	  It is a Bayer 5MP sensor with auto focus and it supports
+	  two mipi lanes, required for msm7x2xA platform.
+	  Say Y here if this is msm7x2xA variant platform.
+
+config OV2720
+	bool "Sensor ov2720 (Omnivision 2MP)"
+	depends on MSM_CAMERA
+
+config OV8825
+	bool "Sensor ov8825 (Omnivision 8M)"
+	depends on MSM_CAMERA
+	---help---
+	  Support for OV8825 sensor driver.
+	  It is a Bayer 8MP sensor with auto focus and it supports
+	  two mipi lanes, required for msm8625 platform.
+	  Say Y here if this is msm8625 variant platform.
+
+config IMX135
+	bool "Sensor imx135 (Sony 13MP)"
+	depends on MSM_CAMERA
+	---help---
+	  Support for IMX135 sensor driver.
+	  This is a Sony 13MP Bayer Sensor with autofocus and video HDR
+	  support.
+	  Say Y if the platform uses IMX135 sensor.
+
+config VB6801
+	bool "Sensor vb6801"
+	depends on MSM_CAMERA && !ARCH_MSM8X60 && !MSM_CAMERA_V4L2
+	---help---
+	  5M with flash
+
+config MSM_CAMERA_FLASH
+	bool "Qualcomm MSM camera flash support"
+	depends on MSM_CAMERA
+	default y
+	---help---
+	  Enable support for LED flash for msm camera
+
+config MSM_CAMERA_SENSOR
+	bool "Qualcomm MSM camera sensor support"
+	depends on MSM_CAMERA
+
+config MSM_ACTUATOR
+	bool "Qualcomm MSM actuator support"
+	depends on MSM_CAMERA
+
+config MSM_EEPROM
+	bool "Qualcomm MSM EEPROM support"
+	depends on MSM_CAMERA
+
+config IMX074_EEPROM
+	bool "IMX074 EEPROM support"
+	depends on MSM_CAMERA
+
+config IMX091_EEPROM
+	bool "IMX091 EEPROM support"
+	depends on MSM_CAMERA
+
+config MSM_GEMINI
+	tristate "Qualcomm MSM Gemini Jpeg Engine support"
+	depends on MSM_CAMERA && (ARCH_MSM7X30 || ARCH_MSM8X60 || ARCH_MSM8960)
+	default n
+	---help---
+	  Enable support for Gemini Jpeg Engine
+
+config MSM_MERCURY
+        tristate "Qualcomm MSM Mercury Jpeg Decoder Engine support"
+        depends on MSM_CAMERA && ARCH_MSM8960
+        ---help---
+          Enable support for Mercury Jpeg Engine
+
+config MSM_VPE
+	tristate "Qualcomm MSM Video Pre-processing Engine support"
+	depends on MSM_CAMERA && (ARCH_MSM7X30 || ARCH_MSM8X60)
+	default y
+	---help---
+	  Enable support for Video Pre-processing Engine
+
+config MSM_CAM_IRQ_ROUTER
+	bool "Enable MSM CAM IRQ Router"
+	depends on MSM_CAMERA
+	---help---
+	Enable IRQ Router for Camera. Depending on the
+	configuration, this module can handle the
+	interrupts from multiple camera hardware
+	cores and composite them into a single
+	interrupt to the MSM.
+
+config MSM_CPP
+        bool "Qualcomm MSM Camera Post Processing Engine support"
+        depends on MSM_CAMERA && MSM_CAMERA_V4L2
+        ---help---
+          Enable support for Camera Post-processing Engine
+          The Post processing engine is capable of scaling
+          and cropping image. The driver support V4L2 subdev
+          APIs.
+
+config MSM_CCI
+        bool "Qualcomm MSM Camera Control Interface support"
+        depends on MSM_CAMERA
+        ---help---
+          Enable support for Camera Control Interface driver only
+          for those platforms that have hardware support. This driver
+          is responsible for handling I2C read and write on the I2C
+          bus. It is also responsible for synchronization with
+          GPIO and data frames.
+
+config QUP_EXCLUSIVE_TO_CAMERA
+	bool "QUP exclusive to camera"
+	depends on MSM_CAMERA
+	default y
+	---help---
+	  This flag enabled states that QUP
+	  is exclusive to camera. In case this
+	  is disabled, the lvs1 voltage is enabled
+	  by QUP in the board file as QUP is used by
+	  applications other than camera.
+
+config MSM_CSI20_HEADER
+        bool "Qualcomm MSM CSI 2.0 Header"
+        depends on MSM_CAMERA
+        ---help---
+          Enable support for CSI drivers to include 2.0
+          header. This header has register macros and its
+          values and bit mask for register configuration bits
+          This config macro is required targets based on 8960,
+          8930 and 8064 platforms.
+
+config MSM_CSI30_HEADER
+        bool "Qualcomm MSM CSI 3.0 Header"
+        depends on MSM_CAMERA
+        ---help---
+          Enable support for CSI drivers to include 3.0
+          header. This header has register macros and its
+          values and bit mask for register configuration bits
+          This config macro is required for targets based on
+          8064 platforms.
+
+config MSM_CSIPHY
+        bool "Qualcomm MSM Camera Serial Interface Physical receiver support"
+        depends on MSM_CAMERA
+        ---help---
+          Enable support for Camera Serial Interface
+          Physical receiver. It deserializes packets and
+          supports detection of packet start and stop
+          signalling.
+
+config MSM_CSID
+        bool "Qualcomm MSM Camera Serial Interface decoder support"
+        depends on MSM_CAMERA
+        ---help---
+          Enable support for Camera Serial Interface decoder.
+          It supports lane merging and decoding of packets
+          based on cid which is mapped to a virtual channel
+          and datatype.
+
+config MSM_CSI2_REGISTER
+        bool "Qualcomm MSM CSI2 Register"
+        depends on MSM_CAMERA
+        ---help---
+          Register CSIPHY, CSID and ISPIF subdevices during
+          msm_open. Different CSI components are registered
+          based on platform. This macro specifies registering
+          of CSIPHY, CSID and ISPIF subdevices to receive data
+          from sensor.
+
+config MSM_ISPIF
+        bool "Qualcomm MSM Image Signal Processing interface support"
+        depends on MSM_CAMERA
+        ---help---
+          Enable support for Image Signal Processing interface module.
+          This module acts as a crossbar between CSID and VFE. Output
+          of any CID of CSID can be routed to of of pixel or raw
+          data interface in VFE.
+
+config S5K3L1YX
+	bool "Sensor S5K3L1YX (BAYER 12M)"
+	depends on MSM_CAMERA
+	---help---
+		Samsung 12 MP Bayer Sensor with auto focus, uses
+		4 mipi lanes, preview config = 1984 * 1508 at 30 fps,
+		snapshot config = 4000 * 3000 at 20 fps,
+		hfr video at 60, 90 and 120 fps.
+
+config IMX091
+        bool "Sensor imx091 (Sony 13MP)"
+        depends on MSM_CAMERA
+	---help---
+	  Sony 13MP sensor back camera that uses 4 mipi lanes,
+	  runs at 30 fps preview and 14 fps snapshot
+
+config MSM_V4L2_VIDEO_OVERLAY_DEVICE
+	tristate "Qualcomm MSM V4l2 video overlay device"
+	---help---
+	  Enables support for the MSM V4L2 video
+	  overlay driver. This allows video rendering
+	  apps to render overlaid video using Video4Linux2
+	  APIs, by using /dev/videoX device
+
+config OV7692
+	bool "Sensor OV7692 (VGA YUV)"
+	depends on MSM_CAMERA
+	---help---
+	  Omni Vision VGA YUV Sensor
diff --git a/drivers/media/platform/msm/camera_v1/Makefile b/drivers/media/platform/msm/camera_v1/Makefile
new file mode 100644
index 0000000..eb66b29
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/Makefile
@@ -0,0 +1,59 @@
+GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
+
+ccflags-y += -Idrivers/media/platform/msm/camera_v1/io
+ccflags-y += -Idrivers/media/platform/msm/camera_v1/vfe
+obj-$(CONFIG_MSM_CAMERA) += io/
+ifeq ($(CONFIG_MSM_CAMERA_V4L2),y)
+  EXTRA_CFLAGS += -Idrivers/media/platform/msm/camera_v1/cci
+  EXTRA_CFLAGS += -Idrivers/media/platform/msm/camera_v1/csi
+  EXTRA_CFLAGS += -Idrivers/media/platform/msm/camera_v1/eeprom
+  EXTRA_CFLAGS += -Idrivers/media/platform/msm/camera_v1/sensors
+  EXTRA_CFLAGS += -Idrivers/media/platform/msm/camera_v1/actuators
+  EXTRA_CFLAGS += -Idrivers/media/platform/msm/camera_v1/server
+  EXTRA_CFLAGS += -Idrivers/media/platform/msm/camera_v1/flash
+  obj-$(CONFIG_MSM_CAMERA) += msm_isp.o msm.o msm_mem.o msm_mctl.o msm_mctl_buf.o msm_mctl_pp.o
+  obj-$(CONFIG_MSM_CAMERA) += server/
+  obj-$(CONFIG_MSM_CAM_IRQ_ROUTER) += msm_camirq_router.o
+  obj-$(CONFIG_MSM_CAMERA) += cci/ eeprom/ sensors/ actuators/ csi/
+  obj-$(CONFIG_MSM_CPP) += cpp/
+  obj-$(CONFIG_MSM_CAMERA) += msm_gesture.o
+  obj-$(CONFIG_MSM_CAMERA) += flash/
+else
+  obj-$(CONFIG_MSM_CAMERA) += msm_camera.o
+endif
+obj-$(CONFIG_MSM_CAMERA) += vfe/
+obj-$(CONFIG_MSM_CAMERA) += msm_axi_qos.o gemini/ mercury/
+ifeq ($(CONFIG_MSM_CAMERA_V4L2),y)
+  obj-$(CONFIG_ARCH_MSM8X60) += msm_vpe.o
+  obj-$(CONFIG_ARCH_MSM7X30) += msm_vpe.o msm_axi_qos.o
+else
+  obj-$(CONFIG_ARCH_MSM8X60) += msm_vpe1.o
+  obj-$(CONFIG_ARCH_MSM7X30) += msm_vpe1.o
+endif
+obj-$(CONFIG_ARCH_MSM8960) += msm_vpe.o
+obj-$(CONFIG_MT9T013) += mt9t013.o mt9t013_reg.o
+obj-$(CONFIG_SN12M0PZ) += sn12m0pz.o sn12m0pz_reg.o
+obj-$(CONFIG_MT9P012) += mt9p012_reg.o
+obj-$(CONFIG_MSM_CAMERA_AF_FOXCONN) += mt9p012_fox.o
+obj-$(CONFIG_MSM_CAMERA_AF_BAM) += mt9p012_bam.o
+obj-$(CONFIG_MT9P012_KM) += mt9p012_km.o mt9p012_km_reg.o
+obj-$(CONFIG_S5K3E2FX) += s5k3e2fx.o
+#FIXME: Merge the two ifeq causes VX6953 preview not coming up.
+ifneq ($(CONFIG_MSM_CAMERA_V4L2),y)
+  obj-$(CONFIG_VX6953) += vx6953.o vx6953_reg.o
+  obj-$(CONFIG_IMX074) += imx074.o imx074_reg.o
+  obj-$(CONFIG_MT9E013) += mt9e013.o mt9e013_reg.o
+  obj-$(CONFIG_WEBCAM_OV9726) += ov9726.o ov9726_reg.o
+  obj-$(CONFIG_OV5647) += ov5647.o ov5647_reg.o
+  obj-$(CONFIG_S5K4E1) += s5k4e1.o s5k4e1_reg.o
+  obj-$(CONFIG_WEBCAM_OV7692) += ov7692.o
+  obj-$(CONFIG_WEBCAM_OV7692_QRD) += ov7692_qrd.o
+endif
+obj-$(CONFIG_QS_S5K4E1) += qs_s5k4e1.o qs_s5k4e1_reg.o
+obj-$(CONFIG_VB6801) += vb6801.o
+obj-$(CONFIG_IMX072) += imx072.o imx072_reg.o
+obj-$(CONFIG_OV5640) += ov5640.o
+obj-$(CONFIG_MT9D112) += mt9d112.o mt9d112_reg.o
+
+obj-$(CONFIG_MT9D113) += mt9d113.o mt9d113_reg.o
+obj-$(CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE) += msm_v4l2_video.o
diff --git a/drivers/media/platform/msm/camera_v1/actuators/Makefile b/drivers/media/platform/msm/camera_v1/actuators/Makefile
new file mode 100644
index 0000000..95713a1
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/actuators/Makefile
@@ -0,0 +1,4 @@
+GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
+EXTRA_CFLAGS += -Idrivers/media/platform/msm/camera_v1
+EXTRA_CFLAGS += -Idrivers/media/platform/msm/camera_v1/io
+obj-$(CONFIG_MSM_ACTUATOR) += msm_actuator.o
diff --git a/drivers/media/platform/msm/camera_v1/actuators/msm_actuator.c b/drivers/media/platform/msm/camera_v1/actuators/msm_actuator.c
new file mode 100644
index 0000000..29a4866
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/actuators/msm_actuator.c
@@ -0,0 +1,692 @@
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include "msm_actuator.h"
+
+static struct msm_actuator_ctrl_t msm_actuator_t;
+static struct msm_actuator msm_vcm_actuator_table;
+static struct msm_actuator msm_piezo_actuator_table;
+
+static struct msm_actuator *actuators[] = {
+	&msm_vcm_actuator_table,
+	&msm_piezo_actuator_table,
+};
+
+static int32_t msm_actuator_piezo_set_default_focus(
+	struct msm_actuator_ctrl_t *a_ctrl,
+	struct msm_actuator_move_params_t *move_params)
+{
+	int32_t rc = 0;
+
+	if (a_ctrl->curr_step_pos != 0) {
+		a_ctrl->i2c_tbl_index = 0;
+		rc = a_ctrl->func_tbl->actuator_parse_i2c_params(a_ctrl,
+			a_ctrl->initial_code, 0, 0);
+		rc = a_ctrl->func_tbl->actuator_parse_i2c_params(a_ctrl,
+			a_ctrl->initial_code, 0, 0);
+		rc = msm_camera_i2c_write_table_w_microdelay(
+			&a_ctrl->i2c_client, a_ctrl->i2c_reg_tbl,
+			a_ctrl->i2c_tbl_index, a_ctrl->i2c_data_type);
+		if (rc < 0) {
+			pr_err("%s: i2c write error:%d\n",
+				__func__, rc);
+			return rc;
+		}
+		a_ctrl->i2c_tbl_index = 0;
+		a_ctrl->curr_step_pos = 0;
+	}
+	return rc;
+}
+
+static int32_t msm_actuator_parse_i2c_params(struct msm_actuator_ctrl_t *a_ctrl,
+	int16_t next_lens_position, uint32_t hw_params, uint16_t delay)
+{
+	struct msm_actuator_reg_params_t *write_arr = a_ctrl->reg_tbl;
+	uint32_t hw_dword = hw_params;
+	uint16_t i2c_byte1 = 0, i2c_byte2 = 0;
+	uint16_t value = 0;
+	uint32_t size = a_ctrl->reg_tbl_size, i = 0;
+	int32_t rc = 0;
+	struct msm_camera_i2c_reg_tbl *i2c_tbl = a_ctrl->i2c_reg_tbl;
+	CDBG("%s: IN\n", __func__);
+	for (i = 0; i < size; i++) {
+		if (write_arr[i].reg_write_type == MSM_ACTUATOR_WRITE_DAC) {
+			value = (next_lens_position <<
+				write_arr[i].data_shift) |
+				((hw_dword & write_arr[i].hw_mask) >>
+				write_arr[i].hw_shift);
+
+			if (write_arr[i].reg_addr != 0xFFFF) {
+				i2c_byte1 = write_arr[i].reg_addr;
+				i2c_byte2 = value;
+				if (size != (i+1)) {
+					i2c_byte2 = value & 0xFF;
+					CDBG("%s: byte1:0x%x, byte2:0x%x\n",
+					__func__, i2c_byte1, i2c_byte2);
+					i2c_tbl[a_ctrl->i2c_tbl_index].
+						reg_addr = i2c_byte1;
+					i2c_tbl[a_ctrl->i2c_tbl_index].
+						reg_data = i2c_byte2;
+					i2c_tbl[a_ctrl->i2c_tbl_index].
+						delay = 0;
+					a_ctrl->i2c_tbl_index++;
+					i++;
+					i2c_byte1 = write_arr[i].reg_addr;
+					i2c_byte2 = (value & 0xFF00) >> 8;
+				}
+			} else {
+				i2c_byte1 = (value & 0xFF00) >> 8;
+				i2c_byte2 = value & 0xFF;
+			}
+		} else {
+			i2c_byte1 = write_arr[i].reg_addr;
+			i2c_byte2 = (hw_dword & write_arr[i].hw_mask) >>
+				write_arr[i].hw_shift;
+		}
+		CDBG("%s: i2c_byte1:0x%x, i2c_byte2:0x%x\n", __func__,
+			i2c_byte1, i2c_byte2);
+		i2c_tbl[a_ctrl->i2c_tbl_index].reg_addr = i2c_byte1;
+		i2c_tbl[a_ctrl->i2c_tbl_index].reg_data = i2c_byte2;
+		i2c_tbl[a_ctrl->i2c_tbl_index].delay = delay;
+		a_ctrl->i2c_tbl_index++;
+	}
+		CDBG("%s: OUT\n", __func__);
+	return rc;
+}
+
+static int32_t msm_actuator_init_focus(struct msm_actuator_ctrl_t *a_ctrl,
+	uint16_t size, enum msm_actuator_data_type type,
+	struct reg_settings_t *settings)
+{
+	int32_t rc = -EFAULT;
+	int32_t i = 0;
+	CDBG("%s called\n", __func__);
+
+	for (i = 0; i < size; i++) {
+		switch (type) {
+		case MSM_ACTUATOR_BYTE_DATA:
+			rc = msm_camera_i2c_write(
+				&a_ctrl->i2c_client,
+				settings[i].reg_addr,
+				settings[i].reg_data, MSM_CAMERA_I2C_BYTE_DATA);
+			break;
+		case MSM_ACTUATOR_WORD_DATA:
+			rc = msm_camera_i2c_write(
+				&a_ctrl->i2c_client,
+				settings[i].reg_addr,
+				settings[i].reg_data, MSM_CAMERA_I2C_WORD_DATA);
+			break;
+		default:
+			pr_err("%s: Unsupport data type: %d\n",
+				__func__, type);
+			break;
+		}
+		if (rc < 0)
+			break;
+	}
+
+	a_ctrl->curr_step_pos = 0;
+	CDBG("%s Exit:%d\n", __func__, rc);
+	return rc;
+}
+
+static int32_t msm_actuator_write_focus(
+	struct msm_actuator_ctrl_t *a_ctrl,
+	uint16_t curr_lens_pos,
+	struct damping_params_t *damping_params,
+	int8_t sign_direction,
+	int16_t code_boundary)
+{
+	int32_t rc = 0;
+	int16_t next_lens_pos = 0;
+	uint16_t damping_code_step = 0;
+	uint16_t wait_time = 0;
+
+	damping_code_step = damping_params->damping_step;
+	wait_time = damping_params->damping_delay;
+
+	/* Write code based on damping_code_step in a loop */
+	for (next_lens_pos =
+		curr_lens_pos + (sign_direction * damping_code_step);
+		(sign_direction * next_lens_pos) <=
+			(sign_direction * code_boundary);
+		next_lens_pos =
+			(next_lens_pos +
+				(sign_direction * damping_code_step))) {
+		rc = a_ctrl->func_tbl->
+			actuator_parse_i2c_params(a_ctrl, next_lens_pos,
+				damping_params->hw_params, wait_time);
+		if (rc < 0) {
+			pr_err("%s: error:%d\n",
+				__func__, rc);
+			return rc;
+		}
+		curr_lens_pos = next_lens_pos;
+	}
+
+	if (curr_lens_pos != code_boundary) {
+		rc = a_ctrl->func_tbl->
+			actuator_parse_i2c_params(a_ctrl, code_boundary,
+				damping_params->hw_params, wait_time);
+	}
+	return rc;
+}
+
+static int32_t msm_actuator_piezo_move_focus(
+	struct msm_actuator_ctrl_t *a_ctrl,
+	struct msm_actuator_move_params_t *move_params)
+{
+	int32_t dest_step_position = move_params->dest_step_pos;
+	int32_t rc = 0;
+	int32_t num_steps = move_params->num_steps;
+
+	if (num_steps == 0)
+		return rc;
+
+	a_ctrl->i2c_tbl_index = 0;
+	rc = a_ctrl->func_tbl->
+		actuator_parse_i2c_params(a_ctrl,
+		(num_steps *
+		a_ctrl->region_params[0].code_per_step),
+		move_params->ringing_params[0].hw_params, 0);
+
+	rc = msm_camera_i2c_write_table_w_microdelay(&a_ctrl->i2c_client,
+		a_ctrl->i2c_reg_tbl, a_ctrl->i2c_tbl_index,
+		a_ctrl->i2c_data_type);
+	if (rc < 0) {
+		pr_err("%s: i2c write error:%d\n",
+			__func__, rc);
+		return rc;
+	}
+	a_ctrl->i2c_tbl_index = 0;
+	a_ctrl->curr_step_pos = dest_step_position;
+	return rc;
+}
+
+static int32_t msm_actuator_move_focus(
+	struct msm_actuator_ctrl_t *a_ctrl,
+	struct msm_actuator_move_params_t *move_params)
+{
+	int32_t rc = 0;
+	int8_t sign_dir = move_params->sign_dir;
+	uint16_t step_boundary = 0;
+	uint16_t target_step_pos = 0;
+	uint16_t target_lens_pos = 0;
+	int16_t dest_step_pos = move_params->dest_step_pos;
+	uint16_t curr_lens_pos = 0;
+	int dir = move_params->dir;
+	int32_t num_steps = move_params->num_steps;
+
+	CDBG("%s called, dir %d, num_steps %d\n",
+		__func__,
+		dir,
+		num_steps);
+
+	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);
+
+	while (a_ctrl->curr_step_pos != dest_step_pos) {
+		step_boundary =
+			a_ctrl->region_params[a_ctrl->curr_region_index].
+			step_bound[dir];
+		if ((dest_step_pos * sign_dir) <=
+			(step_boundary * sign_dir)) {
+
+			target_step_pos = dest_step_pos;
+			target_lens_pos =
+				a_ctrl->step_position_table[target_step_pos];
+			rc = a_ctrl->func_tbl->
+				actuator_write_focus(
+					a_ctrl,
+					curr_lens_pos,
+					&(move_params->
+						ringing_params[a_ctrl->
+						curr_region_index]),
+					sign_dir,
+					target_lens_pos);
+			if (rc < 0) {
+				pr_err("%s: error:%d\n",
+					__func__, rc);
+				return rc;
+			}
+			curr_lens_pos = target_lens_pos;
+
+		} else {
+			target_step_pos = step_boundary;
+			target_lens_pos =
+				a_ctrl->step_position_table[target_step_pos];
+			rc = a_ctrl->func_tbl->
+				actuator_write_focus(
+					a_ctrl,
+					curr_lens_pos,
+					&(move_params->
+						ringing_params[a_ctrl->
+						curr_region_index]),
+					sign_dir,
+					target_lens_pos);
+			if (rc < 0) {
+				pr_err("%s: error:%d\n",
+					__func__, rc);
+				return rc;
+			}
+			curr_lens_pos = target_lens_pos;
+
+			a_ctrl->curr_region_index += sign_dir;
+		}
+		a_ctrl->curr_step_pos = target_step_pos;
+	}
+
+	rc = msm_camera_i2c_write_table_w_microdelay(&a_ctrl->i2c_client,
+		a_ctrl->i2c_reg_tbl, a_ctrl->i2c_tbl_index,
+		a_ctrl->i2c_data_type);
+	if (rc < 0) {
+		pr_err("%s: i2c write error:%d\n",
+			__func__, rc);
+		return rc;
+	}
+	a_ctrl->i2c_tbl_index = 0;
+
+	return rc;
+}
+
+static int32_t msm_actuator_init_step_table(struct msm_actuator_ctrl_t *a_ctrl,
+	struct msm_actuator_set_info_t *set_info)
+{
+	int16_t code_per_step = 0;
+	int32_t rc = 0;
+	int16_t cur_code = 0;
+	int16_t step_index = 0, region_index = 0;
+	uint16_t step_boundary = 0;
+	uint32_t max_code_size = 1;
+	uint16_t data_size = set_info->actuator_params.data_size;
+	CDBG("%s called\n", __func__);
+
+	for (; data_size > 0; data_size--)
+		max_code_size *= 2;
+
+	kfree(a_ctrl->step_position_table);
+	a_ctrl->step_position_table = NULL;
+
+	/* Fill step position table */
+	a_ctrl->step_position_table =
+		kmalloc(sizeof(uint16_t) *
+		(set_info->af_tuning_params.total_steps + 1), GFP_KERNEL);
+
+	if (a_ctrl->step_position_table == NULL)
+		return -EFAULT;
+
+	cur_code = set_info->af_tuning_params.initial_code;
+	a_ctrl->step_position_table[step_index++] = cur_code;
+	for (region_index = 0;
+		region_index < a_ctrl->region_size;
+		region_index++) {
+		code_per_step =
+			a_ctrl->region_params[region_index].code_per_step;
+		step_boundary =
+			a_ctrl->region_params[region_index].
+			step_bound[MOVE_NEAR];
+		for (; step_index <= step_boundary;
+			step_index++) {
+			cur_code += code_per_step;
+			if (cur_code < max_code_size)
+				a_ctrl->step_position_table[step_index] =
+					cur_code;
+			else {
+				for (; step_index <
+					set_info->af_tuning_params.total_steps;
+					step_index++)
+					a_ctrl->
+						step_position_table[
+						step_index] =
+						max_code_size;
+
+				return rc;
+			}
+		}
+	}
+
+	return rc;
+}
+
+static int32_t msm_actuator_set_default_focus(
+	struct msm_actuator_ctrl_t *a_ctrl,
+	struct msm_actuator_move_params_t *move_params)
+{
+	int32_t rc = 0;
+	CDBG("%s called\n", __func__);
+
+	if (a_ctrl->curr_step_pos != 0)
+		rc = a_ctrl->func_tbl->actuator_move_focus(a_ctrl, move_params);
+	return rc;
+}
+
+static int32_t msm_actuator_power_down(struct msm_actuator_ctrl_t *a_ctrl)
+{
+	int32_t rc = 0;
+	if (a_ctrl->vcm_enable) {
+		rc = gpio_direction_output(a_ctrl->vcm_pwd, 0);
+		if (!rc)
+			gpio_free(a_ctrl->vcm_pwd);
+	}
+
+	kfree(a_ctrl->step_position_table);
+	a_ctrl->step_position_table = NULL;
+	kfree(a_ctrl->i2c_reg_tbl);
+	a_ctrl->i2c_reg_tbl = NULL;
+	a_ctrl->i2c_tbl_index = 0;
+	return rc;
+}
+
+static int32_t msm_actuator_init(struct msm_actuator_ctrl_t *a_ctrl,
+	struct msm_actuator_set_info_t *set_info) {
+	struct reg_settings_t *init_settings = NULL;
+	int32_t rc = -EFAULT;
+	uint16_t i = 0;
+	CDBG("%s: IN\n", __func__);
+
+	for (i = 0; i < ARRAY_SIZE(actuators); i++) {
+		if (set_info->actuator_params.act_type ==
+			actuators[i]->act_type) {
+			a_ctrl->func_tbl = &actuators[i]->func_tbl;
+			rc = 0;
+		}
+	}
+
+	if (rc < 0) {
+		pr_err("%s: Actuator function table not found\n", __func__);
+		return rc;
+	}
+
+	a_ctrl->region_size = set_info->af_tuning_params.region_size;
+	if (a_ctrl->region_size > MAX_ACTUATOR_REGION) {
+		pr_err("%s: MAX_ACTUATOR_REGION is exceeded.\n", __func__);
+		return -EFAULT;
+	}
+	a_ctrl->pwd_step = set_info->af_tuning_params.pwd_step;
+	a_ctrl->total_steps = set_info->af_tuning_params.total_steps;
+
+	if (copy_from_user(&a_ctrl->region_params,
+		(void *)set_info->af_tuning_params.region_params,
+		a_ctrl->region_size * sizeof(struct region_params_t)))
+		return -EFAULT;
+
+	a_ctrl->i2c_data_type = set_info->actuator_params.i2c_data_type;
+	a_ctrl->i2c_client.client->addr = set_info->actuator_params.i2c_addr;
+	a_ctrl->i2c_client.addr_type = set_info->actuator_params.i2c_addr_type;
+	a_ctrl->reg_tbl_size = set_info->actuator_params.reg_tbl_size;
+	if (a_ctrl->reg_tbl_size > MAX_ACTUATOR_REG_TBL_SIZE) {
+		pr_err("%s: MAX_ACTUATOR_REG_TBL_SIZE is exceeded.\n",
+			__func__);
+		return -EFAULT;
+	}
+
+	a_ctrl->i2c_reg_tbl =
+		kmalloc(sizeof(struct msm_camera_i2c_reg_tbl) *
+		(set_info->af_tuning_params.total_steps + 1), GFP_KERNEL);
+	if (!a_ctrl->i2c_reg_tbl) {
+		pr_err("%s kmalloc fail\n", __func__);
+		return -EFAULT;
+	}
+
+	if (copy_from_user(&a_ctrl->reg_tbl,
+		(void *)set_info->actuator_params.reg_tbl_params,
+		a_ctrl->reg_tbl_size *
+		sizeof(struct msm_actuator_reg_params_t))) {
+		kfree(a_ctrl->i2c_reg_tbl);
+		return -EFAULT;
+	}
+
+	if (set_info->actuator_params.init_setting_size) {
+		if (a_ctrl->func_tbl->actuator_init_focus) {
+			init_settings = kmalloc(sizeof(struct reg_settings_t) *
+				(set_info->actuator_params.init_setting_size),
+				GFP_KERNEL);
+			if (init_settings == NULL) {
+				kfree(a_ctrl->i2c_reg_tbl);
+				pr_err("%s Error allocating memory for init_settings\n",
+					__func__);
+				return -EFAULT;
+			}
+			if (copy_from_user(init_settings,
+				(void *)set_info->actuator_params.init_settings,
+				set_info->actuator_params.init_setting_size *
+				sizeof(struct reg_settings_t))) {
+				kfree(init_settings);
+				kfree(a_ctrl->i2c_reg_tbl);
+				pr_err("%s Error copying init_settings\n",
+					__func__);
+				return -EFAULT;
+			}
+			rc = a_ctrl->func_tbl->actuator_init_focus(a_ctrl,
+				set_info->actuator_params.init_setting_size,
+				a_ctrl->i2c_data_type,
+				init_settings);
+			kfree(init_settings);
+			if (rc < 0) {
+				kfree(a_ctrl->i2c_reg_tbl);
+				pr_err("%s Error actuator_init_focus\n",
+					__func__);
+				return -EFAULT;
+			}
+		}
+	}
+
+	a_ctrl->initial_code = set_info->af_tuning_params.initial_code;
+	if (a_ctrl->func_tbl->actuator_init_step_table)
+		rc = a_ctrl->func_tbl->
+			actuator_init_step_table(a_ctrl, set_info);
+
+	a_ctrl->curr_step_pos = 0;
+	a_ctrl->curr_region_index = 0;
+
+	return rc;
+}
+
+
+static int32_t msm_actuator_config(struct msm_actuator_ctrl_t *a_ctrl,
+							void __user *argp)
+{
+	struct msm_actuator_cfg_data cdata;
+	int32_t rc = 0;
+	if (copy_from_user(&cdata,
+		(void *)argp,
+		sizeof(struct msm_actuator_cfg_data)))
+		return -EFAULT;
+	mutex_lock(a_ctrl->actuator_mutex);
+	CDBG("%s called, type %d\n", __func__, cdata.cfgtype);
+	switch (cdata.cfgtype) {
+	case CFG_SET_ACTUATOR_INFO:
+		rc = msm_actuator_init(a_ctrl, &cdata.cfg.set_info);
+		if (rc < 0)
+			pr_err("%s init table failed %d\n", __func__, rc);
+		break;
+
+	case CFG_SET_DEFAULT_FOCUS:
+		rc = a_ctrl->func_tbl->actuator_set_default_focus(a_ctrl,
+			&cdata.cfg.move);
+		if (rc < 0)
+			pr_err("%s move focus failed %d\n", __func__, rc);
+		break;
+
+	case CFG_MOVE_FOCUS:
+		rc = a_ctrl->func_tbl->actuator_move_focus(a_ctrl,
+			&cdata.cfg.move);
+		if (rc < 0)
+			pr_err("%s move focus failed %d\n", __func__, rc);
+		break;
+
+	default:
+		break;
+	}
+	mutex_unlock(a_ctrl->actuator_mutex);
+	return rc;
+}
+
+static int32_t msm_actuator_i2c_probe(
+	struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+	struct msm_actuator_ctrl_t *act_ctrl_t = NULL;
+	CDBG("%s called\n", __func__);
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		pr_err("i2c_check_functionality failed\n");
+		goto probe_failure;
+	}
+
+	act_ctrl_t = (struct msm_actuator_ctrl_t *)(id->driver_data);
+	CDBG("%s client = %x\n",
+		__func__, (unsigned int) client);
+	act_ctrl_t->i2c_client.client = client;
+
+	/* Assign name for sub device */
+	snprintf(act_ctrl_t->sdev.name, sizeof(act_ctrl_t->sdev.name),
+			 "%s", act_ctrl_t->i2c_driver->driver.name);
+
+	/* Initialize sub device */
+	v4l2_i2c_subdev_init(&act_ctrl_t->sdev,
+		act_ctrl_t->i2c_client.client,
+		act_ctrl_t->act_v4l2_subdev_ops);
+
+	CDBG("%s succeeded\n", __func__);
+	return rc;
+
+probe_failure:
+	pr_err("%s failed! rc = %d\n", __func__, rc);
+	return rc;
+}
+
+static int32_t msm_actuator_power_up(struct msm_actuator_ctrl_t *a_ctrl)
+{
+	int rc = 0;
+	CDBG("%s called\n", __func__);
+
+	CDBG("vcm info: %x %x\n", a_ctrl->vcm_pwd,
+		a_ctrl->vcm_enable);
+	if (a_ctrl->vcm_enable) {
+		rc = gpio_request(a_ctrl->vcm_pwd, "msm_actuator");
+		if (!rc) {
+			CDBG("Enable VCM PWD\n");
+			gpio_direction_output(a_ctrl->vcm_pwd, 1);
+		}
+	}
+	return rc;
+}
+
+DEFINE_MUTEX(msm_actuator_mutex);
+
+static const struct i2c_device_id msm_actuator_i2c_id[] = {
+	{"msm_actuator", (kernel_ulong_t)&msm_actuator_t},
+	{ }
+};
+
+static struct i2c_driver msm_actuator_i2c_driver = {
+	.id_table = msm_actuator_i2c_id,
+	.probe  = msm_actuator_i2c_probe,
+	.remove = __exit_p(msm_actuator_i2c_remove),
+	.driver = {
+		.name = "msm_actuator",
+	},
+};
+
+static int __init msm_actuator_i2c_add_driver(
+	void)
+{
+	CDBG("%s called\n", __func__);
+	return i2c_add_driver(msm_actuator_t.i2c_driver);
+}
+
+static long msm_actuator_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int cmd, void *arg)
+{
+	struct msm_actuator_ctrl_t *a_ctrl = get_actrl(sd);
+	void __user *argp = (void __user *)arg;
+	switch (cmd) {
+	case VIDIOC_MSM_ACTUATOR_CFG:
+		return msm_actuator_config(a_ctrl, argp);
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
+static int32_t msm_actuator_power(struct v4l2_subdev *sd, int on)
+{
+	int rc = 0;
+	struct msm_actuator_ctrl_t *a_ctrl = get_actrl(sd);
+	mutex_lock(a_ctrl->actuator_mutex);
+	if (on)
+		rc = msm_actuator_power_up(a_ctrl);
+	else
+		rc = msm_actuator_power_down(a_ctrl);
+	mutex_unlock(a_ctrl->actuator_mutex);
+	return rc;
+}
+
+struct msm_actuator_ctrl_t *get_actrl(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct msm_actuator_ctrl_t, sdev);
+}
+
+static struct v4l2_subdev_core_ops msm_actuator_subdev_core_ops = {
+	.ioctl = msm_actuator_subdev_ioctl,
+	.s_power = msm_actuator_power,
+};
+
+static struct v4l2_subdev_ops msm_actuator_subdev_ops = {
+	.core = &msm_actuator_subdev_core_ops,
+};
+
+static struct msm_actuator_ctrl_t msm_actuator_t = {
+	.i2c_driver = &msm_actuator_i2c_driver,
+	.act_v4l2_subdev_ops = &msm_actuator_subdev_ops,
+
+	.curr_step_pos = 0,
+	.curr_region_index = 0,
+	.actuator_mutex = &msm_actuator_mutex,
+
+};
+
+static struct msm_actuator msm_vcm_actuator_table = {
+	.act_type = ACTUATOR_VCM,
+	.func_tbl = {
+		.actuator_init_step_table = msm_actuator_init_step_table,
+		.actuator_move_focus = msm_actuator_move_focus,
+		.actuator_write_focus = msm_actuator_write_focus,
+		.actuator_set_default_focus = msm_actuator_set_default_focus,
+		.actuator_init_focus = msm_actuator_init_focus,
+		.actuator_parse_i2c_params = msm_actuator_parse_i2c_params,
+	},
+};
+
+static struct msm_actuator msm_piezo_actuator_table = {
+	.act_type = ACTUATOR_PIEZO,
+	.func_tbl = {
+		.actuator_init_step_table = NULL,
+		.actuator_move_focus = msm_actuator_piezo_move_focus,
+		.actuator_write_focus = NULL,
+		.actuator_set_default_focus =
+			msm_actuator_piezo_set_default_focus,
+		.actuator_init_focus = msm_actuator_init_focus,
+		.actuator_parse_i2c_params = msm_actuator_parse_i2c_params,
+	},
+};
+
+subsys_initcall(msm_actuator_i2c_add_driver);
+MODULE_DESCRIPTION("MSM ACTUATOR");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/actuators/msm_actuator.h b/drivers/media/platform/msm/camera_v1/actuators/msm_actuator.h
new file mode 100644
index 0000000..19b71a6
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/actuators/msm_actuator.h
@@ -0,0 +1,99 @@
+/* Copyright (c) 2011-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.
+ */
+#ifndef MSM_ACTUATOR_H
+#define MSM_ACTUATOR_H
+
+#include <linux/i2c.h>
+#include <mach/camera.h>
+#include <mach/gpio.h>
+#include <media/v4l2-subdev.h>
+#include <media/msm_camera.h>
+#include "msm_camera_i2c.h"
+
+#ifdef LERROR
+#undef LERROR
+#endif
+
+#ifdef LINFO
+#undef LINFO
+#endif
+
+#define LERROR(fmt, args...) pr_err(fmt, ##args)
+
+#define CONFIG_MSM_CAMERA_ACT_DBG 0
+
+#if CONFIG_MSM_CAMERA_ACT_DBG
+#define LINFO(fmt, args...) printk(fmt, ##args)
+#else
+#define LINFO(fmt, args...) CDBG(fmt, ##args)
+#endif
+
+struct msm_actuator_ctrl_t;
+
+struct msm_actuator_func_tbl {
+	int32_t (*actuator_i2c_write_b_af)(struct msm_actuator_ctrl_t *,
+			uint8_t,
+			uint8_t);
+	int32_t (*actuator_init_step_table)(struct msm_actuator_ctrl_t *,
+		struct msm_actuator_set_info_t *);
+	int32_t (*actuator_init_focus)(struct msm_actuator_ctrl_t *,
+		uint16_t, enum msm_actuator_data_type, struct reg_settings_t *);
+	int32_t (*actuator_set_default_focus) (struct msm_actuator_ctrl_t *,
+			struct msm_actuator_move_params_t *);
+	int32_t (*actuator_move_focus) (struct msm_actuator_ctrl_t *,
+			struct msm_actuator_move_params_t *);
+	int32_t (*actuator_parse_i2c_params)(struct msm_actuator_ctrl_t *,
+			int16_t, uint32_t, uint16_t);
+	int32_t (*actuator_write_focus)(struct msm_actuator_ctrl_t *,
+			uint16_t,
+			struct damping_params_t *,
+			int8_t,
+			int16_t);
+};
+
+struct msm_actuator {
+	enum actuator_type act_type;
+	struct msm_actuator_func_tbl func_tbl;
+};
+
+struct msm_actuator_ctrl_t {
+	struct i2c_driver *i2c_driver;
+	struct msm_camera_i2c_client i2c_client;
+	struct mutex *actuator_mutex;
+	struct msm_actuator_func_tbl *func_tbl;
+	enum msm_actuator_data_type i2c_data_type;
+	struct v4l2_subdev sdev;
+	struct v4l2_subdev_ops *act_v4l2_subdev_ops;
+
+	int16_t curr_step_pos;
+	uint16_t curr_region_index;
+	uint16_t *step_position_table;
+	struct region_params_t region_params[MAX_ACTUATOR_REGION];
+	uint16_t reg_tbl_size;
+	struct msm_actuator_reg_params_t reg_tbl[MAX_ACTUATOR_REG_TBL_SIZE];
+	uint16_t region_size;
+	void *user_data;
+	uint32_t vcm_pwd;
+	uint32_t vcm_enable;
+	uint32_t total_steps;
+	uint16_t pwd_step;
+	uint16_t initial_code;
+	struct msm_camera_i2c_reg_tbl *i2c_reg_tbl;
+	uint16_t i2c_tbl_index;
+};
+
+struct msm_actuator_ctrl_t *get_actrl(struct v4l2_subdev *sd);
+
+#define VIDIOC_MSM_ACTUATOR_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 11, void __user *)
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v1/cci/Makefile b/drivers/media/platform/msm/camera_v1/cci/Makefile
new file mode 100644
index 0000000..0f23f6c
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/cci/Makefile
@@ -0,0 +1,3 @@
+GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
+ccflags-y += -Idrivers/media/platform/msm/camera_v1 -Idrivers/media/platform/msm/camera_v1/server
+obj-$(CONFIG_MSM_CCI) += msm_cci.o
diff --git a/drivers/media/platform/msm/camera_v1/cci/msm_cam_cci_hwreg.h b/drivers/media/platform/msm/camera_v1/cci/msm_cam_cci_hwreg.h
new file mode 100644
index 0000000..0262eb4
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/cci/msm_cam_cci_hwreg.h
@@ -0,0 +1,60 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MSM_CAM_CCI_HWREG__
+#define __MSM_CAM_CCI_HWREG__
+
+#define CCI_HW_VERSION_ADDR                                         0x00000000
+#define CCI_RESET_CMD_ADDR                                          0x00000004
+#define CCI_RESET_CMD_RMSK                                          0xcf73f3f7
+#define CCI_M0_RESET_RMSK                                                0x3F1
+#define CCI_M1_RESET_RMSK                                              0x3F001
+#define CCI_QUEUE_START_ADDR                                        0x00000008
+#define CCI_SET_CID_SYNC_TIMER_0_ADDR                               0x00000010
+#define CCI_I2C_M0_SCL_CTL_ADDR                                     0x00000100
+#define CCI_I2C_M0_SDA_CTL_0_ADDR                                   0x00000104
+#define CCI_I2C_M0_SDA_CTL_1_ADDR                                   0x00000108
+#define CCI_I2C_M0_SDA_CTL_2_ADDR                                   0x0000010c
+#define CCI_I2C_M0_READ_DATA_ADDR                                   0x00000118
+#define CCI_I2C_M0_MISC_CTL_ADDR                                    0x00000110
+#define CCI_I2C_M0_READ_BUF_LEVEL_ADDR                              0x0000011C
+#define CCI_HALT_REQ_ADDR                                           0x00000034
+#define CCI_M0_HALT_REQ_RMSK                                               0x1
+#define CCI_M1_HALT_REQ_RMSK                                              0x01
+#define CCI_HALT_REQ_ADDR                                           0x00000034
+#define CCI_I2C_M1_SCL_CTL_ADDR                                     0x00000200
+#define CCI_I2C_M1_SDA_CTL_0_ADDR                                   0x00000204
+#define CCI_I2C_M1_SDA_CTL_1_ADDR                                   0x00000208
+#define CCI_I2C_M1_SDA_CTL_2_ADDR                                   0x0000020c
+#define CCI_I2C_M1_MISC_CTL_ADDR                                    0x00000210
+#define CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR                             0x00000304
+#define CCI_I2C_M0_Q0_CUR_CMD_ADDR                                  0x00000308
+#define CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR                            0x00000300
+#define CCI_I2C_M0_Q0_LOAD_DATA_ADDR                                0x00000310
+#define CCI_IRQ_MASK_0_ADDR                                         0x00000c04
+#define CCI_IRQ_CLEAR_0_ADDR                                        0x00000c08
+#define CCI_IRQ_STATUS_0_ADDR                                       0x00000c0c
+#define CCI_IRQ_STATUS_0_I2C_M1_Q1_NACK_ERR_BMSK                    0x40000000
+#define CCI_IRQ_STATUS_0_I2C_M1_Q0_NACK_ERR_BMSK                    0x20000000
+#define CCI_IRQ_STATUS_0_I2C_M0_Q1_NACK_ERR_BMSK                    0x10000000
+#define CCI_IRQ_STATUS_0_I2C_M0_Q0_NACK_ERR_BMSK                     0x8000000
+#define CCI_IRQ_STATUS_0_I2C_M1_Q0Q1_HALT_ACK_BMSK                   0x4000000
+#define CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK_BMSK                   0x2000000
+#define CCI_IRQ_STATUS_0_RST_DONE_ACK_BMSK                           0x1000000
+#define CCI_IRQ_STATUS_0_I2C_M1_Q1_REPORT_BMSK                        0x100000
+#define CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT_BMSK                         0x10000
+#define CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK                            0x1000
+#define CCI_IRQ_STATUS_0_I2C_M0_Q1_REPORT_BMSK                           0x100
+#define CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK                            0x10
+#define CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK                               0x1
+#define CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR                               0x00000c00
+#endif /* __MSM_CAM_CCI_HWREG__ */
diff --git a/drivers/media/platform/msm/camera_v1/cci/msm_cci.c b/drivers/media/platform/msm/camera_v1/cci/msm_cci.c
new file mode 100644
index 0000000..4da5897
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/cci/msm_cci.c
@@ -0,0 +1,769 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <mach/board.h>
+#include <mach/camera.h>
+#include <media/msm_isp.h>
+#include "msm_cci.h"
+#include "msm.h"
+#include "msm_cam_server.h"
+#include "msm_cam_cci_hwreg.h"
+
+#define V4L2_IDENT_CCI 50005
+#define CCI_I2C_QUEUE_0_SIZE 64
+#define CCI_I2C_QUEUE_1_SIZE 16
+
+#define CCI_TIMEOUT msecs_to_jiffies(100)
+
+static void msm_cci_set_clk_param(struct cci_device *cci_dev)
+{
+	uint16_t THIGH = 78;
+	uint16_t TLOW = 114;
+	uint16_t TSUSTO = 28;
+	uint16_t TSUSTA = 28;
+	uint16_t THDDAT = 10;
+	uint16_t THDSTA = 77;
+	uint16_t TBUF = 118;
+	uint8_t HW_SCL_STRETCH_EN = 0; /*enable or disable SCL clock
+					* stretching */
+	uint8_t HW_RDHLD = 6; /* internal hold time 1-6 cycles of SDA to bridge
+			       * undefined falling SCL region */
+	uint8_t HW_TSP = 1; /* glitch filter 1-3 cycles */
+
+	msm_camera_io_w(THIGH << 16 | TLOW, cci_dev->base +
+		CCI_I2C_M0_SCL_CTL_ADDR);
+	msm_camera_io_w(TSUSTO << 16 | TSUSTA, cci_dev->base +
+		CCI_I2C_M0_SDA_CTL_0_ADDR);
+	msm_camera_io_w(THDDAT << 16 | THDSTA, cci_dev->base +
+		CCI_I2C_M0_SDA_CTL_1_ADDR);
+	msm_camera_io_w(TBUF, cci_dev->base +
+		CCI_I2C_M0_SDA_CTL_2_ADDR);
+	msm_camera_io_w(HW_SCL_STRETCH_EN << 8 | HW_RDHLD << 4 | HW_TSP,
+		cci_dev->base + CCI_I2C_M0_MISC_CTL_ADDR);
+	msm_camera_io_w(THIGH << 16 | TLOW, cci_dev->base +
+		CCI_I2C_M1_SCL_CTL_ADDR);
+	msm_camera_io_w(TSUSTO << 16 | TSUSTA, cci_dev->base +
+		CCI_I2C_M1_SDA_CTL_0_ADDR);
+	msm_camera_io_w(THDDAT << 16 | THDSTA, cci_dev->base +
+		CCI_I2C_M1_SDA_CTL_1_ADDR);
+	msm_camera_io_w(TBUF, cci_dev->base + CCI_I2C_M1_SDA_CTL_2_ADDR);
+	msm_camera_io_w(HW_SCL_STRETCH_EN << 8 | HW_RDHLD << 4 | HW_TSP,
+		cci_dev->base + CCI_I2C_M1_MISC_CTL_ADDR);
+}
+
+static int32_t msm_cci_i2c_config_sync_timer(struct v4l2_subdev *sd,
+	struct msm_camera_cci_ctrl *c_ctrl)
+{
+	struct cci_device *cci_dev;
+	cci_dev = v4l2_get_subdevdata(sd);
+	msm_camera_io_w(c_ctrl->cci_info->cid, cci_dev->base +
+		CCI_SET_CID_SYNC_TIMER_0_ADDR + (c_ctrl->cci_info->cid * 0x4));
+	return 0;
+}
+
+static int32_t msm_cci_i2c_set_freq(struct v4l2_subdev *sd,
+	struct msm_camera_cci_ctrl *c_ctrl)
+{
+	struct cci_device *cci_dev;
+	uint32_t val;
+	cci_dev = v4l2_get_subdevdata(sd);
+	val = c_ctrl->cci_info->freq;
+	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SCL_CTL_ADDR +
+		c_ctrl->cci_info->cci_i2c_master*0x100);
+	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SDA_CTL_0_ADDR +
+		c_ctrl->cci_info->cci_i2c_master*0x100);
+	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SDA_CTL_1_ADDR +
+		c_ctrl->cci_info->cci_i2c_master*0x100);
+	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SDA_CTL_2_ADDR +
+		c_ctrl->cci_info->cci_i2c_master*0x100);
+	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_MISC_CTL_ADDR +
+		c_ctrl->cci_info->cci_i2c_master*0x100);
+	return 0;
+}
+
+static int32_t msm_cci_validate_queue(struct cci_device *cci_dev,
+	uint32_t len,
+	enum cci_i2c_master_t master,
+	enum cci_i2c_queue_t queue)
+{
+	int32_t rc = 0;
+	uint32_t read_val = 0;
+	uint32_t reg_offset = master * 0x200 + queue * 0x100;
+	read_val = msm_camera_io_r(cci_dev->base +
+		CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR + reg_offset);
+	CDBG("%s line %d CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR %d len %d max %d\n",
+		__func__, __LINE__, read_val, len,
+		cci_dev->cci_i2c_queue_info[master][queue].max_queue_size);
+	if ((read_val + len + 1) > cci_dev->
+		cci_i2c_queue_info[master][queue].max_queue_size) {
+		uint32_t reg_val = 0;
+		uint32_t report_val = CCI_I2C_REPORT_CMD | (1 << 8);
+		CDBG("%s:%d CCI_I2C_REPORT_CMD\n", __func__, __LINE__);
+		msm_camera_io_w(report_val,
+			cci_dev->base + CCI_I2C_M0_Q0_LOAD_DATA_ADDR +
+			reg_offset);
+		read_val++;
+		CDBG("%s:%d CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR %d\n",
+			__func__, __LINE__, read_val);
+		msm_camera_io_w(read_val, cci_dev->base +
+			CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR + reg_offset);
+		reg_val = 1 << ((master * 2) + queue);
+		CDBG("%s:%d CCI_QUEUE_START_ADDR\n", __func__, __LINE__);
+		msm_camera_io_w(reg_val, cci_dev->base + CCI_QUEUE_START_ADDR);
+		CDBG("%s line %d wait_for_completion_interruptible\n",
+			__func__, __LINE__);
+		wait_for_completion_interruptible_timeout(&cci_dev->
+			cci_master_info[master].reset_complete, CCI_TIMEOUT);
+
+		rc = cci_dev->cci_master_info[master].status;
+		if (rc < 0)
+			pr_err("%s failed rc %d\n", __func__, rc);
+	}
+	return rc;
+}
+
+static int32_t msm_cci_data_queue(struct cci_device *cci_dev,
+	struct msm_camera_cci_ctrl *c_ctrl, enum cci_i2c_queue_t queue)
+{
+	uint16_t i = 0, j = 0, k = 0, h = 0, len = 0;
+	uint32_t cmd = 0;
+	uint8_t data[10];
+	uint16_t reg_addr = 0;
+	struct msm_camera_cci_i2c_write_cfg *i2c_msg =
+		&c_ctrl->cfg.cci_i2c_write_cfg;
+	uint16_t cmd_size = i2c_msg->size;
+	struct msm_camera_i2c_reg_conf *i2c_cmd = i2c_msg->reg_conf_tbl;
+	enum cci_i2c_master_t master = c_ctrl->cci_info->cci_i2c_master;
+	CDBG("%s addr type %d data type %d\n", __func__,
+		i2c_msg->addr_type, i2c_msg->data_type);
+	/* assume total size within the max queue */
+	while (cmd_size) {
+		CDBG("%s cmd_size %d addr 0x%x data 0x%x", __func__,
+			cmd_size, i2c_cmd->reg_addr, i2c_cmd->reg_data);
+		data[i++] = CCI_I2C_WRITE_CMD;
+		if (i2c_cmd->reg_addr)
+			reg_addr = i2c_cmd->reg_addr;
+		/* either byte or word addr */
+		if (i2c_msg->addr_type == MSM_CAMERA_I2C_BYTE_ADDR)
+			data[i++] = reg_addr;
+		else {
+			data[i++] = (reg_addr & 0xFF00) >> 8;
+			data[i++] = reg_addr & 0x00FF;
+		}
+		/* max of 10 data bytes */
+		do {
+			if (i2c_msg->data_type == MSM_CAMERA_I2C_BYTE_DATA) {
+				data[i++] = i2c_cmd->reg_data;
+				reg_addr++;
+			} else {
+				if ((i + 1) <= 10) {
+					data[i++] = (i2c_cmd->reg_data &
+						0xFF00) >> 8; /* MSB */
+					data[i++] = i2c_cmd->reg_data &
+						0x00FF; /* LSB */
+					reg_addr += 2;
+				} else
+					break;
+			}
+			i2c_cmd++;
+		} while (--cmd_size && !i2c_cmd->reg_addr && (i <= 10));
+		data[0] |= ((i-1) << 4);
+		len = ((i-1)/4) + 1;
+		msm_cci_validate_queue(cci_dev, len, master, queue);
+		for (h = 0, k = 0; h < len; h++) {
+			cmd = 0;
+			for (j = 0; (j < 4 && k < i); j++)
+				cmd |= (data[k++] << (j * 8));
+			CDBG("%s CCI_I2C_M0_Q0_LOAD_DATA_ADDR 0x%x\n",
+				__func__, cmd);
+			msm_camera_io_w(cmd, cci_dev->base +
+				CCI_I2C_M0_Q0_LOAD_DATA_ADDR +
+				master * 0x200 + queue * 0x100);
+		}
+		i = 0;
+	}
+	return 0;
+}
+
+static int32_t msm_cci_write_i2c_queue(struct cci_device *cci_dev,
+	uint32_t val,
+	enum cci_i2c_master_t master,
+	enum cci_i2c_queue_t queue)
+{
+	int32_t rc = 0;
+	uint32_t reg_offset = master * 0x200 + queue * 0x100;
+	CDBG("%s:%d called\n", __func__, __LINE__);
+	msm_cci_validate_queue(cci_dev, 1, master, queue);
+	CDBG("%s CCI_I2C_M0_Q0_LOAD_DATA_ADDR:val %x:%x\n",
+		__func__, CCI_I2C_M0_Q0_LOAD_DATA_ADDR +
+		reg_offset, val);
+	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_Q0_LOAD_DATA_ADDR +
+		reg_offset);
+	return rc;
+}
+
+static int32_t msm_cci_i2c_read(struct v4l2_subdev *sd,
+	struct msm_camera_cci_ctrl *c_ctrl)
+{
+	uint32_t rc = 0;
+	uint32_t val = 0;
+	int32_t read_words = 0, exp_words = 0;
+	int32_t index = 0, first_byte = 0;
+	uint32_t i = 0;
+	enum cci_i2c_master_t master;
+	enum cci_i2c_queue_t queue = QUEUE_1;
+	struct cci_device *cci_dev = NULL;
+	struct msm_camera_cci_i2c_read_cfg *read_cfg = NULL;
+	CDBG("%s line %d\n", __func__, __LINE__);
+	cci_dev = v4l2_get_subdevdata(sd);
+	master = c_ctrl->cci_info->cci_i2c_master;
+	read_cfg = &c_ctrl->cfg.cci_i2c_read_cfg;
+	mutex_lock(&cci_dev->cci_master_info[master].mutex);
+	CDBG("%s master %d, queue %d\n", __func__, master, queue);
+	CDBG("%s set param sid 0x%x retries %d id_map %d\n", __func__,
+		c_ctrl->cci_info->sid, c_ctrl->cci_info->retries,
+		c_ctrl->cci_info->id_map);
+	val = CCI_I2C_SET_PARAM_CMD | c_ctrl->cci_info->sid << 4 |
+		c_ctrl->cci_info->retries << 16 |
+		c_ctrl->cci_info->id_map << 18;
+	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
+	if (rc < 0) {
+		CDBG("%s failed line %d\n", __func__, __LINE__);
+		goto ERROR;
+	}
+
+	val = CCI_I2C_LOCK_CMD;
+	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
+	if (rc < 0) {
+		CDBG("%s failed line %d\n", __func__, __LINE__);
+		goto ERROR;
+	}
+
+	if (read_cfg->addr_type == MSM_CAMERA_I2C_BYTE_ADDR)
+		val = CCI_I2C_WRITE_CMD | (read_cfg->addr_type << 4) |
+			((read_cfg->addr & 0xFF) << 8);
+	if (read_cfg->addr_type == MSM_CAMERA_I2C_WORD_ADDR)
+		val = CCI_I2C_WRITE_CMD | (read_cfg->addr_type << 4) |
+			(((read_cfg->addr & 0xFF00) >> 8) << 8) |
+			((read_cfg->addr & 0xFF) << 16);
+	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
+	if (rc < 0) {
+		CDBG("%s failed line %d\n", __func__, __LINE__);
+		goto ERROR;
+	}
+
+	val = CCI_I2C_READ_CMD | (read_cfg->num_byte << 4);
+	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
+	if (rc < 0) {
+		CDBG("%s failed line %d\n", __func__, __LINE__);
+		goto ERROR;
+	}
+
+	val = CCI_I2C_UNLOCK_CMD;
+	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
+	if (rc < 0) {
+		CDBG("%s failed line %d\n", __func__, __LINE__);
+		goto ERROR;
+	}
+
+	val = msm_camera_io_r(cci_dev->base + CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR +
+		master * 0x200 + queue * 0x100);
+	CDBG("%s cur word cnt %x\n", __func__, val);
+	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR +
+		master * 0x200 + queue * 0x100);
+
+	val = 1 << ((master * 2) + queue);
+	msm_camera_io_w(val, cci_dev->base + CCI_QUEUE_START_ADDR);
+	wait_for_completion_interruptible_timeout(&cci_dev->
+		cci_master_info[master].reset_complete, CCI_TIMEOUT);
+
+	read_words = msm_camera_io_r(cci_dev->base +
+		CCI_I2C_M0_READ_BUF_LEVEL_ADDR + master * 0x100);
+	exp_words = ((read_cfg->num_byte / 4) + 1);
+	if (read_words != exp_words) {
+		pr_err("%s:%d read_words = %d, exp words = %d\n", __func__,
+			__LINE__, read_words, exp_words);
+		memset(read_cfg->data, 0, read_cfg->num_byte);
+		goto ERROR;
+	}
+	index = 0;
+	CDBG("%s index %d num_type %d\n", __func__, index,
+		read_cfg->num_byte);
+	first_byte = 0;
+	do {
+		val = msm_camera_io_r(cci_dev->base +
+			CCI_I2C_M0_READ_DATA_ADDR + master * 0x100);
+		CDBG("%s read val %x\n", __func__, val);
+		for (i = 0; (i < 4) && (index < read_cfg->num_byte); i++) {
+			CDBG("%s i %d index %d\n", __func__, i, index);
+			if (!first_byte) {
+				CDBG("%s sid %x\n", __func__, val & 0xFF);
+				first_byte++;
+			} else {
+				read_cfg->data[index] =
+					(val  >> (i * 8)) & 0xFF;
+				CDBG("%s data[%d] %x\n", __func__, index,
+					read_cfg->data[index]);
+				index++;
+			}
+		}
+	} while (--read_words > 0);
+ERROR:
+	mutex_unlock(&cci_dev->cci_master_info[master].mutex);
+	return rc;
+}
+
+static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd,
+	struct msm_camera_cci_ctrl *c_ctrl)
+{
+	int32_t rc = 0;
+	struct cci_device *cci_dev;
+	uint32_t val;
+	enum cci_i2c_master_t master;
+	enum cci_i2c_queue_t queue = QUEUE_0;
+	cci_dev = v4l2_get_subdevdata(sd);
+	master = c_ctrl->cci_info->cci_i2c_master;
+	CDBG("%s master %d, queue %d\n", __func__, master, queue);
+	CDBG("%s set param sid 0x%x retries %d id_map %d\n", __func__,
+		c_ctrl->cci_info->sid, c_ctrl->cci_info->retries,
+		c_ctrl->cci_info->id_map);
+	mutex_lock(&cci_dev->cci_master_info[master].mutex);
+	val = CCI_I2C_SET_PARAM_CMD | c_ctrl->cci_info->sid << 4 |
+		c_ctrl->cci_info->retries << 16 |
+		c_ctrl->cci_info->id_map << 18;
+	CDBG("%s:%d CCI_I2C_SET_PARAM_CMD\n", __func__, __LINE__);
+	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
+	if (rc < 0) {
+		CDBG("%s failed line %d\n", __func__, __LINE__);
+		goto ERROR;
+	}
+
+	val = CCI_I2C_LOCK_CMD;
+	CDBG("%s:%d CCI_I2C_LOCK_CMD\n", __func__, __LINE__);
+	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
+	if (rc < 0) {
+		CDBG("%s failed line %d\n", __func__, __LINE__);
+		goto ERROR;
+	}
+
+	msm_cci_data_queue(cci_dev, c_ctrl, queue);
+	val = CCI_I2C_UNLOCK_CMD;
+	CDBG("%s:%d CCI_I2C_UNLOCK_CMD\n", __func__, __LINE__);
+	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
+	if (rc < 0) {
+		CDBG("%s failed line %d\n", __func__, __LINE__);
+		goto ERROR;
+	}
+
+	val = CCI_I2C_REPORT_CMD | (1 << 8);
+	CDBG("%s:%d CCI_I2C_REPORT_CMD\n", __func__, __LINE__);
+	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
+	if (rc < 0) {
+		CDBG("%s failed line %d\n", __func__, __LINE__);
+		goto ERROR;
+	}
+
+	val = msm_camera_io_r(cci_dev->base + CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR +
+		master * 0x200 + queue * 0x100);
+	CDBG("%s:%d cur word count %d\n", __func__, __LINE__, val);
+	CDBG("%s:%d CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR\n", __func__, __LINE__);
+	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR +
+		master * 0x200 + queue * 0x100);
+
+	val = 1 << ((master * 2) + queue);
+	CDBG("%s:%d CCI_QUEUE_START_ADDR\n", __func__, __LINE__);
+	msm_camera_io_w(val, cci_dev->base + CCI_QUEUE_START_ADDR +
+		master*0x200 + queue * 0x100);
+
+	CDBG("%s line %d wait_for_completion_interruptible\n",
+		__func__, __LINE__);
+	wait_for_completion_interruptible_timeout(&cci_dev->
+		cci_master_info[master].reset_complete, CCI_TIMEOUT);
+
+ERROR:
+	mutex_unlock(&cci_dev->cci_master_info[master].mutex);
+	return rc;
+}
+
+static int msm_cci_subdev_g_chip_ident(struct v4l2_subdev *sd,
+			struct v4l2_dbg_chip_ident *chip)
+{
+	BUG_ON(!chip);
+	chip->ident = V4L2_IDENT_CCI;
+	chip->revision = 0;
+	return 0;
+}
+
+static struct msm_cam_clk_info cci_clk_info[] = {
+	{"camss_top_ahb_clk", -1},
+	{"cci_src_clk", 19200000},
+	{"cci_ahb_clk", -1},
+	{"cci_clk", -1},
+};
+
+static int32_t msm_cci_init(struct v4l2_subdev *sd)
+{
+	int rc = 0;
+	struct cci_device *cci_dev;
+	cci_dev = v4l2_get_subdevdata(sd);
+	CDBG("%s line %d\n", __func__, __LINE__);
+	if (cci_dev == NULL) {
+		rc = -ENOMEM;
+		return rc;
+	}
+	rc = msm_cam_clk_enable(&cci_dev->pdev->dev, cci_clk_info,
+		cci_dev->cci_clk, ARRAY_SIZE(cci_clk_info), 1);
+	if (rc < 0) {
+		CDBG("%s: clk enable failed\n", __func__);
+		goto clk_enable_failed;
+	}
+
+	enable_irq(cci_dev->irq->start);
+	cci_dev->hw_version = msm_camera_io_r(cci_dev->base +
+		CCI_HW_VERSION_ADDR);
+	cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE;
+	msm_camera_io_w(0xFFFFFFFF, cci_dev->base + CCI_RESET_CMD_ADDR);
+	msm_camera_io_w(0x1, cci_dev->base + CCI_RESET_CMD_ADDR);
+	wait_for_completion_interruptible_timeout(
+		&cci_dev->cci_master_info[MASTER_0].reset_complete,
+		CCI_TIMEOUT);
+	msm_cci_set_clk_param(cci_dev);
+	msm_camera_io_w(0xFFFFFFFF, cci_dev->base + CCI_IRQ_MASK_0_ADDR);
+	msm_camera_io_w(0xFFFFFFFF, cci_dev->base + CCI_IRQ_CLEAR_0_ADDR);
+	msm_camera_io_w(0x1, cci_dev->base + CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR);
+	msm_camera_io_w(0x0, cci_dev->base + CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR);
+	msm_camera_io_w(0x0, cci_dev->base + CCI_IRQ_CLEAR_0_ADDR);
+	return 0;
+
+clk_enable_failed:
+	return rc;
+}
+
+static int32_t msm_cci_release(struct v4l2_subdev *sd)
+{
+	struct cci_device *cci_dev;
+	cci_dev = v4l2_get_subdevdata(sd);
+
+	disable_irq(cci_dev->irq->start);
+
+	msm_cam_clk_enable(&cci_dev->pdev->dev, cci_clk_info,
+		cci_dev->cci_clk, ARRAY_SIZE(cci_clk_info), 0);
+
+	return 0;
+}
+
+static int32_t msm_cci_config(struct v4l2_subdev *sd,
+	struct msm_camera_cci_ctrl *cci_ctrl)
+{
+	int32_t rc = 0;
+	CDBG("%s line %d cmd %d\n", __func__, __LINE__,
+		cci_ctrl->cmd);
+	switch (cci_ctrl->cmd) {
+	case MSM_CCI_INIT:
+		rc = msm_cci_init(sd);
+		break;
+	case MSM_CCI_RELEASE:
+		rc = msm_cci_release(sd);
+		break;
+	case MSM_CCI_SET_SID:
+		break;
+	case MSM_CCI_SET_FREQ:
+		rc = msm_cci_i2c_set_freq(sd, cci_ctrl);
+		break;
+	case MSM_CCI_SET_SYNC_CID:
+		rc = msm_cci_i2c_config_sync_timer(sd, cci_ctrl);
+		break;
+	case MSM_CCI_I2C_READ:
+		rc = msm_cci_i2c_read(sd, cci_ctrl);
+		break;
+	case MSM_CCI_I2C_WRITE:
+		rc = msm_cci_i2c_write(sd, cci_ctrl);
+		break;
+	case MSM_CCI_GPIO_WRITE:
+		break;
+	default:
+		rc = -ENOIOCTLCMD;
+	}
+	CDBG("%s line %d rc %d\n", __func__, __LINE__, rc);
+	cci_ctrl->status = rc;
+	return rc;
+}
+
+static irqreturn_t msm_cci_irq(int irq_num, void *data)
+{
+	uint32_t irq;
+	struct cci_device *cci_dev = data;
+	irq = msm_camera_io_r(cci_dev->base + CCI_IRQ_STATUS_0_ADDR);
+	msm_camera_io_w(irq, cci_dev->base + CCI_IRQ_CLEAR_0_ADDR);
+	msm_camera_io_w(0x1, cci_dev->base + CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR);
+	msm_camera_io_w(0x0, cci_dev->base + CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR);
+	CDBG("%s CCI_I2C_M0_STATUS_ADDR = 0x%x\n", __func__, irq);
+	if (irq & CCI_IRQ_STATUS_0_RST_DONE_ACK_BMSK) {
+		if (cci_dev->cci_master_info[MASTER_0].reset_pending == TRUE) {
+			cci_dev->cci_master_info[MASTER_0].reset_pending =
+				FALSE;
+			complete(&cci_dev->cci_master_info[MASTER_0].
+				reset_complete);
+		}
+		if (cci_dev->cci_master_info[MASTER_1].reset_pending == TRUE) {
+			cci_dev->cci_master_info[MASTER_1].reset_pending =
+				FALSE;
+			complete(&cci_dev->cci_master_info[MASTER_1].
+				reset_complete);
+		}
+	} else if ((irq & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK) ||
+		(irq & CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK) ||
+		(irq & CCI_IRQ_STATUS_0_I2C_M0_Q1_REPORT_BMSK)) {
+		cci_dev->cci_master_info[MASTER_0].status = 0;
+		complete(&cci_dev->cci_master_info[MASTER_0].reset_complete);
+	} else if ((irq & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) ||
+		(irq & CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT_BMSK) ||
+		(irq & CCI_IRQ_STATUS_0_I2C_M1_Q1_REPORT_BMSK)) {
+		cci_dev->cci_master_info[MASTER_1].status = 0;
+		complete(&cci_dev->cci_master_info[MASTER_1].reset_complete);
+	} else if ((irq & CCI_IRQ_STATUS_0_I2C_M0_Q0_NACK_ERR_BMSK) ||
+		(irq & CCI_IRQ_STATUS_0_I2C_M0_Q1_NACK_ERR_BMSK)) {
+		cci_dev->cci_master_info[MASTER_0].status = -EINVAL;
+		msm_camera_io_w(CCI_M0_HALT_REQ_RMSK,
+			cci_dev->base + CCI_HALT_REQ_ADDR);
+	} else if ((irq & CCI_IRQ_STATUS_0_I2C_M1_Q0_NACK_ERR_BMSK) ||
+		(irq & CCI_IRQ_STATUS_0_I2C_M1_Q1_NACK_ERR_BMSK)) {
+		cci_dev->cci_master_info[MASTER_1].status = -EINVAL;
+		msm_camera_io_w(CCI_M1_HALT_REQ_RMSK,
+			cci_dev->base + CCI_HALT_REQ_ADDR);
+	} else if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK_BMSK) {
+		cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE;
+		msm_camera_io_w(CCI_M0_RESET_RMSK,
+			cci_dev->base + CCI_RESET_CMD_ADDR);
+	} else if (irq & CCI_IRQ_STATUS_0_I2C_M1_Q0Q1_HALT_ACK_BMSK) {
+		cci_dev->cci_master_info[MASTER_1].reset_pending = TRUE;
+		msm_camera_io_w(CCI_M1_RESET_RMSK,
+			cci_dev->base + CCI_RESET_CMD_ADDR);
+	} else {
+		pr_err("%s unhandled irq 0x%x\n", __func__, irq);
+		cci_dev->cci_master_info[MASTER_0].status = 0;
+		complete(&cci_dev->cci_master_info[MASTER_0].reset_complete);
+		cci_dev->cci_master_info[MASTER_1].status = 0;
+		complete(&cci_dev->cci_master_info[MASTER_1].reset_complete);
+	}
+	return IRQ_HANDLED;
+}
+
+int msm_cci_irq_routine(struct v4l2_subdev *sd, u32 status, bool *handled)
+{
+	struct cci_device *cci_dev = v4l2_get_subdevdata(sd);
+	irqreturn_t ret;
+	CDBG("%s line %d\n", __func__, __LINE__);
+	ret = msm_cci_irq(cci_dev->irq->start, cci_dev);
+	*handled = TRUE;
+	return 0;
+}
+
+static long msm_cci_subdev_ioctl(struct v4l2_subdev *sd,
+	unsigned int cmd, void *arg)
+{
+	int32_t rc = 0;
+	CDBG("%s line %d\n", __func__, __LINE__);
+	switch (cmd) {
+	case VIDIOC_MSM_CCI_CFG:
+		rc = msm_cci_config(sd, arg);
+		break;
+	default:
+		rc = -ENOIOCTLCMD;
+	}
+	CDBG("%s line %d rc %d\n", __func__, __LINE__, rc);
+	return rc;
+}
+
+static struct v4l2_subdev_core_ops msm_cci_subdev_core_ops = {
+	.g_chip_ident = &msm_cci_subdev_g_chip_ident,
+	.ioctl = &msm_cci_subdev_ioctl,
+	.interrupt_service_routine = msm_cci_irq_routine,
+};
+
+static const struct v4l2_subdev_ops msm_cci_subdev_ops = {
+	.core = &msm_cci_subdev_core_ops,
+};
+
+static const struct v4l2_subdev_internal_ops msm_cci_internal_ops;
+
+static void msm_cci_initialize_cci_params(struct cci_device *new_cci_dev)
+{
+	uint8_t i = 0, j = 0;
+	for (i = 0; i < NUM_MASTERS; i++) {
+		new_cci_dev->cci_master_info[i].status = 0;
+		mutex_init(&new_cci_dev->cci_master_info[i].mutex);
+		init_completion(&new_cci_dev->
+			cci_master_info[i].reset_complete);
+		for (j = 0; j < NUM_QUEUES; j++) {
+			if (j == QUEUE_0)
+				new_cci_dev->cci_i2c_queue_info[i][j].
+					max_queue_size = CCI_I2C_QUEUE_0_SIZE;
+			else
+				new_cci_dev->cci_i2c_queue_info[i][j].
+					max_queue_size = CCI_I2C_QUEUE_1_SIZE;
+			}
+	}
+	return;
+}
+
+static int __devinit msm_cci_probe(struct platform_device *pdev)
+{
+	struct cci_device *new_cci_dev;
+	int rc = 0;
+	struct msm_cam_subdev_info sd_info;
+	struct intr_table_entry irq_req;
+	CDBG("%s: pdev %p device id = %d\n", __func__, pdev, pdev->id);
+	new_cci_dev = kzalloc(sizeof(struct cci_device), GFP_KERNEL);
+	if (!new_cci_dev) {
+		CDBG("%s: no enough memory\n", __func__);
+		return -ENOMEM;
+	}
+	v4l2_subdev_init(&new_cci_dev->subdev, &msm_cci_subdev_ops);
+	new_cci_dev->subdev.internal_ops = &msm_cci_internal_ops;
+	new_cci_dev->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	snprintf(new_cci_dev->subdev.name,
+			ARRAY_SIZE(new_cci_dev->subdev.name), "msm_cci");
+	v4l2_set_subdevdata(&new_cci_dev->subdev, new_cci_dev);
+	platform_set_drvdata(pdev, &new_cci_dev->subdev);
+	CDBG("%s sd %p\n", __func__, &new_cci_dev->subdev);
+	if (pdev->dev.of_node)
+		of_property_read_u32((&pdev->dev)->of_node,
+			"cell-index", &pdev->id);
+
+	new_cci_dev->mem = platform_get_resource_byname(pdev,
+					IORESOURCE_MEM, "cci");
+	if (!new_cci_dev->mem) {
+		CDBG("%s: no mem resource?\n", __func__);
+		rc = -ENODEV;
+		goto cci_no_resource;
+	}
+	new_cci_dev->irq = platform_get_resource_byname(pdev,
+					IORESOURCE_IRQ, "cci");
+	CDBG("%s line %d cci irq start %d end %d\n", __func__,
+		__LINE__,
+		new_cci_dev->irq->start,
+		new_cci_dev->irq->end);
+	if (!new_cci_dev->irq) {
+		CDBG("%s: no irq resource?\n", __func__);
+		rc = -ENODEV;
+		goto cci_no_resource;
+	}
+	new_cci_dev->io = request_mem_region(new_cci_dev->mem->start,
+		resource_size(new_cci_dev->mem), pdev->name);
+	if (!new_cci_dev->io) {
+		CDBG("%s: no valid mem region\n", __func__);
+		rc = -EBUSY;
+		goto cci_no_resource;
+	}
+
+	new_cci_dev->base = ioremap(new_cci_dev->mem->start,
+		resource_size(new_cci_dev->mem));
+	if (!new_cci_dev->base) {
+		rc = -ENOMEM;
+		goto cci_release_mem;
+	}
+
+	sd_info.sdev_type = CCI_DEV;
+	sd_info.sd_index = pdev->id;
+	sd_info.irq_num = new_cci_dev->irq->start;
+	msm_cam_register_subdev_node(&new_cci_dev->subdev, &sd_info);
+
+	irq_req.cam_hw_idx       = MSM_CAM_HW_CCI;
+	irq_req.dev_name         = "msm_cci";
+	irq_req.irq_idx          = CAMERA_SS_IRQ_1;
+	irq_req.irq_num          = new_cci_dev->irq->start;
+	irq_req.is_composite     = 0;
+	irq_req.irq_trigger_type = IRQF_TRIGGER_RISING;
+	irq_req.num_hwcore       = 1;
+	irq_req.subdev_list[0]   = &new_cci_dev->subdev;
+	irq_req.data             = (void *)new_cci_dev;
+	rc = msm_cam_server_request_irq(&irq_req);
+	if (rc == -ENXIO) {
+		/* IRQ Router hardware is not present on this hardware.
+		 * Request for the IRQ and register the interrupt handler. */
+		rc = request_irq(new_cci_dev->irq->start, msm_cci_irq,
+			IRQF_TRIGGER_RISING, "cci", new_cci_dev);
+		if (rc < 0) {
+			CDBG("%s: irq request fail\n", __func__);
+			rc = -EBUSY;
+			goto cci_release_mem;
+		}
+		disable_irq(new_cci_dev->irq->start);
+	} else if (rc < 0) {
+		CDBG("%s Error registering irq ", __func__);
+		rc = -EBUSY;
+		goto cci_release_mem;
+	}
+
+	new_cci_dev->pdev = pdev;
+	msm_cci_initialize_cci_params(new_cci_dev);
+	rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+	if (rc)
+		pr_err("%s: failed to add child nodes, rc=%d\n", __func__, rc);
+	CDBG("%s line %d\n", __func__, __LINE__);
+	return 0;
+
+cci_release_mem:
+	release_mem_region(new_cci_dev->mem->start,
+		resource_size(new_cci_dev->mem));
+cci_no_resource:
+	kfree(new_cci_dev);
+	return 0;
+}
+
+static int __exit msm_cci_exit(struct platform_device *pdev)
+{
+	struct v4l2_subdev *subdev = platform_get_drvdata(pdev);
+	struct cci_device *cci_dev =
+		v4l2_get_subdevdata(subdev);
+	release_mem_region(cci_dev->mem->start, resource_size(cci_dev->mem));
+	kfree(cci_dev);
+	return 0;
+}
+
+static const struct of_device_id msm_cci_dt_match[] = {
+	{.compatible = "qcom,cci"},
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, msm_cci_dt_match);
+
+static struct platform_driver cci_driver = {
+	.probe = msm_cci_probe,
+	.remove = msm_cci_exit,
+	.driver = {
+		.name = MSM_CCI_DRV_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = msm_cci_dt_match,
+	},
+};
+
+static int __init msm_cci_init_module(void)
+{
+	return platform_driver_register(&cci_driver);
+}
+
+static void __exit msm_cci_exit_module(void)
+{
+	platform_driver_unregister(&cci_driver);
+}
+
+module_init(msm_cci_init_module);
+module_exit(msm_cci_exit_module);
+MODULE_DESCRIPTION("MSM CCI driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/cci/msm_cci.h b/drivers/media/platform/msm/camera_v1/cci/msm_cci.h
new file mode 100644
index 0000000..827916d
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/cci/msm_cci.h
@@ -0,0 +1,85 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_CCI_H
+#define MSM_CCI_H
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <media/v4l2-subdev.h>
+#include <mach/camera.h>
+
+#define NUM_MASTERS 2
+#define NUM_QUEUES 2
+
+#define TRUE  1
+#define FALSE 0
+
+struct msm_camera_cci_master_info {
+	uint32_t status;
+	uint8_t reset_pending;
+	struct mutex mutex;
+	struct completion reset_complete;
+};
+
+struct cci_device {
+	struct platform_device *pdev;
+	struct v4l2_subdev subdev;
+	struct resource *mem;
+	struct resource *irq;
+	struct resource *io;
+	void __iomem *base;
+	uint32_t hw_version;
+	struct clk *cci_clk[5];
+	struct msm_camera_cci_i2c_queue_info
+		cci_i2c_queue_info[NUM_MASTERS][NUM_QUEUES];
+	struct msm_camera_cci_master_info cci_master_info[NUM_MASTERS];
+};
+
+enum msm_cci_i2c_cmd_type {
+	CCI_I2C_SET_PARAM_CMD = 1,
+	CCI_I2C_WAIT_CMD,
+	CCI_I2C_WAIT_SYNC_CMD,
+	CCI_I2C_WAIT_GPIO_EVENT_CMD,
+	CCI_I2C_TRIG_I2C_EVENT_CMD,
+	CCI_I2C_LOCK_CMD,
+	CCI_I2C_UNLOCK_CMD,
+	CCI_I2C_REPORT_CMD,
+	CCI_I2C_WRITE_CMD,
+	CCI_I2C_READ_CMD,
+	CCI_I2C_WRITE_DISABLE_P_CMD,
+	CCI_I2C_READ_DISABLE_P_CMD,
+	CCI_I2C_WRITE_CMD2,
+	CCI_I2C_WRITE_CMD3,
+	CCI_I2C_REPEAT_CMD,
+	CCI_I2C_INVALID_CMD,
+};
+
+enum msm_cci_gpio_cmd_type {
+	CCI_GPIO_SET_PARAM_CMD = 1,
+	CCI_GPIO_WAIT_CMD,
+	CCI_GPIO_WAIT_SYNC_CMD,
+	CCI_GPIO_WAIT_GPIO_IN_EVENT_CMD,
+	CCI_GPIO_WAIT_I2C_Q_TRIG_EVENT_CMD,
+	CCI_GPIO_OUT_CMD,
+	CCI_GPIO_TRIG_EVENT_CMD,
+	CCI_GPIO_REPORT_CMD,
+	CCI_GPIO_REPEAT_CMD,
+	CCI_GPIO_CONTINUE_CMD,
+	CCI_GPIO_INVALID_CMD,
+};
+
+#define VIDIOC_MSM_CCI_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 23, struct msm_camera_cci_ctrl *)
+
+#endif
+
diff --git a/drivers/media/platform/msm/camera_v1/cpp/Makefile b/drivers/media/platform/msm/camera_v1/cpp/Makefile
new file mode 100644
index 0000000..aa4c362
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/cpp/Makefile
@@ -0,0 +1,5 @@
+GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
+ccflags-y += -Idrivers/media/platform/msm/camera_v1
+ccflags-y += -Idrivers/media/platform/msm/camera_v1/io
+obj-$(CONFIG_MSM_CPP) += msm_cpp.o
+
diff --git a/drivers/media/platform/msm/camera_v1/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v1/cpp/msm_cpp.c
new file mode 100644
index 0000000..cd932bd
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/cpp/msm_cpp.c
@@ -0,0 +1,412 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <mach/board.h>
+#include <mach/camera.h>
+#include <mach/vreg.h>
+#include <media/msm_isp.h>
+#include <linux/proc_fs.h>
+#include <linux/debugfs.h>
+
+#include "msm_cpp.h"
+#include "msm.h"
+
+#define CONFIG_MSM_CPP_DBG 0
+
+#if CONFIG_MSM_CPP_DBG
+#define CPP_DBG(fmt, args...) pr_info(fmt, ##args)
+#else
+#define CPP_DBG(fmt, args...) pr_debug(fmt, ##args)
+#endif
+
+static int cpp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	uint32_t i;
+	struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd);
+	CPP_DBG("%s\n", __func__);
+
+	mutex_lock(&cpp_dev->mutex);
+	if (cpp_dev->cpp_open_cnt == MAX_ACTIVE_CPP_INSTANCE) {
+		pr_err("No free CPP instance\n");
+		mutex_unlock(&cpp_dev->mutex);
+		return -ENODEV;
+	}
+
+	for (i = 0; i < MAX_ACTIVE_CPP_INSTANCE; i++) {
+		if (cpp_dev->cpp_subscribe_list[i].active == 0) {
+			cpp_dev->cpp_subscribe_list[i].active = 1;
+			cpp_dev->cpp_subscribe_list[i].vfh = &fh->vfh;
+			break;
+		}
+	}
+	if (i == MAX_ACTIVE_CPP_INSTANCE) {
+		pr_err("No free instance\n");
+		mutex_unlock(&cpp_dev->mutex);
+		return -ENODEV;
+	}
+
+	CPP_DBG("open %d %p\n", i, &fh->vfh);
+	cpp_dev->cpp_open_cnt++;
+	mutex_unlock(&cpp_dev->mutex);
+	return 0;
+}
+
+static int cpp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	uint32_t i;
+	struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd);
+	mutex_lock(&cpp_dev->mutex);
+	for (i = 0; i < MAX_ACTIVE_CPP_INSTANCE; i++) {
+		if (cpp_dev->cpp_subscribe_list[i].vfh == &fh->vfh) {
+			cpp_dev->cpp_subscribe_list[i].active = 0;
+			cpp_dev->cpp_subscribe_list[i].vfh = NULL;
+			break;
+		}
+	}
+	if (i == MAX_ACTIVE_CPP_INSTANCE) {
+		pr_err("Invalid close\n");
+		mutex_unlock(&cpp_dev->mutex);
+		return -ENODEV;
+	}
+
+	CPP_DBG("close %d %p\n", i, &fh->vfh);
+	cpp_dev->cpp_open_cnt--;
+	mutex_unlock(&cpp_dev->mutex);
+	return 0;
+}
+
+static const struct v4l2_subdev_internal_ops msm_cpp_internal_ops = {
+	.open = cpp_open_node,
+	.close = cpp_close_node,
+};
+
+static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev)
+{
+	struct v4l2_event v4l2_evt;
+	struct msm_queue_cmd *frame_qcmd;
+	struct msm_queue_cmd *event_qcmd;
+	struct msm_cpp_frame_info_t *processed_frame;
+	struct msm_device_queue *queue = &cpp_dev->processing_q;
+
+	if (queue->len > 0) {
+		frame_qcmd = msm_dequeue(queue, list_frame);
+		processed_frame = frame_qcmd->command;
+
+		event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
+		if (!event_qcmd) {
+			pr_err("%s Insufficient memory. return", __func__);
+			return -ENOMEM;
+		}
+		atomic_set(&event_qcmd->on_heap, 1);
+		event_qcmd->command = processed_frame;
+		CPP_DBG("fid %d\n", processed_frame->frame_id);
+		msm_enqueue(&cpp_dev->eventData_q, &event_qcmd->list_eventdata);
+
+		v4l2_evt.id = processed_frame->inst_id;
+		v4l2_evt.type = V4L2_EVENT_CPP_FRAME_DONE;
+		v4l2_event_queue(cpp_dev->subdev.devnode, &v4l2_evt);
+	}
+	return 0;
+}
+
+static int msm_cpp_send_frame_to_hardware(struct cpp_device *cpp_dev)
+{
+	struct msm_queue_cmd *frame_qcmd;
+	struct msm_cpp_frame_info_t *process_frame;
+	struct msm_device_queue *queue;
+
+	if (cpp_dev->processing_q.len < MAX_CPP_PROCESSING_FRAME) {
+		while (cpp_dev->processing_q.len < MAX_CPP_PROCESSING_FRAME) {
+			if (cpp_dev->realtime_q.len != 0) {
+				queue = &cpp_dev->realtime_q;
+			} else if (cpp_dev->offline_q.len != 0) {
+				queue = &cpp_dev->offline_q;
+			} else {
+				pr_debug("%s: All frames queued\n", __func__);
+				break;
+			}
+			frame_qcmd = msm_dequeue(queue, list_frame);
+			/*TBD Code to actually sending to harware*/
+			process_frame = frame_qcmd->command;
+
+			msm_enqueue(&cpp_dev->processing_q,
+						&frame_qcmd->list_frame);
+		}
+	}
+	return 0;
+}
+
+long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int cmd, void *arg)
+{
+	struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd);
+	struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
+	int rc = 0;
+
+	CPP_DBG("%s: %d\n", __func__, __LINE__);
+	mutex_lock(&cpp_dev->mutex);
+	CPP_DBG("%s cmd: %d\n", __func__, cmd);
+	switch (cmd) {
+	case VIDIOC_MSM_CPP_CFG: {
+		struct msm_queue_cmd *frame_qcmd;
+		struct msm_cpp_frame_info_t *new_frame =
+			kzalloc(sizeof(struct msm_cpp_frame_info_t),
+					GFP_KERNEL);
+		if (!new_frame) {
+			pr_err("%s Insufficient memory. return", __func__);
+			mutex_unlock(&cpp_dev->mutex);
+			return -ENOMEM;
+		}
+
+		COPY_FROM_USER(rc, new_frame,
+			       (void __user *)ioctl_ptr->ioctl_ptr,
+			       sizeof(struct msm_cpp_frame_info_t));
+		if (rc) {
+			ERR_COPY_FROM_USER();
+			kfree(new_frame);
+			mutex_unlock(&cpp_dev->mutex);
+			return -EINVAL;
+		}
+
+		frame_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
+		if (!frame_qcmd) {
+			pr_err("%s Insufficient memory. return", __func__);
+			kfree(new_frame);
+			mutex_unlock(&cpp_dev->mutex);
+			return -ENOMEM;
+		}
+
+		atomic_set(&frame_qcmd->on_heap, 1);
+		frame_qcmd->command = new_frame;
+		if (new_frame->frame_type == MSM_CPP_REALTIME_FRAME) {
+			msm_enqueue(&cpp_dev->realtime_q,
+						&frame_qcmd->list_frame);
+		} else if (new_frame->frame_type == MSM_CPP_OFFLINE_FRAME) {
+			msm_enqueue(&cpp_dev->offline_q,
+						&frame_qcmd->list_frame);
+		} else {
+			pr_err("%s: Invalid frame type\n", __func__);
+			kfree(new_frame);
+			kfree(frame_qcmd);
+			mutex_unlock(&cpp_dev->mutex);
+			return -EINVAL;
+		}
+		break;
+	}
+	case VIDIOC_MSM_CPP_GET_EVENTPAYLOAD: {
+		struct msm_device_queue *queue = &cpp_dev->eventData_q;
+		struct msm_queue_cmd *event_qcmd;
+		struct msm_cpp_frame_info_t *process_frame;
+		event_qcmd = msm_dequeue(queue, list_eventdata);
+		process_frame = event_qcmd->command;
+		CPP_DBG("fid %d\n", process_frame->frame_id);
+		if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
+				process_frame,
+				sizeof(struct msm_cpp_frame_info_t))) {
+					mutex_unlock(&cpp_dev->mutex);
+					return -EINVAL;
+		}
+		kfree(process_frame);
+		kfree(event_qcmd);
+		break;
+	}
+	}
+	mutex_unlock(&cpp_dev->mutex);
+	CPP_DBG("%s: %d\n", __func__, __LINE__);
+	return 0;
+}
+
+int msm_cpp_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+	struct v4l2_event_subscription *sub)
+{
+	CPP_DBG("%s\n", __func__);
+	return v4l2_event_subscribe(fh, sub, MAX_CPP_V4l2_EVENTS);
+}
+
+int msm_cpp_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+	struct v4l2_event_subscription *sub)
+{
+	CPP_DBG("%s\n", __func__);
+	return v4l2_event_unsubscribe(fh, sub);
+}
+
+static struct v4l2_subdev_core_ops msm_cpp_subdev_core_ops = {
+	.ioctl = msm_cpp_subdev_ioctl,
+	.subscribe_event = msm_cpp_subscribe_event,
+	.unsubscribe_event = msm_cpp_unsubscribe_event,
+};
+
+static const struct v4l2_subdev_ops msm_cpp_subdev_ops = {
+	.core = &msm_cpp_subdev_core_ops,
+};
+
+static int msm_cpp_enable_debugfs(struct cpp_device *cpp_dev);
+
+static struct v4l2_file_operations msm_cpp_v4l2_subdev_fops;
+
+static long msm_cpp_subdev_do_ioctl(
+	struct file *file, unsigned int cmd, void *arg)
+{
+	struct video_device *vdev = video_devdata(file);
+	struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
+	struct v4l2_fh *vfh = file->private_data;
+
+	switch (cmd) {
+	case VIDIOC_DQEVENT:
+		if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS))
+			return -ENOIOCTLCMD;
+
+		return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK);
+
+	case VIDIOC_SUBSCRIBE_EVENT:
+		return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg);
+
+	case VIDIOC_UNSUBSCRIBE_EVENT:
+		return v4l2_subdev_call(sd, core, unsubscribe_event, vfh, arg);
+
+	case VIDIOC_MSM_CPP_GET_INST_INFO: {
+		uint32_t i;
+		struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd);
+		struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
+		struct msm_cpp_frame_info_t inst_info;
+		for (i = 0; i < MAX_ACTIVE_CPP_INSTANCE; i++) {
+			if (cpp_dev->cpp_subscribe_list[i].vfh == vfh) {
+				inst_info.inst_id = i;
+				break;
+			}
+		}
+		if (copy_to_user(
+				(void __user *)ioctl_ptr->ioctl_ptr, &inst_info,
+				sizeof(struct msm_cpp_frame_info_t))) {
+			return -EINVAL;
+		}
+	}
+	break;
+	default:
+		return v4l2_subdev_call(sd, core, ioctl, cmd, arg);
+	}
+
+	return 0;
+}
+
+static long msm_cpp_subdev_fops_ioctl(struct file *file, unsigned int cmd,
+	unsigned long arg)
+{
+	return video_usercopy(file, cmd, arg, msm_cpp_subdev_do_ioctl);
+}
+
+static int __devinit cpp_probe(struct platform_device *pdev)
+{
+	struct cpp_device *cpp_dev;
+	struct msm_cam_subdev_info sd_info;
+	int rc = 0;
+	CDBG("%s: device id = %d\n", __func__, pdev->id);
+	cpp_dev = kzalloc(sizeof(struct cpp_device), GFP_KERNEL);
+	if (!cpp_dev) {
+		pr_err("%s: no enough memory\n", __func__);
+		return -ENOMEM;
+	}
+	v4l2_subdev_init(&cpp_dev->subdev, &msm_cpp_subdev_ops);
+	cpp_dev->subdev.internal_ops = &msm_cpp_internal_ops;
+	snprintf(cpp_dev->subdev.name, ARRAY_SIZE(cpp_dev->subdev.name),
+		 "cpp");
+	cpp_dev->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	cpp_dev->subdev.flags |= V4L2_SUBDEV_FL_HAS_EVENTS;
+	v4l2_set_subdevdata(&cpp_dev->subdev, cpp_dev);
+	platform_set_drvdata(pdev, &cpp_dev->subdev);
+	mutex_init(&cpp_dev->mutex);
+
+	cpp_dev->pdev = pdev;
+
+	media_entity_init(&cpp_dev->subdev.entity, 0, NULL, 0);
+	cpp_dev->subdev.entity.type = MEDIA_ENT_T_DEVNODE_V4L;
+	cpp_dev->subdev.entity.group_id = CPP_DEV;
+	cpp_dev->subdev.entity.name = pdev->name;
+	sd_info.sdev_type = CPP_DEV;
+	sd_info.sd_index = pdev->id;
+	msm_cam_register_subdev_node(&cpp_dev->subdev, &sd_info);
+	msm_cpp_v4l2_subdev_fops.owner = v4l2_subdev_fops.owner;
+	msm_cpp_v4l2_subdev_fops.open = v4l2_subdev_fops.open;
+	msm_cpp_v4l2_subdev_fops.unlocked_ioctl = msm_cpp_subdev_fops_ioctl;
+	msm_cpp_v4l2_subdev_fops.release = v4l2_subdev_fops.release;
+	msm_cpp_v4l2_subdev_fops.poll = v4l2_subdev_fops.poll;
+
+	cpp_dev->subdev.devnode->fops = &msm_cpp_v4l2_subdev_fops;
+	cpp_dev->subdev.entity.revision = cpp_dev->subdev.devnode->num;
+	msm_cpp_enable_debugfs(cpp_dev);
+	msm_queue_init(&cpp_dev->eventData_q, "eventdata");
+	msm_queue_init(&cpp_dev->offline_q, "frame");
+	msm_queue_init(&cpp_dev->realtime_q, "frame");
+	msm_queue_init(&cpp_dev->processing_q, "frame");
+	cpp_dev->cpp_open_cnt = 0;
+
+	return rc;
+}
+
+static struct platform_driver cpp_driver = {
+	.probe = cpp_probe,
+	.driver = {
+		.name = MSM_CPP_DRV_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init msm_cpp_init_module(void)
+{
+	return platform_driver_register(&cpp_driver);
+}
+
+static void __exit msm_cpp_exit_module(void)
+{
+	platform_driver_unregister(&cpp_driver);
+}
+
+static int msm_cpp_debugfs_stream_s(void *data, u64 val)
+{
+	struct cpp_device *cpp_dev = data;
+	CPP_DBG("CPP processing frame E\n");
+	while (1) {
+		mutex_lock(&cpp_dev->mutex);
+		msm_cpp_notify_frame_done(cpp_dev);
+		msm_cpp_send_frame_to_hardware(cpp_dev);
+		mutex_unlock(&cpp_dev->mutex);
+		msleep(20);
+	}
+	CPP_DBG("CPP processing frame X\n");
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(cpp_debugfs_stream, NULL,
+			msm_cpp_debugfs_stream_s, "%llu\n");
+
+static int msm_cpp_enable_debugfs(struct cpp_device *cpp_dev)
+{
+	struct dentry *debugfs_base;
+	debugfs_base = debugfs_create_dir("msm_camera", NULL);
+	if (!debugfs_base)
+		return -ENOMEM;
+
+	if (!debugfs_create_file("test", S_IRUGO | S_IWUSR, debugfs_base,
+			(void *)cpp_dev, &cpp_debugfs_stream))
+		return -ENOMEM;
+
+	return 0;
+}
+
+module_init(msm_cpp_init_module);
+module_exit(msm_cpp_exit_module);
+MODULE_DESCRIPTION("MSM CPP driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/cpp/msm_cpp.h b/drivers/media/platform/msm/camera_v1/cpp/msm_cpp.h
new file mode 100644
index 0000000..f585569
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/cpp/msm_cpp.h
@@ -0,0 +1,65 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <media/v4l2-subdev.h>
+
+#define MAX_ACTIVE_CPP_INSTANCE 8
+#define MAX_CPP_PROCESSING_FRAME 2
+#define MAX_CPP_V4l2_EVENTS 30
+
+#define MSM_CPP_MICRO_BASE          0x4000
+#define MSM_CPP_MICRO_HW_VERSION    0x0000
+#define MSM_CPP_MICRO_IRQGEN_STAT   0x0004
+#define MSM_CPP_MICRO_IRQGEN_CLR    0x0008
+#define MSM_CPP_MICRO_IRQGEN_MASK   0x000C
+#define MSM_CPP_MICRO_FIFO_TX_DATA  0x0010
+#define MSM_CPP_MICRO_FIFO_TX_STAT  0x0014
+#define MSM_CPP_MICRO_FIFO_RX_DATA  0x0018
+#define MSM_CPP_MICRO_FIFO_RX_STAT  0x001C
+#define MSM_CPP_MICRO_BOOT_START    0x0020
+#define MSM_CPP_MICRO_BOOT_LDORG    0x0024
+#define MSM_CPP_MICRO_CLKEN_CTL     0x0030
+
+struct cpp_subscribe_info {
+	struct v4l2_fh *vfh;
+	uint32_t active;
+};
+
+struct cpp_device {
+	struct platform_device *pdev;
+	struct v4l2_subdev subdev;
+	struct resource *mem;
+	struct resource *irq;
+	struct resource *io;
+	void __iomem *base;
+	struct clk *cpp_clk[2];
+	struct mutex mutex;
+
+	struct cpp_subscribe_info cpp_subscribe_list[MAX_ACTIVE_CPP_INSTANCE];
+	uint32_t cpp_open_cnt;
+
+	struct msm_device_queue eventData_q; /*V4L2 Event Payload Queue*/
+
+	/*Offline Frame Queue
+	  process when realtime queue is empty*/
+	struct msm_device_queue offline_q;
+	/*Realtime Frame Queue
+	  process with highest priority*/
+	struct msm_device_queue realtime_q;
+	/*Processing Queue
+	  store frame info for frames sent to microcontroller*/
+	struct msm_device_queue processing_q;
+};
+
diff --git a/drivers/media/platform/msm/camera_v1/csi/Makefile b/drivers/media/platform/msm/camera_v1/csi/Makefile
new file mode 100644
index 0000000..6284511
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/csi/Makefile
@@ -0,0 +1,15 @@
+GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
+ccflags-y += -Idrivers/media/platform/msm/camera_v1 -Idrivers/media/platform/msm/camera_v1/server
+ifeq ($(CONFIG_MSM_CSI20_HEADER),y)
+  ccflags-y += -Idrivers/media/platform/msm/camera_v1/csi/include/csi2.0
+else ifeq ($(CONFIG_MSM_CSI30_HEADER),y)
+  ccflags-y += -Idrivers/media/platform/msm/camera_v1/csi/include/csi3.0
+endif
+obj-$(CONFIG_MSM_CSI2_REGISTER) += msm_csi2_register.o
+obj-$(CONFIG_MSM_CSIPHY) += msm_csiphy.o
+obj-$(CONFIG_MSM_CSID) += msm_csid.o
+obj-$(CONFIG_MSM_ISPIF) += msm_ispif.o
+obj-$(CONFIG_ARCH_MSM8960) += msm_csi2_register.o msm_csiphy.o msm_csid.o msm_ispif.o
+obj-$(CONFIG_ARCH_MSM7X27A) += msm_csic_register.o msm_csic.o
+obj-$(CONFIG_ARCH_MSM8X60) += msm_csic_register.o msm_csic.o
+obj-$(CONFIG_ARCH_MSM7X30) += msm_csic_register.o msm_csic.o
diff --git a/drivers/media/platform/msm/camera_v1/csi/include/csi2.0/msm_csid_hwreg.h b/drivers/media/platform/msm/camera_v1/csi/include/csi2.0/msm_csid_hwreg.h
new file mode 100644
index 0000000..cc8a9cf
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/csi/include/csi2.0/msm_csid_hwreg.h
@@ -0,0 +1,52 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_CSID_HWREG_H
+#define MSM_CSID_HWREG_H
+
+/* MIPI	CSID registers */
+#define CSID_HW_VERSION_ADDR                        0x0
+#define CSID_CORE_CTRL_0_ADDR                       0x4
+#define CSID_CORE_CTRL_1_ADDR                       0x4
+#define CSID_RST_CMD_ADDR                           0x8
+#define CSID_CID_LUT_VC_0_ADDR                      0xc
+#define CSID_CID_LUT_VC_1_ADDR                      0x10
+#define CSID_CID_LUT_VC_2_ADDR                      0x14
+#define CSID_CID_LUT_VC_3_ADDR                      0x18
+#define CSID_CID_n_CFG_ADDR                         0x1C
+#define CSID_IRQ_CLEAR_CMD_ADDR                     0x5c
+#define CSID_IRQ_MASK_ADDR                          0x60
+#define CSID_IRQ_STATUS_ADDR                        0x64
+#define CSID_CAPTURED_UNMAPPED_LONG_PKT_HDR_ADDR    0x68
+#define CSID_CAPTURED_MMAPPED_LONG_PKT_HDR_ADDR     0x6c
+#define CSID_CAPTURED_SHORT_PKT_ADDR                0x70
+#define CSID_CAPTURED_LONG_PKT_HDR_ADDR             0x74
+#define CSID_CAPTURED_LONG_PKT_FTR_ADDR             0x78
+#define CSID_PIF_MISR_DL0_ADDR                      0x7C
+#define CSID_PIF_MISR_DL1_ADDR                      0x80
+#define CSID_PIF_MISR_DL2_ADDR                      0x84
+#define CSID_PIF_MISR_DL3_ADDR                      0x88
+#define CSID_STATS_TOTAL_PKTS_RCVD_ADDR             0x8C
+#define CSID_STATS_ECC_ADDR                         0x90
+#define CSID_STATS_CRC_ADDR                         0x94
+#define CSID_TG_CTRL_ADDR                           0x9C
+#define CSID_TG_VC_CFG_ADDR                         0xA0
+#define CSID_TG_DT_n_CFG_0_ADDR                     0xA8
+#define CSID_TG_DT_n_CFG_1_ADDR                     0xAC
+#define CSID_TG_DT_n_CFG_2_ADDR                     0xB0
+#define CSID_RST_DONE_IRQ_BITSHIFT                  11
+#define CSID_RST_STB_ALL                            0x7FFF
+#define CSID_DL_INPUT_SEL_SHIFT                     0x2
+#define CSID_PHY_SEL_SHIFT                          17
+#define CSID_VERSION                                0x02000011
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v1/csi/include/csi2.0/msm_csiphy_hwreg.h b/drivers/media/platform/msm/camera_v1/csi/include/csi2.0/msm_csiphy_hwreg.h
new file mode 100644
index 0000000..9263483
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/csi/include/csi2.0/msm_csiphy_hwreg.h
@@ -0,0 +1,43 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_CSIPHY_HWREG_H
+#define MSM_CSIPHY_HWREG_H
+
+/*MIPI CSI PHY registers*/
+#define MIPI_CSIPHY_HW_VERSION_ADDR              0x180
+#define MIPI_CSIPHY_LNn_CFG1_ADDR                0x0
+#define MIPI_CSIPHY_LNn_CFG2_ADDR                0x4
+#define MIPI_CSIPHY_LNn_CFG3_ADDR                0x8
+#define MIPI_CSIPHY_LNn_CFG4_ADDR                0xC
+#define MIPI_CSIPHY_LNn_CFG5_ADDR                0x10
+#define MIPI_CSIPHY_LNCK_CFG1_ADDR               0x100
+#define MIPI_CSIPHY_LNCK_CFG2_ADDR               0x104
+#define MIPI_CSIPHY_LNCK_CFG3_ADDR               0x108
+#define MIPI_CSIPHY_LNCK_CFG4_ADDR               0x10C
+#define MIPI_CSIPHY_LNCK_CFG5_ADDR               0x110
+#define MIPI_CSIPHY_LNCK_MISC1_ADDR              0x128
+#define MIPI_CSIPHY_GLBL_RESET_ADDR              0x140
+#define MIPI_CSIPHY_GLBL_PWR_CFG_ADDR            0x144
+#define MIPI_CSIPHY_GLBL_IRQ_CMD_ADDR            0x164
+#define MIPI_CSIPHY_INTERRUPT_STATUS0_ADDR       0x180
+#define MIPI_CSIPHY_INTERRUPT_MASK0_ADDR         0x1A0
+#define MIPI_CSIPHY_INTERRUPT_MASK_VAL           0x6F
+#define MIPI_CSIPHY_INTERRUPT_MASK_ADDR          0x1A4
+#define MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR        0x1C0
+#define MIPI_CSIPHY_INTERRUPT_CLEAR_ADDR         0x1C4
+#define MIPI_CSIPHY_MODE_CONFIG_SHIFT            0x4
+#define MIPI_CSIPHY_GLBL_T_INIT_CFG0_ADDR        0x1E0
+#define MIPI_CSIPHY_T_WAKEUP_CFG0_ADDR           0x1E8
+#define CSIPHY_VERSION                           0x0
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v1/csi/include/csi2.0/msm_ispif_hwreg.h b/drivers/media/platform/msm/camera_v1/csi/include/csi2.0/msm_ispif_hwreg.h
new file mode 100644
index 0000000..1864d40
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/csi/include/csi2.0/msm_ispif_hwreg.h
@@ -0,0 +1,88 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_ISPIF_HWREG_H
+#define MSM_ISPIF_HWREG_H
+
+
+/* ISPIF registers */
+
+#define ISPIF_RST_CMD_ADDR                        0x00
+#define ISPIF_RST_CMD_1_ADDR                      0x00
+#define ISPIF_INTF_CMD_ADDR                       0x04
+#define ISPIF_INTF_CMD_1_ADDR                     0x30
+#define ISPIF_CTRL_ADDR                           0x08
+#define ISPIF_INPUT_SEL_ADDR                      0x0C
+#define ISPIF_PIX_0_INTF_CID_MASK_ADDR            0x10
+#define ISPIF_RDI_0_INTF_CID_MASK_ADDR            0x14
+#define ISPIF_PIX_1_INTF_CID_MASK_ADDR            0x38
+#define ISPIF_RDI_1_INTF_CID_MASK_ADDR            0x3C
+#define ISPIF_RDI_2_INTF_CID_MASK_ADDR            0x44
+#define ISPIF_PIX_0_STATUS_ADDR                   0x24
+#define ISPIF_RDI_0_STATUS_ADDR                   0x28
+#define ISPIF_PIX_1_STATUS_ADDR                   0x60
+#define ISPIF_RDI_1_STATUS_ADDR                   0x64
+#define ISPIF_RDI_2_STATUS_ADDR                   0x6C
+#define ISPIF_IRQ_MASK_ADDR                     0x0100
+#define ISPIF_IRQ_CLEAR_ADDR                    0x0104
+#define ISPIF_IRQ_STATUS_ADDR                   0x0108
+#define ISPIF_IRQ_MASK_1_ADDR                   0x010C
+#define ISPIF_IRQ_CLEAR_1_ADDR                  0x0110
+#define ISPIF_IRQ_STATUS_1_ADDR                 0x0114
+#define ISPIF_IRQ_MASK_2_ADDR                   0x0118
+#define ISPIF_IRQ_CLEAR_2_ADDR                  0x011C
+#define ISPIF_IRQ_STATUS_2_ADDR                 0x0120
+#define ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR         0x0124
+
+/*ISPIF RESET BITS*/
+
+#define VFE_CLK_DOMAIN_RST           31
+#define RDI_CLK_DOMAIN_RST           30
+#define PIX_CLK_DOMAIN_RST           29
+#define AHB_CLK_DOMAIN_RST           28
+#define RDI_1_CLK_DOMAIN_RST         27
+#define RDI_2_VFE_RST_STB            19
+#define RDI_2_CSID_RST_STB           18
+#define RDI_1_VFE_RST_STB            13
+#define RDI_1_CSID_RST_STB           12
+#define RDI_0_VFE_RST_STB            7
+#define RDI_0_CSID_RST_STB           6
+#define PIX_1_VFE_RST_STB            10
+#define PIX_1_CSID_RST_STB           9
+#define PIX_0_VFE_RST_STB            4
+#define PIX_0_CSID_RST_STB           3
+#define SW_REG_RST_STB               2
+#define MISC_LOGIC_RST_STB           1
+#define STROBED_RST_EN               0
+
+#define ISPIF_RST_CMD_MASK           0xFE0F1FFF
+#define ISPIF_RST_CMD_1_MASK         0xFC0F1FF9
+
+#define PIX_INTF_0_OVERFLOW_IRQ      12
+#define RAW_INTF_0_OVERFLOW_IRQ      25
+#define RAW_INTF_1_OVERFLOW_IRQ      25
+#define RAW_INTF_2_OVERFLOW_IRQ      12
+#define RESET_DONE_IRQ               27
+
+#define ISPIF_IRQ_STATUS_MASK        0x0A493249
+#define ISPIF_IRQ_STATUS_1_MASK      0x02493249
+#define ISPIF_IRQ_STATUS_2_MASK      0x00001249
+
+#define ISPIF_IRQ_STATUS_PIX_SOF_MASK	0x249
+#define ISPIF_IRQ_STATUS_RDI0_SOF_MASK	0x492000
+#define ISPIF_IRQ_STATUS_RDI1_SOF_MASK	0x492000
+#define ISPIF_IRQ_STATUS_RDI2_SOF_MASK	0x249
+
+#define ISPIF_IRQ_STATUS_SOF_MASK	0x492249
+#define ISPIF_IRQ_GLOBAL_CLEAR_CMD     0x1
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v1/csi/include/csi3.0/msm_csid_hwreg.h b/drivers/media/platform/msm/camera_v1/csi/include/csi3.0/msm_csid_hwreg.h
new file mode 100644
index 0000000..7f35c2c
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/csi/include/csi3.0/msm_csid_hwreg.h
@@ -0,0 +1,52 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_CSID_HWREG_H
+#define MSM_CSID_HWREG_H
+
+/* MIPI	CSID registers */
+#define CSID_HW_VERSION_ADDR                        0x0
+#define CSID_CORE_CTRL_0_ADDR                       0x4
+#define CSID_CORE_CTRL_1_ADDR                       0x8
+#define CSID_RST_CMD_ADDR                           0xC
+#define CSID_CID_LUT_VC_0_ADDR                      0x10
+#define CSID_CID_LUT_VC_1_ADDR                      0x14
+#define CSID_CID_LUT_VC_2_ADDR                      0x18
+#define CSID_CID_LUT_VC_3_ADDR                      0x1C
+#define CSID_CID_n_CFG_ADDR                         0x20
+#define CSID_IRQ_CLEAR_CMD_ADDR                     0x60
+#define CSID_IRQ_MASK_ADDR                          0x64
+#define CSID_IRQ_STATUS_ADDR                        0x68
+#define CSID_CAPTURED_UNMAPPED_LONG_PKT_HDR_ADDR    0x6C
+#define CSID_CAPTURED_MMAPPED_LONG_PKT_HDR_ADDR     0x70
+#define CSID_CAPTURED_SHORT_PKT_ADDR                0x74
+#define CSID_CAPTURED_LONG_PKT_HDR_ADDR             0x78
+#define CSID_CAPTURED_LONG_PKT_FTR_ADDR             0x7C
+#define CSID_PIF_MISR_DL0_ADDR                      0x80
+#define CSID_PIF_MISR_DL1_ADDR                      0x84
+#define CSID_PIF_MISR_DL2_ADDR                      0x88
+#define CSID_PIF_MISR_DL3_ADDR                      0x8C
+#define CSID_STATS_TOTAL_PKTS_RCVD_ADDR             0x90
+#define CSID_STATS_ECC_ADDR                         0x94
+#define CSID_STATS_CRC_ADDR                         0x98
+#define CSID_TG_CTRL_ADDR                           0xA0
+#define CSID_TG_VC_CFG_ADDR                         0xA4
+#define CSID_TG_DT_n_CFG_0_ADDR                     0xAC
+#define CSID_TG_DT_n_CFG_1_ADDR                     0xB0
+#define CSID_TG_DT_n_CFG_2_ADDR                     0xB4
+#define CSID_RST_DONE_IRQ_BITSHIFT                  11
+#define CSID_RST_STB_ALL                            0x7FFF
+#define CSID_DL_INPUT_SEL_SHIFT                     0x4
+#define CSID_PHY_SEL_SHIFT                          17
+#define CSID_VERSION                                0x30000000
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v1/csi/include/csi3.0/msm_csiphy_hwreg.h b/drivers/media/platform/msm/camera_v1/csi/include/csi3.0/msm_csiphy_hwreg.h
new file mode 100644
index 0000000..c290731
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/csi/include/csi3.0/msm_csiphy_hwreg.h
@@ -0,0 +1,43 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_CSIPHY_HWREG_H
+#define MSM_CSIPHY_HWREG_H
+
+/*MIPI CSI PHY registers*/
+#define MIPI_CSIPHY_LNn_CFG1_ADDR                0x0
+#define MIPI_CSIPHY_LNn_CFG2_ADDR                0x4
+#define MIPI_CSIPHY_LNn_CFG3_ADDR                0x8
+#define MIPI_CSIPHY_LNn_CFG4_ADDR                0xC
+#define MIPI_CSIPHY_LNn_CFG5_ADDR                0x10
+#define MIPI_CSIPHY_LNCK_CFG1_ADDR               0x100
+#define MIPI_CSIPHY_LNCK_CFG2_ADDR               0x104
+#define MIPI_CSIPHY_LNCK_CFG3_ADDR               0x108
+#define MIPI_CSIPHY_LNCK_CFG4_ADDR               0x10C
+#define MIPI_CSIPHY_LNCK_CFG5_ADDR               0x110
+#define MIPI_CSIPHY_LNCK_MISC1_ADDR              0x128
+#define MIPI_CSIPHY_GLBL_RESET_ADDR              0x140
+#define MIPI_CSIPHY_GLBL_PWR_CFG_ADDR            0x144
+#define MIPI_CSIPHY_GLBL_IRQ_CMD_ADDR            0x164
+#define MIPI_CSIPHY_HW_VERSION_ADDR              0x188
+#define MIPI_CSIPHY_INTERRUPT_STATUS0_ADDR       0x18C
+#define MIPI_CSIPHY_INTERRUPT_MASK0_ADDR         0x1AC
+#define MIPI_CSIPHY_INTERRUPT_MASK_VAL           0x3F
+#define MIPI_CSIPHY_INTERRUPT_MASK_ADDR          0x1AC
+#define MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR        0x1CC
+#define MIPI_CSIPHY_INTERRUPT_CLEAR_ADDR         0x1CC
+#define MIPI_CSIPHY_MODE_CONFIG_SHIFT            0x4
+#define MIPI_CSIPHY_GLBL_T_INIT_CFG0_ADDR        0x1EC
+#define MIPI_CSIPHY_T_WAKEUP_CFG0_ADDR           0x1F4
+#define CSIPHY_VERSION                           0x10
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v1/csi/include/csi3.0/msm_ispif_hwreg.h b/drivers/media/platform/msm/camera_v1/csi/include/csi3.0/msm_ispif_hwreg.h
new file mode 100644
index 0000000..4b69dda
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/csi/include/csi3.0/msm_ispif_hwreg.h
@@ -0,0 +1,102 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_ISPIF_HWREG_H
+#define MSM_ISPIF_HWREG_H
+
+
+/* ISPIF registers */
+
+#define ISPIF_RST_CMD_ADDR                        0x08
+#define ISPIF_RST_CMD_1_ADDR                      0x0C
+#define ISPIF_INTF_CMD_ADDR                      0x248
+#define ISPIF_INTF_CMD_1_ADDR                    0x24C
+#define ISPIF_CTRL_ADDR                           0x08
+#define ISPIF_INPUT_SEL_ADDR                     0x244
+#define ISPIF_PIX_0_INTF_CID_MASK_ADDR           0x254
+#define ISPIF_RDI_0_INTF_CID_MASK_ADDR           0x264
+#define ISPIF_PIX_1_INTF_CID_MASK_ADDR           0x258
+#define ISPIF_RDI_1_INTF_CID_MASK_ADDR           0x268
+#define ISPIF_RDI_2_INTF_CID_MASK_ADDR           0x26C
+#define ISPIF_PIX_0_STATUS_ADDR                  0x2C0
+#define ISPIF_RDI_0_STATUS_ADDR                  0x2D0
+#define ISPIF_PIX_1_STATUS_ADDR                  0x2C4
+#define ISPIF_RDI_1_STATUS_ADDR                  0x2D4
+#define ISPIF_RDI_2_STATUS_ADDR                  0x2D8
+#define ISPIF_IRQ_MASK_ADDR                      0x208
+#define ISPIF_IRQ_CLEAR_ADDR                     0x230
+#define ISPIF_IRQ_STATUS_ADDR                    0x21C
+#define ISPIF_IRQ_MASK_1_ADDR                    0x20C
+#define ISPIF_IRQ_CLEAR_1_ADDR                   0x234
+#define ISPIF_IRQ_STATUS_1_ADDR                  0x220
+#define ISPIF_IRQ_MASK_2_ADDR                    0x210
+#define ISPIF_IRQ_CLEAR_2_ADDR                   0x238
+#define ISPIF_IRQ_STATUS_2_ADDR                  0x224
+#define ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR           0x1C
+
+/* new */
+#define ISPIF_VFE_m_CTRL_0_ADDR                  0x200
+#define ISPIF_VFE_m_IRQ_MASK_0                   0x208
+#define ISPIF_VFE_m_IRQ_MASK_1                   0x20C
+#define ISPIF_VFE_m_IRQ_MASK_2                   0x210
+#define ISPIF_VFE_m_IRQ_STATUS_0                 0x21C
+#define ISPIF_VFE_m_IRQ_STATUS_1                 0x220
+#define ISPIF_VFE_m_IRQ_STATUS_2                 0x224
+#define ISPIF_VFE_m_IRQ_CLEAR_0                  0x230
+#define ISPIF_VFE_m_IRQ_CLEAR_1                  0x234
+#define ISPIF_VFE_m_IRQ_CLEAR_2                  0x238
+
+/*ISPIF RESET BITS*/
+
+#define VFE_CLK_DOMAIN_RST           31
+#define RDI_CLK_DOMAIN_RST           26
+#define RDI_1_CLK_DOMAIN_RST         27
+#define RDI_2_CLK_DOMAIN_RST         28
+#define PIX_CLK_DOMAIN_RST           29
+#define PIX_1_CLK_DOMAIN_RST         30
+#define AHB_CLK_DOMAIN_RST           25
+#define RDI_2_VFE_RST_STB            12
+#define RDI_2_CSID_RST_STB           11
+#define RDI_1_VFE_RST_STB            10
+#define RDI_1_CSID_RST_STB           9
+#define RDI_0_VFE_RST_STB            8
+#define RDI_0_CSID_RST_STB           7
+#define PIX_1_VFE_RST_STB            6
+#define PIX_1_CSID_RST_STB           5
+#define PIX_0_VFE_RST_STB            4
+#define PIX_0_CSID_RST_STB           3
+#define SW_REG_RST_STB               2
+#define MISC_LOGIC_RST_STB           1
+#define STROBED_RST_EN               0
+
+#define ISPIF_RST_CMD_MASK           0xFE0F1FFF
+#define ISPIF_RST_CMD_1_MASK         0xFC0F1FF9
+
+#define PIX_INTF_0_OVERFLOW_IRQ      12
+#define RAW_INTF_0_OVERFLOW_IRQ      25
+#define RAW_INTF_1_OVERFLOW_IRQ      25
+#define RAW_INTF_2_OVERFLOW_IRQ      12
+#define RESET_DONE_IRQ               27
+
+#define ISPIF_IRQ_STATUS_MASK        0x0A493249
+#define ISPIF_IRQ_STATUS_1_MASK      0x02493249
+#define ISPIF_IRQ_STATUS_2_MASK      0x00001249
+
+#define ISPIF_IRQ_STATUS_PIX_SOF_MASK	0x249
+#define ISPIF_IRQ_STATUS_RDI0_SOF_MASK	0x492000
+#define ISPIF_IRQ_STATUS_RDI1_SOF_MASK	0x492000
+#define ISPIF_IRQ_STATUS_RDI2_SOF_MASK	0x249
+
+#define ISPIF_IRQ_STATUS_SOF_MASK	0x492249
+#define ISPIF_IRQ_GLOBAL_CLEAR_CMD     0x1
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v1/csi/msm_csi2_register.c b/drivers/media/platform/msm/camera_v1/csi/msm_csi2_register.c
new file mode 100644
index 0000000..cebfa7f
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/csi/msm_csi2_register.c
@@ -0,0 +1,50 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/device.h>
+#include "msm.h"
+#include "msm_csi_register.h"
+
+int msm_csi_register_subdevs(struct msm_cam_media_controller *p_mctl,
+	uint8_t csiphy_code_index, uint8_t csid_core_index,
+	struct msm_cam_server_dev *server_dev)
+{
+	int rc = -ENODEV;
+
+	CDBG("%s csiphy sel %d csid sel %d\n", __func__, csiphy_code_index,
+		csid_core_index);
+	/* register csiphy subdev */
+	p_mctl->csiphy_sdev = server_dev->csiphy_device[csiphy_code_index];
+	if (!p_mctl->csiphy_sdev)
+		goto out;
+	v4l2_set_subdev_hostdata(p_mctl->csiphy_sdev, p_mctl);
+
+	/* register csid subdev */
+	p_mctl->csid_sdev = server_dev->csid_device[csid_core_index];
+	if (!p_mctl->csid_sdev)
+		goto out;
+	v4l2_set_subdev_hostdata(p_mctl->csid_sdev, p_mctl);
+
+	/* register ispif subdev */
+	p_mctl->ispif_sdev = server_dev->ispif_device[0];
+	if (!p_mctl->ispif_sdev)
+		goto out;
+	v4l2_set_subdev_hostdata(p_mctl->ispif_sdev, p_mctl);
+
+	rc = 0;
+	return rc;
+out:
+	p_mctl->ispif_sdev = NULL;
+	return rc;
+}
+
diff --git a/drivers/media/platform/msm/camera_v1/csi/msm_csi_register.h b/drivers/media/platform/msm/camera_v1/csi/msm_csi_register.h
new file mode 100644
index 0000000..b276267
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/csi/msm_csi_register.h
@@ -0,0 +1,16 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+int msm_csi_register_subdevs(struct msm_cam_media_controller *p_mctl,
+	uint8_t csiphy_code_index, uint8_t csid_core_index,
+	struct msm_cam_server_dev *server_dev);
diff --git a/drivers/media/platform/msm/camera_v1/csi/msm_csic.c b/drivers/media/platform/msm/camera_v1/csi/msm_csic.c
new file mode 100644
index 0000000..34489cb
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/csi/msm_csic.c
@@ -0,0 +1,523 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <mach/clk.h>
+#include <mach/board.h>
+#include <mach/camera.h>
+#include <media/msm_isp.h>
+#include "msm_csic.h"
+#include "msm.h"
+
+#define DBG_CSIC 0
+
+#define V4L2_IDENT_CSIC			50004
+/* MIPI	CSI controller registers */
+#define	MIPI_PHY_CONTROL		0x00000000
+#define	MIPI_PROTOCOL_CONTROL		0x00000004
+#define	MIPI_INTERRUPT_STATUS		0x00000008
+#define	MIPI_INTERRUPT_MASK		0x0000000C
+#define	MIPI_CAMERA_CNTL		0x00000024
+#define	MIPI_CALIBRATION_CONTROL	0x00000018
+#define	MIPI_PHY_D0_CONTROL2		0x00000038
+#define	MIPI_PHY_D1_CONTROL2		0x0000003C
+#define	MIPI_PHY_D2_CONTROL2		0x00000040
+#define	MIPI_PHY_D3_CONTROL2		0x00000044
+#define	MIPI_PHY_CL_CONTROL		0x00000048
+#define	MIPI_PHY_D0_CONTROL		0x00000034
+#define	MIPI_PHY_D1_CONTROL		0x00000020
+#define	MIPI_PHY_D2_CONTROL		0x0000002C
+#define	MIPI_PHY_D3_CONTROL		0x00000030
+#define	MIPI_PWR_CNTL			0x00000054
+
+/*
+ * MIPI_PROTOCOL_CONTROL register bits to enable/disable the features of
+ * CSI Rx Block
+ */
+
+/* DPCM scheme */
+#define	MIPI_PROTOCOL_CONTROL_DPCM_SCHEME_SHFT			0x1e
+/* SW_RST to issue a SW reset to the CSI core */
+#define	MIPI_PROTOCOL_CONTROL_SW_RST_BMSK			0x8000000
+/* To Capture Long packet Header Info in MIPI_PROTOCOL_STATUS register */
+#define	MIPI_PROTOCOL_CONTROL_LONG_PACKET_HEADER_CAPTURE_BMSK	0x200000
+/* Data format for unpacking purpose */
+#define	MIPI_PROTOCOL_CONTROL_DATA_FORMAT_SHFT			0x13
+/* Enable decoding of payload based on data type filed of packet hdr */
+#define	MIPI_PROTOCOL_CONTROL_DECODE_ID_BMSK			0x40000
+/* Enable error correction on packet headers */
+#define	MIPI_PROTOCOL_CONTROL_ECC_EN_BMSK			0x20000
+
+/*
+ * MIPI_CALIBRATION_CONTROL register contains control info for
+ * calibration impledence controller
+*/
+
+/* Enable bit for calibration pad */
+#define	MIPI_CALIBRATION_CONTROL_SWCAL_CAL_EN_SHFT		0x16
+/* With SWCAL_STRENGTH_OVERRIDE_EN, SW_CAL_EN and MANUAL_OVERRIDE_EN
+ * the hardware calibration circuitry associated with CAL_SW_HW_MODE
+ * is bypassed
+*/
+#define	MIPI_CALIBRATION_CONTROL_SWCAL_STRENGTH_OVERRIDE_EN_SHFT	0x15
+/* To indicate the Calibration process is in the control of HW/SW */
+#define	MIPI_CALIBRATION_CONTROL_CAL_SW_HW_MODE_SHFT		0x14
+/* When this is set the strength value of the data and clk lane impedence
+ * termination is updated with MANUAL_STRENGTH settings and calibration
+ * sensing logic is idle.
+*/
+#define	MIPI_CALIBRATION_CONTROL_MANUAL_OVERRIDE_EN_SHFT	0x7
+
+/* Data lane0 control */
+/* T-hs Settle count value  for Rx */
+#define	MIPI_PHY_D0_CONTROL2_SETTLE_COUNT_SHFT			0x18
+/* Rx termination control */
+#define	MIPI_PHY_D0_CONTROL2_HS_TERM_IMP_SHFT			0x10
+/* LP Rx enable */
+#define	MIPI_PHY_D0_CONTROL2_LP_REC_EN_SHFT			0x4
+/*
+ * Enable for error in sync sequence
+ * 1 - one bit error in sync seq
+ * 0 - requires all 8 bit correct seq
+*/
+#define	MIPI_PHY_D0_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
+
+/* Comments are same as D0 */
+#define	MIPI_PHY_D1_CONTROL2_SETTLE_COUNT_SHFT			0x18
+#define	MIPI_PHY_D1_CONTROL2_HS_TERM_IMP_SHFT			0x10
+#define	MIPI_PHY_D1_CONTROL2_LP_REC_EN_SHFT			0x4
+#define	MIPI_PHY_D1_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
+
+/* Comments are same as D0 */
+#define	MIPI_PHY_D2_CONTROL2_SETTLE_COUNT_SHFT			0x18
+#define	MIPI_PHY_D2_CONTROL2_HS_TERM_IMP_SHFT			0x10
+#define	MIPI_PHY_D2_CONTROL2_LP_REC_EN_SHFT			0x4
+#define	MIPI_PHY_D2_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
+
+/* Comments are same as D0 */
+#define	MIPI_PHY_D3_CONTROL2_SETTLE_COUNT_SHFT			0x18
+#define	MIPI_PHY_D3_CONTROL2_HS_TERM_IMP_SHFT			0x10
+#define	MIPI_PHY_D3_CONTROL2_LP_REC_EN_SHFT			0x4
+#define	MIPI_PHY_D3_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
+
+/* PHY_CL_CTRL programs the parameters of clk lane of CSIRXPHY */
+/* HS Rx termination control */
+#define	MIPI_PHY_CL_CONTROL_HS_TERM_IMP_SHFT			0x18
+/* Start signal for T-hs delay */
+#define	MIPI_PHY_CL_CONTROL_LP_REC_EN_SHFT			0x2
+
+/* PHY DATA lane 0 control */
+/*
+ * HS RX equalizer strength control
+ * 00 - 0db 01 - 3db 10 - 5db 11 - 7db
+*/
+#define	MIPI_PHY_D0_CONTROL_HS_REC_EQ_SHFT			0x1c
+/* PHY DATA lane 1 control */
+/* Shutdown signal for MIPI clk phy line */
+#define	MIPI_PHY_D1_CONTROL_MIPI_CLK_PHY_SHUTDOWNB_SHFT		0x9
+/* Shutdown signal for MIPI data phy line */
+#define	MIPI_PHY_D1_CONTROL_MIPI_DATA_PHY_SHUTDOWNB_SHFT	0x8
+
+#define MSM_AXI_QOS_PREVIEW 200000
+#define MSM_AXI_QOS_SNAPSHOT 200000
+#define MSM_AXI_QOS_RECORDING 200000
+
+#define MIPI_PWR_CNTL_EN	0x07
+#define MIPI_PWR_CNTL_DIS	0x0
+
+static int msm_csic_config(struct v4l2_subdev *sd,
+	struct msm_camera_csi_params *csic_params)
+{
+	int rc = 0;
+	uint32_t val = 0;
+	struct csic_device *csic_dev;
+	void __iomem *csicbase;
+	int i;
+
+	csic_dev = v4l2_get_subdevdata(sd);
+	csicbase = csic_dev->base;
+
+	/* Enable error correction for DATA lane. Applies to all data lanes */
+	msm_camera_io_w(0x4, csicbase + MIPI_PHY_CONTROL);
+
+	msm_camera_io_w(MIPI_PROTOCOL_CONTROL_SW_RST_BMSK,
+		csicbase + MIPI_PROTOCOL_CONTROL);
+
+	val = MIPI_PROTOCOL_CONTROL_LONG_PACKET_HEADER_CAPTURE_BMSK |
+		MIPI_PROTOCOL_CONTROL_DECODE_ID_BMSK |
+		MIPI_PROTOCOL_CONTROL_ECC_EN_BMSK;
+	val |= (uint32_t)(csic_params->data_format) <<
+		MIPI_PROTOCOL_CONTROL_DATA_FORMAT_SHFT;
+	val |= csic_params->dpcm_scheme <<
+		MIPI_PROTOCOL_CONTROL_DPCM_SCHEME_SHFT;
+	CDBG("%s MIPI_PROTOCOL_CONTROL val=0x%x\n", __func__, val);
+	msm_camera_io_w(val, csicbase + MIPI_PROTOCOL_CONTROL);
+
+	val = (csic_params->settle_cnt <<
+		MIPI_PHY_D0_CONTROL2_SETTLE_COUNT_SHFT) |
+		(0x0F << MIPI_PHY_D0_CONTROL2_HS_TERM_IMP_SHFT) |
+		(0x1 << MIPI_PHY_D0_CONTROL2_LP_REC_EN_SHFT) |
+		(0x1 << MIPI_PHY_D0_CONTROL2_ERR_SOT_HS_EN_SHFT);
+	CDBG("%s MIPI_PHY_D0_CONTROL2 val=0x%x\n", __func__, val);
+	for (i = 0; i < csic_params->lane_cnt; i++)
+		msm_camera_io_w(val, csicbase + MIPI_PHY_D0_CONTROL2 + i * 4);
+
+
+	val = (0x0F << MIPI_PHY_CL_CONTROL_HS_TERM_IMP_SHFT) |
+		(0x1 << MIPI_PHY_CL_CONTROL_LP_REC_EN_SHFT);
+	CDBG("%s MIPI_PHY_CL_CONTROL val=0x%x\n", __func__, val);
+	msm_camera_io_w(val, csicbase + MIPI_PHY_CL_CONTROL);
+
+	val = 0 << MIPI_PHY_D0_CONTROL_HS_REC_EQ_SHFT;
+	msm_camera_io_w(val, csicbase + MIPI_PHY_D0_CONTROL);
+
+	val = (0x1 << MIPI_PHY_D1_CONTROL_MIPI_CLK_PHY_SHUTDOWNB_SHFT) |
+		(0x1 << MIPI_PHY_D1_CONTROL_MIPI_DATA_PHY_SHUTDOWNB_SHFT);
+	CDBG("%s MIPI_PHY_D1_CONTROL val=0x%x\n", __func__, val);
+	msm_camera_io_w(val, csicbase + MIPI_PHY_D1_CONTROL);
+
+	msm_camera_io_w(0x00000000, csicbase + MIPI_PHY_D2_CONTROL);
+	msm_camera_io_w(0x00000000, csicbase + MIPI_PHY_D3_CONTROL);
+
+	/* program number of lanes and lane mapping */
+	switch (csic_params->lane_cnt) {
+	case 1:
+		msm_camera_io_w(csic_params->lane_assign << 8 | 0x4,
+			csicbase + MIPI_CAMERA_CNTL);
+		break;
+	case 2:
+		msm_camera_io_w(csic_params->lane_assign << 8 | 0x5,
+			csicbase + MIPI_CAMERA_CNTL);
+		break;
+	case 3:
+		msm_camera_io_w(csic_params->lane_assign << 8 | 0x6,
+			csicbase + MIPI_CAMERA_CNTL);
+		break;
+	case 4:
+		msm_camera_io_w(csic_params->lane_assign << 8 | 0x7,
+			csicbase + MIPI_CAMERA_CNTL);
+		break;
+	}
+
+	msm_camera_io_w(0xF077F3C0, csicbase + MIPI_INTERRUPT_MASK);
+	/*clear IRQ bits*/
+	msm_camera_io_w(0xF077F3C0, csicbase + MIPI_INTERRUPT_STATUS);
+
+	return rc;
+}
+
+static irqreturn_t msm_csic_irq(int irq_num, void *data)
+{
+	uint32_t irq;
+	struct csic_device *csic_dev = data;
+
+	pr_info("msm_csic_irq: %x\n", (unsigned int)csic_dev->base);
+	irq = msm_camera_io_r(csic_dev->base + MIPI_INTERRUPT_STATUS);
+	pr_info("%s MIPI_INTERRUPT_STATUS = 0x%x 0x%x\n",
+		__func__, irq,
+		msm_camera_io_r(csic_dev->base + MIPI_PROTOCOL_CONTROL));
+	msm_camera_io_w(irq, csic_dev->base + MIPI_INTERRUPT_STATUS);
+
+	/* TODO: Needs to send this info to upper layers */
+	if ((irq >> 19) & 0x1)
+		pr_info("Unsupported packet format is received\n");
+	return IRQ_HANDLED;
+}
+
+static int msm_csic_subdev_g_chip_ident(struct v4l2_subdev *sd,
+			struct v4l2_dbg_chip_ident *chip)
+{
+	BUG_ON(!chip);
+	chip->ident = V4L2_IDENT_CSIC;
+	chip->revision = 0;
+	return 0;
+}
+
+static struct msm_cam_clk_info csic_8x_clk_info[] = {
+	{"csi_src_clk", 384000000},
+	{"csi_clk", -1},
+	{"csi_vfe_clk", -1},
+	{"csi_pclk", -1},
+};
+
+static struct msm_cam_clk_info csic_7x_clk_info[] = {
+	{"csi_clk", 400000000},
+	{"csi_vfe_clk", -1},
+	{"csi_pclk", -1},
+};
+
+static int msm_csic_init(struct v4l2_subdev *sd)
+{
+	int rc = 0;
+	struct csic_device *csic_dev;
+	csic_dev = v4l2_get_subdevdata(sd);
+	if (csic_dev == NULL) {
+		rc = -ENOMEM;
+		return rc;
+	}
+
+	csic_dev->base = ioremap(csic_dev->mem->start,
+		resource_size(csic_dev->mem));
+	if (!csic_dev->base) {
+		rc = -ENOMEM;
+		return rc;
+	}
+
+	csic_dev->hw_version = CSIC_8X;
+	rc = msm_cam_clk_enable(&csic_dev->pdev->dev, csic_8x_clk_info,
+		csic_dev->csic_clk, ARRAY_SIZE(csic_8x_clk_info), 1);
+	if (rc < 0) {
+		csic_dev->hw_version = CSIC_7X;
+		rc = msm_cam_clk_enable(&csic_dev->pdev->dev, csic_7x_clk_info,
+			csic_dev->csic_clk, ARRAY_SIZE(csic_7x_clk_info), 1);
+		if (rc < 0) {
+			csic_dev->hw_version = 0;
+			iounmap(csic_dev->base);
+			csic_dev->base = NULL;
+			return rc;
+		}
+	}
+	if (csic_dev->hw_version == CSIC_7X)
+		msm_camio_vfe_blk_reset_3();
+
+#if DBG_CSIC
+	enable_irq(csic_dev->irq->start);
+#endif
+
+	return 0;
+}
+
+static void msm_csic_disable(struct v4l2_subdev *sd)
+{
+	uint32_t val;
+	struct csic_device *csic_dev;
+	csic_dev = v4l2_get_subdevdata(sd);
+
+	val = 0x0;
+	if (csic_dev->base != NULL) {
+		CDBG("%s MIPI_PHY_D0_CONTROL2 val=0x%x\n", __func__, val);
+		msm_camera_io_w(val, csic_dev->base + MIPI_PHY_D0_CONTROL2);
+		msm_camera_io_w(val, csic_dev->base + MIPI_PHY_D1_CONTROL2);
+		msm_camera_io_w(val, csic_dev->base + MIPI_PHY_D2_CONTROL2);
+		msm_camera_io_w(val, csic_dev->base + MIPI_PHY_D3_CONTROL2);
+		CDBG("%s MIPI_PHY_CL_CONTROL val=0x%x\n", __func__, val);
+		msm_camera_io_w(val, csic_dev->base + MIPI_PHY_CL_CONTROL);
+		msleep(20);
+		val = msm_camera_io_r(csic_dev->base + MIPI_PHY_D1_CONTROL);
+		val &=
+		~((0x1 << MIPI_PHY_D1_CONTROL_MIPI_CLK_PHY_SHUTDOWNB_SHFT)
+		|(0x1 << MIPI_PHY_D1_CONTROL_MIPI_DATA_PHY_SHUTDOWNB_SHFT));
+		CDBG("%s MIPI_PHY_D1_CONTROL val=0x%x\n", __func__, val);
+		msm_camera_io_w(val, csic_dev->base + MIPI_PHY_D1_CONTROL);
+		usleep_range(5000, 6000);
+		msm_camera_io_w(0x0, csic_dev->base + MIPI_INTERRUPT_MASK);
+		msm_camera_io_w(0x0, csic_dev->base + MIPI_INTERRUPT_STATUS);
+		msm_camera_io_w(MIPI_PROTOCOL_CONTROL_SW_RST_BMSK,
+			csic_dev->base + MIPI_PROTOCOL_CONTROL);
+
+		msm_camera_io_w(0xE400, csic_dev->base + MIPI_CAMERA_CNTL);
+	}
+}
+
+static int msm_csic_release(struct v4l2_subdev *sd)
+{
+	struct csic_device *csic_dev;
+	csic_dev = v4l2_get_subdevdata(sd);
+
+	msm_csic_disable(sd);
+#if DBG_CSIC
+	disable_irq(csic_dev->irq->start);
+#endif
+
+	if (csic_dev->hw_version == CSIC_8X) {
+		msm_cam_clk_enable(&csic_dev->pdev->dev, csic_8x_clk_info,
+			csic_dev->csic_clk, ARRAY_SIZE(csic_8x_clk_info), 0);
+	} else if (csic_dev->hw_version == CSIC_7X) {
+		msm_cam_clk_enable(&csic_dev->pdev->dev, csic_7x_clk_info,
+			csic_dev->csic_clk, ARRAY_SIZE(csic_7x_clk_info), 0);
+	}
+
+	iounmap(csic_dev->base);
+	csic_dev->base = NULL;
+	return 0;
+}
+
+static long msm_csic_cmd(struct v4l2_subdev *sd, void *arg)
+{
+	long rc = 0;
+	struct csic_cfg_data cdata;
+	struct msm_camera_csi_params csic_params;
+	if (copy_from_user(&cdata,
+		(void *)arg,
+		sizeof(struct csic_cfg_data)))
+		return -EFAULT;
+	CDBG("%s cfgtype = %d\n", __func__, cdata.cfgtype);
+	switch (cdata.cfgtype) {
+	case CSIC_INIT:
+		rc = msm_csic_init(sd);
+		break;
+	case CSIC_CFG:
+		if (copy_from_user(&csic_params,
+			(void *)cdata.csic_params,
+			sizeof(struct msm_camera_csi_params)))
+			return -EFAULT;
+		rc = msm_csic_config(sd, &csic_params);
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
+static long msm_csic_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int cmd, void *arg)
+{
+	switch (cmd) {
+	case VIDIOC_MSM_CSIC_CFG:
+		return msm_csic_cmd(sd, arg);
+	case VIDIOC_MSM_CSIC_RELEASE:
+		return msm_csic_release(sd);
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
+static struct v4l2_subdev_core_ops msm_csic_subdev_core_ops = {
+	.g_chip_ident = &msm_csic_subdev_g_chip_ident,
+	.ioctl = &msm_csic_subdev_ioctl,
+};
+
+static const struct v4l2_subdev_ops msm_csic_subdev_ops = {
+	.core = &msm_csic_subdev_core_ops,
+};
+
+static const struct v4l2_subdev_internal_ops msm_csic_internal_ops;
+
+static int __devinit csic_probe(struct platform_device *pdev)
+{
+	struct csic_device *new_csic_dev;
+	int rc = 0;
+	struct msm_cam_subdev_info sd_info;
+
+	CDBG("%s: device id = %d\n", __func__, pdev->id);
+	new_csic_dev = kzalloc(sizeof(struct csic_device), GFP_KERNEL);
+	if (!new_csic_dev) {
+		pr_err("%s: no enough memory\n", __func__);
+		return -ENOMEM;
+	}
+
+	v4l2_subdev_init(&new_csic_dev->subdev, &msm_csic_subdev_ops);
+	new_csic_dev->subdev.internal_ops = &msm_csic_internal_ops;
+	new_csic_dev->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	snprintf(new_csic_dev->subdev.name,
+			ARRAY_SIZE(new_csic_dev->subdev.name), "msm_csic");
+	v4l2_set_subdevdata(&new_csic_dev->subdev, new_csic_dev);
+	platform_set_drvdata(pdev, &new_csic_dev->subdev);
+	mutex_init(&new_csic_dev->mutex);
+
+	new_csic_dev->mem = platform_get_resource_byname(pdev,
+					IORESOURCE_MEM, "csic");
+	if (!new_csic_dev->mem) {
+		pr_err("%s: no mem resource?\n", __func__);
+		rc = -ENODEV;
+		goto csic_no_resource;
+	}
+	new_csic_dev->irq = platform_get_resource_byname(pdev,
+					IORESOURCE_IRQ, "csic");
+	if (!new_csic_dev->irq) {
+		pr_err("%s: no irq resource?\n", __func__);
+		rc = -ENODEV;
+		goto csic_no_resource;
+	}
+	new_csic_dev->io = request_mem_region(new_csic_dev->mem->start,
+		resource_size(new_csic_dev->mem), pdev->name);
+	if (!new_csic_dev->io) {
+		pr_err("%s: no valid mem region\n", __func__);
+		rc = -EBUSY;
+		goto csic_no_resource;
+	}
+
+	rc = request_irq(new_csic_dev->irq->start, msm_csic_irq,
+		IRQF_TRIGGER_HIGH, "csic", new_csic_dev);
+	if (rc < 0) {
+		release_mem_region(new_csic_dev->mem->start,
+			resource_size(new_csic_dev->mem));
+		pr_err("%s: irq request fail\n", __func__);
+		rc = -EBUSY;
+		goto csic_no_resource;
+	}
+	disable_irq(new_csic_dev->irq->start);
+
+	new_csic_dev->pdev = pdev;
+
+	rc = msm_cam_clk_enable(&new_csic_dev->pdev->dev, &csic_7x_clk_info[2],
+				new_csic_dev->csic_clk, 1, 1);
+	new_csic_dev->base = ioremap(new_csic_dev->mem->start,
+		resource_size(new_csic_dev->mem));
+	if (!new_csic_dev->base) {
+		rc = -ENOMEM;
+		return rc;
+	}
+
+	msm_camera_io_w(MIPI_PWR_CNTL_DIS, new_csic_dev->base + MIPI_PWR_CNTL);
+
+	rc = msm_cam_clk_enable(&new_csic_dev->pdev->dev, &csic_7x_clk_info[2],
+				new_csic_dev->csic_clk, 1, 0);
+
+	iounmap(new_csic_dev->base);
+	new_csic_dev->base = NULL;
+	sd_info.sdev_type = CSIC_DEV;
+	sd_info.sd_index = pdev->id;
+	sd_info.irq_num = new_csic_dev->irq->start;
+	msm_cam_register_subdev_node(
+		&new_csic_dev->subdev, &sd_info);
+
+	media_entity_init(&new_csic_dev->subdev.entity, 0, NULL, 0);
+	new_csic_dev->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	new_csic_dev->subdev.entity.group_id = CSIC_DEV;
+	new_csic_dev->subdev.entity.name = pdev->name;
+	new_csic_dev->subdev.entity.revision =
+		new_csic_dev->subdev.devnode->num;
+	return 0;
+
+csic_no_resource:
+	mutex_destroy(&new_csic_dev->mutex);
+	kfree(new_csic_dev);
+	return 0;
+}
+
+static struct platform_driver csic_driver = {
+	.probe = csic_probe,
+	.driver = {
+		.name = MSM_CSIC_DRV_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init msm_csic_init_module(void)
+{
+	return platform_driver_register(&csic_driver);
+}
+
+static void __exit msm_csic_exit_module(void)
+{
+	platform_driver_unregister(&csic_driver);
+}
+
+module_init(msm_csic_init_module);
+module_exit(msm_csic_exit_module);
+MODULE_DESCRIPTION("MSM csic driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/csi/msm_csic.h b/drivers/media/platform/msm/camera_v1/csi/msm_csic.h
new file mode 100644
index 0000000..f8aa92a
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/csi/msm_csic.h
@@ -0,0 +1,42 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_CSIC_H
+#define MSM_CSIC_H
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <media/v4l2-subdev.h>
+
+#define CSIC_7X 0x1
+#define CSIC_8X (0x1 << 1)
+
+struct csic_device {
+	struct platform_device *pdev;
+	struct v4l2_subdev subdev;
+	struct resource *mem;
+	struct resource *irq;
+	struct resource *io;
+	void __iomem *base;
+	struct mutex mutex;
+	uint32_t hw_version;
+
+	struct clk *csic_clk[5];
+};
+
+#define VIDIOC_MSM_CSIC_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 4, struct csic_cfg_data*)
+
+#define VIDIOC_MSM_CSIC_RELEASE \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 5, struct v4l2_subdev*)
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v1/csi/msm_csic_register.c b/drivers/media/platform/msm/camera_v1/csi/msm_csic_register.c
new file mode 100644
index 0000000..660fdaf
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/csi/msm_csic_register.c
@@ -0,0 +1,37 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/device.h>
+#include "msm.h"
+#include "msm_csi_register.h"
+
+int msm_csi_register_subdevs(struct msm_cam_media_controller *p_mctl,
+	uint8_t csiphy_code_index, uint8_t csid_core_index,
+	struct msm_cam_server_dev *server_dev)
+{
+	int rc = -ENODEV;
+
+	p_mctl->csic_sdev = server_dev->csic_device[csid_core_index];
+	if (!p_mctl->csic_sdev)
+		goto out;
+	v4l2_set_subdev_hostdata(p_mctl->csic_sdev, p_mctl);
+
+	rc = 0;
+	p_mctl->ispif_sdev = NULL;
+	return rc;
+
+out:
+	p_mctl->ispif_sdev = NULL;
+	return rc;
+}
+
diff --git a/drivers/media/platform/msm/camera_v1/csi/msm_csid.c b/drivers/media/platform/msm/camera_v1/csi/msm_csid.c
new file mode 100644
index 0000000..c1ffac3
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/csi/msm_csid.c
@@ -0,0 +1,649 @@
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <mach/board.h>
+#include <mach/camera.h>
+#include <media/msm_isp.h>
+#include "msm_csid.h"
+#include "msm_csid_hwreg.h"
+#include "msm.h"
+#include "msm_cam_server.h"
+
+#define V4L2_IDENT_CSID                            50002
+#define CSID_VERSION_V2                      0x02000011
+#define CSID_VERSION_V3                      0x30000000
+
+#define DBG_CSID 0
+
+#define TRUE   1
+#define FALSE  0
+
+static int msm_csid_cid_lut(
+	struct msm_camera_csid_lut_params *csid_lut_params,
+	void __iomem *csidbase)
+{
+	int rc = 0, i = 0;
+	uint32_t val = 0;
+
+	if (!csid_lut_params) {
+		pr_err("%s:%d csid_lut_params NULL\n", __func__, __LINE__);
+		return -EINVAL;
+	}
+	for (i = 0; i < csid_lut_params->num_cid && i < 16; i++) {
+		CDBG("%s lut params num_cid = %d, cid = %d, dt = %x, df = %d\n",
+			__func__,
+			csid_lut_params->num_cid,
+			csid_lut_params->vc_cfg[i].cid,
+			csid_lut_params->vc_cfg[i].dt,
+			csid_lut_params->vc_cfg[i].decode_format);
+		if (csid_lut_params->vc_cfg[i].dt < 0x12 ||
+			csid_lut_params->vc_cfg[i].dt > 0x37) {
+			CDBG("%s: unsupported data type 0x%x\n",
+				 __func__, csid_lut_params->vc_cfg[i].dt);
+			return rc;
+		}
+		val = msm_camera_io_r(csidbase + CSID_CID_LUT_VC_0_ADDR +
+			(csid_lut_params->vc_cfg[i].cid >> 2) * 4)
+			& ~(0xFF << ((csid_lut_params->vc_cfg[i].cid % 4) * 8));
+		val |= (csid_lut_params->vc_cfg[i].dt <<
+			((csid_lut_params->vc_cfg[i].cid % 4) * 8));
+		msm_camera_io_w(val, csidbase + CSID_CID_LUT_VC_0_ADDR +
+			(csid_lut_params->vc_cfg[i].cid >> 2) * 4);
+
+		val = (csid_lut_params->vc_cfg[i].decode_format << 4) | 0x3;
+		msm_camera_io_w(val, csidbase + CSID_CID_n_CFG_ADDR +
+			(csid_lut_params->vc_cfg[i].cid * 4));
+	}
+	return rc;
+}
+
+#if DBG_CSID
+static void msm_csid_set_debug_reg(void __iomem *csidbase,
+	struct msm_camera_csid_params *csid_params)
+{
+	uint32_t val = 0;
+	val = ((1 << csid_params->lane_cnt) - 1) << 20;
+	msm_camera_io_w(0x7f010800 | val, csidbase + CSID_IRQ_MASK_ADDR);
+	msm_camera_io_w(0x7f010800 | val, csidbase + CSID_IRQ_CLEAR_CMD_ADDR);
+}
+#else
+static void msm_csid_set_debug_reg(void __iomem *csidbase,
+	struct msm_camera_csid_params *csid_params) {}
+#endif
+
+static int msm_csid_config(struct csid_device *csid_dev,
+	struct msm_camera_csid_params *csid_params)
+{
+	int rc = 0;
+	uint32_t val = 0;
+	void __iomem *csidbase;
+	csidbase = csid_dev->base;
+	if (!csidbase || !csid_params) {
+		pr_err("%s:%d csidbase %p, csid params %p\n", __func__,
+			__LINE__, csidbase, csid_params);
+		return -EINVAL;
+	}
+
+	CDBG("%s csid_params, lane_cnt = %d, lane_assign = %x, phy sel = %d\n",
+		__func__,
+		csid_params->lane_cnt,
+		csid_params->lane_assign,
+		csid_params->phy_sel);
+	val = csid_params->lane_cnt - 1;
+	val |= csid_params->lane_assign << CSID_DL_INPUT_SEL_SHIFT;
+	if (csid_dev->hw_version < 0x30000000) {
+		val |= (0xF << 10);
+		msm_camera_io_w(val, csidbase + CSID_CORE_CTRL_0_ADDR);
+	} else {
+		msm_camera_io_w(val, csidbase + CSID_CORE_CTRL_0_ADDR);
+		val = csid_params->phy_sel << CSID_PHY_SEL_SHIFT;
+		val |= 0xF;
+		msm_camera_io_w(val, csidbase + CSID_CORE_CTRL_1_ADDR);
+	}
+
+	rc = msm_csid_cid_lut(&csid_params->lut_params, csidbase);
+	if (rc < 0)
+		return rc;
+
+	msm_csid_set_debug_reg(csidbase, csid_params);
+	return rc;
+}
+
+static irqreturn_t msm_csid_irq(int irq_num, void *data)
+{
+	uint32_t irq;
+	struct csid_device *csid_dev = data;
+	if (!csid_dev) {
+		pr_err("%s:%d csid_dev NULL\n", __func__, __LINE__);
+		return IRQ_HANDLED;
+	}
+	irq = msm_camera_io_r(csid_dev->base + CSID_IRQ_STATUS_ADDR);
+	CDBG("%s CSID%d_IRQ_STATUS_ADDR = 0x%x\n",
+		 __func__, csid_dev->pdev->id, irq);
+	if (irq & (0x1 << CSID_RST_DONE_IRQ_BITSHIFT))
+			complete(&csid_dev->reset_complete);
+	msm_camera_io_w(irq, csid_dev->base + CSID_IRQ_CLEAR_CMD_ADDR);
+	return IRQ_HANDLED;
+}
+
+int msm_csid_irq_routine(struct v4l2_subdev *sd, u32 status, bool *handled)
+{
+	struct csid_device *csid_dev = v4l2_get_subdevdata(sd);
+	irqreturn_t ret;
+	CDBG("%s E\n", __func__);
+	ret = msm_csid_irq(csid_dev->irq->start, csid_dev);
+	*handled = TRUE;
+	return 0;
+}
+
+static void msm_csid_reset(struct csid_device *csid_dev)
+{
+	msm_camera_io_w(CSID_RST_STB_ALL, csid_dev->base + CSID_RST_CMD_ADDR);
+	wait_for_completion_interruptible(&csid_dev->reset_complete);
+	return;
+}
+
+static int msm_csid_subdev_g_chip_ident(struct v4l2_subdev *sd,
+			struct v4l2_dbg_chip_ident *chip)
+{
+	BUG_ON(!chip);
+	chip->ident = V4L2_IDENT_CSID;
+	chip->revision = 0;
+	return 0;
+}
+
+static struct msm_cam_clk_info csid_8960_clk_info[] = {
+	{"csi_src_clk", 177780000},
+	{"csi_clk", -1},
+	{"csi_phy_clk", -1},
+	{"csi_pclk", -1},
+};
+
+static struct msm_cam_clk_info csid0_8974_clk_info[] = {
+	{"csi0_ahb_clk", -1},
+	{"csi0_src_clk", 200000000},
+	{"csi0_clk", -1},
+	{"csi0_phy_clk", -1},
+	{"csi0_pix_clk", -1},
+	{"csi0_rdi_clk", -1},
+};
+
+static struct msm_cam_clk_info csid1_8974_clk_info[] = {
+	{"csi1_ahb_clk", -1},
+	{"csi1_src_clk", 200000000},
+	{"csi1_clk", -1},
+	{"csi1_phy_clk", -1},
+	{"csi1_pix_clk", -1},
+	{"csi1_rdi_clk", -1},
+};
+
+static struct msm_cam_clk_info csid2_8974_clk_info[] = {
+	{"csi2_ahb_clk", -1},
+	{"csi2_src_clk", 200000000},
+	{"csi2_clk", -1},
+	{"csi2_phy_clk", -1},
+	{"csi2_pix_clk", -1},
+	{"csi2_rdi_clk", -1},
+};
+
+static struct msm_cam_clk_info csid3_8974_clk_info[] = {
+	{"csi3_ahb_clk", -1},
+	{"csi3_src_clk", 200000000},
+	{"csi3_clk", -1},
+	{"csi3_phy_clk", -1},
+	{"csi3_pix_clk", -1},
+	{"csi3_rdi_clk", -1},
+};
+
+static struct msm_cam_clk_setting csid_8974_clk_info[] = {
+	{&csid0_8974_clk_info[0], ARRAY_SIZE(csid0_8974_clk_info)},
+	{&csid1_8974_clk_info[0], ARRAY_SIZE(csid1_8974_clk_info)},
+	{&csid2_8974_clk_info[0], ARRAY_SIZE(csid2_8974_clk_info)},
+	{&csid3_8974_clk_info[0], ARRAY_SIZE(csid3_8974_clk_info)},
+};
+
+static struct camera_vreg_t csid_8960_vreg_info[] = {
+	{"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
+};
+
+static struct camera_vreg_t csid_8974_vreg_info[] = {
+	{"mipi_csi_vdd", REG_LDO, 1800000, 1800000, 12000},
+};
+
+static int msm_csid_init(struct csid_device *csid_dev, uint32_t *csid_version)
+{
+	int rc = 0;
+	uint8_t core_id = 0;
+
+	if (!csid_version) {
+		pr_err("%s:%d csid_version NULL\n", __func__, __LINE__);
+		rc = -EINVAL;
+		return rc;
+	}
+
+	if (csid_dev->csid_state == CSID_POWER_UP) {
+		pr_err("%s: csid invalid state %d\n", __func__,
+			csid_dev->csid_state);
+		rc = -EINVAL;
+		return rc;
+	}
+
+	csid_dev->base = ioremap(csid_dev->mem->start,
+		resource_size(csid_dev->mem));
+	if (!csid_dev->base) {
+		pr_err("%s csid_dev->base NULL\n", __func__);
+		rc = -ENOMEM;
+		return rc;
+	}
+
+	if (CSID_VERSION <= CSID_VERSION_V2) {
+		rc = msm_camera_config_vreg(&csid_dev->pdev->dev,
+			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 1);
+		if (rc < 0) {
+			pr_err("%s: regulator on failed\n", __func__);
+			goto vreg_config_failed;
+		}
+
+		rc = msm_camera_enable_vreg(&csid_dev->pdev->dev,
+			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 1);
+		if (rc < 0) {
+			pr_err("%s: regulator enable failed\n", __func__);
+			goto vreg_enable_failed;
+		}
+
+		rc = msm_cam_clk_enable(&csid_dev->pdev->dev,
+			csid_8960_clk_info, csid_dev->csid_clk,
+			ARRAY_SIZE(csid_8960_clk_info), 1);
+		if (rc < 0) {
+			pr_err("%s: clock enable failed\n", __func__);
+			goto clk_enable_failed;
+		}
+	} else if (CSID_VERSION == CSID_VERSION_V3) {
+		rc = msm_camera_config_vreg(&csid_dev->pdev->dev,
+			csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 1);
+		if (rc < 0) {
+			pr_err("%s: regulator on failed\n", __func__);
+			goto vreg_config_failed;
+		}
+
+		rc = msm_camera_enable_vreg(&csid_dev->pdev->dev,
+			csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 1);
+		if (rc < 0) {
+			pr_err("%s: regulator enable failed\n", __func__);
+			goto vreg_enable_failed;
+		}
+
+		rc = msm_cam_clk_enable(&csid_dev->pdev->dev,
+			csid_8974_clk_info[0].clk_info, csid_dev->csid0_clk,
+			csid_8974_clk_info[0].num_clk_info, 1);
+		if (rc < 0) {
+			pr_err("%s: clock enable failed\n", __func__);
+			goto csid0_clk_enable_failed;
+		}
+		core_id = csid_dev->pdev->id;
+		if (core_id) {
+			rc = msm_cam_clk_enable(&csid_dev->pdev->dev,
+				csid_8974_clk_info[core_id].clk_info,
+				csid_dev->csid_clk,
+				csid_8974_clk_info[core_id].num_clk_info, 1);
+			if (rc < 0) {
+				pr_err("%s: clock enable failed\n",
+					__func__);
+				goto clk_enable_failed;
+			}
+		}
+	}
+
+	csid_dev->hw_version =
+		msm_camera_io_r(csid_dev->base + CSID_HW_VERSION_ADDR);
+	*csid_version = csid_dev->hw_version;
+
+	init_completion(&csid_dev->reset_complete);
+
+	enable_irq(csid_dev->irq->start);
+
+	msm_csid_reset(csid_dev);
+	csid_dev->csid_state = CSID_POWER_UP;
+	return rc;
+
+clk_enable_failed:
+	if (CSID_VERSION == CSID_VERSION_V3) {
+		msm_cam_clk_enable(&csid_dev->pdev->dev,
+			csid_8974_clk_info[0].clk_info, csid_dev->csid0_clk,
+			csid_8974_clk_info[0].num_clk_info, 0);
+	}
+csid0_clk_enable_failed:
+	if (CSID_VERSION <= CSID_VERSION_V2) {
+		msm_camera_enable_vreg(&csid_dev->pdev->dev,
+			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 0);
+	} else if (CSID_VERSION == CSID_VERSION_V3) {
+		msm_camera_enable_vreg(&csid_dev->pdev->dev,
+			csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 0);
+	}
+vreg_enable_failed:
+	if (CSID_VERSION <= CSID_VERSION_V2) {
+		msm_camera_config_vreg(&csid_dev->pdev->dev,
+			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 0);
+	} else if (CSID_VERSION == CSID_VERSION_V3) {
+		msm_camera_config_vreg(&csid_dev->pdev->dev,
+			csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 0);
+	}
+vreg_config_failed:
+	iounmap(csid_dev->base);
+	csid_dev->base = NULL;
+	return rc;
+}
+
+static int msm_csid_release(struct csid_device *csid_dev)
+{
+	uint32_t irq;
+	uint8_t core_id = 0;
+
+	if (csid_dev->csid_state != CSID_POWER_UP) {
+		pr_err("%s: csid invalid state %d\n", __func__,
+			csid_dev->csid_state);
+		return -EINVAL;
+	}
+
+	irq = msm_camera_io_r(csid_dev->base + CSID_IRQ_STATUS_ADDR);
+	msm_camera_io_w(irq, csid_dev->base + CSID_IRQ_CLEAR_CMD_ADDR);
+	msm_camera_io_w(0, csid_dev->base + CSID_IRQ_MASK_ADDR);
+
+	disable_irq(csid_dev->irq->start);
+
+	if (csid_dev->hw_version <= CSID_VERSION_V2) {
+		msm_cam_clk_enable(&csid_dev->pdev->dev, csid_8960_clk_info,
+			csid_dev->csid_clk, ARRAY_SIZE(csid_8960_clk_info), 0);
+
+		msm_camera_enable_vreg(&csid_dev->pdev->dev,
+			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 0);
+
+		msm_camera_config_vreg(&csid_dev->pdev->dev,
+			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 0);
+	} else if (csid_dev->hw_version == CSID_VERSION_V3) {
+		core_id = csid_dev->pdev->id;
+		if (core_id)
+			msm_cam_clk_enable(&csid_dev->pdev->dev,
+				csid_8974_clk_info[core_id].clk_info,
+				csid_dev->csid_clk,
+				csid_8974_clk_info[core_id].num_clk_info, 0);
+
+		msm_cam_clk_enable(&csid_dev->pdev->dev,
+			csid_8974_clk_info[0].clk_info, csid_dev->csid0_clk,
+			csid_8974_clk_info[0].num_clk_info, 0);
+
+		msm_camera_enable_vreg(&csid_dev->pdev->dev,
+			csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 0);
+
+		msm_camera_config_vreg(&csid_dev->pdev->dev,
+			csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 0);
+	}
+
+	iounmap(csid_dev->base);
+	csid_dev->base = NULL;
+	csid_dev->csid_state = CSID_POWER_DOWN;
+	return 0;
+}
+
+static long msm_csid_cmd(struct csid_device *csid_dev, void *arg)
+{
+	int rc = 0;
+	struct csid_cfg_data cdata;
+
+	if (!csid_dev) {
+		pr_err("%s:%d csid_dev NULL\n", __func__, __LINE__);
+		return -EINVAL;
+	}
+
+	if (copy_from_user(&cdata,
+		(void *)arg,
+		sizeof(struct csid_cfg_data))) {
+		pr_err("%s: %d failed\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+	CDBG("%s cfgtype = %d\n", __func__, cdata.cfgtype);
+	switch (cdata.cfgtype) {
+	case CSID_INIT:
+		rc = msm_csid_init(csid_dev, &cdata.cfg.csid_version);
+		if (copy_to_user((void *)arg,
+			&cdata,
+			sizeof(struct csid_cfg_data))) {
+			pr_err("%s: %d failed\n", __func__, __LINE__);
+			rc = -EFAULT;
+		}
+		break;
+	case CSID_CFG: {
+		struct msm_camera_csid_params csid_params;
+		struct msm_camera_csid_vc_cfg *vc_cfg = NULL;
+		if (copy_from_user(&csid_params,
+			(void *)cdata.cfg.csid_params,
+			sizeof(struct msm_camera_csid_params))) {
+			pr_err("%s: %d failed\n", __func__, __LINE__);
+			rc = -EFAULT;
+			break;
+		}
+		vc_cfg = kzalloc(csid_params.lut_params.num_cid *
+			sizeof(struct msm_camera_csid_vc_cfg),
+			GFP_KERNEL);
+		if (!vc_cfg) {
+			pr_err("%s: %d failed\n", __func__, __LINE__);
+			rc = -ENOMEM;
+			break;
+		}
+		if (copy_from_user(vc_cfg,
+			(void *)csid_params.lut_params.vc_cfg,
+			(csid_params.lut_params.num_cid *
+			sizeof(struct msm_camera_csid_vc_cfg)))) {
+			pr_err("%s: %d failed\n", __func__, __LINE__);
+			kfree(vc_cfg);
+			rc = -EFAULT;
+			break;
+		}
+		csid_params.lut_params.vc_cfg = vc_cfg;
+		rc = msm_csid_config(csid_dev, &csid_params);
+		kfree(vc_cfg);
+		break;
+	}
+	default:
+		pr_err("%s: %d failed\n", __func__, __LINE__);
+		rc = -ENOIOCTLCMD;
+		break;
+	}
+	return rc;
+}
+
+static long msm_csid_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int cmd, void *arg)
+{
+	int rc = -ENOIOCTLCMD;
+	struct csid_device *csid_dev = v4l2_get_subdevdata(sd);
+	mutex_lock(&csid_dev->mutex);
+	switch (cmd) {
+	case VIDIOC_MSM_CSID_CFG:
+		rc = msm_csid_cmd(csid_dev, arg);
+		break;
+	case VIDIOC_MSM_CSID_RELEASE:
+		rc = msm_csid_release(csid_dev);
+		break;
+	default:
+		pr_err("%s: command not found\n", __func__);
+	}
+	mutex_unlock(&csid_dev->mutex);
+	return rc;
+}
+
+static const struct v4l2_subdev_internal_ops msm_csid_internal_ops;
+
+static struct v4l2_subdev_core_ops msm_csid_subdev_core_ops = {
+	.g_chip_ident = &msm_csid_subdev_g_chip_ident,
+	.ioctl = &msm_csid_subdev_ioctl,
+	.interrupt_service_routine = msm_csid_irq_routine,
+};
+
+static const struct v4l2_subdev_ops msm_csid_subdev_ops = {
+	.core = &msm_csid_subdev_core_ops,
+};
+
+static int __devinit csid_probe(struct platform_device *pdev)
+{
+	struct csid_device *new_csid_dev;
+	struct msm_cam_subdev_info sd_info;
+	struct intr_table_entry irq_req;
+
+	int rc = 0;
+	CDBG("%s:%d called\n", __func__, __LINE__);
+	new_csid_dev = kzalloc(sizeof(struct csid_device), GFP_KERNEL);
+	if (!new_csid_dev) {
+		pr_err("%s: no enough memory\n", __func__);
+		return -ENOMEM;
+	}
+
+	v4l2_subdev_init(&new_csid_dev->subdev, &msm_csid_subdev_ops);
+	new_csid_dev->subdev.internal_ops = &msm_csid_internal_ops;
+	new_csid_dev->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	snprintf(new_csid_dev->subdev.name,
+			ARRAY_SIZE(new_csid_dev->subdev.name), "msm_csid");
+	v4l2_set_subdevdata(&new_csid_dev->subdev, new_csid_dev);
+	platform_set_drvdata(pdev, &new_csid_dev->subdev);
+	mutex_init(&new_csid_dev->mutex);
+
+	if (pdev->dev.of_node)
+		of_property_read_u32((&pdev->dev)->of_node,
+			"cell-index", &pdev->id);
+
+	CDBG("%s device id %d\n", __func__, pdev->id);
+	new_csid_dev->mem = platform_get_resource_byname(pdev,
+					IORESOURCE_MEM, "csid");
+	if (!new_csid_dev->mem) {
+		pr_err("%s: no mem resource?\n", __func__);
+		rc = -ENODEV;
+		goto csid_no_resource;
+	}
+	new_csid_dev->irq = platform_get_resource_byname(pdev,
+					IORESOURCE_IRQ, "csid");
+	if (!new_csid_dev->irq) {
+		pr_err("%s: no irq resource?\n", __func__);
+		rc = -ENODEV;
+		goto csid_no_resource;
+	}
+	new_csid_dev->io = request_mem_region(new_csid_dev->mem->start,
+		resource_size(new_csid_dev->mem), pdev->name);
+	if (!new_csid_dev->io) {
+		pr_err("%s: no valid mem region\n", __func__);
+		rc = -EBUSY;
+		goto csid_no_resource;
+	}
+
+	new_csid_dev->pdev = pdev;
+	sd_info.sdev_type = CSID_DEV;
+	sd_info.sd_index = pdev->id;
+	sd_info.irq_num = new_csid_dev->irq->start;
+	msm_cam_register_subdev_node(&new_csid_dev->subdev, &sd_info);
+
+	media_entity_init(&new_csid_dev->subdev.entity, 0, NULL, 0);
+	new_csid_dev->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	new_csid_dev->subdev.entity.group_id = CSID_DEV;
+	new_csid_dev->subdev.entity.name = pdev->name;
+	new_csid_dev->subdev.entity.revision =
+		new_csid_dev->subdev.devnode->num;
+
+	/* Request for this device irq from the camera server. If the
+	 * IRQ Router is present on this target, the interrupt will be
+	 * handled by the camera server and the interrupt service
+	 * routine called. If the request_irq call returns ENXIO, then
+	 * the IRQ Router hardware is not present on this target. We
+	 * have to request for the irq ourselves and register the
+	 * appropriate interrupt handler. */
+	irq_req.cam_hw_idx       = MSM_CAM_HW_CSI0 + pdev->id;
+	irq_req.dev_name         = "csid";
+	irq_req.irq_idx          = CAMERA_SS_IRQ_2 + pdev->id;
+	irq_req.irq_num          = new_csid_dev->irq->start;
+	irq_req.is_composite     = 0;
+	irq_req.irq_trigger_type = IRQF_TRIGGER_RISING;
+	irq_req.num_hwcore       = 1;
+	irq_req.subdev_list[0]   = &new_csid_dev->subdev;
+	irq_req.data             = (void *)new_csid_dev;
+	rc = msm_cam_server_request_irq(&irq_req);
+	if (rc == -ENXIO) {
+		/* IRQ Router hardware is not present on this hardware.
+		 * Request for the IRQ and register the interrupt handler. */
+		rc = request_irq(new_csid_dev->irq->start, msm_csid_irq,
+			IRQF_TRIGGER_RISING, "csid", new_csid_dev);
+		if (rc < 0) {
+			release_mem_region(new_csid_dev->mem->start,
+				resource_size(new_csid_dev->mem));
+			pr_err("%s: irq request fail\n", __func__);
+			rc = -EBUSY;
+			goto csid_no_resource;
+		}
+		disable_irq(new_csid_dev->irq->start);
+	} else if (rc < 0) {
+		release_mem_region(new_csid_dev->mem->start,
+			resource_size(new_csid_dev->mem));
+		pr_err("%s Error registering irq ", __func__);
+		goto csid_no_resource;
+	}
+
+	new_csid_dev->csid_state = CSID_POWER_DOWN;
+	return 0;
+
+csid_no_resource:
+	mutex_destroy(&new_csid_dev->mutex);
+	kfree(new_csid_dev);
+	return 0;
+}
+
+static const struct of_device_id msm_csid_dt_match[] = {
+	{.compatible = "qcom,csid"},
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, msm_csid_dt_match);
+
+static struct platform_driver csid_driver = {
+	.probe = csid_probe,
+	.driver = {
+		.name = MSM_CSID_DRV_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = msm_csid_dt_match,
+	},
+};
+
+static int __init msm_csid_init_module(void)
+{
+	return platform_driver_register(&csid_driver);
+}
+
+static void __exit msm_csid_exit_module(void)
+{
+	platform_driver_unregister(&csid_driver);
+}
+
+module_init(msm_csid_init_module);
+module_exit(msm_csid_exit_module);
+MODULE_DESCRIPTION("MSM CSID driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/csi/msm_csid.h b/drivers/media/platform/msm/camera_v1/csi/msm_csid.h
new file mode 100644
index 0000000..252f5fd
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/csi/msm_csid.h
@@ -0,0 +1,49 @@
+/* Copyright (c) 2011-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.
+ */
+
+#ifndef MSM_CSID_H
+#define MSM_CSID_H
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <media/v4l2-subdev.h>
+#include <media/msm_camera.h>
+
+enum msm_csid_state_t {
+	CSID_POWER_UP,
+	CSID_POWER_DOWN,
+};
+
+struct csid_device {
+	struct platform_device *pdev;
+	struct v4l2_subdev subdev;
+	struct resource *mem;
+	struct resource *irq;
+	struct resource *io;
+	struct regulator *csi_vdd;
+	void __iomem *base;
+	struct mutex mutex;
+	struct completion reset_complete;
+	uint32_t hw_version;
+	enum msm_csid_state_t csid_state;
+
+	struct clk *csid0_clk[6];
+	struct clk *csid_clk[6];
+};
+
+#define VIDIOC_MSM_CSID_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 4, struct csic_cfg_data*)
+
+#define VIDIOC_MSM_CSID_RELEASE \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 5, struct v4l2_subdev*)
+#endif
+
diff --git a/drivers/media/platform/msm/camera_v1/csi/msm_csiphy.c b/drivers/media/platform/msm/camera_v1/csi/msm_csiphy.c
new file mode 100644
index 0000000..0c754e9
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/csi/msm_csiphy.c
@@ -0,0 +1,465 @@
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/module.h>
+#include <mach/board.h>
+#include <mach/vreg.h>
+#include <media/msm_isp.h>
+#include "msm_csiphy.h"
+#include "msm.h"
+#include "msm_csiphy_hwreg.h"
+#define DBG_CSIPHY 0
+
+#define V4L2_IDENT_CSIPHY                        50003
+#define CSIPHY_VERSION_V3                        0x10
+
+int msm_csiphy_lane_config(struct csiphy_device *csiphy_dev,
+	struct msm_camera_csiphy_params *csiphy_params)
+{
+	int rc = 0;
+	int j = 0;
+	uint32_t val = 0;
+	uint8_t lane_cnt = 0;
+	uint16_t lane_mask = 0;
+	void __iomem *csiphybase;
+	csiphybase = csiphy_dev->base;
+	if (!csiphybase) {
+		pr_err("%s: csiphybase NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	csiphy_dev->lane_mask[csiphy_dev->pdev->id] |= csiphy_params->lane_mask;
+	lane_mask = csiphy_dev->lane_mask[csiphy_dev->pdev->id];
+	lane_cnt = csiphy_params->lane_cnt;
+	if (csiphy_params->lane_cnt < 1 || csiphy_params->lane_cnt > 4) {
+		pr_err("%s: unsupported lane cnt %d\n",
+			__func__, csiphy_params->lane_cnt);
+		return rc;
+	}
+
+	CDBG("%s csiphy_params, mask = %x, cnt = %d, settle cnt = %x\n",
+		__func__,
+		csiphy_params->lane_mask,
+		csiphy_params->lane_cnt,
+		csiphy_params->settle_cnt);
+	msm_camera_io_w(0x1, csiphybase + MIPI_CSIPHY_GLBL_T_INIT_CFG0_ADDR);
+	msm_camera_io_w(0x1, csiphybase + MIPI_CSIPHY_T_WAKEUP_CFG0_ADDR);
+
+	if (csiphy_dev->hw_version != CSIPHY_VERSION_V3) {
+		val = 0x3;
+		msm_camera_io_w((lane_mask << 2) | val,
+				csiphybase + MIPI_CSIPHY_GLBL_PWR_CFG_ADDR);
+		msm_camera_io_w(0x10, csiphybase + MIPI_CSIPHY_LNCK_CFG2_ADDR);
+		msm_camera_io_w(csiphy_params->settle_cnt,
+			 csiphybase + MIPI_CSIPHY_LNCK_CFG3_ADDR);
+		msm_camera_io_w(0x24,
+			csiphybase + MIPI_CSIPHY_INTERRUPT_MASK0_ADDR);
+		msm_camera_io_w(0x24,
+			csiphybase + MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR);
+	} else {
+		val = 0x1;
+		msm_camera_io_w((lane_mask << 1) | val,
+				csiphybase + MIPI_CSIPHY_GLBL_PWR_CFG_ADDR);
+		msm_camera_io_w(csiphy_params->combo_mode <<
+			MIPI_CSIPHY_MODE_CONFIG_SHIFT,
+			csiphybase + MIPI_CSIPHY_GLBL_RESET_ADDR);
+	}
+
+	lane_mask &= 0x1f;
+	while (lane_mask & 0x1f) {
+		if (!(lane_mask & 0x1)) {
+			j++;
+			lane_mask >>= 1;
+			continue;
+		}
+		msm_camera_io_w(0x10,
+			csiphybase + MIPI_CSIPHY_LNn_CFG2_ADDR + 0x40*j);
+		msm_camera_io_w(csiphy_params->settle_cnt,
+			csiphybase + MIPI_CSIPHY_LNn_CFG3_ADDR + 0x40*j);
+		msm_camera_io_w(MIPI_CSIPHY_INTERRUPT_MASK_VAL, csiphybase +
+			MIPI_CSIPHY_INTERRUPT_MASK_ADDR + 0x4*j);
+		msm_camera_io_w(MIPI_CSIPHY_INTERRUPT_MASK_VAL, csiphybase +
+			MIPI_CSIPHY_INTERRUPT_CLEAR_ADDR + 0x4*j);
+		j++;
+		lane_mask >>= 1;
+	}
+	msleep(20);
+	return rc;
+}
+
+static irqreturn_t msm_csiphy_irq(int irq_num, void *data)
+{
+	uint32_t irq;
+	int i;
+	struct csiphy_device *csiphy_dev = data;
+
+	for (i = 0; i < 8; i++) {
+		irq = msm_camera_io_r(
+			csiphy_dev->base +
+			MIPI_CSIPHY_INTERRUPT_STATUS0_ADDR + 0x4*i);
+		msm_camera_io_w(irq,
+			csiphy_dev->base +
+			MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR + 0x4*i);
+		pr_err("%s MIPI_CSIPHY%d_INTERRUPT_STATUS%d = 0x%x\n",
+			 __func__, csiphy_dev->pdev->id, i, irq);
+		msm_camera_io_w(0x1, csiphy_dev->base +
+			MIPI_CSIPHY_GLBL_IRQ_CMD_ADDR);
+		msm_camera_io_w(0x0, csiphy_dev->base +
+			MIPI_CSIPHY_GLBL_IRQ_CMD_ADDR);
+		msm_camera_io_w(0x0,
+			csiphy_dev->base +
+			MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR + 0x4*i);
+	}
+	return IRQ_HANDLED;
+}
+
+static void msm_csiphy_reset(struct csiphy_device *csiphy_dev)
+{
+	msm_camera_io_w(0x1, csiphy_dev->base + MIPI_CSIPHY_GLBL_RESET_ADDR);
+	usleep_range(5000, 8000);
+	msm_camera_io_w(0x0, csiphy_dev->base + MIPI_CSIPHY_GLBL_RESET_ADDR);
+}
+
+static int msm_csiphy_subdev_g_chip_ident(struct v4l2_subdev *sd,
+			struct v4l2_dbg_chip_ident *chip)
+{
+	BUG_ON(!chip);
+	chip->ident = V4L2_IDENT_CSIPHY;
+	chip->revision = 0;
+	return 0;
+}
+
+static struct msm_cam_clk_info csiphy_8960_clk_info[] = {
+	{"csiphy_timer_src_clk", 177780000},
+	{"csiphy_timer_clk", -1},
+};
+
+static struct msm_cam_clk_info csiphy_8974_clk_info[] = {
+	{"ispif_ahb_clk", -1},
+	{"csiphy_timer_src_clk", 200000000},
+	{"csiphy_timer_clk", -1},
+};
+
+static int msm_csiphy_init(struct csiphy_device *csiphy_dev)
+{
+	int rc = 0;
+	if (csiphy_dev == NULL) {
+		pr_err("%s: csiphy_dev NULL\n", __func__);
+		rc = -ENOMEM;
+		return rc;
+	}
+
+	if (csiphy_dev->csiphy_state == CSIPHY_POWER_UP) {
+		pr_err("%s: csiphy invalid state %d\n", __func__,
+			csiphy_dev->csiphy_state);
+		rc = -EINVAL;
+		return rc;
+	}
+
+	if (csiphy_dev->ref_count++) {
+		CDBG("%s csiphy refcount = %d\n", __func__,
+			csiphy_dev->ref_count);
+		return rc;
+	}
+
+	csiphy_dev->base = ioremap(csiphy_dev->mem->start,
+		resource_size(csiphy_dev->mem));
+	if (!csiphy_dev->base) {
+		pr_err("%s: csiphy_dev->base NULL\n", __func__);
+		csiphy_dev->ref_count--;
+		rc = -ENOMEM;
+		return rc;
+	}
+
+	if (CSIPHY_VERSION != CSIPHY_VERSION_V3)
+		rc = msm_cam_clk_enable(&csiphy_dev->pdev->dev,
+			csiphy_8960_clk_info, csiphy_dev->csiphy_clk,
+			ARRAY_SIZE(csiphy_8960_clk_info), 1);
+	else
+		rc = msm_cam_clk_enable(&csiphy_dev->pdev->dev,
+			csiphy_8974_clk_info, csiphy_dev->csiphy_clk,
+			ARRAY_SIZE(csiphy_8974_clk_info), 1);
+
+	if (rc < 0) {
+		pr_err("%s: csiphy clk enable failed\n", __func__);
+		csiphy_dev->ref_count--;
+		iounmap(csiphy_dev->base);
+		csiphy_dev->base = NULL;
+		return rc;
+	}
+
+#if DBG_CSIPHY
+	enable_irq(csiphy_dev->irq->start);
+#endif
+	msm_csiphy_reset(csiphy_dev);
+
+	csiphy_dev->hw_version =
+		msm_camera_io_r(csiphy_dev->base + MIPI_CSIPHY_HW_VERSION_ADDR);
+
+	csiphy_dev->csiphy_state = CSIPHY_POWER_UP;
+	return 0;
+}
+
+static int msm_csiphy_release(struct csiphy_device *csiphy_dev, void *arg)
+{
+	int i = 0;
+	struct msm_camera_csi_lane_params *csi_lane_params;
+	uint16_t csi_lane_mask;
+	csi_lane_params = (struct msm_camera_csi_lane_params *)arg;
+	csi_lane_mask = csi_lane_params->csi_lane_mask;
+
+	if (!csiphy_dev || !csiphy_dev->ref_count) {
+		pr_err("%s csiphy dev NULL / ref_count ZERO\n", __func__);
+		return 0;
+	}
+
+	if (csiphy_dev->csiphy_state != CSIPHY_POWER_UP) {
+		pr_err("%s: csiphy invalid state %d\n", __func__,
+			csiphy_dev->csiphy_state);
+		return -EINVAL;
+	}
+
+	CDBG("%s csiphy_params, lane assign %x mask = %x\n",
+		__func__,
+		csi_lane_params->csi_lane_assign,
+		csi_lane_params->csi_lane_mask);
+
+	if (csiphy_dev->hw_version != CSIPHY_VERSION_V3) {
+		csiphy_dev->lane_mask[csiphy_dev->pdev->id] = 0;
+		for (i = 0; i < 4; i++)
+			msm_camera_io_w(0x0, csiphy_dev->base +
+				MIPI_CSIPHY_LNn_CFG2_ADDR + 0x40*i);
+	} else {
+		csiphy_dev->lane_mask[csiphy_dev->pdev->id] &=
+			~(csi_lane_params->csi_lane_mask);
+		i = 0;
+		while (csi_lane_mask & 0x1F) {
+			if (csi_lane_mask & 0x1) {
+				msm_camera_io_w(0x0, csiphy_dev->base +
+					MIPI_CSIPHY_LNn_CFG2_ADDR + 0x40*i);
+			}
+			csi_lane_mask >>= 1;
+			i++;
+		}
+	}
+
+	if (--csiphy_dev->ref_count) {
+		CDBG("%s csiphy refcount = %d\n", __func__,
+			csiphy_dev->ref_count);
+		return 0;
+	}
+
+	msm_camera_io_w(0x0, csiphy_dev->base + MIPI_CSIPHY_LNCK_CFG2_ADDR);
+	msm_camera_io_w(0x0, csiphy_dev->base + MIPI_CSIPHY_GLBL_PWR_CFG_ADDR);
+
+#if DBG_CSIPHY
+	disable_irq(csiphy_dev->irq->start);
+#endif
+	if (CSIPHY_VERSION != CSIPHY_VERSION_V3)
+		msm_cam_clk_enable(&csiphy_dev->pdev->dev,
+			csiphy_8960_clk_info, csiphy_dev->csiphy_clk,
+			ARRAY_SIZE(csiphy_8960_clk_info), 0);
+	else
+		msm_cam_clk_enable(&csiphy_dev->pdev->dev,
+			csiphy_8974_clk_info, csiphy_dev->csiphy_clk,
+			ARRAY_SIZE(csiphy_8974_clk_info), 0);
+
+	iounmap(csiphy_dev->base);
+	csiphy_dev->base = NULL;
+	csiphy_dev->csiphy_state = CSIPHY_POWER_DOWN;
+	return 0;
+}
+
+static long msm_csiphy_cmd(struct csiphy_device *csiphy_dev, void *arg)
+{
+	int rc = 0;
+	struct csiphy_cfg_data cdata;
+	struct msm_camera_csiphy_params csiphy_params;
+	if (!csiphy_dev) {
+		pr_err("%s: csiphy_dev NULL\n", __func__);
+		return -EINVAL;
+	}
+	if (copy_from_user(&cdata,
+		(void *)arg,
+		sizeof(struct csiphy_cfg_data))) {
+		pr_err("%s: %d failed\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+	switch (cdata.cfgtype) {
+	case CSIPHY_INIT:
+		rc = msm_csiphy_init(csiphy_dev);
+		break;
+	case CSIPHY_CFG:
+		if (copy_from_user(&csiphy_params,
+			(void *)cdata.csiphy_params,
+			sizeof(struct msm_camera_csiphy_params))) {
+			pr_err("%s: %d failed\n", __func__, __LINE__);
+			rc = -EFAULT;
+			break;
+		}
+		rc = msm_csiphy_lane_config(csiphy_dev, &csiphy_params);
+		break;
+	default:
+		pr_err("%s: %d failed\n", __func__, __LINE__);
+		rc = -ENOIOCTLCMD;
+		break;
+	}
+	return rc;
+}
+
+static long msm_csiphy_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int cmd, void *arg)
+{
+	int rc = -ENOIOCTLCMD;
+	struct csiphy_device *csiphy_dev = v4l2_get_subdevdata(sd);
+	mutex_lock(&csiphy_dev->mutex);
+	switch (cmd) {
+	case VIDIOC_MSM_CSIPHY_CFG:
+		rc = msm_csiphy_cmd(csiphy_dev, arg);
+		break;
+	case VIDIOC_MSM_CSIPHY_RELEASE:
+		rc = msm_csiphy_release(csiphy_dev, arg);
+		break;
+	default:
+		pr_err("%s: command not found\n", __func__);
+	}
+	mutex_unlock(&csiphy_dev->mutex);
+	return rc;
+}
+
+static const struct v4l2_subdev_internal_ops msm_csiphy_internal_ops;
+
+static struct v4l2_subdev_core_ops msm_csiphy_subdev_core_ops = {
+	.g_chip_ident = &msm_csiphy_subdev_g_chip_ident,
+	.ioctl = &msm_csiphy_subdev_ioctl,
+};
+
+static const struct v4l2_subdev_ops msm_csiphy_subdev_ops = {
+	.core = &msm_csiphy_subdev_core_ops,
+};
+
+static int __devinit csiphy_probe(struct platform_device *pdev)
+{
+	struct csiphy_device *new_csiphy_dev;
+	int rc = 0;
+	struct msm_cam_subdev_info sd_info;
+
+	new_csiphy_dev = kzalloc(sizeof(struct csiphy_device), GFP_KERNEL);
+	if (!new_csiphy_dev) {
+		pr_err("%s: no enough memory\n", __func__);
+		return -ENOMEM;
+	}
+
+	v4l2_subdev_init(&new_csiphy_dev->subdev, &msm_csiphy_subdev_ops);
+	new_csiphy_dev->subdev.internal_ops = &msm_csiphy_internal_ops;
+	new_csiphy_dev->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	snprintf(new_csiphy_dev->subdev.name,
+			ARRAY_SIZE(new_csiphy_dev->subdev.name), "msm_csiphy");
+	v4l2_set_subdevdata(&new_csiphy_dev->subdev, new_csiphy_dev);
+	platform_set_drvdata(pdev, &new_csiphy_dev->subdev);
+
+	mutex_init(&new_csiphy_dev->mutex);
+
+	if (pdev->dev.of_node)
+		of_property_read_u32((&pdev->dev)->of_node,
+			"cell-index", &pdev->id);
+	CDBG("%s: device id = %d\n", __func__, pdev->id);
+
+	new_csiphy_dev->mem = platform_get_resource_byname(pdev,
+					IORESOURCE_MEM, "csiphy");
+	if (!new_csiphy_dev->mem) {
+		pr_err("%s: no mem resource?\n", __func__);
+		rc = -ENODEV;
+		goto csiphy_no_resource;
+	}
+	new_csiphy_dev->irq = platform_get_resource_byname(pdev,
+					IORESOURCE_IRQ, "csiphy");
+	if (!new_csiphy_dev->irq) {
+		pr_err("%s: no irq resource?\n", __func__);
+		rc = -ENODEV;
+		goto csiphy_no_resource;
+	}
+	new_csiphy_dev->io = request_mem_region(new_csiphy_dev->mem->start,
+		resource_size(new_csiphy_dev->mem), pdev->name);
+	if (!new_csiphy_dev->io) {
+		pr_err("%s: no valid mem region\n", __func__);
+		rc = -EBUSY;
+		goto csiphy_no_resource;
+	}
+
+	rc = request_irq(new_csiphy_dev->irq->start, msm_csiphy_irq,
+		IRQF_TRIGGER_RISING, "csiphy", new_csiphy_dev);
+	if (rc < 0) {
+		release_mem_region(new_csiphy_dev->mem->start,
+			resource_size(new_csiphy_dev->mem));
+		pr_err("%s: irq request fail\n", __func__);
+		rc = -EBUSY;
+		goto csiphy_no_resource;
+	}
+	disable_irq(new_csiphy_dev->irq->start);
+
+	new_csiphy_dev->pdev = pdev;
+	sd_info.sdev_type = CSIPHY_DEV;
+	sd_info.sd_index = pdev->id;
+	sd_info.irq_num = new_csiphy_dev->irq->start;
+	msm_cam_register_subdev_node(
+		&new_csiphy_dev->subdev, &sd_info);
+
+	media_entity_init(&new_csiphy_dev->subdev.entity, 0, NULL, 0);
+	new_csiphy_dev->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	new_csiphy_dev->subdev.entity.group_id = CSIPHY_DEV;
+	new_csiphy_dev->subdev.entity.name = pdev->name;
+	new_csiphy_dev->subdev.entity.revision =
+		new_csiphy_dev->subdev.devnode->num;
+	new_csiphy_dev->csiphy_state = CSIPHY_POWER_DOWN;
+	return 0;
+
+csiphy_no_resource:
+	mutex_destroy(&new_csiphy_dev->mutex);
+	kfree(new_csiphy_dev);
+	return 0;
+}
+
+static const struct of_device_id msm_csiphy_dt_match[] = {
+	{.compatible = "qcom,csiphy"},
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, msm_csiphy_dt_match);
+
+static struct platform_driver csiphy_driver = {
+	.probe = csiphy_probe,
+	.driver = {
+		.name = MSM_CSIPHY_DRV_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = msm_csiphy_dt_match,
+	},
+};
+
+static int __init msm_csiphy_init_module(void)
+{
+	return platform_driver_register(&csiphy_driver);
+}
+
+static void __exit msm_csiphy_exit_module(void)
+{
+	platform_driver_unregister(&csiphy_driver);
+}
+
+module_init(msm_csiphy_init_module);
+module_exit(msm_csiphy_exit_module);
+MODULE_DESCRIPTION("MSM CSIPHY driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/csi/msm_csiphy.h b/drivers/media/platform/msm/camera_v1/csi/msm_csiphy.h
new file mode 100644
index 0000000..93c9758
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/csi/msm_csiphy.h
@@ -0,0 +1,49 @@
+/* Copyright (c) 2011-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.
+ */
+
+#ifndef MSM_CSIPHY_H
+#define MSM_CSIPHY_H
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <media/v4l2-subdev.h>
+#include <media/msm_camera.h>
+
+#define MAX_CSIPHY 3
+
+enum msm_csiphy_state_t {
+	CSIPHY_POWER_UP,
+	CSIPHY_POWER_DOWN,
+};
+
+struct csiphy_device {
+	struct platform_device *pdev;
+	struct v4l2_subdev subdev;
+	struct resource *mem;
+	struct resource *irq;
+	struct resource *io;
+	void __iomem *base;
+	struct mutex mutex;
+	uint32_t hw_version;
+	enum msm_csiphy_state_t csiphy_state;
+
+	struct clk *csiphy_clk[3];
+	uint8_t ref_count;
+	uint16_t lane_mask[MAX_CSIPHY];
+};
+
+#define VIDIOC_MSM_CSIPHY_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 7, struct csiphy_cfg_data*)
+
+#define VIDIOC_MSM_CSIPHY_RELEASE \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 9, void *)
+#endif
diff --git a/drivers/media/platform/msm/camera_v1/csi/msm_ispif.c b/drivers/media/platform/msm/camera_v1/csi/msm_ispif.c
new file mode 100644
index 0000000..009a8d0
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/csi/msm_ispif.c
@@ -0,0 +1,928 @@
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <mach/gpio.h>
+#include <mach/camera.h>
+#include "msm_ispif.h"
+#include "msm.h"
+#include "msm_ispif_hwreg.h"
+
+#define V4L2_IDENT_ISPIF                     50001
+#define CSID_VERSION_V2                      0x02000011
+#define CSID_VERSION_V3                      0x30000000
+
+#define MAX_CID 15
+
+static atomic_t ispif_irq_cnt;
+static spinlock_t ispif_tasklet_lock;
+static struct list_head ispif_tasklet_q;
+
+static int msm_ispif_intf_reset(struct ispif_device *ispif,
+	uint16_t intfmask, uint8_t vfe_intf)
+{
+	int rc = 0;
+	uint32_t data = (0x1 << STROBED_RST_EN);
+	uint16_t intfnum = 0, mask = intfmask;
+
+	while (mask != 0) {
+		if (!(intfmask & (0x1 << intfnum))) {
+			mask >>= 1;
+			intfnum++;
+			continue;
+		}
+		switch (intfnum) {
+		case PIX0:
+			data |= (0x1 << PIX_0_VFE_RST_STB) |
+				(0x1 << PIX_0_CSID_RST_STB);
+			ispif->pix_sof_count = 0;
+			break;
+
+		case RDI0:
+			data |= (0x1 << RDI_0_VFE_RST_STB) |
+				(0x1 << RDI_0_CSID_RST_STB);
+			break;
+
+		case PIX1:
+			data |= (0x1 << PIX_1_VFE_RST_STB) |
+				(0x1 << PIX_1_CSID_RST_STB);
+			break;
+
+		case RDI1:
+			data |= (0x1 << RDI_1_VFE_RST_STB) |
+				(0x1 << RDI_1_CSID_RST_STB);
+			break;
+
+		case RDI2:
+			data |= (0x1 << RDI_2_VFE_RST_STB) |
+				(0x1 << RDI_2_CSID_RST_STB);
+			break;
+
+		default:
+			rc = -EINVAL;
+			break;
+		}
+		mask >>= 1;
+		intfnum++;
+	}	/*end while */
+	if (data > 0x1) {
+		if (vfe_intf == VFE0)
+			msm_camera_io_w(data, ispif->base + ISPIF_RST_CMD_ADDR);
+		else
+			msm_camera_io_w(data, ispif->base +
+				ISPIF_RST_CMD_1_ADDR);
+		rc = wait_for_completion_interruptible(&ispif->reset_complete);
+	}
+	return rc;
+}
+
+static int msm_ispif_reset(struct ispif_device *ispif)
+{
+	int rc = 0;
+	ispif->pix_sof_count = 0;
+	msm_camera_io_w(ISPIF_RST_CMD_MASK, ispif->base + ISPIF_RST_CMD_ADDR);
+	if (ispif->csid_version == CSID_VERSION_V3)
+		msm_camera_io_w(ISPIF_RST_CMD_1_MASK, ispif->base +
+				ISPIF_RST_CMD_1_ADDR);
+	rc = wait_for_completion_interruptible(&ispif->reset_complete);
+	return rc;
+}
+
+static int msm_ispif_subdev_g_chip_ident(struct v4l2_subdev *sd,
+			struct v4l2_dbg_chip_ident *chip)
+{
+	BUG_ON(!chip);
+	chip->ident = V4L2_IDENT_ISPIF;
+	chip->revision = 0;
+	return 0;
+}
+
+static void msm_ispif_sel_csid_core(struct ispif_device *ispif,
+	uint8_t intftype, uint8_t csid, uint8_t vfe_intf)
+{
+	int rc = 0;
+	uint32_t data = 0;
+
+	if (ispif->csid_version <= CSID_VERSION_V2) {
+		if (ispif->ispif_clk[intftype] == NULL) {
+			pr_err("%s: ispif NULL clk\n", __func__);
+			return;
+		}
+		rc = clk_set_rate(ispif->ispif_clk[intftype], csid);
+		if (rc < 0)
+			pr_err("%s: clk_set_rate failed %d\n", __func__, rc);
+	}
+	data = msm_camera_io_r(ispif->base + ISPIF_INPUT_SEL_ADDR +
+		(0x200 * vfe_intf));
+	switch (intftype) {
+	case PIX0:
+		data &= ~(0x3);
+		data |= csid;
+		break;
+
+	case RDI0:
+		data &= ~(0x3 << 4);
+		data |= (csid << 4);
+		break;
+
+	case PIX1:
+		data &= ~(0x3 << 8);
+		data |= (csid << 8);
+		break;
+
+	case RDI1:
+		data &= ~(0x3 << 12);
+		data |= (csid << 12);
+		break;
+
+	case RDI2:
+		data &= ~(0x3 << 20);
+		data |= (csid << 20);
+		break;
+	}
+	if (data) {
+		msm_camera_io_w(data, ispif->base + ISPIF_INPUT_SEL_ADDR +
+			(0x200 * vfe_intf));
+	}
+}
+
+static void msm_ispif_enable_intf_cids(struct ispif_device *ispif,
+	uint8_t intftype, uint16_t cid_mask, uint8_t vfe_intf)
+{
+	uint32_t data = 0;
+	mutex_lock(&ispif->mutex);
+	switch (intftype) {
+	case PIX0:
+		data = msm_camera_io_r(ispif->base +
+			ISPIF_PIX_0_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
+		data |= cid_mask;
+		msm_camera_io_w(data, ispif->base +
+			ISPIF_PIX_0_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
+		break;
+
+	case RDI0:
+		data = msm_camera_io_r(ispif->base +
+			ISPIF_RDI_0_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
+		data |= cid_mask;
+		msm_camera_io_w(data, ispif->base +
+			ISPIF_RDI_0_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
+		break;
+
+	case PIX1:
+		data = msm_camera_io_r(ispif->base +
+			ISPIF_PIX_1_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
+		data |= cid_mask;
+		msm_camera_io_w(data, ispif->base +
+			ISPIF_PIX_1_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
+		break;
+
+	case RDI1:
+		data = msm_camera_io_r(ispif->base +
+			ISPIF_RDI_1_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
+		data |= cid_mask;
+		msm_camera_io_w(data, ispif->base +
+			ISPIF_RDI_1_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
+		break;
+
+	case RDI2:
+		data = msm_camera_io_r(ispif->base +
+			ISPIF_RDI_2_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
+		data |= cid_mask;
+		msm_camera_io_w(data, ispif->base +
+			ISPIF_RDI_2_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
+		break;
+	}
+	mutex_unlock(&ispif->mutex);
+}
+
+static int32_t msm_ispif_validate_intf_status(struct ispif_device *ispif,
+	uint8_t intftype, uint8_t vfe_intf)
+{
+	int32_t rc = 0;
+	uint32_t data = 0;
+	mutex_lock(&ispif->mutex);
+	switch (intftype) {
+	case PIX0:
+		data = msm_camera_io_r(ispif->base +
+				ISPIF_PIX_0_STATUS_ADDR + (0x200 * vfe_intf));
+		break;
+
+	case RDI0:
+		data = msm_camera_io_r(ispif->base +
+				ISPIF_RDI_0_STATUS_ADDR + (0x200 * vfe_intf));
+		break;
+
+	case PIX1:
+		data = msm_camera_io_r(ispif->base +
+				ISPIF_PIX_1_STATUS_ADDR + (0x200 * vfe_intf));
+		break;
+
+	case RDI1:
+		data = msm_camera_io_r(ispif->base +
+				ISPIF_RDI_1_STATUS_ADDR + (0x200 * vfe_intf));
+		break;
+
+	case RDI2:
+		data = msm_camera_io_r(ispif->base +
+				ISPIF_RDI_2_STATUS_ADDR + (0x200 * vfe_intf));
+		break;
+	}
+	if ((data & 0xf) != 0xf)
+		rc = -EBUSY;
+	mutex_unlock(&ispif->mutex);
+	return rc;
+}
+
+static int msm_ispif_config(struct ispif_device *ispif,
+	struct msm_ispif_params_list *params_list)
+{
+	uint32_t params_len;
+	struct msm_ispif_params *ispif_params;
+	int rc = 0, i = 0;
+	uint8_t intftype;
+	uint8_t vfe_intf;
+	params_len = params_list->len;
+	ispif_params = params_list->params;
+	CDBG("Enable interface\n");
+	msm_camera_io_w(0x00000000, ispif->base + ISPIF_IRQ_MASK_ADDR);
+	msm_camera_io_w(0x00000000, ispif->base + ISPIF_IRQ_MASK_1_ADDR);
+	msm_camera_io_w(0x00000000, ispif->base + ISPIF_IRQ_MASK_2_ADDR);
+	for (i = 0; i < params_len; i++) {
+		intftype = ispif_params[i].intftype;
+		vfe_intf = ispif_params[i].vfe_intf;
+		CDBG("%s intftype %x, vfe_intf %d, csid %d\n", __func__,
+			intftype, vfe_intf, ispif_params[i].csid);
+		if ((intftype >= INTF_MAX) ||
+			(ispif->csid_version <= CSID_VERSION_V2 &&
+			vfe_intf > VFE0) ||
+			(ispif->csid_version == CSID_VERSION_V3 &&
+			vfe_intf >= VFE_MAX)) {
+			pr_err("%s: intftype / vfe intf not valid\n",
+				__func__);
+			return -EINVAL;
+		}
+
+		rc = msm_ispif_validate_intf_status(ispif, intftype, vfe_intf);
+		if (rc < 0) {
+			pr_err("%s:%d failed rc %d\n", __func__, __LINE__, rc);
+			return rc;
+		}
+		msm_ispif_sel_csid_core(ispif, intftype, ispif_params[i].csid,
+			vfe_intf);
+		msm_ispif_enable_intf_cids(ispif, intftype,
+			ispif_params[i].cid_mask, vfe_intf);
+	}
+
+	msm_camera_io_w(ISPIF_IRQ_STATUS_MASK, ispif->base +
+					ISPIF_IRQ_MASK_ADDR);
+	msm_camera_io_w(ISPIF_IRQ_STATUS_MASK, ispif->base +
+					ISPIF_IRQ_CLEAR_ADDR);
+	msm_camera_io_w(ISPIF_IRQ_STATUS_1_MASK, ispif->base +
+					ISPIF_IRQ_MASK_1_ADDR);
+	msm_camera_io_w(ISPIF_IRQ_STATUS_1_MASK, ispif->base +
+					ISPIF_IRQ_CLEAR_1_ADDR);
+	msm_camera_io_w(ISPIF_IRQ_STATUS_2_MASK, ispif->base +
+					ISPIF_IRQ_MASK_2_ADDR);
+	msm_camera_io_w(ISPIF_IRQ_STATUS_2_MASK, ispif->base +
+					ISPIF_IRQ_CLEAR_2_ADDR);
+	msm_camera_io_w(ISPIF_IRQ_GLOBAL_CLEAR_CMD, ispif->base +
+		 ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR);
+	return rc;
+}
+
+static uint32_t msm_ispif_get_cid_mask(struct ispif_device *ispif,
+	uint16_t intftype, uint8_t vfe_intf)
+{
+	uint32_t mask = 0;
+	switch (intftype) {
+	case PIX0:
+		mask = msm_camera_io_r(ispif->base +
+			ISPIF_PIX_0_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
+		break;
+
+	case RDI0:
+		mask = msm_camera_io_r(ispif->base +
+			ISPIF_RDI_0_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
+		break;
+
+	case PIX1:
+		mask = msm_camera_io_r(ispif->base +
+			ISPIF_PIX_1_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
+		break;
+
+	case RDI1:
+		mask = msm_camera_io_r(ispif->base +
+			ISPIF_RDI_1_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
+		break;
+
+	case RDI2:
+		mask = msm_camera_io_r(ispif->base +
+			ISPIF_RDI_2_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
+		break;
+
+	default:
+		break;
+	}
+	return mask;
+}
+
+static void msm_ispif_intf_cmd(struct ispif_device *ispif, uint16_t intfmask,
+	uint8_t intf_cmd_mask, uint8_t vfe_intf)
+{
+	uint8_t vc = 0, val = 0;
+	uint16_t mask = intfmask, intfnum = 0;
+	uint32_t cid_mask = 0;
+	uint32_t global_intf_cmd_mask1 = 0xFFFFFFFF;
+	while (mask != 0) {
+		if (!(intfmask & (0x1 << intfnum))) {
+			mask >>= 1;
+			intfnum++;
+			continue;
+		}
+
+		cid_mask = msm_ispif_get_cid_mask(ispif, intfnum, vfe_intf);
+		vc = 0;
+
+		while (cid_mask != 0) {
+			if ((cid_mask & 0xf) != 0x0) {
+				if (intfnum != RDI2) {
+					val = (intf_cmd_mask>>(vc*2)) & 0x3;
+					ispif->global_intf_cmd_mask |=
+						(0x3 << ((vc * 2) +
+						(intfnum * 8)));
+					ispif->global_intf_cmd_mask &=
+						~((0x3 & ~val) << ((vc * 2) +
+						(intfnum * 8)));
+				} else
+					global_intf_cmd_mask1 &=
+						~((0x3 & ~intf_cmd_mask)
+						<< ((vc * 2) + 8));
+			}
+			vc++;
+			cid_mask >>= 4;
+		}
+		mask >>= 1;
+		intfnum++;
+	}
+	msm_camera_io_w(ispif->global_intf_cmd_mask,
+		ispif->base + ISPIF_INTF_CMD_ADDR + (0x200 * vfe_intf));
+	if (global_intf_cmd_mask1 != 0xFFFFFFFF)
+		msm_camera_io_w(global_intf_cmd_mask1,
+			ispif->base + ISPIF_INTF_CMD_1_ADDR +
+			(0x200 * vfe_intf));
+}
+
+static int msm_ispif_abort_intf_transfer(struct ispif_device *ispif,
+	uint16_t intfmask, uint8_t vfe_intf)
+{
+	int rc = 0;
+	uint8_t intf_cmd_mask = 0xAA;
+	uint16_t intfnum = 0, mask = intfmask;
+	mutex_lock(&ispif->mutex);
+	CDBG("%s intfmask %x intf_cmd_mask %x\n", __func__, intfmask,
+		intf_cmd_mask);
+	msm_ispif_intf_cmd(ispif, intfmask, intf_cmd_mask, vfe_intf);
+	while (mask != 0) {
+		if (intfmask & (0x1 << intfnum))
+			ispif->global_intf_cmd_mask |= (0xFF << (intfnum * 8));
+		mask >>= 1;
+		intfnum++;
+		if (intfnum == RDI2)
+			break;
+	}
+	mutex_unlock(&ispif->mutex);
+	return rc;
+}
+
+static int msm_ispif_start_intf_transfer(struct ispif_device *ispif,
+	uint16_t intfmask, uint8_t vfe_intf)
+{
+	uint8_t intf_cmd_mask = 0x55;
+	int rc = 0;
+	mutex_lock(&ispif->mutex);
+	rc = msm_ispif_intf_reset(ispif, intfmask, vfe_intf);
+	CDBG("%s intfmask start after%x intf_cmd_mask %x\n", __func__, intfmask,
+		intf_cmd_mask);
+	msm_ispif_intf_cmd(ispif, intfmask, intf_cmd_mask, vfe_intf);
+	mutex_unlock(&ispif->mutex);
+	return rc;
+}
+
+static int msm_ispif_stop_intf_transfer(struct ispif_device *ispif,
+	uint16_t intfmask, uint8_t vfe_intf)
+{
+	int rc = 0;
+	uint8_t intf_cmd_mask = 0x00;
+	uint16_t intfnum = 0, mask = intfmask;
+	mutex_lock(&ispif->mutex);
+	CDBG("%s intfmask %x intf_cmd_mask %x\n", __func__, intfmask,
+		intf_cmd_mask);
+	msm_ispif_intf_cmd(ispif, intfmask, intf_cmd_mask, vfe_intf);
+	while (mask != 0) {
+		if (intfmask & (0x1 << intfnum)) {
+			switch (intfnum) {
+			case PIX0:
+				while ((msm_camera_io_r(ispif->base +
+					ISPIF_PIX_0_STATUS_ADDR +
+					(0x200 * vfe_intf))
+					& 0xf) != 0xf) {
+					CDBG("Wait for pix0 Idle\n");
+				}
+				break;
+
+			case RDI0:
+				while ((msm_camera_io_r(ispif->base +
+					ISPIF_RDI_0_STATUS_ADDR +
+					(0x200 * vfe_intf))
+					& 0xf) != 0xf) {
+					CDBG("Wait for rdi0 Idle\n");
+				}
+				break;
+
+			case PIX1:
+				while ((msm_camera_io_r(ispif->base +
+					ISPIF_PIX_1_STATUS_ADDR +
+					(0x200 * vfe_intf))
+					& 0xf) != 0xf) {
+					CDBG("Wait for pix1 Idle\n");
+				}
+				break;
+
+			case RDI1:
+				while ((msm_camera_io_r(ispif->base +
+					ISPIF_RDI_1_STATUS_ADDR +
+					(0x200 * vfe_intf))
+					& 0xf) != 0xf) {
+					CDBG("Wait for rdi1 Idle\n");
+				}
+				break;
+
+			case RDI2:
+				while ((msm_camera_io_r(ispif->base +
+					ISPIF_RDI_2_STATUS_ADDR +
+					(0x200 * vfe_intf))
+					& 0xf) != 0xf) {
+					CDBG("Wait for rdi2 Idle\n");
+				}
+				break;
+
+			default:
+				break;
+			}
+			if (intfnum != RDI2)
+				ispif->global_intf_cmd_mask |= (0xFF <<
+					(intfnum * 8));
+		}
+		mask >>= 1;
+		intfnum++;
+	}
+	mutex_unlock(&ispif->mutex);
+	return rc;
+}
+
+static int msm_ispif_subdev_video_s_stream(struct v4l2_subdev *sd,
+	int enable)
+{
+	struct ispif_device *ispif =
+			(struct ispif_device *)v4l2_get_subdevdata(sd);
+	uint32_t cmd = enable & ((1<<ISPIF_S_STREAM_SHIFT)-1);
+	uint16_t intf = enable >> ISPIF_S_STREAM_SHIFT;
+	uint8_t vfe_intf = enable >> ISPIF_VFE_INTF_SHIFT;
+	int rc = -EINVAL;
+	CDBG("%s enable %x, cmd %x, intf %x\n", __func__, enable, cmd, intf);
+	BUG_ON(!ispif);
+	if ((ispif->csid_version <= CSID_VERSION_V2 && vfe_intf > VFE0) ||
+		(ispif->csid_version == CSID_VERSION_V3 &&
+		vfe_intf >= VFE_MAX)) {
+		pr_err("%s invalid csid version %x && vfe intf %d\n", __func__,
+			ispif->csid_version, vfe_intf);
+		return rc;
+	}
+	switch (cmd) {
+	case ISPIF_ON_FRAME_BOUNDARY:
+		rc = msm_ispif_start_intf_transfer(ispif, intf, vfe_intf);
+		break;
+	case ISPIF_OFF_FRAME_BOUNDARY:
+		rc = msm_ispif_stop_intf_transfer(ispif, intf, vfe_intf);
+		break;
+	case ISPIF_OFF_IMMEDIATELY:
+		rc = msm_ispif_abort_intf_transfer(ispif, intf, vfe_intf);
+		break;
+	default:
+		break;
+	}
+	return rc;
+}
+
+static void send_rdi_sof(struct ispif_device *ispif,
+	enum msm_ispif_intftype interface, int count)
+{
+	struct rdi_count_msg sof_msg;
+	sof_msg.rdi_interface = interface;
+	sof_msg.count = count;
+	v4l2_subdev_notify(&ispif->subdev, NOTIFY_AXI_RDI_SOF_COUNT,
+					   (void *)&sof_msg);
+}
+
+static void ispif_do_tasklet(unsigned long data)
+{
+	unsigned long flags;
+
+	struct ispif_isr_queue_cmd *qcmd = NULL;
+	struct ispif_device *ispif;
+
+	ispif = (struct ispif_device *)data;
+	while (atomic_read(&ispif_irq_cnt)) {
+		spin_lock_irqsave(&ispif_tasklet_lock, flags);
+		qcmd = list_first_entry(&ispif_tasklet_q,
+			struct ispif_isr_queue_cmd, list);
+		atomic_sub(1, &ispif_irq_cnt);
+
+		if (!qcmd) {
+			spin_unlock_irqrestore(&ispif_tasklet_lock,
+				flags);
+			return;
+		}
+		list_del(&qcmd->list);
+		spin_unlock_irqrestore(&ispif_tasklet_lock,
+			flags);
+
+		kfree(qcmd);
+	}
+}
+
+static void ispif_process_irq(struct ispif_device *ispif,
+	struct ispif_irq_status *out)
+{
+	unsigned long flags;
+	struct ispif_isr_queue_cmd *qcmd;
+
+	qcmd = kzalloc(sizeof(struct ispif_isr_queue_cmd),
+		GFP_ATOMIC);
+	if (!qcmd) {
+		pr_err("ispif_process_irq: qcmd malloc failed!\n");
+		return;
+	}
+	qcmd->ispifInterruptStatus0 = out->ispifIrqStatus0;
+	qcmd->ispifInterruptStatus1 = out->ispifIrqStatus1;
+	qcmd->ispifInterruptStatus2 = out->ispifIrqStatus2;
+
+	if (qcmd->ispifInterruptStatus0 &
+			ISPIF_IRQ_STATUS_PIX_SOF_MASK) {
+			CDBG("%s: ispif PIX irq status", __func__);
+			ispif->pix_sof_count++;
+			v4l2_subdev_notify(&ispif->subdev,
+				NOTIFY_VFE_PIX_SOF_COUNT,
+				(void *)&ispif->pix_sof_count);
+	}
+
+	if (qcmd->ispifInterruptStatus0 &
+			ISPIF_IRQ_STATUS_RDI0_SOF_MASK) {
+			CDBG("%s: ispif RDI0 irq status", __func__);
+			ispif->rdi0_sof_count++;
+			send_rdi_sof(ispif, RDI_0, ispif->rdi0_sof_count);
+	}
+	if (qcmd->ispifInterruptStatus1 &
+		ISPIF_IRQ_STATUS_RDI1_SOF_MASK) {
+		CDBG("%s: ispif RDI1 irq status", __func__);
+		ispif->rdi1_sof_count++;
+		send_rdi_sof(ispif, RDI_1, ispif->rdi1_sof_count);
+	}
+	if (qcmd->ispifInterruptStatus2 &
+		ISPIF_IRQ_STATUS_RDI2_SOF_MASK) {
+		CDBG("%s: ispif RDI2 irq status", __func__);
+		ispif->rdi2_sof_count++;
+		send_rdi_sof(ispif, RDI_2, ispif->rdi2_sof_count);
+	}
+
+	spin_lock_irqsave(&ispif_tasklet_lock, flags);
+	list_add_tail(&qcmd->list, &ispif_tasklet_q);
+
+	atomic_add(1, &ispif_irq_cnt);
+	spin_unlock_irqrestore(&ispif_tasklet_lock, flags);
+	tasklet_schedule(&ispif->ispif_tasklet);
+	return;
+}
+
+static inline void msm_ispif_read_irq_status(struct ispif_irq_status *out,
+	void *data)
+{
+	uint32_t status0 = 0, status1 = 0, status2 = 0;
+	struct ispif_device *ispif = (struct ispif_device *)data;
+	out->ispifIrqStatus0 = msm_camera_io_r(ispif->base +
+		ISPIF_IRQ_STATUS_ADDR);
+	out->ispifIrqStatus1 = msm_camera_io_r(ispif->base +
+		ISPIF_IRQ_STATUS_1_ADDR);
+	out->ispifIrqStatus2 = msm_camera_io_r(ispif->base +
+		ISPIF_IRQ_STATUS_2_ADDR);
+	msm_camera_io_w(out->ispifIrqStatus0,
+		ispif->base + ISPIF_IRQ_CLEAR_ADDR);
+	msm_camera_io_w(out->ispifIrqStatus1,
+		ispif->base + ISPIF_IRQ_CLEAR_1_ADDR);
+	msm_camera_io_w(out->ispifIrqStatus2,
+		ispif->base + ISPIF_IRQ_CLEAR_2_ADDR);
+
+	CDBG("%s: irq vfe0 Irq_status0 = 0x%x, 1 = 0x%x, 2 = 0x%x\n",
+		__func__, out->ispifIrqStatus0, out->ispifIrqStatus1,
+		out->ispifIrqStatus2);
+	if (out->ispifIrqStatus0 & ISPIF_IRQ_STATUS_MASK) {
+		if (out->ispifIrqStatus0 & (0x1 << RESET_DONE_IRQ))
+			complete(&ispif->reset_complete);
+		if (out->ispifIrqStatus0 & (0x1 << PIX_INTF_0_OVERFLOW_IRQ))
+			pr_err("%s: pix intf 0 overflow.\n", __func__);
+		if (out->ispifIrqStatus0 & (0x1 << RAW_INTF_0_OVERFLOW_IRQ))
+			pr_err("%s: rdi intf 0 overflow.\n", __func__);
+		if (out->ispifIrqStatus1 & (0x1 << RAW_INTF_1_OVERFLOW_IRQ))
+			pr_err("%s: rdi intf 1 overflow.\n", __func__);
+		if (out->ispifIrqStatus2 & (0x1 << RAW_INTF_2_OVERFLOW_IRQ))
+			pr_err("%s: rdi intf 2 overflow.\n", __func__);
+		if ((out->ispifIrqStatus0 & ISPIF_IRQ_STATUS_SOF_MASK) ||
+			(out->ispifIrqStatus1 &	ISPIF_IRQ_STATUS_SOF_MASK) ||
+			(out->ispifIrqStatus2 & ISPIF_IRQ_STATUS_RDI2_SOF_MASK))
+			ispif_process_irq(ispif, out);
+	}
+	if (ispif->csid_version == CSID_VERSION_V3) {
+		status0 = msm_camera_io_r(ispif->base +
+			ISPIF_IRQ_STATUS_ADDR + 0x200);
+		msm_camera_io_w(status0,
+			ispif->base + ISPIF_IRQ_CLEAR_ADDR + 0x200);
+		status1 = msm_camera_io_r(ispif->base +
+			ISPIF_IRQ_STATUS_1_ADDR + 0x200);
+		msm_camera_io_w(status1,
+			ispif->base + ISPIF_IRQ_CLEAR_1_ADDR + 0x200);
+		status2 = msm_camera_io_r(ispif->base +
+			ISPIF_IRQ_STATUS_2_ADDR + 0x200);
+		msm_camera_io_w(status2,
+			ispif->base + ISPIF_IRQ_CLEAR_2_ADDR + 0x200);
+		CDBG("%s: irq vfe1 Irq_status0 = 0x%x, 1 = 0x%x, 2 = 0x%x\n",
+			__func__, status0, status1, status2);
+	}
+	msm_camera_io_w(ISPIF_IRQ_GLOBAL_CLEAR_CMD, ispif->base +
+		ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR);
+}
+
+static irqreturn_t msm_io_ispif_irq(int irq_num, void *data)
+{
+	struct ispif_irq_status irq;
+	msm_ispif_read_irq_status(&irq, data);
+	return IRQ_HANDLED;
+}
+
+static struct msm_cam_clk_info ispif_8960_clk_info[] = {
+	{"csi_pix_clk", 0},
+	{"csi_rdi_clk", 0},
+	{"csi_pix1_clk", 0},
+	{"csi_rdi1_clk", 0},
+	{"csi_rdi2_clk", 0},
+};
+
+static int msm_ispif_init(struct ispif_device *ispif,
+	const uint32_t *csid_version)
+{
+	int rc = 0;
+	CDBG("%s called %d\n", __func__, __LINE__);
+
+	if (ispif->ispif_state == ISPIF_POWER_UP) {
+		pr_err("%s: ispif invalid state %d\n", __func__,
+			ispif->ispif_state);
+		rc = -EINVAL;
+		return rc;
+	}
+
+	spin_lock_init(&ispif_tasklet_lock);
+	INIT_LIST_HEAD(&ispif_tasklet_q);
+	rc = request_irq(ispif->irq->start, msm_io_ispif_irq,
+		IRQF_TRIGGER_RISING, "ispif", ispif);
+	ispif->global_intf_cmd_mask = 0xFFFFFFFF;
+	init_completion(&ispif->reset_complete);
+
+	tasklet_init(&ispif->ispif_tasklet,
+		ispif_do_tasklet, (unsigned long)ispif);
+
+	ispif->csid_version = *csid_version;
+	if (ispif->csid_version < CSID_VERSION_V2) {
+		rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_8960_clk_info,
+			ispif->ispif_clk, 2, 1);
+		if (rc < 0)
+			return rc;
+	} else if (ispif->csid_version == CSID_VERSION_V2) {
+		rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_8960_clk_info,
+			ispif->ispif_clk, ARRAY_SIZE(ispif_8960_clk_info), 1);
+		if (rc < 0)
+			return rc;
+	}
+	rc = msm_ispif_reset(ispif);
+	ispif->ispif_state = ISPIF_POWER_UP;
+	return rc;
+}
+
+static void msm_ispif_release(struct ispif_device *ispif)
+{
+	if (ispif->ispif_state != ISPIF_POWER_UP) {
+		pr_err("%s: ispif invalid state %d\n", __func__,
+			ispif->ispif_state);
+		return;
+	}
+
+	CDBG("%s, free_irq\n", __func__);
+	free_irq(ispif->irq->start, ispif);
+	tasklet_kill(&ispif->ispif_tasklet);
+
+	if (ispif->csid_version < CSID_VERSION_V2) {
+		msm_cam_clk_enable(&ispif->pdev->dev, ispif_8960_clk_info,
+			ispif->ispif_clk, 2, 0);
+	} else if (ispif->csid_version == CSID_VERSION_V2) {
+		msm_cam_clk_enable(&ispif->pdev->dev, ispif_8960_clk_info,
+			ispif->ispif_clk, ARRAY_SIZE(ispif_8960_clk_info), 0);
+	}
+	ispif->ispif_state = ISPIF_POWER_DOWN;
+}
+
+static long msm_ispif_cmd(struct v4l2_subdev *sd, void *arg)
+{
+	long rc = 0;
+	struct ispif_cfg_data cdata;
+	struct ispif_device *ispif =
+		(struct ispif_device *)v4l2_get_subdevdata(sd);
+	if (copy_from_user(&cdata, (void *)arg, sizeof(struct ispif_cfg_data)))
+		return -EFAULT;
+	CDBG("%s cfgtype = %d\n", __func__, cdata.cfgtype);
+	switch (cdata.cfgtype) {
+	case ISPIF_INIT:
+		CDBG("%s csid_version = %x\n", __func__,
+			cdata.cfg.csid_version);
+		rc = msm_ispif_init(ispif, &cdata.cfg.csid_version);
+		break;
+	case ISPIF_SET_CFG:
+		CDBG("%s len = %d, intftype = %d,.cid_mask = %d, csid = %d\n",
+			__func__,
+			cdata.cfg.ispif_params.len,
+			cdata.cfg.ispif_params.params[0].intftype,
+			cdata.cfg.ispif_params.params[0].cid_mask,
+			cdata.cfg.ispif_params.params[0].csid);
+		rc = msm_ispif_config(ispif, &cdata.cfg.ispif_params);
+		break;
+
+	case ISPIF_SET_ON_FRAME_BOUNDARY:
+	case ISPIF_SET_OFF_FRAME_BOUNDARY:
+	case ISPIF_SET_OFF_IMMEDIATELY:
+		rc = msm_ispif_subdev_video_s_stream(sd, cdata.cfg.cmd);
+		break;
+	case ISPIF_RELEASE:
+		msm_ispif_release(ispif);
+		break;
+	default:
+		break;
+	}
+
+	return rc;
+}
+
+static long msm_ispif_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd,
+								void *arg)
+{
+	switch (cmd) {
+	case VIDIOC_MSM_ISPIF_CFG:
+		return msm_ispif_cmd(sd, arg);
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
+static struct v4l2_subdev_core_ops msm_ispif_subdev_core_ops = {
+	.g_chip_ident = &msm_ispif_subdev_g_chip_ident,
+	.ioctl = &msm_ispif_subdev_ioctl,
+};
+
+static struct v4l2_subdev_video_ops msm_ispif_subdev_video_ops = {
+	.s_stream = &msm_ispif_subdev_video_s_stream,
+};
+
+static const struct v4l2_subdev_ops msm_ispif_subdev_ops = {
+	.core = &msm_ispif_subdev_core_ops,
+	.video = &msm_ispif_subdev_video_ops,
+};
+
+static const struct v4l2_subdev_internal_ops msm_ispif_internal_ops;
+
+static int __devinit ispif_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+	struct msm_cam_subdev_info sd_info;
+	struct ispif_device *ispif;
+
+	CDBG("%s\n", __func__);
+	ispif = kzalloc(sizeof(struct ispif_device), GFP_KERNEL);
+	if (!ispif) {
+		pr_err("%s: no enough memory\n", __func__);
+		return -ENOMEM;
+	}
+
+	v4l2_subdev_init(&ispif->subdev, &msm_ispif_subdev_ops);
+	ispif->subdev.internal_ops = &msm_ispif_internal_ops;
+	ispif->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	snprintf(ispif->subdev.name,
+			ARRAY_SIZE(ispif->subdev.name), "msm_ispif");
+	v4l2_set_subdevdata(&ispif->subdev, ispif);
+	platform_set_drvdata(pdev, &ispif->subdev);
+	snprintf(ispif->subdev.name, sizeof(ispif->subdev.name),
+								"ispif");
+	mutex_init(&ispif->mutex);
+
+	if (pdev->dev.of_node)
+		of_property_read_u32((&pdev->dev)->of_node,
+			"cell-index", &pdev->id);
+
+	ispif->mem = platform_get_resource_byname(pdev,
+					IORESOURCE_MEM, "ispif");
+	if (!ispif->mem) {
+		pr_err("%s: no mem resource?\n", __func__);
+		rc = -ENODEV;
+		goto ispif_no_resource;
+	}
+	ispif->irq = platform_get_resource_byname(pdev,
+					IORESOURCE_IRQ, "ispif");
+	if (!ispif->irq) {
+		pr_err("%s: no irq resource?\n", __func__);
+		rc = -ENODEV;
+		goto ispif_no_resource;
+	}
+	ispif->io = request_mem_region(ispif->mem->start,
+		resource_size(ispif->mem), pdev->name);
+	if (!ispif->io) {
+		pr_err("%s: no valid mem region\n", __func__);
+		rc = -EBUSY;
+		goto ispif_no_resource;
+	}
+	ispif->base = ioremap(ispif->mem->start,
+		resource_size(ispif->mem));
+	if (!ispif->base) {
+		rc = -ENOMEM;
+		goto ispif_no_mem;
+	}
+
+	ispif->pdev = pdev;
+	sd_info.sdev_type = ISPIF_DEV;
+	sd_info.sd_index = pdev->id;
+	sd_info.irq_num = ispif->irq->start;
+	msm_cam_register_subdev_node(&ispif->subdev, &sd_info);
+
+	media_entity_init(&ispif->subdev.entity, 0, NULL, 0);
+	ispif->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	ispif->subdev.entity.group_id = ISPIF_DEV;
+	ispif->subdev.entity.name = pdev->name;
+	ispif->subdev.entity.revision = ispif->subdev.devnode->num;
+	ispif->ispif_state = ISPIF_POWER_DOWN;
+	return 0;
+
+ispif_no_mem:
+	release_mem_region(ispif->mem->start,
+		resource_size(ispif->mem));
+ispif_no_resource:
+	mutex_destroy(&ispif->mutex);
+	kfree(ispif);
+	return rc;
+}
+
+static const struct of_device_id msm_ispif_dt_match[] = {
+	{.compatible = "qcom,ispif"},
+};
+
+MODULE_DEVICE_TABLE(of, msm_ispif_dt_match);
+
+static struct platform_driver ispif_driver = {
+	.probe = ispif_probe,
+	.driver = {
+		.name = MSM_ISPIF_DRV_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = msm_ispif_dt_match,
+	},
+};
+
+static int __init msm_ispif_init_module(void)
+{
+	return platform_driver_register(&ispif_driver);
+}
+
+static void __exit msm_ispif_exit_module(void)
+{
+	platform_driver_unregister(&ispif_driver);
+}
+
+module_init(msm_ispif_init_module);
+module_exit(msm_ispif_exit_module);
+MODULE_DESCRIPTION("MSM ISP Interface driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/csi/msm_ispif.h b/drivers/media/platform/msm/camera_v1/csi/msm_ispif.h
new file mode 100644
index 0000000..cb7bd80
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/csi/msm_ispif.h
@@ -0,0 +1,62 @@
+/* Copyright (c) 2011-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.
+ */
+
+#ifndef MSM_ISPIF_H
+#define MSM_ISPIF_H
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <media/v4l2-subdev.h>
+
+struct ispif_irq_status {
+	uint32_t ispifIrqStatus0;
+	uint32_t ispifIrqStatus1;
+	uint32_t ispifIrqStatus2;
+};
+
+enum msm_ispif_state_t {
+	ISPIF_POWER_UP,
+	ISPIF_POWER_DOWN,
+};
+
+struct ispif_device {
+	struct platform_device *pdev;
+	struct v4l2_subdev subdev;
+	struct resource *mem;
+	struct resource *irq;
+	struct resource *io;
+	void __iomem *base;
+	struct mutex mutex;
+	uint8_t start_ack_pending;
+	struct completion reset_complete;
+	uint32_t csid_version;
+	struct clk *ispif_clk[5];
+	uint32_t pix_sof_count;
+	uint32_t rdi0_sof_count;
+	uint32_t rdi1_sof_count;
+	uint32_t rdi2_sof_count;
+	uint32_t global_intf_cmd_mask;
+	struct tasklet_struct ispif_tasklet;
+	enum msm_ispif_state_t ispif_state;
+};
+
+struct ispif_isr_queue_cmd {
+	struct list_head list;
+	uint32_t    ispifInterruptStatus0;
+	uint32_t    ispifInterruptStatus1;
+	uint32_t    ispifInterruptStatus2;
+};
+
+#define VIDIOC_MSM_ISPIF_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 18, struct ispif_cfg_data*)
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v1/eeprom/Makefile b/drivers/media/platform/msm/camera_v1/eeprom/Makefile
new file mode 100644
index 0000000..6474aee
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/eeprom/Makefile
@@ -0,0 +1,5 @@
+GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
+EXTRA_CFLAGS += -Idrivers/media/platform/msm/camera_v1/io
+obj-$(CONFIG_MSM_EEPROM) += msm_camera_eeprom.o
+obj-$(CONFIG_IMX074_EEPROM) += imx074_eeprom.o
+obj-$(CONFIG_IMX091_EEPROM) += imx091_eeprom.o
\ No newline at end of file
diff --git a/drivers/media/platform/msm/camera_v1/eeprom/imx074_eeprom.c b/drivers/media/platform/msm/camera_v1/eeprom/imx074_eeprom.c
new file mode 100644
index 0000000..eafa9a8
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/eeprom/imx074_eeprom.c
@@ -0,0 +1,113 @@
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include "msm_camera_eeprom.h"
+#include "msm_camera_i2c.h"
+
+DEFINE_MUTEX(imx074_eeprom_mutex);
+static struct msm_eeprom_ctrl_t imx074_eeprom_t;
+
+static const struct i2c_device_id imx074_eeprom_i2c_id[] = {
+	{"imx074_eeprom", (kernel_ulong_t)&imx074_eeprom_t},
+	{ }
+};
+
+static struct i2c_driver imx074_eeprom_i2c_driver = {
+	.id_table = imx074_eeprom_i2c_id,
+	.probe  = msm_eeprom_i2c_probe,
+	.remove = __exit_p(imx074_eeprom_i2c_remove),
+	.driver = {
+		.name = "imx074_eeprom",
+	},
+};
+
+static int __init imx074_eeprom_i2c_add_driver(void)
+{
+	int rc = 0;
+	rc = i2c_add_driver(imx074_eeprom_t.i2c_driver);
+	return rc;
+}
+
+static struct v4l2_subdev_core_ops imx074_eeprom_subdev_core_ops = {
+	.ioctl = msm_eeprom_subdev_ioctl,
+};
+
+static struct v4l2_subdev_ops imx074_eeprom_subdev_ops = {
+	.core = &imx074_eeprom_subdev_core_ops,
+};
+
+static uint8_t imx074_wbcalib_data[6];
+static struct msm_calib_wb imx074_wb_data;
+
+static struct msm_camera_eeprom_info_t imx074_calib_supp_info = {
+	{FALSE, 0, 0, 1},
+	{TRUE, 6, 0, 1024},
+	{FALSE, 0, 0, 1},
+	{FALSE, 0, 0, 1},
+	{FALSE, 0, 0, 1},
+};
+
+static struct msm_camera_eeprom_read_t imx074_eeprom_read_tbl[] = {
+	{0x10, &imx074_wbcalib_data[0], 6, 0},
+};
+
+
+static struct msm_camera_eeprom_data_t imx074_eeprom_data_tbl[] = {
+	{&imx074_wb_data, sizeof(struct msm_calib_wb)},
+};
+
+static void imx074_format_wbdata(void)
+{
+	imx074_wb_data.r_over_g = (uint16_t)(imx074_wbcalib_data[0] << 8) |
+		imx074_wbcalib_data[1];
+	imx074_wb_data.b_over_g = (uint16_t)(imx074_wbcalib_data[2] << 8) |
+		imx074_wbcalib_data[3];
+	imx074_wb_data.gr_over_gb = (uint16_t)(imx074_wbcalib_data[4] << 8) |
+		imx074_wbcalib_data[5];
+}
+
+void imx074_format_calibrationdata(void)
+{
+	imx074_format_wbdata();
+}
+static struct msm_eeprom_ctrl_t imx074_eeprom_t = {
+	.i2c_driver = &imx074_eeprom_i2c_driver,
+	.i2c_addr = 0xA4,
+	.eeprom_v4l2_subdev_ops = &imx074_eeprom_subdev_ops,
+
+	.i2c_client = {
+		.addr_type = MSM_CAMERA_I2C_BYTE_ADDR,
+	},
+
+	.eeprom_mutex = &imx074_eeprom_mutex,
+
+	.func_tbl = {
+		.eeprom_init = NULL,
+		.eeprom_release = NULL,
+		.eeprom_get_info = msm_camera_eeprom_get_info,
+		.eeprom_get_data = msm_camera_eeprom_get_data,
+		.eeprom_set_dev_addr = NULL,
+		.eeprom_format_data = imx074_format_calibrationdata,
+	},
+	.info = &imx074_calib_supp_info,
+	.info_size = sizeof(struct msm_camera_eeprom_info_t),
+	.read_tbl = imx074_eeprom_read_tbl,
+	.read_tbl_size = ARRAY_SIZE(imx074_eeprom_read_tbl),
+	.data_tbl = imx074_eeprom_data_tbl,
+	.data_tbl_size = ARRAY_SIZE(imx074_eeprom_data_tbl),
+};
+
+subsys_initcall(imx074_eeprom_i2c_add_driver);
+MODULE_DESCRIPTION("IMX074 EEPROM");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/eeprom/imx091_eeprom.c b/drivers/media/platform/msm/camera_v1/eeprom/imx091_eeprom.c
new file mode 100644
index 0000000..20624ac
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/eeprom/imx091_eeprom.c
@@ -0,0 +1,128 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include "msm_camera_eeprom.h"
+#include "msm_camera_i2c.h"
+
+DEFINE_MUTEX(imx091_eeprom_mutex);
+static struct msm_eeprom_ctrl_t imx091_eeprom_t;
+
+static const struct i2c_device_id imx091_eeprom_i2c_id[] = {
+	{"imx091_eeprom", (kernel_ulong_t)&imx091_eeprom_t},
+	{ }
+};
+
+static struct i2c_driver imx091_eeprom_i2c_driver = {
+	.id_table = imx091_eeprom_i2c_id,
+	.probe  = msm_eeprom_i2c_probe,
+	.remove = __exit_p(imx091_eeprom_i2c_remove),
+	.driver = {
+		.name = "imx091_eeprom",
+	},
+};
+
+static int __init imx091_eeprom_i2c_add_driver(void)
+{
+	int rc = 0;
+	rc = i2c_add_driver(imx091_eeprom_t.i2c_driver);
+	return rc;
+}
+
+static struct v4l2_subdev_core_ops imx091_eeprom_subdev_core_ops = {
+	.ioctl = msm_eeprom_subdev_ioctl,
+};
+
+static struct v4l2_subdev_ops imx091_eeprom_subdev_ops = {
+	.core = &imx091_eeprom_subdev_core_ops,
+};
+
+static uint8_t imx091_wbcalib_data[6];
+static uint8_t imx091_afcalib_data[6];
+static struct msm_calib_wb imx091_wb_data;
+static struct msm_calib_af imx091_af_data;
+
+static struct msm_camera_eeprom_info_t imx091_calib_supp_info = {
+	{TRUE, 6, 1, 1},
+	{TRUE, 6, 0, 32768},
+	{FALSE, 0, 0, 1},
+	{FALSE, 0, 0, 1},
+	{FALSE, 0, 0, 1},
+};
+
+static struct msm_camera_eeprom_read_t imx091_eeprom_read_tbl[] = {
+	{0x05, &imx091_wbcalib_data[0], 6, 0},
+	{0x0B, &imx091_afcalib_data[0], 6, 0},
+};
+
+
+static struct msm_camera_eeprom_data_t imx091_eeprom_data_tbl[] = {
+	{&imx091_wb_data, sizeof(struct msm_calib_wb)},
+	{&imx091_af_data, sizeof(struct msm_calib_af)},
+};
+
+static void imx091_format_wbdata(void)
+{
+	imx091_wb_data.r_over_g = (uint16_t)(imx091_wbcalib_data[1] << 8) |
+		(imx091_wbcalib_data[0] - 0x32);
+	imx091_wb_data.b_over_g = (uint16_t)(imx091_wbcalib_data[3] << 8) |
+		(imx091_wbcalib_data[2] - 0x32);
+	imx091_wb_data.gr_over_gb = (uint16_t)(imx091_wbcalib_data[5] << 8) |
+		(imx091_wbcalib_data[4] - 0x32);
+}
+
+static void imx091_format_afdata(void)
+{
+	imx091_af_data.inf_dac = (uint16_t)(imx091_afcalib_data[1] << 8) |
+		imx091_afcalib_data[0];
+	imx091_af_data.macro_dac = (uint16_t)(imx091_afcalib_data[3] << 8) |
+		imx091_afcalib_data[2];
+	imx091_af_data.start_dac = (uint16_t)(imx091_afcalib_data[5] << 8) |
+		imx091_afcalib_data[4];
+}
+
+void imx091_format_calibrationdata(void)
+{
+	imx091_format_wbdata();
+	imx091_format_afdata();
+}
+static struct msm_eeprom_ctrl_t imx091_eeprom_t = {
+	.i2c_driver = &imx091_eeprom_i2c_driver,
+	.i2c_addr = 0xA1,
+	.eeprom_v4l2_subdev_ops = &imx091_eeprom_subdev_ops,
+
+	.i2c_client = {
+		.addr_type = MSM_CAMERA_I2C_BYTE_ADDR,
+	},
+
+	.eeprom_mutex = &imx091_eeprom_mutex,
+
+	.func_tbl = {
+		.eeprom_init = NULL,
+		.eeprom_release = NULL,
+		.eeprom_get_info = msm_camera_eeprom_get_info,
+		.eeprom_get_data = msm_camera_eeprom_get_data,
+		.eeprom_set_dev_addr = NULL,
+		.eeprom_format_data = imx091_format_calibrationdata,
+	},
+	.info = &imx091_calib_supp_info,
+	.info_size = sizeof(struct msm_camera_eeprom_info_t),
+	.read_tbl = imx091_eeprom_read_tbl,
+	.read_tbl_size = ARRAY_SIZE(imx091_eeprom_read_tbl),
+	.data_tbl = imx091_eeprom_data_tbl,
+	.data_tbl_size = ARRAY_SIZE(imx091_eeprom_data_tbl),
+};
+
+subsys_initcall(imx091_eeprom_i2c_add_driver);
+MODULE_DESCRIPTION("imx091 EEPROM");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/eeprom/msm_camera_eeprom.c b/drivers/media/platform/msm/camera_v1/eeprom/msm_camera_eeprom.c
new file mode 100644
index 0000000..a1b809f
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/eeprom/msm_camera_eeprom.c
@@ -0,0 +1,196 @@
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include "msm_camera_eeprom.h"
+
+int32_t msm_camera_eeprom_read(struct msm_eeprom_ctrl_t *ectrl,
+	uint32_t reg_addr, void *data, uint32_t num_byte,
+	uint16_t convert_endian)
+{
+	int rc = 0;
+	if (ectrl->func_tbl.eeprom_set_dev_addr != NULL)
+		ectrl->func_tbl.eeprom_set_dev_addr(ectrl, &reg_addr);
+
+	if (!convert_endian) {
+		rc = msm_camera_i2c_read_seq(
+			&ectrl->i2c_client, reg_addr, data, num_byte);
+	} else {
+		unsigned char buf[num_byte];
+		uint8_t *data_ptr = (uint8_t *) data;
+		int i;
+		rc = msm_camera_i2c_read_seq(
+			&ectrl->i2c_client, reg_addr, buf, num_byte);
+		for (i = 0; i < num_byte; i += 2) {
+			data_ptr[i] = buf[i+1];
+			data_ptr[i+1] = buf[i];
+		}
+	}
+	return rc;
+}
+
+int32_t msm_camera_eeprom_read_tbl(struct msm_eeprom_ctrl_t *ectrl,
+	struct msm_camera_eeprom_read_t *read_tbl, uint16_t tbl_size)
+{
+	int i, rc = 0;
+	CDBG("%s: open\n", __func__);
+	if (read_tbl == NULL)
+		return rc;
+
+	for (i = 0; i < tbl_size; i++) {
+		rc = msm_camera_eeprom_read
+			(ectrl, read_tbl[i].reg_addr,
+			read_tbl[i].dest_ptr, read_tbl[i].num_byte,
+			read_tbl[i].convert_endian);
+		if (rc < 0) {
+			pr_err("%s: read failed\n", __func__);
+			return rc;
+		}
+	}
+	CDBG("%s: done\n", __func__);
+	return rc;
+}
+
+int32_t msm_camera_eeprom_get_info(struct msm_eeprom_ctrl_t *ectrl,
+	struct msm_camera_eeprom_info_t *einfo)
+{
+	int rc = 0;
+	CDBG("%s: open\n", __func__);
+	memcpy(einfo, ectrl->info, ectrl->info_size);
+	CDBG("%s: done =%d\n", __func__, rc);
+	return rc;
+}
+
+int32_t msm_camera_eeprom_get_data(struct msm_eeprom_ctrl_t *ectrl,
+	struct msm_eeprom_data_t *edata)
+{
+	int rc = 0;
+	if (edata->index >= ectrl->data_tbl_size)
+		return -EFAULT;
+	if (copy_to_user(edata->eeprom_data,
+		ectrl->data_tbl[edata->index].data,
+		ectrl->data_tbl[edata->index].size))
+		rc = -EFAULT;
+	return rc;
+}
+
+int32_t msm_eeprom_config(struct msm_eeprom_ctrl_t *e_ctrl,
+	void __user *argp)
+{
+	struct msm_eeprom_cfg_data cdata;
+	int32_t rc = 0;
+	if (copy_from_user(&cdata,
+		(void *)argp,
+		sizeof(struct msm_eeprom_cfg_data)))
+		return -EFAULT;
+	mutex_lock(e_ctrl->eeprom_mutex);
+
+	switch (cdata.cfgtype) {
+	case CFG_GET_EEPROM_INFO:
+		if (e_ctrl->func_tbl.eeprom_get_info == NULL) {
+			rc = -EFAULT;
+			break;
+		}
+		rc = e_ctrl->func_tbl.eeprom_get_info(e_ctrl,
+			&cdata.cfg.get_info);
+		cdata.is_eeprom_supported = 1;
+		if (copy_to_user((void *)argp,
+			&cdata,
+			sizeof(struct msm_eeprom_cfg_data)))
+			rc = -EFAULT;
+		break;
+	case CFG_GET_EEPROM_DATA:
+		if (e_ctrl->func_tbl.eeprom_get_data == NULL) {
+			rc = -EFAULT;
+			break;
+		}
+		rc = e_ctrl->func_tbl.eeprom_get_data(e_ctrl,
+			&cdata.cfg.get_data);
+
+		if (copy_to_user((void *)argp,
+			&cdata,
+			sizeof(struct msm_eeprom_cfg_data)))
+			rc = -EFAULT;
+		break;
+	default:
+		break;
+	}
+	mutex_unlock(e_ctrl->eeprom_mutex);
+	return rc;
+}
+
+struct msm_eeprom_ctrl_t *get_ectrl(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct msm_eeprom_ctrl_t, sdev);
+}
+
+long msm_eeprom_subdev_ioctl(struct v4l2_subdev *sd,
+	unsigned int cmd, void *arg)
+{
+	struct msm_eeprom_ctrl_t *e_ctrl = get_ectrl(sd);
+	void __user *argp = (void __user *)arg;
+	switch (cmd) {
+	case VIDIOC_MSM_EEPROM_CFG:
+		return msm_eeprom_config(e_ctrl, argp);
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
+int32_t msm_eeprom_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+	struct msm_eeprom_ctrl_t *e_ctrl_t = NULL;
+	CDBG("%s called\n", __func__);
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		pr_err("i2c_check_functionality failed\n");
+		goto probe_failure;
+	}
+
+	e_ctrl_t = (struct msm_eeprom_ctrl_t *)(id->driver_data);
+	e_ctrl_t->i2c_client.client = client;
+
+	if (e_ctrl_t->i2c_addr != 0)
+		e_ctrl_t->i2c_client.client->addr = e_ctrl_t->i2c_addr;
+
+	CDBG("%s client = %x\n", __func__, (unsigned int) client);
+
+	/* Assign name for sub device */
+	snprintf(e_ctrl_t->sdev.name, sizeof(e_ctrl_t->sdev.name),
+		"%s", e_ctrl_t->i2c_driver->driver.name);
+
+	if (e_ctrl_t->func_tbl.eeprom_init != NULL) {
+		rc = e_ctrl_t->func_tbl.eeprom_init(e_ctrl_t,
+			e_ctrl_t->i2c_client.client->adapter);
+	}
+	msm_camera_eeprom_read_tbl(e_ctrl_t,
+		e_ctrl_t->read_tbl,
+		e_ctrl_t->read_tbl_size);
+
+	if (e_ctrl_t->func_tbl.eeprom_format_data != NULL)
+		e_ctrl_t->func_tbl.eeprom_format_data();
+
+	if (e_ctrl_t->func_tbl.eeprom_release != NULL)
+		rc = e_ctrl_t->func_tbl.eeprom_release(e_ctrl_t);
+
+
+	/* Initialize sub device */
+	v4l2_i2c_subdev_init(&e_ctrl_t->sdev,
+		e_ctrl_t->i2c_client.client,
+		e_ctrl_t->eeprom_v4l2_subdev_ops);
+	CDBG("%s success resut=%d\n", __func__, rc);
+	return rc;
+
+probe_failure:
+	pr_err("%s failed! rc = %d\n", __func__, rc);
+	return rc;
+}
diff --git a/drivers/media/platform/msm/camera_v1/eeprom/msm_camera_eeprom.h b/drivers/media/platform/msm/camera_v1/eeprom/msm_camera_eeprom.h
new file mode 100644
index 0000000..05b4533
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/eeprom/msm_camera_eeprom.h
@@ -0,0 +1,82 @@
+/* Copyright (c) 2011-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.
+ */
+#ifndef MSM_CAMERA_EEPROM_H
+#define MSM_CAMERA_EEPROM_H
+
+#include <linux/delay.h>
+#include <mach/camera.h>
+#include <media/v4l2-subdev.h>
+#include "msm_camera_i2c.h"
+
+#define TRUE  1
+#define FALSE 0
+
+struct msm_eeprom_ctrl_t;
+
+struct msm_camera_eeprom_fn_t {
+	int32_t (*eeprom_init)
+		(struct msm_eeprom_ctrl_t *ectrl,
+		struct i2c_adapter *adapter);
+	int32_t (*eeprom_release)
+		(struct msm_eeprom_ctrl_t *ectrl);
+	int32_t (*eeprom_get_info)
+		(struct msm_eeprom_ctrl_t *ectrl,
+		 struct msm_camera_eeprom_info_t *einfo);
+	int32_t (*eeprom_get_data)
+		(struct msm_eeprom_ctrl_t *ectrl,
+		 struct msm_eeprom_data_t *edata);
+	void (*eeprom_set_dev_addr)
+		(struct msm_eeprom_ctrl_t*, uint32_t*);
+	void (*eeprom_format_data)
+		(void);
+};
+
+struct msm_camera_eeprom_read_t {
+	uint32_t reg_addr;
+	void *dest_ptr;
+	uint32_t num_byte;
+	uint16_t convert_endian;
+};
+
+struct msm_camera_eeprom_data_t {
+	void *data;
+	uint16_t size;
+};
+
+struct msm_eeprom_ctrl_t {
+	struct msm_camera_i2c_client i2c_client;
+	uint16_t i2c_addr;
+	struct i2c_driver *i2c_driver;
+	struct mutex *eeprom_mutex;
+	struct v4l2_subdev sdev;
+	struct v4l2_subdev_ops *eeprom_v4l2_subdev_ops;
+	struct msm_camera_eeprom_fn_t func_tbl;
+	struct msm_camera_eeprom_info_t *info;
+	uint16_t info_size;
+	struct msm_camera_eeprom_read_t *read_tbl;
+	uint16_t read_tbl_size;
+	struct msm_camera_eeprom_data_t *data_tbl;
+	uint16_t data_tbl_size;
+};
+
+int32_t msm_camera_eeprom_get_data(struct msm_eeprom_ctrl_t *ectrl,
+	struct msm_eeprom_data_t *edata);
+int32_t msm_camera_eeprom_get_info(struct msm_eeprom_ctrl_t *ectrl,
+	struct msm_camera_eeprom_info_t *einfo);
+int32_t msm_eeprom_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id);
+long msm_eeprom_subdev_ioctl(struct v4l2_subdev *sd,
+	unsigned int cmd, void *arg);
+
+#define VIDIOC_MSM_EEPROM_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 12, void __user *)
+#endif
diff --git a/drivers/media/platform/msm/camera_v1/flash/Makefile b/drivers/media/platform/msm/camera_v1/flash/Makefile
new file mode 100644
index 0000000..ad1d452
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/flash/Makefile
@@ -0,0 +1,10 @@
+GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
+ccflags-y += -Idrivers/media/platform/msm/camera_v1
+ccflags-y += -Idrivers/media/platform/msm/camera_v1/io
+obj-$(CONFIG_MSM_CAMERA_FLASH) += msm_flash.o
+obj-$(CONFIG_MSM_CAMERA_FLASH_SC628A) += sc628a.o
+obj-$(CONFIG_MSM_CAMERA_FLASH_TPS61310) += tps61310.o
+obj-$(CONFIG_MSM_CAMERA_FLASH_PMIC_FLASH) += pmic8058_flash.o
+obj-$(CONFIG_MSM_CAMERA_FLASH_SGM3141) += sgm3141.o
+obj-$(CONFIG_MSM_CAMERA_FLASH_PMIC8058_PWM) += pmic8058_pwm.o
+obj-$(CONFIG_MSM_CAMERA_LED_TRIGGER_FLASH) += led_trigger_flash.o
diff --git a/drivers/media/video/msm/flash/led_trigger_flash.c b/drivers/media/platform/msm/camera_v1/flash/led_trigger_flash.c
similarity index 100%
rename from drivers/media/video/msm/flash/led_trigger_flash.c
rename to drivers/media/platform/msm/camera_v1/flash/led_trigger_flash.c
diff --git a/drivers/media/video/msm/flash/msm_flash.c b/drivers/media/platform/msm/camera_v1/flash/msm_flash.c
similarity index 100%
rename from drivers/media/video/msm/flash/msm_flash.c
rename to drivers/media/platform/msm/camera_v1/flash/msm_flash.c
diff --git a/drivers/media/video/msm/flash/msm_flash.h b/drivers/media/platform/msm/camera_v1/flash/msm_flash.h
similarity index 100%
rename from drivers/media/video/msm/flash/msm_flash.h
rename to drivers/media/platform/msm/camera_v1/flash/msm_flash.h
diff --git a/drivers/media/video/msm/flash/pmic8058_flash.c b/drivers/media/platform/msm/camera_v1/flash/pmic8058_flash.c
similarity index 100%
rename from drivers/media/video/msm/flash/pmic8058_flash.c
rename to drivers/media/platform/msm/camera_v1/flash/pmic8058_flash.c
diff --git a/drivers/media/video/msm/flash/pmic8058_pwm.c b/drivers/media/platform/msm/camera_v1/flash/pmic8058_pwm.c
similarity index 100%
rename from drivers/media/video/msm/flash/pmic8058_pwm.c
rename to drivers/media/platform/msm/camera_v1/flash/pmic8058_pwm.c
diff --git a/drivers/media/video/msm/flash/sc628a.c b/drivers/media/platform/msm/camera_v1/flash/sc628a.c
similarity index 100%
rename from drivers/media/video/msm/flash/sc628a.c
rename to drivers/media/platform/msm/camera_v1/flash/sc628a.c
diff --git a/drivers/media/video/msm/flash/sgm3141.c b/drivers/media/platform/msm/camera_v1/flash/sgm3141.c
similarity index 100%
rename from drivers/media/video/msm/flash/sgm3141.c
rename to drivers/media/platform/msm/camera_v1/flash/sgm3141.c
diff --git a/drivers/media/video/msm/flash/tps61310.c b/drivers/media/platform/msm/camera_v1/flash/tps61310.c
similarity index 100%
rename from drivers/media/video/msm/flash/tps61310.c
rename to drivers/media/platform/msm/camera_v1/flash/tps61310.c
diff --git a/drivers/media/platform/msm/camera_v1/gemini/Makefile b/drivers/media/platform/msm/camera_v1/gemini/Makefile
new file mode 100644
index 0000000..6d4166c
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/gemini/Makefile
@@ -0,0 +1,3 @@
+GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
+EXTRA_CFLAGS += -Idrivers/media/platform/msm/camera_v1
+obj-$(CONFIG_MSM_GEMINI) += msm_gemini_dev.o msm_gemini_sync.o msm_gemini_core.o msm_gemini_hw.o msm_gemini_platform.o
diff --git a/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_common.h b/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_common.h
new file mode 100644
index 0000000..95223d80
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_common.h
@@ -0,0 +1,39 @@
+/* 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.
+ */
+
+#ifndef MSM_GEMINI_COMMON_H
+#define MSM_GEMINI_COMMON_H
+
+#define MSM_GEMINI_DEBUG
+#ifdef MSM_GEMINI_DEBUG
+#define GMN_DBG(fmt, args...) pr_debug(fmt, ##args)
+#else
+#define GMN_DBG(fmt, args...) do { } while (0)
+#endif
+
+#define GMN_PR_ERR   pr_err
+
+enum GEMINI_MODE {
+	GEMINI_MODE_DISABLE,
+	GEMINI_MODE_OFFLINE,
+	GEMINI_MODE_REALTIME,
+	GEMINI_MODE_REALTIME_ROTATION
+};
+
+enum GEMINI_ROTATION {
+	GEMINI_ROTATION_0,
+	GEMINI_ROTATION_90,
+	GEMINI_ROTATION_180,
+	GEMINI_ROTATION_270
+};
+
+#endif /* MSM_GEMINI_COMMON_H */
diff --git a/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_core.c b/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_core.c
new file mode 100644
index 0000000..84f7307
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_core.c
@@ -0,0 +1,250 @@
+/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include "msm_gemini_hw.h"
+#include "msm_gemini_core.h"
+#include "msm_gemini_platform.h"
+#include "msm_gemini_common.h"
+
+static struct msm_gemini_hw_pingpong fe_pingpong_buf;
+static struct msm_gemini_hw_pingpong we_pingpong_buf;
+static int we_pingpong_index;
+static int reset_done_ack;
+static spinlock_t reset_lock;
+static wait_queue_head_t reset_wait;
+
+int msm_gemini_core_reset(uint8_t op_mode, void *base, int size)
+{
+	unsigned long flags;
+	int rc = 0;
+	int tm = 500; /*500ms*/
+	memset(&fe_pingpong_buf, 0, sizeof(fe_pingpong_buf));
+	fe_pingpong_buf.is_fe = 1;
+	we_pingpong_index = 0;
+	memset(&we_pingpong_buf, 0, sizeof(we_pingpong_buf));
+	spin_lock_irqsave(&reset_lock, flags);
+	reset_done_ack = 0;
+	msm_gemini_hw_reset(base, size);
+	spin_unlock_irqrestore(&reset_lock, flags);
+	rc = wait_event_interruptible_timeout(
+			reset_wait,
+			reset_done_ack,
+			msecs_to_jiffies(tm));
+
+	if (!reset_done_ack) {
+		GMN_DBG("%s: reset ACK failed %d", __func__, rc);
+		return -EBUSY;
+	}
+
+	GMN_DBG("%s: reset_done_ack rc %d", __func__, rc);
+	spin_lock_irqsave(&reset_lock, flags);
+	reset_done_ack = 0;
+	spin_unlock_irqrestore(&reset_lock, flags);
+
+	if (op_mode == MSM_GEMINI_MODE_REALTIME_ENCODE) {
+		/* Nothing needed for fe buffer cfg, config we only */
+		msm_gemini_hw_we_buffer_cfg(1);
+	} else {
+		/* Nothing needed for fe buffer cfg, config we only */
+		msm_gemini_hw_we_buffer_cfg(0);
+	}
+
+	/* @todo wait for reset done irq */
+
+	return 0;
+}
+
+void msm_gemini_core_release(int release_buf)
+{
+	int i = 0;
+	for (i = 0; i < 2; i++) {
+		if (we_pingpong_buf.buf_status[i] && release_buf)
+			msm_gemini_platform_p2v(we_pingpong_buf.buf[i].file,
+					&we_pingpong_buf.buf[i].handle);
+		we_pingpong_buf.buf_status[i] = 0;
+	}
+}
+
+void msm_gemini_core_init(void)
+{
+	init_waitqueue_head(&reset_wait);
+	spin_lock_init(&reset_lock);
+}
+
+int msm_gemini_core_fe_start(void)
+{
+	msm_gemini_hw_fe_start();
+	return 0;
+}
+
+/* fetch engine */
+int msm_gemini_core_fe_buf_update(struct msm_gemini_core_buf *buf)
+{
+	GMN_DBG("%s:%d] 0x%08x %d 0x%08x %d\n", __func__, __LINE__,
+		(int) buf->y_buffer_addr, buf->y_len,
+		(int) buf->cbcr_buffer_addr, buf->cbcr_len);
+	return msm_gemini_hw_pingpong_update(&fe_pingpong_buf, buf);
+}
+
+void *msm_gemini_core_fe_pingpong_irq(int gemini_irq_status, void *context)
+{
+	return msm_gemini_hw_pingpong_irq(&fe_pingpong_buf);
+}
+
+/* write engine */
+int msm_gemini_core_we_buf_update(struct msm_gemini_core_buf *buf)
+{
+	int rc;
+	GMN_DBG("%s:%d] 0x%08x 0x%08x %d\n", __func__, __LINE__,
+		(int) buf->y_buffer_addr, (int) buf->cbcr_buffer_addr,
+		buf->y_len);
+	we_pingpong_buf.buf_status[we_pingpong_index] = 0;
+	we_pingpong_index = (we_pingpong_index + 1)%2;
+	rc = msm_gemini_hw_pingpong_update(&we_pingpong_buf, buf);
+	return 0;
+}
+
+int msm_gemini_core_we_buf_reset(struct msm_gemini_hw_buf *buf)
+{
+	int i = 0;
+	for (i = 0; i < 2; i++) {
+		if (we_pingpong_buf.buf[i].y_buffer_addr
+					== buf->y_buffer_addr)
+			we_pingpong_buf.buf_status[i] = 0;
+	}
+	return 0;
+}
+
+void *msm_gemini_core_we_pingpong_irq(int gemini_irq_status, void *context)
+{
+	GMN_DBG("%s:%d]\n", __func__, __LINE__);
+
+	return msm_gemini_hw_pingpong_irq(&we_pingpong_buf);
+}
+
+void *msm_gemini_core_framedone_irq(int gemini_irq_status, void *context)
+{
+	struct msm_gemini_hw_buf *buf_p;
+
+	GMN_DBG("%s:%d]\n", __func__, __LINE__);
+
+	buf_p = msm_gemini_hw_pingpong_active_buffer(&we_pingpong_buf);
+	if (buf_p) {
+		buf_p->framedone_len = msm_gemini_hw_encode_output_size();
+		GMN_DBG("%s:%d] framedone_len %d\n", __func__, __LINE__,
+			buf_p->framedone_len);
+	}
+
+	return buf_p;
+}
+
+void *msm_gemini_core_reset_ack_irq(int gemini_irq_status, void *context)
+{
+	/* @todo return the status back to msm_gemini_core_reset */
+	GMN_DBG("%s:%d]\n", __func__, __LINE__);
+	return NULL;
+}
+
+void *msm_gemini_core_err_irq(int gemini_irq_status, void *context)
+{
+	GMN_PR_ERR("%s:%d]\n", __func__, gemini_irq_status);
+	return NULL;
+}
+
+static int (*msm_gemini_irq_handler) (int, void *, void *);
+
+irqreturn_t msm_gemini_core_irq(int irq_num, void *context)
+{
+	void *data = NULL;
+	unsigned long flags;
+	int gemini_irq_status;
+
+	GMN_DBG("%s:%d] irq_num = %d\n", __func__, __LINE__, irq_num);
+
+	spin_lock_irqsave(&reset_lock, flags);
+	reset_done_ack = 1;
+	spin_unlock_irqrestore(&reset_lock, flags);
+	gemini_irq_status = msm_gemini_hw_irq_get_status();
+
+	GMN_DBG("%s:%d] gemini_irq_status = %0x\n", __func__, __LINE__,
+		gemini_irq_status);
+
+	/*For reset and framedone IRQs, clear all bits*/
+	if (gemini_irq_status & 0x400) {
+		wake_up(&reset_wait);
+		msm_gemini_hw_irq_clear(HWIO_JPEG_IRQ_CLEAR_RMSK,
+			JPEG_IRQ_CLEAR_ALL);
+	} else if (gemini_irq_status & 0x1) {
+		msm_gemini_hw_irq_clear(HWIO_JPEG_IRQ_CLEAR_RMSK,
+			JPEG_IRQ_CLEAR_ALL);
+	} else {
+		msm_gemini_hw_irq_clear(HWIO_JPEG_IRQ_CLEAR_RMSK,
+			gemini_irq_status);
+	}
+
+	if (msm_gemini_hw_irq_is_frame_done(gemini_irq_status)) {
+		data = msm_gemini_core_framedone_irq(gemini_irq_status,
+			context);
+		if (msm_gemini_irq_handler)
+			msm_gemini_irq_handler(
+				MSM_GEMINI_HW_MASK_COMP_FRAMEDONE,
+				context, data);
+	}
+
+	if (msm_gemini_hw_irq_is_fe_pingpong(gemini_irq_status)) {
+		data = msm_gemini_core_fe_pingpong_irq(gemini_irq_status,
+			context);
+		if (msm_gemini_irq_handler)
+			msm_gemini_irq_handler(MSM_GEMINI_HW_MASK_COMP_FE,
+				context, data);
+	}
+
+	if (msm_gemini_hw_irq_is_we_pingpong(gemini_irq_status) &&
+	    !msm_gemini_hw_irq_is_frame_done(gemini_irq_status)) {
+		data = msm_gemini_core_we_pingpong_irq(gemini_irq_status,
+			context);
+		if (msm_gemini_irq_handler)
+			msm_gemini_irq_handler(MSM_GEMINI_HW_MASK_COMP_WE,
+				context, data);
+	}
+
+	if (msm_gemini_hw_irq_is_reset_ack(gemini_irq_status)) {
+		data = msm_gemini_core_reset_ack_irq(gemini_irq_status,
+			context);
+		if (msm_gemini_irq_handler)
+			msm_gemini_irq_handler(
+				MSM_GEMINI_HW_MASK_COMP_RESET_ACK,
+				context, data);
+	}
+
+	/* Unexpected/unintended HW interrupt */
+	if (msm_gemini_hw_irq_is_err(gemini_irq_status)) {
+		data = msm_gemini_core_err_irq(gemini_irq_status, context);
+		if (msm_gemini_irq_handler)
+			msm_gemini_irq_handler(MSM_GEMINI_HW_MASK_COMP_ERR,
+				context, data);
+	}
+
+	return IRQ_HANDLED;
+}
+
+void msm_gemini_core_irq_install(int (*irq_handler) (int, void *, void *))
+{
+	msm_gemini_irq_handler = irq_handler;
+}
+
+void msm_gemini_core_irq_remove(void)
+{
+	msm_gemini_irq_handler = NULL;
+}
diff --git a/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_core.h b/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_core.h
new file mode 100644
index 0000000..62dd473
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_core.h
@@ -0,0 +1,35 @@
+/* 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.
+ */
+
+#ifndef MSM_GEMINI_CORE_H
+#define MSM_GEMINI_CORE_H
+
+#include <linux/interrupt.h>
+#include "msm_gemini_hw.h"
+
+#define msm_gemini_core_buf msm_gemini_hw_buf
+
+irqreturn_t msm_gemini_core_irq(int irq_num, void *context);
+
+void msm_gemini_core_irq_install(int (*irq_handler) (int, void *, void *));
+void msm_gemini_core_irq_remove(void);
+
+int msm_gemini_core_fe_buf_update(struct msm_gemini_core_buf *buf);
+int msm_gemini_core_we_buf_update(struct msm_gemini_core_buf *buf);
+int msm_gemini_core_we_buf_reset(struct msm_gemini_hw_buf *buf);
+
+int msm_gemini_core_reset(uint8_t op_mode, void *base, int size);
+int msm_gemini_core_fe_start(void);
+
+void msm_gemini_core_release(int);
+void msm_gemini_core_init(void);
+#endif /* MSM_GEMINI_CORE_H */
diff --git a/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_dev.c b/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_dev.c
new file mode 100644
index 0000000..770a28f
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_dev.c
@@ -0,0 +1,266 @@
+/* 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.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <mach/board.h>
+
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/uaccess.h>
+#include <media/msm_gemini.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+
+#include "msm.h"
+#include "msm_gemini_sync.h"
+#include "msm_gemini_common.h"
+
+#define MSM_GEMINI_NAME "gemini"
+
+static int msm_gemini_open(struct inode *inode, struct file *filp)
+{
+	int rc;
+
+	struct msm_gemini_device *pgmn_dev = container_of(inode->i_cdev,
+		struct msm_gemini_device, cdev);
+	filp->private_data = pgmn_dev;
+
+	GMN_DBG("%s:%d]\n", __func__, __LINE__);
+
+	rc = __msm_gemini_open(pgmn_dev);
+
+	GMN_DBG(KERN_INFO "%s:%d] %s open_count = %d\n", __func__, __LINE__,
+		filp->f_path.dentry->d_name.name, pgmn_dev->open_count);
+
+	return rc;
+}
+
+static int msm_gemini_release(struct inode *inode, struct file *filp)
+{
+	int rc;
+
+	struct msm_gemini_device *pgmn_dev = filp->private_data;
+
+	GMN_DBG(KERN_INFO "%s:%d]\n", __func__, __LINE__);
+
+	rc = __msm_gemini_release(pgmn_dev);
+
+	GMN_DBG(KERN_INFO "%s:%d] %s open_count = %d\n", __func__, __LINE__,
+		filp->f_path.dentry->d_name.name, pgmn_dev->open_count);
+	return rc;
+}
+
+static long msm_gemini_ioctl(struct file *filp, unsigned int cmd,
+	unsigned long arg)
+{
+	int rc;
+	struct msm_gemini_device *pgmn_dev = filp->private_data;
+
+	GMN_DBG("%s:%d] cmd=%d pgmn_dev=0x%x arg=0x%x\n", __func__,
+		__LINE__, _IOC_NR(cmd), (uint32_t)pgmn_dev, (uint32_t)arg);
+
+	rc = __msm_gemini_ioctl(pgmn_dev, cmd, arg);
+
+	GMN_DBG("%s:%d]\n", __func__, __LINE__);
+	return rc;
+}
+
+static const struct file_operations msm_gemini_fops = {
+	.owner	  = THIS_MODULE,
+	.open	   = msm_gemini_open,
+	.release	= msm_gemini_release,
+	.unlocked_ioctl = msm_gemini_ioctl,
+};
+
+static struct class *msm_gemini_class;
+static dev_t msm_gemini_devno;
+struct msm_gemini_device *msm_gemini_device_p;
+
+int msm_gemini_subdev_init(struct v4l2_subdev *gemini_sd)
+{
+	int rc;
+	struct msm_gemini_device *pgmn_dev =
+		(struct msm_gemini_device *)gemini_sd->host_priv;
+
+	GMN_DBG("%s:%d: gemini_sd=0x%x pgmn_dev=0x%x\n",
+		__func__, __LINE__, (uint32_t)gemini_sd, (uint32_t)pgmn_dev);
+	rc = __msm_gemini_open(pgmn_dev);
+	GMN_DBG("%s:%d: rc=%d\n",
+		__func__, __LINE__, rc);
+	return rc;
+}
+
+static long msm_gemini_subdev_ioctl(struct v4l2_subdev *sd,
+	unsigned int cmd, void *arg)
+{
+	long rc;
+	struct msm_gemini_device *pgmn_dev =
+		(struct msm_gemini_device *)sd->host_priv;
+
+	GMN_DBG("%s: cmd=%d\n", __func__, cmd);
+
+	GMN_DBG("%s: pgmn_dev 0x%x", __func__, (uint32_t)pgmn_dev);
+
+	GMN_DBG("%s: Calling __msm_gemini_ioctl\n", __func__);
+
+	rc = __msm_gemini_ioctl(pgmn_dev, cmd, (unsigned long)arg);
+	pr_debug("%s: X\n", __func__);
+	return rc;
+}
+
+void msm_gemini_subdev_release(struct v4l2_subdev *gemini_sd)
+{
+	int rc;
+	struct msm_gemini_device *pgmn_dev =
+		(struct msm_gemini_device *)gemini_sd->host_priv;
+	GMN_DBG("%s:pgmn_dev=0x%x", __func__, (uint32_t)pgmn_dev);
+	rc = __msm_gemini_release(pgmn_dev);
+	GMN_DBG("%s:rc=%d", __func__, rc);
+}
+
+static const struct v4l2_subdev_core_ops msm_gemini_subdev_core_ops = {
+	.ioctl = msm_gemini_subdev_ioctl,
+};
+
+static const struct v4l2_subdev_ops msm_gemini_subdev_ops = {
+	.core = &msm_gemini_subdev_core_ops,
+};
+
+static int msm_gemini_init(struct platform_device *pdev)
+{
+	int rc = -1;
+	struct device *dev;
+
+	GMN_DBG("%s:\n", __func__);
+	msm_gemini_device_p = __msm_gemini_init(pdev);
+	if (msm_gemini_device_p == NULL) {
+		GMN_PR_ERR("%s: initialization failed\n", __func__);
+		goto fail;
+	}
+
+	v4l2_subdev_init(&msm_gemini_device_p->subdev, &msm_gemini_subdev_ops);
+	v4l2_set_subdev_hostdata(&msm_gemini_device_p->subdev,
+		msm_gemini_device_p);
+	pr_debug("%s: msm_gemini_device_p 0x%x", __func__,
+			(uint32_t)msm_gemini_device_p);
+	GMN_DBG("%s:gemini: platform_set_drvdata\n", __func__);
+	platform_set_drvdata(pdev, &msm_gemini_device_p->subdev);
+
+	rc = alloc_chrdev_region(&msm_gemini_devno, 0, 1, MSM_GEMINI_NAME);
+	if (rc < 0) {
+		GMN_PR_ERR("%s: failed to allocate chrdev\n", __func__);
+		goto fail_1;
+	}
+
+	if (!msm_gemini_class) {
+		msm_gemini_class = class_create(THIS_MODULE, MSM_GEMINI_NAME);
+		if (IS_ERR(msm_gemini_class)) {
+			rc = PTR_ERR(msm_gemini_class);
+			GMN_PR_ERR("%s: create device class failed\n",
+				__func__);
+			goto fail_2;
+		}
+	}
+
+	dev = device_create(msm_gemini_class, NULL,
+		MKDEV(MAJOR(msm_gemini_devno), MINOR(msm_gemini_devno)), NULL,
+		"%s%d", MSM_GEMINI_NAME, 0);
+
+	if (IS_ERR(dev)) {
+		GMN_PR_ERR("%s: error creating device\n", __func__);
+		rc = -ENODEV;
+		goto fail_3;
+	}
+
+	cdev_init(&msm_gemini_device_p->cdev, &msm_gemini_fops);
+	msm_gemini_device_p->cdev.owner = THIS_MODULE;
+	msm_gemini_device_p->cdev.ops   =
+		(const struct file_operations *) &msm_gemini_fops;
+	rc = cdev_add(&msm_gemini_device_p->cdev, msm_gemini_devno, 1);
+	if (rc < 0) {
+		GMN_PR_ERR("%s: error adding cdev\n", __func__);
+		rc = -ENODEV;
+		goto fail_4;
+	}
+
+	GMN_DBG("%s %s: success\n", __func__, MSM_GEMINI_NAME);
+
+	return rc;
+
+fail_4:
+	device_destroy(msm_gemini_class, msm_gemini_devno);
+
+fail_3:
+	class_destroy(msm_gemini_class);
+
+fail_2:
+	unregister_chrdev_region(msm_gemini_devno, 1);
+
+fail_1:
+	__msm_gemini_exit(msm_gemini_device_p);
+
+fail:
+	return rc;
+}
+
+static void msm_gemini_exit(void)
+{
+	cdev_del(&msm_gemini_device_p->cdev);
+	device_destroy(msm_gemini_class, msm_gemini_devno);
+	class_destroy(msm_gemini_class);
+	unregister_chrdev_region(msm_gemini_devno, 1);
+
+	__msm_gemini_exit(msm_gemini_device_p);
+}
+
+static int __msm_gemini_probe(struct platform_device *pdev)
+{
+	return msm_gemini_init(pdev);
+}
+
+static int __msm_gemini_remove(struct platform_device *pdev)
+{
+	msm_gemini_exit();
+	return 0;
+}
+
+static struct platform_driver msm_gemini_driver = {
+	.probe  = __msm_gemini_probe,
+	.remove = __msm_gemini_remove,
+	.driver = {
+		.name = MSM_GEMINI_DRV_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init msm_gemini_driver_init(void)
+{
+	int rc;
+	rc = platform_driver_register(&msm_gemini_driver);
+	return rc;
+}
+
+static void __exit msm_gemini_driver_exit(void)
+{
+	platform_driver_unregister(&msm_gemini_driver);
+}
+
+MODULE_DESCRIPTION("msm gemini jpeg driver");
+MODULE_VERSION("msm gemini 0.1");
+
+module_init(msm_gemini_driver_init);
+module_exit(msm_gemini_driver_exit);
+
diff --git a/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_hw.c b/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_hw.c
new file mode 100644
index 0000000..0cbb101
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_hw.c
@@ -0,0 +1,525 @@
+/* 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/delay.h>
+#include "msm_gemini_hw.h"
+#include "msm_gemini_common.h"
+
+#include <linux/io.h>
+
+static void *gemini_region_base;
+static uint32_t gemini_region_size;
+
+int msm_gemini_hw_pingpong_update(struct msm_gemini_hw_pingpong *pingpong_hw,
+	struct msm_gemini_hw_buf *buf)
+{
+	int buf_free_index = -1;
+
+	if (!pingpong_hw->buf_status[0]) {
+		buf_free_index = 0;
+	} else if (!pingpong_hw->buf_status[1]) {
+		buf_free_index = 1;
+	} else {
+		GMN_PR_ERR("%s:%d: pingpong buffer busy\n", __func__, __LINE__);
+		return -1;
+	}
+
+	pingpong_hw->buf[buf_free_index] = *buf;
+	pingpong_hw->buf_status[buf_free_index] = 1;
+
+	if (pingpong_hw->is_fe) {
+		/* it is fe */
+		msm_gemini_hw_fe_buffer_update(
+			&pingpong_hw->buf[buf_free_index], buf_free_index);
+	} else {
+		/* it is we */
+		msm_gemini_hw_we_buffer_update(
+			&pingpong_hw->buf[buf_free_index], buf_free_index);
+	}
+	return 0;
+}
+
+void *msm_gemini_hw_pingpong_irq(struct msm_gemini_hw_pingpong *pingpong_hw)
+{
+	struct msm_gemini_hw_buf *buf_p = NULL;
+
+	if (pingpong_hw->buf_status[pingpong_hw->buf_active_index]) {
+		buf_p = &pingpong_hw->buf[pingpong_hw->buf_active_index];
+		pingpong_hw->buf_status[pingpong_hw->buf_active_index] = 0;
+	}
+
+	pingpong_hw->buf_active_index = !pingpong_hw->buf_active_index;
+
+	return (void *) buf_p;
+}
+
+void *msm_gemini_hw_pingpong_active_buffer(
+	struct msm_gemini_hw_pingpong *pingpong_hw)
+{
+	struct msm_gemini_hw_buf *buf_p = NULL;
+
+	if (pingpong_hw->buf_status[pingpong_hw->buf_active_index])
+		buf_p = &pingpong_hw->buf[pingpong_hw->buf_active_index];
+
+	return (void *) buf_p;
+}
+
+struct msm_gemini_hw_cmd hw_cmd_irq_get_status[] = {
+	/* type, repeat n times, offset, mask, data or pdata */
+	{MSM_GEMINI_HW_CMD_TYPE_READ, 1, HWIO_JPEG_IRQ_STATUS_ADDR,
+		HWIO_JPEG_IRQ_STATUS_RMSK, {0} },
+};
+
+int msm_gemini_hw_irq_get_status(void)
+{
+	uint32_t n_irq_status = 0;
+	rmb();
+	n_irq_status = msm_gemini_hw_read(&hw_cmd_irq_get_status[0]);
+	rmb();
+	return n_irq_status;
+}
+
+struct msm_gemini_hw_cmd hw_cmd_encode_output_size[] = {
+	/* type, repeat n times, offset, mask, data or pdata */
+	{MSM_GEMINI_HW_CMD_TYPE_READ, 1,
+		HWIO_JPEG_STATUS_ENCODE_OUTPUT_SIZE_ADDR,
+		HWIO_JPEG_STATUS_ENCODE_OUTPUT_SIZE_RMSK, {0} },
+};
+
+long msm_gemini_hw_encode_output_size(void)
+{
+	uint32_t encode_output_size = 0;
+
+	encode_output_size = msm_gemini_hw_read(&hw_cmd_encode_output_size[0]);
+
+	return encode_output_size;
+}
+
+struct msm_gemini_hw_cmd hw_cmd_irq_clear[] = {
+	/* type, repeat n times, offset, mask, data or pdata */
+	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_IRQ_CLEAR_ADDR,
+		HWIO_JPEG_IRQ_CLEAR_RMSK, {JPEG_IRQ_CLEAR_ALL} },
+};
+
+void msm_gemini_hw_irq_clear(uint32_t mask, uint32_t data)
+{
+	GMN_DBG("%s:%d] mask %0x data %0x", __func__, __LINE__, mask, data);
+	hw_cmd_irq_clear[0].mask = mask;
+	hw_cmd_irq_clear[0].data = data;
+	msm_gemini_hw_write(&hw_cmd_irq_clear[0]);
+}
+
+struct msm_gemini_hw_cmd hw_cmd_fe_ping_update[] = {
+	/* type, repeat n times, offset, mask, data or pdata */
+	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_FE_BUFFER_CFG_ADDR,
+		HWIO_JPEG_FE_BUFFER_CFG_RMSK, {0} },
+	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_FE_Y_PING_ADDR_ADDR,
+		HWIO_JPEG_FE_Y_PING_ADDR_RMSK, {0} },
+	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_FE_CBCR_PING_ADDR_ADDR,
+		HWIO_JPEG_FE_CBCR_PING_ADDR_RMSK, {0} },
+	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_FE_CMD_ADDR,
+		HWIO_JPEG_FE_CMD_RMSK, {JPEG_FE_CMD_BUFFERRELOAD} },
+};
+
+struct msm_gemini_hw_cmd hw_cmd_fe_pong_update[] = {
+	/* type, repeat n times, offset, mask, data or pdata */
+	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_FE_BUFFER_CFG_ADDR,
+		HWIO_JPEG_FE_BUFFER_CFG_RMSK, {0} },
+	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_FE_Y_PONG_ADDR_ADDR,
+		HWIO_JPEG_FE_Y_PONG_ADDR_RMSK, {0} },
+	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_FE_CBCR_PONG_ADDR_ADDR,
+		HWIO_JPEG_FE_CBCR_PONG_ADDR_RMSK, {0} },
+	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_FE_CMD_ADDR,
+		HWIO_JPEG_FE_CMD_RMSK, {JPEG_FE_CMD_BUFFERRELOAD} },
+};
+
+void msm_gemini_hw_fe_buffer_update(struct msm_gemini_hw_buf *p_input,
+	uint8_t pingpong_index)
+{
+	uint32_t n_reg_val = 0;
+
+	struct msm_gemini_hw_cmd *hw_cmd_p;
+
+	if (pingpong_index == 0) {
+		hw_cmd_p = &hw_cmd_fe_ping_update[0];
+		n_reg_val = ((((p_input->num_of_mcu_rows - 1) <<
+			HWIO_JPEG_FE_BUFFER_CFG_CBCR_MCU_ROWS_SHFT) &
+			HWIO_JPEG_FE_BUFFER_CFG_CBCR_MCU_ROWS_BMSK) |
+			(((p_input->num_of_mcu_rows - 1) <<
+			HWIO_JPEG_FE_BUFFER_CFG_Y_MCU_ROWS_SHFT) &
+			HWIO_JPEG_FE_BUFFER_CFG_Y_MCU_ROWS_BMSK));
+		hw_cmd_p->data = n_reg_val;
+		msm_gemini_hw_write(hw_cmd_p++);
+
+		n_reg_val = ((p_input->y_buffer_addr <<
+			HWIO_JPEG_FE_Y_PING_ADDR_FE_Y_PING_START_ADDR_SHFT) &
+			HWIO_JPEG_FE_Y_PING_ADDR_FE_Y_PING_START_ADDR_BMSK);
+		hw_cmd_p->data = n_reg_val;
+		msm_gemini_hw_write(hw_cmd_p++);
+
+		n_reg_val = ((p_input->cbcr_buffer_addr<<
+		HWIO_JPEG_FE_CBCR_PING_ADDR_FE_CBCR_PING_START_ADDR_SHFT) &
+		HWIO_JPEG_FE_CBCR_PING_ADDR_FE_CBCR_PING_START_ADDR_BMSK);
+		hw_cmd_p->data = n_reg_val;
+		msm_gemini_hw_write(hw_cmd_p++);
+
+		msm_gemini_hw_write(hw_cmd_p);
+	} else if (pingpong_index == 1) {
+		hw_cmd_p = &hw_cmd_fe_pong_update[0];
+		n_reg_val = ((((p_input->num_of_mcu_rows - 1) <<
+			HWIO_JPEG_FE_BUFFER_CFG_CBCR_MCU_ROWS_SHFT) &
+			HWIO_JPEG_FE_BUFFER_CFG_CBCR_MCU_ROWS_BMSK) |
+			(((p_input->num_of_mcu_rows - 1) <<
+			HWIO_JPEG_FE_BUFFER_CFG_Y_MCU_ROWS_SHFT) &
+			HWIO_JPEG_FE_BUFFER_CFG_Y_MCU_ROWS_BMSK));
+		hw_cmd_p->data = n_reg_val;
+		msm_gemini_hw_write(hw_cmd_p++);
+
+		n_reg_val = ((p_input->y_buffer_addr <<
+			HWIO_JPEG_FE_Y_PONG_ADDR_FE_Y_PONG_START_ADDR_SHFT) &
+			HWIO_JPEG_FE_Y_PONG_ADDR_FE_Y_PONG_START_ADDR_BMSK);
+		hw_cmd_p->data = n_reg_val;
+		msm_gemini_hw_write(hw_cmd_p++);
+
+		n_reg_val = ((p_input->cbcr_buffer_addr<<
+		HWIO_JPEG_FE_CBCR_PONG_ADDR_FE_CBCR_PONG_START_ADDR_SHFT) &
+		HWIO_JPEG_FE_CBCR_PONG_ADDR_FE_CBCR_PONG_START_ADDR_BMSK);
+		hw_cmd_p->data = n_reg_val;
+		msm_gemini_hw_write(hw_cmd_p++);
+
+		msm_gemini_hw_write(hw_cmd_p);
+	} else {
+		/* shall not get to here */
+	}
+
+	return;
+}
+
+struct msm_gemini_hw_cmd hw_cmd_fe_start[] = {
+	/* type, repeat n times, offset, mask, data or pdata */
+	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_FE_CMD_ADDR,
+		HWIO_JPEG_FE_CMD_RMSK, {JPEG_OFFLINE_CMD_START} },
+};
+
+void msm_gemini_hw_fe_start(void)
+{
+	msm_gemini_hw_write(&hw_cmd_fe_start[0]);
+
+	return;
+}
+
+struct msm_gemini_hw_cmd hw_cmd_we_buffer_cfg[] = {
+	/* type, repeat n times, offset, mask, data or pdata */
+	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_WE_Y_THRESHOLD_ADDR,
+		HWIO_JPEG_WE_Y_THRESHOLD_RMSK, {0} },
+	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_WE_Y_UB_CFG_ADDR,
+		HWIO_JPEG_WE_Y_UB_CFG_RMSK, {JPEG_WE_YUB_ENCODE} },
+	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_WE_CBCR_THRESHOLD_ADDR,
+		HWIO_JPEG_WE_CBCR_THRESHOLD_RMSK, {0} },
+};
+
+/* first dimension is WE_ASSERT_STALL_TH and WE_DEASSERT_STALL_TH
+   second dimension is for offline and real-time settings
+ */
+static const uint32_t GEMINI_WE_Y_THRESHOLD[2][2] = {
+	{ 0x00000190, 0x000001ff },
+	{ 0x0000016a, 0x000001ff }
+};
+
+/* first dimension is WE_ASSERT_STALL_TH and WE_DEASSERT_STALL_TH
+   second dimension is for offline and real-time settings
+ */
+static const uint32_t GEMINI_WE_CBCR_THRESHOLD[2][2] = {
+	{ 0x00000190, 0x000001ff },
+	{ 0x0000016a, 0x000001ff }
+};
+
+void msm_gemini_hw_we_buffer_cfg(uint8_t is_realtime)
+{
+	uint32_t              n_reg_val = 0;
+
+	struct msm_gemini_hw_cmd *hw_cmd_p = &hw_cmd_we_buffer_cfg[0];
+
+	n_reg_val = (((GEMINI_WE_Y_THRESHOLD[1][is_realtime] <<
+		HWIO_JPEG_WE_Y_THRESHOLD_WE_DEASSERT_STALL_TH_SHFT) &
+		HWIO_JPEG_WE_Y_THRESHOLD_WE_DEASSERT_STALL_TH_BMSK) |
+		((GEMINI_WE_Y_THRESHOLD[0][is_realtime] <<
+		HWIO_JPEG_WE_Y_THRESHOLD_WE_ASSERT_STALL_TH_SHFT) &
+		HWIO_JPEG_WE_Y_THRESHOLD_WE_ASSERT_STALL_TH_BMSK));
+	hw_cmd_p->data = n_reg_val;
+	msm_gemini_hw_write(hw_cmd_p++);
+
+	msm_gemini_hw_write(hw_cmd_p++);
+
+	/* @todo maybe not for realtime? */
+	n_reg_val = (((GEMINI_WE_CBCR_THRESHOLD[1][is_realtime] <<
+		HWIO_JPEG_WE_CBCR_THRESHOLD_WE_DEASSERT_STALL_TH_SHFT) &
+		HWIO_JPEG_WE_CBCR_THRESHOLD_WE_DEASSERT_STALL_TH_BMSK) |
+		((GEMINI_WE_CBCR_THRESHOLD[0][is_realtime] <<
+		HWIO_JPEG_WE_CBCR_THRESHOLD_WE_ASSERT_STALL_TH_SHFT) &
+		HWIO_JPEG_WE_CBCR_THRESHOLD_WE_ASSERT_STALL_TH_BMSK));
+	hw_cmd_p->data = n_reg_val;
+	msm_gemini_hw_write(hw_cmd_p);
+
+	return;
+}
+
+struct msm_gemini_hw_cmd hw_cmd_we_ping_update[] = {
+	/* type, repeat n times, offset, mask, data or pdata */
+	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_WE_Y_PING_BUFFER_CFG_ADDR,
+		HWIO_JPEG_WE_Y_PING_BUFFER_CFG_RMSK, {0} },
+	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_WE_Y_PING_ADDR_ADDR,
+		HWIO_JPEG_WE_Y_PING_ADDR_RMSK, {0} },
+};
+
+struct msm_gemini_hw_cmd hw_cmd_we_pong_update[] = {
+	/* type, repeat n times, offset, mask, data or pdata */
+	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_WE_Y_PONG_BUFFER_CFG_ADDR,
+		HWIO_JPEG_WE_Y_PONG_BUFFER_CFG_RMSK, {0} },
+	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_WE_Y_PONG_ADDR_ADDR,
+		HWIO_JPEG_WE_Y_PONG_ADDR_RMSK, {0} },
+};
+
+void msm_gemini_hw_we_buffer_update(struct msm_gemini_hw_buf *p_input,
+	uint8_t pingpong_index)
+{
+	uint32_t n_reg_val = 0;
+
+	struct msm_gemini_hw_cmd *hw_cmd_p;
+
+	if (pingpong_index == 0) {
+		hw_cmd_p = &hw_cmd_we_ping_update[0];
+
+		n_reg_val = ((p_input->y_len <<
+			HWIO_JPEG_WE_Y_PING_BUFFER_CFG_WE_BUFFER_LENGTH_SHFT) &
+			HWIO_JPEG_WE_Y_PING_BUFFER_CFG_WE_BUFFER_LENGTH_BMSK);
+		hw_cmd_p->data = n_reg_val;
+		msm_gemini_hw_write(hw_cmd_p++);
+
+		n_reg_val = p_input->y_buffer_addr;
+		hw_cmd_p->data = n_reg_val;
+		msm_gemini_hw_write(hw_cmd_p++);
+	} else if (pingpong_index == 1) {
+		hw_cmd_p = &hw_cmd_we_pong_update[0];
+
+		n_reg_val = ((p_input->y_len <<
+			HWIO_JPEG_WE_Y_PONG_BUFFER_CFG_WE_BUFFER_LENGTH_SHFT) &
+			HWIO_JPEG_WE_Y_PONG_BUFFER_CFG_WE_BUFFER_LENGTH_BMSK);
+		hw_cmd_p->data = n_reg_val;
+		msm_gemini_hw_write(hw_cmd_p++);
+
+		n_reg_val = p_input->y_buffer_addr;
+		hw_cmd_p->data = n_reg_val;
+		msm_gemini_hw_write(hw_cmd_p++);
+	} else {
+		/* shall not get to here */
+	}
+
+	return;
+}
+
+struct msm_gemini_hw_cmd hw_cmd_reset[] = {
+	/* type, repeat n times, offset, mask, data or pdata */
+	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_IRQ_MASK_ADDR,
+		HWIO_JPEG_IRQ_MASK_RMSK, {JPEG_IRQ_DISABLE_ALL} },
+	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_IRQ_CLEAR_ADDR,
+		HWIO_JPEG_IRQ_MASK_RMSK, {JPEG_IRQ_CLEAR_ALL} },
+	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_IRQ_MASK_ADDR,
+		HWIO_JPEG_IRQ_MASK_RMSK, {JPEG_IRQ_ALLSOURCES_ENABLE} },
+	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_RESET_CMD_ADDR,
+		HWIO_JPEG_RESET_CMD_RMSK, {JPEG_RESET_DEFAULT} },
+};
+
+void msm_gemini_hw_init(void *base, int size)
+{
+	gemini_region_base = base;
+	gemini_region_size = size;
+}
+
+void msm_gemini_hw_reset(void *base, int size)
+{
+	struct msm_gemini_hw_cmd *hw_cmd_p;
+
+	hw_cmd_p = &hw_cmd_reset[0];
+
+	wmb();
+	msm_gemini_hw_write(hw_cmd_p++);
+	msm_gemini_hw_write(hw_cmd_p++);
+	msm_gemini_hw_write(hw_cmd_p++);
+	msm_gemini_hw_write(hw_cmd_p);
+	wmb();
+
+	return;
+}
+
+uint32_t msm_gemini_hw_read(struct msm_gemini_hw_cmd *hw_cmd_p)
+{
+	uint32_t *paddr;
+	uint32_t data;
+
+	paddr = gemini_region_base + hw_cmd_p->offset;
+
+	data = readl(paddr);
+	data &= hw_cmd_p->mask;
+
+	GMN_DBG("%s:%d] type-%d n-%d offset-0x%4x mask-0x%8x data-0x%8x\n",
+		__func__, __LINE__, hw_cmd_p->type, hw_cmd_p->n,
+		hw_cmd_p->offset, hw_cmd_p->mask, data);
+	return data;
+}
+
+void msm_gemini_hw_write(struct msm_gemini_hw_cmd *hw_cmd_p)
+{
+	uint32_t *paddr;
+	uint32_t old_data, new_data;
+
+	/* type, repeat n times, offset, mask, data or pdata */
+	GMN_DBG("%s:%d] type-%d n-%d offset-0x%4x mask-0x%8x data-0x%8x\n",
+		__func__, __LINE__, hw_cmd_p->type, hw_cmd_p->n,
+		hw_cmd_p->offset, hw_cmd_p->mask, hw_cmd_p->data);
+
+	paddr = gemini_region_base + hw_cmd_p->offset;
+
+	if (hw_cmd_p->mask == 0xffffffff) {
+		old_data = 0;
+	} else {
+		old_data = readl(paddr);
+		old_data &= ~hw_cmd_p->mask;
+	}
+
+	new_data = hw_cmd_p->data & hw_cmd_p->mask;
+	new_data |= old_data;
+	writel(new_data, paddr);
+}
+
+int msm_gemini_hw_wait(struct msm_gemini_hw_cmd *hw_cmd_p, int m_us)
+{
+	int tm = hw_cmd_p->n;
+	uint32_t data;
+	uint32_t wait_data = hw_cmd_p->data & hw_cmd_p->mask;
+
+	data = msm_gemini_hw_read(hw_cmd_p);
+	if (data != wait_data) {
+		while (tm) {
+			udelay(m_us);
+			data = msm_gemini_hw_read(hw_cmd_p);
+			if (data == wait_data)
+				break;
+			tm--;
+		}
+	}
+	hw_cmd_p->data = data;
+	return tm;
+}
+
+void msm_gemini_hw_delay(struct msm_gemini_hw_cmd *hw_cmd_p, int m_us)
+{
+	int tm = hw_cmd_p->n;
+	while (tm) {
+		udelay(m_us);
+		tm--;
+	}
+}
+
+int msm_gemini_hw_exec_cmds(struct msm_gemini_hw_cmd *hw_cmd_p, int m_cmds)
+{
+	int is_copy_to_user = -1;
+	uint32_t data;
+
+	while (m_cmds--) {
+		if (hw_cmd_p->offset > gemini_region_size) {
+			GMN_PR_ERR("%s:%d] %d exceed hw region %d\n", __func__,
+				__LINE__, hw_cmd_p->offset, gemini_region_size);
+			return -EFAULT;
+		}
+
+		switch (hw_cmd_p->type) {
+		case MSM_GEMINI_HW_CMD_TYPE_READ:
+			hw_cmd_p->data = msm_gemini_hw_read(hw_cmd_p);
+			is_copy_to_user = 1;
+			break;
+
+		case MSM_GEMINI_HW_CMD_TYPE_WRITE:
+			msm_gemini_hw_write(hw_cmd_p);
+			break;
+
+		case MSM_GEMINI_HW_CMD_TYPE_WRITE_OR:
+			data = msm_gemini_hw_read(hw_cmd_p);
+			hw_cmd_p->data = (hw_cmd_p->data & hw_cmd_p->mask) |
+				data;
+			msm_gemini_hw_write(hw_cmd_p);
+			break;
+
+		case MSM_GEMINI_HW_CMD_TYPE_UWAIT:
+			msm_gemini_hw_wait(hw_cmd_p, 1);
+			break;
+
+		case MSM_GEMINI_HW_CMD_TYPE_MWAIT:
+			msm_gemini_hw_wait(hw_cmd_p, 1000);
+			break;
+
+		case MSM_GEMINI_HW_CMD_TYPE_UDELAY:
+			msm_gemini_hw_delay(hw_cmd_p, 1);
+			break;
+
+		case MSM_GEMINI_HW_CMD_TYPE_MDELAY:
+			msm_gemini_hw_delay(hw_cmd_p, 1000);
+			break;
+
+		default:
+			GMN_PR_ERR("wrong hw command type\n");
+			break;
+		}
+
+		hw_cmd_p++;
+	}
+	return is_copy_to_user;
+}
+
+void msm_gemini_hw_region_dump(int size)
+{
+	uint32_t *p;
+	uint8_t *p8;
+
+	if (size > gemini_region_size)
+		GMN_PR_ERR("%s:%d] wrong region dump size\n",
+			__func__, __LINE__);
+
+	p = (uint32_t *) gemini_region_base;
+	while (size >= 16) {
+		GMN_DBG("0x%08X] %08X %08X %08X %08X\n",
+			gemini_region_size - size,
+			readl(p), readl(p+1), readl(p+2), readl(p+3));
+		p += 4;
+		size -= 16;
+	}
+
+	if (size > 0) {
+		uint32_t d;
+		GMN_DBG("0x%08X] ", gemini_region_size - size);
+		while (size >= 4) {
+			GMN_DBG("%08X ", readl(p++));
+			size -= 4;
+		}
+
+		d = readl(p);
+		p8 = (uint8_t *) &d;
+		while (size) {
+			GMN_DBG("%02X", *p8++);
+			size--;
+		}
+
+		GMN_DBG("\n");
+	}
+}
+
diff --git a/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_hw.h b/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_hw.h
new file mode 100644
index 0000000..1c8de19
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_hw.h
@@ -0,0 +1,104 @@
+/* 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.
+ */
+
+#ifndef MSM_GEMINI_HW_H
+#define MSM_GEMINI_HW_H
+
+#include <media/msm_gemini.h>
+#include "msm_gemini_hw_reg.h"
+#include <linux/msm_ion.h>
+#include <mach/iommu_domains.h>
+
+struct msm_gemini_hw_buf {
+	struct msm_gemini_buf vbuf;
+	struct file  *file;
+	uint32_t framedone_len;
+	uint32_t y_buffer_addr;
+	uint32_t y_len;
+	uint32_t cbcr_buffer_addr;
+	uint32_t cbcr_len;
+	uint32_t num_of_mcu_rows;
+	struct ion_handle *handle;
+};
+
+struct msm_gemini_hw_pingpong {
+	uint8_t is_fe; /* 1: fe; 0: we */
+	struct  msm_gemini_hw_buf buf[2];
+	int     buf_status[2];
+	int     buf_active_index;
+};
+
+int msm_gemini_hw_pingpong_update(struct msm_gemini_hw_pingpong *pingpong_hw,
+	struct msm_gemini_hw_buf *buf);
+void *msm_gemini_hw_pingpong_irq(struct msm_gemini_hw_pingpong *pingpong_hw);
+void *msm_gemini_hw_pingpong_active_buffer(struct msm_gemini_hw_pingpong
+	*pingpong_hw);
+
+void msm_gemini_hw_irq_clear(uint32_t, uint32_t);
+int msm_gemini_hw_irq_get_status(void);
+long msm_gemini_hw_encode_output_size(void);
+#define MSM_GEMINI_HW_MASK_COMP_FRAMEDONE \
+		MSM_GEMINI_HW_IRQ_STATUS_FRAMEDONE_MASK
+#define MSM_GEMINI_HW_MASK_COMP_FE \
+		MSM_GEMINI_HW_IRQ_STATUS_FE_RD_DONE_MASK
+#define MSM_GEMINI_HW_MASK_COMP_WE \
+		(MSM_GEMINI_HW_IRQ_STATUS_WE_Y_PINGPONG_MASK | \
+		 MSM_GEMINI_HW_IRQ_STATUS_WE_CBCR_PINGPONG_MASK)
+#define MSM_GEMINI_HW_MASK_COMP_RESET_ACK \
+		MSM_GEMINI_HW_IRQ_STATUS_RESET_ACK_MASK
+#define MSM_GEMINI_HW_MASK_COMP_ERR \
+		(MSM_GEMINI_HW_IRQ_STATUS_FE_RTOVF_MASK | \
+		MSM_GEMINI_HW_IRQ_STATUS_FE_VFE_OVERFLOW_MASK | \
+		MSM_GEMINI_HW_IRQ_STATUS_WE_Y_BUFFER_OVERFLOW_MASK | \
+		MSM_GEMINI_HW_IRQ_STATUS_WE_CBCR_BUFFER_OVERFLOW_MASK | \
+		MSM_GEMINI_HW_IRQ_STATUS_WE_CH0_DATAFIFO_OVERFLOW_MASK | \
+		MSM_GEMINI_HW_IRQ_STATUS_WE_CH1_DATAFIFO_OVERFLOW_MASK | \
+		MSM_GEMINI_HW_IRQ_STATUS_BUS_ERROR_MASK | \
+		MSM_GEMINI_HW_IRQ_STATUS_VIOLATION_MASK)
+
+#define msm_gemini_hw_irq_is_frame_done(gemini_irq_status) \
+	(gemini_irq_status & MSM_GEMINI_HW_MASK_COMP_FRAMEDONE)
+#define msm_gemini_hw_irq_is_fe_pingpong(gemini_irq_status) \
+	(gemini_irq_status & MSM_GEMINI_HW_MASK_COMP_FE)
+#define msm_gemini_hw_irq_is_we_pingpong(gemini_irq_status) \
+	(gemini_irq_status & MSM_GEMINI_HW_MASK_COMP_WE)
+#define msm_gemini_hw_irq_is_reset_ack(gemini_irq_status) \
+	(gemini_irq_status & MSM_GEMINI_HW_MASK_COMP_RESET_ACK)
+#define msm_gemini_hw_irq_is_err(gemini_irq_status) \
+	(gemini_irq_status & MSM_GEMINI_HW_MASK_COMP_ERR)
+
+void msm_gemini_hw_fe_buffer_update(struct msm_gemini_hw_buf *p_input,
+	uint8_t pingpong_index);
+void msm_gemini_hw_we_buffer_update(struct msm_gemini_hw_buf *p_input,
+	uint8_t pingpong_index);
+
+void msm_gemini_hw_we_buffer_cfg(uint8_t is_realtime);
+
+void msm_gemini_hw_fe_start(void);
+void msm_gemini_hw_clk_cfg(void);
+
+void msm_gemini_hw_reset(void *base, int size);
+void msm_gemini_hw_irq_cfg(void);
+void msm_gemini_hw_init(void *base, int size);
+
+uint32_t msm_gemini_hw_read(struct msm_gemini_hw_cmd *hw_cmd_p);
+void msm_gemini_hw_write(struct msm_gemini_hw_cmd *hw_cmd_p);
+int msm_gemini_hw_wait(struct msm_gemini_hw_cmd *hw_cmd_p, int m_us);
+void msm_gemini_hw_delay(struct msm_gemini_hw_cmd *hw_cmd_p, int m_us);
+int msm_gemini_hw_exec_cmds(struct msm_gemini_hw_cmd *hw_cmd_p, int m_cmds);
+void msm_gemini_hw_region_dump(int size);
+
+#define MSM_GEMINI_PIPELINE_CLK_128MHZ 128 /* 8MP  128MHz */
+#define MSM_GEMINI_PIPELINE_CLK_140MHZ 140 /* 9MP  140MHz */
+#define MSM_GEMINI_PIPELINE_CLK_200MHZ 153 /* 12MP 153MHz */
+
+#endif /* MSM_GEMINI_HW_H */
diff --git a/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_hw_reg.h b/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_hw_reg.h
new file mode 100644
index 0000000..ea13d68
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_hw_reg.h
@@ -0,0 +1,176 @@
+/* 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.
+ */
+
+#ifndef MSM_GEMINI_HW_REG_H
+#define MSM_GEMINI_HW_REG_H
+
+#define GEMINI_REG_BASE 0
+
+#define MSM_GEMINI_HW_IRQ_MASK_ADDR 0x00000014
+#define MSM_GEMINI_HW_IRQ_MASK_RMSK 0xffffffff
+#define MSM_GEMINI_HW_IRQ_MASK_SHFT 0
+#define MSM_GEMINI_HW_IRQ_DISABLE 0
+#define MSM_GEMINI_HW_IRQ_ENABLE 0xffffffff
+
+#define MSM_GEMINI_HW_IRQ_CLEAR_ADDR 0x00000018
+#define MSM_GEMINI_HW_IRQ_CLEAR_RMSK 0xffffffff
+#define MSM_GEMINI_HW_IRQ_CLEAR_SHFT 0
+#define MSM_GEMINI_HW_IRQ_CLEAR  0xffffffff
+
+#define MSM_GEMINI_HW_IRQ_STATUS_FRAMEDONE_MASK 0x00000001
+#define MSM_GEMINI_HW_IRQ_STATUS_FRAMEDONE_SHIFT 0x00000000
+
+#define MSM_GEMINI_HW_IRQ_STATUS_FE_RD_DONE_MASK 0x00000002
+#define MSM_GEMINI_HW_IRQ_STATUS_FE_RD_DONE_SHIFT 0x00000001
+
+#define MSM_GEMINI_HW_IRQ_STATUS_FE_RTOVF_MASK 0x00000004
+#define MSM_GEMINI_HW_IRQ_STATUS_FE_RTOVF_SHIFT 0x00000002
+
+#define MSM_GEMINI_HW_IRQ_STATUS_FE_VFE_OVERFLOW_MASK 0x00000008
+#define MSM_GEMINI_HW_IRQ_STATUS_FE_VFE_OVERFLOW_SHIFT 0x00000003
+
+#define MSM_GEMINI_HW_IRQ_STATUS_WE_Y_PINGPONG_MASK 0x00000010
+#define MSM_GEMINI_HW_IRQ_STATUS_WE_Y_PINGPONG_SHIFT 0x00000004
+
+#define MSM_GEMINI_HW_IRQ_STATUS_WE_CBCR_PINGPONG_MASK 0x00000020
+#define MSM_GEMINI_HW_IRQ_STATUS_WE_CBCR_PINGPONG_SHIFT 0x00000005
+
+#define MSM_GEMINI_HW_IRQ_STATUS_WE_Y_BUFFER_OVERFLOW_MASK 0x00000040
+#define MSM_GEMINI_HW_IRQ_STATUS_WE_Y_BUFFER_OVERFLOW_SHIFT 0x00000006
+
+#define MSM_GEMINI_HW_IRQ_STATUS_WE_CBCR_BUFFER_OVERFLOW_MASK 0x00000080
+#define MSM_GEMINI_HW_IRQ_STATUS_WE_CBCR_BUFFER_OVERFLOW_SHIFT 0x00000007
+
+#define MSM_GEMINI_HW_IRQ_STATUS_WE_CH0_DATAFIFO_OVERFLOW_MASK 0x00000100
+#define MSM_GEMINI_HW_IRQ_STATUS_WE_CH0_DATAFIFO_OVERFLOW_SHIFT 0x00000008
+
+#define MSM_GEMINI_HW_IRQ_STATUS_WE_CH1_DATAFIFO_OVERFLOW_MASK 0x00000200
+#define MSM_GEMINI_HW_IRQ_STATUS_WE_CH1_DATAFIFO_OVERFLOW_SHIFT 0x00000009
+
+#define MSM_GEMINI_HW_IRQ_STATUS_RESET_ACK_MASK 0x00000400
+#define MSM_GEMINI_HW_IRQ_STATUS_RESET_ACK_SHIFT 0x0000000a
+
+#define MSM_GEMINI_HW_IRQ_STATUS_BUS_ERROR_MASK 0x00000800
+#define MSM_GEMINI_HW_IRQ_STATUS_BUS_ERROR_SHIFT 0x0000000b
+
+#define MSM_GEMINI_HW_IRQ_STATUS_VIOLATION_MASK 0x00001000
+#define MSM_GEMINI_HW_IRQ_STATUS_VIOLATION_SHIFT 0x0000000c
+
+#define JPEG_BUS_CMD_HALT_REQ 0x00000001
+
+#define JPEG_REALTIME_CMD_STOP_FB 0x00000000
+#define JPEG_REALTIME_CMD_STOP_IM 0x00000003
+#define JPEG_REALTIME_CMD_START 0x00000001
+
+#define JPEG_OFFLINE_CMD_START 0x00000003
+
+#define JPEG_DMI_CFG_DISABLE 0x00000000
+#define JPEG_DMI_ADDR_START 0x00000000
+
+#define JPEG_FE_CMD_BUFFERRELOAD 0x00000001
+
+#define JPEG_WE_YUB_ENCODE 0x01ff0000
+
+#define JPEG_RESET_DEFAULT 0x0004ffff /* cfff? */
+
+#define JPEG_IRQ_DISABLE_ALL 0x00000000
+#define JPEG_IRQ_CLEAR_ALL 0xffffffff
+#define JPEG_IRQ_ALLSOURCES_ENABLE 0xffffffff
+
+#define HWIO_JPEG_FE_BUFFER_CFG_ADDR (GEMINI_REG_BASE + 0x00000080)
+#define HWIO_JPEG_FE_BUFFER_CFG_RMSK 0x1fff1fff
+
+#define HWIO_JPEG_FE_Y_PING_ADDR_ADDR (GEMINI_REG_BASE + 0x00000084)
+#define HWIO_JPEG_FE_Y_PING_ADDR_RMSK 0xffffffff
+
+#define HWIO_JPEG_FE_Y_PONG_ADDR_ADDR (GEMINI_REG_BASE + 0x00000088)
+#define HWIO_JPEG_FE_Y_PONG_ADDR_RMSK 0xffffffff
+
+#define HWIO_JPEG_FE_CBCR_PING_ADDR_ADDR (GEMINI_REG_BASE + 0x0000008c)
+#define HWIO_JPEG_FE_CBCR_PING_ADDR_RMSK 0xffffffff
+
+#define HWIO_JPEG_FE_CBCR_PONG_ADDR_ADDR (GEMINI_REG_BASE + 0x00000090)
+#define HWIO_JPEG_FE_CBCR_PONG_ADDR_RMSK 0xffffffff
+
+#define HWIO_JPEG_FE_CMD_ADDR (GEMINI_REG_BASE + 0x00000094)
+#define HWIO_JPEG_FE_CMD_RMSK 0x3
+
+#define HWIO_JPEG_FE_BUFFER_CFG_CBCR_MCU_ROWS_BMSK 0x1fff0000
+#define HWIO_JPEG_FE_BUFFER_CFG_CBCR_MCU_ROWS_SHFT 0x10
+#define HWIO_JPEG_FE_BUFFER_CFG_Y_MCU_ROWS_BMSK 0x1fff
+#define HWIO_JPEG_FE_BUFFER_CFG_Y_MCU_ROWS_SHFT 0
+
+#define HWIO_JPEG_FE_Y_PING_ADDR_FE_Y_PING_START_ADDR_BMSK 0xffffffff
+#define HWIO_JPEG_FE_Y_PING_ADDR_FE_Y_PING_START_ADDR_SHFT 0
+
+#define HWIO_JPEG_FE_CBCR_PING_ADDR_FE_CBCR_PING_START_ADDR_BMSK 0xffffffff
+#define HWIO_JPEG_FE_CBCR_PING_ADDR_FE_CBCR_PING_START_ADDR_SHFT 0
+
+#define HWIO_JPEG_FE_Y_PONG_ADDR_FE_Y_PONG_START_ADDR_BMSK 0xffffffff
+#define HWIO_JPEG_FE_Y_PONG_ADDR_FE_Y_PONG_START_ADDR_SHFT 0
+
+#define HWIO_JPEG_FE_CBCR_PONG_ADDR_FE_CBCR_PONG_START_ADDR_BMSK 0xffffffff
+#define HWIO_JPEG_FE_CBCR_PONG_ADDR_FE_CBCR_PONG_START_ADDR_SHFT 0
+
+#define HWIO_JPEG_WE_Y_THRESHOLD_ADDR (GEMINI_REG_BASE + 0x000000c0)
+#define HWIO_JPEG_WE_Y_THRESHOLD_RMSK 0x1ff01ff
+
+#define HWIO_JPEG_WE_CBCR_THRESHOLD_ADDR (GEMINI_REG_BASE      + 0x000000c4)
+#define HWIO_JPEG_WE_CBCR_THRESHOLD_RMSK 0x1ff01ff
+
+#define HWIO_JPEG_WE_Y_UB_CFG_ADDR (GEMINI_REG_BASE + 0x000000e8)
+#define HWIO_JPEG_WE_Y_UB_CFG_RMSK 0x1ff01ff
+
+#define HWIO_JPEG_WE_Y_THRESHOLD_WE_DEASSERT_STALL_TH_BMSK 0x1ff0000
+#define HWIO_JPEG_WE_Y_THRESHOLD_WE_DEASSERT_STALL_TH_SHFT 0x10
+#define HWIO_JPEG_WE_Y_THRESHOLD_WE_ASSERT_STALL_TH_BMSK 0x1ff
+#define HWIO_JPEG_WE_Y_THRESHOLD_WE_ASSERT_STALL_TH_SHFT 0
+
+#define HWIO_JPEG_WE_CBCR_THRESHOLD_WE_DEASSERT_STALL_TH_BMSK 0x1ff0000
+#define HWIO_JPEG_WE_CBCR_THRESHOLD_WE_DEASSERT_STALL_TH_SHFT 0x10
+#define HWIO_JPEG_WE_CBCR_THRESHOLD_WE_ASSERT_STALL_TH_BMSK 0x1ff
+#define HWIO_JPEG_WE_CBCR_THRESHOLD_WE_ASSERT_STALL_TH_SHFT 0
+
+#define HWIO_JPEG_WE_Y_PING_BUFFER_CFG_ADDR (GEMINI_REG_BASE + 0x000000c8)
+#define HWIO_JPEG_WE_Y_PING_BUFFER_CFG_RMSK 0x7fffff
+
+#define HWIO_JPEG_WE_Y_PING_ADDR_ADDR (GEMINI_REG_BASE + 0x000000d8)
+#define HWIO_JPEG_WE_Y_PING_ADDR_RMSK 0xfffffff8
+
+#define HWIO_JPEG_WE_Y_PONG_BUFFER_CFG_ADDR (GEMINI_REG_BASE + 0x000000cc)
+#define HWIO_JPEG_WE_Y_PONG_BUFFER_CFG_RMSK 0x7fffff
+
+#define HWIO_JPEG_WE_Y_PONG_ADDR_ADDR (GEMINI_REG_BASE + 0x000000dc)
+#define HWIO_JPEG_WE_Y_PONG_ADDR_RMSK 0xfffffff8
+
+#define HWIO_JPEG_WE_Y_PING_BUFFER_CFG_WE_BUFFER_LENGTH_BMSK 0x7fffff
+#define HWIO_JPEG_WE_Y_PING_BUFFER_CFG_WE_BUFFER_LENGTH_SHFT 0
+
+#define HWIO_JPEG_WE_Y_PONG_BUFFER_CFG_WE_BUFFER_LENGTH_BMSK 0x7fffff
+#define HWIO_JPEG_WE_Y_PONG_BUFFER_CFG_WE_BUFFER_LENGTH_SHFT 0
+
+#define HWIO_JPEG_IRQ_MASK_ADDR (GEMINI_REG_BASE + 0x00000014)
+#define HWIO_JPEG_IRQ_MASK_RMSK 0xffffffff
+
+#define HWIO_JPEG_IRQ_CLEAR_ADDR (GEMINI_REG_BASE + 0x00000018)
+#define HWIO_JPEG_IRQ_CLEAR_RMSK 0xffffffff
+
+#define HWIO_JPEG_RESET_CMD_ADDR (GEMINI_REG_BASE + 0x00000004)
+#define HWIO_JPEG_RESET_CMD_RMSK 0xe004ffff
+
+#define HWIO_JPEG_IRQ_STATUS_ADDR (GEMINI_REG_BASE + 0x0000001c)
+#define HWIO_JPEG_IRQ_STATUS_RMSK 0xffffffff
+
+#define HWIO_JPEG_STATUS_ENCODE_OUTPUT_SIZE_ADDR (GEMINI_REG_BASE + 0x00000034)
+#define HWIO_JPEG_STATUS_ENCODE_OUTPUT_SIZE_RMSK 0xffffff
+
+#endif /* MSM_GEMINI_HW_REG_H */
diff --git a/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_platform.c b/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_platform.c
new file mode 100644
index 0000000..d5a8098
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_platform.c
@@ -0,0 +1,255 @@
+/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/pm_qos.h>
+#include <linux/clk.h>
+#include <mach/clk.h>
+#include <linux/io.h>
+#include <linux/android_pmem.h>
+#include <mach/camera.h>
+#include <mach/iommu_domains.h>
+
+#include "msm_gemini_platform.h"
+#include "msm_gemini_sync.h"
+#include "msm_gemini_common.h"
+#include "msm_gemini_hw.h"
+
+/* AXI rate in KHz */
+#define MSM_SYSTEM_BUS_RATE	160000
+struct ion_client *gemini_client;
+
+void msm_gemini_platform_p2v(struct file  *file,
+				struct ion_handle **ionhandle)
+{
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	ion_unmap_iommu(gemini_client, *ionhandle, CAMERA_DOMAIN, GEN_POOL);
+	ion_free(gemini_client, *ionhandle);
+	*ionhandle = NULL;
+#elif CONFIG_ANDROID_PMEM
+	put_pmem_file(file);
+#endif
+}
+
+uint32_t msm_gemini_platform_v2p(int fd, uint32_t len, struct file **file_p,
+				struct ion_handle **ionhandle)
+{
+	unsigned long paddr;
+	unsigned long size;
+	int rc;
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	*ionhandle = ion_import_dma_buf(gemini_client, fd);
+	if (IS_ERR_OR_NULL(*ionhandle))
+		return 0;
+
+	rc = ion_map_iommu(gemini_client, *ionhandle, CAMERA_DOMAIN, GEN_POOL,
+			SZ_4K, 0, &paddr, (unsigned long *)&size, 0, 0);
+#elif CONFIG_ANDROID_PMEM
+	unsigned long kvstart;
+	rc = get_pmem_file(fd, &paddr, &kvstart, &size, file_p);
+#else
+	rc = 0;
+	paddr = 0;
+	size = 0;
+#endif
+	if (rc < 0) {
+		GMN_PR_ERR("%s: get_pmem_file fd %d error %d\n", __func__, fd,
+			rc);
+		goto error1;
+	}
+
+	/* validate user input */
+	if (len > size) {
+		GMN_PR_ERR("%s: invalid offset + len\n", __func__);
+		goto error1;
+	}
+
+	return paddr;
+error1:
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	ion_free(gemini_client, *ionhandle);
+#endif
+	return 0;
+}
+
+static struct msm_cam_clk_info gemini_8x_clk_info[] = {
+	{"core_clk", 228571000},
+	{"iface_clk", -1},
+};
+
+static struct msm_cam_clk_info gemini_7x_clk_info[] = {
+	{"core_clk", 153600000},
+	{"iface_clk", -1},
+};
+
+static struct msm_cam_clk_info gemini_imem_clk_info[] = {
+	{"mem_clk", -1},
+};
+
+int msm_gemini_platform_init(struct platform_device *pdev,
+	struct resource **mem,
+	void **base,
+	int *irq,
+	irqreturn_t (*handler) (int, void *),
+	void *context)
+{
+	int rc = -1;
+	int gemini_irq;
+	struct resource *gemini_mem, *gemini_io, *gemini_irq_res;
+	void *gemini_base;
+	struct msm_gemini_device *pgmn_dev =
+		(struct msm_gemini_device *) context;
+
+	gemini_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!gemini_mem) {
+		GMN_PR_ERR("%s: no mem resource?\n", __func__);
+		return -ENODEV;
+	}
+
+	gemini_irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!gemini_irq_res) {
+		GMN_PR_ERR("no irq resource?\n");
+		return -ENODEV;
+	}
+	gemini_irq = gemini_irq_res->start;
+
+	gemini_io = request_mem_region(gemini_mem->start,
+		resource_size(gemini_mem), pdev->name);
+	if (!gemini_io) {
+		GMN_PR_ERR("%s: region already claimed\n", __func__);
+		return -EBUSY;
+	}
+
+	gemini_base = ioremap(gemini_mem->start, resource_size(gemini_mem));
+	if (!gemini_base) {
+		rc = -ENOMEM;
+		GMN_PR_ERR("%s: ioremap failed\n", __func__);
+		goto fail1;
+	}
+
+	pgmn_dev->hw_version = GEMINI_8X60;
+	rc = msm_cam_clk_enable(&pgmn_dev->pdev->dev, gemini_8x_clk_info,
+	 pgmn_dev->gemini_clk, ARRAY_SIZE(gemini_8x_clk_info), 1);
+	if (rc < 0) {
+		pgmn_dev->hw_version = GEMINI_7X;
+		rc = msm_cam_clk_enable(&pgmn_dev->pdev->dev,
+			gemini_7x_clk_info, pgmn_dev->gemini_clk,
+			ARRAY_SIZE(gemini_7x_clk_info), 1);
+		if (rc < 0) {
+			GMN_PR_ERR("%s: clk failed rc = %d\n", __func__, rc);
+			goto fail2;
+		}
+	} else {
+		rc = msm_cam_clk_enable(&pgmn_dev->pdev->dev,
+				gemini_imem_clk_info, &pgmn_dev->gemini_clk[2],
+				ARRAY_SIZE(gemini_imem_clk_info), 1);
+		if (!rc)
+			pgmn_dev->hw_version = GEMINI_8960;
+	}
+
+	if (pgmn_dev->hw_version != GEMINI_7X) {
+		if (pgmn_dev->gemini_fs == NULL) {
+			pgmn_dev->gemini_fs =
+				regulator_get(&pgmn_dev->pdev->dev, "vdd");
+			if (IS_ERR(pgmn_dev->gemini_fs)) {
+				pr_err("%s: Regulator FS_ijpeg get failed %ld\n",
+					__func__, PTR_ERR(pgmn_dev->gemini_fs));
+				pgmn_dev->gemini_fs = NULL;
+				goto gemini_fs_failed;
+			} else if (regulator_enable(pgmn_dev->gemini_fs)) {
+				pr_err("%s: Regulator FS_ijpeg enable failed\n",
+								__func__);
+				regulator_put(pgmn_dev->gemini_fs);
+				pgmn_dev->gemini_fs = NULL;
+				goto gemini_fs_failed;
+			}
+		}
+	}
+
+	msm_gemini_hw_init(gemini_base, resource_size(gemini_mem));
+	rc = request_irq(gemini_irq, handler, IRQF_TRIGGER_RISING, "gemini",
+		context);
+	if (rc) {
+		GMN_PR_ERR("%s: request_irq failed, %d\n", __func__,
+			gemini_irq);
+		goto fail3;
+	}
+
+	*mem  = gemini_mem;
+	*base = gemini_base;
+	*irq  = gemini_irq;
+
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	gemini_client = msm_ion_client_create(-1, "camera/gemini");
+#endif
+	GMN_DBG("%s:%d] success\n", __func__, __LINE__);
+
+	return rc;
+
+fail3:
+	if (pgmn_dev->hw_version != GEMINI_7X) {
+		regulator_disable(pgmn_dev->gemini_fs);
+		regulator_put(pgmn_dev->gemini_fs);
+		pgmn_dev->gemini_fs = NULL;
+	}
+gemini_fs_failed:
+	if (pgmn_dev->hw_version == GEMINI_8960)
+		msm_cam_clk_enable(&pgmn_dev->pdev->dev, gemini_imem_clk_info,
+		 &pgmn_dev->gemini_clk[2], ARRAY_SIZE(gemini_imem_clk_info), 0);
+	if (pgmn_dev->hw_version != GEMINI_7X)
+		msm_cam_clk_enable(&pgmn_dev->pdev->dev, gemini_8x_clk_info,
+		pgmn_dev->gemini_clk, ARRAY_SIZE(gemini_8x_clk_info), 0);
+	else
+		msm_cam_clk_enable(&pgmn_dev->pdev->dev, gemini_7x_clk_info,
+		pgmn_dev->gemini_clk, ARRAY_SIZE(gemini_7x_clk_info), 0);
+fail2:
+	iounmap(gemini_base);
+fail1:
+	release_mem_region(gemini_mem->start, resource_size(gemini_mem));
+	GMN_DBG("%s:%d] fail\n", __func__, __LINE__);
+	return rc;
+}
+
+int msm_gemini_platform_release(struct resource *mem, void *base, int irq,
+	void *context)
+{
+	int result = 0;
+	struct msm_gemini_device *pgmn_dev =
+		(struct msm_gemini_device *) context;
+
+	free_irq(irq, context);
+
+	if (pgmn_dev->hw_version != GEMINI_7X) {
+		regulator_disable(pgmn_dev->gemini_fs);
+		regulator_put(pgmn_dev->gemini_fs);
+		pgmn_dev->gemini_fs = NULL;
+	}
+
+	if (pgmn_dev->hw_version == GEMINI_8960)
+		msm_cam_clk_enable(&pgmn_dev->pdev->dev, gemini_imem_clk_info,
+		 &pgmn_dev->gemini_clk[2], ARRAY_SIZE(gemini_imem_clk_info), 0);
+	if (pgmn_dev->hw_version != GEMINI_7X)
+		msm_cam_clk_enable(&pgmn_dev->pdev->dev, gemini_8x_clk_info,
+		pgmn_dev->gemini_clk, ARRAY_SIZE(gemini_8x_clk_info), 0);
+	else
+		msm_cam_clk_enable(&pgmn_dev->pdev->dev, gemini_7x_clk_info,
+		pgmn_dev->gemini_clk, ARRAY_SIZE(gemini_7x_clk_info), 0);
+
+	iounmap(base);
+	release_mem_region(mem->start, resource_size(mem));
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	ion_client_destroy(gemini_client);
+#endif
+	GMN_DBG("%s:%d] success\n", __func__, __LINE__);
+	return result;
+}
+
diff --git a/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_platform.h b/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_platform.h
new file mode 100644
index 0000000..f6291dc
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_platform.h
@@ -0,0 +1,37 @@
+/* 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.
+ */
+
+#ifndef MSM_GEMINI_PLATFORM_H
+#define MSM_GEMINI_PLATFORM_H
+
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/msm_ion.h>
+#include <linux/iommu.h>
+void msm_gemini_platform_p2v(struct file  *file,
+				struct ion_handle **ionhandle);
+uint32_t msm_gemini_platform_v2p(int fd, uint32_t len, struct file **file,
+				struct ion_handle **ionhandle);
+
+int msm_gemini_platform_clk_enable(void);
+int msm_gemini_platform_clk_disable(void);
+
+int msm_gemini_platform_init(struct platform_device *pdev,
+	struct resource **mem,
+	void **base,
+	int *irq,
+	irqreturn_t (*handler) (int, void *),
+	void *context);
+int msm_gemini_platform_release(struct resource *mem, void *base, int irq,
+	void *context);
+
+#endif /* MSM_GEMINI_PLATFORM_H */
diff --git a/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_sync.c b/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_sync.c
new file mode 100644
index 0000000..ed2222a
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_sync.c
@@ -0,0 +1,863 @@
+/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/uaccess.h>
+#include <linux/slab.h>
+#include <media/msm_gemini.h>
+#include "msm_gemini_sync.h"
+#include "msm_gemini_core.h"
+#include "msm_gemini_platform.h"
+#include "msm_gemini_common.h"
+
+static int release_buf;
+
+/*************** queue helper ****************/
+inline void msm_gemini_q_init(char const *name, struct msm_gemini_q *q_p)
+{
+	GMN_DBG("%s:%d] %s\n", __func__, __LINE__, name);
+	q_p->name = name;
+	spin_lock_init(&q_p->lck);
+	INIT_LIST_HEAD(&q_p->q);
+	init_waitqueue_head(&q_p->wait);
+	q_p->unblck = 0;
+}
+
+inline void *msm_gemini_q_out(struct msm_gemini_q *q_p)
+{
+	unsigned long flags;
+	struct msm_gemini_q_entry *q_entry_p = NULL;
+	void *data = NULL;
+
+	GMN_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
+	spin_lock_irqsave(&q_p->lck, flags);
+	if (!list_empty(&q_p->q)) {
+		q_entry_p = list_first_entry(&q_p->q, struct msm_gemini_q_entry,
+			list);
+		list_del_init(&q_entry_p->list);
+	}
+	spin_unlock_irqrestore(&q_p->lck, flags);
+
+	if (q_entry_p) {
+		data = q_entry_p->data;
+		kfree(q_entry_p);
+	} else {
+		GMN_DBG("%s:%d] %s no entry\n", __func__, __LINE__,
+			q_p->name);
+	}
+
+	return data;
+}
+
+inline int msm_gemini_q_in(struct msm_gemini_q *q_p, void *data)
+{
+	unsigned long flags;
+
+	struct msm_gemini_q_entry *q_entry_p;
+
+	GMN_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
+
+	q_entry_p = kmalloc(sizeof(struct msm_gemini_q_entry), GFP_ATOMIC);
+	if (!q_entry_p) {
+		GMN_PR_ERR("%s: no mem\n", __func__);
+		return -1;
+	}
+	q_entry_p->data = data;
+
+	spin_lock_irqsave(&q_p->lck, flags);
+	list_add_tail(&q_entry_p->list, &q_p->q);
+	spin_unlock_irqrestore(&q_p->lck, flags);
+
+	return 0;
+}
+
+inline int msm_gemini_q_in_buf(struct msm_gemini_q *q_p,
+	struct msm_gemini_core_buf *buf)
+{
+	struct msm_gemini_core_buf *buf_p;
+
+	GMN_DBG("%s:%d]\n", __func__, __LINE__);
+	buf_p = kmalloc(sizeof(struct msm_gemini_core_buf), GFP_ATOMIC);
+	if (!buf_p) {
+		GMN_PR_ERR("%s: no mem\n", __func__);
+		return -1;
+	}
+
+	memcpy(buf_p, buf, sizeof(struct msm_gemini_core_buf));
+
+	msm_gemini_q_in(q_p, buf_p);
+	return 0;
+}
+
+inline int msm_gemini_q_wait(struct msm_gemini_q *q_p)
+{
+	int tm = MAX_SCHEDULE_TIMEOUT; /* 500ms */
+	int rc;
+
+	GMN_DBG("%s:%d] %s wait\n", __func__, __LINE__, q_p->name);
+	rc = wait_event_interruptible_timeout(q_p->wait,
+		(!list_empty_careful(&q_p->q) || q_p->unblck),
+		msecs_to_jiffies(tm));
+	GMN_DBG("%s:%d] %s wait done\n", __func__, __LINE__, q_p->name);
+	if (list_empty_careful(&q_p->q)) {
+		if (rc == 0) {
+			rc = -ETIMEDOUT;
+			GMN_PR_ERR("%s:%d] %s timeout\n", __func__, __LINE__,
+				q_p->name);
+		} else if (q_p->unblck) {
+			GMN_DBG("%s:%d] %s unblock is true\n", __func__,
+				__LINE__, q_p->name);
+			q_p->unblck = 0;
+			rc = -ECANCELED;
+		} else if (rc < 0) {
+			GMN_PR_ERR("%s:%d] %s rc %d\n", __func__, __LINE__,
+				q_p->name, rc);
+		}
+	}
+	return rc;
+}
+
+inline int msm_gemini_q_wakeup(struct msm_gemini_q *q_p)
+{
+	GMN_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
+	wake_up(&q_p->wait);
+	return 0;
+}
+
+inline int msm_gemini_q_unblock(struct msm_gemini_q *q_p)
+{
+	GMN_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
+	q_p->unblck = 1;
+	wake_up(&q_p->wait);
+	return 0;
+}
+
+inline void msm_gemini_outbuf_q_cleanup(struct msm_gemini_q *q_p)
+{
+	struct msm_gemini_core_buf *buf_p;
+	GMN_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
+	do {
+		buf_p = msm_gemini_q_out(q_p);
+		if (buf_p) {
+			msm_gemini_platform_p2v(buf_p->file,
+				&buf_p->handle);
+			GMN_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
+			kfree(buf_p);
+		}
+	} while (buf_p);
+	q_p->unblck = 0;
+}
+
+inline void msm_gemini_q_cleanup(struct msm_gemini_q *q_p)
+{
+	void *data;
+	GMN_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
+	do {
+		data = msm_gemini_q_out(q_p);
+		if (data) {
+			GMN_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
+			kfree(data);
+		}
+	} while (data);
+	q_p->unblck = 0;
+}
+
+/*************** event queue ****************/
+
+int msm_gemini_framedone_irq(struct msm_gemini_device *pgmn_dev,
+	struct msm_gemini_core_buf *buf_in)
+{
+	int rc = 0;
+
+	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
+
+	if (buf_in) {
+		buf_in->vbuf.framedone_len = buf_in->framedone_len;
+		buf_in->vbuf.type = MSM_GEMINI_EVT_FRAMEDONE;
+		GMN_DBG("%s:%d] 0x%08x %d framedone_len %d\n",
+			__func__, __LINE__,
+			(int) buf_in->y_buffer_addr, buf_in->y_len,
+			buf_in->vbuf.framedone_len);
+		rc = msm_gemini_q_in_buf(&pgmn_dev->evt_q, buf_in);
+	} else {
+		GMN_PR_ERR("%s:%d] no output return buffer\n",
+			__func__, __LINE__);
+		rc = -1;
+	}
+
+	if (buf_in)
+		rc = msm_gemini_q_wakeup(&pgmn_dev->evt_q);
+
+	return rc;
+}
+
+int msm_gemini_evt_get(struct msm_gemini_device *pgmn_dev,
+	void __user *to)
+{
+	struct msm_gemini_core_buf *buf_p;
+	struct msm_gemini_ctrl_cmd ctrl_cmd;
+
+	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
+
+	msm_gemini_q_wait(&pgmn_dev->evt_q);
+	buf_p = msm_gemini_q_out(&pgmn_dev->evt_q);
+
+	if (!buf_p) {
+		GMN_DBG("%s:%d] no buffer\n", __func__, __LINE__);
+		return -EAGAIN;
+	}
+
+	memset(&ctrl_cmd, 0, sizeof(struct msm_gemini_ctrl_cmd));
+	ctrl_cmd.type = buf_p->vbuf.type;
+	kfree(buf_p);
+
+	GMN_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
+		(int) ctrl_cmd.value, ctrl_cmd.len);
+
+	if (copy_to_user(to, &ctrl_cmd, sizeof(ctrl_cmd))) {
+		GMN_PR_ERR("%s:%d]\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+int msm_gemini_evt_get_unblock(struct msm_gemini_device *pgmn_dev)
+{
+	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
+	msm_gemini_q_unblock(&pgmn_dev->evt_q);
+	return 0;
+}
+
+void msm_gemini_reset_ack_irq(struct msm_gemini_device *pgmn_dev)
+{
+	GMN_DBG("%s:%d]\n", __func__, __LINE__);
+}
+
+void msm_gemini_err_irq(struct msm_gemini_device *pgmn_dev,
+	int event)
+{
+	int rc = 0;
+	struct msm_gemini_core_buf buf;
+
+	GMN_PR_ERR("%s:%d] error: %d\n", __func__, __LINE__, event);
+
+	buf.vbuf.type = MSM_GEMINI_EVT_ERR;
+	rc = msm_gemini_q_in_buf(&pgmn_dev->evt_q, &buf);
+	if (!rc)
+		rc = msm_gemini_q_wakeup(&pgmn_dev->evt_q);
+
+	if (!rc)
+		GMN_PR_ERR("%s:%d] err err\n", __func__, __LINE__);
+
+	return;
+}
+
+/*************** output queue ****************/
+
+int msm_gemini_we_pingpong_irq(struct msm_gemini_device *pgmn_dev,
+	struct msm_gemini_core_buf *buf_in)
+{
+	int rc = 0;
+	struct msm_gemini_core_buf *buf_out;
+
+	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
+	if (buf_in) {
+		GMN_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
+			(int) buf_in->y_buffer_addr, buf_in->y_len);
+		rc = msm_gemini_q_in_buf(&pgmn_dev->output_rtn_q, buf_in);
+	} else {
+		GMN_DBG("%s:%d] no output return buffer\n", __func__,
+			__LINE__);
+		rc = -1;
+		return rc;
+	}
+
+	buf_out = msm_gemini_q_out(&pgmn_dev->output_buf_q);
+
+	if (buf_out) {
+		rc = msm_gemini_core_we_buf_update(buf_out);
+		kfree(buf_out);
+	} else {
+		msm_gemini_core_we_buf_reset(buf_in);
+		GMN_DBG("%s:%d] no output buffer\n", __func__, __LINE__);
+		rc = -2;
+	}
+
+	if (buf_in)
+		rc = msm_gemini_q_wakeup(&pgmn_dev->output_rtn_q);
+
+	return rc;
+}
+
+int msm_gemini_output_get(struct msm_gemini_device *pgmn_dev, void __user *to)
+{
+	struct msm_gemini_core_buf *buf_p;
+	struct msm_gemini_buf buf_cmd;
+
+	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
+
+	msm_gemini_q_wait(&pgmn_dev->output_rtn_q);
+	buf_p = msm_gemini_q_out(&pgmn_dev->output_rtn_q);
+
+	if (!buf_p) {
+		GMN_DBG("%s:%d] no output buffer return\n",
+			__func__, __LINE__);
+		return -EAGAIN;
+	}
+
+	buf_cmd = buf_p->vbuf;
+	msm_gemini_platform_p2v(buf_p->file, &buf_p->handle);
+	kfree(buf_p);
+
+	GMN_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
+		(int) buf_cmd.vaddr, buf_cmd.y_len);
+
+	if (copy_to_user(to, &buf_cmd, sizeof(buf_cmd))) {
+		GMN_PR_ERR("%s:%d]", __func__, __LINE__);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+int msm_gemini_output_get_unblock(struct msm_gemini_device *pgmn_dev)
+{
+	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
+	msm_gemini_q_unblock(&pgmn_dev->output_rtn_q);
+	return 0;
+}
+
+int msm_gemini_output_buf_enqueue(struct msm_gemini_device *pgmn_dev,
+	void __user *arg)
+{
+	struct msm_gemini_buf buf_cmd;
+	struct msm_gemini_core_buf *buf_p;
+
+	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
+	if (copy_from_user(&buf_cmd, arg, sizeof(struct msm_gemini_buf))) {
+		GMN_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+
+	buf_p = kmalloc(sizeof(struct msm_gemini_core_buf), GFP_ATOMIC);
+	if (!buf_p) {
+		GMN_PR_ERR("%s:%d] no mem\n", __func__, __LINE__);
+		return -1;
+	}
+
+	GMN_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__, (int) buf_cmd.vaddr,
+		buf_cmd.y_len);
+
+	buf_p->y_buffer_addr = msm_gemini_platform_v2p(buf_cmd.fd,
+		buf_cmd.y_len, &buf_p->file, &buf_p->handle);
+	if (!buf_p->y_buffer_addr) {
+		GMN_PR_ERR("%s:%d] v2p wrong\n", __func__, __LINE__);
+		kfree(buf_p);
+		return -1;
+	}
+	buf_p->y_len = buf_cmd.y_len;
+	buf_p->vbuf = buf_cmd;
+
+	msm_gemini_q_in(&pgmn_dev->output_buf_q, buf_p);
+	return 0;
+}
+
+/*************** input queue ****************/
+
+int msm_gemini_fe_pingpong_irq(struct msm_gemini_device *pgmn_dev,
+	struct msm_gemini_core_buf *buf_in)
+{
+	struct msm_gemini_core_buf *buf_out;
+	int rc = 0;
+
+	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
+	if (buf_in) {
+		GMN_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
+			(int) buf_in->y_buffer_addr, buf_in->y_len);
+		rc = msm_gemini_q_in_buf(&pgmn_dev->input_rtn_q, buf_in);
+	} else {
+		GMN_DBG("%s:%d] no input return buffer\n", __func__,
+			__LINE__);
+		rc = -1;
+	}
+
+	buf_out = msm_gemini_q_out(&pgmn_dev->input_buf_q);
+
+	if (buf_out) {
+		rc = msm_gemini_core_fe_buf_update(buf_out);
+		kfree(buf_out);
+		msm_gemini_core_fe_start();
+	} else {
+		GMN_DBG("%s:%d] no input buffer\n", __func__, __LINE__);
+		rc = -2;
+	}
+
+	if (buf_in)
+		rc = msm_gemini_q_wakeup(&pgmn_dev->input_rtn_q);
+
+	return rc;
+}
+
+int msm_gemini_input_get(struct msm_gemini_device *pgmn_dev, void __user * to)
+{
+	struct msm_gemini_core_buf *buf_p;
+	struct msm_gemini_buf buf_cmd;
+
+	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
+	msm_gemini_q_wait(&pgmn_dev->input_rtn_q);
+	buf_p = msm_gemini_q_out(&pgmn_dev->input_rtn_q);
+
+	if (!buf_p) {
+		GMN_DBG("%s:%d] no input buffer return\n",
+			__func__, __LINE__);
+		return -EAGAIN;
+	}
+
+	buf_cmd = buf_p->vbuf;
+	if (pgmn_dev->op_mode == MSM_GEMINI_MODE_OFFLINE_ENCODE ||
+		pgmn_dev->op_mode == MSM_GEMINI_MODE_OFFLINE_ROTATION) {
+		msm_gemini_platform_p2v(buf_p->file, &buf_p->handle);
+	}
+	kfree(buf_p);
+
+	GMN_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
+		(int) buf_cmd.vaddr, buf_cmd.y_len);
+
+	if (copy_to_user(to, &buf_cmd, sizeof(buf_cmd))) {
+		GMN_PR_ERR("%s:%d]\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+int msm_gemini_input_get_unblock(struct msm_gemini_device *pgmn_dev)
+{
+	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
+	msm_gemini_q_unblock(&pgmn_dev->input_rtn_q);
+	return 0;
+}
+
+int msm_gemini_input_buf_enqueue(struct msm_gemini_device *pgmn_dev,
+	void __user *arg)
+{
+	struct msm_gemini_core_buf *buf_p;
+	struct msm_gemini_buf buf_cmd;
+	int rc = 0;
+
+	if (copy_from_user(&buf_cmd, arg, sizeof(struct msm_gemini_buf))) {
+		GMN_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+
+	buf_p = kmalloc(sizeof(struct msm_gemini_core_buf), GFP_ATOMIC);
+	if (!buf_p) {
+		GMN_PR_ERR("%s:%d] no mem\n", __func__, __LINE__);
+		return -1;
+	}
+
+	GMN_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
+		(int) buf_cmd.vaddr, buf_cmd.y_len);
+
+	if (pgmn_dev->op_mode == MSM_GEMINI_MODE_REALTIME_ENCODE) {
+		rc = msm_iommu_map_contig_buffer(
+			(unsigned long)buf_cmd.y_off, CAMERA_DOMAIN, GEN_POOL,
+			((buf_cmd.y_len + buf_cmd.cbcr_len + 4095) & (~4095)),
+			SZ_4K, IOMMU_WRITE | IOMMU_READ,
+			(unsigned long *)&buf_p->y_buffer_addr);
+		if (rc < 0) {
+			pr_err("%s iommu mapping failed with error %d\n",
+				 __func__, rc);
+			kfree(buf_p);
+			return rc;
+		}
+	} else {
+	buf_p->y_buffer_addr    = msm_gemini_platform_v2p(buf_cmd.fd,
+		buf_cmd.y_len + buf_cmd.cbcr_len, &buf_p->file,
+		&buf_p->handle)	+ buf_cmd.offset + buf_cmd.y_off;
+	}
+	buf_p->y_len          = buf_cmd.y_len;
+
+	buf_p->cbcr_buffer_addr = buf_p->y_buffer_addr + buf_cmd.y_len +
+					buf_cmd.cbcr_off;
+	buf_p->cbcr_len       = buf_cmd.cbcr_len;
+	buf_p->num_of_mcu_rows = buf_cmd.num_of_mcu_rows;
+	GMN_DBG("%s: y_addr=%x,y_len=%x,cbcr_addr=%x,cbcr_len=%x\n", __func__,
+		buf_p->y_buffer_addr, buf_p->y_len, buf_p->cbcr_buffer_addr,
+		buf_p->cbcr_len);
+
+	if (!buf_p->y_buffer_addr || !buf_p->cbcr_buffer_addr) {
+		GMN_PR_ERR("%s:%d] v2p wrong\n", __func__, __LINE__);
+		kfree(buf_p);
+		return -1;
+	}
+	buf_p->vbuf           = buf_cmd;
+
+	msm_gemini_q_in(&pgmn_dev->input_buf_q, buf_p);
+
+	return 0;
+}
+
+int msm_gemini_irq(int event, void *context, void *data)
+{
+	struct msm_gemini_device *pgmn_dev =
+		(struct msm_gemini_device *) context;
+
+	switch (event) {
+	case MSM_GEMINI_HW_MASK_COMP_FRAMEDONE:
+		msm_gemini_framedone_irq(pgmn_dev, data);
+		msm_gemini_we_pingpong_irq(pgmn_dev, data);
+		break;
+
+	case MSM_GEMINI_HW_MASK_COMP_FE:
+		msm_gemini_fe_pingpong_irq(pgmn_dev, data);
+		break;
+
+	case MSM_GEMINI_HW_MASK_COMP_WE:
+		msm_gemini_we_pingpong_irq(pgmn_dev, data);
+		break;
+
+	case MSM_GEMINI_HW_MASK_COMP_RESET_ACK:
+		msm_gemini_reset_ack_irq(pgmn_dev);
+		break;
+
+	case MSM_GEMINI_HW_MASK_COMP_ERR:
+	default:
+		msm_gemini_err_irq(pgmn_dev, event);
+		break;
+	}
+
+	return 0;
+}
+
+int __msm_gemini_open(struct msm_gemini_device *pgmn_dev)
+{
+	int rc;
+
+	mutex_lock(&pgmn_dev->lock);
+	if (pgmn_dev->open_count) {
+		/* only open once */
+		GMN_PR_ERR("%s:%d] busy\n", __func__, __LINE__);
+		mutex_unlock(&pgmn_dev->lock);
+		return -EBUSY;
+	}
+	pgmn_dev->open_count++;
+	mutex_unlock(&pgmn_dev->lock);
+
+	msm_gemini_core_irq_install(msm_gemini_irq);
+	rc = msm_gemini_platform_init(pgmn_dev->pdev,
+		&pgmn_dev->mem, &pgmn_dev->base,
+		&pgmn_dev->irq, msm_gemini_core_irq, pgmn_dev);
+	if (rc) {
+		GMN_PR_ERR("%s:%d] platform_init fail %d\n", __func__,
+			__LINE__, rc);
+		return rc;
+	}
+
+	GMN_DBG("%s:%d] platform resources - mem %p, base %p, irq %d\n",
+		__func__, __LINE__,
+		pgmn_dev->mem, pgmn_dev->base, pgmn_dev->irq);
+
+	msm_gemini_q_cleanup(&pgmn_dev->evt_q);
+	msm_gemini_q_cleanup(&pgmn_dev->output_rtn_q);
+	msm_gemini_outbuf_q_cleanup(&pgmn_dev->output_buf_q);
+	msm_gemini_q_cleanup(&pgmn_dev->input_rtn_q);
+	msm_gemini_q_cleanup(&pgmn_dev->input_buf_q);
+	msm_gemini_core_init();
+
+	GMN_DBG("%s:%d] success\n", __func__, __LINE__);
+	return rc;
+}
+
+int __msm_gemini_release(struct msm_gemini_device *pgmn_dev)
+{
+	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
+	mutex_lock(&pgmn_dev->lock);
+	if (!pgmn_dev->open_count) {
+		GMN_PR_ERR(KERN_ERR "%s: not opened\n", __func__);
+		mutex_unlock(&pgmn_dev->lock);
+		return -EINVAL;
+	}
+	pgmn_dev->open_count--;
+	mutex_unlock(&pgmn_dev->lock);
+
+	msm_gemini_core_release(release_buf);
+	msm_gemini_q_cleanup(&pgmn_dev->evt_q);
+	msm_gemini_q_cleanup(&pgmn_dev->output_rtn_q);
+	msm_gemini_outbuf_q_cleanup(&pgmn_dev->output_buf_q);
+	msm_gemini_q_cleanup(&pgmn_dev->input_rtn_q);
+	msm_gemini_outbuf_q_cleanup(&pgmn_dev->input_buf_q);
+
+	if (pgmn_dev->open_count)
+		GMN_PR_ERR(KERN_ERR "%s: multiple opens\n", __func__);
+
+	msm_gemini_platform_release(pgmn_dev->mem, pgmn_dev->base,
+		pgmn_dev->irq, pgmn_dev);
+
+	return 0;
+}
+
+int msm_gemini_ioctl_hw_cmd(struct msm_gemini_device *pgmn_dev,
+	void * __user arg)
+{
+	struct msm_gemini_hw_cmd hw_cmd;
+	int is_copy_to_user;
+
+	if (copy_from_user(&hw_cmd, arg, sizeof(struct msm_gemini_hw_cmd))) {
+		GMN_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+
+	is_copy_to_user = msm_gemini_hw_exec_cmds(&hw_cmd, 1);
+	GMN_DBG("%s:%d] type %d, n %d, offset %d, mask %x, data %x, pdata %x\n",
+		__func__, __LINE__, hw_cmd.type, hw_cmd.n, hw_cmd.offset,
+		hw_cmd.mask, hw_cmd.data, (int) hw_cmd.pdata);
+
+	if (is_copy_to_user >= 0) {
+		if (copy_to_user(arg, &hw_cmd, sizeof(hw_cmd))) {
+			GMN_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
+			return -EFAULT;
+		}
+	}
+
+	return 0;
+}
+
+int msm_gemini_ioctl_hw_cmds(struct msm_gemini_device *pgmn_dev,
+	void * __user arg)
+{
+	int is_copy_to_user;
+	int len;
+	uint32_t m;
+	struct msm_gemini_hw_cmds *hw_cmds_p;
+	struct msm_gemini_hw_cmd *hw_cmd_p;
+
+	if (copy_from_user(&m, arg, sizeof(m))) {
+		GMN_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+
+	len = sizeof(struct msm_gemini_hw_cmds) +
+		sizeof(struct msm_gemini_hw_cmd) * (m - 1);
+	hw_cmds_p = kmalloc(len, GFP_KERNEL);
+	if (!hw_cmds_p) {
+		GMN_PR_ERR("%s:%d] no mem %d\n", __func__, __LINE__, len);
+		return -EFAULT;
+	}
+
+	if (copy_from_user(hw_cmds_p, arg, len)) {
+		GMN_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
+		kfree(hw_cmds_p);
+		return -EFAULT;
+	}
+
+	hw_cmd_p = (struct msm_gemini_hw_cmd *) &(hw_cmds_p->hw_cmd);
+
+	is_copy_to_user = msm_gemini_hw_exec_cmds(hw_cmd_p, m);
+
+	if (is_copy_to_user >= 0) {
+		if (copy_to_user(arg, hw_cmds_p, len)) {
+			GMN_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
+			kfree(hw_cmds_p);
+			return -EFAULT;
+		}
+	}
+	kfree(hw_cmds_p);
+	return 0;
+}
+
+int msm_gemini_start(struct msm_gemini_device *pgmn_dev, void * __user arg)
+{
+	struct msm_gemini_core_buf *buf_out;
+	struct msm_gemini_core_buf *buf_out_free[2] = {NULL, NULL};
+	int i, rc;
+
+	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
+
+	release_buf = 1;
+	for (i = 0; i < 2; i++) {
+		buf_out = msm_gemini_q_out(&pgmn_dev->input_buf_q);
+
+		if (buf_out) {
+			msm_gemini_core_fe_buf_update(buf_out);
+			kfree(buf_out);
+		} else {
+			GMN_DBG("%s:%d] no input buffer\n", __func__, __LINE__);
+			break;
+		}
+	}
+
+	for (i = 0; i < 2; i++) {
+		buf_out_free[i] = msm_gemini_q_out(&pgmn_dev->output_buf_q);
+
+		if (buf_out_free[i]) {
+			msm_gemini_core_we_buf_update(buf_out_free[i]);
+		} else if (i == 1) {
+			/* set the pong to same address as ping */
+			buf_out_free[0]->y_len >>= 1;
+			buf_out_free[0]->y_buffer_addr +=
+				buf_out_free[0]->y_len;
+			msm_gemini_core_we_buf_update(buf_out_free[0]);
+			/* since ping and pong are same buf release only once*/
+			release_buf = 0;
+		} else {
+			GMN_DBG("%s:%d] no output buffer\n",
+			__func__, __LINE__);
+			break;
+		}
+	}
+
+	for (i = 0; i < 2; i++)
+		kfree(buf_out_free[i]);
+
+	rc = msm_gemini_ioctl_hw_cmds(pgmn_dev, arg);
+	GMN_DBG("%s:%d]\n", __func__, __LINE__);
+	return rc;
+}
+
+int msm_gemini_ioctl_reset(struct msm_gemini_device *pgmn_dev,
+	void * __user arg)
+{
+	int rc;
+	struct msm_gemini_ctrl_cmd ctrl_cmd;
+
+	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
+	if (copy_from_user(&ctrl_cmd, arg, sizeof(ctrl_cmd))) {
+		GMN_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+
+	pgmn_dev->op_mode = ctrl_cmd.type;
+
+	rc = msm_gemini_core_reset(pgmn_dev->op_mode, pgmn_dev->base,
+		resource_size(pgmn_dev->mem));
+	return rc;
+}
+
+int msm_gemini_ioctl_test_dump_region(struct msm_gemini_device *pgmn_dev,
+	unsigned long arg)
+{
+	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
+	msm_gemini_hw_region_dump(arg);
+	return 0;
+}
+
+long __msm_gemini_ioctl(struct msm_gemini_device *pgmn_dev,
+	unsigned int cmd, unsigned long arg)
+{
+	int rc = 0;
+	switch (cmd) {
+	case MSM_GMN_IOCTL_GET_HW_VERSION:
+		GMN_DBG("%s:%d] VERSION 1\n", __func__, __LINE__);
+		rc = msm_gemini_ioctl_hw_cmd(pgmn_dev, (void __user *) arg);
+		break;
+
+	case MSM_GMN_IOCTL_RESET:
+		rc = msm_gemini_ioctl_reset(pgmn_dev, (void __user *) arg);
+		break;
+
+	case MSM_GMN_IOCTL_STOP:
+		rc = msm_gemini_ioctl_hw_cmds(pgmn_dev, (void __user *) arg);
+		break;
+
+	case MSM_GMN_IOCTL_START:
+		rc = msm_gemini_start(pgmn_dev, (void __user *) arg);
+		break;
+
+	case MSM_GMN_IOCTL_INPUT_BUF_ENQUEUE:
+		rc = msm_gemini_input_buf_enqueue(pgmn_dev,
+			(void __user *) arg);
+		break;
+
+	case MSM_GMN_IOCTL_INPUT_GET:
+		rc = msm_gemini_input_get(pgmn_dev, (void __user *) arg);
+		break;
+
+	case MSM_GMN_IOCTL_INPUT_GET_UNBLOCK:
+		rc = msm_gemini_input_get_unblock(pgmn_dev);
+		break;
+
+	case MSM_GMN_IOCTL_OUTPUT_BUF_ENQUEUE:
+		rc = msm_gemini_output_buf_enqueue(pgmn_dev,
+			(void __user *) arg);
+		break;
+
+	case MSM_GMN_IOCTL_OUTPUT_GET:
+		rc = msm_gemini_output_get(pgmn_dev, (void __user *) arg);
+		break;
+
+	case MSM_GMN_IOCTL_OUTPUT_GET_UNBLOCK:
+		rc = msm_gemini_output_get_unblock(pgmn_dev);
+		break;
+
+	case MSM_GMN_IOCTL_EVT_GET:
+		rc = msm_gemini_evt_get(pgmn_dev, (void __user *) arg);
+		break;
+
+	case MSM_GMN_IOCTL_EVT_GET_UNBLOCK:
+		rc = msm_gemini_evt_get_unblock(pgmn_dev);
+		break;
+
+	case MSM_GMN_IOCTL_HW_CMD:
+		rc = msm_gemini_ioctl_hw_cmd(pgmn_dev, (void __user *) arg);
+		break;
+
+	case MSM_GMN_IOCTL_HW_CMDS:
+		rc = msm_gemini_ioctl_hw_cmds(pgmn_dev, (void __user *) arg);
+		break;
+
+	case MSM_GMN_IOCTL_TEST_DUMP_REGION:
+		rc = msm_gemini_ioctl_test_dump_region(pgmn_dev, arg);
+		break;
+
+	default:
+		GMN_PR_ERR(KERN_INFO "%s:%d] cmd = %d not supported\n",
+			__func__, __LINE__, _IOC_NR(cmd));
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
+struct msm_gemini_device *__msm_gemini_init(struct platform_device *pdev)
+{
+	struct msm_gemini_device *pgmn_dev;
+
+	pgmn_dev = kzalloc(sizeof(struct msm_gemini_device), GFP_ATOMIC);
+	if (!pgmn_dev) {
+		GMN_PR_ERR("%s:%d]no mem\n", __func__, __LINE__);
+		return NULL;
+	}
+
+	mutex_init(&pgmn_dev->lock);
+
+	pgmn_dev->pdev = pdev;
+
+	msm_gemini_q_init("evt_q", &pgmn_dev->evt_q);
+	msm_gemini_q_init("output_rtn_q", &pgmn_dev->output_rtn_q);
+	msm_gemini_q_init("output_buf_q", &pgmn_dev->output_buf_q);
+	msm_gemini_q_init("input_rtn_q", &pgmn_dev->input_rtn_q);
+	msm_gemini_q_init("input_buf_q", &pgmn_dev->input_buf_q);
+
+	return pgmn_dev;
+}
+
+int __msm_gemini_exit(struct msm_gemini_device *pgmn_dev)
+{
+	mutex_destroy(&pgmn_dev->lock);
+	kfree(pgmn_dev);
+	return 0;
+}
+
diff --git a/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_sync.h b/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_sync.h
new file mode 100644
index 0000000..d1a43e1
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/gemini/msm_gemini_sync.h
@@ -0,0 +1,88 @@
+/* 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.
+ */
+
+#ifndef MSM_GEMINI_SYNC_H
+#define MSM_GEMINI_SYNC_H
+
+#include <linux/fs.h>
+#include <linux/list.h>
+#include <linux/cdev.h>
+#include <linux/platform_device.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+#include "msm_gemini_core.h"
+
+#define GEMINI_7X 0x1
+#define GEMINI_8X60 (0x1 << 1)
+#define GEMINI_8960 (0x1 << 2)
+
+struct msm_gemini_q {
+	char const	*name;
+	struct list_head  q;
+	spinlock_t	lck;
+	wait_queue_head_t wait;
+	int	       unblck;
+};
+
+struct msm_gemini_q_entry {
+	struct list_head list;
+	void   *data;
+};
+
+struct msm_gemini_device {
+	struct platform_device *pdev;
+	struct resource        *mem;
+	int                     irq;
+	void                   *base;
+	struct clk *gemini_clk[3];
+	struct regulator *gemini_fs;
+	uint32_t hw_version;
+
+	struct device *device;
+	struct cdev   cdev;
+	struct mutex  lock;
+	char	  open_count;
+	uint8_t       op_mode;
+
+	/* event queue including frame done & err indications
+	 */
+	struct msm_gemini_q evt_q;
+
+	/* output return queue
+	 */
+	struct msm_gemini_q output_rtn_q;
+
+	/* output buf queue
+	 */
+	struct msm_gemini_q output_buf_q;
+
+	/* input return queue
+	 */
+	struct msm_gemini_q input_rtn_q;
+
+	/* input buf queue
+	 */
+	struct msm_gemini_q input_buf_q;
+
+	struct v4l2_subdev subdev;
+};
+
+int __msm_gemini_open(struct msm_gemini_device *pgmn_dev);
+int __msm_gemini_release(struct msm_gemini_device *pgmn_dev);
+
+long __msm_gemini_ioctl(struct msm_gemini_device *pgmn_dev,
+	unsigned int cmd, unsigned long arg);
+
+struct msm_gemini_device *__msm_gemini_init(struct platform_device *pdev);
+int __msm_gemini_exit(struct msm_gemini_device *pgmn_dev);
+
+#endif /* MSM_GEMINI_SYNC_H */
diff --git a/drivers/media/platform/msm/camera_v1/imx072.c b/drivers/media/platform/msm/camera_v1/imx072.c
new file mode 100644
index 0000000..29d2118
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/imx072.c
@@ -0,0 +1,1184 @@
+/* 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/delay.h>
+#include <linux/debugfs.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/slab.h>
+#include <media/msm_camera.h>
+#include <mach/gpio.h>
+#include <mach/camera.h>
+#include "imx072.h"
+
+/* SENSOR REGISTER DEFINES */
+#define REG_GROUPED_PARAMETER_HOLD		0x0104
+#define GROUPED_PARAMETER_HOLD_OFF		0x00
+#define GROUPED_PARAMETER_HOLD			0x01
+/* Integration Time */
+#define REG_COARSE_INTEGRATION_TIME		0x0202
+/* Gain */
+#define REG_GLOBAL_GAIN					0x0204
+
+/* PLL registers */
+#define REG_FRAME_LENGTH_LINES			0x0340
+#define REG_LINE_LENGTH_PCK				0x0342
+
+/* 16bit address - 8 bit context register structure */
+#define Q8  0x00000100
+#define Q10 0x00000400
+#define IMX072_MASTER_CLK_RATE 24000000
+#define IMX072_OFFSET		3
+
+/* AF Total steps parameters */
+#define IMX072_AF_I2C_ADDR	0x18
+#define IMX072_TOTAL_STEPS_NEAR_TO_FAR    30
+
+static uint16_t imx072_step_position_table[IMX072_TOTAL_STEPS_NEAR_TO_FAR+1];
+static uint16_t imx072_nl_region_boundary1;
+static uint16_t imx072_nl_region_code_per_step1;
+static uint16_t imx072_l_region_code_per_step = 12;
+static uint16_t imx072_sw_damping_time_wait = 8;
+static uint16_t imx072_af_initial_code = 350;
+static uint16_t imx072_damping_threshold = 10;
+
+struct imx072_work_t {
+	struct work_struct work;
+};
+
+static struct imx072_work_t *imx072_sensorw;
+static struct i2c_client *imx072_client;
+
+struct imx072_ctrl_t {
+	const struct  msm_camera_sensor_info *sensordata;
+
+	uint32_t sensormode;
+	uint32_t fps_divider;/* init to 1 * 0x00000400 */
+	uint32_t pict_fps_divider;/* init to 1 * 0x00000400 */
+	uint16_t fps;
+
+	uint16_t curr_lens_pos;
+	uint16_t curr_step_pos;
+	uint16_t my_reg_gain;
+	uint32_t my_reg_line_count;
+	uint16_t total_lines_per_frame;
+
+	enum imx072_resolution_t prev_res;
+	enum imx072_resolution_t pict_res;
+	enum imx072_resolution_t curr_res;
+	enum imx072_test_mode_t  set_test;
+	enum imx072_cam_mode_t cam_mode;
+};
+
+static uint16_t prev_line_length_pck;
+static uint16_t prev_frame_length_lines;
+static uint16_t snap_line_length_pck;
+static uint16_t snap_frame_length_lines;
+
+static bool CSI_CONFIG;
+static struct imx072_ctrl_t *imx072_ctrl;
+static DECLARE_WAIT_QUEUE_HEAD(imx072_wait_queue);
+DEFINE_MUTEX(imx072_mut);
+
+#ifdef CONFIG_DEBUG_FS
+static int cam_debug_init(void);
+static struct dentry *debugfs_base;
+#endif
+
+static int imx072_i2c_rxdata(unsigned short saddr,
+	unsigned char *rxdata, int length)
+{
+	struct i2c_msg msgs[] = {
+		{
+			.addr  = saddr,
+			.flags = 0,
+			.len   = length,
+			.buf   = rxdata,
+		},
+		{
+			.addr  = saddr,
+			.flags = I2C_M_RD,
+			.len   = length,
+			.buf   = rxdata,
+		},
+	};
+	if (i2c_transfer(imx072_client->adapter, msgs, 2) < 0) {
+		pr_err("imx072_i2c_rxdata faild 0x%x\n", saddr);
+		return -EIO;
+	}
+	return 0;
+}
+
+static int32_t imx072_i2c_txdata(unsigned short saddr,
+				unsigned char *txdata, int length)
+{
+	struct i2c_msg msg[] = {
+		{
+			.addr = saddr,
+			.flags = 0,
+			.len = length,
+			.buf = txdata,
+		 },
+	};
+	if (i2c_transfer(imx072_client->adapter, msg, 1) < 0) {
+		pr_err("imx072_i2c_txdata faild 0x%x\n", saddr);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t imx072_i2c_read(unsigned short raddr,
+	unsigned short *rdata, int rlen)
+{
+	int32_t rc = 0;
+	unsigned char buf[2];
+	if (!rdata)
+		return -EIO;
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (raddr & 0xFF00) >> 8;
+	buf[1] = (raddr & 0x00FF);
+	rc = imx072_i2c_rxdata(imx072_client->addr>>1, buf, rlen);
+	if (rc < 0) {
+		pr_err("imx072_i2c_read 0x%x failed!\n", raddr);
+		return rc;
+	}
+	*rdata = (rlen == 2 ? buf[0] << 8 | buf[1] : buf[0]);
+	CDBG("imx072_i2c_read 0x%x val = 0x%x!\n", raddr, *rdata);
+	return rc;
+}
+
+static int32_t imx072_i2c_write_w_sensor(unsigned short waddr,
+	uint16_t wdata)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[4];
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00) >> 8;
+	buf[1] = (waddr & 0x00FF);
+	buf[2] = (wdata & 0xFF00) >> 8;
+	buf[3] = (wdata & 0x00FF);
+	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, wdata);
+	rc = imx072_i2c_txdata(imx072_client->addr>>1, buf, 4);
+	if (rc < 0) {
+		pr_err("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
+			waddr, wdata);
+	}
+	return rc;
+}
+
+static int32_t imx072_i2c_write_b_sensor(unsigned short waddr,
+	uint8_t bdata)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[3];
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00) >> 8;
+	buf[1] = (waddr & 0x00FF);
+	buf[2] = bdata;
+	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
+	rc = imx072_i2c_txdata(imx072_client->addr>>1, buf, 3);
+	if (rc < 0)
+		pr_err("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
+			waddr, bdata);
+	return rc;
+}
+
+static int32_t imx072_i2c_write_b_af(uint8_t msb, uint8_t lsb)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[2];
+
+	buf[0] = msb;
+	buf[1] = lsb;
+	rc = imx072_i2c_txdata(IMX072_AF_I2C_ADDR>>1, buf, 2);
+	if (rc < 0)
+		pr_err("af_i2c_write faield msb = 0x%x lsb = 0x%x",
+			msb, lsb);
+	return rc;
+}
+
+static int32_t imx072_i2c_write_w_table(struct imx072_i2c_reg_conf const
+					 *reg_conf_tbl, int num)
+{
+	int i;
+	int32_t rc = -EIO;
+	for (i = 0; i < num; i++) {
+		rc = imx072_i2c_write_b_sensor(reg_conf_tbl->waddr,
+			reg_conf_tbl->wdata);
+		if (rc < 0)
+			break;
+		reg_conf_tbl++;
+	}
+	return rc;
+}
+
+static void imx072_group_hold_on(void)
+{
+	imx072_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
+						GROUPED_PARAMETER_HOLD);
+}
+
+static void imx072_group_hold_off(void)
+{
+	imx072_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
+						GROUPED_PARAMETER_HOLD_OFF);
+}
+
+static void imx072_start_stream(void)
+{
+	imx072_i2c_write_b_sensor(0x0100, 0x01);
+}
+
+static void imx072_stop_stream(void)
+{
+	imx072_i2c_write_b_sensor(0x0100, 0x00);
+}
+
+static void imx072_get_pict_fps(uint16_t fps, uint16_t *pfps)
+{
+	/* input fps is preview fps in Q8 format */
+	uint32_t divider, d1, d2;
+
+	d1 = prev_frame_length_lines * 0x00000400 / snap_frame_length_lines;
+	d2 = prev_line_length_pck * 0x00000400 / snap_line_length_pck;
+	divider = d1 * d2 / 0x400;
+
+	/*Verify PCLK settings and frame sizes.*/
+	*pfps = (uint16_t) (fps * divider / 0x400);
+}
+
+static uint16_t imx072_get_prev_lines_pf(void)
+{
+	return prev_frame_length_lines;
+}
+
+static uint16_t imx072_get_prev_pixels_pl(void)
+{
+	return prev_line_length_pck;
+}
+
+static uint16_t imx072_get_pict_lines_pf(void)
+{
+	return snap_frame_length_lines;
+}
+
+static uint16_t imx072_get_pict_pixels_pl(void)
+{
+	return snap_line_length_pck;
+}
+
+static uint32_t imx072_get_pict_max_exp_lc(void)
+{
+	return snap_frame_length_lines  * 24;
+}
+
+static int32_t imx072_set_fps(struct fps_cfg   *fps)
+{
+	uint16_t total_lines_per_frame;
+	int32_t rc = 0;
+	total_lines_per_frame = (uint16_t)
+		((prev_frame_length_lines *
+		imx072_ctrl->fps_divider)/0x400);
+	imx072_ctrl->fps_divider = fps->fps_div;
+	imx072_ctrl->pict_fps_divider = fps->pict_fps_div;
+
+	imx072_group_hold_on();
+	rc = imx072_i2c_write_w_sensor(REG_FRAME_LENGTH_LINES,
+							total_lines_per_frame);
+	imx072_group_hold_off();
+	return rc;
+}
+
+static int32_t imx072_write_exp_gain(uint16_t gain, uint32_t line)
+{
+	uint32_t fl_lines = 0;
+	uint8_t offset;
+	int32_t rc = 0;
+	if (imx072_ctrl->curr_res == imx072_ctrl->prev_res)
+		fl_lines = prev_frame_length_lines;
+	else if (imx072_ctrl->curr_res == imx072_ctrl->pict_res)
+		fl_lines = snap_frame_length_lines;
+	line = (line * imx072_ctrl->fps_divider) / Q10;
+	offset = IMX072_OFFSET;
+	if (line > (fl_lines - offset))
+		fl_lines = line + offset;
+
+	imx072_group_hold_on();
+	rc = imx072_i2c_write_w_sensor(REG_FRAME_LENGTH_LINES, fl_lines);
+	rc = imx072_i2c_write_w_sensor(REG_COARSE_INTEGRATION_TIME, line);
+	rc = imx072_i2c_write_w_sensor(REG_GLOBAL_GAIN, gain);
+	imx072_group_hold_off();
+	return rc;
+}
+
+static int32_t imx072_set_pict_exp_gain(uint16_t gain, uint32_t line)
+{
+	int32_t rc = 0;
+	rc = imx072_write_exp_gain(gain, line);
+	return rc;
+}
+
+static int32_t imx072_sensor_setting(int update_type, int rt)
+{
+
+	int32_t rc = 0;
+	struct msm_camera_csi_params imx072_csi_params;
+
+	imx072_stop_stream();
+	msleep(30);
+	if (update_type == REG_INIT) {
+		msleep(20);
+		CSI_CONFIG = 0;
+		imx072_i2c_write_w_table(imx072_regs.rec_settings,
+			imx072_regs.rec_size);
+	} else if (update_type == UPDATE_PERIODIC) {
+#ifdef CONFIG_DEBUG_FS
+		cam_debug_init();
+#endif
+		msleep(20);
+		if (!CSI_CONFIG) {
+			imx072_csi_params.lane_cnt = 2;
+			imx072_csi_params.data_format = CSI_10BIT;
+			imx072_csi_params.lane_assign = 0xe4;
+			imx072_csi_params.dpcm_scheme = 0;
+			imx072_csi_params.settle_cnt = 0x18;
+			msm_camio_vfe_clk_rate_set(192000000);
+			rc = msm_camio_csi_config(&imx072_csi_params);
+			msleep(100);
+			CSI_CONFIG = 1;
+		}
+		imx072_i2c_write_w_table(
+			imx072_regs.conf_array[rt].conf,
+			imx072_regs.conf_array[rt].size);
+		imx072_start_stream();
+		msleep(30);
+	}
+	return rc;
+}
+
+static int32_t imx072_video_config(int mode)
+{
+
+	int32_t rc = 0;
+	/* change sensor resolution if needed */
+	if (imx072_sensor_setting(UPDATE_PERIODIC,
+		imx072_ctrl->prev_res) < 0)
+		return rc;
+
+	imx072_ctrl->curr_res = imx072_ctrl->prev_res;
+	imx072_ctrl->sensormode = mode;
+	return rc;
+}
+
+static int32_t imx072_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+	/*change sensor resolution if needed */
+	if (imx072_ctrl->curr_res != imx072_ctrl->pict_res) {
+		if (imx072_sensor_setting(UPDATE_PERIODIC,
+					imx072_ctrl->pict_res) < 0)
+			return rc;
+	}
+
+	imx072_ctrl->curr_res = imx072_ctrl->pict_res;
+	imx072_ctrl->sensormode = mode;
+	return rc;
+}
+
+static int32_t imx072_raw_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+	/* change sensor resolution if needed */
+	if (imx072_ctrl->curr_res != imx072_ctrl->pict_res) {
+		if (imx072_sensor_setting(UPDATE_PERIODIC,
+					imx072_ctrl->pict_res) < 0)
+			return rc;
+	}
+
+	imx072_ctrl->curr_res = imx072_ctrl->pict_res;
+	imx072_ctrl->sensormode = mode;
+	return rc;
+}
+
+static int32_t imx072_mode_init(int mode, struct sensor_init_cfg init_info)
+{
+	int32_t rc = 0;
+	CDBG("%s: %d\n", __func__, __LINE__);
+	if (mode != imx072_ctrl->cam_mode) {
+		imx072_ctrl->prev_res = init_info.prev_res;
+		imx072_ctrl->pict_res = init_info.pict_res;
+		imx072_ctrl->cam_mode = mode;
+
+		prev_frame_length_lines =
+			imx072_regs.conf_array[imx072_ctrl->prev_res].
+			conf[IMX072_FRAME_LENGTH_LINES_HI].wdata << 8 |
+			imx072_regs.conf_array[imx072_ctrl->prev_res].
+			conf[IMX072_FRAME_LENGTH_LINES_LO].wdata;
+		prev_line_length_pck =
+			imx072_regs.conf_array[imx072_ctrl->prev_res].
+			conf[IMX072_LINE_LENGTH_PCK_HI].wdata << 8 |
+			imx072_regs.conf_array[imx072_ctrl->prev_res].
+			conf[IMX072_LINE_LENGTH_PCK_LO].wdata;
+		snap_frame_length_lines =
+			imx072_regs.conf_array[imx072_ctrl->pict_res].
+			conf[IMX072_FRAME_LENGTH_LINES_HI].wdata << 8 |
+			imx072_regs.conf_array[imx072_ctrl->pict_res].
+			conf[IMX072_FRAME_LENGTH_LINES_LO].wdata;
+		snap_line_length_pck =
+			imx072_regs.conf_array[imx072_ctrl->pict_res].
+			conf[IMX072_LINE_LENGTH_PCK_HI].wdata << 8 |
+			imx072_regs.conf_array[imx072_ctrl->pict_res].
+			conf[IMX072_LINE_LENGTH_PCK_LO].wdata;
+
+		rc = imx072_sensor_setting(REG_INIT,
+			imx072_ctrl->prev_res);
+	}
+	return rc;
+}
+
+static int32_t imx072_set_sensor_mode(int mode,
+	int res)
+{
+	int32_t rc = 0;
+
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		imx072_ctrl->prev_res = res;
+		rc = imx072_video_config(mode);
+		break;
+	case SENSOR_SNAPSHOT_MODE:
+		imx072_ctrl->pict_res = res;
+		rc = imx072_snapshot_config(mode);
+		break;
+	case SENSOR_RAW_SNAPSHOT_MODE:
+		imx072_ctrl->pict_res = res;
+		rc = imx072_raw_snapshot_config(mode);
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
+#define DIV_CEIL(x, y) ((x/y + ((x%y) ? 1 : 0)))
+static int32_t imx072_move_focus(int direction,
+	int32_t num_steps)
+{
+	int32_t rc = 0;
+	int16_t step_direction, dest_lens_position, dest_step_position;
+	uint8_t code_val_msb, code_val_lsb;
+	int16_t next_lens_position, target_dist, small_step;
+
+	if (direction == MOVE_NEAR)
+		step_direction = 1;
+	else if (direction == MOVE_FAR)
+		step_direction = -1;
+	else {
+		pr_err("Illegal focus direction\n");
+		return -EINVAL;
+	}
+	dest_step_position = imx072_ctrl->curr_step_pos +
+			(step_direction * num_steps);
+
+	if (dest_step_position < 0)
+		dest_step_position = 0;
+	else if (dest_step_position > IMX072_TOTAL_STEPS_NEAR_TO_FAR)
+		dest_step_position = IMX072_TOTAL_STEPS_NEAR_TO_FAR;
+
+	if (dest_step_position == imx072_ctrl->curr_step_pos) {
+		CDBG("imx072 same position No-Move exit\n");
+		return rc;
+	}
+	CDBG("%s Index = [%d]\n", __func__, dest_step_position);
+
+	dest_lens_position = imx072_step_position_table[dest_step_position];
+	CDBG("%s lens_position value = %d\n", __func__, dest_lens_position);
+	target_dist = step_direction * (dest_lens_position -
+		imx072_ctrl->curr_lens_pos);
+	if (step_direction < 0 && (target_dist >=
+		(imx072_step_position_table[imx072_damping_threshold]
+			- imx072_af_initial_code))) {
+		small_step = DIV_CEIL(target_dist, 10);
+		imx072_sw_damping_time_wait = 30;
+	} else {
+		small_step = DIV_CEIL(target_dist, 4);
+		imx072_sw_damping_time_wait = 20;
+	}
+
+	CDBG("%s: small_step:%d, wait_time:%d\n", __func__, small_step,
+		imx072_sw_damping_time_wait);
+	for (next_lens_position = imx072_ctrl->curr_lens_pos +
+		(step_direction * small_step);
+		(step_direction * next_lens_position) <=
+		(step_direction * dest_lens_position);
+		next_lens_position += (step_direction * small_step)) {
+
+		code_val_msb = ((next_lens_position & 0x03F0) >> 4);
+		code_val_lsb = ((next_lens_position & 0x000F) << 4);
+		CDBG("position value = %d\n", next_lens_position);
+		CDBG("movefocus vcm_msb = %d\n", code_val_msb);
+		CDBG("movefocus vcm_lsb = %d\n", code_val_lsb);
+		rc = imx072_i2c_write_b_af(code_val_msb, code_val_lsb);
+		if (rc < 0) {
+			pr_err("imx072_move_focus failed writing i2c\n");
+			return rc;
+			}
+		imx072_ctrl->curr_lens_pos = next_lens_position;
+		usleep(imx072_sw_damping_time_wait*100);
+	}
+	if (imx072_ctrl->curr_lens_pos != dest_lens_position) {
+		code_val_msb = ((dest_lens_position & 0x03F0) >> 4);
+		code_val_lsb = ((dest_lens_position & 0x000F) << 4);
+		CDBG("position value = %d\n", dest_lens_position);
+		CDBG("movefocus vcm_msb = %d\n", code_val_msb);
+		CDBG("movefocus vcm_lsb = %d\n", code_val_lsb);
+		rc = imx072_i2c_write_b_af(code_val_msb, code_val_lsb);
+		if (rc < 0) {
+			pr_err("imx072_move_focus failed writing i2c\n");
+			return rc;
+			}
+		usleep(imx072_sw_damping_time_wait * 100);
+	}
+	imx072_ctrl->curr_lens_pos = dest_lens_position;
+	imx072_ctrl->curr_step_pos = dest_step_position;
+	return rc;
+
+}
+
+static int32_t imx072_init_focus(void)
+{
+	uint8_t i;
+	int32_t rc = 0;
+
+	imx072_step_position_table[0] = imx072_af_initial_code;
+	for (i = 1; i <= IMX072_TOTAL_STEPS_NEAR_TO_FAR; i++) {
+		if (i <= imx072_nl_region_boundary1)
+			imx072_step_position_table[i] =
+				imx072_step_position_table[i-1]
+				+ imx072_nl_region_code_per_step1;
+		else
+			imx072_step_position_table[i] =
+				imx072_step_position_table[i-1]
+				+ imx072_l_region_code_per_step;
+
+		if (imx072_step_position_table[i] > 1023)
+			imx072_step_position_table[i] = 1023;
+	}
+	imx072_ctrl->curr_lens_pos = 0;
+
+	return rc;
+}
+
+static int32_t imx072_set_default_focus(void)
+{
+	int32_t rc = 0;
+	uint8_t code_val_msb, code_val_lsb;
+	int16_t dest_lens_position = 0;
+
+	CDBG("%s Index = [%d]\n", __func__, 0);
+	if (imx072_ctrl->curr_step_pos != 0)
+		rc = imx072_move_focus(MOVE_FAR,
+		imx072_ctrl->curr_step_pos);
+	else {
+		dest_lens_position = imx072_af_initial_code;
+		code_val_msb = ((dest_lens_position & 0x03F0) >> 4);
+		code_val_lsb = ((dest_lens_position & 0x000F) << 4);
+
+		CDBG("position value = %d\n", dest_lens_position);
+		CDBG("movefocus vcm_msb = %d\n", code_val_msb);
+		CDBG("movefocus vcm_lsb = %d\n", code_val_lsb);
+		rc = imx072_i2c_write_b_af(code_val_msb, code_val_lsb);
+		if (rc < 0) {
+			pr_err("imx072_set_default_focus failed writing i2c\n");
+			return rc;
+		}
+
+		imx072_ctrl->curr_lens_pos = dest_lens_position;
+		imx072_ctrl->curr_step_pos = 0;
+
+	}
+	usleep(5000);
+	return rc;
+}
+
+static int32_t imx072_af_power_down(void)
+{
+	int32_t rc = 0;
+	int32_t i = 0;
+	int16_t dest_lens_position = imx072_af_initial_code;
+
+	if (imx072_ctrl->curr_lens_pos != 0) {
+		rc = imx072_set_default_focus();
+		CDBG("%s after imx072_set_default_focus\n", __func__);
+		msleep(40);
+		/*to avoid the sound during the power off.
+		brings the actuator to mechanical infinity gradually.*/
+		for (i = 0; i < IMX072_TOTAL_STEPS_NEAR_TO_FAR; i++) {
+			dest_lens_position = dest_lens_position -
+				(imx072_af_initial_code /
+					IMX072_TOTAL_STEPS_NEAR_TO_FAR);
+			CDBG("position value = %d\n", dest_lens_position);
+			rc = imx072_i2c_write_b_af(
+				((dest_lens_position & 0x03F0) >> 4),
+				((dest_lens_position & 0x000F) << 4));
+			CDBG("count = %d\n", i);
+			msleep(20);
+			if (rc < 0) {
+				pr_err("imx072_set_default_focus failed writing i2c\n");
+				return rc;
+			}
+		}
+		rc = imx072_i2c_write_b_af(0x00, 00);
+		msleep(40);
+	}
+	rc = imx072_i2c_write_b_af(0x80, 00);
+	return rc;
+}
+
+static int32_t imx072_power_down(void)
+{
+	int32_t rc = 0;
+
+	rc = imx072_af_power_down();
+	return rc;
+}
+
+static int imx072_probe_init_done(const struct msm_camera_sensor_info *data)
+{
+	pr_err("probe done\n");
+	gpio_free(data->sensor_reset);
+	return 0;
+}
+
+static int imx072_probe_init_sensor(
+	const struct msm_camera_sensor_info *data)
+{
+	int32_t rc = 0;
+	uint16_t chipid = 0;
+
+	CDBG("%s: %d\n", __func__, __LINE__);
+	rc = gpio_request(data->sensor_reset, "imx072");
+	CDBG(" imx072_probe_init_sensor\n");
+	if (!rc) {
+		pr_err("sensor_reset = %d\n", rc);
+		gpio_direction_output(data->sensor_reset, 0);
+		msleep(50);
+		gpio_set_value_cansleep(data->sensor_reset, 1);
+		msleep(20);
+	} else
+		goto gpio_req_fail;
+
+	CDBG(" imx072_probe_init_sensor is called\n");
+	rc = imx072_i2c_read(0x0, &chipid, 2);
+	CDBG("ID: %d\n", chipid);
+	/* 4. Compare sensor ID to IMX072 ID: */
+	if (chipid != 0x0045) {
+		rc = -ENODEV;
+		pr_err("imx072_probe_init_sensor chip id doesnot match\n");
+		goto init_probe_fail;
+	}
+
+	return rc;
+init_probe_fail:
+	pr_err(" imx072_probe_init_sensor fails\n");
+	gpio_set_value_cansleep(data->sensor_reset, 0);
+	imx072_probe_init_done(data);
+	if (data->vcm_enable) {
+		int ret = gpio_request(data->vcm_pwd, "imx072_af");
+		if (!ret) {
+			gpio_direction_output(data->vcm_pwd, 0);
+			msleep(20);
+			gpio_free(data->vcm_pwd);
+		}
+	}
+gpio_req_fail:
+	return rc;
+}
+
+int imx072_sensor_open_init(const struct msm_camera_sensor_info *data)
+{
+	int32_t rc = 0;
+
+	CDBG("%s: %d\n", __func__, __LINE__);
+	imx072_ctrl = kzalloc(sizeof(struct imx072_ctrl_t), GFP_KERNEL);
+	if (!imx072_ctrl) {
+		pr_err("imx072_init failed!\n");
+		rc = -ENOMEM;
+		goto init_done;
+	}
+	imx072_ctrl->fps_divider = 1 * 0x00000400;
+	imx072_ctrl->pict_fps_divider = 1 * 0x00000400;
+	imx072_ctrl->set_test = TEST_OFF;
+	imx072_ctrl->cam_mode = MODE_INVALID;
+
+	if (data)
+		imx072_ctrl->sensordata = data;
+	if (rc < 0) {
+		pr_err("Calling imx072_sensor_open_init fail1\n");
+		return rc;
+	}
+	CDBG("%s: %d\n", __func__, __LINE__);
+	/* enable mclk first */
+	msm_camio_clk_rate_set(IMX072_MASTER_CLK_RATE);
+	rc = imx072_probe_init_sensor(data);
+	if (rc < 0)
+		goto init_fail;
+
+	imx072_init_focus();
+	imx072_ctrl->fps = 30*Q8;
+	if (rc < 0) {
+		gpio_set_value_cansleep(data->sensor_reset, 0);
+		goto init_fail;
+	} else
+		goto init_done;
+init_fail:
+	pr_err("init_fail\n");
+	imx072_probe_init_done(data);
+init_done:
+	pr_err("init_done\n");
+	return rc;
+}
+
+static int imx072_init_client(struct i2c_client *client)
+{
+	/* Initialize the MSM_CAMI2C Chip */
+	init_waitqueue_head(&imx072_wait_queue);
+	return 0;
+}
+
+static const struct i2c_device_id imx072_i2c_id[] = {
+	{"imx072", 0},
+	{ }
+};
+
+static int imx072_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+	CDBG("imx072_probe called!\n");
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		pr_err("i2c_check_functionality failed\n");
+		goto probe_failure;
+	}
+
+	imx072_sensorw = kzalloc(sizeof(struct imx072_work_t),
+			GFP_KERNEL);
+	if (!imx072_sensorw) {
+		pr_err("kzalloc failed.\n");
+		rc = -ENOMEM;
+		goto probe_failure;
+	}
+
+	i2c_set_clientdata(client, imx072_sensorw);
+	imx072_init_client(client);
+	imx072_client = client;
+
+	msleep(50);
+
+	CDBG("imx072_probe successed! rc = %d\n", rc);
+	return 0;
+
+probe_failure:
+	pr_err("imx072_probe failed! rc = %d\n", rc);
+	return rc;
+}
+
+static int imx072_send_wb_info(struct wb_info_cfg *wb)
+{
+	return 0;
+
+}
+
+static int __exit imx072_remove(struct i2c_client *client)
+{
+	struct imx072_work_t_t *sensorw = i2c_get_clientdata(client);
+	free_irq(client->irq, sensorw);
+	imx072_client = NULL;
+	kfree(sensorw);
+	return 0;
+}
+
+static struct i2c_driver imx072_i2c_driver = {
+	.id_table = imx072_i2c_id,
+	.probe  = imx072_i2c_probe,
+	.remove = __exit_p(imx072_i2c_remove),
+	.driver = {
+		.name = "imx072",
+	},
+};
+
+int imx072_sensor_config(void __user *argp)
+{
+	struct sensor_cfg_data cdata;
+	long   rc = 0;
+	if (copy_from_user(&cdata,
+		(void *)argp,
+		sizeof(struct sensor_cfg_data)))
+		return -EFAULT;
+	mutex_lock(&imx072_mut);
+	CDBG("imx072_sensor_config: cfgtype = %d\n",
+		 cdata.cfgtype);
+	switch (cdata.cfgtype) {
+	case CFG_GET_PICT_FPS:
+		imx072_get_pict_fps(
+			cdata.cfg.gfps.prevfps,
+			&(cdata.cfg.gfps.pictfps));
+
+		if (copy_to_user((void *)argp,
+			&cdata,
+			sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+	case CFG_GET_PREV_L_PF:
+		cdata.cfg.prevl_pf =
+		imx072_get_prev_lines_pf();
+
+		if (copy_to_user((void *)argp,
+			&cdata,
+			sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+	case CFG_GET_PREV_P_PL:
+		cdata.cfg.prevp_pl =
+			imx072_get_prev_pixels_pl();
+
+		if (copy_to_user((void *)argp,
+			&cdata,
+			sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+	case CFG_GET_PICT_L_PF:
+		cdata.cfg.pictl_pf =
+			imx072_get_pict_lines_pf();
+
+		if (copy_to_user((void *)argp,
+			&cdata,
+			sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+	case CFG_GET_PICT_P_PL:
+		cdata.cfg.pictp_pl =
+			imx072_get_pict_pixels_pl();
+
+		if (copy_to_user((void *)argp,
+			&cdata,
+			sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+	case CFG_GET_PICT_MAX_EXP_LC:
+		cdata.cfg.pict_max_exp_lc =
+			imx072_get_pict_max_exp_lc();
+
+		if (copy_to_user((void *)argp,
+			&cdata,
+			sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+	case CFG_SET_FPS:
+	case CFG_SET_PICT_FPS:
+		rc = imx072_set_fps(&(cdata.cfg.fps));
+		break;
+	case CFG_SET_EXP_GAIN:
+		rc = imx072_write_exp_gain(
+			cdata.cfg.exp_gain.gain,
+			cdata.cfg.exp_gain.line);
+		break;
+	case CFG_SET_PICT_EXP_GAIN:
+		rc = imx072_set_pict_exp_gain(
+			cdata.cfg.exp_gain.gain,
+			cdata.cfg.exp_gain.line);
+		break;
+	case CFG_SET_MODE:
+		rc = imx072_set_sensor_mode(cdata.mode, cdata.rs);
+		break;
+	case CFG_PWR_DOWN:
+		rc = imx072_power_down();
+		break;
+	case CFG_MOVE_FOCUS:
+		rc = imx072_move_focus(cdata.cfg.focus.dir,
+				cdata.cfg.focus.steps);
+		break;
+	case CFG_SET_DEFAULT_FOCUS:
+		imx072_set_default_focus();
+		break;
+	case CFG_GET_AF_MAX_STEPS:
+		cdata.max_steps = IMX072_TOTAL_STEPS_NEAR_TO_FAR;
+		if (copy_to_user((void *)argp,
+			&cdata,
+			sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+	case CFG_SET_EFFECT:
+		break;
+	case CFG_SEND_WB_INFO:
+		rc = imx072_send_wb_info(
+			&(cdata.cfg.wb_info));
+	break;
+	case CFG_SENSOR_INIT:
+		rc = imx072_mode_init(cdata.mode,
+				cdata.cfg.init_info);
+	break;
+	case CFG_SET_LENS_SHADING:
+		break;
+	default:
+		rc = -EFAULT;
+		break;
+	}
+
+	mutex_unlock(&imx072_mut);
+
+	return rc;
+}
+
+static int imx072_sensor_release(void)
+{
+	int rc = -EBADF;
+	mutex_lock(&imx072_mut);
+	imx072_power_down();
+	gpio_set_value_cansleep(imx072_ctrl->sensordata->sensor_reset, 0);
+	msleep(20);
+	gpio_free(imx072_ctrl->sensordata->sensor_reset);
+	if (imx072_ctrl->sensordata->vcm_enable) {
+		gpio_set_value_cansleep(imx072_ctrl->sensordata->vcm_pwd, 0);
+		gpio_free(imx072_ctrl->sensordata->vcm_pwd);
+	}
+	kfree(imx072_ctrl);
+	imx072_ctrl = NULL;
+	pr_err("imx072_release completed\n");
+	mutex_unlock(&imx072_mut);
+
+	return rc;
+}
+
+static int imx072_sensor_probe(const struct msm_camera_sensor_info *info,
+		struct msm_sensor_ctrl *s)
+{
+	int rc = 0;
+	rc = i2c_add_driver(&imx072_i2c_driver);
+	if (rc < 0 || imx072_client == NULL) {
+		rc = -ENOTSUPP;
+		pr_err("I2C add driver failed");
+		goto probe_fail;
+	}
+	msm_camio_clk_rate_set(IMX072_MASTER_CLK_RATE);
+	rc = imx072_probe_init_sensor(info);
+	if (rc < 0)
+		goto probe_fail;
+	s->s_init = imx072_sensor_open_init;
+	s->s_release = imx072_sensor_release;
+	s->s_config  = imx072_sensor_config;
+	s->s_mount_angle = info->sensor_platform_info->mount_angle;
+
+	gpio_set_value_cansleep(info->sensor_reset, 0);
+	imx072_probe_init_done(info);
+	if (info->vcm_enable) {
+		rc = gpio_request(info->vcm_pwd, "imx072_af");
+		if (!rc) {
+			gpio_direction_output(info->vcm_pwd, 0);
+			msleep(20);
+			gpio_free(info->vcm_pwd);
+		} else
+			return rc;
+	}
+	pr_info("imx072_sensor_probe : SUCCESS\n");
+	return rc;
+
+probe_fail:
+	pr_err("imx072_sensor_probe: SENSOR PROBE FAILS!\n");
+	return rc;
+}
+
+static int __imx072_probe(struct platform_device *pdev)
+{
+	return msm_camera_drv_start(pdev, imx072_sensor_probe);
+}
+
+static struct platform_driver msm_camera_driver = {
+	.probe = __imx072_probe,
+	.driver = {
+		.name = "msm_camera_imx072",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init imx072_init(void)
+{
+	return platform_driver_register(&msm_camera_driver);
+}
+
+module_init(imx072_init);
+void imx072_exit(void)
+{
+	i2c_del_driver(&imx072_i2c_driver);
+}
+MODULE_DESCRIPTION("Aptina 8 MP Bayer sensor driver");
+MODULE_LICENSE("GPL v2");
+
+#ifdef CONFIG_DEBUG_FS
+static bool streaming = 1;
+
+static int cam_debug_stream_set(void *data, u64 val)
+{
+	int rc = 0;
+
+	if (val) {
+		imx072_start_stream();
+		streaming = 1;
+	} else {
+		imx072_stop_stream();
+		streaming = 0;
+	}
+
+	return rc;
+}
+
+static int cam_debug_stream_get(void *data, u64 *val)
+{
+	*val = streaming;
+	return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(cam_stream, cam_debug_stream_get,
+			cam_debug_stream_set, "%llu\n");
+
+
+
+static int imx072_set_af_codestep(void *data, u64 val)
+{
+	imx072_l_region_code_per_step = val;
+	imx072_init_focus();
+	return 0;
+}
+
+static int imx072_get_af_codestep(void *data, u64 *val)
+{
+	*val = imx072_l_region_code_per_step;
+	return 0;
+}
+
+static uint16_t imx072_linear_total_step = IMX072_TOTAL_STEPS_NEAR_TO_FAR;
+static int imx072_set_linear_total_step(void *data, u64 val)
+{
+	imx072_linear_total_step = val;
+	return 0;
+}
+
+static int imx072_af_linearity_test(void *data, u64 *val)
+{
+	int i = 0;
+
+	imx072_set_default_focus();
+	msleep(3000);
+	for (i = 0; i < imx072_linear_total_step; i++) {
+		imx072_move_focus(MOVE_NEAR, 1);
+		CDBG("moved to index =[%d]\n", i);
+		msleep(1000);
+	}
+
+	for (i = 0; i < imx072_linear_total_step; i++) {
+		imx072_move_focus(MOVE_FAR, 1);
+		CDBG("moved to index =[%d]\n", i);
+		msleep(1000);
+	}
+	return 0;
+}
+
+static uint16_t imx072_step_val = IMX072_TOTAL_STEPS_NEAR_TO_FAR;
+static uint8_t imx072_step_dir = MOVE_NEAR;
+static int imx072_af_step_config(void *data, u64 val)
+{
+	imx072_step_val = val & 0xFFFF;
+	imx072_step_dir = (val >> 16) & 0x1;
+	return 0;
+}
+
+static int imx072_af_step(void *data, u64 *val)
+{
+	int i = 0;
+	int dir = MOVE_NEAR;
+	imx072_set_default_focus();
+	msleep(3000);
+	if (imx072_step_dir == 1)
+		dir = MOVE_FAR;
+
+	for (i = 0; i < imx072_step_val; i += 4) {
+		imx072_move_focus(dir, 4);
+		msleep(1000);
+	}
+	imx072_set_default_focus();
+	msleep(3000);
+	return 0;
+}
+
+static int imx072_af_set_resolution(void *data, u64 val)
+{
+	imx072_init_focus();
+	return 0;
+}
+
+static int imx072_af_get_resolution(void *data, u64 *val)
+{
+	*val = 0xFF;
+	return 0;
+}
+
+
+
+DEFINE_SIMPLE_ATTRIBUTE(af_codeperstep, imx072_get_af_codestep,
+			imx072_set_af_codestep, "%llu\n");
+
+DEFINE_SIMPLE_ATTRIBUTE(af_linear, imx072_af_linearity_test,
+			imx072_set_linear_total_step, "%llu\n");
+
+DEFINE_SIMPLE_ATTRIBUTE(af_step, imx072_af_step,
+			imx072_af_step_config, "%llu\n");
+
+DEFINE_SIMPLE_ATTRIBUTE(af_step_res, imx072_af_get_resolution,
+			imx072_af_set_resolution, "%llu\n");
+
+static int cam_debug_init(void)
+{
+	struct dentry *cam_dir;
+	debugfs_base = debugfs_create_dir("sensor", NULL);
+	if (!debugfs_base)
+		return -ENOMEM;
+
+	cam_dir = debugfs_create_dir("imx072", debugfs_base);
+	if (!cam_dir)
+		return -ENOMEM;
+
+	if (!debugfs_create_file("stream", S_IRUGO | S_IWUSR, cam_dir,
+							 NULL, &cam_stream))
+		return -ENOMEM;
+
+	if (!debugfs_create_file("af_codeperstep", S_IRUGO | S_IWUSR, cam_dir,
+							 NULL, &af_codeperstep))
+		return -ENOMEM;
+	if (!debugfs_create_file("af_linear", S_IRUGO | S_IWUSR, cam_dir,
+							 NULL, &af_linear))
+		return -ENOMEM;
+	if (!debugfs_create_file("af_step", S_IRUGO | S_IWUSR, cam_dir,
+							 NULL, &af_step))
+		return -ENOMEM;
+
+	if (!debugfs_create_file("af_step_res", S_IRUGO | S_IWUSR, cam_dir,
+							 NULL, &af_step_res))
+		return -ENOMEM;
+
+	return 0;
+}
+#endif
diff --git a/drivers/media/platform/msm/camera_v1/imx072.h b/drivers/media/platform/msm/camera_v1/imx072.h
new file mode 100644
index 0000000..95f688c
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/imx072.h
@@ -0,0 +1,79 @@
+/* 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.
+ *
+ */
+
+#ifndef IMX072_H
+#define IMX072_H
+#include <linux/types.h>
+#include <mach/board.h>
+extern struct imx072_reg imx072_regs;
+
+struct imx072_i2c_reg_conf {
+	unsigned short waddr;
+	unsigned short wdata;
+};
+
+struct imx072_i2c_conf_array {
+	struct imx072_i2c_reg_conf *conf;
+	unsigned short size;
+};
+
+enum imx072_test_mode_t {
+	TEST_OFF,
+	TEST_1,
+	TEST_2,
+	TEST_3
+};
+
+enum imx072_resolution_t {
+	QTR_2D_SIZE,
+	FULL_2D_SIZE,
+	QTR_3D_SIZE,
+	FULL_3D_SIZE,
+	INVALID_SIZE
+};
+enum imx072_setting {
+	RES_PREVIEW,
+	RES_CAPTURE,
+	RES_3D_PREVIEW,
+	RES_3D_CAPTURE
+};
+enum imx072_cam_mode_t {
+	MODE_2D_RIGHT,
+	MODE_2D_LEFT,
+	MODE_3D,
+	MODE_INVALID
+};
+enum imx072_reg_update {
+	/* Sensor egisters that need to be updated during initialization */
+	REG_INIT,
+	/* Sensor egisters that needs periodic I2C writes */
+	UPDATE_PERIODIC,
+	/* All the sensor Registers will be updated */
+	UPDATE_ALL,
+	/* Not valid update */
+	UPDATE_INVALID
+};
+
+enum imx072_reg_mode {
+	IMX072_FRAME_LENGTH_LINES_HI = 0,
+	IMX072_FRAME_LENGTH_LINES_LO,
+	IMX072_LINE_LENGTH_PCK_HI,
+	IMX072_LINE_LENGTH_PCK_LO,
+};
+
+struct imx072_reg {
+	const struct imx072_i2c_reg_conf *rec_settings;
+	const unsigned short rec_size;
+	const struct imx072_i2c_conf_array *conf_array;
+};
+#endif /* IMX072_H */
diff --git a/drivers/media/platform/msm/camera_v1/imx072_reg.c b/drivers/media/platform/msm/camera_v1/imx072_reg.c
new file mode 100644
index 0000000..fc07e0f
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/imx072_reg.c
@@ -0,0 +1,153 @@
+/* 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 "imx072.h"
+
+struct imx072_i2c_reg_conf imx072_prev_settings[] = {
+	{0x0340, 0x03},/*frame_length*/
+	{0x0341, 0xF7},/*frame_length*/
+	{0x0342, 0x0A},/*line_length*/
+	{0x0343, 0xE0},/*line_length*/
+	{0x0344, 0x00},/*x_addr_start*/
+	{0x0345, 0x00},/*x_addr_start*/
+	{0x0346, 0x00},/*y_addr_start*/
+	{0x0347, 0x00},/*y_addr_start*/
+	{0x0348, 0x0A},/*x_addr_end*/
+	{0x0349, 0x2F},/*x_addr_end*/
+	{0x034A, 0x07},/*y_addr_end*/
+	{0x034B, 0xA7},/*y_addr_end*/
+	{0x034C, 0x05},/*x_out_size*/
+	{0x034D, 0x18},/*x_out_size*/
+	{0x034E, 0x03},/*y_out_size*/
+	{0x034F, 0xD4},/*y_out_size*/
+	{0x0381, 0x01},/*x_even_inc*/
+	{0x0383, 0x03},/*x_odd_inc*/
+	{0x0385, 0x01},/*y_even_inc*/
+	{0x0387, 0x03},/*y_odd_inc*/
+	{0x3016, 0x06},/*VMODEADD*/
+	{0x3017, 0x40},
+	{0x3069, 0x24},
+	{0x306A, 0x00},
+	{0x306B, 0xCB},
+	{0x306C, 0x07},
+	{0x30E8, 0x86},
+	{0x3304, 0x03},
+	{0x3305, 0x02},
+	{0x3306, 0x0A},
+	{0x3307, 0x02},
+	{0x3308, 0x11},
+	{0x3309, 0x04},
+	{0x330A, 0x05},
+	{0x330B, 0x04},
+	{0x330C, 0x05},
+	{0x330D, 0x04},
+	{0x330E, 0x01},
+	{0x3301, 0x80},
+};
+
+struct imx072_i2c_reg_conf imx072_snap_settings[] = {
+	{0x0340, 0x07},/*frame_length*/
+	{0x0341, 0xEE},/*frame_length*/
+	{0x0342, 0x0A},/*line_length*/
+	{0x0343, 0xE0},/*line_length*/
+	{0x0344, 0x00},/*x_addr_start*/
+	{0x0345, 0x00},/*x_addr_start*/
+	{0x0346, 0x00},/*y_addr_start*/
+	{0x0347, 0x00},/*y_addr_start*/
+	{0x0348, 0x0A},/*x_addr_end*/
+	{0x0349, 0x2F},/*x_addr_end*/
+	{0x034A, 0x07},/*y_addr_end*/
+	{0x034B, 0xA7},/*y_addr_end*/
+	{0x034C, 0x0A},/*x_out_size*/
+	{0x034D, 0x30},/*x_out_size*/
+	{0x034E, 0x07},/*y_out_size*/
+	{0x034F, 0xA8},/*y_out_size*/
+	{0x0381, 0x01},/*x_even_inc*/
+	{0x0383, 0x01},/*x_odd_inc*/
+	{0x0385, 0x01},/*y_even_inc*/
+	{0x0387, 0x01},/*y_odd_inc*/
+	{0x3016, 0x06},/*VMODEADD*/
+	{0x3017, 0x40},
+	{0x3069, 0x24},
+	{0x306A, 0x00},
+	{0x306B, 0xCB},
+	{0x306C, 0x07},
+	{0x30E8, 0x06},
+	{0x3304, 0x05},
+	{0x3305, 0x04},
+	{0x3306, 0x15},
+	{0x3307, 0x02},
+	{0x3308, 0x11},
+	{0x3309, 0x07},
+	{0x330A, 0x05},
+	{0x330B, 0x04},
+	{0x330C, 0x05},
+	{0x330D, 0x04},
+	{0x330E, 0x01},
+	{0x3301, 0x00},
+};
+
+struct imx072_i2c_reg_conf imx072_recommend_settings[] = {
+	{0x0307, 0x12},
+	{0x302B, 0x4B},
+	{0x0101, 0x03},
+	{0x300A, 0x80},
+	{0x3014, 0x08},
+	{0x3015, 0x37},
+	{0x3017, 0x40},
+	{0x301C, 0x01},
+	{0x3031, 0x28},
+	{0x3040, 0x00},
+	{0x3041, 0x60},
+	{0x3051, 0x24},
+	{0x3053, 0x34},
+	{0x3055, 0x3B},
+	{0x3057, 0xC0},
+	{0x3060, 0x30},
+	{0x3065, 0x00},
+	{0x30AA, 0x88},
+	{0x30AB, 0x1C},
+	{0x30B0, 0x32},
+	{0x30B2, 0x83},
+	{0x30D3, 0x04},
+	{0x310E, 0xDD},
+	{0x31A4, 0xD8},
+	{0x31A6, 0x17},
+	{0x31AC, 0xCF},
+	{0x31AE, 0xF1},
+	{0x31B4, 0xD8},
+	{0x31B6, 0x17},
+	{0x3304, 0x05},
+	{0x3305, 0x04},
+	{0x3306, 0x15},
+	{0x3307, 0x02},
+	{0x3308, 0x11},
+	{0x3309, 0x07},
+	{0x330A, 0x05},
+	{0x330B, 0x04},
+	{0x330C, 0x05},
+	{0x330D, 0x04},
+	{0x330E, 0x01},
+	{0x30d8, 0x20},
+};
+
+struct imx072_i2c_conf_array imx072_confs[] = {
+	{&imx072_prev_settings[0], ARRAY_SIZE(imx072_prev_settings)},
+	{&imx072_snap_settings[0], ARRAY_SIZE(imx072_snap_settings)},
+};
+
+struct imx072_reg imx072_regs = {
+	.rec_settings = &imx072_recommend_settings[0],
+	.rec_size = ARRAY_SIZE(imx072_recommend_settings),
+	.conf_array = &imx072_confs[0],
+};
diff --git a/drivers/media/platform/msm/camera_v1/imx074.c b/drivers/media/platform/msm/camera_v1/imx074.c
new file mode 100644
index 0000000..511c7db
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/imx074.c
@@ -0,0 +1,1414 @@
+/* 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/slab.h>
+#include <media/msm_camera.h>
+#include <mach/gpio.h>
+#include <mach/camera.h>
+#include <asm/mach-types.h>
+#include "imx074.h"
+
+/*SENSOR REGISTER DEFINES*/
+#define	IMX074_EEPROM_SLAVE_ADDR			0x52
+#define REG_GROUPED_PARAMETER_HOLD			0x0104
+#define GROUPED_PARAMETER_HOLD_OFF			0x00
+#define GROUPED_PARAMETER_HOLD				0x01
+#define REG_MODE_SELECT					0x100
+#define MODE_SELECT_STANDBY_MODE			0x00
+#define MODE_SELECT_STREAM				0x01
+/* Integration Time */
+#define REG_COARSE_INTEGRATION_TIME_HI			0x0202
+#define REG_COARSE_INTEGRATION_TIME_LO			0x0203
+/* Gain */
+#define REG_ANALOGUE_GAIN_CODE_GLOBAL_HI		0x0204
+#define REG_ANALOGUE_GAIN_CODE_GLOBAL_LO		0x0205
+/* PLL registers */
+#define REG_PLL_MULTIPLIER				0x0307
+#define REG_PRE_PLL_CLK_DIV				0x0305
+#define REG_PLSTATIM					0x302b
+#define REG_3024					0x3024
+#define REG_IMAGE_ORIENTATION				0x0101
+#define REG_VNDMY_ABLMGSHLMT				0x300a
+#define REG_Y_OPBADDR_START_DI				0x3014
+#define REG_3015					0x3015
+#define REG_301C					0x301C
+#define REG_302C					0x302C
+#define REG_3031					0x3031
+#define REG_3041					0x3041
+#define REG_3051					0x3051
+#define REG_3053					0x3053
+#define REG_3057					0x3057
+#define REG_305C					0x305C
+#define REG_305D					0x305D
+#define REG_3060					0x3060
+#define REG_3065					0x3065
+#define REG_30AA					0x30AA
+#define REG_30AB					0x30AB
+#define REG_30B0					0x30B0
+#define REG_30B2					0x30B2
+#define REG_30D3					0x30D3
+#define REG_3106					0x3106
+#define REG_310C					0x310C
+#define REG_3304					0x3304
+#define REG_3305					0x3305
+#define REG_3306					0x3306
+#define REG_3307					0x3307
+#define REG_3308					0x3308
+#define REG_3309					0x3309
+#define REG_330A					0x330A
+#define REG_330B					0x330B
+#define REG_330C					0x330C
+#define REG_330D					0x330D
+#define REG_330F					0x330F
+#define REG_3381					0x3381
+
+/* mode setting */
+#define REG_FRAME_LENGTH_LINES_HI			0x0340
+#define REG_FRAME_LENGTH_LINES_LO			0x0341
+#define REG_YADDR_START					0x0347
+#define REG_YAAAR_END					0x034b
+#define REG_X_OUTPUT_SIZE_MSB				0x034c
+#define REG_X_OUTPUT_SIZE_LSB				0x034d
+#define REG_Y_OUTPUT_SIZE_MSB				0x034e
+#define REG_Y_OUTPUT_SIZE_LSB				0x034f
+#define REG_X_EVEN_INC					0x0381
+#define REG_X_ODD_INC					0x0383
+#define REG_Y_EVEN_INC					0x0385
+#define REG_Y_ODD_INC					0x0387
+#define REG_HMODEADD					0x3001
+#define REG_VMODEADD					0x3016
+#define REG_VAPPLINE_START				0x3069
+#define REG_VAPPLINE_END				0x306b
+#define REG_SHUTTER					0x3086
+#define REG_HADDAVE					0x30e8
+#define REG_LANESEL					0x3301
+/* Test Pattern */
+#define REG_TEST_PATTERN_MODE				0x0601
+
+#define REG_LINE_LENGTH_PCK_HI				0x0342
+#define REG_LINE_LENGTH_PCK_LO				0x0343
+/*..... TYPE DECLARATIONS.....*/
+#define	IMX074_OFFSET					3
+#define	IMX074_DEFAULT_MASTER_CLK_RATE			24000000
+/* Full	Size */
+#define	IMX074_FULL_SIZE_WIDTH				4208
+#define	IMX074_FULL_SIZE_HEIGHT				3120
+#define	IMX074_FULL_SIZE_DUMMY_PIXELS			0
+#define	IMX074_FULL_SIZE_DUMMY_LINES			0
+/* Quarter Size	*/
+#define	IMX074_QTR_SIZE_WIDTH				2104
+#define	IMX074_QTR_SIZE_HEIGHT				1560
+#define	IMX074_QTR_SIZE_DUMMY_PIXELS			0
+#define	IMX074_QTR_SIZE_DUMMY_LINES			0
+/* Blanking as measured	on the scope */
+/* Full	Size */
+#define	IMX074_HRZ_FULL_BLK_PIXELS			264
+#define	IMX074_VER_FULL_BLK_LINES			96
+/* Quarter Size	*/
+#define	IMX074_HRZ_QTR_BLK_PIXELS			2368
+#define	IMX074_VER_QTR_BLK_LINES			21
+#define	Q8						0x100
+#define	Q10						0x400
+#define	IMX074_AF_I2C_SLAVE_ID				0x72
+#define	IMX074_STEPS_NEAR_TO_CLOSEST_INF		52
+#define	IMX074_TOTAL_STEPS_NEAR_TO_FAR			52
+static uint32_t imx074_l_region_code_per_step = 2;
+
+struct imx074_work_t {
+	struct work_struct work;
+};
+
+static struct imx074_work_t *imx074_sensorw;
+static struct i2c_client *imx074_client;
+
+struct imx074_ctrl_t {
+	const struct msm_camera_sensor_info *sensordata;
+	uint32_t sensormode;
+	uint32_t fps_divider;/* init to 1 * 0x00000400 */
+	uint32_t pict_fps_divider;/* init to 1 * 0x00000400 */
+	uint16_t fps;
+	int16_t curr_lens_pos;
+	uint16_t curr_step_pos;
+	uint16_t my_reg_gain;
+	uint32_t my_reg_line_count;
+	uint16_t total_lines_per_frame;
+	enum imx074_resolution_t prev_res;
+	enum imx074_resolution_t pict_res;
+	enum imx074_resolution_t curr_res;
+	enum imx074_test_mode_t set_test;
+	unsigned short imgaddr;
+};
+static uint8_t imx074_delay_msecs_stdby = 5;
+static uint16_t imx074_delay_msecs_stream = 5;
+static int32_t config_csi;
+
+static struct imx074_ctrl_t *imx074_ctrl;
+static DECLARE_WAIT_QUEUE_HEAD(imx074_wait_queue);
+DEFINE_MUTEX(imx074_mut);
+
+/*=============================================================*/
+
+static int imx074_i2c_rxdata(unsigned short saddr,
+	unsigned char *rxdata, int length)
+{
+	struct i2c_msg msgs[] = {
+		{
+			.addr  = saddr,
+			.flags = 0,
+			.len   = 2,
+			.buf   = rxdata,
+		},
+		{
+			.addr  = saddr,
+			.flags = I2C_M_RD,
+			.len   = 2,
+			.buf   = rxdata,
+		},
+	};
+	if (i2c_transfer(imx074_client->adapter, msgs, 2) < 0) {
+		CDBG("imx074_i2c_rxdata failed!\n");
+		return -EIO;
+	}
+	return 0;
+}
+static int32_t imx074_i2c_txdata(unsigned short saddr,
+				unsigned char *txdata, int length)
+{
+	struct i2c_msg msg[] = {
+		{
+			.addr = saddr,
+			.flags = 0,
+			.len = length,
+			.buf = txdata,
+		 },
+	};
+	if (i2c_transfer(imx074_client->adapter, msg, 1) < 0) {
+		CDBG("imx074_i2c_txdata faild 0x%x\n", imx074_client->addr);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+
+static int32_t imx074_i2c_read(unsigned short raddr,
+	unsigned short *rdata, int rlen)
+{
+	int32_t rc = 0;
+	unsigned char buf[2];
+	if (!rdata)
+		return -EIO;
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (raddr & 0xFF00) >> 8;
+	buf[1] = (raddr & 0x00FF);
+	rc = imx074_i2c_rxdata(imx074_client->addr, buf, rlen);
+	if (rc < 0) {
+		CDBG("imx074_i2c_read 0x%x failed!\n", raddr);
+		return rc;
+	}
+	*rdata = (rlen == 2 ? buf[0] << 8 | buf[1] : buf[0]);
+	return rc;
+}
+
+static int imx074_af_i2c_rxdata_b(unsigned short saddr,
+	unsigned char *rxdata, int length)
+{
+	struct i2c_msg msgs[] = {
+		{
+		.addr  = saddr,
+		.flags = 0,
+		.len   = 1,
+		.buf   = rxdata,
+		},
+		{
+		.addr  = saddr,
+		.flags = I2C_M_RD,
+		.len   = 1,
+		.buf   = rxdata,
+		},
+	};
+
+	if (i2c_transfer(imx074_client->adapter, msgs, 2) < 0) {
+		CDBG("imx074_i2c_rxdata_b failed!\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t imx074_i2c_read_w_eeprom(unsigned short raddr,
+	unsigned short *rdata)
+{
+	int32_t rc;
+	unsigned char buf;
+	if (!rdata)
+		return -EIO;
+	/* Read 2 bytes in sequence */
+	buf = (raddr & 0x00FF);
+	rc = imx074_af_i2c_rxdata_b(IMX074_EEPROM_SLAVE_ADDR, &buf, 1);
+	if (rc < 0) {
+		CDBG("imx074_i2c_read_eeprom 0x%x failed!\n", raddr);
+		return rc;
+	}
+	*rdata = buf<<8;
+
+	/* Read Second byte of data */
+	buf = (raddr & 0x00FF) + 1;
+	rc = imx074_af_i2c_rxdata_b(IMX074_EEPROM_SLAVE_ADDR, &buf, 1);
+	if (rc < 0) {
+		CDBG("imx074_i2c_read_eeprom 0x%x failed!\n", raddr);
+		return rc;
+	}
+	*rdata |= buf;
+	return rc;
+}
+
+static int32_t imx074_i2c_write_b_sensor(unsigned short waddr, uint8_t bdata)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[3];
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00) >> 8;
+	buf[1] = (waddr & 0x00FF);
+	buf[2] = bdata;
+	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
+	rc = imx074_i2c_txdata(imx074_client->addr, buf, 3);
+	if (rc < 0) {
+		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
+			waddr, bdata);
+	}
+	return rc;
+}
+static int16_t imx074_i2c_write_b_af(unsigned short saddr,
+	unsigned short baddr, unsigned short bdata)
+{
+	int32_t rc;
+	unsigned char buf[2];
+	memset(buf, 0, sizeof(buf));
+	buf[0] = baddr;
+	buf[1] = bdata;
+	rc = imx074_i2c_txdata(saddr, buf, 2);
+	if (rc < 0)
+		CDBG("AFi2c_write failed, saddr = 0x%x addr = 0x%x, val =0x%x!",
+			saddr, baddr, bdata);
+	return rc;
+}
+
+static int32_t imx074_i2c_write_w_table(struct imx074_i2c_reg_conf const
+					 *reg_conf_tbl, int num)
+{
+	int i;
+	int32_t rc = -EIO;
+	for (i = 0; i < num; i++) {
+		rc = imx074_i2c_write_b_sensor(reg_conf_tbl->waddr,
+			reg_conf_tbl->wdata);
+		if (rc < 0)
+			break;
+		reg_conf_tbl++;
+	}
+	return rc;
+}
+static int16_t imx074_af_init(void)
+{
+	int32_t rc;
+	/* Initialize waveform */
+	rc = imx074_i2c_write_b_af(IMX074_AF_I2C_SLAVE_ID, 0x01, 0xA9);
+	rc = imx074_i2c_write_b_af(IMX074_AF_I2C_SLAVE_ID, 0x02, 0xD2);
+	rc = imx074_i2c_write_b_af(IMX074_AF_I2C_SLAVE_ID, 0x03, 0x0C);
+	rc = imx074_i2c_write_b_af(IMX074_AF_I2C_SLAVE_ID, 0x04, 0x14);
+	rc = imx074_i2c_write_b_af(IMX074_AF_I2C_SLAVE_ID, 0x05, 0xB6);
+	rc = imx074_i2c_write_b_af(IMX074_AF_I2C_SLAVE_ID, 0x06, 0x4F);
+	return rc;
+}
+
+static void imx074_get_pict_fps(uint16_t fps, uint16_t *pfps)
+{
+	/* input fps is preview fps in Q8 format */
+	uint16_t preview_frame_length_lines, snapshot_frame_length_lines;
+	uint32_t divider, d1;
+	uint32_t pclk_mult;/*Q10 */
+	/* Total frame_length_lines and line_length_pck for preview */
+	preview_frame_length_lines = IMX074_QTR_SIZE_HEIGHT +
+		IMX074_VER_QTR_BLK_LINES;
+	/* Total frame_length_lines and line_length_pck for snapshot */
+	snapshot_frame_length_lines = IMX074_FULL_SIZE_HEIGHT +
+		IMX074_VER_FULL_BLK_LINES;
+	d1 = preview_frame_length_lines * 0x00010000 /
+		snapshot_frame_length_lines;
+	pclk_mult =
+		(uint32_t) ((imx074_regs.reg_pat[RES_CAPTURE].pll_multiplier *
+		0x00010000) /
+		(imx074_regs.reg_pat[RES_PREVIEW].pll_multiplier));
+	divider = d1 * pclk_mult / 0x00010000;
+	*pfps = (uint16_t) (fps * divider / 0x00010000);
+}
+
+static uint16_t imx074_get_prev_lines_pf(void)
+{
+	if (imx074_ctrl->prev_res == QTR_SIZE)
+		return IMX074_QTR_SIZE_HEIGHT + IMX074_VER_QTR_BLK_LINES;
+	else
+		return IMX074_FULL_SIZE_HEIGHT + IMX074_VER_FULL_BLK_LINES;
+
+}
+
+static uint16_t imx074_get_prev_pixels_pl(void)
+{
+	if (imx074_ctrl->prev_res == QTR_SIZE)
+		return IMX074_QTR_SIZE_WIDTH + IMX074_HRZ_QTR_BLK_PIXELS;
+	else
+		return IMX074_FULL_SIZE_WIDTH + IMX074_HRZ_FULL_BLK_PIXELS;
+}
+
+static uint16_t imx074_get_pict_lines_pf(void)
+{
+		if (imx074_ctrl->pict_res == QTR_SIZE)
+			return IMX074_QTR_SIZE_HEIGHT +
+				IMX074_VER_QTR_BLK_LINES;
+		else
+			return IMX074_FULL_SIZE_HEIGHT +
+				IMX074_VER_FULL_BLK_LINES;
+}
+
+static uint16_t imx074_get_pict_pixels_pl(void)
+{
+	if (imx074_ctrl->pict_res == QTR_SIZE)
+		return IMX074_QTR_SIZE_WIDTH +
+			IMX074_HRZ_QTR_BLK_PIXELS;
+	else
+		return IMX074_FULL_SIZE_WIDTH +
+			IMX074_HRZ_FULL_BLK_PIXELS;
+}
+
+static uint32_t imx074_get_pict_max_exp_lc(void)
+{
+	if (imx074_ctrl->pict_res == QTR_SIZE)
+		return (IMX074_QTR_SIZE_HEIGHT +
+			IMX074_VER_QTR_BLK_LINES)*24;
+	else
+		return (IMX074_FULL_SIZE_HEIGHT +
+			IMX074_VER_FULL_BLK_LINES)*24;
+}
+
+static int32_t imx074_set_fps(struct fps_cfg	*fps)
+{
+	uint16_t total_lines_per_frame;
+	int32_t rc = 0;
+	imx074_ctrl->fps_divider = fps->fps_div;
+	imx074_ctrl->pict_fps_divider = fps->pict_fps_div;
+	if (imx074_ctrl->curr_res  == QTR_SIZE) {
+		total_lines_per_frame = (uint16_t)(((IMX074_QTR_SIZE_HEIGHT +
+			IMX074_VER_QTR_BLK_LINES) *
+			imx074_ctrl->fps_divider) / 0x400);
+	} else {
+		total_lines_per_frame = (uint16_t)(((IMX074_FULL_SIZE_HEIGHT +
+			IMX074_VER_FULL_BLK_LINES) *
+			imx074_ctrl->pict_fps_divider) / 0x400);
+	}
+	if (imx074_i2c_write_b_sensor(REG_FRAME_LENGTH_LINES_HI,
+		((total_lines_per_frame & 0xFF00) >> 8)) < 0)
+		return rc;
+	if (imx074_i2c_write_b_sensor(REG_FRAME_LENGTH_LINES_LO,
+		(total_lines_per_frame & 0x00FF)) < 0)
+		return rc;
+	return rc;
+}
+
+static int32_t imx074_write_exp_gain(uint16_t gain, uint32_t line)
+{
+	static uint16_t max_legal_gain = 0x00E0;
+	uint8_t gain_msb, gain_lsb;
+	uint8_t intg_time_msb, intg_time_lsb;
+	uint8_t frame_length_line_msb, frame_length_line_lsb;
+	uint16_t frame_length_lines;
+	int32_t rc = -1;
+
+	CDBG("imx074_write_exp_gain : gain = %d line = %d", gain, line);
+	if (imx074_ctrl->curr_res  == QTR_SIZE) {
+		frame_length_lines = IMX074_QTR_SIZE_HEIGHT +
+			IMX074_VER_QTR_BLK_LINES;
+		frame_length_lines = frame_length_lines *
+			imx074_ctrl->fps_divider / 0x400;
+	} else {
+		frame_length_lines = IMX074_FULL_SIZE_HEIGHT +
+			IMX074_VER_FULL_BLK_LINES;
+		frame_length_lines = frame_length_lines *
+			imx074_ctrl->pict_fps_divider / 0x400;
+	}
+	if (line > (frame_length_lines - IMX074_OFFSET))
+		frame_length_lines = line + IMX074_OFFSET;
+
+	CDBG("imx074 setting line = %d\n", line);
+
+
+	CDBG("imx074 setting frame_length_lines = %d\n",
+					frame_length_lines);
+
+	if (gain > max_legal_gain)
+		/* range: 0 to 224 */
+		gain = max_legal_gain;
+
+	/* update gain registers */
+	gain_msb = (uint8_t) ((gain & 0xFF00) >> 8);
+	gain_lsb = (uint8_t) (gain & 0x00FF);
+
+	frame_length_line_msb = (uint8_t) ((frame_length_lines & 0xFF00) >> 8);
+	frame_length_line_lsb = (uint8_t) (frame_length_lines & 0x00FF);
+
+	/* update line count registers */
+	intg_time_msb = (uint8_t) ((line & 0xFF00) >> 8);
+	intg_time_lsb = (uint8_t) (line & 0x00FF);
+
+	rc = imx074_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
+					GROUPED_PARAMETER_HOLD);
+	if (rc < 0)
+		return rc;
+	CDBG("imx074 setting REG_ANALOGUE_GAIN_CODE_GLOBAL_HI = 0x%X\n",
+					gain_msb);
+	rc = imx074_i2c_write_b_sensor(REG_ANALOGUE_GAIN_CODE_GLOBAL_HI,
+					gain_msb);
+	if (rc < 0)
+		return rc;
+	CDBG("imx074 setting REG_ANALOGUE_GAIN_CODE_GLOBAL_LO = 0x%X\n",
+					gain_lsb);
+	rc = imx074_i2c_write_b_sensor(REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
+					gain_lsb);
+	if (rc < 0)
+		return rc;
+
+	CDBG("imx074 setting REG_FRAME_LENGTH_LINES_HI = 0x%X\n",
+					frame_length_line_msb);
+	rc = imx074_i2c_write_b_sensor(REG_FRAME_LENGTH_LINES_HI,
+			frame_length_line_msb);
+	if (rc < 0)
+		return rc;
+
+	CDBG("imx074 setting REG_FRAME_LENGTH_LINES_LO = 0x%X\n",
+			frame_length_line_lsb);
+	rc = imx074_i2c_write_b_sensor(REG_FRAME_LENGTH_LINES_LO,
+			frame_length_line_lsb);
+	if (rc < 0)
+		return rc;
+
+	CDBG("imx074 setting REG_COARSE_INTEGRATION_TIME_HI = 0x%X\n",
+					intg_time_msb);
+	rc = imx074_i2c_write_b_sensor(REG_COARSE_INTEGRATION_TIME_HI,
+					intg_time_msb);
+	if (rc < 0)
+		return rc;
+
+	CDBG("imx074 setting REG_COARSE_INTEGRATION_TIME_LO = 0x%X\n",
+					intg_time_lsb);
+	rc = imx074_i2c_write_b_sensor(REG_COARSE_INTEGRATION_TIME_LO,
+					intg_time_lsb);
+	if (rc < 0)
+		return rc;
+
+	rc = imx074_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
+					GROUPED_PARAMETER_HOLD_OFF);
+	if (rc < 0)
+		return rc;
+
+	return rc;
+}
+
+static int32_t imx074_set_pict_exp_gain(uint16_t gain, uint32_t line)
+{
+	int32_t rc = 0;
+	rc = imx074_write_exp_gain(gain, line);
+	return rc;
+}
+
+static int32_t imx074_move_focus(int direction,
+	int32_t num_steps)
+{
+	int32_t step_direction, dest_step_position, bit_mask;
+	int32_t rc = 0;
+
+	if (num_steps == 0)
+		return rc;
+
+	if (direction == MOVE_NEAR) {
+		step_direction = 1;
+		bit_mask = 0x80;
+	} else if (direction == MOVE_FAR) {
+		step_direction = -1;
+		bit_mask = 0x00;
+	} else {
+		CDBG("imx074_move_focus: Illegal focus direction");
+		return -EINVAL;
+	}
+	dest_step_position = imx074_ctrl->curr_step_pos +
+		(step_direction * num_steps);
+	if (dest_step_position < 0)
+		dest_step_position = 0;
+	else if (dest_step_position > IMX074_TOTAL_STEPS_NEAR_TO_FAR)
+		dest_step_position = IMX074_TOTAL_STEPS_NEAR_TO_FAR;
+	rc = imx074_i2c_write_b_af(IMX074_AF_I2C_SLAVE_ID, 0x00,
+		((num_steps * imx074_l_region_code_per_step) | bit_mask));
+	CDBG("%s: Index: %d\n", __func__, dest_step_position);
+	imx074_ctrl->curr_step_pos = dest_step_position;
+	return rc;
+}
+
+
+static int32_t imx074_set_default_focus(uint8_t af_step)
+{
+	int32_t rc;
+	/* Initialize to infinity */
+	rc = imx074_i2c_write_b_af(IMX074_AF_I2C_SLAVE_ID, 0x00, 0x7F);
+	rc = imx074_i2c_write_b_af(IMX074_AF_I2C_SLAVE_ID, 0x00, 0x7F);
+	imx074_ctrl->curr_step_pos = 0;
+	return rc;
+}
+static int32_t imx074_test(enum imx074_test_mode_t mo)
+{
+	int32_t rc = 0;
+	if (mo == TEST_OFF)
+		return rc;
+	else {
+		/* Set mo to 2 inorder to enable test pattern*/
+		if (imx074_i2c_write_b_sensor(REG_TEST_PATTERN_MODE,
+			(uint8_t) mo) < 0) {
+			return rc;
+		}
+	}
+	return rc;
+}
+static int32_t imx074_sensor_setting(int update_type, int rt)
+{
+	int32_t rc = 0;
+	struct msm_camera_csi_params imx074_csi_params;
+	switch (update_type) {
+	case REG_INIT:
+		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
+			struct imx074_i2c_reg_conf init_tbl[] = {
+				{REG_PRE_PLL_CLK_DIV,
+					imx074_regs.reg_pat_init[0].
+					pre_pll_clk_div},
+				{REG_PLSTATIM,
+					imx074_regs.reg_pat_init[0].
+					plstatim},
+				{REG_3024,
+					imx074_regs.reg_pat_init[0].
+					reg_3024},
+				{REG_IMAGE_ORIENTATION,
+					imx074_regs.reg_pat_init[0].
+					image_orientation},
+				{REG_VNDMY_ABLMGSHLMT,
+					imx074_regs.reg_pat_init[0].
+					vndmy_ablmgshlmt},
+				{REG_Y_OPBADDR_START_DI,
+					imx074_regs.reg_pat_init[0].
+					y_opbaddr_start_di},
+				{REG_3015,
+					imx074_regs.reg_pat_init[0].
+					reg_0x3015},
+				{REG_301C,
+					imx074_regs.reg_pat_init[0].
+					reg_0x301c},
+				{REG_302C,
+					imx074_regs.reg_pat_init[0].
+					reg_0x302c},
+				{REG_3031,
+					imx074_regs.reg_pat_init[0].reg_0x3031},
+				{REG_3041,
+					imx074_regs.reg_pat_init[0].reg_0x3041},
+				{REG_3051,
+					imx074_regs.reg_pat_init[0].reg_0x3051},
+				{REG_3053,
+					imx074_regs.reg_pat_init[0].reg_0x3053},
+				{REG_3057,
+					imx074_regs.reg_pat_init[0].reg_0x3057},
+				{REG_305C,
+					imx074_regs.reg_pat_init[0].reg_0x305c},
+				{REG_305D,
+					imx074_regs.reg_pat_init[0].reg_0x305d},
+				{REG_3060,
+					imx074_regs.reg_pat_init[0].reg_0x3060},
+				{REG_3065,
+					imx074_regs.reg_pat_init[0].reg_0x3065},
+				{REG_30AA,
+					imx074_regs.reg_pat_init[0].reg_0x30aa},
+				{REG_30AB,
+					imx074_regs.reg_pat_init[0].reg_0x30ab},
+				{REG_30B0,
+					imx074_regs.reg_pat_init[0].reg_0x30b0},
+				{REG_30B2,
+					imx074_regs.reg_pat_init[0].reg_0x30b2},
+				{REG_30D3,
+					imx074_regs.reg_pat_init[0].reg_0x30d3},
+				{REG_3106,
+					imx074_regs.reg_pat_init[0].reg_0x3106},
+				{REG_310C,
+					imx074_regs.reg_pat_init[0].reg_0x310c},
+				{REG_3304,
+					imx074_regs.reg_pat_init[0].reg_0x3304},
+				{REG_3305,
+					imx074_regs.reg_pat_init[0].reg_0x3305},
+				{REG_3306,
+					imx074_regs.reg_pat_init[0].reg_0x3306},
+				{REG_3307,
+					imx074_regs.reg_pat_init[0].reg_0x3307},
+				{REG_3308,
+					imx074_regs.reg_pat_init[0].reg_0x3308},
+				{REG_3309,
+					imx074_regs.reg_pat_init[0].reg_0x3309},
+				{REG_330A,
+					imx074_regs.reg_pat_init[0].reg_0x330a},
+				{REG_330B,
+					imx074_regs.reg_pat_init[0].reg_0x330b},
+				{REG_330C,
+					imx074_regs.reg_pat_init[0].reg_0x330c},
+				{REG_330D,
+					imx074_regs.reg_pat_init[0].reg_0x330d},
+				{REG_330F,
+					imx074_regs.reg_pat_init[0].reg_0x330f},
+				{REG_3381,
+					imx074_regs.reg_pat_init[0].reg_0x3381},
+			};
+			struct imx074_i2c_reg_conf init_mode_tbl[] = {
+				{REG_GROUPED_PARAMETER_HOLD,
+					GROUPED_PARAMETER_HOLD},
+				{REG_PLL_MULTIPLIER,
+					imx074_regs.reg_pat[rt].
+					pll_multiplier},
+				{REG_FRAME_LENGTH_LINES_HI,
+					imx074_regs.reg_pat[rt].
+					frame_length_lines_hi},
+				{REG_FRAME_LENGTH_LINES_LO,
+					imx074_regs.reg_pat[rt].
+					frame_length_lines_lo},
+				{REG_YADDR_START ,
+					imx074_regs.reg_pat[rt].
+					y_addr_start},
+				{REG_YAAAR_END,
+					imx074_regs.reg_pat[rt].
+					y_add_end},
+				{REG_X_OUTPUT_SIZE_MSB,
+					imx074_regs.reg_pat[rt].
+					x_output_size_msb},
+				{REG_X_OUTPUT_SIZE_LSB,
+					imx074_regs.reg_pat[rt].
+					x_output_size_lsb},
+				{REG_Y_OUTPUT_SIZE_MSB,
+					imx074_regs.reg_pat[rt].
+					y_output_size_msb},
+				{REG_Y_OUTPUT_SIZE_LSB ,
+					imx074_regs.reg_pat[rt].
+					y_output_size_lsb},
+				{REG_X_EVEN_INC,
+					imx074_regs.reg_pat[rt].
+					x_even_inc},
+				{REG_X_ODD_INC,
+					imx074_regs.reg_pat[rt].
+					x_odd_inc},
+				{REG_Y_EVEN_INC,
+					imx074_regs.reg_pat[rt].
+					y_even_inc},
+				{REG_Y_ODD_INC,
+					imx074_regs.reg_pat[rt].
+					y_odd_inc},
+				{REG_HMODEADD,
+					imx074_regs.reg_pat[rt].
+					hmodeadd},
+				{REG_VMODEADD,
+					imx074_regs.reg_pat[rt].
+					vmodeadd},
+				{REG_VAPPLINE_START,
+					imx074_regs.reg_pat[rt].
+					vapplinepos_start},
+				{REG_VAPPLINE_END,
+					imx074_regs.reg_pat[rt].
+					vapplinepos_end},
+				{REG_SHUTTER,
+					imx074_regs.reg_pat[rt].
+					shutter},
+				{REG_HADDAVE,
+					imx074_regs.reg_pat[rt].
+					haddave},
+				{REG_LANESEL,
+					imx074_regs.reg_pat[rt].
+					lanesel},
+				{REG_GROUPED_PARAMETER_HOLD,
+					GROUPED_PARAMETER_HOLD_OFF},
+
+			};
+			/* reset fps_divider */
+			imx074_ctrl->fps = 30 * Q8;
+			imx074_ctrl->fps_divider = 1 * 0x400;
+			/* stop streaming */
+			rc = imx074_i2c_write_b_sensor(REG_MODE_SELECT,
+				MODE_SELECT_STANDBY_MODE);
+			if (rc < 0)
+				return rc;
+			msleep(imx074_delay_msecs_stdby);
+			rc = imx074_i2c_write_w_table(&init_tbl[0],
+				ARRAY_SIZE(init_tbl));
+			if (rc < 0)
+				return rc;
+			rc = imx074_i2c_write_w_table(&init_mode_tbl[0],
+				ARRAY_SIZE(init_mode_tbl));
+			if (rc < 0)
+				return rc;
+			rc = imx074_test(imx074_ctrl->set_test);
+			return rc;
+		}
+		break;
+	case UPDATE_PERIODIC:
+		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
+			struct imx074_i2c_reg_conf mode_tbl[] = {
+				{REG_GROUPED_PARAMETER_HOLD,
+					GROUPED_PARAMETER_HOLD},
+				{REG_PLL_MULTIPLIER,
+					imx074_regs.reg_pat[rt].
+					pll_multiplier},
+				{REG_FRAME_LENGTH_LINES_HI,
+					imx074_regs.reg_pat[rt].
+					frame_length_lines_hi},
+				{REG_FRAME_LENGTH_LINES_LO,
+					imx074_regs.reg_pat[rt].
+					frame_length_lines_lo},
+				{REG_YADDR_START ,
+					imx074_regs.reg_pat[rt].
+					y_addr_start},
+				{REG_YAAAR_END,
+					imx074_regs.reg_pat[rt].
+					y_add_end},
+				{REG_X_OUTPUT_SIZE_MSB,
+					imx074_regs.reg_pat[rt].
+					x_output_size_msb},
+				{REG_X_OUTPUT_SIZE_LSB,
+					imx074_regs.reg_pat[rt].
+					x_output_size_lsb},
+				{REG_Y_OUTPUT_SIZE_MSB,
+					imx074_regs.reg_pat[rt].
+					y_output_size_msb},
+				{REG_Y_OUTPUT_SIZE_LSB ,
+					imx074_regs.reg_pat[rt].
+					y_output_size_lsb},
+				{REG_X_EVEN_INC,
+					imx074_regs.reg_pat[rt].
+					x_even_inc},
+				{REG_X_ODD_INC,
+					imx074_regs.reg_pat[rt].
+					x_odd_inc},
+				{REG_Y_EVEN_INC,
+					imx074_regs.reg_pat[rt].
+					y_even_inc},
+				{REG_Y_ODD_INC,
+					imx074_regs.reg_pat[rt].
+					y_odd_inc},
+				{REG_HMODEADD,
+					imx074_regs.reg_pat[rt].
+					hmodeadd},
+				{REG_VMODEADD,
+					imx074_regs.reg_pat[rt].
+					vmodeadd},
+				{REG_VAPPLINE_START,
+					imx074_regs.reg_pat[rt].
+					vapplinepos_start},
+				{REG_VAPPLINE_END,
+					imx074_regs.reg_pat[rt].
+					vapplinepos_end},
+				{REG_SHUTTER,
+					imx074_regs.reg_pat[rt].
+					shutter},
+				{REG_HADDAVE,
+					imx074_regs.reg_pat[rt].
+					haddave},
+				{REG_LANESEL,
+					imx074_regs.reg_pat[rt].
+					lanesel},
+				{REG_GROUPED_PARAMETER_HOLD,
+					GROUPED_PARAMETER_HOLD_OFF},
+			};
+
+			/* stop streaming */
+			rc = imx074_i2c_write_b_sensor(REG_MODE_SELECT,
+				MODE_SELECT_STANDBY_MODE);
+			msleep(imx074_delay_msecs_stdby);
+			if (config_csi == 0) {
+				imx074_csi_params.lane_cnt = 4;
+				imx074_csi_params.data_format = CSI_10BIT;
+				imx074_csi_params.lane_assign = 0xe4;
+				imx074_csi_params.dpcm_scheme = 0;
+				imx074_csi_params.settle_cnt = 0x14;
+				rc = msm_camio_csi_config(&imx074_csi_params);
+				/*imx074_delay_msecs_stdby*/
+				msleep(imx074_delay_msecs_stream);
+				config_csi = 1;
+			}
+			rc = imx074_i2c_write_w_table(&mode_tbl[0],
+				ARRAY_SIZE(mode_tbl));
+			if (rc < 0)
+				return rc;
+			rc = imx074_i2c_write_b_sensor(REG_MODE_SELECT,
+				MODE_SELECT_STREAM);
+			if (rc < 0)
+				return rc;
+			msleep(imx074_delay_msecs_stream);
+		}
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
+
+static int32_t imx074_video_config(int mode)
+{
+
+	int32_t	rc = 0;
+	int	rt;
+	/* change sensor resolution	if needed */
+	if (imx074_ctrl->prev_res == QTR_SIZE) {
+		rt = RES_PREVIEW;
+	} else {
+		rt = RES_CAPTURE;
+	}
+	if (imx074_sensor_setting(UPDATE_PERIODIC, rt) < 0)
+		return rc;
+	imx074_ctrl->curr_res = imx074_ctrl->prev_res;
+	imx074_ctrl->sensormode = mode;
+	return rc;
+}
+
+static int32_t imx074_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+	int rt = RES_PREVIEW; /* TODO: Used without initialization, guessing. */
+	/* change sensor resolution if needed */
+	if (imx074_ctrl->curr_res != imx074_ctrl->pict_res) {
+		if (imx074_ctrl->pict_res == QTR_SIZE) {
+			rt = RES_PREVIEW;
+		} else {
+			rt = RES_CAPTURE;
+		}
+	}
+	if (imx074_sensor_setting(UPDATE_PERIODIC, rt) < 0)
+		return rc;
+	imx074_ctrl->curr_res = imx074_ctrl->pict_res;
+	imx074_ctrl->sensormode = mode;
+	return rc;
+}
+static int32_t imx074_raw_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+	int rt = RES_PREVIEW; /* TODO: Used without initialization, guessing. */
+	/* change sensor resolution if needed */
+	if (imx074_ctrl->curr_res != imx074_ctrl->pict_res) {
+		if (imx074_ctrl->pict_res == QTR_SIZE) {
+			rt = RES_PREVIEW;
+		} else {
+			rt = RES_CAPTURE;
+		}
+	}
+	if (imx074_sensor_setting(UPDATE_PERIODIC, rt) < 0)
+		return rc;
+	imx074_ctrl->curr_res = imx074_ctrl->pict_res;
+	imx074_ctrl->sensormode = mode;
+	return rc;
+}
+static int32_t imx074_set_sensor_mode(int mode,
+	int res)
+{
+	int32_t rc = 0;
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		rc = imx074_video_config(mode);
+		break;
+	case SENSOR_SNAPSHOT_MODE:
+		rc = imx074_snapshot_config(mode);
+		break;
+	case SENSOR_RAW_SNAPSHOT_MODE:
+		rc = imx074_raw_snapshot_config(mode);
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+static int32_t imx074_power_down(void)
+{
+	imx074_i2c_write_b_sensor(REG_MODE_SELECT,
+		MODE_SELECT_STANDBY_MODE);
+	msleep(imx074_delay_msecs_stdby);
+	return 0;
+}
+static int imx074_probe_init_done(const struct msm_camera_sensor_info *data)
+{
+	gpio_set_value_cansleep(data->sensor_reset, 0);
+	gpio_direction_input(data->sensor_reset);
+	gpio_free(data->sensor_reset);
+	return 0;
+}
+
+static int imx074_read_eeprom_data(struct sensor_cfg_data *cfg)
+{
+	int32_t rc = 0;
+	uint16_t eepromdata = 0;
+	uint8_t addr = 0;
+
+	addr = 0x10;
+	rc = imx074_i2c_read_w_eeprom(addr, &eepromdata);
+	if (rc < 0) {
+		CDBG("%s: Error Reading EEPROM @ 0x%x\n", __func__, addr);
+		return rc;
+	}
+	cfg->cfg.calib_info.r_over_g = eepromdata;
+
+	addr = 0x12;
+	rc = imx074_i2c_read_w_eeprom(addr, &eepromdata);
+	if (rc < 0) {
+		CDBG("%s: Error Reading EEPROM @ 0x%x\n", __func__, addr);
+		return rc;
+	}
+	cfg->cfg.calib_info.b_over_g = eepromdata;
+
+	addr = 0x14;
+	rc = imx074_i2c_read_w_eeprom(addr, &eepromdata);
+	if (rc < 0) {
+		CDBG("%s: Error Reading EEPROM @ 0x%x\n", __func__, addr);
+		return rc;
+	}
+	cfg->cfg.calib_info.gr_over_gb = eepromdata;
+
+	addr = 0x1A;
+	rc = imx074_i2c_read_w_eeprom(addr, &eepromdata);
+	if (rc < 0) {
+		CDBG("%s: Error Reading EEPROM @ 0x%x\n", __func__, addr);
+		return rc;
+	}
+	cfg->cfg.calib_info.macro_2_inf = eepromdata;
+
+	addr = 0x1C;
+	rc = imx074_i2c_read_w_eeprom(addr, &eepromdata);
+	if (rc < 0) {
+		CDBG("%s: Error Reading EEPROM @ 0x%x\n", __func__, addr);
+		return rc;
+	}
+	cfg->cfg.calib_info.inf_2_macro = eepromdata;
+
+	addr = 0x1E;
+	rc = imx074_i2c_read_w_eeprom(addr, &eepromdata);
+	if (rc < 0) {
+		CDBG("%s: Error Reading EEPROM @ 0x%x\n", __func__, addr);
+		return rc;
+	}
+	cfg->cfg.calib_info.stroke_amt = eepromdata;
+
+	addr = 0x20;
+	rc = imx074_i2c_read_w_eeprom(addr, &eepromdata);
+	if (rc < 0) {
+		CDBG("%s: Error Reading EEPROM @ 0x%x\n", __func__, addr);
+		return rc;
+	}
+	cfg->cfg.calib_info.af_pos_1m = eepromdata;
+
+	addr = 0x22;
+	rc = imx074_i2c_read_w_eeprom(addr, &eepromdata);
+	if (rc < 0) {
+		CDBG("%s: Error Reading EEPROM @ 0x%x\n", __func__, addr);
+		return rc;
+	}
+	cfg->cfg.calib_info.af_pos_inf = eepromdata;
+
+	return rc;
+}
+
+static int imx074_probe_init_sensor(const struct msm_camera_sensor_info *data)
+{
+	int32_t rc = 0;
+	unsigned short chipidl, chipidh;
+	CDBG("%s: %d\n", __func__, __LINE__);
+	rc = gpio_request(data->sensor_reset, "imx074");
+	CDBG(" imx074_probe_init_sensor \n");
+	if (!rc) {
+		CDBG("sensor_reset = %d\n", rc);
+		gpio_direction_output(data->sensor_reset, 0);
+		usleep_range(5000, 6000);
+		gpio_set_value_cansleep(data->sensor_reset, 1);
+		usleep_range(5000, 6000);
+	} else {
+		CDBG("gpio reset fail");
+		goto init_probe_done;
+	}
+	CDBG("imx074_probe_init_sensor is called\n");
+	/* 3. Read sensor Model ID: */
+	rc = imx074_i2c_read(0x0000, &chipidh, 1);
+	if (rc < 0) {
+		CDBG("Model read failed\n");
+		goto init_probe_fail;
+	}
+	rc = imx074_i2c_read(0x0001, &chipidl, 1);
+	if (rc < 0) {
+		CDBG("Model read failed\n");
+		goto init_probe_fail;
+	}
+	CDBG("imx074 model_id = 0x%x  0x%x\n", chipidh, chipidl);
+	/* 4. Compare sensor ID to IMX074 ID: */
+	if (chipidh != 0x00 || chipidl != 0x74) {
+		rc = -ENODEV;
+		CDBG("imx074_probe_init_sensor fail chip id doesnot match\n");
+		goto init_probe_fail;
+	}
+	goto init_probe_done;
+init_probe_fail:
+	CDBG("imx074_probe_init_sensor fails\n");
+	imx074_probe_init_done(data);
+init_probe_done:
+	CDBG(" imx074_probe_init_sensor finishes\n");
+	return rc;
+	}
+static int32_t imx074_poweron_af(void)
+{
+	int32_t rc = 0;
+	CDBG("imx074 enable AF actuator, gpio = %d\n",
+			imx074_ctrl->sensordata->vcm_pwd);
+	rc = gpio_request(imx074_ctrl->sensordata->vcm_pwd, "imx074");
+	if (!rc) {
+		gpio_direction_output(imx074_ctrl->sensordata->vcm_pwd, 1);
+		msleep(20);
+		rc = imx074_af_init();
+		if (rc < 0)
+			CDBG("imx074 AF initialisation failed\n");
+	} else {
+		CDBG("%s: AF PowerON gpio_request failed %d\n", __func__, rc);
+	 }
+	return rc;
+}
+static void imx074_poweroff_af(void)
+{
+	gpio_set_value_cansleep(imx074_ctrl->sensordata->vcm_pwd, 0);
+	gpio_free(imx074_ctrl->sensordata->vcm_pwd);
+}
+/* camsensor_iu060f_imx074_reset */
+int imx074_sensor_open_init(const struct msm_camera_sensor_info *data)
+{
+	int32_t rc = 0;
+	CDBG("%s: %d\n", __func__, __LINE__);
+	CDBG("Calling imx074_sensor_open_init\n");
+	imx074_ctrl = kzalloc(sizeof(struct imx074_ctrl_t), GFP_KERNEL);
+	if (!imx074_ctrl) {
+		CDBG("imx074_init failed!\n");
+		rc = -ENOMEM;
+		goto init_done;
+	}
+	imx074_ctrl->fps_divider = 1 * 0x00000400;
+	imx074_ctrl->pict_fps_divider = 1 * 0x00000400;
+	imx074_ctrl->fps = 30 * Q8;
+	imx074_ctrl->set_test = TEST_OFF;
+	imx074_ctrl->prev_res = QTR_SIZE;
+	imx074_ctrl->pict_res = FULL_SIZE;
+	imx074_ctrl->curr_res = INVALID_SIZE;
+	config_csi = 0;
+
+	if (data)
+		imx074_ctrl->sensordata = data;
+
+	/* enable mclk first */
+	msm_camio_clk_rate_set(IMX074_DEFAULT_MASTER_CLK_RATE);
+	usleep_range(1000, 2000);
+	rc = imx074_probe_init_sensor(data);
+	if (rc < 0) {
+		CDBG("Calling imx074_sensor_open_init fail\n");
+		goto probe_fail;
+	}
+
+	rc = imx074_sensor_setting(REG_INIT, RES_PREVIEW);
+	if (rc < 0) {
+		CDBG("imx074_sensor_setting failed\n");
+		goto init_fail;
+	}
+	if (machine_is_msm8x60_fluid())
+		rc = imx074_poweron_af();
+	else
+		rc = imx074_af_init();
+	if (rc < 0) {
+		CDBG("AF initialisation failed\n");
+		goto init_fail;
+	} else
+		goto init_done;
+probe_fail:
+	CDBG(" imx074_sensor_open_init probe fail\n");
+	kfree(imx074_ctrl);
+	return rc;
+init_fail:
+	CDBG(" imx074_sensor_open_init fail\n");
+	imx074_probe_init_done(data);
+	kfree(imx074_ctrl);
+init_done:
+	CDBG("imx074_sensor_open_init done\n");
+	return rc;
+}
+static int imx074_init_client(struct i2c_client *client)
+{
+	/* Initialize the MSM_CAMI2C Chip */
+	init_waitqueue_head(&imx074_wait_queue);
+	return 0;
+}
+
+static const struct i2c_device_id imx074_i2c_id[] = {
+	{"imx074", 0},
+	{ }
+};
+
+static int imx074_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+	CDBG("imx074_probe called!\n");
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		CDBG("i2c_check_functionality failed\n");
+		goto probe_failure;
+	}
+
+	imx074_sensorw = kzalloc(sizeof(struct imx074_work_t), GFP_KERNEL);
+	if (!imx074_sensorw) {
+		CDBG("kzalloc failed.\n");
+		rc = -ENOMEM;
+		goto probe_failure;
+	}
+
+	i2c_set_clientdata(client, imx074_sensorw);
+	imx074_init_client(client);
+	imx074_client = client;
+
+
+	CDBG("imx074_probe successed! rc = %d\n", rc);
+	return 0;
+
+probe_failure:
+	CDBG("imx074_probe failed! rc = %d\n", rc);
+	return rc;
+}
+
+static int __exit imx074_remove(struct i2c_client *client)
+{
+	struct imx074_work_t_t *sensorw = i2c_get_clientdata(client);
+	free_irq(client->irq, sensorw);
+	imx074_client = NULL;
+	kfree(sensorw);
+	return 0;
+}
+
+static struct i2c_driver imx074_i2c_driver = {
+	.id_table = imx074_i2c_id,
+	.probe  = imx074_i2c_probe,
+	.remove = __exit_p(imx074_i2c_remove),
+	.driver = {
+		.name = "imx074",
+	},
+};
+
+int imx074_sensor_config(void __user *argp)
+{
+	struct sensor_cfg_data cdata;
+	long   rc = 0;
+	if (copy_from_user(&cdata,
+		(void *)argp,
+		sizeof(struct sensor_cfg_data)))
+		return -EFAULT;
+	mutex_lock(&imx074_mut);
+	CDBG("imx074_sensor_config: cfgtype = %d\n",
+	cdata.cfgtype);
+	switch (cdata.cfgtype) {
+	case CFG_GET_PICT_FPS:
+		imx074_get_pict_fps(
+			cdata.cfg.gfps.prevfps,
+			&(cdata.cfg.gfps.pictfps));
+		if (copy_to_user((void *)argp,
+			&cdata,
+			sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+			break;
+	case CFG_GET_PREV_L_PF:
+		cdata.cfg.prevl_pf =
+			imx074_get_prev_lines_pf();
+		if (copy_to_user((void *)argp,
+			&cdata,
+			sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+			break;
+	case CFG_GET_PREV_P_PL:
+		cdata.cfg.prevp_pl =
+			imx074_get_prev_pixels_pl();
+		if (copy_to_user((void *)argp,
+			&cdata,
+			sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+			break;
+
+	case CFG_GET_PICT_L_PF:
+		cdata.cfg.pictl_pf =
+			imx074_get_pict_lines_pf();
+		if (copy_to_user((void *)argp,
+			&cdata,
+			sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+			break;
+	case CFG_GET_PICT_P_PL:
+		cdata.cfg.pictp_pl =
+			imx074_get_pict_pixels_pl();
+		if (copy_to_user((void *)argp,
+			&cdata,
+			sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+			break;
+	case CFG_GET_PICT_MAX_EXP_LC:
+		cdata.cfg.pict_max_exp_lc =
+			imx074_get_pict_max_exp_lc();
+		if (copy_to_user((void *)argp,
+			&cdata,
+			sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+			break;
+	case CFG_SET_FPS:
+	case CFG_SET_PICT_FPS:
+		rc = imx074_set_fps(&(cdata.cfg.fps));
+		break;
+	case CFG_SET_EXP_GAIN:
+		rc =
+			imx074_write_exp_gain(
+			cdata.cfg.exp_gain.gain,
+			cdata.cfg.exp_gain.line);
+			break;
+	case CFG_SET_PICT_EXP_GAIN:
+		rc =
+			imx074_set_pict_exp_gain(
+			cdata.cfg.exp_gain.gain,
+			cdata.cfg.exp_gain.line);
+			break;
+	case CFG_SET_MODE:
+		rc = imx074_set_sensor_mode(cdata.mode,
+			cdata.rs);
+			break;
+	case CFG_PWR_DOWN:
+		rc = imx074_power_down();
+			break;
+	case CFG_GET_CALIB_DATA:
+		rc = imx074_read_eeprom_data(&cdata);
+		if (rc < 0)
+			break;
+		if (copy_to_user((void *)argp,
+			&cdata,
+			sizeof(cdata)))
+			rc = -EFAULT;
+		break;
+	case CFG_MOVE_FOCUS:
+		rc =
+			imx074_move_focus(
+			cdata.cfg.focus.dir,
+			cdata.cfg.focus.steps);
+			break;
+	case CFG_SET_DEFAULT_FOCUS:
+		rc =
+			imx074_set_default_focus(
+			cdata.cfg.focus.steps);
+			break;
+	case CFG_GET_AF_MAX_STEPS:
+		cdata.max_steps = IMX074_STEPS_NEAR_TO_CLOSEST_INF;
+		if (copy_to_user((void *)argp,
+			&cdata,
+			sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+			break;
+	case CFG_SET_EFFECT:
+	default:
+		rc = -EFAULT;
+		break;
+	}
+
+	mutex_unlock(&imx074_mut);
+
+	return rc;
+}
+static int imx074_sensor_release(void)
+{
+	int rc = -EBADF;
+	mutex_lock(&imx074_mut);
+	if (machine_is_msm8x60_fluid())
+		imx074_poweroff_af();
+	imx074_power_down();
+	gpio_set_value_cansleep(imx074_ctrl->sensordata->sensor_reset, 0);
+	msleep(5);
+	gpio_direction_input(imx074_ctrl->sensordata->sensor_reset);
+	gpio_free(imx074_ctrl->sensordata->sensor_reset);
+	kfree(imx074_ctrl);
+	imx074_ctrl = NULL;
+	CDBG("imx074_release completed\n");
+	mutex_unlock(&imx074_mut);
+
+	return rc;
+}
+
+static int imx074_sensor_probe(const struct msm_camera_sensor_info *info,
+		struct msm_sensor_ctrl *s)
+{
+	int rc = 0;
+	rc = i2c_add_driver(&imx074_i2c_driver);
+	if (rc < 0 || imx074_client == NULL) {
+		rc = -ENOTSUPP;
+		goto probe_fail;
+	}
+	msm_camio_clk_rate_set(IMX074_DEFAULT_MASTER_CLK_RATE);
+	rc = imx074_probe_init_sensor(info);
+	if (rc < 0)
+		goto probe_fail;
+	s->s_init = imx074_sensor_open_init;
+	s->s_release = imx074_sensor_release;
+	s->s_config  = imx074_sensor_config;
+	s->s_mount_angle = info->sensor_platform_info->mount_angle;
+	imx074_probe_init_done(info);
+	return rc;
+
+probe_fail:
+	CDBG("imx074_sensor_probe: SENSOR PROBE FAILS!\n");
+	i2c_del_driver(&imx074_i2c_driver);
+	return rc;
+}
+
+static int __imx074_probe(struct platform_device *pdev)
+{
+
+	return msm_camera_drv_start(pdev, imx074_sensor_probe);
+}
+
+static struct platform_driver msm_camera_driver = {
+	.probe = __imx074_probe,
+	.driver = {
+		.name = "msm_camera_imx074",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init imx074_init(void)
+{
+	return platform_driver_register(&msm_camera_driver);
+}
+
+module_init(imx074_init);
+
+MODULE_DESCRIPTION("Sony 13 MP Bayer sensor driver");
+MODULE_LICENSE("GPL v2");
+
diff --git a/drivers/media/platform/msm/camera_v1/imx074.h b/drivers/media/platform/msm/camera_v1/imx074.h
new file mode 100644
index 0000000..9468cb0
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/imx074.h
@@ -0,0 +1,118 @@
+/* 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.
+ */
+
+#ifndef IMX074_H
+#define IMX074_H
+#include <linux/types.h>
+#include <mach/board.h>
+extern struct imx074_reg imx074_regs;
+struct reg_struct_init {
+    /* PLL setting */
+	uint8_t pre_pll_clk_div; /* 0x0305 */
+	uint8_t plstatim; /* 0x302b */
+	uint8_t reg_3024; /*ox3024*/
+	uint8_t image_orientation;  /* 0x0101*/
+	uint8_t vndmy_ablmgshlmt; /*0x300a*/
+	uint8_t y_opbaddr_start_di; /*0x3014*/
+	uint8_t reg_0x3015; /*0x3015*/
+	uint8_t reg_0x301c; /*0x301c*/
+	uint8_t reg_0x302c; /*0x302c*/
+	uint8_t reg_0x3031; /*0x3031*/
+	uint8_t reg_0x3041; /* 0x3041 */
+	uint8_t reg_0x3051; /* 0x3051 */
+	uint8_t reg_0x3053; /* 0x3053 */
+	uint8_t reg_0x3057; /* 0x3057 */
+	uint8_t reg_0x305c; /* 0x305c */
+	uint8_t reg_0x305d; /* 0x305d */
+	uint8_t reg_0x3060; /* 0x3060 */
+	uint8_t reg_0x3065; /* 0x3065 */
+	uint8_t reg_0x30aa; /* 0x30aa */
+	uint8_t reg_0x30ab;
+	uint8_t reg_0x30b0;
+	uint8_t reg_0x30b2;
+	uint8_t reg_0x30d3;
+	uint8_t reg_0x3106;
+	uint8_t reg_0x310c;
+	uint8_t reg_0x3304;
+	uint8_t reg_0x3305;
+	uint8_t reg_0x3306;
+	uint8_t reg_0x3307;
+	uint8_t reg_0x3308;
+	uint8_t reg_0x3309;
+	uint8_t reg_0x330a;
+	uint8_t reg_0x330b;
+	uint8_t reg_0x330c;
+	uint8_t reg_0x330d;
+	uint8_t reg_0x330f;
+	uint8_t reg_0x3381;
+};
+
+struct reg_struct {
+	uint8_t pll_multiplier; /* 0x0307 */
+	uint8_t frame_length_lines_hi; /* 0x0340*/
+	uint8_t frame_length_lines_lo; /* 0x0341*/
+	uint8_t y_addr_start;  /* 0x347 */
+	uint8_t y_add_end;  /* 0x034b */
+	uint8_t x_output_size_msb;  /* 0x034c */
+	uint8_t x_output_size_lsb;  /* 0x034d */
+	uint8_t y_output_size_msb; /* 0x034e */
+	uint8_t y_output_size_lsb; /* 0x034f */
+	uint8_t x_even_inc;  /* 0x0381 */
+	uint8_t x_odd_inc; /* 0x0383 */
+	uint8_t y_even_inc;  /* 0x0385 */
+	uint8_t y_odd_inc; /* 0x0387 */
+	uint8_t hmodeadd;   /* 0x3001 */
+	uint8_t vmodeadd;   /* 0x3016 */
+	uint8_t vapplinepos_start;/*ox3069*/
+	uint8_t vapplinepos_end;/*306b*/
+	uint8_t shutter;	/* 0x3086 */
+	uint8_t haddave;	/* 0x30e8 */
+	uint8_t lanesel;    /* 0x3301 */
+};
+
+struct imx074_i2c_reg_conf {
+	unsigned short waddr;
+	unsigned short wdata;
+};
+
+enum imx074_test_mode_t {
+	TEST_OFF,
+	TEST_1,
+	TEST_2,
+	TEST_3
+};
+
+enum imx074_resolution_t {
+	QTR_SIZE,
+	FULL_SIZE,
+	INVALID_SIZE
+};
+enum imx074_setting {
+	RES_PREVIEW,
+	RES_CAPTURE
+};
+enum mt9p012_reg_update {
+	/* Sensor egisters that need to be updated during initialization */
+	REG_INIT,
+	/* Sensor egisters that needs periodic I2C writes */
+	UPDATE_PERIODIC,
+	/* All the sensor Registers will be updated */
+	UPDATE_ALL,
+	/* Not valid update */
+	UPDATE_INVALID
+};
+
+struct imx074_reg {
+	const struct reg_struct_init  *reg_pat_init;
+	const struct reg_struct  *reg_pat;
+};
+#endif /* IMX074_H */
diff --git a/drivers/media/platform/msm/camera_v1/imx074_reg.c b/drivers/media/platform/msm/camera_v1/imx074_reg.c
new file mode 100644
index 0000000..a9d19f2
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/imx074_reg.c
@@ -0,0 +1,111 @@
+/* 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 "imx074.h"
+const struct reg_struct_init imx074_reg_init[1] = {
+	{
+		/* PLL setting */
+		0x02,	/* pll_divider 0x0305 */
+		0x4B,	/* plstatim 0x302b */
+		0x03,	/* reg_3024 */
+		0x00,	/* image_orientation 0x0101 */
+		0x80,	/* vndmy_ablmgshlmt 0x300a*/
+		0x08,	/* y_opbaddr_start_di 3014*/
+		0x37,	/* 0x3015*/
+		0x01,	/* 0x301c*/
+		0x05,	/* 0x302c*/
+		0x26,	/* 0x3031*/
+		0x60,	/* 0x3041*/
+		0x24,	/* 0x3051 CLK DIV*/
+		0x34,	/* 0x3053*/
+		0xc0,	/* 0x3057*/
+		0x09,	/* 0x305c*/
+		0x07,	/* 0x305d */
+		0x30,	/* 0x3060 */
+		0x00,	/* 0x3065 */
+		0x08,	/* 0x30aa */
+		0x1c,	/* 0x30ab */
+		0x32,	/* 0x30b0 */
+		0x83,	/* 0x30b2 */
+		0x04,	/* 0x30d3 */
+		0x78,	/* 0x3106 */
+		0x82,	/* 0x310c */
+		0x05,	/* 0x3304 */
+		0x04,	/* 0x3305 */
+		0x11,	/* 0x3306 */
+		0x02,	/* 0x3307 */
+		0x0c,	/* 0x3308 */
+		0x06,	/* 0x3309 */
+		0x08,	/* 0x330a */
+		0x04,	/* 0x330b */
+		0x08,	/* 0x330c */
+		0x06,	/* 0x330d */
+		0x01,	/* 0x330f */
+		0x00,	/* 0x3381 */
+
+	}
+};
+
+/* Preview / Snapshot register settings	*/
+const struct reg_struct	imx074_reg_pat[2] = {
+	/*preview*/
+	{
+		0x2D, /*pll_multiplier*/
+		0x06, /*frame_length_lines_hi 0x0340*/
+		0x2D, /* frame_length_lines_lo 0x0341*/
+		0x00, /* y_addr_start 0x347 */
+		0x2F, /* y_add_end 0x034b */
+		0x08, /* x_output_size_msb0x034c */
+		0x38, /* x_output_size_lsb0x034d */
+		0x06, /*  y_output_size_msb0x034e */
+		0x18, /*  y_output_size_lsb0x034f */
+		0x01, /* x_even_inc 0x0381 */
+		0x03, /* x_odd_inc 0x0383 */
+		0x01, /* y_even_inc 0x0385 */
+		0x03, /* y_odd_inc 0x0387 */
+		0x80, /* hmodeadd0x3001 */
+		0x16, /* vmodeadd0x3016 */
+		0x24, /* vapplinepos_startox3069*/
+		0x53, /* vapplinepos_end306b*/
+		0x00,/*  shutter 0x3086 */
+		0x80, /* haddave 0x30e8 */
+		0x83, /* lanesel 0x3301 */
+	},
+
+	/*snapshot*/
+	{
+		0x26, /*pll_multiplier*/
+		0x0C, /* frame_length_lines_hi 0x0340*/
+		0x90, /* frame_length_lines_lo 0x0341*/
+		0x00, /* y_addr_start 0x347 */
+		0x2F, /* y_add_end 0x034b */
+		0x10, /* x_output_size_msb0x034c */
+		0x70, /* x_output_size_lsb0x034d */
+		0x0c, /* y_output_size_msb0x034e */
+		0x30, /* y_output_size_lsb0x034f */
+		0x01, /* x_even_inc 0x0381 */
+		0x01, /* x_odd_inc 0x0383 */
+		0x01, /* y_even_inc 0x0385 */
+		0x01, /* y_odd_inc 0x0387 */
+		0x00, /* hmodeadd0x3001 */
+		0x06, /* vmodeadd0x3016 */
+		0x24, /* vapplinepos_startox3069*/
+		0x53, /* vapplinepos_end306b*/
+		0x00, /* shutter 0x3086 */
+		0x00, /* haddave 0x30e8 */
+		0x03, /* lanesel 0x3301 */
+	}
+};
+struct imx074_reg imx074_regs = {
+	.reg_pat_init = &imx074_reg_init[0],
+	.reg_pat = &imx074_reg_pat[0],
+};
diff --git a/drivers/media/platform/msm/camera_v1/io/Makefile b/drivers/media/platform/msm/camera_v1/io/Makefile
new file mode 100644
index 0000000..9ec119c
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/io/Makefile
@@ -0,0 +1,17 @@
+GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
+
+ccflags-y += -Idrivers/media/platform/msm/camera_v1 -Idrivers/media/platform/msm/camera_v1/cci
+obj-$(CONFIG_MSM_CAMERA)   += msm_camera_io_util.o msm_camera_i2c.o
+ifeq ($(CONFIG_MSM_CAMERA_V4L2),y)
+  obj-$(CONFIG_MSM_CAMERA) += msm_camera_i2c_mux.o
+  obj-$(CONFIG_ARCH_MSM7X27A) += msm_io_7x27a_v4l2.o
+  obj-$(CONFIG_ARCH_MSM8X60) += msm_io_vfe31_v4l2.o
+  obj-$(CONFIG_ARCH_MSM7X30) += msm_io_vfe31_v4l2.o
+else
+  obj-$(CONFIG_ARCH_MSM7X27A) += msm_io_7x27a.o
+  obj-$(CONFIG_ARCH_MSM8X60) += msm_io_8x60.o
+  obj-$(CONFIG_ARCH_MSM7X30) += msm_io_vfe31.o
+endif
+obj-$(CONFIG_ARCH_MSM_ARM11) += msm_io7x.o
+obj-$(CONFIG_ARCH_QSD8X50) += msm_io8x.o
+obj-$(CONFIG_ARCH_MSM8960) += msm_io_8960.o
diff --git a/drivers/media/platform/msm/camera_v1/io/msm_camera_i2c.c b/drivers/media/platform/msm/camera_v1/io/msm_camera_i2c.c
new file mode 100644
index 0000000..bc826aa
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/io/msm_camera_i2c.c
@@ -0,0 +1,606 @@
+/* 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 <mach/camera.h>
+#include "msm_camera_i2c.h"
+#include "msm.h"
+#include "msm_cci.h"
+
+int32_t msm_camera_i2c_rxdata(struct msm_camera_i2c_client *dev_client,
+	unsigned char *rxdata, int data_length)
+{
+	int32_t rc = 0;
+	uint16_t saddr = dev_client->client->addr >> 1;
+	struct i2c_msg msgs[] = {
+		{
+			.addr  = saddr,
+			.flags = 0,
+			.len   = dev_client->addr_type,
+			.buf   = rxdata,
+		},
+		{
+			.addr  = saddr,
+			.flags = I2C_M_RD,
+			.len   = data_length,
+			.buf   = rxdata,
+		},
+	};
+	rc = i2c_transfer(dev_client->client->adapter, msgs, 2);
+	if (rc < 0)
+		S_I2C_DBG("msm_camera_i2c_rxdata failed 0x%x\n", saddr);
+	return rc;
+}
+
+int32_t msm_camera_i2c_txdata(struct msm_camera_i2c_client *dev_client,
+				unsigned char *txdata, int length)
+{
+	int32_t rc = 0;
+	uint16_t saddr = dev_client->client->addr >> 1;
+	struct i2c_msg msg[] = {
+		{
+			.addr = saddr,
+			.flags = 0,
+			.len = length,
+			.buf = txdata,
+		 },
+	};
+	rc = i2c_transfer(dev_client->client->adapter, msg, 1);
+	if (rc < 0)
+		S_I2C_DBG("msm_camera_i2c_txdata faild 0x%x\n", saddr);
+	return 0;
+}
+
+int32_t msm_camera_i2c_write(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t data,
+	enum msm_camera_i2c_data_type data_type)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[client->addr_type+data_type];
+	uint8_t len = 0;
+
+	if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
+		&& client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
+		|| (data_type != MSM_CAMERA_I2C_BYTE_DATA
+		&& data_type != MSM_CAMERA_I2C_WORD_DATA))
+		return rc;
+
+	S_I2C_DBG("%s reg addr = 0x%x data type: %d\n",
+			  __func__, addr, data_type);
+	if (client->cci_client) {
+		struct msm_camera_cci_ctrl cci_ctrl;
+		struct msm_camera_i2c_reg_conf reg_conf_tbl;
+		reg_conf_tbl.reg_addr = addr;
+		reg_conf_tbl.reg_data = data;
+		cci_ctrl.cmd = MSM_CCI_I2C_WRITE;
+		cci_ctrl.cci_info = client->cci_client;
+		cci_ctrl.cfg.cci_i2c_write_cfg.reg_conf_tbl = &reg_conf_tbl;
+		cci_ctrl.cfg.cci_i2c_write_cfg.data_type = data_type;
+		cci_ctrl.cfg.cci_i2c_write_cfg.addr_type = client->addr_type;
+		cci_ctrl.cfg.cci_i2c_write_cfg.size = 1;
+		rc = v4l2_subdev_call(client->cci_client->cci_subdev,
+				core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl);
+		CDBG("%s line %d rc = %d\n", __func__, __LINE__, rc);
+		rc = cci_ctrl.status;
+	} else {
+		if (client->addr_type == MSM_CAMERA_I2C_BYTE_ADDR) {
+			buf[0] = addr;
+			S_I2C_DBG("%s byte %d: 0x%x\n", __func__,
+				len, buf[len]);
+			len = 1;
+		} else if (client->addr_type == MSM_CAMERA_I2C_WORD_ADDR) {
+			buf[0] = addr >> BITS_PER_BYTE;
+			buf[1] = addr;
+			S_I2C_DBG("%s byte %d: 0x%x\n", __func__,
+				len, buf[len]);
+			S_I2C_DBG("%s byte %d: 0x%x\n", __func__,
+				len+1, buf[len+1]);
+			len = 2;
+		}
+		S_I2C_DBG("Data: 0x%x\n", data);
+		if (data_type == MSM_CAMERA_I2C_BYTE_DATA) {
+			buf[len] = data;
+			S_I2C_DBG("Byte %d: 0x%x\n", len, buf[len]);
+			len += 1;
+		} else if (data_type == MSM_CAMERA_I2C_WORD_DATA) {
+			buf[len] = data >> BITS_PER_BYTE;
+			buf[len+1] = data;
+			S_I2C_DBG("Byte %d: 0x%x\n", len, buf[len]);
+			S_I2C_DBG("Byte %d: 0x%x\n", len+1, buf[len+1]);
+			len += 2;
+		}
+		rc = msm_camera_i2c_txdata(client, buf, len);
+		if (rc < 0)
+			S_I2C_DBG("%s fail\n", __func__);
+	}
+	return rc;
+}
+
+int32_t msm_camera_i2c_write_seq(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint8_t *data, uint16_t num_byte)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[client->addr_type+num_byte];
+	uint8_t len = 0, i = 0;
+
+	if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
+		&& client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
+		|| num_byte == 0)
+		return rc;
+
+	S_I2C_DBG("%s reg addr = 0x%x num bytes: %d\n",
+			  __func__, addr, num_byte);
+	if (client->cci_client) {
+		struct msm_camera_cci_ctrl cci_ctrl;
+		struct msm_camera_i2c_reg_conf reg_conf_tbl[num_byte];
+		reg_conf_tbl[0].reg_addr = addr;
+		for (i = 0; i < num_byte; i++)
+			reg_conf_tbl[i].reg_data = data[i];
+		cci_ctrl.cmd = MSM_CCI_I2C_WRITE;
+		cci_ctrl.cci_info = client->cci_client;
+		cci_ctrl.cfg.cci_i2c_write_cfg.reg_conf_tbl = reg_conf_tbl;
+		cci_ctrl.cfg.cci_i2c_write_cfg.size = num_byte;
+		rc = v4l2_subdev_call(client->cci_client->cci_subdev,
+				core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl);
+		CDBG("%s line %d rc = %d\n", __func__, __LINE__, rc);
+		rc = cci_ctrl.status;
+	} else {
+		if (client->addr_type == MSM_CAMERA_I2C_BYTE_ADDR) {
+			buf[0] = addr;
+			S_I2C_DBG("%s byte %d: 0x%x\n", __func__,
+				len, buf[len]);
+			len = 1;
+		} else if (client->addr_type == MSM_CAMERA_I2C_WORD_ADDR) {
+			buf[0] = addr >> BITS_PER_BYTE;
+			buf[1] = addr;
+			S_I2C_DBG("%s byte %d: 0x%x\n", __func__,
+				len, buf[len]);
+			S_I2C_DBG("%s byte %d: 0x%x\n", __func__,
+				len+1, buf[len+1]);
+			len = 2;
+		}
+		for (i = 0; i < num_byte; i++) {
+			buf[i+len] = data[i];
+			S_I2C_DBG("Byte %d: 0x%x\n", i+len, buf[i+len]);
+			S_I2C_DBG("Data: 0x%x\n", data[i]);
+		}
+		rc = msm_camera_i2c_txdata(client, buf, len+num_byte);
+		if (rc < 0)
+			S_I2C_DBG("%s fail\n", __func__);
+	}
+	return rc;
+}
+
+int32_t msm_camera_i2c_set_mask(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t mask,
+	enum msm_camera_i2c_data_type data_type, uint16_t set_mask)
+{
+	int32_t rc;
+	uint16_t reg_data;
+
+	rc = msm_camera_i2c_read(client, addr, &reg_data, data_type);
+	if (rc < 0) {
+		S_I2C_DBG("%s read fail\n", __func__);
+		return rc;
+	}
+	S_I2C_DBG("%s addr: 0x%x data: 0x%x setmask: 0x%x\n",
+			__func__, addr, reg_data, mask);
+
+	if (set_mask)
+		reg_data |= mask;
+	else
+		reg_data &= ~mask;
+	S_I2C_DBG("%s write: 0x%x\n", __func__, reg_data);
+
+	rc = msm_camera_i2c_write(client, addr, reg_data, data_type);
+	if (rc < 0)
+		S_I2C_DBG("%s write fail\n", __func__);
+
+	return rc;
+}
+int32_t msm_camera_i2c_set_write_mask_data(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t data, int16_t mask,
+	enum msm_camera_i2c_data_type data_type)
+{
+	int32_t rc;
+	uint16_t reg_data;
+	CDBG("%s\n", __func__);
+	if (mask == -1)
+		return 0;
+	if (mask == 0)
+		rc = msm_camera_i2c_write(client, addr, data, data_type);
+	else{
+		rc = msm_camera_i2c_read(client, addr, &reg_data, data_type);
+		if (rc < 0) {
+			CDBG("%s read fail\n", __func__);
+			return rc;
+		}
+		reg_data  = reg_data & mask;
+		reg_data  = (reg_data | (data & (~mask)));
+		rc = msm_camera_i2c_write(client, addr, reg_data, data_type);
+		if (rc < 0)
+			CDBG("%s write fail\n", __func__);
+	}
+	return rc;
+}
+
+int32_t msm_camera_i2c_compare(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t data,
+	enum msm_camera_i2c_data_type data_type)
+{
+	int32_t rc = -EIO;
+	uint16_t reg_data = 0;
+	int data_len = 0;
+	switch (data_type) {
+	case MSM_CAMERA_I2C_BYTE_DATA:
+	case MSM_CAMERA_I2C_WORD_DATA:
+		data_len = data_type;
+		break;
+	case MSM_CAMERA_I2C_SET_BYTE_MASK:
+	case MSM_CAMERA_I2C_UNSET_BYTE_MASK:
+		data_len = MSM_CAMERA_I2C_BYTE_DATA;
+		break;
+	case MSM_CAMERA_I2C_SET_WORD_MASK:
+	case MSM_CAMERA_I2C_UNSET_WORD_MASK:
+		data_len = MSM_CAMERA_I2C_WORD_DATA;
+		break;
+	default:
+		pr_err("%s: Unsupport data type: %d\n", __func__, data_type);
+		break;
+	}
+
+	rc = msm_camera_i2c_read(client,
+		addr, &reg_data, data_len);
+	if (rc < 0)
+		return rc;
+
+	rc = 0;
+	switch (data_type) {
+	case MSM_CAMERA_I2C_BYTE_DATA:
+	case MSM_CAMERA_I2C_WORD_DATA:
+		if (data == reg_data)
+			return rc;
+		break;
+	case MSM_CAMERA_I2C_SET_BYTE_MASK:
+	case MSM_CAMERA_I2C_SET_WORD_MASK:
+		if ((reg_data & data) == data)
+			return rc;
+		break;
+	case MSM_CAMERA_I2C_UNSET_BYTE_MASK:
+	case MSM_CAMERA_I2C_UNSET_WORD_MASK:
+		if (!(reg_data & data))
+			return rc;
+		break;
+	default:
+		pr_err("%s: Unsupport data type: %d\n", __func__, data_type);
+		break;
+	}
+
+	S_I2C_DBG("%s: Register and data does not match\n", __func__);
+	rc = 1;
+	return rc;
+}
+
+int32_t msm_camera_i2c_poll(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t data,
+	enum msm_camera_i2c_data_type data_type)
+{
+	int32_t rc = -EIO;
+	int i;
+	S_I2C_DBG("%s: addr: 0x%x data: 0x%x dt: %d\n",
+		__func__, addr, data, data_type);
+
+	for (i = 0; i < 20; i++) {
+		rc = msm_camera_i2c_compare(client,
+			addr, data, data_type);
+		if (rc == 0 || rc < 0)
+			break;
+		usleep_range(10000, 11000);
+	}
+	return rc;
+}
+
+int32_t msm_camera_i2c_write_table_w_microdelay(
+	struct msm_camera_i2c_client *client,
+	struct msm_camera_i2c_reg_tbl *reg_tbl, uint16_t size,
+	enum msm_camera_i2c_data_type data_type)
+{
+	int i;
+	int32_t rc = -EFAULT;
+
+	if (!client || !reg_tbl)
+		return rc;
+
+	if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
+		&& client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
+		|| (data_type != MSM_CAMERA_I2C_BYTE_DATA
+		&& data_type != MSM_CAMERA_I2C_WORD_DATA))
+		return rc;
+
+	for (i = 0; i < size; i++) {
+		rc = msm_camera_i2c_write(client, reg_tbl->reg_addr,
+			reg_tbl->reg_data, data_type);
+		if (rc < 0)
+			break;
+		if (reg_tbl->delay)
+			usleep_range(reg_tbl->delay, reg_tbl->delay + 1000);
+		reg_tbl++;
+	}
+	return rc;
+}
+
+int32_t msm_camera_i2c_write_bayer_table(
+	struct msm_camera_i2c_client *client,
+	struct msm_camera_i2c_reg_setting *write_setting)
+{
+	int i;
+	int32_t rc = -EFAULT;
+	struct msm_camera_i2c_reg_array *reg_setting;
+
+	if (!client || !write_setting)
+		return rc;
+
+	reg_setting = write_setting->reg_setting;
+	client->addr_type = write_setting->addr_type;
+	if ((write_setting->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
+		&& write_setting->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
+		|| (write_setting->data_type != MSM_CAMERA_I2C_BYTE_DATA
+		&& write_setting->data_type != MSM_CAMERA_I2C_WORD_DATA))
+		return rc;
+	for (i = 0; i < write_setting->size; i++) {
+		rc = msm_camera_i2c_write(client, reg_setting->reg_addr,
+			reg_setting->reg_data, write_setting->data_type);
+		if (rc < 0)
+			break;
+		reg_setting++;
+	}
+	if (write_setting->delay > 20)
+		msleep(write_setting->delay);
+	else if (write_setting->delay)
+		usleep_range(write_setting->delay * 1000, (write_setting->delay
+			* 1000) + 1000);
+	return rc;
+}
+
+int32_t msm_camera_i2c_write_tbl(struct msm_camera_i2c_client *client,
+	struct msm_camera_i2c_reg_conf *reg_conf_tbl, uint16_t size,
+	enum msm_camera_i2c_data_type data_type)
+{
+	int i;
+	int32_t rc = -EFAULT;
+	for (i = 0; i < size; i++) {
+		enum msm_camera_i2c_data_type dt;
+		if (reg_conf_tbl->cmd_type == MSM_CAMERA_I2C_CMD_POLL) {
+			rc = msm_camera_i2c_poll(client,
+				reg_conf_tbl->reg_addr,
+				reg_conf_tbl->reg_data,
+				reg_conf_tbl->dt);
+		} else {
+			if (reg_conf_tbl->dt == 0)
+				dt = data_type;
+			else
+				dt = reg_conf_tbl->dt;
+			switch (dt) {
+			case MSM_CAMERA_I2C_BYTE_DATA:
+			case MSM_CAMERA_I2C_WORD_DATA:
+				rc = msm_camera_i2c_write(
+					client,
+					reg_conf_tbl->reg_addr,
+					reg_conf_tbl->reg_data, dt);
+				break;
+			case MSM_CAMERA_I2C_SET_BYTE_MASK:
+				rc = msm_camera_i2c_set_mask(client,
+					reg_conf_tbl->reg_addr,
+					reg_conf_tbl->reg_data,
+					MSM_CAMERA_I2C_BYTE_DATA, 1);
+				break;
+			case MSM_CAMERA_I2C_UNSET_BYTE_MASK:
+				rc = msm_camera_i2c_set_mask(client,
+					reg_conf_tbl->reg_addr,
+					reg_conf_tbl->reg_data,
+					MSM_CAMERA_I2C_BYTE_DATA, 0);
+				break;
+			case MSM_CAMERA_I2C_SET_WORD_MASK:
+				rc = msm_camera_i2c_set_mask(client,
+					reg_conf_tbl->reg_addr,
+					reg_conf_tbl->reg_data,
+					MSM_CAMERA_I2C_WORD_DATA, 1);
+				break;
+			case MSM_CAMERA_I2C_UNSET_WORD_MASK:
+				rc = msm_camera_i2c_set_mask(client,
+					reg_conf_tbl->reg_addr,
+					reg_conf_tbl->reg_data,
+					MSM_CAMERA_I2C_WORD_DATA, 0);
+				break;
+			case MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA:
+				rc = msm_camera_i2c_set_write_mask_data(
+					client,
+					reg_conf_tbl->reg_addr,
+					reg_conf_tbl->reg_data,
+					reg_conf_tbl->mask,
+					MSM_CAMERA_I2C_BYTE_DATA);
+				break;
+			default:
+				pr_err("%s: Unsupport data type: %d\n",
+					__func__, dt);
+				break;
+			}
+		}
+		if (rc < 0)
+			break;
+		reg_conf_tbl++;
+	}
+	return rc;
+}
+
+int32_t msm_camera_i2c_read(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t *data,
+	enum msm_camera_i2c_data_type data_type)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[client->addr_type+data_type];
+
+	if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
+		&& client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
+		|| (data_type != MSM_CAMERA_I2C_BYTE_DATA
+		&& data_type != MSM_CAMERA_I2C_WORD_DATA))
+		return rc;
+
+	if (client->cci_client) {
+		struct msm_camera_cci_ctrl cci_ctrl;
+		cci_ctrl.cmd = MSM_CCI_I2C_READ;
+		cci_ctrl.cci_info = client->cci_client;
+		cci_ctrl.cfg.cci_i2c_read_cfg.addr = addr;
+		cci_ctrl.cfg.cci_i2c_read_cfg.addr_type = client->addr_type;
+		cci_ctrl.cfg.cci_i2c_read_cfg.data = buf;
+		cci_ctrl.cfg.cci_i2c_read_cfg.num_byte = data_type;
+		rc = v4l2_subdev_call(client->cci_client->cci_subdev,
+				core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl);
+		CDBG("%s line %d rc = %d\n", __func__, __LINE__, rc);
+		rc = cci_ctrl.status;
+	} else {
+		if (client->addr_type == MSM_CAMERA_I2C_BYTE_ADDR) {
+			buf[0] = addr;
+		} else if (client->addr_type == MSM_CAMERA_I2C_WORD_ADDR) {
+			buf[0] = addr >> BITS_PER_BYTE;
+			buf[1] = addr;
+		}
+		rc = msm_camera_i2c_rxdata(client, buf, data_type);
+		if (rc < 0) {
+			S_I2C_DBG("%s fail\n", __func__);
+			return rc;
+		}
+	}
+	if (data_type == MSM_CAMERA_I2C_BYTE_DATA)
+		*data = buf[0];
+	else
+		*data = buf[0] << 8 | buf[1];
+
+	S_I2C_DBG("%s addr = 0x%x data: 0x%x\n", __func__, addr, *data);
+	return rc;
+}
+
+int32_t msm_camera_i2c_read_seq(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint8_t *data, uint16_t num_byte)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[client->addr_type+num_byte];
+	int i;
+
+	if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
+		&& client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
+		|| num_byte == 0)
+		return rc;
+
+	if (client->cci_client) {
+		struct msm_camera_cci_ctrl cci_ctrl;
+		cci_ctrl.cmd = MSM_CCI_I2C_READ;
+		cci_ctrl.cci_info = client->cci_client;
+		cci_ctrl.cfg.cci_i2c_read_cfg.addr = addr;
+		cci_ctrl.cfg.cci_i2c_read_cfg.addr_type = client->addr_type;
+		cci_ctrl.cfg.cci_i2c_read_cfg.data = buf;
+		cci_ctrl.cfg.cci_i2c_read_cfg.num_byte = num_byte;
+		rc = v4l2_subdev_call(client->cci_client->cci_subdev,
+				core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl);
+		CDBG("%s line %d rc = %d\n", __func__, __LINE__, rc);
+		rc = cci_ctrl.status;
+	} else {
+		if (client->addr_type == MSM_CAMERA_I2C_BYTE_ADDR) {
+			buf[0] = addr;
+		} else if (client->addr_type == MSM_CAMERA_I2C_WORD_ADDR) {
+			buf[0] = addr >> BITS_PER_BYTE;
+			buf[1] = addr;
+		}
+		rc = msm_camera_i2c_rxdata(client, buf, num_byte);
+		if (rc < 0) {
+			S_I2C_DBG("%s fail\n", __func__);
+			return rc;
+		}
+	}
+
+	S_I2C_DBG("%s addr = 0x%x", __func__, addr);
+	for (i = 0; i < num_byte; i++) {
+		data[i] = buf[i];
+		S_I2C_DBG("Byte %d: 0x%x\n", i, buf[i]);
+		S_I2C_DBG("Data: 0x%x\n", data[i]);
+	}
+	return rc;
+}
+
+int32_t msm_sensor_write_conf_array(struct msm_camera_i2c_client *client,
+			struct msm_camera_i2c_conf_array *array, uint16_t index)
+{
+	int32_t rc;
+
+	rc = msm_camera_i2c_write_tbl(client,
+		(struct msm_camera_i2c_reg_conf *) array[index].conf,
+		array[index].size, array[index].data_type);
+	if (array[index].delay > 20)
+		msleep(array[index].delay);
+	else
+		usleep_range(array[index].delay*1000,
+					(array[index].delay+1)*1000);
+	return rc;
+}
+
+int32_t msm_sensor_write_enum_conf_array(struct msm_camera_i2c_client *client,
+			struct msm_camera_i2c_enum_conf_array *conf,
+			uint16_t enum_val)
+{
+	int32_t rc = -1, i;
+	for (i = 0; i < conf->num_enum; i++) {
+		if (conf->conf_enum[i] == enum_val)
+			break;
+		if (conf->conf_enum[i] > enum_val)
+			break;
+	}
+	if (i == conf->num_enum)
+		i = conf->num_enum - 1;
+
+	if (i >= conf->num_index)
+		return rc;
+	rc = msm_sensor_write_all_conf_array(client,
+		&conf->conf[i*conf->num_conf], conf->num_conf);
+
+	if (conf->delay > 20)
+		msleep(conf->delay);
+	else
+		usleep_range(conf->delay*1000,
+					(conf->delay+1)*1000);
+	return rc;
+}
+
+int32_t msm_sensor_write_all_conf_array(struct msm_camera_i2c_client *client,
+			struct msm_camera_i2c_conf_array *array, uint16_t size)
+{
+	int32_t rc = 0, i;
+	for (i = 0; i < size; i++) {
+		rc = msm_sensor_write_conf_array(client, array, i);
+		if (rc < 0)
+			break;
+	}
+	return rc;
+}
+
+int32_t msm_sensor_cci_util(struct msm_camera_i2c_client *client,
+	uint16_t cci_cmd)
+{
+	int32_t rc = 0;
+	struct msm_camera_cci_ctrl cci_ctrl;
+
+	CDBG("%s line %d\n", __func__, __LINE__);
+	cci_ctrl.cmd = cci_cmd;
+	cci_ctrl.cci_info = client->cci_client;
+	rc = v4l2_subdev_call(client->cci_client->cci_subdev,
+			core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl);
+	CDBG("%s line %d rc = %d\n", __func__, __LINE__, rc);
+	return cci_ctrl.status;
+}
diff --git a/drivers/media/platform/msm/camera_v1/io/msm_camera_i2c.h b/drivers/media/platform/msm/camera_v1/io/msm_camera_i2c.h
new file mode 100644
index 0000000..ce42607
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/io/msm_camera_i2c.h
@@ -0,0 +1,115 @@
+/* Copyright (c) 2011-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.
+ */
+
+#ifndef MSM_CAMERA_I2C_H
+#define MSM_CAMERA_I2C_H
+
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <mach/camera.h>
+#include <media/v4l2-subdev.h>
+#include <media/msm_camera.h>
+
+#define CONFIG_MSM_CAMERA_I2C_DBG 0
+
+#if CONFIG_MSM_CAMERA_I2C_DBG
+#define S_I2C_DBG(fmt, args...) printk(fmt, ##args)
+#else
+#define S_I2C_DBG(fmt, args...) CDBG(fmt, ##args)
+#endif
+
+struct msm_camera_i2c_client {
+	struct i2c_client *client;
+	struct msm_camera_cci_client *cci_client;
+	enum msm_camera_i2c_reg_addr_type addr_type;
+};
+
+struct msm_camera_i2c_reg_tbl {
+	uint16_t reg_addr;
+	uint16_t reg_data;
+	uint16_t delay;
+};
+
+struct msm_camera_i2c_conf_array {
+	struct msm_camera_i2c_reg_conf *conf;
+	uint16_t size;
+	uint16_t delay;
+	enum msm_camera_i2c_data_type data_type;
+};
+
+struct msm_camera_i2c_enum_conf_array {
+	struct msm_camera_i2c_conf_array *conf;
+	int *conf_enum;
+	uint16_t num_enum;
+	uint16_t num_index;
+	uint16_t num_conf;
+	uint16_t delay;
+	enum msm_camera_i2c_data_type data_type;
+};
+
+int32_t msm_camera_i2c_rxdata(struct msm_camera_i2c_client *client,
+	unsigned char *rxdata, int data_length);
+
+int32_t msm_camera_i2c_txdata(struct msm_camera_i2c_client *client,
+	unsigned char *txdata, int length);
+
+int32_t msm_camera_i2c_read(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t *data,
+	enum msm_camera_i2c_data_type data_type);
+
+int32_t msm_camera_i2c_read_seq(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint8_t *data, uint16_t num_byte);
+
+int32_t msm_camera_i2c_write(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t data,
+	enum msm_camera_i2c_data_type data_type);
+
+int32_t msm_camera_i2c_write_seq(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint8_t *data, uint16_t num_byte);
+
+int32_t msm_camera_i2c_set_mask(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t mask,
+	enum msm_camera_i2c_data_type data_type, uint16_t flag);
+
+int32_t msm_camera_i2c_compare(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t data,
+	enum msm_camera_i2c_data_type data_type);
+
+int32_t msm_camera_i2c_poll(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t data,
+	enum msm_camera_i2c_data_type data_type);
+
+int32_t msm_camera_i2c_write_table_w_microdelay(
+	struct msm_camera_i2c_client *client,
+	struct msm_camera_i2c_reg_tbl *reg_tbl, uint16_t size,
+	enum msm_camera_i2c_data_type data_type);
+
+int32_t msm_camera_i2c_write_bayer_table(
+	struct msm_camera_i2c_client *client,
+	struct msm_camera_i2c_reg_setting *write_setting);
+
+int32_t msm_camera_i2c_write_tbl(struct msm_camera_i2c_client *client,
+	struct msm_camera_i2c_reg_conf *reg_conf_tbl, uint16_t size,
+	enum msm_camera_i2c_data_type data_type);
+
+int32_t msm_sensor_write_conf_array(struct msm_camera_i2c_client *client,
+	struct msm_camera_i2c_conf_array *array, uint16_t index);
+
+int32_t msm_sensor_write_enum_conf_array(struct msm_camera_i2c_client *client,
+	struct msm_camera_i2c_enum_conf_array *conf, uint16_t enum_val);
+
+int32_t msm_sensor_write_all_conf_array(struct msm_camera_i2c_client *client,
+	struct msm_camera_i2c_conf_array *array, uint16_t size);
+
+int32_t msm_sensor_cci_util(struct msm_camera_i2c_client *client,
+	uint16_t cci_cmd);
+#endif
diff --git a/drivers/media/platform/msm/camera_v1/io/msm_camera_i2c_mux.c b/drivers/media/platform/msm/camera_v1/io/msm_camera_i2c_mux.c
new file mode 100644
index 0000000..b24a91a
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/io/msm_camera_i2c_mux.c
@@ -0,0 +1,187 @@
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <mach/board.h>
+#include <mach/camera.h>
+#include "msm.h"
+#include "msm_camera_i2c_mux.h"
+
+static int msm_i2c_mux_config(struct i2c_mux_device *mux_device, uint8_t *mode)
+{
+	uint32_t val;
+	val = msm_camera_io_r(mux_device->ctl_base);
+	if (*mode == MODE_DUAL) {
+		msm_camera_io_w(val | 0x3, mux_device->ctl_base);
+	} else if (*mode == MODE_L) {
+		msm_camera_io_w(((val | 0x2) & ~(0x1)), mux_device->ctl_base);
+		val = msm_camera_io_r(mux_device->ctl_base);
+		CDBG("the camio mode config left value is %d\n", val);
+	} else {
+		msm_camera_io_w(((val | 0x1) & ~(0x2)), mux_device->ctl_base);
+		val = msm_camera_io_r(mux_device->ctl_base);
+		CDBG("the camio mode config right value is %d\n", val);
+	}
+	return 0;
+}
+
+static int msm_i2c_mux_init(struct i2c_mux_device *mux_device)
+{
+	int rc = 0, val = 0;
+	if (mux_device->use_count == 0) {
+		mux_device->ctl_base = ioremap(mux_device->ctl_mem->start,
+			resource_size(mux_device->ctl_mem));
+		if (!mux_device->ctl_base) {
+			rc = -ENOMEM;
+			return rc;
+		}
+		mux_device->rw_base = ioremap(mux_device->rw_mem->start,
+			resource_size(mux_device->rw_mem));
+		if (!mux_device->rw_base) {
+			rc = -ENOMEM;
+			iounmap(mux_device->ctl_base);
+			return rc;
+		}
+		val = msm_camera_io_r(mux_device->rw_base);
+		msm_camera_io_w((val | 0x200), mux_device->rw_base);
+	}
+	mux_device->use_count++;
+	return 0;
+};
+
+static int msm_i2c_mux_release(struct i2c_mux_device *mux_device)
+{
+	int val = 0;
+	mux_device->use_count--;
+	if (mux_device->use_count == 0) {
+		val = msm_camera_io_r(mux_device->rw_base);
+		msm_camera_io_w((val & ~0x200), mux_device->rw_base);
+		iounmap(mux_device->rw_base);
+		iounmap(mux_device->ctl_base);
+	}
+	return 0;
+}
+
+static long msm_i2c_mux_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int cmd, void *arg)
+{
+	struct i2c_mux_device *mux_device;
+	int rc = 0;
+	mux_device = v4l2_get_subdevdata(sd);
+	if (mux_device == NULL) {
+		rc = -ENOMEM;
+		return rc;
+	}
+	mutex_lock(&mux_device->mutex);
+	switch (cmd) {
+	case VIDIOC_MSM_I2C_MUX_CFG:
+		rc = msm_i2c_mux_config(mux_device, (uint8_t *) arg);
+		break;
+	case VIDIOC_MSM_I2C_MUX_INIT:
+		rc = msm_i2c_mux_init(mux_device);
+		break;
+	case VIDIOC_MSM_I2C_MUX_RELEASE:
+		rc = msm_i2c_mux_release(mux_device);
+		break;
+	default:
+		rc = -ENOIOCTLCMD;
+	}
+	mutex_unlock(&mux_device->mutex);
+	return rc;
+}
+
+static struct v4l2_subdev_core_ops msm_i2c_mux_subdev_core_ops = {
+	.ioctl = &msm_i2c_mux_subdev_ioctl,
+};
+
+static const struct v4l2_subdev_ops msm_i2c_mux_subdev_ops = {
+	.core = &msm_i2c_mux_subdev_core_ops,
+};
+
+static int __devinit i2c_mux_probe(struct platform_device *pdev)
+{
+	struct i2c_mux_device *mux_device;
+	int rc = 0;
+	CDBG("%s: device id = %d\n", __func__, pdev->id);
+	mux_device = kzalloc(sizeof(struct i2c_mux_device), GFP_KERNEL);
+	if (!mux_device) {
+		pr_err("%s: no enough memory\n", __func__);
+		return -ENOMEM;
+	}
+
+	v4l2_subdev_init(&mux_device->subdev, &msm_i2c_mux_subdev_ops);
+	v4l2_set_subdevdata(&mux_device->subdev, mux_device);
+	platform_set_drvdata(pdev, &mux_device->subdev);
+	mutex_init(&mux_device->mutex);
+
+	mux_device->ctl_mem = platform_get_resource_byname(pdev,
+					IORESOURCE_MEM, "i2c_mux_ctl");
+	if (!mux_device->ctl_mem) {
+		pr_err("%s: no mem resource?\n", __func__);
+		rc = -ENODEV;
+		goto i2c_mux_no_resource;
+	}
+	mux_device->ctl_io = request_mem_region(mux_device->ctl_mem->start,
+		resource_size(mux_device->ctl_mem), pdev->name);
+	if (!mux_device->ctl_io) {
+		pr_err("%s: no valid mem region\n", __func__);
+		rc = -EBUSY;
+		goto i2c_mux_no_resource;
+	}
+	mux_device->rw_mem = platform_get_resource_byname(pdev,
+					IORESOURCE_MEM, "i2c_mux_rw");
+	if (!mux_device->rw_mem) {
+		pr_err("%s: no mem resource?\n", __func__);
+		rc = -ENODEV;
+		goto i2c_mux_no_resource;
+	}
+	mux_device->rw_io = request_mem_region(mux_device->rw_mem->start,
+		resource_size(mux_device->rw_mem), pdev->name);
+	if (!mux_device->rw_io) {
+		pr_err("%s: no valid mem region\n", __func__);
+		rc = -EBUSY;
+		goto i2c_mux_no_resource;
+	}
+	mux_device->pdev = pdev;
+	return 0;
+
+i2c_mux_no_resource:
+	mutex_destroy(&mux_device->mutex);
+	kfree(mux_device);
+	return 0;
+}
+
+static struct platform_driver i2c_mux_driver = {
+	.probe = i2c_mux_probe,
+	.driver = {
+		.name = MSM_I2C_MUX_DRV_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init msm_camera_i2c_mux_init_module(void)
+{
+	return platform_driver_register(&i2c_mux_driver);
+}
+
+static void __exit msm_camera_i2c_mux_exit_module(void)
+{
+	platform_driver_unregister(&i2c_mux_driver);
+}
+
+module_init(msm_camera_i2c_mux_init_module);
+module_exit(msm_camera_i2c_mux_exit_module);
+MODULE_DESCRIPTION("MSM Camera I2C mux driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/io/msm_camera_i2c_mux.h b/drivers/media/platform/msm/camera_v1/io/msm_camera_i2c_mux.h
new file mode 100644
index 0000000..30f908b
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/io/msm_camera_i2c_mux.h
@@ -0,0 +1,46 @@
+/* Copyright (c) 2011-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.
+ */
+
+#ifndef MSM_I2C_MUX_H
+#define MSM_I2C_MUX_H
+
+#include <linux/io.h>
+#include <media/v4l2-subdev.h>
+
+struct i2c_mux_device {
+	struct platform_device *pdev;
+	struct v4l2_subdev subdev;
+	struct resource *ctl_mem;
+	struct resource *ctl_io;
+	void __iomem *ctl_base;
+	struct resource *rw_mem;
+	struct resource *rw_io;
+	void __iomem *rw_base;
+	struct mutex mutex;
+	unsigned use_count;
+};
+
+struct i2c_mux_cfg_params {
+	struct v4l2_subdev *subdev;
+	void *parms;
+};
+
+#define VIDIOC_MSM_I2C_MUX_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 13, struct i2c_mux_cfg_params)
+
+#define VIDIOC_MSM_I2C_MUX_INIT \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 14, struct v4l2_subdev*)
+
+#define VIDIOC_MSM_I2C_MUX_RELEASE \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 15, struct v4l2_subdev*)
+
+#endif
diff --git a/drivers/media/video/msm/io/msm_camera_io_util.c b/drivers/media/platform/msm/camera_v1/io/msm_camera_io_util.c
similarity index 100%
rename from drivers/media/video/msm/io/msm_camera_io_util.c
rename to drivers/media/platform/msm/camera_v1/io/msm_camera_io_util.c
diff --git a/drivers/media/platform/msm/camera_v1/io/msm_io7x.c b/drivers/media/platform/msm/camera_v1/io/msm_io7x.c
new file mode 100644
index 0000000..ebdaeb1
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/io/msm_io7x.c
@@ -0,0 +1,318 @@
+/* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <mach/gpio.h>
+#include <mach/board.h>
+#include <mach/camera.h>
+#include <mach/clk.h>
+
+#define CAMIF_CFG_RMSK 0x1fffff
+#define CAM_SEL_BMSK 0x2
+#define CAM_PCLK_SRC_SEL_BMSK 0x60000
+#define CAM_PCLK_INVERT_BMSK 0x80000
+#define CAM_PAD_REG_SW_RESET_BMSK 0x100000
+
+#define EXT_CAM_HSYNC_POL_SEL_BMSK 0x10000
+#define EXT_CAM_VSYNC_POL_SEL_BMSK 0x8000
+#define MDDI_CLK_CHICKEN_BIT_BMSK  0x80
+
+#define CAM_SEL_SHFT 0x1
+#define CAM_PCLK_SRC_SEL_SHFT 0x11
+#define CAM_PCLK_INVERT_SHFT 0x13
+#define CAM_PAD_REG_SW_RESET_SHFT 0x14
+
+#define EXT_CAM_HSYNC_POL_SEL_SHFT 0x10
+#define EXT_CAM_VSYNC_POL_SEL_SHFT 0xF
+#define MDDI_CLK_CHICKEN_BIT_SHFT  0x7
+#define APPS_RESET_OFFSET 0x00000210
+
+static struct clk *camio_vfe_mdc_clk;
+static struct clk *camio_mdc_clk;
+static struct clk *camio_vfe_clk;
+
+static struct msm_camera_io_ext camio_ext;
+static struct resource *appio, *mdcio;
+void __iomem *appbase, *mdcbase;
+
+static struct resource *appio, *mdcio;
+void __iomem *appbase, *mdcbase;
+
+int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
+{
+	int rc = -1;
+	struct clk *clk = NULL;
+
+	switch (clktype) {
+	case CAMIO_VFE_MDC_CLK:
+		clk = camio_vfe_mdc_clk = clk_get(NULL, "vfe_mdc_clk");
+		break;
+
+	case CAMIO_MDC_CLK:
+		clk = camio_mdc_clk = clk_get(NULL, "mdc_clk");
+		break;
+
+	case CAMIO_VFE_CLK:
+		clk = camio_vfe_clk = clk_get(NULL, "vfe_clk");
+		break;
+
+	default:
+		break;
+	}
+
+	if (!IS_ERR(clk)) {
+		clk_enable(clk);
+		rc = 0;
+	}
+
+	return rc;
+}
+
+int msm_camio_clk_disable(enum msm_camio_clk_type clktype)
+{
+	int rc = -1;
+	struct clk *clk = NULL;
+
+	switch (clktype) {
+	case CAMIO_VFE_MDC_CLK:
+		clk = camio_vfe_mdc_clk;
+		break;
+
+	case CAMIO_MDC_CLK:
+		clk = camio_mdc_clk;
+		break;
+
+	case CAMIO_VFE_CLK:
+		clk = camio_vfe_clk;
+		break;
+
+	default:
+		break;
+	}
+
+	if (!IS_ERR(clk)) {
+		clk_disable(clk);
+		clk_put(clk);
+		rc = 0;
+	}
+
+	return rc;
+}
+
+void msm_camio_clk_rate_set(int rate)
+{
+	struct clk *clk = camio_vfe_clk;
+
+	if (clk != ERR_PTR(-ENOENT))
+		clk_set_rate(clk, rate);
+}
+
+int msm_camio_enable(struct platform_device *pdev)
+{
+	int rc = 0;
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+
+	camio_ext = camdev->ioext;
+
+	appio = request_mem_region(camio_ext.appphy,
+		camio_ext.appsz, pdev->name);
+	if (!appio) {
+		rc = -EBUSY;
+		goto enable_fail;
+	}
+
+	appbase = ioremap(camio_ext.appphy,
+		camio_ext.appsz);
+	if (!appbase) {
+		rc = -ENOMEM;
+		goto apps_no_mem;
+	}
+
+	msm_camio_clk_enable(CAMIO_VFE_CLK);
+	msm_camio_clk_enable(CAMIO_MDC_CLK);
+	return 0;
+apps_no_mem:
+	release_mem_region(camio_ext.appphy, camio_ext.appsz);
+enable_fail:
+	return rc;
+}
+
+int msm_camio_sensor_clk_on(struct platform_device *pdev)
+{
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+	int32_t rc = 0;
+	camio_ext = camdev->ioext;
+	mdcio = request_mem_region(camio_ext.mdcphy,
+		camio_ext.mdcsz, pdev->name);
+	if (!mdcio)
+		rc = -EBUSY;
+	mdcbase = ioremap(camio_ext.mdcphy,
+		camio_ext.mdcsz);
+	if (!mdcbase) {
+		rc = -EINVAL;
+		goto mdc_no_mem;
+	}
+	camdev->camera_gpio_on();
+	return msm_camio_clk_enable(CAMIO_VFE_MDC_CLK);
+
+mdc_no_mem:
+	release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
+	return rc;
+}
+
+int msm_camio_sensor_clk_off(struct platform_device *pdev)
+{
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+	camdev->camera_gpio_off();
+	iounmap(mdcbase);
+	release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
+	return msm_camio_clk_disable(CAMIO_VFE_MDC_CLK);
+}
+
+void msm_camio_disable(struct platform_device *pdev)
+{
+	iounmap(appbase);
+	release_mem_region(camio_ext.appphy, camio_ext.appsz);
+	msm_camio_clk_disable(CAMIO_VFE_CLK);
+	msm_camio_clk_disable(CAMIO_MDC_CLK);
+}
+
+void msm_disable_io_gpio_clk(struct platform_device *pdev)
+{
+	return;
+}
+
+void msm_camio_camif_pad_reg_reset(void)
+{
+	uint32_t reg;
+	uint32_t mask, value;
+
+	/* select CLKRGM_VFE_SRC_CAM_VFE_SRC:  internal source */
+	msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_INTERNAL);
+
+	reg = (msm_camera_io_r_mb(mdcbase)) & CAMIF_CFG_RMSK;
+
+	mask = CAM_SEL_BMSK |
+		CAM_PCLK_SRC_SEL_BMSK |
+		CAM_PCLK_INVERT_BMSK;
+
+	value = 1 << CAM_SEL_SHFT |
+		3 << CAM_PCLK_SRC_SEL_SHFT |
+		0 << CAM_PCLK_INVERT_SHFT;
+
+	msm_camera_io_w_mb((reg & (~mask)) | (value & mask), mdcbase);
+	usleep_range(10000, 11000);
+
+	reg = (msm_camera_io_r_mb(mdcbase)) & CAMIF_CFG_RMSK;
+	mask = CAM_PAD_REG_SW_RESET_BMSK;
+	value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
+	msm_camera_io_w_mb((reg & (~mask)) | (value & mask), mdcbase);
+	usleep_range(10000, 11000);
+
+	reg = (msm_camera_io_r_mb(mdcbase)) & CAMIF_CFG_RMSK;
+	mask = CAM_PAD_REG_SW_RESET_BMSK;
+	value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
+	msm_camera_io_w_mb((reg & (~mask)) | (value & mask), mdcbase);
+	usleep_range(10000, 11000);
+
+	msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_EXTERNAL);
+	usleep_range(10000, 11000);
+}
+
+void msm_camio_vfe_blk_reset(void)
+{
+	uint32_t val;
+
+	/* do apps reset */
+	val = msm_camera_io_r_mb(appbase + 0x00000210);
+	val |= 0x1;
+	msm_camera_io_w_mb(val, appbase + 0x00000210);
+	usleep_range(10000, 11000);
+
+	val = msm_camera_io_r_mb(appbase + 0x00000210);
+	val &= ~0x1;
+	msm_camera_io_w_mb(val, appbase + 0x00000210);
+	usleep_range(10000, 11000);
+
+	/* do axi reset */
+	val = msm_camera_io_r_mb(appbase + 0x00000208);
+	val |= 0x1;
+	msm_camera_io_w_mb(val, appbase + 0x00000208);
+	usleep_range(10000, 11000);
+
+	val = msm_camera_io_r_mb(appbase + 0x00000208);
+	val &= ~0x1;
+	msm_camera_io_w_mb(val, appbase + 0x00000208);
+	usleep_range(10000, 11000);
+}
+
+void msm_camio_camif_pad_reg_reset_2(void)
+{
+	uint32_t reg;
+	uint32_t mask, value;
+
+	reg = (msm_camera_io_r_mb(mdcbase)) & CAMIF_CFG_RMSK;
+	mask = CAM_PAD_REG_SW_RESET_BMSK;
+	value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
+	msm_camera_io_w_mb((reg & (~mask)) | (value & mask), mdcbase);
+	usleep_range(10000, 11000);
+
+	reg = (msm_camera_io_r_mb(mdcbase)) & CAMIF_CFG_RMSK;
+	mask = CAM_PAD_REG_SW_RESET_BMSK;
+	value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
+	msm_camera_io_w_mb((reg & (~mask)) | (value & mask), mdcbase);
+	usleep_range(10000, 11000);
+}
+
+void msm_camio_clk_sel(enum msm_camio_clk_src_type srctype)
+{
+	struct clk *clk = NULL;
+
+	clk = camio_vfe_clk;
+
+	if (clk != NULL && clk != ERR_PTR(-ENOENT)) {
+		switch (srctype) {
+		case MSM_CAMIO_CLK_SRC_INTERNAL:
+			clk_set_flags(clk, 0x00000100 << 1);
+			break;
+
+		case MSM_CAMIO_CLK_SRC_EXTERNAL:
+			clk_set_flags(clk, 0x00000100);
+			break;
+
+		default:
+			break;
+		}
+	}
+}
+
+int msm_camio_probe_on(struct platform_device *pdev)
+{
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+	camdev->camera_gpio_on();
+	return msm_camio_clk_enable(CAMIO_VFE_CLK);
+}
+
+int msm_camio_probe_off(struct platform_device *pdev)
+{
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+	camdev->camera_gpio_off();
+	return msm_camio_clk_disable(CAMIO_VFE_CLK);
+}
diff --git a/drivers/media/platform/msm/camera_v1/io/msm_io8x.c b/drivers/media/platform/msm/camera_v1/io/msm_io8x.c
new file mode 100644
index 0000000..dba93a0
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/io/msm_io8x.c
@@ -0,0 +1,331 @@
+/* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <mach/gpio.h>
+#include <mach/board.h>
+#include <mach/camera.h>
+#include <mach/clk.h>
+
+#define CAMIF_CFG_RMSK 0x1fffff
+#define CAM_SEL_BMSK 0x2
+#define CAM_PCLK_SRC_SEL_BMSK 0x60000
+#define CAM_PCLK_INVERT_BMSK 0x80000
+#define CAM_PAD_REG_SW_RESET_BMSK 0x100000
+
+#define EXT_CAM_HSYNC_POL_SEL_BMSK 0x10000
+#define EXT_CAM_VSYNC_POL_SEL_BMSK 0x8000
+#define MDDI_CLK_CHICKEN_BIT_BMSK  0x80
+
+#define CAM_SEL_SHFT 0x1
+#define CAM_PCLK_SRC_SEL_SHFT 0x11
+#define CAM_PCLK_INVERT_SHFT 0x13
+#define CAM_PAD_REG_SW_RESET_SHFT 0x14
+
+#define EXT_CAM_HSYNC_POL_SEL_SHFT 0x10
+#define EXT_CAM_VSYNC_POL_SEL_SHFT 0xF
+#define MDDI_CLK_CHICKEN_BIT_SHFT  0x7
+#define APPS_RESET_OFFSET 0x00000214
+
+static struct clk *camio_vfe_mdc_clk;
+static struct clk *camio_mdc_clk;
+static struct clk *camio_vfe_clk;
+static struct clk *camio_vfe_axi_clk;
+static struct msm_camera_io_ext camio_ext;
+static struct resource *appio, *mdcio;
+
+void __iomem *appbase, *mdcbase;
+
+
+int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
+{
+	int rc = 0;
+	struct clk *clk = NULL;
+
+	switch (clktype) {
+	case CAMIO_VFE_MDC_CLK:
+		camio_vfe_mdc_clk = clk = clk_get(NULL, "vfe_mdc_clk");
+		break;
+
+	case CAMIO_MDC_CLK:
+		camio_mdc_clk = clk = clk_get(NULL, "mdc_clk");
+		break;
+
+	case CAMIO_VFE_CLK:
+		camio_vfe_clk = clk = clk_get(NULL, "vfe_clk");
+		break;
+
+	case CAMIO_VFE_AXI_CLK:
+		camio_vfe_axi_clk = clk = clk_get(NULL, "vfe_axi_clk");
+		break;
+
+	default:
+		break;
+	}
+
+	if (!IS_ERR(clk))
+		clk_enable(clk);
+	else
+		rc = -1;
+
+	return rc;
+}
+
+int msm_camio_clk_disable(enum msm_camio_clk_type clktype)
+{
+	int rc = 0;
+	struct clk *clk = NULL;
+
+	switch (clktype) {
+	case CAMIO_VFE_MDC_CLK:
+		clk = camio_vfe_mdc_clk;
+		break;
+
+	case CAMIO_MDC_CLK:
+		clk = camio_mdc_clk;
+		break;
+
+	case CAMIO_VFE_CLK:
+		clk = camio_vfe_clk;
+		break;
+
+	case CAMIO_VFE_AXI_CLK:
+		clk = camio_vfe_axi_clk;
+		break;
+
+	default:
+		break;
+	}
+
+	if (!IS_ERR(clk)) {
+		clk_disable(clk);
+		clk_put(clk);
+	} else
+		rc = -1;
+
+	return rc;
+}
+
+void msm_camio_clk_rate_set(int rate)
+{
+	struct clk *clk = camio_vfe_mdc_clk;
+
+	/* TODO: check return */
+	clk_set_rate(clk, rate);
+}
+
+int msm_camio_enable(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	appio = request_mem_region(camio_ext.appphy,
+		camio_ext.appsz, pdev->name);
+	if (!appio) {
+		rc = -EBUSY;
+		goto enable_fail;
+	}
+
+	appbase = ioremap(camio_ext.appphy, camio_ext.appsz);
+	if (!appbase) {
+		rc = -ENOMEM;
+		goto apps_no_mem;
+	}
+	msm_camio_clk_enable(CAMIO_MDC_CLK);
+	msm_camio_clk_enable(CAMIO_VFE_AXI_CLK);
+	return 0;
+
+apps_no_mem:
+	release_mem_region(camio_ext.appphy, camio_ext.appsz);
+enable_fail:
+	return rc;
+}
+
+void msm_camio_disable(struct platform_device *pdev)
+{
+	iounmap(appbase);
+	release_mem_region(camio_ext.appphy, camio_ext.appsz);
+	msm_camio_clk_disable(CAMIO_MDC_CLK);
+	msm_camio_clk_disable(CAMIO_VFE_AXI_CLK);
+}
+
+int msm_camio_sensor_clk_on(struct platform_device *pdev)
+{
+
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+	int32_t rc = 0;
+	camio_ext = camdev->ioext;
+
+	mdcio = request_mem_region(camio_ext.mdcphy,
+		camio_ext.mdcsz, pdev->name);
+	if (!mdcio)
+		rc = -EBUSY;
+	mdcbase = ioremap(camio_ext.mdcphy,
+		camio_ext.mdcsz);
+	if (!mdcbase)
+		goto mdc_no_mem;
+	camdev->camera_gpio_on();
+
+	msm_camio_clk_enable(CAMIO_VFE_CLK);
+	msm_camio_clk_enable(CAMIO_VFE_MDC_CLK);
+	return rc;
+
+
+mdc_no_mem:
+	release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
+	return -EINVAL;
+}
+
+int msm_camio_sensor_clk_off(struct platform_device *pdev)
+{
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+	camdev->camera_gpio_off();
+	iounmap(mdcbase);
+	release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
+	msm_camio_clk_disable(CAMIO_VFE_CLK);
+	return msm_camio_clk_disable(CAMIO_VFE_MDC_CLK);
+
+}
+
+void msm_disable_io_gpio_clk(struct platform_device *pdev)
+{
+	return;
+}
+
+void msm_camio_camif_pad_reg_reset(void)
+{
+	uint32_t reg;
+	uint32_t mask, value;
+
+	/* select CLKRGM_VFE_SRC_CAM_VFE_SRC:  internal source */
+	msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_INTERNAL);
+
+	reg = (msm_camera_io_r_mb(mdcbase)) & CAMIF_CFG_RMSK;
+
+	mask = CAM_SEL_BMSK |
+		CAM_PCLK_SRC_SEL_BMSK |
+		CAM_PCLK_INVERT_BMSK |
+		EXT_CAM_HSYNC_POL_SEL_BMSK |
+	    EXT_CAM_VSYNC_POL_SEL_BMSK | MDDI_CLK_CHICKEN_BIT_BMSK;
+
+	value = 1 << CAM_SEL_SHFT |
+		3 << CAM_PCLK_SRC_SEL_SHFT |
+		0 << CAM_PCLK_INVERT_SHFT |
+		0 << EXT_CAM_HSYNC_POL_SEL_SHFT |
+	    0 << EXT_CAM_VSYNC_POL_SEL_SHFT | 0 << MDDI_CLK_CHICKEN_BIT_SHFT;
+	msm_camera_io_w_mb((reg & (~mask)) | (value & mask), mdcbase);
+	usleep_range(10000, 11000);
+
+	reg = (msm_camera_io_r_mb(mdcbase)) & CAMIF_CFG_RMSK;
+	mask = CAM_PAD_REG_SW_RESET_BMSK;
+	value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
+	msm_camera_io_w_mb((reg & (~mask)) | (value & mask), mdcbase);
+	usleep_range(10000, 11000);
+
+	reg = (msm_camera_io_r_mb(mdcbase)) & CAMIF_CFG_RMSK;
+	mask = CAM_PAD_REG_SW_RESET_BMSK;
+	value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
+	msm_camera_io_w_mb((reg & (~mask)) | (value & mask), mdcbase);
+	usleep_range(10000, 11000);
+
+	msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_EXTERNAL);
+
+	usleep_range(10000, 11000);
+
+	/* todo: check return */
+	if (camio_vfe_clk)
+		clk_set_rate(camio_vfe_clk, 96000000);
+}
+
+void msm_camio_vfe_blk_reset(void)
+{
+	uint32_t val;
+
+	val = msm_camera_io_r_mb(appbase + APPS_RESET_OFFSET);
+	val |= 0x1;
+	msm_camera_io_w_mb(val, appbase + APPS_RESET_OFFSET);
+	usleep_range(10000, 11000);
+
+	val = msm_camera_io_r_mb(appbase + APPS_RESET_OFFSET);
+	val &= ~0x1;
+	msm_camera_io_w_mb(val, appbase + APPS_RESET_OFFSET);
+	usleep_range(10000, 11000);
+}
+
+void msm_camio_camif_pad_reg_reset_2(void)
+{
+	uint32_t reg;
+	uint32_t mask, value;
+
+	reg = (msm_camera_io_r_mb(mdcbase)) & CAMIF_CFG_RMSK;
+	mask = CAM_PAD_REG_SW_RESET_BMSK;
+	value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
+	msm_camera_io_w_mb((reg & (~mask)) | (value & mask), mdcbase);
+	usleep_range(10000, 11000);
+
+	reg = (msm_camera_io_r_mb(mdcbase)) & CAMIF_CFG_RMSK;
+	mask = CAM_PAD_REG_SW_RESET_BMSK;
+	value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
+	msm_camera_io_w_mb((reg & (~mask)) | (value & mask), mdcbase);
+	usleep_range(10000, 11000);
+}
+
+void msm_camio_clk_sel(enum msm_camio_clk_src_type srctype)
+{
+	struct clk *clk = NULL;
+
+	clk = camio_vfe_clk;
+
+	if (clk != NULL) {
+		switch (srctype) {
+		case MSM_CAMIO_CLK_SRC_INTERNAL:
+			clk_set_flags(clk, 0x00000100 << 1);
+			break;
+
+		case MSM_CAMIO_CLK_SRC_EXTERNAL:
+			clk_set_flags(clk, 0x00000100);
+			break;
+
+		default:
+			break;
+		}
+	}
+}
+
+void msm_camio_clk_axi_rate_set(int rate)
+{
+	struct clk *clk = camio_vfe_axi_clk;
+	/* todo: check return */
+	clk_set_rate(clk, rate);
+}
+
+int msm_camio_probe_on(struct platform_device *pdev)
+{
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+
+	camdev->camera_gpio_on();
+	return msm_camio_clk_enable(CAMIO_VFE_MDC_CLK);
+}
+
+int msm_camio_probe_off(struct platform_device *pdev)
+{
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+
+	camdev->camera_gpio_off();
+	return msm_camio_clk_disable(CAMIO_VFE_MDC_CLK);
+}
diff --git a/drivers/media/platform/msm/camera_v1/io/msm_io_7x27a.c b/drivers/media/platform/msm/camera_v1/io/msm_io_7x27a.c
new file mode 100644
index 0000000..6e70d37
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/io/msm_io_7x27a.c
@@ -0,0 +1,595 @@
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/pm_qos.h>
+#include <mach/board.h>
+#include <mach/camera.h>
+#include <mach/camera.h>
+#include <mach/clk.h>
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
+
+
+/* MIPI	CSI controller registers */
+#define	MIPI_PHY_CONTROL		0x00000000
+#define	MIPI_PROTOCOL_CONTROL		0x00000004
+#define	MIPI_INTERRUPT_STATUS		0x00000008
+#define	MIPI_INTERRUPT_MASK		0x0000000C
+#define	MIPI_CAMERA_CNTL		0x00000024
+#define	MIPI_CALIBRATION_CONTROL	0x00000018
+#define	MIPI_PHY_D0_CONTROL2		0x00000038
+#define	MIPI_PHY_D1_CONTROL2		0x0000003C
+#define	MIPI_PHY_D2_CONTROL2		0x00000040
+#define	MIPI_PHY_D3_CONTROL2		0x00000044
+#define	MIPI_PHY_CL_CONTROL		0x00000048
+#define	MIPI_PHY_D0_CONTROL		0x00000034
+#define	MIPI_PHY_D1_CONTROL		0x00000020
+#define	MIPI_PHY_D2_CONTROL		0x0000002C
+#define	MIPI_PHY_D3_CONTROL		0x00000030
+#define	MIPI_PWR_CNTL			0x00000054
+
+/*
+ * MIPI_PROTOCOL_CONTROL register bits to enable/disable the features of
+ * CSI Rx Block
+ */
+
+/* DPCM scheme */
+#define	MIPI_PROTOCOL_CONTROL_DPCM_SCHEME_SHFT			0x1e
+/* SW_RST to issue a SW reset to the CSI core */
+#define	MIPI_PROTOCOL_CONTROL_SW_RST_BMSK			0x8000000
+/* To Capture Long packet Header Info in MIPI_PROTOCOL_STATUS register */
+#define	MIPI_PROTOCOL_CONTROL_LONG_PACKET_HEADER_CAPTURE_BMSK	0x200000
+/* Data format for unpacking purpose */
+#define	MIPI_PROTOCOL_CONTROL_DATA_FORMAT_SHFT			0x13
+/* Enable decoding of payload based on data type filed of packet hdr */
+#define	MIPI_PROTOCOL_CONTROL_DECODE_ID_BMSK			0x00000
+/* Enable error correction on packet headers */
+#define	MIPI_PROTOCOL_CONTROL_ECC_EN_BMSK			0x20000
+
+/*
+ * MIPI_CALIBRATION_CONTROL register contains control info for
+ * calibration impledence controller
+*/
+
+/* Enable bit for calibration pad */
+#define	MIPI_CALIBRATION_CONTROL_SWCAL_CAL_EN_SHFT		0x16
+/* With SWCAL_STRENGTH_OVERRIDE_EN, SW_CAL_EN and MANUAL_OVERRIDE_EN
+ * the hardware calibration circuitry associated with CAL_SW_HW_MODE
+ * is bypassed
+*/
+#define	MIPI_CALIBRATION_CONTROL_SWCAL_STRENGTH_OVERRIDE_EN_SHFT	0x15
+/* To indicate the Calibration process is in the control of HW/SW */
+#define	MIPI_CALIBRATION_CONTROL_CAL_SW_HW_MODE_SHFT		0x14
+/* When this is set the strength value of the data and clk lane impedence
+ * termination is updated with MANUAL_STRENGTH settings and calibration
+ * sensing logic is idle.
+*/
+#define	MIPI_CALIBRATION_CONTROL_MANUAL_OVERRIDE_EN_SHFT	0x7
+
+/* Data lane0 control */
+/* T-hs Settle count value  for Rx */
+#define	MIPI_PHY_D0_CONTROL2_SETTLE_COUNT_SHFT			0x18
+/* Rx termination control */
+#define	MIPI_PHY_D0_CONTROL2_HS_TERM_IMP_SHFT			0x10
+/* LP Rx enable */
+#define	MIPI_PHY_D0_CONTROL2_LP_REC_EN_SHFT			0x4
+/*
+ * Enable for error in sync sequence
+ * 1 - one bit error in sync seq
+ * 0 - requires all 8 bit correct seq
+*/
+#define	MIPI_PHY_D0_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
+
+/* Comments are same as D0 */
+#define	MIPI_PHY_D1_CONTROL2_SETTLE_COUNT_SHFT			0x18
+#define	MIPI_PHY_D1_CONTROL2_HS_TERM_IMP_SHFT			0x10
+#define	MIPI_PHY_D1_CONTROL2_LP_REC_EN_SHFT			0x4
+#define	MIPI_PHY_D1_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
+
+/* Comments are same as D0 */
+#define	MIPI_PHY_D2_CONTROL2_SETTLE_COUNT_SHFT			0x18
+#define	MIPI_PHY_D2_CONTROL2_HS_TERM_IMP_SHFT			0x10
+#define	MIPI_PHY_D2_CONTROL2_LP_REC_EN_SHFT			0x4
+#define	MIPI_PHY_D2_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
+
+/* Comments are same as D0 */
+#define	MIPI_PHY_D3_CONTROL2_SETTLE_COUNT_SHFT			0x18
+#define	MIPI_PHY_D3_CONTROL2_HS_TERM_IMP_SHFT			0x10
+#define	MIPI_PHY_D3_CONTROL2_LP_REC_EN_SHFT			0x4
+#define	MIPI_PHY_D3_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
+
+/* PHY_CL_CTRL programs the parameters of clk lane of CSIRXPHY */
+/* HS Rx termination control */
+#define	MIPI_PHY_CL_CONTROL_HS_TERM_IMP_SHFT			0x18
+/* Start signal for T-hs delay */
+#define	MIPI_PHY_CL_CONTROL_LP_REC_EN_SHFT			0x2
+
+/* PHY DATA lane 0 control */
+/*
+ * HS RX equalizer strength control
+ * 00 - 0db 01 - 3db 10 - 5db 11 - 7db
+*/
+#define	MIPI_PHY_D0_CONTROL_HS_REC_EQ_SHFT			0x1c
+
+/* PHY DATA lane 1 control */
+/* Shutdown signal for MIPI clk phy line */
+#define	MIPI_PHY_D1_CONTROL_MIPI_CLK_PHY_SHUTDOWNB_SHFT		0x9
+/* Shutdown signal for MIPI data phy line */
+#define	MIPI_PHY_D1_CONTROL_MIPI_DATA_PHY_SHUTDOWNB_SHFT	0x8
+
+#define MSM_AXI_QOS_PREVIEW 200000
+#define MSM_AXI_QOS_SNAPSHOT 200000
+#define MSM_AXI_QOS_RECORDING 200000
+
+#define MIPI_PWR_CNTL_ENA	0x07
+#define MIPI_PWR_CNTL_DIS	0x0
+
+static struct clk *camio_cam_clk;
+static struct clk *camio_vfe_clk;
+static struct clk *camio_csi_src_clk;
+static struct clk *camio_csi0_vfe_clk;
+static struct clk *camio_csi1_vfe_clk;
+static struct clk *camio_csi0_clk;
+static struct clk *camio_csi1_clk;
+static struct clk *camio_csi0_pclk;
+static struct clk *camio_csi1_pclk;
+
+static struct msm_camera_io_ext camio_ext;
+static struct msm_camera_io_clk camio_clk;
+static struct platform_device *camio_dev;
+void __iomem *csibase;
+void __iomem *appbase;
+
+
+int msm_camio_vfe_clk_rate_set(int rate)
+{
+	int rc = 0;
+	struct clk *clk = camio_vfe_clk;
+	if (rate > clk_get_rate(clk))
+		rc = clk_set_rate(clk, rate);
+	return rc;
+}
+
+int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
+{
+	int rc = 0;
+	struct clk *clk = NULL;
+
+	switch (clktype) {
+	case CAMIO_CAM_MCLK_CLK:
+		clk = clk_get(NULL, "cam_m_clk");
+		camio_cam_clk = clk;
+		msm_camio_clk_rate_set_2(clk, camio_clk.mclk_clk_rate);
+		break;
+	case CAMIO_VFE_CLK:
+		clk = clk_get(NULL, "vfe_clk");
+		camio_vfe_clk = clk;
+		msm_camio_clk_rate_set_2(clk, camio_clk.vfe_clk_rate);
+		break;
+	case CAMIO_CSI0_VFE_CLK:
+		clk = clk_get(&camio_dev->dev, "csi_vfe_clk");
+		camio_csi0_vfe_clk = clk;
+		break;
+	case CAMIO_CSI1_VFE_CLK:
+		clk = clk_get(NULL, "csi_vfe_clk");
+		camio_csi1_vfe_clk = clk;
+		break;
+	case CAMIO_CSI_SRC_CLK:
+		clk = clk_get(NULL, "csi_src_clk");
+		camio_csi_src_clk = clk;
+		break;
+	case CAMIO_CSI0_CLK:
+		clk = clk_get(&camio_dev->dev, "csi_clk");
+		camio_csi0_clk = clk;
+		msm_camio_clk_rate_set_2(clk, 400000000);
+		break;
+	case CAMIO_CSI1_CLK:
+		clk = clk_get(NULL, "csi_clk");
+		camio_csi1_clk = clk;
+		break;
+	case CAMIO_CSI0_PCLK:
+		clk = clk_get(&camio_dev->dev, "csi_pclk");
+		camio_csi0_pclk = clk;
+		break;
+	case CAMIO_CSI1_PCLK:
+		clk = clk_get(NULL, "csi_pclk");
+		camio_csi1_pclk = clk;
+		break;
+	default:
+		break;
+	}
+
+	if (!IS_ERR(clk))
+		clk_enable(clk);
+	else
+		rc = -1;
+	return rc;
+}
+
+int msm_camio_clk_disable(enum msm_camio_clk_type clktype)
+{
+	int rc = 0;
+	struct clk *clk = NULL;
+
+	switch (clktype) {
+	case CAMIO_CAM_MCLK_CLK:
+		clk = camio_cam_clk;
+		break;
+	case CAMIO_VFE_CLK:
+		clk = camio_vfe_clk;
+		break;
+	case CAMIO_CSI_SRC_CLK:
+		clk = camio_csi_src_clk;
+		break;
+	case CAMIO_CSI0_VFE_CLK:
+		clk = camio_csi0_vfe_clk;
+		break;
+	case CAMIO_CSI1_VFE_CLK:
+		clk = camio_csi1_vfe_clk;
+		break;
+	case CAMIO_CSI0_CLK:
+		clk = camio_csi0_clk;
+		break;
+	case CAMIO_CSI1_CLK:
+		clk = camio_csi1_clk;
+		break;
+	case CAMIO_CSI0_PCLK:
+		clk = camio_csi0_pclk;
+		break;
+	case CAMIO_CSI1_PCLK:
+		clk = camio_csi1_pclk;
+		break;
+	default:
+		break;
+	}
+
+	if (!IS_ERR(clk)) {
+		clk_disable(clk);
+		clk_put(clk);
+	} else
+		rc = -1;
+	return rc;
+}
+
+void msm_camio_clk_rate_set(int rate)
+{
+	struct clk *clk = camio_cam_clk;
+	clk_set_rate(clk, rate);
+}
+
+void msm_camio_clk_rate_set_2(struct clk *clk, int rate)
+{
+	clk_set_rate(clk, rate);
+}
+
+static irqreturn_t msm_io_csi_irq(int irq_num, void *data)
+{
+	uint32_t irq;
+
+	irq = msm_camera_io_r(csibase + MIPI_INTERRUPT_STATUS);
+	CDBG("%s MIPI_INTERRUPT_STATUS = 0x%x\n", __func__, irq);
+	msm_camera_io_w(irq, csibase + MIPI_INTERRUPT_STATUS);
+
+	/* TODO: Needs to send this info to upper layers */
+	if ((irq >> 19) & 0x1)
+		pr_info("Unsupported packet format is received\n");
+	return IRQ_HANDLED;
+}
+
+int msm_camio_enable(struct platform_device *pdev)
+{
+	int rc = 0;
+	const struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+	uint32_t val;
+
+	camio_dev = pdev;
+	camio_ext = camdev->ioext;
+	camio_clk = camdev->ioclk;
+
+	msm_camio_clk_enable(CAMIO_VFE_CLK);
+	msm_camio_clk_enable(CAMIO_CSI0_VFE_CLK);
+	msm_camio_clk_enable(CAMIO_CSI1_VFE_CLK);
+	msm_camio_clk_enable(CAMIO_CSI0_CLK);
+	msm_camio_clk_enable(CAMIO_CSI1_CLK);
+	msm_camio_clk_enable(CAMIO_CSI0_PCLK);
+	msm_camio_clk_enable(CAMIO_CSI1_PCLK);
+
+	csibase = ioremap(camio_ext.csiphy, camio_ext.csisz);
+	if (!csibase) {
+		rc = -ENOMEM;
+		goto csi_busy;
+	}
+	rc = request_irq(camio_ext.csiirq, msm_io_csi_irq,
+				IRQF_TRIGGER_RISING, "csi", 0);
+	if (rc < 0)
+		goto csi_irq_fail;
+
+	msleep(20);
+	val = (20 <<
+		MIPI_PHY_D0_CONTROL2_SETTLE_COUNT_SHFT) |
+		(0x0F << MIPI_PHY_D0_CONTROL2_HS_TERM_IMP_SHFT) |
+		(0x0 << MIPI_PHY_D0_CONTROL2_LP_REC_EN_SHFT) |
+		(0x1 << MIPI_PHY_D0_CONTROL2_ERR_SOT_HS_EN_SHFT);
+	CDBG("%s MIPI_PHY_D0_CONTROL2 val=0x%x\n", __func__, val);
+	msm_camera_io_w(val, csibase + MIPI_PHY_D0_CONTROL2);
+	msm_camera_io_w(val, csibase + MIPI_PHY_D1_CONTROL2);
+	msm_camera_io_w(val, csibase + MIPI_PHY_D2_CONTROL2);
+	msm_camera_io_w(val, csibase + MIPI_PHY_D3_CONTROL2);
+
+	val = (0x0F << MIPI_PHY_CL_CONTROL_HS_TERM_IMP_SHFT) |
+		(0x0 << MIPI_PHY_CL_CONTROL_LP_REC_EN_SHFT);
+	CDBG("%s MIPI_PHY_CL_CONTROL val=0x%x\n", __func__, val);
+	msm_camera_io_w(val, csibase + MIPI_PHY_CL_CONTROL);
+
+	appbase = ioremap(camio_ext.appphy,
+		camio_ext.appsz);
+	if (!appbase) {
+		rc = -ENOMEM;
+		goto csi_irq_fail;
+	}
+	return 0;
+
+csi_irq_fail:
+	iounmap(csibase);
+csi_busy:
+	msm_camio_clk_disable(CAMIO_CAM_MCLK_CLK);
+	msm_camio_clk_disable(CAMIO_VFE_CLK);
+	msm_camio_clk_disable(CAMIO_CSI0_VFE_CLK);
+	msm_camio_clk_disable(CAMIO_CSI1_VFE_CLK);
+	msm_camio_clk_disable(CAMIO_CSI0_CLK);
+	msm_camio_clk_disable(CAMIO_CSI1_CLK);
+	msm_camio_clk_disable(CAMIO_CSI0_PCLK);
+	msm_camio_clk_disable(CAMIO_CSI1_PCLK);
+	camdev->camera_gpio_off();
+	return rc;
+}
+
+void msm_camio_disable(struct platform_device *pdev)
+{
+	uint32_t val;
+
+	val = (20 <<
+		MIPI_PHY_D0_CONTROL2_SETTLE_COUNT_SHFT) |
+		(0x0F << MIPI_PHY_D0_CONTROL2_HS_TERM_IMP_SHFT) |
+		(0x0 << MIPI_PHY_D0_CONTROL2_LP_REC_EN_SHFT) |
+		(0x1 << MIPI_PHY_D0_CONTROL2_ERR_SOT_HS_EN_SHFT);
+	CDBG("%s MIPI_PHY_D0_CONTROL2 val=0x%x\n", __func__, val);
+	msm_camera_io_w(val, csibase + MIPI_PHY_D0_CONTROL2);
+	msm_camera_io_w(val, csibase + MIPI_PHY_D1_CONTROL2);
+	msm_camera_io_w(val, csibase + MIPI_PHY_D2_CONTROL2);
+	msm_camera_io_w(val, csibase + MIPI_PHY_D3_CONTROL2);
+
+	val = (0x0F << MIPI_PHY_CL_CONTROL_HS_TERM_IMP_SHFT) |
+		(0x0 << MIPI_PHY_CL_CONTROL_LP_REC_EN_SHFT);
+	CDBG("%s MIPI_PHY_CL_CONTROL val=0x%x\n", __func__, val);
+	msm_camera_io_w(val, csibase + MIPI_PHY_CL_CONTROL);
+	msleep(20);
+
+	free_irq(camio_ext.csiirq, 0);
+	iounmap(csibase);
+	iounmap(appbase);
+	CDBG("disable clocks\n");
+
+	msm_camio_clk_disable(CAMIO_VFE_CLK);
+	msm_camio_clk_disable(CAMIO_CSI0_CLK);
+	msm_camio_clk_disable(CAMIO_CSI1_CLK);
+	msm_camio_clk_disable(CAMIO_CSI0_VFE_CLK);
+	msm_camio_clk_disable(CAMIO_CSI1_VFE_CLK);
+	msm_camio_clk_disable(CAMIO_CSI0_PCLK);
+	msm_camio_clk_disable(CAMIO_CSI1_PCLK);
+}
+
+int msm_camio_sensor_clk_on(struct platform_device *pdev)
+{
+	int rc = 0;
+	const struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+	camio_dev = pdev;
+	camio_ext = camdev->ioext;
+	camio_clk = camdev->ioclk;
+
+	rc = camdev->camera_gpio_on();
+	if (rc < 0)
+		return rc;
+	return msm_camio_clk_enable(CAMIO_CAM_MCLK_CLK);
+}
+
+int msm_camio_sensor_clk_off(struct platform_device *pdev)
+{
+	const struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+	camdev->camera_gpio_off();
+	return msm_camio_clk_disable(CAMIO_CAM_MCLK_CLK);
+
+}
+
+void msm_camio_vfe_blk_reset(void)
+{
+	uint32_t val;
+
+	/* do apps reset */
+	val = msm_camera_io_r(appbase + 0x00000210);
+	val |= 0x1;
+	msm_camera_io_w(val, appbase + 0x00000210);
+	usleep_range(10000, 11000);
+
+	val = msm_camera_io_r(appbase + 0x00000210);
+	val &= ~0x1;
+	msm_camera_io_w(val, appbase + 0x00000210);
+	usleep_range(10000, 11000);
+
+	/* do axi reset */
+	val = msm_camera_io_r(appbase + 0x00000208);
+	val |= 0x1;
+	msm_camera_io_w(val, appbase + 0x00000208);
+	usleep_range(10000, 11000);
+
+	val = msm_camera_io_r(appbase + 0x00000208);
+	val &= ~0x1;
+	msm_camera_io_w(val, appbase + 0x00000208);
+	mb();
+	usleep_range(10000, 11000);
+	return;
+}
+
+int msm_camio_probe_on(struct platform_device *pdev)
+{
+	int rc = 0;
+	const struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+	camio_dev = pdev;
+	camio_ext = camdev->ioext;
+	camio_clk = camdev->ioclk;
+
+	msm_camio_clk_enable(CAMIO_CSI0_PCLK);
+	msm_camio_clk_enable(CAMIO_CSI1_PCLK);
+
+	rc = camdev->camera_gpio_on();
+	if (rc < 0)
+		return rc;
+	return msm_camio_clk_enable(CAMIO_CAM_MCLK_CLK);
+}
+
+int msm_camio_probe_off(struct platform_device *pdev)
+{
+	const struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+	camdev->camera_gpio_off();
+
+	csibase = ioremap(camdev->ioext.csiphy, camdev->ioext.csisz);
+	if (!csibase) {
+		pr_err("ioremap failed for CSIBASE\n");
+		goto ioremap_fail;
+	}
+	msm_camera_io_w(MIPI_PWR_CNTL_DIS, csibase + MIPI_PWR_CNTL);
+	iounmap(csibase);
+ioremap_fail:
+	msm_camio_clk_disable(CAMIO_CSI0_PCLK);
+	msm_camio_clk_disable(CAMIO_CSI1_PCLK);
+	return msm_camio_clk_disable(CAMIO_CAM_MCLK_CLK);
+}
+
+int msm_camio_csi_config(struct msm_camera_csi_params *csi_params)
+{
+	int rc = 0;
+	uint32_t val = 0;
+
+	CDBG("msm_camio_csi_config\n");
+
+	/* Enable error correction for DATA lane. Applies to all data lanes */
+	msm_camera_io_w(0x4, csibase + MIPI_PHY_CONTROL);
+
+	msm_camera_io_w(MIPI_PROTOCOL_CONTROL_SW_RST_BMSK,
+		csibase + MIPI_PROTOCOL_CONTROL);
+
+	val = MIPI_PROTOCOL_CONTROL_LONG_PACKET_HEADER_CAPTURE_BMSK |
+		MIPI_PROTOCOL_CONTROL_DECODE_ID_BMSK |
+		MIPI_PROTOCOL_CONTROL_ECC_EN_BMSK;
+	val |= (uint32_t)(csi_params->data_format) <<
+		MIPI_PROTOCOL_CONTROL_DATA_FORMAT_SHFT;
+	val |= csi_params->dpcm_scheme <<
+		MIPI_PROTOCOL_CONTROL_DPCM_SCHEME_SHFT;
+	CDBG("%s MIPI_PROTOCOL_CONTROL val=0x%x\n", __func__, val);
+	msm_camera_io_w(val, csibase + MIPI_PROTOCOL_CONTROL);
+
+	val = (0x1 << MIPI_CALIBRATION_CONTROL_SWCAL_CAL_EN_SHFT) |
+		(0x1 <<
+		MIPI_CALIBRATION_CONTROL_SWCAL_STRENGTH_OVERRIDE_EN_SHFT) |
+		(0x1 << MIPI_CALIBRATION_CONTROL_CAL_SW_HW_MODE_SHFT) |
+		(0x1 << MIPI_CALIBRATION_CONTROL_MANUAL_OVERRIDE_EN_SHFT);
+	CDBG("%s MIPI_CALIBRATION_CONTROL val=0x%x\n", __func__, val);
+	msm_camera_io_w(val, csibase + MIPI_CALIBRATION_CONTROL);
+
+	val = (csi_params->settle_cnt <<
+		MIPI_PHY_D0_CONTROL2_SETTLE_COUNT_SHFT) |
+		(0x0F << MIPI_PHY_D0_CONTROL2_HS_TERM_IMP_SHFT) |
+		(0x1 << MIPI_PHY_D0_CONTROL2_LP_REC_EN_SHFT) |
+		(0x1 << MIPI_PHY_D0_CONTROL2_ERR_SOT_HS_EN_SHFT);
+	CDBG("%s MIPI_PHY_D0_CONTROL2 val=0x%x\n", __func__, val);
+	msm_camera_io_w(val, csibase + MIPI_PHY_D0_CONTROL2);
+	msm_camera_io_w(val, csibase + MIPI_PHY_D1_CONTROL2);
+	msm_camera_io_w(val, csibase + MIPI_PHY_D2_CONTROL2);
+	msm_camera_io_w(val, csibase + MIPI_PHY_D3_CONTROL2);
+
+
+	val = (0x0F << MIPI_PHY_CL_CONTROL_HS_TERM_IMP_SHFT) |
+		(0x1 << MIPI_PHY_CL_CONTROL_LP_REC_EN_SHFT);
+	CDBG("%s MIPI_PHY_CL_CONTROL val=0x%x\n", __func__, val);
+	msm_camera_io_w(val, csibase + MIPI_PHY_CL_CONTROL);
+
+	val = 0 << MIPI_PHY_D0_CONTROL_HS_REC_EQ_SHFT;
+	msm_camera_io_w(val, csibase + MIPI_PHY_D0_CONTROL);
+
+	val = (0x1 << MIPI_PHY_D1_CONTROL_MIPI_CLK_PHY_SHUTDOWNB_SHFT) |
+		(0x1 << MIPI_PHY_D1_CONTROL_MIPI_DATA_PHY_SHUTDOWNB_SHFT);
+	CDBG("%s MIPI_PHY_D1_CONTROL val=0x%x\n", __func__, val);
+	msm_camera_io_w(val, csibase + MIPI_PHY_D1_CONTROL);
+
+	msm_camera_io_w(0x00000000, csibase + MIPI_PHY_D2_CONTROL);
+	msm_camera_io_w(0x00000000, csibase + MIPI_PHY_D3_CONTROL);
+
+	/* program number of lanes and lane mapping */
+	switch (csi_params->lane_cnt) {
+	case 1:
+		msm_camera_io_w(csi_params->lane_assign << 8 | 0x4,
+			csibase + MIPI_CAMERA_CNTL);
+		break;
+	case 2:
+		msm_camera_io_w(csi_params->lane_assign << 8 | 0x5,
+			csibase + MIPI_CAMERA_CNTL);
+		break;
+	case 3:
+		msm_camera_io_w(csi_params->lane_assign << 8 | 0x6,
+			csibase + MIPI_CAMERA_CNTL);
+		break;
+	case 4:
+		msm_camera_io_w(csi_params->lane_assign << 8 | 0x7,
+			csibase + MIPI_CAMERA_CNTL);
+		break;
+	}
+
+	msm_camera_io_w(0xFFFFF3FF, csibase + MIPI_INTERRUPT_MASK);
+	/*clear IRQ bits - write 1 clears the status*/
+	msm_camera_io_w(0xFFFFF3FF, csibase + MIPI_INTERRUPT_STATUS);
+
+	return rc;
+}
+
+void msm_camio_set_perf_lvl(enum msm_bus_perf_setting perf_setting)
+{
+	switch (perf_setting) {
+	case S_INIT:
+		add_axi_qos();
+		break;
+	case S_PREVIEW:
+		update_axi_qos(MSM_AXI_QOS_PREVIEW);
+		break;
+	case S_VIDEO:
+		update_axi_qos(MSM_AXI_QOS_RECORDING);
+		break;
+	case S_CAPTURE:
+		update_axi_qos(MSM_AXI_QOS_SNAPSHOT);
+		break;
+	case S_DEFAULT:
+		update_axi_qos(PM_QOS_DEFAULT_VALUE);
+		break;
+	case S_EXIT:
+		release_axi_qos();
+		break;
+	default:
+		CDBG("%s: INVALID CASE\n", __func__);
+	}
+}
diff --git a/drivers/media/platform/msm/camera_v1/io/msm_io_7x27a_v4l2.c b/drivers/media/platform/msm/camera_v1/io/msm_io_7x27a_v4l2.c
new file mode 100644
index 0000000..6d2a11d
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/io/msm_io_7x27a_v4l2.c
@@ -0,0 +1,218 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/pm_qos.h>
+#include <linux/module.h>
+#include <mach/board.h>
+#include <mach/camera.h>
+#include <mach/camera.h>
+#include <mach/clk.h>
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
+#include <mach/dal_axi.h>
+
+#define MSM_AXI_QOS_PREVIEW 200000
+#define MSM_AXI_QOS_SNAPSHOT 200000
+#define MSM_AXI_QOS_RECORDING 200000
+
+static struct clk *camio_cam_clk;
+static struct resource *clk_ctrl_mem;
+static struct msm_camera_io_clk camio_clk;
+static int apps_reset;
+void __iomem *appbase;
+
+void msm_camio_clk_rate_set_2(struct clk *clk, int rate)
+{
+	clk_set_rate(clk, rate);
+}
+int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
+{
+	int rc = 0;
+	struct clk *clk = NULL;
+
+	switch (clktype) {
+	case CAMIO_CAM_MCLK_CLK:
+		clk = clk_get(NULL, "cam_m_clk");
+		camio_cam_clk = clk;
+		msm_camio_clk_rate_set_2(clk, camio_clk.mclk_clk_rate);
+		break;
+	default:
+		break;
+	}
+
+	if (!IS_ERR(clk))
+		clk_enable(clk);
+	else
+		rc = -1;
+	return rc;
+}
+
+int msm_camio_clk_disable(enum msm_camio_clk_type clktype)
+{
+	int rc = 0;
+	struct clk *clk = NULL;
+
+	switch (clktype) {
+	case CAMIO_CAM_MCLK_CLK:
+		clk = camio_cam_clk;
+		break;
+	default:
+		break;
+	}
+
+	if (!IS_ERR(clk)) {
+		clk_disable(clk);
+		clk_put(clk);
+	} else
+		rc = -1;
+	return rc;
+}
+
+void msm_camio_clk_rate_set(int rate)
+{
+	struct clk *clk = camio_cam_clk;
+	clk_set_rate(clk, rate);
+}
+
+void msm_camio_vfe_blk_reset_2(void)
+{
+	uint32_t val;
+
+	/* do apps reset */
+	val = readl_relaxed(appbase + 0x00000210);
+	val |= 0x1;
+	writel_relaxed(val, appbase + 0x00000210);
+	usleep_range(10000, 11000);
+
+	val = readl_relaxed(appbase + 0x00000210);
+	val &= ~0x1;
+	writel_relaxed(val, appbase + 0x00000210);
+	usleep_range(10000, 11000);
+
+	/* do axi reset */
+	val = readl_relaxed(appbase + 0x00000208);
+	val |= 0x1;
+	writel_relaxed(val, appbase + 0x00000208);
+	usleep_range(10000, 11000);
+
+	val = readl_relaxed(appbase + 0x00000208);
+	val &= ~0x1;
+	writel_relaxed(val, appbase + 0x00000208);
+	mb();
+	usleep_range(10000, 11000);
+}
+
+void msm_camio_vfe_blk_reset_3(void)
+{
+	uint32_t val;
+
+	if (!apps_reset)
+		return;
+
+	/* do apps reset */
+	val = readl_relaxed(appbase + 0x00000210);
+	val |= 0x10A0000;
+	writel_relaxed(val, appbase + 0x00000210);
+	usleep_range(10000, 11000);
+
+	val = readl_relaxed(appbase + 0x00000210);
+	val &= ~(0x10A0000);
+	writel_relaxed(val, appbase + 0x00000210);
+	usleep_range(10000, 11000);
+	mb();
+}
+
+void msm_camio_set_perf_lvl(enum msm_bus_perf_setting perf_setting)
+{
+	switch (perf_setting) {
+	case S_INIT:
+		add_axi_qos();
+		update_axi_qos(MSM_AXI_QOS_PREVIEW);
+		axi_allocate(AXI_FLOW_VIEWFINDER_HI);
+		break;
+	case S_PREVIEW:
+		break;
+	case S_VIDEO:
+		break;
+	case S_CAPTURE:
+		break;
+	case S_DEFAULT:
+		break;
+	case S_EXIT:
+		axi_free(AXI_FLOW_VIEWFINDER_HI);
+		release_axi_qos();
+		break;
+	default:
+		CDBG("%s: INVALID CASE\n", __func__);
+	}
+}
+
+static int __devinit clkctl_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	apps_reset = *(int *)pdev->dev.platform_data;
+	clk_ctrl_mem = platform_get_resource_byname(pdev,
+					IORESOURCE_MEM, "clk_ctl");
+	if (!clk_ctrl_mem) {
+		pr_err("%s: no mem resource:3?\n", __func__);
+		return -ENODEV;
+	}
+
+	appbase = ioremap(clk_ctrl_mem->start,
+		resource_size(clk_ctrl_mem));
+	if (!appbase) {
+		pr_err("clkctl_probe: appbase:err\n");
+		rc = -ENOMEM;
+		goto ioremap_fail;
+	}
+	return 0;
+
+ioremap_fail:
+	msm_camio_clk_disable(CAMIO_CAM_MCLK_CLK);
+	return rc;
+}
+
+static int clkctl_remove(struct platform_device *pdev)
+{
+	if (clk_ctrl_mem)
+		iounmap(clk_ctrl_mem);
+
+	return 0;
+}
+
+static struct platform_driver clkctl_driver = {
+	.probe  = clkctl_probe,
+	.remove = clkctl_remove,
+	.driver = {
+		.name = "msm_clk_ctl",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init msm_clkctl_init_module(void)
+{
+	return platform_driver_register(&clkctl_driver);
+}
+
+static void __exit msm_clkctl_exit_module(void)
+{
+	platform_driver_unregister(&clkctl_driver);
+}
+
+module_init(msm_clkctl_init_module);
+module_exit(msm_clkctl_exit_module);
+MODULE_DESCRIPTION("CAM IO driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/io/msm_io_8960.c b/drivers/media/platform/msm/camera_v1/io/msm_io_8960.c
new file mode 100644
index 0000000..6dc4fa4
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/io/msm_io_8960.c
@@ -0,0 +1,119 @@
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/regulator/consumer.h>
+#include <linux/mfd/pm8xxx/pm8921.h>
+#include <mach/gpio.h>
+#include <mach/gpiomux.h>
+#include <mach/board.h>
+#include <mach/camera.h>
+#include <mach/vreg.h>
+#include <mach/camera.h>
+#include <mach/clk.h>
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
+
+#define BUFF_SIZE_128 128
+
+void msm_camio_clk_rate_set_2(struct clk *clk, int rate)
+{
+	clk_set_rate(clk, rate);
+}
+
+void msm_camio_bus_scale_cfg(struct msm_bus_scale_pdata *cam_bus_scale_table,
+		enum msm_bus_perf_setting perf_setting)
+{
+	static uint32_t bus_perf_client;
+	int rc = 0;
+	switch (perf_setting) {
+	case S_INIT:
+		bus_perf_client =
+			msm_bus_scale_register_client(cam_bus_scale_table);
+		if (!bus_perf_client) {
+			CDBG("%s: Registration Failed!!!\n", __func__);
+			bus_perf_client = 0;
+			return;
+		}
+		CDBG("%s: S_INIT rc = %u\n", __func__, bus_perf_client);
+		break;
+	case S_EXIT:
+		if (bus_perf_client) {
+			CDBG("%s: S_EXIT\n", __func__);
+			msm_bus_scale_unregister_client(bus_perf_client);
+		} else
+			CDBG("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+	case S_PREVIEW:
+		if (bus_perf_client) {
+			rc = msm_bus_scale_client_update_request(
+				bus_perf_client, 1);
+			CDBG("%s: S_PREVIEW rc = %d\n", __func__, rc);
+		} else
+			CDBG("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+	case S_VIDEO:
+		if (bus_perf_client) {
+			rc = msm_bus_scale_client_update_request(
+				bus_perf_client, 2);
+			CDBG("%s: S_VIDEO rc = %d\n", __func__, rc);
+		} else
+			CDBG("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+	case S_CAPTURE:
+		if (bus_perf_client) {
+			rc = msm_bus_scale_client_update_request(
+				bus_perf_client, 3);
+			CDBG("%s: S_CAPTURE rc = %d\n", __func__, rc);
+		} else
+			CDBG("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+	case S_ZSL:
+		if (bus_perf_client) {
+			rc = msm_bus_scale_client_update_request(
+				bus_perf_client, 4);
+			CDBG("%s: S_ZSL rc = %d\n", __func__, rc);
+		} else
+			CDBG("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+	case S_LIVESHOT:
+		if (bus_perf_client) {
+			rc = msm_bus_scale_client_update_request(
+				bus_perf_client, 5);
+			CDBG("%s: S_LIVESHOT rc = %d\n", __func__, rc);
+		} else
+			CDBG("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+	case S_DUAL:
+		if (bus_perf_client) {
+			rc = msm_bus_scale_client_update_request(
+				bus_perf_client, 6);
+			CDBG("%s: S_DUAL rc = %d\n", __func__, rc);
+		} else
+			CDBG("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+	case S_ADV_VIDEO:
+		if (bus_perf_client) {
+			rc = msm_bus_scale_client_update_request(
+				bus_perf_client, 7);
+			CDBG("%s: S_ADV_VIDEO rc = %d\n", __func__, rc);
+		} else
+			CDBG("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+	case S_DEFAULT:
+		break;
+	default:
+		pr_warning("%s: INVALID CASE\n", __func__);
+	}
+}
diff --git a/drivers/media/platform/msm/camera_v1/io/msm_io_8x60.c b/drivers/media/platform/msm/camera_v1/io/msm_io_8x60.c
new file mode 100644
index 0000000..6896538
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/io/msm_io_8x60.c
@@ -0,0 +1,820 @@
+/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/regulator/consumer.h>
+#include <mach/gpio.h>
+#include <mach/board.h>
+#include <mach/camera.h>
+#include <mach/vreg.h>
+#include <mach/camera.h>
+#include <mach/clk.h>
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
+
+
+/* MIPI	CSI	controller registers */
+#define	MIPI_PHY_CONTROL			0x00000000
+#define	MIPI_PROTOCOL_CONTROL		0x00000004
+#define	MIPI_INTERRUPT_STATUS		0x00000008
+#define	MIPI_INTERRUPT_MASK			0x0000000C
+#define	MIPI_CAMERA_CNTL			0x00000024
+#define	MIPI_CALIBRATION_CONTROL	0x00000018
+#define	MIPI_PHY_D0_CONTROL2		0x00000038
+#define	MIPI_PHY_D1_CONTROL2		0x0000003C
+#define	MIPI_PHY_D2_CONTROL2		0x00000040
+#define	MIPI_PHY_D3_CONTROL2		0x00000044
+#define	MIPI_PHY_CL_CONTROL			0x00000048
+#define	MIPI_PHY_D0_CONTROL			0x00000034
+#define	MIPI_PHY_D1_CONTROL			0x00000020
+#define	MIPI_PHY_D2_CONTROL			0x0000002C
+#define	MIPI_PHY_D3_CONTROL			0x00000030
+#define	MIPI_PROTOCOL_CONTROL_SW_RST_BMSK			0x8000000
+#define	MIPI_PROTOCOL_CONTROL_LONG_PACKET_HEADER_CAPTURE_BMSK	0x200000
+#define	MIPI_PROTOCOL_CONTROL_DATA_FORMAT_BMSK			0x180000
+#define	MIPI_PROTOCOL_CONTROL_DECODE_ID_BMSK			0x40000
+#define	MIPI_PROTOCOL_CONTROL_ECC_EN_BMSK			0x20000
+#define	MIPI_CALIBRATION_CONTROL_SWCAL_CAL_EN_SHFT		0x16
+#define	MIPI_CALIBRATION_CONTROL_SWCAL_STRENGTH_OVERRIDE_EN_SHFT	0x15
+#define	MIPI_CALIBRATION_CONTROL_CAL_SW_HW_MODE_SHFT		0x14
+#define	MIPI_CALIBRATION_CONTROL_MANUAL_OVERRIDE_EN_SHFT	0x7
+#define	MIPI_PROTOCOL_CONTROL_DATA_FORMAT_SHFT			0x13
+#define	MIPI_PROTOCOL_CONTROL_DPCM_SCHEME_SHFT			0x1e
+#define	MIPI_PHY_D0_CONTROL2_SETTLE_COUNT_SHFT			0x18
+#define	MIPI_PHY_D0_CONTROL2_HS_TERM_IMP_SHFT			0x10
+#define	MIPI_PHY_D0_CONTROL2_LP_REC_EN_SHFT				0x4
+#define	MIPI_PHY_D0_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
+#define	MIPI_PHY_D1_CONTROL2_SETTLE_COUNT_SHFT			0x18
+#define	MIPI_PHY_D1_CONTROL2_HS_TERM_IMP_SHFT			0x10
+#define	MIPI_PHY_D1_CONTROL2_LP_REC_EN_SHFT				0x4
+#define	MIPI_PHY_D1_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
+#define	MIPI_PHY_D2_CONTROL2_SETTLE_COUNT_SHFT			0x18
+#define	MIPI_PHY_D2_CONTROL2_HS_TERM_IMP_SHFT			0x10
+#define	MIPI_PHY_D2_CONTROL2_LP_REC_EN_SHFT				0x4
+#define	MIPI_PHY_D2_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
+#define	MIPI_PHY_D3_CONTROL2_SETTLE_COUNT_SHFT			0x18
+#define	MIPI_PHY_D3_CONTROL2_HS_TERM_IMP_SHFT			0x10
+#define	MIPI_PHY_D3_CONTROL2_LP_REC_EN_SHFT				0x4
+#define	MIPI_PHY_D3_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
+#define	MIPI_PHY_CL_CONTROL_HS_TERM_IMP_SHFT			0x18
+#define	MIPI_PHY_CL_CONTROL_LP_REC_EN_SHFT				0x2
+#define	MIPI_PHY_D0_CONTROL_HS_REC_EQ_SHFT				0x1c
+#define	MIPI_PHY_D1_CONTROL_MIPI_CLK_PHY_SHUTDOWNB_SHFT		0x9
+#define	MIPI_PHY_D1_CONTROL_MIPI_DATA_PHY_SHUTDOWNB_SHFT	0x8
+#define	DBG_CSI	0
+
+static struct clk *camio_cam_clk;
+static struct clk *camio_vfe_clk;
+static struct clk *camio_csi_src_clk;
+static struct clk *camio_csi0_vfe_clk;
+static struct clk *camio_csi1_vfe_clk;
+static struct clk *camio_csi0_clk;
+static struct clk *camio_csi1_clk;
+static struct clk *camio_csi0_pclk;
+static struct clk *camio_csi1_pclk;
+static struct clk *camio_vfe_pclk;
+static struct clk *camio_vpe_clk;
+static struct clk *camio_vpe_pclk;
+static struct regulator *fs_vfe;
+static struct regulator *fs_vpe;
+static struct regulator *ldo15;
+static struct regulator *lvs0;
+static struct regulator *ldo25;
+
+static struct msm_camera_io_ext camio_ext;
+static struct msm_camera_io_clk camio_clk;
+static struct platform_device *camio_dev;
+static struct resource *csiio;
+void __iomem *csibase;
+static int vpe_clk_rate;
+struct msm_bus_scale_pdata *cam_bus_scale_table;
+
+static void msm_camera_vreg_enable(void)
+{
+	ldo15 = regulator_get(NULL, "8058_l15");
+	if (IS_ERR(ldo15)) {
+		pr_err("%s: VREG LDO15 get failed\n", __func__);
+		ldo15 = NULL;
+		return;
+	}
+	if (regulator_set_voltage(ldo15, 2850000, 2850000)) {
+		pr_err("%s: VREG LDO15 set voltage failed\n",  __func__);
+		goto ldo15_disable;
+	}
+	if (regulator_enable(ldo15)) {
+		pr_err("%s: VREG LDO15 enable failed\n", __func__);
+		goto ldo15_put;
+	}
+
+	lvs0 = regulator_get(NULL, "8058_lvs0");
+	if (IS_ERR(lvs0)) {
+		pr_err("%s: VREG LVS0 get failed\n", __func__);
+		lvs0 = NULL;
+		goto ldo15_disable;
+	}
+	if (regulator_enable(lvs0)) {
+		pr_err("%s: VREG LVS0 enable failed\n", __func__);
+		goto lvs0_put;
+	}
+
+	ldo25 = regulator_get(NULL, "8058_l25");
+	if (IS_ERR(ldo25)) {
+		pr_err("%s: VREG LDO25 get failed\n", __func__);
+		ldo25 = NULL;
+		goto lvs0_disable;
+	}
+	if (regulator_set_voltage(ldo25, 1200000, 1200000)) {
+		pr_err("%s: VREG LDO25 set voltage failed\n",  __func__);
+		goto ldo25_disable;
+	}
+	if (regulator_enable(ldo25)) {
+		pr_err("%s: VREG LDO25 enable failed\n", __func__);
+		goto ldo25_put;
+	}
+
+	fs_vfe = regulator_get(NULL, "fs_vfe");
+	if (IS_ERR(fs_vfe)) {
+		CDBG("%s: Regulator FS_VFE get failed %ld\n", __func__,
+			PTR_ERR(fs_vfe));
+		fs_vfe = NULL;
+	} else if (regulator_enable(fs_vfe)) {
+		CDBG("%s: Regulator FS_VFE enable failed\n", __func__);
+		regulator_put(fs_vfe);
+	}
+	return;
+
+ldo25_disable:
+	regulator_disable(ldo25);
+ldo25_put:
+	regulator_put(ldo25);
+lvs0_disable:
+	regulator_disable(lvs0);
+lvs0_put:
+	regulator_put(lvs0);
+ldo15_disable:
+	regulator_disable(ldo15);
+ldo15_put:
+	regulator_put(ldo15);
+}
+
+static void msm_camera_vreg_disable(void)
+{
+	if (ldo15) {
+		regulator_disable(ldo15);
+		regulator_put(ldo15);
+	}
+
+	if (lvs0) {
+		regulator_disable(lvs0);
+		regulator_put(lvs0);
+	}
+
+	if (ldo25) {
+		regulator_disable(ldo25);
+		regulator_put(ldo25);
+	}
+
+	if (fs_vfe) {
+		regulator_disable(fs_vfe);
+		regulator_put(fs_vfe);
+	}
+}
+
+int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
+{
+	int rc = 0;
+	struct clk *clk = NULL;
+
+	switch (clktype) {
+	case CAMIO_CAM_MCLK_CLK:
+		camio_cam_clk =
+		clk = clk_get(NULL, "cam_clk");
+		msm_camio_clk_rate_set_2(clk, camio_clk.mclk_clk_rate);
+		break;
+
+	case CAMIO_VFE_CLK:
+		camio_vfe_clk =
+		clk = clk_get(NULL, "vfe_clk");
+		msm_camio_clk_rate_set_2(clk, camio_clk.vfe_clk_rate);
+		break;
+
+	case CAMIO_CSI0_VFE_CLK:
+		camio_csi0_vfe_clk =
+		clk = clk_get(NULL, "csi_vfe_clk");
+		break;
+
+	case CAMIO_CSI1_VFE_CLK:
+		camio_csi1_vfe_clk =
+		clk = clk_get(&camio_dev->dev, "csi_vfe_clk");
+		break;
+
+	case CAMIO_CSI_SRC_CLK:
+		camio_csi_src_clk =
+		clk = clk_get(NULL, "csi_src_clk");
+		msm_camio_clk_rate_set_2(clk, 384000000);
+		break;
+
+	case CAMIO_CSI0_CLK:
+		camio_csi0_clk =
+		clk = clk_get(NULL, "csi_clk");
+		break;
+
+	case CAMIO_CSI1_CLK:
+		camio_csi1_clk =
+		clk = clk_get(&camio_dev->dev, "csi_clk");
+		break;
+
+	case CAMIO_VFE_PCLK:
+		camio_vfe_pclk =
+		clk = clk_get(NULL, "vfe_pclk");
+		break;
+
+	case CAMIO_CSI0_PCLK:
+		camio_csi0_pclk =
+		clk = clk_get(NULL, "csi_pclk");
+		break;
+
+	case CAMIO_CSI1_PCLK:
+		camio_csi1_pclk =
+		clk = clk_get(&camio_dev->dev, "csi_pclk");
+		break;
+
+	case CAMIO_VPE_CLK:
+		camio_vpe_clk =
+		clk = clk_get(NULL, "vpe_clk");
+		vpe_clk_rate = clk_round_rate(camio_vpe_clk, vpe_clk_rate);
+		clk_set_rate(camio_vpe_clk, vpe_clk_rate);
+		break;
+
+	case CAMIO_VPE_PCLK:
+		camio_vpe_pclk =
+		clk = clk_get(NULL, "vpe_pclk");
+		break;
+
+	default:
+		break;
+	}
+
+	if (!IS_ERR(clk))
+		clk_enable(clk);
+	else
+		rc = -1;
+	return rc;
+}
+
+int msm_camio_clk_disable(enum msm_camio_clk_type clktype)
+{
+	int rc = 0;
+	struct clk *clk = NULL;
+
+	switch (clktype) {
+	case CAMIO_CAM_MCLK_CLK:
+		clk = camio_cam_clk;
+		break;
+
+	case CAMIO_VFE_CLK:
+		clk = camio_vfe_clk;
+		break;
+
+	case CAMIO_CSI_SRC_CLK:
+		clk = camio_csi_src_clk;
+		break;
+
+	case CAMIO_CSI0_VFE_CLK:
+		clk = camio_csi0_vfe_clk;
+		break;
+
+	case CAMIO_CSI1_VFE_CLK:
+		clk = camio_csi1_vfe_clk;
+		break;
+
+	case CAMIO_CSI0_CLK:
+		clk = camio_csi0_clk;
+		break;
+
+	case CAMIO_CSI1_CLK:
+		clk = camio_csi1_clk;
+		break;
+
+	case CAMIO_VFE_PCLK:
+		clk = camio_vfe_pclk;
+		break;
+
+	case CAMIO_CSI0_PCLK:
+		clk = camio_csi0_pclk;
+		break;
+
+	case CAMIO_CSI1_PCLK:
+		clk = camio_csi1_pclk;
+		break;
+
+	case CAMIO_VPE_CLK:
+		clk = camio_vpe_clk;
+		break;
+
+	case CAMIO_VPE_PCLK:
+		clk = camio_vpe_pclk;
+		break;
+
+	default:
+		break;
+	}
+
+	if (!IS_ERR(clk)) {
+		clk_disable(clk);
+		clk_put(clk);
+	} else
+		rc = -1;
+	return rc;
+}
+
+int msm_camio_vfe_clk_rate_set(int rate)
+{
+	int rc = 0;
+	struct clk *clk = camio_vfe_clk;
+	if (rate > clk_get_rate(clk))
+		rc = clk_set_rate(clk, rate);
+	return rc;
+}
+
+void msm_camio_clk_rate_set(int rate)
+{
+	struct clk *clk = camio_cam_clk;
+	clk_set_rate(clk, rate);
+}
+
+void msm_camio_clk_rate_set_2(struct clk *clk, int rate)
+{
+	clk_set_rate(clk, rate);
+}
+
+static irqreturn_t msm_io_csi_irq(int irq_num, void *data)
+{
+	uint32_t irq = 0;
+	if (csibase != NULL)
+		irq = msm_camera_io_r(csibase + MIPI_INTERRUPT_STATUS);
+	CDBG("%s MIPI_INTERRUPT_STATUS = 0x%x\n", __func__, irq);
+	if (csibase != NULL)
+		msm_camera_io_w(irq, csibase + MIPI_INTERRUPT_STATUS);
+	return IRQ_HANDLED;
+}
+
+int msm_camio_vpe_clk_disable(void)
+{
+	int rc = 0;
+	if (fs_vpe) {
+		regulator_disable(fs_vpe);
+		regulator_put(fs_vpe);
+	}
+
+	rc = msm_camio_clk_disable(CAMIO_VPE_CLK);
+	if (rc < 0)
+		return rc;
+	rc = msm_camio_clk_disable(CAMIO_VPE_PCLK);
+	return rc;
+}
+
+int msm_camio_vpe_clk_enable(uint32_t clk_rate)
+{
+	int rc = 0;
+	fs_vpe = regulator_get(NULL, "fs_vpe");
+	if (IS_ERR(fs_vpe)) {
+		CDBG("%s: Regulator FS_VPE get failed %ld\n", __func__,
+			PTR_ERR(fs_vpe));
+		fs_vpe = NULL;
+	} else if (regulator_enable(fs_vpe)) {
+		CDBG("%s: Regulator FS_VPE enable failed\n", __func__);
+		regulator_put(fs_vpe);
+	}
+
+	vpe_clk_rate = clk_rate;
+	rc = msm_camio_clk_enable(CAMIO_VPE_CLK);
+	if (rc < 0)
+		return rc;
+
+	rc = msm_camio_clk_enable(CAMIO_VPE_PCLK);
+	return rc;
+}
+
+#ifdef DBG_CSI
+static int csi_request_irq(void)
+{
+	return request_irq(camio_ext.csiirq, msm_io_csi_irq,
+		IRQF_TRIGGER_HIGH, "csi", 0);
+}
+#else
+static int csi_request_irq(void) { return 0; }
+#endif
+
+#ifdef DBG_CSI
+static void csi_free_irq(void)
+{
+	free_irq(camio_ext.csiirq, 0);
+}
+#else
+static void csi_free_irq(void) { return 0; }
+#endif
+
+int msm_camio_enable(struct platform_device *pdev)
+{
+	int rc = 0;
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+	camio_dev = pdev;
+	camio_ext = camdev->ioext;
+	camio_clk = camdev->ioclk;
+	cam_bus_scale_table = camdev->cam_bus_scale_table;
+
+	msm_camio_clk_enable(CAMIO_VFE_CLK);
+	msm_camio_clk_enable(CAMIO_CSI0_VFE_CLK);
+	msm_camio_clk_enable(CAMIO_CSI1_VFE_CLK);
+	msm_camio_clk_enable(CAMIO_CSI_SRC_CLK);
+	msm_camio_clk_enable(CAMIO_CSI0_CLK);
+	msm_camio_clk_enable(CAMIO_CSI1_CLK);
+	msm_camio_clk_enable(CAMIO_VFE_PCLK);
+	msm_camio_clk_enable(CAMIO_CSI0_PCLK);
+	msm_camio_clk_enable(CAMIO_CSI1_PCLK);
+
+	csiio = request_mem_region(camio_ext.csiphy,
+		camio_ext.csisz, pdev->name);
+	if (!csiio) {
+		rc = -EBUSY;
+		goto common_fail;
+	}
+	csibase = ioremap(camio_ext.csiphy,
+		camio_ext.csisz);
+	if (!csibase) {
+		rc = -ENOMEM;
+		goto csi_busy;
+	}
+	rc = csi_request_irq();
+	if (rc < 0)
+		goto csi_irq_fail;
+
+	return 0;
+
+csi_irq_fail:
+	iounmap(csibase);
+	csibase = NULL;
+csi_busy:
+	release_mem_region(camio_ext.csiphy, camio_ext.csisz);
+	csibase = NULL;
+common_fail:
+	msm_camio_clk_disable(CAMIO_CAM_MCLK_CLK);
+	msm_camio_clk_disable(CAMIO_CSI0_VFE_CLK);
+	msm_camio_clk_disable(CAMIO_CSI0_CLK);
+	msm_camio_clk_disable(CAMIO_CSI1_VFE_CLK);
+	msm_camio_clk_disable(CAMIO_CSI1_CLK);
+	msm_camio_clk_disable(CAMIO_VFE_PCLK);
+	msm_camio_clk_disable(CAMIO_CSI0_PCLK);
+	msm_camio_clk_disable(CAMIO_CSI1_PCLK);
+	msm_camera_vreg_disable();
+	camdev->camera_gpio_off();
+	return rc;
+}
+
+static void msm_camio_csi_disable(void)
+{
+	uint32_t val;
+
+	val = 0x0;
+	if (csibase != NULL) {
+		CDBG("%s MIPI_PHY_D0_CONTROL2 val=0x%x\n", __func__, val);
+		msm_camera_io_w(val, csibase + MIPI_PHY_D0_CONTROL2);
+		msm_camera_io_w(val, csibase + MIPI_PHY_D1_CONTROL2);
+		msm_camera_io_w(val, csibase + MIPI_PHY_D2_CONTROL2);
+		msm_camera_io_w(val, csibase + MIPI_PHY_D3_CONTROL2);
+		CDBG("%s MIPI_PHY_CL_CONTROL val=0x%x\n", __func__, val);
+		msm_camera_io_w(val, csibase + MIPI_PHY_CL_CONTROL);
+		msleep(20);
+		val = msm_camera_io_r(csibase + MIPI_PHY_D1_CONTROL);
+		val &=
+		~((0x1 << MIPI_PHY_D1_CONTROL_MIPI_CLK_PHY_SHUTDOWNB_SHFT)
+		|(0x1 << MIPI_PHY_D1_CONTROL_MIPI_DATA_PHY_SHUTDOWNB_SHFT));
+		CDBG("%s MIPI_PHY_D1_CONTROL val=0x%x\n", __func__, val);
+		msm_camera_io_w(val, csibase + MIPI_PHY_D1_CONTROL);
+		usleep_range(5000, 6000);
+		msm_camera_io_w(0x0, csibase + MIPI_INTERRUPT_MASK);
+		msm_camera_io_w(0x0, csibase + MIPI_INTERRUPT_STATUS);
+		csi_free_irq();
+		iounmap(csibase);
+		csibase = NULL;
+		release_mem_region(camio_ext.csiphy, camio_ext.csisz);
+	}
+}
+void msm_camio_disable(struct platform_device *pdev)
+{
+	CDBG("disable mipi\n");
+	msm_camio_csi_disable();
+	CDBG("disable clocks\n");
+	msm_camio_clk_disable(CAMIO_CSI0_VFE_CLK);
+	msm_camio_clk_disable(CAMIO_CSI0_CLK);
+	msm_camio_clk_disable(CAMIO_CSI1_VFE_CLK);
+	msm_camio_clk_disable(CAMIO_CSI1_CLK);
+	msm_camio_clk_disable(CAMIO_VFE_PCLK);
+	msm_camio_clk_disable(CAMIO_CSI0_PCLK);
+	msm_camio_clk_disable(CAMIO_CSI1_PCLK);
+	msm_camio_clk_disable(CAMIO_CSI_SRC_CLK);
+	msm_camio_clk_disable(CAMIO_VFE_CLK);
+}
+
+int msm_camio_sensor_clk_on(struct platform_device *pdev)
+{
+	int rc = 0;
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+	camio_dev = pdev;
+	camio_ext = camdev->ioext;
+	camio_clk = camdev->ioclk;
+
+	msm_camera_vreg_enable();
+	usleep_range(10000, 11000);
+	rc = camdev->camera_gpio_on();
+	if (rc < 0)
+		return rc;
+	return msm_camio_clk_enable(CAMIO_CAM_MCLK_CLK);
+}
+
+int msm_camio_sensor_clk_off(struct platform_device *pdev)
+{
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+	msm_camera_vreg_disable();
+	camdev->camera_gpio_off();
+	return msm_camio_clk_disable(CAMIO_CAM_MCLK_CLK);
+
+}
+
+void msm_camio_vfe_blk_reset(void)
+{
+	return;
+}
+
+int msm_camio_probe_on(struct platform_device *pdev)
+{
+	int rc = 0;
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+	camio_dev = pdev;
+	camio_ext = camdev->ioext;
+	camio_clk = camdev->ioclk;
+
+	rc = camdev->camera_gpio_on();
+	if (rc < 0)
+		return rc;
+	msm_camera_vreg_enable();
+	return msm_camio_clk_enable(CAMIO_CAM_MCLK_CLK);
+}
+
+int msm_camio_probe_off(struct platform_device *pdev)
+{
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+	msm_camera_vreg_disable();
+	camdev->camera_gpio_off();
+	return msm_camio_clk_disable(CAMIO_CAM_MCLK_CLK);
+}
+
+int msm_camio_csi_config(struct msm_camera_csi_params *csi_params)
+{
+	int rc = 0;
+	uint32_t val = 0;
+	int i;
+
+	CDBG("msm_camio_csi_config\n");
+	if (csibase != NULL) {
+		/* SOT_ECC_EN enable error correction for SYNC (data-lane) */
+		msm_camera_io_w(0x4, csibase + MIPI_PHY_CONTROL);
+
+		/* SW_RST to the CSI core */
+		msm_camera_io_w(MIPI_PROTOCOL_CONTROL_SW_RST_BMSK,
+		csibase + MIPI_PROTOCOL_CONTROL);
+
+		/* PROTOCOL CONTROL */
+		val = MIPI_PROTOCOL_CONTROL_LONG_PACKET_HEADER_CAPTURE_BMSK |
+			MIPI_PROTOCOL_CONTROL_DECODE_ID_BMSK |
+			MIPI_PROTOCOL_CONTROL_ECC_EN_BMSK;
+		val |= (uint32_t)(csi_params->data_format) <<
+			MIPI_PROTOCOL_CONTROL_DATA_FORMAT_SHFT;
+		val |= csi_params->dpcm_scheme <<
+			MIPI_PROTOCOL_CONTROL_DPCM_SCHEME_SHFT;
+		CDBG("%s MIPI_PROTOCOL_CONTROL val=0x%x\n", __func__, val);
+		msm_camera_io_w(val, csibase + MIPI_PROTOCOL_CONTROL);
+
+		/* settle_cnt is very sensitive to speed!
+		increase this value to run at higher speeds */
+		val = (csi_params->settle_cnt <<
+			MIPI_PHY_D0_CONTROL2_SETTLE_COUNT_SHFT) |
+			(0x0F << MIPI_PHY_D0_CONTROL2_HS_TERM_IMP_SHFT) |
+			(0x1 << MIPI_PHY_D0_CONTROL2_LP_REC_EN_SHFT) |
+			(0x1 << MIPI_PHY_D0_CONTROL2_ERR_SOT_HS_EN_SHFT);
+		CDBG("%s MIPI_PHY_D0_CONTROL2 val=0x%x\n", __func__, val);
+		for (i = 0; i < csi_params->lane_cnt; i++)
+			msm_camera_io_w(val,
+				csibase + MIPI_PHY_D0_CONTROL2 + i * 4);
+
+		val = (0x0F << MIPI_PHY_CL_CONTROL_HS_TERM_IMP_SHFT) |
+			(0x1 << MIPI_PHY_CL_CONTROL_LP_REC_EN_SHFT);
+		CDBG("%s MIPI_PHY_CL_CONTROL val=0x%x\n", __func__, val);
+		msm_camera_io_w(val, csibase + MIPI_PHY_CL_CONTROL);
+
+		val = 0 << MIPI_PHY_D0_CONTROL_HS_REC_EQ_SHFT;
+		msm_camera_io_w(val, csibase + MIPI_PHY_D0_CONTROL);
+
+		val =
+		(0x1 << MIPI_PHY_D1_CONTROL_MIPI_CLK_PHY_SHUTDOWNB_SHFT)
+		|(0x1 << MIPI_PHY_D1_CONTROL_MIPI_DATA_PHY_SHUTDOWNB_SHFT);
+		CDBG("%s MIPI_PHY_D1_CONTROL val=0x%x\n", __func__, val);
+		msm_camera_io_w(val, csibase + MIPI_PHY_D1_CONTROL);
+
+		msm_camera_io_w(0x00000000, csibase + MIPI_PHY_D2_CONTROL);
+		msm_camera_io_w(0x00000000, csibase + MIPI_PHY_D3_CONTROL);
+
+		/* halcyon only supports 1 or 2 lane */
+		switch (csi_params->lane_cnt) {
+		case 1:
+			msm_camera_io_w(csi_params->lane_assign << 8 | 0x4,
+				csibase + MIPI_CAMERA_CNTL);
+			break;
+		case 2:
+			msm_camera_io_w(csi_params->lane_assign << 8 | 0x5,
+				csibase + MIPI_CAMERA_CNTL);
+			break;
+		case 3:
+			msm_camera_io_w(csi_params->lane_assign << 8 | 0x6,
+				csibase + MIPI_CAMERA_CNTL);
+			break;
+		case 4:
+			msm_camera_io_w(csi_params->lane_assign << 8 | 0x7,
+				csibase + MIPI_CAMERA_CNTL);
+			break;
+		}
+
+		/* mask out ID_ERROR[19], DATA_CMM_ERR[11]
+		and CLK_CMM_ERR[10] - de-featured */
+		msm_camera_io_w(0xF017F3C0, csibase + MIPI_INTERRUPT_MASK);
+		/*clear IRQ bits*/
+		msm_camera_io_w(0xF017F3C0, csibase + MIPI_INTERRUPT_STATUS);
+	} else {
+		pr_info("CSIBASE is NULL");
+	}
+
+	return rc;
+}
+
+void msm_camio_set_perf_lvl(enum msm_bus_perf_setting perf_setting)
+{
+	static uint32_t bus_perf_client;
+	int rc = 0;
+	switch (perf_setting) {
+	case S_INIT:
+		bus_perf_client =
+			msm_bus_scale_register_client(cam_bus_scale_table);
+		if (!bus_perf_client) {
+			pr_err("%s: Registration Failed!!!\n", __func__);
+			bus_perf_client = 0;
+			return;
+		}
+		CDBG("%s: S_INIT rc = %u\n", __func__, bus_perf_client);
+		break;
+	case S_EXIT:
+		if (bus_perf_client) {
+			CDBG("%s: S_EXIT\n", __func__);
+			msm_bus_scale_unregister_client(bus_perf_client);
+		} else
+			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+	case S_PREVIEW:
+		if (bus_perf_client) {
+			rc = msm_bus_scale_client_update_request(
+				bus_perf_client, 1);
+			CDBG("%s: S_PREVIEW rc = %d\n", __func__, rc);
+		} else
+			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+	case S_VIDEO:
+		if (bus_perf_client) {
+			rc = msm_bus_scale_client_update_request(
+				bus_perf_client, 2);
+			CDBG("%s: S_VIDEO rc = %d\n", __func__, rc);
+		} else
+			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+	case S_CAPTURE:
+		if (bus_perf_client) {
+			rc = msm_bus_scale_client_update_request(
+				bus_perf_client, 3);
+			CDBG("%s: S_CAPTURE rc = %d\n", __func__, rc);
+		} else
+			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+
+	case S_ZSL:
+		if (bus_perf_client) {
+			rc = msm_bus_scale_client_update_request(
+				bus_perf_client, 4);
+			CDBG("%s: S_ZSL rc = %d\n", __func__, rc);
+		} else
+			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+	case S_STEREO_VIDEO:
+		if (bus_perf_client) {
+			rc = msm_bus_scale_client_update_request(
+				bus_perf_client, 5);
+			CDBG("%s: S_STEREO_VIDEO rc = %d\n", __func__, rc);
+		} else
+			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+	case S_STEREO_CAPTURE:
+		if (bus_perf_client) {
+			rc = msm_bus_scale_client_update_request(
+				bus_perf_client, 6);
+			CDBG("%s: S_STEREO_VIDEO rc = %d\n", __func__, rc);
+		} else
+			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+	case S_DEFAULT:
+		break;
+	default:
+		pr_warning("%s: INVALID CASE\n", __func__);
+	}
+}
+
+int msm_cam_core_reset(void)
+{
+	struct clk *clk1;
+	int rc = 0;
+	clk1 = clk_get(&camio_dev->dev, "csi_vfe_clk");
+	if (IS_ERR(clk1)) {
+		pr_err("%s: did not get csi_vfe_clk\n", __func__);
+		return PTR_ERR(clk1);
+	}
+	rc = clk_reset(clk1, CLK_RESET_ASSERT);
+	if (rc) {
+		pr_err("%s:csi_vfe_clk assert failed\n", __func__);
+		clk_put(clk1);
+		return rc;
+	}
+	usleep_range(1000, 1200);
+	rc = clk_reset(clk1, CLK_RESET_DEASSERT);
+	if (rc) {
+		pr_err("%s:csi_vfe_clk deassert failed\n", __func__);
+		clk_put(clk1);
+		return rc;
+	}
+	clk_put(clk1);
+
+	clk1 = clk_get(&camio_dev->dev, "csi_clk");
+	if (IS_ERR(clk1)) {
+		pr_err("%s: did not get csi_clk\n", __func__);
+		return PTR_ERR(clk1);
+	}
+	rc = clk_reset(clk1, CLK_RESET_ASSERT);
+	if (rc) {
+		pr_err("%s:csi_clk assert failed\n", __func__);
+		clk_put(clk1);
+		return rc;
+	}
+	usleep_range(1000, 1200);
+	rc = clk_reset(clk1, CLK_RESET_DEASSERT);
+	if (rc) {
+		pr_err("%s:csi_clk deassert failed\n", __func__);
+		clk_put(clk1);
+		return rc;
+	}
+	clk_put(clk1);
+
+	clk1 = clk_get(&camio_dev->dev, "csi_pclk");
+	if (IS_ERR(clk1)) {
+		pr_err("%s: did not get csi_pclk\n", __func__);
+		return PTR_ERR(clk1);
+	}
+	rc = clk_reset(clk1, CLK_RESET_ASSERT);
+	if (rc) {
+		pr_err("%s:csi_pclk assert failed\n", __func__);
+		clk_put(clk1);
+		return rc;
+	}
+	usleep_range(1000, 1200);
+	rc = clk_reset(clk1, CLK_RESET_DEASSERT);
+	if (rc) {
+		pr_err("%s:csi_pclk deassert failed\n", __func__);
+		clk_put(clk1);
+		return rc;
+	}
+	clk_put(clk1);
+
+	return rc;
+}
diff --git a/drivers/media/platform/msm/camera_v1/io/msm_io_vfe31.c b/drivers/media/platform/msm/camera_v1/io/msm_io_vfe31.c
new file mode 100644
index 0000000..1cd2782
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/io/msm_io_vfe31.c
@@ -0,0 +1,776 @@
+/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/pm_qos.h>
+#include <linux/regulator/consumer.h>
+#include <mach/gpio.h>
+#include <mach/board.h>
+#include <mach/camera.h>
+#include <mach/vreg.h>
+#include <mach/clk.h>
+
+#define CAMIF_CFG_RMSK             0x1fffff
+#define CAM_SEL_BMSK               0x2
+#define CAM_PCLK_SRC_SEL_BMSK      0x60000
+#define CAM_PCLK_INVERT_BMSK       0x80000
+#define CAM_PAD_REG_SW_RESET_BMSK  0x100000
+
+#define EXT_CAM_HSYNC_POL_SEL_BMSK 0x10000
+#define EXT_CAM_VSYNC_POL_SEL_BMSK 0x8000
+#define MDDI_CLK_CHICKEN_BIT_BMSK  0x80
+
+#define CAM_SEL_SHFT               0x1
+#define CAM_PCLK_SRC_SEL_SHFT      0x11
+#define CAM_PCLK_INVERT_SHFT       0x13
+#define CAM_PAD_REG_SW_RESET_SHFT  0x14
+
+#define EXT_CAM_HSYNC_POL_SEL_SHFT 0x10
+#define EXT_CAM_VSYNC_POL_SEL_SHFT 0xF
+#define MDDI_CLK_CHICKEN_BIT_SHFT  0x7
+
+/* MIPI	CSI	controller registers */
+#define	MIPI_PHY_CONTROL			0x00000000
+#define	MIPI_PROTOCOL_CONTROL		0x00000004
+#define	MIPI_INTERRUPT_STATUS		0x00000008
+#define	MIPI_INTERRUPT_MASK			0x0000000C
+#define	MIPI_CAMERA_CNTL			0x00000024
+#define	MIPI_CALIBRATION_CONTROL	0x00000018
+#define	MIPI_PHY_D0_CONTROL2		0x00000038
+#define	MIPI_PHY_D1_CONTROL2		0x0000003C
+#define	MIPI_PHY_D2_CONTROL2		0x00000040
+#define	MIPI_PHY_D3_CONTROL2		0x00000044
+#define	MIPI_PHY_CL_CONTROL			0x00000048
+#define	MIPI_PHY_D0_CONTROL			0x00000034
+#define	MIPI_PHY_D1_CONTROL			0x00000020
+#define	MIPI_PHY_D2_CONTROL			0x0000002C
+#define	MIPI_PHY_D3_CONTROL			0x00000030
+#define	MIPI_PROTOCOL_CONTROL_SW_RST_BMSK			0x8000000
+#define	MIPI_PROTOCOL_CONTROL_LONG_PACKET_HEADER_CAPTURE_BMSK	0x200000
+#define	MIPI_PROTOCOL_CONTROL_DATA_FORMAT_BMSK			0x180000
+#define	MIPI_PROTOCOL_CONTROL_DECODE_ID_BMSK			0x40000
+#define	MIPI_PROTOCOL_CONTROL_ECC_EN_BMSK			0x20000
+#define	MIPI_CALIBRATION_CONTROL_SWCAL_CAL_EN_SHFT		0x16
+#define	MIPI_CALIBRATION_CONTROL_SWCAL_STRENGTH_OVERRIDE_EN_SHFT	0x15
+#define	MIPI_CALIBRATION_CONTROL_CAL_SW_HW_MODE_SHFT		0x14
+#define	MIPI_CALIBRATION_CONTROL_MANUAL_OVERRIDE_EN_SHFT	0x7
+#define	MIPI_PROTOCOL_CONTROL_DATA_FORMAT_SHFT			0x13
+#define	MIPI_PROTOCOL_CONTROL_DPCM_SCHEME_SHFT			0x1e
+#define	MIPI_PHY_D0_CONTROL2_SETTLE_COUNT_SHFT			0x18
+#define	MIPI_PHY_D0_CONTROL2_HS_TERM_IMP_SHFT			0x10
+#define	MIPI_PHY_D0_CONTROL2_LP_REC_EN_SHFT				0x4
+#define	MIPI_PHY_D0_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
+#define	MIPI_PHY_D1_CONTROL2_SETTLE_COUNT_SHFT			0x18
+#define	MIPI_PHY_D1_CONTROL2_HS_TERM_IMP_SHFT			0x10
+#define	MIPI_PHY_D1_CONTROL2_LP_REC_EN_SHFT				0x4
+#define	MIPI_PHY_D1_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
+#define	MIPI_PHY_D2_CONTROL2_SETTLE_COUNT_SHFT			0x18
+#define	MIPI_PHY_D2_CONTROL2_HS_TERM_IMP_SHFT			0x10
+#define	MIPI_PHY_D2_CONTROL2_LP_REC_EN_SHFT				0x4
+#define	MIPI_PHY_D2_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
+#define	MIPI_PHY_D3_CONTROL2_SETTLE_COUNT_SHFT			0x18
+#define	MIPI_PHY_D3_CONTROL2_HS_TERM_IMP_SHFT			0x10
+#define	MIPI_PHY_D3_CONTROL2_LP_REC_EN_SHFT				0x4
+#define	MIPI_PHY_D3_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
+#define	MIPI_PHY_CL_CONTROL_HS_TERM_IMP_SHFT			0x18
+#define	MIPI_PHY_CL_CONTROL_LP_REC_EN_SHFT				0x2
+#define	MIPI_PHY_D0_CONTROL_HS_REC_EQ_SHFT				0x1c
+#define	MIPI_PHY_D1_CONTROL_MIPI_CLK_PHY_SHUTDOWNB_SHFT		0x9
+#define	MIPI_PHY_D1_CONTROL_MIPI_DATA_PHY_SHUTDOWNB_SHFT	0x8
+
+#define	CAMIO_VFE_CLK_SNAP			122880000
+#define	CAMIO_VFE_CLK_PREV			122880000
+
+/* AXI rates in KHz */
+#define MSM_AXI_QOS_PREVIEW     192000
+#define MSM_AXI_QOS_SNAPSHOT    192000
+#define MSM_AXI_QOS_RECORDING   192000
+
+static struct clk *camio_vfe_mdc_clk;
+static struct clk *camio_mdc_clk;
+static struct clk *camio_vfe_clk;
+static struct clk *camio_vfe_camif_clk;
+static struct clk *camio_vfe_pbdg_clk;
+static struct clk *camio_cam_m_clk;
+static struct clk *camio_camif_pad_pbdg_clk;
+static struct clk *camio_csi_clk;
+static struct clk *camio_csi_pclk;
+static struct clk *camio_csi_vfe_clk;
+static struct clk *camio_vpe_clk;
+static struct regulator *fs_vpe;
+static struct msm_camera_io_ext camio_ext;
+static struct msm_camera_io_clk camio_clk;
+static struct resource *camifpadio, *csiio;
+void __iomem *camifpadbase, *csibase;
+static uint32_t vpe_clk_rate;
+
+static struct regulator_bulk_data regs[] = {
+	{ .supply = "gp2",  .min_uV = 2600000, .max_uV = 2600000 },
+	{ .supply = "lvsw1" },
+	{ .supply = "fs_vfe" },
+	/* sn12m0pz regulators */
+	{ .supply = "gp6",  .min_uV = 3050000, .max_uV = 3100000 },
+	{ .supply = "gp16", .min_uV = 1200000, .max_uV = 1200000 },
+};
+
+static int reg_count;
+
+static void msm_camera_vreg_enable(struct platform_device *pdev)
+{
+	int count, rc;
+
+	struct device *dev = &pdev->dev;
+
+	/* Use gp6 and gp16 if and only if dev name matches. */
+	if (!strncmp(pdev->name, "msm_camera_sn12m0pz", 20))
+		count = ARRAY_SIZE(regs);
+	else
+		count = ARRAY_SIZE(regs) - 2;
+
+	rc = regulator_bulk_get(dev, count, regs);
+
+	if (rc) {
+		dev_err(dev, "%s: could not get regulators: %d\n",
+				__func__, rc);
+		return;
+	}
+
+	rc = regulator_bulk_set_voltage(count, regs);
+
+	if (rc) {
+		dev_err(dev, "%s: could not set voltages: %d\n",
+				__func__, rc);
+		goto reg_free;
+	}
+
+	rc = regulator_bulk_enable(count, regs);
+
+	if (rc) {
+		dev_err(dev, "%s: could not enable regulators: %d\n",
+				__func__, rc);
+		goto reg_free;
+	}
+
+	reg_count = count;
+	return;
+
+reg_free:
+	regulator_bulk_free(count, regs);
+	return;
+}
+
+
+static void msm_camera_vreg_disable(void)
+{
+	regulator_bulk_disable(reg_count, regs);
+	regulator_bulk_free(reg_count, regs);
+	reg_count = 0;
+}
+
+int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
+{
+	int rc = 0;
+	struct clk *clk = NULL;
+
+	switch (clktype) {
+	case CAMIO_VFE_MDC_CLK:
+		camio_vfe_mdc_clk =
+		clk = clk_get(NULL, "vfe_mdc_clk");
+		break;
+
+	case CAMIO_MDC_CLK:
+		camio_mdc_clk =
+		clk = clk_get(NULL, "mdc_clk");
+		break;
+
+	case CAMIO_VFE_CLK:
+		camio_vfe_clk =
+		clk = clk_get(NULL, "vfe_clk");
+		msm_camio_clk_rate_set_2(clk, camio_clk.vfe_clk_rate);
+		break;
+
+	case CAMIO_VFE_CAMIF_CLK:
+		camio_vfe_camif_clk =
+		clk = clk_get(NULL, "vfe_camif_clk");
+		break;
+
+	case CAMIO_VFE_PBDG_CLK:
+		camio_vfe_pbdg_clk =
+		clk = clk_get(NULL, "vfe_pclk");
+		break;
+
+	case CAMIO_CAM_MCLK_CLK:
+		camio_cam_m_clk =
+		clk = clk_get(NULL, "cam_m_clk");
+		msm_camio_clk_rate_set_2(clk, camio_clk.mclk_clk_rate);
+		break;
+
+	case CAMIO_CAMIF_PAD_PBDG_CLK:
+		camio_camif_pad_pbdg_clk =
+		clk = clk_get(NULL, "camif_pad_pclk");
+		break;
+
+	case CAMIO_CSI0_CLK:
+		camio_csi_clk =
+		clk = clk_get(NULL, "csi_clk");
+		msm_camio_clk_rate_set_2(clk, 153600000);
+		break;
+	case CAMIO_CSI0_VFE_CLK:
+		camio_csi_vfe_clk =
+		clk = clk_get(NULL, "csi_vfe_clk");
+		break;
+	case CAMIO_CSI0_PCLK:
+		camio_csi_pclk =
+		clk = clk_get(NULL, "csi_pclk");
+		break;
+
+	case CAMIO_VPE_CLK:
+		camio_vpe_clk =
+		clk = clk_get(NULL, "vpe_clk");
+		vpe_clk_rate = clk_round_rate(clk, vpe_clk_rate);
+		clk_set_rate(clk, vpe_clk_rate);
+		break;
+	default:
+		break;
+	}
+
+	if (!IS_ERR(clk))
+		clk_prepare_enable(clk);
+	else
+		rc = -1;
+	return rc;
+}
+
+int msm_camio_clk_disable(enum msm_camio_clk_type clktype)
+{
+	int rc = 0;
+	struct clk *clk = NULL;
+
+	switch (clktype) {
+	case CAMIO_VFE_MDC_CLK:
+		clk = camio_vfe_mdc_clk;
+		break;
+
+	case CAMIO_MDC_CLK:
+		clk = camio_mdc_clk;
+		break;
+
+	case CAMIO_VFE_CLK:
+		clk = camio_vfe_clk;
+		break;
+
+	case CAMIO_VFE_CAMIF_CLK:
+		clk = camio_vfe_camif_clk;
+		break;
+
+	case CAMIO_VFE_PBDG_CLK:
+		clk = camio_vfe_pbdg_clk;
+		break;
+
+	case CAMIO_CAM_MCLK_CLK:
+		clk = camio_cam_m_clk;
+		break;
+
+	case CAMIO_CAMIF_PAD_PBDG_CLK:
+		clk = camio_camif_pad_pbdg_clk;
+		break;
+	case CAMIO_CSI0_CLK:
+		clk = camio_csi_clk;
+		break;
+	case CAMIO_CSI0_VFE_CLK:
+		clk = camio_csi_vfe_clk;
+		break;
+	case CAMIO_CSI0_PCLK:
+		clk = camio_csi_pclk;
+		break;
+	case CAMIO_VPE_CLK:
+		clk = camio_vpe_clk;
+		break;
+	default:
+		break;
+	}
+
+	if (!IS_ERR(clk)) {
+		clk_disable_unprepare(clk);
+		clk_put(clk);
+	} else {
+		rc = -1;
+	}
+
+	return rc;
+}
+
+void msm_camio_clk_rate_set(int rate)
+{
+	struct clk *clk = camio_cam_m_clk;
+	clk_set_rate(clk, rate);
+}
+
+int msm_camio_vfe_clk_rate_set(int rate)
+{
+	struct clk *clk = camio_vfe_clk;
+	return clk_set_rate(clk, rate);
+}
+
+void msm_camio_clk_rate_set_2(struct clk *clk, int rate)
+{
+	clk_set_rate(clk, rate);
+}
+
+static irqreturn_t msm_io_csi_irq(int irq_num, void *data)
+{
+	uint32_t irq;
+	irq = msm_camera_io_r(csibase + MIPI_INTERRUPT_STATUS);
+	CDBG("%s MIPI_INTERRUPT_STATUS = 0x%x\n", __func__, irq);
+	msm_camera_io_w(irq, csibase + MIPI_INTERRUPT_STATUS);
+	return IRQ_HANDLED;
+}
+
+int msm_camio_vpe_clk_disable(void)
+{
+	msm_camio_clk_disable(CAMIO_VPE_CLK);
+
+	if (fs_vpe) {
+		regulator_disable(fs_vpe);
+		regulator_put(fs_vpe);
+	}
+
+	return 0;
+}
+
+int msm_camio_vpe_clk_enable(uint32_t clk_rate)
+{
+	fs_vpe = regulator_get(NULL, "fs_vpe");
+	if (IS_ERR(fs_vpe)) {
+		pr_err("%s: Regulator FS_VPE get failed %ld\n", __func__,
+			PTR_ERR(fs_vpe));
+		fs_vpe = NULL;
+	} else if (regulator_enable(fs_vpe)) {
+		pr_err("%s: Regulator FS_VPE enable failed\n", __func__);
+		regulator_put(fs_vpe);
+	}
+
+	vpe_clk_rate = clk_rate;
+	msm_camio_clk_enable(CAMIO_VPE_CLK);
+	return 0;
+}
+
+int msm_camio_enable(struct platform_device *pdev)
+{
+	int rc = 0;
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	msm_camio_clk_enable(CAMIO_VFE_PBDG_CLK);
+	if (!sinfo->csi_if)
+		msm_camio_clk_enable(CAMIO_VFE_CAMIF_CLK);
+	else {
+		msm_camio_clk_enable(CAMIO_VFE_CLK);
+		csiio = request_mem_region(camio_ext.csiphy,
+			camio_ext.csisz, pdev->name);
+		if (!csiio) {
+			rc = -EBUSY;
+			goto common_fail;
+		}
+		csibase = ioremap(camio_ext.csiphy,
+			camio_ext.csisz);
+		if (!csibase) {
+			rc = -ENOMEM;
+			goto csi_busy;
+		}
+		rc = request_irq(camio_ext.csiirq, msm_io_csi_irq,
+			IRQF_TRIGGER_RISING, "csi", 0);
+		if (rc < 0)
+			goto csi_irq_fail;
+		/* enable required clocks for CSI */
+		msm_camio_clk_enable(CAMIO_CSI0_PCLK);
+		msm_camio_clk_enable(CAMIO_CSI0_VFE_CLK);
+		msm_camio_clk_enable(CAMIO_CSI0_CLK);
+	}
+	return 0;
+csi_irq_fail:
+	iounmap(csibase);
+csi_busy:
+	release_mem_region(camio_ext.csiphy, camio_ext.csisz);
+common_fail:
+	msm_camio_clk_disable(CAMIO_VFE_PBDG_CLK);
+	msm_camio_clk_disable(CAMIO_VFE_CLK);
+	return rc;
+}
+
+static void msm_camio_csi_disable(void)
+{
+	uint32_t val;
+	val = 0x0;
+	CDBG("%s MIPI_PHY_D0_CONTROL2 val=0x%x\n", __func__, val);
+	msm_camera_io_w(val, csibase + MIPI_PHY_D0_CONTROL2);
+	msm_camera_io_w(val, csibase + MIPI_PHY_D1_CONTROL2);
+	msm_camera_io_w(val, csibase + MIPI_PHY_D2_CONTROL2);
+	msm_camera_io_w(val, csibase + MIPI_PHY_D3_CONTROL2);
+
+	CDBG("%s MIPI_PHY_CL_CONTROL val=0x%x\n", __func__, val);
+	msm_camera_io_w(val, csibase + MIPI_PHY_CL_CONTROL);
+	usleep_range(9000, 10000);
+	free_irq(camio_ext.csiirq, 0);
+	iounmap(csibase);
+	release_mem_region(camio_ext.csiphy, camio_ext.csisz);
+}
+
+void msm_camio_disable(struct platform_device *pdev)
+{
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	if (!sinfo->csi_if) {
+		msm_camio_clk_disable(CAMIO_VFE_CAMIF_CLK);
+	} else {
+		CDBG("disable mipi\n");
+		msm_camio_csi_disable();
+		CDBG("disable clocks\n");
+		msm_camio_clk_disable(CAMIO_CSI0_PCLK);
+		msm_camio_clk_disable(CAMIO_CSI0_VFE_CLK);
+		msm_camio_clk_disable(CAMIO_CSI0_CLK);
+		msm_camio_clk_disable(CAMIO_VFE_CLK);
+	}
+	msm_camio_clk_disable(CAMIO_VFE_PBDG_CLK);
+}
+
+void msm_camio_camif_pad_reg_reset(void)
+{
+	uint32_t reg;
+
+	msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_INTERNAL);
+	usleep_range(10000, 11000);
+
+	reg = (msm_camera_io_r(camifpadbase)) & CAMIF_CFG_RMSK;
+	reg |= 0x3;
+	msm_camera_io_w(reg, camifpadbase);
+	usleep_range(10000, 11000);
+
+	reg = (msm_camera_io_r(camifpadbase)) & CAMIF_CFG_RMSK;
+	reg |= 0x10;
+	msm_camera_io_w(reg, camifpadbase);
+	usleep_range(10000, 11000);
+
+	reg = (msm_camera_io_r(camifpadbase)) & CAMIF_CFG_RMSK;
+	/* Need to be uninverted*/
+	reg &= 0x03;
+	msm_camera_io_w(reg, camifpadbase);
+	usleep_range(10000, 11000);
+}
+
+void msm_camio_vfe_blk_reset(void)
+{
+	return;
+
+
+}
+
+void msm_camio_camif_pad_reg_reset_2(void)
+{
+	uint32_t reg;
+	uint32_t mask, value;
+	reg = (msm_camera_io_r(camifpadbase)) & CAMIF_CFG_RMSK;
+	mask = CAM_PAD_REG_SW_RESET_BMSK;
+	value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
+	msm_camera_io_w((reg & (~mask)) | (value & mask), camifpadbase);
+	usleep_range(10000, 11000);
+	reg = (msm_camera_io_r(camifpadbase)) & CAMIF_CFG_RMSK;
+	mask = CAM_PAD_REG_SW_RESET_BMSK;
+	value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
+	msm_camera_io_w((reg & (~mask)) | (value & mask), camifpadbase);
+	usleep_range(10000, 11000);
+}
+
+void msm_camio_clk_sel(enum msm_camio_clk_src_type srctype)
+{
+	struct clk *clk = NULL;
+
+	clk = camio_vfe_clk;
+
+	if (clk != NULL) {
+		switch (srctype) {
+		case MSM_CAMIO_CLK_SRC_INTERNAL:
+			clk_set_flags(clk, 0x00000100 << 1);
+			break;
+
+		case MSM_CAMIO_CLK_SRC_EXTERNAL:
+			clk_set_flags(clk, 0x00000100);
+			break;
+
+		default:
+			break;
+		}
+	}
+}
+int msm_camio_probe_on(struct platform_device *pdev)
+{
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+	camio_clk = camdev->ioclk;
+	camio_ext = camdev->ioext;
+	camdev->camera_gpio_on();
+	msm_camera_vreg_enable(pdev);
+	return msm_camio_clk_enable(CAMIO_CAM_MCLK_CLK);
+}
+
+int msm_camio_probe_off(struct platform_device *pdev)
+{
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+	msm_camera_vreg_disable();
+	camdev->camera_gpio_off();
+	return msm_camio_clk_disable(CAMIO_CAM_MCLK_CLK);
+}
+
+int msm_camio_sensor_clk_on(struct platform_device *pdev)
+{
+	int rc = 0;
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+	camio_clk = camdev->ioclk;
+	camio_ext = camdev->ioext;
+	camdev->camera_gpio_on();
+	msm_camera_vreg_enable(pdev);
+	msm_camio_clk_enable(CAMIO_CAM_MCLK_CLK);
+	msm_camio_clk_enable(CAMIO_CAMIF_PAD_PBDG_CLK);
+	if (!sinfo->csi_if) {
+		camifpadio = request_mem_region(camio_ext.camifpadphy,
+			camio_ext.camifpadsz, pdev->name);
+		msm_camio_clk_enable(CAMIO_VFE_CLK);
+		if (!camifpadio) {
+			rc = -EBUSY;
+			goto common_fail;
+		}
+		camifpadbase = ioremap(camio_ext.camifpadphy,
+			camio_ext.camifpadsz);
+		if (!camifpadbase) {
+			CDBG("msm_camio_sensor_clk_on fail\n");
+			rc = -ENOMEM;
+			goto parallel_busy;
+		}
+	}
+	return rc;
+parallel_busy:
+	release_mem_region(camio_ext.camifpadphy, camio_ext.camifpadsz);
+	goto common_fail;
+common_fail:
+	msm_camio_clk_disable(CAMIO_CAM_MCLK_CLK);
+	msm_camio_clk_disable(CAMIO_VFE_CLK);
+	msm_camio_clk_disable(CAMIO_CAMIF_PAD_PBDG_CLK);
+	msm_camera_vreg_disable();
+	camdev->camera_gpio_off();
+	return rc;
+}
+
+int msm_camio_sensor_clk_off(struct platform_device *pdev)
+{
+	uint32_t rc = 0;
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+	camdev->camera_gpio_off();
+	msm_camera_vreg_disable();
+	rc = msm_camio_clk_disable(CAMIO_CAM_MCLK_CLK);
+	rc = msm_camio_clk_disable(CAMIO_CAMIF_PAD_PBDG_CLK);
+	if (!sinfo->csi_if) {
+		iounmap(camifpadbase);
+		release_mem_region(camio_ext.camifpadphy, camio_ext.camifpadsz);
+		rc = msm_camio_clk_disable(CAMIO_VFE_CLK);
+	}
+	return rc;
+}
+
+int msm_camio_csi_config(struct msm_camera_csi_params *csi_params)
+{
+	int rc = 0;
+	uint32_t val = 0;
+	int i;
+
+	CDBG("msm_camio_csi_config\n");
+
+	/* SOT_ECC_EN enable error correction for SYNC (data-lane) */
+	msm_camera_io_w(0x4, csibase + MIPI_PHY_CONTROL);
+
+	/* SW_RST to the CSI core */
+	msm_camera_io_w(MIPI_PROTOCOL_CONTROL_SW_RST_BMSK,
+		csibase + MIPI_PROTOCOL_CONTROL);
+
+	/* PROTOCOL CONTROL */
+	val = MIPI_PROTOCOL_CONTROL_LONG_PACKET_HEADER_CAPTURE_BMSK |
+		MIPI_PROTOCOL_CONTROL_DECODE_ID_BMSK |
+		MIPI_PROTOCOL_CONTROL_ECC_EN_BMSK;
+	val |= (uint32_t)(csi_params->data_format) <<
+		MIPI_PROTOCOL_CONTROL_DATA_FORMAT_SHFT;
+	val |= csi_params->dpcm_scheme <<
+		MIPI_PROTOCOL_CONTROL_DPCM_SCHEME_SHFT;
+	CDBG("%s MIPI_PROTOCOL_CONTROL val=0x%x\n", __func__, val);
+	msm_camera_io_w(val, csibase + MIPI_PROTOCOL_CONTROL);
+
+	/* SW CAL EN */
+	val = (0x1 << MIPI_CALIBRATION_CONTROL_SWCAL_CAL_EN_SHFT) |
+		(0x1 <<
+		MIPI_CALIBRATION_CONTROL_SWCAL_STRENGTH_OVERRIDE_EN_SHFT) |
+		(0x1 << MIPI_CALIBRATION_CONTROL_CAL_SW_HW_MODE_SHFT) |
+		(0x1 << MIPI_CALIBRATION_CONTROL_MANUAL_OVERRIDE_EN_SHFT);
+	CDBG("%s MIPI_CALIBRATION_CONTROL val=0x%x\n", __func__, val);
+	msm_camera_io_w(val, csibase + MIPI_CALIBRATION_CONTROL);
+
+	/* settle_cnt is very sensitive to speed!
+	increase this value to run at higher speeds */
+	val = (csi_params->settle_cnt <<
+			MIPI_PHY_D0_CONTROL2_SETTLE_COUNT_SHFT) |
+		(0x0F << MIPI_PHY_D0_CONTROL2_HS_TERM_IMP_SHFT) |
+		(0x1 << MIPI_PHY_D0_CONTROL2_LP_REC_EN_SHFT) |
+		(0x1 << MIPI_PHY_D0_CONTROL2_ERR_SOT_HS_EN_SHFT);
+	CDBG("%s MIPI_PHY_D0_CONTROL2 val=0x%x\n", __func__, val);
+	for (i = 0; i < csi_params->lane_cnt; i++)
+		msm_camera_io_w(val, csibase + MIPI_PHY_D0_CONTROL2 + i * 4);
+
+	val = (0x0F << MIPI_PHY_CL_CONTROL_HS_TERM_IMP_SHFT) |
+		(0x1 << MIPI_PHY_CL_CONTROL_LP_REC_EN_SHFT);
+	CDBG("%s MIPI_PHY_CL_CONTROL val=0x%x\n", __func__, val);
+	msm_camera_io_w(val, csibase + MIPI_PHY_CL_CONTROL);
+
+	val = 0 << MIPI_PHY_D0_CONTROL_HS_REC_EQ_SHFT;
+	msm_camera_io_w(val, csibase + MIPI_PHY_D0_CONTROL);
+
+	val = (0x1 << MIPI_PHY_D1_CONTROL_MIPI_CLK_PHY_SHUTDOWNB_SHFT) |
+		(0x1 << MIPI_PHY_D1_CONTROL_MIPI_DATA_PHY_SHUTDOWNB_SHFT);
+	CDBG("%s MIPI_PHY_D1_CONTROL val=0x%x\n", __func__, val);
+	msm_camera_io_w(val, csibase + MIPI_PHY_D1_CONTROL);
+
+	msm_camera_io_w(0x00000000, csibase + MIPI_PHY_D2_CONTROL);
+	msm_camera_io_w(0x00000000, csibase + MIPI_PHY_D3_CONTROL);
+
+	/* halcyon only supports 1 or 2 lane */
+	switch (csi_params->lane_cnt) {
+	case 1:
+		msm_camera_io_w(csi_params->lane_assign << 8 | 0x4,
+			csibase + MIPI_CAMERA_CNTL);
+		break;
+	case 2:
+		msm_camera_io_w(csi_params->lane_assign << 8 | 0x5,
+			csibase + MIPI_CAMERA_CNTL);
+		break;
+	case 3:
+		msm_camera_io_w(csi_params->lane_assign << 8 | 0x6,
+			csibase + MIPI_CAMERA_CNTL);
+		break;
+	case 4:
+		msm_camera_io_w(csi_params->lane_assign << 8 | 0x7,
+			csibase + MIPI_CAMERA_CNTL);
+		break;
+	}
+
+	/* mask out ID_ERROR[19], DATA_CMM_ERR[11]
+	and CLK_CMM_ERR[10] - de-featured */
+	msm_camera_io_w(0xFFF7F3FF, csibase + MIPI_INTERRUPT_MASK);
+	/*clear IRQ bits*/
+	msm_camera_io_w(0xFFF7F3FF, csibase + MIPI_INTERRUPT_STATUS);
+
+	return rc;
+}
+void msm_camio_set_perf_lvl(enum msm_bus_perf_setting perf_setting)
+{
+	switch (perf_setting) {
+	case S_INIT:
+		add_axi_qos();
+		break;
+	case S_PREVIEW:
+		update_axi_qos(MSM_AXI_QOS_PREVIEW);
+		break;
+	case S_VIDEO:
+		update_axi_qos(MSM_AXI_QOS_RECORDING);
+		break;
+	case S_CAPTURE:
+		update_axi_qos(MSM_AXI_QOS_SNAPSHOT);
+		break;
+	case S_DEFAULT:
+		update_axi_qos(PM_QOS_DEFAULT_VALUE);
+		break;
+	case S_EXIT:
+		release_axi_qos();
+		break;
+	default:
+		CDBG("%s: INVALID CASE\n", __func__);
+	}
+}
+
+int msm_cam_core_reset(void)
+{
+	struct clk *clk1;
+	int rc = 0;
+
+	clk1 = clk_get(NULL, "csi_vfe_clk");
+	if (IS_ERR(clk1)) {
+		pr_err("%s: did not get csi_vfe_clk\n", __func__);
+		return PTR_ERR(clk1);
+	}
+
+	rc = clk_reset(clk1, CLK_RESET_ASSERT);
+	if (rc) {
+		pr_err("%s:csi_vfe_clk assert failed\n", __func__);
+		clk_put(clk1);
+		return rc;
+	}
+	usleep_range(1000, 1200);
+	rc = clk_reset(clk1, CLK_RESET_DEASSERT);
+	if (rc) {
+		pr_err("%s:csi_vfe_clk deassert failed\n", __func__);
+		clk_put(clk1);
+		return rc;
+	}
+	clk_put(clk1);
+
+	clk1 = clk_get(NULL, "csi_clk");
+	if (IS_ERR(clk1)) {
+		pr_err("%s: did not get csi_clk\n", __func__);
+		return PTR_ERR(clk1);
+	}
+
+	rc = clk_reset(clk1, CLK_RESET_ASSERT);
+	if (rc) {
+		pr_err("%s:csi_clk assert failed\n", __func__);
+		clk_put(clk1);
+		return rc;
+	}
+	usleep_range(1000, 1200);
+	rc = clk_reset(clk1, CLK_RESET_DEASSERT);
+	if (rc) {
+		pr_err("%s:csi_clk deassert failed\n", __func__);
+		clk_put(clk1);
+		return rc;
+	}
+	clk_put(clk1);
+
+	clk1 = clk_get(NULL, "csi_pclk");
+	if (IS_ERR(clk1)) {
+		pr_err("%s: did not get csi_pclk\n", __func__);
+		return PTR_ERR(clk1);
+	}
+
+	rc = clk_reset(clk1, CLK_RESET_ASSERT);
+	if (rc) {
+		pr_err("%s:csi_pclk assert failed\n", __func__);
+		clk_put(clk1);
+		return rc;
+	}
+	usleep_range(1000, 1200);
+	rc = clk_reset(clk1, CLK_RESET_DEASSERT);
+	if (rc) {
+		pr_err("%s:csi_pclk deassert failed\n", __func__);
+		clk_put(clk1);
+		return rc;
+	}
+	clk_put(clk1);
+
+	return rc;
+}
diff --git a/drivers/media/platform/msm/camera_v1/io/msm_io_vfe31_v4l2.c b/drivers/media/platform/msm/camera_v1/io/msm_io_vfe31_v4l2.c
new file mode 100644
index 0000000..acf87e4
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/io/msm_io_vfe31_v4l2.c
@@ -0,0 +1,274 @@
+/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/regulator/consumer.h>
+#include <linux/export.h>
+#include <mach/gpio.h>
+#include <mach/board.h>
+#include <mach/camera.h>
+#include <mach/vreg.h>
+#include <mach/camera.h>
+#include <mach/clk.h>
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
+
+#include <linux/pm_qos.h>
+
+/* AXI rates in KHz */
+#define MSM_AXI_QOS_PREVIEW     192000
+#define MSM_AXI_QOS_SNAPSHOT    192000
+#define MSM_AXI_QOS_RECORDING   192000
+
+#define BUFF_SIZE_128 128
+
+static struct clk *camio_vfe_clk;
+static struct clk *camio_vpe_clk;
+static struct clk *camio_vpe_pclk;
+static struct regulator *fs_vpe;
+
+static int vpe_clk_rate;
+
+int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
+{
+	int rc = 0;
+	struct clk *clk = NULL;
+
+	switch (clktype) {
+	case CAMIO_VPE_CLK:
+		camio_vpe_clk =
+		clk = clk_get(NULL, "vpe_clk");
+		vpe_clk_rate = clk_round_rate(camio_vpe_clk, vpe_clk_rate);
+		clk_set_rate(camio_vpe_clk, vpe_clk_rate);
+		break;
+
+	case CAMIO_VPE_PCLK:
+		camio_vpe_pclk =
+		clk = clk_get(NULL, "vpe_pclk");
+		break;
+
+	default:
+		break;
+	}
+
+	if (!IS_ERR(clk)) {
+		clk_prepare(clk);
+		clk_enable(clk);
+	} else {
+		rc = -1;
+	}
+	return rc;
+}
+
+int msm_camio_clk_disable(enum msm_camio_clk_type clktype)
+{
+	int rc = 0;
+	struct clk *clk = NULL;
+
+	switch (clktype) {
+	case CAMIO_VPE_CLK:
+		clk = camio_vpe_clk;
+		break;
+
+	case CAMIO_VPE_PCLK:
+		clk = camio_vpe_pclk;
+		break;
+
+	default:
+		break;
+	}
+
+	if (!IS_ERR(clk)) {
+		clk_disable(clk);
+		clk_unprepare(clk);
+		clk_put(clk);
+	} else {
+		rc = -1;
+	}
+
+	return rc;
+}
+
+int msm_camio_vfe_clk_rate_set(int rate)
+{
+	int rc = 0;
+	struct clk *clk = camio_vfe_clk;
+	if (rate > clk_get_rate(clk))
+		rc = clk_set_rate(clk, rate);
+	return rc;
+}
+
+void msm_camio_clk_rate_set_2(struct clk *clk, int rate)
+{
+	clk_set_rate(clk, rate);
+}
+
+int msm_camio_vpe_clk_disable(void)
+{
+	int rc = 0;
+	if (fs_vpe) {
+		regulator_disable(fs_vpe);
+		regulator_put(fs_vpe);
+	}
+
+	rc = msm_camio_clk_disable(CAMIO_VPE_CLK);
+	if (rc < 0)
+		return rc;
+	rc = msm_camio_clk_disable(CAMIO_VPE_PCLK);
+	return rc;
+}
+
+int msm_camio_vpe_clk_enable(uint32_t clk_rate)
+{
+	int rc = 0;
+	fs_vpe = regulator_get(NULL, "fs_vpe");
+	if (IS_ERR(fs_vpe)) {
+		CDBG("%s: Regulator FS_VPE get failed %ld\n", __func__,
+			PTR_ERR(fs_vpe));
+		fs_vpe = NULL;
+	} else if (regulator_enable(fs_vpe)) {
+		CDBG("%s: Regulator FS_VPE enable failed\n", __func__);
+		regulator_put(fs_vpe);
+	}
+
+	vpe_clk_rate = clk_rate;
+	rc = msm_camio_clk_enable(CAMIO_VPE_CLK);
+	if (rc < 0)
+		return rc;
+
+	rc = msm_camio_clk_enable(CAMIO_VPE_PCLK);
+	return rc;
+}
+
+void msm_camio_vfe_blk_reset(void)
+{
+	return;
+}
+
+void msm_camio_vfe_blk_reset_3(void)
+{
+	return;
+}
+
+static void msm_camio_axi_cfg(enum msm_bus_perf_setting perf_setting)
+{
+	switch (perf_setting) {
+	case S_INIT:
+		add_axi_qos();
+		break;
+	case S_PREVIEW:
+		update_axi_qos(MSM_AXI_QOS_PREVIEW);
+		break;
+	case S_VIDEO:
+		update_axi_qos(MSM_AXI_QOS_RECORDING);
+		break;
+	case S_CAPTURE:
+		update_axi_qos(MSM_AXI_QOS_SNAPSHOT);
+		break;
+	case S_DEFAULT:
+		update_axi_qos(PM_QOS_DEFAULT_VALUE);
+		break;
+	case S_EXIT:
+		release_axi_qos();
+		break;
+	default:
+		CDBG("%s: INVALID CASE\n", __func__);
+	}
+}
+
+void msm_camio_bus_scale_cfg(struct msm_bus_scale_pdata *cam_bus_scale_table,
+		enum msm_bus_perf_setting perf_setting)
+{
+	static uint32_t bus_perf_client;
+	int rc = 0;
+	if (cam_bus_scale_table == NULL) {
+		msm_camio_axi_cfg(perf_setting);
+		return;
+	}
+
+	switch (perf_setting) {
+	case S_INIT:
+		bus_perf_client =
+			msm_bus_scale_register_client(cam_bus_scale_table);
+		if (!bus_perf_client) {
+			pr_err("%s: Registration Failed!!!\n", __func__);
+			bus_perf_client = 0;
+			return;
+		}
+		CDBG("%s: S_INIT rc = %u\n", __func__, bus_perf_client);
+		break;
+	case S_EXIT:
+		if (bus_perf_client) {
+			CDBG("%s: S_EXIT\n", __func__);
+			msm_bus_scale_unregister_client(bus_perf_client);
+		} else
+			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+	case S_PREVIEW:
+		if (bus_perf_client) {
+			rc = msm_bus_scale_client_update_request(
+				bus_perf_client, 1);
+			CDBG("%s: S_PREVIEW rc = %d\n", __func__, rc);
+		} else
+			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+	case S_VIDEO:
+		if (bus_perf_client) {
+			rc = msm_bus_scale_client_update_request(
+				bus_perf_client, 2);
+			CDBG("%s: S_VIDEO rc = %d\n", __func__, rc);
+		} else
+			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+	case S_CAPTURE:
+		if (bus_perf_client) {
+			rc = msm_bus_scale_client_update_request(
+				bus_perf_client, 3);
+			CDBG("%s: S_CAPTURE rc = %d\n", __func__, rc);
+		} else
+			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+
+	case S_ZSL:
+		if (bus_perf_client) {
+			rc = msm_bus_scale_client_update_request(
+				bus_perf_client, 4);
+			CDBG("%s: S_ZSL rc = %d\n", __func__, rc);
+		} else
+			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+	case S_STEREO_VIDEO:
+		if (bus_perf_client) {
+			rc = msm_bus_scale_client_update_request(
+				bus_perf_client, 5);
+			CDBG("%s: S_STEREO_VIDEO rc = %d\n", __func__, rc);
+		} else
+			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+	case S_STEREO_CAPTURE:
+		if (bus_perf_client) {
+			rc = msm_bus_scale_client_update_request(
+				bus_perf_client, 6);
+			CDBG("%s: S_STEREO_VIDEO rc = %d\n", __func__, rc);
+		} else
+			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
+		break;
+	case S_DEFAULT:
+		break;
+	default:
+		pr_warning("%s: INVALID CASE\n", __func__);
+	}
+}
+
diff --git a/drivers/media/platform/msm/camera_v1/mercury/Makefile b/drivers/media/platform/msm/camera_v1/mercury/Makefile
new file mode 100644
index 0000000..bc9c950
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mercury/Makefile
@@ -0,0 +1,3 @@
+GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
+EXTRA_CFLAGS += -Idrivers/media/platform/msm/camera_v1
+obj-$(CONFIG_MSM_MERCURY) += msm_mercury_dev.o msm_mercury_core.o msm_mercury_hw.o msm_mercury_platform.o msm_mercury_sync.o
diff --git a/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_common.h b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_common.h
new file mode 100644
index 0000000..8ce7f7e
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_common.h
@@ -0,0 +1,24 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_MERCURY_COMMON_H
+#define MSM_MERCURY_COMMON_H
+
+#define MSM_MERCURY_DEBUG
+#ifdef MSM_MERCURY_DEBUG
+#define MCR_DBG(fmt, args...) pr_debug(fmt, ##args)
+#else
+#define MCR_DBG(fmt, args...) do { } while (0)
+#endif
+
+#define MCR_PR_ERR   pr_err
+#endif /* MSM_MERCURY_COMMON_H */
diff --git a/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_core.c b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_core.c
new file mode 100644
index 0000000..b0630f0
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_core.c
@@ -0,0 +1,136 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <mach/clk.h>
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
+#include "msm_mercury_hw.h"
+#include "msm_mercury_core.h"
+#include "msm_mercury_platform.h"
+#include "msm_mercury_common.h"
+
+static int reset_done_ack;
+static spinlock_t reset_lock;
+static wait_queue_head_t reset_wait;
+
+int mercury_core_reset(void)
+{
+	struct clk *clk = NULL;
+
+	/*Resettting MMSS Fabric*/
+
+	clk = clk_get(NULL, "jpegd_clk");
+
+	if (!IS_ERR(clk))
+		clk_enable(clk);
+
+	msm_bus_axi_porthalt(MSM_BUS_MASTER_JPEG_DEC);
+	clk_reset(clk, CLK_RESET_ASSERT);
+
+	/*need to have some delay here, there is no
+	 other way to know if hardware reset is complete*/
+	usleep_range(1000, 1200);
+
+	msm_bus_axi_portunhalt(MSM_BUS_MASTER_JPEG_DEC);
+	clk_reset(clk, CLK_RESET_DEASSERT);
+
+	return 0;
+}
+
+int msm_mercury_core_reset(void)
+{
+	unsigned long flags;
+	int rc = 0;
+	int tm = 500;/*500ms*/
+	MCR_DBG("\n%s\n(%d)%s()\n", __FILE__, __LINE__, __func__);
+
+	spin_lock_irqsave(&reset_lock, flags);
+	reset_done_ack = 0;
+	spin_unlock_irqrestore(&reset_lock, flags);
+
+	msm_mercury_hw_reset();
+	rc = wait_event_interruptible_timeout(reset_wait,
+		reset_done_ack,
+		msecs_to_jiffies(tm));
+
+	if (!reset_done_ack) {
+		MCR_DBG("%s: reset ACK failed %d", __func__, rc);
+		return -EBUSY;
+	}
+
+	MCR_DBG("(%d)%s() reset_done_ack rc %d\n\n", __LINE__, __func__, rc);
+	spin_lock_irqsave(&reset_lock, flags);
+	reset_done_ack = 0;
+	spin_unlock_irqrestore(&reset_lock, flags);
+
+	return 0;
+}
+
+void msm_mercury_core_init(void)
+{
+	init_waitqueue_head(&reset_wait);
+	spin_lock_init(&reset_lock);
+}
+
+static int (*msm_mercury_irq_handler) (int, void *, void *);
+
+irqreturn_t msm_mercury_core_irq(int irq_num, void *context)
+{
+	void *data = NULL;
+	unsigned long flags;
+	uint16_t mcr_rd_irq;
+	uint16_t mcr_wr_irq;
+	uint32_t jpeg_status;
+
+	MCR_DBG("\n(%d)%s() irq_number = %d", __LINE__, __func__, irq_num);
+
+	spin_lock_irqsave(&reset_lock, flags);
+	reset_done_ack = 1;
+	spin_unlock_irqrestore(&reset_lock, flags);
+
+	msm_mercury_hw_irq_get_status(&mcr_rd_irq, &mcr_wr_irq);
+	msm_mercury_hw_get_jpeg_status(&jpeg_status);
+	MCR_DBG("mercury_rd_irq = 0x%08X\n", mcr_rd_irq);
+	MCR_DBG("mercury_wr_irq = 0x%08X\n", mcr_wr_irq);
+	MCR_DBG("jpeg_status = 0x%08X\n", jpeg_status);
+	if (mcr_wr_irq & MSM_MERCURY_HW_IRQ_SW_RESET_ACK) {
+		MCR_DBG("*** SW Reset IRQ received ***\n");
+		wake_up(&reset_wait);
+		msm_mercury_hw_wr_irq_clear(MSM_MERCURY_HW_IRQ_SW_RESET_ACK);
+	}
+	if (mcr_wr_irq & MSM_MERCURY_HW_IRQ_WR_ERR_ACK) {
+		MCR_DBG("   *** Error IRQ received ***\n");
+		msm_mercury_irq_handler(MSM_MERCURY_HW_IRQ_WR_ERR_ACK,
+								context, data);
+	}
+	if (mcr_wr_irq & MSM_MERCURY_HW_IRQ_WR_EOI_ACK) {
+		MCR_DBG("   *** WE_EOI IRQ received ***\n");
+		msm_mercury_irq_handler(MSM_MERCURY_HW_IRQ_WR_EOI_ACK,
+								context, data);
+	}
+	return IRQ_HANDLED;
+}
+
+void msm_mercury_core_irq_install(int (*irq_handler) (int, void *, void *))
+{
+	msm_mercury_irq_handler = irq_handler;
+}
+
+void msm_mercury_core_irq_remove(void)
+{
+	msm_mercury_irq_handler = NULL;
+}
diff --git a/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_core.h b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_core.h
new file mode 100644
index 0000000..7237e7b
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_core.h
@@ -0,0 +1,29 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_MERCURY_CORE_H
+#define MSM_MERCURY_CORE_H
+
+#include <linux/interrupt.h>
+#include "msm_mercury_hw.h"
+
+#define msm_mercury_core_buf msm_mercury_hw_buf
+
+irqreturn_t msm_mercury_core_irq(int irq_num, void *context);
+
+void msm_mercury_core_irq_install(int (*irq_handler) (int, void *, void *));
+void msm_mercury_core_irq_remove(void);
+
+int msm_mercury_core_reset(void);
+void msm_mercury_core_init(void);
+
+#endif /* MSM_MERCURY_CORE_H */
diff --git a/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_dev.c b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_dev.c
new file mode 100644
index 0000000..b245bfd
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_dev.c
@@ -0,0 +1,256 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/uaccess.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+#include <media/msm_mercury.h>
+#include <mach/board.h>
+#include "msm_mercury_sync.h"
+#include "msm_mercury_common.h"
+#include "msm.h"
+
+#define MSM_MERCURY_NAME "mercury"
+
+static int msm_mercury_open(struct inode *inode, struct file *filp)
+{
+	int rc;
+
+	struct msm_mercury_device *pmercury_dev = container_of(inode->i_cdev,
+		struct msm_mercury_device, cdev);
+	filp->private_data = pmercury_dev;
+
+	MCR_DBG("\n---(%d)%s()\n", __LINE__, __func__);
+
+	rc = __msm_mercury_open(pmercury_dev);
+
+	MCR_DBG("%s:%d] %s open_count = %d\n", __func__, __LINE__,
+		filp->f_path.dentry->d_name.name, pmercury_dev->open_count);
+
+	return rc;
+}
+
+static int msm_mercury_release(struct inode *inode, struct file *filp)
+{
+	int rc;
+
+	struct msm_mercury_device *pmercury_dev = filp->private_data;
+
+	MCR_DBG("\n---(%d)%s()\n", __LINE__, __func__);
+
+	rc = __msm_mercury_release(pmercury_dev);
+
+	MCR_DBG("%s:%d] %s open_count = %d\n", __func__, __LINE__,
+		filp->f_path.dentry->d_name.name, pmercury_dev->open_count);
+	return rc;
+}
+
+static long msm_mercury_ioctl(struct file *filp, unsigned int cmd,
+	unsigned long arg) {
+	int rc;
+	struct msm_mercury_device *pmercury_dev = filp->private_data;
+	rc = __msm_mercury_ioctl(pmercury_dev, cmd, arg);
+	return rc;
+}
+
+static const struct file_operations msm_mercury_fops = {
+	.owner     = THIS_MODULE,
+	.open    = msm_mercury_open,
+	.release = msm_mercury_release,
+	.unlocked_ioctl = msm_mercury_ioctl,
+};
+
+static struct class *msm_mercury_class;
+static dev_t msm_mercury_devno;
+static struct msm_mercury_device *msm_mercury_device_p;
+
+int msm_mercury_subdev_init(struct v4l2_subdev *mercury_sd)
+{
+	int rc;
+	struct msm_mercury_device *pgmn_dev =
+		(struct msm_mercury_device *)mercury_sd->host_priv;
+
+	MCR_DBG("%s:%d: mercury_sd=0x%x pgmn_dev=0x%x\n",
+		__func__, __LINE__, (uint32_t)mercury_sd, (uint32_t)pgmn_dev);
+	rc = __msm_mercury_open(pgmn_dev);
+	MCR_DBG("%s:%d: rc=%d\n",
+		__func__, __LINE__, rc);
+	return rc;
+}
+
+static long msm_mercury_subdev_ioctl(struct v4l2_subdev *sd,
+	unsigned int cmd, void *arg)
+{
+	long rc;
+	struct msm_mercury_device *pgmn_dev =
+		(struct msm_mercury_device *)sd->host_priv;
+
+	MCR_DBG("%s: cmd=%d\n", __func__, cmd);
+
+	MCR_DBG("%s: pgmn_dev 0x%x", __func__, (uint32_t)pgmn_dev);
+
+	MCR_DBG("%s: Calling __msm_mercury_ioctl\n", __func__);
+
+	rc = __msm_mercury_ioctl(pgmn_dev, cmd, (unsigned long)arg);
+	pr_debug("%s: X\n", __func__);
+	return rc;
+}
+
+void msm_mercury_subdev_release(struct v4l2_subdev *mercury_sd)
+{
+	int rc;
+	struct msm_mercury_device *pgmn_dev =
+		(struct msm_mercury_device *)mercury_sd->host_priv;
+	MCR_DBG("%s:pgmn_dev=0x%x", __func__, (uint32_t)pgmn_dev);
+	rc = __msm_mercury_release(pgmn_dev);
+	MCR_DBG("%s:rc=%d", __func__, rc);
+}
+
+static const struct v4l2_subdev_core_ops msm_mercury_subdev_core_ops = {
+	.ioctl = msm_mercury_subdev_ioctl,
+};
+
+static const struct v4l2_subdev_ops msm_mercury_subdev_ops = {
+	.core = &msm_mercury_subdev_core_ops,
+};
+
+static int msm_mercury_init(struct platform_device *pdev)
+{
+	int rc = -1;
+	struct device *dev;
+
+	MCR_DBG("%s:\n", __func__);
+	msm_mercury_device_p = __msm_mercury_init(pdev);
+	if (msm_mercury_device_p == NULL) {
+		MCR_PR_ERR("%s: initialization failed\n", __func__);
+		goto fail;
+	}
+
+	v4l2_subdev_init(&msm_mercury_device_p->subdev,
+		&msm_mercury_subdev_ops);
+	v4l2_set_subdev_hostdata(&msm_mercury_device_p->subdev,
+		msm_mercury_device_p);
+	pr_debug("%s: msm_mercury_device_p 0x%x", __func__,
+		(uint32_t)msm_mercury_device_p);
+	MCR_DBG("%s:mercury: platform_set_drvdata\n", __func__);
+	platform_set_drvdata(pdev, &msm_mercury_device_p->subdev);
+
+	rc = alloc_chrdev_region(&msm_mercury_devno, 0, 1, MSM_MERCURY_NAME);
+	if (rc < 0) {
+		MCR_PR_ERR("%s: failed to allocate chrdev\n", __func__);
+		goto fail_1;
+	}
+
+	if (!msm_mercury_class) {
+		msm_mercury_class = class_create(THIS_MODULE, MSM_MERCURY_NAME);
+		if (IS_ERR(msm_mercury_class)) {
+			rc = PTR_ERR(msm_mercury_class);
+			MCR_PR_ERR("%s: create device class failed\n",
+				__func__);
+			goto fail_2;
+		}
+	}
+
+	dev = device_create(msm_mercury_class, NULL,
+		MKDEV(MAJOR(msm_mercury_devno), MINOR(msm_mercury_devno)), NULL,
+		"%s%d", MSM_MERCURY_NAME, 0);
+
+	if (IS_ERR(dev)) {
+		MCR_PR_ERR("%s: error creating device\n", __func__);
+		rc = -ENODEV;
+		goto fail_3;
+	}
+
+	cdev_init(&msm_mercury_device_p->cdev, &msm_mercury_fops);
+	msm_mercury_device_p->cdev.owner = THIS_MODULE;
+	msm_mercury_device_p->cdev.ops   =
+		(const struct file_operations *) &msm_mercury_fops;
+	rc = cdev_add(&msm_mercury_device_p->cdev, msm_mercury_devno, 1);
+	if (rc < 0) {
+		MCR_PR_ERR("%s: error adding cdev\n", __func__);
+		rc = -ENODEV;
+		goto fail_4;
+	}
+
+	MCR_DBG("%s %s: success\n", __func__, MSM_MERCURY_NAME);
+
+	return rc;
+
+fail_4:
+	device_destroy(msm_mercury_class, msm_mercury_devno);
+
+fail_3:
+	class_destroy(msm_mercury_class);
+
+fail_2:
+	unregister_chrdev_region(msm_mercury_devno, 1);
+
+fail_1:
+	__msm_mercury_exit(msm_mercury_device_p);
+
+fail:
+	return rc;
+}
+
+static void msm_mercury_exit(void)
+{
+	cdev_del(&msm_mercury_device_p->cdev);
+	device_destroy(msm_mercury_class, msm_mercury_devno);
+	class_destroy(msm_mercury_class);
+	unregister_chrdev_region(msm_mercury_devno, 1);
+
+	__msm_mercury_exit(msm_mercury_device_p);
+}
+
+static int __msm_mercury_probe(struct platform_device *pdev)
+{
+	return msm_mercury_init(pdev);
+}
+
+static int __msm_mercury_remove(struct platform_device *pdev)
+{
+	msm_mercury_exit();
+	return 0;
+}
+
+static struct platform_driver msm_mercury_driver = {
+	.probe  = __msm_mercury_probe,
+	.remove = __msm_mercury_remove,
+	.driver = {
+		.name = MSM_MERCURY_DRV_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init msm_mercury_driver_init(void)
+{
+	int rc;
+	rc = platform_driver_register(&msm_mercury_driver);
+	return rc;
+}
+
+static void __exit msm_mercury_driver_exit(void)
+{
+	platform_driver_unregister(&msm_mercury_driver);
+}
+
+MODULE_DESCRIPTION("msm mercury jpeg driver");
+
+module_init(msm_mercury_driver_init);
+module_exit(msm_mercury_driver_exit);
diff --git a/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_hw.c b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_hw.c
new file mode 100644
index 0000000..244c038
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_hw.c
@@ -0,0 +1,361 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include "msm_mercury_hw.h"
+#include "msm_mercury_common.h"
+#include "msm_mercury_hw_reg.h"
+#include "msm_mercury_macros.h"
+
+static void *mercury_region_base;
+static uint32_t mercury_region_size;
+
+
+void msm_mercury_hw_write(struct msm_mercury_hw_cmd *hw_cmd_p)
+{
+	uint32_t *paddr;
+	uint32_t old_data, new_data;
+
+	paddr = mercury_region_base + hw_cmd_p->offset;
+
+	if (hw_cmd_p->mask == 0xffffffff) {
+		old_data = 0;
+	} else {
+		old_data = readl_relaxed(paddr);
+		old_data &= ~hw_cmd_p->mask;
+	}
+
+	new_data = hw_cmd_p->data & hw_cmd_p->mask;
+	new_data |= old_data;
+	writel_relaxed(new_data, paddr);
+}
+
+uint32_t msm_mercury_hw_read(struct msm_mercury_hw_cmd *hw_cmd_p)
+{
+	uint32_t *paddr;
+	uint32_t data;
+
+	paddr = mercury_region_base + hw_cmd_p->offset;
+
+	data = readl_relaxed(paddr);
+	data &= hw_cmd_p->mask;
+
+	MCR_DBG("MERCURY_READ: offset=0x%04X data=0x%08X\n",
+		hw_cmd_p->offset, data);
+
+	return data;
+}
+
+void msm_mercury_hw_start_decode(void)
+{
+	struct msm_mercury_hw_cmd hw_cmd;
+
+	mercury_kread(JPEG_STATUS);
+	mercury_kread(RTDMA_JPEG_RD_STA_ACK);
+	mercury_kread(RTDMA_JPEG_WR_STA_ACK);
+	mercury_kread(RTDMA_JPEG_RD_BUF_Y_PNTR);
+	mercury_kread(RTDMA_JPEG_WR_BUF_Y_PNTR);
+	mercury_kread(RTDMA_JPEG_WR_BUF_U_PNTR);
+	mercury_kwrite(RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO, (7<<2));
+	return;
+}
+
+void msm_mercury_hw_bitstream_buf_cfg(uint32_t bitstream_buf_addr)
+{
+	struct msm_mercury_hw_cmd hw_cmd;
+
+	mercury_kwrite(RTDMA_JPEG_RD_BUF_Y_PNTR, bitstream_buf_addr);
+	return;
+}
+
+
+void msm_mercury_hw_output_y_buf_cfg(uint32_t y_buf_addr)
+{
+	struct msm_mercury_hw_cmd hw_cmd;
+
+	mercury_kwrite(RTDMA_JPEG_WR_BUF_Y_PNTR, y_buf_addr);
+	return;
+}
+
+void msm_mercury_hw_output_u_buf_cfg(uint32_t u_buf_addr)
+{
+	struct msm_mercury_hw_cmd hw_cmd;
+
+	mercury_kwrite(RTDMA_JPEG_WR_BUF_U_PNTR, u_buf_addr);
+	return;
+}
+
+void msm_mercury_hw_output_v_buf_cfg(uint32_t v_buf_addr)
+{
+	struct msm_mercury_hw_cmd hw_cmd;
+
+	mercury_kwrite(RTDMA_JPEG_WR_BUF_V_PNTR, v_buf_addr);
+	return;
+}
+
+int msm_mercury_hw_wait(struct msm_mercury_hw_cmd *hw_cmd_p, int m_us)
+{
+	int tm = hw_cmd_p->n;
+	uint32_t data;
+	uint32_t wait_data = hw_cmd_p->data & hw_cmd_p->mask;
+
+	data = msm_mercury_hw_read(hw_cmd_p);
+	if (data != wait_data) {
+		while (tm) {
+			udelay(m_us);
+			data = msm_mercury_hw_read(hw_cmd_p);
+			if (data == wait_data)
+				break;
+			tm--;
+		}
+	}
+	hw_cmd_p->data = data;
+	return tm;
+}
+
+void msm_mercury_hw_irq_get_status(uint16_t *rd_irq, uint16_t *wr_irq)
+{
+	struct msm_mercury_hw_cmd hw_cmd;
+	rmb();
+	mercury_kread(RTDMA_JPEG_RD_STA_ACK);
+	*rd_irq = hw_cmd.data;
+
+	mercury_kread(RTDMA_JPEG_WR_STA_ACK);
+	*wr_irq = hw_cmd.data;
+	rmb();
+}
+
+void msm_mercury_hw_get_jpeg_status(uint32_t *jpeg_status)
+{
+	struct msm_mercury_hw_cmd hw_cmd;
+
+	rmb();
+	mercury_kread(JPEG_STATUS);
+	*jpeg_status = hw_cmd.data;
+	rmb();
+}
+
+uint32_t msm_mercury_get_restartInterval(void)
+{
+	struct msm_mercury_hw_cmd hw_cmd;
+
+	rmb();
+	mercury_kread(JPEG_DRI);
+	rmb();
+	return hw_cmd.data;
+
+}
+
+void msm_mercury_hw_rd_irq_clear(uint32_t val)
+{
+	struct msm_mercury_hw_cmd hw_cmd;
+	mercury_kwrite(RTDMA_JPEG_RD_STA_ACK, val);
+}
+
+void msm_mercury_hw_wr_irq_clear(uint32_t val)
+{
+	struct msm_mercury_hw_cmd hw_cmd;
+
+	mercury_kwrite(RTDMA_JPEG_WR_STA_ACK, val);
+}
+
+void msm_mercury_hw_set_rd_irq_mask(uint32_t val)
+{
+	struct msm_mercury_hw_cmd hw_cmd;
+
+	mercury_kwrite(RTDMA_JPEG_RD_INT_EN, val);
+}
+
+void msm_mercury_hw_set_wr_irq_mask(uint32_t val)
+{
+	struct msm_mercury_hw_cmd hw_cmd;
+
+	mercury_kwrite(RTDMA_JPEG_WR_INT_EN, val);
+}
+
+void msm_mercury_set_jpeg_ctl_common(uint32_t val)
+{
+	struct msm_mercury_hw_cmd hw_cmd;
+
+	mercury_kwrite(JPEG_CTRL_COMMON, val);
+}
+
+void msm_mercury_hw_reset(void)
+{
+	uint32_t val;
+	struct msm_mercury_hw_cmd hw_cmd;
+
+	wmb();
+	/* disable all interrupts*/
+	mercury_kwrite(RTDMA_JPEG_RD_INT_EN, 0);
+
+	mercury_kwrite(RTDMA_JPEG_WR_INT_EN, 0);
+
+	/* clear pending interrupts*/
+	val = 0;
+	MEM_OUTF2(&val, RTDMA_JPEG_WR_STA_ACK,
+		SW_RESET_ABORT_RDY_ACK,
+		ERR_ACK, 1, 1);
+	MEM_OUTF2(&val, RTDMA_JPEG_WR_STA_ACK, EOF_ACK, SOF_ACK, 1, 1);
+	mercury_kwrite(RTDMA_JPEG_WR_STA_ACK, val);
+
+	val = 0;
+	MEM_OUTF2(&val, RTDMA_JPEG_RD_STA_ACK, EOF_ACK, SOF_ACK, 1, 1);
+	mercury_kwrite(RTDMA_JPEG_RD_STA_ACK, val);
+
+	/* enable SWResetAbortRdyInt for core reset*/
+	val = 0;
+	MEM_OUTF(&val, RTDMA_JPEG_WR_INT_EN, SW_RESET_ABORT_RDY_EN, 1);
+	mercury_kwrite(RTDMA_JPEG_WR_INT_EN, val);
+
+	/* Reset Core from MMSS Fabric*/
+	mercury_core_reset();
+
+	/* disable all interrupts*/
+	mercury_kwrite(RTDMA_JPEG_WR_INT_EN, 0);
+
+	/* clear pending interrupts*/
+	val = 0;
+	MEM_OUTF2(&val, RTDMA_JPEG_WR_STA_ACK,
+		SW_RESET_ABORT_RDY_ACK,
+		ERR_ACK, 1, 1);
+	MEM_OUTF2(&val, RTDMA_JPEG_WR_STA_ACK, EOF_ACK, SOF_ACK, 1, 1);
+	mercury_kwrite(RTDMA_JPEG_WR_STA_ACK, val);
+
+	val = 0;
+	MEM_OUTF2(&val, RTDMA_JPEG_RD_STA_ACK, EOF_ACK, SOF_ACK, 1, 1);
+	mercury_kwrite(RTDMA_JPEG_RD_STA_ACK, val);
+
+	/* enable neccessary interrupt source*/
+	val = 0;
+	MEM_OUTF2(&val, RTDMA_JPEG_WR_INT_EN, EOF_EN, ERR_EN, 1, 1);
+	MEM_OUTF(&val, RTDMA_JPEG_WR_INT_EN, SW_RESET_ABORT_RDY_EN, 1);
+	mercury_kwrite(RTDMA_JPEG_WR_INT_EN, val);
+
+	wmb();
+
+}
+
+void msm_mercury_hw_init(void *base, int size)
+{
+	mercury_region_base = base;
+	mercury_region_size = size;
+}
+
+
+void msm_mercury_hw_delay(struct msm_mercury_hw_cmd *hw_cmd_p, int m_us)
+{
+	int tm = hw_cmd_p->n;
+	while (tm) {
+		udelay(m_us);
+		tm--;
+	}
+}
+
+int msm_mercury_hw_exec_cmds(struct msm_mercury_hw_cmd *hw_cmd_p, int m_cmds)
+{
+	int is_copy_to_user = -1;
+	uint32_t data;
+	if (m_cmds > 1)
+		MCR_DBG("m_cmds = %d\n", m_cmds);
+
+	while (m_cmds--) {
+		if (hw_cmd_p->offset > mercury_region_size) {
+			MCR_PR_ERR("%s:%d] %d exceed hw region %d\n",
+					__func__, __LINE__, hw_cmd_p->offset,
+					mercury_region_size);
+			return -EFAULT;
+		}
+
+		switch (hw_cmd_p->type) {
+		case MSM_MERCURY_HW_CMD_TYPE_READ:
+			hw_cmd_p->data = msm_mercury_hw_read(hw_cmd_p);
+			is_copy_to_user = 1;
+			break;
+
+		case MSM_MERCURY_HW_CMD_TYPE_WRITE:
+			msm_mercury_hw_write(hw_cmd_p);
+			break;
+
+		case MSM_MERCURY_HW_CMD_TYPE_WRITE_OR:
+			data = msm_mercury_hw_read(hw_cmd_p);
+			hw_cmd_p->data = (hw_cmd_p->data & hw_cmd_p->mask) |
+				data;
+			msm_mercury_hw_write(hw_cmd_p);
+			break;
+
+		case MSM_MERCURY_HW_CMD_TYPE_UWAIT:
+			msm_mercury_hw_wait(hw_cmd_p, 1);
+			break;
+
+		case MSM_MERCURY_HW_CMD_TYPE_MWAIT:
+			msm_mercury_hw_wait(hw_cmd_p, 1000);
+			break;
+
+		case MSM_MERCURY_HW_CMD_TYPE_UDELAY:
+			msm_mercury_hw_delay(hw_cmd_p, 1);
+			break;
+
+		case MSM_MERCURY_HW_CMD_TYPE_MDELAY:
+			msm_mercury_hw_delay(hw_cmd_p, 1000);
+			break;
+
+		default:
+			MCR_DBG("wrong hw command type\n");
+			break;
+		}
+
+		hw_cmd_p++;
+	}
+	return is_copy_to_user;
+}
+
+void msm_mercury_hw_region_dump(int size)
+{
+	uint32_t *p;
+	uint8_t *p8;
+
+	MCR_DBG("(%d)%s()\n", __LINE__, __func__);
+	if (size > mercury_region_size)
+		MCR_DBG("%s:%d] wrong region dump size\n",
+			__func__, __LINE__);
+
+	p = (uint32_t *) mercury_region_base;
+	while (size >= 16) {
+		MCR_DBG("0x%08X] %08X %08X %08X %08X\n",
+			mercury_region_size - size,
+			readl_relaxed(p), readl_relaxed(p+1),
+			readl_relaxed(p+2), readl_relaxed(p+3));
+		p += 4;
+		size -= 16;
+	}
+
+	if (size > 0) {
+		uint32_t d;
+		MCR_DBG("0x%08X] ", mercury_region_size - size);
+		while (size >= 4) {
+			MCR_DBG("%08X ", readl_relaxed(p++));
+			size -= 4;
+		}
+
+		d = readl_relaxed(p);
+		p8 = (uint8_t *) &d;
+		while (size) {
+			MCR_DBG("%02X", *p8++);
+			size--;
+		}
+
+		MCR_DBG("\n");
+	}
+}
diff --git a/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_hw.h b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_hw.h
new file mode 100644
index 0000000..54fc818
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_hw.h
@@ -0,0 +1,70 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_MERCURY_HW_H
+#define MSM_MERCURY_HW_H
+
+#include <media/msm_mercury.h>
+
+/*number of pel per block (horiz/vert)*/
+#define JPEGDEC_BLOCK_SIZE                 (8)
+/* Hardware alignment*/
+#define JPEGDEC_HW_ALIGN                   (8)
+#define JPEGDEC_HW_SAMPLING_RATIO_MAX      (4)
+
+#define MSM_MERCURY_HW_IRQ_SW_RESET_ACK    (1<<3)
+#define MSM_MERCURY_HW_IRQ_WR_ERR_ACK      (1<<2)
+#define MSM_MERCURY_HW_IRQ_WR_EOI_ACK      (1<<1)
+#define MSM_MERCURY_HW_IRQ_WR_SOF_ACK      (1<<0)
+
+#define MSM_MERCURY_HW_IRQ_RD_EOF_ACK      (1<<1)
+#define MSM_MERCURY_HW_IRQ_RD_SOF_ACK      (1<<0)
+
+extern int mercury_core_reset(void);
+
+struct msm_mercury_hw_buf {
+		struct msm_mercury_buf vbuf;
+		struct file  *file;
+		uint32_t framedone_len;
+		uint32_t y_buffer_addr;
+		uint32_t y_len;
+		uint32_t cbcr_buffer_addr;
+		uint32_t cbcr_len;
+		uint32_t num_of_mcu_rows;
+		struct msm_mapped_buffer *msm_buffer;
+		int *subsystem_id;
+		struct ion_handle *handle;
+};
+
+
+void msm_mercury_hw_reset(void);
+void msm_mercury_hw_init(void *base, int size);
+void msm_mercury_hw_rd_irq_clear(uint32_t val);
+void msm_mercury_hw_wr_irq_clear(uint32_t val);
+
+uint32_t msm_mercury_hw_read(struct msm_mercury_hw_cmd *hw_cmd_p);
+void msm_mercury_hw_write(struct msm_mercury_hw_cmd *hw_cmd_p);
+int msm_mercury_hw_wait(struct msm_mercury_hw_cmd *hw_cmd_p, int m_us);
+void msm_mercury_hw_delay(struct msm_mercury_hw_cmd *hw_cmd_p, int m_us);
+int msm_mercury_hw_exec_cmds(struct msm_mercury_hw_cmd *hw_cmd_p, int m_cmds);
+void msm_mercury_hw_region_dump(int size);
+
+
+void msm_mercury_hw_irq_get_status(uint16_t *rd_irq, uint16_t *wr_irq);
+void msm_mercury_hw_start_decode(void);
+void msm_mercury_hw_get_jpeg_status(uint32_t *jpeg_status);
+void msm_mercury_hw_output_y_buf_cfg(uint32_t y_buf_addr);
+void msm_mercury_hw_output_u_buf_cfg(uint32_t u_buf_addr);
+void msm_mercury_hw_output_v_buf_cfg(uint32_t v_buf_addr);
+void msm_mercury_hw_bitstream_buf_cfg(uint32_t bitstream_buf_addr);
+
+#endif /* MSM_MERCURY_HW_H */
diff --git a/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_hw_reg.h b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_hw_reg.h
new file mode 100644
index 0000000..015bf49
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_hw_reg.h
@@ -0,0 +1,715 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_MERCURY_HW_REG_H
+#define MSM_MERCURY_HW_REG_H
+
+
+#define JPEGD_BASE  0x00000000
+
+/* Register ADDR, RMSK, and SHFT*/
+/* RW */
+#define JPEG_CTRL_COMMON                        JPEG_CTRL_COMMON
+#define HWIO_JPEG_CTRL_COMMON_ADDR            (JPEGD_BASE+0x00000000)
+#define HWIO_JPEG_CTRL_COMMON__POR                    0x00000000
+#define HWIO_JPEG_CTRL_COMMON__RMSK                   0x0000001F
+#define HWIO_JPEG_CTRL_COMMON__SHFT                            0
+/* Register Field FMSK and SHFT*/
+#define HWIO_JPEG_CTRL_COMMON__JPEG_CTRL_COMMON_ZZ_OVERRIDE_EN__BMSK 0x00000010
+#define HWIO_JPEG_CTRL_COMMON__JPEG_CTRL_COMMON_ZZ_OVERRIDE_EN__SHFT          4
+#define HWIO_JPEG_CTRL_COMMON__JPEG_CTRL_COMMON_MODE__BMSK           0x0000000F
+#define HWIO_JPEG_CTRL_COMMON__JPEG_CTRL_COMMON_MODE__SHFT                    0
+
+/* Register Field FMSK and SHFT*/
+/* RW */
+#define JPEG_CTRL_ENCODE                     JPEG_CTRL_ENCODE
+#define HWIO_JPEG_CTRL_ENCODE_ADDR        (JPEGD_BASE+0x00000008)
+#define HWIO_JPEG_CTRL_ENCODE__POR                 0x00000000
+#define HWIO_JPEG_CTRL_ENCODE__RMSK                0x00000010
+#define HWIO_JPEG_CTRL_ENCODE__SHFT                         4
+/* Register Element MIN and MAX*/
+#define HWIO_JPEG_CTRL_ENCODE___S                           4
+
+/* Register Field FMSK and SHFT*/
+#define HWIO_JPEG_CTRL_ENCODE__JPEG_CTRL_ENCODE_EOI_MARKER_EN__BMSK  0x00000010
+#define HWIO_JPEG_CTRL_ENCODE__JPEG_CTRL_ENCODE_EOI_MARKER_EN__SHFT           4
+
+/* Register Field FMSK and SHFT*/
+#define JPEG_STATUS                        JPEG_STATUS
+#define HWIO_JPEG_STATUS_ADDR        (JPEGD_BASE+0x00000010)
+#define HWIO_JPEG_STATUS__POR               0x00000000
+#define HWIO_JPEG_STATUS__RMSK              0x00003FF0
+#define HWIO_JPEG_STATUS__SHFT                       4
+/* Register Element MIN and MAX*/
+#define HWIO_JPEG_STATUS___S                         4
+
+/* Register Field FMSK and SHFT*/
+#define HWIO_JPEG_STATUS__JPEG_STATUS_REGISTER_TIMEOUT__BMSK       0x00002000
+#define HWIO_JPEG_STATUS__JPEG_STATUS_REGISTER_TIMEOUT__SHFT               13
+#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_EOI__BMSK               0x00001000
+#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_EOI__SHFT                       12
+#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_UNESCAPED_FF__BMSK  0x00000800
+#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_UNESCAPED_FF__SHFT          11
+#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_INV_HUFFCODE__BMSK  0x00000400
+#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_INV_HUFFCODE__SHFT          10
+#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_INV_MARKER__BMSK    0x00000200
+#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_INV_MARKER__SHFT             9
+#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_RSTRT_SEQ__BMSK     0x00000100
+#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_RSTRT_SEQ__SHFT              8
+#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_RSTRT_OVRFLW__BMSK  0x00000080
+#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_RSTRT_OVRFLW__SHFT           7
+#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_RSTRT_UNDFLW__BMSK  0x00000040
+#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_RSTRT_UNDFLW__SHFT           6
+#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_SCAN_OVRFLW__BMSK   0x00000020
+#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_SCAN_OVRFLW__SHFT            5
+#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_SCAN_UNDFLW__BMSK   0x00000010
+#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_SCAN_UNDFLW__SHFT            4
+
+/* Register ADDR, RMSK, and SHFT*/
+/* R */
+#define JPEG_SOF_REG_0                               JPEG_SOF_REG_0
+#define HWIO_JPEG_SOF_REG_0_ADDR  /* RW */               (JPEGD_BASE+0x00000014)
+#define HWIO_JPEG_SOF_REG_0__POR                         0x00000000
+#define HWIO_JPEG_SOF_REG_0__RMSK                        0x000000FF
+#define HWIO_JPEG_SOF_REG_0__SHFT                                 0
+/* Register Field FMSK and SHFT*/
+#define HWIO_JPEG_SOF_REG_0__JPEG_SOF_REG_0_NF__BMSK     0x000000FF
+#define HWIO_JPEG_SOF_REG_0__JPEG_SOF_REG_0_NF__SHFT              0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define JPEG_SOF_REG_1                               JPEG_SOF_REG_1
+#define HWIO_JPEG_SOF_REG_1_ADDR  /* RW */               (JPEGD_BASE+0x00000018)
+#define HWIO_JPEG_SOF_REG_1__POR                         0x00000000
+#define HWIO_JPEG_SOF_REG_1__RMSK                        0x00FFFFFF
+#define HWIO_JPEG_SOF_REG_1__SHFT                                 0
+/* Register Field FMSK and SHFT*/
+#define HWIO_JPEG_SOF_REG_1__JPEG_SOF_REG_1_C__BMSK      0x00FF0000
+#define HWIO_JPEG_SOF_REG_1__JPEG_SOF_REG_1_C__SHFT              16
+#define HWIO_JPEG_SOF_REG_1__JPEG_SOF_REG_1_H__BMSK      0x0000F000
+#define HWIO_JPEG_SOF_REG_1__JPEG_SOF_REG_1_H__SHFT              12
+#define HWIO_JPEG_SOF_REG_1__JPEG_SOF_REG_1_V__BMSK      0x00000F00
+#define HWIO_JPEG_SOF_REG_1__JPEG_SOF_REG_1_V__SHFT               8
+#define HWIO_JPEG_SOF_REG_1__JPEG_SOF_REG_1_TQ__BMSK     0x000000FF
+#define HWIO_JPEG_SOF_REG_1__JPEG_SOF_REG_1_TQ__SHFT              0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define JPEG_SOF_REG_2                               JPEG_SOF_REG_2
+#define HWIO_JPEG_SOF_REG_2_ADDR  /* RW */               (JPEGD_BASE+0x0000001C)
+#define HWIO_JPEG_SOF_REG_2__POR                         0x00000000
+#define HWIO_JPEG_SOF_REG_2__RMSK                        0xFFFFFFFF
+#define HWIO_JPEG_SOF_REG_2__SHFT                                 0
+/* Register Field FMSK and SHFT*/
+#define HWIO_JPEG_SOF_REG_2__JPEG_SOF_REG_2_Y__BMSK      0xFFFF0000
+#define HWIO_JPEG_SOF_REG_2__JPEG_SOF_REG_2_Y__SHFT              16
+#define HWIO_JPEG_SOF_REG_2__JPEG_SOF_REG_2_X__BMSK      0x0000FFFF
+#define HWIO_JPEG_SOF_REG_2__JPEG_SOF_REG_2_X__SHFT               0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define JPEG_SOS_REG_0                               JPEG_SOS_REG_0
+#define HWIO_JPEG_SOS_REG_0_ADDR  /* RW */               (JPEGD_BASE+0x00000020)
+#define HWIO_JPEG_SOS_REG_0__POR                         0x00000000
+#define HWIO_JPEG_SOS_REG_0__RMSK                        0xFF000000
+#define HWIO_JPEG_SOS_REG_0__SHFT                                24
+/*Register Element MIN and MAX*/
+#define HWIO_JPEG_SOS_REG_0___S                                  24
+#define HWIO_JPEG_SOS_REG_0___S                                  24
+#define HWIO_JPEG_SOS_REG_0___S                                  24
+#define HWIO_JPEG_SOS_REG_0___S                                  24
+/* Register Field FMSK and SHFT*/
+#define HWIO_JPEG_SOS_REG_0__JPEG_SOS_REG_0_NS__BMSK       0xFF000000
+#define HWIO_JPEG_SOS_REG_0__JPEG_SOS_REG_0_NS__SHFT               24
+
+/* Register ADDR, RMSK, and SHFT*/
+#define JPEG_SOS_REG_1                                   JPEG_SOS_REG_1
+#define HWIO_JPEG_SOS_REG_1_ADDR  /* RW */              (JPEGD_BASE+0x00000024)
+#define HWIO_JPEG_SOS_REG_1__POR                        0x00000000
+#define HWIO_JPEG_SOS_REG_1__RMSK                       0x0000FFFF
+#define HWIO_JPEG_SOS_REG_1__SHFT                                0
+/* Register Field FMSK and SHFT*/
+#define HWIO_JPEG_SOS_REG_1__JPEG_SOS_REG_1_CS__BMSK    0x0000FF00
+#define HWIO_JPEG_SOS_REG_1__JPEG_SOS_REG_1_CS__SHFT             8
+#define HWIO_JPEG_SOS_REG_1__JPEG_SOS_REG_1_TD__BMSK    0x000000F0
+#define HWIO_JPEG_SOS_REG_1__JPEG_SOS_REG_1_TD__SHFT             4
+#define HWIO_JPEG_SOS_REG_1__JPEG_SOS_REG_1_TA__BMSK    0x0000000F
+#define HWIO_JPEG_SOS_REG_1__JPEG_SOS_REG_1_TA__SHFT             0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define JPEG_QT_IDX                                       JPEG_QT_IDX
+#define HWIO_JPEG_QT_IDX_ADDR       (JPEGD_BASE+0x00000030)
+#define HWIO_JPEG_QT_IDX__POR                              0x00000000
+#define HWIO_JPEG_QT_IDX__RMSK                             0x0000FFFF
+#define HWIO_JPEG_QT_IDX__SHFT                                      0
+/* Register Field FMSK and SHFT*/
+#define HWIO_JPEG_QT_IDX__JPEG_QT_IDX_TABLE_1__BMSK        0x0000FF00
+#define HWIO_JPEG_QT_IDX__JPEG_QT_IDX_TABLE_1__SHFT                  8
+#define HWIO_JPEG_QT_IDX__JPEG_QT_IDX_TABLE_0__BMSK         0x000000FF
+#define HWIO_JPEG_QT_IDX__JPEG_QT_IDX_TABLE_0__SHFT                  0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define JPEG_DQT                                        JPEG_DQT
+#define HWIO_JPEG_DQT_ADDR  /* RW */                    (JPEGD_BASE+0x00000034)
+#define HWIO_JPEG_DQT__POR                              0x00000000
+#define HWIO_JPEG_DQT__RMSK                             0x0F00FFFF
+#define HWIO_JPEG_DQT__SHFT                             0
+/* Register Field FMSK and SHFT*/
+#define HWIO_JPEG_DQT__JPEG_DQT_TQ__BMSK                0x0F000000
+#define HWIO_JPEG_DQT__JPEG_DQT_TQ__SHFT                24
+#define HWIO_JPEG_DQT__JPEG_DQT_QK__BMSK                0x0000FFFF
+#define HWIO_JPEG_DQT__JPEG_DQT_QK__SHFT                0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define JPEG_DRI                                JPEG_DRI
+#define HWIO_JPEG_DRI_ADDR  /* RW */            (JPEGD_BASE+0x00000040)
+#define HWIO_JPEG_DRI__POR                      0x00000000
+#define HWIO_JPEG_DRI__RMSK                     0x0000FFFF
+#define HWIO_JPEG_DRI__SHFT                              0
+/* Register Field FMSK and SHFT*/
+#define HWIO_JPEG_DRI__JPEG_DRI_RI__BMSK        0x0000FFFF
+#define HWIO_JPEG_DRI__JPEG_DRI_RI__SHFT                 0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define JPEG_DHT_REG_0                               JPEG_DHT_REG_0
+#define HWIO_JPEG_DHT_REG_0_ADDR  /* RW */               (JPEGD_BASE+0x00000050)
+#define HWIO_JPEG_DHT_REG_0__POR                         0x00000000
+#define HWIO_JPEG_DHT_REG_0__RMSK                        0x000000FF
+#define HWIO_JPEG_DHT_REG_0__SHFT                                 0
+/* Register Field FMSK and SHFT*/
+#define HWIO_JPEG_DHT_REG_0__JPEG_DHT_REG_0_TH__BMSK     0x000000F0
+#define HWIO_JPEG_DHT_REG_0__JPEG_DHT_REG_0_TH__SHFT              4
+#define HWIO_JPEG_DHT_REG_0__JPEG_DHT_REG_0_TC__BMSK     0x0000000F
+#define HWIO_JPEG_DHT_REG_0__JPEG_DHT_REG_0_TC__SHFT              0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define JPEG_DHT_IDX                                        JPEG_DHT_IDX
+#define HWIO_JPEG_DHT_IDX_ADDR  /* RW */      (JPEGD_BASE+0x00000054)
+#define HWIO_JPEG_DHT_IDX__POR                                0x00000000
+#define HWIO_JPEG_DHT_IDX__RMSK                               0x00000FFF
+#define HWIO_JPEG_DHT_IDX__SHFT                                        0
+/* Register Field FMSK and SHFT*/
+#define HWIO_JPEG_DHT_IDX__JPEG_DHT_IDX_CCC_MAX__BMSK         0x00000F00
+#define HWIO_JPEG_DHT_IDX__JPEG_DHT_IDX_CCC_MAX__SHFT                  8
+#define HWIO_JPEG_DHT_IDX__JPEG_DHT_IDX_VIJ__BMSK             0x000000FF
+#define HWIO_JPEG_DHT_IDX__JPEG_DHT_IDX_VIJ__SHFT                      0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define JPEG_DHT_REG_1                          JPEG_DHT_REG_1
+#define HWIO_JPEG_DHT_REG_1_ADDR  /* RW */          (JPEGD_BASE+0x00000058)
+#define HWIO_JPEG_DHT_REG_1__POR                    0x00000000
+#define HWIO_JPEG_DHT_REG_1__RMSK                   0xFFFFFFFF
+#define HWIO_JPEG_DHT_REG_1__SHFT                            0
+/* Register Field FMSK and SHFT*/
+#define HWIO_JPEG_DHT_REG_1__JPEG_DHT_REG_1_VIJ_0__BMSK       0xFF000000
+#define HWIO_JPEG_DHT_REG_1__JPEG_DHT_REG_1_VIJ_0__SHFT               24
+#define HWIO_JPEG_DHT_REG_1__JPEG_DHT_REG_1_VIJ_1__BMSK       0x00FF0000
+#define HWIO_JPEG_DHT_REG_1__JPEG_DHT_REG_1_VIJ_1__SHFT               16
+#define HWIO_JPEG_DHT_REG_1__JPEG_DHT_REG_1_VIJ_2__BMSK       0x0000FF00
+#define HWIO_JPEG_DHT_REG_1__JPEG_DHT_REG_1_VIJ_2__SHFT                8
+#define HWIO_JPEG_DHT_REG_1__JPEG_DHT_REG_1_VIJ_3__BMSK       0x000000FF
+#define HWIO_JPEG_DHT_REG_1__JPEG_DHT_REG_1_VIJ_3__SHFT                0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define JPEG_DHT_CCC_MAX                          JPEG_DHT_CCC_MAX
+#define HWIO_JPEG_DHT_CCC_MAX_ADDR  /* RW */            (JPEGD_BASE+0x0000005C)
+#define HWIO_JPEG_DHT_CCC_MAX__POR                      0x00000000
+#define HWIO_JPEG_DHT_CCC_MAX__RMSK                     0xFFFFFFFF
+#define HWIO_JPEG_DHT_CCC_MAX__SHFT                              0
+/* Register Field FMSK and SHFT*/
+#define HWIO_JPEG_DHT_CCC_MAX__JPEG_DHT_CCC_MAX_MAX__BMSK    0xFFFF0000
+#define HWIO_JPEG_DHT_CCC_MAX__JPEG_DHT_CCC_MAX_MAX__SHFT            16
+#define HWIO_JPEG_DHT_CCC_MAX__JPEG_DHT_CCC_MAX_CCC__BMSK    0x0000FFFF
+#define HWIO_JPEG_DHT_CCC_MAX__JPEG_DHT_CCC_MAX_CCC__SHFT             0
+/* Register Field FMSK and SHFT*/
+#define HWIO_JPEG_DHT_CCC_MAX__JPEG_DHT_CCC_MAX_MAX__BMSK    0xFFFF0000
+#define HWIO_JPEG_DHT_CCC_MAX__JPEG_DHT_CCC_MAX_MAX__SHFT            16
+#define HWIO_JPEG_DHT_CCC_MAX__JPEG_DHT_CCC_MAX_CCC__BMSK    0x0000FFFF
+#define HWIO_JPEG_DHT_CCC_MAX__JPEG_DHT_CCC_MAX_CCC__SHFT             0
+#define HWIO_JPEG_DHT_CCC_MAX__JPEG_DHT_LI__BMSK       0x000000FF
+#define HWIO_JPEG_DHT_CCC_MAX__JPEG_DHT_LI__SHFT                0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define JPEG_DEC_SCALE                       JPEG_DEC_SCALE
+#define HWIO_JPEG_DEC_SCALE_ADDR  /* RW */       (JPEGD_BASE+0x00000060)
+#define HWIO_JPEG_DEC_SCALE__POR                 0x00000000
+#define HWIO_JPEG_DEC_SCALE__RMSK                0x00000003
+#define HWIO_JPEG_DEC_SCALE__SHFT                         0
+/* Register Field FMSK and SHFT*/
+#define HWIO_JPEG_DEC_SCALE__JPEG_DEC_SCALE_RATIO__BMSK       0x00000003
+#define HWIO_JPEG_DEC_SCALE__JPEG_DEC_SCALE_RATIO__SHFT                0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define JPEG_CONVERT                         JPEG_CONVERT
+#define HWIO_JPEG_CONVERT_ADDR  /* RW */       (JPEGD_BASE+0x00000064)
+#define HWIO_JPEG_CONVERT__POR                 0x00000000
+#define HWIO_JPEG_CONVERT__RMSK                0xFFFF13FF
+#define HWIO_JPEG_CONVERT__SHFT                         0
+/* Register Field FMSK and SHFT*/
+#define HWIO_JPEG_CONVERT__JPEG_CONVERT_MONO_CB_VALUE__BMSK      0xFF000000
+#define HWIO_JPEG_CONVERT__JPEG_CONVERT_MONO_CB_VALUE__SHFT              24
+#define HWIO_JPEG_CONVERT__JPEG_CONVERT_MONO_CR_VALUE__BMSK      0x00FF0000
+#define HWIO_JPEG_CONVERT__JPEG_CONVERT_MONO_CR_VALUE__SHFT              16
+#define HWIO_JPEG_CONVERT__JPEG_CONVERT_CLAMP_EN__BMSK           0x00001000
+#define HWIO_JPEG_CONVERT__JPEG_CONVERT_CLAMP_EN__SHFT                   12
+#define HWIO_JPEG_CONVERT__JPEG_CONVERT_CBCR_SWITCH__BMSK        0x00000200
+#define HWIO_JPEG_CONVERT__JPEG_CONVERT_CBCR_SWITCH__SHFT                 9
+#define HWIO_JPEG_CONVERT__JPEG_CONVERT_MONOCHROME_EN__BMSK      0x00000100
+#define HWIO_JPEG_CONVERT__JPEG_CONVERT_MONOCHROME_EN__SHFT               8
+#define HWIO_JPEG_CONVERT__JPEG_CONVERT_MEM_ORG__BMSK            0x000000C0
+#define HWIO_JPEG_CONVERT__JPEG_CONVERT_MEM_ORG__SHFT                     6
+#define HWIO_JPEG_CONVERT__JPEG_CONVERT_422_MCU_TYPE__BMSK       0x00000030
+#define HWIO_JPEG_CONVERT__JPEG_CONVERT_422_MCU_TYPE__SHFT                4
+#define HWIO_JPEG_CONVERT__JPEG_CONVERT_OUTPUT_FORMAT__BMSK      0x0000000C
+#define HWIO_JPEG_CONVERT__JPEG_CONVERT_OUTPUT_FORMAT__SHFT               2
+#define HWIO_JPEG_CONVERT__JPEG_CONVERT_INPUT_FORMAT__BMSK       0x00000003
+#define HWIO_JPEG_CONVERT__JPEG_CONVERT_INPUT_FORMAT__SHFT                0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define JPEG_ENC_BYTE_CNT                       JPEG_ENC_BYTE_CNT
+#define HWIO_JPEG_ENC_BYTE_CNT_ADDR  /* RW */          (JPEGD_BASE+0x00000070)
+#define HWIO_JPEG_ENC_BYTE_CNT__POR                    0x00000000
+#define HWIO_JPEG_ENC_BYTE_CNT__RMSK                   0xFFFFFFFF
+#define HWIO_JPEG_ENC_BYTE_CNT__SHFT                            0
+/* Register Field FMSK and SHFT*/
+#define HWIO_JPEG_ENC_BYTE_CNT__JPEG_ENC_BYTE_CNT_TOT__BMSK     0xFFFFFFFF
+#define HWIO_JPEG_ENC_BYTE_CNT__JPEG_ENC_BYTE_CNT_TOT__SHFT              0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define JPEG_DEBUG                                  JPEG_DEBUG
+#define HWIO_JPEG_DEBUG_ADDR  /* RW */              (JPEGD_BASE+0x00000080)
+#define HWIO_JPEG_DEBUG__POR                        0x4A504547
+#define HWIO_JPEG_DEBUG__RMSK                       0xFFFFFFFF
+#define HWIO_JPEG_DEBUG__SHFT                                0
+/* Register Field FMSK and SHFT*/
+#define HWIO_JPEG_DEBUG__JPEG_DEBUG__BMSK            0xFFFFFFFF
+#define HWIO_JPEG_DEBUG__JPEG_DEBUG__SHFT                     0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define JPEG_SPARE                                JPEG_SPARE
+#define HWIO_JPEG_SPARE_ADDR  /* RW */            (JPEGD_BASE+0x00000084)
+#define HWIO_JPEG_SPARE__POR                      0x00000000
+#define HWIO_JPEG_SPARE__RMSK                     0xFFFFFFFF
+#define HWIO_JPEG_SPARE__SHFT                              0
+/* Register Field FMSK and SHFT*/
+#define HWIO_JPEG_SPARE__JPEG_SPARE_00__BMSK            0xFFFFFFFF
+#define HWIO_JPEG_SPARE__JPEG_SPARE_00__SHFT                     0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define JPEG_REGISTER_TIMEOUT                       JPEG_REGISTER_TIMEOUT
+#define HWIO_JPEG_REGISTER_TIMEOUT_ADDR    (JPEGD_BASE+0x00000088)
+#define HWIO_JPEG_REGISTER_TIMEOUT__POR                        0x0000FFFF
+#define HWIO_JPEG_REGISTER_TIMEOUT__RMSK                       0x0000FFFF
+#define HWIO_JPEG_REGISTER_TIMEOUT__SHFT                                0
+/* Register Field FMSK and SHFT*/
+#define HWIO_JPEG_REGISTER_TIMEOUT__JPEG_TIMEOUT_VALUE__BMSK        0x0000FFFF
+#define HWIO_JPEG_REGISTER_TIMEOUT__JPEG_TIMEOUT_VALUE__SHFT                 0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define JPEGD_STATUS_BUS_DATA                     JPEGD_STATUS_BUS_DATA
+#define HWIO_JPEGD_STATUS_BUS_DATA_ADDR  /* RW */       (JPEGD_BASE+0x00000258)
+#define HWIO_JPEGD_STATUS_BUS_DATA__POR                      0x00000000
+#define HWIO_JPEGD_STATUS_BUS_DATA__RMSK                     0xFFFFFFFF
+#define HWIO_JPEGD_STATUS_BUS_DATA__SHFT                              0
+/* Register Field FMSK and SHFT*/
+#define HWIO_JPEGD_STATUS_BUS_DATA__STATUS_BUS_DATA__BMSK      0xFFFFFFFF
+#define HWIO_JPEGD_STATUS_BUS_DATA__STATUS_BUS_DATA__SHFT               0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define JPEGD_STATUS_BUS_CONFIG                     JPEGD_STATUS_BUS_CONFIG
+#define HWIO_JPEGD_STATUS_BUS_CONFIG_ADDR  /* RW */     (JPEGD_BASE+0x0000025C)
+#define HWIO_JPEGD_STATUS_BUS_CONFIG__POR                        0x00000000
+#define HWIO_JPEGD_STATUS_BUS_CONFIG__RMSK                       0x0000001F
+#define HWIO_JPEGD_STATUS_BUS_CONFIG__SHFT                                0
+/* Register Field FMSK and SHFT*/
+#define HWIO_JPEGD_STATUS_BUS_CONFIG__STATUS_BUS_SEL__BMSK         0x0000001F
+#define HWIO_JPEGD_STATUS_BUS_CONFIG__STATUS_BUS_SEL__SHFT                  0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define RTDMA_JPEG_AXI_CONFIG                       RTDMA_JPEG_AXI_CONFIG
+#define HWIO_RTDMA_JPEG_AXI_CONFIG_ADDR  /* RW */        (JPEGD_BASE+0x00000260)
+#define HWIO_RTDMA_JPEG_AXI_CONFIG__POR                        0x00000024
+#define HWIO_RTDMA_JPEG_AXI_CONFIG__RMSK                       0x00000FFF
+#define HWIO_RTDMA_JPEG_AXI_CONFIG__SHFT                                0
+/* Register Field FMSK and SHFT*/
+#define HWIO_RTDMA_JPEG_AXI_CONFIG__OUT_OF_ORDER_WR__BMSK          0x00000800
+#define HWIO_RTDMA_JPEG_AXI_CONFIG__OUT_OF_ORDER_WR__SHFT                  11
+#define HWIO_RTDMA_JPEG_AXI_CONFIG__OUT_OF_ORDER_RD__BMSK          0x00000400
+#define HWIO_RTDMA_JPEG_AXI_CONFIG__OUT_OF_ORDER_RD__SHFT                  10
+#define HWIO_RTDMA_JPEG_AXI_CONFIG__BOUND_LIMIT__BMSK              0x00000300
+#define HWIO_RTDMA_JPEG_AXI_CONFIG__BOUND_LIMIT__SHFT                       8
+#define HWIO_RTDMA_JPEG_AXI_CONFIG__PACK_TIMEOUT__BMSK             0x000000F0
+#define HWIO_RTDMA_JPEG_AXI_CONFIG__PACK_TIMEOUT__SHFT                      4
+#define HWIO_RTDMA_JPEG_AXI_CONFIG__PACK_MAX_BLEN__BMSK            0x0000000F
+#define HWIO_RTDMA_JPEG_AXI_CONFIG__PACK_MAX_BLEN__SHFT                     0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define JPEGD_CLK_CONTROL                             JPEGD_CLK_CONTROL
+#define HWIO_JPEGD_CLK_CONTROL_ADDR  /* RW */   (JPEGD_BASE+0x00000264)
+#define HWIO_JPEGD_CLK_CONTROL__POR             0x00000005
+#define HWIO_JPEGD_CLK_CONTROL__RMSK                         0x0000000F
+#define HWIO_JPEGD_CLK_CONTROL__SHFT                                  0
+/* Register Field FMSK and SHFT*/
+#define HWIO_JPEGD_CLK_CONTROL__JPEG_CLKIDLE__BMSK           0x00000008
+#define HWIO_JPEGD_CLK_CONTROL__JPEG_CLKIDLE__SHFT                    3
+#define HWIO_JPEGD_CLK_CONTROL__JPEG_CLKON__BMSK             0x00000004
+#define HWIO_JPEGD_CLK_CONTROL__JPEG_CLKON__SHFT                      2
+#define HWIO_JPEGD_CLK_CONTROL__AXI_CLKIDLE__BMSK            0x00000002
+#define HWIO_JPEGD_CLK_CONTROL__AXI_CLKIDLE__SHFT                     1
+#define HWIO_JPEGD_CLK_CONTROL__AXI_CLKON__BMSK              0x00000001
+#define HWIO_JPEGD_CLK_CONTROL__AXI_CLKON__SHFT                       0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define RTDMA_JPEG_WR_BUF_CONFIG                     RTDMA_JPEG_WR_BUF_CONFIG
+#define HWIO_RTDMA_JPEG_WR_BUF_CONFIG_ADDR  /* RW */   (JPEGD_BASE+0x00000200)
+#define HWIO_RTDMA_JPEG_WR_BUF_CONFIG__POR             0x00000000
+#define HWIO_RTDMA_JPEG_WR_BUF_CONFIG__RMSK            0x0000001F
+#define HWIO_RTDMA_JPEG_WR_BUF_CONFIG__SHFT                     0
+/* Register Field FMSK and SHFT*/
+#define HWIO_RTDMA_JPEG_WR_BUF_CONFIG__BUF_FORMAT__BMSK         0x0000001C
+#define HWIO_RTDMA_JPEG_WR_BUF_CONFIG__BUF_FORMAT__SHFT                  2
+#define HWIO_RTDMA_JPEG_WR_BUF_CONFIG__NUM_OF_PLANES__BMSK      0x00000003
+#define HWIO_RTDMA_JPEG_WR_BUF_CONFIG__NUM_OF_PLANES__SHFT               0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define RTDMA_JPEG_WR_OP                               RTDMA_JPEG_WR_OP
+#define HWIO_RTDMA_JPEG_WR_OP_ADDR  /* RW */        (JPEGD_BASE+0x00000204)
+#define HWIO_RTDMA_JPEG_WR_OP__POR                  0x00000000
+#define HWIO_RTDMA_JPEG_WR_OP__RMSK                 0x00000013
+#define HWIO_RTDMA_JPEG_WR_OP__SHFT                          0
+/* Register Field FMSK and SHFT*/
+#define HWIO_RTDMA_JPEG_WR_OP__ALIGN__BMSK          0x00000010
+#define HWIO_RTDMA_JPEG_WR_OP__ALIGN__SHFT                   4
+#define HWIO_RTDMA_JPEG_WR_OP__FLIP__BMSK           0x00000002
+#define HWIO_RTDMA_JPEG_WR_OP__FLIP__SHFT                    1
+#define HWIO_RTDMA_JPEG_WR_OP__MIRROR__BMSK         0x00000001
+#define HWIO_RTDMA_JPEG_WR_OP__MIRROR__SHFT                  0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define RTDMA_JPEG_WR_BUF_Y_PNTR                      RTDMA_JPEG_WR_BUF_Y_PNTR
+#define HWIO_RTDMA_JPEG_WR_BUF_Y_PNTR_ADDR    (JPEGD_BASE+0x00000208)
+#define HWIO_RTDMA_JPEG_WR_BUF_Y_PNTR__POR                0x00000000
+#define HWIO_RTDMA_JPEG_WR_BUF_Y_PNTR__RMSK               0xFFFFFFF8
+#define HWIO_RTDMA_JPEG_WR_BUF_Y_PNTR__SHFT                        3
+/* Register Element MIN and MAX*/
+#define HWIO_RTDMA_JPEG_WR_BUF_Y_PNTR___S                          3
+#define HWIO_RTDMA_JPEG_WR_BUF_Y_PNTR___S                          3
+#define HWIO_RTDMA_JPEG_WR_BUF_Y_PNTR___S                          3
+#define HWIO_RTDMA_JPEG_WR_BUF_Y_PNTR___S                          3
+
+/* Register Field FMSK and SHFT*/
+#define HWIO_RTDMA_JPEG_WR_BUF_Y_PNTR__PNTR__BMSK         0xFFFFFFF8
+#define HWIO_RTDMA_JPEG_WR_BUF_Y_PNTR__PNTR__SHFT                  3
+
+/* Register ADDR, RMSK, and SHFT*/
+#define RTDMA_JPEG_WR_BUF_U_PNTR                      RTDMA_JPEG_WR_BUF_U_PNTR
+#define HWIO_RTDMA_JPEG_WR_BUF_U_PNTR_ADDR  /* RW */     (JPEGD_BASE+0x0000020C)
+#define HWIO_RTDMA_JPEG_WR_BUF_U_PNTR__POR               0x00000000
+#define HWIO_RTDMA_JPEG_WR_BUF_U_PNTR__RMSK              0xFFFFFFF8
+#define HWIO_RTDMA_JPEG_WR_BUF_U_PNTR__SHFT                       3
+
+/* Register Element MIN and MAX*/
+#define HWIO_RTDMA_JPEG_WR_BUF_U_PNTR___S                         3
+#define HWIO_RTDMA_JPEG_WR_BUF_U_PNTR___S                         3
+#define HWIO_RTDMA_JPEG_WR_BUF_U_PNTR___S                         3
+#define HWIO_RTDMA_JPEG_WR_BUF_U_PNTR___S                         3
+
+/* Register Field FMSK and SHFT*/
+#define HWIO_RTDMA_JPEG_WR_BUF_U_PNTR__PNTR__BMSK        0xFFFFFFF8
+#define HWIO_RTDMA_JPEG_WR_BUF_U_PNTR__PNTR__SHFT                 3
+
+/* Register ADDR, RMSK, and SHFT*/
+#define RTDMA_JPEG_WR_BUF_V_PNTR                       RTDMA_JPEG_WR_BUF_V_PNTR
+#define HWIO_RTDMA_JPEG_WR_BUF_V_PNTR_ADDR   (JPEGD_BASE+0x00000210)
+#define HWIO_RTDMA_JPEG_WR_BUF_V_PNTR__POR                0x00000000
+#define HWIO_RTDMA_JPEG_WR_BUF_V_PNTR__RMSK               0xFFFFFFF8
+#define HWIO_RTDMA_JPEG_WR_BUF_V_PNTR__SHFT                        3
+
+/* Register Element MIN and MAX*/
+#define HWIO_RTDMA_JPEG_WR_BUF_V_PNTR___S                          3
+#define HWIO_RTDMA_JPEG_WR_BUF_V_PNTR___S                          3
+#define HWIO_RTDMA_JPEG_WR_BUF_V_PNTR___S                          3
+#define HWIO_RTDMA_JPEG_WR_BUF_V_PNTR___S                          3
+
+/* Register Field FMSK and SHFT*/
+#define HWIO_RTDMA_JPEG_WR_BUF_V_PNTR__PNTR__BMSK         0xFFFFFFF8
+#define HWIO_RTDMA_JPEG_WR_BUF_V_PNTR__PNTR__SHFT                  3
+
+/* Register ADDR, RMSK, and SHFT*/
+#define RTDMA_JPEG_WR_BUF_PITCH                         RTDMA_JPEG_WR_BUF_PITCH
+#define HWIO_RTDMA_JPEG_WR_BUF_PITCH_ADDR  /* RW */    (JPEGD_BASE+0x00000214)
+#define HWIO_RTDMA_JPEG_WR_BUF_PITCH__POR              0x00000000
+#define HWIO_RTDMA_JPEG_WR_BUF_PITCH__RMSK             0x00003FF8
+#define HWIO_RTDMA_JPEG_WR_BUF_PITCH__SHFT                      3
+
+/* Register Element MIN and MAX*/
+#define HWIO_RTDMA_JPEG_WR_BUF_PITCH___S                        3
+#define HWIO_RTDMA_JPEG_WR_BUF_PITCH___S                        3
+#define HWIO_RTDMA_JPEG_WR_BUF_PITCH___S                        3
+#define HWIO_RTDMA_JPEG_WR_BUF_PITCH___S                        3
+
+/* Register Field FMSK and SHFT*/
+#define HWIO_RTDMA_JPEG_WR_BUF_PITCH__PITCH__BMSK          0x00003FF8
+#define HWIO_RTDMA_JPEG_WR_BUF_PITCH__PITCH__SHFT                   3
+
+/* Register ADDR, RMSK, and SHFT*/
+#define RTDMA_JPEG_WR_PLANE_SIZE                      RTDMA_JPEG_WR_PLANE_SIZE
+#define HWIO_RTDMA_JPEG_WR_PLANE_SIZE_ADDR  /* RW */  (JPEGD_BASE+0x00000218)
+#define HWIO_RTDMA_JPEG_WR_PLANE_SIZE__POR            0x00000000
+#define HWIO_RTDMA_JPEG_WR_PLANE_SIZE__RMSK           0x1FFF1FFF
+#define HWIO_RTDMA_JPEG_WR_PLANE_SIZE__SHFT                    0
+
+/* Register Field FMSK and SHFT*/
+#define HWIO_RTDMA_JPEG_WR_PLANE_SIZE__PLANE_VSIZE__BMSK       0x1FFF0000
+#define HWIO_RTDMA_JPEG_WR_PLANE_SIZE__PLANE_VSIZE__SHFT               16
+#define HWIO_RTDMA_JPEG_WR_PLANE_SIZE__PLANE_HSIZE__BMSK       0x00001FFF
+#define HWIO_RTDMA_JPEG_WR_PLANE_SIZE__PLANE_HSIZE__SHFT                0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define RTDMA_JPEG_WR_BLOCK_SIZE                      RTDMA_JPEG_WR_BLOCK_SIZE
+#define HWIO_RTDMA_JPEG_WR_BLOCK_SIZE_ADDR  /* RW */    (JPEGD_BASE+0x0000021C)
+#define HWIO_RTDMA_JPEG_WR_BLOCK_SIZE__POR              0x00000000
+#define HWIO_RTDMA_JPEG_WR_BLOCK_SIZE__RMSK             0x00000FFF
+#define HWIO_RTDMA_JPEG_WR_BLOCK_SIZE__SHFT                      0
+
+/* Register Field FMSK and SHFT*/
+#define HWIO_RTDMA_JPEG_WR_BLOCK_SIZE__BLOCK_VSIZE__BMSK           0x00000FC0
+#define HWIO_RTDMA_JPEG_WR_BLOCK_SIZE__BLOCK_VSIZE__SHFT                    6
+#define HWIO_RTDMA_JPEG_WR_BLOCK_SIZE__BLOCK_HSIZE__BMSK           0x0000003F
+#define HWIO_RTDMA_JPEG_WR_BLOCK_SIZE__BLOCK_HSIZE__SHFT                    0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define RTDMA_JPEG_WR_BUFFER_SIZE                      RTDMA_JPEG_WR_BUFFER_SIZE
+#define HWIO_RTDMA_JPEG_WR_BUFFER_SIZE_ADDR  /* RW */   (JPEGD_BASE+0x00000220)
+#define HWIO_RTDMA_JPEG_WR_BUFFER_SIZE__POR             0x00000000
+#define HWIO_RTDMA_JPEG_WR_BUFFER_SIZE__RMSK            0x00001FFF
+#define HWIO_RTDMA_JPEG_WR_BUFFER_SIZE__SHFT                     0
+
+/* Register Field FMSK and SHFT*/
+#define HWIO_RTDMA_JPEG_WR_BUFFER_SIZE__BUFFER_VSIZE__BMSK         0x00001FFF
+#define HWIO_RTDMA_JPEG_WR_BUFFER_SIZE__BUFFER_VSIZE__SHFT                  0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define RTDMA_JPEG_WR_STA_ACK                      RTDMA_JPEG_WR_STA_ACK
+#define HWIO_RTDMA_JPEG_WR_STA_ACK_ADDR  /* RW */   (JPEGD_BASE+0x00000224)
+#define HWIO_RTDMA_JPEG_WR_STA_ACK__POR             0x00000000
+#define HWIO_RTDMA_JPEG_WR_STA_ACK__RMSK            0x0000000F
+#define HWIO_RTDMA_JPEG_WR_STA_ACK__SHFT                     3
+
+/* Register Element MIN and MAX*/
+#define HWIO_RTDMA_JPEG_WR_STA_ACK___S                       3
+#define HWIO_RTDMA_JPEG_WR_STA_ACK___S                       3
+#define HWIO_RTDMA_JPEG_WR_STA_ACK___S                       3
+#define HWIO_RTDMA_JPEG_WR_STA_ACK___S                       3
+
+/* Register Field FMSK and SHFT*/
+#define HWIO_RTDMA_JPEG_WR_STA_ACK__SW_RESET_ABORT_RDY_STA__BMSK   0x00000008
+#define HWIO_RTDMA_JPEG_WR_STA_ACK__SW_RESET_ABORT_RDY_STA__SHFT            3
+#define HWIO_RTDMA_JPEG_WR_STA_ACK__SW_RESET_ABORT_RDY_ACK__BMSK   0x00000008
+#define HWIO_RTDMA_JPEG_WR_STA_ACK__SW_RESET_ABORT_RDY_ACK__SHFT            3
+#define HWIO_RTDMA_JPEG_WR_STA_ACK__ERR_STA__BMSK                  0x00000004
+#define HWIO_RTDMA_JPEG_WR_STA_ACK__ERR_STA__SHFT                           2
+#define HWIO_RTDMA_JPEG_WR_STA_ACK__ERR_ACK__BMSK                  0x00000004
+#define HWIO_RTDMA_JPEG_WR_STA_ACK__ERR_ACK__SHFT                           2
+#define HWIO_RTDMA_JPEG_WR_STA_ACK__EOF_STA__BMSK                  0x00000002
+#define HWIO_RTDMA_JPEG_WR_STA_ACK__EOF_STA__SHFT                           1
+#define HWIO_RTDMA_JPEG_WR_STA_ACK__EOF_ACK__BMSK                  0x00000002
+#define HWIO_RTDMA_JPEG_WR_STA_ACK__EOF_ACK__SHFT                           1
+#define HWIO_RTDMA_JPEG_WR_STA_ACK__SOF_STA__BMSK                  0x00000001
+#define HWIO_RTDMA_JPEG_WR_STA_ACK__SOF_STA__SHFT                           0
+#define HWIO_RTDMA_JPEG_WR_STA_ACK__SOF_ACK__BMSK           0x00000001
+#define HWIO_RTDMA_JPEG_WR_STA_ACK__SOF_ACK__SHFT                    0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define RTDMA_JPEG_WR_INT_EN                      RTDMA_JPEG_WR_INT_EN
+#define HWIO_RTDMA_JPEG_WR_INT_EN_ADDR  /* W */        (JPEGD_BASE+0x00000228)
+#define HWIO_RTDMA_JPEG_WR_INT_EN__POR                 0x00000000
+#define HWIO_RTDMA_JPEG_WR_INT_EN__RMSK                0x0000000F
+#define HWIO_RTDMA_JPEG_WR_INT_EN__SHFT                         0
+
+/* Register Field FMSK and SHFT*/
+#define HWIO_RTDMA_JPEG_WR_INT_EN__SW_RESET_ABORT_RDY_EN__BMSK 0x00000008
+#define HWIO_RTDMA_JPEG_WR_INT_EN__SW_RESET_ABORT_RDY_EN__SHFT          3
+#define HWIO_RTDMA_JPEG_WR_INT_EN__ERR_EN__BMSK                0x00000004
+#define HWIO_RTDMA_JPEG_WR_INT_EN__ERR_EN__SHFT                         2
+#define HWIO_RTDMA_JPEG_WR_INT_EN__EOF_EN__BMSK                0x00000002
+#define HWIO_RTDMA_JPEG_WR_INT_EN__EOF_EN__SHFT                         1
+#define HWIO_RTDMA_JPEG_WR_INT_EN__SOF_EN__BMSK                0x00000001
+#define HWIO_RTDMA_JPEG_WR_INT_EN__SOF_EN__SHFT                         0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define RTDMA_JPEG_RD_BUF_CONFIG                     RTDMA_JPEG_RD_BUF_CONFIG
+#define HWIO_RTDMA_JPEG_RD_BUF_CONFIG_ADDR  /* RW */     (JPEGD_BASE+0x00000100)
+#define HWIO_RTDMA_JPEG_RD_BUF_CONFIG__POR               0x00000000
+#define HWIO_RTDMA_JPEG_RD_BUF_CONFIG__RMSK              0x0000001F
+#define HWIO_RTDMA_JPEG_RD_BUF_CONFIG__SHFT                       0
+
+/* Register Field FMSK and SHFT*/
+#define HWIO_RTDMA_JPEG_RD_BUF_CONFIG__BUF_FORMAT__BMSK          0x0000001C
+#define HWIO_RTDMA_JPEG_RD_BUF_CONFIG__BUF_FORMAT__SHFT                   2
+#define HWIO_RTDMA_JPEG_RD_BUF_CONFIG__NUM_OF_PLANES__BMSK       0x00000003
+#define HWIO_RTDMA_JPEG_RD_BUF_CONFIG__NUM_OF_PLANES__SHFT                0
+
+/* Register ADDR, RMSK, and SHFT, W */
+#define RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO   RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO
+#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO_ADDR  (JPEGD_BASE+0x00000104)
+#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO__POR            0x00000000
+#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO__RMSK           0x0000001C
+#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO__SHFT                    2
+
+/* Register Element MIN and MAX*/
+#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO___S                      2
+#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO___S                      2
+#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO___S                      2
+#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO___S                      2
+
+/* Register Field FMSK and SHFT*/
+#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO__BUF_APPLY__BMSK   0x00000010
+#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO__BUF_APPLY__SHFT            4
+#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO__BUF_EOF__BMSK     0x00000008
+#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO__BUF_EOF__SHFT              3
+#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO__BUF_SOF__BMSK     0x00000004
+#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO__BUF_SOF__SHFT              2
+
+/* Register ADDR, RMSK, and SHFT*/
+#define RTDMA_JPEG_RD_BUF_Y_PNTR                        RTDMA_JPEG_RD_BUF_Y_PNTR
+#define HWIO_RTDMA_JPEG_RD_BUF_Y_PNTR_ADDR  /* RW */   (JPEGD_BASE+0x0000010C)
+#define HWIO_RTDMA_JPEG_RD_BUF_Y_PNTR__POR             0x00000000
+#define HWIO_RTDMA_JPEG_RD_BUF_Y_PNTR__RMSK            0xFFFFFFF8
+#define HWIO_RTDMA_JPEG_RD_BUF_Y_PNTR__SHFT                     3
+
+/* Register Element MIN and MAX*/
+#define HWIO_RTDMA_JPEG_RD_BUF_Y_PNTR___S                       3
+#define HWIO_RTDMA_JPEG_RD_BUF_Y_PNTR___S                       3
+#define HWIO_RTDMA_JPEG_RD_BUF_Y_PNTR___S                       3
+#define HWIO_RTDMA_JPEG_RD_BUF_Y_PNTR___S                       3
+
+/* Register Field FMSK and SHFT*/
+#define HWIO_RTDMA_JPEG_RD_BUF_Y_PNTR__PNTR__BMSK      0xFFFFFFF8
+#define HWIO_RTDMA_JPEG_RD_BUF_Y_PNTR__PNTR__SHFT               3
+
+/* Register ADDR, RMSK, and SHFT*/
+#define RTDMA_JPEG_RD_BUF_U_PNTR                     RTDMA_JPEG_RD_BUF_U_PNTR
+#define HWIO_RTDMA_JPEG_RD_BUF_U_PNTR_ADDR  /* RW */ (JPEGD_BASE+0x00000110)
+#define HWIO_RTDMA_JPEG_RD_BUF_U_PNTR__POR           0x00000000
+#define HWIO_RTDMA_JPEG_RD_BUF_U_PNTR__RMSK          0xFFFFFFF8
+#define HWIO_RTDMA_JPEG_RD_BUF_U_PNTR__SHFT                   3
+
+/* Register Element MIN and MAX*/
+#define HWIO_RTDMA_JPEG_RD_BUF_U_PNTR___S                     3
+#define HWIO_RTDMA_JPEG_RD_BUF_U_PNTR___S                     3
+#define HWIO_RTDMA_JPEG_RD_BUF_U_PNTR___S                     3
+#define HWIO_RTDMA_JPEG_RD_BUF_U_PNTR___S                     3
+
+/* Register Field FMSK and SHFT*/
+#define HWIO_RTDMA_JPEG_RD_BUF_U_PNTR__PNTR__BMSK        0xFFFFFFF8
+#define HWIO_RTDMA_JPEG_RD_BUF_U_PNTR__PNTR__SHFT               3
+
+/* Register ADDR, RMSK, and SHFT*/
+#define RTDMA_JPEG_RD_BUF_V_PNTR                     RTDMA_JPEG_RD_BUF_V_PNTR
+#define HWIO_RTDMA_JPEG_RD_BUF_V_PNTR_ADDR  /* RW */    (JPEGD_BASE+0x00000114)
+#define HWIO_RTDMA_JPEG_RD_BUF_V_PNTR__POR              0x00000000
+#define HWIO_RTDMA_JPEG_RD_BUF_V_PNTR__RMSK             0xFFFFFFF8
+#define HWIO_RTDMA_JPEG_RD_BUF_V_PNTR__SHFT                      3
+
+/* Register Element MIN and MAX*/
+#define HWIO_RTDMA_JPEG_RD_BUF_V_PNTR___S                        3
+#define HWIO_RTDMA_JPEG_RD_BUF_V_PNTR___S                        3
+#define HWIO_RTDMA_JPEG_RD_BUF_V_PNTR___S                        3
+#define HWIO_RTDMA_JPEG_RD_BUF_V_PNTR___S                        3
+
+/* Register Field FMSK and SHFT*/
+#define HWIO_RTDMA_JPEG_RD_BUF_V_PNTR__PNTR__BMSK       0xFFFFFFF8
+#define HWIO_RTDMA_JPEG_RD_BUF_V_PNTR__PNTR__SHFT                3
+
+/* Register ADDR, RMSK, and SHFT*/
+#define RTDMA_JPEG_RD_BUF_PITCH                       RTDMA_JPEG_RD_BUF_PITCH
+#define HWIO_RTDMA_JPEG_RD_BUF_PITCH_ADDR  /* RW */    (JPEGD_BASE+0x00000118)
+#define HWIO_RTDMA_JPEG_RD_BUF_PITCH__POR              0x00000000
+#define HWIO_RTDMA_JPEG_RD_BUF_PITCH__RMSK             0x00003FF8
+#define HWIO_RTDMA_JPEG_RD_BUF_PITCH__SHFT                      3
+
+/* Register Element MIN and MAX*/
+#define HWIO_RTDMA_JPEG_RD_BUF_PITCH___S                        3
+#define HWIO_RTDMA_JPEG_RD_BUF_PITCH___S                        3
+#define HWIO_RTDMA_JPEG_RD_BUF_PITCH___S                        3
+#define HWIO_RTDMA_JPEG_RD_BUF_PITCH___S                        3
+
+/* Register Field FMSK and SHFT*/
+#define HWIO_RTDMA_JPEG_RD_BUF_PITCH__PITCH__BMSK            0x00003FF8
+#define HWIO_RTDMA_JPEG_RD_BUF_PITCH__PITCH__SHFT                     3
+
+/* Register ADDR, RMSK, and SHFT*/
+#define RTDMA_JPEG_RD_PLANE_SIZE                     RTDMA_JPEG_RD_PLANE_SIZE
+#define HWIO_RTDMA_JPEG_RD_PLANE_SIZE_ADDR  /* RW */  (JPEGD_BASE+0x0000011C)
+#define HWIO_RTDMA_JPEG_RD_PLANE_SIZE__POR            0x00000000
+#define HWIO_RTDMA_JPEG_RD_PLANE_SIZE__RMSK            0x1FFF1FFF
+#define HWIO_RTDMA_JPEG_RD_PLANE_SIZE__SHFT                     0
+
+/* Register Field FMSK and SHFT*/
+#define HWIO_RTDMA_JPEG_RD_PLANE_SIZE__PLANE_VSIZE__BMSK         0x1FFF0000
+#define HWIO_RTDMA_JPEG_RD_PLANE_SIZE__PLANE_VSIZE__SHFT                 16
+#define HWIO_RTDMA_JPEG_RD_PLANE_SIZE__PLANE_HSIZE__BMSK         0x00001FFF
+#define HWIO_RTDMA_JPEG_RD_PLANE_SIZE__PLANE_HSIZE__SHFT                  0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define RTDMA_JPEG_RD_BLOCK_SIZE                       RTDMA_JPEG_RD_BLOCK_SIZE
+#define HWIO_RTDMA_JPEG_RD_BLOCK_SIZE_ADDR  /* RW */    (JPEGD_BASE+0x00000120)
+#define HWIO_RTDMA_JPEG_RD_BLOCK_SIZE__POR              0x000003CF
+#define HWIO_RTDMA_JPEG_RD_BLOCK_SIZE__RMSK             0x00000FFF
+#define HWIO_RTDMA_JPEG_RD_BLOCK_SIZE__SHFT                      0
+
+/* Register Field FMSK and SHFT*/
+#define HWIO_RTDMA_JPEG_RD_BLOCK_SIZE__BLOCK_VSIZE__BMSK       0x00000FC0
+#define HWIO_RTDMA_JPEG_RD_BLOCK_SIZE__BLOCK_VSIZE__SHFT                6
+#define HWIO_RTDMA_JPEG_RD_BLOCK_SIZE__BLOCK_HSIZE__BMSK       0x0000003F
+#define HWIO_RTDMA_JPEG_RD_BLOCK_SIZE__BLOCK_HSIZE__SHFT                0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define RTDMA_JPEG_RD_BUFFER_SIZE               RTDMA_JPEG_RD_BUFFER_SIZE
+#define HWIO_RTDMA_JPEG_RD_BUFFER_SIZE_ADDR  (JPEGD_BASE+0x00000124)
+#define HWIO_RTDMA_JPEG_RD_BUFFER_SIZE__POR               0x00000000
+#define HWIO_RTDMA_JPEG_RD_BUFFER_SIZE__RMSK              0x00001FFF
+#define HWIO_RTDMA_JPEG_RD_BUFFER_SIZE__SHFT                       0
+
+/* Register Field FMSK and SHFT*/
+#define HWIO_RTDMA_JPEG_RD_BUFFER_SIZE__BUFFER_VSIZE__BMSK      0x00001FFF
+#define HWIO_RTDMA_JPEG_RD_BUFFER_SIZE__BUFFER_VSIZE__SHFT                0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define RTDMA_JPEG_RD_STA_ACK                     RTDMA_JPEG_RD_STA_ACK
+#define HWIO_RTDMA_JPEG_RD_STA_ACK_ADDR         (JPEGD_BASE+0x00000128)
+#define HWIO_RTDMA_JPEG_RD_STA_ACK__POR                     0x00000000
+#define HWIO_RTDMA_JPEG_RD_STA_ACK__RMSK                    0x00000003
+#define HWIO_RTDMA_JPEG_RD_STA_ACK__SHFT                             0
+
+/* Register Field FMSK and SHFT*/
+#define HWIO_RTDMA_JPEG_RD_STA_ACK__EOF_STA__BMSK           0x00000002
+#define HWIO_RTDMA_JPEG_RD_STA_ACK__EOF_STA__SHFT                    1
+#define HWIO_RTDMA_JPEG_RD_STA_ACK__SOF_STA__BMSK           0x00000001
+#define HWIO_RTDMA_JPEG_RD_STA_ACK__SOF_STA__SHFT                    0
+#define HWIO_RTDMA_JPEG_RD_STA_ACK__EOF_ACK__BMSK           0x00000002
+#define HWIO_RTDMA_JPEG_RD_STA_ACK__EOF_ACK__SHFT                    1
+#define HWIO_RTDMA_JPEG_RD_STA_ACK__SOF_ACK__BMSK           0x00000001
+#define HWIO_RTDMA_JPEG_RD_STA_ACK__SOF_ACK__SHFT                    0
+
+/* Register ADDR, RMSK, and SHFT*/
+#define RTDMA_JPEG_RD_INT_EN                      RTDMA_JPEG_RD_INT_EN
+#define HWIO_RTDMA_JPEG_RD_INT_EN_ADDR  /* W */        (JPEGD_BASE+0x0000012C)
+#define HWIO_RTDMA_JPEG_RD_INT_EN__POR                      0x00000000
+#define HWIO_RTDMA_JPEG_RD_INT_EN__RMSK                     0x00000003
+#define HWIO_RTDMA_JPEG_RD_INT_EN__SHFT                              0
+
+/* Register Field FMSK and SHFT*/
+#define HWIO_RTDMA_JPEG_RD_INT_EN__EOF_EN__BMSK             0x00000002
+#define HWIO_RTDMA_JPEG_RD_INT_EN__EOF_EN__SHFT                      1
+#define HWIO_RTDMA_JPEG_RD_INT_EN__SOF_EN__BMSK             0x00000001
+#define HWIO_RTDMA_JPEG_RD_INT_EN__SOF_EN__SHFT                      0
+
+#endif /* MSM_MERCURY_HW_REG_H */
diff --git a/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_macros.h b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_macros.h
new file mode 100644
index 0000000..0ab07cd
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_macros.h
@@ -0,0 +1,118 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_MERCURY_MACROS_H
+#define MSM_MERCURY_MACROS_H
+
+#include <media/msm_mercury.h>
+
+#define mercury_kread(reg) \
+	hw_cmd.type = MSM_MERCURY_HW_CMD_TYPE_READ; \
+	hw_cmd.n = 1; \
+	hw_cmd.offset = HWIO_##reg##_ADDR; \
+	hw_cmd.mask = HWIO_##reg##__RMSK; \
+	hw_cmd.data = 0x0; \
+	msm_mercury_hw_exec_cmds(&hw_cmd, 1);
+
+#define mercury_kwrite(reg, val) \
+	hw_cmd.offset = HWIO_##reg##_ADDR; \
+	hw_cmd.mask = HWIO_##reg##__RMSK; \
+	hw_cmd.type = MSM_MERCURY_HW_CMD_TYPE_WRITE; \
+	hw_cmd.n = 1; \
+	hw_cmd.data = val; \
+	msm_mercury_hw_exec_cmds(&hw_cmd, 1);
+
+#define GET_FVAL(val, reg, field) ((val & HWIO_FMSK(reg, field)) >> \
+	HWIO_SHFT(reg, field))
+
+#define byte unsigned char
+#define word unsigned short
+#define dword unsigned long
+
+#define inp(port)    (*((dword *) (port)))
+#define inpb(port)     (*((byte *) (port)))
+#define inpw(port)   (*((word *) (port)))
+#define inpdw(port)   (*((dword *)(port)))
+
+#define outp(port, val)   (*((dword *) (port)) = ((dword) (val)))
+#define outpb(port, val)   (*((byte *) (port)) = ((byte) (val)))
+#define outpw(port, val)  (*((word *) (port)) = ((word) (val)))
+#define outpdw(port, val) (*((dword *) (port)) = ((dword) (val)))
+
+
+#define in_byte(addr)				(inp(addr))
+#define in_byte_masked(addr, mask)	(inp(addr) & (byte)mask)
+#define out_byte(addr, val)			 outp(addr, val)
+#define in_word(addr)				(inpw(addr))
+#define in_word_masked(addr, mask)	(inpw(addr) & (word)mask)
+#define out_word(addr, val)			 outpw(addr, val)
+#define in_dword(addr)				(inpdw(addr))
+#define in_dword_masked(addr, mask)	(inpdw(addr) & mask)
+#define out_dword(addr, val)			 outpdw(addr, val)
+
+/* shadowed, masked output for write-only registers */
+#define out_byte_masked(io, mask, val, shadow)  \
+	do { \
+		shadow = (shadow & (word)(~(mask))) | \
+		((word)((val) & (mask))); \
+		(void) out_byte(io, shadow);\
+	} while (0);
+
+#define out_word_masked(io, mask, val, shadow)  \
+	do { \
+		shadow = (shadow & (word)(~(mask))) | \
+		((word)((val) & (mask))); \
+		(void) out_word(io, shadow); \
+	} while (0);
+
+#define out_dword_masked(io, mask, val, shadow)  \
+	do { \
+		shadow = (shadow & (dword)(~(mask))) | \
+		((dword)((val) & (mask))); \
+		(void) out_dword(io, shadow);\
+	} while (0);
+
+#define out_byte_masked_ns(io, mask, val, current_reg_content)  \
+	(void) out_byte(io, ((current_reg_content & \
+	(word)(~(mask))) | ((word)((val) & (mask)))))
+
+#define out_word_masked_ns(io, mask, val, current_reg_content)  \
+	(void) out_word(io, ((current_reg_content & \
+	(word)(~(mask))) | ((word)((val) & (mask)))))
+
+#define out_dword_masked_ns(io, mask, val, current_reg_content) \
+	(void) out_dword(io, ((current_reg_content & \
+	(dword)(~(mask))) | ((dword)((val) & (mask)))))
+
+#define MEM_INF(val, reg, field)	((val & HWIO_FMSK(reg, field)) >> \
+	HWIO_SHFT(reg, field))
+
+#define MEM_OUTF(mem, reg, field, val)\
+	out_dword_masked_ns(mem, HWIO_FMSK(reg, field), \
+	(unsigned  int)val<<HWIO_SHFT(reg, field), in_dword(mem))
+
+#define MEM_OUTF2(mem, reg, field2, field1, val2, val1)  \
+	out_dword_masked_ns(mem, (HWIO_FMSK(reg, field2)| \
+	HWIO_FMSK(reg, field1)), \
+	(((unsigned int)val2<<HWIO_SHFT(reg, field2))| \
+	((unsigned int)val1<<HWIO_SHFT(reg, field1))), in_dword(mem))
+
+#define MEM_OUTF3(mem, reg, fld3, fld2, fld1, val3, val2, val1)  \
+	out_dword_masked_ns(mem, (HWIO_FMSK(reg, fld3)| \
+	HWIO_FMSK(reg, fld2)|HWIO_FMSK(reg, fld1)), \
+	(((unsigned int)val3<<HWIO_SHFT(reg, fld3))| \
+	((unsigned int)val2<<HWIO_SHFT(reg, fld2))| \
+	((unsigned int)val1<<HWIO_SHFT(reg, fld1))), in_dword(mem))
+
+#define HWIO_FMSK(reg, field)   HWIO_##reg##__##field##__BMSK
+#define HWIO_SHFT(reg, field)   HWIO_##reg##__##field##__SHFT
+#endif
diff --git a/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_platform.c b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_platform.c
new file mode 100644
index 0000000..e6392fe
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_platform.c
@@ -0,0 +1,193 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/android_pmem.h>
+#include <mach/clk.h>
+#include <mach/camera.h>
+#include <mach/msm_subsystem_map.h>
+
+#include "msm_mercury_platform.h"
+#include "msm_mercury_sync.h"
+#include "msm_mercury_common.h"
+#include "msm_mercury_hw.h"
+
+
+struct ion_client *mercury_client;
+
+static struct msm_cam_clk_info mercury_jpegd_clk_info[] = {
+	{"core_clk", 200000000},
+	{"iface_clk", -1}
+};
+
+void msm_mercury_platform_p2v(struct file  *file,
+	struct ion_handle **ionhandle)
+{
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	ion_unmap_iommu(mercury_client, *ionhandle, CAMERA_DOMAIN,
+		GEN_POOL);
+	ion_free(mercury_client, *ionhandle);
+	*ionhandle = NULL;
+#elif CONFIG_ANDROID_PMEM
+	put_pmem_file(file);
+#endif
+}
+
+uint32_t msm_mercury_platform_v2p(int fd, uint32_t len,
+	struct file **file_p,
+	struct ion_handle **ionhandle)
+{
+	unsigned long paddr;
+	unsigned long size;
+	int rc;
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	*ionhandle = ion_import_dma_buf(mercury_client, fd);
+	if (IS_ERR_OR_NULL(*ionhandle))
+		return 0;
+
+	rc = ion_map_iommu(mercury_client, *ionhandle, CAMERA_DOMAIN,
+		GEN_POOL, SZ_4K, 0, &paddr,
+		(unsigned long *)&size, 0, 0);
+#elif CONFIG_ANDROID_PMEM
+	unsigned long kvstart;
+	rc = get_pmem_file(fd, &paddr, &kvstart, &size, file_p);
+#else
+	rc = 0;
+	paddr = 0;
+	size = 0;
+#endif
+	if (rc < 0) {
+		MCR_PR_ERR("%s: get_pmem_file fd %d error %d\n", __func__, fd,
+			rc);
+		goto error1;
+	}
+
+	/* validate user input */
+	if (len > size) {
+		MCR_PR_ERR("%s: invalid offset + len\n", __func__);
+		goto error1;
+	}
+
+	return paddr;
+error1:
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	ion_free(mercury_client, *ionhandle);
+#endif
+	return 0;
+}
+
+int msm_mercury_platform_init(struct platform_device *pdev,
+	struct resource **mem,
+	void **base,
+	int *irq,
+	irqreturn_t (*handler) (int, void *),
+	void *context)
+{
+	int rc = 0;
+	int mercury_irq;
+	struct resource *mercury_mem, *mercury_io, *mercury_irq_res;
+	void *mercury_base;
+	struct msm_mercury_device *pmercury_dev =
+		(struct msm_mercury_device *) context;
+
+	MCR_DBG("%s:%d]\n", __func__, __LINE__);
+
+	mercury_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!mercury_mem) {
+		MCR_PR_ERR("%s: no mem resource?\n", __func__);
+		return -ENODEV;
+	}
+
+	mercury_irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!mercury_irq_res) {
+		MCR_PR_ERR("no irq resource?\n");
+		return -ENODEV;
+	}
+	mercury_irq = mercury_irq_res->start;
+
+	mercury_io = request_mem_region(mercury_mem->start,
+		resource_size(mercury_mem), pdev->name);
+	if (!mercury_io) {
+		MCR_PR_ERR("%s: region already claimed\n", __func__);
+		return -EBUSY;
+	}
+	MCR_DBG("%s:%d]\n", __func__, __LINE__);
+	mercury_base = ioremap(mercury_mem->start,
+		resource_size(mercury_mem));
+	if (!mercury_base) {
+		rc = -ENOMEM;
+		MCR_PR_ERR("%s: ioremap failed\n", __func__);
+		goto fail1;
+	}
+	MCR_DBG("%s:%d]\n", __func__, __LINE__);
+
+	rc = msm_cam_clk_enable(&pmercury_dev->pdev->dev,
+		mercury_jpegd_clk_info, pmercury_dev->mercury_clk,
+		ARRAY_SIZE(mercury_jpegd_clk_info), 1);
+	if (rc < 0)
+		MCR_PR_ERR("%s:%d] rc = %d\n", __func__, __LINE__, rc);
+
+	MCR_DBG("%s:%d]\n", __func__, __LINE__);
+	msm_mercury_hw_init(mercury_base, resource_size(mercury_mem));
+	rc = request_irq(mercury_irq, handler, IRQF_TRIGGER_RISING,
+		"mercury", context);
+	if (rc) {
+		MCR_PR_ERR("%s: request_irq failed, %d\n", __func__,
+			mercury_irq);
+		goto fail3;
+	}
+	MCR_DBG("%s:%d]\n", __func__, __LINE__);
+	*mem  = mercury_mem;
+	*base = mercury_base;
+	*irq  = mercury_irq;
+	MCR_DBG("%s:%d]\n", __func__, __LINE__);
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	mercury_client = msm_ion_client_create(-1, "camera/mercury");
+#endif
+	MCR_PR_ERR("%s:%d] success\n", __func__, __LINE__);
+	return rc;
+fail3:
+	MCR_DBG("%s:%d]\n", __func__, __LINE__);
+	msm_cam_clk_enable(&pmercury_dev->pdev->dev, mercury_jpegd_clk_info,
+		pmercury_dev->mercury_clk,
+		ARRAY_SIZE(mercury_jpegd_clk_info), 0);
+	MCR_DBG("%s:%d]\n", __func__, __LINE__);
+	iounmap(mercury_base);
+fail1:
+	MCR_DBG("%s:%d]\n", __func__, __LINE__);
+	release_mem_region(mercury_mem->start, resource_size(mercury_mem));
+	MCR_DBG("%s:%d]\n", __func__, __LINE__);
+	return rc;
+}
+
+int msm_mercury_platform_release(struct resource *mem, void *base,
+	int irq, void *context)
+{
+	int result = 0;
+	struct msm_mercury_device *pmercury_dev =
+		(struct msm_mercury_device *) context;
+
+	free_irq(irq, context);
+	msm_cam_clk_enable(&pmercury_dev->pdev->dev, mercury_jpegd_clk_info,
+		pmercury_dev->mercury_clk, ARRAY_SIZE(mercury_jpegd_clk_info),
+		0);
+	iounmap(base);
+	release_mem_region(mem->start, resource_size(mem));
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	ion_client_destroy(mercury_client);
+#endif
+	MCR_DBG("%s:%d] success\n", __func__, __LINE__);
+	return result;
+}
+
diff --git a/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_platform.h b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_platform.h
new file mode 100644
index 0000000..dfdea3c
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_platform.h
@@ -0,0 +1,39 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_MERCURY_PLATFORM_H
+#define MSM_MERCURY_PLATFORM_H
+
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/msm_ion.h>
+
+int msm_mercury_platform_clk_enable(void);
+int msm_mercury_platform_clk_disable(void);
+
+void msm_mercury_platform_p2v(struct file  *file,
+	struct ion_handle **ionhandle);
+
+uint32_t msm_mercury_platform_v2p(int fd, uint32_t len, struct file **file,
+	struct ion_handle **ionhandle);
+
+int msm_mercury_platform_init(struct platform_device *pdev,
+	struct resource **mem,
+	void **base,
+	int *irq,
+	irqreturn_t (*handler) (int, void *),
+	void *context);
+
+int msm_mercury_platform_release(struct resource *mem, void *base, int irq,
+	void *context);
+
+#endif /* MSM_MERCURY_PLATFORM_H */
diff --git a/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_sync.c b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_sync.c
new file mode 100644
index 0000000..9293aad
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_sync.c
@@ -0,0 +1,614 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/uaccess.h>
+#include <linux/slab.h>
+#include <media/msm_mercury.h>
+
+#include "msm_mercury_sync.h"
+#include "msm_mercury_core.h"
+#include "msm_mercury_platform.h"
+#include "msm_mercury_common.h"
+#include "msm_mercury_macros.h"
+#include "msm_mercury_hw_reg.h"
+
+static struct msm_mercury_core_buf out_buf_local;
+static struct msm_mercury_core_buf in_buf_local;
+
+/*************** queue helper ****************/
+inline void msm_mercury_q_init(char const *name, struct msm_mercury_q *q_p)
+{
+	MCR_DBG("%s:%d] %s\n", __func__, __LINE__, name);
+	q_p->name = name;
+	spin_lock_init(&q_p->lck);
+	INIT_LIST_HEAD(&q_p->q);
+	init_waitqueue_head(&q_p->wait);
+	q_p->unblck = 0;
+}
+
+inline void *msm_mercury_q_out(struct msm_mercury_q *q_p)
+{
+	unsigned long flags;
+	struct msm_mercury_q_entry *q_entry_p = NULL;
+	void *data = NULL;
+
+	MCR_DBG("(%d)%s()  %s\n", __LINE__, __func__, q_p->name);
+	spin_lock_irqsave(&q_p->lck, flags);
+	if (!list_empty(&q_p->q)) {
+		q_entry_p = list_first_entry(&q_p->q,
+			struct msm_mercury_q_entry,
+			list);
+		list_del_init(&q_entry_p->list);
+	}
+	spin_unlock_irqrestore(&q_p->lck, flags);
+
+	if (q_entry_p) {
+		data = q_entry_p->data;
+		kfree(q_entry_p);
+	} else {
+		MCR_DBG("%s:%d] %s no entry\n", __func__, __LINE__, q_p->name);
+	}
+
+	return data;
+}
+
+inline int msm_mercury_q_in(struct msm_mercury_q *q_p, void *data)
+{
+	unsigned long flags;
+
+	struct msm_mercury_q_entry *q_entry_p;
+
+	MCR_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
+
+	q_entry_p = kmalloc(sizeof(struct msm_mercury_q_entry), GFP_ATOMIC);
+	if (!q_entry_p) {
+		MCR_PR_ERR("%s: no mem\n", __func__);
+		return -EFAULT;
+	}
+	q_entry_p->data = data;
+
+	spin_lock_irqsave(&q_p->lck, flags);
+	list_add_tail(&q_entry_p->list, &q_p->q);
+	spin_unlock_irqrestore(&q_p->lck, flags);
+
+	return 0;
+}
+
+inline int msm_mercury_q_in_buf(struct msm_mercury_q *q_p,
+	struct msm_mercury_core_buf *buf)
+{
+	struct msm_mercury_core_buf *buf_p;
+
+	MCR_DBG("%s:%d]\n", __func__, __LINE__);
+	buf_p = kmalloc(sizeof(struct msm_mercury_core_buf), GFP_ATOMIC);
+	if (!buf_p) {
+		MCR_PR_ERR("%s: no mem\n", __func__);
+		return -EFAULT;
+	}
+
+	memcpy(buf_p, buf, sizeof(struct msm_mercury_core_buf));
+
+	msm_mercury_q_in(q_p, buf_p);
+	return 0;
+}
+
+inline int msm_mercury_q_wait(struct msm_mercury_q *q_p)
+{
+	int tm = MAX_SCHEDULE_TIMEOUT; /* 500ms */
+	int rc;
+
+	MCR_DBG("%s:%d %s wait\n", __func__, __LINE__, q_p->name);
+	rc = wait_event_interruptible_timeout(q_p->wait,
+		(!list_empty_careful(&q_p->q) || q_p->unblck),
+		msecs_to_jiffies(tm));
+
+	MCR_DBG("%s:%d %s wait done (rc=%d)\n", __func__,
+		__LINE__, q_p->name, rc);
+	if (list_empty_careful(&q_p->q)) {
+		if (rc == 0) {
+			rc = -ETIMEDOUT;
+			MCR_PR_ERR("%s:%d] %s timeout\n", __func__,
+				__LINE__, q_p->name);
+		} else if (q_p->unblck) {
+			MCR_DBG("%s:%d %s unblock is true", __func__,
+				__LINE__, q_p->name);
+			rc = q_p->unblck;
+			q_p->unblck = 0;
+		} else if (rc < 0) {
+			MCR_PR_ERR("%s:%d %s rc %d\n", __func__, __LINE__,
+				q_p->name, rc);
+		}
+	}
+	return rc;
+}
+
+inline int msm_mercury_q_wakeup(struct msm_mercury_q *q_p)
+{
+	MCR_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
+	wake_up(&q_p->wait);
+	return 0;
+}
+
+inline int msm_mercury_q_wr_eoi(struct msm_mercury_q *q_p)
+{
+	MCR_DBG("%s:%d] Wake up %s\n", __func__, __LINE__, q_p->name);
+	q_p->unblck = MSM_MERCURY_EVT_FRAMEDONE;
+	wake_up(&q_p->wait);
+	return 0;
+}
+
+inline int msm_mercury_q_wr_err(struct msm_mercury_q *q_p)
+{
+	MCR_DBG("%s:%d] Wake up %s\n", __func__, __LINE__, q_p->name);
+	q_p->unblck = MSM_MERCURY_EVT_ERR;
+	wake_up(&q_p->wait);
+	return 0;
+}
+
+inline int msm_mercury_q_unblock(struct msm_mercury_q *q_p)
+{
+	MCR_DBG("%s:%d] Wake up %s\n", __func__, __LINE__, q_p->name);
+	q_p->unblck = MSM_MERCURY_EVT_UNBLOCK;
+	wake_up(&q_p->wait);
+	return 0;
+}
+
+inline void msm_mercury_q_cleanup(struct msm_mercury_q *q_p)
+{
+	void *data;
+	MCR_DBG("\n%s:%d] %s\n", __func__, __LINE__, q_p->name);
+	do {
+		data = msm_mercury_q_out(q_p);
+		if (data) {
+			MCR_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
+			kfree(data);
+		}
+	} while (data);
+	q_p->unblck = 0;
+}
+
+/*************** event queue ****************/
+int msm_mercury_framedone_irq(struct msm_mercury_device *pmercury_dev)
+{
+	MCR_DBG("%s:%d] Enter\n", __func__, __LINE__);
+	msm_mercury_q_unblock(&pmercury_dev->evt_q);
+
+	MCR_DBG("%s:%d] Exit\n", __func__, __LINE__);
+	return 0;
+}
+
+int msm_mercury_evt_get(struct msm_mercury_device *pmercury_dev,
+	void __user *arg)
+{
+	struct msm_mercury_ctrl_cmd ctrl_cmd;
+	int rc = 0;
+
+	MCR_DBG("(%d)%s() Enter\n", __LINE__, __func__);
+	ctrl_cmd.type = (uint32_t)msm_mercury_q_wait(&pmercury_dev->evt_q);
+
+	rc = copy_to_user(arg, &ctrl_cmd, sizeof(ctrl_cmd));
+
+	if (rc) {
+		MCR_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+int msm_mercury_evt_get_unblock(struct msm_mercury_device *pmercury_dev)
+{
+	MCR_DBG("--(%d)%s() Enter\n", __LINE__, __func__);
+	msm_mercury_q_unblock(&pmercury_dev->evt_q);
+	return 0;
+}
+
+int msm_mercury_output_buf_cfg(struct msm_mercury_device *pmercury_dev,
+	void __user *arg)
+{
+	struct msm_mercury_buf buf_cmd;
+
+
+	MCR_DBG("%s:%d] Enter\n", __func__, __LINE__);
+	if (copy_from_user(&buf_cmd, arg, sizeof(struct msm_mercury_buf))) {
+		MCR_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+
+	out_buf_local.y_buffer_addr = msm_mercury_platform_v2p(buf_cmd.fd,
+		buf_cmd.y_len, &out_buf_local.file, &out_buf_local.handle);
+	out_buf_local.cbcr_buffer_addr = out_buf_local.y_buffer_addr +
+		buf_cmd.y_len;
+
+	if (!out_buf_local.y_buffer_addr) {
+		MCR_PR_ERR("%s:%d] v2p wrong\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+
+	msm_mercury_hw_output_y_buf_cfg(out_buf_local.y_buffer_addr);
+	msm_mercury_hw_output_u_buf_cfg(out_buf_local.cbcr_buffer_addr);
+
+	MCR_DBG("(%d)%s()\n  y_buf=0x%08X, y_len=0x%08X, vaddr=0x%08X\n"
+		"  u_buf=0x%08X, u_len=0x%08X\n\n", __LINE__, __func__,
+		out_buf_local.y_buffer_addr, buf_cmd.y_len, (int) buf_cmd.vaddr,
+		out_buf_local.cbcr_buffer_addr, buf_cmd.cbcr_len);
+
+	return 0;
+}
+
+int msm_mercury_input_buf_cfg(struct msm_mercury_device *pmercury_dev,
+	void __user *arg)
+{
+	struct msm_mercury_buf buf_cmd;
+
+
+	MCR_DBG("%s:%d] Enter\n", __func__, __LINE__);
+	if (copy_from_user(&buf_cmd, arg, sizeof(struct msm_mercury_buf))) {
+		MCR_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+
+	in_buf_local.y_buffer_addr = msm_mercury_platform_v2p(buf_cmd.fd,
+		buf_cmd.y_len, &in_buf_local.file, &in_buf_local.handle);
+
+	if (!in_buf_local.y_buffer_addr) {
+		MCR_PR_ERR("%s:%d] v2p wrong\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+
+	msm_mercury_hw_bitstream_buf_cfg(in_buf_local.y_buffer_addr);
+
+	MCR_DBG("(%d)%s()\n  bitstream_buf=0x%08X, len=0x%08X, vaddr=0x%08X\n",
+		__LINE__, __func__, in_buf_local.y_buffer_addr, buf_cmd.y_len,
+		(int) buf_cmd.vaddr);
+
+	return 0;
+}
+
+int msm_mercury_output_get(struct msm_mercury_device *pmercury_dev,
+	void __user *to)
+{
+	MCR_DBG("%s:%d] Enter\n", __func__, __LINE__);
+	msm_mercury_platform_p2v(out_buf_local.file, &out_buf_local.handle);
+	return 0;
+}
+
+int msm_mercury_input_get(struct msm_mercury_device *pmercury_dev,
+	void __user *to)
+{
+
+
+	MCR_DBG("%s:%d] Enter\n", __func__, __LINE__);
+	msm_mercury_platform_p2v(in_buf_local.file, &in_buf_local.handle);
+	return 0;
+}
+
+int msm_mercury_ioctl_dump_regs(void)
+{
+	uint32_t mercury_regs[] = {
+		0x0000, 0x0008, 0x0010, 0x0014, 0x0018, 0x001C, 0x0020, 0x0024,
+		0x0030, 0x0034, 0x0040, 0x0050, 0x0054, 0x0058, 0x005C, 0x0060,
+		0x0064, 0x0070, 0x0080, 0x0084, 0x0088, 0x0258, 0x025C, 0x0260,
+		0x0264, 0x0200, 0x0204, 0x0208, 0x020C, 0x0210, 0x0214, 0x0218,
+		0x021C, 0x0220, 0x0224, 0x0228, 0x0100, 0x0104, 0x010C, 0x0110,
+		0x0114, 0x0118, 0x011C, 0x0120, 0x0124, 0x0128, 0x012C};
+
+	struct msm_mercury_hw_cmd hw_cmd;
+	int len = sizeof(mercury_regs)/4;
+	int i;
+
+	MCR_DBG("\n%s\n  (%d)%s()\n", __FILE__, __LINE__, __func__);
+
+	hw_cmd.mask = 0xFFFFFFFF;
+	hw_cmd.type = MSM_MERCURY_HW_CMD_TYPE_READ;
+	hw_cmd.n = 1;
+
+	for (i = 0; i < len; i++) {
+		hw_cmd.offset = mercury_regs[i];
+		msm_mercury_hw_exec_cmds(&hw_cmd, 1);
+	}
+
+	return 0;
+}
+
+int msm_mercury_ioctl_magic_code(struct msm_mercury_device *pmercury_dev,
+	void * __user arg)
+{
+	struct msm_mercury_hw_cmd hw_cmd;
+	int rc = 0;
+
+	rc = copy_from_user(&hw_cmd, arg, sizeof(struct msm_mercury_hw_cmd));
+	if (rc) {
+		printk(KERN_ERR "%s:%d] failed\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+
+	hw_cmd.data = 0x600D600D;
+	rc = copy_to_user(arg, &hw_cmd, sizeof(hw_cmd));
+
+	if (rc) {
+		printk(KERN_ERR "%s:%d] failed\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+int msm_mercury_irq(int event, void *context, void *data)
+{
+	struct msm_mercury_device *pmercury_dev =
+		(struct msm_mercury_device *) context;
+
+	switch (event) {
+	case MSM_MERCURY_HW_IRQ_SW_RESET_ACK:
+		/* wake up evt_q*/
+		MCR_DBG("(%d)%s Wake up event q from Reset IRQ\n", __LINE__,
+			__func__);
+		msm_mercury_q_wakeup(&pmercury_dev->evt_q);
+		break;
+	case MSM_MERCURY_HW_IRQ_WR_EOI_ACK:
+		/*wake up evt_q*/
+		MCR_DBG("%d%s Wake up eventq from WR_EOI IRQ\n", __LINE__,
+			__func__);
+		msm_mercury_q_wr_eoi(&pmercury_dev->evt_q);
+		break;
+	case MSM_MERCURY_HW_IRQ_WR_ERR_ACK:
+		MCR_DBG("(%d)%s Wake up eventq from WR_ERR IRQ\n",
+			__LINE__, __func__);
+		msm_mercury_q_wr_err(&pmercury_dev->evt_q);
+		break;
+	default:
+		MCR_DBG("(%d)%s (default) Wake up event q from WR_ERR IRQ\n",
+			__LINE__, __func__);
+		msm_mercury_q_wr_err(&pmercury_dev->evt_q);
+	}
+	return 0;
+}
+
+int __msm_mercury_open(struct msm_mercury_device *pmercury_dev)
+{
+	int rc = 0;
+
+	mutex_lock(&pmercury_dev->lock);
+	if (pmercury_dev->open_count) {
+		/* only open once */
+		MCR_PR_ERR("%s:%d] busy\n", __func__, __LINE__);
+		mutex_unlock(&pmercury_dev->lock);
+		return -EBUSY;
+	}
+	pmercury_dev->open_count++;
+	mutex_unlock(&pmercury_dev->lock);
+
+	msm_mercury_core_irq_install(msm_mercury_irq);
+
+	rc = msm_mercury_platform_init(pmercury_dev->pdev,
+		&pmercury_dev->mem, &pmercury_dev->base,
+		&pmercury_dev->irq, msm_mercury_core_irq, pmercury_dev);
+	if (rc) {
+		MCR_PR_ERR("%s:%d] platform_init fail %d\n", __func__,
+			__LINE__, rc);
+		return rc;
+	}
+
+	MCR_DBG("\n%s:%d] platform resources - mem 0x%p, base 0x%p, irq %d\n",
+		__func__, __LINE__, pmercury_dev->mem, pmercury_dev->base,
+		pmercury_dev->irq);
+
+	msm_mercury_q_cleanup(&pmercury_dev->evt_q);
+	msm_mercury_core_init();
+
+	MCR_DBG("\n%s:%d] success\n", __func__, __LINE__);
+	return rc;
+}
+
+int __msm_mercury_release(struct msm_mercury_device *pmercury_dev)
+{
+	MCR_DBG("%s:%d] Enter\n", __func__, __LINE__);
+	mutex_lock(&pmercury_dev->lock);
+	if (!pmercury_dev->open_count) {
+		MCR_PR_ERR(KERN_ERR "%s: not opened\n", __func__);
+		mutex_unlock(&pmercury_dev->lock);
+		return -EINVAL;
+	}
+	pmercury_dev->open_count--;
+	mutex_unlock(&pmercury_dev->lock);
+
+	msm_mercury_q_cleanup(&pmercury_dev->evt_q);
+
+	if (pmercury_dev->open_count)
+		MCR_PR_ERR(KERN_ERR "%s: multiple opens\n", __func__);
+
+	if (pmercury_dev->open_count)
+		MCR_PR_ERR(KERN_ERR "%s: multiple opens\n", __func__);
+
+
+	msm_mercury_platform_release(pmercury_dev->mem, pmercury_dev->base,
+		pmercury_dev->irq, pmercury_dev);
+
+	return 0;
+}
+
+int msm_mercury_ioctl_hw_cmd(struct msm_mercury_device *pmercury_dev,
+	void * __user arg)
+{
+	struct msm_mercury_hw_cmd hw_cmd;
+	int is_copy_to_user;
+	int rc = 0;
+
+	rc = copy_from_user(&hw_cmd, arg, sizeof(struct msm_mercury_hw_cmd));
+	if (rc) {
+		MCR_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+
+	is_copy_to_user = msm_mercury_hw_exec_cmds(&hw_cmd, 1);
+	if (is_copy_to_user >= 0) {
+		rc = copy_to_user(arg, &hw_cmd, sizeof(hw_cmd));
+
+		if (rc) {
+			MCR_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
+			return -EFAULT;
+		}
+	}
+
+	return 0;
+}
+
+int msm_mercury_ioctl_hw_cmds(struct msm_mercury_device *pmercury_dev,
+	void * __user arg)
+{
+	int is_copy_to_user;
+	int len;
+	uint32_t m;
+	struct msm_mercury_hw_cmds *hw_cmds_p;
+	struct msm_mercury_hw_cmd *hw_cmd_p;
+
+	if (copy_from_user(&m, arg, sizeof(m))) {
+		MCR_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+
+	len = sizeof(struct msm_mercury_hw_cmds) +
+		sizeof(struct msm_mercury_hw_cmd) * (m - 1);
+	hw_cmds_p = kmalloc(len, GFP_KERNEL);
+	if (!hw_cmds_p) {
+		MCR_PR_ERR("[%d]%s() no mem %d\n", __LINE__, __func__, len);
+		return -EFAULT;
+	}
+
+	if (copy_from_user(hw_cmds_p, arg, len)) {
+		MCR_PR_ERR("[%d]%s Fail to copy hw_cmds of len %d from user\n",
+			__LINE__, __func__, len);
+		kfree(hw_cmds_p);
+		return -EFAULT;
+	}
+
+	hw_cmd_p = (struct msm_mercury_hw_cmd *) &(hw_cmds_p->hw_cmd);
+
+	is_copy_to_user = msm_mercury_hw_exec_cmds(hw_cmd_p, m);
+
+	if (is_copy_to_user >= 0) {
+		if (copy_to_user(arg, hw_cmds_p, len)) {
+			MCR_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
+			kfree(hw_cmds_p);
+			return -EFAULT;
+		}
+	}
+	kfree(hw_cmds_p);
+	return 0;
+}
+
+int msm_mercury_ioctl_reset(struct msm_mercury_device *pmercury_dev,
+	void * __user arg)
+{
+	int rc = 0;
+
+	MCR_DBG("(%d)%s() Enter\n", __LINE__, __func__);
+	rc = msm_mercury_core_reset();
+
+	return rc;
+}
+
+long __msm_mercury_ioctl(struct msm_mercury_device *pmercury_dev,
+	unsigned int cmd, unsigned long arg)
+{
+	int rc = 0;
+
+	switch (cmd) {
+	case MSM_MCR_IOCTL_GET_HW_VERSION:
+		rc = msm_mercury_ioctl_magic_code(pmercury_dev,
+			(void __user *) arg);
+		break;
+
+	case MSM_MCR_IOCTL_RESET:
+		rc = msm_mercury_ioctl_reset(pmercury_dev, (void __user *) arg);
+		break;
+
+	case MSM_MCR_IOCTL_EVT_GET:
+		rc = msm_mercury_evt_get(pmercury_dev, (void __user *) arg);
+		break;
+
+	case MSM_MCR_IOCTL_EVT_GET_UNBLOCK:
+		rc = msm_mercury_evt_get_unblock(pmercury_dev);
+		break;
+
+	case MSM_MCR_IOCTL_HW_CMD:
+		rc = msm_mercury_ioctl_hw_cmd(pmercury_dev,
+			(void __user *) arg);
+		break;
+
+	case MSM_MCR_IOCTL_HW_CMDS:
+		rc = msm_mercury_ioctl_hw_cmds(pmercury_dev,
+			(void __user *) arg);
+		break;
+
+	case MSM_MCR_IOCTL_INPUT_BUF_CFG:
+		rc = msm_mercury_input_buf_cfg(pmercury_dev,
+			(void __user *) arg);
+		break;
+
+	case MSM_MCR_IOCTL_OUTPUT_BUF_CFG:
+		rc = msm_mercury_output_buf_cfg(pmercury_dev,
+			(void __user *) arg);
+		break;
+
+	case MSM_MCR_IOCTL_OUTPUT_GET:
+		rc = msm_mercury_output_get(pmercury_dev,
+			(void __user *) arg);
+		break;
+
+	case MSM_MCR_IOCTL_INPUT_GET:
+		rc = msm_mercury_input_get(pmercury_dev,
+			(void __user *) arg);
+		break;
+
+	case MSM_MCR_IOCTL_TEST_DUMP_REGION:
+		rc = msm_mercury_ioctl_dump_regs();
+		break;
+
+	default:
+		printk(KERN_ERR "(%d)%s()  cmd = %d not supported\n",
+			__LINE__, __func__, _IOC_NR(cmd));
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
+struct msm_mercury_device *__msm_mercury_init(struct platform_device *pdev)
+{
+	struct msm_mercury_device *pmercury_dev;
+	pmercury_dev = kzalloc(sizeof(struct msm_mercury_device), GFP_ATOMIC);
+	if (!pmercury_dev) {
+		printk(KERN_ERR "%s:%d]no mem\n", __func__, __LINE__);
+		return NULL;
+	}
+
+	mutex_init(&pmercury_dev->lock);
+
+	pmercury_dev->pdev = pdev;
+
+	msm_mercury_q_init("evt_q", &pmercury_dev->evt_q);
+
+	return pmercury_dev;
+}
+
+int __msm_mercury_exit(struct msm_mercury_device *pmercury_dev)
+{
+	mutex_destroy(&pmercury_dev->lock);
+	kfree(pmercury_dev);
+	return 0;
+}
+
diff --git a/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_sync.h b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_sync.h
new file mode 100644
index 0000000..a44092f
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_sync.h
@@ -0,0 +1,67 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_MERCURY_SYNC_H
+#define MSM_MERCURY_SYNC_H
+
+#include <linux/fs.h>
+#include <linux/list.h>
+#include <linux/cdev.h>
+#include <linux/platform_device.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+#include "msm_mercury_core.h"
+
+struct msm_mercury_q {
+		char const  *name;
+		struct list_head  q;
+		spinlock_t  lck;
+		wait_queue_head_t wait;
+		int        unblck;
+};
+
+struct msm_mercury_q_entry {
+		struct list_head list;
+		void   *data;
+};
+
+struct msm_mercury_device {
+		struct platform_device *pdev;
+		struct resource        *mem;
+		int                     irq;
+		void                   *base;
+		struct clk *mercury_clk[2];
+		struct device *device;
+		struct cdev   cdev;
+		struct mutex  lock;
+		char      open_count;
+		uint8_t       op_mode;
+
+		/* event queue including frame done & err indications*/
+		struct msm_mercury_q evt_q;
+		struct v4l2_subdev subdev;
+
+};
+
+int __msm_mercury_open(struct msm_mercury_device *pmcry_dev);
+int __msm_mercury_release(struct msm_mercury_device *pmcry_dev);
+
+long __msm_mercury_ioctl(struct msm_mercury_device *pmcry_dev,
+	unsigned int cmd, unsigned long arg);
+
+struct msm_mercury_device *__msm_mercury_init(struct platform_device *pdev);
+int __msm_mercury_exit(struct msm_mercury_device *pmcry_dev);
+int msm_mercury_ioctl_hw_cmds(struct msm_mercury_device *pmcry_dev,
+	void * __user arg);
+int msm_mercury_ioctl_hw_cmds_wo(struct msm_mercury_device *pmcry_dev,
+	void * __user arg);
+#endif /* MSM_MERCURY_SYNC_H */
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/platform/msm/camera_v1/msm.c
similarity index 100%
rename from drivers/media/video/msm/msm.c
rename to drivers/media/platform/msm/camera_v1/msm.c
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/platform/msm/camera_v1/msm.h
similarity index 100%
rename from drivers/media/video/msm/msm.h
rename to drivers/media/platform/msm/camera_v1/msm.h
diff --git a/drivers/media/platform/msm/camera_v1/msm_axi_qos.c b/drivers/media/platform/msm/camera_v1/msm_axi_qos.c
new file mode 100644
index 0000000..ac484d3
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/msm_axi_qos.c
@@ -0,0 +1,50 @@
+/* Copyright (c) 2009, 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/clk.h>
+#include <mach/camera.h>
+#define MSM_AXI_QOS_NAME "msm_camera"
+
+static struct clk *ebi1_clk;
+
+int add_axi_qos(void)
+{
+	ebi1_clk = clk_get(NULL, "ebi1_vfe_clk");
+	if (IS_ERR(ebi1_clk))
+		ebi1_clk = NULL;
+	else {
+		clk_prepare(ebi1_clk);
+		clk_enable(ebi1_clk);
+	}
+
+	return 0;
+}
+
+int update_axi_qos(uint32_t rate)
+{
+	if (!ebi1_clk)
+		return 0;
+
+	return clk_set_rate(ebi1_clk, rate * 1000);
+}
+
+void release_axi_qos(void)
+{
+	if (!ebi1_clk)
+		return;
+
+	clk_disable(ebi1_clk);
+	clk_unprepare(ebi1_clk);
+	clk_put(ebi1_clk);
+	ebi1_clk = NULL;
+}
diff --git a/drivers/media/platform/msm/camera_v1/msm_camera.c b/drivers/media/platform/msm/camera_v1/msm_camera.c
new file mode 100644
index 0000000..622ecfd
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/msm_camera.c
@@ -0,0 +1,4073 @@
+/* Copyright (c) 2009-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.
+ *
+ */
+//FIXME: most allocations need not be GFP_ATOMIC
+/* FIXME: management of mutexes */
+/* FIXME: msm_pmem_region_lookup return values */
+/* FIXME: way too many copy to/from user */
+/* FIXME: does region->active mean free */
+/* FIXME: check limits on command lenghts passed from userspace */
+/* FIXME: __msm_release: which queues should we flush when opencnt != 0 */
+
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <mach/board.h>
+
+#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/list.h>
+#include <linux/uaccess.h>
+#include <linux/android_pmem.h>
+#include <linux/poll.h>
+#include <media/msm_camera.h>
+#include <mach/camera.h>
+#include <linux/syscalls.h>
+#include <linux/hrtimer.h>
+#include <linux/msm_ion.h>
+
+#include <mach/cpuidle.h>
+DEFINE_MUTEX(ctrl_cmd_lock);
+
+#define CAMERA_STOP_VIDEO 58
+spinlock_t pp_prev_spinlock;
+spinlock_t pp_stereocam_spinlock;
+spinlock_t st_frame_spinlock;
+
+#define ERR_USER_COPY(to) pr_err("%s(%d): copy %s user\n", \
+				__func__, __LINE__, ((to) ? "to" : "from"))
+#define ERR_COPY_FROM_USER() ERR_USER_COPY(0)
+#define ERR_COPY_TO_USER() ERR_USER_COPY(1)
+#define MAX_PMEM_CFG_BUFFERS 10
+
+static struct class *msm_class;
+static dev_t msm_devno;
+static LIST_HEAD(msm_sensors);
+struct  msm_control_device *g_v4l2_control_device;
+int g_v4l2_opencnt;
+static int camera_node;
+static enum msm_camera_type camera_type[MSM_MAX_CAMERA_SENSORS];
+static uint32_t sensor_mount_angle[MSM_MAX_CAMERA_SENSORS];
+
+struct ion_client *client_for_ion;
+
+static const char *vfe_config_cmd[] = {
+	"CMD_GENERAL",  /* 0 */
+	"CMD_AXI_CFG_OUT1",
+	"CMD_AXI_CFG_SNAP_O1_AND_O2",
+	"CMD_AXI_CFG_OUT2",
+	"CMD_PICT_T_AXI_CFG",
+	"CMD_PICT_M_AXI_CFG",  /* 5 */
+	"CMD_RAW_PICT_AXI_CFG",
+	"CMD_FRAME_BUF_RELEASE",
+	"CMD_PREV_BUF_CFG",
+	"CMD_SNAP_BUF_RELEASE",
+	"CMD_SNAP_BUF_CFG",  /* 10 */
+	"CMD_STATS_DISABLE",
+	"CMD_STATS_AEC_AWB_ENABLE",
+	"CMD_STATS_AF_ENABLE",
+	"CMD_STATS_AEC_ENABLE",
+	"CMD_STATS_AWB_ENABLE",  /* 15 */
+	"CMD_STATS_ENABLE",
+	"CMD_STATS_AXI_CFG",
+	"CMD_STATS_AEC_AXI_CFG",
+	"CMD_STATS_AF_AXI_CFG",
+	"CMD_STATS_AWB_AXI_CFG",  /* 20 */
+	"CMD_STATS_RS_AXI_CFG",
+	"CMD_STATS_CS_AXI_CFG",
+	"CMD_STATS_IHIST_AXI_CFG",
+	"CMD_STATS_SKIN_AXI_CFG",
+	"CMD_STATS_BUF_RELEASE",  /* 25 */
+	"CMD_STATS_AEC_BUF_RELEASE",
+	"CMD_STATS_AF_BUF_RELEASE",
+	"CMD_STATS_AWB_BUF_RELEASE",
+	"CMD_STATS_RS_BUF_RELEASE",
+	"CMD_STATS_CS_BUF_RELEASE",  /* 30 */
+	"CMD_STATS_IHIST_BUF_RELEASE",
+	"CMD_STATS_SKIN_BUF_RELEASE",
+	"UPDATE_STATS_INVALID",
+	"CMD_AXI_CFG_SNAP_GEMINI",
+	"CMD_AXI_CFG_SNAP",  /* 35 */
+	"CMD_AXI_CFG_PREVIEW",
+	"CMD_AXI_CFG_VIDEO",
+	"CMD_STATS_IHIST_ENABLE",
+	"CMD_STATS_RS_ENABLE",
+	"CMD_STATS_CS_ENABLE",  /* 40 */
+	"CMD_VPE",
+	"CMD_AXI_CFG_VPE",
+	"CMD_AXI_CFG_SNAP_VPE",
+	"CMD_AXI_CFG_SNAP_THUMB_VPE",
+};
+#define __CONTAINS(r, v, l, field) ({				\
+	typeof(r) __r = r;					\
+	typeof(v) __v = v;					\
+	typeof(v) __e = __v + l;				\
+	int res = __v >= __r->field &&				\
+		__e <= __r->field + __r->len;			\
+	res;							\
+})
+
+#define CONTAINS(r1, r2, field) ({				\
+	typeof(r2) __r2 = r2;					\
+	__CONTAINS(r1, __r2->field, __r2->len, field);		\
+})
+
+#define IN_RANGE(r, v, field) ({				\
+	typeof(r) __r = r;					\
+	typeof(v) __vv = v;					\
+	int res = ((__vv >= __r->field) &&			\
+		(__vv < (__r->field + __r->len)));		\
+	res;							\
+})
+
+#define OVERLAPS(r1, r2, field) ({				\
+	typeof(r1) __r1 = r1;					\
+	typeof(r2) __r2 = r2;					\
+	typeof(__r2->field) __v = __r2->field;			\
+	typeof(__v) __e = __v + __r2->len - 1;			\
+	int res = (IN_RANGE(__r1, __v, field) ||		\
+		   IN_RANGE(__r1, __e, field));                 \
+	res;							\
+})
+
+static inline void free_qcmd(struct msm_queue_cmd *qcmd)
+{
+	if (!qcmd || !atomic_read(&qcmd->on_heap))
+		return;
+	if (!atomic_sub_return(1, &qcmd->on_heap))
+		kfree(qcmd);
+}
+
+static void msm_region_init(struct msm_sync *sync)
+{
+	INIT_HLIST_HEAD(&sync->pmem_frames);
+	INIT_HLIST_HEAD(&sync->pmem_stats);
+	spin_lock_init(&sync->pmem_frame_spinlock);
+	spin_lock_init(&sync->pmem_stats_spinlock);
+}
+
+static void msm_queue_init(struct msm_device_queue *queue, const char *name)
+{
+	spin_lock_init(&queue->lock);
+	queue->len = 0;
+	queue->max = 0;
+	queue->name = name;
+	INIT_LIST_HEAD(&queue->list);
+	init_waitqueue_head(&queue->wait);
+}
+
+static void msm_enqueue(struct msm_device_queue *queue,
+		struct list_head *entry)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&queue->lock, flags);
+	queue->len++;
+	if (queue->len > queue->max) {
+		queue->max = queue->len;
+		CDBG("%s: queue %s new max is %d\n", __func__,
+			queue->name, queue->max);
+	}
+	list_add_tail(entry, &queue->list);
+	wake_up(&queue->wait);
+	CDBG("%s: woke up %s\n", __func__, queue->name);
+	spin_unlock_irqrestore(&queue->lock, flags);
+}
+
+static void msm_enqueue_vpe(struct msm_device_queue *queue,
+		struct list_head *entry)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&queue->lock, flags);
+	queue->len++;
+	if (queue->len > queue->max) {
+		queue->max = queue->len;
+		CDBG("%s: queue %s new max is %d\n", __func__,
+			queue->name, queue->max);
+	}
+	list_add_tail(entry, &queue->list);
+    CDBG("%s: woke up %s\n", __func__, queue->name);
+	spin_unlock_irqrestore(&queue->lock, flags);
+}
+
+#define msm_dequeue(queue, member) ({				\
+	unsigned long flags;					\
+	struct msm_device_queue *__q = (queue);			\
+	struct msm_queue_cmd *qcmd = 0;				\
+	spin_lock_irqsave(&__q->lock, flags);			\
+	if (!list_empty(&__q->list)) {				\
+		__q->len--;					\
+		qcmd = list_first_entry(&__q->list,		\
+				struct msm_queue_cmd, member);	\
+		if ((qcmd) && (&qcmd->member) && (&qcmd->member.next))	\
+			list_del_init(&qcmd->member);			\
+	}							\
+	spin_unlock_irqrestore(&__q->lock, flags);	\
+	qcmd;							\
+})
+
+#define msm_delete_entry(queue, member, q_cmd) ({		\
+	unsigned long flags;					\
+	struct msm_device_queue *__q = (queue);			\
+	struct msm_queue_cmd *qcmd = 0;				\
+	spin_lock_irqsave(&__q->lock, flags);			\
+	if (!list_empty(&__q->list)) {				\
+		list_for_each_entry(qcmd, &__q->list, member)	\
+		if (qcmd == q_cmd) {				\
+			__q->len--;				\
+			list_del_init(&qcmd->member);		\
+			CDBG("msm_delete_entry, match found\n");\
+			kfree(q_cmd);				\
+			q_cmd = NULL;				\
+			break;					\
+		}						\
+	}							\
+	spin_unlock_irqrestore(&__q->lock, flags);		\
+	q_cmd;		\
+})
+
+#define msm_queue_drain(queue, member) do {			\
+	unsigned long flags;					\
+	struct msm_device_queue *__q = (queue);			\
+	struct msm_queue_cmd *qcmd;				\
+	spin_lock_irqsave(&__q->lock, flags);			\
+	while (!list_empty(&__q->list)) {			\
+		__q->len--;					\
+		qcmd = list_first_entry(&__q->list,		\
+			struct msm_queue_cmd, member);		\
+		if (qcmd) {					\
+			if (&qcmd->member)	\
+				list_del_init(&qcmd->member);		\
+			free_qcmd(qcmd);				\
+		}							\
+	}							\
+	spin_unlock_irqrestore(&__q->lock, flags);		\
+} while (0)
+
+static int check_overlap(struct hlist_head *ptype,
+			unsigned long paddr,
+			unsigned long len)
+{
+	struct msm_pmem_region *region;
+	struct msm_pmem_region t = { .paddr = paddr, .len = len };
+	struct hlist_node *node;
+
+	hlist_for_each_entry(region, node, ptype, list) {
+		if (CONTAINS(region, &t, paddr) ||
+				CONTAINS(&t, region, paddr) ||
+				OVERLAPS(region, &t, paddr)) {
+			CDBG(" region (PHYS %p len %ld)"
+				" clashes with registered region"
+				" (paddr %p len %ld)\n",
+				(void *)t.paddr, t.len,
+				(void *)region->paddr, region->len);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static int check_pmem_info(struct msm_pmem_info *info, int len)
+{
+	if (info->offset < len &&
+	    info->offset + info->len <= len &&
+	    info->planar0_off < len &&
+	    info->planar1_off < len &&
+	    info->planar2_off < len)
+		return 0;
+
+	pr_err("%s: check failed: off %d len %d y 0x%x cbcr_p1 0x%x p2_add 0x%x(total len %d)\n",
+		__func__,
+		info->offset,
+		info->len,
+		info->planar0_off,
+		info->planar1_off,
+		info->planar2_off,
+		len);
+	return -EINVAL;
+}
+static int msm_pmem_table_add(struct hlist_head *ptype,
+	struct msm_pmem_info *info, spinlock_t* pmem_spinlock,
+	struct msm_sync *sync)
+{
+	unsigned long paddr;
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
+	struct file *file;
+	unsigned long kvstart;
+#endif
+	unsigned long len;
+	int rc = -ENOMEM;
+	struct msm_pmem_region *region;
+	unsigned long flags;
+
+	region = kmalloc(sizeof(struct msm_pmem_region), GFP_KERNEL);
+	if (!region)
+		goto out;
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+		region->handle = ion_import_dma_buf(client_for_ion, info->fd);
+		if (IS_ERR_OR_NULL(region->handle))
+			goto out1;
+		ion_phys(client_for_ion, region->handle,
+			&paddr, (size_t *)&len);
+#else
+	rc = get_pmem_file(info->fd, &paddr, &kvstart, &len, &file);
+	if (rc < 0) {
+		pr_err("%s: get_pmem_file fd %d error %d\n",
+			__func__,
+			info->fd, rc);
+		goto out1;
+	}
+	region->file = file;
+#endif
+	if (!info->len)
+		info->len = len;
+
+	rc = check_pmem_info(info, len);
+	if (rc < 0)
+		goto out2;
+
+	paddr += info->offset;
+	len = info->len;
+
+	spin_lock_irqsave(pmem_spinlock, flags);
+	if (check_overlap(ptype, paddr, len) < 0) {
+		spin_unlock_irqrestore(pmem_spinlock, flags);
+		rc = -EINVAL;
+		goto out2;
+	}
+	spin_unlock_irqrestore(pmem_spinlock, flags);
+
+	spin_lock_irqsave(pmem_spinlock, flags);
+	INIT_HLIST_NODE(&region->list);
+
+	region->paddr = paddr;
+	region->len = len;
+	memcpy(&region->info, info, sizeof(region->info));
+
+	hlist_add_head(&(region->list), ptype);
+	spin_unlock_irqrestore(pmem_spinlock, flags);
+	CDBG("%s: type %d, paddr 0x%lx, vaddr 0x%lx p0_add = 0x%x"
+		"p1_addr = 0x%x p2_addr = 0x%x\n",
+		__func__, info->type, paddr, (unsigned long)info->vaddr,
+		info->planar0_off, info->planar1_off, info->planar2_off);
+	return 0;
+out2:
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	ion_free(client_for_ion, region->handle);
+#else
+	put_pmem_file(region->file);
+#endif
+out1:
+	kfree(region);
+out:
+	return rc;
+}
+
+/* return of 0 means failure */
+static uint8_t msm_pmem_region_lookup(struct hlist_head *ptype,
+	int pmem_type, struct msm_pmem_region *reg, uint8_t maxcount,
+	spinlock_t *pmem_spinlock)
+{
+	struct msm_pmem_region *region;
+	struct msm_pmem_region *regptr;
+	struct hlist_node *node, *n;
+	unsigned long flags = 0;
+
+	uint8_t rc = 0;
+
+	regptr = reg;
+	spin_lock_irqsave(pmem_spinlock, flags);
+	hlist_for_each_entry_safe(region, node, n, ptype, list) {
+		if (region->info.type == pmem_type && region->info.active) {
+			*regptr = *region;
+			rc += 1;
+			if (rc >= maxcount)
+				break;
+			regptr++;
+		}
+	}
+	spin_unlock_irqrestore(pmem_spinlock, flags);
+	/* After lookup failure, dump all the list entries...*/
+	if (rc == 0) {
+		pr_err("%s: pmem_type = %d\n", __func__, pmem_type);
+		hlist_for_each_entry_safe(region, node, n, ptype, list) {
+			pr_err("listed region->info.type = %d, active = %d",
+				region->info.type, region->info.active);
+		}
+
+	}
+	return rc;
+}
+
+static uint8_t msm_pmem_region_lookup_2(struct hlist_head *ptype,
+					int pmem_type,
+					struct msm_pmem_region *reg,
+					uint8_t maxcount,
+					spinlock_t *pmem_spinlock)
+{
+	struct msm_pmem_region *region;
+	struct msm_pmem_region *regptr;
+	struct hlist_node *node, *n;
+	uint8_t rc = 0;
+	unsigned long flags = 0;
+	regptr = reg;
+	spin_lock_irqsave(pmem_spinlock, flags);
+	hlist_for_each_entry_safe(region, node, n, ptype, list) {
+		CDBG("%s:info.type=%d, pmem_type = %d,"
+						"info.active = %d\n",
+		__func__, region->info.type, pmem_type, region->info.active);
+
+		if (region->info.type == pmem_type && region->info.active) {
+			CDBG("%s:info.type=%d, pmem_type = %d,"
+							"info.active = %d,\n",
+				__func__, region->info.type, pmem_type,
+				region->info.active);
+			*regptr = *region;
+			region->info.type = MSM_PMEM_VIDEO;
+			rc += 1;
+			if (rc >= maxcount)
+				break;
+			regptr++;
+		}
+	}
+	spin_unlock_irqrestore(pmem_spinlock, flags);
+	return rc;
+}
+
+static int msm_pmem_frame_ptov_lookup(struct msm_sync *sync,
+		unsigned long p0addr,
+		unsigned long p1addr,
+		unsigned long p2addr,
+		struct msm_pmem_info *pmem_info,
+		int clear_active)
+{
+	struct msm_pmem_region *region;
+	struct hlist_node *node, *n;
+	unsigned long flags = 0;
+
+	spin_lock_irqsave(&sync->pmem_frame_spinlock, flags);
+	hlist_for_each_entry_safe(region, node, n, &sync->pmem_frames, list) {
+		if (p0addr == (region->paddr + region->info.planar0_off) &&
+			p1addr == (region->paddr + region->info.planar1_off) &&
+			p2addr == (region->paddr + region->info.planar2_off) &&
+			region->info.active) {
+			/* offset since we could pass vaddr inside
+			 * a registerd pmem buffer
+			 */
+			memcpy(pmem_info, &region->info, sizeof(*pmem_info));
+			if (clear_active)
+				region->info.active = 0;
+			spin_unlock_irqrestore(&sync->pmem_frame_spinlock,
+				flags);
+			return 0;
+		}
+	}
+	/* After lookup failure, dump all the list entries... */
+	pr_err("%s, for plane0 addr = 0x%lx, plane1 addr = 0x%lx  plane2 addr = 0x%lx\n",
+			__func__, p0addr, p1addr, p2addr);
+	hlist_for_each_entry_safe(region, node, n, &sync->pmem_frames, list) {
+		pr_err("listed p0addr 0x%lx, p1addr 0x%lx, p2addr 0x%lx, active = %d",
+				(region->paddr + region->info.planar0_off),
+				(region->paddr + region->info.planar1_off),
+				(region->paddr + region->info.planar2_off),
+				region->info.active);
+	}
+
+	spin_unlock_irqrestore(&sync->pmem_frame_spinlock, flags);
+	return -EINVAL;
+}
+
+static int msm_pmem_frame_ptov_lookup2(struct msm_sync *sync,
+		unsigned long p0_phy,
+		struct msm_pmem_info *pmem_info,
+		int clear_active)
+{
+	struct msm_pmem_region *region;
+	struct hlist_node *node, *n;
+	unsigned long flags = 0;
+
+	spin_lock_irqsave(&sync->pmem_frame_spinlock, flags);
+	hlist_for_each_entry_safe(region, node, n, &sync->pmem_frames, list) {
+		if (p0_phy == (region->paddr + region->info.planar0_off) &&
+				region->info.active) {
+			/* offset since we could pass vaddr inside
+			 * a registerd pmem buffer
+			 */
+			memcpy(pmem_info, &region->info, sizeof(*pmem_info));
+			if (clear_active)
+				region->info.active = 0;
+			spin_unlock_irqrestore(&sync->pmem_frame_spinlock,
+				flags);
+			return 0;
+		}
+	}
+
+	spin_unlock_irqrestore(&sync->pmem_frame_spinlock, flags);
+	return -EINVAL;
+}
+
+static unsigned long msm_pmem_stats_ptov_lookup(struct msm_sync *sync,
+		unsigned long addr, int *fd)
+{
+	struct msm_pmem_region *region;
+	struct hlist_node *node, *n;
+	unsigned long flags = 0;
+
+	spin_lock_irqsave(&sync->pmem_stats_spinlock, flags);
+	hlist_for_each_entry_safe(region, node, n, &sync->pmem_stats, list) {
+		if (addr == region->paddr && region->info.active) {
+			/* offset since we could pass vaddr inside a
+			 * registered pmem buffer */
+			*fd = region->info.fd;
+			region->info.active = 0;
+			spin_unlock_irqrestore(&sync->pmem_stats_spinlock,
+				flags);
+			return (unsigned long)(region->info.vaddr);
+		}
+	}
+	/* After lookup failure, dump all the list entries... */
+	pr_err("%s, lookup failure, for paddr 0x%lx\n",
+			__func__, addr);
+	hlist_for_each_entry_safe(region, node, n, &sync->pmem_stats, list) {
+		pr_err("listed paddr 0x%lx, active = %d",
+				region->paddr,
+				region->info.active);
+	}
+	spin_unlock_irqrestore(&sync->pmem_stats_spinlock, flags);
+
+	return 0;
+}
+
+static unsigned long msm_pmem_frame_vtop_lookup(struct msm_sync *sync,
+		unsigned long buffer, uint32_t p0_off, uint32_t p1_off,
+		uint32_t p2_off, int fd, int change_flag)
+{
+	struct msm_pmem_region *region;
+	struct hlist_node *node, *n;
+	unsigned long flags = 0;
+
+	spin_lock_irqsave(&sync->pmem_frame_spinlock, flags);
+	hlist_for_each_entry_safe(region,
+		node, n, &sync->pmem_frames, list) {
+		if (((unsigned long)(region->info.vaddr) == buffer) &&
+				(region->info.planar0_off == p0_off) &&
+				(region->info.planar1_off == p1_off) &&
+				(region->info.planar2_off == p2_off) &&
+				(region->info.fd == fd) &&
+				(region->info.active == 0)) {
+			if (change_flag)
+				region->info.active = 1;
+			spin_unlock_irqrestore(&sync->pmem_frame_spinlock,
+				flags);
+			return region->paddr;
+		}
+	}
+	/* After lookup failure, dump all the list entries... */
+	pr_err("%s, failed for vaddr 0x%lx, p0_off %d p1_off %d\n",
+			__func__, buffer, p0_off, p1_off);
+	hlist_for_each_entry_safe(region, node, n, &sync->pmem_frames, list) {
+		pr_err("%s, listed vaddr 0x%lx, r_p0 = 0x%x p0_off 0x%x"
+			"r_p1 = 0x%x, p1_off 0x%x, r_p2 = 0x%x, p2_off = 0x%x"
+			" active = %d\n", __func__, buffer,
+			region->info.planar0_off,
+			p0_off, region->info.planar1_off,
+			p1_off, region->info.planar2_off, p2_off,
+			region->info.active);
+	}
+
+	spin_unlock_irqrestore(&sync->pmem_frame_spinlock, flags);
+
+	return 0;
+}
+
+static unsigned long msm_pmem_stats_vtop_lookup(
+		struct msm_sync *sync,
+		unsigned long buffer,
+		int fd)
+{
+	struct msm_pmem_region *region;
+	struct hlist_node *node, *n;
+	unsigned long flags = 0;
+
+	spin_lock_irqsave(&sync->pmem_stats_spinlock, flags);
+	hlist_for_each_entry_safe(region, node, n, &sync->pmem_stats, list) {
+		if (((unsigned long)(region->info.vaddr) == buffer) &&
+				(region->info.fd == fd) &&
+				region->info.active == 0) {
+			region->info.active = 1;
+			spin_unlock_irqrestore(&sync->pmem_stats_spinlock,
+				flags);
+			return region->paddr;
+		}
+	}
+	/* After lookup failure, dump all the list entries... */
+	pr_err("%s,look up error for vaddr %ld\n",
+			__func__, buffer);
+	hlist_for_each_entry_safe(region, node, n, &sync->pmem_stats, list) {
+		pr_err("listed vaddr 0x%p, active = %d",
+				region->info.vaddr,
+				region->info.active);
+	}
+	spin_unlock_irqrestore(&sync->pmem_stats_spinlock, flags);
+
+	return 0;
+}
+
+static int __msm_pmem_table_del(struct msm_sync *sync,
+		struct msm_pmem_info *pinfo)
+{
+	int rc = 0;
+	struct msm_pmem_region *region;
+	struct hlist_node *node, *n;
+	unsigned long flags = 0;
+
+	switch (pinfo->type) {
+	case MSM_PMEM_PREVIEW:
+	case MSM_PMEM_THUMBNAIL:
+	case MSM_PMEM_MAINIMG:
+	case MSM_PMEM_RAW_MAINIMG:
+	case MSM_PMEM_C2D:
+	case MSM_PMEM_MAINIMG_VPE:
+	case MSM_PMEM_THUMBNAIL_VPE:
+		spin_lock_irqsave(&sync->pmem_frame_spinlock, flags);
+		hlist_for_each_entry_safe(region, node, n,
+			&sync->pmem_frames, list) {
+
+			if (pinfo->type == region->info.type &&
+					pinfo->vaddr == region->info.vaddr &&
+					pinfo->fd == region->info.fd) {
+				hlist_del(node);
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+				ion_free(client_for_ion, region->handle);
+#else
+				put_pmem_file(region->file);
+#endif
+				kfree(region);
+				CDBG("%s: type %d, vaddr  0x%p\n",
+					__func__, pinfo->type, pinfo->vaddr);
+			}
+		}
+		spin_unlock_irqrestore(&sync->pmem_frame_spinlock, flags);
+		break;
+
+	case MSM_PMEM_VIDEO:
+	case MSM_PMEM_VIDEO_VPE:
+		spin_lock_irqsave(&sync->pmem_frame_spinlock, flags);
+		hlist_for_each_entry_safe(region, node, n,
+			&sync->pmem_frames, list) {
+
+			if (((region->info.type == MSM_PMEM_VIDEO) ||
+				(region->info.type == MSM_PMEM_VIDEO_VPE)) &&
+				pinfo->vaddr == region->info.vaddr &&
+				pinfo->fd == region->info.fd) {
+				hlist_del(node);
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+				ion_free(client_for_ion, region->handle);
+#else
+				put_pmem_file(region->file);
+#endif
+				kfree(region);
+				CDBG("%s: type %d, vaddr  0x%p\n",
+					__func__, pinfo->type, pinfo->vaddr);
+			}
+		}
+		spin_unlock_irqrestore(&sync->pmem_frame_spinlock, flags);
+		break;
+
+	case MSM_PMEM_AEC_AWB:
+	case MSM_PMEM_AF:
+		spin_lock_irqsave(&sync->pmem_stats_spinlock, flags);
+		hlist_for_each_entry_safe(region, node, n,
+			&sync->pmem_stats, list) {
+
+			if (pinfo->type == region->info.type &&
+					pinfo->vaddr == region->info.vaddr &&
+					pinfo->fd == region->info.fd) {
+				hlist_del(node);
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+				ion_free(client_for_ion, region->handle);
+#else
+				put_pmem_file(region->file);
+#endif
+				kfree(region);
+				CDBG("%s: type %d, vaddr  0x%p\n",
+					__func__, pinfo->type, pinfo->vaddr);
+			}
+		}
+		spin_unlock_irqrestore(&sync->pmem_stats_spinlock, flags);
+		break;
+
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
+static int msm_pmem_table_del(struct msm_sync *sync, void __user *arg)
+{
+	struct msm_pmem_info info;
+
+	if (copy_from_user(&info, arg, sizeof(info))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	return __msm_pmem_table_del(sync, &info);
+}
+
+static int __msm_get_frame(struct msm_sync *sync,
+		struct msm_frame *frame)
+{
+	int rc = 0;
+
+	struct msm_pmem_info pmem_info;
+	struct msm_queue_cmd *qcmd = NULL;
+	struct msm_vfe_resp *vdata;
+	struct msm_vfe_phy_info *pphy;
+
+	qcmd = msm_dequeue(&sync->frame_q, list_frame);
+
+	if (!qcmd) {
+		pr_err("%s: no preview frame.\n", __func__);
+		return -EAGAIN;
+	}
+
+	if ((!qcmd->command) && (qcmd->error_code & MSM_CAMERA_ERR_MASK)) {
+		frame->error_code = qcmd->error_code;
+		pr_err("%s: fake frame with camera error code = %d\n",
+			__func__, frame->error_code);
+		goto err;
+	}
+
+	vdata = (struct msm_vfe_resp *)(qcmd->command);
+	pphy = &vdata->phy;
+	CDBG("%s, pphy->p2_phy = 0x%x\n", __func__, pphy->p2_phy);
+
+	rc = msm_pmem_frame_ptov_lookup(sync,
+			pphy->p0_phy,
+			pphy->p1_phy,
+			pphy->p2_phy,
+			&pmem_info,
+			1); /* Clear the active flag */
+
+	if (rc < 0) {
+		pr_err("%s: cannot get frame, invalid lookup address"
+		"plane0 add %x plane1 add %x plane2 add%x\n",
+		__func__,
+		pphy->p0_phy,
+		pphy->p1_phy,
+		pphy->p2_phy);
+		goto err;
+	}
+
+	frame->ts = qcmd->ts;
+	frame->buffer = (unsigned long)pmem_info.vaddr;
+	frame->planar0_off = pmem_info.planar0_off;
+	frame->planar1_off = pmem_info.planar1_off;
+	frame->planar2_off = pmem_info.planar2_off;
+	frame->fd = pmem_info.fd;
+	frame->path = vdata->phy.output_id;
+	frame->frame_id = vdata->phy.frame_id;
+	CDBG("%s: plane0 %x, plane1 %x, plane2 %x,qcmd %x, virt_addr %x\n",
+		__func__, pphy->p0_phy, pphy->p1_phy, pphy->p2_phy,
+		(int) qcmd, (int) frame->buffer);
+
+err:
+	free_qcmd(qcmd);
+	return rc;
+}
+
+static int msm_get_frame(struct msm_sync *sync, void __user *arg)
+{
+	int rc = 0;
+	struct msm_frame frame;
+
+	if (copy_from_user(&frame,
+				arg,
+				sizeof(struct msm_frame))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	rc = __msm_get_frame(sync, &frame);
+	if (rc < 0)
+		return rc;
+
+	mutex_lock(&sync->lock);
+	if (sync->croplen && (!sync->stereocam_enabled)) {
+		if (frame.croplen != sync->croplen) {
+			pr_err("%s: invalid frame croplen %d,"
+				"expecting %d\n",
+				__func__,
+				frame.croplen,
+				sync->croplen);
+			mutex_unlock(&sync->lock);
+			return -EINVAL;
+		}
+
+		if (copy_to_user((void *)frame.cropinfo,
+				sync->cropinfo,
+				sync->croplen)) {
+			ERR_COPY_TO_USER();
+			mutex_unlock(&sync->lock);
+			return -EFAULT;
+		}
+	}
+
+	if (sync->fdroiinfo.info) {
+		if (copy_to_user((void *)frame.roi_info.info,
+			sync->fdroiinfo.info,
+			sync->fdroiinfo.info_len)) {
+			ERR_COPY_TO_USER();
+			mutex_unlock(&sync->lock);
+			return -EFAULT;
+		}
+	}
+
+	if (sync->stereocam_enabled) {
+		frame.stcam_conv_value = sync->stcam_conv_value;
+		frame.stcam_quality_ind = sync->stcam_quality_ind;
+	}
+
+	if (copy_to_user((void *)arg,
+				&frame, sizeof(struct msm_frame))) {
+		ERR_COPY_TO_USER();
+		rc = -EFAULT;
+	}
+
+	mutex_unlock(&sync->lock);
+	CDBG("%s: got frame\n", __func__);
+
+	return rc;
+}
+
+static int msm_enable_vfe(struct msm_sync *sync, void __user *arg)
+{
+	int rc = -EIO;
+	struct camera_enable_cmd cfg;
+
+	if (copy_from_user(&cfg,
+			arg,
+			sizeof(struct camera_enable_cmd))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	if (sync->vfefn.vfe_enable)
+		rc = sync->vfefn.vfe_enable(&cfg);
+
+	return rc;
+}
+
+static int msm_disable_vfe(struct msm_sync *sync, void __user *arg)
+{
+	int rc = -EIO;
+	struct camera_enable_cmd cfg;
+
+	if (copy_from_user(&cfg,
+			arg,
+			sizeof(struct camera_enable_cmd))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	if (sync->vfefn.vfe_disable)
+		rc = sync->vfefn.vfe_disable(&cfg, NULL);
+
+	return rc;
+}
+
+static struct msm_queue_cmd *__msm_control(struct msm_sync *sync,
+		struct msm_device_queue *queue,
+		struct msm_queue_cmd *qcmd,
+		int timeout)
+{
+	int rc;
+
+	CDBG("Inside __msm_control\n");
+	if (sync->event_q.len <= 100 && sync->frame_q.len <= 100) {
+		/* wake up config thread */
+		msm_enqueue(&sync->event_q, &qcmd->list_config);
+	} else {
+		pr_err("%s, Error Queue limit exceeded e_q = %d, f_q = %d\n",
+			__func__, sync->event_q.len, sync->frame_q.len);
+		free_qcmd(qcmd);
+		return NULL;
+	}
+	if (!queue)
+		return NULL;
+
+	/* wait for config status */
+	CDBG("Waiting for config status \n");
+	rc = wait_event_interruptible_timeout(
+			queue->wait,
+			!list_empty_careful(&queue->list),
+			timeout);
+	CDBG("Waiting over for config status\n");
+	if (list_empty_careful(&queue->list)) {
+		if (!rc) {
+			rc = -ETIMEDOUT;
+			pr_err("%s: wait_event error %d\n", __func__, rc);
+			return ERR_PTR(rc);
+		} else if (rc < 0) {
+			pr_err("%s: wait_event error %d\n", __func__, rc);
+			if (msm_delete_entry(&sync->event_q,
+				list_config, qcmd)) {
+				sync->ignore_qcmd = true;
+				sync->ignore_qcmd_type =
+					(int16_t)((struct msm_ctrl_cmd *)
+					(qcmd->command))->type;
+			}
+			return ERR_PTR(rc);
+		}
+	}
+	qcmd = msm_dequeue(queue, list_control);
+	BUG_ON(!qcmd);
+	CDBG("__msm_control done \n");
+	return qcmd;
+}
+
+static struct msm_queue_cmd *__msm_control_nb(struct msm_sync *sync,
+					struct msm_queue_cmd *qcmd_to_copy)
+{
+	/* Since this is a non-blocking command, we cannot use qcmd_to_copy and
+	 * its data, since they are on the stack.  We replicate them on the heap
+	 * and mark them on_heap so that they get freed when the config thread
+	 * dequeues them.
+	 */
+
+	struct msm_ctrl_cmd *udata;
+	struct msm_ctrl_cmd *udata_to_copy = qcmd_to_copy->command;
+
+	struct msm_queue_cmd *qcmd =
+			kmalloc(sizeof(*qcmd_to_copy) +
+				sizeof(*udata_to_copy) +
+				udata_to_copy->length,
+				GFP_KERNEL);
+	if (!qcmd) {
+		pr_err("%s: out of memory\n", __func__);
+		return ERR_PTR(-ENOMEM);
+	}
+	*qcmd = *qcmd_to_copy;
+	udata = qcmd->command = qcmd + 1;
+	memcpy(udata, udata_to_copy, sizeof(*udata));
+	udata->value = udata + 1;
+	memcpy(udata->value, udata_to_copy->value, udata_to_copy->length);
+
+	atomic_set(&qcmd->on_heap, 1);
+
+	/* qcmd_resp will be set to NULL */
+	return __msm_control(sync, NULL, qcmd, 0);
+}
+
+static int msm_control(struct msm_control_device *ctrl_pmsm,
+			int block,
+			void __user *arg)
+{
+	int rc = 0;
+
+	struct msm_sync *sync = ctrl_pmsm->pmsm->sync;
+	void __user *uptr;
+	struct msm_ctrl_cmd udata_resp;
+	struct msm_queue_cmd *qcmd_resp = NULL;
+	uint8_t data[max_control_command_size];
+	struct msm_ctrl_cmd *udata;
+	struct msm_queue_cmd *qcmd =
+		kmalloc(sizeof(struct msm_queue_cmd) +
+			sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
+	if (!qcmd) {
+		pr_err("%s: out of memory\n", __func__);
+		return -ENOMEM;
+	}
+	udata = (struct msm_ctrl_cmd *)(qcmd + 1);
+	atomic_set(&(qcmd->on_heap), 1);
+	CDBG("Inside msm_control\n");
+	if (copy_from_user(udata, arg, sizeof(struct msm_ctrl_cmd))) {
+		ERR_COPY_FROM_USER();
+		rc = -EFAULT;
+		goto end;
+	}
+
+	uptr = udata->value;
+	udata->value = data;
+	qcmd->type = MSM_CAM_Q_CTRL;
+	qcmd->command = udata;
+
+	if (udata->length) {
+		if (udata->length > sizeof(data)) {
+			pr_err("%s: user data too large (%d, max is %d)\n",
+					__func__,
+					udata->length,
+					sizeof(data));
+			rc = -EIO;
+			goto end;
+		}
+		if (copy_from_user(udata->value, uptr, udata->length)) {
+			ERR_COPY_FROM_USER();
+			rc = -EFAULT;
+			goto end;
+		}
+	}
+
+	if (unlikely(!block)) {
+		qcmd_resp = __msm_control_nb(sync, qcmd);
+		goto end;
+	}
+	msm_queue_drain(&ctrl_pmsm->ctrl_q, list_control);
+	qcmd_resp = __msm_control(sync,
+				  &ctrl_pmsm->ctrl_q,
+				  qcmd, msecs_to_jiffies(10000));
+
+	/* ownership of qcmd will be transfered to event queue */
+	qcmd = NULL;
+
+	if (!qcmd_resp || IS_ERR(qcmd_resp)) {
+		/* Do not free qcmd_resp here.  If the config thread read it,
+		 * then it has already been freed, and we timed out because
+		 * we did not receive a MSM_CAM_IOCTL_CTRL_CMD_DONE.  If the
+		 * config thread itself is blocked and not dequeueing commands,
+		 * then it will either eventually unblock and process them,
+		 * or when it is killed, qcmd will be freed in
+		 * msm_release_config.
+		 */
+		rc = PTR_ERR(qcmd_resp);
+		qcmd_resp = NULL;
+		goto end;
+	}
+
+	if (qcmd_resp->command) {
+		udata_resp = *(struct msm_ctrl_cmd *)qcmd_resp->command;
+		if (udata_resp.length > 0) {
+			if (copy_to_user(uptr,
+					 udata_resp.value,
+					 udata_resp.length)) {
+				ERR_COPY_TO_USER();
+				rc = -EFAULT;
+				goto end;
+			}
+		}
+		udata_resp.value = uptr;
+
+		if (copy_to_user((void *)arg, &udata_resp,
+				sizeof(struct msm_ctrl_cmd))) {
+			ERR_COPY_TO_USER();
+			rc = -EFAULT;
+			goto end;
+		}
+	}
+
+end:
+	free_qcmd(qcmd);
+	CDBG("%s: done rc = %d\n", __func__, rc);
+	return rc;
+}
+
+/* Divert frames for post-processing by delivering them to the config thread;
+ * when post-processing is done, it will return the frame to the frame thread.
+ */
+static int msm_divert_frame(struct msm_sync *sync,
+		struct msm_vfe_resp *data,
+		struct msm_stats_event_ctrl *se)
+{
+	struct msm_pmem_info pinfo;
+	struct msm_postproc buf;
+	int rc;
+
+	CDBG("%s: Frame PP sync->pp_mask %d\n", __func__, sync->pp_mask);
+
+	if (!(sync->pp_mask & PP_PREV)  && !(sync->pp_mask & PP_SNAP)) {
+		pr_err("%s: diverting frame, not in PP_PREV or PP_SNAP!\n",
+			__func__);
+		return -EINVAL;
+	}
+
+	rc = msm_pmem_frame_ptov_lookup(sync, data->phy.p0_phy,
+			data->phy.p1_phy, data->phy.p2_phy, &pinfo,
+			0); /* do not clear the active flag */
+
+	if (rc < 0) {
+		pr_err("%s: msm_pmem_frame_ptov_lookup failed\n", __func__);
+		return rc;
+	}
+
+	buf.fmain.buffer = (unsigned long)pinfo.vaddr;
+	buf.fmain.planar0_off = pinfo.planar0_off;
+	buf.fmain.planar1_off = pinfo.planar1_off;
+	buf.fmain.fd = pinfo.fd;
+
+	CDBG("%s: buf 0x%x fd %d\n", __func__, (unsigned int)buf.fmain.buffer,
+		 buf.fmain.fd);
+	if (copy_to_user((void *)(se->stats_event.data),
+			&(buf.fmain), sizeof(struct msm_frame))) {
+		ERR_COPY_TO_USER();
+		return -EFAULT;
+	}
+	return 0;
+}
+
+/* Divert stereo frames for post-processing by delivering
+ * them to the config thread.
+ */
+static int msm_divert_st_frame(struct msm_sync *sync,
+	struct msm_vfe_resp *data, struct msm_stats_event_ctrl *se, int path)
+{
+	struct msm_pmem_info pinfo;
+	struct msm_st_frame buf;
+	struct video_crop_t *crop = NULL;
+	int rc = 0;
+
+	if (se->stats_event.msg_id == OUTPUT_TYPE_ST_L) {
+		buf.type = OUTPUT_TYPE_ST_L;
+	} else if (se->stats_event.msg_id == OUTPUT_TYPE_ST_R) {
+		buf.type = OUTPUT_TYPE_ST_R;
+	} else {
+		if (se->resptype == MSM_CAM_RESP_STEREO_OP_1) {
+			rc = msm_pmem_frame_ptov_lookup(sync, data->phy.p0_phy,
+				data->phy.p1_phy, data->phy.p2_phy, &pinfo,
+				1);  /* do clear the active flag */
+			buf.buf_info.path = path;
+		} else if (se->resptype == MSM_CAM_RESP_STEREO_OP_2) {
+			rc = msm_pmem_frame_ptov_lookup(sync, data->phy.p0_phy,
+				data->phy.p1_phy, data->phy.p2_phy, &pinfo,
+				0); /* do not clear the active flag */
+			buf.buf_info.path = path;
+		} else
+			CDBG("%s: Invalid resptype = %d\n", __func__,
+				se->resptype);
+
+		if (rc < 0) {
+			CDBG("%s: msm_pmem_frame_ptov_lookup failed\n",
+				__func__);
+			return rc;
+		}
+
+		buf.type = OUTPUT_TYPE_ST_D;
+
+		if (sync->cropinfo != NULL) {
+			crop = sync->cropinfo;
+			switch (path) {
+			case OUTPUT_TYPE_P:
+			case OUTPUT_TYPE_T: {
+				buf.L.stCropInfo.in_w = crop->in1_w;
+				buf.L.stCropInfo.in_h = crop->in1_h;
+				buf.L.stCropInfo.out_w = crop->out1_w;
+				buf.L.stCropInfo.out_h = crop->out1_h;
+				buf.R.stCropInfo = buf.L.stCropInfo;
+				break;
+			}
+
+			case OUTPUT_TYPE_V:
+			case OUTPUT_TYPE_S: {
+				buf.L.stCropInfo.in_w = crop->in2_w;
+				buf.L.stCropInfo.in_h = crop->in2_h;
+				buf.L.stCropInfo.out_w = crop->out2_w;
+				buf.L.stCropInfo.out_h = crop->out2_h;
+				buf.R.stCropInfo = buf.L.stCropInfo;
+				break;
+			}
+			default: {
+				pr_warning("%s: invalid frame path %d\n",
+					__func__, path);
+				break;
+			}
+			}
+		} else {
+			buf.L.stCropInfo.in_w = 0;
+			buf.L.stCropInfo.in_h = 0;
+			buf.L.stCropInfo.out_w = 0;
+			buf.L.stCropInfo.out_h = 0;
+			buf.R.stCropInfo = buf.L.stCropInfo;
+		}
+
+		/* hardcode for now. */
+		if ((path == OUTPUT_TYPE_S) || (path == OUTPUT_TYPE_T))
+			buf.packing = sync->sctrl.s_snap_packing;
+		else
+			buf.packing = sync->sctrl.s_video_packing;
+
+		buf.buf_info.buffer = (unsigned long)pinfo.vaddr;
+		buf.buf_info.phy_offset = pinfo.offset;
+		buf.buf_info.planar0_off = pinfo.planar0_off;
+		buf.buf_info.planar1_off = pinfo.planar1_off;
+		buf.buf_info.planar2_off = pinfo.planar2_off;
+		buf.buf_info.fd = pinfo.fd;
+
+		CDBG("%s: buf 0x%x fd %d\n", __func__,
+			(unsigned int)buf.buf_info.buffer, buf.buf_info.fd);
+	}
+
+	if (copy_to_user((void *)(se->stats_event.data),
+			&buf, sizeof(struct msm_st_frame))) {
+		ERR_COPY_TO_USER();
+		return -EFAULT;
+	}
+	return 0;
+}
+
+static int msm_get_stats(struct msm_sync *sync, void __user *arg)
+{
+	int rc = 0;
+
+	struct msm_stats_event_ctrl se;
+
+	struct msm_queue_cmd *qcmd = NULL;
+	struct msm_ctrl_cmd  *ctrl = NULL;
+	struct msm_vfe_resp  *data = NULL;
+	struct msm_vpe_resp  *vpe_data = NULL;
+	struct msm_stats_buf stats;
+
+	if (copy_from_user(&se, arg,
+			sizeof(struct msm_stats_event_ctrl))) {
+		ERR_COPY_FROM_USER();
+		pr_err("%s, ERR_COPY_FROM_USER\n", __func__);
+		return -EFAULT;
+	}
+
+	rc = 0;
+
+	qcmd = msm_dequeue(&sync->event_q, list_config);
+	if (!qcmd) {
+		/* Should be associated with wait_event
+			error -512 from __msm_control*/
+		pr_err("%s, qcmd is Null\n", __func__);
+		rc = -ETIMEDOUT;
+		return rc;
+	}
+
+	CDBG("%s: received from DSP %d\n", __func__, qcmd->type);
+
+	switch (qcmd->type) {
+	case MSM_CAM_Q_VPE_MSG:
+		/* Complete VPE response. */
+		vpe_data = (struct msm_vpe_resp *)(qcmd->command);
+		se.resptype = MSM_CAM_RESP_STEREO_OP_2;
+		se.stats_event.type   = vpe_data->evt_msg.type;
+		se.stats_event.msg_id = vpe_data->evt_msg.msg_id;
+		se.stats_event.len    = vpe_data->evt_msg.len;
+
+		if (vpe_data->type == VPE_MSG_OUTPUT_ST_L) {
+			CDBG("%s: Change msg_id to OUTPUT_TYPE_ST_L\n",
+				__func__);
+			se.stats_event.msg_id = OUTPUT_TYPE_ST_L;
+			rc = msm_divert_st_frame(sync, data, &se,
+				OUTPUT_TYPE_V);
+		} else if (vpe_data->type == VPE_MSG_OUTPUT_ST_R) {
+			CDBG("%s: Change msg_id to OUTPUT_TYPE_ST_R\n",
+				__func__);
+			se.stats_event.msg_id = OUTPUT_TYPE_ST_R;
+			rc = msm_divert_st_frame(sync, data, &se,
+				OUTPUT_TYPE_V);
+		} else {
+			pr_warning("%s: invalid vpe_data->type = %d\n",
+				__func__, vpe_data->type);
+		}
+		break;
+
+	case MSM_CAM_Q_VFE_EVT:
+	case MSM_CAM_Q_VFE_MSG:
+		data = (struct msm_vfe_resp *)(qcmd->command);
+
+		/* adsp event and message */
+		se.resptype = MSM_CAM_RESP_STAT_EVT_MSG;
+
+		/* 0 - msg from aDSP, 1 - event from mARM */
+		se.stats_event.type   = data->evt_msg.type;
+		se.stats_event.msg_id = data->evt_msg.msg_id;
+		se.stats_event.len    = data->evt_msg.len;
+		se.stats_event.frame_id = data->evt_msg.frame_id;
+
+		CDBG("%s: qcmd->type %d length %d msd_id %d\n", __func__,
+			qcmd->type,
+			se.stats_event.len,
+			se.stats_event.msg_id);
+
+		if (data->type == VFE_MSG_COMMON) {
+			stats.status_bits = data->stats_msg.status_bits;
+			stats.awb_ymin = data->stats_msg.awb_ymin;
+
+			if (data->stats_msg.aec_buff) {
+				stats.aec.buff =
+				msm_pmem_stats_ptov_lookup(sync,
+						data->stats_msg.aec_buff,
+						&(stats.aec.fd));
+				if (!stats.aec.buff) {
+					pr_err("%s: msm_pmem_stats_ptov_lookup error\n",
+						__func__);
+					rc = -EINVAL;
+					goto failure;
+				}
+
+			} else {
+				stats.aec.buff = 0;
+			}
+			if (data->stats_msg.awb_buff) {
+				stats.awb.buff =
+				msm_pmem_stats_ptov_lookup(sync,
+						data->stats_msg.awb_buff,
+						&(stats.awb.fd));
+				if (!stats.awb.buff) {
+					pr_err("%s: msm_pmem_stats_ptov_lookup error\n",
+						__func__);
+					rc = -EINVAL;
+					goto failure;
+				}
+
+			} else {
+				stats.awb.buff = 0;
+			}
+			if (data->stats_msg.af_buff) {
+				stats.af.buff =
+				msm_pmem_stats_ptov_lookup(sync,
+						data->stats_msg.af_buff,
+						&(stats.af.fd));
+				if (!stats.af.buff) {
+					pr_err("%s: msm_pmem_stats_ptov_lookup error\n",
+						__func__);
+					rc = -EINVAL;
+					goto failure;
+				}
+
+			} else {
+				stats.af.buff = 0;
+			}
+			if (data->stats_msg.ihist_buff) {
+				stats.ihist.buff =
+				msm_pmem_stats_ptov_lookup(sync,
+						data->stats_msg.ihist_buff,
+						&(stats.ihist.fd));
+				if (!stats.ihist.buff) {
+					pr_err("%s: msm_pmem_stats_ptov_lookup error\n",
+						__func__);
+					rc = -EINVAL;
+					goto failure;
+				}
+
+			} else {
+				stats.ihist.buff = 0;
+			}
+
+			if (data->stats_msg.rs_buff) {
+				stats.rs.buff =
+				msm_pmem_stats_ptov_lookup(sync,
+						data->stats_msg.rs_buff,
+						&(stats.rs.fd));
+				if (!stats.rs.buff) {
+					pr_err("%s: msm_pmem_stats_ptov_lookup error\n",
+						__func__);
+					rc = -EINVAL;
+					goto failure;
+				}
+
+			} else {
+				stats.rs.buff = 0;
+			}
+
+			if (data->stats_msg.cs_buff) {
+				stats.cs.buff =
+				msm_pmem_stats_ptov_lookup(sync,
+						data->stats_msg.cs_buff,
+						&(stats.cs.fd));
+				if (!stats.cs.buff) {
+					pr_err("%s: msm_pmem_stats_ptov_lookup error\n",
+						__func__);
+					rc = -EINVAL;
+					goto failure;
+				}
+			} else {
+				stats.cs.buff = 0;
+			}
+
+			se.stats_event.frame_id = data->phy.frame_id;
+			if (copy_to_user((void *)(se.stats_event.data),
+					&stats,
+					sizeof(struct msm_stats_buf))) {
+				ERR_COPY_TO_USER();
+				rc = -EFAULT;
+				goto failure;
+			}
+		} else if ((data->type >= VFE_MSG_STATS_AEC) &&
+			(data->type <=  VFE_MSG_STATS_WE)) {
+			/* the check above includes all stats type. */
+			stats.awb_ymin = data->stats_msg.awb_ymin;
+			stats.buffer =
+				msm_pmem_stats_ptov_lookup(sync,
+						data->phy.sbuf_phy,
+						&(stats.fd));
+			if (!stats.buffer) {
+					pr_err("%s: msm_pmem_stats_ptov_lookup error\n",
+						__func__);
+					rc = -EINVAL;
+					goto failure;
+			}
+			se.stats_event.frame_id = data->phy.frame_id;
+			if (copy_to_user((void *)(se.stats_event.data),
+					&stats,
+					sizeof(struct msm_stats_buf))) {
+				ERR_COPY_TO_USER();
+				rc = -EFAULT;
+				goto failure;
+			}
+		} else if ((data->evt_msg.len > 0) &&
+				(data->type == VFE_MSG_GENERAL)) {
+			if (copy_to_user((void *)(se.stats_event.data),
+					data->evt_msg.data,
+					data->evt_msg.len)) {
+				ERR_COPY_TO_USER();
+				rc = -EFAULT;
+				goto failure;
+			}
+		} else {
+			if (sync->stereocam_enabled) {
+				if (data->type == VFE_MSG_OUTPUT_P) {
+					CDBG("%s: Preview mark as st op 1\n",
+						__func__);
+					se.resptype = MSM_CAM_RESP_STEREO_OP_1;
+					rc = msm_divert_st_frame(sync, data,
+						&se, OUTPUT_TYPE_P);
+					break;
+				} else if (data->type == VFE_MSG_OUTPUT_V) {
+					CDBG("%s: Video mark as st op 2\n",
+						__func__);
+					se.resptype = MSM_CAM_RESP_STEREO_OP_2;
+					rc = msm_divert_st_frame(sync, data,
+						&se, OUTPUT_TYPE_V);
+					break;
+				} else if (data->type == VFE_MSG_OUTPUT_S) {
+					CDBG("%s: Main img mark as st op 2\n",
+						__func__);
+					se.resptype = MSM_CAM_RESP_STEREO_OP_2;
+					rc = msm_divert_st_frame(sync, data,
+						&se, OUTPUT_TYPE_S);
+					break;
+				} else if (data->type == VFE_MSG_OUTPUT_T) {
+					CDBG("%s: Thumb img mark as st op 2\n",
+						__func__);
+					se.resptype = MSM_CAM_RESP_STEREO_OP_2;
+					rc = msm_divert_st_frame(sync, data,
+						&se, OUTPUT_TYPE_T);
+					break;
+				} else
+					CDBG("%s: VFE_MSG Fall Through\n",
+						__func__);
+			}
+			if ((sync->pp_frame_avail == 1) &&
+				(sync->pp_mask & PP_PREV) &&
+				(data->type == VFE_MSG_OUTPUT_P)) {
+					CDBG("%s:%d:preiew PP\n",
+					__func__, __LINE__);
+					se.stats_event.frame_id =
+							data->phy.frame_id;
+					rc = msm_divert_frame(sync, data, &se);
+					sync->pp_frame_avail = 0;
+			} else {
+				if ((sync->pp_mask & PP_PREV) &&
+					(data->type == VFE_MSG_OUTPUT_P)) {
+					se.stats_event.frame_id =
+							data->phy.frame_id;
+					free_qcmd(qcmd);
+					return 0;
+				} else
+					CDBG("%s:indication type is %d\n",
+						__func__, data->type);
+			}
+			if (sync->pp_mask & PP_SNAP)
+				if (data->type == VFE_MSG_OUTPUT_S ||
+					data->type == VFE_MSG_OUTPUT_T)
+					rc = msm_divert_frame(sync, data, &se);
+		}
+		break;
+
+	case MSM_CAM_Q_CTRL:
+		/* control command from control thread */
+		ctrl = (struct msm_ctrl_cmd *)(qcmd->command);
+
+		CDBG("%s: qcmd->type %d length %d\n", __func__,
+			qcmd->type, ctrl->length);
+
+		if (ctrl->length > 0) {
+			if (copy_to_user((void *)(se.ctrl_cmd.value),
+						ctrl->value,
+						ctrl->length)) {
+				ERR_COPY_TO_USER();
+				rc = -EFAULT;
+				goto failure;
+			}
+		}
+
+		se.resptype = MSM_CAM_RESP_CTRL;
+
+		/* what to control */
+		se.ctrl_cmd.type = ctrl->type;
+		se.ctrl_cmd.length = ctrl->length;
+		se.ctrl_cmd.resp_fd = ctrl->resp_fd;
+		break;
+
+	case MSM_CAM_Q_V4L2_REQ:
+		/* control command from v4l2 client */
+		ctrl = (struct msm_ctrl_cmd *)(qcmd->command);
+		if (ctrl->length > 0) {
+			if (copy_to_user((void *)(se.ctrl_cmd.value),
+					ctrl->value, ctrl->length)) {
+				ERR_COPY_TO_USER();
+				rc = -EFAULT;
+				goto failure;
+			}
+		}
+
+		/* 2 tells config thread this is v4l2 request */
+		se.resptype = MSM_CAM_RESP_V4L2;
+
+		/* what to control */
+		se.ctrl_cmd.type   = ctrl->type;
+		se.ctrl_cmd.length = ctrl->length;
+		break;
+
+	default:
+		rc = -EFAULT;
+		goto failure;
+	} /* switch qcmd->type */
+	if (copy_to_user((void *)arg, &se, sizeof(se))) {
+		ERR_COPY_TO_USER();
+		rc = -EFAULT;
+		goto failure;
+	}
+
+failure:
+	free_qcmd(qcmd);
+
+	CDBG("%s: %d\n", __func__, rc);
+	return rc;
+}
+
+static int msm_ctrl_cmd_done(struct msm_control_device *ctrl_pmsm,
+		void __user *arg)
+{
+	void __user *uptr;
+	struct msm_queue_cmd *qcmd = &ctrl_pmsm->qcmd;
+	struct msm_ctrl_cmd *command = &ctrl_pmsm->ctrl;
+
+	if (copy_from_user(command, arg, sizeof(*command))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	atomic_set(&qcmd->on_heap, 0);
+	qcmd->command = command;
+	uptr = command->value;
+
+	if (command->length > 0) {
+		command->value = ctrl_pmsm->ctrl_data;
+		if (command->length > sizeof(ctrl_pmsm->ctrl_data)) {
+			pr_err("%s: user data %d is too big (max %d)\n",
+				__func__, command->length,
+				sizeof(ctrl_pmsm->ctrl_data));
+			return -EINVAL;
+		}
+
+		if (copy_from_user(command->value,
+					uptr,
+					command->length)) {
+			ERR_COPY_FROM_USER();
+			return -EFAULT;
+		}
+	} else
+		command->value = NULL;
+
+	/* Ignore the command if the ctrl cmd has
+	   return back due to signaling */
+	/* Should be associated with wait_event
+	   error -512 from __msm_control*/
+	if (ctrl_pmsm->pmsm->sync->ignore_qcmd == true &&
+	   ctrl_pmsm->pmsm->sync->ignore_qcmd_type == (int16_t)command->type) {
+		ctrl_pmsm->pmsm->sync->ignore_qcmd = false;
+		ctrl_pmsm->pmsm->sync->ignore_qcmd_type = -1;
+	} else /* wake up control thread */
+		msm_enqueue(&ctrl_pmsm->ctrl_q, &qcmd->list_control);
+
+	return 0;
+}
+
+static int msm_config_vpe(struct msm_sync *sync, void __user *arg)
+{
+	struct msm_vpe_cfg_cmd cfgcmd;
+	if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+	CDBG("%s: cmd_type %s\n", __func__, vfe_config_cmd[cfgcmd.cmd_type]);
+	switch (cfgcmd.cmd_type) {
+	case CMD_VPE:
+		return sync->vpefn.vpe_config(&cfgcmd, NULL);
+	default:
+		pr_err("%s: unknown command type %d\n",
+			__func__, cfgcmd.cmd_type);
+	}
+	return -EINVAL;
+}
+
+static int msm_config_vfe(struct msm_sync *sync, void __user *arg)
+{
+	struct msm_vfe_cfg_cmd cfgcmd;
+	struct msm_pmem_region region[8];
+	struct axidata axi_data;
+
+	if (!sync->vfefn.vfe_config) {
+		pr_err("%s: no vfe_config!\n", __func__);
+		return -EIO;
+	}
+
+	if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	memset(&axi_data, 0, sizeof(axi_data));
+	CDBG("%s: cmd_type %s\n", __func__, vfe_config_cmd[cfgcmd.cmd_type]);
+	switch (cfgcmd.cmd_type) {
+	case CMD_STATS_ENABLE:
+		axi_data.bufnum1 =
+			msm_pmem_region_lookup(&sync->pmem_stats,
+				MSM_PMEM_AEC_AWB, &region[0],
+				NUM_STAT_OUTPUT_BUFFERS,
+				&sync->pmem_stats_spinlock);
+		axi_data.bufnum2 =
+			msm_pmem_region_lookup(&sync->pmem_stats,
+				MSM_PMEM_AF, &region[axi_data.bufnum1],
+				NUM_STAT_OUTPUT_BUFFERS,
+				&sync->pmem_stats_spinlock);
+		if (!axi_data.bufnum1 || !axi_data.bufnum2) {
+			pr_err("%s: pmem region lookup error\n", __func__);
+			return -EINVAL;
+		}
+		axi_data.region = &region[0];
+		return sync->vfefn.vfe_config(&cfgcmd, &axi_data);
+	case CMD_STATS_AF_ENABLE:
+		axi_data.bufnum1 =
+			msm_pmem_region_lookup(&sync->pmem_stats,
+				MSM_PMEM_AF, &region[0],
+				NUM_STAT_OUTPUT_BUFFERS,
+				&sync->pmem_stats_spinlock);
+		if (!axi_data.bufnum1) {
+			pr_err("%s %d: pmem region lookup error\n",
+				__func__, __LINE__);
+			return -EINVAL;
+		}
+		axi_data.region = &region[0];
+		return sync->vfefn.vfe_config(&cfgcmd, &axi_data);
+	case CMD_STATS_AEC_AWB_ENABLE:
+		axi_data.bufnum1 =
+			msm_pmem_region_lookup(&sync->pmem_stats,
+				MSM_PMEM_AEC_AWB, &region[0],
+				NUM_STAT_OUTPUT_BUFFERS,
+				&sync->pmem_stats_spinlock);
+		if (!axi_data.bufnum1) {
+			pr_err("%s %d: pmem region lookup error\n",
+				__func__, __LINE__);
+			return -EINVAL;
+		}
+		axi_data.region = &region[0];
+		return sync->vfefn.vfe_config(&cfgcmd, &axi_data);
+	case CMD_STATS_AEC_ENABLE:
+		axi_data.bufnum1 =
+			msm_pmem_region_lookup(&sync->pmem_stats,
+			MSM_PMEM_AEC, &region[0],
+			NUM_STAT_OUTPUT_BUFFERS,
+			&sync->pmem_stats_spinlock);
+		if (!axi_data.bufnum1) {
+			pr_err("%s %d: pmem region lookup error\n",
+				__func__, __LINE__);
+			return -EINVAL;
+		}
+		axi_data.region = &region[0];
+		return sync->vfefn.vfe_config(&cfgcmd, &axi_data);
+	case CMD_STATS_AWB_ENABLE:
+		axi_data.bufnum1 =
+			msm_pmem_region_lookup(&sync->pmem_stats,
+			MSM_PMEM_AWB, &region[0],
+			NUM_STAT_OUTPUT_BUFFERS,
+			&sync->pmem_stats_spinlock);
+		if (!axi_data.bufnum1) {
+			pr_err("%s %d: pmem region lookup error\n",
+				__func__, __LINE__);
+			return -EINVAL;
+		}
+		axi_data.region = &region[0];
+		return sync->vfefn.vfe_config(&cfgcmd, &axi_data);
+
+
+	case CMD_STATS_IHIST_ENABLE:
+		axi_data.bufnum1 =
+			msm_pmem_region_lookup(&sync->pmem_stats,
+			MSM_PMEM_IHIST, &region[0],
+			NUM_STAT_OUTPUT_BUFFERS,
+			&sync->pmem_stats_spinlock);
+		if (!axi_data.bufnum1) {
+			pr_err("%s %d: pmem region lookup error\n",
+				__func__, __LINE__);
+			return -EINVAL;
+		}
+		axi_data.region = &region[0];
+		return sync->vfefn.vfe_config(&cfgcmd, &axi_data);
+
+	case CMD_STATS_RS_ENABLE:
+		axi_data.bufnum1 =
+			msm_pmem_region_lookup(&sync->pmem_stats,
+			MSM_PMEM_RS, &region[0],
+			NUM_STAT_OUTPUT_BUFFERS,
+			&sync->pmem_stats_spinlock);
+		if (!axi_data.bufnum1) {
+			pr_err("%s %d: pmem region lookup error\n",
+				__func__, __LINE__);
+			return -EINVAL;
+		}
+		axi_data.region = &region[0];
+		return sync->vfefn.vfe_config(&cfgcmd, &axi_data);
+
+	case CMD_STATS_CS_ENABLE:
+		axi_data.bufnum1 =
+			msm_pmem_region_lookup(&sync->pmem_stats,
+			MSM_PMEM_CS, &region[0],
+			NUM_STAT_OUTPUT_BUFFERS,
+			&sync->pmem_stats_spinlock);
+		if (!axi_data.bufnum1) {
+			pr_err("%s %d: pmem region lookup error\n",
+				__func__, __LINE__);
+			return -EINVAL;
+		}
+		axi_data.region = &region[0];
+		return sync->vfefn.vfe_config(&cfgcmd, &axi_data);
+
+	case CMD_GENERAL:
+	case CMD_STATS_DISABLE:
+		return sync->vfefn.vfe_config(&cfgcmd, NULL);
+	default:
+		pr_err("%s: unknown command type %d\n",
+			__func__, cfgcmd.cmd_type);
+	}
+
+	return -EINVAL;
+}
+static int msm_vpe_frame_cfg(struct msm_sync *sync,
+				void *cfgcmdin)
+{
+	int rc = -EIO;
+	struct axidata axi_data;
+	void *data = &axi_data;
+	struct msm_pmem_region region[8];
+	int pmem_type;
+
+	struct msm_vpe_cfg_cmd *cfgcmd;
+	cfgcmd = (struct msm_vpe_cfg_cmd *)cfgcmdin;
+
+	memset(&axi_data, 0, sizeof(axi_data));
+	CDBG("In vpe_frame_cfg cfgcmd->cmd_type = %s\n",
+		vfe_config_cmd[cfgcmd->cmd_type]);
+	switch (cfgcmd->cmd_type) {
+	case CMD_AXI_CFG_VPE:
+		pmem_type = MSM_PMEM_VIDEO_VPE;
+		axi_data.bufnum1 =
+			msm_pmem_region_lookup_2(&sync->pmem_frames, pmem_type,
+				&region[0], 8, &sync->pmem_frame_spinlock);
+		CDBG("axi_data.bufnum1 = %d\n", axi_data.bufnum1);
+		if (!axi_data.bufnum1) {
+			pr_err("%s %d: pmem region lookup error\n",
+				__func__, __LINE__);
+			return -EINVAL;
+		}
+		pmem_type = MSM_PMEM_VIDEO;
+		break;
+	case CMD_AXI_CFG_SNAP_THUMB_VPE:
+		CDBG("%s: CMD_AXI_CFG_SNAP_THUMB_VPE", __func__);
+		pmem_type = MSM_PMEM_THUMBNAIL_VPE;
+		axi_data.bufnum1 =
+			msm_pmem_region_lookup(&sync->pmem_frames, pmem_type,
+			&region[0], 8, &sync->pmem_frame_spinlock);
+		if (!axi_data.bufnum1) {
+			pr_err("%s: THUMBNAIL_VPE pmem region lookup error\n",
+				__func__);
+			return -EINVAL;
+		}
+		break;
+	case CMD_AXI_CFG_SNAP_VPE:
+		CDBG("%s: CMD_AXI_CFG_SNAP_VPE", __func__);
+		pmem_type = MSM_PMEM_MAINIMG_VPE;
+		axi_data.bufnum1 =
+			msm_pmem_region_lookup(&sync->pmem_frames, pmem_type,
+				&region[0], 8, &sync->pmem_frame_spinlock);
+		if (!axi_data.bufnum1) {
+			pr_err("%s: MAINIMG_VPE pmem region lookup error\n",
+				__func__);
+			return -EINVAL;
+		}
+		break;
+	default:
+		pr_err("%s: unknown command type %d\n",
+			__func__, cfgcmd->cmd_type);
+		break;
+	}
+	axi_data.region = &region[0];
+	CDBG("out vpe_frame_cfg cfgcmd->cmd_type = %s\n",
+		vfe_config_cmd[cfgcmd->cmd_type]);
+	/* send the AXI configuration command to driver */
+	if (sync->vpefn.vpe_config)
+		rc = sync->vpefn.vpe_config(cfgcmd, data);
+	return rc;
+}
+
+static int msm_frame_axi_cfg(struct msm_sync *sync,
+		struct msm_vfe_cfg_cmd *cfgcmd)
+{
+	int rc = -EIO;
+	struct axidata axi_data;
+	void *data = &axi_data;
+	struct msm_pmem_region region[MAX_PMEM_CFG_BUFFERS];
+	int pmem_type;
+
+	memset(&axi_data, 0, sizeof(axi_data));
+
+	switch (cfgcmd->cmd_type) {
+
+	case CMD_AXI_CFG_PREVIEW:
+		pmem_type = MSM_PMEM_PREVIEW;
+		axi_data.bufnum2 =
+			msm_pmem_region_lookup(&sync->pmem_frames, pmem_type,
+				&region[0], MAX_PMEM_CFG_BUFFERS,
+				&sync->pmem_frame_spinlock);
+		if (!axi_data.bufnum2) {
+			pr_err("%s %d: pmem region lookup error (empty %d)\n",
+				__func__, __LINE__,
+				hlist_empty(&sync->pmem_frames));
+			return -EINVAL;
+		}
+		break;
+
+	case CMD_AXI_CFG_VIDEO_ALL_CHNLS:
+	case CMD_AXI_CFG_VIDEO:
+		pmem_type = MSM_PMEM_PREVIEW;
+		axi_data.bufnum1 =
+			msm_pmem_region_lookup(&sync->pmem_frames, pmem_type,
+				&region[0], MAX_PMEM_CFG_BUFFERS,
+				&sync->pmem_frame_spinlock);
+		if (!axi_data.bufnum1) {
+			pr_err("%s %d: pmem region lookup error\n",
+				__func__, __LINE__);
+			return -EINVAL;
+		}
+
+		pmem_type = MSM_PMEM_VIDEO;
+		axi_data.bufnum2 =
+			msm_pmem_region_lookup(&sync->pmem_frames, pmem_type,
+				&region[axi_data.bufnum1],
+				(MAX_PMEM_CFG_BUFFERS-(axi_data.bufnum1)),
+				&sync->pmem_frame_spinlock);
+		if (!axi_data.bufnum2) {
+			pr_err("%s %d: pmem region lookup error\n",
+				__func__, __LINE__);
+			return -EINVAL;
+		}
+		break;
+
+	case CMD_AXI_CFG_SNAP:
+		CDBG("%s, CMD_AXI_CFG_SNAP, type=%d\n", __func__,
+			cfgcmd->cmd_type);
+		pmem_type = MSM_PMEM_THUMBNAIL;
+		axi_data.bufnum1 =
+			msm_pmem_region_lookup(&sync->pmem_frames, pmem_type,
+				&region[0], MAX_PMEM_CFG_BUFFERS,
+				&sync->pmem_frame_spinlock);
+		if (!axi_data.bufnum1) {
+			pr_err("%s %d: pmem region lookup error\n",
+				__func__, __LINE__);
+			return -EINVAL;
+		}
+
+		pmem_type = MSM_PMEM_MAINIMG;
+		axi_data.bufnum2 =
+			msm_pmem_region_lookup(&sync->pmem_frames, pmem_type,
+				&region[axi_data.bufnum1],
+				(MAX_PMEM_CFG_BUFFERS-(axi_data.bufnum1)),
+				 &sync->pmem_frame_spinlock);
+		if (!axi_data.bufnum2) {
+			pr_err("%s %d: pmem region lookup error\n",
+				__func__, __LINE__);
+			return -EINVAL;
+		}
+		break;
+
+	case CMD_AXI_CFG_ZSL_ALL_CHNLS:
+	case CMD_AXI_CFG_ZSL:
+		CDBG("%s, CMD_AXI_CFG_ZSL, type = %d\n", __func__,
+			cfgcmd->cmd_type);
+		pmem_type = MSM_PMEM_PREVIEW;
+		axi_data.bufnum1 =
+			msm_pmem_region_lookup(&sync->pmem_frames, pmem_type,
+				&region[0], MAX_PMEM_CFG_BUFFERS,
+				&sync->pmem_frame_spinlock);
+		if (!axi_data.bufnum1) {
+			pr_err("%s %d: pmem region lookup error\n",
+				__func__, __LINE__);
+			return -EINVAL;
+		}
+
+		pmem_type = MSM_PMEM_THUMBNAIL;
+		axi_data.bufnum2 =
+			msm_pmem_region_lookup(&sync->pmem_frames, pmem_type,
+				&region[axi_data.bufnum1],
+				(MAX_PMEM_CFG_BUFFERS-(axi_data.bufnum1)),
+				 &sync->pmem_frame_spinlock);
+		if (!axi_data.bufnum2) {
+			pr_err("%s %d: pmem region lookup error\n",
+				__func__, __LINE__);
+			return -EINVAL;
+		}
+
+		pmem_type = MSM_PMEM_MAINIMG;
+		axi_data.bufnum3 =
+			msm_pmem_region_lookup(&sync->pmem_frames, pmem_type,
+				&region[axi_data.bufnum1 + axi_data.bufnum2],
+				(MAX_PMEM_CFG_BUFFERS - axi_data.bufnum1 -
+				axi_data.bufnum2), &sync->pmem_frame_spinlock);
+		if (!axi_data.bufnum3) {
+			pr_err("%s %d: pmem region lookup error\n",
+				__func__, __LINE__);
+			return -EINVAL;
+		}
+		break;
+
+	case CMD_RAW_PICT_AXI_CFG:
+		pmem_type = MSM_PMEM_RAW_MAINIMG;
+		axi_data.bufnum2 =
+			msm_pmem_region_lookup(&sync->pmem_frames, pmem_type,
+				&region[0], MAX_PMEM_CFG_BUFFERS,
+				&sync->pmem_frame_spinlock);
+		if (!axi_data.bufnum2) {
+			pr_err("%s %d: pmem region lookup error\n",
+				__func__, __LINE__);
+			return -EINVAL;
+		}
+		break;
+
+	case CMD_GENERAL:
+		data = NULL;
+		break;
+
+	default:
+		pr_err("%s: unknown command type %d\n",
+			__func__, cfgcmd->cmd_type);
+		return -EINVAL;
+	}
+
+	axi_data.region = &region[0];
+
+	/* send the AXI configuration command to driver */
+	if (sync->vfefn.vfe_config)
+		rc = sync->vfefn.vfe_config(cfgcmd, data);
+
+	return rc;
+}
+
+static int msm_get_sensor_info(struct msm_sync *sync, void __user *arg)
+{
+	int rc = 0;
+	struct msm_camsensor_info info;
+	struct msm_camera_sensor_info *sdata;
+
+	if (copy_from_user(&info,
+			arg,
+			sizeof(struct msm_camsensor_info))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	sdata = sync->pdev->dev.platform_data;
+	if (sync->sctrl.s_camera_type == BACK_CAMERA_3D)
+		info.support_3d = true;
+	else
+		info.support_3d = false;
+	memcpy(&info.name[0],
+		sdata->sensor_name,
+		MAX_SENSOR_NAME);
+	info.flash_enabled = sdata->flash_data->flash_type !=
+		MSM_CAMERA_FLASH_NONE;
+
+	/* copy back to user space */
+	if (copy_to_user((void *)arg,
+			&info,
+			sizeof(struct msm_camsensor_info))) {
+		ERR_COPY_TO_USER();
+		rc = -EFAULT;
+	}
+
+	return rc;
+}
+
+static int msm_get_camera_info(void __user *arg)
+{
+	int rc = 0;
+	int i = 0;
+	struct msm_camera_info info;
+
+	if (copy_from_user(&info, arg, sizeof(struct msm_camera_info))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	CDBG("%s: camera_node %d\n", __func__, camera_node);
+	info.num_cameras = camera_node;
+
+	for (i = 0; i < camera_node; i++) {
+		info.has_3d_support[i] = 0;
+		info.is_internal_cam[i] = 0;
+		info.s_mount_angle[i] = sensor_mount_angle[i];
+		switch (camera_type[i]) {
+		case FRONT_CAMERA_2D:
+			info.is_internal_cam[i] = 1;
+			break;
+		case BACK_CAMERA_3D:
+			info.has_3d_support[i] = 1;
+			break;
+		case BACK_CAMERA_2D:
+		default:
+			break;
+		}
+	}
+	/* copy back to user space */
+	if (copy_to_user((void *)arg, &info, sizeof(struct msm_camera_info))) {
+		ERR_COPY_TO_USER();
+		rc = -EFAULT;
+	}
+	return rc;
+}
+
+static int __msm_put_frame_buf(struct msm_sync *sync,
+		struct msm_frame *pb)
+{
+	unsigned long pphy;
+	struct msm_vfe_cfg_cmd cfgcmd;
+
+	int rc = -EIO;
+
+	/* Change the active flag. */
+	pphy = msm_pmem_frame_vtop_lookup(sync,
+		pb->buffer,
+		pb->planar0_off, pb->planar1_off, pb->planar2_off, pb->fd, 1);
+
+	if (pphy != 0) {
+		CDBG("%s: rel: vaddr %lx, paddr %lx\n",
+			__func__,
+			pb->buffer, pphy);
+		cfgcmd.cmd_type = CMD_FRAME_BUF_RELEASE;
+		cfgcmd.value    = (void *)pb;
+		if (sync->vfefn.vfe_config)
+			rc = sync->vfefn.vfe_config(&cfgcmd, &pphy);
+	} else {
+		pr_err("%s: msm_pmem_frame_vtop_lookup failed\n",
+			__func__);
+		rc = -EINVAL;
+	}
+
+	return rc;
+}
+static int __msm_put_pic_buf(struct msm_sync *sync,
+		struct msm_frame *pb)
+{
+	unsigned long pphy;
+	struct msm_vfe_cfg_cmd cfgcmd;
+
+	int rc = -EIO;
+
+	pphy = msm_pmem_frame_vtop_lookup(sync,
+		pb->buffer,
+		pb->planar0_off, pb->planar1_off, pb->planar2_off, pb->fd, 1);
+
+	if (pphy != 0) {
+		CDBG("%s: rel: vaddr %lx, paddr %lx\n",
+			__func__,
+			pb->buffer, pphy);
+		cfgcmd.cmd_type = CMD_SNAP_BUF_RELEASE;
+		cfgcmd.value    = (void *)pb;
+		if (sync->vfefn.vfe_config)
+			rc = sync->vfefn.vfe_config(&cfgcmd, &pphy);
+	} else {
+		pr_err("%s: msm_pmem_frame_vtop_lookup failed\n",
+			__func__);
+		rc = -EINVAL;
+	}
+
+	return rc;
+}
+
+
+static int msm_put_frame_buffer(struct msm_sync *sync, void __user *arg)
+{
+	struct msm_frame buf_t;
+
+	if (copy_from_user(&buf_t,
+				arg,
+				sizeof(struct msm_frame))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	return __msm_put_frame_buf(sync, &buf_t);
+}
+
+
+static int msm_put_pic_buffer(struct msm_sync *sync, void __user *arg)
+{
+	struct msm_frame buf_t;
+
+	if (copy_from_user(&buf_t,
+				arg,
+				sizeof(struct msm_frame))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	return __msm_put_pic_buf(sync, &buf_t);
+}
+
+static int __msm_register_pmem(struct msm_sync *sync,
+		struct msm_pmem_info *pinfo)
+{
+	int rc = 0;
+
+	switch (pinfo->type) {
+	case MSM_PMEM_VIDEO:
+	case MSM_PMEM_PREVIEW:
+	case MSM_PMEM_THUMBNAIL:
+	case MSM_PMEM_MAINIMG:
+	case MSM_PMEM_RAW_MAINIMG:
+	case MSM_PMEM_VIDEO_VPE:
+	case MSM_PMEM_C2D:
+	case MSM_PMEM_MAINIMG_VPE:
+	case MSM_PMEM_THUMBNAIL_VPE:
+		rc = msm_pmem_table_add(&sync->pmem_frames, pinfo,
+			&sync->pmem_frame_spinlock, sync);
+		break;
+
+	case MSM_PMEM_AEC_AWB:
+	case MSM_PMEM_AF:
+	case MSM_PMEM_AEC:
+	case MSM_PMEM_AWB:
+	case MSM_PMEM_RS:
+	case MSM_PMEM_CS:
+	case MSM_PMEM_IHIST:
+	case MSM_PMEM_SKIN:
+
+		rc = msm_pmem_table_add(&sync->pmem_stats, pinfo,
+			 &sync->pmem_stats_spinlock, sync);
+		break;
+
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
+static int msm_register_pmem(struct msm_sync *sync, void __user *arg)
+{
+	struct msm_pmem_info info;
+
+	if (copy_from_user(&info, arg, sizeof(info))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	return __msm_register_pmem(sync, &info);
+}
+
+static int msm_stats_axi_cfg(struct msm_sync *sync,
+		struct msm_vfe_cfg_cmd *cfgcmd)
+{
+	int rc = -EIO;
+	struct axidata axi_data;
+	void *data = &axi_data;
+
+	struct msm_pmem_region region[3];
+	int pmem_type = MSM_PMEM_MAX;
+
+	memset(&axi_data, 0, sizeof(axi_data));
+
+	switch (cfgcmd->cmd_type) {
+	case CMD_STATS_AXI_CFG:
+		pmem_type = MSM_PMEM_AEC_AWB;
+		break;
+	case CMD_STATS_AF_AXI_CFG:
+		pmem_type = MSM_PMEM_AF;
+		break;
+	case CMD_GENERAL:
+		data = NULL;
+		break;
+	default:
+		pr_err("%s: unknown command type %d\n",
+			__func__, cfgcmd->cmd_type);
+		return -EINVAL;
+	}
+
+	if (cfgcmd->cmd_type != CMD_GENERAL) {
+		axi_data.bufnum1 =
+			msm_pmem_region_lookup(&sync->pmem_stats, pmem_type,
+				&region[0], NUM_STAT_OUTPUT_BUFFERS,
+				&sync->pmem_stats_spinlock);
+		if (!axi_data.bufnum1) {
+			pr_err("%s %d: pmem region lookup error\n",
+				__func__, __LINE__);
+			return -EINVAL;
+		}
+	axi_data.region = &region[0];
+	}
+
+	/* send the AEC/AWB STATS configuration command to driver */
+	if (sync->vfefn.vfe_config)
+		rc = sync->vfefn.vfe_config(cfgcmd, &axi_data);
+
+	return rc;
+}
+
+static int msm_put_stats_buffer(struct msm_sync *sync, void __user *arg)
+{
+	int rc = -EIO;
+
+	struct msm_stats_buf buf;
+	unsigned long pphy;
+	struct msm_vfe_cfg_cmd cfgcmd;
+
+	if (copy_from_user(&buf, arg,
+				sizeof(struct msm_stats_buf))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	CDBG("%s\n", __func__);
+	pphy = msm_pmem_stats_vtop_lookup(sync, buf.buffer, buf.fd);
+
+	if (pphy != 0) {
+		if (buf.type == STAT_AEAW)
+			cfgcmd.cmd_type = CMD_STATS_BUF_RELEASE;
+		else if (buf.type == STAT_AF)
+			cfgcmd.cmd_type = CMD_STATS_AF_BUF_RELEASE;
+		else if (buf.type == STAT_AEC)
+			cfgcmd.cmd_type = CMD_STATS_AEC_BUF_RELEASE;
+		else if (buf.type == STAT_AWB)
+			cfgcmd.cmd_type = CMD_STATS_AWB_BUF_RELEASE;
+		else if (buf.type == STAT_IHIST)
+			cfgcmd.cmd_type = CMD_STATS_IHIST_BUF_RELEASE;
+		else if (buf.type == STAT_RS)
+			cfgcmd.cmd_type = CMD_STATS_RS_BUF_RELEASE;
+		else if (buf.type == STAT_CS)
+			cfgcmd.cmd_type = CMD_STATS_CS_BUF_RELEASE;
+
+		else {
+			pr_err("%s: invalid buf type %d\n",
+				__func__,
+				buf.type);
+			rc = -EINVAL;
+			goto put_done;
+		}
+
+		cfgcmd.value = (void *)&buf;
+
+		if (sync->vfefn.vfe_config) {
+			rc = sync->vfefn.vfe_config(&cfgcmd, &pphy);
+			if (rc < 0)
+				pr_err("%s: vfe_config error %d\n",
+					__func__, rc);
+		} else
+			pr_err("%s: vfe_config is NULL\n", __func__);
+	} else {
+		pr_err("%s: NULL physical address\n", __func__);
+		rc = -EINVAL;
+	}
+
+put_done:
+	return rc;
+}
+
+static int msm_axi_config(struct msm_sync *sync, void __user *arg)
+{
+	struct msm_vfe_cfg_cmd cfgcmd;
+
+	if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	switch (cfgcmd.cmd_type) {
+	case CMD_AXI_CFG_VIDEO:
+	case CMD_AXI_CFG_PREVIEW:
+	case CMD_AXI_CFG_SNAP:
+	case CMD_RAW_PICT_AXI_CFG:
+	case CMD_AXI_CFG_ZSL:
+	case CMD_AXI_CFG_VIDEO_ALL_CHNLS:
+	case CMD_AXI_CFG_ZSL_ALL_CHNLS:
+		CDBG("%s, cfgcmd.cmd_type = %d\n", __func__, cfgcmd.cmd_type);
+		return msm_frame_axi_cfg(sync, &cfgcmd);
+
+	case CMD_AXI_CFG_VPE:
+	case CMD_AXI_CFG_SNAP_VPE:
+	case CMD_AXI_CFG_SNAP_THUMB_VPE:
+		return msm_vpe_frame_cfg(sync, (void *)&cfgcmd);
+
+	case CMD_STATS_AXI_CFG:
+	case CMD_STATS_AF_AXI_CFG:
+		return msm_stats_axi_cfg(sync, &cfgcmd);
+
+	default:
+		pr_err("%s: unknown command type %d\n",
+			__func__,
+			cfgcmd.cmd_type);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int __msm_get_pic(struct msm_sync *sync,
+		struct msm_frame *frame)
+{
+
+	int rc = 0;
+	struct msm_queue_cmd *qcmd = NULL;
+	struct msm_vfe_resp *vdata;
+	struct msm_vfe_phy_info *pphy;
+	struct msm_pmem_info pmem_info;
+	struct msm_frame *pframe;
+
+	qcmd = msm_dequeue(&sync->pict_q, list_pict);
+
+	if (!qcmd) {
+		pr_err("%s: no pic frame.\n", __func__);
+		return -EAGAIN;
+	}
+
+	if (MSM_CAM_Q_PP_MSG != qcmd->type) {
+		vdata = (struct msm_vfe_resp *)(qcmd->command);
+		pphy = &vdata->phy;
+
+		rc = msm_pmem_frame_ptov_lookup2(sync,
+				pphy->p0_phy,
+				&pmem_info,
+				1); /* mark pic frame in use */
+
+		if (rc < 0) {
+			pr_err("%s: cannot get pic frame, invalid lookup"
+				" address p0_phy add  %x p1_phy add%x\n",
+				__func__, pphy->p0_phy, pphy->p1_phy);
+			goto err;
+		}
+
+		frame->ts = qcmd->ts;
+		frame->buffer = (unsigned long)pmem_info.vaddr;
+		frame->planar0_off = pmem_info.planar0_off;
+		frame->planar1_off = pmem_info.planar1_off;
+		frame->fd = pmem_info.fd;
+		if (sync->stereocam_enabled &&
+			sync->stereo_state != STEREO_RAW_SNAP_STARTED) {
+			if (pmem_info.type == MSM_PMEM_THUMBNAIL_VPE)
+				frame->path = OUTPUT_TYPE_T;
+			else
+				frame->path = OUTPUT_TYPE_S;
+		} else
+			frame->path = vdata->phy.output_id;
+
+		CDBG("%s:p0_phy add %x, p0_phy add %x, qcmd %x, virt_addr %x\n",
+			__func__, pphy->p0_phy,
+			pphy->p1_phy, (int) qcmd, (int) frame->buffer);
+	} else { /* PP */
+		pframe = (struct msm_frame *)(qcmd->command);
+		frame->ts = qcmd->ts;
+		frame->buffer = pframe->buffer;
+		frame->planar0_off = pframe->planar0_off;
+		frame->planar1_off = pframe->planar1_off;
+		frame->fd = pframe->fd;
+		frame->path = pframe->path;
+		CDBG("%s: PP y_off %x, cbcr_off %x, path %d vaddr 0x%x\n",
+		__func__, frame->planar0_off, frame->planar1_off, frame->path,
+		(int) frame->buffer);
+	}
+
+err:
+	free_qcmd(qcmd);
+
+	return rc;
+}
+
+static int msm_get_pic(struct msm_sync *sync, void __user *arg)
+{
+	int rc = 0;
+	struct msm_frame frame;
+
+	if (copy_from_user(&frame,
+				arg,
+				sizeof(struct msm_frame))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	rc = __msm_get_pic(sync, &frame);
+	if (rc < 0)
+		return rc;
+
+	if (sync->croplen && (!sync->stereocam_enabled)) {
+		if (frame.croplen != sync->croplen) {
+			pr_err("%s: invalid frame croplen %d,"
+				"expecting %d\n",
+				__func__,
+				frame.croplen,
+				sync->croplen);
+			return -EINVAL;
+		}
+
+		if (copy_to_user((void *)frame.cropinfo,
+				sync->cropinfo,
+				sync->croplen)) {
+			ERR_COPY_TO_USER();
+			return -EFAULT;
+		}
+	}
+	CDBG("%s: copy snapshot frame to user\n", __func__);
+	if (copy_to_user((void *)arg,
+				&frame, sizeof(struct msm_frame))) {
+		ERR_COPY_TO_USER();
+		rc = -EFAULT;
+	}
+
+	CDBG("%s: got pic frame\n", __func__);
+
+	return rc;
+}
+
+static int msm_set_crop(struct msm_sync *sync, void __user *arg)
+{
+	struct crop_info crop;
+
+	mutex_lock(&sync->lock);
+	if (copy_from_user(&crop,
+				arg,
+				sizeof(struct crop_info))) {
+		ERR_COPY_FROM_USER();
+		mutex_unlock(&sync->lock);
+		return -EFAULT;
+	}
+
+	if (crop.len != CROP_LEN) {
+		mutex_unlock(&sync->lock);
+		return -EINVAL;
+	}
+
+	if (!sync->croplen) {
+		sync->cropinfo = kmalloc(crop.len, GFP_KERNEL);
+		if (!sync->cropinfo) {
+			mutex_unlock(&sync->lock);
+			return -ENOMEM;
+		}
+	}
+
+	if (copy_from_user(sync->cropinfo,
+				crop.info,
+				crop.len)) {
+		ERR_COPY_FROM_USER();
+		sync->croplen = 0;
+		kfree(sync->cropinfo);
+		mutex_unlock(&sync->lock);
+		return -EFAULT;
+	}
+
+	sync->croplen = crop.len;
+
+	mutex_unlock(&sync->lock);
+	return 0;
+}
+
+static int msm_error_config(struct msm_sync *sync, void __user *arg)
+{
+	struct msm_queue_cmd *qcmd =
+		kmalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
+
+	qcmd->command = NULL;
+
+	if (qcmd)
+		atomic_set(&(qcmd->on_heap), 1);
+
+	if (copy_from_user(&(qcmd->error_code), arg, sizeof(uint32_t))) {
+		ERR_COPY_FROM_USER();
+		free_qcmd(qcmd);
+		return -EFAULT;
+	}
+
+	pr_err("%s: Enqueue Fake Frame with error code = %d\n", __func__,
+		qcmd->error_code);
+	msm_enqueue(&sync->frame_q, &qcmd->list_frame);
+	return 0;
+}
+
+static int msm_set_fd_roi(struct msm_sync *sync, void __user *arg)
+{
+	struct fd_roi_info fd_roi;
+
+	mutex_lock(&sync->lock);
+	if (copy_from_user(&fd_roi,
+			arg,
+			sizeof(struct fd_roi_info))) {
+		ERR_COPY_FROM_USER();
+		mutex_unlock(&sync->lock);
+		return -EFAULT;
+	}
+	if (fd_roi.info_len <= 0) {
+		mutex_unlock(&sync->lock);
+		return -EFAULT;
+	}
+
+	if (!sync->fdroiinfo.info) {
+		sync->fdroiinfo.info = kmalloc(fd_roi.info_len, GFP_KERNEL);
+		if (!sync->fdroiinfo.info) {
+			mutex_unlock(&sync->lock);
+			return -ENOMEM;
+		}
+		sync->fdroiinfo.info_len = fd_roi.info_len;
+	} else if (sync->fdroiinfo.info_len < fd_roi.info_len) {
+		mutex_unlock(&sync->lock);
+		return -EINVAL;
+    }
+
+	if (copy_from_user(sync->fdroiinfo.info,
+			fd_roi.info,
+			fd_roi.info_len)) {
+		ERR_COPY_FROM_USER();
+		kfree(sync->fdroiinfo.info);
+		sync->fdroiinfo.info = NULL;
+		mutex_unlock(&sync->lock);
+		return -EFAULT;
+	}
+	mutex_unlock(&sync->lock);
+	return 0;
+}
+
+static int msm_pp_grab(struct msm_sync *sync, void __user *arg)
+{
+	uint32_t enable;
+	if (copy_from_user(&enable, arg, sizeof(enable))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	} else {
+		enable &= PP_MASK;
+		if (enable & (enable - 1)) {
+			CDBG("%s: more than one PP request!\n",
+				__func__);
+		}
+		if (sync->pp_mask) {
+			if (enable) {
+				CDBG("%s: postproc %x is already enabled\n",
+					__func__, sync->pp_mask & enable);
+			} else {
+				sync->pp_mask &= enable;
+				CDBG("%s: sync->pp_mask %d enable %d\n",
+					__func__, sync->pp_mask, enable);
+			}
+		}
+
+		CDBG("%s: sync->pp_mask %d enable %d\n", __func__,
+			sync->pp_mask, enable);
+		sync->pp_mask |= enable;
+	}
+
+	return 0;
+}
+
+static int msm_put_st_frame(struct msm_sync *sync, void __user *arg)
+{
+	unsigned long flags;
+	unsigned long st_pphy;
+	if (sync->stereocam_enabled) {
+		/* Make stereo frame ready for VPE. */
+		struct msm_st_frame stereo_frame_half;
+
+		if (copy_from_user(&stereo_frame_half, arg,
+			sizeof(stereo_frame_half))) {
+			ERR_COPY_FROM_USER();
+			return -EFAULT;
+		}
+
+		if (stereo_frame_half.type == OUTPUT_TYPE_ST_L) {
+			struct msm_vfe_resp *vfe_rp;
+			struct msm_queue_cmd *qcmd;
+
+			spin_lock_irqsave(&pp_stereocam_spinlock, flags);
+			if (!sync->pp_stereocam) {
+				pr_warning("%s: no stereo frame to deliver!\n",
+					__func__);
+				spin_unlock_irqrestore(&pp_stereocam_spinlock,
+					flags);
+				return -EINVAL;
+			}
+			CDBG("%s: delivering left frame to VPE\n", __func__);
+
+			qcmd = sync->pp_stereocam;
+			sync->pp_stereocam = NULL;
+			spin_unlock_irqrestore(&pp_stereocam_spinlock, flags);
+
+			vfe_rp = (struct msm_vfe_resp *)qcmd->command;
+
+			CDBG("%s: Left Py = 0x%x y_off = %d cbcr_off = %d\n",
+				__func__, vfe_rp->phy.p0_phy,
+				stereo_frame_half.L.buf_p0_off,
+				stereo_frame_half.L.buf_p1_off);
+
+			sync->vpefn.vpe_cfg_offset(stereo_frame_half.packing,
+			vfe_rp->phy.p0_phy + stereo_frame_half.L.buf_p0_off,
+			vfe_rp->phy.p1_phy + stereo_frame_half.L.buf_p1_off,
+			&(qcmd->ts), OUTPUT_TYPE_ST_L, stereo_frame_half.L,
+			stereo_frame_half.frame_id);
+
+			free_qcmd(qcmd);
+		} else if (stereo_frame_half.type == OUTPUT_TYPE_ST_R) {
+			CDBG("%s: delivering right frame to VPE\n", __func__);
+			spin_lock_irqsave(&st_frame_spinlock, flags);
+
+			sync->stcam_conv_value =
+				stereo_frame_half.buf_info.stcam_conv_value;
+			sync->stcam_quality_ind =
+				stereo_frame_half.buf_info.stcam_quality_ind;
+
+			st_pphy = msm_pmem_frame_vtop_lookup(sync,
+				stereo_frame_half.buf_info.buffer,
+				stereo_frame_half.buf_info.planar0_off,
+				stereo_frame_half.buf_info.planar1_off,
+				stereo_frame_half.buf_info.planar2_off,
+				stereo_frame_half.buf_info.fd,
+				0); /* Do not change the active flag. */
+
+			sync->vpefn.vpe_cfg_offset(stereo_frame_half.packing,
+				st_pphy + stereo_frame_half.R.buf_p0_off,
+				st_pphy + stereo_frame_half.R.buf_p1_off,
+				NULL, OUTPUT_TYPE_ST_R, stereo_frame_half.R,
+				stereo_frame_half.frame_id);
+
+			spin_unlock_irqrestore(&st_frame_spinlock, flags);
+		} else {
+			CDBG("%s: Invalid Msg\n", __func__);
+		}
+	}
+
+	return 0;
+}
+
+static struct msm_queue_cmd *msm_get_pp_qcmd(struct msm_frame* frame)
+{
+	struct msm_queue_cmd *qcmd =
+		kmalloc(sizeof(struct msm_queue_cmd) +
+			sizeof(struct msm_frame), GFP_ATOMIC);
+	qcmd->command = (struct msm_frame *)(qcmd + 1);
+
+	qcmd->type = MSM_CAM_Q_PP_MSG;
+
+	ktime_get_ts(&(qcmd->ts));
+	memcpy(qcmd->command, frame, sizeof(struct msm_frame));
+	atomic_set(&(qcmd->on_heap), 1);
+	return qcmd;
+}
+
+static int msm_pp_release(struct msm_sync *sync, void __user *arg)
+{
+	unsigned long flags;
+
+	if (!sync->pp_mask) {
+		pr_warning("%s: pp not in progress for\n", __func__);
+		return -EINVAL;
+	}
+	if (sync->pp_mask & PP_PREV) {
+
+
+		spin_lock_irqsave(&pp_prev_spinlock, flags);
+		if (!sync->pp_prev) {
+			pr_err("%s: no preview frame to deliver!\n",
+				__func__);
+			spin_unlock_irqrestore(&pp_prev_spinlock,
+				flags);
+			return -EINVAL;
+		}
+		CDBG("%s: delivering pp_prev\n", __func__);
+
+			if (sync->frame_q.len <= 100 &&
+				sync->event_q.len <= 100) {
+					msm_enqueue(&sync->frame_q,
+						&sync->pp_prev->list_frame);
+			} else {
+				pr_err("%s, Error Queue limit exceeded f_q=%d,\
+					e_q = %d\n",
+					__func__, sync->frame_q.len,
+					sync->event_q.len);
+				free_qcmd(sync->pp_prev);
+				goto done;
+			}
+
+			sync->pp_prev = NULL;
+			spin_unlock_irqrestore(&pp_prev_spinlock, flags);
+		goto done;
+	}
+
+	if ((sync->pp_mask & PP_SNAP) ||
+		(sync->pp_mask & PP_RAW_SNAP)) {
+		struct msm_frame frame;
+		struct msm_queue_cmd *qcmd;
+
+		if (copy_from_user(&frame,
+			arg,
+			sizeof(struct msm_frame))) {
+			ERR_COPY_FROM_USER();
+			return -EFAULT;
+		}
+		qcmd = msm_get_pp_qcmd(&frame);
+		if (!qcmd) {
+			pr_err("%s: no snapshot to deliver!\n", __func__);
+			return -EINVAL;
+		}
+		CDBG("%s: delivering pp snap\n", __func__);
+		msm_enqueue(&sync->pict_q, &qcmd->list_pict);
+	}
+
+done:
+	return 0;
+}
+
+static long msm_ioctl_common(struct msm_cam_device *pmsm,
+		unsigned int cmd,
+		void __user *argp)
+{
+	switch (cmd) {
+	case MSM_CAM_IOCTL_REGISTER_PMEM:
+		CDBG("%s cmd = MSM_CAM_IOCTL_REGISTER_PMEM\n", __func__);
+		return msm_register_pmem(pmsm->sync, argp);
+	case MSM_CAM_IOCTL_UNREGISTER_PMEM:
+		CDBG("%s cmd = MSM_CAM_IOCTL_UNREGISTER_PMEM\n", __func__);
+		return msm_pmem_table_del(pmsm->sync, argp);
+	case MSM_CAM_IOCTL_RELEASE_FRAME_BUFFER:
+		CDBG("%s cmd = MSM_CAM_IOCTL_RELEASE_FRAME_BUFFER\n", __func__);
+		return msm_put_frame_buffer(pmsm->sync, argp);
+		break;
+	default:
+		CDBG("%s cmd invalid\n", __func__);
+		return -EINVAL;
+	}
+}
+
+static long msm_ioctl_config(struct file *filep, unsigned int cmd,
+	unsigned long arg)
+{
+	int rc = -EINVAL;
+	void __user *argp = (void __user *)arg;
+	struct msm_cam_device *pmsm = filep->private_data;
+
+	CDBG("%s: cmd %d\n", __func__, _IOC_NR(cmd));
+
+	switch (cmd) {
+	case MSM_CAM_IOCTL_GET_SENSOR_INFO:
+		rc = msm_get_sensor_info(pmsm->sync, argp);
+		break;
+
+	case MSM_CAM_IOCTL_CONFIG_VFE:
+		/* Coming from config thread for update */
+		rc = msm_config_vfe(pmsm->sync, argp);
+		break;
+
+	case MSM_CAM_IOCTL_CONFIG_VPE:
+		/* Coming from config thread for update */
+		rc = msm_config_vpe(pmsm->sync, argp);
+		break;
+
+	case MSM_CAM_IOCTL_GET_STATS:
+		/* Coming from config thread wait
+		 * for vfe statistics and control requests */
+		rc = msm_get_stats(pmsm->sync, argp);
+		break;
+
+	case MSM_CAM_IOCTL_ENABLE_VFE:
+		/* This request comes from control thread:
+		 * enable either QCAMTASK or VFETASK */
+		rc = msm_enable_vfe(pmsm->sync, argp);
+		break;
+
+	case MSM_CAM_IOCTL_DISABLE_VFE:
+		/* This request comes from control thread:
+		 * disable either QCAMTASK or VFETASK */
+		rc = msm_disable_vfe(pmsm->sync, argp);
+		break;
+
+	case MSM_CAM_IOCTL_VFE_APPS_RESET:
+		msm_camio_vfe_blk_reset();
+		rc = 0;
+		break;
+
+	case MSM_CAM_IOCTL_RELEASE_STATS_BUFFER:
+		rc = msm_put_stats_buffer(pmsm->sync, argp);
+		break;
+
+	case MSM_CAM_IOCTL_AXI_CONFIG:
+	case MSM_CAM_IOCTL_AXI_VPE_CONFIG:
+		rc = msm_axi_config(pmsm->sync, argp);
+		break;
+
+	case MSM_CAM_IOCTL_SET_CROP:
+		rc = msm_set_crop(pmsm->sync, argp);
+		break;
+
+	case MSM_CAM_IOCTL_SET_FD_ROI:
+		rc = msm_set_fd_roi(pmsm->sync, argp);
+		break;
+
+	case MSM_CAM_IOCTL_PICT_PP:
+		/* Grab one preview frame or one snapshot
+		 * frame.
+		 */
+		rc = msm_pp_grab(pmsm->sync, argp);
+		break;
+
+	case MSM_CAM_IOCTL_PICT_PP_DONE:
+		/* Release the preview of snapshot frame
+		 * that was grabbed.
+		 */
+		rc = msm_pp_release(pmsm->sync, argp);
+		break;
+
+	case MSM_CAM_IOCTL_PUT_ST_FRAME:
+		/* Release the left or right frame
+		 * that was sent for stereo processing.
+		 */
+		rc = msm_put_st_frame(pmsm->sync, argp);
+		break;
+
+	case MSM_CAM_IOCTL_SENSOR_IO_CFG:
+		rc = pmsm->sync->sctrl.s_config(argp);
+		break;
+
+	case MSM_CAM_IOCTL_ERROR_CONFIG:
+		rc = msm_error_config(pmsm->sync, argp);
+		break;
+
+	case MSM_CAM_IOCTL_ABORT_CAPTURE: {
+		unsigned long flags = 0;
+		CDBG("get_pic:MSM_CAM_IOCTL_ABORT_CAPTURE\n");
+		spin_lock_irqsave(&pmsm->sync->abort_pict_lock, flags);
+		pmsm->sync->get_pic_abort = 1;
+		spin_unlock_irqrestore(&pmsm->sync->abort_pict_lock, flags);
+		wake_up(&(pmsm->sync->pict_q.wait));
+		rc = 0;
+		break;
+	}
+
+	default:
+		rc = msm_ioctl_common(pmsm, cmd, argp);
+		break;
+	}
+
+	CDBG("%s: cmd %d DONE\n", __func__, _IOC_NR(cmd));
+	return rc;
+}
+
+static int msm_unblock_poll_frame(struct msm_sync *);
+
+static long msm_ioctl_frame(struct file *filep, unsigned int cmd,
+	unsigned long arg)
+{
+	int rc = -EINVAL;
+	void __user *argp = (void __user *)arg;
+	struct msm_cam_device *pmsm = filep->private_data;
+
+
+	switch (cmd) {
+	case MSM_CAM_IOCTL_GETFRAME:
+		/* Coming from frame thread to get frame
+		 * after SELECT is done */
+		rc = msm_get_frame(pmsm->sync, argp);
+		break;
+	case MSM_CAM_IOCTL_RELEASE_FRAME_BUFFER:
+		rc = msm_put_frame_buffer(pmsm->sync, argp);
+		break;
+	case MSM_CAM_IOCTL_UNBLOCK_POLL_FRAME:
+		rc = msm_unblock_poll_frame(pmsm->sync);
+		break;
+	default:
+		break;
+	}
+
+	return rc;
+}
+
+static int msm_unblock_poll_pic(struct msm_sync *sync);
+static long msm_ioctl_pic(struct file *filep, unsigned int cmd,
+	unsigned long arg)
+{
+	int rc = -EINVAL;
+	void __user *argp = (void __user *)arg;
+	struct msm_cam_device *pmsm = filep->private_data;
+
+
+	switch (cmd) {
+	case MSM_CAM_IOCTL_GET_PICTURE:
+		rc = msm_get_pic(pmsm->sync, argp);
+		break;
+	case MSM_CAM_IOCTL_RELEASE_PIC_BUFFER:
+		rc = msm_put_pic_buffer(pmsm->sync, argp);
+		break;
+	case MSM_CAM_IOCTL_UNBLOCK_POLL_PIC_FRAME:
+		rc = msm_unblock_poll_pic(pmsm->sync);
+		break;
+	default:
+		break;
+	}
+
+	return rc;
+}
+
+
+static long msm_ioctl_control(struct file *filep, unsigned int cmd,
+	unsigned long arg)
+{
+	int rc = -EINVAL;
+	void __user *argp = (void __user *)arg;
+	struct msm_control_device *ctrl_pmsm = filep->private_data;
+	struct msm_cam_device *pmsm = ctrl_pmsm->pmsm;
+
+	switch (cmd) {
+	case MSM_CAM_IOCTL_CTRL_COMMAND:
+		/* Coming from control thread, may need to wait for
+		 * command status */
+		CDBG("calling msm_control kernel msm_ioctl_control\n");
+		mutex_lock(&ctrl_cmd_lock);
+		rc = msm_control(ctrl_pmsm, 1, argp);
+		mutex_unlock(&ctrl_cmd_lock);
+		break;
+	case MSM_CAM_IOCTL_CTRL_COMMAND_2:
+		/* Sends a message, returns immediately */
+		rc = msm_control(ctrl_pmsm, 0, argp);
+		break;
+	case MSM_CAM_IOCTL_CTRL_CMD_DONE:
+		/* Config thread calls the control thread to notify it
+		 * of the result of a MSM_CAM_IOCTL_CTRL_COMMAND.
+		 */
+		rc = msm_ctrl_cmd_done(ctrl_pmsm, argp);
+		break;
+	case MSM_CAM_IOCTL_GET_SENSOR_INFO:
+		rc = msm_get_sensor_info(pmsm->sync, argp);
+		break;
+	case MSM_CAM_IOCTL_GET_CAMERA_INFO:
+		rc = msm_get_camera_info(argp);
+		break;
+	default:
+		rc = msm_ioctl_common(pmsm, cmd, argp);
+		break;
+	}
+
+	return rc;
+}
+
+static int __msm_release(struct msm_sync *sync)
+{
+	struct msm_pmem_region *region;
+	struct hlist_node *hnode;
+	struct hlist_node *n;
+
+	mutex_lock(&sync->lock);
+	if (sync->opencnt)
+		sync->opencnt--;
+	pr_info("%s, open count =%d\n", __func__, sync->opencnt);
+	if (!sync->opencnt) {
+		/* need to clean up system resource */
+		pr_info("%s, release VFE\n", __func__);
+		if (sync->core_powered_on) {
+			if (sync->vfefn.vfe_release)
+				sync->vfefn.vfe_release(sync->pdev);
+			/*sensor release */
+			pr_info("%s, release Sensor\n", __func__);
+			sync->sctrl.s_release();
+			CDBG("%s, msm_camio_sensor_clk_off\n", __func__);
+			msm_camio_sensor_clk_off(sync->pdev);
+			if (sync->sfctrl.strobe_flash_release) {
+				CDBG("%s, strobe_flash_release\n", __func__);
+				sync->sfctrl.strobe_flash_release(
+				sync->sdata->strobe_flash_data, 1);
+			}
+		}
+		kfree(sync->cropinfo);
+		sync->cropinfo = NULL;
+		sync->croplen = 0;
+		CDBG("%s, free frame pmem region\n", __func__);
+		hlist_for_each_entry_safe(region, hnode, n,
+				&sync->pmem_frames, list) {
+			hlist_del(hnode);
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+				ion_free(client_for_ion, region->handle);
+#else
+			put_pmem_file(region->file);
+#endif
+			kfree(region);
+		}
+		CDBG("%s, free stats pmem region\n", __func__);
+		hlist_for_each_entry_safe(region, hnode, n,
+				&sync->pmem_stats, list) {
+			hlist_del(hnode);
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+				ion_free(client_for_ion, region->handle);
+#else
+			put_pmem_file(region->file);
+#endif
+			kfree(region);
+		}
+		msm_queue_drain(&sync->pict_q, list_pict);
+		msm_queue_drain(&sync->event_q, list_config);
+
+		pm_qos_update_request(&sync->idle_pm_qos, PM_QOS_DEFAULT_VALUE);
+		sync->apps_id = NULL;
+		sync->core_powered_on = 0;
+	}
+	mutex_unlock(&sync->lock);
+	ion_client_destroy(client_for_ion);
+
+	return 0;
+}
+
+static int msm_release_config(struct inode *node, struct file *filep)
+{
+	int rc;
+	struct msm_cam_device *pmsm = filep->private_data;
+	pr_info("%s: %s\n", __func__, filep->f_path.dentry->d_name.name);
+	rc = __msm_release(pmsm->sync);
+	if (!rc) {
+		msm_queue_drain(&pmsm->sync->event_q, list_config);
+		atomic_set(&pmsm->opened, 0);
+	}
+	return rc;
+}
+
+static int msm_release_control(struct inode *node, struct file *filep)
+{
+	int rc;
+	struct msm_control_device *ctrl_pmsm = filep->private_data;
+	struct msm_cam_device *pmsm = ctrl_pmsm->pmsm;
+	pr_info("%s: %s\n", __func__, filep->f_path.dentry->d_name.name);
+	g_v4l2_opencnt--;
+	mutex_lock(&pmsm->sync->lock);
+	if (pmsm->sync->core_powered_on && pmsm->sync->vfefn.vfe_stop) {
+		pr_info("%s, stop vfe if active\n", __func__);
+		pmsm->sync->vfefn.vfe_stop();
+	}
+	mutex_unlock(&pmsm->sync->lock);
+	rc = __msm_release(pmsm->sync);
+	if (!rc) {
+		msm_queue_drain(&ctrl_pmsm->ctrl_q, list_control);
+		kfree(ctrl_pmsm);
+	}
+	return rc;
+}
+
+static int msm_release_frame(struct inode *node, struct file *filep)
+{
+	int rc;
+	struct msm_cam_device *pmsm = filep->private_data;
+	pr_info("%s: %s\n", __func__, filep->f_path.dentry->d_name.name);
+	rc = __msm_release(pmsm->sync);
+	if (!rc) {
+		msm_queue_drain(&pmsm->sync->frame_q, list_frame);
+		atomic_set(&pmsm->opened, 0);
+	}
+	return rc;
+}
+
+
+static int msm_release_pic(struct inode *node, struct file *filep)
+{
+	int rc;
+	struct msm_cam_device *pmsm = filep->private_data;
+	CDBG("%s: %s\n", __func__, filep->f_path.dentry->d_name.name);
+	rc = __msm_release(pmsm->sync);
+	if (!rc) {
+		msm_queue_drain(&pmsm->sync->pict_q, list_pict);
+		atomic_set(&pmsm->opened, 0);
+	}
+	return rc;
+}
+
+static int msm_unblock_poll_pic(struct msm_sync *sync)
+{
+	unsigned long flags;
+	CDBG("%s\n", __func__);
+	spin_lock_irqsave(&sync->pict_q.lock, flags);
+	sync->unblock_poll_pic_frame = 1;
+	wake_up(&sync->pict_q.wait);
+	spin_unlock_irqrestore(&sync->pict_q.lock, flags);
+	return 0;
+}
+
+static int msm_unblock_poll_frame(struct msm_sync *sync)
+{
+	unsigned long flags;
+	CDBG("%s\n", __func__);
+	spin_lock_irqsave(&sync->frame_q.lock, flags);
+	sync->unblock_poll_frame = 1;
+	wake_up(&sync->frame_q.wait);
+	spin_unlock_irqrestore(&sync->frame_q.lock, flags);
+	return 0;
+}
+
+static unsigned int __msm_poll_frame(struct msm_sync *sync,
+		struct file *filep,
+		struct poll_table_struct *pll_table)
+{
+	int rc = 0;
+	unsigned long flags;
+
+	poll_wait(filep, &sync->frame_q.wait, pll_table);
+
+	spin_lock_irqsave(&sync->frame_q.lock, flags);
+	if (!list_empty_careful(&sync->frame_q.list))
+		/* frame ready */
+		rc = POLLIN | POLLRDNORM;
+	if (sync->unblock_poll_frame) {
+		CDBG("%s: sync->unblock_poll_frame is true\n", __func__);
+		rc |= POLLPRI;
+		sync->unblock_poll_frame = 0;
+	}
+	spin_unlock_irqrestore(&sync->frame_q.lock, flags);
+
+	return rc;
+}
+
+static unsigned int __msm_poll_pic(struct msm_sync *sync,
+		struct file *filep,
+		struct poll_table_struct *pll_table)
+{
+	int rc = 0;
+	unsigned long flags;
+
+	poll_wait(filep, &sync->pict_q.wait , pll_table);
+	spin_lock_irqsave(&sync->abort_pict_lock, flags);
+	if (sync->get_pic_abort == 1) {
+		/* TODO: need to pass an error case */
+		sync->get_pic_abort = 0;
+	}
+	spin_unlock_irqrestore(&sync->abort_pict_lock, flags);
+
+	spin_lock_irqsave(&sync->pict_q.lock, flags);
+	if (!list_empty_careful(&sync->pict_q.list))
+		/* frame ready */
+		rc = POLLIN | POLLRDNORM;
+	if (sync->unblock_poll_pic_frame) {
+		CDBG("%s: sync->unblock_poll_pic_frame is true\n", __func__);
+		rc |= POLLPRI;
+		sync->unblock_poll_pic_frame = 0;
+	}
+	spin_unlock_irqrestore(&sync->pict_q.lock, flags);
+
+	return rc;
+}
+
+static unsigned int msm_poll_frame(struct file *filep,
+	struct poll_table_struct *pll_table)
+{
+	struct msm_cam_device *pmsm = filep->private_data;
+	return __msm_poll_frame(pmsm->sync, filep, pll_table);
+}
+
+static unsigned int msm_poll_pic(struct file *filep,
+	struct poll_table_struct *pll_table)
+{
+	struct msm_cam_device *pmsm = filep->private_data;
+	return __msm_poll_pic(pmsm->sync, filep, pll_table);
+}
+
+static unsigned int __msm_poll_config(struct msm_sync *sync,
+		struct file *filep,
+		struct poll_table_struct *pll_table)
+{
+	int rc = 0;
+	unsigned long flags;
+
+	poll_wait(filep, &sync->event_q.wait, pll_table);
+
+	spin_lock_irqsave(&sync->event_q.lock, flags);
+	if (!list_empty_careful(&sync->event_q.list))
+		/* event ready */
+		rc = POLLIN | POLLRDNORM;
+	spin_unlock_irqrestore(&sync->event_q.lock, flags);
+
+	return rc;
+}
+
+static unsigned int msm_poll_config(struct file *filep,
+	struct poll_table_struct *pll_table)
+{
+	struct msm_cam_device *pmsm = filep->private_data;
+	return __msm_poll_config(pmsm->sync, filep, pll_table);
+}
+
+/*
+ * This function executes in interrupt context.
+ */
+
+static void *msm_vfe_sync_alloc(int size,
+			void *syncdata __attribute__((unused)),
+			gfp_t gfp)
+{
+	struct msm_queue_cmd *qcmd =
+		kzalloc(sizeof(struct msm_queue_cmd) + size, gfp);
+	if (qcmd) {
+		atomic_set(&qcmd->on_heap, 1);
+		return qcmd + 1;
+	}
+	return NULL;
+}
+
+static void *msm_vpe_sync_alloc(int size,
+			void *syncdata __attribute__((unused)),
+			gfp_t gfp)
+{
+	struct msm_queue_cmd *qcmd =
+		kzalloc(sizeof(struct msm_queue_cmd) + size, gfp);
+	if (qcmd) {
+		atomic_set(&qcmd->on_heap, 1);
+		return qcmd + 1;
+	}
+	return NULL;
+}
+
+static void msm_vfe_sync_free(void *ptr)
+{
+	if (ptr) {
+		struct msm_queue_cmd *qcmd =
+			(struct msm_queue_cmd *)ptr;
+		qcmd--;
+		if (atomic_read(&qcmd->on_heap))
+			kfree(qcmd);
+	}
+}
+
+static void msm_vpe_sync_free(void *ptr)
+{
+	if (ptr) {
+		struct msm_queue_cmd *qcmd =
+			(struct msm_queue_cmd *)ptr;
+		qcmd--;
+		if (atomic_read(&qcmd->on_heap))
+			kfree(qcmd);
+	}
+}
+
+/*
+ * This function executes in interrupt context.
+ */
+
+static void msm_vfe_sync(struct msm_vfe_resp *vdata,
+		enum msm_queue qtype, void *syncdata,
+		gfp_t gfp)
+{
+	struct msm_queue_cmd *qcmd = NULL;
+	struct msm_sync *sync = (struct msm_sync *)syncdata;
+	unsigned long flags;
+
+	if (!sync) {
+		pr_err("%s: no context in dsp callback.\n", __func__);
+		return;
+	}
+
+	qcmd = ((struct msm_queue_cmd *)vdata) - 1;
+	qcmd->type = qtype;
+	qcmd->command = vdata;
+
+	ktime_get_ts(&(qcmd->ts));
+
+	if (qtype != MSM_CAM_Q_VFE_MSG)
+		goto vfe_for_config;
+
+	CDBG("%s: vdata->type %d\n", __func__, vdata->type);
+
+	switch (vdata->type) {
+	case VFE_MSG_OUTPUT_P:
+		if (sync->pp_mask & PP_PREV) {
+			CDBG("%s: PP_PREV in progress: p0_add %x p1_add %x\n",
+				__func__,
+				vdata->phy.p0_phy,
+				vdata->phy.p1_phy);
+			spin_lock_irqsave(&pp_prev_spinlock, flags);
+			if (sync->pp_prev)
+				CDBG("%s: overwriting pp_prev!\n",
+					__func__);
+			CDBG("%s: sending preview to config\n", __func__);
+			sync->pp_prev = qcmd;
+			spin_unlock_irqrestore(&pp_prev_spinlock, flags);
+			sync->pp_frame_avail = 1;
+			if (atomic_read(&qcmd->on_heap))
+				atomic_add(1, &qcmd->on_heap);
+			break;
+		}
+		CDBG("%s: msm_enqueue frame_q\n", __func__);
+		if (sync->stereocam_enabled)
+			CDBG("%s: Enqueue VFE_MSG_OUTPUT_P to event_q for "
+				"stereo processing\n", __func__);
+		else {
+			if (sync->frame_q.len <= 100 &&
+				sync->event_q.len <= 100) {
+				if (atomic_read(&qcmd->on_heap))
+					atomic_add(1, &qcmd->on_heap);
+				msm_enqueue(&sync->frame_q, &qcmd->list_frame);
+			} else {
+				pr_err("%s, Error Queue limit exceeded "
+					"f_q = %d, e_q = %d\n",	__func__,
+					sync->frame_q.len, sync->event_q.len);
+				free_qcmd(qcmd);
+				return;
+			}
+		}
+		break;
+
+	case VFE_MSG_OUTPUT_T:
+		if (sync->stereocam_enabled) {
+			spin_lock_irqsave(&pp_stereocam_spinlock, flags);
+
+			/* if out1/2 is currently in progress, save the qcmd
+			and issue only ionce the 1st one completes the 3D
+			pipeline */
+			if (STEREO_SNAP_BUFFER1_PROCESSING ==
+				sync->stereo_state) {
+				sync->pp_stereocam2 = qcmd;
+				spin_unlock_irqrestore(&pp_stereocam_spinlock,
+					flags);
+				if (atomic_read(&qcmd->on_heap))
+					atomic_add(1, &qcmd->on_heap);
+				CDBG("%s: snapshot stereo in progress\n",
+					__func__);
+				return;
+			}
+
+			if (sync->pp_stereocam)
+				CDBG("%s: overwriting pp_stereocam!\n",
+					__func__);
+
+			CDBG("%s: sending stereo frame to config\n", __func__);
+			sync->pp_stereocam = qcmd;
+			sync->stereo_state =
+				STEREO_SNAP_BUFFER1_PROCESSING;
+
+			spin_unlock_irqrestore(&pp_stereocam_spinlock, flags);
+
+			/* Increament on_heap by one because the same qcmd will
+			be used for VPE in msm_pp_release. */
+			if (atomic_read(&qcmd->on_heap))
+				atomic_add(1, &qcmd->on_heap);
+			CDBG("%s: Enqueue VFE_MSG_OUTPUT_T to event_q for "
+				"stereo processing.\n", __func__);
+			break;
+		}
+		if (sync->pp_mask & PP_SNAP) {
+			CDBG("%s: pp sending thumbnail to config\n",
+				__func__);
+		} else {
+			msm_enqueue(&sync->pict_q, &qcmd->list_pict);
+			return;
+		}
+
+	case VFE_MSG_OUTPUT_S:
+		if (sync->stereocam_enabled &&
+			sync->stereo_state != STEREO_RAW_SNAP_STARTED) {
+			spin_lock_irqsave(&pp_stereocam_spinlock, flags);
+
+			/* if out1/2 is currently in progress, save the qcmd
+			and issue only once the 1st one completes the 3D
+			pipeline */
+			if (STEREO_SNAP_BUFFER1_PROCESSING ==
+				sync->stereo_state) {
+				sync->pp_stereocam2 = qcmd;
+				spin_unlock_irqrestore(&pp_stereocam_spinlock,
+					flags);
+				if (atomic_read(&qcmd->on_heap))
+					atomic_add(1, &qcmd->on_heap);
+				CDBG("%s: snapshot stereo in progress\n",
+					__func__);
+				return;
+			}
+			if (sync->pp_stereocam)
+				CDBG("%s: overwriting pp_stereocam!\n",
+					__func__);
+
+			CDBG("%s: sending stereo frame to config\n", __func__);
+			sync->pp_stereocam = qcmd;
+			sync->stereo_state =
+				STEREO_SNAP_BUFFER1_PROCESSING;
+
+			spin_unlock_irqrestore(&pp_stereocam_spinlock, flags);
+
+			/* Increament on_heap by one because the same qcmd will
+			be used for VPE in msm_pp_release. */
+			if (atomic_read(&qcmd->on_heap))
+				atomic_add(1, &qcmd->on_heap);
+			CDBG("%s: Enqueue VFE_MSG_OUTPUT_S to event_q for "
+				"stereo processing.\n", __func__);
+			break;
+		}
+		if (sync->pp_mask & PP_SNAP) {
+			CDBG("%s: pp sending main image to config\n",
+				__func__);
+		} else {
+			CDBG("%s: enqueue to picture queue\n", __func__);
+			msm_enqueue(&sync->pict_q, &qcmd->list_pict);
+			return;
+		}
+		break;
+
+	case VFE_MSG_OUTPUT_V:
+		if (sync->stereocam_enabled) {
+			spin_lock_irqsave(&pp_stereocam_spinlock, flags);
+
+			if (sync->pp_stereocam)
+				CDBG("%s: overwriting pp_stereocam!\n",
+					__func__);
+
+			CDBG("%s: sending stereo frame to config\n", __func__);
+			sync->pp_stereocam = qcmd;
+
+			spin_unlock_irqrestore(&pp_stereocam_spinlock, flags);
+
+			/* Increament on_heap by one because the same qcmd will
+			be used for VPE in msm_pp_release. */
+			if (atomic_read(&qcmd->on_heap))
+				atomic_add(1, &qcmd->on_heap);
+			CDBG("%s: Enqueue VFE_MSG_OUTPUT_V to event_q for "
+				"stereo processing.\n", __func__);
+			break;
+		}
+		if (sync->vpefn.vpe_cfg_update) {
+			CDBG("dis_en = %d\n", *sync->vpefn.dis);
+			if (*(sync->vpefn.dis)) {
+				memset(&(vdata->vpe_bf), 0,
+					sizeof(vdata->vpe_bf));
+
+				if (sync->cropinfo != NULL)
+					vdata->vpe_bf.vpe_crop =
+				*(struct video_crop_t *)(sync->cropinfo);
+
+				vdata->vpe_bf.p0_phy = vdata->phy.p0_phy;
+				vdata->vpe_bf.p1_phy = vdata->phy.p1_phy;
+				vdata->vpe_bf.ts = (qcmd->ts);
+				vdata->vpe_bf.frame_id = vdata->phy.frame_id;
+				qcmd->command = vdata;
+				msm_enqueue_vpe(&sync->vpe_q,
+					&qcmd->list_vpe_frame);
+				return;
+			} else if (sync->vpefn.vpe_cfg_update(sync->cropinfo)) {
+				CDBG("%s: msm_enqueue video frame to vpe time "
+					"= %ld\n", __func__, qcmd->ts.tv_nsec);
+
+				sync->vpefn.send_frame_to_vpe(
+					vdata->phy.p0_phy,
+					vdata->phy.p1_phy,
+					&(qcmd->ts), OUTPUT_TYPE_V);
+
+				free_qcmd(qcmd);
+				return;
+			} else {
+				CDBG("%s: msm_enqueue video frame_q\n",
+					__func__);
+				if (sync->liveshot_enabled) {
+					CDBG("%s: msm_enqueue liveshot\n",
+						__func__);
+					vdata->phy.output_id |= OUTPUT_TYPE_L;
+					sync->liveshot_enabled = false;
+				}
+				if (sync->frame_q.len <= 100 &&
+					sync->event_q.len <= 100) {
+						msm_enqueue(&sync->frame_q,
+							&qcmd->list_frame);
+				} else {
+					pr_err("%s, Error Queue limit exceeded\
+						f_q = %d, e_q = %d\n",
+						__func__, sync->frame_q.len,
+						sync->event_q.len);
+					free_qcmd(qcmd);
+				}
+
+				return;
+			}
+		} else {
+			CDBG("%s: msm_enqueue video frame_q\n",	__func__);
+			if (sync->frame_q.len <= 100 &&
+				sync->event_q.len <= 100) {
+				msm_enqueue(&sync->frame_q, &qcmd->list_frame);
+			} else {
+				pr_err("%s, Error Queue limit exceeded\
+					f_q = %d, e_q = %d\n",
+					__func__, sync->frame_q.len,
+					sync->event_q.len);
+				free_qcmd(qcmd);
+			}
+
+			return;
+		}
+
+	case VFE_MSG_SNAPSHOT:
+		if (sync->pp_mask & (PP_SNAP | PP_RAW_SNAP)) {
+			CDBG("%s: PP_SNAP in progress: pp_mask %x\n",
+				__func__, sync->pp_mask);
+		} else {
+			if (atomic_read(&qcmd->on_heap))
+				atomic_add(1, &qcmd->on_heap);
+			CDBG("%s: VFE_MSG_SNAPSHOT store\n",
+				__func__);
+			if (sync->stereocam_enabled &&
+				sync->stereo_state != STEREO_RAW_SNAP_STARTED) {
+				sync->pp_stereosnap = qcmd;
+				return;
+			}
+		}
+		break;
+
+	case VFE_MSG_COMMON:
+		CDBG("%s: qtype %d, comp stats, enqueue event_q.\n",
+			__func__, vdata->type);
+		break;
+
+	case VFE_MSG_GENERAL:
+		CDBG("%s: qtype %d, general msg, enqueue event_q.\n",
+			__func__, vdata->type);
+		break;
+
+	default:
+		CDBG("%s: qtype %d not handled\n", __func__, vdata->type);
+		/* fall through, send to config. */
+	}
+
+vfe_for_config:
+	CDBG("%s: msm_enqueue event_q\n", __func__);
+	if (sync->frame_q.len <= 100 && sync->event_q.len <= 100) {
+		msm_enqueue(&sync->event_q, &qcmd->list_config);
+	} else if (sync->event_q.len > 100) {
+		pr_err("%s, Error Event Queue limit exceeded f_q = %d, e_q = %d\n",
+			__func__, sync->frame_q.len, sync->event_q.len);
+		qcmd->error_code = 0xffffffff;
+		qcmd->command = NULL;
+		msm_enqueue(&sync->frame_q, &qcmd->list_frame);
+	} else {
+		pr_err("%s, Error Queue limit exceeded f_q = %d, e_q = %d\n",
+			__func__, sync->frame_q.len, sync->event_q.len);
+		free_qcmd(qcmd);
+	}
+
+}
+
+static void msm_vpe_sync(struct msm_vpe_resp *vdata,
+	enum msm_queue qtype, void *syncdata, void *ts, gfp_t gfp)
+{
+	struct msm_queue_cmd *qcmd = NULL;
+	unsigned long flags;
+
+	struct msm_sync *sync = (struct msm_sync *)syncdata;
+	if (!sync) {
+		pr_err("%s: no context in dsp callback.\n", __func__);
+		return;
+	}
+
+	qcmd = ((struct msm_queue_cmd *)vdata) - 1;
+	qcmd->type = qtype;
+	qcmd->command = vdata;
+	qcmd->ts = *((struct timespec *)ts);
+
+	if (qtype != MSM_CAM_Q_VPE_MSG) {
+		pr_err("%s: Invalid qcmd type = %d.\n", __func__, qcmd->type);
+		free_qcmd(qcmd);
+		return;
+	}
+
+	CDBG("%s: vdata->type %d\n", __func__, vdata->type);
+	switch (vdata->type) {
+	case VPE_MSG_OUTPUT_V:
+		if (sync->liveshot_enabled) {
+			CDBG("%s: msm_enqueue liveshot %d\n", __func__,
+				sync->liveshot_enabled);
+			vdata->phy.output_id |= OUTPUT_TYPE_L;
+			sync->liveshot_enabled = false;
+		}
+		vdata->phy.p2_phy = vdata->phy.p0_phy;
+		if (sync->frame_q.len <= 100 && sync->event_q.len <= 100) {
+			CDBG("%s: enqueue to frame_q from VPE\n", __func__);
+			msm_enqueue(&sync->frame_q, &qcmd->list_frame);
+		} else {
+			pr_err("%s, Error Queue limit exceeded f_q = %d, "
+				"e_q = %d\n", __func__, sync->frame_q.len,
+				sync->event_q.len);
+			free_qcmd(qcmd);
+		}
+		return;
+
+	case VPE_MSG_OUTPUT_ST_L:
+		CDBG("%s: enqueue left frame done msg to event_q from VPE\n",
+			__func__);
+		msm_enqueue(&sync->event_q, &qcmd->list_config);
+		return;
+
+	case VPE_MSG_OUTPUT_ST_R:
+		spin_lock_irqsave(&pp_stereocam_spinlock, flags);
+		CDBG("%s: received VPE_MSG_OUTPUT_ST_R state %d\n", __func__,
+			sync->stereo_state);
+
+		if (STEREO_SNAP_BUFFER1_PROCESSING == sync->stereo_state) {
+			msm_enqueue(&sync->pict_q, &qcmd->list_pict);
+			qcmd = sync->pp_stereocam2;
+			sync->pp_stereocam = sync->pp_stereocam2;
+			sync->pp_stereocam2 = NULL;
+			msm_enqueue(&sync->event_q, &qcmd->list_config);
+			sync->stereo_state =
+				STEREO_SNAP_BUFFER2_PROCESSING;
+		} else if (STEREO_SNAP_BUFFER2_PROCESSING ==
+				sync->stereo_state) {
+			sync->stereo_state = STEREO_SNAP_IDLE;
+			/* Send snapshot DONE */
+			msm_enqueue(&sync->pict_q, &qcmd->list_pict);
+			qcmd = sync->pp_stereosnap;
+			sync->pp_stereosnap = NULL;
+			CDBG("%s: send SNAPSHOT_DONE message\n", __func__);
+			msm_enqueue(&sync->event_q, &qcmd->list_config);
+		} else {
+			if (atomic_read(&qcmd->on_heap))
+				atomic_add(1, &qcmd->on_heap);
+			msm_enqueue(&sync->event_q, &qcmd->list_config);
+			if (sync->stereo_state == STEREO_VIDEO_ACTIVE) {
+				CDBG("%s: st frame to frame_q from VPE\n",
+					__func__);
+				msm_enqueue(&sync->frame_q, &qcmd->list_frame);
+			}
+		}
+		spin_unlock_irqrestore(&pp_stereocam_spinlock, flags);
+		return;
+
+	default:
+		pr_err("%s: qtype %d not handled\n", __func__, vdata->type);
+	}
+	pr_err("%s: Should not come here. Error.\n", __func__);
+}
+
+static struct msm_vpe_callback msm_vpe_s = {
+	.vpe_resp = msm_vpe_sync,
+	.vpe_alloc = msm_vpe_sync_alloc,
+	.vpe_free = msm_vpe_sync_free,
+};
+
+static struct msm_vfe_callback msm_vfe_s = {
+	.vfe_resp = msm_vfe_sync,
+	.vfe_alloc = msm_vfe_sync_alloc,
+	.vfe_free = msm_vfe_sync_free,
+};
+
+static int __msm_open(struct msm_cam_device *pmsm, const char *const apps_id,
+			int is_controlnode)
+{
+	int rc = 0;
+	struct msm_sync *sync = pmsm->sync;
+
+	mutex_lock(&sync->lock);
+	if (sync->apps_id && strcmp(sync->apps_id, apps_id)
+				&& (!strcmp(MSM_APPS_ID_V4L2, apps_id))) {
+		pr_err("%s(%s): sensor %s is already opened for %s\n",
+			__func__,
+			apps_id,
+			sync->sdata->sensor_name,
+			sync->apps_id);
+		rc = -EBUSY;
+		goto msm_open_done;
+	}
+
+	sync->apps_id = apps_id;
+
+	if (!sync->core_powered_on && !is_controlnode) {
+		pm_qos_update_request(&sync->idle_pm_qos,
+			msm_cpuidle_get_deep_idle_latency());
+
+		msm_camvfe_fn_init(&sync->vfefn, sync);
+		if (sync->vfefn.vfe_init) {
+			sync->pp_frame_avail = 0;
+			sync->get_pic_abort = 0;
+			rc = msm_camio_sensor_clk_on(sync->pdev);
+			if (rc < 0) {
+				pr_err("%s: setting sensor clocks failed: %d\n",
+					__func__, rc);
+				goto msm_open_err;
+			}
+			rc = sync->sctrl.s_init(sync->sdata);
+			if (rc < 0) {
+				pr_err("%s: sensor init failed: %d\n",
+					__func__, rc);
+				msm_camio_sensor_clk_off(sync->pdev);
+				goto msm_open_err;
+			}
+			rc = sync->vfefn.vfe_init(&msm_vfe_s,
+				sync->pdev);
+			if (rc < 0) {
+				pr_err("%s: vfe_init failed at %d\n",
+					__func__, rc);
+				sync->sctrl.s_release();
+				msm_camio_sensor_clk_off(sync->pdev);
+				goto msm_open_err;
+			}
+		} else {
+			pr_err("%s: no sensor init func\n", __func__);
+			rc = -ENODEV;
+			goto msm_open_err;
+		}
+		msm_camvpe_fn_init(&sync->vpefn, sync);
+
+		spin_lock_init(&sync->abort_pict_lock);
+		spin_lock_init(&pp_prev_spinlock);
+		spin_lock_init(&pp_stereocam_spinlock);
+		spin_lock_init(&st_frame_spinlock);
+		if (rc >= 0) {
+			msm_region_init(sync);
+			if (sync->vpefn.vpe_reg)
+				sync->vpefn.vpe_reg(&msm_vpe_s);
+			sync->unblock_poll_frame = 0;
+			sync->unblock_poll_pic_frame = 0;
+		}
+		sync->core_powered_on = 1;
+	}
+	sync->opencnt++;
+	client_for_ion = msm_ion_client_create(-1, "camera");
+
+msm_open_done:
+	mutex_unlock(&sync->lock);
+	return rc;
+
+msm_open_err:
+	atomic_set(&pmsm->opened, 0);
+	mutex_unlock(&sync->lock);
+	return rc;
+}
+
+static int msm_open_common(struct inode *inode, struct file *filep,
+			int once, int is_controlnode)
+{
+	int rc;
+	struct msm_cam_device *pmsm =
+		container_of(inode->i_cdev, struct msm_cam_device, cdev);
+
+	CDBG("%s: open %s\n", __func__, filep->f_path.dentry->d_name.name);
+
+	if (atomic_cmpxchg(&pmsm->opened, 0, 1) && once) {
+		pr_err("%s: %s is already opened.\n",
+			__func__,
+			filep->f_path.dentry->d_name.name);
+		return -EBUSY;
+	}
+
+	rc = nonseekable_open(inode, filep);
+	if (rc < 0) {
+		pr_err("%s: nonseekable_open error %d\n", __func__, rc);
+		return rc;
+	}
+
+	rc = __msm_open(pmsm, MSM_APPS_ID_PROP, is_controlnode);
+	if (rc < 0)
+		return rc;
+	filep->private_data = pmsm;
+	CDBG("%s: rc %d\n", __func__, rc);
+	return rc;
+}
+
+static int msm_open_frame(struct inode *inode, struct file *filep)
+{
+	struct msm_cam_device *pmsm =
+		container_of(inode->i_cdev, struct msm_cam_device, cdev);
+	msm_queue_drain(&pmsm->sync->frame_q, list_frame);
+	return msm_open_common(inode, filep, 1, 0);
+}
+
+static int msm_open(struct inode *inode, struct file *filep)
+{
+	return msm_open_common(inode, filep, 1, 0);
+}
+
+static int msm_open_control(struct inode *inode, struct file *filep)
+{
+	int rc;
+
+	struct msm_control_device *ctrl_pmsm =
+		kmalloc(sizeof(struct msm_control_device), GFP_KERNEL);
+	if (!ctrl_pmsm)
+		return -ENOMEM;
+
+	rc = msm_open_common(inode, filep, 0, 1);
+	if (rc < 0) {
+		kfree(ctrl_pmsm);
+		return rc;
+	}
+	ctrl_pmsm->pmsm = filep->private_data;
+	filep->private_data = ctrl_pmsm;
+
+	msm_queue_init(&ctrl_pmsm->ctrl_q, "control");
+
+	if (!g_v4l2_opencnt)
+		g_v4l2_control_device = ctrl_pmsm;
+	g_v4l2_opencnt++;
+	CDBG("%s: rc %d\n", __func__, rc);
+	return rc;
+}
+
+static const struct file_operations msm_fops_config = {
+	.owner = THIS_MODULE,
+	.open = msm_open,
+	.unlocked_ioctl = msm_ioctl_config,
+	.release = msm_release_config,
+	.poll = msm_poll_config,
+};
+
+static const struct file_operations msm_fops_control = {
+	.owner = THIS_MODULE,
+	.open = msm_open_control,
+	.unlocked_ioctl = msm_ioctl_control,
+	.release = msm_release_control,
+};
+
+static const struct file_operations msm_fops_frame = {
+	.owner = THIS_MODULE,
+	.open = msm_open_frame,
+	.unlocked_ioctl = msm_ioctl_frame,
+	.release = msm_release_frame,
+	.poll = msm_poll_frame,
+};
+
+static const struct file_operations msm_fops_pic = {
+	.owner = THIS_MODULE,
+	.open = msm_open,
+	.unlocked_ioctl = msm_ioctl_pic,
+	.release = msm_release_pic,
+	.poll = msm_poll_pic,
+};
+
+static int msm_setup_cdev(struct msm_cam_device *msm,
+			int node,
+			dev_t devno,
+			const char *suffix,
+			const struct file_operations *fops)
+{
+	int rc = -ENODEV;
+
+	struct device *device =
+		device_create(msm_class, NULL,
+			devno, NULL,
+			"%s%d", suffix, node);
+
+	if (IS_ERR(device)) {
+		rc = PTR_ERR(device);
+		pr_err("%s: error creating device: %d\n", __func__, rc);
+		return rc;
+	}
+
+	cdev_init(&msm->cdev, fops);
+	msm->cdev.owner = THIS_MODULE;
+
+	rc = cdev_add(&msm->cdev, devno, 1);
+	if (rc < 0) {
+		pr_err("%s: error adding cdev: %d\n", __func__, rc);
+		device_destroy(msm_class, devno);
+		return rc;
+	}
+
+	return rc;
+}
+
+static int msm_tear_down_cdev(struct msm_cam_device *msm, dev_t devno)
+{
+	cdev_del(&msm->cdev);
+	device_destroy(msm_class, devno);
+	return 0;
+}
+
+static int msm_sync_init(struct msm_sync *sync,
+		struct platform_device *pdev,
+		int (*sensor_probe)(const struct msm_camera_sensor_info *,
+				struct msm_sensor_ctrl *))
+{
+	int rc = 0;
+	struct msm_sensor_ctrl sctrl;
+	sync->sdata = pdev->dev.platform_data;
+
+	msm_queue_init(&sync->event_q, "event");
+	msm_queue_init(&sync->frame_q, "frame");
+	msm_queue_init(&sync->pict_q, "pict");
+	msm_queue_init(&sync->vpe_q, "vpe");
+
+	pm_qos_add_request(&sync->idle_pm_qos, PM_QOS_CPU_DMA_LATENCY,
+					   PM_QOS_DEFAULT_VALUE);
+
+	rc = msm_camio_probe_on(pdev);
+	if (rc < 0) {
+		pm_qos_remove_request(&sync->idle_pm_qos);
+		return rc;
+	}
+	rc = sensor_probe(sync->sdata, &sctrl);
+	if (rc >= 0) {
+		sync->pdev = pdev;
+		sync->sctrl = sctrl;
+	}
+	msm_camio_probe_off(pdev);
+	if (rc < 0) {
+		pr_err("%s: failed to initialize %s\n",
+			__func__,
+			sync->sdata->sensor_name);
+		pm_qos_remove_request(&sync->idle_pm_qos);
+		return rc;
+	}
+
+	sync->opencnt = 0;
+	sync->core_powered_on = 0;
+	sync->ignore_qcmd = false;
+	sync->ignore_qcmd_type = -1;
+	mutex_init(&sync->lock);
+	if (sync->sdata->strobe_flash_data) {
+		sync->sdata->strobe_flash_data->state = 0;
+		spin_lock_init(&sync->sdata->strobe_flash_data->spin_lock);
+	}
+	CDBG("%s: initialized %s\n", __func__, sync->sdata->sensor_name);
+	return rc;
+}
+
+static int msm_sync_destroy(struct msm_sync *sync)
+{
+	pm_qos_remove_request(&sync->idle_pm_qos);
+	return 0;
+}
+
+static int msm_device_init(struct msm_cam_device *pmsm,
+		struct msm_sync *sync,
+		int node)
+{
+	int dev_num = 4 * node;
+	int rc = msm_setup_cdev(pmsm, node,
+		MKDEV(MAJOR(msm_devno), dev_num),
+		"control", &msm_fops_control);
+	if (rc < 0) {
+		pr_err("%s: error creating control node: %d\n", __func__, rc);
+		return rc;
+	}
+
+	rc = msm_setup_cdev(pmsm + 1, node,
+		MKDEV(MAJOR(msm_devno), dev_num + 1),
+		"config", &msm_fops_config);
+	if (rc < 0) {
+		pr_err("%s: error creating config node: %d\n", __func__, rc);
+		msm_tear_down_cdev(pmsm, MKDEV(MAJOR(msm_devno),
+				dev_num));
+		return rc;
+	}
+
+	rc = msm_setup_cdev(pmsm + 2, node,
+		MKDEV(MAJOR(msm_devno), dev_num + 2),
+		"frame", &msm_fops_frame);
+	if (rc < 0) {
+		pr_err("%s: error creating frame node: %d\n", __func__, rc);
+		msm_tear_down_cdev(pmsm,
+			MKDEV(MAJOR(msm_devno), dev_num));
+		msm_tear_down_cdev(pmsm + 1,
+			MKDEV(MAJOR(msm_devno), dev_num + 1));
+		return rc;
+	}
+
+	rc = msm_setup_cdev(pmsm + 3, node,
+		MKDEV(MAJOR(msm_devno), dev_num + 3),
+		"pic", &msm_fops_pic);
+	if (rc < 0) {
+		pr_err("%s: error creating pic node: %d\n", __func__, rc);
+		msm_tear_down_cdev(pmsm,
+			MKDEV(MAJOR(msm_devno), dev_num));
+		msm_tear_down_cdev(pmsm + 1,
+			MKDEV(MAJOR(msm_devno), dev_num + 1));
+		msm_tear_down_cdev(pmsm + 2,
+			MKDEV(MAJOR(msm_devno), dev_num + 2));
+		return rc;
+	}
+
+
+	atomic_set(&pmsm[0].opened, 0);
+	atomic_set(&pmsm[1].opened, 0);
+	atomic_set(&pmsm[2].opened, 0);
+	atomic_set(&pmsm[3].opened, 0);
+
+	pmsm[0].sync = sync;
+	pmsm[1].sync = sync;
+	pmsm[2].sync = sync;
+	pmsm[3].sync = sync;
+
+	return rc;
+}
+
+int msm_camera_drv_start(struct platform_device *dev,
+		int (*sensor_probe)(const struct msm_camera_sensor_info *,
+			struct msm_sensor_ctrl *))
+{
+	struct msm_cam_device *pmsm = NULL;
+	struct msm_sync *sync;
+	int rc = -ENODEV;
+
+	if (camera_node >= MSM_MAX_CAMERA_SENSORS) {
+		pr_err("%s: too many camera sensors\n", __func__);
+		return rc;
+	}
+
+	if (!msm_class) {
+		/* There are three device nodes per sensor */
+		rc = alloc_chrdev_region(&msm_devno, 0,
+				4 * MSM_MAX_CAMERA_SENSORS,
+				"msm_camera");
+		if (rc < 0) {
+			pr_err("%s: failed to allocate chrdev: %d\n", __func__,
+				rc);
+			return rc;
+		}
+
+		msm_class = class_create(THIS_MODULE, "msm_camera");
+		if (IS_ERR(msm_class)) {
+			rc = PTR_ERR(msm_class);
+			pr_err("%s: create device class failed: %d\n",
+				__func__, rc);
+			return rc;
+		}
+	}
+
+	pmsm = kzalloc(sizeof(struct msm_cam_device) * 4 +
+			sizeof(struct msm_sync), GFP_ATOMIC);
+	if (!pmsm)
+		return -ENOMEM;
+	sync = (struct msm_sync *)(pmsm + 4);
+
+	rc = msm_sync_init(sync, dev, sensor_probe);
+	if (rc < 0) {
+		kfree(pmsm);
+		return rc;
+	}
+
+	CDBG("%s: setting camera node %d\n", __func__, camera_node);
+	rc = msm_device_init(pmsm, sync, camera_node);
+	if (rc < 0) {
+		msm_sync_destroy(sync);
+		kfree(pmsm);
+		return rc;
+	}
+
+	camera_type[camera_node] = sync->sctrl.s_camera_type;
+	sensor_mount_angle[camera_node] = sync->sctrl.s_mount_angle;
+	camera_node++;
+
+	list_add(&sync->list, &msm_sensors);
+	return rc;
+}
+EXPORT_SYMBOL(msm_camera_drv_start);
diff --git a/drivers/media/platform/msm/camera_v1/msm_camirq_router.c b/drivers/media/platform/msm/camera_v1/msm_camirq_router.c
new file mode 100644
index 0000000..37dd6c2
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/msm_camirq_router.c
@@ -0,0 +1,282 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/of.h>
+#include <mach/irqs.h>
+#include <media/msm_isp.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+#include "msm.h"
+#include "server/msm_cam_server.h"
+#include "msm_camirq_router.h"
+
+#ifdef CONFIG_MSM_CAMERA_DEBUG
+#define D(fmt, args...) pr_debug("msm: " fmt, ##args)
+#else
+#define D(fmt, args...) do {} while (0)
+#endif
+
+static void msm_irqrouter_update_irqmap_entry(
+	struct msm_cam_server_irqmap_entry *entry,
+	int is_composite, int irq_idx, int cam_hw_idx)
+{
+	int rc = 0;
+	entry->irq_idx = irq_idx;
+	entry->is_composite = is_composite;
+	entry->cam_hw_idx = cam_hw_idx;
+	rc = msm_cam_server_update_irqmap(entry);
+	if (rc < 0)
+		pr_err("%s Error updating irq %d information ",
+			__func__, irq_idx);
+}
+
+static void msm_irqrouter_send_default_irqmap(
+	struct irqrouter_ctrl_type *irqrouter_ctrl)
+{
+	struct msm_cam_server_irqmap_entry *irqmap =
+		&irqrouter_ctrl->def_hw_irqmap[0];
+
+	msm_irqrouter_update_irqmap_entry(&irqmap[CAMERA_SS_IRQ_0],
+		0, CAMERA_SS_IRQ_0, MSM_CAM_HW_MICRO);
+
+	msm_irqrouter_update_irqmap_entry(&irqmap[CAMERA_SS_IRQ_1],
+		0, CAMERA_SS_IRQ_1, MSM_CAM_HW_CCI);
+
+	msm_irqrouter_update_irqmap_entry(&irqmap[CAMERA_SS_IRQ_2],
+		0, CAMERA_SS_IRQ_2, MSM_CAM_HW_CSI0);
+
+	msm_irqrouter_update_irqmap_entry(&irqmap[CAMERA_SS_IRQ_3],
+		0, CAMERA_SS_IRQ_3, MSM_CAM_HW_CSI1);
+
+	msm_irqrouter_update_irqmap_entry(&irqmap[CAMERA_SS_IRQ_4],
+		0, CAMERA_SS_IRQ_4, MSM_CAM_HW_CSI2);
+
+	msm_irqrouter_update_irqmap_entry(&irqmap[CAMERA_SS_IRQ_5],
+		0, CAMERA_SS_IRQ_5, MSM_CAM_HW_CSI3);
+
+	msm_irqrouter_update_irqmap_entry(&irqmap[CAMERA_SS_IRQ_6],
+		0, CAMERA_SS_IRQ_6, MSM_CAM_HW_ISPIF);
+
+	msm_irqrouter_update_irqmap_entry(&irqmap[CAMERA_SS_IRQ_7],
+		0, CAMERA_SS_IRQ_7, MSM_CAM_HW_CPP);
+
+	msm_irqrouter_update_irqmap_entry(&irqmap[CAMERA_SS_IRQ_8],
+		0, CAMERA_SS_IRQ_8, MSM_CAM_HW_VFE0);
+
+	msm_irqrouter_update_irqmap_entry(&irqmap[CAMERA_SS_IRQ_9],
+		0, CAMERA_SS_IRQ_9, MSM_CAM_HW_VFE1);
+
+	msm_irqrouter_update_irqmap_entry(&irqmap[CAMERA_SS_IRQ_10],
+		0, CAMERA_SS_IRQ_10, MSM_CAM_HW_JPEG0);
+
+	msm_irqrouter_update_irqmap_entry(&irqmap[CAMERA_SS_IRQ_11],
+		0, CAMERA_SS_IRQ_11, MSM_CAM_HW_JPEG1);
+
+	msm_irqrouter_update_irqmap_entry(&irqmap[CAMERA_SS_IRQ_12],
+		0, CAMERA_SS_IRQ_12, MSM_CAM_HW_JPEG2);
+}
+
+static int msm_irqrouter_open(struct v4l2_subdev *sd,
+	struct v4l2_subdev_fh *fh)
+{
+	struct irqrouter_ctrl_type *irqrouter_ctrl = v4l2_get_subdevdata(sd);
+	/* Only one object of IRQ Router allowed. */
+	if (atomic_read(&irqrouter_ctrl->active) != 0) {
+		pr_err("%s IRQ router is already opened\n", __func__);
+		return -EINVAL;
+	}
+
+	D("%s E ", __func__);
+	atomic_inc(&irqrouter_ctrl->active);
+
+	return 0;
+}
+
+static int msm_irqrouter_close(struct v4l2_subdev *sd,
+	struct v4l2_subdev_fh *fh)
+{
+	struct irqrouter_ctrl_type *irqrouter_ctrl = v4l2_get_subdevdata(sd);
+	if (atomic_read(&irqrouter_ctrl->active) == 0) {
+		pr_err("%s IRQ router is already closed\n", __func__);
+		return -EINVAL;
+	}
+	D("%s E ", __func__);
+	atomic_dec(&irqrouter_ctrl->active);
+	return 0;
+}
+
+static const struct v4l2_subdev_internal_ops msm_irqrouter_internal_ops = {
+	.open = msm_irqrouter_open,
+	.close = msm_irqrouter_close,
+};
+
+long msm_irqrouter_subdev_ioctl(struct v4l2_subdev *sd,
+	unsigned int cmd, void *arg)
+{
+	struct irqrouter_ctrl_type *irqrouter_ctrl = v4l2_get_subdevdata(sd);
+	struct msm_camera_irq_cfg *irq_cfg;
+	struct intr_table_entry irq_req;
+	int rc = 0;
+
+	/* Handle all IRQ Router Subdev IOCTLs here.
+	 * Userspace sends the composite irq configuration.
+	 * IRQ Router subdev then configures the registers to group
+	 * together individual core hw irqs into a composite IRQ
+	 * to the MSM IRQ controller. It also registers them with
+	 * the irq manager in the camera server. */
+	switch (cmd) {
+	case MSM_IRQROUTER_CFG_COMPIRQ:
+		COPY_FROM_USER(rc, &irq_cfg, (void __user *)arg,
+			sizeof(struct msm_camera_irq_cfg));
+		if (rc) {
+			ERR_COPY_FROM_USER();
+			break;
+		}
+
+		if (!irq_cfg ||
+			(irq_cfg->irq_idx < CAMERA_SS_IRQ_0) ||
+			(irq_cfg->irq_idx >= CAMERA_SS_IRQ_MAX)) {
+			pr_err("%s Invalid input", __func__);
+			return -EINVAL;
+		} else {
+			irq_req.cam_hw_mask      = irq_cfg->cam_hw_mask;
+			irq_req.irq_idx          = irq_cfg->irq_idx;
+			irq_req.irq_num          =
+			irqrouter_ctrl->def_hw_irqmap[irq_cfg->irq_idx].irq_num;
+			irq_req.is_composite     = 1;
+			irq_req.irq_trigger_type = IRQF_TRIGGER_RISING;
+			irq_req.num_hwcore       = irq_cfg->num_hwcore;
+			irq_req.data             = NULL;
+			rc = msm_cam_server_request_irq(&irq_req);
+			if (rc < 0) {
+				pr_err("%s Error requesting comp irq %d ",
+					__func__, irq_req.irq_idx);
+				return rc;
+			}
+			irqrouter_ctrl->def_hw_irqmap
+				[irq_cfg->irq_idx].is_composite = 1;
+		}
+		break;
+	default:
+		pr_err("%s Invalid cmd %d ", __func__, cmd);
+		break;
+	}
+
+	return rc;
+}
+
+static const struct v4l2_subdev_core_ops msm_irqrouter_subdev_core_ops = {
+	.ioctl = msm_irqrouter_subdev_ioctl,
+};
+
+static const struct v4l2_subdev_ops msm_irqrouter_subdev_ops = {
+	.core = &msm_irqrouter_subdev_core_ops,
+};
+
+static int __devinit irqrouter_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+	struct irqrouter_ctrl_type *irqrouter_ctrl;
+	struct msm_cam_subdev_info sd_info;
+
+	D("%s: device id = %d\n", __func__, pdev->id);
+
+	irqrouter_ctrl = kzalloc(sizeof(struct irqrouter_ctrl_type),
+				GFP_KERNEL);
+	if (!irqrouter_ctrl) {
+		pr_err("%s: not enough memory\n", __func__);
+		return -ENOMEM;
+	}
+
+	v4l2_subdev_init(&irqrouter_ctrl->subdev, &msm_irqrouter_subdev_ops);
+	irqrouter_ctrl->subdev.internal_ops = &msm_irqrouter_internal_ops;
+	irqrouter_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	snprintf(irqrouter_ctrl->subdev.name,
+			 sizeof(irqrouter_ctrl->subdev.name), "msm_irqrouter");
+	v4l2_set_subdevdata(&irqrouter_ctrl->subdev, irqrouter_ctrl);
+	irqrouter_ctrl->pdev = pdev;
+
+	if (pdev->dev.of_node)
+		of_property_read_u32((&pdev->dev)->of_node,
+			"cell-index", &pdev->id);
+
+	msm_irqrouter_send_default_irqmap(irqrouter_ctrl);
+
+	media_entity_init(&irqrouter_ctrl->subdev.entity, 0, NULL, 0);
+	irqrouter_ctrl->subdev.entity.type = MEDIA_ENT_T_DEVNODE_V4L;
+	irqrouter_ctrl->subdev.entity.group_id = IRQ_ROUTER_DEV;
+	irqrouter_ctrl->subdev.entity.name = pdev->name;
+
+	sd_info.sdev_type = IRQ_ROUTER_DEV;
+	sd_info.sd_index = 0;
+	sd_info.irq_num = 0;
+	/* Now register this subdev with the camera server. */
+	rc = msm_cam_register_subdev_node(&irqrouter_ctrl->subdev, &sd_info);
+	if (rc < 0) {
+		pr_err("%s Error registering irqr subdev %d", __func__, rc);
+		goto error;
+	}
+	irqrouter_ctrl->subdev.entity.revision =
+		irqrouter_ctrl->subdev.devnode->num;
+	atomic_set(&irqrouter_ctrl->active, 0);
+
+	platform_set_drvdata(pdev, &irqrouter_ctrl->subdev);
+
+	return rc;
+error:
+	kfree(irqrouter_ctrl);
+	return rc;
+}
+
+static int __exit irqrouter_exit(struct platform_device *pdev)
+{
+	struct v4l2_subdev *subdev = dev_get_drvdata(&pdev->dev);
+	struct irqrouter_ctrl_type *irqrouter_ctrl =
+		v4l2_get_subdevdata(subdev);
+	kfree(irqrouter_ctrl);
+	return 0;
+}
+
+static const struct of_device_id msm_irqrouter_dt_match[] = {
+	{.compatible = "qcom,irqrouter"},
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, msm_irqrouter_dt_match);
+
+static struct platform_driver msm_irqrouter_driver = {
+	.probe = irqrouter_probe,
+	.remove = irqrouter_exit,
+	.driver = {
+		.name = MSM_IRQ_ROUTER_DRV_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = msm_irqrouter_dt_match,
+	},
+};
+
+static int __init msm_irqrouter_init_module(void)
+{
+	return platform_driver_register(&msm_irqrouter_driver);
+}
+
+static void __exit msm_irqrouter_exit_module(void)
+{
+	platform_driver_unregister(&msm_irqrouter_driver);
+}
+
+module_init(msm_irqrouter_init_module);
+module_exit(msm_irqrouter_exit_module);
+MODULE_DESCRIPTION("msm camera irq router");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/msm_camirq_router.h b/drivers/media/platform/msm/camera_v1/msm_camirq_router.h
new file mode 100644
index 0000000..3ea3cec
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/msm_camirq_router.h
@@ -0,0 +1,206 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MSM_CAM_IRQROUTER_H__
+#define __MSM_CAM_IRQROUTER_H__
+
+#include <linux/bitops.h>
+
+/* Camera SS common registers defines - Start */
+/* These registers are not directly related to
+ * IRQ Router, but are common to the Camera SS.
+ * IRQ Router registers dont have a unique base address
+ * in the memory mapped address space. It is offset from
+ * the Camera SS base address. So keep the common Camera
+ * SS registers also in the IRQ Router subdev for now. */
+
+/* READ ONLY: Camera Subsystem HW version */
+#define CAMSS_HW_VERSION			0x00000000
+
+/* Bits 4:0 of this register can be used to select a desired
+ * camera core test bus to drive the Camera_SS test bus output */
+#define CAMSS_TESTBUS_SEL			0x00000004
+
+/* Bits 4:0 of this register is used to allow either Microcontroller
+ * or the CCI drive the corresponding GPIO output.
+ * For eg: Setting bit 0 of this register allows Microcontroller to
+ * drive GPIO #0. Clearing the bit allows CCI to drive GPIO #0. */
+#define CAMSS_GPIO_MUX_SEL			0x00000008
+
+/* Bit 0 of this register is used to set the default AHB master
+ * for the AHB Arbiter. 0 - AHB Master 0, 1 - AHB Master 1*/
+#define CAMSS_AHB_ARB_CTL			0x0000000C
+
+/* READ ONLY */
+#define CAMSS_XPU2_STATUS			0x00000010
+
+/* Select the appropriate CSI clock for CSID Pixel pipes */
+#define CAMSS_CSI_PIX_CLK_MUX_SEL		0x00000020
+#define CAMSS_CSI_PIX_CLK_CGC_EN		0x00000024
+
+/* Select the appropriate CSI clock for CSID RDI pipes */
+#define CAMSS_CSI_RDI_CLK_MUX_SEL		0x00000028
+#define CAMSS_CSI_RDI_CLK_CGC_EN		0x0000002C
+
+/* Select the appropriate CSI clock for CSI Phy0 */
+#define CAMSS_CSI_PHY_0_CLK_MUX_SEL		0x00000030
+#define CAMSS_CSI_PHY_0_CLK_CGC_EN		0x00000034
+
+/* Select the appropriate CSI clock for CSI Phy1 */
+#define CAMSS_CSI_PHY_1_CLK_MUX_SEL		0x00000038
+#define CAMSS_CSI_PHY_1_CLK_CGC_EN		0x0000003C
+
+/* Select the appropriate CSI clock for CSI Phy2 */
+#define CAMSS_CSI_PHY_2_CLK_MUX_SEL		0x00000040
+#define CAMSS_CSI_PHY_2_CLK_CGC_EN		0x00000044
+/* Camera SS common registers defines - End */
+
+/* IRQ Router registers defines - Start */
+/* This register is used to reset the composite
+ * IRQ outputs of the Camera_SS IRQ Router */
+#define CAMSS_IRQ_COMPOSITE_RESET_CTRL		0x00000060
+
+/* By default, this 'allows' the interrupts from
+ * Micro to pass through, unless configured in
+ * composite mode. */
+#define CAMSS_IRQ_COMPOSITE_MASK_0		0x00000064
+
+/* By default, this 'allows' the interrupts from
+ * CCI to pass through, unless configured in
+ * composite mode. */
+#define CAMSS_IRQ_COMPOSITE_MASK_1		0x00000068
+
+/* By default, this 'allows' the interrupts from
+ * CSI_0 to pass through, unless configured in
+ * composite mode. */
+#define CAMSS_IRQ_COMPOSITE_MASK_2		0x0000006C
+
+/* By default, this 'allows' the interrupts from
+ * CSI_1 to pass through, unless configured in
+ * composite mode. */
+#define CAMSS_IRQ_COMPOSITE_MASK_3		0x00000070
+
+/* By default, this 'allows' the interrupts from
+ * CSI_2 to pass through, unless configured in
+ * composite mode. */
+#define CAMSS_IRQ_COMPOSITE_MASK_4		0x00000074
+
+/* By default, this 'allows' the interrupts from
+ * CSI_3 to pass through, unless configured in
+ * composite mode. */
+#define CAMSS_IRQ_COMPOSITE_MASK_5		0x00000078
+
+/* By default, this 'allows' the interrupts from
+ * ISPIF to pass through, unless configured in
+ * composite mode. */
+#define CAMSS_IRQ_COMPOSITE_MASK_6		0x0000007C
+
+/* By default, this 'allows' the interrupts from
+ * CPP to pass through, unless configured in
+ * composite mode. */
+#define CAMSS_IRQ_COMPOSITE_MASK_7		0x00000080
+
+/* By default, this 'allows' the interrupts from
+ * VFE_0 to pass through, unless configured in
+ * composite mode. */
+#define CAMSS_IRQ_COMPOSITE_MASK_8		0x00000084
+
+/* By default, this 'allows' the interrupts from
+ * VFE_1 to pass through, unless configured in
+ * composite mode. */
+#define CAMSS_IRQ_COMPOSITE_MASK_9		0x00000088
+
+/* By default, this 'allows' the interrupts from
+ * JPEG_0 to pass through, unless configured in
+ * composite mode. */
+#define CAMSS_IRQ_COMPOSITE_MASK_10		0x0000008C
+
+/* By default, this 'allows' the interrupts from
+ * JPEG_1 to pass through, unless configured in
+ * composite mode. */
+#define CAMSS_IRQ_COMPOSITE_MASK_11		0x00000090
+
+/* By default, this 'allows' the interrupts from
+ * JPEG_2 to pass through, unless configured in
+ * composite mode. */
+#define CAMSS_IRQ_COMPOSITE_MASK_12		0x00000094
+
+/* The following IRQ_COMPOSITE_MICRO_MASK registers
+ * allow the interrupts from the individual hw
+ * cores to be composited into an IRQ for Micro. */
+#define CAMSS_IRQ_COMPOSITE_MICRO_MASK_0	0x000000A4
+#define CAMSS_IRQ_COMPOSITE_MICRO_MASK_1	0x000000A8
+#define CAMSS_IRQ_COMPOSITE_MICRO_MASK_2	0x000000AC
+#define CAMSS_IRQ_COMPOSITE_MICRO_MASK_3	0x000000B0
+#define CAMSS_IRQ_COMPOSITE_MICRO_MASK_4	0x000000B4
+#define CAMSS_IRQ_COMPOSITE_MICRO_MASK_5	0x000000B8
+/* IRQ Router register defines - End */
+
+/* Writing this mask will reset all the composite
+ * IRQs of the Camera_SS IRQ Router */
+#define CAMSS_IRQ_COMPOSITE_RESET_MASK		0x003F1FFF
+
+/* Use this to enable Micro IRQ from IRQ Router
+ * composite interrupt */
+#define ENABLE_MICRO_IRQ_IN_COMPOSITE		BIT(0)
+/* Use this to enable CCI IRQ from IRQ Router
+ * composite interrupt */
+#define ENABLE_CCI_IRQ_IN_COMPOSITE		BIT(1)
+/* Use this to enable CSI0 IRQ from IRQ Router
+ * composite interrupt */
+#define ENABLE_CSI0_IRQ_IN_COMPOSITE		BIT(2)
+/* Use this to enable CSI1 IRQ from IRQ Router
+ * composite interrupt */
+#define ENABLE_CSI1_IRQ_IN_COMPOSITE		BIT(3)
+/* Use this to enable CSI2 IRQ from IRQ Router
+ * composite interrupt */
+#define ENABLE_CSI2_IRQ_IN_COMPOSITE		BIT(4)
+/* Use this to enable CSI3 IRQ from IRQ Router
+ * composite interrupt */
+#define ENABLE_CSI3_IRQ_IN_COMPOSITE		BIT(5)
+/* Use this to enable ISPIF IRQ from IRQ Router
+ * composite interrupt */
+#define ENABLE_ISPIF_IRQ_IN_COMPOSITE		BIT(6)
+/* Use this to enable CPP IRQ from IRQ Router
+ * composite interrupt */
+#define ENABLE_CPP_IRQ_IN_COMPOSITE		BIT(7)
+/* Use this to enable VFE0 IRQ from IRQ Router
+ * composite interrupt */
+#define ENABLE_VFE0_IRQ_IN_COMPOSITE		BIT(8)
+/* Use this to enable VFE1 IRQ from IRQ Router
+ * composite interrupt */
+#define ENABLE_VFE1_IRQ_IN_COMPOSITE		BIT(9)
+/* Use this to enable JPEG0 IRQ from IRQ Router
+ * composite interrupt */
+#define ENABLE_JPEG0_IRQ_IN_COMPOSITE		BIT(10)
+/* Use this to enable JPEG1 IRQ from IRQ Router
+ * composite interrupt */
+#define ENABLE_JPEG1_IRQ_IN_COMPOSITE		BIT(11)
+/* Use this to enable JPEG2 IRQ from IRQ Router
+ * composite interrupt */
+#define ENABLE_JPEG2_IRQ_IN_COMPOSITE		BIT(12)
+
+struct irqrouter_ctrl_type {
+	/* v4l2 subdev */
+	struct v4l2_subdev subdev;
+	struct platform_device *pdev;
+
+	void __iomem *irqr_dev_base;
+
+	struct resource	*irqr_dev_mem;
+	struct resource *irqr_dev_io;
+	atomic_t active;
+	struct msm_cam_server_irqmap_entry def_hw_irqmap[CAMERA_SS_IRQ_MAX];
+};
+
+#endif /* __MSM_CAM_IRQROUTER_H__ */
diff --git a/drivers/media/platform/msm/camera_v1/msm_gesture.c b/drivers/media/platform/msm/camera_v1/msm_gesture.c
new file mode 100644
index 0000000..3ab041e
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/msm_gesture.c
@@ -0,0 +1,501 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <media/v4l2-subdev.h>
+#include <media/msm_camera.h>
+#include <media/msm_gestures.h>
+#include <media/v4l2-ctrls.h>
+#include <mach/camera.h>
+#include "msm.h"
+
+#ifdef CONFIG_MSM_CAMERA_DEBUG
+#define D(fmt, args...) pr_debug("msm_gesture: " fmt, ##args)
+#else
+#define D(fmt, args...) do {} while (0)
+#endif
+
+struct msm_gesture_ctrl {
+	int queue_id;
+	atomic_t active;
+	struct v4l2_ctrl_handler ctrl_handler;
+	int num_ctrls;
+	struct v4l2_fh *p_eventHandle;
+	struct v4l2_subdev *sd;
+	struct msm_ges_evt event;
+	int camera_opened;
+};
+
+static struct msm_gesture_ctrl g_gesture_ctrl;
+
+int msm_gesture_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+	struct v4l2_event_subscription *sub)
+{
+	D("%s\n", __func__);
+	if (sub->type == V4L2_EVENT_ALL)
+		sub->type = MSM_GES_APP_NOTIFY_EVENT;
+	return v4l2_event_subscribe(fh, sub, 30);
+}
+
+static int msm_gesture_send_ctrl(struct msm_gesture_ctrl *p_gesture_ctrl,
+	int type, void *value, int length, uint32_t timeout)
+{
+	int rc = 0;
+	struct msm_ctrl_cmd ctrlcmd;
+	D("%s qid %d\n", __func__, p_gesture_ctrl->queue_id);
+	ctrlcmd.type = type;
+	ctrlcmd.timeout_ms = timeout;
+	ctrlcmd.length = length;
+	ctrlcmd.value = value;
+	ctrlcmd.vnode_id = 0;
+	ctrlcmd.queue_idx = p_gesture_ctrl->queue_id;
+	ctrlcmd.config_ident = 0;
+
+	rc = msm_server_send_ctrl(&ctrlcmd, MSM_GES_RESP_V4L2);
+	return rc;
+}
+
+static int msm_gesture_proc_ctrl_cmd(struct msm_gesture_ctrl *p_gesture_ctrl,
+	struct v4l2_control *ctrl)
+{
+	int rc = 0;
+	struct msm_ctrl_cmd *tmp_cmd = NULL;
+	uint8_t *ctrl_data = NULL;
+	void __user *uptr_cmd;
+	void __user *uptr_value;
+	uint32_t cmd_len = sizeof(struct msm_ctrl_cmd);
+	uint32_t value_len;
+
+	tmp_cmd = (struct msm_ctrl_cmd *)ctrl->value;
+	uptr_cmd = (void __user *)ctrl->value;
+	uptr_value = (void __user *)tmp_cmd->value;
+	value_len = tmp_cmd->length;
+
+	D("%s: cmd type = %d, up1=0x%x, ulen1=%d, up2=0x%x, ulen2=%d\n",
+		__func__, tmp_cmd->type, (uint32_t)uptr_cmd, cmd_len,
+		(uint32_t)uptr_value, tmp_cmd->length);
+
+	ctrl_data = kzalloc(value_len + cmd_len, GFP_KERNEL);
+	if (ctrl_data == 0) {
+		pr_err("%s could not allocate memory\n", __func__);
+		rc = -ENOMEM;
+		goto end;
+	}
+	tmp_cmd = (struct msm_ctrl_cmd *)ctrl_data;
+	if (copy_from_user((void *)ctrl_data, uptr_cmd,
+			cmd_len)) {
+		pr_err("%s: copy_from_user failed.\n", __func__);
+		rc = -EINVAL;
+		goto end;
+	}
+	tmp_cmd->value = (void *)(ctrl_data + cmd_len);
+	if (uptr_value && tmp_cmd->length > 0) {
+		if (copy_from_user((void *)tmp_cmd->value, uptr_value,
+			value_len)) {
+			pr_err("%s: copy_from_user failed, size=%d\n",
+				__func__, value_len);
+			rc = -EINVAL;
+			goto end;
+		}
+	} else
+		tmp_cmd->value = NULL;
+
+	/* send command to config thread in usersspace, and get return value */
+	rc = msm_server_send_ctrl((struct msm_ctrl_cmd *)ctrl_data,
+			MSM_GES_RESP_V4L2);
+	D("%s: msm_server_control rc=%d\n", __func__, rc);
+	if (rc == 0) {
+		if (uptr_value && tmp_cmd->length > 0 &&
+			copy_to_user((void __user *)uptr_value,
+				(void *)(ctrl_data + cmd_len),
+				tmp_cmd->length)) {
+			pr_err("%s: copy_to_user failed, size=%d\n",
+				__func__, tmp_cmd->length);
+			rc = -EINVAL;
+			goto end;
+		}
+		tmp_cmd->value = uptr_value;
+		if (copy_to_user((void __user *)uptr_cmd,
+			(void *)tmp_cmd, cmd_len)) {
+			pr_err("%s: copy_to_user failed in cpy, size=%d\n",
+				__func__, cmd_len);
+			rc = -EINVAL;
+			goto end;
+		}
+	}
+end:
+	D("%s: END, type = %d, vaddr = 0x%x, vlen = %d, status = %d, rc = %d\n",
+		__func__, tmp_cmd->type, (uint32_t)tmp_cmd->value,
+		tmp_cmd->length, tmp_cmd->status, rc);
+	kfree(ctrl_data);
+	return rc;
+}
+
+static int msm_gesture_s_ctrl(struct v4l2_subdev *sd,
+	struct v4l2_control *ctrl)
+{
+	int rc = 0;
+	struct msm_gesture_ctrl *p_gesture_ctrl = &g_gesture_ctrl;
+	D("%s ctrl->id %d\n", __func__, ctrl->id);
+	rc = msm_gesture_proc_ctrl_cmd(p_gesture_ctrl, ctrl);
+	if (rc != 0) {
+		pr_err("%s set ctrl failed %d\n", __func__, rc);
+		return -EINVAL;
+	}
+	return rc;
+}
+
+static int msm_gesture_s_ctrl_ops(struct v4l2_ctrl *ctrl)
+{
+	int rc = 0;
+	struct v4l2_control control;
+	struct msm_gesture_ctrl *p_gesture_ctrl = &g_gesture_ctrl;
+	control.id = ctrl->id;
+	control.value = ctrl->val;
+	D("%s ctrl->id 0x%x\n", __func__, ctrl->id);
+	rc = msm_gesture_proc_ctrl_cmd(p_gesture_ctrl, &control);
+	if (rc != 0) {
+		pr_err("%s proc ctrl failed %d\n", __func__, rc);
+		return -EINVAL;
+	}
+	return rc;
+}
+
+static int msm_gesture_s_ctrl_ext(struct v4l2_subdev *sd,
+	struct v4l2_ext_controls *ctrls)
+{
+	int rc = 0;
+	struct v4l2_control control;
+	struct msm_gesture_ctrl *p_gesture_ctrl = &g_gesture_ctrl;
+	if ((ctrls->count < 1) || (NULL == ctrls->controls)) {
+		pr_err("%s invalid ctrl failed\n", __func__);
+		return -EINVAL;
+	}
+	control.id = ctrls->controls->id;
+	control.value = ctrls->controls->value;
+	D("%s ctrl->id %d\n", __func__, control.id);
+	rc = msm_gesture_proc_ctrl_cmd(p_gesture_ctrl, &control);
+	if (rc != 0) {
+		pr_err("%s proc ctrl failed %d\n", __func__, rc);
+		return -EINVAL;
+	}
+	return rc;
+}
+
+static int msm_gesture_handle_event(struct v4l2_subdev *sd,
+	struct msm_gesture_ctrl *p_gesture_ctrl, void* arg)
+{
+	int rc = 0;
+	struct v4l2_event *evt = (struct v4l2_event *)arg;
+	struct msm_ges_evt *p_ges_evt = NULL;
+	D("%s: Received gesture evt 0x%x ", __func__, evt->type);
+	p_gesture_ctrl->event.evt_len = 0;
+	p_gesture_ctrl->event.evt_data = NULL;
+
+	p_ges_evt = (struct msm_ges_evt *)evt->u.data;
+	D("%s: event data %p len %d", __func__,
+		p_ges_evt->evt_data,
+		p_ges_evt->evt_len);
+
+	if (p_ges_evt->evt_len > 0) {
+		p_gesture_ctrl->event.evt_data =
+			kzalloc(p_ges_evt->evt_len, GFP_KERNEL);
+
+		if (NULL == p_gesture_ctrl->event.evt_data) {
+			pr_err("%s: cannot allocate event", __func__);
+			rc = -ENOMEM;
+		} else {
+			if (copy_from_user(
+				(void *)p_gesture_ctrl->event.evt_data,
+				(void __user *)p_ges_evt->evt_data,
+				p_ges_evt->evt_len)) {
+				pr_err("%s: copy_from_user failed",
+					__func__);
+				rc = -EFAULT;
+			} else {
+				D("%s: copied the event", __func__);
+				p_gesture_ctrl->event.evt_len =
+					p_ges_evt->evt_len;
+			}
+		}
+	}
+
+	if (rc == 0) {
+		ktime_get_ts(&evt->timestamp);
+		v4l2_event_queue(sd->devnode, evt);
+	}
+	D("%s: exit rc %d ", __func__, rc);
+	return rc;
+}
+
+static int msm_gesture_get_evt_payload(struct v4l2_subdev *sd,
+	struct msm_gesture_ctrl *p_gesture_ctrl, void* arg)
+{
+	int rc = 0;
+	struct msm_ges_evt *p_ges_evt = (struct msm_ges_evt *)arg;
+	D("%s: enter ", __func__);
+	if (NULL != p_gesture_ctrl->event.evt_data) {
+		D("%s: event data %p len %d", __func__,
+			p_gesture_ctrl->event.evt_data,
+			p_gesture_ctrl->event.evt_len);
+
+		if (copy_to_user((void __user *)p_ges_evt->evt_data,
+			p_gesture_ctrl->event.evt_data,
+			p_gesture_ctrl->event.evt_len)) {
+			pr_err("%s: copy_to_user failed.\n", __func__);
+			rc = -EFAULT;
+		} else {
+			D("%s: copied the event", __func__);
+			p_ges_evt->evt_len = p_gesture_ctrl->event.evt_len;
+		}
+	}
+	D("%s: exit rc %d ", __func__, rc);
+	return rc;
+}
+
+static int msm_gesture_handle_cam_event(struct v4l2_subdev *sd,
+	struct msm_gesture_ctrl *p_gesture_ctrl, int cam_evt)
+{
+	int rc = 0;
+	D("%s: cam_evt %d ", __func__, cam_evt);
+
+	if ((cam_evt != MSM_V4L2_GES_CAM_OPEN)
+		&& (cam_evt != MSM_V4L2_GES_CAM_CLOSE)) {
+		pr_err("%s: error invalid event %d ", __func__, cam_evt);
+		return -EINVAL;
+	}
+
+	p_gesture_ctrl->camera_opened =
+		(cam_evt == MSM_V4L2_GES_CAM_OPEN);
+
+	if (atomic_read(&p_gesture_ctrl->active) == 0) {
+		D("%s gesture not active\n", __func__);
+		return 0;
+	}
+
+	rc = msm_gesture_send_ctrl(p_gesture_ctrl, cam_evt, NULL,
+		0, 2000);
+	if (rc != 0) {
+		pr_err("%s gesture ctrl failed %d\n", __func__, rc);
+		rc = -EINVAL;
+	}
+	D("%s exit rc %d\n", __func__, rc);
+	return rc;
+}
+
+long msm_gesture_ioctl(struct v4l2_subdev *sd,
+	 unsigned int cmd, void *arg)
+{
+	int rc = 0;
+	struct msm_gesture_ctrl *p_gesture_ctrl = &g_gesture_ctrl;
+	D("%s\n", __func__);
+	switch (cmd) {
+	case MSM_GES_IOCTL_CTRL_COMMAND: {
+		struct v4l2_control *ctrl = (struct v4l2_control *)arg;
+		D("%s MSM_GES_IOCTL_CTRL_COMMAND arg %p size %d\n", __func__,
+			arg, sizeof(ctrl));
+		rc = msm_gesture_s_ctrl(sd, ctrl);
+		break;
+	}
+	case VIDIOC_MSM_GESTURE_EVT: {
+		rc = msm_gesture_handle_event(sd, p_gesture_ctrl, arg);
+		break;
+	}
+	case VIDIOC_MSM_GESTURE_CAM_EVT: {
+		int cam_evt = *((int *)arg);
+		rc = msm_gesture_handle_cam_event(sd, p_gesture_ctrl, cam_evt);
+		break;
+	}
+	case MSM_GES_GET_EVT_PAYLOAD: {
+		rc = msm_gesture_get_evt_payload(sd, p_gesture_ctrl, arg);
+		break;
+	}
+	default:
+		pr_err("%s: Invalid ioctl %d", __func__, cmd);
+		break;
+	}
+	D("%s exit rc %d\n", __func__, rc);
+	return rc;
+}
+
+static const struct v4l2_ctrl_ops msm_gesture_ctrl_ops = {
+	.s_ctrl = msm_gesture_s_ctrl_ops,
+};
+
+static const struct v4l2_ctrl_config msm_gesture_ctrl_filter = {
+	.ops = &msm_gesture_ctrl_ops,
+	.id = MSM_GESTURE_CID_CTRL_CMD,
+	.name = "Gesture ctrl",
+	.type = V4L2_CTRL_TYPE_INTEGER,
+	.flags = V4L2_CTRL_FLAG_SLIDER,
+	.max = 0x7fffffff,
+	.step = 1,
+	.min = 0x80000000,
+};
+
+static int msm_gesture_init_ctrl(struct v4l2_subdev *sd,
+	struct msm_gesture_ctrl *p_gesture_ctrl)
+{
+	int rc = 0;
+	p_gesture_ctrl->num_ctrls = 1;
+	p_gesture_ctrl->ctrl_handler.error = 0;
+	v4l2_ctrl_handler_init(&p_gesture_ctrl->ctrl_handler,
+		p_gesture_ctrl->num_ctrls);
+	v4l2_ctrl_new_custom(&p_gesture_ctrl->ctrl_handler,
+		&msm_gesture_ctrl_filter, p_gesture_ctrl);
+	if (p_gesture_ctrl->ctrl_handler.error) {
+		int err = p_gesture_ctrl->ctrl_handler.error;
+		D("%s: error adding control %d", __func__, err);
+		p_gesture_ctrl->ctrl_handler.error = 0;
+	}
+	sd->ctrl_handler = &p_gesture_ctrl->ctrl_handler;
+	return rc;
+}
+
+static int msm_gesture_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	int rc = 0, rc_err = 0;
+	struct msm_gesture_ctrl *p_gesture_ctrl = &g_gesture_ctrl;
+	D("%s\n", __func__);
+	if (atomic_read(&p_gesture_ctrl->active) != 0) {
+		pr_err("%s already opened\n", __func__);
+		return -EINVAL;
+	}
+	memset(&p_gesture_ctrl->event, 0x0, sizeof(struct msm_ges_evt));
+	rc = msm_server_open_client(&p_gesture_ctrl->queue_id);
+	if (rc != 0) {
+		pr_err("%s open failed %d\n", __func__, rc);
+		rc = -EINVAL;
+		goto err;
+	}
+
+	rc = msm_gesture_init_ctrl(sd, p_gesture_ctrl);
+	if (rc != 0) {
+		pr_err("%s init ctrl failed %d\n", __func__, rc);
+		rc = -EINVAL;
+		goto err;
+	}
+
+	rc = msm_gesture_send_ctrl(p_gesture_ctrl, MSM_V4L2_GES_OPEN, NULL,
+		0, 10000);
+	if (rc != 0) {
+		pr_err("%s gesture ctrl failed %d\n", __func__, rc);
+		rc = -EINVAL;
+		goto err;
+	}
+
+	atomic_inc(&p_gesture_ctrl->active);
+
+	return rc;
+
+err:
+	rc_err = msm_server_close_client(p_gesture_ctrl->queue_id);
+	if (rc_err != 0)
+		pr_err("%s failed %d\n", __func__, rc);
+	return rc;
+}
+
+static int msm_gesture_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	int rc = 0;
+	struct msm_gesture_ctrl *p_gesture_ctrl = &g_gesture_ctrl;
+	D("%s\n", __func__);
+	if (atomic_read(&p_gesture_ctrl->active) == 0) {
+		pr_err("%s already closed\n", __func__);
+		return -EINVAL;
+	}
+
+	rc = msm_gesture_send_ctrl(p_gesture_ctrl, MSM_V4L2_GES_CLOSE, NULL,
+		0, 10000);
+	if (rc != 0)
+		pr_err("%s gesture ctrl failed %d\n", __func__, rc);
+
+	rc = msm_server_close_client(p_gesture_ctrl->queue_id);
+	if (rc != 0)
+		pr_err("%s failed %d\n", __func__, rc);
+
+	v4l2_ctrl_handler_free(&p_gesture_ctrl->ctrl_handler);
+	kfree(p_gesture_ctrl->event.evt_data);
+
+	atomic_dec(&p_gesture_ctrl->active);
+	g_gesture_ctrl.queue_id = -1;
+	return 0;
+}
+
+static struct v4l2_subdev_core_ops msm_gesture_core_ops = {
+	.s_ctrl = msm_gesture_s_ctrl,
+	.s_ext_ctrls = msm_gesture_s_ctrl_ext,
+	.ioctl = msm_gesture_ioctl,
+	.subscribe_event = msm_gesture_subscribe_event,
+};
+
+static struct v4l2_subdev_video_ops msm_gesture_video_ops;
+
+static struct v4l2_subdev_ops msm_gesture_subdev_ops = {
+	.core = &msm_gesture_core_ops,
+	.video  = &msm_gesture_video_ops,
+};
+
+static const struct v4l2_subdev_internal_ops msm_gesture_internal_ops = {
+	.open = msm_gesture_open,
+	.close = msm_gesture_close,
+};
+
+static int msm_gesture_node_register(void)
+{
+	struct msm_gesture_ctrl *p_gesture_ctrl = &g_gesture_ctrl;
+	struct v4l2_subdev *gesture_subdev =
+		kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+	struct msm_cam_subdev_info sd_info;
+
+	D("%s\n", __func__);
+	if (!gesture_subdev) {
+		pr_err("%s: no enough memory\n", __func__);
+		return -ENOMEM;
+	};
+
+	v4l2_subdev_init(gesture_subdev, &msm_gesture_subdev_ops);
+	gesture_subdev->internal_ops = &msm_gesture_internal_ops;
+	gesture_subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	snprintf(gesture_subdev->name,
+			 sizeof(gesture_subdev->name), "gesture");
+
+	media_entity_init(&gesture_subdev->entity, 0, NULL, 0);
+	gesture_subdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
+	gesture_subdev->entity.group_id = GESTURE_DEV;
+	gesture_subdev->entity.name = gesture_subdev->name;
+
+	/* events */
+	gesture_subdev->flags |= V4L2_SUBDEV_FL_HAS_EVENTS;
+
+	sd_info.sdev_type = GESTURE_DEV;
+	sd_info.sd_index = 0;
+	sd_info.irq_num = 0;
+	msm_cam_register_subdev_node(gesture_subdev, &sd_info);
+
+	gesture_subdev->entity.revision = gesture_subdev->devnode->num;
+
+	atomic_set(&p_gesture_ctrl->active, 0);
+	p_gesture_ctrl->queue_id = -1;
+	p_gesture_ctrl->event.evt_data = NULL;
+	p_gesture_ctrl->event.evt_len = 0;
+	return 0;
+}
+
+static int __init msm_gesture_init_module(void)
+{
+	return msm_gesture_node_register();
+}
+
+module_init(msm_gesture_init_module);
+MODULE_DESCRIPTION("MSM Gesture driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/msm_isp.c b/drivers/media/platform/msm/camera_v1/msm_isp.c
new file mode 100644
index 0000000..f646f09
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/msm_isp.c
@@ -0,0 +1,767 @@
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/export.h>
+#include <linux/workqueue.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/ioctl.h>
+#include <linux/spinlock.h>
+#include <linux/videodev2.h>
+#include <linux/proc_fs.h>
+#include <linux/vmalloc.h>
+#include <linux/android_pmem.h>
+
+#include <media/v4l2-dev.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
+#include <media/msm_isp.h>
+#include <media/msm_gemini.h>
+
+#include "msm.h"
+
+#ifdef CONFIG_MSM_CAMERA_DEBUG
+#define D(fmt, args...) pr_debug("msm_isp: " fmt, ##args)
+#else
+#define D(fmt, args...) do {} while (0)
+#endif
+
+#define MSM_FRAME_AXI_MAX_BUF 32
+
+/*
+ * This function executes in interrupt context.
+ */
+
+void *msm_isp_sync_alloc(int size,
+	  gfp_t gfp)
+{
+	struct msm_queue_cmd *qcmd =
+		kmalloc(sizeof(struct msm_queue_cmd) + size, gfp);
+
+	if (qcmd) {
+		atomic_set(&qcmd->on_heap, 1);
+		return qcmd + 1;
+	}
+	return NULL;
+}
+
+void msm_isp_sync_free(void *ptr)
+{
+	if (ptr) {
+		struct msm_queue_cmd *qcmd =
+			(struct msm_queue_cmd *)ptr;
+		qcmd--;
+		if (atomic_read(&qcmd->on_heap))
+			kfree(qcmd);
+	}
+}
+
+static int msm_isp_notify_VFE_SOF_COUNT_EVT(struct v4l2_subdev *sd, void *arg)
+{
+	struct msm_vfe_cfg_cmd cfgcmd;
+	struct msm_camvfe_params vfe_params;
+	int rc;
+
+	cfgcmd.cmd_type = CMD_VFE_PIX_SOF_COUNT_UPDATE;
+	cfgcmd.value = NULL;
+	vfe_params.vfe_cfg = &cfgcmd;
+	vfe_params.data = arg;
+	rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
+	return 0;
+}
+
+int msm_isp_vfe_msg_to_img_mode(struct msm_cam_media_controller *pmctl,
+				int vfe_msg)
+{
+	int image_mode;
+	uint32_t vfe_output_mode = pmctl->vfe_output_mode;
+	vfe_output_mode &= ~(VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1);
+	if (vfe_msg == VFE_MSG_OUTPUT_PRIMARY) {
+		switch (vfe_output_mode) {
+		case VFE_OUTPUTS_MAIN_AND_PREVIEW:
+		case VFE_OUTPUTS_MAIN_AND_VIDEO:
+		case VFE_OUTPUTS_MAIN_AND_THUMB:
+		case VFE_OUTPUTS_RAW:
+		case VFE_OUTPUTS_JPEG_AND_THUMB:
+			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_MAIN;
+			break;
+		case VFE_OUTPUTS_THUMB_AND_MAIN:
+			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL;
+			break;
+		case VFE_OUTPUTS_VIDEO:
+		case VFE_OUTPUTS_VIDEO_AND_PREVIEW:
+			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_VIDEO;
+			break;
+		case VFE_OUTPUTS_PREVIEW:
+		case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
+			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW;
+			break;
+		default:
+			image_mode = -1;
+			break;
+		}
+	} else if (vfe_msg == VFE_MSG_OUTPUT_SECONDARY) {
+		switch (vfe_output_mode) {
+		case VFE_OUTPUTS_MAIN_AND_PREVIEW:
+		case VFE_OUTPUTS_VIDEO_AND_PREVIEW:
+			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW;
+			break;
+		case VFE_OUTPUTS_MAIN_AND_VIDEO:
+		case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
+			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_VIDEO;
+			break;
+		case VFE_OUTPUTS_MAIN_AND_THUMB:
+			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL;
+			break;
+		case VFE_OUTPUTS_THUMB_AND_MAIN:
+			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_MAIN;
+			break;
+		case VFE_OUTPUTS_JPEG_AND_THUMB:
+			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL;
+			break;
+		case VFE_OUTPUTS_PREVIEW:
+		case VFE_OUTPUTS_VIDEO:
+			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW;
+			break;
+		default:
+			image_mode = -1;
+			break;
+		}
+	} else if (vfe_msg == VFE_MSG_OUTPUT_TERTIARY1) {
+		if (pmctl->vfe_output_mode & VFE_OUTPUTS_RDI0)
+			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_RDI;
+		else
+			image_mode = -1;
+	} else if (vfe_msg == VFE_MSG_OUTPUT_TERTIARY2) {
+		if (pmctl->vfe_output_mode & VFE_OUTPUTS_RDI1)
+			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_RDI1;
+		else
+			image_mode = -1;
+	} else if (VFE_MSG_V2X_LIVESHOT_PRIMARY == vfe_msg) {
+			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_V2X_LIVESHOT;
+	} else
+		image_mode = -1;
+
+	D("%s Selected image mode %d vfe output mode %d, vfe msg %d\n",
+	  __func__, image_mode, pmctl->vfe_output_mode, vfe_msg);
+	return image_mode;
+}
+
+static int msm_isp_notify_VFE_BUF_EVT(struct msm_cam_media_controller *pmctl,
+					struct v4l2_subdev *sd, void *arg)
+{
+	int rc = -EINVAL;
+	struct msm_vfe_resp *vdata = (struct msm_vfe_resp *)arg;
+	struct msm_free_buf free_buf, temp_free_buf;
+	struct msm_camvfe_params vfe_params;
+	struct msm_vfe_cfg_cmd cfgcmd;
+	struct msm_cam_v4l2_device *pcam = pmctl->pcam_ptr;
+	struct msm_frame_info *frame_info =
+		(struct msm_frame_info *)vdata->evt_msg.data;
+	uint32_t vfe_id;
+	struct msm_cam_buf_handle buf_handle;
+
+	if (!pcam) {
+		pr_err("%s pcam is null. return\n", __func__);
+		msm_isp_sync_free(vdata);
+		return rc;
+	}
+	if (frame_info) {
+		vfe_id = frame_info->path;
+		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_INST_HANDLE;
+		buf_handle.inst_handle = frame_info->inst_handle;
+	} else {
+		vfe_id = vdata->evt_msg.msg_id;
+		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_IMG_MODE;
+		buf_handle.image_mode =
+			msm_isp_vfe_msg_to_img_mode(pmctl, vfe_id);
+	}
+
+	switch (vdata->type) {
+	case VFE_MSG_START:
+	case VFE_MSG_START_RECORDING:
+	case VFE_MSG_PREVIEW:
+		D("%s Got V32_START_*: Getting ping addr id = %d",
+						__func__, vfe_id);
+		msm_mctl_reserve_free_buf(pmctl, NULL,
+					&buf_handle, &free_buf);
+		cfgcmd.cmd_type = CMD_CONFIG_PING_ADDR;
+		cfgcmd.value = &vfe_id;
+		vfe_params.vfe_cfg = &cfgcmd;
+		vfe_params.data = (void *)&free_buf;
+		rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
+		msm_mctl_reserve_free_buf(pmctl, NULL,
+					&buf_handle, &free_buf);
+		cfgcmd.cmd_type = CMD_CONFIG_PONG_ADDR;
+		cfgcmd.value = &vfe_id;
+		vfe_params.vfe_cfg = &cfgcmd;
+		vfe_params.data = (void *)&free_buf;
+		rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
+		break;
+	case VFE_MSG_CAPTURE:
+		pr_debug("%s Got V32_CAPTURE: getting buffer for id = %d",
+						__func__, vfe_id);
+		msm_mctl_reserve_free_buf(pmctl, NULL,
+					&buf_handle, &free_buf);
+		cfgcmd.cmd_type = CMD_CONFIG_PING_ADDR;
+		cfgcmd.value = &vfe_id;
+		vfe_params.vfe_cfg = &cfgcmd;
+		vfe_params.data = (void *)&free_buf;
+		rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
+		temp_free_buf = free_buf;
+		if (msm_mctl_reserve_free_buf(pmctl, NULL,
+					&buf_handle, &free_buf)) {
+			/* Write the same buffer into PONG */
+			free_buf = temp_free_buf;
+		}
+		cfgcmd.cmd_type = CMD_CONFIG_PONG_ADDR;
+		cfgcmd.value = &vfe_id;
+		vfe_params.vfe_cfg = &cfgcmd;
+		vfe_params.data = (void *)&free_buf;
+		rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
+		break;
+	case VFE_MSG_JPEG_CAPTURE:
+		D("%s:VFE_MSG_JPEG_CAPTURE vdata->type %d\n", __func__,
+			vdata->type);
+		free_buf.num_planes = 2;
+		free_buf.ch_paddr[0] = pmctl->ping_imem_y;
+		free_buf.ch_paddr[1] = pmctl->ping_imem_cbcr;
+		cfgcmd.cmd_type = CMD_CONFIG_PING_ADDR;
+		cfgcmd.value = &vfe_id;
+		vfe_params.vfe_cfg = &cfgcmd;
+		vfe_params.data = (void *)&free_buf;
+		D("%s:VFE_MSG_JPEG_CAPTURE y_ping=%x cbcr_ping=%x\n",
+			__func__, free_buf.ch_paddr[0], free_buf.ch_paddr[1]);
+		rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
+		/* Write the same buffer into PONG */
+		free_buf.ch_paddr[0] = pmctl->pong_imem_y;
+		free_buf.ch_paddr[1] = pmctl->pong_imem_cbcr;
+		cfgcmd.cmd_type = CMD_CONFIG_PONG_ADDR;
+		cfgcmd.value = &vfe_id;
+		vfe_params.vfe_cfg = &cfgcmd;
+		vfe_params.data = (void *)&free_buf;
+		D("%s:VFE_MSG_JPEG_CAPTURE y_pong=%x cbcr_pong=%x\n",
+			__func__, free_buf.ch_paddr[0], free_buf.ch_paddr[1]);
+		rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
+		break;
+	case VFE_MSG_OUTPUT_IRQ:
+		D("%s Got OUTPUT_IRQ: Getting free buf id = %d",
+						__func__, vfe_id);
+		msm_mctl_reserve_free_buf(pmctl, NULL,
+					&buf_handle, &free_buf);
+		cfgcmd.cmd_type = CMD_CONFIG_FREE_BUF_ADDR;
+		cfgcmd.value = &vfe_id;
+		vfe_params.vfe_cfg = &cfgcmd;
+		vfe_params.data = (void *)&free_buf;
+		rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
+		break;
+	default:
+		pr_err("%s: Invalid vdata type: %d\n", __func__, vdata->type);
+		break;
+	}
+	return rc;
+}
+
+/*
+ * This function executes in interrupt context.
+ */
+static int msm_isp_notify_vfe(struct msm_cam_media_controller *pmctl,
+	struct v4l2_subdev *sd,	unsigned int notification,  void *arg)
+{
+	int rc = 0;
+	struct v4l2_event v4l2_evt;
+	struct msm_isp_event_ctrl *isp_event;
+	struct msm_free_buf buf;
+
+	if (!pmctl) {
+		pr_err("%s: no context in dsp callback.\n", __func__);
+		rc = -EINVAL;
+		return rc;
+	}
+
+	if (notification == NOTIFY_VFE_BUF_EVT)
+		return msm_isp_notify_VFE_BUF_EVT(pmctl, sd, arg);
+
+	if (notification == NOTIFY_VFE_PIX_SOF_COUNT)
+		return msm_isp_notify_VFE_SOF_COUNT_EVT(sd, arg);
+
+	isp_event = kzalloc(sizeof(struct msm_isp_event_ctrl), GFP_ATOMIC);
+	if (!isp_event) {
+		pr_err("%s Insufficient memory. return", __func__);
+		return -ENOMEM;
+	}
+
+	v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
+					MSM_CAM_RESP_STAT_EVT_MSG;
+	v4l2_evt.id = 0;
+
+	*((uint32_t *)v4l2_evt.u.data) = (uint32_t)isp_event;
+
+	isp_event->resptype = MSM_CAM_RESP_STAT_EVT_MSG;
+	isp_event->isp_data.isp_msg.type = MSM_CAMERA_MSG;
+	isp_event->isp_data.isp_msg.len = 0;
+
+	switch (notification) {
+	case NOTIFY_ISP_MSG_EVT: {
+		struct isp_msg_event *isp_msg = (struct isp_msg_event *)arg;
+
+		isp_event->isp_data.isp_msg.msg_id = isp_msg->msg_id;
+		isp_event->isp_data.isp_msg.frame_id = isp_msg->sof_count;
+		getnstimeofday(&(isp_event->isp_data.isp_msg.timestamp));
+		break;
+	}
+	case NOTIFY_VFE_MSG_OUT: {
+		uint8_t msgid;
+		struct msm_cam_buf_handle buf_handle;
+		struct isp_msg_output *isp_output =
+				(struct isp_msg_output *)arg;
+		if (!isp_output->buf.inst_handle) {
+			switch (isp_output->output_id) {
+			case MSG_ID_OUTPUT_P:
+				msgid = VFE_MSG_OUTPUT_P;
+				break;
+			case MSG_ID_OUTPUT_V:
+				msgid = VFE_MSG_OUTPUT_V;
+				break;
+			case MSG_ID_OUTPUT_T:
+				msgid = VFE_MSG_OUTPUT_T;
+				break;
+			case MSG_ID_OUTPUT_S:
+				msgid = VFE_MSG_OUTPUT_S;
+				break;
+			case MSG_ID_OUTPUT_PRIMARY:
+				msgid = VFE_MSG_OUTPUT_PRIMARY;
+				break;
+			case MSG_ID_OUTPUT_SECONDARY:
+				msgid = VFE_MSG_OUTPUT_SECONDARY;
+				break;
+			case MSG_ID_OUTPUT_TERTIARY1:
+				msgid = VFE_MSG_OUTPUT_TERTIARY1;
+				break;
+			case MSG_ID_OUTPUT_TERTIARY2:
+				msgid = VFE_MSG_OUTPUT_TERTIARY2;
+				break;
+
+			default:
+				pr_err("%s: Invalid VFE output id: %d\n",
+					   __func__, isp_output->output_id);
+				rc = -EINVAL;
+				break;
+			}
+			if (!rc) {
+				buf_handle.buf_lookup_type =
+					BUF_LOOKUP_BY_IMG_MODE;
+				buf_handle.image_mode =
+				msm_isp_vfe_msg_to_img_mode(pmctl, msgid);
+			}
+		} else {
+			buf_handle.buf_lookup_type = BUF_LOOKUP_BY_INST_HANDLE;
+			buf_handle.inst_handle = isp_output->buf.inst_handle;
+		}
+		isp_event->isp_data.isp_msg.msg_id =
+			isp_output->output_id;
+		isp_event->isp_data.isp_msg.frame_id =
+			isp_output->frameCounter;
+		buf = isp_output->buf;
+		msm_mctl_buf_done(pmctl, &buf_handle,
+			&buf, isp_output->frameCounter);
+		}
+		break;
+	case NOTIFY_VFE_MSG_COMP_STATS: {
+		struct msm_stats_buf *stats = (struct msm_stats_buf *)arg;
+		struct msm_stats_buf *stats_buf = NULL;
+
+		isp_event->isp_data.isp_msg.msg_id = MSG_ID_STATS_COMPOSITE;
+		stats->aec.buff = msm_pmem_stats_ptov_lookup(pmctl,
+					stats->aec.buff, &(stats->aec.fd));
+		stats->awb.buff = msm_pmem_stats_ptov_lookup(pmctl,
+					stats->awb.buff, &(stats->awb.fd));
+		stats->af.buff = msm_pmem_stats_ptov_lookup(pmctl,
+					stats->af.buff, &(stats->af.fd));
+		stats->ihist.buff = msm_pmem_stats_ptov_lookup(pmctl,
+					stats->ihist.buff, &(stats->ihist.fd));
+		stats->rs.buff = msm_pmem_stats_ptov_lookup(pmctl,
+					stats->rs.buff, &(stats->rs.fd));
+		stats->cs.buff = msm_pmem_stats_ptov_lookup(pmctl,
+					stats->cs.buff, &(stats->cs.fd));
+
+		stats_buf = kmalloc(sizeof(struct msm_stats_buf), GFP_ATOMIC);
+		if (!stats_buf) {
+			pr_err("%s: out of memory.\n", __func__);
+			rc = -ENOMEM;
+		} else {
+			*stats_buf = *stats;
+			isp_event->isp_data.isp_msg.len	=
+				sizeof(struct msm_stats_buf);
+			isp_event->isp_data.isp_msg.data = stats_buf;
+		}
+		}
+		break;
+	case NOTIFY_VFE_MSG_STATS: {
+		struct msm_stats_buf stats;
+		struct isp_msg_stats *isp_stats = (struct isp_msg_stats *)arg;
+
+		memset(&stats, 0, sizeof(stats));
+		isp_event->isp_data.isp_msg.msg_id = isp_stats->id;
+		isp_event->isp_data.isp_msg.frame_id =
+			isp_stats->frameCounter;
+		stats.buffer = isp_stats->buffer;
+		stats.fd = isp_stats->fd;
+		/* buf_idx used for O(0) lookup */
+		stats.buf_idx = isp_stats->buf_idx;
+		switch (isp_stats->id) {
+		case MSG_ID_STATS_AEC:
+		case MSG_ID_STATS_BG:
+			stats.aec.buff = stats.buffer;
+			stats.aec.fd = stats.fd;
+			break;
+		case MSG_ID_STATS_BE:
+			stats.be.buff = stats.buffer;
+			stats.be.fd = stats.fd;
+			break;
+		case MSG_ID_STATS_AF:
+		case MSG_ID_STATS_BF:
+			stats.af.buff = stats.buffer;
+			stats.af.fd = stats.fd;
+			break;
+		case MSG_ID_STATS_AWB:
+			stats.awb.buff = stats.buffer;
+			stats.awb.fd = stats.fd;
+			break;
+		case MSG_ID_STATS_IHIST:
+			stats.ihist.buff = stats.buffer;
+			stats.ihist.fd = stats.fd;
+			break;
+		case MSG_ID_STATS_RS:
+			stats.rs.buff = stats.buffer;
+			stats.rs.fd = stats.fd;
+			break;
+		case MSG_ID_STATS_CS:
+			stats.cs.buff = stats.buffer;
+			stats.cs.fd = stats.fd;
+			break;
+		case MSG_ID_STATS_BHIST:
+			stats.skin.buff = stats.buffer;
+			stats.skin.fd = stats.fd;
+			break;
+		case MSG_ID_STATS_AWB_AEC:
+			break;
+		default:
+			pr_err("%s: Invalid msg type", __func__);
+			break;
+		}
+		if (!stats.buffer) {
+			pr_err("%s: msm_pmem_stats_ptov_lookup error\n",
+							__func__);
+			isp_event->isp_data.isp_msg.len = 0;
+			rc = -EFAULT;
+		} else {
+			struct msm_stats_buf *stats_buf =
+				kmalloc(sizeof(struct msm_stats_buf),
+							GFP_ATOMIC);
+			if (!stats_buf) {
+				pr_err("%s: out of memory. stats_id = %d\n",
+					__func__, isp_stats->id);
+				rc = -ENOMEM;
+			} else {
+				*stats_buf = stats;
+				isp_event->isp_data.isp_msg.len	=
+					sizeof(struct msm_stats_buf);
+				isp_event->isp_data.isp_msg.data = stats_buf;
+			}
+		}
+		}
+		break;
+	default:
+		pr_err("%s: Unsupport isp notification %d\n",
+			__func__, notification);
+		rc = -EINVAL;
+		break;
+	}
+
+	v4l2_event_queue(pmctl->config_device->config_stat_event_queue.pvdev,
+			 &v4l2_evt);
+
+	return rc;
+}
+
+int msm_isp_notify(struct msm_cam_media_controller *pmctl,
+	struct v4l2_subdev *sd,	unsigned int notification, void *arg)
+{
+	return msm_isp_notify_vfe(pmctl, sd, notification, arg);
+}
+EXPORT_SYMBOL(msm_isp_notify);
+
+static int msm_config_vfe(struct v4l2_subdev *sd,
+	struct msm_cam_media_controller *mctl, void __user *arg)
+{
+	struct msm_vfe_cfg_cmd cfgcmd;
+	struct axidata axi_data;
+
+	if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	memset(&axi_data, 0, sizeof(axi_data));
+	CDBG("%s: cmd_type %d\n", __func__, cfgcmd.cmd_type);
+	switch (cfgcmd.cmd_type) {
+	case CMD_STATS_BG_ENABLE:
+	case CMD_STATS_BE_ENABLE:
+	case CMD_STATS_BF_ENABLE:
+	case CMD_STATS_BHIST_ENABLE:
+	case CMD_STATS_AF_ENABLE:
+	case CMD_STATS_AEC_ENABLE:
+	case CMD_STATS_AWB_ENABLE:
+	case CMD_STATS_AEC_AWB_ENABLE:
+	case CMD_STATS_IHIST_ENABLE:
+	case CMD_STATS_RS_ENABLE:
+	case CMD_STATS_CS_ENABLE:
+		return msm_isp_subdev_ioctl(sd, &cfgcmd, NULL);
+	case CMD_GENERAL:
+	case CMD_STATS_DISABLE:
+		return msm_isp_subdev_ioctl(sd, &cfgcmd,
+							&axi_data);
+	default:
+		pr_err("%s: unknown command type %d\n",
+			__func__, cfgcmd.cmd_type);
+	}
+
+	return -EINVAL;
+}
+
+static int msm_axi_config(struct v4l2_subdev *sd,
+		struct msm_cam_media_controller *mctl, void __user *arg)
+{
+	struct msm_vfe_cfg_cmd cfgcmd;
+
+	if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	switch (cfgcmd.cmd_type) {
+	case CMD_AXI_CFG_PRIM:
+	case CMD_AXI_CFG_SEC:
+	case CMD_AXI_CFG_ZSL:
+	case CMD_RAW_PICT_AXI_CFG:
+	case CMD_AXI_CFG_PRIM_ALL_CHNLS:
+	case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC:
+	case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC_ALL_CHNLS:
+	case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC:
+	case CMD_AXI_START:
+	case CMD_AXI_STOP:
+	case CMD_AXI_RESET:
+	case CMD_AXI_CFG_TERT1:
+	case CMD_AXI_CFG_TERT2:
+		/* Dont need to pass buffer information.
+		 * subdev will get the buffer from media
+		 * controller free queue.
+		 */
+		return msm_isp_subdev_ioctl(sd, &cfgcmd, NULL);
+
+	default:
+		pr_err("%s: unknown command type %d\n",
+			__func__,
+			cfgcmd.cmd_type);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int msm_put_stats_buffer(struct v4l2_subdev *sd,
+			struct msm_cam_media_controller *mctl, void __user *arg)
+{
+	int rc = -EIO;
+
+	struct msm_stats_buf buf;
+	unsigned long pphy;
+	struct msm_vfe_cfg_cmd cfgcmd;
+
+	if (copy_from_user(&buf, arg,
+				sizeof(struct msm_stats_buf))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	CDBG("%s\n", __func__);
+	pphy = msm_pmem_stats_vtop_lookup(mctl, buf.buffer, buf.fd);
+
+	if (pphy != 0) {
+		if (buf.type == STAT_AF)
+			cfgcmd.cmd_type = CMD_STATS_AF_BUF_RELEASE;
+		else if (buf.type == STAT_AEC)
+			cfgcmd.cmd_type = CMD_STATS_AEC_BUF_RELEASE;
+		else if (buf.type == STAT_AWB)
+			cfgcmd.cmd_type = CMD_STATS_AWB_BUF_RELEASE;
+		else if (buf.type == STAT_IHIST)
+			cfgcmd.cmd_type = CMD_STATS_IHIST_BUF_RELEASE;
+		else if (buf.type == STAT_RS)
+			cfgcmd.cmd_type = CMD_STATS_RS_BUF_RELEASE;
+		else if (buf.type == STAT_CS)
+			cfgcmd.cmd_type = CMD_STATS_CS_BUF_RELEASE;
+		else if (buf.type == STAT_AEAW)
+			cfgcmd.cmd_type = CMD_STATS_BUF_RELEASE;
+		else if (buf.type == STAT_BG)
+			cfgcmd.cmd_type = CMD_STATS_BG_BUF_RELEASE;
+		else if (buf.type == STAT_BE)
+			cfgcmd.cmd_type = CMD_STATS_BE_BUF_RELEASE;
+		else if (buf.type == STAT_BF)
+			cfgcmd.cmd_type = CMD_STATS_BF_BUF_RELEASE;
+		else if (buf.type == STAT_BHIST)
+			cfgcmd.cmd_type = CMD_STATS_BHIST_BUF_RELEASE;
+
+		else {
+			pr_err("%s: invalid buf type %d\n",
+				__func__,
+				buf.type);
+			rc = -EINVAL;
+			goto put_done;
+		}
+
+		cfgcmd.value = (void *)&buf;
+
+		rc = msm_isp_subdev_ioctl(sd, &cfgcmd, &pphy);
+	} else {
+		pr_err("%s: NULL physical address\n", __func__);
+		rc = -EINVAL;
+	}
+
+put_done:
+	return rc;
+}
+
+static int msm_vfe_stats_buf_ioctl(struct v4l2_subdev *sd,
+	unsigned int cmd,
+	struct msm_cam_media_controller *mctl,
+	void __user *arg)
+{
+	struct msm_vfe_cfg_cmd cfgcmd;
+	int rc = 0;
+	v4l2_set_subdev_hostdata(sd, mctl);
+	switch (cmd) {
+	case MSM_CAM_IOCTL_STATS_REQBUF: {
+		struct msm_stats_reqbuf reqbuf;
+		if (copy_from_user(&reqbuf, arg,
+			sizeof(struct msm_stats_reqbuf))) {
+			ERR_COPY_FROM_USER();
+			return -EFAULT;
+		}
+	cfgcmd.cmd_type = VFE_CMD_STATS_REQBUF;
+	cfgcmd.value = (void *)&reqbuf;
+	cfgcmd.length = sizeof(struct msm_stats_reqbuf);
+	rc = msm_isp_subdev_ioctl(sd, &cfgcmd, (void *)mctl->client);
+	break;
+	}
+	case MSM_CAM_IOCTL_STATS_ENQUEUEBUF: {
+		struct msm_stats_buf_info buf_info;
+		if (copy_from_user(&buf_info, arg,
+			sizeof(struct msm_stats_buf_info))) {
+			ERR_COPY_FROM_USER();
+			return -EFAULT;
+		}
+	cfgcmd.cmd_type = VFE_CMD_STATS_ENQUEUEBUF;
+	cfgcmd.value = (void *)&buf_info;
+	cfgcmd.length = sizeof(struct msm_stats_buf_info);
+	rc = msm_isp_subdev_ioctl(sd, &cfgcmd, NULL);
+	break;
+	}
+	case MSM_CAM_IOCTL_STATS_FLUSH_BUFQ: {
+		struct msm_stats_flush_bufq bufq_info;
+		if (copy_from_user(&bufq_info, arg,
+			sizeof(struct msm_stats_flush_bufq))) {
+			ERR_COPY_FROM_USER();
+			return -EFAULT;
+		}
+	cfgcmd.cmd_type = VFE_CMD_STATS_FLUSH_BUFQ;
+	cfgcmd.value = (void *)&bufq_info;
+	cfgcmd.length = sizeof(struct msm_stats_flush_bufq);
+	rc = msm_isp_subdev_ioctl(sd, &cfgcmd, NULL);
+	break;
+	}
+	case MSM_CAM_IOCTL_STATS_UNREG_BUF: {
+		struct msm_stats_reqbuf reqbuf;
+		if (copy_from_user(&reqbuf, arg,
+			sizeof(struct msm_stats_reqbuf))) {
+			ERR_COPY_FROM_USER();
+			return -EFAULT;
+		}
+	cfgcmd.cmd_type = VFE_CMD_STATS_UNREGBUF;
+	cfgcmd.value = (void *)&reqbuf;
+	cfgcmd.length = sizeof(struct msm_stats_reqbuf);
+	rc = msm_isp_subdev_ioctl(sd, &cfgcmd, (void *)mctl->client);
+	break;
+	}
+	default:
+		rc = -1;
+	break;
+	}
+	CDBG("%s\n", __func__);
+	return rc;
+}
+/* config function simliar to origanl msm_ioctl_config*/
+int msm_isp_config(struct msm_cam_media_controller *pmctl,
+			 unsigned int cmd, unsigned long arg)
+{
+
+	int rc = -EINVAL;
+	void __user *argp = (void __user *)arg;
+	struct v4l2_subdev *sd;
+	if (!pmctl->vfe_sdev) {
+		pr_err("%s vfe subdev is NULL\n", __func__);
+		return -ENXIO;
+	}
+	sd = pmctl->vfe_sdev;
+	D("%s: cmd %d\n", __func__, _IOC_NR(cmd));
+	switch (cmd) {
+	case MSM_CAM_IOCTL_CONFIG_VFE:
+		/* Coming from config thread for update */
+		rc = msm_config_vfe(sd, pmctl, argp);
+		break;
+
+	case MSM_CAM_IOCTL_AXI_CONFIG:
+		D("Received MSM_CAM_IOCTL_AXI_CONFIG\n");
+		rc = msm_axi_config(sd, pmctl, argp);
+		break;
+
+	case MSM_CAM_IOCTL_RELEASE_STATS_BUFFER:
+		rc = msm_put_stats_buffer(sd, pmctl, argp);
+		break;
+
+	case MSM_CAM_IOCTL_STATS_REQBUF:
+	case MSM_CAM_IOCTL_STATS_ENQUEUEBUF:
+	case MSM_CAM_IOCTL_STATS_FLUSH_BUFQ:
+	case MSM_CAM_IOCTL_STATS_UNREG_BUF:
+		rc = msm_vfe_stats_buf_ioctl(sd, cmd, pmctl, argp);
+		break;
+
+	default:
+		break;
+	}
+
+	D("%s: cmd %d DONE\n", __func__, _IOC_NR(cmd));
+
+	return rc;
+}
+EXPORT_SYMBOL(msm_isp_config);
+
+int msm_isp_subdev_ioctl(struct v4l2_subdev *isp_subdev,
+	struct msm_vfe_cfg_cmd *cfgcmd, void *data)
+{
+	struct msm_camvfe_params vfe_params;
+	vfe_params.vfe_cfg = cfgcmd;
+	vfe_params.data = data;
+	return v4l2_subdev_call(isp_subdev, core, ioctl, 0, &vfe_params);
+}
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/platform/msm/camera_v1/msm_mctl.c
similarity index 100%
rename from drivers/media/video/msm/msm_mctl.c
rename to drivers/media/platform/msm/camera_v1/msm_mctl.c
diff --git a/drivers/media/platform/msm/camera_v1/msm_mctl_buf.c b/drivers/media/platform/msm/camera_v1/msm_mctl_buf.c
new file mode 100644
index 0000000..3ccd258
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/msm_mctl_buf.c
@@ -0,0 +1,1116 @@
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/workqueue.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/ioctl.h>
+#include <linux/spinlock.h>
+#include <linux/videodev2.h>
+#include <linux/vmalloc.h>
+
+#include <media/v4l2-dev.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
+
+#include <linux/android_pmem.h>
+
+#include "msm.h"
+#include "msm_cam_server.h"
+#include "msm_ispif.h"
+
+#ifdef CONFIG_MSM_CAMERA_DEBUG
+#define D(fmt, args...) pr_debug("msm_mctl_buf: " fmt, ##args)
+#else
+#define D(fmt, args...) do {} while (0)
+#endif
+
+static int msm_vb2_ops_queue_setup(struct vb2_queue *vq,
+				const struct v4l2_format *fmt,
+				unsigned int *num_buffers,
+				unsigned int *num_planes,
+				unsigned int sizes[],
+				void *alloc_ctxs[])
+{
+	/* get the video device */
+	struct msm_cam_v4l2_dev_inst *pcam_inst = vb2_get_drv_priv(vq);
+	struct msm_cam_v4l2_device *pcam = pcam_inst->pcam;
+	int i;
+
+	D("%s\n", __func__);
+	if (!pcam || !(*num_buffers)) {
+		pr_err("%s error : invalid input\n", __func__);
+		return -EINVAL;
+	}
+
+	*num_planes = pcam_inst->plane_info.num_planes;
+	for (i = 0; i < pcam_inst->vid_fmt.fmt.pix_mp.num_planes; i++) {
+		sizes[i] = pcam_inst->plane_info.plane[i].size;
+		D("%s Inst %p : Plane %d Offset = %d Size = %ld"
+			"Aligned Size = %d", __func__, pcam_inst, i,
+			pcam_inst->plane_info.plane[i].offset,
+			pcam_inst->plane_info.plane[i].size, sizes[i]);
+	}
+	return 0;
+}
+
+static void msm_vb2_ops_wait_prepare(struct vb2_queue *q)
+{
+	/* we use polling so do not use this fn now */
+}
+static void msm_vb2_ops_wait_finish(struct vb2_queue *q)
+{
+	/* we use polling so do not use this fn now */
+}
+
+static int msm_vb2_ops_buf_init(struct vb2_buffer *vb)
+{
+	struct msm_cam_v4l2_dev_inst *pcam_inst;
+	struct msm_cam_v4l2_device *pcam;
+	struct msm_cam_media_controller *pmctl;
+	struct videobuf2_contig_pmem *mem;
+	struct vb2_queue	*vq;
+	uint32_t buf_idx;
+	struct msm_frame_buffer *buf;
+	int rc = 0, i;
+	enum videobuf2_buffer_type buf_type;
+	struct videobuf2_msm_offset offset;
+	vq = vb->vb2_queue;
+	pcam_inst = vb2_get_drv_priv(vq);
+	pcam = pcam_inst->pcam;
+	D("%s\n", __func__);
+	D("%s, inst=0x%x,idx=%d, width = %d\n", __func__,
+		(u32)pcam_inst, pcam_inst->my_index,
+		pcam_inst->vid_fmt.fmt.pix.width);
+	D("%s, inst=0x%x,idx=%d, height = %d\n", __func__,
+		(u32)pcam_inst, pcam_inst->my_index,
+		pcam_inst->vid_fmt.fmt.pix.height);
+
+	buf = container_of(vb, struct msm_frame_buffer, vidbuf);
+	if (buf->state == MSM_BUFFER_STATE_INITIALIZED)
+		return rc;
+
+	if (pcam_inst->plane_info.buffer_type ==
+		V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+		buf_type = VIDEOBUF2_MULTIPLE_PLANES;
+	else if (pcam_inst->plane_info.buffer_type ==
+		V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		buf_type = VIDEOBUF2_SINGLE_PLANE;
+	else
+		return -EINVAL;
+
+	if (buf_type == VIDEOBUF2_SINGLE_PLANE) {
+		offset.sp_off.y_off = pcam_inst->plane_info.sp_y_offset;
+		offset.sp_off.cbcr_off =
+			pcam_inst->plane_info.plane[0].offset;
+	}
+	buf_idx = vb->v4l2_buf.index;
+	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
+	if (pmctl == NULL) {
+		pr_err("%s No mctl found\n", __func__);
+		return -EINVAL;
+	}
+	for (i = 0; i < vb->num_planes; i++) {
+		mem = vb2_plane_cookie(vb, i);
+		if (mem == NULL) {
+			pr_err("%s Inst %p Buffer %d Plane %d cookie is null",
+				__func__, pcam_inst, buf_idx, i);
+			return -EINVAL;
+		}
+		if (buf_type == VIDEOBUF2_MULTIPLE_PLANES)
+			offset.data_offset =
+				pcam_inst->plane_info.plane[i].offset;
+
+		if (vb->v4l2_buf.memory == V4L2_MEMORY_USERPTR)
+			rc = videobuf2_pmem_contig_user_get(mem, &offset,
+				buf_type,
+				pcam_inst->buf_offset[buf_idx][i].addr_offset,
+				pcam_inst->path, pmctl->client,
+				pmctl->domain_num);
+		else
+			rc = videobuf2_pmem_contig_mmap_get(mem, &offset,
+				buf_type, pcam_inst->path);
+		if (rc < 0) {
+			pr_err("%s error initializing buffer ",
+				__func__);
+			return rc;
+		}
+	}
+	buf->state = MSM_BUFFER_STATE_INITIALIZED;
+	return rc;
+}
+
+static int msm_vb2_ops_buf_prepare(struct vb2_buffer *vb)
+{
+	int i, rc = 0;
+	uint32_t len;
+	struct msm_cam_v4l2_dev_inst *pcam_inst;
+	struct msm_cam_v4l2_device *pcam;
+	struct msm_frame_buffer *buf;
+	struct vb2_queue *vq;
+
+	D("%s\n", __func__);
+	if (!vb || !vb->vb2_queue) {
+		pr_err("%s error : input is NULL\n", __func__);
+		return -EINVAL;
+	}
+	vq = vb->vb2_queue;
+	pcam_inst = vb2_get_drv_priv(vq);
+	pcam = pcam_inst->pcam;
+	buf = container_of(vb, struct msm_frame_buffer, vidbuf);
+
+	if (!pcam || !buf) {
+		pr_err("%s error : pointer is NULL\n", __func__);
+		return -EINVAL;
+	}
+	/* by this time vid_fmt should be already set.
+	 * return error if it is not. */
+	if ((pcam_inst->vid_fmt.fmt.pix.width == 0) ||
+		(pcam_inst->vid_fmt.fmt.pix.height == 0)) {
+		pr_err("%s error : pcam vid_fmt is not set\n", __func__);
+		return -EINVAL;
+	}
+	/* prefill in the byteused field */
+	for (i = 0; i < vb->num_planes; i++) {
+		len = vb2_plane_size(vb, i);
+		vb2_set_plane_payload(vb, i, len);
+	}
+	buf->state = MSM_BUFFER_STATE_PREPARED;
+	return rc;
+}
+
+static int msm_vb2_ops_buf_finish(struct vb2_buffer *vb)
+{
+	struct msm_cam_v4l2_dev_inst *pcam_inst;
+	struct msm_cam_v4l2_device *pcam;
+	struct msm_frame_buffer *buf;
+
+	pcam_inst = vb2_get_drv_priv(vb->vb2_queue);
+	pcam = pcam_inst->pcam;
+	buf = container_of(vb, struct msm_frame_buffer, vidbuf);
+	buf->state = MSM_BUFFER_STATE_DEQUEUED;
+	D("%s: inst=0x%x, buf=0x%x, idx=%d\n", __func__,
+	(uint32_t)pcam_inst, (uint32_t)buf, vb->v4l2_buf.index);
+	return 0;
+}
+
+static void msm_vb2_ops_buf_cleanup(struct vb2_buffer *vb)
+{
+	struct msm_cam_v4l2_dev_inst *pcam_inst;
+	struct msm_cam_media_controller *pmctl;
+	struct msm_cam_v4l2_device *pcam;
+	struct videobuf2_contig_pmem *mem;
+	struct msm_frame_buffer *buf, *tmp;
+	uint32_t i, vb_phyaddr = 0, buf_phyaddr = 0;
+	unsigned long flags = 0;
+
+	pcam_inst = vb2_get_drv_priv(vb->vb2_queue);
+	pcam = pcam_inst->pcam;
+	buf = container_of(vb, struct msm_frame_buffer, vidbuf);
+
+
+	if (pcam_inst->vid_fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+		for (i = 0; i < vb->num_planes; i++) {
+			mem = vb2_plane_cookie(vb, i);
+			if (!mem) {
+				D("%s Inst %p memory already freed up. return",
+					__func__, pcam_inst);
+				return;
+			}
+			D("%s: inst=%p, buf=0x%x, idx=%d plane id = %d\n",
+				__func__, pcam_inst,
+				(uint32_t)buf, vb->v4l2_buf.index, i);
+
+			spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
+			list_for_each_entry_safe(buf, tmp,
+					&pcam_inst->free_vq, list) {
+				if (&buf->vidbuf == vb) {
+					list_del_init(&buf->list);
+					break;
+				}
+			}
+			spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
+		}
+	} else {
+		mem = vb2_plane_cookie(vb, 0);
+		if (!mem)
+			return;
+		D("%s: inst=0x%x, buf=0x%x, idx=%d\n", __func__,
+		(uint32_t)pcam_inst, (uint32_t)buf, vb->v4l2_buf.index);
+		vb_phyaddr = (unsigned long) videobuf2_to_pmem_contig(vb, 0);
+		spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
+		list_for_each_entry_safe(buf, tmp,
+				&pcam_inst->free_vq, list) {
+			buf_phyaddr = (unsigned long)
+				videobuf2_to_pmem_contig(&buf->vidbuf, 0);
+			D("%s vb_idx=%d,vb_paddr=0x%x,phyaddr=0x%x\n",
+				__func__, buf->vidbuf.v4l2_buf.index,
+				buf_phyaddr, vb_phyaddr);
+			if (vb_phyaddr == buf_phyaddr) {
+				list_del_init(&buf->list);
+				break;
+			}
+		}
+		spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
+	}
+	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
+	if (pmctl == NULL) {
+		pr_err("%s No mctl found\n", __func__);
+		buf->state = MSM_BUFFER_STATE_UNUSED;
+		return;
+	}
+	for (i = 0; i < vb->num_planes; i++) {
+		mem = vb2_plane_cookie(vb, i);
+		if (mem) {
+			videobuf2_pmem_contig_user_put(mem, pmctl->client,
+				pmctl->domain_num);
+		} else {
+			pr_err("%s Inst %p buffer plane cookie is null",
+				__func__, pcam_inst);
+			return;
+		}
+	}
+	buf->state = MSM_BUFFER_STATE_UNUSED;
+}
+
+static int msm_vb2_ops_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+	return 0;
+}
+
+static int msm_vb2_ops_stop_streaming(struct vb2_queue *q)
+{
+	return 0;
+}
+
+static void msm_vb2_ops_buf_queue(struct vb2_buffer *vb)
+{
+	struct msm_cam_v4l2_dev_inst *pcam_inst = NULL;
+	struct msm_cam_v4l2_device *pcam = NULL;
+	unsigned long flags = 0;
+	struct vb2_queue *vq;
+	struct msm_frame_buffer *buf;
+	D("%s\n", __func__);
+	if (!vb || !vb->vb2_queue) {
+		pr_err("%s error : input is NULL\n", __func__);
+		return ;
+	}
+	vq = vb->vb2_queue;
+	pcam_inst = vb2_get_drv_priv(vq);
+	pcam = pcam_inst->pcam;
+	D("%s pcam_inst=%p,(vb=0x%p),idx=%d,len=%d\n",
+		__func__, pcam_inst,
+	vb, vb->v4l2_buf.index, vb->v4l2_buf.length);
+	D("%s pcam_inst=%p, idx=%d\n", __func__, pcam_inst,
+		vb->v4l2_buf.index);
+	buf = container_of(vb, struct msm_frame_buffer, vidbuf);
+	spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
+	/* we are returning a buffer to the queue */
+	list_add_tail(&buf->list, &pcam_inst->free_vq);
+	spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
+	buf->state = MSM_BUFFER_STATE_QUEUED;
+}
+
+static struct vb2_ops msm_vb2_ops = {
+	.queue_setup = msm_vb2_ops_queue_setup,
+	.wait_prepare = msm_vb2_ops_wait_prepare,
+	.wait_finish = msm_vb2_ops_wait_finish,
+	.buf_init = msm_vb2_ops_buf_init,
+	.buf_prepare = msm_vb2_ops_buf_prepare,
+	.buf_finish = msm_vb2_ops_buf_finish,
+	.buf_cleanup = msm_vb2_ops_buf_cleanup,
+	.start_streaming = msm_vb2_ops_start_streaming,
+	.stop_streaming = msm_vb2_ops_stop_streaming,
+	.buf_queue = msm_vb2_ops_buf_queue,
+};
+
+
+/* prepare a video buffer queue for a vl42 device*/
+static int msm_vbqueue_init(struct msm_cam_v4l2_dev_inst *pcam_inst,
+			struct vb2_queue *q, enum v4l2_buf_type type)
+{
+	if (!q) {
+		pr_err("%s error : input is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	spin_lock_init(&pcam_inst->vq_irqlock);
+	INIT_LIST_HEAD(&pcam_inst->free_vq);
+	videobuf2_queue_pmem_contig_init(q, type,
+					&msm_vb2_ops,
+					sizeof(struct msm_frame_buffer),
+					(void *)pcam_inst);
+	return 0;
+}
+
+int msm_mctl_img_mode_to_inst_index(struct msm_cam_media_controller *pmctl,
+					int image_mode, int node_type)
+{
+	if ((image_mode >= 0) && node_type &&
+		pmctl->pcam_ptr->mctl_node.dev_inst_map[image_mode])
+		return pmctl->pcam_ptr->
+				mctl_node.dev_inst_map[image_mode]->my_index;
+	else if ((image_mode >= 0) &&
+		pmctl->pcam_ptr->dev_inst_map[image_mode])
+		return	pmctl->pcam_ptr->
+				dev_inst_map[image_mode]->my_index;
+	else
+		return -EINVAL;
+}
+
+void msm_mctl_gettimeofday(struct timeval *tv)
+{
+	struct timespec ts;
+
+	BUG_ON(!tv);
+
+	ktime_get_ts(&ts);
+	tv->tv_sec = ts.tv_sec;
+	tv->tv_usec = ts.tv_nsec/1000;
+}
+
+struct msm_frame_buffer *msm_mctl_buf_find(
+	struct msm_cam_media_controller *pmctl,
+	struct msm_cam_v4l2_dev_inst *pcam_inst, int del_buf,
+	struct msm_free_buf *fbuf)
+{
+	struct msm_frame_buffer *buf = NULL, *tmp;
+	uint32_t buf_phyaddr = 0;
+	unsigned long flags = 0;
+	uint32_t buf_idx, offset = 0;
+	struct videobuf2_contig_pmem *mem;
+
+	/* we actually need a list, not a queue */
+	spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
+	list_for_each_entry_safe(buf, tmp,
+			&pcam_inst->free_vq, list) {
+		buf_idx = buf->vidbuf.v4l2_buf.index;
+		mem = vb2_plane_cookie(&buf->vidbuf, 0);
+		if (mem == NULL) {
+			pr_err("%s Inst %p plane cookie is null",
+				__func__, pcam_inst);
+			spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
+			return NULL;
+		}
+		if (mem->buffer_type == VIDEOBUF2_MULTIPLE_PLANES)
+			offset = mem->offset.data_offset +
+				pcam_inst->buf_offset[buf_idx][0].data_offset;
+		else
+			offset = mem->offset.sp_off.y_off;
+		buf_phyaddr = (unsigned long)
+				videobuf2_to_pmem_contig(&buf->vidbuf, 0) +
+				offset;
+		D("%s vb_idx=%d,vb_paddr=0x%x ch0=0x%x\n",
+			__func__, buf->vidbuf.v4l2_buf.index,
+			buf_phyaddr, fbuf->ch_paddr[0]);
+		if (fbuf->ch_paddr[0] == buf_phyaddr) {
+			if (del_buf)
+				list_del_init(&buf->list);
+			spin_unlock_irqrestore(&pcam_inst->vq_irqlock,
+								flags);
+			buf->state = MSM_BUFFER_STATE_RESERVED;
+			return buf;
+		}
+	}
+	spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
+	return NULL;
+}
+
+int msm_mctl_buf_done_proc(
+		struct msm_cam_media_controller *pmctl,
+		struct msm_cam_v4l2_dev_inst *pcam_inst,
+		struct msm_free_buf *fbuf,
+		uint32_t *frame_id,
+		struct msm_cam_timestamp *cam_ts)
+{
+	struct msm_frame_buffer *buf = NULL;
+	int del_buf = 1;
+
+	buf = msm_mctl_buf_find(pmctl, pcam_inst, del_buf, fbuf);
+	if (!buf) {
+		pr_err("%s: buf=0x%x not found\n",
+			__func__, fbuf->ch_paddr[0]);
+		return -EINVAL;
+	}
+	if (!cam_ts->present) {
+		if (frame_id)
+			buf->vidbuf.v4l2_buf.sequence = *frame_id;
+		msm_mctl_gettimeofday(
+			&buf->vidbuf.v4l2_buf.timestamp);
+	} else {
+		D("%s Copying timestamp as %ld.%ld", __func__,
+			cam_ts->timestamp.tv_sec, cam_ts->timestamp.tv_usec);
+		buf->vidbuf.v4l2_buf.timestamp = cam_ts->timestamp;
+		buf->vidbuf.v4l2_buf.sequence  = cam_ts->frame_id;
+	}
+	D("%s Notify user about buffer %d image_mode %d frame_id %d", __func__,
+		buf->vidbuf.v4l2_buf.index, pcam_inst->image_mode,
+		buf->vidbuf.v4l2_buf.sequence);
+	vb2_buffer_done(&buf->vidbuf, VB2_BUF_STATE_DONE);
+	return 0;
+}
+
+
+int msm_mctl_buf_done(struct msm_cam_media_controller *p_mctl,
+	struct msm_cam_buf_handle *buf_handle,
+	struct msm_free_buf *fbuf,
+	uint32_t frame_id)
+{
+	struct msm_cam_v4l2_dev_inst *pcam_inst;
+	int idx, rc;
+	int pp_divert_type = 0, pp_type = 0;
+	uint32_t image_mode;
+	struct msm_cam_timestamp cam_ts;
+
+	if (!p_mctl || !buf_handle || !fbuf) {
+		pr_err("%s Invalid argument. ", __func__);
+		return -EINVAL;
+	}
+	if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_IMG_MODE)
+		image_mode = buf_handle->image_mode;
+	else
+		image_mode = GET_IMG_MODE(buf_handle->inst_handle);
+
+	if (image_mode > MSM_V4L2_EXT_CAPTURE_MODE_MAX) {
+		pr_err("%s Invalid image mode %d ", __func__, image_mode);
+		return -EINVAL;
+	}
+
+	msm_mctl_check_pp(p_mctl, image_mode, &pp_divert_type, &pp_type);
+	D("%s: pp_type=%d, pp_divert_type = %d, frame_id = 0x%x image_mode %d",
+		__func__, pp_type, pp_divert_type, frame_id, image_mode);
+	if (pp_type || pp_divert_type) {
+		rc = msm_mctl_do_pp_divert(p_mctl, buf_handle,
+			fbuf, frame_id, pp_type);
+	} else {
+		/* Find the instance on which vb2_buffer_done() needs to be
+		 * called, so that the user can get the buffer.
+		 * If the lookup type is
+		 * - By instance handle:
+		 *    Either mctl_pp inst idx or video inst idx should be set.
+		 *    Try to get the MCTL_PP inst idx first, if its not set,
+		 *    fall back to video inst idx. Once we get the inst idx,
+		 *    get the pcam_inst from the corresponding dev_inst[] map.
+		 *    If neither are set, its a serious error, trigger a BUG_ON.
+		 * - By image mode:
+		 *    Legacy usecase. Use the image mode and get the pcam_inst
+		 *    from the video node.
+		 */
+		if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_INST_HANDLE) {
+			idx = GET_MCTLPP_INST_IDX(buf_handle->inst_handle);
+			if (idx > MSM_DEV_INST_MAX) {
+				idx = GET_VIDEO_INST_IDX(
+					buf_handle->inst_handle);
+				BUG_ON(idx > MSM_DEV_INST_MAX);
+				pcam_inst = p_mctl->pcam_ptr->dev_inst[idx];
+			} else {
+				pcam_inst = p_mctl->pcam_ptr->mctl_node.
+					dev_inst[idx];
+			}
+		} else if (buf_handle->buf_lookup_type ==
+				BUF_LOOKUP_BY_IMG_MODE) {
+			idx = msm_mctl_img_mode_to_inst_index(p_mctl,
+				buf_handle->image_mode, 0);
+			if (idx < 0) {
+				pr_err("%s Invalid idx %d ", __func__, idx);
+				return -EINVAL;
+			}
+			pcam_inst = p_mctl->pcam_ptr->dev_inst[idx];
+		} else {
+			pr_err("%s Invalid buffer lookup type %d", __func__,
+				buf_handle->buf_lookup_type);
+			return -EINVAL;
+		}
+		if (!pcam_inst) {
+			pr_err("%s Invalid instance, Dropping buffer. ",
+				__func__);
+			return -EINVAL;
+		}
+		memset(&cam_ts, 0, sizeof(cam_ts));
+		rc = msm_mctl_buf_done_proc(p_mctl, pcam_inst,
+			fbuf, &frame_id, &cam_ts);
+	}
+	return rc;
+}
+
+int msm_mctl_buf_init(struct msm_cam_v4l2_device *pcam)
+{
+	struct msm_cam_media_controller *pmctl;
+	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
+	if (pmctl == NULL) {
+		pr_err("%s No mctl found\n", __func__);
+		return -EINVAL;
+	}
+	pmctl->mctl_vbqueue_init = msm_vbqueue_init;
+	return 0;
+}
+
+static int is_buffer_queued(struct msm_cam_v4l2_device *pcam, int image_mode)
+{
+	int idx;
+	int ret = 0;
+	struct msm_frame_buffer *buf = NULL;
+	struct msm_cam_v4l2_dev_inst *pcam_inst = NULL;
+	idx = pcam->mctl_node.dev_inst_map[image_mode]->my_index;
+	pcam_inst = pcam->mctl_node.dev_inst[idx];
+	list_for_each_entry(buf, &pcam_inst->free_vq, list) {
+		if (buf->state != MSM_BUFFER_STATE_QUEUED)
+			continue;
+		ret = 1;
+	}
+	return ret;
+}
+
+struct msm_cam_v4l2_dev_inst *msm_mctl_get_inst_by_img_mode(
+	struct msm_cam_media_controller *pmctl, uint32_t img_mode)
+{
+	struct msm_cam_v4l2_dev_inst *pcam_inst = NULL;
+	struct msm_cam_v4l2_device *pcam = pmctl->pcam_ptr;
+	int idx;
+
+		/* Valid image mode. Search the mctl node first.
+		 * If mctl node doesnt have the instance, then
+		 * search in the user's video node */
+		if (pmctl->vfe_output_mode == VFE_OUTPUTS_MAIN_AND_THUMB
+		|| pmctl->vfe_output_mode == VFE_OUTPUTS_THUMB_AND_MAIN) {
+			if (pcam->mctl_node.dev_inst_map[img_mode]
+			&& is_buffer_queued(pcam, img_mode)) {
+				idx = pcam->mctl_node.dev_inst_map[img_mode]
+							->my_index;
+				pcam_inst = pcam->mctl_node.dev_inst[idx];
+				D("%s Found instance %p in mctl node device\n",
+				  __func__, pcam_inst);
+			} else if (pcam->dev_inst_map[img_mode]) {
+				idx = pcam->dev_inst_map[img_mode]->my_index;
+				pcam_inst = pcam->dev_inst[idx];
+				D("%s Found instance %p in video device\n",
+				__func__, pcam_inst);
+			}
+		} else if (img_mode == MSM_V4L2_EXT_CAPTURE_MODE_V2X_LIVESHOT) {
+				img_mode = MSM_V4L2_EXT_CAPTURE_MODE_MAIN;
+			if (pcam->mctl_node.dev_inst_map[img_mode] &&
+					is_buffer_queued(pcam, img_mode)) {
+				idx = pcam->mctl_node.dev_inst_map[img_mode]
+							->my_index;
+				pcam_inst = pcam->mctl_node.dev_inst[idx];
+				D("%s Found instance %p in mctl node device\n",
+				  __func__, pcam_inst);
+			} else if (pcam->dev_inst_map[img_mode]) {
+				idx = pcam->dev_inst_map[img_mode]->my_index;
+				pcam_inst = pcam->dev_inst[idx];
+				D("%s Found instance %p in video device\n",
+				__func__, pcam_inst);
+			}
+		} else {
+			if (pcam->mctl_node.dev_inst_map[img_mode]) {
+				idx = pcam->mctl_node.dev_inst_map[img_mode]
+				->my_index;
+				pcam_inst = pcam->mctl_node.dev_inst[idx];
+				D("%s Found instance %p in mctl node device\n",
+				__func__, pcam_inst);
+			} else if (pcam->dev_inst_map[img_mode]) {
+				idx = pcam->dev_inst_map[img_mode]->my_index;
+				pcam_inst = pcam->dev_inst[idx];
+				D("%s Found instance %p in video device\n",
+					__func__, pcam_inst);
+			}
+		}
+	return pcam_inst;
+}
+
+struct msm_cam_v4l2_dev_inst *msm_mctl_get_pcam_inst(
+				struct msm_cam_media_controller *pmctl,
+				struct msm_cam_buf_handle *buf_handle)
+{
+	struct msm_cam_v4l2_dev_inst *pcam_inst = NULL;
+	struct msm_cam_v4l2_device *pcam = pmctl->pcam_ptr;
+	int idx;
+
+	/* Get the pcam instance on based on the following rules:
+	 * If the lookup type is
+	 * - By instance handle:
+	 *    Either mctl_pp inst idx or video inst idx should be set.
+	 *    Try to get the MCTL_PP inst idx first, if its not set,
+	 *    fall back to video inst idx. Once we get the inst idx,
+	 *    get the pcam_inst from the corresponding dev_inst[] map.
+	 *    If neither are set, its a serious error, trigger a BUG_ON.
+	 * - By image mode:(Legacy usecase)
+	 *    If vfe is in configured in snapshot mode, first check if
+	 *    mctl pp node has a instance created for this image mode
+	 *    and if there is a buffer queued for that instance.
+	 *    If so, return that instance, otherwise get the pcam instance
+	 *    for this image_mode from the video instance.
+	 *    If the vfe is configured in any other mode, then first check
+	 *    if mctl pp node has a instance created for this image mode,
+	 *    otherwise get the pcam instance for this image mode from the
+	 *    video instance.
+	 */
+	if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_INST_HANDLE) {
+		idx = GET_MCTLPP_INST_IDX(buf_handle->inst_handle);
+		if (idx > MSM_DEV_INST_MAX) {
+			idx = GET_VIDEO_INST_IDX(buf_handle->inst_handle);
+			BUG_ON(idx > MSM_DEV_INST_MAX);
+			pcam_inst = pcam->dev_inst[idx];
+		} else {
+			pcam_inst = pcam->mctl_node.dev_inst[idx];
+		}
+	} else if ((buf_handle->buf_lookup_type == BUF_LOOKUP_BY_IMG_MODE)
+		&& (buf_handle->image_mode >= 0 &&
+		buf_handle->image_mode < MSM_V4L2_EXT_CAPTURE_MODE_MAX)) {
+		pcam_inst = msm_mctl_get_inst_by_img_mode(pmctl,
+				buf_handle->image_mode);
+	} else {
+		pr_err("%s Invalid buffer lookup type %d", __func__,
+			buf_handle->buf_lookup_type);
+	}
+	return pcam_inst;
+}
+
+int msm_mctl_reserve_free_buf(
+	struct msm_cam_media_controller *pmctl,
+	struct msm_cam_v4l2_dev_inst *pref_pcam_inst,
+	struct msm_cam_buf_handle *buf_handle,
+	struct msm_free_buf *free_buf)
+{
+	struct msm_cam_v4l2_dev_inst *pcam_inst = pref_pcam_inst;
+	unsigned long flags = 0;
+	struct videobuf2_contig_pmem *mem;
+	struct msm_frame_buffer *buf = NULL;
+	int rc = -EINVAL, i;
+	uint32_t buf_idx, plane_offset = 0;
+
+	if (!free_buf || !pmctl || !buf_handle) {
+		pr_err("%s: Invalid argument passed\n", __func__);
+		return rc;
+	}
+	memset(free_buf, 0, sizeof(struct msm_free_buf));
+
+	/* If the caller wants to reserve a buffer from a particular
+	 * camera instance, he would send the preferred camera instance.
+	 * If the preferred camera instance is NULL, get the
+	 * camera instance using the image mode passed */
+	if (!pcam_inst)
+		pcam_inst = msm_mctl_get_pcam_inst(pmctl, buf_handle);
+
+	if (!pcam_inst || !pcam_inst->streamon) {
+		pr_err("%s: stream is turned off\n", __func__);
+		return rc;
+	}
+	spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
+	if (pcam_inst->free_vq.next == NULL) {
+		pr_err("%s Inst %p Free queue head is null",
+			__func__, pcam_inst);
+		spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
+		return rc;
+	}
+	list_for_each_entry(buf, &pcam_inst->free_vq, list) {
+		if (buf == NULL) {
+			pr_err("%s Inst %p Invalid buffer ptr",
+				__func__, pcam_inst);
+			spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
+			return rc;
+		}
+		if (buf->state != MSM_BUFFER_STATE_QUEUED)
+			continue;
+
+		buf_idx = buf->vidbuf.v4l2_buf.index;
+		if (pcam_inst->vid_fmt.type ==
+				V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+			free_buf->num_planes =
+				pcam_inst->plane_info.num_planes;
+			for (i = 0; i < free_buf->num_planes; i++) {
+				mem = vb2_plane_cookie(&buf->vidbuf, i);
+				if (mem == NULL) {
+					pr_err("%s Inst %p %d invalid cookie",
+						__func__, pcam_inst, buf_idx);
+					spin_unlock_irqrestore(
+						&pcam_inst->vq_irqlock, flags);
+					return rc;
+				}
+				if (mem->buffer_type ==
+						VIDEOBUF2_MULTIPLE_PLANES)
+					plane_offset =
+					mem->offset.data_offset;
+				else
+					plane_offset =
+					mem->offset.sp_off.cbcr_off;
+
+				D("%s: data off %d plane off %d",
+					__func__,
+					pcam_inst->buf_offset[buf_idx][i].
+					data_offset, plane_offset);
+				free_buf->ch_paddr[i] =	(uint32_t)
+				videobuf2_to_pmem_contig(&buf->vidbuf, i) +
+				pcam_inst->buf_offset[buf_idx][i].data_offset +
+				plane_offset;
+
+			}
+		} else {
+			mem = vb2_plane_cookie(&buf->vidbuf, 0);
+			if (mem == NULL) {
+				pr_err("%s Inst %p %d invalid cookie",
+					__func__, pcam_inst, buf_idx);
+				spin_unlock_irqrestore(
+					&pcam_inst->vq_irqlock, flags);
+				return rc;
+			}
+			free_buf->ch_paddr[0] = (uint32_t)
+				videobuf2_to_pmem_contig(&buf->vidbuf, 0) +
+				mem->offset.sp_off.y_off;
+			free_buf->ch_paddr[1] =	free_buf->ch_paddr[0] +
+				mem->offset.sp_off.cbcr_off;
+		}
+		free_buf->vb = (uint32_t)buf;
+		buf->state = MSM_BUFFER_STATE_RESERVED;
+		D("%s inst=0x%p, idx=%d, paddr=0x%x, "
+			"ch1 addr=0x%x\n", __func__,
+			pcam_inst, buf->vidbuf.v4l2_buf.index,
+			free_buf->ch_paddr[0], free_buf->ch_paddr[1]);
+		rc = 0;
+		break;
+	}
+	if (rc != 0)
+		D("%s:No free buffer available: inst = 0x%p ",
+				__func__, pcam_inst);
+	spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
+	return rc;
+}
+
+int msm_mctl_release_free_buf(struct msm_cam_media_controller *pmctl,
+				struct msm_cam_v4l2_dev_inst *pcam_inst,
+				struct msm_free_buf *free_buf)
+{
+	unsigned long flags = 0;
+	struct msm_frame_buffer *buf = NULL;
+	uint32_t buf_phyaddr = 0;
+	int rc = -EINVAL;
+
+	if (!pcam_inst || !free_buf) {
+		pr_err("%s Invalid argument, buffer will not be returned\n",
+			__func__);
+		return rc;
+	}
+
+	spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
+	list_for_each_entry(buf, &pcam_inst->free_vq, list) {
+		buf_phyaddr =
+			(uint32_t) videobuf2_to_pmem_contig(&buf->vidbuf, 0);
+		if (free_buf->ch_paddr[0] == buf_phyaddr) {
+			D("%s Return buffer %d and mark it as QUEUED\n",
+				__func__, buf->vidbuf.v4l2_buf.index);
+			buf->state = MSM_BUFFER_STATE_QUEUED;
+			rc = 0;
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
+
+	if (rc)
+		pr_err("%s Cannot find buffer %x", __func__,
+			free_buf->ch_paddr[0]);
+
+	return rc;
+}
+
+int msm_mctl_buf_done_pp(struct msm_cam_media_controller *pmctl,
+	struct msm_cam_buf_handle *buf_handle,
+	struct msm_free_buf *frame,
+	struct msm_cam_return_frame_info *ret_frame)
+{
+	struct msm_cam_v4l2_dev_inst *pcam_inst = NULL;
+	int rc = 0, idx;
+	struct msm_cam_timestamp cam_ts;
+
+	if (!pmctl || !buf_handle || !ret_frame) {
+		pr_err("%s Invalid argument ", __func__);
+		return -EINVAL;
+	}
+
+	if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_INST_HANDLE) {
+		idx = GET_MCTLPP_INST_IDX(buf_handle->inst_handle);
+		if (idx > MSM_DEV_INST_MAX) {
+			idx = GET_VIDEO_INST_IDX(buf_handle->inst_handle);
+			BUG_ON(idx > MSM_DEV_INST_MAX);
+			pcam_inst = pmctl->pcam_ptr->dev_inst[idx];
+		} else {
+			pcam_inst = pmctl->pcam_ptr->mctl_node.dev_inst[idx];
+		}
+	} else if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_IMG_MODE) {
+		idx = msm_mctl_img_mode_to_inst_index(pmctl,
+			buf_handle->image_mode, ret_frame->node_type);
+		if (idx < 0) {
+			pr_err("%s Invalid instance, buffer not released\n",
+				__func__);
+			return idx;
+		}
+		if (ret_frame->node_type)
+			pcam_inst = pmctl->pcam_ptr->mctl_node.dev_inst[idx];
+		else
+			pcam_inst = pmctl->pcam_ptr->dev_inst[idx];
+	}
+	if (!pcam_inst) {
+		pr_err("%s Invalid instance, cannot send buf to user",
+			__func__);
+		return -EINVAL;
+	}
+
+	D("%s:inst=0x%p, paddr=0x%x, dirty=%d",
+		__func__, pcam_inst, frame->ch_paddr[0], ret_frame->dirty);
+	cam_ts.present = 1;
+	cam_ts.timestamp = ret_frame->timestamp;
+	cam_ts.frame_id   = ret_frame->frame_id;
+	if (ret_frame->dirty)
+		/* the frame is dirty, not going to disptach to app */
+		rc = msm_mctl_release_free_buf(pmctl, pcam_inst, frame);
+	else
+		rc = msm_mctl_buf_done_proc(pmctl, pcam_inst, frame,
+			NULL, &cam_ts);
+	return rc;
+}
+
+int msm_mctl_buf_return_buf(struct msm_cam_media_controller *pmctl,
+			int image_mode, struct msm_frame_buffer *rbuf)
+{
+	int idx = 0;
+	struct msm_frame_buffer *buf = NULL;
+	struct msm_cam_v4l2_dev_inst *pcam_inst;
+	struct msm_cam_v4l2_device *pcam = pmctl->pcam_ptr;
+	unsigned long flags = 0;
+
+	if (pcam->mctl_node.dev_inst_map[image_mode]) {
+		idx = pcam->mctl_node.dev_inst_map[image_mode]->my_index;
+		pcam_inst = pcam->mctl_node.dev_inst[idx];
+		D("%s Found instance %p in mctl node device\n",
+			__func__, pcam_inst);
+	} else {
+		pr_err("%s Invalid image mode %d ", __func__, image_mode);
+		return -EINVAL;
+	}
+
+	if (!pcam_inst) {
+		pr_err("%s Invalid instance\n", __func__);
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
+	if (!list_empty(&pcam_inst->free_vq)) {
+		list_for_each_entry(buf, &pcam_inst->free_vq, list) {
+			if (rbuf == buf) {
+				D("%s Return buffer %x in pcam_inst %p ",
+				__func__, (int)rbuf, pcam_inst);
+				buf->state = MSM_BUFFER_STATE_QUEUED;
+				spin_unlock_irqrestore(&pcam_inst->vq_irqlock,
+					flags);
+				return 0;
+			}
+		}
+	}
+	spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
+	return -EINVAL;
+}
+
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+/* Unmap using ION APIs */
+static void __msm_mctl_unmap_user_frame(struct msm_cam_meta_frame *meta_frame,
+	struct ion_client *client, int domain_num)
+{
+	int i = 0;
+	for (i = 0; i < meta_frame->frame.num_planes; i++) {
+		D("%s Plane %d handle %p", __func__, i,
+			meta_frame->map[i].handle);
+		ion_unmap_iommu(client, meta_frame->map[i].handle,
+					domain_num, 0);
+		ion_free(client, meta_frame->map[i].handle);
+	}
+}
+
+/* Map using ION APIs */
+static int __msm_mctl_map_user_frame(struct msm_cam_meta_frame *meta_frame,
+	struct ion_client *client, int domain_num)
+{
+	unsigned long paddr = 0;
+	unsigned long len = 0;
+	int i = 0, j = 0;
+
+	for (i = 0; i < meta_frame->frame.num_planes; i++) {
+		meta_frame->map[i].handle = ion_import_dma_buf(client,
+			meta_frame->frame.mp[i].fd);
+		if (IS_ERR_OR_NULL(meta_frame->map[i].handle)) {
+			pr_err("%s: ion_import failed for plane = %d fd = %d",
+				__func__, i, meta_frame->frame.mp[i].fd);
+			/* Roll back previous plane mappings, if any */
+			for (j = i-1; j >= 0; j--) {
+				ion_unmap_iommu(client,
+					meta_frame->map[j].handle,
+					domain_num, 0);
+				ion_free(client, meta_frame->map[j].handle);
+			}
+			return -EACCES;
+		}
+		D("%s Mapping fd %d plane %d handle %p", __func__,
+			meta_frame->frame.mp[i].fd, i,
+			meta_frame->map[i].handle);
+		if (ion_map_iommu(client, meta_frame->map[i].handle,
+				domain_num, 0, SZ_4K,
+				0, &paddr, &len, 0, 0) < 0) {
+			pr_err("%s: cannot map address plane %d", __func__, i);
+			ion_free(client, meta_frame->map[i].handle);
+			/* Roll back previous plane mappings, if any */
+			for (j = i-1; j >= 0; j--) {
+				if (meta_frame->map[j].handle) {
+					ion_unmap_iommu(client,
+						meta_frame->map[j].handle,
+						domain_num, 0);
+					ion_free(client,
+						meta_frame->map[j].handle);
+				}
+			}
+			return -EFAULT;
+		}
+
+		/* Validate the offsets with the mapped length. */
+		if ((meta_frame->frame.mp[i].addr_offset > len) ||
+			(meta_frame->frame.mp[i].data_offset +
+			meta_frame->frame.mp[i].length > len)) {
+			pr_err("%s: Invalid offsets A %d D %d L %d len %ld",
+				__func__, meta_frame->frame.mp[i].addr_offset,
+				meta_frame->frame.mp[i].data_offset,
+				meta_frame->frame.mp[i].length, len);
+			/* Roll back previous plane mappings, if any */
+			for (j = i; j >= 0; j--) {
+				if (meta_frame->map[j].handle) {
+					ion_unmap_iommu(client,
+						meta_frame->map[j].handle,
+						domain_num, 0);
+					ion_free(client,
+						meta_frame->map[j].handle);
+				}
+			}
+			return -EINVAL;
+		}
+		meta_frame->map[i].data_offset =
+			meta_frame->frame.mp[i].data_offset;
+		/* Add the addr_offset to the paddr here itself. The addr_offset
+		 * will be non-zero only if the user has allocated a buffer with
+		 * a single fd, but logically partitioned it into
+		 * multiple planes or buffers.*/
+		paddr += meta_frame->frame.mp[i].addr_offset;
+		meta_frame->map[i].paddr = paddr;
+		meta_frame->map[i].len = len;
+		D("%s Plane %d fd %d handle %p paddr %x", __func__,
+			i, meta_frame->frame.mp[i].fd,
+			meta_frame->map[i].handle,
+			(uint32_t)meta_frame->map[i].paddr);
+	}
+	D("%s Frame mapped successfully ", __func__);
+	return 0;
+}
+#else
+/* Unmap using PMEM APIs */
+static int __msm_mctl_unmap_user_frame(struct msm_cam_meta_frame *meta_frame,
+	struct ion_client *client, int domain_num)
+{
+	int i = 0, rc = 0;
+
+	for (i = 0; i < meta_frame->frame.num_planes; i++) {
+		D("%s Plane %d handle %p", __func__, i,
+			meta_frame->map[i].handle);
+		put_pmem_file(meta_frame->map[i].file);
+	}
+}
+
+/* Map using PMEM APIs */
+static int __msm_mctl_map_user_frame(struct msm_cam_meta_frame *meta_frame,
+	struct ion_client *client, int domain_num)
+{
+	unsigned long kvstart = 0;
+	unsigned long paddr = 0;
+	struct file *file = NULL;
+	unsigned long len;
+	int i = 0, j = 0;
+
+	for (i = 0; i < meta_frame->frame.num_planes; i++) {
+		rc = get_pmem_file(meta_frame->frame.mp[i].fd,
+			&paddr, &kvstart, &len, &file);
+		if (rc < 0) {
+			pr_err("%s: get_pmem_file fd %d error %d\n",
+				__func__, meta_frame->frame.mp[i].fd, rc);
+			/* Roll back previous plane mappings, if any */
+			for (j = i-1; j >= 0; j--)
+				if (meta_frame->map[j].file)
+					put_pmem_file(meta_frame->map[j].file);
+
+			return -EACCES;
+		}
+		D("%s Got pmem file for fd %d plane %d as %p", __func__,
+			meta_frame->frame.mp[i].fd, i, file);
+		meta_frame->map[i].file = file;
+		/* Validate the offsets with the mapped length. */
+		if ((meta_frame->frame.mp[i].addr_offset > len) ||
+			(meta_frame->frame.mp[i].data_offset +
+			meta_frame->frame.mp[i].length > len)) {
+			pr_err("%s: Invalid offsets A %d D %d L %d len %ld",
+				__func__, meta_frame->frame.mp[i].addr_offset,
+				meta_frame->frame.mp[i].data_offset,
+				meta_frame->frame.mp[i].length, len);
+			/* Roll back previous plane mappings, if any */
+			for (j = i; j >= 0; j--)
+				if (meta_frame->map[j].file)
+					put_pmem_file(meta_frame->map[j].file);
+
+			return -EINVAL;
+		}
+		meta_frame->map[i].data_offset =
+			meta_frame->frame.mp[i].data_offset;
+		/* Add the addr_offset to the paddr here itself. The addr_offset
+		 * will be non-zero only if the user has allocated a buffer with
+		 * a single fd, but logically partitioned it into
+		 * multiple planes or buffers.*/
+		paddr += meta_frame->frame.mp[i].addr_offset;
+		meta_frame->map[i].paddr = paddr;
+		meta_frame->map[i].len = len;
+		D("%s Plane %d fd %d handle %p paddr %x", __func__,
+			i, meta_frame->frame.mp[i].fd,
+			meta_frame->map[i].handle,
+			(uint32_t)meta_frame->map[i].paddr);
+	}
+	D("%s Frame mapped successfully ", __func__);
+	return 0;
+}
+#endif
+
+int msm_mctl_map_user_frame(struct msm_cam_meta_frame *meta_frame,
+	struct ion_client *client, int domain_num)
+{
+
+	if ((NULL == meta_frame) || (NULL == client)) {
+		pr_err("%s Invalid input ", __func__);
+		return -EINVAL;
+	}
+
+	memset(&meta_frame->map[0], 0,
+		sizeof(struct msm_cam_buf_map_info) * VIDEO_MAX_PLANES);
+
+	return __msm_mctl_map_user_frame(meta_frame, client, domain_num);
+}
+
+int msm_mctl_unmap_user_frame(struct msm_cam_meta_frame *meta_frame,
+	struct ion_client *client, int domain_num)
+{
+	if ((NULL == meta_frame) || (NULL == client)) {
+		pr_err("%s Invalid input ", __func__);
+		return -EINVAL;
+	}
+	__msm_mctl_unmap_user_frame(meta_frame, client, domain_num);
+	return 0;
+}
diff --git a/drivers/media/platform/msm/camera_v1/msm_mctl_pp.c b/drivers/media/platform/msm/camera_v1/msm_mctl_pp.c
new file mode 100644
index 0000000..9267c9f
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/msm_mctl_pp.c
@@ -0,0 +1,738 @@
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/workqueue.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/ioctl.h>
+#include <linux/spinlock.h>
+#include <linux/videodev2.h>
+#include <linux/proc_fs.h>
+#include <linux/vmalloc.h>
+
+#include <media/v4l2-dev.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
+
+#include <linux/android_pmem.h>
+
+#include "msm.h"
+#include "msm_vpe.h"
+
+#ifdef CONFIG_MSM_CAMERA_DEBUG
+#define D(fmt, args...) pr_debug("msm_mctl: " fmt, ##args)
+#else
+#define D(fmt, args...) do {} while (0)
+#endif
+
+static int msm_mctl_pp_buf_divert(
+			struct msm_cam_media_controller *pmctl,
+			struct msm_cam_v4l2_dev_inst *pcam_inst,
+			struct msm_cam_evt_divert_frame *div)
+{
+	struct v4l2_event v4l2_evt;
+	struct msm_isp_event_ctrl *isp_event;
+	isp_event = kzalloc(sizeof(struct msm_isp_event_ctrl),
+						GFP_ATOMIC);
+	if (!isp_event) {
+		pr_err("%s Insufficient memory. return", __func__);
+		return -ENOMEM;
+	}
+	D("%s: msm_cam_evt_divert_frame=%d",
+		__func__, sizeof(struct msm_cam_evt_divert_frame));
+	memset(&v4l2_evt, 0, sizeof(v4l2_evt));
+	v4l2_evt.id = 0;
+	v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
+			MSM_CAM_RESP_DIV_FRAME_EVT_MSG;
+	*((uint32_t *)v4l2_evt.u.data) = (uint32_t)isp_event;
+	/* Copy the divert frame struct into event ctrl struct. */
+	isp_event->isp_data.div_frame = *div;
+
+	D("%s inst=%p, img_mode=%d, frame_id=%d\n", __func__,
+		pcam_inst, pcam_inst->image_mode, div->frame.frame_id);
+	v4l2_event_queue(
+		pmctl->config_device->config_stat_event_queue.pvdev,
+		&v4l2_evt);
+	return 0;
+}
+
+int msm_mctl_check_pp(struct msm_cam_media_controller *p_mctl,
+	int image_mode, int *pp_divert_type, int *pp_type)
+{
+	int rc = 0;
+	unsigned long flags;
+	uint32_t pp_key = 0;
+
+	*pp_type = 0;
+	*pp_divert_type = 0;
+	spin_lock_irqsave(&p_mctl->pp_info.lock, flags);
+	switch (image_mode) {
+	case MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW:
+		pp_key = PP_PREV;
+		if (p_mctl->pp_info.pp_key & pp_key)
+			*pp_divert_type = OUTPUT_TYPE_P;
+		if (p_mctl->pp_info.pp_ctrl.pp_msg_type & OUTPUT_TYPE_P)
+			*pp_type = OUTPUT_TYPE_P;
+		break;
+	case MSM_V4L2_EXT_CAPTURE_MODE_MAIN:
+		pp_key = PP_SNAP;
+		if (p_mctl->pp_info.pp_key & pp_key)
+			*pp_divert_type = OUTPUT_TYPE_S;
+		if (p_mctl->pp_info.pp_ctrl.pp_msg_type & OUTPUT_TYPE_S)
+			*pp_type = OUTPUT_TYPE_P;
+		break;
+	case MSM_V4L2_EXT_CAPTURE_MODE_VIDEO:
+		if (p_mctl->pp_info.pp_ctrl.pp_msg_type == OUTPUT_TYPE_V)
+			*pp_type = OUTPUT_TYPE_V;
+		break;
+	case MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL:
+		pp_key = PP_THUMB;
+		if (p_mctl->pp_info.pp_key & pp_key)
+			*pp_divert_type = OUTPUT_TYPE_T;
+		if (p_mctl->pp_info.pp_ctrl.pp_msg_type == OUTPUT_TYPE_T)
+			*pp_type = OUTPUT_TYPE_T;
+		break;
+	case MSM_V4L2_EXT_CAPTURE_MODE_RDI:
+		if (p_mctl->pp_info.pp_ctrl.pp_msg_type & OUTPUT_TYPE_R)
+			*pp_type = OUTPUT_TYPE_R;
+		break;
+	default:
+		break;
+	}
+	if (p_mctl->vfe_output_mode != VFE_OUTPUTS_MAIN_AND_THUMB &&
+		p_mctl->vfe_output_mode != VFE_OUTPUTS_THUMB_AND_MAIN) {
+		if (p_mctl->pp_info.div_frame[image_mode].ch_paddr[0])
+			*pp_divert_type = 0;
+	}
+	spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
+	D("%s: pp_type=%d, pp_divert_type = %d",
+	__func__, *pp_type, *pp_divert_type);
+	return rc;
+}
+
+static int is_buf_in_queue(struct msm_cam_v4l2_device *pcam,
+	struct msm_free_buf *fbuf, int image_mode)
+{
+	struct msm_frame_buffer *buf = NULL, *tmp;
+	struct msm_cam_v4l2_dev_inst *pcam_inst = NULL;
+	unsigned long flags = 0;
+	struct videobuf2_contig_pmem *mem;
+	uint32_t buf_idx, offset = 0;
+	uint32_t buf_phyaddr = 0;
+	int idx;
+	idx = pcam->mctl_node.dev_inst_map[image_mode]->my_index;
+	pcam_inst = pcam->mctl_node.dev_inst[idx];
+	spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
+	list_for_each_entry_safe(buf, tmp,
+	&pcam_inst->free_vq, list) {
+		buf_idx = buf->vidbuf.v4l2_buf.index;
+		mem = vb2_plane_cookie(&buf->vidbuf, 0);
+		if (mem == NULL) {
+			pr_err("%s Inst %p Buffer %d invalid plane cookie",
+				__func__, pcam_inst, buf_idx);
+			spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
+			return 0;
+		}
+		if (mem->buffer_type ==	VIDEOBUF2_MULTIPLE_PLANES)
+			offset = mem->offset.data_offset +
+				pcam_inst->buf_offset[buf_idx][0].data_offset;
+		else
+			offset = mem->offset.sp_off.y_off;
+		buf_phyaddr = (unsigned long)
+			videobuf2_to_pmem_contig(&buf->vidbuf, 0) +
+			offset;
+		D("%s vb_idx=%d,vb_paddr=0x%x ch0=0x%x\n",
+		  __func__, buf->vidbuf.v4l2_buf.index,
+		  buf_phyaddr, fbuf->ch_paddr[0]);
+		if (fbuf->ch_paddr[0] == buf_phyaddr) {
+			spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
+			return 1;
+		}
+	}
+	spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
+	return 0;
+}
+
+static struct msm_cam_v4l2_dev_inst *msm_mctl_get_pcam_inst_for_divert(
+	struct msm_cam_media_controller *pmctl,
+	struct msm_cam_buf_handle *buf_handle,
+	struct msm_free_buf *fbuf, int *node_type)
+{
+	struct msm_cam_v4l2_dev_inst *pcam_inst = NULL;
+	struct msm_cam_v4l2_device *pcam = pmctl->pcam_ptr;
+	int idx;
+	uint32_t img_mode;
+
+	if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_INST_HANDLE) {
+		idx = GET_MCTLPP_INST_IDX(buf_handle->inst_handle);
+		if (idx > MSM_DEV_INST_MAX) {
+			idx = GET_VIDEO_INST_IDX(buf_handle->inst_handle);
+			BUG_ON(idx > MSM_DEV_INST_MAX);
+			pcam_inst = pcam->dev_inst[idx];
+			*node_type = VIDEO_NODE;
+		} else {
+			pcam_inst = pcam->mctl_node.dev_inst[idx];
+			*node_type = MCTL_NODE;
+		}
+	} else if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_IMG_MODE) {
+		img_mode = buf_handle->image_mode;
+		if (img_mode >= 0 && img_mode < MSM_V4L2_EXT_CAPTURE_MODE_MAX) {
+			/* Valid image mode. Search the mctl node first.
+			 * If mctl node doesnt have the instance, then
+			 * search in the user's video node */
+			if (pcam->mctl_node.dev_inst_map[img_mode]
+				&& is_buf_in_queue(pcam, fbuf, img_mode)) {
+				idx = pcam->mctl_node.
+					dev_inst_map[img_mode]->my_index;
+				pcam_inst = pcam->mctl_node.dev_inst[idx];
+				*node_type = MCTL_NODE;
+				D("%s Found instance %p in mctl node device\n",
+					__func__, pcam_inst);
+			} else if (pcam->dev_inst_map[img_mode]) {
+				idx = pcam->dev_inst_map[img_mode]->my_index;
+				pcam_inst = pcam->dev_inst[idx];
+				*node_type = VIDEO_NODE;
+				D("%s Found instance %p in video device",
+					__func__, pcam_inst);
+			} else {
+				pr_err("%s Cannot find instance for %d.\n",
+					__func__, img_mode);
+			}
+		} else {
+			pr_err("%s Invalid image mode %d. Return NULL\n",
+				__func__, buf_handle->image_mode);
+		}
+	} else {
+		pr_err("%s Invalid buffer lookup type ", __func__);
+	}
+	return pcam_inst;
+}
+
+int msm_mctl_do_pp_divert(
+	struct msm_cam_media_controller *p_mctl,
+	struct msm_cam_buf_handle *buf_handle,
+	struct msm_free_buf *fbuf,
+	uint32_t frame_id, int pp_type)
+{
+	struct msm_cam_v4l2_dev_inst *pcam_inst;
+	int rc = 0, i, buf_idx, node;
+	int del_buf = 0; /* delete from free queue */
+	struct msm_cam_evt_divert_frame div;
+	struct msm_frame_buffer *vb = NULL;
+	struct videobuf2_contig_pmem *mem;
+	uint32_t image_mode;
+
+	if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_IMG_MODE) {
+		image_mode = buf_handle->image_mode;
+		div.frame.inst_handle = 0;
+	} else if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_INST_HANDLE) {
+		image_mode = GET_IMG_MODE(buf_handle->inst_handle);
+		div.frame.inst_handle = buf_handle->inst_handle;
+	} else {
+		pr_err("%s Invalid buffer lookup type %d ", __func__,
+			buf_handle->buf_lookup_type);
+		return -EINVAL;
+	}
+
+	pcam_inst = msm_mctl_get_pcam_inst_for_divert(p_mctl,
+			buf_handle, fbuf, &node);
+	if (!pcam_inst) {
+		pr_err("%s Invalid instance. Cannot divert frame.\n",
+			__func__);
+		return -EINVAL;
+	}
+	vb = msm_mctl_buf_find(p_mctl, pcam_inst, del_buf, fbuf);
+	if (!vb)
+		return -EINVAL;
+
+	vb->vidbuf.v4l2_buf.sequence = frame_id;
+	buf_idx = vb->vidbuf.v4l2_buf.index;
+	D("%s Diverting frame %d %x Image mode %d\n", __func__, buf_idx,
+		(uint32_t)vb, pcam_inst->image_mode);
+	div.image_mode = pcam_inst->image_mode;
+	div.op_mode    = pcam_inst->pcam->op_mode;
+	div.inst_idx   = pcam_inst->my_index;
+	div.node_idx   = pcam_inst->pcam->vnode_id;
+	p_mctl->pp_info.cur_frame_id[pcam_inst->image_mode] = frame_id;
+	div.frame.frame_id =
+		p_mctl->pp_info.cur_frame_id[pcam_inst->image_mode];
+	div.frame.buf_idx  = buf_idx;
+	div.frame.handle = (uint32_t)vb;
+	msm_mctl_gettimeofday(&div.frame.timestamp);
+	vb->vidbuf.v4l2_buf.timestamp = div.frame.timestamp;
+	div.do_pp = pp_type;
+	D("%s Diverting frame %x id %d to userspace ", __func__,
+		(int)div.frame.handle, div.frame.frame_id);
+	/* Get the cookie for 1st plane and store the path.
+	 * Also use this to check the number of planes in
+	 * this buffer.*/
+	mem = vb2_plane_cookie(&vb->vidbuf, 0);
+	if (mem == NULL) {
+		pr_err("%s Inst %p Buffer %d, invalid plane cookie ", __func__,
+			pcam_inst, buf_idx);
+		return -EINVAL;
+	}
+	div.frame.path = mem->path;
+	div.frame.node_type = node;
+	if (mem->buffer_type == VIDEOBUF2_SINGLE_PLANE) {
+		/* This buffer contains only 1 plane. Use the
+		 * single planar structure to store the info.*/
+		div.frame.num_planes	= 1;
+		div.frame.sp.phy_addr	=
+			videobuf2_to_pmem_contig(&vb->vidbuf, 0);
+		div.frame.sp.addr_offset = mem->addr_offset;
+		div.frame.sp.y_off      = 0;
+		div.frame.sp.cbcr_off   = mem->offset.sp_off.cbcr_off;
+		div.frame.sp.fd         = (int)mem->vaddr;
+		div.frame.sp.length     = mem->size;
+		if (!pp_type)
+			p_mctl->pp_info.div_frame[pcam_inst->image_mode].
+			ch_paddr[0] = div.frame.sp.phy_addr;
+	} else {
+		/* This buffer contains multiple planes. Use the mutliplanar
+		 * structure to store the info. */
+		div.frame.num_planes	= pcam_inst->plane_info.num_planes;
+		/* Now traverse through all the planes of the buffer to
+		 * fill out the plane info. */
+		for (i = 0; i < div.frame.num_planes; i++) {
+			mem = vb2_plane_cookie(&vb->vidbuf, i);
+			if (mem == NULL) {
+				pr_err("%s Inst %p %d invalid plane cookie ",
+					__func__, pcam_inst, buf_idx);
+				return -EINVAL;
+			}
+			div.frame.mp[i].phy_addr =
+				videobuf2_to_pmem_contig(&vb->vidbuf, i);
+			if (!pcam_inst->buf_offset)
+				div.frame.mp[i].data_offset = 0;
+			else
+				div.frame.mp[i].data_offset =
+				pcam_inst->buf_offset[buf_idx][i].data_offset;
+			div.frame.mp[i].addr_offset =
+				mem->addr_offset;
+			div.frame.mp[i].fd = (int)mem->vaddr;
+			div.frame.mp[i].length = mem->size;
+		}
+		if (!pp_type)
+			p_mctl->pp_info.div_frame[pcam_inst->image_mode].
+			ch_paddr[0] = div.frame.mp[0].phy_addr +
+					div.frame.mp[0].data_offset;
+	}
+	rc = msm_mctl_pp_buf_divert(p_mctl, pcam_inst, &div);
+	return rc;
+}
+
+static int msm_mctl_pp_get_phy_addr(
+	struct msm_cam_v4l2_dev_inst *pcam_inst,
+	uint32_t frame_handle,
+	struct msm_pp_frame *pp_frame)
+{
+	struct msm_frame_buffer *vb = NULL;
+	struct videobuf2_contig_pmem *mem;
+	int i, buf_idx = 0;
+
+	vb = (struct msm_frame_buffer *)frame_handle;
+	buf_idx = vb->vidbuf.v4l2_buf.index;
+	memset(pp_frame, 0, sizeof(struct msm_pp_frame));
+	pp_frame->handle = (uint32_t)vb;
+	pp_frame->frame_id = vb->vidbuf.v4l2_buf.sequence;
+	pp_frame->timestamp = vb->vidbuf.v4l2_buf.timestamp;
+	pp_frame->buf_idx = buf_idx;
+	pp_frame->inst_handle = pcam_inst->inst_handle;
+	/* Get the cookie for 1st plane and store the path.
+	 * Also use this to check the number of planes in
+	 * this buffer.*/
+	mem = vb2_plane_cookie(&vb->vidbuf, 0);
+	if (mem == NULL) {
+		pr_err("%s Inst %p Buffer %d, invalid plane cookie ", __func__,
+			pcam_inst, buf_idx);
+		return -EINVAL;
+	}
+	pp_frame->image_type = (unsigned short)mem->path;
+	if (mem->buffer_type == VIDEOBUF2_SINGLE_PLANE) {
+		pp_frame->num_planes = 1;
+		pp_frame->sp.addr_offset = mem->addr_offset;
+		pp_frame->sp.phy_addr =
+			videobuf2_to_pmem_contig(&vb->vidbuf, 0);
+		pp_frame->sp.y_off = 0;
+		pp_frame->sp.cbcr_off = mem->offset.sp_off.cbcr_off;
+		pp_frame->sp.length = mem->size;
+		pp_frame->sp.fd = (int)mem->vaddr;
+	} else {
+		pp_frame->num_planes = pcam_inst->plane_info.num_planes;
+		for (i = 0; i < pp_frame->num_planes; i++) {
+			mem = vb2_plane_cookie(&vb->vidbuf, i);
+			pp_frame->mp[i].addr_offset = mem->addr_offset;
+			pp_frame->mp[i].phy_addr =
+				videobuf2_to_pmem_contig(&vb->vidbuf, i);
+			pp_frame->mp[i].data_offset =
+			pcam_inst->buf_offset[buf_idx][i].data_offset;
+			pp_frame->mp[i].fd = (int)mem->vaddr;
+			pp_frame->mp[i].length = mem->size;
+			D("%s frame id %d buffer %d plane %d phy addr 0x%x"
+				" fd %d length %d\n", __func__,
+				pp_frame->frame_id, buf_idx, i,
+				(uint32_t)pp_frame->mp[i].phy_addr,
+				pp_frame->mp[i].fd, pp_frame->mp[i].length);
+		}
+	}
+	return 0;
+}
+
+static int msm_mctl_pp_path_to_img_mode(int path)
+{
+	switch (path) {
+	case OUTPUT_TYPE_P:
+		return MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW;
+	case OUTPUT_TYPE_V:
+		return MSM_V4L2_EXT_CAPTURE_MODE_VIDEO;
+	case OUTPUT_TYPE_S:
+		return MSM_V4L2_EXT_CAPTURE_MODE_MAIN;
+	case OUTPUT_TYPE_T:
+		return MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL;
+	case OUTPUT_TYPE_SAEC:
+		return MSM_V4L2_EXT_CAPTURE_MODE_AEC;
+	case OUTPUT_TYPE_SAWB:
+		return MSM_V4L2_EXT_CAPTURE_MODE_AWB;
+	case OUTPUT_TYPE_SAFC:
+		return MSM_V4L2_EXT_CAPTURE_MODE_AF;
+	case OUTPUT_TYPE_IHST:
+		return MSM_V4L2_EXT_CAPTURE_MODE_IHIST;
+	case OUTPUT_TYPE_CSTA:
+		return MSM_V4L2_EXT_CAPTURE_MODE_CSTA;
+	default:
+		return -EINVAL;
+	}
+}
+
+int msm_mctl_pp_proc_cmd(struct msm_cam_media_controller *p_mctl,
+			struct msm_mctl_pp_cmd *pp_cmd)
+{
+	int rc = 0;
+	unsigned long flags;
+
+	switch (pp_cmd->id) {
+	case MCTL_CMD_DIVERT_FRAME_PP_PATH: {
+		struct msm_mctl_pp_divert_pp divert_pp;
+		if (copy_from_user(&divert_pp, pp_cmd->value,
+				sizeof(divert_pp))) {
+			ERR_COPY_FROM_USER();
+			return -EFAULT;
+		}
+		D("%s: Divert Image mode =%d Enable %d",
+			__func__, divert_pp.path, divert_pp.enable);
+		spin_lock_irqsave(&p_mctl->pp_info.lock, flags);
+		if (divert_pp.enable)
+			p_mctl->pp_info.pp_ctrl.pp_msg_type |= divert_pp.path;
+		else
+			p_mctl->pp_info.pp_ctrl.pp_msg_type &= ~divert_pp.path;
+		spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
+		D("%s: pp path = 0x%x", __func__,
+			p_mctl->pp_info.pp_ctrl.pp_msg_type);
+		break;
+	}
+	default:
+		rc = -EPERM;
+	break;
+	}
+	return rc;
+}
+
+
+int msm_mctl_pp_ioctl(struct msm_cam_media_controller *p_mctl,
+			unsigned int cmd, unsigned long arg)
+{
+	int rc = -EINVAL;
+	struct msm_mctl_post_proc_cmd pp_cmd;
+	void __user *argp = (void __user *)arg;
+
+	if (copy_from_user(&pp_cmd, argp, sizeof(pp_cmd)))
+		return -EFAULT;
+
+	switch (pp_cmd.type) {
+	case MSM_PP_CMD_TYPE_MCTL:
+		rc = msm_mctl_pp_proc_cmd(p_mctl, &pp_cmd.cmd);
+		break;
+	default:
+		rc = -EPERM;
+		break;
+	}
+	if (!rc) {
+		/* deep copy back the return value */
+		if (copy_to_user((void *)arg,
+			&pp_cmd,
+			sizeof(struct msm_mctl_post_proc_cmd))) {
+			ERR_COPY_TO_USER();
+			rc = -EFAULT;
+		}
+	}
+	return rc;
+}
+
+int msm_mctl_pp_reserve_free_frame(
+	struct msm_cam_media_controller *p_mctl,
+	void __user *arg)
+{
+	struct msm_cam_evt_divert_frame div_frame;
+	int image_mode, rc = 0;
+	struct msm_free_buf free_buf;
+	struct msm_cam_v4l2_dev_inst *pcam_inst;
+	struct msm_cam_buf_handle buf_handle;
+
+	memset(&free_buf, 0, sizeof(struct msm_free_buf));
+	if (copy_from_user(&div_frame, arg,
+		sizeof(struct msm_cam_evt_divert_frame))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	image_mode = div_frame.image_mode;
+	if (image_mode <= 0) {
+		pr_err("%s Invalid image mode %d", __func__, image_mode);
+		return -EINVAL;
+	}
+	/* Always reserve the buffer from user's video node */
+	pcam_inst = p_mctl->pcam_ptr->dev_inst_map[image_mode];
+	if (!pcam_inst) {
+		pr_err("%s Instance already closed ", __func__);
+		return -EINVAL;
+	}
+	D("%s Reserving free frame using %p inst handle %x ", __func__,
+		pcam_inst, div_frame.frame.inst_handle);
+	if (div_frame.frame.inst_handle) {
+		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_INST_HANDLE;
+		buf_handle.inst_handle = div_frame.frame.inst_handle;
+	} else {
+		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_IMG_MODE;
+		buf_handle.image_mode = image_mode;
+	}
+	rc = msm_mctl_reserve_free_buf(p_mctl, pcam_inst,
+					&buf_handle, &free_buf);
+	if (rc == 0) {
+		msm_mctl_pp_get_phy_addr(pcam_inst,
+			free_buf.vb, &div_frame.frame);
+		if (copy_to_user((void *)arg, &div_frame, sizeof(div_frame))) {
+			ERR_COPY_TO_USER();
+			rc = -EFAULT;
+		}
+	}
+	D("%s: Got buffer %d from Inst %p rc = %d, phy = 0x%x",
+		__func__, div_frame.frame.buf_idx,
+		pcam_inst, rc, free_buf.ch_paddr[0]);
+	return rc;
+}
+
+int msm_mctl_pp_release_free_frame(
+	struct msm_cam_media_controller *p_mctl,
+	void __user *arg)
+{
+	struct msm_cam_evt_divert_frame div_frame;
+	struct msm_cam_v4l2_dev_inst *pcam_inst;
+	struct msm_pp_frame *frame;
+	int image_mode, rc = 0;
+	struct msm_free_buf free_buf;
+	struct msm_cam_buf_handle buf_handle;
+
+	if (copy_from_user(&div_frame, arg,
+		sizeof(struct msm_cam_evt_divert_frame))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	image_mode = div_frame.image_mode;
+	if (image_mode < 0) {
+		pr_err("%s Invalid image mode %d\n", __func__, image_mode);
+		return -EINVAL;
+	}
+	frame = &div_frame.frame;
+	if (frame->num_planes > 1)
+		free_buf.ch_paddr[0] = frame->mp[0].phy_addr;
+	else
+		free_buf.ch_paddr[0] = frame->sp.phy_addr;
+
+	if (div_frame.frame.inst_handle) {
+		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_INST_HANDLE;
+		buf_handle.inst_handle = div_frame.frame.inst_handle;
+	} else {
+		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_IMG_MODE;
+		buf_handle.image_mode = image_mode;
+	}
+	pcam_inst = msm_mctl_get_pcam_inst(p_mctl, &buf_handle);
+	if (!pcam_inst) {
+		pr_err("%s Invalid instance. Cannot release frame.\n",
+			__func__);
+		return -EINVAL;
+	}
+
+	rc = msm_mctl_release_free_buf(p_mctl, pcam_inst, &free_buf);
+	D("%s: release free buf, rc = %d, phy = 0x%x",
+		__func__, rc, free_buf.ch_paddr[0]);
+
+	return rc;
+}
+
+int msm_mctl_set_pp_key(struct msm_cam_media_controller *p_mctl,
+				void __user *arg)
+{
+	int rc = 0;
+	unsigned long flags;
+	spin_lock_irqsave(&p_mctl->pp_info.lock, flags);
+	if (copy_from_user(&p_mctl->pp_info.pp_key,
+			arg, sizeof(p_mctl->pp_info.pp_key))) {
+		ERR_COPY_FROM_USER();
+		rc = -EFAULT;
+	} else {
+		D("%s: mctl=0x%p, pp_key_setting=0x%x",
+			__func__, p_mctl, p_mctl->pp_info.pp_key);
+	}
+	spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
+	return rc;
+}
+
+int msm_mctl_pp_done(
+	struct msm_cam_media_controller *p_mctl,
+	void __user *arg)
+{
+	struct msm_pp_frame frame;
+	int image_mode, rc = 0;
+	int dirty = 0;
+	struct msm_free_buf buf;
+	unsigned long flags;
+	struct msm_cam_buf_handle buf_handle;
+	struct msm_cam_return_frame_info ret_frame;
+
+	if (copy_from_user(&frame, arg, sizeof(frame))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	spin_lock_irqsave(&p_mctl->pp_info.lock, flags);
+	if (frame.inst_handle) {
+		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_INST_HANDLE;
+		buf_handle.inst_handle = frame.inst_handle;
+		image_mode = GET_IMG_MODE(frame.inst_handle);
+	} else {
+		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_IMG_MODE;
+		buf_handle.image_mode =
+			msm_mctl_pp_path_to_img_mode(frame.path);
+		image_mode = buf_handle.image_mode;
+	}
+	if (image_mode < 0) {
+		pr_err("%s Invalid image mode\n", __func__);
+		return image_mode;
+	}
+	D("%s Returning frame %x id %d to kernel ", __func__,
+		(int)frame.handle, frame.frame_id);
+	if (p_mctl->pp_info.div_frame[image_mode].ch_paddr[0]) {
+		memcpy(&buf,
+			&p_mctl->pp_info.div_frame[image_mode],
+			sizeof(buf));
+		memset(&p_mctl->pp_info.div_frame[image_mode],
+			0, sizeof(buf));
+		if (p_mctl->pp_info.cur_frame_id[image_mode] !=
+					frame.frame_id) {
+			/* dirty frame. should not pass to app */
+			dirty = 1;
+		}
+	} else {
+		if (frame.num_planes > 1)
+			buf.ch_paddr[0] = frame.mp[0].phy_addr +
+						frame.mp[0].data_offset;
+		else
+			buf.ch_paddr[0] = frame.sp.phy_addr + frame.sp.y_off;
+	}
+	spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
+
+	ret_frame.dirty = dirty;
+	ret_frame.node_type = 0;
+	ret_frame.timestamp = frame.timestamp;
+	ret_frame.frame_id   = frame.frame_id;
+	D("%s frame_id: %d buffer idx %d\n", __func__,
+		frame.frame_id, frame.buf_idx);
+	rc = msm_mctl_buf_done_pp(p_mctl, &buf_handle, &buf, &ret_frame);
+	return rc;
+}
+
+int msm_mctl_pp_divert_done(
+	struct msm_cam_media_controller *p_mctl,
+	void __user *arg)
+{
+	struct msm_pp_frame frame;
+	int rc = 0;
+	struct msm_free_buf buf;
+	unsigned long flags;
+	struct msm_cam_buf_handle buf_handle;
+	struct msm_cam_return_frame_info ret_frame;
+
+	D("%s enter\n", __func__);
+
+	if (copy_from_user(&frame, arg, sizeof(frame))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	spin_lock_irqsave(&p_mctl->pp_info.lock, flags);
+	if (frame.inst_handle) {
+		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_INST_HANDLE;
+		buf_handle.inst_handle = frame.inst_handle;
+	} else {
+		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_IMG_MODE;
+		buf_handle.image_mode = frame.image_type;
+	}
+
+	if (frame.num_planes > 1)
+		buf.ch_paddr[0] = frame.mp[0].phy_addr +
+					frame.mp[0].data_offset;
+	else
+		buf.ch_paddr[0] = frame.sp.phy_addr + frame.sp.y_off;
+
+	spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
+
+	ret_frame.dirty = 0;
+	ret_frame.node_type = frame.node_type;
+	ret_frame.timestamp = frame.timestamp;
+	ret_frame.frame_id  = frame.frame_id;
+	D("%s Frame done id: %d\n", __func__, frame.frame_id);
+	rc = msm_mctl_buf_done_pp(p_mctl, &buf_handle, &buf, &ret_frame);
+	return rc;
+}
+
+int msm_mctl_pp_mctl_divert_done(
+	struct msm_cam_media_controller *p_mctl,
+	void __user *arg)
+{
+	struct msm_cam_evt_divert_frame div_frame;
+	struct msm_frame_buffer *buf;
+	int image_mode, rc = 0;
+
+	if (copy_from_user(&div_frame, arg,
+			sizeof(struct msm_cam_evt_divert_frame))) {
+		pr_err("%s copy from user failed ", __func__);
+		return -EFAULT;
+	}
+
+	if (!div_frame.frame.handle) {
+		pr_err("%s Invalid buffer handle ", __func__);
+		return -EINVAL;
+	}
+	image_mode = div_frame.image_mode;
+	buf = (struct msm_frame_buffer *)div_frame.frame.handle;
+	D("%s Returning buffer %x Image mode %d ", __func__,
+		(int)buf, image_mode);
+	rc = msm_mctl_buf_return_buf(p_mctl, image_mode, buf);
+	if (rc < 0)
+		pr_err("%s Error returning mctl buffer ", __func__);
+
+	return rc;
+}
diff --git a/drivers/media/platform/msm/camera_v1/msm_mem.c b/drivers/media/platform/msm/camera_v1/msm_mem.c
new file mode 100644
index 0000000..8144415
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/msm_mem.c
@@ -0,0 +1,427 @@
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/workqueue.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/ioctl.h>
+#include <linux/spinlock.h>
+#include <linux/videodev2.h>
+#include <linux/proc_fs.h>
+#include <linux/vmalloc.h>
+
+#include <media/v4l2-dev.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
+
+#include <linux/android_pmem.h>
+
+#include "msm.h"
+
+#ifdef CONFIG_MSM_CAMERA_DEBUG
+#define D(fmt, args...) pr_debug("msm_isp: " fmt, ##args)
+#else
+#define D(fmt, args...) do {} while (0)
+#endif
+
+#define PAD_TO_WORD(a)	  (((a) + 3) & ~3)
+
+#define __CONTAINS(r, v, l, field) ({			   \
+	typeof(r) __r = r;				  \
+	typeof(v) __v = v;				  \
+	typeof(v) __e = __v + l;				\
+	int res = __v >= __r->field &&			  \
+		__e <= __r->field + __r->len;		   \
+	res;							\
+})
+
+#define CONTAINS(r1, r2, field) ({			  \
+	typeof(r2) __r2 = r2;				   \
+	__CONTAINS(r1, __r2->field, __r2->len, field);	  \
+})
+
+#define IN_RANGE(r, v, field) ({				\
+	typeof(r) __r = r;				  \
+	typeof(v) __vv = v;				 \
+	int res = ((__vv >= __r->field) &&		  \
+		(__vv < (__r->field + __r->len)));	  \
+	res;							\
+})
+
+#define OVERLAPS(r1, r2, field) ({			  \
+	typeof(r1) __r1 = r1;				   \
+	typeof(r2) __r2 = r2;				   \
+	typeof(__r2->field) __v = __r2->field;		  \
+	typeof(__v) __e = __v + __r2->len - 1;		  \
+	int res = (IN_RANGE(__r1, __v, field) ||		\
+		IN_RANGE(__r1, __e, field));				 \
+	res;							\
+})
+
+static DEFINE_MUTEX(hlist_mut);
+
+#ifdef CONFIG_ANDROID_PMEM
+static int check_pmem_info(struct msm_pmem_info *info, int len)
+{
+	if (info->offset < len &&
+		info->offset + info->len <= len &&
+		info->planar0_off < len &&
+		info->planar1_off < len)
+		return 0;
+
+	pr_err("%s: check failed: off %d len %d y %d cbcr %d (total len %d)\n",
+						__func__,
+						info->offset,
+						info->len,
+						info->planar0_off,
+						info->planar1_off,
+						len);
+	return -EINVAL;
+}
+#endif
+
+static int check_overlap(struct hlist_head *ptype,
+				unsigned long paddr,
+				unsigned long len)
+{
+	struct msm_pmem_region *region;
+	struct msm_pmem_region t = { .paddr = paddr, .len = len };
+	struct hlist_node *node;
+
+	hlist_for_each_entry(region, node, ptype, list) {
+		if (CONTAINS(region, &t, paddr) ||
+			CONTAINS(&t, region, paddr) ||
+			OVERLAPS(region, &t, paddr)) {
+			CDBG(" region (PHYS %p len %ld)"
+				" clashes with registered region"
+				" (paddr %p len %ld)\n",
+				(void *)t.paddr, t.len,
+				(void *)region->paddr, region->len);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static int msm_pmem_table_add(struct hlist_head *ptype,
+	struct msm_pmem_info *info, struct ion_client *client, int domain_num)
+{
+	unsigned long paddr;
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
+	unsigned long kvstart;
+	struct file *file;
+#endif
+	int rc = -ENOMEM;
+
+	unsigned long len;
+	struct msm_pmem_region *region;
+
+	region = kmalloc(sizeof(struct msm_pmem_region), GFP_KERNEL);
+	if (!region)
+		goto out;
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	region->handle = ion_import_dma_buf(client, info->fd);
+	if (IS_ERR_OR_NULL(region->handle))
+		goto out1;
+	if (ion_map_iommu(client, region->handle, domain_num, 0,
+				  SZ_4K, 0, &paddr, &len, 0, 0) < 0)
+		goto out2;
+#elif CONFIG_ANDROID_PMEM
+	rc = get_pmem_file(info->fd, &paddr, &kvstart, &len, &file);
+	if (rc < 0) {
+		pr_err("%s: get_pmem_file fd %d error %d\n",
+				__func__, info->fd, rc);
+		goto out1;
+	}
+	region->file = file;
+#else
+	paddr = 0;
+	file = NULL;
+	kvstart = 0;
+#endif
+	if (!info->len)
+		info->len = len;
+	rc = check_pmem_info(info, len);
+	if (rc < 0)
+		goto out3;
+	paddr += info->offset;
+	len = info->len;
+
+	if (check_overlap(ptype, paddr, len) < 0) {
+		rc = -EINVAL;
+		goto out3;
+	}
+
+	CDBG("%s: type %d, active flag %d, paddr 0x%lx, vaddr 0x%lx\n",
+		__func__, info->type, info->active, paddr,
+		(unsigned long)info->vaddr);
+
+	INIT_HLIST_NODE(&region->list);
+	region->paddr = paddr;
+	region->len = len;
+	memcpy(&region->info, info, sizeof(region->info));
+	D("%s Adding region to list with type %d\n", __func__,
+						region->info.type);
+	D("%s pmem_stats address is 0x%p\n", __func__, ptype);
+	hlist_add_head(&(region->list), ptype);
+
+	return 0;
+out3:
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	ion_unmap_iommu(client, region->handle, domain_num, 0);
+#endif
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+out2:
+	ion_free(client, region->handle);
+#elif CONFIG_ANDROID_PMEM
+	put_pmem_file(region->file);
+#endif
+out1:
+	kfree(region);
+out:
+	return rc;
+}
+
+static int __msm_register_pmem(struct hlist_head *ptype,
+			struct msm_pmem_info *pinfo, struct ion_client *client,
+			int domain_num)
+{
+	int rc = 0;
+
+	switch (pinfo->type) {
+	case MSM_PMEM_AF:
+	case MSM_PMEM_AEC:
+	case MSM_PMEM_AWB:
+	case MSM_PMEM_RS:
+	case MSM_PMEM_CS:
+	case MSM_PMEM_IHIST:
+	case MSM_PMEM_SKIN:
+	case MSM_PMEM_AEC_AWB:
+	case MSM_PMEM_BAYER_GRID:
+	case MSM_PMEM_BAYER_EXPOSURE:
+	case MSM_PMEM_BAYER_FOCUS:
+	case MSM_PMEM_BAYER_HIST:
+		rc = msm_pmem_table_add(ptype, pinfo, client, domain_num);
+		break;
+
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
+static int __msm_pmem_table_del(struct hlist_head *ptype,
+			struct msm_pmem_info *pinfo, struct ion_client *client,
+			int domain_num)
+{
+	int rc = 0;
+	struct msm_pmem_region *region;
+	struct hlist_node *node, *n;
+
+	switch (pinfo->type) {
+	case MSM_PMEM_AF:
+	case MSM_PMEM_AEC:
+	case MSM_PMEM_AWB:
+	case MSM_PMEM_RS:
+	case MSM_PMEM_CS:
+	case MSM_PMEM_IHIST:
+	case MSM_PMEM_SKIN:
+	case MSM_PMEM_AEC_AWB:
+	case MSM_PMEM_BAYER_GRID:
+	case MSM_PMEM_BAYER_EXPOSURE:
+	case MSM_PMEM_BAYER_FOCUS:
+	case MSM_PMEM_BAYER_HIST:
+		hlist_for_each_entry_safe(region, node, n,
+				ptype, list) {
+
+			if (pinfo->type == region->info.type &&
+				pinfo->vaddr == region->info.vaddr &&
+				pinfo->fd == region->info.fd) {
+				hlist_del(node);
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+				ion_unmap_iommu(client, region->handle,
+					domain_num, 0);
+				ion_free(client, region->handle);
+#else
+				put_pmem_file(region->file);
+#endif
+				kfree(region);
+			}
+		}
+		break;
+
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
+/* return of 0 means failure */
+uint8_t msm_pmem_region_lookup(struct hlist_head *ptype,
+	int pmem_type, struct msm_pmem_region *reg, uint8_t maxcount)
+{
+	struct msm_pmem_region *region;
+	struct msm_pmem_region *regptr;
+	struct hlist_node *node, *n;
+
+	uint8_t rc = 0;
+	D("%s\n", __func__);
+	regptr = reg;
+	mutex_lock(&hlist_mut);
+	hlist_for_each_entry_safe(region, node, n, ptype, list) {
+		if (region->info.type == pmem_type && region->info.active) {
+			*regptr = *region;
+			rc += 1;
+			if (rc >= maxcount)
+				break;
+			regptr++;
+		}
+	}
+	D("%s finished, rc=%d\n", __func__, rc);
+	mutex_unlock(&hlist_mut);
+	return rc;
+}
+
+int msm_pmem_region_get_phy_addr(struct hlist_head *ptype,
+	struct msm_mem_map_info *mem_map, int32_t *phyaddr)
+{
+	struct msm_pmem_region *region;
+	struct hlist_node *node, *n;
+	int pmem_type = mem_map->mem_type;
+	int rc = -EFAULT;
+
+	D("%s\n", __func__);
+	*phyaddr = 0;
+	mutex_lock(&hlist_mut);
+	hlist_for_each_entry_safe(region, node, n, ptype, list) {
+		if (region->info.type == pmem_type &&
+			(uint32_t)region->info.vaddr == mem_map->cookie) {
+			*phyaddr = (int32_t)region->paddr;
+			rc = 0;
+			break;
+		}
+	}
+	D("%s finished, phy_addr = 0x%x, rc=%d\n", __func__, *phyaddr, rc);
+	mutex_unlock(&hlist_mut);
+	return rc;
+}
+
+uint8_t msm_pmem_region_lookup_2(struct hlist_head *ptype,
+					int pmem_type,
+					struct msm_pmem_region *reg,
+					uint8_t maxcount)
+{
+	struct msm_pmem_region *region;
+	struct msm_pmem_region *regptr;
+	struct hlist_node *node, *n;
+	uint8_t rc = 0;
+	regptr = reg;
+	mutex_lock(&hlist_mut);
+	hlist_for_each_entry_safe(region, node, n, ptype, list) {
+		D("Mio: info.type=%d, pmem_type = %d,"
+						"info.active = %d\n",
+		region->info.type, pmem_type, region->info.active);
+
+		if (region->info.type == pmem_type && region->info.active) {
+			D("info.type=%d, pmem_type = %d,"
+							"info.active = %d,\n",
+				region->info.type, pmem_type,
+				region->info.active);
+			*regptr = *region;
+			region->info.type = MSM_PMEM_VIDEO;
+			rc += 1;
+			if (rc >= maxcount)
+				break;
+			regptr++;
+		}
+	}
+	mutex_unlock(&hlist_mut);
+	return rc;
+}
+
+unsigned long msm_pmem_stats_vtop_lookup(
+				struct msm_cam_media_controller *mctl,
+				unsigned long buffer,
+				int fd)
+{
+	struct msm_pmem_region *region;
+	struct hlist_node *node, *n;
+
+	hlist_for_each_entry_safe(region, node, n,
+	&mctl->stats_info.pmem_stats_list, list) {
+		if (((unsigned long)(region->info.vaddr) == buffer) &&
+						(region->info.fd == fd) &&
+						region->info.active == 0) {
+			region->info.active = 1;
+			return region->paddr;
+		}
+	}
+
+	return 0;
+}
+
+unsigned long msm_pmem_stats_ptov_lookup(
+		struct msm_cam_media_controller *mctl,
+		unsigned long addr, int *fd)
+{
+	struct msm_pmem_region *region;
+	struct hlist_node *node, *n;
+
+	hlist_for_each_entry_safe(region, node, n,
+	&mctl->stats_info.pmem_stats_list, list) {
+		if (addr == region->paddr && region->info.active) {
+			/* offset since we could pass vaddr inside a
+			 * registered pmem buffer */
+			*fd = region->info.fd;
+			region->info.active = 0;
+			return (unsigned long)(region->info.vaddr);
+		}
+	}
+
+	return 0;
+}
+
+int msm_register_pmem(struct hlist_head *ptype, void __user *arg,
+					struct ion_client *client,
+					int domain_num)
+{
+	struct msm_pmem_info info;
+
+	if (copy_from_user(&info, arg, sizeof(info))) {
+		ERR_COPY_FROM_USER();
+			return -EFAULT;
+	}
+
+	return __msm_register_pmem(ptype, &info, client, domain_num);
+}
+//EXPORT_SYMBOL(msm_register_pmem);
+
+int msm_pmem_table_del(struct hlist_head *ptype, void __user *arg,
+			struct ion_client *client, int domain_num)
+{
+	struct msm_pmem_info info;
+
+	if (copy_from_user(&info, arg, sizeof(info))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	return __msm_pmem_table_del(ptype, &info, client, domain_num);
+}
+//EXPORT_SYMBOL(msm_pmem_table_del);
diff --git a/drivers/media/platform/msm/camera_v1/msm_v4l2_video.c b/drivers/media/platform/msm/camera_v1/msm_v4l2_video.c
new file mode 100644
index 0000000..96f968c
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/msm_v4l2_video.c
@@ -0,0 +1,957 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/fb.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/time.h>
+#include <linux/videodev2.h>
+#include <linux/platform_device.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/msm_mdp.h>
+#include <linux/sched.h>
+#include <linux/capability.h>
+
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf-dma-sg.h>
+#include <media/v4l2-dev.h>
+#include <media/msm_v4l2_overlay.h>
+
+#include <mach/board.h>
+#include <mach/msm_fb.h>
+
+#include "msm_v4l2_video.h"
+
+#define MSM_VIDEO -1
+
+static struct msm_v4l2_overlay_device	*saved_vout0;
+
+static struct mutex msmfb_lock;
+static char *v4l2_ram_phys;
+static unsigned int v4l2_ram_size;
+
+static int msm_v4l2_overlay_mapformat(uint32_t pixelformat);
+
+static int msm_v4l2_overlay_startstreaming(struct msm_v4l2_overlay_device *vout)
+{
+	vout->req.src.width = vout->pix.width;
+	vout->req.src.height = vout->pix.height;
+
+	vout->req.src_rect.x = vout->crop_rect.left;
+	vout->req.src_rect.y = vout->crop_rect.top;
+	vout->req.src_rect.w = vout->crop_rect.width;
+	vout->req.src_rect.h = vout->crop_rect.height;
+
+	vout->req.src.format =
+		msm_v4l2_overlay_mapformat(vout->pix.pixelformat);
+
+	vout->req.dst_rect.x = vout->win.w.left;
+	vout->req.dst_rect.y = vout->win.w.top;
+	vout->req.dst_rect.w = vout->win.w.width;
+	vout->req.dst_rect.h = vout->win.w.height;
+
+	vout->req.alpha = MDP_ALPHA_NOP;
+	vout->req.transp_mask = MDP_TRANSP_NOP;
+
+	pr_debug("msm_v4l2_overlay:startstreaming:enabling fb\n");
+	mutex_lock(&msmfb_lock);
+	msm_fb_v4l2_enable(&vout->req, true, &vout->par);
+	mutex_unlock(&msmfb_lock);
+
+	vout->streaming = 1;
+
+	return 0;
+}
+
+static int msm_v4l2_overlay_stopstreaming(struct msm_v4l2_overlay_device *vout)
+{
+	if (!vout->streaming)
+		return 0;
+
+	pr_debug("msm_v4l2_overlay:startstreaming:disabling fb\n");
+	mutex_lock(&msmfb_lock);
+	msm_fb_v4l2_enable(&vout->req, false, &vout->par);
+	mutex_unlock(&msmfb_lock);
+
+	vout->streaming = 0;
+
+	return 0;
+}
+
+static int msm_v4l2_overlay_mapformat(uint32_t pixelformat)
+{
+	int mdp_format;
+
+	switch (pixelformat) {
+	case V4L2_PIX_FMT_RGB565:
+		mdp_format = MDP_RGB_565;
+		break;
+	case V4L2_PIX_FMT_RGB32:
+		mdp_format = MDP_ARGB_8888;
+		break;
+	case V4L2_PIX_FMT_RGB24:
+		mdp_format = MDP_RGB_888;
+		break;
+	case V4L2_PIX_FMT_NV12:
+		mdp_format = MDP_Y_CRCB_H2V2;
+		break;
+	case V4L2_PIX_FMT_NV21:
+		mdp_format = MDP_Y_CBCR_H2V2;
+		break;
+	case V4L2_PIX_FMT_YUV420:
+		mdp_format = MDP_Y_CR_CB_H2V2;
+		break;
+	default:
+		pr_err("%s:Unrecognized format %u\n", __func__, pixelformat);
+		mdp_format = MDP_Y_CBCR_H2V2;
+		break;
+	}
+
+	return mdp_format;
+}
+
+static int
+msm_v4l2_overlay_fb_update(struct msm_v4l2_overlay_device *vout,
+	struct v4l2_buffer *buffer)
+{
+	int ret;
+	unsigned long src_addr, src_size;
+	struct msm_v4l2_overlay_userptr_buffer up_buffer;
+
+	if (!buffer ||
+		(buffer->memory == V4L2_MEMORY_MMAP &&
+		 buffer->index >= vout->numbufs))
+		return -EINVAL;
+
+	mutex_lock(&msmfb_lock);
+	switch (buffer->memory) {
+	case V4L2_MEMORY_MMAP:
+		src_addr = (unsigned long)v4l2_ram_phys
+		+ vout->bufs[buffer->index].offset;
+		src_size = buffer->bytesused;
+		ret = msm_fb_v4l2_update(vout->par, false, src_addr, src_size,
+		0, 0, 0, 0);
+		break;
+	case V4L2_MEMORY_USERPTR:
+		if (copy_from_user(&up_buffer,
+		(void __user *)buffer->m.userptr,
+		sizeof(struct msm_v4l2_overlay_userptr_buffer))) {
+			pr_err("%s:copy_from_user for userptr failed\n",
+				__func__);
+			mutex_unlock(&msmfb_lock);
+			return -EINVAL;
+		}
+		ret = msm_fb_v4l2_update(vout->par, true,
+		(unsigned long)up_buffer.fd[0], up_buffer.offset[0],
+		(unsigned long)up_buffer.fd[1], up_buffer.offset[1],
+		(unsigned long)up_buffer.fd[2], up_buffer.offset[2]);
+		break;
+	default:
+		mutex_unlock(&msmfb_lock);
+		return -EINVAL;
+	}
+	mutex_unlock(&msmfb_lock);
+
+	if (buffer->memory == V4L2_MEMORY_MMAP) {
+		vout->bufs[buffer->index].queued = 1;
+		buffer->flags |= V4L2_BUF_FLAG_MAPPED;
+	}
+	buffer->flags |= V4L2_BUF_FLAG_QUEUED;
+
+	return ret;
+}
+
+static int
+msm_v4l2_overlay_vidioc_dqbuf(struct file *file,
+	struct msm_v4l2_overlay_fh *fh, void *arg)
+{
+	struct msm_v4l2_overlay_device *vout = fh->vout;
+	struct v4l2_buffer *buffer = arg;
+	int i;
+
+	if (!vout->streaming) {
+		pr_err("%s: Video Stream not enabled\n", __func__);
+		return -EINVAL;
+	}
+
+	if (!buffer || buffer->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+		return -EINVAL;
+
+	if (buffer->memory == V4L2_MEMORY_MMAP) {
+		for (i = 0; i < vout->numbufs; i++) {
+			if (vout->bufs[i].queued == 1)  {
+				vout->bufs[i].queued = 0;
+				/* Call into fb to remove this buffer? */
+				break;
+			}
+		}
+
+		/*
+		 * This should actually block, unless O_NONBLOCK was
+		 *  specified in open, but fine for now, especially
+		 *  since this is not a capturing device
+		 */
+		if (i == vout->numbufs)
+			return -EAGAIN;
+	}
+
+	buffer->flags &= ~V4L2_BUF_FLAG_QUEUED;
+
+	return 0;
+}
+
+
+static int
+msm_v4l2_overlay_vidioc_qbuf(struct file *file, struct msm_v4l2_overlay_fh* fh,
+	void *arg, bool bUserPtr)
+{
+	struct msm_v4l2_overlay_device *vout = fh->vout;
+	struct v4l2_buffer *buffer = arg;
+	int ret;
+
+	if (!bUserPtr && buffer->memory != V4L2_MEMORY_MMAP)
+		return -EINVAL;
+
+	if (!vout->streaming) {
+		pr_err("%s: Video Stream not enabled\n", __func__);
+		return -EINVAL;
+	}
+
+	if (!buffer || buffer->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+		return -EINVAL;
+
+	/* maybe allow only one qbuf at a time? */
+	ret =  msm_v4l2_overlay_fb_update(vout, buffer);
+
+	return 0;
+}
+
+static int
+msm_v4l2_overlay_vidioc_querycap(struct file *file, void *arg)
+{
+	struct v4l2_capability *buffer = arg;
+
+	memset(buffer, 0, sizeof(struct v4l2_capability));
+	strlcpy(buffer->driver, "msm_v4l2_video_overlay",
+		ARRAY_SIZE(buffer->driver));
+	strlcpy(buffer->card, "MSM MDP",
+		ARRAY_SIZE(buffer->card));
+	buffer->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT
+		| V4L2_CAP_VIDEO_OVERLAY;
+	return 0;
+}
+
+static int
+msm_v4l2_overlay_vidioc_fbuf(struct file *file,
+	struct msm_v4l2_overlay_device *vout, void *arg, bool get)
+{
+	struct v4l2_framebuffer *fb = arg;
+
+	if (fb == NULL)
+		return -EINVAL;
+
+	if (get) {
+		mutex_lock(&vout->update_lock);
+		memcpy(&fb->fmt, &vout->pix, sizeof(struct v4l2_pix_format));
+		mutex_unlock(&vout->update_lock);
+	}
+	/* The S_FBUF request does not store anything right now */
+	return 0;
+}
+
+static long msm_v4l2_overlay_calculate_bufsize(struct v4l2_pix_format *pix)
+{
+	int bpp;
+	long bufsize;
+	switch (pix->pixelformat) {
+	case V4L2_PIX_FMT_YUV420:
+	case V4L2_PIX_FMT_NV12:
+		bpp = 12;
+		break;
+
+	case V4L2_PIX_FMT_RGB565:
+		bpp = 16;
+		break;
+
+	case V4L2_PIX_FMT_RGB24:
+	case V4L2_PIX_FMT_BGR24:
+	case V4L2_PIX_FMT_YUV444:
+		bpp = 24;
+		break;
+
+	case V4L2_PIX_FMT_RGB32:
+	case V4L2_PIX_FMT_BGR32:
+		bpp = 32;
+		break;
+	default:
+		pr_err("%s: Unrecognized format %u\n", __func__,
+		pix->pixelformat);
+		bpp = 0;
+	}
+
+	bufsize = (pix->width * pix->height * bpp)/8;
+
+	return bufsize;
+}
+
+static long
+msm_v4l2_overlay_vidioc_reqbufs(struct file *file,
+	struct msm_v4l2_overlay_device *vout, void *arg)
+
+{
+	struct v4l2_requestbuffers *rqb = arg;
+	long bufsize;
+	int i;
+
+	if (rqb == NULL || rqb->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+		return -EINVAL;
+
+	if (rqb->memory == V4L2_MEMORY_MMAP) {
+		if (rqb->count == 0) {
+			/* Deallocate allocated buffers */
+			mutex_lock(&vout->update_lock);
+			vout->numbufs = 0;
+			kfree(vout->bufs);
+			/*
+			 * There should be a way to look at bufs[i]->mapped,
+			 * and prevent userspace from mmaping and directly
+			 * calling this ioctl without unmapping. Maybe kernel
+			 * handles for us, but needs to be checked out
+			 */
+			mutex_unlock(&vout->update_lock);
+		} else {
+			/*
+			 * Keep it simple for now - need to deallocate
+			 * before reallocate
+			 */
+			if (vout->bufs)
+				return -EINVAL;
+
+			mutex_lock(&vout->update_lock);
+			bufsize =
+				msm_v4l2_overlay_calculate_bufsize(&vout->pix);
+			mutex_unlock(&vout->update_lock);
+
+			if (bufsize == 0
+				|| (bufsize * rqb->count) > v4l2_ram_size) {
+				pr_err("%s: Unsupported format or buffer size too large\n",
+				__func__);
+				pr_err("%s: bufsize %lu ram_size %u count %u\n",
+				__func__, bufsize, v4l2_ram_size, rqb->count);
+				return -EINVAL;
+			}
+
+			/*
+			 * We don't support multiple open of one vout,
+			 * but there are probably still some MT problems here,
+			 * (what if same fh is shared between two userspace
+			 * threads and they both call REQBUFS etc)
+			 */
+
+			mutex_lock(&vout->update_lock);
+			vout->numbufs = rqb->count;
+			vout->bufs =
+				kmalloc(rqb->count *
+					sizeof(struct msm_v4l2_overlay_buffer),
+					GFP_KERNEL);
+
+			for (i = 0; i < rqb->count; i++) {
+				struct msm_v4l2_overlay_buffer *b =
+				(struct msm_v4l2_overlay_buffer *)vout->bufs
+				+ i;
+				b->mapped = 0;
+				b->queued = 0;
+				b->offset = PAGE_ALIGN(bufsize*i);
+				b->bufsize = bufsize;
+			}
+
+			mutex_unlock(&vout->update_lock);
+
+		}
+	}
+
+	return 0;
+}
+
+static long
+msm_v4l2_overlay_vidioc_querybuf(struct file *file,
+				 struct msm_v4l2_overlay_device *vout,
+				 void *arg)
+{
+	struct v4l2_buffer *buf = arg;
+	struct msm_v4l2_overlay_buffer *mbuf;
+
+	if (buf == NULL || buf->type != V4L2_BUF_TYPE_VIDEO_OUTPUT
+			|| buf->memory == V4L2_MEMORY_USERPTR
+			|| buf->index >= vout->numbufs)
+		return -EINVAL;
+
+	mutex_lock(&vout->update_lock);
+
+	mbuf = (struct msm_v4l2_overlay_buffer *)vout->bufs + buf->index;
+	buf->flags = 0;
+	if (mbuf->mapped)
+		buf->flags |= V4L2_BUF_FLAG_MAPPED;
+	if (mbuf->queued)
+		buf->flags |= V4L2_BUF_FLAG_QUEUED;
+
+	buf->memory = V4L2_MEMORY_MMAP;
+	buf->length = mbuf->bufsize;
+	buf->m.offset = mbuf->offset;
+
+	mutex_unlock(&vout->update_lock);
+
+	return 0;
+}
+
+static long
+msm_v4l2_overlay_do_ioctl(struct file *file,
+		       unsigned int cmd, void *arg)
+{
+	struct msm_v4l2_overlay_fh *fh = file->private_data;
+	struct msm_v4l2_overlay_device *vout = fh->vout;
+	int ret;
+	struct v4l2_buffer *buffer = arg;
+
+	switch (cmd) {
+	case VIDIOC_QUERYCAP:
+		return msm_v4l2_overlay_vidioc_querycap(file, arg);
+
+	case VIDIOC_G_FBUF:
+		return msm_v4l2_overlay_vidioc_fbuf(file, vout, arg, true);
+
+	case VIDIOC_S_FBUF:
+		return msm_v4l2_overlay_vidioc_fbuf(file, vout, arg, false);
+
+	case VIDIOC_REQBUFS:
+		return msm_v4l2_overlay_vidioc_reqbufs(file, vout, arg);
+
+	case VIDIOC_QUERYBUF:
+		return msm_v4l2_overlay_vidioc_querybuf(file, vout, arg);
+
+	case VIDIOC_QBUF:
+		mutex_lock(&vout->update_lock);
+		if (buffer->memory == V4L2_MEMORY_USERPTR) {
+			if (!capable(CAP_SYS_RAWIO))
+				return -EPERM;
+			ret = msm_v4l2_overlay_vidioc_qbuf(file, fh, arg, true);
+		} else {
+			ret = msm_v4l2_overlay_vidioc_qbuf(file, fh, arg,
+						false);
+		}
+		mutex_unlock(&vout->update_lock);
+
+		return ret;
+
+	case VIDIOC_MSM_USERPTR_QBUF:
+		if (!capable(CAP_SYS_RAWIO))
+			return -EPERM;
+
+		mutex_lock(&vout->update_lock);
+		ret = msm_v4l2_overlay_vidioc_qbuf(file, fh, arg, true);
+		mutex_unlock(&vout->update_lock);
+
+		return ret;
+
+	case VIDIOC_DQBUF:
+		mutex_lock(&vout->update_lock);
+		ret = msm_v4l2_overlay_vidioc_dqbuf(file, fh, arg);
+		mutex_unlock(&vout->update_lock);
+		break;
+
+	case VIDIOC_S_FMT: {
+		struct v4l2_format *f = arg;
+
+		switch (f->type) {
+		case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+			mutex_lock(&vout->update_lock);
+			memcpy(&vout->win, &f->fmt.win,
+				sizeof(struct v4l2_window));
+			mutex_unlock(&vout->update_lock);
+			break;
+
+		case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+			mutex_lock(&vout->update_lock);
+			memcpy(&vout->pix, &f->fmt.pix,
+				sizeof(struct v4l2_pix_format));
+			mutex_unlock(&vout->update_lock);
+			break;
+
+		default:
+			return -EINVAL;
+		}
+		break;
+	}
+	case VIDIOC_G_FMT: {
+		struct v4l2_format *f = arg;
+
+		switch (f->type) {
+		case V4L2_BUF_TYPE_VIDEO_OUTPUT: {
+			struct v4l2_pix_format *pix = &f->fmt.pix;
+			memset(pix, 0, sizeof(*pix));
+			*pix = vout->pix;
+			break;
+		}
+
+		case V4L2_BUF_TYPE_VIDEO_OVERLAY: {
+			struct v4l2_window *win = &f->fmt.win;
+			memset(win, 0, sizeof(*win));
+			win->w = vout->win.w;
+			break;
+		}
+		default:
+			return -EINVAL;
+		}
+		break;
+	}
+
+	case VIDIOC_CROPCAP: {
+		struct v4l2_cropcap *cr = arg;
+		if (cr->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+			return -EINVAL;
+
+		cr->bounds.left =  0;
+		cr->bounds.top = 0;
+		cr->bounds.width = vout->crop_rect.width;
+		cr->bounds.height = vout->crop_rect.height;
+
+		cr->defrect.left =  0;
+		cr->defrect.top = 0;
+		cr->defrect.width = vout->crop_rect.width;
+		cr->defrect.height = vout->crop_rect.height;
+
+		cr->pixelaspect.numerator = 1;
+		cr->pixelaspect.denominator = 1;
+		break;
+	}
+
+	case VIDIOC_S_CROP: {
+		struct v4l2_crop *crop = arg;
+
+		switch (crop->type) {
+
+		case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+
+			mutex_lock(&vout->update_lock);
+			memcpy(&vout->crop_rect, &crop->c,
+				sizeof(struct v4l2_rect));
+			mutex_unlock(&vout->update_lock);
+
+			break;
+
+		default:
+
+			return -EINVAL;
+		}
+		break;
+	}
+	case VIDIOC_G_CROP: {
+		struct v4l2_crop *crop = arg;
+
+		switch (crop->type) {
+
+		case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+			memcpy(&crop->c, &vout->crop_rect,
+				sizeof(struct v4l2_rect));
+			break;
+
+		default:
+			return -EINVAL;
+		}
+		break;
+	}
+
+	case VIDIOC_S_CTRL: {
+		struct v4l2_control *ctrl = arg;
+		int32_t rotflag;
+
+		switch (ctrl->id) {
+
+		case V4L2_CID_ROTATE:
+			switch (ctrl->value) {
+			case 0:
+				rotflag = MDP_ROT_NOP;
+				break;
+			case 90:
+				rotflag = MDP_ROT_90;
+				break;
+			case 180:
+				rotflag = MDP_ROT_180;
+				break;
+			case 270:
+				rotflag = MDP_ROT_270;
+				break;
+			default:
+				pr_err("%s: V4L2_CID_ROTATE invalid rotation value %d.\n",
+						__func__, ctrl->value);
+				return -ERANGE;
+			}
+
+			mutex_lock(&vout->update_lock);
+			/* Clear the rotation flags */
+			vout->req.flags &= ~MDP_ROT_NOP;
+			vout->req.flags &= ~MDP_ROT_90;
+			vout->req.flags &= ~MDP_ROT_180;
+			vout->req.flags &= ~MDP_ROT_270;
+			/* Set the new rotation flag */
+			vout->req.flags |= rotflag;
+			mutex_unlock(&vout->update_lock);
+
+			break;
+
+		case V4L2_CID_HFLIP:
+			mutex_lock(&vout->update_lock);
+			/* Clear the flip flag */
+			vout->req.flags &= ~MDP_FLIP_LR;
+			if (true == ctrl->value)
+				vout->req.flags |= MDP_FLIP_LR;
+			mutex_unlock(&vout->update_lock);
+
+			break;
+
+		case V4L2_CID_VFLIP:
+			mutex_lock(&vout->update_lock);
+			/* Clear the flip flag */
+			vout->req.flags &= ~MDP_FLIP_UD;
+			if (true == ctrl->value)
+				vout->req.flags |= MDP_FLIP_UD;
+			mutex_unlock(&vout->update_lock);
+
+			break;
+
+		default:
+			pr_err("%s: VIDIOC_S_CTRL invalid control ID %d.\n",
+			__func__, ctrl->id);
+			return -EINVAL;
+		}
+		break;
+	}
+	case VIDIOC_G_CTRL: {
+		struct v4l2_control *ctrl = arg;
+		__s32 rotation;
+
+		switch (ctrl->id) {
+
+		case V4L2_CID_ROTATE:
+			if (MDP_ROT_NOP == (vout->req.flags & MDP_ROT_NOP))
+				rotation = 0;
+			if (MDP_ROT_90 == (vout->req.flags & MDP_ROT_90))
+				rotation = 90;
+			if (MDP_ROT_180 == (vout->req.flags & MDP_ROT_180))
+				rotation = 180;
+			if (MDP_ROT_270 == (vout->req.flags & MDP_ROT_270))
+				rotation = 270;
+
+			ctrl->value = rotation;
+			break;
+
+		case V4L2_CID_HFLIP:
+			if (MDP_FLIP_LR == (vout->req.flags & MDP_FLIP_LR))
+				ctrl->value = true;
+			break;
+
+		case V4L2_CID_VFLIP:
+			if (MDP_FLIP_UD == (vout->req.flags & MDP_FLIP_UD))
+				ctrl->value = true;
+			break;
+
+		default:
+			pr_err("%s: VIDIOC_G_CTRL invalid control ID %d.\n",
+			__func__, ctrl->id);
+			return -EINVAL;
+		}
+		break;
+	}
+
+	case VIDIOC_STREAMON: {
+
+		if (vout->streaming) {
+			pr_err("%s: VIDIOC_STREAMON: already streaming.\n",
+			__func__);
+			return -EBUSY;
+		}
+
+		mutex_lock(&vout->update_lock);
+		msm_v4l2_overlay_startstreaming(vout);
+		mutex_unlock(&vout->update_lock);
+
+		break;
+	}
+
+	case VIDIOC_STREAMOFF: {
+
+		if (!vout->streaming) {
+			pr_err("%s: VIDIOC_STREAMOFF: not currently streaming.\n",
+			__func__);
+			return -EINVAL;
+		}
+
+		mutex_lock(&vout->update_lock);
+		msm_v4l2_overlay_stopstreaming(vout);
+		mutex_unlock(&vout->update_lock);
+
+		break;
+	}
+
+	default:
+		return -ENOIOCTLCMD;
+
+	} /* switch */
+
+	return 0;
+}
+
+static long
+msm_v4l2_overlay_ioctl(struct file *file, unsigned int cmd,
+		    unsigned long arg)
+{
+	return video_usercopy(file, cmd, arg, msm_v4l2_overlay_do_ioctl);
+}
+
+static int
+msm_v4l2_overlay_mmap(struct file *filp, struct vm_area_struct * vma)
+{
+	unsigned long start = (unsigned long)v4l2_ram_phys;
+
+	/*
+	 * vm_pgoff is the offset (>>PAGE_SHIFT) that we provided
+	 * during REQBUFS. off therefore should equal the offset we
+	 * provided in REQBUFS, since last (PAGE_SHIFT) bits of off
+	 * should be 0
+	 */
+	unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
+	u32 len = PAGE_ALIGN((start & ~PAGE_MASK) + v4l2_ram_size);
+
+	/*
+	 * This is probably unnecessary now - the last PAGE_SHIFT
+	 * bits of start should be 0 now, since we are page aligning
+	 * v4l2_ram_phys
+	 */
+	start &= PAGE_MASK;
+
+	pr_debug("v4l2 map req for phys(%p,%p) offset %u to virt (%p,%p)\n",
+	(void *)(start+off), (void *)(start+off+(vma->vm_end - vma->vm_start)),
+	(unsigned int)off, (void *)vma->vm_start, (void *)vma->vm_end);
+
+	if ((vma->vm_end - vma->vm_start + off) > len) {
+		pr_err("v4l2 map request, memory requested too big\n");
+		return -EINVAL;
+	}
+
+	start += off;
+	vma->vm_pgoff = start >> PAGE_SHIFT;
+	/* This is an IO map - tell maydump to skip this VMA */
+	vma->vm_flags |= VM_IO | VM_RESERVED;
+
+	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+	/* Remap the frame buffer I/O range */
+	if (io_remap_pfn_range(vma, vma->vm_start, start >> PAGE_SHIFT,
+				vma->vm_end - vma->vm_start,
+				vma->vm_page_prot))
+		return -EAGAIN;
+
+	return 0;
+}
+
+static int
+msm_v4l2_overlay_release(struct file *file)
+{
+	struct msm_v4l2_overlay_fh *fh = file->private_data;
+	struct msm_v4l2_overlay_device *vout = fh->vout;
+
+	if (vout->streaming)
+		msm_v4l2_overlay_stopstreaming(vout);
+
+	vout->ref_count--;
+
+	kfree(vout->bufs);
+	vout->numbufs = 0;
+	kfree(fh);
+
+	return 0;
+}
+
+static int
+msm_v4l2_overlay_open(struct file *file)
+{
+	struct msm_v4l2_overlay_device	*vout = NULL;
+	struct v4l2_pix_format	*pix = NULL;
+	struct msm_v4l2_overlay_fh *fh;
+
+	vout = saved_vout0;
+	vout->id = 0;
+
+	if (vout->ref_count) {
+		pr_err("%s: multiple open currently is not"
+		"supported!\n", __func__);
+		return -EBUSY;
+	}
+
+	vout->ref_count++;
+
+	/* allocate per-filehandle data */
+	fh = kmalloc(sizeof(struct msm_v4l2_overlay_fh), GFP_KERNEL);
+	if (NULL == fh)
+		return -ENOMEM;
+
+	fh->vout = vout;
+	fh->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+
+	file->private_data = fh;
+
+	vout->streaming		= 0;
+	vout->crop_rect.left	= vout->crop_rect.top = 0;
+	vout->crop_rect.width	= vout->screen_width;
+	vout->crop_rect.height	= vout->screen_height;
+
+	pix				= &vout->pix;
+	pix->width			= vout->screen_width;
+	pix->height		= vout->screen_height;
+	pix->pixelformat	= V4L2_PIX_FMT_RGB32;
+	pix->field			= V4L2_FIELD_NONE;
+	pix->bytesperline	= pix->width * 4;
+	pix->sizeimage		= pix->bytesperline * pix->height;
+	pix->priv			= 0;
+	pix->colorspace		= V4L2_COLORSPACE_SRGB;
+
+	vout->win.w.left	= 0;
+	vout->win.w.top		= 0;
+	vout->win.w.width	= vout->screen_width;
+	vout->win.w.height	= vout->screen_height;
+
+	vout->fb.capability = V4L2_FBUF_CAP_EXTERNOVERLAY
+		| V4L2_FBUF_CAP_LOCAL_ALPHA;
+	vout->fb.flags = V4L2_FBUF_FLAG_LOCAL_ALPHA;
+	vout->fb.base = 0;
+	memcpy(&vout->fb.fmt, pix, sizeof(struct v4l2_format));
+
+	vout->bufs = 0;
+	vout->numbufs = 0;
+
+	mutex_init(&vout->update_lock);
+
+	return 0;
+}
+
+
+static int __devinit
+msm_v4l2_overlay_probe(struct platform_device *pdev)
+{
+	char *v4l2_ram_phys_unaligned;
+	if ((pdev->id == 0) && (pdev->num_resources > 0)) {
+		v4l2_ram_size =
+			pdev->resource[0].end - pdev->resource[0].start + 1;
+		v4l2_ram_phys_unaligned = (char *)pdev->resource[0].start;
+		v4l2_ram_phys =
+		(char *)PAGE_ALIGN((unsigned int)v4l2_ram_phys_unaligned);
+		/*
+		 * We are (fwd) page aligning the start of v4l2 memory.
+		 * Therefore we have that much less physical memory available
+		 */
+		v4l2_ram_size -= (unsigned int)v4l2_ram_phys
+			- (unsigned int)v4l2_ram_phys_unaligned;
+
+
+	}
+	return 0;
+}
+
+static int __devexit
+msm_v4l2_overlay_remove(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static void msm_v4l2_overlay_videodev_release(struct video_device *vfd)
+{
+	return;
+}
+
+static const struct v4l2_file_operations msm_v4l2_overlay_fops = {
+	.owner		= THIS_MODULE,
+	.open		= msm_v4l2_overlay_open,
+	.release	= msm_v4l2_overlay_release,
+	.mmap		= msm_v4l2_overlay_mmap,
+	.ioctl		= msm_v4l2_overlay_ioctl,
+};
+
+static struct video_device msm_v4l2_overlay_vid_device0 = {
+	.name		= "msm_v4l2_overlay",
+	.fops       = &msm_v4l2_overlay_fops,
+	.minor		= -1,
+	.release	= msm_v4l2_overlay_videodev_release,
+};
+
+static struct platform_driver msm_v4l2_overlay_platform_driver = {
+	.probe   = msm_v4l2_overlay_probe,
+	.remove  = msm_v4l2_overlay_remove,
+	.driver  = {
+			 .name = "msm_v4l2_overlay_pd",
+		   },
+};
+
+static int __init msm_v4l2_overlay_init(void)
+{
+	int ret;
+
+
+	saved_vout0 = kzalloc(sizeof(struct msm_v4l2_overlay_device),
+		GFP_KERNEL);
+
+	if (!saved_vout0)
+		return -ENOMEM;
+
+	ret = platform_driver_register(&msm_v4l2_overlay_platform_driver);
+	if (ret < 0)
+		goto end;
+
+	/*
+	 * Register the device with videodev.
+	 * Videodev will make IOCTL calls on application requests
+	 */
+	ret = video_register_device(&msm_v4l2_overlay_vid_device0,
+		VFL_TYPE_GRABBER, MSM_VIDEO);
+
+	if (ret < 0) {
+		pr_err("%s: V4L2 video overlay device registration failure(%d)\n",
+				  __func__, ret);
+		goto end_unregister;
+	}
+
+	mutex_init(&msmfb_lock);
+
+	return 0;
+
+end_unregister:
+	platform_driver_unregister(&msm_v4l2_overlay_platform_driver);
+
+end:
+	kfree(saved_vout0);
+	return ret;
+}
+
+static void __exit msm_v4l2_overlay_exit(void)
+{
+	video_unregister_device(&msm_v4l2_overlay_vid_device0);
+	platform_driver_unregister(&msm_v4l2_overlay_platform_driver);
+	mutex_destroy(&msmfb_lock);
+	kfree(saved_vout0);
+}
+
+module_init(msm_v4l2_overlay_init);
+module_exit(msm_v4l2_overlay_exit);
+
+MODULE_DESCRIPTION("MSM V4L2 Video Overlay Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/msm_v4l2_video.h b/drivers/media/platform/msm/camera_v1/msm_v4l2_video.h
new file mode 100644
index 0000000..6de6c80
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/msm_v4l2_video.h
@@ -0,0 +1,59 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef MSM_V4L2_VIDEO_H
+#define MSM_V4L2_VIDEO_H
+
+#include <linux/mm.h>
+#include <linux/msm_mdp.h>
+#include <linux/videodev2.h>
+
+
+struct msm_v4l2_overlay_buffer {
+	int mapped;
+	int queued;
+	int offset;
+	int bufsize;
+};
+
+struct msm_v4l2_overlay_device {
+	struct device dev;
+
+	int ref_count;
+	int id;
+
+	int screen_width;
+	int screen_height;
+	int streaming;
+
+	struct v4l2_pix_format pix;
+	struct v4l2_window win;
+	struct v4l2_rect crop_rect;
+	struct v4l2_framebuffer fb;
+	struct msm_v4l2_overlay_buffer *bufs;
+	int numbufs;
+	struct mdp_overlay req;
+	void *par;
+
+	struct mutex update_lock;
+};
+
+struct msm_v4l2_overlay_fh {
+	struct msm_v4l2_overlay_device *vout;
+	enum v4l2_buf_type type;
+};
+
+struct msm_v4l2_overlay_userptr_buffer {
+	uint fd[3]; /* ION fd of frame or plane */
+	size_t offset[3]; /* offset of frame or plane in multi buffer case */
+};
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v1/msm_vpe.c b/drivers/media/platform/msm/camera_v1/msm_vpe.c
new file mode 100644
index 0000000..ea1c819
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/msm_vpe.c
@@ -0,0 +1,1146 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/interrupt.h>
+#include <mach/irqs.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/regulator/consumer.h>
+#include <linux/clk.h>
+#include <mach/clk.h>
+#include <asm/div64.h>
+#include <linux/workqueue.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/ioctl.h>
+#include <linux/spinlock.h>
+#include "msm.h"
+#include "msm_vpe.h"
+
+#ifdef CONFIG_MSM_CAMERA_DEBUG
+#define D(fmt, args...) pr_debug("msm_vpe: " fmt, ##args)
+#else
+#define D(fmt, args...) do {} while (0)
+#endif
+
+static int vpe_enable(uint32_t, struct msm_cam_media_controller *);
+static int vpe_disable(struct msm_cam_media_controller *);
+static int vpe_update_scaler(struct msm_pp_crop *pcrop);
+struct vpe_ctrl_type *vpe_ctrl;
+static atomic_t vpe_init_done = ATOMIC_INIT(0);
+
+static int msm_vpe_do_pp(struct msm_mctl_pp_frame_info *pp_frame_info);
+
+static long long vpe_do_div(long long num, long long den)
+{
+	do_div(num, den);
+	return num;
+}
+
+static int vpe_start(void)
+{
+	/*  enable the frame irq, bit 0 = Display list 0 ROI done */
+	msm_camera_io_w_mb(1, vpe_ctrl->vpebase + VPE_INTR_ENABLE_OFFSET);
+	msm_camera_io_dump(vpe_ctrl->vpebase, 0x120);
+	msm_camera_io_dump(vpe_ctrl->vpebase + 0x00400, 0x18);
+	msm_camera_io_dump(vpe_ctrl->vpebase + 0x10000, 0x250);
+	msm_camera_io_dump(vpe_ctrl->vpebase + 0x30000, 0x20);
+	msm_camera_io_dump(vpe_ctrl->vpebase + 0x50000, 0x30);
+	msm_camera_io_dump(vpe_ctrl->vpebase + 0x50400, 0x10);
+
+	/* this triggers the operation. */
+	msm_camera_io_w_mb(1, vpe_ctrl->vpebase + VPE_DL0_START_OFFSET);
+	return 0;
+}
+
+void vpe_reset_state_variables(void)
+{
+	/* initialize local variables for state control, etc.*/
+	vpe_ctrl->op_mode = 0;
+	vpe_ctrl->state = VPE_STATE_INIT;
+}
+
+static void vpe_config_axi_default(void)
+{
+	msm_camera_io_w(0x25, vpe_ctrl->vpebase + VPE_AXI_ARB_2_OFFSET);
+	D("%s: yaddr %ld cbcraddr %ld", __func__,
+		 vpe_ctrl->out_y_addr, vpe_ctrl->out_cbcr_addr);
+	if (!vpe_ctrl->out_y_addr || !vpe_ctrl->out_cbcr_addr)
+		return;
+	msm_camera_io_w(vpe_ctrl->out_y_addr,
+		vpe_ctrl->vpebase + VPE_OUTP0_ADDR_OFFSET);
+	/* for video  CbCr address */
+	msm_camera_io_w(vpe_ctrl->out_cbcr_addr,
+		vpe_ctrl->vpebase + VPE_OUTP1_ADDR_OFFSET);
+}
+
+static int vpe_reset(void)
+{
+	uint32_t vpe_version;
+	uint32_t rc = 0;
+	unsigned long flags = 0;
+
+	spin_lock_irqsave(&vpe_ctrl->lock, flags);
+	if (vpe_ctrl->state == VPE_STATE_IDLE) {
+		D("%s: VPE already disabled.", __func__);
+		spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
+		return rc;
+	}
+	spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
+
+	vpe_reset_state_variables();
+	vpe_version = msm_camera_io_r(
+			vpe_ctrl->vpebase + VPE_HW_VERSION_OFFSET);
+	D("vpe_version = 0x%x\n", vpe_version);
+	/* disable all interrupts.*/
+	msm_camera_io_w(0, vpe_ctrl->vpebase + VPE_INTR_ENABLE_OFFSET);
+	/* clear all pending interrupts*/
+	msm_camera_io_w(0x1fffff, vpe_ctrl->vpebase + VPE_INTR_CLEAR_OFFSET);
+	/* write sw_reset to reset the core. */
+	msm_camera_io_w(0x10, vpe_ctrl->vpebase + VPE_SW_RESET_OFFSET);
+	/* then poll the reset bit, it should be self-cleared. */
+	while (1) {
+		rc =
+		msm_camera_io_r(vpe_ctrl->vpebase + VPE_SW_RESET_OFFSET) & 0x10;
+		if (rc == 0)
+			break;
+	}
+	/*  at this point, hardware is reset. Then pogram to default
+		values. */
+	msm_camera_io_w(VPE_AXI_RD_ARB_CONFIG_VALUE,
+			vpe_ctrl->vpebase + VPE_AXI_RD_ARB_CONFIG_OFFSET);
+
+	msm_camera_io_w(VPE_CGC_ENABLE_VALUE,
+			vpe_ctrl->vpebase + VPE_CGC_EN_OFFSET);
+	msm_camera_io_w(1, vpe_ctrl->vpebase + VPE_CMD_MODE_OFFSET);
+	msm_camera_io_w(VPE_DEFAULT_OP_MODE_VALUE,
+			vpe_ctrl->vpebase + VPE_OP_MODE_OFFSET);
+	msm_camera_io_w(VPE_DEFAULT_SCALE_CONFIG,
+			vpe_ctrl->vpebase + VPE_SCALE_CONFIG_OFFSET);
+	vpe_config_axi_default();
+	return rc;
+}
+
+static int msm_vpe_cfg_update(void *pinfo)
+{
+	uint32_t  rot_flag, rc = 0;
+	struct msm_pp_crop *pcrop = (struct msm_pp_crop *)pinfo;
+
+	rot_flag = msm_camera_io_r(vpe_ctrl->vpebase +
+						VPE_OP_MODE_OFFSET) & 0xE00;
+	if (pinfo != NULL) {
+		D("%s: Crop info in2_w = %d, in2_h = %d "
+			"out2_w = %d out2_h = %d\n",
+			__func__, pcrop->src_w, pcrop->src_h,
+			pcrop->dst_w, pcrop->dst_h);
+		rc = vpe_update_scaler(pcrop);
+	}
+	D("return rc = %d rot_flag = %d\n", rc, rot_flag);
+	rc |= rot_flag;
+
+	return rc;
+}
+
+void vpe_update_scale_coef(uint32_t *p)
+{
+	uint32_t i, offset;
+	offset = *p;
+	for (i = offset; i < (VPE_SCALE_COEFF_NUM + offset); i++) {
+		msm_camera_io_w(*(++p),
+			vpe_ctrl->vpebase + VPE_SCALE_COEFF_LSBn(i));
+		msm_camera_io_w(*(++p),
+			vpe_ctrl->vpebase + VPE_SCALE_COEFF_MSBn(i));
+	}
+}
+
+void vpe_input_plane_config(uint32_t *p)
+{
+	msm_camera_io_w(*p, vpe_ctrl->vpebase + VPE_SRC_FORMAT_OFFSET);
+	msm_camera_io_w(*(++p),
+		vpe_ctrl->vpebase + VPE_SRC_UNPACK_PATTERN1_OFFSET);
+	msm_camera_io_w(*(++p), vpe_ctrl->vpebase + VPE_SRC_IMAGE_SIZE_OFFSET);
+	msm_camera_io_w(*(++p), vpe_ctrl->vpebase + VPE_SRC_YSTRIDE1_OFFSET);
+	msm_camera_io_w(*(++p), vpe_ctrl->vpebase + VPE_SRC_SIZE_OFFSET);
+	msm_camera_io_w(*(++p), vpe_ctrl->vpebase + VPE_SRC_XY_OFFSET);
+}
+
+void vpe_output_plane_config(uint32_t *p)
+{
+	msm_camera_io_w(*p, vpe_ctrl->vpebase + VPE_OUT_FORMAT_OFFSET);
+	msm_camera_io_w(*(++p),
+		vpe_ctrl->vpebase + VPE_OUT_PACK_PATTERN1_OFFSET);
+	msm_camera_io_w(*(++p), vpe_ctrl->vpebase + VPE_OUT_YSTRIDE1_OFFSET);
+	msm_camera_io_w(*(++p), vpe_ctrl->vpebase + VPE_OUT_SIZE_OFFSET);
+	msm_camera_io_w(*(++p), vpe_ctrl->vpebase + VPE_OUT_XY_OFFSET);
+}
+
+static int vpe_operation_config(uint32_t *p)
+{
+	uint32_t w, h, temp;
+	msm_camera_io_w(*p, vpe_ctrl->vpebase + VPE_OP_MODE_OFFSET);
+
+	temp = msm_camera_io_r(vpe_ctrl->vpebase + VPE_OUT_SIZE_OFFSET);
+	w = temp & 0xFFF;
+	h = (temp & 0xFFF0000) >> 16;
+	if (*p++ & 0xE00) {
+		/* rotation enabled. */
+		vpe_ctrl->out_w = h;
+		vpe_ctrl->out_h = w;
+	} else {
+		vpe_ctrl->out_w = w;
+		vpe_ctrl->out_h = h;
+	}
+	D("%s: out_w=%d, out_h=%d", __func__, vpe_ctrl->out_w,
+		vpe_ctrl->out_h);
+	return 0;
+}
+
+/* Later we can separate the rotation and scaler calc. If
+*  rotation is enabled, simply swap the destination dimension.
+*  And then pass the already swapped output size to this
+*  function. */
+static int vpe_update_scaler(struct msm_pp_crop *pcrop)
+{
+	uint32_t out_ROI_width, out_ROI_height;
+	uint32_t src_ROI_width, src_ROI_height;
+
+	/*
+	* phase_step_x, phase_step_y, phase_init_x and phase_init_y
+	* are represented in fixed-point, unsigned 3.29 format
+	*/
+	uint32_t phase_step_x = 0;
+	uint32_t phase_step_y = 0;
+	uint32_t phase_init_x = 0;
+	uint32_t phase_init_y = 0;
+
+	uint32_t src_roi, src_x, src_y, src_xy, temp;
+	uint32_t yscale_filter_sel, xscale_filter_sel;
+	uint32_t scale_unit_sel_x, scale_unit_sel_y;
+	uint64_t numerator, denominator;
+
+	/* assumption is both direction need zoom. this can be
+	improved. */
+	temp =
+		msm_camera_io_r(vpe_ctrl->vpebase + VPE_OP_MODE_OFFSET) | 0x3;
+	msm_camera_io_w(temp, vpe_ctrl->vpebase + VPE_OP_MODE_OFFSET);
+
+	src_ROI_width = pcrop->src_w;
+	src_ROI_height = pcrop->src_h;
+	out_ROI_width = pcrop->dst_w;
+	out_ROI_height = pcrop->dst_h;
+
+	D("src w = 0x%x, h=0x%x, dst w = 0x%x, h =0x%x.\n",
+		src_ROI_width, src_ROI_height, out_ROI_width,
+		out_ROI_height);
+	src_roi = (src_ROI_height << 16) + src_ROI_width;
+
+	msm_camera_io_w(src_roi, vpe_ctrl->vpebase + VPE_SRC_SIZE_OFFSET);
+
+	src_x = pcrop->src_x;
+	src_y = pcrop->src_y;
+
+	D("src_x = %d, src_y=%d.\n", src_x, src_y);
+
+	src_xy = src_y*(1<<16) + src_x;
+	msm_camera_io_w(src_xy, vpe_ctrl->vpebase +
+			VPE_SRC_XY_OFFSET);
+	D("src_xy = %d, src_roi=%d.\n", src_xy, src_roi);
+
+	/* decide whether to use FIR or M/N for scaling */
+	if ((out_ROI_width == 1 && src_ROI_width < 4) ||
+		(src_ROI_width < 4 * out_ROI_width - 3))
+		scale_unit_sel_x = 0;/* use FIR scalar */
+	else
+		scale_unit_sel_x = 1;/* use M/N scalar */
+
+	if ((out_ROI_height == 1 && src_ROI_height < 4) ||
+		(src_ROI_height < 4 * out_ROI_height - 3))
+		scale_unit_sel_y = 0;/* use FIR scalar */
+	else
+		scale_unit_sel_y = 1;/* use M/N scalar */
+
+	/* calculate phase step for the x direction */
+
+	/* if destination is only 1 pixel wide,
+	the value of phase_step_x
+	is unimportant. Assigning phase_step_x to
+	src ROI width as an arbitrary value. */
+	if (out_ROI_width == 1)
+		phase_step_x = (uint32_t) ((src_ROI_width) <<
+						SCALER_PHASE_BITS);
+
+		/* if using FIR scalar */
+	else if (scale_unit_sel_x == 0) {
+
+		/* Calculate the quotient ( src_ROI_width - 1 )
+			( out_ROI_width - 1)
+			with u3.29 precision. Quotient is rounded up to
+			the larger 29th decimal point*/
+		numerator = (uint64_t)(src_ROI_width - 1) <<
+			SCALER_PHASE_BITS;
+		/* never equals to 0 because of the
+			"(out_ROI_width == 1 )"*/
+		denominator = (uint64_t)(out_ROI_width - 1);
+		/* divide and round up to the larger 29th
+			decimal point.*/
+		phase_step_x = (uint32_t) vpe_do_div((numerator +
+					denominator - 1), denominator);
+	} else if (scale_unit_sel_x == 1) { /* if M/N scalar */
+		/* Calculate the quotient ( src_ROI_width ) /
+			( out_ROI_width)
+			with u3.29 precision. Quotient is rounded down to the
+			smaller 29th decimal point.*/
+		numerator = (uint64_t)(src_ROI_width) <<
+			SCALER_PHASE_BITS;
+		denominator = (uint64_t)(out_ROI_width);
+		phase_step_x =
+			(uint32_t) vpe_do_div(numerator, denominator);
+	}
+	/* calculate phase step for the y direction */
+
+	/* if destination is only 1 pixel wide, the value of
+		phase_step_x is unimportant. Assigning phase_step_x
+		to src ROI width as an arbitrary value. */
+	if (out_ROI_height == 1)
+		phase_step_y =
+		(uint32_t) ((src_ROI_height) << SCALER_PHASE_BITS);
+
+	/* if FIR scalar */
+	else if (scale_unit_sel_y == 0) {
+		/* Calculate the quotient ( src_ROI_height - 1 ) /
+		( out_ROI_height - 1)
+		with u3.29 precision. Quotient is rounded up to the
+		larger 29th decimal point. */
+		numerator = (uint64_t)(src_ROI_height - 1) <<
+			SCALER_PHASE_BITS;
+		/* never equals to 0 because of the "
+		( out_ROI_height == 1 )" case */
+		denominator = (uint64_t)(out_ROI_height - 1);
+		/* Quotient is rounded up to the larger
+		29th decimal point. */
+		phase_step_y =
+		(uint32_t) vpe_do_div(
+			(numerator + denominator - 1), denominator);
+	} else if (scale_unit_sel_y == 1) { /* if M/N scalar */
+		/* Calculate the quotient ( src_ROI_height )
+			( out_ROI_height)
+			with u3.29 precision. Quotient is rounded down
+			to the smaller 29th decimal point. */
+		numerator = (uint64_t)(src_ROI_height) <<
+			SCALER_PHASE_BITS;
+		denominator = (uint64_t)(out_ROI_height);
+		phase_step_y = (uint32_t) vpe_do_div(
+			numerator, denominator);
+	}
+
+	/* decide which set of FIR coefficients to use */
+	if (phase_step_x > HAL_MDP_PHASE_STEP_2P50)
+		xscale_filter_sel = 0;
+	else if (phase_step_x > HAL_MDP_PHASE_STEP_1P66)
+		xscale_filter_sel = 1;
+	else if (phase_step_x > HAL_MDP_PHASE_STEP_1P25)
+		xscale_filter_sel = 2;
+	else
+		xscale_filter_sel = 3;
+
+	if (phase_step_y > HAL_MDP_PHASE_STEP_2P50)
+		yscale_filter_sel = 0;
+	else if (phase_step_y > HAL_MDP_PHASE_STEP_1P66)
+		yscale_filter_sel = 1;
+	else if (phase_step_y > HAL_MDP_PHASE_STEP_1P25)
+		yscale_filter_sel = 2;
+	else
+		yscale_filter_sel = 3;
+
+	/* calculate phase init for the x direction */
+
+	/* if using FIR scalar */
+	if (scale_unit_sel_x == 0) {
+		if (out_ROI_width == 1)
+			phase_init_x =
+				(uint32_t) ((src_ROI_width - 1) <<
+							SCALER_PHASE_BITS);
+		else
+			phase_init_x = 0;
+	} else if (scale_unit_sel_x == 1) /* M over N scalar  */
+		phase_init_x = 0;
+
+	/* calculate phase init for the y direction
+	if using FIR scalar */
+	if (scale_unit_sel_y == 0) {
+		if (out_ROI_height == 1)
+			phase_init_y =
+			(uint32_t) ((src_ROI_height -
+						1) << SCALER_PHASE_BITS);
+		else
+			phase_init_y = 0;
+	} else if (scale_unit_sel_y == 1) /* M over N scalar   */
+		phase_init_y = 0;
+
+	D("phase step x = %d, step y = %d.\n",
+		 phase_step_x, phase_step_y);
+	D("phase init x = %d, init y = %d.\n",
+		 phase_init_x, phase_init_y);
+
+	msm_camera_io_w(phase_step_x, vpe_ctrl->vpebase +
+			VPE_SCALE_PHASEX_STEP_OFFSET);
+	msm_camera_io_w(phase_step_y, vpe_ctrl->vpebase +
+			VPE_SCALE_PHASEY_STEP_OFFSET);
+
+	msm_camera_io_w(phase_init_x, vpe_ctrl->vpebase +
+			VPE_SCALE_PHASEX_INIT_OFFSET);
+
+	msm_camera_io_w(phase_init_y, vpe_ctrl->vpebase +
+			VPE_SCALE_PHASEY_INIT_OFFSET);
+
+	return 1;
+}
+
+int msm_vpe_is_busy(void)
+{
+	int busy = 0;
+	unsigned long flags;
+	spin_lock_irqsave(&vpe_ctrl->lock, flags);
+	if (vpe_ctrl->state == VPE_STATE_ACTIVE)
+		busy = 1;
+	spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
+	return busy;
+}
+
+static int msm_send_frame_to_vpe(void)
+{
+	int rc = 0;
+	unsigned long flags;
+	unsigned long srcP0, srcP1, outP0, outP1;
+	struct msm_mctl_pp_frame_info *frame_info = vpe_ctrl->pp_frame_info;
+
+	if (!frame_info) {
+		pr_err("%s Invalid frame", __func__);
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&vpe_ctrl->lock, flags);
+
+	if (frame_info->src_frame.frame.num_planes > 1) {
+		srcP0 = frame_info->src_frame.map[0].paddr +
+			frame_info->src_frame.map[0].data_offset;
+		srcP1 = frame_info->src_frame.map[1].paddr +
+			frame_info->src_frame.map[1].data_offset;
+		outP0 = frame_info->dest_frame.map[0].paddr +
+			frame_info->dest_frame.map[0].data_offset;
+		outP1 = frame_info->dest_frame.map[1].paddr +
+			frame_info->dest_frame.map[1].data_offset;
+	} else {
+		srcP0 = frame_info->src_frame.map[0].paddr;
+		srcP1 = frame_info->src_frame.map[0].paddr +
+			frame_info->src_frame.map[0].data_offset;
+		outP0 = frame_info->dest_frame.map[0].paddr;
+		outP1 = frame_info->dest_frame.map[0].paddr +
+			frame_info->dest_frame.map[0].data_offset;
+	}
+
+	D("%s VPE Configured with Src %x, %x Dest %x, %x",
+		__func__, (uint32_t)srcP0, (uint32_t)srcP1,
+		(uint32_t)outP0, (uint32_t)outP1);
+
+	msm_camera_io_w(srcP0, vpe_ctrl->vpebase + VPE_SRCP0_ADDR_OFFSET);
+	msm_camera_io_w(srcP1, vpe_ctrl->vpebase + VPE_SRCP1_ADDR_OFFSET);
+	msm_camera_io_w(outP0, vpe_ctrl->vpebase + VPE_OUTP0_ADDR_OFFSET);
+	msm_camera_io_w(outP1, vpe_ctrl->vpebase + VPE_OUTP1_ADDR_OFFSET);
+
+	vpe_ctrl->state = VPE_STATE_ACTIVE;
+	spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
+	vpe_start();
+	return rc;
+}
+
+static void vpe_send_outmsg(void)
+{
+	unsigned long flags;
+	struct v4l2_event v4l2_evt;
+	struct msm_queue_cmd *event_qcmd;
+	spin_lock_irqsave(&vpe_ctrl->lock, flags);
+	if (vpe_ctrl->state == VPE_STATE_IDLE) {
+		pr_err("%s VPE is in IDLE state. Ignore the ack msg", __func__);
+		spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
+		return;
+	}
+	event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_ATOMIC);
+	atomic_set(&event_qcmd->on_heap, 1);
+	event_qcmd->command = (void *)vpe_ctrl->pp_frame_info;
+	vpe_ctrl->pp_frame_info = NULL;
+	vpe_ctrl->state = VPE_STATE_INIT;   /* put it back to idle. */
+
+	/* Enqueue the event payload. */
+	msm_enqueue(&vpe_ctrl->eventData_q, &event_qcmd->list_eventdata);
+	/* Now queue the event. */
+	v4l2_evt.type = V4L2_EVENT_PRIVATE_START + MSM_CAM_RESP_MCTL_PP_EVENT;
+	v4l2_evt.id = 0;
+	v4l2_event_queue(vpe_ctrl->subdev.devnode, &v4l2_evt);
+	spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
+}
+
+static void vpe_do_tasklet(unsigned long data)
+{
+	D("%s: irq_status = 0x%x",
+		   __func__, vpe_ctrl->irq_status);
+	if (vpe_ctrl->irq_status & 0x1)
+		vpe_send_outmsg();
+
+}
+DECLARE_TASKLET(vpe_tasklet, vpe_do_tasklet, 0);
+
+static irqreturn_t vpe_parse_irq(int irq_num, void *data)
+{
+	vpe_ctrl->irq_status = msm_camera_io_r_mb(vpe_ctrl->vpebase +
+							VPE_INTR_STATUS_OFFSET);
+	msm_camera_io_w_mb(vpe_ctrl->irq_status, vpe_ctrl->vpebase +
+				VPE_INTR_CLEAR_OFFSET);
+	msm_camera_io_w(0, vpe_ctrl->vpebase + VPE_INTR_ENABLE_OFFSET);
+	D("%s: vpe_parse_irq =0x%x.\n", __func__, vpe_ctrl->irq_status);
+	tasklet_schedule(&vpe_tasklet);
+	return IRQ_HANDLED;
+}
+
+static struct msm_cam_clk_info vpe_clk_info[] = {
+	{"vpe_clk", 160000000},
+	{"vpe_pclk", -1},
+};
+
+int vpe_enable(uint32_t clk_rate, struct msm_cam_media_controller *mctl)
+{
+	int rc = 0;
+	unsigned long flags = 0;
+	D("%s", __func__);
+	/* don't change the order of clock and irq.*/
+	spin_lock_irqsave(&vpe_ctrl->lock, flags);
+	if (vpe_ctrl->state != VPE_STATE_IDLE) {
+		pr_err("%s: VPE already enabled", __func__);
+		spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
+		return 0;
+	}
+	vpe_ctrl->state = VPE_STATE_INIT;
+	spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
+	enable_irq(vpe_ctrl->vpeirq->start);
+
+	if (vpe_ctrl->fs_vpe) {
+		rc = regulator_enable(vpe_ctrl->fs_vpe);
+		if (rc) {
+			pr_err("%s: Regulator enable failed\n", __func__);
+			goto vpe_fs_failed;
+		}
+	}
+
+	rc = msm_cam_clk_enable(&vpe_ctrl->pdev->dev, vpe_clk_info,
+			vpe_ctrl->vpe_clk, ARRAY_SIZE(vpe_clk_info), 1);
+	if (rc < 0)
+		goto vpe_clk_failed;
+
+#ifdef CONFIG_MSM_IOMMU
+	rc = iommu_attach_device(mctl->domain, vpe_ctrl->iommu_ctx_src);
+	if (rc < 0) {
+		pr_err("%s: Device attach failed\n", __func__);
+		goto src_attach_failed;
+	}
+	rc = iommu_attach_device(mctl->domain, vpe_ctrl->iommu_ctx_dst);
+	if (rc < 0) {
+		pr_err("%s: Device attach failed\n", __func__);
+		goto dst_attach_failed;
+	}
+#endif
+	return rc;
+
+#ifdef CONFIG_MSM_IOMMU
+dst_attach_failed:
+	iommu_detach_device(mctl->domain, vpe_ctrl->iommu_ctx_src);
+src_attach_failed:
+#endif
+	msm_cam_clk_enable(&vpe_ctrl->pdev->dev, vpe_clk_info,
+		vpe_ctrl->vpe_clk, ARRAY_SIZE(vpe_clk_info), 0);
+vpe_clk_failed:
+	if (vpe_ctrl->fs_vpe)
+		regulator_disable(vpe_ctrl->fs_vpe);
+vpe_fs_failed:
+	disable_irq(vpe_ctrl->vpeirq->start);
+	vpe_ctrl->state = VPE_STATE_IDLE;
+	return rc;
+}
+
+int vpe_disable(struct msm_cam_media_controller *mctl)
+{
+	int rc = 0;
+	unsigned long flags = 0;
+	D("%s", __func__);
+	spin_lock_irqsave(&vpe_ctrl->lock, flags);
+	if (vpe_ctrl->state == VPE_STATE_IDLE) {
+		D("%s: VPE already disabled", __func__);
+		spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
+		return rc;
+	}
+	spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
+#ifdef CONFIG_MSM_IOMMU
+	iommu_detach_device(mctl->domain, vpe_ctrl->iommu_ctx_dst);
+	iommu_detach_device(mctl->domain, vpe_ctrl->iommu_ctx_src);
+#endif
+	disable_irq(vpe_ctrl->vpeirq->start);
+	tasklet_kill(&vpe_tasklet);
+	msm_cam_clk_enable(&vpe_ctrl->pdev->dev, vpe_clk_info,
+			vpe_ctrl->vpe_clk, ARRAY_SIZE(vpe_clk_info), 0);
+
+	regulator_disable(vpe_ctrl->fs_vpe);
+	spin_lock_irqsave(&vpe_ctrl->lock, flags);
+	vpe_ctrl->state = VPE_STATE_IDLE;
+	spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
+	return rc;
+}
+
+static int msm_vpe_do_pp(struct msm_mctl_pp_frame_info *pp_frame_info)
+{
+	int rc = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&vpe_ctrl->lock, flags);
+	if (vpe_ctrl->state == VPE_STATE_ACTIVE ||
+		 vpe_ctrl->state == VPE_STATE_IDLE) {
+		spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
+		pr_err(" =====VPE in wrong state:%d!!!  Wrong!========\n",
+		vpe_ctrl->state);
+		return -EBUSY;
+	}
+	spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
+	vpe_ctrl->pp_frame_info = pp_frame_info;
+	msm_vpe_cfg_update(
+		&vpe_ctrl->pp_frame_info->pp_frame_cmd.crop);
+	D("%s Sending frame idx %d id %d to VPE ", __func__,
+		pp_frame_info->src_frame.frame.buf_idx,
+		pp_frame_info->src_frame.frame.frame_id);
+	rc = msm_send_frame_to_vpe();
+	return rc;
+}
+
+static int msm_vpe_resource_init(void);
+
+int msm_vpe_subdev_init(struct v4l2_subdev *sd)
+{
+	int rc = 0;
+	struct msm_cam_media_controller *mctl;
+	mctl = v4l2_get_subdev_hostdata(sd);
+	D("%s:begin", __func__);
+	if (atomic_read(&vpe_init_done)) {
+		pr_err("%s: VPE has been initialized", __func__);
+		return -EBUSY;
+	}
+	atomic_set(&vpe_init_done, 1);
+
+	rc = msm_vpe_resource_init();
+	if (rc < 0) {
+		atomic_set(&vpe_init_done, 0);
+		return rc;
+	}
+	spin_lock_init(&vpe_ctrl->lock);
+	D("%s:end", __func__);
+	return rc;
+}
+EXPORT_SYMBOL(msm_vpe_subdev_init);
+
+static int msm_vpe_resource_init(void)
+{
+	int rc = 0;
+
+	vpe_ctrl->vpebase = ioremap(vpe_ctrl->vpemem->start,
+		resource_size(vpe_ctrl->vpemem));
+
+	if (!vpe_ctrl->vpebase) {
+		rc = -ENOMEM;
+		pr_err("%s: vpe ioremap failed\n", __func__);
+		goto vpe_unmap_mem_region;
+	}
+
+	return rc;
+/* from this part it is error handling. */
+vpe_unmap_mem_region:
+	iounmap(vpe_ctrl->vpebase);
+	vpe_ctrl->vpebase = NULL;
+	return rc;  /* this rc should have error code. */
+}
+
+void msm_vpe_subdev_release(struct v4l2_subdev *sd)
+{
+	struct msm_cam_media_controller *mctl;
+	mctl = v4l2_get_subdev_hostdata(sd);
+	if (!atomic_read(&vpe_init_done)) {
+		/* no VPE object created */
+		pr_err("%s: no VPE object to release", __func__);
+		return;
+	}
+	vpe_reset();
+	vpe_disable(mctl);
+	iounmap(vpe_ctrl->vpebase);
+	vpe_ctrl->vpebase = NULL;
+	atomic_set(&vpe_init_done, 0);
+}
+EXPORT_SYMBOL(msm_vpe_subdev_release);
+
+static int msm_vpe_process_vpe_cmd(struct msm_vpe_cfg_cmd *vpe_cmd,
+				struct msm_cam_media_controller *mctl)
+{
+	int rc = 0;
+
+	switch (vpe_cmd->cmd_type) {
+	case VPE_CMD_RESET:
+		rc = vpe_reset();
+		break;
+
+	case VPE_CMD_OPERATION_MODE_CFG: {
+		struct msm_vpe_op_mode_cfg op_mode_cfg;
+		if (sizeof(struct msm_vpe_op_mode_cfg) != vpe_cmd->length) {
+			pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d",
+				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
+				sizeof(struct msm_vpe_op_mode_cfg));
+			rc = -EINVAL;
+			break;
+		}
+		COPY_FROM_USER(rc, &op_mode_cfg, (void __user *)vpe_cmd->value,
+			sizeof(op_mode_cfg));
+		if (rc) {
+			ERR_COPY_FROM_USER();
+			break;
+		}
+
+		vpe_cmd->value = (void *)&op_mode_cfg;
+		rc = vpe_operation_config(vpe_cmd->value);
+		break;
+		}
+
+	case VPE_CMD_INPUT_PLANE_CFG: {
+		struct msm_vpe_input_plane_cfg input_cfg;
+		if (sizeof(struct msm_vpe_input_plane_cfg) != vpe_cmd->length) {
+			pr_err("%s: mismatch cmd = %d, len = %d, expected = %d",
+				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
+				sizeof(struct msm_vpe_input_plane_cfg));
+			rc = -EINVAL;
+			break;
+		}
+		COPY_FROM_USER(rc, &input_cfg, (void __user *)vpe_cmd->value,
+			sizeof(input_cfg));
+		if (rc) {
+			ERR_COPY_FROM_USER();
+			break;
+		}
+
+		vpe_cmd->value = (void *)&input_cfg;
+		vpe_input_plane_config(vpe_cmd->value);
+		break;
+		}
+
+	case VPE_CMD_OUTPUT_PLANE_CFG: {
+		struct msm_vpe_output_plane_cfg output_cfg;
+		if (sizeof(struct msm_vpe_output_plane_cfg) !=
+			vpe_cmd->length) {
+			pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d",
+				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
+				sizeof(struct msm_vpe_output_plane_cfg));
+				rc = -EINVAL;
+				break;
+		}
+		COPY_FROM_USER(rc, &output_cfg, (void __user *)vpe_cmd->value,
+			sizeof(output_cfg));
+		if (rc) {
+			ERR_COPY_FROM_USER();
+			break;
+		}
+
+		vpe_cmd->value = (void *)&output_cfg;
+		vpe_output_plane_config(vpe_cmd->value);
+		break;
+		}
+
+	case VPE_CMD_SCALE_CFG_TYPE:{
+		struct msm_vpe_scaler_cfg scaler_cfg;
+		if (sizeof(struct msm_vpe_scaler_cfg) != vpe_cmd->length) {
+			pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d",
+				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
+				sizeof(struct msm_vpe_scaler_cfg));
+			rc = -EINVAL;
+			break;
+		}
+		COPY_FROM_USER(rc, &scaler_cfg, (void __user *)vpe_cmd->value,
+			sizeof(scaler_cfg));
+		if (rc) {
+			ERR_COPY_FROM_USER();
+			break;
+		}
+
+		vpe_cmd->value = (void *)&scaler_cfg;
+		vpe_update_scale_coef(vpe_cmd->value);
+		break;
+		}
+
+	case VPE_CMD_ZOOM: {
+		struct msm_mctl_pp_frame_info *zoom;
+		zoom = kmalloc(sizeof(struct msm_mctl_pp_frame_info),
+				GFP_ATOMIC);
+		if (!zoom) {
+			pr_err("%s Not enough memory ", __func__);
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (sizeof(zoom->pp_frame_cmd) != vpe_cmd->length) {
+			pr_err("%s: size mismatch id=%d, len=%d, expected=%d",
+				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
+				sizeof(zoom->pp_frame_cmd));
+			rc = -EINVAL;
+			kfree(zoom);
+			break;
+		}
+		COPY_FROM_USER(rc, &zoom->pp_frame_cmd,
+			(void __user *)vpe_cmd->value,
+			sizeof(zoom->pp_frame_cmd));
+		if (rc) {
+			ERR_COPY_FROM_USER();
+			kfree(zoom);
+			break;
+		}
+
+		zoom->user_cmd = vpe_cmd->cmd_type;
+		zoom->p_mctl = v4l2_get_subdev_hostdata(&vpe_ctrl->subdev);
+		D("%s: cookie=0x%x,action=0x%x,path=0x%x",
+			__func__, zoom->pp_frame_cmd.cookie,
+			zoom->pp_frame_cmd.vpe_output_action,
+			zoom->pp_frame_cmd.path);
+
+		D("%s Mapping Source frame ", __func__);
+		zoom->src_frame.frame = zoom->pp_frame_cmd.src_frame;
+		rc = msm_mctl_map_user_frame(&zoom->src_frame,
+			zoom->p_mctl->client, mctl->domain_num);
+		if (rc < 0) {
+			pr_err("%s Error mapping source buffer rc = %d",
+				__func__, rc);
+			kfree(zoom);
+			break;
+		}
+
+		D("%s Mapping Destination frame ", __func__);
+		zoom->dest_frame.frame = zoom->pp_frame_cmd.dest_frame;
+		rc = msm_mctl_map_user_frame(&zoom->dest_frame,
+			zoom->p_mctl->client, mctl->domain_num);
+		if (rc < 0) {
+			pr_err("%s Error mapping dest buffer rc = %d",
+				__func__, rc);
+			msm_mctl_unmap_user_frame(&zoom->src_frame,
+				zoom->p_mctl->client, mctl->domain_num);
+			kfree(zoom);
+			break;
+		}
+
+		rc = msm_vpe_do_pp(zoom);
+		break;
+		}
+
+	case VPE_CMD_ENABLE: {
+		struct msm_vpe_clock_rate clk_rate;
+		int turbo_mode;
+		if (sizeof(struct msm_vpe_clock_rate) != vpe_cmd->length) {
+			pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d",
+				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
+				sizeof(struct msm_vpe_clock_rate));
+			rc = -EINVAL;
+			break;
+		}
+		if (copy_from_user(&clk_rate, (void __user *)vpe_cmd->value,
+			sizeof(struct msm_vpe_clock_rate))) {
+			pr_err("%s:clk_rate copy failed", __func__);
+			return -EFAULT;
+		}
+		turbo_mode = (int)clk_rate.rate;
+		rc = turbo_mode ? vpe_enable(VPE_TURBO_MODE_CLOCK_RATE, mctl) :
+				vpe_enable(VPE_NORMAL_MODE_CLOCK_RATE, mctl);
+		break;
+		}
+
+	case VPE_CMD_DISABLE:
+		rc = vpe_disable(mctl);
+		break;
+
+	default:
+		break;
+	}
+
+	return rc;
+}
+
+static long msm_vpe_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int cmd, void *arg)
+{
+	struct msm_vpe_cfg_cmd *vpe_cmd;
+	int rc = 0;
+	struct msm_cam_media_controller *mctl;
+	mctl = v4l2_get_subdev_hostdata(sd);
+	switch (cmd) {
+	case VIDIOC_MSM_VPE_INIT: {
+		msm_vpe_subdev_init(sd);
+		break;
+		}
+
+	case VIDIOC_MSM_VPE_RELEASE:
+		msm_vpe_subdev_release(sd);
+		break;
+
+	case MSM_CAM_V4L2_IOCTL_CFG_VPE: {
+		vpe_cmd = (struct msm_vpe_cfg_cmd *)arg;
+		rc = msm_vpe_process_vpe_cmd(vpe_cmd, mctl);
+		if (rc < 0) {
+			pr_err("%s Error processing VPE cmd %d ",
+				__func__, vpe_cmd->cmd_type);
+			break;
+		}
+		break;
+		}
+
+	case MSM_CAM_V4L2_IOCTL_GET_EVENT_PAYLOAD: {
+		struct msm_device_queue *queue = &vpe_ctrl->eventData_q;
+		struct msm_queue_cmd *event_qcmd;
+		struct msm_mctl_pp_event_info pp_event_info;
+		struct msm_mctl_pp_frame_info *pp_frame_info;
+		struct msm_camera_v4l2_ioctl_t *v4l2_ioctl = arg;
+
+		event_qcmd = msm_dequeue(queue, list_eventdata);
+		if (!event_qcmd) {
+			pr_err("%s No events in the queue", __func__);
+			return -EFAULT;
+		}
+		pp_frame_info = event_qcmd->command;
+
+		D("%s Unmapping source and destination buffers ",
+			__func__);
+		msm_mctl_unmap_user_frame(&pp_frame_info->src_frame,
+			pp_frame_info->p_mctl->client, mctl->domain_num);
+		msm_mctl_unmap_user_frame(&pp_frame_info->dest_frame,
+			pp_frame_info->p_mctl->client, mctl->domain_num);
+
+		pp_event_info.event = MCTL_PP_EVENT_CMD_ACK;
+		pp_event_info.ack.cmd = pp_frame_info->user_cmd;
+		pp_event_info.ack.status = 0;
+		pp_event_info.ack.cookie = pp_frame_info->pp_frame_cmd.cookie;
+		D("%s Sending payload %d %d %d", __func__,
+			pp_event_info.ack.cmd, pp_event_info.ack.status,
+			pp_event_info.ack.cookie);
+		if (copy_to_user((void __user *)v4l2_ioctl->ioctl_ptr,
+			&pp_event_info,	sizeof(struct msm_mctl_pp_event_info)))
+			pr_err("%s PAYLOAD Copy to user failed ", __func__);
+
+		kfree(pp_frame_info);
+		kfree(event_qcmd);
+		break;
+		}
+
+	default:
+		break;
+	}
+	return rc;
+}
+
+int msm_vpe_subdev_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+	struct v4l2_event_subscription *sub)
+{
+	D("%s E\n", __func__);
+	return v4l2_event_subscribe(fh, sub, VPE_SUBDEV_MAX_EVENTS);
+}
+
+int msm_vpe_subdev_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+	struct v4l2_event_subscription *sub)
+{
+	D("%s E\n", __func__);
+	return v4l2_event_unsubscribe(fh, sub);
+}
+
+static const struct v4l2_subdev_core_ops msm_vpe_subdev_core_ops = {
+	.ioctl = msm_vpe_subdev_ioctl,
+	.subscribe_event = msm_vpe_subdev_subscribe_event,
+	.unsubscribe_event = msm_vpe_subdev_unsubscribe_event,
+};
+
+static const struct v4l2_subdev_ops msm_vpe_subdev_ops = {
+	.core = &msm_vpe_subdev_core_ops,
+};
+
+static int msm_vpe_subdev_open(struct v4l2_subdev *sd,
+	struct v4l2_subdev_fh *fh)
+{
+	struct vpe_ctrl_type *vpe_ctrl = v4l2_get_subdevdata(sd);
+	/* Only one client of VPE allowed. */
+	if (atomic_read(&vpe_ctrl->active) != 0) {
+		pr_err("%s already opened\n", __func__);
+		return -EINVAL;
+	}
+
+	D("%s E ", __func__);
+	atomic_inc(&vpe_ctrl->active);
+	return 0;
+}
+
+static int msm_vpe_subdev_close(struct v4l2_subdev *sd,
+	struct v4l2_subdev_fh *fh)
+{
+	struct vpe_ctrl_type *vpe_ctrl = v4l2_get_subdevdata(sd);
+	struct msm_mctl_pp_frame_info *frame_info = vpe_ctrl->pp_frame_info;
+	struct msm_cam_media_controller *mctl;
+	mctl = v4l2_get_subdev_hostdata(sd);
+	if (atomic_read(&vpe_ctrl->active) == 0) {
+		pr_err("%s already closed\n", __func__);
+		return -EINVAL;
+	}
+
+	D("%s E ", __func__);
+	if (frame_info) {
+		D("%s Unmap the pending item from the queue ", __func__);
+		msm_mctl_unmap_user_frame(&frame_info->src_frame,
+			frame_info->p_mctl->client, mctl->domain_num);
+		msm_mctl_unmap_user_frame(&frame_info->dest_frame,
+			frame_info->p_mctl->client, mctl->domain_num);
+	}
+	/* Drain the payload queue. */
+	msm_queue_drain(&vpe_ctrl->eventData_q, list_eventdata);
+	atomic_dec(&vpe_ctrl->active);
+	return 0;
+}
+
+static const struct v4l2_subdev_internal_ops msm_vpe_internal_ops = {
+	.open = msm_vpe_subdev_open,
+	.close = msm_vpe_subdev_close,
+};
+
+static int __devinit msm_vpe_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+	struct msm_cam_subdev_info sd_info;
+
+	D("%s: device id = %d\n", __func__, pdev->id);
+	vpe_ctrl = kzalloc(sizeof(struct vpe_ctrl_type), GFP_KERNEL);
+	if (!vpe_ctrl) {
+		pr_err("%s: not enough memory\n", __func__);
+		return -ENOMEM;
+	}
+
+	v4l2_subdev_init(&vpe_ctrl->subdev, &msm_vpe_subdev_ops);
+	v4l2_set_subdevdata(&vpe_ctrl->subdev, vpe_ctrl);
+	vpe_ctrl->subdev.internal_ops = &msm_vpe_internal_ops;
+	vpe_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	snprintf(vpe_ctrl->subdev.name, sizeof(vpe_ctrl->subdev.name), "vpe");
+	platform_set_drvdata(pdev, &vpe_ctrl->subdev);
+
+	media_entity_init(&vpe_ctrl->subdev.entity, 0, NULL, 0);
+	vpe_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	vpe_ctrl->subdev.entity.group_id = VPE_DEV;
+	vpe_ctrl->subdev.entity.name = vpe_ctrl->subdev.name;
+
+	vpe_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_EVENTS;
+
+	vpe_ctrl->vpemem = platform_get_resource_byname(pdev,
+					IORESOURCE_MEM, "vpe");
+	if (!vpe_ctrl->vpemem) {
+		pr_err("%s: no mem resource?\n", __func__);
+		rc = -ENODEV;
+		goto vpe_no_resource;
+	}
+	vpe_ctrl->vpeirq = platform_get_resource_byname(pdev,
+					IORESOURCE_IRQ, "vpe");
+	if (!vpe_ctrl->vpeirq) {
+		pr_err("%s: no irq resource?\n", __func__);
+		rc = -ENODEV;
+		goto vpe_no_resource;
+	}
+
+	vpe_ctrl->vpeio = request_mem_region(vpe_ctrl->vpemem->start,
+		resource_size(vpe_ctrl->vpemem), pdev->name);
+	if (!vpe_ctrl->vpeio) {
+		pr_err("%s: no valid mem region\n", __func__);
+		rc = -EBUSY;
+		goto vpe_no_resource;
+	}
+
+	rc = request_irq(vpe_ctrl->vpeirq->start, vpe_parse_irq,
+		IRQF_TRIGGER_RISING, "vpe", 0);
+	if (rc < 0) {
+		release_mem_region(vpe_ctrl->vpemem->start,
+			resource_size(vpe_ctrl->vpemem));
+		pr_err("%s: irq request fail\n", __func__);
+		rc = -EBUSY;
+		goto vpe_no_resource;
+	}
+
+	vpe_ctrl->fs_vpe = regulator_get(&pdev->dev, "vdd");
+	if (IS_ERR(vpe_ctrl->fs_vpe)) {
+		pr_err("%s: Regulator FS_VPE get failed %ld\n", __func__,
+			PTR_ERR(vpe_ctrl->fs_vpe));
+		vpe_ctrl->fs_vpe = NULL;
+	}
+
+	disable_irq(vpe_ctrl->vpeirq->start);
+
+#ifdef CONFIG_MSM_IOMMU
+	/*get device context for IOMMU*/
+	vpe_ctrl->iommu_ctx_src = msm_iommu_get_ctx("vpe_src"); /*re-confirm*/
+	vpe_ctrl->iommu_ctx_dst = msm_iommu_get_ctx("vpe_dst"); /*re-confirm*/
+	if (!vpe_ctrl->iommu_ctx_src || !vpe_ctrl->iommu_ctx_dst) {
+		release_mem_region(vpe_ctrl->vpemem->start,
+			resource_size(vpe_ctrl->vpemem));
+		pr_err("%s: No iommu fw context found\n", __func__);
+		rc = -ENODEV;
+		goto vpe_no_resource;
+	}
+#endif
+
+	atomic_set(&vpe_ctrl->active, 0);
+	vpe_ctrl->pdev = pdev;
+	sd_info.sdev_type = VPE_DEV;
+	sd_info.sd_index = pdev->id;
+	sd_info.irq_num = vpe_ctrl->vpeirq->start;
+	msm_cam_register_subdev_node(&vpe_ctrl->subdev, &sd_info);
+	vpe_ctrl->subdev.entity.revision = vpe_ctrl->subdev.devnode->num;
+	msm_queue_init(&vpe_ctrl->eventData_q, "ackevents");
+
+	return 0;
+
+vpe_no_resource:
+	pr_err("%s: VPE Probe failed.\n", __func__);
+	kfree(vpe_ctrl);
+	return rc;
+}
+
+struct platform_driver msm_vpe_driver = {
+	.probe = msm_vpe_probe,
+	.driver = {
+		.name = MSM_VPE_DRV_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init msm_vpe_init_module(void)
+{
+	return platform_driver_register(&msm_vpe_driver);
+}
+
+static void __exit msm_vpe_exit_module(void)
+{
+	platform_driver_unregister(&msm_vpe_driver);
+}
+
+module_init(msm_vpe_init_module);
+module_exit(msm_vpe_exit_module);
+MODULE_DESCRIPTION("VPE driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/msm_vpe.h b/drivers/media/platform/msm/camera_v1/msm_vpe.h
new file mode 100644
index 0000000..6b89bf0
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/msm_vpe.h
@@ -0,0 +1,186 @@
+/* Copyright (c) 2011-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.
+ *
+ */
+
+#ifndef _MSM_VPE_H_
+#define _MSM_VPE_H_
+
+#include <mach/camera.h>
+
+/***********  start of register offset *********************/
+#define VPE_INTR_ENABLE_OFFSET                0x0020
+#define VPE_INTR_STATUS_OFFSET                0x0024
+#define VPE_INTR_CLEAR_OFFSET                 0x0028
+#define VPE_DL0_START_OFFSET                  0x0030
+#define VPE_HW_VERSION_OFFSET                 0x0070
+#define VPE_SW_RESET_OFFSET                   0x0074
+#define VPE_AXI_RD_ARB_CONFIG_OFFSET          0x0078
+#define VPE_SEL_CLK_OR_HCLK_TEST_BUS_OFFSET   0x007C
+#define VPE_CGC_EN_OFFSET                     0x0100
+#define VPE_CMD_STATUS_OFFSET                 0x10008
+#define VPE_PROFILE_EN_OFFSET                 0x10010
+#define VPE_PROFILE_COUNT_OFFSET              0x10014
+#define VPE_CMD_MODE_OFFSET                   0x10060
+#define VPE_SRC_SIZE_OFFSET                   0x10108
+#define VPE_SRCP0_ADDR_OFFSET                 0x1010C
+#define VPE_SRCP1_ADDR_OFFSET                 0x10110
+#define VPE_SRC_YSTRIDE1_OFFSET               0x1011C
+#define VPE_SRC_FORMAT_OFFSET                 0x10124
+#define VPE_SRC_UNPACK_PATTERN1_OFFSET        0x10128
+#define VPE_OP_MODE_OFFSET                    0x10138
+#define VPE_SCALE_PHASEX_INIT_OFFSET          0x1013C
+#define VPE_SCALE_PHASEY_INIT_OFFSET          0x10140
+#define VPE_SCALE_PHASEX_STEP_OFFSET          0x10144
+#define VPE_SCALE_PHASEY_STEP_OFFSET          0x10148
+#define VPE_OUT_FORMAT_OFFSET                 0x10150
+#define VPE_OUT_PACK_PATTERN1_OFFSET          0x10154
+#define VPE_OUT_SIZE_OFFSET                   0x10164
+#define VPE_OUTP0_ADDR_OFFSET                 0x10168
+#define VPE_OUTP1_ADDR_OFFSET                 0x1016C
+#define VPE_OUT_YSTRIDE1_OFFSET               0x10178
+#define VPE_OUT_XY_OFFSET                     0x1019C
+#define VPE_SRC_XY_OFFSET                     0x10200
+#define VPE_SRC_IMAGE_SIZE_OFFSET             0x10208
+#define VPE_SCALE_CONFIG_OFFSET               0x10230
+#define VPE_DEINT_STATUS_OFFSET               0x30000
+#define VPE_DEINT_DECISION_OFFSET             0x30004
+#define VPE_DEINT_COEFF0_OFFSET               0x30010
+#define VPE_SCALE_STATUS_OFFSET               0x50000
+#define VPE_SCALE_SVI_PARAM_OFFSET            0x50010
+#define VPE_SCALE_SHARPEN_CFG_OFFSET          0x50020
+#define VPE_SCALE_COEFF_LSP_0_OFFSET          0x50400
+#define VPE_SCALE_COEFF_MSP_0_OFFSET          0x50404
+
+#define VPE_AXI_ARB_1_OFFSET                  0x00408
+#define VPE_AXI_ARB_2_OFFSET                  0x0040C
+
+#define VPE_SCALE_COEFF_LSBn(n)	(0x50400 + 8 * (n))
+#define VPE_SCALE_COEFF_MSBn(n)	(0x50404 + 8 * (n))
+#define VPE_SCALE_COEFF_NUM			32
+
+/*********** end of register offset ********************/
+
+
+#define VPE_HARDWARE_VERSION          0x00080308
+#define VPE_SW_RESET_VALUE            0x00000010  /* bit 4 for PPP*/
+#define VPE_AXI_RD_ARB_CONFIG_VALUE   0x124924
+#define VPE_CMD_MODE_VALUE            0x1
+#define VPE_DEFAULT_OP_MODE_VALUE     0x40FC0004
+#define VPE_CGC_ENABLE_VALUE          0xffff
+#define VPE_DEFAULT_SCALE_CONFIG      0x3c
+
+#define VPE_NORMAL_MODE_CLOCK_RATE   150000000
+#define VPE_TURBO_MODE_CLOCK_RATE    200000000
+#define VPE_SUBDEV_MAX_EVENTS        30
+
+/**************************************************/
+/*********** End of command id ********************/
+/**************************************************/
+
+enum vpe_state {
+	VPE_STATE_IDLE,
+	VPE_STATE_INIT,
+	VPE_STATE_ACTIVE,
+};
+
+struct vpe_ctrl_type {
+	spinlock_t        lock;
+	uint32_t          irq_status;
+	void              *syncdata;
+	uint16_t          op_mode;
+	void              *extdata;
+	uint32_t          extlen;
+	struct msm_vpe_callback *resp;
+	uint32_t          out_h;  /* this is BEFORE rotation. */
+	uint32_t          out_w;  /* this is BEFORE rotation. */
+	struct timespec   ts;
+	int               output_type;
+	int               frame_pack;
+	uint8_t           pad_2k_bool;
+	enum vpe_state    state;
+	unsigned long     out_y_addr;
+	unsigned long     out_cbcr_addr;
+	struct v4l2_subdev subdev;
+	struct platform_device *pdev;
+	struct resource   *vpeirq;
+	void __iomem      *vpebase;
+	struct resource	  *vpemem;
+	struct resource   *vpeio;
+	void        *device_extdata;
+	struct regulator *fs_vpe;
+	struct clk	*vpe_clk[2];
+	struct msm_mctl_pp_frame_info *pp_frame_info;
+	atomic_t active;
+	struct msm_device_queue eventData_q; /*V4L2 Event Payload Queue*/
+	struct device *iommu_ctx_src;
+	struct device *iommu_ctx_dst;
+};
+
+/*
+* vpe_input_update
+*
+* Define the parameters for output plane
+*/
+/* this is the dimension of ROI.  width / height. */
+struct vpe_src_size_packed {
+	uint32_t        src_w;
+	uint32_t        src_h;
+};
+
+struct vpe_src_xy_packed {
+	uint32_t        src_x;
+	uint32_t        src_y;
+};
+
+struct vpe_input_plane_update_type {
+	struct vpe_src_size_packed             src_roi_size;
+	/* crop updates this set. */
+	struct vpe_src_xy_packed               src_roi_offset;
+	/* input address*/
+	uint8_t                         *src_p0_addr;
+	uint8_t                         *src_p1_addr;
+};
+
+struct vpe_msg_stats {
+	uint32_t    buffer;
+	uint32_t    frameCounter;
+};
+
+struct vpe_msg_output {
+	uint8_t   output_id;
+	uint32_t  yBuffer;
+	uint32_t  cbcrBuffer;
+	uint32_t  frameCounter;
+};
+
+struct vpe_message {
+	uint8_t  _d;
+	union {
+		struct vpe_msg_output              msgOut;
+		struct vpe_msg_stats               msgStats;
+	} _u;
+};
+
+#define SCALER_PHASE_BITS 29
+#define HAL_MDP_PHASE_STEP_2P50    0x50000000
+#define HAL_MDP_PHASE_STEP_1P66    0x35555555
+#define HAL_MDP_PHASE_STEP_1P25    0x28000000
+
+struct phase_val_t {
+	int32_t phase_init_x;
+	int32_t phase_init_y;
+	int32_t phase_step_x;
+	int32_t phase_step_y;
+};
+
+#endif /*_MSM_VPE_H_*/
+
diff --git a/drivers/media/platform/msm/camera_v1/msm_vpe1.c b/drivers/media/platform/msm/camera_v1/msm_vpe1.c
new file mode 100644
index 0000000..948f7ac
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/msm_vpe1.c
@@ -0,0 +1,1469 @@
+/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/uaccess.h>
+#include <linux/interrupt.h>
+#include <mach/irqs.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include "msm_vpe1.h"
+#include <linux/pm_qos.h>
+#include <linux/clk.h>
+#include <mach/clk.h>
+#include <asm/div64.h>
+
+static int vpe_enable(uint32_t);
+static int vpe_disable(void);
+static int vpe_update_scaler(struct video_crop_t *pcrop);
+static struct vpe_device_type  vpe_device_data;
+static struct vpe_device_type  *vpe_device;
+struct vpe_ctrl_type    *vpe_ctrl;
+char *vpe_general_cmd[] = {
+	"VPE_DUMMY_0",  /* 0 */
+	"VPE_SET_CLK",
+	"VPE_RESET",
+	"VPE_START",
+	"VPE_ABORT",
+	"VPE_OPERATION_MODE_CFG",  /* 5 */
+	"VPE_INPUT_PLANE_CFG",
+	"VPE_OUTPUT_PLANE_CFG",
+	"VPE_INPUT_PLANE_UPDATE",
+	"VPE_SCALE_CFG_TYPE",
+	"VPE_ROTATION_CFG_TYPE",  /* 10 */
+	"VPE_AXI_OUT_CFG",
+	"VPE_CMD_DIS_OFFSET_CFG",
+	"VPE_ENABLE",
+	"VPE_DISABLE",
+};
+static uint32_t orig_src_y, orig_src_cbcr;
+
+#define CHECKED_COPY_FROM_USER(in) {					\
+	if (copy_from_user((in), (void __user *)cmd->value,		\
+			cmd->length)) {					\
+		rc = -EFAULT;						\
+		break;							\
+	}								\
+}
+
+#define msm_dequeue_vpe(queue, member) ({			\
+	unsigned long flags;					\
+	struct msm_device_queue *__q = (queue);			\
+	struct msm_queue_cmd *qcmd = 0;				\
+	spin_lock_irqsave(&__q->lock, flags);			\
+	if (!list_empty(&__q->list)) {				\
+		__q->len--;					\
+		qcmd = list_first_entry(&__q->list,		\
+				struct msm_queue_cmd, member);	\
+		list_del_init(&qcmd->member);			\
+	}							\
+	spin_unlock_irqrestore(&__q->lock, flags);		\
+	qcmd;							\
+})
+
+/*
+static   struct vpe_cmd_type vpe_cmd[] = {
+		{VPE_DUMMY_0, 0},
+		{VPE_SET_CLK, 0},
+		{VPE_RESET, 0},
+		{VPE_START, 0},
+		{VPE_ABORT, 0},
+		{VPE_OPERATION_MODE_CFG, VPE_OPERATION_MODE_CFG_LEN},
+		{VPE_INPUT_PLANE_CFG, VPE_INPUT_PLANE_CFG_LEN},
+		{VPE_OUTPUT_PLANE_CFG, VPE_OUTPUT_PLANE_CFG_LEN},
+		{VPE_INPUT_PLANE_UPDATE, VPE_INPUT_PLANE_UPDATE_LEN},
+		{VPE_SCALE_CFG_TYPE, VPE_SCALER_CONFIG_LEN},
+		{VPE_ROTATION_CFG_TYPE, 0},
+		{VPE_AXI_OUT_CFG, 0},
+		{VPE_CMD_DIS_OFFSET_CFG, VPE_DIS_OFFSET_CFG_LEN},
+};
+*/
+
+static long long vpe_do_div(long long num, long long den)
+{
+	do_div(num, den);
+	return num;
+}
+
+static int vpe_start(void)
+{
+	/*  enable the frame irq, bit 0 = Display list 0 ROI done */
+	msm_camera_io_w(1, vpe_device->vpebase + VPE_INTR_ENABLE_OFFSET);
+	msm_camera_io_dump(vpe_device->vpebase + 0x10000, 0x250);
+	/* this triggers the operation. */
+	msm_camera_io_w(1, vpe_device->vpebase + VPE_DL0_START_OFFSET);
+
+	return 0;
+}
+
+void vpe_reset_state_variables(void)
+{
+	/* initialize local variables for state control, etc.*/
+	vpe_ctrl->op_mode = 0;
+	vpe_ctrl->state = VPE_STATE_INIT;
+	spin_lock_init(&vpe_ctrl->tasklet_lock);
+	spin_lock_init(&vpe_ctrl->state_lock);
+	INIT_LIST_HEAD(&vpe_ctrl->tasklet_q);
+}
+
+static void vpe_config_axi_default(void)
+{
+	msm_camera_io_w(0x25, vpe_device->vpebase + VPE_AXI_ARB_2_OFFSET);
+
+	CDBG("%s: yaddr %ld cbcraddr %ld", __func__,
+		 vpe_ctrl->out_y_addr, vpe_ctrl->out_cbcr_addr);
+
+	if (!vpe_ctrl->out_y_addr || !vpe_ctrl->out_cbcr_addr)
+		return;
+
+	msm_camera_io_w(vpe_ctrl->out_y_addr,
+		vpe_device->vpebase + VPE_OUTP0_ADDR_OFFSET);
+	/* for video  CbCr address */
+	msm_camera_io_w(vpe_ctrl->out_cbcr_addr,
+		vpe_device->vpebase + VPE_OUTP1_ADDR_OFFSET);
+
+}
+
+static int vpe_reset(void)
+{
+	uint32_t vpe_version;
+	uint32_t rc;
+
+	vpe_reset_state_variables();
+	vpe_version = msm_camera_io_r(
+			vpe_device->vpebase + VPE_HW_VERSION_OFFSET);
+	CDBG("vpe_version = 0x%x\n", vpe_version);
+
+	/* disable all interrupts.*/
+	msm_camera_io_w(0, vpe_device->vpebase + VPE_INTR_ENABLE_OFFSET);
+	/* clear all pending interrupts*/
+	msm_camera_io_w(0x1fffff, vpe_device->vpebase + VPE_INTR_CLEAR_OFFSET);
+
+	/* write sw_reset to reset the core. */
+	msm_camera_io_w(0x10, vpe_device->vpebase + VPE_SW_RESET_OFFSET);
+
+	/* then poll the reset bit, it should be self-cleared. */
+	while (1) {
+		rc = msm_camera_io_r(vpe_device->vpebase + VPE_SW_RESET_OFFSET)
+				& 0x10;
+		if (rc == 0)
+			break;
+	}
+
+	/*  at this point, hardware is reset. Then pogram to default
+		values. */
+	msm_camera_io_w(VPE_AXI_RD_ARB_CONFIG_VALUE,
+			vpe_device->vpebase + VPE_AXI_RD_ARB_CONFIG_OFFSET);
+
+	msm_camera_io_w(VPE_CGC_ENABLE_VALUE,
+			vpe_device->vpebase + VPE_CGC_EN_OFFSET);
+
+	msm_camera_io_w(1, vpe_device->vpebase + VPE_CMD_MODE_OFFSET);
+
+	msm_camera_io_w(VPE_DEFAULT_OP_MODE_VALUE,
+			vpe_device->vpebase + VPE_OP_MODE_OFFSET);
+
+	msm_camera_io_w(VPE_DEFAULT_SCALE_CONFIG,
+			vpe_device->vpebase + VPE_SCALE_CONFIG_OFFSET);
+
+	vpe_config_axi_default();
+	return 0;
+}
+
+int msm_vpe_cfg_update(void *pinfo)
+{
+	uint32_t  rot_flag, rc = 0;
+	struct video_crop_t *pcrop = (struct video_crop_t *)pinfo;
+
+	rot_flag = msm_camera_io_r(vpe_device->vpebase +
+						VPE_OP_MODE_OFFSET) & 0xE00;
+	if (pinfo != NULL) {
+		CDBG("Crop info in2_w = %d, in2_h = %d "
+			"out2_h = %d out2_w = %d \n", pcrop->in2_w,
+			pcrop->in2_h,
+			pcrop->out2_h, pcrop->out2_w);
+		rc = vpe_update_scaler(pcrop);
+	}
+	CDBG("return rc = %d rot_flag = %d\n", rc, rot_flag);
+	rc |= rot_flag;
+
+	return rc;
+}
+
+void vpe_update_scale_coef(uint32_t *p)
+{
+	uint32_t i, offset;
+	offset = *p;
+	for (i = offset; i < (VPE_SCALE_COEFF_NUM + offset); i++) {
+		msm_camera_io_w(*(++p),
+			vpe_device->vpebase + VPE_SCALE_COEFF_LSBn(i));
+		msm_camera_io_w(*(++p),
+			vpe_device->vpebase + VPE_SCALE_COEFF_MSBn(i));
+	}
+}
+
+void vpe_input_plane_config(uint32_t *p)
+{
+	msm_camera_io_w(*p,
+		vpe_device->vpebase + VPE_SRC_FORMAT_OFFSET);
+	msm_camera_io_w(*(++p),
+		vpe_device->vpebase + VPE_SRC_UNPACK_PATTERN1_OFFSET);
+	msm_camera_io_w(*(++p),
+		vpe_device->vpebase + VPE_SRC_IMAGE_SIZE_OFFSET);
+	msm_camera_io_w(*(++p),
+		vpe_device->vpebase + VPE_SRC_YSTRIDE1_OFFSET);
+	msm_camera_io_w(*(++p),
+		vpe_device->vpebase + VPE_SRC_SIZE_OFFSET);
+	vpe_ctrl->in_h_w = *p;
+	msm_camera_io_w(*(++p),
+		vpe_device->vpebase + VPE_SRC_XY_OFFSET);
+}
+
+void vpe_output_plane_config(uint32_t *p)
+{
+	msm_camera_io_w(*p,
+		vpe_device->vpebase + VPE_OUT_FORMAT_OFFSET);
+	msm_camera_io_w(*(++p),
+		vpe_device->vpebase + VPE_OUT_PACK_PATTERN1_OFFSET);
+	msm_camera_io_w(*(++p),
+		vpe_device->vpebase + VPE_OUT_YSTRIDE1_OFFSET);
+	msm_camera_io_w(*(++p),
+		vpe_device->vpebase + VPE_OUT_SIZE_OFFSET);
+	msm_camera_io_w(*(++p),
+		vpe_device->vpebase + VPE_OUT_XY_OFFSET);
+	vpe_ctrl->pcbcr_dis_offset = *(++p);
+}
+
+static int vpe_operation_config(uint32_t *p)
+{
+	uint32_t  outw, outh, temp;
+	msm_camera_io_w(*p, vpe_device->vpebase + VPE_OP_MODE_OFFSET);
+
+	temp = msm_camera_io_r(vpe_device->vpebase + VPE_OUT_SIZE_OFFSET);
+	outw = temp & 0xFFF;
+	outh = (temp & 0xFFF0000) >> 16;
+
+	if (*p++ & 0xE00) {
+		/* rotation enabled. */
+		vpe_ctrl->out_w = outh;
+		vpe_ctrl->out_h = outw;
+	} else {
+		vpe_ctrl->out_w = outw;
+		vpe_ctrl->out_h = outh;
+	}
+	vpe_ctrl->dis_en = *p;
+	return 0;
+}
+
+/* Later we can separate the rotation and scaler calc. If
+*  rotation is enabled, simply swap the destination dimension.
+*  And then pass the already swapped output size to this
+*  function. */
+static int vpe_update_scaler(struct video_crop_t *pcrop)
+{
+	uint32_t out_ROI_width, out_ROI_height;
+	uint32_t src_ROI_width, src_ROI_height;
+
+	uint32_t rc = 0;  /* default to no zoom. */
+	/*
+	* phase_step_x, phase_step_y, phase_init_x and phase_init_y
+	* are represented in fixed-point, unsigned 3.29 format
+	*/
+	uint32_t phase_step_x = 0;
+	uint32_t phase_step_y = 0;
+	uint32_t phase_init_x = 0;
+	uint32_t phase_init_y = 0;
+
+	uint32_t src_roi, src_x, src_y, src_xy, temp;
+	uint32_t yscale_filter_sel, xscale_filter_sel;
+	uint32_t scale_unit_sel_x, scale_unit_sel_y;
+	uint64_t numerator, denominator;
+
+	if ((pcrop->in2_w >= pcrop->out2_w) &&
+		(pcrop->in2_h >= pcrop->out2_h)) {
+		CDBG(" =======VPE no zoom needed.\n");
+
+		temp = msm_camera_io_r(vpe_device->vpebase + VPE_OP_MODE_OFFSET)
+		& 0xfffffffc;
+		msm_camera_io_w(temp, vpe_device->vpebase + VPE_OP_MODE_OFFSET);
+
+
+		msm_camera_io_w(0, vpe_device->vpebase + VPE_SRC_XY_OFFSET);
+
+		CDBG("vpe_ctrl->in_h_w = %d\n", vpe_ctrl->in_h_w);
+		msm_camera_io_w(vpe_ctrl->in_h_w , vpe_device->vpebase +
+				VPE_SRC_SIZE_OFFSET);
+
+		return rc;
+	}
+	/* If fall through then scaler is needed.*/
+
+	CDBG("========VPE zoom needed.\n");
+	/* assumption is both direction need zoom. this can be
+	improved. */
+	temp =
+		msm_camera_io_r(vpe_device->vpebase + VPE_OP_MODE_OFFSET) | 0x3;
+	msm_camera_io_w(temp, vpe_device->vpebase + VPE_OP_MODE_OFFSET);
+
+	src_ROI_width = pcrop->in2_w;
+	src_ROI_height = pcrop->in2_h;
+	out_ROI_width = pcrop->out2_w;
+	out_ROI_height = pcrop->out2_h;
+
+	CDBG("src w = 0x%x, h=0x%x, dst w = 0x%x, h =0x%x.\n",
+		src_ROI_width, src_ROI_height, out_ROI_width,
+		out_ROI_height);
+	src_roi = (src_ROI_height << 16) + src_ROI_width;
+
+	msm_camera_io_w(src_roi, vpe_device->vpebase + VPE_SRC_SIZE_OFFSET);
+
+	src_x = (out_ROI_width - src_ROI_width)/2;
+	src_y = (out_ROI_height - src_ROI_height)/2;
+
+	CDBG("src_x = %d, src_y=%d.\n", src_x, src_y);
+
+	src_xy = src_y*(1<<16) + src_x;
+	msm_camera_io_w(src_xy, vpe_device->vpebase +
+			VPE_SRC_XY_OFFSET);
+	CDBG("src_xy = %d, src_roi=%d.\n", src_xy, src_roi);
+
+	/* decide whether to use FIR or M/N for scaling */
+	if ((out_ROI_width == 1 && src_ROI_width < 4) ||
+		(src_ROI_width < 4 * out_ROI_width - 3))
+		scale_unit_sel_x = 0;/* use FIR scalar */
+	else
+		scale_unit_sel_x = 1;/* use M/N scalar */
+
+	if ((out_ROI_height == 1 && src_ROI_height < 4) ||
+		(src_ROI_height < 4 * out_ROI_height - 3))
+		scale_unit_sel_y = 0;/* use FIR scalar */
+	else
+		scale_unit_sel_y = 1;/* use M/N scalar */
+
+	/* calculate phase step for the x direction */
+
+	/* if destination is only 1 pixel wide,
+	the value of phase_step_x
+	is unimportant. Assigning phase_step_x to
+	src ROI width as an arbitrary value. */
+	if (out_ROI_width == 1)
+		phase_step_x = (uint32_t) ((src_ROI_width) <<
+						SCALER_PHASE_BITS);
+
+		/* if using FIR scalar */
+	else if (scale_unit_sel_x == 0) {
+
+		/* Calculate the quotient ( src_ROI_width - 1 )
+		/ ( out_ROI_width - 1)
+		with u3.29 precision. Quotient is rounded up to
+		the larger 29th decimal point. */
+		numerator = (uint64_t)(src_ROI_width - 1) <<
+			SCALER_PHASE_BITS;
+		/* never equals to 0 because of the
+		"(out_ROI_width == 1 )"*/
+		denominator = (uint64_t)(out_ROI_width - 1);
+		/* divide and round up to the larger 29th
+		decimal point. */
+		phase_step_x = (uint32_t) vpe_do_div((numerator +
+					denominator - 1), denominator);
+	} else if (scale_unit_sel_x == 1) { /* if M/N scalar */
+		/* Calculate the quotient ( src_ROI_width ) /
+		( out_ROI_width)
+		with u3.29 precision. Quotient is rounded down to the
+		smaller 29th decimal point. */
+		numerator = (uint64_t)(src_ROI_width) <<
+			SCALER_PHASE_BITS;
+		denominator = (uint64_t)(out_ROI_width);
+		phase_step_x =
+			(uint32_t) vpe_do_div(numerator, denominator);
+	}
+	/* calculate phase step for the y direction */
+
+	/* if destination is only 1 pixel wide, the value of
+		phase_step_x is unimportant. Assigning phase_step_x
+		to src ROI width as an arbitrary value. */
+	if (out_ROI_height == 1)
+		phase_step_y =
+		(uint32_t) ((src_ROI_height) << SCALER_PHASE_BITS);
+
+	/* if FIR scalar */
+	else if (scale_unit_sel_y == 0) {
+		/* Calculate the quotient ( src_ROI_height - 1 ) /
+		( out_ROI_height - 1)
+		with u3.29 precision. Quotient is rounded up to the
+		larger 29th decimal point. */
+		numerator = (uint64_t)(src_ROI_height - 1) <<
+			SCALER_PHASE_BITS;
+		/* never equals to 0 because of the "
+		( out_ROI_height == 1 )" case */
+		denominator = (uint64_t)(out_ROI_height - 1);
+		/* Quotient is rounded up to the larger
+		29th decimal point. */
+		phase_step_y =
+		(uint32_t) vpe_do_div(
+			(numerator + denominator - 1), denominator);
+	} else if (scale_unit_sel_y == 1) { /* if M/N scalar */
+		/* Calculate the quotient ( src_ROI_height )
+		/ ( out_ROI_height)
+		with u3.29 precision. Quotient is rounded down
+		to the smaller 29th decimal point. */
+		numerator = (uint64_t)(src_ROI_height) <<
+			SCALER_PHASE_BITS;
+		denominator = (uint64_t)(out_ROI_height);
+		phase_step_y = (uint32_t) vpe_do_div(
+			numerator, denominator);
+	}
+
+	/* decide which set of FIR coefficients to use */
+	if (phase_step_x > HAL_MDP_PHASE_STEP_2P50)
+		xscale_filter_sel = 0;
+	else if (phase_step_x > HAL_MDP_PHASE_STEP_1P66)
+		xscale_filter_sel = 1;
+	else if (phase_step_x > HAL_MDP_PHASE_STEP_1P25)
+		xscale_filter_sel = 2;
+	else
+		xscale_filter_sel = 3;
+
+	if (phase_step_y > HAL_MDP_PHASE_STEP_2P50)
+		yscale_filter_sel = 0;
+	else if (phase_step_y > HAL_MDP_PHASE_STEP_1P66)
+		yscale_filter_sel = 1;
+	else if (phase_step_y > HAL_MDP_PHASE_STEP_1P25)
+		yscale_filter_sel = 2;
+	else
+		yscale_filter_sel = 3;
+
+	/* calculate phase init for the x direction */
+
+	/* if using FIR scalar */
+	if (scale_unit_sel_x == 0) {
+		if (out_ROI_width == 1)
+			phase_init_x =
+				(uint32_t) ((src_ROI_width - 1) <<
+							SCALER_PHASE_BITS);
+		else
+			phase_init_x = 0;
+	} else if (scale_unit_sel_x == 1) /* M over N scalar  */
+		phase_init_x = 0;
+
+	/* calculate phase init for the y direction
+	if using FIR scalar */
+	if (scale_unit_sel_y == 0) {
+		if (out_ROI_height == 1)
+			phase_init_y =
+			(uint32_t) ((src_ROI_height -
+						1) << SCALER_PHASE_BITS);
+		else
+			phase_init_y = 0;
+	} else if (scale_unit_sel_y == 1) /* M over N scalar   */
+		phase_init_y = 0;
+
+	CDBG("phase step x = %d, step y = %d.\n",
+		 phase_step_x, phase_step_y);
+	CDBG("phase init x = %d, init y = %d.\n",
+		 phase_init_x, phase_init_y);
+
+	msm_camera_io_w(phase_step_x, vpe_device->vpebase +
+			VPE_SCALE_PHASEX_STEP_OFFSET);
+	msm_camera_io_w(phase_step_y, vpe_device->vpebase +
+			VPE_SCALE_PHASEY_STEP_OFFSET);
+
+	msm_camera_io_w(phase_init_x, vpe_device->vpebase +
+			VPE_SCALE_PHASEX_INIT_OFFSET);
+
+	msm_camera_io_w(phase_init_y, vpe_device->vpebase +
+			VPE_SCALE_PHASEY_INIT_OFFSET);
+
+	return 1;
+}
+
+static int vpe_update_scaler_with_dis(struct video_crop_t *pcrop,
+				struct dis_offset_type *dis_offset)
+{
+	uint32_t out_ROI_width, out_ROI_height;
+	uint32_t src_ROI_width, src_ROI_height;
+
+	uint32_t rc = 0;  /* default to no zoom. */
+	/*
+	* phase_step_x, phase_step_y, phase_init_x and phase_init_y
+	* are represented in fixed-point, unsigned 3.29 format
+	*/
+	uint32_t phase_step_x = 0;
+	uint32_t phase_step_y = 0;
+	uint32_t phase_init_x = 0;
+	uint32_t phase_init_y = 0;
+
+	uint32_t src_roi, temp;
+	int32_t  src_x, src_y, src_xy;
+	uint32_t yscale_filter_sel, xscale_filter_sel;
+	uint32_t scale_unit_sel_x, scale_unit_sel_y;
+	uint64_t numerator, denominator;
+	int32_t  zoom_dis_x, zoom_dis_y;
+
+	CDBG("%s: pcrop->in2_w = %d, pcrop->in2_h = %d\n", __func__,
+		 pcrop->in2_w, pcrop->in2_h);
+	CDBG("%s: pcrop->out2_w = %d, pcrop->out2_h = %d\n", __func__,
+		 pcrop->out2_w, pcrop->out2_h);
+
+	if ((pcrop->in2_w >= pcrop->out2_w) &&
+		(pcrop->in2_h >= pcrop->out2_h)) {
+		CDBG(" =======VPE no zoom needed, DIS is still enabled.\n");
+
+		temp = msm_camera_io_r(vpe_device->vpebase + VPE_OP_MODE_OFFSET)
+		& 0xfffffffc;
+		msm_camera_io_w(temp, vpe_device->vpebase + VPE_OP_MODE_OFFSET);
+
+		/* no zoom, use dis offset directly. */
+		src_xy = dis_offset->dis_offset_y * (1<<16) +
+			dis_offset->dis_offset_x;
+
+		msm_camera_io_w(src_xy,
+			vpe_device->vpebase + VPE_SRC_XY_OFFSET);
+
+		CDBG("vpe_ctrl->in_h_w = 0x%x\n", vpe_ctrl->in_h_w);
+		msm_camera_io_w(vpe_ctrl->in_h_w,
+			vpe_device->vpebase + VPE_SRC_SIZE_OFFSET);
+		return rc;
+	}
+	/* If fall through then scaler is needed.*/
+
+	CDBG("========VPE zoom needed + DIS enabled.\n");
+	/* assumption is both direction need zoom. this can be
+	 improved. */
+	temp = msm_camera_io_r(vpe_device->vpebase +
+					VPE_OP_MODE_OFFSET) | 0x3;
+	msm_camera_io_w(temp, vpe_device->vpebase +
+			VPE_OP_MODE_OFFSET);
+	zoom_dis_x = dis_offset->dis_offset_x *
+		pcrop->in2_w / pcrop->out2_w;
+	zoom_dis_y = dis_offset->dis_offset_y *
+		pcrop->in2_h / pcrop->out2_h;
+
+	src_x = zoom_dis_x + (pcrop->out2_w-pcrop->in2_w)/2;
+	src_y = zoom_dis_y + (pcrop->out2_h-pcrop->in2_h)/2;
+
+	out_ROI_width = vpe_ctrl->out_w;
+	out_ROI_height = vpe_ctrl->out_h;
+
+	src_ROI_width = out_ROI_width * pcrop->in2_w / pcrop->out2_w;
+	src_ROI_height = out_ROI_height * pcrop->in2_h / pcrop->out2_h;
+
+	/* clamp to output size.  This is because along
+	processing, we mostly do truncation, therefore
+	dis_offset tends to be
+	smaller values.  The intention was to make sure that the
+	offset does not exceed margin.   But in the case it could
+	result src_roi bigger, due to subtract a smaller value. */
+	CDBG("src w = 0x%x, h=0x%x, dst w = 0x%x, h =0x%x.\n",
+		src_ROI_width, src_ROI_height, out_ROI_width,
+		out_ROI_height);
+
+	src_roi = (src_ROI_height << 16) + src_ROI_width;
+
+	msm_camera_io_w(src_roi, vpe_device->vpebase + VPE_SRC_SIZE_OFFSET);
+
+	CDBG("src_x = %d, src_y=%d.\n", src_x, src_y);
+
+	src_xy = src_y*(1<<16) + src_x;
+	msm_camera_io_w(src_xy, vpe_device->vpebase +
+			VPE_SRC_XY_OFFSET);
+	CDBG("src_xy = 0x%x, src_roi=0x%x.\n", src_xy, src_roi);
+
+	/* decide whether to use FIR or M/N for scaling */
+	if ((out_ROI_width == 1 && src_ROI_width < 4) ||
+		(src_ROI_width < 4 * out_ROI_width - 3))
+		scale_unit_sel_x = 0;/* use FIR scalar */
+	else
+		scale_unit_sel_x = 1;/* use M/N scalar */
+
+	if ((out_ROI_height == 1 && src_ROI_height < 4) ||
+		(src_ROI_height < 4 * out_ROI_height - 3))
+		scale_unit_sel_y = 0;/* use FIR scalar */
+	else
+		scale_unit_sel_y = 1;/* use M/N scalar */
+	/* calculate phase step for the x direction */
+
+	/* if destination is only 1 pixel wide, the value of
+	phase_step_x is unimportant. Assigning phase_step_x
+	to src ROI width as an arbitrary value. */
+	if (out_ROI_width == 1)
+		phase_step_x = (uint32_t) ((src_ROI_width) <<
+							SCALER_PHASE_BITS);
+	else if (scale_unit_sel_x == 0) { /* if using FIR scalar */
+		/* Calculate the quotient ( src_ROI_width - 1 )
+		/ ( out_ROI_width - 1)with u3.29 precision.
+		Quotient is rounded up to the larger
+		29th decimal point. */
+		numerator =
+			(uint64_t)(src_ROI_width - 1) <<
+			SCALER_PHASE_BITS;
+		/* never equals to 0 because of the "
+		(out_ROI_width == 1 )"*/
+		denominator = (uint64_t)(out_ROI_width - 1);
+		/* divide and round up to the larger 29th
+		decimal point. */
+		phase_step_x = (uint32_t) vpe_do_div(
+			(numerator + denominator - 1), denominator);
+	} else if (scale_unit_sel_x == 1) { /* if M/N scalar */
+		/* Calculate the quotient
+		( src_ROI_width ) / ( out_ROI_width)
+		with u3.29 precision. Quotient is rounded
+		down to the smaller 29th decimal point. */
+		numerator = (uint64_t)(src_ROI_width) <<
+			SCALER_PHASE_BITS;
+		denominator = (uint64_t)(out_ROI_width);
+		phase_step_x =
+			(uint32_t) vpe_do_div(numerator, denominator);
+	}
+	/* calculate phase step for the y direction */
+
+	/* if destination is only 1 pixel wide, the value of
+		phase_step_x is unimportant. Assigning phase_step_x
+		to src ROI width as an arbitrary value. */
+	if (out_ROI_height == 1)
+		phase_step_y =
+		(uint32_t) ((src_ROI_height) << SCALER_PHASE_BITS);
+	else if (scale_unit_sel_y == 0) { /* if FIR scalar */
+		/* Calculate the quotient
+		( src_ROI_height - 1 ) / ( out_ROI_height - 1)
+		with u3.29 precision. Quotient is rounded up to the
+		larger 29th decimal point. */
+		numerator = (uint64_t)(src_ROI_height - 1) <<
+			SCALER_PHASE_BITS;
+		/* never equals to 0 because of the
+		"( out_ROI_height == 1 )" case */
+		denominator = (uint64_t)(out_ROI_height - 1);
+		/* Quotient is rounded up to the larger 29th
+		decimal point. */
+		phase_step_y =
+		(uint32_t) vpe_do_div(
+		(numerator + denominator - 1), denominator);
+	} else if (scale_unit_sel_y == 1) { /* if M/N scalar */
+		/* Calculate the quotient ( src_ROI_height ) / ( out_ROI_height)
+		with u3.29 precision. Quotient is rounded down to the smaller
+		29th decimal point. */
+		numerator = (uint64_t)(src_ROI_height) <<
+			SCALER_PHASE_BITS;
+		denominator = (uint64_t)(out_ROI_height);
+		phase_step_y = (uint32_t) vpe_do_div(
+			numerator, denominator);
+	}
+
+	/* decide which set of FIR coefficients to use */
+	if (phase_step_x > HAL_MDP_PHASE_STEP_2P50)
+		xscale_filter_sel = 0;
+	else if (phase_step_x > HAL_MDP_PHASE_STEP_1P66)
+		xscale_filter_sel = 1;
+	else if (phase_step_x > HAL_MDP_PHASE_STEP_1P25)
+		xscale_filter_sel = 2;
+	else
+		xscale_filter_sel = 3;
+
+	if (phase_step_y > HAL_MDP_PHASE_STEP_2P50)
+		yscale_filter_sel = 0;
+	else if (phase_step_y > HAL_MDP_PHASE_STEP_1P66)
+		yscale_filter_sel = 1;
+	else if (phase_step_y > HAL_MDP_PHASE_STEP_1P25)
+		yscale_filter_sel = 2;
+	else
+		yscale_filter_sel = 3;
+
+	/* calculate phase init for the x direction */
+
+	/* if using FIR scalar */
+	if (scale_unit_sel_x == 0) {
+		if (out_ROI_width == 1)
+			phase_init_x =
+			(uint32_t) ((src_ROI_width - 1) <<
+						SCALER_PHASE_BITS);
+		else
+			phase_init_x = 0;
+
+	} else if (scale_unit_sel_x == 1) /* M over N scalar  */
+		phase_init_x = 0;
+
+	/* calculate phase init for the y direction
+	if using FIR scalar */
+	if (scale_unit_sel_y == 0) {
+		if (out_ROI_height == 1)
+			phase_init_y =
+			(uint32_t) ((src_ROI_height -
+						1) << SCALER_PHASE_BITS);
+		else
+			phase_init_y = 0;
+
+	} else if (scale_unit_sel_y == 1) /* M over N scalar   */
+		phase_init_y = 0;
+
+	CDBG("phase step x = %d, step y = %d.\n",
+		phase_step_x, phase_step_y);
+	CDBG("phase init x = %d, init y = %d.\n",
+		phase_init_x, phase_init_y);
+
+	msm_camera_io_w(phase_step_x, vpe_device->vpebase +
+			VPE_SCALE_PHASEX_STEP_OFFSET);
+
+	msm_camera_io_w(phase_step_y, vpe_device->vpebase +
+			VPE_SCALE_PHASEY_STEP_OFFSET);
+
+	msm_camera_io_w(phase_init_x, vpe_device->vpebase +
+			VPE_SCALE_PHASEX_INIT_OFFSET);
+
+	msm_camera_io_w(phase_init_y, vpe_device->vpebase +
+			VPE_SCALE_PHASEY_INIT_OFFSET);
+
+	return 1;
+}
+
+void msm_send_frame_to_vpe(uint32_t p0_phy_add, uint32_t p1_phy_add,
+		struct timespec *ts, int output_type)
+{
+	uint32_t temp_pyaddr = 0, temp_pcbcraddr = 0;
+
+	CDBG("vpe input, p0_phy_add = 0x%x, p1_phy_add = 0x%x\n",
+		p0_phy_add, p1_phy_add);
+	msm_camera_io_w(p0_phy_add,
+		vpe_device->vpebase + VPE_SRCP0_ADDR_OFFSET);
+	msm_camera_io_w(p1_phy_add,
+		vpe_device->vpebase + VPE_SRCP1_ADDR_OFFSET);
+
+	if (vpe_ctrl->state == VPE_STATE_ACTIVE)
+		CDBG(" =====VPE is busy!!!  Wrong!========\n");
+
+	if (output_type != OUTPUT_TYPE_ST_R)
+		vpe_ctrl->ts = *ts;
+
+	if (output_type == OUTPUT_TYPE_ST_L) {
+		vpe_ctrl->pcbcr_before_dis =
+			msm_camera_io_r(vpe_device->vpebase +
+			VPE_OUTP1_ADDR_OFFSET);
+		temp_pyaddr = msm_camera_io_r(vpe_device->vpebase +
+			VPE_OUTP0_ADDR_OFFSET);
+		temp_pcbcraddr = temp_pyaddr + PAD_TO_2K(vpe_ctrl->out_w *
+			vpe_ctrl->out_h * 2, vpe_ctrl->pad_2k_bool);
+		msm_camera_io_w(temp_pcbcraddr, vpe_device->vpebase +
+			VPE_OUTP1_ADDR_OFFSET);
+	}
+
+	if (vpe_ctrl->dis_en) {
+		/* Changing the VPE output CBCR address,
+		to make Y/CBCR continuous */
+		vpe_ctrl->pcbcr_before_dis =
+			msm_camera_io_r(vpe_device->vpebase +
+			VPE_OUTP1_ADDR_OFFSET);
+		temp_pyaddr = msm_camera_io_r(vpe_device->vpebase +
+			VPE_OUTP0_ADDR_OFFSET);
+		temp_pcbcraddr = temp_pyaddr + vpe_ctrl->pcbcr_dis_offset;
+		msm_camera_io_w(temp_pcbcraddr, vpe_device->vpebase +
+			VPE_OUTP1_ADDR_OFFSET);
+	}
+
+	vpe_ctrl->output_type = output_type;
+	vpe_ctrl->state = VPE_STATE_ACTIVE;
+	vpe_start();
+}
+
+static int vpe_proc_general(struct msm_vpe_cmd *cmd)
+{
+	int rc = 0;
+	uint32_t *cmdp = NULL;
+	struct msm_queue_cmd *qcmd = NULL;
+	struct msm_vpe_buf_info *vpe_buf;
+	int turbo_mode = 0;
+	struct msm_sync *sync = (struct msm_sync *)vpe_ctrl->syncdata;
+	CDBG("vpe_proc_general: cmdID = %s, length = %d\n",
+		vpe_general_cmd[cmd->id], cmd->length);
+	switch (cmd->id) {
+	case VPE_ENABLE:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto vpe_proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto vpe_proc_general_done;
+		}
+		turbo_mode = *((int *)(cmd->value));
+		rc = turbo_mode ? vpe_enable(VPE_TURBO_MODE_CLOCK_RATE)
+			: vpe_enable(VPE_NORMAL_MODE_CLOCK_RATE);
+		break;
+	case VPE_DISABLE:
+		rc = vpe_disable();
+		break;
+	case VPE_RESET:
+	case VPE_ABORT:
+		rc = vpe_reset();
+		break;
+	case VPE_START:
+		rc = vpe_start();
+		break;
+
+	case VPE_INPUT_PLANE_CFG:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto vpe_proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto vpe_proc_general_done;
+		}
+		vpe_input_plane_config(cmdp);
+		break;
+
+	case VPE_OPERATION_MODE_CFG:
+		CDBG("cmd->length = %d \n", cmd->length);
+		if (cmd->length != VPE_OPERATION_MODE_CFG_LEN) {
+			rc = -EINVAL;
+			goto vpe_proc_general_done;
+		}
+		cmdp = kmalloc(VPE_OPERATION_MODE_CFG_LEN,
+					GFP_ATOMIC);
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			VPE_OPERATION_MODE_CFG_LEN)) {
+			rc = -EFAULT;
+			goto vpe_proc_general_done;
+		}
+		rc = vpe_operation_config(cmdp);
+		CDBG("rc = %d \n", rc);
+		break;
+
+	case VPE_OUTPUT_PLANE_CFG:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto vpe_proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto vpe_proc_general_done;
+		}
+		vpe_output_plane_config(cmdp);
+		break;
+
+	case VPE_SCALE_CFG_TYPE:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto vpe_proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto vpe_proc_general_done;
+		}
+		vpe_update_scale_coef(cmdp);
+		break;
+
+	case VPE_CMD_DIS_OFFSET_CFG: {
+		struct msm_vfe_resp *vdata;
+		/* first get the dis offset and frame id. */
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto vpe_proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto vpe_proc_general_done;
+		}
+		/* get the offset. */
+		vpe_ctrl->dis_offset = *(struct dis_offset_type *)cmdp;
+		qcmd = msm_dequeue_vpe(&sync->vpe_q, list_vpe_frame);
+		if (!qcmd) {
+			pr_err("%s: no video frame.\n", __func__);
+			kfree(cmdp);
+			return -EAGAIN;
+		}
+		vdata = (struct msm_vfe_resp *)(qcmd->command);
+		vpe_buf = &vdata->vpe_bf;
+		vpe_update_scaler_with_dis(&(vpe_buf->vpe_crop),
+					&(vpe_ctrl->dis_offset));
+
+		msm_send_frame_to_vpe(vpe_buf->p0_phy, vpe_buf->p1_phy,
+						&(vpe_buf->ts), OUTPUT_TYPE_V);
+
+		if (!qcmd || !atomic_read(&qcmd->on_heap)) {
+			kfree(cmdp);
+			return -EAGAIN;
+		}
+		if (!atomic_sub_return(1, &qcmd->on_heap))
+			kfree(qcmd);
+		break;
+	}
+
+	default:
+		break;
+	}
+vpe_proc_general_done:
+	kfree(cmdp);
+	return rc;
+}
+
+static void vpe_addr_convert(struct msm_vpe_phy_info *pinfo,
+	enum vpe_resp_msg type, void *data, void **ext, int32_t *elen)
+{
+	CDBG("In vpe_addr_convert type = %d\n", type);
+	switch (type) {
+	case VPE_MSG_OUTPUT_V:
+		pinfo->output_id = OUTPUT_TYPE_V;
+		break;
+	case VPE_MSG_OUTPUT_ST_R:
+		/* output_id will be used by user space only. */
+		pinfo->output_id = OUTPUT_TYPE_V;
+		break;
+	default:
+		break;
+	} /* switch */
+
+	CDBG("In vpe_addr_convert output_id = %d\n", pinfo->output_id);
+
+	pinfo->p0_phy =
+		((struct vpe_message *)data)->_u.msgOut.p0_Buffer;
+	pinfo->p1_phy =
+		((struct vpe_message *)data)->_u.msgOut.p1_Buffer;
+	*ext  = vpe_ctrl->extdata;
+	*elen = vpe_ctrl->extlen;
+}
+
+void vpe_proc_ops(uint8_t id, void *msg, size_t len)
+{
+	struct msm_vpe_resp *rp;
+
+	rp = vpe_ctrl->resp->vpe_alloc(sizeof(struct msm_vpe_resp),
+		vpe_ctrl->syncdata, GFP_ATOMIC);
+	if (!rp) {
+		CDBG("rp: cannot allocate buffer\n");
+		return;
+	}
+
+	CDBG("vpe_proc_ops, msgId = %d rp->evt_msg.msg_id = %d\n",
+		id, rp->evt_msg.msg_id);
+	rp->evt_msg.type   = MSM_CAMERA_MSG;
+	rp->evt_msg.msg_id = id;
+	rp->evt_msg.len    = len;
+	rp->evt_msg.data   = msg;
+
+	switch (rp->evt_msg.msg_id) {
+	case MSG_ID_VPE_OUTPUT_V:
+		rp->type = VPE_MSG_OUTPUT_V;
+		vpe_addr_convert(&(rp->phy), VPE_MSG_OUTPUT_V,
+			rp->evt_msg.data, &(rp->extdata),
+			&(rp->extlen));
+		break;
+
+	case MSG_ID_VPE_OUTPUT_ST_R:
+		rp->type = VPE_MSG_OUTPUT_ST_R;
+		vpe_addr_convert(&(rp->phy), VPE_MSG_OUTPUT_ST_R,
+			rp->evt_msg.data, &(rp->extdata),
+			&(rp->extlen));
+		break;
+
+	case MSG_ID_VPE_OUTPUT_ST_L:
+		rp->type = VPE_MSG_OUTPUT_ST_L;
+		break;
+
+	default:
+		rp->type = VPE_MSG_GENERAL;
+		break;
+	}
+	CDBG("%s: time = %ld\n",
+			__func__, vpe_ctrl->ts.tv_nsec);
+
+	vpe_ctrl->resp->vpe_resp(rp, MSM_CAM_Q_VPE_MSG,
+					vpe_ctrl->syncdata,
+					&(vpe_ctrl->ts), GFP_ATOMIC);
+}
+
+int vpe_config_axi(struct axidata *ad)
+{
+	uint32_t p1;
+	struct msm_pmem_region *regp1 = NULL;
+	CDBG("vpe_config_axi:bufnum1 = %d.\n", ad->bufnum1);
+
+	if (ad->bufnum1 != 1)
+		return -EINVAL;
+
+	regp1 = &(ad->region[0]);
+	/* for video  Y address */
+	p1 = (regp1->paddr + regp1->info.planar0_off);
+	msm_camera_io_w(p1, vpe_device->vpebase + VPE_OUTP0_ADDR_OFFSET);
+	/* for video  CbCr address */
+	p1 = (regp1->paddr + regp1->info.planar1_off);
+	msm_camera_io_w(p1, vpe_device->vpebase + VPE_OUTP1_ADDR_OFFSET);
+
+	return 0;
+}
+
+int msm_vpe_config(struct msm_vpe_cfg_cmd *cmd, void *data)
+{
+	struct msm_vpe_cmd vpecmd;
+	int rc = 0;
+	if (copy_from_user(&vpecmd,
+			(void __user *)(cmd->value),
+			sizeof(vpecmd))) {
+		pr_err("%s %d: copy_from_user failed\n", __func__,
+				__LINE__);
+		return -EFAULT;
+	}
+	CDBG("%s: cmd_type %d\n", __func__, cmd->cmd_type);
+	switch (cmd->cmd_type) {
+	case CMD_VPE:
+		rc = vpe_proc_general(&vpecmd);
+		CDBG(" rc = %d\n", rc);
+		break;
+
+	case CMD_AXI_CFG_VPE:
+	case CMD_AXI_CFG_SNAP_VPE:
+	case CMD_AXI_CFG_SNAP_THUMB_VPE: {
+		struct axidata *axid;
+		axid = data;
+		if (!axid)
+			return -EFAULT;
+		vpe_config_axi(axid);
+		break;
+	}
+	default:
+		break;
+	}
+	CDBG("%s: rc = %d\n", __func__, rc);
+	return rc;
+}
+
+void msm_vpe_offset_update(int frame_pack, uint32_t pyaddr, uint32_t pcbcraddr,
+	struct timespec *ts, int output_id, struct msm_st_half st_half,
+	int frameid)
+{
+	struct msm_vpe_buf_info vpe_buf;
+	uint32_t input_stride;
+
+	vpe_buf.vpe_crop.in2_w = st_half.stCropInfo.in_w;
+	vpe_buf.vpe_crop.in2_h = st_half.stCropInfo.in_h;
+	vpe_buf.vpe_crop.out2_w = st_half.stCropInfo.out_w;
+	vpe_buf.vpe_crop.out2_h = st_half.stCropInfo.out_h;
+	vpe_ctrl->dis_offset.dis_offset_x = st_half.pix_x_off;
+	vpe_ctrl->dis_offset.dis_offset_y = st_half.pix_y_off;
+	vpe_ctrl->dis_offset.frame_id = frameid;
+	vpe_ctrl->frame_pack = frame_pack;
+	vpe_ctrl->output_type = output_id;
+
+	input_stride = (st_half.buf_p1_stride * (1<<16)) +
+		st_half.buf_p0_stride;
+
+	msm_camera_io_w(input_stride,
+		vpe_device->vpebase + VPE_SRC_YSTRIDE1_OFFSET);
+
+	vpe_update_scaler_with_dis(&(vpe_buf.vpe_crop),
+		&(vpe_ctrl->dis_offset));
+
+	msm_send_frame_to_vpe(pyaddr, pcbcraddr, ts, output_id);
+}
+
+static void vpe_send_outmsg(uint8_t msgid, uint32_t p0_addr,
+	uint32_t p1_addr, uint32_t p2_addr)
+{
+	struct vpe_message msg;
+	uint8_t outid;
+	msg._d = outid = msgid;
+	msg._u.msgOut.output_id   = msgid;
+	msg._u.msgOut.p0_Buffer = p0_addr;
+	msg._u.msgOut.p1_Buffer = p1_addr;
+	msg._u.msgOut.p2_Buffer = p2_addr;
+	vpe_proc_ops(outid, &msg, sizeof(struct vpe_message));
+	return;
+}
+
+int msm_vpe_reg(struct msm_vpe_callback *presp)
+{
+	if (presp && presp->vpe_resp)
+		vpe_ctrl->resp = presp;
+
+	return 0;
+}
+
+static void vpe_send_msg_no_payload(enum VPE_MESSAGE_ID id)
+{
+	struct vpe_message msg;
+
+	CDBG("vfe31_send_msg_no_payload\n");
+	msg._d = id;
+	vpe_proc_ops(id, &msg, 0);
+}
+
+static void vpe_do_tasklet(unsigned long data)
+{
+	unsigned long flags;
+	uint32_t pyaddr = 0, pcbcraddr = 0;
+	uint32_t src_y, src_cbcr, temp;
+
+	struct vpe_isr_queue_cmd_type *qcmd = NULL;
+
+	CDBG("=== vpe_do_tasklet start === \n");
+
+	spin_lock_irqsave(&vpe_ctrl->tasklet_lock, flags);
+	qcmd = list_first_entry(&vpe_ctrl->tasklet_q,
+		struct vpe_isr_queue_cmd_type, list);
+
+	if (!qcmd) {
+		spin_unlock_irqrestore(&vpe_ctrl->tasklet_lock, flags);
+		return;
+	}
+
+	list_del(&qcmd->list);
+	spin_unlock_irqrestore(&vpe_ctrl->tasklet_lock, flags);
+
+	/* interrupt to be processed,  *qcmd has the payload.  */
+	if (qcmd->irq_status & 0x1) {
+		if (vpe_ctrl->output_type == OUTPUT_TYPE_ST_L) {
+			CDBG("vpe left frame done.\n");
+			vpe_ctrl->output_type = 0;
+			CDBG("vpe send out msg.\n");
+			orig_src_y = msm_camera_io_r(vpe_device->vpebase +
+				VPE_SRCP0_ADDR_OFFSET);
+			orig_src_cbcr = msm_camera_io_r(vpe_device->vpebase +
+				VPE_SRCP1_ADDR_OFFSET);
+
+			pyaddr = msm_camera_io_r(vpe_device->vpebase +
+				VPE_OUTP0_ADDR_OFFSET);
+			pcbcraddr = msm_camera_io_r(vpe_device->vpebase +
+				VPE_OUTP1_ADDR_OFFSET);
+			CDBG("%s: out_w = %d, out_h = %d\n", __func__,
+				vpe_ctrl->out_w, vpe_ctrl->out_h);
+
+			if ((vpe_ctrl->frame_pack == TOP_DOWN_FULL) ||
+				(vpe_ctrl->frame_pack == TOP_DOWN_HALF)) {
+				msm_camera_io_w(pyaddr + (vpe_ctrl->out_w *
+					vpe_ctrl->out_h), vpe_device->vpebase +
+					VPE_OUTP0_ADDR_OFFSET);
+				msm_camera_io_w(pcbcraddr + (vpe_ctrl->out_w *
+					vpe_ctrl->out_h/2),
+					vpe_device->vpebase +
+					VPE_OUTP1_ADDR_OFFSET);
+			} else if ((vpe_ctrl->frame_pack ==
+				SIDE_BY_SIDE_HALF) || (vpe_ctrl->frame_pack ==
+				SIDE_BY_SIDE_FULL)) {
+				msm_camera_io_w(pyaddr + vpe_ctrl->out_w,
+					vpe_device->vpebase +
+					VPE_OUTP0_ADDR_OFFSET);
+				msm_camera_io_w(pcbcraddr + vpe_ctrl->out_w,
+					vpe_device->vpebase +
+					VPE_OUTP1_ADDR_OFFSET);
+			} else
+				CDBG("%s: Invalid packing = %d\n", __func__,
+					vpe_ctrl->frame_pack);
+
+			vpe_send_msg_no_payload(MSG_ID_VPE_OUTPUT_ST_L);
+			vpe_ctrl->state = VPE_STATE_INIT;
+			kfree(qcmd);
+			return;
+		} else if (vpe_ctrl->output_type == OUTPUT_TYPE_ST_R) {
+			src_y = orig_src_y;
+			src_cbcr = orig_src_cbcr;
+			CDBG("%s: out_w = %d, out_h = %d\n", __func__,
+				vpe_ctrl->out_w, vpe_ctrl->out_h);
+
+			if ((vpe_ctrl->frame_pack == TOP_DOWN_FULL) ||
+				(vpe_ctrl->frame_pack == TOP_DOWN_HALF)) {
+				pyaddr = msm_camera_io_r(vpe_device->vpebase +
+					VPE_OUTP0_ADDR_OFFSET) -
+					(vpe_ctrl->out_w * vpe_ctrl->out_h);
+			} else if ((vpe_ctrl->frame_pack ==
+				SIDE_BY_SIDE_HALF) || (vpe_ctrl->frame_pack ==
+				SIDE_BY_SIDE_FULL)) {
+				pyaddr = msm_camera_io_r(vpe_device->vpebase +
+				VPE_OUTP0_ADDR_OFFSET) - vpe_ctrl->out_w;
+			} else
+				CDBG("%s: Invalid packing = %d\n", __func__,
+					vpe_ctrl->frame_pack);
+
+			pcbcraddr = vpe_ctrl->pcbcr_before_dis;
+		} else {
+			src_y =	msm_camera_io_r(vpe_device->vpebase +
+				VPE_SRCP0_ADDR_OFFSET);
+			src_cbcr = msm_camera_io_r(vpe_device->vpebase +
+				VPE_SRCP1_ADDR_OFFSET);
+			pyaddr = msm_camera_io_r(vpe_device->vpebase +
+				VPE_OUTP0_ADDR_OFFSET);
+			pcbcraddr = msm_camera_io_r(vpe_device->vpebase +
+				VPE_OUTP1_ADDR_OFFSET);
+		}
+
+		if (vpe_ctrl->dis_en)
+			pcbcraddr = vpe_ctrl->pcbcr_before_dis;
+
+		msm_camera_io_w(src_y,
+				vpe_device->vpebase + VPE_OUTP0_ADDR_OFFSET);
+		msm_camera_io_w(src_cbcr,
+				vpe_device->vpebase + VPE_OUTP1_ADDR_OFFSET);
+
+		temp = msm_camera_io_r(vpe_device->vpebase + VPE_OP_MODE_OFFSET)
+				& 0xFFFFFFFC;
+		msm_camera_io_w(temp, vpe_device->vpebase + VPE_OP_MODE_OFFSET);
+
+		/*  now pass this frame to msm_camera.c. */
+		if (vpe_ctrl->output_type == OUTPUT_TYPE_ST_R) {
+			CDBG("vpe send out R msg.\n");
+			vpe_send_outmsg(MSG_ID_VPE_OUTPUT_ST_R, pyaddr,
+				pcbcraddr, pyaddr);
+		} else if (vpe_ctrl->output_type == OUTPUT_TYPE_V) {
+			CDBG("vpe send out V msg.\n");
+			vpe_send_outmsg(MSG_ID_VPE_OUTPUT_V, pyaddr,
+				pcbcraddr, pyaddr);
+		}
+
+		vpe_ctrl->output_type = 0;
+		vpe_ctrl->state = VPE_STATE_INIT;   /* put it back to idle. */
+
+	}
+	kfree(qcmd);
+}
+DECLARE_TASKLET(vpe_tasklet, vpe_do_tasklet, 0);
+
+static irqreturn_t vpe_parse_irq(int irq_num, void *data)
+{
+	unsigned long flags;
+	uint32_t irq_status = 0;
+	struct vpe_isr_queue_cmd_type *qcmd;
+
+	CDBG("vpe_parse_irq.\n");
+	/* read and clear back-to-back. */
+	irq_status = msm_camera_io_r_mb(vpe_device->vpebase +
+							VPE_INTR_STATUS_OFFSET);
+	msm_camera_io_w_mb(irq_status, vpe_device->vpebase +
+				VPE_INTR_CLEAR_OFFSET);
+
+	msm_camera_io_w(0, vpe_device->vpebase + VPE_INTR_ENABLE_OFFSET);
+
+	if (irq_status == 0) {
+		pr_err("%s: irq_status = 0,Something is wrong!\n", __func__);
+		return IRQ_HANDLED;
+	}
+	irq_status &= 0x1;
+	/* apply mask. only interested in bit 0.  */
+	if (irq_status) {
+		qcmd = kzalloc(sizeof(struct vpe_isr_queue_cmd_type),
+			GFP_ATOMIC);
+		if (!qcmd) {
+			pr_err("%s: qcmd malloc failed!\n", __func__);
+			return IRQ_HANDLED;
+		}
+		/* must be 0x1 now. so in bottom half we don't really
+		need to check. */
+		qcmd->irq_status = irq_status & 0x1;
+		spin_lock_irqsave(&vpe_ctrl->tasklet_lock, flags);
+		list_add_tail(&qcmd->list, &vpe_ctrl->tasklet_q);
+		spin_unlock_irqrestore(&vpe_ctrl->tasklet_lock, flags);
+		tasklet_schedule(&vpe_tasklet);
+	}
+	return IRQ_HANDLED;
+}
+
+static int vpe_enable_irq(void)
+{
+	uint32_t   rc = 0;
+	rc = request_irq(vpe_device->vpeirq,
+				vpe_parse_irq,
+				IRQF_TRIGGER_HIGH, "vpe", 0);
+	return rc;
+}
+
+int msm_vpe_open(void)
+{
+	int rc = 0;
+
+	CDBG("%s: In \n", __func__);
+
+	vpe_ctrl = kzalloc(sizeof(struct vpe_ctrl_type), GFP_KERNEL);
+	if (!vpe_ctrl) {
+		pr_err("%s: no memory!\n", __func__);
+		return -ENOMEM;
+	}
+
+	spin_lock_init(&vpe_ctrl->ops_lock);
+	CDBG("%s: Out\n", __func__);
+
+	return rc;
+}
+
+int msm_vpe_release(void)
+{
+	/* clean up....*/
+	int rc = 0;
+	CDBG("%s: state %d\n", __func__, vpe_ctrl->state);
+	if (vpe_ctrl->state != VPE_STATE_IDLE)
+		rc = vpe_disable();
+
+	kfree(vpe_ctrl);
+	return rc;
+}
+
+
+int vpe_enable(uint32_t clk_rate)
+{
+	int rc = 0;
+	unsigned long flags = 0;
+	/* don't change the order of clock and irq.*/
+	CDBG("%s: enable_clock rate %u\n", __func__, clk_rate);
+	spin_lock_irqsave(&vpe_ctrl->ops_lock, flags);
+	if (vpe_ctrl->state != VPE_STATE_IDLE) {
+		CDBG("%s: VPE already enabled", __func__);
+		spin_unlock_irqrestore(&vpe_ctrl->ops_lock, flags);
+		return 0;
+	}
+	vpe_ctrl->state = VPE_STATE_INIT;
+	spin_unlock_irqrestore(&vpe_ctrl->ops_lock, flags);
+
+	rc = msm_camio_vpe_clk_enable(clk_rate);
+	if (rc < 0) {
+		pr_err("%s: msm_camio_vpe_clk_enable failed", __func__);
+		vpe_ctrl->state = VPE_STATE_IDLE;
+		return rc;
+	}
+
+	CDBG("%s: enable_irq\n", __func__);
+	vpe_enable_irq();
+
+	/* initialize the data structure - lock, queue etc. */
+	spin_lock_init(&vpe_ctrl->tasklet_lock);
+	INIT_LIST_HEAD(&vpe_ctrl->tasklet_q);
+
+	return rc;
+}
+
+int vpe_disable(void)
+{
+	int rc = 0;
+	unsigned long flags = 0;
+	CDBG("%s: called", __func__);
+	spin_lock_irqsave(&vpe_ctrl->ops_lock, flags);
+	if (vpe_ctrl->state == VPE_STATE_IDLE) {
+		CDBG("%s: VPE already disabled", __func__);
+		spin_unlock_irqrestore(&vpe_ctrl->ops_lock, flags);
+		return 0;
+	}
+	vpe_ctrl->state = VPE_STATE_IDLE;
+	spin_unlock_irqrestore(&vpe_ctrl->ops_lock, flags);
+	vpe_ctrl->out_y_addr = msm_camera_io_r(vpe_device->vpebase +
+		VPE_OUTP0_ADDR_OFFSET);
+	vpe_ctrl->out_cbcr_addr = msm_camera_io_r(vpe_device->vpebase +
+		VPE_OUTP1_ADDR_OFFSET);
+	free_irq(vpe_device->vpeirq, 0);
+	tasklet_kill(&vpe_tasklet);
+	rc = msm_camio_vpe_clk_disable();
+	return rc;
+}
+
+static int __msm_vpe_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+	struct resource   *vpemem, *vpeirq, *vpeio;
+	void __iomem      *vpebase;
+
+	/* first allocate */
+
+	vpe_device = &vpe_device_data;
+	memset(vpe_device, 0, sizeof(struct vpe_device_type));
+
+	/* does the device exist? */
+	vpeirq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!vpeirq) {
+		pr_err("%s: no vpe irq resource.\n", __func__);
+		rc = -ENODEV;
+		goto vpe_free_device;
+	}
+	vpemem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!vpemem) {
+		pr_err("%s: no vpe mem resource!\n", __func__);
+		rc = -ENODEV;
+		goto vpe_free_device;
+	}
+	vpeio = request_mem_region(vpemem->start,
+			resource_size(vpemem), pdev->name);
+	if (!vpeio) {
+		pr_err("%s: VPE region already claimed.\n", __func__);
+		rc = -EBUSY;
+		goto vpe_free_device;
+	}
+
+	vpebase =
+		ioremap(vpemem->start,
+				(vpemem->end - vpemem->start) + 1);
+	if (!vpebase) {
+		pr_err("%s: vpe ioremap failed.\n", __func__);
+		rc = -ENOMEM;
+		goto vpe_release_mem_region;
+	}
+
+	/* Fall through, _probe is successful. */
+	vpe_device->vpeirq = vpeirq->start;
+	vpe_device->vpemem = vpemem;
+	vpe_device->vpeio = vpeio;
+	vpe_device->vpebase = vpebase;
+	return rc;  /* this rc should be zero.*/
+
+	iounmap(vpe_device->vpebase);  /* this path should never occur */
+	vpe_device->vpebase = NULL;
+/* from this part it is error handling. */
+vpe_release_mem_region:
+	release_mem_region(vpemem->start, (vpemem->end - vpemem->start) + 1);
+vpe_free_device:
+	return rc;  /* this rc should have error code. */
+}
+
+static int __msm_vpe_remove(struct platform_device *pdev)
+{
+	struct resource	*vpemem;
+	vpemem = vpe_device->vpemem;
+
+	iounmap(vpe_device->vpebase);
+	vpe_device->vpebase = NULL;
+	release_mem_region(vpemem->start,
+					(vpemem->end - vpemem->start) + 1);
+	return 0;
+}
+
+static struct platform_driver msm_vpe_driver = {
+	.probe = __msm_vpe_probe,
+	.remove = __msm_vpe_remove,
+	.driver = {
+		.name = "msm_vpe",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init msm_vpe_init(void)
+{
+	return platform_driver_register(&msm_vpe_driver);
+}
+module_init(msm_vpe_init);
+
+static void __exit msm_vpe_exit(void)
+{
+	platform_driver_unregister(&msm_vpe_driver);
+}
+module_exit(msm_vpe_exit);
+
+MODULE_DESCRIPTION("msm vpe 1.0 driver");
+MODULE_VERSION("msm vpe driver 1.0");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/msm_vpe1.h b/drivers/media/platform/msm/camera_v1/msm_vpe1.h
new file mode 100644
index 0000000..5fd7a4a
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/msm_vpe1.h
@@ -0,0 +1,254 @@
+/* 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.
+ */
+
+#ifndef _msm_vpe1_h_
+#define _msm_vpe1_h_
+
+#include <mach/camera.h>
+
+/***********  start of register offset *********************/
+#define VPE_INTR_ENABLE_OFFSET                0x0020
+#define VPE_INTR_STATUS_OFFSET                0x0024
+#define VPE_INTR_CLEAR_OFFSET                 0x0028
+#define VPE_DL0_START_OFFSET                  0x0030
+#define VPE_HW_VERSION_OFFSET                 0x0070
+#define VPE_SW_RESET_OFFSET                   0x0074
+#define VPE_AXI_RD_ARB_CONFIG_OFFSET          0x0078
+#define VPE_SEL_CLK_OR_HCLK_TEST_BUS_OFFSET   0x007C
+#define VPE_CGC_EN_OFFSET                     0x0100
+#define VPE_CMD_STATUS_OFFSET                 0x10008
+#define VPE_PROFILE_EN_OFFSET                 0x10010
+#define VPE_PROFILE_COUNT_OFFSET              0x10014
+#define VPE_CMD_MODE_OFFSET                   0x10060
+#define VPE_SRC_SIZE_OFFSET                   0x10108
+#define VPE_SRCP0_ADDR_OFFSET                 0x1010C
+#define VPE_SRCP1_ADDR_OFFSET                 0x10110
+#define VPE_SRC_YSTRIDE1_OFFSET               0x1011C
+#define VPE_SRC_FORMAT_OFFSET                 0x10124
+#define VPE_SRC_UNPACK_PATTERN1_OFFSET        0x10128
+#define VPE_OP_MODE_OFFSET                    0x10138
+#define VPE_SCALE_PHASEX_INIT_OFFSET          0x1013C
+#define VPE_SCALE_PHASEY_INIT_OFFSET          0x10140
+#define VPE_SCALE_PHASEX_STEP_OFFSET          0x10144
+#define VPE_SCALE_PHASEY_STEP_OFFSET          0x10148
+#define VPE_OUT_FORMAT_OFFSET                 0x10150
+#define VPE_OUT_PACK_PATTERN1_OFFSET          0x10154
+#define VPE_OUT_SIZE_OFFSET                   0x10164
+#define VPE_OUTP0_ADDR_OFFSET                 0x10168
+#define VPE_OUTP1_ADDR_OFFSET                 0x1016C
+#define VPE_OUT_YSTRIDE1_OFFSET               0x10178
+#define VPE_OUT_XY_OFFSET                     0x1019C
+#define VPE_SRC_XY_OFFSET                     0x10200
+#define VPE_SRC_IMAGE_SIZE_OFFSET             0x10208
+#define VPE_SCALE_CONFIG_OFFSET               0x10230
+#define VPE_DEINT_STATUS_OFFSET               0x30000
+#define VPE_DEINT_DECISION_OFFSET             0x30004
+#define VPE_DEINT_COEFF0_OFFSET               0x30010
+#define VPE_SCALE_STATUS_OFFSET               0x50000
+#define VPE_SCALE_SVI_PARAM_OFFSET            0x50010
+#define VPE_SCALE_SHARPEN_CFG_OFFSET          0x50020
+#define VPE_SCALE_COEFF_LSP_0_OFFSET          0x50400
+#define VPE_SCALE_COEFF_MSP_0_OFFSET          0x50404
+
+#define VPE_AXI_ARB_2_OFFSET                  0x004C
+
+#define VPE_SCALE_COEFF_LSBn(n)	(0x50400 + 8 * (n))
+#define VPE_SCALE_COEFF_MSBn(n)	(0x50404 + 8 * (n))
+#define VPE_SCALE_COEFF_NUM			32
+
+/*********** end of register offset ********************/
+
+
+#define VPE_HARDWARE_VERSION          0x00080308
+#define VPE_SW_RESET_VALUE            0x00000010  /* bit 4 for PPP*/
+#define VPE_AXI_RD_ARB_CONFIG_VALUE   0x124924
+#define VPE_CMD_MODE_VALUE        0x1
+#define VPE_DEFAULT_OP_MODE_VALUE     0x40FC0004
+#define VPE_CGC_ENABLE_VALUE          0xffff
+#define VPE_DEFAULT_SCALE_CONFIG      0x3c
+
+#define VPE_NORMAL_MODE_CLOCK_RATE   150000000
+#define VPE_TURBO_MODE_CLOCK_RATE   200000000
+/**************************************************/
+/*********** Start of command id ******************/
+/**************************************************/
+enum VPE_CMD_ID_ENUM {
+	VPE_DUMMY_0 = 0,
+	VPE_SET_CLK,
+	VPE_RESET,
+	VPE_START,
+	VPE_ABORT,
+	VPE_OPERATION_MODE_CFG, /* 5 */
+	VPE_INPUT_PLANE_CFG,
+	VPE_OUTPUT_PLANE_CFG,
+	VPE_INPUT_PLANE_UPDATE,
+	VPE_SCALE_CFG_TYPE,
+	VPE_ROTATION_CFG_TYPE, /* 10 */
+	VPE_AXI_OUT_CFG,
+	VPE_CMD_DIS_OFFSET_CFG,
+	VPE_ENABLE,
+	VPE_DISABLE,
+};
+
+/* Length of each command.  In bytes.  (payload only) */
+#define VPE_OPERATION_MODE_CFG_LEN 8
+#define VPE_INPUT_PLANE_CFG_LEN    24
+#define VPE_OUTPUT_PLANE_CFG_LEN   20
+#define VPE_INPUT_PLANE_UPDATE_LEN 12
+#define VPE_SCALER_CONFIG_LEN      260
+#define VPE_DIS_OFFSET_CFG_LEN     12
+/**************************************************/
+/*********** End of command id ********************/
+/**************************************************/
+
+struct msm_vpe_cmd {
+	int32_t  id;
+	uint16_t length;
+	void     *value;
+};
+
+struct vpe_cmd_type {
+	uint16_t id;
+	uint32_t length;
+};
+
+struct vpe_isr_queue_cmd_type {
+	struct list_head            list;
+	uint32_t                    irq_status;
+};
+
+enum VPE_MESSAGE_ID {
+	MSG_ID_VPE_OUTPUT_V = 7, /* To match with that of VFE */
+	MSG_ID_VPE_OUTPUT_ST_L,
+	MSG_ID_VPE_OUTPUT_ST_R,
+};
+
+enum vpe_state {
+	VPE_STATE_IDLE,
+	VPE_STATE_INIT,
+	VPE_STATE_ACTIVE,
+};
+
+struct vpe_device_type {
+	/* device related. */
+	int   vpeirq;
+	void __iomem      *vpebase;
+	struct resource	  *vpemem;
+	struct resource   *vpeio;
+	void        *device_extdata;
+};
+
+struct dis_offset_type {
+	int32_t dis_offset_x;
+	int32_t dis_offset_y;
+	uint32_t frame_id;
+};
+
+struct vpe_ctrl_type {
+	spinlock_t        tasklet_lock;
+	spinlock_t        state_lock;
+	spinlock_t        ops_lock;
+
+	struct list_head  tasklet_q;
+	void              *syncdata;
+	uint16_t          op_mode;
+	void              *extdata;
+	uint32_t          extlen;
+	struct msm_vpe_callback *resp;
+	uint32_t          in_h_w;
+	uint32_t          out_h;  /* this is BEFORE rotation. */
+	uint32_t          out_w;  /* this is BEFORE rotation. */
+	uint32_t          dis_en;
+	struct timespec   ts;
+	struct dis_offset_type   dis_offset;
+	uint32_t          pcbcr_before_dis;
+	uint32_t          pcbcr_dis_offset;
+	int               output_type;
+	int               frame_pack;
+	uint8_t           pad_2k_bool;
+	enum vpe_state    state;
+	unsigned long     out_y_addr;
+	unsigned long     out_cbcr_addr;
+};
+
+/*
+* vpe_input_update
+*
+* Define the parameters for output plane
+*/
+/* this is the dimension of ROI.  width / height. */
+struct vpe_src_size_packed {
+	uint32_t        src_w;
+	uint32_t        src_h;
+};
+
+struct vpe_src_xy_packed {
+	uint32_t        src_x;
+	uint32_t        src_y;
+};
+
+struct vpe_input_plane_update_type {
+	struct vpe_src_size_packed             src_roi_size;
+	/* DIS updates this set. */
+	struct vpe_src_xy_packed               src_roi_offset;
+	/* input address*/
+	uint8_t                         *src_p0_addr;
+	uint8_t                         *src_p1_addr;
+};
+
+struct vpe_msg_stats{
+	uint32_t    buffer;
+	uint32_t    frameCounter;
+};
+
+struct vpe_msg_output {
+	uint8_t   output_id;
+	uint32_t  p0_Buffer;
+	uint32_t  p1_Buffer;
+	uint32_t  p2_Buffer;
+	uint32_t  frameCounter;
+};
+
+struct vpe_message {
+	uint8_t  _d;
+	union {
+		struct vpe_msg_output              msgOut;
+		struct vpe_msg_stats               msgStats;
+	} _u;
+};
+
+#define SCALER_PHASE_BITS 29
+#define HAL_MDP_PHASE_STEP_2P50    0x50000000
+#define HAL_MDP_PHASE_STEP_1P66    0x35555555
+#define HAL_MDP_PHASE_STEP_1P25    0x28000000
+
+struct phase_val_t {
+	int32_t phase_init_x;
+	int32_t phase_init_y;
+	int32_t phase_step_x;
+	int32_t phase_step_y;
+};
+
+extern struct vpe_ctrl_type *vpe_ctrl;
+
+int msm_vpe_open(void);
+int msm_vpe_release(void);
+int msm_vpe_reg(struct msm_vpe_callback *presp);
+void msm_send_frame_to_vpe(uint32_t pyaddr, uint32_t pcbcraddr,
+	struct timespec *ts, int output_id);
+int msm_vpe_config(struct msm_vpe_cfg_cmd *cmd, void *data);
+int msm_vpe_cfg_update(void *pinfo);
+void msm_vpe_offset_update(int frame_pack, uint32_t pyaddr, uint32_t pcbcraddr,
+	struct timespec *ts, int output_id, struct msm_st_half st_half,
+	int frameid);
+#endif /*_msm_vpe1_h_*/
+
diff --git a/drivers/media/platform/msm/camera_v1/mt9d112.c b/drivers/media/platform/msm/camera_v1/mt9d112.c
new file mode 100644
index 0000000..9c19965
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mt9d112.c
@@ -0,0 +1,846 @@
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <media/msm_camera.h>
+#include <mach/gpio.h>
+#include "mt9d112.h"
+
+/* Micron MT9D112 Registers and their values */
+/* Sensor Core Registers */
+#define  REG_MT9D112_MODEL_ID 0x3000
+#define  MT9D112_MODEL_ID     0x1580
+
+/*  SOC Registers Page 1  */
+#define  REG_MT9D112_SENSOR_RESET     0x301A
+#define  REG_MT9D112_STANDBY_CONTROL  0x3202
+#define  REG_MT9D112_MCU_BOOT         0x3386
+
+#define SENSOR_DEBUG 0
+
+struct mt9d112_work {
+	struct work_struct work;
+};
+
+static struct  mt9d112_work *mt9d112_sensorw;
+static struct  i2c_client *mt9d112_client;
+
+struct mt9d112_ctrl {
+	const struct msm_camera_sensor_info *sensordata;
+};
+
+
+static struct mt9d112_ctrl *mt9d112_ctrl;
+
+static DECLARE_WAIT_QUEUE_HEAD(mt9d112_wait_queue);
+DEFINE_SEMAPHORE(mt9d112_sem);
+static int16_t mt9d112_effect = CAMERA_EFFECT_OFF;
+
+/*=============================================================
+	EXTERNAL DECLARATIONS
+==============================================================*/
+extern struct mt9d112_reg mt9d112_regs;
+
+
+/*=============================================================*/
+
+static int mt9d112_reset(const struct msm_camera_sensor_info *dev)
+{
+	int rc = 0;
+
+	rc = gpio_request(dev->sensor_reset, "mt9d112");
+
+	if (!rc) {
+		rc = gpio_direction_output(dev->sensor_reset, 0);
+		msleep(20);
+		gpio_set_value_cansleep(dev->sensor_reset, 1);
+		msleep(20);
+	}
+
+	return rc;
+}
+
+static int32_t mt9d112_i2c_txdata(unsigned short saddr,
+	unsigned char *txdata, int length)
+{
+	struct i2c_msg msg[] = {
+		{
+			.addr = saddr,
+			.flags = 0,
+			.len = length,
+			.buf = txdata,
+		},
+	};
+
+#if SENSOR_DEBUG
+	if (length == 2)
+		CDBG("msm_io_i2c_w: 0x%04x 0x%04x\n",
+			*(u16 *) txdata, *(u16 *) (txdata + 2));
+	else if (length == 4)
+		CDBG("msm_io_i2c_w: 0x%04x\n", *(u16 *) txdata);
+	else
+		CDBG("msm_io_i2c_w: length = %d\n", length);
+#endif
+	if (i2c_transfer(mt9d112_client->adapter, msg, 1) < 0) {
+		CDBG("mt9d112_i2c_txdata failed\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t mt9d112_i2c_write(unsigned short saddr,
+	unsigned short waddr, unsigned short wdata, enum mt9d112_width width)
+{
+	int32_t rc = -EIO;
+	unsigned char buf[4];
+
+	memset(buf, 0, sizeof(buf));
+	switch (width) {
+	case WORD_LEN: {
+		buf[0] = (waddr & 0xFF00)>>8;
+		buf[1] = (waddr & 0x00FF);
+		buf[2] = (wdata & 0xFF00)>>8;
+		buf[3] = (wdata & 0x00FF);
+
+		rc = mt9d112_i2c_txdata(saddr, buf, 4);
+	}
+		break;
+
+	case BYTE_LEN: {
+		buf[0] = waddr;
+		buf[1] = wdata;
+		rc = mt9d112_i2c_txdata(saddr, buf, 2);
+	}
+		break;
+
+	default:
+		break;
+	}
+
+	if (rc < 0)
+		CDBG(
+		"i2c_write failed, addr = 0x%x, val = 0x%x!\n",
+		waddr, wdata);
+
+	return rc;
+}
+
+static int32_t mt9d112_i2c_write_table(
+	struct mt9d112_i2c_reg_conf const *reg_conf_tbl,
+	int num_of_items_in_table)
+{
+	int i;
+	int32_t rc = -EIO;
+
+	for (i = 0; i < num_of_items_in_table; i++) {
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			reg_conf_tbl->waddr, reg_conf_tbl->wdata,
+			reg_conf_tbl->width);
+		if (rc < 0)
+			break;
+		if (reg_conf_tbl->mdelay_time != 0)
+			mdelay(reg_conf_tbl->mdelay_time);
+		reg_conf_tbl++;
+	}
+
+	return rc;
+}
+
+static int mt9d112_i2c_rxdata(unsigned short saddr,
+	unsigned char *rxdata, int length)
+{
+	struct i2c_msg msgs[] = {
+	{
+		.addr   = saddr,
+		.flags = 0,
+		.len   = 2,
+		.buf   = rxdata,
+	},
+	{
+		.addr   = saddr,
+		.flags = I2C_M_RD,
+		.len   = length,
+		.buf   = rxdata,
+	},
+	};
+
+#if SENSOR_DEBUG
+	if (length == 2)
+		CDBG("msm_io_i2c_r: 0x%04x 0x%04x\n",
+			*(u16 *) rxdata, *(u16 *) (rxdata + 2));
+	else if (length == 4)
+		CDBG("msm_io_i2c_r: 0x%04x\n", *(u16 *) rxdata);
+	else
+		CDBG("msm_io_i2c_r: length = %d\n", length);
+#endif
+
+	if (i2c_transfer(mt9d112_client->adapter, msgs, 2) < 0) {
+		CDBG("mt9d112_i2c_rxdata failed!\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t mt9d112_i2c_read(unsigned short   saddr,
+	unsigned short raddr, unsigned short *rdata, enum mt9d112_width width)
+{
+	int32_t rc = 0;
+	unsigned char buf[4];
+
+	if (!rdata)
+		return -EIO;
+
+	memset(buf, 0, sizeof(buf));
+
+	switch (width) {
+	case WORD_LEN: {
+		buf[0] = (raddr & 0xFF00)>>8;
+		buf[1] = (raddr & 0x00FF);
+
+		rc = mt9d112_i2c_rxdata(saddr, buf, 2);
+		if (rc < 0)
+			return rc;
+
+		*rdata = buf[0] << 8 | buf[1];
+	}
+		break;
+
+	default:
+		break;
+	}
+
+	if (rc < 0)
+		CDBG("mt9d112_i2c_read failed!\n");
+
+	return rc;
+}
+
+static int32_t mt9d112_set_lens_roll_off(void)
+{
+	int32_t rc = 0;
+	rc = mt9d112_i2c_write_table(&mt9d112_regs.rftbl[0],
+								 mt9d112_regs.rftbl_size);
+	return rc;
+}
+
+static long mt9d112_reg_init(void)
+{
+	int32_t array_length;
+	int32_t i;
+	long rc;
+
+	/* PLL Setup Start */
+	rc = mt9d112_i2c_write_table(&mt9d112_regs.plltbl[0],
+					mt9d112_regs.plltbl_size);
+
+	if (rc < 0)
+		return rc;
+	/* PLL Setup End   */
+
+	array_length = mt9d112_regs.prev_snap_reg_settings_size;
+
+	/* Configure sensor for Preview mode and Snapshot mode */
+	for (i = 0; i < array_length; i++) {
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+		  mt9d112_regs.prev_snap_reg_settings[i].register_address,
+		  mt9d112_regs.prev_snap_reg_settings[i].register_value,
+		  WORD_LEN);
+
+		if (rc < 0)
+			return rc;
+	}
+
+	/* Configure for Noise Reduction, Saturation and Aperture Correction */
+	array_length = mt9d112_regs.noise_reduction_reg_settings_size;
+
+	for (i = 0; i < array_length; i++) {
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			mt9d112_regs.noise_reduction_reg_settings[i].register_address,
+			mt9d112_regs.noise_reduction_reg_settings[i].register_value,
+			WORD_LEN);
+
+		if (rc < 0)
+			return rc;
+	}
+
+	/* Set Color Kill Saturation point to optimum value */
+	rc =
+	mt9d112_i2c_write(mt9d112_client->addr,
+	0x35A4,
+	0x0593,
+	WORD_LEN);
+	if (rc < 0)
+		return rc;
+
+	rc = mt9d112_i2c_write_table(&mt9d112_regs.stbl[0],
+					mt9d112_regs.stbl_size);
+	if (rc < 0)
+		return rc;
+
+	rc = mt9d112_set_lens_roll_off();
+	if (rc < 0)
+		return rc;
+
+	return 0;
+}
+
+static long mt9d112_set_effect(int mode, int effect)
+{
+	uint16_t reg_addr;
+	uint16_t reg_val;
+	long rc = 0;
+
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		/* Context A Special Effects */
+		reg_addr = 0x2799;
+		break;
+
+	case SENSOR_RAW_SNAPSHOT_MODE:
+	case SENSOR_SNAPSHOT_MODE:
+		/* Context B Special Effects */
+		reg_addr = 0x279B;
+		break;
+
+	default:
+		reg_addr = 0x2799;
+		break;
+	}
+
+	switch (effect) {
+	case CAMERA_EFFECT_OFF: {
+		reg_val = 0x6440;
+
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			0x338C, reg_addr, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			0x3390, reg_val, WORD_LEN);
+		if (rc < 0)
+			return rc;
+	}
+			break;
+
+	case CAMERA_EFFECT_MONO: {
+		reg_val = 0x6441;
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			0x338C, reg_addr, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			0x3390, reg_val, WORD_LEN);
+		if (rc < 0)
+			return rc;
+	}
+		break;
+
+	case CAMERA_EFFECT_NEGATIVE: {
+		reg_val = 0x6443;
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			0x338C, reg_addr, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			0x3390, reg_val, WORD_LEN);
+		if (rc < 0)
+			return rc;
+	}
+		break;
+
+	case CAMERA_EFFECT_SOLARIZE: {
+		reg_val = 0x6445;
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			0x338C, reg_addr, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			0x3390, reg_val, WORD_LEN);
+		if (rc < 0)
+			return rc;
+	}
+		break;
+
+	case CAMERA_EFFECT_SEPIA: {
+		reg_val = 0x6442;
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			0x338C, reg_addr, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			0x3390, reg_val, WORD_LEN);
+		if (rc < 0)
+			return rc;
+	}
+		break;
+
+	default: {
+		reg_val = 0x6440;
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			0x338C, reg_addr, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			0x3390, reg_val, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		return -EINVAL;
+	}
+	}
+	mt9d112_effect = effect;
+	/* Refresh Sequencer */
+	rc = mt9d112_i2c_write(mt9d112_client->addr,
+		0x338C, 0xA103, WORD_LEN);
+	if (rc < 0)
+		return rc;
+
+	rc = mt9d112_i2c_write(mt9d112_client->addr,
+		0x3390, 0x0005, WORD_LEN);
+
+	return rc;
+}
+
+static long mt9d112_set_sensor_mode(int mode)
+{
+	uint16_t clock;
+	long rc = 0;
+
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x338C, 0xA20C, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x3390, 0x0004, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x338C, 0xA215, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x3390, 0x0004, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x338C, 0xA20B, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x3390, 0x0000, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		clock = 0x23C;
+
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x341C, clock, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x338C, 0xA103, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x3390, 0x0001, WORD_LEN);
+		if (rc < 0)
+			return rc;
+		mdelay(5);
+
+		break;
+
+	case SENSOR_SNAPSHOT_MODE:
+		/* Switch to lower fps for Snapshot */
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x341C, 0x0120, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x338C, 0xA120, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		msleep(40);/*waiting for the delay of one frame*/
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x3390, 0x0002, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		msleep(80);/*waiting for the delay of two frames*/
+
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x338C, 0xA103, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		msleep(40);/*waiting for the delay of one frame*/
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x3390, 0x0002, WORD_LEN);
+		if (rc < 0)
+			return rc;
+		break;
+
+	case SENSOR_RAW_SNAPSHOT_MODE:
+		/* Setting the effect to CAMERA_EFFECT_OFF */
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x338C, 0x279B, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+			0x3390, 0x6440, WORD_LEN);
+		if (rc < 0)
+			return rc;
+		msleep(40);/*waiting for the delay of one frame*/
+		/* Switch to lower fps for Snapshot */
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x341C, 0x0120, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x338C, 0xA120, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x3390, 0x0002, WORD_LEN);
+		if (rc < 0)
+			return rc;
+		msleep(80);/*waiting for the delay of two frames frame*/
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x338C, 0xA103, WORD_LEN);
+		if (rc < 0)
+			return rc;
+		msleep(40);/*waiting for the delay of one frame*/
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x3390, 0x0002, WORD_LEN);
+		if (rc < 0)
+			return rc;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int mt9d112_sensor_init_probe(const struct msm_camera_sensor_info *data)
+{
+	uint16_t model_id = 0;
+	int rc = 0;
+
+	CDBG("init entry \n");
+	rc = mt9d112_reset(data);
+	if (rc < 0) {
+		CDBG("reset failed!\n");
+		goto init_probe_fail;
+	}
+
+	msm_camio_clk_rate_set(24000000);
+	msleep(20);
+
+	/* Micron suggested Power up block Start:
+	* Put MCU into Reset - Stop MCU */
+	rc = mt9d112_i2c_write(mt9d112_client->addr,
+		REG_MT9D112_MCU_BOOT, 0x0501, WORD_LEN);
+	if (rc < 0)
+		goto init_probe_fail;
+
+	/* Pull MCU from Reset - Start MCU */
+	rc = mt9d112_i2c_write(mt9d112_client->addr,
+		REG_MT9D112_MCU_BOOT, 0x0500, WORD_LEN);
+	if (rc < 0)
+		goto init_probe_fail;
+
+	mdelay(5);
+
+	/* Micron Suggested - Power up block */
+	rc = mt9d112_i2c_write(mt9d112_client->addr,
+		REG_MT9D112_SENSOR_RESET, 0x0ACC, WORD_LEN);
+	if (rc < 0)
+		goto init_probe_fail;
+
+	rc = mt9d112_i2c_write(mt9d112_client->addr,
+		REG_MT9D112_STANDBY_CONTROL, 0x0008, WORD_LEN);
+	if (rc < 0)
+		goto init_probe_fail;
+
+	/* FUSED_DEFECT_CORRECTION */
+	rc = mt9d112_i2c_write(mt9d112_client->addr,
+		0x33F4, 0x031D, WORD_LEN);
+	if (rc < 0)
+		goto init_probe_fail;
+
+	mdelay(5);
+
+	/* Micron suggested Power up block End */
+	/* Read the Model ID of the sensor */
+	rc = mt9d112_i2c_read(mt9d112_client->addr,
+		REG_MT9D112_MODEL_ID, &model_id, WORD_LEN);
+	if (rc < 0)
+		goto init_probe_fail;
+
+	CDBG("mt9d112 model_id = 0x%x\n", model_id);
+
+	/* Check if it matches it with the value in Datasheet */
+	if (model_id != MT9D112_MODEL_ID) {
+		rc = -EINVAL;
+		goto init_probe_fail;
+	}
+
+	rc = mt9d112_reg_init();
+	if (rc < 0)
+		goto init_probe_fail;
+
+	return rc;
+
+init_probe_fail:
+	return rc;
+}
+
+int mt9d112_sensor_init(const struct msm_camera_sensor_info *data)
+{
+	int rc = 0;
+
+	mt9d112_ctrl = kzalloc(sizeof(struct mt9d112_ctrl), GFP_KERNEL);
+	if (!mt9d112_ctrl) {
+		CDBG("mt9d112_init failed!\n");
+		rc = -ENOMEM;
+		goto init_done;
+	}
+
+	if (data)
+		mt9d112_ctrl->sensordata = data;
+
+	/* Input MCLK = 24MHz */
+	msm_camio_clk_rate_set(24000000);
+	mdelay(5);
+
+	msm_camio_camif_pad_reg_reset();
+
+	rc = mt9d112_sensor_init_probe(data);
+	if (rc < 0) {
+		CDBG("mt9d112_sensor_init failed!\n");
+		goto init_fail;
+	}
+
+init_done:
+	return rc;
+
+init_fail:
+	kfree(mt9d112_ctrl);
+	return rc;
+}
+
+static int mt9d112_init_client(struct i2c_client *client)
+{
+	/* Initialize the MSM_CAMI2C Chip */
+	init_waitqueue_head(&mt9d112_wait_queue);
+	return 0;
+}
+
+int mt9d112_sensor_config(void __user *argp)
+{
+	struct sensor_cfg_data cfg_data;
+	long   rc = 0;
+
+	if (copy_from_user(&cfg_data,
+			(void *)argp,
+			sizeof(struct sensor_cfg_data)))
+		return -EFAULT;
+
+	/* down(&mt9d112_sem); */
+
+	CDBG("mt9d112_ioctl, cfgtype = %d, mode = %d\n",
+		cfg_data.cfgtype, cfg_data.mode);
+
+		switch (cfg_data.cfgtype) {
+		case CFG_SET_MODE:
+			rc = mt9d112_set_sensor_mode(
+						cfg_data.mode);
+			break;
+
+		case CFG_SET_EFFECT:
+			rc = mt9d112_set_effect(cfg_data.mode,
+						cfg_data.cfg.effect);
+			break;
+
+		case CFG_GET_AF_MAX_STEPS:
+		default:
+			rc = -EINVAL;
+			break;
+		}
+
+	/* up(&mt9d112_sem); */
+
+	return rc;
+}
+
+int mt9d112_sensor_release(void)
+{
+	int rc = 0;
+
+	/* down(&mt9d112_sem); */
+	gpio_set_value_cansleep(mt9d112_ctrl->sensordata->sensor_reset, 0);
+	msleep(20);
+	gpio_free(mt9d112_ctrl->sensordata->sensor_reset);
+	kfree(mt9d112_ctrl);
+	/* up(&mt9d112_sem); */
+
+	return rc;
+}
+
+static int mt9d112_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		rc = -ENOTSUPP;
+		goto probe_failure;
+	}
+
+	mt9d112_sensorw =
+		kzalloc(sizeof(struct mt9d112_work), GFP_KERNEL);
+
+	if (!mt9d112_sensorw) {
+		rc = -ENOMEM;
+		goto probe_failure;
+	}
+
+	i2c_set_clientdata(client, mt9d112_sensorw);
+	mt9d112_init_client(client);
+	mt9d112_client = client;
+
+	CDBG("mt9d112_probe succeeded!\n");
+
+	return 0;
+
+probe_failure:
+	kfree(mt9d112_sensorw);
+	mt9d112_sensorw = NULL;
+	CDBG("mt9d112_probe failed!\n");
+	return rc;
+}
+
+static const struct i2c_device_id mt9d112_i2c_id[] = {
+	{ "mt9d112", 0},
+	{ },
+};
+
+static struct i2c_driver mt9d112_i2c_driver = {
+	.id_table = mt9d112_i2c_id,
+	.probe  = mt9d112_i2c_probe,
+	.remove = __exit_p(mt9d112_i2c_remove),
+	.driver = {
+		.name = "mt9d112",
+	},
+};
+
+static int mt9d112_sensor_probe(const struct msm_camera_sensor_info *info,
+				struct msm_sensor_ctrl *s)
+{
+	int rc = i2c_add_driver(&mt9d112_i2c_driver);
+	if (rc < 0 || mt9d112_client == NULL) {
+		rc = -ENOTSUPP;
+		goto probe_done;
+	}
+
+	/* Input MCLK = 24MHz */
+	msm_camio_clk_rate_set(24000000);
+	mdelay(5);
+
+	rc = mt9d112_sensor_init_probe(info);
+	if (rc < 0) {
+		gpio_free(info->sensor_reset);
+		goto probe_done;
+	}
+	s->s_init = mt9d112_sensor_init;
+	s->s_release = mt9d112_sensor_release;
+	s->s_config  = mt9d112_sensor_config;
+	s->s_camera_type = FRONT_CAMERA_2D;
+	s->s_mount_angle  = 0;
+	gpio_set_value_cansleep(info->sensor_reset, 0);
+	msleep(20);
+	gpio_free(info->sensor_reset);
+
+probe_done:
+	CDBG("%s %s:%d\n", __FILE__, __func__, __LINE__);
+	return rc;
+}
+
+static int __mt9d112_probe(struct platform_device *pdev)
+{
+	return msm_camera_drv_start(pdev, mt9d112_sensor_probe);
+}
+
+static struct platform_driver msm_camera_driver = {
+	.probe = __mt9d112_probe,
+	.driver = {
+		.name = "msm_camera_mt9d112",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init mt9d112_init(void)
+{
+	return platform_driver_register(&msm_camera_driver);
+}
+
+module_init(mt9d112_init);
diff --git a/drivers/media/platform/msm/camera_v1/mt9d112.h b/drivers/media/platform/msm/camera_v1/mt9d112.h
new file mode 100644
index 0000000..f07d732
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mt9d112.h
@@ -0,0 +1,47 @@
+/* Copyright (c) 2009, 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 MT9D112_H
+#define MT9D112_H
+
+#include <linux/types.h>
+#include <mach/camera.h>
+
+extern struct mt9d112_reg mt9d112_regs;
+
+enum mt9d112_width {
+	WORD_LEN,
+	BYTE_LEN
+};
+
+struct mt9d112_i2c_reg_conf {
+	unsigned short waddr;
+	unsigned short wdata;
+	enum mt9d112_width width;
+	unsigned short mdelay_time;
+};
+
+struct mt9d112_reg {
+	const struct register_address_value_pair *prev_snap_reg_settings;
+	uint16_t prev_snap_reg_settings_size;
+	const struct register_address_value_pair *noise_reduction_reg_settings;
+	uint16_t noise_reduction_reg_settings_size;
+	const struct mt9d112_i2c_reg_conf *plltbl;
+	uint16_t plltbl_size;
+	const struct mt9d112_i2c_reg_conf *stbl;
+	uint16_t stbl_size;
+	const struct mt9d112_i2c_reg_conf *rftbl;
+	uint16_t rftbl_size;
+};
+
+#endif /* MT9D112_H */
diff --git a/drivers/media/platform/msm/camera_v1/mt9d112_reg.c b/drivers/media/platform/msm/camera_v1/mt9d112_reg.c
new file mode 100644
index 0000000..6c35cbc
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mt9d112_reg.c
@@ -0,0 +1,319 @@
+/* Copyright (c) 2009, 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 "mt9d112.h"
+
+
+struct register_address_value_pair const
+preview_snapshot_mode_reg_settings_array[] = {
+	{0x338C, 0x2703},
+	{0x3390, 800},    /* Output Width (P) = 640 */
+	{0x338C, 0x2705},
+	{0x3390, 600},    /* Output Height (P) = 480 */
+	{0x338C, 0x2707},
+	{0x3390, 0x0640}, /* Output Width (S) = 1600 */
+	{0x338C, 0x2709},
+	{0x3390, 0x04B0}, /* Output Height (S) = 1200 */
+	{0x338C, 0x270D},
+	{0x3390, 0x0000}, /* Row Start (P) = 0 */
+	{0x338C, 0x270F},
+	{0x3390, 0x0000}, /* Column Start (P) = 0 */
+	{0x338C, 0x2711},
+	{0x3390, 0x04BD}, /* Row End (P) = 1213 */
+	{0x338C, 0x2713},
+	{0x3390, 0x064D}, /* Column End (P) = 1613 */
+	{0x338C, 0x2715},
+	{0x3390, 0x0000}, /* Extra Delay (P) = 0 */
+	{0x338C, 0x2717},
+	{0x3390, 0x2111}, /* Row Speed (P) = 8465 */
+	{0x338C, 0x2719},
+	{0x3390, 0x046C}, /* Read Mode (P) = 1132 */
+	{0x338C, 0x271B},
+	{0x3390, 0x024F}, /* Sensor_Sample_Time_pck(P) = 591 */
+	{0x338C, 0x271D},
+	{0x3390, 0x0102}, /* Sensor_Fine_Correction(P) = 258 */
+	{0x338C, 0x271F},
+	{0x3390, 0x0279}, /* Sensor_Fine_IT_min(P) = 633 */
+	{0x338C, 0x2721},
+	{0x3390, 0x0155}, /* Sensor_Fine_IT_max_margin(P) = 341 */
+	{0x338C, 0x2723},
+	{0x3390, 659},    /* Frame Lines (P) = 679 */
+	{0x338C, 0x2725},
+	{0x3390, 0x061B}, /* Line Length (P) = 1563 */
+	{0x338C, 0x2727},
+	{0x3390, 0x2020},
+	{0x338C, 0x2729},
+	{0x3390, 0x2020},
+	{0x338C, 0x272B},
+	{0x3390, 0x1020},
+	{0x338C, 0x272D},
+	{0x3390, 0x2007},
+	{0x338C, 0x272F},
+	{0x3390, 0x0004}, /* Row Start(S) = 4 */
+	{0x338C, 0x2731},
+	{0x3390, 0x0004}, /* Column Start(S) = 4 */
+	{0x338C, 0x2733},
+	{0x3390, 0x04BB}, /* Row End(S) = 1211 */
+	{0x338C, 0x2735},
+	{0x3390, 0x064B}, /* Column End(S) = 1611 */
+	{0x338C, 0x2737},
+	{0x3390, 0x04CE}, /* Extra Delay(S) = 1230 */
+	{0x338C, 0x2739},
+	{0x3390, 0x2111}, /* Row Speed(S) = 8465 */
+	{0x338C, 0x273B},
+	{0x3390, 0x0024}, /* Read Mode(S) = 36 */
+	{0x338C, 0x273D},
+	{0x3390, 0x0120}, /* Sensor sample time pck(S) = 288 */
+	{0x338C, 0x2741},
+	{0x3390, 0x0169}, /* Sensor_Fine_IT_min(P) = 361 */
+	{0x338C, 0x2745},
+	{0x3390, 0x04FF}, /* Frame Lines(S) = 1279 */
+	{0x338C, 0x2747},
+	{0x3390, 0x0824}, /* Line Length(S) = 2084 */
+	{0x338C, 0x2751},
+	{0x3390, 0x0000}, /* Crop_X0(P) = 0 */
+	{0x338C, 0x2753},
+	{0x3390, 0x0320}, /* Crop_X1(P) = 800 */
+	{0x338C, 0x2755},
+	{0x3390, 0x0000}, /* Crop_Y0(P) = 0 */
+	{0x338C, 0x2757},
+	{0x3390, 0x0258}, /* Crop_Y1(P) = 600 */
+	{0x338C, 0x275F},
+	{0x3390, 0x0000}, /* Crop_X0(S) = 0 */
+	{0x338C, 0x2761},
+	{0x3390, 0x0640}, /* Crop_X1(S) = 1600 */
+	{0x338C, 0x2763},
+	{0x3390, 0x0000}, /* Crop_Y0(S) = 0 */
+	{0x338C, 0x2765},
+	{0x3390, 0x04B0}, /* Crop_Y1(S) = 1200 */
+	{0x338C, 0x222E},
+	{0x3390, 0x00A0}, /* R9 Step = 160 */
+	{0x338C, 0xA408},
+	{0x3390, 0x001F},
+	{0x338C, 0xA409},
+	{0x3390, 0x0021},
+	{0x338C, 0xA40A},
+	{0x3390, 0x0025},
+	{0x338C, 0xA40B},
+	{0x3390, 0x0027},
+	{0x338C, 0x2411},
+	{0x3390, 0x00A0},
+	{0x338C, 0x2413},
+	{0x3390, 0x00C0},
+	{0x338C, 0x2415},
+	{0x3390, 0x00A0},
+	{0x338C, 0x2417},
+	{0x3390, 0x00C0},
+	{0x338C, 0x2799},
+	{0x3390, 0x6408}, /* MODE_SPEC_EFFECTS(P) */
+	{0x338C, 0x279B},
+	{0x3390, 0x6408}, /* MODE_SPEC_EFFECTS(S) */
+};
+
+static struct register_address_value_pair const
+noise_reduction_reg_settings_array[] = {
+	{0x338C, 0xA76D},
+	{0x3390, 0x0003},
+	{0x338C, 0xA76E},
+	{0x3390, 0x0003},
+	{0x338C, 0xA76F},
+	{0x3390, 0},
+	{0x338C, 0xA770},
+	{0x3390, 21},
+	{0x338C, 0xA771},
+	{0x3390, 37},
+	{0x338C, 0xA772},
+	{0x3390, 63},
+	{0x338C, 0xA773},
+	{0x3390, 100},
+	{0x338C, 0xA774},
+	{0x3390, 128},
+	{0x338C, 0xA775},
+	{0x3390, 151},
+	{0x338C, 0xA776},
+	{0x3390, 169},
+	{0x338C, 0xA777},
+	{0x3390, 186},
+	{0x338C, 0xA778},
+	{0x3390, 199},
+	{0x338C, 0xA779},
+	{0x3390, 210},
+	{0x338C, 0xA77A},
+	{0x3390, 220},
+	{0x338C, 0xA77B},
+	{0x3390, 228},
+	{0x338C, 0xA77C},
+	{0x3390, 234},
+	{0x338C, 0xA77D},
+	{0x3390, 240},
+	{0x338C, 0xA77E},
+	{0x3390, 244},
+	{0x338C, 0xA77F},
+	{0x3390, 248},
+	{0x338C, 0xA780},
+	{0x3390, 252},
+	{0x338C, 0xA781},
+	{0x3390, 255},
+	{0x338C, 0xA782},
+	{0x3390, 0},
+	{0x338C, 0xA783},
+	{0x3390, 21},
+	{0x338C, 0xA784},
+	{0x3390, 37},
+	{0x338C, 0xA785},
+	{0x3390, 63},
+	{0x338C, 0xA786},
+	{0x3390, 100},
+	{0x338C, 0xA787},
+	{0x3390, 128},
+	{0x338C, 0xA788},
+	{0x3390, 151},
+	{0x338C, 0xA789},
+	{0x3390, 169},
+	{0x338C, 0xA78A},
+	{0x3390, 186},
+	{0x338C, 0xA78B},
+	{0x3390, 199},
+	{0x338C, 0xA78C},
+	{0x3390, 210},
+	{0x338C, 0xA78D},
+	{0x3390, 220},
+	{0x338C, 0xA78E},
+	{0x3390, 228},
+	{0x338C, 0xA78F},
+	{0x3390, 234},
+	{0x338C, 0xA790},
+	{0x3390, 240},
+	{0x338C, 0xA791},
+	{0x3390, 244},
+	{0x338C, 0xA793},
+	{0x3390, 252},
+	{0x338C, 0xA794},
+	{0x3390, 255},
+	{0x338C, 0xA103},
+	{0x3390, 6},
+};
+
+static const struct mt9d112_i2c_reg_conf const lens_roll_off_tbl[] = {
+	{ 0x34CE, 0x81A0, WORD_LEN, 0 },
+	{ 0x34D0, 0x6331, WORD_LEN, 0 },
+	{ 0x34D2, 0x3394, WORD_LEN, 0 },
+	{ 0x34D4, 0x9966, WORD_LEN, 0 },
+	{ 0x34D6, 0x4B25, WORD_LEN, 0 },
+	{ 0x34D8, 0x2670, WORD_LEN, 0 },
+	{ 0x34DA, 0x724C, WORD_LEN, 0 },
+	{ 0x34DC, 0xFFFD, WORD_LEN, 0 },
+	{ 0x34DE, 0x00CA, WORD_LEN, 0 },
+	{ 0x34E6, 0x00AC, WORD_LEN, 0 },
+	{ 0x34EE, 0x0EE1, WORD_LEN, 0 },
+	{ 0x34F6, 0x0D87, WORD_LEN, 0 },
+	{ 0x3500, 0xE1F7, WORD_LEN, 0 },
+	{ 0x3508, 0x1CF4, WORD_LEN, 0 },
+	{ 0x3510, 0x1D28, WORD_LEN, 0 },
+	{ 0x3518, 0x1F26, WORD_LEN, 0 },
+	{ 0x3520, 0x2220, WORD_LEN, 0 },
+	{ 0x3528, 0x333D, WORD_LEN, 0 },
+	{ 0x3530, 0x15D9, WORD_LEN, 0 },
+	{ 0x3538, 0xCFB8, WORD_LEN, 0 },
+	{ 0x354C, 0x05FE, WORD_LEN, 0 },
+	{ 0x3544, 0x05F8, WORD_LEN, 0 },
+	{ 0x355C, 0x0596, WORD_LEN, 0 },
+	{ 0x3554, 0x0611, WORD_LEN, 0 },
+	{ 0x34E0, 0x00F2, WORD_LEN, 0 },
+	{ 0x34E8, 0x00A8, WORD_LEN, 0 },
+	{ 0x34F0, 0x0F7B, WORD_LEN, 0 },
+	{ 0x34F8, 0x0CD7, WORD_LEN, 0 },
+	{ 0x3502, 0xFEDB, WORD_LEN, 0 },
+	{ 0x350A, 0x13E4, WORD_LEN, 0 },
+	{ 0x3512, 0x1F2C, WORD_LEN, 0 },
+	{ 0x351A, 0x1D20, WORD_LEN, 0 },
+	{ 0x3522, 0x2422, WORD_LEN, 0 },
+	{ 0x352A, 0x2925, WORD_LEN, 0 },
+	{ 0x3532, 0x1D04, WORD_LEN, 0 },
+	{ 0x353A, 0xFBF2, WORD_LEN, 0 },
+	{ 0x354E, 0x0616, WORD_LEN, 0 },
+	{ 0x3546, 0x0597, WORD_LEN, 0 },
+	{ 0x355E, 0x05CD, WORD_LEN, 0 },
+	{ 0x3556, 0x0529, WORD_LEN, 0 },
+	{ 0x34E4, 0x00B2, WORD_LEN, 0 },
+	{ 0x34EC, 0x005E, WORD_LEN, 0 },
+	{ 0x34F4, 0x0F43, WORD_LEN, 0 },
+	{ 0x34FC, 0x0E2F, WORD_LEN, 0 },
+	{ 0x3506, 0xF9FC, WORD_LEN, 0 },
+	{ 0x350E, 0x0CE4, WORD_LEN, 0 },
+	{ 0x3516, 0x1E1E, WORD_LEN, 0 },
+	{ 0x351E, 0x1B19, WORD_LEN, 0 },
+	{ 0x3526, 0x151B, WORD_LEN, 0 },
+	{ 0x352E, 0x1416, WORD_LEN, 0 },
+	{ 0x3536, 0x10FC, WORD_LEN, 0 },
+	{ 0x353E, 0xC018, WORD_LEN, 0 },
+	{ 0x3552, 0x06B4, WORD_LEN, 0 },
+	{ 0x354A, 0x0506, WORD_LEN, 0 },
+	{ 0x3562, 0x06AB, WORD_LEN, 0 },
+	{ 0x355A, 0x063A, WORD_LEN, 0 },
+	{ 0x34E2, 0x00E5, WORD_LEN, 0 },
+	{ 0x34EA, 0x008B, WORD_LEN, 0 },
+	{ 0x34F2, 0x0E4C, WORD_LEN, 0 },
+	{ 0x34FA, 0x0CA3, WORD_LEN, 0 },
+	{ 0x3504, 0x0907, WORD_LEN, 0 },
+	{ 0x350C, 0x1DFD, WORD_LEN, 0 },
+	{ 0x3514, 0x1E24, WORD_LEN, 0 },
+	{ 0x351C, 0x2529, WORD_LEN, 0 },
+	{ 0x3524, 0x1D20, WORD_LEN, 0 },
+	{ 0x352C, 0x2332, WORD_LEN, 0 },
+	{ 0x3534, 0x10E9, WORD_LEN, 0 },
+	{ 0x353C, 0x0BCB, WORD_LEN, 0 },
+	{ 0x3550, 0x04EF, WORD_LEN, 0 },
+	{ 0x3548, 0x0609, WORD_LEN, 0 },
+	{ 0x3560, 0x0580, WORD_LEN, 0 },
+	{ 0x3558, 0x05DD, WORD_LEN, 0 },
+	{ 0x3540, 0x0000, WORD_LEN, 0 },
+	{ 0x3542, 0x0000, WORD_LEN, 0 }
+};
+
+static const struct mt9d112_i2c_reg_conf const pll_setup_tbl[] = {
+	{ 0x341E, 0x8F09, WORD_LEN, 0 },
+	{ 0x341C, 0x0250, WORD_LEN, 0 },
+	{ 0x341E, 0x8F09, WORD_LEN, 5 },
+	{ 0x341E, 0x8F08, WORD_LEN, 0 }
+};
+
+/* Refresh Sequencer */
+static const struct mt9d112_i2c_reg_conf const sequencer_tbl[] = {
+	{ 0x338C, 0x2799, WORD_LEN, 0},
+	{ 0x3390, 0x6440, WORD_LEN, 5},
+	{ 0x338C, 0x279B, WORD_LEN, 0},
+	{ 0x3390, 0x6440, WORD_LEN, 5},
+	{ 0x338C, 0xA103, WORD_LEN, 0},
+	{ 0x3390, 0x0005, WORD_LEN, 5},
+	{ 0x338C, 0xA103, WORD_LEN, 0},
+	{ 0x3390, 0x0006, WORD_LEN, 5}
+};
+
+struct mt9d112_reg mt9d112_regs = {
+	.prev_snap_reg_settings = &preview_snapshot_mode_reg_settings_array[0],
+	.prev_snap_reg_settings_size = ARRAY_SIZE(
+		preview_snapshot_mode_reg_settings_array),
+	.noise_reduction_reg_settings = &noise_reduction_reg_settings_array[0],
+	.noise_reduction_reg_settings_size = ARRAY_SIZE(
+		noise_reduction_reg_settings_array),
+	.plltbl = pll_setup_tbl,
+	.plltbl_size = ARRAY_SIZE(pll_setup_tbl),
+	.stbl = sequencer_tbl,
+	.stbl_size = ARRAY_SIZE(sequencer_tbl),
+	.rftbl = lens_roll_off_tbl,
+	.rftbl_size = ARRAY_SIZE(lens_roll_off_tbl)
+};
+
+
+
diff --git a/drivers/media/platform/msm/camera_v1/mt9d113.c b/drivers/media/platform/msm/camera_v1/mt9d113.c
new file mode 100644
index 0000000..a32c804
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mt9d113.c
@@ -0,0 +1,656 @@
+/* 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/delay.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <media/msm_camera.h>
+#include <mach/gpio.h>
+#include "mt9d113.h"
+
+/* Micron MT9D113 Registers and their values */
+#define  REG_MT9D113_MODEL_ID	0x0000
+#define  MT9D113_MODEL_ID		0x2580
+#define Q8						0x00000100
+
+struct mt9d113_work {
+	struct work_struct work;
+};
+
+static struct  mt9d113_work *mt9d113_sensorw;
+static struct  i2c_client *mt9d113_client;
+
+struct mt9d113_ctrl {
+	const struct msm_camera_sensor_info *sensordata;
+	uint32_t sensormode;
+	uint32_t fps_divider;/* init to 1 * 0x00000400 */
+	uint32_t pict_fps_divider;/* init to 1 * 0x00000400 */
+	uint16_t fps;
+	uint16_t curr_step_pos;
+	uint16_t my_reg_gain;
+	uint32_t my_reg_line_count;
+	uint16_t total_lines_per_frame;
+	uint16_t config_csi;
+	enum mt9d113_resolution_t prev_res;
+	enum mt9d113_resolution_t pict_res;
+	enum mt9d113_resolution_t curr_res;
+	enum mt9d113_test_mode_t  set_test;
+};
+
+static struct mt9d113_ctrl *mt9d113_ctrl;
+
+static DECLARE_WAIT_QUEUE_HEAD(mt9d113_wait_queue);
+DEFINE_MUTEX(mt9d113_mut);
+
+static int mt9d113_i2c_rxdata(unsigned short saddr,
+				unsigned char *rxdata, int length)
+{
+	struct i2c_msg msgs[] = {
+		{
+			.addr   = saddr,
+			.flags = 0,
+			.len   = 2,
+			.buf   = rxdata,
+		},
+		{
+			.addr   = saddr,
+			.flags = I2C_M_RD,
+			.len   = length,
+			.buf   = rxdata,
+		},
+	};
+	if (i2c_transfer(mt9d113_client->adapter, msgs, 2) < 0) {
+		CDBG("mt9d113_i2c_rxdata failed!\n");
+		return -EIO;
+	}
+	return 0;
+}
+
+static int32_t mt9d113_i2c_read(unsigned short   saddr,
+				unsigned short raddr,
+				unsigned short *rdata,
+				enum mt9d113_width width)
+{
+	int32_t rc = 0;
+	unsigned char buf[4];
+	if (!rdata)
+		return -EIO;
+	memset(buf, 0, sizeof(buf));
+	switch (width) {
+	case WORD_LEN: {
+			buf[0] = (raddr & 0xFF00)>>8;
+			buf[1] = (raddr & 0x00FF);
+			rc = mt9d113_i2c_rxdata(saddr, buf, 2);
+			if (rc < 0)
+				return rc;
+			*rdata = buf[0] << 8 | buf[1];
+		}
+		break;
+	default:
+		break;
+	}
+	if (rc < 0)
+		CDBG("mt9d113_i2c_read failed !\n");
+	return rc;
+}
+
+static int32_t mt9d113_i2c_txdata(unsigned short saddr,
+				unsigned char *txdata, int length)
+{
+	struct i2c_msg msg[] = {
+		{
+			.addr = saddr,
+			.flags = 0,
+			.len = length,
+			.buf = txdata,
+		},
+	};
+	if (i2c_transfer(mt9d113_client->adapter, msg, 1) < 0) {
+		CDBG("mt9d113_i2c_txdata failed\n");
+		return -EIO;
+	}
+	return 0;
+}
+
+static int32_t mt9d113_i2c_write(unsigned short saddr,
+				unsigned short waddr,
+				unsigned short wdata,
+				enum mt9d113_width width)
+{
+	int32_t rc = -EIO;
+	unsigned char buf[4];
+	memset(buf, 0, sizeof(buf));
+	switch (width) {
+	case WORD_LEN: {
+			buf[0] = (waddr & 0xFF00)>>8;
+			buf[1] = (waddr & 0x00FF);
+			buf[2] = (wdata & 0xFF00)>>8;
+			buf[3] = (wdata & 0x00FF);
+			rc = mt9d113_i2c_txdata(saddr, buf, 4);
+		}
+		break;
+	case BYTE_LEN: {
+			buf[0] = waddr;
+			buf[1] = wdata;
+			rc = mt9d113_i2c_txdata(saddr, buf, 2);
+		}
+		break;
+	default:
+		break;
+	}
+	if (rc < 0)
+		printk(KERN_ERR
+			"i2c_write failed, addr = 0x%x, val = 0x%x!\n",
+			waddr, wdata);
+	return rc;
+}
+
+static int32_t mt9d113_i2c_write_table(
+				struct mt9d113_i2c_reg_conf
+				const *reg_conf_tbl,
+				int num_of_items_in_table)
+{
+	int i;
+	int32_t rc = -EIO;
+	for (i = 0; i < num_of_items_in_table; i++) {
+		rc = mt9d113_i2c_write(mt9d113_client->addr,
+				reg_conf_tbl->waddr, reg_conf_tbl->wdata,
+				WORD_LEN);
+		if (rc < 0)
+			break;
+		reg_conf_tbl++;
+	}
+	return rc;
+}
+
+static long mt9d113_reg_init(void)
+{
+	uint16_t data = 0;
+	int32_t rc = 0;
+	int count = 0;
+	struct msm_camera_csi_params mt9d113_csi_params;
+	if (!mt9d113_ctrl->config_csi) {
+		mt9d113_csi_params.lane_cnt = 1;
+		mt9d113_csi_params.data_format = CSI_8BIT;
+		mt9d113_csi_params.lane_assign = 0xe4;
+		mt9d113_csi_params.dpcm_scheme = 0;
+		mt9d113_csi_params.settle_cnt = 0x14;
+		rc = msm_camio_csi_config(&mt9d113_csi_params);
+		mt9d113_ctrl->config_csi = 1;
+		msleep(50);
+	}
+	/* Disable parallel and enable mipi*/
+	rc = mt9d113_i2c_write(mt9d113_client->addr,
+				0x001A,
+				0x0051, WORD_LEN);
+	rc = mt9d113_i2c_write(mt9d113_client->addr,
+				0x001A,
+				0x0050,
+				WORD_LEN);
+	msleep(20);
+	rc = mt9d113_i2c_write(mt9d113_client->addr,
+				0x001A,
+				0x0058,
+				WORD_LEN);
+
+	/* Preset pll settings begin*/
+	rc = mt9d113_i2c_write_table(&mt9d113_regs.pll_tbl[0],
+				mt9d113_regs.pll_tbl_size);
+	if (rc < 0)
+		return rc;
+	rc = mt9d113_i2c_read(mt9d113_client->addr,
+				0x0014, &data, WORD_LEN);
+	data = data&0x8000;
+	/* Poll*/
+	while (data == 0x0000) {
+		data = 0;
+		rc = mt9d113_i2c_read(mt9d113_client->addr,
+				0x0014, &data, WORD_LEN);
+		data = data & 0x8000;
+		usleep_range(11000, 12000);
+		count++;
+		if (count == 100) {
+			CDBG(" Timeout:1\n");
+			break;
+		}
+	}
+	rc = mt9d113_i2c_write(mt9d113_client->addr,
+				0x0014,
+				0x20FA,
+				WORD_LEN);
+
+	/*Preset pll Ends*/
+	mt9d113_i2c_write(mt9d113_client->addr,
+				0x0018,
+				0x402D,
+				WORD_LEN);
+
+	mt9d113_i2c_write(mt9d113_client->addr,
+				0x0018,
+				0x402C,
+				WORD_LEN);
+	/*POLL_REG=0x0018,0x4000,!=0x0000,DELAY=10,TIMEOUT=100*/
+	data = 0;
+	rc = mt9d113_i2c_read(mt9d113_client->addr,
+		0x0018, &data, WORD_LEN);
+	data = data & 0x4000;
+	count = 0;
+	while (data != 0x0000) {
+		rc = mt9d113_i2c_read(mt9d113_client->addr,
+			0x0018, &data, WORD_LEN);
+		data = data & 0x4000;
+		CDBG(" data is %d\n" , data);
+		usleep_range(11000, 12000);
+		count++;
+		if (count == 100) {
+			CDBG(" Loop2 timeout: MT9D113\n");
+			break;
+		}
+		CDBG(" Not streaming\n");
+	}
+	CDBG("MT9D113: Start stream\n");
+	/*Preset Register Wizard Conf*/
+	rc = mt9d113_i2c_write_table(&mt9d113_regs.register_tbl[0],
+				mt9d113_regs.register_tbl_size);
+	if (rc < 0)
+		return rc;
+	rc = mt9d113_i2c_write_table(&mt9d113_regs.err_tbl[0],
+				mt9d113_regs.err_tbl_size);
+	if (rc < 0)
+		return rc;
+	rc = mt9d113_i2c_write_table(&mt9d113_regs.eeprom_tbl[0],
+				mt9d113_regs.eeprom_tbl_size);
+	if (rc < 0)
+		return rc;
+
+	rc = mt9d113_i2c_write_table(&mt9d113_regs.low_light_tbl[0],
+				mt9d113_regs.low_light_tbl_size);
+	if (rc < 0)
+		return rc;
+
+	rc = mt9d113_i2c_write_table(&mt9d113_regs.awb_tbl[0],
+				mt9d113_regs.awb_tbl_size);
+	if (rc < 0)
+		return rc;
+
+	rc = mt9d113_i2c_write_table(&mt9d113_regs.patch_tbl[0],
+				mt9d113_regs.patch_tbl_size);
+	if (rc < 0)
+		return rc;
+
+	/*check patch load*/
+	mt9d113_i2c_write(mt9d113_client->addr,
+				0x098C,
+				0xA024,
+				WORD_LEN);
+	count = 0;
+	/*To check if patch is loaded properly
+	poll the register 0x990 till the condition is
+	met or till the timeout*/
+	data = 0;
+	rc = mt9d113_i2c_read(mt9d113_client->addr,
+				0x0990, &data, WORD_LEN);
+	while (data == 0) {
+		data = 0;
+		rc = mt9d113_i2c_read(mt9d113_client->addr,
+				0x0990, &data, WORD_LEN);
+		usleep_range(11000, 12000);
+		count++;
+		if (count == 100) {
+			CDBG("Timeout in patch loading\n");
+			break;
+		}
+	}
+		/*BITFIELD=0x0018, 0x0004, 0*/
+	/*Preset continue begin */
+	rc = mt9d113_i2c_write(mt9d113_client->addr, 0x0018, 0x0028,
+				WORD_LEN);
+	CDBG(" mt9d113 wait for seq done\n");
+	/* syncronize the FW with the sensor
+	MCU_ADDRESS [SEQ_CMD]*/
+	rc = mt9d113_i2c_write(mt9d113_client->addr,
+				0x098C, 0xA103, WORD_LEN);
+	rc = mt9d113_i2c_write(mt9d113_client->addr,
+				0x0990, 0x0006, WORD_LEN);
+		/*mt9d113 wait for seq done
+	 syncronize the FW with the sensor */
+	msleep(20);
+	/*Preset continue end */
+	CDBG(" MT9D113: Preset continue end\n");
+	rc = mt9d113_i2c_write(mt9d113_client->addr,
+				0x0012,
+				0x00F5,
+				WORD_LEN);
+	/*continue begin */
+	CDBG(" MT9D113: Preset continue begin\n");
+	rc = mt9d113_i2c_write(mt9d113_client->addr, 0x0018, 0x0028 ,
+				WORD_LEN);
+	/*mt9d113 wait for seq done
+	 syncronize the FW with the sensor
+	MCU_ADDRESS [SEQ_CMD]*/
+	msleep(20);
+	rc = mt9d113_i2c_write(mt9d113_client->addr,
+				0x098C, 0xA103, WORD_LEN);
+	/* MCU DATA */
+	rc = mt9d113_i2c_write(mt9d113_client->addr, 0x0990,
+				0x0006, WORD_LEN);
+	/*mt9d113 wait for seq done
+	syncronize the FW with the sensor */
+	/* MCU_ADDRESS [SEQ_CMD]*/
+	msleep(20);
+	/*Preset continue end*/
+	return rc;
+
+}
+
+static long mt9d113_set_sensor_mode(int mode)
+{
+	long rc = 0;
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		rc = mt9d113_reg_init();
+		CDBG("MT9D113: configure to preview begin\n");
+		rc =
+		mt9d113_i2c_write(mt9d113_client->addr,
+						0x098C, 0xA115, WORD_LEN);
+		if (rc < 0)
+			return rc;
+		rc =
+		mt9d113_i2c_write(mt9d113_client->addr,
+						0x0990, 0x0000, WORD_LEN);
+		if (rc < 0)
+			return rc;
+		rc =
+		mt9d113_i2c_write(mt9d113_client->addr,
+						0x098C, 0xA103, WORD_LEN);
+		if (rc < 0)
+			return rc;
+		rc =
+		mt9d113_i2c_write(mt9d113_client->addr,
+						0x0990, 0x0001, WORD_LEN);
+		if (rc < 0)
+			return rc;
+		break;
+	case SENSOR_SNAPSHOT_MODE:
+	case SENSOR_RAW_SNAPSHOT_MODE:
+		rc =
+		mt9d113_i2c_write(mt9d113_client->addr,
+						0x098C, 0xA115, WORD_LEN);
+		rc =
+		mt9d113_i2c_write(mt9d113_client->addr,
+						0x0990, 0x0002, WORD_LEN);
+		rc =
+		mt9d113_i2c_write(mt9d113_client->addr,
+						0x098C, 0xA103, WORD_LEN);
+		rc =
+		mt9d113_i2c_write(mt9d113_client->addr,
+						0x0990, 0x0002, WORD_LEN);
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int mt9d113_sensor_init_probe(const struct
+				msm_camera_sensor_info * data)
+{
+	uint16_t model_id = 0;
+	int rc = 0;
+	/* Read the Model ID of the sensor */
+	rc = mt9d113_i2c_read(mt9d113_client->addr,
+						REG_MT9D113_MODEL_ID,
+						&model_id, WORD_LEN);
+	if (rc < 0)
+		goto init_probe_fail;
+	/* Check if it matches it with the value in Datasheet */
+	if (model_id != MT9D113_MODEL_ID)
+		printk(KERN_INFO "mt9d113 model_id = 0x%x\n", model_id);
+	if (rc < 0)
+		goto init_probe_fail;
+	return rc;
+init_probe_fail:
+	printk(KERN_INFO "probe fail\n");
+	return rc;
+}
+
+static int mt9d113_init_client(struct i2c_client *client)
+{
+	/* Initialize the MSM_CAMI2C Chip */
+	init_waitqueue_head(&mt9d113_wait_queue);
+	return 0;
+}
+
+int mt9d113_sensor_config(void __user *argp)
+{
+	struct sensor_cfg_data cfg_data;
+	long rc = 0;
+
+	if (copy_from_user(&cfg_data,
+					(void *)argp,
+					(sizeof(struct sensor_cfg_data))))
+		return -EFAULT;
+	mutex_lock(&mt9d113_mut);
+	CDBG("mt9d113_ioctl, cfgtype = %d, mode = %d\n",
+		 cfg_data.cfgtype, cfg_data.mode);
+	switch (cfg_data.cfgtype) {
+	case CFG_SET_MODE:
+		rc = mt9d113_set_sensor_mode(
+						cfg_data.mode);
+		break;
+	case CFG_SET_EFFECT:
+		return rc;
+	case CFG_GET_AF_MAX_STEPS:
+	default:
+		rc = -EINVAL;
+		break;
+	}
+	mutex_unlock(&mt9d113_mut);
+	return rc;
+}
+
+int mt9d113_sensor_release(void)
+{
+	int rc = 0;
+
+	mutex_lock(&mt9d113_mut);
+	gpio_set_value_cansleep(mt9d113_ctrl->sensordata->sensor_reset, 0);
+	msleep(20);
+	gpio_free(mt9d113_ctrl->sensordata->sensor_reset);
+	kfree(mt9d113_ctrl);
+	mutex_unlock(&mt9d113_mut);
+
+	return rc;
+}
+
+static int mt9d113_probe_init_done(const struct msm_camera_sensor_info
+				*data)
+{
+	gpio_free(data->sensor_reset);
+	return 0;
+}
+
+static int mt9d113_probe_init_sensor(const struct msm_camera_sensor_info
+				*data)
+{
+	int32_t rc = 0;
+	uint16_t chipid = 0;
+
+	rc = gpio_request(data->sensor_reset, "mt9d113");
+	printk(KERN_INFO " mt9d113_probe_init_sensor\n");
+	if (!rc) {
+		printk(KERN_INFO "sensor_reset = %d\n", rc);
+		gpio_direction_output(data->sensor_reset, 0);
+		usleep_range(11000, 12000);
+		gpio_set_value_cansleep(data->sensor_reset, 1);
+		usleep_range(11000, 12000);
+	} else
+		goto init_probe_done;
+	printk(KERN_INFO " mt9d113_probe_init_sensor called\n");
+	rc = mt9d113_i2c_read(mt9d113_client->addr, REG_MT9D113_MODEL_ID,
+						&chipid, WORD_LEN);
+	if (rc < 0)
+		goto init_probe_fail;
+	/*Compare sensor ID to MT9D113 ID: */
+	if (chipid != MT9D113_MODEL_ID) {
+		printk(KERN_INFO "mt9d113_probe_init_sensor chip id is%d\n",
+			chipid);
+	}
+	CDBG("mt9d113_probe_init_sensor Success\n");
+	goto init_probe_done;
+init_probe_fail:
+	CDBG(" ov2720_probe_init_sensor fails\n");
+	gpio_set_value_cansleep(data->sensor_reset, 0);
+	mt9d113_probe_init_done(data);
+init_probe_done:
+	printk(KERN_INFO " mt9d113_probe_init_sensor finishes\n");
+	return rc;
+}
+
+static int mt9d113_i2c_probe(struct i2c_client *client,
+				const struct i2c_device_id *id)
+{
+	int rc = 0;
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		rc = -ENOTSUPP;
+		goto probe_failure;
+	}
+	mt9d113_sensorw =
+	kzalloc(sizeof(struct mt9d113_work), GFP_KERNEL);
+	if (!mt9d113_sensorw) {
+		rc = -ENOMEM;
+		goto probe_failure;
+	}
+	i2c_set_clientdata(client, mt9d113_sensorw);
+	mt9d113_init_client(client);
+	mt9d113_client = client;
+	CDBG("mt9d113_probe succeeded!\n");
+	return 0;
+probe_failure:
+	kfree(mt9d113_sensorw);
+	mt9d113_sensorw = NULL;
+	CDBG("mt9d113_probe failed!\n");
+	return rc;
+}
+
+static const struct i2c_device_id mt9d113_i2c_id[] = {
+	{ "mt9d113", 0},
+	{},
+};
+
+static struct i2c_driver mt9d113_i2c_driver = {
+	.id_table = mt9d113_i2c_id,
+	.probe  = mt9d113_i2c_probe,
+	.remove = __exit_p(mt9d113_i2c_remove),
+			  .driver = {
+		.name = "mt9d113",
+	},
+};
+
+int mt9d113_sensor_open_init(const struct msm_camera_sensor_info *data)
+{
+	int32_t rc = 0;
+	mt9d113_ctrl = kzalloc(sizeof(struct mt9d113_ctrl), GFP_KERNEL);
+	if (!mt9d113_ctrl) {
+		printk(KERN_INFO "mt9d113_init failed!\n");
+		rc = -ENOMEM;
+		goto init_done;
+	}
+	mt9d113_ctrl->fps_divider = 1 * 0x00000400;
+	mt9d113_ctrl->pict_fps_divider = 1 * 0x00000400;
+	mt9d113_ctrl->set_test = TEST_OFF;
+	mt9d113_ctrl->config_csi = 0;
+	mt9d113_ctrl->prev_res = QTR_SIZE;
+	mt9d113_ctrl->pict_res = FULL_SIZE;
+	mt9d113_ctrl->curr_res = INVALID_SIZE;
+	if (data)
+		mt9d113_ctrl->sensordata = data;
+	if (rc < 0) {
+		printk(KERN_INFO "mt9d113_sensor_open_init fail\n");
+		return rc;
+	}
+		/* enable mclk first */
+		msm_camio_clk_rate_set(24000000);
+		msleep(20);
+		rc = mt9d113_probe_init_sensor(data);
+		if (rc < 0)
+			goto init_fail;
+		mt9d113_ctrl->fps = 30*Q8;
+		rc = mt9d113_sensor_init_probe(data);
+		if (rc < 0) {
+			gpio_set_value_cansleep(data->sensor_reset, 0);
+			goto init_fail;
+		} else
+			printk(KERN_ERR "%s: %d\n", __func__, __LINE__);
+		goto init_done;
+init_fail:
+		printk(KERN_INFO "init_fail\n");
+		mt9d113_probe_init_done(data);
+init_done:
+		CDBG("init_done\n");
+		return rc;
+}
+
+static int mt9d113_sensor_probe(const struct msm_camera_sensor_info
+				*info,
+				struct msm_sensor_ctrl *s)
+{
+	int rc = 0;
+	rc = i2c_add_driver(&mt9d113_i2c_driver);
+	if (rc < 0 || mt9d113_client == NULL) {
+		rc = -ENOTSUPP;
+		goto probe_fail;
+	}
+	msm_camio_clk_rate_set(24000000);
+	usleep_range(5000, 6000);
+	rc = mt9d113_probe_init_sensor(info);
+	if (rc < 0)
+		goto probe_fail;
+	s->s_init = mt9d113_sensor_open_init;
+	s->s_release = mt9d113_sensor_release;
+	s->s_config  = mt9d113_sensor_config;
+	s->s_camera_type = FRONT_CAMERA_2D;
+	s->s_mount_angle  = 0;
+	gpio_set_value_cansleep(info->sensor_reset, 0);
+	mt9d113_probe_init_done(info);
+	return rc;
+probe_fail:
+	printk(KERN_INFO "mt9d113_sensor_probe: SENSOR PROBE FAILS!\n");
+	return rc;
+}
+
+static int __mt9d113_probe(struct platform_device *pdev)
+{
+	return msm_camera_drv_start(pdev, mt9d113_sensor_probe);
+}
+
+static struct platform_driver msm_camera_driver = {
+	.probe = __mt9d113_probe,
+	.driver = {
+		.name = "msm_cam_mt9d113",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init mt9d113_init(void)
+{
+	return platform_driver_register(&msm_camera_driver);
+}
+
+module_init(mt9d113_init);
+
+MODULE_DESCRIPTION("Micron 2MP YUV sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/mt9d113.h b/drivers/media/platform/msm/camera_v1/mt9d113.h
new file mode 100644
index 0000000..4aedc5e
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mt9d113.h
@@ -0,0 +1,66 @@
+/* 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.
+ *
+ */
+
+#ifndef MT9D113_H
+#define MT9D113_H
+
+#include <linux/types.h>
+#include <mach/camera.h>
+
+extern struct mt9d113_reg mt9d113_regs;
+
+enum mt9d113_width {
+	WORD_LEN,
+	BYTE_LEN
+};
+
+struct mt9d113_i2c_reg_conf {
+	unsigned short waddr;
+	unsigned short wdata;
+};
+
+struct mt9d113_reg {
+	const struct mt9d113_i2c_reg_conf *pll_tbl;
+	uint16_t pll_tbl_size;
+	const struct mt9d113_i2c_reg_conf *register_tbl;
+	uint16_t register_tbl_size;
+	const struct mt9d113_i2c_reg_conf *err_tbl;
+	uint16_t err_tbl_size;
+	const struct mt9d113_i2c_reg_conf *low_light_tbl;
+	uint16_t low_light_tbl_size;
+	const struct mt9d113_i2c_reg_conf *awb_tbl;
+	uint16_t awb_tbl_size;
+	const struct mt9d113_i2c_reg_conf *patch_tbl;
+	uint16_t patch_tbl_size;
+	const struct mt9d113_i2c_reg_conf *eeprom_tbl ;
+	uint16_t eeprom_tbl_size ;
+};
+
+enum mt9d113_test_mode_t {
+	TEST_OFF,
+	TEST_1,
+	TEST_2,
+	TEST_3
+};
+
+enum mt9d113_resolution_t {
+	QTR_SIZE,
+	FULL_SIZE,
+	INVALID_SIZE
+};
+
+enum mt9d113_setting {
+	RES_PREVIEW,
+	RES_CAPTURE
+};
+#endif /* MT9D113_H */
diff --git a/drivers/media/platform/msm/camera_v1/mt9d113_reg.c b/drivers/media/platform/msm/camera_v1/mt9d113_reg.c
new file mode 100644
index 0000000..28ff518
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mt9d113_reg.c
@@ -0,0 +1,455 @@
+/* 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 "mt9d113.h"
+
+struct mt9d113_i2c_reg_conf const
+	pll_tbl_settings[] = {
+		{0x0014, 0x21F9 }, /*PLL control: BYPASS PLL = 8697*/
+		{0x0010, 0x0115 }, /*PLL Dividers = 277*/
+		{0x0012, 0x0F5  }, /*PLL P Dividers = 245*/
+		{0x0014, 0x21FB }, /*PLL control: PLL_ENABLE on = 8699*/
+		{0x0014, 0x20FB }, /*PLL control: SEL_LOCK_DET on = 8443*/
+};
+
+struct mt9d113_i2c_reg_conf const
+	register_wizard_settings[] = {
+		{0x098C, 0x2719},
+		{0x0990, 0x005A},
+		{0x098C, 0x271B},
+		{0x0990, 0x01BE},
+		{0x098C, 0x271D},
+		{0x0990, 0x0131},
+		{0x098C, 0x271F},
+		{0x0990, 0x02BB},
+		{0x098C, 0x2721},
+		{0x0990, 0x0888},
+		{0x098C, 0x272F},
+		{0x0990, 0x003A},
+		{0x098C, 0x2731},
+		{0x0990, 0x00F6},
+		{0x098C, 0x2733},
+		{0x0990, 0x008B},
+		{0x098C, 0x2735},
+		{0x0990, 0x0521},
+		{0x098C, 0x2737},
+		{0x0990, 0x0888},
+		{0x098C, 0x275F},
+		{0x0990, 0x0194},
+		{0x098C, 0x2761},
+		{0x0990, 0x0014},
+		{0x098C, 0xA765},
+		{0x0990, 0x0044},
+		{0x098C, 0xA24F},
+		{0x0990, 0x0028},
+		{0x098C, 0xA20E},
+		{0x0990, 0x00A0},
+		{0x098C, 0xA20C},
+		{0x0990, 0x000E},
+		{0x098C, 0x2222},
+		{0x0990, 0x00A0},
+		{0x098C, 0x2212},
+		{0x0990, 0x01EE},
+		{0x098C, 0xA408},
+		{0x0990, 0x0026},
+		{0x098C, 0xA409},
+		{0x0990, 0x0029},
+		{0x098C, 0xA40A},
+		{0x0990, 0x002E},
+		{0x098C, 0xA40B},
+		{0x0990, 0x0031},
+		{0x098C, 0x2411},
+		{0x0990, 0x00A0},
+		{0x098C, 0x2413},
+		{0x0990, 0x00C0},
+		{0x098C, 0x2415},
+		{0x0990, 0x00A0},
+		{0x098C, 0x2417},
+		{0x0990, 0x00C0},
+};
+
+struct mt9d113_i2c_reg_conf const
+	err_settings[] = {
+		{0x3084, 0x240C},
+		{0x3092, 0x0A4C},
+		{0x3094, 0x4C4C},
+		{0x3096, 0x4C54},
+};
+
+struct mt9d113_i2c_reg_conf const
+	patch_settings[] = {
+		{0x098C, 0x0415},    /* MCU_ADDRESS*/
+		{0x0990, 0xF601},
+		{0x0992, 0x42C1},
+		{0x0994, 0x0326},
+		{0x0996, 0x11F6},
+		{0x0998, 0x0143},
+		{0x099A, 0xC104},
+		{0x099C, 0x260A},
+		{0x099E, 0xCC04},
+		{0x098C, 0x0425},
+		{0x0990, 0x33BD},
+		{0x0992, 0xA362},
+		{0x0994, 0xBD04},
+		{0x0996, 0x3339},
+		{0x0998, 0xC6FF},
+		{0x099A, 0xF701},
+		{0x099C, 0x6439},
+		{0x099E, 0xFE01},
+		{0x098C, 0x0435},
+		{0x0990, 0x6918},
+		{0x0992, 0xCE03},
+		{0x0994, 0x25CC},
+		{0x0996, 0x0013},
+		{0x0998, 0xBDC2},
+		{0x099A, 0xB8CC},
+		{0x099C, 0x0489},
+		{0x099E, 0xFD03},
+		{0x098C, 0x0445},
+		{0x0990, 0x27CC},
+		{0x0992, 0x0325},
+		{0x0994, 0xFD01},
+		{0x0996, 0x69FE},
+		{0x0998, 0x02BD},
+		{0x099A, 0x18CE},
+		{0x099C, 0x0339},
+		{0x099E, 0xCC00},
+		{0x098C, 0x0455},
+		{0x0990, 0x11BD},
+		{0x0992, 0xC2B8},
+		{0x0994, 0xCC04},
+		{0x0996, 0xC8FD},
+		{0x0998, 0x0347},
+		{0x099A, 0xCC03},
+		{0x099C, 0x39FD},
+		{0x099E, 0x02BD},
+		{0x098C, 0x0465},
+		{0x0990, 0xDE00},
+		{0x0992, 0x18CE},
+		{0x0994, 0x00C2},
+		{0x0996, 0xCC00},
+		{0x0998, 0x37BD},
+		{0x099A, 0xC2B8},
+		{0x099C, 0xCC04},
+		{0x099E, 0xEFDD},
+		{0x098C, 0x0475},
+		{0x0990, 0xE6CC},
+		{0x0992, 0x00C2},
+		{0x0994, 0xDD00},
+		{0x0996, 0xC601},
+		{0x0998, 0xF701},
+		{0x099A, 0x64C6},
+		{0x099C, 0x03F7},
+		{0x099E, 0x0165},
+		{0x098C, 0x0485},
+		{0x0990, 0x7F01},
+		{0x0992, 0x6639},
+		{0x0994, 0x3C3C},
+		{0x0996, 0x3C34},
+		{0x0998, 0xCC32},
+		{0x099A, 0x3EBD},
+		{0x099C, 0xA558},
+		{0x099E, 0x30ED},
+		{0x098C, 0x0495},
+		{0x0990, 0x04BD},
+		{0x0992, 0xB2D7},
+		{0x0994, 0x30E7},
+		{0x0996, 0x06CC},
+		{0x0998, 0x323E},
+		{0x099A, 0xED00},
+		{0x099C, 0xEC04},
+		{0x099E, 0xBDA5},
+		{0x098C, 0x04A5},
+		{0x0990, 0x44CC},
+		{0x0992, 0x3244},
+		{0x0994, 0xBDA5},
+		{0x0996, 0x585F},
+		{0x0998, 0x30ED},
+		{0x099A, 0x02CC},
+		{0x099C, 0x3244},
+		{0x099E, 0xED00},
+		{0x098C, 0x04B5},
+		{0x0990, 0xF601},
+		{0x0992, 0xD54F},
+		{0x0994, 0xEA03},
+		{0x0996, 0xAA02},
+		{0x0998, 0xBDA5},
+		{0x099A, 0x4430},
+		{0x099C, 0xE606},
+		{0x099E, 0x3838},
+		{0x098C, 0x04C5},
+		{0x0990, 0x3831},
+		{0x0992, 0x39BD},
+		{0x0994, 0xD661},
+		{0x0996, 0xF602},
+		{0x0998, 0xF4C1},
+		{0x099A, 0x0126},
+		{0x099C, 0x0BFE},
+		{0x099E, 0x02BD},
+		{0x098C, 0x04D5},
+		{0x0990, 0xEE10},
+		{0x0992, 0xFC02},
+		{0x0994, 0xF5AD},
+		{0x0996, 0x0039},
+		{0x0998, 0xF602},
+		{0x099A, 0xF4C1},
+		{0x099C, 0x0226},
+		{0x099E, 0x0AFE},
+		{0x098C, 0x04E5},
+		{0x0990, 0x02BD},
+		{0x0992, 0xEE10},
+		{0x0994, 0xFC02},
+		{0x0996, 0xF7AD},
+		{0x0998, 0x0039},
+		{0x099A, 0x3CBD},
+		{0x099C, 0xB059},
+		{0x099E, 0xCC00},
+		{0x098C, 0x04F5},
+		{0x0990, 0x28BD},
+		{0x0992, 0xA558},
+		{0x0994, 0x8300},
+		{0x0996, 0x0027},
+		{0x0998, 0x0BCC},
+		{0x099A, 0x0026},
+		{0x099C, 0x30ED},
+		{0x099E, 0x00C6},
+		{0x098C, 0x0505},
+		{0x0990, 0x03BD},
+		{0x0992, 0xA544},
+		{0x0994, 0x3839},
+		{0x098C, 0x2006},
+		{0x0990, 0x0415},
+		{0x098C, 0xA005},
+		{0x0990, 0x0001},
+};
+
+struct mt9d113_i2c_reg_conf const
+	eeprom_settings[] = {
+		{0x3658, 0x0110},
+		{0x365A, 0x1B6D},
+		{0x365C, 0x01F2},
+		{0x365E, 0xFBCD},
+		{0x3660, 0x8C91},
+		{0x3680, 0xB9ED},
+		{0x3682, 0x0EE},
+		{0x3684, 0x256F},
+		{0x3686, 0x824F},
+		{0x3688, 0xD293},
+		{0x36A8, 0x5BF2},
+		{0x36AA, 0x1711},
+		{0x36AC, 0xA095},
+		{0x36AE, 0x642C},
+		{0x36B0, 0x0E38},
+		{0x36D0, 0x88B0},
+		{0x36D2, 0x2EB2},
+		{0x36D4, 0x4C74},
+		{0x36D6, 0x9F96},
+		{0x36D8, 0x9557},
+		{0x36F8, 0xCE51},
+		{0x36FA, 0xB354},
+		{0x36FC, 0x2817},
+		{0x36FE, 0x14B8},
+		{0x3700, 0xB019},
+		{0x364E, 0x0710},
+		{0x3650, 0x30ED},
+		{0x3652, 0x03F2},
+		{0x3654, 0xF12E},
+		{0x3656, 0x8492},
+		{0x3676, 0xD9AD},
+		{0x3678, 0x88D0},
+		{0x367A, 0x7DED},
+		{0x367C, 0x3E31},
+		{0x367E, 0x91B3},
+		{0x369E, 0x7032},
+		{0x36A0, 0x2791},
+		{0x36A2, 0xBB55},
+		{0x36A4, 0xAB32},
+		{0x36A6, 0x1A58},
+		{0x36C6, 0xB50F},
+		{0x36C8, 0x0011},
+		{0x36CA, 0x6DB4},
+		{0x36CC, 0x96F5},
+		{0x36CE, 0x9BB7},
+		{0x36EE, 0x9353},
+		{0x36F0, 0xDF74},
+		{0x36F2, 0x04F8},
+		{0x36F4, 0x0FD8},
+		{0x36F6, 0xA87A},
+		{0x3662, 0x0170},
+		{0x3664, 0x6F0C},
+		{0x3666, 0x0112},
+		{0x3668, 0xCBAB},
+		{0x366A, 0x9111},
+		{0x368A, 0xB38D},
+		{0x368C, 0xE96F},
+		{0x368E, 0xCC0F},
+		{0x3690, 0x5851},
+		{0x3692, 0xFDD2},
+		{0x36B2, 0x5F92},
+		{0x36B4, 0x33B2},
+		{0x36B6, 0x9815},
+		{0x36B8, 0x86F5},
+		{0x36BA, 0x0578},
+		{0x36DA, 0xCD90},
+		{0x36DC, 0x1131},
+		{0x36DE, 0x5275},
+		{0x36E0, 0xE855},
+		{0x36E2, 0xD037},
+		{0x3702, 0xAAD1},
+		{0x3704, 0xEB75},
+		{0x3706, 0x0CD7},
+		{0x3708, 0x2C79},
+		{0x370A, 0xE0B9},
+		{0x366C, 0x0190},
+		{0x366E, 0x1C8D},
+		{0x3670, 0x0052},
+		{0x3672, 0xD66E},
+		{0x3674, 0xF511},
+		{0x3694, 0xB54D},
+		{0x3696, 0x6E4E},
+		{0x3698, 0x142E},
+		{0x369A, 0xC190},
+		{0x369C, 0xA753},
+		{0x36BC, 0x70F2},
+		{0x36BE, 0x04F1},
+		{0x36C0, 0xBD95},
+		{0x36C2, 0x0CEE},
+		{0x36C4, 0x1BF8},
+		{0x36E4, 0x806F},
+		{0x36E6, 0x1672},
+		{0x36E8, 0x2DF4},
+		{0x36EA, 0x8F16},
+		{0x36EC, 0xF776},
+		{0x370C, 0xAD73},
+		{0x370E, 0xB534},
+		{0x3710, 0x0D18},
+		{0x3712, 0x6057},
+		{0x3714, 0xBD1A},
+		{0x3644, 0x0354},
+		{0x3642, 0x0234},
+		{0x3210, 0x01B8},
+};
+
+struct mt9d113_i2c_reg_conf const
+	awb_settings[] = {
+		{0x098C, 0x2306},
+		{0x0990, 0x0180},
+		{0x098C, 0x2308},
+		{0x0990, 0xFF00},
+		{0x098C, 0x230A},
+		{0x0990, 0x0080},
+		{0x098C, 0x230C},
+		{0x0990, 0xFF66},
+		{0x098C, 0x230E},
+		{0x0990, 0x0180},
+		{0x098C, 0x2310},
+		{0x0990, 0xFFEE},
+		{0x098C, 0x2312},
+		{0x0990, 0xFFCD},
+		{0x098C, 0x2314},
+		{0x0990, 0xFECD},
+		{0x098C, 0x2316},
+		{0x0990, 0x019A},
+		{0x098C, 0x2318},
+		{0x0990, 0x0020},
+		{0x098C, 0x231A},
+		{0x0990, 0x0033},
+		{0x098C, 0x231C},
+		{0x0990, 0x0100},
+		{0x098C, 0x231E},
+		{0x0990, 0xFF9A},
+		{0x098C, 0x2320},
+		{0x0990, 0x0000},
+		{0x098C, 0x2322},
+		{0x0990, 0x004D},
+		{0x098C, 0x2324},
+		{0x0990, 0xFFCD},
+		{0x098C, 0x2326},
+		{0x0990, 0xFFB8},
+		{0x098C, 0x2328},
+		{0x0990, 0x004D},
+		{0x098C, 0x232A},
+		{0x0990, 0x0080},
+		{0x098C, 0x232C},
+		{0x0990, 0xFF66},
+		{0x098C, 0x232E},
+		{0x0990, 0x0008},
+		{0x098C, 0x2330},
+		{0x0990, 0xFFF7},
+		{0x098C, 0xA363},
+		{0x0990, 0x00D2},
+		{0x098C, 0xA364},
+		{0x0990, 0x00EE},
+		{0x3244, 0x0328},
+		{0x323E, 0xC22C},
+};
+
+struct mt9d113_i2c_reg_conf const
+	low_light_setting[] = {
+		{0x098C, 0x2B28},
+		{0x0990, 0x35E8},
+		{0x098C, 0x2B2A},
+		{0x0990, 0xB3B0},
+		{0x098C, 0xAB20},
+		{0x0990, 0x004B},
+		{0x098C, 0xAB24},
+		{0x0990, 0x0000},
+		{0x098C, 0xAB25},
+		{0x0990, 0x00FF},
+		{0x098C, 0xAB30},
+		{0x0990, 0x00FF},
+		{0x098C, 0xAB31},
+		{0x0990, 0x00FF},
+		{0x098C, 0xAB32},
+		{0x0990, 0x00FF},
+		{0x098C, 0xAB33},
+		{0x0990, 0x0057},
+		{0x098C, 0xAB34},
+		{0x0990, 0x0080},
+		{0x098C, 0xAB35},
+		{0x0990, 0x00FF},
+		{0x098C, 0xAB36},
+		{0x0990, 0x0014},
+		{0x098C, 0xAB37},
+		{0x0990, 0x0003},
+		{0x098C, 0x2B38},
+		{0x0990, 0x32C8},
+		{0x098C, 0x2B3A},
+		{0x0990, 0x7918},
+		{0x098C, 0x2B62},
+		{0x0990, 0xFFFE},
+		{0x098C, 0x2B64},
+		{0x0990, 0xFFFF},
+};
+
+struct mt9d113_reg mt9d113_regs = {
+		.pll_tbl = pll_tbl_settings,
+		.pll_tbl_size = ARRAY_SIZE(
+			pll_tbl_settings),
+		.register_tbl = register_wizard_settings,
+		.register_tbl_size = ARRAY_SIZE(
+			register_wizard_settings),
+		.err_tbl = err_settings,
+		.err_tbl_size = ARRAY_SIZE(err_settings),
+		.low_light_tbl = low_light_setting,
+		.low_light_tbl_size = ARRAY_SIZE(low_light_setting),
+		.awb_tbl = awb_settings,
+		.awb_tbl_size = ARRAY_SIZE(awb_settings),
+		.patch_tbl = patch_settings,
+		.patch_tbl_size = ARRAY_SIZE(patch_settings),
+		.eeprom_tbl = eeprom_settings,
+		.eeprom_tbl_size = ARRAY_SIZE(eeprom_settings),
+};
+
+
+
diff --git a/drivers/media/platform/msm/camera_v1/mt9e013.c b/drivers/media/platform/msm/camera_v1/mt9e013.c
new file mode 100644
index 0000000..f91bec4
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mt9e013.c
@@ -0,0 +1,1140 @@
+/* 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/delay.h>
+#include <linux/debugfs.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/slab.h>
+#include <media/msm_camera.h>
+#include <mach/gpio.h>
+#include <mach/camera.h>
+#include "mt9e013.h"
+/*=============================================================
+	SENSOR REGISTER DEFINES
+==============================================================*/
+#define REG_GROUPED_PARAMETER_HOLD		0x0104
+#define GROUPED_PARAMETER_HOLD_OFF		0x00
+#define GROUPED_PARAMETER_HOLD			0x01
+/* Integration Time */
+#define REG_COARSE_INTEGRATION_TIME		0x3012
+/* Gain */
+#define REG_GLOBAL_GAIN	0x305E
+/* PLL registers */
+#define REG_FRAME_LENGTH_LINES		0x0340
+/* Test Pattern */
+#define REG_TEST_PATTERN_MODE			0x0601
+#define REG_VCM_NEW_CODE			0x30F2
+
+/*============================================================================
+							 TYPE DECLARATIONS
+============================================================================*/
+
+/* 16bit address - 8 bit context register structure */
+#define Q8	0x00000100
+#define Q10	0x00000400
+#define MT9E013_MASTER_CLK_RATE 24000000
+
+/* AF Total steps parameters */
+#define MT9E013_TOTAL_STEPS_NEAR_TO_FAR    32
+
+uint16_t mt9e013_step_position_table[MT9E013_TOTAL_STEPS_NEAR_TO_FAR+1];
+uint16_t mt9e013_nl_region_boundary1;
+uint16_t mt9e013_nl_region_code_per_step1;
+uint16_t mt9e013_l_region_code_per_step = 4;
+uint16_t mt9e013_damping_threshold = 10;
+uint16_t mt9e013_sw_damping_time_wait = 1;
+
+struct mt9e013_work_t {
+	struct work_struct work;
+};
+
+static struct mt9e013_work_t *mt9e013_sensorw;
+static struct i2c_client *mt9e013_client;
+
+struct mt9e013_ctrl_t {
+	const struct  msm_camera_sensor_info *sensordata;
+
+	uint32_t sensormode;
+	uint32_t fps_divider;/* init to 1 * 0x00000400 */
+	uint32_t pict_fps_divider;/* init to 1 * 0x00000400 */
+	uint16_t fps;
+
+	uint16_t curr_lens_pos;
+	uint16_t curr_step_pos;
+	uint16_t my_reg_gain;
+	uint32_t my_reg_line_count;
+	uint16_t total_lines_per_frame;
+
+	enum mt9e013_resolution_t prev_res;
+	enum mt9e013_resolution_t pict_res;
+	enum mt9e013_resolution_t curr_res;
+	enum mt9e013_test_mode_t  set_test;
+};
+
+
+static bool CSI_CONFIG;
+static struct mt9e013_ctrl_t *mt9e013_ctrl;
+static DECLARE_WAIT_QUEUE_HEAD(mt9e013_wait_queue);
+DEFINE_MUTEX(mt9e013_mut);
+
+static int cam_debug_init(void);
+static struct dentry *debugfs_base;
+/*=============================================================*/
+
+static int mt9e013_i2c_rxdata(unsigned short saddr,
+	unsigned char *rxdata, int length)
+{
+	struct i2c_msg msgs[] = {
+		{
+			.addr  = saddr,
+			.flags = 0,
+			.len   = 2,
+			.buf   = rxdata,
+		},
+		{
+			.addr  = saddr,
+			.flags = I2C_M_RD,
+			.len   = 2,
+			.buf   = rxdata,
+		},
+	};
+	if (i2c_transfer(mt9e013_client->adapter, msgs, 2) < 0) {
+		CDBG("mt9e013_i2c_rxdata faild 0x%x\n", saddr);
+		return -EIO;
+	}
+	return 0;
+}
+
+static int32_t mt9e013_i2c_txdata(unsigned short saddr,
+				unsigned char *txdata, int length)
+{
+	struct i2c_msg msg[] = {
+		{
+			.addr = saddr,
+			.flags = 0,
+			.len = length,
+			.buf = txdata,
+		 },
+	};
+	if (i2c_transfer(mt9e013_client->adapter, msg, 1) < 0) {
+		CDBG("mt9e013_i2c_txdata faild 0x%x\n", saddr);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t mt9e013_i2c_read(unsigned short raddr,
+	unsigned short *rdata, int rlen)
+{
+	int32_t rc = 0;
+	unsigned char buf[2];
+	if (!rdata)
+		return -EIO;
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (raddr & 0xFF00) >> 8;
+	buf[1] = (raddr & 0x00FF);
+	rc = mt9e013_i2c_rxdata(mt9e013_client->addr<<1, buf, rlen);
+	if (rc < 0) {
+		CDBG("mt9e013_i2c_read 0x%x failed!\n", raddr);
+		return rc;
+	}
+	*rdata = (rlen == 2 ? buf[0] << 8 | buf[1] : buf[0]);
+	CDBG("mt9e013_i2c_read 0x%x val = 0x%x!\n", raddr, *rdata);
+	return rc;
+}
+
+static int32_t mt9e013_i2c_write_w_sensor(unsigned short waddr, uint16_t wdata)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[4];
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00) >> 8;
+	buf[1] = (waddr & 0x00FF);
+	buf[2] = (wdata & 0xFF00) >> 8;
+	buf[3] = (wdata & 0x00FF);
+	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, wdata);
+	rc = mt9e013_i2c_txdata(mt9e013_client->addr<<1, buf, 4);
+	if (rc < 0) {
+		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
+			waddr, wdata);
+	}
+	return rc;
+}
+
+static int32_t mt9e013_i2c_write_b_sensor(unsigned short waddr, uint8_t bdata)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[3];
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00) >> 8;
+	buf[1] = (waddr & 0x00FF);
+	buf[2] = bdata;
+	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
+	rc = mt9e013_i2c_txdata(mt9e013_client->addr<<1, buf, 3);
+	if (rc < 0) {
+		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
+			waddr, bdata);
+	}
+	return rc;
+}
+
+static int32_t mt9e013_i2c_write_w_table(struct mt9e013_i2c_reg_conf const
+					 *reg_conf_tbl, int num)
+{
+	int i;
+	int32_t rc = -EIO;
+	for (i = 0; i < num; i++) {
+		rc = mt9e013_i2c_write_w_sensor(reg_conf_tbl->waddr,
+			reg_conf_tbl->wdata);
+		if (rc < 0)
+			break;
+		reg_conf_tbl++;
+	}
+	return rc;
+}
+
+static void mt9e013_group_hold_on(void)
+{
+	mt9e013_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
+						GROUPED_PARAMETER_HOLD);
+}
+
+static void mt9e013_group_hold_off(void)
+{
+	mt9e013_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
+						GROUPED_PARAMETER_HOLD_OFF);
+}
+
+static void mt9e013_start_stream(void)
+{
+	mt9e013_i2c_write_w_sensor(0x301A, 0x8250);
+	mt9e013_i2c_write_w_sensor(0x301A, 0x8650);
+	mt9e013_i2c_write_w_sensor(0x301A, 0x8658);
+	mt9e013_i2c_write_b_sensor(0x0104, 0x00);
+	mt9e013_i2c_write_w_sensor(0x301A, 0x065C);
+}
+
+static void mt9e013_stop_stream(void)
+{
+	mt9e013_i2c_write_w_sensor(0x301A, 0x0058);
+	mt9e013_i2c_write_w_sensor(0x301A, 0x0050);
+	mt9e013_i2c_write_b_sensor(0x0104, 0x01);
+}
+
+static void mt9e013_get_pict_fps(uint16_t fps, uint16_t *pfps)
+{
+	/* input fps is preview fps in Q8 format */
+	uint32_t divider, d1, d2;
+
+	d1 = mt9e013_regs.reg_prev[E013_FRAME_LENGTH_LINES].wdata
+		* 0x00000400/
+		mt9e013_regs.reg_snap[E013_FRAME_LENGTH_LINES].wdata;
+	d2 = mt9e013_regs.reg_prev[E013_LINE_LENGTH_PCK].wdata
+		* 0x00000400/
+		mt9e013_regs.reg_snap[E013_LINE_LENGTH_PCK].wdata;
+	divider = d1 * d2 / 0x400;
+
+	/*Verify PCLK settings and frame sizes.*/
+	*pfps = (uint16_t) (fps * divider / 0x400);
+	/* 2 is the ratio of no.of snapshot channels
+	to number of preview channels */
+}
+
+static uint16_t mt9e013_get_prev_lines_pf(void)
+{
+	if (mt9e013_ctrl->prev_res == QTR_SIZE)
+		return mt9e013_regs.reg_prev[E013_FRAME_LENGTH_LINES].wdata;
+	else if (mt9e013_ctrl->prev_res == FULL_SIZE)
+		return mt9e013_regs.reg_snap[E013_FRAME_LENGTH_LINES].wdata;
+	else if (mt9e013_ctrl->prev_res == HFR_60FPS)
+		return mt9e013_regs.reg_60fps[E013_FRAME_LENGTH_LINES].wdata;
+	else if (mt9e013_ctrl->prev_res == HFR_90FPS)
+		return mt9e013_regs.reg_120fps[E013_FRAME_LENGTH_LINES].wdata;
+	else
+		return mt9e013_regs.reg_120fps[E013_FRAME_LENGTH_LINES].wdata;
+}
+
+static uint16_t mt9e013_get_prev_pixels_pl(void)
+{
+	if (mt9e013_ctrl->prev_res == QTR_SIZE)
+		return mt9e013_regs.reg_prev[E013_LINE_LENGTH_PCK].wdata;
+	else if (mt9e013_ctrl->prev_res == FULL_SIZE)
+		return mt9e013_regs.reg_snap[E013_LINE_LENGTH_PCK].wdata;
+	else if (mt9e013_ctrl->prev_res == HFR_60FPS)
+		return mt9e013_regs.reg_60fps[E013_LINE_LENGTH_PCK].wdata;
+	else if (mt9e013_ctrl->prev_res == HFR_90FPS)
+		return mt9e013_regs.reg_120fps[E013_LINE_LENGTH_PCK].wdata;
+	else
+		return mt9e013_regs.reg_120fps[E013_LINE_LENGTH_PCK].wdata;
+}
+
+static uint16_t mt9e013_get_pict_lines_pf(void)
+{
+	if (mt9e013_ctrl->pict_res == QTR_SIZE)
+		return mt9e013_regs.reg_prev[E013_FRAME_LENGTH_LINES].wdata;
+	else if (mt9e013_ctrl->pict_res == FULL_SIZE)
+		return mt9e013_regs.reg_snap[E013_FRAME_LENGTH_LINES].wdata;
+	else if (mt9e013_ctrl->pict_res == HFR_60FPS)
+		return mt9e013_regs.reg_60fps[E013_FRAME_LENGTH_LINES].wdata;
+	else if (mt9e013_ctrl->pict_res == HFR_90FPS)
+		return mt9e013_regs.reg_120fps[E013_FRAME_LENGTH_LINES].wdata;
+	else
+		return mt9e013_regs.reg_120fps[E013_FRAME_LENGTH_LINES].wdata;
+}
+
+static uint16_t mt9e013_get_pict_pixels_pl(void)
+{
+	if (mt9e013_ctrl->pict_res == QTR_SIZE)
+		return mt9e013_regs.reg_prev[E013_LINE_LENGTH_PCK].wdata;
+	else if (mt9e013_ctrl->pict_res == FULL_SIZE)
+		return mt9e013_regs.reg_snap[E013_LINE_LENGTH_PCK].wdata;
+	else if (mt9e013_ctrl->pict_res == HFR_60FPS)
+		return mt9e013_regs.reg_60fps[E013_LINE_LENGTH_PCK].wdata;
+	else if (mt9e013_ctrl->pict_res == HFR_90FPS)
+		return mt9e013_regs.reg_120fps[E013_LINE_LENGTH_PCK].wdata;
+	else
+		return mt9e013_regs.reg_120fps[E013_LINE_LENGTH_PCK].wdata;
+}
+
+static uint32_t mt9e013_get_pict_max_exp_lc(void)
+{
+	if (mt9e013_ctrl->pict_res == QTR_SIZE)
+		return mt9e013_regs.reg_prev[E013_FRAME_LENGTH_LINES].wdata
+			* 24;
+	else if (mt9e013_ctrl->pict_res == FULL_SIZE)
+		return mt9e013_regs.reg_snap[E013_FRAME_LENGTH_LINES].wdata
+			* 24;
+	else if (mt9e013_ctrl->pict_res == HFR_60FPS)
+		return mt9e013_regs.reg_60fps[E013_FRAME_LENGTH_LINES].wdata
+			* 24;
+	else if (mt9e013_ctrl->pict_res == HFR_90FPS)
+		return mt9e013_regs.reg_120fps[E013_FRAME_LENGTH_LINES].wdata
+			* 24;
+	else
+		return mt9e013_regs.reg_120fps[E013_FRAME_LENGTH_LINES].wdata
+			* 24;
+}
+
+static int32_t mt9e013_set_fps(struct fps_cfg   *fps)
+{
+	uint16_t total_lines_per_frame;
+	int32_t rc = 0;
+	if (mt9e013_ctrl->curr_res == QTR_SIZE)
+		total_lines_per_frame =
+		mt9e013_regs.reg_prev[E013_FRAME_LENGTH_LINES].wdata;
+	else if (mt9e013_ctrl->curr_res == FULL_SIZE)
+		total_lines_per_frame =
+		mt9e013_regs.reg_snap[E013_FRAME_LENGTH_LINES].wdata;
+	else if (mt9e013_ctrl->curr_res == HFR_60FPS)
+		total_lines_per_frame =
+		mt9e013_regs.reg_60fps[E013_FRAME_LENGTH_LINES].wdata;
+	else if (mt9e013_ctrl->curr_res == HFR_90FPS)
+		total_lines_per_frame =
+		mt9e013_regs.reg_120fps[E013_FRAME_LENGTH_LINES].wdata;
+	else
+		total_lines_per_frame =
+		mt9e013_regs.reg_120fps[E013_FRAME_LENGTH_LINES].wdata;
+
+	mt9e013_ctrl->fps_divider = fps->fps_div;
+	mt9e013_ctrl->pict_fps_divider = fps->pict_fps_div;
+
+	if (mt9e013_ctrl->curr_res == FULL_SIZE) {
+		total_lines_per_frame = (uint16_t)
+		(total_lines_per_frame * mt9e013_ctrl->pict_fps_divider/0x400);
+	} else {
+		total_lines_per_frame = (uint16_t)
+		(total_lines_per_frame * mt9e013_ctrl->fps_divider/0x400);
+	}
+
+	mt9e013_group_hold_on();
+	rc = mt9e013_i2c_write_w_sensor(REG_FRAME_LENGTH_LINES,
+							total_lines_per_frame);
+	mt9e013_group_hold_off();
+	return rc;
+}
+
+static int32_t mt9e013_write_exp_gain(uint16_t gain, uint32_t line)
+{
+	uint16_t max_legal_gain = 0xE7F;
+	int32_t rc = 0;
+	if (gain > max_legal_gain) {
+		CDBG("Max legal gain Line:%d\n", __LINE__);
+		gain = max_legal_gain;
+	}
+
+	if (mt9e013_ctrl->curr_res != FULL_SIZE) {
+		mt9e013_ctrl->my_reg_gain = gain;
+		mt9e013_ctrl->my_reg_line_count = (uint16_t) line;
+		line = (uint32_t) (line * mt9e013_ctrl->fps_divider /
+						   0x00000400);
+	} else {
+		line = (uint32_t) (line * mt9e013_ctrl->pict_fps_divider /
+						   0x00000400);
+	}
+
+	gain |= 0x1000;
+
+	mt9e013_group_hold_on();
+	rc = mt9e013_i2c_write_w_sensor(REG_GLOBAL_GAIN, gain);
+	rc = mt9e013_i2c_write_w_sensor(REG_COARSE_INTEGRATION_TIME, line);
+	mt9e013_group_hold_off();
+	return rc;
+}
+
+static int32_t mt9e013_set_pict_exp_gain(uint16_t gain, uint32_t line)
+{
+	int32_t rc = 0;
+	rc = mt9e013_write_exp_gain(gain, line);
+	mt9e013_i2c_write_w_sensor(0x301A, 0x065C|0x2);
+	return rc;
+}
+
+#define DIV_CEIL(x, y) (x/y + (x%y) ? 1 : 0)
+
+static int32_t mt9e013_move_focus(int direction,
+	int32_t num_steps)
+{
+	int16_t step_direction, dest_lens_position, dest_step_position;
+	int16_t target_dist, small_step, next_lens_position;
+	if (direction == MOVE_NEAR)
+		step_direction = 1;
+	else
+		step_direction = -1;
+
+	dest_step_position = mt9e013_ctrl->curr_step_pos
+						+ (step_direction * num_steps);
+
+	if (dest_step_position < 0)
+		dest_step_position = 0;
+	else if (dest_step_position > MT9E013_TOTAL_STEPS_NEAR_TO_FAR)
+		dest_step_position = MT9E013_TOTAL_STEPS_NEAR_TO_FAR;
+
+	if (dest_step_position == mt9e013_ctrl->curr_step_pos)
+		return 0;
+
+	dest_lens_position = mt9e013_step_position_table[dest_step_position];
+	target_dist = step_direction *
+		(dest_lens_position - mt9e013_ctrl->curr_lens_pos);
+
+	if (step_direction < 0 && (target_dist >=
+		mt9e013_step_position_table[mt9e013_damping_threshold])) {
+		small_step = DIV_CEIL(target_dist, 10);
+		mt9e013_sw_damping_time_wait = 10;
+	} else {
+		small_step = DIV_CEIL(target_dist, 4);
+		mt9e013_sw_damping_time_wait = 4;
+	}
+
+	for (next_lens_position = mt9e013_ctrl->curr_lens_pos
+		+ (step_direction * small_step);
+		(step_direction * next_lens_position) <=
+		(step_direction * dest_lens_position);
+		next_lens_position += (step_direction * small_step)) {
+		mt9e013_i2c_write_w_sensor(REG_VCM_NEW_CODE,
+		next_lens_position);
+		mt9e013_ctrl->curr_lens_pos = next_lens_position;
+		usleep(mt9e013_sw_damping_time_wait*50);
+	}
+
+	if (mt9e013_ctrl->curr_lens_pos != dest_lens_position) {
+		mt9e013_i2c_write_w_sensor(REG_VCM_NEW_CODE,
+		dest_lens_position);
+		usleep(mt9e013_sw_damping_time_wait*50);
+	}
+	mt9e013_ctrl->curr_lens_pos = dest_lens_position;
+	mt9e013_ctrl->curr_step_pos = dest_step_position;
+	return 0;
+}
+
+static int32_t mt9e013_set_default_focus(uint8_t af_step)
+{
+	int32_t rc = 0;
+	if (mt9e013_ctrl->curr_step_pos != 0) {
+		rc = mt9e013_move_focus(MOVE_FAR,
+		mt9e013_ctrl->curr_step_pos);
+	} else {
+		mt9e013_i2c_write_w_sensor(REG_VCM_NEW_CODE, 0x00);
+	}
+
+	mt9e013_ctrl->curr_lens_pos = 0;
+	mt9e013_ctrl->curr_step_pos = 0;
+
+	return rc;
+}
+
+static void mt9e013_init_focus(void)
+{
+	uint8_t i;
+	mt9e013_step_position_table[0] = 0;
+	for (i = 1; i <= MT9E013_TOTAL_STEPS_NEAR_TO_FAR; i++) {
+		if (i <= mt9e013_nl_region_boundary1) {
+			mt9e013_step_position_table[i] =
+				mt9e013_step_position_table[i-1]
+				+ mt9e013_nl_region_code_per_step1;
+		} else {
+			mt9e013_step_position_table[i] =
+				mt9e013_step_position_table[i-1]
+				+ mt9e013_l_region_code_per_step;
+		}
+
+		if (mt9e013_step_position_table[i] > 255)
+			mt9e013_step_position_table[i] = 255;
+	}
+}
+
+static int32_t mt9e013_test(enum mt9e013_test_mode_t mo)
+{
+	int32_t rc = 0;
+	if (mo == TEST_OFF)
+		return rc;
+	else {
+		/* REG_0x30D8[4] is TESBYPEN: 0: Normal Operation,
+		1: Bypass Signal Processing
+		REG_0x30D8[5] is EBDMASK: 0:
+		Output Embedded data, 1: No output embedded data */
+		if (mt9e013_i2c_write_b_sensor(REG_TEST_PATTERN_MODE,
+			(uint8_t) mo) < 0) {
+			return rc;
+		}
+	}
+	return rc;
+}
+
+static int32_t mt9e013_sensor_setting(int update_type, int rt)
+{
+
+	int32_t rc = 0;
+	struct msm_camera_csi_params mt9e013_csi_params;
+	uint8_t stored_af_step = 0;
+	CDBG("sensor_settings\n");
+	stored_af_step = mt9e013_ctrl->curr_step_pos;
+	mt9e013_set_default_focus(0);
+	mt9e013_stop_stream();
+	msleep(15);
+	if (update_type == REG_INIT) {
+		mt9e013_i2c_write_w_table(mt9e013_regs.reg_mipi,
+			mt9e013_regs.reg_mipi_size);
+		mt9e013_i2c_write_w_table(mt9e013_regs.rec_settings,
+			mt9e013_regs.rec_size);
+		cam_debug_init();
+		CSI_CONFIG = 0;
+	} else if (update_type == UPDATE_PERIODIC) {
+		if (rt == QTR_SIZE) {
+			mt9e013_i2c_write_w_table(mt9e013_regs.reg_pll,
+				mt9e013_regs.reg_pll_size);
+			mt9e013_i2c_write_w_table(mt9e013_regs.reg_prev,
+				mt9e013_regs.reg_prev_size);
+		} else if (rt == FULL_SIZE) {
+			mt9e013_i2c_write_w_table(mt9e013_regs.reg_pll,
+				mt9e013_regs.reg_pll_size);
+			mt9e013_i2c_write_w_table(mt9e013_regs.reg_snap,
+				mt9e013_regs.reg_snap_size);
+		} else if (rt == HFR_60FPS) {
+			mt9e013_i2c_write_w_table(mt9e013_regs.reg_pll_120fps,
+				mt9e013_regs.reg_pll_120fps_size);
+			mt9e013_i2c_write_w_sensor(0x0306, 0x0029);
+			mt9e013_i2c_write_w_table(mt9e013_regs.reg_120fps,
+				mt9e013_regs.reg_120fps_size);
+		} else if (rt == HFR_90FPS) {
+			mt9e013_i2c_write_w_table(mt9e013_regs.reg_pll_120fps,
+				mt9e013_regs.reg_pll_120fps_size);
+			mt9e013_i2c_write_w_sensor(0x0306, 0x003D);
+			mt9e013_i2c_write_w_table(mt9e013_regs.reg_120fps,
+				mt9e013_regs.reg_120fps_size);
+		} else if (rt == HFR_120FPS) {
+			msm_camio_vfe_clk_rate_set(266667000);
+			mt9e013_i2c_write_w_table(mt9e013_regs.reg_pll_120fps,
+				mt9e013_regs.reg_pll_120fps_size);
+			mt9e013_i2c_write_w_table(mt9e013_regs.reg_120fps,
+				mt9e013_regs.reg_120fps_size);
+		}
+		if (!CSI_CONFIG) {
+			msm_camio_vfe_clk_rate_set(192000000);
+			mt9e013_csi_params.data_format = CSI_10BIT;
+			mt9e013_csi_params.lane_cnt = 2;
+			mt9e013_csi_params.lane_assign = 0xe4;
+			mt9e013_csi_params.dpcm_scheme = 0;
+			mt9e013_csi_params.settle_cnt = 0x18;
+			rc = msm_camio_csi_config(&mt9e013_csi_params);
+			msleep(10);
+			CSI_CONFIG = 1;
+		}
+		mt9e013_move_focus(MOVE_NEAR, stored_af_step);
+		mt9e013_start_stream();
+	}
+	return rc;
+}
+
+static int32_t mt9e013_video_config(int mode)
+{
+
+	int32_t rc = 0;
+
+	CDBG("video config\n");
+	/* change sensor resolution if needed */
+	if (mt9e013_sensor_setting(UPDATE_PERIODIC,
+			mt9e013_ctrl->prev_res) < 0)
+		return rc;
+	if (mt9e013_ctrl->set_test) {
+		if (mt9e013_test(mt9e013_ctrl->set_test) < 0)
+			return  rc;
+	}
+
+	mt9e013_ctrl->curr_res = mt9e013_ctrl->prev_res;
+	mt9e013_ctrl->sensormode = mode;
+	return rc;
+}
+
+static int32_t mt9e013_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+	/*change sensor resolution if needed */
+	if (mt9e013_ctrl->curr_res != mt9e013_ctrl->pict_res) {
+		if (mt9e013_sensor_setting(UPDATE_PERIODIC,
+				mt9e013_ctrl->pict_res) < 0)
+			return rc;
+	}
+
+	mt9e013_ctrl->curr_res = mt9e013_ctrl->pict_res;
+	mt9e013_ctrl->sensormode = mode;
+	return rc;
+} /*end of mt9e013_snapshot_config*/
+
+static int32_t mt9e013_raw_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+	/* change sensor resolution if needed */
+	if (mt9e013_ctrl->curr_res != mt9e013_ctrl->pict_res) {
+		if (mt9e013_sensor_setting(UPDATE_PERIODIC,
+				mt9e013_ctrl->pict_res) < 0)
+			return rc;
+	}
+
+	mt9e013_ctrl->curr_res = mt9e013_ctrl->pict_res;
+	mt9e013_ctrl->sensormode = mode;
+	return rc;
+} /*end of mt9e013_raw_snapshot_config*/
+
+static int32_t mt9e013_set_sensor_mode(int mode,
+	int res)
+{
+	int32_t rc = 0;
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+	case SENSOR_HFR_60FPS_MODE:
+	case SENSOR_HFR_90FPS_MODE:
+	case SENSOR_HFR_120FPS_MODE:
+		mt9e013_ctrl->prev_res = res;
+		rc = mt9e013_video_config(mode);
+		break;
+	case SENSOR_SNAPSHOT_MODE:
+		mt9e013_ctrl->pict_res = res;
+		rc = mt9e013_snapshot_config(mode);
+		break;
+	case SENSOR_RAW_SNAPSHOT_MODE:
+		mt9e013_ctrl->pict_res = res;
+		rc = mt9e013_raw_snapshot_config(mode);
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
+static int32_t mt9e013_power_down(void)
+{
+	return 0;
+}
+
+static int mt9e013_probe_init_done(const struct msm_camera_sensor_info *data)
+{
+	CDBG("probe done\n");
+	gpio_free(data->sensor_reset);
+	return 0;
+}
+
+static int mt9e013_probe_init_sensor(const struct msm_camera_sensor_info *data)
+{
+	int32_t rc = 0;
+	uint16_t chipid = 0;
+	CDBG("%s: %d\n", __func__, __LINE__);
+	rc = gpio_request(data->sensor_reset, "mt9e013");
+	CDBG(" mt9e013_probe_init_sensor\n");
+	if (!rc) {
+		CDBG("sensor_reset = %d\n", rc);
+		gpio_direction_output(data->sensor_reset, 0);
+		msleep(10);
+		gpio_set_value_cansleep(data->sensor_reset, 1);
+		msleep(10);
+	} else {
+		goto init_probe_done;
+	}
+
+	CDBG(" mt9e013_probe_init_sensor is called\n");
+	rc = mt9e013_i2c_read(0x0000, &chipid, 2);
+	CDBG("ID: %d\n", chipid);
+	/* 4. Compare sensor ID to MT9E013 ID: */
+	if (chipid != 0x4B00) {
+		rc = -ENODEV;
+		CDBG("mt9e013_probe_init_sensor fail chip id doesnot match\n");
+		goto init_probe_fail;
+	}
+
+	mt9e013_ctrl = kzalloc(sizeof(struct mt9e013_ctrl_t), GFP_KERNEL);
+	if (!mt9e013_ctrl) {
+		CDBG("mt9e013_init failed!\n");
+		rc = -ENOMEM;
+	}
+	mt9e013_ctrl->fps_divider = 1 * 0x00000400;
+	mt9e013_ctrl->pict_fps_divider = 1 * 0x00000400;
+	mt9e013_ctrl->set_test = TEST_OFF;
+	mt9e013_ctrl->prev_res = QTR_SIZE;
+	mt9e013_ctrl->pict_res = FULL_SIZE;
+
+	if (data)
+		mt9e013_ctrl->sensordata = data;
+
+	goto init_probe_done;
+init_probe_fail:
+	CDBG(" mt9e013_probe_init_sensor fails\n");
+	gpio_set_value_cansleep(data->sensor_reset, 0);
+	mt9e013_probe_init_done(data);
+init_probe_done:
+	CDBG(" mt9e013_probe_init_sensor finishes\n");
+	return rc;
+}
+/* camsensor_mt9e013_reset */
+
+int mt9e013_sensor_open_init(const struct msm_camera_sensor_info *data)
+{
+	int32_t rc = 0;
+
+	CDBG("%s: %d\n", __func__, __LINE__);
+	CDBG("Calling mt9e013_sensor_open_init\n");
+
+	mt9e013_ctrl = kzalloc(sizeof(struct mt9e013_ctrl_t), GFP_KERNEL);
+	if (!mt9e013_ctrl) {
+		CDBG("mt9e013_init failed!\n");
+		rc = -ENOMEM;
+		goto init_done;
+	}
+	mt9e013_ctrl->fps_divider = 1 * 0x00000400;
+	mt9e013_ctrl->pict_fps_divider = 1 * 0x00000400;
+	mt9e013_ctrl->set_test = TEST_OFF;
+	mt9e013_ctrl->prev_res = QTR_SIZE;
+	mt9e013_ctrl->pict_res = FULL_SIZE;
+
+	if (data)
+		mt9e013_ctrl->sensordata = data;
+	if (rc < 0) {
+		CDBG("Calling mt9e013_sensor_open_init fail1\n");
+		return rc;
+	}
+	CDBG("%s: %d\n", __func__, __LINE__);
+	/* enable mclk first */
+	msm_camio_clk_rate_set(MT9E013_MASTER_CLK_RATE);
+	rc = mt9e013_probe_init_sensor(data);
+	if (rc < 0)
+		goto init_fail;
+
+	CDBG("init settings\n");
+	rc = mt9e013_sensor_setting(REG_INIT, mt9e013_ctrl->prev_res);
+	mt9e013_ctrl->fps = 30*Q8;
+	mt9e013_init_focus();
+	if (rc < 0) {
+		gpio_set_value_cansleep(data->sensor_reset, 0);
+		goto init_fail;
+	} else
+		goto init_done;
+init_fail:
+	CDBG("init_fail\n");
+	mt9e013_probe_init_done(data);
+init_done:
+	CDBG("init_done\n");
+	return rc;
+} /*endof mt9e013_sensor_open_init*/
+
+static int mt9e013_init_client(struct i2c_client *client)
+{
+	/* Initialize the MSM_CAMI2C Chip */
+	init_waitqueue_head(&mt9e013_wait_queue);
+	return 0;
+}
+
+static const struct i2c_device_id mt9e013_i2c_id[] = {
+	{"mt9e013", 0},
+	{ }
+};
+
+static int mt9e013_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+	CDBG("mt9e013_probe called!\n");
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		CDBG("i2c_check_functionality failed\n");
+		goto probe_failure;
+	}
+
+	mt9e013_sensorw = kzalloc(sizeof(struct mt9e013_work_t), GFP_KERNEL);
+	if (!mt9e013_sensorw) {
+		CDBG("kzalloc failed.\n");
+		rc = -ENOMEM;
+		goto probe_failure;
+	}
+
+	i2c_set_clientdata(client, mt9e013_sensorw);
+	mt9e013_init_client(client);
+	mt9e013_client = client;
+
+
+	CDBG("mt9e013_probe successed! rc = %d\n", rc);
+	return 0;
+
+probe_failure:
+	CDBG("mt9e013_probe failed! rc = %d\n", rc);
+	return rc;
+}
+
+static int mt9e013_send_wb_info(struct wb_info_cfg *wb)
+{
+	return 0;
+
+} /*end of mt9e013_snapshot_config*/
+
+static int __exit mt9e013_remove(struct i2c_client *client)
+{
+	struct mt9e013_work_t_t *sensorw = i2c_get_clientdata(client);
+	free_irq(client->irq, sensorw);
+	mt9e013_client = NULL;
+	kfree(sensorw);
+	return 0;
+}
+
+static struct i2c_driver mt9e013_i2c_driver = {
+	.id_table = mt9e013_i2c_id,
+	.probe  = mt9e013_i2c_probe,
+	.remove = __exit_p(mt9e013_i2c_remove),
+	.driver = {
+		.name = "mt9e013",
+	},
+};
+
+int mt9e013_sensor_config(void __user *argp)
+{
+	struct sensor_cfg_data cdata;
+	long   rc = 0;
+	if (copy_from_user(&cdata,
+		(void *)argp,
+		sizeof(struct sensor_cfg_data)))
+		return -EFAULT;
+	mutex_lock(&mt9e013_mut);
+	CDBG("mt9e013_sensor_config: cfgtype = %d\n",
+	cdata.cfgtype);
+		switch (cdata.cfgtype) {
+		case CFG_GET_PICT_FPS:
+			mt9e013_get_pict_fps(
+				cdata.cfg.gfps.prevfps,
+				&(cdata.cfg.gfps.pictfps));
+
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_GET_PREV_L_PF:
+			cdata.cfg.prevl_pf =
+			mt9e013_get_prev_lines_pf();
+
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_GET_PREV_P_PL:
+			cdata.cfg.prevp_pl =
+				mt9e013_get_prev_pixels_pl();
+
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_GET_PICT_L_PF:
+			cdata.cfg.pictl_pf =
+				mt9e013_get_pict_lines_pf();
+
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_GET_PICT_P_PL:
+			cdata.cfg.pictp_pl =
+				mt9e013_get_pict_pixels_pl();
+
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_GET_PICT_MAX_EXP_LC:
+			cdata.cfg.pict_max_exp_lc =
+				mt9e013_get_pict_max_exp_lc();
+
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_SET_FPS:
+		case CFG_SET_PICT_FPS:
+			rc = mt9e013_set_fps(&(cdata.cfg.fps));
+			break;
+
+		case CFG_SET_EXP_GAIN:
+			rc =
+				mt9e013_write_exp_gain(
+					cdata.cfg.exp_gain.gain,
+					cdata.cfg.exp_gain.line);
+			break;
+
+		case CFG_SET_PICT_EXP_GAIN:
+			rc =
+				mt9e013_set_pict_exp_gain(
+				cdata.cfg.exp_gain.gain,
+				cdata.cfg.exp_gain.line);
+			break;
+
+		case CFG_SET_MODE:
+			rc = mt9e013_set_sensor_mode(cdata.mode,
+					cdata.rs);
+			break;
+
+		case CFG_PWR_DOWN:
+			rc = mt9e013_power_down();
+			break;
+
+		case CFG_MOVE_FOCUS:
+			rc =
+				mt9e013_move_focus(
+				cdata.cfg.focus.dir,
+				cdata.cfg.focus.steps);
+			break;
+
+		case CFG_SET_DEFAULT_FOCUS:
+			rc =
+				mt9e013_set_default_focus(
+				cdata.cfg.focus.steps);
+			break;
+
+		case CFG_GET_AF_MAX_STEPS:
+			cdata.max_steps = MT9E013_TOTAL_STEPS_NEAR_TO_FAR;
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_SET_EFFECT:
+			rc = mt9e013_set_default_focus(
+				cdata.cfg.effect);
+			break;
+
+
+		case CFG_SEND_WB_INFO:
+			rc = mt9e013_send_wb_info(
+				&(cdata.cfg.wb_info));
+			break;
+
+		default:
+			rc = -EFAULT;
+			break;
+		}
+
+	mutex_unlock(&mt9e013_mut);
+
+	return rc;
+}
+
+static int mt9e013_sensor_release(void)
+{
+	int rc = -EBADF;
+	mutex_lock(&mt9e013_mut);
+	mt9e013_power_down();
+	gpio_set_value_cansleep(mt9e013_ctrl->sensordata->sensor_reset, 0);
+	msleep(5);
+	gpio_free(mt9e013_ctrl->sensordata->sensor_reset);
+	kfree(mt9e013_ctrl);
+	mt9e013_ctrl = NULL;
+	CDBG("mt9e013_release completed\n");
+	mutex_unlock(&mt9e013_mut);
+
+	return rc;
+}
+
+static int mt9e013_sensor_probe(const struct msm_camera_sensor_info *info,
+		struct msm_sensor_ctrl *s)
+{
+	int rc = 0;
+	rc = i2c_add_driver(&mt9e013_i2c_driver);
+	if (rc < 0 || mt9e013_client == NULL) {
+		rc = -ENOTSUPP;
+		CDBG("I2C add driver failed");
+		goto probe_fail;
+	}
+	msm_camio_clk_rate_set(MT9E013_MASTER_CLK_RATE);
+	rc = mt9e013_probe_init_sensor(info);
+	if (rc < 0)
+		goto probe_fail;
+	s->s_init = mt9e013_sensor_open_init;
+	s->s_release = mt9e013_sensor_release;
+	s->s_config  = mt9e013_sensor_config;
+	s->s_mount_angle = info->sensor_platform_info->mount_angle;
+	gpio_set_value_cansleep(info->sensor_reset, 0);
+	mt9e013_probe_init_done(info);
+	return rc;
+
+probe_fail:
+	CDBG("mt9e013_sensor_probe: SENSOR PROBE FAILS!\n");
+	return rc;
+}
+
+static int __mt9e013_probe(struct platform_device *pdev)
+{
+	return msm_camera_drv_start(pdev, mt9e013_sensor_probe);
+}
+
+static struct platform_driver msm_camera_driver = {
+	.probe = __mt9e013_probe,
+	.driver = {
+		.name = "msm_camera_mt9e013",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init mt9e013_init(void)
+{
+	return platform_driver_register(&msm_camera_driver);
+}
+
+module_init(mt9e013_init);
+void mt9e013_exit(void)
+{
+	i2c_del_driver(&mt9e013_i2c_driver);
+}
+MODULE_DESCRIPTION("Aptina 8 MP Bayer sensor driver");
+MODULE_LICENSE("GPL v2");
+
+static bool streaming = 1;
+
+static int mt9e013_focus_test(void *data, u64 *val)
+{
+	int i = 0;
+	mt9e013_set_default_focus(0);
+
+	for (i = 90; i < 256; i++) {
+		mt9e013_i2c_write_w_sensor(REG_VCM_NEW_CODE, i);
+		msleep(5000);
+	}
+	msleep(5000);
+	for (i = 255; i > 90; i--) {
+		mt9e013_i2c_write_w_sensor(REG_VCM_NEW_CODE, i);
+		msleep(5000);
+	}
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(cam_focus, mt9e013_focus_test,
+			NULL, "%lld\n");
+
+static int mt9e013_step_test(void *data, u64 *val)
+{
+	int i = 0;
+	mt9e013_set_default_focus(0);
+
+	for (i = 0; i < MT9E013_TOTAL_STEPS_NEAR_TO_FAR; i++) {
+		mt9e013_move_focus(MOVE_NEAR, 1);
+		msleep(5000);
+	}
+
+	mt9e013_move_focus(MOVE_FAR, MT9E013_TOTAL_STEPS_NEAR_TO_FAR);
+	msleep(5000);
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(cam_step, mt9e013_step_test,
+			NULL, "%lld\n");
+
+static int cam_debug_stream_set(void *data, u64 val)
+{
+	int rc = 0;
+
+	if (val) {
+		mt9e013_start_stream();
+		streaming = 1;
+	} else {
+		mt9e013_stop_stream();
+		streaming = 0;
+	}
+
+	return rc;
+}
+
+static int cam_debug_stream_get(void *data, u64 *val)
+{
+	*val = streaming;
+	return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(cam_stream, cam_debug_stream_get,
+			cam_debug_stream_set, "%llu\n");
+
+
+static int cam_debug_init(void)
+{
+	struct dentry *cam_dir;
+	debugfs_base = debugfs_create_dir("sensor", NULL);
+	if (!debugfs_base)
+		return -ENOMEM;
+
+	cam_dir = debugfs_create_dir("mt9e013", debugfs_base);
+	if (!cam_dir)
+		return -ENOMEM;
+
+	if (!debugfs_create_file("focus", S_IRUGO | S_IWUSR, cam_dir,
+							 NULL, &cam_focus))
+		return -ENOMEM;
+	if (!debugfs_create_file("step", S_IRUGO | S_IWUSR, cam_dir,
+							 NULL, &cam_step))
+		return -ENOMEM;
+	if (!debugfs_create_file("stream", S_IRUGO | S_IWUSR, cam_dir,
+							 NULL, &cam_stream))
+		return -ENOMEM;
+
+	return 0;
+}
+
+
+
diff --git a/drivers/media/platform/msm/camera_v1/mt9e013.h b/drivers/media/platform/msm/camera_v1/mt9e013.h
new file mode 100644
index 0000000..6f43ec4
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mt9e013.h
@@ -0,0 +1,174 @@
+/* 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.
+ *
+ */
+
+#ifndef MT9E013_H
+#define MT9E013_H
+#include <linux/types.h>
+#include <mach/board.h>
+extern struct mt9e013_reg mt9e013_regs;
+struct reg_struct_init {
+	uint8_t reg_0x0112;      /* 0x0112*/
+	uint8_t reg_0x0113;      /* 0x0113*/
+	uint8_t vt_pix_clk_div;  /* 0x0301*/
+	uint8_t pre_pll_clk_div; /* 0x0305*/
+	uint8_t pll_multiplier;  /* 0x0307*/
+	uint8_t op_pix_clk_div;  /* 0x0309*/
+	uint8_t reg_0x3030;      /*0x3030*/
+	uint8_t reg_0x0111;      /*0x0111*/
+	uint8_t reg_0x0b00;      /*0x0b00*/
+	uint8_t reg_0x3001;      /*0x3001*/
+	uint8_t reg_0x3004;      /*0x3004*/
+	uint8_t reg_0x3007;      /*0x3007*/
+	uint8_t reg_0x3016;      /*0x3016*/
+	uint8_t reg_0x301d;      /*0x301d*/
+	uint8_t reg_0x317e;      /*0x317E*/
+	uint8_t reg_0x317f;      /*0x317F*/
+	uint8_t reg_0x3400;      /*0x3400*/
+	uint8_t reg_0x0b06;      /*0x0b06*/
+	uint8_t reg_0x0b07;      /*0x0b07*/
+	uint8_t reg_0x0b08;      /*0x0b08*/
+	uint8_t reg_0x0b09;      /*0x0b09*/
+	uint8_t reg_0x0136;
+	uint8_t reg_0x0137;
+	/* Edof */
+	uint8_t reg_0x0b83;      /*0x0b83*/
+	uint8_t reg_0x0b84;      /*0x0b84*/
+	uint8_t reg_0x0b85;      /*0x0b85*/
+	uint8_t reg_0x0b88;      /*0x0b88*/
+	uint8_t reg_0x0b89;      /*0x0b89*/
+	uint8_t reg_0x0b8a;      /*0x0b8a*/
+	};
+struct reg_struct {
+	uint8_t coarse_integration_time_hi; /*REG_COARSE_INTEGRATION_TIME_HI*/
+	uint8_t coarse_integration_time_lo; /*REG_COARSE_INTEGRATION_TIME_LO*/
+	uint8_t analogue_gain_code_global;
+	uint8_t frame_length_lines_hi; /* 0x0340*/
+	uint8_t frame_length_lines_lo; /* 0x0341*/
+	uint8_t line_length_pck_hi;    /* 0x0342*/
+	uint8_t line_length_pck_lo;    /* 0x0343*/
+	uint8_t reg_0x3005;   /* 0x3005*/
+	uint8_t reg_0x3010;  /* 0x3010*/
+	uint8_t reg_0x3011;  /* 0x3011*/
+	uint8_t reg_0x301a;  /* 0x301a*/
+	uint8_t reg_0x3035;  /* 0x3035*/
+	uint8_t reg_0x3036;   /* 0x3036*/
+	uint8_t reg_0x3041;  /*0x3041*/
+	uint8_t reg_0x3042;  /*0x3042*/
+	uint8_t reg_0x3045;  /*0x3045*/
+	uint8_t reg_0x0b80;   /* 0x0b80*/
+	uint8_t reg_0x0900;   /*0x0900*/
+	uint8_t reg_0x0901;   /* 0x0901*/
+	uint8_t reg_0x0902;   /*0x0902*/
+	uint8_t reg_0x0383;   /*0x0383*/
+	uint8_t reg_0x0387;   /* 0x0387*/
+	uint8_t reg_0x034c;   /* 0x034c*/
+	uint8_t reg_0x034d;   /*0x034d*/
+	uint8_t reg_0x034e;   /* 0x034e*/
+	uint8_t reg_0x034f;   /* 0x034f*/
+	uint8_t reg_0x1716; /*0x1716*/
+	uint8_t reg_0x1717; /*0x1717*/
+	uint8_t reg_0x1718; /*0x1718*/
+	uint8_t reg_0x1719; /*0x1719*/
+	uint8_t reg_0x3210;/*0x3210*/
+	uint8_t reg_0x111; /*0x111*/
+	uint8_t reg_0x3410;  /*0x3410*/
+	uint8_t reg_0x3098;
+	uint8_t reg_0x309D;
+	uint8_t reg_0x0200;
+	uint8_t reg_0x0201;
+	};
+struct mt9e013_i2c_reg_conf {
+	unsigned short waddr;
+	unsigned short wdata;
+};
+
+enum mt9e013_test_mode_t {
+	TEST_OFF,
+	TEST_1,
+	TEST_2,
+	TEST_3
+};
+
+enum mt9e013_resolution_t {
+	QTR_SIZE,
+	FULL_SIZE,
+	HFR_60FPS,
+	HFR_90FPS,
+	HFR_120FPS,
+	INVALID_SIZE
+};
+enum mt9e013_setting {
+	RES_PREVIEW,
+	RES_CAPTURE
+};
+enum mt9e013_reg_update {
+	/* Sensor egisters that need to be updated during initialization */
+	REG_INIT,
+	/* Sensor egisters that needs periodic I2C writes */
+	UPDATE_PERIODIC,
+	/* All the sensor Registers will be updated */
+	UPDATE_ALL,
+	/* Not valid update */
+	UPDATE_INVALID
+};
+
+enum mt9e013_reg_pll {
+	E013_VT_PIX_CLK_DIV,
+	E013_VT_SYS_CLK_DIV,
+	E013_PRE_PLL_CLK_DIV,
+	E013_PLL_MULTIPLIER,
+	E013_OP_PIX_CLK_DIV,
+	E013_OP_SYS_CLK_DIV
+};
+
+enum mt9e013_reg_mode {
+	E013_X_ADDR_START,
+	E013_X_ADDR_END,
+	E013_Y_ADDR_START,
+	E013_Y_ADDR_END,
+	E013_X_OUTPUT_SIZE,
+	E013_Y_OUTPUT_SIZE,
+	E013_DATAPATH_SELECT,
+	E013_READ_MODE,
+	E013_ANALOG_CONTROL5,
+	E013_DAC_LD_4_5,
+	E013_SCALING_MODE,
+	E013_SCALE_M,
+	E013_LINE_LENGTH_PCK,
+	E013_FRAME_LENGTH_LINES,
+	E013_COARSE_INTEGRATION_TIME,
+	E013_FINE_INTEGRATION_TIME,
+	E013_FINE_CORRECTION
+};
+
+struct mt9e013_reg {
+	const struct mt9e013_i2c_reg_conf *reg_mipi;
+	const unsigned short reg_mipi_size;
+	const struct mt9e013_i2c_reg_conf *rec_settings;
+	const unsigned short rec_size;
+	const struct mt9e013_i2c_reg_conf *reg_pll;
+	const unsigned short reg_pll_size;
+	const struct mt9e013_i2c_reg_conf *reg_pll_60fps;
+	const unsigned short reg_pll_60fps_size;
+	const struct mt9e013_i2c_reg_conf *reg_pll_120fps;
+	const unsigned short reg_pll_120fps_size;
+	const struct mt9e013_i2c_reg_conf *reg_prev;
+	const unsigned short reg_prev_size;
+	const struct mt9e013_i2c_reg_conf *reg_snap;
+	const unsigned short reg_snap_size;
+	const struct mt9e013_i2c_reg_conf *reg_60fps;
+	const unsigned short reg_60fps_size;
+	const struct mt9e013_i2c_reg_conf *reg_120fps;
+	const unsigned short reg_120fps_size;
+};
+#endif /* MT9E013_H */
diff --git a/drivers/media/platform/msm/camera_v1/mt9e013_reg.c b/drivers/media/platform/msm/camera_v1/mt9e013_reg.c
new file mode 100644
index 0000000..bdcf3f8
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mt9e013_reg.c
@@ -0,0 +1,234 @@
+/* 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 "mt9e013.h"
+
+static struct mt9e013_i2c_reg_conf mipi_settings[] = {
+	/*Disable embedded data*/
+	{0x3064, 0x7800},/*SMIA_TEST*/
+	/*configure 2-lane MIPI*/
+	{0x31AE, 0x0202},/*SERIAL_FORMAT*/
+	{0x31B8, 0x0E3F},/*MIPI_TIMING_2*/
+	/*set data to RAW10 format*/
+	{0x0112, 0x0A0A},/*CCP_DATA_FORMAT*/
+	{0x30F0, 0x8000},/*VCM CONTROL*/
+};
+
+/*PLL Configuration
+(Ext=24MHz, vt_pix_clk=174MHz, op_pix_clk=69.6MHz)*/
+static struct mt9e013_i2c_reg_conf pll_settings[] = {
+	{0x0300, 0x0004},/*VT_PIX_CLK_DIV*/
+	{0x0302, 0x0001},/*VT_SYS_CLK_DIV*/
+	{0x0304, 0x0002},/*PRE_PLL_CLK_DIV*/
+	{0x0306, 0x003A},/*PLL_MULTIPLIER*/
+	{0x0308, 0x000A},/*OP_PIX_CLK_DIV*/
+	{0x030A, 0x0001},/*OP_SYS_CLK_DIV*/
+};
+
+static struct mt9e013_i2c_reg_conf prev_settings[] = {
+	/*Output Size (1632x1224)*/
+	{0x0344, 0x0008},/*X_ADDR_START*/
+	{0x0348, 0x0CC9},/*X_ADDR_END*/
+	{0x0346, 0x0008},/*Y_ADDR_START*/
+	{0x034A, 0x0999},/*Y_ADDR_END*/
+	{0x034C, 0x0660},/*X_OUTPUT_SIZE*/
+	{0x034E, 0x04C8},/*Y_OUTPUT_SIZE*/
+	{0x306E, 0xFCB0},/*DATAPATH_SELECT*/
+	{0x3040, 0x04C3},/*READ_MODE*/
+	{0x3178, 0x0000},/*ANALOG_CONTROL5*/
+	{0x3ED0, 0x1E24},/*DAC_LD_4_5*/
+	{0x0400, 0x0002},/*SCALING_MODE*/
+	{0x0404, 0x0010},/*SCALE_M*/
+	/*Timing configuration*/
+	{0x0342, 0x1018},/*LINE_LENGTH_PCK*/
+	{0x0340, 0x055B},/*FRAME_LENGTH_LINES*/
+	{0x0202, 0x0557},/*COARSE_INTEGRATION_TIME*/
+	{0x3014, 0x0846},/*FINE_INTEGRATION_TIME_*/
+	{0x3010, 0x0130},/*FINE_CORRECTION*/
+};
+
+static struct mt9e013_i2c_reg_conf snap_settings[] = {
+	/*Output Size (3264x2448)*/
+	{0x0344, 0x0008},/*X_ADDR_START */
+	{0x0348, 0x0CD7},/*X_ADDR_END*/
+	{0x0346, 0x0008},/*Y_ADDR_START */
+	{0x034A, 0x09A7},/*Y_ADDR_END*/
+	{0x034C, 0x0CD0},/*X_OUTPUT_SIZE*/
+	{0x034E, 0x09A0},/*Y_OUTPUT_SIZE*/
+	{0x306E, 0xFC80},/*DATAPATH_SELECT*/
+	{0x3040, 0x0041},/*READ_MODE*/
+	{0x3178, 0x0000},/*ANALOG_CONTROL5*/
+	{0x3ED0, 0x1E24},/*DAC_LD_4_5*/
+	{0x0400, 0x0000},/*SCALING_MODE*/
+	{0x0404, 0x0010},/*SCALE_M*/
+	/*Timing configuration*/
+	{0x0342, 0x13F8},/*LINE_LENGTH_PCK*/
+	{0x0340, 0x0A2F},/*FRAME_LENGTH_LINES*/
+	{0x0202, 0x0A1F},/*COARSE_INTEGRATION_TIME*/
+	{0x3014, 0x03F6},/*FINE_INTEGRATION_TIME_ */
+	{0x3010, 0x0078},/*FINE_CORRECTION*/
+};
+
+static struct mt9e013_i2c_reg_conf pll_settings_60fps[] = {
+	{0x0300, 0x0004},/*VT_PIX_CLK_DIV*/
+	{0x0302, 0x0001},/*VT_SYS_CLK_DIV*/
+	{0x0304, 0x0002},/*PRE_PLL_CLK_DIV*/
+	{0x0306, 0x0042},/*PLL_MULTIPLIER*/
+	{0x0308, 0x000A},/*OP_PIX_CLK_DIV*/
+	{0x030A, 0x0001},/*OP_SYS_CLK_DIV*/
+};
+
+static struct mt9e013_i2c_reg_conf prev_settings_60fps[] = {
+	/*Output Size (1632x1224)*/
+	{0x0344, 0x0008},/*X_ADDR_START*/
+	{0x0348, 0x0CC5},/*X_ADDR_END*/
+	{0x0346, 0x013a},/*Y_ADDR_START*/
+	{0x034A, 0x0863},/*Y_ADDR_END*/
+	{0x034C, 0x0660},/*X_OUTPUT_SIZE*/
+	{0x034E, 0x0396},/*Y_OUTPUT_SIZE*/
+	{0x306E, 0xFC80},/*DATAPATH_SELECT*/
+	{0x3040, 0x00C3},/*READ_MODE*/
+	{0x3178, 0x0000},/*ANALOG_CONTROL5*/
+	{0x3ED0, 0x1E24},/*DAC_LD_4_5*/
+	{0x0400, 0x0000},/*SCALING_MODE*/
+	{0x0404, 0x0010},/*SCALE_M*/
+	/*Timing configuration*/
+	{0x0342, 0x0BE8},/*LINE_LENGTH_PCK*/
+	{0x0340, 0x0425},/*FRAME_LENGTH_LINES*/
+	{0x0202, 0x0425},/*COARSE_INTEGRATION_TIME*/
+	{0x3014, 0x03F6},/*FINE_INTEGRATION_TIME_*/
+	{0x3010, 0x0078},/*FINE_CORRECTION*/
+};
+
+static struct mt9e013_i2c_reg_conf pll_settings_120fps[] = {
+	{0x0300, 0x0005},/*VT_PIX_CLK_DIV*/
+	{0x0302, 0x0001},/*VT_SYS_CLK_DIV*/
+	{0x0304, 0x0002},/*PRE_PLL_CLK_DIV*/
+	{0x0306, 0x0052},/*PLL_MULTIPLIER*/
+	{0x0308, 0x000A},/*OP_PIX_CLK_DIV*/
+	{0x030A, 0x0001},/*OP_SYS_CLK_DIV*/
+};
+
+static struct mt9e013_i2c_reg_conf prev_settings_120fps[] = {
+	{0x0344, 0x0008},/*X_ADDR_START*/
+	{0x0348, 0x0685},/*X_ADDR_END*/
+	{0x0346, 0x013a},/*Y_ADDR_START*/
+	{0x034A, 0x055B},/*Y_ADDR_END*/
+	{0x034C, 0x0340},/*X_OUTPUT_SIZE*/
+	{0x034E, 0x0212},/*Y_OUTPUT_SIZE*/
+	{0x306E, 0xFC80},/*DATAPATH_SELECT*/
+	{0x3040, 0x00C3},/*READ_MODE*/
+	{0x3178, 0x0000},/*ANALOG_CONTROL5*/
+	{0x3ED0, 0x1E24},/*DAC_LD_4_5*/
+	{0x0400, 0x0000},/*SCALING_MODE*/
+	{0x0404, 0x0010},/*SCALE_M*/
+	/*Timing configuration*/
+	{0x0342, 0x0970},/*LINE_LENGTH_PCK*/
+	{0x0340, 0x02A1},/*FRAME_LENGTH_LINES*/
+	{0x0202, 0x02A1},/*COARSE_INTEGRATION_TIME*/
+	{0x3014, 0x03F6},/*FINE_INTEGRATION_TIME_*/
+	{0x3010, 0x0078},/*FINE_CORRECTION*/
+};
+
+static struct mt9e013_i2c_reg_conf recommend_settings[] = {
+	{0x3044, 0x0590},
+	{0x306E, 0xFC80},
+	{0x30B2, 0xC000},
+	{0x30D6, 0x0800},
+	{0x316C, 0xB42F},
+	{0x316E, 0x869C},
+	{0x3170, 0x210E},
+	{0x317A, 0x010E},
+	{0x31E0, 0x1FB9},
+	{0x31E6, 0x07FC},
+	{0x37C0, 0x0000},
+	{0x37C2, 0x0000},
+	{0x37C4, 0x0000},
+	{0x37C6, 0x0000},
+	{0x3E02, 0x8801},
+	{0x3E04, 0x2301},
+	{0x3E06, 0x8449},
+	{0x3E08, 0x6841},
+	{0x3E0A, 0x400C},
+	{0x3E0C, 0x1001},
+	{0x3E0E, 0x2103},
+	{0x3E10, 0x4B41},
+	{0x3E12, 0x4B26},
+	{0x3E16, 0x8802},
+	{0x3E18, 0x84FF},
+	{0x3E1A, 0x8601},
+	{0x3E1C, 0x8401},
+	{0x3E1E, 0x840A},
+	{0x3E20, 0xFF00},
+	{0x3E22, 0x8401},
+	{0x3E24, 0x00FF},
+	{0x3E26, 0x0088},
+	{0x3E28, 0x2E8A},
+	{0x3E32, 0x8801},
+	{0x3E34, 0x4024},
+	{0x3E38, 0x8469},
+	{0x3E3C, 0x2301},
+	{0x3E3E, 0x3E25},
+	{0x3E40, 0x1C01},
+	{0x3E42, 0x8486},
+	{0x3E44, 0x8401},
+	{0x3E46, 0x00FF},
+	{0x3E48, 0x8401},
+	{0x3E4A, 0x8601},
+	{0x3E4C, 0x8402},
+	{0x3E4E, 0x00FF},
+	{0x3E50, 0x6623},
+	{0x3E52, 0x8340},
+	{0x3E54, 0x00FF},
+	{0x3E56, 0x4A42},
+	{0x3E58, 0x2203},
+	{0x3E5A, 0x674D},
+	{0x3E5C, 0x3F25},
+	{0x3E5E, 0x846A},
+	{0x3E60, 0x4C01},
+	{0x3E62, 0x8401},
+	{0x3E66, 0x3901},
+	{0x3ECC, 0x00EB},
+	{0x3ED0, 0x1E24},
+	{0x3ED4, 0xAFC4},
+	{0x3ED6, 0x909B},
+	{0x3ED8, 0x0006},
+	{0x3EDA, 0xCFC6},
+	{0x3EDC, 0x4FE4},
+	{0x3EE0, 0x2424},
+	{0x3EE2, 0x9797},
+	{0x3EE4, 0xC100},
+	{0x3EE6, 0x0540}
+};
+
+struct mt9e013_reg mt9e013_regs = {
+	.reg_mipi = &mipi_settings[0],
+	.reg_mipi_size = ARRAY_SIZE(mipi_settings),
+	.rec_settings = &recommend_settings[0],
+	.rec_size = ARRAY_SIZE(recommend_settings),
+	.reg_pll = &pll_settings[0],
+	.reg_pll_size = ARRAY_SIZE(pll_settings),
+	.reg_prev = &prev_settings[0],
+	.reg_pll_60fps = &pll_settings_60fps[0],
+	.reg_pll_60fps_size = ARRAY_SIZE(pll_settings_60fps),
+	.reg_pll_120fps = &pll_settings_120fps[0],
+	.reg_pll_120fps_size = ARRAY_SIZE(pll_settings_120fps),
+	.reg_prev_size = ARRAY_SIZE(prev_settings),
+	.reg_snap = &snap_settings[0],
+	.reg_snap_size = ARRAY_SIZE(snap_settings),
+	.reg_60fps = &prev_settings_60fps[0],
+	.reg_60fps_size = ARRAY_SIZE(prev_settings_60fps),
+	.reg_120fps = &prev_settings_120fps[0],
+	.reg_120fps_size = ARRAY_SIZE(prev_settings_120fps),
+};
diff --git a/drivers/media/platform/msm/camera_v1/mt9p012.h b/drivers/media/platform/msm/camera_v1/mt9p012.h
new file mode 100644
index 0000000..a30b2f1
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mt9p012.h
@@ -0,0 +1,60 @@
+/* Copyright (c) 2009-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.
+ *
+ */
+
+#ifndef MT9T012_H
+#define MT9T012_H
+
+#include <linux/types.h>
+#include <mach/board.h>
+
+extern struct mt9p012_reg mt9p012_regs;	/* from mt9p012_reg.c */
+
+struct reg_struct {
+	uint16_t vt_pix_clk_div;     /* 0x0300 */
+	uint16_t vt_sys_clk_div;     /* 0x0302 */
+	uint16_t pre_pll_clk_div;    /* 0x0304 */
+	uint16_t pll_multiplier;     /* 0x0306 */
+	uint16_t op_pix_clk_div;     /* 0x0308 */
+	uint16_t op_sys_clk_div;     /* 0x030A */
+	uint16_t scale_m;            /* 0x0404 */
+	uint16_t row_speed;          /* 0x3016 */
+	uint16_t x_addr_start;       /* 0x3004 */
+	uint16_t x_addr_end;         /* 0x3008 */
+	uint16_t y_addr_start;       /* 0x3002 */
+	uint16_t y_addr_end;         /* 0x3006 */
+	uint16_t read_mode;          /* 0x3040 */
+	uint16_t x_output_size ;     /* 0x034C */
+	uint16_t y_output_size;      /* 0x034E */
+	uint16_t line_length_pck;    /* 0x300C */
+	uint16_t frame_length_lines; /* 0x300A */
+	uint16_t coarse_int_time;    /* 0x3012 */
+	uint16_t fine_int_time;      /* 0x3014 */
+};
+
+
+struct mt9p012_i2c_reg_conf {
+	unsigned short waddr;
+	unsigned short wdata;
+};
+
+
+struct mt9p012_reg {
+	struct reg_struct const *reg_pat;
+	uint16_t reg_pat_size;
+	struct mt9p012_i2c_reg_conf const *ttbl;
+	uint16_t ttbl_size;
+	struct mt9p012_i2c_reg_conf const *rftbl;
+	uint16_t rftbl_size;
+};
+
+#endif /* MT9T012_H */
diff --git a/drivers/media/platform/msm/camera_v1/mt9p012_bam.c b/drivers/media/platform/msm/camera_v1/mt9p012_bam.c
new file mode 100644
index 0000000..9363893
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mt9p012_bam.c
@@ -0,0 +1,1426 @@
+/* Copyright (c) 2008-2009, 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/delay.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/kernel.h>
+#include <media/msm_camera.h>
+#include <mach/gpio.h>
+#include <mach/camera.h>
+#include "mt9p012.h"
+
+/*=============================================================
+    SENSOR REGISTER DEFINES
+==============================================================*/
+#define MT9P012_REG_MODEL_ID         0x0000
+#define MT9P012_MODEL_ID             0x2801
+#define REG_GROUPED_PARAMETER_HOLD   0x0104
+#define GROUPED_PARAMETER_HOLD       0x0100
+#define GROUPED_PARAMETER_UPDATE     0x0000
+#define REG_COARSE_INT_TIME          0x3012
+#define REG_VT_PIX_CLK_DIV           0x0300
+#define REG_VT_SYS_CLK_DIV           0x0302
+#define REG_PRE_PLL_CLK_DIV          0x0304
+#define REG_PLL_MULTIPLIER           0x0306
+#define REG_OP_PIX_CLK_DIV           0x0308
+#define REG_OP_SYS_CLK_DIV           0x030A
+#define REG_SCALE_M                  0x0404
+#define REG_FRAME_LENGTH_LINES       0x300A
+#define REG_LINE_LENGTH_PCK          0x300C
+#define REG_X_ADDR_START             0x3004
+#define REG_Y_ADDR_START             0x3002
+#define REG_X_ADDR_END               0x3008
+#define REG_Y_ADDR_END               0x3006
+#define REG_X_OUTPUT_SIZE            0x034C
+#define REG_Y_OUTPUT_SIZE            0x034E
+#define REG_FINE_INTEGRATION_TIME    0x3014
+#define REG_ROW_SPEED                0x3016
+#define MT9P012_REG_RESET_REGISTER   0x301A
+#define MT9P012_RESET_REGISTER_PWON  0x10CC
+#define MT9P012_RESET_REGISTER_PWOFF 0x10C8
+#define REG_READ_MODE                0x3040
+#define REG_GLOBAL_GAIN              0x305E
+#define REG_TEST_PATTERN_MODE        0x3070
+
+#define MT9P012_REV_7
+
+enum mt9p012_test_mode {
+	TEST_OFF,
+	TEST_1,
+	TEST_2,
+	TEST_3
+};
+
+enum mt9p012_resolution {
+	QTR_SIZE,
+	FULL_SIZE,
+	INVALID_SIZE
+};
+
+enum mt9p012_reg_update {
+	/* Sensor egisters that need to be updated during initialization */
+	REG_INIT,
+	/* Sensor egisters that needs periodic I2C writes */
+	UPDATE_PERIODIC,
+	/* All the sensor Registers will be updated */
+	UPDATE_ALL,
+	/* Not valid update */
+	UPDATE_INVALID
+};
+
+enum mt9p012_setting {
+	RES_PREVIEW,
+	RES_CAPTURE
+};
+
+/* actuator's Slave Address */
+#define MT9P012_AF_I2C_ADDR   0x0A
+
+/* AF Total steps parameters */
+#define MT9P012_STEPS_NEAR_TO_CLOSEST_INF  20
+#define MT9P012_TOTAL_STEPS_NEAR_TO_FAR    20
+
+#define MT9P012_MU5M0_PREVIEW_DUMMY_PIXELS 0
+#define MT9P012_MU5M0_PREVIEW_DUMMY_LINES  0
+
+/* Time in milisecs for waiting for the sensor to reset.*/
+#define MT9P012_RESET_DELAY_MSECS   66
+
+/* for 20 fps preview */
+#define MT9P012_DEFAULT_CLOCK_RATE  24000000
+#define MT9P012_DEFAULT_MAX_FPS     26	/* ???? */
+
+struct mt9p012_work {
+	struct work_struct work;
+};
+static struct mt9p012_work *mt9p012_sensorw;
+static struct i2c_client *mt9p012_client;
+
+struct mt9p012_ctrl {
+	const struct msm_camera_sensor_info *sensordata;
+
+	int sensormode;
+	uint32_t fps_divider;	/* init to 1 * 0x00000400 */
+	uint32_t pict_fps_divider;	/* init to 1 * 0x00000400 */
+
+	uint16_t curr_lens_pos;
+	uint16_t init_curr_lens_pos;
+	uint16_t my_reg_gain;
+	uint32_t my_reg_line_count;
+
+	enum mt9p012_resolution prev_res;
+	enum mt9p012_resolution pict_res;
+	enum mt9p012_resolution curr_res;
+	enum mt9p012_test_mode set_test;
+};
+
+static uint16_t bam_macro, bam_infinite;
+static uint16_t bam_step_lookup_table[MT9P012_TOTAL_STEPS_NEAR_TO_FAR + 1];
+static uint16_t update_type = UPDATE_PERIODIC;
+static struct mt9p012_ctrl *mt9p012_ctrl;
+static DECLARE_WAIT_QUEUE_HEAD(mt9p012_wait_queue);
+DEFINE_MUTEX(mt9p012_mut);
+
+/*=============================================================*/
+
+static int mt9p012_i2c_rxdata(unsigned short saddr, int slength,
+			      unsigned char *rxdata, int rxlength)
+{
+	struct i2c_msg msgs[] = {
+		{
+			.addr = saddr,
+			.flags = 0,
+			.len = slength,
+			.buf = rxdata,
+		},
+		{
+			.addr = saddr,
+			.flags = I2C_M_RD,
+			.len = rxlength,
+			.buf = rxdata,
+		},
+	};
+
+	if (i2c_transfer(mt9p012_client->adapter, msgs, 2) < 0) {
+		CDBG("mt9p012_i2c_rxdata failed!\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+static int32_t mt9p012_i2c_read_b(unsigned short saddr, unsigned char raddr,
+				  unsigned short *rdata)
+{
+	int32_t rc = 0;
+	if (!rdata)
+		return -EIO;
+	rc = mt9p012_i2c_rxdata(saddr, 1, &raddr, 1);
+	if (rc < 0)
+		return rc;
+	*rdata = raddr;
+	if (rc < 0)
+		CDBG("mt9p012_i2c_read_b failed!\n");
+	return rc;
+}
+
+static int32_t mt9p012_i2c_read_w(unsigned short saddr, unsigned short raddr,
+				  unsigned short *rdata)
+{
+	int32_t rc = 0;
+	unsigned char buf[4];
+
+	if (!rdata)
+		return -EIO;
+
+	memset(buf, 0, sizeof(buf));
+
+	buf[0] = (raddr & 0xFF00) >> 8;
+	buf[1] = (raddr & 0x00FF);
+
+	rc = mt9p012_i2c_rxdata(saddr, 2, buf, 2);
+	if (rc < 0)
+		return rc;
+
+	*rdata = buf[0] << 8 | buf[1];
+
+	if (rc < 0)
+		CDBG("mt9p012_i2c_read failed!\n");
+
+	return rc;
+}
+
+static int32_t mt9p012_i2c_txdata(unsigned short saddr, unsigned char *txdata,
+				  int length)
+{
+	struct i2c_msg msg[] = {
+		{
+		 .addr = saddr,
+		 .flags = 0,
+		 .len = length,
+		 .buf = txdata,
+		 },
+	};
+
+	if (i2c_transfer(mt9p012_client->adapter, msg, 1) < 0) {
+		CDBG("mt9p012_i2c_txdata failed\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t mt9p012_i2c_write_b(unsigned short saddr, unsigned short baddr,
+				   unsigned short bdata)
+{
+	int32_t rc = -EIO;
+	unsigned char buf[2];
+
+	memset(buf, 0, sizeof(buf));
+	buf[0] = baddr;
+	buf[1] = bdata;
+	rc = mt9p012_i2c_txdata(saddr, buf, 2);
+
+	if (rc < 0)
+		CDBG("i2c_write failed, saddr = 0x%x addr = 0x%x, val =0x%x!\n",
+		     saddr, baddr, bdata);
+
+	return rc;
+}
+
+static int32_t mt9p012_i2c_write_w(unsigned short saddr, unsigned short waddr,
+				   unsigned short wdata)
+{
+	int32_t rc = -EIO;
+	unsigned char buf[4];
+
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00) >> 8;
+	buf[1] = (waddr & 0x00FF);
+	buf[2] = (wdata & 0xFF00) >> 8;
+	buf[3] = (wdata & 0x00FF);
+
+	rc = mt9p012_i2c_txdata(saddr, buf, 4);
+
+	if (rc < 0)
+		CDBG("i2c_write_w failed, addr = 0x%x, val = 0x%x!\n",
+		     waddr, wdata);
+
+	return rc;
+}
+
+static int32_t mt9p012_i2c_write_w_table(struct mt9p012_i2c_reg_conf const
+					 *reg_conf_tbl, int num)
+{
+	int i;
+	int32_t rc = -EIO;
+
+	for (i = 0; i < num; i++) {
+		rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+					 reg_conf_tbl->waddr,
+					 reg_conf_tbl->wdata);
+		if (rc < 0)
+			break;
+		reg_conf_tbl++;
+	}
+
+	return rc;
+}
+
+static int32_t mt9p012_test(enum mt9p012_test_mode mo)
+{
+	int32_t rc = 0;
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+				 REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_HOLD);
+	if (rc < 0)
+		return rc;
+
+	if (mo == TEST_OFF)
+		return 0;
+	else {
+		rc = mt9p012_i2c_write_w_table(mt9p012_regs.ttbl,
+					       mt9p012_regs.ttbl_size);
+		if (rc < 0)
+			return rc;
+
+		rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+					 REG_TEST_PATTERN_MODE, (uint16_t) mo);
+		if (rc < 0)
+			return rc;
+	}
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+				 REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_UPDATE);
+	if (rc < 0)
+		return rc;
+
+	return rc;
+}
+
+static int32_t mt9p012_lens_shading_enable(uint8_t is_enable)
+{
+	int32_t rc = 0;
+
+	CDBG("%s: entered. enable = %d\n", __func__, is_enable);
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+				 REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_HOLD);
+	if (rc < 0)
+		return rc;
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x3780,
+				 ((uint16_t) is_enable) << 15);
+	if (rc < 0)
+		return rc;
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+				 REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_UPDATE);
+
+	CDBG("%s: exiting. rc = %d\n", __func__, rc);
+	return rc;
+}
+
+static int32_t mt9p012_set_lc(void)
+{
+	int32_t rc;
+
+	rc = mt9p012_i2c_write_w_table(mt9p012_regs.rftbl,
+				       mt9p012_regs.rftbl_size);
+
+	return rc;
+}
+
+static void mt9p012_get_pict_fps(uint16_t fps, uint16_t *pfps)
+{
+	/* input fps is preview fps in Q8 format */
+	uint32_t divider;	/*Q10 */
+	uint32_t pclk_mult;	/*Q10 */
+
+	if (mt9p012_ctrl->prev_res == QTR_SIZE) {
+		divider = (uint32_t)
+		    (((mt9p012_regs.reg_pat[RES_PREVIEW].frame_length_lines *
+		       mt9p012_regs.reg_pat[RES_PREVIEW].line_length_pck) *
+		      0x00000400) /
+		     (mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines *
+		      mt9p012_regs.reg_pat[RES_CAPTURE].line_length_pck));
+
+		pclk_mult =
+		    (uint32_t) ((mt9p012_regs.reg_pat[RES_CAPTURE].
+				 pll_multiplier * 0x00000400) /
+				(mt9p012_regs.reg_pat[RES_PREVIEW].
+				 pll_multiplier));
+	} else {
+		/* full size resolution used for preview. */
+		divider = 0x00000400;	/*1.0 */
+		pclk_mult = 0x00000400;	/*1.0 */
+	}
+
+	/* Verify PCLK settings and frame sizes. */
+	*pfps = (uint16_t) (fps * divider * pclk_mult / 0x00000400 /
+			    0x00000400);
+}
+
+static uint16_t mt9p012_get_prev_lines_pf(void)
+{
+	if (mt9p012_ctrl->prev_res == QTR_SIZE)
+		return mt9p012_regs.reg_pat[RES_PREVIEW].frame_length_lines;
+	else
+		return mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines;
+}
+
+static uint16_t mt9p012_get_prev_pixels_pl(void)
+{
+	if (mt9p012_ctrl->prev_res == QTR_SIZE)
+		return mt9p012_regs.reg_pat[RES_PREVIEW].line_length_pck;
+	else
+		return mt9p012_regs.reg_pat[RES_CAPTURE].line_length_pck;
+}
+
+static uint16_t mt9p012_get_pict_lines_pf(void)
+{
+	return mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines;
+}
+
+static uint16_t mt9p012_get_pict_pixels_pl(void)
+{
+	return mt9p012_regs.reg_pat[RES_CAPTURE].line_length_pck;
+}
+
+static uint32_t mt9p012_get_pict_max_exp_lc(void)
+{
+	uint16_t snapshot_lines_per_frame;
+
+	if (mt9p012_ctrl->pict_res == QTR_SIZE)
+		snapshot_lines_per_frame =
+		    mt9p012_regs.reg_pat[RES_PREVIEW].frame_length_lines - 1;
+	else
+		snapshot_lines_per_frame =
+		    mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines - 1;
+
+	return snapshot_lines_per_frame * 24;
+}
+
+static int32_t mt9p012_set_fps(struct fps_cfg *fps)
+{
+	/* input is new fps in Q10 format */
+	int32_t rc = 0;
+	enum mt9p012_setting setting;
+
+	mt9p012_ctrl->fps_divider = fps->fps_div;
+	mt9p012_ctrl->pict_fps_divider = fps->pict_fps_div;
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+				 REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_HOLD);
+	if (rc < 0)
+		return -EBUSY;
+
+	if (mt9p012_ctrl->sensormode == SENSOR_PREVIEW_MODE)
+		setting = RES_PREVIEW;
+	else
+		setting = RES_CAPTURE;
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+			REG_FRAME_LENGTH_LINES,
+			(mt9p012_regs.reg_pat[setting].frame_length_lines *
+			fps->fps_div / 0x00000400));
+	if (rc < 0)
+		return rc;
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+				 REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_UPDATE);
+
+	return rc;
+}
+
+static int32_t mt9p012_write_exp_gain(uint16_t gain, uint32_t line)
+{
+	uint16_t max_legal_gain = 0x01FF;
+	uint32_t line_length_ratio = 0x00000400;
+	enum mt9p012_setting setting;
+	int32_t rc = 0;
+
+	CDBG("Line:%d mt9p012_write_exp_gain \n", __LINE__);
+
+	if (mt9p012_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
+		mt9p012_ctrl->my_reg_gain = gain;
+		mt9p012_ctrl->my_reg_line_count = (uint16_t) line;
+	}
+
+	if (gain > max_legal_gain) {
+		CDBG("Max legal gain Line:%d \n", __LINE__);
+		gain = max_legal_gain;
+	}
+
+	/* Verify no overflow */
+	if (mt9p012_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
+		line = (uint32_t) (line * mt9p012_ctrl->fps_divider /
+				   0x00000400);
+		setting = RES_PREVIEW;
+	} else {
+		line = (uint32_t) (line * mt9p012_ctrl->pict_fps_divider /
+				   0x00000400);
+		setting = RES_CAPTURE;
+	}
+
+	/* Set digital gain to 1 */
+#ifdef MT9P012_REV_7
+	gain |= 0x1000;
+#else
+	gain |= 0x0200;
+#endif
+
+	if ((mt9p012_regs.reg_pat[setting].frame_length_lines - 1) < line) {
+		line_length_ratio = (uint32_t) (line * 0x00000400) /
+		    (mt9p012_regs.reg_pat[setting].frame_length_lines - 1);
+	} else
+		line_length_ratio = 0x00000400;
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr, REG_GLOBAL_GAIN, gain);
+	if (rc < 0) {
+		CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__);
+		return rc;
+	}
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+				 REG_COARSE_INT_TIME, line);
+	if (rc < 0) {
+		CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__);
+		return rc;
+	}
+
+	CDBG("mt9p012_write_exp_gain: gain = %d, line = %d\n", gain, line);
+
+	return rc;
+}
+
+static int32_t mt9p012_set_pict_exp_gain(uint16_t gain, uint32_t line)
+{
+	int32_t rc = 0;
+
+	CDBG("Line:%d mt9p012_set_pict_exp_gain \n", __LINE__);
+
+	rc = mt9p012_write_exp_gain(gain, line);
+	if (rc < 0) {
+		CDBG("Line:%d mt9p012_set_pict_exp_gain failed... \n",
+		     __LINE__);
+		return rc;
+	}
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+				 MT9P012_REG_RESET_REGISTER, 0x10CC | 0x0002);
+	if (rc < 0) {
+		CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__);
+		return rc;
+	}
+
+	mdelay(5);
+
+	/* camera_timed_wait(snapshot_wait*exposure_ratio); */
+	return rc;
+}
+
+static int32_t mt9p012_setting(enum mt9p012_reg_update rupdate,
+			       enum mt9p012_setting rt)
+{
+	int32_t rc = 0;
+
+	switch (rupdate) {
+	case UPDATE_PERIODIC:
+		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
+			struct mt9p012_i2c_reg_conf ppc_tbl[] = {
+				{REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_HOLD},
+				{REG_ROW_SPEED,
+				 mt9p012_regs.reg_pat[rt].row_speed},
+				{REG_X_ADDR_START,
+				 mt9p012_regs.reg_pat[rt].x_addr_start},
+				{REG_X_ADDR_END,
+				 mt9p012_regs.reg_pat[rt].x_addr_end},
+				{REG_Y_ADDR_START,
+				 mt9p012_regs.reg_pat[rt].y_addr_start},
+				{REG_Y_ADDR_END,
+				 mt9p012_regs.reg_pat[rt].y_addr_end},
+				{REG_READ_MODE,
+				 mt9p012_regs.reg_pat[rt].read_mode},
+				{REG_SCALE_M, mt9p012_regs.reg_pat[rt].scale_m},
+				{REG_X_OUTPUT_SIZE,
+				 mt9p012_regs.reg_pat[rt].x_output_size},
+				{REG_Y_OUTPUT_SIZE,
+				 mt9p012_regs.reg_pat[rt].y_output_size},
+
+				{REG_LINE_LENGTH_PCK,
+				 mt9p012_regs.reg_pat[rt].line_length_pck},
+				{REG_FRAME_LENGTH_LINES,
+				 (mt9p012_regs.reg_pat[rt].frame_length_lines *
+				  mt9p012_ctrl->fps_divider / 0x00000400)},
+				{REG_COARSE_INT_TIME,
+				 mt9p012_regs.reg_pat[rt].coarse_int_time},
+				{REG_FINE_INTEGRATION_TIME,
+				 mt9p012_regs.reg_pat[rt].fine_int_time},
+				{REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_UPDATE},
+			};
+			if (update_type == REG_INIT) {
+				update_type = rupdate;
+				return rc;
+			}
+			rc = mt9p012_i2c_write_w_table(&ppc_tbl[0],
+						ARRAY_SIZE(ppc_tbl));
+			if (rc < 0)
+				return rc;
+
+			rc = mt9p012_test(mt9p012_ctrl->set_test);
+			if (rc < 0)
+				return rc;
+
+			rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+						 MT9P012_REG_RESET_REGISTER,
+						 MT9P012_RESET_REGISTER_PWON |
+						 0x0002);
+			if (rc < 0)
+				return rc;
+
+			mdelay(5);	/* 15? wait for sensor to transition */
+
+			return rc;
+		}
+		break;		/* UPDATE_PERIODIC */
+
+	case REG_INIT:
+		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
+			struct mt9p012_i2c_reg_conf ipc_tbl1[] = {
+				{MT9P012_REG_RESET_REGISTER,
+				 MT9P012_RESET_REGISTER_PWOFF},
+				{REG_VT_PIX_CLK_DIV,
+				 mt9p012_regs.reg_pat[rt].vt_pix_clk_div},
+				{REG_VT_SYS_CLK_DIV,
+				 mt9p012_regs.reg_pat[rt].vt_sys_clk_div},
+				{REG_PRE_PLL_CLK_DIV,
+				 mt9p012_regs.reg_pat[rt].pre_pll_clk_div},
+				{REG_PLL_MULTIPLIER,
+				 mt9p012_regs.reg_pat[rt].pll_multiplier},
+				{REG_OP_PIX_CLK_DIV,
+				 mt9p012_regs.reg_pat[rt].op_pix_clk_div},
+				{REG_OP_SYS_CLK_DIV,
+				 mt9p012_regs.reg_pat[rt].op_sys_clk_div},
+#ifdef MT9P012_REV_7
+				{0x30B0, 0x0001},
+				{0x308E, 0xE060},
+				{0x3092, 0x0A52},
+				{0x3094, 0x4656},
+				{0x3096, 0x5652},
+				{0x30CA, 0x8006},
+				{0x312A, 0xDD02},
+				{0x312C, 0x00E4},
+				{0x3170, 0x299A},
+#endif
+				/* optimized settings for noise */
+				{0x3088, 0x6FF6},
+				{0x3154, 0x0282},
+				{0x3156, 0x0381},
+				{0x3162, 0x04CE},
+				{0x0204, 0x0010},
+				{0x0206, 0x0010},
+				{0x0208, 0x0010},
+				{0x020A, 0x0010},
+				{0x020C, 0x0010},
+				{MT9P012_REG_RESET_REGISTER,
+				 MT9P012_RESET_REGISTER_PWON},
+			};
+
+			struct mt9p012_i2c_reg_conf ipc_tbl2[] = {
+				{MT9P012_REG_RESET_REGISTER,
+				 MT9P012_RESET_REGISTER_PWOFF},
+				{REG_VT_PIX_CLK_DIV,
+				 mt9p012_regs.reg_pat[rt].vt_pix_clk_div},
+				{REG_VT_SYS_CLK_DIV,
+				 mt9p012_regs.reg_pat[rt].vt_sys_clk_div},
+				{REG_PRE_PLL_CLK_DIV,
+				 mt9p012_regs.reg_pat[rt].pre_pll_clk_div},
+				{REG_PLL_MULTIPLIER,
+				 mt9p012_regs.reg_pat[rt].pll_multiplier},
+				{REG_OP_PIX_CLK_DIV,
+				 mt9p012_regs.reg_pat[rt].op_pix_clk_div},
+				{REG_OP_SYS_CLK_DIV,
+				 mt9p012_regs.reg_pat[rt].op_sys_clk_div},
+#ifdef MT9P012_REV_7
+				{0x30B0, 0x0001},
+				{0x308E, 0xE060},
+				{0x3092, 0x0A52},
+				{0x3094, 0x4656},
+				{0x3096, 0x5652},
+				{0x30CA, 0x8006},
+				{0x312A, 0xDD02},
+				{0x312C, 0x00E4},
+				{0x3170, 0x299A},
+#endif
+				/* optimized settings for noise */
+				{0x3088, 0x6FF6},
+				{0x3154, 0x0282},
+				{0x3156, 0x0381},
+				{0x3162, 0x04CE},
+				{0x0204, 0x0010},
+				{0x0206, 0x0010},
+				{0x0208, 0x0010},
+				{0x020A, 0x0010},
+				{0x020C, 0x0010},
+				{MT9P012_REG_RESET_REGISTER,
+				 MT9P012_RESET_REGISTER_PWON},
+			};
+
+			struct mt9p012_i2c_reg_conf ipc_tbl3[] = {
+				{REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_HOLD},
+				/* Set preview or snapshot mode */
+				{REG_ROW_SPEED,
+				 mt9p012_regs.reg_pat[rt].row_speed},
+				{REG_X_ADDR_START,
+				 mt9p012_regs.reg_pat[rt].x_addr_start},
+				{REG_X_ADDR_END,
+				 mt9p012_regs.reg_pat[rt].x_addr_end},
+				{REG_Y_ADDR_START,
+				 mt9p012_regs.reg_pat[rt].y_addr_start},
+				{REG_Y_ADDR_END,
+				 mt9p012_regs.reg_pat[rt].y_addr_end},
+				{REG_READ_MODE,
+				 mt9p012_regs.reg_pat[rt].read_mode},
+				{REG_SCALE_M, mt9p012_regs.reg_pat[rt].scale_m},
+				{REG_X_OUTPUT_SIZE,
+				 mt9p012_regs.reg_pat[rt].x_output_size},
+				{REG_Y_OUTPUT_SIZE,
+				 mt9p012_regs.reg_pat[rt].y_output_size},
+				{REG_LINE_LENGTH_PCK,
+				 mt9p012_regs.reg_pat[rt].line_length_pck},
+				{REG_FRAME_LENGTH_LINES,
+				 mt9p012_regs.reg_pat[rt].frame_length_lines},
+				{REG_COARSE_INT_TIME,
+				 mt9p012_regs.reg_pat[rt].coarse_int_time},
+				{REG_FINE_INTEGRATION_TIME,
+				 mt9p012_regs.reg_pat[rt].fine_int_time},
+				{REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_UPDATE},
+			};
+
+			/* reset fps_divider */
+			mt9p012_ctrl->fps_divider = 1 * 0x0400;
+
+			rc = mt9p012_i2c_write_w_table(&ipc_tbl1[0],
+						       ARRAY_SIZE(ipc_tbl1));
+			if (rc < 0)
+				return rc;
+
+			rc = mt9p012_i2c_write_w_table(&ipc_tbl2[0],
+						       ARRAY_SIZE(ipc_tbl2));
+			if (rc < 0)
+				return rc;
+
+			mdelay(5);
+
+			rc = mt9p012_i2c_write_w_table(&ipc_tbl3[0],
+						       ARRAY_SIZE(ipc_tbl3));
+			if (rc < 0)
+				return rc;
+
+			/* load lens shading */
+			rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+						 REG_GROUPED_PARAMETER_HOLD,
+						 GROUPED_PARAMETER_HOLD);
+			if (rc < 0)
+				return rc;
+
+			rc = mt9p012_set_lc();
+			if (rc < 0)
+				return rc;
+
+			rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+						 REG_GROUPED_PARAMETER_HOLD,
+						 GROUPED_PARAMETER_UPDATE);
+
+			if (rc < 0)
+				return rc;
+		}
+		update_type = rupdate;
+		break;		/* case REG_INIT: */
+
+	default:
+		rc = -EINVAL;
+		break;
+	}			/* switch (rupdate) */
+
+	return rc;
+}
+
+static int32_t mt9p012_video_config(int mode, int res)
+{
+	int32_t rc;
+
+	switch (res) {
+	case QTR_SIZE:
+		rc = mt9p012_setting(UPDATE_PERIODIC, RES_PREVIEW);
+		if (rc < 0)
+			return rc;
+
+		CDBG("mt9p012 sensor configuration done!\n");
+		break;
+
+	case FULL_SIZE:
+		rc = mt9p012_setting(UPDATE_PERIODIC, RES_CAPTURE);
+		if (rc < 0)
+			return rc;
+
+		break;
+
+	default:
+		return 0;
+	}			/* switch */
+
+	mt9p012_ctrl->prev_res = res;
+	mt9p012_ctrl->curr_res = res;
+	mt9p012_ctrl->sensormode = mode;
+
+	rc = mt9p012_write_exp_gain(mt9p012_ctrl->my_reg_gain,
+				    mt9p012_ctrl->my_reg_line_count);
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+				 MT9P012_REG_RESET_REGISTER, 0x10cc | 0x0002);
+
+	return rc;
+}
+
+static int32_t mt9p012_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+
+	rc = mt9p012_setting(UPDATE_PERIODIC, RES_CAPTURE);
+	if (rc < 0)
+		return rc;
+
+	mt9p012_ctrl->curr_res = mt9p012_ctrl->pict_res;
+
+	mt9p012_ctrl->sensormode = mode;
+
+	return rc;
+}
+
+static int32_t mt9p012_raw_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+
+	rc = mt9p012_setting(UPDATE_PERIODIC, RES_CAPTURE);
+	if (rc < 0)
+		return rc;
+
+	mt9p012_ctrl->curr_res = mt9p012_ctrl->pict_res;
+
+	mt9p012_ctrl->sensormode = mode;
+
+	return rc;
+}
+
+static int32_t mt9p012_power_down(void)
+{
+	int32_t rc = 0;
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+				 MT9P012_REG_RESET_REGISTER,
+				 MT9P012_RESET_REGISTER_PWOFF);
+
+	mdelay(5);
+	return rc;
+}
+
+static int32_t mt9p012_move_focus(int direction, int32_t num_steps)
+{
+	int32_t rc;
+	int16_t step_direction;
+	int16_t actual_step;
+	int16_t next_position;
+	uint8_t code_val;
+	uint8_t time_out;
+	uint8_t temp_pos;
+
+	uint16_t actual_position_target;
+	if (num_steps > MT9P012_TOTAL_STEPS_NEAR_TO_FAR)
+		num_steps = MT9P012_TOTAL_STEPS_NEAR_TO_FAR;
+	else if (num_steps == 0) {
+		CDBG("mt9p012_move_focus failed at line %d ...\n", __LINE__);
+		return -EINVAL;
+	}
+
+	if (direction == MOVE_NEAR)
+		step_direction = -1;
+	else if (direction == MOVE_FAR)
+		step_direction = 1;
+	else {
+		CDBG("mt9p012_move_focus failed at line %d ...\n", __LINE__);
+		return -EINVAL;
+	}
+
+	if (mt9p012_ctrl->curr_lens_pos < mt9p012_ctrl->init_curr_lens_pos)
+		mt9p012_ctrl->curr_lens_pos = mt9p012_ctrl->init_curr_lens_pos;
+
+	actual_step = (int16_t) (step_direction * (int16_t) num_steps);
+	next_position = (int16_t) (mt9p012_ctrl->curr_lens_pos + actual_step);
+
+	if (next_position > MT9P012_TOTAL_STEPS_NEAR_TO_FAR)
+		next_position = MT9P012_TOTAL_STEPS_NEAR_TO_FAR;
+	else if (next_position < 0)
+		next_position = 0;
+
+	if (num_steps >= 10)
+		time_out = 100;
+	else
+		time_out = 30;
+	code_val = next_position;
+	actual_position_target = bam_step_lookup_table[code_val];
+	rc = mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x01, 0x29);
+	if (rc < 0)
+		return rc;
+	temp_pos = (uint8_t) (actual_position_target >> 8);
+	rc = mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x05, temp_pos);
+	if (rc < 0)
+		return rc;
+	temp_pos = (uint8_t) (actual_position_target & 0x00FF);
+	/* code_val_lsb |= mode_mask; */
+	rc = mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x06, temp_pos);
+	if (rc < 0)
+		return rc;
+
+	rc = mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x0B, time_out);
+	if (rc < 0)
+		return rc;
+	rc = mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x07, 0x27);
+	if (rc < 0)
+		return rc;
+
+	mdelay(time_out);
+
+	/* Storing the current lens Position */
+	mt9p012_ctrl->curr_lens_pos = next_position;
+
+	return rc;
+}
+
+static int32_t mt9p012_set_default_focus(void)
+{
+	int32_t rc = 0;
+
+	uint8_t temp_pos;
+
+	/* Write the digital code for current to the actuator */
+	rc = mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x01, 0x29);
+	if (rc < 0)
+		return rc;
+	temp_pos = (uint8_t) (bam_infinite >> 8);
+
+	rc = mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x05, temp_pos);
+	if (rc < 0)
+		return rc;
+	temp_pos = (uint8_t) (bam_infinite & 0x00FF);
+	rc = mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x06, temp_pos);
+	if (rc < 0)
+		return rc;
+
+	rc = mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x0B, 0x64);
+	if (rc < 0)
+		return rc;
+
+	rc = mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x07, 0x27);
+	if (rc < 0)
+		return rc;
+
+	mdelay(140);
+
+	mt9p012_ctrl->curr_lens_pos = MT9P012_TOTAL_STEPS_NEAR_TO_FAR;
+
+	return rc;
+}
+
+static int mt9p012_probe_init_done(const struct msm_camera_sensor_info *data)
+{
+	gpio_direction_output(data->sensor_reset, 0);
+	gpio_free(data->sensor_reset);
+	return 0;
+}
+
+static int mt9p012_probe_init_sensor(const struct msm_camera_sensor_info *data)
+{
+	int32_t rc;
+	uint16_t chipid;
+
+	rc = gpio_request(data->sensor_reset, "mt9p012");
+	if (!rc)
+		gpio_direction_output(data->sensor_reset, 1);
+	else
+		goto init_probe_done;
+
+	msleep(20);
+
+	/* RESET the sensor image part via I2C command */
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+				 MT9P012_REG_RESET_REGISTER, 0x10CC | 0x0001);
+	if (rc < 0) {
+		CDBG("sensor reset failed. rc = %d\n", rc);
+		goto init_probe_fail;
+	}
+
+	msleep(MT9P012_RESET_DELAY_MSECS);
+
+	/* 3. Read sensor Model ID: */
+	rc = mt9p012_i2c_read_w(mt9p012_client->addr,
+				MT9P012_REG_MODEL_ID, &chipid);
+	if (rc < 0)
+		goto init_probe_fail;
+
+	/* 4. Compare sensor ID to MT9T012VC ID: */
+	if (chipid != MT9P012_MODEL_ID) {
+		rc = -ENODEV;
+		goto init_probe_fail;
+	}
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x306E, 0x9000);
+	if (rc < 0) {
+		CDBG("REV_7 write failed. rc = %d\n", rc);
+		goto init_probe_fail;
+	}
+
+	/* RESET_REGISTER, enable parallel interface and disable serialiser */
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x301A, 0x10CC);
+	if (rc < 0) {
+		CDBG("enable parallel interface failed. rc = %d\n", rc);
+		goto init_probe_fail;
+	}
+
+	/* To disable the 2 extra lines */
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x3064, 0x0805);
+
+	if (rc < 0) {
+		CDBG("disable the 2 extra lines failed. rc = %d\n", rc);
+		goto init_probe_fail;
+	}
+
+	goto init_probe_done;
+
+init_probe_fail:
+	mt9p012_probe_init_done(data);
+init_probe_done:
+	return rc;
+}
+
+static int mt9p012_sensor_open_init(const struct msm_camera_sensor_info *data)
+{
+	int32_t rc;
+	unsigned short temp_pos;
+	uint8_t i;
+	uint16_t temp;
+
+	mt9p012_ctrl = kzalloc(sizeof(struct mt9p012_ctrl), GFP_KERNEL);
+	if (!mt9p012_ctrl) {
+		CDBG("mt9p012_init failed!\n");
+		rc = -ENOMEM;
+		goto init_done;
+	}
+
+	mt9p012_ctrl->fps_divider = 1 * 0x00000400;
+	mt9p012_ctrl->pict_fps_divider = 1 * 0x00000400;
+	mt9p012_ctrl->set_test = TEST_OFF;
+	mt9p012_ctrl->prev_res = QTR_SIZE;
+	mt9p012_ctrl->pict_res = FULL_SIZE;
+
+	if (data)
+		mt9p012_ctrl->sensordata = data;
+
+	msm_camio_camif_pad_reg_reset();
+	mdelay(20);
+
+	rc = mt9p012_probe_init_sensor(data);
+	if (rc < 0)
+		goto init_fail1;
+
+	if (mt9p012_ctrl->prev_res == QTR_SIZE)
+		rc = mt9p012_setting(REG_INIT, RES_PREVIEW);
+	else
+		rc = mt9p012_setting(REG_INIT, RES_CAPTURE);
+
+	if (rc < 0) {
+		CDBG("mt9p012_setting failed. rc = %d\n", rc);
+		goto init_fail1;
+	}
+
+	/* sensor : output enable */
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+				 MT9P012_REG_RESET_REGISTER,
+				 MT9P012_RESET_REGISTER_PWON);
+	if (rc < 0) {
+		CDBG("sensor output enable failed. rc = %d\n", rc);
+		goto init_fail1;
+	}
+
+	/* enable AF actuator */
+	rc = gpio_request(mt9p012_ctrl->sensordata->vcm_pwd, "mt9p012");
+	if (!rc)
+		gpio_direction_output(mt9p012_ctrl->sensordata->vcm_pwd, 1);
+	else {
+		CDBG("mt9p012_ctrl gpio request failed!\n");
+		goto init_fail1;
+	}
+
+	mdelay(20);
+
+	bam_infinite = 0;
+	bam_macro = 0;
+	/*initialize AF actuator */
+	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x01, 0x09);
+	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x07, 0x2E);
+	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x0A, 0x01);
+	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x17, 0x06);
+	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x16, 0x0A);
+
+	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x01, 0x29);
+	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x05, 0x00);
+	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x06, 0x00);
+	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x0B, 0x64);
+	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x07, 0x27);
+	mdelay(140);
+	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x01, 0x29);
+	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x05, 0x03);
+	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x06, 0xFF);
+	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x0B, 0x64);
+	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x07, 0x27);
+	mdelay(140);
+
+	if (mt9p012_i2c_read_b(MT9P012_AF_I2C_ADDR >> 1, 0x12, &temp_pos)
+	    >= 0) {
+		bam_infinite = (uint16_t) temp_pos;
+		if (mt9p012_i2c_read_b
+		    (MT9P012_AF_I2C_ADDR >> 1, 0x13, &temp_pos) >= 0)
+			bam_infinite =
+			    (bam_infinite << 8) | ((uint16_t) temp_pos);
+	} else {
+		bam_infinite = 100;
+	}
+
+	if (mt9p012_i2c_read_b(MT9P012_AF_I2C_ADDR >> 1, 0x14, &temp_pos)
+	    >= 0) {
+		bam_macro = (uint16_t) temp_pos;
+		if (mt9p012_i2c_read_b
+		    (MT9P012_AF_I2C_ADDR >> 1, 0x15, &temp_pos) >= 0)
+			bam_macro = (bam_macro << 8) | ((uint16_t) temp_pos);
+	}
+	temp = (bam_infinite - bam_macro) / MT9P012_TOTAL_STEPS_NEAR_TO_FAR;
+	for (i = 0; i < MT9P012_TOTAL_STEPS_NEAR_TO_FAR; i++)
+		bam_step_lookup_table[i] = bam_macro + temp * i;
+
+	bam_step_lookup_table[MT9P012_TOTAL_STEPS_NEAR_TO_FAR] = bam_infinite;
+
+	rc = mt9p012_set_default_focus();
+	if (rc >= 0)
+		goto init_done;
+
+init_fail1:
+	mt9p012_probe_init_done(data);
+	kfree(mt9p012_ctrl);
+init_done:
+	return rc;
+}
+
+static int mt9p012_init_client(struct i2c_client *client)
+{
+	/* Initialize the MSM_CAMI2C Chip */
+	init_waitqueue_head(&mt9p012_wait_queue);
+	return 0;
+}
+
+static int32_t mt9p012_set_sensor_mode(int mode, int res)
+{
+	int32_t rc = 0;
+
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		rc = mt9p012_video_config(mode, res);
+		break;
+
+	case SENSOR_SNAPSHOT_MODE:
+		rc = mt9p012_snapshot_config(mode);
+		break;
+
+	case SENSOR_RAW_SNAPSHOT_MODE:
+		rc = mt9p012_raw_snapshot_config(mode);
+		break;
+
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
+int mt9p012_sensor_config(void __user *argp)
+{
+	struct sensor_cfg_data cdata;
+	int rc = 0;
+
+	if (copy_from_user(&cdata,
+			   (void *)argp, sizeof(struct sensor_cfg_data)))
+		return -EFAULT;
+
+	mutex_lock(&mt9p012_mut);
+
+	CDBG("%s: cfgtype = %d\n", __func__, cdata.cfgtype);
+	switch (cdata.cfgtype) {
+	case CFG_GET_PICT_FPS:
+		mt9p012_get_pict_fps(cdata.cfg.gfps.prevfps,
+				     &(cdata.cfg.gfps.pictfps));
+
+		if (copy_to_user((void *)argp, &cdata,
+				 sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PREV_L_PF:
+		cdata.cfg.prevl_pf = mt9p012_get_prev_lines_pf();
+
+		if (copy_to_user((void *)argp,
+				 &cdata, sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PREV_P_PL:
+		cdata.cfg.prevp_pl = mt9p012_get_prev_pixels_pl();
+
+		if (copy_to_user((void *)argp,
+				 &cdata, sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_L_PF:
+		cdata.cfg.pictl_pf = mt9p012_get_pict_lines_pf();
+
+		if (copy_to_user((void *)argp,
+				 &cdata, sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_P_PL:
+		cdata.cfg.pictp_pl = mt9p012_get_pict_pixels_pl();
+
+		if (copy_to_user((void *)argp,
+				 &cdata, sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_MAX_EXP_LC:
+		cdata.cfg.pict_max_exp_lc = mt9p012_get_pict_max_exp_lc();
+
+		if (copy_to_user((void *)argp,
+				 &cdata, sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_SET_FPS:
+	case CFG_SET_PICT_FPS:
+		rc = mt9p012_set_fps(&(cdata.cfg.fps));
+		break;
+
+	case CFG_SET_EXP_GAIN:
+		rc = mt9p012_write_exp_gain(cdata.cfg.exp_gain.gain,
+					    cdata.cfg.exp_gain.line);
+		break;
+
+	case CFG_SET_PICT_EXP_GAIN:
+		CDBG("Line:%d CFG_SET_PICT_EXP_GAIN \n", __LINE__);
+		rc = mt9p012_set_pict_exp_gain(cdata.cfg.exp_gain.gain,
+					       cdata.cfg.exp_gain.line);
+		break;
+
+	case CFG_SET_MODE:
+		rc = mt9p012_set_sensor_mode(cdata.mode, cdata.rs);
+		break;
+
+	case CFG_PWR_DOWN:
+		rc = mt9p012_power_down();
+		break;
+
+	case CFG_MOVE_FOCUS:
+		CDBG("mt9p012_ioctl: CFG_MOVE_FOCUS: dir=%d steps=%d\n",
+		     cdata.cfg.focus.dir, cdata.cfg.focus.steps);
+		rc = mt9p012_move_focus(cdata.cfg.focus.dir,
+					cdata.cfg.focus.steps);
+		break;
+
+	case CFG_SET_DEFAULT_FOCUS:
+		rc = mt9p012_set_default_focus();
+
+		break;
+
+	case CFG_SET_EFFECT:
+		rc = mt9p012_set_default_focus();
+		break;
+
+	case CFG_SET_LENS_SHADING:
+		CDBG("%s: CFG_SET_LENS_SHADING\n", __func__);
+		rc = mt9p012_lens_shading_enable(cdata.cfg.lens_shading);
+		break;
+
+	case CFG_GET_AF_MAX_STEPS:
+		cdata.max_steps = MT9P012_STEPS_NEAR_TO_CLOSEST_INF;
+		if (copy_to_user((void *)argp,
+				 &cdata, sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	mutex_unlock(&mt9p012_mut);
+	return rc;
+}
+
+int mt9p012_sensor_release(void)
+{
+	int rc = -EBADF;
+
+	mutex_lock(&mt9p012_mut);
+
+	mt9p012_power_down();
+
+	gpio_direction_output(mt9p012_ctrl->sensordata->sensor_reset, 0);
+	gpio_free(mt9p012_ctrl->sensordata->sensor_reset);
+
+	gpio_direction_output(mt9p012_ctrl->sensordata->vcm_pwd, 0);
+	gpio_free(mt9p012_ctrl->sensordata->vcm_pwd);
+
+	kfree(mt9p012_ctrl);
+	mt9p012_ctrl = NULL;
+
+	CDBG("mt9p012_release completed\n");
+
+	mutex_unlock(&mt9p012_mut);
+	return rc;
+}
+
+static int mt9p012_i2c_probe(struct i2c_client *client,
+			     const struct i2c_device_id *id)
+{
+	int rc = 0;
+	CDBG("mt9p012_probe called!\n");
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		CDBG("i2c_check_functionality failed\n");
+		goto probe_failure;
+	}
+
+	mt9p012_sensorw = kzalloc(sizeof(struct mt9p012_work), GFP_KERNEL);
+	if (!mt9p012_sensorw) {
+		CDBG("kzalloc failed.\n");
+		rc = -ENOMEM;
+		goto probe_failure;
+	}
+
+	i2c_set_clientdata(client, mt9p012_sensorw);
+	mt9p012_init_client(client);
+	mt9p012_client = client;
+
+	mdelay(50);
+
+	CDBG("mt9p012_probe successed! rc = %d\n", rc);
+	return 0;
+
+probe_failure:
+	CDBG("mt9p012_probe failed! rc = %d\n", rc);
+	return rc;
+}
+
+static int __exit mt9p012_remove(struct i2c_client *client)
+{
+	struct mt9p012_work_t *sensorw = i2c_get_clientdata(client);
+	free_irq(client->irq, sensorw);
+	mt9p012_client = NULL;
+	kfree(sensorw);
+	return 0;
+}
+
+static const struct i2c_device_id mt9p012_i2c_id[] = {
+	{"mt9p012", 0}
+};
+
+static struct i2c_driver mt9p012_i2c_driver = {
+	.id_table = mt9p012_i2c_id,
+	.probe = mt9p012_i2c_probe,
+	.remove = __exit_p(mt9p012_i2c_remove),
+	.driver = {
+		.name = "mt9p012",
+	},
+};
+
+static int mt9p012_sensor_probe(const struct msm_camera_sensor_info *info,
+				struct msm_sensor_ctrl *s)
+{
+	int rc = i2c_add_driver(&mt9p012_i2c_driver);
+	if (rc < 0 || mt9p012_client == NULL) {
+		rc = -ENOTSUPP;
+		goto probe_done;
+	}
+
+	msm_camio_clk_rate_set(MT9P012_DEFAULT_CLOCK_RATE);
+	mdelay(20);
+
+	rc = mt9p012_probe_init_sensor(info);
+	if (rc < 0)
+		goto probe_done;
+
+	s->s_init = mt9p012_sensor_open_init;
+	s->s_release = mt9p012_sensor_release;
+	s->s_config = mt9p012_sensor_config;
+	s->s_mount_angle  = 0;
+	mt9p012_probe_init_done(info);
+
+probe_done:
+	CDBG("%s %s:%d\n", __FILE__, __func__, __LINE__);
+	return rc;
+}
+
+static int __mt9p012_probe(struct platform_device *pdev)
+{
+	return msm_camera_drv_start(pdev, mt9p012_sensor_probe);
+}
+
+static struct platform_driver msm_camera_driver = {
+	.probe = __mt9p012_probe,
+	.driver = {
+		.name = "msm_camera_mt9p012",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init mt9p012_init(void)
+{
+	return platform_driver_register(&msm_camera_driver);
+}
+
+module_init(mt9p012_init);
+void mt9p012_exit(void)
+{
+	i2c_del_driver(&mt9p012_i2c_driver);
+}
diff --git a/drivers/media/platform/msm/camera_v1/mt9p012_fox.c b/drivers/media/platform/msm/camera_v1/mt9p012_fox.c
new file mode 100644
index 0000000..a8d90c1
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mt9p012_fox.c
@@ -0,0 +1,1346 @@
+/* Copyright (c) 2009, 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/module.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/kernel.h>
+#include <media/msm_camera.h>
+#include <mach/gpio.h>
+#include <mach/camera.h>
+#include "mt9p012.h"
+
+/*=============================================================
+    SENSOR REGISTER DEFINES
+==============================================================*/
+#define MT9P012_REG_MODEL_ID         0x0000
+#define MT9P012_MODEL_ID             0x2801
+#define REG_GROUPED_PARAMETER_HOLD   0x0104
+#define GROUPED_PARAMETER_HOLD       0x0100
+#define GROUPED_PARAMETER_UPDATE     0x0000
+#define REG_COARSE_INT_TIME          0x3012
+#define REG_VT_PIX_CLK_DIV           0x0300
+#define REG_VT_SYS_CLK_DIV           0x0302
+#define REG_PRE_PLL_CLK_DIV          0x0304
+#define REG_PLL_MULTIPLIER           0x0306
+#define REG_OP_PIX_CLK_DIV           0x0308
+#define REG_OP_SYS_CLK_DIV           0x030A
+#define REG_SCALE_M                  0x0404
+#define REG_FRAME_LENGTH_LINES       0x300A
+#define REG_LINE_LENGTH_PCK          0x300C
+#define REG_X_ADDR_START             0x3004
+#define REG_Y_ADDR_START             0x3002
+#define REG_X_ADDR_END               0x3008
+#define REG_Y_ADDR_END               0x3006
+#define REG_X_OUTPUT_SIZE            0x034C
+#define REG_Y_OUTPUT_SIZE            0x034E
+#define REG_FINE_INTEGRATION_TIME    0x3014
+#define REG_ROW_SPEED                0x3016
+#define MT9P012_REG_RESET_REGISTER   0x301A
+#define MT9P012_RESET_REGISTER_PWON  0x10CC
+#define MT9P012_RESET_REGISTER_PWOFF 0x10C8
+#define REG_READ_MODE                0x3040
+#define REG_GLOBAL_GAIN              0x305E
+#define REG_TEST_PATTERN_MODE        0x3070
+
+#define MT9P012_REV_7
+
+enum mt9p012_test_mode {
+	TEST_OFF,
+	TEST_1,
+	TEST_2,
+	TEST_3
+};
+
+enum mt9p012_resolution {
+	QTR_SIZE,
+	FULL_SIZE,
+	INVALID_SIZE
+};
+
+enum mt9p012_reg_update {
+	/* Sensor egisters that need to be updated during initialization */
+	REG_INIT,
+	/* Sensor egisters that needs periodic I2C writes */
+	UPDATE_PERIODIC,
+	/* All the sensor Registers will be updated */
+	UPDATE_ALL,
+	/* Not valid update */
+	UPDATE_INVALID
+};
+
+enum mt9p012_setting {
+	RES_PREVIEW,
+	RES_CAPTURE
+};
+
+/* actuator's Slave Address */
+#define MT9P012_AF_I2C_ADDR   0x18
+
+/* AF Total steps parameters */
+#define MT9P012_STEPS_NEAR_TO_CLOSEST_INF  32
+#define MT9P012_TOTAL_STEPS_NEAR_TO_FAR    32
+
+#define MT9P012_MU5M0_PREVIEW_DUMMY_PIXELS 0
+#define MT9P012_MU5M0_PREVIEW_DUMMY_LINES  0
+
+/* Time in milisecs for waiting for the sensor to reset.*/
+#define MT9P012_RESET_DELAY_MSECS   66
+
+/* for 20 fps preview */
+#define MT9P012_DEFAULT_CLOCK_RATE  24000000
+#define MT9P012_DEFAULT_MAX_FPS     26	/* ???? */
+
+struct mt9p012_work {
+	struct work_struct work;
+};
+static struct mt9p012_work *mt9p012_sensorw;
+static struct i2c_client *mt9p012_client;
+
+struct mt9p012_ctrl {
+	const struct msm_camera_sensor_info *sensordata;
+
+	int sensormode;
+	uint32_t fps_divider;	/* init to 1 * 0x00000400 */
+	uint32_t pict_fps_divider;	/* init to 1 * 0x00000400 */
+
+	uint16_t curr_lens_pos;
+	uint16_t init_curr_lens_pos;
+	uint16_t my_reg_gain;
+	uint32_t my_reg_line_count;
+
+	enum mt9p012_resolution prev_res;
+	enum mt9p012_resolution pict_res;
+	enum mt9p012_resolution curr_res;
+	enum mt9p012_test_mode set_test;
+};
+static uint16_t update_type = UPDATE_PERIODIC;
+static struct mt9p012_ctrl *mt9p012_ctrl;
+static DECLARE_WAIT_QUEUE_HEAD(mt9p012_wait_queue);
+DEFINE_MUTEX(mt9p012_mut);
+
+
+/*=============================================================*/
+
+static int mt9p012_i2c_rxdata(unsigned short saddr, unsigned char *rxdata,
+			      int length)
+{
+	int retry_cnt = 0;
+	int rc;
+
+	struct i2c_msg msgs[] = {
+		{
+		 .addr = saddr,
+		 .flags = 0,
+		 .len = 2,
+		 .buf = rxdata,
+		 },
+		{
+		 .addr = saddr,
+		 .flags = I2C_M_RD,
+		 .len = length,
+		 .buf = rxdata,
+		 },
+	};
+
+	do {
+		rc = i2c_transfer(mt9p012_client->adapter, msgs, 2);
+		if (rc > 0)
+			break;
+		retry_cnt++;
+	} while (retry_cnt < 3);
+
+	if (rc < 0) {
+		pr_err("mt9p012_i2c_rxdata failed!:%d %d\n", rc, retry_cnt);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t mt9p012_i2c_read_w(unsigned short saddr, unsigned short raddr,
+				  unsigned short *rdata)
+{
+	int32_t rc = 0;
+	unsigned char buf[4];
+
+	if (!rdata)
+		return -EIO;
+
+	memset(buf, 0, sizeof(buf));
+
+	buf[0] = (raddr & 0xFF00) >> 8;
+	buf[1] = (raddr & 0x00FF);
+
+	rc = mt9p012_i2c_rxdata(saddr, buf, 2);
+	if (rc < 0)
+		return rc;
+
+	*rdata = buf[0] << 8 | buf[1];
+
+	if (rc < 0)
+		CDBG("mt9p012_i2c_read failed!\n");
+
+	return rc;
+}
+
+static int32_t mt9p012_i2c_txdata(unsigned short saddr, unsigned char *txdata,
+				  int length)
+{
+	int retry_cnt = 0;
+	int rc;
+
+	struct i2c_msg msg[] = {
+		{
+		 .addr = saddr,
+		 .flags = 0,
+		 .len = length,
+		 .buf = txdata,
+		 },
+	};
+
+	do {
+		rc = i2c_transfer(mt9p012_client->adapter, msg, 1);
+		if (rc > 0)
+			break;
+		retry_cnt++;
+	} while (retry_cnt < 3);
+
+	if (rc < 0) {
+		pr_err("mt9p012_i2c_txdata failed: %d %d\n", rc, retry_cnt);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t mt9p012_i2c_write_b(unsigned short saddr, unsigned short baddr,
+				   unsigned short bdata)
+{
+	int32_t rc = -EIO;
+	unsigned char buf[2];
+
+	memset(buf, 0, sizeof(buf));
+	buf[0] = baddr;
+	buf[1] = bdata;
+	rc = mt9p012_i2c_txdata(saddr, buf, 2);
+
+	if (rc < 0)
+		CDBG("i2c_write failed, saddr = 0x%x addr = 0x%x, val =0x%x!\n",
+		     saddr, baddr, bdata);
+
+	return rc;
+}
+
+static int32_t mt9p012_i2c_write_w(unsigned short saddr, unsigned short waddr,
+				   unsigned short wdata)
+{
+	int32_t rc = -EIO;
+	unsigned char buf[4];
+
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00) >> 8;
+	buf[1] = (waddr & 0x00FF);
+	buf[2] = (wdata & 0xFF00) >> 8;
+	buf[3] = (wdata & 0x00FF);
+
+	rc = mt9p012_i2c_txdata(saddr, buf, 4);
+
+	if (rc < 0)
+		CDBG("i2c_write_w failed, addr = 0x%x, val = 0x%x!\n",
+		     waddr, wdata);
+
+	return rc;
+}
+
+static int32_t mt9p012_i2c_write_w_table(struct mt9p012_i2c_reg_conf const
+					 *reg_conf_tbl, int num)
+{
+	int i;
+	int32_t rc = -EIO;
+
+	for (i = 0; i < num; i++) {
+		rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+					 reg_conf_tbl->waddr,
+					 reg_conf_tbl->wdata);
+		if (rc < 0)
+			break;
+		reg_conf_tbl++;
+	}
+
+	return rc;
+}
+
+static int32_t mt9p012_test(enum mt9p012_test_mode mo)
+{
+	int32_t rc = 0;
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+				 REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_HOLD);
+	if (rc < 0)
+		return rc;
+
+	if (mo == TEST_OFF)
+		return 0;
+	else {
+		rc = mt9p012_i2c_write_w_table(mt9p012_regs.ttbl,
+					       mt9p012_regs.ttbl_size);
+		if (rc < 0)
+			return rc;
+
+		rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+					 REG_TEST_PATTERN_MODE, (uint16_t) mo);
+		if (rc < 0)
+			return rc;
+	}
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+				 REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_UPDATE);
+	if (rc < 0)
+		return rc;
+
+	return rc;
+}
+
+static int32_t mt9p012_lens_shading_enable(uint8_t is_enable)
+{
+	int32_t rc = 0;
+
+	CDBG("%s: entered. enable = %d\n", __func__, is_enable);
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+				 REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_HOLD);
+	if (rc < 0)
+		return rc;
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x3780,
+				 ((uint16_t) is_enable) << 15);
+	if (rc < 0)
+		return rc;
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+				 REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_UPDATE);
+
+	CDBG("%s: exiting. rc = %d\n", __func__, rc);
+	return rc;
+}
+
+static int32_t mt9p012_set_lc(void)
+{
+	int32_t rc;
+
+	rc = mt9p012_i2c_write_w_table(mt9p012_regs.rftbl,
+				       mt9p012_regs.rftbl_size);
+
+	return rc;
+}
+
+static void mt9p012_get_pict_fps(uint16_t fps, uint16_t *pfps)
+{
+	/* input fps is preview fps in Q8 format */
+	uint32_t divider;	/*Q10 */
+	uint32_t pclk_mult;	/*Q10 */
+	uint32_t d1;
+	uint32_t d2;
+
+	d1 =
+		(uint32_t)(
+		(mt9p012_regs.reg_pat[RES_PREVIEW].frame_length_lines *
+		0x00000400) /
+		mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines);
+
+	d2 =
+		(uint32_t)(
+		(mt9p012_regs.reg_pat[RES_PREVIEW].line_length_pck *
+		0x00000400) /
+		mt9p012_regs.reg_pat[RES_CAPTURE].line_length_pck);
+
+	divider = (uint32_t) (d1 * d2) / 0x00000400;
+
+	pclk_mult =
+		(uint32_t) ((mt9p012_regs.reg_pat[RES_CAPTURE].pll_multiplier *
+		0x00000400) /
+		(mt9p012_regs.reg_pat[RES_PREVIEW].pll_multiplier));
+
+	/* Verify PCLK settings and frame sizes. */
+	*pfps = (uint16_t) (fps * divider * pclk_mult / 0x00000400 /
+			    0x00000400);
+}
+
+static uint16_t mt9p012_get_prev_lines_pf(void)
+{
+	if (mt9p012_ctrl->prev_res == QTR_SIZE)
+		return mt9p012_regs.reg_pat[RES_PREVIEW].frame_length_lines;
+	else
+		return mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines;
+}
+
+static uint16_t mt9p012_get_prev_pixels_pl(void)
+{
+	if (mt9p012_ctrl->prev_res == QTR_SIZE)
+		return mt9p012_regs.reg_pat[RES_PREVIEW].line_length_pck;
+	else
+		return mt9p012_regs.reg_pat[RES_CAPTURE].line_length_pck;
+}
+
+static uint16_t mt9p012_get_pict_lines_pf(void)
+{
+	return mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines;
+}
+
+static uint16_t mt9p012_get_pict_pixels_pl(void)
+{
+	return mt9p012_regs.reg_pat[RES_CAPTURE].line_length_pck;
+}
+
+static uint32_t mt9p012_get_pict_max_exp_lc(void)
+{
+	uint16_t snapshot_lines_per_frame;
+
+	if (mt9p012_ctrl->pict_res == QTR_SIZE)
+		snapshot_lines_per_frame =
+		    mt9p012_regs.reg_pat[RES_PREVIEW].frame_length_lines - 1;
+	else
+		snapshot_lines_per_frame =
+		    mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines - 1;
+
+	return snapshot_lines_per_frame * 24;
+}
+
+static int32_t mt9p012_set_fps(struct fps_cfg *fps)
+{
+	/* input is new fps in Q10 format */
+	int32_t rc = 0;
+	enum mt9p012_setting setting;
+
+	mt9p012_ctrl->fps_divider = fps->fps_div;
+	mt9p012_ctrl->pict_fps_divider = fps->pict_fps_div;
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+				 REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_HOLD);
+	if (rc < 0)
+		return -EBUSY;
+
+	if (mt9p012_ctrl->sensormode == SENSOR_PREVIEW_MODE)
+		setting = RES_PREVIEW;
+	else
+		setting = RES_CAPTURE;
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+		REG_FRAME_LENGTH_LINES,
+		(mt9p012_regs.reg_pat[setting].frame_length_lines *
+		fps->fps_div / 0x00000400));
+	if (rc < 0)
+		return rc;
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+				 REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_UPDATE);
+
+	return rc;
+}
+
+static int32_t mt9p012_write_exp_gain(uint16_t gain, uint32_t line)
+{
+	uint16_t max_legal_gain = 0x01FF;
+	uint32_t line_length_ratio = 0x00000400;
+	enum mt9p012_setting setting;
+	int32_t rc = 0;
+
+	CDBG("Line:%d mt9p012_write_exp_gain \n", __LINE__);
+
+	if (mt9p012_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
+		mt9p012_ctrl->my_reg_gain = gain;
+		mt9p012_ctrl->my_reg_line_count = (uint16_t) line;
+	}
+
+	if (gain > max_legal_gain) {
+		CDBG("Max legal gain Line:%d \n", __LINE__);
+		gain = max_legal_gain;
+	}
+
+	/* Verify no overflow */
+	if (mt9p012_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
+		line = (uint32_t) (line * mt9p012_ctrl->fps_divider /
+				   0x00000400);
+		setting = RES_PREVIEW;
+	} else {
+		line = (uint32_t) (line * mt9p012_ctrl->pict_fps_divider /
+				   0x00000400);
+		setting = RES_CAPTURE;
+	}
+
+	/* Set digital gain to 1 */
+#ifdef MT9P012_REV_7
+	gain |= 0x1000;
+#else
+	gain |= 0x0200;
+#endif
+
+	if ((mt9p012_regs.reg_pat[setting].frame_length_lines - 1) < line) {
+		line_length_ratio = (uint32_t) (line * 0x00000400) /
+		    (mt9p012_regs.reg_pat[setting].frame_length_lines - 1);
+	} else
+		line_length_ratio = 0x00000400;
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr, REG_GLOBAL_GAIN, gain);
+	if (rc < 0) {
+		CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__);
+		return rc;
+	}
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+				 REG_COARSE_INT_TIME, line);
+	if (rc < 0) {
+		CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__);
+		return rc;
+	}
+
+	CDBG("mt9p012_write_exp_gain: gain = %d, line = %d\n", gain, line);
+
+	return rc;
+}
+
+static int32_t mt9p012_set_pict_exp_gain(uint16_t gain, uint32_t line)
+{
+	int32_t rc = 0;
+
+	CDBG("Line:%d mt9p012_set_pict_exp_gain \n", __LINE__);
+
+	rc = mt9p012_write_exp_gain(gain, line);
+	if (rc < 0) {
+		CDBG("Line:%d mt9p012_set_pict_exp_gain failed... \n",
+		     __LINE__);
+		return rc;
+	}
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+				 MT9P012_REG_RESET_REGISTER, 0x10CC | 0x0002);
+	if (rc < 0) {
+		CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__);
+		return rc;
+	}
+
+	mdelay(5);
+
+	/* camera_timed_wait(snapshot_wait*exposure_ratio); */
+	return rc;
+}
+
+static int32_t mt9p012_setting(enum mt9p012_reg_update rupdate,
+			       enum mt9p012_setting rt)
+{
+	int32_t rc = 0;
+	switch (rupdate) {
+	case UPDATE_PERIODIC:
+		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
+			struct mt9p012_i2c_reg_conf ppc_tbl[] = {
+				{REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_HOLD},
+				{REG_ROW_SPEED,
+				 mt9p012_regs.reg_pat[rt].row_speed},
+				{REG_X_ADDR_START,
+				 mt9p012_regs.reg_pat[rt].x_addr_start},
+				{REG_X_ADDR_END,
+				 mt9p012_regs.reg_pat[rt].x_addr_end},
+				{REG_Y_ADDR_START,
+				 mt9p012_regs.reg_pat[rt].y_addr_start},
+				{REG_Y_ADDR_END,
+				 mt9p012_regs.reg_pat[rt].y_addr_end},
+				{REG_READ_MODE,
+				 mt9p012_regs.reg_pat[rt].read_mode},
+				{REG_SCALE_M, mt9p012_regs.reg_pat[rt].scale_m},
+				{REG_X_OUTPUT_SIZE,
+				 mt9p012_regs.reg_pat[rt].x_output_size},
+				{REG_Y_OUTPUT_SIZE,
+				 mt9p012_regs.reg_pat[rt].y_output_size},
+
+				{REG_LINE_LENGTH_PCK,
+				 mt9p012_regs.reg_pat[rt].line_length_pck},
+				{REG_FRAME_LENGTH_LINES,
+				 (mt9p012_regs.reg_pat[rt].frame_length_lines *
+				  mt9p012_ctrl->fps_divider / 0x00000400)},
+				{REG_COARSE_INT_TIME,
+				 mt9p012_regs.reg_pat[rt].coarse_int_time},
+				{REG_FINE_INTEGRATION_TIME,
+				 mt9p012_regs.reg_pat[rt].fine_int_time},
+				{REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_UPDATE},
+			};
+			if (update_type == REG_INIT) {
+				update_type = rupdate;
+				return rc;
+			}
+			rc = mt9p012_i2c_write_w_table(&ppc_tbl[0],
+						ARRAY_SIZE(ppc_tbl));
+			if (rc < 0)
+				return rc;
+
+			rc = mt9p012_test(mt9p012_ctrl->set_test);
+			if (rc < 0)
+				return rc;
+
+			rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+						 MT9P012_REG_RESET_REGISTER,
+						 MT9P012_RESET_REGISTER_PWON |
+						 0x0002);
+			if (rc < 0)
+				return rc;
+
+			mdelay(5);	/* 15? wait for sensor to transition */
+
+			return rc;
+		}
+		break;		/* UPDATE_PERIODIC */
+
+	case REG_INIT:
+		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
+			struct mt9p012_i2c_reg_conf ipc_tbl1[] = {
+				{MT9P012_REG_RESET_REGISTER,
+				 MT9P012_RESET_REGISTER_PWOFF},
+				{REG_VT_PIX_CLK_DIV,
+				 mt9p012_regs.reg_pat[rt].vt_pix_clk_div},
+				{REG_VT_SYS_CLK_DIV,
+				 mt9p012_regs.reg_pat[rt].vt_sys_clk_div},
+				{REG_PRE_PLL_CLK_DIV,
+				 mt9p012_regs.reg_pat[rt].pre_pll_clk_div},
+				{REG_PLL_MULTIPLIER,
+				 mt9p012_regs.reg_pat[rt].pll_multiplier},
+				{REG_OP_PIX_CLK_DIV,
+				 mt9p012_regs.reg_pat[rt].op_pix_clk_div},
+				{REG_OP_SYS_CLK_DIV,
+				 mt9p012_regs.reg_pat[rt].op_sys_clk_div},
+#ifdef MT9P012_REV_7
+				{0x30B0, 0x0001},
+				{0x308E, 0xE060},
+				{0x3092, 0x0A52},
+				{0x3094, 0x4656},
+				{0x3096, 0x5652},
+				{0x30CA, 0x8006},
+				{0x312A, 0xDD02},
+				{0x312C, 0x00E4},
+				{0x3170, 0x299A},
+#endif
+				/* optimized settings for noise */
+				{0x3088, 0x6FF6},
+				{0x3154, 0x0282},
+				{0x3156, 0x0381},
+				{0x3162, 0x04CE},
+				{0x0204, 0x0010},
+				{0x0206, 0x0010},
+				{0x0208, 0x0010},
+				{0x020A, 0x0010},
+				{0x020C, 0x0010},
+				{MT9P012_REG_RESET_REGISTER,
+				 MT9P012_RESET_REGISTER_PWON},
+			};
+
+			struct mt9p012_i2c_reg_conf ipc_tbl2[] = {
+				{MT9P012_REG_RESET_REGISTER,
+				 MT9P012_RESET_REGISTER_PWOFF},
+				{REG_VT_PIX_CLK_DIV,
+				 mt9p012_regs.reg_pat[rt].vt_pix_clk_div},
+				{REG_VT_SYS_CLK_DIV,
+				 mt9p012_regs.reg_pat[rt].vt_sys_clk_div},
+				{REG_PRE_PLL_CLK_DIV,
+				 mt9p012_regs.reg_pat[rt].pre_pll_clk_div},
+				{REG_PLL_MULTIPLIER,
+				 mt9p012_regs.reg_pat[rt].pll_multiplier},
+				{REG_OP_PIX_CLK_DIV,
+				 mt9p012_regs.reg_pat[rt].op_pix_clk_div},
+				{REG_OP_SYS_CLK_DIV,
+				 mt9p012_regs.reg_pat[rt].op_sys_clk_div},
+#ifdef MT9P012_REV_7
+				{0x30B0, 0x0001},
+				{0x308E, 0xE060},
+				{0x3092, 0x0A52},
+				{0x3094, 0x4656},
+				{0x3096, 0x5652},
+				{0x30CA, 0x8006},
+				{0x312A, 0xDD02},
+				{0x312C, 0x00E4},
+				{0x3170, 0x299A},
+#endif
+				/* optimized settings for noise */
+				{0x3088, 0x6FF6},
+				{0x3154, 0x0282},
+				{0x3156, 0x0381},
+				{0x3162, 0x04CE},
+				{0x0204, 0x0010},
+				{0x0206, 0x0010},
+				{0x0208, 0x0010},
+				{0x020A, 0x0010},
+				{0x020C, 0x0010},
+				{MT9P012_REG_RESET_REGISTER,
+				 MT9P012_RESET_REGISTER_PWON},
+			};
+
+			struct mt9p012_i2c_reg_conf ipc_tbl3[] = {
+				{REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_HOLD},
+				/* Set preview or snapshot mode */
+				{REG_ROW_SPEED,
+				 mt9p012_regs.reg_pat[rt].row_speed},
+				{REG_X_ADDR_START,
+				 mt9p012_regs.reg_pat[rt].x_addr_start},
+				{REG_X_ADDR_END,
+				 mt9p012_regs.reg_pat[rt].x_addr_end},
+				{REG_Y_ADDR_START,
+				 mt9p012_regs.reg_pat[rt].y_addr_start},
+				{REG_Y_ADDR_END,
+				 mt9p012_regs.reg_pat[rt].y_addr_end},
+				{REG_READ_MODE,
+				 mt9p012_regs.reg_pat[rt].read_mode},
+				{REG_SCALE_M, mt9p012_regs.reg_pat[rt].scale_m},
+				{REG_X_OUTPUT_SIZE,
+				 mt9p012_regs.reg_pat[rt].x_output_size},
+				{REG_Y_OUTPUT_SIZE,
+				 mt9p012_regs.reg_pat[rt].y_output_size},
+				{REG_LINE_LENGTH_PCK,
+				 mt9p012_regs.reg_pat[rt].line_length_pck},
+				{REG_FRAME_LENGTH_LINES,
+				 mt9p012_regs.reg_pat[rt].frame_length_lines},
+				{REG_COARSE_INT_TIME,
+				 mt9p012_regs.reg_pat[rt].coarse_int_time},
+				{REG_FINE_INTEGRATION_TIME,
+				 mt9p012_regs.reg_pat[rt].fine_int_time},
+				{REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_UPDATE},
+			};
+
+			/* reset fps_divider */
+			mt9p012_ctrl->fps_divider = 1 * 0x0400;
+
+			rc = mt9p012_i2c_write_w_table(&ipc_tbl1[0],
+						       ARRAY_SIZE(ipc_tbl1));
+			if (rc < 0)
+				return rc;
+
+			rc = mt9p012_i2c_write_w_table(&ipc_tbl2[0],
+						       ARRAY_SIZE(ipc_tbl2));
+			if (rc < 0)
+				return rc;
+
+			mdelay(5);
+
+			rc = mt9p012_i2c_write_w_table(&ipc_tbl3[0],
+						       ARRAY_SIZE(ipc_tbl3));
+			if (rc < 0)
+				return rc;
+
+			/* load lens shading */
+			rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+						 REG_GROUPED_PARAMETER_HOLD,
+						 GROUPED_PARAMETER_HOLD);
+			if (rc < 0)
+				return rc;
+
+			rc = mt9p012_set_lc();
+			if (rc < 0)
+				return rc;
+
+			rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+						 REG_GROUPED_PARAMETER_HOLD,
+						 GROUPED_PARAMETER_UPDATE);
+
+			if (rc < 0)
+				return rc;
+		}
+		update_type = rupdate;
+		break;		/* case REG_INIT: */
+
+	default:
+		rc = -EINVAL;
+		break;
+	}			/* switch (rupdate) */
+
+	return rc;
+}
+
+static int32_t mt9p012_video_config(int mode, int res)
+{
+	int32_t rc;
+
+	switch (res) {
+	case QTR_SIZE:
+		rc = mt9p012_setting(UPDATE_PERIODIC, RES_PREVIEW);
+		if (rc < 0)
+			return rc;
+
+		CDBG("mt9p012 sensor configuration done!\n");
+		break;
+
+	case FULL_SIZE:
+		rc = mt9p012_setting(UPDATE_PERIODIC, RES_CAPTURE);
+		if (rc < 0)
+			return rc;
+
+		break;
+
+	default:
+		return 0;
+	}			/* switch */
+
+	mt9p012_ctrl->prev_res = res;
+	mt9p012_ctrl->curr_res = res;
+	mt9p012_ctrl->sensormode = mode;
+
+	rc = mt9p012_write_exp_gain(mt9p012_ctrl->my_reg_gain,
+				    mt9p012_ctrl->my_reg_line_count);
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+				 MT9P012_REG_RESET_REGISTER, 0x10cc | 0x0002);
+
+	return rc;
+}
+
+static int32_t mt9p012_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+
+	rc = mt9p012_setting(UPDATE_PERIODIC, RES_CAPTURE);
+	if (rc < 0)
+		return rc;
+
+	mt9p012_ctrl->curr_res = mt9p012_ctrl->pict_res;
+
+	mt9p012_ctrl->sensormode = mode;
+
+	return rc;
+}
+
+static int32_t mt9p012_raw_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+
+	rc = mt9p012_setting(UPDATE_PERIODIC, RES_CAPTURE);
+	if (rc < 0)
+		return rc;
+
+	mt9p012_ctrl->curr_res = mt9p012_ctrl->pict_res;
+
+	mt9p012_ctrl->sensormode = mode;
+
+	return rc;
+}
+
+static int32_t mt9p012_power_down(void)
+{
+	int32_t rc = 0;
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+				 MT9P012_REG_RESET_REGISTER,
+				 MT9P012_RESET_REGISTER_PWOFF);
+
+	mdelay(5);
+	return rc;
+}
+
+static int32_t mt9p012_move_focus(int direction, int32_t num_steps)
+{
+	int16_t step_direction;
+	int16_t actual_step;
+	int16_t next_position;
+	uint8_t code_val_msb, code_val_lsb;
+
+	if (num_steps > MT9P012_TOTAL_STEPS_NEAR_TO_FAR)
+		num_steps = MT9P012_TOTAL_STEPS_NEAR_TO_FAR;
+	else if (num_steps == 0) {
+		CDBG("mt9p012_move_focus failed at line %d ...\n", __LINE__);
+		return -EINVAL;
+	}
+
+	if (direction == MOVE_NEAR)
+		step_direction = 16;	/* 10bit */
+	else if (direction == MOVE_FAR)
+		step_direction = -16;	/* 10 bit */
+	else {
+		CDBG("mt9p012_move_focus failed at line %d ...\n", __LINE__);
+		return -EINVAL;
+	}
+
+	if (mt9p012_ctrl->curr_lens_pos < mt9p012_ctrl->init_curr_lens_pos)
+		mt9p012_ctrl->curr_lens_pos = mt9p012_ctrl->init_curr_lens_pos;
+
+	actual_step = (int16_t) (step_direction * (int16_t) num_steps);
+	next_position = (int16_t) (mt9p012_ctrl->curr_lens_pos + actual_step);
+
+	if (next_position > 1023)
+		next_position = 1023;
+	else if (next_position < 0)
+		next_position = 0;
+
+	code_val_msb = next_position >> 4;
+	code_val_lsb = (next_position & 0x000F) << 4;
+	/* code_val_lsb |= mode_mask; */
+
+	/* Writing the digital code for current to the actuator */
+	if (mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1,
+				code_val_msb, code_val_lsb) < 0) {
+		CDBG("mt9p012_move_focus failed at line %d ...\n", __LINE__);
+		return -EBUSY;
+	}
+
+	/* Storing the current lens Position */
+	mt9p012_ctrl->curr_lens_pos = next_position;
+
+	return 0;
+}
+
+static int32_t mt9p012_set_default_focus(void)
+{
+	int32_t rc = 0;
+	uint8_t code_val_msb, code_val_lsb;
+
+	code_val_msb = 0x00;
+	code_val_lsb = 0x00;
+
+	/* Write the digital code for current to the actuator */
+	rc = mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1,
+				 code_val_msb, code_val_lsb);
+
+	mt9p012_ctrl->curr_lens_pos = 0;
+	mt9p012_ctrl->init_curr_lens_pos = 0;
+
+	return rc;
+}
+
+static int mt9p012_probe_init_done(const struct msm_camera_sensor_info *data)
+{
+	gpio_direction_output(data->sensor_reset, 0);
+	gpio_free(data->sensor_reset);
+	return 0;
+}
+
+static int mt9p012_probe_init_sensor(const struct msm_camera_sensor_info *data)
+{
+	int32_t rc;
+	uint16_t chipid;
+
+	rc = gpio_request(data->sensor_reset, "mt9p012");
+	if (!rc)
+		gpio_direction_output(data->sensor_reset, 1);
+	else
+		goto init_probe_done;
+
+	msleep(20);
+
+	/* RESET the sensor image part via I2C command */
+	CDBG("mt9p012_sensor_init(): reseting sensor.\n");
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+				 MT9P012_REG_RESET_REGISTER, 0x10CC | 0x0001);
+	if (rc < 0) {
+		CDBG("sensor reset failed. rc = %d\n", rc);
+		goto init_probe_fail;
+	}
+
+	msleep(MT9P012_RESET_DELAY_MSECS);
+
+	/* 3. Read sensor Model ID: */
+	rc = mt9p012_i2c_read_w(mt9p012_client->addr,
+				MT9P012_REG_MODEL_ID, &chipid);
+	if (rc < 0)
+		goto init_probe_fail;
+
+	/* 4. Compare sensor ID to MT9T012VC ID: */
+	if (chipid != MT9P012_MODEL_ID) {
+		CDBG("mt9p012 wrong model_id = 0x%x\n", chipid);
+		rc = -ENODEV;
+		goto init_probe_fail;
+	}
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x306E, 0x9000);
+	if (rc < 0) {
+		CDBG("REV_7 write failed. rc = %d\n", rc);
+		goto init_probe_fail;
+	}
+
+	/* RESET_REGISTER, enable parallel interface and disable serialiser */
+	CDBG("mt9p012_sensor_init(): enabling parallel interface.\n");
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x301A, 0x10CC);
+	if (rc < 0) {
+		CDBG("enable parallel interface failed. rc = %d\n", rc);
+		goto init_probe_fail;
+	}
+
+	/* To disable the 2 extra lines */
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x3064, 0x0805);
+
+	if (rc < 0) {
+		CDBG("disable the 2 extra lines failed. rc = %d\n", rc);
+		goto init_probe_fail;
+	}
+	goto init_probe_done;
+
+init_probe_fail:
+	mt9p012_probe_init_done(data);
+init_probe_done:
+	return rc;
+}
+
+static int mt9p012_sensor_open_init(const struct msm_camera_sensor_info *data)
+{
+	int32_t rc;
+
+	mt9p012_ctrl = kzalloc(sizeof(struct mt9p012_ctrl), GFP_KERNEL);
+	if (!mt9p012_ctrl) {
+		CDBG("mt9p012_init failed!\n");
+		rc = -ENOMEM;
+		goto init_done;
+	}
+
+	mt9p012_ctrl->fps_divider = 1 * 0x00000400;
+	mt9p012_ctrl->pict_fps_divider = 1 * 0x00000400;
+	mt9p012_ctrl->set_test = TEST_OFF;
+	mt9p012_ctrl->prev_res = QTR_SIZE;
+	mt9p012_ctrl->pict_res = FULL_SIZE;
+
+	if (data)
+		mt9p012_ctrl->sensordata = data;
+
+	msm_camio_camif_pad_reg_reset();
+	mdelay(20);
+
+	rc = mt9p012_probe_init_sensor(data);
+	if (rc < 0)
+		goto init_fail1;
+
+	if (mt9p012_ctrl->prev_res == QTR_SIZE)
+		rc = mt9p012_setting(REG_INIT, RES_PREVIEW);
+	else
+		rc = mt9p012_setting(REG_INIT, RES_CAPTURE);
+
+	if (rc < 0) {
+		CDBG("mt9p012_setting failed. rc = %d\n", rc);
+		goto init_fail1;
+	}
+
+	/* sensor : output enable */
+	CDBG("mt9p012_sensor_open_init(): enabling output.\n");
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+				 MT9P012_REG_RESET_REGISTER,
+				 MT9P012_RESET_REGISTER_PWON);
+	if (rc < 0) {
+		CDBG("sensor output enable failed. rc = %d\n", rc);
+		goto init_fail1;
+	}
+
+	/* enable AF actuator */
+	if (mt9p012_ctrl->sensordata->vcm_enable) {
+		CDBG("enable AF actuator, gpio = %d\n",
+			 mt9p012_ctrl->sensordata->vcm_pwd);
+		rc = gpio_request(mt9p012_ctrl->sensordata->vcm_pwd,
+						"mt9p012");
+		if (!rc)
+			gpio_direction_output(
+				mt9p012_ctrl->sensordata->vcm_pwd,
+				 1);
+		else {
+			CDBG("mt9p012_ctrl gpio request failed!\n");
+			goto init_fail1;
+		}
+		msleep(20);
+		rc = mt9p012_set_default_focus();
+		if (rc < 0) {
+			gpio_direction_output(mt9p012_ctrl->sensordata->vcm_pwd,
+								0);
+			gpio_free(mt9p012_ctrl->sensordata->vcm_pwd);
+		}
+	}
+	if (rc >= 0)
+		goto init_done;
+init_fail1:
+	mt9p012_probe_init_done(data);
+	kfree(mt9p012_ctrl);
+init_done:
+	return rc;
+}
+
+static int mt9p012_init_client(struct i2c_client *client)
+{
+	/* Initialize the MSM_CAMI2C Chip */
+	init_waitqueue_head(&mt9p012_wait_queue);
+	return 0;
+}
+
+static int32_t mt9p012_set_sensor_mode(int mode, int res)
+{
+	int32_t rc = 0;
+
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		rc = mt9p012_video_config(mode, res);
+		break;
+
+	case SENSOR_SNAPSHOT_MODE:
+		rc = mt9p012_snapshot_config(mode);
+		break;
+
+	case SENSOR_RAW_SNAPSHOT_MODE:
+		rc = mt9p012_raw_snapshot_config(mode);
+		break;
+
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
+int mt9p012_sensor_config(void __user *argp)
+{
+	struct sensor_cfg_data cdata;
+	int rc = 0;
+
+	if (copy_from_user(&cdata,
+			   (void *)argp, sizeof(struct sensor_cfg_data)))
+		return -EFAULT;
+
+	mutex_lock(&mt9p012_mut);
+
+	CDBG("%s: cfgtype = %d\n", __func__, cdata.cfgtype);
+	switch (cdata.cfgtype) {
+	case CFG_GET_PICT_FPS:
+		mt9p012_get_pict_fps(cdata.cfg.gfps.prevfps,
+				     &(cdata.cfg.gfps.pictfps));
+
+		if (copy_to_user((void *)argp, &cdata,
+				 sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PREV_L_PF:
+		cdata.cfg.prevl_pf = mt9p012_get_prev_lines_pf();
+
+		if (copy_to_user((void *)argp,
+				 &cdata, sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PREV_P_PL:
+		cdata.cfg.prevp_pl = mt9p012_get_prev_pixels_pl();
+
+		if (copy_to_user((void *)argp,
+				 &cdata, sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_L_PF:
+		cdata.cfg.pictl_pf = mt9p012_get_pict_lines_pf();
+
+		if (copy_to_user((void *)argp,
+				 &cdata, sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_P_PL:
+		cdata.cfg.pictp_pl = mt9p012_get_pict_pixels_pl();
+
+		if (copy_to_user((void *)argp,
+				 &cdata, sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_MAX_EXP_LC:
+		cdata.cfg.pict_max_exp_lc = mt9p012_get_pict_max_exp_lc();
+
+		if (copy_to_user((void *)argp,
+				 &cdata, sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_SET_FPS:
+	case CFG_SET_PICT_FPS:
+		rc = mt9p012_set_fps(&(cdata.cfg.fps));
+		break;
+
+	case CFG_SET_EXP_GAIN:
+		rc = mt9p012_write_exp_gain(cdata.cfg.exp_gain.gain,
+					    cdata.cfg.exp_gain.line);
+		break;
+
+	case CFG_SET_PICT_EXP_GAIN:
+		CDBG("Line:%d CFG_SET_PICT_EXP_GAIN \n", __LINE__);
+		rc = mt9p012_set_pict_exp_gain(cdata.cfg.exp_gain.gain,
+					       cdata.cfg.exp_gain.line);
+		break;
+
+	case CFG_SET_MODE:
+		rc = mt9p012_set_sensor_mode(cdata.mode, cdata.rs);
+		break;
+
+	case CFG_PWR_DOWN:
+		rc = mt9p012_power_down();
+		break;
+
+	case CFG_MOVE_FOCUS:
+		CDBG("mt9p012_ioctl: CFG_MOVE_FOCUS: cdata.cfg.focus.dir=%d \
+				cdata.cfg.focus.steps=%d\n",
+				cdata.cfg.focus.dir, cdata.cfg.focus.steps);
+		rc = mt9p012_move_focus(cdata.cfg.focus.dir,
+					cdata.cfg.focus.steps);
+		break;
+
+	case CFG_SET_DEFAULT_FOCUS:
+		rc = mt9p012_set_default_focus();
+		break;
+
+	case CFG_SET_LENS_SHADING:
+		CDBG("%s: CFG_SET_LENS_SHADING\n", __func__);
+		rc = mt9p012_lens_shading_enable(cdata.cfg.lens_shading);
+		break;
+
+	case CFG_GET_AF_MAX_STEPS:
+		cdata.max_steps = MT9P012_STEPS_NEAR_TO_CLOSEST_INF;
+		if (copy_to_user((void *)argp,
+				 &cdata, sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_SET_EFFECT:
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	mutex_unlock(&mt9p012_mut);
+	return rc;
+}
+
+int mt9p012_sensor_release(void)
+{
+	int rc = -EBADF;
+
+	mutex_lock(&mt9p012_mut);
+
+	mt9p012_power_down();
+
+	gpio_direction_output(mt9p012_ctrl->sensordata->sensor_reset, 0);
+	gpio_free(mt9p012_ctrl->sensordata->sensor_reset);
+
+	if (mt9p012_ctrl->sensordata->vcm_enable) {
+		gpio_direction_output(mt9p012_ctrl->sensordata->vcm_pwd, 0);
+		gpio_free(mt9p012_ctrl->sensordata->vcm_pwd);
+	}
+
+	kfree(mt9p012_ctrl);
+	mt9p012_ctrl = NULL;
+
+	CDBG("mt9p012_release completed\n");
+
+	mutex_unlock(&mt9p012_mut);
+	return rc;
+}
+
+static int mt9p012_i2c_probe(struct i2c_client *client,
+			     const struct i2c_device_id *id)
+{
+	int rc = 0;
+	CDBG("mt9p012_probe called!\n");
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		CDBG("i2c_check_functionality failed\n");
+		goto probe_failure;
+	}
+
+	mt9p012_sensorw = kzalloc(sizeof(struct mt9p012_work), GFP_KERNEL);
+	if (!mt9p012_sensorw) {
+		CDBG("kzalloc failed.\n");
+		rc = -ENOMEM;
+		goto probe_failure;
+	}
+
+	i2c_set_clientdata(client, mt9p012_sensorw);
+	mt9p012_init_client(client);
+	mt9p012_client = client;
+
+	mdelay(50);
+
+	CDBG("mt9p012_probe successed! rc = %d\n", rc);
+	return 0;
+
+probe_failure:
+	CDBG("mt9p012_probe failed! rc = %d\n", rc);
+	return rc;
+}
+
+static const struct i2c_device_id mt9p012_i2c_id[] = {
+	{"mt9p012", 0},
+	{}
+};
+
+static struct i2c_driver mt9p012_i2c_driver = {
+	.id_table = mt9p012_i2c_id,
+	.probe = mt9p012_i2c_probe,
+	.remove = __exit_p(mt9p012_i2c_remove),
+	.driver = {
+		   .name = "mt9p012",
+		   },
+};
+
+static int mt9p012_sensor_probe(const struct msm_camera_sensor_info *info,
+				struct msm_sensor_ctrl *s)
+{
+	int rc = i2c_add_driver(&mt9p012_i2c_driver);
+	if (rc < 0 || mt9p012_client == NULL) {
+		rc = -ENOTSUPP;
+		goto probe_done;
+	}
+
+	msm_camio_clk_rate_set(MT9P012_DEFAULT_CLOCK_RATE);
+	mdelay(20);
+
+	rc = mt9p012_probe_init_sensor(info);
+	if (rc < 0)
+		goto probe_done;
+
+	s->s_init = mt9p012_sensor_open_init;
+	s->s_release = mt9p012_sensor_release;
+	s->s_config = mt9p012_sensor_config;
+	s->s_mount_angle  = 0;
+	mt9p012_probe_init_done(info);
+
+probe_done:
+	CDBG("%s %s:%d\n", __FILE__, __func__, __LINE__);
+	return rc;
+}
+
+static int __mt9p012_probe(struct platform_device *pdev)
+{
+	return msm_camera_drv_start(pdev, mt9p012_sensor_probe);
+}
+
+static struct platform_driver msm_camera_driver = {
+	.probe = __mt9p012_probe,
+	.driver = {
+		   .name = "msm_camera_mt9p012",
+		   .owner = THIS_MODULE,
+		   },
+};
+
+static int __init mt9p012_init(void)
+{
+	return platform_driver_register(&msm_camera_driver);
+}
+
+module_init(mt9p012_init);
diff --git a/drivers/media/platform/msm/camera_v1/mt9p012_km.c b/drivers/media/platform/msm/camera_v1/mt9p012_km.c
new file mode 100644
index 0000000..959023b
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mt9p012_km.c
@@ -0,0 +1,1296 @@
+/* Copyright (c) 2009-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/slab.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/kernel.h>
+#include <media/msm_camera.h>
+#include <mach/gpio.h>
+#include <mach/camera.h>
+#include "mt9p012_km.h"
+
+/*=============================================================
+    SENSOR REGISTER DEFINES
+==============================================================*/
+
+#define MT9P012_KM_REG_MODEL_ID      0x0000
+#define MT9P012_KM_MODEL_ID          0x2800
+#define REG_GROUPED_PARAMETER_HOLD   0x0104
+#define GROUPED_PARAMETER_HOLD       0x0100
+#define GROUPED_PARAMETER_UPDATE     0x0000
+#define REG_COARSE_INT_TIME          0x3012
+#define REG_VT_PIX_CLK_DIV           0x0300
+#define REG_VT_SYS_CLK_DIV           0x0302
+#define REG_PRE_PLL_CLK_DIV          0x0304
+#define REG_PLL_MULTIPLIER           0x0306
+#define REG_OP_PIX_CLK_DIV           0x0308
+#define REG_OP_SYS_CLK_DIV           0x030A
+#define REG_SCALE_M                  0x0404
+#define REG_FRAME_LENGTH_LINES       0x300A
+#define REG_LINE_LENGTH_PCK          0x300C
+#define REG_X_ADDR_START             0x3004
+#define REG_Y_ADDR_START             0x3002
+#define REG_X_ADDR_END               0x3008
+#define REG_Y_ADDR_END               0x3006
+#define REG_X_OUTPUT_SIZE            0x034C
+#define REG_Y_OUTPUT_SIZE            0x034E
+#define REG_FINE_INTEGRATION_TIME    0x3014
+#define REG_ROW_SPEED                0x3016
+#define MT9P012_KM_REG_RESET_REGISTER   0x301A
+#define MT9P012_KM_RESET_REGISTER_PWON  0x10CC
+#define MT9P012_KM_RESET_REGISTER_PWOFF 0x10C8
+#define REG_READ_MODE                0x3040
+#define REG_GLOBAL_GAIN              0x305E
+#define REG_TEST_PATTERN_MODE        0x3070
+
+enum mt9p012_km_test_mode {
+	TEST_OFF,
+	TEST_1,
+	TEST_2,
+	TEST_3
+};
+
+enum mt9p012_km_resolution {
+	QTR_SIZE,
+	FULL_SIZE,
+	INVALID_SIZE
+};
+
+enum mt9p012_km_reg_update {
+	/* Sensor egisters that need to be updated during initialization */
+	REG_INIT,
+	/* Sensor egisters that needs periodic I2C writes */
+	UPDATE_PERIODIC,
+	/* All the sensor Registers will be updated */
+	UPDATE_ALL,
+	/* Not valid update */
+	UPDATE_INVALID
+};
+
+enum mt9p012_km_setting {
+	RES_PREVIEW,
+	RES_CAPTURE
+};
+
+uint8_t mode_mask = 0x04;
+
+/* actuator's Slave Address */
+#define MT9P012_KM_AF_I2C_ADDR   (0x18 >> 1)
+
+/* AF Total steps parameters */
+#define MT9P012_KM_STEPS_NEAR_TO_CLOSEST_INF  30
+#define MT9P012_KM_TOTAL_STEPS_NEAR_TO_FAR    30
+
+/* Time in milisecs for waiting for the sensor to reset.*/
+#define MT9P012_KM_RESET_DELAY_MSECS   66
+
+/* for 20 fps preview */
+#define MT9P012_KM_DEFAULT_CLOCK_RATE  24000000
+
+struct mt9p012_km_work {
+	struct work_struct work;
+};
+static struct mt9p012_km_work *mt9p012_km_sensorw;
+static struct i2c_client *mt9p012_km_client;
+
+struct mt9p012_km_ctrl {
+	const struct msm_camera_sensor_info *sensordata;
+
+	int sensormode;
+	uint32_t fps_divider;	/* init to 1 * 0x00000400 */
+	uint32_t pict_fps_divider;	/* init to 1 * 0x00000400 */
+
+	uint16_t curr_lens_pos;
+	uint16_t init_curr_lens_pos;
+	uint16_t my_reg_gain;
+	uint32_t my_reg_line_count;
+
+	enum mt9p012_km_resolution prev_res;
+	enum mt9p012_km_resolution pict_res;
+	enum mt9p012_km_resolution curr_res;
+	enum mt9p012_km_test_mode set_test;
+};
+static uint16_t update_type = UPDATE_PERIODIC;
+static struct mt9p012_km_ctrl *mt9p012_km_ctrl;
+static DECLARE_WAIT_QUEUE_HEAD(mt9p012_km_wait_queue);
+DEFINE_MUTEX(mt9p012_km_mut);
+
+/*=============================================================*/
+
+static int mt9p012_km_i2c_rxdata(unsigned short saddr, unsigned char *rxdata,
+			int length)
+{
+	struct i2c_msg msgs[] = {
+		{
+			.addr = saddr << 1,
+			.flags = 0,
+			.len = 2,
+			.buf = rxdata,
+		},
+		{
+			.addr = saddr << 1,
+			.flags = I2C_M_RD,
+			.len = length,
+			.buf = rxdata,
+		},
+	};
+
+	if (i2c_transfer(mt9p012_km_client->adapter, msgs, 2) < 0) {
+		CDBG("mt9p012_km_i2c_rxdata failed!\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t mt9p012_km_i2c_read_w(unsigned short saddr, unsigned short raddr,
+				  unsigned short *rdata)
+{
+	int32_t rc = 0;
+	unsigned char buf[4];
+
+	if (!rdata)
+		return -EIO;
+
+	memset(buf, 0, sizeof(buf));
+
+	buf[0] = (raddr & 0xFF00) >> 8;
+	buf[1] = (raddr & 0x00FF);
+
+	rc = mt9p012_km_i2c_rxdata(saddr, buf, 2);
+	if (rc < 0)
+		return rc;
+
+	*rdata = buf[0] << 8 | buf[1];
+
+	if (rc < 0)
+		CDBG("mt9p012_km_i2c_read failed!\n");
+
+	return rc;
+}
+
+static int32_t mt9p012_km_i2c_txdata(unsigned short saddr,
+				  unsigned char *txdata,
+				  int length)
+{
+	struct i2c_msg msg[] = {
+		{
+		 .addr = saddr << 1,
+		 .flags = 0,
+		 .len = length,
+		 .buf = txdata,
+		 },
+	};
+
+	if (i2c_transfer(mt9p012_km_client->adapter, msg, 1) < 0) {
+		CDBG("mt9p012_km_i2c_txdata failed\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t mt9p012_km_i2c_write_b(unsigned short saddr,
+				   unsigned short baddr,
+				   unsigned short bdata)
+{
+	int32_t rc = -EIO;
+	unsigned char buf[2];
+
+	memset(buf, 0, sizeof(buf));
+	buf[0] = baddr;
+	buf[1] = bdata;
+	rc = mt9p012_km_i2c_txdata(saddr, buf, 2);
+
+	if (rc < 0)
+		CDBG("i2c_write failed, saddr = 0x%x addr = 0x%x, val =0x%x!\n",
+		     saddr, baddr, bdata);
+
+	return rc;
+}
+
+static int32_t mt9p012_km_i2c_write_w(unsigned short saddr,
+				   unsigned short waddr,
+				   unsigned short wdata)
+{
+	int32_t rc = -EIO;
+	unsigned char buf[4];
+
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00) >> 8;
+	buf[1] = (waddr & 0x00FF);
+	buf[2] = (wdata & 0xFF00) >> 8;
+	buf[3] = (wdata & 0x00FF);
+
+	rc = mt9p012_km_i2c_txdata(saddr, buf, 4);
+
+	if (rc < 0)
+		CDBG("i2c_write_w failed, addr = 0x%x, val = 0x%x!\n",
+		     waddr, wdata);
+
+	return rc;
+}
+
+static int32_t mt9p012_km_i2c_write_w_table(struct mt9p012_km_i2c_reg_conf const
+					 *reg_conf_tbl, int num)
+{
+	int i;
+	int32_t rc = -EIO;
+
+	for (i = 0; i < num; i++) {
+		rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
+					 reg_conf_tbl->waddr,
+					 reg_conf_tbl->wdata);
+		if (rc < 0)
+			break;
+		reg_conf_tbl++;
+	}
+
+	return rc;
+}
+
+static int32_t mt9p012_km_test(enum mt9p012_km_test_mode mo)
+{
+	int32_t rc = 0;
+
+	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
+				 REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_HOLD);
+	if (rc < 0)
+		return rc;
+
+	if (mo == TEST_OFF)
+		return 0;
+	else {
+		rc = mt9p012_km_i2c_write_w_table(mt9p012_km_regs.ttbl,
+					 mt9p012_km_regs.ttbl_size);
+		if (rc < 0)
+			return rc;
+
+		rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
+					 REG_TEST_PATTERN_MODE, (uint16_t) mo);
+		if (rc < 0)
+			return rc;
+	}
+
+	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
+				 REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_UPDATE);
+	if (rc < 0)
+		return rc;
+
+	return rc;
+}
+
+static int32_t mt9p012_km_lens_shading_enable(uint8_t is_enable)
+{
+	int32_t rc = 0;
+
+	CDBG("%s: entered. enable = %d\n", __func__, is_enable);
+
+	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
+				 REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_HOLD);
+	if (rc < 0)
+		return rc;
+
+	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr, 0x3780,
+				 ((uint16_t) is_enable) << 15);
+	if (rc < 0)
+		return rc;
+
+	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
+				 REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_UPDATE);
+
+	CDBG("%s: exiting. rc = %d\n", __func__, rc);
+	return rc;
+}
+
+static int32_t mt9p012_km_set_lc(void)
+{
+	int32_t rc;
+
+	rc = mt9p012_km_i2c_write_w_table(mt9p012_km_regs.lctbl,
+				       mt9p012_km_regs.lctbl_size);
+
+	return rc;
+}
+
+static void mt9p012_km_get_pict_fps(uint16_t fps, uint16_t *pfps)
+{
+
+	/* input fps is preview fps in Q8 format */
+	uint32_t divider;   /*Q10 */
+	uint32_t pclk_mult; /*Q10 */
+	uint32_t d1;
+	uint32_t d2;
+
+	d1 =
+		(uint32_t)(
+		(mt9p012_km_regs.reg_pat[RES_PREVIEW].frame_length_lines *
+		0x00000400) /
+		mt9p012_km_regs.reg_pat[RES_CAPTURE].frame_length_lines);
+
+	d2 =
+		(uint32_t)(
+		(mt9p012_km_regs.reg_pat[RES_PREVIEW].line_length_pck *
+		0x00000400) /
+		mt9p012_km_regs.reg_pat[RES_CAPTURE].line_length_pck);
+
+	divider = (uint32_t) (d1 * d2) / 0x00000400;
+
+	pclk_mult =
+		(uint32_t) ((mt9p012_km_regs.reg_pat[RES_CAPTURE].
+		pll_multiplier * 0x00000400) /
+		(mt9p012_km_regs.reg_pat[RES_PREVIEW].pll_multiplier));
+
+
+	/* Verify PCLK settings and frame sizes. */
+	*pfps = (uint16_t)((((fps * pclk_mult) / 0x00000400) * divider)/
+				0x00000400);
+}
+
+static uint16_t mt9p012_km_get_prev_lines_pf(void)
+{
+	if (mt9p012_km_ctrl->prev_res == QTR_SIZE)
+		return  mt9p012_km_regs.reg_pat[RES_PREVIEW].frame_length_lines;
+	else
+		return  mt9p012_km_regs.reg_pat[RES_CAPTURE].frame_length_lines;
+}
+
+static uint16_t mt9p012_km_get_prev_pixels_pl(void)
+{
+	if (mt9p012_km_ctrl->prev_res == QTR_SIZE)
+		return  mt9p012_km_regs.reg_pat[RES_PREVIEW].line_length_pck;
+	else
+		return  mt9p012_km_regs.reg_pat[RES_CAPTURE].line_length_pck;
+}
+
+static uint16_t mt9p012_km_get_pict_lines_pf(void)
+{
+	return  mt9p012_km_regs.reg_pat[RES_CAPTURE].frame_length_lines;
+}
+
+static uint16_t mt9p012_km_get_pict_pixels_pl(void)
+{
+	return  mt9p012_km_regs.reg_pat[RES_CAPTURE].line_length_pck;
+}
+
+static uint32_t mt9p012_km_get_pict_max_exp_lc(void)
+{
+	uint16_t snapshot_lines_per_frame;
+
+	if (mt9p012_km_ctrl->pict_res == QTR_SIZE)
+		snapshot_lines_per_frame =
+	    mt9p012_km_regs.reg_pat[RES_PREVIEW].frame_length_lines - 1;
+	else
+		snapshot_lines_per_frame =
+	    mt9p012_km_regs.reg_pat[RES_CAPTURE].frame_length_lines - 1;
+
+	return snapshot_lines_per_frame * 24;
+}
+
+static int32_t mt9p012_km_set_fps(struct fps_cfg *fps)
+{
+	int32_t rc = 0;
+
+	mt9p012_km_ctrl->fps_divider = fps->fps_div;
+	mt9p012_km_ctrl->pict_fps_divider = fps->pict_fps_div;
+
+	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
+				 REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_HOLD);
+	if (rc < 0)
+		return -EBUSY;
+
+	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
+			REG_FRAME_LENGTH_LINES,
+			mt9p012_km_regs.reg_pat[mt9p012_km_ctrl->sensormode].
+			frame_length_lines *
+			mt9p012_km_ctrl->fps_divider / 0x00000400);
+	if (rc < 0)
+		return rc;
+
+	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
+				 REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_UPDATE);
+
+	return rc;
+}
+
+
+static int32_t mt9p012_km_write_exp_gain(uint16_t gain, uint32_t line)
+{
+	uint16_t max_legal_gain = 0x01FF;
+	uint32_t line_length_ratio = 0x00000400;
+	enum mt9p012_km_setting setting;
+	int32_t rc = 0;
+
+	CDBG("Line:%d mt9p012_km_write_exp_gain \n", __LINE__);
+
+	if (mt9p012_km_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
+		mt9p012_km_ctrl->my_reg_gain = gain;
+		mt9p012_km_ctrl->my_reg_line_count = (uint16_t) line;
+	}
+
+	if (gain > max_legal_gain) {
+		CDBG("Max legal gain Line:%d \n", __LINE__);
+		gain = max_legal_gain;
+	}
+
+	/* Verify no overflow */
+	if (mt9p012_km_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
+		line = (uint32_t) (line * mt9p012_km_ctrl->fps_divider /
+				   0x00000400);
+		setting = RES_PREVIEW;
+	} else {
+		line = (uint32_t) (line * mt9p012_km_ctrl->pict_fps_divider /
+				   0x00000400);
+		setting = RES_CAPTURE;
+	}
+
+	gain |= 0x0200;
+
+	if ((mt9p012_km_regs.reg_pat[setting].frame_length_lines - 1) < line) {
+		line_length_ratio = (uint32_t) (line * 0x00000400) /
+		    (mt9p012_km_regs.reg_pat[setting].frame_length_lines - 1);
+	} else
+		line_length_ratio = 0x00000400;
+
+	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
+				REG_GROUPED_PARAMETER_HOLD,
+				GROUPED_PARAMETER_HOLD);
+	if (rc < 0) {
+		CDBG("mt9p012_km_i2c_write_w failed... Line:%d \n", __LINE__);
+		return rc;
+	}
+
+	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
+				 REG_GLOBAL_GAIN, gain);
+	if (rc < 0) {
+		CDBG("mt9p012_km_i2c_write_w failed... Line:%d \n", __LINE__);
+		return rc;
+	}
+
+	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
+				REG_LINE_LENGTH_PCK,
+			       (uint16_t) (mt9p012_km_regs.reg_pat[setting].
+			    line_length_pck * line_length_ratio / 0x00000400));
+	if (rc < 0)
+		return rc;
+
+	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
+				 REG_COARSE_INT_TIME,
+				 (uint16_t) ((line * 0x00000400)/
+				 line_length_ratio));
+	if (rc < 0) {
+		CDBG("mt9p012_km_i2c_write_w failed... Line:%d \n", __LINE__);
+		return rc;
+	}
+
+	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
+				 REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_UPDATE);
+	if (rc < 0) {
+		CDBG("mt9p012_km_i2c_write_w failed... Line:%d \n", __LINE__);
+		return rc;
+	}
+
+	CDBG("mt9p012_km_write_exp_gain: gain = %d, line = %d\n", gain, line);
+
+	return rc;
+}
+
+static int32_t mt9p012_km_set_pict_exp_gain(uint16_t gain, uint32_t line)
+{
+	int32_t rc = 0;
+
+	CDBG("Line:%d mt9p012_km_set_pict_exp_gain \n", __LINE__);
+
+	rc = mt9p012_km_write_exp_gain(gain, line);
+	if (rc < 0) {
+		CDBG("Line:%d mt9p012_km_set_pict_exp_gain failed... \n",
+		     __LINE__);
+		return rc;
+	}
+
+	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
+				 MT9P012_KM_REG_RESET_REGISTER,
+				 0x10CC | 0x0002);
+	if (rc < 0) {
+		CDBG("mt9p012_km_i2c_write_w failed... Line:%d \n", __LINE__);
+		return rc;
+	}
+
+	mdelay(5);
+
+	/* camera_timed_wait(snapshot_wait*exposure_ratio); */
+	return rc;
+}
+
+static int32_t mt9p012_km_setting(enum mt9p012_km_reg_update rupdate,
+				enum mt9p012_km_setting rt)
+{
+	int32_t rc = 0;
+
+	switch (rupdate) {
+	case UPDATE_PERIODIC:
+		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
+
+			struct mt9p012_km_i2c_reg_conf ppc_tbl[] = {
+				{REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_HOLD},
+				{REG_ROW_SPEED,
+				 mt9p012_km_regs.reg_pat[rt].row_speed},
+				{REG_X_ADDR_START,
+				 mt9p012_km_regs.reg_pat[rt].x_addr_start},
+				{REG_X_ADDR_END,
+				 mt9p012_km_regs.reg_pat[rt].x_addr_end},
+				{REG_Y_ADDR_START,
+				 mt9p012_km_regs.reg_pat[rt].y_addr_start},
+				{REG_Y_ADDR_END,
+				 mt9p012_km_regs.reg_pat[rt].y_addr_end},
+				{REG_READ_MODE,
+				 mt9p012_km_regs.reg_pat[rt].read_mode},
+				{REG_SCALE_M,
+				 mt9p012_km_regs.reg_pat[rt].scale_m},
+				{REG_X_OUTPUT_SIZE,
+				 mt9p012_km_regs.reg_pat[rt].x_output_size},
+				{REG_Y_OUTPUT_SIZE,
+				 mt9p012_km_regs.reg_pat[rt].y_output_size},
+				{REG_LINE_LENGTH_PCK,
+				 mt9p012_km_regs.reg_pat[rt].line_length_pck},
+				{REG_FRAME_LENGTH_LINES,
+			       (mt9p012_km_regs.reg_pat[rt].frame_length_lines *
+				mt9p012_km_ctrl->fps_divider / 0x00000400)},
+				{REG_COARSE_INT_TIME,
+				 mt9p012_km_regs.reg_pat[rt].coarse_int_time},
+				{REG_FINE_INTEGRATION_TIME,
+				 mt9p012_km_regs.reg_pat[rt].fine_int_time},
+				{REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_UPDATE},
+			};
+
+			if (update_type == REG_INIT) {
+				update_type = rupdate;
+				return rc;
+			}
+
+			rc = mt9p012_km_i2c_write_w_table(&ppc_tbl[0],
+						ARRAY_SIZE(ppc_tbl));
+			if (rc < 0)
+				return rc;
+
+			rc = mt9p012_km_test(mt9p012_km_ctrl->set_test);
+			if (rc < 0)
+				return rc;
+
+			rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
+						 MT9P012_KM_REG_RESET_REGISTER,
+						 0x10cc |
+						 0x0002);
+			if (rc < 0)
+				return rc;
+
+			mdelay(15);	/* 15? wait for sensor to transition */
+
+			return rc;
+		}
+		break;	/* UPDATE_PERIODIC */
+
+	case REG_INIT:
+		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
+			struct mt9p012_km_i2c_reg_conf ipc_tbl1[] = {
+				{MT9P012_KM_REG_RESET_REGISTER,
+				 MT9P012_KM_RESET_REGISTER_PWOFF},
+				{REG_VT_PIX_CLK_DIV,
+				 mt9p012_km_regs.reg_pat[rt].vt_pix_clk_div},
+				{REG_VT_SYS_CLK_DIV,
+				 mt9p012_km_regs.reg_pat[rt].vt_sys_clk_div},
+				{REG_PRE_PLL_CLK_DIV,
+				 mt9p012_km_regs.reg_pat[rt].pre_pll_clk_div},
+				{REG_PLL_MULTIPLIER,
+				 mt9p012_km_regs.reg_pat[rt].pll_multiplier},
+				{REG_OP_PIX_CLK_DIV,
+				 mt9p012_km_regs.reg_pat[rt].op_pix_clk_div},
+				{REG_OP_SYS_CLK_DIV,
+				 mt9p012_km_regs.reg_pat[rt].op_sys_clk_div},
+				{MT9P012_KM_REG_RESET_REGISTER,
+				 MT9P012_KM_RESET_REGISTER_PWON},
+			};
+
+			struct mt9p012_km_i2c_reg_conf ipc_tbl2[] = {
+				{REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_HOLD},
+				/* Optimized register settings for
+				   Rev3 Silicon */
+				{0x308A, 0x6424},
+				{0x3092, 0x0A52},
+				{0x3094, 0x4656},
+				{0x3096, 0x5652},
+				{0x0204, 0x0010},
+				{0x0206, 0x0010},
+				{0x0208, 0x0010},
+				{0x020A, 0x0010},
+				{0x020C, 0x0010},
+				{0x3088, 0x6FF6},
+				{0x3154, 0x0282},
+				{0x3156, 0x0381},
+				{0x3162, 0x04CE},
+			};
+
+			struct mt9p012_km_i2c_reg_conf ipc_tbl3[] = {
+				/* Set preview or snapshot mode */
+				{REG_ROW_SPEED,
+				 mt9p012_km_regs.reg_pat[rt].row_speed},
+				{REG_X_ADDR_START,
+				 mt9p012_km_regs.reg_pat[rt].x_addr_start},
+				{REG_X_ADDR_END,
+				 mt9p012_km_regs.reg_pat[rt].x_addr_end},
+				{REG_Y_ADDR_START,
+				 mt9p012_km_regs.reg_pat[rt].y_addr_start},
+				{REG_Y_ADDR_END,
+				 mt9p012_km_regs.reg_pat[rt].y_addr_end},
+				{REG_READ_MODE,
+				 mt9p012_km_regs.reg_pat[rt].read_mode},
+				{REG_SCALE_M,
+				 mt9p012_km_regs.reg_pat[rt].scale_m},
+				{REG_X_OUTPUT_SIZE,
+				 mt9p012_km_regs.reg_pat[rt].x_output_size},
+				{REG_Y_OUTPUT_SIZE,
+				 mt9p012_km_regs.reg_pat[rt].y_output_size},
+				{REG_LINE_LENGTH_PCK,
+				 mt9p012_km_regs.reg_pat[rt].line_length_pck},
+				{REG_FRAME_LENGTH_LINES,
+				 mt9p012_km_regs.reg_pat[rt].
+				 frame_length_lines},
+				{REG_COARSE_INT_TIME,
+				 mt9p012_km_regs.reg_pat[rt].coarse_int_time},
+				{REG_FINE_INTEGRATION_TIME,
+				 mt9p012_km_regs.reg_pat[rt].fine_int_time},
+				{REG_GROUPED_PARAMETER_HOLD,
+				 GROUPED_PARAMETER_UPDATE},
+			};
+
+			/* reset fps_divider */
+			mt9p012_km_ctrl->fps_divider = 1 * 0x0400;
+
+			rc = mt9p012_km_i2c_write_w_table(&ipc_tbl1[0],
+							ARRAY_SIZE(ipc_tbl1));
+			if (rc < 0)
+				return rc;
+
+			mdelay(15);
+
+			rc = mt9p012_km_i2c_write_w_table(&ipc_tbl2[0],
+							ARRAY_SIZE(ipc_tbl2));
+			if (rc < 0)
+				return rc;
+
+			mdelay(5);
+
+			rc = mt9p012_km_i2c_write_w_table(&ipc_tbl3[0],
+						       ARRAY_SIZE(ipc_tbl3));
+			if (rc < 0)
+				return rc;
+
+			/* load lens shading */
+			rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
+						 REG_GROUPED_PARAMETER_HOLD,
+						 GROUPED_PARAMETER_HOLD);
+			if (rc < 0)
+				return rc;
+
+			rc = mt9p012_km_set_lc();
+			if (rc < 0)
+				return rc;
+
+			rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
+						 REG_GROUPED_PARAMETER_HOLD,
+						 GROUPED_PARAMETER_UPDATE);
+
+			if (rc < 0)
+				return rc;
+		}
+		update_type = rupdate;
+		break;		/* case REG_INIT: */
+
+	default:
+		rc = -EINVAL;
+		break;
+	}			/* switch (rupdate) */
+
+	return rc;
+}
+
+static int32_t mt9p012_km_video_config(int mode, int res)
+{
+	int32_t rc;
+
+	switch (res) {
+	case QTR_SIZE:
+		rc = mt9p012_km_setting(UPDATE_PERIODIC, RES_PREVIEW);
+		if (rc < 0)
+			return rc;
+
+		CDBG("mt9p012_km sensor configuration done!\n");
+		break;
+
+	case FULL_SIZE:
+		rc = mt9p012_km_setting(UPDATE_PERIODIC, RES_CAPTURE);
+		if (rc < 0)
+			return rc;
+
+		break;
+
+	default:
+		return 0;
+	}			/* switch */
+
+	mt9p012_km_ctrl->prev_res = res;
+	mt9p012_km_ctrl->curr_res = res;
+	mt9p012_km_ctrl->sensormode = mode;
+
+	rc = mt9p012_km_write_exp_gain(mt9p012_km_ctrl->my_reg_gain,
+				    mt9p012_km_ctrl->my_reg_line_count);
+
+	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
+				 MT9P012_KM_REG_RESET_REGISTER,
+				 0x10cc | 0x0002);
+
+	mdelay(15);
+	return rc;
+}
+
+static int32_t mt9p012_km_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+
+	rc = mt9p012_km_setting(UPDATE_PERIODIC, RES_CAPTURE);
+	if (rc < 0)
+		return rc;
+
+	mt9p012_km_ctrl->curr_res = mt9p012_km_ctrl->pict_res;
+
+	mt9p012_km_ctrl->sensormode = mode;
+
+	return rc;
+}
+
+static int32_t mt9p012_km_raw_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+
+	rc = mt9p012_km_setting(UPDATE_PERIODIC, RES_CAPTURE);
+	if (rc < 0)
+		return rc;
+
+	mt9p012_km_ctrl->curr_res = mt9p012_km_ctrl->pict_res;
+
+	mt9p012_km_ctrl->sensormode = mode;
+
+	return rc;
+}
+
+static int32_t mt9p012_km_power_down(void)
+{
+	int32_t rc = 0;
+
+	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
+				 MT9P012_KM_REG_RESET_REGISTER,
+				 MT9P012_KM_RESET_REGISTER_PWOFF);
+
+	mdelay(5);
+	return rc;
+}
+
+static int32_t mt9p012_km_move_focus(int direction, int32_t num_steps)
+{
+	int16_t step_direction;
+	int16_t actual_step;
+	int16_t next_position;
+	uint8_t code_val_msb, code_val_lsb;
+
+	if (num_steps > MT9P012_KM_TOTAL_STEPS_NEAR_TO_FAR)
+		num_steps = MT9P012_KM_TOTAL_STEPS_NEAR_TO_FAR;
+	else if (num_steps == 0) {
+		CDBG("mt9p012_km_move_focus failed at line %d ...\n", __LINE__);
+		return -EINVAL;
+	}
+
+	if (direction == MOVE_NEAR)
+		step_direction = 16;	/* 10bit */
+	else if (direction == MOVE_FAR)
+		step_direction = -16;	/* 10 bit */
+	else {
+		CDBG("mt9p012_km_move_focus failed at line %d ...\n", __LINE__);
+		return -EINVAL;
+	}
+
+	if (mt9p012_km_ctrl->curr_lens_pos <
+				mt9p012_km_ctrl->init_curr_lens_pos)
+		mt9p012_km_ctrl->curr_lens_pos =
+				mt9p012_km_ctrl->init_curr_lens_pos;
+
+	actual_step = (int16_t) (step_direction * (int16_t) num_steps);
+	next_position = (int16_t) (mt9p012_km_ctrl->curr_lens_pos +
+							actual_step);
+
+	if (next_position > 1023)
+		next_position = 1023;
+	else if (next_position < 0)
+		next_position = 0;
+
+	code_val_msb = next_position >> 4;
+	code_val_lsb = (next_position & 0x000F) << 4;
+	code_val_lsb |= mode_mask;
+
+	/* Writing the digital code for current to the actuator */
+	if (mt9p012_km_i2c_write_b(MT9P012_KM_AF_I2C_ADDR >> 1,
+				code_val_msb, code_val_lsb) < 0) {
+		CDBG("mt9p012_km_move_focus failed at line %d ...\n", __LINE__);
+		return -EBUSY;
+	}
+
+	/* Storing the current lens Position */
+	mt9p012_km_ctrl->curr_lens_pos = next_position;
+
+	return 0;
+}
+
+static int32_t mt9p012_km_set_default_focus(void)
+{
+	int32_t rc = 0;
+	uint8_t code_val_msb, code_val_lsb;
+
+	code_val_msb = 0x00;
+	code_val_lsb = 0x04;
+
+	/* Write the digital code for current to the actuator */
+	rc = mt9p012_km_i2c_write_b(MT9P012_KM_AF_I2C_ADDR >> 1,
+				 code_val_msb, code_val_lsb);
+
+	mt9p012_km_ctrl->curr_lens_pos = 0;
+	mt9p012_km_ctrl->init_curr_lens_pos = 0;
+
+	return rc;
+}
+
+static int mt9p012_km_probe_init_done(const struct msm_camera_sensor_info *data)
+{
+	gpio_direction_output(data->sensor_reset, 0);
+	gpio_free(data->sensor_reset);
+	return 0;
+}
+
+static int
+	mt9p012_km_probe_init_sensor(const struct msm_camera_sensor_info *data)
+{
+	int32_t rc;
+	uint16_t chipid;
+
+	rc = gpio_request(data->sensor_reset, "mt9p012_km");
+	if (!rc)
+		gpio_direction_output(data->sensor_reset, 1);
+	else
+		goto init_probe_done;
+
+	msleep(20);
+
+	/* RESET the sensor image part via I2C command */
+	CDBG("mt9p012_km_sensor_init(): reseting sensor.\n");
+	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
+				 MT9P012_KM_REG_RESET_REGISTER,
+				 0x10CC | 0x0001);
+	if (rc < 0) {
+		CDBG("sensor reset failed. rc = %d\n", rc);
+		goto init_probe_fail;
+	}
+
+		msleep(MT9P012_KM_RESET_DELAY_MSECS);
+
+	/* 3. Read sensor Model ID: */
+	rc = mt9p012_km_i2c_read_w(mt9p012_km_client->addr,
+				MT9P012_KM_REG_MODEL_ID, &chipid);
+	if (rc < 0)
+		goto init_probe_fail;
+
+	/* 4. Compare sensor ID to MT9T012VC ID: */
+	if (chipid != MT9P012_KM_MODEL_ID) {
+		CDBG("mt9p012_km wrong model_id = 0x%x\n", chipid);
+		rc = -ENODEV;
+		goto init_probe_fail;
+	}
+
+	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr, 0x306E, 0x9080);
+	if (rc < 0) {
+		CDBG("REV_7 write failed. rc = %d\n", rc);
+		goto init_probe_fail;
+	}
+
+	/* RESET_REGISTER, enable parallel interface and disable serialiser */
+	CDBG("mt9p012_km_sensor_init(): enabling parallel interface.\n");
+	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr, 0x301A, 0x10CC);
+	if (rc < 0) {
+		CDBG("enable parallel interface failed. rc = %d\n", rc);
+		goto init_probe_fail;
+	}
+
+	/* To disable the 2 extra lines */
+	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr, 0x3064, 0x0805);
+
+	if (rc < 0) {
+		CDBG("disable the 2 extra lines failed. rc = %d\n", rc);
+		goto init_probe_fail;
+	}
+
+	goto init_probe_done;
+
+init_probe_fail:
+	mt9p012_km_probe_init_done(data);
+init_probe_done:
+	return rc;
+}
+
+static int
+	mt9p012_km_sensor_open_init(const struct msm_camera_sensor_info *data)
+{
+	int32_t rc;
+
+	mt9p012_km_ctrl = kzalloc(sizeof(struct mt9p012_km_ctrl), GFP_KERNEL);
+	if (!mt9p012_km_ctrl) {
+		CDBG("mt9p012_km_init failed!\n");
+		rc = -ENOMEM;
+		goto init_done;
+	}
+
+	mt9p012_km_ctrl->fps_divider = 1 * 0x00000400;
+	mt9p012_km_ctrl->pict_fps_divider = 1 * 0x00000400;
+	mt9p012_km_ctrl->set_test = TEST_OFF;
+	mt9p012_km_ctrl->prev_res = QTR_SIZE;
+	mt9p012_km_ctrl->pict_res = FULL_SIZE;
+
+	if (data)
+		mt9p012_km_ctrl->sensordata = data;
+
+	msm_camio_camif_pad_reg_reset();
+	mdelay(20);
+
+	rc = mt9p012_km_probe_init_sensor(data);
+	if (rc < 0)
+		goto init_fail1;
+
+	if (mt9p012_km_ctrl->prev_res == QTR_SIZE)
+		rc = mt9p012_km_setting(REG_INIT, RES_PREVIEW);
+	else
+		rc = mt9p012_km_setting(REG_INIT, RES_CAPTURE);
+
+	if (rc < 0) {
+		CDBG("mt9p012_km_setting failed. rc = %d\n", rc);
+		goto init_fail1;
+	}
+
+	/* sensor : output enable */
+	CDBG("mt9p012_km_sensor_open_init(): enabling output.\n");
+	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
+				 MT9P012_KM_REG_RESET_REGISTER,
+				 MT9P012_KM_RESET_REGISTER_PWON);
+	if (rc < 0) {
+		CDBG("sensor output enable failed. rc = %d\n", rc);
+		goto init_fail1;
+	}
+
+	if (rc >= 0)
+		goto init_done;
+
+init_fail1:
+	mt9p012_km_probe_init_done(data);
+	kfree(mt9p012_km_ctrl);
+init_done:
+	return rc;
+}
+
+static int mt9p012_km_init_client(struct i2c_client *client)
+{
+	/* Initialize the MSM_CAMI2C Chip */
+	init_waitqueue_head(&mt9p012_km_wait_queue);
+	return 0;
+}
+
+static int32_t mt9p012_km_set_sensor_mode(int mode, int res)
+{
+	int32_t rc = 0;
+
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		rc = mt9p012_km_video_config(mode, res);
+		break;
+
+	case SENSOR_SNAPSHOT_MODE:
+		rc = mt9p012_km_snapshot_config(mode);
+		break;
+
+	case SENSOR_RAW_SNAPSHOT_MODE:
+		rc = mt9p012_km_raw_snapshot_config(mode);
+		break;
+
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
+int mt9p012_km_sensor_config(void __user *argp)
+{
+	struct sensor_cfg_data cdata;
+	int rc = 0;
+
+	if (copy_from_user(&cdata,
+			   (void *)argp, sizeof(struct sensor_cfg_data)))
+		return -EFAULT;
+
+	mutex_lock(&mt9p012_km_mut);
+
+	CDBG("%s: cfgtype = %d\n", __func__, cdata.cfgtype);
+	switch (cdata.cfgtype) {
+	case CFG_GET_PICT_FPS:
+		mt9p012_km_get_pict_fps(cdata.cfg.gfps.prevfps,
+				     &(cdata.cfg.gfps.pictfps));
+
+		if (copy_to_user((void *)argp, &cdata,
+				 sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PREV_L_PF:
+		cdata.cfg.prevl_pf = mt9p012_km_get_prev_lines_pf();
+
+		if (copy_to_user((void *)argp,
+				 &cdata, sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PREV_P_PL:
+		cdata.cfg.prevp_pl = mt9p012_km_get_prev_pixels_pl();
+
+		if (copy_to_user((void *)argp,
+				 &cdata, sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_L_PF:
+		cdata.cfg.pictl_pf = mt9p012_km_get_pict_lines_pf();
+
+		if (copy_to_user((void *)argp,
+				 &cdata, sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_P_PL:
+		cdata.cfg.pictp_pl = mt9p012_km_get_pict_pixels_pl();
+
+		if (copy_to_user((void *)argp,
+				 &cdata, sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_MAX_EXP_LC:
+		cdata.cfg.pict_max_exp_lc = mt9p012_km_get_pict_max_exp_lc();
+
+		if (copy_to_user((void *)argp,
+				 &cdata, sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_SET_FPS:
+	case CFG_SET_PICT_FPS:
+		rc = mt9p012_km_set_fps(&(cdata.cfg.fps));
+		break;
+
+	case CFG_SET_EXP_GAIN:
+		rc = mt9p012_km_write_exp_gain(cdata.cfg.exp_gain.gain,
+					    cdata.cfg.exp_gain.line);
+		break;
+
+	case CFG_SET_PICT_EXP_GAIN:
+		CDBG("Line:%d CFG_SET_PICT_EXP_GAIN \n", __LINE__);
+		rc = mt9p012_km_set_pict_exp_gain(cdata.cfg.exp_gain.gain,
+					       cdata.cfg.exp_gain.line);
+		break;
+
+	case CFG_SET_MODE:
+		rc = mt9p012_km_set_sensor_mode(cdata.mode, cdata.rs);
+		break;
+
+	case CFG_PWR_DOWN:
+		rc = mt9p012_km_power_down();
+		break;
+
+	case CFG_MOVE_FOCUS:
+		CDBG("mt9p012_km_ioctl: CFG_MOVE_FOCUS: cdata.cfg.focus.dir=%d \
+				cdata.cfg.focus.steps=%d\n",
+				cdata.cfg.focus.dir, cdata.cfg.focus.steps);
+		rc = mt9p012_km_move_focus(cdata.cfg.focus.dir,
+					cdata.cfg.focus.steps);
+		break;
+
+	case CFG_SET_DEFAULT_FOCUS:
+		rc = mt9p012_km_set_default_focus();
+		break;
+
+	case CFG_SET_LENS_SHADING:
+		CDBG("%s: CFG_SET_LENS_SHADING\n", __func__);
+		rc = mt9p012_km_lens_shading_enable(cdata.cfg.lens_shading);
+		break;
+
+	case CFG_GET_AF_MAX_STEPS:
+		cdata.max_steps = MT9P012_KM_STEPS_NEAR_TO_CLOSEST_INF;
+		if (copy_to_user((void *)argp,
+				 &cdata, sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_SET_EFFECT:
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	mutex_unlock(&mt9p012_km_mut);
+	return rc;
+}
+
+int mt9p012_km_sensor_release(void)
+{
+	int rc = -EBADF;
+
+	mutex_lock(&mt9p012_km_mut);
+
+	mt9p012_km_power_down();
+
+	gpio_direction_output(mt9p012_km_ctrl->sensordata->sensor_reset, 0);
+	gpio_free(mt9p012_km_ctrl->sensordata->sensor_reset);
+
+	gpio_direction_output(mt9p012_km_ctrl->sensordata->vcm_pwd, 0);
+	gpio_free(mt9p012_km_ctrl->sensordata->vcm_pwd);
+
+	kfree(mt9p012_km_ctrl);
+	mt9p012_km_ctrl = NULL;
+
+	CDBG("mt9p012_km_release completed\n");
+
+	mutex_unlock(&mt9p012_km_mut);
+	return rc;
+}
+
+static int mt9p012_km_i2c_probe(struct i2c_client *client,
+			     const struct i2c_device_id *id)
+{
+	int rc = 0;
+	CDBG("mt9p012_km_probe called!\n");
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		CDBG("i2c_check_functionality failed\n");
+		goto probe_failure;
+	}
+
+	mt9p012_km_sensorw = kzalloc(sizeof(struct mt9p012_km_work),
+							GFP_KERNEL);
+	if (!mt9p012_km_sensorw) {
+		CDBG("kzalloc failed.\n");
+		rc = -ENOMEM;
+		goto probe_failure;
+	}
+
+	i2c_set_clientdata(client, mt9p012_km_sensorw);
+	mt9p012_km_init_client(client);
+	mt9p012_km_client = client;
+
+	mdelay(50);
+
+	CDBG("mt9p012_km_probe successed! rc = %d\n", rc);
+	return 0;
+
+probe_failure:
+	CDBG("mt9p012_km_probe failed! rc = %d\n", rc);
+	return rc;
+}
+
+static const struct i2c_device_id mt9p012_km_i2c_id[] = {
+	{"mt9p012_km", 0},
+	{}
+};
+
+static struct i2c_driver mt9p012_km_i2c_driver = {
+	.id_table = mt9p012_km_i2c_id,
+	.probe = mt9p012_km_i2c_probe,
+	.remove = __exit_p(mt9p012_km_i2c_remove),
+	.driver = {
+		   .name = "mt9p012_km",
+		   },
+};
+
+static int mt9p012_km_sensor_probe(const struct msm_camera_sensor_info *info,
+				struct msm_sensor_ctrl *s)
+{
+	int rc = i2c_add_driver(&mt9p012_km_i2c_driver);
+	if (rc < 0 || mt9p012_km_client == NULL) {
+		rc = -ENOTSUPP;
+		goto probe_done;
+	}
+
+	msm_camio_clk_rate_set(MT9P012_KM_DEFAULT_CLOCK_RATE);
+	mdelay(20);
+
+	rc = mt9p012_km_probe_init_sensor(info);
+	if (rc < 0)
+		goto probe_done;
+
+	s->s_init = mt9p012_km_sensor_open_init;
+	s->s_release = mt9p012_km_sensor_release;
+	s->s_config = mt9p012_km_sensor_config;
+	s->s_mount_angle  = 0;
+	mt9p012_km_probe_init_done(info);
+
+probe_done:
+	CDBG("%s %s:%d\n", __FILE__, __func__, __LINE__);
+	return rc;
+}
+
+static int __mt9p012_km_probe(struct platform_device *pdev)
+{
+	return msm_camera_drv_start(pdev, mt9p012_km_sensor_probe);
+}
+
+static struct platform_driver msm_camera_driver = {
+	.probe = __mt9p012_km_probe,
+	.driver = {
+		   .name = "msm_camera_mt9p012_km",
+		   .owner = THIS_MODULE,
+		   },
+};
+
+static int __init mt9p012_km_init(void)
+{
+	return platform_driver_register(&msm_camera_driver);
+}
+
+module_init(mt9p012_km_init);
diff --git a/drivers/media/platform/msm/camera_v1/mt9p012_km.h b/drivers/media/platform/msm/camera_v1/mt9p012_km.h
new file mode 100644
index 0000000..d386474
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mt9p012_km.h
@@ -0,0 +1,62 @@
+/* Copyright (c) 2009-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.
+ *
+ */
+
+#ifndef MT9P012_KM_H
+#define MT9P012_KM_H
+
+#include <linux/types.h>
+#include <mach/board.h>
+
+extern struct mt9p012_km_reg mt9p012_km_regs;	/* from mt9p012_km_reg.c */
+
+struct reg_struct {
+	uint16_t vt_pix_clk_div;     /* 0x0300 */
+	uint16_t vt_sys_clk_div;     /* 0x0302 */
+	uint16_t pre_pll_clk_div;    /* 0x0304 */
+	uint16_t pll_multiplier;     /* 0x0306 */
+	uint16_t op_pix_clk_div;     /* 0x0308 */
+	uint16_t op_sys_clk_div;     /* 0x030A */
+	uint16_t scale_m;            /* 0x0404 */
+	uint16_t row_speed;          /* 0x3016 */
+	uint16_t x_addr_start;       /* 0x3004 */
+	uint16_t x_addr_end;         /* 0x3008 */
+	uint16_t y_addr_start;       /* 0x3002 */
+	uint16_t y_addr_end;         /* 0x3006 */
+	uint16_t read_mode;          /* 0x3040 */
+	uint16_t x_output_size ;     /* 0x034C */
+	uint16_t y_output_size;      /* 0x034E */
+	uint16_t line_length_pck;    /* 0x300C */
+	uint16_t frame_length_lines; /* 0x300A */
+	uint16_t coarse_int_time;    /* 0x3012 */
+	uint16_t fine_int_time;      /* 0x3014 */
+};
+
+
+struct mt9p012_km_i2c_reg_conf {
+	unsigned short waddr;
+	unsigned short wdata;
+};
+
+
+struct mt9p012_km_reg {
+	struct reg_struct const *reg_pat;
+	uint16_t reg_pat_size;
+	struct mt9p012_km_i2c_reg_conf const *ttbl;
+	uint16_t ttbl_size;
+	struct mt9p012_km_i2c_reg_conf const *lctbl;
+	uint16_t lctbl_size;
+	struct mt9p012_km_i2c_reg_conf const *rftbl;
+	uint16_t rftbl_size;
+};
+
+#endif /* MT9P012_KM_H */
diff --git a/drivers/media/platform/msm/camera_v1/mt9p012_km_reg.c b/drivers/media/platform/msm/camera_v1/mt9p012_km_reg.c
new file mode 100644
index 0000000..5c6318f
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mt9p012_km_reg.c
@@ -0,0 +1,375 @@
+/* Copyright (c) 2009-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 "mt9p012_km.h"
+#include <linux/kernel.h>
+
+/*Micron settings from Applications for lower power consumption.*/
+struct reg_struct const mt9p012_km_reg_pat[2] = {
+	{ /* Preview */
+		/* vt_pix_clk_div          REG=0x0300 */
+		6,  /* 5 */
+
+		/* vt_sys_clk_div          REG=0x0302 */
+		1,
+
+		/* pre_pll_clk_div         REG=0x0304 */
+		2,
+
+		/* pll_multiplier          REG=0x0306 */
+		60,
+
+		/* op_pix_clk_div          REG=0x0308 */
+		8,  /* 10 */
+
+		/* op_sys_clk_div          REG=0x030A */
+		1,
+
+		/* scale_m                 REG=0x0404 */
+		16,
+
+		/* row_speed               REG=0x3016 */
+		0x0111,
+
+		/* x_addr_start            REG=0x3004 */
+		8,
+
+		/* x_addr_end              REG=0x3008 */
+		2597,
+
+		/* y_addr_start            REG=0x3002 */
+		8,
+
+		/* y_addr_end              REG=0x3006 */
+		1949,
+
+		/* read_mode               REG=0x3040
+		 * Preview 2x2 skipping */
+		0x006C,
+
+		/* x_output_size           REG=0x034C */
+		1296,
+
+		/* y_output_size           REG=0x034E */
+		972,
+
+		/* line_length_pck         REG=0x300C */
+		3783,
+
+		/* frame_length_lines      REG=0x300A */
+		1074,
+
+		/* coarse_integration_time REG=0x3012 */
+		16,
+
+		/* fine_integration_time   REG=0x3014 */
+		1764
+	},
+	{ /* Snapshot */
+		/* vt_pix_clk_div          REG=0x0300 */
+		6,
+
+		/* vt_sys_clk_div          REG=0x0302 */
+		1,
+
+		/* pre_pll_clk_div         REG=0x0304 */
+		2,
+
+		/* pll_multiplier          REG=0x0306
+		 * 39 for 10fps snapshot */
+		39,
+
+		/* op_pix_clk_div          REG=0x0308 */
+		8,
+
+		/* op_sys_clk_div          REG=0x030A */
+		1,
+
+		/* scale_m                 REG=0x0404 */
+		16,
+
+		/* row_speed               REG=0x3016 */
+		0x0111,
+
+		/* x_addr_start            REG=0x3004 */
+		8,
+
+		/* x_addr_end              REG=0x3008 */
+		2615,
+
+		/* y_addr_start            REG=0x3002 */
+		8,
+
+		/* y_addr_end              REG=0x3006 */
+		1967,
+
+		/* read_mode               REG=0x3040 */
+		0x0024,
+
+		/* x_output_size           REG=0x034C */
+		2608,
+
+		/* y_output_size           REG=0x034E */
+		1960,
+
+		/* line_length_pck         REG=0x300C */
+		3788,
+
+		/* frame_length_lines      REG=0x300A 10 fps snapshot */
+		2045,
+
+		/* coarse_integration_time REG=0x3012 */
+		16,
+
+		/* fine_integration_time   REG=0x3014 */
+		882
+	}
+};
+
+struct mt9p012_km_i2c_reg_conf const mt9p012_km_test_tbl[] = {
+	{0x3044, 0x0544 & 0xFBFF},
+	{0x30CA, 0x0004 | 0x0001},
+	{0x30D4, 0x9020 & 0x7FFF},
+	{0x31E0, 0x0003 & 0xFFFE},
+	{0x3180, 0x91FF & 0x7FFF},
+	{0x301A, (0x10CC | 0x8000) & 0xFFF7},
+	{0x301E, 0x0000},
+	{0x3780, 0x0000},
+};
+
+
+struct mt9p012_km_i2c_reg_conf const mt9p012_km_lc_tbl[] = {
+	{0x360A, 0x00F0},
+	{0x360C, 0x0B29},
+	{0x360E, 0x5ED1},
+	{0x3610, 0x890D},
+	{0x3612, 0x9871},
+	{0x364A, 0xAD2C},
+	{0x364C, 0x0A8C},
+	{0x364E, 0x91EC},
+	{0x3650, 0x94EC},
+	{0x3652, 0xC76B},
+	{0x368A, 0x5931},
+	{0x368C, 0x4FED},
+	{0x368E, 0x8A50},
+	{0x3690, 0x5C0F},
+	{0x3692, 0x8393},
+	{0x36CA, 0xDB8E},
+	{0x36CC, 0xCA4D},
+	{0x36CE, 0x146F},
+	{0x36D0, 0x618F},
+	{0x36D2, 0x014F},
+	{0x370A, 0x1FEE},
+	{0x370C, 0xDD50},
+	{0x370E, 0xDB54},
+	{0x3710, 0xCA92},
+	{0x3712, 0x1896},
+	{0x3600, 0x00F0},
+	{0x3602, 0xA04C},
+	{0x3604, 0x5711},
+	{0x3606, 0x5E6D},
+	{0x3608, 0xA971},
+	{0x3640, 0xDCCC},
+	{0x3642, 0x0529},
+	{0x3644, 0x96ED},
+	{0x3646, 0xF447},
+	{0x3648, 0x4AEE},
+	{0x3680, 0x2171},
+	{0x3682, 0x634F},
+	{0x3684, 0xCC91},
+	{0x3686, 0xA9CE},
+	{0x3688, 0x8751},
+	{0x36C0, 0x8B6D},
+	{0x36C2, 0xE20E},
+	{0x36C4, 0x750F},
+	{0x36C6, 0x0090},
+	{0x36C8, 0x9E91},
+	{0x3700, 0xEAAF},
+	{0x3702, 0xB8AF},
+	{0x3704, 0xE293},
+	{0x3706, 0xAB33},
+	{0x3708, 0x4595},
+	{0x3614, 0x00D0},
+	{0x3616, 0x8AAB},
+	{0x3618, 0x18B1},
+	{0x361A, 0x54AD},
+	{0x361C, 0x9DB0},
+	{0x3654, 0x11EB},
+	{0x3656, 0x332C},
+	{0x3658, 0x316D},
+	{0x365A, 0xF0EB},
+	{0x365C, 0xB4ED},
+	{0x3694, 0x0F31},
+	{0x3696, 0x08D0},
+	{0x3698, 0xA52F},
+	{0x369A, 0xE64F},
+	{0x369C, 0xC9D2},
+	{0x36D4, 0x8C2D},
+	{0x36D6, 0xAD6E},
+	{0x36D8, 0xE1CE},
+	{0x36DA, 0x1750},
+	{0x36DC, 0x8CAD},
+	{0x3714, 0x8CAF},
+	{0x3716, 0x8C11},
+	{0x3718, 0xE453},
+	{0x371A, 0x9693},
+	{0x371C, 0x38B5},
+	{0x361E, 0x00D0},
+	{0x3620, 0xB6CB},
+	{0x3622, 0x4811},
+	{0x3624, 0xB70C},
+	{0x3626, 0xA771},
+	{0x365E, 0xB5A9},
+	{0x3660, 0x05AA},
+	{0x3662, 0x00CF},
+	{0x3664, 0xB86B},
+	{0x3666, 0xA4AF},
+	{0x369E, 0x3E31},
+	{0x36A0, 0x902B},
+	{0x36A2, 0xD251},
+	{0x36A4, 0x5C2F},
+	{0x36A6, 0x8471},
+	{0x36DE, 0x2C6D},
+	{0x36E0, 0xECEE},
+	{0x36E2, 0xB650},
+	{0x36E4, 0x0210},
+	{0x36E6, 0xACAE},
+	{0x371E, 0xAC30},
+	{0x3720, 0x394E},
+	{0x3722, 0xFDD3},
+	{0x3724, 0xBCB2},
+	{0x3726, 0x5AD5},
+	{0x3782, 0x0508},
+	{0x3784, 0x03B4},
+	{0x3780, 0x8000},
+};
+
+struct mt9p012_km_i2c_reg_conf const mt9p012_km_rolloff_tbl[] = {
+	{0x360A, 0x00F0},
+	{0x360C, 0x0B29},
+	{0x360E, 0x5ED1},
+	{0x3610, 0x890D},
+	{0x3612, 0x9871},
+	{0x364A, 0xAD2C},
+	{0x364C, 0x0A8C},
+	{0x364E, 0x91EC},
+	{0x3650, 0x94EC},
+	{0x3652, 0xC76B},
+	{0x368A, 0x5931},
+	{0x368C, 0x4FED},
+	{0x368E, 0x8A50},
+	{0x3690, 0x5C0F},
+	{0x3692, 0x8393},
+	{0x36CA, 0xDB8E},
+	{0x36CC, 0xCA4D},
+	{0x36CE, 0x146F},
+	{0x36D0, 0x618F},
+	{0x36D2, 0x014F},
+	{0x370A, 0x1FEE},
+	{0x370C, 0xDD50},
+	{0x370E, 0xDB54},
+	{0x3710, 0xCA92},
+	{0x3712, 0x1896},
+	{0x3600, 0x00F0},
+	{0x3602, 0xA04C},
+	{0x3604, 0x5711},
+	{0x3606, 0x5E6D},
+	{0x3608, 0xA971},
+	{0x3640, 0xDCCC},
+	{0x3642, 0x0529},
+	{0x3644, 0x96ED},
+	{0x3646, 0xF447},
+	{0x3648, 0x4AEE},
+	{0x3680, 0x2171},
+	{0x3682, 0x634F},
+	{0x3684, 0xCC91},
+	{0x3686, 0xA9CE},
+	{0x3688, 0x8751},
+	{0x36C0, 0x8B6D},
+	{0x36C2, 0xE20E},
+	{0x36C4, 0x750F},
+	{0x36C6, 0x0090},
+	{0x36C8, 0x9E91},
+	{0x3700, 0xEAAF},
+	{0x3702, 0xB8AF},
+	{0x3704, 0xE293},
+	{0x3706, 0xAB33},
+	{0x3708, 0x4595},
+	{0x3614, 0x00D0},
+	{0x3616, 0x8AAB},
+	{0x3618, 0x18B1},
+	{0x361A, 0x54AD},
+	{0x361C, 0x9DB0},
+	{0x3654, 0x11EB},
+	{0x3656, 0x332C},
+	{0x3658, 0x316D},
+	{0x365A, 0xF0EB},
+	{0x365C, 0xB4ED},
+	{0x3694, 0x0F31},
+	{0x3696, 0x08D0},
+	{0x3698, 0xA52F},
+	{0x369A, 0xE64F},
+	{0x369C, 0xC9D2},
+	{0x36D4, 0x8C2D},
+	{0x36D6, 0xAD6E},
+	{0x36D8, 0xE1CE},
+	{0x36DA, 0x1750},
+	{0x36DC, 0x8CAD},
+	{0x3714, 0x8CAF},
+	{0x3716, 0x8C11},
+	{0x3718, 0xE453},
+	{0x371A, 0x9693},
+	{0x371C, 0x38B5},
+	{0x361E, 0x00D0},
+	{0x3620, 0xB6CB},
+	{0x3622, 0x4811},
+	{0x3624, 0xB70C},
+	{0x3626, 0xA771},
+	{0x365E, 0xB5A9},
+	{0x3660, 0x05AA},
+	{0x3662, 0x00CF},
+	{0x3664, 0xB86B},
+	{0x3666, 0xA4AF},
+	{0x369E, 0x3E31},
+	{0x36A0, 0x902B},
+	{0x36A2, 0xD251},
+	{0x36A4, 0x5C2F},
+	{0x36A6, 0x8471},
+	{0x36DE, 0x2C6D},
+	{0x36E0, 0xECEE},
+	{0x36E2, 0xB650},
+	{0x36E4, 0x0210},
+	{0x36E6, 0xACAE},
+	{0x371E, 0xAC30},
+	{0x3720, 0x394E},
+	{0x3722, 0xFDD3},
+	{0x3724, 0xBCB2},
+	{0x3726, 0x5AD5},
+	{0x3782, 0x0508},
+	{0x3784, 0x03B4},
+	{0x3780, 0x8000},
+};
+
+
+struct mt9p012_km_reg mt9p012_km_regs = {
+	.reg_pat = &mt9p012_km_reg_pat[0],
+	.reg_pat_size = ARRAY_SIZE(mt9p012_km_reg_pat),
+	.ttbl = &mt9p012_km_test_tbl[0],
+	.ttbl_size = ARRAY_SIZE(mt9p012_km_test_tbl),
+	.lctbl = &mt9p012_km_lc_tbl[0],
+	.lctbl_size = ARRAY_SIZE(mt9p012_km_lc_tbl),
+	.rftbl = &mt9p012_km_rolloff_tbl[0],
+	.rftbl_size = ARRAY_SIZE(mt9p012_km_rolloff_tbl)
+};
+
+
diff --git a/drivers/media/platform/msm/camera_v1/mt9p012_reg.c b/drivers/media/platform/msm/camera_v1/mt9p012_reg.c
new file mode 100644
index 0000000..b828852
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mt9p012_reg.c
@@ -0,0 +1,263 @@
+/* Copyright (c) 2009, 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 "mt9p012.h"
+#include <linux/kernel.h>
+
+/*Micron settings from Applications for lower power consumption.*/
+struct reg_struct const mt9p012_reg_pat[2] = {
+	{ /* Preview */
+		/* vt_pix_clk_div          REG=0x0300 */
+		6,  /* 5 */
+
+		/* vt_sys_clk_div          REG=0x0302 */
+		1,
+		/* pre_pll_clk_div         REG=0x0304 */
+		2,
+		/* pll_multiplier          REG=0x0306 */
+		60,
+
+		/* op_pix_clk_div          REG=0x0308 */
+		8,  /* 10 */
+
+		/* op_sys_clk_div          REG=0x030A */
+		1,
+
+		/* scale_m                 REG=0x0404 */
+		16,
+
+		/* row_speed               REG=0x3016 */
+		0x0111,
+
+		/* x_addr_start            REG=0x3004 */
+		8,
+
+		/* x_addr_end              REG=0x3008 */
+		2597,
+
+		/* y_addr_start            REG=0x3002 */
+		8,
+
+		/* y_addr_end              REG=0x3006 */
+		1949,
+
+		/* read_mode               REG=0x3040
+		 * Preview 2x2 skipping */
+		0x00C3,
+
+		/* x_output_size           REG=0x034C */
+		1296,
+
+		/* y_output_size           REG=0x034E */
+		972,
+
+		/* line_length_pck         REG=0x300C */
+		3659,
+
+		/* frame_length_lines      REG=0x300A */
+		1074,
+
+		/* coarse_integration_time REG=0x3012 */
+		16,
+
+		/* fine_integration_time   REG=0x3014 */
+		1764
+	},
+	{ /* Snapshot */
+		/* vt_pix_clk_div          REG=0x0300 */
+		6,
+
+		/* vt_sys_clk_div          REG=0x0302 */
+		1,
+
+		/* pre_pll_clk_div         REG=0x0304 */
+		2,
+
+		/* pll_multiplier          REG=0x0306
+		 * 60 for 10fps snapshot */
+		60,
+
+		/* op_pix_clk_div          REG=0x0308 */
+		8,
+
+		/* op_sys_clk_div          REG=0x030A */
+		1,
+
+		/* scale_m                 REG=0x0404 */
+		16,
+
+		/* row_speed               REG=0x3016 */
+		0x0111,
+
+		/* x_addr_start            REG=0x3004 */
+		8,
+
+		/* x_addr_end              REG=0x3008 */
+		2615,
+
+		/* y_addr_start            REG=0x3002 */
+		8,
+
+		/* y_addr_end              REG=0x3006 */
+		1967,
+
+		/* read_mode               REG=0x3040 */
+		0x0041,
+
+		/* x_output_size           REG=0x034C */
+		2608,
+
+		/* y_output_size           REG=0x034E */
+		1960,
+
+		/* line_length_pck         REG=0x300C */
+		3911,
+
+		/* frame_length_lines      REG=0x300A 10 fps snapshot */
+		2045,
+
+		/* coarse_integration_time REG=0x3012 */
+		16,
+
+		/* fine_integration_time   REG=0x3014 */
+		882
+	}
+};
+
+
+struct mt9p012_i2c_reg_conf const mt9p012_test_tbl[] = {
+	{0x3044, 0x0544 & 0xFBFF},
+	{0x30CA, 0x0004 | 0x0001},
+	{0x30D4, 0x9020 & 0x7FFF},
+	{0x31E0, 0x0003 & 0xFFFE},
+	{0x3180, 0x91FF & 0x7FFF},
+	{0x301A, (0x10CC | 0x8000) & 0xFFF7},
+	{0x301E, 0x0000},
+	{0x3780, 0x0000},
+};
+struct mt9p012_i2c_reg_conf const mt9p012_rolloff_tbl[] = {
+	{0x360A, 0x0110},
+	{0x360C, 0x270D},
+	{0x360E, 0x0071},
+	{0x3610, 0xA38D},
+	{0x3612, 0xA610},
+	{0x364A, 0x8F49},
+	{0x364C, 0x696A},
+	{0x364E, 0x0FCD},
+	{0x3650, 0x20ED},
+	{0x3652, 0x81ED},
+	{0x368A, 0x1031},
+	{0x368C, 0xBCAD},
+	{0x368E, 0x77AA},
+	{0x3690, 0xD10E},
+	{0x3692, 0xC133},
+	{0x36CA, 0x4F8D},
+	{0x36CC, 0xAC4D},
+	{0x36CE, 0xC8CE},
+	{0x36D0, 0x73AD},
+	{0x36D2, 0xC150},
+	{0x370A, 0xB590},
+	{0x370C, 0x9010},
+	{0x370E, 0xAC52},
+	{0x3710, 0x4D51},
+	{0x3712, 0x5670},
+	{0x3600, 0x00F0},
+	{0x3602, 0xCE4B},
+	{0x3604, 0x4270},
+	{0x3606, 0x8BC9},
+	{0x3608, 0xFA2F},
+	{0x3640, 0x9A09},
+	{0x3642, 0xB40C},
+	{0x3644, 0x4ECD},
+	{0x3646, 0x1BCC},
+	{0x3648, 0xD68E},
+	{0x3680, 0x1BF0},
+	{0x3682, 0xC94D},
+	{0x3684, 0x714F},
+	{0x3686, 0x1491},
+	{0x3688, 0xB8D3},
+	{0x36C0, 0x3E49},
+	{0x36C2, 0x7A6C},
+	{0x36C4, 0xEF2E},
+	{0x36C6, 0xE0EE},
+	{0x36C8, 0x570F},
+	{0x3700, 0xD6AF},
+	{0x3702, 0x2251},
+	{0x3704, 0x8A33},
+	{0x3706, 0xEFB3},
+	{0x3708, 0x1174},
+	{0x3614, 0x0150},
+	{0x3616, 0xA9AB},
+	{0x3618, 0x1770},
+	{0x361A, 0x8809},
+	{0x361C, 0xE3AE},
+	{0x3654, 0x5ACC},
+	{0x3656, 0x35EA},
+	{0x3658, 0x2DEC},
+	{0x365A, 0xB90B},
+	{0x365C, 0x250C},
+	{0x3694, 0x1630},
+	{0x3696, 0xD88C},
+	{0x3698, 0xBD0E},
+	{0x369A, 0x16D1},
+	{0x369C, 0xE492},
+	{0x36D4, 0x5D6D},
+	{0x36D6, 0x906E},
+	{0x36D8, 0x10AE},
+	{0x36DA, 0x7A8E},
+	{0x36DC, 0x9672},
+	{0x3714, 0x8D90},
+	{0x3716, 0x04F1},
+	{0x3718, 0x23F1},
+	{0x371A, 0xF313},
+	{0x371C, 0xE833},
+	{0x361E, 0x0490},
+	{0x3620, 0x14CD},
+	{0x3622, 0x38F0},
+	{0x3624, 0xBAED},
+	{0x3626, 0xFF6F},
+	{0x365E, 0x358C},
+	{0x3660, 0xA9E9},
+	{0x3662, 0x4A4E},
+	{0x3664, 0x398D},
+	{0x3666, 0x890F},
+	{0x369E, 0x2DF0},
+	{0x36A0, 0xF7CE},
+	{0x36A2, 0xB3CC},
+	{0x36A4, 0x118D},
+	{0x36A6, 0x9CB3},
+	{0x36DE, 0x462D},
+	{0x36E0, 0x74AA},
+	{0x36E2, 0xC8CF},
+	{0x36E4, 0x8DEF},
+	{0x36E6, 0xF130},
+	{0x371E, 0x9250},
+	{0x3720, 0x19CC},
+	{0x3722, 0xDFD1},
+	{0x3724, 0x5B70},
+	{0x3726, 0x34D2},
+	{0x3782, 0x0530},
+	{0x3784, 0x03C8},
+	{0x3780, 0x8000},
+};
+
+struct mt9p012_reg mt9p012_regs = {
+	.reg_pat = &mt9p012_reg_pat[0],
+	.reg_pat_size = ARRAY_SIZE(mt9p012_reg_pat),
+	.ttbl = &mt9p012_test_tbl[0],
+	.ttbl_size = ARRAY_SIZE(mt9p012_test_tbl),
+	.rftbl = &mt9p012_rolloff_tbl[0],
+	.rftbl_size = ARRAY_SIZE(mt9p012_rolloff_tbl)
+};
+
+
diff --git a/drivers/media/platform/msm/camera_v1/mt9t013.c b/drivers/media/platform/msm/camera_v1/mt9t013.c
new file mode 100644
index 0000000..e107930
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mt9t013.c
@@ -0,0 +1,1504 @@
+/* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <media/msm_camera.h>
+#include <mach/gpio.h>
+#include <mach/camera.h>
+#include <asm/mach-types.h>
+#include "mt9t013.h"
+
+/*=============================================================
+	SENSOR REGISTER DEFINES
+==============================================================*/
+#define MT9T013_REG_MODEL_ID 		 0x0000
+#define MT9T013_MODEL_ID     		 0x2600
+#define REG_GROUPED_PARAMETER_HOLD   0x0104
+#define GROUPED_PARAMETER_HOLD       0x0100
+#define GROUPED_PARAMETER_UPDATE     0x0000
+#define REG_COARSE_INT_TIME          0x3012
+#define REG_VT_PIX_CLK_DIV           0x0300
+#define REG_VT_SYS_CLK_DIV           0x0302
+#define REG_PRE_PLL_CLK_DIV          0x0304
+#define REG_PLL_MULTIPLIER           0x0306
+#define REG_OP_PIX_CLK_DIV           0x0308
+#define REG_OP_SYS_CLK_DIV           0x030A
+#define REG_SCALE_M                  0x0404
+#define REG_FRAME_LENGTH_LINES       0x300A
+#define REG_LINE_LENGTH_PCK          0x300C
+#define REG_X_ADDR_START             0x3004
+#define REG_Y_ADDR_START             0x3002
+#define REG_X_ADDR_END               0x3008
+#define REG_Y_ADDR_END               0x3006
+#define REG_X_OUTPUT_SIZE            0x034C
+#define REG_Y_OUTPUT_SIZE            0x034E
+#define REG_FINE_INT_TIME            0x3014
+#define REG_ROW_SPEED                0x3016
+#define MT9T013_REG_RESET_REGISTER   0x301A
+#define MT9T013_RESET_REGISTER_PWON  0x10CC
+#define MT9T013_RESET_REGISTER_PWOFF 0x1008 /* 0x10C8 stop streaming*/
+#define MT9T013_RESET_FAST_TRANSITION 0x0002
+#define REG_READ_MODE                0x3040
+#define REG_GLOBAL_GAIN              0x305E
+#define REG_TEST_PATTERN_MODE        0x3070
+
+
+enum mt9t013_test_mode {
+	TEST_OFF,
+	TEST_1,
+	TEST_2,
+	TEST_3
+};
+
+enum mt9t013_resolution {
+	QTR_SIZE,
+	FULL_SIZE,
+	INVALID_SIZE
+};
+
+enum mt9t013_reg_update {
+	REG_INIT, /* registers that need to be updated during initialization */
+	UPDATE_PERIODIC, /* registers that needs periodic I2C writes */
+	UPDATE_ALL, /* all registers will be updated */
+	UPDATE_INVALID
+};
+
+enum mt9t013_setting {
+	RES_PREVIEW,
+	RES_CAPTURE
+};
+
+/* actuator's Slave Address */
+#define MT9T013_AF_I2C_ADDR   0x18
+
+/*
+* AF Total steps parameters
+*/
+#define MT9T013_TOTAL_STEPS_NEAR_TO_FAR    30
+
+/*
+ * Time in milisecs for waiting for the sensor to reset.
+ */
+#define MT9T013_RESET_DELAY_MSECS   66
+
+/* for 30 fps preview */
+#define MT9T013_DEFAULT_CLOCK_RATE  24000000
+#define MT9T013_DEFAULT_MAX_FPS     26
+
+
+/* FIXME: Changes from here */
+struct mt9t013_work {
+	struct work_struct work;
+};
+
+static struct  mt9t013_work *mt9t013_sensorw;
+static struct  i2c_client *mt9t013_client;
+
+struct mt9t013_ctrl {
+	const struct msm_camera_sensor_info *sensordata;
+
+	int sensormode;
+	uint32_t fps_divider; 		/* init to 1 * 0x00000400 */
+	uint32_t pict_fps_divider; 	/* init to 1 * 0x00000400 */
+
+	uint16_t curr_lens_pos;
+	uint16_t init_curr_lens_pos;
+	uint16_t my_reg_gain;
+	uint32_t my_reg_line_count;
+
+	enum mt9t013_resolution prev_res;
+	enum mt9t013_resolution pict_res;
+	enum mt9t013_resolution curr_res;
+	enum mt9t013_test_mode  set_test;
+
+	unsigned short imgaddr;
+};
+
+
+static struct mt9t013_ctrl *mt9t013_ctrl;
+static DECLARE_WAIT_QUEUE_HEAD(mt9t013_wait_queue);
+DEFINE_SEMAPHORE(mt9t013_sem);
+
+static int mt9t013_i2c_rxdata(unsigned short saddr,
+	unsigned char *rxdata, int length)
+{
+	struct i2c_msg msgs[] = {
+	{
+		.addr   = saddr,
+		.flags = 0,
+		.len   = 2,
+		.buf   = rxdata,
+	},
+	{
+		.addr  = saddr,
+		.flags = I2C_M_RD,
+		.len   = length,
+		.buf   = rxdata,
+	},
+	};
+
+	if (i2c_transfer(mt9t013_client->adapter, msgs, 2) < 0) {
+		pr_err("mt9t013_i2c_rxdata failed!\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t mt9t013_i2c_read_w(unsigned short saddr,
+	unsigned short raddr, unsigned short *rdata)
+{
+	int32_t rc = 0;
+	unsigned char buf[4];
+
+	if (!rdata)
+		return -EIO;
+
+	memset(buf, 0, sizeof(buf));
+
+	buf[0] = (raddr & 0xFF00)>>8;
+	buf[1] = (raddr & 0x00FF);
+
+	rc = mt9t013_i2c_rxdata(saddr, buf, 2);
+	if (rc < 0)
+		return rc;
+
+	*rdata = buf[0] << 8 | buf[1];
+
+	if (rc < 0)
+		pr_err("mt9t013_i2c_read failed!\n");
+
+	return rc;
+}
+
+static int32_t mt9t013_i2c_txdata(unsigned short saddr,
+	unsigned char *txdata, int length)
+{
+	struct i2c_msg msg[] = {
+	{
+		.addr = saddr,
+		.flags = 0,
+		.len = length,
+		.buf = txdata,
+	},
+	};
+
+	if (i2c_transfer(mt9t013_client->adapter, msg, 1) < 0) {
+		pr_err("mt9t013_i2c_txdata failed\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t mt9t013_i2c_write_b(unsigned short saddr,
+	unsigned short waddr, unsigned short wdata)
+{
+	int32_t rc = -EIO;
+	unsigned char buf[2];
+
+	memset(buf, 0, sizeof(buf));
+	buf[0] = waddr;
+	buf[1] = wdata;
+	rc = mt9t013_i2c_txdata(saddr, buf, 2);
+
+	if (rc < 0)
+		pr_err("i2c_write failed, addr = 0x%x, val = 0x%x!\n",
+		waddr, wdata);
+
+	return rc;
+}
+
+static int32_t mt9t013_i2c_write_w(unsigned short saddr,
+	unsigned short waddr, unsigned short wdata)
+{
+	int32_t rc = -EIO;
+	unsigned char buf[4];
+
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00)>>8;
+	buf[1] = (waddr & 0x00FF);
+	buf[2] = (wdata & 0xFF00)>>8;
+	buf[3] = (wdata & 0x00FF);
+
+	rc = mt9t013_i2c_txdata(saddr, buf, 4);
+
+	if (rc < 0)
+		pr_err("i2c_write_w failed, addr = 0x%x, val = 0x%x!\n",
+		waddr, wdata);
+
+	return rc;
+}
+
+static int32_t mt9t013_i2c_write_w_table(
+	struct mt9t013_i2c_reg_conf const *reg_conf_tbl,
+	int num_of_items_in_table)
+{
+	int i;
+	int32_t rc = -EIO;
+
+	for (i = 0; i < num_of_items_in_table; i++) {
+		rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+			reg_conf_tbl->waddr, reg_conf_tbl->wdata);
+		if (rc < 0)
+			break;
+		reg_conf_tbl++;
+	}
+
+	return rc;
+}
+
+static int32_t mt9t013_test(enum mt9t013_test_mode mo)
+{
+	int32_t rc = 0;
+
+	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+			REG_GROUPED_PARAMETER_HOLD,
+			GROUPED_PARAMETER_HOLD);
+	if (rc < 0)
+		return rc;
+
+	if (mo == TEST_OFF)
+		return 0;
+	else {
+		rc = mt9t013_i2c_write_w_table(mt9t013_regs.ttbl,
+				mt9t013_regs.ttbl_size);
+		if (rc < 0)
+			return rc;
+		rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_TEST_PATTERN_MODE, (uint16_t)mo);
+		if (rc < 0)
+			return rc;
+	}
+
+	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+			REG_GROUPED_PARAMETER_HOLD,
+			GROUPED_PARAMETER_UPDATE);
+	if (rc < 0)
+		return rc;
+
+	return rc;
+}
+
+static int32_t mt9t013_set_lc(void)
+{
+	int32_t rc;
+
+	rc = mt9t013_i2c_write_w_table(mt9t013_regs.lctbl,
+		mt9t013_regs.lctbl_size);
+	if (rc < 0)
+		return rc;
+
+	return rc;
+}
+
+static int32_t mt9t013_set_default_focus(uint8_t af_step)
+{
+	int32_t rc = 0;
+	uint8_t code_val_msb, code_val_lsb;
+	code_val_msb = 0x01;
+	code_val_lsb = af_step;
+
+	/* Write the digital code for current to the actuator */
+	rc = mt9t013_i2c_write_b(MT9T013_AF_I2C_ADDR>>1,
+			code_val_msb, code_val_lsb);
+
+	mt9t013_ctrl->curr_lens_pos = 0;
+	mt9t013_ctrl->init_curr_lens_pos = 0;
+	return rc;
+}
+
+static void mt9t013_get_pict_fps(uint16_t fps, uint16_t *pfps)
+{
+	/* input fps is preview fps in Q8 format */
+	uint32_t divider;   /*Q10 */
+	uint32_t pclk_mult; /*Q10 */
+	uint32_t d1;
+	uint32_t d2;
+
+	d1 =
+		(uint32_t)(
+		(mt9t013_regs.reg_pat[RES_PREVIEW].frame_length_lines *
+		0x00000400) /
+		mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines);
+
+	d2 =
+		(uint32_t)(
+		(mt9t013_regs.reg_pat[RES_PREVIEW].line_length_pck *
+		0x00000400) /
+		mt9t013_regs.reg_pat[RES_CAPTURE].line_length_pck);
+
+	divider = (uint32_t) (d1 * d2) / 0x00000400;
+
+	pclk_mult =
+		(uint32_t) ((mt9t013_regs.reg_pat[RES_CAPTURE].pll_multiplier *
+		0x00000400) /
+		(mt9t013_regs.reg_pat[RES_PREVIEW].pll_multiplier));
+
+
+	/* Verify PCLK settings and frame sizes. */
+	*pfps =
+		(uint16_t) (fps * divider * pclk_mult /
+		0x00000400 / 0x00000400);
+}
+
+static uint16_t mt9t013_get_prev_lines_pf(void)
+{
+	if (mt9t013_ctrl->prev_res == QTR_SIZE)
+		return mt9t013_regs.reg_pat[RES_PREVIEW].frame_length_lines;
+	else
+		return mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines;
+}
+
+static uint16_t mt9t013_get_prev_pixels_pl(void)
+{
+	if (mt9t013_ctrl->prev_res == QTR_SIZE)
+		return mt9t013_regs.reg_pat[RES_PREVIEW].line_length_pck;
+	else
+		return mt9t013_regs.reg_pat[RES_CAPTURE].line_length_pck;
+}
+
+static uint16_t mt9t013_get_pict_lines_pf(void)
+{
+	return mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines;
+}
+
+static uint16_t mt9t013_get_pict_pixels_pl(void)
+{
+	return mt9t013_regs.reg_pat[RES_CAPTURE].line_length_pck;
+}
+
+static uint32_t mt9t013_get_pict_max_exp_lc(void)
+{
+	uint16_t snapshot_lines_per_frame;
+
+	if (mt9t013_ctrl->pict_res == QTR_SIZE) {
+		snapshot_lines_per_frame =
+		mt9t013_regs.reg_pat[RES_PREVIEW].frame_length_lines - 1;
+	} else  {
+		snapshot_lines_per_frame =
+		mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines - 1;
+	}
+
+	return snapshot_lines_per_frame * 24;
+}
+
+static int32_t mt9t013_set_fps(struct fps_cfg *fps)
+{
+	/* input is new fps in Q8 format */
+	int32_t rc = 0;
+	enum mt9t013_setting setting;
+
+	mt9t013_ctrl->fps_divider = fps->fps_div;
+	mt9t013_ctrl->pict_fps_divider = fps->pict_fps_div;
+
+	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+			REG_GROUPED_PARAMETER_HOLD,
+			GROUPED_PARAMETER_HOLD);
+	if (rc < 0)
+		return -EBUSY;
+
+	CDBG("mt9t013_set_fps: fps_div is %d, f_mult is %d\n",
+			fps->fps_div, fps->f_mult);
+
+	if (mt9t013_ctrl->sensormode == SENSOR_PREVIEW_MODE)
+		setting = RES_PREVIEW;
+	else
+		setting = RES_CAPTURE;
+	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+			REG_FRAME_LENGTH_LINES,
+			(uint16_t) (
+			mt9t013_regs.reg_pat[setting].frame_length_lines *
+			fps->fps_div / 0x00000400));
+
+	if (rc < 0)
+		return rc;
+
+	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+			REG_GROUPED_PARAMETER_HOLD,
+			GROUPED_PARAMETER_UPDATE);
+	if (rc < 0)
+		return rc;
+
+	return rc;
+}
+
+static int32_t mt9t013_write_exp_gain(uint16_t gain, uint32_t line)
+{
+	uint16_t max_legal_gain = 0x01FF;
+	int32_t rc = 0;
+
+	if (mt9t013_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
+		mt9t013_ctrl->my_reg_gain = gain;
+		mt9t013_ctrl->my_reg_line_count = (uint16_t) line;
+	}
+
+	if (gain > max_legal_gain)
+		gain = max_legal_gain;
+
+	if (mt9t013_ctrl->sensormode != SENSOR_SNAPSHOT_MODE)
+		line = (uint32_t) (line * mt9t013_ctrl->fps_divider /
+				   0x00000400);
+	else
+		line = (uint32_t) (line * mt9t013_ctrl->pict_fps_divider /
+				   0x00000400);
+
+	/*Set digital gain to 1 */
+	gain |= 0x0200;
+
+	/* There used to be PARAMETER_HOLD register write before and
+	 * after REG_GLOBAL_GAIN & REG_COARSE_INIT_TIME. This causes
+	 * aec oscillation. Hence removed. */
+
+	rc = mt9t013_i2c_write_w(mt9t013_client->addr, REG_GLOBAL_GAIN, gain);
+	if (rc < 0)
+		return rc;
+
+	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+			REG_COARSE_INT_TIME, line);
+	if (rc < 0)
+		return rc;
+
+	return rc;
+}
+
+static int32_t mt9t013_set_pict_exp_gain(uint16_t gain, uint32_t line)
+{
+	int32_t rc = 0;
+
+	rc = mt9t013_write_exp_gain(gain, line);
+	if (rc < 0)
+		return rc;
+
+	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+			MT9T013_REG_RESET_REGISTER,
+			0x10CC | 0x0002);
+
+	mdelay(5);
+
+	return rc;
+}
+
+static int32_t mt9t013_setting(enum mt9t013_reg_update rupdate,
+	enum mt9t013_setting rt)
+{
+	int32_t rc = 0;
+
+	switch (rupdate) {
+	case UPDATE_PERIODIC: {
+
+	if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
+#if 0
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				MT9T013_REG_RESET_REGISTER,
+				MT9T013_RESET_REGISTER_PWOFF);
+		if (rc < 0)
+			return rc;
+#endif
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_VT_PIX_CLK_DIV,
+				mt9t013_regs.reg_pat[rt].vt_pix_clk_div);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_VT_SYS_CLK_DIV,
+				mt9t013_regs.reg_pat[rt].vt_sys_clk_div);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_PRE_PLL_CLK_DIV,
+				mt9t013_regs.reg_pat[rt].pre_pll_clk_div);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_PLL_MULTIPLIER,
+				mt9t013_regs.reg_pat[rt].pll_multiplier);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_OP_PIX_CLK_DIV,
+				mt9t013_regs.reg_pat[rt].op_pix_clk_div);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_OP_SYS_CLK_DIV,
+				mt9t013_regs.reg_pat[rt].op_sys_clk_div);
+		if (rc < 0)
+			return rc;
+
+		mdelay(5);
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_GROUPED_PARAMETER_HOLD,
+				GROUPED_PARAMETER_HOLD);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_ROW_SPEED,
+				mt9t013_regs.reg_pat[rt].row_speed);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_X_ADDR_START,
+				mt9t013_regs.reg_pat[rt].x_addr_start);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_X_ADDR_END,
+				mt9t013_regs.reg_pat[rt].x_addr_end);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_Y_ADDR_START,
+				mt9t013_regs.reg_pat[rt].y_addr_start);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_Y_ADDR_END,
+				mt9t013_regs.reg_pat[rt].y_addr_end);
+		if (rc < 0)
+			return rc;
+
+		if (machine_is_sapphire()) {
+			if (rt == 0)
+				rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+					REG_READ_MODE,
+					0x046F);
+			else
+				rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+					REG_READ_MODE,
+					0x0027);
+		} else
+			rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+					REG_READ_MODE,
+					mt9t013_regs.reg_pat[rt].read_mode);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_SCALE_M,
+				mt9t013_regs.reg_pat[rt].scale_m);
+		if (rc < 0)
+			return rc;
+
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_X_OUTPUT_SIZE,
+				mt9t013_regs.reg_pat[rt].x_output_size);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_Y_OUTPUT_SIZE,
+				mt9t013_regs.reg_pat[rt].y_output_size);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_LINE_LENGTH_PCK,
+				mt9t013_regs.reg_pat[rt].line_length_pck);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+			REG_FRAME_LENGTH_LINES,
+			(mt9t013_regs.reg_pat[rt].frame_length_lines *
+			mt9t013_ctrl->fps_divider / 0x00000400));
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+			REG_COARSE_INT_TIME,
+			mt9t013_regs.reg_pat[rt].coarse_int_time);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+			REG_FINE_INT_TIME,
+			mt9t013_regs.reg_pat[rt].fine_int_time);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+			REG_GROUPED_PARAMETER_HOLD,
+			GROUPED_PARAMETER_UPDATE);
+		if (rc < 0)
+			return rc;
+
+		rc = mt9t013_test(mt9t013_ctrl->set_test);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+			MT9T013_REG_RESET_REGISTER,
+			MT9T013_RESET_REGISTER_PWON|
+			MT9T013_RESET_FAST_TRANSITION);
+		if (rc < 0)
+			return rc;
+
+		mdelay(5);
+
+		return rc;
+	}
+	}
+		break;
+
+	/*CAMSENSOR_REG_UPDATE_PERIODIC */
+	case REG_INIT: {
+	if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				MT9T013_REG_RESET_REGISTER,
+				MT9T013_RESET_REGISTER_PWOFF);
+		if (rc < 0)
+			/* MODE_SELECT, stop streaming */
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_VT_PIX_CLK_DIV,
+				mt9t013_regs.reg_pat[rt].vt_pix_clk_div);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_VT_SYS_CLK_DIV,
+				mt9t013_regs.reg_pat[rt].vt_sys_clk_div);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_PRE_PLL_CLK_DIV,
+				mt9t013_regs.reg_pat[rt].pre_pll_clk_div);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_PLL_MULTIPLIER,
+				mt9t013_regs.reg_pat[rt].pll_multiplier);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_OP_PIX_CLK_DIV,
+				mt9t013_regs.reg_pat[rt].op_pix_clk_div);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_OP_SYS_CLK_DIV,
+				mt9t013_regs.reg_pat[rt].op_sys_clk_div);
+		if (rc < 0)
+			return rc;
+
+		mdelay(5);
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_GROUPED_PARAMETER_HOLD,
+				GROUPED_PARAMETER_HOLD);
+		if (rc < 0)
+			return rc;
+
+		/* additional power saving mode ok around 38.2MHz */
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				0x3084, 0x2409);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				0x3092, 0x0A49);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				0x3094, 0x4949);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				0x3096, 0x4949);
+		if (rc < 0)
+			return rc;
+
+		/* Set preview or snapshot mode */
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_ROW_SPEED,
+				mt9t013_regs.reg_pat[rt].row_speed);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_X_ADDR_START,
+				mt9t013_regs.reg_pat[rt].x_addr_start);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_X_ADDR_END,
+				mt9t013_regs.reg_pat[rt].x_addr_end);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_Y_ADDR_START,
+				mt9t013_regs.reg_pat[rt].y_addr_start);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_Y_ADDR_END,
+				mt9t013_regs.reg_pat[rt].y_addr_end);
+		if (rc < 0)
+			return rc;
+
+		if (machine_is_sapphire()) {
+			if (rt == 0)
+				rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+					REG_READ_MODE,
+					0x046F);
+			else
+				rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+					REG_READ_MODE,
+					0x0027);
+		} else
+			rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+					REG_READ_MODE,
+					mt9t013_regs.reg_pat[rt].read_mode);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_SCALE_M,
+				mt9t013_regs.reg_pat[rt].scale_m);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_X_OUTPUT_SIZE,
+				mt9t013_regs.reg_pat[rt].x_output_size);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_Y_OUTPUT_SIZE,
+				mt9t013_regs.reg_pat[rt].y_output_size);
+		if (rc < 0)
+			return 0;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_LINE_LENGTH_PCK,
+				mt9t013_regs.reg_pat[rt].line_length_pck);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_FRAME_LENGTH_LINES,
+				mt9t013_regs.reg_pat[rt].frame_length_lines);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_COARSE_INT_TIME,
+				mt9t013_regs.reg_pat[rt].coarse_int_time);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_FINE_INT_TIME,
+				mt9t013_regs.reg_pat[rt].fine_int_time);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_GROUPED_PARAMETER_HOLD,
+				GROUPED_PARAMETER_UPDATE);
+			if (rc < 0)
+				return rc;
+
+		/* load lens shading */
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_GROUPED_PARAMETER_HOLD,
+				GROUPED_PARAMETER_HOLD);
+		if (rc < 0)
+			return rc;
+
+		/* most likely needs to be written only once. */
+		rc = mt9t013_set_lc();
+		if (rc < 0)
+			return -EBUSY;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_GROUPED_PARAMETER_HOLD,
+				GROUPED_PARAMETER_UPDATE);
+		if (rc < 0)
+			return rc;
+
+		rc = mt9t013_test(mt9t013_ctrl->set_test);
+		if (rc < 0)
+			return rc;
+
+		mdelay(5);
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				MT9T013_REG_RESET_REGISTER,
+				MT9T013_RESET_REGISTER_PWON);
+		if (rc < 0)
+			/* MODE_SELECT, stop streaming */
+			return rc;
+
+		CDBG("!!! mt9t013 !!! PowerOn is done!\n");
+		mdelay(5);
+		return rc;
+		}
+	} /* case CAMSENSOR_REG_INIT: */
+	break;
+
+	/*CAMSENSOR_REG_INIT */
+	default:
+		rc = -EINVAL;
+		break;
+	} /* switch (rupdate) */
+
+	return rc;
+}
+
+static int32_t mt9t013_video_config(int mode, int res)
+{
+	int32_t rc;
+
+	switch (res) {
+	case QTR_SIZE:
+		rc = mt9t013_setting(UPDATE_PERIODIC, RES_PREVIEW);
+		if (rc < 0)
+			return rc;
+		CDBG("sensor configuration done!\n");
+		break;
+
+	case FULL_SIZE:
+		rc = mt9t013_setting(UPDATE_PERIODIC, RES_CAPTURE);
+		if (rc < 0)
+			return rc;
+		break;
+
+	default:
+		return -EINVAL;
+	} /* switch */
+
+	mt9t013_ctrl->prev_res = res;
+	mt9t013_ctrl->curr_res = res;
+	mt9t013_ctrl->sensormode = mode;
+
+	rc = mt9t013_write_exp_gain(mt9t013_ctrl->my_reg_gain,
+			mt9t013_ctrl->my_reg_line_count);
+	if (rc < 0)
+		return rc;
+
+	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+		MT9T013_REG_RESET_REGISTER,
+		MT9T013_RESET_REGISTER_PWON|MT9T013_RESET_FAST_TRANSITION);
+	if (rc < 0)
+		return rc;
+
+	msleep(5);
+	return rc;
+}
+
+static int32_t mt9t013_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+
+	rc = mt9t013_setting(UPDATE_PERIODIC, RES_CAPTURE);
+	if (rc < 0)
+		return rc;
+
+	mt9t013_ctrl->curr_res = mt9t013_ctrl->pict_res;
+	mt9t013_ctrl->sensormode = mode;
+	return rc;
+}
+
+static int32_t mt9t013_raw_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+
+	rc = mt9t013_setting(UPDATE_PERIODIC, RES_CAPTURE);
+	if (rc < 0)
+		return rc;
+
+	mt9t013_ctrl->curr_res = mt9t013_ctrl->pict_res;
+	mt9t013_ctrl->sensormode = mode;
+	return rc;
+}
+
+static int32_t mt9t013_power_down(void)
+{
+	int32_t rc = 0;
+
+	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+			MT9T013_REG_RESET_REGISTER,
+			MT9T013_RESET_REGISTER_PWOFF);
+	if (rc >= 0)
+		mdelay(5);
+	return rc;
+}
+
+static int32_t mt9t013_move_focus(int direction, int32_t num_steps)
+{
+	int16_t step_direction;
+	int16_t actual_step;
+	int16_t next_position;
+	int16_t break_steps[4];
+	uint8_t code_val_msb, code_val_lsb;
+	int16_t i;
+
+	if (num_steps > MT9T013_TOTAL_STEPS_NEAR_TO_FAR)
+		num_steps = MT9T013_TOTAL_STEPS_NEAR_TO_FAR;
+	else if (num_steps == 0)
+		return -EINVAL;
+
+	if (direction == MOVE_NEAR)
+		step_direction = 4;
+	else if (direction == MOVE_FAR)
+		step_direction = -4;
+	else
+		return -EINVAL;
+
+	if (mt9t013_ctrl->curr_lens_pos < mt9t013_ctrl->init_curr_lens_pos)
+		mt9t013_ctrl->curr_lens_pos = mt9t013_ctrl->init_curr_lens_pos;
+
+	actual_step =
+		(int16_t) (step_direction *
+		(int16_t) num_steps);
+
+	for (i = 0; i < 4; i++)
+		break_steps[i] =
+			actual_step / 4 * (i + 1) - actual_step / 4 * i;
+
+	for (i = 0; i < 4; i++) {
+		next_position =
+		(int16_t)
+		(mt9t013_ctrl->curr_lens_pos + break_steps[i]);
+
+		if (next_position > 255)
+			next_position = 255;
+		else if (next_position < 0)
+			next_position = 0;
+
+		code_val_msb =
+		((next_position >> 4) << 2) |
+		((next_position << 4) >> 6);
+
+		code_val_lsb =
+		((next_position & 0x03) << 6);
+
+		/* Writing the digital code for current to the actuator */
+		if (mt9t013_i2c_write_b(MT9T013_AF_I2C_ADDR>>1,
+				code_val_msb, code_val_lsb) < 0)
+			return -EBUSY;
+
+		/* Storing the current lens Position */
+		mt9t013_ctrl->curr_lens_pos = next_position;
+
+		if (i < 3)
+			mdelay(1);
+	} /* for */
+
+	return 0;
+}
+
+static int mt9t013_sensor_init_done(const struct msm_camera_sensor_info *data)
+{
+	gpio_direction_output(data->sensor_reset, 0);
+	gpio_free(data->sensor_reset);
+	return 0;
+}
+
+static int mt9t013_probe_init_sensor(const struct msm_camera_sensor_info *data)
+{
+	int rc;
+	uint16_t chipid;
+
+	rc = gpio_request(data->sensor_reset, "mt9t013");
+	if (!rc)
+		gpio_direction_output(data->sensor_reset, 1);
+	else
+		goto init_probe_done;
+
+	mdelay(20);
+
+	/* RESET the sensor image part via I2C command */
+	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+		MT9T013_REG_RESET_REGISTER, 0x1009);
+	if (rc < 0)
+		goto init_probe_fail;
+
+	msleep(10);
+
+	/* 3. Read sensor Model ID: */
+	rc = mt9t013_i2c_read_w(mt9t013_client->addr,
+		MT9T013_REG_MODEL_ID, &chipid);
+
+	if (rc < 0)
+		goto init_probe_fail;
+
+	CDBG("mt9t013 model_id = 0x%x\n", chipid);
+
+	/* 4. Compare sensor ID to MT9T012VC ID: */
+	if (chipid != MT9T013_MODEL_ID) {
+		rc = -ENODEV;
+		goto init_probe_fail;
+	}
+
+	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+		0x3064, 0x0805);
+	if (rc < 0)
+		goto init_probe_fail;
+
+	mdelay(MT9T013_RESET_DELAY_MSECS);
+
+	goto init_probe_done;
+
+	/* sensor: output enable */
+#if 0
+	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+		MT9T013_REG_RESET_REGISTER,
+		MT9T013_RESET_REGISTER_PWON);
+
+	/* if this fails, the sensor is not the MT9T013 */
+	rc = mt9t013_set_default_focus(0);
+#endif
+
+init_probe_fail:
+	gpio_direction_output(data->sensor_reset, 0);
+	gpio_free(data->sensor_reset);
+init_probe_done:
+	return rc;
+}
+
+static int32_t mt9t013_poweron_af(void)
+{
+	int32_t rc = 0;
+
+	/* enable AF actuator */
+	CDBG("enable AF actuator, gpio = %d\n",
+			mt9t013_ctrl->sensordata->vcm_pwd);
+	rc = gpio_request(mt9t013_ctrl->sensordata->vcm_pwd, "mt9t013");
+	if (!rc) {
+		gpio_direction_output(mt9t013_ctrl->sensordata->vcm_pwd, 0);
+		mdelay(20);
+		rc = mt9t013_set_default_focus(0);
+	} else
+		pr_err("%s, gpio_request failed (%d)!\n", __func__, rc);
+	return rc;
+}
+
+static void mt9t013_poweroff_af(void)
+{
+	gpio_direction_output(mt9t013_ctrl->sensordata->vcm_pwd, 1);
+	gpio_free(mt9t013_ctrl->sensordata->vcm_pwd);
+}
+
+int mt9t013_sensor_open_init(const struct msm_camera_sensor_info *data)
+{
+	int32_t  rc;
+
+	mt9t013_ctrl = kzalloc(sizeof(struct mt9t013_ctrl), GFP_KERNEL);
+	if (!mt9t013_ctrl) {
+		pr_err("mt9t013_init failed!\n");
+		rc = -ENOMEM;
+		goto init_done;
+	}
+
+	mt9t013_ctrl->fps_divider = 1 * 0x00000400;
+	mt9t013_ctrl->pict_fps_divider = 1 * 0x00000400;
+	mt9t013_ctrl->set_test = TEST_OFF;
+	mt9t013_ctrl->prev_res = QTR_SIZE;
+	mt9t013_ctrl->pict_res = FULL_SIZE;
+
+	if (data)
+		mt9t013_ctrl->sensordata = data;
+
+	/* enable mclk first */
+	msm_camio_clk_rate_set(MT9T013_DEFAULT_CLOCK_RATE);
+	mdelay(20);
+
+	msm_camio_camif_pad_reg_reset();
+	mdelay(20);
+
+	rc = mt9t013_probe_init_sensor(data);
+	if (rc < 0)
+		goto init_fail;
+
+	if (mt9t013_ctrl->prev_res == QTR_SIZE)
+		rc = mt9t013_setting(REG_INIT, RES_PREVIEW);
+	else
+		rc = mt9t013_setting(REG_INIT, RES_CAPTURE);
+
+	if (rc >= 0)
+		if (machine_is_sapphire())
+			rc = mt9t013_poweron_af();
+
+	if (rc < 0)
+		goto init_fail;
+	else
+		goto init_done;
+
+init_fail:
+	kfree(mt9t013_ctrl);
+init_done:
+	return rc;
+}
+
+static int mt9t013_init_client(struct i2c_client *client)
+{
+	/* Initialize the MSM_CAMI2C Chip */
+	init_waitqueue_head(&mt9t013_wait_queue);
+	return 0;
+}
+
+
+static int32_t mt9t013_set_sensor_mode(int mode, int res)
+{
+	int32_t rc = 0;
+	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+			REG_GROUPED_PARAMETER_HOLD,
+			GROUPED_PARAMETER_HOLD);
+	if (rc < 0)
+		return rc;
+
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		rc = mt9t013_video_config(mode, res);
+		break;
+
+	case SENSOR_SNAPSHOT_MODE:
+		rc = mt9t013_snapshot_config(mode);
+		break;
+
+	case SENSOR_RAW_SNAPSHOT_MODE:
+		rc = mt9t013_raw_snapshot_config(mode);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	/* FIXME: what should we do if rc < 0? */
+	if (rc >= 0)
+		return mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_GROUPED_PARAMETER_HOLD,
+				GROUPED_PARAMETER_UPDATE);
+	return rc;
+}
+
+int mt9t013_sensor_config(void __user *argp)
+{
+	struct sensor_cfg_data cdata;
+	long   rc = 0;
+
+	if (copy_from_user(&cdata, (void *)argp,
+			sizeof(struct sensor_cfg_data)))
+		return -EFAULT;
+
+	down(&mt9t013_sem);
+
+	CDBG("mt9t013_sensor_config: cfgtype = %d\n", cdata.cfgtype);
+	switch (cdata.cfgtype) {
+	case CFG_GET_PICT_FPS:
+		mt9t013_get_pict_fps(cdata.cfg.gfps.prevfps,
+				&(cdata.cfg.gfps.pictfps));
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PREV_L_PF:
+		cdata.cfg.prevl_pf = mt9t013_get_prev_lines_pf();
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PREV_P_PL:
+		cdata.cfg.prevp_pl = mt9t013_get_prev_pixels_pl();
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_L_PF:
+		cdata.cfg.pictl_pf = mt9t013_get_pict_lines_pf();
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_P_PL:
+		cdata.cfg.pictp_pl =
+			mt9t013_get_pict_pixels_pl();
+
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_MAX_EXP_LC:
+		cdata.cfg.pict_max_exp_lc =
+			mt9t013_get_pict_max_exp_lc();
+
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_SET_FPS:
+	case CFG_SET_PICT_FPS:
+		rc = mt9t013_set_fps(&(cdata.cfg.fps));
+		break;
+
+	case CFG_SET_EXP_GAIN:
+		rc = mt9t013_write_exp_gain(cdata.cfg.exp_gain.gain,
+				cdata.cfg.exp_gain.line);
+		break;
+
+	case CFG_SET_PICT_EXP_GAIN:
+		rc = mt9t013_set_pict_exp_gain(cdata.cfg.exp_gain.gain,
+				cdata.cfg.exp_gain.line);
+		break;
+
+	case CFG_SET_MODE:
+		rc = mt9t013_set_sensor_mode(cdata.mode, cdata.rs);
+		break;
+
+	case CFG_PWR_DOWN:
+		rc = mt9t013_power_down();
+		break;
+
+	case CFG_MOVE_FOCUS:
+		rc = mt9t013_move_focus(cdata.cfg.focus.dir,
+				cdata.cfg.focus.steps);
+		break;
+
+	case CFG_SET_DEFAULT_FOCUS:
+		rc = mt9t013_set_default_focus(cdata.cfg.focus.steps);
+		break;
+
+	case CFG_GET_AF_MAX_STEPS:
+		cdata.max_steps = MT9T013_TOTAL_STEPS_NEAR_TO_FAR;
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_SET_EFFECT:
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	up(&mt9t013_sem);
+	return rc;
+}
+
+int mt9t013_sensor_release(void)
+{
+	int rc = -EBADF;
+
+	down(&mt9t013_sem);
+
+	if (machine_is_sapphire())
+		mt9t013_poweroff_af();
+	mt9t013_power_down();
+
+	gpio_direction_output(mt9t013_ctrl->sensordata->sensor_reset,
+			0);
+	gpio_free(mt9t013_ctrl->sensordata->sensor_reset);
+
+	kfree(mt9t013_ctrl);
+
+	up(&mt9t013_sem);
+	CDBG("mt9t013_release completed!\n");
+	return rc;
+}
+
+static int mt9t013_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		rc = -ENOTSUPP;
+		goto probe_failure;
+	}
+
+	mt9t013_sensorw =
+		kzalloc(sizeof(struct mt9t013_work), GFP_KERNEL);
+
+	if (!mt9t013_sensorw) {
+		rc = -ENOMEM;
+		goto probe_failure;
+	}
+
+	i2c_set_clientdata(client, mt9t013_sensorw);
+	mt9t013_init_client(client);
+	mt9t013_client = client;
+	mt9t013_client->addr = mt9t013_client->addr >> 1;
+	mdelay(50);
+
+	CDBG("i2c probe ok\n");
+	return 0;
+
+probe_failure:
+	kfree(mt9t013_sensorw);
+	mt9t013_sensorw = NULL;
+	pr_err("i2c probe failure %d\n", rc);
+	return rc;
+}
+
+static const struct i2c_device_id mt9t013_i2c_id[] = {
+	{ "mt9t013", 0},
+	{ }
+};
+
+static struct i2c_driver mt9t013_i2c_driver = {
+	.id_table = mt9t013_i2c_id,
+	.probe  = mt9t013_i2c_probe,
+	.remove = __exit_p(mt9t013_i2c_remove),
+	.driver = {
+		.name = "mt9t013",
+	},
+};
+
+static int mt9t013_sensor_probe(
+		const struct msm_camera_sensor_info *info,
+		struct msm_sensor_ctrl *s)
+{
+	/* We expect this driver to match with the i2c device registered
+	 * in the board file immediately. */
+	int rc = i2c_add_driver(&mt9t013_i2c_driver);
+	if (rc < 0 || mt9t013_client == NULL) {
+		rc = -ENOTSUPP;
+		goto probe_done;
+	}
+
+	/* enable mclk first */
+	msm_camio_clk_rate_set(MT9T013_DEFAULT_CLOCK_RATE);
+	mdelay(20);
+
+	rc = mt9t013_probe_init_sensor(info);
+	if (rc < 0) {
+		i2c_del_driver(&mt9t013_i2c_driver);
+		goto probe_done;
+	}
+
+	s->s_init = mt9t013_sensor_open_init;
+	s->s_release = mt9t013_sensor_release;
+	s->s_config  = mt9t013_sensor_config;
+	s->s_mount_angle = 0;
+	mt9t013_sensor_init_done(info);
+
+probe_done:
+	return rc;
+}
+
+static int __mt9t013_probe(struct platform_device *pdev)
+{
+	return msm_camera_drv_start(pdev, mt9t013_sensor_probe);
+}
+
+static struct platform_driver msm_camera_driver = {
+	.probe = __mt9t013_probe,
+	.driver = {
+		.name = "msm_camera_mt9t013",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init mt9t013_init(void)
+{
+	return platform_driver_register(&msm_camera_driver);
+}
+
+module_init(mt9t013_init);
diff --git a/drivers/media/platform/msm/camera_v1/mt9t013.h b/drivers/media/platform/msm/camera_v1/mt9t013.h
new file mode 100644
index 0000000..e2d0c23
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mt9t013.h
@@ -0,0 +1,60 @@
+/* Copyright (c) 2009-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.
+ *
+ */
+
+#ifndef MT9T013_H
+#define MT9T013_H
+
+#include <linux/types.h>
+#include <mach/board.h>
+
+extern struct mt9t013_reg mt9t013_regs; /* from mt9t013_reg.c */
+
+struct reg_struct {
+	uint16_t vt_pix_clk_div;        /*  0x0300 */
+	uint16_t vt_sys_clk_div;        /*  0x0302 */
+	uint16_t pre_pll_clk_div;       /*  0x0304 */
+	uint16_t pll_multiplier;        /*  0x0306 */
+	uint16_t op_pix_clk_div;        /*  0x0308 */
+	uint16_t op_sys_clk_div;        /*  0x030A */
+	uint16_t scale_m;               /*  0x0404 */
+	uint16_t row_speed;             /*  0x3016 */
+	uint16_t x_addr_start;          /*  0x3004 */
+	uint16_t x_addr_end;            /*  0x3008 */
+	uint16_t y_addr_start;        	/*  0x3002 */
+	uint16_t y_addr_end;            /*  0x3006 */
+	uint16_t read_mode;             /*  0x3040 */
+	uint16_t x_output_size;         /*  0x034C */
+	uint16_t y_output_size;         /*  0x034E */
+	uint16_t line_length_pck;       /*  0x300C */
+	uint16_t frame_length_lines;	/*  0x300A */
+	uint16_t coarse_int_time; 		/*  0x3012 */
+	uint16_t fine_int_time;   		/*  0x3014 */
+};
+
+struct mt9t013_i2c_reg_conf {
+	unsigned short waddr;
+	unsigned short wdata;
+};
+
+struct mt9t013_reg {
+	struct reg_struct const *reg_pat;
+	uint16_t reg_pat_size;
+	struct mt9t013_i2c_reg_conf const *ttbl;
+	uint16_t ttbl_size;
+	struct mt9t013_i2c_reg_conf const *lctbl;
+	uint16_t lctbl_size;
+	struct mt9t013_i2c_reg_conf const *rftbl;
+	uint16_t rftbl_size;
+};
+
+#endif /* #define MT9T013_H */
diff --git a/drivers/media/platform/msm/camera_v1/mt9t013_reg.c b/drivers/media/platform/msm/camera_v1/mt9t013_reg.c
new file mode 100644
index 0000000..9031441
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/mt9t013_reg.c
@@ -0,0 +1,275 @@
+/* Copyright (c) 2009, 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 "mt9t013.h"
+#include <linux/kernel.h>
+
+struct reg_struct const mt9t013_reg_pat[2] = {
+	{ /* Preview 2x2 binning 20fps, pclk MHz, MCLK 24MHz */
+	/* vt_pix_clk_div:REG=0x0300 update get_snapshot_fps
+	* if this change */
+	8,
+
+	/* vt_sys_clk_div: REG=0x0302  update get_snapshot_fps
+	* if this change */
+	1,
+
+	/* pre_pll_clk_div REG=0x0304  update get_snapshot_fps
+	* if this change */
+	2,
+
+	/* pll_multiplier  REG=0x0306 60 for 30fps preview, 40
+	 * for 20fps preview
+	 * 46 for 30fps preview, try 47/48 to increase further */
+	46,
+
+	/* op_pix_clk_div        REG=0x0308 */
+	8,
+
+	/* op_sys_clk_div        REG=0x030A */
+	1,
+
+	/* scale_m       REG=0x0404 */
+	16,
+
+	/* row_speed     REG=0x3016 */
+	0x0111,
+
+	/* x_addr_start  REG=0x3004 */
+	8,
+
+	/* x_addr_end    REG=0x3008 */
+	2053,
+
+	/* y_addr_start  REG=0x3002 */
+	8,
+
+	/* y_addr_end    REG=0x3006 */
+	1541,
+
+	/* read_mode     REG=0x3040 */
+	0x046C,
+
+	/* x_output_size REG=0x034C */
+	1024,
+
+	/* y_output_size REG=0x034E */
+	768,
+
+	/* line_length_pck    REG=0x300C */
+	2616,
+
+	/* frame_length_lines REG=0x300A */
+	916,
+
+	/* coarse_int_time REG=0x3012 */
+	16,
+
+	/* fine_int_time   REG=0x3014 */
+	1461
+	},
+	{ /*Snapshot */
+	/* vt_pix_clk_div  REG=0x0300 update get_snapshot_fps
+	* if this change */
+	8,
+
+	/* vt_sys_clk_div  REG=0x0302 update get_snapshot_fps
+	* if this change */
+	1,
+
+	/* pre_pll_clk_div REG=0x0304 update get_snapshot_fps
+	 * if this change */
+	2,
+
+	/* pll_multiplier REG=0x0306 50 for 15fps snapshot,
+	 * 40 for 10fps snapshot
+	 * 46 for 30fps snapshot, try 47/48 to increase further */
+	46,
+
+	/* op_pix_clk_div        REG=0x0308 */
+	8,
+
+	/* op_sys_clk_div        REG=0x030A */
+	1,
+
+	/* scale_m       REG=0x0404 */
+	16,
+
+	/* row_speed     REG=0x3016 */
+	0x0111,
+
+	/* x_addr_start  REG=0x3004 */
+	8,
+
+	/* x_addr_end    REG=0x3008 */
+	2071,
+
+	/* y_addr_start  REG=0x3002 */
+	8,
+
+	/* y_addr_end    REG=0x3006 */
+	1551,
+
+	/* read_mode     REG=0x3040 */
+	0x0024,
+
+	/* x_output_size REG=0x034C */
+	2064,
+
+	/* y_output_size REG=0x034E */
+	1544,
+
+	/* line_length_pck REG=0x300C */
+	2952,
+
+	/* frame_length_lines    REG=0x300A */
+	1629,
+
+	/* coarse_int_time REG=0x3012 */
+	16,
+
+	/* fine_int_time REG=0x3014   */
+	733
+	}
+};
+
+struct mt9t013_i2c_reg_conf const mt9t013_test_tbl[] = {
+	{ 0x3044, 0x0544 & 0xFBFF },
+	{ 0x30CA, 0x0004 | 0x0001 },
+	{ 0x30D4, 0x9020 & 0x7FFF },
+	{ 0x31E0, 0x0003 & 0xFFFE },
+	{ 0x3180, 0x91FF & 0x7FFF },
+	{ 0x301A, (0x10CC | 0x8000) & 0xFFF7 },
+	{ 0x301E, 0x0000 },
+	{ 0x3780, 0x0000 },
+};
+
+/* [Lens shading 85 Percent TL84] */
+struct mt9t013_i2c_reg_conf const mt9t013_lc_tbl[] = {
+	{ 0x360A, 0x0290 }, /* P_RD_P0Q0 */
+	{ 0x360C, 0xC92D }, /* P_RD_P0Q1 */
+	{ 0x360E, 0x0771 }, /* P_RD_P0Q2 */
+	{ 0x3610, 0xE38C }, /* P_RD_P0Q3 */
+	{ 0x3612, 0xD74F }, /* P_RD_P0Q4 */
+	{ 0x364A, 0x168C }, /* P_RD_P1Q0 */
+	{ 0x364C, 0xCACB }, /* P_RD_P1Q1 */
+	{ 0x364E, 0x8C4C }, /* P_RD_P1Q2 */
+	{ 0x3650, 0x0BEA }, /* P_RD_P1Q3 */
+	{ 0x3652, 0xDC0F }, /* P_RD_P1Q4 */
+	{ 0x368A, 0x70B0 }, /* P_RD_P2Q0 */
+	{ 0x368C, 0x200B }, /* P_RD_P2Q1 */
+	{ 0x368E, 0x30B2 }, /* P_RD_P2Q2 */
+	{ 0x3690, 0xD04F }, /* P_RD_P2Q3 */
+	{ 0x3692, 0xACF5 }, /* P_RD_P2Q4 */
+	{ 0x36CA, 0xF7C9 }, /* P_RD_P3Q0 */
+	{ 0x36CC, 0x2AED }, /* P_RD_P3Q1 */
+	{ 0x36CE, 0xA652 }, /* P_RD_P3Q2 */
+	{ 0x36D0, 0x8192 }, /* P_RD_P3Q3 */
+	{ 0x36D2, 0x3A15 }, /* P_RD_P3Q4 */
+	{ 0x370A, 0xDA30 }, /* P_RD_P4Q0 */
+	{ 0x370C, 0x2E2F }, /* P_RD_P4Q1 */
+	{ 0x370E, 0xBB56 }, /* P_RD_P4Q2 */
+	{ 0x3710, 0x8195 }, /* P_RD_P4Q3 */
+	{ 0x3712, 0x02F9 }, /* P_RD_P4Q4 */
+	{ 0x3600, 0x0230 }, /* P_GR_P0Q0 */
+	{ 0x3602, 0x58AD }, /* P_GR_P0Q1 */
+	{ 0x3604, 0x18D1 }, /* P_GR_P0Q2 */
+	{ 0x3606, 0x260D }, /* P_GR_P0Q3 */
+	{ 0x3608, 0xF530 }, /* P_GR_P0Q4 */
+	{ 0x3640, 0x17EB }, /* P_GR_P1Q0 */
+	{ 0x3642, 0x3CAB }, /* P_GR_P1Q1 */
+	{ 0x3644, 0x87CE }, /* P_GR_P1Q2 */
+	{ 0x3646, 0xC02E }, /* P_GR_P1Q3 */
+	{ 0x3648, 0xF48F }, /* P_GR_P1Q4 */
+	{ 0x3680, 0x5350 }, /* P_GR_P2Q0 */
+	{ 0x3682, 0x7EAF }, /* P_GR_P2Q1 */
+	{ 0x3684, 0x4312 }, /* P_GR_P2Q2 */
+	{ 0x3686, 0xC652 }, /* P_GR_P2Q3 */
+	{ 0x3688, 0xBC15 }, /* P_GR_P2Q4 */
+	{ 0x36C0, 0xB8AD }, /* P_GR_P3Q0 */
+	{ 0x36C2, 0xBDCD }, /* P_GR_P3Q1 */
+	{ 0x36C4, 0xE4B2 }, /* P_GR_P3Q2 */
+	{ 0x36C6, 0xB50F }, /* P_GR_P3Q3 */
+	{ 0x36C8, 0x5B95 }, /* P_GR_P3Q4 */
+	{ 0x3700, 0xFC90 }, /* P_GR_P4Q0 */
+	{ 0x3702, 0x8C51 }, /* P_GR_P4Q1 */
+	{ 0x3704, 0xCED6 }, /* P_GR_P4Q2 */
+	{ 0x3706, 0xB594 }, /* P_GR_P4Q3 */
+	{ 0x3708, 0x0A39 }, /* P_GR_P4Q4 */
+	{ 0x3614, 0x0230 }, /* P_BL_P0Q0 */
+	{ 0x3616, 0x160D }, /* P_BL_P0Q1 */
+	{ 0x3618, 0x08D1 }, /* P_BL_P0Q2 */
+	{ 0x361A, 0x98AB }, /* P_BL_P0Q3 */
+	{ 0x361C, 0xEA50 }, /* P_BL_P0Q4 */
+	{ 0x3654, 0xB4EA }, /* P_BL_P1Q0 */
+	{ 0x3656, 0xEA6C }, /* P_BL_P1Q1 */
+	{ 0x3658, 0xFE08 }, /* P_BL_P1Q2 */
+	{ 0x365A, 0x2C6E }, /* P_BL_P1Q3 */
+	{ 0x365C, 0xEB0E }, /* P_BL_P1Q4 */
+	{ 0x3694, 0x6DF0 }, /* P_BL_P2Q0 */
+	{ 0x3696, 0x3ACF }, /* P_BL_P2Q1 */
+	{ 0x3698, 0x3E0F }, /* P_BL_P2Q2 */
+	{ 0x369A, 0xB2B1 }, /* P_BL_P2Q3 */
+	{ 0x369C, 0xC374 }, /* P_BL_P2Q4 */
+	{ 0x36D4, 0xF2AA }, /* P_BL_P3Q0 */
+	{ 0x36D6, 0x8CCC }, /* P_BL_P3Q1 */
+	{ 0x36D8, 0xDEF2 }, /* P_BL_P3Q2 */
+	{ 0x36DA, 0xFA11 }, /* P_BL_P3Q3 */
+	{ 0x36DC, 0x42F5 }, /* P_BL_P3Q4 */
+	{ 0x3714, 0xF4F1 }, /* P_BL_P4Q0 */
+	{ 0x3716, 0xF6F0 }, /* P_BL_P4Q1 */
+	{ 0x3718, 0x8FD6 }, /* P_BL_P4Q2 */
+	{ 0x371A, 0xEA14 }, /* P_BL_P4Q3 */
+	{ 0x371C, 0x6338 }, /* P_BL_P4Q4 */
+	{ 0x361E, 0x0350 }, /* P_GB_P0Q0 */
+	{ 0x3620, 0x91AE }, /* P_GB_P0Q1 */
+	{ 0x3622, 0x0571 }, /* P_GB_P0Q2 */
+	{ 0x3624, 0x100D }, /* P_GB_P0Q3 */
+	{ 0x3626, 0xCA70 }, /* P_GB_P0Q4 */
+	{ 0x365E, 0xE6CB }, /* P_GB_P1Q0 */
+	{ 0x3660, 0x50ED }, /* P_GB_P1Q1 */
+	{ 0x3662, 0x3DAE }, /* P_GB_P1Q2 */
+	{ 0x3664, 0xAA4F }, /* P_GB_P1Q3 */
+	{ 0x3666, 0xDC50 }, /* P_GB_P1Q4 */
+	{ 0x369E, 0x5470 }, /* P_GB_P2Q0 */
+	{ 0x36A0, 0x1F6E }, /* P_GB_P2Q1 */
+	{ 0x36A2, 0x6671 }, /* P_GB_P2Q2 */
+	{ 0x36A4, 0xC010 }, /* P_GB_P2Q3 */
+	{ 0x36A6, 0x8DF5 }, /* P_GB_P2Q4 */
+	{ 0x36DE, 0x0B0C }, /* P_GB_P3Q0 */
+	{ 0x36E0, 0x84CE }, /* P_GB_P3Q1 */
+	{ 0x36E2, 0x8493 }, /* P_GB_P3Q2 */
+	{ 0x36E4, 0xA610 }, /* P_GB_P3Q3 */
+	{ 0x36E6, 0x50B5 }, /* P_GB_P3Q4 */
+	{ 0x371E, 0x9651 }, /* P_GB_P4Q0 */
+	{ 0x3720, 0x1EAB }, /* P_GB_P4Q1 */
+	{ 0x3722, 0xAF76 }, /* P_GB_P4Q2 */
+	{ 0x3724, 0xE4F4 }, /* P_GB_P4Q3 */
+	{ 0x3726, 0x79F8 }, /* P_GB_P4Q4 */
+	{ 0x3782, 0x0410 }, /* POLY_ORIGIN_C */
+	{ 0x3784, 0x0320 }, /* POLY_ORIGIN_R  */
+	{ 0x3780, 0x8000 } /* POLY_SC_ENABLE */
+};
+
+struct mt9t013_reg mt9t013_regs = {
+	.reg_pat = &mt9t013_reg_pat[0],
+	.reg_pat_size = ARRAY_SIZE(mt9t013_reg_pat),
+	.ttbl = &mt9t013_test_tbl[0],
+	.ttbl_size = ARRAY_SIZE(mt9t013_test_tbl),
+	.lctbl = &mt9t013_lc_tbl[0],
+	.lctbl_size = ARRAY_SIZE(mt9t013_lc_tbl),
+	.rftbl = &mt9t013_lc_tbl[0],	/* &mt9t013_rolloff_tbl[0], */
+	.rftbl_size = ARRAY_SIZE(mt9t013_lc_tbl)
+};
+
+
diff --git a/drivers/media/platform/msm/camera_v1/ov5640.c b/drivers/media/platform/msm/camera_v1/ov5640.c
new file mode 100644
index 0000000..8441a46
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/ov5640.c
@@ -0,0 +1,1477 @@
+/* Copyright (c) 2011, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/* #define DEBUG */
+
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/leds.h>
+#include <linux/slab.h>
+#include <media/msm_camera.h>
+#include <mach/gpio.h>
+#include <mach/camera.h>
+#include "ov5640.h"
+
+#define FALSE 0
+#define TRUE 1
+
+struct ov5640_work {
+	struct work_struct work;
+};
+
+struct __ov5640_ctrl {
+	const struct msm_camera_sensor_info *sensordata;
+	int sensormode;
+	uint fps_divider; /* init to 1 * 0x00000400 */
+	uint pict_fps_divider; /* init to 1 * 0x00000400 */
+	u16 curr_step_pos;
+	u16 curr_lens_pos;
+	u16 init_curr_lens_pos;
+	u16 my_reg_gain;
+	u16 my_reg_line_count;
+	enum msm_s_resolution prev_res;
+	enum msm_s_resolution pict_res;
+	enum msm_s_resolution curr_res;
+	enum msm_s_test_mode  set_test;
+};
+
+static DECLARE_WAIT_QUEUE_HEAD(ov5640_wait_queue);
+DEFINE_MUTEX(ov5640_mutex);
+
+static int ov5640_pwdn_gpio;
+static int ov5640_reset_gpio;
+static int ov5640_driver_pwdn_gpio;
+static int OV5640_CSI_CONFIG;
+static struct ov5640_work *ov5640_sensorw;
+static struct i2c_client    *ov5640_client;
+static u8 ov5640_i2c_buf[4];
+static u8 ov5640_counter;
+static int16_t ov5640_effect;
+static int is_autoflash;
+static int effect_value;
+unsigned int ov5640_SAT_U = 0x40;
+unsigned int ov5640_SAT_V = 0x40;
+
+static struct __ov5640_ctrl *ov5640_ctrl;
+static int ov5640_afinit = 1;
+
+struct rw_semaphore ov_leds_list_lock;
+struct list_head ov_leds_list;
+
+static int ov5640_i2c_remove(struct i2c_client *client);
+static int ov5640_i2c_probe(struct i2c_client *client,
+		const struct i2c_device_id *id);
+
+static int ov5640_i2c_txdata(u16 saddr, u8 *txdata, int length)
+{
+	struct i2c_msg msg[] = {
+		{
+			.addr	= saddr,
+			.flags	= 0,
+			.len	= length,
+			.buf	= txdata,
+		},
+	};
+
+	if (i2c_transfer(ov5640_client->adapter, msg, 1) < 0)
+		return -EIO;
+	else
+		return 0;
+}
+
+static int ov5640_i2c_write(unsigned short saddr, unsigned int waddr,
+		unsigned short bdata, u8 trytimes)
+{
+	int rc = -EIO;
+
+	ov5640_counter = 0;
+	ov5640_i2c_buf[0] = (waddr & 0xFF00) >> 8;
+	ov5640_i2c_buf[1] = (waddr & 0x00FF);
+	ov5640_i2c_buf[2] = (bdata & 0x00FF);
+
+	while ((ov5640_counter < trytimes) && (rc != 0)) {
+		rc = ov5640_i2c_txdata(saddr, ov5640_i2c_buf, 3);
+
+		if (rc < 0) {
+			ov5640_counter++;
+			CDBG("***--CAMERA i2c_write_w failed,i2c addr=0x%x,"
+				"command addr = 0x%x, val = 0x%x,s=%d,"
+					"rc=%d!\n", saddr, waddr, bdata,
+					ov5640_counter, rc);
+			msleep(20);
+		}
+	}
+	return rc;
+}
+
+static int ov5640_i2c_rxdata(unsigned short saddr, unsigned char *rxdata,
+		int length)
+{
+	struct i2c_msg msgs[] = {
+		{
+			.addr	= saddr,
+			.flags	= 0,
+			.len	= 2,
+			.buf	= rxdata,
+		},
+		{
+			.addr	= saddr,
+			.flags	= I2C_M_RD,
+			.len	= length,
+			.buf	= rxdata,
+		},
+	};
+
+	if (i2c_transfer(ov5640_client->adapter, msgs, 2) < 0) {
+		CDBG("ov5640_i2c_rxdata failed!\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t ov5640_i2c_read_byte(unsigned short  saddr,
+		unsigned int raddr, unsigned int *rdata)
+{
+	int rc = 0;
+	unsigned char buf[2];
+
+	memset(buf, 0, sizeof(buf));
+
+	buf[0] = (raddr & 0xFF00)>>8;
+	buf[1] = (raddr & 0x00FF);
+
+	rc = ov5640_i2c_rxdata(saddr, buf, 1);
+	if (rc < 0) {
+		CDBG("ov5640_i2c_read_byte failed!\n");
+		return rc;
+	}
+
+	*rdata = buf[0];
+
+	return rc;
+}
+
+static int32_t ov5640_writepregs(struct ov5640_sensor *ptb, int32_t len)
+{
+	int32_t i, ret = 0;
+	uint32_t regv;
+
+	for (i = 0; i < len; i++) {
+		if (0 == ptb[i].mask) {
+			ov5640_i2c_write(ov5640_client->addr, ptb[i].addr,
+					ptb[i].data, 10);
+		} else {
+			ov5640_i2c_read_byte(ov5640_client->addr, ptb[i].addr,
+					&regv);
+			regv &= ptb[i].mask;
+			regv |= (ptb[i].data & (~ptb[i].mask));
+			ov5640_i2c_write(ov5640_client->addr, ptb[i].addr,
+					regv, 10);
+		}
+	}
+	return ret;
+}
+
+static void camera_sw_power_onoff(int v)
+{
+	if (v == 0) {
+		CDBG("camera_sw_power_onoff: down\n");
+		ov5640_i2c_write(ov5640_client->addr, 0x3008, 0x42, 10);
+	} else {
+		CDBG("camera_sw_power_onoff: on\n");
+		ov5640_i2c_write(ov5640_client->addr, 0x3008, 0x02, 10);
+	}
+}
+
+static void ov5640_power_off(void)
+{
+	CDBG("--CAMERA-- %s ... (Start...)\n", __func__);
+	gpio_set_value(ov5640_pwdn_gpio, 1);
+	CDBG("--CAMERA-- %s ... (End...)\n", __func__);
+}
+
+static void ov5640_power_on(void)
+{
+	CDBG("--CAMERA-- %s ... (Start...)\n", __func__);
+	gpio_set_value(ov5640_pwdn_gpio, 0);
+	CDBG("--CAMERA-- %s ... (End...)\n", __func__);
+}
+
+static void ov5640_power_reset(void)
+{
+	CDBG("--CAMERA-- %s ... (Start...)\n", __func__);
+	gpio_set_value(ov5640_reset_gpio, 1);   /* reset camera reset pin */
+	msleep(20);
+	gpio_set_value(ov5640_reset_gpio, 0);
+	msleep(20);
+	gpio_set_value(ov5640_reset_gpio, 1);
+	msleep(20);
+
+	CDBG("--CAMERA-- %s ... (End...)\n", __func__);
+}
+
+static int ov5640_probe_readID(const struct msm_camera_sensor_info *data)
+{
+	int rc = 0;
+	u32 device_id_high = 0;
+	u32 device_id_low = 0;
+
+	CDBG("--CAMERA-- %s (Start...)\n", __func__);
+	CDBG("--CAMERA-- %s sensor poweron,begin to read ID!\n", __func__);
+
+	/* 0x300A ,sensor ID register */
+	rc = ov5640_i2c_read_byte(ov5640_client->addr, 0x300A,
+			&device_id_high);
+
+	if (rc < 0) {
+		CDBG("--CAMERA-- %s ok , readI2C failed, rc = 0x%x\r\n",
+				__func__, rc);
+		return rc;
+	}
+	CDBG("--CAMERA-- %s  readID high byte, data = 0x%x\r\n",
+			__func__, device_id_high);
+
+	/* 0x300B ,sensor ID register */
+	rc = ov5640_i2c_read_byte(ov5640_client->addr, 0x300B,
+			&device_id_low);
+	if (rc < 0) {
+		CDBG("--CAMERA-- %s ok , readI2C failed,rc = 0x%x\r\n",
+				__func__, rc);
+		return rc;
+	}
+
+	CDBG("--CAMERA-- %s  readID low byte, data = 0x%x\r\n",
+			__func__, device_id_low);
+	CDBG("--CAMERA-- %s return ID :0x%x\n", __func__,
+			(device_id_high << 8) + device_id_low);
+
+	/* 0x5640, ov5640 chip id */
+	if ((device_id_high << 8) + device_id_low != OV5640_SENSOR_ID) {
+		CDBG("--CAMERA-- %s ok , device id error, should be 0x%x\r\n",
+				__func__, OV5640_SENSOR_ID);
+		return -EINVAL;
+	} else {
+		CDBG("--CAMERA-- %s ok , device id=0x%x\n", __func__,
+				OV5640_SENSOR_ID);
+		return 0;
+	}
+}
+
+static int ov5640_af_setting(void)
+{
+	int rc = 0;
+	int lens = sizeof(ov5640_afinit_tbl) / sizeof(ov5640_afinit_tbl[0]);
+
+	CDBG("--CAMERA-- ov5640_af_setting\n");
+
+	ov5640_i2c_write(ov5640_client->addr, 0x3000, 0x20, 10);
+
+	rc = ov5640_i2c_txdata(ov5640_client->addr, ov5640_afinit_tbl, lens);
+	if (rc < 0) {
+		CDBG("--CAMERA-- AF_init failed\n");
+		return rc;
+	}
+
+	ov5640_i2c_write(ov5640_client->addr, OV5640_CMD_MAIN, 0x00, 10);
+	ov5640_i2c_write(ov5640_client->addr, OV5640_CMD_ACK, 0x00, 10);
+	ov5640_i2c_write(ov5640_client->addr, OV5640_CMD_PARA0, 0x00, 10);
+	ov5640_i2c_write(ov5640_client->addr, OV5640_CMD_PARA1, 0x00, 10);
+	ov5640_i2c_write(ov5640_client->addr, OV5640_CMD_PARA2, 0x00, 10);
+	ov5640_i2c_write(ov5640_client->addr, OV5640_CMD_PARA3, 0x00, 10);
+	ov5640_i2c_write(ov5640_client->addr, OV5640_CMD_PARA4, 0x00, 10);
+	ov5640_i2c_write(ov5640_client->addr, OV5640_CMD_FW_STATUS, 0x7f, 10);
+	ov5640_i2c_write(ov5640_client->addr, 0x3000, 0x00, 10);
+
+	return rc;
+}
+
+static int ov5640_set_flash_light(enum led_brightness brightness)
+{
+	struct led_classdev *led_cdev;
+
+	CDBG("ov5640_set_flash_light brightness = %d\n", brightness);
+
+	down_read(&ov_leds_list_lock);
+	list_for_each_entry(led_cdev, &ov_leds_list, node) {
+		if (!strncmp(led_cdev->name, "flashlight", 10))
+			break;
+	}
+	up_read(&ov_leds_list_lock);
+
+	if (led_cdev) {
+		led_brightness_set(led_cdev, brightness);
+	} else {
+		CDBG("get flashlight device failed\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int ov5640_video_config(void)
+{
+	int rc = 0;
+
+	CDBG("--CAMERA-- ov5640_video_config\n");
+	CDBG("--CAMERA-- preview in, is_autoflash - 0x%x\n", is_autoflash);
+
+	/* autoflash setting */
+	if (is_autoflash == 1)
+		ov5640_set_flash_light(LED_OFF);
+
+	/* preview setting */
+	rc = OV5640CORE_WRITEPREG(ov5640_preview_tbl);
+	return rc;
+}
+
+static int ov5640_snapshot_config(void)
+{
+	int rc = 0;
+	unsigned int tmp;
+
+	CDBG("--CAMERA-- SENSOR_SNAPSHOT_MODE\n");
+	CDBG("--CAMERA-- %s, snapshot in, is_autoflash - 0x%x\n", __func__,
+			is_autoflash);
+
+	if (is_autoflash == 1) {
+		ov5640_i2c_read_byte(ov5640_client->addr, 0x350b, &tmp);
+		CDBG("--CAMERA-- GAIN VALUE : %x\n", tmp);
+		if ((tmp & 0x80) == 0)
+			ov5640_set_flash_light(LED_OFF);
+		else
+			ov5640_set_flash_light(LED_FULL);
+	}
+
+	rc = OV5640CORE_WRITEPREG(ov5640_capture_tbl);
+
+	return rc;
+}
+
+static int ov5640_setting(enum msm_s_reg_update rupdate,
+		enum msm_s_setting rt)
+{
+	int rc = -EINVAL, tmp;
+	struct msm_camera_csi_params ov5640_csi_params;
+
+	CDBG("--CAMERA-- %s (Start...), rupdate=%d\n", __func__, rupdate);
+
+	switch (rupdate) {
+	case S_UPDATE_PERIODIC:
+		if (!OV5640_CSI_CONFIG) {
+			camera_sw_power_onoff(0); /* standby */
+			msleep(20);
+
+			ov5640_csi_params.lane_cnt = 2;
+			ov5640_csi_params.data_format = CSI_8BIT;
+			ov5640_csi_params.lane_assign = 0xe4;
+			ov5640_csi_params.dpcm_scheme = 0;
+			ov5640_csi_params.settle_cnt = 0x6;
+
+			CDBG("%s: msm_camio_csi_config\n", __func__);
+
+			rc = msm_camio_csi_config(&ov5640_csi_params);
+			msleep(20);
+			camera_sw_power_onoff(1); /* on */
+			msleep(20);
+
+			OV5640_CSI_CONFIG = 1;
+
+		} else {
+			rc = 0;
+		}
+
+		if (S_RES_PREVIEW == rt)
+			rc = ov5640_video_config();
+		else if (S_RES_CAPTURE == rt)
+			rc = ov5640_snapshot_config();
+
+		break; /* UPDATE_PERIODIC */
+
+	case S_REG_INIT:
+		CDBG("--CAMERA-- S_REG_INIT (Start)\n");
+
+		rc = ov5640_i2c_write(ov5640_client->addr, 0x3103, 0x11, 10);
+		rc = ov5640_i2c_write(ov5640_client->addr, 0x3008, 0x82, 10);
+		msleep(20);
+
+		/* set sensor init setting */
+		CDBG("set sensor init setting\n");
+		rc = OV5640CORE_WRITEPREG(ov5640_init_tbl);
+		if (rc < 0) {
+			CDBG("sensor init setting failed\n");
+			break;
+		}
+
+		/* set image quality setting */
+		rc = OV5640CORE_WRITEPREG(ov5640_init_iq_tbl);
+		rc = ov5640_i2c_read_byte(ov5640_client->addr, 0x4740, &tmp);
+		CDBG("--CAMERA-- init 0x4740 value=0x%x\n", tmp);
+
+		if (tmp != 0x21) {
+			rc = ov5640_i2c_write(ov5640_client->addr, 0x4740,
+					0x21, 10);
+			msleep(20);
+			rc = ov5640_i2c_read_byte(ov5640_client->addr,
+					0x4740, &tmp);
+			CDBG("--CAMERA-- WG 0x4740 value=0x%x\n", tmp);
+		}
+
+		CDBG("--CAMERA-- AF_init: ov5640_afinit = %d\n",
+				ov5640_afinit);
+		if (ov5640_afinit == 1) {
+			rc = ov5640_af_setting();
+			if (rc < 0) {
+				CDBG("--CAMERA-- ov5640_af_setting failed\n");
+				break;
+			}
+			ov5640_afinit = 0;
+		}
+
+		/* reset fps_divider */
+		ov5640_ctrl->fps_divider = 1 * 0x0400;
+		CDBG("--CAMERA-- S_REG_INIT (End)\n");
+		break; /* case REG_INIT: */
+
+	default:
+		break;
+	} /* switch (rupdate) */
+
+	CDBG("--CAMERA-- %s (End), rupdate=%d\n", __func__, rupdate);
+
+	return rc;
+}
+
+static int ov5640_sensor_open_init(const struct msm_camera_sensor_info *data)
+{
+	int rc = -ENOMEM;
+
+	CDBG("--CAMERA-- %s\n", __func__);
+	ov5640_ctrl = kzalloc(sizeof(struct __ov5640_ctrl), GFP_KERNEL);
+	if (!ov5640_ctrl) {
+		CDBG("--CAMERA-- kzalloc ov5640_ctrl error !!\n");
+		kfree(ov5640_ctrl);
+		return rc;
+	}
+
+	ov5640_ctrl->fps_divider = 1 * 0x00000400;
+	ov5640_ctrl->pict_fps_divider = 1 * 0x00000400;
+	ov5640_ctrl->set_test = S_TEST_OFF;
+	ov5640_ctrl->prev_res = S_QTR_SIZE;
+	ov5640_ctrl->pict_res = S_FULL_SIZE;
+
+	if (data)
+		ov5640_ctrl->sensordata = data;
+
+	ov5640_power_off();
+
+	CDBG("%s: msm_camio_clk_rate_set\n", __func__);
+
+	msm_camio_clk_rate_set(24000000);
+	msleep(20);
+
+	ov5640_power_on();
+	ov5640_power_reset();
+
+	CDBG("%s: init sequence\n", __func__);
+
+	if (ov5640_ctrl->prev_res == S_QTR_SIZE)
+		rc = ov5640_setting(S_REG_INIT, S_RES_PREVIEW);
+	else
+		rc = ov5640_setting(S_REG_INIT, S_RES_CAPTURE);
+
+	if (rc < 0) {
+		CDBG("--CAMERA-- %s : ov5640_setting failed. rc = %d\n",
+				__func__, rc);
+		kfree(ov5640_ctrl);
+		return rc;
+	}
+
+	OV5640_CSI_CONFIG = 0;
+
+	CDBG("--CAMERA--re_init_sensor ok!!\n");
+	return rc;
+}
+
+static int ov5640_sensor_release(void)
+{
+	CDBG("--CAMERA--ov5640_sensor_release!!\n");
+
+	mutex_lock(&ov5640_mutex);
+
+	ov5640_power_off();
+
+	kfree(ov5640_ctrl);
+	ov5640_ctrl = NULL;
+
+	OV5640_CSI_CONFIG = 0;
+
+	mutex_unlock(&ov5640_mutex);
+	return 0;
+}
+
+static const struct i2c_device_id ov5640_i2c_id[] = {
+	{"ov5640",  0}, {}
+};
+
+static int ov5640_i2c_remove(struct i2c_client *client)
+{
+	return 0;
+}
+
+static int ov5640_init_client(struct i2c_client *client)
+{
+	/* Initialize the MSM_CAMI2C Chip */
+	init_waitqueue_head(&ov5640_wait_queue);
+	return 0;
+}
+
+static long ov5640_set_effect(int mode, int effect)
+{
+	int rc = 0;
+
+	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		/* Context A Special Effects */
+		CDBG("--CAMERA-- %s ...SENSOR_PREVIEW_MODE\n", __func__);
+		break;
+
+	case SENSOR_SNAPSHOT_MODE:
+		/* Context B Special Effects */
+		CDBG("--CAMERA-- %s ...SENSOR_SNAPSHOT_MODE\n", __func__);
+		break;
+
+	default:
+		break;
+	}
+
+	effect_value = effect;
+
+	switch (effect)	{
+	case CAMERA_EFFECT_OFF:
+		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_OFF\n", __func__);
+		rc = OV5640CORE_WRITEPREG(ov5640_effect_normal_tbl);
+		/* for recover saturation level when change special effect */
+		ov5640_i2c_write(ov5640_client->addr, 0x5583, ov5640_SAT_U,
+				10);
+		/* for recover saturation level when change special effect */
+		ov5640_i2c_write(ov5640_client->addr, 0x5584, ov5640_SAT_V,
+				10);
+		break;
+
+	case CAMERA_EFFECT_MONO:
+		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_MONO\n", __func__);
+		rc = OV5640CORE_WRITEPREG(ov5640_effect_mono_tbl);
+		break;
+
+	case CAMERA_EFFECT_BW:
+		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_BW\n", __func__);
+		rc = OV5640CORE_WRITEPREG(ov5640_effect_bw_tbl);
+		break;
+
+	case CAMERA_EFFECT_BLUISH:
+		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_BLUISH\n", __func__);
+		rc = OV5640CORE_WRITEPREG(ov5640_effect_bluish_tbl);
+		break;
+
+	case CAMERA_EFFECT_SOLARIZE:
+		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_NEGATIVE\n", __func__);
+		rc = OV5640CORE_WRITEPREG(ov5640_effect_solarize_tbl);
+		break;
+
+	case CAMERA_EFFECT_SEPIA:
+		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_SEPIA\n", __func__);
+		rc = OV5640CORE_WRITEPREG(ov5640_effect_sepia_tbl);
+		break;
+
+	case CAMERA_EFFECT_REDDISH:
+		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_REDDISH\n", __func__);
+		rc = OV5640CORE_WRITEPREG(ov5640_effect_reddish_tbl);
+		break;
+
+	case CAMERA_EFFECT_GREENISH:
+		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_GREENISH\n", __func__);
+		rc = OV5640CORE_WRITEPREG(ov5640_effect_greenish_tbl);
+		break;
+
+	case CAMERA_EFFECT_NEGATIVE:
+		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_NEGATIVE\n", __func__);
+		rc = OV5640CORE_WRITEPREG(ov5640_effect_negative_tbl);
+		break;
+
+	default:
+		CDBG("--CAMERA-- %s ...Default(Not Support)\n", __func__);
+	}
+
+	ov5640_effect = effect;
+	/* Refresh Sequencer */
+	CDBG("--CAMERA-- %s ...(End)\n", __func__);
+	return rc;
+}
+
+static int ov5640_set_brightness(int8_t brightness)
+{
+	int rc = 0;
+
+	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+	CDBG("--CAMERA-- %s ...brightness = %d\n", __func__ , brightness);
+
+	switch (brightness) {
+	case CAMERA_BRIGHTNESS_LV0:
+		CDBG("--CAMERA--CAMERA_BRIGHTNESS_LV0\n");
+		rc = OV5640CORE_WRITEPREG(ov5640_brightness_lv0_tbl);
+		break;
+
+	case CAMERA_BRIGHTNESS_LV1:
+		CDBG("--CAMERA--CAMERA_BRIGHTNESS_LV1\n");
+		rc = OV5640CORE_WRITEPREG(ov5640_brightness_lv1_tbl);
+		break;
+
+	case CAMERA_BRIGHTNESS_LV2:
+		CDBG("--CAMERA--CAMERA_BRIGHTNESS_LV2\n");
+		rc = OV5640CORE_WRITEPREG(ov5640_brightness_lv2_tbl);
+		break;
+
+	case CAMERA_BRIGHTNESS_LV3:
+		CDBG("--CAMERA--CAMERA_BRIGHTNESS_LV3\n");
+		rc = OV5640CORE_WRITEPREG(ov5640_brightness_lv3_tbl);
+		break;
+
+	case CAMERA_BRIGHTNESS_LV4:
+		CDBG("--CAMERA--CAMERA_BRIGHTNESS_LV4\n");
+		rc = OV5640CORE_WRITEPREG(ov5640_brightness_default_lv4_tbl);
+		break;
+
+	case CAMERA_BRIGHTNESS_LV5:
+		CDBG("--CAMERA--CAMERA_BRIGHTNESS_LV5\n");
+		rc = OV5640CORE_WRITEPREG(ov5640_brightness_lv5_tbl);
+		break;
+
+	case CAMERA_BRIGHTNESS_LV6:
+		CDBG("--CAMERA--CAMERA_BRIGHTNESS_LV6\n");
+		rc = OV5640CORE_WRITEPREG(ov5640_brightness_lv6_tbl);
+		break;
+
+	case CAMERA_BRIGHTNESS_LV7:
+		CDBG("--CAMERA--CAMERA_BRIGHTNESS_LV7\n");
+		rc = OV5640CORE_WRITEPREG(ov5640_brightness_lv7_tbl);
+		break;
+
+	case CAMERA_BRIGHTNESS_LV8:
+		CDBG("--CAMERA--CAMERA_BRIGHTNESS_LV8\n");
+		rc = OV5640CORE_WRITEPREG(ov5640_brightness_lv8_tbl);
+		break;
+
+	default:
+		CDBG("--CAMERA--CAMERA_BRIGHTNESS_ERROR COMMAND\n");
+		break;
+	}
+
+	CDBG("--CAMERA-- %s ...(End)\n", __func__);
+	return rc;
+}
+
+static int ov5640_set_contrast(int contrast)
+{
+	int rc = 0;
+
+	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+	CDBG("--CAMERA-- %s ...contrast = %d\n", __func__ , contrast);
+
+	if (effect_value == CAMERA_EFFECT_OFF) {
+		switch (contrast) {
+		case CAMERA_CONTRAST_LV0:
+			CDBG("--CAMERA--CAMERA_CONTRAST_LV0\n");
+			rc = OV5640CORE_WRITEPREG(ov5640_contrast_lv0_tbl);
+			break;
+
+		case CAMERA_CONTRAST_LV1:
+			CDBG("--CAMERA--CAMERA_CONTRAST_LV1\n");
+			rc = OV5640CORE_WRITEPREG(ov5640_contrast_lv1_tbl);
+			break;
+
+		case CAMERA_CONTRAST_LV2:
+			CDBG("--CAMERA--CAMERA_CONTRAST_LV2\n");
+			rc = OV5640CORE_WRITEPREG(ov5640_contrast_lv2_tbl);
+			break;
+
+		case CAMERA_CONTRAST_LV3:
+			CDBG("--CAMERA--CAMERA_CONTRAST_LV3\n");
+			rc = OV5640CORE_WRITEPREG(ov5640_contrast_lv3_tbl);
+			break;
+
+		case CAMERA_CONTRAST_LV4:
+			CDBG("--CAMERA--CAMERA_CONTRAST_LV4\n");
+			rc = OV5640CORE_WRITEPREG(
+					ov5640_contrast_default_lv4_tbl);
+			break;
+
+		case CAMERA_CONTRAST_LV5:
+			CDBG("--CAMERA--CAMERA_CONTRAST_LV5\n");
+			rc = OV5640CORE_WRITEPREG(ov5640_contrast_lv5_tbl);
+			break;
+
+		case CAMERA_CONTRAST_LV6:
+			CDBG("--CAMERA--CAMERA_CONTRAST_LV6\n");
+			rc = OV5640CORE_WRITEPREG(ov5640_contrast_lv6_tbl);
+			break;
+
+		case CAMERA_CONTRAST_LV7:
+			CDBG("--CAMERA--CAMERA_CONTRAST_LV7\n");
+			rc = OV5640CORE_WRITEPREG(ov5640_contrast_lv7_tbl);
+			break;
+
+		case CAMERA_CONTRAST_LV8:
+			CDBG("--CAMERA--CAMERA_CONTRAST_LV8\n");
+			rc = OV5640CORE_WRITEPREG(ov5640_contrast_lv8_tbl);
+			break;
+
+		default:
+			CDBG("--CAMERA--CAMERA_CONTRAST_ERROR COMMAND\n");
+			break;
+		}
+	}
+
+	CDBG("--CAMERA-- %s ...(End)\n", __func__);
+	return rc;
+}
+
+static int ov5640_set_sharpness(int sharpness)
+{
+	int rc = 0;
+
+	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+	CDBG("--CAMERA-- %s ...sharpness = %d\n", __func__ , sharpness);
+
+	if (effect_value == CAMERA_EFFECT_OFF) {
+		switch (sharpness) {
+		case CAMERA_SHARPNESS_LV0:
+			CDBG("--CAMERA--CAMERA_SHARPNESS_LV0\n");
+			rc = OV5640CORE_WRITEPREG(ov5640_sharpness_lv0_tbl);
+			break;
+
+		case CAMERA_SHARPNESS_LV1:
+			CDBG("--CAMERA--CAMERA_SHARPNESS_LV1\n");
+			rc = OV5640CORE_WRITEPREG(ov5640_sharpness_lv1_tbl);
+			break;
+
+		case CAMERA_SHARPNESS_LV2:
+			CDBG("--CAMERA--CAMERA_SHARPNESS_LV2\n");
+			rc = OV5640CORE_WRITEPREG(
+					ov5640_sharpness_default_lv2_tbl);
+			break;
+
+		case CAMERA_SHARPNESS_LV3:
+			CDBG("--CAMERA--CAMERA_SHARPNESS_LV3\n");
+			rc = OV5640CORE_WRITEPREG(ov5640_sharpness_lv3_tbl);
+			break;
+
+		case CAMERA_SHARPNESS_LV4:
+			CDBG("--CAMERA--CAMERA_SHARPNESS_LV4\n");
+			rc = OV5640CORE_WRITEPREG(ov5640_sharpness_lv4_tbl);
+			break;
+
+		case CAMERA_SHARPNESS_LV5:
+			CDBG("--CAMERA--CAMERA_SHARPNESS_LV5\n");
+			rc = OV5640CORE_WRITEPREG(ov5640_sharpness_lv5_tbl);
+			break;
+
+		case CAMERA_SHARPNESS_LV6:
+			CDBG("--CAMERA--CAMERA_SHARPNESS_LV6\n");
+			rc = OV5640CORE_WRITEPREG(ov5640_sharpness_lv6_tbl);
+			break;
+
+		case CAMERA_SHARPNESS_LV7:
+			CDBG("--CAMERA--CAMERA_SHARPNESS_LV7\n");
+			rc = OV5640CORE_WRITEPREG(ov5640_sharpness_lv7_tbl);
+			break;
+
+		case CAMERA_SHARPNESS_LV8:
+			CDBG("--CAMERA--CAMERA_SHARPNESS_LV8\n");
+			rc = OV5640CORE_WRITEPREG(ov5640_sharpness_lv8_tbl);
+			break;
+
+		default:
+			CDBG("--CAMERA--CAMERA_SHARPNESS_ERROR COMMAND\n");
+			break;
+		}
+	}
+
+	CDBG("--CAMERA-- %s ...(End)\n", __func__);
+	return rc;
+}
+
+static int ov5640_set_saturation(int saturation)
+{
+	long rc = 0;
+
+	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+	CDBG("--CAMERA-- %s ...saturation = %d\n", __func__ , saturation);
+
+	if (effect_value == CAMERA_EFFECT_OFF) {
+		switch (saturation) {
+		case CAMERA_SATURATION_LV0:
+			CDBG("--CAMERA--CAMERA_SATURATION_LV0\n");
+			rc = OV5640CORE_WRITEPREG(ov5640_saturation_lv0_tbl);
+			break;
+
+		case CAMERA_SATURATION_LV1:
+			CDBG("--CAMERA--CAMERA_SATURATION_LV1\n");
+			rc = OV5640CORE_WRITEPREG(ov5640_saturation_lv1_tbl);
+			break;
+
+		case CAMERA_SATURATION_LV2:
+			CDBG("--CAMERA--CAMERA_SATURATION_LV2\n");
+			rc = OV5640CORE_WRITEPREG(ov5640_saturation_lv2_tbl);
+			break;
+
+		case CAMERA_SATURATION_LV3:
+			CDBG("--CAMERA--CAMERA_SATURATION_LV3\n");
+			rc = OV5640CORE_WRITEPREG(ov5640_saturation_lv3_tbl);
+			break;
+
+		case CAMERA_SATURATION_LV4:
+			CDBG("--CAMERA--CAMERA_SATURATION_LV4\n");
+			rc = OV5640CORE_WRITEPREG(
+					ov5640_saturation_default_lv4_tbl);
+			break;
+
+		case CAMERA_SATURATION_LV5:
+			CDBG("--CAMERA--CAMERA_SATURATION_LV5\n");
+			rc = OV5640CORE_WRITEPREG(ov5640_saturation_lv5_tbl);
+			break;
+
+		case CAMERA_SATURATION_LV6:
+			CDBG("--CAMERA--CAMERA_SATURATION_LV6\n");
+			rc = OV5640CORE_WRITEPREG(ov5640_saturation_lv6_tbl);
+			break;
+
+		case CAMERA_SATURATION_LV7:
+			CDBG("--CAMERA--CAMERA_SATURATION_LV7\n");
+			rc = OV5640CORE_WRITEPREG(ov5640_saturation_lv7_tbl);
+			break;
+
+		case CAMERA_SATURATION_LV8:
+			CDBG("--CAMERA--CAMERA_SATURATION_LV8\n");
+			rc = OV5640CORE_WRITEPREG(ov5640_saturation_lv8_tbl);
+			break;
+
+		default:
+			CDBG("--CAMERA--CAMERA_SATURATION_ERROR COMMAND\n");
+			break;
+		}
+	}
+
+	/* for recover saturation level when change special effect */
+	switch (saturation) {
+	case CAMERA_SATURATION_LV0:
+		CDBG("--CAMERA--CAMERA_SATURATION_LV0\n");
+		ov5640_SAT_U = 0x00;
+		ov5640_SAT_V = 0x00;
+		break;
+	case CAMERA_SATURATION_LV1:
+		CDBG("--CAMERA--CAMERA_SATURATION_LV1\n");
+		ov5640_SAT_U = 0x10;
+		ov5640_SAT_V = 0x10;
+		break;
+	case CAMERA_SATURATION_LV2:
+		CDBG("--CAMERA--CAMERA_SATURATION_LV2\n");
+		ov5640_SAT_U = 0x20;
+		ov5640_SAT_V = 0x20;
+		break;
+	case CAMERA_SATURATION_LV3:
+		CDBG("--CAMERA--CAMERA_SATURATION_LV3\n");
+		ov5640_SAT_U = 0x30;
+		ov5640_SAT_V = 0x30;
+		break;
+	case CAMERA_SATURATION_LV4:
+		CDBG("--CAMERA--CAMERA_SATURATION_LV4\n");
+		ov5640_SAT_U = 0x40;
+		ov5640_SAT_V = 0x40;            break;
+	case CAMERA_SATURATION_LV5:
+		CDBG("--CAMERA--CAMERA_SATURATION_LV5\n");
+		ov5640_SAT_U = 0x50;
+		ov5640_SAT_V = 0x50;            break;
+	case CAMERA_SATURATION_LV6:
+		CDBG("--CAMERA--CAMERA_SATURATION_LV6\n");
+		ov5640_SAT_U = 0x60;
+		ov5640_SAT_V = 0x60;
+		break;
+	case CAMERA_SATURATION_LV7:
+		CDBG("--CAMERA--CAMERA_SATURATION_LV7\n");
+		ov5640_SAT_U = 0x70;
+		ov5640_SAT_V = 0x70;            break;
+	case CAMERA_SATURATION_LV8:
+		CDBG("--CAMERA--CAMERA_SATURATION_LV8\n");
+		ov5640_SAT_U = 0x80;
+		ov5640_SAT_V = 0x80;
+		break;
+	default:
+		CDBG("--CAMERA--CAMERA_SATURATION_ERROR COMMAND\n");
+		break;
+	}
+
+	CDBG("--CAMERA-- %s ...(End)\n", __func__);
+	return rc;
+}
+
+static long ov5640_set_antibanding(int antibanding)
+{
+	long rc = 0;
+
+	CDBG("--CAMERA-- %s ...(Start)\n",  __func__);
+	CDBG("--CAMERA-- %s ...antibanding = %d\n",  __func__, antibanding);
+
+	switch (antibanding) {
+	case CAMERA_ANTIBANDING_OFF:
+		CDBG("--CAMERA--CAMERA_ANTIBANDING_OFF\n");
+		break;
+
+	case CAMERA_ANTIBANDING_60HZ:
+		CDBG("--CAMERA--CAMERA_ANTIBANDING_60HZ\n");
+		rc = OV5640CORE_WRITEPREG(ov5640_antibanding_60z_tbl);
+		break;
+
+	case CAMERA_ANTIBANDING_50HZ:
+		CDBG("--CAMERA--CAMERA_ANTIBANDING_50HZ\n");
+		rc = OV5640CORE_WRITEPREG(ov5640_antibanding_50z_tbl);
+		break;
+
+	case CAMERA_ANTIBANDING_AUTO:
+		CDBG("--CAMERA--CAMERA_ANTIBANDING_AUTO\n");
+		rc = OV5640CORE_WRITEPREG(ov5640_antibanding_auto_tbl);
+		break;
+
+	default:
+		CDBG("--CAMERA--CAMERA_ANTIBANDING_ERROR COMMAND\n");
+		break;
+	}
+
+	CDBG("--CAMERA-- %s ...(End)\n", __func__);
+	return rc;
+}
+
+static long ov5640_set_exposure_mode(int mode)
+{
+	long rc = 0;
+	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+	CDBG("--CAMERA-- %s ...mode = %d\n", __func__ , mode);
+	CDBG("--CAMERA-- %s ...(End)\n", __func__);
+	return rc;
+}
+
+static int32_t ov5640_lens_shading_enable(uint8_t is_enable)
+{
+	int32_t rc = 0;
+	CDBG("--CAMERA--%s: ...(Start). enable = %d\n",  __func__, is_enable);
+
+	if (is_enable) {
+		CDBG("%s: enable~!!\n", __func__);
+		rc = OV5640CORE_WRITEPREG(ov5640_lens_shading_on_tbl);
+	} else {
+		CDBG("%s: disable~!!\n", __func__);
+		rc = OV5640CORE_WRITEPREG(ov5640_lens_shading_off_tbl);
+	}
+	CDBG("--CAMERA--%s: ...(End). rc = %d\n", __func__, rc);
+	return rc;
+}
+
+static int ov5640_set_sensor_mode(int mode, int res)
+{
+	int rc = 0;
+
+	CDBG("--CAMERA-- ov5640_set_sensor_mode mode = %d, res = %d\n",
+			mode, res);
+
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		CDBG("--CAMERA-- SENSOR_PREVIEW_MODE\n");
+		rc = ov5640_setting(S_UPDATE_PERIODIC, S_RES_PREVIEW);
+		break;
+
+	case SENSOR_SNAPSHOT_MODE:
+		CDBG("--CAMERA-- SENSOR_SNAPSHOT_MODE\n");
+		rc = ov5640_setting(S_UPDATE_PERIODIC, S_RES_CAPTURE);
+		break;
+
+	case SENSOR_RAW_SNAPSHOT_MODE:
+		CDBG("--CAMERA-- SENSOR_RAW_SNAPSHOT_MODE\n");
+		rc = ov5640_setting(S_UPDATE_PERIODIC, S_RES_CAPTURE);
+		break;
+
+	default:
+		CDBG("--CAMERA--ov5640_set_sensor_mode no support\n");
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
+static int ov5640_set_wb_oem(uint8_t param)
+{
+	int rc = 0;
+	unsigned int tmp2;
+
+	CDBG("[kylin] %s \r\n", __func__);
+
+	ov5640_i2c_read_byte(ov5640_client->addr, 0x350b, &tmp2);
+	CDBG("--CAMERA-- GAIN VALUE : %x\n", tmp2);
+
+	switch (param) {
+	case CAMERA_WB_AUTO:
+
+		CDBG("--CAMERA--CAMERA_WB_AUTO\n");
+		rc = OV5640CORE_WRITEPREG(ov5640_wb_def);
+		break;
+
+	case CAMERA_WB_CUSTOM:
+		CDBG("--CAMERA--CAMERA_WB_CUSTOM\n");
+		rc = OV5640CORE_WRITEPREG(ov5640_wb_custom);
+		break;
+	case CAMERA_WB_INCANDESCENT:
+		CDBG("--CAMERA--CAMERA_WB_INCANDESCENT\n");
+		rc = OV5640CORE_WRITEPREG(ov5640_wb_inc);
+		break;
+	case CAMERA_WB_DAYLIGHT:
+		CDBG("--CAMERA--CAMERA_WB_DAYLIGHT\n");
+		rc = OV5640CORE_WRITEPREG(ov5640_wb_daylight);
+		break;
+	case CAMERA_WB_CLOUDY_DAYLIGHT:
+		CDBG("--CAMERA--CAMERA_WB_CLOUDY_DAYLIGHT\n");
+		rc = OV5640CORE_WRITEPREG(ov5640_wb_cloudy);
+		break;
+	default:
+		break;
+	}
+	return rc;
+}
+
+static int ov5640_set_touchaec(uint32_t x, uint32_t y)
+{
+	uint8_t aec_arr[8] = {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11};
+	int idx = 0;
+	int i;
+
+	CDBG("[kylin] %s x: %d ,y: %d\r\n", __func__ , x, y);
+	idx = x / 2 + y * 2;
+	CDBG("[kylin] idx: %d\r\n", idx);
+
+	if (x % 2 == 0)
+		aec_arr[idx] = 0x10 | 0x0a;
+	else
+		aec_arr[idx] = 0x01 | 0xa0;
+
+	for (i = 0; i < 8; i++) {
+		CDBG("write : %x val : %x ", 0x5688 + i, aec_arr[i]);
+		ov5640_i2c_write(ov5640_client->addr, 0x5688 + i,
+				aec_arr[i], 10);
+	}
+
+	return 1;
+}
+
+static int ov5640_set_exposure_compensation(int compensation)
+{
+	long rc = 0;
+
+	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+
+	CDBG("--CAMERA-- %s ...exposure_compensation = %d\n", __func__ ,
+			    compensation);
+
+	switch (compensation) {
+	case CAMERA_EXPOSURE_COMPENSATION_LV0:
+		CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV0\n");
+		rc = OV5640CORE_WRITEPREG(
+				ov5640_exposure_compensation_lv0_tbl);
+		break;
+
+	case CAMERA_EXPOSURE_COMPENSATION_LV1:
+		CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV1\n");
+		rc = OV5640CORE_WRITEPREG(
+				ov5640_exposure_compensation_lv1_tbl);
+		break;
+
+	case CAMERA_EXPOSURE_COMPENSATION_LV2:
+		CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV2\n");
+		rc = OV5640CORE_WRITEPREG(
+			    ov5640_exposure_compensation_lv2_default_tbl);
+		break;
+
+	case CAMERA_EXPOSURE_COMPENSATION_LV3:
+		CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV3\n");
+		rc = OV5640CORE_WRITEPREG(
+				ov5640_exposure_compensation_lv3_tbl);
+		break;
+
+	case CAMERA_EXPOSURE_COMPENSATION_LV4:
+		CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV3\n");
+		rc = OV5640CORE_WRITEPREG(
+				ov5640_exposure_compensation_lv4_tbl);
+		break;
+
+	default:
+		CDBG("--CAMERA--ERROR CAMERA_EXPOSURE_COMPENSATION\n");
+		break;
+	}
+
+	CDBG("--CAMERA-- %s ...(End)\n", __func__);
+
+	return rc;
+}
+
+static int ov5640_sensor_start_af(void)
+{
+	int i;
+	unsigned int af_st = 0;
+	unsigned int af_ack = 0;
+	unsigned int tmp = 0;
+	int rc = 0;
+
+	CDBG("--CAMERA-- %s (Start...)\n", __func__);
+
+	ov5640_i2c_read_byte(ov5640_client->addr,
+			OV5640_CMD_FW_STATUS, &af_st);
+	CDBG("--CAMERA-- %s af_st = %d\n", __func__, af_st);
+
+	ov5640_i2c_write(ov5640_client->addr, OV5640_CMD_ACK, 0x01, 10);
+	ov5640_i2c_write(ov5640_client->addr, OV5640_CMD_MAIN, 0x03, 10);
+
+	for (i = 0; i < 50; i++) {
+		ov5640_i2c_read_byte(ov5640_client->addr,
+				OV5640_CMD_ACK, &af_ack);
+		if (af_ack == 0)
+			break;
+		msleep(50);
+	}
+	CDBG("--CAMERA-- %s af_ack = 0x%x\n", __func__, af_ack);
+
+	ov5640_i2c_read_byte(ov5640_client->addr, OV5640_CMD_FW_STATUS,
+			&af_st);
+	CDBG("--CAMERA-- %s af_st = %d\n", __func__, af_st);
+
+	if (af_st == 0x10) {
+		CDBG("--CAMERA-- %s AF ok and release AF setting~!!\n",
+				__func__);
+	} else {
+		CDBG("--CAMERA-- %s AF not ready!!\n", __func__);
+	}
+
+	ov5640_i2c_write(ov5640_client->addr, OV5640_CMD_ACK, 0x01, 10);
+	ov5640_i2c_write(ov5640_client->addr, OV5640_CMD_MAIN, 0x07, 10);
+
+	for (i = 0; i < 70; i++) {
+		ov5640_i2c_read_byte(ov5640_client->addr, OV5640_CMD_ACK,
+				&af_ack);
+		if (af_ack == 0)
+			break;
+		msleep(25);
+	}
+
+	ov5640_i2c_read_byte(ov5640_client->addr, OV5640_CMD_PARA0, &tmp);
+	CDBG("0x3024 = %x\n", tmp);
+	rc = ((tmp == 0) ? 1 : 0);
+
+	ov5640_i2c_read_byte(ov5640_client->addr, OV5640_CMD_PARA1, &tmp);
+	CDBG("0x3025 = %x\n", tmp);
+	rc = ((tmp == 0) ? 1 : 0);
+
+	ov5640_i2c_read_byte(ov5640_client->addr, OV5640_CMD_PARA2, &tmp);
+	CDBG("0x3026 = %x\n", tmp);
+	rc = ((tmp == 0) ? 1 : 0);
+
+	ov5640_i2c_read_byte(ov5640_client->addr, OV5640_CMD_PARA3, &tmp);
+	CDBG("0x3027 = %x\n", tmp);
+	rc = ((tmp == 0) ? 1 : 0) ;
+
+	ov5640_i2c_read_byte(ov5640_client->addr, OV5640_CMD_PARA4, &tmp);
+	CDBG("0x3028 = %x\n", tmp);
+	rc = ((tmp == 0) ? 1 : 0) ;
+
+	CDBG("--CAMERA-- %s rc = %d(End...)\n", __func__, rc);
+	return rc;
+}
+
+static int ov5640_sensor_config(void __user *argp)
+{
+	struct sensor_cfg_data cdata;
+	long rc = 0;
+
+	if (copy_from_user(&cdata, (void *)argp,
+				sizeof(struct sensor_cfg_data)))
+		return -EFAULT;
+
+	CDBG("--CAMERA-- %s %d\n", __func__, cdata.cfgtype);
+
+	mutex_lock(&ov5640_mutex);
+
+	switch (cdata.cfgtype) {
+	case CFG_SET_MODE:
+		rc = ov5640_set_sensor_mode(cdata.mode, cdata.rs);
+		break;
+
+	case CFG_SET_EFFECT:
+		CDBG("--CAMERA-- CFG_SET_EFFECT mode=%d,"
+				"effect = %d !!\n", cdata.mode,
+				cdata.cfg.effect);
+		rc = ov5640_set_effect(cdata.mode, cdata.cfg.effect);
+		break;
+
+	case CFG_START:
+		CDBG("--CAMERA-- CFG_START (Not Support) !!\n");
+		/* Not Support */
+		break;
+
+	case CFG_PWR_UP:
+		CDBG("--CAMERA-- CFG_PWR_UP (Not Support) !!\n");
+		/* Not Support */
+		break;
+
+	case CFG_PWR_DOWN:
+		CDBG("--CAMERA-- CFG_PWR_DOWN (Not Support)\n");
+		ov5640_power_off();
+		break;
+
+	case CFG_SET_DEFAULT_FOCUS:
+		CDBG("--CAMERA-- CFG_SET_DEFAULT_FOCUS (Not Implement) !!\n");
+		break;
+
+	case CFG_MOVE_FOCUS:
+		CDBG("--CAMERA-- CFG_MOVE_FOCUS (Not Implement) !!\n");
+		break;
+
+	case CFG_SET_BRIGHTNESS:
+		CDBG("--CAMERA-- CFG_SET_BRIGHTNESS  !!\n");
+		rc = ov5640_set_brightness(cdata.cfg.brightness);
+		break;
+
+	case CFG_SET_CONTRAST:
+		CDBG("--CAMERA-- CFG_SET_CONTRAST  !!\n");
+		rc = ov5640_set_contrast(cdata.cfg.contrast);
+		break;
+
+	case CFG_SET_EXPOSURE_MODE:
+		CDBG("--CAMERA-- CFG_SET_EXPOSURE_MODE !!\n");
+		rc = ov5640_set_exposure_mode(cdata.cfg.ae_mode);
+		break;
+
+	case CFG_SET_ANTIBANDING:
+		CDBG("--CAMERA-- CFG_SET_ANTIBANDING antibanding = %d!!\n",
+				cdata.cfg.antibanding);
+		rc = ov5640_set_antibanding(cdata.cfg.antibanding);
+		break;
+
+	case CFG_SET_LENS_SHADING:
+		CDBG("--CAMERA-- CFG_SET_LENS_SHADING !!\n");
+		rc = ov5640_lens_shading_enable(
+				cdata.cfg.lens_shading);
+		break;
+
+	case CFG_SET_SATURATION:
+		CDBG("--CAMERA-- CFG_SET_SATURATION !!\n");
+		rc = ov5640_set_saturation(cdata.cfg.saturation);
+		break;
+
+	case CFG_SET_SHARPNESS:
+		CDBG("--CAMERA-- CFG_SET_SHARPNESS !!\n");
+		rc = ov5640_set_sharpness(cdata.cfg.sharpness);
+		break;
+
+	case CFG_SET_WB:
+		CDBG("--CAMERA-- CFG_SET_WB!!\n");
+		ov5640_set_wb_oem(cdata.cfg.wb_val);
+		rc = 0 ;
+		break;
+
+	case CFG_SET_TOUCHAEC:
+		CDBG("--CAMERA-- CFG_SET_TOUCHAEC!!\n");
+		ov5640_set_touchaec(cdata.cfg.aec_cord.x,
+				cdata.cfg.aec_cord.y);
+		rc = 0 ;
+		break;
+
+	case CFG_SET_AUTO_FOCUS:
+		CDBG("--CAMERA-- CFG_SET_AUTO_FOCUS !\n");
+		rc = ov5640_sensor_start_af();
+		break;
+
+	case CFG_SET_AUTOFLASH:
+		CDBG("--CAMERA-- CFG_SET_AUTOFLASH !\n");
+		is_autoflash = cdata.cfg.is_autoflash;
+		CDBG("[kylin] is autoflash %d\r\n", is_autoflash);
+		rc = 0;
+		break;
+
+	case CFG_SET_EXPOSURE_COMPENSATION:
+		CDBG("--CAMERA-- CFG_SET_EXPOSURE_COMPENSATION !\n");
+		rc = ov5640_set_exposure_compensation(
+				cdata.cfg.exp_compensation);
+		break;
+
+	default:
+		CDBG("%s: Command=%d (Not Implement)!!\n", __func__,
+				cdata.cfgtype);
+		rc = -EINVAL;
+		break;
+	}
+
+	mutex_unlock(&ov5640_mutex);
+	return rc;
+}
+
+static struct i2c_driver ov5640_i2c_driver = {
+	.id_table = ov5640_i2c_id,
+	.probe  = ov5640_i2c_probe,
+	.remove = ov5640_i2c_remove,
+	.driver = {
+		.name = "ov5640",
+	},
+};
+
+static int ov5640_probe_init_gpio(const struct msm_camera_sensor_info *data)
+{
+	int rc = 0;
+
+	CDBG("--CAMERA-- %s\n", __func__);
+
+	ov5640_pwdn_gpio = data->sensor_pwd;
+	ov5640_reset_gpio = data->sensor_reset;
+	ov5640_driver_pwdn_gpio = data->vcm_pwd ;
+
+	if (data->vcm_enable)
+		gpio_direction_output(data->vcm_pwd, 1);
+
+	gpio_direction_output(data->sensor_reset, 1);
+	gpio_direction_output(data->sensor_pwd, 1);
+
+	return rc;
+
+}
+
+static void ov5640_probe_free_gpio(const struct msm_camera_sensor_info *data)
+{
+	gpio_free(ov5640_pwdn_gpio);
+	gpio_free(ov5640_reset_gpio);
+
+	if (data->vcm_enable) {
+		gpio_free(ov5640_driver_pwdn_gpio);
+		ov5640_driver_pwdn_gpio = 0xFF ;
+	}
+
+	ov5640_pwdn_gpio	= 0xFF;
+	ov5640_reset_gpio	= 0xFF;
+}
+
+static int ov5640_sensor_probe(const struct msm_camera_sensor_info *info,
+		struct msm_sensor_ctrl *s)
+{
+	int rc = -ENOTSUPP;
+
+	CDBG("--CAMERA-- %s (Start...)\n", __func__);
+	rc = i2c_add_driver(&ov5640_i2c_driver);
+	CDBG("--CAMERA-- i2c_add_driver ret:0x%x,ov5640_client=0x%x\n",
+			rc, (unsigned int)ov5640_client);
+	if ((rc < 0) || (ov5640_client == NULL)) {
+		CDBG("--CAMERA-- i2c_add_driver FAILS!!\n");
+		return rc;
+	}
+
+	rc = ov5640_probe_init_gpio(info);
+	if (rc < 0)
+		return rc;
+
+	ov5640_power_off();
+
+	/* SENSOR NEED MCLK TO DO I2C COMMUNICTION, OPEN CLK FIRST*/
+	msm_camio_clk_rate_set(24000000);
+
+	msleep(20);
+
+	ov5640_power_on();
+	ov5640_power_reset();
+
+	rc = ov5640_probe_readID(info);
+
+	if (rc < 0) {
+		CDBG("--CAMERA--ov5640_probe_readID Fail !!~~~~!!\n");
+		CDBG("--CAMERA-- %s, unregister\n", __func__);
+		i2c_del_driver(&ov5640_i2c_driver);
+		ov5640_power_off();
+		ov5640_probe_free_gpio(info);
+		return rc;
+	}
+
+	s->s_init		= ov5640_sensor_open_init;
+	s->s_release		= ov5640_sensor_release;
+	s->s_config		= ov5640_sensor_config;
+	s->s_camera_type	= BACK_CAMERA_2D;
+	s->s_mount_angle	= info->sensor_platform_info->mount_angle;
+
+	ov5640_power_off();
+
+	CDBG("--CAMERA-- %s (End...)\n", __func__);
+	return rc;
+}
+
+static int ov5640_i2c_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	CDBG("--CAMERA-- %s ... (Start...)\n", __func__);
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		CDBG("--CAMERA--i2c_check_functionality failed\n");
+		return -ENOMEM;
+	}
+
+	ov5640_sensorw = kzalloc(sizeof(struct ov5640_work), GFP_KERNEL);
+	if (!ov5640_sensorw) {
+		CDBG("--CAMERA--kzalloc failed\n");
+		return -ENOMEM;
+	}
+
+	i2c_set_clientdata(client, ov5640_sensorw);
+	ov5640_init_client(client);
+	ov5640_client = client;
+
+	CDBG("--CAMERA-- %s ... (End...)\n", __func__);
+	return 0;
+}
+
+static int __ov5640_probe(struct platform_device *pdev)
+{
+	return msm_camera_drv_start(pdev, ov5640_sensor_probe);
+}
+
+static struct platform_driver msm_camera_driver = {
+	.probe	= __ov5640_probe,
+	.driver	= {
+		.name	= "msm_camera_ov5640",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init ov5640_init(void)
+{
+	ov5640_i2c_buf[0] = 0x5A;
+	return platform_driver_register(&msm_camera_driver);
+}
+
+module_init(ov5640_init);
+
+MODULE_DESCRIPTION("OV5640 YUV MIPI sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/ov5640.h b/drivers/media/platform/msm/camera_v1/ov5640.h
new file mode 100644
index 0000000..a428da6
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/ov5640.h
@@ -0,0 +1,2993 @@
+/* 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.
+ */
+
+
+/*
+[SENSOR]
+Sensor Model:   OV5640
+Camera Module:
+Lens Model:
+Driver IC:
+PV Size         = 640 x 480
+Cap Size        = 2592 x 1944
+Output Format   = YUYV
+MCLK Speed      = 24M
+PV DVP_PCLK     = 28M
+Cap DVP_PCLK    = 56M
+PV Frame Rate   = 30fps
+Cap Frame Rate  = 7.5fps
+I2C Slave ID    = 0x78
+I2C Mode        = 16Addr, 8Data
+*/
+
+#ifndef CAMSENSOR_OV5640
+#define CAMSENSOR_OV5640
+
+#define INVMASK(v)  (0xff-v)
+#define OV5640CORE_WRITEPREG(PTBL)	ov5640_writepregs(PTBL,\
+					sizeof(PTBL)/sizeof(PTBL[0]))
+
+/* OV SENSOR SCCB */
+struct ov5640_sensor {
+	uint16_t addr;
+	uint8_t data;
+	uint8_t mask;
+};
+
+/* Auto Focus Command */
+#define OV5640_CMD_MAIN 0x3022
+#define OV5640_CMD_ACK 0x3023
+#define OV5640_CMD_PARA0 0x3024
+#define OV5640_CMD_PARA1 0x3025
+#define OV5640_CMD_PARA2 0x3026
+#define OV5640_CMD_PARA3 0x3027
+#define OV5640_CMD_PARA4 0x3028
+#define OV5640_CMD_FW_STATUS 0x3029
+
+/* Sensor ID */
+#define OV5640_SENSOR_ID 0x5640
+
+#define capture_framerate 750     /* 7.5fps capture frame rate */
+#define g_preview_frameRate 3000  /* 30fps preview frame rate */
+
+struct ov5640_sensor ov5640_init_tbl[] = {
+	{0x3008, 0x42},
+	{0x3103, 0x03},
+	{0x3017, 0x00},
+	{0x3018, 0x00},
+	{0x3034, 0x18},
+	{0x3035, 0x14},
+	{0x3036, 0x38},
+	{0x3037, 0x13},
+	{0x3108, 0x01},
+	{0x3630, 0x36},
+	{0x3631, 0x0e},
+	{0x3632, 0xe2},
+	{0x3633, 0x12},
+	{0x3621, 0xe0},
+	{0x3704, 0xa0},
+	{0x3703, 0x5a},
+	{0x3715, 0x78},
+	{0x3717, 0x01},
+	{0x370b, 0x60},
+	{0x3705, 0x1a},
+	{0x3905, 0x02},
+	{0x3906, 0x10},
+	{0x3901, 0x0a},
+	{0x3731, 0x12},
+	{0x3600, 0x08},
+	{0x3601, 0x33},
+	{0x302d, 0x60},
+	{0x3620, 0x52},
+	{0x371b, 0x20},
+	{0x471c, 0x50},
+	{0x3a13, 0x43},
+	{0x3a18, 0x00},
+	{0x3a19, 0xf8},
+	{0x3635, 0x13},
+	{0x3636, 0x03},
+	{0x3634, 0x40},
+	{0x3622, 0x01},
+	{0x3c01, 0x34},
+	{0x3c04, 0x28},
+	{0x3c05, 0x98},
+	{0x3c06, 0x00},
+	{0x3c07, 0x08},
+	{0x3c08, 0x00},
+	{0x3c09, 0x1c},
+	{0x3c0a, 0x9c},
+	{0x3c0b, 0x40},
+	{0x3820, 0x41},
+	{0x3821, 0x07},
+	{0x3814, 0x31},
+	{0x3815, 0x31},
+	{0x3800, 0x00},
+	{0x3801, 0x00},
+	{0x3802, 0x00},
+	{0x3803, 0x04},
+	{0x3804, 0x0a},
+	{0x3805, 0x3f},
+	{0x3806, 0x07},
+	{0x3807, 0x9b},
+	{0x3808, 0x02},
+	{0x3809, 0x80},
+	{0x380a, 0x01},
+	{0x380b, 0xe0},
+	{0x380c, 0x07},
+	{0x380d, 0x68},
+	{0x380e, 0x03},
+	{0x380f, 0xd8},
+	{0x3810, 0x00},
+	{0x3811, 0x10},
+	{0x3812, 0x00},
+	{0x3813, 0x06},
+	{0x3618, 0x00},
+	{0x3612, 0x29},
+	{0x3708, 0x64},
+	{0x3709, 0x52},
+	{0x370c, 0x03},
+	{0x3a02, 0x03},
+	{0x3a03, 0xd8},
+	{0x3a08, 0x01},
+	{0x3a09, 0x27},
+	{0x3a0a, 0x00},
+	{0x3a0b, 0xf6},
+	{0x3a0e, 0x03},
+	{0x3a0d, 0x04},
+	{0x3a14, 0x03},
+	{0x3a15, 0xd8},
+	{0x4001, 0x02},
+	{0x4004, 0x02},
+	{0x3000, 0x00},
+	{0x3002, 0x1c},
+	{0x3004, 0xff},
+	{0x3006, 0xc3},
+	{0x300e, 0x45},
+	{0x302e, 0x08},
+	{0x4300, 0x30},
+	{0x501f, 0x00},
+	{0x4713, 0x03},
+	{0x4407, 0x04},
+	{0x440e, 0x00},
+	{0x460b, 0x35},
+	{0x460c, 0x22},
+	{0x4837, 0x44},
+	{0x3824, 0x02},
+	{0x5000, 0xa7},
+	{0x5001, 0xa3},
+	{0x5180, 0xff},
+	{0x5181, 0xf2},
+	{0x5182, 0x00},
+	{0x5183, 0x14},
+	{0x5184, 0x25},
+	{0x5185, 0x24},
+	{0x5186, 0x09},
+	{0x5187, 0x09},
+	{0x5188, 0x09},
+	{0x5189, 0x75},
+	{0x518a, 0x54},
+	{0x518b, 0xe0},
+	{0x518c, 0xb2},
+	{0x518d, 0x42},
+	{0x518e, 0x3d},
+	{0x518f, 0x56},
+	{0x5190, 0x46},
+	{0x5191, 0xf8},
+	{0x5192, 0x04},
+	{0x5193, 0x70},
+	{0x5194, 0xf0},
+	{0x5195, 0xf0},
+	{0x5196, 0x03},
+	{0x5197, 0x01},
+	{0x5198, 0x04},
+	{0x5199, 0x12},
+	{0x519a, 0x04},
+	{0x519b, 0x00},
+	{0x519c, 0x06},
+	{0x519d, 0x82},
+	{0x519e, 0x38},
+	{0x5381, 0x1e},
+	{0x5382, 0x5b},
+	{0x5383, 0x08},
+	{0x5384, 0x0a},
+	{0x5385, 0x7e},
+	{0x5386, 0x88},
+	{0x5387, 0x7c},
+	{0x5388, 0x6c},
+	{0x5389, 0x10},
+	{0x538a, 0x01},
+	{0x538b, 0x98},
+	{0x5300, 0x08},
+	{0x5301, 0x30},
+	{0x5302, 0x10},
+	{0x5303, 0x00},
+	{0x5304, 0x08},
+	{0x5305, 0x30},
+	{0x5306, 0x08},
+	{0x5307, 0x16},
+	{0x5309, 0x08},
+	{0x530a, 0x30},
+	{0x530b, 0x04},
+	{0x530c, 0x06},
+	{0x5480, 0x01},
+	{0x5481, 0x08},
+	{0x5482, 0x14},
+	{0x5483, 0x28},
+	{0x5484, 0x51},
+	{0x5485, 0x65},
+	{0x5486, 0x71},
+	{0x5487, 0x7d},
+	{0x5488, 0x87},
+	{0x5489, 0x91},
+	{0x548a, 0x9a},
+	{0x548b, 0xaa},
+	{0x548c, 0xb8},
+	{0x548d, 0xcd},
+	{0x548e, 0xdd},
+	{0x548f, 0xea},
+	{0x5490, 0x1d},
+	{0x5580, 0x02},
+	{0x5583, 0x40},
+	{0x5584, 0x10},
+	{0x5589, 0x10},
+	{0x558a, 0x00},
+	{0x558b, 0xf8},
+	{0x5800, 0x23},
+	{0x5801, 0x14},
+	{0x5802, 0x0f},
+	{0x5803, 0x0f},
+	{0x5804, 0x12},
+	{0x5805, 0x26},
+	{0x5806, 0x0c},
+	{0x5807, 0x08},
+	{0x5808, 0x05},
+	{0x5809, 0x05},
+	{0x580a, 0x08},
+	{0x580b, 0x0d},
+	{0x580c, 0x08},
+	{0x580d, 0x03},
+	{0x580e, 0x00},
+	{0x580f, 0x00},
+	{0x5810, 0x03},
+	{0x5811, 0x09},
+	{0x5812, 0x07},
+	{0x5813, 0x03},
+	{0x5814, 0x00},
+	{0x5815, 0x01},
+	{0x5816, 0x03},
+	{0x5817, 0x08},
+	{0x5818, 0x0d},
+	{0x5819, 0x08},
+	{0x581a, 0x05},
+	{0x581b, 0x06},
+	{0x581c, 0x08},
+	{0x581d, 0x0e},
+	{0x581e, 0x29},
+	{0x581f, 0x17},
+	{0x5820, 0x11},
+	{0x5821, 0x11},
+	{0x5822, 0x15},
+	{0x5823, 0x28},
+	{0x5824, 0x46},
+	{0x5825, 0x26},
+	{0x5826, 0x08},
+	{0x5827, 0x26},
+	{0x5828, 0x64},
+	{0x5829, 0x26},
+	{0x582a, 0x24},
+	{0x582b, 0x22},
+	{0x582c, 0x24},
+	{0x582d, 0x24},
+	{0x582e, 0x06},
+	{0x582f, 0x22},
+	{0x5830, 0x40},
+	{0x5831, 0x42},
+	{0x5832, 0x24},
+	{0x5833, 0x26},
+	{0x5834, 0x24},
+	{0x5835, 0x22},
+	{0x5836, 0x22},
+	{0x5837, 0x26},
+	{0x5838, 0x44},
+	{0x5839, 0x24},
+	{0x583a, 0x26},
+	{0x583b, 0x28},
+	{0x583c, 0x42},
+	{0x583d, 0xce},
+	{0x5025, 0x00},
+	{0x3a0f, 0x30},
+	{0x3a10, 0x28},
+	{0x3a1b, 0x30},
+	{0x3a1e, 0x26},
+	{0x3a11, 0x60},
+	{0x3a1f, 0x14},
+	{0x3008, 0x02},
+};
+
+struct ov5640_sensor ov5640_init_iq_tbl[] = {
+/* Lens correction */
+/* OV5640 LENC setting */
+	{0x5800, 0x3f},
+	{0x5801, 0x20},
+	{0x5802, 0x1a},
+	{0x5803, 0x1a},
+	{0x5804, 0x23},
+	{0x5805, 0x3f},
+	{0x5806, 0x11},
+	{0x5807, 0x0c},
+	{0x5808, 0x09},
+	{0x5809, 0x08},
+	{0x580a, 0x0d},
+	{0x580b, 0x12},
+	{0x580c, 0x0d},
+	{0x580d, 0x04},
+	{0x580e, 0x00},
+	{0x580f, 0x00},
+	{0x5810, 0x05},
+	{0x5811, 0x0d},
+	{0x5812, 0x0d},
+	{0x5813, 0x04},
+	{0x5814, 0x00},
+	{0x5815, 0x00},
+	{0x5816, 0x04},
+	{0x5817, 0x0d},
+	{0x5818, 0x13},
+	{0x5819, 0x0d},
+	{0x581a, 0x08},
+	{0x581b, 0x08},
+	{0x581c, 0x0c},
+	{0x581d, 0x13},
+	{0x581e, 0x3f},
+	{0x581f, 0x1f},
+	{0x5820, 0x1b},
+	{0x5821, 0x1c},
+	{0x5822, 0x23},
+	{0x5823, 0x3f},
+	{0x5824, 0x6a},
+	{0x5825, 0x06},
+	{0x5826, 0x08},
+	{0x5827, 0x06},
+	{0x5828, 0x2a},
+	{0x5829, 0x08},
+	{0x582a, 0x24},
+	{0x582b, 0x24},
+	{0x582c, 0x24},
+	{0x582d, 0x08},
+	{0x582e, 0x08},
+	{0x582f, 0x22},
+	{0x5830, 0x40},
+	{0x5831, 0x22},
+	{0x5832, 0x06},
+	{0x5833, 0x08},
+	{0x5834, 0x24},
+	{0x5835, 0x24},
+	{0x5836, 0x04},
+	{0x5837, 0x0a},
+	{0x5838, 0x86},
+	{0x5839, 0x08},
+	{0x583a, 0x28},
+	{0x583b, 0x28},
+	{0x583c, 0x66},
+	{0x583d, 0xce},
+/* AEC */
+	{0x3a0f, 0x38},
+	{0x3a10, 0x30},
+	{0x3a11, 0x61},
+	{0x3a1b, 0x38},
+	{0x3a1e, 0x30},
+	{0x3a1f, 0x10},
+	/* AWB */
+	{0x5180, 0xff},
+	{0x5181, 0xf2},
+	{0x5182, 0x00},
+	{0x5183, 0x14},
+	{0x5184, 0x25},
+	{0x5185, 0x24},
+	{0x5186, 0x09},
+	{0x5187, 0x09},
+	{0x5188, 0x09},
+	{0x5189, 0x88},
+	{0x518a, 0x54},
+	{0x518b, 0xee},
+	{0x518c, 0xb2},
+	{0x518d, 0x50},
+	{0x518e, 0x34},
+	{0x518f, 0x6b},
+	{0x5190, 0x46},
+	{0x5191, 0xf8},
+	{0x5192, 0x04},
+	{0x5193, 0x70},
+	{0x5194, 0xf0},
+	{0x5195, 0xf0},
+	{0x5196, 0x03},
+	{0x5197, 0x01},
+	{0x5198, 0x04},
+	{0x5199, 0x6c},
+	{0x519a, 0x04},
+	{0x519b, 0x00},
+	{0x519c, 0x09},
+	{0x519d, 0x2b},
+	{0x519e, 0x38},
+
+/* UV Adjust Auto Mode */
+	{0x5580, 0x02},	/* 02 ;Sat enable */
+	{0x5588, 0x01},	/*40 ;enable UV adj */
+	{0x5583, 0x40},	/*	;offset high */
+	{0x5584, 0x18},	/*	;offset low */
+	{0x5589, 0x18},	/*	;gth1	*/
+	{0x558a, 0x00},
+	{0x358b, 0xf8},	/*	;gth2 */
+};
+
+struct ov5640_sensor ov5640_preview_tbl[] = {
+/* @@ MIPI_2lane_5M to vga(YUV) 30fps 99 640 480 98 0 0 */
+	{0x3503, 0x00}, /* enable AE back from capture to preview */
+	{0x3035, 0x14},
+	{0x3036, 0x38},
+	{0x3820, 0x41},
+	{0x3821, 0x07},
+	{0x3814, 0x31},
+	{0x3815, 0x31},
+	{0x3803, 0x04},
+	{0x3807, 0x9b},
+	{0x3808, 0x02},
+	{0x3809, 0x80},
+	{0x380a, 0x01},
+	{0x380b, 0xe0},
+	{0x380c, 0x07},
+	{0x380d, 0x68},
+	{0x380e, 0x03},
+	{0x380f, 0xd8},
+	{0x3813, 0x06},
+	{0x3618, 0x00},
+	{0x3612, 0x29},
+	{0x3708, 0x64},
+	{0x3709, 0x52},
+	{0x370c, 0x03},
+	{0x5001, 0xa3},
+	{0x4004, 0x02},
+	{0x4005, 0x18},
+	{0x4837, 0x44},
+	{0x4713, 0x03},
+	{0x4407, 0x04},
+	{0x460b, 0x35},
+	{0x460c, 0x22},
+	{0x3824, 0x02},
+};
+
+struct ov5640_sensor ov5640_capture_tbl[] = {
+/* @@ MIPI_2lane_5M(YUV) 7.5/15fps 99 2592 1944 98 0 0 */
+	{0x3035, 0x21}, /* 11 */
+	{0x3036, 0x54},
+	{0x3820, 0x40},
+	{0x3821, 0x06},
+	{0x3814, 0x11},
+	{0x3815, 0x11},
+	{0x3803, 0x00},
+	{0x3807, 0x9f},
+	{0x3808, 0x0a},
+	{0x3809, 0x20},
+	{0x380a, 0x07},
+	{0x380b, 0x98},
+	{0x380c, 0x0b},
+	{0x380d, 0x1c},
+	{0x380e, 0x07},
+	{0x380f, 0xb0},
+	{0x3813, 0x04},
+	{0x3618, 0x04},
+	{0x3612, 0x2b},
+	{0x3708, 0x21},
+	{0x3709, 0x12},
+	{0x370c, 0x00},
+	{0x5001, 0x83},
+	{0x4004, 0x06},
+	{0x4005, 0x1a},
+	{0x4837, 0x15}, /* 0a */
+	{0x4713, 0x02},
+	{0x4407, 0x0c},
+	{0x460b, 0x37},
+	{0x460c, 0x20},
+	{0x3824, 0x01},
+};
+
+/* Contrast */
+
+struct ov5640_sensor ov5640_contrast_lv0_tbl[] = {
+/* Contrast -4 */
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5580, 0x04, INVMASK(0x04)}, /* Enable BIT2 for contrast/brightness
+					  control*/
+	{0x5586, 0x10},                /* Gain */
+	{0x5585, 0x10},                /* Offset */
+	{0x5588, 0x00, INVMASK(0x04)}, /* Offset sign */
+};
+
+struct ov5640_sensor ov5640_contrast_lv1_tbl[] = {
+/* Contrast -3 */
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5580, 0x04, INVMASK(0x04)}, /* Enable BIT2 for contrast/brightness
+					  control */
+	{0x5586, 0x14},                /* Gain */
+	{0x5585, 0x14},                /* Offset */
+	{0x5588, 0x00, INVMASK(0x04)}, /* Offset sign */
+};
+
+struct ov5640_sensor ov5640_contrast_lv2_tbl[] = {
+/* Contrast -2 */
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5580, 0x04, INVMASK(0x04)}, /* Enable BIT2 for contrast/brightness
+					  control */
+	{0x5586, 0x18},                /* Gain */
+	{0x5585, 0x18},                /* Offset */
+	{0x5588, 0x00, INVMASK(0x04)}, /* Offset sign */
+};
+
+struct ov5640_sensor ov5640_contrast_lv3_tbl[] = {
+/* Contrast -1 */
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5580, 0x04, INVMASK(0x04)},
+	{0x5586, 0x1c},
+	{0x5585, 0x1c},
+	{0x5588, 0x00, INVMASK(0x04)},
+};
+
+struct ov5640_sensor ov5640_contrast_default_lv4_tbl[] = {
+/* Contrast (Default) */
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5580, 0x04, INVMASK(0x04)},
+	{0x5586, 0x20},
+	{0x5585, 0x00},
+	{0x5588, 0x00, INVMASK(0x04)},
+};
+
+struct ov5640_sensor ov5640_contrast_lv5_tbl[] = {
+/* Contrast +1 */
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5580, 0x04, INVMASK(0x04)},
+	{0x5586, 0x24},
+	{0x5585, 0x10},
+	{0x5588, 0x00, INVMASK(0x04)},
+};
+
+struct ov5640_sensor ov5640_contrast_lv6_tbl[] = {
+/* Contrast +2 */
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5580, 0x04, INVMASK(0x04)},
+	{0x5586, 0x28},
+	{0x5585, 0x18},
+	{0x5588, 0x00, INVMASK(0x04)},
+};
+
+struct ov5640_sensor ov5640_contrast_lv7_tbl[] = {
+/* Contrast +3 */
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5580, 0x04, INVMASK(0x04)},
+	{0x5586, 0x2c},
+	{0x5585, 0x1c},
+	{0x5588, 0x00, INVMASK(0x04)},
+};
+
+struct ov5640_sensor ov5640_contrast_lv8_tbl[] = {
+/* Contrast +4 */
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5580, 0x04, INVMASK(0x04)},
+	{0x5586, 0x30},
+	{0x5585, 0x20},
+	{0x5588, 0x00, INVMASK(0x04)},
+};
+
+/* Sharpness */
+
+struct ov5640_sensor ov5640_sharpness_lv0_tbl[] = {
+/* Sharpness 0 */
+	{0x5308, 0x40, INVMASK(0x40)},
+	{0x5302, 0x00},
+};
+
+struct ov5640_sensor ov5640_sharpness_lv1_tbl[] = {
+/* Sharpness 1 */
+	{0x5308, 0x40, INVMASK(0x40)},
+	{0x5302, 0x02},
+};
+
+struct ov5640_sensor ov5640_sharpness_default_lv2_tbl[] = {
+/* Sharpness_Auto (Default) */
+	{0x5308, 0x00, INVMASK(0x40)},
+	{0x5300, 0x08},
+	{0x5301, 0x30},
+	{0x5302, 0x10},
+	{0x5303, 0x00},
+	{0x5309, 0x08},
+	{0x530a, 0x30},
+	{0x530b, 0x04},
+	{0x530c, 0x06},
+};
+
+struct ov5640_sensor ov5640_sharpness_lv3_tbl[] = {
+/* Sharpness 3 */
+	{0x5308, 0x40, INVMASK(0x40)},
+	{0x5302, 0x08},
+};
+
+struct ov5640_sensor ov5640_sharpness_lv4_tbl[] = {
+/* Sharpness 4 */
+	{0x5308, 0x40, INVMASK(0x40)},
+	{0x5302, 0x0c},
+};
+
+struct ov5640_sensor ov5640_sharpness_lv5_tbl[] = {
+/* Sharpness 5 */
+	{0x5308, 0x40, INVMASK(0x40)},
+	{0x5302, 0x10},
+};
+
+struct ov5640_sensor ov5640_sharpness_lv6_tbl[] = {
+/* Sharpness 6 */
+	{0x5308, 0x40, INVMASK(0x40)},
+	{0x5302, 0x14},
+};
+
+struct ov5640_sensor ov5640_sharpness_lv7_tbl[] = {
+/* Sharpness 7 */
+	{0x5308, 0x40, INVMASK(0x40)},
+	{0x5302, 0x18},
+};
+
+struct ov5640_sensor ov5640_sharpness_lv8_tbl[] = {
+/* Sharpness 8 */
+	{0x5308, 0x40, INVMASK(0x40)},
+	{0x5302, 0x20},
+};
+
+/* Saturation */
+
+struct ov5640_sensor ov5640_saturation_lv0_tbl[] = {
+/* Saturation x0.25 */
+	{0x5001, 0x83, INVMASK(0x80)},  /* SDE_En */
+	{0x5583, 0x00},                 /* Saturaion gain in U */
+	{0x5584, 0x00},                 /* Saturation gain in V */
+	{0x5580, 0x02, INVMASK(0x02)},  /* Saturation enable */
+	{0x5588, 0x40, INVMASK(0x40)},
+};
+
+struct ov5640_sensor ov5640_saturation_lv1_tbl[] = {
+/* Saturation x0.5 */
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5583, 0x10},
+	{0x5584, 0x10},
+	{0x5580, 0x02, INVMASK(0x02)},
+	{0x5588, 0x40, INVMASK(0x40)},
+};
+
+struct ov5640_sensor ov5640_saturation_lv2_tbl[] = {
+/* Saturation x0.75 */
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5583, 0x20},
+	{0x5584, 0x20},
+	{0x5580, 0x02, INVMASK(0x02)},
+	{0x5588, 0x40, INVMASK(0x40)},
+};
+
+struct ov5640_sensor ov5640_saturation_lv3_tbl[] = {
+/* Saturation x0.75 */
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5583, 0x30},
+	{0x5584, 0x30},
+	{0x5580, 0x02, INVMASK(0x02)},
+	{0x5588, 0x40, INVMASK(0x40)},
+};
+
+struct ov5640_sensor ov5640_saturation_default_lv4_tbl[] = {
+/* Saturation x1 (Default) */
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5583, 0x40},
+	{0x5584, 0x40},
+	{0x5580, 0x02, INVMASK(0x02)},
+	{0x5588, 0x40, INVMASK(0x40)},
+};
+
+struct ov5640_sensor ov5640_saturation_lv5_tbl[] = {
+/* Saturation x1.25 */
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5583, 0x50},
+	{0x5584, 0x50},
+	{0x5580, 0x02, INVMASK(0x02)},
+	{0x5588, 0x40, INVMASK(0x40)},
+};
+
+struct ov5640_sensor ov5640_saturation_lv6_tbl[] = {
+/* Saturation x1.5 */
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5583, 0x60},
+	{0x5584, 0x60},
+	{0x5580, 0x02, INVMASK(0x02)},
+	{0x5588, 0x40, INVMASK(0x40)},
+};
+
+struct ov5640_sensor ov5640_saturation_lv7_tbl[] = {
+/* Saturation x1.25 */
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5583, 0x70},
+	{0x5584, 0x70},
+	{0x5580, 0x02, INVMASK(0x02)},
+	{0x5588, 0x40, INVMASK(0x40)},
+};
+
+struct ov5640_sensor ov5640_saturation_lv8_tbl[] = {
+/* Saturation x1.5 */
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5583, 0x80},
+	{0x5584, 0x80},
+	{0x5580, 0x02, INVMASK(0x02)},
+	{0x5588, 0x40, INVMASK(0x40)},
+};
+
+/* Brightness */
+
+struct ov5640_sensor ov5640_brightness_lv0_tbl[] = {
+/* Brightness -4 */
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5587, 0x40},
+	{0x5580, 0x04, INVMASK(0x04)},
+	{0x5588, 0x08, INVMASK(0x08)},
+};
+
+struct ov5640_sensor ov5640_brightness_lv1_tbl[] = {
+/* Brightness -3 */
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5587, 0x30},
+	{0x5580, 0x04, INVMASK(0x04)},
+	{0x5588, 0x08, INVMASK(0x08)},
+};
+
+struct ov5640_sensor ov5640_brightness_lv2_tbl[] = {
+/* Brightness -2 */
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5587, 0x20},
+	{0x5580, 0x04, INVMASK(0x04)},
+	{0x5588, 0x08, INVMASK(0x08)},
+};
+
+struct ov5640_sensor ov5640_brightness_lv3_tbl[] = {
+/* Brightness -1 */
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5587, 0x10},
+	{0x5580, 0x04, INVMASK(0x04)},
+	{0x5588, 0x08, INVMASK(0x08)},
+};
+
+struct ov5640_sensor ov5640_brightness_default_lv4_tbl[] = {
+/* Brightness 0 (Default) */
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5587, 0x00},
+	{0x5580, 0x04, INVMASK(0x04)},
+	{0x5588, 0x00, INVMASK(0x08)},
+};
+
+struct ov5640_sensor ov5640_brightness_lv5_tbl[] = {
+/* Brightness +1 */
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5587, 0x10},
+	{0x5580, 0x04, INVMASK(0x04)},
+	{0x5588, 0x00, INVMASK(0x08)},
+};
+
+struct ov5640_sensor ov5640_brightness_lv6_tbl[] = {
+/* Brightness +2 */
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5587, 0x20},
+	{0x5580, 0x04, INVMASK(0x04)},
+	{0x5588, 0x00, INVMASK(0x08)},
+};
+
+struct ov5640_sensor ov5640_brightness_lv7_tbl[] = {
+/* Brightness +3 */
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5587, 0x30},
+	{0x5580, 0x04, INVMASK(0x04)},
+	{0x5588, 0x00, INVMASK(0x08)},
+};
+
+struct ov5640_sensor ov5640_brightness_lv8_tbl[] = {
+/* Brightness +4 */
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5587, 0x40},
+	{0x5580, 0x04, INVMASK(0x04)},
+	{0x5588, 0x00, INVMASK(0x08)},
+};
+
+/* Exposure Compensation */
+struct ov5640_sensor ov5640_exposure_compensation_lv0_tbl[] = {
+	/* @@ +1.7EV */
+	{0x3a0f, 0x60},
+	{0x3a10, 0x58},
+	{0x3a11, 0xa0},
+	{0x3a1b, 0x60},
+	{0x3a1e, 0x58},
+	{0x3a1f, 0x20},
+};
+
+struct ov5640_sensor ov5640_exposure_compensation_lv1_tbl[] = {
+	/* @@ +1.0EV */
+	{0x3a0f, 0x50},
+	{0x3a10, 0x48},
+	{0x3a11, 0x90},
+	{0x3a1b, 0x50},
+	{0x3a1e, 0x48},
+	{0x3a1f, 0x20},
+};
+
+struct ov5640_sensor ov5640_exposure_compensation_lv2_default_tbl[] = {
+	/* @@ default */
+	{0x3a0f, 0x38},
+	{0x3a10, 0x30},
+	{0x3a11, 0x61},
+	{0x3a1b, 0x38},
+	{0x3a1e, 0x30},
+	{0x3a1f, 0x10},
+};
+
+struct ov5640_sensor ov5640_exposure_compensation_lv3_tbl[] = {
+	/* @@ -1.0EV */
+	{0x3a0f, 0x20},
+	{0x3a10, 0x18},
+	{0x3a11, 0x41},
+	{0x3a1b, 0x20},
+	{0x3a1e, 0x18},
+	{0x3a1f, 0x10},
+};
+
+struct ov5640_sensor ov5640_exposure_compensation_lv4_tbl[] = {
+	/* @@ -1.7EV */
+	{0x3a0f, 0x10},
+	{0x3a10, 0x08},
+	{0x3a11, 0x10},
+	{0x3a1b, 0x08},
+	{0x3a1e, 0x20},
+	{0x3a1f, 0x10},
+};
+
+/* Auto Expourse Weight */
+
+struct ov5640_sensor ov5640_ae_average_tbl[] = {
+  /* Whole Image Average */
+	{0x5688, 0x11}, /* Zone 1/Zone 0 weight */
+	{0x5689, 0x11}, /* Zone 3/Zone 2 weight */
+	{0x569a, 0x11}, /* Zone 5/Zone 4 weight */
+	{0x569b, 0x11}, /* Zone 7/Zone 6 weight */
+	{0x569c, 0x11}, /* Zone 9/Zone 8 weight */
+	{0x569d, 0x11}, /* Zone b/Zone a weight */
+	{0x569e, 0x11}, /* Zone d/Zone c weight */
+	{0x569f, 0x11}, /* Zone f/Zone e weight */
+};
+
+struct ov5640_sensor ov5640_ae_centerweight_tbl[] = {
+  /* Whole Image Center More weight */
+	{0x5688, 0x62},
+	{0x5689, 0x26},
+	{0x568a, 0xe6},
+	{0x568b, 0x6e},
+	{0x568c, 0xea},
+	{0x568d, 0xae},
+	{0x568e, 0xa6},
+	{0x568f, 0x6a},
+};
+
+/* Light Mode */
+struct ov5640_sensor ov5640_wb_def[] = {
+	{0x3406, 0x00, INVMASK(0x01)},
+};
+
+struct ov5640_sensor ov5640_wb_custom[] = {
+	{0x3406, 0x01, INVMASK(0x01)},
+	{0x3400, 0x04},
+	{0x3401, 0x58},
+	{0x3402, 0x04},
+	{0x3403, 0x00},
+	{0x3404, 0x08},
+	{0x3405, 0x40},
+};
+
+struct ov5640_sensor ov5640_wb_inc[] = {
+	{0x3406, 0x01, INVMASK(0x01)},
+	{0x3400, 0x04},
+	{0x3401, 0x88},
+	{0x3402, 0x04},
+	{0x3403, 0x00},
+	{0x3404, 0x08},
+	{0x3405, 0xb6},
+};
+
+struct ov5640_sensor ov5640_wb_daylight[] = {
+	{0x3406, 0x01, INVMASK(0x01)},
+	{0x3400, 0x07},
+	{0x3401, 0x02},
+	{0x3402, 0x04},
+	{0x3403, 0x00},
+	{0x3404, 0x05},
+	{0x3405, 0x15},
+};
+
+struct ov5640_sensor ov5640_wb_cloudy[] = {
+	{0x3406, 0x01, INVMASK(0x01)},
+	{0x3400, 0x07},
+	{0x3401, 0x88},
+	{0x3402, 0x04},
+	{0x3403, 0x00},
+	{0x3404, 0x05},
+	{0x3405, 0x00},
+};
+
+/* EFFECT */
+struct ov5640_sensor ov5640_effect_normal_tbl[] = {
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5580, 0x00, INVMASK(0x78)},
+	{0x5003, 0x08},
+	{0x5583, 0x40},
+	{0x5584, 0x40},
+};
+
+struct ov5640_sensor ov5640_effect_mono_tbl[] = {
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5580, 0x20, INVMASK(0x78)},
+	{0x5003, 0x08},
+	{0x5583, 0x40},
+	{0x5584, 0x40},
+};
+
+struct ov5640_sensor ov5640_effect_bw_tbl[] = {
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5580, 0x18, INVMASK(0x78)},
+	{0x5003, 0x08},
+	{0x5583, 0x80},
+	{0x5584, 0x80},
+};
+
+struct ov5640_sensor ov5640_effect_bluish_tbl[] = {
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5580, 0x18, INVMASK(0x78)},
+	{0x5003, 0x08},
+	{0x5583, 0xa0},
+	{0x5584, 0x40},
+};
+
+struct ov5640_sensor ov5640_effect_solarize_tbl[] = {
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5580, 0x00, INVMASK(0x78)},
+	{0x5003, 0x09},
+};
+
+
+struct ov5640_sensor ov5640_effect_sepia_tbl[] = {
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5580, 0x18, INVMASK(0x78)},
+	{0x5003, 0x08},
+	{0x5583, 0x40},
+	{0x5584, 0xa0},
+};
+
+struct ov5640_sensor ov5640_effect_reddish_tbl[] = {
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5580, 0x18, INVMASK(0x78)},
+	{0x5003, 0x08},
+	{0x5583, 0x80},
+	{0x5584, 0xc0},
+};
+
+struct ov5640_sensor ov5640_effect_greenish_tbl[] = {
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5580, 0x18, INVMASK(0x78)},
+	{0x5003, 0x08},
+	{0x5583, 0x60},
+	{0x5584, 0x60},
+};
+
+struct ov5640_sensor ov5640_effect_negative_tbl[] = {
+	{0x5001, 0x83, INVMASK(0x80)},
+	{0x5580, 0x40, INVMASK(0x78)},
+	{0x5003, 0x08},
+};
+
+/* AntiBanding */
+struct ov5640_sensor ov5640_antibanding_auto_tbl[] = {
+  /* Auto-XCLK24MHz */
+	{0x3622, 0x01}, /* PD-sel */
+	{0x3635, 0x1c}, /* VMREF 3635[2:0] */
+	{0x3634, 0x40}, /* I_5060 3643[2:0] */
+	{0x3c01, 0x34},
+	{0x3c00, 0x00},
+	{0x3c04, 0x28},
+	{0x3c05, 0x98},
+	{0x3c06, 0x00},
+	{0x3c07, 0x08},
+	{0x3c08, 0x00},
+	{0x3c09, 0x1c},
+	{0x300c, 0x22}, /* 50/60div 300c[2:0] */
+	{0x3c0a, 0x9c},
+	{0x3c0b, 0x40},
+};
+
+struct ov5640_sensor ov5640_antibanding_50z_tbl[] = {
+  /* Band 50Hz */
+	{0x3c01, 0x80, INVMASK(0x80)},
+	{0x3c00, 0x04},
+};
+
+struct ov5640_sensor ov5640_antibanding_60z_tbl[] = {
+  /* Band 60Hz */
+	{0x3c01, 0x80, INVMASK(0x80)},
+	{0x3c00, 0x00},
+};
+
+
+/* Lens_shading */
+
+struct ov5640_sensor ov5640_lens_shading_on_tbl[] = {
+	/* @@ Lenc On(C) */
+	{0x5000, 0x80, INVMASK(0x80)},
+};
+
+struct ov5640_sensor ov5640_lens_shading_off_tbl[] = {
+	/*  Lenc Off */
+	{0x5000, 0x00, INVMASK(0x80)},
+};
+
+/* Auto Focus Firmware-use 2011-08-24 firmware settings */
+u8 ov5640_afinit_tbl[] = {
+	0x80,	0x00,	0x02,	0x0b,	0x7b,	0x02,	0x07,	0xbd,	0xc2,
+	0x01,	0x22,	0x22,	0x00,	0x02,	0x0b,	0x57,	0xe5,	0x1f,
+	0x70,	0x72,	0xf5,	0x1e,	0xd2,	0x35,	0xff,	0xef,	0x25,
+	0xe0,	0x24,	0x4b,	0xf8,	0xe4,	0xf6,	0x08,	0xf6,	0x0f,
+	0xbf,	0x34,	0xf2,	0x90,	0x0e,	0x88,	0xe4,	0x93,	0xff,
+	0xe5,	0x49,	0xc3,	0x9f,	0x50,	0x04,	0x7f,	0x05,	0x80,
+	0x02,	0x7f,	0xfb,	0x78,	0xba,	0xa6,	0x07,	0x12,	0x0a,
+	0xb4,	0x40,	0x04,	0x7f,	0x03,	0x80,	0x02,	0x7f,	0x30,
+	0x78,	0xb9,	0xa6,	0x07,	0xe6,	0x18,	0xf6,	0x08,	0xe6,
+	0x78,	0xb6,	0xf6,	0x78,	0xb9,	0xe6,	0x78,	0xb7,	0xf6,
+	0x78,	0xbc,	0x76,	0x33,	0xe4,	0x08,	0xf6,	0x78,	0xb5,
+	0x76,	0x01,	0x75,	0x48,	0x02,	0x78,	0xb3,	0xf6,	0x08,
+	0xf6,	0x74,	0xff,	0x78,	0xbe,	0xf6,	0x08,	0xf6,	0x75,
+	0x1f,	0x01,	0x78,	0xb9,	0xe6,	0x75,	0xf0,	0x05,	0xa4,
+	0xf5,	0x49,	0x12,	0x08,	0x5b,	0xc2,	0x37,	0x22,	0x78,
+	0xb5,	0xe6,	0xd3,	0x94,	0x00,	0x40,	0x02,	0x16,	0x22,
+	0xe5,	0x1f,	0x64,	0x05,	0x70,	0x28,	0xf5,	0x1f,	0xc2,
+	0x01,	0x78,	0xb6,	0xe6,	0x25,	0xe0,	0x24,	0x4b,	0xf8,
+	0xe6,	0xfe,	0x08,	0xe6,	0xff,	0x78,	0x4b,	0xa6,	0x06,
+	0x08,	0xa6,	0x07,	0xa2,	0x37,	0xe4,	0x33,	0xf5,	0x3c,
+	0x90,	0x30,	0x28,	0xf0,	0x75,	0x1e,	0x10,	0xd2,	0x35,
+	0x22,	0xe5,	0x49,	0x75,	0xf0,	0x05,	0x84,	0x78,	0xb9,
+	0xf6,	0x90,	0x0e,	0x85,	0xe4,	0x93,	0xff,	0x25,	0xe0,
+	0x24,	0x0a,	0xf8,	0xe6,	0xfc,	0x08,	0xe6,	0xfd,	0x78,
+	0xb9,	0xe6,	0x25,	0xe0,	0x24,	0x4b,	0xf8,	0xa6,	0x04,
+	0x08,	0xa6,	0x05,	0xef,	0x12,	0x0a,	0xbb,	0xd3,	0x78,
+	0xb4,	0x96,	0xee,	0x18,	0x96,	0x40,	0x0d,	0x78,	0xb9,
+	0xe6,	0x78,	0xb6,	0xf6,	0x78,	0xb3,	0xa6,	0x06,	0x08,
+	0xa6,	0x07,	0x90,	0x0e,	0x85,	0xe4,	0x93,	0x12,	0x0a,
+	0xbb,	0xc3,	0x78,	0xbf,	0x96,	0xee,	0x18,	0x96,	0x50,
+	0x0d,	0x78,	0xb9,	0xe6,	0x78,	0xb7,	0xf6,	0x78,	0xbe,
+	0xa6,	0x06,	0x08,	0xa6,	0x07,	0x78,	0xb3,	0xe6,	0xfe,
+	0x08,	0xe6,	0xc3,	0x78,	0xbf,	0x96,	0xff,	0xee,	0x18,
+	0x96,	0x78,	0xc0,	0xf6,	0x08,	0xa6,	0x07,	0x90,	0x0e,
+	0x8a,	0xe4,	0x18,	0x12,	0x0a,	0x99,	0xc3,	0x33,	0xce,
+	0x33,	0xce,	0xd8,	0xf9,	0xff,	0xd3,	0xed,	0x9f,	0xec,
+	0x9e,	0x40,	0x02,	0xd2,	0x37,	0x78,	0xb9,	0xe6,	0x08,
+	0x26,	0x08,	0xf6,	0xe5,	0x1f,	0x64,	0x01,	0x70,	0x55,
+	0xe6,	0xc3,	0x78,	0xbd,	0x12,	0x0a,	0x8f,	0x40,	0x10,
+	0x12,	0x0a,	0x8a,	0x50,	0x0b,	0x30,	0x37,	0x41,	0x78,
+	0xb9,	0xe6,	0x78,	0xb6,	0x66,	0x60,	0x39,	0x12,	0x0a,
+	0xb2,	0x40,	0x04,	0x7f,	0xfe,	0x80,	0x02,	0x7f,	0x02,
+	0x78,	0xba,	0xa6,	0x07,	0x78,	0xb6,	0xe6,	0x24,	0x03,
+	0x78,	0xbc,	0xf6,	0x78,	0xb6,	0xe6,	0x24,	0xfd,	0x78,
+	0xbd,	0xf6,	0x12,	0x0a,	0xb2,	0x40,	0x06,	0x78,	0xbd,
+	0xe6,	0xff,	0x80,	0x04,	0x78,	0xbc,	0xe6,	0xff,	0x78,
+	0xbb,	0xa6,	0x07,	0x75,	0x1f,	0x02,	0x78,	0xb5,	0x76,
+	0x01,	0x02,	0x02,	0x68,	0xe5,	0x1f,	0x64,	0x02,	0x60,
+	0x03,	0x02,	0x02,	0x48,	0x78,	0xbb,	0xe6,	0xff,	0xc3,
+	0x78,	0xbd,	0x12,	0x0a,	0x90,	0x40,	0x08,	0x12,	0x0a,
+	0x8a,	0x50,	0x03,	0x02,	0x02,	0x46,	0x12,	0x0a,	0xb2,
+	0x40,	0x04,	0x7f,	0xff,	0x80,	0x02,	0x7f,	0x01,	0x78,
+	0xba,	0xa6,	0x07,	0x78,	0xb6,	0xe6,	0x04,	0x78,	0xbc,
+	0xf6,	0x78,	0xb6,	0xe6,	0x14,	0x78,	0xbd,	0xf6,	0x18,
+	0x12,	0x0a,	0xb4,	0x40,	0x04,	0xe6,	0xff,	0x80,	0x02,
+	0x7f,	0x00,	0x78,	0xbc,	0xa6,	0x07,	0xd3,	0x08,	0xe6,
+	0x64,	0x80,	0x94,	0x80,	0x40,	0x04,	0xe6,	0xff,	0x80,
+	0x02,	0x7f,	0x00,	0x78,	0xbd,	0xa6,	0x07,	0xc3,	0x18,
+	0xe6,	0x64,	0x80,	0x94,	0xb3,	0x50,	0x04,	0xe6,	0xff,
+	0x80,	0x02,	0x7f,	0x33,	0x78,	0xbc,	0xa6,	0x07,	0xc3,
+	0x08,	0xe6,	0x64,	0x80,	0x94,	0xb3,	0x50,	0x04,	0xe6,
+	0xff,	0x80,	0x02,	0x7f,	0x33,	0x78,	0xbd,	0xa6,	0x07,
+	0x12,	0x0a,	0xb2,	0x40,	0x06,	0x78,	0xbd,	0xe6,	0xff,
+	0x80,	0x04,	0x78,	0xbc,	0xe6,	0xff,	0x78,	0xbb,	0xa6,
+	0x07,	0x75,	0x1f,	0x03,	0x78,	0xb5,	0x76,	0x01,	0x80,
+	0x20,	0xe5,	0x1f,	0x64,	0x03,	0x70,	0x26,	0x78,	0xbb,
+	0xe6,	0xff,	0xc3,	0x78,	0xbd,	0x12,	0x0a,	0x90,	0x40,
+	0x05,	0x12,	0x0a,	0x8a,	0x40,	0x09,	0x78,	0xb6,	0xe6,
+	0x78,	0xbb,	0xf6,	0x75,	0x1f,	0x04,	0x78,	0xbb,	0xe6,
+	0x75,	0xf0,	0x05,	0xa4,	0xf5,	0x49,	0x02,	0x08,	0x5b,
+	0xe5,	0x1f,	0xb4,	0x04,	0x1d,	0x90,	0x0e,	0x89,	0xe4,
+	0x78,	0xc0,	0x12,	0x0a,	0x99,	0xc3,	0x33,	0xce,	0x33,
+	0xce,	0xd8,	0xf9,	0xff,	0xd3,	0xed,	0x9f,	0xec,	0x9e,
+	0x40,	0x02,	0xd2,	0x37,	0x75,	0x1f,	0x05,	0x22,	0xef,
+	0x8d,	0xf0,	0xa4,	0xa8,	0xf0,	0xcf,	0x8c,	0xf0,	0xa4,
+	0x28,	0xce,	0x8d,	0xf0,	0xa4,	0x2e,	0xfe,	0x22,	0xbc,
+	0x00,	0x0b,	0xbe,	0x00,	0x29,	0xef,	0x8d,	0xf0,	0x84,
+	0xff,	0xad,	0xf0,	0x22,	0xe4,	0xcc,	0xf8,	0x75,	0xf0,
+	0x08,	0xef,	0x2f,	0xff,	0xee,	0x33,	0xfe,	0xec,	0x33,
+	0xfc,	0xee,	0x9d,	0xec,	0x98,	0x40,	0x05,	0xfc,	0xee,
+	0x9d,	0xfe,	0x0f,	0xd5,	0xf0,	0xe9,	0xe4,	0xce,	0xfd,
+	0x22,	0xed,	0xf8,	0xf5,	0xf0,	0xee,	0x84,	0x20,	0xd2,
+	0x1c,	0xfe,	0xad,	0xf0,	0x75,	0xf0,	0x08,	0xef,	0x2f,
+	0xff,	0xed,	0x33,	0xfd,	0x40,	0x07,	0x98,	0x50,	0x06,
+	0xd5,	0xf0,	0xf2,	0x22,	0xc3,	0x98,	0xfd,	0x0f,	0xd5,
+	0xf0,	0xea,	0x22,	0xe8,	0x8f,	0xf0,	0xa4,	0xcc,	0x8b,
+	0xf0,	0xa4,	0x2c,	0xfc,	0xe9,	0x8e,	0xf0,	0xa4,	0x2c,
+	0xfc,	0x8a,	0xf0,	0xed,	0xa4,	0x2c,	0xfc,	0xea,	0x8e,
+	0xf0,	0xa4,	0xcd,	0xa8,	0xf0,	0x8b,	0xf0,	0xa4,	0x2d,
+	0xcc,	0x38,	0x25,	0xf0,	0xfd,	0xe9,	0x8f,	0xf0,	0xa4,
+	0x2c,	0xcd,	0x35,	0xf0,	0xfc,	0xeb,	0x8e,	0xf0,	0xa4,
+	0xfe,	0xa9,	0xf0,	0xeb,	0x8f,	0xf0,	0xa4,	0xcf,	0xc5,
+	0xf0,	0x2e,	0xcd,	0x39,	0xfe,	0xe4,	0x3c,	0xfc,	0xea,
+	0xa4,	0x2d,	0xce,	0x35,	0xf0,	0xfd,	0xe4,	0x3c,	0xfc,
+	0x22,	0x75,	0xf0,	0x08,	0x75,	0x82,	0x00,	0xef,	0x2f,
+	0xff,	0xee,	0x33,	0xfe,	0xcd,	0x33,	0xcd,	0xcc,	0x33,
+	0xcc,	0xc5,	0x82,	0x33,	0xc5,	0x82,	0x9b,	0xed,	0x9a,
+	0xec,	0x99,	0xe5,	0x82,	0x98,	0x40,	0x0c,	0xf5,	0x82,
+	0xee,	0x9b,	0xfe,	0xed,	0x9a,	0xfd,	0xec,	0x99,	0xfc,
+	0x0f,	0xd5,	0xf0,	0xd6,	0xe4,	0xce,	0xfb,	0xe4,	0xcd,
+	0xfa,	0xe4,	0xcc,	0xf9,	0xa8,	0x82,	0x22,	0xb8,	0x00,
+	0xc1,	0xb9,	0x00,	0x59,	0xba,	0x00,	0x2d,	0xec,	0x8b,
+	0xf0,	0x84,	0xcf,	0xce,	0xcd,	0xfc,	0xe5,	0xf0,	0xcb,
+	0xf9,	0x78,	0x18,	0xef,	0x2f,	0xff,	0xee,	0x33,	0xfe,
+	0xed,	0x33,	0xfd,	0xec,	0x33,	0xfc,	0xeb,	0x33,	0xfb,
+	0x10,	0xd7,	0x03,	0x99,	0x40,	0x04,	0xeb,	0x99,	0xfb,
+	0x0f,	0xd8,	0xe5,	0xe4,	0xf9,	0xfa,	0x22,	0x78,	0x18,
+	0xef,	0x2f,	0xff,	0xee,	0x33,	0xfe,	0xed,	0x33,	0xfd,
+	0xec,	0x33,	0xfc,	0xc9,	0x33,	0xc9,	0x10,	0xd7,	0x05,
+	0x9b,	0xe9,	0x9a,	0x40,	0x07,	0xec,	0x9b,	0xfc,	0xe9,
+	0x9a,	0xf9,	0x0f,	0xd8,	0xe0,	0xe4,	0xc9,	0xfa,	0xe4,
+	0xcc,	0xfb,	0x22,	0x75,	0xf0,	0x10,	0xef,	0x2f,	0xff,
+	0xee,	0x33,	0xfe,	0xed,	0x33,	0xfd,	0xcc,	0x33,	0xcc,
+	0xc8,	0x33,	0xc8,	0x10,	0xd7,	0x07,	0x9b,	0xec,	0x9a,
+	0xe8,	0x99,	0x40,	0x0a,	0xed,	0x9b,	0xfd,	0xec,	0x9a,
+	0xfc,	0xe8,	0x99,	0xf8,	0x0f,	0xd5,	0xf0,	0xda,	0xe4,
+	0xcd,	0xfb,	0xe4,	0xcc,	0xfa,	0xe4,	0xc8,	0xf9,	0x22,
+	0xeb,	0x9f,	0xf5,	0xf0,	0xea,	0x9e,	0x42,	0xf0,	0xe9,
+	0x9d,	0x42,	0xf0,	0xe8,	0x9c,	0x45,	0xf0,	0x22,	0xe8,
+	0x60,	0x0f,	0xef,	0xc3,	0x33,	0xff,	0xee,	0x33,	0xfe,
+	0xed,	0x33,	0xfd,	0xec,	0x33,	0xfc,	0xd8,	0xf1,	0x22,
+	0xe4,	0x93,	0xfc,	0x74,	0x01,	0x93,	0xfd,	0x74,	0x02,
+	0x93,	0xfe,	0x74,	0x03,	0x93,	0xff,	0x22,	0xe6,	0xfb,
+	0x08,	0xe6,	0xf9,	0x08,	0xe6,	0xfa,	0x08,	0xe6,	0xcb,
+	0xf8,	0x22,	0xec,	0xf6,	0x08,	0xed,	0xf6,	0x08,	0xee,
+	0xf6,	0x08,	0xef,	0xf6,	0x22,	0xa4,	0x25,	0x82,	0xf5,
+	0x82,	0xe5,	0xf0,	0x35,	0x83,	0xf5,	0x83,	0x22,	0xd0,
+	0x83,	0xd0,	0x82,	0xf8,	0xe4,	0x93,	0x70,	0x12,	0x74,
+	0x01,	0x93,	0x70,	0x0d,	0xa3,	0xa3,	0x93,	0xf8,	0x74,
+	0x01,	0x93,	0xf5,	0x82,	0x88,	0x83,	0xe4,	0x73,	0x74,
+	0x02,	0x93,	0x68,	0x60,	0xef,	0xa3,	0xa3,	0xa3,	0x80,
+	0xdf,	0x90,	0x38,	0x04,	0x78,	0x4f,	0x12,	0x09,	0x50,
+	0x90,	0x38,	0x00,	0xe0,	0xfe,	0xa3,	0xe0,	0xfd,	0xed,
+	0xff,	0xc3,	0x12,	0x09,	0x09,	0x90,	0x38,	0x10,	0x12,
+	0x08,	0xfd,	0x90,	0x38,	0x06,	0x78,	0x51,	0x12,	0x09,
+	0x50,	0x90,	0x38,	0x02,	0xe0,	0xfe,	0xa3,	0xe0,	0xfd,
+	0xed,	0xff,	0xc3,	0x12,	0x09,	0x09,	0x90,	0x38,	0x12,
+	0x12,	0x08,	0xfd,	0xa3,	0xe0,	0xb4,	0x31,	0x07,	0x78,
+	0x4f,	0x79,	0x4f,	0x12,	0x09,	0x66,	0x90,	0x38,	0x14,
+	0xe0,	0xb4,	0x71,	0x15,	0x78,	0x4f,	0xe6,	0xfe,	0x08,
+	0xe6,	0x78,	0x02,	0xce,	0xc3,	0x13,	0xce,	0x13,	0xd8,
+	0xf9,	0x79,	0x50,	0xf7,	0xee,	0x19,	0xf7,	0x90,	0x38,
+	0x15,	0xe0,	0xb4,	0x31,	0x07,	0x78,	0x51,	0x79,	0x51,
+	0x12,	0x09,	0x66,	0x90,	0x38,	0x15,	0xe0,	0xb4,	0x71,
+	0x15,	0x78,	0x51,	0xe6,	0xfe,	0x08,	0xe6,	0x78,	0x02,
+	0xce,	0xc3,	0x13,	0xce,	0x13,	0xd8,	0xf9,	0x79,	0x52,
+	0xf7,	0xee,	0x19,	0xf7,	0x79,	0x4f,	0x12,	0x09,	0x38,
+	0x09,	0x12,	0x09,	0x38,	0xaf,	0x45,	0x12,	0x08,	0xee,
+	0x7d,	0x50,	0x12,	0x02,	0xa9,	0x78,	0x57,	0xa6,	0x06,
+	0x08,	0xa6,	0x07,	0xaf,	0x43,	0x12,	0x08,	0xee,	0x7d,
+	0x50,	0x12,	0x02,	0xa9,	0x78,	0x53,	0xa6,	0x06,	0x08,
+	0xa6,	0x07,	0xaf,	0x46,	0x78,	0x51,	0x12,	0x08,	0xf0,
+	0x7d,	0x3c,	0x12,	0x02,	0xa9,	0x78,	0x59,	0xa6,	0x06,
+	0x08,	0xa6,	0x07,	0xaf,	0x44,	0x7e,	0x00,	0x78,	0x51,
+	0x12,	0x08,	0xf2,	0x7d,	0x3c,	0x12,	0x02,	0xa9,	0x78,
+	0x55,	0xa6,	0x06,	0x08,	0xa6,	0x07,	0xc3,	0x78,	0x58,
+	0xe6,	0x94,	0x08,	0x18,	0xe6,	0x94,	0x00,	0x50,	0x05,
+	0x76,	0x00,	0x08,	0x76,	0x08,	0xc3,	0x78,	0x5a,	0xe6,
+	0x94,	0x08,	0x18,	0xe6,	0x94,	0x00,	0x50,	0x05,	0x76,
+	0x00,	0x08,	0x76,	0x08,	0x78,	0x57,	0x12,	0x09,	0x25,
+	0xff,	0xd3,	0x78,	0x54,	0xe6,	0x9f,	0x18,	0xe6,	0x9e,
+	0x40,	0x0e,	0x78,	0x57,	0xe6,	0x13,	0xfe,	0x08,	0xe6,
+	0x78,	0x54,	0x12,	0x09,	0x5b,	0x80,	0x04,	0x7e,	0x00,
+	0x7f,	0x00,	0x78,	0x5b,	0x12,	0x09,	0x1d,	0xff,	0xd3,
+	0x78,	0x56,	0xe6,	0x9f,	0x18,	0xe6,	0x9e,	0x40,	0x0e,
+	0x78,	0x59,	0xe6,	0x13,	0xfe,	0x08,	0xe6,	0x78,	0x56,
+	0x12,	0x09,	0x5b,	0x80,	0x04,	0x7e,	0x00,	0x7f,	0x00,
+	0xe4,	0xfc,	0xfd,	0x78,	0x5f,	0x12,	0x04,	0x5c,	0x78,
+	0x57,	0x12,	0x09,	0x25,	0x78,	0x54,	0x26,	0xff,	0xee,
+	0x18,	0x36,	0xfe,	0x78,	0x63,	0x12,	0x09,	0x1d,	0x78,
+	0x56,	0x26,	0xff,	0xee,	0x18,	0x36,	0xfe,	0xe4,	0xfc,
+	0xfd,	0x78,	0x67,	0x12,	0x04,	0x5c,	0x12,	0x09,	0x2d,
+	0x78,	0x63,	0x12,	0x04,	0x4f,	0xd3,	0x12,	0x04,	0x1b,
+	0x40,	0x08,	0x12,	0x09,	0x2d,	0x78,	0x63,	0x12,	0x04,
+	0x5c,	0x78,	0x51,	0x12,	0x09,	0x2f,	0x78,	0x67,	0x12,
+	0x04,	0x4f,	0xd3,	0x12,	0x04,	0x1b,	0x40,	0x0a,	0x78,
+	0x51,	0x12,	0x09,	0x2f,	0x78,	0x67,	0x12,	0x04,	0x5c,
+	0xe4,	0xfd,	0x78,	0x5e,	0x12,	0x09,	0x48,	0x24,	0x01,
+	0x12,	0x09,	0x11,	0x78,	0x62,	0x12,	0x09,	0x48,	0x24,
+	0x02,	0x12,	0x09,	0x11,	0x78,	0x66,	0x12,	0x09,	0x48,
+	0x24,	0x03,	0x12,	0x09,	0x11,	0x78,	0x6a,	0x12,	0x09,
+	0x48,	0x24,	0x04,	0x12,	0x09,	0x11,	0x0d,	0xbd,	0x05,
+	0xd4,	0xc2,	0x0e,	0xc2,	0x06,	0x22,	0x85,	0x08,	0x41,
+	0x90,	0x30,	0x24,	0xe0,	0xf5,	0x3d,	0xa3,	0xe0,	0xf5,
+	0x3e,	0xa3,	0xe0,	0xf5,	0x3f,	0xa3,	0xe0,	0xf5,	0x40,
+	0xa3,	0xe0,	0xf5,	0x3c,	0xd2,	0x34,	0xe5,	0x41,	0x12,
+	0x04,	0x74,	0x06,	0xc7,	0x03,	0x06,	0xcb,	0x04,	0x06,
+	0xd1,	0x07,	0x06,	0xda,	0x08,	0x06,	0xeb,	0x12,	0x07,
+	0x03,	0x18,	0x07,	0x19,	0x19,	0x06,	0xee,	0x1a,	0x06,
+	0xfa,	0x1b,	0x07,	0x3e,	0x80,	0x07,	0x43,	0x81,	0x07,
+	0xa1,	0x8f,	0x07,	0x90,	0x90,	0x07,	0xa1,	0x91,	0x07,
+	0xa1,	0x92,	0x07,	0xa1,	0x93,	0x07,	0xa1,	0x94,	0x07,
+	0xa1,	0x98,	0x07,	0x9e,	0x9f,	0x00,	0x00,	0x07,	0xbc,
+	0x12,	0x0a,	0xf4,	0x22,	0x12,	0x0a,	0xf4,	0xd2,	0x03,
+	0x22,	0xa2,	0x37,	0xe4,	0x33,	0xf5,	0x3c,	0x02,	0x07,
+	0xa1,	0xc2,	0x01,	0xc2,	0x02,	0xc2,	0x03,	0x12,	0x09,
+	0x70,	0x75,	0x1e,	0x70,	0xd2,	0x35,	0x02,	0x07,	0xa1,
+	0x02,	0x07,	0x8b,	0x85,	0x40,	0x48,	0x85,	0x3c,	0x49,
+	0x12,	0x08,	0x5b,	0x02,	0x07,	0xa1,	0x85,	0x48,	0x40,
+	0x85,	0x49,	0x3c,	0x02,	0x07,	0xa1,	0xe4,	0xf5,	0x22,
+	0xf5,	0x23,	0x85,	0x40,	0x31,	0x85,	0x3f,	0x30,	0x85,
+	0x3e,	0x2f,	0x85,	0x3d,	0x2e,	0x12,	0x0a,	0xc6,	0x80,
+	0x1f,	0x75,	0x22,	0x00,	0x75,	0x23,	0x01,	0x74,	0xff,
+	0xf5,	0x2d,	0xf5,	0x2c,	0xf5,	0x2b,	0xf5,	0x2a,	0x12,
+	0x0a,	0xc6,	0x85,	0x2d,	0x40,	0x85,	0x2c,	0x3f,	0x85,
+	0x2b,	0x3e,	0x85,	0x2a,	0x3d,	0xe4,	0xf5,	0x3c,	0x02,
+	0x07,	0xa1,	0x12,	0x0b,	0x3d,	0x80,	0x5e,	0x85,	0x3d,
+	0x43,	0x85,	0x3e,	0x44,	0xe5,	0x45,	0xc3,	0x13,	0xff,
+	0xe5,	0x43,	0xc3,	0x9f,	0x50,	0x02,	0x8f,	0x43,	0xe5,
+	0x46,	0xc3,	0x13,	0xff,	0xe5,	0x44,	0xc3,	0x9f,	0x50,
+	0x02,	0x8f,	0x44,	0xe5,	0x45,	0xc3,	0x13,	0xff,	0xfd,
+	0xe5,	0x43,	0x90,	0x0e,	0x7f,	0x12,	0x0b,	0x10,	0x40,
+	0x04,	0xee,	0x9f,	0xf5,	0x43,	0xe5,	0x46,	0xc3,	0x13,
+	0xff,	0xfd,	0xe5,	0x44,	0x90,	0x0e,	0x80,	0x12,	0x0b,
+	0x10,	0x40,	0x04,	0xee,	0x9f,	0xf5,	0x44,	0x12,	0x04,
+	0x9a,	0x80,	0x11,	0x85,	0x40,	0x46,	0x85,	0x3f,	0x45,
+	0x85,	0x3e,	0x44,	0x85,	0x3d,	0x43,	0x80,	0x03,	0x02,
+	0x04,	0x9a,	0x90,	0x30,	0x24,	0xe5,	0x3d,	0xf0,	0xa3,
+	0xe5,	0x3e,	0xf0,	0xa3,	0xe5,	0x3f,	0xf0,	0xa3,	0xe5,
+	0x40,	0xf0,	0xa3,	0xe5,	0x3c,	0xf0,	0x90,	0x30,	0x23,
+	0xe4,	0xf0,	0x22,	0xc0,	0xe0,	0xc0,	0x83,	0xc0,	0x82,
+	0xc0,	0xd0,	0x90,	0x3f,	0x0c,	0xe0,	0xf5,	0x32,	0xe5,
+	0x32,	0x30,	0xe3,	0x4c,	0x30,	0x36,	0x3e,	0x90,	0x60,
+	0x19,
+	0xe0,
+	0xf5,
+	0x0a,
+	0xa3,
+	0xe0,
+	0xf5,
+	0x0b,
+	0x90,
+	0x60,
+	0x1d,
+	0xe0,
+	0xf5,
+	0x14,
+	0xa3,
+	0xe0,
+	0xf5,
+	0x15,
+	0x30,
+	0x01,
+	0x06,
+	0x30,
+	0x33,
+	0x03,
+	0xd3,
+	0x80,
+	0x01,
+	0xc3,
+	0x92,
+	0x09,
+	0x30,
+	0x02,
+	0x06,
+	0x30,
+	0x33,
+	0x03,
+	0xd3,
+	0x80,
+	0x01,
+	0xc3,
+	0x92,
+	0x0a,
+	0x30,
+	0x33,
+	0x0c,
+	0x30,
+	0x03,
+	0x09,
+	0x20,
+	0x02,
+	0x06,
+	0x20,
+	0x01,
+	0x03,
+	0xd3,
+	0x80,
+	0x01,
+	0xc3,
+	0x92,
+	0x0b,
+	0x90,
+	0x30,
+	0x01,
+	0xe0,
+	0x44,
+	0x40,
+	0xf0,
+	0xe0,
+	0x54,
+	0xbf,
+	0xf0,
+	0xe5,
+	0x32,
+	0x30,
+	0xe1,
+	0x14,
+	0x30,
+	0x34,
+	0x11,
+	0x90,
+	0x30,
+	0x22,
+	0xe0,
+	0xf5,
+	0x08,
+	0xe4,
+	0xf0,
+	0x30,
+	0x00,
+	0x03,
+	0xd3,
+	0x80,
+	0x01,
+	0xc3,
+	0x92,
+	0x08,
+	0xe5,
+	0x32,
+	0x30,
+	0xe5,
+	0x12,
+	0x90,
+	0x56,
+	0xa1,
+	0xe0,
+	0xf5,
+	0x09,
+	0x30,
+	0x31,
+	0x09,
+	0x30,
+	0x05,
+	0x03,
+	0xd3,
+	0x80,
+	0x01,
+	0xc3,
+	0x92,
+	0x0d,
+	0x90,
+	0x3f,
+	0x0c,
+	0xe5,
+	0x32,
+	0xf0,
+	0xd0,
+	0xd0,
+	0xd0,
+	0x82,
+	0xd0,
+	0x83,
+	0xd0,
+	0xe0,
+	0x32,
+	0x90,
+	0x0e,
+	0x7d,
+	0xe4,
+	0x93,
+	0xfe,
+	0x74,
+	0x01,
+	0x93,
+	0xff,
+	0xc3,
+	0x90,
+	0x0e,
+	0x7b,
+	0x74,
+	0x01,
+	0x93,
+	0x9f,
+	0xff,
+	0xe4,
+	0x93,
+	0x9e,
+	0xfe,
+	0xe4,
+	0x8f,
+	0x3b,
+	0x8e,
+	0x3a,
+	0xf5,
+	0x39,
+	0xf5,
+	0x38,
+	0xab,
+	0x3b,
+	0xaa,
+	0x3a,
+	0xa9,
+	0x39,
+	0xa8,
+	0x38,
+	0xaf,
+	0x49,
+	0xfc,
+	0xfd,
+	0xfe,
+	0x12,
+	0x02,
+	0xfe,
+	0x12,
+	0x0b,
+	0x22,
+	0xe4,
+	0x7b,
+	0xff,
+	0xfa,
+	0xf9,
+	0xf8,
+	0x12,
+	0x03,
+	0x89,
+	0x12,
+	0x0b,
+	0x22,
+	0x90,
+	0x0e,
+	0x69,
+	0xe4,
+	0x12,
+	0x0b,
+	0x37,
+	0x12,
+	0x0b,
+	0x22,
+	0xe4,
+	0x85,
+	0x48,
+	0x37,
+	0xf5,
+	0x36,
+	0xf5,
+	0x35,
+	0xf5,
+	0x34,
+	0xaf,
+	0x37,
+	0xae,
+	0x36,
+	0xad,
+	0x35,
+	0xac,
+	0x34,
+	0xa3,
+	0x12,
+	0x0b,
+	0x37,
+	0x8f,
+	0x37,
+	0x8e,
+	0x36,
+	0x8d,
+	0x35,
+	0x8c,
+	0x34,
+	0xe5,
+	0x3b,
+	0x45,
+	0x37,
+	0xf5,
+	0x3b,
+	0xe5,
+	0x3a,
+	0x45,
+	0x36,
+	0xf5,
+	0x3a,
+	0xe5,
+	0x39,
+	0x45,
+	0x35,
+	0xf5,
+	0x39,
+	0xe5,
+	0x38,
+	0x45,
+	0x34,
+	0xf5,
+	0x38,
+	0xe4,
+	0xf5,
+	0x22,
+	0xf5,
+	0x23,
+	0x85,
+	0x3b,
+	0x31,
+	0x85,
+	0x3a,
+	0x30,
+	0x85,
+	0x39,
+	0x2f,
+	0x85,
+	0x38,
+	0x2e,
+	0x02,
+	0x0a,
+	0xc6,
+	0x78,
+	0x4f,
+	0x7e,
+	0x00,
+	0xe6,
+	0xfc,
+	0x08,
+	0xe6,
+	0xfd,
+	0x12,
+	0x02,
+	0x97,
+	0x7c,
+	0x00,
+	0x22,
+	0xe0,
+	0xa3,
+	0xe0,
+	0x75,
+	0xf0,
+	0x02,
+	0xa4,
+	0xff,
+	0xae,
+	0xf0,
+	0xc3,
+	0x08,
+	0xe6,
+	0x9f,
+	0xf6,
+	0x18,
+	0xe6,
+	0x9e,
+	0xf6,
+	0x22,
+	0xff,
+	0xe5,
+	0xf0,
+	0x34,
+	0x60,
+	0x8f,
+	0x82,
+	0xf5,
+	0x83,
+	0xec,
+	0xf0,
+	0x22,
+	0xe4,
+	0xfc,
+	0xfd,
+	0x12,
+	0x04,
+	0x5c,
+	0x78,
+	0x59,
+	0xe6,
+	0xc3,
+	0x13,
+	0xfe,
+	0x08,
+	0xe6,
+	0x13,
+	0x22,
+	0x78,
+	0x4f,
+	0xe6,
+	0xfe,
+	0x08,
+	0xe6,
+	0xff,
+	0xe4,
+	0xfc,
+	0xfd,
+	0x22,
+	0xe7,
+	0xc4,
+	0xf8,
+	0x54,
+	0xf0,
+	0xc8,
+	0x68,
+	0xf7,
+	0x09,
+	0xe7,
+	0xc4,
+	0x54,
+	0x0f,
+	0x48,
+	0xf7,
+	0x22,
+	0xe6,
+	0xfc,
+	0xed,
+	0x75,
+	0xf0,
+	0x04,
+	0xa4,
+	0x22,
+	0xe0,
+	0xfe,
+	0xa3,
+	0xe0,
+	0xfd,
+	0xee,
+	0xf6,
+	0xed,
+	0x08,
+	0xf6,
+	0x22,
+	0x13,
+	0xff,
+	0xc3,
+	0xe6,
+	0x9f,
+	0xff,
+	0x18,
+	0xe6,
+	0x9e,
+	0xfe,
+	0x22,
+	0xe6,
+	0xc3,
+	0x13,
+	0xf7,
+	0x08,
+	0xe6,
+	0x13,
+	0x09,
+	0xf7,
+	0x22,
+	0xe4,
+	0xf5,
+	0x49,
+	0x90,
+	0x0e,
+	0x77,
+	0x93,
+	0xff,
+	0xe4,
+	0x8f,
+	0x37,
+	0xf5,
+	0x36,
+	0xf5,
+	0x35,
+	0xf5,
+	0x34,
+	0xaf,
+	0x37,
+	0xae,
+	0x36,
+	0xad,
+	0x35,
+	0xac,
+	0x34,
+	0x90,
+	0x0e,
+	0x6a,
+	0x12,
+	0x0b,
+	0x37,
+	0x8f,
+	0x37,
+	0x8e,
+	0x36,
+	0x8d,
+	0x35,
+	0x8c,
+	0x34,
+	0x90,
+	0x0e,
+	0x72,
+	0x12,
+	0x04,
+	0x3f,
+	0xef,
+	0x45,
+	0x37,
+	0xf5,
+	0x37,
+	0xee,
+	0x45,
+	0x36,
+	0xf5,
+	0x36,
+	0xed,
+	0x45,
+	0x35,
+	0xf5,
+	0x35,
+	0xec,
+	0x45,
+	0x34,
+	0xf5,
+	0x34,
+	0xe4,
+	0xf5,
+	0x22,
+	0xf5,
+	0x23,
+	0x85,
+	0x37,
+	0x31,
+	0x85,
+	0x36,
+	0x30,
+	0x85,
+	0x35,
+	0x2f,
+	0x85,
+	0x34,
+	0x2e,
+	0x12,
+	0x0a,
+	0xc6,
+	0xe4,
+	0xf5,
+	0x22,
+	0xf5,
+	0x23,
+	0x90,
+	0x0e,
+	0x72,
+	0x12,
+	0x0b,
+	0x2b,
+	0x12,
+	0x0a,
+	0xc6,
+	0xe4,
+	0xf5,
+	0x22,
+	0xf5,
+	0x23,
+	0x90,
+	0x0e,
+	0x6e,
+	0x12,
+	0x0b,
+	0x2b,
+	0x02,
+	0x0a,
+	0xc6,
+	0x75,
+	0x89,
+	0x03,
+	0x75,
+	0xa8,
+	0x01,
+	0x75,
+	0xb8,
+	0x04,
+	0x75,
+	0x34,
+	0xff,
+	0x75,
+	0x35,
+	0x0e,
+	0x75,
+	0x36,
+	0x15,
+	0x75,
+	0x37,
+	0x0d,
+	0x12,
+	0x0a,
+	0x4a,
+	0x12,
+	0x00,
+	0x09,
+	0x12,
+	0x0b,
+	0x3d,
+	0x12,
+	0x00,
+	0x06,
+	0xd2,
+	0x00,
+	0xd2,
+	0x34,
+	0xd2,
+	0xaf,
+	0x75,
+	0x34,
+	0xff,
+	0x75,
+	0x35,
+	0x0e,
+	0x75,
+	0x36,
+	0x49,
+	0x75,
+	0x37,
+	0x03,
+	0x12,
+	0x0a,
+	0x4a,
+	0x30,
+	0x08,
+	0x09,
+	0xc2,
+	0x34,
+	0x12,
+	0x06,
+	0x6a,
+	0xc2,
+	0x08,
+	0xd2,
+	0x34,
+	0x30,
+	0x09,
+	0x09,
+	0xc2,
+	0x36,
+	0x12,
+	0x00,
+	0x0e,
+	0xc2,
+	0x09,
+	0xd2,
+	0x36,
+	0x30,
+	0x0e,
+	0x03,
+	0x12,
+	0x04,
+	0x9a,
+	0x30,
+	0x35,
+	0xdf,
+	0x90,
+	0x30,
+	0x29,
+	0xe5,
+	0x1e,
+	0xf0,
+	0xb4,
+	0x10,
+	0x05,
+	0x90,
+	0x30,
+	0x23,
+	0xe4,
+	0xf0,
+	0xc2,
+	0x35,
+	0x80,
+	0xcd,
+	0xae,
+	0x35,
+	0xaf,
+	0x36,
+	0xe4,
+	0xfd,
+	0xed,
+	0xc3,
+	0x95,
+	0x37,
+	0x50,
+	0x33,
+	0x12,
+	0x0b,
+	0x87,
+	0xe4,
+	0x93,
+	0xf5,
+	0x38,
+	0x74,
+	0x01,
+	0x93,
+	0xf5,
+	0x39,
+	0x45,
+	0x38,
+	0x60,
+	0x23,
+	0x85,
+	0x39,
+	0x82,
+	0x85,
+	0x38,
+	0x83,
+	0xe0,
+	0xfc,
+	0x12,
+	0x0b,
+	0x87,
+	0x74,
+	0x03,
+	0x93,
+	0x52,
+	0x04,
+	0x12,
+	0x0b,
+	0x87,
+	0x74,
+	0x02,
+	0x93,
+	0x42,
+	0x04,
+	0x85,
+	0x39,
+	0x82,
+	0x85,
+	0x38,
+	0x83,
+	0xec,
+	0xf0,
+	0x0d,
+	0x80,
+	0xc7,
+	0x22,
+	0x78,
+	0xbb,
+	0xe6,
+	0xd3,
+	0x08,
+	0xff,
+	0xe6,
+	0x64,
+	0x80,
+	0xf8,
+	0xef,
+	0x64,
+	0x80,
+	0x98,
+	0x22,
+	0x93,
+	0xff,
+	0x7e,
+	0x00,
+	0xe6,
+	0xfc,
+	0x08,
+	0xe6,
+	0xfd,
+	0x12,
+	0x02,
+	0x97,
+	0xac,
+	0x06,
+	0xad,
+	0x07,
+	0x78,
+	0xb3,
+	0xe6,
+	0xfe,
+	0x08,
+	0xe6,
+	0x78,
+	0x03,
+	0x22,
+	0x78,
+	0xba,
+	0xd3,
+	0xe6,
+	0x64,
+	0x80,
+	0x94,
+	0x80,
+	0x22,
+	0x25,
+	0xe0,
+	0x24,
+	0x0a,
+	0xf8,
+	0xe6,
+	0xfe,
+	0x08,
+	0xe6,
+	0xff,
+	0x22,
+	0xa2,
+	0xaf,
+	0x92,
+	0x32,
+	0xc2,
+	0xaf,
+	0xe5,
+	0x23,
+	0x45,
+	0x22,
+	0x90,
+	0x0e,
+	0x5d,
+	0x60,
+	0x0e,
+	0x12,
+	0x0b,
+	0x70,
+	0xe0,
+	0xf5,
+	0x2c,
+	0x12,
+	0x0b,
+	0x6d,
+	0xe0,
+	0xf5,
+	0x2d,
+	0x80,
+	0x0c,
+	0x12,
+	0x0b,
+	0x70,
+	0xe5,
+	0x30,
+	0xf0,
+	0x12,
+	0x0b,
+	0x6d,
+	0xe5,
+	0x31,
+	0xf0,
+	0xa2,
+	0x32,
+	0x92,
+	0xaf,
+	0x22,
+	0xd2,
+	0x01,
+	0xc2,
+	0x02,
+	0xe4,
+	0xf5,
+	0x1f,
+	0xf5,
+	0x1e,
+	0xd2,
+	0x35,
+	0xd2,
+	0x33,
+	0xd2,
+	0x36,
+	0xd2,
+	0x01,
+	0xc2,
+	0x02,
+	0xf5,
+	0x1f,
+	0xf5,
+	0x1e,
+	0xd2,
+	0x35,
+	0xd2,
+	0x33,
+	0x22,
+	0x2d,
+	0xfd,
+	0xe4,
+	0x33,
+	0xfc,
+	0xe4,
+	0x93,
+	0xfe,
+	0xfb,
+	0xd3,
+	0xed,
+	0x9b,
+	0x74,
+	0x80,
+	0xf8,
+	0x6c,
+	0x98,
+	0x22,
+	0x8f,
+	0x3b,
+	0x8e,
+	0x3a,
+	0x8d,
+	0x39,
+	0x8c,
+	0x38,
+	0x22,
+	0x12,
+	0x04,
+	0x3f,
+	0x8f,
+	0x31,
+	0x8e,
+	0x30,
+	0x8d,
+	0x2f,
+	0x8c,
+	0x2e,
+	0x22,
+	0x93,
+	0xf9,
+	0xf8,
+	0x02,
+	0x04,
+	0x2c,
+	0x90,
+	0x0e,
+	0x81,
+	0x12,
+	0x04,
+	0x3f,
+	0x8f,
+	0x46,
+	0x8e,
+	0x45,
+	0x8d,
+	0x44,
+	0x8c,
+	0x43,
+	0xd2,
+	0x06,
+	0x30,
+	0x06,
+	0x03,
+	0xd3,
+	0x80,
+	0x01,
+	0xc3,
+	0x92,
+	0x0e,
+	0x22,
+	0xc0,
+	0xe0,
+	0xc0,
+	0x83,
+	0xc0,
+	0x82,
+	0x90,
+	0x3f,
+	0x0d,
+	0xe0,
+	0xf5,
+	0x33,
+	0xe5,
+	0x33,
+	0xf0,
+	0xd0,
+	0x82,
+	0xd0,
+	0x83,
+	0xd0,
+	0xe0,
+	0x32,
+	0x90,
+	0x0e,
+	0x5f,
+	0xe4,
+	0x93,
+	0xfe,
+	0x74,
+	0x01,
+	0x93,
+	0xf5,
+	0x82,
+	0x8e,
+	0x83,
+	0x22,
+	0x78,
+	0x7f,
+	0xe4,
+	0xf6,
+	0xd8,
+	0xfd,
+	0x75,
+	0x81,
+	0xca,
+	0x02,
+	0x09,
+	0xe1,
+	0x8f,
+	0x82,
+	0x8e,
+	0x83,
+	0x75,
+	0xf0,
+	0x04,
+	0xed,
+	0x02,
+	0x04,
+	0x68,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x11,
+	0x07,
+	0x21,
+	0x15,
+	0x29,
+	0x13,
+	0x4f,
+	0x56,
+	0x54,
+	0x20,
+	0x20,
+	0x20,
+	0x20,
+	0x20,
+	0x20,
+	0x01,
+	0x10,
+	0x00,
+	0x56,
+	0x40,
+	0x1a,
+	0x30,
+	0x29,
+	0x7e,
+	0x00,
+	0x30,
+	0x04,
+	0x20,
+	0xdf,
+	0x30,
+	0x05,
+	0x40,
+	0xbf,
+	0x50,
+	0x03,
+	0x00,
+	0xfd,
+	0x50,
+	0x27,
+	0x01,
+	0xfe,
+	0x60,
+	0x00,
+	0x11,
+	0x00,
+	0x3f,
+	0x05,
+	0x30,
+	0x00,
+	0x3f,
+	0x06,
+	0x22,
+	0x00,
+	0x3f,
+	0x01,
+	0x2a,
+	0x00,
+	0x3f,
+	0x02,
+	0x00,
+	0x00,
+	0x36,
+	0x06,
+	0x07,
+	0x00,
+	0x3f,
+	0x0b,
+	0x0f,
+	0xf0,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x30,
+	0x01,
+	0x40,
+	0xbf,
+	0x30,
+	0x01,
+	0x00,
+	0xbf,
+	0x30,
+	0x29,
+	0x70,
+	0x00,
+	0x3a,
+	0x00,
+	0x00,
+	0xff,
+	0x3a,
+	0x00,
+	0x00,
+	0xff,
+	0x36,
+	0x03,
+	0x36,
+	0x02,
+	0x41,
+	0x44,
+	0x58,
+	0x20,
+	0x18,
+	0x10,
+	0x0a,
+	0x04,
+	0x04,
+	0x00,
+	0x03,
+	0xff,
+	0x64,
+	0x00,
+	0x00,
+	0x80,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x02,
+	0x04,
+	0x06,
+	0x00,
+	0x03,
+	0x98,
+	0x00,
+	0xcc,
+	0x50,
+	0x3c,
+	0x28,
+	0x1e,
+	0x10,
+	0x10,
+	0x00,
+	0x00,
+	0x00,
+	0x6e,
+	0x30,
+	0x28,
+	0x00,
+	0xa5,
+	0x5a,
+	0x00,
+};
+
+#endif /* CAMSENSOR_OV5640 */
diff --git a/drivers/media/platform/msm/camera_v1/ov5647.c b/drivers/media/platform/msm/camera_v1/ov5647.c
new file mode 100644
index 0000000..365faef
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/ov5647.c
@@ -0,0 +1,1201 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/debugfs.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/bitops.h>
+#include <linux/leds.h>
+#include <mach/camera.h>
+#include <media/msm_camera.h>
+#include "ov5647.h"
+
+/* 16bit address - 8 bit context register structure */
+#define Q8	0x00000100
+#define Q10	0x00000400
+
+#define REG_OV5647_GAIN_MSB           0x350A
+#define REG_OV5647_GAIN_LSB           0x350B
+#define REG_OV5647_LINE_HSB           0x3500
+#define REG_OV5647_LINE_MSB           0x3501
+#define REG_OV5647_LINE_LSB           0x3502
+
+/* MCLK */
+#define OV5647_MASTER_CLK_RATE 24000000
+
+/* AF Total steps parameters */
+#define OV5647_TOTAL_STEPS_NEAR_TO_FAR	32
+
+#define OV5647_REG_PREV_FRAME_LEN_1	31
+#define OV5647_REG_PREV_FRAME_LEN_2	32
+#define OV5647_REG_PREV_LINE_LEN_1	33
+#define OV5647_REG_PREV_LINE_LEN_2	34
+
+#define OV5647_REG_SNAP_FRAME_LEN_1	15
+#define OV5647_REG_SNAP_FRAME_LEN_2	16
+#define OV5647_REG_SNAP_LINE_LEN_1	17
+#define OV5647_REG_SNAP_LINE_LEN_2	18
+#define MSB                             1
+#define LSB                             0
+
+/* Debug switch */
+#ifdef CDBG
+#undef CDBG
+#endif
+#ifdef CDBG_HIGH
+#undef CDBG_HIGH
+#endif
+
+/*#define OV5647_VERBOSE_DGB*/
+
+#ifdef OV5647_VERBOSE_DGB
+#define CDBG(fmt, args...) pr_debug(fmt, ##args)
+#define CDBG_HIGH(fmt, args...) pr_debug(fmt, ##args)
+#else
+#define CDBG(fmt, args...) do { } while (0)
+#define CDBG_HIGH(fmt, args...) pr_debug(fmt, ##args)
+#endif
+
+/*for debug*/
+#ifdef CDBG
+#undef CDBG
+#endif
+#define CDBG(fmt, args...) printk(fmt, ##args)
+
+static uint8_t  mode_mask = 0x09;
+struct ov5647_work_t {
+	struct work_struct work;
+};
+
+static struct ov5647_work_t *ov5647_sensorw;
+static struct ov5647_work_t *ov5647_af_sensorw;
+static struct i2c_client *ov5647_af_client;
+static struct i2c_client *ov5647_client;
+
+struct ov5647_ctrl_t {
+	const struct  msm_camera_sensor_info *sensordata;
+
+	uint32_t sensormode;
+	uint32_t fps_divider;/* init to 1 * 0x00000400 */
+	uint32_t pict_fps_divider;/* init to 1 * 0x00000400 */
+	uint16_t fps;
+
+	uint16_t curr_lens_pos;
+	uint16_t curr_step_pos;
+	uint16_t my_reg_gain;
+	uint32_t my_reg_line_count;
+	uint16_t total_lines_per_frame;
+
+	enum ov5647_resolution_t prev_res;
+	enum ov5647_resolution_t pict_res;
+	enum ov5647_resolution_t curr_res;
+	enum ov5647_test_mode_t  set_test;
+};
+
+static bool CSI_CONFIG;
+static struct ov5647_ctrl_t *ov5647_ctrl;
+
+static DECLARE_WAIT_QUEUE_HEAD(ov5647_wait_queue);
+static DECLARE_WAIT_QUEUE_HEAD(ov5647_af_wait_queue);
+DEFINE_MUTEX(ov5647_mut);
+
+static uint16_t prev_line_length_pck;
+static uint16_t prev_frame_length_lines;
+static uint16_t snap_line_length_pck;
+static uint16_t snap_frame_length_lines;
+
+static int ov5647_i2c_rxdata(unsigned short saddr,
+		unsigned char *rxdata, int length)
+{
+	struct i2c_msg msgs[] = {
+		{
+			.addr  = saddr,
+			.flags = 0,
+			.len   = 2,
+			.buf   = rxdata,
+		},
+		{
+			.addr  = saddr,
+			.flags = I2C_M_RD,
+			.len   = 1,
+			.buf   = rxdata,
+		},
+	};
+	if (i2c_transfer(ov5647_client->adapter, msgs, 2) < 0) {
+		CDBG("ov5647_i2c_rxdata faild 0x%x\n", saddr);
+		return -EIO;
+	}
+	return 0;
+}
+
+static int32_t ov5647_i2c_txdata(unsigned short saddr,
+		unsigned char *txdata, int length)
+{
+	struct i2c_msg msg[] = {
+		{
+			.addr = saddr,
+			.flags = 0,
+			.len = length,
+			.buf = txdata,
+		},
+	};
+	if (i2c_transfer(ov5647_client->adapter, msg, 1) < 0) {
+		CDBG("ov5647_i2c_txdata faild 0x%x\n", saddr);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t ov5647_i2c_read(unsigned short raddr,
+		unsigned short *rdata)
+{
+	int32_t rc = 0;
+	unsigned char buf[2];
+
+	if (!rdata)
+		return -EIO;
+	CDBG("%s:saddr:0x%x raddr:0x%x data:0x%x",
+		__func__, ov5647_client->addr, raddr, *rdata);
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (raddr & 0xFF00) >> 8;
+	buf[1] = (raddr & 0x00FF);
+	rc = ov5647_i2c_rxdata(ov5647_client->addr >> 1, buf, 1);
+	if (rc < 0) {
+		CDBG("ov5647_i2c_read 0x%x failed!\n", raddr);
+		return rc;
+	}
+	*rdata = buf[0];
+	CDBG("ov5647_i2c_read 0x%x val = 0x%x!\n", raddr, *rdata);
+
+	return rc;
+}
+
+static int32_t ov5647_i2c_write_b_sensor(unsigned short waddr, uint8_t bdata)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[3];
+
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00) >> 8;
+	buf[1] = (waddr & 0x00FF);
+	buf[2] = bdata;
+	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
+	rc = ov5647_i2c_txdata(ov5647_client->addr >> 1, buf, 3);
+	if (rc < 0) {
+		pr_err("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
+				waddr, bdata);
+	}
+	return rc;
+}
+
+static int32_t ov5647_i2c_write_b_table(struct ov5647_i2c_reg_conf const
+		*reg_conf_tbl, int num)
+{
+	int i;
+	int32_t rc = -EIO;
+
+	for (i = 0; i < num; i++) {
+		rc = ov5647_i2c_write_b_sensor(reg_conf_tbl->waddr,
+				reg_conf_tbl->wdata);
+		if (rc < 0)
+			break;
+		reg_conf_tbl++;
+	}
+	return rc;
+}
+
+static int32_t ov5647_af_i2c_txdata(unsigned short saddr,
+		unsigned char *txdata, int length)
+{
+	struct i2c_msg msg[] = {
+		{
+			.addr = saddr,
+			.flags = 0,
+			.len = length,
+			.buf = txdata,
+		},
+	};
+	if (i2c_transfer(ov5647_af_client->adapter, msg, 1) < 0) {
+		pr_err("ov5647_af_i2c_txdata faild 0x%x\n", saddr);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t ov5647_af_i2c_write_b_sensor(uint8_t waddr, uint8_t bdata)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[2];
+
+	memset(buf, 0, sizeof(buf));
+	buf[0] = waddr;
+	buf[1] = bdata;
+	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
+	rc = ov5647_af_i2c_txdata(ov5647_af_client->addr, buf, 2);
+	if (rc < 0) {
+		pr_err("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
+				waddr, bdata);
+	}
+	return rc;
+}
+
+static void ov5647_start_stream(void)
+{
+	CDBG("CAMERA_DBG: 0x4202 0x0, stream on...\r\n");
+	ov5647_i2c_write_b_sensor(0x4202, 0x00);/* streaming on */
+}
+
+static void ov5647_stop_stream(void)
+{
+	CDBG("CAMERA_DBG: 0x4202 0xf, stream off...\r\n");
+	ov5647_i2c_write_b_sensor(0x4202, 0x0f);/* streaming off */
+}
+
+static void ov5647_group_hold_on(void)
+{
+	ov5647_i2c_write_b_sensor(0x0104, 0x01);
+}
+
+static void ov5647_group_hold_off(void)
+{
+	ov5647_i2c_write_b_sensor(0x0104, 0x0);
+}
+
+static void ov5647_get_pict_fps(uint16_t fps, uint16_t *pfps)
+{
+	/* input fps is preview fps in Q8 format */
+	uint32_t divider, d1, d2;
+	uint32_t preview_pclk = 0x37, snapshot_pclk = 0x4f;
+
+	d1 = (prev_frame_length_lines * 0x00000400) / snap_frame_length_lines;
+	d2 = (prev_line_length_pck * 0x00000400) / snap_line_length_pck;
+	divider = (d1 * d2*preview_pclk/snapshot_pclk) / 0x400;
+	CDBG(KERN_ERR "ov5647_get_pict_fps divider = %d", divider);
+	/*Verify PCLK settings and frame sizes.*/
+	*pfps = (uint16_t) (fps * divider / 0x400);
+}
+
+static uint16_t ov5647_get_prev_lines_pf(void)
+{
+	if (ov5647_ctrl->prev_res == QTR_SIZE)
+		return prev_frame_length_lines;
+	else
+		return snap_frame_length_lines;
+}
+
+static uint16_t ov5647_get_prev_pixels_pl(void)
+{
+	if (ov5647_ctrl->prev_res == QTR_SIZE)
+		return prev_line_length_pck;
+	else
+		return snap_line_length_pck;
+}
+
+static uint16_t ov5647_get_pict_lines_pf(void)
+{
+	if (ov5647_ctrl->pict_res == QTR_SIZE)
+		return prev_frame_length_lines;
+	else
+		return snap_frame_length_lines;
+}
+
+static uint16_t ov5647_get_pict_pixels_pl(void)
+{
+	if (ov5647_ctrl->pict_res == QTR_SIZE)
+		return prev_line_length_pck;
+	else
+		return snap_line_length_pck;
+}
+
+static uint32_t ov5647_get_pict_max_exp_lc(void)
+{
+	return snap_frame_length_lines * 24;
+}
+
+static int32_t ov5647_set_fps(struct fps_cfg   *fps)
+{
+	uint16_t total_lines_per_frame;
+	int32_t rc = 0;
+
+	ov5647_ctrl->fps_divider = fps->fps_div;
+	ov5647_ctrl->pict_fps_divider = fps->pict_fps_div;
+
+	if (ov5647_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
+		total_lines_per_frame = (uint16_t)
+		((prev_frame_length_lines * ov5647_ctrl->fps_divider) / 0x400);
+	} else {
+		total_lines_per_frame = (uint16_t)
+		((snap_frame_length_lines * ov5647_ctrl->fps_divider) / 0x400);
+	}
+
+	ov5647_group_hold_on();
+	rc = ov5647_i2c_write_b_sensor(0x0340,
+			((total_lines_per_frame & 0xFF00) >> 8));
+	rc = ov5647_i2c_write_b_sensor(0x0341,
+			(total_lines_per_frame & 0x00FF));
+	ov5647_group_hold_off();
+
+	return rc;
+}
+
+static inline uint8_t ov5647_byte(uint16_t word, uint8_t offset)
+{
+	return word >> (offset * BITS_PER_BYTE);
+}
+
+static int32_t ov5647_write_exp_gain(uint16_t gain, uint32_t line)
+{
+	int rc = 0;
+	uint16_t max_line;
+	u8 intg_time_hsb, intg_time_msb, intg_time_lsb;
+	uint8_t gain_lsb, gain_hsb;
+	ov5647_ctrl->my_reg_gain = gain;
+	ov5647_ctrl->my_reg_line_count = (uint16_t)line;
+
+	CDBG(KERN_ERR "preview exposure setting 0x%x, 0x%x, %d",
+		 gain, line, line);
+
+	gain_lsb = (uint8_t) (ov5647_ctrl->my_reg_gain);
+	gain_hsb = (uint8_t)((ov5647_ctrl->my_reg_gain & 0x300)>>8);
+	/* adjust frame rate */
+	if (line > 980) {
+		rc = ov5647_i2c_write_b_sensor(0x380E,
+			 (uint8_t)((line+4) >> 8)) ;
+		rc = ov5647_i2c_write_b_sensor(0x380F,
+			 (uint8_t)((line+4) & 0x00FF)) ;
+		max_line = line + 4;
+	} else if (max_line > 984) {
+		rc = ov5647_i2c_write_b_sensor(0x380E,
+			 (uint8_t)(984 >> 8)) ;
+		rc = ov5647_i2c_write_b_sensor(0x380F,
+			 (uint8_t)(984 & 0x00FF)) ;
+		max_line = 984;
+	}
+
+	line = line<<4;
+	/* ov5647 need this operation */
+	intg_time_hsb = (u8)(line>>16);
+	intg_time_msb = (u8) ((line & 0xFF00) >> 8);
+	intg_time_lsb = (u8) (line & 0x00FF);
+
+	ov5647_group_hold_on();
+	rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_HSB, intg_time_hsb) ;
+	rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_MSB, intg_time_msb) ;
+	rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_LSB, intg_time_lsb) ;
+
+	rc = ov5647_i2c_write_b_sensor(REG_OV5647_GAIN_MSB, gain_hsb) ;
+	rc = ov5647_i2c_write_b_sensor(REG_OV5647_GAIN_LSB, gain_lsb) ;
+	ov5647_group_hold_off();
+
+	return rc;
+}
+
+
+static int32_t ov5647_set_pict_exp_gain(uint16_t gain, uint32_t line)
+{
+	uint16_t max_line;
+	int rc = 0;
+	uint8_t gain_lsb, gain_hsb;
+	u8 intg_time_hsb, intg_time_msb, intg_time_lsb;
+
+	ov5647_ctrl->my_reg_gain = gain;
+	ov5647_ctrl->my_reg_line_count = (uint16_t)line;
+
+	gain_lsb = (uint8_t) (ov5647_ctrl->my_reg_gain);
+	gain_hsb = (uint8_t)((ov5647_ctrl->my_reg_gain & 0x300)>>8);
+
+	CDBG(KERN_ERR "snapshot exposure seting 0x%x, 0x%x, %d"
+		, gain, line, line);
+
+	if (line > 1964) {
+		rc = ov5647_i2c_write_b_sensor(0x380E,
+			 (uint8_t)((line+4) >> 8)) ;
+		rc = ov5647_i2c_write_b_sensor(0x380F,
+			 (uint8_t)((line+4) & 0x00FF)) ;
+		max_line = line + 4;
+	} else if (max_line > 1968) {
+		rc = ov5647_i2c_write_b_sensor(0x380E,
+			 (uint8_t)(1968 >> 8)) ;
+		rc = ov5647_i2c_write_b_sensor(0x380F,
+			 (uint8_t)(1968 & 0x00FF)) ;
+		max_line = 1968;
+	}
+	line = line<<4;
+	/* ov5647 need this operation */
+	intg_time_hsb = (u8)(line>>16);
+	intg_time_msb = (u8) ((line & 0xFF00) >> 8);
+	intg_time_lsb = (u8) (line & 0x00FF);
+
+	/* FIXME for BLC trigger */
+	ov5647_group_hold_on();
+	rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_HSB, intg_time_hsb) ;
+	rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_MSB, intg_time_msb) ;
+	rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_LSB, intg_time_lsb) ;
+
+	rc = ov5647_i2c_write_b_sensor(REG_OV5647_GAIN_MSB, gain_hsb) ;
+	rc = ov5647_i2c_write_b_sensor(REG_OV5647_GAIN_LSB, gain_lsb - 1) ;
+
+	rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_HSB, intg_time_hsb) ;
+	rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_MSB, intg_time_msb) ;
+	rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_LSB, intg_time_lsb) ;
+
+	rc = ov5647_i2c_write_b_sensor(REG_OV5647_GAIN_MSB, gain_hsb) ;
+	rc = ov5647_i2c_write_b_sensor(REG_OV5647_GAIN_LSB, gain_lsb) ;
+	ov5647_group_hold_off();
+
+	msleep(500);
+	return rc;
+
+}
+
+static int32_t ov5647_move_focus(int direction, int32_t num_steps)
+{
+	uint8_t   code_val_msb = 0;
+	uint8_t   code_val_lsb = 0;
+	int16_t   step_direction, actual_step, next_position;
+	int rc;
+
+	if (num_steps == 0)
+		return 0;
+
+	if (direction == MOVE_NEAR)
+		step_direction = 20;
+	else if (direction == MOVE_FAR)
+		step_direction = -20;
+	else
+		return -EINVAL;
+
+	actual_step = (int16_t)(step_direction * num_steps);
+	next_position = (int16_t)ov5647_ctrl->curr_lens_pos + actual_step;
+	if (next_position < 0) {
+		CDBG(KERN_ERR "%s: OV5647 position(=%d) out of range",
+			__func__, next_position);
+		next_position = 0;
+	}
+	if (next_position > 0x3FF) {
+		CDBG(KERN_ERR "%s: OV5647 position(=%d) out of range",
+			__func__, next_position);
+		next_position = 0x3FF;
+	}
+	ov5647_ctrl->curr_lens_pos = next_position;
+
+	code_val_msb = (uint8_t)((ov5647_ctrl->curr_lens_pos & 0x03FF) >> 4);
+	code_val_lsb = (uint8_t)((ov5647_ctrl->curr_lens_pos & 0x000F) << 4);
+	code_val_lsb |= mode_mask;
+
+	rc = ov5647_af_i2c_write_b_sensor(code_val_msb, code_val_lsb);
+	/* DAC Setting */
+	if (rc != 0) {
+		CDBG(KERN_ERR "%s: WRITE ERROR lsb = 0x%x, msb = 0x%x",
+			__func__, code_val_lsb, code_val_msb);
+	} else {
+		CDBG(KERN_ERR "%s: Successful lsb = 0x%x, msb = 0x%x",
+			__func__, code_val_lsb, code_val_msb);
+		/* delay may set based on the steps moved
+		when I2C write successful */
+		msleep(100);
+	}
+	return 0;
+}
+
+static int32_t ov5647_set_default_focus(uint8_t af_step)
+{
+	uint8_t  code_val_msb = 0;
+	uint8_t  code_val_lsb = 0;
+	int rc = 0;
+
+	ov5647_ctrl->curr_lens_pos = 200;
+
+
+	code_val_msb = (ov5647_ctrl->curr_lens_pos & 0x03FF) >> 4;
+	code_val_lsb = (ov5647_ctrl->curr_lens_pos & 0x000F) << 4;
+	code_val_lsb |= mode_mask;
+
+	CDBG(KERN_ERR "ov5647_set_default_focus:lens pos = %d",
+		 ov5647_ctrl->curr_lens_pos);
+	rc = ov5647_af_i2c_write_b_sensor(code_val_msb, code_val_lsb);
+	/* DAC Setting */
+	if (rc != 0)
+		CDBG(KERN_ERR "%s: WRITE ERROR lsb = 0x%x, msb = 0x%x",
+			__func__, code_val_lsb, code_val_msb);
+	else
+		CDBG(KERN_ERR "%s: WRITE successful lsb = 0x%x, msb = 0x%x",
+			__func__, code_val_lsb, code_val_msb);
+
+	usleep_range(10000, 11000);
+	return 0;
+}
+
+static int32_t ov5647_test(enum ov5647_test_mode_t mo)
+{
+	int32_t rc = 0;
+
+	if (mo != TEST_OFF)
+		rc = ov5647_i2c_write_b_sensor(0x0601, (uint8_t) mo);
+
+	return rc;
+}
+
+static void ov5647_reset_sensor(void)
+{
+	ov5647_i2c_write_b_sensor(0x103, 0x1);
+}
+
+
+static int32_t ov5647_sensor_setting(int update_type, int rt)
+{
+
+	int32_t rc = 0;
+	struct msm_camera_csi_params ov5647_csi_params;
+
+	ov5647_stop_stream();
+
+	/* wait for clk/data really stop */
+	if ((rt == RES_CAPTURE) || (CSI_CONFIG == 0))
+		msleep(66);
+	else
+		msleep(266);
+
+	CDBG("CAMERA_DBG1: 0x4800 regVal:0x25\r\n");
+	ov5647_i2c_write_b_sensor(0x4800, 0x25);/* streaming off */
+
+	usleep_range(10000, 11000);
+
+	if (update_type == REG_INIT) {
+		ov5647_reset_sensor();
+		ov5647_i2c_write_b_table(ov5647_regs.rec_settings,
+			ov5647_regs.rec_size);
+		CSI_CONFIG = 0;
+	} else if (update_type == UPDATE_PERIODIC) {
+			/* turn off flash when preview */
+
+			if (rt == RES_PREVIEW) {
+				ov5647_i2c_write_b_table(ov5647_regs.reg_prev,
+					 ov5647_regs.reg_prev_size);
+				CDBG("CAMERA_DBG:preview settings...\r\n");
+			} else {
+				ov5647_i2c_write_b_table(ov5647_regs.reg_snap,
+					 ov5647_regs.reg_snap_size);
+				CDBG("CAMERA_DBG:snapshot settings...\r\n");
+			}
+
+			msleep(20);
+			if (!CSI_CONFIG) {
+				msm_camio_vfe_clk_rate_set(192000000);
+				ov5647_csi_params.data_format = CSI_8BIT;
+				ov5647_csi_params.lane_cnt = 2;
+				ov5647_csi_params.lane_assign = 0xe4;
+				ov5647_csi_params.dpcm_scheme = 0;
+				ov5647_csi_params.settle_cnt = 10;
+				rc = msm_camio_csi_config(&ov5647_csi_params);
+				msleep(20);
+				CSI_CONFIG = 1;
+			/* exit powerdown state */
+				ov5647_i2c_write_b_sensor(0x0100, 0x01);
+			}
+			CDBG("CAMERA_DBG: 0x4800 regVal:0x04\r\n");
+			/* streaming on */
+			ov5647_i2c_write_b_sensor(0x4800, 0x04);
+			msleep(266);
+			ov5647_start_stream();
+			msleep(30);
+	}
+	return rc;
+}
+
+static int32_t ov5647_video_config(int mode)
+{
+	int32_t rc = 0;
+	int rt;
+	CDBG("video config\n");
+	/* change sensor resolution if needed */
+	if (ov5647_ctrl->prev_res == QTR_SIZE)
+		rt = RES_PREVIEW;
+	else
+		rt = RES_CAPTURE;
+	if (ov5647_sensor_setting(UPDATE_PERIODIC, rt) < 0)
+		return rc;
+	if (ov5647_ctrl->set_test) {
+		if (ov5647_test(ov5647_ctrl->set_test) < 0)
+			return  rc;
+	}
+
+	ov5647_ctrl->curr_res = ov5647_ctrl->prev_res;
+	ov5647_ctrl->sensormode = mode;
+	return rc;
+}
+
+static int32_t ov5647_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+	int rt;
+
+	/*change sensor resolution if needed */
+	if (ov5647_ctrl->curr_res != ov5647_ctrl->pict_res) {
+		if (ov5647_ctrl->pict_res == QTR_SIZE)
+			rt = RES_PREVIEW;
+		else
+			rt = RES_CAPTURE;
+		if (ov5647_sensor_setting(UPDATE_PERIODIC, rt) < 0)
+			return rc;
+	}
+
+	ov5647_ctrl->curr_res = ov5647_ctrl->pict_res;
+	ov5647_ctrl->sensormode = mode;
+	return rc;
+}
+
+static int32_t ov5647_raw_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+	int rt;
+
+	/* change sensor resolution if needed */
+	if (ov5647_ctrl->curr_res != ov5647_ctrl->pict_res) {
+		if (ov5647_ctrl->pict_res == QTR_SIZE)
+			rt = RES_PREVIEW;
+		else
+			rt = RES_CAPTURE;
+		if (ov5647_sensor_setting(UPDATE_PERIODIC, rt) < 0)
+			return rc;
+	}
+
+	ov5647_ctrl->curr_res = ov5647_ctrl->pict_res;
+	ov5647_ctrl->sensormode = mode;
+	return rc;
+}
+
+static int32_t ov5647_set_sensor_mode(int mode,
+		int res)
+{
+	int32_t rc = 0;
+
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		rc = ov5647_video_config(mode);
+		break;
+	case SENSOR_SNAPSHOT_MODE:
+		rc = ov5647_snapshot_config(mode);
+		break;
+	case SENSOR_RAW_SNAPSHOT_MODE:
+		rc = ov5647_raw_snapshot_config(mode);
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
+static int32_t ov5647_power_down(void)
+{
+	ov5647_stop_stream();
+	return 0;
+}
+
+static int ov5647_probe_init_done(const struct msm_camera_sensor_info *data)
+{
+	CDBG("probe done\n");
+	gpio_direction_output(data->sensor_pwd, 1);
+	return 0;
+}
+
+static int ov5647_probe_init_sensor(const struct msm_camera_sensor_info *data)
+{
+	int32_t rc = 0;
+	uint16_t regaddress1 = 0x300a;
+	uint16_t regaddress2 = 0x300b;
+	uint16_t chipid1 = 0;
+	uint16_t chipid2 = 0;
+
+	CDBG("%s: %d\n", __func__, __LINE__);
+
+	gpio_direction_output(data->sensor_pwd, 0);
+	usleep_range(4000, 4100);
+	gpio_direction_output(data->sensor_reset, 1);
+	usleep_range(2000, 2100);
+
+	ov5647_i2c_read(regaddress1, &chipid1);
+	if (chipid1 != 0x56) {
+		rc = -ENODEV;
+		pr_err("ov5647_probe_init_sensor fail chip id doesnot match\n");
+		goto init_probe_fail;
+	}
+
+	ov5647_i2c_read(regaddress2, &chipid2);
+	if (chipid2 != 0x47) {
+		rc = -ENODEV;
+		pr_err("ov5647_probe_init_sensor fail chip id doesnot match\n");
+		goto init_probe_fail;
+	}
+
+	pr_err("ID1: 0x%x\n", chipid1);
+	pr_err("ID2: 0x%x\n", chipid2);
+	goto init_probe_done;
+
+init_probe_fail:
+	pr_err(" ov5647_probe_init_sensor fails\n");
+	ov5647_probe_init_done(data);
+	return rc;
+init_probe_done:
+	pr_debug(" ov5647_probe_init_sensor finishes\n");
+	gpio_direction_output(data->sensor_pwd, 1);
+	return rc;
+}
+
+
+static int ov5647_sensor_open_init(const struct msm_camera_sensor_info *data)
+{
+	int32_t rc = 0;
+
+	CDBG("%s: %d\n", __func__, __LINE__);
+	CDBG("Calling ov5647_sensor_open_init\n");
+
+	ov5647_ctrl = kzalloc(sizeof(struct ov5647_ctrl_t), GFP_KERNEL);
+	if (!ov5647_ctrl) {
+		CDBG("ov5647_init failed!\n");
+		rc = -ENOMEM;
+		goto init_done;
+	}
+	ov5647_ctrl->fps_divider = 1 * 0x00000400;
+	ov5647_ctrl->pict_fps_divider = 1 * 0x00000400;
+	ov5647_ctrl->set_test = TEST_OFF;
+	ov5647_ctrl->prev_res = QTR_SIZE;
+	ov5647_ctrl->pict_res = FULL_SIZE;
+
+	if (data)
+		ov5647_ctrl->sensordata = data;
+
+	prev_frame_length_lines = 0x3d8;
+
+	prev_line_length_pck = 0x768*2;
+
+	snap_frame_length_lines = 0x7b0;
+
+	snap_line_length_pck = 0xa8c;
+
+	/* enable mclk first */
+	msm_camio_clk_rate_set(OV5647_MASTER_CLK_RATE);
+
+	gpio_direction_output(data->sensor_pwd, 1);
+	gpio_direction_output(data->sensor_reset, 0);
+	usleep_range(10000, 11000);
+	/* power on camera ldo and vreg */
+	if (ov5647_ctrl->sensordata->pmic_gpio_enable)
+		lcd_camera_power_onoff(1);
+	usleep_range(10000, 11000); /*waiting for ldo stable*/
+	gpio_direction_output(data->sensor_pwd, 0);
+	msleep(20);
+	gpio_direction_output(data->sensor_reset, 1);
+	msleep(25);
+
+	CDBG("init settings\n");
+	if (ov5647_ctrl->prev_res == QTR_SIZE)
+		rc = ov5647_sensor_setting(REG_INIT, RES_PREVIEW);
+	else
+		rc = ov5647_sensor_setting(REG_INIT, RES_CAPTURE);
+	ov5647_ctrl->fps = 30 * Q8;
+
+	/* enable AF actuator */
+	if (ov5647_ctrl->sensordata->vcm_enable) {
+		CDBG("enable AF actuator, gpio = %d\n",
+			 ov5647_ctrl->sensordata->vcm_pwd);
+		rc = gpio_request(ov5647_ctrl->sensordata->vcm_pwd,
+						"ov5647_af");
+		if (!rc)
+			gpio_direction_output(
+				ov5647_ctrl->sensordata->vcm_pwd,
+				 1);
+		else {
+			pr_err("ov5647_ctrl gpio request failed!\n");
+			goto init_fail;
+		}
+		msleep(20);
+		rc = ov5647_set_default_focus(0);
+		if (rc < 0) {
+			gpio_direction_output(ov5647_ctrl->sensordata->vcm_pwd,
+								0);
+			gpio_free(ov5647_ctrl->sensordata->vcm_pwd);
+		}
+	}
+	if (rc < 0)
+		goto init_fail;
+	else
+		goto init_done;
+init_fail:
+	CDBG("init_fail\n");
+	ov5647_probe_init_done(data);
+	/* No need to power OFF camera ldo and vreg
+	affects Display while resume */
+init_done:
+	CDBG("init_done\n");
+	return rc;
+}
+
+static int ov5647_i2c_remove(struct i2c_client *client)
+{
+	return 0;
+}
+
+static int ov5647_init_client(struct i2c_client *client)
+{
+	/* Initialize the MSM_CAMI2C Chip */
+	init_waitqueue_head(&ov5647_wait_queue);
+	return 0;
+}
+
+static int ov5647_af_init_client(struct i2c_client *client)
+{
+	/* Initialize the MSM_CAMI2C Chip */
+	init_waitqueue_head(&ov5647_af_wait_queue);
+	return 0;
+}
+
+static const struct i2c_device_id ov5647_af_i2c_id[] = {
+	{"ov5647_af", 0},
+	{ }
+};
+
+static int ov5647_af_i2c_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	int rc = 0;
+	CDBG("ov5647_af_probe called!\n");
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		CDBG("i2c_check_functionality failed\n");
+		goto probe_failure;
+	}
+
+	ov5647_af_sensorw = kzalloc(sizeof(struct ov5647_work_t), GFP_KERNEL);
+	if (!ov5647_af_sensorw) {
+		CDBG("kzalloc failed.\n");
+		rc = -ENOMEM;
+		goto probe_failure;
+	}
+
+	i2c_set_clientdata(client, ov5647_af_sensorw);
+	ov5647_af_init_client(client);
+	ov5647_af_client = client;
+
+	msleep(50);
+
+	CDBG("ov5647_af_probe successed! rc = %d\n", rc);
+	return 0;
+
+probe_failure:
+	CDBG("ov5647_af_probe failed! rc = %d\n", rc);
+	return rc;
+}
+
+static const struct i2c_device_id ov5647_i2c_id[] = {
+	{"ov5647", 0}, {}
+};
+
+static int ov5647_i2c_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	int rc = 0;
+	CDBG("ov5647_probe called!\n");
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		CDBG("i2c_check_functionality failed\n");
+		goto probe_failure;
+	}
+
+	ov5647_sensorw = kzalloc(sizeof(struct ov5647_work_t), GFP_KERNEL);
+	if (!ov5647_sensorw) {
+		CDBG("kzalloc failed.\n");
+		rc = -ENOMEM;
+		goto probe_failure;
+	}
+
+	i2c_set_clientdata(client, ov5647_sensorw);
+	ov5647_init_client(client);
+	ov5647_client = client;
+
+	msleep(50);
+
+	CDBG("ov5647_probe successed! rc = %d\n", rc);
+	return 0;
+
+probe_failure:
+	CDBG("ov5647_probe failed! rc = %d\n", rc);
+	return rc;
+}
+
+static int __devexit ov5647_remove(struct i2c_client *client)
+{
+	struct ov5647_work_t *sensorw = i2c_get_clientdata(client);
+	free_irq(client->irq, sensorw);
+	ov5647_client = NULL;
+	kfree(sensorw);
+	return 0;
+}
+
+static int __devexit ov5647_af_remove(struct i2c_client *client)
+{
+	struct ov5647_work_t *ov5647_af = i2c_get_clientdata(client);
+	free_irq(client->irq, ov5647_af);
+	ov5647_af_client = NULL;
+	kfree(ov5647_af);
+	return 0;
+}
+
+static struct i2c_driver ov5647_i2c_driver = {
+	.id_table = ov5647_i2c_id,
+	.probe  = ov5647_i2c_probe,
+	.remove = ov5647_i2c_remove,
+	.driver = {
+		.name = "ov5647",
+	},
+};
+
+static struct i2c_driver ov5647_af_i2c_driver = {
+	.id_table = ov5647_af_i2c_id,
+	.probe  = ov5647_af_i2c_probe,
+	.remove = __exit_p(ov5647_af_i2c_remove),
+	.driver = {
+		.name = "ov5647_af",
+	},
+};
+
+int ov5647_sensor_config(void __user *argp)
+{
+	struct sensor_cfg_data cdata;
+	long   rc = 0;
+	if (copy_from_user(&cdata,
+				(void *)argp,
+				sizeof(struct sensor_cfg_data)))
+		return -EFAULT;
+	mutex_lock(&ov5647_mut);
+	CDBG("ov5647_sensor_config: cfgtype = %d\n",
+			cdata.cfgtype);
+	switch (cdata.cfgtype) {
+	case CFG_GET_PICT_FPS:
+		ov5647_get_pict_fps(
+			cdata.cfg.gfps.prevfps,
+			&(cdata.cfg.gfps.pictfps));
+
+		if (copy_to_user((void *)argp,
+			&cdata,
+			sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+	case CFG_GET_PREV_L_PF:
+		cdata.cfg.prevl_pf =
+			ov5647_get_prev_lines_pf();
+
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+	case CFG_GET_PREV_P_PL:
+		cdata.cfg.prevp_pl =
+			ov5647_get_prev_pixels_pl();
+
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+	case CFG_GET_PICT_L_PF:
+		cdata.cfg.pictl_pf =
+			ov5647_get_pict_lines_pf();
+
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+	case CFG_GET_PICT_P_PL:
+		cdata.cfg.pictp_pl =
+			ov5647_get_pict_pixels_pl();
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+	case CFG_GET_PICT_MAX_EXP_LC:
+		cdata.cfg.pict_max_exp_lc =
+			ov5647_get_pict_max_exp_lc();
+
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+	case CFG_SET_FPS:
+	case CFG_SET_PICT_FPS:
+		rc = ov5647_set_fps(&(cdata.cfg.fps));
+		break;
+	case CFG_SET_EXP_GAIN:
+		rc = ov5647_write_exp_gain(cdata.cfg.exp_gain.gain,
+				cdata.cfg.exp_gain.line);
+		break;
+	case CFG_SET_PICT_EXP_GAIN:
+		rc = ov5647_set_pict_exp_gain(cdata.cfg.exp_gain.gain,
+				cdata.cfg.exp_gain.line);
+		break;
+	case CFG_SET_MODE:
+		rc = ov5647_set_sensor_mode(cdata.mode, cdata.rs);
+		break;
+	case CFG_PWR_DOWN:
+		rc = ov5647_power_down();
+		break;
+	case CFG_MOVE_FOCUS:
+		rc = ov5647_move_focus(cdata.cfg.focus.dir,
+				cdata.cfg.focus.steps);
+		break;
+	case CFG_SET_DEFAULT_FOCUS:
+		rc = ov5647_set_default_focus(cdata.cfg.focus.steps);
+		break;
+
+	case CFG_GET_AF_MAX_STEPS:
+		cdata.max_steps = OV5647_TOTAL_STEPS_NEAR_TO_FAR;
+		if (copy_to_user((void *)argp,
+					&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+	case CFG_SET_EFFECT:
+		rc = ov5647_set_default_focus(cdata.cfg.effect);
+		break;
+	default:
+		rc = -EFAULT;
+		break;
+	}
+	mutex_unlock(&ov5647_mut);
+
+	return rc;
+}
+
+static int ov5647_sensor_release(void)
+{
+	int rc = -EBADF;
+	unsigned short rdata;
+
+	mutex_lock(&ov5647_mut);
+	ov5647_power_down();
+	msleep(20);
+	ov5647_i2c_read(0x3018, &rdata);
+	rdata |= 0x18; /*set bit 3 bit 4 to 1*/
+	ov5647_i2c_write_b_sensor(0x3018, rdata);/*write back*/
+	msleep(20);
+
+	gpio_set_value(ov5647_ctrl->sensordata->sensor_pwd, 1);
+	usleep_range(5000, 5100);
+	if (ov5647_ctrl->sensordata->vcm_enable) {
+		gpio_direction_output(ov5647_ctrl->sensordata->vcm_pwd, 0);
+		gpio_free(ov5647_ctrl->sensordata->vcm_pwd);
+	}
+
+	/* No need to power OFF camera ldo and vreg
+	affects Display while resume */
+
+	kfree(ov5647_ctrl);
+	ov5647_ctrl = NULL;
+	CDBG("ov5647_release completed\n");
+	mutex_unlock(&ov5647_mut);
+
+	return rc;
+}
+
+static int ov5647_sensor_probe(const struct msm_camera_sensor_info *info,
+		struct msm_sensor_ctrl *s)
+{
+	int rc = 0;
+
+	CDBG("%s E\n", __func__);
+
+	gpio_direction_output(info->sensor_pwd, 1);
+	gpio_direction_output(info->sensor_reset, 0);
+	usleep_range(1000, 1100);
+	/* turn on ldo and vreg */
+	if (info->pmic_gpio_enable)
+		lcd_camera_power_onoff(1);
+
+	rc = i2c_add_driver(&ov5647_i2c_driver);
+	if (rc < 0 || ov5647_client == NULL) {
+		rc = -ENOTSUPP;
+		CDBG("I2C add driver ov5647 failed");
+		goto probe_fail_2;
+	}
+	if (info->vcm_enable) {
+		rc = i2c_add_driver(&ov5647_af_i2c_driver);
+		if (rc < 0 || ov5647_af_client == NULL) {
+			rc = -ENOTSUPP;
+			CDBG("I2C add driver ov5647 af failed");
+			goto probe_fail_3;
+		}
+	}
+	msm_camio_clk_rate_set(OV5647_MASTER_CLK_RATE);
+
+	rc = ov5647_probe_init_sensor(info);
+	if (rc < 0)
+		goto probe_fail_1;
+
+	s->s_init = ov5647_sensor_open_init;
+	s->s_release = ov5647_sensor_release;
+	s->s_config  = ov5647_sensor_config;
+	s->s_mount_angle = info->sensor_platform_info->mount_angle;
+	gpio_set_value(info->sensor_pwd, 1);
+	ov5647_probe_init_done(info);
+	/* turn off ldo and vreg */
+	if (info->pmic_gpio_enable)
+		lcd_camera_power_onoff(0);
+
+	CDBG("%s X", __func__);
+	return rc;
+
+probe_fail_3:
+	i2c_del_driver(&ov5647_af_i2c_driver);
+probe_fail_2:
+	i2c_del_driver(&ov5647_i2c_driver);
+probe_fail_1:
+	/* turn off ldo and vreg */
+	if (info->pmic_gpio_enable)
+		lcd_camera_power_onoff(0);
+	CDBG("ov5647_sensor_probe: SENSOR PROBE FAILS!\n");
+	CDBG("%s X", __func__);
+	return rc;
+}
+
+static int __devinit ov5647_probe(struct platform_device *pdev)
+{
+	return msm_camera_drv_start(pdev, ov5647_sensor_probe);
+}
+
+static struct platform_driver msm_camera_driver = {
+	.probe = ov5647_probe,
+	.driver = {
+		.name = "msm_camera_ov5647",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init ov5647_init(void)
+{
+	return platform_driver_register(&msm_camera_driver);
+}
+
+module_init(ov5647_init);
+MODULE_DESCRIPTION("Omnivision 5 MP Bayer sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/ov5647.h b/drivers/media/platform/msm/camera_v1/ov5647.h
new file mode 100644
index 0000000..0015d63
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/ov5647.h
@@ -0,0 +1,92 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef OV5647_H
+#define OV5647_H
+#include <linux/types.h>
+#include <mach/board.h>
+
+extern struct ov5647_reg ov5647_regs;
+extern int lcd_camera_power_onoff(int on);
+extern struct rw_semaphore leds_list_lock;
+extern struct list_head leds_list;
+
+struct ov5647_i2c_reg_conf {
+	unsigned short waddr;
+	unsigned short wdata;
+};
+
+enum ov5647_test_mode_t {
+	TEST_OFF,
+	TEST_1,
+	TEST_2,
+	TEST_3
+};
+
+enum ov5647_resolution_t {
+	QTR_SIZE,
+	FULL_SIZE,
+	INVALID_SIZE
+};
+enum ov5647_setting {
+	RES_PREVIEW,
+	RES_CAPTURE
+};
+enum ov5647_reg_update {
+	/* Sensor egisters that need to be updated during initialization */
+	REG_INIT,
+	/* Sensor egisters that needs periodic I2C writes */
+	UPDATE_PERIODIC,
+	/* All the sensor Registers will be updated */
+	UPDATE_ALL,
+	/* Not valid update */
+	UPDATE_INVALID
+};
+
+enum ov5647_reg_pll {
+	E013_VT_PIX_CLK_DIV,
+	E013_VT_SYS_CLK_DIV,
+	E013_PRE_PLL_CLK_DIV,
+	E013_PLL_MULTIPLIER,
+	E013_OP_PIX_CLK_DIV,
+	E013_OP_SYS_CLK_DIV
+};
+
+enum ov5647_reg_mode {
+	E013_X_ADDR_START,
+	E013_X_ADDR_END,
+	E013_Y_ADDR_START,
+	E013_Y_ADDR_END,
+	E013_X_OUTPUT_SIZE,
+	E013_Y_OUTPUT_SIZE,
+	E013_DATAPATH_SELECT,
+	E013_READ_MODE,
+	E013_ANALOG_CONTROL5,
+	E013_DAC_LD_4_5,
+	E013_SCALING_MODE,
+	E013_SCALE_M,
+	E013_LINE_LENGTH_PCK,
+	E013_FRAME_LENGTH_LINES,
+	E013_COARSE_INTEGRATION_TIME,
+	E013_FINE_INTEGRATION_TIME,
+	E013_FINE_CORRECTION
+};
+
+struct ov5647_reg {
+	const struct ov5647_i2c_reg_conf *rec_settings;
+	const unsigned short rec_size;
+	const struct ov5647_i2c_reg_conf *reg_prev;
+	const unsigned short reg_prev_size;
+	const struct ov5647_i2c_reg_conf *reg_snap;
+	const unsigned short reg_snap_size;
+};
+#endif /* OV5647_H */
diff --git a/drivers/media/platform/msm/camera_v1/ov5647_reg.c b/drivers/media/platform/msm/camera_v1/ov5647_reg.c
new file mode 100644
index 0000000..c9709bf
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/ov5647_reg.c
@@ -0,0 +1,219 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+
+#include "ov5647.h"
+struct ov5647_i2c_reg_conf ov5647_prev_settings[] = {
+	/*1280*960 Reference Setting 24M MCLK 2lane 280Mbps/lane 30fps
+	for back to preview*/
+	{0x3035, 0x21},
+	{0x3036, 0x37},
+	{0x3821, 0x07},
+	{0x3820, 0x41},
+	{0x3612, 0x09},
+	{0x3618, 0x00},
+	{0x380c, 0x07},
+	{0x380d, 0x68},
+	{0x380e, 0x03},
+	{0x380f, 0xd8},
+	{0x3814, 0x31},
+	{0x3815, 0x31},
+	{0x3709, 0x52},
+	{0x3808, 0x05},
+	{0x3809, 0x00},
+	{0x380a, 0x03},
+	{0x380b, 0xc0},
+	{0x3800, 0x00},
+	{0x3801, 0x18},
+	{0x3802, 0x00},
+	{0x3803, 0x0e},
+	{0x3804, 0x0a},
+	{0x3805, 0x27},
+	{0x3806, 0x07},
+	{0x3807, 0x95},
+	{0x4004, 0x02},
+};
+
+struct ov5647_i2c_reg_conf ov5647_snap_settings[] = {
+	/*2608*1952 Reference Setting 24M MCLK 2lane 280Mbps/lane 30fps*/
+	{0x3035, 0x21},
+	{0x3036, 0x4f},
+	{0x3821, 0x06},
+	{0x3820, 0x00},
+	{0x3612, 0x0b},
+	{0x3618, 0x04},
+	{0x380c, 0x0a},
+	{0x380d, 0x8c},
+	{0x380e, 0x07},
+	{0x380f, 0xb0},
+	{0x3814, 0x11},
+	{0x3815, 0x11},
+	{0x3709, 0x12},
+	{0x3808, 0x0a},
+	{0x3809, 0x30},
+	{0x380a, 0x07},
+	{0x380b, 0xa0},
+	{0x3800, 0x00},
+	{0x3801, 0x04},
+	{0x3802, 0x00},
+	{0x3803, 0x00},
+	{0x3804, 0x0a},
+	{0x3805, 0x3b},
+	{0x3806, 0x07},
+	{0x3807, 0xa3},
+	{0x4004, 0x04},
+};
+
+struct ov5647_i2c_reg_conf ov5647_recommend_settings[] = {
+	{0x3035, 0x11},
+	{0x303c, 0x11},
+	{0x370c, 0x03},
+	{0x5000, 0x06},
+	{0x5003, 0x08},
+	{0x5a00, 0x08},
+	{0x3000, 0xff},
+	{0x3001, 0xff},
+	{0x3002, 0xff},
+	{0x301d, 0xf0},
+	{0x3a18, 0x00},
+	{0x3a19, 0xf8},
+	{0x3c01, 0x80},
+	{0x3b07, 0x0c},
+	{0x3708, 0x64},
+	{0x3630, 0x2e},
+	{0x3632, 0xe2},
+	{0x3633, 0x23},
+	{0x3634, 0x44},
+	{0x3620, 0x64},
+	{0x3621, 0xe0},
+	{0x3600, 0x37},
+	{0x3704, 0xa0},
+	{0x3703, 0x5a},
+	{0x3715, 0x78},
+	{0x3717, 0x01},
+	{0x3731, 0x02},
+	{0x370b, 0x60},
+	{0x3705, 0x1a},
+	{0x3f05, 0x02},
+	{0x3f06, 0x10},
+	{0x3f01, 0x0a},
+	{0x3a08, 0x01},
+	{0x3a0f, 0x58},
+	{0x3a10, 0x50},
+	{0x3a1b, 0x58},
+	{0x3a1e, 0x50},
+	{0x3a11, 0x60},
+	{0x3a1f, 0x28},
+	{0x4001, 0x02},
+	{0x4000, 0x09},
+	{0x3000, 0x00},
+	{0x3001, 0x00},
+	{0x3002, 0x00},
+	{0x3017, 0xe0},
+	{0x301c, 0xfc},
+	{0x3636, 0x06},
+	{0x3016, 0x08},
+	{0x3827, 0xec},
+	{0x3018, 0x44},
+	{0x3035, 0x21},
+	{0x3106, 0xf5},
+	{0x3034, 0x18},
+	{0x301c, 0xf8},
+	/*lens setting*/
+	{0x5000, 0x86},
+	{0x5800, 0x11},
+	{0x5801, 0x0c},
+	{0x5802, 0x0a},
+	{0x5803, 0x0b},
+	{0x5804, 0x0d},
+	{0x5805, 0x13},
+	{0x5806, 0x09},
+	{0x5807, 0x05},
+	{0x5808, 0x03},
+	{0x5809, 0x03},
+	{0x580a, 0x06},
+	{0x580b, 0x08},
+	{0x580c, 0x05},
+	{0x580d, 0x01},
+	{0x580e, 0x00},
+	{0x580f, 0x00},
+	{0x5810, 0x02},
+	{0x5811, 0x06},
+	{0x5812, 0x05},
+	{0x5813, 0x01},
+	{0x5814, 0x00},
+	{0x5815, 0x00},
+	{0x5816, 0x02},
+	{0x5817, 0x06},
+	{0x5818, 0x09},
+	{0x5819, 0x05},
+	{0x581a, 0x04},
+	{0x581b, 0x04},
+	{0x581c, 0x06},
+	{0x581d, 0x09},
+	{0x581e, 0x11},
+	{0x581f, 0x0c},
+	{0x5820, 0x0b},
+	{0x5821, 0x0b},
+	{0x5822, 0x0d},
+	{0x5823, 0x13},
+	{0x5824, 0x22},
+	{0x5825, 0x26},
+	{0x5826, 0x26},
+	{0x5827, 0x24},
+	{0x5828, 0x24},
+	{0x5829, 0x24},
+	{0x582a, 0x22},
+	{0x582b, 0x20},
+	{0x582c, 0x22},
+	{0x582d, 0x26},
+	{0x582e, 0x22},
+	{0x582f, 0x22},
+	{0x5830, 0x42},
+	{0x5831, 0x22},
+	{0x5832, 0x02},
+	{0x5833, 0x24},
+	{0x5834, 0x22},
+	{0x5835, 0x22},
+	{0x5836, 0x22},
+	{0x5837, 0x26},
+	{0x5838, 0x42},
+	{0x5839, 0x26},
+	{0x583a, 0x06},
+	{0x583b, 0x26},
+	{0x583c, 0x24},
+	{0x583d, 0xce},
+	/* manual AWB,manual AE,close Lenc,open WBC*/
+	{0x3503, 0x03}, /*manual AE*/
+	{0x3501, 0x10},
+	{0x3502, 0x80},
+	{0x350a, 0x00},
+	{0x350b, 0x7f},
+	{0x5001, 0x01}, /*manual AWB*/
+	{0x5180, 0x08},
+	{0x5186, 0x04},
+	{0x5187, 0x00},
+	{0x5188, 0x04},
+	{0x5189, 0x00},
+	{0x518a, 0x04},
+	{0x518b, 0x00},
+	{0x5000, 0x06}, /*No lenc,WBC on*/
+};
+
+struct ov5647_reg ov5647_regs = {
+	.rec_settings = &ov5647_recommend_settings[0],
+	.rec_size = ARRAY_SIZE(ov5647_recommend_settings),
+	.reg_prev = &ov5647_prev_settings[0],
+	.reg_prev_size = ARRAY_SIZE(ov5647_prev_settings),
+	.reg_snap = &ov5647_snap_settings[0],
+	.reg_snap_size = ARRAY_SIZE(ov5647_snap_settings),
+};
diff --git a/drivers/media/platform/msm/camera_v1/ov7692.c b/drivers/media/platform/msm/camera_v1/ov7692.c
new file mode 100644
index 0000000..252d42c
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/ov7692.c
@@ -0,0 +1,597 @@
+/* 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/slab.h>
+#include <media/msm_camera.h>
+#include <mach/camera.h>
+#include "ov7692.h"
+
+/*=============================================================
+	SENSOR REGISTER DEFINES
+==============================================================*/
+#define Q8    0x00000100
+
+/* Omnivision8810 product ID register address */
+#define REG_OV7692_MODEL_ID_MSB                       0x0A
+#define REG_OV7692_MODEL_ID_LSB                       0x0B
+
+#define OV7692_MODEL_ID                       0x7692
+/* Omnivision8810 product ID */
+
+/* Time in milisecs for waiting for the sensor to reset */
+#define OV7692_RESET_DELAY_MSECS    66
+#define OV7692_DEFAULT_CLOCK_RATE   24000000
+/* Registers*/
+
+/* Color bar pattern selection */
+#define OV7692_COLOR_BAR_PATTERN_SEL_REG     0x82
+/* Color bar enabling control */
+#define OV7692_COLOR_BAR_ENABLE_REG           0x601
+/* Time in milisecs for waiting for the sensor to reset*/
+#define OV7692_RESET_DELAY_MSECS    66
+
+/*============================================================================
+							DATA DECLARATIONS
+============================================================================*/
+/*  96MHz PCLK @ 24MHz MCLK */
+struct reg_addr_val_pair_struct ov7692_init_settings_array[] = {
+    {0x12, 0x80},
+    {0x0e, 0x08},
+    {0x69, 0x52},
+    {0x1e, 0xb3},
+    {0x48, 0x42},
+    {0xff, 0x01},
+    {0xae, 0xa0},
+    {0xa8, 0x26},
+    {0xb4, 0xc0},
+    {0xb5, 0x40},
+    {0xff, 0x00},
+    {0x0c, 0x00},
+    {0x62, 0x10},
+    {0x12, 0x00},
+    {0x17, 0x65},
+    {0x18, 0xa4},
+    {0x19, 0x0a},
+    {0x1a, 0xf6},
+    {0x3e, 0x30},
+    {0x64, 0x0a},
+    {0xff, 0x01},
+    {0xb4, 0xc0},
+    {0xff, 0x00},
+    {0x67, 0x20},
+    {0x81, 0x3f},
+    {0xcc, 0x02},
+    {0xcd, 0x80},
+    {0xce, 0x01},
+    {0xcf, 0xe0},
+    {0xc8, 0x02},
+    {0xc9, 0x80},
+    {0xca, 0x01},
+    {0xcb, 0xe0},
+    {0xd0, 0x48},
+    {0x82, 0x03},
+    {0x0e, 0x00},
+    {0x70, 0x00},
+    {0x71, 0x34},
+    {0x74, 0x28},
+    {0x75, 0x98},
+    {0x76, 0x00},
+    {0x77, 0x64},
+    {0x78, 0x01},
+    {0x79, 0xc2},
+    {0x7a, 0x4e},
+    {0x7b, 0x1f},
+    {0x7c, 0x00},
+    {0x11, 0x00},
+    {0x20, 0x00},
+    {0x21, 0x23},
+    {0x50, 0x9a},
+    {0x51, 0x80},
+    {0x4c, 0x7d},
+    {0x0e, 0x00},
+    {0x80, 0x7f},
+    {0x85, 0x10},
+    {0x86, 0x00},
+    {0x87, 0x00},
+    {0x88, 0x00},
+    {0x89, 0x2a},
+    {0x8a, 0x26},
+    {0x8b, 0x22},
+    {0xbb, 0x7a},
+    {0xbc, 0x69},
+    {0xbd, 0x11},
+    {0xbe, 0x13},
+    {0xbf, 0x81},
+    {0xc0, 0x96},
+    {0xc1, 0x1e},
+    {0xb7, 0x05},
+    {0xb8, 0x09},
+    {0xb9, 0x00},
+    {0xba, 0x18},
+    {0x5a, 0x1f},
+    {0x5b, 0x9f},
+    {0x5c, 0x6a},
+    {0x5d, 0x42},
+    {0x24, 0x78},
+    {0x25, 0x68},
+    {0x26, 0xb3},
+    {0xa3, 0x0b},
+    {0xa4, 0x15},
+    {0xa5, 0x2a},
+    {0xa6, 0x51},
+    {0xa7, 0x63},
+    {0xa8, 0x74},
+    {0xa9, 0x83},
+    {0xaa, 0x91},
+    {0xab, 0x9e},
+    {0xac, 0xaa},
+    {0xad, 0xbe},
+    {0xae, 0xce},
+    {0xaf, 0xe5},
+    {0xb0, 0xf3},
+    {0xb1, 0xfb},
+    {0xb2, 0x06},
+    {0x8c, 0x5c},
+    {0x8d, 0x11},
+    {0x8e, 0x12},
+    {0x8f, 0x19},
+    {0x90, 0x50},
+    {0x91, 0x20},
+    {0x92, 0x96},
+    {0x93, 0x80},
+    {0x94, 0x13},
+    {0x95, 0x1b},
+    {0x96, 0xff},
+    {0x97, 0x00},
+    {0x98, 0x3d},
+    {0x99, 0x36},
+    {0x9a, 0x51},
+    {0x9b, 0x43},
+    {0x9c, 0xf0},
+    {0x9d, 0xf0},
+    {0x9e, 0xf0},
+    {0x9f, 0xff},
+    {0xa0, 0x68},
+    {0xa1, 0x62},
+    {0xa2, 0x0e},
+};
+
+static bool OV7692_CSI_CONFIG;
+/* 816x612, 24MHz MCLK 96MHz PCLK */
+uint32_t OV7692_FULL_SIZE_WIDTH        = 640;
+uint32_t OV7692_FULL_SIZE_HEIGHT       = 480;
+
+uint32_t OV7692_QTR_SIZE_WIDTH         = 640;
+uint32_t OV7692_QTR_SIZE_HEIGHT        = 480;
+
+uint32_t OV7692_HRZ_FULL_BLK_PIXELS    = 16;
+uint32_t OV7692_VER_FULL_BLK_LINES     = 12;
+uint32_t OV7692_HRZ_QTR_BLK_PIXELS     = 16;
+uint32_t OV7692_VER_QTR_BLK_LINES      = 12;
+
+struct ov7692_work_t {
+	struct work_struct work;
+};
+static struct  ov7692_work_t *ov7692_sensorw;
+static struct  i2c_client *ov7692_client;
+struct ov7692_ctrl_t {
+	const struct  msm_camera_sensor_info *sensordata;
+	uint32_t sensormode;
+	uint32_t fps_divider;		/* init to 1 * 0x00000400 */
+	uint32_t pict_fps_divider;	/* init to 1 * 0x00000400 */
+	uint32_t fps;
+	int32_t  curr_lens_pos;
+	uint32_t curr_step_pos;
+	uint32_t my_reg_gain;
+	uint32_t my_reg_line_count;
+	uint32_t total_lines_per_frame;
+	enum ov7692_resolution_t prev_res;
+	enum ov7692_resolution_t pict_res;
+	enum ov7692_resolution_t curr_res;
+	enum ov7692_test_mode_t  set_test;
+	unsigned short imgaddr;
+};
+static struct ov7692_ctrl_t *ov7692_ctrl;
+static DECLARE_WAIT_QUEUE_HEAD(ov7692_wait_queue);
+DEFINE_MUTEX(ov7692_mut);
+
+/*=============================================================*/
+
+static int ov7692_i2c_rxdata(unsigned short saddr,
+	unsigned char *rxdata, int length)
+{
+	struct i2c_msg msgs[] = {
+		{
+			.addr  = saddr,
+			.flags = 0,
+			.len   = 1,
+			.buf   = rxdata,
+		},
+		{
+			.addr  = saddr,
+			.flags = I2C_M_RD,
+			.len   = 1,
+			.buf   = rxdata,
+		},
+	};
+	if (i2c_transfer(ov7692_client->adapter, msgs, 2) < 0) {
+		CDBG("ov7692_i2c_rxdata failed!\n");
+		return -EIO;
+	}
+	return 0;
+}
+static int32_t ov7692_i2c_txdata(unsigned short saddr,
+				unsigned char *txdata, int length)
+{
+	struct i2c_msg msg[] = {
+		{
+			.addr = saddr,
+			.flags = 0,
+			.len = 2,
+			.buf = txdata,
+		 },
+	};
+	if (i2c_transfer(ov7692_client->adapter, msg, 1) < 0) {
+		CDBG("ov7692_i2c_txdata faild 0x%x\n", ov7692_client->addr);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t ov7692_i2c_read(uint8_t raddr,
+	uint8_t *rdata, int rlen)
+{
+	int32_t rc = 0;
+	unsigned char buf[1];
+	if (!rdata)
+		return -EIO;
+	memset(buf, 0, sizeof(buf));
+	buf[0] = raddr;
+	rc = ov7692_i2c_rxdata(ov7692_client->addr >> 1, buf, rlen);
+	if (rc < 0) {
+		CDBG("ov7692_i2c_read 0x%x failed!\n", raddr);
+		return rc;
+	}
+	*rdata = buf[0];
+	return rc;
+}
+static int32_t ov7692_i2c_write_b_sensor(uint8_t waddr, uint8_t bdata)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[2];
+	memset(buf, 0, sizeof(buf));
+	buf[0] = waddr;
+	buf[1] = bdata;
+	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
+	rc = ov7692_i2c_txdata(ov7692_client->addr >> 1, buf, 2);
+	if (rc < 0)
+		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
+			waddr, bdata);
+	return rc;
+}
+
+static int32_t ov7692_sensor_setting(int update_type, int rt)
+{
+	int32_t i, array_length;
+	int32_t rc = 0;
+	struct msm_camera_csi_params ov7692_csi_params;
+	switch (update_type) {
+	case REG_INIT:
+		OV7692_CSI_CONFIG = 0;
+		ov7692_i2c_write_b_sensor(0x0e, 0x08);
+		return rc;
+		break;
+	case UPDATE_PERIODIC:
+		if (!OV7692_CSI_CONFIG) {
+			ov7692_csi_params.lane_cnt = 1;
+			ov7692_csi_params.data_format = CSI_8BIT;
+			ov7692_csi_params.lane_assign = 0xe4;
+			ov7692_csi_params.dpcm_scheme = 0;
+			ov7692_csi_params.settle_cnt = 0x14;
+
+			rc = msm_camio_csi_config(&ov7692_csi_params);
+			msleep(10);
+			array_length = sizeof(ov7692_init_settings_array) /
+				sizeof(ov7692_init_settings_array[0]);
+			for (i = 0; i < array_length; i++) {
+				rc = ov7692_i2c_write_b_sensor(
+					ov7692_init_settings_array[i].reg_addr,
+					ov7692_init_settings_array[i].reg_val);
+				if (rc < 0)
+					return rc;
+			}
+			OV7692_CSI_CONFIG = 1;
+			msleep(20);
+			return rc;
+		}
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
+static int32_t ov7692_video_config(int mode)
+{
+	int32_t rc = 0;
+	int rt;
+	/* change sensor resolution if needed */
+	rt = RES_PREVIEW;
+
+	if (ov7692_sensor_setting(UPDATE_PERIODIC, rt) < 0)
+		return rc;
+	ov7692_ctrl->curr_res = ov7692_ctrl->prev_res;
+	ov7692_ctrl->sensormode = mode;
+	return rc;
+}
+
+static int32_t ov7692_set_sensor_mode(int mode,
+	int res)
+{
+	int32_t rc = 0;
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		rc = ov7692_video_config(mode);
+		break;
+	case SENSOR_SNAPSHOT_MODE:
+	case SENSOR_RAW_SNAPSHOT_MODE:
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+static int32_t ov7692_power_down(void)
+{
+	return 0;
+}
+
+static int ov7692_probe_init_sensor(const struct msm_camera_sensor_info *data)
+{
+	uint8_t model_id_msb, model_id_lsb = 0;
+	uint16_t model_id;
+	int32_t rc = 0;
+	/*The reset pin is not physically connected to the sensor.
+	The standby pin will do the reset hence there is no need
+	to request the gpio reset*/
+
+	/* Read sensor Model ID: */
+	rc = ov7692_i2c_read(REG_OV7692_MODEL_ID_MSB, &model_id_msb, 1);
+	if (rc < 0)
+		goto init_probe_fail;
+	rc = ov7692_i2c_read(REG_OV7692_MODEL_ID_LSB, &model_id_lsb, 1);
+	if (rc < 0)
+		goto init_probe_fail;
+	model_id = (model_id_msb << 8) | ((model_id_lsb & 0x00FF)) ;
+	CDBG("ov7692 model_id = 0x%x, 0x%x, 0x%x\n",
+		 model_id, model_id_msb, model_id_lsb);
+	/* 4. Compare sensor ID to OV7692 ID: */
+	if (model_id != OV7692_MODEL_ID) {
+		rc = -ENODEV;
+		goto init_probe_fail;
+	}
+	goto init_probe_done;
+init_probe_fail:
+	pr_warning(" ov7692_probe_init_sensor fails\n");
+init_probe_done:
+	CDBG(" ov7692_probe_init_sensor finishes\n");
+	return rc;
+}
+
+int ov7692_sensor_open_init(const struct msm_camera_sensor_info *data)
+{
+	int32_t rc = 0;
+
+	CDBG("%s: %d\n", __func__, __LINE__);
+	CDBG("Calling ov7692_sensor_open_init\n");
+	ov7692_ctrl = kzalloc(sizeof(struct ov7692_ctrl_t), GFP_KERNEL);
+	if (!ov7692_ctrl) {
+		CDBG("ov7692_init failed!\n");
+		rc = -ENOMEM;
+		goto init_done;
+	}
+	ov7692_ctrl->fps_divider = 1 * 0x00000400;
+	ov7692_ctrl->pict_fps_divider = 1 * 0x00000400;
+	ov7692_ctrl->fps = 30 * Q8;
+	ov7692_ctrl->set_test = TEST_OFF;
+	ov7692_ctrl->prev_res = QTR_SIZE;
+	ov7692_ctrl->pict_res = FULL_SIZE;
+	ov7692_ctrl->curr_res = INVALID_SIZE;
+
+	if (data)
+		ov7692_ctrl->sensordata = data;
+
+	/* enable mclk first */
+
+	msm_camio_clk_rate_set(24000000);
+	msleep(20);
+
+	rc = ov7692_probe_init_sensor(data);
+	if (rc < 0) {
+		CDBG("Calling ov7692_sensor_open_init fail\n");
+		goto init_fail;
+	}
+
+	rc = ov7692_sensor_setting(REG_INIT, RES_PREVIEW);
+	if (rc < 0)
+		goto init_fail;
+	else
+		goto init_done;
+
+init_fail:
+	CDBG(" ov7692_sensor_open_init fail\n");
+	kfree(ov7692_ctrl);
+init_done:
+	CDBG("ov7692_sensor_open_init done\n");
+	return rc;
+}
+
+static int ov7692_init_client(struct i2c_client *client)
+{
+	/* Initialize the MSM_CAMI2C Chip */
+	init_waitqueue_head(&ov7692_wait_queue);
+	return 0;
+}
+
+static const struct i2c_device_id ov7692_i2c_id[] = {
+	{"ov7692", 0},
+	{ }
+};
+
+static int ov7692_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+	CDBG("ov7692_i2c_probe called!\n");
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		CDBG("i2c_check_functionality failed\n");
+		goto probe_failure;
+	}
+
+	ov7692_sensorw = kzalloc(sizeof(struct ov7692_work_t), GFP_KERNEL);
+	if (!ov7692_sensorw) {
+		CDBG("kzalloc failed.\n");
+		rc = -ENOMEM;
+		goto probe_failure;
+	}
+
+	i2c_set_clientdata(client, ov7692_sensorw);
+	ov7692_init_client(client);
+	ov7692_client = client;
+
+	CDBG("ov7692_i2c_probe success! rc = %d\n", rc);
+	return 0;
+
+probe_failure:
+	CDBG("ov7692_i2c_probe failed! rc = %d\n", rc);
+	return rc;
+}
+
+static int __exit ov7692_remove(struct i2c_client *client)
+{
+	struct ov7692_work_t_t *sensorw = i2c_get_clientdata(client);
+	free_irq(client->irq, sensorw);
+	ov7692_client = NULL;
+	kfree(sensorw);
+	return 0;
+}
+
+static struct i2c_driver ov7692_i2c_driver = {
+	.id_table = ov7692_i2c_id,
+	.probe  = ov7692_i2c_probe,
+	.remove = __exit_p(ov7692_i2c_remove),
+	.driver = {
+		.name = "ov7692",
+	},
+};
+
+int ov7692_sensor_config(void __user *argp)
+{
+	struct sensor_cfg_data cdata;
+	long   rc = 0;
+	if (copy_from_user(&cdata,
+		(void *)argp,
+		sizeof(struct sensor_cfg_data)))
+		return -EFAULT;
+	mutex_lock(&ov7692_mut);
+	CDBG("ov7692_sensor_config: cfgtype = %d\n",
+	cdata.cfgtype);
+	switch (cdata.cfgtype) {
+	case CFG_SET_MODE:
+		rc = ov7692_set_sensor_mode(cdata.mode,
+			cdata.rs);
+		break;
+	case CFG_PWR_DOWN:
+		rc = ov7692_power_down();
+		break;
+	case CFG_SET_EFFECT:
+		break;
+	default:
+		rc = -EFAULT;
+		break;
+	}
+
+	mutex_unlock(&ov7692_mut);
+
+	return rc;
+}
+static int ov7692_sensor_release(void)
+{
+	int rc = -EBADF;
+	mutex_lock(&ov7692_mut);
+	ov7692_power_down();
+	kfree(ov7692_ctrl);
+	ov7692_ctrl = NULL;
+	CDBG("ov7692_release completed\n");
+	mutex_unlock(&ov7692_mut);
+
+	return rc;
+}
+
+static int ov7692_sensor_probe(const struct msm_camera_sensor_info *info,
+		struct msm_sensor_ctrl *s)
+{
+	int rc = 0;
+	rc = i2c_add_driver(&ov7692_i2c_driver);
+	if (rc < 0 || ov7692_client == NULL) {
+		rc = -ENOTSUPP;
+		goto probe_fail;
+	}
+	msm_camio_clk_rate_set(24000000);
+	rc = ov7692_probe_init_sensor(info);
+	if (rc < 0)
+		goto probe_fail;
+	s->s_init = ov7692_sensor_open_init;
+	s->s_release = ov7692_sensor_release;
+	s->s_config  = ov7692_sensor_config;
+	s->s_camera_type = FRONT_CAMERA_2D;
+	s->s_mount_angle = 0;
+	return rc;
+
+probe_fail:
+	CDBG("ov7692_sensor_probe: SENSOR PROBE FAILS!\n");
+	i2c_del_driver(&ov7692_i2c_driver);
+	return rc;
+}
+
+static int __ov7692_probe(struct platform_device *pdev)
+{
+
+	return msm_camera_drv_start(pdev, ov7692_sensor_probe);
+}
+
+static struct platform_driver msm_camera_driver = {
+	.probe = __ov7692_probe,
+	.driver = {
+		.name = "msm_camera_ov7692",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init ov7692_init(void)
+{
+	return platform_driver_register(&msm_camera_driver);
+}
+
+module_init(ov7692_init);
+
+MODULE_DESCRIPTION("OMNI VGA YUV sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/ov7692.h b/drivers/media/platform/msm/camera_v1/ov7692.h
new file mode 100644
index 0000000..da98284
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/ov7692.h
@@ -0,0 +1,666 @@
+/* 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.
+ */
+#ifndef OV7692_H
+#define OV7692_H
+#include <linux/types.h>
+#include <mach/board.h>
+
+#define INVMASK(v)  (0xff-v)
+#define OV7692Core_WritePREG(pTbl)  OV7692_WritePRegs \
+			(pTbl, sizeof(pTbl)/sizeof(pTbl[0]))
+
+extern int lcd_camera_power_onoff(int on);
+struct reg_addr_val_pair_struct {
+	uint8_t	reg_addr;
+	uint8_t	reg_val;
+};
+
+enum ov7692_test_mode_t {
+	TEST_OFF,
+	TEST_1,
+	TEST_2,
+	TEST_3
+};
+
+enum ov7692_resolution_t {
+	QTR_SIZE,
+	FULL_SIZE,
+	INVALID_SIZE
+};
+
+enum ov7692_setting {
+	RES_PREVIEW,
+	RES_CAPTURE
+};
+enum ov7692_reg_update {
+	/* Sensor egisters that need to be updated during initialization */
+	REG_INIT,
+	/* Sensor egisters that needs periodic I2C writes */
+	UPDATE_PERIODIC,
+	/* All the sensor Registers will be updated */
+	UPDATE_ALL,
+	/* Not valid update */
+	UPDATE_INVALID
+};
+
+/*OV SENSOR SCCB*/
+struct OV7692_WREG {
+	uint8_t addr;
+	uint8_t data;
+	uint8_t mask;
+} OV7692_WREG;
+
+#ifdef CONFIG_WEBCAM_OV7692_QRD
+/*  96MHz PCLK @ 24MHz MCLK */
+struct reg_addr_val_pair_struct ov7692_init_settings_array[] = {
+	{0x12, 0x80},
+	{0x0e, 0x08},
+	{0x69, 0x52},
+	{0x1e, 0xb3},
+	{0x48, 0x42},
+	{0xff, 0x01},
+	{0xae, 0xa0},
+	{0xa8, 0x26},
+	{0xb4, 0xc0},
+	{0xb5, 0x40},
+	{0xff, 0x00},
+	{0x0c, 0x00},
+	{0x62, 0x10},
+	{0x12, 0x00},
+	{0x17, 0x65},
+	{0x18, 0xa4},
+	{0x19, 0x0a},
+	{0x1a, 0xf6},
+	{0x3e, 0x30},
+	{0x64, 0x0a},
+	{0xff, 0x01},
+	{0xb4, 0xc0},
+	{0xff, 0x00},
+	{0x67, 0x20},
+	{0x81, 0x3f},
+	{0xcc, 0x02},
+	{0xcd, 0x80},
+	{0xce, 0x01},
+	{0xcf, 0xe0},
+	{0xc8, 0x02},
+	{0xc9, 0x80},
+	{0xca, 0x01},
+	{0xcb, 0xe0},
+	{0xd0, 0x48},
+	{0x82, 0x03},
+	/*{0x0e, 0x00},*/
+	{0x70, 0x00},
+	{0x71, 0x34},
+	{0x74, 0x28},
+	{0x75, 0x98},
+	{0x76, 0x00},
+	{0x77, 0x64},
+	{0x78, 0x01},
+	{0x79, 0xc2},
+	{0x7a, 0x4e},
+	{0x7b, 0x1f},
+	{0x7c, 0x00},
+	{0x11, 0x00},
+	{0x20, 0x00},
+	{0x21, 0x23},
+	{0x50, 0x9a},
+	{0x51, 0x80},
+	{0x4c, 0x7d},
+	/*{0x0e, 0x00},*/
+	{0x85, 0x10},
+	{0x86, 0x00},
+	{0x87, 0x00},
+	{0x88, 0x00},
+	{0x89, 0x2a},
+	{0x8a, 0x26},
+	{0x8b, 0x22},
+	{0xbb, 0x7a},
+	{0xbc, 0x69},
+	{0xbd, 0x11},
+	{0xbe, 0x13},
+	{0xbf, 0x81},
+	{0xc0, 0x96},
+	{0xc1, 0x1e},
+	{0xb7, 0x05},
+	{0xb8, 0x09},
+	{0xb9, 0x00},
+	{0xba, 0x18},
+	{0x5a, 0x1f},
+	{0x5b, 0x9f},
+	{0x5c, 0x6a},
+	{0x5d, 0x42},
+	{0x24, 0x78},
+	{0x25, 0x68},
+	{0x26, 0xb3},
+	{0xa3, 0x0b},
+	{0xa4, 0x15},
+	{0xa5, 0x2a},
+	{0xa6, 0x51},
+	{0xa7, 0x63},
+	{0xa8, 0x74},
+	{0xa9, 0x83},
+	{0xaa, 0x91},
+	{0xab, 0x9e},
+	{0xac, 0xaa},
+	{0xad, 0xbe},
+	{0xae, 0xce},
+	{0xaf, 0xe5},
+	{0xb0, 0xf3},
+	{0xb1, 0xfb},
+	{0xb2, 0x06},
+	{0x8c, 0x5c},
+	{0x8d, 0x11},
+	{0x8e, 0x12},
+	{0x8f, 0x19},
+	{0x90, 0x50},
+	{0x91, 0x20},
+	{0x92, 0x96},
+	{0x93, 0x80},
+	{0x94, 0x13},
+	{0x95, 0x1b},
+	{0x96, 0xff},
+	{0x97, 0x00},
+	{0x98, 0x3d},
+	{0x99, 0x36},
+	{0x9a, 0x51},
+	{0x9b, 0x43},
+	{0x9c, 0xf0},
+	{0x9d, 0xf0},
+	{0x9e, 0xf0},
+	{0x9f, 0xff},
+	{0xa0, 0x68},
+	{0xa1, 0x62},
+	{0xa2, 0x0e},
+};
+#endif
+/* Exposure Compensation */
+struct OV7692_WREG ov7692_exposure_compensation_lv0_tbl[] = {
+	/*@@ +1.7EV*/
+	{0x24, 0xc0},
+	{0x25, 0xb8},
+	{0x26, 0xe6},
+};
+
+struct OV7692_WREG ov7692_exposure_compensation_lv1_tbl[] = {
+	/*@@ +1.0EV*/
+	{0x24, 0xa8},
+	{0x25, 0xa0},
+	{0x26, 0xc4},
+};
+
+struct OV7692_WREG ov7692_exposure_compensation_lv2_default_tbl[] = {
+	/*@@ default*/
+	{0x24, 0x86},
+	{0x25, 0x76},
+	{0x26, 0xb3},
+};
+
+struct OV7692_WREG ov7692_exposure_compensation_lv3_tbl[] = {
+	/*@@ -1.0EV*/
+	{0x24, 0x70},
+	{0x25, 0x60},
+	{0x26, 0xa2},
+};
+
+struct OV7692_WREG ov7692_exposure_compensation_lv4_tbl[] = {
+	/*@@ -1.7EV*/
+	{0x24, 0x50},
+	{0x25, 0x40},
+	{0x26, 0xa2},
+};
+
+struct OV7692_WREG ov7692_antibanding_off_tbl[] = {
+	{0x13, 0xE5, INVMASK(0x20)},
+};
+
+struct OV7692_WREG ov7692_antibanding_auto_tbl[] = {
+	{0x13, 0x20, INVMASK(0x20)},
+	{0x14, 0x14, INVMASK(0x17)},
+};
+
+struct OV7692_WREG ov7692_antibanding_50z_tbl[] = {
+	/*Band 50Hz*/
+	{0x13, 0x20, INVMASK(0x20)},
+	{0x14, 0x17, INVMASK(0x17)},
+};
+
+struct OV7692_WREG ov7692_antibanding_60z_tbl[] = {
+	/*Band 60Hz*/
+	{0x13, 0x20, INVMASK(0x20)},
+	{0x14, 0x16, INVMASK(0x17)},
+};
+
+/*Saturation*/
+struct OV7692_WREG ov7692_saturation_lv0_tbl[] = {
+	/*Saturation level 0*/
+	{0x81, 0x33, INVMASK(0x33)},
+	{0xd8, 0x00, INVMASK(0xff)},
+	{0xd9, 0x00, INVMASK(0xff)},
+	{0xd2, 0x02, INVMASK(0xff)},
+};
+
+struct OV7692_WREG ov7692_saturation_lv1_tbl[] = {
+	/*Saturation level 1*/
+	{0x81, 0x33, INVMASK(0x33)},
+	{0xd8, 0x10, INVMASK(0xff)},
+	{0xd9, 0x10, INVMASK(0xff)},
+	{0xd2, 0x02, INVMASK(0xff)},
+};
+
+struct OV7692_WREG ov7692_saturation_lv2_tbl[] = {
+	/*Saturation level 2*/
+	{0x81, 0x33, INVMASK(0x33)},
+	{0xd8, 0x20, INVMASK(0xff)},
+	{0xd9, 0x20, INVMASK(0xff)},
+	{0xd2, 0x02, INVMASK(0xff)},
+
+};
+
+struct OV7692_WREG ov7692_saturation_lv3_tbl[] = {
+	/*Saturation level 3*/
+	{0x81, 0x33, INVMASK(0x33)},
+	{0xd8, 0x30, INVMASK(0xff)},
+	{0xd9, 0x30, INVMASK(0xff)},
+	{0xd2, 0x02, INVMASK(0xff)},
+
+};
+
+struct OV7692_WREG ov7692_saturation_default_lv4_tbl[] = {
+	/*Saturation level 4 (default)*/
+	{0x81, 0x33, INVMASK(0x33)},
+	{0xd8, 0x40, INVMASK(0xff)},
+	{0xd9, 0x40, INVMASK(0xff)},
+	{0xd2, 0x02, INVMASK(0xff)},
+};
+
+struct OV7692_WREG ov7692_saturation_lv5_tbl[] = {
+	/*Saturation level 5*/
+	{0x81, 0x33, INVMASK(0x33)},
+	{0xd8, 0x50, INVMASK(0xff)},
+	{0xd9, 0x50, INVMASK(0xff)},
+	{0xd2, 0x02, INVMASK(0xff)},
+};
+
+struct OV7692_WREG ov7692_saturation_lv6_tbl[] = {
+	/*Saturation level 6*/
+	{0x81, 0x33, INVMASK(0x33)},
+	{0xd8, 0x60, INVMASK(0xff)},
+	{0xd9, 0x60, INVMASK(0xff)},
+	{0xd2, 0x02, INVMASK(0xff)},
+};
+
+struct OV7692_WREG ov7692_saturation_lv7_tbl[] = {
+	/*Saturation level 7*/
+	{0x81, 0x33, INVMASK(0x33)},
+	{0xd8, 0x70, INVMASK(0xff)},
+	{0xd9, 0x70, INVMASK(0xff)},
+	{0xd2, 0x02, INVMASK(0xff)},
+};
+
+struct OV7692_WREG ov7692_saturation_lv8_tbl[] = {
+	/*Saturation level 8*/
+	{0x81, 0x33, INVMASK(0x33)},
+	{0xd8, 0x80, INVMASK(0xff)},
+	{0xd9, 0x80, INVMASK(0xff)},
+	{0xd2, 0x02, INVMASK(0xff)},
+};
+
+/*EFFECT*/
+struct OV7692_WREG ov7692_effect_normal_tbl[] = {
+	{0x81, 0x00, INVMASK(0x20)},
+	{0x28, 0x00, },
+	{0xd2, 0x00, },
+	{0xda, 0x80, },
+	{0xdb, 0x80, },
+};
+
+struct OV7692_WREG ov7692_effect_mono_tbl[] = {
+	{0x81, 0x20, INVMASK(0x20)},
+	{0x28, 0x00, },
+	{0xd2, 0x18, },
+	{0xda, 0x80, },
+	{0xdb, 0x80, },
+};
+
+struct OV7692_WREG ov7692_effect_bw_tbl[] = {
+	{0x81, 0x20, INVMASK(0x20)},
+	{0x28, 0x00, },
+	{0xd2, 0x18, },
+	{0xda, 0x80, },
+	{0xdb, 0x80, },
+};
+
+struct OV7692_WREG ov7692_effect_sepia_tbl[] = {
+	{0x81, 0x20, INVMASK(0x20)},
+	{0x28, 0x00, },
+	{0xd2, 0x18, },
+	{0xda, 0x40, },
+	{0xdb, 0xa0, },
+};
+
+struct OV7692_WREG ov7692_effect_bluish_tbl[] = {
+	{0x81, 0x20, INVMASK(0x20)},
+	{0x28, 0x00, },
+	{0xd2, 0x18, },
+	{0xda, 0xc0, },
+	{0xdb, 0x80, },
+};
+
+struct OV7692_WREG ov7692_effect_reddish_tbl[] = {
+	{0x81, 0x20, INVMASK(0x20)},
+	{0x28, 0x00, },
+	{0xd2, 0x18, },
+	{0xda, 0x80, },
+	{0xdb, 0xc0, },
+};
+
+struct OV7692_WREG ov7692_effect_greenish_tbl[] = {
+	{0x81, 0x20, INVMASK(0x20)},
+	{0x28, 0x00, },
+	{0xd2, 0x18, },
+	{0xda, 0x60, },
+	{0xdb, 0x60, },
+};
+
+struct OV7692_WREG ov7692_effect_negative_tbl[] = {
+	{0x81, 0x20, INVMASK(0x20)},
+	{0x28, 0x80, },
+	{0xd2, 0x40, },
+	{0xda, 0x80, },
+	{0xdb, 0x80, },
+};
+
+/*Contrast*/
+struct OV7692_WREG ov7692_contrast_lv0_tbl[] = {
+	/*Contrast -4*/
+	{0xb2, 0x29},
+	{0xa3, 0x55},
+	{0xa4, 0x5b},
+	{0xa5, 0x67},
+	{0xa6, 0x7e},
+	{0xa7, 0x89},
+	{0xa8, 0x93},
+	{0xa9, 0x9c},
+	{0xaa, 0xa4},
+	{0xab, 0xac},
+	{0xac, 0xb3},
+	{0xad, 0xbe},
+	{0xae, 0xc7},
+	{0xaf, 0xd5},
+	{0xb0, 0xdd},
+	{0xb1, 0xe1},
+};
+
+struct OV7692_WREG ov7692_contrast_lv1_tbl[] = {
+	/*Contrast -3*/
+	{0xb2, 0x20},
+	{0xa3, 0x43},
+	{0xa4, 0x4a},
+	{0xa5, 0x58},
+	{0xa6, 0x73},
+	{0xa7, 0x80},
+	{0xa8, 0x8b},
+	{0xa9, 0x96},
+	{0xaa, 0x9f},
+	{0xab, 0xa8},
+	{0xac, 0xb1},
+	{0xad, 0xbe},
+	{0xae, 0xc9},
+	{0xaf, 0xd8},
+	{0xb0, 0xe2},
+	{0xb1, 0xe8},
+};
+
+struct OV7692_WREG ov7692_contrast_lv2_tbl[] = {
+	/*Contrast -2*/
+	{0xb2, 0x18},
+	{0xa3, 0x31},
+	{0xa4, 0x39},
+	{0xa5, 0x4a},
+	{0xa6, 0x68},
+	{0xa7, 0x77},
+	{0xa8, 0x84},
+	{0xa9, 0x90},
+	{0xaa, 0x9b},
+	{0xab, 0xa5},
+	{0xac, 0xaf},
+	{0xad, 0xbe},
+	{0xae, 0xca},
+	{0xaf, 0xdc},
+	{0xb0, 0xe7},
+	{0xb1, 0xee},
+};
+
+struct OV7692_WREG ov7692_contrast_lv3_tbl[] = {
+	/*Contrast -1*/
+	{0xb2, 0x10},
+	{0xa3, 0x1f},
+	{0xa4, 0x28},
+	{0xa5, 0x3b},
+	{0xa6, 0x5d},
+	{0xa7, 0x6e},
+	{0xa8, 0x7d},
+	{0xa9, 0x8a},
+	{0xaa, 0x96},
+	{0xab, 0xa2},
+	{0xac, 0xad},
+	{0xad, 0xbe},
+	{0xae, 0xcc},
+	{0xaf, 0xe0},
+	{0xb0, 0xed},
+	{0xb1, 0xf4},
+};
+
+struct OV7692_WREG ov7692_contrast_default_lv4_tbl[] = {
+	/*Contrast 0*/
+	{0xb2, 0x6},
+	{0xa3, 0xb},
+	{0xa4, 0x15},
+	{0xa5, 0x2a},
+	{0xa6, 0x51},
+	{0xa7, 0x63},
+	{0xa8, 0x74},
+	{0xa9, 0x83},
+	{0xaa, 0x91},
+	{0xab, 0x9e},
+	{0xac, 0xaa},
+	{0xad, 0xbe},
+	{0xae, 0xce},
+	{0xaf, 0xe5},
+	{0xb0, 0xf3},
+	{0xb1, 0xfb},
+};
+
+struct OV7692_WREG ov7692_contrast_lv5_tbl[] = {
+	/*Contrast 1*/
+	{0xb2, 0xc},
+	{0xa3, 0x4},
+	{0xa4, 0xc},
+	{0xa5, 0x1f},
+	{0xa6, 0x45},
+	{0xa7, 0x58},
+	{0xa8, 0x6b},
+	{0xa9, 0x7c},
+	{0xaa, 0x8d},
+	{0xab, 0x9d},
+	{0xac, 0xac},
+	{0xad, 0xc3},
+	{0xae, 0xd2},
+	{0xaf, 0xe8},
+	{0xb0, 0xf2},
+	{0xb1, 0xf7},
+};
+
+struct OV7692_WREG ov7692_contrast_lv6_tbl[] = {
+	/*Contrast 2*/
+	{0xb2, 0x1},
+	{0xa3, 0x2},
+	{0xa4, 0x9},
+	{0xa5, 0x1a},
+	{0xa6, 0x3e},
+	{0xa7, 0x4a},
+	{0xa8, 0x59},
+	{0xa9, 0x6a},
+	{0xaa, 0x79},
+	{0xab, 0x8e},
+	{0xac, 0xa4},
+	{0xad, 0xc1},
+	{0xae, 0xdb},
+	{0xaf, 0xf4},
+	{0xb0, 0xff},
+	{0xb1, 0xff},
+};
+
+struct OV7692_WREG ov7692_contrast_lv7_tbl[] = {
+	/*Contrast 3*/
+	{0xb2, 0xc},
+	{0xa3, 0x4},
+	{0xa4, 0x8},
+	{0xa5, 0x17},
+	{0xa6, 0x27},
+	{0xa7, 0x3d},
+	{0xa8, 0x54},
+	{0xa9, 0x60},
+	{0xaa, 0x77},
+	{0xab, 0x85},
+	{0xac, 0xa4},
+	{0xad, 0xc6},
+	{0xae, 0xd2},
+	{0xaf, 0xe9},
+	{0xb0, 0xf0},
+	{0xb1, 0xf7},
+};
+
+struct OV7692_WREG ov7692_contrast_lv8_tbl[] = {
+	/*Contrast 4*/
+	{0xb2, 0x1},
+	{0xa3, 0x4},
+	{0xa4, 0x4},
+	{0xa5, 0x7},
+	{0xa6, 0xb},
+	{0xa7, 0x17},
+	{0xa8, 0x2a},
+	{0xa9, 0x41},
+	{0xaa, 0x59},
+	{0xab, 0x6b},
+	{0xac, 0x8b},
+	{0xad, 0xb1},
+	{0xae, 0xd2},
+	{0xaf, 0xea},
+	{0xb0, 0xf4},
+	{0xb1, 0xff},
+};
+
+	/*Sharpness*/
+struct OV7692_WREG ov7692_sharpness_lv0_tbl[] = {
+	/*Sharpness 0*/
+	{0xb4, 0x20, INVMASK(0x20)},
+	{0xb6, 0x00, INVMASK(0x1f)},
+};
+struct OV7692_WREG ov7692_sharpness_lv1_tbl[] = {
+	/*Sharpness 1*/
+	{0xb4, 0x20, INVMASK(0x20)},
+	{0xb6, 0x01, INVMASK(0x1f)},
+};
+struct OV7692_WREG ov7692_sharpness_default_lv2_tbl[] = {
+	/*Sharpness Auto (Default)*/
+	{0xb4, 0x00, INVMASK(0x20)},
+	{0xb6, 0x00, INVMASK(0x1f)},
+};
+struct OV7692_WREG ov7692_sharpness_lv3_tbl[] = {
+	/*Sharpness 3*/
+	{0xb4, 0x20, INVMASK(0x20)},
+	{0xb6, 0x66, INVMASK(0x04)},
+};
+struct OV7692_WREG ov7692_sharpness_lv4_tbl[] = {
+	/*Sharpness 4*/
+	{0xb4, 0x20, INVMASK(0x20)},
+	{0xb6, 0x99, INVMASK(0x1f)},
+};
+struct OV7692_WREG ov7692_sharpness_lv5_tbl[] = {
+	/*Sharpness 5*/
+	{0xb4, 0x20, INVMASK(0x20)},
+	{0xb6, 0xcc, INVMASK(0x1f)},
+};
+struct OV7692_WREG ov7692_sharpness_lv6_tbl[] = {
+	/*Sharpness 6*/
+	{0xb4, 0x20, INVMASK(0x20)},
+	{0xb6, 0xff, INVMASK(0x1f)},
+};
+
+	/* ISO TYPE*/
+struct OV7692_WREG ov7692_iso_type_auto[] = {
+	/*@@ISO Auto*/
+	{0x14, 0x20, INVMASK(0x70)},
+};
+
+struct OV7692_WREG ov7692_iso_type_100[] = {
+	/*@@ISO 100*/
+	{0x14, 0x00, INVMASK(0x70)},
+};
+
+struct OV7692_WREG ov7692_iso_type_200[] = {
+	/*@@ISO 200*/
+	{0x14, 0x10, INVMASK(0x70)},
+};
+
+struct OV7692_WREG ov7692_iso_type_400[] = {
+	/*@@ISO 400*/
+	{0x14, 0x20, INVMASK(0x70)},
+};
+
+struct OV7692_WREG ov7692_iso_type_800[] = {
+	/*@@ISO 800*/
+	{0x14, 0x30, INVMASK(0x70)},
+};
+
+struct OV7692_WREG ov7692_iso_type_1600[] = {
+	/*@@ISO 1600*/
+	{0x14, 0x40, INVMASK(0x70)},
+};
+
+	/*Light Mode*/
+struct OV7692_WREG ov7692_wb_def[] = {
+	{0x13, 0xf7},
+	{0x15, 0x00},
+};
+
+struct OV7692_WREG ov7692_wb_custom[] = {
+	{0x13, 0xf5},
+	{0x01, 0x56},
+	{0x02, 0x50},
+	{0x15, 0x00},
+};
+
+struct OV7692_WREG ov7692_wb_inc[] = {
+	{0x13, 0xf5},
+	{0x01, 0x66},
+	{0x02, 0x40},
+	{0x15, 0x00},
+};
+
+struct OV7692_WREG ov7692_wb_daylight[] = {
+	{0x13, 0xf5},
+	{0x01, 0x43},
+	{0x02, 0x5d},
+	{0x15, 0x00},
+};
+
+struct OV7692_WREG ov7692_wb_cloudy[] = {
+	{0x13, 0xf5},
+	{0x01, 0x48},
+	{0x02, 0x63},
+	{0x15, 0x00},
+};
+
+#endif
+
diff --git a/drivers/media/platform/msm/camera_v1/ov7692_qrd.c b/drivers/media/platform/msm/camera_v1/ov7692_qrd.c
new file mode 100644
index 0000000..05a82ab
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/ov7692_qrd.c
@@ -0,0 +1,1178 @@
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/slab.h>
+#include <media/msm_camera.h>
+#include <mach/camera.h>
+#include <mach/gpio.h>
+#include "ov7692.h"
+
+/*=============================================================
+    SENSOR REGISTER DEFINES
+==============================================================*/
+#define Q8    0x00000100
+
+/* Omnivision8810 product ID register address */
+#define REG_OV7692_MODEL_ID_MSB                       0x0A
+#define REG_OV7692_MODEL_ID_LSB                       0x0B
+
+#define OV7692_MODEL_ID                       0x7692
+/* Omnivision8810 product ID */
+
+/* Time in milisecs for waiting for the sensor to reset */
+#define OV7692_RESET_DELAY_MSECS    66
+#define OV7692_DEFAULT_CLOCK_RATE   24000000
+/* Registers*/
+
+/* Color bar pattern selection */
+#define OV7692_COLOR_BAR_PATTERN_SEL_REG     0x82
+/* Color bar enabling control */
+#define OV7692_COLOR_BAR_ENABLE_REG           0x601
+/* Time in milisecs for waiting for the sensor to reset*/
+#define OV7692_RESET_DELAY_MSECS    66
+
+static int ov7692_pwdn_gpio;
+static int ov7692_reset_gpio;
+
+
+/*============================================================================
+			DATA DECLARATIONS
+============================================================================*/
+
+
+static bool OV7692_CSI_CONFIG;
+/* 816x612, 24MHz MCLK 96MHz PCLK */
+uint32_t OV7692_FULL_SIZE_WIDTH        = 640;
+uint32_t OV7692_FULL_SIZE_HEIGHT       = 480;
+
+uint32_t OV7692_QTR_SIZE_WIDTH         = 640;
+uint32_t OV7692_QTR_SIZE_HEIGHT        = 480;
+
+uint32_t OV7692_HRZ_FULL_BLK_PIXELS    = 16;
+uint32_t OV7692_VER_FULL_BLK_LINES     = 12;
+uint32_t OV7692_HRZ_QTR_BLK_PIXELS     = 16;
+uint32_t OV7692_VER_QTR_BLK_LINES      = 12;
+
+struct ov7692_work_t {
+	struct work_struct work;
+};
+static struct  ov7692_work_t *ov7692_sensorw;
+static struct  i2c_client *ov7692_client;
+struct ov7692_ctrl_t {
+	const struct  msm_camera_sensor_info *sensordata;
+	uint32_t sensormode;
+	uint32_t fps_divider;        /* init to 1 * 0x00000400 */
+	uint32_t pict_fps_divider;    /* init to 1 * 0x00000400 */
+	uint32_t fps;
+	int32_t  curr_lens_pos;
+	uint32_t curr_step_pos;
+	uint32_t my_reg_gain;
+	uint32_t my_reg_line_count;
+	uint32_t total_lines_per_frame;
+	enum ov7692_resolution_t prev_res;
+	enum ov7692_resolution_t pict_res;
+	enum ov7692_resolution_t curr_res;
+	enum ov7692_test_mode_t  set_test;
+	unsigned short imgaddr;
+};
+static struct ov7692_ctrl_t *ov7692_ctrl;
+static DECLARE_WAIT_QUEUE_HEAD(ov7692_wait_queue);
+DEFINE_MUTEX(ov7692_mut);
+static int effect_value;
+static int16_t ov7692_effect = CAMERA_EFFECT_OFF;
+static unsigned int SAT_U = 0x80;
+static unsigned int SAT_V = 0x80;
+
+/*=============================================================*/
+
+static int ov7692_i2c_rxdata(unsigned short saddr,
+		unsigned char *rxdata, int length)
+{
+	struct i2c_msg msgs[] = {
+		{
+			.addr  = saddr,
+			.flags = 0,
+			.len   = 1,
+			.buf   = rxdata,
+		},
+		{
+			.addr  = saddr,
+			.flags = I2C_M_RD,
+			.len   = 1,
+			.buf   = rxdata,
+		},
+	};
+	if (i2c_transfer(ov7692_client->adapter, msgs, 2) < 0) {
+		CDBG("ov7692_i2c_rxdata failed!\n");
+		return -EIO;
+	}
+	return 0;
+}
+static int32_t ov7692_i2c_txdata(unsigned short saddr,
+		unsigned char *txdata, int length)
+{
+	struct i2c_msg msg[] = {
+		{
+			.addr = saddr,
+			.flags = 0,
+			.len = 2,
+			.buf = txdata,
+		},
+	};
+	if (i2c_transfer(ov7692_client->adapter, msg, 1) < 0) {
+		CDBG("ov7692_i2c_txdata faild 0x%x\n", ov7692_client->addr);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t ov7692_i2c_read(uint8_t raddr,
+		uint8_t *rdata, int rlen)
+{
+	int32_t rc = 0;
+	unsigned char buf[1];
+	if (!rdata)
+		return -EIO;
+	memset(buf, 0, sizeof(buf));
+	buf[0] = raddr;
+	rc = ov7692_i2c_rxdata(ov7692_client->addr >> 1, buf, rlen);
+	if (rc < 0) {
+		CDBG("ov7692_i2c_read 0x%x failed!\n", raddr);
+		return rc;
+	}
+	*rdata = buf[0];
+	return rc;
+}
+static int32_t ov7692_i2c_write_b_sensor(uint8_t waddr, uint8_t bdata)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[2];
+
+	memset(buf, 0, sizeof(buf));
+	buf[0] = waddr;
+	buf[1] = bdata;
+	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
+	rc = ov7692_i2c_txdata(ov7692_client->addr >> 1, buf, 2);
+	if (rc < 0)
+		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
+		waddr, bdata);
+
+	return rc;
+}
+
+static int32_t OV7692_WritePRegs(struct OV7692_WREG *pTb, int32_t len)
+{
+	int32_t i, ret = 0;
+	uint8_t regv;
+
+	for (i = 0; i < len; i++) {
+		if (pTb[i].mask == 0) {
+			ov7692_i2c_write_b_sensor(pTb[i].addr, pTb[i].data);
+		} else {
+			ov7692_i2c_read(pTb[i].addr, &regv, 1);
+			regv &= pTb[i].mask;
+			regv |= (pTb[i].data & (~pTb[i].mask));
+			ov7692_i2c_write_b_sensor(pTb[i].addr, regv);
+		}
+	}
+	return ret;
+}
+
+static int32_t ov7692_sensor_setting(int update_type, int rt)
+{
+	int32_t i, array_length;
+	int32_t rc = 0;
+	struct msm_camera_csi_params ov7692_csi_params;
+
+	CDBG("%s: rt = %d\n", __func__, rt);
+
+	switch (update_type) {
+	case REG_INIT:
+		OV7692_CSI_CONFIG = 0;
+		ov7692_i2c_write_b_sensor(0x0e, 0x08);
+		return rc;
+		break;
+	case UPDATE_PERIODIC:
+		if (!OV7692_CSI_CONFIG) {
+			ov7692_csi_params.lane_cnt = 1;
+			ov7692_csi_params.data_format = CSI_8BIT;
+			ov7692_csi_params.lane_assign = 0xe4;
+			ov7692_csi_params.dpcm_scheme = 0;
+			ov7692_csi_params.settle_cnt = 0x14;
+
+			array_length = sizeof(ov7692_init_settings_array) /
+				sizeof(ov7692_init_settings_array[0]);
+			for (i = 0; i < array_length; i++) {
+				rc = ov7692_i2c_write_b_sensor(
+				ov7692_init_settings_array[i].reg_addr,
+				ov7692_init_settings_array[i].reg_val);
+				if (rc < 0)
+					return rc;
+			}
+			usleep_range(10000, 11000);
+			rc = msm_camio_csi_config(&ov7692_csi_params);
+			usleep_range(10000, 11000);
+			ov7692_i2c_write_b_sensor(0x0e, 0x00);
+			OV7692_CSI_CONFIG = 1;
+			msleep(20);
+			return rc;
+		}
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
+static int32_t ov7692_video_config(int mode)
+{
+	int32_t rc = 0;
+	int rt;
+	/* change sensor resolution if needed */
+	rt = RES_PREVIEW;
+
+	CDBG("%s\n", __func__);
+
+	if (ov7692_sensor_setting(UPDATE_PERIODIC, rt) < 0)
+		return rc;
+	ov7692_ctrl->curr_res = ov7692_ctrl->prev_res;
+	ov7692_ctrl->sensormode = mode;
+	return rc;
+}
+
+static int32_t ov7692_set_sensor_mode(int mode,
+		int res)
+{
+	int32_t rc = 0;
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		rc = ov7692_video_config(mode);
+		break;
+	case SENSOR_SNAPSHOT_MODE:
+	case SENSOR_RAW_SNAPSHOT_MODE:
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
+static int ov7692_set_exposure_compensation(int compensation)
+{
+	long rc = 0;
+
+	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+	CDBG("--CAMERA-- %s ...exposure_compensation = %d\n",
+		 __func__ , compensation);
+	switch (compensation) {
+	case CAMERA_EXPOSURE_COMPENSATION_LV0:
+		CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV0\n");
+		rc = OV7692Core_WritePREG(
+			ov7692_exposure_compensation_lv0_tbl);
+		break;
+	case CAMERA_EXPOSURE_COMPENSATION_LV1:
+		CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV1\n");
+		rc = OV7692Core_WritePREG(
+			ov7692_exposure_compensation_lv1_tbl);
+		break;
+	case CAMERA_EXPOSURE_COMPENSATION_LV2:
+		CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV2\n");
+		rc = OV7692Core_WritePREG(
+			ov7692_exposure_compensation_lv2_default_tbl);
+		break;
+	case CAMERA_EXPOSURE_COMPENSATION_LV3:
+		CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV3\n");
+		rc = OV7692Core_WritePREG(
+			ov7692_exposure_compensation_lv3_tbl);
+		break;
+	case CAMERA_EXPOSURE_COMPENSATION_LV4:
+		CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV3\n");
+		rc = OV7692Core_WritePREG(
+			ov7692_exposure_compensation_lv4_tbl);
+		break;
+	default:
+		CDBG("--CAMERA--ERROR CAMERA_EXPOSURE_COMPENSATION\n");
+		break;
+	}
+	CDBG("--CAMERA-- %s ...(End)\n", __func__);
+	return rc;
+}
+
+static long ov7692_set_antibanding(int antibanding)
+{
+	long rc = 0;
+
+	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+	CDBG("--CAMERA-- %s ...antibanding = %d\n", __func__, antibanding);
+	switch (antibanding) {
+	case CAMERA_ANTIBANDING_OFF:
+		CDBG("--CAMERA--CAMERA_ANTIBANDING_OFF\n");
+		break;
+	case CAMERA_ANTIBANDING_60HZ:
+		CDBG("--CAMERA--CAMERA_ANTIBANDING_60HZ\n");
+		rc = OV7692Core_WritePREG(ov7692_antibanding_60z_tbl);
+		break;
+	case CAMERA_ANTIBANDING_50HZ:
+		CDBG("--CAMERA--CAMERA_ANTIBANDING_50HZ\n");
+		rc = OV7692Core_WritePREG(ov7692_antibanding_50z_tbl);
+		break;
+	case CAMERA_ANTIBANDING_AUTO:
+		CDBG("--CAMERA--CAMERA_ANTIBANDING_AUTO\n");
+		rc = OV7692Core_WritePREG(ov7692_antibanding_auto_tbl);
+		break;
+	default:
+		CDBG("--CAMERA--CAMERA_ANTIBANDING_ERROR COMMAND\n");
+		break;
+	}
+	CDBG("--CAMERA-- %s ...(End)\n", __func__);
+	return rc;
+}
+
+static int ov7692_set_saturation(int saturation)
+{
+	long rc = 0;
+
+	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+	CDBG("--CAMERA-- %s ...saturation = %d\n", __func__ , saturation);
+
+	if (effect_value == CAMERA_EFFECT_OFF) {
+		switch (saturation) {
+		case CAMERA_SATURATION_LV0:
+			CDBG("--CAMERA--CAMERA_SATURATION_LV0\n");
+			rc = OV7692Core_WritePREG(ov7692_saturation_lv0_tbl);
+			break;
+		case CAMERA_SATURATION_LV1:
+			CDBG("--CAMERA--CAMERA_SATURATION_LV1\n");
+			rc = OV7692Core_WritePREG(ov7692_saturation_lv1_tbl);
+			break;
+		case CAMERA_SATURATION_LV2:
+			CDBG("--CAMERA--CAMERA_SATURATION_LV2\n");
+			rc = OV7692Core_WritePREG(ov7692_saturation_lv2_tbl);
+			break;
+		case CAMERA_SATURATION_LV3:
+			CDBG("--CAMERA--CAMERA_SATURATION_LV3\n");
+			rc = OV7692Core_WritePREG(ov7692_saturation_lv3_tbl);
+			break;
+		case CAMERA_SATURATION_LV4:
+			CDBG("--CAMERA--CAMERA_SATURATION_LV4\n");
+			rc = OV7692Core_WritePREG(
+				ov7692_saturation_default_lv4_tbl);
+			break;
+		case CAMERA_SATURATION_LV5:
+			CDBG("--CAMERA--CAMERA_SATURATION_LV5\n");
+			rc = OV7692Core_WritePREG(ov7692_saturation_lv5_tbl);
+			break;
+		case CAMERA_SATURATION_LV6:
+			CDBG("--CAMERA--CAMERA_SATURATION_LV6\n");
+			rc = OV7692Core_WritePREG(ov7692_saturation_lv6_tbl);
+			break;
+		case CAMERA_SATURATION_LV7:
+			CDBG("--CAMERA--CAMERA_SATURATION_LV7\n");
+			rc = OV7692Core_WritePREG(ov7692_saturation_lv7_tbl);
+			break;
+		case CAMERA_SATURATION_LV8:
+			CDBG("--CAMERA--CAMERA_SATURATION_LV8\n");
+			rc = OV7692Core_WritePREG(ov7692_saturation_lv8_tbl);
+			break;
+		default:
+			CDBG("--CAMERA--CAMERA_SATURATION_ERROR COMMAND\n");
+			break;
+		}
+	}
+
+	/*for recover saturation level when change special effect*/
+	switch (saturation) {
+	case CAMERA_SATURATION_LV0:
+		CDBG("--CAMERA--CAMERA_SATURATION_LV0\n");
+		SAT_U = 0x00;
+		SAT_V = 0x00;
+		break;
+	case CAMERA_SATURATION_LV1:
+		CDBG("--CAMERA--CAMERA_SATURATION_LV1\n");
+		SAT_U = 0x10;
+		SAT_V = 0x10;
+		break;
+	case CAMERA_SATURATION_LV2:
+		CDBG("--CAMERA--CAMERA_SATURATION_LV2\n");
+		SAT_U = 0x20;
+		SAT_V = 0x20;
+		break;
+	case CAMERA_SATURATION_LV3:
+		CDBG("--CAMERA--CAMERA_SATURATION_LV3\n");
+		SAT_U = 0x30;
+		SAT_V = 0x30;
+		break;
+	case CAMERA_SATURATION_LV4:
+		CDBG("--CAMERA--CAMERA_SATURATION_LV4\n");
+		SAT_U = 0x40;
+		SAT_V = 0x40;
+		break;
+	case CAMERA_SATURATION_LV5:
+		CDBG("--CAMERA--CAMERA_SATURATION_LV5\n");
+		SAT_U = 0x50;
+		SAT_V = 0x50;
+		break;
+	case CAMERA_SATURATION_LV6:
+		CDBG("--CAMERA--CAMERA_SATURATION_LV6\n");
+		SAT_U = 0x60;
+		SAT_V = 0x60;
+		break;
+	case CAMERA_SATURATION_LV7:
+		CDBG("--CAMERA--CAMERA_SATURATION_LV7\n");
+		SAT_U = 0x70;
+		SAT_V = 0x70;
+		break;
+	case CAMERA_SATURATION_LV8:
+		CDBG("--CAMERA--CAMERA_SATURATION_LV8\n");
+		SAT_U = 0x80;
+		SAT_V = 0x80;
+		break;
+	default:
+		CDBG("--CAMERA--CAMERA_SATURATION_ERROR COMMAND\n");
+		break;
+	}
+	CDBG("--CAMERA-- %s ...(End)\n", __func__);
+	return rc;
+}
+
+static long ov7692_set_effect(int mode, int effect)
+{
+	int rc = 0;
+	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		break;
+	case SENSOR_HFR_60FPS_MODE:
+		break;
+	case SENSOR_HFR_90FPS_MODE:
+		/* Context A Special Effects */
+		CDBG("-CAMERA- %s ...SENSOR_PREVIEW_MODE\n", __func__);
+		break;
+	case SENSOR_SNAPSHOT_MODE:
+		/* Context B Special Effects */
+		CDBG("-CAMERA- %s ...SENSOR_SNAPSHOT_MODE\n", __func__);
+		break;
+	default:
+		break;
+	}
+	effect_value = effect;
+	switch (effect) {
+	case CAMERA_EFFECT_OFF: {
+		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_OFF\n", __func__);
+		rc = OV7692Core_WritePREG(ov7692_effect_normal_tbl);
+		/* for recover saturation level
+		 when change special effect*/
+		ov7692_i2c_write_b_sensor(0xda, SAT_U);
+		/* for recover saturation level
+		when change special effect*/
+		ov7692_i2c_write_b_sensor(0xdb, SAT_V);
+		break;
+	}
+	case CAMERA_EFFECT_MONO: {
+		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_MONO\n", __func__);
+		rc = OV7692Core_WritePREG(ov7692_effect_mono_tbl);
+		break;
+	}
+	case CAMERA_EFFECT_BW: {
+		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_BW\n", __func__);
+		rc = OV7692Core_WritePREG(ov7692_effect_bw_tbl);
+		break;
+	}
+	case CAMERA_EFFECT_BLUISH: {
+		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_BLUISH\n", __func__);
+		rc = OV7692Core_WritePREG(ov7692_effect_bluish_tbl);
+		break;
+	}
+	case CAMERA_EFFECT_SOLARIZE: {
+		CDBG("%s ...CAMERA_EFFECT_NEGATIVE(No Support)!\n", __func__);
+		break;
+	}
+	case CAMERA_EFFECT_SEPIA: {
+		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_SEPIA\n", __func__);
+		rc = OV7692Core_WritePREG(ov7692_effect_sepia_tbl);
+		break;
+	}
+	case CAMERA_EFFECT_REDDISH: {
+		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_REDDISH\n", __func__);
+		rc = OV7692Core_WritePREG(ov7692_effect_reddish_tbl);
+		break;
+	}
+	case CAMERA_EFFECT_GREENISH: {
+		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_GREENISH\n", __func__);
+		rc = OV7692Core_WritePREG(ov7692_effect_greenish_tbl);
+		break;
+	}
+	case CAMERA_EFFECT_NEGATIVE: {
+		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_NEGATIVE\n", __func__);
+		rc = OV7692Core_WritePREG(ov7692_effect_negative_tbl);
+		break;
+	}
+	default: {
+		CDBG("--CAMERA-- %s ...Default(Not Support)\n", __func__);
+	}
+	}
+	ov7692_effect = effect;
+	/*Refresh Sequencer */
+	CDBG("--CAMERA-- %s ...(End)\n", __func__);
+	return rc;
+}
+
+static int ov7692_set_contrast(int contrast)
+{
+	int rc = 0;
+	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+	CDBG("--CAMERA-- %s ...contrast = %d\n", __func__ , contrast);
+
+	if (effect_value == CAMERA_EFFECT_OFF) {
+		switch (contrast) {
+		case CAMERA_CONTRAST_LV0:
+			CDBG("--CAMERA--CAMERA_CONTRAST_LV0\n");
+			rc = OV7692Core_WritePREG(ov7692_contrast_lv0_tbl);
+			break;
+		case CAMERA_CONTRAST_LV1:
+			CDBG("--CAMERA--CAMERA_CONTRAST_LV1\n");
+			rc = OV7692Core_WritePREG(ov7692_contrast_lv1_tbl);
+			break;
+		case CAMERA_CONTRAST_LV2:
+			CDBG("--CAMERA--CAMERA_CONTRAST_LV2\n");
+			rc = OV7692Core_WritePREG(ov7692_contrast_lv2_tbl);
+			break;
+		case CAMERA_CONTRAST_LV3:
+			CDBG("--CAMERA--CAMERA_CONTRAST_LV3\n");
+			rc = OV7692Core_WritePREG(ov7692_contrast_lv3_tbl);
+			break;
+		case CAMERA_CONTRAST_LV4:
+			CDBG("--CAMERA--CAMERA_CONTRAST_LV4\n");
+			rc = OV7692Core_WritePREG(
+				ov7692_contrast_default_lv4_tbl);
+			break;
+		case CAMERA_CONTRAST_LV5:
+			CDBG("--CAMERA--CAMERA_CONTRAST_LV5\n");
+			rc = OV7692Core_WritePREG(ov7692_contrast_lv5_tbl);
+			break;
+		case CAMERA_CONTRAST_LV6:
+			CDBG("--CAMERA--CAMERA_CONTRAST_LV6\n");
+			rc = OV7692Core_WritePREG(ov7692_contrast_lv6_tbl);
+			break;
+		case CAMERA_CONTRAST_LV7:
+			CDBG("--CAMERA--CAMERA_CONTRAST_LV7\n");
+			rc = OV7692Core_WritePREG(ov7692_contrast_lv7_tbl);
+			break;
+		case CAMERA_CONTRAST_LV8:
+			CDBG("--CAMERA--CAMERA_CONTRAST_LV8\n");
+			rc = OV7692Core_WritePREG(ov7692_contrast_lv8_tbl);
+			break;
+		default:
+			CDBG("--CAMERA--CAMERA_CONTRAST_ERROR COMMAND\n");
+			break;
+		}
+	}
+	CDBG("--CAMERA-- %s ...(End)\n", __func__);
+	return rc;
+}
+
+static int ov7692_set_sharpness(int sharpness)
+{
+	int rc = 0;
+	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+	CDBG("--CAMERA-- %s ...sharpness = %d\n", __func__ , sharpness);
+
+	if (effect_value == CAMERA_EFFECT_OFF) {
+		switch (sharpness) {
+		case CAMERA_SHARPNESS_LV0:
+			CDBG("--CAMERA--CAMERA_SHARPNESS_LV0\n");
+			rc = OV7692Core_WritePREG(ov7692_sharpness_lv0_tbl);
+			break;
+		case CAMERA_SHARPNESS_LV1:
+			CDBG("--CAMERA--CAMERA_SHARPNESS_LV1\n");
+			rc = OV7692Core_WritePREG(ov7692_sharpness_lv1_tbl);
+			break;
+		case CAMERA_SHARPNESS_LV2:
+			CDBG("--CAMERA--CAMERA_SHARPNESS_LV2\n");
+			rc = OV7692Core_WritePREG(
+				ov7692_sharpness_default_lv2_tbl);
+			break;
+		case CAMERA_SHARPNESS_LV3:
+			CDBG("--CAMERA--CAMERA_SHARPNESS_LV3\n");
+			rc = OV7692Core_WritePREG(ov7692_sharpness_lv3_tbl);
+			break;
+		case CAMERA_SHARPNESS_LV4:
+			CDBG("--CAMERA--CAMERA_SHARPNESS_LV4\n");
+			rc = OV7692Core_WritePREG(ov7692_sharpness_lv4_tbl);
+			break;
+		case CAMERA_SHARPNESS_LV5:
+			CDBG("--CAMERA--CAMERA_SHARPNESS_LV5\n");
+			rc = OV7692Core_WritePREG(ov7692_sharpness_lv5_tbl);
+			break;
+		case CAMERA_SHARPNESS_LV6:
+			CDBG("--CAMERA--CAMERA_SHARPNESS_LV6\n");
+			rc = OV7692Core_WritePREG(ov7692_sharpness_lv6_tbl);
+			break;
+		default:
+			CDBG("--CAMERA--CAMERA_SHARPNESS_ERROR COMMAND\n");
+			break;
+		}
+	}
+	CDBG("--CAMERA-- %s ...(End)\n", __func__);
+	return rc;
+}
+
+static int ov7692_set_iso(int8_t iso_type)
+{
+	long rc = 0;
+
+	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+	CDBG("--CAMERA-- %s ...iso_type = %d\n", __func__ , iso_type);
+	switch (iso_type) {
+	case CAMERA_ISO_TYPE_AUTO:
+		CDBG("--CAMERA--CAMERA_ISO_TYPE_AUTO\n");
+		rc = OV7692Core_WritePREG(ov7692_iso_type_auto);
+		break;
+	case CAMEAR_ISO_TYPE_HJR:
+		CDBG("--CAMERA--CAMEAR_ISO_TYPE_HJR\n");
+		rc = OV7692Core_WritePREG(ov7692_iso_type_auto);
+		break;
+	case CAMEAR_ISO_TYPE_100:
+		CDBG("--CAMERA--CAMEAR_ISO_TYPE_100\n");
+		rc = OV7692Core_WritePREG(ov7692_iso_type_100);
+		break;
+	case CAMERA_ISO_TYPE_200:
+		CDBG("--CAMERA--CAMERA_ISO_TYPE_200\n");
+		rc = OV7692Core_WritePREG(ov7692_iso_type_200);
+		break;
+	case CAMERA_ISO_TYPE_400:
+		CDBG("--CAMERA--CAMERA_ISO_TYPE_400\n");
+		rc = OV7692Core_WritePREG(ov7692_iso_type_400);
+		break;
+	case CAMEAR_ISO_TYPE_800:
+		CDBG("--CAMERA--CAMEAR_ISO_TYPE_800\n");
+		rc = OV7692Core_WritePREG(ov7692_iso_type_800);
+		break;
+	case CAMERA_ISO_TYPE_1600:
+		CDBG("--CAMERA--CAMERA_ISO_TYPE_1600\n");
+		rc = OV7692Core_WritePREG(ov7692_iso_type_1600);
+		break;
+	default:
+		CDBG("--CAMERA--ERROR ISO TYPE\n");
+		break;
+	}
+	CDBG("--CAMERA-- %s ...(End)\n", __func__);
+	return rc;
+}
+
+static int ov7692_set_wb_oem(uint8_t param)
+{
+	int rc = 0;
+	CDBG("--CAMERA--%s runs\r\n", __func__);
+
+	switch (param) {
+	case CAMERA_WB_AUTO:
+		CDBG("--CAMERA--CAMERA_WB_AUTO\n");
+		rc = OV7692Core_WritePREG(ov7692_wb_def);
+		break;
+	case CAMERA_WB_CUSTOM:
+		CDBG("--CAMERA--CAMERA_WB_CUSTOM\n");
+		rc = OV7692Core_WritePREG(ov7692_wb_custom);
+		break;
+	case CAMERA_WB_INCANDESCENT:
+		CDBG("--CAMERA--CAMERA_WB_INCANDESCENT\n");
+		rc = OV7692Core_WritePREG(ov7692_wb_inc);
+		break;
+	case CAMERA_WB_DAYLIGHT:
+		CDBG("--CAMERA--CAMERA_WB_DAYLIGHT\n");
+		rc = OV7692Core_WritePREG(ov7692_wb_daylight);
+		break;
+	case CAMERA_WB_CLOUDY_DAYLIGHT:
+		CDBG("--CAMERA--CAMERA_WB_CLOUDY_DAYLIGHT\n");
+		rc = OV7692Core_WritePREG(ov7692_wb_cloudy);
+		break;
+	default:
+		break;
+	}
+	return rc;
+}
+
+static void ov7692_power_on(void)
+{
+	CDBG("%s\n", __func__);
+	gpio_set_value(ov7692_pwdn_gpio, 0);
+}
+
+static void ov7692_power_down(void)
+{
+	CDBG("%s\n", __func__);
+	gpio_set_value(ov7692_pwdn_gpio, 1);
+}
+
+static void ov7692_sw_reset(void)
+{
+	CDBG("%s\n", __func__);
+	ov7692_i2c_write_b_sensor(0x12, 0x80);
+}
+
+static void ov7692_hw_reset(void)
+{
+	CDBG("--CAMERA-- %s ... (Start...)\n", __func__);
+	gpio_set_value(ov7692_reset_gpio, 1);   /*reset camera reset pin*/
+	usleep_range(5000, 5100);
+	gpio_set_value(ov7692_reset_gpio, 0);
+	usleep_range(5000, 5100);
+	gpio_set_value(ov7692_reset_gpio, 1);
+	usleep_range(1000, 1100);
+	CDBG("--CAMERA-- %s ... (End...)\n", __func__);
+}
+
+
+
+static int ov7692_probe_init_sensor(const struct msm_camera_sensor_info *data)
+{
+	uint8_t model_id_msb, model_id_lsb = 0;
+	uint16_t model_id = 0;
+	int32_t rc = 0;
+	/*The reset pin is not physically connected to the sensor.
+	  The standby pin will do the reset hence there is no need
+	  to request the gpio reset*/
+
+	/* Read sensor Model ID: */
+	rc = ov7692_i2c_read(REG_OV7692_MODEL_ID_MSB, &model_id_msb, 1);
+	if (rc < 0)
+		goto init_probe_fail;
+	rc = ov7692_i2c_read(REG_OV7692_MODEL_ID_LSB, &model_id_lsb, 1);
+	if (rc < 0)
+		goto init_probe_fail;
+	model_id = (model_id_msb << 8) | ((model_id_lsb & 0x00FF)) ;
+	CDBG("ov7692 model_id = 0x%x, 0x%x, 0x%x\n",
+			model_id, model_id_msb, model_id_lsb);
+	/* 4. Compare sensor ID to OV7692 ID: */
+	if (model_id != OV7692_MODEL_ID) {
+		rc = -ENODEV;
+		goto init_probe_fail;
+	}
+	goto init_probe_done;
+init_probe_fail:
+	pr_warning(" ov7692_probe_init_sensor fails\n");
+init_probe_done:
+	CDBG(" ov7692_probe_init_sensor finishes\n");
+	return rc;
+}
+
+int ov7692_sensor_open_init(const struct msm_camera_sensor_info *data)
+{
+	int32_t rc = 0;
+
+	CDBG("%s: %d\n", __func__, __LINE__);
+	CDBG("Calling ov7692_sensor_open_init\n");
+	ov7692_ctrl = kzalloc(sizeof(struct ov7692_ctrl_t), GFP_KERNEL);
+	if (!ov7692_ctrl) {
+		CDBG("ov7692_init failed!\n");
+		rc = -ENOMEM;
+		goto init_done;
+	}
+	ov7692_ctrl->fps_divider = 1 * 0x00000400;
+	ov7692_ctrl->pict_fps_divider = 1 * 0x00000400;
+	ov7692_ctrl->fps = 30 * Q8;
+	ov7692_ctrl->set_test = TEST_OFF;
+	ov7692_ctrl->prev_res = QTR_SIZE;
+	ov7692_ctrl->pict_res = FULL_SIZE;
+	ov7692_ctrl->curr_res = INVALID_SIZE;
+
+	if (data)
+		ov7692_ctrl->sensordata = data;
+	/* turn on LDO for PVT */
+	if (data->pmic_gpio_enable)
+		lcd_camera_power_onoff(1);
+
+	/* enable mclk first */
+
+	msm_camio_clk_rate_set(24000000);
+	msleep(20);
+
+	ov7692_power_on();
+	usleep_range(5000, 5100);
+
+	rc = ov7692_probe_init_sensor(data);
+	if (rc < 0) {
+		CDBG("Calling ov7692_sensor_open_init fail\n");
+		goto init_fail;
+	}
+
+	rc = ov7692_sensor_setting(REG_INIT, RES_PREVIEW);
+	if (rc < 0)
+		goto init_fail;
+	else
+		goto init_done;
+
+init_fail:
+	CDBG(" ov7692_sensor_open_init fail\n");
+	if (data->pmic_gpio_enable)
+		lcd_camera_power_onoff(0);
+	kfree(ov7692_ctrl);
+init_done:
+	CDBG("ov7692_sensor_open_init done\n");
+	return rc;
+}
+
+static int ov7692_init_client(struct i2c_client *client)
+{
+	/* Initialize the MSM_CAMI2C Chip */
+	init_waitqueue_head(&ov7692_wait_queue);
+	return 0;
+}
+
+static const struct i2c_device_id ov7692_i2c_id[] = {
+	{"ov7692", 0},
+	{ }
+};
+
+static int ov7692_i2c_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	int rc = 0;
+	CDBG("ov7692_i2c_probe called!\n");
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		CDBG("i2c_check_functionality failed\n");
+		goto probe_failure;
+	}
+
+	ov7692_sensorw = kzalloc(sizeof(struct ov7692_work_t), GFP_KERNEL);
+	if (!ov7692_sensorw) {
+		CDBG("kzalloc failed.\n");
+		rc = -ENOMEM;
+		goto probe_failure;
+	}
+
+	i2c_set_clientdata(client, ov7692_sensorw);
+	ov7692_init_client(client);
+	ov7692_client = client;
+
+	CDBG("ov7692_i2c_probe success! rc = %d\n", rc);
+	return 0;
+
+probe_failure:
+	CDBG("ov7692_i2c_probe failed! rc = %d\n", rc);
+	return rc;
+}
+
+static int __exit ov7692_remove(struct i2c_client *client)
+{
+	struct ov7692_work_t_t *sensorw = i2c_get_clientdata(client);
+	free_irq(client->irq, sensorw);
+	ov7692_client = NULL;
+	kfree(sensorw);
+	return 0;
+}
+
+static struct i2c_driver ov7692_i2c_driver = {
+	.id_table = ov7692_i2c_id,
+	.probe  = ov7692_i2c_probe,
+	.remove = __exit_p(ov7692_i2c_remove),
+	.driver = {
+		.name = "ov7692",
+	},
+};
+
+int ov7692_sensor_config(void __user *argp)
+{
+	struct sensor_cfg_data cdata;
+	long   rc = 0;
+	if (copy_from_user(&cdata,
+				(void *)argp,
+				sizeof(struct sensor_cfg_data)))
+		return -EFAULT;
+	mutex_lock(&ov7692_mut);
+	CDBG("ov7692_sensor_config: cfgtype = %d\n", cdata.cfgtype);
+	switch (cdata.cfgtype) {
+	case CFG_SET_MODE:
+		rc = ov7692_set_sensor_mode(cdata.mode, cdata.rs);
+		break;
+	case CFG_SET_EFFECT:
+		CDBG("--CAMERA-- CFG_SET_EFFECT mode=%d, effect = %d !!\n",
+			 cdata.mode, cdata.cfg.effect);
+		rc = ov7692_set_effect(cdata.mode, cdata.cfg.effect);
+		break;
+	case CFG_START:
+		CDBG("--CAMERA-- CFG_START (Not Support) !!\n");
+		/* Not Support */
+		break;
+	case CFG_PWR_UP:
+		CDBG("--CAMERA-- CFG_PWR_UP (Not Support) !!\n");
+		/* Not Support */
+		break;
+	case CFG_PWR_DOWN:
+		CDBG("--CAMERA-- CFG_PWR_DOWN !!\n");
+		ov7692_power_down();
+		break;
+	case CFG_WRITE_EXPOSURE_GAIN:
+		CDBG("--CAMERA-- CFG_WRITE_EXPOSURE_GAIN (Not Support) !!\n");
+		/* Not Support */
+		break;
+	case CFG_SET_DEFAULT_FOCUS:
+		CDBG("--CAMERA-- CFG_SET_DEFAULT_FOCUS (Not Implement) !!\n");
+		break;
+	case CFG_MOVE_FOCUS:
+		CDBG("--CAMERA-- CFG_MOVE_FOCUS (Not Implement) !!\n");
+		break;
+	case CFG_REGISTER_TO_REAL_GAIN:
+		CDBG("--CAMERA-- CFG_REGISTER_TO_REAL_GAIN (Not Support) !!\n");
+		/* Not Support */
+		break;
+	case CFG_REAL_TO_REGISTER_GAIN:
+		CDBG("--CAMERA-- CFG_REAL_TO_REGISTER_GAIN (Not Support) !!\n");
+		/* Not Support */
+		break;
+	case CFG_SET_FPS:
+		CDBG("--CAMERA-- CFG_SET_FPS (Not Support) !!\n");
+		/* Not Support */
+		break;
+	case CFG_SET_PICT_FPS:
+		CDBG("--CAMERA-- CFG_SET_PICT_FPS (Not Support) !!\n");
+		/* Not Support */
+		break;
+	case CFG_SET_BRIGHTNESS:
+		CDBG("--CAMERA-- CFG_SET_BRIGHTNESS  !!\n");
+		/* rc = ov7692_set_brightness(cdata.cfg.brightness); */
+		break;
+	case CFG_SET_CONTRAST:
+		CDBG("--CAMERA-- CFG_SET_CONTRAST  !!\n");
+		rc = ov7692_set_contrast(cdata.cfg.contrast);
+		break;
+	case CFG_SET_ZOOM:
+		CDBG("--CAMERA-- CFG_SET_ZOOM (Not Support) !!\n");
+		/* Not Support */
+		break;
+	case CFG_SET_EXPOSURE_MODE:
+		CDBG("--CAMERA-- CFG_SET_EXPOSURE_MODE !!\n");
+		/* rc = ov7692_set_exposure_mode(cdata.cfg.ae_mode); */
+		break;
+	case CFG_SET_WB:
+		CDBG("--CAMERA-- CFG_SET_WB!!\n");
+		ov7692_set_wb_oem(cdata.cfg.wb_val);
+		rc = 0 ;
+		break;
+	case CFG_SET_ANTIBANDING:
+		CDBG("--CAMERA-- CFG_SET_ANTIBANDING antibanding = %d !!\n",
+			 cdata.cfg.antibanding);
+		rc = ov7692_set_antibanding(cdata.cfg.antibanding);
+		break;
+	case CFG_SET_EXP_GAIN:
+		CDBG("--CAMERA-- CFG_SET_EXP_GAIN (Not Support) !!\n");
+		/* Not Support */
+		break;
+	case CFG_SET_PICT_EXP_GAIN:
+		CDBG("--CAMERA-- CFG_SET_PICT_EXP_GAIN (Not Support) !!\n");
+		/* Not Support */
+		break;
+	case CFG_SET_LENS_SHADING:
+		CDBG("--CAMERA-- CFG_SET_LENS_SHADING !!\n");
+		/* rc = ov7692_lens_shading_enable(cdata.cfg.lens_shading); */
+		break;
+	case CFG_GET_PICT_FPS:
+		CDBG("--CAMERA-- CFG_GET_PICT_FPS (Not Support) !!\n");
+		/* Not Support */
+		break;
+	case CFG_GET_PREV_L_PF:
+		CDBG("--CAMERA-- CFG_GET_PREV_L_PF (Not Support) !!\n");
+		/* Not Support */
+		break;
+	case CFG_GET_PREV_P_PL:
+		CDBG("--CAMERA-- CFG_GET_PREV_P_PL (Not Support) !!\n");
+		/* Not Support */
+		break;
+	case CFG_GET_PICT_L_PF:
+		CDBG("--CAMERA-- CFG_GET_PICT_L_PF (Not Support) !!\n");
+		/* Not Support */
+		break;
+	case CFG_GET_PICT_P_PL:
+		CDBG("--CAMERA-- CFG_GET_PICT_P_PL (Not Support) !!\n");
+		/* Not Support */
+		break;
+	case CFG_GET_AF_MAX_STEPS:
+		CDBG("--CAMERA-- CFG_GET_AF_MAX_STEPS (Not Support) !!\n");
+		/* Not Support */
+		break;
+	case CFG_GET_PICT_MAX_EXP_LC:
+		CDBG("--CAMERA-- CFG_GET_PICT_MAX_EXP_LC (Not Support) !!\n");
+		/* Not Support */
+		break;
+	case CFG_SEND_WB_INFO:
+		CDBG("--CAMERA-- CFG_SEND_WB_INFO (Not Support) !!\n");
+		/* Not Support */
+		break;
+	case CFG_SENSOR_INIT:
+		CDBG("--CAMERA-- CFG_SENSOR_INIT (Not Support) !!\n");
+		/* Not Support */
+		break;
+	case CFG_SET_SATURATION:
+		CDBG("--CAMERA-- CFG_SET_SATURATION !!\n");
+		rc = ov7692_set_saturation(cdata.cfg.saturation);
+		break;
+	case CFG_SET_SHARPNESS:
+		CDBG("--CAMERA-- CFG_SET_SHARPNESS !!\n");
+		rc = ov7692_set_sharpness(cdata.cfg.sharpness);
+		break;
+	case CFG_SET_TOUCHAEC:
+		CDBG("--CAMERA-- CFG_SET_TOUCHAEC!!\n");
+		/* ov7692_set_touchaec(cdata.cfg.aec_cord.x,
+			 cdata.cfg.aec_cord.y); */
+		rc = 0 ;
+		break;
+	case CFG_SET_AUTO_FOCUS:
+		CDBG("--CAMERA-- CFG_SET_AUTO_FOCUS (Not Support) !!\n");
+		/* Not Support */
+		break;
+	case CFG_SET_AUTOFLASH:
+		CDBG("--CAMERA-- CFG_SET_AUTOFLASH (Not Support) !!\n");
+		/* Not Support */
+		break;
+	case CFG_SET_EXPOSURE_COMPENSATION:
+		CDBG("--CAMERA-- CFG_SET_EXPOSURE_COMPENSATION !\n");
+		rc = ov7692_set_exposure_compensation(
+			cdata.cfg.exp_compensation);
+		break;
+	case CFG_SET_ISO:
+		CDBG("--CAMERA-- CFG_SET_ISO !\n");
+		rc = ov7692_set_iso(cdata.cfg.iso_type);
+		break;
+	default:
+		CDBG("--CAMERA-- %s: Command=%d (Not Implement) !!\n",
+			 __func__, cdata.cfgtype);
+		rc = -EINVAL;
+		break;
+	}
+
+	mutex_unlock(&ov7692_mut);
+
+	return rc;
+}
+static int ov7692_sensor_release(void)
+{
+	int rc = -EBADF;
+
+	mutex_lock(&ov7692_mut);
+	ov7692_sw_reset();
+	ov7692_power_down();
+	kfree(ov7692_ctrl);
+	ov7692_ctrl = NULL;
+	CDBG("ov7692_release completed\n");
+	mutex_unlock(&ov7692_mut);
+
+	return rc;
+}
+
+static int ov7692_probe_init_gpio(const struct msm_camera_sensor_info *data)
+{
+	int rc = 0;
+
+	ov7692_pwdn_gpio = data->sensor_pwd;
+	ov7692_reset_gpio = data->sensor_reset ;
+
+	if (data->sensor_reset_enable)
+		gpio_direction_output(data->sensor_reset, 1);
+
+	gpio_direction_output(data->sensor_pwd, 1);
+
+	return rc;
+
+}
+
+
+static int ov7692_sensor_probe(const struct msm_camera_sensor_info *info,
+		struct msm_sensor_ctrl *s)
+{
+	int rc = 0;
+	rc = i2c_add_driver(&ov7692_i2c_driver);
+	if (rc < 0 || ov7692_client == NULL) {
+		rc = -ENOTSUPP;
+		goto probe_fail;
+	}
+	pr_debug("%s: %d Entered\n", __func__, __LINE__);
+	rc = ov7692_probe_init_gpio(info);
+	if (rc < 0) {
+		CDBG("%s: gpio init failed\n", __func__);
+		goto probe_fail;
+	}
+	/* turn on LDO for PVT */
+	if (info->pmic_gpio_enable)
+		lcd_camera_power_onoff(1);
+
+	ov7692_power_down();
+
+	msm_camio_clk_rate_set(24000000);
+	usleep_range(5000, 5100);
+
+	ov7692_power_on();
+	usleep_range(5000, 5100);
+
+	if (info->sensor_reset_enable)
+		ov7692_hw_reset();
+	else
+		ov7692_sw_reset();
+
+	rc = ov7692_probe_init_sensor(info);
+	if (rc < 0)
+		goto probe_fail;
+
+
+	s->s_init = ov7692_sensor_open_init;
+	s->s_release = ov7692_sensor_release;
+	s->s_config  = ov7692_sensor_config;
+	s->s_camera_type = FRONT_CAMERA_2D;
+	s->s_mount_angle = info->sensor_platform_info->mount_angle;
+
+	/* ov7692_sw_reset(); */
+	ov7692_power_down();
+
+	if (info->pmic_gpio_enable)
+		lcd_camera_power_onoff(0);
+
+	return rc;
+
+probe_fail:
+	CDBG("ov7692_sensor_probe: SENSOR PROBE FAILS!\n");
+	if (info->pmic_gpio_enable)
+		lcd_camera_power_onoff(0);
+	i2c_del_driver(&ov7692_i2c_driver);
+	return rc;
+}
+
+static int __ov7692_probe(struct platform_device *pdev)
+{
+	return msm_camera_drv_start(pdev, ov7692_sensor_probe);
+}
+
+static struct platform_driver msm_camera_driver = {
+	.probe = __ov7692_probe,
+	.driver = {
+		.name = "msm_camera_ov7692",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init ov7692_init(void)
+{
+	return platform_driver_register(&msm_camera_driver);
+}
+
+module_init(ov7692_init);
+
+MODULE_DESCRIPTION("OMNI VGA YUV sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/ov9726.c b/drivers/media/platform/msm/camera_v1/ov9726.c
new file mode 100644
index 0000000..96a084c
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/ov9726.c
@@ -0,0 +1,794 @@
+/* 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/delay.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/slab.h>
+#include <media/msm_camera.h>
+#include <mach/gpio.h>
+#include <mach/camera.h>
+#include "ov9726.h"
+
+/*=============================================================
+	SENSOR REGISTER DEFINES
+==============================================================*/
+#define OV9726_Q8				0x00000100
+#define OV9726_Q8Shift				8
+#define OV9726_Q10				0x00000400
+#define OV9726_Q10Shift				10
+
+/* Omnivision8810 product ID register address */
+#define	OV9726_PIDH_REG				0x0000
+#define	OV9726_PIDL_REG				0x0001
+/* Omnivision8810 product ID */
+#define	OV9726_PID				0x97
+/* Omnivision8810 version */
+#define	OV9726_VER				0x26
+/* Time in milisecs for waiting for the sensor to reset */
+#define	OV9726_RESET_DELAY_MSECS		66
+#define	OV9726_DEFAULT_CLOCK_RATE		24000000
+/* Registers*/
+#define	OV9726_GAIN				0x3000
+#define	OV9726_AEC_MSB				0x3002
+#define	OV9726_AEC_LSB				0x3003
+
+/* Color bar pattern selection */
+#define OV9726_COLOR_BAR_PATTERN_SEL_REG	0x600
+/* Color bar enabling control */
+#define OV9726_COLOR_BAR_ENABLE_REG		0x601
+/* Time in milisecs for waiting for the sensor to reset*/
+#define OV9726_RESET_DELAY_MSECS		66
+/* I2C Address of the Sensor */
+/*============================================================================
+		DATA DECLARATIONS
+============================================================================*/
+#define OV9726_FULL_SIZE_DUMMY_PIXELS		0
+#define OV9726_FULL_SIZE_DUMMY_LINES		0
+#define OV9726_QTR_SIZE_DUMMY_PIXELS		0
+#define OV9726_QTR_SIZE_DUMMY_LINES		0
+
+#define OV9726_FULL_SIZE_WIDTH			1296
+#define OV9726_FULL_SIZE_HEIGHT			808
+
+#define OV9726_QTR_SIZE_WIDTH			1296
+#define OV9726_QTR_SIZE_HEIGHT			808
+
+#define OV9726_HRZ_FULL_BLK_PIXELS		368
+#define OV9726_VER_FULL_BLK_LINES		32
+#define OV9726_HRZ_QTR_BLK_PIXELS		368
+#define OV9726_VER_QTR_BLK_LINES		32
+
+#define OV9726_MSB_MASK			0xFF00
+#define OV9726_LSB_MASK			0x00FF
+
+struct ov9726_work_t {
+	struct work_struct work;
+};
+static struct ov9726_work_t *ov9726_sensorw;
+static struct i2c_client *ov9726_client;
+struct ov9726_ctrl_t {
+	const struct  msm_camera_sensor_info *sensordata;
+	uint32_t sensormode;
+	uint32_t fps_divider;		/* init to 1 * 0x00000400 */
+	uint32_t pict_fps_divider;	/* init to 1 * 0x00000400 */
+	uint16_t fps;
+	int16_t curr_lens_pos;
+	uint16_t curr_step_pos;
+	uint16_t my_reg_gain;
+	uint32_t my_reg_line_count;
+	uint16_t total_lines_per_frame;
+	enum ov9726_resolution_t prev_res;
+	enum ov9726_resolution_t pict_res;
+	enum ov9726_resolution_t curr_res;
+	enum ov9726_test_mode_t  set_test;
+	unsigned short imgaddr;
+};
+static struct ov9726_ctrl_t *ov9726_ctrl;
+static int8_t config_not_set = 1;
+static DECLARE_WAIT_QUEUE_HEAD(ov9726_wait_queue);
+DEFINE_MUTEX(ov9726_mut);
+
+/*=============================================================*/
+static int ov9726_i2c_rxdata(unsigned short saddr,
+	unsigned char *rxdata, int length)
+{
+	struct i2c_msg msgs[] = {
+	{
+		.addr  = saddr,
+		.flags = 0,
+		.len   = 2,
+		.buf   = rxdata,
+	},
+	{
+		.addr  = saddr,
+		.flags = I2C_M_RD,
+		.len   = length,
+		.buf   = rxdata,
+	},
+	};
+
+	if (i2c_transfer(ov9726_client->adapter, msgs, 2) < 0) {
+		CDBG("ov9726_i2c_rxdata failed!\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t ov9726_i2c_txdata(unsigned short saddr,
+				unsigned char *txdata, int length)
+{
+	struct i2c_msg msg[] = {
+		{
+		 .addr = saddr ,
+		 .flags = 0,
+		 .len = length,
+		 .buf = txdata,
+		 },
+	};
+
+	if (i2c_transfer(ov9726_client->adapter, msg, 1) < 0) {
+		CDBG("ov9726_i2c_txdata faild 0x%x\n", ov9726_client->addr);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t ov9726_i2c_read(unsigned short raddr,
+				unsigned short *rdata, int rlen)
+{
+	int32_t rc = 0;
+	unsigned char buf[2];
+
+	if (!rdata)
+		return -EIO;
+
+	buf[0] = (raddr & OV9726_MSB_MASK) >> 8;
+	buf[1] = (raddr & OV9726_LSB_MASK);
+
+	rc = ov9726_i2c_rxdata(ov9726_client->addr, buf, rlen);
+
+	if (rc < 0) {
+		CDBG("ov9726_i2c_read 0x%x failed!\n", raddr);
+		return rc;
+	}
+
+	*rdata = (rlen == 2 ? buf[0] << 8 | buf[1] : buf[0]);
+	return rc;
+}
+
+static int32_t ov9726_i2c_write_b(unsigned short saddr,
+	unsigned short waddr, uint8_t bdata)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[3];
+
+	buf[0] = (waddr & OV9726_MSB_MASK) >> 8;
+	buf[1] = (waddr & OV9726_LSB_MASK);
+	buf[2] = bdata;
+
+	CDBG("i2c_write_b addr = 0x%x, val = 0x%xd\n", waddr, bdata);
+	rc = ov9726_i2c_txdata(saddr, buf, 3);
+
+	if (rc < 0) {
+		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
+			 waddr, bdata);
+	}
+
+	return rc;
+}
+
+static void ov9726_get_pict_fps(uint16_t fps, uint16_t *pfps)
+{
+	uint32_t divider;	/*Q10 */
+	uint32_t d1;
+	uint32_t d2;
+	uint16_t snapshot_height, preview_height, preview_width, snapshot_width;
+	if (ov9726_ctrl->prev_res == QTR_SIZE) {
+		preview_width = OV9726_QTR_SIZE_WIDTH +
+			OV9726_HRZ_QTR_BLK_PIXELS ;
+		preview_height = OV9726_QTR_SIZE_HEIGHT +
+			OV9726_VER_QTR_BLK_LINES ;
+	} else {
+		/* full size resolution used for preview. */
+		preview_width = OV9726_FULL_SIZE_WIDTH +
+			OV9726_HRZ_FULL_BLK_PIXELS ;
+		preview_height = OV9726_FULL_SIZE_HEIGHT +
+			OV9726_VER_FULL_BLK_LINES ;
+	}
+	if (ov9726_ctrl->pict_res == QTR_SIZE) {
+		snapshot_width  = OV9726_QTR_SIZE_WIDTH +
+			OV9726_HRZ_QTR_BLK_PIXELS ;
+		snapshot_height = OV9726_QTR_SIZE_HEIGHT +
+			OV9726_VER_QTR_BLK_LINES ;
+	} else {
+		snapshot_width  = OV9726_FULL_SIZE_WIDTH +
+			OV9726_HRZ_FULL_BLK_PIXELS;
+		snapshot_height = OV9726_FULL_SIZE_HEIGHT +
+			OV9726_VER_FULL_BLK_LINES;
+	}
+
+	d1 = (uint32_t)(((uint32_t)preview_height <<
+		OV9726_Q10Shift) /
+		snapshot_height);
+
+	d2 = (uint32_t)(((uint32_t)preview_width <<
+		OV9726_Q10Shift) /
+		 snapshot_width);
+
+	divider = (uint32_t) (d1 * d2) >> OV9726_Q10Shift;
+	*pfps = (uint16_t)((uint32_t)(fps * divider) >> OV9726_Q10Shift);
+}
+
+static uint16_t ov9726_get_prev_lines_pf(void)
+{
+	if (ov9726_ctrl->prev_res == QTR_SIZE)
+		return OV9726_QTR_SIZE_HEIGHT + OV9726_VER_QTR_BLK_LINES;
+	else
+		return OV9726_FULL_SIZE_HEIGHT + OV9726_VER_FULL_BLK_LINES;
+}
+
+static uint16_t ov9726_get_prev_pixels_pl(void)
+{
+	if (ov9726_ctrl->prev_res == QTR_SIZE)
+		return OV9726_QTR_SIZE_WIDTH + OV9726_HRZ_QTR_BLK_PIXELS;
+	else
+		return OV9726_FULL_SIZE_WIDTH + OV9726_HRZ_FULL_BLK_PIXELS;
+}
+
+static uint16_t ov9726_get_pict_lines_pf(void)
+{
+	if (ov9726_ctrl->pict_res == QTR_SIZE)
+		return OV9726_QTR_SIZE_HEIGHT + OV9726_VER_QTR_BLK_LINES;
+	else
+		return OV9726_FULL_SIZE_HEIGHT + OV9726_VER_FULL_BLK_LINES;
+}
+
+static uint16_t ov9726_get_pict_pixels_pl(void)
+{
+	if (ov9726_ctrl->pict_res == QTR_SIZE)
+		return OV9726_QTR_SIZE_WIDTH + OV9726_HRZ_QTR_BLK_PIXELS;
+	else
+		return OV9726_FULL_SIZE_WIDTH + OV9726_HRZ_FULL_BLK_PIXELS;
+}
+
+static uint32_t ov9726_get_pict_max_exp_lc(void)
+{
+	if (ov9726_ctrl->pict_res == QTR_SIZE)
+		return (OV9726_QTR_SIZE_HEIGHT + OV9726_VER_QTR_BLK_LINES)*24;
+	else
+		return (OV9726_FULL_SIZE_HEIGHT + OV9726_VER_FULL_BLK_LINES)*24;
+}
+
+static int32_t ov9726_set_fps(struct fps_cfg	*fps)
+{
+	int32_t rc = 0;
+	CDBG("%s: fps->fps_div = %d\n", __func__, fps->fps_div);
+	/* TODO: Passing of fps_divider from user space has issues. */
+	/* ov9726_ctrl->fps_divider = fps->fps_div; */
+	ov9726_ctrl->fps_divider = 1 * 0x400;
+	CDBG("%s: ov9726_ctrl->fps_divider = %d\n", __func__,
+		ov9726_ctrl->fps_divider);
+	ov9726_ctrl->pict_fps_divider = fps->pict_fps_div;
+	ov9726_ctrl->fps = fps->f_mult;
+	return rc;
+}
+
+static int32_t ov9726_write_exp_gain(uint16_t gain, uint32_t line)
+{
+	static uint16_t max_legal_gain = 0x00FF;
+	uint8_t gain_msb, gain_lsb;
+	uint8_t intg_time_msb, intg_time_lsb;
+	uint8_t ov9726_offset = 6;
+	uint8_t line_length_pck_msb, line_length_pck_lsb;
+	uint16_t line_length_pck, frame_length_lines;
+	uint32_t line_length_ratio = 1 << OV9726_Q8Shift;
+	int32_t rc = -1;
+	CDBG("%s: gain = %d	line = %d", __func__, gain, line);
+
+	if (ov9726_ctrl->sensormode != SENSOR_SNAPSHOT_MODE) {
+		if (ov9726_ctrl->curr_res == QTR_SIZE) {
+			frame_length_lines = OV9726_QTR_SIZE_HEIGHT +
+			 OV9726_VER_QTR_BLK_LINES;
+			line_length_pck = OV9726_QTR_SIZE_WIDTH	+
+			 OV9726_HRZ_QTR_BLK_PIXELS;
+		} else {
+			frame_length_lines = OV9726_FULL_SIZE_HEIGHT +
+				OV9726_VER_FULL_BLK_LINES;
+			line_length_pck = OV9726_FULL_SIZE_WIDTH +
+				OV9726_HRZ_FULL_BLK_PIXELS;
+		}
+		if (line > (frame_length_lines - ov9726_offset))
+			ov9726_ctrl->fps = (uint16_t) (((uint32_t)30 <<
+				OV9726_Q8Shift) *
+				(frame_length_lines - ov9726_offset) / line);
+		else
+			ov9726_ctrl->fps = (uint16_t) ((uint32_t)30 <<
+				OV9726_Q8Shift);
+	} else {
+		frame_length_lines = OV9726_FULL_SIZE_HEIGHT +
+			OV9726_VER_FULL_BLK_LINES;
+		line_length_pck = OV9726_FULL_SIZE_WIDTH +
+			OV9726_HRZ_FULL_BLK_PIXELS;
+	}
+
+	if (ov9726_ctrl->sensormode != SENSOR_SNAPSHOT_MODE) {
+		line = (uint32_t) (line * ov9726_ctrl->fps_divider) >>
+			OV9726_Q10Shift;
+	} else {
+		line = (uint32_t) (line * ov9726_ctrl->pict_fps_divider) >>
+			OV9726_Q10Shift;
+	}
+
+	/* calculate line_length_ratio */
+	if (line > (frame_length_lines - ov9726_offset)) {
+		line_length_ratio = (line << OV9726_Q8Shift) /
+			(frame_length_lines - ov9726_offset);
+		line = frame_length_lines - ov9726_offset;
+	} else
+		line_length_ratio = (uint32_t)1 << OV9726_Q8Shift;
+
+	if (gain > max_legal_gain) {
+		/* range:	0	to 224 */
+		gain = max_legal_gain;
+	}
+	/* update	gain registers */
+	gain_msb = (uint8_t) ((gain & 0xFF00) >> 8);
+	gain_lsb = (uint8_t) (gain & 0x00FF);
+	/* linear	AFR	horizontal stretch */
+	line_length_pck = (uint16_t) ((line_length_pck *
+		line_length_ratio) >> OV9726_Q8Shift);
+	line_length_pck_msb = (uint8_t) ((line_length_pck & 0xFF00) >> 8);
+	line_length_pck_lsb = (uint8_t) (line_length_pck & 0x00FF);
+	/* update	line count registers */
+	intg_time_msb = (uint8_t) ((line & 0xFF00) >> 8);
+	intg_time_lsb = (uint8_t) (line	& 0x00FF);
+
+	rc = ov9726_i2c_write_b(ov9726_client->addr, 0x104, 0x1);
+	if (rc < 0)
+		return rc;
+
+	rc = ov9726_i2c_write_b(ov9726_client->addr, 0x204, gain_msb);
+	if (rc < 0)
+		return rc;
+
+	rc = ov9726_i2c_write_b(ov9726_client->addr, 0x205, gain_lsb);
+	if (rc < 0)
+		return rc;
+
+	rc = ov9726_i2c_write_b(ov9726_client->addr, 0x342,
+		line_length_pck_msb);
+	if (rc < 0)
+		return rc;
+
+	rc = ov9726_i2c_write_b(ov9726_client->addr, 0x343,
+		line_length_pck_lsb);
+	if (rc < 0)
+		return rc;
+
+	rc = ov9726_i2c_write_b(ov9726_client->addr, 0x0202, intg_time_msb);
+	if (rc < 0)
+		return rc;
+
+	rc = ov9726_i2c_write_b(ov9726_client->addr, 0x0203, intg_time_lsb);
+	if (rc < 0)
+		return rc;
+
+	rc = ov9726_i2c_write_b(ov9726_client->addr, 0x104, 0x0);
+	if (rc < 0)
+		return rc;
+
+	return rc;
+}
+
+static int32_t ov9726_set_pict_exp_gain(uint16_t gain, uint32_t line)
+{
+	int32_t rc = 0;
+	rc = ov9726_write_exp_gain(gain, line);
+	return rc;
+}
+
+static int32_t initialize_ov9726_registers(void)
+{
+	int32_t i;
+	int32_t rc = 0;
+	ov9726_ctrl->sensormode = SENSOR_PREVIEW_MODE ;
+	/* Configure sensor for Preview mode and Snapshot mode */
+	CDBG("Initialize_ov9726_registers\n");
+	for (i = 0; i < ov9726_array_length; i++) {
+		rc = ov9726_i2c_write_b(ov9726_client->addr,
+			ov9726_init_settings_array[i].reg_addr,
+			ov9726_init_settings_array[i].reg_val);
+	if (rc < 0)
+		return rc;
+	}
+	return rc;
+}
+
+static int32_t ov9726_video_config(int mode)
+{
+	int32_t rc = 0;
+
+	ov9726_ctrl->sensormode = mode;
+
+	if (config_not_set) {
+		struct msm_camera_csi_params ov9726_csi_params;
+
+		/* sensor in standby */
+		ov9726_i2c_write_b(ov9726_client->addr, 0x100, 0);
+		msleep(5);
+		/* Initialize Sensor registers */
+		ov9726_csi_params.data_format = CSI_10BIT;
+		ov9726_csi_params.lane_cnt = 1;
+		ov9726_csi_params.lane_assign = 0xe4;
+		ov9726_csi_params.dpcm_scheme = 0;
+		ov9726_csi_params.settle_cnt = 7;
+
+		rc = msm_camio_csi_config(&ov9726_csi_params);
+		rc = initialize_ov9726_registers();
+		config_not_set = 0;
+	}
+	return rc;
+}
+
+static int32_t ov9726_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+	ov9726_ctrl->sensormode = mode;
+	return rc;
+}
+
+static int32_t ov9726_raw_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+	ov9726_ctrl->sensormode = mode;
+	return rc;
+}
+
+static int32_t ov9726_set_sensor_mode(int  mode,
+			int  res)
+{
+	int32_t rc = 0;
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		rc = ov9726_video_config(mode);
+		break;
+	case SENSOR_SNAPSHOT_MODE:
+		rc = ov9726_snapshot_config(mode);
+		break;
+	case SENSOR_RAW_SNAPSHOT_MODE:
+		rc = ov9726_raw_snapshot_config(mode);
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
+static int ov9726_probe_init_sensor(const struct msm_camera_sensor_info *data)
+{
+	int32_t rc = 0;
+	uint16_t  chipidl, chipidh;
+
+	if (data->sensor_reset_enable) {
+		rc = gpio_request(data->sensor_reset, "ov9726");
+		if (!rc) {
+			gpio_direction_output(data->sensor_reset, 0);
+			gpio_set_value_cansleep(data->sensor_reset, 1);
+			msleep(20);
+		} else
+			goto init_probe_done;
+	}
+	/* 3. Read sensor Model ID: */
+	rc = ov9726_i2c_read(OV9726_PIDH_REG, &chipidh, 1);
+	if (rc < 0)
+		goto init_probe_fail;
+	rc = ov9726_i2c_read(OV9726_PIDL_REG, &chipidl, 1);
+	if (rc < 0)
+		goto init_probe_fail;
+	CDBG("kov9726 model_id = 0x%x  0x%x\n", chipidh, chipidl);
+	/* 4. Compare sensor ID to OV9726 ID: */
+	if (chipidh != OV9726_PID) {
+		rc = -ENODEV;
+		printk(KERN_INFO "Probeinit fail\n");
+		goto init_probe_fail;
+	}
+	CDBG("chipidh == OV9726_PID\n");
+	msleep(OV9726_RESET_DELAY_MSECS);
+	CDBG("after delay\n");
+	goto init_probe_done;
+
+init_probe_fail:
+	if (data->sensor_reset_enable) {
+		gpio_direction_output(data->sensor_reset, 0);
+		gpio_free(data->sensor_reset);
+	}
+init_probe_done:
+	printk(KERN_INFO " ov9726_probe_init_sensor finishes\n");
+	return rc;
+}
+
+int ov9726_sensor_open_init(const struct msm_camera_sensor_info *data)
+{
+	int32_t  rc;
+
+	CDBG("Calling ov9726_sensor_open_init\n");
+	ov9726_ctrl = kzalloc(sizeof(struct ov9726_ctrl_t), GFP_KERNEL);
+	if (!ov9726_ctrl) {
+		CDBG("ov9726_init failed!\n");
+		rc = -ENOMEM;
+		goto init_done;
+	}
+	ov9726_ctrl->curr_lens_pos = -1;
+	ov9726_ctrl->fps_divider = 1 << OV9726_Q10Shift;
+	ov9726_ctrl->pict_fps_divider = 1 << OV9726_Q10Shift;
+	ov9726_ctrl->set_test = TEST_OFF;
+	ov9726_ctrl->prev_res = FULL_SIZE;
+	ov9726_ctrl->pict_res = FULL_SIZE;
+	ov9726_ctrl->curr_res = INVALID_SIZE;
+	config_not_set = 1;
+	if (data)
+		ov9726_ctrl->sensordata = data;
+	/* enable mclk first */
+	msm_camio_clk_rate_set(OV9726_DEFAULT_CLOCK_RATE);
+	msleep(20);
+	rc = ov9726_probe_init_sensor(data);
+	if (rc < 0)
+		goto init_fail;
+
+	ov9726_ctrl->fps = (uint16_t)(30 << OV9726_Q8Shift);
+	/* generate test pattern */
+	if (rc < 0)
+		goto init_fail;
+	else
+		goto init_done;
+	/* reset the driver state */
+init_fail:
+	CDBG(" init_fail\n");
+	kfree(ov9726_ctrl);
+init_done:
+	CDBG("init_done\n");
+	return rc;
+}
+
+static int ov9726_init_client(struct i2c_client *client)
+{
+	/* Initialize the MSM_CAMI2C Chip */
+	init_waitqueue_head(&ov9726_wait_queue);
+	return 0;
+}
+
+static const struct i2c_device_id ov9726_i2c_id[] = {
+	{ "ov9726", 0},
+	{ }
+};
+
+static int ov9726_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+	CDBG("ov9726_probe called!\n");
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		CDBG("i2c_check_functionality failed\n");
+		goto probe_failure;
+	}
+	ov9726_sensorw = kzalloc(sizeof(struct ov9726_work_t), GFP_KERNEL);
+	if (!ov9726_sensorw) {
+		CDBG("kzalloc failed.\n");
+		rc = -ENOMEM;
+		goto probe_failure;
+	}
+	i2c_set_clientdata(client, ov9726_sensorw);
+	ov9726_init_client(client);
+	ov9726_client = client;
+	msleep(50);
+	CDBG("ov9726_probe successed! rc = %d\n", rc);
+	return 0;
+probe_failure:
+	CDBG("ov9726_probe failed! rc = %d\n", rc);
+	return rc;
+}
+
+static int __exit ov9726_remove(struct i2c_client *client)
+{
+	struct ov9726_work_t_t *sensorw = i2c_get_clientdata(client);
+	free_irq(client->irq, sensorw);
+	ov9726_client = NULL;
+	kfree(sensorw);
+	return 0;
+}
+
+static struct i2c_driver ov9726_i2c_driver = {
+	.id_table = ov9726_i2c_id,
+	.probe	= ov9726_i2c_probe,
+	.remove = __exit_p(ov9726_i2c_remove),
+	.driver = {
+		.name = "ov9726",
+	},
+};
+
+int ov9726_sensor_config(void __user *argp)
+{
+	struct sensor_cfg_data cdata;
+	long   rc = 0;
+
+	if (copy_from_user(&cdata,
+				(void *)argp,
+				sizeof(struct sensor_cfg_data)))
+		return -EFAULT;
+	mutex_lock(&ov9726_mut);
+	CDBG("ov9726_sensor_config: cfgtype = %d\n",
+		cdata.cfgtype);
+	switch (cdata.cfgtype) {
+	case CFG_GET_PICT_FPS:
+		ov9726_get_pict_fps(cdata.cfg.gfps.prevfps,
+				&(cdata.cfg.gfps.pictfps));
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+			break;
+	case CFG_GET_PREV_L_PF:
+		cdata.cfg.prevl_pf = ov9726_get_prev_lines_pf();
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+	case CFG_GET_PREV_P_PL:
+		cdata.cfg.prevp_pl = ov9726_get_prev_pixels_pl();
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+	case CFG_GET_PICT_L_PF:
+		cdata.cfg.pictl_pf = ov9726_get_pict_lines_pf();
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+	case CFG_GET_PICT_P_PL:
+		cdata.cfg.pictp_pl =
+				ov9726_get_pict_pixels_pl();
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+	case CFG_GET_PICT_MAX_EXP_LC:
+		cdata.cfg.pict_max_exp_lc = ov9726_get_pict_max_exp_lc();
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+	case CFG_SET_FPS:
+	case CFG_SET_PICT_FPS:
+		rc = ov9726_set_fps(&(cdata.cfg.fps));
+		break;
+	case CFG_SET_EXP_GAIN:
+		rc = ov9726_write_exp_gain(
+					cdata.cfg.exp_gain.gain,
+					cdata.cfg.exp_gain.line);
+		break;
+	case CFG_SET_PICT_EXP_GAIN:
+		rc = ov9726_set_pict_exp_gain(
+					cdata.cfg.exp_gain.gain,
+					cdata.cfg.exp_gain.line);
+		break;
+	case CFG_SET_MODE:
+		rc = ov9726_set_sensor_mode(cdata.mode,
+						cdata.rs);
+		break;
+	case CFG_PWR_DOWN:
+	case CFG_MOVE_FOCUS:
+	case CFG_SET_DEFAULT_FOCUS:
+		rc = 0;
+		break;
+	case CFG_SET_EFFECT:
+	default:
+		rc = -EFAULT;
+		break;
+	}
+	mutex_unlock(&ov9726_mut);
+	return rc;
+}
+
+static int ov9726_probe_init_done(const struct msm_camera_sensor_info *data)
+{
+	if (data->sensor_reset_enable) {
+		gpio_direction_output(data->sensor_reset, 0);
+		gpio_free(data->sensor_reset);
+	}
+	return 0;
+}
+
+static int ov9726_sensor_release(void)
+{
+	int rc = -EBADF;
+	mutex_lock(&ov9726_mut);
+	if (ov9726_ctrl->sensordata->sensor_reset_enable) {
+		gpio_direction_output(
+			ov9726_ctrl->sensordata->sensor_reset, 0);
+		gpio_free(ov9726_ctrl->sensordata->sensor_reset);
+	}
+	kfree(ov9726_ctrl);
+	ov9726_ctrl = NULL;
+	CDBG("ov9726_release completed\n");
+	mutex_unlock(&ov9726_mut);
+	return rc;
+}
+
+static int ov9726_sensor_probe(const struct msm_camera_sensor_info *info,
+		struct msm_sensor_ctrl *s)
+{
+	int rc = 0;
+
+	rc = i2c_add_driver(&ov9726_i2c_driver);
+	if (rc < 0 || ov9726_client == NULL) {
+		rc = -ENOTSUPP;
+		goto probe_fail;
+	}
+	msm_camio_clk_rate_set(24000000);
+	msleep(20);
+	rc = ov9726_probe_init_sensor(info);
+	if (rc < 0)
+		goto probe_fail;
+
+	s->s_init = ov9726_sensor_open_init;
+	s->s_release = ov9726_sensor_release;
+	s->s_config  = ov9726_sensor_config;
+	s->s_camera_type = FRONT_CAMERA_2D;
+	s->s_mount_angle = info->sensor_platform_info->mount_angle;
+	ov9726_probe_init_done(info);
+
+	return rc;
+
+probe_fail:
+	CDBG("SENSOR PROBE FAILS!\n");
+	return rc;
+}
+
+static int __ov9726_probe(struct platform_device *pdev)
+{
+	return msm_camera_drv_start(pdev, ov9726_sensor_probe);
+}
+
+static struct platform_driver msm_camera_driver = {
+	.probe = __ov9726_probe,
+	.driver = {
+		.name = "msm_camera_ov9726",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init ov9726_init(void)
+{
+	return platform_driver_register(&msm_camera_driver);
+}
+
+module_init(ov9726_init);
+void ov9726_exit(void)
+{
+	i2c_del_driver(&ov9726_i2c_driver);
+}
+
+MODULE_DESCRIPTION("OMNI VGA Bayer sensor driver");
+MODULE_LICENSE("GPL v2");
+
diff --git a/drivers/media/platform/msm/camera_v1/ov9726.h b/drivers/media/platform/msm/camera_v1/ov9726.h
new file mode 100644
index 0000000..40ba1a8
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/ov9726.h
@@ -0,0 +1,39 @@
+/* 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.
+ */
+
+#ifndef OV9726_H
+#define OV9726_H
+#include <linux/types.h>
+#include <mach/board.h>
+
+/* 16bit address - 8 bit context register structure */
+struct reg_struct_type {
+	uint16_t	reg_addr;
+	unsigned char	reg_val;
+};
+
+enum ov9726_test_mode_t {
+	TEST_OFF,
+	TEST_1,
+	TEST_2,
+	TEST_3
+};
+
+enum ov9726_resolution_t {
+	QTR_SIZE,
+	FULL_SIZE,
+	INVALID_SIZE
+};
+extern struct reg_struct_type ov9726_init_settings_array[];
+extern int32_t ov9726_array_length;
+#endif
+
diff --git a/drivers/media/platform/msm/camera_v1/ov9726_reg.c b/drivers/media/platform/msm/camera_v1/ov9726_reg.c
new file mode 100644
index 0000000..216ecca
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/ov9726_reg.c
@@ -0,0 +1,101 @@
+/* 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 "ov9726.h"
+struct reg_struct_type ov9726_init_settings_array[] = {
+	{0x0103, 0x01}, /* SOFTWARE_RESET */
+	{0x3026, 0x00}, /* OUTPUT_SELECT01 */
+	{0x3027, 0x00}, /* OUTPUT_SELECT02 */
+	{0x3002, 0xe8}, /* IO_CTRL00 */
+	{0x3004, 0x03}, /* IO_CTRL01 */
+	{0x3005, 0xff}, /* IO_CTRL02 */
+	{0x3703, 0x42},
+	{0x3704, 0x10},
+	{0x3705, 0x45},
+	{0x3603, 0xaa},
+	{0x3632, 0x2f},
+	{0x3620, 0x66},
+	{0x3621, 0xc0},
+	{0x0340, 0x03}, /* FRAME_LENGTH_LINES_HI */
+	{0x0341, 0xC1}, /* FRAME_LENGTH_LINES_LO */
+	{0x0342, 0x06}, /* LINE_LENGTH_PCK_HI */
+	{0x0343, 0x80}, /* LINE_LENGTH_PCK_LO */
+	{0x0202, 0x03}, /* COARSE_INTEGRATION_TIME_HI */
+	{0x0203, 0x43}, /* COARSE_INTEGRATION_TIME_LO */
+	{0x3833, 0x04},
+	{0x3835, 0x02},
+	{0x4702, 0x04},
+	{0x4704, 0x00}, /* DVP_CTRL01 */
+	{0x4706, 0x08},
+	{0x5052, 0x01},
+	{0x3819, 0x6e},
+	{0x3817, 0x94},
+	{0x3a18, 0x00}, /* AEC_GAIN_CEILING_HI */
+	{0x3a19, 0x7f}, /* AEC_GAIN_CEILING_LO */
+	{0x404e, 0x7e},
+	{0x3631, 0x52},
+	{0x3633, 0x50},
+	{0x3630, 0xd2},
+	{0x3604, 0x08},
+	{0x3601, 0x40},
+	{0x3602, 0x14},
+	{0x3610, 0xa0},
+	{0x3612, 0x20},
+	{0x034c, 0x05}, /* X_OUTPUT_SIZE_HI */
+	{0x034d, 0x10}, /* X_OUTPUT_SIZE_LO */
+	{0x034e, 0x03}, /* Y_OUTPUT_SIZE_HI */
+	{0x034f, 0x28}, /* Y_OUTPUT_SIZE_LO */
+	{0x0340, 0x03}, /* FRAME_LENGTH_LINES_HI */
+	{0x0341, 0xC1}, /* FRAME_LENGTH_LINES_LO */
+	{0x0342, 0x06}, /* LINE_LENGTH_PCK_HI */
+	{0x0343, 0x80}, /* LINE_LENGTH_PCK_LO */
+	{0x0202, 0x03}, /* COARSE_INTEGRATION_TIME_HI */
+	{0x0203, 0x43}, /* COARSE_INTEGRATION_TIME_LO */
+	{0x0303, 0x01}, /* VT_SYS_CLK_DIV_LO */
+	{0x3002, 0x00}, /* IO_CTRL00 */
+	{0x3004, 0x00}, /* IO_CTRL01 */
+	{0x3005, 0x00}, /* IO_CTRL02 */
+	{0x4801, 0x0f}, /* MIPI_CTRL01 */
+	{0x4803, 0x05}, /* MIPI_CTRL03 */
+	{0x4601, 0x16}, /* VFIFO_READ_CONTROL */
+	{0x3014, 0x05}, /* SC_CMMN_MIPI / SC_CTRL00 */
+	{0x3104, 0x80},
+	{0x0305, 0x04}, /* PRE_PLL_CLK_DIV_LO */
+	{0x0307, 0x64}, /* PLL_MULTIPLIER_LO */
+	{0x300c, 0x02},
+	{0x300d, 0x20},
+	{0x300e, 0x01},
+	{0x3010, 0x01},
+	{0x460e, 0x81}, /* VFIFO_CONTROL00 */
+	{0x0101, 0x01}, /* IMAGE_ORIENTATION */
+	{0x3707, 0x14},
+	{0x3622, 0x9f},
+	{0x5047, 0x3D}, /* ISP_CTRL47 */
+	{0x4002, 0x45}, /* BLC_CTRL02 */
+	{0x5000, 0x06}, /* ISP_CTRL0 */
+	{0x5001, 0x00}, /* ISP_CTRL1 */
+	{0x3406, 0x00}, /* AWB_MANUAL_CTRL */
+	{0x3503, 0x13}, /* AEC_ENABLE */
+	{0x4005, 0x18}, /* BLC_CTRL05 */
+	{0x4837, 0x21},
+	{0x0100, 0x01}, /* MODE_SELECT */
+	{0x3a0f, 0x64}, /* AEC_CTRL0F */
+	{0x3a10, 0x54}, /* AEC_CTRL10 */
+	{0x3a11, 0xc2}, /* AEC_CTRL11 */
+	{0x3a1b, 0x64}, /* AEC_CTRL1B */
+	{0x3a1e, 0x54}, /* AEC_CTRL1E */
+	{0x3a1a, 0x05}, /* AEC_DIFF_MAX */
+};
+int32_t ov9726_array_length = sizeof(ov9726_init_settings_array) /
+	sizeof(ov9726_init_settings_array[0]);
+
diff --git a/drivers/media/platform/msm/camera_v1/qs_s5k4e1.c b/drivers/media/platform/msm/camera_v1/qs_s5k4e1.c
new file mode 100644
index 0000000..32d094d
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/qs_s5k4e1.c
@@ -0,0 +1,1822 @@
+/* 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/delay.h>
+#include <linux/debugfs.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/slab.h>
+#include <media/msm_camera.h>
+#include <mach/gpio.h>
+#include <mach/camera.h>
+#include "qs_s5k4e1.h"
+/*=============================================================
+	SENSOR REGISTER DEFINES
+==============================================================*/
+#define REG_GROUPED_PARAMETER_HOLD		0x0104
+#define GROUPED_PARAMETER_HOLD_OFF		0x00
+#define GROUPED_PARAMETER_HOLD			0x01
+/* Integration Time */
+#define REG_COARSE_INTEGRATION_TIME		0x0202
+/* Gain */
+#define REG_GLOBAL_GAIN					0x0204
+#define REG_GR_GAIN					0x020E
+#define REG_R_GAIN					0x0210
+#define REG_B_GAIN					0x0212
+#define REG_GB_GAIN					0x0214
+/* PLL registers */
+#define REG_FRAME_LENGTH_LINES			0x0340
+#define REG_LINE_LENGTH_PCK				0x0342
+/* Test Pattern */
+#define REG_TEST_PATTERN_MODE			0x0601
+#define REG_VCM_NEW_CODE				0x30F2
+#define AF_ADDR							0x18
+#define BRIDGE_ADDR						0x80
+/*============================================================================
+			 TYPE DECLARATIONS
+============================================================================*/
+
+/* 16bit address - 8 bit context register structure */
+#define Q8  0x00000100
+#define Q10 0x00000400
+#define QS_S5K4E1_MASTER_CLK_RATE 24000000
+#define QS_S5K4E1_OFFSET			8
+
+/* AF Total steps parameters */
+#define QS_S5K4E1_TOTAL_STEPS_NEAR_TO_FAR    32
+#define QS_S5K4E1_TOTAL_STEPS_3D    32
+
+uint16_t qs_s5k4e1_step_position_table[QS_S5K4E1_TOTAL_STEPS_NEAR_TO_FAR+1];
+uint16_t qs_s5k4e1_step_position_table_left[QS_S5K4E1_TOTAL_STEPS_3D+1];
+uint16_t qs_s5k4e1_step_position_table_right[QS_S5K4E1_TOTAL_STEPS_3D+1];
+uint16_t qs_s5k4e1_nl_region_boundary1;
+uint16_t qs_s5k4e1_nl_region_code_per_step1 = 190;
+uint16_t qs_s5k4e1_l_region_code_per_step = 8;
+uint16_t qs_s5k4e1_damping_threshold = 10;
+uint16_t qs_s5k4e1_sw_damping_time_wait = 8;
+uint16_t qs_s5k4e1_af_mode = 4;
+int16_t qs_s5k4e1_af_initial_code = 190;
+int16_t qs_s5k4e1_af_right_adjust;
+
+struct qs_s5k4e1_work_t {
+	struct work_struct work;
+};
+
+static struct qs_s5k4e1_work_t *qs_s5k4e1_sensorw;
+static struct i2c_client *qs_s5k4e1_client;
+static char lens_eeprom_data[864];
+static bool cali_data_status;
+struct qs_s5k4e1_ctrl_t {
+	const struct  msm_camera_sensor_info *sensordata;
+
+	uint32_t sensormode;
+	uint32_t fps_divider;/* init to 1 * 0x00000400 */
+	uint32_t pict_fps_divider;/* init to 1 * 0x00000400 */
+	uint16_t fps;
+
+	uint16_t curr_lens_pos;
+	uint16_t curr_step_pos;
+	uint16_t my_reg_gain;
+	uint32_t my_reg_line_count;
+	uint16_t total_lines_per_frame;
+
+	enum qs_s5k4e1_resolution_t prev_res;
+	enum qs_s5k4e1_resolution_t pict_res;
+	enum qs_s5k4e1_resolution_t curr_res;
+	enum qs_s5k4e1_test_mode_t  set_test;
+	enum qs_s5k4e1_cam_mode_t cam_mode;
+};
+
+static uint16_t prev_line_length_pck;
+static uint16_t prev_frame_length_lines;
+static uint16_t snap_line_length_pck;
+static uint16_t snap_frame_length_lines;
+
+static bool CSI_CONFIG, LENS_SHADE_CONFIG, default_lens_shade;
+static struct qs_s5k4e1_ctrl_t *qs_s5k4e1_ctrl;
+static DECLARE_WAIT_QUEUE_HEAD(qs_s5k4e1_wait_queue);
+DEFINE_MUTEX(qs_s5k4e1_mut);
+
+static int cam_debug_init(void);
+static struct dentry *debugfs_base;
+/*=============================================================*/
+
+static int qs_s5k4e1_i2c_rxdata(unsigned short saddr,
+	unsigned char *rxdata, int length)
+{
+	struct i2c_msg msgs[] = {
+		{
+			.addr  = saddr,
+			.flags = 0,
+			.len   = 2,
+			.buf   = rxdata,
+		},
+		{
+			.addr  = saddr,
+			.flags = I2C_M_RD,
+			.len   = length,
+			.buf   = rxdata,
+		},
+	};
+	if (i2c_transfer(qs_s5k4e1_client->adapter, msgs, 2) < 0) {
+		CDBG("qs_s5k4e1_i2c_rxdata faild 0x%x\n", saddr);
+		return -EIO;
+	}
+	return 0;
+}
+
+static int32_t qs_s5k4e1_i2c_txdata(unsigned short saddr,
+				unsigned char *txdata, int length)
+{
+	struct i2c_msg msg[] = {
+		{
+			.addr = saddr,
+			.flags = 0,
+			.len = length,
+			.buf = txdata,
+		 },
+	};
+	if (i2c_transfer(qs_s5k4e1_client->adapter, msg, 1) < 0) {
+		CDBG("qs_s5k4e1_i2c_txdata faild 0x%x\n", saddr);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t qs_s5k4e1_i2c_read(unsigned short raddr,
+	unsigned short *rdata, int rlen)
+{
+	int32_t rc = 0;
+	unsigned char buf[2];
+	if (!rdata)
+		return -EIO;
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (raddr & 0xFF00) >> 8;
+	buf[1] = (raddr & 0x00FF);
+	rc = qs_s5k4e1_i2c_rxdata(qs_s5k4e1_client->addr>>1, buf, rlen);
+	if (rc < 0) {
+		CDBG("qs_s5k4e1_i2c_read 0x%x failed!\n", raddr);
+		return rc;
+	}
+	*rdata = (rlen == 2 ? buf[0] << 8 | buf[1] : buf[0]);
+	CDBG("qs_s5k4e1_i2c_read 0x%x val = 0x%x!\n", raddr, *rdata);
+	return rc;
+}
+
+static int32_t qs_s5k4e1_i2c_write_w_sensor(unsigned short waddr,
+	 uint16_t wdata)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[4];
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00) >> 8;
+	buf[1] = (waddr & 0x00FF);
+	buf[2] = (wdata & 0xFF00) >> 8;
+	buf[3] = (wdata & 0x00FF);
+	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, wdata);
+	rc = qs_s5k4e1_i2c_txdata(qs_s5k4e1_client->addr>>1, buf, 4);
+	if (rc < 0) {
+		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
+			waddr, wdata);
+	}
+	return rc;
+}
+
+static int32_t qs_s5k4e1_i2c_write_b_sensor(unsigned short waddr, uint8_t bdata)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[3];
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00) >> 8;
+	buf[1] = (waddr & 0x00FF);
+	buf[2] = bdata;
+	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
+	rc = qs_s5k4e1_i2c_txdata(qs_s5k4e1_client->addr>>1, buf, 3);
+	if (rc < 0) {
+		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
+			waddr, bdata);
+	}
+	return rc;
+}
+
+static int32_t qs_s5k4e1_i2c_write_b_table(struct qs_s5k4e1_i2c_reg_conf const
+					 *reg_conf_tbl, int num)
+{
+	int i;
+	int32_t rc = -EIO;
+	for (i = 0; i < num; i++) {
+		rc = qs_s5k4e1_i2c_write_b_sensor(reg_conf_tbl->waddr,
+			reg_conf_tbl->wdata);
+		if (rc < 0)
+			break;
+		reg_conf_tbl++;
+	}
+	return rc;
+}
+
+static int32_t qs_s5k4e1_i2c_write_seq_sensor(unsigned short waddr,
+		unsigned char *seq_data, int len)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[len+2];
+	int i = 0;
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00) >> 8;
+	buf[1] = (waddr & 0x00FF);
+	for (i = 0; i < len; i++)
+		buf[i+2] = seq_data[i];
+	rc = qs_s5k4e1_i2c_txdata(qs_s5k4e1_client->addr>>1, buf, len+2);
+	return rc;
+}
+
+static int32_t af_i2c_write_b_sensor(unsigned short baddr, uint8_t bdata)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[2];
+	memset(buf, 0, sizeof(buf));
+	buf[0] = baddr;
+	buf[1] = bdata;
+	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", baddr, bdata);
+	rc = qs_s5k4e1_i2c_txdata(AF_ADDR>>1, buf, 2);
+	if (rc < 0) {
+		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
+			baddr, bdata);
+	}
+	return rc;
+}
+
+static int32_t bridge_i2c_write_w(unsigned short waddr, uint16_t wdata)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[4];
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00) >> 8;
+	buf[1] = (waddr & 0x00FF);
+	buf[2] = (wdata & 0xFF00) >> 8;
+	buf[3] = (wdata & 0x00FF);
+	CDBG("bridge_i2c_write_w addr = 0x%x, val = 0x%x\n", waddr, wdata);
+	rc = qs_s5k4e1_i2c_txdata(BRIDGE_ADDR>>1, buf, 4);
+	if (rc < 0) {
+		CDBG("bridge_i2c_write_w failed, addr = 0x%x, val = 0x%x!\n",
+			waddr, wdata);
+	}
+	return rc;
+}
+
+static int32_t bridge_i2c_read(unsigned short raddr,
+	unsigned short *rdata, int rlen)
+{
+	int32_t rc = 0;
+	unsigned char buf[2];
+	if (!rdata)
+		return -EIO;
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (raddr & 0xFF00) >> 8;
+	buf[1] = (raddr & 0x00FF);
+	rc = qs_s5k4e1_i2c_rxdata(BRIDGE_ADDR>>1, buf, rlen);
+	if (rc < 0) {
+		CDBG("bridge_i2c_read 0x%x failed!\n", raddr);
+		return rc;
+	}
+	*rdata = (rlen == 2 ? buf[0] << 8 | buf[1] : buf[0]);
+	CDBG("bridge_i2c_read 0x%x val = 0x%x!\n", raddr, *rdata);
+	return rc;
+}
+
+static int32_t qs_s5k4e1_eeprom_i2c_read(unsigned short raddr,
+	unsigned char *rdata, int rlen)
+{
+	int32_t rc = 0;
+	unsigned short i2caddr = 0xA0 >> 1;
+	unsigned char buf[rlen];
+	int i = 0;
+	if (!rdata)
+		return -EIO;
+
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (raddr & 0xFF00) >> 8;
+	buf[1] = (raddr & 0x00FF);
+	rc = qs_s5k4e1_i2c_rxdata(i2caddr, buf, rlen);
+	if (rc < 0) {
+		CDBG("qs_s5k4e1_eeprom_i2c_read 0x%x failed!\n", raddr);
+		return rc;
+	}
+	for (i = 0; i < rlen; i++) {
+		rdata[i] = buf[i];
+		CDBG("qs_s5k4e1_eeprom_i2c_read 0x%x index: %d val = 0x%x!\n",
+			raddr, i, buf[i]);
+	}
+	return rc;
+}
+
+static int32_t qs_s5k4e1_eeprom_i2c_read_b(unsigned short raddr,
+	unsigned short *rdata, int rlen)
+{
+	int32_t rc = 0;
+	unsigned char buf[2];
+	rc = qs_s5k4e1_eeprom_i2c_read(raddr, &buf[0], rlen);
+	*rdata = (rlen == 2 ? buf[0] << 8 | buf[1] : buf[0]);
+	CDBG("qs_s5k4e1_eeprom_i2c_read 0x%x val = 0x%x!\n", raddr, *rdata);
+	return rc;
+}
+
+static int32_t qs_s5k4e1_get_calibration_data(
+	struct sensor_3d_cali_data_t *cdata)
+{
+	int32_t rc = 0;
+	cali_data_status = 1;
+	rc = qs_s5k4e1_eeprom_i2c_read(0x0,
+		&(cdata->left_p_matrix[0][0][0]), 96);
+	if (rc < 0)
+		goto fail;
+	rc = qs_s5k4e1_eeprom_i2c_read(0x60,
+		&(cdata->right_p_matrix[0][0][0]), 96);
+	if (rc < 0)
+		goto fail;
+	rc = qs_s5k4e1_eeprom_i2c_read(0xC0, &(cdata->square_len[0]), 8);
+	if (rc < 0)
+		goto fail;
+	rc = qs_s5k4e1_eeprom_i2c_read(0xC8, &(cdata->focal_len[0]), 8);
+	if (rc < 0)
+		goto fail;
+	rc = qs_s5k4e1_eeprom_i2c_read(0xD0, &(cdata->pixel_pitch[0]), 8);
+	if (rc < 0)
+		goto fail;
+	rc = qs_s5k4e1_eeprom_i2c_read_b(0x100, &(cdata->left_r), 1);
+	if (rc < 0)
+		goto fail;
+	rc = qs_s5k4e1_eeprom_i2c_read_b(0x101, &(cdata->right_r), 1);
+	if (rc < 0)
+		goto fail;
+	rc = qs_s5k4e1_eeprom_i2c_read_b(0x102, &(cdata->left_b), 1);
+	if (rc < 0)
+		goto fail;
+	rc = qs_s5k4e1_eeprom_i2c_read_b(0x103, &(cdata->right_b), 1);
+	if (rc < 0)
+		goto fail;
+	rc = qs_s5k4e1_eeprom_i2c_read_b(0x104, &(cdata->left_gb), 1);
+	if (rc < 0)
+		goto fail;
+	rc = qs_s5k4e1_eeprom_i2c_read_b(0x105, &(cdata->right_gb), 1);
+	if (rc < 0)
+		goto fail;
+	rc = qs_s5k4e1_eeprom_i2c_read_b(0x110, &(cdata->left_af_far), 2);
+	if (rc < 0)
+		goto fail;
+	rc = qs_s5k4e1_eeprom_i2c_read_b(0x112, &(cdata->right_af_far), 2);
+	if (rc < 0)
+		goto fail;
+	rc = qs_s5k4e1_eeprom_i2c_read_b(0x114, &(cdata->left_af_mid), 2);
+	if (rc < 0)
+		goto fail;
+	rc = qs_s5k4e1_eeprom_i2c_read_b(0x116, &(cdata->right_af_mid), 2);
+	if (rc < 0)
+		goto fail;
+	rc = qs_s5k4e1_eeprom_i2c_read_b(0x118, &(cdata->left_af_short), 2);
+	if (rc < 0)
+		goto fail;
+	rc = qs_s5k4e1_eeprom_i2c_read_b(0x11A, &(cdata->right_af_short), 2);
+	if (rc < 0)
+		goto fail;
+	rc = qs_s5k4e1_eeprom_i2c_read_b(0x11C, &(cdata->left_af_5um), 2);
+	if (rc < 0)
+		goto fail;
+	rc = qs_s5k4e1_eeprom_i2c_read_b(0x11E, &(cdata->right_af_5um), 2);
+	if (rc < 0)
+		goto fail;
+	rc = qs_s5k4e1_eeprom_i2c_read_b(0x120, &(cdata->left_af_50up), 2);
+	if (rc < 0)
+		goto fail;
+	rc = qs_s5k4e1_eeprom_i2c_read_b(0x122, &(cdata->right_af_50up), 2);
+	if (rc < 0)
+		goto fail;
+	rc = qs_s5k4e1_eeprom_i2c_read_b(0x124, &(cdata->left_af_50down), 2);
+	if (rc < 0)
+		goto fail;
+	rc = qs_s5k4e1_eeprom_i2c_read_b(0x126, &(cdata->right_af_50down), 2);
+	if (rc < 0)
+		goto fail;
+
+	return 0;
+
+fail:
+	cali_data_status = 0;
+	return -EIO;
+
+}
+static int32_t qs_s5k4e1_write_left_lsc(char *left_lsc, int rt)
+{
+	struct qs_s5k4e1_i2c_reg_conf *ptr = (struct qs_s5k4e1_i2c_reg_conf *)
+		(qs_s5k4e1_regs.reg_lens + rt);
+	bridge_i2c_write_w(0x06, 0x02);
+	if (!LENS_SHADE_CONFIG) {
+		qs_s5k4e1_i2c_write_b_sensor(0x3096, 0x40);
+		qs_s5k4e1_i2c_write_b_table(ptr, qs_s5k4e1_regs.reg_lens_size);
+		if (default_lens_shade)
+			qs_s5k4e1_i2c_write_b_table(qs_s5k4e1_regs.
+			reg_default_lens, qs_s5k4e1_regs.reg_default_lens_size);
+		else {
+			qs_s5k4e1_i2c_write_seq_sensor(0x3200,
+				&left_lsc[0], 216);
+			qs_s5k4e1_i2c_write_seq_sensor(0x32D8,
+				&left_lsc[216], 216);
+		}
+		qs_s5k4e1_i2c_write_b_sensor(0x3096, 0x60);
+		qs_s5k4e1_i2c_write_b_sensor(0x3096, 0x40);
+	} else
+		qs_s5k4e1_i2c_write_b_table(ptr, qs_s5k4e1_regs.reg_lens_size);
+	return 0;
+}
+
+static int32_t qs_s5k4e1_write_right_lsc(char *right_lsc, int rt)
+{
+	struct qs_s5k4e1_i2c_reg_conf *ptr = (struct qs_s5k4e1_i2c_reg_conf *)
+		(qs_s5k4e1_regs.reg_lens + rt);
+	bridge_i2c_write_w(0x06, 0x01);
+	if (!LENS_SHADE_CONFIG) {
+		qs_s5k4e1_i2c_write_b_sensor(0x3096, 0x40);
+		qs_s5k4e1_i2c_write_b_table(ptr, qs_s5k4e1_regs.reg_lens_size);
+		if (default_lens_shade)
+			qs_s5k4e1_i2c_write_b_table(qs_s5k4e1_regs.
+			reg_default_lens, qs_s5k4e1_regs.reg_default_lens_size);
+		else {
+			qs_s5k4e1_i2c_write_seq_sensor(0x3200,
+				&right_lsc[0], 216);
+			qs_s5k4e1_i2c_write_seq_sensor(0x32D8,
+				&right_lsc[216], 216);
+		}
+		qs_s5k4e1_i2c_write_b_sensor(0x3096, 0x60);
+		qs_s5k4e1_i2c_write_b_sensor(0x3096, 0x40);
+	} else
+		qs_s5k4e1_i2c_write_b_table(ptr, qs_s5k4e1_regs.reg_lens_size);
+	return 0;
+}
+
+static int32_t qs_s5k4e1_write_lsc(char *lsc, int rt)
+{
+	if (qs_s5k4e1_ctrl->cam_mode == MODE_3D) {
+		qs_s5k4e1_write_left_lsc(&lsc[0], rt);
+		qs_s5k4e1_write_right_lsc(&lsc[432], rt);
+		bridge_i2c_write_w(0x06, 0x03);
+	} else if (qs_s5k4e1_ctrl->cam_mode == MODE_2D_LEFT)
+		qs_s5k4e1_write_left_lsc(&lsc[0], rt);
+	else if (qs_s5k4e1_ctrl->cam_mode == MODE_2D_RIGHT)
+		qs_s5k4e1_write_right_lsc(&lsc[432], rt);
+	return 0;
+}
+
+static int32_t qs_s5k4e1_read_left_lsc(char *left_lsc)
+{
+	qs_s5k4e1_eeprom_i2c_read(0x200, &left_lsc[0], 216);
+	qs_s5k4e1_eeprom_i2c_read(0x2D8, &left_lsc[216], 216);
+	return 0;
+}
+
+static int32_t qs_s5k4e1_read_right_lsc(char *right_lsc)
+{
+	qs_s5k4e1_eeprom_i2c_read(0x3B0, &right_lsc[0], 216);
+	qs_s5k4e1_eeprom_i2c_read(0x488, &right_lsc[216], 216);
+	return 0;
+}
+
+static int32_t qs_s5k4e1_read_lsc(char *lsc)
+{
+	qs_s5k4e1_read_left_lsc(&lsc[0]);
+	qs_s5k4e1_read_right_lsc(&lsc[432]);
+	return 0;
+}
+
+static int32_t qs_s5k4e1_bridge_reset(void){
+	unsigned short RegData = 0, GPIOInState = 0;
+	int32_t rc = 0;
+	rc = bridge_i2c_write_w(0x50, 0x00);
+	if (rc < 0)
+		goto bridge_fail;
+	rc = bridge_i2c_write_w(0x53, 0x00);
+	if (rc < 0)
+		goto bridge_fail;
+	msleep(30);
+	rc = bridge_i2c_write_w(0x53, 0x01);
+	if (rc < 0)
+		goto bridge_fail;
+	msleep(30);
+	rc = bridge_i2c_write_w(0x0E, 0xFFFF);
+	if (rc < 0)
+		goto err;
+	rc = bridge_i2c_read(0x54, &RegData, 2);
+	if (rc < 0)
+		goto err;
+	rc = bridge_i2c_write_w(0x54, (RegData | 0x1));
+	if (rc < 0)
+		goto err;
+	msleep(30);
+	rc = bridge_i2c_read(0x54, &RegData, 2);
+	if (rc < 0)
+		goto err;
+	rc = bridge_i2c_write_w(0x54, (RegData | 0x4));
+	if (rc < 0)
+		goto err;
+	rc = bridge_i2c_read(0x55, &GPIOInState, 2);
+	if (rc < 0)
+		goto err;
+	rc = bridge_i2c_write_w(0x55, (GPIOInState | 0x1));
+	if (rc < 0)
+		goto err;
+	msleep(30);
+	rc = bridge_i2c_read(0x55, &GPIOInState, 2);
+	if (rc < 0)
+		goto err;
+	rc = bridge_i2c_write_w(0x55, (GPIOInState | 0x4));
+	if (rc < 0)
+		goto err;
+	msleep(30);
+	rc = bridge_i2c_read(0x55, &GPIOInState, 2);
+	if (rc < 0)
+		goto err;
+	GPIOInState = ((GPIOInState >> 4) & 0x1);
+
+	rc = bridge_i2c_read(0x08, &GPIOInState, 2);
+	if (rc < 0)
+		goto err;
+	rc = bridge_i2c_write_w(0x08, GPIOInState | 0x4000);
+	if (rc < 0)
+		goto err;
+	return rc;
+
+err:
+	bridge_i2c_write_w(0x53, 0x00);
+	msleep(30);
+
+bridge_fail:
+	return rc;
+
+}
+
+static void qs_s5k4e1_bridge_config(int mode, int rt)
+{
+	unsigned short RegData = 0;
+	if (mode == MODE_3D) {
+		bridge_i2c_read(0x54, &RegData, 2);
+		bridge_i2c_write_w(0x54, (RegData | 0x2));
+		bridge_i2c_write_w(0x54, (RegData | 0xa));
+		bridge_i2c_read(0x55, &RegData, 2);
+		bridge_i2c_write_w(0x55, (RegData | 0x2));
+		bridge_i2c_write_w(0x55, (RegData | 0xa));
+		bridge_i2c_write_w(0x14, 0x0C);
+		msleep(20);
+		bridge_i2c_write_w(0x16, 0x00);
+		bridge_i2c_write_w(0x51, 0x3);
+		bridge_i2c_write_w(0x52, 0x1);
+		bridge_i2c_write_w(0x06, 0x03);
+		bridge_i2c_write_w(0x04, 0x2018);
+		bridge_i2c_write_w(0x50, 0x00);
+	} else if (mode == MODE_2D_RIGHT) {
+		bridge_i2c_read(0x54, &RegData, 2);
+		RegData |= 0x2;
+		bridge_i2c_write_w(0x54, RegData);
+		bridge_i2c_write_w(0x54, (RegData & ~(0x8)));
+		bridge_i2c_read(0x55, &RegData, 2);
+		RegData |= 0x2;
+		bridge_i2c_write_w(0x55, RegData);
+		bridge_i2c_write_w(0x55, (RegData & ~(0x8)));
+		bridge_i2c_write_w(0x14, 0x04);
+		msleep(20);
+		bridge_i2c_write_w(0x51, 0x3);
+		bridge_i2c_write_w(0x06, 0x01);
+		bridge_i2c_write_w(0x04, 0x2018);
+		bridge_i2c_write_w(0x50, 0x01);
+	} else if (mode == MODE_2D_LEFT) {
+		bridge_i2c_read(0x54, &RegData, 2);
+		RegData |= 0x8;
+		bridge_i2c_write_w(0x54, RegData);
+		bridge_i2c_write_w(0x54, (RegData & ~(0x2)));
+		bridge_i2c_read(0x55, &RegData, 2);
+		RegData |= 0x8;
+		bridge_i2c_write_w(0x55, RegData);
+		bridge_i2c_write_w(0x55, (RegData & ~(0x2)));
+		bridge_i2c_write_w(0x14, 0x08);
+		msleep(20);
+		bridge_i2c_write_w(0x51, 0x3);
+		bridge_i2c_write_w(0x06, 0x02);
+		bridge_i2c_write_w(0x04, 0x2018);
+		bridge_i2c_write_w(0x50, 0x02);
+	}
+}
+
+static void qs_s5k4e1_group_hold_on(void)
+{
+	qs_s5k4e1_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
+						GROUPED_PARAMETER_HOLD);
+}
+
+static void qs_s5k4e1_group_hold_off(void)
+{
+	qs_s5k4e1_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
+						GROUPED_PARAMETER_HOLD_OFF);
+}
+
+static void qs_s5k4e1_start_stream(void)
+{
+	qs_s5k4e1_i2c_write_b_sensor(0x0100, 0x01);
+}
+
+static void qs_s5k4e1_stop_stream(void)
+{
+	qs_s5k4e1_i2c_write_b_sensor(0x0100, 0x00);
+}
+
+static void qs_s5k4e1_get_pict_fps(uint16_t fps, uint16_t *pfps)
+{
+	/* input fps is preview fps in Q8 format */
+	uint32_t divider, d1, d2;
+
+	d1 = prev_frame_length_lines * 0x00000400 / snap_frame_length_lines;
+	d2 = prev_line_length_pck * 0x00000400 / snap_line_length_pck;
+	divider = d1 * d2 / 0x400;
+
+	/*Verify PCLK settings and frame sizes.*/
+	*pfps = (uint16_t) (fps * divider / 0x400);
+	/* 2 is the ratio of no.of snapshot channels
+	to number of preview channels */
+}
+
+static uint16_t qs_s5k4e1_get_prev_lines_pf(void)
+{
+
+	return prev_frame_length_lines;
+
+}
+
+static uint16_t qs_s5k4e1_get_prev_pixels_pl(void)
+{
+	return prev_line_length_pck;
+
+}
+
+static uint16_t qs_s5k4e1_get_pict_lines_pf(void)
+{
+	return snap_frame_length_lines;
+}
+
+static uint16_t qs_s5k4e1_get_pict_pixels_pl(void)
+{
+	return snap_line_length_pck;
+}
+
+
+static uint32_t qs_s5k4e1_get_pict_max_exp_lc(void)
+{
+	return snap_frame_length_lines  * 24;
+}
+
+static int32_t qs_s5k4e1_set_fps(struct fps_cfg   *fps)
+{
+	uint16_t total_lines_per_frame;
+	int32_t rc = 0;
+	qs_s5k4e1_ctrl->fps_divider = fps->fps_div;
+	qs_s5k4e1_ctrl->pict_fps_divider = fps->pict_fps_div;
+	if (qs_s5k4e1_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
+		total_lines_per_frame = (uint16_t)
+		((prev_frame_length_lines) * qs_s5k4e1_ctrl->fps_divider/0x400);
+	} else {
+		total_lines_per_frame = (uint16_t)
+		((snap_frame_length_lines) *
+			qs_s5k4e1_ctrl->pict_fps_divider/0x400);
+	}
+	qs_s5k4e1_group_hold_on();
+	rc = qs_s5k4e1_i2c_write_w_sensor(REG_FRAME_LENGTH_LINES,
+							total_lines_per_frame);
+	qs_s5k4e1_group_hold_off();
+	return rc;
+}
+
+static int32_t qs_s5k4e1_write_exp_gain(struct sensor_3d_exp_cfg exp_cfg)
+{
+	uint16_t max_legal_gain = 0x0200;
+	uint32_t ll_pck, fl_lines;
+	uint16_t gain = exp_cfg.gain;
+	uint32_t line = exp_cfg.line;
+	int32_t rc = 0;
+	if (gain > max_legal_gain) {
+		CDBG("Max legal gain Line:%d\n", __LINE__);
+		gain = max_legal_gain;
+	}
+	CDBG("qs_s5k4e1_write_exp_gain : gain = %d line = %d\n", gain, line);
+
+	if (qs_s5k4e1_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
+		qs_s5k4e1_ctrl->my_reg_gain = gain;
+		qs_s5k4e1_ctrl->my_reg_line_count = (uint16_t) line;
+		fl_lines = prev_frame_length_lines *
+			qs_s5k4e1_ctrl->fps_divider / 0x400;
+		ll_pck = prev_line_length_pck;
+	} else {
+		fl_lines = snap_frame_length_lines *
+			qs_s5k4e1_ctrl->pict_fps_divider / 0x400;
+		ll_pck = snap_line_length_pck;
+	}
+	if (line > (fl_lines - QS_S5K4E1_OFFSET))
+		fl_lines = line + QS_S5K4E1_OFFSET;
+	qs_s5k4e1_group_hold_on();
+	rc = qs_s5k4e1_i2c_write_w_sensor(REG_GLOBAL_GAIN, gain);
+	rc = qs_s5k4e1_i2c_write_w_sensor(REG_FRAME_LENGTH_LINES, fl_lines);
+	rc = qs_s5k4e1_i2c_write_w_sensor(REG_COARSE_INTEGRATION_TIME, line);
+	if ((qs_s5k4e1_ctrl->cam_mode == MODE_3D) && (cali_data_status == 1)) {
+		bridge_i2c_write_w(0x06, 0x01);
+		rc = qs_s5k4e1_i2c_write_w_sensor(REG_GLOBAL_GAIN,
+			 exp_cfg.gain_adjust);
+		rc = qs_s5k4e1_i2c_write_w_sensor(REG_GR_GAIN, exp_cfg.gr_gain);
+		rc = qs_s5k4e1_i2c_write_w_sensor(REG_R_GAIN,
+				exp_cfg.r_gain);
+		rc = qs_s5k4e1_i2c_write_w_sensor(REG_B_GAIN,
+				exp_cfg.b_gain);
+		rc = qs_s5k4e1_i2c_write_w_sensor(REG_GB_GAIN,
+				exp_cfg.gb_gain);
+		bridge_i2c_write_w(0x06, 0x03);
+	}
+	qs_s5k4e1_group_hold_off();
+	return rc;
+}
+
+static int32_t qs_s5k4e1_set_pict_exp_gain(struct sensor_3d_exp_cfg exp_cfg)
+{
+	int32_t rc = 0;
+	rc = qs_s5k4e1_write_exp_gain(exp_cfg);
+	return rc;
+}
+
+static int32_t qs_s5k4e1_write_focus_value(uint16_t code_value)
+{
+	uint8_t code_val_msb, code_val_lsb;
+	if ((qs_s5k4e1_ctrl->cam_mode == MODE_2D_LEFT) ||
+		(qs_s5k4e1_ctrl->cam_mode == MODE_3D)) {
+		/* Left */
+		bridge_i2c_write_w(0x06, 0x02);
+		CDBG("%s: Left Lens Position: %d\n", __func__,
+			code_value);
+		code_val_msb = code_value >> 4;
+		code_val_lsb = (code_value & 0x000F) << 4;
+		code_val_lsb |= qs_s5k4e1_af_mode;
+		if (af_i2c_write_b_sensor(code_val_msb, code_val_lsb) < 0) {
+			CDBG("move_focus failed at line %d ...\n", __LINE__);
+			return -EBUSY;
+		}
+	}
+
+	if ((qs_s5k4e1_ctrl->cam_mode == MODE_2D_RIGHT) ||
+		(qs_s5k4e1_ctrl->cam_mode == MODE_3D)) {
+		/* Right */
+		bridge_i2c_write_w(0x06, 0x01);
+		code_value += qs_s5k4e1_af_right_adjust;
+		CDBG("%s: Right Lens Position: %d\n", __func__,
+			code_value);
+		code_val_msb = code_value >> 4;
+		code_val_lsb = (code_value & 0x000F) << 4;
+		code_val_lsb |= qs_s5k4e1_af_mode;
+		if (af_i2c_write_b_sensor(code_val_msb, code_val_lsb) < 0) {
+			CDBG("move_focus failed at line %d ...\n", __LINE__);
+			return -EBUSY;
+		}
+	}
+
+	if (qs_s5k4e1_ctrl->cam_mode == MODE_3D) {
+		/* 3D Mode */
+		bridge_i2c_write_w(0x06, 0x03);
+	}
+	usleep(qs_s5k4e1_sw_damping_time_wait*50);
+	return 0;
+}
+
+static int32_t qs_s5k4e1_write_1D_focus_value(uint16_t code_value)
+{
+	uint8_t code_val_msb, code_val_lsb;
+	CDBG("%s: Lens Position: %d\n", __func__, code_value);
+	code_val_msb = code_value >> 4;
+	code_val_lsb = (code_value & 0x000F) << 4;
+	code_val_lsb |= qs_s5k4e1_af_mode;
+	if (af_i2c_write_b_sensor(code_val_msb, code_val_lsb) < 0) {
+		CDBG("move_focus failed at line %d ...\n", __LINE__);
+		return -EBUSY;
+	}
+
+	usleep(qs_s5k4e1_sw_damping_time_wait*50);
+	return 0;
+}
+
+static int32_t qs_s5k4e1_move_focus(int direction,
+	int32_t num_steps)
+{
+	int16_t step_direction, actual_step, dest_lens_position,
+		dest_step_position;
+	int16_t max_step_postion = QS_S5K4E1_TOTAL_STEPS_NEAR_TO_FAR;
+	CDBG("Inside %s\n", __func__);
+	if (direction == MOVE_NEAR)
+		step_direction = 1;
+	else
+		step_direction = -1;
+
+	actual_step = (int16_t) (step_direction * (int16_t) num_steps);
+	dest_step_position = (int16_t) (qs_s5k4e1_ctrl->curr_step_pos +
+		actual_step);
+
+	if (qs_s5k4e1_ctrl->cam_mode == MODE_3D)
+		max_step_postion = QS_S5K4E1_TOTAL_STEPS_3D;
+
+	if (dest_step_position > max_step_postion)
+		dest_step_position = max_step_postion;
+	else if (dest_step_position < 0)
+		dest_step_position = 0;
+
+	if (dest_step_position == qs_s5k4e1_ctrl->curr_step_pos) {
+		CDBG("%s cur and dest pos are same\n", __func__);
+		CDBG("%s cur_step_pos:%d\n", __func__,
+			qs_s5k4e1_ctrl->curr_step_pos);
+		return 0;
+	}
+
+	if (step_direction < 0) {
+		if (num_steps >= 20) {
+			/* sweeping towards all the way in infinity direction */
+			qs_s5k4e1_af_mode = 2;
+			qs_s5k4e1_sw_damping_time_wait = 8;
+		} else if (num_steps <= 4) {
+			/* reverse search during macro mode */
+			qs_s5k4e1_af_mode = 4;
+			qs_s5k4e1_sw_damping_time_wait = 16;
+		} else {
+			qs_s5k4e1_af_mode = 3;
+			qs_s5k4e1_sw_damping_time_wait = 12;
+		}
+	} else {
+		/* coarse search towards macro direction */
+		qs_s5k4e1_af_mode = 4;
+		qs_s5k4e1_sw_damping_time_wait = 16;
+	}
+
+	if (qs_s5k4e1_ctrl->cam_mode == MODE_3D) {
+		/* Left */
+		bridge_i2c_write_w(0x06, 0x02);
+		dest_lens_position =
+			qs_s5k4e1_step_position_table_left[dest_step_position];
+		if (qs_s5k4e1_write_1D_focus_value(dest_lens_position) < 0) {
+			CDBG("move_focus failed at line %d ...\n", __LINE__);
+			bridge_i2c_write_w(0x06, 0x03);
+			return -EBUSY;
+		}
+		/* Keep left sensor as reference as AF stats is from left */
+		qs_s5k4e1_ctrl->curr_step_pos = dest_step_position;
+		qs_s5k4e1_ctrl->curr_lens_pos = dest_lens_position;
+
+		/* Right */
+		bridge_i2c_write_w(0x06, 0x01);
+		dest_lens_position =
+			qs_s5k4e1_step_position_table_right[dest_step_position];
+		if (qs_s5k4e1_write_1D_focus_value(dest_lens_position) < 0) {
+			CDBG("move_focus failed at line %d ...\n", __LINE__);
+			bridge_i2c_write_w(0x06, 0x03);
+			return -EBUSY;
+		}
+
+		/* 3D Mode */
+		bridge_i2c_write_w(0x06, 0x03);
+		return 0;
+	}
+
+	dest_lens_position = qs_s5k4e1_step_position_table[dest_step_position];
+	CDBG("%s: Step Position: %d\n", __func__, dest_step_position);
+	if (qs_s5k4e1_ctrl->curr_lens_pos != dest_lens_position) {
+		if (qs_s5k4e1_write_focus_value(dest_lens_position) < 0) {
+			CDBG("move_focus failed at line %d ...\n", __LINE__);
+			return -EBUSY;
+		}
+	}
+
+	qs_s5k4e1_ctrl->curr_step_pos = dest_step_position;
+	qs_s5k4e1_ctrl->curr_lens_pos = dest_lens_position;
+	return 0;
+}
+
+static int32_t qs_s5k4e1_set_default_focus(uint8_t af_step)
+{
+	int32_t rc = 0;
+	if (qs_s5k4e1_ctrl->curr_step_pos) {
+		rc = qs_s5k4e1_move_focus(MOVE_FAR,
+			qs_s5k4e1_ctrl->curr_step_pos);
+		if (rc < 0)
+			return rc;
+	} else {
+		if (qs_s5k4e1_ctrl->cam_mode == MODE_3D) {
+			/* Left */
+			bridge_i2c_write_w(0x06, 0x02);
+			rc = qs_s5k4e1_write_1D_focus_value(
+				qs_s5k4e1_step_position_table_left[0]);
+			if (rc < 0) {
+				bridge_i2c_write_w(0x06, 0x03);
+				return rc;
+			}
+
+			/* Right */
+			bridge_i2c_write_w(0x06, 0x01);
+			rc = qs_s5k4e1_write_1D_focus_value(
+				qs_s5k4e1_step_position_table_right[0]);
+			if (rc < 0) {
+				bridge_i2c_write_w(0x06, 0x03);
+				return rc;
+			}
+
+			/* Left sensor is the reference sensor for AF stats */
+			qs_s5k4e1_ctrl->curr_lens_pos =
+				qs_s5k4e1_step_position_table_left[0];
+
+			/* 3D Mode */
+			bridge_i2c_write_w(0x06, 0x03);
+		} else {
+			rc = qs_s5k4e1_write_focus_value(
+				qs_s5k4e1_step_position_table[0]);
+			if (rc < 0)
+				return rc;
+			qs_s5k4e1_ctrl->curr_lens_pos =
+				qs_s5k4e1_step_position_table[0];
+		}
+	}
+	CDBG("%s\n", __func__);
+	return 0;
+}
+
+static void qs_s5k4e1_3d_table_init(void)
+{
+	int16_t af_data = 0;
+	uint16_t step = 8, step_q2 = 8, anchor_point_q2;
+	int32_t rc = 0, i, j;
+	uint16_t eeprom_read_addr[2][3] = {{0x110, 0x114, 0x118},
+		{0x112, 0x116, 0x11A} };
+	uint16_t *step_position_table;
+
+	step_position_table = qs_s5k4e1_step_position_table_left;
+	for (j = 0; j < 2; j++) {
+		rc = qs_s5k4e1_eeprom_i2c_read_b(eeprom_read_addr[j][0],
+			&af_data, 2);
+		if (rc == 0) {
+			CDBG("%s: Far data - %d\n", __func__, af_data);
+			step_position_table[0] = af_data;
+		} else {
+			CDBG("%s: EEPROM data read error\n", __func__);
+			return;
+		}
+
+		rc = qs_s5k4e1_eeprom_i2c_read_b(eeprom_read_addr[j][1],
+			&af_data, 2);
+		if (rc == 0) {
+			CDBG("%s: Medium data - %d\n", __func__, af_data);
+			step_position_table[2] = af_data;
+		} else {
+			CDBG("%s: EEPROM data read error\n", __func__);
+			return;
+		}
+
+		/*
+		 * Using the 150cm and 100cm calibration values
+		 * as per the Lens characteristics derive intermediate step
+		 */
+		step_position_table[1] = step_position_table[0] +
+			(step_position_table[2] - step_position_table[0])/2;
+		CDBG("%s: Step between 150cm:100cm is %d\n", __func__,
+			step_position_table[1]);
+
+		rc = qs_s5k4e1_eeprom_i2c_read_b(eeprom_read_addr[j][2],
+			&af_data, 2);
+		if (rc == 0) {
+			CDBG("%s: Short data - %d\n", __func__, af_data);
+			step_position_table[6] = af_data;
+		} else {
+			CDBG("%s: EEPROM data read error\n", __func__);
+			return;
+		}
+
+		/*
+		 * Using the 100cm and 50cm calibration values
+		 * as per the Lens characteristics derive
+		 * intermediate steps
+		 */
+		step = (step_position_table[6] - step_position_table[2])/4;
+
+		/*
+		 * Interpolate the intermediate steps between 100cm
+		 * to 50cm based on COC1.5
+		 */
+		step_position_table[3] = step_position_table[2] + step;
+		step_position_table[4] = step_position_table[3] + step;
+		step_position_table[5] = step_position_table[4] + step;
+
+		/*
+		 * Extrapolate the steps within 50cm based on
+		 * OC2 to converge faster. This range is beyond the 3D
+		 * specification of 50cm
+		 */
+		anchor_point_q2 = step_position_table[6] << 1;
+		step_q2 = (step_position_table[6] - step_position_table[2]);
+
+		for (i = 7; i < QS_S5K4E1_TOTAL_STEPS_3D; i++) {
+			anchor_point_q2 += step_q2;
+			step_position_table[i] = anchor_point_q2 >> 1;
+		}
+		step_position_table = qs_s5k4e1_step_position_table_right;
+	}
+}
+
+static void qs_s5k4e1_init_focus(void)
+{
+	uint8_t i;
+	int32_t rc = 0;
+	int16_t af_far_data = 0;
+	qs_s5k4e1_af_initial_code = 190;
+	/* Read the calibration data from left and right sensors if available */
+	rc = qs_s5k4e1_eeprom_i2c_read_b(0x110, &af_far_data, 2);
+	if (rc == 0) {
+		CDBG("%s: Left Far data - %d\n", __func__, af_far_data);
+		qs_s5k4e1_af_initial_code = af_far_data;
+	}
+
+	rc = qs_s5k4e1_eeprom_i2c_read_b(0x112, &af_far_data, 2);
+	if (rc == 0) {
+		CDBG("%s: Right Far data - %d\n", __func__, af_far_data);
+		qs_s5k4e1_af_right_adjust = af_far_data -
+			qs_s5k4e1_af_initial_code;
+	}
+
+	qs_s5k4e1_3d_table_init();
+
+	qs_s5k4e1_step_position_table[0] = qs_s5k4e1_af_initial_code;
+	for (i = 1; i <= QS_S5K4E1_TOTAL_STEPS_NEAR_TO_FAR; i++) {
+		if (i <= qs_s5k4e1_nl_region_boundary1) {
+			qs_s5k4e1_step_position_table[i] =
+				qs_s5k4e1_step_position_table[i-1]
+				+ qs_s5k4e1_nl_region_code_per_step1;
+		} else {
+			qs_s5k4e1_step_position_table[i] =
+				qs_s5k4e1_step_position_table[i-1]
+				+ qs_s5k4e1_l_region_code_per_step;
+		}
+
+		if (qs_s5k4e1_step_position_table[i] > 1023)
+			qs_s5k4e1_step_position_table[i] = 1023;
+	}
+	qs_s5k4e1_ctrl->curr_step_pos = 0;
+}
+
+static int32_t qs_s5k4e1_test(enum qs_s5k4e1_test_mode_t mo)
+{
+	int32_t rc = 0;
+	if (mo == TEST_OFF)
+		return rc;
+	else {
+		/* REG_0x30D8[4] is TESBYPEN: 0: Normal Operation,
+		1: Bypass Signal Processing
+		REG_0x30D8[5] is EBDMASK: 0:
+		Output Embedded data, 1: No output embedded data */
+		if (qs_s5k4e1_i2c_write_b_sensor(REG_TEST_PATTERN_MODE,
+			(uint8_t) mo) < 0) {
+			return rc;
+		}
+	}
+	return rc;
+}
+
+static int32_t qs_s5k4e1_sensor_setting(int update_type, int rt)
+{
+
+	int32_t rc = 0;
+	struct msm_camera_csi_params qs_s5k4e1_csi_params;
+
+	qs_s5k4e1_stop_stream();
+	msleep(80);
+	bridge_i2c_write_w(0x53, 0x00);
+	msleep(80);
+	if (update_type == REG_INIT) {
+		CSI_CONFIG = 0;
+		LENS_SHADE_CONFIG = 0;
+		default_lens_shade = 0;
+		bridge_i2c_write_w(0x53, 0x01);
+		msleep(30);
+		qs_s5k4e1_bridge_config(qs_s5k4e1_ctrl->cam_mode, rt);
+		msleep(30);
+		qs_s5k4e1_i2c_write_b_table(qs_s5k4e1_regs.rec_settings,
+				qs_s5k4e1_regs.rec_size);
+		msleep(30);
+	} else if (update_type == UPDATE_PERIODIC) {
+		qs_s5k4e1_write_lsc(lens_eeprom_data, rt);
+		msleep(100);
+		if (!CSI_CONFIG) {
+			if (qs_s5k4e1_ctrl->cam_mode == MODE_3D) {
+				qs_s5k4e1_csi_params.lane_cnt = 4;
+				qs_s5k4e1_csi_params.data_format = CSI_8BIT;
+			} else {
+				qs_s5k4e1_csi_params.lane_cnt = 1;
+				qs_s5k4e1_csi_params.data_format = CSI_10BIT;
+			}
+			qs_s5k4e1_csi_params.lane_assign = 0xe4;
+			qs_s5k4e1_csi_params.dpcm_scheme = 0;
+			qs_s5k4e1_csi_params.settle_cnt = 28;
+			rc = msm_camio_csi_config(&qs_s5k4e1_csi_params);
+			msleep(10);
+			cam_debug_init();
+			CSI_CONFIG = 1;
+		}
+		bridge_i2c_write_w(0x53, 0x01);
+		msleep(50);
+		qs_s5k4e1_i2c_write_b_table(qs_s5k4e1_regs.conf_array[rt].conf,
+			qs_s5k4e1_regs.conf_array[rt].size);
+		msleep(50);
+		qs_s5k4e1_start_stream();
+		msleep(80);
+	}
+	return rc;
+}
+
+static int32_t qs_s5k4e1_video_config(int mode)
+{
+
+	int32_t rc = 0;
+	/* change sensor resolution if needed */
+	if (qs_s5k4e1_sensor_setting(UPDATE_PERIODIC,
+			qs_s5k4e1_ctrl->prev_res) < 0)
+		return rc;
+	if (qs_s5k4e1_ctrl->set_test) {
+		if (qs_s5k4e1_test(qs_s5k4e1_ctrl->set_test) < 0)
+			return  rc;
+	}
+
+	qs_s5k4e1_ctrl->curr_res = qs_s5k4e1_ctrl->prev_res;
+	qs_s5k4e1_ctrl->sensormode = mode;
+	return rc;
+}
+
+static int32_t qs_s5k4e1_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+	/*change sensor resolution if needed */
+	if (qs_s5k4e1_ctrl->curr_res != qs_s5k4e1_ctrl->pict_res) {
+		if (qs_s5k4e1_sensor_setting(UPDATE_PERIODIC,
+				qs_s5k4e1_ctrl->pict_res) < 0)
+			return rc;
+	}
+
+	qs_s5k4e1_ctrl->curr_res = qs_s5k4e1_ctrl->pict_res;
+	qs_s5k4e1_ctrl->sensormode = mode;
+	return rc;
+} /*end of qs_s5k4e1_snapshot_config*/
+
+static int32_t qs_s5k4e1_raw_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+	/* change sensor resolution if needed */
+	if (qs_s5k4e1_ctrl->curr_res != qs_s5k4e1_ctrl->pict_res) {
+		if (qs_s5k4e1_sensor_setting(UPDATE_PERIODIC,
+				qs_s5k4e1_ctrl->pict_res) < 0)
+			return rc;
+	}
+
+	qs_s5k4e1_ctrl->curr_res = qs_s5k4e1_ctrl->pict_res;
+	qs_s5k4e1_ctrl->sensormode = mode;
+	return rc;
+} /*end of qs_s5k4e1_raw_snapshot_config*/
+
+static int32_t qs_s5k4e1_mode_init(int mode, struct sensor_init_cfg init_info)
+{
+	int32_t rc = 0;
+	if (mode != qs_s5k4e1_ctrl->cam_mode) {
+		qs_s5k4e1_ctrl->prev_res = init_info.prev_res;
+		qs_s5k4e1_ctrl->pict_res = init_info.pict_res;
+		qs_s5k4e1_ctrl->cam_mode = mode;
+
+		prev_frame_length_lines =
+		((qs_s5k4e1_regs.conf_array[qs_s5k4e1_ctrl->prev_res]\
+			.conf[QS_S5K4E1_FRAME_LENGTH_LINES_H].wdata << 8)
+			| qs_s5k4e1_regs.conf_array[qs_s5k4e1_ctrl->prev_res]\
+			.conf[QS_S5K4E1_FRAME_LENGTH_LINES_L].wdata);
+		prev_line_length_pck =
+		(qs_s5k4e1_regs.conf_array[qs_s5k4e1_ctrl->prev_res]\
+			.conf[QS_S5K4E1_LINE_LENGTH_PCK_H].wdata << 8)
+			| qs_s5k4e1_regs.conf_array[qs_s5k4e1_ctrl->prev_res]\
+			.conf[QS_S5K4E1_LINE_LENGTH_PCK_L].wdata;
+		snap_frame_length_lines =
+		(qs_s5k4e1_regs.conf_array[qs_s5k4e1_ctrl->pict_res]\
+			.conf[QS_S5K4E1_FRAME_LENGTH_LINES_H].wdata << 8)
+			| qs_s5k4e1_regs.conf_array[qs_s5k4e1_ctrl->pict_res]\
+			.conf[QS_S5K4E1_FRAME_LENGTH_LINES_L].wdata;
+		snap_line_length_pck =
+		(qs_s5k4e1_regs.conf_array[qs_s5k4e1_ctrl->pict_res]\
+			.conf[QS_S5K4E1_LINE_LENGTH_PCK_H].wdata << 8)
+			| qs_s5k4e1_regs.conf_array[qs_s5k4e1_ctrl->pict_res]\
+			.conf[QS_S5K4E1_LINE_LENGTH_PCK_L].wdata;
+
+	rc = qs_s5k4e1_sensor_setting(REG_INIT,
+		qs_s5k4e1_ctrl->prev_res);
+	}
+	return rc;
+}
+static int32_t qs_s5k4e1_set_sensor_mode(int mode,
+	int res)
+{
+	int32_t rc = 0;
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		qs_s5k4e1_ctrl->prev_res = res;
+		rc = qs_s5k4e1_video_config(mode);
+		break;
+	case SENSOR_SNAPSHOT_MODE:
+		qs_s5k4e1_ctrl->pict_res = res;
+		rc = qs_s5k4e1_snapshot_config(mode);
+		break;
+	case SENSOR_RAW_SNAPSHOT_MODE:
+		qs_s5k4e1_ctrl->pict_res = res;
+		rc = qs_s5k4e1_raw_snapshot_config(mode);
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
+static int32_t qs_s5k4e1_power_down(void)
+{
+	qs_s5k4e1_stop_stream();
+	msleep(30);
+	qs_s5k4e1_af_mode = 2;
+	qs_s5k4e1_af_right_adjust = 0;
+	qs_s5k4e1_write_focus_value(0);
+	msleep(100);
+	/* Set AF actutator to PowerDown */
+	af_i2c_write_b_sensor(0x80, 00);
+	return 0;
+}
+
+static int qs_s5k4e1_probe_init_done(const struct msm_camera_sensor_info *data)
+{
+	CDBG("probe done\n");
+	gpio_free(data->sensor_reset);
+	return 0;
+}
+
+static int
+	qs_s5k4e1_probe_init_sensor(const struct msm_camera_sensor_info *data)
+{
+	int32_t rc = 0;
+	uint16_t chipid = 0;
+	CDBG("%s: %d\n", __func__, __LINE__);
+	rc = gpio_request(data->sensor_reset, "qs_s5k4e1");
+	CDBG(" qs_s5k4e1_probe_init_sensor\n");
+	if (!rc) {
+		CDBG("sensor_reset = %d\n", rc);
+		gpio_direction_output(data->sensor_reset, 0);
+		msleep(50);
+		gpio_set_value_cansleep(data->sensor_reset, 1);
+		msleep(13);
+	} else {
+		goto init_probe_done;
+	}
+	msleep(70);
+	rc = qs_s5k4e1_bridge_reset();
+	if (rc < 0)
+		goto init_probe_fail;
+	qs_s5k4e1_bridge_config(MODE_3D, RES_PREVIEW);
+	msleep(30);
+
+	CDBG(" qs_s5k4e1_probe_init_sensor is called\n");
+	rc = qs_s5k4e1_i2c_read(0x0000, &chipid, 2);
+	CDBG("ID: %d\n", chipid);
+	/* 4. Compare sensor ID to QS_S5K4E1 ID: */
+	if (chipid != 0x4e10) {
+		rc = -ENODEV;
+		CDBG("qs_s5k4e1_probe_init_sensor fail chip id mismatch\n");
+		goto init_probe_fail;
+	}
+	goto init_probe_done;
+init_probe_fail:
+	CDBG(" qs_s5k4e1_probe_init_sensor fails\n");
+	gpio_set_value_cansleep(data->sensor_reset, 0);
+	qs_s5k4e1_probe_init_done(data);
+init_probe_done:
+	CDBG(" qs_s5k4e1_probe_init_sensor finishes\n");
+	return rc;
+}
+/* camsensor_qs_s5k4e1_reset */
+
+int qs_s5k4e1_sensor_open_init(const struct msm_camera_sensor_info *data)
+{
+	int32_t rc = 0;
+	CDBG("%s: %d\n", __func__, __LINE__);
+	CDBG("Calling qs_s5k4e1_sensor_open_init\n");
+
+	qs_s5k4e1_ctrl = kzalloc(sizeof(struct qs_s5k4e1_ctrl_t), GFP_KERNEL);
+	if (!qs_s5k4e1_ctrl) {
+		CDBG("qs_s5k4e1_init failed!\n");
+		rc = -ENOMEM;
+		goto init_done;
+	}
+	qs_s5k4e1_ctrl->fps_divider = 1 * 0x00000400;
+	qs_s5k4e1_ctrl->pict_fps_divider = 1 * 0x00000400;
+	qs_s5k4e1_ctrl->set_test = TEST_OFF;
+	qs_s5k4e1_ctrl->cam_mode = MODE_INVALID;
+
+	if (data)
+		qs_s5k4e1_ctrl->sensordata = data;
+	if (rc < 0) {
+		CDBG("Calling qs_s5k4e1_sensor_open_init fail1\n");
+		return rc;
+	}
+	CDBG("%s: %d\n", __func__, __LINE__);
+	/* enable mclk first */
+	msm_camio_clk_rate_set(QS_S5K4E1_MASTER_CLK_RATE);
+	rc = qs_s5k4e1_probe_init_sensor(data);
+	if (rc < 0)
+		goto init_fail;
+/*Default mode is 3D*/
+	memcpy(lens_eeprom_data, data->eeprom_data, 864);
+	qs_s5k4e1_ctrl->fps = 30*Q8;
+	qs_s5k4e1_init_focus();
+	if (rc < 0) {
+		gpio_set_value_cansleep(data->sensor_reset, 0);
+		goto init_fail;
+	} else
+		goto init_done;
+init_fail:
+	CDBG("init_fail\n");
+	qs_s5k4e1_probe_init_done(data);
+init_done:
+	CDBG("init_done\n");
+	return rc;
+} /*endof qs_s5k4e1_sensor_open_init*/
+
+static int qs_s5k4e1_init_client(struct i2c_client *client)
+{
+	/* Initialize the MSM_CAMI2C Chip */
+	init_waitqueue_head(&qs_s5k4e1_wait_queue);
+	return 0;
+}
+
+static const struct i2c_device_id qs_s5k4e1_i2c_id[] = {
+	{"qs_s5k4e1", 0},
+	{ }
+};
+
+static int qs_s5k4e1_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+	CDBG("qs_s5k4e1_probe called!\n");
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		CDBG("i2c_check_functionality failed\n");
+		goto probe_failure;
+	}
+
+	qs_s5k4e1_sensorw = kzalloc(sizeof(struct qs_s5k4e1_work_t),
+		 GFP_KERNEL);
+	if (!qs_s5k4e1_sensorw) {
+		CDBG("kzalloc failed.\n");
+		rc = -ENOMEM;
+		goto probe_failure;
+	}
+
+	i2c_set_clientdata(client, qs_s5k4e1_sensorw);
+	qs_s5k4e1_init_client(client);
+	qs_s5k4e1_client = client;
+
+	msleep(50);
+
+	CDBG("qs_s5k4e1_probe successed! rc = %d\n", rc);
+	return 0;
+
+probe_failure:
+	CDBG("qs_s5k4e1_probe failed! rc = %d\n", rc);
+	return rc;
+}
+
+static int qs_s5k4e1_send_wb_info(struct wb_info_cfg *wb)
+{
+	return 0;
+
+} /*end of qs_s5k4e1_snapshot_config*/
+
+static int __exit qs_s5k4e1_remove(struct i2c_client *client)
+{
+	struct qs_s5k4e1_work_t_t *sensorw = i2c_get_clientdata(client);
+	free_irq(client->irq, sensorw);
+	qs_s5k4e1_client = NULL;
+	kfree(sensorw);
+	return 0;
+}
+
+static struct i2c_driver qs_s5k4e1_i2c_driver = {
+	.id_table = qs_s5k4e1_i2c_id,
+	.probe  = qs_s5k4e1_i2c_probe,
+	.remove = __exit_p(qs_s5k4e1_i2c_remove),
+	.driver = {
+		.name = "qs_s5k4e1",
+	},
+};
+
+int qs_s5k4e1_3D_sensor_config(void __user *argp)
+{
+	struct sensor_large_data cdata;
+	long rc;
+	if (copy_from_user(&cdata,
+		(void *)argp,
+		sizeof(struct sensor_large_data)))
+		return -EFAULT;
+	mutex_lock(&qs_s5k4e1_mut);
+	rc = qs_s5k4e1_get_calibration_data
+		(&cdata.data.sensor_3d_cali_data);
+	if (rc < 0)
+		goto fail;
+	if (copy_to_user((void *)argp,
+		&cdata,
+		sizeof(struct sensor_large_data)))
+		rc = -EFAULT;
+fail:
+	mutex_unlock(&qs_s5k4e1_mut);
+	return rc;
+}
+
+int qs_s5k4e1_2D_sensor_config(void __user *argp)
+{
+	struct sensor_cfg_data cdata;
+	long   rc = 0;
+	if (copy_from_user(&cdata,
+		(void *)argp,
+		sizeof(struct sensor_cfg_data)))
+		return -EFAULT;
+	mutex_lock(&qs_s5k4e1_mut);
+	CDBG("qs_s5k4e1_sensor_config: cfgtype = %d\n",
+	cdata.cfgtype);
+		switch (cdata.cfgtype) {
+		case CFG_GET_PICT_FPS:
+			qs_s5k4e1_get_pict_fps(
+				cdata.cfg.gfps.prevfps,
+				&(cdata.cfg.gfps.pictfps));
+
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_GET_PREV_L_PF:
+			cdata.cfg.prevl_pf =
+			qs_s5k4e1_get_prev_lines_pf();
+
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_GET_PREV_P_PL:
+			cdata.cfg.prevp_pl =
+				qs_s5k4e1_get_prev_pixels_pl();
+
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_GET_PICT_L_PF:
+			cdata.cfg.pictl_pf =
+				qs_s5k4e1_get_pict_lines_pf();
+
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_GET_PICT_P_PL:
+			cdata.cfg.pictp_pl =
+				qs_s5k4e1_get_pict_pixels_pl();
+
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_GET_PICT_MAX_EXP_LC:
+			cdata.cfg.pict_max_exp_lc =
+				qs_s5k4e1_get_pict_max_exp_lc();
+
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_SET_FPS:
+		case CFG_SET_PICT_FPS:
+			rc = qs_s5k4e1_set_fps(&(cdata.cfg.fps));
+			break;
+
+		case CFG_SET_EXP_GAIN:
+			rc =
+				qs_s5k4e1_write_exp_gain(
+					cdata.cfg.sensor_3d_exp);
+			break;
+
+		case CFG_SET_PICT_EXP_GAIN:
+			rc =
+				qs_s5k4e1_set_pict_exp_gain(
+				cdata.cfg.sensor_3d_exp);
+			break;
+
+		case CFG_SET_MODE:
+			rc = qs_s5k4e1_set_sensor_mode(cdata.mode,
+					cdata.rs);
+			break;
+
+		case CFG_PWR_DOWN:
+			rc = qs_s5k4e1_power_down();
+			break;
+
+		case CFG_MOVE_FOCUS:
+			rc =
+				qs_s5k4e1_move_focus(
+				cdata.cfg.focus.dir,
+				cdata.cfg.focus.steps);
+			break;
+
+		case CFG_SET_DEFAULT_FOCUS:
+			rc =
+				qs_s5k4e1_set_default_focus(
+				cdata.cfg.focus.steps);
+			break;
+
+		case CFG_GET_AF_MAX_STEPS:
+			if (qs_s5k4e1_ctrl->cam_mode == MODE_3D)
+				cdata.max_steps = QS_S5K4E1_TOTAL_STEPS_3D;
+			else
+				cdata.max_steps =
+					QS_S5K4E1_TOTAL_STEPS_NEAR_TO_FAR;
+
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_SET_EFFECT:
+			rc = qs_s5k4e1_set_default_focus(
+				cdata.cfg.effect);
+			break;
+
+
+		case CFG_SEND_WB_INFO:
+			rc = qs_s5k4e1_send_wb_info(
+				&(cdata.cfg.wb_info));
+			break;
+
+		case CFG_SENSOR_INIT:
+			rc = qs_s5k4e1_mode_init(cdata.mode,
+					cdata.cfg.init_info);
+			break;
+
+		default:
+			rc = -EFAULT;
+			break;
+		}
+
+	mutex_unlock(&qs_s5k4e1_mut);
+
+	return rc;
+}
+
+int qs_s5k4e1_sensor_config(void __user *argp)
+{
+	int cfgtype;
+	long rc;
+	if (copy_from_user(&cfgtype,
+		(void *)argp,
+		sizeof(int)))
+		return -EFAULT;
+	if (cfgtype != CFG_GET_3D_CALI_DATA)
+		rc = qs_s5k4e1_2D_sensor_config(argp);
+	else
+		rc = qs_s5k4e1_3D_sensor_config(argp);
+	return rc;
+}
+
+static int qs_s5k4e1_sensor_release(void)
+{
+	int rc = -EBADF;
+	mutex_lock(&qs_s5k4e1_mut);
+	qs_s5k4e1_power_down();
+	bridge_i2c_write_w(0x53, 0x00);
+	msleep(20);
+	gpio_set_value_cansleep(qs_s5k4e1_ctrl->sensordata->sensor_reset, 0);
+	msleep(5);
+	gpio_free(qs_s5k4e1_ctrl->sensordata->sensor_reset);
+	kfree(qs_s5k4e1_ctrl);
+	qs_s5k4e1_ctrl = NULL;
+	CDBG("qs_s5k4e1_release completed\n");
+	mutex_unlock(&qs_s5k4e1_mut);
+
+	return rc;
+}
+
+static int qs_s5k4e1_sensor_probe(const struct msm_camera_sensor_info *info,
+		struct msm_sensor_ctrl *s)
+{
+	int rc = 0;
+	rc = i2c_add_driver(&qs_s5k4e1_i2c_driver);
+	if (rc < 0 || qs_s5k4e1_client == NULL) {
+		rc = -ENOTSUPP;
+		CDBG("I2C add driver failed");
+		goto probe_fail;
+	}
+	msm_camio_clk_rate_set(QS_S5K4E1_MASTER_CLK_RATE);
+	rc = qs_s5k4e1_probe_init_sensor(info);
+	if (rc < 0)
+		goto probe_fail;
+	qs_s5k4e1_read_lsc(info->eeprom_data); /*Default mode is 3D*/
+	s->s_init = qs_s5k4e1_sensor_open_init;
+	s->s_release = qs_s5k4e1_sensor_release;
+	s->s_config  = qs_s5k4e1_sensor_config;
+	s->s_mount_angle = info->sensor_platform_info->mount_angle;
+	s->s_camera_type = BACK_CAMERA_3D;
+	s->s_video_packing = SIDE_BY_SIDE_HALF;
+	s->s_snap_packing = SIDE_BY_SIDE_FULL;
+	bridge_i2c_write_w(0x53, 0x00);
+	msleep(20);
+	gpio_set_value_cansleep(info->sensor_reset, 0);
+	qs_s5k4e1_probe_init_done(info);
+	return rc;
+
+probe_fail:
+	CDBG("qs_s5k4e1_sensor_probe: SENSOR PROBE FAILS!\n");
+	return rc;
+}
+
+static bool streaming = 1;
+
+static int qs_s5k4e1_focus_test(void *data, u64 *val)
+{
+	int i = 0;
+	qs_s5k4e1_set_default_focus(0);
+
+	for (i = 0; i < QS_S5K4E1_TOTAL_STEPS_NEAR_TO_FAR; i++) {
+		qs_s5k4e1_move_focus(MOVE_NEAR, 1);
+		msleep(2000);
+	}
+	msleep(5000);
+	for ( ; i > 0; i--) {
+		qs_s5k4e1_move_focus(MOVE_FAR, 1);
+		msleep(2000);
+	}
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(cam_focus, qs_s5k4e1_focus_test,
+			NULL, "%lld\n");
+
+static int qs_s5k4e1_step_test(void *data, u64 *val)
+{
+	int rc = 0;
+	struct sensor_large_data cdata;
+	rc = qs_s5k4e1_get_calibration_data
+		(&cdata.data.sensor_3d_cali_data);
+	if (rc < 0)
+		CDBG("%s: Calibration data read fail.\n", __func__);
+
+	return 0;
+}
+
+static int qs_s5k4e1_set_step(void *data, u64 val)
+{
+	qs_s5k4e1_l_region_code_per_step = val & 0xFF;
+	qs_s5k4e1_af_mode = (val >> 8) & 0xFF;
+	qs_s5k4e1_nl_region_code_per_step1 = (val >> 16) & 0xFFFF;
+
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(cam_step, qs_s5k4e1_step_test,
+			qs_s5k4e1_set_step, "%lld\n");
+
+static int cam_debug_stream_set(void *data, u64 val)
+{
+	int rc = 0;
+
+	if (val) {
+		qs_s5k4e1_start_stream();
+		streaming = 1;
+	} else {
+		qs_s5k4e1_stop_stream();
+		streaming = 0;
+	}
+
+	return rc;
+}
+
+static int cam_debug_stream_get(void *data, u64 *val)
+{
+	*val = streaming;
+	return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(cam_stream, cam_debug_stream_get,
+			cam_debug_stream_set, "%llu\n");
+
+static uint16_t qs_s5k4e1_step_val = QS_S5K4E1_TOTAL_STEPS_NEAR_TO_FAR;
+static uint8_t qs_s5k4e1_step_dir = MOVE_NEAR;
+static int qs_s5k4e1_af_step_config(void *data, u64 val)
+{
+	qs_s5k4e1_step_val = val & 0xFFFF;
+	qs_s5k4e1_step_dir = (val >> 16) & 0x1;
+	CDBG("%s\n", __func__);
+	return 0;
+}
+
+static int qs_s5k4e1_af_step(void *data, u64 *val)
+{
+	int i = 0;
+	int dir = MOVE_NEAR;
+	CDBG("%s\n", __func__);
+	qs_s5k4e1_set_default_focus(0);
+	msleep(5000);
+	if (qs_s5k4e1_step_dir == 1)
+		dir = MOVE_FAR;
+
+	for (i = 0; i < qs_s5k4e1_step_val; i += 4) {
+		qs_s5k4e1_move_focus(dir, 4);
+		msleep(1000);
+	}
+	qs_s5k4e1_set_default_focus(0);
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(af_step, qs_s5k4e1_af_step,
+			qs_s5k4e1_af_step_config, "%llu\n");
+
+static int cam_debug_init(void)
+{
+	struct dentry *cam_dir;
+	debugfs_base = debugfs_create_dir("sensor", NULL);
+	if (!debugfs_base)
+		return -ENOMEM;
+
+	cam_dir = debugfs_create_dir("qs_s5k4e1", debugfs_base);
+	if (!cam_dir)
+		return -ENOMEM;
+
+	if (!debugfs_create_file("focus", S_IRUGO | S_IWUSR, cam_dir,
+							 NULL, &cam_focus))
+		return -ENOMEM;
+	if (!debugfs_create_file("step", S_IRUGO | S_IWUSR, cam_dir,
+							 NULL, &cam_step))
+		return -ENOMEM;
+	if (!debugfs_create_file("stream", S_IRUGO | S_IWUSR, cam_dir,
+							 NULL, &cam_stream))
+		return -ENOMEM;
+	if (!debugfs_create_file("af_step", S_IRUGO | S_IWUSR, cam_dir,
+							 NULL, &af_step))
+		return -ENOMEM;
+	return 0;
+}
+
+static int __qs_s5k4e1_probe(struct platform_device *pdev)
+{
+	return msm_camera_drv_start(pdev, qs_s5k4e1_sensor_probe);
+}
+
+static struct platform_driver msm_camera_driver = {
+	.probe = __qs_s5k4e1_probe,
+	.driver = {
+		.name = "msm_camera_qs_s5k4e1",
+	.owner = THIS_MODULE,
+	},
+};
+
+static int __init qs_s5k4e1_init(void)
+{
+	return platform_driver_register(&msm_camera_driver);
+}
+
+module_init(qs_s5k4e1_init);
+void qs_s5k4e1_exit(void)
+{
+	i2c_del_driver(&qs_s5k4e1_i2c_driver);
+}
+MODULE_DESCRIPTION("Samsung 5MP Bayer sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/qs_s5k4e1.h b/drivers/media/platform/msm/camera_v1/qs_s5k4e1.h
new file mode 100644
index 0000000..dca3d0a
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/qs_s5k4e1.h
@@ -0,0 +1,89 @@
+/* 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.
+ *
+ */
+
+#ifndef QS_S5K4E1_H
+#define QS_S5K4E1_H
+#include <linux/types.h>
+#include <mach/board.h>
+extern struct qs_s5k4e1_reg qs_s5k4e1_regs;
+
+#define LENS_SHADE_TABLE 16
+
+struct qs_s5k4e1_i2c_reg_conf {
+	unsigned short waddr;
+	unsigned short wdata;
+};
+
+struct qs_s5k4e1_i2c_conf_array {
+       struct qs_s5k4e1_i2c_reg_conf *conf;
+       unsigned short size;
+};
+
+enum qs_s5k4e1_test_mode_t {
+	TEST_OFF,
+	TEST_1,
+	TEST_2,
+	TEST_3
+};
+
+enum qs_s5k4e1_resolution_t {
+	QTR_2D_SIZE,
+	FULL_2D_SIZE,
+	QTR_3D_SIZE,
+	FULL_3D_SIZE,
+	INVALID_SIZE
+};
+enum qs_s5k4e1_setting {
+	RES_PREVIEW,
+	RES_CAPTURE,
+	RES_3D_PREVIEW,
+	RES_3D_CAPTURE
+};
+enum qs_s5k4e1_cam_mode_t {
+    MODE_2D_RIGHT,
+	MODE_2D_LEFT,
+	MODE_3D,
+	MODE_INVALID
+};
+enum qs_s5k4e1_reg_update {
+	/* Sensor egisters that need to be updated during initialization */
+	REG_INIT,
+	/* Sensor egisters that needs periodic I2C writes */
+	UPDATE_PERIODIC,
+	/* All the sensor Registers will be updated */
+	UPDATE_ALL,
+	/* Not valid update */
+	UPDATE_INVALID
+};
+
+enum qs_s5k4e1_reg_mode {
+	QS_S5K4E1_FRAME_LENGTH_LINES_H = 1,
+	QS_S5K4E1_FRAME_LENGTH_LINES_L,
+	QS_S5K4E1_LINE_LENGTH_PCK_H,
+	QS_S5K4E1_LINE_LENGTH_PCK_L,
+};
+
+struct qs_s5k4e1_reg {
+	const struct qs_s5k4e1_i2c_reg_conf *rec_settings;
+	const unsigned short rec_size;
+	const struct qs_s5k4e1_i2c_reg_conf *reg_prev;
+	const unsigned short reg_prev_size;
+	const struct qs_s5k4e1_i2c_reg_conf *reg_snap;
+	const unsigned short reg_snap_size;
+	const struct qs_s5k4e1_i2c_reg_conf (*reg_lens)[LENS_SHADE_TABLE];
+	const unsigned short reg_lens_size;
+	const struct qs_s5k4e1_i2c_reg_conf *reg_default_lens;
+	const unsigned short reg_default_lens_size;
+	const struct qs_s5k4e1_i2c_conf_array *conf_array;
+};
+#endif /* QS_S5K4E1_H */
diff --git a/drivers/media/platform/msm/camera_v1/qs_s5k4e1_reg.c b/drivers/media/platform/msm/camera_v1/qs_s5k4e1_reg.c
new file mode 100644
index 0000000..b872343
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/qs_s5k4e1_reg.c
@@ -0,0 +1,804 @@
+/* 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 "qs_s5k4e1.h"
+
+struct qs_s5k4e1_i2c_reg_conf qs_s5k4e1_prev_settings_3d[] = {
+	{0x0100, 0x00},
+	/*Frame Length*/
+	{0x0340, 0x04},
+	{0x0341, 0x90},
+	/*Line Length*/
+	{0x0342, 0x0A},
+	{0x0343, 0xB2},
+	{0x3030, 0x06},
+	{0x3017, 0xA4},
+	{0x301B, 0x88},
+	{0x30BC, 0x90},
+	{0x301C, 0x04},
+	{0x0202, 0x04},
+	{0x0203, 0x12},
+	{0x0204, 0x00},
+	{0x0205, 0x80},
+	{0x0306, 0x00},
+	{0x0307, 0x60},
+	{0x30B5, 0x01},
+	{0x30E2, 0x02},/*num lanes[1:0] = 1*/
+	{0x30F1, 0x60},
+/*MIPI Size Setting*/
+	{0x30A9, 0x02},
+	{0x300E, 0xE8},
+	{0x0387, 0x01},
+	{0x0344, 0x01},
+	{0x0345, 0x18},
+	{0x0348, 0x09},
+	{0x0349, 0x17},
+	{0x0346, 0x01},
+	{0x0347, 0x94},
+	{0x034A, 0x06},
+	{0x034B, 0x13},
+	{0x0380, 0x00},
+	{0x0381, 0x01},
+	{0x0382, 0x00},
+	{0x0383, 0x01},
+	{0x0384, 0x00},
+	{0x0385, 0x01},
+	{0x0386, 0x00},
+	{0x0387, 0x01},
+	{0x034C, 0x04},
+	{0x034D, 0x00},
+	{0x034E, 0x04},
+	{0x034F, 0x80},
+	{0x30BF, 0xAA},
+	{0x30C0, 0x40},
+	{0x30C8, 0x04},
+	{0x30C9, 0x00},
+};
+
+struct qs_s5k4e1_i2c_reg_conf qs_s5k4e1_prev_settings_2d[] = {
+	{0x0100, 0x00},
+	{0x0340, 0x03},
+	{0x0341, 0xe0},
+	{0x0342, 0x0A},
+	{0x0343, 0xB2},
+	{0x3030, 0x06},
+	{0x301B, 0x83},
+	{0x30BC, 0x98},
+	{0x301C, 0x04},
+	{0x0202, 0x01},
+	{0x0203, 0xFD},
+	{0x0204, 0x00},
+	{0x0205, 0x80},
+	{0x0306, 0x00},
+	{0x0307, 0x64},
+	{0x30B5, 0x00},
+	{0x30E2, 0x01},/*num lanes[1:0] = 1*/
+	{0x30F1, 0xd0},
+	{0x30A9, 0x02},
+	{0x300E, 0xEB},
+	{0x0387, 0x03},
+	{0x0344, 0x00},
+	{0x0345, 0x00},
+	{0x0348, 0x0A},
+	{0x0349, 0x2F},
+	{0x0346, 0x00},
+	{0x0347, 0x00},
+	{0x034A, 0x07},
+	{0x034B, 0xA7},
+	{0x0380, 0x00},
+	{0x0381, 0x01},
+	{0x0382, 0x00},
+	{0x0383, 0x01},
+	{0x0384, 0x00},
+	{0x0385, 0x01},
+	{0x0386, 0x00},
+	{0x0387, 0x03},
+	{0x034C, 0x05},
+	{0x034D, 0x10},
+	{0x034E, 0x03},
+	{0x034F, 0xd4},
+	{0x30BF, 0xAB},
+	{0x30C0, 0xc0},
+	{0x30C8, 0x06},
+	{0x30C9, 0x54},
+};
+
+struct qs_s5k4e1_i2c_reg_conf qs_s5k4e1_snap_settings_2d[] = {
+	{0x0100, 0x00},
+	{0x0340, 0x07},
+	{0x0341, 0xb4},
+	{0x0342, 0x0A},
+	{0x0343, 0xB2},
+	{0x3030, 0x06}, /*shut streaming off*/
+	{0x300E, 0xE8},
+	{0x301B, 0x75},
+	{0x301C, 0x04},
+	{0x30BC, 0x98},
+	{0x0202, 0x04},
+	{0x0203, 0x12},
+	{0x0204, 0x00},
+	{0x0205, 0x80},
+	{0x0306, 0x00},
+	{0x0307, 0x64},
+	{0x30B5, 0x00},
+	{0x30E2, 0x01},/*num lanes[1:0] = 1*/
+	{0x30F1, 0xd0},
+	{0x30A9, 0x03},/*Horizontal Binning Off*/
+	{0x300E, 0xE8},/*Vertical Binning Off*/
+	{0x0387, 0x01},/*y_odd_inc*/
+	{0x034C, 0x0A},/*x_output size*/
+	{0x034D, 0x30},
+	{0x034E, 0x07},/*y_output size*/
+	{0x034F, 0xA8},
+	{0x30BF, 0xAB},/*outif_enable[7], data_type[5:0](2Bh = bayer 10bit)*/
+	{0x30C0, 0x86},/*video_offset[7:4] 3260%12*/
+	{0x30C8, 0x0C},/*video_data_length 3260 = 2608 * 1.25*/
+	{0x30C9, 0xBC},
+
+};
+
+struct qs_s5k4e1_i2c_reg_conf qs_s5k4e1_snap_settings_3d[] = {
+	{0x0100, 0x00},
+
+/* Frame Length*/
+	{0x0340, 0x09},
+	{0x0341, 0x20},
+/* Line Length*/
+	{0x0342, 0x0A},
+	{0x0343, 0xB2},
+	{0x3030, 0x06},/*shut streaming off*/
+/*Analog Setting*/
+	{0x3017, 0xA4},
+	{0x301B, 0x88},
+	{0x30BC, 0x90},
+	{0x301C, 0x04},
+/*Integration setting ... */
+	{0x0202, 0x04},
+	{0x0203, 0x12},
+	{0x0204, 0x00},
+	{0x0205, 0x80},
+/*PLL setting ...*/
+	{0x0306, 0x00},
+	{0x0307, 0x60},
+	{0x30B5, 0x01},
+	{0x30E2, 0x02},/*num lanes[1:0] = 1*/
+	{0x30F1, 0x60},
+/*MIPI Size Setting*/
+	{0x30A9, 0x01},
+	{0x300E, 0xE8},
+	{0x0387, 0x01},
+	{0x0344, 0x01},/*x_addr_start*/
+	{0x0345, 0x14},
+	{0x0348, 0x09},/*x_addr_end*/
+	{0x0349, 0x17},
+	{0x0346, 0x01},/*y_addr_start*/
+	{0x0347, 0x94},
+	{0x034A, 0x06},/*y_addr_end*/
+	{0x034B, 0x13},
+	{0x0380, 0x00},/*x_even_inc 1*/
+	{0x0381, 0x01},
+	{0x0382, 0x00},/*x_odd_inc 1*/
+	{0x0383, 0x01},
+	{0x0384, 0x00},/*y_even_inc 1*/
+	{0x0385, 0x01},
+	{0x0386, 0x00},/*y_odd_inc 1*/
+	{0x0387, 0x01},
+	{0x034C, 0x08},/*x_output size*/
+	{0x034D, 0x00},
+	{0x034E, 0x04},/*y_output size*/
+	{0x034F, 0x80},
+	{0x30BF, 0xAA},/*outif_enable[7], data_type[5:0](2Bh = bayer 8bit)*/
+	{0x30C0, 0x80},/*video_offset[7:4]*/
+	{0x30C8, 0x08},/*video_data_length*/
+	{0x30C9, 0x00},
+
+};
+
+struct qs_s5k4e1_i2c_reg_conf qs_s5k4e1_recommend_settings[] = {
+	{0x0100, 0x00},
+
+	{0x3030, 0x06},/*shut streaming*/
+/*Analog Setting*/
+	{0x3000, 0x05},
+	{0x3001, 0x03},
+	{0x3002, 0x08},
+	{0x3003, 0x09},
+	{0x3004, 0x2E},
+	{0x3005, 0x06},
+	{0x3006, 0x34},
+	{0x3007, 0x00},
+	{0x3008, 0x3C},
+	{0x3009, 0x3C},
+	{0x300A, 0x28},
+	{0x300B, 0x04},
+	{0x300C, 0x0A},
+	{0x300D, 0x02},
+	{0x300F, 0x82},
+	{0x3010, 0x00},
+	{0x3011, 0x4C},
+	{0x3012, 0x30},
+	{0x3013, 0xC0},
+	{0x3014, 0x00},
+	{0x3015, 0x00},
+	{0x3016, 0x2C},
+	{0x3017, 0x94},
+	{0x3018, 0x78},
+	{0x301D, 0xD4},
+	{0x3021, 0x02},
+	{0x3022, 0x24},
+	{0x3024, 0x40},
+	{0x3027, 0x08},
+	{0x3029, 0xC6},
+	{0x302B, 0x01},
+	{0x30D8, 0x3F},
+/* ADLC setting ...*/
+	{0x3070, 0x5F},
+	{0x3071, 0x00},
+	{0x3080, 0x04},
+	{0x3081, 0x38},
+
+/*MIPI setting*/
+	{0x30BD, 0x00},/*SEL_CCP[0]*/
+	{0x3084, 0x15},/*SYNC Mode*/
+	{0x30BE, 0x1A},/*M_PCLKDIV_AUTO[4], M_DIV_PCLK[3:0]*/
+	{0x30C1, 0x01},/*pack video enable [0]*/
+	{0x30EE, 0x02},/*DPHY enable [1]*/
+	{0x3111, 0x86},/*Embedded data off [5]*/
+/*For MIPI T8 T9*/
+	{0x30E3, 0x38},
+	{0x30E4, 0x40},
+	{0x3113, 0x70},
+	{0x3114, 0x80},
+	{0x3115, 0x7B},
+	{0x3116, 0xC0},
+	{0x30EE, 0x12},
+
+/*PLL setting ...*/
+	{0x0305, 0x06},
+};
+static struct qs_s5k4e1_i2c_reg_conf qs_s5k4e1_default_lenshading_settings[] = {
+
+	{0x3200, 0x00},
+	{0x3201, 0x9a},
+	{0x3202, 0x56},
+	{0x3203, 0xf },
+	{0x3204, 0xd8},
+	{0x3205, 0x94},
+	{0x3206, 0x0 },
+	{0x3207, 0x10},
+	{0x3208, 0x71},
+	{0x3209, 0x0 },
+	{0x320a, 0x9 },
+	{0x320b, 0xc1},
+	{0x320c, 0xf },
+	{0x320d, 0xf1},
+	{0x320e, 0x3d},
+	{0x320f, 0x0 },
+	{0x3210, 0xa },
+	{0x3211, 0x93},
+	{0x3212, 0xf },
+	{0x3213, 0xc9},
+	{0x3214, 0xa1},
+	{0x3215, 0x0 },
+	{0x3216, 0x10},
+	{0x3217, 0x89},
+	{0x3218, 0xf },
+	{0x3219, 0xfb},
+	{0x321a, 0xf3},
+	{0x321b, 0xf },
+	{0x321c, 0xf8},
+	{0x321d, 0xfc},
+	{0x321e, 0x0 },
+	{0x321f, 0x4 },
+	{0x3220, 0xe3},
+	{0x3221, 0xf },
+	{0x3222, 0xfe},
+	{0x3223, 0x94},
+	{0x3224, 0x0 },
+	{0x3225, 0x24},
+	{0x3226, 0x59},
+	{0x3227, 0xf },
+	{0x3228, 0xe9},
+	{0x3229, 0x68},
+	{0x322a, 0xf },
+	{0x322b, 0xfa},
+	{0x322c, 0x7f},
+	{0x322d, 0x0 },
+	{0x322e, 0x13},
+	{0x322f, 0xe1},
+	{0x3230, 0x0 },
+	{0x3231, 0x3 },
+	{0x3232, 0xbc},
+	{0x3233, 0xf },
+	{0x3234, 0xf0},
+	{0x3235, 0xa1},
+	{0x3236, 0xf },
+	{0x3237, 0xf4},
+	{0x3238, 0xc9},
+	{0x3239, 0x0 },
+	{0x323a, 0x11},
+	{0x323b, 0x4b},
+	{0x323c, 0x0 },
+	{0x323d, 0x12},
+	{0x323e, 0xc5},
+	{0x323f, 0xf },
+	{0x3240, 0xe3},
+	{0x3241, 0xb },
+	{0x3242, 0xf },
+	{0x3243, 0xf8},
+	{0x3244, 0x4f},
+	{0x3245, 0x0 },
+	{0x3246, 0x13},
+	{0x3247, 0xac},
+	{0x3248, 0x0 },
+	{0x3249, 0x0 },
+	{0x324a, 0x7c},
+	{0x324b, 0xf },
+	{0x324c, 0xfe},
+	{0x324d, 0xdd},
+	{0x324e, 0xf },
+	{0x324f, 0xf2},
+	{0x3250, 0x96},
+	{0x3251, 0x0 },
+	{0x3252, 0x8 },
+	{0x3253, 0xef},
+	{0x3254, 0x0 },
+	{0x3255, 0x6 },
+	{0x3256, 0xa4},
+	{0x3257, 0x0 },
+	{0x3258, 0x2 },
+	{0x3259, 0x4b},
+	{0x325a, 0x0 },
+	{0x325b, 0x6 },
+	{0x325c, 0x85},
+	{0x325d, 0xf },
+	{0x325e, 0xf8},
+	{0x325f, 0x6a},
+	{0x3260, 0xf },
+	{0x3261, 0xfd},
+	{0x3262, 0x70},
+	{0x3263, 0x0 },
+	{0x3264, 0xd },
+	{0x3265, 0xa9},
+	{0x3266, 0xf },
+	{0x3267, 0xfd},
+	{0x3268, 0xf8},
+	{0x3269, 0xf },
+	{0x326a, 0xec},
+	{0x326b, 0xfc},
+	{0x326c, 0x0 },
+	{0x326d, 0xa7},
+	{0x326e, 0x5 },
+	{0x326f, 0xf },
+	{0x3270, 0xd6},
+	{0x3271, 0x19},
+	{0x3272, 0x0 },
+	{0x3273, 0xa },
+	{0x3274, 0xe8},
+	{0x3275, 0x0 },
+	{0x3276, 0x17},
+	{0x3277, 0x1 },
+	{0x3278, 0xf },
+	{0x3279, 0xe7},
+	{0x327a, 0xa0},
+	{0x327b, 0x0 },
+	{0x327c, 0xb },
+	{0x327d, 0xc3},
+	{0x327e, 0xf },
+	{0x327f, 0xc0},
+	{0x3280, 0xe3},
+	{0x3281, 0x0 },
+	{0x3282, 0x15},
+	{0x3283, 0x5a},
+	{0x3284, 0xf },
+	{0x3285, 0xf9},
+	{0x3286, 0xa0},
+	{0x3287, 0xf },
+	{0x3288, 0xf4},
+	{0x3289, 0xce},
+	{0x328a, 0x0 },
+	{0x328b, 0xb },
+	{0x328c, 0x72},
+	{0x328d, 0xf },
+	{0x328e, 0xfb},
+	{0x328f, 0xb5},
+	{0x3290, 0x0 },
+	{0x3291, 0x2f},
+	{0x3292, 0xb },
+	{0x3293, 0xf },
+	{0x3294, 0xde},
+	{0x3295, 0xc0},
+	{0x3296, 0x0 },
+	{0x3297, 0x0 },
+	{0x3298, 0x58},
+	{0x3299, 0x0 },
+	{0x329a, 0x1b},
+	{0x329b, 0x5 },
+	{0x329c, 0xf },
+	{0x329d, 0xf9},
+	{0x329e, 0x23},
+	{0x329f, 0xf },
+	{0x32a0, 0xf3},
+	{0x32a1, 0x94},
+	{0x32a2, 0xf },
+	{0x32a3, 0xe7},
+	{0x32a4, 0xc2},
+	{0x32a5, 0x0 },
+	{0x32a6, 0x1d},
+	{0x32a7, 0xe5},
+	{0x32a8, 0x0 },
+	{0x32a9, 0x5 },
+	{0x32aa, 0xaf},
+	{0x32ab, 0xf },
+	{0x32ac, 0xe3},
+	{0x32ad, 0xb7},
+	{0x32ae, 0xf },
+	{0x32af, 0xf8},
+	{0x32b0, 0x34},
+	{0x32b1, 0x0 },
+	{0x32b2, 0x1c},
+	{0x32b3, 0x3d},
+	{0x32b4, 0x0 },
+	{0x32b5, 0x10},
+	{0x32b6, 0x4a},
+	{0x32b7, 0xf },
+	{0x32b8, 0xfa},
+	{0x32b9, 0x7 },
+	{0x32ba, 0xf },
+	{0x32bb, 0xff},
+	{0x32bc, 0x16},
+	{0x32bd, 0x0 },
+	{0x32be, 0x5 },
+	{0x32bf, 0x4e},
+	{0x32c0, 0x0 },
+	{0x32c1, 0xc },
+	{0x32c2, 0x1b},
+	{0x32c3, 0xf },
+	{0x32c4, 0xf1},
+	{0x32c5, 0xdb},
+	{0x32c6, 0xf },
+	{0x32c7, 0xfc},
+	{0x32c8, 0xf8},
+	{0x32c9, 0xf },
+	{0x32ca, 0xf4},
+	{0x32cb, 0xad},
+	{0x32cc, 0xf },
+	{0x32cd, 0xfb},
+	{0x32ce, 0x59},
+	{0x32cf, 0x0 },
+	{0x32d0, 0x9 },
+	{0x32d1, 0xf7},
+	{0x32d2, 0x0 },
+	{0x32d3, 0x0 },
+	{0x32d4, 0xc1},
+	{0x32d5, 0xf },
+	{0x32d6, 0xf5},
+	{0x32d7, 0x30},
+	{0x32d8, 0x0 },
+	{0x32d9, 0x83},
+	{0x32da, 0x1d},
+	{0x32db, 0xf },
+	{0x32dc, 0xe3},
+	{0x32dd, 0x3c},
+	{0x32de, 0x0 },
+	{0x32df, 0xa },
+	{0x32e0, 0x10},
+	{0x32e1, 0x0 },
+	{0x32e2, 0x7 },
+	{0x32e3, 0x65},
+	{0x32e4, 0xf },
+	{0x32e5, 0xfe},
+	{0x32e6, 0x79},
+	{0x32e7, 0xf },
+	{0x32e8, 0xfd},
+	{0x32e9, 0x57},
+	{0x32ea, 0xf },
+	{0x32eb, 0xd6},
+	{0x32ec, 0x8f},
+	{0x32ed, 0x0 },
+	{0x32ee, 0x3 },
+	{0x32ef, 0x93},
+	{0x32f0, 0x0 },
+	{0x32f1, 0x6 },
+	{0x32f2, 0xa },
+	{0x32f3, 0xf },
+	{0x32f4, 0xfa},
+	{0x32f5, 0x6c},
+	{0x32f6, 0xf },
+	{0x32f7, 0xf1},
+	{0x32f8, 0x1e},
+	{0x32f9, 0x0 },
+	{0x32fa, 0x14},
+	{0x32fb, 0xe7},
+	{0x32fc, 0x0 },
+	{0x32fd, 0x1f},
+	{0x32fe, 0x2d},
+	{0x32ff, 0x0 },
+	{0x3300, 0x7 },
+	{0x3301, 0x5e},
+	{0x3302, 0xf },
+	{0x3303, 0xe0},
+	{0x3304, 0x55},
+	{0x3305, 0x0 },
+	{0x3306, 0x20},
+	{0x3307, 0x93},
+	{0x3308, 0x0 },
+	{0x3309, 0xf },
+	{0x330a, 0x20},
+	{0x330b, 0xf },
+	{0x330c, 0xd7},
+	{0x330d, 0xf5},
+	{0x330e, 0xf },
+	{0x330f, 0xef},
+	{0x3310, 0xb8},
+	{0x3311, 0xf },
+	{0x3312, 0xf0},
+	{0x3313, 0x29},
+	{0x3314, 0x0 },
+	{0x3315, 0x27},
+	{0x3316, 0x5e},
+	{0x3317, 0xf },
+	{0x3318, 0xda},
+	{0x3319, 0x14},
+	{0x331a, 0xf },
+	{0x331b, 0xef},
+	{0x331c, 0x93},
+	{0x331d, 0x0 },
+	{0x331e, 0x2c},
+	{0x331f, 0xdc},
+	{0x3320, 0x0 },
+	{0x3321, 0xe },
+	{0x3322, 0x2d},
+	{0x3323, 0x0 },
+	{0x3324, 0x6 },
+	{0x3325, 0xcf},
+	{0x3326, 0xf },
+	{0x3327, 0xfb},
+	{0x3328, 0x26},
+	{0x3329, 0x0 },
+	{0x332a, 0x3 },
+	{0x332b, 0x5 },
+	{0x332c, 0x0 },
+	{0x332d, 0x6 },
+	{0x332e, 0xa6},
+	{0x332f, 0xf },
+	{0x3330, 0xf7},
+	{0x3331, 0x7b},
+	{0x3332, 0xf },
+	{0x3333, 0xf9},
+	{0x3334, 0xb },
+	{0x3335, 0x0 },
+	{0x3336, 0x7 },
+	{0x3337, 0x5a},
+	{0x3338, 0xf },
+	{0x3339, 0xe4},
+	{0x333a, 0x7a},
+	{0x333b, 0x0 },
+	{0x333c, 0x1b},
+	{0x333d, 0xb0},
+	{0x333e, 0x0 },
+	{0x333f, 0x2 },
+	{0x3340, 0xa7},
+	{0x3341, 0xf },
+	{0x3342, 0xe9},
+	{0x3343, 0x3a},
+	{0x3344, 0x0 },
+	{0x3345, 0x95},
+	{0x3346, 0x42},
+	{0x3347, 0xf },
+	{0x3348, 0xda},
+	{0x3349, 0x45},
+	{0x334a, 0x0 },
+	{0x334b, 0x16},
+	{0x334c, 0x7a},
+	{0x334d, 0xf },
+	{0x334e, 0xfb},
+	{0x334f, 0x32},
+	{0x3350, 0x0 },
+	{0x3351, 0x6 },
+	{0x3352, 0x35},
+	{0x3353, 0xf },
+	{0x3354, 0xfc},
+	{0x3355, 0x8f},
+	{0x3356, 0xf },
+	{0x3357, 0xca},
+	{0x3358, 0xd5},
+	{0x3359, 0x0 },
+	{0x335a, 0x11},
+	{0x335b, 0x59},
+	{0x335c, 0xf },
+	{0x335d, 0xfa},
+	{0x335e, 0xaa},
+	{0x335f, 0xf },
+	{0x3360, 0xfe},
+	{0x3361, 0x84},
+	{0x3362, 0xf },
+	{0x3363, 0xf6},
+	{0x3364, 0x8f},
+	{0x3365, 0x0 },
+	{0x3366, 0xb },
+	{0x3367, 0x70},
+	{0x3368, 0x0 },
+	{0x3369, 0x25},
+	{0x336a, 0x83},
+	{0x336b, 0xf },
+	{0x336c, 0xe7},
+	{0x336d, 0x27},
+	{0x336e, 0xf },
+	{0x336f, 0xf1},
+	{0x3370, 0x72},
+	{0x3371, 0x0 },
+	{0x3372, 0x21},
+	{0x3373, 0x6d},
+	{0x3374, 0x0 },
+	{0x3375, 0x2 },
+	{0x3376, 0xc3},
+	{0x3377, 0xf },
+	{0x3378, 0xe8},
+	{0x3379, 0x5a},
+	{0x337a, 0xf },
+	{0x337b, 0xf2},
+	{0x337c, 0x73},
+	{0x337d, 0x0 },
+	{0x337e, 0x19},
+	{0x337f, 0xa5},
+	{0x3380, 0x0 },
+	{0x3381, 0x1a},
+	{0x3382, 0x81},
+	{0x3383, 0xf },
+	{0x3384, 0xd0},
+	{0x3385, 0x31},
+	{0x3386, 0xf },
+	{0x3387, 0xfb},
+	{0x3388, 0xff},
+	{0x3389, 0x0 },
+	{0x338a, 0x1e},
+	{0x338b, 0xe1},
+	{0x338c, 0x0 },
+	{0x338d, 0x5 },
+	{0x338e, 0xe1},
+	{0x338f, 0xf },
+	{0x3390, 0xee},
+	{0x3391, 0xe2},
+	{0x3392, 0xf },
+	{0x3393, 0xf6},
+	{0x3394, 0xcf},
+	{0x3395, 0x0 },
+	{0x3396, 0x13},
+	{0x3397, 0x8f},
+	{0x3398, 0x0 },
+	{0x3399, 0x3 },
+	{0x339a, 0x61},
+	{0x339b, 0xf },
+	{0x339c, 0xf8},
+	{0x339d, 0xf7},
+	{0x339e, 0x0 },
+	{0x339f, 0x0 },
+	{0x33a0, 0xb5},
+	{0x33a1, 0x0 },
+	{0x33a2, 0x5 },
+	{0x33a3, 0x78},
+	{0x33a4, 0xf },
+	{0x33a5, 0xf4},
+	{0x33a6, 0x5 },
+	{0x33a7, 0x0 },
+	{0x33a8, 0xc },
+	{0x33a9, 0xe },
+	{0x33aa, 0x0 },
+	{0x33ab, 0x3 },
+	{0x33ac, 0x53},
+	{0x33ad, 0xf },
+	{0x33ae, 0xec},
+	{0x33af, 0xbd},
+};
+
+const struct
+qs_s5k4e1_i2c_reg_conf qs_s5k4e1_lenshading_settings[4][LENS_SHADE_TABLE] = {
+	{/*2D Preview*/
+		{0x3097, 0x52},/*sh4ch_blk_width = 82*/
+		{0x3098, 0x3e},/*sh4ch_blk_height = 62*/
+		{0x3099, 0x03},/*sh4ch_step_x msb (sh4ch_step_x = 799)*/
+		{0x309a, 0x1f},/*sh4ch_step_x lsb*/
+		{0x309b, 0x04},/*sh4ch_step_y msb (sh4ch_step_y = 1057)*/
+		{0x309c, 0x21},/*sh4ch_step_y lsb*/
+		{0x309d, 0x00},/*sh4ch_start_blk_cnt_x = 0*/
+		{0x309e, 0x00},/*sh4ch_start_int_cnt_x = 0*/
+		{0x309f, 0x00},/*sh4ch_start_frac_cnt_x msb (0)*/
+		{0x30a0, 0x00},/*sh4ch_start_frac_cnt_x lsb*/
+		{0x30a1, 0x00},/*sh4ch_start_blk_cnt_y = 0*/
+		{0x30a2, 0x00},/*sh4ch_start_int_cnt_y = 0*/
+		{0x30a3, 0x00},/*sh4ch_start_frac_cnt_y msb (0)*/
+		{0x30a4, 0x00},/*sh4ch_start_frac_cnt_y lsb*/
+		{0x30a5, 0x01},
+		{0x30a6, 0x00},/*gs_pedestal	= 64*/
+	},
+	{/*2D Snapshot*/
+		{0x3097, 0x52},/*sh4ch_blk_width = 82*/
+		{0x3098, 0x7b},/*sh4ch_blk_height = 123*/
+		{0x3099, 0x03},/*sh4ch_step_x msb (sh4ch_step_x = 799)*/
+		{0x309a, 0x1f},/*sh4ch_step_x lsb*/
+		{0x309b, 0x02},/*sh4ch_step_y msb (sh4ch_step_y = 533)*/
+		{0x309c, 0x15},/*sh4ch_step_y lsb*/
+		{0x309d, 0x00},/*sh4ch_start_blk_cnt_x = 0*/
+		{0x309e, 0x00},/*sh4ch_start_int_cnt_x = 0*/
+		{0x309f, 0x00},/*sh4ch_start_frac_cnt_x msb (0)*/
+		{0x30a0, 0x00},/*sh4ch_start_frac_cnt_x lsb*/
+		{0x30a1, 0x00},/*sh4ch_start_blk_cnt_y = 0*/
+		{0x30a2, 0x00},/*sh4ch_start_int_cnt_y = 0*/
+		{0x30a3, 0x00},/*sh4ch_start_frac_cnt_y msb (0)*/
+		{0x30a4, 0x00},/*sh4ch_start_frac_cnt_y lsb*/
+		{0x30a5, 0x01},
+		{0x30a6, 0x00},/*gs_pedestal	= 64*/
+	},
+
+	{/*3D Preview*/
+		{0x3097, 0x52},/*sh4ch_blk_width = 82*/
+		{0x3098, 0x7b},/*sh4ch_blk_height = 123*/
+		{0x3099, 0x03},/*sh4ch_step_x msb (sh4ch_step_x = 799)*/
+		{0x309a, 0x1f},/*sh4ch_step_x lsb*/
+		{0x309b, 0x02},/*sh4ch_step_y msb (sh4ch_step_y = 533)*/
+		{0x309c, 0x15},/*sh4ch_step_y lsb*/
+		{0x309d, 0x3a},/*sh4ch_start_blk_cnt_x = 58*/
+		{0x309e, 0x01},/*sh4ch_start_int_cnt_x = 1*/
+		{0x309f, 0xb5},/*sh4ch_start_frac_cnt_x msb (46342)*/
+		{0x30a0, 0x06},/*sh4ch_start_frac_cnt_x lsb*/
+		{0x30a1, 0x23},/*sh4ch_start_blk_cnt_y = 35*/
+		{0x30a2, 0x03},/*sh4ch_start_int_cnt_y = 3*/
+		{0x30a3, 0x48},/*sh4ch_start_frac_cnt_y msb (46342)*/
+		{0x30a4, 0xdf},/*sh4ch_start_frac_cnt_y lsb*/
+		{0x30a5, 0x01},
+		{0x30a6, 0x00},/*gs_pedestal	= 64*/
+	},
+
+	{/*3D Snapshot*/
+		{0x3097, 0x52},/*sh4ch_blk_width = 82*/
+		{0x3098, 0x7b},/*sh4ch_blk_height = 123*/
+		{0x3099, 0x03},/*sh4ch_step_x msb (sh4ch_step_x = 799)*/
+		{0x309a, 0x1f},/*sh4ch_step_x lsb*/
+		{0x309b, 0x02},/*sh4ch_step_y msb (sh4ch_step_y = 533)*/
+		{0x309c, 0x15},/*sh4ch_step_y lsb*/
+		{0x309d, 0x38},/*sh4ch_start_blk_cnt_x = 56*/
+		{0x309e, 0x01},/*sh4ch_start_int_cnt_x = 1*/
+		{0x309f, 0xae},/*sh4ch_start_frac_cnt_x msb (44744)*/
+		{0x30a0, 0xc8},/*sh4ch_start_frac_cnt_x lsb*/
+		{0x30a1, 0x23},/*sh4ch_start_blk_cnt_y = 35*/
+		{0x30a2, 0x03},/*sh4ch_start_int_cnt_y = 3*/
+		{0x30a3, 0x48},/*sh4ch_start_frac_cnt_y msb (44744)*/
+		{0x30a4, 0xdf},/*sh4ch_start_frac_cnt_y lsb*/
+		{0x30a5, 0x01},
+		{0x30a6, 0x00},/*gs_pedestal	= 64*/
+	},
+
+};
+
+struct qs_s5k4e1_i2c_conf_array qs_s5k4e1_confs[] = {
+	{&qs_s5k4e1_prev_settings_2d[0], \
+		ARRAY_SIZE(qs_s5k4e1_prev_settings_2d)},
+	{&qs_s5k4e1_snap_settings_2d[0], \
+		ARRAY_SIZE(qs_s5k4e1_snap_settings_2d)},
+	{&qs_s5k4e1_prev_settings_3d[0], \
+		ARRAY_SIZE(qs_s5k4e1_prev_settings_3d)},
+	{&qs_s5k4e1_snap_settings_3d[0], \
+		ARRAY_SIZE(qs_s5k4e1_snap_settings_3d)},
+};
+struct qs_s5k4e1_reg qs_s5k4e1_regs = {
+	.rec_settings = &qs_s5k4e1_recommend_settings[0],
+	.rec_size = ARRAY_SIZE(qs_s5k4e1_recommend_settings),
+	.reg_lens = &qs_s5k4e1_lenshading_settings[0],
+	.reg_lens_size = ARRAY_SIZE(qs_s5k4e1_lenshading_settings[0]),
+	.reg_default_lens = &qs_s5k4e1_default_lenshading_settings[0],
+	.reg_default_lens_size =
+		ARRAY_SIZE(qs_s5k4e1_default_lenshading_settings),
+	.conf_array = &qs_s5k4e1_confs[0],
+};
diff --git a/drivers/media/platform/msm/camera_v1/s5k3e2fx.c b/drivers/media/platform/msm/camera_v1/s5k3e2fx.c
new file mode 100644
index 0000000..f7591d9
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/s5k3e2fx.c
@@ -0,0 +1,1387 @@
+/* Copyright (c) 2009, 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/slab.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <media/msm_camera.h>
+#include <mach/gpio.h>
+#include <mach/camera.h>
+#include "s5k3e2fx.h"
+
+#define S5K3E2FX_REG_MODEL_ID   0x0000
+#define S5K3E2FX_MODEL_ID       0x3E2F
+
+/* PLL Registers */
+#define REG_PRE_PLL_CLK_DIV           0x0305
+#define REG_PLL_MULTIPLIER_MSB        0x0306
+#define REG_PLL_MULTIPLIER_LSB        0x0307
+#define REG_VT_PIX_CLK_DIV            0x0301
+#define REG_VT_SYS_CLK_DIV            0x0303
+#define REG_OP_PIX_CLK_DIV            0x0309
+#define REG_OP_SYS_CLK_DIV            0x030B
+
+/* Data Format Registers */
+#define REG_CCP_DATA_FORMAT_MSB       0x0112
+#define REG_CCP_DATA_FORMAT_LSB       0x0113
+
+/* Output Size */
+#define REG_X_OUTPUT_SIZE_MSB         0x034C
+#define REG_X_OUTPUT_SIZE_LSB         0x034D
+#define REG_Y_OUTPUT_SIZE_MSB         0x034E
+#define REG_Y_OUTPUT_SIZE_LSB         0x034F
+
+/* Binning */
+#define REG_X_EVEN_INC                0x0381
+#define REG_X_ODD_INC                 0x0383
+#define REG_Y_EVEN_INC                0x0385
+#define REG_Y_ODD_INC                 0x0387
+/*Reserved register */
+#define REG_BINNING_ENABLE            0x3014
+
+/* Frame Fotmat */
+#define REG_FRAME_LENGTH_LINES_MSB    0x0340
+#define REG_FRAME_LENGTH_LINES_LSB    0x0341
+#define REG_LINE_LENGTH_PCK_MSB       0x0342
+#define REG_LINE_LENGTH_PCK_LSB       0x0343
+
+/* MSR setting */
+/* Reserved registers */
+#define REG_SHADE_CLK_ENABLE          0x30AC
+#define REG_SEL_CCP                   0x30C4
+#define REG_VPIX                      0x3024
+#define REG_CLAMP_ON                  0x3015
+#define REG_OFFSET                    0x307E
+
+/* CDS timing settings */
+/* Reserved registers */
+#define REG_LD_START                  0x3000
+#define REG_LD_END                    0x3001
+#define REG_SL_START                  0x3002
+#define REG_SL_END                    0x3003
+#define REG_RX_START                  0x3004
+#define REG_S1_START                  0x3005
+#define REG_S1_END                    0x3006
+#define REG_S1S_START                 0x3007
+#define REG_S1S_END                   0x3008
+#define REG_S3_START                  0x3009
+#define REG_S3_END                    0x300A
+#define REG_CMP_EN_START              0x300B
+#define REG_CLP_SL_START              0x300C
+#define REG_CLP_SL_END                0x300D
+#define REG_OFF_START                 0x300E
+#define REG_RMP_EN_START              0x300F
+#define REG_TX_START                  0x3010
+#define REG_TX_END                    0x3011
+#define REG_STX_WIDTH                 0x3012
+#define REG_TYPE1_AF_ENABLE           0x3130
+#define DRIVER_ENABLED                0x0001
+#define AUTO_START_ENABLED            0x0010
+#define REG_NEW_POSITION              0x3131
+#define REG_3152_RESERVED             0x3152
+#define REG_315A_RESERVED             0x315A
+#define REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB 0x0204
+#define REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB 0x0205
+#define REG_FINE_INTEGRATION_TIME         0x0200
+#define REG_COARSE_INTEGRATION_TIME       0x0202
+#define REG_COARSE_INTEGRATION_TIME_LSB   0x0203
+
+/* Mode select register */
+#define S5K3E2FX_REG_MODE_SELECT      0x0100
+#define S5K3E2FX_MODE_SELECT_STREAM     0x01   /* start streaming */
+#define S5K3E2FX_MODE_SELECT_SW_STANDBY 0x00   /* software standby */
+#define S5K3E2FX_REG_SOFTWARE_RESET   0x0103
+#define S5K3E2FX_SOFTWARE_RESET         0x01
+#define REG_TEST_PATTERN_MODE         0x0601
+
+struct reg_struct {
+  uint8_t pre_pll_clk_div;               /* 0x0305 */
+  uint8_t pll_multiplier_msb;            /* 0x0306 */
+  uint8_t pll_multiplier_lsb;            /* 0x0307 */
+  uint8_t vt_pix_clk_div;                /* 0x0301 */
+  uint8_t vt_sys_clk_div;                /* 0x0303 */
+  uint8_t op_pix_clk_div;                /* 0x0309 */
+  uint8_t op_sys_clk_div;                /* 0x030B */
+  uint8_t ccp_data_format_msb;           /* 0x0112 */
+  uint8_t ccp_data_format_lsb;           /* 0x0113 */
+  uint8_t x_output_size_msb;             /* 0x034C */
+  uint8_t x_output_size_lsb;             /* 0x034D */
+  uint8_t y_output_size_msb;             /* 0x034E */
+  uint8_t y_output_size_lsb;             /* 0x034F */
+  uint8_t x_even_inc;                    /* 0x0381 */
+  uint8_t x_odd_inc;                     /* 0x0383 */
+  uint8_t y_even_inc;                    /* 0x0385 */
+  uint8_t y_odd_inc;                     /* 0x0387 */
+  uint8_t binning_enable;                /* 0x3014 */
+  uint8_t frame_length_lines_msb;        /* 0x0340 */
+  uint8_t frame_length_lines_lsb;        /* 0x0341 */
+  uint8_t line_length_pck_msb;           /* 0x0342 */
+  uint8_t line_length_pck_lsb;           /* 0x0343 */
+  uint8_t shade_clk_enable ;             /* 0x30AC */
+  uint8_t sel_ccp;                       /* 0x30C4 */
+  uint8_t vpix;                          /* 0x3024 */
+  uint8_t clamp_on;                      /* 0x3015 */
+  uint8_t offset;                        /* 0x307E */
+  uint8_t ld_start;                      /* 0x3000 */
+  uint8_t ld_end;                        /* 0x3001 */
+  uint8_t sl_start;                      /* 0x3002 */
+  uint8_t sl_end;                        /* 0x3003 */
+  uint8_t rx_start;                      /* 0x3004 */
+  uint8_t s1_start;                      /* 0x3005 */
+  uint8_t s1_end;                        /* 0x3006 */
+  uint8_t s1s_start;                     /* 0x3007 */
+  uint8_t s1s_end;                       /* 0x3008 */
+  uint8_t s3_start;                      /* 0x3009 */
+  uint8_t s3_end;                        /* 0x300A */
+  uint8_t cmp_en_start;                  /* 0x300B */
+  uint8_t clp_sl_start;                  /* 0x300C */
+  uint8_t clp_sl_end;                    /* 0x300D */
+  uint8_t off_start;                     /* 0x300E */
+  uint8_t rmp_en_start;                  /* 0x300F */
+  uint8_t tx_start;                      /* 0x3010 */
+  uint8_t tx_end;                        /* 0x3011 */
+  uint8_t stx_width;                     /* 0x3012 */
+  uint8_t reg_3152_reserved;             /* 0x3152 */
+  uint8_t reg_315A_reserved;             /* 0x315A */
+  uint8_t analogue_gain_code_global_msb; /* 0x0204 */
+  uint8_t analogue_gain_code_global_lsb; /* 0x0205 */
+  uint8_t fine_integration_time;         /* 0x0200 */
+  uint8_t coarse_integration_time;       /* 0x0202 */
+  uint32_t  size_h;
+  uint32_t  blk_l;
+  uint32_t  size_w;
+  uint32_t  blk_p;
+};
+
+struct reg_struct s5k3e2fx_reg_pat[2] =  {
+  {	/* Preview */
+    0x06,  /* pre_pll_clk_div       REG=0x0305 */
+    0x00,  /* pll_multiplier_msb    REG=0x0306 */
+    0x88,  /* pll_multiplier_lsb    REG=0x0307 */
+    0x0a,  /* vt_pix_clk_div        REG=0x0301 */
+    0x01,  /* vt_sys_clk_div        REG=0x0303 */
+    0x0a,  /* op_pix_clk_div        REG=0x0309 */
+    0x01,  /* op_sys_clk_div        REG=0x030B */
+    0x0a,  /* ccp_data_format_msb   REG=0x0112 */
+    0x0a,  /* ccp_data_format_lsb   REG=0x0113 */
+    0x05,  /* x_output_size_msb     REG=0x034C */
+    0x10,  /* x_output_size_lsb     REG=0x034D */
+    0x03,  /* y_output_size_msb     REG=0x034E */
+    0xcc,  /* y_output_size_lsb     REG=0x034F */
+
+    /* enable binning for preview */
+    0x01,  /* x_even_inc             REG=0x0381 */
+    0x01,  /* x_odd_inc              REG=0x0383 */
+    0x01,  /* y_even_inc             REG=0x0385 */
+    0x03,  /* y_odd_inc              REG=0x0387 */
+    0x06,  /* binning_enable         REG=0x3014 */
+
+    0x03,  /* frame_length_lines_msb        REG=0x0340 */
+    0xde,  /* frame_length_lines_lsb        REG=0x0341 */
+    0x0a,  /* line_length_pck_msb           REG=0x0342 */
+    0xac,  /* line_length_pck_lsb           REG=0x0343 */
+    0x81,  /* shade_clk_enable              REG=0x30AC */
+    0x01,  /* sel_ccp                       REG=0x30C4 */
+    0x04,  /* vpix                          REG=0x3024 */
+    0x00,  /* clamp_on                      REG=0x3015 */
+    0x02,  /* offset                        REG=0x307E */
+    0x03,  /* ld_start                      REG=0x3000 */
+    0x9c,  /* ld_end                        REG=0x3001 */
+    0x02,  /* sl_start                      REG=0x3002 */
+    0x9e,  /* sl_end                        REG=0x3003 */
+    0x05,  /* rx_start                      REG=0x3004 */
+    0x0f,  /* s1_start                      REG=0x3005 */
+    0x24,  /* s1_end                        REG=0x3006 */
+    0x7c,  /* s1s_start                     REG=0x3007 */
+    0x9a,  /* s1s_end                       REG=0x3008 */
+    0x10,  /* s3_start                      REG=0x3009 */
+    0x14,  /* s3_end                        REG=0x300A */
+    0x10,  /* cmp_en_start                  REG=0x300B */
+    0x04,  /* clp_sl_start                  REG=0x300C */
+    0x26,  /* clp_sl_end                    REG=0x300D */
+    0x02,  /* off_start                     REG=0x300E */
+    0x0e,  /* rmp_en_start                  REG=0x300F */
+    0x30,  /* tx_start                      REG=0x3010 */
+    0x4e,  /* tx_end                        REG=0x3011 */
+    0x1E,  /* stx_width                     REG=0x3012 */
+    0x08,  /* reg_3152_reserved             REG=0x3152 */
+    0x10,  /* reg_315A_reserved             REG=0x315A */
+    0x00,  /* analogue_gain_code_global_msb REG=0x0204 */
+    0x80,  /* analogue_gain_code_global_lsb REG=0x0205 */
+    0x02,  /* fine_integration_time         REG=0x0200 */
+    0x03,  /* coarse_integration_time       REG=0x0202 */
+		972,
+		18,
+		1296,
+		1436
+  },
+  { /* Snapshot */
+    0x06,  /* pre_pll_clk_div               REG=0x0305 */
+    0x00,  /* pll_multiplier_msb            REG=0x0306 */
+    0x88,  /* pll_multiplier_lsb            REG=0x0307 */
+    0x0a,  /* vt_pix_clk_div                REG=0x0301 */
+    0x01,  /* vt_sys_clk_div                REG=0x0303 */
+    0x0a,  /* op_pix_clk_div                REG=0x0309 */
+    0x01,  /* op_sys_clk_div                REG=0x030B */
+    0x0a,  /* ccp_data_format_msb           REG=0x0112 */
+    0x0a,  /* ccp_data_format_lsb           REG=0x0113 */
+    0x0a,  /* x_output_size_msb             REG=0x034C */
+    0x30,  /* x_output_size_lsb             REG=0x034D */
+    0x07,  /* y_output_size_msb             REG=0x034E */
+    0xa8,  /* y_output_size_lsb             REG=0x034F */
+
+    /* disable binning for snapshot */
+    0x01,  /* x_even_inc                    REG=0x0381 */
+    0x01,  /* x_odd_inc                     REG=0x0383 */
+    0x01,  /* y_even_inc                    REG=0x0385 */
+    0x01,  /* y_odd_inc                     REG=0x0387 */
+    0x00,  /* binning_enable                REG=0x3014 */
+
+    0x07,  /* frame_length_lines_msb        REG=0x0340 */
+    0xb6,  /* frame_length_lines_lsb        REG=0x0341 */
+    0x0a,  /* line_length_pck_msb           REG=0x0342 */
+    0xac,  /* line_length_pck_lsb           REG=0x0343 */
+    0x81,  /* shade_clk_enable              REG=0x30AC */
+    0x01,  /* sel_ccp                       REG=0x30C4 */
+    0x04,  /* vpix                          REG=0x3024 */
+    0x00,  /* clamp_on                      REG=0x3015 */
+    0x02,  /* offset                        REG=0x307E */
+    0x03,  /* ld_start                      REG=0x3000 */
+    0x9c,  /* ld_end                        REG=0x3001 */
+    0x02,  /* sl_start                      REG=0x3002 */
+    0x9e,  /* sl_end                        REG=0x3003 */
+    0x05,  /* rx_start                      REG=0x3004 */
+    0x0f,  /* s1_start                      REG=0x3005 */
+    0x24,  /* s1_end                        REG=0x3006 */
+    0x7c,  /* s1s_start                     REG=0x3007 */
+    0x9a,  /* s1s_end                       REG=0x3008 */
+    0x10,  /* s3_start                      REG=0x3009 */
+    0x14,  /* s3_end                        REG=0x300A */
+    0x10,  /* cmp_en_start                  REG=0x300B */
+    0x04,  /* clp_sl_start                  REG=0x300C */
+    0x26,  /* clp_sl_end                    REG=0x300D */
+    0x02,  /* off_start                     REG=0x300E */
+    0x0e,  /* rmp_en_start                  REG=0x300F */
+    0x30,  /* tx_start                      REG=0x3010 */
+    0x4e,  /* tx_end                        REG=0x3011 */
+    0x1E,  /* stx_width                     REG=0x3012 */
+    0x08,  /* reg_3152_reserved             REG=0x3152 */
+    0x10,  /* reg_315A_reserved             REG=0x315A */
+    0x00,  /* analogue_gain_code_global_msb REG=0x0204 */
+    0x80,  /* analogue_gain_code_global_lsb REG=0x0205 */
+    0x02,  /* fine_integration_time         REG=0x0200 */
+    0x03,  /* coarse_integration_time       REG=0x0202 */
+		1960,
+		14,
+		2608,
+		124
+	}
+};
+
+struct s5k3e2fx_work {
+	struct work_struct work;
+};
+static struct s5k3e2fx_work *s5k3e2fx_sensorw;
+static struct i2c_client *s5k3e2fx_client;
+
+struct s5k3e2fx_ctrl {
+	const struct msm_camera_sensor_info *sensordata;
+
+	int sensormode;
+	uint32_t fps_divider; /* init to 1 * 0x00000400 */
+	uint32_t pict_fps_divider; /* init to 1 * 0x00000400 */
+
+	uint16_t curr_lens_pos;
+	uint16_t init_curr_lens_pos;
+	uint16_t my_reg_gain;
+	uint32_t my_reg_line_count;
+
+	enum msm_s_resolution prev_res;
+	enum msm_s_resolution pict_res;
+	enum msm_s_resolution curr_res;
+	enum msm_s_test_mode  set_test;
+};
+
+struct s5k3e2fx_i2c_reg_conf {
+	unsigned short waddr;
+	unsigned char  bdata;
+};
+
+static struct s5k3e2fx_ctrl *s5k3e2fx_ctrl;
+static DECLARE_WAIT_QUEUE_HEAD(s5k3e2fx_wait_queue);
+DEFINE_MUTEX(s5k3e2fx_mutex);
+
+static int s5k3e2fx_i2c_rxdata(unsigned short saddr, unsigned char *rxdata,
+	int length)
+{
+	struct i2c_msg msgs[] = {
+		{
+			.addr   = saddr,
+			.flags = 0,
+			.len   = 2,
+			.buf   = rxdata,
+		},
+		{
+			.addr   = saddr,
+			.flags = I2C_M_RD,
+			.len   = length,
+			.buf   = rxdata,
+		},
+	};
+
+	if (i2c_transfer(s5k3e2fx_client->adapter, msgs, 2) < 0) {
+		CDBG("s5k3e2fx_i2c_rxdata failed!\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t s5k3e2fx_i2c_txdata(unsigned short saddr,
+	unsigned char *txdata, int length)
+{
+	struct i2c_msg msg[] = {
+		{
+		.addr  = saddr,
+		.flags = 0,
+		.len = length,
+		.buf = txdata,
+		},
+	};
+
+	if (i2c_transfer(s5k3e2fx_client->adapter, msg, 1) < 0) {
+		CDBG("s5k3e2fx_i2c_txdata failed\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t s5k3e2fx_i2c_write_b(unsigned short saddr, unsigned short waddr,
+	unsigned char bdata)
+{
+	int32_t rc = -EIO;
+	unsigned char buf[4];
+
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00)>>8;
+	buf[1] = (waddr & 0x00FF);
+	buf[2] = bdata;
+
+	rc = s5k3e2fx_i2c_txdata(saddr, buf, 3);
+
+	if (rc < 0)
+		CDBG("i2c_write_w failed, addr = 0x%x, val = 0x%x!\n",
+			waddr, bdata);
+
+	return rc;
+}
+
+static int32_t s5k3e2fx_i2c_write_table(
+	struct s5k3e2fx_i2c_reg_conf *reg_cfg_tbl, int num)
+{
+	int i;
+	int32_t rc = -EIO;
+	for (i = 0; i < num; i++) {
+		rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
+			reg_cfg_tbl->waddr, reg_cfg_tbl->bdata);
+		if (rc < 0)
+			break;
+		reg_cfg_tbl++;
+	}
+
+	return rc;
+}
+
+static int32_t s5k3e2fx_i2c_read_w(unsigned short saddr, unsigned short raddr,
+	unsigned short *rdata)
+{
+	int32_t rc = 0;
+	unsigned char buf[4];
+
+	if (!rdata)
+		return -EIO;
+
+	memset(buf, 0, sizeof(buf));
+
+	buf[0] = (raddr & 0xFF00)>>8;
+	buf[1] = (raddr & 0x00FF);
+
+	rc = s5k3e2fx_i2c_rxdata(saddr, buf, 2);
+	if (rc < 0)
+		return rc;
+
+	*rdata = buf[0] << 8 | buf[1];
+
+	if (rc < 0)
+		CDBG("s5k3e2fx_i2c_read failed!\n");
+
+	return rc;
+}
+
+static int s5k3e2fx_probe_init_done(const struct msm_camera_sensor_info *data)
+{
+	gpio_direction_output(data->sensor_reset, 0);
+	gpio_free(data->sensor_reset);
+	return 0;
+}
+
+static int s5k3e2fx_probe_init_sensor(const struct msm_camera_sensor_info *data)
+{
+	int32_t  rc;
+	uint16_t chipid = 0;
+
+	rc = gpio_request(data->sensor_reset, "s5k3e2fx");
+	if (!rc)
+		gpio_direction_output(data->sensor_reset, 1);
+	else
+		goto init_probe_done;
+
+	mdelay(20);
+
+	CDBG("s5k3e2fx_sensor_init(): reseting sensor.\n");
+
+	rc = s5k3e2fx_i2c_read_w(s5k3e2fx_client->addr,
+		S5K3E2FX_REG_MODEL_ID, &chipid);
+	if (rc < 0)
+		goto init_probe_fail;
+
+	if (chipid != S5K3E2FX_MODEL_ID) {
+		CDBG("S5K3E2FX wrong model_id = 0x%x\n", chipid);
+		rc = -ENODEV;
+		goto init_probe_fail;
+	}
+
+	goto init_probe_done;
+
+init_probe_fail:
+	s5k3e2fx_probe_init_done(data);
+init_probe_done:
+	return rc;
+}
+
+static int s5k3e2fx_init_client(struct i2c_client *client)
+{
+	/* Initialize the MSM_CAMI2C Chip */
+	init_waitqueue_head(&s5k3e2fx_wait_queue);
+	return 0;
+}
+
+static const struct i2c_device_id s5k3e2fx_i2c_id[] = {
+	{ "s5k3e2fx", 0},
+	{ }
+};
+
+static int s5k3e2fx_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+	CDBG("s5k3e2fx_probe called!\n");
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		CDBG("i2c_check_functionality failed\n");
+		goto probe_failure;
+	}
+
+	s5k3e2fx_sensorw = kzalloc(sizeof(struct s5k3e2fx_work), GFP_KERNEL);
+	if (!s5k3e2fx_sensorw) {
+		CDBG("kzalloc failed.\n");
+		rc = -ENOMEM;
+		goto probe_failure;
+	}
+
+	i2c_set_clientdata(client, s5k3e2fx_sensorw);
+	s5k3e2fx_init_client(client);
+	s5k3e2fx_client = client;
+
+	mdelay(50);
+
+	CDBG("s5k3e2fx_probe successed! rc = %d\n", rc);
+	return 0;
+
+probe_failure:
+	CDBG("s5k3e2fx_probe failed! rc = %d\n", rc);
+	return rc;
+}
+
+static struct i2c_driver s5k3e2fx_i2c_driver = {
+	.id_table = s5k3e2fx_i2c_id,
+	.probe  = s5k3e2fx_i2c_probe,
+	.remove = __exit_p(s5k3e2fx_i2c_remove),
+	.driver = {
+		.name = "s5k3e2fx",
+	},
+};
+
+static int32_t s5k3e2fx_test(enum msm_s_test_mode mo)
+{
+	int32_t rc = 0;
+
+	if (mo == S_TEST_OFF)
+		rc = 0;
+	else
+		rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
+			REG_TEST_PATTERN_MODE, (uint16_t)mo);
+
+	return rc;
+}
+
+static int32_t s5k3e2fx_setting(enum msm_s_reg_update rupdate,
+	enum msm_s_setting rt)
+{
+	int32_t rc = 0;
+  uint16_t num_lperf;
+
+	switch (rupdate) {
+	case S_UPDATE_PERIODIC:
+	if (rt == S_RES_PREVIEW || rt == S_RES_CAPTURE) {
+
+		struct s5k3e2fx_i2c_reg_conf tbl_1[] = {
+			{REG_CCP_DATA_FORMAT_MSB,
+				s5k3e2fx_reg_pat[rt].ccp_data_format_msb},
+			{REG_CCP_DATA_FORMAT_LSB,
+				s5k3e2fx_reg_pat[rt].ccp_data_format_lsb},
+			{REG_X_OUTPUT_SIZE_MSB,
+				s5k3e2fx_reg_pat[rt].x_output_size_msb},
+			{REG_X_OUTPUT_SIZE_LSB,
+				s5k3e2fx_reg_pat[rt].x_output_size_lsb},
+			{REG_Y_OUTPUT_SIZE_MSB,
+				s5k3e2fx_reg_pat[rt].y_output_size_msb},
+			{REG_Y_OUTPUT_SIZE_LSB,
+				s5k3e2fx_reg_pat[rt].y_output_size_lsb},
+			{REG_X_EVEN_INC,
+				s5k3e2fx_reg_pat[rt].x_even_inc},
+			{REG_X_ODD_INC,
+				s5k3e2fx_reg_pat[rt].x_odd_inc},
+			{REG_Y_EVEN_INC,
+				s5k3e2fx_reg_pat[rt].y_even_inc},
+			{REG_Y_ODD_INC,
+				s5k3e2fx_reg_pat[rt].y_odd_inc},
+			{REG_BINNING_ENABLE,
+				s5k3e2fx_reg_pat[rt].binning_enable},
+		};
+
+		struct s5k3e2fx_i2c_reg_conf tbl_2[] = {
+			{REG_FRAME_LENGTH_LINES_MSB, 0},
+			{REG_FRAME_LENGTH_LINES_LSB, 0},
+			{REG_LINE_LENGTH_PCK_MSB,
+				s5k3e2fx_reg_pat[rt].line_length_pck_msb},
+			{REG_LINE_LENGTH_PCK_LSB,
+				s5k3e2fx_reg_pat[rt].line_length_pck_lsb},
+			{REG_SHADE_CLK_ENABLE,
+				s5k3e2fx_reg_pat[rt].shade_clk_enable},
+			{REG_SEL_CCP, s5k3e2fx_reg_pat[rt].sel_ccp},
+			{REG_VPIX, s5k3e2fx_reg_pat[rt].vpix},
+			{REG_CLAMP_ON, s5k3e2fx_reg_pat[rt].clamp_on},
+			{REG_OFFSET, s5k3e2fx_reg_pat[rt].offset},
+			{REG_LD_START, s5k3e2fx_reg_pat[rt].ld_start},
+			{REG_LD_END, s5k3e2fx_reg_pat[rt].ld_end},
+			{REG_SL_START, s5k3e2fx_reg_pat[rt].sl_start},
+			{REG_SL_END, s5k3e2fx_reg_pat[rt].sl_end},
+			{REG_RX_START, s5k3e2fx_reg_pat[rt].rx_start},
+			{REG_S1_START, s5k3e2fx_reg_pat[rt].s1_start},
+			{REG_S1_END, s5k3e2fx_reg_pat[rt].s1_end},
+			{REG_S1S_START, s5k3e2fx_reg_pat[rt].s1s_start},
+			{REG_S1S_END, s5k3e2fx_reg_pat[rt].s1s_end},
+			{REG_S3_START, s5k3e2fx_reg_pat[rt].s3_start},
+			{REG_S3_END, s5k3e2fx_reg_pat[rt].s3_end},
+			{REG_CMP_EN_START, s5k3e2fx_reg_pat[rt].cmp_en_start},
+			{REG_CLP_SL_START, s5k3e2fx_reg_pat[rt].clp_sl_start},
+			{REG_CLP_SL_END, s5k3e2fx_reg_pat[rt].clp_sl_end},
+			{REG_OFF_START, s5k3e2fx_reg_pat[rt].off_start},
+			{REG_RMP_EN_START, s5k3e2fx_reg_pat[rt].rmp_en_start},
+			{REG_TX_START, s5k3e2fx_reg_pat[rt].tx_start},
+			{REG_TX_END, s5k3e2fx_reg_pat[rt].tx_end},
+			{REG_STX_WIDTH, s5k3e2fx_reg_pat[rt].stx_width},
+			{REG_3152_RESERVED,
+				s5k3e2fx_reg_pat[rt].reg_3152_reserved},
+			{REG_315A_RESERVED,
+				s5k3e2fx_reg_pat[rt].reg_315A_reserved},
+			{REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB,
+				s5k3e2fx_reg_pat[rt].
+				analogue_gain_code_global_msb},
+			{REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB,
+				s5k3e2fx_reg_pat[rt].
+				analogue_gain_code_global_lsb},
+			{REG_FINE_INTEGRATION_TIME,
+				s5k3e2fx_reg_pat[rt].fine_integration_time},
+			{REG_COARSE_INTEGRATION_TIME,
+				s5k3e2fx_reg_pat[rt].coarse_integration_time},
+			{S5K3E2FX_REG_MODE_SELECT, S5K3E2FX_MODE_SELECT_STREAM},
+		};
+
+		rc = s5k3e2fx_i2c_write_table(&tbl_1[0],
+			ARRAY_SIZE(tbl_1));
+		if (rc < 0)
+			return rc;
+
+		num_lperf = (uint16_t)
+			((s5k3e2fx_reg_pat[rt].frame_length_lines_msb << 8)
+			& 0xFF00)
+			+ s5k3e2fx_reg_pat[rt].frame_length_lines_lsb;
+
+		num_lperf = num_lperf * s5k3e2fx_ctrl->fps_divider / 0x0400;
+
+		tbl_2[0] = (struct s5k3e2fx_i2c_reg_conf)
+			{REG_FRAME_LENGTH_LINES_MSB, (num_lperf & 0xFF00) >> 8};
+		tbl_2[1] = (struct s5k3e2fx_i2c_reg_conf)
+			{REG_FRAME_LENGTH_LINES_LSB, (num_lperf & 0x00FF)};
+
+		rc = s5k3e2fx_i2c_write_table(&tbl_2[0],
+			ARRAY_SIZE(tbl_2));
+		if (rc < 0)
+			return rc;
+
+		mdelay(5);
+
+		rc = s5k3e2fx_test(s5k3e2fx_ctrl->set_test);
+		if (rc < 0)
+			return rc;
+	  }
+    break; /* UPDATE_PERIODIC */
+
+	case S_REG_INIT:
+	if (rt == S_RES_PREVIEW || rt == S_RES_CAPTURE) {
+
+		struct s5k3e2fx_i2c_reg_conf tbl_3[] = {
+			{S5K3E2FX_REG_SOFTWARE_RESET, S5K3E2FX_SOFTWARE_RESET},
+			{S5K3E2FX_REG_MODE_SELECT,
+				S5K3E2FX_MODE_SELECT_SW_STANDBY},
+			/* PLL setting */
+			{REG_PRE_PLL_CLK_DIV,
+				s5k3e2fx_reg_pat[rt].pre_pll_clk_div},
+			{REG_PLL_MULTIPLIER_MSB,
+				s5k3e2fx_reg_pat[rt].pll_multiplier_msb},
+			{REG_PLL_MULTIPLIER_LSB,
+				s5k3e2fx_reg_pat[rt].pll_multiplier_lsb},
+			{REG_VT_PIX_CLK_DIV,
+				s5k3e2fx_reg_pat[rt].vt_pix_clk_div},
+			{REG_VT_SYS_CLK_DIV,
+				s5k3e2fx_reg_pat[rt].vt_sys_clk_div},
+			{REG_OP_PIX_CLK_DIV,
+				s5k3e2fx_reg_pat[rt].op_pix_clk_div},
+			{REG_OP_SYS_CLK_DIV,
+				s5k3e2fx_reg_pat[rt].op_sys_clk_div},
+			/*Data Format */
+			{REG_CCP_DATA_FORMAT_MSB,
+				s5k3e2fx_reg_pat[rt].ccp_data_format_msb},
+			{REG_CCP_DATA_FORMAT_LSB,
+				s5k3e2fx_reg_pat[rt].ccp_data_format_lsb},
+			/*Output Size */
+			{REG_X_OUTPUT_SIZE_MSB,
+				s5k3e2fx_reg_pat[rt].x_output_size_msb},
+			{REG_X_OUTPUT_SIZE_LSB,
+				s5k3e2fx_reg_pat[rt].x_output_size_lsb},
+			{REG_Y_OUTPUT_SIZE_MSB,
+				s5k3e2fx_reg_pat[rt].y_output_size_msb},
+			{REG_Y_OUTPUT_SIZE_LSB,
+				s5k3e2fx_reg_pat[rt].y_output_size_lsb},
+			/* Binning */
+			{REG_X_EVEN_INC, s5k3e2fx_reg_pat[rt].x_even_inc},
+			{REG_X_ODD_INC, s5k3e2fx_reg_pat[rt].x_odd_inc },
+			{REG_Y_EVEN_INC, s5k3e2fx_reg_pat[rt].y_even_inc},
+			{REG_Y_ODD_INC, s5k3e2fx_reg_pat[rt].y_odd_inc},
+			{REG_BINNING_ENABLE,
+				s5k3e2fx_reg_pat[rt].binning_enable},
+			/* Frame format */
+			{REG_FRAME_LENGTH_LINES_MSB,
+				s5k3e2fx_reg_pat[rt].frame_length_lines_msb},
+			{REG_FRAME_LENGTH_LINES_LSB,
+				s5k3e2fx_reg_pat[rt].frame_length_lines_lsb},
+			{REG_LINE_LENGTH_PCK_MSB,
+				s5k3e2fx_reg_pat[rt].line_length_pck_msb},
+			{REG_LINE_LENGTH_PCK_LSB,
+				s5k3e2fx_reg_pat[rt].line_length_pck_lsb},
+			/* MSR setting */
+			{REG_SHADE_CLK_ENABLE,
+				s5k3e2fx_reg_pat[rt].shade_clk_enable},
+			{REG_SEL_CCP, s5k3e2fx_reg_pat[rt].sel_ccp},
+			{REG_VPIX, s5k3e2fx_reg_pat[rt].vpix},
+			{REG_CLAMP_ON, s5k3e2fx_reg_pat[rt].clamp_on},
+			{REG_OFFSET, s5k3e2fx_reg_pat[rt].offset},
+			/* CDS timing setting */
+			{REG_LD_START, s5k3e2fx_reg_pat[rt].ld_start},
+			{REG_LD_END, s5k3e2fx_reg_pat[rt].ld_end},
+			{REG_SL_START, s5k3e2fx_reg_pat[rt].sl_start},
+			{REG_SL_END, s5k3e2fx_reg_pat[rt].sl_end},
+			{REG_RX_START, s5k3e2fx_reg_pat[rt].rx_start},
+			{REG_S1_START, s5k3e2fx_reg_pat[rt].s1_start},
+			{REG_S1_END, s5k3e2fx_reg_pat[rt].s1_end},
+			{REG_S1S_START, s5k3e2fx_reg_pat[rt].s1s_start},
+			{REG_S1S_END, s5k3e2fx_reg_pat[rt].s1s_end},
+			{REG_S3_START, s5k3e2fx_reg_pat[rt].s3_start},
+			{REG_S3_END, s5k3e2fx_reg_pat[rt].s3_end},
+			{REG_CMP_EN_START, s5k3e2fx_reg_pat[rt].cmp_en_start},
+			{REG_CLP_SL_START, s5k3e2fx_reg_pat[rt].clp_sl_start},
+			{REG_CLP_SL_END, s5k3e2fx_reg_pat[rt].clp_sl_end},
+			{REG_OFF_START, s5k3e2fx_reg_pat[rt].off_start},
+			{REG_RMP_EN_START, s5k3e2fx_reg_pat[rt].rmp_en_start},
+			{REG_TX_START, s5k3e2fx_reg_pat[rt].tx_start},
+			{REG_TX_END, s5k3e2fx_reg_pat[rt].tx_end},
+			{REG_STX_WIDTH, s5k3e2fx_reg_pat[rt].stx_width},
+			{REG_3152_RESERVED,
+				s5k3e2fx_reg_pat[rt].reg_3152_reserved},
+			{REG_315A_RESERVED,
+				s5k3e2fx_reg_pat[rt].reg_315A_reserved},
+			{REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB,
+				s5k3e2fx_reg_pat[rt].
+				analogue_gain_code_global_msb},
+			{REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB,
+				s5k3e2fx_reg_pat[rt].
+				analogue_gain_code_global_lsb},
+			{REG_FINE_INTEGRATION_TIME,
+				s5k3e2fx_reg_pat[rt].fine_integration_time},
+			{REG_COARSE_INTEGRATION_TIME,
+				s5k3e2fx_reg_pat[rt].coarse_integration_time},
+			{S5K3E2FX_REG_MODE_SELECT, S5K3E2FX_MODE_SELECT_STREAM},
+		};
+
+		/* reset fps_divider */
+		s5k3e2fx_ctrl->fps_divider = 1 * 0x0400;
+		rc = s5k3e2fx_i2c_write_table(&tbl_3[0],
+			ARRAY_SIZE(tbl_3));
+		if (rc < 0)
+			return rc;
+		}
+		break; /* case REG_INIT: */
+
+	default:
+		rc = -EINVAL;
+		break;
+	} /* switch (rupdate) */
+
+	return rc;
+}
+
+static int s5k3e2fx_sensor_open_init(const struct msm_camera_sensor_info *data)
+{
+	int32_t  rc;
+
+	s5k3e2fx_ctrl = kzalloc(sizeof(struct s5k3e2fx_ctrl), GFP_KERNEL);
+	if (!s5k3e2fx_ctrl) {
+		CDBG("s5k3e2fx_init failed!\n");
+		rc = -ENOMEM;
+		goto init_done;
+	}
+
+	s5k3e2fx_ctrl->fps_divider = 1 * 0x00000400;
+	s5k3e2fx_ctrl->pict_fps_divider = 1 * 0x00000400;
+	s5k3e2fx_ctrl->set_test = S_TEST_OFF;
+	s5k3e2fx_ctrl->prev_res = S_QTR_SIZE;
+	s5k3e2fx_ctrl->pict_res = S_FULL_SIZE;
+
+	if (data)
+		s5k3e2fx_ctrl->sensordata = data;
+
+	/* enable mclk first */
+	msm_camio_clk_rate_set(24000000);
+	mdelay(20);
+
+	msm_camio_camif_pad_reg_reset();
+	mdelay(20);
+
+	rc = s5k3e2fx_probe_init_sensor(data);
+	if (rc < 0)
+		goto init_fail1;
+
+	if (s5k3e2fx_ctrl->prev_res == S_QTR_SIZE)
+		rc = s5k3e2fx_setting(S_REG_INIT, S_RES_PREVIEW);
+	else
+		rc = s5k3e2fx_setting(S_REG_INIT, S_RES_CAPTURE);
+
+	if (rc < 0) {
+		CDBG("s5k3e2fx_setting failed. rc = %d\n", rc);
+		goto init_fail1;
+	}
+
+	/* initialize AF */
+	rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
+			0x3146, 0x3A);
+	if (rc < 0)
+		goto init_fail1;
+
+	rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
+			0x3130, 0x03);
+	if (rc < 0)
+		goto init_fail1;
+
+	goto init_done;
+
+init_fail1:
+	s5k3e2fx_probe_init_done(data);
+	kfree(s5k3e2fx_ctrl);
+init_done:
+	return rc;
+}
+
+static int32_t s5k3e2fx_power_down(void)
+{
+	int32_t rc = 0;
+	return rc;
+}
+
+static int s5k3e2fx_sensor_release(void)
+{
+	int rc = -EBADF;
+
+	mutex_lock(&s5k3e2fx_mutex);
+
+	s5k3e2fx_power_down();
+
+	gpio_direction_output(s5k3e2fx_ctrl->sensordata->sensor_reset,
+		0);
+	gpio_free(s5k3e2fx_ctrl->sensordata->sensor_reset);
+
+	kfree(s5k3e2fx_ctrl);
+	s5k3e2fx_ctrl = NULL;
+
+	CDBG("s5k3e2fx_release completed\n");
+
+	mutex_unlock(&s5k3e2fx_mutex);
+	return rc;
+}
+
+static void s5k3e2fx_get_pict_fps(uint16_t fps, uint16_t *pfps)
+{
+	/* input fps is preview fps in Q8 format */
+	uint32_t divider;   /* Q10 */
+
+	divider = (uint32_t)
+		((s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h +
+			s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l) *
+		 (s5k3e2fx_reg_pat[S_RES_PREVIEW].size_w +
+			s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_p)) * 0x00000400 /
+		((s5k3e2fx_reg_pat[S_RES_CAPTURE].size_h +
+			s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l) *
+		 (s5k3e2fx_reg_pat[S_RES_CAPTURE].size_w +
+			s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p));
+
+	/* Verify PCLK settings and frame sizes. */
+	*pfps = (uint16_t)(fps * divider / 0x00000400);
+}
+
+static uint16_t s5k3e2fx_get_prev_lines_pf(void)
+{
+	return s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h +
+		s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l;
+}
+
+static uint16_t s5k3e2fx_get_prev_pixels_pl(void)
+{
+	return s5k3e2fx_reg_pat[S_RES_PREVIEW].size_w +
+		s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_p;
+}
+
+static uint16_t s5k3e2fx_get_pict_lines_pf(void)
+{
+	return s5k3e2fx_reg_pat[S_RES_CAPTURE].size_h +
+		s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l;
+}
+
+static uint16_t s5k3e2fx_get_pict_pixels_pl(void)
+{
+	return s5k3e2fx_reg_pat[S_RES_CAPTURE].size_w +
+		s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p;
+}
+
+static uint32_t s5k3e2fx_get_pict_max_exp_lc(void)
+{
+	uint32_t snapshot_lines_per_frame;
+
+	if (s5k3e2fx_ctrl->pict_res == S_QTR_SIZE)
+		snapshot_lines_per_frame =
+		s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h +
+		s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l;
+	else
+		snapshot_lines_per_frame = 3961 * 3;
+
+	return snapshot_lines_per_frame;
+}
+
+static int32_t s5k3e2fx_set_fps(struct fps_cfg *fps)
+{
+	/* input is new fps in Q10 format */
+	int32_t rc = 0;
+	enum msm_s_setting setting;
+
+	s5k3e2fx_ctrl->fps_divider = fps->fps_div;
+
+	if (s5k3e2fx_ctrl->sensormode == SENSOR_PREVIEW_MODE)
+		setting = S_RES_PREVIEW;
+	else
+		setting = S_RES_CAPTURE;
+
+  rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
+		REG_FRAME_LENGTH_LINES_MSB,
+		(((s5k3e2fx_reg_pat[setting].size_h +
+			s5k3e2fx_reg_pat[setting].blk_l) *
+			s5k3e2fx_ctrl->fps_divider / 0x400) & 0xFF00) >> 8);
+	if (rc < 0)
+		goto set_fps_done;
+
+  rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
+		REG_FRAME_LENGTH_LINES_LSB,
+		(((s5k3e2fx_reg_pat[setting].size_h +
+			s5k3e2fx_reg_pat[setting].blk_l) *
+			s5k3e2fx_ctrl->fps_divider / 0x400) & 0x00FF));
+
+set_fps_done:
+	return rc;
+}
+
+static int32_t s5k3e2fx_write_exp_gain(uint16_t gain, uint32_t line)
+{
+	int32_t rc = 0;
+
+	uint16_t max_legal_gain = 0x0200;
+	uint32_t ll_ratio; /* Q10 */
+	uint32_t ll_pck, fl_lines;
+	uint16_t offset = 4;
+	uint32_t  gain_msb, gain_lsb;
+	uint32_t  intg_t_msb, intg_t_lsb;
+	uint32_t  ll_pck_msb, ll_pck_lsb;
+
+	struct s5k3e2fx_i2c_reg_conf tbl[2];
+
+	CDBG("Line:%d s5k3e2fx_write_exp_gain \n", __LINE__);
+
+	if (s5k3e2fx_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
+
+		s5k3e2fx_ctrl->my_reg_gain = gain;
+		s5k3e2fx_ctrl->my_reg_line_count = (uint16_t)line;
+
+		fl_lines = s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h +
+			s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l;
+
+		ll_pck = s5k3e2fx_reg_pat[S_RES_PREVIEW].size_w +
+			s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_p;
+
+	} else {
+
+		fl_lines = s5k3e2fx_reg_pat[S_RES_CAPTURE].size_h +
+			s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l;
+
+		ll_pck = s5k3e2fx_reg_pat[S_RES_CAPTURE].size_w +
+			s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p;
+	}
+
+	if (gain > max_legal_gain)
+		gain = max_legal_gain;
+
+	/* in Q10 */
+	line = (line * s5k3e2fx_ctrl->fps_divider);
+
+	if (fl_lines < (line / 0x400))
+		ll_ratio = (line / (fl_lines - offset));
+	else
+		ll_ratio = 0x400;
+
+	/* update gain registers */
+	gain_msb = (gain & 0xFF00) >> 8;
+	gain_lsb = gain & 0x00FF;
+	tbl[0].waddr = REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB;
+	tbl[0].bdata = gain_msb;
+	tbl[1].waddr = REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB;
+	tbl[1].bdata = gain_lsb;
+	rc = s5k3e2fx_i2c_write_table(&tbl[0], ARRAY_SIZE(tbl));
+	if (rc < 0)
+		goto write_gain_done;
+
+	ll_pck = ll_pck * ll_ratio;
+	ll_pck_msb = ((ll_pck / 0x400) & 0xFF00) >> 8;
+	ll_pck_lsb = (ll_pck / 0x400) & 0x00FF;
+	tbl[0].waddr = REG_LINE_LENGTH_PCK_MSB;
+	tbl[0].bdata = ll_pck_msb;
+	tbl[1].waddr = REG_LINE_LENGTH_PCK_LSB;
+	tbl[1].bdata = ll_pck_lsb;
+	rc = s5k3e2fx_i2c_write_table(&tbl[0], ARRAY_SIZE(tbl));
+	if (rc < 0)
+		goto write_gain_done;
+
+	line = line / ll_ratio;
+	intg_t_msb = (line & 0xFF00) >> 8;
+	intg_t_lsb = (line & 0x00FF);
+	tbl[0].waddr = REG_COARSE_INTEGRATION_TIME;
+	tbl[0].bdata = intg_t_msb;
+	tbl[1].waddr = REG_COARSE_INTEGRATION_TIME_LSB;
+	tbl[1].bdata = intg_t_lsb;
+	rc = s5k3e2fx_i2c_write_table(&tbl[0], ARRAY_SIZE(tbl));
+
+write_gain_done:
+	return rc;
+}
+
+static int32_t s5k3e2fx_set_pict_exp_gain(uint16_t gain, uint32_t line)
+{
+	int32_t rc = 0;
+
+	CDBG("Line:%d s5k3e2fx_set_pict_exp_gain \n", __LINE__);
+
+	rc =
+		s5k3e2fx_write_exp_gain(gain, line);
+
+	return rc;
+}
+
+static int32_t s5k3e2fx_video_config(int mode, int res)
+{
+	int32_t rc;
+
+	switch (res) {
+	case S_QTR_SIZE:
+		rc = s5k3e2fx_setting(S_UPDATE_PERIODIC, S_RES_PREVIEW);
+		if (rc < 0)
+			return rc;
+
+		CDBG("s5k3e2fx sensor configuration done!\n");
+		break;
+
+	case S_FULL_SIZE:
+		rc = s5k3e2fx_setting(S_UPDATE_PERIODIC, S_RES_CAPTURE);
+		if (rc < 0)
+			return rc;
+
+		break;
+
+	default:
+		return 0;
+	} /* switch */
+
+	s5k3e2fx_ctrl->prev_res = res;
+	s5k3e2fx_ctrl->curr_res = res;
+	s5k3e2fx_ctrl->sensormode = mode;
+
+	rc =
+		s5k3e2fx_write_exp_gain(s5k3e2fx_ctrl->my_reg_gain,
+			s5k3e2fx_ctrl->my_reg_line_count);
+
+	return rc;
+}
+
+static int32_t s5k3e2fx_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+
+	rc = s5k3e2fx_setting(S_UPDATE_PERIODIC, S_RES_CAPTURE);
+	if (rc < 0)
+		return rc;
+
+	s5k3e2fx_ctrl->curr_res = s5k3e2fx_ctrl->pict_res;
+	s5k3e2fx_ctrl->sensormode = mode;
+
+	return rc;
+}
+
+static int32_t s5k3e2fx_raw_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+
+	rc = s5k3e2fx_setting(S_UPDATE_PERIODIC, S_RES_CAPTURE);
+	if (rc < 0)
+		return rc;
+
+	s5k3e2fx_ctrl->curr_res = s5k3e2fx_ctrl->pict_res;
+	s5k3e2fx_ctrl->sensormode = mode;
+
+	return rc;
+}
+
+static int32_t s5k3e2fx_set_sensor_mode(int mode, int res)
+{
+	int32_t rc = 0;
+
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		rc = s5k3e2fx_video_config(mode, res);
+		break;
+
+	case SENSOR_SNAPSHOT_MODE:
+		rc = s5k3e2fx_snapshot_config(mode);
+		break;
+
+	case SENSOR_RAW_SNAPSHOT_MODE:
+		rc = s5k3e2fx_raw_snapshot_config(mode);
+		break;
+
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
+static int32_t s5k3e2fx_set_default_focus(void)
+{
+	int32_t rc = 0;
+
+  rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
+		0x3131, 0);
+	if (rc < 0)
+		return rc;
+
+  rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
+		0x3132, 0);
+	if (rc < 0)
+		return rc;
+
+	s5k3e2fx_ctrl->curr_lens_pos = 0;
+
+	return rc;
+}
+
+static int32_t s5k3e2fx_move_focus(int direction, int32_t num_steps)
+{
+	int32_t rc = 0;
+	int32_t i;
+	int16_t step_direction;
+	int16_t actual_step;
+	int16_t next_pos, pos_offset;
+	int16_t init_code = 50;
+	uint8_t next_pos_msb, next_pos_lsb;
+	int16_t s_move[5];
+	uint32_t gain; /* Q10 format */
+
+	if (direction == MOVE_NEAR)
+		step_direction = 20;
+	else if (direction == MOVE_FAR)
+		step_direction = -20;
+	else {
+		CDBG("s5k3e2fx_move_focus failed at line %d ...\n", __LINE__);
+		return -EINVAL;
+	}
+
+	actual_step = step_direction * (int16_t)num_steps;
+	pos_offset = init_code + s5k3e2fx_ctrl->curr_lens_pos;
+	gain = actual_step * 0x400 / 5;
+
+	for (i = 0; i <= 4; i++) {
+		if (actual_step >= 0)
+			s_move[i] = (((i+1)*gain+0x200)-(i*gain+0x200))/0x400;
+		else
+			s_move[i] = (((i+1)*gain-0x200)-(i*gain-0x200))/0x400;
+	}
+
+	/* Ring Damping Code */
+	for (i = 0; i <= 4; i++) {
+		next_pos = (int16_t)(pos_offset + s_move[i]);
+
+		if (next_pos > (738 + init_code))
+			next_pos = 738 + init_code;
+		else if (next_pos < 0)
+			next_pos = 0;
+
+		CDBG("next_position in damping mode = %d\n", next_pos);
+		/* Writing the Values to the actuator */
+		if (next_pos == init_code)
+			next_pos = 0x00;
+
+		next_pos_msb = next_pos >> 8;
+		next_pos_lsb = next_pos & 0x00FF;
+
+		rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
+			0x3131, next_pos_msb);
+		if (rc < 0)
+			break;
+
+		rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
+			0x3132, next_pos_lsb);
+		if (rc < 0)
+			break;
+
+		pos_offset = next_pos;
+		s5k3e2fx_ctrl->curr_lens_pos = pos_offset - init_code;
+		if (i < 4)
+			mdelay(3);
+	}
+
+	return rc;
+}
+
+static int s5k3e2fx_sensor_config(void __user *argp)
+{
+	struct sensor_cfg_data cdata;
+	long   rc = 0;
+
+	if (copy_from_user(&cdata,
+			(void *)argp,
+			sizeof(struct sensor_cfg_data)))
+		return -EFAULT;
+
+	mutex_lock(&s5k3e2fx_mutex);
+
+	CDBG("%s: cfgtype = %d\n", __func__, cdata.cfgtype);
+	switch (cdata.cfgtype) {
+	case CFG_GET_PICT_FPS:
+		s5k3e2fx_get_pict_fps(cdata.cfg.gfps.prevfps,
+			&(cdata.cfg.gfps.pictfps));
+
+		if (copy_to_user((void *)argp, &cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PREV_L_PF:
+		cdata.cfg.prevl_pf = s5k3e2fx_get_prev_lines_pf();
+
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PREV_P_PL:
+		cdata.cfg.prevp_pl = s5k3e2fx_get_prev_pixels_pl();
+
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_L_PF:
+		cdata.cfg.pictl_pf = s5k3e2fx_get_pict_lines_pf();
+
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_P_PL:
+		cdata.cfg.pictp_pl = s5k3e2fx_get_pict_pixels_pl();
+
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_MAX_EXP_LC:
+		cdata.cfg.pict_max_exp_lc =
+			s5k3e2fx_get_pict_max_exp_lc();
+
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_SET_FPS:
+	case CFG_SET_PICT_FPS:
+		rc = s5k3e2fx_set_fps(&(cdata.cfg.fps));
+		break;
+
+	case CFG_SET_EXP_GAIN:
+		rc =
+			s5k3e2fx_write_exp_gain(cdata.cfg.exp_gain.gain,
+				cdata.cfg.exp_gain.line);
+		break;
+
+	case CFG_SET_PICT_EXP_GAIN:
+		CDBG("Line:%d CFG_SET_PICT_EXP_GAIN \n", __LINE__);
+		rc =
+			s5k3e2fx_set_pict_exp_gain(
+				cdata.cfg.exp_gain.gain,
+				cdata.cfg.exp_gain.line);
+		break;
+
+	case CFG_SET_MODE:
+		rc =
+			s5k3e2fx_set_sensor_mode(
+			cdata.mode, cdata.rs);
+		break;
+
+	case CFG_PWR_DOWN:
+		rc = s5k3e2fx_power_down();
+		break;
+
+	case CFG_MOVE_FOCUS:
+		rc =
+			s5k3e2fx_move_focus(
+			cdata.cfg.focus.dir,
+			cdata.cfg.focus.steps);
+		break;
+
+	case CFG_SET_DEFAULT_FOCUS:
+		rc =
+			s5k3e2fx_set_default_focus();
+		break;
+
+	case CFG_GET_AF_MAX_STEPS:
+	case CFG_SET_EFFECT:
+	case CFG_SET_LENS_SHADING:
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	mutex_unlock(&s5k3e2fx_mutex);
+	return rc;
+}
+
+static int s5k3e2fx_sensor_probe(const struct msm_camera_sensor_info *info,
+		struct msm_sensor_ctrl *s)
+{
+	int rc = 0;
+
+	rc = i2c_add_driver(&s5k3e2fx_i2c_driver);
+	if (rc < 0 || s5k3e2fx_client == NULL) {
+		rc = -ENOTSUPP;
+		goto probe_fail;
+	}
+
+	msm_camio_clk_rate_set(24000000);
+	mdelay(20);
+
+	rc = s5k3e2fx_probe_init_sensor(info);
+	if (rc < 0)
+		goto probe_fail;
+
+	s->s_init = s5k3e2fx_sensor_open_init;
+	s->s_release = s5k3e2fx_sensor_release;
+	s->s_config  = s5k3e2fx_sensor_config;
+	s->s_mount_angle  = 0;
+	s5k3e2fx_probe_init_done(info);
+
+	return rc;
+
+probe_fail:
+	CDBG("SENSOR PROBE FAILS!\n");
+	return rc;
+}
+
+static int __s5k3e2fx_probe(struct platform_device *pdev)
+{
+	return msm_camera_drv_start(pdev, s5k3e2fx_sensor_probe);
+}
+
+static struct platform_driver msm_camera_driver = {
+	.probe = __s5k3e2fx_probe,
+	.driver = {
+		.name = "msm_camera_s5k3e2fx",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init s5k3e2fx_init(void)
+{
+	return platform_driver_register(&msm_camera_driver);
+}
+
+module_init(s5k3e2fx_init);
+
diff --git a/drivers/media/platform/msm/camera_v1/s5k3e2fx.h b/drivers/media/platform/msm/camera_v1/s5k3e2fx.h
new file mode 100644
index 0000000..3cf4f8e
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/s5k3e2fx.h
@@ -0,0 +1,18 @@
+/* Copyright (c) 2009, 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 CAMSENSOR_S5K3E2FX
+#define CAMSENSOR_S5K3E2FX
+
+#include <mach/board.h>
+#endif /* CAMSENSOR_S5K3E2FX */
diff --git a/drivers/media/platform/msm/camera_v1/s5k4e1.c b/drivers/media/platform/msm/camera_v1/s5k4e1.c
new file mode 100644
index 0000000..c62103e
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/s5k4e1.c
@@ -0,0 +1,1103 @@
+/* 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/delay.h>
+#include <linux/debugfs.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/bitops.h>
+#include <mach/camera.h>
+#include <media/msm_camera.h>
+#include "s5k4e1.h"
+
+/* 16bit address - 8 bit context register structure */
+#define Q8	0x00000100
+#define Q10	0x00000400
+
+/* MCLK */
+#define S5K4E1_MASTER_CLK_RATE 24000000
+
+/* AF Total steps parameters */
+#define S5K4E1_TOTAL_STEPS_NEAR_TO_FAR	32
+
+#define S5K4E1_REG_PREV_FRAME_LEN_1	31
+#define S5K4E1_REG_PREV_FRAME_LEN_2	32
+#define S5K4E1_REG_PREV_LINE_LEN_1	33
+#define S5K4E1_REG_PREV_LINE_LEN_2	34
+
+#define S5K4E1_REG_SNAP_FRAME_LEN_1	15
+#define S5K4E1_REG_SNAP_FRAME_LEN_2	16
+#define  S5K4E1_REG_SNAP_LINE_LEN_1	17
+#define S5K4E1_REG_SNAP_LINE_LEN_2	18
+#define MSB                             1
+#define LSB                             0
+
+struct s5k4e1_work_t {
+	struct work_struct work;
+};
+
+static struct s5k4e1_work_t *s5k4e1_sensorw;
+static struct s5k4e1_work_t *s5k4e1_af_sensorw;
+static struct i2c_client *s5k4e1_af_client;
+static struct i2c_client *s5k4e1_client;
+
+struct s5k4e1_ctrl_t {
+	const struct  msm_camera_sensor_info *sensordata;
+
+	uint32_t sensormode;
+	uint32_t fps_divider;/* init to 1 * 0x00000400 */
+	uint32_t pict_fps_divider;/* init to 1 * 0x00000400 */
+	uint16_t fps;
+
+	uint16_t curr_lens_pos;
+	uint16_t curr_step_pos;
+	uint16_t my_reg_gain;
+	uint32_t my_reg_line_count;
+	uint16_t total_lines_per_frame;
+
+	enum s5k4e1_resolution_t prev_res;
+	enum s5k4e1_resolution_t pict_res;
+	enum s5k4e1_resolution_t curr_res;
+	enum s5k4e1_test_mode_t  set_test;
+};
+
+static bool CSI_CONFIG;
+static struct s5k4e1_ctrl_t *s5k4e1_ctrl;
+
+static DECLARE_WAIT_QUEUE_HEAD(s5k4e1_wait_queue);
+static DECLARE_WAIT_QUEUE_HEAD(s5k4e1_af_wait_queue);
+DEFINE_MUTEX(s5k4e1_mut);
+
+static uint16_t prev_line_length_pck;
+static uint16_t prev_frame_length_lines;
+static uint16_t snap_line_length_pck;
+static uint16_t snap_frame_length_lines;
+
+static int s5k4e1_i2c_rxdata(unsigned short saddr,
+		unsigned char *rxdata, int length)
+{
+	struct i2c_msg msgs[] = {
+		{
+			.addr  = saddr,
+			.flags = 0,
+			.len   = 1,
+			.buf   = rxdata,
+		},
+		{
+			.addr  = saddr,
+			.flags = I2C_M_RD,
+			.len   = 1,
+			.buf   = rxdata,
+		},
+	};
+	if (i2c_transfer(s5k4e1_client->adapter, msgs, 2) < 0) {
+		CDBG("s5k4e1_i2c_rxdata faild 0x%x\n", saddr);
+		return -EIO;
+	}
+	return 0;
+}
+
+static int32_t s5k4e1_i2c_txdata(unsigned short saddr,
+		unsigned char *txdata, int length)
+{
+	struct i2c_msg msg[] = {
+		{
+			.addr = saddr,
+			.flags = 0,
+			.len = length,
+			.buf = txdata,
+		},
+	};
+	if (i2c_transfer(s5k4e1_client->adapter, msg, 1) < 0) {
+		CDBG("s5k4e1_i2c_txdata faild 0x%x\n", saddr);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t s5k4e1_i2c_read(unsigned short raddr,
+		unsigned short *rdata, int rlen)
+{
+	int32_t rc = 0;
+	unsigned char buf[2];
+
+	if (!rdata)
+		return -EIO;
+
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (raddr & 0xFF00) >> 8;
+	buf[1] = (raddr & 0x00FF);
+	rc = s5k4e1_i2c_rxdata(s5k4e1_client->addr, buf, rlen);
+	if (rc < 0) {
+		CDBG("s5k4e1_i2c_read 0x%x failed!\n", raddr);
+		return rc;
+	}
+	*rdata = (rlen == 2 ? buf[0] << 8 | buf[1] : buf[0]);
+	CDBG("s5k4e1_i2c_read 0x%x val = 0x%x!\n", raddr, *rdata);
+
+	return rc;
+}
+
+static int32_t s5k4e1_i2c_write_b_sensor(unsigned short waddr, uint8_t bdata)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[3];
+
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00) >> 8;
+	buf[1] = (waddr & 0x00FF);
+	buf[2] = bdata;
+	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
+	rc = s5k4e1_i2c_txdata(s5k4e1_client->addr, buf, 3);
+	if (rc < 0) {
+		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
+				waddr, bdata);
+	}
+	return rc;
+}
+
+static int32_t s5k4e1_i2c_write_b_table(struct s5k4e1_i2c_reg_conf const
+		*reg_conf_tbl, int num)
+{
+	int i;
+	int32_t rc = -EIO;
+
+	for (i = 0; i < num; i++) {
+		rc = s5k4e1_i2c_write_b_sensor(reg_conf_tbl->waddr,
+				reg_conf_tbl->wdata);
+		if (rc < 0)
+			break;
+		reg_conf_tbl++;
+	}
+	return rc;
+}
+
+static int32_t s5k4e1_af_i2c_txdata(unsigned short saddr,
+		unsigned char *txdata, int length)
+{
+	struct i2c_msg msg[] = {
+		{
+			.addr = saddr,
+			.flags = 0,
+			.len = length,
+			.buf = txdata,
+		},
+	};
+	if (i2c_transfer(s5k4e1_af_client->adapter, msg, 1) < 0) {
+		pr_err("s5k4e1_af_i2c_txdata faild 0x%x\n", saddr);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t s5k4e1_af_i2c_write_b_sensor(uint8_t waddr, uint8_t bdata)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[2];
+
+	memset(buf, 0, sizeof(buf));
+	buf[0] = waddr;
+	buf[1] = bdata;
+	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
+	rc = s5k4e1_af_i2c_txdata(s5k4e1_af_client->addr << 1, buf, 2);
+	if (rc < 0) {
+		pr_err("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
+				waddr, bdata);
+	}
+	return rc;
+}
+
+static void s5k4e1_start_stream(void)
+{
+	s5k4e1_i2c_write_b_sensor(0x0100, 0x01);/* streaming on */
+}
+
+static void s5k4e1_stop_stream(void)
+{
+	s5k4e1_i2c_write_b_sensor(0x0100, 0x00);/* streaming off */
+}
+
+static void s5k4e1_group_hold_on(void)
+{
+	s5k4e1_i2c_write_b_sensor(0x0104, 0x01);
+}
+
+static void s5k4e1_group_hold_off(void)
+{
+	s5k4e1_i2c_write_b_sensor(0x0104, 0x0);
+}
+
+static void s5k4e1_get_pict_fps(uint16_t fps, uint16_t *pfps)
+{
+	/* input fps is preview fps in Q8 format */
+	uint32_t divider, d1, d2;
+
+	d1 = (prev_frame_length_lines * 0x00000400) / snap_frame_length_lines;
+	d2 = (prev_line_length_pck * 0x00000400) / snap_line_length_pck;
+	divider = (d1 * d2) / 0x400;
+
+	/*Verify PCLK settings and frame sizes.*/
+	*pfps = (uint16_t) (fps * divider / 0x400);
+}
+
+static uint16_t s5k4e1_get_prev_lines_pf(void)
+{
+	if (s5k4e1_ctrl->prev_res == QTR_SIZE)
+		return prev_frame_length_lines;
+	else
+		return snap_frame_length_lines;
+}
+
+static uint16_t s5k4e1_get_prev_pixels_pl(void)
+{
+	if (s5k4e1_ctrl->prev_res == QTR_SIZE)
+		return prev_line_length_pck;
+	else
+		return snap_line_length_pck;
+}
+
+static uint16_t s5k4e1_get_pict_lines_pf(void)
+{
+	if (s5k4e1_ctrl->pict_res == QTR_SIZE)
+		return prev_frame_length_lines;
+	else
+		return snap_frame_length_lines;
+}
+
+static uint16_t s5k4e1_get_pict_pixels_pl(void)
+{
+	if (s5k4e1_ctrl->pict_res == QTR_SIZE)
+		return prev_line_length_pck;
+	else
+		return snap_line_length_pck;
+}
+
+static uint32_t s5k4e1_get_pict_max_exp_lc(void)
+{
+	return snap_frame_length_lines * 24;
+}
+
+static int32_t s5k4e1_set_fps(struct fps_cfg   *fps)
+{
+	uint16_t total_lines_per_frame;
+	int32_t rc = 0;
+
+	s5k4e1_ctrl->fps_divider = fps->fps_div;
+	s5k4e1_ctrl->pict_fps_divider = fps->pict_fps_div;
+
+	if (s5k4e1_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
+		total_lines_per_frame = (uint16_t)
+		((prev_frame_length_lines * s5k4e1_ctrl->fps_divider) / 0x400);
+	} else {
+		total_lines_per_frame = (uint16_t)
+		((snap_frame_length_lines * s5k4e1_ctrl->fps_divider) / 0x400);
+	}
+
+	s5k4e1_group_hold_on();
+	rc = s5k4e1_i2c_write_b_sensor(0x0340,
+			((total_lines_per_frame & 0xFF00) >> 8));
+	rc = s5k4e1_i2c_write_b_sensor(0x0341,
+			(total_lines_per_frame & 0x00FF));
+	s5k4e1_group_hold_off();
+
+	return rc;
+}
+
+static inline uint8_t s5k4e1_byte(uint16_t word, uint8_t offset)
+{
+	return word >> (offset * BITS_PER_BYTE);
+}
+
+static int32_t s5k4e1_write_exp_gain(uint16_t gain, uint32_t line)
+{
+	uint16_t max_legal_gain = 0x0200;
+	int32_t rc = 0;
+	static uint32_t fl_lines;
+
+	if (gain > max_legal_gain) {
+		pr_debug("Max legal gain Line:%d\n", __LINE__);
+		gain = max_legal_gain;
+	}
+	/* Analogue Gain */
+	s5k4e1_i2c_write_b_sensor(0x0204, s5k4e1_byte(gain, MSB));
+	s5k4e1_i2c_write_b_sensor(0x0205, s5k4e1_byte(gain, LSB));
+
+	if (line > (prev_frame_length_lines - 4)) {
+		fl_lines = line+4;
+		s5k4e1_group_hold_on();
+		s5k4e1_i2c_write_b_sensor(0x0340, s5k4e1_byte(fl_lines, MSB));
+		s5k4e1_i2c_write_b_sensor(0x0341, s5k4e1_byte(fl_lines, LSB));
+		/* Coarse Integration Time */
+		s5k4e1_i2c_write_b_sensor(0x0202, s5k4e1_byte(line, MSB));
+		s5k4e1_i2c_write_b_sensor(0x0203, s5k4e1_byte(line, LSB));
+		s5k4e1_group_hold_off();
+	} else if (line < (fl_lines - 4)) {
+		fl_lines = line+4;
+		if (fl_lines < prev_frame_length_lines)
+			fl_lines = prev_frame_length_lines;
+
+		s5k4e1_group_hold_on();
+		/* Coarse Integration Time */
+		s5k4e1_i2c_write_b_sensor(0x0202, s5k4e1_byte(line, MSB));
+		s5k4e1_i2c_write_b_sensor(0x0203, s5k4e1_byte(line, LSB));
+		s5k4e1_i2c_write_b_sensor(0x0340, s5k4e1_byte(fl_lines, MSB));
+		s5k4e1_i2c_write_b_sensor(0x0341, s5k4e1_byte(fl_lines, LSB));
+		s5k4e1_group_hold_off();
+	} else {
+		fl_lines = line+4;
+		s5k4e1_group_hold_on();
+		/* Coarse Integration Time */
+		s5k4e1_i2c_write_b_sensor(0x0202, s5k4e1_byte(line, MSB));
+		s5k4e1_i2c_write_b_sensor(0x0203, s5k4e1_byte(line, LSB));
+		s5k4e1_group_hold_off();
+	}
+	return rc;
+}
+
+static int32_t s5k4e1_set_pict_exp_gain(uint16_t gain, uint32_t line)
+{
+	uint16_t max_legal_gain = 0x0200;
+	uint16_t min_ll_pck = 0x0AB2;
+	uint32_t ll_pck, fl_lines;
+	uint32_t ll_ratio;
+	int32_t rc = 0;
+	uint8_t gain_msb, gain_lsb;
+	uint8_t intg_time_msb, intg_time_lsb;
+	uint8_t ll_pck_msb, ll_pck_lsb;
+
+	if (gain > max_legal_gain) {
+		pr_debug("Max legal gain Line:%d\n", __LINE__);
+		gain = max_legal_gain;
+	}
+
+	pr_debug("s5k4e1_write_exp_gain : gain = %d line = %d\n", gain, line);
+	line = (uint32_t) (line * s5k4e1_ctrl->pict_fps_divider);
+	fl_lines = snap_frame_length_lines;
+	ll_pck = snap_line_length_pck;
+
+	if (fl_lines < (line / 0x400))
+		ll_ratio = (line / (fl_lines - 4));
+	else
+		ll_ratio = 0x400;
+
+	ll_pck = ll_pck * ll_ratio / 0x400;
+	line = line / ll_ratio;
+	if (ll_pck < min_ll_pck)
+		ll_pck = min_ll_pck;
+
+	gain_msb = (uint8_t) ((gain & 0xFF00) >> 8);
+	gain_lsb = (uint8_t) (gain & 0x00FF);
+
+	intg_time_msb = (uint8_t) ((line & 0xFF00) >> 8);
+	intg_time_lsb = (uint8_t) (line & 0x00FF);
+
+	ll_pck_msb = (uint8_t) ((ll_pck & 0xFF00) >> 8);
+	ll_pck_lsb = (uint8_t) (ll_pck & 0x00FF);
+
+	s5k4e1_group_hold_on();
+	s5k4e1_i2c_write_b_sensor(0x0204, gain_msb); /* Analogue Gain */
+	s5k4e1_i2c_write_b_sensor(0x0205, gain_lsb);
+
+	s5k4e1_i2c_write_b_sensor(0x0342, ll_pck_msb);
+	s5k4e1_i2c_write_b_sensor(0x0343, ll_pck_lsb);
+
+	/* Coarse Integration Time */
+	s5k4e1_i2c_write_b_sensor(0x0202, intg_time_msb);
+	s5k4e1_i2c_write_b_sensor(0x0203, intg_time_lsb);
+	s5k4e1_group_hold_off();
+
+	return rc;
+}
+
+static int32_t s5k4e1_move_focus(int direction,
+		int32_t num_steps)
+{
+	int16_t step_direction, actual_step, next_position;
+	uint8_t code_val_msb, code_val_lsb;
+
+	if (direction == MOVE_NEAR)
+		step_direction = 16;
+	else
+		step_direction = -16;
+
+	actual_step = (int16_t) (step_direction * num_steps);
+	next_position = (int16_t) (s5k4e1_ctrl->curr_lens_pos + actual_step);
+
+	if (next_position > 1023)
+		next_position = 1023;
+	else if (next_position < 0)
+		next_position = 0;
+
+	code_val_msb = next_position >> 4;
+	code_val_lsb = (next_position & 0x000F) << 4;
+
+	if (s5k4e1_af_i2c_write_b_sensor(code_val_msb, code_val_lsb) < 0) {
+		pr_err("move_focus failed at line %d ...\n", __LINE__);
+		return -EBUSY;
+	}
+
+	s5k4e1_ctrl->curr_lens_pos = next_position;
+	return 0;
+}
+
+static int32_t s5k4e1_set_default_focus(uint8_t af_step)
+{
+	int32_t rc = 0;
+
+	if (s5k4e1_ctrl->curr_step_pos != 0) {
+		rc = s5k4e1_move_focus(MOVE_FAR,
+				s5k4e1_ctrl->curr_step_pos);
+	} else {
+		s5k4e1_af_i2c_write_b_sensor(0x00, 0x00);
+	}
+
+	s5k4e1_ctrl->curr_lens_pos = 0;
+	s5k4e1_ctrl->curr_step_pos = 0;
+
+	return rc;
+}
+
+static int32_t s5k4e1_test(enum s5k4e1_test_mode_t mo)
+{
+	int32_t rc = 0;
+
+	if (mo != TEST_OFF)
+		rc = s5k4e1_i2c_write_b_sensor(0x0601, (uint8_t) mo);
+
+	return rc;
+}
+
+static void s5k4e1_reset_sensor(void)
+{
+	s5k4e1_i2c_write_b_sensor(0x103, 0x1);
+}
+
+static int32_t s5k4e1_sensor_setting(int update_type, int rt)
+{
+
+	int32_t rc = 0;
+	struct msm_camera_csi_params s5k4e1_csi_params;
+
+	s5k4e1_stop_stream();
+	msleep(30);
+
+	if (update_type == REG_INIT) {
+		s5k4e1_reset_sensor();
+		s5k4e1_i2c_write_b_table(s5k4e1_regs.reg_mipi,
+				s5k4e1_regs.reg_mipi_size);
+		s5k4e1_i2c_write_b_table(s5k4e1_regs.rec_settings,
+				s5k4e1_regs.rec_size);
+		s5k4e1_i2c_write_b_table(s5k4e1_regs.reg_pll_p,
+				s5k4e1_regs.reg_pll_p_size);
+		CSI_CONFIG = 0;
+	} else if (update_type == UPDATE_PERIODIC) {
+		if (rt == RES_PREVIEW)
+			s5k4e1_i2c_write_b_table(s5k4e1_regs.reg_prev,
+					s5k4e1_regs.reg_prev_size);
+		else
+			s5k4e1_i2c_write_b_table(s5k4e1_regs.reg_snap,
+					s5k4e1_regs.reg_snap_size);
+		msleep(20);
+		if (!CSI_CONFIG) {
+			msm_camio_vfe_clk_rate_set(192000000);
+			s5k4e1_csi_params.data_format = CSI_10BIT;
+			s5k4e1_csi_params.lane_cnt = 1;
+			s5k4e1_csi_params.lane_assign = 0xe4;
+			s5k4e1_csi_params.dpcm_scheme = 0;
+			s5k4e1_csi_params.settle_cnt = 24;
+			rc = msm_camio_csi_config(&s5k4e1_csi_params);
+			msleep(20);
+			CSI_CONFIG = 1;
+		}
+		s5k4e1_start_stream();
+		msleep(30);
+	}
+	return rc;
+}
+
+static int32_t s5k4e1_video_config(int mode)
+{
+
+	int32_t rc = 0;
+	int rt;
+	CDBG("video config\n");
+	/* change sensor resolution if needed */
+	if (s5k4e1_ctrl->prev_res == QTR_SIZE)
+		rt = RES_PREVIEW;
+	else
+		rt = RES_CAPTURE;
+	if (s5k4e1_sensor_setting(UPDATE_PERIODIC, rt) < 0)
+		return rc;
+	if (s5k4e1_ctrl->set_test) {
+		if (s5k4e1_test(s5k4e1_ctrl->set_test) < 0)
+			return  rc;
+	}
+
+	s5k4e1_ctrl->curr_res = s5k4e1_ctrl->prev_res;
+	s5k4e1_ctrl->sensormode = mode;
+	return rc;
+}
+
+static int32_t s5k4e1_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+	int rt;
+
+	/*change sensor resolution if needed */
+	if (s5k4e1_ctrl->curr_res != s5k4e1_ctrl->pict_res) {
+		if (s5k4e1_ctrl->pict_res == QTR_SIZE)
+			rt = RES_PREVIEW;
+		else
+			rt = RES_CAPTURE;
+		if (s5k4e1_sensor_setting(UPDATE_PERIODIC, rt) < 0)
+			return rc;
+	}
+
+	s5k4e1_ctrl->curr_res = s5k4e1_ctrl->pict_res;
+	s5k4e1_ctrl->sensormode = mode;
+	return rc;
+}
+
+static int32_t s5k4e1_raw_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+	int rt;
+
+	/* change sensor resolution if needed */
+	if (s5k4e1_ctrl->curr_res != s5k4e1_ctrl->pict_res) {
+		if (s5k4e1_ctrl->pict_res == QTR_SIZE)
+			rt = RES_PREVIEW;
+		else
+			rt = RES_CAPTURE;
+		if (s5k4e1_sensor_setting(UPDATE_PERIODIC, rt) < 0)
+			return rc;
+	}
+
+	s5k4e1_ctrl->curr_res = s5k4e1_ctrl->pict_res;
+	s5k4e1_ctrl->sensormode = mode;
+	return rc;
+}
+
+static int32_t s5k4e1_set_sensor_mode(int mode,
+		int res)
+{
+	int32_t rc = 0;
+
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		rc = s5k4e1_video_config(mode);
+		break;
+	case SENSOR_SNAPSHOT_MODE:
+		rc = s5k4e1_snapshot_config(mode);
+		break;
+	case SENSOR_RAW_SNAPSHOT_MODE:
+		rc = s5k4e1_raw_snapshot_config(mode);
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
+static int32_t s5k4e1_power_down(void)
+{
+	s5k4e1_stop_stream();
+	return 0;
+}
+
+static int s5k4e1_probe_init_done(const struct msm_camera_sensor_info *data)
+{
+	CDBG("probe done\n");
+	gpio_free(data->sensor_reset);
+	return 0;
+}
+
+static int s5k4e1_probe_init_sensor(const struct msm_camera_sensor_info *data)
+{
+	int32_t rc = 0;
+	uint16_t regaddress1 = 0x0000;
+	uint16_t regaddress2 = 0x0001;
+	uint16_t chipid1 = 0;
+	uint16_t chipid2 = 0;
+
+	CDBG("%s: %d\n", __func__, __LINE__);
+	CDBG(" s5k4e1_probe_init_sensor is called\n");
+
+	rc = gpio_request(data->sensor_reset, "s5k4e1");
+	CDBG(" s5k4e1_probe_init_sensor\n");
+	if (!rc) {
+		CDBG("sensor_reset = %d\n", rc);
+		gpio_direction_output(data->sensor_reset, 0);
+		msleep(50);
+		gpio_set_value_cansleep(data->sensor_reset, 1);
+		msleep(20);
+	} else
+		goto gpio_req_fail;
+
+	msleep(20);
+
+	s5k4e1_i2c_read(regaddress1, &chipid1, 1);
+	if (chipid1 != 0x4E) {
+		rc = -ENODEV;
+		CDBG("s5k4e1_probe_init_sensor fail chip id doesnot match\n");
+		goto init_probe_fail;
+	}
+
+	s5k4e1_i2c_read(regaddress2, &chipid2 , 1);
+	if (chipid2 != 0x10) {
+		rc = -ENODEV;
+		CDBG("s5k4e1_probe_init_sensor fail chip id doesnot match\n");
+		goto init_probe_fail;
+	}
+
+	CDBG("ID: %d\n", chipid1);
+	CDBG("ID: %d\n", chipid1);
+
+	return rc;
+
+init_probe_fail:
+	CDBG(" s5k4e1_probe_init_sensor fails\n");
+	gpio_set_value_cansleep(data->sensor_reset, 0);
+	s5k4e1_probe_init_done(data);
+	if (data->vcm_enable) {
+		int ret = gpio_request(data->vcm_pwd, "s5k4e1_af");
+		if (!ret) {
+			gpio_direction_output(data->vcm_pwd, 0);
+			msleep(20);
+			gpio_free(data->vcm_pwd);
+		}
+	}
+gpio_req_fail:
+	return rc;
+}
+
+int s5k4e1_sensor_open_init(const struct msm_camera_sensor_info *data)
+{
+	int32_t rc = 0;
+
+	CDBG("%s: %d\n", __func__, __LINE__);
+	CDBG("Calling s5k4e1_sensor_open_init\n");
+
+	s5k4e1_ctrl = kzalloc(sizeof(struct s5k4e1_ctrl_t), GFP_KERNEL);
+	if (!s5k4e1_ctrl) {
+		CDBG("s5k4e1_init failed!\n");
+		rc = -ENOMEM;
+		goto init_done;
+	}
+	s5k4e1_ctrl->fps_divider = 1 * 0x00000400;
+	s5k4e1_ctrl->pict_fps_divider = 1 * 0x00000400;
+	s5k4e1_ctrl->set_test = TEST_OFF;
+	s5k4e1_ctrl->prev_res = QTR_SIZE;
+	s5k4e1_ctrl->pict_res = FULL_SIZE;
+
+	if (data)
+		s5k4e1_ctrl->sensordata = data;
+
+	prev_frame_length_lines =
+	((s5k4e1_regs.reg_prev[S5K4E1_REG_PREV_FRAME_LEN_1].wdata << 8) |
+		s5k4e1_regs.reg_prev[S5K4E1_REG_PREV_FRAME_LEN_2].wdata);
+
+	prev_line_length_pck =
+	(s5k4e1_regs.reg_prev[S5K4E1_REG_PREV_LINE_LEN_1].wdata << 8) |
+		s5k4e1_regs.reg_prev[S5K4E1_REG_PREV_LINE_LEN_2].wdata;
+
+	snap_frame_length_lines =
+	(s5k4e1_regs.reg_snap[S5K4E1_REG_SNAP_FRAME_LEN_1].wdata << 8) |
+		s5k4e1_regs.reg_snap[S5K4E1_REG_SNAP_FRAME_LEN_2].wdata;
+
+	snap_line_length_pck =
+	(s5k4e1_regs.reg_snap[S5K4E1_REG_SNAP_LINE_LEN_1].wdata << 8) |
+		s5k4e1_regs.reg_snap[S5K4E1_REG_SNAP_LINE_LEN_1].wdata;
+
+	/* enable mclk first */
+	msm_camio_clk_rate_set(S5K4E1_MASTER_CLK_RATE);
+	rc = s5k4e1_probe_init_sensor(data);
+	if (rc < 0)
+		goto init_fail;
+
+	CDBG("init settings\n");
+	if (s5k4e1_ctrl->prev_res == QTR_SIZE)
+		rc = s5k4e1_sensor_setting(REG_INIT, RES_PREVIEW);
+	else
+		rc = s5k4e1_sensor_setting(REG_INIT, RES_CAPTURE);
+	s5k4e1_ctrl->fps = 30 * Q8;
+
+	/* enable AF actuator */
+	if (s5k4e1_ctrl->sensordata->vcm_enable) {
+		CDBG("enable AF actuator, gpio = %d\n",
+			 s5k4e1_ctrl->sensordata->vcm_pwd);
+		rc = gpio_request(s5k4e1_ctrl->sensordata->vcm_pwd,
+						"s5k4e1_af");
+		if (!rc)
+			gpio_direction_output(
+				s5k4e1_ctrl->sensordata->vcm_pwd,
+				 1);
+		else {
+			pr_err("s5k4e1_ctrl gpio request failed!\n");
+			goto init_fail;
+		}
+		msleep(20);
+		rc = s5k4e1_set_default_focus(0);
+		if (rc < 0) {
+			gpio_direction_output(s5k4e1_ctrl->sensordata->vcm_pwd,
+								0);
+			gpio_free(s5k4e1_ctrl->sensordata->vcm_pwd);
+		}
+	}
+	if (rc < 0)
+		goto init_fail;
+	else
+		goto init_done;
+init_fail:
+	CDBG("init_fail\n");
+	s5k4e1_probe_init_done(data);
+init_done:
+	CDBG("init_done\n");
+	return rc;
+}
+
+static int s5k4e1_init_client(struct i2c_client *client)
+{
+	/* Initialize the MSM_CAMI2C Chip */
+	init_waitqueue_head(&s5k4e1_wait_queue);
+	return 0;
+}
+
+static int s5k4e1_af_init_client(struct i2c_client *client)
+{
+	/* Initialize the MSM_CAMI2C Chip */
+	init_waitqueue_head(&s5k4e1_af_wait_queue);
+	return 0;
+}
+
+static const struct i2c_device_id s5k4e1_af_i2c_id[] = {
+	{"s5k4e1_af", 0},
+	{ }
+};
+
+static int s5k4e1_af_i2c_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	int rc = 0;
+	CDBG("s5k4e1_af_probe called!\n");
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		CDBG("i2c_check_functionality failed\n");
+		goto probe_failure;
+	}
+
+	s5k4e1_af_sensorw = kzalloc(sizeof(struct s5k4e1_work_t), GFP_KERNEL);
+	if (!s5k4e1_af_sensorw) {
+		CDBG("kzalloc failed.\n");
+		rc = -ENOMEM;
+		goto probe_failure;
+	}
+
+	i2c_set_clientdata(client, s5k4e1_af_sensorw);
+	s5k4e1_af_init_client(client);
+	s5k4e1_af_client = client;
+
+	msleep(50);
+
+	CDBG("s5k4e1_af_probe successed! rc = %d\n", rc);
+	return 0;
+
+probe_failure:
+	CDBG("s5k4e1_af_probe failed! rc = %d\n", rc);
+	return rc;
+}
+
+static const struct i2c_device_id s5k4e1_i2c_id[] = {
+	{"s5k4e1", 0},
+	{ }
+};
+
+static int s5k4e1_i2c_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	int rc = 0;
+	CDBG("s5k4e1_probe called!\n");
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		CDBG("i2c_check_functionality failed\n");
+		goto probe_failure;
+	}
+
+	s5k4e1_sensorw = kzalloc(sizeof(struct s5k4e1_work_t), GFP_KERNEL);
+	if (!s5k4e1_sensorw) {
+		CDBG("kzalloc failed.\n");
+		rc = -ENOMEM;
+		goto probe_failure;
+	}
+
+	i2c_set_clientdata(client, s5k4e1_sensorw);
+	s5k4e1_init_client(client);
+	s5k4e1_client = client;
+
+	msleep(50);
+
+	CDBG("s5k4e1_probe successed! rc = %d\n", rc);
+	return 0;
+
+probe_failure:
+	CDBG("s5k4e1_probe failed! rc = %d\n", rc);
+	return rc;
+}
+
+static int __devexit s5k4e1_remove(struct i2c_client *client)
+{
+	struct s5k4e1_work_t *sensorw = i2c_get_clientdata(client);
+	free_irq(client->irq, sensorw);
+	s5k4e1_client = NULL;
+	kfree(sensorw);
+	return 0;
+}
+
+static int __devexit s5k4e1_af_remove(struct i2c_client *client)
+{
+	struct s5k4e1_work_t *s5k4e1_af = i2c_get_clientdata(client);
+	free_irq(client->irq, s5k4e1_af);
+	s5k4e1_af_client = NULL;
+	kfree(s5k4e1_af);
+	return 0;
+}
+
+static struct i2c_driver s5k4e1_i2c_driver = {
+	.id_table = s5k4e1_i2c_id,
+	.probe  = s5k4e1_i2c_probe,
+	.remove = __exit_p(s5k4e1_i2c_remove),
+	.driver = {
+		.name = "s5k4e1",
+	},
+};
+
+static struct i2c_driver s5k4e1_af_i2c_driver = {
+	.id_table = s5k4e1_af_i2c_id,
+	.probe  = s5k4e1_af_i2c_probe,
+	.remove = __exit_p(s5k4e1_af_i2c_remove),
+	.driver = {
+		.name = "s5k4e1_af",
+	},
+};
+
+int s5k4e1_sensor_config(void __user *argp)
+{
+	struct sensor_cfg_data cdata;
+	long   rc = 0;
+	if (copy_from_user(&cdata,
+				(void *)argp,
+				sizeof(struct sensor_cfg_data)))
+		return -EFAULT;
+	mutex_lock(&s5k4e1_mut);
+	CDBG("s5k4e1_sensor_config: cfgtype = %d\n",
+			cdata.cfgtype);
+	switch (cdata.cfgtype) {
+	case CFG_GET_PICT_FPS:
+		s5k4e1_get_pict_fps(
+			cdata.cfg.gfps.prevfps,
+			&(cdata.cfg.gfps.pictfps));
+
+		if (copy_to_user((void *)argp,
+			&cdata,
+			sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+	case CFG_GET_PREV_L_PF:
+		cdata.cfg.prevl_pf =
+			s5k4e1_get_prev_lines_pf();
+
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+	case CFG_GET_PREV_P_PL:
+		cdata.cfg.prevp_pl =
+			s5k4e1_get_prev_pixels_pl();
+
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+	case CFG_GET_PICT_L_PF:
+		cdata.cfg.pictl_pf =
+			s5k4e1_get_pict_lines_pf();
+
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+	case CFG_GET_PICT_P_PL:
+		cdata.cfg.pictp_pl =
+			s5k4e1_get_pict_pixels_pl();
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+	case CFG_GET_PICT_MAX_EXP_LC:
+		cdata.cfg.pict_max_exp_lc =
+			s5k4e1_get_pict_max_exp_lc();
+
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+	case CFG_SET_FPS:
+	case CFG_SET_PICT_FPS:
+		rc = s5k4e1_set_fps(&(cdata.cfg.fps));
+		break;
+	case CFG_SET_EXP_GAIN:
+		rc = s5k4e1_write_exp_gain(cdata.cfg.exp_gain.gain,
+				cdata.cfg.exp_gain.line);
+		break;
+	case CFG_SET_PICT_EXP_GAIN:
+		rc = s5k4e1_set_pict_exp_gain(cdata.cfg.exp_gain.gain,
+				cdata.cfg.exp_gain.line);
+		break;
+	case CFG_SET_MODE:
+		rc = s5k4e1_set_sensor_mode(cdata.mode, cdata.rs);
+		break;
+	case CFG_PWR_DOWN:
+		rc = s5k4e1_power_down();
+		break;
+	case CFG_MOVE_FOCUS:
+		rc = s5k4e1_move_focus(cdata.cfg.focus.dir,
+				cdata.cfg.focus.steps);
+		break;
+	case CFG_SET_DEFAULT_FOCUS:
+		rc = s5k4e1_set_default_focus(cdata.cfg.focus.steps);
+		break;
+	case CFG_GET_AF_MAX_STEPS:
+		cdata.max_steps = S5K4E1_TOTAL_STEPS_NEAR_TO_FAR;
+		if (copy_to_user((void *)argp,
+					&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+	case CFG_SET_EFFECT:
+		rc = s5k4e1_set_default_focus(cdata.cfg.effect);
+		break;
+	default:
+		rc = -EFAULT;
+		break;
+	}
+	mutex_unlock(&s5k4e1_mut);
+
+	return rc;
+}
+
+static int s5k4e1_sensor_release(void)
+{
+	int rc = -EBADF;
+
+	mutex_lock(&s5k4e1_mut);
+	s5k4e1_power_down();
+	msleep(20);
+	gpio_set_value_cansleep(s5k4e1_ctrl->sensordata->sensor_reset, 0);
+	usleep_range(5000, 5100);
+	gpio_free(s5k4e1_ctrl->sensordata->sensor_reset);
+	if (s5k4e1_ctrl->sensordata->vcm_enable) {
+		gpio_set_value_cansleep(s5k4e1_ctrl->sensordata->vcm_pwd, 0);
+		gpio_free(s5k4e1_ctrl->sensordata->vcm_pwd);
+	}
+	kfree(s5k4e1_ctrl);
+	s5k4e1_ctrl = NULL;
+	CDBG("s5k4e1_release completed\n");
+	mutex_unlock(&s5k4e1_mut);
+
+	return rc;
+}
+
+static int s5k4e1_sensor_probe(const struct msm_camera_sensor_info *info,
+		struct msm_sensor_ctrl *s)
+{
+	int rc = 0;
+
+	rc = i2c_add_driver(&s5k4e1_i2c_driver);
+	if (rc < 0 || s5k4e1_client == NULL) {
+		rc = -ENOTSUPP;
+		CDBG("I2C add driver failed");
+		goto probe_fail_1;
+	}
+
+	rc = i2c_add_driver(&s5k4e1_af_i2c_driver);
+	if (rc < 0 || s5k4e1_af_client == NULL) {
+		rc = -ENOTSUPP;
+		CDBG("I2C add driver failed");
+		goto probe_fail_2;
+	}
+
+	msm_camio_clk_rate_set(S5K4E1_MASTER_CLK_RATE);
+
+	rc = s5k4e1_probe_init_sensor(info);
+	if (rc < 0)
+		goto probe_fail_3;
+
+	s->s_init = s5k4e1_sensor_open_init;
+	s->s_release = s5k4e1_sensor_release;
+	s->s_config  = s5k4e1_sensor_config;
+	s->s_mount_angle = info->sensor_platform_info->mount_angle;
+	gpio_set_value_cansleep(info->sensor_reset, 0);
+	s5k4e1_probe_init_done(info);
+	/* Keep vcm_pwd to OUT Low */
+	if (info->vcm_enable) {
+		rc = gpio_request(info->vcm_pwd, "s5k4e1_af");
+		if (!rc) {
+			gpio_direction_output(info->vcm_pwd, 0);
+			msleep(20);
+			gpio_free(info->vcm_pwd);
+		} else
+			return rc;
+	}
+	return rc;
+
+probe_fail_3:
+	i2c_del_driver(&s5k4e1_af_i2c_driver);
+probe_fail_2:
+	i2c_del_driver(&s5k4e1_i2c_driver);
+probe_fail_1:
+	CDBG("s5k4e1_sensor_probe: SENSOR PROBE FAILS!\n");
+	return rc;
+}
+
+static int __devinit s5k4e1_probe(struct platform_device *pdev)
+{
+	return msm_camera_drv_start(pdev, s5k4e1_sensor_probe);
+}
+
+static struct platform_driver msm_camera_driver = {
+	.probe = s5k4e1_probe,
+	.driver = {
+		.name = "msm_camera_s5k4e1",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init s5k4e1_init(void)
+{
+	return platform_driver_register(&msm_camera_driver);
+}
+
+module_init(s5k4e1_init);
+MODULE_DESCRIPTION("Samsung 5 MP Bayer sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/s5k4e1.h b/drivers/media/platform/msm/camera_v1/s5k4e1.h
new file mode 100644
index 0000000..d58b3f0
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/s5k4e1.h
@@ -0,0 +1,94 @@
+/* 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.
+ */
+
+#ifndef S5K4E1_H
+#define S5K4E1_H
+#include <linux/types.h>
+#include <mach/board.h>
+extern struct s5k4e1_reg s5k4e1_regs;
+
+struct s5k4e1_i2c_reg_conf {
+	unsigned short waddr;
+	unsigned short wdata;
+};
+
+enum s5k4e1_test_mode_t {
+	TEST_OFF,
+	TEST_1,
+	TEST_2,
+	TEST_3
+};
+
+enum s5k4e1_resolution_t {
+	QTR_SIZE,
+	FULL_SIZE,
+	INVALID_SIZE
+};
+enum s5k4e1_setting {
+	RES_PREVIEW,
+	RES_CAPTURE
+};
+enum s5k4e1_reg_update {
+	/* Sensor egisters that need to be updated during initialization */
+	REG_INIT,
+	/* Sensor egisters that needs periodic I2C writes */
+	UPDATE_PERIODIC,
+	/* All the sensor Registers will be updated */
+	UPDATE_ALL,
+	/* Not valid update */
+	UPDATE_INVALID
+};
+
+enum s5k4e1_reg_pll {
+	E013_VT_PIX_CLK_DIV,
+	E013_VT_SYS_CLK_DIV,
+	E013_PRE_PLL_CLK_DIV,
+	E013_PLL_MULTIPLIER,
+	E013_OP_PIX_CLK_DIV,
+	E013_OP_SYS_CLK_DIV
+};
+
+enum s5k4e1_reg_mode {
+	E013_X_ADDR_START,
+	E013_X_ADDR_END,
+	E013_Y_ADDR_START,
+	E013_Y_ADDR_END,
+	E013_X_OUTPUT_SIZE,
+	E013_Y_OUTPUT_SIZE,
+	E013_DATAPATH_SELECT,
+	E013_READ_MODE,
+	E013_ANALOG_CONTROL5,
+	E013_DAC_LD_4_5,
+	E013_SCALING_MODE,
+	E013_SCALE_M,
+	E013_LINE_LENGTH_PCK,
+	E013_FRAME_LENGTH_LINES,
+	E013_COARSE_INTEGRATION_TIME,
+	E013_FINE_INTEGRATION_TIME,
+	E013_FINE_CORRECTION
+};
+
+struct s5k4e1_reg {
+	const struct s5k4e1_i2c_reg_conf *reg_mipi;
+	const unsigned short reg_mipi_size;
+	const struct s5k4e1_i2c_reg_conf *rec_settings;
+	const unsigned short rec_size;
+	const struct s5k4e1_i2c_reg_conf *reg_pll_p;
+	const unsigned short reg_pll_p_size;
+	const struct s5k4e1_i2c_reg_conf *reg_pll_s;
+	const unsigned short reg_pll_s_size;
+	const struct s5k4e1_i2c_reg_conf *reg_prev;
+	const unsigned short reg_prev_size;
+	const struct s5k4e1_i2c_reg_conf *reg_snap;
+	const unsigned short reg_snap_size;
+};
+#endif /* S5K4E1_H */
diff --git a/drivers/media/platform/msm/camera_v1/s5k4e1_reg.c b/drivers/media/platform/msm/camera_v1/s5k4e1_reg.c
new file mode 100644
index 0000000..679ef17
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/s5k4e1_reg.c
@@ -0,0 +1,169 @@
+/* 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 "s5k4e1.h"
+
+struct s5k4e1_i2c_reg_conf s5k4e1_mipi_settings[] = {
+	{0x30BD, 0x00},/* SEL_CCP[0] */
+	{0x3084, 0x15},/* SYNC Mode */
+	{0x30BE, 0x1A},/* M_PCLKDIV_AUTO[4], M_DIV_PCLK[3:0] */
+	{0x30C1, 0x01},/* pack video enable [0] */
+	{0x30EE, 0x02},/* DPHY enable [ 1] */
+	{0x3111, 0x86},/* Embedded data off [5] */
+};
+
+/* PLL Configuration */
+struct s5k4e1_i2c_reg_conf s5k4e1_pll_preview_settings[] = {
+	{0x0305, 0x04},
+	{0x0306, 0x00},
+	{0x0307, 0x44},
+	{0x30B5, 0x00},
+	{0x30E2, 0x01},/* num lanes[1:0] = 2 */
+	{0x30F1, 0xB0},
+};
+
+struct s5k4e1_i2c_reg_conf s5k4e1_pll_snap_settings[] = {
+	{0x0305, 0x04},
+	{0x0306, 0x00},
+	{0x0307, 0x44},
+	{0x30B5, 0x00},
+	{0x30E2, 0x01},/* num lanes[1:0] = 2 */
+	{0x30F1, 0xB0},
+};
+
+struct s5k4e1_i2c_reg_conf s5k4e1_prev_settings[] = {
+	/* output size (1304 x 980) */
+	{0x30A9, 0x02},/* Horizontal Binning On */
+	{0x300E, 0xEB},/* Vertical Binning On */
+	{0x0387, 0x03},/* y_odd_inc 03(10b AVG) */
+	{0x0344, 0x00},/* x_addr_start 0 */
+	{0x0345, 0x00},
+	{0x0348, 0x0A},/* x_addr_end 2607 */
+	{0x0349, 0x2F},
+	{0x0346, 0x00},/* y_addr_start 0 */
+	{0x0347, 0x00},
+	{0x034A, 0x07},/* y_addr_end 1959 */
+	{0x034B, 0xA7},
+	{0x0380, 0x00},/* x_even_inc 1 */
+	{0x0381, 0x01},
+	{0x0382, 0x00},/* x_odd_inc 1 */
+	{0x0383, 0x01},
+	{0x0384, 0x00},/* y_even_inc 1 */
+	{0x0385, 0x01},
+	{0x0386, 0x00},/* y_odd_inc 3 */
+	{0x0387, 0x03},
+	{0x034C, 0x05},/* x_output_size 1304 */
+	{0x034D, 0x18},
+	{0x034E, 0x03},/* y_output_size 980 */
+	{0x034F, 0xd4},
+	{0x30BF, 0xAB},/* outif_enable[7], data_type[5:0](2Bh = bayer 10bit} */
+	{0x30C0, 0xA0},/* video_offset[7:4] 3260%12 */
+	{0x30C8, 0x06},/* video_data_length 1600 = 1304 * 1.25 */
+	{0x30C9, 0x5E},
+	/* Timing Configuration */
+	{0x0202, 0x03},
+	{0x0203, 0x14},
+	{0x0204, 0x00},
+	{0x0205, 0x80},
+	{0x0340, 0x03},/* Frame Length */
+	{0x0341, 0xE0},
+	{0x0342, 0x0A},/* 2738  Line Length */
+	{0x0343, 0xB2},
+};
+
+struct s5k4e1_i2c_reg_conf s5k4e1_snap_settings[] = {
+	/*Output Size (2608x1960)*/
+	{0x30A9, 0x03},/* Horizontal Binning Off */
+	{0x300E, 0xE8},/* Vertical Binning Off */
+	{0x0387, 0x01},/* y_odd_inc */
+	{0x034C, 0x0A},/* x_output size */
+	{0x034D, 0x30},
+	{0x034E, 0x07},/* y_output size */
+	{0x034F, 0xA8},
+	{0x30BF, 0xAB},/* outif_enable[7], data_type[5:0](2Bh = bayer 10bit} */
+	{0x30C0, 0x80},/* video_offset[7:4] 3260%12 */
+	{0x30C8, 0x0C},/* video_data_length 3260 = 2608 * 1.25 */
+	{0x30C9, 0xBC},
+	/*Timing configuration*/
+	{0x0202, 0x06},
+	{0x0203, 0x28},
+	{0x0204, 0x00},
+	{0x0205, 0x80},
+	{0x0340, 0x07},/* Frame Length */
+	{0x0341, 0xB4},
+	{0x0342, 0x0A},/* 2738 Line Length */
+	{0x0343, 0xB2},
+};
+
+struct s5k4e1_i2c_reg_conf s5k4e1_recommend_settings[] = {
+	/*CDS timing setting ... */
+	{0x3000, 0x05},
+	{0x3001, 0x03},
+	{0x3002, 0x08},
+	{0x3003, 0x0A},
+	{0x3004, 0x50},
+	{0x3005, 0x0E},
+	{0x3006, 0x5E},
+	{0x3007, 0x00},
+	{0x3008, 0x78},
+	{0x3009, 0x78},
+	{0x300A, 0x50},
+	{0x300B, 0x08},
+	{0x300C, 0x14},
+	{0x300D, 0x00},
+	{0x300E, 0xE8},
+	{0x300F, 0x82},
+	{0x301B, 0x77},
+
+	/* CDS option setting ... */
+	{0x3010, 0x00},
+	{0x3011, 0x3A},
+	{0x3029, 0x04},
+	{0x3012, 0x30},
+	{0x3013, 0xA0},
+	{0x3014, 0x00},
+	{0x3015, 0x00},
+	{0x3016, 0x30},
+	{0x3017, 0x94},
+	{0x3018, 0x70},
+	{0x301D, 0xD4},
+	{0x3021, 0x02},
+	{0x3022, 0x24},
+	{0x3024, 0x40},
+	{0x3027, 0x08},
+
+	/* Pixel option setting ...   */
+	{0x301C, 0x04},
+	{0x30D8, 0x3F},
+	{0x302B, 0x01},
+
+	{0x3070, 0x5F},
+	{0x3071, 0x00},
+	{0x3080, 0x04},
+	{0x3081, 0x38},
+};
+
+struct s5k4e1_reg s5k4e1_regs = {
+	.reg_mipi = &s5k4e1_mipi_settings[0],
+	.reg_mipi_size = ARRAY_SIZE(s5k4e1_mipi_settings),
+	.rec_settings = &s5k4e1_recommend_settings[0],
+	.rec_size = ARRAY_SIZE(s5k4e1_recommend_settings),
+	.reg_pll_p = &s5k4e1_pll_preview_settings[0],
+	.reg_pll_p_size = ARRAY_SIZE(s5k4e1_pll_preview_settings),
+	.reg_pll_s = &s5k4e1_pll_snap_settings[0],
+	.reg_pll_s_size = ARRAY_SIZE(s5k4e1_pll_snap_settings),
+	.reg_prev = &s5k4e1_prev_settings[0],
+	.reg_prev_size = ARRAY_SIZE(s5k4e1_prev_settings),
+	.reg_snap = &s5k4e1_snap_settings[0],
+	.reg_snap_size = ARRAY_SIZE(s5k4e1_snap_settings),
+};
diff --git a/drivers/media/platform/msm/camera_v1/sensors/Makefile b/drivers/media/platform/msm/camera_v1/sensors/Makefile
new file mode 100644
index 0000000..174e9ba
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/sensors/Makefile
@@ -0,0 +1,18 @@
+GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
+EXTRA_CFLAGS += -Idrivers/media/platform/msm/camera_v1
+EXTRA_CFLAGS += -Idrivers/media/platform/msm/camera_v1/io
+EXTRA_CFLAGS += -Idrivers/media/platform/msm/camera_v1/eeprom
+EXTRA_CFLAGS += -Idrivers/media/platform/msm/camera_v1/csi
+obj-$(CONFIG_MSM_CAMERA_SENSOR) += msm_sensor_common.o msm_sensor.o msm_sensor_bayer.o msm_sensor_init.o
+obj-$(CONFIG_OV5647) += ov5647_v4l2.o
+obj-$(CONFIG_OV8825) += ov8825_v4l2.o
+obj-$(CONFIG_IMX074) += imx074_v4l2.o
+obj-$(CONFIG_S5K3L1YX) += s5k3l1yx.o
+obj-$(CONFIG_IMX135) += imx135_v4l2.o
+obj-$(CONFIG_OV2720) += ov2720.o
+obj-$(CONFIG_MT9M114) += mt9m114_v4l2.o
+obj-$(CONFIG_S5K4E1) += s5k4e1_v4l2.o
+obj-$(CONFIG_MT9E013) += mt9e013_v4l2.o
+obj-$(CONFIG_WEBCAM_OV9726) += ov9726_v4l2.o
+obj-$(CONFIG_OV7692) += ov7692_v4l2.o
+obj-$(CONFIG_VX6953) += vx6953.o
diff --git a/drivers/media/platform/msm/camera_v1/sensors/imx074_v4l2.c b/drivers/media/platform/msm/camera_v1/sensors/imx074_v4l2.c
new file mode 100644
index 0000000..f0759a8
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/sensors/imx074_v4l2.c
@@ -0,0 +1,291 @@
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_sensor.h"
+#define SENSOR_NAME "imx074"
+#define PLATFORM_DRIVER_NAME "msm_camera_imx074"
+#define imx074_obj imx074_##obj
+
+DEFINE_MUTEX(imx074_mut);
+static struct msm_sensor_ctrl_t imx074_s_ctrl;
+
+static struct msm_camera_i2c_reg_conf imx074_start_settings[] = {
+	{0x0100, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf imx074_stop_settings[] = {
+	{0x0100, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf imx074_groupon_settings[] = {
+	{0x104, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf imx074_groupoff_settings[] = {
+	{0x104, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf imx074_prev_settings[] = {
+	{0x0307, 0x2D}, /*pll_multiplier*/
+	{0x0340, 0x06}, /*frame_length_lines_hi*/
+	{0x0341, 0x34}, /*frame_length_lines_lo*/
+	{0x0342, 0x11}, /*line_length_pclk_hi*/
+	{0x0343, 0x78}, /*line_length_pclk_lo*/
+	{0x0347, 0x00}, /*y_addr_start*/
+	{0x034b, 0x2F}, /*y_add_end*/
+	{0x034c, 0x08}, /*x_output_size_msb*/
+	{0x034d, 0x38}, /*x_output_size_lsb*/
+	{0x034e, 0x06}, /*y_output_size_msb*/
+	{0x034f, 0x18}, /*y_output_size_lsb*/
+	{0x0381, 0x01}, /*x_even_inc*/
+	{0x0383, 0x03}, /*x_odd_inc*/
+	{0x0385, 0x01}, /*y_even_inc*/
+	{0x0387, 0x03}, /*y_odd_inc*/
+	{0x3001, 0x80}, /*hmodeadd*/
+	{0x3016, 0x16}, /*vmodeadd*/
+	{0x3069, 0x24}, /*vapplinepos_start*/
+	{0x306b, 0x53}, /*vapplinepos_end*/
+	{0x3086, 0x00}, /*shutter*/
+	{0x30e8, 0x80}, /*haddave*/
+	{0x3301, 0x83}, /*lanesel*/
+};
+
+static struct msm_camera_i2c_reg_conf imx074_snap_settings[] = {
+	{0x0307, 0x26}, /*pll_multiplier*/
+	{0x0340, 0x0C}, /*frame_length_lines_hi*/
+	{0x0341, 0x90}, /*frame_length_lines_lo*/
+	{0x0342, 0x11}, /*line_length_pclk_hi*/
+	{0x0343, 0x78}, /*line_length_pclk_lo*/
+	{0x0347, 0x00}, /*y_addr_start*/
+	{0x034b, 0x2F}, /*y_add_end*/
+	{0x034c, 0x10}, /*x_output_size_msb*/
+	{0x034d, 0x70}, /*x_output_size_lsb*/
+	{0x034e, 0x0c}, /*y_output_size_msb*/
+	{0x034f, 0x30}, /*y_output_size_lsb*/
+	{0x0381, 0x01}, /*x_even_inc*/
+	{0x0383, 0x01}, /*x_odd_inc*/
+	{0x0385, 0x01}, /*y_even_inc*/
+	{0x0387, 0x01}, /*y_odd_inc*/
+	{0x3001, 0x00}, /*hmodeadd*/
+	{0x3016, 0x06}, /*vmodeadd*/
+	{0x3069, 0x24}, /*vapplinepos_start*/
+	{0x306b, 0x53}, /*vapplinepos_end*/
+	{0x3086, 0x00}, /*shutter*/
+	{0x30e8, 0x00}, /*haddave*/
+	{0x3301, 0x03}, /*lanesel*/
+};
+
+static struct msm_camera_i2c_reg_conf imx074_recommend_settings[] = {
+	{0x0305, 0x02},
+	{0x302b, 0x4B},
+	{0x3024, 0x03},
+	{0x0101, 0x00},
+	{0x300a, 0x80},
+	{0x3014, 0x08},
+	{0x3015, 0x37},
+	{0x301c, 0x01},
+	{0x302c, 0x05},
+	{0x3031, 0x26},
+	{0x3041, 0x60},
+	{0x3051, 0x24},
+	{0x3053, 0x34},
+	{0x3057, 0xc0},
+	{0x305c, 0x09},
+	{0x305d, 0x07},
+	{0x3060, 0x30},
+	{0x3065, 0x00},
+	{0x30aa, 0x08},
+	{0x30ab, 0x1c},
+	{0x30b0, 0x32},
+	{0x30b2, 0x83},
+	{0x30d3, 0x04},
+	{0x3106, 0x78},
+	{0x310c, 0x82},
+	{0x3304, 0x05},
+	{0x3305, 0x04},
+	{0x3306, 0x11},
+	{0x3307, 0x02},
+	{0x3308, 0x0c},
+	{0x3309, 0x06},
+	{0x330a, 0x08},
+	{0x330b, 0x04},
+	{0x330c, 0x08},
+	{0x330d, 0x06},
+	{0x330f, 0x01},
+	{0x3381, 0x00},
+};
+
+static struct v4l2_subdev_info imx074_subdev_info[] = {
+	{
+	.code   = V4L2_MBUS_FMT_SBGGR10_1X10,
+	.colorspace = V4L2_COLORSPACE_JPEG,
+	.fmt    = 1,
+	.order    = 0,
+	},
+	/* more can be supported, to be added later */
+};
+
+static struct msm_camera_i2c_conf_array imx074_init_conf[] = {
+	{&imx074_recommend_settings[0],
+	ARRAY_SIZE(imx074_recommend_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}
+};
+
+static struct msm_camera_i2c_conf_array imx074_confs[] = {
+	{&imx074_snap_settings[0],
+	ARRAY_SIZE(imx074_snap_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+	{&imx074_prev_settings[0],
+	ARRAY_SIZE(imx074_prev_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+};
+
+static struct msm_sensor_output_info_t imx074_dimensions[] = {
+	{
+		.x_output = 0x1070,
+		.y_output = 0xC30,
+		.line_length_pclk = 0x1178,
+		.frame_length_lines = 0xC90,
+		.vt_pixel_clk = 182400000,
+		.op_pixel_clk = 182400000,
+		.binning_factor = 1,
+	},
+	{
+		.x_output = 0x838,
+		.y_output = 0x618,
+		.line_length_pclk = 0x1178,
+		.frame_length_lines = 0x634,
+		.vt_pixel_clk = 216000000,
+		.op_pixel_clk = 108000000,
+		.binning_factor = 2,
+	},
+};
+
+static struct msm_sensor_output_reg_addr_t imx074_reg_addr = {
+	.x_output = 0x34C,
+	.y_output = 0x34E,
+	.line_length_pclk = 0x342,
+	.frame_length_lines = 0x340,
+};
+
+static struct msm_sensor_id_info_t imx074_id_info = {
+	.sensor_id_reg_addr = 0x0,
+	.sensor_id = 0x0074,
+};
+
+static struct msm_sensor_exp_gain_info_t imx074_exp_gain_info = {
+	.coarse_int_time_addr = 0x202,
+	.global_gain_addr = 0x204,
+	.vert_offset = 3,
+};
+
+static enum msm_camera_vreg_name_t imx074_veg_seq[] = {
+	CAM_VDIG,
+	CAM_VIO,
+	CAM_VANA,
+	CAM_VAF,
+};
+
+static const struct i2c_device_id imx074_i2c_id[] = {
+	{SENSOR_NAME, (kernel_ulong_t)&imx074_s_ctrl},
+	{ }
+};
+
+static struct i2c_driver imx074_i2c_driver = {
+	.id_table = imx074_i2c_id,
+	.probe  = msm_sensor_i2c_probe,
+	.driver = {
+		.name = SENSOR_NAME,
+	},
+};
+
+static struct msm_camera_i2c_client imx074_sensor_i2c_client = {
+	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+static int __init msm_sensor_init_module(void)
+{
+	return i2c_add_driver(&imx074_i2c_driver);
+}
+
+static struct v4l2_subdev_core_ops imx074_subdev_core_ops = {
+	.ioctl = msm_sensor_subdev_ioctl,
+	.s_power = msm_sensor_power,
+};
+
+static struct v4l2_subdev_video_ops imx074_subdev_video_ops = {
+	.enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
+};
+
+static struct v4l2_subdev_ops imx074_subdev_ops = {
+	.core = &imx074_subdev_core_ops,
+	.video  = &imx074_subdev_video_ops,
+};
+
+static struct msm_sensor_fn_t imx074_func_tbl = {
+	.sensor_start_stream = msm_sensor_start_stream,
+	.sensor_stop_stream = msm_sensor_stop_stream,
+	.sensor_group_hold_on = msm_sensor_group_hold_on,
+	.sensor_group_hold_off = msm_sensor_group_hold_off,
+	.sensor_set_fps = msm_sensor_set_fps,
+	.sensor_write_exp_gain = msm_sensor_write_exp_gain1,
+	.sensor_write_snapshot_exp_gain = msm_sensor_write_exp_gain1,
+	.sensor_setting = msm_sensor_setting,
+	.sensor_csi_setting = msm_sensor_setting1,
+	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
+	.sensor_mode_init = msm_sensor_mode_init,
+	.sensor_get_output_info = msm_sensor_get_output_info,
+	.sensor_config = msm_sensor_config,
+	.sensor_power_up = msm_sensor_power_up,
+	.sensor_power_down = msm_sensor_power_down,
+	.sensor_adjust_frame_lines = msm_sensor_adjust_frame_lines1,
+	.sensor_get_csi_params = msm_sensor_get_csi_params,
+};
+
+static struct msm_sensor_reg_t imx074_regs = {
+	.default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
+	.start_stream_conf = imx074_start_settings,
+	.start_stream_conf_size = ARRAY_SIZE(imx074_start_settings),
+	.stop_stream_conf = imx074_stop_settings,
+	.stop_stream_conf_size = ARRAY_SIZE(imx074_stop_settings),
+	.group_hold_on_conf = imx074_groupon_settings,
+	.group_hold_on_conf_size = ARRAY_SIZE(imx074_groupon_settings),
+	.group_hold_off_conf = imx074_groupoff_settings,
+	.group_hold_off_conf_size =
+		ARRAY_SIZE(imx074_groupoff_settings),
+	.init_settings = &imx074_init_conf[0],
+	.init_size = ARRAY_SIZE(imx074_init_conf),
+	.mode_settings = &imx074_confs[0],
+	.output_settings = &imx074_dimensions[0],
+	.num_conf = ARRAY_SIZE(imx074_confs),
+};
+
+static struct msm_sensor_ctrl_t imx074_s_ctrl = {
+	.msm_sensor_reg = &imx074_regs,
+	.sensor_i2c_client = &imx074_sensor_i2c_client,
+	.sensor_i2c_addr = 0x34,
+	.vreg_seq = imx074_veg_seq,
+	.num_vreg_seq = ARRAY_SIZE(imx074_veg_seq),
+	.sensor_output_reg_addr = &imx074_reg_addr,
+	.sensor_id_info = &imx074_id_info,
+	.sensor_exp_gain_info = &imx074_exp_gain_info,
+	.cam_mode = MSM_SENSOR_MODE_INVALID,
+	.msm_sensor_mutex = &imx074_mut,
+	.sensor_i2c_driver = &imx074_i2c_driver,
+	.sensor_v4l2_subdev_info = imx074_subdev_info,
+	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(imx074_subdev_info),
+	.sensor_v4l2_subdev_ops = &imx074_subdev_ops,
+	.func_tbl = &imx074_func_tbl,
+	.clk_rate = MSM_SENSOR_MCLK_24HZ,
+};
+
+module_init(msm_sensor_init_module);
+MODULE_DESCRIPTION("Sony 13MP Bayer sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/sensors/imx091.h b/drivers/media/platform/msm/camera_v1/sensors/imx091.h
new file mode 100644
index 0000000..a909138
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/sensors/imx091.h
@@ -0,0 +1,102 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#define IMX091_SENSOR_NAME "imx091"
+DEFINE_MSM_MUTEX(imx091_mut);
+
+static struct msm_sensor_ctrl_t imx091_s_ctrl;
+
+static struct v4l2_subdev_info imx091_subdev_info[] = {
+	{
+	.code   = V4L2_MBUS_FMT_SBGGR10_1X10,
+	.colorspace = V4L2_COLORSPACE_JPEG,
+	.fmt    = 1,
+	.order    = 0,
+	},
+	/* more can be supported, to be added later */
+};
+
+static struct msm_sensor_id_info_t imx091_id_info = {
+	.sensor_id_reg_addr = 0x0000,
+	.sensor_id = 0x0091,
+};
+
+static enum msm_camera_vreg_name_t imx091_veg_seq[] = {
+	CAM_VANA,
+	CAM_VAF,
+	CAM_VDIG,
+	CAM_VIO,
+};
+
+static struct msm_camera_power_seq_t imx091_power_seq[] = {
+	{REQUEST_GPIO, 0},
+	{REQUEST_VREG, 0},
+	{ENABLE_VREG, 0},
+	{ENABLE_GPIO, 0},
+	{CONFIG_CLK, 1},
+	{CONFIG_I2C_MUX, 0},
+};
+
+static const struct i2c_device_id imx091_i2c_id[] = {
+	{IMX091_SENSOR_NAME, (kernel_ulong_t)&imx091_s_ctrl},
+	{ }
+};
+
+static struct i2c_driver imx091_i2c_driver = {
+	.id_table = imx091_i2c_id,
+	.probe  = msm_sensor_bayer_i2c_probe,
+	.driver = {
+		.name = IMX091_SENSOR_NAME,
+	},
+};
+
+static struct msm_camera_i2c_client imx091_sensor_i2c_client = {
+	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+static struct v4l2_subdev_core_ops imx091_subdev_core_ops = {
+	.ioctl = msm_sensor_bayer_subdev_ioctl,
+	.s_power = msm_sensor_bayer_power,
+};
+
+static struct v4l2_subdev_video_ops imx091_subdev_video_ops = {
+	.enum_mbus_fmt = msm_sensor_bayer_v4l2_enum_fmt,
+};
+
+static struct v4l2_subdev_ops imx091_subdev_ops = {
+	.core = &imx091_subdev_core_ops,
+	.video  = &imx091_subdev_video_ops,
+};
+
+static struct msm_sensor_fn_t imx091_func_tbl = {
+	.sensor_config = msm_sensor_bayer_config,
+	.sensor_power_up = msm_sensor_bayer_power_up,
+	.sensor_power_down = msm_sensor_bayer_power_down,
+	.sensor_get_csi_params = msm_sensor_bayer_get_csi_params,
+	.sensor_read_eeprom = msm_sensor_bayer_eeprom_read,
+};
+
+static struct msm_sensor_ctrl_t imx091_s_ctrl = {
+	.sensor_i2c_client = &imx091_sensor_i2c_client,
+	.sensor_i2c_addr = 0x34,
+	.vreg_seq = imx091_veg_seq,
+	.num_vreg_seq = ARRAY_SIZE(imx091_veg_seq),
+	.power_seq = &imx091_power_seq[0],
+	.num_power_seq = ARRAY_SIZE(imx091_power_seq),
+	.sensor_id_info = &imx091_id_info,
+	.msm_sensor_mutex = &imx091_mut,
+	.sensor_v4l2_subdev_info = imx091_subdev_info,
+	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(imx091_subdev_info),
+	.sensor_v4l2_subdev_ops = &imx091_subdev_ops,
+	.func_tbl = &imx091_func_tbl,
+	.clk_rate = MSM_SENSOR_MCLK_24HZ,
+};
diff --git a/drivers/media/platform/msm/camera_v1/sensors/imx135_v4l2.c b/drivers/media/platform/msm/camera_v1/sensors/imx135_v4l2.c
new file mode 100644
index 0000000..98e2999
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/sensors/imx135_v4l2.c
@@ -0,0 +1,1289 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_sensor.h"
+#define SENSOR_NAME "imx135"
+#define PLATFORM_DRIVER_NAME "msm_camera_imx135"
+#define imx135_obj imx135_##obj
+
+DEFINE_MUTEX(imx135_mut);
+static struct msm_sensor_ctrl_t imx135_s_ctrl;
+
+static struct msm_camera_i2c_reg_conf imx135_start_settings[] = {
+	{0x0100, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf imx135_stop_settings[] = {
+	{0x0100, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf imx135_groupon_settings[] = {
+	{0x104, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf imx135_groupoff_settings[] = {
+	{0x104, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf imx135_recommend_settings[] = {
+/* Global Settings */
+	{0x0101, 0x00},
+	{0x0105, 0x01},
+	{0x0110, 0x00},
+	{0x0220, 0x01},
+	{0x3302, 0x11},
+	{0x3833, 0x20},
+	{0x3893, 0x00},
+	{0x3906, 0x08},
+	{0x3907, 0x01},
+	{0x391B, 0x01},
+	{0x3C09, 0x01},
+	{0x600A, 0x00},
+	{0x3008, 0xB0},
+	{0x320A, 0x01},
+	{0x320D, 0x10},
+	{0x3216, 0x2E},
+	{0x322C, 0x02},
+	{0x3409, 0x0C},
+	{0x340C, 0x2D},
+	{0x3411, 0x39},
+	{0x3414, 0x1E},
+	{0x3427, 0x04},
+	{0x3480, 0x1E},
+	{0x3484, 0x1E},
+	{0x3488, 0x1E},
+	{0x348C, 0x1E},
+	{0x3490, 0x1E},
+	{0x3494, 0x1E},
+	{0x3511, 0x8F},
+	{0x364F, 0x2D},
+	/*Defect Correction Recommended Setting */
+	{0x380A, 0x00},
+	{0x380B, 0x00},
+	{0x4103, 0x00},
+	/*Color Artifact Recommended Setting */
+	{0x4243, 0x9A},
+	{0x4330, 0x01},
+	{0x4331, 0x90},
+	{0x4332, 0x02},
+	{0x4333, 0x58},
+	{0x4334, 0x03},
+	{0x4335, 0x20},
+	{0x4336, 0x03},
+	{0x4337, 0x84},
+	{0x433C, 0x01},
+	{0x4340, 0x02},
+	{0x4341, 0x58},
+	{0x4342, 0x03},
+	{0x4343, 0x52},
+	/*Moiré reduction Parameter Setting	*/
+	{0x4364, 0x0B},
+	{0x4368, 0x00},
+	{0x4369, 0x0F},
+	{0x436A, 0x03},
+	{0x436B, 0xA8},
+	{0x436C, 0x00},
+	{0x436D, 0x00},
+	{0x436E, 0x00},
+	{0x436F, 0x06},
+	/*CNR parameter setting	*/
+	{0x4281, 0x21},
+	{0x4282, 0x18},
+	{0x4283, 0x04},
+	{0x4284, 0x08},
+	{0x4287, 0x7F},
+	{0x4288, 0x08},
+	{0x428B, 0x7F},
+	{0x428C, 0x08},
+	{0x428F, 0x7F},
+	{0x4297, 0x00},
+	{0x4298, 0x7E},
+	{0x4299, 0x7E},
+	{0x429A, 0x7E},
+	{0x42A4, 0xFB},
+	{0x42A5, 0x7E},
+	{0x42A6, 0xDF},
+	{0x42A7, 0xB7},
+	{0x42AF, 0x03},
+	/*ARNR Parameter Setting*/
+	{0x4207, 0x03},
+	{0x4216, 0x08},
+	{0x4217, 0x08},
+	/*DLC Parameter Setting*/
+	{0x4218, 0x00},
+	{0x421B, 0x20},
+	{0x421F, 0x04},
+	{0x4222, 0x02},
+	{0x4223, 0x22},
+	{0x422E, 0x54},
+	{0x422F, 0xFB},
+	{0x4230, 0xFF},
+	{0x4231, 0xFE},
+	{0x4232, 0xFF},
+	{0x4235, 0x58},
+	{0x4236, 0xF7},
+	{0x4237, 0xFD},
+	{0x4239, 0x4E},
+	{0x423A, 0xFC},
+	{0x423B, 0xFD},
+	/*HDR Setting*/
+	{0x4300, 0x00},
+	{0x4316, 0x12},
+	{0x4317, 0x22},
+	{0x4318, 0x00},
+	{0x4319, 0x00},
+	{0x431A, 0x00},
+	{0x4324, 0x03},
+	{0x4325, 0x20},
+	{0x4326, 0x03},
+	{0x4327, 0x84},
+	{0x4328, 0x03},
+	{0x4329, 0x20},
+	{0x432A, 0x03},
+	{0x432B, 0x20},
+	{0x432C, 0x01},
+	{0x432D, 0x01},
+	{0x4338, 0x02},
+	{0x4339, 0x00},
+	{0x433A, 0x00},
+	{0x433B, 0x02},
+	{0x435A, 0x03},
+	{0x435B, 0x84},
+	{0x435E, 0x01},
+	{0x435F, 0xFF},
+	{0x4360, 0x01},
+	{0x4361, 0xF4},
+	{0x4362, 0x03},
+	{0x4363, 0x84},
+	{0x437B, 0x01},
+	{0x4401, 0x03}, /*0x3F*/
+	{0x4402, 0xFF},
+	{0x4404, 0x13},
+	{0x4405, 0x26},
+	{0x4406, 0x07},
+	{0x4408, 0x20},
+	{0x4409, 0xE5},
+	{0x440A, 0xFB},
+	{0x440C, 0xF6},
+	{0x440D, 0xEA},
+	{0x440E, 0x20},
+	{0x4410, 0x00},
+	{0x4411, 0x00},
+	{0x4412, 0x3F},
+	{0x4413, 0xFF},
+	{0x4414, 0x1F},
+	{0x4415, 0xFF},
+	{0x4416, 0x20},
+	{0x4417, 0x00},
+	{0x4418, 0x1F},
+	{0x4419, 0xFF},
+	{0x441A, 0x20},
+	{0x441B, 0x00},
+	{0x441D, 0x40},
+	{0x441E, 0x1E},
+	{0x441F, 0x38},
+	{0x4420, 0x01},
+	{0x4444, 0x00},
+	{0x4445, 0x00},
+	{0x4446, 0x1D},
+	{0x4447, 0xF9},
+	{0x4452, 0x00},
+	{0x4453, 0xA0},
+	{0x4454, 0x08},
+	{0x4455, 0x00},
+	{0x4456, 0x0F},
+	{0x4457, 0xFF},
+	{0x4458, 0x18},
+	{0x4459, 0x18},
+	{0x445A, 0x3F},
+	{0x445B, 0x3A},
+	{0x445C, 0x00},
+	{0x445D, 0x28},
+	{0x445E, 0x01},
+	{0x445F, 0x90},
+	{0x4460, 0x00},
+	{0x4461, 0x60},
+	{0x4462, 0x00},
+	{0x4463, 0x00},
+	{0x4464, 0x00},
+	{0x4465, 0x00},
+	{0x446C, 0x00},
+	{0x446D, 0x00},
+	{0x446E, 0x00},
+	/*LSC Setting*/
+	{0x452A, 0x02},
+	/*White Balance Setting */
+	{0x0712, 0x01},
+	{0x0713, 0x00},
+	{0x0714, 0x01},
+	{0x0715, 0x00},
+	{0x0716, 0x01},
+	{0x0717, 0x00},
+	{0x0718, 0x01},
+	{0x0719, 0x00},
+	/*Shading setting*/
+	{0x4500, 0x1F},
+};
+
+static struct msm_camera_i2c_reg_conf imx135_prev_settings[] = {
+	/* Clock Setting */
+	{0x011E, 0x18},
+	{0x011F, 0x00},
+	{0x0301, 0x05},
+	{0x0303, 0x01},
+	{0x0305, 0x03},
+	{0x0309, 0x05},
+	{0x030B, 0x02},
+	{0x030C, 0x00},
+	{0x030D, 0x71},
+	{0x030E, 0x01},
+	{0x3A06, 0x12},
+	/* Mode setting */
+	{0x0108, 0x03},
+	{0x0112, 0x0A},
+	{0x0113, 0x0A},
+	{0x0381, 0x01},
+	{0x0383, 0x01},
+	{0x0385, 0x01},
+	{0x0387, 0x01},
+	{0x0390, 0x01},
+	{0x0391, 0x22},
+	{0x0392, 0x00},
+	{0x0401, 0x00},
+	{0x0404, 0x00},
+	{0x0405, 0x10},
+	{0x4082, 0x01},
+	{0x4083, 0x01},
+	{0x7006, 0x04},
+	/* OptionalFunction setting */
+	{0x0700, 0x00},
+	{0x3A63, 0x00},
+	{0x4100, 0xF8},
+	{0x4203, 0xFF},
+	{0x4344, 0x00},
+	{0x441C, 0x01},
+	/* Size setting	*/
+	{0x0340, 0x06},
+	{0x0341, 0x2E},
+	{0x0342, 0x11},
+	{0x0343, 0xDC},
+	{0x0344, 0x00},
+	{0x0345, 0x00},
+	{0x0346, 0x00},
+	{0x0347, 0x00},
+	{0x0348, 0x10},
+	{0x0349, 0x6F},
+	{0x034A, 0x0C},
+	{0x034B, 0x2F},
+	{0x034C, 0x08},
+	{0x034D, 0x38},
+	{0x034E, 0x06},
+	{0x034F, 0x18},
+	{0x0350, 0x00},
+	{0x0351, 0x00},
+	{0x0352, 0x00},
+	{0x0353, 0x00},
+	{0x0354, 0x08},
+	{0x0355, 0x38},
+	{0x0356, 0x06},
+	{0x0357, 0x18},
+	{0x301D, 0x30},
+	{0x3310, 0x08},
+	{0x3311, 0x38},
+	{0x3312, 0x06},
+	{0x3313, 0x18},
+	{0x331C, 0x00},
+	{0x331D, 0x52},
+	{0x4084, 0x00},
+	{0x4085, 0x00},
+	{0x4086, 0x00},
+	{0x4087, 0x00},
+	{0x4400, 0x00},
+	/* Global Timing Setting */
+	{0x0830, 0x67},
+	{0x0831, 0x27},
+	{0x0832, 0x47},
+	{0x0833, 0x27},
+	{0x0834, 0x27},
+	{0x0835, 0x1F},
+	{0x0836, 0x87},
+	{0x0837, 0x2F},
+	{0x0839, 0x1F},
+	{0x083A, 0x17},
+	{0x083B, 0x02},
+	/* Integration Time Setting */
+	{0x0202, 0x06},
+	{0x0203, 0x2A},
+	/* Gain Setting	*/
+	{0x0205, 0x00},
+	{0x020E, 0x01},
+	{0x020F, 0x00},
+	{0x0210, 0x01},
+	{0x0211, 0x00},
+	{0x0212, 0x01},
+	{0x0213, 0x00},
+	{0x0214, 0x01},
+	{0x0215, 0x00},
+	/* HDR Setting */
+	{0x0230, 0x00},
+	{0x0231, 0x00},
+	{0x0233, 0x00},
+	{0x0234, 0x00},
+	{0x0235, 0x40},
+	{0x0238, 0x00},
+	{0x0239, 0x04},
+	{0x023B, 0x00},
+	{0x023C, 0x01},
+	{0x33B0, 0x04},
+	{0x33B1, 0x00},
+	{0x33B3, 0x00},
+	{0x33B4, 0x00},
+	{0x3800, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf imx135_LSCTable_settings[] = {
+	{0x4800, 0x02},
+	{0x4801, 0x68},
+	{0x4802, 0x02},
+	{0x4803, 0x4f},
+	{0x4804, 0x02},
+	{0x4805, 0x10},
+	{0x4806, 0x01},
+	{0x4807, 0xf3},
+	{0x4808, 0x01},
+	{0x4809, 0xc3},
+	{0x480a, 0x01},
+	{0x480b, 0xb3},
+	{0x480c, 0x01},
+	{0x480d, 0x9a},
+	{0x480e, 0x01},
+	{0x480f, 0x8e},
+	{0x4810, 0x01},
+	{0x4811, 0x84},
+	{0x4812, 0x01},
+	{0x4813, 0x7f},
+	{0x4814, 0x01},
+	{0x4815, 0x94},
+	{0x4816, 0x01},
+	{0x4817, 0x8a},
+	{0x4818, 0x01},
+	{0x4819, 0xb7},
+	{0x481a, 0x01},
+	{0x481b, 0xa6},
+	{0x481c, 0x01},
+	{0x481d, 0xf9},
+	{0x481e, 0x01},
+	{0x481f, 0xe2},
+	{0x4820, 0x02},
+	{0x4821, 0x62},
+	{0x4822, 0x02},
+	{0x4823, 0x37},
+	{0x4824, 0x02},
+	{0x4825, 0x26},
+	{0x4826, 0x02},
+	{0x4827, 0x0c},
+	{0x4828, 0x01},
+	{0x4829, 0xbb},
+	{0x482a, 0x01},
+	{0x482b, 0xaf},
+	{0x482c, 0x01},
+	{0x482d, 0x7c},
+	{0x482e, 0x01},
+	{0x482f, 0x70},
+	{0x4830, 0x01},
+	{0x4831, 0x50},
+	{0x4832, 0x01},
+	{0x4833, 0x4b},
+	{0x4834, 0x01},
+	{0x4835, 0x3e},
+	{0x4836, 0x01},
+	{0x4837, 0x39},
+	{0x4838, 0x01},
+	{0x4839, 0x4c},
+	{0x483a, 0x01},
+	{0x483b, 0x45},
+	{0x483c, 0x01},
+	{0x483d, 0x74},
+	{0x483e, 0x01},
+	{0x483f, 0x63},
+	{0x4840, 0x01},
+	{0x4841, 0xae},
+	{0x4842, 0x01},
+	{0x4843, 0x97},
+	{0x4844, 0x02},
+	{0x4845, 0x07},
+	{0x4846, 0x01},
+	{0x4847, 0xeb},
+	{0x4848, 0x01},
+	{0x4849, 0xf6},
+	{0x484a, 0x01},
+	{0x484b, 0xdf},
+	{0x484c, 0x01},
+	{0x484d, 0x93},
+	{0x484e, 0x01},
+	{0x484f, 0x8d},
+	{0x4850, 0x01},
+	{0x4851, 0x50},
+	{0x4852, 0x01},
+	{0x4853, 0x4b},
+	{0x4854, 0x01},
+	{0x4855, 0x22},
+	{0x4856, 0x01},
+	{0x4857, 0x20},
+	{0x4858, 0x01},
+	{0x4859, 0x10},
+	{0x485a, 0x01},
+	{0x485b, 0x0e},
+	{0x485c, 0x01},
+	{0x485d, 0x1d},
+	{0x485e, 0x01},
+	{0x485f, 0x18},
+	{0x4860, 0x01},
+	{0x4861, 0x48},
+	{0x4862, 0x01},
+	{0x4863, 0x3f},
+	{0x4864, 0x01},
+	{0x4865, 0x85},
+	{0x4866, 0x01},
+	{0x4867, 0x7b},
+	{0x4868, 0x01},
+	{0x4869, 0xd9},
+	{0x486a, 0x01},
+	{0x486b, 0xc5},
+	{0x486c, 0x01},
+	{0x486d, 0xdf},
+	{0x486e, 0x01},
+	{0x486f, 0xcf},
+	{0x4870, 0x01},
+	{0x4871, 0x87},
+	{0x4872, 0x01},
+	{0x4873, 0x7f},
+	{0x4874, 0x01},
+	{0x4875, 0x3d},
+	{0x4876, 0x01},
+	{0x4877, 0x3a},
+	{0x4878, 0x01},
+	{0x4879, 0x10},
+	{0x487a, 0x01},
+	{0x487b, 0x0e},
+	{0x487c, 0x01},
+	{0x487d, 0x00},
+	{0x487e, 0x01},
+	{0x487f, 0x00},
+	{0x4880, 0x01},
+	{0x4881, 0x0a},
+	{0x4882, 0x01},
+	{0x4883, 0x07},
+	{0x4884, 0x01},
+	{0x4885, 0x34},
+	{0x4886, 0x01},
+	{0x4887, 0x2f},
+	{0x4888, 0x01},
+	{0x4889, 0x77},
+	{0x488a, 0x01},
+	{0x488b, 0x69},
+	{0x488c, 0x01},
+	{0x488d, 0xcc},
+	{0x488e, 0x01},
+	{0x488f, 0xb9},
+	{0x4890, 0x01},
+	{0x4891, 0xea},
+	{0x4892, 0x01},
+	{0x4893, 0xdf},
+	{0x4894, 0x01},
+	{0x4895, 0x93},
+	{0x4896, 0x01},
+	{0x4897, 0x86},
+	{0x4898, 0x01},
+	{0x4899, 0x4c},
+	{0x489a, 0x01},
+	{0x489b, 0x48},
+	{0x489c, 0x01},
+	{0x489d, 0x20},
+	{0x489e, 0x01},
+	{0x489f, 0x1c},
+	{0x48a0, 0x01},
+	{0x48a1, 0x0d},
+	{0x48a2, 0x01},
+	{0x48a3, 0x09},
+	{0x48a4, 0x01},
+	{0x48a5, 0x1a},
+	{0x48a6, 0x01},
+	{0x48a7, 0x15},
+	{0x48a8, 0x01},
+	{0x48a9, 0x43},
+	{0x48aa, 0x01},
+	{0x48ab, 0x3d},
+	{0x48ac, 0x01},
+	{0x48ad, 0x84},
+	{0x48ae, 0x01},
+	{0x48af, 0x75},
+	{0x48b0, 0x01},
+	{0x48b1, 0xd3},
+	{0x48b2, 0x01},
+	{0x48b3, 0xbf},
+	{0x48b4, 0x02},
+	{0x48b5, 0x23},
+	{0x48b6, 0x02},
+	{0x48b7, 0x07},
+	{0x48b8, 0x01},
+	{0x48b9, 0xbc},
+	{0x48ba, 0x01},
+	{0x48bb, 0xac},
+	{0x48bc, 0x01},
+	{0x48bd, 0x7a},
+	{0x48be, 0x01},
+	{0x48bf, 0x6f},
+	{0x48c0, 0x01},
+	{0x48c1, 0x4c},
+	{0x48c2, 0x01},
+	{0x48c3, 0x47},
+	{0x48c4, 0x01},
+	{0x48c5, 0x3d},
+	{0x48c6, 0x01},
+	{0x48c7, 0x37},
+	{0x48c8, 0x01},
+	{0x48c9, 0x48},
+	{0x48ca, 0x01},
+	{0x48cb, 0x40},
+	{0x48cc, 0x01},
+	{0x48cd, 0x70},
+	{0x48ce, 0x01},
+	{0x48cf, 0x61},
+	{0x48d0, 0x01},
+	{0x48d1, 0xab},
+	{0x48d2, 0x01},
+	{0x48d3, 0x9a},
+	{0x48d4, 0x02},
+	{0x48d5, 0x03},
+	{0x48d6, 0x01},
+	{0x48d7, 0xe6},
+	{0x48d8, 0x02},
+	{0x48d9, 0x71},
+	{0x48da, 0x02},
+	{0x48db, 0x4a},
+	{0x48dc, 0x02},
+	{0x48dd, 0x07},
+	{0x48de, 0x01},
+	{0x48df, 0xef},
+	{0x48e0, 0x01},
+	{0x48e1, 0xbf},
+	{0x48e2, 0x01},
+	{0x48e3, 0xae},
+	{0x48e4, 0x01},
+	{0x48e5, 0x97},
+	{0x48e6, 0x01},
+	{0x48e7, 0x89},
+	{0x48e8, 0x01},
+	{0x48e9, 0x82},
+	{0x48ea, 0x01},
+	{0x48eb, 0x7a},
+	{0x48ec, 0x01},
+	{0x48ed, 0x91},
+	{0x48ee, 0x01},
+	{0x48ef, 0x83},
+	{0x48f0, 0x01},
+	{0x48f1, 0xb7},
+	{0x48f2, 0x01},
+	{0x48f3, 0xa9},
+	{0x48f4, 0x01},
+	{0x48f5, 0xf0},
+	{0x48f6, 0x01},
+	{0x48f7, 0xd9},
+	{0x48f8, 0x02},
+	{0x48f9, 0x55},
+	{0x48fa, 0x02},
+	{0x48fb, 0x32},
+	{0x48fc, 0x02},
+	{0x48fd, 0x4b},
+	{0x48fe, 0x02},
+	{0x48ff, 0x4c},
+	{0x4900, 0x01},
+	{0x4901, 0xec},
+	{0x4902, 0x01},
+	{0x4903, 0xf2},
+	{0x4904, 0x01},
+	{0x4905, 0xb1},
+	{0x4906, 0x01},
+	{0x4907, 0xb7},
+	{0x4908, 0x01},
+	{0x4909, 0x8a},
+	{0x490a, 0x01},
+	{0x490b, 0x8c},
+	{0x490c, 0x01},
+	{0x490d, 0x7d},
+	{0x490e, 0x01},
+	{0x490f, 0x7d},
+	{0x4910, 0x01},
+	{0x4911, 0x87},
+	{0x4912, 0x01},
+	{0x4913, 0x87},
+	{0x4914, 0x01},
+	{0x4915, 0xa8},
+	{0x4916, 0x01},
+	{0x4917, 0xa8},
+	{0x4918, 0x01},
+	{0x4919, 0xe2},
+	{0x491a, 0x01},
+	{0x491b, 0xda},
+	{0x491c, 0x02},
+	{0x491d, 0x38},
+	{0x491e, 0x02},
+	{0x491f, 0x30},
+	{0x4920, 0x02},
+	{0x4921, 0x0a},
+	{0x4922, 0x02},
+	{0x4923, 0x0e},
+	{0x4924, 0x01},
+	{0x4925, 0xae},
+	{0x4926, 0x01},
+	{0x4927, 0xaf},
+	{0x4928, 0x01},
+	{0x4929, 0x71},
+	{0x492a, 0x01},
+	{0x492b, 0x74},
+	{0x492c, 0x01},
+	{0x492d, 0x4b},
+	{0x492e, 0x01},
+	{0x492f, 0x4a},
+	{0x4930, 0x01},
+	{0x4931, 0x3b},
+	{0x4932, 0x01},
+	{0x4933, 0x3c},
+	{0x4934, 0x01},
+	{0x4935, 0x46},
+	{0x4936, 0x01},
+	{0x4937, 0x47},
+	{0x4938, 0x01},
+	{0x4939, 0x68},
+	{0x493a, 0x01},
+	{0x493b, 0x68},
+	{0x493c, 0x01},
+	{0x493d, 0x9e},
+	{0x493e, 0x01},
+	{0x493f, 0xa0},
+	{0x4940, 0x01},
+	{0x4941, 0xf4},
+	{0x4942, 0x01},
+	{0x4943, 0xec},
+	{0x4944, 0x01},
+	{0x4945, 0xdc},
+	{0x4946, 0x01},
+	{0x4947, 0xe7},
+	{0x4948, 0x01},
+	{0x4949, 0x8a},
+	{0x494a, 0x01},
+	{0x494b, 0x8e},
+	{0x494c, 0x01},
+	{0x494d, 0x4b},
+	{0x494e, 0x01},
+	{0x494f, 0x4b},
+	{0x4950, 0x01},
+	{0x4951, 0x1e},
+	{0x4952, 0x01},
+	{0x4953, 0x1f},
+	{0x4954, 0x01},
+	{0x4955, 0x0c},
+	{0x4956, 0x01},
+	{0x4957, 0x0b},
+	{0x4958, 0x01},
+	{0x4959, 0x18},
+	{0x495a, 0x01},
+	{0x495b, 0x17},
+	{0x495c, 0x01},
+	{0x495d, 0x42},
+	{0x495e, 0x01},
+	{0x495f, 0x3f},
+	{0x4960, 0x01},
+	{0x4961, 0x7b},
+	{0x4962, 0x01},
+	{0x4963, 0x79},
+	{0x4964, 0x01},
+	{0x4965, 0xcb},
+	{0x4966, 0x01},
+	{0x4967, 0xc1},
+	{0x4968, 0x01},
+	{0x4969, 0xd4},
+	{0x496a, 0x01},
+	{0x496b, 0xd4},
+	{0x496c, 0x01},
+	{0x496d, 0x80},
+	{0x496e, 0x01},
+	{0x496f, 0x81},
+	{0x4970, 0x01},
+	{0x4971, 0x3e},
+	{0x4972, 0x01},
+	{0x4973, 0x3a},
+	{0x4974, 0x01},
+	{0x4975, 0x10},
+	{0x4976, 0x01},
+	{0x4977, 0x0d},
+	{0x4978, 0x01},
+	{0x4979, 0x00},
+	{0x497a, 0x01},
+	{0x497b, 0x00},
+	{0x497c, 0x01},
+	{0x497d, 0x07},
+	{0x497e, 0x01},
+	{0x497f, 0x08},
+	{0x4980, 0x01},
+	{0x4981, 0x34},
+	{0x4982, 0x01},
+	{0x4983, 0x32},
+	{0x4984, 0x01},
+	{0x4985, 0x72},
+	{0x4986, 0x01},
+	{0x4987, 0x6d},
+	{0x4988, 0x01},
+	{0x4989, 0xc1},
+	{0x498a, 0x01},
+	{0x498b, 0xb6},
+	{0x498c, 0x01},
+	{0x498d, 0xe1},
+	{0x498e, 0x01},
+	{0x498f, 0xe5},
+	{0x4990, 0x01},
+	{0x4991, 0x8d},
+	{0x4992, 0x01},
+	{0x4993, 0x8f},
+	{0x4994, 0x01},
+	{0x4995, 0x4c},
+	{0x4996, 0x01},
+	{0x4997, 0x4d},
+	{0x4998, 0x01},
+	{0x4999, 0x1d},
+	{0x499a, 0x01},
+	{0x499b, 0x1d},
+	{0x499c, 0x01},
+	{0x499d, 0x0b},
+	{0x499e, 0x01},
+	{0x499f, 0x0b},
+	{0x49a0, 0x01},
+	{0x49a1, 0x18},
+	{0x49a2, 0x01},
+	{0x49a3, 0x16},
+	{0x49a4, 0x01},
+	{0x49a5, 0x40},
+	{0x49a6, 0x01},
+	{0x49a7, 0x3f},
+	{0x49a8, 0x01},
+	{0x49a9, 0x7c},
+	{0x49aa, 0x01},
+	{0x49ab, 0x77},
+	{0x49ac, 0x01},
+	{0x49ad, 0xcb},
+	{0x49ae, 0x01},
+	{0x49af, 0xc8},
+	{0x49b0, 0x02},
+	{0x49b1, 0x0a},
+	{0x49b2, 0x02},
+	{0x49b3, 0x0f},
+	{0x49b4, 0x01},
+	{0x49b5, 0xad},
+	{0x49b6, 0x01},
+	{0x49b7, 0xaf},
+	{0x49b8, 0x01},
+	{0x49b9, 0x74},
+	{0x49ba, 0x01},
+	{0x49bb, 0x73},
+	{0x49bc, 0x01},
+	{0x49bd, 0x49},
+	{0x49be, 0x01},
+	{0x49bf, 0x48},
+	{0x49c0, 0x01},
+	{0x49c1, 0x37},
+	{0x49c2, 0x01},
+	{0x49c3, 0x37},
+	{0x49c4, 0x01},
+	{0x49c5, 0x44},
+	{0x49c6, 0x01},
+	{0x49c7, 0x3f},
+	{0x49c8, 0x01},
+	{0x49c9, 0x68},
+	{0x49ca, 0x01},
+	{0x49cb, 0x65},
+	{0x49cc, 0x01},
+	{0x49cd, 0xa2},
+	{0x49ce, 0x01},
+	{0x49cf, 0x9d},
+	{0x49d0, 0x01},
+	{0x49d1, 0xf0},
+	{0x49d2, 0x01},
+	{0x49d3, 0xe6},
+	{0x49d4, 0x02},
+	{0x49d5, 0x4f},
+	{0x49d6, 0x02},
+	{0x49d7, 0x4c},
+	{0x49d8, 0x01},
+	{0x49d9, 0xf4},
+	{0x49da, 0x01},
+	{0x49db, 0xf8},
+	{0x49dc, 0x01},
+	{0x49dd, 0xb6},
+	{0x49de, 0x01},
+	{0x49df, 0xb4},
+	{0x49e0, 0x01},
+	{0x49e1, 0x90},
+	{0x49e2, 0x01},
+	{0x49e3, 0x91},
+	{0x49e4, 0x01},
+	{0x49e5, 0x7f},
+	{0x49e6, 0x01},
+	{0x49e7, 0x81},
+	{0x49e8, 0x01},
+	{0x49e9, 0x8a},
+	{0x49ea, 0x01},
+	{0x49eb, 0x88},
+	{0x49ec, 0x01},
+	{0x49ed, 0xa8},
+	{0x49ee, 0x01},
+	{0x49ef, 0xa9},
+	{0x49f0, 0x01},
+	{0x49f1, 0xde},
+	{0x49f2, 0x01},
+	{0x49f3, 0xd9},
+	{0x49f4, 0x02},
+	{0x49f5, 0x3b},
+	{0x49f6, 0x02},
+	{0x49f7, 0x30},
+	{0x3A63, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf imx135_snap_settings[] = {
+	/* Clock Setting	*/
+	{0x011E, 0x18},
+	{0x011F, 0x00},
+	{0x0301, 0x05},
+	{0x0303, 0x01},
+	{0x0305, 0x03},
+	{0x0309, 0x05},
+	{0x030B, 0x01},
+	{0x030C, 0x00},
+	{0x030D, 0x60},/*0x64*/
+	{0x030E, 0x01},
+	{0x3A06, 0x11},
+	/* Mode setting */
+	{0x0108, 0x03},
+	{0x0112, 0x0A},
+	{0x0113, 0x0A},
+	{0x0381, 0x01},
+	{0x0383, 0x01},
+	{0x0385, 0x01},
+	{0x0387, 0x01},
+	{0x0390, 0x00},
+	{0x0391, 0x11},
+	{0x0392, 0x00},
+	{0x0401, 0x00},
+	{0x0404, 0x00},
+	{0x0405, 0x10},
+	{0x4082, 0x01},
+	{0x4083, 0x01},
+	{0x7006, 0x04},
+	/* OptionalFunction setting */
+	{0x0700, 0x00},
+	{0x3A63, 0x00},
+	{0x4100, 0xF8},
+	{0x4203, 0xFF},
+	{0x4344, 0x00},
+	{0x441C, 0x01},
+	/* Size setting	*/
+	{0x0340, 0x0C},
+	{0x0341, 0x46},
+	{0x0342, 0x11},
+	{0x0343, 0xDC},
+	{0x0344, 0x00},
+	{0x0345, 0x00},
+	{0x0346, 0x00},
+	{0x0347, 0x00},
+	{0x0348, 0x10},
+	{0x0349, 0x6F},
+	{0x034A, 0x0C},
+	{0x034B, 0x2F},
+	{0x034C, 0x10},
+	{0x034D, 0x70},
+	{0x034E, 0x0C},
+	{0x034F, 0x30},
+	{0x0350, 0x00},
+	{0x0351, 0x00},
+	{0x0352, 0x00},
+	{0x0353, 0x00},
+	{0x0354, 0x10},
+	{0x0355, 0x70},
+	{0x0356, 0x0C},
+	{0x0357, 0x30},
+	{0x301D, 0x30},
+	{0x3310, 0x10},
+	{0x3311, 0x70},
+	{0x3312, 0x0C},
+	{0x3313, 0x30},
+	{0x331C, 0x01},
+	{0x331D, 0x68},
+	{0x4084, 0x00},
+	{0x4085, 0x00},
+	{0x4086, 0x00},
+	{0x4087, 0x00},
+	{0x4400, 0x00},
+	/* Global Timing Setting */
+	{0x0830, 0x7F},
+	{0x0831, 0x37},
+	{0x0832, 0x5F},
+	{0x0833, 0x37},
+	{0x0834, 0x37},
+	{0x0835, 0x3F},
+	{0x0836, 0xC7},
+	{0x0837, 0x3F},
+	{0x0839, 0x1F},
+	{0x083A, 0x17},
+	{0x083B, 0x02},
+	/* Integration Time Setting */
+	{0x0202, 0x0C},
+	{0x0203, 0x42},
+	/* Gain Setting	*/
+	{0x0205, 0x00},
+	{0x020E, 0x01},
+	{0x020F, 0x00},
+	{0x0210, 0x01},
+	{0x0211, 0x00},
+	{0x0212, 0x01},
+	{0x0213, 0x00},
+	{0x0214, 0x01},
+	{0x0215, 0x00},
+	/* HDR Setting */
+	{0x0230, 0x00},
+	{0x0231, 0x00},
+	{0x0233, 0x00},
+	{0x0234, 0x00},
+	{0x0235, 0x40},
+	{0x0238, 0x00},
+	{0x0239, 0x04},
+	{0x023B, 0x00},
+	{0x023C, 0x01},
+	{0x33B0, 0x04},
+	{0x33B1, 0x00},
+	{0x33B3, 0x00},
+	{0x33B4, 0x00},
+	{0x3800, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf imx135_hdr_settings[] = {
+	/* Clock Setting */
+	{0x011E, 0x18},
+	{0x011F, 0x00},
+	{0x0301, 0x05},
+	{0x0303, 0x01},
+	{0x0305, 0x03},
+	{0x0309, 0x05},
+	{0x030B, 0x02},
+	{0x030C, 0x00},
+	{0x030D, 0x71},
+	{0x030E, 0x01},
+	{0x3A06, 0x12},
+	/* Mode setting	*/
+	{0x0108, 0x03},
+	{0x0112, 0x0E},
+	{0x0113, 0x0A},
+	{0x0381, 0x01},
+	{0x0383, 0x01},
+	{0x0385, 0x01},
+	{0x0387, 0x01},
+	{0x0390, 0x00},
+	{0x0391, 0x11},
+	{0x0392, 0x00},
+	{0x0401, 0x00},
+	{0x0404, 0x00},
+	{0x0405, 0x10},
+	{0x4082, 0x01},
+	{0x4083, 0x01},
+	{0x7006, 0x04},
+	/* OptionnalFunction setting */
+	{0x0700, 0x01},
+	{0x3A63, 0x00},
+	{0x4100, 0xF8},
+	{0x4203, 0xFF},
+	{0x4344, 0x00},
+	{0x441C, 0x01},
+	/* Size setting	*/
+	{0x0340, 0x0C},
+	{0x0341, 0x48},
+	{0x0342, 0x11},
+	{0x0343, 0xDC},
+	{0x0344, 0x00},
+	{0x0345, 0x08},
+	{0x0346, 0x00},
+	{0x0347, 0x00},
+	{0x0348, 0x10},
+	{0x0349, 0x67},
+	{0x034A, 0x0C},
+	{0x034B, 0x2F},
+	{0x034C, 0x08},
+	{0x034D, 0x30},
+	{0x034E, 0x06},
+	{0x034F, 0x18},
+	{0x0350, 0x00},
+	{0x0351, 0x00},
+	{0x0352, 0x00},
+	{0x0353, 0x00},
+	{0x0354, 0x08},
+	{0x0355, 0x30},
+	{0x0356, 0x06},
+	{0x0357, 0x18},
+	{0x301D, 0x30},
+	{0x3310, 0x08},
+	{0x3311, 0x30},
+	{0x3312, 0x06},
+	{0x3313, 0x18},
+	{0x331C, 0x00},
+	{0x331D, 0x10},
+	{0x4084, 0x00},
+	{0x4085, 0x00},
+	{0x4086, 0x00},
+	{0x4087, 0x00},
+	{0x4400, 0x00},
+	/*Global Timing Setting	*/
+	{0x0830, 0x67},
+	{0x0831, 0x27},
+	{0x0832, 0x47},
+	{0x0833, 0x27},
+	{0x0834, 0x27},
+	{0x0835, 0x1F},
+	{0x0836, 0x87},
+	{0x0837, 0x2F},
+	{0x0839, 0x1F},
+	{0x083A, 0x17},
+	{0x083B, 0x02},
+	/*Integration Time Setting*/
+	{0x0202, 0x0C},
+	{0x0203, 0x44},
+	/*Gain Setting */
+	{0x0205, 0x00},
+	{0x020E, 0x01},
+	{0x020F, 0x00},
+	{0x0210, 0x01},
+	{0x0211, 0x00},
+	{0x0212, 0x01},
+	{0x0213, 0x00},
+	{0x0214, 0x01},
+	{0x0215, 0x00},
+	/* HDR Setting */
+	{0x0230, 0x00},
+	{0x0231, 0x00},
+	{0x0233, 0x00},
+	{0x0234, 0x00},
+	{0x0235, 0x40},
+	{0x0238, 0x01}, /*Direct 1 / Auto 0*/
+	{0x0239, 0x04},
+	{0x023B, 0x03},
+	{0x023C, 0x01},
+	{0x33B0, 0x08},
+	{0x33B1, 0x30},
+	{0x33B3, 0x01},
+	{0x33B4, 0x00},
+	{0x3800, 0x00},
+};
+
+static struct v4l2_subdev_info imx135_subdev_info[] = {
+	{
+	.code		= V4L2_MBUS_FMT_SBGGR10_1X10,
+	.colorspace	= V4L2_COLORSPACE_JPEG,
+	.fmt		= 1,
+	.order		= 0,
+	},
+	/* more can be supported, to be added later */
+};
+
+static struct msm_camera_i2c_conf_array imx135_init_conf[] = {
+	{&imx135_recommend_settings[0],
+	ARRAY_SIZE(imx135_recommend_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+	{&imx135_LSCTable_settings[0],
+	ARRAY_SIZE(imx135_LSCTable_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}
+};
+
+static struct msm_camera_i2c_conf_array imx135_confs[] = {
+	{&imx135_snap_settings[0],
+	ARRAY_SIZE(imx135_snap_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+	{&imx135_prev_settings[0],
+	ARRAY_SIZE(imx135_prev_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+	{&imx135_hdr_settings[0],
+	ARRAY_SIZE(imx135_hdr_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+};
+
+static struct msm_sensor_output_info_t imx135_dimensions[] = {
+	/* RES0 snapshot(FULL SIZE) */
+	{
+		.x_output = 4208,
+		.y_output = 3120,
+		.line_length_pclk = 4572,
+		.frame_length_lines = 3290,
+		.vt_pixel_clk = 360000000,
+		.op_pixel_clk = 319680000,
+		.binning_factor = 1,
+	},
+	/* RES1 4:3 preview(1/2HV QTR SIZE) */
+	{
+		.x_output = 2104,
+		.y_output = 1560,
+		.line_length_pclk = 4572,
+		.frame_length_lines = 1582,
+		.vt_pixel_clk = 360000000,
+		.op_pixel_clk = 180000000,
+		.binning_factor = 1,
+	},
+	/* RES2 4:3 HDR movie mode */
+	{
+		.x_output = 2096,
+		.y_output = 1560,
+		.line_length_pclk = 4572,
+		.frame_length_lines = 3290,
+		.vt_pixel_clk = 360000000,
+		.op_pixel_clk = 180000000,
+		.binning_factor = 1,
+	},
+};
+
+static struct msm_sensor_output_reg_addr_t imx135_reg_addr = {
+	.x_output = 0x34C,
+	.y_output = 0x34E,
+	.line_length_pclk = 0x342,
+	.frame_length_lines = 0x340,
+};
+
+static struct msm_sensor_id_info_t imx135_id_info = {
+	.sensor_id_reg_addr = 0x0000,
+	.sensor_id = 0x1210,
+};
+
+static struct msm_sensor_exp_gain_info_t imx135_exp_gain_info = {
+	.coarse_int_time_addr = 0x202,
+	.global_gain_addr = 0x205,
+	.vert_offset = 4,
+};
+
+static const struct i2c_device_id imx135_i2c_id[] = {
+	{SENSOR_NAME, (kernel_ulong_t)&imx135_s_ctrl},
+	{ }
+};
+
+static struct i2c_driver imx135_i2c_driver = {
+	.id_table = imx135_i2c_id,
+	.probe  = msm_sensor_i2c_probe,
+	.driver = {
+		.name = SENSOR_NAME,
+	},
+};
+
+static struct msm_camera_i2c_client imx135_sensor_i2c_client = {
+	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+static int __init msm_sensor_init_module(void)
+{
+	return i2c_add_driver(&imx135_i2c_driver);
+}
+
+static struct v4l2_subdev_core_ops imx135_subdev_core_ops = {
+	.ioctl = msm_sensor_subdev_ioctl,
+	.s_power = msm_sensor_power,
+};
+
+static struct v4l2_subdev_video_ops imx135_subdev_video_ops = {
+	.enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
+};
+
+static struct v4l2_subdev_ops imx135_subdev_ops = {
+	.core = &imx135_subdev_core_ops,
+	.video  = &imx135_subdev_video_ops,
+};
+
+int32_t imx135_write_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
+		uint16_t gain, uint32_t line)
+{
+	uint32_t fl_lines;
+	uint8_t offset;
+	fl_lines = s_ctrl->curr_frame_length_lines;
+	fl_lines = (fl_lines * s_ctrl->fps_divider) / Q10;
+	offset = s_ctrl->sensor_exp_gain_info->vert_offset;
+	if (line > (fl_lines - offset))
+		fl_lines = line + offset;
+
+	s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_output_reg_addr->frame_length_lines, fl_lines,
+		MSM_CAMERA_I2C_WORD_DATA);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr, line,
+		MSM_CAMERA_I2C_WORD_DATA);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->global_gain_addr, gain,
+		MSM_CAMERA_I2C_BYTE_DATA);
+	s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
+	return 0;
+}
+
+static struct msm_sensor_fn_t imx135_func_tbl = {
+	.sensor_start_stream = msm_sensor_start_stream,
+	.sensor_stop_stream = msm_sensor_stop_stream,
+	.sensor_group_hold_on = msm_sensor_group_hold_on,
+	.sensor_group_hold_off = msm_sensor_group_hold_off,
+	.sensor_set_fps = msm_sensor_set_fps,
+	.sensor_write_exp_gain = imx135_write_exp_gain,
+	.sensor_write_snapshot_exp_gain = imx135_write_exp_gain,
+	.sensor_setting = msm_sensor_setting,
+	.sensor_csi_setting = msm_sensor_setting1,
+	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
+	.sensor_mode_init = msm_sensor_mode_init,
+	.sensor_get_output_info = msm_sensor_get_output_info,
+	.sensor_config = msm_sensor_config,
+	.sensor_power_up = msm_sensor_power_up,
+	.sensor_power_down = msm_sensor_power_down,
+	.sensor_adjust_frame_lines = msm_sensor_adjust_frame_lines1,
+	.sensor_get_csi_params = msm_sensor_get_csi_params,
+};
+
+static struct msm_sensor_reg_t imx135_regs = {
+	.default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
+	.start_stream_conf = imx135_start_settings,
+	.start_stream_conf_size = ARRAY_SIZE(imx135_start_settings),
+	.stop_stream_conf = imx135_stop_settings,
+	.stop_stream_conf_size = ARRAY_SIZE(imx135_stop_settings),
+	.group_hold_on_conf = imx135_groupon_settings,
+	.group_hold_on_conf_size = ARRAY_SIZE(imx135_groupon_settings),
+	.group_hold_off_conf = imx135_groupoff_settings,
+	.group_hold_off_conf_size =
+		ARRAY_SIZE(imx135_groupoff_settings),
+	.init_settings = &imx135_init_conf[0],
+	.init_size = ARRAY_SIZE(imx135_init_conf),
+	.mode_settings = &imx135_confs[0],
+	.output_settings = &imx135_dimensions[0],
+	.num_conf = ARRAY_SIZE(imx135_confs),
+};
+
+static struct msm_sensor_ctrl_t imx135_s_ctrl = {
+	.msm_sensor_reg = &imx135_regs,
+	.sensor_i2c_client = &imx135_sensor_i2c_client,
+	.sensor_i2c_addr = 0x20,
+	.sensor_output_reg_addr = &imx135_reg_addr,
+	.sensor_id_info = &imx135_id_info,
+	.sensor_exp_gain_info = &imx135_exp_gain_info,
+	.cam_mode = MSM_SENSOR_MODE_INVALID,
+	.msm_sensor_mutex = &imx135_mut,
+	.sensor_i2c_driver = &imx135_i2c_driver,
+	.sensor_v4l2_subdev_info = imx135_subdev_info,
+	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(imx135_subdev_info),
+	.sensor_v4l2_subdev_ops = &imx135_subdev_ops,
+	.func_tbl = &imx135_func_tbl,
+	.clk_rate = MSM_SENSOR_MCLK_24HZ,
+};
+
+module_init(msm_sensor_init_module);
+MODULE_DESCRIPTION("Sony 13MP Bayer sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/sensors/msm_sensor.c b/drivers/media/platform/msm/camera_v1/sensors/msm_sensor.c
new file mode 100644
index 0000000..3df963a
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/sensors/msm_sensor.c
@@ -0,0 +1,1975 @@
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
+#include "msm_sensor.h"
+#include "msm_sensor_common.h"
+#include "msm.h"
+#include "msm_ispif.h"
+#include "msm_camera_i2c_mux.h"
+
+/*=============================================================*/
+void msm_sensor_adjust_frame_lines1(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	uint16_t cur_line = 0;
+	uint16_t exp_fl_lines = 0;
+	if (s_ctrl->sensor_exp_gain_info) {
+		msm_camera_i2c_read(s_ctrl->sensor_i2c_client,
+			s_ctrl->sensor_exp_gain_info->coarse_int_time_addr,
+			&cur_line,
+			MSM_CAMERA_I2C_WORD_DATA);
+		exp_fl_lines = cur_line +
+			s_ctrl->sensor_exp_gain_info->vert_offset;
+		if (exp_fl_lines > s_ctrl->msm_sensor_reg->
+			output_settings[s_ctrl->curr_res].frame_length_lines)
+			msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+				s_ctrl->sensor_output_reg_addr->
+				frame_length_lines,
+				exp_fl_lines,
+				MSM_CAMERA_I2C_WORD_DATA);
+		CDBG("%s cur_fl_lines %d, exp_fl_lines %d\n", __func__,
+			s_ctrl->msm_sensor_reg->
+			output_settings[s_ctrl->curr_res].frame_length_lines,
+			exp_fl_lines);
+	}
+	return;
+}
+
+void msm_sensor_adjust_frame_lines2(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	uint16_t cur_line = 0;
+	uint16_t exp_fl_lines = 0;
+	uint8_t int_time[3];
+	if (s_ctrl->sensor_exp_gain_info) {
+		msm_camera_i2c_read_seq(s_ctrl->sensor_i2c_client,
+			s_ctrl->sensor_exp_gain_info->coarse_int_time_addr-1,
+			&int_time[0], 3);
+		cur_line |= int_time[0] << 12;
+		cur_line |= int_time[1] << 4;
+		cur_line |= int_time[2] >> 4;
+		exp_fl_lines = cur_line +
+			s_ctrl->sensor_exp_gain_info->vert_offset;
+		if (exp_fl_lines > s_ctrl->msm_sensor_reg->
+			output_settings[s_ctrl->curr_res].frame_length_lines)
+			msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+				s_ctrl->sensor_output_reg_addr->
+				frame_length_lines,
+				exp_fl_lines,
+				MSM_CAMERA_I2C_WORD_DATA);
+		CDBG("%s cur_line %x cur_fl_lines %x, exp_fl_lines %x\n",
+			__func__,
+			cur_line,
+			s_ctrl->msm_sensor_reg->
+			output_settings[s_ctrl->curr_res].frame_length_lines,
+			exp_fl_lines);
+	}
+	return;
+}
+
+static void msm_sensor_delay_frames(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	long fps = 0;
+	uint32_t delay = 0;
+
+	if (s_ctrl->curr_res < MSM_SENSOR_INVALID_RES &&
+		s_ctrl->wait_num_frames > 0) {
+		fps = s_ctrl->msm_sensor_reg->
+			output_settings[s_ctrl->curr_res].vt_pixel_clk /
+			s_ctrl->curr_frame_length_lines /
+			s_ctrl->curr_line_length_pclk;
+		if (fps == 0)
+			delay = s_ctrl->min_delay;
+		else
+			delay = (1000 * s_ctrl->wait_num_frames) / fps / Q10;
+	}
+	CDBG("%s fps = %ld, delay = %d, min_delay %d\n", __func__, fps,
+		delay, s_ctrl->min_delay);
+	if (delay > s_ctrl->min_delay)
+		msleep(delay);
+	else if (s_ctrl->min_delay)
+		msleep(s_ctrl->min_delay);
+	return;
+}
+
+int32_t msm_sensor_write_init_settings(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	int32_t rc;
+	rc = msm_sensor_write_all_conf_array(
+		s_ctrl->sensor_i2c_client,
+		s_ctrl->msm_sensor_reg->init_settings,
+		s_ctrl->msm_sensor_reg->init_size);
+	return rc;
+}
+
+int32_t msm_sensor_write_res_settings(struct msm_sensor_ctrl_t *s_ctrl,
+	uint16_t res)
+{
+	int32_t rc;
+	rc = msm_sensor_write_conf_array(
+		s_ctrl->sensor_i2c_client,
+		s_ctrl->msm_sensor_reg->mode_settings, res);
+	if (rc < 0)
+		return rc;
+
+	rc = msm_sensor_write_output_settings(s_ctrl, res);
+	if (rc < 0)
+		return rc;
+
+	return rc;
+}
+
+int32_t msm_sensor_write_output_settings(struct msm_sensor_ctrl_t *s_ctrl,
+	uint16_t res)
+{
+	int32_t rc = -EFAULT;
+	struct msm_camera_i2c_reg_conf dim_settings[] = {
+		{s_ctrl->sensor_output_reg_addr->x_output,
+			s_ctrl->msm_sensor_reg->
+			output_settings[res].x_output},
+		{s_ctrl->sensor_output_reg_addr->y_output,
+			s_ctrl->msm_sensor_reg->
+			output_settings[res].y_output},
+		{s_ctrl->sensor_output_reg_addr->line_length_pclk,
+			s_ctrl->msm_sensor_reg->
+			output_settings[res].line_length_pclk},
+		{s_ctrl->sensor_output_reg_addr->frame_length_lines,
+			s_ctrl->msm_sensor_reg->
+			output_settings[res].frame_length_lines},
+	};
+
+	rc = msm_camera_i2c_write_tbl(s_ctrl->sensor_i2c_client, dim_settings,
+		ARRAY_SIZE(dim_settings), MSM_CAMERA_I2C_WORD_DATA);
+	return rc;
+}
+
+void msm_sensor_start_stream(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	if (s_ctrl->curr_res >= s_ctrl->msm_sensor_reg->num_conf)
+		return;
+
+	if (s_ctrl->func_tbl->sensor_adjust_frame_lines)
+		s_ctrl->func_tbl->sensor_adjust_frame_lines(s_ctrl);
+
+	msm_camera_i2c_write_tbl(
+		s_ctrl->sensor_i2c_client,
+		s_ctrl->msm_sensor_reg->start_stream_conf,
+		s_ctrl->msm_sensor_reg->start_stream_conf_size,
+		s_ctrl->msm_sensor_reg->default_data_type);
+	msleep(20);
+}
+
+void msm_sensor_stop_stream(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	msm_camera_i2c_write_tbl(
+		s_ctrl->sensor_i2c_client,
+		s_ctrl->msm_sensor_reg->stop_stream_conf,
+		s_ctrl->msm_sensor_reg->stop_stream_conf_size,
+		s_ctrl->msm_sensor_reg->default_data_type);
+	msm_sensor_delay_frames(s_ctrl);
+}
+
+void msm_sensor_group_hold_on(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	msm_camera_i2c_write_tbl(
+		s_ctrl->sensor_i2c_client,
+		s_ctrl->msm_sensor_reg->group_hold_on_conf,
+		s_ctrl->msm_sensor_reg->group_hold_on_conf_size,
+		s_ctrl->msm_sensor_reg->default_data_type);
+}
+
+void msm_sensor_group_hold_off(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	msm_camera_i2c_write_tbl(
+		s_ctrl->sensor_i2c_client,
+		s_ctrl->msm_sensor_reg->group_hold_off_conf,
+		s_ctrl->msm_sensor_reg->group_hold_off_conf_size,
+		s_ctrl->msm_sensor_reg->default_data_type);
+}
+
+int32_t msm_sensor_set_fps(struct msm_sensor_ctrl_t *s_ctrl,
+						struct fps_cfg *fps)
+{
+	s_ctrl->fps_divider = fps->fps_div;
+
+	return 0;
+}
+
+int32_t msm_sensor_write_exp_gain1(struct msm_sensor_ctrl_t *s_ctrl,
+		uint16_t gain, uint32_t line)
+{
+	uint32_t fl_lines;
+	uint8_t offset;
+	fl_lines = s_ctrl->curr_frame_length_lines;
+	fl_lines = (fl_lines * s_ctrl->fps_divider) / Q10;
+	offset = s_ctrl->sensor_exp_gain_info->vert_offset;
+	if (line > (fl_lines - offset))
+		fl_lines = line + offset;
+
+	s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_output_reg_addr->frame_length_lines, fl_lines,
+		MSM_CAMERA_I2C_WORD_DATA);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr, line,
+		MSM_CAMERA_I2C_WORD_DATA);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->global_gain_addr, gain,
+		MSM_CAMERA_I2C_WORD_DATA);
+	s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
+	return 0;
+}
+
+int32_t msm_sensor_write_exp_gain2(struct msm_sensor_ctrl_t *s_ctrl,
+		uint16_t gain, uint32_t line)
+{
+	uint32_t fl_lines, ll_pclk, ll_ratio;
+	uint8_t offset;
+	fl_lines = s_ctrl->curr_frame_length_lines * s_ctrl->fps_divider / Q10;
+	ll_pclk = s_ctrl->curr_line_length_pclk;
+	offset = s_ctrl->sensor_exp_gain_info->vert_offset;
+	if (line > (fl_lines - offset)) {
+		ll_ratio = (line * Q10) / (fl_lines - offset);
+		ll_pclk = ll_pclk * ll_ratio / Q10;
+		line = fl_lines - offset;
+	}
+
+	s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_output_reg_addr->line_length_pclk, ll_pclk,
+		MSM_CAMERA_I2C_WORD_DATA);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr, line,
+		MSM_CAMERA_I2C_WORD_DATA);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->global_gain_addr, gain,
+		MSM_CAMERA_I2C_WORD_DATA);
+	s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
+	return 0;
+}
+
+int32_t msm_sensor_setting1(struct msm_sensor_ctrl_t *s_ctrl,
+			int update_type, int res)
+{
+	int32_t rc = 0;
+
+	if (update_type == MSM_SENSOR_REG_INIT) {
+		CDBG("Register INIT\n");
+		msm_sensor_enable_debugfs(s_ctrl);
+		s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
+		msm_sensor_write_init_settings(s_ctrl);
+	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
+		CDBG("PERIODIC : %d\n", res);
+		msm_sensor_write_conf_array(
+			s_ctrl->sensor_i2c_client,
+			s_ctrl->msm_sensor_reg->mode_settings, res);
+		msleep(30);
+		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
+			NOTIFY_PCLK_CHANGE,
+			&s_ctrl->sensordata->pdata->ioclk.vfe_clk_rate);
+	}
+	return rc;
+}
+
+int32_t msm_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
+			int update_type, int res)
+{
+	int32_t rc = 0;
+
+	if (update_type == MSM_SENSOR_REG_INIT) {
+		s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
+		msm_sensor_write_init_settings(s_ctrl);
+	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
+		msm_sensor_write_res_settings(s_ctrl, res);
+		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
+			NOTIFY_PCLK_CHANGE, &s_ctrl->msm_sensor_reg->
+			output_settings[res].op_pixel_clk);
+	}
+	return rc;
+}
+
+int32_t msm_sensor_set_sensor_mode(struct msm_sensor_ctrl_t *s_ctrl,
+	int mode, int res)
+{
+	int32_t rc = 0;
+	if (s_ctrl->curr_res != res) {
+		s_ctrl->curr_frame_length_lines =
+			s_ctrl->msm_sensor_reg->
+			output_settings[res].frame_length_lines;
+
+		s_ctrl->curr_line_length_pclk =
+			s_ctrl->msm_sensor_reg->
+			output_settings[res].line_length_pclk;
+
+		if (s_ctrl->is_csic ||
+			!s_ctrl->sensordata->csi_if)
+			rc = s_ctrl->func_tbl->sensor_csi_setting(s_ctrl,
+				MSM_SENSOR_UPDATE_PERIODIC, res);
+		else
+			rc = s_ctrl->func_tbl->sensor_setting(s_ctrl,
+				MSM_SENSOR_UPDATE_PERIODIC, res);
+		if (rc < 0)
+			return rc;
+		s_ctrl->curr_res = res;
+	}
+
+	return rc;
+}
+
+int32_t msm_sensor_mode_init(struct msm_sensor_ctrl_t *s_ctrl,
+			int mode, struct sensor_init_cfg *init_info)
+{
+	int32_t rc = 0;
+	s_ctrl->fps_divider = Q10;
+	s_ctrl->cam_mode = MSM_SENSOR_MODE_INVALID;
+
+	CDBG("%s: %d\n", __func__, __LINE__);
+	if (mode != s_ctrl->cam_mode) {
+		s_ctrl->curr_res = MSM_SENSOR_INVALID_RES;
+		s_ctrl->cam_mode = mode;
+
+		if (s_ctrl->is_csic ||
+			!s_ctrl->sensordata->csi_if)
+			rc = s_ctrl->func_tbl->sensor_csi_setting(s_ctrl,
+				MSM_SENSOR_REG_INIT, 0);
+		else
+			rc = s_ctrl->func_tbl->sensor_setting(s_ctrl,
+				MSM_SENSOR_REG_INIT, 0);
+	}
+	return rc;
+}
+
+int32_t msm_sensor_get_output_info(struct msm_sensor_ctrl_t *s_ctrl,
+		struct sensor_output_info_t *sensor_output_info)
+{
+	int rc = 0;
+	sensor_output_info->num_info = s_ctrl->msm_sensor_reg->num_conf;
+	if (copy_to_user((void *)sensor_output_info->output_info,
+		s_ctrl->msm_sensor_reg->output_settings,
+		sizeof(struct msm_sensor_output_info_t) *
+		s_ctrl->msm_sensor_reg->num_conf))
+		rc = -EFAULT;
+
+	return rc;
+}
+
+static int32_t msm_sensor_release(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	CDBG("%s called\n", __func__);
+	s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
+	return 0;
+}
+
+long msm_sensor_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int cmd, void *arg)
+{
+	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
+	void __user *argp = (void __user *)arg;
+	if (s_ctrl->sensor_state == MSM_SENSOR_POWER_DOWN)
+		return -EINVAL;
+	switch (cmd) {
+	case VIDIOC_MSM_SENSOR_CFG:
+		return s_ctrl->func_tbl->sensor_config(s_ctrl, argp);
+	case VIDIOC_MSM_SENSOR_RELEASE:
+		return msm_sensor_release(s_ctrl);
+	case VIDIOC_MSM_SENSOR_CSID_INFO: {
+		struct msm_sensor_csi_info *csi_info =
+			(struct msm_sensor_csi_info *)arg;
+		s_ctrl->is_csic = csi_info->is_csic;
+		return 0;
+	}
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
+int32_t msm_sensor_get_csi_params(struct msm_sensor_ctrl_t *s_ctrl,
+		struct csi_lane_params_t *sensor_output_info)
+{
+	uint8_t index;
+	struct msm_camera_csi_lane_params *csi_lane_params =
+		s_ctrl->sensordata->sensor_platform_info->csi_lane_params;
+	if (csi_lane_params) {
+		sensor_output_info->csi_lane_assign = csi_lane_params->
+			csi_lane_assign;
+		sensor_output_info->csi_lane_mask = csi_lane_params->
+			csi_lane_mask;
+		sensor_output_info->csi_phy_sel =
+			s_ctrl->sensordata->pdata->csiphy_core;
+	}
+	sensor_output_info->csi_if = s_ctrl->sensordata->csi_if;
+	for (index = 0; index < sensor_output_info->csi_if; index++)
+		sensor_output_info->csid_core[index] = s_ctrl->sensordata->
+			pdata[index].csid_core;
+
+	return 0;
+}
+
+int32_t msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl, void __user *argp)
+{
+	struct sensor_cfg_data cdata;
+	long   rc = 0;
+	if (copy_from_user(&cdata,
+		(void *)argp,
+		sizeof(struct sensor_cfg_data)))
+		return -EFAULT;
+	mutex_lock(s_ctrl->msm_sensor_mutex);
+	CDBG("%s:%d %s cfgtype = %d\n", __func__, __LINE__,
+		s_ctrl->sensordata->sensor_name, cdata.cfgtype);
+	switch (cdata.cfgtype) {
+		case CFG_SET_FPS:
+		case CFG_SET_PICT_FPS:
+			if (s_ctrl->func_tbl->
+			sensor_set_fps == NULL) {
+				rc = -EFAULT;
+				break;
+			}
+			rc = s_ctrl->func_tbl->
+				sensor_set_fps(
+				s_ctrl,
+				&(cdata.cfg.fps));
+			break;
+
+		case CFG_SET_EXP_GAIN:
+			if (s_ctrl->func_tbl->
+			sensor_write_exp_gain == NULL) {
+				rc = -EFAULT;
+				break;
+			}
+			rc =
+				s_ctrl->func_tbl->
+				sensor_write_exp_gain(
+					s_ctrl,
+					cdata.cfg.exp_gain.gain,
+					cdata.cfg.exp_gain.line);
+			break;
+
+		case CFG_SET_PICT_EXP_GAIN:
+			if (s_ctrl->func_tbl->
+			sensor_write_snapshot_exp_gain == NULL) {
+				rc = -EFAULT;
+				break;
+			}
+			rc =
+				s_ctrl->func_tbl->
+				sensor_write_snapshot_exp_gain(
+					s_ctrl,
+					cdata.cfg.exp_gain.gain,
+					cdata.cfg.exp_gain.line);
+			break;
+
+		case CFG_SET_MODE:
+			if (s_ctrl->func_tbl->
+			sensor_set_sensor_mode == NULL) {
+				rc = -EFAULT;
+				break;
+			}
+			rc = s_ctrl->func_tbl->
+				sensor_set_sensor_mode(
+					s_ctrl,
+					cdata.mode,
+					cdata.rs);
+			break;
+
+		case CFG_SET_EFFECT:
+			break;
+
+		case CFG_SENSOR_INIT:
+			if (s_ctrl->func_tbl->
+			sensor_mode_init == NULL) {
+				rc = -EFAULT;
+				break;
+			}
+			rc = s_ctrl->func_tbl->
+				sensor_mode_init(
+				s_ctrl,
+				cdata.mode,
+				&(cdata.cfg.init_info));
+			break;
+
+		case CFG_GET_OUTPUT_INFO:
+			if (s_ctrl->func_tbl->
+			sensor_get_output_info == NULL) {
+				rc = -EFAULT;
+				break;
+			}
+			rc = s_ctrl->func_tbl->
+				sensor_get_output_info(
+				s_ctrl,
+				&cdata.cfg.output_info);
+
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_START_STREAM:
+			if (s_ctrl->func_tbl->sensor_start_stream == NULL) {
+				rc = -EFAULT;
+				break;
+			}
+			s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
+			break;
+
+		case CFG_STOP_STREAM:
+			if (s_ctrl->func_tbl->sensor_stop_stream == NULL) {
+				rc = -EFAULT;
+				break;
+			}
+			s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
+			break;
+
+		case CFG_GET_CSI_PARAMS:
+			if (s_ctrl->func_tbl->sensor_get_csi_params == NULL) {
+				rc = -EFAULT;
+				break;
+			}
+			rc = s_ctrl->func_tbl->sensor_get_csi_params(
+				s_ctrl,
+				&cdata.cfg.csi_lane_params);
+
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_POWER_UP:
+			pr_err("%s calling power up\n", __func__);
+			if (s_ctrl->func_tbl->sensor_power_up)
+				rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
+			else
+				rc = -EFAULT;
+			break;
+
+		case CFG_POWER_DOWN:
+			if (s_ctrl->func_tbl->sensor_power_down)
+				rc = s_ctrl->func_tbl->sensor_power_down(
+					s_ctrl);
+			else
+				rc = -EFAULT;
+			break;
+
+		default:
+			rc = -EFAULT;
+			break;
+		}
+
+	mutex_unlock(s_ctrl->msm_sensor_mutex);
+
+	return rc;
+}
+
+static struct msm_cam_clk_info cam_8960_clk_info[] = {
+	{"cam_clk", MSM_SENSOR_MCLK_24HZ},
+};
+
+static struct msm_cam_clk_info cam_8974_clk_info[] = {
+	{"cam_src_clk", 19200000},
+	{"cam_clk", -1},
+};
+
+int32_t msm_sensor_enable_i2c_mux(struct msm_camera_i2c_conf *i2c_conf)
+{
+	struct v4l2_subdev *i2c_mux_sd =
+		dev_get_drvdata(&i2c_conf->mux_dev->dev);
+	v4l2_subdev_call(i2c_mux_sd, core, ioctl,
+		VIDIOC_MSM_I2C_MUX_INIT, NULL);
+	v4l2_subdev_call(i2c_mux_sd, core, ioctl,
+		VIDIOC_MSM_I2C_MUX_CFG, (void *)&i2c_conf->i2c_mux_mode);
+	return 0;
+}
+
+int32_t msm_sensor_disable_i2c_mux(struct msm_camera_i2c_conf *i2c_conf)
+{
+	struct v4l2_subdev *i2c_mux_sd =
+		dev_get_drvdata(&i2c_conf->mux_dev->dev);
+	v4l2_subdev_call(i2c_mux_sd, core, ioctl,
+				VIDIOC_MSM_I2C_MUX_RELEASE, NULL);
+	return 0;
+}
+
+static int32_t msm_sensor_init_flash_data(struct device_node *of_node,
+	struct  msm_camera_sensor_info *sensordata)
+{
+	int32_t rc = 0;
+	uint32_t val = 0;
+	struct msm_camera_sensor_flash_data *flash_data = NULL;
+	struct device_node *flash_src_node = NULL;
+
+	sensordata->flash_data = kzalloc(sizeof(
+		struct msm_camera_sensor_flash_data), GFP_KERNEL);
+	if (!sensordata->flash_data) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		return -ENOMEM;
+	}
+
+	if (!of_get_property(of_node, "qcom,flash-src-index", &val)) {
+		CDBG("%s flash not available\n", __func__);
+		return rc;
+	}
+	flash_data = sensordata->flash_data;
+
+	flash_src_node = of_parse_phandle(of_node, "qcom,flash-src-index", 0);
+	if (!flash_src_node) {
+		pr_err("%s:%d flash_src_node NULL\n", __func__,
+			__LINE__);
+		goto ERROR1;
+	}
+
+	rc = of_property_read_u32(flash_src_node, "qcom,flash-type", &val);
+	CDBG("%s qcom,flash-type %d, rc %d\n", __func__, val, rc);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	flash_data->flash_type = val;
+
+	rc = of_property_read_u32(flash_src_node, "cell-index", &val);
+	CDBG("%s qcom,flash-src-index %d, rc %d\n", __func__, val, rc);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	flash_data->flash_src_index = val;
+
+	of_node_put(flash_src_node);
+
+	return rc;
+ERROR2:
+	of_node_put(flash_src_node);
+ERROR1:
+	flash_data->flash_type = MSM_CAMERA_FLASH_NONE;
+	return rc;
+}
+
+static int32_t msm_sensor_init_vreg_data(struct device_node *of_node,
+	struct msm_camera_sensor_platform_info *pinfo)
+{
+	int32_t rc = 0, i = 0;
+	uint32_t count = 0;
+	uint32_t *val_array = NULL;
+
+	count = of_property_count_strings(of_node, "qcom,cam-vreg-name");
+	CDBG("%s qcom,cam-vreg-name count %d\n", __func__, count);
+
+	if (!count)
+		return 0;
+
+	pinfo->cam_vreg = kzalloc(sizeof(struct camera_vreg_t) * count,
+		GFP_KERNEL);
+	if (!pinfo->cam_vreg) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		return -ENOMEM;
+	}
+
+	pinfo->num_vreg = count;
+	for (i = 0; i < count; i++) {
+		rc = of_property_read_string_index(of_node,
+			"qcom,cam-vreg-name", i, &pinfo->cam_vreg[i].reg_name);
+		CDBG("%s reg_name[%d] = %s\n", __func__, i,
+			pinfo->cam_vreg[i].reg_name);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR1;
+		}
+	}
+
+	val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
+	if (!val_array) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		goto ERROR1;
+	}
+
+	rc = of_property_read_u32_array(of_node, "qcom,cam-vreg-type",
+		val_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		pinfo->cam_vreg[i].type = val_array[i];
+		CDBG("%s cam_vreg[%d].type = %d\n", __func__, i,
+			pinfo->cam_vreg[i].type);
+	}
+
+	rc = of_property_read_u32_array(of_node, "qcom,cam-vreg-min-voltage",
+		val_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		pinfo->cam_vreg[i].min_voltage = val_array[i];
+		CDBG("%s cam_vreg[%d].min_voltage = %d\n", __func__,
+			i, pinfo->cam_vreg[i].min_voltage);
+	}
+
+	rc = of_property_read_u32_array(of_node, "qcom,cam-vreg-max-voltage",
+		val_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		pinfo->cam_vreg[i].max_voltage = val_array[i];
+		CDBG("%s cam_vreg[%d].max_voltage = %d\n", __func__,
+			i, pinfo->cam_vreg[i].max_voltage);
+	}
+
+	rc = of_property_read_u32_array(of_node, "qcom,cam-vreg-op-mode",
+		val_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		pinfo->cam_vreg[i].op_mode = val_array[i];
+		CDBG("%s cam_vreg[%d].op_mode = %d\n", __func__, i,
+			pinfo->cam_vreg[i].op_mode);
+	}
+
+	kfree(val_array);
+	return rc;
+ERROR2:
+	kfree(val_array);
+ERROR1:
+	kfree(pinfo->cam_vreg);
+	pinfo->num_vreg = 0;
+	return rc;
+}
+
+static int32_t msm_sensor_init_gpio_common_tbl_data(struct device_node *of_node,
+	struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
+	uint16_t gpio_array_size)
+{
+	int32_t rc = 0, i = 0;
+	uint32_t count = 0;
+	uint32_t *val_array = NULL;
+
+	if (!of_get_property(of_node, "qcom,gpio-common-tbl-num", &count))
+		return 0;
+
+	count /= sizeof(uint32_t);
+	if (!count) {
+		pr_err("%s qcom,gpio-common-tbl-num 0\n", __func__);
+		return 0;
+	} else if (count > gpio_array_size) {
+		pr_err("%s gpio common tbl size exceeds gpio array\n",
+			__func__);
+		return -EFAULT;
+	}
+
+	val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
+	if (!val_array) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		return -ENOMEM;
+	}
+
+	gconf->cam_gpio_common_tbl = kzalloc(sizeof(struct gpio) * count,
+		GFP_KERNEL);
+	if (!gconf->cam_gpio_common_tbl) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		goto ERROR1;
+	}
+	gconf->cam_gpio_common_tbl_size = count;
+
+	rc = of_property_read_u32_array(of_node, "qcom,gpio-common-tbl-num",
+		val_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		if (val_array[i] >= gpio_array_size) {
+			pr_err("%s gpio common tbl index %d invalid\n",
+				__func__, val_array[i]);
+			return -EINVAL;
+		}
+		gconf->cam_gpio_common_tbl[i].gpio = gpio_array[val_array[i]];
+		CDBG("%s cam_gpio_common_tbl[%d].gpio = %d\n", __func__, i,
+			gconf->cam_gpio_common_tbl[i].gpio);
+	}
+
+	rc = of_property_read_u32_array(of_node, "qcom,gpio-common-tbl-flags",
+		val_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		gconf->cam_gpio_common_tbl[i].flags = val_array[i];
+		CDBG("%s cam_gpio_common_tbl[%d].flags = %ld\n", __func__, i,
+			gconf->cam_gpio_common_tbl[i].flags);
+	}
+
+	for (i = 0; i < count; i++) {
+		rc = of_property_read_string_index(of_node,
+			"qcom,gpio-common-tbl-label", i,
+			&gconf->cam_gpio_common_tbl[i].label);
+		CDBG("%s cam_gpio_common_tbl[%d].label = %s\n", __func__, i,
+			gconf->cam_gpio_common_tbl[i].label);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR2;
+		}
+	}
+
+	kfree(val_array);
+	return rc;
+
+ERROR2:
+	kfree(gconf->cam_gpio_common_tbl);
+ERROR1:
+	kfree(val_array);
+	gconf->cam_gpio_common_tbl_size = 0;
+	return rc;
+}
+
+static int32_t msm_sensor_init_gpio_req_tbl_data(struct device_node *of_node,
+	struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
+	uint16_t gpio_array_size)
+{
+	int32_t rc = 0, i = 0;
+	uint32_t count = 0;
+	uint32_t *val_array = NULL;
+
+	if (!of_get_property(of_node, "qcom,gpio-req-tbl-num", &count))
+		return 0;
+
+	count /= sizeof(uint32_t);
+	if (!count) {
+		pr_err("%s qcom,gpio-req-tbl-num 0\n", __func__);
+		return 0;
+	}
+
+	val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
+	if (!val_array) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		return -ENOMEM;
+	}
+
+	gconf->cam_gpio_req_tbl = kzalloc(sizeof(struct gpio) * count,
+		GFP_KERNEL);
+	if (!gconf->cam_gpio_req_tbl) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		goto ERROR1;
+	}
+	gconf->cam_gpio_req_tbl_size = count;
+
+	rc = of_property_read_u32_array(of_node, "qcom,gpio-req-tbl-num",
+		val_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		if (val_array[i] >= gpio_array_size) {
+			pr_err("%s gpio req tbl index %d invalid\n",
+				__func__, val_array[i]);
+			return -EINVAL;
+		}
+		gconf->cam_gpio_req_tbl[i].gpio = gpio_array[val_array[i]];
+		CDBG("%s cam_gpio_req_tbl[%d].gpio = %d\n", __func__, i,
+			gconf->cam_gpio_req_tbl[i].gpio);
+	}
+
+	rc = of_property_read_u32_array(of_node, "qcom,gpio-req-tbl-flags",
+		val_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		gconf->cam_gpio_req_tbl[i].flags = val_array[i];
+		CDBG("%s cam_gpio_req_tbl[%d].flags = %ld\n", __func__, i,
+			gconf->cam_gpio_req_tbl[i].flags);
+	}
+
+	for (i = 0; i < count; i++) {
+		rc = of_property_read_string_index(of_node,
+			"qcom,gpio-req-tbl-label", i,
+			&gconf->cam_gpio_req_tbl[i].label);
+		CDBG("%s cam_gpio_req_tbl[%d].label = %s\n", __func__, i,
+			gconf->cam_gpio_req_tbl[i].label);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR2;
+		}
+	}
+
+	kfree(val_array);
+	return rc;
+
+ERROR2:
+	kfree(gconf->cam_gpio_req_tbl);
+ERROR1:
+	kfree(val_array);
+	gconf->cam_gpio_req_tbl_size = 0;
+	return rc;
+}
+
+static int32_t msm_sensor_init_gpio_set_tbl_data(struct device_node *of_node,
+	struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
+	uint16_t gpio_array_size)
+{
+	int32_t rc = 0, i = 0;
+	uint32_t count = 0;
+	uint32_t *val_array = NULL;
+
+	if (!of_get_property(of_node, "qcom,gpio-set-tbl-num", &count))
+		return 0;
+
+	count /= sizeof(uint32_t);
+	if (!count) {
+		pr_err("%s qcom,gpio-set-tbl-num 0\n", __func__);
+		return 0;
+	}
+
+	val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
+	if (!val_array) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		return -ENOMEM;
+	}
+
+	gconf->cam_gpio_set_tbl = kzalloc(sizeof(struct msm_gpio_set_tbl) *
+		count, GFP_KERNEL);
+	if (!gconf->cam_gpio_set_tbl) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		goto ERROR1;
+	}
+	gconf->cam_gpio_set_tbl_size = count;
+
+	rc = of_property_read_u32_array(of_node, "qcom,gpio-set-tbl-num",
+		val_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		if (val_array[i] >= gpio_array_size) {
+			pr_err("%s gpio set tbl index %d invalid\n",
+				__func__, val_array[i]);
+			return -EINVAL;
+		}
+		gconf->cam_gpio_set_tbl[i].gpio = gpio_array[val_array[i]];
+		CDBG("%s cam_gpio_set_tbl[%d].gpio = %d\n", __func__, i,
+			gconf->cam_gpio_set_tbl[i].gpio);
+	}
+
+	rc = of_property_read_u32_array(of_node, "qcom,gpio-set-tbl-flags",
+		val_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		gconf->cam_gpio_set_tbl[i].flags = val_array[i];
+		CDBG("%s cam_gpio_set_tbl[%d].flags = %ld\n", __func__, i,
+			gconf->cam_gpio_set_tbl[i].flags);
+	}
+
+	rc = of_property_read_u32_array(of_node, "qcom,gpio-set-tbl-delay",
+		val_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		gconf->cam_gpio_set_tbl[i].delay = val_array[i];
+		CDBG("%s cam_gpio_set_tbl[%d].delay = %d\n", __func__, i,
+			gconf->cam_gpio_set_tbl[i].delay);
+	}
+
+	kfree(val_array);
+	return rc;
+
+ERROR2:
+	kfree(gconf->cam_gpio_set_tbl);
+ERROR1:
+	kfree(val_array);
+	gconf->cam_gpio_set_tbl_size = 0;
+	return rc;
+}
+
+static int32_t msm_sensor_init_gpio_tlmm_tbl_data(struct device_node *of_node,
+	struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
+	uint16_t gpio_array_size)
+{
+	int32_t rc = 0, i = 0;
+	uint32_t count = 0;
+	uint32_t *val_array = NULL;
+	struct gpio_tlmm_cfg *tlmm_cfg = NULL;
+
+	if (!of_get_property(of_node, "gpio_tlmm_table_num", &count))
+		return 0;
+
+	count /= sizeof(uint32_t);
+
+	if (!count)
+		return 0;
+
+	val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
+	if (!val_array) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		return -ENOMEM;
+	}
+
+	tlmm_cfg = kzalloc(sizeof(struct gpio_tlmm_cfg) * count, GFP_KERNEL);
+	if (!tlmm_cfg) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		goto ERROR1;
+	}
+
+	gconf->camera_off_table = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
+	if (!gconf->camera_off_table) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		goto ERROR2;
+	}
+	gconf->camera_off_table_size = count;
+
+	gconf->camera_on_table = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
+	if (!gconf->camera_on_table) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		goto ERROR3;
+	}
+	gconf->camera_on_table_size = count;
+
+	rc = of_property_read_u32_array(of_node, "gpio_tlmm_table_num",
+		val_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR4;
+	}
+	for (i = 0; i < count; i++) {
+		if (val_array[i] >= gpio_array_size) {
+			pr_err("%s gpio set tbl index %d invalid\n",
+				__func__, val_array[i]);
+			return -EINVAL;
+		}
+		tlmm_cfg[i].gpio = gpio_array[val_array[i]];
+		CDBG("%s tlmm_cfg[%d].gpio = %d\n", __func__, i,
+			tlmm_cfg[i].gpio);
+	}
+
+	rc = of_property_read_u32_array(of_node, "gpio_tlmm_table_dir",
+		val_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR4;
+	}
+	for (i = 0; i < count; i++) {
+		tlmm_cfg[i].dir = val_array[i];
+		CDBG("%s tlmm_cfg[%d].dir = %d\n", __func__, i,
+			tlmm_cfg[i].dir);
+	}
+
+	rc = of_property_read_u32_array(of_node, "gpio_tlmm_table_pull",
+		val_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR4;
+	}
+	for (i = 0; i < count; i++) {
+		tlmm_cfg[i].pull = val_array[i];
+		CDBG("%s tlmm_cfg[%d].pull = %d\n", __func__, i,
+			tlmm_cfg[i].pull);
+	}
+
+	rc = of_property_read_u32_array(of_node, "gpio_tlmm_table_drvstr",
+		val_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR4;
+	}
+	for (i = 0; i < count; i++) {
+		tlmm_cfg[i].drvstr = val_array[i];
+		CDBG("%s tlmm_cfg[%d].drvstr = %d\n", __func__, i,
+			tlmm_cfg[i].drvstr);
+	}
+
+	for (i = 0; i < count; i++) {
+		gconf->camera_off_table[i] = GPIO_CFG(tlmm_cfg[i].gpio,
+			0, tlmm_cfg[i].dir, tlmm_cfg[i].pull,
+			tlmm_cfg[i].drvstr);
+		gconf->camera_on_table[i] = GPIO_CFG(tlmm_cfg[i].gpio,
+			1, tlmm_cfg[i].dir, tlmm_cfg[i].pull,
+			tlmm_cfg[i].drvstr);
+	}
+
+	kfree(tlmm_cfg);
+	kfree(val_array);
+	return rc;
+
+ERROR4:
+	kfree(gconf->camera_on_table);
+ERROR3:
+	kfree(gconf->camera_off_table);
+ERROR2:
+	kfree(tlmm_cfg);
+ERROR1:
+	kfree(val_array);
+	gconf->camera_off_table_size = 0;
+	gconf->camera_on_table_size = 0;
+	return rc;
+}
+
+static int32_t msm_sensor_init_csi_data(struct device_node *of_node,
+	struct  msm_camera_sensor_info *sensordata)
+{
+	int32_t rc = 0, i = 0;
+	uint32_t count = 0, val = 0;
+	uint32_t *val_array = NULL;
+	struct msm_camera_sensor_platform_info *pinfo =
+		sensordata->sensor_platform_info;
+
+	rc = of_property_read_u32(of_node, "qcom,csi-if", &count);
+	CDBG("%s qcom,csi-if %d, rc %d\n", __func__, count, rc);
+	if (rc < 0 || !count)
+		return rc;
+	sensordata->csi_if = count;
+
+	sensordata->pdata = kzalloc(sizeof(
+		struct msm_camera_device_platform_data) * count, GFP_KERNEL);
+	if (!sensordata->pdata) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		return -ENOMEM;
+	}
+
+	val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
+	if (!val_array) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		goto ERROR1;
+	}
+
+	rc = of_property_read_u32_array(of_node, "qcom,csid-core", val_array,
+		count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		sensordata->pdata[i].csid_core = val_array[i];
+		CDBG("%s csi_data[%d].csid_core = %d\n", __func__, i,
+			sensordata->pdata[i].csid_core);
+	}
+
+	pinfo->csi_lane_params = kzalloc(
+		sizeof(struct msm_camera_csi_lane_params), GFP_KERNEL);
+	if (!pinfo->csi_lane_params) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		goto ERROR2;
+	}
+
+	rc = of_property_read_u32(of_node, "qcom,csi-lane-assign", &val);
+	CDBG("%s qcom,csi-lane-assign %x, rc %d\n", __func__, val, rc);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR3;
+	}
+	pinfo->csi_lane_params->csi_lane_assign = val;
+
+	rc = of_property_read_u32(of_node, "qcom,csi-lane-mask", &val);
+	CDBG("%s qcom,csi-lane-mask %x, rc %d\n", __func__, val, rc);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR3;
+	}
+	pinfo->csi_lane_params->csi_lane_mask = val;
+
+	rc = of_property_read_u32(of_node, "qcom,csi-phy-sel", &val);
+	CDBG("%s qcom,csi-phy-sel %x, rc %d\n", __func__, val, rc);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR3;
+	}
+	sensordata->pdata->csiphy_core = val;
+	kfree(val_array);
+	return rc;
+ERROR3:
+	kfree(pinfo->csi_lane_params);
+ERROR2:
+	kfree(val_array);
+ERROR1:
+	kfree(sensordata->pdata);
+	sensordata->csi_if = 0;
+	return rc;
+}
+static int32_t msm_sensor_init_actuator_data(struct device_node *of_node,
+	struct  msm_camera_sensor_info *sensordata)
+{
+	int32_t rc = 0;
+	uint32_t val = 0;
+
+	rc = of_property_read_u32(of_node, "qcom,actuator-cam-name", &val);
+	CDBG("%s qcom,actuator-cam-name %d, rc %d\n", __func__, val, rc);
+	if (rc < 0)
+		return 0;
+
+	sensordata->actuator_info = kzalloc(sizeof(struct msm_actuator_info),
+		GFP_KERNEL);
+	if (!sensordata->actuator_info) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		goto ERROR;
+	}
+
+	sensordata->actuator_info->cam_name = val;
+
+	rc = of_property_read_u32(of_node, "qcom,actuator-vcm-pwd", &val);
+	CDBG("%s qcom,actuator-vcm-pwd %d, rc %d\n", __func__, val, rc);
+	if (!rc)
+		sensordata->actuator_info->vcm_pwd = val;
+
+	rc = of_property_read_u32(of_node, "qcom,actuator-vcm-enable", &val);
+	CDBG("%s qcom,actuator-vcm-enable %d, rc %d\n", __func__, val, rc);
+	if (!rc)
+		sensordata->actuator_info->vcm_enable = val;
+
+	return 0;
+ERROR:
+	return rc;
+}
+
+static int32_t msm_sensor_init_sensor_data(struct platform_device *pdev,
+	struct msm_sensor_ctrl_t *s_ctrl)
+{
+	int32_t rc = 0, i = 0;
+	uint32_t val = 0;
+	struct device_node *of_node = pdev->dev.of_node;
+	struct msm_camera_sensor_platform_info *pinfo = NULL;
+	struct msm_camera_gpio_conf *gconf = NULL;
+	struct msm_camera_sensor_info *sensordata = NULL;
+	uint16_t *gpio_array = NULL;
+	uint16_t gpio_array_size = 0;
+
+	s_ctrl->sensordata = kzalloc(sizeof(struct msm_camera_sensor_info),
+		GFP_KERNEL);
+	if (!s_ctrl->sensordata) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		return -ENOMEM;
+	}
+
+	sensordata = s_ctrl->sensordata;
+
+	rc = of_property_read_string(of_node, "qcom,sensor-name",
+		&sensordata->sensor_name);
+	CDBG("%s qcom,sensor-name %s, rc %d\n", __func__,
+		sensordata->sensor_name, rc);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR1;
+	}
+
+	rc = of_property_read_u32(of_node, "qcom,camera-type", &val);
+	CDBG("%s qcom,camera-type %d, rc %d\n", __func__, val, rc);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR1;
+	}
+	sensordata->camera_type = val;
+
+	rc = of_property_read_u32(of_node, "qcom,sensor-type", &val);
+	CDBG("%s qcom,sensor-type %d, rc %d\n", __func__, val, rc);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR1;
+	}
+	sensordata->sensor_type = val;
+
+	rc = msm_sensor_init_flash_data(of_node, sensordata);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR1;
+	}
+
+	sensordata->sensor_platform_info = kzalloc(sizeof(
+		struct msm_camera_sensor_platform_info), GFP_KERNEL);
+	if (!sensordata->sensor_platform_info) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		goto ERROR1;
+	}
+
+	pinfo = sensordata->sensor_platform_info;
+
+	rc = of_property_read_u32(of_node, "qcom,mount-angle",
+		&pinfo->mount_angle);
+	CDBG("%s qcom,mount-angle %d, rc %d\n", __func__, pinfo->mount_angle,
+		rc);
+	if (rc < 0) {
+		/* Set default mount angle */
+		pinfo->mount_angle = 0;
+		rc = 0;
+	}
+
+	rc = msm_sensor_init_csi_data(of_node, sensordata);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+
+	rc = msm_sensor_init_vreg_data(of_node, pinfo);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR3;
+	}
+
+	pinfo->gpio_conf = kzalloc(sizeof(struct msm_camera_gpio_conf),
+		GFP_KERNEL);
+	if (!pinfo->gpio_conf) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		goto ERROR4;
+	}
+	gconf = pinfo->gpio_conf;
+	rc = of_property_read_u32(of_node, "qcom,gpio-no-mux",
+		&gconf->gpio_no_mux);
+	CDBG("%s gconf->gpio_no_mux %d, rc %d\n", __func__,
+		gconf->gpio_no_mux, rc);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR5;
+	}
+
+	gpio_array_size = of_gpio_count(of_node);
+	CDBG("%s gpio count %d\n", __func__, gpio_array_size);
+
+	if (gpio_array_size) {
+		gpio_array = kzalloc(sizeof(uint16_t) * gpio_array_size,
+			GFP_KERNEL);
+		if (!gpio_array) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR5;
+		}
+		for (i = 0; i < gpio_array_size; i++) {
+			gpio_array[i] = of_get_gpio(of_node, i);
+			CDBG("%s gpio_array[%d] = %d\n", __func__, i,
+				gpio_array[i]);
+		}
+
+		rc = msm_sensor_init_gpio_common_tbl_data(of_node, gconf,
+			gpio_array, gpio_array_size);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR5;
+		}
+
+		rc = msm_sensor_init_gpio_req_tbl_data(of_node, gconf,
+			gpio_array, gpio_array_size);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR6;
+		}
+
+		rc = msm_sensor_init_gpio_set_tbl_data(of_node, gconf,
+			gpio_array, gpio_array_size);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR7;
+		}
+
+		rc = msm_sensor_init_gpio_tlmm_tbl_data(of_node, gconf,
+			gpio_array, gpio_array_size);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR8;
+		}
+	}
+	rc = msm_sensor_init_actuator_data(of_node, sensordata);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR9;
+	}
+
+	kfree(gpio_array);
+	return rc;
+
+ERROR9:
+	kfree(s_ctrl->sensordata->sensor_platform_info->gpio_conf->
+		camera_on_table);
+	kfree(s_ctrl->sensordata->sensor_platform_info->gpio_conf->
+		camera_off_table);
+ERROR8:
+	kfree(s_ctrl->sensordata->sensor_platform_info->gpio_conf->
+		cam_gpio_set_tbl);
+ERROR7:
+	kfree(s_ctrl->sensordata->sensor_platform_info->gpio_conf->
+		cam_gpio_req_tbl);
+ERROR6:
+	kfree(s_ctrl->sensordata->sensor_platform_info->gpio_conf->
+		cam_gpio_common_tbl);
+ERROR5:
+	kfree(s_ctrl->sensordata->sensor_platform_info->gpio_conf);
+ERROR4:
+	kfree(s_ctrl->sensordata->sensor_platform_info->cam_vreg);
+ERROR3:
+	kfree(s_ctrl->sensordata->sensor_platform_info->csi_lane_params);
+	kfree(s_ctrl->sensordata->pdata);
+ERROR2:
+	kfree(s_ctrl->sensordata->sensor_platform_info);
+	kfree(s_ctrl->sensordata->flash_data);
+ERROR1:
+	kfree(s_ctrl->sensordata);
+	kfree(gpio_array);
+	return rc;
+}
+
+int32_t msm_sensor_free_sensor_data(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	if (!s_ctrl->pdev)
+		return 0;
+	kfree(s_ctrl->sensordata->sensor_platform_info->gpio_conf->
+		camera_on_table);
+	kfree(s_ctrl->sensordata->sensor_platform_info->gpio_conf->
+		camera_off_table);
+	kfree(s_ctrl->sensordata->sensor_platform_info->gpio_conf->
+		cam_gpio_set_tbl);
+	kfree(s_ctrl->sensordata->sensor_platform_info->gpio_conf->
+		cam_gpio_req_tbl);
+	kfree(s_ctrl->sensordata->sensor_platform_info->gpio_conf->
+		cam_gpio_common_tbl);
+	kfree(s_ctrl->sensordata->sensor_platform_info->gpio_conf);
+	kfree(s_ctrl->sensordata->sensor_platform_info->cam_vreg);
+	kfree(s_ctrl->sensordata->sensor_platform_info->csi_lane_params);
+	kfree(s_ctrl->sensordata->pdata);
+	kfree(s_ctrl->sensordata->sensor_platform_info);
+	kfree(s_ctrl->sensordata->flash_data);
+	kfree(s_ctrl->sensordata);
+	return 0;
+}
+
+int32_t msm_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	int32_t rc = 0;
+	struct msm_camera_sensor_info *data = s_ctrl->sensordata;
+	struct device *dev = NULL;
+	if (s_ctrl->sensor_device_type == MSM_SENSOR_PLATFORM_DEVICE)
+		dev = &s_ctrl->pdev->dev;
+	else
+		dev = &s_ctrl->sensor_i2c_client->client->dev;
+	s_ctrl->reg_ptr = kzalloc(sizeof(struct regulator *)
+			* data->sensor_platform_info->num_vreg, GFP_KERNEL);
+	if (!s_ctrl->reg_ptr) {
+		pr_err("%s: could not allocate mem for regulators\n",
+			__func__);
+		return -ENOMEM;
+	}
+
+	rc = msm_camera_request_gpio_table(data, 1);
+	if (rc < 0) {
+		pr_err("%s: request gpio failed\n", __func__);
+		goto request_gpio_failed;
+	}
+
+	rc = msm_camera_config_vreg(dev,
+		s_ctrl->sensordata->sensor_platform_info->cam_vreg,
+		s_ctrl->sensordata->sensor_platform_info->num_vreg,
+		s_ctrl->vreg_seq,
+		s_ctrl->num_vreg_seq,
+		s_ctrl->reg_ptr, 1);
+	if (rc < 0) {
+		pr_err("%s: regulator on failed\n", __func__);
+		goto config_vreg_failed;
+	}
+
+	rc = msm_camera_enable_vreg(dev,
+		s_ctrl->sensordata->sensor_platform_info->cam_vreg,
+		s_ctrl->sensordata->sensor_platform_info->num_vreg,
+		s_ctrl->vreg_seq,
+		s_ctrl->num_vreg_seq,
+		s_ctrl->reg_ptr, 1);
+	if (rc < 0) {
+		pr_err("%s: enable regulator failed\n", __func__);
+		goto enable_vreg_failed;
+	}
+
+	rc = msm_camera_config_gpio_table(data, 1);
+	if (rc < 0) {
+		pr_err("%s: config gpio failed\n", __func__);
+		goto config_gpio_failed;
+	}
+
+	if (s_ctrl->sensor_device_type == MSM_SENSOR_I2C_DEVICE) {
+		if (s_ctrl->clk_rate != 0)
+			cam_8960_clk_info->clk_rate = s_ctrl->clk_rate;
+
+		rc = msm_cam_clk_enable(dev, cam_8960_clk_info,
+			s_ctrl->cam_clk, ARRAY_SIZE(cam_8960_clk_info), 1);
+		if (rc < 0) {
+			pr_err("%s: clk enable failed\n", __func__);
+			goto enable_clk_failed;
+		}
+	} else {
+		rc = msm_cam_clk_enable(dev, cam_8974_clk_info,
+			s_ctrl->cam_clk, ARRAY_SIZE(cam_8974_clk_info), 1);
+		if (rc < 0) {
+			pr_err("%s: clk enable failed\n", __func__);
+			goto enable_clk_failed;
+		}
+	}
+
+	if (!s_ctrl->power_seq_delay)
+		usleep_range(1000, 2000);
+	else if (s_ctrl->power_seq_delay < 20)
+		usleep_range((s_ctrl->power_seq_delay * 1000),
+			((s_ctrl->power_seq_delay * 1000) + 1000));
+	else
+		msleep(s_ctrl->power_seq_delay);
+
+	if (data->sensor_platform_info->ext_power_ctrl != NULL)
+		data->sensor_platform_info->ext_power_ctrl(1);
+
+	if (data->sensor_platform_info->i2c_conf &&
+		data->sensor_platform_info->i2c_conf->use_i2c_mux)
+		msm_sensor_enable_i2c_mux(data->sensor_platform_info->i2c_conf);
+
+	if (s_ctrl->sensor_device_type == MSM_SENSOR_PLATFORM_DEVICE) {
+		rc = msm_sensor_cci_util(s_ctrl->sensor_i2c_client,
+			MSM_CCI_INIT);
+		if (rc < 0) {
+			pr_err("%s cci_init failed\n", __func__);
+			goto cci_init_failed;
+		}
+	}
+	s_ctrl->curr_res = MSM_SENSOR_INVALID_RES;
+	return rc;
+
+cci_init_failed:
+	if (data->sensor_platform_info->i2c_conf &&
+		data->sensor_platform_info->i2c_conf->use_i2c_mux)
+		msm_sensor_disable_i2c_mux(
+			data->sensor_platform_info->i2c_conf);
+enable_clk_failed:
+		msm_camera_config_gpio_table(data, 0);
+config_gpio_failed:
+	msm_camera_enable_vreg(dev,
+			s_ctrl->sensordata->sensor_platform_info->cam_vreg,
+			s_ctrl->sensordata->sensor_platform_info->num_vreg,
+			s_ctrl->vreg_seq,
+			s_ctrl->num_vreg_seq,
+			s_ctrl->reg_ptr, 0);
+
+enable_vreg_failed:
+	msm_camera_config_vreg(dev,
+		s_ctrl->sensordata->sensor_platform_info->cam_vreg,
+		s_ctrl->sensordata->sensor_platform_info->num_vreg,
+		s_ctrl->vreg_seq,
+		s_ctrl->num_vreg_seq,
+		s_ctrl->reg_ptr, 0);
+config_vreg_failed:
+	msm_camera_request_gpio_table(data, 0);
+request_gpio_failed:
+	kfree(s_ctrl->reg_ptr);
+	return rc;
+}
+
+int32_t msm_sensor_power_down(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	struct msm_camera_sensor_info *data = s_ctrl->sensordata;
+	struct device *dev = NULL;
+	if (s_ctrl->sensor_device_type == MSM_SENSOR_PLATFORM_DEVICE)
+		dev = &s_ctrl->pdev->dev;
+	else
+		dev = &s_ctrl->sensor_i2c_client->client->dev;
+	if (s_ctrl->sensor_device_type == MSM_SENSOR_PLATFORM_DEVICE) {
+		msm_sensor_cci_util(s_ctrl->sensor_i2c_client,
+			MSM_CCI_RELEASE);
+	}
+
+	if (data->sensor_platform_info->i2c_conf &&
+		data->sensor_platform_info->i2c_conf->use_i2c_mux)
+		msm_sensor_disable_i2c_mux(
+			data->sensor_platform_info->i2c_conf);
+
+	if (data->sensor_platform_info->ext_power_ctrl != NULL)
+		data->sensor_platform_info->ext_power_ctrl(0);
+	if (s_ctrl->sensor_device_type == MSM_SENSOR_I2C_DEVICE)
+		msm_cam_clk_enable(dev, cam_8960_clk_info, s_ctrl->cam_clk,
+			ARRAY_SIZE(cam_8960_clk_info), 0);
+	else
+		msm_cam_clk_enable(dev, cam_8974_clk_info, s_ctrl->cam_clk,
+			ARRAY_SIZE(cam_8974_clk_info), 0);
+	msm_camera_config_gpio_table(data, 0);
+	msm_camera_enable_vreg(dev,
+		s_ctrl->sensordata->sensor_platform_info->cam_vreg,
+		s_ctrl->sensordata->sensor_platform_info->num_vreg,
+		s_ctrl->vreg_seq,
+		s_ctrl->num_vreg_seq,
+		s_ctrl->reg_ptr, 0);
+	msm_camera_config_vreg(dev,
+		s_ctrl->sensordata->sensor_platform_info->cam_vreg,
+		s_ctrl->sensordata->sensor_platform_info->num_vreg,
+		s_ctrl->vreg_seq,
+		s_ctrl->num_vreg_seq,
+		s_ctrl->reg_ptr, 0);
+	msm_camera_request_gpio_table(data, 0);
+	kfree(s_ctrl->reg_ptr);
+	s_ctrl->curr_res = MSM_SENSOR_INVALID_RES;
+	return 0;
+}
+
+int32_t msm_sensor_match_id(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	int32_t rc = 0;
+	uint16_t chipid = 0;
+	rc = msm_camera_i2c_read(
+			s_ctrl->sensor_i2c_client,
+			s_ctrl->sensor_id_info->sensor_id_reg_addr, &chipid,
+			MSM_CAMERA_I2C_WORD_DATA);
+	if (rc < 0) {
+		pr_err("%s: %s: read id failed\n", __func__,
+			s_ctrl->sensordata->sensor_name);
+		return rc;
+	}
+
+	CDBG("%s: read id: %x expected id %x:\n", __func__, chipid,
+		s_ctrl->sensor_id_info->sensor_id);
+	if (chipid != s_ctrl->sensor_id_info->sensor_id) {
+		pr_err("msm_sensor_match_id chip id doesnot match\n");
+		return -ENODEV;
+	}
+	return rc;
+}
+
+int32_t msm_sensor_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+	struct msm_sensor_ctrl_t *s_ctrl;
+	CDBG("%s %s_i2c_probe called\n", __func__, client->name);
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		pr_err("%s %s i2c_check_functionality failed\n",
+			__func__, client->name);
+		rc = -EFAULT;
+		return rc;
+	}
+
+	s_ctrl = (struct msm_sensor_ctrl_t *)(id->driver_data);
+	s_ctrl->sensor_device_type = MSM_SENSOR_I2C_DEVICE;
+	if (s_ctrl->sensor_i2c_client != NULL) {
+		s_ctrl->sensor_i2c_client->client = client;
+		if (s_ctrl->sensor_i2c_addr != 0)
+			s_ctrl->sensor_i2c_client->client->addr =
+				s_ctrl->sensor_i2c_addr;
+	} else {
+		pr_err("%s %s sensor_i2c_client NULL\n",
+			__func__, client->name);
+		rc = -EFAULT;
+		return rc;
+	}
+
+	s_ctrl->sensordata = client->dev.platform_data;
+	if (s_ctrl->sensordata == NULL) {
+		pr_err("%s %s NULL sensor data\n", __func__, client->name);
+		return -EFAULT;
+	}
+
+	rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
+	if (rc < 0) {
+		pr_err("%s %s power up failed\n", __func__, client->name);
+		return rc;
+	}
+
+	if (s_ctrl->func_tbl->sensor_match_id)
+		rc = s_ctrl->func_tbl->sensor_match_id(s_ctrl);
+	else
+		rc = msm_sensor_match_id(s_ctrl);
+	if (rc < 0)
+		goto probe_fail;
+
+	if (!s_ctrl->wait_num_frames)
+		s_ctrl->wait_num_frames = 1 * Q10;
+
+	pr_err("%s %s probe succeeded\n", __func__, client->name);
+	snprintf(s_ctrl->sensor_v4l2_subdev.name,
+		sizeof(s_ctrl->sensor_v4l2_subdev.name), "%s", id->name);
+	v4l2_i2c_subdev_init(&s_ctrl->sensor_v4l2_subdev, client,
+		s_ctrl->sensor_v4l2_subdev_ops);
+	s_ctrl->sensor_v4l2_subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	media_entity_init(&s_ctrl->sensor_v4l2_subdev.entity, 0, NULL, 0);
+	s_ctrl->sensor_v4l2_subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	s_ctrl->sensor_v4l2_subdev.entity.group_id = SENSOR_DEV;
+	s_ctrl->sensor_v4l2_subdev.entity.name =
+		s_ctrl->sensor_v4l2_subdev.name;
+	msm_sensor_register(&s_ctrl->sensor_v4l2_subdev);
+	s_ctrl->sensor_v4l2_subdev.entity.revision =
+		s_ctrl->sensor_v4l2_subdev.devnode->num;
+	goto power_down;
+probe_fail:
+	pr_err("%s %s_i2c_probe failed\n", __func__, client->name);
+power_down:
+	if (rc > 0)
+		rc = 0;
+	s_ctrl->func_tbl->sensor_power_down(s_ctrl);
+	s_ctrl->sensor_state = MSM_SENSOR_POWER_DOWN;
+	return rc;
+}
+
+static int msm_sensor_subdev_match_core(struct device *dev, void *data)
+{
+	int core_index = (int)data;
+	struct platform_device *pdev = to_platform_device(dev);
+	CDBG("%s cci pdev %p\n", __func__, pdev);
+	if (pdev->id == core_index)
+		return 1;
+	else
+		return 0;
+}
+
+int32_t msm_sensor_platform_probe(struct platform_device *pdev, void *data)
+{
+	int32_t rc = 0;
+	struct msm_sensor_ctrl_t *s_ctrl = (struct msm_sensor_ctrl_t *)data;
+	struct device_driver *driver;
+	struct device *dev;
+	s_ctrl->pdev = pdev;
+	CDBG("%s called data %p\n", __func__, data);
+	if (pdev->dev.of_node) {
+		rc = msm_sensor_init_sensor_data(pdev, s_ctrl);
+		if (rc < 0) {
+			pr_err("%s failed line %d\n", __func__, __LINE__);
+			return rc;
+		}
+	}
+	s_ctrl->sensor_device_type = MSM_SENSOR_PLATFORM_DEVICE;
+	s_ctrl->sensor_i2c_client->cci_client = kzalloc(sizeof(
+		struct msm_camera_cci_client), GFP_KERNEL);
+	if (!s_ctrl->sensor_i2c_client->cci_client) {
+		pr_err("%s failed line %d\n", __func__, __LINE__);
+		return rc;
+	}
+	driver = driver_find(MSM_CCI_DRV_NAME, &platform_bus_type);
+	if (!driver) {
+		pr_err("%s failed line %d\n", __func__, __LINE__);
+		return rc;
+	}
+
+	dev = driver_find_device(driver, NULL, 0,
+				msm_sensor_subdev_match_core);
+	if (!dev) {
+		pr_err("%s failed line %d\n", __func__, __LINE__);
+		return rc;
+	}
+	s_ctrl->sensor_i2c_client->cci_client->cci_subdev =
+		dev_get_drvdata(dev);
+	CDBG("%s sd %p\n", __func__,
+		s_ctrl->sensor_i2c_client->cci_client->cci_subdev);
+	s_ctrl->sensor_i2c_client->cci_client->cci_i2c_master = MASTER_0;
+	s_ctrl->sensor_i2c_client->cci_client->sid =
+		s_ctrl->sensor_i2c_addr >> 1;
+	s_ctrl->sensor_i2c_client->cci_client->retries = 3;
+	s_ctrl->sensor_i2c_client->cci_client->id_map = 0;
+	if (!s_ctrl->wait_num_frames)
+		s_ctrl->wait_num_frames = 1 * Q10;
+
+	rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
+	if (rc < 0) {
+		pr_err("%s %s power up failed\n", __func__,
+			pdev->id_entry->name);
+		return rc;
+	}
+
+	if (s_ctrl->func_tbl->sensor_match_id)
+		rc = s_ctrl->func_tbl->sensor_match_id(s_ctrl);
+	else
+		rc = msm_sensor_match_id(s_ctrl);
+	if (rc < 0)
+		goto probe_fail;
+
+	pr_err("%s %s probe succeeded\n", __func__,
+		s_ctrl->sensordata->sensor_name);
+	v4l2_subdev_init(&s_ctrl->sensor_v4l2_subdev,
+		s_ctrl->sensor_v4l2_subdev_ops);
+	snprintf(s_ctrl->sensor_v4l2_subdev.name,
+		sizeof(s_ctrl->sensor_v4l2_subdev.name), "%s",
+		s_ctrl->sensordata->sensor_name);
+	v4l2_set_subdevdata(&s_ctrl->sensor_v4l2_subdev, pdev);
+	msm_sensor_register(&s_ctrl->sensor_v4l2_subdev);
+
+	goto power_down;
+probe_fail:
+	pr_err("%s %s probe failed\n", __func__, pdev->id_entry->name);
+power_down:
+	s_ctrl->func_tbl->sensor_power_down(s_ctrl);
+	return rc;
+}
+
+int32_t msm_sensor_power(struct v4l2_subdev *sd, int on)
+{
+	int rc = 0;
+	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
+	mutex_lock(s_ctrl->msm_sensor_mutex);
+	if (on) {
+		rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
+		if (rc < 0) {
+			pr_err("%s: %s power_up failed rc = %d\n", __func__,
+				s_ctrl->sensordata->sensor_name, rc);
+			s_ctrl->sensor_state = MSM_SENSOR_POWER_DOWN;
+		} else {
+			if (s_ctrl->func_tbl->sensor_match_id)
+				rc = s_ctrl->func_tbl->sensor_match_id(s_ctrl);
+			else
+				rc = msm_sensor_match_id(s_ctrl);
+			if (rc < 0) {
+				pr_err("%s: %s match_id failed  rc=%d\n",
+					__func__,
+					s_ctrl->sensordata->sensor_name, rc);
+				if (s_ctrl->func_tbl->sensor_power_down(s_ctrl)
+					< 0)
+					pr_err("%s: %s power_down failed\n",
+					__func__,
+					s_ctrl->sensordata->sensor_name);
+				s_ctrl->sensor_state = MSM_SENSOR_POWER_DOWN;
+			}
+			s_ctrl->sensor_state = MSM_SENSOR_POWER_UP;
+		}
+	} else {
+		rc = s_ctrl->func_tbl->sensor_power_down(s_ctrl);
+		s_ctrl->sensor_state = MSM_SENSOR_POWER_DOWN;
+	}
+	mutex_unlock(s_ctrl->msm_sensor_mutex);
+	return rc;
+}
+
+int32_t msm_sensor_v4l2_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
+			   enum v4l2_mbus_pixelcode *code)
+{
+	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
+
+	if ((unsigned int)index >= s_ctrl->sensor_v4l2_subdev_info_size)
+		return -EINVAL;
+
+	*code = s_ctrl->sensor_v4l2_subdev_info[index].code;
+	return 0;
+}
+
+int32_t msm_sensor_v4l2_s_ctrl(struct v4l2_subdev *sd,
+	struct v4l2_control *ctrl)
+{
+	int rc = -1, i = 0;
+	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
+	struct msm_sensor_v4l2_ctrl_info_t *v4l2_ctrl =
+		s_ctrl->msm_sensor_v4l2_ctrl_info;
+
+	CDBG("%s\n", __func__);
+	CDBG("%d\n", ctrl->id);
+	if (v4l2_ctrl == NULL)
+		return rc;
+	for (i = 0; i < s_ctrl->num_v4l2_ctrl; i++) {
+		if (v4l2_ctrl[i].ctrl_id == ctrl->id) {
+			if (v4l2_ctrl[i].s_v4l2_ctrl != NULL) {
+				CDBG("\n calling msm_sensor_s_ctrl_by_enum\n");
+				rc = v4l2_ctrl[i].s_v4l2_ctrl(
+					s_ctrl,
+					&s_ctrl->msm_sensor_v4l2_ctrl_info[i],
+					ctrl->value);
+			}
+			break;
+		}
+	}
+
+	return rc;
+}
+
+int32_t msm_sensor_v4l2_query_ctrl(
+	struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl)
+{
+	int rc = -1, i = 0;
+	struct msm_sensor_ctrl_t *s_ctrl =
+		(struct msm_sensor_ctrl_t *) sd->dev_priv;
+
+	CDBG("%s\n", __func__);
+	CDBG("%s id: %d\n", __func__, qctrl->id);
+
+	if (s_ctrl->msm_sensor_v4l2_ctrl_info == NULL)
+		return rc;
+
+	for (i = 0; i < s_ctrl->num_v4l2_ctrl; i++) {
+		if (s_ctrl->msm_sensor_v4l2_ctrl_info[i].ctrl_id == qctrl->id) {
+			qctrl->minimum =
+				s_ctrl->msm_sensor_v4l2_ctrl_info[i].min;
+			qctrl->maximum =
+				s_ctrl->msm_sensor_v4l2_ctrl_info[i].max;
+			qctrl->flags = 1;
+			rc = 0;
+			break;
+		}
+	}
+
+	return rc;
+}
+
+int msm_sensor_s_ctrl_by_enum(struct msm_sensor_ctrl_t *s_ctrl,
+		struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value)
+{
+	int rc = 0;
+	CDBG("%s enter\n", __func__);
+	rc = msm_sensor_write_enum_conf_array(
+		s_ctrl->sensor_i2c_client,
+		ctrl_info->enum_cfg_settings, value);
+	return rc;
+}
+
+static int msm_sensor_debugfs_stream_s(void *data, u64 val)
+{
+	struct msm_sensor_ctrl_t *s_ctrl = (struct msm_sensor_ctrl_t *) data;
+	if (val)
+		s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
+	else
+		s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(sensor_debugfs_stream, NULL,
+			msm_sensor_debugfs_stream_s, "%llu\n");
+
+static int msm_sensor_debugfs_test_s(void *data, u64 val)
+{
+	CDBG("val: %llu\n", val);
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(sensor_debugfs_test, NULL,
+			msm_sensor_debugfs_test_s, "%llu\n");
+
+int msm_sensor_enable_debugfs(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	struct dentry *debugfs_base, *sensor_dir;
+	debugfs_base = debugfs_create_dir("msm_sensor", NULL);
+	if (!debugfs_base)
+		return -ENOMEM;
+
+	sensor_dir = debugfs_create_dir
+		(s_ctrl->sensordata->sensor_name, debugfs_base);
+	if (!sensor_dir)
+		return -ENOMEM;
+
+	if (!debugfs_create_file("stream", S_IRUGO | S_IWUSR, sensor_dir,
+			(void *) s_ctrl, &sensor_debugfs_stream))
+		return -ENOMEM;
+
+	if (!debugfs_create_file("test", S_IRUGO | S_IWUSR, sensor_dir,
+			(void *) s_ctrl, &sensor_debugfs_test))
+		return -ENOMEM;
+
+	return 0;
+}
diff --git a/drivers/media/platform/msm/camera_v1/sensors/msm_sensor.h b/drivers/media/platform/msm/camera_v1/sensors/msm_sensor.h
new file mode 100644
index 0000000..e144197
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/sensors/msm_sensor.h
@@ -0,0 +1,118 @@
+/* Copyright (c) 2011-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.
+ */
+
+#ifndef MSM_SENSOR_H
+#define MSM_SENSOR_H
+
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/uaccess.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/gpio.h>
+#include <mach/camera.h>
+#include <media/msm_camera.h>
+#include <media/v4l2-subdev.h>
+#include "msm_camera_i2c.h"
+#include "msm_camera_eeprom.h"
+#include "msm_sensor_common.h"
+
+void msm_sensor_start_stream(struct msm_sensor_ctrl_t *s_ctrl);
+void msm_sensor_stop_stream(struct msm_sensor_ctrl_t *s_ctrl);
+void msm_sensor_group_hold_on(struct msm_sensor_ctrl_t *s_ctrl);
+void msm_sensor_group_hold_off(struct msm_sensor_ctrl_t *s_ctrl);
+
+int32_t msm_sensor_set_fps(struct msm_sensor_ctrl_t *s_ctrl,
+			struct fps_cfg   *fps);
+int32_t msm_sensor_write_exp_gain1(struct msm_sensor_ctrl_t *s_ctrl,
+		uint16_t gain, uint32_t line);
+int32_t msm_sensor_write_exp_gain2(struct msm_sensor_ctrl_t *s_ctrl,
+		uint16_t gain, uint32_t line);
+int32_t msm_sensor_set_sensor_mode(struct msm_sensor_ctrl_t *s_ctrl,
+	int mode, int res);
+int32_t msm_sensor_mode_init(struct msm_sensor_ctrl_t *s_ctrl,
+			int mode, struct sensor_init_cfg *init_info);
+int32_t msm_sensor_get_output_info(struct msm_sensor_ctrl_t *,
+		struct sensor_output_info_t *);
+int32_t msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl,
+			void __user *argp);
+int32_t msm_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl);
+int32_t msm_sensor_power_down(struct msm_sensor_ctrl_t *s_ctrl);
+
+int32_t msm_sensor_match_id(struct msm_sensor_ctrl_t *s_ctrl);
+int msm_sensor_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id);
+
+int32_t msm_sensor_platform_probe(struct platform_device *pdev, void *data);
+
+int32_t msm_sensor_power(struct v4l2_subdev *sd, int on);
+
+int32_t msm_sensor_v4l2_s_ctrl(struct v4l2_subdev *sd,
+	struct v4l2_control *ctrl);
+
+int32_t msm_sensor_v4l2_query_ctrl(
+	struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl);
+
+int msm_sensor_s_ctrl_by_index(struct msm_sensor_ctrl_t *s_ctrl,
+	struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value);
+
+int msm_sensor_s_ctrl_by_enum(struct msm_sensor_ctrl_t *s_ctrl,
+		struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value);
+
+int msm_sensor_v4l2_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
+			enum v4l2_mbus_pixelcode *code);
+
+int msm_sensor_write_init_settings(struct msm_sensor_ctrl_t *s_ctrl);
+int msm_sensor_write_res_settings
+	(struct msm_sensor_ctrl_t *s_ctrl, uint16_t res);
+
+int32_t msm_sensor_write_output_settings(struct msm_sensor_ctrl_t *s_ctrl,
+	uint16_t res);
+
+void msm_sensor_adjust_frame_lines1(struct msm_sensor_ctrl_t *s_ctrl);
+
+void msm_sensor_adjust_frame_lines2(struct msm_sensor_ctrl_t *s_ctrl);
+
+int32_t msm_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
+			int update_type, int res);
+
+int32_t msm_sensor_setting1(struct msm_sensor_ctrl_t *s_ctrl,
+			int update_type, int res);
+
+int msm_sensor_enable_debugfs(struct msm_sensor_ctrl_t *s_ctrl);
+
+long msm_sensor_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int cmd, void *arg);
+
+int32_t msm_sensor_get_csi_params(struct msm_sensor_ctrl_t *s_ctrl,
+		struct csi_lane_params_t *sensor_output_info);
+
+struct msm_sensor_ctrl_t *get_sctrl(struct v4l2_subdev *sd);
+int32_t msm_sensor_free_sensor_data(struct msm_sensor_ctrl_t *s_ctrl);
+
+#define VIDIOC_MSM_SENSOR_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 4, void __user *)
+
+#define VIDIOC_MSM_SENSOR_RELEASE \
+	_IO('V', BASE_VIDIOC_PRIVATE + 11)
+
+#define VIDIOC_MSM_SENSOR_CSID_INFO\
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 12, struct msm_sensor_csi_info *)
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v1/sensors/msm_sensor_bayer.c b/drivers/media/platform/msm/camera_v1/sensors/msm_sensor_bayer.c
new file mode 100644
index 0000000..18e78a8
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/sensors/msm_sensor_bayer.c
@@ -0,0 +1,909 @@
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include "msm_sensor_bayer.h"
+#include "msm.h"
+#include "msm_ispif.h"
+#include "msm_camera_i2c_mux.h"
+/*=============================================================*/
+
+long msm_sensor_bayer_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int cmd, void *arg)
+{
+	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
+	void __user *argp = (void __user *)arg;
+	switch (cmd) {
+	case VIDIOC_MSM_SENSOR_CFG:
+		return s_ctrl->func_tbl->sensor_config(s_ctrl, argp);
+	case VIDIOC_MSM_SENSOR_RELEASE:
+		return 0;
+	case VIDIOC_MSM_SENSOR_CSID_INFO: {
+		struct msm_sensor_csi_info *csi_info =
+			(struct msm_sensor_csi_info *)arg;
+		s_ctrl->is_csic = csi_info->is_csic;
+		return 0;
+	}
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
+int32_t msm_sensor_bayer_get_csi_params(struct msm_sensor_ctrl_t *s_ctrl,
+		struct csi_lane_params_t *sensor_output_info)
+{
+	uint8_t index;
+	struct msm_camera_csi_lane_params *csi_lane_params =
+		s_ctrl->sensordata->sensor_platform_info->csi_lane_params;
+	if (csi_lane_params) {
+		sensor_output_info->csi_lane_assign = csi_lane_params->
+			csi_lane_assign;
+		sensor_output_info->csi_lane_mask = csi_lane_params->
+			csi_lane_mask;
+	}
+	sensor_output_info->csi_if = s_ctrl->sensordata->csi_if;
+	for (index = 0; index < sensor_output_info->csi_if; index++)
+		sensor_output_info->csid_core[index] = s_ctrl->sensordata->
+			pdata[index].csid_core;
+
+	return 0;
+}
+
+int32_t msm_sensor_bayer_config(struct msm_sensor_ctrl_t *s_ctrl,
+	void __user *argp)
+{
+	struct sensor_cfg_data cdata;
+	long rc = 0;
+	if (copy_from_user(&cdata,
+		(void *)argp,
+		sizeof(struct sensor_cfg_data)))
+		return -EFAULT;
+	mutex_lock(s_ctrl->msm_sensor_mutex);
+	CDBG("%s:%d %s cfgtype = %d\n", __func__, __LINE__,
+		s_ctrl->sensordata->sensor_name, cdata.cfgtype);
+	switch (cdata.cfgtype) {
+	case CFG_WRITE_I2C_ARRAY: {
+		struct msm_camera_i2c_reg_setting conf_array;
+		struct msm_camera_i2c_reg_array *regs = NULL;
+
+		if (copy_from_user(&conf_array,
+			(void *)cdata.cfg.setting,
+			sizeof(struct msm_camera_i2c_reg_setting))) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			rc = -EFAULT;
+			break;
+		}
+
+		regs = kzalloc(conf_array.size * sizeof(
+			struct msm_camera_i2c_reg_array),
+			GFP_KERNEL);
+		if (!regs) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			rc = -EFAULT;
+			break;
+		}
+
+		if (copy_from_user(regs, (void *)conf_array.reg_setting,
+			conf_array.size * sizeof(
+			struct msm_camera_i2c_reg_array))) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			kfree(regs);
+			rc = -EFAULT;
+			break;
+		}
+
+		conf_array.reg_setting = regs;
+		rc = msm_camera_i2c_write_bayer_table(s_ctrl->sensor_i2c_client,
+			&conf_array);
+		kfree(regs);
+		break;
+	}
+	case CFG_READ_I2C_ARRAY: {
+		struct msm_camera_i2c_reg_setting conf_array;
+		struct msm_camera_i2c_reg_array *regs;
+		int index;
+
+		if (copy_from_user(&conf_array,
+				(void *)cdata.cfg.setting,
+				sizeof(struct msm_camera_i2c_reg_setting))) {
+				pr_err("%s:%d failed\n", __func__, __LINE__);
+				rc = -EFAULT;
+				break;
+		}
+
+		regs = kzalloc(conf_array.size * sizeof(
+				struct msm_camera_i2c_reg_array),
+				GFP_KERNEL);
+		if (!regs) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			rc = -EFAULT;
+			kfree(regs);
+			break;
+		}
+
+		if (copy_from_user(regs, (void *)conf_array.reg_setting,
+				conf_array.size * sizeof(
+				struct msm_camera_i2c_reg_array))) {
+				pr_err("%s:%d failed\n", __func__, __LINE__);
+				kfree(regs);
+				rc = -EFAULT;
+				break;
+			}
+
+		s_ctrl->sensor_i2c_client->addr_type = conf_array.addr_type;
+		for (index = 0; index < conf_array.size; index++) {
+			msm_camera_i2c_read(s_ctrl->sensor_i2c_client,
+					regs[index].reg_addr,
+					&regs[index].reg_data,
+				conf_array.data_type
+				);
+		}
+
+		if (copy_to_user(conf_array.reg_setting,
+			regs,
+			conf_array.size * sizeof(
+			struct msm_camera_i2c_reg_array))) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			kfree(regs);
+			rc = -EFAULT;
+			break;
+		}
+		s_ctrl->sensor_i2c_client->addr_type = conf_array.addr_type;
+		kfree(regs);
+		break;
+	}
+	case CFG_PCLK_CHANGE: {
+		uint32_t pclk = cdata.cfg.pclk;
+		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
+			NOTIFY_PCLK_CHANGE, &pclk);
+		break;
+	}
+	case CFG_GPIO_OP: {
+		struct msm_cam_gpio_operation gop;
+		if (copy_from_user(&gop,
+			(void *)cdata.cfg.setting,
+			sizeof(struct msm_cam_gpio_operation))) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+		}
+		switch (gop.op_type) {
+		case GPIO_GET_VALUE:
+			gop.value = gpio_get_value(gop.address);
+			if (copy_from_user((void *)cdata.cfg.setting,
+				&gop,
+				sizeof(struct msm_cam_gpio_operation))) {
+				pr_err("%s:%d failed\n", __func__, __LINE__);
+				rc = -EFAULT;
+				break;
+			}
+			break;
+		case GPIO_SET_VALUE:
+			gpio_set_value(gop.address, gop.value);
+			break;
+		case GPIO_SET_DIRECTION_INPUT:
+			gpio_direction_input(gop.address);
+			break;
+		case GPIO_SET_DIRECTION_OUTPUT:
+			gpio_direction_output(gop.address, gop.value);
+			break;
+		case GPIO_REQUEST:
+			gpio_request(gop.address, gop.tag);
+			break;
+		case GPIO_FREE:
+			gpio_free(gop.address);
+			break;
+		default:
+			break;
+		}
+
+		break;
+	}
+	case CFG_GET_CSI_PARAMS:
+		if (s_ctrl->func_tbl->sensor_get_csi_params == NULL) {
+			rc = -EFAULT;
+			break;
+		}
+		rc = s_ctrl->func_tbl->sensor_get_csi_params(
+			s_ctrl,
+			&cdata.cfg.csi_lane_params);
+
+		if (copy_to_user((void *)argp,
+			&cdata,
+			sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_POWER_UP:
+		if (s_ctrl->func_tbl->sensor_power_up)
+			rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
+		else
+			rc = -EFAULT;
+		break;
+
+	case CFG_POWER_DOWN:
+		if (s_ctrl->func_tbl->sensor_power_down)
+			rc = s_ctrl->func_tbl->sensor_power_down(
+				s_ctrl);
+		else
+			rc = -EFAULT;
+		break;
+
+	case CFG_CONFIG_VREG_ARRAY: {
+		struct msm_camera_vreg_setting vreg_setting;
+		struct camera_vreg_t *cam_vreg = NULL;
+
+		if (copy_from_user(&vreg_setting,
+			(void *)cdata.cfg.setting,
+			sizeof(struct msm_camera_vreg_setting))) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			rc = -EFAULT;
+			break;
+		}
+
+		cam_vreg = kzalloc(vreg_setting.num_vreg * sizeof(
+			struct camera_vreg_t),
+			GFP_KERNEL);
+		if (!cam_vreg) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			rc = -EFAULT;
+			break;
+		}
+
+		if (copy_from_user(cam_vreg, (void *)vreg_setting.cam_vreg,
+			vreg_setting.num_vreg * sizeof(
+			struct camera_vreg_t))) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			kfree(cam_vreg);
+			rc = -EFAULT;
+			break;
+		}
+		rc = msm_camera_config_vreg(
+			&s_ctrl->sensor_i2c_client->client->dev,
+			cam_vreg,
+			vreg_setting.num_vreg,
+			NULL,
+			0,
+			s_ctrl->reg_ptr,
+			vreg_setting.enable);
+		if (rc < 0) {
+			kfree(cam_vreg);
+			pr_err("%s: regulator on failed\n", __func__);
+			break;
+		}
+
+		rc = msm_camera_enable_vreg(
+			&s_ctrl->sensor_i2c_client->client->dev,
+			cam_vreg,
+			vreg_setting.num_vreg,
+			NULL,
+			0,
+			s_ctrl->reg_ptr,
+			vreg_setting.enable);
+		if (rc < 0) {
+			kfree(cam_vreg);
+			pr_err("%s: enable regulator failed\n", __func__);
+			break;
+		}
+		kfree(cam_vreg);
+		break;
+	}
+	case CFG_CONFIG_CLK_ARRAY: {
+		struct msm_cam_clk_setting clk_setting;
+		struct msm_cam_clk_info *clk_info = NULL;
+
+		if (copy_from_user(&clk_setting,
+			(void *)cdata.cfg.setting,
+			sizeof(struct msm_camera_vreg_setting))) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			rc = -EFAULT;
+			break;
+		}
+
+		clk_info = kzalloc(clk_setting.num_clk_info * sizeof(
+			struct msm_cam_clk_info),
+			GFP_KERNEL);
+		if (!clk_info) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			rc = -EFAULT;
+			break;
+		}
+
+		if (copy_from_user(clk_info, (void *)clk_setting.clk_info,
+			clk_setting.num_clk_info * sizeof(
+			struct msm_cam_clk_info))) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			kfree(clk_info);
+			rc = -EFAULT;
+			break;
+		}
+		rc = msm_cam_clk_enable(&s_ctrl->sensor_i2c_client->client->dev,
+			clk_info, s_ctrl->cam_clk,
+			clk_setting.num_clk_info,
+			clk_setting.enable);
+		kfree(clk_info);
+		break;
+	}
+	case CFG_GET_EEPROM_DATA: {
+		if (copy_to_user((void *)cdata.cfg.eeprom_data.eeprom_data,
+			&s_ctrl->eeprom_data.data, s_ctrl->eeprom_data.length)){
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			rc = -EFAULT;
+		}
+		cdata.cfg.eeprom_data.index = s_ctrl->eeprom_data.length;
+		break;
+	}
+	default:
+		rc = -EFAULT;
+		break;
+	}
+
+	mutex_unlock(s_ctrl->msm_sensor_mutex);
+
+	return rc;
+}
+
+static struct msm_cam_clk_info cam_clk_info[] = {
+	{"cam_clk", MSM_SENSOR_MCLK_24HZ},
+};
+
+int32_t msm_sensor_bayer_enable_i2c_mux(struct msm_camera_i2c_conf *i2c_conf)
+{
+	struct v4l2_subdev *i2c_mux_sd =
+		dev_get_drvdata(&i2c_conf->mux_dev->dev);
+	v4l2_subdev_call(i2c_mux_sd, core, ioctl,
+		VIDIOC_MSM_I2C_MUX_INIT, NULL);
+	v4l2_subdev_call(i2c_mux_sd, core, ioctl,
+		VIDIOC_MSM_I2C_MUX_CFG, (void *)&i2c_conf->i2c_mux_mode);
+	return 0;
+}
+
+int32_t msm_sensor_bayer_disable_i2c_mux(struct msm_camera_i2c_conf *i2c_conf)
+{
+	struct v4l2_subdev *i2c_mux_sd =
+		dev_get_drvdata(&i2c_conf->mux_dev->dev);
+	v4l2_subdev_call(i2c_mux_sd, core, ioctl,
+				VIDIOC_MSM_I2C_MUX_RELEASE, NULL);
+	return 0;
+}
+
+static struct msm_camera_power_seq_t sensor_power_seq[] = {
+	{REQUEST_GPIO, 0},
+	{REQUEST_VREG, 0},
+	{ENABLE_VREG, 0},
+	{ENABLE_GPIO, 0},
+	{CONFIG_CLK, 0},
+	{CONFIG_EXT_POWER_CTRL, 0},
+	{CONFIG_I2C_MUX, 0},
+};
+
+int32_t msm_sensor_bayer_power_up(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	int32_t rc = 0, size = 0, index = 0;
+	struct msm_camera_sensor_info *data = s_ctrl->sensordata;
+	struct msm_camera_power_seq_t *power_seq = NULL;
+	CDBG("%s: %d\n", __func__, __LINE__);
+	if (s_ctrl->power_seq) {
+		power_seq = s_ctrl->power_seq;
+		size = s_ctrl->num_power_seq;
+	} else {
+		power_seq = &sensor_power_seq[0];
+		size = ARRAY_SIZE(sensor_power_seq);
+	}
+
+	s_ctrl->reg_ptr = kzalloc(sizeof(struct regulator *)
+			* data->sensor_platform_info->num_vreg, GFP_KERNEL);
+	if (!s_ctrl->reg_ptr) {
+		pr_err("%s: could not allocate mem for regulators\n",
+			__func__);
+		return -ENOMEM;
+	}
+
+	for (index = 0; index < size; index++) {
+		switch (power_seq[index].power_config) {
+		case REQUEST_GPIO:
+			rc = msm_camera_request_gpio_table(data, 1);
+			if (rc < 0) {
+				pr_err("%s: request gpio failed\n", __func__);
+				goto ERROR;
+			}
+			if (power_seq[index].delay)
+				usleep_range(power_seq[index].delay * 1000,
+					(power_seq[index].delay * 1000) + 1000);
+			break;
+		case REQUEST_VREG:
+			rc = msm_camera_config_vreg(
+				&s_ctrl->sensor_i2c_client->client->dev,
+				s_ctrl->sensordata->sensor_platform_info->
+				cam_vreg,
+				s_ctrl->sensordata->sensor_platform_info->
+				num_vreg,
+				s_ctrl->vreg_seq,
+				s_ctrl->num_vreg_seq,
+				s_ctrl->reg_ptr, 1);
+			if (rc < 0) {
+				pr_err("%s: regulator on failed\n", __func__);
+				goto ERROR;
+			}
+			if (power_seq[index].delay)
+				usleep_range(power_seq[index].delay * 1000,
+					(power_seq[index].delay * 1000) + 1000);
+			break;
+		case ENABLE_VREG:
+			rc = msm_camera_enable_vreg(
+				&s_ctrl->sensor_i2c_client->client->dev,
+				s_ctrl->sensordata->sensor_platform_info->
+				cam_vreg,
+				s_ctrl->sensordata->sensor_platform_info->
+				num_vreg,
+				s_ctrl->vreg_seq,
+				s_ctrl->num_vreg_seq,
+				s_ctrl->reg_ptr, 1);
+			if (rc < 0) {
+				pr_err("%s: enable regulator failed\n",
+					__func__);
+				goto ERROR;
+			}
+			if (power_seq[index].delay)
+				usleep_range(power_seq[index].delay * 1000,
+					(power_seq[index].delay * 1000) + 1000);
+			break;
+		case ENABLE_GPIO:
+			rc = msm_camera_config_gpio_table(data, 1);
+			if (rc < 0) {
+				pr_err("%s: config gpio failed\n", __func__);
+				goto ERROR;
+			}
+			if (power_seq[index].delay)
+				usleep_range(power_seq[index].delay * 1000,
+					(power_seq[index].delay * 1000) + 1000);
+			break;
+		case CONFIG_CLK:
+			if (s_ctrl->clk_rate != 0)
+				cam_clk_info->clk_rate = s_ctrl->clk_rate;
+
+			rc = msm_cam_clk_enable(
+				&s_ctrl->sensor_i2c_client->client->dev,
+				cam_clk_info, s_ctrl->cam_clk,
+				ARRAY_SIZE(cam_clk_info), 1);
+			if (rc < 0) {
+				pr_err("%s: clk enable failed\n", __func__);
+				goto ERROR;
+			}
+			if (power_seq[index].delay)
+				usleep_range(power_seq[index].delay * 1000,
+					(power_seq[index].delay * 1000) + 1000);
+			break;
+		case CONFIG_EXT_POWER_CTRL:
+			if (data->sensor_platform_info->ext_power_ctrl != NULL)
+				data->sensor_platform_info->ext_power_ctrl(1);
+			if (power_seq[index].delay)
+				usleep_range(power_seq[index].delay * 1000,
+					(power_seq[index].delay * 1000) + 1000);
+			break;
+		case CONFIG_I2C_MUX:
+			if (data->sensor_platform_info->i2c_conf &&
+				data->sensor_platform_info->i2c_conf->
+				use_i2c_mux)
+				msm_sensor_bayer_enable_i2c_mux(
+					data->sensor_platform_info->i2c_conf);
+			if (power_seq[index].delay)
+				usleep_range(power_seq[index].delay * 1000,
+					(power_seq[index].delay * 1000) + 1000);
+			break;
+		default:
+			pr_err("%s error power config %d\n", __func__,
+				power_seq[index].power_config);
+			rc = -EINVAL;
+			break;
+		}
+	}
+
+	return rc;
+
+ERROR:
+	for (index--; index >= 0; index--) {
+		switch (power_seq[index].power_config) {
+		case CONFIG_I2C_MUX:
+			if (data->sensor_platform_info->i2c_conf &&
+				data->sensor_platform_info->i2c_conf->
+				use_i2c_mux)
+				msm_sensor_bayer_disable_i2c_mux(
+					data->sensor_platform_info->i2c_conf);
+			break;
+		case CONFIG_EXT_POWER_CTRL:
+			if (data->sensor_platform_info->ext_power_ctrl != NULL)
+				data->sensor_platform_info->ext_power_ctrl(0);
+			break;
+		case CONFIG_CLK:
+			msm_cam_clk_enable(&s_ctrl->sensor_i2c_client->client->
+				dev, cam_clk_info, s_ctrl->cam_clk,
+				ARRAY_SIZE(cam_clk_info), 0);
+			break;
+		case ENABLE_GPIO:
+			msm_camera_config_gpio_table(data, 0);
+			break;
+		case ENABLE_VREG:
+			msm_camera_enable_vreg(&s_ctrl->sensor_i2c_client->
+				client->dev,
+				s_ctrl->sensordata->sensor_platform_info->
+				cam_vreg,
+				s_ctrl->sensordata->sensor_platform_info->
+				num_vreg,
+				s_ctrl->vreg_seq,
+				s_ctrl->num_vreg_seq,
+				s_ctrl->reg_ptr, 0);
+			break;
+		case REQUEST_VREG:
+			msm_camera_config_vreg(&s_ctrl->sensor_i2c_client->
+				client->dev,
+				s_ctrl->sensordata->sensor_platform_info->
+				cam_vreg,
+				s_ctrl->sensordata->sensor_platform_info->
+				num_vreg,
+				s_ctrl->vreg_seq,
+				s_ctrl->num_vreg_seq,
+				s_ctrl->reg_ptr, 0);
+			break;
+		case REQUEST_GPIO:
+			msm_camera_request_gpio_table(data, 0);
+			break;
+		default:
+			pr_err("%s error power config %d\n", __func__,
+				power_seq[index].power_config);
+			break;
+		}
+	}
+	kfree(s_ctrl->reg_ptr);
+	return rc;
+}
+
+int32_t msm_sensor_bayer_power_down(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	int32_t size = 0, index = 0;
+	struct msm_camera_sensor_info *data = s_ctrl->sensordata;
+	struct msm_camera_power_seq_t *power_seq = NULL;
+	CDBG("%s\n", __func__);
+
+	if (s_ctrl->power_seq) {
+		power_seq = s_ctrl->power_seq;
+		size = s_ctrl->num_power_seq;
+	} else {
+		power_seq = &sensor_power_seq[0];
+		size = ARRAY_SIZE(sensor_power_seq);
+	}
+
+	for (index = (size - 1); index >= 0; index--) {
+		switch (power_seq[index].power_config) {
+		case CONFIG_I2C_MUX:
+			if (data->sensor_platform_info->i2c_conf &&
+				data->sensor_platform_info->i2c_conf->
+				use_i2c_mux)
+				msm_sensor_bayer_disable_i2c_mux(
+					data->sensor_platform_info->i2c_conf);
+			break;
+		case CONFIG_EXT_POWER_CTRL:
+			if (data->sensor_platform_info->ext_power_ctrl != NULL)
+				data->sensor_platform_info->ext_power_ctrl(0);
+			break;
+		case CONFIG_CLK:
+			msm_cam_clk_enable(&s_ctrl->sensor_i2c_client->client->
+				dev, cam_clk_info, s_ctrl->cam_clk,
+				ARRAY_SIZE(cam_clk_info), 0);
+			break;
+		case ENABLE_GPIO:
+			msm_camera_config_gpio_table(data, 0);
+			break;
+		case ENABLE_VREG:
+			msm_camera_enable_vreg(&s_ctrl->sensor_i2c_client->
+				client->dev,
+				s_ctrl->sensordata->sensor_platform_info->
+				cam_vreg,
+				s_ctrl->sensordata->sensor_platform_info->
+				num_vreg,
+				s_ctrl->vreg_seq,
+				s_ctrl->num_vreg_seq,
+				s_ctrl->reg_ptr, 0);
+			break;
+		case REQUEST_VREG:
+			msm_camera_config_vreg(&s_ctrl->sensor_i2c_client->
+				client->dev,
+				s_ctrl->sensordata->sensor_platform_info->
+				cam_vreg,
+				s_ctrl->sensordata->sensor_platform_info->
+				num_vreg,
+				s_ctrl->vreg_seq,
+				s_ctrl->num_vreg_seq,
+				s_ctrl->reg_ptr, 0);
+			break;
+		case REQUEST_GPIO:
+			msm_camera_request_gpio_table(data, 0);
+			break;
+		default:
+			pr_err("%s error power config %d\n", __func__,
+				power_seq[index].power_config);
+			break;
+		}
+	}
+	kfree(s_ctrl->reg_ptr);
+	return 0;
+}
+
+int32_t msm_sensor_bayer_match_id(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	int32_t rc = 0;
+	uint16_t chipid = 0;
+	rc = msm_camera_i2c_read(
+			s_ctrl->sensor_i2c_client,
+			s_ctrl->sensor_id_info->sensor_id_reg_addr, &chipid,
+			MSM_CAMERA_I2C_WORD_DATA);
+	if (rc < 0) {
+		pr_err("%s: %s: read id failed\n", __func__,
+			s_ctrl->sensordata->sensor_name);
+		return rc;
+	}
+
+	CDBG("%s: read id: %x expected id %x:\n", __func__, chipid,
+		s_ctrl->sensor_id_info->sensor_id);
+	if (chipid != s_ctrl->sensor_id_info->sensor_id) {
+		pr_err("msm_sensor_match_id chip id doesnot match\n");
+		return -ENODEV;
+	}
+	return rc;
+}
+
+int32_t msm_sensor_bayer_eeprom_read(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	uint32_t reg_addr = 0;
+	uint8_t *data = s_ctrl->eeprom_data.data;
+	uint32_t num_byte = 0;
+	int rc = 0;
+	uint32_t i2c_addr;
+	struct msm_camera_sensor_info *sensor_info = s_ctrl->sensordata;
+	i2c_addr = sensor_info->eeprom_info->eeprom_i2c_slave_addr;
+	num_byte = s_ctrl->eeprom_data.length = sensor_info->eeprom_info->
+		eeprom_read_length;
+	reg_addr = sensor_info->eeprom_info->eeprom_reg_addr;
+
+	data = kzalloc(num_byte * sizeof(uint8_t), GFP_KERNEL);
+	if (!data) {
+		pr_err("%s:%d failed\n", __func__, __LINE__);
+		rc = -EFAULT;
+		return rc;
+	}
+
+	s_ctrl->sensor_i2c_client->client->addr = i2c_addr;
+	CDBG("eeprom read: i2c addr is %x num byte %d  reg addr %x\n",
+		i2c_addr, num_byte, reg_addr);
+	rc = msm_camera_i2c_read_seq(s_ctrl->sensor_i2c_client, reg_addr, data,
+		num_byte);
+	s_ctrl->sensor_i2c_client->client->addr = s_ctrl->sensor_i2c_addr;
+	return rc;
+}
+
+int32_t msm_sensor_bayer_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+	struct msm_sensor_ctrl_t *s_ctrl;
+	CDBG("%s %s_i2c_probe called\n", __func__, client->name);
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		pr_err("%s %s i2c_check_functionality failed\n",
+			__func__, client->name);
+		rc = -EFAULT;
+		return rc;
+	}
+
+	s_ctrl = (struct msm_sensor_ctrl_t *)(id->driver_data);
+	if (s_ctrl->sensor_i2c_client != NULL) {
+		s_ctrl->sensor_i2c_client->client = client;
+		if (s_ctrl->sensor_i2c_addr != 0)
+			s_ctrl->sensor_i2c_client->client->addr =
+				s_ctrl->sensor_i2c_addr;
+	} else {
+		pr_err("%s %s sensor_i2c_client NULL\n",
+			__func__, client->name);
+		rc = -EFAULT;
+		return rc;
+	}
+
+	s_ctrl->sensordata = client->dev.platform_data;
+	if (s_ctrl->sensordata == NULL) {
+		pr_err("%s %s NULL sensor data\n", __func__, client->name);
+		return -EFAULT;
+	}
+
+	rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
+	if (rc < 0) {
+		pr_err("%s %s power up failed\n", __func__, client->name);
+		return rc;
+	}
+
+	if (s_ctrl->func_tbl->sensor_match_id)
+		rc = s_ctrl->func_tbl->sensor_match_id(s_ctrl);
+	else
+		rc = msm_sensor_bayer_match_id(s_ctrl);
+	if (rc < 0)
+		goto probe_fail;
+
+	if (!s_ctrl->wait_num_frames)
+		s_ctrl->wait_num_frames = 1;
+
+	pr_err("%s %s probe succeeded\n", __func__, client->name);
+	snprintf(s_ctrl->sensor_v4l2_subdev.name,
+		sizeof(s_ctrl->sensor_v4l2_subdev.name), "%s", id->name);
+	v4l2_i2c_subdev_init(&s_ctrl->sensor_v4l2_subdev, client,
+		s_ctrl->sensor_v4l2_subdev_ops);
+	s_ctrl->sensor_v4l2_subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	media_entity_init(&s_ctrl->sensor_v4l2_subdev.entity, 0, NULL, 0);
+	s_ctrl->sensor_v4l2_subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	s_ctrl->sensor_v4l2_subdev.entity.group_id = SENSOR_DEV;
+	s_ctrl->sensor_v4l2_subdev.entity.name =
+		s_ctrl->sensor_v4l2_subdev.name;
+	msm_sensor_register(&s_ctrl->sensor_v4l2_subdev);
+	s_ctrl->sensor_v4l2_subdev.entity.revision =
+		s_ctrl->sensor_v4l2_subdev.devnode->num;
+	if (s_ctrl->func_tbl->sensor_read_eeprom != NULL)
+		s_ctrl->func_tbl->sensor_read_eeprom(s_ctrl);
+	else
+		msm_sensor_bayer_eeprom_read(s_ctrl);
+	goto power_down;
+probe_fail:
+	pr_err("%s %s_i2c_probe failed\n", __func__, client->name);
+power_down:
+	if (rc > 0)
+		rc = 0;
+	s_ctrl->func_tbl->sensor_power_down(s_ctrl);
+	return rc;
+}
+
+int32_t msm_sensor_delay_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+	struct msm_sensor_ctrl_t *s_ctrl;
+	CDBG("%s %s_delay_i2c_probe called\n", __func__, client->name);
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		pr_err("%s %s i2c_check_functionality failed\n",
+			__func__, client->name);
+		rc = -EFAULT;
+		return rc;
+	}
+
+	s_ctrl = (struct msm_sensor_ctrl_t *)(id->driver_data);
+	if (s_ctrl->sensor_i2c_client != NULL) {
+		s_ctrl->sensor_i2c_client->client = client;
+		if (s_ctrl->sensor_i2c_addr != 0)
+			s_ctrl->sensor_i2c_client->client->addr =
+				s_ctrl->sensor_i2c_addr;
+	} else {
+		pr_err("%s %s sensor_i2c_client NULL\n",
+			__func__, client->name);
+		rc = -EFAULT;
+		return rc;
+	}
+
+	s_ctrl->sensordata = client->dev.platform_data;
+	if (s_ctrl->sensordata == NULL) {
+		pr_err("%s %s NULL sensor data\n", __func__, client->name);
+		return -EFAULT;
+	}
+
+	if (!s_ctrl->wait_num_frames)
+		s_ctrl->wait_num_frames = 1;
+
+	pr_err("%s %s probe succeeded\n", __func__, client->name);
+	snprintf(s_ctrl->sensor_v4l2_subdev.name,
+		sizeof(s_ctrl->sensor_v4l2_subdev.name), "%s", id->name);
+	v4l2_i2c_subdev_init(&s_ctrl->sensor_v4l2_subdev, client,
+		s_ctrl->sensor_v4l2_subdev_ops);
+	s_ctrl->sensor_v4l2_subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	media_entity_init(&s_ctrl->sensor_v4l2_subdev.entity, 0, NULL, 0);
+	s_ctrl->sensor_v4l2_subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	s_ctrl->sensor_v4l2_subdev.entity.group_id = SENSOR_DEV;
+	s_ctrl->sensor_v4l2_subdev.entity.name =
+		s_ctrl->sensor_v4l2_subdev.name;
+	msm_sensor_register(&s_ctrl->sensor_v4l2_subdev);
+	s_ctrl->sensor_v4l2_subdev.entity.revision =
+		s_ctrl->sensor_v4l2_subdev.devnode->num;
+	if (rc > 0)
+		rc = 0;
+	return rc;
+}
+
+int32_t msm_sensor_bayer_power(struct v4l2_subdev *sd, int on)
+{
+	int rc = 0;
+	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
+	mutex_lock(s_ctrl->msm_sensor_mutex);
+	if (!on)
+		rc = s_ctrl->func_tbl->sensor_power_down(s_ctrl);
+	mutex_unlock(s_ctrl->msm_sensor_mutex);
+	return rc;
+}
+
+int32_t msm_sensor_bayer_v4l2_enum_fmt(struct v4l2_subdev *sd,
+	unsigned int index, enum v4l2_mbus_pixelcode *code)
+{
+	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
+
+	if ((unsigned int)index >= s_ctrl->sensor_v4l2_subdev_info_size)
+		return -EINVAL;
+
+	*code = s_ctrl->sensor_v4l2_subdev_info[index].code;
+	return 0;
+}
+
+int32_t msm_sensor_bayer_v4l2_s_ctrl(struct v4l2_subdev *sd,
+	struct v4l2_control *ctrl)
+{
+	int rc = -1, i = 0;
+	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
+	struct msm_sensor_v4l2_ctrl_info_t *v4l2_ctrl =
+		s_ctrl->msm_sensor_v4l2_ctrl_info;
+
+	CDBG("%s\n", __func__);
+	CDBG("%d\n", ctrl->id);
+	if (v4l2_ctrl == NULL)
+		return rc;
+	for (i = 0; i < s_ctrl->num_v4l2_ctrl; i++) {
+		if (v4l2_ctrl[i].ctrl_id == ctrl->id) {
+			if (v4l2_ctrl[i].s_v4l2_ctrl != NULL) {
+				CDBG("\n calling msm_sensor_s_ctrl_by_enum\n");
+				rc = v4l2_ctrl[i].s_v4l2_ctrl(
+					s_ctrl,
+					&s_ctrl->msm_sensor_v4l2_ctrl_info[i],
+					ctrl->value);
+			}
+			break;
+		}
+	}
+
+	return rc;
+}
+
+int32_t msm_sensor_bayer_v4l2_query_ctrl(
+	struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl)
+{
+	int rc = -1, i = 0;
+	struct msm_sensor_ctrl_t *s_ctrl =
+		(struct msm_sensor_ctrl_t *) sd->dev_priv;
+
+	CDBG("%s\n", __func__);
+	CDBG("%s id: %d\n", __func__, qctrl->id);
+
+	if (s_ctrl->msm_sensor_v4l2_ctrl_info == NULL)
+		return rc;
+
+	for (i = 0; i < s_ctrl->num_v4l2_ctrl; i++) {
+		if (s_ctrl->msm_sensor_v4l2_ctrl_info[i].ctrl_id == qctrl->id) {
+			qctrl->minimum =
+				s_ctrl->msm_sensor_v4l2_ctrl_info[i].min;
+			qctrl->maximum =
+				s_ctrl->msm_sensor_v4l2_ctrl_info[i].max;
+			qctrl->flags = 1;
+			rc = 0;
+			break;
+		}
+	}
+
+	return rc;
+}
+
+int msm_sensor_bayer_s_ctrl_by_enum(struct msm_sensor_ctrl_t *s_ctrl,
+		struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value)
+{
+	int rc = 0;
+	CDBG("%s enter\n", __func__);
+	rc = msm_sensor_write_enum_conf_array(
+		s_ctrl->sensor_i2c_client,
+		ctrl_info->enum_cfg_settings, value);
+	return rc;
+}
+
diff --git a/drivers/media/platform/msm/camera_v1/sensors/msm_sensor_bayer.h b/drivers/media/platform/msm/camera_v1/sensors/msm_sensor_bayer.h
new file mode 100644
index 0000000..584b790
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/sensors/msm_sensor_bayer.h
@@ -0,0 +1,78 @@
+/* Copyright (c) 2011-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.
+ */
+
+#ifndef MSM_SENSOR_BAYER_H
+#define MSM_SENSOR_BAYER_H
+
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/uaccess.h>
+#include <mach/camera.h>
+#include <mach/gpio.h>
+#include <media/msm_camera.h>
+#include <media/v4l2-subdev.h>
+#include "msm_camera_i2c.h"
+#include "msm_camera_eeprom.h"
+#include "msm_sensor_common.h"
+
+struct sensor_driver_t {
+	struct platform_driver *platform_pdriver;
+	int32_t (*platform_probe)(struct platform_device *pdev);
+};
+
+int32_t msm_sensor_bayer_config(struct msm_sensor_ctrl_t *s_ctrl,
+			void __user *argp);
+int32_t msm_sensor_bayer_power_up(struct msm_sensor_ctrl_t *s_ctrl);
+int32_t msm_sensor_bayer_power_down(struct msm_sensor_ctrl_t *s_ctrl);
+
+int32_t msm_sensor_bayer_match_id(struct msm_sensor_ctrl_t *s_ctrl);
+int msm_sensor_bayer_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id);
+int32_t msm_sensor_delay_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id);
+int32_t msm_sensor_bayer_power(struct v4l2_subdev *sd, int on);
+
+int32_t msm_sensor_bayer_v4l2_s_ctrl(struct v4l2_subdev *sd,
+	struct v4l2_control *ctrl);
+
+int32_t msm_sensor_bayer_v4l2_query_ctrl(
+	struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl);
+
+int msm_sensor_bayer_s_ctrl_by_enum(struct msm_sensor_ctrl_t *s_ctrl,
+		struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value);
+
+int msm_sensor_bayer_v4l2_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
+			enum v4l2_mbus_pixelcode *code);
+
+long msm_sensor_bayer_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int cmd, void *arg);
+
+int32_t msm_sensor_bayer_get_csi_params(struct msm_sensor_ctrl_t *s_ctrl,
+		struct csi_lane_params_t *sensor_output_info);
+
+int32_t msm_sensor_bayer_eeprom_read(struct msm_sensor_ctrl_t *s_ctrl);
+
+#define VIDIOC_MSM_SENSOR_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 4, void __user *)
+
+#define VIDIOC_MSM_SENSOR_RELEASE \
+	_IO('V', BASE_VIDIOC_PRIVATE + 11)
+
+#define VIDIOC_MSM_SENSOR_CSID_INFO\
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 12, struct msm_sensor_csi_info *)
+#endif
diff --git a/drivers/media/platform/msm/camera_v1/sensors/msm_sensor_common.c b/drivers/media/platform/msm/camera_v1/sensors/msm_sensor_common.c
new file mode 100644
index 0000000..a8d78b0
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/sensors/msm_sensor_common.c
@@ -0,0 +1,18 @@
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include "msm_sensor_common.h"
+
+struct msm_sensor_ctrl_t *get_sctrl(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct msm_sensor_ctrl_t, sensor_v4l2_subdev);
+}
diff --git a/drivers/media/platform/msm/camera_v1/sensors/msm_sensor_common.h b/drivers/media/platform/msm/camera_v1/sensors/msm_sensor_common.h
new file mode 100644
index 0000000..a1f5b83
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/sensors/msm_sensor_common.h
@@ -0,0 +1,227 @@
+/* Copyright (c) 2011-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.
+ */
+
+#ifndef MSM_SENSOR_COMMON_H
+#define MSM_SENSOR_COMMON_H
+
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/uaccess.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <mach/camera.h>
+#include <media/msm_camera.h>
+#include <media/v4l2-subdev.h>
+#include "msm_camera_i2c.h"
+#include "msm_camera_eeprom.h"
+#define Q8  0x00000100
+#define Q10 0x00000400
+
+#define MSM_SENSOR_MCLK_8HZ 8000000
+#define MSM_SENSOR_MCLK_16HZ 16000000
+#define MSM_SENSOR_MCLK_24HZ 24000000
+
+#define DEFINE_MSM_MUTEX(mutexname) \
+	static struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
+
+struct gpio_tlmm_cfg {
+	uint32_t gpio;
+	uint32_t dir;
+	uint32_t pull;
+	uint32_t drvstr;
+};
+
+enum msm_sensor_reg_update {
+	/* Sensor egisters that need to be updated during initialization */
+	MSM_SENSOR_REG_INIT,
+	/* Sensor egisters that needs periodic I2C writes */
+	MSM_SENSOR_UPDATE_PERIODIC,
+	/* All the sensor Registers will be updated */
+	MSM_SENSOR_UPDATE_ALL,
+	/* Not valid update */
+	MSM_SENSOR_UPDATE_INVALID
+};
+
+enum msm_sensor_cam_mode_t {
+	MSM_SENSOR_MODE_2D_RIGHT,
+	MSM_SENSOR_MODE_2D_LEFT,
+	MSM_SENSOR_MODE_3D,
+	MSM_SENSOR_MODE_INVALID
+};
+
+enum msm_camera_power_config_t {
+	REQUEST_GPIO,
+	ENABLE_GPIO,
+	REQUEST_VREG,
+	ENABLE_VREG,
+	CONFIG_CLK,
+	CONFIG_EXT_POWER_CTRL,
+	CONFIG_I2C_MUX,
+};
+
+struct msm_camera_power_seq_t {
+	enum msm_camera_power_config_t power_config;
+	uint32_t delay;
+};
+
+struct msm_sensor_id_info_t {
+	uint16_t sensor_id_reg_addr;
+	uint16_t sensor_id;
+};
+
+struct msm_sensor_reg_t {
+	enum msm_camera_i2c_data_type default_data_type;
+	struct msm_camera_i2c_reg_conf *start_stream_conf;
+	uint8_t start_stream_conf_size;
+	struct msm_camera_i2c_reg_conf *stop_stream_conf;
+	uint8_t stop_stream_conf_size;
+	struct msm_camera_i2c_reg_conf *group_hold_on_conf;
+	uint8_t group_hold_on_conf_size;
+	struct msm_camera_i2c_reg_conf *group_hold_off_conf;
+	uint8_t group_hold_off_conf_size;
+	struct msm_camera_i2c_conf_array *init_settings;
+	uint8_t init_size;
+	struct msm_camera_i2c_conf_array *mode_settings;
+	struct msm_camera_i2c_conf_array *no_effect_settings;
+	struct msm_sensor_output_info_t *output_settings;
+	uint8_t num_conf;
+};
+
+enum msm_sensor_device_type_t {
+	MSM_SENSOR_I2C_DEVICE,
+	MSM_SENSOR_PLATFORM_DEVICE,
+};
+
+struct v4l2_subdev_info {
+	enum v4l2_mbus_pixelcode code;
+	enum v4l2_colorspace colorspace;
+	uint16_t fmt;
+	uint16_t order;
+};
+
+struct msm_sensor_ctrl_t;
+
+struct msm_sensor_v4l2_ctrl_info_t {
+	uint32_t ctrl_id;
+	int16_t min;
+	int16_t max;
+	int16_t step;
+	struct msm_camera_i2c_enum_conf_array *enum_cfg_settings;
+	int (*s_v4l2_ctrl) (struct msm_sensor_ctrl_t *,
+		struct msm_sensor_v4l2_ctrl_info_t *, int);
+};
+
+struct msm_sensor_fn_t {
+	void (*sensor_start_stream) (struct msm_sensor_ctrl_t *);
+	void (*sensor_stop_stream) (struct msm_sensor_ctrl_t *);
+	void (*sensor_group_hold_on) (struct msm_sensor_ctrl_t *);
+	void (*sensor_group_hold_off) (struct msm_sensor_ctrl_t *);
+
+	int32_t (*sensor_set_fps) (struct msm_sensor_ctrl_t *,
+			struct fps_cfg *);
+	int32_t (*sensor_write_exp_gain) (struct msm_sensor_ctrl_t *,
+			uint16_t, uint32_t);
+	int32_t (*sensor_write_snapshot_exp_gain) (struct msm_sensor_ctrl_t *,
+			uint16_t, uint32_t);
+	int32_t (*sensor_setting) (struct msm_sensor_ctrl_t *,
+			int update_type, int rt);
+	int32_t (*sensor_csi_setting) (struct msm_sensor_ctrl_t *,
+			int update_type, int rt);
+	int32_t (*sensor_set_sensor_mode)
+			(struct msm_sensor_ctrl_t *, int, int);
+	int32_t (*sensor_mode_init) (struct msm_sensor_ctrl_t *,
+		int, struct sensor_init_cfg *);
+	int32_t (*sensor_get_output_info) (struct msm_sensor_ctrl_t *,
+		struct sensor_output_info_t *);
+	int (*sensor_config) (struct msm_sensor_ctrl_t *, void __user *);
+	int (*sensor_power_down)
+		(struct msm_sensor_ctrl_t *);
+	int (*sensor_power_up) (struct msm_sensor_ctrl_t *);
+	int32_t (*sensor_match_id)(struct msm_sensor_ctrl_t *s_ctrl);
+	void (*sensor_adjust_frame_lines) (struct msm_sensor_ctrl_t *s_ctrl);
+	int32_t (*sensor_get_csi_params)(struct msm_sensor_ctrl_t *,
+		struct csi_lane_params_t *);
+	int32_t (*sensor_read_eeprom)(struct msm_sensor_ctrl_t *);
+};
+
+struct msm_sensor_csi_info {
+	uint8_t is_csic;
+};
+
+enum msm_sensor_state {
+	MSM_SENSOR_POWER_UP,
+	MSM_SENSOR_POWER_DOWN,
+};
+
+struct msm_sensor_eeprom_data {
+	uint8_t *data;
+	uint32_t length;
+};
+
+struct msm_sensor_ctrl_t {
+	struct  msm_camera_sensor_info *sensordata;
+	struct i2c_client *msm_sensor_client;
+	struct i2c_driver *sensor_i2c_driver;
+	struct platform_device *pdev;
+	struct msm_camera_i2c_client *sensor_i2c_client;
+	uint16_t sensor_i2c_addr;
+	enum msm_camera_vreg_name_t *vreg_seq;
+	int num_vreg_seq;
+	struct msm_camera_power_seq_t *power_seq;
+	int num_power_seq;
+	enum msm_sensor_device_type_t sensor_device_type;
+
+	struct msm_sensor_output_reg_addr_t *sensor_output_reg_addr;
+	struct msm_sensor_id_info_t *sensor_id_info;
+	struct msm_sensor_exp_gain_info_t *sensor_exp_gain_info;
+	struct msm_sensor_reg_t *msm_sensor_reg;
+	struct msm_sensor_v4l2_ctrl_info_t *msm_sensor_v4l2_ctrl_info;
+	uint16_t num_v4l2_ctrl;
+	uint8_t is_csic;
+
+	uint16_t curr_line_length_pclk;
+	uint16_t curr_frame_length_lines;
+
+	uint32_t fps_divider;
+	enum msm_sensor_resolution_t curr_res;
+	enum msm_sensor_cam_mode_t cam_mode;
+
+	struct mutex *msm_sensor_mutex;
+
+	struct v4l2_subdev sensor_v4l2_subdev;
+	struct v4l2_subdev_info *sensor_v4l2_subdev_info;
+	uint8_t sensor_v4l2_subdev_info_size;
+	struct v4l2_subdev_ops *sensor_v4l2_subdev_ops;
+	struct msm_sensor_fn_t *func_tbl;
+	struct regulator **reg_ptr;
+	struct clk *cam_clk[2];
+	long clk_rate;
+	enum msm_sensor_state sensor_state;
+	/* Number of frames to delay after start / stop stream in Q10 format.
+	   Initialize to -1 for this value to be ignored */
+	int16_t wait_num_frames;
+	/* minimum delay after stop / stop stream in ms */
+	uint16_t min_delay;
+	/* delay (in ms) after power up sequence */
+	uint16_t power_seq_delay;
+	struct msm_sensor_eeprom_data eeprom_data;
+};
+
+struct msm_sensor_ctrl_t *get_sctrl(struct v4l2_subdev *sd);
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v1/sensors/msm_sensor_init.c b/drivers/media/platform/msm/camera_v1/sensors/msm_sensor_init.c
new file mode 100644
index 0000000..d759cf1
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/sensors/msm_sensor_init.c
@@ -0,0 +1,35 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_sensor.h"
+#include "msm.h"
+#include "msm_sensor_bayer.h"
+#include "imx091.h"
+
+static struct i2c_driver *sensor_i2c_driver[] = {
+	/* back camera */
+	&imx091_i2c_driver,
+	/* front camera */
+};
+
+static int __init msm_sensor_init_module(void)
+{
+	int index = 0;
+	for (index = 0; index < ARRAY_SIZE(sensor_i2c_driver); index++)
+		i2c_add_driver(sensor_i2c_driver[index]);
+	return 0;
+}
+
+module_init(msm_sensor_init_module);
+MODULE_DESCRIPTION("Sensor driver probe");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/sensors/mt9e013_v4l2.c b/drivers/media/platform/msm/camera_v1/sensors/mt9e013_v4l2.c
new file mode 100644
index 0000000..289beba
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/sensors/mt9e013_v4l2.c
@@ -0,0 +1,496 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_sensor.h"
+#define SENSOR_NAME "mt9e013"
+#define PLATFORM_DRIVER_NAME "msm_camera_mt9e013"
+#define mt9e013_obj mt9e013_##obj
+
+DEFINE_MUTEX(mt9e013_mut);
+static struct msm_sensor_ctrl_t mt9e013_s_ctrl;
+
+static struct msm_camera_i2c_reg_conf mt9e013_groupon_settings[] = {
+	{0x0104, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf mt9e013_groupoff_settings[] = {
+	{0x0104, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf mt9e013_prev_settings[] = {
+	/*Output Size (1632x1224)*/
+	{0x0344, 0x0008},/*X_ADDR_START*/
+	{0x0348, 0x0CC9},/*X_ADDR_END*/
+	{0x0346, 0x0008},/*Y_ADDR_START*/
+	{0x034A, 0x0999},/*Y_ADDR_END*/
+	{0x034C, 0x0660},/*X_OUTPUT_SIZE*/
+	{0x034E, 0x04C8},/*Y_OUTPUT_SIZE*/
+	{0x306E, 0xFCB0},/*DATAPATH_SELECT*/
+	{0x3040, 0x04C3},/*READ_MODE*/
+	{0x3178, 0x0000},/*ANALOG_CONTROL5*/
+	{0x3ED0, 0x1E24},/*DAC_LD_4_5*/
+	{0x0400, 0x0002},/*SCALING_MODE*/
+	{0x0404, 0x0010},/*SCALE_M*/
+	/*Timing configuration*/
+	{0x0342, 0x1018},/*LINE_LENGTH_PCK*/
+	{0x0340, 0x055B},/*FRAME_LENGTH_LINES*/
+	{0x0202, 0x0557},/*COARSE_INTEGRATION_TIME*/
+	{0x3014, 0x0846},/*FINE_INTEGRATION_TIME_*/
+	{0x3010, 0x0130},/*FINE_CORRECTION*/
+};
+
+static struct msm_camera_i2c_reg_conf mt9e013_snap_settings[] = {
+	/*Output Size (3264x2448)*/
+	{0x0344, 0x0000},/*X_ADDR_START */
+	{0x0348, 0x0CCF},/*X_ADDR_END*/
+	{0x0346, 0x0000},/*Y_ADDR_START */
+	{0x034A, 0x099F},/*Y_ADDR_END*/
+	{0x034C, 0x0CD0},/*X_OUTPUT_SIZE*/
+	{0x034E, 0x09A0},/*Y_OUTPUT_SIZE*/
+	{0x306E, 0xFC80},/*DATAPATH_SELECT*/
+	{0x3040, 0x0041},/*READ_MODE*/
+	{0x3178, 0x0000},/*ANALOG_CONTROL5*/
+	{0x3ED0, 0x1E24},/*DAC_LD_4_5*/
+	{0x0400, 0x0000},/*SCALING_MODE*/
+	{0x0404, 0x0010},/*SCALE_M*/
+	/*Timing configuration*/
+	{0x0342, 0x13F8},/*LINE_LENGTH_PCK*/
+	{0x0340, 0x0A2F},/*FRAME_LENGTH_LINES*/
+	{0x0202, 0x0A1F},/*COARSE_INTEGRATION_TIME*/
+	{0x3014, 0x03F6},/*FINE_INTEGRATION_TIME_ */
+	{0x3010, 0x0078},/*FINE_CORRECTION*/
+};
+
+static struct msm_camera_i2c_reg_conf mt9e013_hfr60_settings[] = {
+	{0x0300, 0x0005},/*VT_PIX_CLK_DIV*/
+	{0x0302, 0x0001},/*VT_SYS_CLK_DIV*/
+	{0x0304, 0x0002},/*PRE_PLL_CLK_DIV*/
+	{0x0306, 0x0029},/*PLL_MULTIPLIER*/
+	{0x0308, 0x000A},/*OP_PIX_CLK_DIV*/
+	{0x030A, 0x0001},/*OP_SYS_CLK_DIV*/
+	{0x0344, 0x0008},/*X_ADDR_START*/
+	{0x0348, 0x0685},/*X_ADDR_END*/
+	{0x0346, 0x013a},/*Y_ADDR_START*/
+	{0x034A, 0x055B},/*Y_ADDR_END*/
+	{0x034C, 0x0340},/*X_OUTPUT_SIZE*/
+	{0x034E, 0x0212},/*Y_OUTPUT_SIZE*/
+	{0x306E, 0xFC80},/*DATAPATH_SELECT*/
+	{0x3040, 0x00C3},/*READ_MODE*/
+	{0x3178, 0x0000},/*ANALOG_CONTROL5*/
+	{0x3ED0, 0x1E24},/*DAC_LD_4_5*/
+	{0x0400, 0x0000},/*SCALING_MODE*/
+	{0x0404, 0x0010},/*SCALE_M*/
+	/*Timing configuration*/
+	{0x0342, 0x0970},/*LINE_LENGTH_PCK*/
+	{0x0340, 0x02A1},/*FRAME_LENGTH_LINES*/
+	{0x0202, 0x02A1},/*COARSE_INTEGRATION_TIME*/
+	{0x3014, 0x03F6},/*FINE_INTEGRATION_TIME_*/
+	{0x3010, 0x0078},/*FINE_CORRECTION*/
+};
+
+static struct msm_camera_i2c_reg_conf mt9e013_hfr90_settings[] = {
+	{0x0300, 0x0005},/*VT_PIX_CLK_DIV*/
+	{0x0302, 0x0001},/*VT_SYS_CLK_DIV*/
+	{0x0304, 0x0002},/*PRE_PLL_CLK_DIV*/
+	{0x0306, 0x003D},/*PLL_MULTIPLIER*/
+	{0x0308, 0x000A},/*OP_PIX_CLK_DIV*/
+	{0x030A, 0x0001},/*OP_SYS_CLK_DIV*/
+	{0x0344, 0x0008},/*X_ADDR_START*/
+	{0x0348, 0x0685},/*X_ADDR_END*/
+	{0x0346, 0x013a},/*Y_ADDR_START*/
+	{0x034A, 0x055B},/*Y_ADDR_END*/
+	{0x034C, 0x0340},/*X_OUTPUT_SIZE*/
+	{0x034E, 0x0212},/*Y_OUTPUT_SIZE*/
+	{0x306E, 0xFC80},/*DATAPATH_SELECT*/
+	{0x3040, 0x00C3},/*READ_MODE*/
+	{0x3178, 0x0000},/*ANALOG_CONTROL5*/
+	{0x3ED0, 0x1E24},/*DAC_LD_4_5*/
+	{0x0400, 0x0000},/*SCALING_MODE*/
+	{0x0404, 0x0010},/*SCALE_M*/
+	/*Timing configuration*/
+	{0x0342, 0x0970},/*LINE_LENGTH_PCK*/
+	{0x0340, 0x02A1},/*FRAME_LENGTH_LINES*/
+	{0x0202, 0x02A1},/*COARSE_INTEGRATION_TIME*/
+	{0x3014, 0x03F6},/*FINE_INTEGRATION_TIME_*/
+	{0x3010, 0x0078},/*FINE_CORRECTION*/
+};
+
+static struct msm_camera_i2c_reg_conf mt9e013_hfr120_settings[] = {
+	{0x0300, 0x0005},/*VT_PIX_CLK_DIV*/
+	{0x0302, 0x0001},/*VT_SYS_CLK_DIV*/
+	{0x0304, 0x0002},/*PRE_PLL_CLK_DIV*/
+	{0x0306, 0x0052},/*PLL_MULTIPLIER*/
+	{0x0308, 0x000A},/*OP_PIX_CLK_DIV*/
+	{0x030A, 0x0001},/*OP_SYS_CLK_DIV*/
+	{0x0344, 0x0008},/*X_ADDR_START*/
+	{0x0348, 0x0685},/*X_ADDR_END*/
+	{0x0346, 0x013a},/*Y_ADDR_START*/
+	{0x034A, 0x055B},/*Y_ADDR_END*/
+	{0x034C, 0x0340},/*X_OUTPUT_SIZE*/
+	{0x034E, 0x0212},/*Y_OUTPUT_SIZE*/
+	{0x306E, 0xFC80},/*DATAPATH_SELECT*/
+	{0x3040, 0x00C3},/*READ_MODE*/
+	{0x3178, 0x0000},/*ANALOG_CONTROL5*/
+	{0x3ED0, 0x1E24},/*DAC_LD_4_5*/
+	{0x0400, 0x0000},/*SCALING_MODE*/
+	{0x0404, 0x0010},/*SCALE_M*/
+	/*Timing configuration*/
+	{0x0342, 0x0970},/*LINE_LENGTH_PCK*/
+	{0x0340, 0x02A1},/*FRAME_LENGTH_LINES*/
+	{0x0202, 0x02A1},/*COARSE_INTEGRATION_TIME*/
+	{0x3014, 0x03F6},/*FINE_INTEGRATION_TIME_*/
+	{0x3010, 0x0078},/*FINE_CORRECTION*/
+};
+
+static struct msm_camera_i2c_reg_conf mt9e013_recommend_settings[] = {
+	/*Disable embedded data*/
+	{0x3064, 0x7800},/*SMIA_TEST*/
+	/*configure 2-lane MIPI*/
+	{0x31AE, 0x0202},/*SERIAL_FORMAT*/
+	{0x31B8, 0x0E3F},/*MIPI_TIMING_2*/
+	/*set data to RAW10 format*/
+	{0x0112, 0x0A0A},/*CCP_DATA_FORMAT*/
+	{0x30F0, 0x800D},/*VCM CONTROL*/
+
+	{0x3044, 0x0590},
+	{0x306E, 0xFC80},
+	{0x30B2, 0xC000},
+	{0x30D6, 0x0800},
+	{0x316C, 0xB42F},
+	{0x316E, 0x869A},
+	{0x3170, 0x210E},
+	{0x317A, 0x010E},
+	{0x31E0, 0x1FB9},
+	{0x31E6, 0x07FC},
+	{0x37C0, 0x0000},
+	{0x37C2, 0x0000},
+	{0x37C4, 0x0000},
+	{0x37C6, 0x0000},
+	{0x3E00, 0x0011},
+	{0x3E02, 0x8801},
+	{0x3E04, 0x2801},
+	{0x3E06, 0x8449},
+	{0x3E08, 0x6841},
+	{0x3E0A, 0x400C},
+	{0x3E0C, 0x1001},
+	{0x3E0E, 0x2603},
+	{0x3E10, 0x4B41},
+	{0x3E12, 0x4B24},
+	{0x3E14, 0xA3CF},
+	{0x3E16, 0x8802},
+	{0x3E18, 0x8401},
+	{0x3E1A, 0x8601},
+	{0x3E1C, 0x8401},
+	{0x3E1E, 0x840A},
+	{0x3E20, 0xFF00},
+	{0x3E22, 0x8401},
+	{0x3E24, 0x00FF},
+	{0x3E26, 0x0088},
+	{0x3E28, 0x2E8A},
+	{0x3E30, 0x0000},
+	{0x3E32, 0x8801},
+	{0x3E34, 0x4029},
+	{0x3E36, 0x00FF},
+	{0x3E38, 0x8469},
+	{0x3E3A, 0x00FF},
+	{0x3E3C, 0x2801},
+	{0x3E3E, 0x3E2A},
+	{0x3E40, 0x1C01},
+	{0x3E42, 0xFF84},
+	{0x3E44, 0x8401},
+	{0x3E46, 0x0C01},
+	{0x3E48, 0x8401},
+	{0x3E4A, 0x00FF},
+	{0x3E4C, 0x8402},
+	{0x3E4E, 0x8984},
+	{0x3E50, 0x6628},
+	{0x3E52, 0x8340},
+	{0x3E54, 0x00FF},
+	{0x3E56, 0x4A42},
+	{0x3E58, 0x2703},
+	{0x3E5A, 0x6752},
+	{0x3E5C, 0x3F2A},
+	{0x3E5E, 0x846A},
+	{0x3E60, 0x4C01},
+	{0x3E62, 0x8401},
+	{0x3E66, 0x3901},
+	{0x3E90, 0x2C01},
+	{0x3E98, 0x2B02},
+	{0x3E92, 0x2A04},
+	{0x3E94, 0x2509},
+	{0x3E96, 0x0000},
+	{0x3E9A, 0x2905},
+	{0x3E9C, 0x00FF},
+	{0x3ECC, 0x00EB},
+	{0x3ED0, 0x1E24},
+	{0x3ED4, 0xAFC4},
+	{0x3ED6, 0x909B},
+	{0x3EE0, 0x2424},
+	{0x3EE2, 0x9797},
+	{0x3EE4, 0xC100},
+	{0x3EE6, 0x0540},
+	{0x3174, 0x8000},
+	/* PLL settings */
+	{0x0300, 0x0004},/*VT_PIX_CLK_DIV*/
+	{0x0302, 0x0001},/*VT_SYS_CLK_DIV*/
+	{0x0304, 0x0002},/*PRE_PLL_CLK_DIV*/
+	{0x0306, 0x003A},/*PLL_MULTIPLIER*/
+	{0x0308, 0x000A},/*OP_PIX_CLK_DIV*/
+	{0x030A, 0x0001},/*OP_SYS_CLK_DIV*/
+};
+
+static struct v4l2_subdev_info mt9e013_subdev_info[] = {
+	{
+	.code   = V4L2_MBUS_FMT_SBGGR10_1X10,
+	.colorspace = V4L2_COLORSPACE_JPEG,
+	.fmt    = 1,
+	.order    = 0,
+	},
+	/* more can be supported, to be added later */
+};
+
+static struct msm_camera_i2c_conf_array mt9e013_init_conf[] = {
+	{&mt9e013_recommend_settings[0],
+	ARRAY_SIZE(mt9e013_recommend_settings), 0, MSM_CAMERA_I2C_WORD_DATA}
+};
+
+static struct msm_camera_i2c_conf_array mt9e013_confs[] = {
+	{&mt9e013_snap_settings[0],
+	ARRAY_SIZE(mt9e013_snap_settings), 0, MSM_CAMERA_I2C_WORD_DATA},
+	{&mt9e013_prev_settings[0],
+	ARRAY_SIZE(mt9e013_prev_settings), 0, MSM_CAMERA_I2C_WORD_DATA},
+	{&mt9e013_hfr60_settings[0],
+	ARRAY_SIZE(mt9e013_hfr60_settings), 0, MSM_CAMERA_I2C_WORD_DATA},
+	{&mt9e013_hfr90_settings[0],
+	ARRAY_SIZE(mt9e013_hfr90_settings), 0, MSM_CAMERA_I2C_WORD_DATA},
+	{&mt9e013_hfr120_settings[0],
+	ARRAY_SIZE(mt9e013_hfr120_settings), 0, MSM_CAMERA_I2C_WORD_DATA},
+};
+
+static struct msm_sensor_output_info_t mt9e013_dimensions[] = {
+	{
+		.x_output = 0xCD0,
+		.y_output = 0x9A0,
+		.line_length_pclk = 0x13F8,
+		.frame_length_lines = 0xA2F,
+		.vt_pixel_clk = 174000000,
+		.op_pixel_clk = 174000000,
+		.binning_factor = 1,
+	},
+	{
+		.x_output = 0x660,
+		.y_output = 0x4C8,
+		.line_length_pclk = 0x1018,
+		.frame_length_lines = 0x55B,
+		.vt_pixel_clk = 174000000,
+		.op_pixel_clk = 174000000,
+		.binning_factor = 1,
+	},
+	{
+		.x_output = 0x340,
+		.y_output = 0x212,
+		.line_length_pclk = 0x970,
+		.frame_length_lines = 0x2A1,
+		.vt_pixel_clk = 98400000,
+		.op_pixel_clk = 98400000,
+		.binning_factor = 1,
+	},
+	{
+		.x_output = 0x340,
+		.y_output = 0x212,
+		.line_length_pclk = 0x970,
+		.frame_length_lines = 0x2A1,
+		.vt_pixel_clk = 146400000,
+		.op_pixel_clk = 146400000,
+		.binning_factor = 1,
+	},
+	{
+		.x_output = 0x340,
+		.y_output = 0x212,
+		.line_length_pclk = 0x970,
+		.frame_length_lines = 0x2A1,
+		.vt_pixel_clk = 196800000,
+		.op_pixel_clk = 196800000,
+		.binning_factor = 1,
+	},
+};
+
+static struct msm_sensor_output_reg_addr_t mt9e013_reg_addr = {
+	.x_output = 0x34C,
+	.y_output = 0x34E,
+	.line_length_pclk = 0x342,
+	.frame_length_lines = 0x340,
+};
+
+static struct msm_sensor_id_info_t mt9e013_id_info = {
+	.sensor_id_reg_addr = 0x0,
+	.sensor_id = 0x4B00,
+};
+
+static struct msm_sensor_exp_gain_info_t mt9e013_exp_gain_info = {
+	.coarse_int_time_addr = 0x202,
+	.global_gain_addr = 0x305E,
+	.vert_offset = 0,
+};
+
+static int32_t mt9e013_write_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
+		uint16_t gain, uint32_t line)
+{
+	uint32_t fl_lines;
+	fl_lines =
+		(s_ctrl->curr_frame_length_lines * s_ctrl->fps_divider) / Q10;
+
+	s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->global_gain_addr, gain | 0x1000,
+		MSM_CAMERA_I2C_WORD_DATA);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr, line,
+		MSM_CAMERA_I2C_WORD_DATA);
+	s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
+	return 0;
+}
+
+static int32_t mt9e013_write_exp_snapshot_gain(struct msm_sensor_ctrl_t *s_ctrl,
+		uint16_t gain, uint32_t line)
+{
+	uint32_t fl_lines;
+	fl_lines =
+		(s_ctrl->curr_frame_length_lines * s_ctrl->fps_divider) / Q10;
+
+	s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->global_gain_addr, gain | 0x1000,
+		MSM_CAMERA_I2C_WORD_DATA);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr, line,
+		MSM_CAMERA_I2C_WORD_DATA);
+	s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		0x301A, (0x065C|0x2), MSM_CAMERA_I2C_WORD_DATA);
+
+	return 0;
+}
+static void mt9e013_start_stream(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		0x301A, 0x8250, MSM_CAMERA_I2C_WORD_DATA);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		0x301A, 0x8650, MSM_CAMERA_I2C_WORD_DATA);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		0x301A, 0x8658, MSM_CAMERA_I2C_WORD_DATA);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		0x0104, 0x00, MSM_CAMERA_I2C_BYTE_DATA);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		0x301A, 0x065C, MSM_CAMERA_I2C_WORD_DATA);
+}
+
+static void mt9e013_stop_stream(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		0x301A, 0x0058, MSM_CAMERA_I2C_WORD_DATA);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		0x301A, 0x0050, MSM_CAMERA_I2C_WORD_DATA);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		0x0104, 0x01, MSM_CAMERA_I2C_BYTE_DATA);
+}
+
+static const struct i2c_device_id mt9e013_i2c_id[] = {
+	{SENSOR_NAME, (kernel_ulong_t)&mt9e013_s_ctrl},
+	{ }
+};
+
+static struct i2c_driver mt9e013_i2c_driver = {
+	.id_table = mt9e013_i2c_id,
+	.probe  = msm_sensor_i2c_probe,
+	.driver = {
+		.name = SENSOR_NAME,
+	},
+};
+
+static struct msm_camera_i2c_client mt9e013_sensor_i2c_client = {
+	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+static int __init msm_sensor_init_module(void)
+{
+	return i2c_add_driver(&mt9e013_i2c_driver);
+}
+
+static struct v4l2_subdev_core_ops mt9e013_subdev_core_ops = {
+	.ioctl = msm_sensor_subdev_ioctl,
+	.s_power = msm_sensor_power,
+};
+
+static struct v4l2_subdev_video_ops mt9e013_subdev_video_ops = {
+	.enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
+};
+
+static struct v4l2_subdev_ops mt9e013_subdev_ops = {
+	.core = &mt9e013_subdev_core_ops,
+	.video  = &mt9e013_subdev_video_ops,
+};
+
+static struct msm_sensor_fn_t mt9e013_func_tbl = {
+	.sensor_start_stream = mt9e013_start_stream,
+	.sensor_stop_stream = mt9e013_stop_stream,
+	.sensor_group_hold_on = msm_sensor_group_hold_on,
+	.sensor_group_hold_off = msm_sensor_group_hold_off,
+	.sensor_set_fps = msm_sensor_set_fps,
+	.sensor_write_exp_gain = mt9e013_write_exp_gain,
+	.sensor_write_snapshot_exp_gain = mt9e013_write_exp_snapshot_gain,
+	.sensor_csi_setting = msm_sensor_setting1,
+	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
+	.sensor_mode_init = msm_sensor_mode_init,
+	.sensor_get_output_info = msm_sensor_get_output_info,
+	.sensor_config = msm_sensor_config,
+	.sensor_power_up = msm_sensor_power_up,
+	.sensor_power_down = msm_sensor_power_down,
+};
+
+static struct msm_sensor_reg_t mt9e013_regs = {
+	.default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
+	.group_hold_on_conf = mt9e013_groupon_settings,
+	.group_hold_on_conf_size = ARRAY_SIZE(mt9e013_groupon_settings),
+	.group_hold_off_conf = mt9e013_groupoff_settings,
+	.group_hold_off_conf_size =
+		ARRAY_SIZE(mt9e013_groupoff_settings),
+	.init_settings = &mt9e013_init_conf[0],
+	.init_size = ARRAY_SIZE(mt9e013_init_conf),
+	.mode_settings = &mt9e013_confs[0],
+	.output_settings = &mt9e013_dimensions[0],
+	.num_conf = ARRAY_SIZE(mt9e013_confs),
+};
+
+static struct msm_sensor_ctrl_t mt9e013_s_ctrl = {
+	.msm_sensor_reg = &mt9e013_regs,
+	.sensor_i2c_client = &mt9e013_sensor_i2c_client,
+	.sensor_i2c_addr = 0x6C,
+	.sensor_output_reg_addr = &mt9e013_reg_addr,
+	.sensor_id_info = &mt9e013_id_info,
+	.sensor_exp_gain_info = &mt9e013_exp_gain_info,
+	.cam_mode = MSM_SENSOR_MODE_INVALID,
+	.msm_sensor_mutex = &mt9e013_mut,
+	.sensor_i2c_driver = &mt9e013_i2c_driver,
+	.sensor_v4l2_subdev_info = mt9e013_subdev_info,
+	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(mt9e013_subdev_info),
+	.sensor_v4l2_subdev_ops = &mt9e013_subdev_ops,
+	.func_tbl = &mt9e013_func_tbl,
+	.clk_rate = MSM_SENSOR_MCLK_24HZ,
+};
+
+module_init(msm_sensor_init_module);
+MODULE_DESCRIPTION("Aptina 8MP Bayer sensor driver");
+MODULE_LICENSE("GPL v2");
+
+
diff --git a/drivers/media/video/msm/sensors/mt9m114_v4l2.c b/drivers/media/platform/msm/camera_v1/sensors/mt9m114_v4l2.c
similarity index 100%
rename from drivers/media/video/msm/sensors/mt9m114_v4l2.c
rename to drivers/media/platform/msm/camera_v1/sensors/mt9m114_v4l2.c
diff --git a/drivers/media/platform/msm/camera_v1/sensors/ov2720.c b/drivers/media/platform/msm/camera_v1/sensors/ov2720.c
new file mode 100644
index 0000000..fe7bf07
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/sensors/ov2720.c
@@ -0,0 +1,856 @@
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_sensor.h"
+#include "ov2720.h"
+#define SENSOR_NAME "ov2720"
+#define PLATFORM_DRIVER_NAME "msm_camera_ov2720"
+#define ov2720_obj ov2720_##obj
+
+DEFINE_MUTEX(ov2720_mut);
+static struct msm_sensor_ctrl_t ov2720_s_ctrl;
+
+static struct msm_camera_i2c_reg_conf ov2720_start_settings[] = {
+	{0x0100, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf ov2720_stop_settings[] = {
+	{0x0100, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf ov2720_groupon_settings[] = {
+	{0x3208, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf ov2720_groupoff_settings[] = {
+	{0x3208, 0x10},
+	{0x3208, 0xA0},
+};
+
+static struct msm_camera_i2c_reg_conf ov2720_prev_settings[] = {
+	{0x3800, 0x00},
+	{0x3801, 0x02},
+	{0x3802, 0x00},
+	{0x3803, 0x00},
+	{0x3804, 0x07},
+	{0x3805, 0xA1},
+	{0x3806, 0x04},
+	{0x3807, 0x47},
+	{0x3810, 0x00},
+	{0x3811, 0x09},
+	{0x3812, 0x00},
+	{0x3813, 0x02},
+	{0x3820, 0x80},
+	{0x3821, 0x06},
+	{0x3814, 0x11},
+	{0x3815, 0x11},
+	{0x3612, 0x0b},
+	{0x3618, 0x04},
+	{0x3a08, 0x01},
+	{0x3a09, 0x50},
+	{0x3a0a, 0x01},
+	{0x3a0b, 0x18},
+	{0x3a0d, 0x03},
+	{0x3a0e, 0x03},
+	{0x4520, 0x00},
+	{0x4837, 0x1b},
+	{0x3000, 0xff},
+	{0x3001, 0xff},
+	{0x3002, 0xf0},
+	{0x3600, 0x08},
+	{0x3621, 0xc0},
+	{0x3632, 0xd2},
+	{0x3633, 0x23},
+	{0x3634, 0x54},
+	{0x3f01, 0x0c},
+	{0x5001, 0xc1},
+	{0x3614, 0xf0},
+	{0x3630, 0x2d},
+	{0x370b, 0x62},
+	{0x3706, 0x61},
+	{0x4000, 0x02},
+	{0x4002, 0xc5},
+	{0x4005, 0x08},
+	{0x404f, 0x84},
+	{0x4051, 0x00},
+	{0x5000, 0xcf},
+	{0x3a18, 0x00},
+	{0x3a19, 0x80},
+	{0x3503, 0x03},
+	{0x4521, 0x00},
+	{0x5183, 0xb0},
+	{0x5184, 0xb0},
+	{0x5185, 0xb0},
+	{0x370c, 0x0c},
+	{0x3035, 0x10},
+	{0x3036, 0x1e},
+	{0x3037, 0x21},
+	{0x303e, 0x19},
+	{0x3038, 0x06},
+	{0x3018, 0x04},
+	{0x3000, 0x00},
+	{0x3001, 0x00},
+	{0x3002, 0x00},
+	{0x3a0f, 0x40},
+	{0x3a10, 0x38},
+	{0x3a1b, 0x48},
+	{0x3a1e, 0x30},
+	{0x3a11, 0x90},
+	{0x3a1f, 0x10},
+	{0x4800, 0x24},
+};
+
+static struct msm_camera_i2c_reg_conf ov2720_720_settings[] = {
+	{0x3800, 0x01},
+	{0x3801, 0x4a},
+	{0x3802, 0x00},
+	{0x3803, 0xba},
+	{0x3804, 0x06},
+	{0x3805, 0x51+32},
+	{0x3806, 0x03},
+	{0x3807, 0x8d+24},
+	{0x3810, 0x00},
+	{0x3811, 0x05},
+	{0x3812, 0x00},
+	{0x3813, 0x02},
+	{0x3820, 0x80},
+	{0x3821, 0x06},
+	{0x3814, 0x11},
+	{0x3815, 0x11},
+	{0x3612, 0x0b},
+	{0x3618, 0x04},
+	{0x3a08, 0x01},
+	{0x3a09, 0x50},
+	{0x3a0a, 0x01},
+	{0x3a0b, 0x18},
+	{0x3a0d, 0x03},
+	{0x3a0e, 0x03},
+	{0x4520, 0x00},
+	{0x4837, 0x1b},
+	{0x3000, 0xff},
+	{0x3001, 0xff},
+	{0x3002, 0xf0},
+	{0x3600, 0x08},
+	{0x3621, 0xc0},
+	{0x3632, 0xd2},
+	{0x3633, 0x23},
+	{0x3634, 0x54},
+	{0x3f01, 0x0c},
+	{0x5001, 0xc1},
+	{0x3614, 0xf0},
+	{0x3630, 0x2d},
+	{0x370b, 0x62},
+	{0x3706, 0x61},
+	{0x4000, 0x02},
+	{0x4002, 0xc5},
+	{0x4005, 0x08},
+	{0x404f, 0x84},
+	{0x4051, 0x00},
+	{0x5000, 0xff},
+	{0x3a18, 0x00},
+	{0x3a19, 0x80},
+	{0x3503, 0x13},
+	{0x4521, 0x00},
+	{0x5183, 0xb0},
+	{0x5184, 0xb0},
+	{0x5185, 0xb0},
+	{0x370c, 0x0c},
+	{0x3035, 0x10},
+	{0x3036, 0x04},
+	{0x3037, 0x61},
+	{0x303e, 0x19},
+	{0x3038, 0x06},
+	{0x3018, 0x04},
+	{0x3000, 0x00},
+	{0x3001, 0x00},
+	{0x3002, 0x00},
+	{0x3a0f, 0x40},
+	{0x3a10, 0x38},
+	{0x3a1b, 0x48},
+	{0x3a1e, 0x30},
+	{0x3a11, 0x90},
+	{0x3a1f, 0x10},
+	{0x4800, 0x24},
+};
+
+static struct msm_camera_i2c_reg_conf ov2720_vga_settings[] = {
+	{0x3800, 0x00},
+	{0x3801, 0x0c},
+	{0x3802, 0x00},
+	{0x3803, 0x02},
+	{0x3804, 0x07},
+	{0x3805, 0x97+32},
+	{0x3806, 0x04},
+	{0x3807, 0x45+24},
+	{0x3810, 0x00},
+	{0x3811, 0x03},
+	{0x3812, 0x00},
+	{0x3813, 0x03},
+	{0x3820, 0x80},
+	{0x3821, 0x06},
+	{0x3814, 0x11},
+	{0x3815, 0x11},
+	{0x3612, 0x0b},
+	{0x3618, 0x04},
+	{0x3a08, 0x01},
+	{0x3a09, 0x50},
+	{0x3a0a, 0x01},
+	{0x3a0b, 0x18},
+	{0x3a0d, 0x03},
+	{0x3a0e, 0x03},
+	{0x4520, 0x00},
+	{0x4837, 0x1b},
+	{0x3000, 0xff},
+	{0x3001, 0xff},
+	{0x3002, 0xf0},
+	{0x3600, 0x08},
+	{0x3621, 0xc0},
+	{0x3632, 0xd2},
+	{0x3633, 0x23},
+	{0x3634, 0x54},
+	{0x3f01, 0x0c},
+	{0x5001, 0xc1},
+	{0x3614, 0xf0},
+	{0x3630, 0x2d},
+	{0x370b, 0x62},
+	{0x3706, 0x61},
+	{0x4000, 0x02},
+	{0x4002, 0xc5},
+	{0x4005, 0x08},
+	{0x404f, 0x84},
+	{0x4051, 0x00},
+	{0x5000, 0xff},
+	{0x3a18, 0x00},
+	{0x3a19, 0x80},
+	{0x3503, 0x13},
+	{0x4521, 0x00},
+	{0x5183, 0xb0},
+	{0x5184, 0xb0},
+	{0x5185, 0xb0},
+	{0x370c, 0x0c},
+	{0x3035, 0x10},
+	{0x3036, 0x04},
+	{0x3037, 0x61},
+	{0x303e, 0x19},
+	{0x3038, 0x06},
+	{0x3018, 0x04},
+	{0x3000, 0x00},
+	{0x3001, 0x00},
+	{0x3002, 0x00},
+	{0x3a0f, 0x40},
+	{0x3a10, 0x38},
+	{0x3a1b, 0x48},
+	{0x3a1e, 0x30},
+	{0x3a11, 0x90},
+	{0x3a1f, 0x10},
+	{0x4800, 0x24},
+	{0x3500, 0x00},
+	{0x3501, 0x17},
+	{0x3502, 0xf0},
+	{0x3508, 0x00},
+	{0x3509, 0x20},
+};
+
+static struct msm_camera_i2c_reg_conf ov2720_60fps_settings[] = {
+	{0x3718, 0x10},
+	{0x3702, 0x18},
+	{0x373a, 0x3c},
+	{0x3715, 0x01},
+	{0x3703, 0x1d},
+	{0x3705, 0x0b},
+	{0x3730, 0x1f},
+	{0x3704, 0x3f},
+	{0x3f06, 0x1d},
+	{0x371c, 0x00},
+	{0x371d, 0x83},
+	{0x371e, 0x00},
+	{0x371f, 0xb6},
+	{0x3708, 0x63},
+	{0x3709, 0x52},
+	{0x3800, 0x01},
+	{0x3801, 0x42},
+	{0x3802, 0x00},
+	{0x3803, 0x40},
+	{0x3804, 0x06},
+	{0x3805, 0x61},
+	{0x3806, 0x04},
+	{0x3807, 0x08},
+	{0x3808, 0x02},
+	{0x3809, 0x80},
+	{0x380a, 0x01},
+	{0x380b, 0xe0},
+	{0x380c, 0x03},
+	{0x380d, 0x0c},
+	{0x380e, 0x02},
+	{0x380f, 0x00},
+	{0x3810, 0x00},
+	{0x3811, 0x0f},
+	{0x3812, 0x00},
+	{0x3813, 0x02},
+	{0x3820, 0x80},
+	{0x3821, 0x06},
+	{0x3814, 0x31},
+	{0x3815, 0x31},
+	{0x3612, 0x0b},
+	{0x3618, 0x04},
+	{0x3a08, 0x02},
+	{0x3a09, 0x67},
+	{0x3a0a, 0x02},
+	{0x3a0b, 0x00},
+	{0x3a0d, 0x00},
+	{0x3a0e, 0x00},
+	{0x4520, 0x0a},
+	{0x4837, 0x29},
+	{0x3000, 0xff},
+	{0x3001, 0xff},
+	{0x3002, 0xf0},
+	{0x3600, 0x08},
+	{0x3621, 0xc0},
+	{0x3632, 0xd2},
+	{0x3633, 0x23},
+	{0x3634, 0x54},
+	{0x3f01, 0x0c},
+	{0x5001, 0xc1},
+	{0x3614, 0xf0},
+	{0x3630, 0x2d},
+	{0x370b, 0x62},
+	{0x3706, 0x61},
+	{0x4000, 0x02},
+	{0x4002, 0xc5},
+	{0x4005, 0x08},
+	{0x404f, 0x84},
+	{0x4051, 0x00},
+	{0x5000, 0xcf},
+	{0x3a18, 0x00},
+	{0x3a19, 0x80},
+	{0x3503, 0x07},
+	{0x4521, 0x00},
+	{0x5183, 0xb0},
+	{0x5184, 0xb0},
+	{0x5185, 0xb0},
+	{0x370c, 0x0c},
+	{0x3035, 0x30},
+	{0x3036, 0x14},
+	{0x3037, 0x21},
+	{0x303e, 0x19},
+	{0x3038, 0x06},
+	{0x3018, 0x04},
+	{0x3000, 0x00},
+	{0x3001, 0x00},
+	{0x3002, 0x00},
+	{0x3a0f, 0x40},
+	{0x3a10, 0x38},
+	{0x3a1b, 0x48},
+	{0x3a1e, 0x30},
+	{0x3a11, 0x90},
+	{0x3a1f, 0x10},
+	{0x3011, 0x22},
+	{0x3a00, 0x58},
+};
+
+static struct msm_camera_i2c_reg_conf ov2720_90fps_settings[] = {
+	{0x3718, 0x10},
+	{0x3702, 0x18},
+	{0x373a, 0x3c},
+	{0x3715, 0x01},
+	{0x3703, 0x1d},
+	{0x3705, 0x0b},
+	{0x3730, 0x1f},
+	{0x3704, 0x3f},
+	{0x3f06, 0x1d},
+	{0x371c, 0x00},
+	{0x371d, 0x83},
+	{0x371e, 0x00},
+	{0x371f, 0xb6},
+	{0x3708, 0x63},
+	{0x3709, 0x52},
+	{0x3800, 0x01},
+	{0x3801, 0x42},
+	{0x3802, 0x00},
+	{0x3803, 0x40},
+	{0x3804, 0x06},
+	{0x3805, 0x61},
+	{0x3806, 0x04},
+	{0x3807, 0x08},
+	{0x3808, 0x02},
+	{0x3809, 0x80},
+	{0x380a, 0x01},
+	{0x380b, 0xe0},
+	{0x380c, 0x03},
+	{0x380d, 0x0c},
+	{0x380e, 0x02},
+	{0x380f, 0x00},
+	{0x3810, 0x00},
+	{0x3811, 0x0f},
+	{0x3812, 0x00},
+	{0x3813, 0x02},
+	{0x3820, 0x80},
+	{0x3821, 0x06},
+	{0x3814, 0x31},
+	{0x3815, 0x31},
+	{0x3612, 0x0b},
+	{0x3618, 0x04},
+	{0x3a08, 0x02},
+	{0x3a09, 0x67},
+	{0x3a0a, 0x02},
+	{0x3a0b, 0x00},
+	{0x3a0d, 0x00},
+	{0x3a0e, 0x00},
+	{0x4520, 0x0a},
+	{0x4837, 0x29},
+	{0x3000, 0xff},
+	{0x3001, 0xff},
+	{0x3002, 0xf0},
+	{0x3600, 0x08},
+	{0x3621, 0xc0},
+	{0x3632, 0xd2},
+	{0x3633, 0x23},
+	{0x3634, 0x54},
+	{0x3f01, 0x0c},
+	{0x5001, 0xc1},
+	{0x3614, 0xf0},
+	{0x3630, 0x2d},
+	{0x370b, 0x62},
+	{0x3706, 0x61},
+	{0x4000, 0x02},
+	{0x4002, 0xc5},
+	{0x4005, 0x08},
+	{0x404f, 0x84},
+	{0x4051, 0x00},
+	{0x5000, 0xcf},
+	{0x3a18, 0x00},
+	{0x3a19, 0x80},
+	{0x3503, 0x07},
+	{0x4521, 0x00},
+	{0x5183, 0xb0},
+	{0x5184, 0xb0},
+	{0x5185, 0xb0},
+	{0x370c, 0x0c},
+	{0x3035, 0x30},
+	{0x3036, 0x1e},
+	{0x3037, 0x21},
+	{0x303e, 0x19},
+	{0x3038, 0x06},
+	{0x3018, 0x04},
+	{0x3000, 0x00},
+	{0x3001, 0x00},
+	{0x3002, 0x00},
+	{0x3a0f, 0x40},
+	{0x3a10, 0x38},
+	{0x3a1b, 0x48},
+	{0x3a1e, 0x30},
+	{0x3a11, 0x90},
+	{0x3a1f, 0x10},
+	{0x3011, 0x22},
+	{0x3a00, 0x58},
+};
+
+static struct msm_camera_i2c_reg_conf ov2720_120fps_settings[] = {
+	{0x3718, 0x10},
+	{0x3702, 0x18},
+	{0x373a, 0x3c},
+	{0x3715, 0x01},
+	{0x3703, 0x1d},
+	{0x3705, 0x0b},
+	{0x3730, 0x1f},
+	{0x3704, 0x3f},
+	{0x3f06, 0x1d},
+	{0x371c, 0x00},
+	{0x371d, 0x83},
+	{0x371e, 0x00},
+	{0x371f, 0xb6},
+	{0x3708, 0x63},
+	{0x3709, 0x52},
+	{0x3800, 0x01},
+	{0x3801, 0x42},
+	{0x3802, 0x00},
+	{0x3803, 0x40},
+	{0x3804, 0x06},
+	{0x3805, 0x61},
+	{0x3806, 0x04},
+	{0x3807, 0x08},
+	{0x3808, 0x02},
+	{0x3809, 0x80},
+	{0x380a, 0x01},
+	{0x380b, 0xe0},
+	{0x380c, 0x03},
+	{0x380d, 0x0c},
+	{0x380e, 0x02},
+	{0x380f, 0x00},
+	{0x3810, 0x00},
+	{0x3811, 0x0f},
+	{0x3812, 0x00},
+	{0x3813, 0x02},
+	{0x3820, 0x80},
+	{0x3821, 0x06},
+	{0x3814, 0x31},
+	{0x3815, 0x31},
+	{0x3612, 0x0b},
+	{0x3618, 0x04},
+	{0x3a08, 0x02},
+	{0x3a09, 0x67},
+	{0x3a0a, 0x02},
+	{0x3a0b, 0x00},
+	{0x3a0d, 0x00},
+	{0x3a0e, 0x00},
+	{0x4520, 0x0a},
+	{0x4837, 0x29},
+	{0x3000, 0xff},
+	{0x3001, 0xff},
+	{0x3002, 0xf0},
+	{0x3600, 0x08},
+	{0x3621, 0xc0},
+	{0x3632, 0xd2},
+	{0x3633, 0x23},
+	{0x3634, 0x54},
+	{0x3f01, 0x0c},
+	{0x5001, 0xc1},
+	{0x3614, 0xf0},
+	{0x3630, 0x2d},
+	{0x370b, 0x62},
+	{0x3706, 0x61},
+	{0x4000, 0x02},
+	{0x4002, 0xc5},
+	{0x4005, 0x08},
+	{0x404f, 0x84},
+	{0x4051, 0x00},
+	{0x5000, 0xcf},
+	{0x3a18, 0x00},
+	{0x3a19, 0x80},
+	{0x3503, 0x07},
+	{0x4521, 0x00},
+	{0x5183, 0xb0},
+	{0x5184, 0xb0},
+	{0x5185, 0xb0},
+	{0x370c, 0x0c},
+	{0x3035, 0x10},
+	{0x3036, 0x14},
+	{0x3037, 0x21},
+	{0x303e, 0x19},
+	{0x3038, 0x06},
+	{0x3018, 0x04},
+	{0x3000, 0x00},
+	{0x3001, 0x00},
+	{0x3002, 0x00},
+	{0x3a0f, 0x40},
+	{0x3a10, 0x38},
+	{0x3a1b, 0x48},
+	{0x3a1e, 0x30},
+	{0x3a11, 0x90},
+	{0x3a1f, 0x10},
+	{0x3011, 0x22},
+	{0x3a00, 0x58},
+};
+
+static struct msm_camera_i2c_reg_conf ov2720_recommend_settings[] = {
+	{0x0103, 0x01},
+	{0x3718, 0x10},
+	{0x3702, 0x24},
+	{0x373a, 0x60},
+	{0x3715, 0x01},
+	{0x3703, 0x2e},
+	{0x3705, 0x10},
+	{0x3730, 0x30},
+	{0x3704, 0x62},
+	{0x3f06, 0x3a},
+	{0x371c, 0x00},
+	{0x371d, 0xc4},
+	{0x371e, 0x01},
+	{0x371f, 0x0d},
+	{0x3708, 0x61},
+	{0x3709, 0x12},
+};
+
+static struct v4l2_subdev_info ov2720_subdev_info[] = {
+	{
+	.code   = V4L2_MBUS_FMT_SBGGR10_1X10,
+	.colorspace = V4L2_COLORSPACE_JPEG,
+	.fmt    = 1,
+	.order    = 0,
+	},
+	/* more can be supported, to be added later */
+};
+
+static struct msm_camera_i2c_conf_array ov2720_init_conf[] = {
+	{&ov2720_recommend_settings[0],
+	ARRAY_SIZE(ov2720_recommend_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}
+};
+
+static struct msm_camera_i2c_conf_array ov2720_confs[] = {
+	{&ov2720_prev_settings[0],
+	ARRAY_SIZE(ov2720_prev_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+	{&ov2720_vga_settings[0],
+	ARRAY_SIZE(ov2720_vga_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+	{&ov2720_720_settings[0],
+	ARRAY_SIZE(ov2720_720_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+	{&ov2720_60fps_settings[0],
+	ARRAY_SIZE(ov2720_60fps_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+	{&ov2720_90fps_settings[0],
+	ARRAY_SIZE(ov2720_90fps_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+	{&ov2720_120fps_settings[0],
+	ARRAY_SIZE(ov2720_120fps_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+};
+
+static struct msm_sensor_output_info_t ov2720_dimensions[] = {
+	{
+		.x_output = 0x78C,
+		.y_output = 0x444,
+		.line_length_pclk = 0x85c,
+		.frame_length_lines = 0x460,
+		.vt_pixel_clk = 72000000,
+		.op_pixel_clk = 72000000,
+		.binning_factor = 1,
+	},
+	{
+		.x_output = 0x510,
+		.y_output = 0x278,
+		.line_length_pclk = 0x85c,
+		.frame_length_lines = 0x460,
+		.vt_pixel_clk = 72000000,
+		.op_pixel_clk = 72000000,
+		.binning_factor = 1,
+	},
+	{
+		.x_output = 0x298,
+		.y_output = 0x1F2,
+		.line_length_pclk = 0x85c,
+		.frame_length_lines = 0x460,
+		.vt_pixel_clk = 72000000,
+		.op_pixel_clk = 72000000,
+		.binning_factor = 1,
+	},
+	{
+		.x_output = 0x280, /* 640 */
+		.y_output = 0x1E0, /* 480 */
+		.line_length_pclk = 0x30C, /* 780 */
+		.frame_length_lines = 0x200, /* 512 */
+		.vt_pixel_clk = 24000000,
+		.op_pixel_clk = 24000000,
+		.binning_factor = 1,
+	},
+	{
+		.x_output = 0x280, /* 640 */
+		.y_output = 0x1E0, /* 480 */
+		.line_length_pclk = 0x30C, /* 780 */
+		.frame_length_lines = 0x200, /* 512 */
+		.vt_pixel_clk = 36000000,
+		.op_pixel_clk = 36000000,
+		.binning_factor = 1,
+	},
+	{
+		.x_output = 0x280, /* 640 */
+		.y_output = 0x1E0, /* 480 */
+		.line_length_pclk = 0x30C, /* 780 */
+		.frame_length_lines = 0x200, /* 512 */
+		.vt_pixel_clk = 48000000,
+		.op_pixel_clk = 48000000,
+		.binning_factor = 1,
+	},
+};
+
+static struct msm_sensor_output_reg_addr_t ov2720_reg_addr = {
+	.x_output = 0x3808,
+	.y_output = 0x380a,
+	.line_length_pclk = 0x380c,
+	.frame_length_lines = 0x380e,
+};
+
+static struct msm_sensor_id_info_t ov2720_id_info = {
+	.sensor_id_reg_addr = 0x300A,
+	.sensor_id = 0x2720,
+};
+
+static struct msm_sensor_exp_gain_info_t ov2720_exp_gain_info = {
+	.coarse_int_time_addr = 0x3501,
+	.global_gain_addr = 0x3508,
+	.vert_offset = 6,
+};
+
+static enum msm_camera_vreg_name_t ov2720_veg_seq[] = {
+	CAM_VIO,
+	CAM_VANA,
+	CAM_VDIG,
+};
+
+static int32_t ov2720_write_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
+		uint16_t gain, uint32_t line)
+{
+	uint32_t fl_lines, offset;
+	uint8_t int_time[3];
+	fl_lines =
+		(s_ctrl->curr_frame_length_lines * s_ctrl->fps_divider) / Q10;
+	offset = s_ctrl->sensor_exp_gain_info->vert_offset;
+	if (line > (fl_lines - offset))
+		fl_lines = line + offset;
+
+	s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_output_reg_addr->frame_length_lines, fl_lines,
+		MSM_CAMERA_I2C_WORD_DATA);
+	int_time[0] = line >> 12;
+	int_time[1] = line >> 4;
+	int_time[2] = line << 4;
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr-1,
+		int_time[0], MSM_CAMERA_I2C_BYTE_DATA);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr,
+		int_time[1], MSM_CAMERA_I2C_BYTE_DATA);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr+1,
+		int_time[2], MSM_CAMERA_I2C_BYTE_DATA);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->global_gain_addr, gain,
+		MSM_CAMERA_I2C_WORD_DATA);
+	s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
+	return 0;
+}
+
+static const struct i2c_device_id ov2720_i2c_id[] = {
+	{SENSOR_NAME, (kernel_ulong_t)&ov2720_s_ctrl},
+	{ }
+};
+
+static struct i2c_driver ov2720_i2c_driver = {
+	.id_table = ov2720_i2c_id,
+	.probe  = msm_sensor_i2c_probe,
+	.driver = {
+		.name = SENSOR_NAME,
+	},
+};
+
+static struct msm_camera_i2c_client ov2720_sensor_i2c_client = {
+	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+
+static const struct of_device_id ov2720_dt_match[] = {
+	{.compatible = "qcom,ov2720", .data = &ov2720_s_ctrl},
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, ov2720_dt_match);
+
+static struct platform_driver ov2720_platform_driver = {
+	.driver = {
+		.name = "qcom,ov2720",
+		.owner = THIS_MODULE,
+		.of_match_table = ov2720_dt_match,
+	},
+};
+
+static int32_t ov2720_platform_probe(struct platform_device *pdev)
+{
+	int32_t rc = 0;
+	const struct of_device_id *match;
+	match = of_match_device(ov2720_dt_match, &pdev->dev);
+	rc = msm_sensor_platform_probe(pdev, match->data);
+	return rc;
+}
+
+static int __init msm_sensor_init_module(void)
+{
+	int32_t rc = 0;
+	rc = platform_driver_probe(&ov2720_platform_driver,
+		ov2720_platform_probe);
+	if (!rc)
+		return rc;
+	return i2c_add_driver(&ov2720_i2c_driver);
+}
+
+static void __exit msm_sensor_exit_module(void)
+{
+	if (ov2720_s_ctrl.pdev) {
+		msm_sensor_free_sensor_data(&ov2720_s_ctrl);
+		platform_driver_unregister(&ov2720_platform_driver);
+	} else
+		i2c_del_driver(&ov2720_i2c_driver);
+	return;
+}
+
+static struct v4l2_subdev_core_ops ov2720_subdev_core_ops = {
+	.ioctl = msm_sensor_subdev_ioctl,
+	.s_power = msm_sensor_power,
+};
+
+static struct v4l2_subdev_video_ops ov2720_subdev_video_ops = {
+	.enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
+};
+
+static struct v4l2_subdev_ops ov2720_subdev_ops = {
+	.core = &ov2720_subdev_core_ops,
+	.video  = &ov2720_subdev_video_ops,
+};
+
+static struct msm_sensor_fn_t ov2720_func_tbl = {
+	.sensor_start_stream = msm_sensor_start_stream,
+	.sensor_stop_stream = msm_sensor_stop_stream,
+	.sensor_group_hold_on = msm_sensor_group_hold_on,
+	.sensor_group_hold_off = msm_sensor_group_hold_off,
+	.sensor_set_fps = msm_sensor_set_fps,
+	.sensor_write_exp_gain = ov2720_write_exp_gain,
+	.sensor_write_snapshot_exp_gain = ov2720_write_exp_gain,
+	.sensor_setting = msm_sensor_setting,
+	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
+	.sensor_mode_init = msm_sensor_mode_init,
+	.sensor_get_output_info = msm_sensor_get_output_info,
+	.sensor_config = msm_sensor_config,
+	.sensor_power_up = msm_sensor_power_up,
+	.sensor_power_down = msm_sensor_power_down,
+	.sensor_adjust_frame_lines = msm_sensor_adjust_frame_lines2,
+	.sensor_get_csi_params = msm_sensor_get_csi_params,
+};
+
+static struct msm_sensor_reg_t ov2720_regs = {
+	.default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
+	.start_stream_conf = ov2720_start_settings,
+	.start_stream_conf_size = ARRAY_SIZE(ov2720_start_settings),
+	.stop_stream_conf = ov2720_stop_settings,
+	.stop_stream_conf_size = ARRAY_SIZE(ov2720_stop_settings),
+	.group_hold_on_conf = ov2720_groupon_settings,
+	.group_hold_on_conf_size = ARRAY_SIZE(ov2720_groupon_settings),
+	.group_hold_off_conf = ov2720_groupoff_settings,
+	.group_hold_off_conf_size =
+		ARRAY_SIZE(ov2720_groupoff_settings),
+	.init_settings = &ov2720_init_conf[0],
+	.init_size = ARRAY_SIZE(ov2720_init_conf),
+	.mode_settings = &ov2720_confs[0],
+	.output_settings = &ov2720_dimensions[0],
+	.num_conf = ARRAY_SIZE(ov2720_confs),
+};
+
+static struct msm_sensor_ctrl_t ov2720_s_ctrl = {
+	.msm_sensor_reg = &ov2720_regs,
+	.sensor_i2c_client = &ov2720_sensor_i2c_client,
+	.sensor_i2c_addr = 0x6C,
+	.vreg_seq = ov2720_veg_seq,
+	.num_vreg_seq = ARRAY_SIZE(ov2720_veg_seq),
+	.sensor_output_reg_addr = &ov2720_reg_addr,
+	.sensor_id_info = &ov2720_id_info,
+	.sensor_exp_gain_info = &ov2720_exp_gain_info,
+	.cam_mode = MSM_SENSOR_MODE_INVALID,
+	.msm_sensor_mutex = &ov2720_mut,
+	.sensor_i2c_driver = &ov2720_i2c_driver,
+	.sensor_v4l2_subdev_info = ov2720_subdev_info,
+	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(ov2720_subdev_info),
+	.sensor_v4l2_subdev_ops = &ov2720_subdev_ops,
+	.func_tbl = &ov2720_func_tbl,
+	.clk_rate = MSM_SENSOR_MCLK_24HZ,
+};
+
+module_init(msm_sensor_init_module);
+module_exit(msm_sensor_exit_module);
+MODULE_DESCRIPTION("Omnivision 2MP Bayer sensor driver");
+MODULE_LICENSE("GPL v2");
+
+
diff --git a/drivers/media/platform/msm/camera_v1/sensors/ov2720.h b/drivers/media/platform/msm/camera_v1/sensors/ov2720.h
new file mode 100644
index 0000000..6b47666
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/sensors/ov2720.h
@@ -0,0 +1,16 @@
+/* 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 <mach/board.h>
+extern struct platform_driver ov2720_driver;
+
diff --git a/drivers/media/platform/msm/camera_v1/sensors/ov5647_v4l2.c b/drivers/media/platform/msm/camera_v1/sensors/ov5647_v4l2.c
new file mode 100644
index 0000000..f27e648
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/sensors/ov5647_v4l2.c
@@ -0,0 +1,831 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_sensor.h"
+#include "msm.h"
+#define SENSOR_NAME "ov5647"
+#define PLATFORM_DRIVER_NAME "msm_camera_ov5647"
+#define ov5647_obj ov5647_##obj
+
+static struct msm_sensor_ctrl_t ov5647_s_ctrl;
+
+DEFINE_MUTEX(ov5647_mut);
+
+static struct msm_camera_i2c_reg_conf ov5647_start_settings[] = {
+	{0x4202, 0x00},  /* streaming on */
+	{0x0100, 0x01},
+	{0x4800, 0x04},
+};
+
+static struct msm_camera_i2c_reg_conf ov5647_stop_settings[] = {
+	{0x4202, 0x0f},  /* streaming off*/
+};
+
+static struct msm_camera_i2c_reg_conf ov5647_groupon_settings[] = {
+	{0x3208, 0x0},
+};
+
+static struct msm_camera_i2c_reg_conf ov5647_groupoff_settings[] = {
+	{0x3208, 0x10},
+	{0x3208, 0xa0},
+};
+
+static struct msm_camera_i2c_reg_conf ov5647_prev_settings[] = {
+	/*1280*960 Reference Setting 24M MCLK 2lane 280Mbps/lane 30fps
+	for back to preview*/
+	{0x3035, 0x21},
+	{0x3036, 0x37},
+	{0x3821, 0x07},
+	{0x3820, 0x41},
+	{0x3612, 0x09},
+	{0x3618, 0x00},
+	{0x380c, 0x07},
+	{0x380d, 0x68},
+	{0x380e, 0x03},
+	{0x380f, 0xd8},
+	{0x3814, 0x31},
+	{0x3815, 0x31},
+	{0x3709, 0x52},
+	{0x3808, 0x05},
+	{0x3809, 0x00},
+	{0x380a, 0x03},
+	{0x380b, 0xc0},
+	{0x3800, 0x00},
+	{0x3801, 0x18},
+	{0x3802, 0x00},
+	{0x3803, 0x0e},
+	{0x3804, 0x0a},
+	{0x3805, 0x27},
+	{0x3806, 0x07},
+	{0x3807, 0x95},
+	{0x4004, 0x02},
+};
+
+static struct msm_camera_i2c_reg_conf ov5647_snap_settings[] = {
+	/*2608*1952 Reference Setting 24M MCLK 2lane 280Mbps/lane 30fps*/
+	{0x3035, 0x21},
+	{0x3036, 0x4f},
+	{0x3821, 0x06},
+	{0x3820, 0x00},
+	{0x3612, 0x0b},
+	{0x3618, 0x04},
+	{0x380c, 0x0a},
+	{0x380d, 0x8c},
+	{0x380e, 0x07},
+	{0x380f, 0xb0},
+	{0x3814, 0x11},
+	{0x3815, 0x11},
+	{0x3709, 0x12},
+	{0x3808, 0x0a},
+	{0x3809, 0x30},
+	{0x380a, 0x07},
+	{0x380b, 0xa0},
+	{0x3800, 0x00},
+	{0x3801, 0x04},
+	{0x3802, 0x00},
+	{0x3803, 0x00},
+	{0x3804, 0x0a},
+	{0x3805, 0x3b},
+	{0x3806, 0x07},
+	{0x3807, 0xa3},
+	{0x4004, 0x04},
+};
+
+static struct msm_camera_i2c_reg_conf ov5647_video_60fps_settings[] = {
+	{0x3035, 0x21},
+	{0x3036, 0x38},
+	{0x3821, 0x07},
+	{0x3820, 0x41},
+	{0x3612, 0x49},
+	{0x3618, 0x00},
+	{0x380c, 0x07},
+	{0x380d, 0x30},
+	{0x380e, 0x01},
+	{0x380f, 0xf8},
+	{0x3814, 0x71},
+	{0x3815, 0x71},
+	{0x3709, 0x52},
+	{0x3808, 0x02},
+	{0x3809, 0x80},
+	{0x380a, 0x01},
+	{0x380b, 0xe0},
+	{0x3800, 0x00},
+	{0x3801, 0x10},
+	{0x3802, 0x00},
+	{0x3803, 0x00},
+	{0x3804, 0x0a},
+	{0x3805, 0x2f},
+	{0x3806, 0x07},
+	{0x3807, 0x9f},
+	{0x4004, 0x02},
+};
+
+static struct msm_camera_i2c_reg_conf ov5647_video_90fps_settings[] = {
+	{0x3035, 0x11},
+	{0x3036, 0x2a},
+	{0x3821, 0x07},
+	{0x3820, 0x41},
+	{0x3612, 0x49},
+	{0x3618, 0x00},
+	{0x380c, 0x07},
+	{0x380d, 0x30},
+	{0x380e, 0x01},
+	{0x380f, 0xf8},
+	{0x3814, 0x71},
+	{0x3815, 0x71},
+	{0x3709, 0x52},
+	{0x3808, 0x02},
+	{0x3809, 0x80},
+	{0x380a, 0x01},
+	{0x380b, 0xe0},
+	{0x3800, 0x00},
+	{0x3801, 0x10},
+	{0x3802, 0x00},
+	{0x3803, 0x00},
+	{0x3804, 0x0a},
+	{0x3805, 0x2f},
+	{0x3806, 0x07},
+	{0x3807, 0x9f},
+	{0x4004, 0x02},
+};
+
+static struct msm_camera_i2c_reg_conf ov5647_zsl_settings[] = {
+	{0x3035, 0x21},
+	{0x3036, 0x4f},
+	{0x3821, 0x06},
+	{0x3820, 0x00},
+	{0x3612, 0x0b},
+	{0x3618, 0x04},
+	{0x380c, 0x0a},
+	{0x380d, 0x8c},
+	{0x380e, 0x07},
+	{0x380f, 0xb0},
+	{0x3814, 0x11},
+	{0x3815, 0x11},
+	{0x3709, 0x12},
+	{0x3808, 0x0a},
+	{0x3809, 0x30},
+	{0x380a, 0x07},
+	{0x380b, 0xa0},
+	{0x3800, 0x00},
+	{0x3801, 0x04},
+	{0x3802, 0x00},
+	{0x3803, 0x00},
+	{0x3804, 0x0a},
+	{0x3805, 0x3b},
+	{0x3806, 0x07},
+	{0x3807, 0xa3},
+	{0x4004, 0x04},
+};
+
+static struct msm_camera_i2c_reg_conf ov5647_recommend_settings[] = {
+	{0x3035, 0x11},
+	{0x303c, 0x11},
+	{0x370c, 0x03},
+	{0x5000, 0x06},
+	{0x5003, 0x08},
+	{0x5a00, 0x08},
+	{0x3000, 0xff},
+	{0x3001, 0xff},
+	{0x3002, 0xff},
+	{0x301d, 0xf0},
+	{0x3a18, 0x00},
+	{0x3a19, 0xf8},
+	{0x3c01, 0x80},
+	{0x3b07, 0x0c},
+	{0x3708, 0x64},
+	{0x3630, 0x2e},
+	{0x3632, 0xe2},
+	{0x3633, 0x23},
+	{0x3634, 0x44},
+	{0x3620, 0x64},
+	{0x3621, 0xe0},
+	{0x3600, 0x37},
+	{0x3704, 0xa0},
+	{0x3703, 0x5a},
+	{0x3715, 0x78},
+	{0x3717, 0x01},
+	{0x3731, 0x02},
+	{0x370b, 0x60},
+	{0x3705, 0x1a},
+	{0x3f05, 0x02},
+	{0x3f06, 0x10},
+	{0x3f01, 0x0a},
+	{0x3a08, 0x01},
+	{0x3a0f, 0x58},
+	{0x3a10, 0x50},
+	{0x3a1b, 0x58},
+	{0x3a1e, 0x50},
+	{0x3a11, 0x60},
+	{0x3a1f, 0x28},
+	{0x4001, 0x02},
+	{0x4000, 0x09},
+	{0x3000, 0x00},
+	{0x3001, 0x00},
+	{0x3002, 0x00},
+	{0x3017, 0xe0},
+	{0x301c, 0xfc},
+	{0x3636, 0x06},
+	{0x3016, 0x08},
+	{0x3827, 0xec},
+	{0x3018, 0x44},
+	{0x3035, 0x21},
+	{0x3106, 0xf5},
+	{0x3034, 0x18},
+	{0x301c, 0xf8},
+	/*lens setting*/
+	{0x5000, 0x86},
+	{0x5800, 0x11},
+	{0x5801, 0x0c},
+	{0x5802, 0x0a},
+	{0x5803, 0x0b},
+	{0x5804, 0x0d},
+	{0x5805, 0x13},
+	{0x5806, 0x09},
+	{0x5807, 0x05},
+	{0x5808, 0x03},
+	{0x5809, 0x03},
+	{0x580a, 0x06},
+	{0x580b, 0x08},
+	{0x580c, 0x05},
+	{0x580d, 0x01},
+	{0x580e, 0x00},
+	{0x580f, 0x00},
+	{0x5810, 0x02},
+	{0x5811, 0x06},
+	{0x5812, 0x05},
+	{0x5813, 0x01},
+	{0x5814, 0x00},
+	{0x5815, 0x00},
+	{0x5816, 0x02},
+	{0x5817, 0x06},
+	{0x5818, 0x09},
+	{0x5819, 0x05},
+	{0x581a, 0x04},
+	{0x581b, 0x04},
+	{0x581c, 0x06},
+	{0x581d, 0x09},
+	{0x581e, 0x11},
+	{0x581f, 0x0c},
+	{0x5820, 0x0b},
+	{0x5821, 0x0b},
+	{0x5822, 0x0d},
+	{0x5823, 0x13},
+	{0x5824, 0x22},
+	{0x5825, 0x26},
+	{0x5826, 0x26},
+	{0x5827, 0x24},
+	{0x5828, 0x24},
+	{0x5829, 0x24},
+	{0x582a, 0x22},
+	{0x582b, 0x20},
+	{0x582c, 0x22},
+	{0x582d, 0x26},
+	{0x582e, 0x22},
+	{0x582f, 0x22},
+	{0x5830, 0x42},
+	{0x5831, 0x22},
+	{0x5832, 0x02},
+	{0x5833, 0x24},
+	{0x5834, 0x22},
+	{0x5835, 0x22},
+	{0x5836, 0x22},
+	{0x5837, 0x26},
+	{0x5838, 0x42},
+	{0x5839, 0x26},
+	{0x583a, 0x06},
+	{0x583b, 0x26},
+	{0x583c, 0x24},
+	{0x583d, 0xce},
+	/* manual AWB,manual AE,close Lenc,open WBC*/
+	{0x3503, 0x03}, /*manual AE*/
+	{0x3501, 0x10},
+	{0x3502, 0x80},
+	{0x350a, 0x00},
+	{0x350b, 0x7f},
+	{0x5001, 0x01}, /*manual AWB*/
+	{0x5180, 0x08},
+	{0x5186, 0x04},
+	{0x5187, 0x00},
+	{0x5188, 0x04},
+	{0x5189, 0x00},
+	{0x518a, 0x04},
+	{0x518b, 0x00},
+	{0x5000, 0x06}, /*No lenc,WBC on*/
+	{0x4005, 0x18},
+	{0x4051, 0x8f},
+};
+
+
+static struct msm_camera_i2c_conf_array ov5647_init_conf[] = {
+	{&ov5647_recommend_settings[0],
+	ARRAY_SIZE(ov5647_recommend_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}
+};
+
+static struct msm_camera_i2c_conf_array ov5647_confs[] = {
+	{&ov5647_snap_settings[0],
+	ARRAY_SIZE(ov5647_snap_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+	{&ov5647_prev_settings[0],
+	ARRAY_SIZE(ov5647_prev_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+	{&ov5647_video_60fps_settings[0],
+	ARRAY_SIZE(ov5647_video_60fps_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+	{&ov5647_video_90fps_settings[0],
+	ARRAY_SIZE(ov5647_video_90fps_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+	{&ov5647_zsl_settings[0],
+	ARRAY_SIZE(ov5647_zsl_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+};
+
+static struct v4l2_subdev_info ov5647_subdev_info[] = {
+	{
+		.code   = V4L2_MBUS_FMT_SBGGR10_1X10,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.fmt    = 1,
+		.order    = 0,
+	},
+	/* more can be supported, to be added later */
+};
+
+static struct msm_sensor_output_info_t ov5647_dimensions[] = {
+	{ /* For SNAPSHOT */
+		.x_output = 0xA30,  /*2608*/  /*for 5Mp*/
+		.y_output = 0x7A0,   /*1952*/
+		.line_length_pclk = 0xA8C,
+		.frame_length_lines = 0x7B0,
+		.vt_pixel_clk = 79704000,
+		.op_pixel_clk = 159408000,
+		.binning_factor = 0x0,
+	},
+	{ /* For PREVIEW */
+		.x_output = 0x500, /*1280*/
+		.y_output = 0x3C0, /*960*/
+		.line_length_pclk = 0x768,
+		.frame_length_lines = 0x3D8,
+		.vt_pixel_clk = 55969920,
+		.op_pixel_clk = 159408000,
+		.binning_factor = 0x0,
+	},
+	{ /* For 60fps */
+		.x_output = 0x280,  /*640*/
+		.y_output = 0x1E0,   /*480*/
+		.line_length_pclk = 0x73C,
+		.frame_length_lines = 0x1F8,
+		.vt_pixel_clk = 56004480,
+		.op_pixel_clk = 159408000,
+		.binning_factor = 0x0,
+	},
+	{ /* For 90fps */
+		.x_output = 0x280,  /*640*/
+		.y_output = 0x1E0,   /*480*/
+		.line_length_pclk = 0x73C,
+		.frame_length_lines = 0x1F8,
+		.vt_pixel_clk = 56004480,
+		.op_pixel_clk = 159408000,
+		.binning_factor = 0x0,
+	},
+	{ /* For ZSL */
+		.x_output = 0xA30,  /*2608*/  /*for 5Mp*/
+		.y_output = 0x7A0,   /*1952*/
+		.line_length_pclk = 0xA8C,
+		.frame_length_lines = 0x7B0,
+		.vt_pixel_clk = 79704000,
+		.op_pixel_clk = 159408000,
+		.binning_factor = 0x0,
+	},
+
+};
+
+static struct msm_sensor_output_reg_addr_t ov5647_reg_addr = {
+	.x_output = 0x3808,
+	.y_output = 0x380A,
+	.line_length_pclk = 0x380C,
+	.frame_length_lines = 0x380E,
+};
+
+static struct msm_sensor_id_info_t ov5647_id_info = {
+	.sensor_id_reg_addr = 0x300a,
+	.sensor_id = 0x5647,
+};
+
+static struct msm_sensor_exp_gain_info_t ov5647_exp_gain_info = {
+	.coarse_int_time_addr = 0x3500,
+	.global_gain_addr = 0x350A,
+	.vert_offset = 4,
+};
+
+void ov5647_sensor_reset_stream(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	msm_camera_i2c_write(
+		s_ctrl->sensor_i2c_client,
+		0x103, 0x1,
+		MSM_CAMERA_I2C_BYTE_DATA);
+}
+
+static int32_t ov5647_write_pict_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
+		uint16_t gain, uint32_t line)
+{
+
+	static uint16_t max_line = 1964;
+	uint8_t gain_lsb, gain_hsb;
+	u8 intg_time_hsb, intg_time_msb, intg_time_lsb;
+
+	gain_lsb = (uint8_t) (gain);
+	gain_hsb = (uint8_t)((gain & 0x300)>>8);
+
+	CDBG(KERN_ERR "snapshot exposure seting 0x%x, 0x%x, %d"
+		, gain, line, line);
+	s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
+	if (line > 1964) {
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+			s_ctrl->sensor_output_reg_addr->frame_length_lines,
+			(uint8_t)((line+4) >> 8),
+			MSM_CAMERA_I2C_BYTE_DATA);
+
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+			s_ctrl->sensor_output_reg_addr->frame_length_lines + 1,
+			(uint8_t)((line+4) & 0x00FF),
+			MSM_CAMERA_I2C_BYTE_DATA);
+		max_line = line + 4;
+	} else if (max_line > 1968) {
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+			s_ctrl->sensor_output_reg_addr->frame_length_lines,
+			(uint8_t)(1968 >> 8),
+			MSM_CAMERA_I2C_BYTE_DATA);
+
+		 msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+			s_ctrl->sensor_output_reg_addr->frame_length_lines + 1,
+			(uint8_t)(1968 & 0x00FF),
+			MSM_CAMERA_I2C_BYTE_DATA);
+			max_line = 1968;
+	}
+
+
+	line = line<<4;
+	/* ov5647 need this operation */
+	intg_time_hsb = (u8)(line>>16);
+	intg_time_msb = (u8) ((line & 0xFF00) >> 8);
+	intg_time_lsb = (u8) (line & 0x00FF);
+
+	/* FIXME for BLC trigger */
+	/* Coarse Integration Time */
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr,
+		intg_time_hsb,
+		MSM_CAMERA_I2C_BYTE_DATA);
+
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr + 1,
+		intg_time_msb,
+		MSM_CAMERA_I2C_BYTE_DATA);
+
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr + 2,
+		intg_time_lsb,
+		MSM_CAMERA_I2C_BYTE_DATA);
+
+	/* gain */
+
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->global_gain_addr,
+		gain_hsb,
+		MSM_CAMERA_I2C_BYTE_DATA);
+
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->global_gain_addr + 1,
+		gain_lsb^0x1,
+		MSM_CAMERA_I2C_BYTE_DATA);
+
+	/* Coarse Integration Time */
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr,
+		intg_time_hsb,
+		MSM_CAMERA_I2C_BYTE_DATA);
+
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr + 1,
+		intg_time_msb,
+		MSM_CAMERA_I2C_BYTE_DATA);
+
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr + 2,
+		intg_time_lsb,
+		MSM_CAMERA_I2C_BYTE_DATA);
+
+	/* gain */
+
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->global_gain_addr,
+		gain_hsb,
+		MSM_CAMERA_I2C_BYTE_DATA);
+
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->global_gain_addr + 1,
+		gain_lsb,
+		MSM_CAMERA_I2C_BYTE_DATA);
+
+
+	s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
+	return 0;
+
+}
+
+
+static int32_t ov5647_write_prev_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
+						uint16_t gain, uint32_t line)
+{
+	u8 intg_time_hsb, intg_time_msb, intg_time_lsb;
+	uint8_t gain_lsb, gain_hsb;
+	uint32_t fl_lines = s_ctrl->curr_frame_length_lines;
+	uint8_t offset = s_ctrl->sensor_exp_gain_info->vert_offset;
+
+	CDBG(KERN_ERR "preview exposure setting 0x%x, 0x%x, %d",
+		 gain, line, line);
+
+	gain_lsb = (uint8_t) (gain);
+	gain_hsb = (uint8_t)((gain & 0x300)>>8);
+
+	fl_lines = (fl_lines * s_ctrl->fps_divider) / Q10;
+
+	s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
+
+	/* adjust frame rate */
+	if ((s_ctrl->curr_res < MSM_SENSOR_RES_2) &&
+		(line > (fl_lines - offset)))
+		fl_lines = line + offset;
+
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_output_reg_addr->frame_length_lines,
+		(uint8_t)(fl_lines >> 8),
+		MSM_CAMERA_I2C_BYTE_DATA);
+
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_output_reg_addr->frame_length_lines + 1,
+		(uint8_t)(fl_lines & 0x00FF),
+		MSM_CAMERA_I2C_BYTE_DATA);
+
+	line = line<<4;
+	/* ov5647 need this operation */
+	intg_time_hsb = (u8)(line>>16);
+	intg_time_msb = (u8) ((line & 0xFF00) >> 8);
+	intg_time_lsb = (u8) (line & 0x00FF);
+
+
+	/* Coarse Integration Time */
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr,
+		intg_time_hsb,
+		MSM_CAMERA_I2C_BYTE_DATA);
+
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr + 1,
+		intg_time_msb,
+		MSM_CAMERA_I2C_BYTE_DATA);
+
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr + 2,
+		intg_time_lsb,
+		MSM_CAMERA_I2C_BYTE_DATA);
+
+	/* gain */
+
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->global_gain_addr,
+		gain_hsb,
+		MSM_CAMERA_I2C_BYTE_DATA);
+
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->global_gain_addr + 1,
+		gain_lsb,
+		MSM_CAMERA_I2C_BYTE_DATA);
+
+	s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
+
+	return 0;
+}
+
+static const struct i2c_device_id ov5647_i2c_id[] = {
+	{SENSOR_NAME, (kernel_ulong_t)&ov5647_s_ctrl},
+	{ }
+};
+int32_t ov5647_sensor_i2c_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	int32_t rc = 0;
+	struct msm_sensor_ctrl_t *s_ctrl;
+
+	rc = msm_sensor_i2c_probe(client, id);
+
+	if (client->dev.platform_data == NULL) {
+		pr_err("%s: NULL sensor data\n", __func__);
+		return -EFAULT;
+	}
+
+	s_ctrl = client->dev.platform_data;
+
+	return rc;
+}
+
+static struct i2c_driver ov5647_i2c_driver = {
+	.id_table = ov5647_i2c_id,
+	.probe  = ov5647_sensor_i2c_probe,
+	.driver = {
+		.name = SENSOR_NAME,
+	},
+};
+
+
+
+static struct msm_camera_i2c_client ov5647_sensor_i2c_client = {
+	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+static int __init msm_sensor_init_module(void)
+{
+	return i2c_add_driver(&ov5647_i2c_driver);
+}
+
+static struct v4l2_subdev_core_ops ov5647_subdev_core_ops = {
+	.ioctl = msm_sensor_subdev_ioctl,
+	.s_power = msm_sensor_power,
+};
+
+static struct v4l2_subdev_video_ops ov5647_subdev_video_ops = {
+	.enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
+};
+
+static struct v4l2_subdev_ops ov5647_subdev_ops = {
+	.core = &ov5647_subdev_core_ops,
+	.video  = &ov5647_subdev_video_ops,
+};
+
+int32_t ov5647_sensor_power_down(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	struct msm_camera_sensor_info *info = NULL;
+	unsigned short rdata;
+	int rc;
+
+	info = s_ctrl->sensordata;
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		0x4202, 0xf,
+		MSM_CAMERA_I2C_BYTE_DATA);
+	msleep(20);
+	rc = msm_camera_i2c_read(s_ctrl->sensor_i2c_client, 0x3018,
+			&rdata, MSM_CAMERA_I2C_WORD_DATA);
+	CDBG("ov5647_sensor_power_down: %d\n", rc);
+	rdata |= 0x18;
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		0x3018, rdata,
+		MSM_CAMERA_I2C_WORD_DATA);
+	msleep(20);
+	gpio_direction_output(info->sensor_pwd, 1);
+	usleep_range(5000, 5100);
+	msm_sensor_power_down(s_ctrl);
+	return 0;
+}
+
+int32_t ov5647_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	int32_t rc = 0;
+	struct msm_camera_sensor_info *info = NULL;
+
+	info = s_ctrl->sensordata;
+	gpio_direction_output(info->sensor_pwd, 1);
+	gpio_direction_output(info->sensor_reset, 0);
+	usleep_range(10000, 11000);
+	rc = msm_sensor_power_up(s_ctrl);
+	if (rc < 0) {
+		CDBG("%s: msm_sensor_power_up failed\n", __func__);
+		return rc;
+	}
+
+	/* turn on ldo and vreg */
+
+	gpio_direction_output(info->sensor_pwd, 0);
+	msleep(20);
+	gpio_direction_output(info->sensor_reset, 1);
+	msleep(25);
+
+	return rc;
+
+}
+
+static int32_t vfe_clk = 266667000;
+
+static void ov5647_stop_stream(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	msm_camera_i2c_write_tbl(
+		s_ctrl->sensor_i2c_client,
+		s_ctrl->msm_sensor_reg->stop_stream_conf,
+		s_ctrl->msm_sensor_reg->stop_stream_conf_size,
+		s_ctrl->msm_sensor_reg->default_data_type);
+
+	if (s_ctrl->curr_res == MSM_SENSOR_RES_FULL)
+		msleep(66);
+	else
+		msleep(266);
+
+	msm_camera_i2c_write(
+			s_ctrl->sensor_i2c_client,
+			0x4800, 0x25,
+			MSM_CAMERA_I2C_BYTE_DATA);
+}
+
+int32_t ov5647_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
+			int update_type, int res)
+{
+	int32_t rc = 0;
+	if (update_type == MSM_SENSOR_REG_INIT) {
+		CDBG("Register INIT\n");
+		s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
+		msm_camera_i2c_write(
+				s_ctrl->sensor_i2c_client,
+				0x103, 0x1,
+				MSM_CAMERA_I2C_BYTE_DATA);
+		msm_sensor_enable_debugfs(s_ctrl);
+		msm_sensor_write_init_settings(s_ctrl);
+	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
+		CDBG("PERIODIC : %d\n", res);
+		msm_sensor_write_conf_array(
+			s_ctrl->sensor_i2c_client,
+			s_ctrl->msm_sensor_reg->mode_settings, res);
+		msleep(30);
+		msm_camera_i2c_write(
+			s_ctrl->sensor_i2c_client,
+			0x100, 0x1,
+			MSM_CAMERA_I2C_BYTE_DATA);
+		msm_camera_i2c_write(
+			s_ctrl->sensor_i2c_client,
+			0x4800, 0x4,
+			MSM_CAMERA_I2C_BYTE_DATA);
+		msleep(266);
+		if (res == MSM_SENSOR_RES_4)
+			v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
+					NOTIFY_PCLK_CHANGE,
+					&vfe_clk);
+	}
+	return rc;
+}
+static struct msm_sensor_fn_t ov5647_func_tbl = {
+	.sensor_start_stream = msm_sensor_start_stream,
+	.sensor_stop_stream = ov5647_stop_stream,
+	.sensor_group_hold_on = msm_sensor_group_hold_on,
+	.sensor_group_hold_off = msm_sensor_group_hold_off,
+	.sensor_set_fps = msm_sensor_set_fps,
+	.sensor_write_exp_gain = ov5647_write_prev_exp_gain,
+	.sensor_write_snapshot_exp_gain = ov5647_write_pict_exp_gain,
+	.sensor_csi_setting = ov5647_sensor_setting,
+	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
+	.sensor_mode_init = msm_sensor_mode_init,
+	.sensor_get_output_info = msm_sensor_get_output_info,
+	.sensor_config = msm_sensor_config,
+	.sensor_power_up = ov5647_sensor_power_up,
+	.sensor_power_down = ov5647_sensor_power_down,
+};
+
+static struct msm_sensor_reg_t ov5647_regs = {
+	.default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
+	.start_stream_conf = ov5647_start_settings,
+	.start_stream_conf_size = ARRAY_SIZE(ov5647_start_settings),
+	.stop_stream_conf = ov5647_stop_settings,
+	.stop_stream_conf_size = ARRAY_SIZE(ov5647_stop_settings),
+	.group_hold_on_conf = ov5647_groupon_settings,
+	.group_hold_on_conf_size = ARRAY_SIZE(ov5647_groupon_settings),
+	.group_hold_off_conf = ov5647_groupoff_settings,
+	.group_hold_off_conf_size =
+		ARRAY_SIZE(ov5647_groupoff_settings),
+	.init_settings = &ov5647_init_conf[0],
+	.init_size = ARRAY_SIZE(ov5647_init_conf),
+	.mode_settings = &ov5647_confs[0],
+	.output_settings = &ov5647_dimensions[0],
+	.num_conf = ARRAY_SIZE(ov5647_confs),
+};
+
+static struct msm_sensor_ctrl_t ov5647_s_ctrl = {
+	.msm_sensor_reg = &ov5647_regs,
+	.sensor_i2c_client = &ov5647_sensor_i2c_client,
+	.sensor_i2c_addr =  0x36 << 1 ,
+	.sensor_output_reg_addr = &ov5647_reg_addr,
+	.sensor_id_info = &ov5647_id_info,
+	.sensor_exp_gain_info = &ov5647_exp_gain_info,
+	.cam_mode = MSM_SENSOR_MODE_INVALID,
+	.msm_sensor_mutex = &ov5647_mut,
+	.sensor_i2c_driver = &ov5647_i2c_driver,
+	.sensor_v4l2_subdev_info = ov5647_subdev_info,
+	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(ov5647_subdev_info),
+	.sensor_v4l2_subdev_ops = &ov5647_subdev_ops,
+	.func_tbl = &ov5647_func_tbl,
+	.clk_rate = MSM_SENSOR_MCLK_24HZ,
+};
+
+module_init(msm_sensor_init_module);
+MODULE_DESCRIPTION("Omnivision WXGA Bayer sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/sensors/ov7692_v4l2.c b/drivers/media/platform/msm/camera_v1/sensors/ov7692_v4l2.c
new file mode 100644
index 0000000..efc78f8
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/sensors/ov7692_v4l2.c
@@ -0,0 +1,926 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_sensor.h"
+#define SENSOR_NAME "ov7692"
+
+DEFINE_MUTEX(ov7692_mut);
+static struct msm_sensor_ctrl_t ov7692_s_ctrl;
+
+static int effect_value = CAMERA_EFFECT_OFF;
+static unsigned int SAT_U = 0x80; /* DEFAULT SATURATION VALUES*/
+static unsigned int SAT_V = 0x80; /* DEFAULT SATURATION VALUES*/
+
+static struct msm_camera_i2c_reg_conf ov7692_start_settings[] = {
+	{0x0e, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf ov7692_stop_settings[] = {
+	{0x0e, 0x08},
+};
+
+static struct msm_camera_i2c_reg_conf ov7692_recommend_settings[] = {
+	{0x12, 0x80},
+	{0x0e, 0x08},
+	{0x69, 0x52},
+	{0x1e, 0xb3},
+	{0x48, 0x42},
+	{0xff, 0x01},
+	{0xae, 0xa0},
+	{0xa8, 0x26},
+	{0xb4, 0xc0},
+	{0xb5, 0x40},
+	{0xff, 0x00},
+	{0x0c, 0x00},
+	{0x62, 0x10},
+	{0x12, 0x00},
+	{0x17, 0x65},
+	{0x18, 0xa4},
+	{0x19, 0x0a},
+	{0x1a, 0xf6},
+	{0x3e, 0x30},
+	{0x64, 0x0a},
+	{0xff, 0x01},
+	{0xb4, 0xc0},
+	{0xff, 0x00},
+	{0x67, 0x20},
+	{0x81, 0x3f},
+	{0xd0, 0x48},
+	{0x82, 0x03},
+	{0x70, 0x00},
+	{0x71, 0x34},
+	{0x74, 0x28},
+	{0x75, 0x98},
+	{0x76, 0x00},
+	{0x77, 0x64},
+	{0x78, 0x01},
+	{0x79, 0xc2},
+	{0x7a, 0x4e},
+	{0x7b, 0x1f},
+	{0x7c, 0x00},
+	{0x11, 0x00},
+	{0x20, 0x00},
+	{0x21, 0x23},
+	{0x50, 0x9a},
+	{0x51, 0x80},
+	{0x4c, 0x7d},
+	{0x85, 0x10},
+	{0x86, 0x00},
+	{0x87, 0x00},
+	{0x88, 0x00},
+	{0x89, 0x2a},
+	{0x8a, 0x26},
+	{0x8b, 0x22},
+	{0xbb, 0x7a},
+	{0xbc, 0x69},
+	{0xbd, 0x11},
+	{0xbe, 0x13},
+	{0xbf, 0x81},
+	{0xc0, 0x96},
+	{0xc1, 0x1e},
+	{0xb7, 0x05},
+	{0xb8, 0x09},
+	{0xb9, 0x00},
+	{0xba, 0x18},
+	{0x5a, 0x1f},
+	{0x5b, 0x9f},
+	{0x5c, 0x6a},
+	{0x5d, 0x42},
+	{0x24, 0x78},
+	{0x25, 0x68},
+	{0x26, 0xb3},
+	{0xa3, 0x0b},
+	{0xa4, 0x15},
+	{0xa5, 0x2a},
+	{0xa6, 0x51},
+	{0xa7, 0x63},
+	{0xa8, 0x74},
+	{0xa9, 0x83},
+	{0xaa, 0x91},
+	{0xab, 0x9e},
+	{0xac, 0xaa},
+	{0xad, 0xbe},
+	{0xae, 0xce},
+	{0xaf, 0xe5},
+	{0xb0, 0xf3},
+	{0xb1, 0xfb},
+	{0xb2, 0x06},
+	{0x8c, 0x5c},
+	{0x8d, 0x11},
+	{0x8e, 0x12},
+	{0x8f, 0x19},
+	{0x90, 0x50},
+	{0x91, 0x20},
+	{0x92, 0x96},
+	{0x93, 0x80},
+	{0x94, 0x13},
+	{0x95, 0x1b},
+	{0x96, 0xff},
+	{0x97, 0x00},
+	{0x98, 0x3d},
+	{0x99, 0x36},
+	{0x9a, 0x51},
+	{0x9b, 0x43},
+	{0x9c, 0xf0},
+	{0x9d, 0xf0},
+	{0x9e, 0xf0},
+	{0x9f, 0xff},
+	{0xa0, 0x68},
+	{0xa1, 0x62},
+	{0xa2, 0x0e},
+};
+
+static struct msm_camera_i2c_reg_conf ov7692_full_settings[] = {
+	{0xcc, 0x02},
+	{0xcd, 0x80},
+	{0xce, 0x01},
+	{0xcf, 0xe0},
+	{0xc8, 0x02},
+	{0xc9, 0x80},
+	{0xca, 0x01},
+	{0xcb, 0xe0},
+};
+
+static struct v4l2_subdev_info ov7692_subdev_info[] = {
+	{
+		.code   = V4L2_MBUS_FMT_YUYV8_2X8,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.fmt    = 1,
+		.order    = 0,
+	},
+	/* more can be supported, to be added later */
+};
+
+
+static struct msm_camera_i2c_conf_array ov7692_init_conf[] = {
+	{&ov7692_recommend_settings[0],
+	ARRAY_SIZE(ov7692_recommend_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}
+};
+
+static struct msm_camera_i2c_conf_array ov7692_confs[] = {
+	{&ov7692_full_settings[0],
+	ARRAY_SIZE(ov7692_full_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+};
+
+static struct msm_camera_i2c_reg_conf ov7692_saturation[][4] = {
+	{{0x81, 0x33, 0x00, 0x00, 0xCC}, {0xd8, 0x00, 0x00, 0x00, 0x00},
+		{0xd9, 0x00, 0x00, 0x00, 0x00},
+		{0xd2, 0x02, 0x00, 0x00, 0x00},},/* SATURATION LEVEL0*/
+	{{0x81, 0x33, 0x00, 0x00, 0xCC}, {0xd8, 0x10, 0x00, 0x00, 0x00},
+		{0xd9, 0x10, 0x00, 0x00, 0x00},
+		{0xd2, 0x02, 0x00, 0x00, 0x00},},	/* SATURATION LEVEL1*/
+	{{0x81, 0x33, 0x00, 0x00, 0xCC}, {0xd8, 0x20, 0x00, 0x00, 0x00},
+		{0xd9, 0x20, 0x00, 0x00, 0x00},
+		{0xd2, 0x02, 0x00, 0x00, 0x00},},	/* SATURATION LEVEL2*/
+	{{0x81, 0x33, 0x00, 0x00, 0xCC}, {0xd8, 0x30, 0x00, 0x00, 0x00},
+		{0xd9, 0x30, 0x00, 0x00, 0x00},
+		{0xd2, 0x02, 0x00, 0x00, 0x00},},	/* SATURATION LEVEL3*/
+	{{0x81, 0x33, 0x00, 0x00, 0xCC}, {0xd8, 0x40, 0x00, 0x00, 0x00},
+		{0xd9, 0x40, 0x00, 0x00, 0x00},
+		{0xd2, 0x02, 0x00, 0x00, 0x00},},	/* SATURATION LEVEL4*/
+	{{0x81, 0x33, 0x00, 0x00, 0xCC}, {0xd8, 0x50, 0x00, 0x00, 0x00},
+		{0xd9, 0x50, 0x00, 0x00, 0x00},
+		{0xd2, 0x02, 0x00, 0x00, 0x00},},	/* SATURATION LEVEL5*/
+	{{0x81, 0x33, 0x00, 0x00, 0xCC}, {0xd8, 0x60, 0x00, 0x00, 0x00},
+		{0xd9, 0x60, 0x00, 0x00, 0x00},
+		{0xd2, 0x02, 0x00, 0x00, 0x00},},	/* SATURATION LEVEL6*/
+	{{0x81, 0x33, 0x00, 0x00, 0xCC}, {0xd8, 0x70, 0x00, 0x00, 0x00},
+		{0xd9, 0x70, 0x00, 0x00, 0x00},
+		{0xd2, 0x02, 0x00, 0x00, 0x00},},	/* SATURATION LEVEL7*/
+	{{0x81, 0x33, 0x00, 0x00, 0xCC}, {0xd8, 0x80, 0x00, 0x00, 0x00},
+		{0xd9, 0x80, 0x00, 0x00, 0x00},
+		{0xd2, 0x02, 0x00, 0x00, 0x00},},	/* SATURATION LEVEL8*/
+};
+static struct msm_camera_i2c_conf_array ov7692_saturation_confs[][1] = {
+	{{ov7692_saturation[0], ARRAY_SIZE(ov7692_saturation[0]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_saturation[1], ARRAY_SIZE(ov7692_saturation[1]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_saturation[2], ARRAY_SIZE(ov7692_saturation[2]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_saturation[3], ARRAY_SIZE(ov7692_saturation[3]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_saturation[4], ARRAY_SIZE(ov7692_saturation[4]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_saturation[5], ARRAY_SIZE(ov7692_saturation[5]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_saturation[6], ARRAY_SIZE(ov7692_saturation[6]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_saturation[7], ARRAY_SIZE(ov7692_saturation[7]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_saturation[8], ARRAY_SIZE(ov7692_saturation[8]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+};
+
+static int ov7692_saturation_enum_map[] = {
+	MSM_V4L2_SATURATION_L0,
+	MSM_V4L2_SATURATION_L1,
+	MSM_V4L2_SATURATION_L2,
+	MSM_V4L2_SATURATION_L3,
+	MSM_V4L2_SATURATION_L4,
+	MSM_V4L2_SATURATION_L5,
+	MSM_V4L2_SATURATION_L6,
+	MSM_V4L2_SATURATION_L7,
+	MSM_V4L2_SATURATION_L8,
+};
+static struct msm_sensor_output_info_t ov7692_dimensions[] = {
+	{
+		.x_output = 0x280,
+		.y_output = 0x1E0,
+		.line_length_pclk = 0x290,
+		.frame_length_lines = 0x1EC,
+		.vt_pixel_clk = 9216000,
+		.op_pixel_clk = 9216000,
+		.binning_factor = 1,
+	},
+};
+
+static struct msm_camera_i2c_enum_conf_array ov7692_saturation_enum_confs = {
+	.conf = &ov7692_saturation_confs[0][0],
+	.conf_enum = ov7692_saturation_enum_map,
+	.num_enum = ARRAY_SIZE(ov7692_saturation_enum_map),
+	.num_index = ARRAY_SIZE(ov7692_saturation_confs),
+	.num_conf = ARRAY_SIZE(ov7692_saturation_confs[0]),
+	.data_type = MSM_CAMERA_I2C_BYTE_DATA,
+};
+
+static struct msm_camera_i2c_reg_conf ov7692_contrast[][16] = {
+	{{0xb2, 0x29}, {0xa3, 0x55}, {0xa4, 0x5b}, {0xa5, 0x67}, {0xa6, 0x7e},
+		{0xa7, 0x89}, {0xa8, 0x93}, {0xa9, 0x9c}, {0xaa, 0xa4},
+		{0xab, 0xac}, {0xac, 0xb3}, {0xad, 0xbe}, {0xae, 0xc7},
+		{0xaf, 0xd5}, {0xb0, 0xdd}, {0xb1, 0xe1},},	/* CONTRAST L0*/
+	{{0xb2, 0x20}, {0xa3, 0x43}, {0xa4, 0x4a}, {0xa5, 0x58}, {0xa6, 0x73},
+		{0xa7, 0x80}, {0xa8, 0x8b}, {0xa9, 0x96}, {0xaa, 0x9f},
+		{0xab, 0xa8}, {0xac, 0xb1}, {0xad, 0xbe}, {0xae, 0xc9},
+		{0xaf, 0xd8}, {0xb0, 0xe2}, {0xb1, 0xe8},},	/* CONTRAST L1*/
+	{{0xb2, 0x18}, {0xa3, 0x31}, {0xa4, 0x39}, {0xa5, 0x4a}, {0xa6, 0x68},
+		{0xa7, 0x77}, {0xa8, 0x84}, {0xa9, 0x90}, {0xaa, 0x9b},
+		{0xab, 0xa5}, {0xac, 0xaf}, {0xad, 0xbe}, {0xae, 0xca},
+		{0xaf, 0xdc}, {0xb0, 0xe7}, {0xb1, 0xee},},	/* CONTRAST L2*/
+	{{0xb2, 0x10}, {0xa3, 0x1f}, {0xa4, 0x28}, {0xa5, 0x3b}, {0xa6, 0x5d},
+		{0xa7, 0x6e}, {0xa8, 0x7d}, {0xa9, 0x8a}, {0xaa, 0x96},
+		{0xab, 0xa2}, {0xac, 0xad}, {0xad, 0xbe}, {0xae, 0xcc},
+		{0xaf, 0xe0}, {0xb0, 0xed}, {0xb1, 0xf4},},	/* CONTRAST L3*/
+	 {{0xb2, 0x6}, {0xa3, 0xb}, {0xa4, 0x15}, {0xa5, 0x2a}, {0xa6, 0x51},
+		{0xa7, 0x63}, {0xa8, 0x74}, {0xa9, 0x83}, {0xaa, 0x91},
+		{0xab, 0x9e}, {0xac, 0xaa}, {0xad, 0xbe}, {0xae, 0xce},
+		{0xaf, 0xe5}, {0xb0, 0xf3}, {0xb1, 0xfb},},	/* CONTRAST L4*/
+	{{0xb2, 0xc}, {0xa3, 0x4}, {0xa4, 0xc}, {0xa5, 0x1f}, {0xa6, 0x45},
+		{0xa7, 0x58}, {0xa8, 0x6b}, {0xa9, 0x7c}, {0xaa, 0x8d},
+		{0xab, 0x9d}, {0xac, 0xac}, {0xad, 0xc3}, {0xae, 0xd2},
+		{0xaf, 0xe8}, {0xb0, 0xf2}, {0xb1, 0xf7},},	/* CONTRAST L5*/
+	{{0xb2, 0x1}, {0xa3, 0x2}, {0xa4, 0x9}, {0xa5, 0x1a}, {0xa6, 0x3e},
+		{0xa7, 0x4a}, {0xa8, 0x59}, {0xa9, 0x6a}, {0xaa, 0x79},
+		{0xab, 0x8e}, {0xac, 0xa4}, {0xad, 0xc1}, {0xae, 0xdb},
+		{0xaf, 0xf4}, {0xb0, 0xff}, {0xb1, 0xff},},	/* CONTRAST L6*/
+	{{0xb2, 0xc}, {0xa3, 0x4}, {0xa4, 0x8}, {0xa5, 0x17}, {0xa6, 0x27},
+		{0xa7, 0x3d}, {0xa8, 0x54}, {0xa9, 0x60}, {0xaa, 0x77},
+		{0xab, 0x85}, {0xac, 0xa4}, {0xad, 0xc6}, {0xae, 0xd2},
+		{0xaf, 0xe9}, {0xb0, 0xf0}, {0xb1, 0xf7},},	/* CONTRAST L7*/
+	{{0xb2, 0x1}, {0xa3, 0x4}, {0xa4, 0x4}, {0xa5, 0x7}, {0xa6, 0xb},
+		{0xa7, 0x17}, {0xa8, 0x2a}, {0xa9, 0x41}, {0xaa, 0x59},
+		{0xab, 0x6b}, {0xac, 0x8b}, {0xad, 0xb1}, {0xae, 0xd2},
+		{0xaf, 0xea}, {0xb0, 0xf4}, {0xb1, 0xff},},	/* CONTRAST L8*/
+};
+
+static struct msm_camera_i2c_conf_array ov7692_contrast_confs[][1] = {
+	{{ov7692_contrast[0], ARRAY_SIZE(ov7692_contrast[0]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_contrast[1], ARRAY_SIZE(ov7692_contrast[1]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_contrast[2], ARRAY_SIZE(ov7692_contrast[2]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_contrast[3], ARRAY_SIZE(ov7692_contrast[3]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_contrast[4], ARRAY_SIZE(ov7692_contrast[4]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_contrast[5], ARRAY_SIZE(ov7692_contrast[5]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_contrast[6], ARRAY_SIZE(ov7692_contrast[6]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_contrast[7], ARRAY_SIZE(ov7692_contrast[7]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_contrast[8], ARRAY_SIZE(ov7692_contrast[8]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+};
+
+
+static int ov7692_contrast_enum_map[] = {
+	MSM_V4L2_CONTRAST_L0,
+	MSM_V4L2_CONTRAST_L1,
+	MSM_V4L2_CONTRAST_L2,
+	MSM_V4L2_CONTRAST_L3,
+	MSM_V4L2_CONTRAST_L4,
+	MSM_V4L2_CONTRAST_L5,
+	MSM_V4L2_CONTRAST_L6,
+	MSM_V4L2_CONTRAST_L7,
+	MSM_V4L2_CONTRAST_L8,
+};
+
+static struct msm_camera_i2c_enum_conf_array ov7692_contrast_enum_confs = {
+	.conf = &ov7692_contrast_confs[0][0],
+	.conf_enum = ov7692_contrast_enum_map,
+	.num_enum = ARRAY_SIZE(ov7692_contrast_enum_map),
+	.num_index = ARRAY_SIZE(ov7692_contrast_confs),
+	.num_conf = ARRAY_SIZE(ov7692_contrast_confs[0]),
+	.data_type = MSM_CAMERA_I2C_BYTE_DATA,
+};
+static struct msm_camera_i2c_reg_conf ov7692_sharpness[][2] = {
+	{{0xb4, 0x20, 0x00, 0x00, 0xDF},
+		{0xb6, 0x00, 0x00, 0x00, 0xE0},},    /* SHARPNESS LEVEL 0*/
+	{{0xb4, 0x20, 0x00, 0x00, 0xDF},
+		{0xb6, 0x01, 0x00, 0x00, 0xE0},},    /* SHARPNESS LEVEL 1*/
+	{{0xb4, 0x00, 0x00, 0x00, 0xDF},
+		{0xb6, 0x00, 0x00, 0x00, 0xE0},},    /* SHARPNESS LEVEL 2*/
+	{{0xb4, 0x20, 0x00, 0x00, 0xDF},
+		{0xb6, 0x66, 0x00, 0x00, 0xE0},},    /* SHARPNESS LEVEL 3*/
+	{{0xb4, 0x20, 0x00, 0x00, 0xDF},
+		{0xb6, 0x99, 0x00, 0x00, 0xE0},},    /* SHARPNESS LEVEL 4*/
+	{{0xb4, 0x20, 0x00, 0x00, 0xDF},
+		{0xb6, 0xcc, 0x00, 0x00, 0xE0},},    /* SHARPNESS LEVEL 5*/
+};
+
+static struct msm_camera_i2c_conf_array ov7692_sharpness_confs[][1] = {
+	{{ov7692_sharpness[0], ARRAY_SIZE(ov7692_sharpness[0]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_sharpness[1], ARRAY_SIZE(ov7692_sharpness[1]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_sharpness[2], ARRAY_SIZE(ov7692_sharpness[2]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_sharpness[3], ARRAY_SIZE(ov7692_sharpness[3]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_sharpness[4], ARRAY_SIZE(ov7692_sharpness[4]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_sharpness[5], ARRAY_SIZE(ov7692_sharpness[5]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+};
+
+static int ov7692_sharpness_enum_map[] = {
+	MSM_V4L2_SHARPNESS_L0,
+	MSM_V4L2_SHARPNESS_L1,
+	MSM_V4L2_SHARPNESS_L2,
+	MSM_V4L2_SHARPNESS_L3,
+	MSM_V4L2_SHARPNESS_L4,
+	MSM_V4L2_SHARPNESS_L5,
+};
+
+static struct msm_camera_i2c_enum_conf_array ov7692_sharpness_enum_confs = {
+	.conf = &ov7692_sharpness_confs[0][0],
+	.conf_enum = ov7692_sharpness_enum_map,
+	.num_enum = ARRAY_SIZE(ov7692_sharpness_enum_map),
+	.num_index = ARRAY_SIZE(ov7692_sharpness_confs),
+	.num_conf = ARRAY_SIZE(ov7692_sharpness_confs[0]),
+	.data_type = MSM_CAMERA_I2C_BYTE_DATA,
+};
+
+static struct msm_camera_i2c_reg_conf ov7692_exposure[][3] = {
+	{{0x24, 0x50}, {0x25, 0x40}, {0x26, 0xa2},}, /*EXPOSURECOMPENSATIONN2*/
+	{{0x24, 0x70}, {0x25, 0x60}, {0x26, 0xa2},}, /*EXPOSURECOMPENSATIONN1*/
+	{{0x24, 0x86}, {0x25, 0x76}, {0x26, 0xb3},}, /*EXPOSURECOMPENSATIOND*/
+	{{0x24, 0xa8}, {0x25, 0xa0}, {0x26, 0xc4},}, /*EXPOSURECOMPENSATIONp1*/
+	{{0x24, 0xc0}, {0x25, 0xb8}, {0x26, 0xe6},}, /*EXPOSURECOMPENSATIONP2*/
+};
+
+static struct msm_camera_i2c_conf_array ov7692_exposure_confs[][1] = {
+	{{ov7692_exposure[0], ARRAY_SIZE(ov7692_exposure[0]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_exposure[1], ARRAY_SIZE(ov7692_exposure[1]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_exposure[2], ARRAY_SIZE(ov7692_exposure[2]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_exposure[3], ARRAY_SIZE(ov7692_exposure[3]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_exposure[4], ARRAY_SIZE(ov7692_exposure[4]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+};
+
+static int ov7692_exposure_enum_map[] = {
+	MSM_V4L2_EXPOSURE_N2,
+	MSM_V4L2_EXPOSURE_N1,
+	MSM_V4L2_EXPOSURE_D,
+	MSM_V4L2_EXPOSURE_P1,
+	MSM_V4L2_EXPOSURE_P2,
+};
+
+static struct msm_camera_i2c_enum_conf_array ov7692_exposure_enum_confs = {
+	.conf = &ov7692_exposure_confs[0][0],
+	.conf_enum = ov7692_exposure_enum_map,
+	.num_enum = ARRAY_SIZE(ov7692_exposure_enum_map),
+	.num_index = ARRAY_SIZE(ov7692_exposure_confs),
+	.num_conf = ARRAY_SIZE(ov7692_exposure_confs[0]),
+	.data_type = MSM_CAMERA_I2C_BYTE_DATA,
+};
+
+static struct msm_camera_i2c_reg_conf ov7692_iso[][1] = {
+	{{0x14, 0x20, 0x00, 0x00, 0x8F},},   /*ISO_AUTO*/
+	{{0x14, 0x20, 0x00, 0x00, 0x8F},},   /*ISO_DEBLUR*/
+	{{0x14, 0x00, 0x00, 0x00, 0x8F},},   /*ISO_100*/
+	{{0x14, 0x10, 0x00, 0x00, 0x8F},},   /*ISO_200*/
+	{{0x14, 0x20, 0x00, 0x00, 0x8F},},   /*ISO_400*/
+	{{0x14, 0x30, 0x00, 0x00, 0x8F},},   /*ISO_800*/
+	{{0x14, 0x40, 0x00, 0x00, 0x8F},},   /*ISO_1600*/
+};
+
+
+static struct msm_camera_i2c_conf_array ov7692_iso_confs[][1] = {
+	{{ov7692_iso[0], ARRAY_SIZE(ov7692_iso[0]),  0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_iso[1], ARRAY_SIZE(ov7692_iso[1]),  0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_iso[2], ARRAY_SIZE(ov7692_iso[2]),  0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_iso[3], ARRAY_SIZE(ov7692_iso[3]),  0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_iso[4], ARRAY_SIZE(ov7692_iso[4]),  0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_iso[5], ARRAY_SIZE(ov7692_iso[5]),  0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+};
+
+static int ov7692_iso_enum_map[] = {
+	MSM_V4L2_ISO_AUTO ,
+	MSM_V4L2_ISO_DEBLUR,
+	MSM_V4L2_ISO_100,
+	MSM_V4L2_ISO_200,
+	MSM_V4L2_ISO_400,
+	MSM_V4L2_ISO_800,
+	MSM_V4L2_ISO_1600,
+};
+
+
+static struct msm_camera_i2c_enum_conf_array ov7692_iso_enum_confs = {
+	.conf = &ov7692_iso_confs[0][0],
+	.conf_enum = ov7692_iso_enum_map,
+	.num_enum = ARRAY_SIZE(ov7692_iso_enum_map),
+	.num_index = ARRAY_SIZE(ov7692_iso_confs),
+	.num_conf = ARRAY_SIZE(ov7692_iso_confs[0]),
+	.data_type = MSM_CAMERA_I2C_BYTE_DATA,
+};
+
+static struct msm_camera_i2c_reg_conf ov7692_no_effect[] = {
+	{0x81, 0x00, 0x00, 0x00, 0xDF},
+	{0x28, 0x00,},
+	{0xd2, 0x00,},
+	{0xda, 0x80,},
+	{0xdb, 0x80,},
+};
+
+static struct msm_camera_i2c_conf_array ov7692_no_effect_confs[] = {
+	{&ov7692_no_effect[0],
+	ARRAY_SIZE(ov7692_no_effect), 0,
+	MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},
+};
+
+static struct msm_camera_i2c_reg_conf ov7692_special_effect[][5] = {
+	{{0x81, 0x20, 0x00, 0x00, 0xDF}, {0x28, 0x00,}, {0xd2, 0x18,},
+		{0xda, 0x80,}, {0xdb, 0x80,},},	/*for special effect OFF*/
+	{{0x81, 0x20, 0x00, 0x00, 0xDF}, {0x28, 0x00,}, {0xd2, 0x18,},
+		{0xda, 0x80,}, {0xdb, 0x80,},},	/*for special effect MONO*/
+	{{0x81, 0x20, 0x00, 0x00, 0xDF}, {0x28, 0x80,}, {0xd2, 0x40,},
+		{0xda, 0x80,}, {0xdb, 0x80,},},	/*for special efefct Negative*/
+	{{-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1},
+		{-1, -1, -1, -1, -1},
+		{-1, -1, -1, -1, -1},},/*Solarize is not supported by sensor*/
+	{{0x81, 0x20, 0x00, 0x00, 0xDF}, {0x28, 0x00,}, {0xd2, 0x18,},
+		{0xda, 0x40,}, {0xdb, 0xa0,},},	/*for sepia*/
+	{{-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1},
+		{-1, -1, -1, -1, -1},
+		{-1, -1, -1, -1, -1},},		/* Posteraize not supported */
+	{{-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1},
+		{-1, -1, -1, -1, -1},
+		{-1, -1, -1, -1, -1},},		/* White board not supported*/
+	{{-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1},
+		{-1, -1, -1, -1, -1},
+		{-1, -1, -1, -1, -1},},		/*Blackboard not supported*/
+	{{-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1},
+		{-1, -1, -1, -1, -1},
+		{-1, -1, -1, -1, -1},},		/*Aqua not supported*/
+	{{-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1},
+		{-1, -1, -1, -1, -1},
+		{-1, -1, -1, -1, -1},},		/*Emboss not supported */
+	{{-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1},
+		{-1, -1, -1, -1, -1},
+		{-1, -1, -1, -1, -1},},		/*sketch not supported*/
+	{{-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1},
+		{-1, -1, -1, -1, -1},
+		{-1, -1, -1, -1, -1},},		/*Neon not supported*/
+	{{-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1},
+		{-1, -1, -1, -1, -1},
+		{-1, -1, -1, -1, -1},},		/*MAX value*/
+};
+
+static struct msm_camera_i2c_conf_array ov7692_special_effect_confs[][1] = {
+	{{ov7692_special_effect[0],  ARRAY_SIZE(ov7692_special_effect[0]),  0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_special_effect[1],  ARRAY_SIZE(ov7692_special_effect[1]),  0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_special_effect[2],  ARRAY_SIZE(ov7692_special_effect[2]),  0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_special_effect[3],  ARRAY_SIZE(ov7692_special_effect[3]),  0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_special_effect[4],  ARRAY_SIZE(ov7692_special_effect[4]),  0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_special_effect[5],  ARRAY_SIZE(ov7692_special_effect[5]),  0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_special_effect[6],  ARRAY_SIZE(ov7692_special_effect[6]),  0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_special_effect[7],  ARRAY_SIZE(ov7692_special_effect[7]),  0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_special_effect[8],  ARRAY_SIZE(ov7692_special_effect[8]),  0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_special_effect[9],  ARRAY_SIZE(ov7692_special_effect[9]),  0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_special_effect[10], ARRAY_SIZE(ov7692_special_effect[10]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_special_effect[11], ARRAY_SIZE(ov7692_special_effect[11]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_special_effect[12], ARRAY_SIZE(ov7692_special_effect[12]), 0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+};
+
+static int ov7692_special_effect_enum_map[] = {
+	MSM_V4L2_EFFECT_OFF,
+	MSM_V4L2_EFFECT_MONO,
+	MSM_V4L2_EFFECT_NEGATIVE,
+	MSM_V4L2_EFFECT_SOLARIZE,
+	MSM_V4L2_EFFECT_SEPIA,
+	MSM_V4L2_EFFECT_POSTERAIZE,
+	MSM_V4L2_EFFECT_WHITEBOARD,
+	MSM_V4L2_EFFECT_BLACKBOARD,
+	MSM_V4L2_EFFECT_AQUA,
+	MSM_V4L2_EFFECT_EMBOSS,
+	MSM_V4L2_EFFECT_SKETCH,
+	MSM_V4L2_EFFECT_NEON,
+	MSM_V4L2_EFFECT_MAX,
+};
+
+static struct msm_camera_i2c_enum_conf_array
+		 ov7692_special_effect_enum_confs = {
+	.conf = &ov7692_special_effect_confs[0][0],
+	.conf_enum = ov7692_special_effect_enum_map,
+	.num_enum = ARRAY_SIZE(ov7692_special_effect_enum_map),
+	.num_index = ARRAY_SIZE(ov7692_special_effect_confs),
+	.num_conf = ARRAY_SIZE(ov7692_special_effect_confs[0]),
+	.data_type = MSM_CAMERA_I2C_BYTE_DATA,
+};
+
+static struct msm_camera_i2c_reg_conf ov7692_antibanding[][2] = {
+	{{0x13, 0x20, 0x00, 0x00, 0xDF},
+		{0x14, 0x16, 0x00, 0x00, 0xE8},},   /*ANTIBANDING 60HZ*/
+	{{0x13, 0x20, 0x00, 0x00, 0xDF},
+		{0x14, 0x17, 0x00, 0x00, 0xE8},},   /*ANTIBANDING 50HZ*/
+	{{0x13, 0x20, 0x00, 0x00, 0xDF},
+		{0x14, 0x14, 0x00, 0x00, 0xE8},},   /* ANTIBANDING AUTO*/
+};
+
+
+static struct msm_camera_i2c_conf_array ov7692_antibanding_confs[][1] = {
+	{{ov7692_antibanding[0], ARRAY_SIZE(ov7692_antibanding[0]),  0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_antibanding[1], ARRAY_SIZE(ov7692_antibanding[1]),  0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_antibanding[2], ARRAY_SIZE(ov7692_antibanding[2]),  0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+};
+
+static int ov7692_antibanding_enum_map[] = {
+	MSM_V4L2_POWER_LINE_60HZ,
+	MSM_V4L2_POWER_LINE_50HZ,
+	MSM_V4L2_POWER_LINE_AUTO,
+};
+
+
+static struct msm_camera_i2c_enum_conf_array ov7692_antibanding_enum_confs = {
+	.conf = &ov7692_antibanding_confs[0][0],
+	.conf_enum = ov7692_antibanding_enum_map,
+	.num_enum = ARRAY_SIZE(ov7692_antibanding_enum_map),
+	.num_index = ARRAY_SIZE(ov7692_antibanding_confs),
+	.num_conf = ARRAY_SIZE(ov7692_antibanding_confs[0]),
+	.data_type = MSM_CAMERA_I2C_BYTE_DATA,
+};
+
+static struct msm_camera_i2c_reg_conf ov7692_wb_oem[][4] = {
+	{{-1, -1, -1, -1 , -1}, {-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1},
+		{-1, -1, -1, -1, -1},},/*WHITEBALNACE OFF*/
+	{{0x13, 0xf7}, {0x15, 0x00}, {-1, -1, -1, -1, -1},
+		{-1, -1, -1, -1, -1},}, /*WHITEBALNACE AUTO*/
+	{{0x13, 0xf5}, {0x01, 0x56}, {0x02, 0x50},
+		{0x15, 0x00},},	/*WHITEBALNACE CUSTOM*/
+	{{0x13, 0xf5}, {0x01, 0x66}, {0x02, 0x40},
+		{0x15, 0x00},},	/*INCANDISCENT*/
+	{{-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1},
+		{-1, -1, -1, -1, -1},},	/*FLOURESECT NOT SUPPORTED */
+	{{0x13, 0xf5}, {0x01, 0x43}, {0x02, 0x5d},
+		{0x15, 0x00},},	/*DAYLIGHT*/
+	{{0x13, 0xf5}, {0x01, 0x48}, {0x02, 0x63},
+		{0x15, 0x00},},	/*CLOUDY*/
+};
+
+static struct msm_camera_i2c_conf_array ov7692_wb_oem_confs[][1] = {
+	{{ov7692_wb_oem[0], ARRAY_SIZE(ov7692_wb_oem[0]),  0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_wb_oem[1], ARRAY_SIZE(ov7692_wb_oem[1]),  0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_wb_oem[2], ARRAY_SIZE(ov7692_wb_oem[2]),  0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_wb_oem[3], ARRAY_SIZE(ov7692_wb_oem[3]),  0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_wb_oem[4], ARRAY_SIZE(ov7692_wb_oem[4]),  0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_wb_oem[5], ARRAY_SIZE(ov7692_wb_oem[5]),  0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+	{{ov7692_wb_oem[6], ARRAY_SIZE(ov7692_wb_oem[6]),  0,
+		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
+};
+
+static int ov7692_wb_oem_enum_map[] = {
+	MSM_V4L2_WB_OFF,
+	MSM_V4L2_WB_AUTO ,
+	MSM_V4L2_WB_CUSTOM,
+	MSM_V4L2_WB_INCANDESCENT,
+	MSM_V4L2_WB_FLUORESCENT,
+	MSM_V4L2_WB_DAYLIGHT,
+	MSM_V4L2_WB_CLOUDY_DAYLIGHT,
+};
+
+static struct msm_camera_i2c_enum_conf_array ov7692_wb_oem_enum_confs = {
+	.conf = &ov7692_wb_oem_confs[0][0],
+	.conf_enum = ov7692_wb_oem_enum_map,
+	.num_enum = ARRAY_SIZE(ov7692_wb_oem_enum_map),
+	.num_index = ARRAY_SIZE(ov7692_wb_oem_confs),
+	.num_conf = ARRAY_SIZE(ov7692_wb_oem_confs[0]),
+	.data_type = MSM_CAMERA_I2C_BYTE_DATA,
+};
+
+
+int ov7692_saturation_msm_sensor_s_ctrl_by_enum(
+		struct msm_sensor_ctrl_t *s_ctrl,
+		struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value)
+{
+	int rc = 0;
+	if (effect_value == CAMERA_EFFECT_OFF) {
+		rc = msm_sensor_write_enum_conf_array(
+			s_ctrl->sensor_i2c_client,
+			ctrl_info->enum_cfg_settings, value);
+	}
+	if (value <= MSM_V4L2_SATURATION_L8)
+		SAT_U = SAT_V = value * 0x10;
+	CDBG("--CAMERA-- %s ...(End)\n", __func__);
+	return rc;
+}
+
+
+int ov7692_contrast_msm_sensor_s_ctrl_by_enum(
+		struct msm_sensor_ctrl_t *s_ctrl,
+		struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value)
+{
+	int rc = 0;
+	if (effect_value == CAMERA_EFFECT_OFF) {
+		rc = msm_sensor_write_enum_conf_array(
+			s_ctrl->sensor_i2c_client,
+			ctrl_info->enum_cfg_settings, value);
+	}
+	return rc;
+}
+
+int ov7692_sharpness_msm_sensor_s_ctrl_by_enum(
+		struct msm_sensor_ctrl_t *s_ctrl,
+		struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value)
+{
+	int rc = 0;
+	if (effect_value == CAMERA_EFFECT_OFF) {
+		rc = msm_sensor_write_enum_conf_array(
+			s_ctrl->sensor_i2c_client,
+			ctrl_info->enum_cfg_settings, value);
+	}
+	return rc;
+}
+
+int ov7692_effect_msm_sensor_s_ctrl_by_enum(struct msm_sensor_ctrl_t *s_ctrl,
+		struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value)
+{
+	int rc = 0;
+	effect_value = value;
+	if (effect_value == CAMERA_EFFECT_OFF) {
+		rc = msm_sensor_write_conf_array(
+			s_ctrl->sensor_i2c_client,
+			s_ctrl->msm_sensor_reg->no_effect_settings, 0);
+		if (rc < 0) {
+			CDBG("write faield\n");
+			return rc;
+		}
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0xda, SAT_U,
+			MSM_CAMERA_I2C_BYTE_DATA);
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0xdb, SAT_V,
+			MSM_CAMERA_I2C_BYTE_DATA);
+	} else {
+		rc = msm_sensor_write_enum_conf_array(
+			s_ctrl->sensor_i2c_client,
+			ctrl_info->enum_cfg_settings, value);
+	}
+	return rc;
+}
+
+int ov7692_antibanding_msm_sensor_s_ctrl_by_enum(
+		struct msm_sensor_ctrl_t *s_ctrl,
+		struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value)
+{
+	int rc = 0;
+		return rc;
+}
+
+int ov7692_msm_sensor_s_ctrl_by_enum(struct msm_sensor_ctrl_t *s_ctrl,
+		struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value)
+{
+	int rc = 0;
+	rc = msm_sensor_write_enum_conf_array(
+		s_ctrl->sensor_i2c_client,
+		ctrl_info->enum_cfg_settings, value);
+	if (rc < 0) {
+		CDBG("write faield\n");
+		return rc;
+	}
+	return rc;
+}
+
+struct msm_sensor_v4l2_ctrl_info_t ov7692_v4l2_ctrl_info[] = {
+	{
+		.ctrl_id = V4L2_CID_SATURATION,
+		.min = MSM_V4L2_SATURATION_L0,
+		.max = MSM_V4L2_SATURATION_L8,
+		.step = 1,
+		.enum_cfg_settings = &ov7692_saturation_enum_confs,
+		.s_v4l2_ctrl = ov7692_saturation_msm_sensor_s_ctrl_by_enum,
+	},
+	{
+		.ctrl_id = V4L2_CID_CONTRAST,
+		.min = MSM_V4L2_CONTRAST_L0,
+		.max = MSM_V4L2_CONTRAST_L8,
+		.step = 1,
+		.enum_cfg_settings = &ov7692_contrast_enum_confs,
+		.s_v4l2_ctrl = ov7692_contrast_msm_sensor_s_ctrl_by_enum,
+	},
+	{
+		.ctrl_id = V4L2_CID_SHARPNESS,
+		.min = MSM_V4L2_SHARPNESS_L0,
+		.max = MSM_V4L2_SHARPNESS_L5,
+		.step = 1,
+		.enum_cfg_settings = &ov7692_sharpness_enum_confs,
+		.s_v4l2_ctrl = ov7692_sharpness_msm_sensor_s_ctrl_by_enum,
+	},
+	{
+		.ctrl_id = V4L2_CID_EXPOSURE,
+		.min = MSM_V4L2_EXPOSURE_N2,
+		.max = MSM_V4L2_EXPOSURE_P2,
+		.step = 1,
+		.enum_cfg_settings = &ov7692_exposure_enum_confs,
+		.s_v4l2_ctrl = ov7692_msm_sensor_s_ctrl_by_enum,
+	},
+	{
+		.ctrl_id = MSM_V4L2_PID_ISO,
+		.min = MSM_V4L2_ISO_AUTO,
+		.max = MSM_V4L2_ISO_1600,
+		.step = 1,
+		.enum_cfg_settings = &ov7692_iso_enum_confs,
+		.s_v4l2_ctrl = ov7692_msm_sensor_s_ctrl_by_enum,
+	},
+	{
+		.ctrl_id = V4L2_CID_SPECIAL_EFFECT,
+		.min = MSM_V4L2_EFFECT_OFF,
+		.max = MSM_V4L2_EFFECT_NEGATIVE,
+		.step = 1,
+		.enum_cfg_settings = &ov7692_special_effect_enum_confs,
+		.s_v4l2_ctrl = ov7692_effect_msm_sensor_s_ctrl_by_enum,
+	},
+	{
+		.ctrl_id = V4L2_CID_POWER_LINE_FREQUENCY,
+		.min = MSM_V4L2_POWER_LINE_60HZ,
+		.max = MSM_V4L2_POWER_LINE_AUTO,
+		.step = 1,
+		.enum_cfg_settings = &ov7692_antibanding_enum_confs,
+		.s_v4l2_ctrl = ov7692_antibanding_msm_sensor_s_ctrl_by_enum,
+	},
+	{
+		.ctrl_id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
+		.min = MSM_V4L2_WB_OFF,
+		.max = MSM_V4L2_WB_CLOUDY_DAYLIGHT,
+		.step = 1,
+		.enum_cfg_settings = &ov7692_wb_oem_enum_confs,
+		.s_v4l2_ctrl = ov7692_msm_sensor_s_ctrl_by_enum,
+	},
+
+};
+
+static struct msm_sensor_output_reg_addr_t ov7692_reg_addr = {
+	.x_output = 0xCC,
+	.y_output = 0xCE,
+	.line_length_pclk = 0xC8,
+	.frame_length_lines = 0xCA,
+};
+
+static struct msm_sensor_id_info_t ov7692_id_info = {
+	.sensor_id_reg_addr = 0x0A,
+	.sensor_id = 0x7692,
+};
+
+static const struct i2c_device_id ov7692_i2c_id[] = {
+	{SENSOR_NAME, (kernel_ulong_t)&ov7692_s_ctrl},
+	{ }
+};
+
+
+static struct i2c_driver ov7692_i2c_driver = {
+	.id_table = ov7692_i2c_id,
+	.probe  = msm_sensor_i2c_probe,
+	.driver = {
+		.name = SENSOR_NAME,
+	},
+};
+
+static struct msm_camera_i2c_client ov7692_sensor_i2c_client = {
+	.addr_type = MSM_CAMERA_I2C_BYTE_ADDR,
+};
+
+static int __init msm_sensor_init_module(void)
+{
+	int rc = 0;
+	CDBG("OV7692\n");
+
+	rc = i2c_add_driver(&ov7692_i2c_driver);
+
+	return rc;
+}
+
+static struct v4l2_subdev_core_ops ov7692_subdev_core_ops = {
+	.s_ctrl = msm_sensor_v4l2_s_ctrl,
+	.queryctrl = msm_sensor_v4l2_query_ctrl,
+	.ioctl = msm_sensor_subdev_ioctl,
+	.s_power = msm_sensor_power,
+};
+
+static struct v4l2_subdev_video_ops ov7692_subdev_video_ops = {
+	.enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
+};
+
+static struct v4l2_subdev_ops ov7692_subdev_ops = {
+	.core = &ov7692_subdev_core_ops,
+	.video  = &ov7692_subdev_video_ops,
+};
+
+static struct msm_sensor_fn_t ov7692_func_tbl = {
+	.sensor_start_stream = msm_sensor_start_stream,
+	.sensor_stop_stream = msm_sensor_stop_stream,
+	.sensor_csi_setting = msm_sensor_setting1,
+	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
+	.sensor_mode_init = msm_sensor_mode_init,
+	.sensor_get_output_info = msm_sensor_get_output_info,
+	.sensor_config = msm_sensor_config,
+	.sensor_power_up = msm_sensor_power_up,
+	.sensor_power_down = msm_sensor_power_down,
+};
+
+static struct msm_sensor_reg_t ov7692_regs = {
+	.default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
+	.start_stream_conf = ov7692_start_settings,
+	.start_stream_conf_size = ARRAY_SIZE(ov7692_start_settings),
+	.stop_stream_conf = ov7692_stop_settings,
+	.stop_stream_conf_size = ARRAY_SIZE(ov7692_stop_settings),
+	.init_settings = &ov7692_init_conf[0],
+	.init_size = ARRAY_SIZE(ov7692_init_conf),
+	.mode_settings = &ov7692_confs[0],
+	.no_effect_settings = &ov7692_no_effect_confs[0],
+	.output_settings = &ov7692_dimensions[0],
+	.num_conf = ARRAY_SIZE(ov7692_confs),
+};
+
+static struct msm_sensor_ctrl_t ov7692_s_ctrl = {
+	.msm_sensor_reg = &ov7692_regs,
+	.msm_sensor_v4l2_ctrl_info = ov7692_v4l2_ctrl_info,
+	.num_v4l2_ctrl = ARRAY_SIZE(ov7692_v4l2_ctrl_info),
+	.sensor_i2c_client = &ov7692_sensor_i2c_client,
+	.sensor_i2c_addr = 0x78,
+	.sensor_output_reg_addr = &ov7692_reg_addr,
+	.sensor_id_info = &ov7692_id_info,
+	.cam_mode = MSM_SENSOR_MODE_INVALID,
+	.msm_sensor_mutex = &ov7692_mut,
+	.sensor_i2c_driver = &ov7692_i2c_driver,
+	.sensor_v4l2_subdev_info = ov7692_subdev_info,
+	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(ov7692_subdev_info),
+	.sensor_v4l2_subdev_ops = &ov7692_subdev_ops,
+	.func_tbl = &ov7692_func_tbl,
+	.clk_rate = MSM_SENSOR_MCLK_24HZ,
+};
+
+module_init(msm_sensor_init_module);
+MODULE_DESCRIPTION("Omnivision VGA YUV sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/sensors/ov8825_v4l2.c b/drivers/media/platform/msm/camera_v1/sensors/ov8825_v4l2.c
new file mode 100644
index 0000000..ddf4619
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/sensors/ov8825_v4l2.c
@@ -0,0 +1,937 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_sensor.h"
+#include "msm.h"
+#define SENSOR_NAME "ov8825"
+#define PLATFORM_DRIVER_NAME "msm_camera_ov8825"
+#define ov8825_obj ov8825_##obj
+
+/* TO DO - Currently ov5647 typical values are used
+ * Need to get the exact values */
+#define OV8825_RG_RATIO_TYPICAL_VALUE 64 /* R/G of typical camera module */
+#define OV8825_BG_RATIO_TYPICAL_VALUE 105 /* B/G of typical camera module */
+
+DEFINE_MUTEX(ov8825_mut);
+static struct msm_sensor_ctrl_t ov8825_s_ctrl;
+
+struct otp_struct {
+	uint8_t customer_id;
+	uint8_t module_integrator_id;
+	uint8_t lens_id;
+	uint8_t rg_ratio;
+	uint8_t bg_ratio;
+	uint8_t user_data[5];
+} st_ov8825_otp;
+
+static struct msm_camera_i2c_reg_conf ov8825_start_settings[] = {
+	{0x0100, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf ov8825_stop_settings[] = {
+	{0x0100, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf ov8825_groupon_settings[] = {
+	{0x3208, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf ov8825_groupoff_settings[] = {
+	{0x3208, 0x10},
+	{0x3208, 0xA0},
+};
+
+static struct msm_camera_i2c_reg_conf ov8825_prev_settings[] = {
+	{0x3003, 0xce}, /*PLL_CTRL0*/
+	{0x3004, 0xd4}, /*PLL_CTRL1*/
+	{0x3005, 0x00}, /*PLL_CTRL2*/
+	{0x3006, 0x10}, /*PLL_CTRL3*/
+	{0x3007, 0x3b}, /*PLL_CTRL4*/
+	{0x3011, 0x01}, /*MIPI_Lane_4_Lane*/
+	{0x3012, 0x80}, /*SC_PLL CTRL_S0*/
+	{0x3013, 0x39}, /*SC_PLL CTRL_S1*/
+	{0x3104, 0x20}, /*SCCB_PLL*/
+	{0x3106, 0x15}, /*SRB_CTRL*/
+	{0x3501, 0x4e}, /*AEC_HIGH*/
+	{0x3502, 0xa0}, /*AEC_LOW*/
+	{0x350b, 0x1f}, /*AGC*/
+	{0x3600, 0x06}, /*ANACTRL0*/
+	{0x3601, 0x34}, /*ANACTRL1*/
+	{0x3700, 0x20}, /*SENCTROL0 Sensor control*/
+	{0x3702, 0x50}, /*SENCTROL2 Sensor control*/
+	{0x3703, 0xcc}, /*SENCTROL3 Sensor control*/
+	{0x3704, 0x19}, /*SENCTROL4 Sensor control*/
+	{0x3705, 0x14}, /*SENCTROL5 Sensor control*/
+	{0x3706, 0x4b}, /*SENCTROL6 Sensor control*/
+	{0x3707, 0x63}, /*SENCTROL7 Sensor control*/
+	{0x3708, 0x84}, /*SENCTROL8 Sensor control*/
+	{0x3709, 0x40}, /*SENCTROL9 Sensor control*/
+	{0x370a, 0x12}, /*SENCTROLA Sensor control*/
+	{0x370e, 0x00}, /*SENCTROLE Sensor control*/
+	{0x3711, 0x0f}, /*SENCTROL11 Sensor control*/
+	{0x3712, 0x9c}, /*SENCTROL12 Sensor control*/
+	{0x3724, 0x01}, /*Reserved*/
+	{0x3725, 0x92}, /*Reserved*/
+	{0x3726, 0x01}, /*Reserved*/
+	{0x3727, 0xa9}, /*Reserved*/
+	{0x3800, 0x00}, /*HS(HREF start High)*/
+	{0x3801, 0x00}, /*HS(HREF start Low)*/
+	{0x3802, 0x00}, /*VS(Vertical start High)*/
+	{0x3803, 0x00}, /*VS(Vertical start Low)*/
+	{0x3804, 0x0c}, /*HW = 3295*/
+	{0x3805, 0xdf}, /*HW*/
+	{0x3806, 0x09}, /*VH = 2459*/
+	{0x3807, 0x9b}, /*VH*/
+	{0x3808, 0x06}, /*ISPHO = 1632*/
+	{0x3809, 0x60}, /*ISPHO*/
+	{0x380a, 0x04}, /*ISPVO = 1224*/
+	{0x380b, 0xc8}, /*ISPVO*/
+	{0x380c, 0x0d}, /*HTS = 3516*/
+	{0x380d, 0xbc}, /*HTS*/
+	{0x380e, 0x04}, /*VTS = 1264*/
+	{0x380f, 0xf0}, /*VTS*/
+	{0x3810, 0x00}, /*HOFF = 8*/
+	{0x3811, 0x08}, /*HOFF*/
+	{0x3812, 0x00}, /*VOFF = 4*/
+	{0x3813, 0x04}, /*VOFF*/
+	{0x3814, 0x31}, /*X INC*/
+	{0x3815, 0x31}, /*Y INC*/
+	{0x3820, 0x81}, /*Timing Reg20:Vflip*/
+	{0x3821, 0x17}, /*Timing Reg21:Hmirror*/
+	{0x3f00, 0x00}, /*PSRAM Ctrl0*/
+	{0x3f01, 0xfc}, /*PSRAM Ctrl1*/
+	{0x3f05, 0x10}, /*PSRAM Ctrl5*/
+	{0x4600, 0x04}, /*VFIFO Ctrl0*/
+	{0x4601, 0x00}, /*VFIFO Read ST High*/
+	{0x4602, 0x30}, /*VFIFO Read ST Low*/
+	{0x4837, 0x28}, /*MIPI PCLK PERIOD*/
+	{0x5068, 0x00}, /*HSCALE_CTRL*/
+	{0x506a, 0x00}, /*VSCALE_CTRL*/
+	{0x5c00, 0x80}, /*PBLC CTRL00*/
+	{0x5c01, 0x00}, /*PBLC CTRL01*/
+	{0x5c02, 0x00}, /*PBLC CTRL02*/
+	{0x5c03, 0x00}, /*PBLC CTRL03*/
+	{0x5c04, 0x00}, /*PBLC CTRL04*/
+	{0x5c08, 0x10}, /*PBLC CTRL08*/
+	{0x6900, 0x61}, /*CADC CTRL00*/
+};
+
+static struct msm_camera_i2c_reg_conf ov8825_snap_settings[] = {
+	{0x3003, 0xce}, /*PLL_CTRL0*/
+	{0x3004, 0xd8}, /*PLL_CTRL1*/
+	{0x3005, 0x00}, /*PLL_CTRL2*/
+	{0x3006, 0x10}, /*PLL_CTRL3*/
+	{0x3007, 0x3b}, /*PLL_CTRL4*/
+	{0x3011, 0x01}, /*MIPI_Lane_4_Lane*/
+	{0x3012, 0x81}, /*SC_PLL CTRL_S0*/
+	{0x3013, 0x39}, /*SC_PLL CTRL_S1*/
+	{0x3104, 0x20}, /*SCCB_PLL*/
+	{0x3106, 0x11}, /*SRB_CTRL*/
+	{0x3501, 0x9a}, /*AEC_HIGH*/
+	{0x3502, 0xa0}, /*AEC_LOW*/
+	{0x350b, 0x1f}, /*AGC*/
+	{0x3600, 0x07}, /*ANACTRL0*/
+	{0x3601, 0x33}, /*ANACTRL1*/
+	{0x3700, 0x10}, /*SENCTROL0 Sensor control*/
+	{0x3702, 0x28}, /*SENCTROL2 Sensor control*/
+	{0x3703, 0x6c}, /*SENCTROL3 Sensor control*/
+	{0x3704, 0x8d}, /*SENCTROL4 Sensor control*/
+	{0x3705, 0x0a}, /*SENCTROL5 Sensor control*/
+	{0x3706, 0x27}, /*SENCTROL6 Sensor control*/
+	{0x3707, 0x63}, /*SENCTROL7 Sensor control*/
+	{0x3708, 0x40}, /*SENCTROL8 Sensor control*/
+	{0x3709, 0x20}, /*SENCTROL9 Sensor control*/
+	{0x370a, 0x12}, /*SENCTROLA Sensor control*/
+	{0x370e, 0x00}, /*SENCTROLE Sensor control*/
+	{0x3711, 0x07}, /*SENCTROL11 Sensor control*/
+	{0x3712, 0x4e}, /*SENCTROL12 Sensor control*/
+	{0x3724, 0x00}, /*Reserved*/
+	{0x3725, 0xd4}, /*Reserved*/
+	{0x3726, 0x00}, /*Reserved*/
+	{0x3727, 0xe1}, /*Reserved*/
+	{0x3800, 0x00}, /*HS(HREF start High)*/
+	{0x3801, 0x00}, /*HS(HREF start Low)*/
+	{0x3802, 0x00}, /*VS(Vertical start Hgh)*/
+	{0x3803, 0x00}, /*VS(Vertical start Low)*/
+	{0x3804, 0x0c}, /*HW = 3295*/
+	{0x3805, 0xdf}, /*HW*/
+	{0x3806, 0x09}, /*VH = 2459*/
+	{0x3807, 0x9b}, /*VH*/
+	{0x3808, 0x0c}, /*ISPHO = 1632*/
+	{0x3809, 0xc0}, /*ISPHO*/
+	{0x380a, 0x09}, /*ISPVO = 1224*/
+	{0x380b, 0x90}, /*ISPVO*/
+	{0x380c, 0x0e}, /*HTS = 3516*/
+	{0x380d, 0x00}, /*HTS*/
+	{0x380e, 0x09}, /*VTS = 1264*/
+	{0x380f, 0xb0}, /*VTS*/
+	{0x3810, 0x00}, /*HOFF = 8*/
+	{0x3811, 0x10}, /*HOFF*/
+	{0x3812, 0x00}, /*VOFF = 4*/
+	{0x3813, 0x06}, /*VOFF*/
+	{0x3814, 0x11}, /*X INC*/
+	{0x3815, 0x11}, /*Y INC*/
+	{0x3820, 0x80}, /*Timing Reg20:Vflip*/
+	{0x3821, 0x16}, /*Timing Reg21:Hmirror*/
+	{0x3f00, 0x02}, /*PSRAM Ctrl0*/
+	{0x3f01, 0xfc}, /*PSRAM Ctrl1*/
+	{0x3f05, 0x10}, /*PSRAM Ctrl5*/
+	{0x4600, 0x04}, /*VFIFO Ctrl0*/
+	{0x4601, 0x00}, /*VFIFO Read ST High*/
+	{0x4602, 0x78}, /*VFIFO Read ST Low*/
+	{0x4837, 0x28}, /*MIPI PCLK PERIOD*/
+	{0x5068, 0x00}, /*HSCALE_CTRL*/
+	{0x506a, 0x00}, /*VSCALE_CTRL*/
+	{0x5c00, 0x80}, /*PBLC CTRL00*/
+	{0x5c01, 0x00}, /*PBLC CTRL01*/
+	{0x5c02, 0x00}, /*PBLC CTRL02*/
+	{0x5c03, 0x00}, /*PBLC CTRL03*/
+	{0x5c04, 0x00}, /*PBLC CTRL04*/
+	{0x5c08, 0x10}, /*PBLC CTRL08*/
+	{0x6900, 0x61}, /*CADC CTRL00*/
+};
+
+
+static struct msm_camera_i2c_reg_conf ov8825_reset_settings[] = {
+	{0x0103, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf ov8825_recommend_settings[] = {
+	{0x3000, 0x16},
+	{0x3001, 0x00},
+	{0x3002, 0x6c},
+	{0x300d, 0x00},
+	{0x301f, 0x09},
+	{0x3010, 0x00},
+	{0x3018, 0x00},
+	{0x3300, 0x00},
+	{0x3500, 0x00},
+	{0x3503, 0x07},
+	{0x3509, 0x00},
+	{0x3602, 0x42},
+	{0x3603, 0x5c},
+	{0x3604, 0x98},
+	{0x3605, 0xf5},
+	{0x3609, 0xb4},
+	{0x360a, 0x7c},
+	{0x360b, 0xc9},
+	{0x360c, 0x0b},
+	{0x3612, 0x00},
+	{0x3613, 0x02},
+	{0x3614, 0x0f},
+	{0x3615, 0x00},
+	{0x3616, 0x03},
+	{0x3617, 0xa1},
+	{0x3618, 0x00},
+	{0x3619, 0x00},
+	{0x361a, 0xB0},
+	{0x361b, 0x04},
+	{0x361c, 0x07},
+	{0x3701, 0x44},
+	{0x370b, 0x01},
+	{0x370c, 0x50},
+	{0x370d, 0x00},
+	{0x3816, 0x02},
+	{0x3817, 0x40},
+	{0x3818, 0x00},
+	{0x3819, 0x40},
+	{0x3b1f, 0x00},
+	{0x3d00, 0x00},
+	{0x3d01, 0x00},
+	{0x3d02, 0x00},
+	{0x3d03, 0x00},
+	{0x3d04, 0x00},
+	{0x3d05, 0x00},
+	{0x3d06, 0x00},
+	{0x3d07, 0x00},
+	{0x3d08, 0x00},
+	{0x3d09, 0x00},
+	{0x3d0a, 0x00},
+	{0x3d0b, 0x00},
+	{0x3d0c, 0x00},
+	{0x3d0d, 0x00},
+	{0x3d0e, 0x00},
+	{0x3d0f, 0x00},
+	{0x3d10, 0x00},
+	{0x3d11, 0x00},
+	{0x3d12, 0x00},
+	{0x3d13, 0x00},
+	{0x3d14, 0x00},
+	{0x3d15, 0x00},
+	{0x3d16, 0x00},
+	{0x3d17, 0x00},
+	{0x3d18, 0x00},
+	{0x3d19, 0x00},
+	{0x3d1a, 0x00},
+	{0x3d1b, 0x00},
+	{0x3d1c, 0x00},
+	{0x3d1d, 0x00},
+	{0x3d1e, 0x00},
+	{0x3d1f, 0x00},
+	{0x3d80, 0x00},
+	{0x3d81, 0x00},
+	{0x3d84, 0x00},
+	{0x3f06, 0x00},
+	{0x3f07, 0x00},
+	{0x4000, 0x29},
+	{0x4001, 0x02},
+	{0x4002, 0x45},
+	{0x4003, 0x08},
+	{0x4004, 0x04},
+	{0x4005, 0x18},
+	{0x4300, 0xff},
+	{0x4303, 0x00},
+	{0x4304, 0x08},
+	{0x4307, 0x00},
+	{0x4800, 0x04},
+	{0x4801, 0x0f},
+	{0x4843, 0x02},
+	{0x5000, 0x06},
+	{0x5001, 0x00},
+	{0x5002, 0x00},
+	{0x501f, 0x00},
+	{0x5780, 0xfc},
+	{0x5c05, 0x00},
+	{0x5c06, 0x00},
+	{0x5c07, 0x80},
+	{0x6700, 0x05},
+	{0x6701, 0x19},
+	{0x6702, 0xfd},
+	{0x6703, 0xd7},
+	{0x6704, 0xff},
+	{0x6705, 0xff},
+	{0x6800, 0x10},
+	{0x6801, 0x02},
+	{0x6802, 0x90},
+	{0x6803, 0x10},
+	{0x6804, 0x59},
+	{0x6901, 0x04},
+	{0x5800, 0x0f},
+	{0x5801, 0x0d},
+	{0x5802, 0x09},
+	{0x5803, 0x0a},
+	{0x5804, 0x0d},
+	{0x5805, 0x14},
+	{0x5806, 0x0a},
+	{0x5807, 0x04},
+	{0x5808, 0x03},
+	{0x5809, 0x03},
+	{0x580a, 0x05},
+	{0x580b, 0x0a},
+	{0x580c, 0x05},
+	{0x580d, 0x02},
+	{0x580e, 0x00},
+	{0x580f, 0x00},
+	{0x5810, 0x03},
+	{0x5811, 0x05},
+	{0x5812, 0x09},
+	{0x5813, 0x03},
+	{0x5814, 0x01},
+	{0x5815, 0x01},
+	{0x5816, 0x04},
+	{0x5817, 0x09},
+	{0x5818, 0x09},
+	{0x5819, 0x08},
+	{0x581a, 0x06},
+	{0x581b, 0x06},
+	{0x581c, 0x08},
+	{0x581d, 0x06},
+	{0x581e, 0x33},
+	{0x581f, 0x11},
+	{0x5820, 0x0e},
+	{0x5821, 0x0f},
+	{0x5822, 0x11},
+	{0x5823, 0x3f},
+	{0x5824, 0x08},
+	{0x5825, 0x46},
+	{0x5826, 0x46},
+	{0x5827, 0x46},
+	{0x5828, 0x46},
+	{0x5829, 0x46},
+	{0x582a, 0x42},
+	{0x582b, 0x42},
+	{0x582c, 0x44},
+	{0x582d, 0x46},
+	{0x582e, 0x46},
+	{0x582f, 0x60},
+	{0x5830, 0x62},
+	{0x5831, 0x42},
+	{0x5832, 0x46},
+	{0x5833, 0x46},
+	{0x5834, 0x44},
+	{0x5835, 0x44},
+	{0x5836, 0x44},
+	{0x5837, 0x48},
+	{0x5838, 0x28},
+	{0x5839, 0x46},
+	{0x583a, 0x48},
+	{0x583b, 0x68},
+	{0x583c, 0x28},
+	{0x583d, 0xae},
+	{0x5842, 0x00},
+	{0x5843, 0xef},
+	{0x5844, 0x01},
+	{0x5845, 0x3f},
+	{0x5846, 0x01},
+	{0x5847, 0x3f},
+	{0x5848, 0x00},
+	{0x5849, 0xd5},
+	{0x3503, 0x07},
+	{0x3500, 0x00},
+	{0x3501, 0x27},
+	{0x3502, 0x00},
+	{0x350b, 0xff},
+	{0x3400, 0x04},
+	{0x3401, 0x00},
+	{0x3402, 0x04},
+	{0x3403, 0x00},
+	{0x3404, 0x04},
+	{0x3405, 0x00},
+	{0x3406, 0x01},
+	{0x5001, 0x01},
+	{0x5000, 0x86},/* enable lens compensation and dpc */
+	/* LENC setting 70% */
+	{0x5800, 0x21},
+	{0x5801, 0x10},
+	{0x5802, 0x09},
+	{0x5803, 0x0a},
+	{0x5804, 0x0f},
+	{0x5805, 0x23},
+	{0x5806, 0x08},
+	{0x5807, 0x04},
+	{0x5808, 0x04},
+	{0x5809, 0x04},
+	{0x580a, 0x04},
+	{0x580b, 0x0a},
+	{0x580c, 0x04},
+	{0x580d, 0x02},
+	{0x580e, 0x00},
+	{0x580f, 0x00},
+	{0x5810, 0x03},
+	{0x5811, 0x06},
+	{0x5812, 0x05},
+	{0x5813, 0x02},
+	{0x5814, 0x00},
+	{0x5815, 0x00},
+	{0x5816, 0x03},
+	{0x5817, 0x06},
+	{0x5818, 0x09},
+	{0x5819, 0x05},
+	{0x581a, 0x04},
+	{0x581b, 0x04},
+	{0x581c, 0x05},
+	{0x581d, 0x0a},
+	{0x581e, 0x24},
+	{0x581f, 0x11},
+	{0x5820, 0x0a},
+	{0x5821, 0x0a},
+	{0x5822, 0x10},
+	{0x5823, 0x27},
+	{0x5824, 0x2a},
+	{0x5825, 0x58},
+	{0x5826, 0x28},
+	{0x5827, 0x28},
+	{0x5828, 0x28},
+	{0x5829, 0x28},
+	{0x582a, 0x46},
+	{0x582b, 0x44},
+	{0x582c, 0x46},
+	{0x582d, 0x46},
+	{0x582e, 0x28},
+	{0x582f, 0x62},
+	{0x5830, 0x60},
+	{0x5831, 0x42},
+	{0x5832, 0x28},
+	{0x5833, 0x48},
+	{0x5834, 0x46},
+	{0x5835, 0x46},
+	{0x5836, 0x26},
+	{0x5837, 0x46},
+	{0x5838, 0x28},
+	{0x5839, 0x48},
+	{0x583a, 0x28},
+	{0x583b, 0x28},
+	{0x583c, 0x26},
+	{0x583d, 0x9d},
+};
+
+static struct v4l2_subdev_info ov8825_subdev_info[] = {
+	{
+		.code   = V4L2_MBUS_FMT_SBGGR10_1X10,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.fmt    = 1,
+		.order    = 0,
+	},
+	/* more can be supported, to be added later */
+};
+
+static struct msm_camera_i2c_conf_array ov8825_init_conf[] = {
+	{&ov8825_reset_settings[0],
+	ARRAY_SIZE(ov8825_reset_settings), 50, MSM_CAMERA_I2C_BYTE_DATA},
+	{&ov8825_recommend_settings[0],
+	ARRAY_SIZE(ov8825_recommend_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}
+};
+
+static struct msm_camera_i2c_conf_array ov8825_confs[] = {
+	{&ov8825_snap_settings[0],
+	ARRAY_SIZE(ov8825_snap_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+	{&ov8825_prev_settings[0],
+	ARRAY_SIZE(ov8825_prev_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+};
+
+static struct msm_sensor_output_info_t ov8825_dimensions[] = {
+	{
+		.x_output = 0xCC0,
+		.y_output = 0x990,
+		.line_length_pclk = 0xE00,
+		.frame_length_lines = 0x9B0,
+		.vt_pixel_clk = 133400000,
+		.op_pixel_clk = 176000000,
+		.binning_factor = 1,
+	},
+	{
+		.x_output = 0x660,
+		.y_output = 0x4C8,
+		.line_length_pclk = 0x6DE,
+		.frame_length_lines = 0x505,
+		.vt_pixel_clk = 66700000,
+		.op_pixel_clk = 88000000,
+		.binning_factor = 2,
+	},
+};
+
+static struct msm_sensor_output_reg_addr_t ov8825_reg_addr = {
+	.x_output = 0x3808,
+	.y_output = 0x380a,
+	.line_length_pclk = 0x380c,
+	.frame_length_lines = 0x380e,
+};
+
+static struct msm_sensor_id_info_t ov8825_id_info = {
+	.sensor_id_reg_addr = 0x300A,
+	.sensor_id = 0x8825,
+};
+
+static struct msm_sensor_exp_gain_info_t ov8825_exp_gain_info = {
+	.coarse_int_time_addr = 0x3501,
+	.global_gain_addr = 0x350A,
+	.vert_offset = 6,
+};
+
+/********************************************
+ * index: index of otp group. (0, 1, 2)
+ * return value:
+ *     0, group index is empty
+ *     1, group index has invalid data
+ *     2, group index has valid data
+ **********************************************/
+uint16_t ov8825_check_otp_wb(struct msm_sensor_ctrl_t *s_ctrl, uint16_t index)
+{
+	uint16_t temp, i;
+	uint16_t address;
+
+	/* clear otp buffer */
+
+	/* select otp bank 0 */
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x3d84, 0x08,
+			MSM_CAMERA_I2C_BYTE_DATA);
+
+	/* load otp into buffer */
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x3d81, 0x01,
+			MSM_CAMERA_I2C_BYTE_DATA);
+
+	/* read from group [index] */
+	address = 0x3d05 + index * 9;
+	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, address, &temp,
+			MSM_CAMERA_I2C_BYTE_DATA);
+
+	/* disable otp read */
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x3d81, 0x00,
+			MSM_CAMERA_I2C_BYTE_DATA);
+
+	/* clear otp buffer */
+	for (i = 0; i < 32; i++) {
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, (0x3d00+i),
+				0x00, MSM_CAMERA_I2C_BYTE_DATA);
+	}
+
+	if (!temp)
+		return 0;
+	else if ((!(temp & 0x80)) && (temp & 0x7f))
+		return 2;
+	else
+		return 1;
+}
+
+void ov8825_read_otp_wb(struct msm_sensor_ctrl_t *s_ctrl,
+		uint16_t index, struct otp_struct *potp)
+{
+	uint16_t temp, i;
+	uint16_t address;
+
+	/* select otp bank 0 */
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x3d84, 0x08,
+			MSM_CAMERA_I2C_BYTE_DATA);
+
+	/* load otp data into buffer */
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x3d81, 0x01,
+			MSM_CAMERA_I2C_BYTE_DATA);
+
+	/* read otp data from 0x3d00 - 0x3d1f*/
+	address = 0x3d05 + index * 9;
+
+	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, address, &temp,
+			MSM_CAMERA_I2C_BYTE_DATA);
+
+	potp->module_integrator_id = temp;
+	potp->customer_id = temp & 0x7f;
+
+	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, (address+1), &temp,
+			MSM_CAMERA_I2C_BYTE_DATA);
+	potp->lens_id = temp;
+
+	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, (address+2), &temp,
+			MSM_CAMERA_I2C_BYTE_DATA);
+	potp->rg_ratio = temp;
+
+	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, (address+3), &temp,
+			MSM_CAMERA_I2C_BYTE_DATA);
+	potp->bg_ratio = temp;
+
+	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, (address+4), &temp,
+			MSM_CAMERA_I2C_BYTE_DATA);
+	potp->user_data[0] = temp;
+
+	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, (address+5), &temp,
+			MSM_CAMERA_I2C_BYTE_DATA);
+	potp->user_data[1] = temp;
+
+	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, (address+6), &temp,
+			MSM_CAMERA_I2C_BYTE_DATA);
+	potp->user_data[2] = temp;
+
+	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, (address+7), &temp,
+			MSM_CAMERA_I2C_BYTE_DATA);
+	potp->user_data[3] = temp;
+
+	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, (address+8), &temp,
+			MSM_CAMERA_I2C_BYTE_DATA);
+	potp->user_data[4] = temp;
+
+	CDBG("%s customer_id  = 0x%02x\r\n", __func__, potp->customer_id);
+	CDBG("%s lens_id      = 0x%02x\r\n", __func__, potp->lens_id);
+	CDBG("%s rg_ratio     = 0x%02x\r\n", __func__, potp->rg_ratio);
+	CDBG("%s bg_ratio     = 0x%02x\r\n", __func__, potp->bg_ratio);
+	CDBG("%s user_data[0] = 0x%02x\r\n", __func__, potp->user_data[0]);
+	CDBG("%s user_data[1] = 0x%02x\r\n", __func__, potp->user_data[1]);
+	CDBG("%s user_data[2] = 0x%02x\r\n", __func__, potp->user_data[2]);
+	CDBG("%s user_data[3] = 0x%02x\r\n", __func__, potp->user_data[3]);
+	CDBG("%s user_data[4] = 0x%02x\r\n", __func__, potp->user_data[4]);
+
+	/* disable otp read */
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x3d81, 0x00,
+			MSM_CAMERA_I2C_BYTE_DATA);
+
+	/* clear otp buffer */
+	for (i = 0; i < 32; i++)
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, (0x3d00+i),
+				0x00, MSM_CAMERA_I2C_BYTE_DATA);
+}
+
+/**********************************************
+ * r_gain, sensor red gain of AWB, 0x400 =1
+ * g_gain, sensor green gain of AWB, 0x400 =1
+ * b_gain, sensor blue gain of AWB, 0x400 =1
+ ***********************************************/
+void ov8825_update_awb_gain(struct msm_sensor_ctrl_t *s_ctrl,
+		uint16_t r_gain, uint16_t g_gain, uint16_t b_gain)
+{
+	CDBG("%s r_gain = 0x%04x\r\n", __func__, r_gain);
+	CDBG("%s g_gain = 0x%04x\r\n", __func__, g_gain);
+	CDBG("%s b_gain = 0x%04x\r\n", __func__, b_gain);
+	if (r_gain > 0x400) {
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x5186,
+				(r_gain>>8), MSM_CAMERA_I2C_BYTE_DATA);
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x5187,
+				(r_gain&0xff), MSM_CAMERA_I2C_BYTE_DATA);
+	}
+	if (g_gain > 0x400) {
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x5188,
+				(g_gain>>8), MSM_CAMERA_I2C_BYTE_DATA);
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x5189,
+				(g_gain&0xff), MSM_CAMERA_I2C_BYTE_DATA);
+	}
+	if (b_gain > 0x400) {
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x518a,
+				(b_gain>>8), MSM_CAMERA_I2C_BYTE_DATA);
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x518b,
+				(b_gain&0xff), MSM_CAMERA_I2C_BYTE_DATA);
+	}
+}
+
+/**************************************************
+ * call this function after OV8825 initialization
+ * return value:
+ *     0, update success
+ *     1, no OTP
+ ***************************************************/
+uint16_t ov8825_update_otp(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	uint16_t i;
+	uint16_t otp_index;
+	uint16_t temp;
+	uint16_t r_gain, g_gain, b_gain, g_gain_r, g_gain_b;
+
+	/* R/G and B/G of current camera module is read out from sensor OTP */
+	/* check first OTP with valid data */
+	for (i = 0; i < 3; i++) {
+		temp = ov8825_check_otp_wb(s_ctrl, i);
+		if (temp == 2) {
+			otp_index = i;
+			break;
+		}
+	}
+	if (i == 3) {
+		/* no valid wb OTP data */
+		CDBG("no valid wb OTP data\r\n");
+		return 1;
+	}
+	ov8825_read_otp_wb(s_ctrl, otp_index, &st_ov8825_otp);
+	/* calculate g_gain */
+	/* 0x400 = 1x gain */
+	if (st_ov8825_otp.bg_ratio < OV8825_BG_RATIO_TYPICAL_VALUE) {
+		if (st_ov8825_otp.rg_ratio < OV8825_RG_RATIO_TYPICAL_VALUE) {
+			g_gain = 0x400;
+			b_gain = 0x400 *
+				OV8825_BG_RATIO_TYPICAL_VALUE /
+				st_ov8825_otp.bg_ratio;
+			r_gain = 0x400 *
+				OV8825_RG_RATIO_TYPICAL_VALUE /
+				st_ov8825_otp.rg_ratio;
+		} else {
+			r_gain = 0x400;
+			g_gain = 0x400 *
+				st_ov8825_otp.rg_ratio /
+				OV8825_RG_RATIO_TYPICAL_VALUE;
+			b_gain = g_gain *
+				OV8825_BG_RATIO_TYPICAL_VALUE /
+				st_ov8825_otp.bg_ratio;
+		}
+	} else {
+		if (st_ov8825_otp.rg_ratio < OV8825_RG_RATIO_TYPICAL_VALUE) {
+			b_gain = 0x400;
+			g_gain = 0x400 *
+				st_ov8825_otp.bg_ratio /
+				OV8825_BG_RATIO_TYPICAL_VALUE;
+			r_gain = g_gain *
+				OV8825_RG_RATIO_TYPICAL_VALUE /
+				st_ov8825_otp.rg_ratio;
+		} else {
+			g_gain_b = 0x400 *
+				st_ov8825_otp.bg_ratio /
+				OV8825_BG_RATIO_TYPICAL_VALUE;
+			g_gain_r = 0x400 *
+				st_ov8825_otp.rg_ratio /
+				OV8825_RG_RATIO_TYPICAL_VALUE;
+			if (g_gain_b > g_gain_r) {
+				b_gain = 0x400;
+				g_gain = g_gain_b;
+				r_gain = g_gain *
+					OV8825_RG_RATIO_TYPICAL_VALUE /
+					st_ov8825_otp.rg_ratio;
+			} else {
+				r_gain = 0x400;
+				g_gain = g_gain_r;
+				b_gain = g_gain *
+					OV8825_BG_RATIO_TYPICAL_VALUE /
+					st_ov8825_otp.bg_ratio;
+			}
+		}
+	}
+	ov8825_update_awb_gain(s_ctrl, r_gain, g_gain, b_gain);
+	return 0;
+}
+
+static int32_t ov8825_write_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
+		uint16_t gain, uint32_t line)
+{
+	uint32_t fl_lines, offset;
+	uint8_t int_time[3];
+
+	fl_lines =
+		(s_ctrl->curr_frame_length_lines * s_ctrl->fps_divider) / Q10;
+	offset = s_ctrl->sensor_exp_gain_info->vert_offset;
+	if (line > (fl_lines - offset))
+		fl_lines = line + offset;
+	CDBG("ov8825_write_exp_gain: %d %d %d\n", fl_lines, gain, line);
+	s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_output_reg_addr->frame_length_lines, fl_lines,
+		MSM_CAMERA_I2C_WORD_DATA);
+	int_time[0] = line >> 12;
+	int_time[1] = line >> 4;
+	int_time[2] = line << 4;
+	msm_camera_i2c_write_seq(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr-1,
+		&int_time[0], 3);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->global_gain_addr, gain,
+		MSM_CAMERA_I2C_WORD_DATA);
+	s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
+	return 0;
+}
+
+static const struct i2c_device_id ov8825_i2c_id[] = {
+	{SENSOR_NAME, (kernel_ulong_t)&ov8825_s_ctrl},
+	{ }
+};
+
+int32_t ov8825_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	int32_t rc = 0;
+	struct msm_camera_sensor_info *info = NULL;
+
+	info = s_ctrl->sensordata;
+	gpio_direction_output(info->sensor_pwd, 0);
+	gpio_direction_output(info->sensor_reset, 0);
+	usleep_range(10000, 11000);
+	rc = msm_sensor_power_up(s_ctrl);
+	if (rc < 0) {
+		CDBG("%s: msm_sensor_power_up failed\n", __func__);
+		return rc;
+	}
+	/* turn on ldo and vreg */
+	gpio_direction_output(info->sensor_pwd, 1);
+	msleep(20);
+	gpio_direction_output(info->sensor_reset, 1);
+	msleep(40);
+	return rc;
+}
+
+static struct i2c_driver ov8825_i2c_driver = {
+	.id_table = ov8825_i2c_id,
+	.probe  = msm_sensor_i2c_probe,
+	.driver = {
+		.name = SENSOR_NAME,
+	},
+};
+
+static struct msm_camera_i2c_client ov8825_sensor_i2c_client = {
+	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+
+
+static int __init msm_sensor_init_module(void)
+{
+	return i2c_add_driver(&ov8825_i2c_driver);
+}
+
+static struct v4l2_subdev_core_ops ov8825_subdev_core_ops = {
+	.ioctl = msm_sensor_subdev_ioctl,
+	.s_power = msm_sensor_power,
+};
+
+static struct v4l2_subdev_video_ops ov8825_subdev_video_ops = {
+	.enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
+};
+
+static struct v4l2_subdev_ops ov8825_subdev_ops = {
+	.core = &ov8825_subdev_core_ops,
+	.video  = &ov8825_subdev_video_ops,
+};
+
+int32_t ov8825_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
+			int update_type, int res)
+{
+	int32_t rc = 0;
+
+	if (update_type == MSM_SENSOR_REG_INIT) {
+		CDBG("Register INIT\n");
+		s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
+		msm_sensor_enable_debugfs(s_ctrl);
+		msm_sensor_write_init_settings(s_ctrl);
+		CDBG("Update OTP\n");
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x100, 0x1,
+				MSM_CAMERA_I2C_BYTE_DATA);
+		msleep(66);
+		ov8825_update_otp(s_ctrl);
+		usleep_range(10000, 11000);
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x100, 0x0,
+		  MSM_CAMERA_I2C_BYTE_DATA);
+	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
+		CDBG("PERIODIC : %d\n", res);
+		msm_sensor_write_conf_array(
+			s_ctrl->sensor_i2c_client,
+			s_ctrl->msm_sensor_reg->mode_settings, res);
+		msleep(30);
+		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
+			NOTIFY_PCLK_CHANGE,
+			&s_ctrl->sensordata->pdata->ioclk.vfe_clk_rate);
+	}
+	return rc;
+}
+
+static struct msm_sensor_fn_t ov8825_func_tbl = {
+	.sensor_start_stream = msm_sensor_start_stream,
+	.sensor_stop_stream = msm_sensor_stop_stream,
+	.sensor_group_hold_on = msm_sensor_group_hold_on,
+	.sensor_group_hold_off = msm_sensor_group_hold_off,
+	.sensor_set_fps = msm_sensor_set_fps,
+	.sensor_write_exp_gain = ov8825_write_exp_gain,
+	.sensor_write_snapshot_exp_gain = ov8825_write_exp_gain,
+	.sensor_csi_setting = ov8825_sensor_setting,
+	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
+	.sensor_mode_init = msm_sensor_mode_init,
+	.sensor_get_output_info = msm_sensor_get_output_info,
+	.sensor_config = msm_sensor_config,
+	.sensor_power_up = ov8825_sensor_power_up,
+	.sensor_power_down = msm_sensor_power_down,
+};
+
+static struct msm_sensor_reg_t ov8825_regs = {
+	.default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
+	.start_stream_conf = ov8825_start_settings,
+	.start_stream_conf_size = ARRAY_SIZE(ov8825_start_settings),
+	.stop_stream_conf = ov8825_stop_settings,
+	.stop_stream_conf_size = ARRAY_SIZE(ov8825_stop_settings),
+	.group_hold_on_conf = ov8825_groupon_settings,
+	.group_hold_on_conf_size = ARRAY_SIZE(ov8825_groupon_settings),
+	.group_hold_off_conf = ov8825_groupoff_settings,
+	.group_hold_off_conf_size =	ARRAY_SIZE(ov8825_groupoff_settings),
+	.init_settings = &ov8825_init_conf[0],
+	.init_size = ARRAY_SIZE(ov8825_init_conf),
+	.mode_settings = &ov8825_confs[0],
+	.output_settings = &ov8825_dimensions[0],
+	.num_conf = ARRAY_SIZE(ov8825_confs),
+};
+
+static struct msm_sensor_ctrl_t ov8825_s_ctrl = {
+	.msm_sensor_reg = &ov8825_regs,
+	.sensor_i2c_client = &ov8825_sensor_i2c_client,
+	.sensor_i2c_addr = 0x6C,
+	.sensor_output_reg_addr = &ov8825_reg_addr,
+	.sensor_id_info = &ov8825_id_info,
+	.sensor_exp_gain_info = &ov8825_exp_gain_info,
+	.cam_mode = MSM_SENSOR_MODE_INVALID,
+	.msm_sensor_mutex = &ov8825_mut,
+	.sensor_i2c_driver = &ov8825_i2c_driver,
+	.sensor_v4l2_subdev_info = ov8825_subdev_info,
+	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(ov8825_subdev_info),
+	.sensor_v4l2_subdev_ops = &ov8825_subdev_ops,
+	.func_tbl = &ov8825_func_tbl,
+};
+
+module_init(msm_sensor_init_module);
+MODULE_DESCRIPTION("Omnivison 8MP Bayer sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/sensors/ov9726_v4l2.c b/drivers/media/platform/msm/camera_v1/sensors/ov9726_v4l2.c
new file mode 100644
index 0000000..debd959
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/sensors/ov9726_v4l2.c
@@ -0,0 +1,268 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_sensor.h"
+#define SENSOR_NAME "ov9726"
+#define PLATFORM_DRIVER_NAME "msm_camera_ov9726"
+#define ov9726_obj ov9726_##obj
+
+DEFINE_MUTEX(ov9726_mut);
+static struct msm_sensor_ctrl_t ov9726_s_ctrl;
+
+static struct msm_camera_i2c_reg_conf ov9726_start_settings[] = {
+	{0x0100, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf ov9726_stop_settings[] = {
+	{0x0100, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf ov9726_groupon_settings[] = {
+	{0x0104, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf ov9726_groupoff_settings[] = {
+	{0x0104, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf ov9726_prev_settings[] = {
+};
+
+static struct msm_camera_i2c_reg_conf ov9726_recommend_settings[] = {
+	{0x0103, 0x01}, /* SOFTWARE_RESET */
+	{0x3026, 0x00}, /* OUTPUT_SELECT01 */
+	{0x3027, 0x00}, /* OUTPUT_SELECT02 */
+	{0x3002, 0xe8}, /* IO_CTRL00 */
+	{0x3004, 0x03}, /* IO_CTRL01 */
+	{0x3005, 0xff}, /* IO_CTRL02 */
+	{0x3703, 0x42},
+	{0x3704, 0x10},
+	{0x3705, 0x45},
+	{0x3603, 0xaa},
+	{0x3632, 0x2f},
+	{0x3620, 0x66},
+	{0x3621, 0xc0},
+	{0x0340, 0x03}, /* FRAME_LENGTH_LINES_HI */
+	{0x0341, 0xC1}, /* FRAME_LENGTH_LINES_LO */
+	{0x0342, 0x06}, /* LINE_LENGTH_PCK_HI */
+	{0x0343, 0x80}, /* LINE_LENGTH_PCK_LO */
+	{0x0202, 0x03}, /* COARSE_INTEGRATION_TIME_HI */
+	{0x0203, 0x43}, /* COARSE_INTEGRATION_TIME_LO */
+	{0x3833, 0x04},
+	{0x3835, 0x02},
+	{0x4702, 0x04},
+	{0x4704, 0x00}, /* DVP_CTRL01 */
+	{0x4706, 0x08},
+	{0x5052, 0x01},
+	{0x3819, 0x6e},
+	{0x3817, 0x94},
+	{0x3a18, 0x00}, /* AEC_GAIN_CEILING_HI */
+	{0x3a19, 0x7f}, /* AEC_GAIN_CEILING_LO */
+	{0x404e, 0x7e},
+	{0x3631, 0x52},
+	{0x3633, 0x50},
+	{0x3630, 0xd2},
+	{0x3604, 0x08},
+	{0x3601, 0x40},
+	{0x3602, 0x14},
+	{0x3610, 0xa0},
+	{0x3612, 0x20},
+	{0x034c, 0x05}, /* X_OUTPUT_SIZE_HI */
+	{0x034d, 0x10}, /* X_OUTPUT_SIZE_LO */
+	{0x034e, 0x03}, /* Y_OUTPUT_SIZE_HI */
+	{0x034f, 0x28}, /* Y_OUTPUT_SIZE_LO */
+	{0x0340, 0x03}, /* FRAME_LENGTH_LINES_HI */
+	{0x0341, 0xC1}, /* FRAME_LENGTH_LINES_LO */
+	{0x0342, 0x06}, /* LINE_LENGTH_PCK_HI */
+	{0x0343, 0x80}, /* LINE_LENGTH_PCK_LO */
+	{0x0202, 0x03}, /* COARSE_INTEGRATION_TIME_HI */
+	{0x0203, 0x43}, /* COARSE_INTEGRATION_TIME_LO */
+	{0x0303, 0x01}, /* VT_SYS_CLK_DIV_LO */
+	{0x3002, 0x00}, /* IO_CTRL00 */
+	{0x3004, 0x00}, /* IO_CTRL01 */
+	{0x3005, 0x00}, /* IO_CTRL02 */
+	{0x4801, 0x0f}, /* MIPI_CTRL01 */
+	{0x4803, 0x05}, /* MIPI_CTRL03 */
+	{0x4601, 0x16}, /* VFIFO_READ_CONTROL */
+	{0x3014, 0x05}, /* SC_CMMN_MIPI / SC_CTRL00 */
+	{0x3104, 0x80},
+	{0x0305, 0x04}, /* PRE_PLL_CLK_DIV_LO */
+	{0x0307, 0x64}, /* PLL_MULTIPLIER_LO */
+	{0x300c, 0x02},
+	{0x300d, 0x20},
+	{0x300e, 0x01},
+	{0x3010, 0x01},
+	{0x460e, 0x81}, /* VFIFO_CONTROL00 */
+	{0x0101, 0x01}, /* IMAGE_ORIENTATION */
+	{0x3707, 0x14},
+	{0x3622, 0x9f},
+	{0x5047, 0x3D}, /* ISP_CTRL47 */
+	{0x4002, 0x45}, /* BLC_CTRL02 */
+	{0x5000, 0x06}, /* ISP_CTRL0 */
+	{0x5001, 0x00}, /* ISP_CTRL1 */
+	{0x3406, 0x00}, /* AWB_MANUAL_CTRL */
+	{0x3503, 0x13}, /* AEC_ENABLE */
+	{0x4005, 0x18}, /* BLC_CTRL05 */
+	{0x4837, 0x21},
+	{0x0100, 0x01}, /* MODE_SELECT */
+	{0x3a0f, 0x64}, /* AEC_CTRL0F */
+	{0x3a10, 0x54}, /* AEC_CTRL10 */
+	{0x3a11, 0xc2}, /* AEC_CTRL11 */
+	{0x3a1b, 0x64}, /* AEC_CTRL1B */
+	{0x3a1e, 0x54}, /* AEC_CTRL1E */
+	{0x3a1a, 0x05}, /* AEC_DIFF_MAX */
+};
+
+static struct v4l2_subdev_info ov9726_subdev_info[] = {
+	{
+	.code   = V4L2_MBUS_FMT_SBGGR10_1X10,
+	.colorspace = V4L2_COLORSPACE_JPEG,
+	.fmt    = 1,
+	.order    = 0,
+	},
+	/* more can be supported, to be added later */
+};
+
+static struct msm_camera_i2c_conf_array ov9726_init_conf[] = {
+	{&ov9726_recommend_settings[0],
+	ARRAY_SIZE(ov9726_recommend_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}
+};
+
+static struct msm_camera_i2c_conf_array ov9726_confs[] = {
+	{&ov9726_prev_settings[0],
+	ARRAY_SIZE(ov9726_prev_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+};
+
+static struct msm_sensor_output_info_t ov9726_dimensions[] = {
+	{
+		.x_output = 0x510, /* 1296 */
+		.y_output = 0x328, /* 808 */
+		.line_length_pclk = 0x680, /* 1664 */
+		.frame_length_lines = 0x3C1, /* 961 */
+		.vt_pixel_clk = 320000000,
+		.op_pixel_clk = 320000000,
+		.binning_factor = 1,
+	},
+};
+
+static struct msm_sensor_output_reg_addr_t ov9726_reg_addr = {
+	.x_output = 0x034c,
+	.y_output = 0x034e,
+	.line_length_pclk = 0x0342,
+	.frame_length_lines = 0x0340,
+};
+
+static struct msm_sensor_id_info_t ov9726_id_info = {
+	.sensor_id_reg_addr = 0x0000,
+	.sensor_id = 0x9726,
+};
+
+static struct msm_sensor_exp_gain_info_t ov9726_exp_gain_info = {
+	.coarse_int_time_addr = 0x0202,
+	.global_gain_addr = 0x0204,
+	.vert_offset = 6,
+};
+
+static const struct i2c_device_id ov9726_i2c_id[] = {
+	{SENSOR_NAME, (kernel_ulong_t)&ov9726_s_ctrl},
+	{ }
+};
+
+static struct i2c_driver ov9726_i2c_driver = {
+	.id_table = ov9726_i2c_id,
+	.probe  = msm_sensor_i2c_probe,
+	.driver = {
+		.name = SENSOR_NAME,
+	},
+};
+
+static struct msm_camera_i2c_client ov9726_sensor_i2c_client = {
+	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+static int __init msm_sensor_init_module(void)
+{
+	return i2c_add_driver(&ov9726_i2c_driver);
+}
+
+static struct v4l2_subdev_core_ops ov9726_subdev_core_ops = {
+	.ioctl = msm_sensor_subdev_ioctl,
+	.s_power = msm_sensor_power,
+};
+
+static struct v4l2_subdev_video_ops ov9726_subdev_video_ops = {
+	.enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
+};
+
+static struct v4l2_subdev_ops ov9726_subdev_ops = {
+	.core = &ov9726_subdev_core_ops,
+	.video  = &ov9726_subdev_video_ops,
+};
+
+static struct msm_sensor_fn_t ov9726_func_tbl = {
+	.sensor_start_stream = msm_sensor_start_stream,
+	.sensor_stop_stream = msm_sensor_stop_stream,
+	.sensor_group_hold_on = msm_sensor_group_hold_on,
+	.sensor_group_hold_off = msm_sensor_group_hold_off,
+	.sensor_set_fps = msm_sensor_set_fps,
+	.sensor_write_exp_gain = msm_sensor_write_exp_gain1,
+	.sensor_write_snapshot_exp_gain = msm_sensor_write_exp_gain1,
+	.sensor_csi_setting = msm_sensor_setting1,
+	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
+	.sensor_mode_init = msm_sensor_mode_init,
+	.sensor_get_output_info = msm_sensor_get_output_info,
+	.sensor_config = msm_sensor_config,
+	.sensor_power_up = msm_sensor_power_up,
+	.sensor_power_down = msm_sensor_power_down,
+};
+
+static struct msm_sensor_reg_t ov9726_regs = {
+	.default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
+	.start_stream_conf = ov9726_start_settings,
+	.start_stream_conf_size = ARRAY_SIZE(ov9726_start_settings),
+	.stop_stream_conf = ov9726_stop_settings,
+	.stop_stream_conf_size = ARRAY_SIZE(ov9726_stop_settings),
+	.group_hold_on_conf = ov9726_groupon_settings,
+	.group_hold_on_conf_size = ARRAY_SIZE(ov9726_groupon_settings),
+	.group_hold_off_conf = ov9726_groupoff_settings,
+	.group_hold_off_conf_size =
+		ARRAY_SIZE(ov9726_groupoff_settings),
+	.init_settings = &ov9726_init_conf[0],
+	.init_size = ARRAY_SIZE(ov9726_init_conf),
+	.mode_settings = &ov9726_confs[0],
+	.output_settings = &ov9726_dimensions[0],
+	.num_conf = ARRAY_SIZE(ov9726_confs),
+};
+
+static struct msm_sensor_ctrl_t ov9726_s_ctrl = {
+	.msm_sensor_reg = &ov9726_regs,
+	.sensor_i2c_client = &ov9726_sensor_i2c_client,
+	.sensor_i2c_addr = 0x20,
+	.sensor_output_reg_addr = &ov9726_reg_addr,
+	.sensor_id_info = &ov9726_id_info,
+	.sensor_exp_gain_info = &ov9726_exp_gain_info,
+	.cam_mode = MSM_SENSOR_MODE_INVALID,
+	.msm_sensor_mutex = &ov9726_mut,
+	.sensor_i2c_driver = &ov9726_i2c_driver,
+	.sensor_v4l2_subdev_info = ov9726_subdev_info,
+	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(ov9726_subdev_info),
+	.sensor_v4l2_subdev_ops = &ov9726_subdev_ops,
+	.func_tbl = &ov9726_func_tbl,
+	.clk_rate = MSM_SENSOR_MCLK_24HZ,
+};
+
+module_init(msm_sensor_init_module);
+MODULE_DESCRIPTION("Omnivision WXGA Bayer sensor driver");
+MODULE_LICENSE("GPL v2");
+
+
diff --git a/drivers/media/video/msm/sensors/s5k3l1yx.c b/drivers/media/platform/msm/camera_v1/sensors/s5k3l1yx.c
similarity index 100%
rename from drivers/media/video/msm/sensors/s5k3l1yx.c
rename to drivers/media/platform/msm/camera_v1/sensors/s5k3l1yx.c
diff --git a/drivers/media/platform/msm/camera_v1/sensors/s5k4e1_v4l2.c b/drivers/media/platform/msm/camera_v1/sensors/s5k4e1_v4l2.c
new file mode 100644
index 0000000..a95bb0a
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/sensors/s5k4e1_v4l2.c
@@ -0,0 +1,518 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_sensor.h"
+#define SENSOR_NAME "s5k4e1"
+#define PLATFORM_DRIVER_NAME "msm_camera_s5k4e1"
+#define s5k4e1_obj s5k4e1_##obj
+#define MSB                             1
+#define LSB                             0
+
+DEFINE_MUTEX(s5k4e1_mut);
+static struct msm_sensor_ctrl_t s5k4e1_s_ctrl;
+
+static struct msm_camera_i2c_reg_conf s5k4e1_start_settings[] = {
+	{0x0100, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf s5k4e1_stop_settings[] = {
+	{0x0100, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf s5k4e1_groupon_settings[] = {
+	{0x0104, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf s5k4e1_groupoff_settings[] = {
+	{0x0104, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf s5k4e1_prev_settings[] = {
+	/* output size (1304 x 980) */
+	{0x30A9, 0x02},/* Horizontal Binning On */
+	{0x300E, 0xEB},/* Vertical Binning On */
+	{0x0387, 0x03},/* y_odd_inc 03(10b AVG) */
+	{0x0344, 0x00},/* x_addr_start 0 */
+	{0x0345, 0x00},
+	{0x0348, 0x0A},/* x_addr_end 2607 */
+	{0x0349, 0x2F},
+	{0x0346, 0x00},/* y_addr_start 0 */
+	{0x0347, 0x00},
+	{0x034A, 0x07},/* y_addr_end 1959 */
+	{0x034B, 0xA7},
+	{0x0380, 0x00},/* x_even_inc 1 */
+	{0x0381, 0x01},
+	{0x0382, 0x00},/* x_odd_inc 1 */
+	{0x0383, 0x01},
+	{0x0384, 0x00},/* y_even_inc 1 */
+	{0x0385, 0x01},
+	{0x0386, 0x00},/* y_odd_inc 3 */
+	{0x0387, 0x03},
+	{0x034C, 0x05},/* x_output_size 1304 */
+	{0x034D, 0x18},
+	{0x034E, 0x03},/* y_output_size 980 */
+	{0x034F, 0xd4},
+	{0x30BF, 0xAB},/* outif_enable[7], data_type[5:0](2Bh = bayer 10bit} */
+	{0x30C0, 0xA0},/* video_offset[7:4] 3260%12 */
+	{0x30C8, 0x06},/* video_data_length 1600 = 1304 * 1.25 */
+	{0x30C9, 0x5E},
+	/* Timing Configuration */
+	{0x0202, 0x03},
+	{0x0203, 0x14},
+	{0x0204, 0x00},
+	{0x0205, 0x80},
+	{0x0340, 0x03},/* Frame Length */
+	{0x0341, 0xE0},
+	{0x0342, 0x0A},/* 2738  Line Length */
+	{0x0343, 0xB2},
+};
+
+static struct msm_camera_i2c_reg_conf s5k4e1_snap_settings[] = {
+	/*Output Size (2608x1960)*/
+	{0x30A9, 0x03},/* Horizontal Binning Off */
+	{0x300E, 0xE8},/* Vertical Binning Off */
+	{0x0387, 0x01},/* y_odd_inc */
+	{0x034C, 0x0A},/* x_output size */
+	{0x034D, 0x30},
+	{0x034E, 0x07},/* y_output size */
+	{0x034F, 0xA8},
+	{0x30BF, 0xAB},/* outif_enable[7], data_type[5:0](2Bh = bayer 10bit} */
+	{0x30C0, 0x80},/* video_offset[7:4] 3260%12 */
+	{0x30C8, 0x0C},/* video_data_length 3260 = 2608 * 1.25 */
+	{0x30C9, 0xBC},
+	/*Timing configuration*/
+	{0x0202, 0x06},
+	{0x0203, 0x28},
+	{0x0204, 0x00},
+	{0x0205, 0x80},
+	{0x0340, 0x07},/* Frame Length */
+	{0x0341, 0xB4},
+	{0x0342, 0x0A},/* 2738 Line Length */
+	{0x0343, 0xB2},
+};
+
+static struct msm_camera_i2c_reg_conf s5k4e1_recommend_settings[] = {
+	/* Reset setting */
+	{0x0103, 0x01},
+	/* MIPI settings */
+	{0x30BD, 0x00},/* SEL_CCP[0] */
+	{0x3084, 0x15},/* SYNC Mode */
+	{0x30BE, 0x1A},/* M_PCLKDIV_AUTO[4], M_DIV_PCLK[3:0] */
+	{0x30C1, 0x01},/* pack video enable [0] */
+	{0x30EE, 0x02},/* DPHY enable [ 1] */
+	{0x3111, 0x86},/* Embedded data off [5] */
+
+	/* REC Settings */
+	/*CDS timing setting ... */
+	{0x3000, 0x05},
+	{0x3001, 0x03},
+	{0x3002, 0x08},
+	{0x3003, 0x0A},
+	{0x3004, 0x50},
+	{0x3005, 0x0E},
+	{0x3006, 0x5E},
+	{0x3007, 0x00},
+	{0x3008, 0x78},
+	{0x3009, 0x78},
+	{0x300A, 0x50},
+	{0x300B, 0x08},
+	{0x300C, 0x14},
+	{0x300D, 0x00},
+	{0x300E, 0xE8},
+	{0x300F, 0x82},
+	{0x301B, 0x77},
+
+	/* CDS option setting ... */
+	{0x3010, 0x00},
+	{0x3011, 0x3A},
+	{0x3029, 0x04},
+	{0x3012, 0x30},
+	{0x3013, 0xA0},
+	{0x3014, 0x00},
+	{0x3015, 0x00},
+	{0x3016, 0x30},
+	{0x3017, 0x94},
+	{0x3018, 0x70},
+	{0x301D, 0xD4},
+	{0x3021, 0x02},
+	{0x3022, 0x24},
+	{0x3024, 0x40},
+	{0x3027, 0x08},
+
+	/* Pixel option setting ...   */
+	{0x301C, 0x04},
+	{0x30D8, 0x3F},
+	{0x302B, 0x01},
+
+	{0x3070, 0x5F},
+	{0x3071, 0x00},
+	{0x3080, 0x04},
+	{0x3081, 0x38},
+
+	/* PLL settings */
+	{0x0305, 0x04},
+	{0x0306, 0x00},
+	{0x0307, 0x44},
+	{0x30B5, 0x00},
+	{0x30E2, 0x01},/* num lanes[1:0] = 2 */
+	{0x30F1, 0xB0},
+};
+
+static struct v4l2_subdev_info s5k4e1_subdev_info[] = {
+	{
+	.code   = V4L2_MBUS_FMT_SGRBG10_1X10,
+	.colorspace = V4L2_COLORSPACE_JPEG,
+	.fmt    = 1,
+	.order    = 0,
+	},
+	/* more can be supported, to be added later */
+};
+
+static struct msm_camera_i2c_conf_array s5k4e1_init_conf[] = {
+	{&s5k4e1_recommend_settings[0],
+	ARRAY_SIZE(s5k4e1_recommend_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}
+};
+
+static struct msm_camera_i2c_conf_array s5k4e1_confs[] = {
+	{&s5k4e1_snap_settings[0],
+	ARRAY_SIZE(s5k4e1_snap_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+	{&s5k4e1_prev_settings[0],
+	ARRAY_SIZE(s5k4e1_prev_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+};
+
+static struct msm_sensor_output_info_t s5k4e1_dimensions[] = {
+	{
+		.x_output = 0xA30,
+		.y_output = 0x7A8,
+		.line_length_pclk = 0xAB2,
+		.frame_length_lines = 0x7B4,
+		.vt_pixel_clk = 81600000,
+		.op_pixel_clk = 81600000,
+		.binning_factor = 0,
+	},
+	{
+		.x_output = 0x518,
+		.y_output = 0x3D4,
+		.line_length_pclk = 0xAB2,
+		.frame_length_lines = 0x3E0,
+		.vt_pixel_clk = 81600000,
+		.op_pixel_clk = 81600000,
+		.binning_factor = 1,
+	},
+};
+
+static struct msm_sensor_output_reg_addr_t s5k4e1_reg_addr = {
+	.x_output = 0x034C,
+	.y_output = 0x034E,
+	.line_length_pclk = 0x0342,
+	.frame_length_lines = 0x0340,
+};
+
+static struct msm_sensor_id_info_t s5k4e1_id_info = {
+	.sensor_id_reg_addr = 0x0000,
+	.sensor_id = 0x4E10,
+};
+
+static struct msm_sensor_exp_gain_info_t s5k4e1_exp_gain_info = {
+	.coarse_int_time_addr = 0x0202,
+	.global_gain_addr = 0x0204,
+	.vert_offset = 4,
+};
+
+static inline uint8_t s5k4e1_byte(uint16_t word, uint8_t offset)
+{
+	return word >> (offset * BITS_PER_BYTE);
+}
+
+static int32_t s5k4e1_write_prev_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
+						uint16_t gain, uint32_t line)
+{
+	uint16_t max_legal_gain = 0x0200;
+	int32_t rc = 0;
+	static uint32_t fl_lines, offset;
+
+	pr_info("s5k4e1_write_prev_exp_gain :%d %d\n", gain, line);
+	offset = s_ctrl->sensor_exp_gain_info->vert_offset;
+	if (gain > max_legal_gain) {
+		CDBG("Max legal gain Line:%d\n", __LINE__);
+		gain = max_legal_gain;
+	}
+
+	/* Analogue Gain */
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->global_gain_addr,
+		s5k4e1_byte(gain, MSB),
+		MSM_CAMERA_I2C_BYTE_DATA);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->global_gain_addr + 1,
+		s5k4e1_byte(gain, LSB),
+		MSM_CAMERA_I2C_BYTE_DATA);
+
+	if (line > (s_ctrl->curr_frame_length_lines - offset)) {
+		fl_lines = line + offset;
+		s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+			s_ctrl->sensor_output_reg_addr->frame_length_lines,
+			s5k4e1_byte(fl_lines, MSB),
+			MSM_CAMERA_I2C_BYTE_DATA);
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+			s_ctrl->sensor_output_reg_addr->frame_length_lines + 1,
+			s5k4e1_byte(fl_lines, LSB),
+			MSM_CAMERA_I2C_BYTE_DATA);
+		/* Coarse Integration Time */
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+			s_ctrl->sensor_exp_gain_info->coarse_int_time_addr,
+			s5k4e1_byte(line, MSB),
+			MSM_CAMERA_I2C_BYTE_DATA);
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+			s_ctrl->sensor_exp_gain_info->coarse_int_time_addr + 1,
+			s5k4e1_byte(line, LSB),
+			MSM_CAMERA_I2C_BYTE_DATA);
+		s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
+	} else if (line < (fl_lines - offset)) {
+		fl_lines = line + offset;
+		if (fl_lines < s_ctrl->curr_frame_length_lines)
+			fl_lines = s_ctrl->curr_frame_length_lines;
+
+		s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
+		/* Coarse Integration Time */
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+			s_ctrl->sensor_exp_gain_info->coarse_int_time_addr,
+			s5k4e1_byte(line, MSB),
+			MSM_CAMERA_I2C_BYTE_DATA);
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+			s_ctrl->sensor_exp_gain_info->coarse_int_time_addr + 1,
+			s5k4e1_byte(line, LSB),
+			MSM_CAMERA_I2C_BYTE_DATA);
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+			s_ctrl->sensor_output_reg_addr->frame_length_lines,
+			s5k4e1_byte(fl_lines, MSB),
+			MSM_CAMERA_I2C_BYTE_DATA);
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+			s_ctrl->sensor_output_reg_addr->frame_length_lines + 1,
+			s5k4e1_byte(fl_lines, LSB),
+			MSM_CAMERA_I2C_BYTE_DATA);
+		s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
+	} else {
+		fl_lines = line+4;
+		s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
+		/* Coarse Integration Time */
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+			s_ctrl->sensor_exp_gain_info->coarse_int_time_addr,
+			s5k4e1_byte(line, MSB),
+			MSM_CAMERA_I2C_BYTE_DATA);
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+			s_ctrl->sensor_exp_gain_info->coarse_int_time_addr + 1,
+			s5k4e1_byte(line, LSB),
+			MSM_CAMERA_I2C_BYTE_DATA);
+		s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
+	}
+	return rc;
+}
+
+static int32_t s5k4e1_write_pict_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
+		uint16_t gain, uint32_t line)
+{
+	uint16_t max_legal_gain = 0x0200;
+	uint16_t min_ll_pck = 0x0AB2;
+	uint32_t ll_pck, fl_lines;
+	uint32_t ll_ratio;
+	uint8_t gain_msb, gain_lsb;
+	uint8_t intg_time_msb, intg_time_lsb;
+	uint8_t ll_pck_msb, ll_pck_lsb;
+
+	if (gain > max_legal_gain) {
+		CDBG("Max legal gain Line:%d\n", __LINE__);
+		gain = max_legal_gain;
+	}
+
+	pr_info("s5k4e1_write_exp_gain : gain = %d line = %d\n", gain, line);
+	line = (uint32_t) (line * s_ctrl->fps_divider);
+	fl_lines = s_ctrl->curr_frame_length_lines * s_ctrl->fps_divider / Q10;
+	ll_pck = s_ctrl->curr_line_length_pclk;
+
+	if (fl_lines < (line / Q10))
+		ll_ratio = (line / (fl_lines - 4));
+	else
+		ll_ratio = Q10;
+
+	ll_pck = ll_pck * ll_ratio / Q10;
+	line = line / ll_ratio;
+	if (ll_pck < min_ll_pck)
+		ll_pck = min_ll_pck;
+
+	gain_msb = (uint8_t) ((gain & 0xFF00) >> 8);
+	gain_lsb = (uint8_t) (gain & 0x00FF);
+
+	intg_time_msb = (uint8_t) ((line & 0xFF00) >> 8);
+	intg_time_lsb = (uint8_t) (line & 0x00FF);
+
+	ll_pck_msb = (uint8_t) ((ll_pck & 0xFF00) >> 8);
+	ll_pck_lsb = (uint8_t) (ll_pck & 0x00FF);
+
+	s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->global_gain_addr,
+		gain_msb,
+		MSM_CAMERA_I2C_BYTE_DATA);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->global_gain_addr + 1,
+		gain_lsb,
+		MSM_CAMERA_I2C_BYTE_DATA);
+
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_output_reg_addr->line_length_pclk,
+		ll_pck_msb,
+		MSM_CAMERA_I2C_BYTE_DATA);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_output_reg_addr->line_length_pclk + 1,
+		ll_pck_lsb,
+		MSM_CAMERA_I2C_BYTE_DATA);
+
+	/* Coarse Integration Time */
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr,
+		intg_time_msb,
+		MSM_CAMERA_I2C_BYTE_DATA);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr + 1,
+		intg_time_lsb,
+		MSM_CAMERA_I2C_BYTE_DATA);
+	s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
+
+	return 0;
+}
+
+int32_t s5k4e1_sensor_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+	struct msm_camera_sensor_info *s_info;
+
+	rc = msm_sensor_i2c_probe(client, id);
+
+	s_info = client->dev.platform_data;
+	if (s_info == NULL) {
+		pr_err("%s %s NULL sensor data\n", __func__, client->name);
+		return -EFAULT;
+	}
+
+	if (s_info->actuator_info->vcm_enable) {
+		rc = gpio_request(s_info->actuator_info->vcm_pwd,
+				"msm_actuator");
+		if (rc < 0)
+			pr_err("%s: gpio_request:msm_actuator %d failed\n",
+				__func__, s_info->actuator_info->vcm_pwd);
+		rc = gpio_direction_output(s_info->actuator_info->vcm_pwd, 0);
+		if (rc < 0)
+			pr_err("%s: gpio:msm_actuator %d direction can't be set\n",
+				__func__, s_info->actuator_info->vcm_pwd);
+		gpio_free(s_info->actuator_info->vcm_pwd);
+	}
+
+	return rc;
+}
+
+static const struct i2c_device_id s5k4e1_i2c_id[] = {
+	{SENSOR_NAME, (kernel_ulong_t)&s5k4e1_s_ctrl},
+	{ }
+};
+
+static struct i2c_driver s5k4e1_i2c_driver = {
+	.id_table = s5k4e1_i2c_id,
+	.probe  = s5k4e1_sensor_i2c_probe,
+	.driver = {
+		.name = SENSOR_NAME,
+	},
+};
+
+static struct msm_camera_i2c_client s5k4e1_sensor_i2c_client = {
+	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+static int __init msm_sensor_init_module(void)
+{
+	return i2c_add_driver(&s5k4e1_i2c_driver);
+}
+
+static struct v4l2_subdev_core_ops s5k4e1_subdev_core_ops = {
+	.ioctl = msm_sensor_subdev_ioctl,
+	.s_power = msm_sensor_power,
+};
+
+static struct v4l2_subdev_video_ops s5k4e1_subdev_video_ops = {
+	.enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
+};
+
+static struct v4l2_subdev_ops s5k4e1_subdev_ops = {
+	.core = &s5k4e1_subdev_core_ops,
+	.video  = &s5k4e1_subdev_video_ops,
+};
+
+static struct msm_sensor_fn_t s5k4e1_func_tbl = {
+	.sensor_start_stream = msm_sensor_start_stream,
+	.sensor_stop_stream = msm_sensor_stop_stream,
+	.sensor_group_hold_on = msm_sensor_group_hold_on,
+	.sensor_group_hold_off = msm_sensor_group_hold_off,
+	.sensor_set_fps = msm_sensor_set_fps,
+	.sensor_write_exp_gain = s5k4e1_write_prev_exp_gain,
+	.sensor_write_snapshot_exp_gain = s5k4e1_write_pict_exp_gain,
+	.sensor_csi_setting = msm_sensor_setting1,
+	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
+	.sensor_mode_init = msm_sensor_mode_init,
+	.sensor_get_output_info = msm_sensor_get_output_info,
+	.sensor_config = msm_sensor_config,
+	.sensor_power_up = msm_sensor_power_up,
+	.sensor_power_down = msm_sensor_power_down,
+};
+
+static struct msm_sensor_reg_t s5k4e1_regs = {
+	.default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
+	.start_stream_conf = s5k4e1_start_settings,
+	.start_stream_conf_size = ARRAY_SIZE(s5k4e1_start_settings),
+	.stop_stream_conf = s5k4e1_stop_settings,
+	.stop_stream_conf_size = ARRAY_SIZE(s5k4e1_stop_settings),
+	.group_hold_on_conf = s5k4e1_groupon_settings,
+	.group_hold_on_conf_size = ARRAY_SIZE(s5k4e1_groupon_settings),
+	.group_hold_off_conf = s5k4e1_groupoff_settings,
+	.group_hold_off_conf_size =
+		ARRAY_SIZE(s5k4e1_groupoff_settings),
+	.init_settings = &s5k4e1_init_conf[0],
+	.init_size = ARRAY_SIZE(s5k4e1_init_conf),
+	.mode_settings = &s5k4e1_confs[0],
+	.output_settings = &s5k4e1_dimensions[0],
+	.num_conf = ARRAY_SIZE(s5k4e1_confs),
+};
+
+static struct msm_sensor_ctrl_t s5k4e1_s_ctrl = {
+	.msm_sensor_reg = &s5k4e1_regs,
+	.sensor_i2c_client = &s5k4e1_sensor_i2c_client,
+	.sensor_i2c_addr = 0x6C,
+	.sensor_output_reg_addr = &s5k4e1_reg_addr,
+	.sensor_id_info = &s5k4e1_id_info,
+	.sensor_exp_gain_info = &s5k4e1_exp_gain_info,
+	.cam_mode = MSM_SENSOR_MODE_INVALID,
+	.msm_sensor_mutex = &s5k4e1_mut,
+	.sensor_i2c_driver = &s5k4e1_i2c_driver,
+	.sensor_v4l2_subdev_info = s5k4e1_subdev_info,
+	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(s5k4e1_subdev_info),
+	.sensor_v4l2_subdev_ops = &s5k4e1_subdev_ops,
+	.func_tbl = &s5k4e1_func_tbl,
+	.clk_rate = MSM_SENSOR_MCLK_24HZ,
+};
+
+module_init(msm_sensor_init_module);
+MODULE_DESCRIPTION("Samsung 5MP Bayer sensor driver");
+MODULE_LICENSE("GPL v2");
+
+
diff --git a/drivers/media/platform/msm/camera_v1/sensors/vx6953.c b/drivers/media/platform/msm/camera_v1/sensors/vx6953.c
new file mode 100644
index 0000000..9867468
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/sensors/vx6953.c
@@ -0,0 +1,2037 @@
+/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_sensor.h"
+#include "msm.h"
+#include "vx6953.h"
+#include "vx6953_reg.h"
+#define SENSOR_NAME "vx6953"
+#define PLATFORM_DRIVER_NAME "msm_camera_vx6953"
+#define vx6953_obj vx6953_##obj
+
+DEFINE_MUTEX(vx6953_mut);
+
+#undef CDBG
+#define CDBG printk
+#define REG_GROUPED_PARAMETER_HOLD			0x0104
+#define GROUPED_PARAMETER_HOLD_OFF			0x00
+#define GROUPED_PARAMETER_HOLD				0x01
+#define REG_MODE_SELECT					0x0100
+#define MODE_SELECT_STANDBY_MODE			0x00
+#define MODE_SELECT_STREAM				0x01
+/* Integration Time */
+#define REG_COARSE_INTEGRATION_TIME_HI			0x0202
+#define REG_COARSE_INTEGRATION_TIME_LO			0x0203
+/* Gain */
+#define REG_ANALOGUE_GAIN_CODE_GLOBAL_HI		0x0204
+#define REG_ANALOGUE_GAIN_CODE_GLOBAL_LO		0x0205
+/* Digital Gain */
+#define REG_DIGITAL_GAIN_GREEN_R_HI			0x020E
+#define REG_DIGITAL_GAIN_GREEN_R_LO			0x020F
+#define REG_DIGITAL_GAIN_RED_HI				0x0210
+#define REG_DIGITAL_GAIN_RED_LO				0x0211
+#define REG_DIGITAL_GAIN_BLUE_HI			0x0212
+#define REG_DIGITAL_GAIN_BLUE_LO			0x0213
+#define REG_DIGITAL_GAIN_GREEN_B_HI			0x0214
+#define REG_DIGITAL_GAIN_GREEN_B_LO			0x0215
+/* output bits setting */
+#define REG_0x0112					0x0112
+#define REG_0x0113					0x0113
+/* PLL registers */
+#define REG_VT_PIX_CLK_DIV				0x0301
+#define REG_PRE_PLL_CLK_DIV				0x0305
+#define REG_PLL_MULTIPLIER				0x0307
+#define REG_OP_PIX_CLK_DIV				0x0309
+#define REG_0x034c					0x034c
+#define REG_0x034d					0x034d
+#define REG_0x034e					0x034e
+#define REG_0x034f					0x034f
+#define REG_0x0387					0x0387
+#define REG_0x0383					0x0383
+#define REG_FRAME_LENGTH_LINES_HI			0x0340
+#define REG_FRAME_LENGTH_LINES_LO			0x0341
+#define REG_LINE_LENGTH_PCK_HI				0x0342
+#define REG_LINE_LENGTH_PCK_LO				0x0343
+#define REG_0x3030					0x3030
+#define REG_0x0111					0x0111
+#define REG_0x0136					0x0136
+#define REG_0x0137					0x0137
+#define REG_0x0b00					0x0b00
+#define REG_0x3001					0x3001
+#define REG_0x3004					0x3004
+#define REG_0x3007					0x3007
+#define REG_0x301a					0x301a
+#define REG_0x3101					0x3101
+#define REG_0x3364					0x3364
+#define REG_0x3365					0x3365
+#define REG_0x0b83					0x0b83
+#define REG_0x0b84					0x0b84
+#define REG_0x0b85					0x0b85
+#define REG_0x0b88					0x0b88
+#define REG_0x0b89					0x0b89
+#define REG_0x0b8a					0x0b8a
+#define REG_0x3005					0x3005
+#define REG_0x3010					0x3010
+#define REG_0x3036					0x3036
+#define REG_0x3041					0x3041
+#define REG_0x0b80					0x0b80
+#define REG_0x0900					0x0900
+#define REG_0x0901					0x0901
+#define REG_0x0902					0x0902
+#define REG_0x3016					0x3016
+#define REG_0x301d					0x301d
+#define REG_0x317e					0x317e
+#define REG_0x317f					0x317f
+#define REG_0x3400					0x3400
+#define REG_0x303a					0x303a
+#define REG_0x1716					0x1716
+#define REG_0x1717					0x1717
+#define REG_0x1718					0x1718
+#define REG_0x1719					0x1719
+#define REG_0x3006					0x3006
+#define REG_0x301b					0x301b
+#define REG_0x3098					0x3098
+#define REG_0x309d					0x309d
+#define REG_0x3011					0x3011
+#define REG_0x3035					0x3035
+#define REG_0x3045					0x3045
+#define REG_0x3210					0x3210
+#define	REG_0x0111					0x0111
+#define REG_0x3410					0x3410
+#define REG_0x0b06					0x0b06
+#define REG_0x0b07					0x0b07
+#define REG_0x0b08					0x0b08
+#define REG_0x0b09					0x0b09
+#define REG_0x3640					0x3640
+/* Test Pattern */
+#define REG_TEST_PATTERN_MODE				0x0601
+/* 16bit address - 8 bit context register structure */
+#define	VX6953_STM5M0EDOF_OFFSET	9
+#define	Q8		0x00000100
+#define	Q10		0x00000400
+#define	VX6953_STM5M0EDOF_MAX_SNAPSHOT_EXPOSURE_LINE_COUNT	2922
+#define	VX6953_STM5M0EDOF_DEFAULT_MASTER_CLK_RATE	24000000
+#define	VX6953_STM5M0EDOF_OP_PIXEL_CLOCK_RATE	79800000
+#define	VX6953_STM5M0EDOF_VT_PIXEL_CLOCK_RATE	88670000
+/* Full	Size */
+#define	VX6953_FULL_SIZE_WIDTH	2608
+#define	VX6953_FULL_SIZE_HEIGHT		1960
+#define	VX6953_FULL_SIZE_DUMMY_PIXELS	1
+#define	VX6953_FULL_SIZE_DUMMY_LINES	0
+/* Quarter Size	*/
+#define	VX6953_QTR_SIZE_WIDTH	1304
+#define	VX6953_QTR_SIZE_HEIGHT		980
+#define	VX6953_QTR_SIZE_DUMMY_PIXELS	1
+#define	VX6953_QTR_SIZE_DUMMY_LINES		0
+/* Blanking	as measured	on the scope */
+/* Full	Size */
+#define	VX6953_HRZ_FULL_BLK_PIXELS	348
+#define	VX6953_VER_FULL_BLK_LINES	40
+/* Quarter Size	*/
+#define	VX6953_HRZ_QTR_BLK_PIXELS	1628
+#define	VX6953_VER_QTR_BLK_LINES	28
+#define	MAX_LINE_LENGTH_PCK		8190
+#define	MAX_FRAME_LENGTH_LINES	16383
+#define	VX6953_REVISION_NUMBER_CUT2	0x10/*revision number	for	Cut2.0*/
+#define	VX6953_REVISION_NUMBER_CUT3	0x20/*revision number	for	Cut3.0*/
+static struct msm_sensor_ctrl_t vx6953_s_ctrl;
+static uint32_t fps_divider;/* init to 1 * 0x00000400 */
+static uint16_t fps;
+static uint8_t vx6953_stm5m0edof_delay_msecs_stdby;
+static struct msm_camera_i2c_reg_conf vx6953_start_settings[] = {
+	{0x0100, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf vx6953_stop_settings[] = {
+	{0x0100, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf vx6953_groupon_settings[] = {
+	{0x0104, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf vx6953_groupoff_settings[] = {
+	{0x0104, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf vx6953_prev_settings[] = {
+	{0x0202, 0x03},/*REG = 0x0202 coarse integration_time_hi*/
+	{0x0203, 0xD0},/*REG = 0x0203 coarse_integration_time_lo*/
+	{0x0205, 0xC0},/*REG = 0x0205 analogue_gain_code_global*/
+	{0x0340, 0x03},/*REG = 0x0340 frame_length_lines_hi*/
+	{0x0341, 0xf0},/*REG = 0x0341 frame_length_lines_lo*/
+	{0x0342, 0x0b},/*REG = 0x0342  line_length_pck_hi*/
+	{0x0343, 0x74},/*REG = 0x0343  line_length_pck_lo*/
+	{0x3005, 0x03},/*REG = 0x3005*/
+	{0x3010, 0x00},/*REG = 0x3010*/
+	{0x3011, 0x01},/*REG = 0x3011*/
+	{0x301a, 0x6a},/*REG = 0x301a*/
+	{0x3035, 0x03},/*REG = 0x3035*/
+	{0x3036, 0x2c},/*REG = 0x3036*/
+	{0x3041, 0x00},/*REG = 0x3041*/
+	{0x3042, 0x24},/*REG = 0x3042*/
+	{0x3045, 0x81},/*REG = 0x3045*/
+	{0x0b80, 0x02},/*REG = 0x0b80 edof estimate*/
+	{0x0900, 0x01},/*REG = 0x0900*/
+	{0x0901, 0x22},/*REG = 0x0901*/
+	{0x0902, 0x04},/*REG = 0x0902*/
+	{0x0383, 0x03},/*REG = 0x0383*/
+	{0x0387, 0x03},/*REG = 0x0387*/
+	{0x034c, 0x05},/*REG = 0x034c*/
+	{0x034d, 0x18},/*REG = 0x034d*/
+	{0x034e, 0x03},/*REG = 0x034e*/
+	{0x034f, 0xd4},/*REG = 0x034f*/
+	{0x1716, 0x02},/*0x1716*/
+	{0x1717, 0x04},/*0x1717*/
+	{0x1718, 0x08},/*0x1718*/
+	{0x1719, 0x2c},/*0x1719*/
+};
+
+static struct msm_camera_i2c_reg_conf vx6953_snap_settings[] = {
+	{0x0202, 0x07},/*REG = 0x0202 coarse_integration_time_hi*/
+	{0x0203, 0x00},/*REG = 0x0203 coarse_integration_time_lo*/
+	{0x0205, 0xc0},/*REG = 0x0205 analogue_gain_code_global*/
+	{0x0340, 0x07},/*REG = 0x0340 frame_length_lines_hi*/
+	{0x0341, 0xd0},/*REG = 0x0341 frame_length_lines_lo*/
+	{0x0342, 0x0b},/*REG = 0x0342 line_length_pck_hi*/
+	{0x0343, 0x8c},/*REG = 0x0343 line_length_pck_lo*/
+	{0x3005, 0x01},/*REG = 0x3005*/
+	{0x3010, 0x00},/*REG = 0x3010*/
+	{0x3011, 0x00},/*REG = 0x3011*/
+	{0x301a, 0x55},/*REG = 0x301a*/
+	{0x3035, 0x01},/*REG = 0x3035*/
+	{0x3036, 0x23},/*REG = 0x3036*/
+	{0x3041, 0x00},/*REG = 0x3041*/
+	{0x3042, 0x24},/*REG = 0x3042*/
+	{0x3045, 0xb7},/*REG = 0x3045*/
+	{0x0b80, 0x01},/*REG = 0x0b80 edof application*/
+	{0x0900, 0x00},/*REG = 0x0900*/
+	{0x0901, 0x00},/*REG = 0x0901*/
+	{0x0902, 0x00},/*REG = 0x0902*/
+	{0x0383, 0x01},/*REG = 0x0383*/
+	{0x0387, 0x01},/*REG = 0x0387*/
+	{0x034c, 0x0A},/*REG = 0x034c*/
+	{0x034d, 0x30},/*REG = 0x034d*/
+	{0x034e, 0x07},/*REG = 0x034e*/
+	{0x034f, 0xA8},/*REG = 0x034f*/
+	{0x1716, 0x02},/*0x1716*/
+	{0x1717, 0x0d},/*0x1717*/
+	{0x1718, 0x07},/*0x1718*/
+	{0x1719, 0x7d},/*0x1719*/
+};
+
+static struct msm_camera_i2c_reg_conf vx6953_recommend_settings[] = {
+	{0x0103, 0x01}, /* standby */
+	{0x0100, 0x00}, /* stop streaming */
+	/* patch cut 2*/
+	{0xFB94, 0},	/*intialise Data Xfer Status reg*/
+	{0xFB95, 0},	/*gain 1	  (0x00)*/
+	{0xFB96, 0},	/*gain 1.07   (0x10)*/
+	{0xFB97, 0},	/*gain 1.14   (0x20)*/
+	{0xFB98, 0},	/*gain 1.23   (0x30)*/
+	{0xFB99, 0},	/*gain 1.33   (0x40)*/
+	{0xFB9A, 0},	/*gain 1.45   (0x50)*/
+	{0xFB9B, 0},	/*gain 1.6    (0x60)*/
+	{0xFB9C, 0},	/*gain 1.78   (0x70)*/
+	{0xFB9D, 2},	/*gain 2	  (0x80)*/
+	{0xFB9E, 2},	/*gain 2.29   (0x90)*/
+	{0xFB9F, 3},	/*gain 2.67   (0xA0)*/
+	{0xFBA0, 3},	/*gain 3.2    (0xB0)*/
+	{0xFBA1, 4},	/*gain 4	  (0xC0)*/
+	{0xFBA2, 7},	/*gain 5.33   (0xD0)*/
+	{0xFBA3, 10},	/*gain 8	  (0xE0)*/
+	{0xFBA4, 11},	/*gain 9.14   (0xE4)*/
+	{0xFBA5, 13},	/*gain 10.67  (0xE8)*/
+	{0xFBA6, 15},	/*gain 12.8   (0xEC)*/
+	{0xFBA7, 19},	/*gain 16     (0xF0)*/
+	{0xF800, 0x12},
+	{0xF801, 0x06},
+	{0xF802, 0xf7},
+	{0xF803, 0x90},
+	{0xF804, 0x02},
+	{0xF805, 0x05},
+	{0xF806, 0xe0},
+	{0xF807, 0xff},
+	{0xF808, 0x65},
+	{0xF809, 0x7d},
+	{0xF80A, 0x70},
+	{0xF80B, 0x03},
+	{0xF80C, 0x02},
+	{0xF80D, 0xf9},
+	{0xF80E, 0x1c},
+	{0xF80F, 0x8f},
+	{0xF810, 0x7d},
+	{0xF811, 0xe4},
+	{0xF812, 0xf5},
+	{0xF813, 0x7a},
+	{0xF814, 0x75},
+	{0xF815, 0x78},
+	{0xF816, 0x30},
+	{0xF817, 0x75},
+	{0xF818, 0x79},
+	{0xF819, 0x53},
+	{0xF81A, 0x85},
+	{0xF81B, 0x79},
+	{0xF81C, 0x82},
+	{0xF81D, 0x85},
+	{0xF81E, 0x78},
+	{0xF81F, 0x83},
+	{0xF820, 0xe0},
+	{0xF821, 0xc3},
+	{0xF822, 0x95},
+	{0xF823, 0x7b},
+	{0xF824, 0xf0},
+	{0xF825, 0x74},
+	{0xF826, 0x02},
+	{0xF827, 0x25},
+	{0xF828, 0x79},
+	{0xF829, 0xf5},
+	{0xF82A, 0x79},
+	{0xF82B, 0xe4},
+	{0xF82C, 0x35},
+	{0xF82D, 0x78},
+	{0xF82E, 0xf5},
+	{0xF82F, 0x78},
+	{0xF830, 0x05},
+	{0xF831, 0x7a},
+	{0xF832, 0xe5},
+	{0xF833, 0x7a},
+	{0xF834, 0xb4},
+	{0xF835, 0x08},
+	{0xF836, 0xe3},
+	{0xF837, 0xe5},
+	{0xF838, 0x7d},
+	{0xF839, 0x70},
+	{0xF83A, 0x04},
+	{0xF83B, 0xff},
+	{0xF83C, 0x02},
+	{0xF83D, 0xf8},
+	{0xF83E, 0xe4},
+	{0xF83F, 0xe5},
+	{0xF840, 0x7d},
+	{0xF841, 0xb4},
+	{0xF842, 0x10},
+	{0xF843, 0x05},
+	{0xF844, 0x7f},
+	{0xF845, 0x01},
+	{0xF846, 0x02},
+	{0xF847, 0xf8},
+	{0xF848, 0xe4},
+	{0xF849, 0xe5},
+	{0xF84A, 0x7d},
+	{0xF84B, 0xb4},
+	{0xF84C, 0x20},
+	{0xF84D, 0x05},
+	{0xF84E, 0x7f},
+	{0xF84F, 0x02},
+	{0xF850, 0x02},
+	{0xF851, 0xf8},
+	{0xF852, 0xe4},
+	{0xF853, 0xe5},
+	{0xF854, 0x7d},
+	{0xF855, 0xb4},
+	{0xF856, 0x30},
+	{0xF857, 0x05},
+	{0xF858, 0x7f},
+	{0xF859, 0x03},
+	{0xF85A, 0x02},
+	{0xF85B, 0xf8},
+	{0xF85C, 0xe4},
+	{0xF85D, 0xe5},
+	{0xF85E, 0x7d},
+	{0xF85F, 0xb4},
+	{0xF860, 0x40},
+	{0xF861, 0x04},
+	{0xF862, 0x7f},
+	{0xF863, 0x04},
+	{0xF864, 0x80},
+	{0xF865, 0x7e},
+	{0xF866, 0xe5},
+	{0xF867, 0x7d},
+	{0xF868, 0xb4},
+	{0xF869, 0x50},
+	{0xF86A, 0x04},
+	{0xF86B, 0x7f},
+	{0xF86C, 0x05},
+	{0xF86D, 0x80},
+	{0xF86E, 0x75},
+	{0xF86F, 0xe5},
+	{0xF870, 0x7d},
+	{0xF871, 0xb4},
+	{0xF872, 0x60},
+	{0xF873, 0x04},
+	{0xF874, 0x7f},
+	{0xF875, 0x06},
+	{0xF876, 0x80},
+	{0xF877, 0x6c},
+	{0xF878, 0xe5},
+	{0xF879, 0x7d},
+	{0xF87A, 0xb4},
+	{0xF87B, 0x70},
+	{0xF87C, 0x04},
+	{0xF87D, 0x7f},
+	{0xF87E, 0x07},
+	{0xF87F, 0x80},
+	{0xF880, 0x63},
+	{0xF881, 0xe5},
+	{0xF882, 0x7d},
+	{0xF883, 0xb4},
+	{0xF884, 0x80},
+	{0xF885, 0x04},
+	{0xF886, 0x7f},
+	{0xF887, 0x08},
+	{0xF888, 0x80},
+	{0xF889, 0x5a},
+	{0xF88A, 0xe5},
+	{0xF88B, 0x7d},
+	{0xF88C, 0xb4},
+	{0xF88D, 0x90},
+	{0xF88E, 0x04},
+	{0xF88F, 0x7f},
+	{0xF890, 0x09},
+	{0xF891, 0x80},
+	{0xF892, 0x51},
+	{0xF893, 0xe5},
+	{0xF894, 0x7d},
+	{0xF895, 0xb4},
+	{0xF896, 0xa0},
+	{0xF897, 0x04},
+	{0xF898, 0x7f},
+	{0xF899, 0x0a},
+	{0xF89A, 0x80},
+	{0xF89B, 0x48},
+	{0xF89C, 0xe5},
+	{0xF89D, 0x7d},
+	{0xF89E, 0xb4},
+	{0xF89F, 0xb0},
+	{0xF8A0, 0x04},
+	{0xF8A1, 0x7f},
+	{0xF8A2, 0x0b},
+	{0xF8A3, 0x80},
+	{0xF8A4, 0x3f},
+	{0xF8A5, 0xe5},
+	{0xF8A6, 0x7d},
+	{0xF8A7, 0xb4},
+	{0xF8A8, 0xc0},
+	{0xF8A9, 0x04},
+	{0xF8AA, 0x7f},
+	{0xF8AB, 0x0c},
+	{0xF8AC, 0x80},
+	{0xF8AD, 0x36},
+	{0xF8AE, 0xe5},
+	{0xF8AF, 0x7d},
+	{0xF8B0, 0xb4},
+	{0xF8B1, 0xd0},
+	{0xF8B2, 0x04},
+	{0xF8B3, 0x7f},
+	{0xF8B4, 0x0d},
+	{0xF8B5, 0x80},
+	{0xF8B6, 0x2d},
+	{0xF8B7, 0xe5},
+	{0xF8B8, 0x7d},
+	{0xF8B9, 0xb4},
+	{0xF8BA, 0xe0},
+	{0xF8BB, 0x04},
+	{0xF8BC, 0x7f},
+	{0xF8BD, 0x0e},
+	{0xF8BE, 0x80},
+	{0xF8BF, 0x24},
+	{0xF8C0, 0xe5},
+	{0xF8C1, 0x7d},
+	{0xF8C2, 0xb4},
+	{0xF8C3, 0xe4},
+	{0xF8C4, 0x04},
+	{0xF8C5, 0x7f},
+	{0xF8C6, 0x0f},
+	{0xF8C7, 0x80},
+	{0xF8C8, 0x1b},
+	{0xF8C9, 0xe5},
+	{0xF8CA, 0x7d},
+	{0xF8CB, 0xb4},
+	{0xF8CC, 0xe8},
+	{0xF8CD, 0x04},
+	{0xF8CE, 0x7f},
+	{0xF8CF, 0x10},
+	{0xF8D0, 0x80},
+	{0xF8D1, 0x12},
+	{0xF8D2, 0xe5},
+	{0xF8D3, 0x7d},
+	{0xF8D4, 0xb4},
+	{0xF8D5, 0xec},
+	{0xF8D6, 0x04},
+	{0xF8D7, 0x7f},
+	{0xF8D8, 0x11},
+	{0xF8D9, 0x80},
+	{0xF8DA, 0x09},
+	{0xF8DB, 0xe5},
+	{0xF8DC, 0x7d},
+	{0xF8DD, 0x7f},
+	{0xF8DE, 0x00},
+	{0xF8DF, 0xb4},
+	{0xF8E0, 0xf0},
+	{0xF8E1, 0x02},
+	{0xF8E2, 0x7f},
+	{0xF8E3, 0x12},
+	{0xF8E4, 0x8f},
+	{0xF8E5, 0x7c},
+	{0xF8E6, 0xef},
+	{0xF8E7, 0x24},
+	{0xF8E8, 0x95},
+	{0xF8E9, 0xff},
+	{0xF8EA, 0xe4},
+	{0xF8EB, 0x34},
+	{0xF8EC, 0xfb},
+	{0xF8ED, 0x8f},
+	{0xF8EE, 0x82},
+	{0xF8EF, 0xf5},
+	{0xF8F0, 0x83},
+	{0xF8F1, 0xe4},
+	{0xF8F2, 0x93},
+	{0xF8F3, 0xf5},
+	{0xF8F4, 0x7c},
+	{0xF8F5, 0xf5},
+	{0xF8F6, 0x7b},
+	{0xF8F7, 0xe4},
+	{0xF8F8, 0xf5},
+	{0xF8F9, 0x7a},
+	{0xF8FA, 0x75},
+	{0xF8FB, 0x78},
+	{0xF8FC, 0x30},
+	{0xF8FD, 0x75},
+	{0xF8FE, 0x79},
+	{0xF8FF, 0x53},
+	{0xF900, 0x85},
+	{0xF901, 0x79},
+	{0xF902, 0x82},
+	{0xF903, 0x85},
+	{0xF904, 0x78},
+	{0xF905, 0x83},
+	{0xF906, 0xe0},
+	{0xF907, 0x25},
+	{0xF908, 0x7c},
+	{0xF909, 0xf0},
+	{0xF90A, 0x74},
+	{0xF90B, 0x02},
+	{0xF90C, 0x25},
+	{0xF90D, 0x79},
+	{0xF90E, 0xf5},
+	{0xF90F, 0x79},
+	{0xF910, 0xe4},
+	{0xF911, 0x35},
+	{0xF912, 0x78},
+	{0xF913, 0xf5},
+	{0xF914, 0x78},
+	{0xF915, 0x05},
+	{0xF916, 0x7a},
+	{0xF917, 0xe5},
+	{0xF918, 0x7a},
+	{0xF919, 0xb4},
+	{0xF91A, 0x08},
+	{0xF91B, 0xe4},
+	{0xF91C, 0x02},
+	{0xF91D, 0x18},
+	{0xF91E, 0x32},
+	{0xF91F, 0x22},
+	{0xF920, 0xf0},
+	{0xF921, 0x90},
+	{0xF922, 0xa0},
+	{0xF923, 0xf8},
+	{0xF924, 0xe0},
+	{0xF925, 0x70},
+	{0xF926, 0x02},
+	{0xF927, 0xa3},
+	{0xF928, 0xe0},
+	{0xF929, 0x70},
+	{0xF92A, 0x0a},
+	{0xF92B, 0x90},
+	{0xF92C, 0xa1},
+	{0xF92D, 0x10},
+	{0xF92E, 0xe0},
+	{0xF92F, 0xfe},
+	{0xF930, 0xa3},
+	{0xF931, 0xe0},
+	{0xF932, 0xff},
+	{0xF933, 0x80},
+	{0xF934, 0x04},
+	{0xF935, 0x7e},
+	{0xF936, 0x00},
+	{0xF937, 0x7f},
+	{0xF938, 0x00},
+	{0xF939, 0x8e},
+	{0xF93A, 0x7e},
+	{0xF93B, 0x8f},
+	{0xF93C, 0x7f},
+	{0xF93D, 0x90},
+	{0xF93E, 0x36},
+	{0xF93F, 0x0d},
+	{0xF940, 0xe0},
+	{0xF941, 0x44},
+	{0xF942, 0x02},
+	{0xF943, 0xf0},
+	{0xF944, 0x90},
+	{0xF945, 0x36},
+	{0xF946, 0x0e},
+	{0xF947, 0xe5},
+	{0xF948, 0x7e},
+	{0xF949, 0xf0},
+	{0xF94A, 0xa3},
+	{0xF94B, 0xe5},
+	{0xF94C, 0x7f},
+	{0xF94D, 0xf0},
+	{0xF94E, 0xe5},
+	{0xF94F, 0x3a},
+	{0xF950, 0x60},
+	{0xF951, 0x0c},
+	{0xF952, 0x90},
+	{0xF953, 0x36},
+	{0xF954, 0x09},
+	{0xF955, 0xe0},
+	{0xF956, 0x70},
+	{0xF957, 0x06},
+	{0xF958, 0x90},
+	{0xF959, 0x36},
+	{0xF95A, 0x08},
+	{0xF95B, 0xf0},
+	{0xF95C, 0xf5},
+	{0xF95D, 0x3a},
+	{0xF95E, 0x02},
+	{0xF95F, 0x03},
+	{0xF960, 0x94},
+	{0xF961, 0x22},
+	{0xF962, 0x78},
+	{0xF963, 0x07},
+	{0xF964, 0xe6},
+	{0xF965, 0xd3},
+	{0xF966, 0x94},
+	{0xF967, 0x00},
+	{0xF968, 0x40},
+	{0xF969, 0x16},
+	{0xF96A, 0x16},
+	{0xF96B, 0xe6},
+	{0xF96C, 0x90},
+	{0xF96D, 0x30},
+	{0xF96E, 0xa1},
+	{0xF96F, 0xf0},
+	{0xF970, 0x90},
+	{0xF971, 0x43},
+	{0xF972, 0x83},
+	{0xF973, 0xe0},
+	{0xF974, 0xb4},
+	{0xF975, 0x01},
+	{0xF976, 0x0f},
+	{0xF977, 0x90},
+	{0xF978, 0x43},
+	{0xF979, 0x87},
+	{0xF97A, 0xe0},
+	{0xF97B, 0xb4},
+	{0xF97C, 0x01},
+	{0xF97D, 0x08},
+	{0xF97E, 0x80},
+	{0xF97F, 0x00},
+	{0xF980, 0x90},
+	{0xF981, 0x30},
+	{0xF982, 0xa0},
+	{0xF983, 0x74},
+	{0xF984, 0x01},
+	{0xF985, 0xf0},
+	{0xF986, 0x22},
+	{0xF987, 0xf0},
+	{0xF988, 0x90},
+	{0xF989, 0x35},
+	{0xF98A, 0xba},
+	{0xF98B, 0xe0},
+	{0xF98C, 0xb4},
+	{0xF98D, 0x0a},
+	{0xF98E, 0x0d},
+	{0xF98F, 0xa3},
+	{0xF990, 0xe0},
+	{0xF991, 0xb4},
+	{0xF992, 0x01},
+	{0xF993, 0x08},
+	{0xF994, 0x90},
+	{0xF995, 0xfb},
+	{0xF996, 0x94},
+	{0xF997, 0xe0},
+	{0xF998, 0x90},
+	{0xF999, 0x35},
+	{0xF99A, 0xb8},
+	{0xF99B, 0xf0},
+	{0xF99C, 0xd0},
+	{0xF99D, 0xd0},
+	{0xF99E, 0xd0},
+	{0xF99F, 0x82},
+	{0xF9A0, 0xd0},
+	{0xF9A1, 0x83},
+	{0xF9A2, 0xd0},
+	{0xF9A3, 0xe0},
+	{0xF9A4, 0x32},
+	{0xF9A5, 0x22},
+	{0xF9A6, 0xe5},
+	{0xF9A7, 0x7f},
+	{0xF9A8, 0x45},
+	{0xF9A9, 0x7e},
+	{0xF9AA, 0x60},
+	{0xF9AB, 0x15},
+	{0xF9AC, 0x90},
+	{0xF9AD, 0x01},
+	{0xF9AE, 0x00},
+	{0xF9AF, 0xe0},
+	{0xF9B0, 0x70},
+	{0xF9B1, 0x0f},
+	{0xF9B2, 0x90},
+	{0xF9B3, 0xa0},
+	{0xF9B4, 0xf8},
+	{0xF9B5, 0xe5},
+	{0xF9B6, 0x7e},
+	{0xF9B7, 0xf0},
+	{0xF9B8, 0xa3},
+	{0xF9B9, 0xe5},
+	{0xF9BA, 0x7f},
+	{0xF9BB, 0xf0},
+	{0xF9BC, 0xe4},
+	{0xF9BD, 0xf5},
+	{0xF9BE, 0x7e},
+	{0xF9BF, 0xf5},
+	{0xF9C0, 0x7f},
+	{0xF9C1, 0x22},
+	{0xF9C2, 0x02},
+	{0xF9C3, 0x0e},
+	{0xF9C4, 0x79},
+	{0xF9C5, 0x22},
+	/* Offsets:*/
+	{0x35C6, 0x00},/* FIDDLEDARKCAL*/
+	{0x35C7, 0x00},
+	{0x35C8, 0x01},/*STOREDISTANCEATSTOPSTREAMING*/
+	{0x35C9, 0x20},
+	{0x35CA, 0x01},/*BRUCEFIX*/
+	{0x35CB, 0x62},
+	{0x35CC, 0x01},/*FIXDATAXFERSTATUSREG*/
+	{0x35CD, 0x87},
+	{0x35CE, 0x01},/*FOCUSDISTANCEUPDATE*/
+	{0x35CF, 0xA6},
+	{0x35D0, 0x01},/*SKIPEDOFRESET*/
+	{0x35D1, 0xC2},
+	{0x35D2, 0x00},
+	{0x35D3, 0xFB},
+	{0x35D4, 0x00},
+	{0x35D5, 0x94},
+	{0x35D6, 0x00},
+	{0x35D7, 0xFB},
+	{0x35D8, 0x00},
+	{0x35D9, 0x94},
+	{0x35DA, 0x00},
+	{0x35DB, 0xFB},
+	{0x35DC, 0x00},
+	{0x35DD, 0x94},
+	{0x35DE, 0x00},
+	{0x35DF, 0xFB},
+	{0x35E0, 0x00},
+	{0x35E1, 0x94},
+	{0x35E6, 0x18},/* FIDDLEDARKCAL*/
+	{0x35E7, 0x2F},
+	{0x35E8, 0x03},/* STOREDISTANCEATSTOPSTREAMING*/
+	{0x35E9, 0x93},
+	{0x35EA, 0x18},/* BRUCEFIX*/
+	{0x35EB, 0x99},
+	{0x35EC, 0x00},/* FIXDATAXFERSTATUSREG*/
+	{0x35ED, 0xA3},
+	{0x35EE, 0x21},/* FOCUSDISTANCEUPDATE*/
+	{0x35EF, 0x5B},
+	{0x35F0, 0x0E},/* SKIPEDOFRESET*/
+	{0x35F1, 0x74},
+	{0x35F2, 0x04},
+	{0x35F3, 0x64},
+	{0x35F4, 0x04},
+	{0x35F5, 0x65},
+	{0x35F6, 0x04},
+	{0x35F7, 0x7B},
+	{0x35F8, 0x04},
+	{0x35F9, 0x7C},
+	{0x35FA, 0x04},
+	{0x35FB, 0xDD},
+	{0x35FC, 0x04},
+	{0x35FD, 0xDE},
+	{0x35FE, 0x04},
+	{0x35FF, 0xEF},
+	{0x3600, 0x04},
+	{0x3601, 0xF0},
+	/*Jump/Data:*/
+	{0x35C2, 0x3F},/* Jump Reg*/
+	{0x35C3, 0xFF},/* Jump Reg*/
+	{0x35C4, 0x3F},/* Data Reg*/
+	{0x35C5, 0xC0},/* Data Reg*/
+	{0x35C0, 0x01},/* Enable*/
+	/* end of patch cut 2 */
+	/* common settings */
+	{0x0112, 10},/*REG = 0x0112 , 10 bit */
+	{0x0113, 10},/*REG = 0x0113*/
+	{0x0301, 9},/*REG = 0x0301 vt_pix_clk_div*/
+	{0x0305, 4},/*REG = 0x0305 pre_pll_clk_div*/
+	{0x0307, 133},/*REG = 0x0307 pll_multiplier*/
+	{0x0309, 10},/*REG = 0x0309 op_pix_clk_div*/
+	{0x3030, 0x08},/*REG = 0x3030*/
+	{0x0111, 0x02},/*REG = 0x0111*/
+	{0x0b00, 0x01},/*REG = 0x0b00 ,lens shading off */
+	{0x3001, 0x30},/*REG = 0x3001*/
+	{0x3004, 0x33},/*REG = 0x3004*/
+	{0x3007, 0x09},/*REG = 0x3007*/
+	{0x3016, 0x1F},/*REG = 0x3016*/
+	{0x301d, 0x03},/*REG = 0x301d*/
+	{0x317E, 0x11},/*REG = 0x317E*/
+	{0x317F, 0x09},/*REG = 0x317F*/
+	{0x3400, 0x38},/*REG = 0x3400*/
+	{0x0b06, 0x00},/*REG_0x0b06*/
+	{0x0b07, 0x80},/*REG_0x0b07*/
+	{0x0b08, 0x01},/*REG_0x0b08*/
+	{0x0b09, 0x4F},/*REG_0x0b09*/
+	{0x0136, 0x18},/*REG_0x0136*/
+	{0x0137, 0x00},/*/REG_0x0137*/
+	{0x0b83, 0x20},/*REG = 0x0b83*/
+	{0x0b84, 0x90},/*REG = 0x0b84*/
+	{0x0b85, 0x20},/*REG = 0x0b85*/
+	{0x0b88, 0x80},/*REG = 0x0b88*/
+	{0x0b89, 0x00},/*REG = 0x0b89*/
+	{0x0b8a, 0x00},/*REG = 0x0b8a*/
+	/* end of common settings */
+};
+
+static struct v4l2_subdev_info vx6953_subdev_info[] = {
+	{
+	.code   = V4L2_MBUS_FMT_SGRBG10_1X10,
+	.colorspace = V4L2_COLORSPACE_JPEG,
+	.fmt    = 1,
+	.order    = 0,
+	},
+	/* more can be supported, to be added later */
+};
+
+static struct msm_camera_i2c_conf_array vx6953_init_conf[] = {
+	{&vx6953_recommend_settings[0],
+	ARRAY_SIZE(vx6953_recommend_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}
+};
+
+static struct msm_camera_i2c_conf_array vx6953_confs[] = {
+	{&vx6953_snap_settings[0],
+	ARRAY_SIZE(vx6953_snap_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+	{&vx6953_prev_settings[0],
+	ARRAY_SIZE(vx6953_prev_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+};
+
+static struct msm_sensor_output_info_t vx6953_dimensions[] = {
+	{
+		.x_output = 0xA30,
+		.y_output = 0x7A8,
+		.line_length_pclk = 0xB8C,
+		.frame_length_lines = 0x7D0,
+		.vt_pixel_clk = 88666666,
+		.op_pixel_clk = 192000000,
+		.binning_factor = 1,
+	},
+	{
+		.x_output = 0x518,
+		.y_output = 0x3D4,
+		.line_length_pclk = 0xB74,
+		.frame_length_lines = 0x3F0,
+		.vt_pixel_clk = 88666666,
+		.op_pixel_clk = 192000000,
+		.binning_factor = 1,
+	},
+};
+
+static struct msm_sensor_output_reg_addr_t vx6953_reg_addr = {
+	.x_output = 0x034C,
+	.y_output = 0x034E,
+	.line_length_pclk = 0x0342,
+	.frame_length_lines = 0x0340,
+};
+
+static struct msm_sensor_id_info_t vx6953_id_info = {
+	.sensor_id_reg_addr = 0x0000,
+	.sensor_id = 0x03B9,
+};
+
+static struct msm_sensor_exp_gain_info_t vx6953_exp_gain_info = {
+	.coarse_int_time_addr = 0x0202,
+	.global_gain_addr = 0x0204,
+	.vert_offset = 9,
+};
+
+static const struct i2c_device_id vx6953_i2c_id[] = {
+	{SENSOR_NAME, (kernel_ulong_t)&vx6953_s_ctrl},
+	{ }
+};
+
+static struct i2c_driver vx6953_i2c_driver = {
+	.id_table = vx6953_i2c_id,
+	.probe  = msm_sensor_i2c_probe,
+	.driver = {
+		.name = SENSOR_NAME,
+	},
+};
+
+static struct msm_camera_i2c_client vx6953_sensor_i2c_client = {
+	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+static int __init msm_sensor_init_module(void)
+{
+	return i2c_add_driver(&vx6953_i2c_driver);
+}
+
+static int32_t vx6953_set_fps(struct msm_sensor_ctrl_t *s_ctrl,
+	struct fps_cfg *fps) {
+	return 0;
+}
+
+int32_t vx6953_write_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
+	uint16_t gain, uint32_t line) {
+	return 0;
+}
+
+static struct v4l2_subdev_core_ops vx6953_subdev_core_ops = {
+	.ioctl = msm_sensor_subdev_ioctl,
+	.s_power = msm_sensor_power,
+};
+
+static struct v4l2_subdev_video_ops vx6953_subdev_video_ops = {
+	.enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
+};
+
+static struct v4l2_subdev_ops vx6953_subdev_ops = {
+	.core = &vx6953_subdev_core_ops,
+	.video  = &vx6953_subdev_video_ops,
+};
+
+static struct msm_camera_i2c_reg_conf vx6953_edof_estimation[] = {
+	{REG_0x0b80, 0x02},
+};
+
+static struct msm_camera_i2c_reg_conf vx6953_edof_application[] = {
+	{REG_0x0b80, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf vx6953_edof_default[] = {
+	{REG_0x0b80, 0x00},
+};
+
+static int vx6953_enable_edof(enum edof_mode_t edof_mode)
+{
+	int rc = 0;
+	if (edof_mode == VX6953_EDOF_ESTIMATION) {
+		/* EDof Estimation mode for preview */
+		msm_camera_i2c_write_tbl(
+			vx6953_s_ctrl.sensor_i2c_client,
+			vx6953_edof_estimation,
+			ARRAY_SIZE(vx6953_edof_estimation),
+			vx6953_s_ctrl.msm_sensor_reg->default_data_type);
+		CDBG("VX6953_EDOF_ESTIMATION");
+	} else if (edof_mode == VX6953_EDOF_APPLICATION) {
+		/* EDof Application mode for Capture */
+		msm_camera_i2c_write_tbl(
+			vx6953_s_ctrl.sensor_i2c_client,
+			vx6953_edof_application,
+			ARRAY_SIZE(vx6953_edof_application),
+			vx6953_s_ctrl.msm_sensor_reg->default_data_type);
+		CDBG("VX6953_EDOF_APPLICATION");
+	} else {
+		/* EDOF disabled */
+		msm_camera_i2c_write_tbl(
+			vx6953_s_ctrl.sensor_i2c_client,
+			vx6953_edof_default,
+			ARRAY_SIZE(vx6953_edof_default),
+			vx6953_s_ctrl.msm_sensor_reg->default_data_type);
+		CDBG("VX6953_EDOF_DISABLE");
+	}
+	return rc;
+}
+
+static struct msm_camera_i2c_reg_conf vx6953_standby[] = {
+	{0x103, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf patch_tbl_cut2[] = {
+	{0xFB94, 0},	/*intialise Data Xfer Status reg*/
+	{0xFB95, 0},	/*gain 1	  (0x00)*/
+	{0xFB96, 0},	/*gain 1.07   (0x10)*/
+	{0xFB97, 0},	/*gain 1.14   (0x20)*/
+	{0xFB98, 0},	/*gain 1.23   (0x30)*/
+	{0xFB99, 0},	/*gain 1.33   (0x40)*/
+	{0xFB9A, 0},	/*gain 1.45   (0x50)*/
+	{0xFB9B, 0},	/*gain 1.6    (0x60)*/
+	{0xFB9C, 0},	/*gain 1.78   (0x70)*/
+	{0xFB9D, 2},	/*gain 2	  (0x80)*/
+	{0xFB9E, 2},	/*gain 2.29   (0x90)*/
+	{0xFB9F, 3},	/*gain 2.67   (0xA0)*/
+	{0xFBA0, 3},	/*gain 3.2    (0xB0)*/
+	{0xFBA1, 4},	/*gain 4	  (0xC0)*/
+	{0xFBA2, 7},	/*gain 5.33   (0xD0)*/
+	{0xFBA3, 10},	/*gain 8	  (0xE0)*/
+	{0xFBA4, 11},	/*gain 9.14   (0xE4)*/
+	{0xFBA5, 13},	/*gain 10.67  (0xE8)*/
+	{0xFBA6, 15},	/*gain 12.8   (0xEC)*/
+	{0xFBA7, 19},	/*gain 16     (0xF0)*/
+	{0xF800, 0x12},
+	{0xF801, 0x06},
+	{0xF802, 0xf7},
+	{0xF803, 0x90},
+	{0xF804, 0x02},
+	{0xF805, 0x05},
+	{0xF806, 0xe0},
+	{0xF807, 0xff},
+	{0xF808, 0x65},
+	{0xF809, 0x7d},
+	{0xF80A, 0x70},
+	{0xF80B, 0x03},
+	{0xF80C, 0x02},
+	{0xF80D, 0xf9},
+	{0xF80E, 0x1c},
+	{0xF80F, 0x8f},
+	{0xF810, 0x7d},
+	{0xF811, 0xe4},
+	{0xF812, 0xf5},
+	{0xF813, 0x7a},
+	{0xF814, 0x75},
+	{0xF815, 0x78},
+	{0xF816, 0x30},
+	{0xF817, 0x75},
+	{0xF818, 0x79},
+	{0xF819, 0x53},
+	{0xF81A, 0x85},
+	{0xF81B, 0x79},
+	{0xF81C, 0x82},
+	{0xF81D, 0x85},
+	{0xF81E, 0x78},
+	{0xF81F, 0x83},
+	{0xF820, 0xe0},
+	{0xF821, 0xc3},
+	{0xF822, 0x95},
+	{0xF823, 0x7b},
+	{0xF824, 0xf0},
+	{0xF825, 0x74},
+	{0xF826, 0x02},
+	{0xF827, 0x25},
+	{0xF828, 0x79},
+	{0xF829, 0xf5},
+	{0xF82A, 0x79},
+	{0xF82B, 0xe4},
+	{0xF82C, 0x35},
+	{0xF82D, 0x78},
+	{0xF82E, 0xf5},
+	{0xF82F, 0x78},
+	{0xF830, 0x05},
+	{0xF831, 0x7a},
+	{0xF832, 0xe5},
+	{0xF833, 0x7a},
+	{0xF834, 0xb4},
+	{0xF835, 0x08},
+	{0xF836, 0xe3},
+	{0xF837, 0xe5},
+	{0xF838, 0x7d},
+	{0xF839, 0x70},
+	{0xF83A, 0x04},
+	{0xF83B, 0xff},
+	{0xF83C, 0x02},
+	{0xF83D, 0xf8},
+	{0xF83E, 0xe4},
+	{0xF83F, 0xe5},
+	{0xF840, 0x7d},
+	{0xF841, 0xb4},
+	{0xF842, 0x10},
+	{0xF843, 0x05},
+	{0xF844, 0x7f},
+	{0xF845, 0x01},
+	{0xF846, 0x02},
+	{0xF847, 0xf8},
+	{0xF848, 0xe4},
+	{0xF849, 0xe5},
+	{0xF84A, 0x7d},
+	{0xF84B, 0xb4},
+	{0xF84C, 0x20},
+	{0xF84D, 0x05},
+	{0xF84E, 0x7f},
+	{0xF84F, 0x02},
+	{0xF850, 0x02},
+	{0xF851, 0xf8},
+	{0xF852, 0xe4},
+	{0xF853, 0xe5},
+	{0xF854, 0x7d},
+	{0xF855, 0xb4},
+	{0xF856, 0x30},
+	{0xF857, 0x05},
+	{0xF858, 0x7f},
+	{0xF859, 0x03},
+	{0xF85A, 0x02},
+	{0xF85B, 0xf8},
+	{0xF85C, 0xe4},
+	{0xF85D, 0xe5},
+	{0xF85E, 0x7d},
+	{0xF85F, 0xb4},
+	{0xF860, 0x40},
+	{0xF861, 0x04},
+	{0xF862, 0x7f},
+	{0xF863, 0x04},
+	{0xF864, 0x80},
+	{0xF865, 0x7e},
+	{0xF866, 0xe5},
+	{0xF867, 0x7d},
+	{0xF868, 0xb4},
+	{0xF869, 0x50},
+	{0xF86A, 0x04},
+	{0xF86B, 0x7f},
+	{0xF86C, 0x05},
+	{0xF86D, 0x80},
+	{0xF86E, 0x75},
+	{0xF86F, 0xe5},
+	{0xF870, 0x7d},
+	{0xF871, 0xb4},
+	{0xF872, 0x60},
+	{0xF873, 0x04},
+	{0xF874, 0x7f},
+	{0xF875, 0x06},
+	{0xF876, 0x80},
+	{0xF877, 0x6c},
+	{0xF878, 0xe5},
+	{0xF879, 0x7d},
+	{0xF87A, 0xb4},
+	{0xF87B, 0x70},
+	{0xF87C, 0x04},
+	{0xF87D, 0x7f},
+	{0xF87E, 0x07},
+	{0xF87F, 0x80},
+	{0xF880, 0x63},
+	{0xF881, 0xe5},
+	{0xF882, 0x7d},
+	{0xF883, 0xb4},
+	{0xF884, 0x80},
+	{0xF885, 0x04},
+	{0xF886, 0x7f},
+	{0xF887, 0x08},
+	{0xF888, 0x80},
+	{0xF889, 0x5a},
+	{0xF88A, 0xe5},
+	{0xF88B, 0x7d},
+	{0xF88C, 0xb4},
+	{0xF88D, 0x90},
+	{0xF88E, 0x04},
+	{0xF88F, 0x7f},
+	{0xF890, 0x09},
+	{0xF891, 0x80},
+	{0xF892, 0x51},
+	{0xF893, 0xe5},
+	{0xF894, 0x7d},
+	{0xF895, 0xb4},
+	{0xF896, 0xa0},
+	{0xF897, 0x04},
+	{0xF898, 0x7f},
+	{0xF899, 0x0a},
+	{0xF89A, 0x80},
+	{0xF89B, 0x48},
+	{0xF89C, 0xe5},
+	{0xF89D, 0x7d},
+	{0xF89E, 0xb4},
+	{0xF89F, 0xb0},
+	{0xF8A0, 0x04},
+	{0xF8A1, 0x7f},
+	{0xF8A2, 0x0b},
+	{0xF8A3, 0x80},
+	{0xF8A4, 0x3f},
+	{0xF8A5, 0xe5},
+	{0xF8A6, 0x7d},
+	{0xF8A7, 0xb4},
+	{0xF8A8, 0xc0},
+	{0xF8A9, 0x04},
+	{0xF8AA, 0x7f},
+	{0xF8AB, 0x0c},
+	{0xF8AC, 0x80},
+	{0xF8AD, 0x36},
+	{0xF8AE, 0xe5},
+	{0xF8AF, 0x7d},
+	{0xF8B0, 0xb4},
+	{0xF8B1, 0xd0},
+	{0xF8B2, 0x04},
+	{0xF8B3, 0x7f},
+	{0xF8B4, 0x0d},
+	{0xF8B5, 0x80},
+	{0xF8B6, 0x2d},
+	{0xF8B7, 0xe5},
+	{0xF8B8, 0x7d},
+	{0xF8B9, 0xb4},
+	{0xF8BA, 0xe0},
+	{0xF8BB, 0x04},
+	{0xF8BC, 0x7f},
+	{0xF8BD, 0x0e},
+	{0xF8BE, 0x80},
+	{0xF8BF, 0x24},
+	{0xF8C0, 0xe5},
+	{0xF8C1, 0x7d},
+	{0xF8C2, 0xb4},
+	{0xF8C3, 0xe4},
+	{0xF8C4, 0x04},
+	{0xF8C5, 0x7f},
+	{0xF8C6, 0x0f},
+	{0xF8C7, 0x80},
+	{0xF8C8, 0x1b},
+	{0xF8C9, 0xe5},
+	{0xF8CA, 0x7d},
+	{0xF8CB, 0xb4},
+	{0xF8CC, 0xe8},
+	{0xF8CD, 0x04},
+	{0xF8CE, 0x7f},
+	{0xF8CF, 0x10},
+	{0xF8D0, 0x80},
+	{0xF8D1, 0x12},
+	{0xF8D2, 0xe5},
+	{0xF8D3, 0x7d},
+	{0xF8D4, 0xb4},
+	{0xF8D5, 0xec},
+	{0xF8D6, 0x04},
+	{0xF8D7, 0x7f},
+	{0xF8D8, 0x11},
+	{0xF8D9, 0x80},
+	{0xF8DA, 0x09},
+	{0xF8DB, 0xe5},
+	{0xF8DC, 0x7d},
+	{0xF8DD, 0x7f},
+	{0xF8DE, 0x00},
+	{0xF8DF, 0xb4},
+	{0xF8E0, 0xf0},
+	{0xF8E1, 0x02},
+	{0xF8E2, 0x7f},
+	{0xF8E3, 0x12},
+	{0xF8E4, 0x8f},
+	{0xF8E5, 0x7c},
+	{0xF8E6, 0xef},
+	{0xF8E7, 0x24},
+	{0xF8E8, 0x95},
+	{0xF8E9, 0xff},
+	{0xF8EA, 0xe4},
+	{0xF8EB, 0x34},
+	{0xF8EC, 0xfb},
+	{0xF8ED, 0x8f},
+	{0xF8EE, 0x82},
+	{0xF8EF, 0xf5},
+	{0xF8F0, 0x83},
+	{0xF8F1, 0xe4},
+	{0xF8F2, 0x93},
+	{0xF8F3, 0xf5},
+	{0xF8F4, 0x7c},
+	{0xF8F5, 0xf5},
+	{0xF8F6, 0x7b},
+	{0xF8F7, 0xe4},
+	{0xF8F8, 0xf5},
+	{0xF8F9, 0x7a},
+	{0xF8FA, 0x75},
+	{0xF8FB, 0x78},
+	{0xF8FC, 0x30},
+	{0xF8FD, 0x75},
+	{0xF8FE, 0x79},
+	{0xF8FF, 0x53},
+	{0xF900, 0x85},
+	{0xF901, 0x79},
+	{0xF902, 0x82},
+	{0xF903, 0x85},
+	{0xF904, 0x78},
+	{0xF905, 0x83},
+	{0xF906, 0xe0},
+	{0xF907, 0x25},
+	{0xF908, 0x7c},
+	{0xF909, 0xf0},
+	{0xF90A, 0x74},
+	{0xF90B, 0x02},
+	{0xF90C, 0x25},
+	{0xF90D, 0x79},
+	{0xF90E, 0xf5},
+	{0xF90F, 0x79},
+	{0xF910, 0xe4},
+	{0xF911, 0x35},
+	{0xF912, 0x78},
+	{0xF913, 0xf5},
+	{0xF914, 0x78},
+	{0xF915, 0x05},
+	{0xF916, 0x7a},
+	{0xF917, 0xe5},
+	{0xF918, 0x7a},
+	{0xF919, 0xb4},
+	{0xF91A, 0x08},
+	{0xF91B, 0xe4},
+	{0xF91C, 0x02},
+	{0xF91D, 0x18},
+	{0xF91E, 0x32},
+	{0xF91F, 0x22},
+	{0xF920, 0xf0},
+	{0xF921, 0x90},
+	{0xF922, 0xa0},
+	{0xF923, 0xf8},
+	{0xF924, 0xe0},
+	{0xF925, 0x70},
+	{0xF926, 0x02},
+	{0xF927, 0xa3},
+	{0xF928, 0xe0},
+	{0xF929, 0x70},
+	{0xF92A, 0x0a},
+	{0xF92B, 0x90},
+	{0xF92C, 0xa1},
+	{0xF92D, 0x10},
+	{0xF92E, 0xe0},
+	{0xF92F, 0xfe},
+	{0xF930, 0xa3},
+	{0xF931, 0xe0},
+	{0xF932, 0xff},
+	{0xF933, 0x80},
+	{0xF934, 0x04},
+	{0xF935, 0x7e},
+	{0xF936, 0x00},
+	{0xF937, 0x7f},
+	{0xF938, 0x00},
+	{0xF939, 0x8e},
+	{0xF93A, 0x7e},
+	{0xF93B, 0x8f},
+	{0xF93C, 0x7f},
+	{0xF93D, 0x90},
+	{0xF93E, 0x36},
+	{0xF93F, 0x0d},
+	{0xF940, 0xe0},
+	{0xF941, 0x44},
+	{0xF942, 0x02},
+	{0xF943, 0xf0},
+	{0xF944, 0x90},
+	{0xF945, 0x36},
+	{0xF946, 0x0e},
+	{0xF947, 0xe5},
+	{0xF948, 0x7e},
+	{0xF949, 0xf0},
+	{0xF94A, 0xa3},
+	{0xF94B, 0xe5},
+	{0xF94C, 0x7f},
+	{0xF94D, 0xf0},
+	{0xF94E, 0xe5},
+	{0xF94F, 0x3a},
+	{0xF950, 0x60},
+	{0xF951, 0x0c},
+	{0xF952, 0x90},
+	{0xF953, 0x36},
+	{0xF954, 0x09},
+	{0xF955, 0xe0},
+	{0xF956, 0x70},
+	{0xF957, 0x06},
+	{0xF958, 0x90},
+	{0xF959, 0x36},
+	{0xF95A, 0x08},
+	{0xF95B, 0xf0},
+	{0xF95C, 0xf5},
+	{0xF95D, 0x3a},
+	{0xF95E, 0x02},
+	{0xF95F, 0x03},
+	{0xF960, 0x94},
+	{0xF961, 0x22},
+	{0xF962, 0x78},
+	{0xF963, 0x07},
+	{0xF964, 0xe6},
+	{0xF965, 0xd3},
+	{0xF966, 0x94},
+	{0xF967, 0x00},
+	{0xF968, 0x40},
+	{0xF969, 0x16},
+	{0xF96A, 0x16},
+	{0xF96B, 0xe6},
+	{0xF96C, 0x90},
+	{0xF96D, 0x30},
+	{0xF96E, 0xa1},
+	{0xF96F, 0xf0},
+	{0xF970, 0x90},
+	{0xF971, 0x43},
+	{0xF972, 0x83},
+	{0xF973, 0xe0},
+	{0xF974, 0xb4},
+	{0xF975, 0x01},
+	{0xF976, 0x0f},
+	{0xF977, 0x90},
+	{0xF978, 0x43},
+	{0xF979, 0x87},
+	{0xF97A, 0xe0},
+	{0xF97B, 0xb4},
+	{0xF97C, 0x01},
+	{0xF97D, 0x08},
+	{0xF97E, 0x80},
+	{0xF97F, 0x00},
+	{0xF980, 0x90},
+	{0xF981, 0x30},
+	{0xF982, 0xa0},
+	{0xF983, 0x74},
+	{0xF984, 0x01},
+	{0xF985, 0xf0},
+	{0xF986, 0x22},
+	{0xF987, 0xf0},
+	{0xF988, 0x90},
+	{0xF989, 0x35},
+	{0xF98A, 0xba},
+	{0xF98B, 0xe0},
+	{0xF98C, 0xb4},
+	{0xF98D, 0x0a},
+	{0xF98E, 0x0d},
+	{0xF98F, 0xa3},
+	{0xF990, 0xe0},
+	{0xF991, 0xb4},
+	{0xF992, 0x01},
+	{0xF993, 0x08},
+	{0xF994, 0x90},
+	{0xF995, 0xfb},
+	{0xF996, 0x94},
+	{0xF997, 0xe0},
+	{0xF998, 0x90},
+	{0xF999, 0x35},
+	{0xF99A, 0xb8},
+	{0xF99B, 0xf0},
+	{0xF99C, 0xd0},
+	{0xF99D, 0xd0},
+	{0xF99E, 0xd0},
+	{0xF99F, 0x82},
+	{0xF9A0, 0xd0},
+	{0xF9A1, 0x83},
+	{0xF9A2, 0xd0},
+	{0xF9A3, 0xe0},
+	{0xF9A4, 0x32},
+	{0xF9A5, 0x22},
+	{0xF9A6, 0xe5},
+	{0xF9A7, 0x7f},
+	{0xF9A8, 0x45},
+	{0xF9A9, 0x7e},
+	{0xF9AA, 0x60},
+	{0xF9AB, 0x15},
+	{0xF9AC, 0x90},
+	{0xF9AD, 0x01},
+	{0xF9AE, 0x00},
+	{0xF9AF, 0xe0},
+	{0xF9B0, 0x70},
+	{0xF9B1, 0x0f},
+	{0xF9B2, 0x90},
+	{0xF9B3, 0xa0},
+	{0xF9B4, 0xf8},
+	{0xF9B5, 0xe5},
+	{0xF9B6, 0x7e},
+	{0xF9B7, 0xf0},
+	{0xF9B8, 0xa3},
+	{0xF9B9, 0xe5},
+	{0xF9BA, 0x7f},
+	{0xF9BB, 0xf0},
+	{0xF9BC, 0xe4},
+	{0xF9BD, 0xf5},
+	{0xF9BE, 0x7e},
+	{0xF9BF, 0xf5},
+	{0xF9C0, 0x7f},
+	{0xF9C1, 0x22},
+	{0xF9C2, 0x02},
+	{0xF9C3, 0x0e},
+	{0xF9C4, 0x79},
+	{0xF9C5, 0x22},
+	/* Offsets:*/
+	{0x35C6, 0x00},/* FIDDLEDARKCAL*/
+	{0x35C7, 0x00},
+	{0x35C8, 0x01},/*STOREDISTANCEATSTOPSTREAMING*/
+	{0x35C9, 0x20},
+	{0x35CA, 0x01},/*BRUCEFIX*/
+	{0x35CB, 0x62},
+	{0x35CC, 0x01},/*FIXDATAXFERSTATUSREG*/
+	{0x35CD, 0x87},
+	{0x35CE, 0x01},/*FOCUSDISTANCEUPDATE*/
+	{0x35CF, 0xA6},
+	{0x35D0, 0x01},/*SKIPEDOFRESET*/
+	{0x35D1, 0xC2},
+	{0x35D2, 0x00},
+	{0x35D3, 0xFB},
+	{0x35D4, 0x00},
+	{0x35D5, 0x94},
+	{0x35D6, 0x00},
+	{0x35D7, 0xFB},
+	{0x35D8, 0x00},
+	{0x35D9, 0x94},
+	{0x35DA, 0x00},
+	{0x35DB, 0xFB},
+	{0x35DC, 0x00},
+	{0x35DD, 0x94},
+	{0x35DE, 0x00},
+	{0x35DF, 0xFB},
+	{0x35E0, 0x00},
+	{0x35E1, 0x94},
+	{0x35E6, 0x18},/* FIDDLEDARKCAL*/
+	{0x35E7, 0x2F},
+	{0x35E8, 0x03},/* STOREDISTANCEATSTOPSTREAMING*/
+	{0x35E9, 0x93},
+	{0x35EA, 0x18},/* BRUCEFIX*/
+	{0x35EB, 0x99},
+	{0x35EC, 0x00},/* FIXDATAXFERSTATUSREG*/
+	{0x35ED, 0xA3},
+	{0x35EE, 0x21},/* FOCUSDISTANCEUPDATE*/
+	{0x35EF, 0x5B},
+	{0x35F0, 0x0E},/* SKIPEDOFRESET*/
+	{0x35F1, 0x74},
+	{0x35F2, 0x04},
+	{0x35F3, 0x64},
+	{0x35F4, 0x04},
+	{0x35F5, 0x65},
+	{0x35F6, 0x04},
+	{0x35F7, 0x7B},
+	{0x35F8, 0x04},
+	{0x35F9, 0x7C},
+	{0x35FA, 0x04},
+	{0x35FB, 0xDD},
+	{0x35FC, 0x04},
+	{0x35FD, 0xDE},
+	{0x35FE, 0x04},
+	{0x35FF, 0xEF},
+	{0x3600, 0x04},
+	{0x3601, 0xF0},
+	/*Jump/Data:*/
+	{0x35C2, 0x3F},/* Jump Reg*/
+	{0x35C3, 0xFF},/* Jump Reg*/
+	{0x35C4, 0x3F},/* Data Reg*/
+	{0x35C5, 0xC0},/* Data Reg*/
+	{0x35C0, 0x01},/* Enable*/
+};
+struct msm_camera_i2c_reg_conf init_tbl[] = {
+	{0x0112, 10},
+	{0x0113, 10},
+	{0x0301, 9},
+	{0x0305, 4},
+	{0x0307, 133},
+	{0x0309, 10},
+	{0x0202, 0x03},
+	{0x0203, 0xd0},
+	{0x0205, 0xc0},
+	{0x3030, 0x08},
+	{0x0111, 0x02},
+	{0x0b00, 0x01},
+	{0x3001, 0x30},
+	{0x3004, 0x33},
+	{0x3007, 0x09},
+	{0x3016, 0x1F},
+	{0x301d, 0x03},
+	{0x317e, 0x11},
+	{0x317f, 0x09},
+	{0x3400, 0x38},
+	{0x0b06, 0x00},
+	{0x0b07, 0x80},
+	{0x0b08, 0x01},
+	{0x0b09, 0x4F},
+	{0x0136, 0x18},
+	{0x0137, 0x00},
+	{0x0b83, 0x20},
+	{0x0b84, 0x90},
+	{0x0b85, 0x20},
+	{0x0b88, 0x80},
+	{0x0b89, 0x00},
+	{0x0b8a, 0x00},
+	{0x0340, 0x03},   /*REG = 0x0340 frame_length_lines_hi*/
+	{0x0341, 0xf0},   /*REG = 0x0341 frame_length_lines_lo*/
+	{0x0342, 0x0b},   /*REG = 0x0342  line_length_pck_hi*/
+	{0x0343, 0x74},   /*REG = 0x0343  line_length_pck_lo*/
+	{0x3005, 0x03},   /*REG = 0x3005*/
+	{0x3010, 0x00},   /*REG = 0x3010*/
+	{0x3011, 0x01},   /*REG = 0x3011*/
+	{0x301a, 0x6a},   /*REG = 0x301a*/
+	{0x3035, 0x03},   /*REG = 0x3035*/
+	{0x3036, 0x2c},   /*REG = 0x3036*/
+	{0x3041, 0x00},   /*REG = 0x3041*/
+	{0x3042, 0x24},   /*REG = 0x3042*/
+	{0x3045, 0x81},   /*REG = 0x3045*/
+	{0x0b80, 0x02},   /*REG = 0x0b80 edof estimate*/
+	{0x0900, 0x01},   /*REG = 0x0900*/
+	{0x0901, 0x22},   /*REG = 0x0901*/
+	{0x0902, 0x04},   /*REG = 0x0902*/
+	{0x0383, 0x03},   /*REG = 0x0383*/
+	{0x0387, 0x03},   /*REG = 0x0387*/
+	{0x034c, 0x05},   /*REG = 0x034c*/
+	{0x034d, 0x18},   /*REG = 0x034d*/
+	{0x034e, 0x03},   /*REG = 0x034e*/
+	{0x034f, 0xd4},   /*REG = 0x034f*/
+	{0x1716, 0x02},   /*0x1716*/
+	{0x1717, 0x04},   /*0x1717*/
+	{0x1718, 0x08},   /*0x1718*/
+	{0x1719, 0x2c},   /*0x1719*/
+};
+
+struct msm_camera_i2c_reg_conf mode_tbl1[] = {
+	{REG_0x0112, 10},/*REG = 0x0112 , 10 bit */
+	{REG_0x0113, 10},/*REG = 0x0113*/
+	{REG_VT_PIX_CLK_DIV, 9},/*REG = 0x0301 vt_pix_clk_div*/
+	{REG_PRE_PLL_CLK_DIV, 4},/*REG = 0x0305 pre_pll_clk_div*/
+	{REG_PLL_MULTIPLIER, 133},/*REG = 0x0307 pll_multiplier*/
+	{REG_OP_PIX_CLK_DIV, 10},/*REG = 0x0309 op_pix_clk_div*/
+	{REG_FRAME_LENGTH_LINES_HI, 0x03},/*REG = 0x0340 frame_length_lines_hi*/
+	{REG_FRAME_LENGTH_LINES_LO, 0xf0},/*REG = 0x0341 frame_length_lines_lo*/
+	{REG_LINE_LENGTH_PCK_HI, 0x0b},   /*REG = 0x0342  line_length_pck_hi*/
+	{REG_LINE_LENGTH_PCK_LO, 0x74},   /*REG = 0x0343  line_length_pck_lo*/
+	{REG_0x3005, 0x03},   /*REG = 0x3005*/
+	{0x3010, 0x00},   /*REG = 0x3010*/
+	{REG_0x3011, 0x01},   /*REG = 0x3011*/
+	{REG_0x301a, 0x6a},   /*REG = 0x301a*/
+	{REG_0x3035, 0x03},   /*REG = 0x3035*/
+	{REG_0x3036, 0x2c},   /*REG = 0x3036*/
+	{REG_0x3041, 0x00},   /*REG = 0x3041*/
+	{0x3042, 0x24},   /*REG = 0x3042*/
+	{REG_0x3045, 0x81},   /*REG = 0x3045*/
+	{REG_0x0b80, 0x02},   /*REG = 0x0b80 edof estimate*/
+	{REG_0x0900, 0x01},   /*REG = 0x0900*/
+	{REG_0x0901, 0x22},   /*REG = 0x0901*/
+	{REG_0x0902, 0x04},   /*REG = 0x0902*/
+	{REG_0x0383, 0x03},   /*REG = 0x0383*/
+	{REG_0x0387, 0x03},   /*REG = 0x0387*/
+	{REG_0x034c, 0x05},   /*REG = 0x034c*/
+	{REG_0x034d, 0x18},   /*REG = 0x034d*/
+	{REG_0x034e, 0x03},   /*REG = 0x034e*/
+	{REG_0x034f, 0xd4},   /*REG = 0x034f*/
+	{REG_0x1716, 0x02},   /*0x1716*/
+	{REG_0x1717, 0x04},   /*0x1717*/
+	{REG_0x1718, 0x08},   /*0x1718*/
+	{REG_0x1719, 0x2c},   /*0x1719*/
+};
+
+struct msm_camera_i2c_reg_conf mode_tbl2[] = {
+	{REG_0x0112, 10},/*REG = 0x0112 , 10 bit */
+	{REG_0x0113, 10},/*REG = 0x0113*/
+	{REG_VT_PIX_CLK_DIV, 9},/*REG = 0x0301 vt_pix_clk_div*/
+	{REG_PRE_PLL_CLK_DIV, 4},/*REG = 0x0305 pre_pll_clk_div*/
+	{REG_PLL_MULTIPLIER, 133},/*REG = 0x0307 pll_multiplier*/
+	{REG_OP_PIX_CLK_DIV, 10},/*REG = 0x0309 op_pix_clk_div*/
+	{REG_FRAME_LENGTH_LINES_HI, 0x07},/*REG = 0x0340 frame_length_lines_hi*/
+	{REG_FRAME_LENGTH_LINES_LO, 0xd0},/*REG = 0x0341 frame_length_lines_lo*/
+	{REG_LINE_LENGTH_PCK_HI, 0x0b},/*REG = 0x0342 line_length_pck_hi*/
+	{REG_LINE_LENGTH_PCK_LO, 0x8c},/*REG = 0x0343 line_length_pck_lo*/
+	{REG_0x3005, 0x01},/*REG = 0x3005*/
+	{0x3010, 0x00},/*REG = 0x3010*/
+	{REG_0x3011, 0x00},/*REG = 0x3011*/
+	{REG_0x301a, 0x55},/*REG = 0x301a*/
+	{REG_0x3035, 0x01},/*REG = 0x3035*/
+	{REG_0x3036, 0x23},/*REG = 0x3036*/
+	{REG_0x3041, 0x00},/*REG = 0x3041*/
+	{0x3042, 0x24},/*REG = 0x3042*/
+	{REG_0x3045, 0xb7},/*REG = 0x3045*/
+	{REG_0x0b80, 0x01},/*REG = 0x0b80 edof application*/
+	{REG_0x0900, 0x00},/*REG = 0x0900*/
+	{REG_0x0901, 0x00},/*REG = 0x0901*/
+	{REG_0x0902, 0x00},/*REG = 0x0902*/
+	{REG_0x0383, 0x01},/*REG = 0x0383*/
+	{REG_0x0387, 0x01},/*REG = 0x0387*/
+	{REG_0x034c, 0x0A},/*REG = 0x034c*/
+	{REG_0x034d, 0x30},/*REG = 0x034d*/
+	{REG_0x034e, 0x07},/*REG = 0x034e*/
+	{REG_0x034f, 0xA8},/*REG = 0x034f*/
+	{REG_0x1716, 0x02},/*0x1716*/
+	{REG_0x1717, 0x0d},/*0x1717*/
+	{REG_0x1718, 0x07},/*0x1718*/
+	{REG_0x1719, 0x7d},/*0x1719*/
+};
+
+static int32_t vx6953_sensor_setting(int update_type, int rt)
+{
+
+	int32_t rc = 0;
+	uint16_t frame_cnt = 0;
+		CDBG("%s update type = %d, rt = %d\n",
+			__func__, update_type, rt);
+
+		switch (update_type) {
+		case REG_INIT:
+		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
+						/* reset fps_divider */
+			fps = 30 * Q8;
+			/* stop streaming */
+
+			/* Reset everything first */
+			msm_camera_i2c_write_tbl(
+				vx6953_s_ctrl.sensor_i2c_client,
+				vx6953_standby,
+				ARRAY_SIZE(vx6953_standby),
+				vx6953_s_ctrl.msm_sensor_reg->
+				default_data_type);
+
+			msleep(20);
+
+			CDBG("Init vx6953_sensor_setting standby\n");
+			msm_camera_i2c_write_tbl(
+				vx6953_s_ctrl.sensor_i2c_client,
+				vx6953_stop_settings,
+				ARRAY_SIZE(vx6953_stop_settings),
+				vx6953_s_ctrl.msm_sensor_reg->
+				default_data_type);
+				/*vx6953_stm5m0edof_delay_msecs_stdby*/
+			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+			msm_camera_i2c_write_tbl(
+				vx6953_s_ctrl.sensor_i2c_client,
+				patch_tbl_cut2,
+				ARRAY_SIZE(patch_tbl_cut2),
+				vx6953_s_ctrl.msm_sensor_reg->
+				default_data_type);
+			msm_camera_i2c_write_tbl(
+				vx6953_s_ctrl.sensor_i2c_client,
+				init_tbl,
+				ARRAY_SIZE(init_tbl),
+				vx6953_s_ctrl.msm_sensor_reg->
+				default_data_type);
+			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+		}
+		return rc;
+		case UPDATE_PERIODIC:
+		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
+			struct msm_camera_i2c_reg_conf init_mode_tbl[] =  {
+			{REG_0x0112,
+				vx6953_regs.reg_pat_init[0].reg_0x0112},
+			{REG_0x0113,
+				vx6953_regs.reg_pat_init[0].reg_0x0113},
+			{REG_VT_PIX_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				vt_pix_clk_div},
+			{REG_PRE_PLL_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				pre_pll_clk_div},
+			{REG_PLL_MULTIPLIER,
+				vx6953_regs.reg_pat_init[0].
+				pll_multiplier},
+			{REG_OP_PIX_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				op_pix_clk_div},
+			{REG_COARSE_INTEGRATION_TIME_HI,
+				vx6953_regs.reg_pat[rt].
+				coarse_integration_time_hi},
+			{REG_COARSE_INTEGRATION_TIME_LO,
+				vx6953_regs.reg_pat[rt].
+				coarse_integration_time_lo},
+			{REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
+				vx6953_regs.reg_pat[rt].
+				analogue_gain_code_global},
+			{REG_0x3030,
+				vx6953_regs.reg_pat_init[0].reg_0x3030},
+			/* 953 specific registers */
+			{REG_0x0111,
+				vx6953_regs.reg_pat_init[0].reg_0x0111},
+			{REG_0x0b00,
+				vx6953_regs.reg_pat_init[0].reg_0x0b00},
+			{REG_0x3001,
+				vx6953_regs.reg_pat_init[0].reg_0x3001},
+			{REG_0x3004,
+				vx6953_regs.reg_pat_init[0].reg_0x3004},
+			{REG_0x3007,
+				vx6953_regs.reg_pat_init[0].reg_0x3007},
+			{REG_0x3016,
+				vx6953_regs.reg_pat_init[0].reg_0x3016},
+			{REG_0x301d,
+				vx6953_regs.reg_pat_init[0].reg_0x301d},
+			{REG_0x317e,
+				vx6953_regs.reg_pat_init[0].reg_0x317e},
+			{REG_0x317f,
+				vx6953_regs.reg_pat_init[0].reg_0x317f},
+			{REG_0x3400,
+				vx6953_regs.reg_pat_init[0].reg_0x3400},
+			{0x0b06,
+				vx6953_regs.reg_pat_init[0].reg_0x0b06},
+			/*Single_defect_correct_weight = auto*/
+			{0x0b07,
+				vx6953_regs.reg_pat_init[0].reg_0x0b07},
+			/*Dynamic couplet correction ENABLED*/
+			{0x0b08,
+				vx6953_regs.reg_pat_init[0].reg_0x0b08},
+			/*Dynamic couplet correction weight*/
+			{0x0b09,
+				vx6953_regs.reg_pat_init[0].reg_0x0b09},
+			/* Clock Setup */
+			/* Tell sensor ext clk is 24MHz*/
+			{0x0136,
+				vx6953_regs.reg_pat_init[0].reg_0x0136},
+			{0x0137,
+				vx6953_regs.reg_pat_init[0].reg_0x0137},
+			/* The white balance gains must be written
+			to the sensor every frame. */
+			/* Edof */
+			{REG_0x0b83,
+				vx6953_regs.reg_pat_init[0].reg_0x0b83},
+			{REG_0x0b84,
+				vx6953_regs.reg_pat_init[0].reg_0x0b84},
+			{0x0b85,
+				vx6953_regs.reg_pat_init[0].reg_0x0b85},
+			{0x0b88,
+				vx6953_regs.reg_pat_init[0].reg_0x0b88},
+			{0x0b89,
+				vx6953_regs.reg_pat_init[0].reg_0x0b89},
+			{REG_0x0b8a,
+				vx6953_regs.reg_pat_init[0].reg_0x0b8a},
+			/* Mode specific regieters */
+			{REG_FRAME_LENGTH_LINES_HI,
+				vx6953_regs.reg_pat[rt].
+				frame_length_lines_hi},
+			{REG_FRAME_LENGTH_LINES_LO,
+				vx6953_regs.reg_pat[rt].
+				frame_length_lines_lo},
+			{REG_LINE_LENGTH_PCK_HI,
+				vx6953_regs.reg_pat[rt].
+				line_length_pck_hi},
+			{REG_LINE_LENGTH_PCK_LO,
+				vx6953_regs.reg_pat[rt].
+				line_length_pck_lo},
+			{REG_0x3005,
+				vx6953_regs.reg_pat[rt].reg_0x3005},
+			{0x3010,
+				vx6953_regs.reg_pat[rt].reg_0x3010},
+			{REG_0x3011,
+				vx6953_regs.reg_pat[rt].reg_0x3011},
+			{REG_0x301a,
+				vx6953_regs.reg_pat[rt].reg_0x301a},
+			{REG_0x3035,
+				vx6953_regs.reg_pat[rt].reg_0x3035},
+			{REG_0x3036,
+				vx6953_regs.reg_pat[rt].reg_0x3036},
+			{REG_0x3041,
+				vx6953_regs.reg_pat[rt].reg_0x3041},
+			{0x3042,
+				vx6953_regs.reg_pat[rt].reg_0x3042},
+			{REG_0x3045,
+				vx6953_regs.reg_pat[rt].reg_0x3045},
+			/*EDOF: Estimation settings for Preview mode
+			Application settings for capture mode
+			(standard settings - Not tuned) */
+			{REG_0x0b80,
+				vx6953_regs.reg_pat[rt].reg_0x0b80},
+			{REG_0x0900,
+				vx6953_regs.reg_pat[rt].reg_0x0900},
+			{REG_0x0901,
+				vx6953_regs.reg_pat[rt].reg_0x0901},
+			{REG_0x0902,
+				vx6953_regs.reg_pat[rt].reg_0x0902},
+			{REG_0x0383,
+				vx6953_regs.reg_pat[rt].reg_0x0383},
+			{REG_0x0387,
+				vx6953_regs.reg_pat[rt].reg_0x0387},
+			/* Change output size / frame rate */
+			{REG_0x034c,
+				vx6953_regs.reg_pat[rt].reg_0x034c},
+			{REG_0x034d,
+				vx6953_regs.reg_pat[rt].reg_0x034d},
+			{REG_0x034e,
+				vx6953_regs.reg_pat[rt].reg_0x034e},
+			{REG_0x034f,
+				vx6953_regs.reg_pat[rt].reg_0x034f},
+			{REG_0x1716,
+				vx6953_regs.reg_pat[rt].reg_0x1716},
+			{REG_0x1717,
+				vx6953_regs.reg_pat[rt].reg_0x1717},
+			{REG_0x1718,
+				vx6953_regs.reg_pat[rt].reg_0x1718},
+			{REG_0x1719,
+				vx6953_regs.reg_pat[rt].reg_0x1719},
+			};
+			/* stop streaming */
+			msleep(20);
+
+			/* Reset everything first */
+			msm_camera_i2c_write_tbl(
+				vx6953_s_ctrl.sensor_i2c_client,
+				vx6953_standby,
+				ARRAY_SIZE(vx6953_standby),
+				vx6953_s_ctrl.msm_sensor_reg->
+				default_data_type);
+
+
+			msleep(20);
+
+			msm_camera_i2c_write_tbl(
+				vx6953_s_ctrl.sensor_i2c_client,
+				vx6953_stop_settings,
+				ARRAY_SIZE(vx6953_stop_settings),
+				vx6953_s_ctrl.msm_sensor_reg->
+				default_data_type);
+			/*vx6953_stm5m0edof_delay_msecs_stdby*/
+			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+
+			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+
+			msm_camera_i2c_write_tbl(
+				vx6953_s_ctrl.sensor_i2c_client,
+				patch_tbl_cut2,
+				ARRAY_SIZE(patch_tbl_cut2),
+				vx6953_s_ctrl.msm_sensor_reg->
+				default_data_type);
+
+			msm_camera_i2c_write_tbl(
+				vx6953_s_ctrl.sensor_i2c_client,
+				init_mode_tbl,
+				ARRAY_SIZE(init_mode_tbl),
+				vx6953_s_ctrl.msm_sensor_reg->
+				default_data_type);
+
+			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+			if (rt == RES_PREVIEW) {
+				CDBG("%s write mode_tbl for preview\n",
+					__func__);
+				msm_camera_i2c_write_tbl(
+					vx6953_s_ctrl.sensor_i2c_client,
+					mode_tbl1,
+					ARRAY_SIZE(mode_tbl1),
+					vx6953_s_ctrl.msm_sensor_reg->
+					default_data_type);
+			} else if (rt == RES_CAPTURE) {
+				CDBG("%s write mode_tbl for capture\n",
+					__func__);
+				msm_camera_i2c_write_tbl(
+					vx6953_s_ctrl.sensor_i2c_client,
+					mode_tbl2,
+					ARRAY_SIZE(mode_tbl2),
+					vx6953_s_ctrl.msm_sensor_reg->
+					default_data_type);
+			}
+			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+
+			/* Start sensor streaming */
+			msm_camera_i2c_write_tbl(
+				vx6953_s_ctrl.sensor_i2c_client,
+				vx6953_start_settings,
+				ARRAY_SIZE(vx6953_start_settings),
+				vx6953_s_ctrl.msm_sensor_reg->
+				default_data_type);
+			msleep(20);
+
+			msm_camera_i2c_read(
+				vx6953_s_ctrl.sensor_i2c_client,
+				0x0005,
+				&frame_cnt,
+				MSM_CAMERA_I2C_BYTE_ADDR);
+			while (frame_cnt == 0xFF) {
+				msm_camera_i2c_read(
+					vx6953_s_ctrl.sensor_i2c_client,
+					0x0005,
+					&frame_cnt,
+					MSM_CAMERA_I2C_BYTE_ADDR);
+				CDBG("%s frame_cnt = %d\n",
+					__func__, frame_cnt);
+				usleep_range(5000, 10000);
+			}
+		}
+		return rc;
+		default:
+		return rc;
+	}
+	return rc;
+}
+
+static int32_t vx6953_init_config(void)
+{
+	int32_t rc = 0;
+	int rt;
+	/* change sensor resolution	if needed */
+	CDBG("%s called\n", __func__);
+	rt = RES_PREVIEW;
+	vx6953_stm5m0edof_delay_msecs_stdby =
+		((((2 * 1000 * fps_divider) /
+		   fps) * Q8) / Q10) + 1;
+
+	vx6953_sensor_setting(REG_INIT, rt);
+
+	vx6953_enable_edof(VX6953_EDOF_ESTIMATION);
+	return rc;
+}
+
+static int32_t vx6953_update_config(int rt)
+{
+	int32_t rc = 0;
+	CDBG("%s rt = %d\n", __func__, rt);
+	if (rt == MSM_SENSOR_RES_FULL)
+		rt = RES_CAPTURE;
+	else if (rt == MSM_SENSOR_RES_QTR)
+		rt = RES_PREVIEW;
+
+	vx6953_stm5m0edof_delay_msecs_stdby = 67;
+	vx6953_sensor_setting(UPDATE_PERIODIC, rt);
+
+	if (rt == RES_PREVIEW)
+		vx6953_enable_edof(VX6953_EDOF_ESTIMATION);
+	else if (rt == RES_CAPTURE)
+		vx6953_enable_edof(VX6953_EDOF_APPLICATION);
+
+	return rc;
+} /*end of vx6953_snapshot_config*/
+
+static int32_t vx6953_set_sensor_mode(struct msm_sensor_ctrl_t *s_ctrl,
+	int update_type, int rt)
+{
+	int32_t rc = 0;
+
+	fps_divider = 1 * 0x00000400;
+	fps = 30*Q8;
+
+	switch (update_type) {
+	case MSM_SENSOR_REG_INIT:
+		rc = vx6953_init_config();
+		break;
+	case MSM_SENSOR_UPDATE_PERIODIC:
+		rc = vx6953_update_config(rt);
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+static struct msm_sensor_fn_t vx6953_func_tbl = {
+	.sensor_start_stream = msm_sensor_start_stream,
+	.sensor_stop_stream = msm_sensor_stop_stream,
+	.sensor_group_hold_on = msm_sensor_group_hold_on,
+	.sensor_group_hold_off = msm_sensor_group_hold_off,
+	.sensor_set_fps = vx6953_set_fps,
+	.sensor_write_exp_gain = vx6953_write_exp_gain,
+	.sensor_write_snapshot_exp_gain = vx6953_write_exp_gain,
+	.sensor_csi_setting = vx6953_set_sensor_mode,
+	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
+	.sensor_mode_init = msm_sensor_mode_init,
+	.sensor_get_output_info = msm_sensor_get_output_info,
+	.sensor_config = msm_sensor_config,
+	.sensor_power_up = msm_sensor_power_up,
+	.sensor_power_down = msm_sensor_power_down,
+};
+
+static struct msm_sensor_reg_t vx6953_data_regs = {
+	.default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
+	.start_stream_conf = vx6953_start_settings,
+	.start_stream_conf_size = ARRAY_SIZE(vx6953_start_settings),
+	.stop_stream_conf = vx6953_stop_settings,
+	.stop_stream_conf_size = ARRAY_SIZE(vx6953_stop_settings),
+	.group_hold_on_conf = vx6953_groupon_settings,
+	.group_hold_on_conf_size = ARRAY_SIZE(vx6953_groupon_settings),
+	.group_hold_off_conf = vx6953_groupoff_settings,
+	.group_hold_off_conf_size =
+		ARRAY_SIZE(vx6953_groupoff_settings),
+	.init_settings = &vx6953_init_conf[0],
+	.init_size = ARRAY_SIZE(vx6953_init_conf),
+	.mode_settings = &vx6953_confs[0],
+	.output_settings = &vx6953_dimensions[0],
+	.num_conf = ARRAY_SIZE(vx6953_confs),
+};
+
+static struct msm_sensor_ctrl_t vx6953_s_ctrl = {
+	.msm_sensor_reg = &vx6953_data_regs,
+	.sensor_i2c_client = &vx6953_sensor_i2c_client,
+	.sensor_i2c_addr = 0x20,
+	.sensor_output_reg_addr = &vx6953_reg_addr,
+	.sensor_id_info = &vx6953_id_info,
+	.sensor_exp_gain_info = &vx6953_exp_gain_info,
+	.cam_mode = MSM_SENSOR_MODE_INVALID,
+	.msm_sensor_mutex = &vx6953_mut,
+	.sensor_i2c_driver = &vx6953_i2c_driver,
+	.sensor_v4l2_subdev_info = vx6953_subdev_info,
+	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(vx6953_subdev_info),
+	.sensor_v4l2_subdev_ops = &vx6953_subdev_ops,
+	.func_tbl = &vx6953_func_tbl,
+	.clk_rate = MSM_SENSOR_MCLK_24HZ,
+};
+
+module_init(msm_sensor_init_module);
+MODULE_DESCRIPTION("Sensor VX6953 (BAYER 5M)");
+MODULE_LICENSE("GPL v2");
+
diff --git a/drivers/media/platform/msm/camera_v1/sensors/vx6953.h b/drivers/media/platform/msm/camera_v1/sensors/vx6953.h
new file mode 100644
index 0000000..2fc2a19
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/sensors/vx6953.h
@@ -0,0 +1,135 @@
+/* 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.
+ *
+ */
+
+#ifndef VX6953_H
+#define VX6953_H
+#include <linux/types.h>
+#include <mach/board.h>
+struct reg_struct_init {
+	uint8_t reg_0x0112;      /* 0x0112*/
+	uint8_t reg_0x0113;      /* 0x0113*/
+	uint8_t vt_pix_clk_div;  /* 0x0301*/
+	uint8_t pre_pll_clk_div; /* 0x0305*/
+	uint8_t pll_multiplier;  /* 0x0307*/
+	uint8_t op_pix_clk_div;  /* 0x0309*/
+	uint8_t reg_0x3030;      /*0x3030*/
+	uint8_t reg_0x0111;      /*0x0111*/
+	uint8_t reg_0x0b00;      /*0x0b00*/
+	uint8_t reg_0x3001;      /*0x3001*/
+	uint8_t reg_0x3004;      /*0x3004*/
+	uint8_t reg_0x3007;      /*0x3007*/
+	uint8_t reg_0x3016;      /*0x3016*/
+	uint8_t reg_0x301d;      /*0x301d*/
+	uint8_t reg_0x317e;      /*0x317E*/
+	uint8_t reg_0x317f;      /*0x317F*/
+	uint8_t reg_0x3400;      /*0x3400*/
+	uint8_t reg_0x0b06;      /*0x0b06*/
+	uint8_t reg_0x0b07;      /*0x0b07*/
+	uint8_t reg_0x0b08;      /*0x0b08*/
+	uint8_t reg_0x0b09;      /*0x0b09*/
+	uint8_t reg_0x0136;
+	uint8_t reg_0x0137;
+	/* Edof */
+	uint8_t reg_0x0b83;      /*0x0b83*/
+	uint8_t reg_0x0b84;      /*0x0b84*/
+	uint8_t reg_0x0b85;      /*0x0b85*/
+	uint8_t reg_0x0b88;      /*0x0b88*/
+	uint8_t reg_0x0b89;      /*0x0b89*/
+	uint8_t reg_0x0b8a;      /*0x0b8a*/
+	};
+struct reg_struct {
+	uint8_t coarse_integration_time_hi; /*REG_COARSE_INTEGRATION_TIME_HI*/
+	uint8_t coarse_integration_time_lo; /*REG_COARSE_INTEGRATION_TIME_LO*/
+	uint8_t analogue_gain_code_global;
+	uint8_t frame_length_lines_hi; /* 0x0340*/
+	uint8_t frame_length_lines_lo; /* 0x0341*/
+	uint8_t line_length_pck_hi;    /* 0x0342*/
+	uint8_t line_length_pck_lo;    /* 0x0343*/
+	uint8_t reg_0x3005;   /* 0x3005*/
+	uint8_t reg_0x3010;  /* 0x3010*/
+	uint8_t reg_0x3011;  /* 0x3011*/
+	uint8_t reg_0x301a;  /* 0x301a*/
+	uint8_t reg_0x3035;  /* 0x3035*/
+	uint8_t reg_0x3036;   /* 0x3036*/
+	uint8_t reg_0x3041;  /*0x3041*/
+	uint8_t reg_0x3042;  /*0x3042*/
+	uint8_t reg_0x3045;  /*0x3045*/
+	uint8_t reg_0x0b80;   /* 0x0b80*/
+	uint8_t reg_0x0900;   /*0x0900*/
+	uint8_t reg_0x0901;   /* 0x0901*/
+	uint8_t reg_0x0902;   /*0x0902*/
+	uint8_t reg_0x0383;   /*0x0383*/
+	uint8_t reg_0x0387;   /* 0x0387*/
+	uint8_t reg_0x034c;   /* 0x034c*/
+	uint8_t reg_0x034d;   /*0x034d*/
+	uint8_t reg_0x034e;   /* 0x034e*/
+	uint8_t reg_0x034f;   /* 0x034f*/
+	uint8_t reg_0x1716; /*0x1716*/
+	uint8_t reg_0x1717; /*0x1717*/
+	uint8_t reg_0x1718; /*0x1718*/
+	uint8_t reg_0x1719; /*0x1719*/
+	uint8_t reg_0x3210;/*0x3210*/
+	uint8_t reg_0x111; /*0x111*/
+	uint8_t reg_0x3410;  /*0x3410*/
+	uint8_t reg_0x3098;
+	uint8_t reg_0x309D;
+	uint8_t reg_0x0200;
+	uint8_t reg_0x0201;
+	};
+struct vx6953_i2c_reg_conf {
+	unsigned short waddr;
+	unsigned short wdata;
+};
+
+enum vx6953_test_mode_t {
+	TEST_OFF,
+	TEST_1,
+	TEST_2,
+	TEST_3
+};
+
+enum vx6953_resolution_t {
+	QTR_SIZE,
+	FULL_SIZE,
+	INVALID_SIZE
+};
+enum vx6953_setting {
+	RES_PREVIEW,
+	RES_CAPTURE
+};
+enum mt9p012_reg_update {
+	/* Sensor egisters that need to be updated during initialization */
+	REG_INIT,
+	/* Sensor egisters that needs periodic I2C writes */
+	UPDATE_PERIODIC,
+	/* All the sensor Registers will be updated */
+	UPDATE_ALL,
+	/* Not valid update */
+	UPDATE_INVALID
+};
+
+enum sensor_revision_t {
+	VX6953_STM5M0EDOF_CUT_1,
+	VX6953_STM5M0EDOF_CUT_2,
+	VX6953_STM5M0EDOF_CUT_3
+};
+enum edof_mode_t {
+	VX6953_EDOF_DISABLE,       /* 0x00 */
+	VX6953_EDOF_APPLICATION,   /* 0x01 */
+	VX6953_EDOF_ESTIMATION     /* 0x02 */
+};
+struct vx6953_reg {
+	const struct reg_struct_init  *reg_pat_init;
+	const struct reg_struct  *reg_pat;
+};
+#endif /* VX6953_H */
diff --git a/drivers/media/platform/msm/camera_v1/sensors/vx6953_reg.h b/drivers/media/platform/msm/camera_v1/sensors/vx6953_reg.h
new file mode 100644
index 0000000..fe99be5
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/sensors/vx6953_reg.h
@@ -0,0 +1,134 @@
+/* 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.
+ *
+ */
+
+
+struct reg_struct_init vx6953_reg_init[1] = {
+	{
+		10,			/*REG = 0x0112 , 10 bit */
+		10,			/*REG = 0x0113*/
+		9,			/*REG = 0x0301 vt_pix_clk_div*/
+		4,		/*REG = 0x0305 pre_pll_clk_div*/
+		133,		/*REG = 0x0307 pll_multiplier*/
+		10,		/*REG = 0x0309 op_pix_clk_div*/
+		0x08,		/*REG = 0x3030*/
+		0x02,		/*REG = 0x0111*/
+		0x01,		/*REG = 0x0b00 ,lens shading off */
+		0x30,		/*REG = 0x3001*/
+		0x33,		/*REG = 0x3004*/
+		0x09,		/*REG = 0x3007*/
+		0x1F,		/*REG = 0x3016*/
+		0x03,		/*REG = 0x301d*/
+		0x11,		/*REG = 0x317E*/
+		0x09,		/*REG = 0x317F*/
+		0x38,		/*REG = 0x3400*/
+		0x00,		/*REG_0x0b06*/
+		0x80,		/*REG_0x0b07*/
+		0x01,		/*REG_0x0b08*/
+		0x4F,		/*REG_0x0b09*/
+		0x18,		/*REG_0x0136*/
+		0x00,		/*/REG_0x0137*/
+		0x20,		/*REG = 0x0b83*/
+		0x90,		/*REG = 0x0b84*/
+		0x20,		/*REG = 0x0b85*/
+		0x80,		/*REG = 0x0b88*/
+		0x00,		/*REG = 0x0b89*/
+		0x00,		/*REG = 0x0b8a*/
+	}
+};
+struct reg_struct vx6953_reg_pat[2] = {
+	{/* Preview */
+		0x03,	/*REG = 0x0202 coarse integration_time_hi*/
+		0xd0,	/*REG = 0x0203 coarse_integration_time_lo*/
+		0xc0,	/*REG = 0x0205 analogue_gain_code_global*/
+		0x03,	/*REG = 0x0340 frame_length_lines_hi*/
+		0xf0,	/*REG = 0x0341 frame_length_lines_lo*/
+		0x0b,	/*REG = 0x0342  line_length_pck_hi*/
+		0x74,	/*REG = 0x0343  line_length_pck_lo*/
+		0x03,	/*REG = 0x3005*/
+		0x00,	/*REG = 0x3010*/
+		0x01,	/*REG = 0x3011*/
+		0x6a,	/*REG = 0x301a*/
+		0x03,	/*REG = 0x3035*/
+		0x2c,	/*REG = 0x3036*/
+		0x00,	/*REG = 0x3041*/
+		0x24,	/*REG = 0x3042*/
+		0x81,	/*REG = 0x3045*/
+		0x02,	/*REG = 0x0b80 edof estimate*/
+		0x01,	/*REG = 0x0900*/
+		0x22,	/*REG = 0x0901*/
+		0x04,	/*REG = 0x0902*/
+		0x03,	/*REG = 0x0383*/
+		0x03,	/*REG = 0x0387*/
+		0x05,	/*REG = 0x034c*/
+		0x18,	/*REG = 0x034d*/
+		0x03,	/*REG = 0x034e*/
+		0xd4,	/*REG = 0x034f*/
+		0x02,	/*0x1716*/
+		0x04,	/*0x1717*/
+		0x08,	/*0x1718*/
+		0x2c,	/*0x1719*/
+		0x01,   /*0x3210*/
+		0x02,   /*0x111*/
+		0x01,   /*0x3410*/
+		0x01,   /*0x3098*/
+		0x05,   /*0x309D*/
+		0x02,
+		0x04,
+	},
+	{ /* Snapshot */
+		0x07,/*REG = 0x0202 coarse_integration_time_hi*/
+		0x00,/*REG = 0x0203 coarse_integration_time_lo*/
+		0xc0,/*REG = 0x0205 analogue_gain_code_global*/
+		0x07,/*REG = 0x0340 frame_length_lines_hi*/
+		0xd0,/*REG = 0x0341 frame_length_lines_lo*/
+		0x0b,/*REG = 0x0342 line_length_pck_hi*/
+		0x8c,/*REG = 0x0343 line_length_pck_lo*/
+		0x01,/*REG = 0x3005*/
+		0x00,/*REG = 0x3010*/
+		0x00,/*REG = 0x3011*/
+		0x55,/*REG = 0x301a*/
+		0x01,/*REG = 0x3035*/
+		0x23,/*REG = 0x3036*/
+		0x00,/*REG = 0x3041*/
+		0x24,/*REG = 0x3042*/
+		0xb7,/*REG = 0x3045*/
+		0x01,/*REG = 0x0b80 edof application*/
+		0x00,/*REG = 0x0900*/
+		0x00,/*REG = 0x0901*/
+		0x00,/*REG = 0x0902*/
+		0x01,/*REG = 0x0383*/
+		0x01,/*REG = 0x0387*/
+		0x0A,/*REG = 0x034c*/
+		0x30,/*REG = 0x034d*/
+		0x07,/*REG = 0x034e*/
+		0xA8,/*REG = 0x034f*/
+		0x02,/*0x1716*/
+		0x0d,/*0x1717*/
+		0x07,/*0x1718*/
+		0x7d,/*0x1719*/
+		0x01,/*0x3210*/
+		0x02,/*0x111*/
+		0x01,/*0x3410*/
+		0x01,/*0x3098*/
+		0x05, /*0x309D*/
+		0x02,
+		0x00,
+	}
+};
+
+
+
+struct vx6953_reg vx6953_regs = {
+	.reg_pat_init = &vx6953_reg_init[0],
+	.reg_pat = &vx6953_reg_pat[0],
+};
diff --git a/drivers/media/platform/msm/camera_v1/server/Makefile b/drivers/media/platform/msm/camera_v1/server/Makefile
new file mode 100644
index 0000000..a64be59
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/server/Makefile
@@ -0,0 +1,11 @@
+GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
+
+ifeq ($(CONFIG_MSM_CAMERA_V4L2),y)
+  EXTRA_CFLAGS += -Idrivers/media/platform/msm/camera_v1
+  EXTRA_CFLAGS += -Idrivers/media/platform/msm/camera_v1/io
+  EXTRA_CFLAGS += -Idrivers/media/platform/msm/camera_v1/csi
+  EXTRA_CFLAGS += -Idrivers/media/platform/msm/camera_v1/eeprom
+  EXTRA_CFLAGS += -Idrivers/media/platform/msm/camera_v1/sensors
+  EXTRA_CFLAGS += -Idrivers/media/platform/msm/camera_v1/actuators
+  obj-$(CONFIG_MSM_CAMERA)   += msm_cam_server.o
+endif
diff --git a/drivers/media/platform/msm/camera_v1/server/msm_cam_server.c b/drivers/media/platform/msm/camera_v1/server/msm_cam_server.c
new file mode 100644
index 0000000..78d15d9
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/server/msm_cam_server.c
@@ -0,0 +1,3299 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/of.h>
+#include "msm_cam_server.h"
+#include "msm_csid.h"
+#include "msm_csic.h"
+#include "msm_csiphy.h"
+#include "msm_ispif.h"
+#include "msm_sensor.h"
+#include "msm_actuator.h"
+#include "msm_csi_register.h"
+
+#ifdef CONFIG_MSM_CAMERA_DEBUG
+#define D(fmt, args...) pr_debug("msm: " fmt, ##args)
+#else
+#define D(fmt, args...) do {} while (0)
+#endif
+
+static struct msm_cam_server_dev g_server_dev;
+static struct class *msm_class;
+static dev_t msm_devno;
+
+static long msm_server_send_v4l2_evt(void *evt);
+static void msm_cam_server_subdev_notify(struct v4l2_subdev *sd,
+	unsigned int notification, void *arg);
+
+void msm_queue_init(struct msm_device_queue *queue, const char *name)
+{
+	D("%s\n", __func__);
+	spin_lock_init(&queue->lock);
+	queue->len = 0;
+	queue->max = 0;
+	queue->name = name;
+	INIT_LIST_HEAD(&queue->list);
+	init_waitqueue_head(&queue->wait);
+}
+
+void msm_enqueue(struct msm_device_queue *queue,
+			struct list_head *entry)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&queue->lock, flags);
+	queue->len++;
+	if (queue->len > queue->max) {
+		queue->max = queue->len;
+		pr_info("%s: queue %s new max is %d\n", __func__,
+			queue->name, queue->max);
+	}
+	list_add_tail(entry, &queue->list);
+	wake_up(&queue->wait);
+	D("%s: woke up %s\n", __func__, queue->name);
+	spin_unlock_irqrestore(&queue->lock, flags);
+}
+
+void msm_drain_eventq(struct msm_device_queue *queue)
+{
+	unsigned long flags;
+	struct msm_queue_cmd *qcmd;
+	struct msm_isp_event_ctrl *isp_event;
+	spin_lock_irqsave(&queue->lock, flags);
+	while (!list_empty(&queue->list)) {
+		qcmd = list_first_entry(&queue->list,
+			struct msm_queue_cmd, list_eventdata);
+		list_del_init(&qcmd->list_eventdata);
+		isp_event =
+			(struct msm_isp_event_ctrl *)
+			qcmd->command;
+		if (isp_event->isp_data.ctrl.value != NULL)
+			kfree(isp_event->isp_data.ctrl.value);
+		kfree(qcmd->command);
+		free_qcmd(qcmd);
+	}
+	spin_unlock_irqrestore(&queue->lock, flags);
+}
+
+int32_t msm_find_free_queue(void)
+{
+	int i;
+	for (i = 0; i < MAX_NUM_ACTIVE_CAMERA; i++) {
+		struct msm_cam_server_queue *queue;
+		queue = &g_server_dev.server_queue[i];
+		if (!queue->queue_active)
+			return i;
+	}
+	return -EINVAL;
+}
+
+void msm_setup_v4l2_event_queue(struct v4l2_fh *eventHandle,
+	struct video_device *pvdev)
+{
+	v4l2_fh_init(eventHandle, pvdev);
+	v4l2_fh_add(eventHandle);
+}
+
+void msm_destroy_v4l2_event_queue(struct v4l2_fh *eventHandle)
+{
+	v4l2_fh_del(eventHandle);
+	v4l2_fh_exit(eventHandle);
+}
+
+int msm_cam_server_config_interface_map(u32 extendedmode,
+	uint32_t mctl_handle, int vnode_id, int is_bayer_sensor)
+{
+	int i = 0;
+	int rc = 0;
+	int old_handle;
+	int interface;
+
+	if (vnode_id >= MAX_NUM_ACTIVE_CAMERA) {
+		pr_err("%s: invalid msm_dev node id = %d", __func__, vnode_id);
+		return -EINVAL;
+	}
+	D("%s: extendedmode = %d, vnode_id = %d, is_bayer_sensor = %d",
+		__func__, extendedmode, vnode_id, is_bayer_sensor);
+	switch (extendedmode) {
+	case MSM_V4L2_EXT_CAPTURE_MODE_RDI:
+		interface = RDI_0;
+		break;
+	case MSM_V4L2_EXT_CAPTURE_MODE_RDI1:
+		interface = RDI_1;
+		break;
+	case MSM_V4L2_EXT_CAPTURE_MODE_RDI2:
+		interface = RDI_2;
+		break;
+	default:
+		interface = PIX_0;
+		break;
+	}
+
+	for (i = 0; i < INTF_MAX; i++) {
+		if (g_server_dev.interface_map_table[i].interface ==
+							interface) {
+			if (is_bayer_sensor && interface == PIX_0) {
+				if (g_server_dev.
+					interface_map_table[i].mctl_handle &&
+					!g_server_dev.interface_map_table[i].
+						is_bayer_sensor) {
+					/* in simultaneous camera usecase
+					 * SoC does not use PIX interface */
+					g_server_dev.interface_map_table[i].
+						mctl_handle = 0;
+				}
+			}
+
+			if (!is_bayer_sensor && interface == PIX_0) {
+				if (g_server_dev.
+					interface_map_table[i].mctl_handle &&
+					g_server_dev.interface_map_table[i].
+						is_bayer_sensor) {
+					/* In case of simultaneous camera,
+					 * the YUV sensor could use PIX
+					 * interface to only queue the preview
+					 * or video buffers, but does not
+					 * expect any notifications directly.
+					 * (preview/video data is updated from
+					 * postprocessing in such scenario).
+					 * In such case, there is no need to
+					 * update the mctl_handle in the intf
+					 * map table, since the notification
+					 * will not be sent directly. */
+					break;
+				}
+			}
+
+			old_handle =
+				g_server_dev.interface_map_table[i].mctl_handle;
+			if (old_handle == 0) {
+				g_server_dev.interface_map_table[i].mctl_handle
+					= mctl_handle;
+				g_server_dev.interface_map_table[i].
+					is_bayer_sensor = is_bayer_sensor;
+				g_server_dev.interface_map_table[i].vnode_id
+					= vnode_id;
+			} else {
+				if (!g_server_dev.interface_map_table[i].
+					is_bayer_sensor &&
+					(extendedmode ==
+					MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW ||
+					extendedmode ==
+					MSM_V4L2_EXT_CAPTURE_MODE_VIDEO ||
+					extendedmode ==
+					MSM_V4L2_EXT_CAPTURE_MODE_MAIN ||
+					extendedmode ==
+					MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL)) {
+					D("%s: SoC sensor, image_mode = %d",
+					__func__, extendedmode);
+					break;
+				}
+				if (old_handle != mctl_handle) {
+					pr_err("%s: iface_map[%d] is set: %d\n",
+						__func__, i, old_handle);
+					rc = -EINVAL;
+				}
+			}
+			break;
+		}
+	}
+
+	if (i == INTF_MAX)
+		rc = -EINVAL;
+	return rc;
+}
+
+void msm_cam_server_clear_interface_map(uint32_t mctl_handle)
+{
+	int i;
+	for (i = 0; i < INTF_MAX; i++)
+		if (g_server_dev.interface_map_table[i].
+			mctl_handle == mctl_handle)
+			g_server_dev.interface_map_table[i].
+				mctl_handle = 0;
+}
+
+struct iommu_domain *msm_cam_server_get_domain()
+{
+	return g_server_dev.domain;
+}
+
+int msm_cam_server_get_domain_num()
+{
+	return g_server_dev.domain_num;
+}
+
+uint32_t msm_cam_server_get_mctl_handle(void)
+{
+	uint32_t i;
+	if ((g_server_dev.mctl_handle_cnt << 8) == 0)
+		g_server_dev.mctl_handle_cnt++;
+	for (i = 0; i < MAX_NUM_ACTIVE_CAMERA; i++) {
+		if (g_server_dev.mctl[i].handle == 0) {
+			g_server_dev.mctl[i].handle =
+				(++g_server_dev.mctl_handle_cnt) << 8 | i;
+			memset(&g_server_dev.mctl[i].mctl,
+				0, sizeof(g_server_dev.mctl[i].mctl));
+			return g_server_dev.mctl[i].handle;
+		}
+	}
+	return 0;
+}
+
+void msm_cam_server_free_mctl(uint32_t handle)
+{
+	uint32_t mctl_index;
+	mctl_index = handle & 0xff;
+	if ((mctl_index < MAX_NUM_ACTIVE_CAMERA) &&
+		(g_server_dev.mctl[mctl_index].handle == handle))
+		g_server_dev.mctl[mctl_index].handle = 0;
+	else
+		pr_err("%s: invalid free handle\n", __func__);
+}
+
+struct msm_cam_media_controller *msm_cam_server_get_mctl(uint32_t handle)
+{
+	uint32_t mctl_index;
+	mctl_index = handle & 0xff;
+	if ((mctl_index < MAX_NUM_ACTIVE_CAMERA) &&
+		(g_server_dev.mctl[mctl_index].handle == handle))
+		return &g_server_dev.mctl[mctl_index].mctl;
+	return NULL;
+}
+
+
+static void msm_cam_server_send_error_evt(
+		struct msm_cam_media_controller *pmctl, int evt_type)
+{
+	struct v4l2_event v4l2_ev;
+	v4l2_ev.id = 0;
+	v4l2_ev.type = evt_type;
+	ktime_get_ts(&v4l2_ev.timestamp);
+	v4l2_event_queue(pmctl->pcam_ptr->pvdev, &v4l2_ev);
+}
+
+static int msm_ctrl_cmd_done(void *arg)
+{
+	void __user *uptr;
+	struct msm_queue_cmd *qcmd;
+	struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
+	struct msm_ctrl_cmd *command;
+	D("%s\n", __func__);
+
+	command = kzalloc(sizeof(struct msm_ctrl_cmd), GFP_KERNEL);
+	if (!command) {
+		pr_err("%s Insufficient memory. return", __func__);
+		goto command_alloc_fail;
+	}
+
+	qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
+	if (!qcmd) {
+		pr_err("%s Insufficient memory. return", __func__);
+		goto qcmd_alloc_fail;
+	}
+
+	mutex_lock(&g_server_dev.server_queue_lock);
+
+	if (copy_from_user(command, (void __user *)ioctl_ptr->ioctl_ptr,
+					   sizeof(struct msm_ctrl_cmd))) {
+		pr_err("%s: copy_from_user failed, size=%d\n",
+			__func__, sizeof(struct msm_ctrl_cmd));
+		goto ctrl_cmd_done_error;
+	}
+
+	if (!g_server_dev.server_queue[command->queue_idx].queue_active) {
+		pr_err("%s: Invalid queue\n", __func__);
+		goto ctrl_cmd_done_error;
+	}
+
+	D("%s qid %d evtid %d %d\n", __func__, command->queue_idx,
+		command->evt_id,
+		g_server_dev.server_queue[command->queue_idx].evt_id);
+
+	if (command->evt_id !=
+		g_server_dev.server_queue[command->queue_idx].evt_id) {
+		pr_err("Invalid event id from userspace\n");
+		goto ctrl_cmd_done_error;
+	}
+
+	atomic_set(&qcmd->on_heap, 1);
+	uptr = command->value;
+	qcmd->command = command;
+
+	if (command->length > 0) {
+		command->value =
+			g_server_dev.server_queue[command->queue_idx].ctrl_data;
+		if (command->length > MAX_SERVER_PAYLOAD_LENGTH) {
+			pr_err("%s: user data %d is too big (max %d)\n",
+				__func__, command->length,
+				max_control_command_size);
+			goto ctrl_cmd_done_error;
+		}
+		if (copy_from_user(command->value, uptr, command->length)) {
+			pr_err("%s: copy_from_user failed, size=%d\n",
+				__func__, sizeof(struct msm_ctrl_cmd));
+			goto ctrl_cmd_done_error;
+		}
+	}
+	msm_enqueue(&g_server_dev.server_queue
+		[command->queue_idx].ctrl_q, &qcmd->list_control);
+	mutex_unlock(&g_server_dev.server_queue_lock);
+	return 0;
+
+ctrl_cmd_done_error:
+	mutex_unlock(&g_server_dev.server_queue_lock);
+	free_qcmd(qcmd);
+qcmd_alloc_fail:
+	kfree(command);
+command_alloc_fail:
+	return -EINVAL;
+}
+
+/* send control command to config and wait for results*/
+static int msm_server_control(struct msm_cam_server_dev *server_dev,
+				uint32_t id, struct msm_ctrl_cmd *out)
+{
+	int rc = 0;
+	uint8_t wait_count;
+	void *value;
+	struct msm_queue_cmd *rcmd;
+	struct msm_queue_cmd *event_qcmd;
+	struct msm_ctrl_cmd *ctrlcmd;
+	struct msm_device_queue *queue =
+		&server_dev->server_queue[out->queue_idx].ctrl_q;
+
+	struct v4l2_event v4l2_evt;
+	struct msm_isp_event_ctrl *isp_event;
+	void *ctrlcmd_data;
+
+	event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
+	if (!event_qcmd) {
+		pr_err("%s Insufficient memory. return", __func__);
+		rc = -ENOMEM;
+		goto event_qcmd_alloc_fail;
+	}
+
+	isp_event = kzalloc(sizeof(struct msm_isp_event_ctrl), GFP_KERNEL);
+	if (!isp_event) {
+		pr_err("%s Insufficient memory. return", __func__);
+		rc = -ENOMEM;
+		goto isp_event_alloc_fail;
+	}
+
+	D("%s\n", __func__);
+	mutex_lock(&server_dev->server_queue_lock);
+	if (++server_dev->server_evt_id == 0)
+		server_dev->server_evt_id++;
+
+	D("%s qid %d evtid %d\n", __func__, out->queue_idx,
+		server_dev->server_evt_id);
+	server_dev->server_queue[out->queue_idx].evt_id =
+		server_dev->server_evt_id;
+	v4l2_evt.type = V4L2_EVENT_PRIVATE_START + MSM_CAM_RESP_V4L2;
+	v4l2_evt.id = id;
+	v4l2_evt.u.data[0] = out->queue_idx;
+	/* setup event object to transfer the command; */
+	isp_event->resptype = MSM_CAM_RESP_V4L2;
+	isp_event->isp_data.ctrl = *out;
+	isp_event->isp_data.ctrl.evt_id = server_dev->server_evt_id;
+
+	if (out->value != NULL && out->length != 0) {
+		ctrlcmd_data = kzalloc(out->length, GFP_KERNEL);
+		if (!ctrlcmd_data) {
+			rc = -ENOMEM;
+			goto ctrlcmd_alloc_fail;
+		}
+		memcpy(ctrlcmd_data, out->value, out->length);
+		isp_event->isp_data.ctrl.value = ctrlcmd_data;
+	}
+
+	atomic_set(&event_qcmd->on_heap, 1);
+	event_qcmd->command = isp_event;
+
+	msm_enqueue(&server_dev->server_queue[out->queue_idx].eventData_q,
+				&event_qcmd->list_eventdata);
+
+	/* now send command to config thread in userspace,
+	 * and wait for results */
+	v4l2_event_queue(server_dev->server_command_queue.pvdev,
+					  &v4l2_evt);
+	D("%s v4l2_event_queue: type = 0x%x\n", __func__, v4l2_evt.type);
+	mutex_unlock(&server_dev->server_queue_lock);
+
+	/* wait for config return status */
+	D("Waiting for config status\n");
+	/* wait event may be interrupted by sugnal,
+	 * in this case -ERESTARTSYS is returned and retry is needed.
+	 * Now we only retry once. */
+	wait_count = 2;
+	do {
+		rc = wait_event_interruptible_timeout(queue->wait,
+			!list_empty_careful(&queue->list),
+			msecs_to_jiffies(out->timeout_ms));
+		wait_count--;
+		if (rc != -ERESTARTSYS)
+			break;
+		D("%s: wait_event interrupted by signal, remain_count = %d",
+			__func__, wait_count);
+	} while (wait_count > 0);
+	D("Waiting is over for config status\n");
+	if (list_empty_careful(&queue->list)) {
+		if (!rc)
+			rc = -ETIMEDOUT;
+		if (rc < 0) {
+			if (++server_dev->server_evt_id == 0)
+				server_dev->server_evt_id++;
+			pr_err("%s: wait_event error %d\n", __func__, rc);
+			return rc;
+		}
+	}
+
+	rcmd = msm_dequeue(queue, list_control);
+	BUG_ON(!rcmd);
+	D("%s Finished servicing ioctl\n", __func__);
+
+	ctrlcmd = (struct msm_ctrl_cmd *)(rcmd->command);
+	value = out->value;
+	if (ctrlcmd->length > 0 && value != NULL &&
+		ctrlcmd->length <= out->length)
+		memcpy(value, ctrlcmd->value, ctrlcmd->length);
+
+	memcpy(out, ctrlcmd, sizeof(struct msm_ctrl_cmd));
+	out->value = value;
+
+	kfree(ctrlcmd);
+	free_qcmd(rcmd);
+	D("%s: rc %d\n", __func__, rc);
+	/* rc is the time elapsed.
+	 * This means that the communication with the daemon itself was
+	 * successful(irrespective of the handling of the ctrlcmd).
+	 * So, just reset the rc to 0 to indicate success.
+	 * Its upto the caller to parse the ctrlcmd to check the status. We
+	 * dont need to parse it here. */
+	if (rc >= 0)
+		rc = 0;
+
+	return rc;
+
+ctrlcmd_alloc_fail:
+	kfree(isp_event);
+isp_event_alloc_fail:
+	kfree(event_qcmd);
+event_qcmd_alloc_fail:
+	return rc;
+}
+
+int msm_server_private_general(struct msm_cam_v4l2_device *pcam,
+		struct msm_camera_v4l2_ioctl_t *ioctl_ptr)
+{
+	struct msm_ctrl_cmd ctrlcmd;
+	void *temp_data = NULL;
+	int rc;
+	if (ioctl_ptr->len > 0) {
+		temp_data = kzalloc(ioctl_ptr->len, GFP_KERNEL);
+		if (!temp_data) {
+			pr_err("%s could not allocate memory\n", __func__);
+			rc = -ENOMEM;
+			goto end;
+		}
+		if (copy_from_user((void *)temp_data,
+			(void __user *)ioctl_ptr->ioctl_ptr,
+			ioctl_ptr->len)) {
+			ERR_COPY_FROM_USER();
+			rc = -EFAULT;
+			goto copy_from_user_failed;
+		}
+	}
+
+	mutex_lock(&pcam->vid_lock);
+	ctrlcmd.type = MSM_V4L2_PRIVATE_CMD;
+	ctrlcmd.length = ioctl_ptr->len;
+	ctrlcmd.value = temp_data;
+	ctrlcmd.timeout_ms = 1000;
+	ctrlcmd.status = ioctl_ptr->id;
+	ctrlcmd.vnode_id = pcam->vnode_id;
+	ctrlcmd.queue_idx = pcam->server_queue_idx;
+	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+	/* send command to config thread in usersspace, and get return value */
+	rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
+	if (rc < 0)
+		pr_err("%s: send event failed\n", __func__);
+	else {
+		if (ioctl_ptr->len > 0) {
+			if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
+				(void *)temp_data,
+				ioctl_ptr->len)) {
+				ERR_COPY_TO_USER();
+				rc = -EFAULT;
+			}
+		}
+	}
+	mutex_unlock(&pcam->vid_lock);
+
+	kfree(temp_data);
+	return rc;
+copy_from_user_failed:
+	kfree(temp_data);
+end:
+return rc;
+}
+
+int msm_server_get_crop(struct msm_cam_v4l2_device *pcam,
+				int idx, struct v4l2_crop *crop)
+{
+	int rc = 0;
+	struct msm_ctrl_cmd ctrlcmd;
+
+	BUG_ON(crop == NULL);
+
+	ctrlcmd.type = MSM_V4L2_GET_CROP;
+	ctrlcmd.length = sizeof(struct v4l2_crop);
+	ctrlcmd.value = (void *)crop;
+	ctrlcmd.timeout_ms = 1000;
+	ctrlcmd.vnode_id = pcam->vnode_id;
+	ctrlcmd.queue_idx = pcam->server_queue_idx;
+	ctrlcmd.stream_type = pcam->dev_inst[idx]->image_mode;
+	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[
+						pcam->server_queue_idx];
+
+	/* send command to config thread in userspace, and get return value */
+	rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
+	D("%s: rc = %d\n", __func__, rc);
+
+	return rc;
+}
+
+/*send open command to server*/
+int msm_send_open_server(struct msm_cam_v4l2_device *pcam)
+{
+	int rc = 0;
+	struct msm_ctrl_cmd ctrlcmd;
+	int idx = pcam->server_queue_idx;
+	D("%s qid %d\n", __func__, pcam->server_queue_idx);
+	ctrlcmd.type	   = MSM_V4L2_OPEN;
+	ctrlcmd.timeout_ms = 10000;
+	ctrlcmd.length = strnlen(
+		g_server_dev.config_info.config_dev_name[idx],
+		MAX_DEV_NAME_LEN)+1;
+	ctrlcmd.value = (char *)g_server_dev.config_info.config_dev_name[idx];
+	ctrlcmd.vnode_id = pcam->vnode_id;
+	ctrlcmd.queue_idx = pcam->server_queue_idx;
+	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[idx];
+
+	/* send command to config thread in usersspace, and get return value */
+	rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
+
+	return rc;
+}
+
+int msm_send_close_server(struct msm_cam_v4l2_device *pcam)
+{
+	int rc = 0;
+	struct msm_ctrl_cmd ctrlcmd;
+	D("%s qid %d\n", __func__, pcam->server_queue_idx);
+	ctrlcmd.type	   = MSM_V4L2_CLOSE;
+	ctrlcmd.timeout_ms = 10000;
+	ctrlcmd.length	 = strnlen(g_server_dev.config_info.config_dev_name[
+				pcam->server_queue_idx], MAX_DEV_NAME_LEN)+1;
+	ctrlcmd.value    = (char *)g_server_dev.config_info.config_dev_name[
+				pcam->server_queue_idx];
+	ctrlcmd.vnode_id = pcam->vnode_id;
+	ctrlcmd.queue_idx = pcam->server_queue_idx;
+	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[
+						pcam->server_queue_idx];
+
+	/* send command to config thread in usersspace, and get return value */
+	rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
+
+	return rc;
+}
+
+int msm_server_set_fmt(struct msm_cam_v4l2_device *pcam, int idx,
+				 struct v4l2_format *pfmt)
+{
+	int rc = 0;
+	int i = 0;
+	struct v4l2_pix_format *pix = &pfmt->fmt.pix;
+	struct msm_ctrl_cmd ctrlcmd;
+	struct img_plane_info plane_info;
+
+	plane_info.width = pix->width;
+	plane_info.height = pix->height;
+	plane_info.pixelformat = pix->pixelformat;
+	plane_info.buffer_type = pfmt->type;
+	plane_info.ext_mode = pcam->dev_inst[idx]->image_mode;
+	plane_info.num_planes = 1;
+	plane_info.inst_handle = pcam->dev_inst[idx]->inst_handle;
+	D("%s: %d, %d, 0x%x\n", __func__,
+		pfmt->fmt.pix.width, pfmt->fmt.pix.height,
+		pfmt->fmt.pix.pixelformat);
+
+	if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		D("%s, Attention! Wrong buf-type %d\n", __func__, pfmt->type);
+
+	for (i = 0; i < pcam->num_fmts; i++)
+		if (pcam->usr_fmts[i].fourcc == pix->pixelformat)
+			break;
+	if (i == pcam->num_fmts) {
+		pr_err("%s: User requested pixelformat %x not supported\n",
+						__func__, pix->pixelformat);
+		return -EINVAL;
+	}
+
+	ctrlcmd.type       = MSM_V4L2_VID_CAP_TYPE;
+	ctrlcmd.length     = sizeof(struct img_plane_info);
+	ctrlcmd.value      = (void *)&plane_info;
+	ctrlcmd.timeout_ms = 10000;
+	ctrlcmd.vnode_id   = pcam->vnode_id;
+	ctrlcmd.queue_idx = pcam->server_queue_idx;
+	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+
+	/* send command to config thread in usersspace, and get return value */
+	rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
+
+	if (rc >= 0) {
+		pcam->dev_inst[idx]->vid_fmt = *pfmt;
+		pcam->dev_inst[idx]->sensor_pxlcode
+					= pcam->usr_fmts[i].pxlcode;
+		D("%s:inst=0x%x,idx=%d,width=%d,heigth=%d\n",
+			 __func__, (u32)pcam->dev_inst[idx], idx,
+			 pcam->dev_inst[idx]->vid_fmt.fmt.pix.width,
+			 pcam->dev_inst[idx]->vid_fmt.fmt.pix.height);
+		pcam->dev_inst[idx]->plane_info = plane_info;
+	}
+
+	return rc;
+}
+
+int msm_server_set_fmt_mplane(struct msm_cam_v4l2_device *pcam, int idx,
+				 struct v4l2_format *pfmt)
+{
+	int rc = 0;
+	int i = 0;
+	struct v4l2_pix_format_mplane *pix_mp = &pfmt->fmt.pix_mp;
+	struct msm_ctrl_cmd ctrlcmd;
+	struct img_plane_info plane_info;
+
+	plane_info.width = pix_mp->width;
+	plane_info.height = pix_mp->height;
+	plane_info.pixelformat = pix_mp->pixelformat;
+	plane_info.buffer_type = pfmt->type;
+	plane_info.ext_mode = pcam->dev_inst[idx]->image_mode;
+	plane_info.num_planes = pix_mp->num_planes;
+	plane_info.inst_handle = pcam->dev_inst[idx]->inst_handle;
+
+	if (plane_info.num_planes <= 0 ||
+		plane_info.num_planes > VIDEO_MAX_PLANES) {
+		pr_err("%s Invalid number of planes set %d", __func__,
+				plane_info.num_planes);
+		return -EINVAL;
+	}
+	D("%s: %d, %d, 0x%x\n", __func__,
+		pfmt->fmt.pix_mp.width, pfmt->fmt.pix_mp.height,
+		pfmt->fmt.pix_mp.pixelformat);
+
+	if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+		pr_err("%s, Attention! Wrong buf-type %d\n",
+			__func__, pfmt->type);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < pcam->num_fmts; i++)
+		if (pcam->usr_fmts[i].fourcc == pix_mp->pixelformat)
+			break;
+	if (i == pcam->num_fmts) {
+		pr_err("%s: User requested pixelformat %x not supported\n",
+						__func__, pix_mp->pixelformat);
+		return -EINVAL;
+	}
+
+	ctrlcmd.type       = MSM_V4L2_VID_CAP_TYPE;
+	ctrlcmd.length     = sizeof(struct img_plane_info);
+	ctrlcmd.value      = (void *)&plane_info;
+	ctrlcmd.timeout_ms = 10000;
+	ctrlcmd.vnode_id   = pcam->vnode_id;
+	ctrlcmd.queue_idx = pcam->server_queue_idx;
+
+	/* send command to config thread in usersspace, and get return value */
+	rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
+	if (rc >= 0) {
+		pcam->dev_inst[idx]->vid_fmt = *pfmt;
+		pcam->dev_inst[idx]->sensor_pxlcode
+					= pcam->usr_fmts[i].pxlcode;
+		D("%s:inst=0x%x,idx=%d,width=%d,heigth=%d\n",
+			 __func__, (u32)pcam->dev_inst[idx], idx,
+			 pcam->dev_inst[idx]->vid_fmt.fmt.pix_mp.width,
+			 pcam->dev_inst[idx]->vid_fmt.fmt.pix_mp.height);
+		pcam->dev_inst[idx]->plane_info = plane_info;
+	}
+
+	return rc;
+}
+
+int msm_server_streamon(struct msm_cam_v4l2_device *pcam, int idx)
+{
+	int rc = 0;
+	struct msm_ctrl_cmd ctrlcmd;
+	D("%s\n", __func__);
+	ctrlcmd.type	   = MSM_V4L2_STREAM_ON;
+	ctrlcmd.timeout_ms = 10000;
+	ctrlcmd.length	 = 0;
+	ctrlcmd.value    = NULL;
+	ctrlcmd.stream_type = pcam->dev_inst[idx]->image_mode;
+	ctrlcmd.vnode_id = pcam->vnode_id;
+	ctrlcmd.queue_idx = pcam->server_queue_idx;
+	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+
+
+	/* send command to config thread in usersspace, and get return value */
+	rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
+
+	return rc;
+}
+
+int msm_server_streamoff(struct msm_cam_v4l2_device *pcam, int idx)
+{
+	int rc = 0;
+	struct msm_ctrl_cmd ctrlcmd;
+
+	D("%s, pcam = 0x%x\n", __func__, (u32)pcam);
+	ctrlcmd.type        = MSM_V4L2_STREAM_OFF;
+	ctrlcmd.timeout_ms  = 10000;
+	ctrlcmd.length      = 0;
+	ctrlcmd.value       = NULL;
+	ctrlcmd.stream_type = pcam->dev_inst[idx]->image_mode;
+	ctrlcmd.vnode_id = pcam->vnode_id;
+	ctrlcmd.queue_idx = pcam->server_queue_idx;
+	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+
+	/* send command to config thread in usersspace, and get return value */
+	rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
+
+	return rc;
+}
+
+int msm_server_proc_ctrl_cmd(struct msm_cam_v4l2_device *pcam,
+		struct msm_camera_v4l2_ioctl_t *ioctl_ptr, int is_set_cmd)
+{
+	int rc = 0;
+	struct msm_ctrl_cmd ctrlcmd, tmp_cmd, *cmd_ptr;
+	uint8_t *ctrl_data = NULL;
+	uint32_t cmd_len = sizeof(struct msm_ctrl_cmd);
+	uint32_t value_len;
+
+	if (copy_from_user(&tmp_cmd,
+		(void __user *)ioctl_ptr->ioctl_ptr, cmd_len)) {
+		pr_err("%s: copy_from_user failed.\n", __func__);
+		rc = -EINVAL;
+		goto end;
+	}
+	value_len = tmp_cmd.length;
+	ctrl_data = kzalloc(value_len+cmd_len, GFP_KERNEL);
+	if (!ctrl_data) {
+		pr_err("%s could not allocate memory\n", __func__);
+		rc = -ENOMEM;
+		goto end;
+	}
+
+	cmd_ptr = (struct msm_ctrl_cmd *) ctrl_data;
+	*cmd_ptr = tmp_cmd;
+	if (tmp_cmd.value && tmp_cmd.length > 0) {
+		cmd_ptr->value = (void *)(ctrl_data+cmd_len);
+		if (copy_from_user((void *)cmd_ptr->value,
+				   (void __user *)tmp_cmd.value,
+				   value_len)) {
+			pr_err("%s: copy_from_user failed.\n", __func__);
+			rc = -EINVAL;
+			goto end;
+		}
+	} else {
+		cmd_ptr->value = NULL;
+	}
+
+	D("%s: cmd type = %d, up1=0x%x, ulen1=%d, up2=0x%x, ulen2=%d\n",
+		__func__, tmp_cmd.type, (uint32_t)ioctl_ptr->ioctl_ptr, cmd_len,
+		(uint32_t)tmp_cmd.value, tmp_cmd.length);
+
+	ctrlcmd.type = MSM_V4L2_SET_CTRL_CMD;
+	ctrlcmd.length = cmd_len + value_len;
+	ctrlcmd.value = (void *)ctrl_data;
+	if (tmp_cmd.timeout_ms > 0)
+		ctrlcmd.timeout_ms = tmp_cmd.timeout_ms;
+	else
+		ctrlcmd.timeout_ms = 1000;
+	ctrlcmd.vnode_id = pcam->vnode_id;
+	ctrlcmd.queue_idx = pcam->server_queue_idx;
+	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+	/* send command to config thread in usersspace, and get return value */
+	rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
+	D("%s: msm_server_control rc=%d\n", __func__, rc);
+	if (rc == 0) {
+		if (tmp_cmd.value && tmp_cmd.length > 0 &&
+			copy_to_user((void __user *)tmp_cmd.value,
+				(void *)(ctrl_data+cmd_len), tmp_cmd.length)) {
+			pr_err("%s: copy_to_user failed, size=%d\n",
+				__func__, tmp_cmd.length);
+			rc = -EINVAL;
+			goto end;
+		}
+		tmp_cmd.status = cmd_ptr->status = ctrlcmd.status;
+		if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
+			(void *)cmd_ptr, cmd_len)) {
+			pr_err("%s: copy_to_user failed in cpy, size=%d\n",
+				__func__, cmd_len);
+			rc = -EINVAL;
+			goto end;
+		}
+	}
+end:
+	D("%s: END, type = %d, vaddr = 0x%x, vlen = %d, status = %d, rc = %d\n",
+		__func__, tmp_cmd.type, (uint32_t)tmp_cmd.value,
+		tmp_cmd.length, tmp_cmd.status, rc);
+	kfree(ctrl_data);
+	ctrl_data = NULL;
+	return rc;
+}
+
+int msm_server_s_ctrl(struct msm_cam_v4l2_device *pcam,
+				 struct v4l2_control *ctrl)
+{
+	int rc = 0;
+	struct msm_ctrl_cmd ctrlcmd;
+	uint8_t ctrl_data[max_control_command_size];
+
+	WARN_ON(ctrl == NULL);
+	if (ctrl == NULL) {
+		pr_err("%s Invalid control\n", __func__);
+		return -EINVAL;
+	}
+
+	memset(ctrl_data, 0, sizeof(ctrl_data));
+
+	ctrlcmd.type = MSM_V4L2_SET_CTRL;
+	ctrlcmd.length = sizeof(struct v4l2_control);
+	ctrlcmd.value = (void *)ctrl_data;
+	memcpy(ctrlcmd.value, ctrl, ctrlcmd.length);
+	ctrlcmd.timeout_ms = 1000;
+	ctrlcmd.vnode_id = pcam->vnode_id;
+	ctrlcmd.queue_idx = pcam->server_queue_idx;
+	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+
+	/* send command to config thread in usersspace, and get return value */
+	rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
+
+	return rc;
+}
+
+int msm_server_g_ctrl(struct msm_cam_v4l2_device *pcam,
+				 struct v4l2_control *ctrl)
+{
+	int rc = 0;
+	struct msm_ctrl_cmd ctrlcmd;
+	uint8_t ctrl_data[max_control_command_size];
+
+	WARN_ON(ctrl == NULL);
+	if (ctrl == NULL) {
+		pr_err("%s Invalid control\n", __func__);
+		return -EINVAL;
+	}
+
+	memset(ctrl_data, 0, sizeof(ctrl_data));
+
+	ctrlcmd.type = MSM_V4L2_GET_CTRL;
+	ctrlcmd.length = sizeof(struct v4l2_control);
+	ctrlcmd.value = (void *)ctrl_data;
+	memcpy(ctrlcmd.value, ctrl, ctrlcmd.length);
+	ctrlcmd.timeout_ms = 1000;
+	ctrlcmd.vnode_id = pcam->vnode_id;
+	ctrlcmd.queue_idx = pcam->server_queue_idx;
+	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+
+	/* send command to config thread in usersspace, and get return value */
+	rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
+
+	ctrl->value = ((struct v4l2_control *)ctrlcmd.value)->value;
+
+	return rc;
+}
+
+int msm_server_q_ctrl(struct msm_cam_v4l2_device *pcam,
+			struct v4l2_queryctrl *queryctrl)
+{
+	int rc = 0;
+	struct msm_ctrl_cmd ctrlcmd;
+	uint8_t ctrl_data[max_control_command_size];
+
+	WARN_ON(queryctrl == NULL);
+	memset(ctrl_data, 0, sizeof(ctrl_data));
+
+	ctrlcmd.type = MSM_V4L2_QUERY_CTRL;
+	ctrlcmd.length = sizeof(struct v4l2_queryctrl);
+	ctrlcmd.value = (void *)ctrl_data;
+	memcpy(ctrlcmd.value, queryctrl, ctrlcmd.length);
+	ctrlcmd.timeout_ms = 1000;
+	ctrlcmd.vnode_id = pcam->vnode_id;
+	ctrlcmd.queue_idx = pcam->server_queue_idx;
+	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+
+	/* send command to config thread in userspace, and get return value */
+	rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
+	D("%s: rc = %d\n", __func__, rc);
+
+	if (rc >= 0)
+		memcpy(queryctrl, ctrlcmd.value, sizeof(struct v4l2_queryctrl));
+
+	return rc;
+}
+
+int msm_server_get_fmt(struct msm_cam_v4l2_device *pcam,
+		 int idx, struct v4l2_format *pfmt)
+{
+	struct v4l2_pix_format *pix = &pfmt->fmt.pix;
+
+	pix->width        = pcam->dev_inst[idx]->vid_fmt.fmt.pix.width;
+	pix->height       = pcam->dev_inst[idx]->vid_fmt.fmt.pix.height;
+	pix->field        = pcam->dev_inst[idx]->vid_fmt.fmt.pix.field;
+	pix->pixelformat  = pcam->dev_inst[idx]->vid_fmt.fmt.pix.pixelformat;
+	pix->bytesperline = pcam->dev_inst[idx]->vid_fmt.fmt.pix.bytesperline;
+	pix->colorspace   = pcam->dev_inst[idx]->vid_fmt.fmt.pix.colorspace;
+	if (pix->bytesperline < 0)
+		return pix->bytesperline;
+
+	pix->sizeimage    = pix->height * pix->bytesperline;
+
+	return 0;
+}
+
+int msm_server_get_fmt_mplane(struct msm_cam_v4l2_device *pcam,
+		 int idx, struct v4l2_format *pfmt)
+{
+	*pfmt = pcam->dev_inst[idx]->vid_fmt;
+	return 0;
+}
+
+int msm_server_try_fmt(struct msm_cam_v4l2_device *pcam,
+				 struct v4l2_format *pfmt)
+{
+	int rc = 0;
+	int i = 0;
+	struct v4l2_pix_format *pix = &pfmt->fmt.pix;
+
+	D("%s: 0x%x\n", __func__, pix->pixelformat);
+	if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		pr_err("%s: pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE!\n",
+							__func__);
+		return -EINVAL;
+	}
+
+	/* check if the format is supported by this host-sensor combo */
+	for (i = 0; i < pcam->num_fmts; i++) {
+		D("%s: usr_fmts.fourcc: 0x%x\n", __func__,
+			pcam->usr_fmts[i].fourcc);
+		if (pcam->usr_fmts[i].fourcc == pix->pixelformat)
+			break;
+	}
+
+	if (i == pcam->num_fmts) {
+		pr_err("%s: Format %x not found\n", __func__, pix->pixelformat);
+		return -EINVAL;
+	}
+	return rc;
+}
+
+int msm_server_try_fmt_mplane(struct msm_cam_v4l2_device *pcam,
+				 struct v4l2_format *pfmt)
+{
+	int rc = 0;
+	int i = 0;
+	struct v4l2_pix_format_mplane *pix_mp = &pfmt->fmt.pix_mp;
+
+	D("%s: 0x%x\n", __func__, pix_mp->pixelformat);
+	if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+		pr_err("%s: Incorrect format type %d ",
+			__func__, pfmt->type);
+		return -EINVAL;
+	}
+
+	/* check if the format is supported by this host-sensor combo */
+	for (i = 0; i < pcam->num_fmts; i++) {
+		D("%s: usr_fmts.fourcc: 0x%x\n", __func__,
+			pcam->usr_fmts[i].fourcc);
+		if (pcam->usr_fmts[i].fourcc == pix_mp->pixelformat)
+			break;
+	}
+
+	if (i == pcam->num_fmts) {
+		pr_err("%s: Format %x not found\n",
+			__func__, pix_mp->pixelformat);
+		return -EINVAL;
+	}
+	return rc;
+}
+
+int msm_server_v4l2_subscribe_event(struct v4l2_fh *fh,
+			struct v4l2_event_subscription *sub)
+{
+	int rc = 0;
+
+	D("%s: fh = 0x%x, type = 0x%x", __func__, (u32)fh, sub->type);
+	if (sub->type == V4L2_EVENT_ALL) {
+		/*sub->type = MSM_ISP_EVENT_START;*/
+		sub->type = V4L2_EVENT_PRIVATE_START + MSM_CAM_RESP_CTRL;
+		D("sub->type start = 0x%x\n", sub->type);
+		do {
+			rc = v4l2_event_subscribe(fh, sub, 30);

+			if (rc < 0) {
+				D("%s: failed for evtType = 0x%x, rc = %d\n",
+						__func__, sub->type, rc);
+			/* unsubscribe all events here and return */
+			sub->type = V4L2_EVENT_ALL;
+			v4l2_event_unsubscribe(fh, sub);
+			return rc;
+			} else
+				D("%s: subscribed evtType = 0x%x, rc = %d\n",
+						__func__, sub->type, rc);
+			sub->type++;
+			D("sub->type while = 0x%x\n", sub->type);
+		} while (sub->type !=
+			V4L2_EVENT_PRIVATE_START + MSM_SVR_RESP_MAX);
+	} else {
+		D("sub->type not V4L2_EVENT_ALL = 0x%x\n", sub->type);
+		rc = v4l2_event_subscribe(fh, sub, 30);

+		if (rc < 0)
+			D("%s: failed for evtType = 0x%x, rc = %d\n",
+						__func__, sub->type, rc);
+	}
+
+	D("%s: rc = %d\n", __func__, rc);
+	return rc;
+}
+
+int msm_server_v4l2_unsubscribe_event(struct v4l2_fh *fh,
+			struct v4l2_event_subscription *sub)
+{
+	int rc = 0;
+	struct v4l2_event ev;
+
+	D("%s: fh = 0x%x\n", __func__, (u32)fh);
+
+	/* Undequeue all pending events and free associated
+	 * msm_isp_event_ctrl  */
+	while (v4l2_event_pending(fh)) {
+		struct msm_isp_event_ctrl *isp_event;
+		rc = v4l2_event_dequeue(fh, &ev, O_NONBLOCK);
+		if (rc) {
+			pr_err("%s: v4l2_event_dequeue failed %d",
+						__func__, rc);
+			break;
+		}
+		isp_event = (struct msm_isp_event_ctrl *)
+			(*((uint32_t *)ev.u.data));
+		if (isp_event) {
+			if (isp_event->isp_data.isp_msg.len != 0 &&
+				isp_event->isp_data.isp_msg.data != NULL) {
+				kfree(isp_event->isp_data.isp_msg.data);
+				isp_event->isp_data.isp_msg.len = 0;
+				isp_event->isp_data.isp_msg.data = NULL;
+			}
+			kfree(isp_event);
+			*((uint32_t *)ev.u.data) = 0;
+		}
+	}
+
+	rc = v4l2_event_unsubscribe(fh, sub);
+	D("%s: rc = %d\n", __func__, rc);
+	return rc;
+}
+
+/* open an active camera session to manage the streaming logic */
+static int msm_cam_server_open_session(struct msm_cam_server_dev *ps,
+	struct msm_cam_v4l2_device *pcam)
+{
+	int rc = 0;
+
+	D("%s\n", __func__);
+
+	if (!ps || !pcam) {
+		pr_err("%s NULL pointer passed in!\n", __func__);
+		return rc;
+	}
+
+	/*
+	 * The number of camera instance should be controlled by the
+	 * resource manager. Currently supporting two active instances
+	 */
+	if (atomic_read(&ps->number_pcam_active) > 1) {
+		pr_err("%s Cannot have more than two active camera %d\n",
+			__func__, atomic_read(&ps->number_pcam_active));
+		return -EINVAL;
+	}
+	/* book keeping this camera session*/
+	ps->pcam_active[pcam->server_queue_idx] = pcam;
+	ps->opened_pcam[pcam->vnode_id] = pcam;
+	atomic_inc(&ps->number_pcam_active);
+
+	D("config pcam = 0x%p\n", pcam);
+
+	/* initialization the media controller module*/
+	msm_mctl_init(pcam);
+
+	return rc;
+}
+
+/* close an active camera session to server */
+static int msm_cam_server_close_session(struct msm_cam_server_dev *ps,
+	struct msm_cam_v4l2_device *pcam)
+{
+	int i;
+	int rc = 0;
+	D("%s\n", __func__);
+
+	if (!ps || !pcam) {
+		D("%s NULL pointer passed in!\n", __func__);
+		return rc;
+	}
+
+	atomic_dec(&ps->number_pcam_active);
+	ps->pcam_active[pcam->server_queue_idx] = NULL;
+	ps->opened_pcam[pcam->vnode_id] = NULL;
+	for (i = 0; i < INTF_MAX; i++) {
+		if (ps->interface_map_table[i].mctl_handle ==
+			pcam->mctl_handle)
+			ps->interface_map_table[i].mctl_handle = 0;
+	}
+	msm_mctl_free(pcam);
+	return rc;
+}
+
+static int map_imem_addresses(struct msm_cam_media_controller *mctl)
+{
+	int rc = 0;
+	rc = msm_iommu_map_contig_buffer(
+		(unsigned long)IMEM_Y_PING_OFFSET, mctl->domain_num, 0,
+		((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)),
+		SZ_4K, IOMMU_WRITE | IOMMU_READ,
+		(unsigned long *)&mctl->ping_imem_y);
+	mctl->ping_imem_cbcr = mctl->ping_imem_y + IMEM_Y_SIZE;
+	if (rc < 0) {
+		pr_err("%s: ping iommu mapping returned error %d\n",
+			__func__, rc);
+		mctl->ping_imem_y = 0;
+		mctl->ping_imem_cbcr = 0;
+	}
+	msm_iommu_map_contig_buffer(
+		(unsigned long)IMEM_Y_PONG_OFFSET, mctl->domain_num, 0,
+		((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)),
+		SZ_4K, IOMMU_WRITE | IOMMU_READ,
+		(unsigned long *)&mctl->pong_imem_y);
+	mctl->pong_imem_cbcr = mctl->pong_imem_y + IMEM_Y_SIZE;
+	if (rc < 0) {
+		pr_err("%s: pong iommu mapping returned error %d\n",
+			 __func__, rc);
+		mctl->pong_imem_y = 0;
+		mctl->pong_imem_cbcr = 0;
+	}
+	return rc;
+}
+
+static void unmap_imem_addresses(struct msm_cam_media_controller *mctl)
+{
+	msm_iommu_unmap_contig_buffer(mctl->ping_imem_y,
+		mctl->domain_num, 0,
+		((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)));
+	msm_iommu_unmap_contig_buffer(mctl->pong_imem_y,
+		mctl->domain_num, 0,
+		((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)));
+	mctl->ping_imem_y = 0;
+	mctl->ping_imem_cbcr = 0;
+	mctl->pong_imem_y = 0;
+	mctl->pong_imem_cbcr = 0;
+}
+
+static long msm_ioctl_server(struct file *file, void *fh,
+		bool valid_prio, int cmd, void *arg)
+{
+	int rc = -EINVAL;
+	struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
+	struct msm_camera_info temp_cam_info;
+	struct msm_cam_config_dev_info temp_config_info;
+	struct msm_mctl_node_info temp_mctl_info;
+	int i;
+
+	D("%s: cmd %d\n", __func__, _IOC_NR(cmd));
+
+	switch (cmd) {
+	case MSM_CAM_V4L2_IOCTL_GET_CAMERA_INFO:
+		if (copy_from_user(&temp_cam_info,
+				(void __user *)ioctl_ptr->ioctl_ptr,
+				sizeof(struct msm_camera_info))) {
+			pr_err("%s Copy from user failed for cmd %d",
+				__func__, cmd);
+			rc = -EINVAL;
+			return rc;
+		}
+		for (i = 0; i < g_server_dev.camera_info.num_cameras; i++) {
+			if (copy_to_user((void __user *)
+			temp_cam_info.video_dev_name[i],
+			g_server_dev.camera_info.video_dev_name[i],
+			strnlen(g_server_dev.camera_info.video_dev_name[i],
+				MAX_DEV_NAME_LEN))) {
+				pr_err("%s Copy to user failed for cmd %d",
+					__func__, cmd);
+				rc = -EINVAL;
+				return rc;
+			}
+			temp_cam_info.has_3d_support[i] =
+				g_server_dev.camera_info.has_3d_support[i];
+			temp_cam_info.is_internal_cam[i] =
+				g_server_dev.camera_info.is_internal_cam[i];
+			temp_cam_info.s_mount_angle[i] =
+				g_server_dev.camera_info.s_mount_angle[i];
+			temp_cam_info.sensor_type[i] =
+				g_server_dev.camera_info.sensor_type[i];
+
+		}
+		temp_cam_info.num_cameras =
+			g_server_dev.camera_info.num_cameras;
+		if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
+			&temp_cam_info,	sizeof(struct msm_camera_info))) {
+			pr_err("%s Copy to user failed for cmd %d",
+				__func__, cmd);
+			rc = -EINVAL;
+			return rc;
+		}
+		rc = 0;
+		break;
+
+	case MSM_CAM_V4L2_IOCTL_GET_CONFIG_INFO:
+		if (copy_from_user(&temp_config_info,
+			(void __user *)ioctl_ptr->ioctl_ptr,
+			sizeof(struct msm_cam_config_dev_info))) {
+			pr_err("%s Copy from user failed for cmd %d",
+				__func__, cmd);
+			rc = -EINVAL;
+			return rc;
+		}
+		for (i = 0;
+		 i < g_server_dev.config_info.num_config_nodes; i++) {
+			if (copy_to_user(
+			(void __user *)temp_config_info.config_dev_name[i],
+			g_server_dev.config_info.config_dev_name[i],
+			strnlen(g_server_dev.config_info.config_dev_name[i],
+				MAX_DEV_NAME_LEN))) {
+				pr_err("%s Copy to user failed for cmd %d",
+					__func__, cmd);
+				rc = -EINVAL;
+				return rc;
+			}
+		}
+		temp_config_info.num_config_nodes =
+			g_server_dev.config_info.num_config_nodes;
+		if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
+			&temp_config_info,
+			sizeof(struct msm_cam_config_dev_info))) {
+			pr_err("%s Copy to user failed for cmd %d",
+				__func__, cmd);
+			rc = -EINVAL;
+			return rc;
+		}
+		rc = 0;
+		break;
+	case MSM_CAM_V4L2_IOCTL_GET_MCTL_INFO:
+		if (copy_from_user(&temp_mctl_info,
+				(void __user *)ioctl_ptr->ioctl_ptr,
+				sizeof(struct msm_mctl_node_info))) {
+			pr_err("%s Copy from user failed for cmd %d",
+				__func__, cmd);
+			rc = -EINVAL;
+			return rc;
+		}
+		for (i = 0; i < g_server_dev.mctl_node_info.num_mctl_nodes;
+				i++) {
+			if (copy_to_user((void __user *)
+			temp_mctl_info.mctl_node_name[i],
+			g_server_dev.mctl_node_info.mctl_node_name[i], strnlen(
+			g_server_dev.mctl_node_info.mctl_node_name[i],
+			MAX_DEV_NAME_LEN))) {
+				pr_err("%s Copy to user failed for cmd %d",
+					__func__, cmd);
+				rc = -EINVAL;
+				return rc;
+			}
+		}
+		temp_mctl_info.num_mctl_nodes =
+			g_server_dev.mctl_node_info.num_mctl_nodes;
+		if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
+			&temp_mctl_info, sizeof(struct msm_mctl_node_info))) {
+			pr_err("%s Copy to user failed for cmd %d",
+				__func__, cmd);
+			rc = -EINVAL;
+			return rc;
+		}
+		rc = 0;
+	break;
+
+	case MSM_CAM_V4L2_IOCTL_CTRL_CMD_DONE:
+		D("%s: MSM_CAM_IOCTL_CTRL_CMD_DONE\n", __func__);
+		rc = msm_ctrl_cmd_done(arg);
+		break;
+
+	case MSM_CAM_V4L2_IOCTL_GET_EVENT_PAYLOAD: {
+		struct msm_queue_cmd *event_cmd;
+		struct msm_isp_event_ctrl u_isp_event;
+		struct msm_isp_event_ctrl *k_isp_event;
+		struct msm_device_queue *queue;
+		void __user *u_ctrl_value = NULL;
+		if (copy_from_user(&u_isp_event,
+			(void __user *)ioctl_ptr->ioctl_ptr,
+			sizeof(struct msm_isp_event_ctrl))) {
+			pr_err("%s Copy from user failed for cmd %d",
+				__func__, cmd);
+			rc = -EINVAL;
+			return rc;
+		}
+
+		mutex_lock(&g_server_dev.server_queue_lock);
+		if (!g_server_dev.server_queue
+			[u_isp_event.isp_data.ctrl.queue_idx].queue_active) {
+			pr_err("%s: Invalid queue\n", __func__);
+			mutex_unlock(&g_server_dev.server_queue_lock);
+			rc = -EINVAL;
+			return rc;
+		}
+		queue = &g_server_dev.server_queue
+			[u_isp_event.isp_data.ctrl.queue_idx].eventData_q;
+		event_cmd = msm_dequeue(queue, list_eventdata);
+		if (!event_cmd) {
+			pr_err("%s: No event payload\n", __func__);
+			rc = -EINVAL;
+			mutex_unlock(&g_server_dev.server_queue_lock);
+			return rc;
+		}
+		k_isp_event = (struct msm_isp_event_ctrl *)
+				event_cmd->command;
+		free_qcmd(event_cmd);
+
+		/* Save the pointer of the user allocated command buffer*/
+		u_ctrl_value = u_isp_event.isp_data.ctrl.value;
+
+		/* Copy the event structure into user struct*/
+		u_isp_event = *k_isp_event;
+
+		/* Restore the saved pointer of the user
+		 * allocated command buffer. */
+		u_isp_event.isp_data.ctrl.value = u_ctrl_value;
+
+		/* Copy the ctrl cmd, if present*/
+		if (k_isp_event->isp_data.ctrl.length > 0 &&
+			k_isp_event->isp_data.ctrl.value != NULL) {
+			void *k_ctrl_value =
+				k_isp_event->isp_data.ctrl.value;
+			if (copy_to_user(u_ctrl_value, k_ctrl_value,
+				 k_isp_event->isp_data.ctrl.length)) {
+				pr_err("%s Copy to user failed for cmd %d",
+					__func__, cmd);
+				kfree(k_isp_event->isp_data.ctrl.value);
+				kfree(k_isp_event);
+				rc = -EINVAL;
+				mutex_unlock(&g_server_dev.server_queue_lock);
+				break;
+			}
+			kfree(k_isp_event->isp_data.ctrl.value);
+		}
+		if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
+			&u_isp_event, sizeof(struct msm_isp_event_ctrl))) {
+			pr_err("%s Copy to user failed for cmd %d",
+				__func__, cmd);
+			kfree(k_isp_event);
+			mutex_unlock(&g_server_dev.server_queue_lock);
+			rc = -EINVAL;
+			return rc;
+		}
+		kfree(k_isp_event);
+		mutex_unlock(&g_server_dev.server_queue_lock);
+		rc = 0;
+		break;
+	}
+
+	case MSM_CAM_IOCTL_SEND_EVENT:
+		rc = msm_server_send_v4l2_evt(arg);
+		break;
+
+	default:
+		pr_err("%s: Invalid IOCTL = %d", __func__, cmd);
+		break;
+	}
+	return rc;
+}
+
+static int msm_open_server(struct file *fp)
+{
+	int rc = 0;
+	D("%s: open %s\n", __func__, fp->f_path.dentry->d_name.name);
+	mutex_lock(&g_server_dev.server_lock);
+	g_server_dev.use_count++;
+	if (g_server_dev.use_count == 1)
+		fp->private_data =
+			&g_server_dev.server_command_queue.eventHandle;
+	mutex_unlock(&g_server_dev.server_lock);
+	return rc;
+}
+
+static int msm_close_server(struct file *fp)
+{
+	struct v4l2_event_subscription sub;
+	D("%s\n", __func__);
+	mutex_lock(&g_server_dev.server_lock);
+	if (g_server_dev.use_count > 0)
+		g_server_dev.use_count--;
+	mutex_unlock(&g_server_dev.server_lock);
+
+	if (g_server_dev.use_count == 0) {
+		int i;
+		mutex_lock(&g_server_dev.server_lock);
+		for (i = 0; i < MAX_NUM_ACTIVE_CAMERA; i++) {
+			if (g_server_dev.pcam_active[i]) {
+				struct msm_cam_media_controller *pmctl = NULL;
+
+				pmctl = msm_cam_server_get_mctl(
+				g_server_dev.pcam_active[i]->mctl_handle);
+				if (pmctl && pmctl->mctl_release) {
+					pmctl->mctl_release(pmctl);
+					/*so that it isn't closed again*/
+					pmctl->mctl_release = NULL;
+				}
+				if (pmctl)
+					msm_cam_server_send_error_evt(pmctl,
+						V4L2_EVENT_PRIVATE_START +
+						MSM_CAM_APP_NOTIFY_ERROR_EVENT);
+			}
+		}
+		sub.type = V4L2_EVENT_ALL;
+		v4l2_event_unsubscribe(
+			&g_server_dev.server_command_queue.eventHandle, &sub);
+		mutex_unlock(&g_server_dev.server_lock);
+	}
+	return 0;
+}
+
+static unsigned int msm_poll_server(struct file *fp,
+					struct poll_table_struct *wait)
+{
+	int rc = 0;
+
+	D("%s\n", __func__);
+	poll_wait(fp,
+		 &g_server_dev.server_command_queue.eventHandle.wait,

+		 wait);
+	if (v4l2_event_pending(&g_server_dev.server_command_queue.eventHandle))
+		rc |= POLLPRI;
+
+	return rc;
+}
+
+int msm_server_get_usecount(void)
+{
+	return g_server_dev.use_count;
+}
+
+int msm_server_update_sensor_info(struct msm_cam_v4l2_device *pcam,
+	struct msm_camera_sensor_info *sdata)
+{
+	int rc = 0;
+
+	if (!pcam || !sdata) {
+		pr_err("%s Input data is null ", __func__);
+		return -EINVAL;
+	}
+
+	g_server_dev.camera_info.video_dev_name
+	[g_server_dev.camera_info.num_cameras]
+	= video_device_node_name(pcam->pvdev);
+	D("%s Connected video device %s\n", __func__,
+		g_server_dev.camera_info.video_dev_name
+		[g_server_dev.camera_info.num_cameras]);
+
+	g_server_dev.camera_info.s_mount_angle
+	[g_server_dev.camera_info.num_cameras]
+	= sdata->sensor_platform_info->mount_angle;
+
+	g_server_dev.camera_info.is_internal_cam
+	[g_server_dev.camera_info.num_cameras]
+	= sdata->camera_type;
+
+	g_server_dev.mctl_node_info.mctl_node_name
+	[g_server_dev.mctl_node_info.num_mctl_nodes]
+	= video_device_node_name(pcam->mctl_node.pvdev);
+
+	pr_info("%s mctl_node_name[%d] = %s\n", __func__,
+		g_server_dev.mctl_node_info.num_mctl_nodes,
+		g_server_dev.mctl_node_info.mctl_node_name
+		[g_server_dev.mctl_node_info.num_mctl_nodes]);
+
+	/*Temporary solution to store info in media device structure
+	  until we can expand media device structure to support more
+	  device info*/
+	snprintf(pcam->media_dev.serial,
+			sizeof(pcam->media_dev.serial),
+			"%s-%d-%d", QCAMERA_NAME,
+			sdata->sensor_platform_info->mount_angle,
+			sdata->camera_type);
+
+	g_server_dev.camera_info.num_cameras++;
+	g_server_dev.mctl_node_info.num_mctl_nodes++;
+
+	D("%s done, rc = %d\n", __func__, rc);
+	D("%s number of sensors connected is %d\n", __func__,
+		g_server_dev.camera_info.num_cameras);
+
+	return rc;
+}
+
+int msm_server_begin_session(struct msm_cam_v4l2_device *pcam,
+	int server_q_idx)
+{
+	int rc = -EINVAL, ges_evt;
+	struct msm_cam_server_queue *queue;
+	struct msm_cam_media_controller *pmctl;
+
+	if (!pcam) {
+		pr_err("%s pcam passed is null ", __func__);
+		return rc;
+	}
+
+	ges_evt = MSM_V4L2_GES_CAM_OPEN;
+	D("%s send gesture evt\n", __func__);
+	msm_cam_server_subdev_notify(g_server_dev.gesture_device,
+		NOTIFY_GESTURE_CAM_EVT, &ges_evt);
+
+	pcam->server_queue_idx = server_q_idx;
+	queue = &g_server_dev.server_queue[server_q_idx];
+	queue->ctrl_data = kzalloc(sizeof(uint8_t) *
+			MAX_SERVER_PAYLOAD_LENGTH, GFP_KERNEL);
+	if (queue->ctrl_data == NULL) {
+		pr_err("%s: Could not allocate memory\n", __func__);
+		rc = -ENOMEM;
+		goto error;
+	}
+	msm_queue_init(&queue->ctrl_q, "control");
+	msm_queue_init(&queue->eventData_q, "eventdata");
+	queue->queue_active = 1;
+	rc = msm_cam_server_open_session(&g_server_dev, pcam);
+	if (rc < 0) {
+		pr_err("%s: cam_server_open_session failed %d\n",
+			__func__, rc);
+		goto error;
+	}
+
+	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
+	if (!pmctl) {
+		pr_err("%s: invalid mctl controller", __func__);
+		goto error;
+	}
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+		pmctl->domain = msm_cam_server_get_domain();
+		pmctl->domain_num = msm_cam_server_get_domain_num();
+#endif
+	rc = map_imem_addresses(pmctl);
+	if (rc < 0) {
+		pr_err("%sFailed to map imem addresses %d\n", __func__, rc);
+		goto error;
+	}
+
+	return rc;
+error:
+	ges_evt = MSM_V4L2_GES_CAM_CLOSE;
+	msm_cam_server_subdev_notify(g_server_dev.gesture_device,
+		NOTIFY_GESTURE_CAM_EVT, &ges_evt);
+
+	queue->queue_active = 0;
+	msm_drain_eventq(&queue->eventData_q);
+	msm_queue_drain(&queue->ctrl_q, list_control);
+	kfree(queue->ctrl_data);
+	queue->ctrl_data = NULL;
+	queue = NULL;
+	return rc;
+}
+
+int msm_server_end_session(struct msm_cam_v4l2_device *pcam)
+{
+	int rc = -EINVAL, ges_evt;
+	struct msm_cam_server_queue *queue;
+	struct msm_cam_media_controller *pmctl;
+
+	mutex_lock(&g_server_dev.server_queue_lock);
+	queue = &g_server_dev.server_queue[pcam->server_queue_idx];
+	queue->queue_active = 0;
+	kfree(queue->ctrl_data);
+	queue->ctrl_data = NULL;
+	msm_queue_drain(&queue->ctrl_q, list_control);
+	msm_drain_eventq(&queue->eventData_q);
+	mutex_unlock(&g_server_dev.server_queue_lock);
+
+	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
+	if (!pmctl) {
+		pr_err("%s: invalid mctl controller", __func__);
+		return -EINVAL;
+	}
+	unmap_imem_addresses(pmctl);
+
+	rc = msm_cam_server_close_session(&g_server_dev, pcam);
+	if (rc < 0)
+		pr_err("msm_cam_server_close_session fails %d\n", rc);
+
+	ges_evt = MSM_V4L2_GES_CAM_CLOSE;
+	msm_cam_server_subdev_notify(g_server_dev.gesture_device,
+			NOTIFY_GESTURE_CAM_EVT, &ges_evt);
+
+	return rc;
+}
+
+/* Init a config node for ISP control,
+ * which will create a config device (/dev/config0/ and plug in
+ * ISP's operation "v4l2_ioctl_ops*"
+ */
+static const struct v4l2_file_operations msm_fops_server = {
+	.owner = THIS_MODULE,
+	.open  = msm_open_server,
+	.poll  = msm_poll_server,
+	.unlocked_ioctl = video_ioctl2,
+	.release = msm_close_server,
+};
+
+static const struct v4l2_ioctl_ops msm_ioctl_ops_server = {
+	.vidioc_subscribe_event = msm_server_v4l2_subscribe_event,
+	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+	.vidioc_default = msm_ioctl_server,
+};
+
+static uint32_t msm_camera_server_find_mctl(
+		unsigned int notification, void *arg)
+{
+	int i;
+	uint32_t interface;
+	switch (notification) {
+	case NOTIFY_ISP_MSG_EVT:
+		if (((struct isp_msg_event *)arg)->msg_id ==
+			MSG_ID_RDI0_UPDATE_ACK)
+			interface = RDI_0;
+		else if (((struct isp_msg_event *)arg)->msg_id ==
+			MSG_ID_RDI1_UPDATE_ACK)
+			interface = RDI_1;
+		else
+			interface = PIX_0;
+		break;
+	case NOTIFY_VFE_MSG_OUT:
+		if (((struct isp_msg_output *)arg)->output_id ==
+					MSG_ID_OUTPUT_TERTIARY1)
+			interface = RDI_0;
+		else if (((struct isp_msg_output *)arg)->output_id ==
+						MSG_ID_OUTPUT_TERTIARY2)
+			interface = RDI_1;
+		else
+			interface = PIX_0;
+		break;
+	case NOTIFY_VFE_BUF_EVT: {
+		struct msm_vfe_resp *rp;
+		struct msm_frame_info *frame_info;
+		uint8_t vnode_id;
+
+		rp = (struct msm_vfe_resp *)arg;
+		frame_info = rp->evt_msg.data;
+		if (!frame_info) {
+			interface = PIX_0;
+			break;
+		}
+		if (frame_info->inst_handle) {
+			vnode_id = GET_DEVID_MODE(frame_info->inst_handle);
+			if (vnode_id < MAX_NUM_ACTIVE_CAMERA &&
+				g_server_dev.opened_pcam[vnode_id]) {
+				return g_server_dev.
+					opened_pcam[vnode_id]->mctl_handle;
+			} else {
+				pr_err("%s: cannot find mctl handle", __func__);
+				return 0;
+			}
+		} else {
+			if (frame_info->path == VFE_MSG_OUTPUT_TERTIARY1)
+				interface = RDI_0;
+			else if (frame_info->path == VFE_MSG_OUTPUT_TERTIARY2)
+				interface = RDI_1;
+			else
+				interface = PIX_0;
+		}
+		}
+		break;
+	case NOTIFY_AXI_RDI_SOF_COUNT: {
+		struct rdi_count_msg *msg = (struct rdi_count_msg *)arg;
+		interface = msg->rdi_interface;
+		}
+		break;
+	case NOTIFY_VFE_MSG_STATS:
+	case NOTIFY_VFE_MSG_COMP_STATS:
+	case NOTIFY_VFE_CAMIF_ERROR:
+	default:
+		interface = PIX_0;
+		break;
+	}
+	for (i = 0; i < INTF_MAX; i++) {
+		if (interface == g_server_dev.interface_map_table[i].interface)
+			break;
+	}
+	if (i == INTF_MAX) {
+		pr_err("%s: Cannot find valid interface map\n", __func__);
+		return -EINVAL;
+	} else
+		return g_server_dev.interface_map_table[i].mctl_handle;
+}
+
+static void msm_cam_server_subdev_notify(struct v4l2_subdev *sd,
+				unsigned int notification, void *arg)
+{
+	int rc = -EINVAL;
+	uint32_t mctl_handle = 0;
+	struct msm_cam_media_controller *p_mctl = NULL;
+	int is_gesture_evt =
+		(notification == NOTIFY_GESTURE_EVT)
+		|| (notification == NOTIFY_GESTURE_CAM_EVT);
+
+	if (!is_gesture_evt) {
+		mctl_handle = msm_camera_server_find_mctl(notification, arg);
+		if (mctl_handle < 0) {
+			pr_err("%s: Couldn't find mctl instance!\n", __func__);
+			return;
+		}
+	}
+	switch (notification) {
+	case NOTIFY_ISP_MSG_EVT:
+	case NOTIFY_VFE_MSG_OUT:
+	case NOTIFY_VFE_PIX_SOF_COUNT:
+	case NOTIFY_VFE_MSG_STATS:
+	case NOTIFY_VFE_MSG_COMP_STATS:
+	case NOTIFY_VFE_BUF_EVT:
+		p_mctl = msm_cam_server_get_mctl(mctl_handle);
+		if (p_mctl && p_mctl->isp_notify && p_mctl->vfe_sdev)
+			rc = p_mctl->isp_notify(p_mctl,
+				p_mctl->vfe_sdev, notification, arg);
+		break;
+	case NOTIFY_VFE_IRQ:{
+		struct msm_vfe_cfg_cmd cfg_cmd;
+		struct msm_camvfe_params vfe_params;
+		cfg_cmd.cmd_type = CMD_VFE_PROCESS_IRQ;
+		vfe_params.vfe_cfg = &cfg_cmd;
+		vfe_params.data = arg;
+		rc = v4l2_subdev_call(sd,
+			core, ioctl, 0, &vfe_params);
+	}
+		break;
+	case NOTIFY_AXI_IRQ:
+		rc = v4l2_subdev_call(sd, core, ioctl, VIDIOC_MSM_AXI_IRQ, arg);
+		break;
+	case NOTIFY_AXI_RDI_SOF_COUNT:
+		p_mctl = msm_cam_server_get_mctl(mctl_handle);
+		if (p_mctl && p_mctl->axi_sdev)
+			rc = v4l2_subdev_call(p_mctl->axi_sdev, core, ioctl,
+				VIDIOC_MSM_AXI_RDI_COUNT_UPDATE, arg);
+		break;
+	case NOTIFY_PCLK_CHANGE:
+		p_mctl = v4l2_get_subdev_hostdata(sd);
+		if (p_mctl) {
+			if (p_mctl->axi_sdev)
+				rc = v4l2_subdev_call(p_mctl->axi_sdev, video,
+				s_crystal_freq, *(uint32_t *)arg, 0);
+			else
+				rc = v4l2_subdev_call(p_mctl->vfe_sdev, video,
+				s_crystal_freq, *(uint32_t *)arg, 0);
+		}
+		break;
+	case NOTIFY_GESTURE_EVT:
+		rc = v4l2_subdev_call(g_server_dev.gesture_device,
+			core, ioctl, VIDIOC_MSM_GESTURE_EVT, arg);
+		break;
+	case NOTIFY_GESTURE_CAM_EVT:
+		rc = v4l2_subdev_call(g_server_dev.gesture_device,
+			core, ioctl, VIDIOC_MSM_GESTURE_CAM_EVT, arg);
+		break;
+	case NOTIFY_VFE_CAMIF_ERROR: {
+		p_mctl = msm_cam_server_get_mctl(mctl_handle);
+		if (p_mctl)
+			msm_cam_server_send_error_evt(p_mctl,
+				V4L2_EVENT_PRIVATE_START +
+				MSM_CAM_APP_NOTIFY_ERROR_EVENT);
+		break;
+	}
+	default:
+		break;
+	}
+
+	return;
+}
+
+void msm_cam_release_subdev_node(struct video_device *vdev)
+{
+	struct v4l2_subdev *sd = video_get_drvdata(vdev);
+	sd->devnode = NULL;
+	kfree(vdev);
+}
+
+/* Helper function to get the irq_idx corresponding
+ * to the irq_num. */
+int get_irq_idx_from_irq_num(int irq_num)
+{
+	int i;
+	for (i = 0; i < CAMERA_SS_IRQ_MAX; i++)
+		if (irq_num == g_server_dev.hw_irqmap[i].irq_num)
+			return g_server_dev.hw_irqmap[i].irq_idx;
+
+	return -EINVAL;
+}
+
+static struct v4l2_subdev  *msm_cam_find_subdev_node(
+	struct v4l2_subdev **sd_list, u32 revision_num)
+{
+	int i = 0;
+	for (i = 0; sd_list[i] != NULL; i++) {
+		if (sd_list[i]->entity.revision == revision_num) {
+			return sd_list[i];
+			break;
+		}
+	}
+	return NULL;
+}
+
+int msm_mctl_find_sensor_subdevs(struct msm_cam_media_controller *p_mctl,
+	uint8_t csiphy_core_index, uint8_t csid_core_index)
+{
+	int rc = -ENODEV;
+
+	v4l2_set_subdev_hostdata(p_mctl->sensor_sdev, p_mctl);
+
+	rc = msm_csi_register_subdevs(p_mctl, csiphy_core_index,
+		csid_core_index, &g_server_dev);
+	if (rc < 0)
+		pr_err("%s: Could not find sensor subdevs\n", __func__);
+
+	return rc;
+}
+
+int msm_mctl_find_flash_subdev(struct msm_cam_media_controller *p_mctl,
+	uint8_t index)
+{
+	if (index < MAX_NUM_FLASH_DEV)
+		p_mctl->flash_sdev = g_server_dev.flash_device[index];
+	return 0;
+}
+
+static irqreturn_t msm_camera_server_parse_irq(int irq_num, void *data)
+{
+	unsigned long flags;
+	int irq_idx, i, rc;
+	u32 status = 0;
+	struct intr_table_entry *ind_irq_tbl;
+	struct intr_table_entry *comp_irq_tbl;
+	bool subdev_handled = 0;
+
+	irq_idx = get_irq_idx_from_irq_num(irq_num);
+	if (irq_idx < 0) {
+		pr_err("server_parse_irq: no clients for irq #%d. returning ",
+			irq_num);
+		return IRQ_HANDLED;
+	}
+
+	spin_lock_irqsave(&g_server_dev.intr_table_lock, flags);
+	ind_irq_tbl = &g_server_dev.irq_lkup_table.ind_intr_tbl[0];
+	comp_irq_tbl = &g_server_dev.irq_lkup_table.comp_intr_tbl[0];
+	if (ind_irq_tbl[irq_idx].is_composite) {
+		for (i = 0; i < comp_irq_tbl[irq_idx].num_hwcore; i++) {
+			if (comp_irq_tbl[irq_idx].subdev_list[i]) {
+				rc = v4l2_subdev_call(
+					comp_irq_tbl[irq_idx].subdev_list[i],
+					core, interrupt_service_routine,
+					status, &subdev_handled);
+				if ((rc < 0) || !subdev_handled) {
+					pr_err("server_parse_irq:Error\n"
+						"handling irq %d rc = %d",
+						irq_num, rc);
+					/* Dispatch the irq to the remaining
+					 * subdevs in the list. */
+					continue;
+				}
+			}
+		}
+	} else {
+		rc = v4l2_subdev_call(ind_irq_tbl[irq_idx].subdev_list[0],
+			core, interrupt_service_routine,
+			status, &subdev_handled);
+		if ((rc < 0) || !subdev_handled) {
+			pr_err("server_parse_irq: Error handling irq %d rc = %d",
+				irq_num, rc);
+			spin_unlock_irqrestore(&g_server_dev.intr_table_lock,
+				flags);
+			return IRQ_HANDLED;
+		}
+	}
+	spin_unlock_irqrestore(&g_server_dev.intr_table_lock, flags);
+	return IRQ_HANDLED;
+}
+
+/* Helper function to get the irq_idx corresponding
+ * to the camera hwcore. This function should _only_
+ * be invoked when the IRQ Router is configured
+ * non-composite mode. */
+int get_irq_idx_from_camhw_idx(int cam_hw_idx)
+{
+	int i;
+	for (i = 0; i < MSM_CAM_HW_MAX; i++)
+		if (cam_hw_idx == g_server_dev.hw_irqmap[i].cam_hw_idx)
+			return g_server_dev.hw_irqmap[i].irq_idx;
+
+	return -EINVAL;
+}
+
+static inline void update_compirq_subdev_info(
+	struct intr_table_entry *irq_entry,
+	uint32_t cam_hw_mask, uint8_t cam_hw_id,
+	int *num_hwcore)
+{
+	if (cam_hw_mask & (0x1 << cam_hw_id)) {
+		/* If the mask has been set for this cam hwcore
+		 * update the subdev ptr......*/
+		irq_entry->subdev_list[cam_hw_id] =
+			g_server_dev.subdev_table[cam_hw_id];
+		(*num_hwcore)++;
+	} else {
+		/*....else, just clear it, so that the irq will
+		 * not be dispatched to this hw. */
+		irq_entry->subdev_list[cam_hw_id] = NULL;
+	}
+}
+
+static int msm_server_update_composite_irq_info(
+	struct intr_table_entry *irq_req)
+{
+	int num_hwcore = 0, rc = 0;
+	struct intr_table_entry *comp_irq_tbl =
+		&g_server_dev.irq_lkup_table.comp_intr_tbl[0];
+
+	comp_irq_tbl[irq_req->irq_idx].is_composite = 1;
+	comp_irq_tbl[irq_req->irq_idx].irq_trigger_type =
+		irq_req->irq_trigger_type;
+	comp_irq_tbl[irq_req->irq_idx].num_hwcore = irq_req->num_hwcore;
+
+	update_compirq_subdev_info(&comp_irq_tbl[irq_req->irq_idx],
+		irq_req->cam_hw_mask, MSM_CAM_HW_MICRO, &num_hwcore);
+
+	update_compirq_subdev_info(&comp_irq_tbl[irq_req->irq_idx],
+		irq_req->cam_hw_mask, MSM_CAM_HW_CCI, &num_hwcore);
+
+	update_compirq_subdev_info(&comp_irq_tbl[irq_req->irq_idx],
+		irq_req->cam_hw_mask, MSM_CAM_HW_CSI0, &num_hwcore);
+
+	update_compirq_subdev_info(&comp_irq_tbl[irq_req->irq_idx],
+		irq_req->cam_hw_mask, MSM_CAM_HW_CSI1, &num_hwcore);
+
+	update_compirq_subdev_info(&comp_irq_tbl[irq_req->irq_idx],
+		irq_req->cam_hw_mask, MSM_CAM_HW_CSI2, &num_hwcore);
+
+	update_compirq_subdev_info(&comp_irq_tbl[irq_req->irq_idx],
+		irq_req->cam_hw_mask, MSM_CAM_HW_CSI3, &num_hwcore);
+
+	update_compirq_subdev_info(&comp_irq_tbl[irq_req->irq_idx],
+		irq_req->cam_hw_mask, MSM_CAM_HW_ISPIF, &num_hwcore);
+
+	update_compirq_subdev_info(&comp_irq_tbl[irq_req->irq_idx],
+		irq_req->cam_hw_mask, MSM_CAM_HW_CPP, &num_hwcore);
+
+	update_compirq_subdev_info(&comp_irq_tbl[irq_req->irq_idx],
+		irq_req->cam_hw_mask, MSM_CAM_HW_VFE0, &num_hwcore);
+
+	update_compirq_subdev_info(&comp_irq_tbl[irq_req->irq_idx],
+		irq_req->cam_hw_mask, MSM_CAM_HW_VFE1, &num_hwcore);
+
+	update_compirq_subdev_info(&comp_irq_tbl[irq_req->irq_idx],
+		irq_req->cam_hw_mask, MSM_CAM_HW_JPEG0, &num_hwcore);
+
+	update_compirq_subdev_info(&comp_irq_tbl[irq_req->irq_idx],
+		irq_req->cam_hw_mask, MSM_CAM_HW_JPEG1, &num_hwcore);
+
+	update_compirq_subdev_info(&comp_irq_tbl[irq_req->irq_idx],
+		irq_req->cam_hw_mask, MSM_CAM_HW_JPEG2, &num_hwcore);
+
+	if (num_hwcore != irq_req->num_hwcore) {
+		pr_warn("%s Mismatch!! requested cam hwcores: %d, Mask set %d",
+			__func__, irq_req->num_hwcore, num_hwcore);
+		rc = -EINVAL;
+	}
+	return rc;
+}
+
+int msm_cam_server_request_irq(void *arg)
+{
+	unsigned long flags;
+	int rc = 0;
+	struct intr_table_entry *irq_req =  (struct intr_table_entry *)arg;
+	struct intr_table_entry *ind_irq_tbl =
+		&g_server_dev.irq_lkup_table.ind_intr_tbl[0];
+	struct intr_table_entry *comp_irq_tbl =
+		&g_server_dev.irq_lkup_table.comp_intr_tbl[0];
+
+	if (!irq_req || !irq_req->irq_num || !irq_req->num_hwcore) {
+		pr_err("%s Invalid input ", __func__);
+		return -EINVAL;
+	}
+
+	if (!g_server_dev.irqr_device) {
+		/* This either means, the current target does not
+		 * have a IRQ Router hw or the IRQ Router device is
+		 * not probed yet. The latter should not happen.
+		 * In any case, just return back without updating
+		 * the interrupt lookup table. */
+		pr_info("%s IRQ Router hw is not present. ", __func__);
+		return -ENXIO;
+	}
+
+	if (irq_req->is_composite) {
+		if (irq_req->irq_idx >= CAMERA_SS_IRQ_0 &&
+				irq_req->irq_idx < CAMERA_SS_IRQ_MAX) {
+			spin_lock_irqsave(&g_server_dev.intr_table_lock, flags);
+			/* Update the composite irq information into
+			 * the composite irq lookup table.... */
+			if (msm_server_update_composite_irq_info(irq_req)) {
+				pr_err("%s Invalid configuration", __func__);
+				spin_unlock_irqrestore(
+					&g_server_dev.intr_table_lock, flags);
+				return -EINVAL;
+			}
+			spin_unlock_irqrestore(&g_server_dev.intr_table_lock,
+				flags);
+			/*...and then update the corresponding entry
+			 * in the individual irq lookup table to indicate
+			 * that this IRQ is a composite irq and needs to be
+			 * sent to multiple subdevs. */
+			ind_irq_tbl[irq_req->irq_idx].is_composite = 1;
+			rc = request_irq(comp_irq_tbl[irq_req->irq_idx].irq_num,
+				msm_camera_server_parse_irq,
+				irq_req->irq_trigger_type,
+				ind_irq_tbl[irq_req->irq_idx].dev_name,
+				ind_irq_tbl[irq_req->irq_idx].data);
+			if (rc < 0) {
+				pr_err("%s: request_irq failed for %s\n",
+					__func__, irq_req->dev_name);
+				return -EBUSY;
+			}
+		} else {
+			pr_err("%s Invalid irq_idx %d ",
+				__func__, irq_req->irq_idx);
+			return -EINVAL;
+		}
+	} else {
+		if (irq_req->cam_hw_idx >= MSM_CAM_HW_MICRO &&
+				irq_req->cam_hw_idx < MSM_CAM_HW_MAX) {
+			/* Update the irq information into
+			 * the individual irq lookup table.... */
+			irq_req->irq_idx =
+				get_irq_idx_from_camhw_idx(irq_req->cam_hw_idx);
+			if (irq_req->irq_idx < 0) {
+				pr_err("%s Invalid hw index %d ", __func__,
+					irq_req->cam_hw_idx);
+				return -EINVAL;
+			}
+			spin_lock_irqsave(&g_server_dev.intr_table_lock, flags);
+			/* Make sure the composite irq is not configured for
+			 * this IRQ already. */
+			BUG_ON(ind_irq_tbl[irq_req->irq_idx].is_composite);
+
+			ind_irq_tbl[irq_req->irq_idx] = *irq_req;
+			/* irq_num is stored inside the server's hw_irqmap
+			 * during the device subdevice registration. */
+			ind_irq_tbl[irq_req->irq_idx].irq_num =
+			g_server_dev.hw_irqmap[irq_req->irq_idx].irq_num;
+
+			/*...and clear the corresponding entry in the
+			 * compsoite irq lookup table to indicate that this
+			 * IRQ will only be dispatched to single subdev. */
+			memset(&comp_irq_tbl[irq_req->irq_idx], 0,
+					sizeof(struct intr_table_entry));
+			D("%s Saving Entry %d %d %d %p",
+			__func__,
+			ind_irq_tbl[irq_req->irq_idx].irq_num,
+			ind_irq_tbl[irq_req->irq_idx].cam_hw_idx,
+			ind_irq_tbl[irq_req->irq_idx].is_composite,
+			ind_irq_tbl[irq_req->irq_idx].subdev_list[0]);
+
+			spin_unlock_irqrestore(&g_server_dev.intr_table_lock,
+				flags);
+
+			rc = request_irq(ind_irq_tbl[irq_req->irq_idx].irq_num,
+				msm_camera_server_parse_irq,
+				irq_req->irq_trigger_type,
+				ind_irq_tbl[irq_req->irq_idx].dev_name,
+				ind_irq_tbl[irq_req->irq_idx].data);
+			if (rc < 0) {
+				pr_err("%s: request_irq failed for %s\n",
+					__func__, irq_req->dev_name);
+				return -EBUSY;
+			}
+		} else {
+			pr_err("%s Invalid hw index %d ", __func__,
+				irq_req->cam_hw_idx);
+			return -EINVAL;
+		}
+	}
+	D("%s Successfully requested for IRQ for device %s ", __func__,
+		irq_req->dev_name);
+	return rc;
+}
+
+int msm_cam_server_update_irqmap(
+	struct msm_cam_server_irqmap_entry *irqmap_entry)
+{
+	if (!irqmap_entry || (irqmap_entry->irq_idx < CAMERA_SS_IRQ_0 ||
+		irqmap_entry->irq_idx >= CAMERA_SS_IRQ_MAX)) {
+		pr_err("%s Invalid irqmap entry ", __func__);
+		return -EINVAL;
+	}
+	g_server_dev.hw_irqmap[irqmap_entry->irq_idx] = *irqmap_entry;
+	return 0;
+}
+
+static int msm_cam_server_register_subdev(struct v4l2_device *v4l2_dev,
+	struct v4l2_subdev *sd)
+{
+	int rc = 0;
+	struct video_device *vdev;
+
+	if (v4l2_dev == NULL || sd == NULL || !sd->name[0]) {
+		pr_err("%s Invalid input ", __func__);
+		return -EINVAL;
+	}
+
+	rc = v4l2_device_register_subdev(v4l2_dev, sd);
+	if (rc < 0) {
+		pr_err("%s v4l2 subdev register failed for %s ret = %d",
+			__func__, sd->name, rc);
+		return rc;
+	}
+
+	/* Register a device node for every subdev marked with the
+	 * V4L2_SUBDEV_FL_HAS_DEVNODE flag.
+	 */
+	if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE))
+		return rc;
+
+	vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
+	if (!vdev) {
+		pr_err("%s Not enough memory ", __func__);
+		rc = -ENOMEM;
+		goto clean_up;
+	}
+
+	video_set_drvdata(vdev, sd);
+	strlcpy(vdev->name, sd->name, sizeof(vdev->name));
+	vdev->v4l2_dev = v4l2_dev;
+	vdev->fops = &v4l2_subdev_fops;
+	vdev->release = msm_cam_release_subdev_node;
+	rc = __video_register_device(vdev, VFL_TYPE_SUBDEV, -1, 1,
+						  sd->owner);
+	if (rc < 0) {
+		pr_err("%s Error registering video device %s", __func__,
+			sd->name);
+		kfree(vdev);
+		goto clean_up;
+	}
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	sd->entity.info.v4l.major = VIDEO_MAJOR;
+	sd->entity.info.v4l.minor = vdev->minor;
+#endif
+	sd->devnode = vdev;
+	return 0;
+
+clean_up:
+	if (sd->devnode)
+		video_unregister_device(sd->devnode);
+	return rc;
+}
+
+static int msm_cam_server_fill_sdev_irqnum(int cam_hw_idx,
+	int irq_num)
+{
+	int rc = 0, irq_idx;
+	irq_idx = get_irq_idx_from_camhw_idx(cam_hw_idx);
+	if (irq_idx < 0) {
+		pr_err("%s Invalid cam_hw_idx %d ", __func__, cam_hw_idx);
+		rc = -EINVAL;
+	} else {
+		g_server_dev.hw_irqmap[irq_idx].irq_num = irq_num;
+	}
+	return rc;
+}
+
+int msm_cam_register_subdev_node(struct v4l2_subdev *sd,
+	struct msm_cam_subdev_info *sd_info)
+{
+	int err = 0, cam_hw_idx;
+	uint8_t sdev_type, index;
+
+	sdev_type = sd_info->sdev_type;
+	index     = sd_info->sd_index;
+
+	switch (sdev_type) {
+	case SENSOR_DEV:
+		if (index >= MAX_NUM_SENSOR_DEV) {
+			pr_err("%s Invalid sensor idx %d", __func__, index);
+			err = -EINVAL;
+			break;
+		}
+		g_server_dev.sensor_device[index] = sd;
+		break;
+
+	case CSIPHY_DEV:
+		if (index >= MAX_NUM_CSIPHY_DEV) {
+			pr_err("%s Invalid CSIPHY idx %d", __func__, index);
+			err = -EINVAL;
+			break;
+		}
+		g_server_dev.csiphy_device[index] = sd;
+		break;
+
+	case CSID_DEV:
+		if (index >= MAX_NUM_CSID_DEV) {
+			pr_err("%s Invalid CSID idx %d", __func__, index);
+			err = -EINVAL;
+			break;
+		}
+		cam_hw_idx = MSM_CAM_HW_CSI0 + index;
+		g_server_dev.csid_device[index] = sd;
+		if (g_server_dev.irqr_device) {
+			g_server_dev.subdev_table[cam_hw_idx] = sd;
+			err = msm_cam_server_fill_sdev_irqnum(cam_hw_idx,
+				sd_info->irq_num);
+		}
+		break;
+
+	case CSIC_DEV:
+		if (index >= MAX_NUM_CSIC_DEV) {
+			pr_err("%s Invalid CSIC idx %d", __func__, index);
+			err = -EINVAL;
+			break;
+		}
+		g_server_dev.csic_device[index] = sd;
+		break;
+
+	case ISPIF_DEV:
+		if (index >= MAX_NUM_ISPIF_DEV) {
+			pr_err("%s Invalid ISPIF idx %d", __func__, index);
+			err = -EINVAL;
+			break;
+		}
+		cam_hw_idx = MSM_CAM_HW_ISPIF + index;
+		g_server_dev.ispif_device[index] = sd;
+		if (g_server_dev.irqr_device) {
+			g_server_dev.subdev_table[cam_hw_idx] = sd;
+			err = msm_cam_server_fill_sdev_irqnum(cam_hw_idx,
+				sd_info->irq_num);
+		}
+		break;
+
+	case VFE_DEV:
+		if (index >= MAX_NUM_VFE_DEV) {
+			pr_err("%s Invalid VFE idx %d", __func__, index);
+			err = -EINVAL;
+			break;
+		}
+		cam_hw_idx = MSM_CAM_HW_VFE0 + index;
+		g_server_dev.vfe_device[index] = sd;
+		if (g_server_dev.irqr_device) {
+			g_server_dev.subdev_table[cam_hw_idx] = sd;
+			err = msm_cam_server_fill_sdev_irqnum(cam_hw_idx,
+				sd_info->irq_num);
+		}
+		break;
+
+	case VPE_DEV:
+		if (index >= MAX_NUM_VPE_DEV) {
+			pr_err("%s Invalid VPE idx %d", __func__, index);
+			err = -EINVAL;
+			break;
+		}
+		g_server_dev.vpe_device[index] = sd;
+		break;
+
+	case AXI_DEV:
+		if (index >= MAX_NUM_AXI_DEV) {
+			pr_err("%s Invalid AXI idx %d", __func__, index);
+			err = -EINVAL;
+			break;
+		}
+		g_server_dev.axi_device[index] = sd;
+		break;
+
+	case GESTURE_DEV:
+		g_server_dev.gesture_device = sd;
+		break;
+
+	case IRQ_ROUTER_DEV:
+		g_server_dev.irqr_device = sd;
+
+	case CPP_DEV:
+		if (index >= MAX_NUM_CPP_DEV) {
+			pr_err("%s Invalid CPP idx %d", __func__, index);
+			err = -EINVAL;
+			break;
+		}
+		g_server_dev.cpp_device[index] = sd;
+		break;
+	case CCI_DEV:
+		g_server_dev.cci_device = sd;
+		if (g_server_dev.irqr_device) {
+			if (index >= MAX_NUM_CCI_DEV) {
+				pr_err("%s Invalid CCI idx %d", __func__,
+					index);
+				err = -EINVAL;
+				break;
+			}
+			cam_hw_idx = MSM_CAM_HW_CCI + index;
+			g_server_dev.subdev_table[cam_hw_idx] = sd;
+			err = msm_cam_server_fill_sdev_irqnum(MSM_CAM_HW_CCI,
+				sd_info->irq_num);
+		}
+		break;
+
+	case FLASH_DEV:
+		if (index >= MAX_NUM_FLASH_DEV) {
+			pr_err("%s Invalid flash idx %d", __func__, index);
+			err = -EINVAL;
+			break;
+		}
+		g_server_dev.flash_device[index] = sd;
+		break;
+
+	default:
+		break;
+	}
+
+	if (err < 0)
+		return err;
+
+	err = msm_cam_server_register_subdev(&g_server_dev.v4l2_dev, sd);
+	return err;
+}
+
+#ifdef CONFIG_MSM_IOMMU
+static int camera_register_domain(void)
+{
+	struct msm_iova_partition camera_fw_partition = {
+		.start = SZ_128K,
+		.size = SZ_2G - SZ_128K,
+	};
+	struct msm_iova_layout camera_fw_layout = {
+		.partitions = &camera_fw_partition,
+		.npartitions = 1,
+		.client_name = "camera_isp",
+		.domain_flags = 0,
+	};
+
+	return msm_register_domain(&camera_fw_layout);
+}
+#endif
+
+static int msm_setup_server_dev(struct platform_device *pdev)
+{
+	int rc = -ENODEV, i;
+
+	D("%s\n", __func__);
+	g_server_dev.server_pdev = pdev;
+	g_server_dev.v4l2_dev.dev = &pdev->dev;
+	g_server_dev.v4l2_dev.notify = msm_cam_server_subdev_notify;
+	rc = v4l2_device_register(g_server_dev.v4l2_dev.dev,
+			&g_server_dev.v4l2_dev);
+	if (rc < 0)
+		return -EINVAL;
+
+	g_server_dev.video_dev = video_device_alloc();
+	if (g_server_dev.video_dev == NULL) {
+		pr_err("%s: video_device_alloc failed\n", __func__);
+		return rc;
+	}
+
+	strlcpy(g_server_dev.video_dev->name, pdev->name,
+			sizeof(g_server_dev.video_dev->name));
+
+	g_server_dev.video_dev->v4l2_dev = &g_server_dev.v4l2_dev;
+	g_server_dev.video_dev->fops = &msm_fops_server;
+	g_server_dev.video_dev->ioctl_ops = &msm_ioctl_ops_server;
+	g_server_dev.video_dev->release   = video_device_release;
+	g_server_dev.video_dev->minor = 100;
+	g_server_dev.video_dev->vfl_type = VFL_TYPE_GRABBER;
+
+	video_set_drvdata(g_server_dev.video_dev, &g_server_dev);
+
+	strlcpy(g_server_dev.media_dev.model, QCAMERA_SERVER_NAME,
+		sizeof(g_server_dev.media_dev.model));
+	g_server_dev.media_dev.dev = &pdev->dev;
+	rc = media_device_register(&g_server_dev.media_dev);
+	g_server_dev.v4l2_dev.mdev = &g_server_dev.media_dev;
+	media_entity_init(&g_server_dev.video_dev->entity, 0, NULL, 0);
+	g_server_dev.video_dev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
+	g_server_dev.video_dev->entity.group_id = QCAMERA_VNODE_GROUP_ID;
+
+	rc = video_register_device(g_server_dev.video_dev,
+		VFL_TYPE_GRABBER, 100);
+
+	g_server_dev.video_dev->entity.name =
+		video_device_node_name(g_server_dev.video_dev);
+
+	mutex_init(&g_server_dev.server_lock);
+	mutex_init(&g_server_dev.server_queue_lock);
+	spin_lock_init(&g_server_dev.intr_table_lock);
+	memset(&g_server_dev.irq_lkup_table, 0,
+			sizeof(struct irqmgr_intr_lkup_table));
+	g_server_dev.camera_info.num_cameras = 0;
+	atomic_set(&g_server_dev.number_pcam_active, 0);
+	g_server_dev.server_evt_id = 0;
+
+	/*initialize fake video device and event queue*/
+
+	g_server_dev.server_command_queue.pvdev = g_server_dev.video_dev;
+	msm_setup_v4l2_event_queue(
+		&g_server_dev.server_command_queue.eventHandle,
+		g_server_dev.server_command_queue.pvdev);
+
+	for (i = 0; i < MAX_NUM_ACTIVE_CAMERA; i++) {
+		struct msm_cam_server_queue *queue;
+		queue = &g_server_dev.server_queue[i];
+		queue->queue_active = 0;
+		msm_queue_init(&queue->ctrl_q, "control");
+		msm_queue_init(&queue->eventData_q, "eventdata");
+		g_server_dev.pcam_active[i] = NULL;
+	}
+
+	for (i = 0; i < INTF_MAX; i++) {
+		g_server_dev.interface_map_table[i].interface = 0x01 << i;
+		g_server_dev.interface_map_table[i].mctl_handle = 0;
+	}
+#ifdef CONFIG_MSM_IOMMU
+	g_server_dev.domain_num = camera_register_domain();
+	if (g_server_dev.domain_num < 0) {
+		pr_err("%s: could not register domain\n", __func__);
+		rc = -ENODEV;
+		return rc;
+	}
+	g_server_dev.domain =
+		msm_get_iommu_domain(g_server_dev.domain_num);
+	if (!g_server_dev.domain) {
+		pr_err("%s: cannot find domain\n", __func__);
+		rc = -ENODEV;
+		return rc;
+	}
+#endif
+	return rc;
+}
+
+static long msm_server_send_v4l2_evt(void *evt)
+{
+	struct v4l2_event *v4l2_ev = (struct v4l2_event *)evt;
+	int rc = 0;
+
+	if (NULL == evt) {
+		pr_err("%s: evt is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	D("%s: evt type 0x%x\n", __func__, v4l2_ev->type);
+	if ((v4l2_ev->type >= MSM_GES_APP_EVT_MIN) &&
+		(v4l2_ev->type < MSM_GES_APP_EVT_MAX)) {
+		msm_cam_server_subdev_notify(g_server_dev.gesture_device,
+			NOTIFY_GESTURE_EVT, v4l2_ev);
+	} else {
+		pr_err("%s: Invalid evt %d\n", __func__, v4l2_ev->type);
+		rc = -EINVAL;
+	}
+	D("%s: end\n", __func__);
+
+	return rc;
+}
+
+int msm_cam_server_open_mctl_session(struct msm_cam_v4l2_device *pcam,
+	int *p_active)
+{
+	int rc = 0;
+	int i = 0;
+	struct msm_cam_media_controller *pmctl = NULL;
+	*p_active = 0;
+
+	for (i = 0; i < MAX_NUM_ACTIVE_CAMERA; i++) {
+		if (NULL != g_server_dev.pcam_active[i]) {
+			pr_info("%s: Active camera present return", __func__);
+			return 0;
+		}
+	}
+
+	rc = msm_cam_server_open_session(&g_server_dev, pcam);
+	if (rc < 0) {
+		pr_err("%s: cam_server_open_session failed %d\n",
+		__func__, rc);
+		return rc;
+	}
+
+	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
+	if (!pmctl || !pmctl->mctl_open) {
+		D("%s: media contoller is not inited\n",
+			 __func__);
+		rc = -ENODEV;
+		return rc;
+	}
+
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+		pmctl->domain = msm_cam_server_get_domain();
+		pmctl->domain_num = msm_cam_server_get_domain_num();
+#endif
+
+	D("%s: call mctl_open\n", __func__);
+	rc = pmctl->mctl_open(pmctl, MSM_APPS_ID_V4L2);
+
+	if (rc < 0) {
+		pr_err("%s: HW open failed rc = 0x%x\n",  __func__, rc);
+		return rc;
+	}
+	pmctl->pcam_ptr = pcam;
+	*p_active = 1;
+	return rc;
+}
+
+int msm_cam_server_close_mctl_session(struct msm_cam_v4l2_device *pcam)
+{
+	int rc = 0;
+	struct msm_cam_media_controller *pmctl = NULL;
+
+	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
+	if (!pmctl) {
+		D("%s: invalid handle\n", __func__);
+		return -ENODEV;
+	}
+
+	if (pmctl->mctl_release)
+		pmctl->mctl_release(pmctl);
+
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	kref_put(&pmctl->refcount, msm_release_ion_client);
+#endif
+
+	rc = msm_cam_server_close_session(&g_server_dev, pcam);
+	if (rc < 0)
+		pr_err("msm_cam_server_close_session fails %d\n", rc);
+
+	return rc;
+}
+
+int msm_server_open_client(int *p_qidx)
+{
+	int rc = 0;
+	int server_q_idx = 0;
+	struct msm_cam_server_queue *queue = NULL;
+
+	mutex_lock(&g_server_dev.server_lock);
+	server_q_idx = msm_find_free_queue();
+	if (server_q_idx < 0) {
+		mutex_unlock(&g_server_dev.server_lock);
+		return server_q_idx;
+	}
+
+	*p_qidx = server_q_idx;
+	queue = &g_server_dev.server_queue[server_q_idx];
+	queue->ctrl_data = kzalloc(sizeof(uint8_t) *
+		MAX_SERVER_PAYLOAD_LENGTH, GFP_KERNEL);
+	if (!queue->ctrl_data) {
+		pr_err("%s: Could not find memory\n", __func__);
+		return -ENOMEM;
+	}
+	msm_queue_init(&queue->ctrl_q, "control");
+	msm_queue_init(&queue->eventData_q, "eventdata");
+	queue->queue_active = 1;
+	mutex_unlock(&g_server_dev.server_lock);
+	return rc;
+}
+
+int msm_server_send_ctrl(struct msm_ctrl_cmd *out,
+	int ctrl_id)
+{
+	int rc = 0;
+	void *value;
+	struct msm_queue_cmd *rcmd;
+	struct msm_queue_cmd *event_qcmd;
+	struct msm_ctrl_cmd *ctrlcmd;
+	struct msm_cam_server_dev *server_dev = &g_server_dev;
+	struct msm_device_queue *queue =
+		&server_dev->server_queue[out->queue_idx].ctrl_q;
+
+	struct v4l2_event v4l2_evt;
+	struct msm_isp_event_ctrl *isp_event;
+	void *ctrlcmd_data;
+
+	event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
+	if (!event_qcmd) {
+		pr_err("%s Insufficient memory. return", __func__);
+		rc = -ENOMEM;
+		goto event_qcmd_alloc_fail;
+	}
+
+	isp_event = kzalloc(sizeof(struct msm_isp_event_ctrl), GFP_KERNEL);
+	if (!isp_event) {
+		pr_err("%s Insufficient memory. return", __func__);
+		rc = -ENOMEM;
+		goto isp_event_alloc_fail;
+	}
+
+	D("%s\n", __func__);
+	mutex_lock(&server_dev->server_queue_lock);
+	if (++server_dev->server_evt_id == 0)
+		server_dev->server_evt_id++;
+
+	D("%s qid %d evtid %d\n", __func__, out->queue_idx,
+		server_dev->server_evt_id);
+	server_dev->server_queue[out->queue_idx].evt_id =
+		server_dev->server_evt_id;
+	v4l2_evt.type = V4L2_EVENT_PRIVATE_START + ctrl_id;
+	v4l2_evt.id = 0;
+	v4l2_evt.u.data[0] = out->queue_idx;
+	/* setup event object to transfer the command; */
+	isp_event->resptype = MSM_CAM_RESP_V4L2;
+	isp_event->isp_data.ctrl = *out;
+	isp_event->isp_data.ctrl.evt_id = server_dev->server_evt_id;
+
+	if (out->value != NULL && out->length != 0) {
+		ctrlcmd_data = kzalloc(out->length, GFP_KERNEL);
+		if (!ctrlcmd_data) {
+			rc = -ENOMEM;
+			goto ctrlcmd_alloc_fail;
+		}
+		memcpy(ctrlcmd_data, out->value, out->length);
+		isp_event->isp_data.ctrl.value = ctrlcmd_data;
+	}
+
+	atomic_set(&event_qcmd->on_heap, 1);
+	event_qcmd->command = isp_event;
+
+	msm_enqueue(&server_dev->server_queue[out->queue_idx].eventData_q,
+				&event_qcmd->list_eventdata);
+
+	/* now send command to config thread in userspace,
+	 * and wait for results */
+	v4l2_event_queue(server_dev->server_command_queue.pvdev,
+					  &v4l2_evt);
+	D("%s v4l2_event_queue: type = 0x%x\n", __func__, v4l2_evt.type);
+	mutex_unlock(&server_dev->server_queue_lock);
+
+	/* wait for config return status */
+	D("Waiting for config status\n");
+	rc = wait_event_interruptible_timeout(queue->wait,
+		!list_empty_careful(&queue->list),
+		msecs_to_jiffies(out->timeout_ms));
+	D("Waiting is over for config status\n");
+	if (list_empty_careful(&queue->list)) {
+		if (!rc)
+			rc = -ETIMEDOUT;
+		if (rc < 0) {
+			if (++server_dev->server_evt_id == 0)
+				server_dev->server_evt_id++;
+			pr_err("%s: wait_event error %d\n", __func__, rc);
+			return rc;
+		}
+	}
+
+	rcmd = msm_dequeue(queue, list_control);
+	BUG_ON(!rcmd);
+	D("%s Finished servicing ioctl\n", __func__);
+
+	ctrlcmd = (struct msm_ctrl_cmd *)(rcmd->command);
+	value = out->value;
+	if (ctrlcmd->length > 0 && value != NULL &&
+		ctrlcmd->length <= out->length)
+		memcpy(value, ctrlcmd->value, ctrlcmd->length);
+
+	memcpy(out, ctrlcmd, sizeof(struct msm_ctrl_cmd));
+	out->value = value;
+
+	kfree(ctrlcmd);
+	free_qcmd(rcmd);
+	D("%s: rc %d\n", __func__, rc);
+	/* rc is the time elapsed. */
+	if (rc >= 0) {
+		/* TODO: Refactor msm_ctrl_cmd::status field */
+		if (out->status == 0)
+			rc = -1;
+		else if (out->status == 1 || out->status == 4)
+			rc = 0;
+		else
+			rc = -EINVAL;
+	}
+	return rc;
+
+ctrlcmd_alloc_fail:
+	kfree(isp_event);
+isp_event_alloc_fail:
+	kfree(event_qcmd);
+event_qcmd_alloc_fail:
+	return rc;
+}
+
+int msm_server_close_client(int idx)
+{
+	int rc = 0;
+	struct msm_cam_server_queue *queue = NULL;
+	mutex_lock(&g_server_dev.server_lock);
+	queue = &g_server_dev.server_queue[idx];
+	queue->queue_active = 0;
+	kfree(queue->ctrl_data);
+	queue->ctrl_data = NULL;
+	msm_queue_drain(&queue->ctrl_q, list_control);
+	msm_drain_eventq(&queue->eventData_q);
+	mutex_unlock(&g_server_dev.server_lock);
+	return rc;
+}
+
+static unsigned int msm_poll_config(struct file *fp,
+					struct poll_table_struct *wait)
+{
+	int rc = 0;
+	struct msm_cam_config_dev *config = fp->private_data;
+	if (config == NULL)
+		return -EINVAL;
+
+	D("%s\n", __func__);
+
+	poll_wait(fp,
+	&config->config_stat_event_queue.eventHandle.wait, wait);

+	if (v4l2_event_pending(&config->config_stat_event_queue.eventHandle))
+		rc |= POLLPRI;
+	return rc;
+}
+
+static int msm_mmap_config(struct file *fp, struct vm_area_struct *vma)
+{
+	struct msm_cam_config_dev *config_cam = fp->private_data;
+	int rc = 0;
+	int phyaddr;
+	int retval;
+	unsigned long size;
+
+	D("%s: phy_addr=0x%x", __func__, config_cam->mem_map.cookie);
+	phyaddr = (int)config_cam->mem_map.cookie;
+	if (!phyaddr) {
+		pr_err("%s: no physical memory to map", __func__);
+		return -EFAULT;
+	}
+	memset(&config_cam->mem_map, 0,
+		sizeof(struct msm_mem_map_info));
+	size = vma->vm_end - vma->vm_start;
+	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+	retval = remap_pfn_range(vma, vma->vm_start,
+					phyaddr >> PAGE_SHIFT,
+					size, vma->vm_page_prot);
+	if (retval) {
+		pr_err("%s: remap failed, rc = %d",
+					__func__, retval);
+		rc = -ENOMEM;
+		goto end;
+	}
+	D("%s: phy_addr=0x%x: %08lx-%08lx, pgoff %08lx\n",
+			__func__, (uint32_t)phyaddr,
+			vma->vm_start, vma->vm_end, vma->vm_pgoff);
+end:
+	return rc;
+}
+
+static int msm_open_config(struct inode *inode, struct file *fp)
+{
+	int rc;
+	struct msm_cam_config_dev *config_cam = container_of(inode->i_cdev,
+		struct msm_cam_config_dev, config_cdev);
+
+	D("%s: open %s\n", __func__, fp->f_path.dentry->d_name.name);
+
+	rc = nonseekable_open(inode, fp);
+	if (rc < 0) {
+		pr_err("%s: nonseekable_open error %d\n", __func__, rc);
+		return rc;
+	}
+	config_cam->use_count++;
+
+	/* assume there is only one active camera possible*/
+	config_cam->p_mctl = msm_cam_server_get_mctl(
+		g_server_dev.pcam_active[config_cam->dev_num]->mctl_handle);
+	if (!config_cam->p_mctl) {
+		pr_err("%s: cannot find mctl\n", __func__);
+		return -ENODEV;
+	}
+
+	INIT_HLIST_HEAD(&config_cam->p_mctl->stats_info.pmem_stats_list);
+	spin_lock_init(&config_cam->p_mctl->stats_info.pmem_stats_spinlock);
+
+	config_cam->p_mctl->config_device = config_cam;
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	kref_get(&config_cam->p_mctl->refcount);
+#endif
+	fp->private_data = config_cam;
+	return rc;
+}
+
+static int msm_set_mctl_subdev(struct msm_cam_media_controller *pmctl,
+	struct msm_mctl_set_sdev_data *set_data)
+{
+	int rc = 0;
+	struct v4l2_subdev *temp_sdev = NULL;
+	switch (set_data->sdev_type) {
+	case CSIPHY_DEV:
+		pmctl->csiphy_sdev = msm_cam_find_subdev_node
+			(&g_server_dev.csiphy_device[0], set_data->revision);
+		temp_sdev = pmctl->csiphy_sdev;
+		break;
+	case CSID_DEV:
+		pmctl->csid_sdev = msm_cam_find_subdev_node
+			(&g_server_dev.csid_device[0], set_data->revision);
+		temp_sdev = pmctl->csid_sdev;
+		break;
+	case CSIC_DEV:
+		pmctl->csic_sdev = msm_cam_find_subdev_node
+			(&g_server_dev.csic_device[0], set_data->revision);
+		temp_sdev = pmctl->csic_sdev;
+		break;
+	case ISPIF_DEV:
+		pmctl->ispif_sdev = msm_cam_find_subdev_node
+			(&g_server_dev.ispif_device[0], set_data->revision);
+		temp_sdev = pmctl->ispif_sdev;
+		break;
+	case VFE_DEV:
+		pmctl->vfe_sdev = msm_cam_find_subdev_node
+			(&g_server_dev.vfe_device[0], set_data->revision);
+		temp_sdev = pmctl->vfe_sdev;
+		break;
+	case AXI_DEV:
+		pmctl->axi_sdev = msm_cam_find_subdev_node
+			(&g_server_dev.axi_device[0], set_data->revision);
+		temp_sdev = pmctl->axi_sdev;
+		break;
+	case VPE_DEV:
+		pmctl->vpe_sdev = msm_cam_find_subdev_node
+			(&g_server_dev.vpe_device[0], set_data->revision);
+		temp_sdev = pmctl->vpe_sdev;
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+	if (temp_sdev != NULL)
+		v4l2_set_subdev_hostdata(temp_sdev, pmctl);
+	else
+		pr_err("%s: Could not find subdev\n", __func__);
+	return rc;
+}
+
+static int msm_unset_mctl_subdev(struct msm_cam_media_controller *pmctl,
+	struct msm_mctl_set_sdev_data *set_data)
+{
+	int rc = 0;
+	switch (set_data->sdev_type) {
+	case CSIPHY_DEV:
+		pmctl->csiphy_sdev = NULL;
+		break;
+	case CSID_DEV:
+		pmctl->csid_sdev = NULL;
+		break;
+	case CSIC_DEV:
+		pmctl->csic_sdev = NULL;
+		break;
+	case ISPIF_DEV:
+		pmctl->ispif_sdev = NULL;
+		break;
+	case VFE_DEV:
+		pmctl->vfe_sdev = NULL;
+		break;
+	case AXI_DEV:
+		pmctl->axi_sdev = NULL;
+		break;
+	case VPE_DEV:
+		pmctl->vpe_sdev = NULL;
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
+static long msm_ioctl_config(struct file *fp, unsigned int cmd,
+	unsigned long arg)
+{
+
+	int rc = 0;
+	struct v4l2_event ev;
+	struct msm_cam_config_dev *config_cam = fp->private_data;
+	struct v4l2_event_subscription temp_sub;
+
+	D("%s: cmd %d\n", __func__, _IOC_NR(cmd));
+	ev.id = 0;

+
+	switch (cmd) {
+	/* memory management shall be handeld here*/
+	case MSM_CAM_IOCTL_REGISTER_PMEM:
+		return msm_register_pmem(
+			&config_cam->p_mctl->stats_info.pmem_stats_list,
+			(void __user *)arg, config_cam->p_mctl->client,
+			config_cam->p_mctl->domain_num);
+		break;
+
+	case MSM_CAM_IOCTL_UNREGISTER_PMEM:
+		return msm_pmem_table_del(
+			&config_cam->p_mctl->stats_info.pmem_stats_list,
+			(void __user *)arg, config_cam->p_mctl->client,
+			config_cam->p_mctl->domain_num);
+		break;
+
+	case VIDIOC_SUBSCRIBE_EVENT:
+		if (copy_from_user(&temp_sub,
+			(void __user *)arg,
+			sizeof(struct v4l2_event_subscription))) {
+				pr_err("%s copy_from_user failed for cmd %d ",
+					__func__, cmd);
+				rc = -EINVAL;
+				return rc;
+		}
+		rc = msm_server_v4l2_subscribe_event
+			(&config_cam->config_stat_event_queue.eventHandle,
+				 &temp_sub);
+		if (rc < 0) {
+			pr_err("%s: cam_v4l2_subscribe_event failed rc=%d\n",
+				__func__, rc);
+			return rc;
+		}
+		break;
+
+	case VIDIOC_UNSUBSCRIBE_EVENT:
+		if (copy_from_user(&temp_sub, (void __user *)arg,
+			  sizeof(struct v4l2_event_subscription))) {
+			rc = -EINVAL;
+			return rc;
+		}
+		rc = msm_server_v4l2_unsubscribe_event
+			(&config_cam->config_stat_event_queue.eventHandle,
+			 &temp_sub);
+		if (rc < 0) {
+			pr_err("%s: cam_v4l2_unsubscribe_event failed rc=%d\n",
+				__func__, rc);
+			return rc;
+		}
+		break;
+
+	case VIDIOC_DQEVENT: {
+		void __user *u_msg_value = NULL, *user_ptr = NULL;
+		struct msm_isp_event_ctrl u_isp_event;
+		struct msm_isp_event_ctrl *k_isp_event;
+
+		/* First, copy the v4l2 event structure from userspace */
+		D("%s: VIDIOC_DQEVENT\n", __func__);
+		if (copy_from_user(&ev, (void __user *)arg,
+				sizeof(struct v4l2_event)))
+			break;
+		/* Next, get the pointer to event_ctrl structure
+		 * embedded inside the v4l2_event.u.data array. */
+		user_ptr = (void __user *)(*((uint32_t *)ev.u.data));
+
+		/* Next, copy the userspace event ctrl structure */
+		if (copy_from_user((void *)&u_isp_event, user_ptr,
+				   sizeof(struct msm_isp_event_ctrl))) {
+			rc = -EFAULT;
+			break;
+		}
+		/* Save the pointer of the user allocated command buffer*/
+		u_msg_value = u_isp_event.isp_data.isp_msg.data;
+
+		/* Dequeue the event queued into the v4l2 queue*/
+		rc = v4l2_event_dequeue(
+			&config_cam->config_stat_event_queue.eventHandle,
+			&ev, fp->f_flags & O_NONBLOCK);
+		if (rc < 0) {
+			pr_err("no pending events?");
+			rc = -EFAULT;
+			break;
+		}
+		/* Use k_isp_event to point to the event_ctrl structure
+		 * embedded inside v4l2_event.u.data */
+		k_isp_event = (struct msm_isp_event_ctrl *)
+				(*((uint32_t *)ev.u.data));
+		/* Copy the event structure into user struct. */
+		u_isp_event = *k_isp_event;
+		if (ev.type != (V4L2_EVENT_PRIVATE_START +
+				MSM_CAM_RESP_DIV_FRAME_EVT_MSG) &&
+				ev.type != (V4L2_EVENT_PRIVATE_START +
+				MSM_CAM_RESP_MCTL_PP_EVENT)) {
+
+			/* Restore the saved pointer of the
+			 * user allocated command buffer. */
+			u_isp_event.isp_data.isp_msg.data = u_msg_value;
+
+			if (ev.type == (V4L2_EVENT_PRIVATE_START +
+					MSM_CAM_RESP_STAT_EVT_MSG)) {
+				if (k_isp_event->isp_data.isp_msg.len > 0) {
+					void *k_msg_value =
+					k_isp_event->isp_data.isp_msg.data;
+					if (copy_to_user(u_msg_value,
+							k_msg_value,
+					 k_isp_event->isp_data.isp_msg.len)) {
+						rc = -EINVAL;
+						break;
+					}
+					kfree(k_msg_value);
+					k_msg_value = NULL;
+				}
+			}
+		}
+		/* Copy the event ctrl structure back
+		 * into user's structure. */
+		if (copy_to_user(user_ptr,
+				(void *)&u_isp_event, sizeof(
+				struct msm_isp_event_ctrl))) {
+			rc = -EINVAL;
+			break;
+		}
+		kfree(k_isp_event);
+		k_isp_event = NULL;
+
+		/* Copy the v4l2_event structure back to the user*/
+		if (copy_to_user((void __user *)arg, &ev,
+				sizeof(struct v4l2_event))) {
+			rc = -EINVAL;
+			break;
+		}
+		}
+
+		break;
+
+	case MSM_CAM_IOCTL_V4L2_EVT_NOTIFY:
+		rc = msm_v4l2_evt_notify(config_cam->p_mctl, cmd, arg);
+		break;
+
+	case MSM_CAM_IOCTL_SET_MEM_MAP_INFO:
+		if (copy_from_user(&config_cam->mem_map, (void __user *)arg,
+				sizeof(struct msm_mem_map_info)))
+			rc = -EINVAL;
+		break;
+
+	case MSM_CAM_IOCTL_SET_MCTL_SDEV:{
+		struct msm_mctl_set_sdev_data set_data;
+		if (copy_from_user(&set_data, (void __user *)arg,
+			sizeof(struct msm_mctl_set_sdev_data))) {
+			ERR_COPY_FROM_USER();
+			rc = -EINVAL;
+			break;
+		}
+		rc = msm_set_mctl_subdev(config_cam->p_mctl, &set_data);
+		break;
+	}
+
+	case MSM_CAM_IOCTL_UNSET_MCTL_SDEV:{
+		struct msm_mctl_set_sdev_data set_data;
+		if (copy_from_user(&set_data, (void __user *)arg,
+			sizeof(struct msm_mctl_set_sdev_data))) {
+			ERR_COPY_FROM_USER();
+			rc = -EINVAL;
+			break;
+		}
+		rc = msm_unset_mctl_subdev(config_cam->p_mctl, &set_data);
+		break;
+	}
+
+	default:{
+		/* For the rest of config command, forward to media controller*/
+		struct msm_cam_media_controller *p_mctl = config_cam->p_mctl;
+		if (p_mctl && p_mctl->mctl_cmd) {
+			rc = config_cam->p_mctl->mctl_cmd(p_mctl, cmd, arg);
+		} else {
+			rc = -EINVAL;
+			pr_err("%s: media controller is null\n", __func__);
+		}
+
+		break;
+	} /* end of default*/
+	} /* end of switch*/
+	return rc;
+}
+
+static int msm_close_config(struct inode *node, struct file *f)
+{
+	struct v4l2_event_subscription sub;
+	struct msm_cam_config_dev *config_cam = f->private_data;
+
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	D("%s Decrementing ref count of config node ", __func__);
+	kref_put(&config_cam->p_mctl->refcount, msm_release_ion_client);
+#endif
+	sub.type = V4L2_EVENT_ALL;
+	msm_server_v4l2_unsubscribe_event(
+		&config_cam->config_stat_event_queue.eventHandle,
+		&sub);
+	return 0;
+}
+
+static const struct file_operations msm_fops_config = {
+	.owner = THIS_MODULE,
+	.open  = msm_open_config,
+	.poll  = msm_poll_config,
+	.unlocked_ioctl = msm_ioctl_config,
+	.mmap	= msm_mmap_config,
+	.release = msm_close_config,
+};
+
+static int msm_setup_config_dev(int node, char *device_name)
+{
+	int rc = -ENODEV;
+	struct device *device_config;
+	int dev_num = node;
+	dev_t devno;
+	struct msm_cam_config_dev *config_cam;
+
+	config_cam = kzalloc(sizeof(*config_cam), GFP_KERNEL);
+	if (!config_cam) {
+		pr_err("%s: could not allocate memory for config_device\n",
+			__func__);
+		return -ENOMEM;
+	}
+
+	D("%s\n", __func__);
+
+	devno = MKDEV(MAJOR(msm_devno), dev_num+1);
+	device_config = device_create(msm_class, NULL, devno, NULL, "%s%d",
+		device_name, dev_num);
+
+	if (IS_ERR(device_config)) {
+		rc = PTR_ERR(device_config);
+		pr_err("%s: error creating device: %d\n", __func__, rc);
+		goto config_setup_fail;
+	}
+
+	cdev_init(&config_cam->config_cdev, &msm_fops_config);
+	config_cam->config_cdev.owner = THIS_MODULE;
+
+	rc = cdev_add(&config_cam->config_cdev, devno, 1);
+	if (rc < 0) {
+		pr_err("%s: error adding cdev: %d\n", __func__, rc);
+		device_destroy(msm_class, devno);
+		goto config_setup_fail;
+	}
+	g_server_dev.config_info.config_dev_name[dev_num] =
+		dev_name(device_config);
+	D("%s Connected config device %s\n", __func__,
+		g_server_dev.config_info.config_dev_name[dev_num]);
+	g_server_dev.config_info.config_dev_id[dev_num] =
+		dev_num;
+
+	config_cam->config_stat_event_queue.pvdev = video_device_alloc();
+	if (config_cam->config_stat_event_queue.pvdev == NULL) {
+		pr_err("%s: video_device_alloc failed\n", __func__);
+		goto config_setup_fail;
+	}
+
+	/* v4l2_fh support */
+	spin_lock_init(&config_cam->config_stat_event_queue.pvdev->fh_lock);
+	INIT_LIST_HEAD(&config_cam->config_stat_event_queue.pvdev->fh_list);
+	msm_setup_v4l2_event_queue(
+		&config_cam->config_stat_event_queue.eventHandle,
+		config_cam->config_stat_event_queue.pvdev);
+	config_cam->dev_num = dev_num;
+
+	return rc;
+
+config_setup_fail:
+	kfree(config_cam);
+	return rc;
+}
+
+static int __devinit msm_camera_probe(struct platform_device *pdev)
+{
+	int rc = 0, i;
+	memset(&g_server_dev, 0, sizeof(struct msm_cam_server_dev));
+	/*for now just create two config nodes
+	  put logic here later to know how many configs to create*/
+	g_server_dev.config_info.num_config_nodes = 2;
+
+	if (!msm_class) {
+		rc = alloc_chrdev_region(&msm_devno, 0,
+		g_server_dev.config_info.num_config_nodes+1, "msm_camera");
+		if (rc < 0) {
+			pr_err("%s: failed to allocate chrdev: %d\n", __func__,
+			rc);
+			return rc;
+		}
+
+		msm_class = class_create(THIS_MODULE, "msm_camera");
+		if (IS_ERR(msm_class)) {
+			rc = PTR_ERR(msm_class);
+			pr_err("%s: create device class failed: %d\n",
+			__func__, rc);
+			return rc;
+		}
+	}
+
+	D("creating server and config nodes\n");
+	rc = msm_setup_server_dev(pdev);
+	if (rc < 0) {
+		pr_err("%s: failed to create server dev: %d\n", __func__,
+		rc);
+		return rc;
+	}
+
+	for (i = 0; i < g_server_dev.config_info.num_config_nodes; i++) {
+		rc = msm_setup_config_dev(i, "config");
+		if (rc < 0) {
+			pr_err("%s:failed to create config dev: %d\n",
+			 __func__, rc);
+			return rc;
+		}
+	}
+
+	return rc;
+}
+
+static int __exit msm_camera_exit(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static const struct of_device_id msm_cam_server_dt_match[] = {
+	{.compatible = "qcom,cam_server"},
+}
+
+MODULE_DEVICE_TABLE(of, msm_cam_server_dt_match);
+
+static struct platform_driver msm_cam_server_driver = {
+	.probe = msm_camera_probe,
+	.remove = msm_camera_exit,
+	.driver = {
+		.name = "msm_cam_server",
+		.owner = THIS_MODULE,
+		.of_match_table = msm_cam_server_dt_match,
+	},
+};
+
+static int __init msm_cam_server_init(void)
+{
+	return platform_driver_register(&msm_cam_server_driver);
+}
+
+static void __exit msm_cam_server_exit(void)
+{
+	platform_driver_unregister(&msm_cam_server_driver);
+}
+
+module_init(msm_cam_server_init);
+module_exit(msm_cam_server_exit);
+MODULE_DESCRIPTION("msm camera server");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/server/msm_cam_server.h b/drivers/media/platform/msm/camera_v1/server/msm_cam_server.h
new file mode 100644
index 0000000..810830e
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/server/msm_cam_server.h
@@ -0,0 +1,73 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _MSM_CAM_SERVER_H
+#define _MSM_CAM_SERVER_H
+
+#include <linux/proc_fs.h>
+#include <linux/ioctl.h>
+#include <mach/camera.h>
+#include "../msm.h"
+
+uint32_t msm_cam_server_get_mctl_handle(void);
+struct iommu_domain *msm_cam_server_get_domain(void);
+int msm_cam_server_get_domain_num(void);
+struct msm_cam_media_controller *msm_cam_server_get_mctl(uint32_t handle);
+void msm_cam_server_free_mctl(uint32_t handle);
+/* Server session control APIs */
+int msm_server_begin_session(struct msm_cam_v4l2_device *pcam,
+	int server_q_idx);
+int msm_server_end_session(struct msm_cam_v4l2_device *pcam);
+int msm_send_open_server(struct msm_cam_v4l2_device *pcam);
+int msm_send_close_server(struct msm_cam_v4l2_device *pcam);
+int msm_server_update_sensor_info(struct msm_cam_v4l2_device *pcam,
+	struct msm_camera_sensor_info *sdata);
+/* Server camera control APIs */
+int msm_server_streamon(struct msm_cam_v4l2_device *pcam, int idx);
+int msm_server_streamoff(struct msm_cam_v4l2_device *pcam, int idx);
+int msm_server_get_usecount(void);
+int32_t msm_find_free_queue(void);
+int msm_server_proc_ctrl_cmd(struct msm_cam_v4l2_device *pcam,
+	struct msm_camera_v4l2_ioctl_t *ioctl_ptr, int is_set_cmd);
+int msm_server_private_general(struct msm_cam_v4l2_device *pcam,
+	struct msm_camera_v4l2_ioctl_t *ioctl_ptr);
+int msm_server_s_ctrl(struct msm_cam_v4l2_device *pcam,
+	struct v4l2_control *ctrl);
+int msm_server_g_ctrl(struct msm_cam_v4l2_device *pcam,
+	struct v4l2_control *ctrl);
+int msm_server_q_ctrl(struct msm_cam_v4l2_device *pcam,
+	struct v4l2_queryctrl *queryctrl);
+int msm_server_set_fmt(struct msm_cam_v4l2_device *pcam, int idx,
+	struct v4l2_format *pfmt);
+int msm_server_set_fmt_mplane(struct msm_cam_v4l2_device *pcam, int idx,
+	struct v4l2_format *pfmt);
+int msm_server_get_fmt(struct msm_cam_v4l2_device *pcam,
+	int idx, struct v4l2_format *pfmt);
+int msm_server_get_fmt_mplane(struct msm_cam_v4l2_device *pcam,
+	int idx, struct v4l2_format *pfmt);
+int msm_server_try_fmt(struct msm_cam_v4l2_device *pcam,
+	struct v4l2_format *pfmt);
+int msm_server_try_fmt_mplane(struct msm_cam_v4l2_device *pcam,
+	struct v4l2_format *pfmt);
+int msm_server_v4l2_subscribe_event(struct v4l2_fh *fh,
+	struct v4l2_event_subscription *sub);
+int msm_server_v4l2_unsubscribe_event(struct v4l2_fh *fh,
+	struct v4l2_event_subscription *sub);
+int msm_server_get_crop(struct msm_cam_v4l2_device *pcam,
+	int idx, struct v4l2_crop *crop);
+int msm_cam_server_request_irq(void *arg);
+int msm_cam_server_update_irqmap(
+	struct msm_cam_server_irqmap_entry *entry);
+int msm_cam_server_config_interface_map(u32 extendedmode,
+	uint32_t mctl_handle, int vnode_id, int is_bayer_sensor);
+#endif /* _MSM_CAM_SERVER_H */
diff --git a/drivers/media/platform/msm/camera_v1/sn12m0pz.c b/drivers/media/platform/msm/camera_v1/sn12m0pz.c
new file mode 100644
index 0000000..1fcd732
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/sn12m0pz.c
@@ -0,0 +1,1851 @@
+/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <media/msm_camera.h>
+#include <mach/gpio.h>
+#include <mach/camera.h>
+#include <linux/slab.h>
+#include "sn12m0pz.h"
+
+
+#define	Q8					0x00000100
+#define	REG_GROUPED_PARAMETER_HOLD		0x0104
+#define	GROUPED_PARAMETER_HOLD_OFF		0x00
+#define	GROUPED_PARAMETER_HOLD			0x01
+#define	REG_MODE_SELECT				0x0100
+#define	MODE_SELECT_STANDBY_MODE		0x00
+#define	MODE_SELECT_STREAM			0x01
+
+/* Integration Time */
+#define	REG_COARSE_INTEGRATION_TIME_MSB		0x0202
+#define	REG_COARSE_INTEGRATION_TIME_LSB		0x0203
+
+/* Gain */
+#define	REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB	0x0204
+#define	REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB	0x0205
+
+/* PLL Register Defines */
+#define	REG_PLL_MULTIPLIER			0x0307
+#define	REG_0x302B				0x302B
+
+/* MIPI Enable Settings */
+#define	REG_0x30E5				0x30E5
+#define	REG_0x3300				0x3300
+
+/* Global Setting */
+#define	REG_IMAGE_ORIENTATION			0x0101
+
+#define	REG_0x300A				0x300A
+#define	REG_0x3014				0x3014
+#define	REG_0x3015				0x3015
+#define	REG_0x3017				0x3017
+#define	REG_0x301C				0x301C
+#define	REG_0x3031				0x3031
+#define	REG_0x3040				0x3040
+#define	REG_0x3041				0x3041
+#define	REG_0x3051				0x3051
+#define	REG_0x3053				0x3053
+#define	REG_0x3055				0x3055
+#define	REG_0x3057				0x3057
+#define	REG_0x3060				0x3060
+#define	REG_0x3065				0x3065
+#define	REG_0x30AA				0x30AA
+#define	REG_0x30AB				0x30AB
+#define	REG_0x30B0				0x30B0
+#define	REG_0x30B2				0x30B2
+#define	REG_0x30D3				0x30D3
+
+#define	REG_0x3106				0x3106
+#define	REG_0x3108				0x3108
+#define	REG_0x310A				0x310A
+#define	REG_0x310C				0x310C
+#define	REG_0x310E				0x310E
+#define	REG_0x3126				0x3126
+#define	REG_0x312E				0x312E
+#define	REG_0x313C				0x313C
+#define	REG_0x313E				0x313E
+#define	REG_0x3140				0x3140
+#define	REG_0x3142				0x3142
+#define	REG_0x3144				0x3144
+#define	REG_0x3148				0x3148
+#define	REG_0x314A				0x314A
+#define	REG_0x3166				0x3166
+#define	REG_0x3168				0x3168
+#define	REG_0x316F				0x316F
+#define	REG_0x3171				0x3171
+#define	REG_0x3173				0x3173
+#define	REG_0x3175				0x3175
+#define	REG_0x3177				0x3177
+#define	REG_0x3179				0x3179
+#define	REG_0x317B				0x317B
+#define	REG_0x317D				0x317D
+#define	REG_0x317F			0x317F
+#define	REG_0x3181			0x3181
+#define	REG_0x3184			0x3184
+#define	REG_0x3185			0x3185
+#define	REG_0x3187			0x3187
+
+#define	REG_0x31A4			0x31A4
+#define	REG_0x31A6			0x31A6
+#define	REG_0x31AC			0x31AC
+#define	REG_0x31AE			0x31AE
+#define	REG_0x31B4			0x31B4
+#define	REG_0x31B6			0x31B6
+
+#define	REG_0x3254			0x3254
+#define	REG_0x3256			0x3256
+#define	REG_0x3258			0x3258
+#define	REG_0x325A			0x325A
+#define	REG_0x3260			0x3260
+#define	REG_0x3262			0x3262
+
+
+#define	REG_0x3304			0x3304
+#define	REG_0x3305			0x3305
+#define	REG_0x3306			0x3306
+#define	REG_0x3307			0x3307
+#define	REG_0x3308			0x3308
+#define	REG_0x3309			0x3309
+#define	REG_0x330A			0x330A
+#define	REG_0x330B			0x330B
+#define	REG_0x330C			0x330C
+#define	REG_0x330D			0x330D
+
+/* Mode Setting */
+#define	REG_FRAME_LENGTH_LINES_MSB	0x0340
+#define	REG_FRAME_LENGTH_LINES_LSB	0x0341
+#define	REG_LINE_LENGTH_PCK_MSB		0x0342
+#define	REG_LINE_LENGTH_PCK_LSB		0x0343
+#define	REG_X_OUTPUT_SIZE_MSB		0x034C
+#define	REG_X_OUTPUT_SIZE_LSB		0x034D
+#define	REG_Y_OUTPUT_SIZE_MSB		0x034E
+#define	REG_Y_OUTPUT_SIZE_LSB		0x034F
+#define	REG_X_EVEN_INC_LSB		0x0381
+#define	REG_X_ODD_INC_LSB		0x0383
+#define	REG_Y_EVEN_INC_LSB		0x0385
+#define	REG_Y_ODD_INC_LSB		0x0387
+#define	REG_0x3016			0x3016
+#define	REG_0x30E8			0x30E8
+#define	REG_0x3301			0x3301
+/* for 120fps support */
+#define	REG_0x0344			0x0344
+#define	REG_0x0345			0x0345
+#define	REG_0x0346			0x0346
+#define	REG_0x0347			0x0347
+#define	REG_0x0348			0x0348
+#define	REG_0x0349			0x0349
+#define	REG_0x034A			0x034A
+#define	REG_0x034B			0x034B
+
+/* Test Pattern */
+#define	REG_0x30D8			0x30D8
+#define	REG_TEST_PATTERN_MODE		0x0601
+
+/* Solid Color Test Pattern */
+#define	REG_TEST_DATA_RED_MSB		0x0603
+#define	REG_TEST_DATA_RED_LSB		0x0603
+#define	REG_TEST_DATA_GREENR_MSB	0x0604
+#define	REG_TEST_DATA_GREENR_LSB	0x0605
+#define	REG_TEST_DATA_BLUE_MSB		0x0606
+#define	REG_TEST_DATA_BLUE_LSB		0x0607
+#define	REG_TEST_DATA_GREENB_MSB	0x0608
+#define	REG_TEST_DATA_GREENB_LSB	0x0609
+#define	SN12M0PZ_AF_I2C_SLAVE_ID	0xE4
+#define	SN12M0PZ_STEPS_NEAR_TO_CLOSEST_INF	42
+#define	SN12M0PZ_TOTAL_STEPS_NEAR_TO_FAR	42
+
+
+/* TYPE DECLARATIONS */
+
+
+enum mipi_config_type {
+	IU060F_SN12M0PZ_STMIPID01,
+	IU060F_SN12M0PZ_STMIPID02
+};
+
+enum sn12m0pz_test_mode_t {
+	TEST_OFF,
+	TEST_1,
+	TEST_2,
+	TEST_3
+};
+
+enum sn12m0pz_resolution_t {
+	QTR_SIZE,
+	FULL_SIZE,
+	INVALID_SIZE,
+	QVGA_SIZE,
+};
+
+enum sn12m0pz_setting {
+	RES_PREVIEW,
+	RES_CAPTURE,
+	RES_VIDEO_120FPS,
+};
+
+enum mt9p012_reg_update {
+	/* Sensor egisters that need to be updated during initialization */
+	REG_INIT,
+	/* Sensor egisters that needs periodic I2C writes */
+	UPDATE_PERIODIC,
+	/* All the sensor Registers will be updated */
+	UPDATE_ALL,
+	/* Not valid update */
+	UPDATE_INVALID
+};
+
+/* 816x612, 24MHz MCLK 96MHz PCLK */
+#define	IU060F_SN12M0PZ_OFFSET			3
+/* Time in milisecs for waiting for the sensor to reset.*/
+#define	SN12M0PZ_RESET_DELAY_MSECS		66
+#define	SN12M0PZ_WIDTH				4032
+#define	SN12M0PZ_HEIGHT				3024
+#define	SN12M0PZ_FULL_SIZE_WIDTH		4032
+#define	SN12M0PZ_FULL_SIZE_HEIGHT		3024
+#define	SN12M0PZ_HRZ_FULL_BLK_PIXELS		176
+#define	SN12M0PZ_VER_FULL_BLK_LINES		50
+#define	SN12M0PZ_QTR_SIZE_WIDTH			2016
+#define	SN12M0PZ_QTR_SIZE_HEIGHT		1512
+#define	SN12M0PZ_HRZ_QTR_BLK_PIXELS		2192
+#define	SN12M0PZ_VER_QTR_BLK_LINES		26
+
+/* 120fps mode */
+#define	SN12M0PZ_QVGA_SIZE_WIDTH		4032
+#define	SN12M0PZ_QVGA_SIZE_HEIGHT		249
+#define	SN12M0PZ_HRZ_QVGA_BLK_PIXELS		176
+#define	SN12M0PZ_VER_QVGA_BLK_LINES		9
+#define	SN12M0PZ_DEFAULT_CLOCK_RATE		24000000
+
+static uint32_t IU060F_SN12M0PZ_DELAY_MSECS = 30;
+static enum mipi_config_type mipi_config = IU060F_SN12M0PZ_STMIPID02;
+/* AF Tuning Parameters */
+static int16_t enable_single_D02_lane;
+static int16_t fullsize_cropped_at_8mp;
+
+struct sn12m0pz_work_t {
+	struct work_struct work;
+};
+
+static struct sn12m0pz_work_t *sn12m0pz_sensorw;
+static struct i2c_client *sn12m0pz_client;
+
+struct sn12m0pz_ctrl_t {
+	const struct msm_camera_sensor_info *sensordata;
+	uint32_t sensormode;
+	uint32_t fps_divider;/* init to 1 * 0x00000400 */
+	uint32_t pict_fps_divider;/* init to 1 * 0x00000400 */
+	uint16_t fps;
+	int16_t curr_lens_pos;
+	uint16_t curr_step_pos;
+	uint16_t my_reg_gain;
+	uint32_t my_reg_line_count;
+	uint16_t total_lines_per_frame;
+	enum sn12m0pz_resolution_t prev_res;
+	enum sn12m0pz_resolution_t pict_res;
+	enum sn12m0pz_resolution_t curr_res;
+	enum sn12m0pz_test_mode_t  set_test;
+	unsigned short imgaddr;
+};
+
+static struct sn12m0pz_ctrl_t *sn12m0pz_ctrl;
+static DECLARE_WAIT_QUEUE_HEAD(sn12m0pz_wait_queue);
+DEFINE_MUTEX(sn12m0pz_mut);
+
+
+static int sn12m0pz_i2c_rxdata(unsigned short saddr,
+	unsigned char *rxdata, int length)
+{
+	struct i2c_msg msgs[] = {
+		{
+			.addr  = saddr,
+			.flags = 0,
+			.len   = 2,
+			.buf   = rxdata,
+		},
+		{
+			.addr  = saddr,
+			.flags = I2C_M_RD,
+			.len   = 2,
+			.buf   = rxdata,
+		},
+	};
+
+	if (i2c_transfer(sn12m0pz_client->adapter, msgs, 2) < 0) {
+		CDBG("sn12m0pz_i2c_rxdata failed!");
+		return -EIO;
+	}
+
+	return 0;
+}
+static int32_t sn12m0pz_i2c_txdata(unsigned short saddr,
+				unsigned char *txdata, int length)
+{
+
+	struct i2c_msg msg[] = {
+		{
+			.addr  = saddr,
+			.flags = 0,
+			.len	 = length,
+			.buf	 = txdata,
+		},
+	};
+
+	if (i2c_transfer(sn12m0pz_client->adapter, msg, 1) < 0) {
+		CDBG("sn12m0pz_i2c_txdata faild 0x%x", sn12m0pz_client->addr);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t sn12m0pz_i2c_read(unsigned short raddr,
+				unsigned short *rdata, int rlen)
+{
+	int32_t rc;
+	unsigned char buf[2];
+	if (!rdata)
+		return -EIO;
+
+	memset(buf, 0, sizeof(buf));
+
+	buf[0] = (raddr & 0xFF00) >> 8;
+	buf[1] = (raddr & 0x00FF);
+
+	rc = sn12m0pz_i2c_rxdata(sn12m0pz_client->addr, buf, rlen);
+
+	if (rc < 0) {
+		CDBG("sn12m0pz_i2c_read 0x%x failed!", raddr);
+		return rc;
+	}
+
+	*rdata = (rlen == 2 ? buf[0] << 8 | buf[1] : buf[0]);
+
+	return rc;
+}
+
+static int32_t sn12m0pz_i2c_write_b_sensor(unsigned short waddr, uint8_t bdata)
+{
+	int32_t rc;
+	unsigned char buf[3];
+
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00) >> 8;
+	buf[1] = (waddr & 0x00FF);
+	buf[2] = bdata;
+	udelay(90);
+	CDBG("i2c_write_b addr = %x, val = %x\n", waddr, bdata);
+	rc = sn12m0pz_i2c_txdata(sn12m0pz_client->addr, buf, 3);
+
+	if (rc < 0) {
+		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!",
+			waddr, bdata);
+	}
+
+	return rc;
+}
+
+static int16_t sn12m0pz_i2c_write_b_af(unsigned short saddr,
+				unsigned short baddr, unsigned short bdata)
+{
+	int16_t rc;
+	unsigned char buf[2];
+
+	memset(buf, 0, sizeof(buf));
+	buf[0] = baddr;
+	buf[1] = bdata;
+	rc = sn12m0pz_i2c_txdata(saddr, buf, 2);
+
+	if (rc < 0)
+		CDBG("i2c_write failed, saddr = 0x%x addr = 0x%x, val =0x%x!",
+			saddr, baddr, bdata);
+
+	return rc;
+}
+
+static int32_t sn12m0pz_i2c_write_byte_bridge(unsigned short saddr,
+				unsigned short waddr, uint8_t bdata)
+{
+	int32_t rc;
+	unsigned char buf[3];
+
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00) >> 8;
+	buf[1] = (waddr & 0x00FF);
+	buf[2] = bdata;
+
+	CDBG("i2c_write_b addr = %x, val = %x", waddr, bdata);
+	rc = sn12m0pz_i2c_txdata(saddr, buf, 3);
+
+	if (rc < 0)
+		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!",
+			waddr, bdata);
+
+	return rc;
+}
+
+static int32_t sn12m0pz_stmipid01_config(void)
+{
+	int32_t rc = 0;
+	/* Initiate I2C for D01: */
+	/* MIPI Bridge configuration */
+	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0002, 0x19) < 0)
+		return rc; /* enable clock lane*/
+	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0003, 0x00) < 0)
+		return rc;
+	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0004, 0x3E) < 0)
+		return rc; /* mipi mode clock*/
+	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0005, 0x01) < 0)
+		return rc; /* enable data line*/
+	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0006, 0x0F) < 0)
+		return rc; /* mipi mode data 0x01*/
+	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0009, 0x00) < 0)
+		return rc; /* Data_Lane1_Reg1*/
+	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x000D, 0x92) < 0)
+		return rc; /* CCPRxRegisters*/
+	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x000E, 0x28) < 0)
+		return rc; /* 10 bits for pixel width input for CCP rx.*/
+	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0014, 0xC0) < 0)
+		return rc; /* no bypass, no decomp, 1Lane System,CSIstreaming*/
+	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0015, 0x48) < 0)
+		return rc; /* ModeControlRegisters-- Don't reset error flag*/
+	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0017, 0x2B) < 0)
+		return rc; /* Data_ID_Rreg*/
+	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0018, 0x2B) < 0)
+		return rc; /* Data_ID_Rreg_emb*/
+	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0019, 0x0C) < 0)
+		return rc;
+	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x001E, 0x0A) < 0)
+		return rc;
+	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x001F, 0x0A) < 0)
+		return rc;
+
+	return rc;
+}
+static int32_t sn12m0pz_stmipid02_config(void)
+{
+	int32_t rc = 0;
+
+	/* Main Camera Clock Lane 1 (CLHP1, CLKN1)*/
+	/* Enable Clock Lane 1 (CLHP1, CLKN1), 0x15 for 400MHz */
+	if (enable_single_D02_lane) {
+		if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0002, 0x19) < 0)
+			return rc;
+		/* Main Camera Data Lane 1.1 (DATA2P1, DATA2N1) */
+		if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0009, 0x00) < 0)
+			return rc;/* Enable Data Lane 1.2 (DATA2P1, DATA2N1) */
+		if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x000A, 0x00) < 0)
+			return rc; /*CSIMode on Data Lane1.2(DATA2P1,DATA2N1)*/
+		/* Mode Control */
+		/* Enable single lane for qtr preview */
+		if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0014, 0xC0) < 0)
+			return rc; /*set 0xC0 - left justified on upper bits)*/
+		/* bit 1 set to 0 i.e. 1 lane system for qtr size preview */
+	} else {
+		if (sn12m0pz_ctrl->prev_res == QVGA_SIZE) {
+			if (sn12m0pz_i2c_write_byte_bridge(0x28>>1,
+				0x0002, 0x19) < 0)
+				return rc;
+		} else {
+			if (sn12m0pz_i2c_write_byte_bridge(0x28>>1,
+				0x0002, 0x21) < 0)
+				return rc;
+		}
+		/* Main Camera Data Lane 1.1 (DATA2P1, DATA2N1) */
+		if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0009, 0x01) < 0)
+			return rc; /* Enable Data Lane 1.2 (DATA2P1, DATA2N1) */
+		if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x000A, 0x01) < 0)
+			return rc; /* CSI Mode Data Lane1.2(DATA2P1, DATA2N1)*/
+
+		/* Mode Control */
+		/* Enable two lanes for full size preview/ snapshot */
+		if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0014, 0xC2) < 0)
+			return rc; /* No decompression, CSI dual lane */
+	}
+
+	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0004, 0x1E) < 0)
+		return rc;
+
+	/* Main Camera Data Lane 1.1 (DATA1P1, DATA1N1) */
+	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0005, 0x03) < 0)
+		return rc; /* Enable Data Lane 1.1 (DATA1P1, DATA1N1) */
+	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0006, 0x0f) < 0)
+		return rc; /* CSI Mode on Data Lane 1.1 (DATA1P1, DATA1N1) */
+
+	/* Tristated Output, continuous clock, */
+	/*polarity of clock is inverted and sync signals not inverted*/
+	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0015, 0x08) < 0)
+		return rc;
+	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0036, 0x20) < 0)
+		return rc; /* Enable compensation macro, main camera */
+
+	/* Data type: 0x2B Raw 10 */
+	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0017, 0x2B) < 0)
+		return rc;
+	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0018, 0x2B) < 0)
+		return rc; /* Data type of embedded data: 0x2B Raw 10 */
+	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0019, 0x0C) < 0)
+		return rc; /* Data type and pixel width programmed 0x0C*/
+
+	/* Decompression Mode */
+
+	/* Pixel Width and Decompression ON/OFF */
+	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x001E, 0x0A) < 0)
+		return rc; /* Image data not compressed: 0x0A for 10 bits */
+	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x001F, 0x0A) < 0)
+		return rc; /* Embedded data not compressed: 0x0A for 10 bits */
+	return rc;
+}
+
+static int16_t sn12m0pz_af_init(void)
+{
+	int16_t rc;
+	/* Initialize waveform */
+	rc = sn12m0pz_i2c_write_b_af(SN12M0PZ_AF_I2C_SLAVE_ID >> 1, 0x01, 0xA9);
+
+	rc = sn12m0pz_i2c_write_b_af(SN12M0PZ_AF_I2C_SLAVE_ID >> 1, 0x02, 0xD2);
+
+	rc = sn12m0pz_i2c_write_b_af(SN12M0PZ_AF_I2C_SLAVE_ID >> 1, 0x03, 0x0C);
+
+	rc = sn12m0pz_i2c_write_b_af(SN12M0PZ_AF_I2C_SLAVE_ID >> 1, 0x04, 0x14);
+
+	rc = sn12m0pz_i2c_write_b_af(SN12M0PZ_AF_I2C_SLAVE_ID >> 1, 0x05, 0xB6);
+
+	rc = sn12m0pz_i2c_write_b_af(SN12M0PZ_AF_I2C_SLAVE_ID >> 1, 0x06, 0x4F);
+
+	rc = sn12m0pz_i2c_write_b_af(SN12M0PZ_AF_I2C_SLAVE_ID >> 1, 0x07, 0x00);
+
+	return rc;
+}
+
+static int32_t sn12m0pz_move_focus(int direction,
+	int32_t num_steps)
+{
+	int8_t step_direction, dest_step_position, bit_mask;
+	int32_t rc = 0;
+	uint16_t sn12m0pz_l_region_code_per_step = 3;
+
+	if (num_steps == 0)
+		return rc;
+
+	if (direction == MOVE_NEAR) {
+		step_direction = 1;
+		bit_mask = 0x80;
+	} else if (direction == MOVE_FAR) {
+		step_direction = -1;
+		bit_mask = 0x00;
+	} else {
+		CDBG("sn12m0pz_move_focus: Illegal focus direction");
+		return -EINVAL;
+	}
+
+	dest_step_position = sn12m0pz_ctrl->curr_step_pos +
+		(step_direction * num_steps);
+
+	if (dest_step_position < 0)
+		dest_step_position = 0;
+	else if (dest_step_position > SN12M0PZ_TOTAL_STEPS_NEAR_TO_FAR)
+		dest_step_position = SN12M0PZ_TOTAL_STEPS_NEAR_TO_FAR;
+
+	rc = sn12m0pz_i2c_write_b_af(SN12M0PZ_AF_I2C_SLAVE_ID >> 1, 0x00,
+		((num_steps * sn12m0pz_l_region_code_per_step) | bit_mask));
+
+	sn12m0pz_ctrl->curr_step_pos = dest_step_position;
+
+	return rc;
+}
+static int32_t sn12m0pz_set_default_focus(uint8_t af_step)
+{
+	int32_t rc;
+
+	/* Initialize to infinity */
+
+	rc = sn12m0pz_i2c_write_b_af(SN12M0PZ_AF_I2C_SLAVE_ID >> 1, 0x00, 0x7F);
+
+	rc = sn12m0pz_i2c_write_b_af(SN12M0PZ_AF_I2C_SLAVE_ID >> 1, 0x00, 0x7F);
+
+	sn12m0pz_ctrl->curr_step_pos = 0;
+
+	return rc;
+}
+static void sn12m0pz_get_pict_fps(uint16_t fps, uint16_t *pfps)
+{
+	/* input fps is preview fps in Q8 format */
+	uint16_t preview_frame_length_lines, snapshot_frame_length_lines;
+	uint16_t preview_line_length_pck, snapshot_line_length_pck;
+	uint32_t divider, pclk_mult, d1, d2;
+
+	/* Total frame_length_lines and line_length_pck for preview */
+	CDBG("sn12m0pz_get_pict_fps prev_res %d", sn12m0pz_ctrl->prev_res);
+	if (sn12m0pz_ctrl->prev_res == QVGA_SIZE) {
+		preview_frame_length_lines = SN12M0PZ_QVGA_SIZE_HEIGHT +
+			SN12M0PZ_VER_QVGA_BLK_LINES;
+		preview_line_length_pck = SN12M0PZ_QVGA_SIZE_WIDTH +
+			SN12M0PZ_HRZ_QVGA_BLK_PIXELS;
+	} else {
+		preview_frame_length_lines = SN12M0PZ_QTR_SIZE_HEIGHT +
+			SN12M0PZ_VER_QTR_BLK_LINES;
+		preview_line_length_pck = SN12M0PZ_QTR_SIZE_WIDTH +
+			SN12M0PZ_HRZ_QTR_BLK_PIXELS;
+	}
+	/* Total frame_length_lines and line_length_pck for snapshot */
+	snapshot_frame_length_lines = SN12M0PZ_FULL_SIZE_HEIGHT
+				+ SN12M0PZ_HRZ_FULL_BLK_PIXELS;
+	snapshot_line_length_pck = SN12M0PZ_FULL_SIZE_WIDTH
+				+ SN12M0PZ_HRZ_FULL_BLK_PIXELS;
+	d1 = preview_frame_length_lines *
+				0x00000400 / snapshot_frame_length_lines;
+	d2 = preview_line_length_pck *
+				0x00000400/snapshot_line_length_pck;
+	divider = d1 * d2 / 0x400;
+	pclk_mult =
+		(uint32_t)
+		(sn12m0pz_regs.reg_pat[RES_CAPTURE].pll_multiplier_lsb *
+		0x400) / (uint32_t)
+		sn12m0pz_regs.reg_pat[RES_PREVIEW].pll_multiplier_lsb;
+	*pfps = (uint16_t) (((fps * divider) / 0x400 * pclk_mult) / 0x400);
+}
+
+static uint16_t sn12m0pz_get_prev_lines_pf(void)
+{
+	if (sn12m0pz_ctrl->prev_res == QTR_SIZE)
+		return SN12M0PZ_QTR_SIZE_HEIGHT +
+			SN12M0PZ_VER_QTR_BLK_LINES;
+	else if (sn12m0pz_ctrl->prev_res == QVGA_SIZE)
+		return SN12M0PZ_QVGA_SIZE_HEIGHT +
+			SN12M0PZ_VER_QVGA_BLK_LINES;
+
+	else
+		return SN12M0PZ_FULL_SIZE_HEIGHT +
+			SN12M0PZ_VER_FULL_BLK_LINES;
+}
+
+static uint16_t sn12m0pz_get_prev_pixels_pl(void)
+{
+	if (sn12m0pz_ctrl->prev_res == QTR_SIZE)
+		return SN12M0PZ_QTR_SIZE_WIDTH +
+			SN12M0PZ_HRZ_QTR_BLK_PIXELS;
+	else
+		return SN12M0PZ_FULL_SIZE_WIDTH +
+			SN12M0PZ_HRZ_FULL_BLK_PIXELS;
+}
+
+static uint16_t sn12m0pz_get_pict_lines_pf(void)
+{
+	if (sn12m0pz_ctrl->pict_res == QTR_SIZE)
+		return SN12M0PZ_QTR_SIZE_HEIGHT +
+			SN12M0PZ_VER_QTR_BLK_LINES;
+	else
+		return SN12M0PZ_FULL_SIZE_HEIGHT +
+			SN12M0PZ_VER_FULL_BLK_LINES;
+}
+
+static uint16_t sn12m0pz_get_pict_pixels_pl(void)
+{
+	if (sn12m0pz_ctrl->pict_res == QTR_SIZE)
+		return SN12M0PZ_QTR_SIZE_WIDTH +
+			SN12M0PZ_HRZ_QTR_BLK_PIXELS;
+	else
+		return SN12M0PZ_FULL_SIZE_WIDTH +
+			SN12M0PZ_HRZ_FULL_BLK_PIXELS;
+}
+
+static uint32_t sn12m0pz_get_pict_max_exp_lc(void)
+{
+	if (sn12m0pz_ctrl->pict_res == QTR_SIZE)
+		return (SN12M0PZ_QTR_SIZE_HEIGHT +
+			SN12M0PZ_VER_QTR_BLK_LINES) * 24;
+	else
+		return (SN12M0PZ_FULL_SIZE_HEIGHT +
+			SN12M0PZ_VER_FULL_BLK_LINES) * 24;
+}
+
+static int32_t sn12m0pz_set_fps(struct fps_cfg	*fps)
+{
+	uint16_t total_lines_per_frame;
+	int32_t rc = 0;
+
+	total_lines_per_frame = (uint16_t)((SN12M0PZ_QTR_SIZE_HEIGHT +
+				SN12M0PZ_VER_QTR_BLK_LINES) *
+				sn12m0pz_ctrl->fps_divider / 0x400);
+
+	if (sn12m0pz_i2c_write_b_sensor(REG_FRAME_LENGTH_LINES_MSB,
+				((total_lines_per_frame & 0xFF00) >> 8)) < 0)
+		return rc;
+
+	if (sn12m0pz_i2c_write_b_sensor(REG_FRAME_LENGTH_LINES_LSB,
+				(total_lines_per_frame & 0x00FF)) < 0)
+		return rc;
+
+	return rc;
+}
+
+static int32_t sn12m0pz_write_exp_gain(uint16_t gain, uint32_t line)
+{
+	static uint16_t max_legal_gain = 0x00E0;
+	uint8_t gain_msb, gain_lsb;
+	uint8_t intg_time_msb, intg_time_lsb;
+	uint8_t line_length_pck_msb, line_length_pck_lsb;
+	uint16_t line_length_pck, frame_length_lines, temp_lines;
+	uint32_t line_length_ratio = 1 * Q8;
+	int32_t rc = 0;
+	CDBG("sn12m0pz_write_exp_gain : gain = %d line = %d", gain, line);
+
+	if (sn12m0pz_ctrl->sensormode != SENSOR_SNAPSHOT_MODE) {
+		if (sn12m0pz_ctrl->prev_res == QVGA_SIZE) {
+			frame_length_lines = SN12M0PZ_QVGA_SIZE_HEIGHT +
+						SN12M0PZ_VER_QVGA_BLK_LINES;
+			line_length_pck = SN12M0PZ_QVGA_SIZE_WIDTH +
+						SN12M0PZ_HRZ_QVGA_BLK_PIXELS;
+			if (line > (frame_length_lines -
+					IU060F_SN12M0PZ_OFFSET))
+				line = frame_length_lines -
+						IU060F_SN12M0PZ_OFFSET;
+			sn12m0pz_ctrl->fps = (uint16_t) (120 * Q8);
+		} else {
+			if (sn12m0pz_ctrl->curr_res  == QTR_SIZE) {
+				frame_length_lines = SN12M0PZ_QTR_SIZE_HEIGHT +
+						SN12M0PZ_VER_QTR_BLK_LINES;
+				line_length_pck = SN12M0PZ_QTR_SIZE_WIDTH +
+						SN12M0PZ_HRZ_QTR_BLK_PIXELS;
+			} else {
+				frame_length_lines = SN12M0PZ_HEIGHT +
+						SN12M0PZ_VER_FULL_BLK_LINES;
+				line_length_pck = SN12M0PZ_WIDTH +
+						SN12M0PZ_HRZ_FULL_BLK_PIXELS;
+			}
+			if (line > (frame_length_lines -
+						IU060F_SN12M0PZ_OFFSET))
+				sn12m0pz_ctrl->fps = (uint16_t) (30 * Q8 *
+			(frame_length_lines - IU060F_SN12M0PZ_OFFSET) / line);
+			else
+				sn12m0pz_ctrl->fps = (uint16_t) (30 * Q8);
+		}
+	} else {
+		if (sn12m0pz_ctrl->curr_res  == QTR_SIZE) {
+			frame_length_lines = SN12M0PZ_QTR_SIZE_HEIGHT +
+						SN12M0PZ_VER_QTR_BLK_LINES;
+			line_length_pck = SN12M0PZ_QTR_SIZE_WIDTH +
+						SN12M0PZ_HRZ_QTR_BLK_PIXELS;
+		} else {
+			frame_length_lines = SN12M0PZ_HEIGHT +
+						SN12M0PZ_VER_FULL_BLK_LINES;
+			line_length_pck = SN12M0PZ_WIDTH +
+						SN12M0PZ_HRZ_FULL_BLK_PIXELS;
+		}
+	}
+	if (gain > max_legal_gain)
+		/* range: 0 to 224 */
+		gain = max_legal_gain;
+	temp_lines = line;
+	/* calculate line_length_ratio */
+	if (line > (frame_length_lines - IU060F_SN12M0PZ_OFFSET)) {
+		line_length_ratio = (line * Q8) / (frame_length_lines -
+					IU060F_SN12M0PZ_OFFSET);
+		temp_lines = frame_length_lines - IU060F_SN12M0PZ_OFFSET;
+		if (line_length_ratio == 0)
+			line_length_ratio = 1 * Q8;
+	} else
+		line_length_ratio = 1 * Q8;
+
+	line = (uint32_t) (line * sn12m0pz_ctrl->fps_divider/0x400);
+
+	/* update gain registers */
+	gain_msb = (uint8_t) ((gain & 0xFF00) >> 8);
+	gain_lsb = (uint8_t) (gain & 0x00FF);
+
+	/* linear AFR horizontal stretch */
+	line_length_pck = (uint16_t) (line_length_pck * line_length_ratio / Q8);
+	line_length_pck_msb = (uint8_t) ((line_length_pck & 0xFF00) >> 8);
+	line_length_pck_lsb = (uint8_t) (line_length_pck & 0x00FF);
+
+	/* update line count registers */
+	intg_time_msb = (uint8_t) ((temp_lines & 0xFF00) >> 8);
+	intg_time_lsb = (uint8_t) (temp_lines & 0x00FF);
+
+
+	if (sn12m0pz_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
+			GROUPED_PARAMETER_HOLD) < 0)
+		return rc;
+
+	if (sn12m0pz_i2c_write_b_sensor(REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB,
+			gain_msb) < 0)
+		return rc;
+
+	if (sn12m0pz_i2c_write_b_sensor(REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB,
+			gain_lsb) < 0)
+		return rc;
+
+	if (sn12m0pz_i2c_write_b_sensor(REG_LINE_LENGTH_PCK_MSB,
+			line_length_pck_msb) < 0)
+		return rc;
+
+	if (sn12m0pz_i2c_write_b_sensor(REG_LINE_LENGTH_PCK_LSB,
+			line_length_pck_lsb) < 0)
+		return rc;
+
+	if (sn12m0pz_i2c_write_b_sensor(REG_COARSE_INTEGRATION_TIME_MSB,
+			intg_time_msb) < 0)
+		return rc;
+
+	if (sn12m0pz_i2c_write_b_sensor(REG_COARSE_INTEGRATION_TIME_LSB,
+			intg_time_lsb) < 0)
+		return rc;
+
+	if (sn12m0pz_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
+			GROUPED_PARAMETER_HOLD_OFF) < 0)
+		return rc;
+
+	return rc;
+}
+
+
+static int32_t sn12m0pz_set_pict_exp_gain(uint16_t gain, uint32_t line)
+{
+	int32_t rc;
+	rc = sn12m0pz_write_exp_gain(gain, line);
+	return rc;
+}
+
+static int32_t sn12m0pz_test(enum sn12m0pz_test_mode_t mo)
+{
+	uint8_t test_data_val_msb = 0x07;
+	uint8_t test_data_val_lsb = 0xFF;
+	int32_t rc = 0;
+	if (mo == TEST_OFF)
+		return rc;
+	else {
+		/* REG_0x30D8[4] is TESBYPEN: 0: Normal Operation,
+		 1: Bypass Signal Processing. REG_0x30D8[5] is EBDMASK:
+		 0: Output Embedded data, 1: No output embedded data */
+
+		if (sn12m0pz_i2c_write_b_sensor(REG_0x30D8, 0x10) < 0)
+			return rc;
+
+		if (sn12m0pz_i2c_write_b_sensor(REG_TEST_PATTERN_MODE,
+			(uint8_t) mo) < 0)
+			return rc;
+
+		/* Solid Color Test Pattern */
+
+		if (mo == TEST_1) {
+			if (sn12m0pz_i2c_write_b_sensor(REG_TEST_DATA_RED_MSB,
+				test_data_val_msb) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_TEST_DATA_RED_LSB,
+				test_data_val_lsb) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(
+						REG_TEST_DATA_GREENR_MSB,
+						test_data_val_msb) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(
+						REG_TEST_DATA_GREENR_LSB,
+						test_data_val_lsb) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_TEST_DATA_BLUE_MSB,
+				test_data_val_msb) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_TEST_DATA_BLUE_LSB,
+				test_data_val_lsb) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(
+						REG_TEST_DATA_GREENB_MSB,
+						test_data_val_msb) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(
+						REG_TEST_DATA_GREENB_LSB,
+						test_data_val_lsb) < 0)
+				return rc;
+		}
+
+	}
+
+	return rc;
+}
+
+static int32_t sn12m0pz_reset(void)
+{
+	int32_t rc = 0;
+	/* register 0x0002 is Port 2, CAM_XCLRO */
+	gpio_direction_output(sn12m0pz_ctrl->
+		sensordata->sensor_reset,
+		0);
+	msleep(50);
+	gpio_direction_output(sn12m0pz_ctrl->
+		sensordata->sensor_reset,
+		1);
+	msleep(13);
+	return rc;
+}
+
+static int32_t sn12m0pz_sensor_setting(int update_type, int rt)
+{
+	uint16_t total_lines_per_frame;
+	int32_t rc = 0;
+
+	switch (update_type) {
+	case UPDATE_PERIODIC:
+		/* Put Sensor into sofware standby mode	*/
+		if (sn12m0pz_i2c_write_b_sensor(REG_MODE_SELECT,
+				MODE_SELECT_STANDBY_MODE) <  0)
+			return rc;
+		msleep(5);
+		/* Hardware reset D02, lane config between full size/qtr size*/
+		rc = sn12m0pz_reset();
+		if (rc < 0)
+			return rc;
+
+		if (sn12m0pz_stmipid02_config() < 0)
+			return rc;
+	case REG_INIT:
+		if (rt == RES_PREVIEW || rt == RES_CAPTURE
+				|| rt == RES_VIDEO_120FPS) {
+			/* reset fps_divider */
+			sn12m0pz_ctrl->fps_divider = 1 * 0x400;
+
+			/* PLL settings */
+			if (sn12m0pz_i2c_write_b_sensor(REG_PLL_MULTIPLIER,
+			sn12m0pz_regs.reg_pat[rt].pll_multiplier_lsb) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x302B,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x302B) < 0)
+				return rc;
+
+			/* MIPI Enable Settings */
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x30E5,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x30E5) < 0)
+				return rc;
+
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3300,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3300) < 0)
+				return rc;
+
+			/* Global Setting */
+			if (
+				sn12m0pz_i2c_write_b_sensor(
+				REG_IMAGE_ORIENTATION,
+				sn12m0pz_regs.reg_pat_init[0].image_orient) < 0)
+				return rc;
+			if (
+				sn12m0pz_i2c_write_b_sensor(
+				REG_COARSE_INTEGRATION_TIME_MSB,
+				sn12m0pz_regs.reg_pat[rt].coarse_integ_time_msb)
+				< 0)
+				return rc;
+			if (
+				sn12m0pz_i2c_write_b_sensor(
+				REG_COARSE_INTEGRATION_TIME_LSB,
+				sn12m0pz_regs.reg_pat[rt].coarse_integ_time_lsb)
+				 < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x300A,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x300A) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3014,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3014) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3015,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3015) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3017,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3017) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x301C,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x301C) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3031,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3031) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3040,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3040) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3041,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3041) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3051,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3051) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3053,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3053) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3055,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3055) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3057,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3057) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3060,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3060) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3065,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3065) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x30AA,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x30AA) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x30AB,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x30AB) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x30B0,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x30B0) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x30B2,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x30B2) < 0)
+				return rc;
+
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x30D3,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x30D3) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x30D8,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x30D8) < 0)
+				return rc;
+
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3106,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3106) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3108,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3108) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x310A,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x310A) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x310C,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x310C) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x310E,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x310E) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3126,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3126) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x312E,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x312E) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x313C,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x313C) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x313E,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x313E) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3140,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3140) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3142,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3142) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3144,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3144) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3148,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3148) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x314A,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x314A) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3166,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3166) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3168,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3168) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x316F,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x316F) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3171,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3171) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3173,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3173) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3175,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3175) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3177,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3177) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3179,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3179) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x317B,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x317B) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x317D,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x317D) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x317F,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x317F) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3181,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3181) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3184,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3184) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3185,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3185) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3187,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3187) < 0)
+				return rc;
+
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x31A4,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x31A4) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x31A6,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x31A6) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x31AC,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x31AC) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x31AE,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x31AE) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x31B4,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x31B4) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x31B6,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x31B6) < 0)
+				return rc;
+
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3254,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3254) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3256,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3256) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3258,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3258) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x325A,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x325A) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3260,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3260) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3262,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3262) < 0)
+				return rc;
+
+
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3304,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3304) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3305,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3305) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3306,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3306) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3307,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3307) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3308,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3308) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3309,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x3309) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x330A,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x330A) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x330B,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x330B) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x330C,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x330C) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x330D,
+				sn12m0pz_regs.reg_pat_init[0].reg_0x330D) < 0)
+				return rc;
+
+			/* Mode setting */
+			/* Update registers with correct
+				 frame_length_line value for AFR */
+			total_lines_per_frame = (uint16_t)(
+			(sn12m0pz_regs.reg_pat[rt].frame_length_lines_msb << 8)
+			& 0xFF00) +
+			sn12m0pz_regs.reg_pat[rt].frame_length_lines_lsb;
+			total_lines_per_frame = total_lines_per_frame *
+					sn12m0pz_ctrl->fps_divider / 0x400;
+
+			if (sn12m0pz_i2c_write_b_sensor(
+					REG_FRAME_LENGTH_LINES_MSB,
+					(total_lines_per_frame & 0xFF00) >> 8)
+					< 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(
+					REG_FRAME_LENGTH_LINES_LSB,
+					(total_lines_per_frame & 0x00FF)) < 0)
+				return rc;
+
+			if (sn12m0pz_i2c_write_b_sensor(REG_LINE_LENGTH_PCK_MSB,
+				sn12m0pz_regs.reg_pat[rt].line_length_pck_msb) <
+				0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_LINE_LENGTH_PCK_LSB,
+				sn12m0pz_regs.reg_pat[rt].line_length_pck_lsb) <
+				0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_X_OUTPUT_SIZE_MSB,
+				sn12m0pz_regs.reg_pat[rt].x_output_size_msb) <
+				0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_X_OUTPUT_SIZE_LSB,
+				sn12m0pz_regs.reg_pat[rt].x_output_size_lsb) <
+				0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_Y_OUTPUT_SIZE_MSB,
+				sn12m0pz_regs.reg_pat[rt].y_output_size_msb) <
+				0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_Y_OUTPUT_SIZE_LSB,
+				sn12m0pz_regs.reg_pat[rt].y_output_size_lsb) <
+				0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_X_EVEN_INC_LSB,
+				sn12m0pz_regs.reg_pat[rt].x_even_inc_lsb) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_X_ODD_INC_LSB,
+				sn12m0pz_regs.reg_pat[rt].x_odd_inc_lsb) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_Y_EVEN_INC_LSB,
+				sn12m0pz_regs.reg_pat[rt].y_even_inc_lsb) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_Y_ODD_INC_LSB,
+				sn12m0pz_regs.reg_pat[rt].y_odd_inc_lsb) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3016,
+				sn12m0pz_regs.reg_pat[rt].reg_0x3016) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x30E8,
+				sn12m0pz_regs.reg_pat[rt].reg_0x30E8) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x3301,
+				sn12m0pz_regs.reg_pat[rt].reg_0x3301) < 0)
+				return rc;
+
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x0344,
+				sn12m0pz_regs.reg_pat[rt].reg_0x0344) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x0345,
+				sn12m0pz_regs.reg_pat[rt].reg_0x0345) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x0346,
+				sn12m0pz_regs.reg_pat[rt].reg_0x0346) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x0347,
+				sn12m0pz_regs.reg_pat[rt].reg_0x0347) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x0348,
+				sn12m0pz_regs.reg_pat[rt].reg_0x0348) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x0349,
+				sn12m0pz_regs.reg_pat[rt].reg_0x0349) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x034A,
+				sn12m0pz_regs.reg_pat[rt].reg_0x034A) < 0)
+				return rc;
+			if (sn12m0pz_i2c_write_b_sensor(REG_0x034B,
+				sn12m0pz_regs.reg_pat[rt].reg_0x034B) < 0)
+				return rc;
+
+			if ((rt == RES_CAPTURE) && fullsize_cropped_at_8mp) {
+				/* x address end */
+				if (sn12m0pz_i2c_write_b_sensor(0x0348,
+								0x0C) < 0)
+					return rc;
+				if (sn12m0pz_i2c_write_b_sensor(0x0349,
+								0x0CF) < 0)
+					return rc;
+				/* y address end */
+				if (sn12m0pz_i2c_write_b_sensor(0x034A,
+								0x09) < 0)
+					return rc;
+				if (sn12m0pz_i2c_write_b_sensor(0x034B,
+								0x9F) < 0)
+					return rc;
+			}
+
+			if (mipi_config == IU060F_SN12M0PZ_STMIPID01) {
+				if (sn12m0pz_i2c_write_b_sensor(
+						REG_PLL_MULTIPLIER, 0x43) < 0)
+					return rc;
+				if (rt == RES_CAPTURE) {
+					if (sn12m0pz_i2c_write_b_sensor(
+						REG_0x3301, 0x01) < 0)
+						return rc;
+				if (sn12m0pz_i2c_write_b_sensor(
+						REG_0x3017, 0xE0) < 0)
+					return rc;
+				}
+			}
+
+			if (sn12m0pz_i2c_write_b_sensor(REG_MODE_SELECT,
+						MODE_SELECT_STREAM) < 0)
+				return rc;
+
+			msleep(IU060F_SN12M0PZ_DELAY_MSECS);
+
+			if (sn12m0pz_test(sn12m0pz_ctrl->set_test) < 0)
+				return rc;
+
+			if (mipi_config == IU060F_SN12M0PZ_STMIPID02)
+				CDBG("%s,%d", __func__, __LINE__);
+			return rc;
+		}
+	default:
+		return rc;
+		}
+}
+
+
+static int32_t sn12m0pz_video_config(int mode)
+{
+
+	int32_t rc = 0;
+	int rt;
+
+
+	if (mode == SENSOR_HFR_120FPS_MODE)
+		sn12m0pz_ctrl->prev_res = QVGA_SIZE;
+
+	/* change sensor resolution if needed */
+	if (sn12m0pz_ctrl->curr_res != sn12m0pz_ctrl->prev_res) {
+		if (sn12m0pz_ctrl->prev_res == QTR_SIZE) {
+			rt = RES_PREVIEW;
+			IU060F_SN12M0PZ_DELAY_MSECS = 35; /*measured on scope*/
+			enable_single_D02_lane = 1;
+		} else if (sn12m0pz_ctrl->prev_res == QVGA_SIZE) {
+			rt = RES_VIDEO_120FPS;
+			IU060F_SN12M0PZ_DELAY_MSECS = 35; /*measured on scope*/
+			enable_single_D02_lane = 0;
+		} else {
+			rt = RES_CAPTURE;
+			enable_single_D02_lane = 0;
+		}
+
+		if (sn12m0pz_sensor_setting(UPDATE_PERIODIC, rt) < 0)
+			return rc;
+	}
+
+	sn12m0pz_ctrl->curr_res = sn12m0pz_ctrl->prev_res;
+	sn12m0pz_ctrl->sensormode = mode;
+
+	return rc;
+}
+static int32_t sn12m0pz_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+	int rt;
+	/* change sensor resolution if needed */
+	if (sn12m0pz_ctrl->curr_res != sn12m0pz_ctrl->pict_res) {
+		if (sn12m0pz_ctrl->pict_res == QTR_SIZE) {
+			rt = RES_PREVIEW;
+			enable_single_D02_lane = 1;
+		} else {
+			rt = RES_CAPTURE;
+			IU060F_SN12M0PZ_DELAY_MSECS = 100;/*measured on scope*/
+			enable_single_D02_lane = 0;
+		}
+
+		if (sn12m0pz_sensor_setting(UPDATE_PERIODIC, rt) < 0)
+			return rc;
+	}
+
+	sn12m0pz_ctrl->curr_res = sn12m0pz_ctrl->pict_res;
+	sn12m0pz_ctrl->sensormode = mode;
+	return rc;
+}
+
+static int32_t sn12m0pz_raw_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+	int rt;
+	/* change sensor resolution if needed */
+	if (sn12m0pz_ctrl->curr_res != sn12m0pz_ctrl->pict_res) {
+		if (sn12m0pz_ctrl->pict_res == QTR_SIZE) {
+			rt = RES_PREVIEW;
+			enable_single_D02_lane = 1;
+		} else {
+			rt = RES_CAPTURE;
+			IU060F_SN12M0PZ_DELAY_MSECS = 100;/*measured on scope*/
+			enable_single_D02_lane = 0;
+		}
+		if (sn12m0pz_sensor_setting(UPDATE_PERIODIC, rt) < 0)
+			return rc;
+		}
+	sn12m0pz_ctrl->curr_res = sn12m0pz_ctrl->pict_res;
+	sn12m0pz_ctrl->sensormode = mode;
+	return rc;
+}
+static int32_t sn12m0pz_set_sensor_mode(int  mode,
+	int  res)
+{
+	int32_t rc;
+
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+	case SENSOR_HFR_120FPS_MODE:
+		rc = sn12m0pz_video_config(mode);
+		break;
+
+	case SENSOR_SNAPSHOT_MODE:
+		rc = sn12m0pz_snapshot_config(mode);
+		break;
+
+	case SENSOR_RAW_SNAPSHOT_MODE:
+		rc = sn12m0pz_raw_snapshot_config(mode);
+		break;
+
+	default:
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
+static int32_t sn12m0pz_power_down(void)
+{
+	return 0;
+}
+
+
+static int sn12m0pz_probe_init_done(const struct msm_camera_sensor_info *data)
+{
+
+	gpio_direction_output(data->sensor_reset, 0);
+	gpio_free(data->sensor_reset);
+	gpio_direction_output(data->vcm_pwd, 0);
+	gpio_free(data->vcm_pwd);
+	return 0;
+}
+
+static int sn12m0pz_probe_init_sensor(const struct msm_camera_sensor_info *data)
+{
+	int32_t rc;
+	unsigned short chipidl, chipidh;
+	CDBG("Requesting gpio");
+	rc = gpio_request(data->sensor_reset, "sn12m0pz");
+	CDBG(" sn12m0pz_probe_init_sensor");
+	if (!rc) {
+		gpio_direction_output(data->sensor_reset, 0);
+		msleep(20);
+		gpio_direction_output(data->sensor_reset, 1);
+		msleep(13);
+	} else {
+		goto init_probe_done;
+	}
+	CDBG("Requestion gpio");
+	rc = gpio_request(data->vcm_pwd, "sn12m0pz");
+	CDBG(" sn12m0pz_probe_init_sensor");
+
+	if (!rc) {
+		gpio_direction_output(data->vcm_pwd, 0);
+		msleep(20);
+		gpio_direction_output(data->vcm_pwd, 1);
+		msleep(13);
+	} else {
+		gpio_direction_output(data->sensor_reset, 0);
+		gpio_free(data->sensor_reset);
+		goto init_probe_done;
+	}
+
+	msleep(20);
+
+	/* 3. Read sensor Model ID: */
+	rc = sn12m0pz_i2c_read(0x0000, &chipidh, 1);
+	if (rc < 0) {
+		CDBG(" sn12m0pz_probe_init_sensor3");
+		goto init_probe_fail;
+	}
+	rc = sn12m0pz_i2c_read(0x0001, &chipidl, 1);
+	if (rc < 0) {
+		CDBG(" sn12m0pz_probe_init_sensor4");
+		goto init_probe_fail;
+	}
+
+	/* 4. Compare sensor ID to SN12M0PZ ID: */
+	if (chipidh != 0x00 || chipidl != 0x60) {
+		rc = -ENODEV;
+		CDBG("sn12m0pz_probe_init_sensor fail chip id doesnot match");
+		goto init_probe_fail;
+	}
+
+	msleep(SN12M0PZ_RESET_DELAY_MSECS);
+
+	goto init_probe_done;
+
+init_probe_fail:
+	CDBG(" sn12m0pz_probe_init_sensor fails");
+	sn12m0pz_probe_init_done(data);
+
+init_probe_done:
+	CDBG(" sn12m0pz_probe_init_sensor finishes");
+	return rc;
+}
+
+int sn12m0pz_sensor_open_init(const struct msm_camera_sensor_info *data)
+{
+	int32_t rc = 0;
+	CDBG("Calling sn12m0pz_sensor_open_init");
+
+	sn12m0pz_ctrl = kzalloc(sizeof(struct sn12m0pz_ctrl_t), GFP_KERNEL);
+	if (!sn12m0pz_ctrl) {
+		CDBG("sn12m0pz_init failed!");
+		rc = -ENOMEM;
+		goto init_done;
+	}
+
+	sn12m0pz_ctrl->fps_divider      = 1 * 0x00000400;
+	sn12m0pz_ctrl->pict_fps_divider = 1 * 0x00000400;
+	sn12m0pz_ctrl->set_test = TEST_OFF;
+	sn12m0pz_ctrl->prev_res = QTR_SIZE;
+	sn12m0pz_ctrl->pict_res = FULL_SIZE;
+	sn12m0pz_ctrl->curr_res = INVALID_SIZE;
+	if (data)
+		sn12m0pz_ctrl->sensordata = data;
+
+	if (rc < 0)
+		return rc;
+
+	/* enable mclk first */
+	msm_camio_clk_rate_set(SN12M0PZ_DEFAULT_CLOCK_RATE);
+	msleep(20);
+	msm_camio_camif_pad_reg_reset();
+	msleep(20);
+	CDBG("Calling sn12m0pz_sensor_open_init");
+	rc = sn12m0pz_probe_init_sensor(data);
+
+	if (rc < 0)
+		goto init_fail;
+	/* send reset signal */
+	if (mipi_config == IU060F_SN12M0PZ_STMIPID01) {
+		if (sn12m0pz_stmipid01_config() < 0) {
+			CDBG("Calling sn12m0pz_sensor_open_init fail");
+			return rc;
+		}
+	} else {
+		if (sn12m0pz_ctrl->prev_res  == QTR_SIZE)
+			enable_single_D02_lane = 1;
+		else /* FULL_SIZE */
+			enable_single_D02_lane = 0;
+
+		if (sn12m0pz_stmipid02_config() < 0) {
+			CDBG("Calling sn12m0pz_sensor_open_init fail");
+			return rc;
+		}
+	}
+
+
+	if (sn12m0pz_ctrl->prev_res == QTR_SIZE) {
+		if (sn12m0pz_sensor_setting(REG_INIT, RES_PREVIEW) < 0)
+			return rc;
+	} else if (sn12m0pz_ctrl->prev_res == QVGA_SIZE) {
+		if (sn12m0pz_sensor_setting(REG_INIT, RES_VIDEO_120FPS) < 0)
+			return rc;
+	} else {
+		if (sn12m0pz_sensor_setting(REG_INIT, RES_CAPTURE) < 0)
+			return rc;
+	}
+
+	if (sn12m0pz_af_init() < 0)
+		return rc;
+	sn12m0pz_ctrl->fps = 30*Q8;
+	if (rc < 0)
+		goto init_fail;
+	else
+		goto init_done;
+init_fail:
+	CDBG(" init_fail");
+	sn12m0pz_probe_init_done(data);
+	kfree(sn12m0pz_ctrl);
+init_done:
+	CDBG("init_done");
+	return rc;
+}
+static int __devinit sn12m0pz_init_client(struct i2c_client *client)
+{
+	/* Initialize the MSM_CAMI2C Chip */
+	init_waitqueue_head(&sn12m0pz_wait_queue);
+	return 0;
+}
+
+static const struct i2c_device_id sn12m0pz_i2c_id[] = {
+	{ "sn12m0pz", 0},
+	{ }
+};
+
+static int __devinit sn12m0pz_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+	CDBG("sn12m0pz_probe called!");
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		CDBG("i2c_check_functionality failed");
+		goto probe_failure;
+	}
+
+	sn12m0pz_sensorw = kzalloc(sizeof(struct sn12m0pz_work_t), GFP_KERNEL);
+	if (!sn12m0pz_sensorw) {
+		CDBG("kzalloc failed");
+		rc = -ENOMEM;
+		goto probe_failure;
+	}
+
+	i2c_set_clientdata(client, sn12m0pz_sensorw);
+	sn12m0pz_init_client(client);
+	sn12m0pz_client = client;
+
+	msleep(50);
+
+	CDBG("sn12m0pz_probe successed! rc = %d", rc);
+	return 0;
+
+probe_failure:
+	CDBG("sn12m0pz_probe failed! rc = %d", rc);
+	return rc;
+}
+
+static int __exit sn12m0pz_remove(struct i2c_client *client)
+{
+	struct sn12m0pz_work_t_t *sensorw = i2c_get_clientdata(client);
+	free_irq(client->irq, sensorw);
+	sn12m0pz_client = NULL;
+	kfree(sensorw);
+	return 0;
+}
+
+static struct i2c_driver sn12m0pz_i2c_driver = {
+	.id_table = sn12m0pz_i2c_id,
+	.probe	= sn12m0pz_i2c_probe,
+	.remove = __exit_p(sn12m0pz_i2c_remove),
+	.driver = {
+		.name = "sn12m0pz",
+	},
+};
+
+int sn12m0pz_sensor_config(void __user *argp)
+{
+	struct sensor_cfg_data cdata;
+	int32_t rc = 0;
+	if (copy_from_user(&cdata,
+				(void *)argp,
+				sizeof(struct sensor_cfg_data)))
+		return -EFAULT;
+
+	mutex_lock(&sn12m0pz_mut);
+
+	CDBG("sn12m0pz_sensor_config: cfgtype = %d",
+		cdata.cfgtype);
+	switch (cdata.cfgtype) {
+	case CFG_GET_PICT_FPS:
+		sn12m0pz_get_pict_fps(cdata.cfg.gfps.prevfps,
+					&(cdata.cfg.gfps.pictfps));
+
+		if (copy_to_user((void *)argp,
+			&cdata,
+			sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PREV_L_PF:
+		cdata.cfg.prevl_pf =
+			sn12m0pz_get_prev_lines_pf();
+
+		if (copy_to_user((void *)argp,
+			&cdata,
+			sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PREV_P_PL:
+		cdata.cfg.prevp_pl =
+			sn12m0pz_get_prev_pixels_pl();
+
+		if (copy_to_user((void *)argp,
+			&cdata,
+			sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_L_PF:
+		cdata.cfg.pictl_pf =
+			sn12m0pz_get_pict_lines_pf();
+
+		if (copy_to_user((void *)argp,
+			&cdata,
+			sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_P_PL:
+		cdata.cfg.pictp_pl =
+			sn12m0pz_get_pict_pixels_pl();
+
+		if (copy_to_user((void *)argp,
+			&cdata,
+			sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_MAX_EXP_LC:
+		cdata.cfg.pict_max_exp_lc =
+			sn12m0pz_get_pict_max_exp_lc();
+
+		if (copy_to_user((void *)argp,
+			&cdata,
+			sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_SET_FPS:
+	case CFG_SET_PICT_FPS:
+		rc = sn12m0pz_set_fps(&(cdata.cfg.fps));
+		break;
+
+	case CFG_SET_EXP_GAIN:
+		rc =
+			sn12m0pz_write_exp_gain(
+				cdata.cfg.exp_gain.gain,
+				cdata.cfg.exp_gain.line);
+		break;
+	case CFG_SET_PICT_EXP_GAIN:
+		rc =
+			sn12m0pz_set_pict_exp_gain(
+				cdata.cfg.exp_gain.gain,
+				cdata.cfg.exp_gain.line);
+		break;
+
+	case CFG_SET_MODE:
+		rc = sn12m0pz_set_sensor_mode(cdata.mode,
+					cdata.rs);
+		break;
+
+	case CFG_PWR_DOWN:
+		rc = sn12m0pz_power_down();
+		break;
+
+	case CFG_MOVE_FOCUS:
+		rc = sn12m0pz_move_focus(cdata.cfg.focus.dir,
+					cdata.cfg.focus.steps);
+		break;
+
+	case CFG_SET_DEFAULT_FOCUS:
+		rc = sn12m0pz_set_default_focus(cdata.cfg.focus.steps);
+		break;
+
+	case CFG_SET_EFFECT:
+		rc = 0;
+		break;
+	case CFG_SET_LENS_SHADING:
+		rc = 0;
+		break;
+	default:
+		rc = -EFAULT;
+		break;
+	}
+
+	mutex_unlock(&sn12m0pz_mut);
+
+	return rc;
+}
+
+static int sn12m0pz_sensor_release(void)
+{
+	int rc = -EBADF;
+
+	mutex_lock(&sn12m0pz_mut);
+
+	sn12m0pz_power_down();
+
+	gpio_direction_output(sn12m0pz_ctrl->sensordata->sensor_reset,
+		0);
+	gpio_free(sn12m0pz_ctrl->sensordata->sensor_reset);
+
+	gpio_direction_output(sn12m0pz_ctrl->sensordata->vcm_pwd,
+		0);
+	gpio_free(sn12m0pz_ctrl->sensordata->vcm_pwd);
+
+	kfree(sn12m0pz_ctrl);
+	sn12m0pz_ctrl = NULL;
+
+	CDBG("sn12m0pz_release completed");
+
+
+	mutex_unlock(&sn12m0pz_mut);
+
+	return rc;
+}
+
+static int sn12m0pz_sensor_probe(const struct msm_camera_sensor_info *info,
+		struct msm_sensor_ctrl *s)
+{
+	int rc;
+
+	rc = i2c_add_driver(&sn12m0pz_i2c_driver);
+	if (rc < 0 || sn12m0pz_client == NULL) {
+		rc = -ENOTSUPP;
+		goto probe_fail;
+	}
+
+	msm_camio_clk_rate_set(SN12M0PZ_DEFAULT_CLOCK_RATE);
+	msleep(20);
+
+	rc = sn12m0pz_probe_init_sensor(info);
+	if (rc < 0)
+		goto probe_fail;
+
+	s->s_init = sn12m0pz_sensor_open_init;
+	s->s_release = sn12m0pz_sensor_release;
+	s->s_config  = sn12m0pz_sensor_config;
+	s->s_mount_angle  = 0;
+	sn12m0pz_probe_init_done(info);
+
+	return rc;
+
+probe_fail:
+	CDBG("SENSOR PROBE FAILS!");
+	i2c_del_driver(&sn12m0pz_i2c_driver);
+	return rc;
+}
+
+static int __sn12m0pz_probe(struct platform_device *pdev)
+{
+	return msm_camera_drv_start(pdev, sn12m0pz_sensor_probe);
+}
+
+static struct platform_driver msm_camera_driver = {
+	.probe = __sn12m0pz_probe,
+	.driver = {
+		.name = "msm_camera_sn12m0pz",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init sn12m0pz_init(void)
+{
+	return platform_driver_register(&msm_camera_driver);
+}
+
+module_init(sn12m0pz_init);
+
+MODULE_DESCRIPTION("Sony 12M MP Bayer sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/sn12m0pz.h b/drivers/media/platform/msm/camera_v1/sn12m0pz.h
new file mode 100644
index 0000000..c3d3346
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/sn12m0pz.h
@@ -0,0 +1,138 @@
+
+/* 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.
+ *
+ */
+#ifndef SN12M0PZ_H
+#define SN12M0PZ_H
+
+#include <linux/types.h>
+extern struct sn12m0pz_reg sn12m0pz_regs; /* from mt9t013_reg.c */
+struct reg_struct{
+	uint8_t pll_multiplier_lsb;            /* 0x0307*/
+	uint8_t coarse_integ_time_msb;   /* 0x0202*/
+	uint8_t coarse_integ_time_lsb;   /* 0x0203*/
+	uint8_t frame_length_lines_msb;        /* 0x0340*/
+	uint8_t frame_length_lines_lsb;        /* 0x0341*/
+	uint8_t line_length_pck_msb;           /* 0x0342*/
+	uint8_t line_length_pck_lsb;           /* 0x0343*/
+	uint8_t x_output_size_msb;             /* 0x034C*/
+	uint8_t x_output_size_lsb;             /* 0x034D*/
+	uint8_t y_output_size_msb;             /* 0x034E*/
+	uint8_t y_output_size_lsb;             /* 0x034F*/
+	uint8_t x_even_inc_lsb;                /* 0x0381*/
+	uint8_t x_odd_inc_lsb;                 /* 0x0383*/
+	uint8_t y_even_inc_lsb;                /* 0x0385*/
+	uint8_t y_odd_inc_lsb;                 /* 0x0387*/
+	uint8_t reg_0x3016;                    /* 0x3016 VMODEADD*/
+	uint8_t reg_0x30E8;                    /* 0x30E8 HADDAVE*/
+	uint8_t reg_0x3301;                    /* 0x3301 RGLANESEL*/
+	/*added for 120fps support */
+	uint8_t reg_0x0344;
+	uint8_t reg_0x0345;
+	uint8_t reg_0x0346;
+	uint8_t reg_0x0347;
+	uint8_t reg_0x0348;
+	uint8_t reg_0x0349;
+	uint8_t reg_0x034A;
+	uint8_t reg_0x034B;
+};
+struct reg_struct_init{
+	uint8_t reg_0x302B;/* 0x302B*/
+
+	uint8_t reg_0x30E5;/* 0x30E5*/
+	uint8_t reg_0x3300;   /* 0x3300*/
+
+	uint8_t image_orient;   /* 0x0101*/
+
+	uint8_t reg_0x300A;   /* 0x300A*/
+	uint8_t reg_0x3014;   /* 0x3014*/
+	uint8_t reg_0x3015;   /* 0x3015*/
+	uint8_t reg_0x3017;   /* 0x3017*/
+	uint8_t reg_0x301C;   /* 0x301C*/
+	uint8_t reg_0x3031;   /* 0x3031*/
+	uint8_t reg_0x3040;   /* 0x3040*/
+	uint8_t reg_0x3041;   /* 0x3041*/
+	uint8_t reg_0x3051;   /* 0x3051*/
+	uint8_t reg_0x3053;   /* 0x3053*/
+	uint8_t reg_0x3055;   /* 0x3055*/
+	uint8_t reg_0x3057;   /* 0x3057*/
+	uint8_t reg_0x3060;   /* 0x3060*/
+	uint8_t reg_0x3065;   /* 0x3065*/
+	uint8_t reg_0x30AA;   /* 0x30AA*/
+	uint8_t reg_0x30AB;   /* 0x30AB*/
+	uint8_t reg_0x30B0;   /* 0x30B0*/
+	uint8_t reg_0x30B2;   /* 0x30B2*/
+
+	uint8_t reg_0x30D3;   /* 0X30D3*/
+	uint8_t reg_0x30D8;   /* 0X30D8*/
+
+	uint8_t reg_0x3106;   /* 0x3106*/
+	uint8_t reg_0x3108;   /* 0x3108*/
+	uint8_t reg_0x310A;   /* 0x310A*/
+	uint8_t reg_0x310C;   /* 0x310C*/
+	uint8_t reg_0x310E;   /* 0x310E*/
+	uint8_t reg_0x3126;   /* 0x3126*/
+	uint8_t reg_0x312E;   /* 0x312E*/
+	uint8_t reg_0x313C;   /* 0x313C*/
+	uint8_t reg_0x313E;   /* 0x313E*/
+	uint8_t reg_0x3140;   /* 0x3140*/
+	uint8_t reg_0x3142;   /* 0x3142*/
+	uint8_t reg_0x3144;   /* 0x3144*/
+	uint8_t reg_0x3148;   /* 0x3148*/
+	uint8_t reg_0x314A;   /* 0x314A*/
+	uint8_t reg_0x3166;   /* 0x3166*/
+	uint8_t reg_0x3168;   /* 0x3168*/
+	uint8_t reg_0x316F;   /* 0x316F*/
+	uint8_t reg_0x3171;   /* 0x3171*/
+	uint8_t reg_0x3173;   /* 0x3173*/
+	uint8_t reg_0x3175;   /* 0x3175*/
+	uint8_t reg_0x3177;   /* 0x3177*/
+	uint8_t reg_0x3179;   /* 0x3179*/
+	uint8_t reg_0x317B;   /* 0x317B*/
+	uint8_t reg_0x317D;   /* 0x317D*/
+	uint8_t reg_0x317F;   /* 0x317F*/
+	uint8_t reg_0x3181;   /* 0x3181*/
+	uint8_t reg_0x3184;   /* 0x3184*/
+	uint8_t reg_0x3185;   /* 0x3185*/
+	uint8_t reg_0x3187;   /* 0x3187*/
+
+	uint8_t reg_0x31A4;   /* 0x31A4*/
+	uint8_t reg_0x31A6;   /* 0x31A6*/
+	uint8_t reg_0x31AC;   /* 0x31AC*/
+	uint8_t reg_0x31AE;   /* 0x31AE*/
+	uint8_t reg_0x31B4;   /* 0x31B4*/
+	uint8_t reg_0x31B6;   /* 0x31B6*/
+
+	uint8_t reg_0x3254;   /* 0x3254*/
+	uint8_t reg_0x3256;   /* 0x3256*/
+	uint8_t reg_0x3258;   /* 0x3258*/
+	uint8_t reg_0x325A;   /* 0x325A*/
+	uint8_t reg_0x3260;   /* 0x3260*/
+	uint8_t reg_0x3262;   /* 0x3262*/
+
+	uint8_t reg_0x3304;   /* 0x3304*/
+	uint8_t reg_0x3305;   /* 0x3305*/
+	uint8_t reg_0x3306;   /* 0x3306*/
+	uint8_t reg_0x3307;   /* 0x3307*/
+	uint8_t reg_0x3308;   /* 0x3308*/
+	uint8_t reg_0x3309;   /* 0x3309*/
+	uint8_t reg_0x330A;   /* 0x330A*/
+	uint8_t reg_0x330B;   /* 0x330B*/
+	uint8_t reg_0x330C;   /* 0x330C*/
+	uint8_t reg_0x330D;   /* 0x330D*/
+
+};
+struct sn12m0pz_reg{
+	const struct reg_struct  *reg_pat;
+	const struct reg_struct_init  *reg_pat_init;
+};
+#endif
diff --git a/drivers/media/platform/msm/camera_v1/sn12m0pz_reg.c b/drivers/media/platform/msm/camera_v1/sn12m0pz_reg.c
new file mode 100644
index 0000000..c406d98
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/sn12m0pz_reg.c
@@ -0,0 +1,213 @@
+/* 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 "sn12m0pz.h"
+/* Initialisation settings */
+
+const struct reg_struct_init iu060f_reg_pat_init[1] = {{
+	/* PLL setting */
+	0x4B, /* reg 0x302B*/
+	/* MIPI Enable Setting */
+	0x04, /* reg 0x30E5*/
+	0x00, /* reg 0x3300*/
+	/* Global Setting */
+	0x00, /* image_orientation*/
+	0x80, /* reg 0x300A*/
+	0x08, /* reg 0x3014*/
+	0x37, /* reg 0x3015*/
+	0x60, /* reg 0x3017*/
+	0x01, /* reg 0x301C*/
+	0x28, /* reg 0x3031*/
+	0x00, /* reg 0x3040*/
+	0x60, /* reg 0x3041*/
+	0x24, /* reg 0x3051*/
+	0x34, /* reg 0x3053*/
+	0x3B, /* reg 0x3055*/
+	0xC0, /* reg 0x3057*/
+	0x30, /* reg 0x3060*/
+	0x00, /* reg 0x3065*/
+	0x88, /* reg 0x30AA*/
+	0x1C, /* reg 0x30AB*/
+	0x32, /* reg 0x30B0*/
+	0x83, /* reg 0x30B2*/
+	0x04, /* reg 0x30D3*/
+	0xC0, /* reg 0x30D8*/
+	0x50, /* reg 0x3106*/
+	0xA5, /* reg 0x3108*/
+	0xA9, /* reg 0x310A*/
+	0x0C, /* reg 0x310C*/
+	0x55, /* reg 0x310E*/
+	0xCC, /* reg 0x3126*/
+	0x83, /* reg 0x312E*/
+	0xC7, /* reg 0x313C*/
+	0x07, /* reg 0x313E*/
+	0x32, /* reg 0x3140*/
+	0x35, /* reg 0x3142*/
+	0x35, /* reg 0x3144*/
+	0x73, /* reg 0x3148*/
+	0x80, /* reg 0x314A*/
+	0xBE, /* reg 0x3166*/
+	0xBD, /* reg 0x3168*/
+	0x82, /* reg 0x316F*/
+	0xBC, /* reg 0x3171*/
+	0x82, /* reg 0x3173*/
+	0xBC, /* reg 0x3175*/
+	0x0C, /* reg 0x3177*/
+	0x2C, /* reg 0x3179*/
+	0x83, /* reg 0x317B*/
+	0xAF, /* reg 0x317D*/
+	0x83, /* reg 0x317F*/
+	0xAF, /* reg 0x3181*/
+	0x06, /* reg 0x3184*/
+	0xBA, /* reg 0x3185*/
+	0xBE, /* reg 0x3187*/
+	0xD8, /* reg 0x31A4*/
+	0x17, /* reg 0x31A6*/
+	0xCF, /* reg 0x31AC*/
+	0xF1, /* reg 0x31AE*/
+	0xD8, /* reg 0x31B4*/
+	0x17, /* reg 0x31B6*/
+	0x09, /* reg 0x3254 */
+	0xC5, /* reg 0x3256 */
+	0x84, /* reg 0x3258 */
+	0x6C, /* reg 0x325A */
+	0x0B, /* reg 0x3260 */
+	0x09, /* reg 0x3262 */
+	0x05, /* reg 0x3304*/
+	0x04, /* reg 0x3305*/
+	0x15, /* reg 0x3306*/
+	0x03, /* reg 0x3307*/
+	0x13, /* reg 0x3308*/
+	0x05, /* reg 0x3309*/
+	0x0B, /* reg 0x330A*/
+	0x04, /* reg 0x330B*/
+	0x0B, /* reg 0x330C*/
+	0x06  /* reg 0x330D*/
+}
+};
+
+/* Preview / Snapshot register settings */
+const struct reg_struct iu060f_reg_pat[3] = {
+	{ /* Preview */
+		0x22, /*0x1b*/ /* fps*/
+
+		/* Global Setting */
+		0x01, /* coarse_integration_time_msb*/
+		0xFF, /* coarse_integration_time_lsb*/
+
+		/* Mode Setting */
+		/* V: 1/2 V-addition (1,3),
+		H: 1/2 H-averaging (1,3) */
+
+		0x06, /* frame_length_lines_msb     0x0340*/
+		0x02, /* frame_length_lines_lsb     0x0341*/
+		0x10, /* line_length_pck_msb        0x0342*/
+		0x70, /* line_length_pck_lsb        0x0343*/
+		0x07, /* x_output_size_msb          0x034C*/
+		0xe0, /* x_output_size_lsb          0x034D*/
+		0x05, /* y_output_size_msb          0x034E*/
+		0xe8, /* y_output_size_lsb          0x034F*/
+		0x01, /* x_even_inc_lsb             0x0381*/
+		0x03, /* x_odd_inc_lsb              0x0383*/
+		0x01, /* y_even_inc_lsb             0x0385*/
+		0x03, /* y_odd_inc_lsb              0x0387*/
+		0x46, /* reg 0x3016 VMODEADD        0x3016*/
+		0x86, /* reg 0x30E8 HADDAVE         0x30E8*/
+		0x01, /* reg 0x3301 RGLANESEL       0x3301*/
+
+		0x00,  /* 0x0344 */
+		0x00,  /* 0x0345 */
+		0x00,  /* 0x0346 */
+		0x00,  /* 0x0347 */
+		0x0F,  /* 0x0348 */
+		0xBF,  /* 0x0349 */
+		0x0B,  /* 0x034A */
+		0xCF,  /* 0x034B */
+	},
+	{ /* Snapshot */
+		0x14, /* pll_multiplier_lsb    // 20/10 fps*/
+		/* 0x14 for pclk 96MHz at 7.5 fps */
+
+		/* Global Setting */
+		0x0B, /* coarse_integration_time_msb*/
+		0xFF, /* coarse_integration_time_lsb*/
+
+		/* Mode Setting */
+		/* Full */
+		0x0C,/*frame_length_lines_msb 0x0340*/
+		0x02,/*frame_length_lines_lsb 0x0341*/
+		0x10,/*line_length_pck_msb 0x0342*/
+		0x70,/* line_length_pck_lsb 0x0343*/
+		0x0F,/* x_output_size_msb   0x034C*/
+		0xC0, /* x_output_size_lsb  0x034D*/
+		0x0B, /* y_output_size_msb  0x034E*/
+		0xD0, /* y_output_size_lsb  0x034F*/
+		0x01, /* x_even_inc_lsb     0x0381*/
+		0x01, /* x_odd_inc_lsb      0x0383*/
+		0x01, /* y_even_inc_lsb                     0x0385*/
+		0x01, /* y_odd_inc_lsb                      0x0387*/
+		0x06, /* reg 0x3016 VMODEADD                0x3016*/
+		0x06, /* reg 0x30E8 HADDAVE                 0x30E8*/
+		0x00, /* reg 0x3301 RGLANESEL               0x3301*/
+
+		0x00,  /* 0x0344 */
+		0x00,  /* 0x0345 */
+		0x00,  /* 0x0346 */
+		0x00,  /* 0x0347 */
+		0x0F,  /* 0x0348 */
+		0xBF,  /* 0x0349 */
+		0x0B,  /* 0x034A */
+		0xCF,  /* 0x034B */
+	},
+	/* 120 fps settings */
+	{
+		0x1B, /*0x1B fps*/
+		/* Global Setting */
+		0x00, /* coarse_integration_time_msb*/
+		0xFE, /* coarse_integration_time_lsb*/
+
+		/* Mode Setting */
+		/* V: 1/8 V-addition (9,7),
+		H: Full */
+
+		0x01, /* frame_length_lines_msb     0x0340*/
+		0x01, /* frame_length_lines_lsb     0x0341*/
+		0x10, /* line_length_pck_msb        0x0342*/
+		0x70, /* line_length_pck_lsb        0x0343*/
+		0x0f, /* x_output_size_msb          0x034C*/
+		0xc0, /* x_output_size_lsb          0x034D*/
+		0x00, /* y_output_size_msb          0x034E*/
+		0xF8, /* y_output_size_lsb          0x034F*/
+		0x01, /* x_even_inc_lsb             0x0381*/
+		0x01, /* x_odd_inc_lsb              0x0383*/
+		0x09, /* y_even_inc_lsb             0x0385*/
+		0x07, /* y_odd_inc_lsb              0x0387*/
+		0x46, /* reg 0x3016 VMODEADD        0x3016*/
+		0x86, /* reg 0x30E8 HADDAVE         0x30E8*/
+		0x00, /* reg 0x3301 RGLANESEL       0x3301*/
+		/* add for 120fps support */
+		0x00, /* 0x0344*/
+		0x00, /* 0x0345*/
+		0x02, /* 0x0346*/
+		0x10, /* 0x0347*/
+		0x0F, /* 0x0348*/
+		0xBF, /* 0x0349*/
+		0x09, /* 0x034A*/
+		0xCF, /* 0x034B*/
+	}
+};
+struct sn12m0pz_reg sn12m0pz_regs = {
+	.reg_pat = &iu060f_reg_pat[0],
+	.reg_pat_init = &iu060f_reg_pat_init[0],
+};
+
diff --git a/drivers/media/platform/msm/camera_v1/vb6801.c b/drivers/media/platform/msm/camera_v1/vb6801.c
new file mode 100644
index 0000000..f916a1c
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vb6801.c
@@ -0,0 +1,1616 @@
+/* Copyright (c) 2009, 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/delay.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <media/msm_camera.h>
+#include <mach/gpio.h>
+#include <mach/camera.h>
+#include "vb6801.h"
+
+/*=============================================================
+	SENSOR REGISTER DEFINES
+==============================================================*/
+enum {
+	REG_HOLD = 0x0104,
+	RELEASE_HOLD = 0x0000,
+	HOLD = 0x0001,
+	STANDBY_MODE = 0x0000,
+	REG_COARSE_INTEGRATION_TIME = 0x0202,
+	REG_ANALOGUE_GAIN_CODE_GLOBAL = 0x0204,
+	REG_RAMP_SCALE = 0x3116,
+	REG_POWER_MAN_ENABLE_3 = 0x3142,
+	REG_POWER_MAN_ENABLE_4 = 0x3143,
+	REG_POWER_MAN_ENABLE_5 = 0x3144,
+	REG_CCP2_DATA_FORMAT = 0x0112,
+	REG_PRE_PLL_CLK_DIV = 0x0304,
+	REG_PLL_MULTIPLIER = 0x0306,
+	REG_VT_SYS_CLK_DIV = 0x0302,
+	REG_VT_PIX_CLK_DIV = 0x0300,
+	REG_OP_SYS_CLK_DIV = 0x030A,
+	REG_OP_PIX_CLK_DIV = 0x0308,
+	REG_VT_LINE_LENGTH_PCK = 0x0342,
+	REG_X_OUTPUT_SIZE = 0x034C,
+	REG_Y_OUTPUT_SIZE = 0x034E,
+	REG_X_ODD_INC = 0x0382,
+	REG_Y_ODD_INC = 0x0386,
+	REG_VT_FRAME_LENGTH_LINES = 0x0340,
+	REG_ANALOG_TIMING_MODES_2 = 0x3113,
+	REG_BRUCE_ENABLE = 0x37B0,
+	REG_OP_CODER_SYNC_CLK_SETUP = 0x3400,
+	REG_OP_CODER_ENABLE = 0x3401,
+	REG_OP_CODER_SLOW_PAD_EN = 0x3402,
+	REG_OP_CODER_AUTO_STARTUP = 0x3414,
+	REG_SCYTHE_ENABLE = 0x3204,
+	REG_SCYTHE_WEIGHT = 0x3206,
+	REG_FRAME_COUNT = 0x0005,
+	REG_MODE_SELECT = 0x0100,
+	REG_CCP2_CHANNEL_IDENTIFIER = 0x0110,
+	REG_CCP2_SIGNALLING_MODE = 0x0111,
+	REG_BTL_LEVEL_SETUP = 0x311B,
+	REG_OP_CODER_AUTOMATIC_MODE_ENABLE = 0x3403,
+	REG_PLL_CTRL = 0x3801,
+	REG_VCM_DAC_CODE = 0x3860,
+	REG_VCM_DAC_STROBE = 0x3868,
+	REG_VCM_DAC_ENABLE = 0x386C,
+	REG_NVM_T1_ADDR_00 = 0x3600,
+	REG_NVM_T1_ADDR_01 = 0x3601,
+	REG_NVM_T1_ADDR_02 = 0x3602,
+	REG_NVM_T1_ADDR_03 = 0x3603,
+	REG_NVM_T1_ADDR_04 = 0x3604,
+	REG_NVM_T1_ADDR_05 = 0x3605,
+	REG_NVM_T1_ADDR_06 = 0x3606,
+	REG_NVM_T1_ADDR_07 = 0x3607,
+	REG_NVM_T1_ADDR_08 = 0x3608,
+	REG_NVM_T1_ADDR_09 = 0x3609,
+	REG_NVM_T1_ADDR_0A = 0x360A,
+	REG_NVM_T1_ADDR_0B = 0x360B,
+	REG_NVM_T1_ADDR_0C = 0x360C,
+	REG_NVM_T1_ADDR_0D = 0x360D,
+	REG_NVM_T1_ADDR_0E = 0x360E,
+	REG_NVM_T1_ADDR_0F = 0x360F,
+	REG_NVM_T1_ADDR_10 = 0x3610,
+	REG_NVM_T1_ADDR_11 = 0x3611,
+	REG_NVM_T1_ADDR_12 = 0x3612,
+	REG_NVM_T1_ADDR_13 = 0x3613,
+	REG_NVM_CTRL = 0x3680,
+	REG_NVM_PDN = 0x3681,
+	REG_NVM_PULSE_WIDTH = 0x368B,
+};
+
+#define VB6801_LINES_PER_FRAME_PREVIEW   800
+#define VB6801_LINES_PER_FRAME_SNAPSHOT 1600
+#define VB6801_PIXELS_PER_LINE_PREVIEW  2500
+#define VB6801_PIXELS_PER_LINE_SNAPSHOT 2500
+
+/* AF constant */
+#define VB6801_TOTAL_STEPS_NEAR_TO_FAR    25
+#define VB6801_STEPS_NEAR_TO_CLOSEST_INF  25
+
+/* for 30 fps preview */
+#define VB6801_DEFAULT_CLOCK_RATE    12000000
+
+enum vb6801_test_mode_t {
+	TEST_OFF,
+	TEST_1,
+	TEST_2,
+	TEST_3
+};
+
+enum vb6801_resolution_t {
+	QTR_SIZE,
+	FULL_SIZE,
+	INVALID_SIZE
+};
+
+enum vb6801_setting_t {
+	RES_PREVIEW,
+	RES_CAPTURE
+};
+
+struct vb6801_work_t {
+	struct work_struct work;
+};
+
+struct sensor_dynamic_params_t {
+	uint16_t preview_pixelsPerLine;
+	uint16_t preview_linesPerFrame;
+	uint16_t snapshot_pixelsPerLine;
+	uint16_t snapshot_linesPerFrame;
+	uint8_t snapshot_changed_fps;
+	uint32_t pclk;
+};
+
+struct vb6801_sensor_info {
+	/* Sensor Configuration Input Parameters */
+	uint32_t ext_clk_freq_mhz;
+	uint32_t target_frame_rate_fps;
+	uint32_t target_vt_pix_clk_freq_mhz;
+	uint32_t sub_sampling_factor;
+	uint32_t analog_binning_allowed;
+	uint32_t raw_mode;
+	uint32_t capture_mode;
+
+	/* Image Readout Registers */
+	uint32_t x_odd_inc;	/* x pixel array addressing odd increment */
+	uint32_t y_odd_inc;	/* y pixel array addressing odd increment */
+	uint32_t x_output_size;	/* width of output image  */
+	uint32_t y_output_size;	/* height of output image */
+
+	/* Declare data format */
+	uint32_t ccp2_data_format;
+
+	/* Clock Tree Registers */
+	uint32_t pre_pll_clk_div;
+	uint32_t pll_multiplier;
+	uint32_t vt_sys_clk_div;
+	uint32_t vt_pix_clk_div;
+	uint32_t op_sys_clk_div;
+	uint32_t op_pix_clk_div;
+
+	/* Video Timing Registers */
+	uint32_t vt_line_length_pck;
+	uint32_t vt_frame_length_lines;
+
+	/* Analogue Binning Registers */
+	uint8_t vtiming_major;
+	uint8_t analog_timing_modes_4;
+
+	/* Fine (pixel) Integration Time Registers */
+	uint32_t fine_integration_time;
+
+	/* Coarse (lines) Integration Time Limit Registers */
+	uint32_t coarse_integration_time_max;
+
+	/* Coarse (lines) Integration Timit Register (16-bit) */
+	uint32_t coarse_integration_time;
+
+	/* Analogue Gain Code Global Registers */
+	uint32_t analogue_gain_code_global;
+
+	/* Digital Gain Code Registers */
+	uint32_t digital_gain_code;
+
+	/* Overall gain (analogue & digital) code
+	 * Note that this is not a real register but just
+	 * an abstraction for the combination of analogue
+	 * and digital gain */
+	uint32_t gain_code;
+
+	/* FMT Test Information */
+	uint32_t pass_fail;
+	uint32_t day;
+	uint32_t month;
+	uint32_t year;
+	uint32_t tester;
+	uint32_t part_number;
+
+	/* Autofocus controls */
+	uint32_t vcm_dac_code;
+	int vcm_max_dac_code_step;
+	int vcm_proportional_factor;
+	int vcm_dac_code_spacing_ms;
+
+	/* VCM NVM Characterisation Information */
+	uint32_t vcm_dac_code_infinity_dn;
+	uint32_t vcm_dac_code_macro_up;
+	uint32_t vcm_dac_code_up_dn_delta;
+
+	/* Internal Variables */
+	uint32_t min_vt_frame_length_lines;
+};
+
+struct vb6801_work_t *vb6801_sensorw;
+struct i2c_client *vb6801_client;
+
+struct vb6801_ctrl_t {
+	const struct msm_camera_sensor_info *sensordata;
+
+	int sensormode;
+	uint32_t factor_fps;	/* init to 1 * 0x00000400 */
+	uint16_t curr_fps;
+	uint16_t max_fps;
+	int8_t pict_exp_update;
+	int8_t reducel;
+	uint16_t curr_lens_pos;
+	uint16_t init_curr_lens_pos;
+	enum vb6801_resolution_t prev_res;
+	enum vb6801_resolution_t pict_res;
+	enum vb6801_resolution_t curr_res;
+	enum vb6801_test_mode_t set_test;
+
+	struct vb6801_sensor_info s_info;
+	struct sensor_dynamic_params_t s_dynamic_params;
+};
+
+static struct vb6801_ctrl_t *vb6801_ctrl;
+static DECLARE_WAIT_QUEUE_HEAD(vb6801_wait_queue);
+DEFINE_MUTEX(vb6801_mut);
+
+static int vb6801_i2c_rxdata(unsigned short saddr,
+			     unsigned char *rxdata, int length)
+{
+	struct i2c_msg msgs[] = {
+		{
+			.addr = saddr,
+			.flags = 0,
+			.len = 2,
+			.buf = rxdata,
+		},
+		{
+			.addr = saddr,
+			.flags = I2C_M_RD,
+			.len = 2,
+			.buf = rxdata,
+		},
+	};
+
+	if (i2c_transfer(vb6801_client->adapter, msgs, 2) < 0) {
+		CDBG("vb6801_i2c_rxdata failed!\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t vb6801_i2c_read(unsigned short raddr,
+			       unsigned short *rdata, int rlen)
+{
+	int32_t rc = 0;
+	unsigned char buf[2];
+
+	if (!rdata)
+		return -EIO;
+
+	memset(buf, 0, sizeof(buf));
+
+	buf[0] = (raddr & 0xFF00) >> 8;
+	buf[1] = (raddr & 0x00FF);
+
+	rc = vb6801_i2c_rxdata(vb6801_client->addr, buf, rlen);
+
+	if (rc < 0) {
+		CDBG("vb6801_i2c_read 0x%x failed!\n", raddr);
+		return rc;
+	}
+
+	*rdata = (rlen == 2 ? buf[0] << 8 | buf[1] : buf[0]);
+
+	return rc;
+}
+
+static int32_t vb6801_i2c_read_table(struct vb6801_i2c_reg_conf_t *regs,
+				     int items)
+{
+	int i;
+	int32_t rc = -EFAULT;
+
+	for (i = 0; i < items; i++) {
+		unsigned short *buf =
+		    regs->dlen == D_LEN_BYTE ?
+		    (unsigned short *)&regs->bdata :
+		    (unsigned short *)&regs->wdata;
+		rc = vb6801_i2c_read(regs->waddr, buf, regs->dlen + 1);
+
+		if (rc < 0) {
+			CDBG("vb6801_i2c_read_table Failed!!!\n");
+			break;
+		}
+
+		regs++;
+	}
+
+	return rc;
+}
+
+static int32_t vb6801_i2c_txdata(unsigned short saddr,
+				 unsigned char *txdata, int length)
+{
+	struct i2c_msg msg[] = {
+		{
+			.addr = saddr,
+			.flags = 0,
+			.len = length,
+			.buf = txdata,
+		},
+	};
+
+	if (i2c_transfer(vb6801_client->adapter, msg, 1) < 0) {
+		CDBG("vb6801_i2c_txdata faild 0x%x\n", vb6801_client->addr);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t vb6801_i2c_write_b(unsigned short waddr, uint8_t bdata)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[3];
+
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00) >> 8;
+	buf[1] = (waddr & 0x00FF);
+	buf[2] = bdata;
+
+	CDBG("i2c_write_b addr = %d, val = %d\n", waddr, bdata);
+	rc = vb6801_i2c_txdata(vb6801_client->addr, buf, 3);
+
+	if (rc < 0) {
+		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
+		     waddr, bdata);
+	}
+
+	return rc;
+}
+
+static int32_t vb6801_i2c_write_w(unsigned short waddr, unsigned short wdata)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[4];
+
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00) >> 8;
+	buf[1] = (waddr & 0x00FF);
+	buf[2] = (wdata & 0xFF00) >> 8;
+	buf[3] = (wdata & 0x00FF);
+
+	CDBG("i2c_write_w addr = %d, val = %d, buf[2] = 0x%x, buf[3] = 0x%x\n",
+	     waddr, wdata, buf[2], buf[3]);
+
+	rc = vb6801_i2c_txdata(vb6801_client->addr, buf, 4);
+	if (rc < 0) {
+		CDBG("i2c_write_w failed, addr = 0x%x, val = 0x%x!\n",
+		     waddr, wdata);
+	}
+
+	return rc;
+}
+
+static int32_t vb6801_i2c_write_table(struct vb6801_i2c_reg_conf_t *regs,
+				      int items)
+{
+	int i;
+	int32_t rc = -EFAULT;
+
+	for (i = 0; i < items; i++) {
+		rc = ((regs->dlen == D_LEN_BYTE) ?
+		      vb6801_i2c_write_b(regs->waddr, regs->bdata) :
+		      vb6801_i2c_write_w(regs->waddr, regs->wdata));
+
+		if (rc < 0) {
+			CDBG("vb6801_i2c_write_table Failed!!!\n");
+			break;
+		}
+
+		regs++;
+	}
+
+	return rc;
+}
+
+static int32_t vb6801_reset(const struct msm_camera_sensor_info *data)
+{
+	int rc;
+
+	rc = gpio_request(data->sensor_reset, "vb6801");
+	if (!rc) {
+		CDBG("sensor_reset SUcceeded\n");
+		gpio_direction_output(data->sensor_reset, 0);
+		mdelay(50);
+		gpio_direction_output(data->sensor_reset, 1);
+		mdelay(13);
+	} else
+		CDBG("sensor_reset FAiled\n");
+
+	return rc;
+}
+
+static int32_t vb6801_set_default_focus(void)
+{
+	int32_t rc = 0;
+
+	/* FIXME: Default focus not supported */
+
+	return rc;
+}
+
+static void vb6801_get_pict_fps(uint16_t fps, uint16_t *pfps)
+{
+	/* input fps is preview fps in Q8 format */
+	uint32_t divider; /*Q10 */
+	uint32_t pclk_mult; /*Q10 */
+	uint32_t d1;
+	uint32_t d2;
+
+	d1 =
+		(uint32_t)(
+		(vb6801_ctrl->s_dynamic_params.preview_linesPerFrame *
+		0x00000400) /
+		vb6801_ctrl->s_dynamic_params.snapshot_linesPerFrame);
+
+	d2 =
+		(uint32_t)(
+		(vb6801_ctrl->s_dynamic_params.preview_pixelsPerLine *
+		0x00000400) /
+		vb6801_ctrl->s_dynamic_params.snapshot_pixelsPerLine);
+
+
+	divider = (uint32_t) (d1 * d2) / 0x00000400;
+
+	pclk_mult = (48 * 0x400) / 60;
+
+	/* Verify PCLK settings and frame sizes. */
+	*pfps = (uint16_t)((((fps * pclk_mult) / 0x00000400) * divider)/
+				0x00000400);
+}
+
+static uint16_t vb6801_get_prev_lines_pf(void)
+{
+	if (vb6801_ctrl->prev_res == QTR_SIZE)
+		return vb6801_ctrl->s_dynamic_params.preview_linesPerFrame;
+	else
+		return vb6801_ctrl->s_dynamic_params.snapshot_linesPerFrame;
+}
+
+static uint16_t vb6801_get_prev_pixels_pl(void)
+{
+	if (vb6801_ctrl->prev_res == QTR_SIZE)
+		return vb6801_ctrl->s_dynamic_params.preview_pixelsPerLine;
+	else
+		return vb6801_ctrl->s_dynamic_params.snapshot_pixelsPerLine;
+}
+
+static uint16_t vb6801_get_pict_lines_pf(void)
+{
+	return vb6801_ctrl->s_dynamic_params.snapshot_linesPerFrame;
+}
+
+static uint16_t vb6801_get_pict_pixels_pl(void)
+{
+	return vb6801_ctrl->s_dynamic_params.snapshot_pixelsPerLine;
+}
+
+static uint32_t vb6801_get_pict_max_exp_lc(void)
+{
+	uint16_t snapshot_lines_per_frame;
+
+	if (vb6801_ctrl->pict_res == QTR_SIZE) {
+		snapshot_lines_per_frame =
+		    vb6801_ctrl->s_dynamic_params.preview_linesPerFrame - 3;
+	} else {
+		snapshot_lines_per_frame =
+		    vb6801_ctrl->s_dynamic_params.snapshot_linesPerFrame - 3;
+	}
+
+	return snapshot_lines_per_frame;
+}
+
+static int32_t vb6801_set_fps(struct fps_cfg *fps)
+{
+	int32_t rc = 0;
+
+	/* input is new fps in Q8 format */
+	switch (fps->fps_div) {
+	case 7680:		/* 30 * Q8 */
+		vb6801_ctrl->factor_fps = 1;
+		break;
+
+	case 3840:		/* 15 * Q8 */
+		vb6801_ctrl->factor_fps = 2;
+		break;
+
+	case 2560:		/* 10 * Q8 */
+		vb6801_ctrl->factor_fps = 3;
+		break;
+
+	case 1920:		/* 7.5 * Q8 */
+		vb6801_ctrl->factor_fps = 4;
+		break;
+
+	default:
+		rc = -ENODEV;
+		break;
+	}
+
+	return rc;
+}
+
+static int32_t vb6801_write_exp_gain(uint16_t gain, uint32_t line)
+{
+	int32_t rc = 0;
+	uint16_t lpf;
+
+	if (vb6801_ctrl->curr_res == SENSOR_FULL_SIZE)
+		lpf = VB6801_LINES_PER_FRAME_SNAPSHOT;
+	else
+		lpf = VB6801_LINES_PER_FRAME_PREVIEW;
+
+	/* hold */
+	rc = vb6801_i2c_write_w(REG_HOLD, HOLD);
+	if (rc < 0)
+		goto exp_gain_done;
+
+	if ((vb6801_ctrl->curr_fps <
+	     vb6801_ctrl->max_fps / vb6801_ctrl->factor_fps) &&
+	    (!vb6801_ctrl->pict_exp_update)) {
+
+		if (vb6801_ctrl->reducel) {
+
+			rc = vb6801_i2c_write_w(REG_VT_FRAME_LENGTH_LINES,
+						lpf * vb6801_ctrl->factor_fps);
+
+			vb6801_ctrl->curr_fps =
+			    vb6801_ctrl->max_fps / vb6801_ctrl->factor_fps;
+
+		} else if (!vb6801_ctrl->reducel) {
+
+			rc = vb6801_i2c_write_w(REG_COARSE_INTEGRATION_TIME,
+						line * vb6801_ctrl->factor_fps);
+
+			vb6801_ctrl->reducel = 1;
+		}
+	} else if ((vb6801_ctrl->curr_fps >
+		    vb6801_ctrl->max_fps / vb6801_ctrl->factor_fps) &&
+		   (!vb6801_ctrl->pict_exp_update)) {
+
+		rc = vb6801_i2c_write_w(REG_VT_FRAME_LENGTH_LINES,
+					lpf * vb6801_ctrl->factor_fps);
+
+		vb6801_ctrl->curr_fps =
+		    vb6801_ctrl->max_fps / vb6801_ctrl->factor_fps;
+
+	} else {
+		/* analogue_gain_code_global */
+		rc = vb6801_i2c_write_w(REG_ANALOGUE_GAIN_CODE_GLOBAL, gain);
+		if (rc < 0)
+			goto exp_gain_done;
+
+		/* coarse_integration_time */
+		rc = vb6801_i2c_write_w(REG_COARSE_INTEGRATION_TIME,
+					line * vb6801_ctrl->factor_fps);
+		if (rc < 0)
+			goto exp_gain_done;
+
+		vb6801_ctrl->pict_exp_update = 1;
+	}
+
+	rc = vb6801_i2c_write_w(REG_HOLD, RELEASE_HOLD);
+
+exp_gain_done:
+	return rc;
+}
+
+static int32_t vb6801_set_pict_exp_gain(uint16_t gain, uint32_t line)
+{
+	vb6801_ctrl->pict_exp_update = 1;
+	return vb6801_write_exp_gain(gain, line);
+}
+
+static int32_t vb6801_power_down(void)
+{
+	int32_t rc = 0;
+	rc = vb6801_i2c_write_b(REG_NVM_PDN, 0);
+
+	mdelay(5);
+	return rc;
+}
+
+static int32_t vb6801_go_to_position(uint32_t target_vcm_dac_code,
+				     struct vb6801_sensor_info *ps)
+{
+	/* Prior to running this function the following values must
+	 * be initialised in the sensor data structure, PS
+	 * ps->vcm_dac_code
+	 * ps->vcm_max_dac_code_step
+	 * ps->vcm_dac_code_spacing_ms */
+
+	int32_t rc = 0;
+
+	ps->vcm_dac_code = target_vcm_dac_code;
+
+	/* Restore Strobe to zero state */
+	rc = vb6801_i2c_write_b(REG_VCM_DAC_STROBE, 0x00);
+	if (rc < 0)
+		return rc;
+
+	/* Write 9-bit VCM DAC Code */
+	rc = vb6801_i2c_write_w(REG_VCM_DAC_CODE, ps->vcm_dac_code);
+	if (rc < 0)
+		return rc;
+
+	/* Generate a rising edge on the dac_strobe to latch
+	 * new DAC value */
+
+	rc = vb6801_i2c_write_w(REG_VCM_DAC_STROBE, 0x01);
+
+	return rc;
+}
+
+static int32_t vb6801_move_focus(int direction, int32_t num_steps)
+{
+	int16_t step_direction;
+	int16_t actual_step;
+	int16_t next_position;
+	uint32_t step_size;
+	int16_t small_move[4];
+	uint16_t i;
+	int32_t rc = 0;
+
+	step_size = (vb6801_ctrl->s_info.vcm_dac_code_macro_up -
+		     vb6801_ctrl->s_info.vcm_dac_code_infinity_dn) /
+	    VB6801_TOTAL_STEPS_NEAR_TO_FAR;
+
+	if (num_steps > VB6801_TOTAL_STEPS_NEAR_TO_FAR)
+		num_steps = VB6801_TOTAL_STEPS_NEAR_TO_FAR;
+	else if (num_steps == 0)
+		return -EINVAL;
+
+	if (direction == MOVE_NEAR)
+		step_direction = 4;
+	else if (direction == MOVE_FAR)
+		step_direction = -4;
+	else
+		return -EINVAL;
+
+	/* need to decide about default position and power supplied
+	 * at start up and reset */
+	if (vb6801_ctrl->curr_lens_pos < vb6801_ctrl->init_curr_lens_pos)
+		vb6801_ctrl->curr_lens_pos = vb6801_ctrl->init_curr_lens_pos;
+
+	actual_step = (step_direction * num_steps);
+
+	next_position = vb6801_ctrl->curr_lens_pos;
+
+	for (i = 0; i < 4; i++) {
+		if (actual_step >= 0)
+			small_move[i] =
+			    (i + 1) * actual_step / 4 - i * actual_step / 4;
+
+		if (actual_step < 0)
+			small_move[i] =
+			    (i + 1) * actual_step / 4 - i * actual_step / 4;
+	}
+
+	if (next_position > 511)
+		next_position = 511;
+	else if (next_position < 0)
+		next_position = 0;
+
+	/* for damping */
+	for (i = 0; i < 4; i++) {
+		next_position =
+		    (int16_t) (vb6801_ctrl->curr_lens_pos + small_move[i]);
+
+		/* Writing the digital code for current to the actuator */
+		CDBG("next_position in damping mode = %d\n", next_position);
+
+		rc = vb6801_go_to_position(next_position, &vb6801_ctrl->s_info);
+		if (rc < 0) {
+			CDBG("go_to_position Failed!!!\n");
+			return rc;
+		}
+
+		vb6801_ctrl->curr_lens_pos = next_position;
+		if (i < 3)
+			mdelay(5);
+	}
+
+	return rc;
+}
+
+static int vb6801_read_nvm_data(struct vb6801_sensor_info *ps)
+{
+	/* +--------+------+------+----------------+---------------+
+	 * | Index | NVM | NVM | Name | Description |
+	 * | | Addr | Byte | | |
+	 * +--------+------+------+----------------+---------------+
+	 * | 0x3600 | 0 | 3 | nvm_t1_addr_00 | {PF[2:0]:Day[4:0]} |
+	 * | 0x3601 | 0 | 2 | nvm_t1_addr_01 | {Month[3:0]:Year[3:0]} |
+	 * | 0x3602 | 0 | 1 | nvm_t1_addr_02 | Tester[7:0] |
+	 * | 0x3603 | 0 | 0 | nvm_t1_addr_03 | Part[15:8] |
+	 * +--------+------+------+----------------+---------------+
+	 * | 0x3604 | 1 | 3 | nvm_t1_addr_04 | Part[7:0] |
+	 * | 0x3605 | 1 | 2 | nvm_t1_addr_05 | StartWPM[7:0] |
+	 * | 0x3606 | 1 | 1 | nvm_t1_addr_06 | Infinity[7:0] |
+	 * | 0x3607 | 1 | 0 | nvm_t1_addr_07 | Macro[7:0] |
+	 * +--------+------+------+----------------+---------------+
+	 * | 0x3608 | 2 | 3 | nvm_t1_addr_08 | Reserved |
+	 * | 0x3609 | 2 | 2 | nvm_t1_addr_09 | Reserved |
+	 * | 0x360A | 2 | 1 | nvm_t1_addr_0A | UpDown[7:0] |
+	 * | 0x360B | 2 | 0 | nvm_t1_addr_0B | Reserved |
+	 * +--------+------+------+----------------+---------------+
+	 * | 0x360C | 3 | 3 | nvm_t1_addr_0C | Reserved |
+	 * | 0x360D | 3 | 2 | nvm_t1_addr_0D | Reserved |
+	 * | 0x360E | 3 | 1 | nvm_t1_addr_0E | Reserved |
+	 * | 0x360F | 3 | 0 | nvm_t1_addr_0F | Reserved |
+	 * +--------+------+------+----------------+---------------+
+	 * | 0x3610 | 4 | 3 | nvm_t1_addr_10 | Reserved |
+	 * | 0x3611 | 4 | 2 | nvm_t1_addr_11 | Reserved |
+	 * | 0x3612 | 4 | 1 | nvm_t1_addr_12 | Reserved |
+	 * | 0x3613 | 4 | 0 | nvm_t1_addr_13 | Reserved |
+	 * +--------+------+------+----------------+---------------+*/
+
+	int32_t rc;
+	struct vb6801_i2c_reg_conf_t rreg[] = {
+		{REG_NVM_T1_ADDR_00, 0, 0, D_LEN_BYTE},
+		{REG_NVM_T1_ADDR_01, 0, 0, D_LEN_BYTE},
+		{REG_NVM_T1_ADDR_02, 0, 0, D_LEN_BYTE},
+		{REG_NVM_T1_ADDR_03, 0, 0, D_LEN_BYTE},
+		{REG_NVM_T1_ADDR_04, 0, 0, D_LEN_BYTE},
+		{REG_NVM_T1_ADDR_05, 0, 0, D_LEN_BYTE},
+		{REG_NVM_T1_ADDR_06, 0, 0, D_LEN_BYTE},
+		{REG_NVM_T1_ADDR_07, 0, 0, D_LEN_BYTE},
+		{REG_NVM_T1_ADDR_08, 0, 0, D_LEN_BYTE},
+		{REG_NVM_T1_ADDR_09, 0, 0, D_LEN_BYTE},
+		{REG_NVM_T1_ADDR_0A, 0, 0, D_LEN_BYTE},
+		{REG_NVM_T1_ADDR_0B, 0, 0, D_LEN_BYTE},
+		{REG_NVM_T1_ADDR_0C, 0, 0, D_LEN_BYTE},
+		{REG_NVM_T1_ADDR_0D, 0, 0, D_LEN_BYTE},
+		{REG_NVM_T1_ADDR_0E, 0, 0, D_LEN_BYTE},
+		{REG_NVM_T1_ADDR_0F, 0, 0, D_LEN_BYTE},
+		{REG_NVM_T1_ADDR_10, 0, 0, D_LEN_BYTE},
+		{REG_NVM_T1_ADDR_11, 0, 0, D_LEN_BYTE},
+		{REG_NVM_T1_ADDR_12, 0, 0, D_LEN_BYTE},
+		{REG_NVM_T1_ADDR_13, 0, 0, D_LEN_BYTE},
+	};
+
+	struct vb6801_i2c_reg_conf_t wreg[] = {
+		/* Enable NVM for Direct Reading */
+		{REG_NVM_CTRL, 0, 2, D_LEN_BYTE},
+
+		/* Power up NVM */
+		{REG_NVM_PDN, 0, 1, D_LEN_BYTE},
+	};
+
+	rc = vb6801_i2c_write_table(wreg, ARRAY_SIZE(wreg));
+	if (rc < 0) {
+		CDBG("I2C Write Table FAILED!!!\n");
+		return rc;
+	}
+
+	/* NVM Read Pulse Width
+	 * ====================
+	 * nvm_pulse_width_us = nvm_pulse_width_ext_clk / ext_clk_freq_mhz
+	 * Valid Range for Read Pulse Width = 400ns -> 3.0us
+	 * Min ext_clk_freq_mhz = 6MHz  => 3.0 *  6  = 18
+	 * Max ext_clk_freq_mhz = 27MHz => 0.4 * 27 = 10.8
+	 * Choose 15 as a common value
+	 *  - 15 /  6.0 = 2.5000us
+	 *  - 15 / 12.0 = 1.2500us
+	 *  - 15 / 27.0 = 0.5555us */
+	rc = vb6801_i2c_write_w(REG_NVM_PULSE_WIDTH, 15);
+	if (rc < 0) {
+		rc = -EBUSY;
+		goto nv_shutdown;
+	}
+
+	rc = vb6801_i2c_read_table(rreg, ARRAY_SIZE(rreg));
+	if (rc < 0) {
+		CDBG("I2C Read Table FAILED!!!\n");
+		rc = -EBUSY;
+		goto nv_shutdown;
+	}
+
+	/* Decode and Save FMT Info */
+	ps->pass_fail = (rreg[0].bdata & 0x00E0) >> 5;
+	ps->day = (rreg[0].bdata & 0x001F);
+	ps->month = (rreg[1].bdata & 0x00F0) >> 4;
+	ps->year = (rreg[1].bdata & 0x000F) + 2000;
+	ps->tester = rreg[2].bdata;
+	ps->part_number = (rreg[3].bdata << 8) + rreg[4].bdata;
+
+	/* Decode and Save VCM Dac Values in data structure */
+	ps->vcm_dac_code_infinity_dn = rreg[6].bdata;
+	ps->vcm_dac_code_macro_up = rreg[7].bdata << 1;
+	ps->vcm_dac_code_up_dn_delta = rreg[10].bdata;
+
+nv_shutdown:
+	/* Power Down NVM to extend life time */
+	rc = vb6801_i2c_write_b(REG_NVM_PDN, 0);
+
+	return rc;
+}
+
+static int vb6801_config_sensor(int32_t ext_clk_freq_mhz,
+				int32_t target_frame_rate_fps,
+				int32_t target_vt_pix_clk_freq_mhz,
+				uint32_t sub_sampling_factor,
+				uint32_t analog_binning_allowed,
+				uint32_t raw_mode, int capture_mode,
+				enum vb6801_resolution_t res)
+{
+	uint32_t rc;
+	/* ext_clk_freq_mhz      = 6.0 -> 27.0 MHz
+	 * target_frame_rate_fps  = 15 fps
+	 * target_vt_pix_clk_freq_mhz = 24.0 -> 64.0MHz
+	 * sub_sampling factor   = 1, 2, 3, or 4
+	 * raw_mode factor       = 10
+	 *
+	 * capture_mode, 0 = CCP1
+	 * capture_mode, 1 = CCP2
+	 * capture_mode, 2 = 10-bit parallel + hsync + vsync */
+
+	/* Declare data format */
+	uint32_t ccp2_data_format = 0x0A0A;
+
+	/*  Declare clock tree variables */
+	int32_t min_pll_ip_freq_mhz = 6;
+	int32_t max_pll_op_freq_mhz = 640;
+	uint32_t pre_pll_clk_div = 1;
+	int32_t pll_ip_freq_mhz = 6;
+	uint32_t pll_multiplier = 100;
+	int32_t pll_op_freq_mhz = 600;
+	uint32_t vt_sys_clk_div = 1;
+	int32_t vt_sys_clk_freq_mhz = 600;
+	uint32_t vt_pix_clk_div = 10;
+	int32_t vt_pix_clk_freq_mhz = 60;
+	uint32_t op_sys_clk_div = 1;
+	int32_t op_sys_clk_freq_mhz = 60;
+	uint32_t op_pix_clk_div = 10;
+	int32_t op_pix_clk_freq_mhz = 60;
+
+	/* Declare pixel array and frame timing variables */
+	uint32_t x_pixel_array = 2064;
+	uint32_t y_pixel_array = 1544;
+	uint32_t x_even_inc = 1;
+	uint32_t x_odd_inc = 1;
+	uint32_t y_even_inc = 1;
+	uint32_t y_odd_inc = 1;
+	uint32_t x_output_size = 2064;
+	uint32_t y_output_size = 1544;
+	uint32_t additional_rows = 2;
+	uint32_t min_vt_frame_blanking_lines = 16;
+	uint32_t vt_line_length_pck = 2500;
+	uint32_t vt_line_length_us = 0;
+	uint32_t min_vt_frame_length_lines = 1562;
+	uint32_t vt_frame_length_lines = 1600;
+	uint32_t target_vt_frame_length_ms;	/* 200 * 0x0001000 / 3; */
+	uint32_t vt_frame_length_ms;	/* 200 * 0x0001000 / 3; */
+	uint32_t frame_rate_fps = 15;
+
+	/* Coarse intergration time */
+	uint32_t coarse_integration_time = 1597;
+	uint32_t coarse_integration_time_max_margin = 3;
+	uint16_t frame_count;
+	int timeout;
+
+	struct vb6801_sensor_info *pinfo = &vb6801_ctrl->s_info;
+
+	struct vb6801_i2c_reg_conf_t rreg[] = {
+		{REG_PRE_PLL_CLK_DIV, 0, 0, D_LEN_WORD},
+		{REG_PLL_MULTIPLIER, 0, 0, D_LEN_WORD},
+		{REG_VT_SYS_CLK_DIV, 0, 0, D_LEN_WORD},
+		{REG_VT_PIX_CLK_DIV, 0, 0, D_LEN_WORD},
+		{REG_OP_SYS_CLK_DIV, 0, 0, D_LEN_WORD},
+		{REG_OP_PIX_CLK_DIV, 0, 0, D_LEN_WORD},
+		{REG_FRAME_COUNT, 0, 0, D_LEN_BYTE},
+	};
+
+	struct vb6801_i2c_reg_conf_t wreg2[] = {
+		{REG_POWER_MAN_ENABLE_3, 0, 95, D_LEN_BYTE},
+		{REG_POWER_MAN_ENABLE_4, 0, 142, D_LEN_BYTE},
+		{REG_POWER_MAN_ENABLE_5, 0, 7, D_LEN_BYTE},
+	};
+
+	/* VIDEO TIMING CALCULATIONS
+	 * ========================= */
+
+	/* Pixel Array Size */
+	x_pixel_array = 2064;
+	y_pixel_array = 1544;
+
+	/* set current resolution */
+	vb6801_ctrl->curr_res = res;
+
+	/* Analogue binning setup */
+	if (pinfo->analog_binning_allowed > 0 &&
+	    pinfo->sub_sampling_factor == 4) {
+
+		pinfo->vtiming_major = 1;
+		pinfo->analog_timing_modes_4 = 32;
+	} else if (pinfo->analog_binning_allowed > 0 &&
+		   pinfo->sub_sampling_factor == 2) {
+
+		pinfo->vtiming_major = 1;
+		pinfo->analog_timing_modes_4 = 0;
+	} else {
+
+		pinfo->vtiming_major = 0;
+		pinfo->analog_timing_modes_4 = 0;
+	}
+
+	/* Sub-Sampling X & Y Odd Increments: valid values 1, 3, 5, 7 */
+	x_even_inc = 1;
+	y_even_inc = 1;
+	x_odd_inc = (sub_sampling_factor << 1) - x_even_inc;
+	y_odd_inc = (sub_sampling_factor << 1) - y_even_inc;
+
+	/* Output image size
+	 * Must always be a multiple of 2 - round down */
+	x_output_size = ((x_pixel_array / sub_sampling_factor) >> 1) << 1;
+	y_output_size = ((y_pixel_array / sub_sampling_factor) >> 1) << 1;
+
+	/* Output data format */
+	ccp2_data_format = (raw_mode << 8) + raw_mode;
+
+	/* Pre PLL clock divider : valid values 1, 2 or 4
+	 * The 1st step is to ensure that PLL input frequency is as close
+	 * as possible to the min allowed PLL input frequency.
+	 * This yields the smallest step size in the PLL output frequency. */
+	pre_pll_clk_div =
+	    ((int)(ext_clk_freq_mhz / min_pll_ip_freq_mhz) >> 1) << 1;
+	if (pre_pll_clk_div < 2)
+		pre_pll_clk_div = 1;
+
+	pll_ip_freq_mhz = ext_clk_freq_mhz / pre_pll_clk_div;
+
+	/* Video Timing System Clock divider: valid values 1, 2, 4
+	 * Now need to work backwards through the clock tree to determine the
+	 * 1st pass estimates for vt_sys_clk_freq_mhz and then the PLL output
+	 * frequency.*/
+	vt_sys_clk_freq_mhz = vt_pix_clk_div * target_vt_pix_clk_freq_mhz;
+	vt_sys_clk_div = max_pll_op_freq_mhz / vt_sys_clk_freq_mhz;
+	if (vt_sys_clk_div < 2)
+		vt_sys_clk_div = 1;
+
+	/* PLL Mulitplier: min , max 106 */
+	pll_op_freq_mhz = vt_sys_clk_div * vt_sys_clk_freq_mhz;
+	pll_multiplier = (pll_op_freq_mhz * 0x0001000) / pll_ip_freq_mhz;
+
+	/* Calculate the acutal pll output frequency
+	 * - the pll_multiplier calculation introduces a quantisation error
+	 *   due the integer nature of the pll multiplier */
+	pll_op_freq_mhz = (pll_ip_freq_mhz * pll_multiplier) / 0x0001000;
+
+	/* Re-calculate video timing clock frequencies based
+	 * on actual PLL freq */
+	vt_sys_clk_freq_mhz = pll_op_freq_mhz / vt_sys_clk_div;
+	vt_pix_clk_freq_mhz = ((vt_sys_clk_freq_mhz * 0x0001000) /
+				vt_pix_clk_div)/0x0001000;
+
+	/* Output System Clock Divider: valid value 1, 2, 4, 6, 8
+	 * op_sys_clk_div = vt_sys_clk_div;*/
+	op_sys_clk_div = (vt_sys_clk_div * sub_sampling_factor);
+	if (op_sys_clk_div < 2)
+		op_sys_clk_div = 1;
+
+	/* Calculate output timing clock frequencies */
+	op_sys_clk_freq_mhz = pll_op_freq_mhz / op_sys_clk_div;
+	op_pix_clk_freq_mhz =
+	    (op_sys_clk_freq_mhz * 0x0001000) / (op_pix_clk_div * 0x0001000);
+
+	/* Line length in pixels and us */
+	vt_line_length_pck = 2500;
+	vt_line_length_us =
+	    vt_line_length_pck * 0x0001000 / vt_pix_clk_freq_mhz;
+
+	/* Target vt_frame_length_ms */
+	target_vt_frame_length_ms = (1000 * 0x0001000 / target_frame_rate_fps);
+
+	/* Frame length in lines */
+	min_vt_frame_length_lines =
+	    additional_rows + y_output_size + min_vt_frame_blanking_lines;
+
+	vt_frame_length_lines =
+	    ((1000 * target_vt_frame_length_ms) / vt_line_length_us);
+
+	if (vt_frame_length_lines <= min_vt_frame_length_lines)
+		vt_frame_length_lines = min_vt_frame_length_lines;
+
+	/* Calcuate the actual frame length in ms */
+	vt_frame_length_ms = (vt_frame_length_lines * vt_line_length_us / 1000);
+
+	/* Frame Rate in fps */
+	frame_rate_fps = (1000 * 0x0001000 / vt_frame_length_ms);
+
+	/* Set coarse integration to max */
+	coarse_integration_time =
+	    vt_frame_length_lines - coarse_integration_time_max_margin;
+
+	CDBG("SENSOR VIDEO TIMING SUMMARY:\n");
+	CDBG(" ============================\n");
+	CDBG("ext_clk_freq_mhz      = %d\n", ext_clk_freq_mhz);
+	CDBG("pre_pll_clk_div       = %d\n", pre_pll_clk_div);
+	CDBG("pll_ip_freq_mhz       = %d\n", pll_ip_freq_mhz);
+	CDBG("pll_multiplier        = %d\n", pll_multiplier);
+	CDBG("pll_op_freq_mhz       = %d\n", pll_op_freq_mhz);
+	CDBG("vt_sys_clk_div        = %d\n", vt_sys_clk_div);
+	CDBG("vt_sys_clk_freq_mhz   = %d\n", vt_sys_clk_freq_mhz);
+	CDBG("vt_pix_clk_div        = %d\n", vt_pix_clk_div);
+	CDBG("vt_pix_clk_freq_mhz   = %d\n", vt_pix_clk_freq_mhz);
+	CDBG("op_sys_clk_div        = %d\n", op_sys_clk_div);
+	CDBG("op_sys_clk_freq_mhz   = %d\n", op_sys_clk_freq_mhz);
+	CDBG("op_pix_clk_div        = %d\n", op_pix_clk_div);
+	CDBG("op_pix_clk_freq_mhz   = %d\n", op_pix_clk_freq_mhz);
+	CDBG("vt_line_length_pck    = %d\n", vt_line_length_pck);
+	CDBG("vt_line_length_us     = %d\n", vt_line_length_us/0x0001000);
+	CDBG("vt_frame_length_lines = %d\n", vt_frame_length_lines);
+	CDBG("vt_frame_length_ms    = %d\n", vt_frame_length_ms/0x0001000);
+	CDBG("frame_rate_fps        = %d\n", frame_rate_fps);
+	CDBG("ccp2_data_format = %d\n", ccp2_data_format);
+	CDBG("x_output_size = %d\n", x_output_size);
+	CDBG("y_output_size = %d\n", y_output_size);
+	CDBG("x_odd_inc = %d\n", x_odd_inc);
+	CDBG("y_odd_inc = %d\n", y_odd_inc);
+	CDBG("(vt_frame_length_lines * frame_rate_factor ) = %d\n",
+	    (vt_frame_length_lines * vb6801_ctrl->factor_fps));
+	CDBG("coarse_integration_time = %d\n", coarse_integration_time);
+	CDBG("pinfo->vcm_dac_code = %d\n", pinfo->vcm_dac_code);
+	CDBG("capture_mode = %d\n", capture_mode);
+
+	/* RE-CONFIGURE SENSOR WITH NEW TIMINGS
+	 * ====================================
+	 * Enter Software Standby Mode */
+	rc = vb6801_i2c_write_b(REG_MODE_SELECT, 0);
+	if (rc < 0) {
+		CDBG("I2C vb6801_i2c_write_b FAILED!!!\n");
+		return rc;
+	}
+
+	/* Wait 100ms */
+	mdelay(100);
+
+	if (capture_mode == 0) {
+
+		rc = vb6801_i2c_write_b(REG_CCP2_CHANNEL_IDENTIFIER, 0);
+		rc = vb6801_i2c_write_b(REG_CCP2_SIGNALLING_MODE, 0);
+	} else if (capture_mode == 1) {
+
+		rc = vb6801_i2c_write_b(REG_CCP2_CHANNEL_IDENTIFIER, 0);
+		rc = vb6801_i2c_write_b(REG_CCP2_SIGNALLING_MODE, 1);
+	}
+
+	{
+		struct vb6801_i2c_reg_conf_t wreg[] = {
+			/* Re-configure Sensor */
+			{REG_CCP2_DATA_FORMAT, ccp2_data_format, 0,
+			 D_LEN_WORD},
+			{REG_ANALOGUE_GAIN_CODE_GLOBAL, 128, 0, D_LEN_WORD},
+			{REG_PRE_PLL_CLK_DIV, pre_pll_clk_div, 0, D_LEN_WORD},
+			{REG_VT_SYS_CLK_DIV, vt_sys_clk_div, 0, D_LEN_WORD},
+			{REG_VT_PIX_CLK_DIV, vt_pix_clk_div, 0, D_LEN_WORD},
+			{REG_OP_SYS_CLK_DIV, vt_sys_clk_div, 0, D_LEN_WORD},
+			{REG_OP_PIX_CLK_DIV, vt_pix_clk_div, 0, D_LEN_WORD},
+			{REG_VT_LINE_LENGTH_PCK, vt_line_length_pck, 0,
+			 D_LEN_WORD},
+			{REG_X_OUTPUT_SIZE, x_output_size, 0, D_LEN_WORD},
+			{REG_Y_OUTPUT_SIZE, y_output_size, 0, D_LEN_WORD},
+			{REG_X_ODD_INC, x_odd_inc, 0, D_LEN_WORD},
+			{REG_Y_ODD_INC, y_odd_inc, 0, D_LEN_WORD},
+			{REG_VT_FRAME_LENGTH_LINES,
+			 vt_frame_length_lines * vb6801_ctrl->factor_fps, 0,
+			 D_LEN_WORD},
+			{REG_COARSE_INTEGRATION_TIME,
+			 coarse_integration_time, 0, D_LEN_WORD},
+			/* Analogue Settings */
+			{REG_ANALOG_TIMING_MODES_2, 0, 132, D_LEN_BYTE},
+			{REG_RAMP_SCALE, 0, 5, D_LEN_BYTE},
+			{REG_BTL_LEVEL_SETUP, 0, 11, D_LEN_BYTE},
+			/* Enable Defect Correction */
+			{REG_SCYTHE_ENABLE, 0, 1, D_LEN_BYTE},
+			{REG_SCYTHE_WEIGHT, 0, 16, D_LEN_BYTE},
+			{REG_BRUCE_ENABLE, 0, 1, D_LEN_BYTE},
+			/* Auto Focus Configuration
+			 * Please note that the DAC Code is a written as a
+			 * 16-bit value 0 = infinity (no DAC current) */
+			{REG_VCM_DAC_CODE, pinfo->vcm_dac_code, 0, D_LEN_WORD},
+			{REG_VCM_DAC_STROBE, 0, 0, D_LEN_BYTE},
+			{REG_VCM_DAC_ENABLE, 0, 1, D_LEN_BYTE},
+		};
+
+		rc = vb6801_i2c_write_table(wreg, ARRAY_SIZE(wreg));
+		if (rc < 0) {
+			CDBG("I2C Write Table FAILED!!!\n");
+			return rc;
+		}
+	}
+	/* Parallel Interface Configuration */
+	if (capture_mode >= 2) {
+		struct vb6801_i2c_reg_conf_t wreg1[] = {
+			{REG_OP_CODER_SYNC_CLK_SETUP, 0, 15, D_LEN_BYTE},
+			{REG_OP_CODER_ENABLE, 0, 3, D_LEN_BYTE},
+			{REG_OP_CODER_SLOW_PAD_EN, 0, 1, D_LEN_BYTE},
+			{REG_OP_CODER_AUTOMATIC_MODE_ENABLE, 0, 3, D_LEN_BYTE},
+			{REG_OP_CODER_AUTO_STARTUP, 0, 2, D_LEN_BYTE},
+		};
+
+		rc = vb6801_i2c_write_table(wreg1, ARRAY_SIZE(wreg1));
+		if (rc < 0) {
+			CDBG("I2C Write Table FAILED!!!\n");
+			return rc;
+		}
+	}
+
+	/* Enter Streaming Mode */
+	rc = vb6801_i2c_write_b(REG_MODE_SELECT, 1);
+	if (rc < 0) {
+		CDBG("I2C Write Table FAILED!!!\n");
+		return rc;
+	}
+
+	/* Wait until the sensor starts streaming
+	 * Poll until the reported frame_count value is != 0xFF */
+	frame_count = 0xFF;
+	timeout = 2000;
+	while (frame_count == 0xFF && timeout > 0) {
+		rc = vb6801_i2c_read(REG_FRAME_COUNT, &frame_count, 1);
+		if (rc < 0)
+			return rc;
+
+		CDBG("REG_FRAME_COUNT  = 0x%x\n", frame_count);
+		timeout--;
+	}
+
+	/* Post Streaming Configuration */
+
+	rc = vb6801_i2c_write_table(wreg2, ARRAY_SIZE(wreg2));
+	if (rc < 0) {
+		CDBG("I2C Write Table FAILED!!!\n");
+		return rc;
+	}
+
+	rc = vb6801_i2c_read_table(rreg, ARRAY_SIZE(rreg));
+	if (rc < 0) {
+		CDBG("I2C Read Table FAILED!!!\n");
+		return rc;
+	}
+
+	CDBG("REG_PRE_PLL_CLK_DIV = 0x%x\n", rreg[0].wdata);
+	CDBG("REG_PLL_MULTIPLIER  = 0x%x\n", rreg[1].wdata);
+	CDBG("REG_VT_SYS_CLK_DIV  = 0x%x\n", rreg[2].wdata);
+	CDBG("REG_VT_PIX_CLK_DIV  = 0x%x\n", rreg[3].wdata);
+	CDBG("REG_OP_SYS_CLK_DIV  = 0x%x\n", rreg[4].wdata);
+	CDBG("REG_OP_PIX_CLK_DIV  = 0x%x\n", rreg[5].wdata);
+	CDBG("REG_FRAME_COUNT  = 0x%x\n", rreg[6].bdata);
+
+	mdelay(50);
+	frame_count = 0;
+	rc = vb6801_i2c_read(REG_FRAME_COUNT, &frame_count, 1);
+	CDBG("REG_FRAME_COUNT1  = 0x%x\n", frame_count);
+
+	mdelay(150);
+	frame_count = 0;
+	rc = vb6801_i2c_read(REG_FRAME_COUNT, &frame_count, 1);
+	CDBG("REG_FRAME_COUNT2  = 0x%x\n", frame_count);
+
+	mdelay(100);
+	frame_count = 0;
+	rc = vb6801_i2c_read(REG_FRAME_COUNT, &frame_count, 1);
+	CDBG("REG_FRAME_COUNT3  = 0x%x\n", frame_count);
+
+	mdelay(250);
+	frame_count = 0;
+	rc = vb6801_i2c_read(REG_FRAME_COUNT, &frame_count, 1);
+	CDBG("REG_FRAME_COUNT4  = 0x%x\n", frame_count);
+
+	return rc;
+}
+
+static int vb6801_sensor_init_done(const struct msm_camera_sensor_info *data)
+{
+	gpio_direction_output(data->sensor_reset, 0);
+	gpio_free(data->sensor_reset);
+	return 0;
+}
+
+static int vb6801_init_client(struct i2c_client *client)
+{
+	/* Initialize the MSM_CAMI2C Chip */
+	init_waitqueue_head(&vb6801_wait_queue);
+	return 0;
+}
+
+static int32_t vb6801_video_config(int mode, int res)
+{
+	int32_t rc = 0;
+
+	vb6801_ctrl->prev_res = res;
+	vb6801_ctrl->curr_res = res;
+	vb6801_ctrl->sensormode = mode;
+
+	rc = vb6801_config_sensor(12, 30, 60, 2, 1, 10, 2, RES_PREVIEW);
+	if (rc < 0)
+		return rc;
+
+	rc = vb6801_i2c_read(REG_VT_LINE_LENGTH_PCK,
+			     &vb6801_ctrl->s_dynamic_params.
+			     preview_pixelsPerLine, 2);
+	if (rc < 0)
+		return rc;
+
+	rc = vb6801_i2c_read(REG_VT_LINE_LENGTH_PCK,
+			     &vb6801_ctrl->s_dynamic_params.
+			     preview_linesPerFrame, 2);
+
+	return rc;
+}
+
+static int32_t vb6801_snapshot_config(int mode, int res)
+{
+	int32_t rc = 0;
+
+	vb6801_ctrl->curr_res = vb6801_ctrl->pict_res;
+	vb6801_ctrl->sensormode = mode;
+
+	rc = vb6801_config_sensor(12, 12, 48, 1, 1, 10, 2, RES_CAPTURE);
+	if (rc < 0)
+		return rc;
+
+	rc = vb6801_i2c_read(REG_VT_LINE_LENGTH_PCK,
+			     &vb6801_ctrl->s_dynamic_params.
+			     snapshot_pixelsPerLine, 2);
+	if (rc < 0)
+		return rc;
+
+	rc = vb6801_i2c_read(REG_VT_LINE_LENGTH_PCK,
+			     &vb6801_ctrl->s_dynamic_params.
+			     snapshot_linesPerFrame, 2);
+
+	return rc;
+}
+
+static int32_t vb6801_set_sensor_mode(int mode, int res)
+{
+	int32_t rc = 0;
+
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		rc = vb6801_video_config(mode, res);
+		break;
+
+	case SENSOR_SNAPSHOT_MODE:
+	case SENSOR_RAW_SNAPSHOT_MODE:
+		rc = vb6801_snapshot_config(mode, res);
+		break;
+
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
+int vb6801_sensor_config(void __user *argp)
+{
+	struct sensor_cfg_data cdata;
+	long rc = 0;
+
+	if (copy_from_user(&cdata,
+			   (void *)argp, sizeof(struct sensor_cfg_data)))
+		return -EFAULT;
+
+	mutex_lock(&vb6801_mut);
+
+	CDBG("vb6801_sensor_config, cfgtype = %d\n", cdata.cfgtype);
+
+	switch (cdata.cfgtype) {
+	case CFG_GET_PICT_FPS:
+		vb6801_get_pict_fps(cdata.cfg.gfps.prevfps,
+				    &(cdata.cfg.gfps.pictfps));
+
+		if (copy_to_user((void *)argp,
+				 &cdata, sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PREV_L_PF:
+		cdata.cfg.prevl_pf = vb6801_get_prev_lines_pf();
+
+		if (copy_to_user((void *)argp,
+				 &cdata, sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PREV_P_PL:
+		cdata.cfg.prevp_pl = vb6801_get_prev_pixels_pl();
+
+		if (copy_to_user((void *)argp,
+				 &cdata, sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_L_PF:
+		cdata.cfg.pictl_pf = vb6801_get_pict_lines_pf();
+
+		if (copy_to_user((void *)argp,
+				 &cdata, sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_P_PL:
+		cdata.cfg.pictp_pl = vb6801_get_pict_pixels_pl();
+
+		if (copy_to_user((void *)argp,
+				 &cdata, sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_MAX_EXP_LC:
+		cdata.cfg.pict_max_exp_lc = vb6801_get_pict_max_exp_lc();
+
+		if (copy_to_user((void *)argp,
+				 &cdata, sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_SET_FPS:
+	case CFG_SET_PICT_FPS:
+		rc = vb6801_set_fps(&(cdata.cfg.fps));
+		break;
+
+	case CFG_SET_EXP_GAIN:
+		rc = vb6801_write_exp_gain(cdata.cfg.exp_gain.gain,
+					   cdata.cfg.exp_gain.line);
+		break;
+
+	case CFG_SET_PICT_EXP_GAIN:
+		rc = vb6801_set_pict_exp_gain(cdata.cfg.exp_gain.gain,
+					      cdata.cfg.exp_gain.line);
+		break;
+
+	case CFG_SET_MODE:
+		rc = vb6801_set_sensor_mode(cdata.mode, cdata.rs);
+		break;
+
+	case CFG_PWR_DOWN:
+		rc = vb6801_power_down();
+		break;
+
+	case CFG_MOVE_FOCUS:
+		rc = vb6801_move_focus(cdata.cfg.focus.dir,
+				       cdata.cfg.focus.steps);
+		break;
+
+	case CFG_SET_DEFAULT_FOCUS:
+		rc = vb6801_set_default_focus();
+		break;
+
+	default:
+		rc = -EFAULT;
+		break;
+	}
+
+	mutex_unlock(&vb6801_mut);
+
+	return rc;
+}
+
+static int vb6801_sensor_release(void)
+{
+	int rc = -EBADF;
+
+	mutex_lock(&vb6801_mut);
+
+	vb6801_power_down();
+	vb6801_sensor_init_done(vb6801_ctrl->sensordata);
+	kfree(vb6801_ctrl);
+	mutex_unlock(&vb6801_mut);
+
+	return rc;
+}
+
+static int vb6801_i2c_probe(struct i2c_client *client,
+			    const struct i2c_device_id *id)
+{
+	int rc = 0;
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		rc = -ENOTSUPP;
+		goto probe_failure;
+	}
+
+	vb6801_sensorw = kzalloc(sizeof(struct vb6801_work_t), GFP_KERNEL);
+
+	if (!vb6801_sensorw) {
+		rc = -ENOMEM;
+		goto probe_failure;
+	}
+
+	i2c_set_clientdata(client, vb6801_sensorw);
+	vb6801_init_client(client);
+	vb6801_client = client;
+	vb6801_client->addr = vb6801_client->addr >> 1;
+
+	return 0;
+
+probe_failure:
+	if (vb6801_sensorw != NULL) {
+		kfree(vb6801_sensorw);
+		vb6801_sensorw = NULL;
+	}
+	return rc;
+}
+
+static int __exit vb6801_i2c_remove(struct i2c_client *client)
+{
+	struct vb6801_work_t *sensorw = i2c_get_clientdata(client);
+	free_irq(client->irq, sensorw);
+	vb6801_client = NULL;
+	kfree(sensorw);
+	return 0;
+}
+
+static const struct i2c_device_id vb6801_i2c_id[] = {
+	{"vb6801", 0},
+	{}
+};
+
+static struct i2c_driver vb6801_i2c_driver = {
+	.id_table = vb6801_i2c_id,
+	.probe = vb6801_i2c_probe,
+	.remove = __exit_p(vb6801_i2c_remove),
+	.driver = {
+		   .name = "vb6801",
+		   },
+};
+
+static int vb6801_probe_init_sensor(const struct msm_camera_sensor_info *data)
+{
+	int rc;
+
+	struct vb6801_i2c_reg_conf_t rreg[] = {
+		{0x0000, 0, 0, D_LEN_BYTE},
+		{0x0001, 0, 0, D_LEN_BYTE},
+	};
+
+	rc = vb6801_reset(data);
+	if (rc < 0)
+		goto init_probe_done;
+
+	mdelay(20);
+
+	rc = vb6801_i2c_read_table(rreg, ARRAY_SIZE(rreg));
+	if (rc < 0) {
+		CDBG("I2C Read Table FAILED!!!\n");
+		goto init_probe_fail;
+	}
+
+	/* 4. Compare sensor ID to VB6801 ID: */
+	if (rreg[0].bdata != 0x03 || rreg[1].bdata != 0x53) {
+		CDBG("vb6801_sensor_init: sensor ID don't match!\n");
+		goto init_probe_fail;
+	}
+
+	goto init_probe_done;
+
+init_probe_fail:
+	vb6801_sensor_init_done(data);
+init_probe_done:
+	return rc;
+}
+
+int vb6801_sensor_open_init(const struct msm_camera_sensor_info *data)
+{
+	int32_t rc;
+	struct vb6801_i2c_reg_conf_t wreg[] = {
+		{REG_MODE_SELECT, 0, STANDBY_MODE, D_LEN_BYTE},
+		{0x0113, 0, 0x0A, D_LEN_BYTE},
+	};
+
+	vb6801_ctrl = kzalloc(sizeof(struct vb6801_ctrl_t), GFP_KERNEL);
+	if (!vb6801_ctrl) {
+		rc = -ENOMEM;
+		goto open_init_fail1;
+	}
+
+	vb6801_ctrl->factor_fps = 1 /** 0x00000400*/ ;
+	vb6801_ctrl->curr_fps = 7680; /* 30 * Q8 */ ;
+	vb6801_ctrl->max_fps = 7680; /* 30 * Q8 */ ;
+	vb6801_ctrl->pict_exp_update = 0; /* 30 * Q8 */ ;
+	vb6801_ctrl->reducel = 0; /* 30 * Q8 */ ;
+
+	vb6801_ctrl->set_test = TEST_OFF;
+	vb6801_ctrl->prev_res = QTR_SIZE;
+	vb6801_ctrl->pict_res = FULL_SIZE;
+
+	vb6801_ctrl->s_dynamic_params.preview_linesPerFrame =
+	    VB6801_LINES_PER_FRAME_PREVIEW;
+	vb6801_ctrl->s_dynamic_params.preview_pixelsPerLine =
+	    VB6801_PIXELS_PER_LINE_PREVIEW;
+	vb6801_ctrl->s_dynamic_params.snapshot_linesPerFrame =
+	    VB6801_LINES_PER_FRAME_SNAPSHOT;
+	vb6801_ctrl->s_dynamic_params.snapshot_pixelsPerLine =
+	    VB6801_PIXELS_PER_LINE_SNAPSHOT;
+
+	if (data)
+		vb6801_ctrl->sensordata = data;
+
+	/* enable mclk first */
+	msm_camio_clk_rate_set(VB6801_DEFAULT_CLOCK_RATE);
+	mdelay(20);
+
+	rc = vb6801_reset(data);
+	if (rc < 0)
+		goto open_init_fail1;
+
+	rc = vb6801_i2c_write_table(wreg, ARRAY_SIZE(wreg));
+	if (rc < 0) {
+		CDBG("I2C Write Table FAILED!!!\n");
+		goto open_init_fail2;
+	}
+
+	rc = vb6801_read_nvm_data(&vb6801_ctrl->s_info);
+	if (rc < 0) {
+		CDBG("vb6801_read_nvm_data FAILED!!!\n");
+		goto open_init_fail2;
+	}
+	mdelay(66);
+
+	rc = vb6801_config_sensor(12, 30, 60, 2, 1, 10, 2, RES_PREVIEW);
+	if (rc < 0)
+		goto open_init_fail2;
+
+	goto open_init_done;
+
+open_init_fail2:
+	vb6801_sensor_init_done(data);
+open_init_fail1:
+	kfree(vb6801_ctrl);
+open_init_done:
+	return rc;
+}
+
+static int vb6801_sensor_probe(const struct msm_camera_sensor_info *info,
+			       struct msm_sensor_ctrl *s)
+{
+	int rc = i2c_add_driver(&vb6801_i2c_driver);
+	if (rc < 0 || vb6801_client == NULL) {
+		rc = -ENOTSUPP;
+		goto probe_done;
+	}
+
+	/* enable mclk first */
+	msm_camio_clk_rate_set(VB6801_DEFAULT_CLOCK_RATE);
+	mdelay(20);
+
+	rc = vb6801_probe_init_sensor(info);
+	if (rc < 0)
+		goto probe_done;
+
+	s->s_init = vb6801_sensor_open_init;
+	s->s_release = vb6801_sensor_release;
+	s->s_config = vb6801_sensor_config;
+	s->s_mount_angle  = 0;
+	vb6801_sensor_init_done(info);
+
+probe_done:
+	return rc;
+}
+
+static int __vb6801_probe(struct platform_device *pdev)
+{
+	return msm_camera_drv_start(pdev, vb6801_sensor_probe);
+}
+
+static struct platform_driver msm_camera_driver = {
+	.probe = __vb6801_probe,
+	.driver = {
+		   .name = "msm_camera_vb6801",
+		   .owner = THIS_MODULE,
+		   },
+};
+
+static int __init vb6801_init(void)
+{
+	return platform_driver_register(&msm_camera_driver);
+}
+
+module_init(vb6801_init);
+void vb6801_exit(void)
+{
+	i2c_del_driver(&vb6801_i2c_driver);
+}
diff --git a/drivers/media/platform/msm/camera_v1/vb6801.h b/drivers/media/platform/msm/camera_v1/vb6801.h
new file mode 100644
index 0000000..5a8842c
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vb6801.h
@@ -0,0 +1,66 @@
+/* Copyright (c) 2008-2009, 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 VB6801_H
+#define VB6801_H
+
+#include <mach/board.h>
+
+extern struct vb6801_reg_t vb6801_regs;	/* from vb6801_reg.c */
+
+struct reg_struct {
+	uint16_t vt_pix_clk_div;	/*  0x0300 */
+	uint16_t vt_sys_clk_div;	/*  0x0302 */
+	uint16_t pre_pll_clk_div;	/*  0x0304 */
+	uint16_t pll_multiplier;	/*  0x0306 */
+	uint16_t op_pix_clk_div;	/*  0x0308 */
+	uint16_t op_sys_clk_div;	/*  0x030A */
+	uint16_t scale_m;	/*  0x0404 */
+	uint16_t row_speed;	/*  0x3016 */
+	uint16_t x_addr_start;	/*  0x3004 */
+	uint16_t x_addr_end;	/*  0x3008 */
+	uint16_t y_addr_start;	/*  0x3002 */
+	uint16_t y_addr_end;	/*  0x3006 */
+	uint16_t read_mode;	/*  0x3040 */
+	uint16_t x_output_size;	/*  0x034C */
+	uint16_t y_output_size;	/*  0x034E */
+	uint16_t line_length_pck;	/*  0x300C */
+	uint16_t frame_length_lines;	/*  0x300A */
+	uint16_t coarse_int_time;	/*  0x3012 */
+	uint16_t fine_int_time;	/*  0x3014 */
+};
+
+enum i2c_data_len {
+	D_LEN_BYTE,
+	D_LEN_WORD
+};
+
+struct vb6801_i2c_reg_conf_t {
+	unsigned short waddr;
+	unsigned short wdata;
+	uint8_t bdata;
+	enum i2c_data_len dlen;
+};
+
+struct vb6801_reg_t {
+	struct reg_struct const *reg_pat;
+	uint16_t reg_pat_size;
+	struct vb6801_i2c_reg_conf_t const *ttbl;
+	uint16_t ttbl_size;
+	struct vb6801_i2c_reg_conf_t const *lctbl;
+	uint16_t lctbl_size;
+	struct vb6801_i2c_reg_conf_t const *rftbl;
+	uint16_t rftbl_size;
+};
+
+#endif /* VB6801_H */
diff --git a/drivers/media/platform/msm/camera_v1/vfe/Makefile b/drivers/media/platform/msm/camera_v1/vfe/Makefile
new file mode 100644
index 0000000..ead1075
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vfe/Makefile
@@ -0,0 +1,20 @@
+GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
+ccflags-y += -Idrivers/media/platform/msm/camera_v1
+ccflags-y += -Idrivers/media/platform/msm/camera_v1/server
+ifeq ($(GCC_VERSION),0404)
+CFLAGS_REMOVE_msm_vfe8x.o = -Wframe-larger-than=1024
+endif
+ifeq ($(CONFIG_MSM_CAMERA_V4L2),y)
+  obj-$(CONFIG_ARCH_MSM7X27A) += msm_vfe7x27a_v4l2.o
+  obj-$(CONFIG_ARCH_MSM8X60) += msm_vfe31_v4l2.o
+  obj-$(CONFIG_ARCH_MSM7X30) += msm_vfe31_v4l2.o
+else
+  obj-$(CONFIG_ARCH_MSM7X27A) += msm_vfe7x27a.o
+  obj-$(CONFIG_ARCH_MSM8X60) += msm_vfe31.o
+  obj-$(CONFIG_ARCH_MSM7X30) += msm_vfe31.o
+endif
+obj-$(CONFIG_ARCH_MSM_ARM11) += msm_vfe7x.o
+obj-$(CONFIG_ARCH_QSD8X50) += msm_vfe8x.o msm_vfe8x_proc.o
+obj-$(CONFIG_ARCH_MSM8960) += msm_vfe32.o
+obj-$(CONFIG_ARCH_MSM8974) += msm_vfe40.o
+obj-$(CONFIG_MSM_CAMERA_V4L2) += msm_vfe_stats_buf.o
diff --git a/drivers/media/platform/msm/camera_v1/vfe/msm_vfe31.c b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe31.c
new file mode 100644
index 0000000..ab92085
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe31.c
@@ -0,0 +1,4012 @@
+/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/uaccess.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <mach/irqs.h>
+#include <mach/camera.h>
+#include <asm/atomic.h>
+
+#include "msm_vfe31.h"
+#include "msm_vpe1.h"
+atomic_t irq_cnt;
+
+static struct vfe31_ctrl_type *vfe31_ctrl;
+static struct msm_camera_io_clk camio_clk;
+static void *vfe_syncdata;
+static void vfe31_send_msg_no_payload(enum VFE31_MESSAGE_ID id);
+static void vfe31_reset_hist_cfg(void);
+
+struct vfe31_isr_queue_cmd {
+	struct list_head list;
+	uint32_t                           vfeInterruptStatus0;
+	uint32_t                           vfeInterruptStatus1;
+	uint32_t                           vfePingPongStatus;
+	struct vfe_frame_asf_info          vfeAsfFrameInfo;
+	struct vfe_frame_bpc_info          vfeBpcFrameInfo;
+	struct vfe_msg_camif_status        vfeCamifStatusLocal;
+};
+
+static struct vfe31_cmd_type vfe31_cmd[] = {
+/* 0*/	{V31_DUMMY_0},
+		{V31_SET_CLK},
+		{V31_RESET},
+		{V31_START},
+		{V31_TEST_GEN_START},
+/* 5*/	{V31_OPERATION_CFG, V31_OPERATION_CFG_LEN},
+		{V31_AXI_OUT_CFG, V31_AXI_OUT_LEN, V31_AXI_OUT_OFF, 0xFF},
+		{V31_CAMIF_CFG, V31_CAMIF_LEN, V31_CAMIF_OFF, 0xFF},
+		{V31_AXI_INPUT_CFG},
+		{V31_BLACK_LEVEL_CFG, V31_BLACK_LEVEL_LEN, V31_BLACK_LEVEL_OFF,
+		0xFF},
+/*10*/  {V31_ROLL_OFF_CFG, V31_ROLL_OFF_CFG_LEN, V31_ROLL_OFF_CFG_OFF,
+		0xFF},
+		{V31_DEMUX_CFG, V31_DEMUX_LEN, V31_DEMUX_OFF, 0xFF},
+		{V31_DEMOSAIC_0_CFG, V31_DEMOSAIC_0_LEN, V31_DEMOSAIC_0_OFF,
+		0xFF},
+		{V31_DEMOSAIC_1_CFG, V31_DEMOSAIC_1_LEN, V31_DEMOSAIC_1_OFF,
+		0xFF},
+		{V31_DEMOSAIC_2_CFG, V31_DEMOSAIC_2_LEN, V31_DEMOSAIC_2_OFF,
+		0xFF},
+/*15*/	{V31_FOV_CFG, V31_FOV_LEN, V31_FOV_OFF, 0xFF},
+		{V31_MAIN_SCALER_CFG, V31_MAIN_SCALER_LEN, V31_MAIN_SCALER_OFF,
+		0xFF},
+		{V31_WB_CFG, V31_WB_LEN, V31_WB_OFF, 0xFF},
+		{V31_COLOR_COR_CFG, V31_COLOR_COR_LEN, V31_COLOR_COR_OFF, 0xFF},
+		{V31_RGB_G_CFG, V31_RGB_G_LEN, V31_RGB_G_OFF, 0xFF},
+/*20*/	{V31_LA_CFG, V31_LA_LEN, V31_LA_OFF, 0xFF },
+		{V31_CHROMA_EN_CFG, V31_CHROMA_EN_LEN, V31_CHROMA_EN_OFF, 0xFF},
+		{V31_CHROMA_SUP_CFG, V31_CHROMA_SUP_LEN, V31_CHROMA_SUP_OFF,
+		0xFF},
+		{V31_MCE_CFG, V31_MCE_LEN, V31_MCE_OFF, 0xFF},
+		{V31_SK_ENHAN_CFG, V31_SCE_LEN, V31_SCE_OFF, 0xFF},
+/*25*/	{V31_ASF_CFG, V31_ASF_LEN, V31_ASF_OFF, 0xFF},
+		{V31_S2Y_CFG, V31_S2Y_LEN, V31_S2Y_OFF, 0xFF},
+		{V31_S2CbCr_CFG, V31_S2CbCr_LEN, V31_S2CbCr_OFF, 0xFF},
+		{V31_CHROMA_SUBS_CFG, V31_CHROMA_SUBS_LEN, V31_CHROMA_SUBS_OFF,
+		0xFF},
+		{V31_OUT_CLAMP_CFG, V31_OUT_CLAMP_LEN, V31_OUT_CLAMP_OFF,
+		0xFF},
+/*30*/	{V31_FRAME_SKIP_CFG, V31_FRAME_SKIP_LEN, V31_FRAME_SKIP_OFF,
+		0xFF},
+		{V31_DUMMY_1},
+		{V31_DUMMY_2},
+		{V31_DUMMY_3},
+		{V31_UPDATE},
+/*35*/	{V31_BL_LVL_UPDATE, V31_BLACK_LEVEL_LEN, V31_BLACK_LEVEL_OFF,
+		0xFF},
+		{V31_DEMUX_UPDATE, V31_DEMUX_LEN, V31_DEMUX_OFF, 0xFF},
+		{V31_DEMOSAIC_1_UPDATE, V31_DEMOSAIC_1_LEN, V31_DEMOSAIC_1_OFF,
+		0xFF},
+		{V31_DEMOSAIC_2_UPDATE, V31_DEMOSAIC_2_LEN, V31_DEMOSAIC_2_OFF,
+		0xFF},
+		{V31_FOV_UPDATE, V31_FOV_LEN, V31_FOV_OFF, 0xFF},
+/*40*/	{V31_MAIN_SCALER_UPDATE, V31_MAIN_SCALER_LEN, V31_MAIN_SCALER_OFF,
+		0xFF},
+		{V31_WB_UPDATE, V31_WB_LEN, V31_WB_OFF, 0xFF},
+		{V31_COLOR_COR_UPDATE, V31_COLOR_COR_LEN, V31_COLOR_COR_OFF,
+		0xFF},
+		{V31_RGB_G_UPDATE, V31_RGB_G_LEN, V31_CHROMA_EN_OFF, 0xFF},
+		{V31_LA_UPDATE, V31_LA_LEN, V31_LA_OFF, 0xFF },
+/*45*/	{V31_CHROMA_EN_UPDATE, V31_CHROMA_EN_LEN, V31_CHROMA_EN_OFF,
+		0xFF},
+		{V31_CHROMA_SUP_UPDATE, V31_CHROMA_SUP_LEN, V31_CHROMA_SUP_OFF,
+		0xFF},
+		{V31_MCE_UPDATE, V31_MCE_LEN, V31_MCE_OFF, 0xFF},
+		{V31_SK_ENHAN_UPDATE, V31_SCE_LEN, V31_SCE_OFF, 0xFF},
+		{V31_S2CbCr_UPDATE, V31_S2CbCr_LEN, V31_S2CbCr_OFF, 0xFF},
+/*50*/	{V31_S2Y_UPDATE, V31_S2Y_LEN, V31_S2Y_OFF, 0xFF},
+		{V31_ASF_UPDATE, V31_ASF_UPDATE_LEN, V31_ASF_OFF, 0xFF},
+		{V31_FRAME_SKIP_UPDATE},
+		{V31_CAMIF_FRAME_UPDATE},
+		{V31_STATS_AF_UPDATE, V31_STATS_AF_LEN, V31_STATS_AF_OFF},
+/*55*/	{V31_STATS_AE_UPDATE, V31_STATS_AE_LEN, V31_STATS_AE_OFF},
+		{V31_STATS_AWB_UPDATE, V31_STATS_AWB_LEN, V31_STATS_AWB_OFF},
+		{V31_STATS_RS_UPDATE, V31_STATS_RS_LEN, V31_STATS_RS_OFF},
+		{V31_STATS_CS_UPDATE, V31_STATS_CS_LEN, V31_STATS_CS_OFF},
+		{V31_STATS_SKIN_UPDATE},
+/*60*/	{V31_STATS_IHIST_UPDATE, V31_STATS_IHIST_LEN, V31_STATS_IHIST_OFF},
+		{V31_DUMMY_4},
+		{V31_EPOCH1_ACK},
+		{V31_EPOCH2_ACK},
+		{V31_START_RECORDING},
+/*65*/	{V31_STOP_RECORDING},
+		{V31_DUMMY_5},
+		{V31_DUMMY_6},
+		{V31_CAPTURE, V31_CAPTURE_LEN, 0xFF},
+		{V31_DUMMY_7},
+/*70*/	{V31_STOP},
+		{V31_GET_HW_VERSION},
+		{V31_GET_FRAME_SKIP_COUNTS},
+		{V31_OUTPUT1_BUFFER_ENQ},
+		{V31_OUTPUT2_BUFFER_ENQ},
+/*75*/	{V31_OUTPUT3_BUFFER_ENQ},
+		{V31_JPEG_OUT_BUF_ENQ},
+		{V31_RAW_OUT_BUF_ENQ},
+		{V31_RAW_IN_BUF_ENQ},
+		{V31_STATS_AF_ENQ},
+/*80*/	{V31_STATS_AE_ENQ},
+		{V31_STATS_AWB_ENQ},
+		{V31_STATS_RS_ENQ},
+		{V31_STATS_CS_ENQ},
+		{V31_STATS_SKIN_ENQ},
+/*85*/	{V31_STATS_IHIST_ENQ},
+		{V31_DUMMY_8},
+		{V31_JPEG_ENC_CFG},
+		{V31_DUMMY_9},
+		{V31_STATS_AF_START, V31_STATS_AF_LEN, V31_STATS_AF_OFF},
+/*90*/	{V31_STATS_AF_STOP},
+		{V31_STATS_AE_START, V31_STATS_AE_LEN, V31_STATS_AE_OFF},
+		{V31_STATS_AE_STOP},
+		{V31_STATS_AWB_START, V31_STATS_AWB_LEN, V31_STATS_AWB_OFF},
+		{V31_STATS_AWB_STOP},
+/*95*/	{V31_STATS_RS_START, V31_STATS_RS_LEN, V31_STATS_RS_OFF},
+		{V31_STATS_RS_STOP},
+		{V31_STATS_CS_START, V31_STATS_CS_LEN, V31_STATS_CS_OFF},
+		{V31_STATS_CS_STOP},
+		{V31_STATS_SKIN_START},
+/*100*/	{V31_STATS_SKIN_STOP},
+		{V31_STATS_IHIST_START,
+		V31_STATS_IHIST_LEN, V31_STATS_IHIST_OFF},
+		{V31_STATS_IHIST_STOP},
+		{V31_DUMMY_10},
+		{V31_SYNC_TIMER_SETTING, V31_SYNC_TIMER_LEN,
+			V31_SYNC_TIMER_OFF},
+/*105*/	{V31_ASYNC_TIMER_SETTING, V31_ASYNC_TIMER_LEN, V31_ASYNC_TIMER_OFF},
+		{V31_LIVESHOT},
+		{V31_ZSL, V31_CAPTURE_LEN, 0xFF},
+		{V31_STEREOCAM},
+		{V31_LA_SETUP},
+/*110*/	{V31_XBAR_CFG, V31_XBAR_CFG_LEN, V31_XBAR_CFG_OFF},
+/*111*/	{V31_EZTUNE_CFG, V31_EZTUNE_CFG_LEN, V31_EZTUNE_CFG_OFF},
+};
+
+uint32_t vfe31_AXI_WM_CFG[] = {
+	0x0000004C,
+	0x00000064,
+	0x0000007C,
+	0x00000094,
+	0x000000AC,
+	0x000000C4,
+	0x000000DC,
+};
+
+static const char *vfe31_general_cmd[] = {
+	"DUMMY_0",  /* 0 */
+	"SET_CLK",
+	"RESET",
+	"START",
+	"TEST_GEN_START",
+	"OPERATION_CFG",  /* 5 */
+	"AXI_OUT_CFG",
+	"CAMIF_CFG",
+	"AXI_INPUT_CFG",
+	"BLACK_LEVEL_CFG",
+	"ROLL_OFF_CFG",  /* 10 */
+	"DEMUX_CFG",
+	"DEMOSAIC_0_CFG",  /* general */
+	"DEMOSAIC_1_CFG",  /* ABF     */
+	"DEMOSAIC_2_CFG",  /* BPC     */
+	"FOV_CFG",  /* 15  */
+	"MAIN_SCALER_CFG",
+	"WB_CFG",
+	"COLOR_COR_CFG",
+	"RGB_G_CFG",
+	"LA_CFG",  /* 20 */
+	"CHROMA_EN_CFG",
+	"CHROMA_SUP_CFG",
+	"MCE_CFG",
+	"SK_ENHAN_CFG",
+	"ASF_CFG",  /* 25 */
+	"S2Y_CFG",
+	"S2CbCr_CFG",
+	"CHROMA_SUBS_CFG",
+	"OUT_CLAMP_CFG",
+	"FRAME_SKIP_CFG",  /* 30 */
+	"DUMMY_1",
+	"DUMMY_2",
+	"DUMMY_3",
+	"UPDATE",
+	"BL_LVL_UPDATE",  /* 35 */
+	"DEMUX_UPDATE",
+	"DEMOSAIC_1_UPDATE",  /* BPC */
+	"DEMOSAIC_2_UPDATE",  /* ABF */
+	"FOV_UPDATE",
+	"MAIN_SCALER_UPDATE",  /* 40 */
+	"WB_UPDATE",
+	"COLOR_COR_UPDATE",
+	"RGB_G_UPDATE",
+	"LA_UPDATE",
+	"CHROMA_EN_UPDATE",  /* 45 */
+	"CHROMA_SUP_UPDATE",
+	"MCE_UPDATE",
+	"SK_ENHAN_UPDATE",
+	"S2CbCr_UPDATE",
+	"S2Y_UPDATE",  /* 50 */
+	"ASF_UPDATE",
+	"FRAME_SKIP_UPDATE",
+	"CAMIF_FRAME_UPDATE",
+	"STATS_AF_UPDATE",
+	"STATS_AE_UPDATE",  /* 55 */
+	"STATS_AWB_UPDATE",
+	"STATS_RS_UPDATE",
+	"STATS_CS_UPDATE",
+	"STATS_SKIN_UPDATE",
+	"STATS_IHIST_UPDATE",  /* 60 */
+	"DUMMY_4",
+	"EPOCH1_ACK",
+	"EPOCH2_ACK",
+	"START_RECORDING",
+	"STOP_RECORDING",  /* 65 */
+	"DUMMY_5",
+	"DUMMY_6",
+	"CAPTURE",
+	"DUMMY_7",
+	"STOP",  /* 70 */
+	"GET_HW_VERSION",
+	"GET_FRAME_SKIP_COUNTS",
+	"OUTPUT1_BUFFER_ENQ",
+	"OUTPUT2_BUFFER_ENQ",
+	"OUTPUT3_BUFFER_ENQ",  /* 75 */
+	"JPEG_OUT_BUF_ENQ",
+	"RAW_OUT_BUF_ENQ",
+	"RAW_IN_BUF_ENQ",
+	"STATS_AF_ENQ",
+	"STATS_AE_ENQ",  /* 80 */
+	"STATS_AWB_ENQ",
+	"STATS_RS_ENQ",
+	"STATS_CS_ENQ",
+	"STATS_SKIN_ENQ",
+	"STATS_IHIST_ENQ",  /* 85 */
+	"DUMMY_8",
+	"JPEG_ENC_CFG",
+	"DUMMY_9",
+	"STATS_AF_START",
+	"STATS_AF_STOP",  /* 90 */
+	"STATS_AE_START",
+	"STATS_AE_STOP",
+	"STATS_AWB_START",
+	"STATS_AWB_STOP",
+	"STATS_RS_START",  /* 95 */
+	"STATS_RS_STOP",
+	"STATS_CS_START",
+	"STATS_CS_STOP",
+	"STATS_SKIN_START",
+	"STATS_SKIN_STOP",  /* 100 */
+	"STATS_IHIST_START",
+	"STATS_IHIST_STOP",
+	"DUMMY_10",
+	"SYNC_TIMER_SETTING",
+	"ASYNC_TIMER_SETTING",  /* 105 */
+	"V31_LIVESHOT",
+	"V31_ZSL",
+	"V31_STEREOCAM",
+	"V31_LA_SETUP",
+	"V31_XBAR_CFG",
+};
+
+static void vfe_addr_convert(struct msm_vfe_phy_info *pinfo,
+	enum vfe_resp_msg type, void *data, void **ext, int32_t *elen)
+{
+	uint8_t outid;
+	switch (type) {
+	case VFE_MSG_OUTPUT_T:
+	case VFE_MSG_OUTPUT_P:
+	case VFE_MSG_OUTPUT_S:
+	case VFE_MSG_OUTPUT_V:
+	{
+		pinfo->output_id =
+			((struct vfe_message *)data)->_u.msgOut.output_id;
+
+		switch (type) {
+		case VFE_MSG_OUTPUT_P:
+			outid = OUTPUT_TYPE_P;
+			break;
+		case VFE_MSG_OUTPUT_V:
+			outid = OUTPUT_TYPE_V;
+			break;
+		case VFE_MSG_OUTPUT_T:
+			outid = OUTPUT_TYPE_T;
+			break;
+		case VFE_MSG_OUTPUT_S:
+			outid = OUTPUT_TYPE_S;
+			break;
+		default:
+			outid = 0xff;
+			break;
+		}
+		pinfo->output_id = outid;
+		pinfo->p0_phy =
+			((struct vfe_message *)data)->_u.msgOut.p0_addr;
+		pinfo->p1_phy =
+			((struct vfe_message *)data)->_u.msgOut.p1_addr;
+		pinfo->p2_phy =
+			((struct vfe_message *)data)->_u.msgOut.p2_addr;
+
+		pinfo->frame_id =
+		((struct vfe_message *)data)->_u.msgOut.frameCounter;
+
+		((struct vfe_msg_output *)(vfe31_ctrl->extdata))->bpcInfo =
+		((struct vfe_message *)data)->_u.msgOut.bpcInfo;
+		((struct vfe_msg_output *)(vfe31_ctrl->extdata))->asfInfo =
+		((struct vfe_message *)data)->_u.msgOut.asfInfo;
+		((struct vfe_msg_output *)(vfe31_ctrl->extdata))->frameCounter =
+		((struct vfe_message *)data)->_u.msgOut.frameCounter;
+		*ext  = vfe31_ctrl->extdata;
+		*elen = vfe31_ctrl->extlen;
+	}
+		break;
+
+	default:
+		break;
+	} /* switch */
+}
+
+
+static void vfe31_proc_ops(enum VFE31_MESSAGE_ID id, void *msg, size_t len)
+{
+	struct msm_vfe_resp *rp;
+
+	rp = vfe31_ctrl->resp->vfe_alloc(sizeof(struct msm_vfe_resp),
+		vfe31_ctrl->syncdata, GFP_ATOMIC);
+	if (!rp) {
+		CDBG("rp: cannot allocate buffer\n");
+		return;
+	}
+	CDBG("vfe31_proc_ops, msgId = %d\n", id);
+	rp->evt_msg.type   = MSM_CAMERA_MSG;
+	rp->evt_msg.msg_id = id;
+	rp->evt_msg.len    = len;
+	rp->evt_msg.data   = msg;
+
+	switch (rp->evt_msg.msg_id) {
+	case MSG_ID_SNAPSHOT_DONE:
+		rp->type = VFE_MSG_SNAPSHOT;
+		break;
+
+	case MSG_ID_OUTPUT_P:
+		rp->type = VFE_MSG_OUTPUT_P;
+		vfe_addr_convert(&(rp->phy), VFE_MSG_OUTPUT_P,
+			rp->evt_msg.data, &(rp->extdata),
+			&(rp->extlen));
+		break;
+
+	case MSG_ID_OUTPUT_T:
+		rp->type = VFE_MSG_OUTPUT_T;
+		vfe_addr_convert(&(rp->phy), VFE_MSG_OUTPUT_T,
+			rp->evt_msg.data, &(rp->extdata),
+			&(rp->extlen));
+		break;
+
+	case MSG_ID_OUTPUT_S:
+		rp->type = VFE_MSG_OUTPUT_S;
+		vfe_addr_convert(&(rp->phy), VFE_MSG_OUTPUT_S,
+			rp->evt_msg.data, &(rp->extdata),
+			&(rp->extlen));
+		break;
+
+	case MSG_ID_OUTPUT_V:
+		rp->type = VFE_MSG_OUTPUT_V;
+		vfe_addr_convert(&(rp->phy), VFE_MSG_OUTPUT_V,
+			rp->evt_msg.data, &(rp->extdata),
+			&(rp->extlen));
+		break;
+
+	case MSG_ID_COMMON:
+		rp->type = VFE_MSG_COMMON;
+		rp->stats_msg.status_bits = ((struct vfe_message *)
+			rp->evt_msg.data)->_u.msgStats.status_bits;
+		rp->stats_msg.frame_id = ((struct vfe_message *)
+			rp->evt_msg.data)->_u.msgStats.frameCounter;
+
+		rp->stats_msg.aec_buff = ((struct vfe_message *)
+			rp->evt_msg.data)->_u.msgStats.buff.aec;
+		rp->stats_msg.awb_buff = ((struct vfe_message *)
+			rp->evt_msg.data)->_u.msgStats.buff.awb;
+		rp->stats_msg.af_buff = ((struct vfe_message *)
+			rp->evt_msg.data)->_u.msgStats.buff.af;
+		rp->stats_msg.ihist_buff = ((struct vfe_message *)
+			rp->evt_msg.data)->_u.msgStats.buff.ihist;
+		rp->stats_msg.rs_buff = ((struct vfe_message *)
+			rp->evt_msg.data)->_u.msgStats.buff.rs;
+		rp->stats_msg.cs_buff = ((struct vfe_message *)
+			rp->evt_msg.data)->_u.msgStats.buff.cs;
+		rp->stats_msg.awb_ymin = ((struct vfe_message *)
+			rp->evt_msg.data)->_u.msgStats.buff.awb_ymin;
+		break;
+
+	case MSG_ID_SYNC_TIMER0_DONE:
+		rp->type = VFE_MSG_SYNC_TIMER0;
+		break;
+
+	case MSG_ID_SYNC_TIMER1_DONE:
+		rp->type = VFE_MSG_SYNC_TIMER1;
+		break;
+
+	case MSG_ID_SYNC_TIMER2_DONE:
+		rp->type = VFE_MSG_SYNC_TIMER2;
+		break;
+
+	default:
+		rp->type = VFE_MSG_GENERAL;
+		break;
+	}
+
+	/* save the frame id.*/
+	rp->evt_msg.frame_id = rp->phy.frame_id;
+
+	vfe31_ctrl->resp->vfe_resp(rp, MSM_CAM_Q_VFE_MSG, vfe31_ctrl->syncdata,
+		GFP_ATOMIC);
+}
+
+static void vfe_send_outmsg(uint8_t msgid, uint32_t p0_addr,
+	uint32_t p1_addr, uint32_t p2_addr)
+{
+	struct vfe_message msg;
+	uint8_t outid;
+
+	msg._d = msgid;   /* now the output mode is redundnat. */
+	msg._u.msgOut.frameCounter = vfe31_ctrl->vfeFrameId;
+
+	switch (msgid) {
+	case MSG_ID_OUTPUT_P:
+		outid = OUTPUT_TYPE_P;
+		break;
+	case MSG_ID_OUTPUT_V:
+		outid = OUTPUT_TYPE_V;
+		break;
+	case MSG_ID_OUTPUT_T:
+		outid = OUTPUT_TYPE_T;
+		break;
+	case MSG_ID_OUTPUT_S:
+		outid = OUTPUT_TYPE_S;
+		break;
+	default:
+		outid = 0xff;  /* -1 for error condition.*/
+		break;
+	}
+	msg._u.msgOut.output_id   = msgid;
+	msg._u.msgOut.p0_addr     = p0_addr;
+	msg._u.msgOut.p1_addr     = p1_addr;
+	msg._u.msgOut.p2_addr     = p2_addr;
+	CDBG("%s p2_addr = 0x%x\n", __func__, p2_addr);
+	vfe31_proc_ops(msgid, &msg, sizeof(struct vfe_message));
+	return;
+}
+static int vfe31_enable(struct camera_enable_cmd *enable)
+{
+	return 0;
+}
+
+static void vfe31_stop(void)
+{
+	atomic_set(&vfe31_ctrl->vstate, 0);
+	atomic_set(&vfe31_ctrl->stop_ack_pending, 1);
+
+	/* in either continuous or snapshot mode, stop command can be issued
+	 * at any time. stop camif immediately. */
+	msm_camera_io_w_mb(CAMIF_COMMAND_STOP_IMMEDIATELY,
+		vfe31_ctrl->vfebase + VFE_CAMIF_COMMAND);
+
+	/* disable all interrupts.  */
+	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
+		vfe31_ctrl->vfebase + VFE_IRQ_MASK_0);
+	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
+		vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+	/* clear all pending interrupts*/
+	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
+		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_0);
+	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
+		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_1);
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_camera_io_w_mb(1,
+		vfe31_ctrl->vfebase + VFE_IRQ_CMD);
+
+	/* now enable only halt_irq & reset_irq */
+	msm_camera_io_w(0xf0000000,          /* this is for async timer. */
+		vfe31_ctrl->vfebase + VFE_IRQ_MASK_0);
+	msm_camera_io_w(VFE_IMASK_AXI_HALT,
+		vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+	/* then apply axi halt command. */
+	msm_camera_io_w_mb(AXI_HALT,
+		vfe31_ctrl->vfebase + VFE_AXI_CMD);
+}
+
+static int vfe31_disable(struct camera_enable_cmd *enable,
+	struct platform_device *dev)
+{
+	msm_camio_set_perf_lvl(S_EXIT);
+	msm_camio_disable(dev);
+	return 0;
+}
+
+static int vfe31_add_free_buf2(struct vfe31_output_ch *outch,
+	uint32_t paddr, uint32_t p0_off, uint32_t p1_off, uint32_t p2_off)
+{
+	struct vfe31_free_buf *free_buf = NULL;
+	unsigned long flags = 0;
+	free_buf = kmalloc(sizeof(struct vfe31_free_buf), GFP_KERNEL);
+	if (!free_buf)
+		return -ENOMEM;
+
+	spin_lock_irqsave(&outch->free_buf_lock, flags);
+	free_buf->paddr = paddr;
+	free_buf->planar0_off = p0_off;
+	free_buf->planar1_off = p1_off;
+	free_buf->planar2_off = p2_off;
+	list_add_tail(&free_buf->node, &outch->free_buf_head);
+
+	CDBG("%s: free_buf paddr = 0x%x, y_off = %d, cbcr_off = %d\n",
+		__func__, free_buf->paddr, free_buf->planar0_off,
+		free_buf->planar1_off);
+	spin_unlock_irqrestore(&outch->free_buf_lock, flags);
+	return 0;
+}
+
+#define vfe31_add_free_buf(outch, regptr) \
+	vfe31_add_free_buf2(outch, regptr->paddr, \
+	regptr->info.planar0_off,	\
+	regptr->info.planar1_off,	\
+	regptr->info.planar2_off)
+
+#define vfe31_free_buf_available(outch) \
+	(!list_empty(&outch.free_buf_head))
+
+static inline struct vfe31_free_buf *vfe31_get_free_buf(
+	struct vfe31_output_ch *outch)
+{
+	unsigned long flags = 0;
+	struct vfe31_free_buf *free_buf = NULL;
+	spin_lock_irqsave(&outch->free_buf_lock, flags);
+	if (!list_empty(&outch->free_buf_head)) {
+		free_buf = list_first_entry(&outch->free_buf_head,
+			struct vfe31_free_buf, node);
+		if (free_buf)
+			list_del_init(&free_buf->node);
+	}
+	spin_unlock_irqrestore(&outch->free_buf_lock, flags);
+	return free_buf;
+}
+
+static inline void vfe31_reset_free_buf_queue(
+	struct vfe31_output_ch *outch)
+{
+	unsigned long flags = 0;
+	struct vfe31_free_buf *free_buf = NULL;
+	spin_lock_irqsave(&outch->free_buf_lock, flags);
+	while (!list_empty(&outch->free_buf_head)) {
+		free_buf = list_first_entry(&outch->free_buf_head,
+			struct vfe31_free_buf, node);
+		if (free_buf) {
+			list_del_init(&free_buf->node);
+			kfree(free_buf);
+		}
+	}
+	spin_unlock_irqrestore(&outch->free_buf_lock, flags);
+}
+
+#define vfe31_init_free_buf_queue() do {	\
+	INIT_LIST_HEAD(&vfe31_ctrl->outpath.out0.free_buf_head);	\
+	INIT_LIST_HEAD(&vfe31_ctrl->outpath.out1.free_buf_head);	\
+	INIT_LIST_HEAD(&vfe31_ctrl->outpath.out2.free_buf_head);	\
+	spin_lock_init(&vfe31_ctrl->outpath.out0.free_buf_lock);	\
+	spin_lock_init(&vfe31_ctrl->outpath.out1.free_buf_lock);	\
+	spin_lock_init(&vfe31_ctrl->outpath.out2.free_buf_lock);	\
+} while (0)
+
+#define vfe31_reset_free_buf_queue_all() do {	\
+	vfe31_reset_free_buf_queue(&vfe31_ctrl->outpath.out0);	\
+	vfe31_reset_free_buf_queue(&vfe31_ctrl->outpath.out1);	\
+	vfe31_reset_free_buf_queue(&vfe31_ctrl->outpath.out2);	\
+} while (0)
+
+static int vfe31_config_axi(int mode, struct axidata *ad, uint32_t *ao)
+{
+	int i;
+	uint32_t *p, *p1, *p2, *p3;
+	int32_t *ch_info;
+	struct vfe31_output_ch *outp1, *outp2, *outp3;
+	struct msm_pmem_region *regp1 = NULL;
+	struct msm_pmem_region *regp2 = NULL;
+	struct msm_pmem_region *regp3 = NULL;
+	int ret;
+	struct msm_sync* p_sync = (struct msm_sync *)vfe_syncdata;
+
+	outp1 = NULL;
+	outp2 = NULL;
+	outp3 = NULL;
+
+	p = ao + 2;
+
+	/* Update the corresponding write masters for each output*/
+	ch_info = ao + V31_AXI_CFG_LEN;
+	vfe31_ctrl->outpath.out0.ch0 = 0x0000FFFF & *ch_info;
+	vfe31_ctrl->outpath.out0.ch1 = 0x0000FFFF & (*ch_info++ >> 16);
+	vfe31_ctrl->outpath.out0.ch2 = 0x0000FFFF & *ch_info++;
+	vfe31_ctrl->outpath.out1.ch0 = 0x0000FFFF & *ch_info;
+	vfe31_ctrl->outpath.out1.ch1 = 0x0000FFFF & (*ch_info++ >> 16);
+	vfe31_ctrl->outpath.out1.ch2 = 0x0000FFFF & *ch_info++;
+	vfe31_ctrl->outpath.out2.ch0 = 0x0000FFFF & *ch_info;
+	vfe31_ctrl->outpath.out2.ch1 = 0x0000FFFF & (*ch_info++ >> 16);
+	vfe31_ctrl->outpath.out2.ch2 = 0x0000FFFF & *ch_info++;
+
+	CDBG("vfe31_config_axi: mode = %d, bufnum1 = %d, bufnum2 = %d"
+		"bufnum3 = %d", mode, ad->bufnum1, ad->bufnum2, ad->bufnum3);
+
+	switch (mode) {
+
+	case OUTPUT_2: {
+		if (ad->bufnum2 != 3)
+			return -EINVAL;
+		regp1 = &(ad->region[ad->bufnum1]);
+		outp1 = &(vfe31_ctrl->outpath.out0);
+		vfe31_ctrl->outpath.output_mode |= VFE31_OUTPUT_MODE_PT;
+
+		for (i = 0; i < 2; i++) {
+			p1 = ao + 6 + i;    /* wm0 for y  */
+			*p1 = (regp1->paddr + regp1->info.planar0_off);
+
+			p1 = ao + 12 + i;  /* wm1 for cbcr */
+			*p1 = (regp1->paddr + regp1->info.planar1_off);
+			regp1++;
+		}
+		ret = vfe31_add_free_buf(outp1, regp1);
+		if (ret < 0)
+			return ret;
+	}
+		break;
+
+	case OUTPUT_1_AND_2:
+		/* use wm0& 4 for thumbnail, wm1&5 for main image.*/
+		if ((ad->bufnum1 < 1) || (ad->bufnum2 < 1))
+			return -EINVAL;
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_S;  /* main image.*/
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_PT;  /* thumbnail. */
+
+		/* this is thumbnail buffer. */
+		regp1 = &(ad->region[ad->bufnum1-1]);
+		/* this is main image buffer. */
+		regp2 = &(ad->region[ad->bufnum1+ad->bufnum2-1]);
+
+		outp1 = &(vfe31_ctrl->outpath.out0);
+		outp2 = &(vfe31_ctrl->outpath.out1); /* snapshot */
+
+		/*  Parse the buffers!!! */
+		if (ad->bufnum2 == 1) {	/* assuming bufnum1 = bufnum2 */
+			p1 = ao + 6;   /* wm0 ping */
+			*p1++ = (regp1->paddr + regp1->info.planar0_off);
+
+			/* this is to duplicate ping address to pong.*/
+			*p1 = (regp1->paddr + regp1->info.planar0_off);
+
+			p1 = ao + 30;  /* wm4 ping */
+			*p1++ = (regp1->paddr + regp1->info.planar1_off);
+			CDBG("%s: regp1->info.cbcr_off = 0x%x\n", __func__,
+						 regp1->info.planar1_off);
+
+			/* this is to duplicate ping address to pong.*/
+			*p1 = (regp1->paddr + regp1->info.planar1_off);
+
+			p1 = ao + 12;   /* wm1 ping */
+			*p1++ = (regp2->paddr + regp2->info.planar0_off);
+
+			/* pong = ping,*/
+			*p1 = (regp2->paddr + regp2->info.planar0_off);
+
+			p1 = ao + 36;  /* wm5 */
+			*p1++ = (regp2->paddr + regp2->info.planar1_off);
+			CDBG("%s: regp2->info.cbcr_off = 0x%x\n", __func__,
+						 regp2->info.planar1_off);
+
+			/* pong = ping,*/
+			*p1 = (regp2->paddr + regp2->info.planar1_off);
+		} else { /* more than one snapshot */
+			/* first fill ping & pong */
+			for (i = 0; i < 2; i++) {
+				p1 = ao + 6 + i;    /* wm0 for y  */
+				*p1 = (regp1->paddr + regp1->info.planar0_off);
+				p1 = ao + 30 + i;  /* wm4 for cbcr */
+				*p1 = (regp1->paddr + regp1->info.planar1_off);
+				regp1--;
+			}
+
+			for (i = 0; i < 2; i++) {
+				p2 = ao + 12 + i;    /* wm1 for y  */
+				*p2 = (regp2->paddr + regp2->info.planar0_off);
+				p2 = ao + 36 + i;  /* wm5 for cbcr */
+				*p2 = (regp2->paddr + regp2->info.planar1_off);
+				regp2--;
+			}
+
+			for (i = 2; i < ad->bufnum1; i++) {
+				ret = vfe31_add_free_buf(outp1, regp1);
+				if (ret < 0)
+					return ret;
+				regp1--;
+			}
+
+			for (i = 2; i < ad->bufnum2; i++) {
+				ret = vfe31_add_free_buf(outp2, regp2);
+				if (ret < 0)
+					return ret;
+				regp2--;
+			}
+		}
+		break;
+
+	case OUTPUT_1_2_AND_3:
+		CDBG("%s: OUTPUT_1_2_AND_3", __func__);
+		CDBG("%s: %d %d %d", __func__, ad->bufnum1, ad->bufnum2,
+			ad->bufnum3);
+		/* use wm0& 4 for postview, wm1&5 for preview.*/
+		/* use wm2& 6 for main img */
+		if ((ad->bufnum1 < 1) || (ad->bufnum2 < 1) || (ad->bufnum3 < 1))
+			return -EINVAL;
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_S;  /* main image.*/
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_P;  /* preview. */
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_T;  /* thumbnail. */
+
+		/* this is preview buffer. */
+		regp1 = &(ad->region[0]);
+		/* this is thumbnail buffer. */
+		regp2 = &(ad->region[ad->bufnum1]);
+		/* this is main image buffer. */
+		regp3 = &(ad->region[ad->bufnum1+ad->bufnum2]);
+		outp1 = &(vfe31_ctrl->outpath.out0);
+		outp2 = &(vfe31_ctrl->outpath.out1);
+		outp3 = &(vfe31_ctrl->outpath.out2);
+
+		/*  Parse the buffers!!! */
+		/* first fill ping & pong */
+		for (i = 0; i < 2; i++) {
+			p1 = ao + 6 + i;    /* wm0 for y  */
+			*p1 = (regp1->paddr + regp1->info.planar0_off);
+			p1 = ao + 30 + i;  /* wm4 for cbcr */
+			*p1 = (regp1->paddr + regp1->info.planar1_off);
+			regp1++;
+		}
+
+		for (i = 0; i < 2; i++) {
+			p2 = ao + 12 + i;    /* wm1 for y  */
+			*p2 = (regp2->paddr + regp2->info.planar0_off);
+			p2 = ao + 36 + i;  /* wm5 for cbcr */
+			*p2 = (regp2->paddr + regp2->info.planar1_off);
+			regp2++;
+		}
+
+		for (i = 0; i < 2; i++) {
+			p3 = ao + 18 + i;    /* wm2 for y  */
+			*p3 = (regp3->paddr + regp3->info.planar0_off);
+			p3 = ao + 42 + i;  /* wm6 for cbcr */
+			*p3 = (regp3->paddr + regp3->info.planar1_off);
+			regp3++;
+		}
+
+		for (i = 2; i < ad->bufnum1; i++) {
+			ret = vfe31_add_free_buf(outp1, regp1);
+			if (ret < 0)
+				return ret;
+			regp1++;
+		}
+
+		for (i = 2; i < ad->bufnum2; i++) {
+			ret = vfe31_add_free_buf(outp2, regp2);
+			if (ret < 0)
+				return ret;
+			regp2++;
+		}
+
+		for (i = 2; i < ad->bufnum3; i++) {
+			ret = vfe31_add_free_buf(outp3, regp3);
+			if (ret < 0)
+				return ret;
+			regp3++;
+		}
+		break;
+
+	case OUTPUT_ZSL_ALL_CHNLS:
+		CDBG("%s: OUTPUT_ZSL_ALL_CHNLS", __func__);
+		CDBG("%s: %d %d %d", __func__, ad->bufnum1, ad->bufnum2,
+			ad->bufnum3);
+		/* use wm0& 4 for postview, wm1&5 for preview.*/
+		/* use wm2& 6 for main img */
+		if ((ad->bufnum1 < 1) || (ad->bufnum2 < 1) || (ad->bufnum3 < 1))
+			return -EINVAL;
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_S;  /* main image.*/
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_P_ALL_CHNLS;  /* preview. */
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_T;  /* thumbnail. */
+
+		/* this is preview buffer. */
+		regp1 = &(ad->region[0]);
+		/* this is thumbnail buffer. */
+		regp2 = &(ad->region[ad->bufnum1]);
+		/* this is main image buffer. */
+		regp3 = &(ad->region[ad->bufnum1+ad->bufnum2]);
+		outp1 = &(vfe31_ctrl->outpath.out0);
+		outp2 = &(vfe31_ctrl->outpath.out1);
+		outp3 = &(vfe31_ctrl->outpath.out2);
+
+		/*  Parse the buffers!!! */
+		/* first fill ping & pong */
+		for (i = 0; i < 2; i++) {
+			p1 = ao + 6 + i;    /* wm0 for y  */
+			*p1 = (regp2->paddr + regp2->info.planar0_off);
+			p1 = ao + 12 + i;  /* wm1 for cbcr */
+			*p1 = (regp2->paddr + regp2->info.planar1_off);
+			regp2++;
+		}
+
+		for (i = 0; i < 2; i++) {
+			p2 = ao + 30 + i;    /* wm4 for y  */
+			*p2 = (regp1->paddr + regp1->info.planar0_off);
+			p2 = ao + 36 + i;  /* wm5 for cbcr */
+			*p2 = (regp1->paddr + regp1->info.planar1_off);
+			p2 = ao + 42 + i;  /* wm5 for cbcr */
+			*p2 = (regp1->paddr + regp1->info.planar2_off);
+			regp1++;
+		}
+
+		for (i = 0; i < 2; i++) {
+			p3 = ao + 18 + i;    /* wm2 for y  */
+			*p3 = (regp3->paddr + regp3->info.planar0_off);
+			p3 = ao + 24 + i;  /* wm3 for cbcr */
+			*p3 = (regp3->paddr + regp3->info.planar1_off);
+			regp3++;
+		}
+		for (i = 2; i < ad->bufnum1; i++) {
+			ret = vfe31_add_free_buf(outp1, regp1);
+			if (ret < 0)
+				return ret;
+			regp1++;
+		}
+
+		for (i = 2; i < ad->bufnum2; i++) {
+			ret = vfe31_add_free_buf(outp2, regp2);
+			if (ret < 0)
+				return ret;
+			regp2++;
+		}
+
+		for (i = 2; i < ad->bufnum3; i++) {
+			ret = vfe31_add_free_buf(outp3, regp3);
+			if (ret < 0)
+				return ret;
+			regp3++;
+		}
+		break;
+
+	case OUTPUT_1_AND_3: {
+		/* use wm0&4 for preview, wm1&5 for video.*/
+		if ((ad->bufnum1 < 2) || (ad->bufnum2 < 2))
+			return -EINVAL;
+
+#ifdef CONFIG_MSM_CAMERA_V4L2
+		*p++ = 0x1;    /* xbar cfg0 */
+		*p = 0x1a03;    /* xbar cfg1 */
+#endif
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_V;  /* video*/
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_PT;  /* preview */
+
+		regp1 = &(ad->region[0]); /* this is preview buffer. */
+		regp2 = &(ad->region[ad->bufnum1]);/* this is video buffer. */
+		outp1 = &(vfe31_ctrl->outpath.out0); /* preview */
+		outp2 = &(vfe31_ctrl->outpath.out2); /* video */
+
+
+		for (i = 0; i < 2; i++) {
+			p1 = ao + 6 + i;    /* wm0 for y  */
+			*p1 = (regp1->paddr + regp1->info.planar0_off);
+
+			p1 = ao + 30 + i;  /* wm4 for cbcr */
+			*p1 = (regp1->paddr + regp1->info.planar1_off);
+			regp1++;
+		}
+
+		for (i = 0; i < 2; i++) {
+			p2 = ao + 12 + i;    /* wm1 for y  */
+			*p2 = (regp2->paddr + regp2->info.planar0_off);
+
+			p2 = ao + 36 + i;  /* wm5 for cbcr */
+			*p2 = (regp2->paddr + regp2->info.planar1_off);
+			regp2++;
+		}
+		for (i = 2; i < ad->bufnum1; i++) {
+			ret = vfe31_add_free_buf(outp1, regp1);
+			if (ret < 0)
+				return ret;
+			regp1++;
+		}
+
+		for (i = 2; i < ad->bufnum2; i++) {
+			ret = vfe31_add_free_buf(outp2, regp2);
+			if (ret < 0)
+				return ret;
+			regp2++;
+		}
+	}
+		break;
+
+	case OUTPUT_VIDEO_ALL_CHNLS: {
+		/* use wm0&4 for preview, wm1&5 for video.*/
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_V;  /* video*/
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_P_ALL_CHNLS;
+		regp1 = &(ad->region[0]);
+		regp2 = &(ad->region[ad->bufnum1]);
+		outp1 = &(vfe31_ctrl->outpath.out0);
+		outp2 = &(vfe31_ctrl->outpath.out2);
+
+		for (i = 0; i < 2; i++) {
+			p1 = ao + 6 + i;    /* wm0 for y  */
+			*p1 = (regp1->paddr + regp1->info.planar0_off);
+
+			p1 = ao + 12 + i;  /* wm1 for cbcr */
+			*p1 = (regp1->paddr + regp1->info.planar1_off);
+
+			p1 = ao + 18 + i;  /* wm2 for cbcr */
+			*p1 = (regp1->paddr + regp1->info.planar2_off);
+			regp1++;
+		}
+		for (i = 0; i < 2; i++) {
+			p2 = ao + 30 + i;    /* wm4 for y  */
+			*p2 = (regp2->paddr + regp2->info.planar0_off);
+
+			p2 = ao + 36 + i;  /* wm5 for cbcr */
+			*p2 = (regp2->paddr + regp2->info.planar1_off);
+			regp2++;
+		}
+		for (i = 2; i < ad->bufnum1; i++) {
+			ret = vfe31_add_free_buf(outp1, regp1);
+			if (ret < 0)
+				return ret;
+			regp1++;
+		}
+		for (i = 2; i < ad->bufnum2; i++) {
+			ret = vfe31_add_free_buf(outp2, regp2);
+			if (ret < 0)
+				return ret;
+			regp2++;
+		}
+	}
+		break;
+
+	case CAMIF_TO_AXI_VIA_OUTPUT_2: {  /* use wm0 only */
+		if (ad->bufnum2 < 1)
+			return -EINVAL;
+		CDBG("config axi for raw snapshot.\n");
+		vfe31_ctrl->outpath.out1.ch0 = 0; /* raw */
+		regp1 = &(ad->region[ad->bufnum1]);
+		vfe31_ctrl->outpath.output_mode |= VFE31_OUTPUT_MODE_S;
+		p1 = ao + 6;    /* wm0 for y  */
+		*p1 = (regp1->paddr + regp1->info.planar0_off);
+		if (p_sync->stereocam_enabled)
+			p_sync->stereo_state = STEREO_RAW_SNAP_IDLE;
+	}
+		break;
+	default:
+		break;
+	}
+	msm_camera_io_memcpy(
+		vfe31_ctrl->vfebase + vfe31_cmd[V31_AXI_OUT_CFG].offset,
+		ao, vfe31_cmd[V31_AXI_OUT_CFG].length - V31_AXI_CH_INF_LEN);
+
+	return 0;
+}
+
+static void vfe31_reset_internal_variables(void)
+{
+	unsigned long flags;
+	vfe31_ctrl->vfeImaskCompositePacked = 0;
+	/* state control variables */
+	vfe31_ctrl->start_ack_pending = FALSE;
+	atomic_set(&irq_cnt, 0);
+
+	spin_lock_irqsave(&vfe31_ctrl->xbar_lock, flags);
+	vfe31_ctrl->xbar_update_pending = 0;
+	spin_unlock_irqrestore(&vfe31_ctrl->xbar_lock, flags);
+
+	atomic_set(&vfe31_ctrl->stop_ack_pending, 0);
+	atomic_set(&vfe31_ctrl->vstate, 0);
+
+	vfe31_ctrl->aec_ack_pending = FALSE;
+	vfe31_ctrl->af_ack_pending = FALSE;
+	vfe31_ctrl->awb_ack_pending = FALSE;
+	vfe31_ctrl->ihist_ack_pending = FALSE;
+	vfe31_ctrl->rs_ack_pending = FALSE;
+	vfe31_ctrl->cs_ack_pending = FALSE;
+
+	vfe31_ctrl->reset_ack_pending  = FALSE;
+
+	spin_lock_irqsave(&vfe31_ctrl->update_ack_lock, flags);
+	vfe31_ctrl->update_ack_pending = FALSE;
+	spin_unlock_irqrestore(&vfe31_ctrl->update_ack_lock, flags);
+
+	vfe31_ctrl->recording_state = VFE_REC_STATE_IDLE;
+
+	/* 0 for continuous mode, 1 for snapshot mode */
+	vfe31_ctrl->operation_mode = VFE_MODE_OF_OPERATION_CONTINUOUS;
+	vfe31_ctrl->outpath.output_mode = 0;
+	vfe31_ctrl->vfe_capture_count = 0;
+
+	/* this is unsigned 32 bit integer. */
+	vfe31_ctrl->vfeFrameId = 0;
+
+	vfe31_ctrl->output1Pattern = 0xffffffff;
+	vfe31_ctrl->output1Period  = 31;
+	vfe31_ctrl->output2Pattern = 0xffffffff;
+	vfe31_ctrl->output2Period  = 31;
+	vfe31_ctrl->vfeFrameSkipCount   = 0;
+	vfe31_ctrl->vfeFrameSkipPeriod  = 31;
+
+	/* Stats control variables. */
+	memset(&(vfe31_ctrl->afStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe31_ctrl->awbStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe31_ctrl->aecStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe31_ctrl->ihistStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe31_ctrl->rsStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe31_ctrl->csStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+}
+
+static void vfe31_reset(void)
+{
+	uint32_t vfe_version;
+	vfe31_reset_free_buf_queue_all();
+	vfe31_reset_internal_variables();
+
+	vfe31_reset_hist_cfg();
+	vfe_version = msm_camera_io_r(vfe31_ctrl->vfebase);
+	CDBG("vfe_version = 0x%x\n", vfe_version);
+	/* disable all interrupts.  vfeImaskLocal is also reset to 0
+	* to begin with. */
+	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
+		vfe31_ctrl->vfebase + VFE_IRQ_MASK_0);
+
+	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
+		vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+	/* clear all pending interrupts*/
+	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
+		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_0);
+	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
+		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_1);
+
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_IRQ_CMD);
+
+	/* enable reset_ack interrupt.  */
+	msm_camera_io_w(VFE_IMASK_RESET,
+		vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+	/* Write to VFE_GLOBAL_RESET_CMD to reset the vfe hardware. Once reset
+	 * is done, hardware interrupt will be generated.  VFE ist processes
+	 * the interrupt to complete the function call.  Note that the reset
+	 * function is synchronous. */
+
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_camera_io_w_mb(VFE_RESET_UPON_RESET_CMD,
+		vfe31_ctrl->vfebase + VFE_GLOBAL_RESET);
+}
+
+static int vfe31_operation_config(uint32_t *cmd)
+{
+	uint32_t *p = cmd;
+
+	vfe31_ctrl->operation_mode = *p;
+	vpe_ctrl->pad_2k_bool = (vfe31_ctrl->operation_mode & 1) ?
+		FALSE : TRUE;
+
+	vfe31_ctrl->stats_comp = *(++p);
+	vfe31_ctrl->hfr_mode = *(++p);
+
+	msm_camera_io_w(*(++p), vfe31_ctrl->vfebase + VFE_CFG_OFF);
+	msm_camera_io_w(*(++p), vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+	msm_camera_io_w(*(++p), vfe31_ctrl->vfebase + VFE_REALIGN_BUF);
+	msm_camera_io_w(*(++p), vfe31_ctrl->vfebase + VFE_CHROMA_UP);
+	msm_camera_io_w(*(++p), vfe31_ctrl->vfebase + VFE_STATS_CFG);
+	wmb();
+	return 0;
+}
+static uint32_t vfe_stats_awb_buf_init(struct vfe_cmd_stats_buf *in)
+{
+	uint32_t *ptr = in->statsBuf;
+	uint32_t addr;
+
+	addr = ptr[0];
+	msm_camera_io_w(addr,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR);
+	addr = ptr[1];
+	msm_camera_io_w(addr,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR);
+	vfe31_ctrl->awbStatsControl.nextFrameAddrBuf = in->statsBuf[2];
+	return 0;
+}
+
+
+static uint32_t vfe_stats_aec_buf_init(struct vfe_cmd_stats_buf *in)
+{
+	uint32_t *ptr = in->statsBuf;
+	uint32_t addr;
+
+	addr = ptr[0];
+	msm_camera_io_w(addr,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_AEC_WR_PING_ADDR);
+	addr = ptr[1];
+	msm_camera_io_w(addr,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_AEC_WR_PONG_ADDR);
+
+	vfe31_ctrl->aecStatsControl.nextFrameAddrBuf = in->statsBuf[2];
+	return 0;
+}
+
+static uint32_t vfe_stats_af_buf_init(struct vfe_cmd_stats_buf *in)
+{
+	uint32_t *ptr = in->statsBuf;
+	uint32_t addr;
+
+	addr = ptr[0];
+	msm_camera_io_w(addr,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR);
+	addr = ptr[1];
+	msm_camera_io_w(addr,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR);
+
+	vfe31_ctrl->afStatsControl.nextFrameAddrBuf = in->statsBuf[2];
+	return 0;
+}
+
+static uint32_t vfe_stats_ihist_buf_init(struct vfe_cmd_stats_buf *in)
+{
+	uint32_t *ptr = in->statsBuf;
+	uint32_t addr;
+
+	addr = ptr[0];
+	msm_camera_io_w(addr,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_HIST_WR_PING_ADDR);
+	addr = ptr[1];
+	msm_camera_io_w(addr,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_HIST_WR_PONG_ADDR);
+
+	vfe31_ctrl->ihistStatsControl.nextFrameAddrBuf = in->statsBuf[2];
+	return 0;
+}
+
+static uint32_t vfe_stats_rs_buf_init(struct vfe_cmd_stats_buf *in)
+{
+	uint32_t *ptr = in->statsBuf;
+	uint32_t addr;
+
+	addr = ptr[0];
+	msm_camera_io_w(addr,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_RS_WR_PING_ADDR);
+	addr = ptr[1];
+	msm_camera_io_w(addr,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_RS_WR_PONG_ADDR);
+
+	vfe31_ctrl->rsStatsControl.nextFrameAddrBuf = in->statsBuf[2];
+	return 0;
+}
+static uint32_t vfe_stats_cs_buf_init(struct vfe_cmd_stats_buf *in)
+{
+	uint32_t *ptr = in->statsBuf;
+	uint32_t addr;
+
+	addr = ptr[0];
+	msm_camera_io_w(addr,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_CS_WR_PING_ADDR);
+	addr = ptr[1];
+	msm_camera_io_w(addr,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_CS_WR_PONG_ADDR);
+
+	vfe31_ctrl->csStatsControl.nextFrameAddrBuf = in->statsBuf[2];
+	return 0;
+}
+
+static void vfe31_start_common(void)
+{
+	uint32_t irq_mask = 0x00E00021;
+	vfe31_ctrl->start_ack_pending = TRUE;
+	CDBG("VFE opertaion mode = 0x%x, output mode = 0x%x\n",
+		vfe31_ctrl->operation_mode, vfe31_ctrl->outpath.output_mode);
+	/* Enable IRQ for comp stats, Image master, SOF & Reg Update*/
+	if (vfe31_ctrl->stats_comp)
+		irq_mask |= 0x01000000;
+	else /* Enable IRQ for Image masters, AF stats, SOF & Reg Update */
+		irq_mask |= 0x00004000;
+
+	/* Enable EOF for video mode */
+	if (VFE_MODE_OF_OPERATION_VIDEO == vfe31_ctrl->operation_mode)
+		irq_mask |= 0x4;
+
+	msm_camera_io_w(irq_mask, vfe31_ctrl->vfebase + VFE_IRQ_MASK_0);
+
+	msm_camera_io_w(VFE_IMASK_RESET,
+		vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
+	/* enable out of order option */
+	msm_camera_io_w(0x80000000, vfe31_ctrl->vfebase + VFE_AXI_CFG);
+	/* enable performance monitor */
+	msm_camera_io_w(1, vfe31_ctrl->vfebase + VFE_BUS_PM_CFG);
+	msm_camera_io_w(1, vfe31_ctrl->vfebase + VFE_BUS_PM_CMD);
+
+
+	msm_camera_io_dump(vfe31_ctrl->vfebase, 0x600);
+
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	msm_camera_io_w(1, vfe31_ctrl->vfebase + VFE_CAMIF_COMMAND);
+	wmb();
+
+	atomic_set(&vfe31_ctrl->vstate, 1);
+}
+
+static int vfe31_start_recording(void)
+{
+	msm_camio_set_perf_lvl(S_VIDEO);
+	usleep(1000);
+	vfe31_ctrl->recording_state = VFE_REC_STATE_START_REQUESTED;
+	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	return 0;
+}
+
+static int vfe31_stop_recording(void)
+{
+	vfe31_ctrl->recording_state = VFE_REC_STATE_STOP_REQUESTED;
+	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	msm_camio_set_perf_lvl(S_PREVIEW);
+	return 0;
+}
+
+static void vfe31_liveshot(void)
+{
+	struct msm_sync* p_sync = (struct msm_sync *)vfe_syncdata;
+	if (p_sync)
+		p_sync->liveshot_enabled = true;
+}
+
+static void vfe31_stereocam(uint32_t enable)
+{
+	struct msm_sync* p_sync = (struct msm_sync *)vfe_syncdata;
+	if (p_sync) {
+		CDBG("%s: Enable StereoCam %d!!!\n", __func__, enable);
+		p_sync->stereocam_enabled = enable;
+	}
+}
+
+static int vfe31_zsl(void)
+{
+	uint32_t irq_comp_mask = 0;
+	/* capture command is valid for both idle and active state. */
+	irq_comp_mask	=
+		msm_camera_io_r(vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+
+	CDBG("%s:op mode %d O/P Mode %d\n", __func__,
+		vfe31_ctrl->operation_mode, vfe31_ctrl->outpath.output_mode);
+	if ((vfe31_ctrl->operation_mode == VFE_MODE_OF_OPERATION_ZSL)) {
+		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_P) {
+			irq_comp_mask |=
+				((0x1 << (vfe31_ctrl->outpath.out0.ch0)) |
+				(0x1 << (vfe31_ctrl->outpath.out0.ch1)));
+		} else if (vfe31_ctrl->outpath.output_mode &
+				VFE31_OUTPUT_MODE_P_ALL_CHNLS) {
+			irq_comp_mask |= (0x1 << vfe31_ctrl->outpath.out0.ch0 |
+				0x1 << vfe31_ctrl->outpath.out0.ch1 |
+				0x1 << vfe31_ctrl->outpath.out0.ch2);
+		}
+		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_T) {
+			irq_comp_mask |=
+				((0x1 << (vfe31_ctrl->outpath.out1.ch0 + 8)) |
+				(0x1 << (vfe31_ctrl->outpath.out1.ch1 + 8)));
+		}
+		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_S) {
+			irq_comp_mask |=
+			((0x1 << (vfe31_ctrl->outpath.out2.ch0 + 8)) |
+			(0x1 << (vfe31_ctrl->outpath.out2.ch1 + 8)));
+		}
+		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_P) {
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+		} else if (vfe31_ctrl->outpath.output_mode &
+				VFE31_OUTPUT_MODE_P_ALL_CHNLS) {
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch2]);
+		}
+		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_T) {
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
+		}
+		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_S) {
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out2.ch0]);
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out2.ch1]);
+		}
+	}
+	msm_camera_io_w(irq_comp_mask, vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+	vfe31_start_common();
+	msm_camio_set_perf_lvl(S_ZSL);
+	usleep(1000);
+	/* for debug */
+	msm_camera_io_w(1, vfe31_ctrl->vfebase + 0x18C);
+	msm_camera_io_w(1, vfe31_ctrl->vfebase + 0x188);
+	return 0;
+}
+
+static int vfe31_capture(uint32_t num_frames_capture)
+{
+	uint32_t irq_comp_mask = 0;
+	struct msm_sync* p_sync = (struct msm_sync *)vfe_syncdata;
+
+	/* capture command is valid for both idle and active state. */
+	vfe31_ctrl->vfe_capture_count = num_frames_capture;
+	if (p_sync) {
+		p_sync->snap_count = num_frames_capture;
+		p_sync->thumb_count = num_frames_capture;
+	}
+
+	irq_comp_mask	=
+		msm_camera_io_r(vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+
+	if ((vfe31_ctrl->operation_mode ==
+		 VFE_MODE_OF_OPERATION_SNAPSHOT) ||
+		(vfe31_ctrl->operation_mode ==
+		 VFE_MODE_OF_OPERATION_ZSL)){
+		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_PT) {
+			irq_comp_mask |=
+				((0x1 << (vfe31_ctrl->outpath.out0.ch0 + 8)) |
+				(0x1 << (vfe31_ctrl->outpath.out0.ch1 + 8)));
+		}
+		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_S) {
+			irq_comp_mask |=
+			((0x1 << (vfe31_ctrl->outpath.out1.ch0 + 8)) |
+			(0x1 << (vfe31_ctrl->outpath.out1.ch1 + 8)));
+		}
+		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_PT) {
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+		}
+		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_S) {
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
+		}
+	} else {  /* this is raw snapshot mode. */
+		CDBG("config the comp imask for raw snapshot mode.\n");
+		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_S) {
+			irq_comp_mask |=
+			(0x1 << (vfe31_ctrl->outpath.out1.ch0 + 8));
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
+		}
+	}
+	msm_camera_io_w(irq_comp_mask, vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+	if (p_sync->stereocam_enabled)
+		msm_camio_set_perf_lvl(S_STEREO_CAPTURE);
+	else
+		msm_camio_set_perf_lvl(S_CAPTURE);
+
+	usleep(1000);
+	vfe31_start_common();
+	return 0;
+}
+
+static int vfe31_start(void)
+{
+	uint32_t irq_comp_mask = 0;
+	struct msm_sync* p_sync = (struct msm_sync *)vfe_syncdata;
+	/* start command now is only good for continuous mode. */
+	if ((vfe31_ctrl->operation_mode != VFE_MODE_OF_OPERATION_CONTINUOUS) &&
+		(vfe31_ctrl->operation_mode != VFE_MODE_OF_OPERATION_VIDEO))
+		return 0;
+	irq_comp_mask =
+		msm_camera_io_r(vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+
+	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_PT) {
+		irq_comp_mask |= (0x1 << vfe31_ctrl->outpath.out0.ch0 |
+			0x1 << vfe31_ctrl->outpath.out0.ch1);
+			if (vfe31_ctrl->outpath.out0.ch2 >= 0)
+				irq_comp_mask |=
+					(0x1 << vfe31_ctrl->outpath.out0.ch0 |
+					0x1 << vfe31_ctrl->outpath.out0.ch1 |
+					0x1 << vfe31_ctrl->outpath.out0.ch2);
+	} else if (vfe31_ctrl->outpath.output_mode &
+		VFE31_OUTPUT_MODE_P_ALL_CHNLS) {
+			irq_comp_mask |= (0x1 << vfe31_ctrl->outpath.out0.ch0 |
+				0x1 << vfe31_ctrl->outpath.out0.ch1 |
+				0x1 << vfe31_ctrl->outpath.out0.ch2);
+	}
+
+	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_V) {
+		irq_comp_mask |= (0x1 << (vfe31_ctrl->outpath.out2.ch0 + 16)|
+			0x1 << (vfe31_ctrl->outpath.out2.ch1 + 16));
+	}
+
+	msm_camera_io_w(irq_comp_mask, vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+
+
+	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_PT) {
+		msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+		msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+		if (vfe31_ctrl->outpath.out0.ch2 >= 0)
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch2]);
+	} else if (vfe31_ctrl->outpath.output_mode &
+		VFE31_OUTPUT_MODE_P_ALL_CHNLS) {
+		msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+		msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+		msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch2]);
+	}
+
+	if (p_sync->stereocam_enabled)
+		msm_camio_set_perf_lvl(S_STEREO_VIDEO);
+	else
+		msm_camio_set_perf_lvl(S_PREVIEW);
+
+	usleep(1000);
+	vfe31_start_common();
+	return 0;
+}
+
+static void vfe31_update(void)
+{
+	unsigned long flags;
+	CDBG("vfe31_update\n");
+
+	if (vfe31_ctrl->update_gamma) {
+		if (!msm_camera_io_r(vfe31_ctrl->vfebase + V31_GAMMA_CFG_OFF))
+			msm_camera_io_w(7,
+				vfe31_ctrl->vfebase+V31_GAMMA_CFG_OFF);
+		else
+			msm_camera_io_w(0,
+				vfe31_ctrl->vfebase+V31_GAMMA_CFG_OFF);
+		vfe31_ctrl->update_gamma = false;
+	}
+	if (vfe31_ctrl->update_luma) {
+		if (!msm_camera_io_r(vfe31_ctrl->vfebase + V31_LUMA_CFG_OFF))
+			msm_camera_io_w(1,
+				vfe31_ctrl->vfebase + V31_LUMA_CFG_OFF);
+		else
+			msm_camera_io_w(0,
+				vfe31_ctrl->vfebase + V31_LUMA_CFG_OFF);
+		vfe31_ctrl->update_luma = false;
+	}
+	spin_lock_irqsave(&vfe31_ctrl->update_ack_lock, flags);
+	vfe31_ctrl->update_ack_pending = TRUE;
+	spin_unlock_irqrestore(&vfe31_ctrl->update_ack_lock, flags);
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	return;
+}
+
+static void vfe31_sync_timer_stop(void)
+{
+	uint32_t value = 0;
+	vfe31_ctrl->sync_timer_state = 0;
+	if (vfe31_ctrl->sync_timer_number == 0)
+		value = 0x10000;
+	else if (vfe31_ctrl->sync_timer_number == 1)
+		value = 0x20000;
+	else if (vfe31_ctrl->sync_timer_number == 2)
+		value = 0x40000;
+
+	/* Timer Stop */
+	msm_camera_io_w_mb(value, vfe31_ctrl->vfebase + V31_SYNC_TIMER_OFF);
+}
+
+static void vfe31_sync_timer_start(const uint32_t *tbl)
+{
+	/* set bit 8 for auto increment. */
+	uint32_t value = 1;
+	uint32_t val;
+
+	vfe31_ctrl->sync_timer_state = *tbl++;
+	vfe31_ctrl->sync_timer_repeat_count = *tbl++;
+	vfe31_ctrl->sync_timer_number = *tbl++;
+	CDBG("%s timer_state %d, repeat_cnt %d timer number %d\n",
+		 __func__, vfe31_ctrl->sync_timer_state,
+		 vfe31_ctrl->sync_timer_repeat_count,
+		 vfe31_ctrl->sync_timer_number);
+
+	if (vfe31_ctrl->sync_timer_state) { /* Start Timer */
+		value = value << vfe31_ctrl->sync_timer_number;
+	} else { /* Stop Timer */
+		CDBG("Failed to Start timer\n");
+		 return;
+	}
+
+	/* Timer Start */
+	msm_camera_io_w(value, vfe31_ctrl->vfebase + V31_SYNC_TIMER_OFF);
+	/* Sync Timer Line Start */
+	value = *tbl++;
+	msm_camera_io_w(value, vfe31_ctrl->vfebase + V31_SYNC_TIMER_OFF +
+		4 + ((vfe31_ctrl->sync_timer_number) * 12));
+	/* Sync Timer Pixel Start */
+	value = *tbl++;
+	msm_camera_io_w(value, vfe31_ctrl->vfebase + V31_SYNC_TIMER_OFF +
+			 8 + ((vfe31_ctrl->sync_timer_number) * 12));
+	/* Sync Timer Pixel Duration */
+	value = *tbl++;
+	val = camio_clk.vfe_clk_rate / 10000;
+	val = 10000000 / val;
+	val = value * 10000 / val;
+	CDBG("%s: Pixel Clk Cycles!!! %d\n", __func__, val);
+	msm_camera_io_w(val, vfe31_ctrl->vfebase + V31_SYNC_TIMER_OFF +
+		12 + ((vfe31_ctrl->sync_timer_number) * 12));
+	/* Timer0 Active High/LOW */
+	value = *tbl++;
+	msm_camera_io_w(value,
+		vfe31_ctrl->vfebase + V31_SYNC_TIMER_POLARITY_OFF);
+	/* Selects sync timer 0 output to drive onto timer1 port */
+	value = 0;
+	msm_camera_io_w(value, vfe31_ctrl->vfebase + V31_TIMER_SELECT_OFF);
+	wmb();
+}
+
+static void vfe31_program_dmi_cfg(enum VFE31_DMI_RAM_SEL bankSel)
+{
+	/* set bit 8 for auto increment. */
+	uint32_t value = VFE_DMI_CFG_DEFAULT;
+	value += (uint32_t)bankSel;
+
+	msm_camera_io_w_mb(value, vfe31_ctrl->vfebase + VFE_DMI_CFG);
+	/* by default, always starts with offset 0.*/
+	msm_camera_io_w(0, vfe31_ctrl->vfebase + VFE_DMI_ADDR);
+	wmb();
+}
+static void vfe31_write_gamma_cfg(enum VFE31_DMI_RAM_SEL channel_sel,
+						const uint32_t *tbl)
+{
+	int i;
+	uint32_t value, value1, value2;
+	vfe31_program_dmi_cfg(channel_sel);
+	/* for loop for extracting init table. */
+	for (i = 0 ; i < (VFE31_GAMMA_NUM_ENTRIES/2) ; i++) {
+		value = *tbl++;
+		value1 = value & 0x0000FFFF;
+		value2 = (value & 0xFFFF0000)>>16;
+		msm_camera_io_w((value1),
+			vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
+		msm_camera_io_w((value2),
+			vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
+	}
+	vfe31_program_dmi_cfg(NO_MEM_SELECTED);
+}
+
+static void vfe31_reset_hist_cfg()
+{
+	uint32_t i;
+	uint32_t value = 0;
+
+	vfe31_program_dmi_cfg(STATS_HIST_RAM);
+	for (i = 0 ; i < VFE31_HIST_TABLE_LENGTH ; i++)
+		msm_camera_io_w(value, vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
+	vfe31_program_dmi_cfg(NO_MEM_SELECTED);
+}
+
+static void vfe31_write_la_cfg(enum VFE31_DMI_RAM_SEL channel_sel,
+						const uint32_t *tbl)
+{
+	uint32_t i;
+	uint32_t value, value1, value2;
+
+	vfe31_program_dmi_cfg(channel_sel);
+	/* for loop for extracting init table. */
+	for (i = 0 ; i < (VFE31_LA_TABLE_LENGTH/2) ; i++) {
+		value = *tbl++;
+		value1 = value & 0x0000FFFF;
+		value2 = (value & 0xFFFF0000)>>16;
+		msm_camera_io_w((value1),
+			vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
+		msm_camera_io_w((value2),
+			vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
+	}
+	vfe31_program_dmi_cfg(NO_MEM_SELECTED);
+}
+
+static int vfe31_proc_general(struct msm_vfe31_cmd *cmd)
+{
+	int i , rc = 0;
+	uint32_t old_val = 0 , new_val = 0;
+	uint32_t *cmdp = NULL;
+	uint32_t *cmdp_local = NULL;
+	uint32_t snapshot_cnt = 0;
+	uint32_t stereo_cam_enable = 0;
+	struct msm_sync* p_sync = (struct msm_sync *)vfe_syncdata;
+
+	CDBG("vfe31_proc_general: cmdID = %s, length = %d\n",
+		vfe31_general_cmd[cmd->id], cmd->length);
+	switch (cmd->id) {
+	case V31_RESET:
+		pr_info("vfe31_proc_general: cmdID = %s\n",
+			vfe31_general_cmd[cmd->id]);
+		vfe31_reset();
+		break;
+	case V31_START:
+		pr_info("vfe31_proc_general: cmdID = %s\n",
+			vfe31_general_cmd[cmd->id]);
+		rc = vfe31_start();
+		break;
+	case V31_UPDATE:
+		vfe31_update();
+		break;
+	case V31_ZSL:
+		pr_info("vfe31_proc_general: cmdID = %s\n",
+			vfe31_general_cmd[cmd->id]);
+		vfe31_zsl();
+		break;
+	case V31_CAPTURE:
+		pr_info("vfe31_proc_general: cmdID = %s\n",
+			vfe31_general_cmd[cmd->id]);
+		if (copy_from_user(&snapshot_cnt, (void __user *)(cmd->value),
+				sizeof(uint32_t))) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		rc = vfe31_capture(snapshot_cnt);
+		break;
+	case V31_START_RECORDING:
+		pr_info("vfe31_proc_general: cmdID = %s\n",
+			vfe31_general_cmd[cmd->id]);
+		rc = vfe31_start_recording();
+		if (p_sync->stereocam_enabled)
+			p_sync->stereo_state = STEREO_VIDEO_ACTIVE;
+		break;
+	case V31_STOP_RECORDING:
+		pr_info("vfe31_proc_general: cmdID = %s\n",
+			vfe31_general_cmd[cmd->id]);
+		rc = vfe31_stop_recording();
+		if (p_sync->stereocam_enabled)
+			p_sync->stereo_state = STEREO_VIDEO_IDLE;
+		break;
+	case V31_OPERATION_CFG: {
+		if (cmd->length != V31_OPERATION_CFG_LEN) {
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(V31_OPERATION_CFG_LEN, GFP_ATOMIC);
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			V31_OPERATION_CFG_LEN)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		rc = vfe31_operation_config(cmdp);
+		}
+		break;
+
+	case V31_STATS_AE_START: {
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val |= AE_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+		cmdp, (vfe31_cmd[cmd->id].length));
+		}
+		break;
+	case V31_STATS_AF_START: {
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val |= AF_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+		cmdp, (vfe31_cmd[cmd->id].length));
+		}
+		break;
+	case V31_STATS_AWB_START: {
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val |= AWB_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp, (vfe31_cmd[cmd->id].length));
+		}
+		break;
+
+	case V31_STATS_IHIST_START: {
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val |= IHIST_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp, (vfe31_cmd[cmd->id].length));
+		}
+		break;
+
+	case V31_XBAR_CFG: {
+		unsigned long flags = 0;
+		spin_lock_irqsave(&vfe31_ctrl->xbar_lock, flags);
+		if ((cmd->length != V31_XBAR_CFG_LEN)
+			|| vfe31_ctrl->xbar_update_pending) {
+			rc = -EINVAL;
+			spin_unlock_irqrestore(&vfe31_ctrl->xbar_lock, flags);
+			goto proc_general_done;
+		}
+		spin_unlock_irqrestore(&vfe31_ctrl->xbar_lock, flags);
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		spin_lock_irqsave(&vfe31_ctrl->xbar_lock, flags);
+		vfe31_ctrl->xbar_cfg[0] = *cmdp;
+		vfe31_ctrl->xbar_cfg[1] = *(cmdp+1);
+		vfe31_ctrl->xbar_update_pending = 1;
+		spin_unlock_irqrestore(&vfe31_ctrl->xbar_lock, flags);
+		CDBG("%s: xbar0 0x%x xbar1 0x%x", __func__,
+			vfe31_ctrl->xbar_cfg[0],
+			vfe31_ctrl->xbar_cfg[1]);
+		}
+		break;
+
+	case V31_STATS_RS_START: {
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp, (vfe31_cmd[cmd->id].length));
+		}
+		break;
+
+	case V31_STATS_CS_START: {
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp, (vfe31_cmd[cmd->id].length));
+		}
+		break;
+
+	case V31_MCE_UPDATE:
+	case V31_MCE_CFG:{
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		/* Incrementing with 4 so as to point to the 2nd Register as
+		the 2nd register has the mce_enable bit */
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase +
+						V31_CHROMA_SUP_OFF + 4);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		new_val = *cmdp_local;
+		old_val &= MCE_EN_MASK;
+		new_val = new_val | old_val;
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + V31_CHROMA_SUP_OFF + 4,
+			&new_val, 4);
+		cmdp_local += 1;
+
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase +
+						V31_CHROMA_SUP_OFF + 8);
+		new_val = *cmdp_local;
+		old_val &= MCE_Q_K_MASK;
+		new_val = new_val | old_val;
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + V31_CHROMA_SUP_OFF + 8,
+			&new_val, 4);
+		cmdp_local += 1;
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp_local, (vfe31_cmd[cmd->id].length));
+		}
+		break;
+	case V31_DEMOSAIC_2_UPDATE: /* 38 BPC update   */
+	case V31_DEMOSAIC_2_CFG: {  /* 14 BPC config   */
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		new_val = *cmdp_local;
+
+		old_val = msm_camera_io_r(
+				vfe31_ctrl->vfebase + V31_DEMOSAIC_0_OFF);
+		old_val &= BPC_MASK;
+
+		new_val = new_val | old_val;
+		*cmdp_local = new_val;
+		msm_camera_io_memcpy(vfe31_ctrl->vfebase + V31_DEMOSAIC_0_OFF,
+					cmdp_local, 4);
+		cmdp_local += 1;
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp_local, (vfe31_cmd[cmd->id].length));
+		}
+		break;
+	case V31_DEMOSAIC_1_UPDATE:/* 37 ABF update  */
+	case V31_DEMOSAIC_1_CFG: { /* 13 ABF config  */
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		new_val = *cmdp_local;
+
+		old_val = msm_camera_io_r(
+				vfe31_ctrl->vfebase + V31_DEMOSAIC_0_OFF);
+		old_val &= ABF_MASK;
+		new_val = new_val | old_val;
+		*cmdp_local = new_val;
+
+		msm_camera_io_memcpy(vfe31_ctrl->vfebase + V31_DEMOSAIC_0_OFF,
+		    cmdp_local, 4);
+
+		cmdp_local += 1;
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp_local, (vfe31_cmd[cmd->id].length));
+		}
+		break;
+	case V31_ROLL_OFF_CFG: {
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value) , cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+		cmdp_local, 16);
+		cmdp_local += 4;
+		vfe31_program_dmi_cfg(ROLLOFF_RAM);
+		/* for loop for extrcting init table. */
+		for (i = 0 ; i < (VFE31_ROLL_OFF_INIT_TABLE_SIZE * 2) ; i++) {
+			msm_camera_io_w(*cmdp_local ,
+			vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
+			cmdp_local++;
+		}
+		CDBG("done writing init table\n");
+		/* by default, always starts with offset 0. */
+		msm_camera_io_w(LENS_ROLL_OFF_DELTA_TABLE_OFFSET,
+		vfe31_ctrl->vfebase + VFE_DMI_ADDR);
+		/* for loop for extracting delta table. */
+		for (i = 0 ; i < (VFE31_ROLL_OFF_DELTA_TABLE_SIZE * 2) ; i++) {
+			msm_camera_io_w(*cmdp_local,
+			vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
+			cmdp_local++;
+		}
+		vfe31_program_dmi_cfg(NO_MEM_SELECTED);
+		}
+		break;
+
+	case V31_LA_CFG:{
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		/* Select Bank 0*/
+		*cmdp = 0;
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp, (vfe31_cmd[cmd->id].length));
+		cmdp += 1;
+		vfe31_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK0 , cmdp);
+		cmdp -= 1;
+		}
+		break;
+
+	case V31_LA_UPDATE: {
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_camera_io_r(
+				vfe31_ctrl->vfebase + V31_LUMA_CFG_OFF);
+		cmdp += 1;
+		if (old_val != 0x0)
+			vfe31_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK0 , cmdp);
+		else
+			vfe31_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK1 , cmdp);
+		vfe31_ctrl->update_luma = true;
+		cmdp -= 1;
+		}
+		break;
+
+	case V31_SK_ENHAN_CFG:
+	case V31_SK_ENHAN_UPDATE:{
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_camera_io_memcpy(vfe31_ctrl->vfebase + V31_SCE_OFF,
+				cmdp, V31_SCE_LEN);
+		}
+		break;
+
+	case V31_LIVESHOT:
+		vfe31_liveshot();
+		break;
+
+	case V31_STEREOCAM:
+		if (copy_from_user(&stereo_cam_enable,
+			(void __user *)(cmd->value), sizeof(uint32_t))) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		vfe31_stereocam(stereo_cam_enable);
+		break;
+
+	case V31_RGB_G_CFG: {
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		/* Select Bank 0*/
+		*cmdp = 0;
+		msm_camera_io_memcpy(vfe31_ctrl->vfebase + V31_RGB_G_OFF,
+				cmdp, 4);
+		cmdp += 1;
+		vfe31_write_gamma_cfg(RGBLUT_CHX_BANK0, cmdp);
+		cmdp -= 1;
+		}
+		break;
+
+	case V31_RGB_G_UPDATE: {
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp, (void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_camera_io_r(
+				vfe31_ctrl->vfebase + V31_GAMMA_CFG_OFF);
+		cmdp += 1;
+
+		if (!old_val) {
+			vfe31_write_gamma_cfg(RGBLUT_CHX_BANK1, cmdp);
+		} else {
+			vfe31_write_gamma_cfg(RGBLUT_CHX_BANK0, cmdp);
+			}
+		vfe31_ctrl->update_gamma = true;
+		cmdp -= 1;
+		}
+		break;
+
+	case V31_STATS_AWB_STOP: {
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~AWB_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		}
+		break;
+	case V31_STATS_AE_STOP: {
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~AE_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		}
+		break;
+	case V31_STATS_AF_STOP: {
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~AF_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		}
+		break;
+
+	case V31_STATS_IHIST_STOP: {
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~IHIST_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		}
+		break;
+
+	case V31_STATS_RS_STOP: {
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~RS_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		}
+		break;
+
+	case V31_STATS_CS_STOP: {
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~CS_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		}
+		break;
+	case V31_STOP:
+		pr_info("vfe31_proc_general: cmdID = %s\n",
+			vfe31_general_cmd[cmd->id]);
+		vfe31_stop();
+		break;
+
+	case V31_SYNC_TIMER_SETTING:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp, (void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		vfe31_sync_timer_start(cmdp);
+		break;
+
+	case V31_EZTUNE_CFG: {
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		*cmdp &= ~STATS_ENABLE_MASK;
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= STATS_ENABLE_MASK;
+		*cmdp |= old_val;
+
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp, (vfe31_cmd[cmd->id].length));
+		}
+		break;
+
+	default: {
+		if (cmd->length != vfe31_cmd[cmd->id].length)
+			return -EINVAL;
+
+		cmdp = kmalloc(vfe31_cmd[cmd->id].length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+
+		if (copy_from_user(cmdp, (void __user *)cmd->value,
+				cmd->length)) {
+			rc = -EFAULT;
+			pr_err("%s copy from user failed for cmd %d",
+				__func__, cmd->id);
+			goto proc_general_done;
+		}
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp, (vfe31_cmd[cmd->id].length));
+	}
+	break;
+
+	}
+
+proc_general_done:
+	kfree(cmdp);
+
+	return rc;
+}
+
+static void vfe31_stats_af_ack(struct vfe_cmd_stats_ack *pAck)
+{
+	vfe31_ctrl->afStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
+	vfe31_ctrl->af_ack_pending = FALSE;
+}
+
+static void vfe31_stats_awb_ack(struct vfe_cmd_stats_ack *pAck)
+{
+	vfe31_ctrl->awbStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
+	vfe31_ctrl->awb_ack_pending = FALSE;
+}
+
+static void vfe31_stats_aec_ack(struct vfe_cmd_stats_ack *pAck)
+{
+	vfe31_ctrl->aecStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
+	vfe31_ctrl->aec_ack_pending = FALSE;
+}
+
+static void vfe31_stats_ihist_ack(struct vfe_cmd_stats_ack *pAck)
+{
+	vfe31_ctrl->ihistStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
+	vfe31_ctrl->ihist_ack_pending = FALSE;
+}
+
+static void vfe31_stats_rs_ack(struct vfe_cmd_stats_ack *pAck)
+{
+	vfe31_ctrl->rsStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
+	vfe31_ctrl->rs_ack_pending = FALSE;
+}
+
+static void vfe31_stats_cs_ack(struct vfe_cmd_stats_ack *pAck)
+{
+	vfe31_ctrl->csStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
+	vfe31_ctrl->cs_ack_pending = FALSE;
+}
+
+static int vfe31_config(struct msm_vfe_cfg_cmd *cmd, void *data)
+{
+	struct msm_vfe31_cmd vfecmd;
+
+	long rc = 0;
+	uint32_t i = 0;
+	struct vfe_cmd_stats_buf *scfg = NULL;
+	struct msm_pmem_region   *regptr = NULL;
+	struct vfe_cmd_stats_ack *sack = NULL;
+
+	if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
+		cmd->cmd_type != CMD_SNAP_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_AEC_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_AWB_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_IHIST_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_RS_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_CS_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE) {
+		if (copy_from_user(&vfecmd,
+				(void __user *)(cmd->value),
+				sizeof(vfecmd))) {
+			pr_err("%s %d: copy_from_user failed\n", __func__,
+				__LINE__);
+			return -EFAULT;
+		}
+	} else {
+	/* here eith stats release or frame release. */
+		if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
+			cmd->cmd_type != CMD_SNAP_BUF_RELEASE) {
+			/* then must be stats release. */
+			if (!data)
+				return -EFAULT;
+				sack = kmalloc(sizeof(struct vfe_cmd_stats_ack),
+				GFP_ATOMIC);
+				if (!sack)
+					return -ENOMEM;
+
+				sack->nextStatsBuf = *(uint32_t *)data;
+			}
+	}
+
+	CDBG("%s: cmdType = %d\n", __func__, cmd->cmd_type);
+
+	if ((cmd->cmd_type == CMD_STATS_AF_ENABLE) ||
+		(cmd->cmd_type == CMD_STATS_AWB_ENABLE) ||
+		(cmd->cmd_type == CMD_STATS_IHIST_ENABLE) ||
+		(cmd->cmd_type == CMD_STATS_RS_ENABLE) ||
+		(cmd->cmd_type == CMD_STATS_CS_ENABLE) ||
+		(cmd->cmd_type == CMD_STATS_AEC_ENABLE)) {
+		struct axidata *axid;
+		axid = data;
+		if (!axid) {
+			rc = -EFAULT;
+			goto vfe31_config_done;
+		}
+
+		scfg =
+			kmalloc(sizeof(struct vfe_cmd_stats_buf),
+				GFP_ATOMIC);
+		if (!scfg) {
+			rc = -ENOMEM;
+			goto vfe31_config_done;
+		}
+		regptr = axid->region;
+		if (axid->bufnum1 > 0) {
+			for (i = 0; i < axid->bufnum1; i++) {
+				scfg->statsBuf[i] =
+					(uint32_t)(regptr->paddr);
+				regptr++;
+			}
+		}
+		/* individual */
+		switch (cmd->cmd_type) {
+		case CMD_STATS_AEC_ENABLE:
+			rc = vfe_stats_aec_buf_init(scfg);
+			break;
+		case CMD_STATS_AF_ENABLE:
+			rc = vfe_stats_af_buf_init(scfg);
+			break;
+		case CMD_STATS_AWB_ENABLE:
+			rc = vfe_stats_awb_buf_init(scfg);
+			break;
+		case CMD_STATS_IHIST_ENABLE:
+			rc = vfe_stats_ihist_buf_init(scfg);
+			break;
+		case CMD_STATS_RS_ENABLE:
+			rc = vfe_stats_rs_buf_init(scfg);
+			break;
+		case CMD_STATS_CS_ENABLE:
+			rc = vfe_stats_cs_buf_init(scfg);
+			break;
+		}
+	}
+
+	switch (cmd->cmd_type) {
+	case CMD_GENERAL:
+		rc = vfe31_proc_general(&vfecmd);
+		break;
+
+	case CMD_FRAME_BUF_RELEASE: {
+		struct msm_frame *b;
+		unsigned long p;
+		int ret;
+		struct vfe31_output_ch *outch = NULL;
+		if (!data) {
+			rc = -EFAULT;
+			break;
+		}
+
+		b = (struct msm_frame *)(cmd->value);
+		p = *(unsigned long *)data;
+
+		CDBG("CMD_FRAME_BUF_RELEASE b->path = %d\n", b->path);
+
+		if (b->path & OUTPUT_TYPE_P) {
+			CDBG("CMD_FRAME_BUF_RELEASE got free buffer\n");
+			outch = &vfe31_ctrl->outpath.out0;
+		} else if (b->path & OUTPUT_TYPE_S) {
+			outch = &vfe31_ctrl->outpath.out1;
+		} else if (b->path & OUTPUT_TYPE_V) {
+			outch = &vfe31_ctrl->outpath.out2;
+		} else {
+			rc = -EFAULT;
+			break;
+		}
+
+		ret = vfe31_add_free_buf2(outch, p, b->planar0_off,
+			b->planar1_off, b->planar2_off);
+		if (ret < 0)
+			return ret;
+		break;
+	}
+
+	case CMD_SNAP_BUF_RELEASE: {
+		struct msm_frame *b;
+		unsigned long p;
+		int ret;
+		struct vfe31_output_ch *outch = NULL;
+		if (!data)
+			return -EFAULT;
+
+		b = (struct msm_frame *)(cmd->value);
+		p = *(unsigned long *)data;
+
+		CDBG("CMD_PIC_BUF_RELEASE b->path = %d\n", b->path);
+
+		if (b->path & OUTPUT_TYPE_T) {
+			CDBG("CMD_FRAME_BUF_RELEASE got free buffer\n");
+			outch = &vfe31_ctrl->outpath.out1;
+		} else if (b->path & OUTPUT_TYPE_S) {
+			outch = &vfe31_ctrl->outpath.out2;
+		} else
+			return -EFAULT;
+
+		ret = vfe31_add_free_buf2(outch, p, b->planar0_off,
+			b->planar1_off,	b->planar2_off);
+		if (ret < 0)
+			return ret;
+		break;
+	}
+
+	case CMD_STATS_AEC_BUF_RELEASE:
+		vfe31_stats_aec_ack(sack);
+		break;
+
+	case CMD_STATS_AF_BUF_RELEASE:
+		vfe31_stats_af_ack(sack);
+		break;
+
+	case CMD_STATS_AWB_BUF_RELEASE:
+		vfe31_stats_awb_ack(sack);
+		break;
+
+	case CMD_STATS_IHIST_BUF_RELEASE:
+		vfe31_stats_ihist_ack(sack);
+		break;
+
+	case CMD_STATS_RS_BUF_RELEASE:
+		vfe31_stats_rs_ack(sack);
+		break;
+
+	case CMD_STATS_CS_BUF_RELEASE:
+		vfe31_stats_cs_ack(sack);
+		break;
+
+	case CMD_AXI_CFG_PREVIEW: {
+		struct axidata *axid;
+		uint32_t *axio = NULL;
+		axid = data;
+		if (!axid) {
+			rc = -EFAULT;
+			break;
+		}
+		axio =
+			kmalloc(vfe31_cmd[V31_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe31_cmd[V31_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe31_config_axi(OUTPUT_2, axid, axio);
+		kfree(axio);
+		break;
+	}
+
+	case CMD_RAW_PICT_AXI_CFG: {
+		struct axidata *axid;
+		uint32_t *axio = NULL;
+		axid = data;
+		if (!axid) {
+			rc = -EFAULT;
+			break;
+		}
+		axio =
+			kmalloc(vfe31_cmd[V31_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe31_cmd[V31_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe31_config_axi(CAMIF_TO_AXI_VIA_OUTPUT_2, axid, axio);
+		kfree(axio);
+		break;
+	}
+
+	case CMD_AXI_CFG_SNAP: {
+		struct axidata *axid;
+		uint32_t *axio = NULL;
+		CDBG("%s, CMD_AXI_CFG_SNAP\n", __func__);
+		axid = data;
+		if (!axid)
+			return -EFAULT;
+		axio =
+			kmalloc(vfe31_cmd[V31_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe31_cmd[V31_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe31_config_axi(OUTPUT_1_AND_2, axid, axio);
+		kfree(axio);
+		break;
+	}
+
+	case CMD_AXI_CFG_ZSL: {
+		struct axidata *axid;
+		uint32_t *axio = NULL;
+		CDBG("%s, CMD_AXI_CFG_ZSL\n", __func__);
+		axid = data;
+		if (!axid)
+			return -EFAULT;
+		axio =
+			kmalloc(vfe31_cmd[V31_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe31_cmd[V31_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe31_config_axi(OUTPUT_1_2_AND_3, axid, axio);
+		kfree(axio);
+	}
+		break;
+
+	case CMD_AXI_CFG_ZSL_ALL_CHNLS: {
+		struct axidata *axid;
+		uint32_t *axio;
+		CDBG("%s, CMD_AXI_CFG_ZSL\n", __func__);
+		axid = data;
+		if (!axid)
+			return -EFAULT;
+		axio =
+			kmalloc(vfe31_cmd[V31_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe31_cmd[V31_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe31_config_axi(OUTPUT_ZSL_ALL_CHNLS, axid, axio);
+		kfree(axio);
+	}
+		break;
+
+	case CMD_AXI_CFG_VIDEO: {
+		struct axidata *axid;
+		uint32_t *axio = NULL;
+		axid = data;
+		if (!axid) {
+			rc = -EFAULT;
+			break;
+		}
+
+		axio =
+			kmalloc(vfe31_cmd[V31_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe31_cmd[V31_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe31_config_axi(OUTPUT_1_AND_3, axid, axio);
+		kfree(axio);
+		break;
+	}
+
+	case CMD_AXI_CFG_VIDEO_ALL_CHNLS: {
+		struct axidata *axid;
+		uint32_t *axio = NULL;
+		axid = data;
+		if (!axid) {
+			rc = -EFAULT;
+			break;
+		}
+
+		axio =
+			kmalloc(vfe31_cmd[V31_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe31_cmd[V31_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe31_config_axi(OUTPUT_VIDEO_ALL_CHNLS, axid, axio);
+		kfree(axio);
+		break;
+	}
+
+	default:
+		break;
+	}
+vfe31_config_done:
+	kfree(scfg);
+	kfree(sack);
+	CDBG("%s done: rc = %d\n", __func__, (int) rc);
+	return rc;
+}
+
+static void vfe31_send_msg_no_payload(enum VFE31_MESSAGE_ID id)
+{
+	struct vfe_message msg;
+
+	CDBG("vfe31_send_msg_no_payload\n");
+	msg._d = id;
+	vfe31_proc_ops(id, &msg, 0);
+}
+
+static void vfe31_process_reg_update_irq(void)
+{
+	uint32_t  temp, old_val;
+	unsigned long flags;
+	if (vfe31_ctrl->recording_state == VFE_REC_STATE_START_REQUESTED) {
+		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_V) {
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out2.ch0]);
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out2.ch1]);
+		}
+		vfe31_ctrl->recording_state = VFE_REC_STATE_STARTED;
+		if (vpe_ctrl->dis_en) {
+			old_val = msm_camera_io_r(
+				vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+			old_val |= RS_CS_ENABLE_MASK;
+			msm_camera_io_w(old_val,
+				vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		}
+		msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+		CDBG("start video triggered .\n");
+	} else if (vfe31_ctrl->recording_state
+			== VFE_REC_STATE_STOP_REQUESTED) {
+		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_V) {
+			msm_camera_io_w(0, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out2.ch0]);
+			msm_camera_io_w(0, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out2.ch1]);
+		}
+
+		/*disable rs& cs when stop recording. */
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= (~RS_CS_ENABLE_MASK);
+		msm_camera_io_w(old_val,
+				vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		CDBG("stop video triggered\n");
+	}
+	if (vfe31_ctrl->start_ack_pending == TRUE) {
+		vfe31_send_msg_no_payload(MSG_ID_START_ACK);
+		vfe31_ctrl->start_ack_pending = FALSE;
+	} else {
+		if (vfe31_ctrl->recording_state ==
+			VFE_REC_STATE_STOP_REQUESTED) {
+			vfe31_ctrl->recording_state = VFE_REC_STATE_STOPPED;
+			msm_camera_io_w_mb(1, vfe31_ctrl->vfebase +
+						VFE_REG_UPDATE_CMD);
+		} else if (vfe31_ctrl->recording_state ==
+			VFE_REC_STATE_STOPPED) {
+			CDBG("sent stop video rec ACK");
+			vfe31_send_msg_no_payload(MSG_ID_STOP_REC_ACK);
+			vfe31_ctrl->recording_state = VFE_REC_STATE_IDLE;
+		}
+		spin_lock_irqsave(&vfe31_ctrl->update_ack_lock, flags);
+		if (vfe31_ctrl->update_ack_pending == TRUE) {
+			vfe31_ctrl->update_ack_pending = FALSE;
+			spin_unlock_irqrestore(
+				&vfe31_ctrl->update_ack_lock, flags);
+			vfe31_send_msg_no_payload(MSG_ID_UPDATE_ACK);
+		} else {
+			spin_unlock_irqrestore(
+				&vfe31_ctrl->update_ack_lock, flags);
+		}
+	}
+	/* in snapshot mode */
+	if (vfe31_ctrl->operation_mode ==
+		VFE_MODE_OF_OPERATION_SNAPSHOT) {
+		/* later we need to add check for live snapshot mode. */
+
+		if (vfe31_ctrl->vfe_capture_count)
+			vfe31_ctrl->vfe_capture_count--;
+		/* if last frame to be captured: */
+		if (vfe31_ctrl->vfe_capture_count == 0) {
+			/* stop the bus output:  write master enable = 0*/
+			if (vfe31_ctrl->outpath.output_mode &
+					VFE31_OUTPUT_MODE_PT) {
+				msm_camera_io_w(0, vfe31_ctrl->vfebase +
+					vfe31_AXI_WM_CFG[
+						vfe31_ctrl->outpath.out0.ch0]);
+				msm_camera_io_w(0, vfe31_ctrl->vfebase +
+					vfe31_AXI_WM_CFG[vfe31_ctrl->
+						outpath.out0.ch1]);
+			}
+			if (vfe31_ctrl->outpath.output_mode &
+					VFE31_OUTPUT_MODE_S) {
+				msm_camera_io_w(0, vfe31_ctrl->vfebase +
+					vfe31_AXI_WM_CFG[vfe31_ctrl->
+						outpath.out1.ch0]);
+				msm_camera_io_w(0, vfe31_ctrl->vfebase +
+					vfe31_AXI_WM_CFG[vfe31_ctrl->
+						outpath.out1.ch1]);
+			}
+
+			/* Ensure the write order while writing
+			to the command register using the barrier */
+			msm_camera_io_w_mb(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
+				vfe31_ctrl->vfebase + VFE_CAMIF_COMMAND);
+
+			/* Ensure the read order while reading
+			to the command register using the barrier */
+			temp = msm_camera_io_r_mb(vfe31_ctrl->vfebase +
+				VFE_CAMIF_COMMAND);
+		}
+		/* then do reg_update. */
+		msm_camera_io_w_mb(1, vfe31_ctrl->vfebase +
+			VFE_REG_UPDATE_CMD);
+	} /* if snapshot mode. */
+}
+
+static void vfe31_set_default_reg_values(void)
+{
+	msm_camera_io_w(0x800080, vfe31_ctrl->vfebase + VFE_DEMUX_GAIN_0);
+	msm_camera_io_w(0x800080, vfe31_ctrl->vfebase + VFE_DEMUX_GAIN_1);
+	msm_camera_io_w(0xFFFFF, vfe31_ctrl->vfebase + VFE_CGC_OVERRIDE);
+
+	/* default frame drop period and pattern */
+	msm_camera_io_w(0x1f, vfe31_ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_CFG);
+	msm_camera_io_w(0x1f, vfe31_ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_CFG);
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe31_ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_PATTERN);
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe31_ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_PATTERN);
+	msm_camera_io_w(0x1f, vfe31_ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y);
+	msm_camera_io_w(0x1f, vfe31_ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR);
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe31_ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_PATTERN);
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe31_ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR_PATTERN);
+	msm_camera_io_w(0, vfe31_ctrl->vfebase + VFE_CLAMP_MIN);
+	msm_camera_io_w(0xFFFFFF, vfe31_ctrl->vfebase + VFE_CLAMP_MAX);
+
+	/* stats UB config */
+	msm_camera_io_w(0x3980007,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_AEC_UB_CFG);
+	msm_camera_io_w(0x3A00007,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_AF_UB_CFG);
+	msm_camera_io_w(0x3A8000F,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_AWB_UB_CFG);
+	msm_camera_io_w(0x3B80007,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_RS_UB_CFG);
+	msm_camera_io_w(0x3C0001F,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_CS_UB_CFG);
+	msm_camera_io_w(0x3E0001F,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_HIST_UB_CFG);
+}
+
+static void vfe31_process_reset_irq(void)
+{
+	atomic_set(&vfe31_ctrl->vstate, 0);
+	vfe31_ctrl->while_stopping_mask = VFE_IMASK_WHILE_STOPPING_1;
+	if (atomic_read(&vfe31_ctrl->stop_ack_pending)) {
+		/* this is from the stop command. */
+		atomic_set(&vfe31_ctrl->stop_ack_pending, 0);
+		vfe31_send_msg_no_payload(MSG_ID_STOP_ACK);
+	} else {
+		/* this is from reset command. */
+		vfe31_set_default_reg_values();
+
+		/* reload all write masters. (frame & line)*/
+		msm_camera_io_w_mb(0x7FFF, vfe31_ctrl->vfebase + VFE_BUS_CMD);
+		vfe31_send_msg_no_payload(MSG_ID_RESET_ACK);
+	}
+}
+
+
+static void vfe31_process_axi_halt_irq(void)
+{
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_camera_io_w_mb(AXI_HALT_CLEAR,
+		vfe31_ctrl->vfebase + VFE_AXI_CMD);
+	vfe31_ctrl->while_stopping_mask = VFE_IMASK_RESET;
+
+	/* disable all interrupts.  */
+	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
+		vfe31_ctrl->vfebase + VFE_IRQ_MASK_0);
+	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
+		vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+	/* clear all pending interrupts*/
+	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
+		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_0);
+	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
+		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_1);
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_camera_io_w_mb(1,
+		vfe31_ctrl->vfebase + VFE_IRQ_CMD);
+
+	/* now enable only halt_irq & reset_irq */
+	msm_camera_io_w(0xf0000000,          /* this is for async timer. */
+		vfe31_ctrl->vfebase + VFE_IRQ_MASK_0);
+	msm_camera_io_w(VFE_IMASK_RESET,
+		vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	CDBG("%s: about to reset vfe...\n", __func__);
+	msm_camera_io_w_mb(VFE_RESET_UPON_STOP_CMD,
+		vfe31_ctrl->vfebase + VFE_GLOBAL_RESET);
+
+}
+
+static void vfe31_process_camif_sof_irq(void)
+{
+	uint32_t  temp;
+
+	/* in raw snapshot mode */
+	if (vfe31_ctrl->operation_mode ==
+		VFE_MODE_OF_OPERATION_RAW_SNAPSHOT) {
+		if (vfe31_ctrl->start_ack_pending) {
+			vfe31_send_msg_no_payload(MSG_ID_START_ACK);
+			vfe31_ctrl->start_ack_pending = FALSE;
+		}
+		if (vfe31_ctrl->vfe_capture_count)
+			vfe31_ctrl->vfe_capture_count--;
+		/* if last frame to be captured: */
+		if (vfe31_ctrl->vfe_capture_count == 0) {
+			/* Ensure the write order while writing
+			to the command register using the barrier */
+			msm_camera_io_w_mb(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
+				vfe31_ctrl->vfebase + VFE_CAMIF_COMMAND);
+			temp = msm_camera_io_r_mb(vfe31_ctrl->vfebase +
+				VFE_CAMIF_COMMAND);
+		}
+	} /* if raw snapshot mode. */
+
+	if ((vfe31_ctrl->hfr_mode != HFR_MODE_OFF) &&
+		(vfe31_ctrl->operation_mode == VFE_MODE_OF_OPERATION_VIDEO) &&
+		(vfe31_ctrl->vfeFrameId % vfe31_ctrl->hfr_mode != 0)) {
+		vfe31_ctrl->vfeFrameId++;
+		CDBG("Skip the SOF notification when HFR enabled\n");
+		return;
+	}
+	vfe31_send_msg_no_payload(MSG_ID_SOF_ACK);
+	vfe31_ctrl->vfeFrameId++;
+	CDBG("camif_sof_irq, frameId = %d\n", vfe31_ctrl->vfeFrameId);
+
+	if (vfe31_ctrl->sync_timer_state) {
+		if (vfe31_ctrl->sync_timer_repeat_count == 0)
+			vfe31_sync_timer_stop();
+		else
+		vfe31_ctrl->sync_timer_repeat_count--;
+	}
+}
+
+static void vfe31_process_error_irq(uint32_t errStatus)
+{
+	uint32_t camifStatus, read_val;
+	uint32_t *temp;
+
+	if (errStatus & VFE31_IMASK_CAMIF_ERROR) {
+		pr_err("vfe31_irq: camif errors\n");
+		temp = (uint32_t *)(vfe31_ctrl->vfebase + VFE_CAMIF_STATUS);
+		camifStatus = msm_camera_io_r(temp);
+		pr_err("camifStatus  = 0x%x\n", camifStatus);
+		vfe31_send_msg_no_payload(MSG_ID_CAMIF_ERROR);
+	}
+
+	if (errStatus & VFE31_IMASK_STATS_CS_OVWR)
+		pr_err("vfe31_irq: stats cs overwrite\n");
+
+	if (errStatus & VFE31_IMASK_STATS_IHIST_OVWR)
+		pr_err("vfe31_irq: stats ihist overwrite\n");
+
+	if (errStatus & VFE31_IMASK_REALIGN_BUF_Y_OVFL)
+		pr_err("vfe31_irq: realign bug Y overflow\n");
+
+	if (errStatus & VFE31_IMASK_REALIGN_BUF_CB_OVFL)
+		pr_err("vfe31_irq: realign bug CB overflow\n");
+
+	if (errStatus & VFE31_IMASK_REALIGN_BUF_CR_OVFL)
+		pr_err("vfe31_irq: realign bug CR overflow\n");
+
+	if (errStatus & VFE31_IMASK_VIOLATION)
+		pr_err("vfe31_irq: violation interrupt\n");
+
+	if (errStatus & VFE31_IMASK_IMG_MAST_0_BUS_OVFL)
+		pr_err("vfe31_irq: image master 0 bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_IMG_MAST_1_BUS_OVFL)
+		pr_err("vfe31_irq: image master 1 bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_IMG_MAST_2_BUS_OVFL)
+		pr_err("vfe31_irq: image master 2 bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_IMG_MAST_3_BUS_OVFL)
+		pr_err("vfe31_irq: image master 3 bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_IMG_MAST_4_BUS_OVFL)
+		pr_err("vfe31_irq: image master 4 bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_IMG_MAST_5_BUS_OVFL)
+		pr_err("vfe31_irq: image master 5 bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_IMG_MAST_6_BUS_OVFL)
+		pr_err("vfe31_irq: image master 6 bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_STATS_AE_BUS_OVFL)
+		pr_err("vfe31_irq: ae stats bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_STATS_AF_BUS_OVFL)
+		pr_err("vfe31_irq: af stats bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_STATS_AWB_BUS_OVFL)
+		pr_err("vfe31_irq: awb stats bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_STATS_RS_BUS_OVFL)
+		pr_err("vfe31_irq: rs stats bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_STATS_CS_BUS_OVFL)
+		pr_err("vfe31_irq: cs stats bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_STATS_IHIST_BUS_OVFL)
+		pr_err("vfe31_irq: ihist stats bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_STATS_SKIN_BUS_OVFL)
+		pr_err("vfe31_irq: skin stats bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_AXI_ERROR) {
+		pr_err("vfe31_irq: axi error\n");
+		/* read status too when overflow happens.*/
+		read_val = msm_camera_io_r(vfe31_ctrl->vfebase +
+			VFE_BUS_PING_PONG_STATUS);
+		pr_debug("VFE_BUS_PING_PONG_STATUS = 0x%x\n", read_val);
+		read_val = msm_camera_io_r(vfe31_ctrl->vfebase +
+			VFE_BUS_OPERATION_STATUS);
+		pr_debug("VFE_BUS_OPERATION_STATUS = 0x%x\n", read_val);
+		read_val = msm_camera_io_r(vfe31_ctrl->vfebase +
+			VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_0);
+		pr_debug("VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_0 = 0x%x\n",
+			read_val);
+		read_val = msm_camera_io_r(vfe31_ctrl->vfebase +
+			VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_1);
+		pr_debug("VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_1 = 0x%x\n",
+			read_val);
+		read_val = msm_camera_io_r(vfe31_ctrl->vfebase +
+			VFE_AXI_STATUS);
+		pr_debug("VFE_AXI_STATUS = 0x%x\n", read_val);
+	}
+}
+
+#define VFE31_AXI_OFFSET 0x0050
+#define vfe31_get_ch_ping_addr(chn) \
+	(msm_camera_io_r(vfe31_ctrl->vfebase + 0x0050 + 0x18 * (chn)))
+#define vfe31_get_ch_pong_addr(chn) \
+	(msm_camera_io_r(vfe31_ctrl->vfebase + 0x0050 + 0x18 * (chn) + 4))
+#define vfe31_get_ch_addr(ping_pong, chn) \
+	(((ping_pong) & (1 << (chn))) == 0 ? \
+	vfe31_get_ch_pong_addr(chn) : vfe31_get_ch_ping_addr(chn))
+
+#define vfe31_put_ch_ping_addr(chn, addr) \
+	(msm_camera_io_w((addr), vfe31_ctrl->vfebase + 0x0050 + 0x18 * (chn)))
+#define vfe31_put_ch_pong_addr(chn, addr) \
+	(msm_camera_io_w((addr), \
+	vfe31_ctrl->vfebase + 0x0050 + 0x18 * (chn) + 4))
+#define vfe31_put_ch_addr(ping_pong, chn, addr) \
+	(((ping_pong) & (1 << (chn))) == 0 ?   \
+	vfe31_put_ch_pong_addr((chn), (addr)) : \
+	vfe31_put_ch_ping_addr((chn), (addr)))
+
+static void vfe31_process_output_path_irq_0(uint32_t ping_pong)
+{
+	uint32_t p0_addr, p1_addr, p2_addr;
+#ifdef CONFIG_MSM_CAMERA_V4L2
+	uint32_t pyaddr_ping, pcbcraddr_ping, pyaddr_pong, pcbcraddr_pong;
+#endif
+	struct vfe31_free_buf *free_buf = NULL;
+	/* we render frames in the following conditions:
+	1. Continuous mode and the free buffer is avaialable.
+	*/
+	if (vfe31_ctrl->outpath.output_mode &
+		VFE31_OUTPUT_MODE_P_ALL_CHNLS) {
+		if (!(((ping_pong & PINGPONG_LOWER) == PINGPONG_LOWER) ||
+			((ping_pong & PINGPONG_LOWER) == 0x0))) {
+			pr_err(" Irq_2 - skip the frame pp_status is not proper"
+				"PP_status = 0x%x\n", ping_pong);
+			return;
+		}
+	}
+	free_buf = vfe31_get_free_buf(&vfe31_ctrl->outpath.out0);
+
+	if (free_buf) {
+		/* Y channel */
+		p0_addr = vfe31_get_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out0.ch0);
+		/* Chroma channel */
+		p1_addr = vfe31_get_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out0.ch1);
+		if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_P_ALL_CHNLS) {
+			p2_addr = vfe31_get_ch_addr(ping_pong,
+				vfe31_ctrl->outpath.out0.ch2);
+		} else {
+			p2_addr = p0_addr;
+		}
+		CDBG("Output path 0, p0_addr = 0x%x, p1_addr = 0x%x,"
+			 "p2_addr = 0x%x\n", p0_addr, p1_addr, p2_addr);
+		/* Y channel */
+		vfe31_put_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out0.ch0,
+			free_buf->paddr + free_buf->planar0_off);
+		/* Chroma channel */
+		vfe31_put_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out0.ch1,
+			free_buf->paddr + free_buf->planar1_off);
+		if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_P_ALL_CHNLS)
+			vfe31_put_ch_addr(ping_pong,
+				vfe31_ctrl->outpath.out0.ch2,
+			free_buf->paddr + free_buf->planar2_off);
+			kfree(free_buf);
+			/* if continuous mode, for display. (preview) */
+			vfe_send_outmsg(MSG_ID_OUTPUT_P,  p0_addr, p1_addr,
+				p2_addr);
+	} else {
+		vfe31_ctrl->outpath.out0.frame_drop_cnt++;
+		pr_warning("path_irq_0 - no free buffer!\n");
+#ifdef CONFIG_MSM_CAMERA_V4L2
+		pr_info("Swapping ping and pong\n");
+
+		/*get addresses*/
+		/* Y channel */
+		pyaddr_ping = vfe31_get_ch_ping_addr(
+			vfe31_ctrl->outpath.out0.ch0);
+		/* Chroma channel */
+		pcbcraddr_ping = vfe31_get_ch_ping_addr(
+			vfe31_ctrl->outpath.out0.ch1);
+		/* Y channel */
+		pyaddr_pong = vfe31_get_ch_pong_addr(
+			vfe31_ctrl->outpath.out0.ch0);
+		/* Chroma channel */
+		pcbcraddr_pong = vfe31_get_ch_pong_addr(
+			vfe31_ctrl->outpath.out0.ch1);
+
+		CDBG("ping = 0x%p, pong = 0x%p\n", (void *)pyaddr_ping,
+			(void *)pyaddr_pong);
+		CDBG("ping_cbcr = 0x%p, pong_cbcr = 0x%p\n",
+			(void *)pcbcraddr_ping, (void *)pcbcraddr_pong);
+
+		/*put addresses*/
+		/* SWAP y channel*/
+		vfe31_put_ch_ping_addr(vfe31_ctrl->outpath.out0.ch0,
+			pyaddr_pong);
+		vfe31_put_ch_pong_addr(vfe31_ctrl->outpath.out0.ch0,
+			pyaddr_ping);
+		/* SWAP chroma channel*/
+		vfe31_put_ch_ping_addr(vfe31_ctrl->outpath.out0.ch1,
+			pcbcraddr_pong);
+		vfe31_put_ch_pong_addr(vfe31_ctrl->outpath.out0.ch1,
+			pcbcraddr_ping);
+		CDBG("after swap: ping = 0x%p, pong = 0x%p\n",
+			(void *)pyaddr_pong, (void *)pyaddr_ping);
+#endif
+	}
+}
+
+static void vfe31_process_snapshot_frame(uint32_t ping_pong)
+{
+	uint32_t p0_addr, p1_addr;
+	struct vfe31_free_buf *free_buf = NULL;
+	/* Y channel- Main Image */
+	p0_addr = vfe31_get_ch_addr(ping_pong,
+		vfe31_ctrl->outpath.out1.ch0);
+	/* Chroma channel - TN Image */
+	p1_addr = vfe31_get_ch_addr(ping_pong,
+		vfe31_ctrl->outpath.out1.ch1);
+
+	free_buf = vfe31_get_free_buf(&vfe31_ctrl->outpath.out1);
+	CDBG("%s: snapshot main, p0_addr = 0x%x, p1_addr = 0x%x\n",
+		__func__, p0_addr, p1_addr);
+	if (free_buf) {
+		/* Y channel */
+		vfe31_put_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out1.ch0,
+			free_buf->paddr + free_buf->planar0_off);
+		/* Chroma channel */
+		vfe31_put_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out1.ch1,
+			free_buf->paddr + free_buf->planar1_off);
+		kfree(free_buf);
+	}
+	vfe_send_outmsg(MSG_ID_OUTPUT_S, p0_addr, p1_addr, p0_addr);
+
+	/* Y channel- TN Image */
+	p0_addr = vfe31_get_ch_addr(ping_pong,
+		vfe31_ctrl->outpath.out0.ch0);
+	/* Chroma channel - TN Image */
+	p1_addr = vfe31_get_ch_addr(ping_pong,
+		vfe31_ctrl->outpath.out0.ch1);
+
+	free_buf = vfe31_get_free_buf(&vfe31_ctrl->outpath.out0);
+	CDBG("%s: snapshot TN, p0_addr = 0x%x, p1_addr = 0x%x\n",
+		__func__, p0_addr, p1_addr);
+	if (free_buf) {
+		/* Y channel */
+		vfe31_put_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out0.ch0,
+			free_buf->paddr + free_buf->planar0_off);
+		/* Chroma channel */
+		vfe31_put_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out0.ch1,
+			free_buf->paddr + free_buf->planar1_off);
+		kfree(free_buf);
+	}
+
+	vfe_send_outmsg(MSG_ID_OUTPUT_T, p0_addr, p1_addr, p0_addr);
+
+	/* in snapshot mode if done then send
+		snapshot done message */
+	if (vfe31_ctrl->vfe_capture_count == 0) {
+		vfe31_send_msg_no_payload(MSG_ID_SNAPSHOT_DONE);
+		/* Ensure the write order while writing
+			to the cmd register using barrier */
+		msm_camera_io_w_mb(CAMIF_COMMAND_STOP_IMMEDIATELY,
+			vfe31_ctrl->vfebase +
+			VFE_CAMIF_COMMAND);
+	}
+}
+
+static void vfe31_process_raw_snapshot_frame(uint32_t ping_pong)
+{
+	uint32_t pyaddr, pcbcraddr;
+	struct vfe31_free_buf *free_buf = NULL;
+	struct msm_sync* p_sync = (struct msm_sync *)vfe_syncdata;
+
+	if (p_sync->stereocam_enabled)
+		p_sync->stereo_state = STEREO_RAW_SNAP_STARTED;
+
+	/* Y channel- Main Image */
+	pyaddr = vfe31_get_ch_addr(ping_pong,
+		vfe31_ctrl->outpath.out1.ch0);
+	/* Chroma channel - Main Image */
+	pcbcraddr = vfe31_get_ch_addr(ping_pong,
+		vfe31_ctrl->outpath.out1.ch1);
+
+	free_buf = vfe31_get_free_buf(&vfe31_ctrl->outpath.out1);
+	CDBG("%s: snapshot raw, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
+		__func__, pyaddr, pcbcraddr);
+	if (free_buf) {
+		/* Y channel */
+		vfe31_put_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out1.ch0,
+			free_buf->paddr + free_buf->planar0_off);
+		/* Chroma channel */
+		vfe31_put_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out1.ch1,
+			free_buf->paddr + free_buf->planar1_off);
+		kfree(free_buf);
+	}
+	 vfe_send_outmsg(MSG_ID_OUTPUT_S, pyaddr, pcbcraddr, 0);
+
+	/* in snapshot mode if done then send
+		snapshot done message */
+	if (vfe31_ctrl->vfe_capture_count == 0) {
+		vfe31_send_msg_no_payload(MSG_ID_SNAPSHOT_DONE);
+		/* Ensure the write order while writing
+		to the cmd register using barrier */
+		msm_camera_io_w_mb(CAMIF_COMMAND_STOP_IMMEDIATELY,
+			vfe31_ctrl->vfebase +
+			VFE_CAMIF_COMMAND);
+	}
+}
+static void vfe31_process_zsl_frame(uint32_t ping_pong)
+{
+	uint32_t p0_addr, p1_addr;
+	struct vfe31_free_buf *free_buf = NULL;
+	/* Y channel- Main Image */
+	p0_addr = vfe31_get_ch_addr(ping_pong,
+		vfe31_ctrl->outpath.out2.ch0);
+	/* Chroma channel - Main Image */
+	p1_addr = vfe31_get_ch_addr(ping_pong,
+		vfe31_ctrl->outpath.out2.ch1);
+
+	free_buf = vfe31_get_free_buf(&vfe31_ctrl->outpath.out2);
+	CDBG("%s: snapshot main, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
+		__func__, p0_addr, p1_addr);
+	if (free_buf) {
+		/* Y channel */
+		vfe31_put_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out2.ch0,
+			free_buf->paddr + free_buf->planar0_off);
+		/* Chroma channel */
+		vfe31_put_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out2.ch1,
+			free_buf->paddr + free_buf->planar1_off);
+		kfree(free_buf);
+	}
+	 vfe_send_outmsg(MSG_ID_OUTPUT_S, p0_addr, p1_addr, p0_addr);
+
+	/* Y channel- TN Image */
+	p0_addr = vfe31_get_ch_addr(ping_pong,
+		vfe31_ctrl->outpath.out1.ch0);
+	/* Chroma channel - TN Image */
+	p1_addr = vfe31_get_ch_addr(ping_pong,
+		vfe31_ctrl->outpath.out1.ch1);
+
+	free_buf = vfe31_get_free_buf(&vfe31_ctrl->outpath.out1);
+	CDBG("%s: snapshot TN, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
+		__func__, p0_addr, p1_addr);
+	if (free_buf) {
+		/* Y channel */
+		vfe31_put_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out1.ch0,
+			free_buf->paddr + free_buf->planar0_off);
+		/* Chroma channel */
+		vfe31_put_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out1.ch1,
+			free_buf->paddr + free_buf->planar1_off);
+		kfree(free_buf);
+	}
+
+	vfe_send_outmsg(MSG_ID_OUTPUT_T, p0_addr, p1_addr, p0_addr);
+}
+
+static void vfe31_process_output_path_irq_1(uint32_t ping_pong)
+{
+
+#ifdef CONFIG_MSM_CAMERA_V4L2
+	uint32_t pyaddr_ping, pcbcraddr_ping, pyaddr_pong, pcbcraddr_pong;
+#endif
+	CDBG("%s, operation_mode = %d, cap_cnt = %d\n", __func__,
+		vfe31_ctrl->operation_mode, vfe31_ctrl->vfe_capture_count);
+
+	/* In Snapshot mode */
+	if ((VFE_MODE_OF_OPERATION_SNAPSHOT == vfe31_ctrl->operation_mode)
+		&& ((vfe31_ctrl->vfe_capture_count <= 1)
+		|| (vfe31_free_buf_available(vfe31_ctrl->outpath.out0) &&
+		vfe31_free_buf_available(vfe31_ctrl->outpath.out1)))) {
+		vfe31_process_snapshot_frame(ping_pong);
+	} else if ((VFE_MODE_OF_OPERATION_RAW_SNAPSHOT ==
+		vfe31_ctrl->operation_mode) &&
+		((vfe31_ctrl->vfe_capture_count <= 1) ||
+		vfe31_free_buf_available(vfe31_ctrl->outpath.out1))) {
+		vfe31_process_raw_snapshot_frame(ping_pong);
+	} else if ((VFE_MODE_OF_OPERATION_ZSL == vfe31_ctrl->operation_mode)
+		&& (vfe31_free_buf_available(vfe31_ctrl->outpath.out1)
+		&& vfe31_free_buf_available(vfe31_ctrl->outpath.out2))) {
+		vfe31_process_zsl_frame(ping_pong);
+	} else {
+		vfe31_ctrl->outpath.out1.frame_drop_cnt++;
+		pr_info("path_irq_1 - no free buffer!\n");
+#ifdef CONFIG_MSM_CAMERA_V4L2
+		pr_info("Swapping ping and pong\n");
+
+		/*get addresses*/
+		/* Y channel */
+		pyaddr_ping = vfe31_get_ch_ping_addr(
+			vfe31_ctrl->outpath.out1.ch0);
+		/* Chroma channel */
+		pcbcraddr_ping = vfe31_get_ch_ping_addr(
+			vfe31_ctrl->outpath.out1.ch1);
+		/* Y channel */
+		pyaddr_pong = vfe31_get_ch_pong_addr(
+			vfe31_ctrl->outpath.out1.ch0);
+		/* Chroma channel */
+		pcbcraddr_pong = vfe31_get_ch_pong_addr(
+			vfe31_ctrl->outpath.out1.ch1);
+
+		CDBG("ping = 0x%p, pong = 0x%p\n", (void *)pyaddr_ping,
+			(void *)pyaddr_pong);
+		CDBG("ping_cbcr = 0x%p, pong_cbcr = 0x%p\n",
+			(void *)pcbcraddr_ping, (void *)pcbcraddr_pong);
+
+		/*put addresses*/
+		/* SWAP y channel*/
+		vfe31_put_ch_ping_addr(vfe31_ctrl->outpath.out1.ch0,
+			pyaddr_pong);
+		vfe31_put_ch_pong_addr(vfe31_ctrl->outpath.out1.ch0,
+			pyaddr_ping);
+		/* SWAP chroma channel*/
+		vfe31_put_ch_ping_addr(vfe31_ctrl->outpath.out1.ch1,
+			pcbcraddr_pong);
+		vfe31_put_ch_pong_addr(vfe31_ctrl->outpath.out1.ch1,
+			pcbcraddr_ping);
+		CDBG("after swap: ping = 0x%p, pong = 0x%p\n",
+			(void *)pyaddr_pong, (void *)pyaddr_ping);
+#endif
+	}
+
+}
+
+static void vfe31_process_output_path_irq_2(uint32_t ping_pong)
+{
+	uint32_t p0_addr, p1_addr, p2_addr;
+	struct vfe31_free_buf *free_buf = NULL;
+
+#ifdef CONFIG_MSM_CAMERA_V4L2
+	uint32_t pyaddr_ping, pcbcraddr_ping, pyaddr_pong, pcbcraddr_pong;
+#endif
+	/* we render frames in the following conditions:
+	1. Continuous mode and the free buffer is avaialable.
+	*/
+	CDBG("%s, operation_mode = %d, state %d\n", __func__,
+		vfe31_ctrl->operation_mode,
+		vfe31_ctrl->recording_state);
+	/* Ensure that both wm1 and wm5 ping and pong buffers are active*/
+	if (!(((ping_pong & 0x22) == 0x22) ||
+		((ping_pong & 0x22) == 0x0))) {
+		pr_err(" Irq_2 - skip the frame pp_status is not proper"
+			"PP_status = 0x%x\n", ping_pong);
+		return;
+	}
+	if ((vfe31_ctrl->recording_state == VFE_REC_STATE_STOP_REQUESTED)
+		|| (vfe31_ctrl->recording_state == VFE_REC_STATE_STOPPED)) {
+		vfe31_ctrl->outpath.out2.frame_drop_cnt++;
+		pr_warning("path_irq_2 - recording stopped\n");
+		return;
+	}
+
+	free_buf = vfe31_get_free_buf(&vfe31_ctrl->outpath.out2);
+
+	if (free_buf) {
+		/* Y channel */
+		p0_addr = vfe31_get_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out2.ch0);
+		/* Chroma channel */
+		p1_addr = vfe31_get_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out2.ch1);
+		p2_addr = p0_addr;
+		CDBG("video output, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
+			p0_addr, p1_addr);
+
+		/* Y channel */
+		vfe31_put_ch_addr(ping_pong,
+		vfe31_ctrl->outpath.out2.ch0,
+		free_buf->paddr + free_buf->planar0_off);
+		/* Chroma channel */
+		vfe31_put_ch_addr(ping_pong,
+		vfe31_ctrl->outpath.out2.ch1,
+		free_buf->paddr + free_buf->planar1_off);
+		kfree(free_buf);
+		vfe_send_outmsg(MSG_ID_OUTPUT_V, p0_addr, p1_addr, p2_addr);
+	} else {
+		vfe31_ctrl->outpath.out2.frame_drop_cnt++;
+		pr_warning("path_irq_2 - no free buffer!\n");
+
+#ifdef CONFIG_MSM_CAMERA_V4L2
+		pr_info("Swapping ping and pong\n");
+
+		/*get addresses*/
+		/* Y channel */
+		pyaddr_ping = vfe31_get_ch_ping_addr(
+			vfe31_ctrl->outpath.out2.ch0);
+		/* Chroma channel */
+		pcbcraddr_ping = vfe31_get_ch_ping_addr(
+			vfe31_ctrl->outpath.out2.ch1);
+		/* Y channel */
+		pyaddr_pong = vfe31_get_ch_pong_addr(
+			vfe31_ctrl->outpath.out2.ch0);
+		/* Chroma channel */
+		pcbcraddr_pong = vfe31_get_ch_pong_addr(
+			vfe31_ctrl->outpath.out2.ch1);
+
+		CDBG("ping = 0x%p, pong = 0x%p\n", (void *)pyaddr_ping,
+			(void *)pyaddr_pong);
+		CDBG("ping_cbcr = 0x%p, pong_cbcr = 0x%p\n",
+			(void *)pcbcraddr_ping, (void *)pcbcraddr_pong);
+
+		/*put addresses*/
+		/* SWAP y channel*/
+		vfe31_put_ch_ping_addr(vfe31_ctrl->outpath.out2.ch0,
+			pyaddr_pong);
+		vfe31_put_ch_pong_addr(vfe31_ctrl->outpath.out2.ch0,
+			pyaddr_ping);
+		/* SWAP chroma channel*/
+		vfe31_put_ch_ping_addr(vfe31_ctrl->outpath.out2.ch1,
+			pcbcraddr_pong);
+		vfe31_put_ch_pong_addr(vfe31_ctrl->outpath.out2.ch1,
+			pcbcraddr_ping);
+		CDBG("after swap: ping = 0x%p, pong = 0x%p\n",
+			(void *)pyaddr_pong, (void *)pyaddr_ping);
+#endif
+	}
+}
+
+
+static uint32_t  vfe31_process_stats_irq_common(uint32_t statsNum,
+						uint32_t newAddr) {
+
+	uint32_t pingpongStatus;
+	uint32_t returnAddr;
+	uint32_t pingpongAddr;
+
+	/* must be 0=ping, 1=pong */
+	pingpongStatus =
+		((msm_camera_io_r(vfe31_ctrl->vfebase +
+		VFE_BUS_PING_PONG_STATUS))
+	& ((uint32_t)(1<<(statsNum + 7)))) >> (statsNum + 7);
+	/* stats bits starts at 7 */
+	CDBG("statsNum %d, pingpongStatus %d\n", statsNum, pingpongStatus);
+	pingpongAddr =
+		((uint32_t)(vfe31_ctrl->vfebase +
+				VFE_BUS_STATS_PING_PONG_BASE)) +
+				(3*statsNum)*4 + (1-pingpongStatus)*4;
+	returnAddr = msm_camera_io_r((uint32_t *)pingpongAddr);
+	msm_camera_io_w(newAddr, (uint32_t *)pingpongAddr);
+	return returnAddr;
+}
+
+static void vfe_send_stats_msg(void)
+{
+	struct  vfe_message msg;
+	uint32_t temp;
+
+	/* fill message with right content. */
+	msg._u.msgStats.frameCounter = vfe31_ctrl->vfeFrameId;
+	msg._u.msgStats.status_bits = vfe31_ctrl->status_bits;
+	msg._d = MSG_ID_COMMON;
+
+	msg._u.msgStats.buff.aec = vfe31_ctrl->aecStatsControl.bufToRender;
+	msg._u.msgStats.buff.awb = vfe31_ctrl->awbStatsControl.bufToRender;
+	msg._u.msgStats.buff.af = vfe31_ctrl->afStatsControl.bufToRender;
+
+	msg._u.msgStats.buff.ihist = vfe31_ctrl->ihistStatsControl.bufToRender;
+	msg._u.msgStats.buff.rs = vfe31_ctrl->rsStatsControl.bufToRender;
+	msg._u.msgStats.buff.cs = vfe31_ctrl->csStatsControl.bufToRender;
+
+	temp = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_STATS_AWB_SGW_CFG);
+	msg._u.msgStats.buff.awb_ymin = (0xFF00 & temp) >> 8;
+
+	vfe31_proc_ops(msg._d,
+		&msg, sizeof(struct vfe_message));
+	return;
+}
+
+static void vfe31_process_stats(void)
+{
+	int32_t process_stats = false;
+
+	CDBG("%s, stats = 0x%x\n", __func__, vfe31_ctrl->status_bits);
+
+	if (vfe31_ctrl->status_bits & VFE_IRQ_STATUS0_STATS_AEC) {
+		if (!vfe31_ctrl->aec_ack_pending) {
+			vfe31_ctrl->aec_ack_pending = TRUE;
+			vfe31_ctrl->aecStatsControl.bufToRender =
+				vfe31_process_stats_irq_common(statsAeNum,
+				vfe31_ctrl->aecStatsControl.nextFrameAddrBuf);
+			process_stats = true;
+		} else{
+			vfe31_ctrl->aecStatsControl.bufToRender = 0;
+			vfe31_ctrl->aecStatsControl.droppedStatsFrameCount++;
+		}
+	} else {
+		vfe31_ctrl->aecStatsControl.bufToRender = 0;
+	}
+
+	if (vfe31_ctrl->status_bits & VFE_IRQ_STATUS0_STATS_AWB) {
+		if (!vfe31_ctrl->awb_ack_pending) {
+			vfe31_ctrl->awb_ack_pending = TRUE;
+			vfe31_ctrl->awbStatsControl.bufToRender =
+				vfe31_process_stats_irq_common(statsAwbNum,
+				vfe31_ctrl->awbStatsControl.nextFrameAddrBuf);
+			process_stats = true;
+		} else{
+			vfe31_ctrl->awbStatsControl.droppedStatsFrameCount++;
+			vfe31_ctrl->awbStatsControl.bufToRender = 0;
+		}
+	} else {
+		vfe31_ctrl->awbStatsControl.bufToRender = 0;
+	}
+
+
+	if (vfe31_ctrl->status_bits & VFE_IRQ_STATUS0_STATS_AF) {
+		if (!vfe31_ctrl->af_ack_pending) {
+			vfe31_ctrl->af_ack_pending = TRUE;
+			vfe31_ctrl->afStatsControl.bufToRender =
+				vfe31_process_stats_irq_common(statsAfNum,
+				vfe31_ctrl->afStatsControl.nextFrameAddrBuf);
+			process_stats = true;
+		} else {
+			vfe31_ctrl->afStatsControl.bufToRender = 0;
+			vfe31_ctrl->afStatsControl.droppedStatsFrameCount++;
+		}
+	} else {
+		vfe31_ctrl->afStatsControl.bufToRender = 0;
+	}
+
+	if (vfe31_ctrl->status_bits & VFE_IRQ_STATUS0_STATS_IHIST) {
+		if (!vfe31_ctrl->ihist_ack_pending) {
+			vfe31_ctrl->ihist_ack_pending = TRUE;
+			vfe31_ctrl->ihistStatsControl.bufToRender =
+				vfe31_process_stats_irq_common(statsIhistNum,
+				vfe31_ctrl->ihistStatsControl.nextFrameAddrBuf);
+			process_stats = true;
+		} else {
+			vfe31_ctrl->ihistStatsControl.droppedStatsFrameCount++;
+			vfe31_ctrl->ihistStatsControl.bufToRender = 0;
+		}
+	} else {
+		vfe31_ctrl->ihistStatsControl.bufToRender = 0;
+	}
+
+	if (vfe31_ctrl->status_bits & VFE_IRQ_STATUS0_STATS_RS) {
+		if (!vfe31_ctrl->rs_ack_pending) {
+			vfe31_ctrl->rs_ack_pending = TRUE;
+			vfe31_ctrl->rsStatsControl.bufToRender =
+				vfe31_process_stats_irq_common(statsRsNum,
+				vfe31_ctrl->rsStatsControl.nextFrameAddrBuf);
+			process_stats = true;
+		} else {
+			vfe31_ctrl->rsStatsControl.droppedStatsFrameCount++;
+			vfe31_ctrl->rsStatsControl.bufToRender = 0;
+		}
+	} else {
+		vfe31_ctrl->rsStatsControl.bufToRender = 0;
+	}
+
+
+	if (vfe31_ctrl->status_bits & VFE_IRQ_STATUS0_STATS_CS) {
+		if (!vfe31_ctrl->cs_ack_pending) {
+			vfe31_ctrl->cs_ack_pending = TRUE;
+			vfe31_ctrl->csStatsControl.bufToRender =
+				vfe31_process_stats_irq_common(statsCsNum,
+				vfe31_ctrl->csStatsControl.nextFrameAddrBuf);
+			process_stats = true;
+		} else {
+			vfe31_ctrl->csStatsControl.droppedStatsFrameCount++;
+			vfe31_ctrl->csStatsControl.bufToRender = 0;
+		}
+	} else {
+		vfe31_ctrl->csStatsControl.bufToRender = 0;
+	}
+
+	if (process_stats)
+		vfe_send_stats_msg();
+
+	return;
+}
+
+static void vfe31_process_stats_irq(uint32_t *irqstatus)
+{
+	/* Subsample the stats according to the hfr speed*/
+	if ((vfe31_ctrl->hfr_mode != HFR_MODE_OFF) &&
+		(vfe31_ctrl->vfeFrameId % vfe31_ctrl->hfr_mode != 0)) {
+		CDBG("Skip the stats when HFR enabled\n");
+		return;
+	}
+
+	vfe31_ctrl->status_bits = VFE_COM_STATUS & *irqstatus;
+	vfe31_process_stats();
+	return;
+}
+
+static void vfe31_do_tasklet(unsigned long data)
+{
+	unsigned long flags;
+
+	struct vfe31_isr_queue_cmd *qcmd = NULL;
+
+	CDBG("=== vfe31_do_tasklet start === \n");
+
+	while (atomic_read(&irq_cnt)) {
+		spin_lock_irqsave(&vfe31_ctrl->tasklet_lock, flags);
+		qcmd = list_first_entry(&vfe31_ctrl->tasklet_q,
+			struct vfe31_isr_queue_cmd, list);
+		atomic_sub(1, &irq_cnt);
+
+		if (!qcmd) {
+			spin_unlock_irqrestore(&vfe31_ctrl->tasklet_lock,
+				flags);
+			return;
+		}
+
+		list_del(&qcmd->list);
+		spin_unlock_irqrestore(&vfe31_ctrl->tasklet_lock,
+			flags);
+
+		/* interrupt to be processed,  *qcmd has the payload.  */
+		if (qcmd->vfeInterruptStatus0 &
+			VFE_IRQ_STATUS0_REG_UPDATE_MASK) {
+			CDBG("irq regUpdateIrq\n");
+			vfe31_process_reg_update_irq();
+		}
+
+		if (qcmd->vfeInterruptStatus1 &
+			VFE_IMASK_RESET) {
+			CDBG("irq resetAckIrq\n");
+			vfe31_process_reset_irq();
+		}
+
+
+		if (qcmd->vfeInterruptStatus1 &
+			VFE_IMASK_AXI_HALT) {
+			CDBG("irq axi halt irq\n");
+			vfe31_process_axi_halt_irq();
+		}
+
+		if (atomic_read(&vfe31_ctrl->vstate)) {
+			if (qcmd->vfeInterruptStatus1 &
+					VFE31_IMASK_ERROR_ONLY_1) {
+				pr_err("irq	errorIrq\n");
+				vfe31_process_error_irq(
+					qcmd->vfeInterruptStatus1 &
+					VFE31_IMASK_ERROR_ONLY_1);
+			}
+
+			/* irqs below are only valid when in active state. */
+			/* next, check output path related interrupts. */
+			if (qcmd->vfeInterruptStatus0 &
+				VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK) {
+				CDBG("Image composite done 0 irq occured.\n");
+				vfe31_process_output_path_irq_0(
+					qcmd->vfePingPongStatus);
+			}
+
+			if (qcmd->vfeInterruptStatus0 &
+				VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK) {
+				CDBG("Image composite done 1 irq occured.\n");
+				vfe31_process_output_path_irq_1(
+					qcmd->vfePingPongStatus);
+			}
+
+			if (qcmd->vfeInterruptStatus0 &
+				VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE2_MASK) {
+				CDBG("Image composite done 2 irq occured.\n");
+				vfe31_process_output_path_irq_2(
+					qcmd->vfePingPongStatus);
+			}
+
+			/* then process stats irq. */
+			if (vfe31_ctrl->stats_comp) {
+				/* process stats comb interrupt. */
+				if (qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK) {
+					CDBG("Stats composite irq occured.\n");
+					vfe31_process_stats_irq(
+						&qcmd->vfeInterruptStatus0);
+				}
+			} else {
+				/* process individual stats interrupt. */
+				if (qcmd->vfeInterruptStatus0 &
+						VFE_COM_STATUS) {
+					CDBG("VFE stats occured.\n");
+					vfe31_process_stats_irq(
+						&qcmd->vfeInterruptStatus0);
+				}
+				if (qcmd->vfeInterruptStatus0 &
+						VFE_IRQ_STATUS0_SYNC_TIMER0) {
+					CDBG("SYNC_TIMER 0 irq occured.\n");
+					vfe31_send_msg_no_payload(
+						MSG_ID_SYNC_TIMER0_DONE);
+				}
+				if (qcmd->vfeInterruptStatus0 &
+						VFE_IRQ_STATUS0_SYNC_TIMER1) {
+					CDBG("SYNC_TIMER 1 irq occured.\n");
+					vfe31_send_msg_no_payload(
+						MSG_ID_SYNC_TIMER1_DONE);
+				}
+				if (qcmd->vfeInterruptStatus0 &
+						VFE_IRQ_STATUS0_SYNC_TIMER2) {
+					CDBG("SYNC_TIMER 2 irq occured.\n");
+					vfe31_send_msg_no_payload(
+						MSG_ID_SYNC_TIMER2_DONE);
+				}
+			}
+		}
+		if (qcmd->vfeInterruptStatus0 &
+				VFE_IRQ_STATUS0_CAMIF_SOF_MASK) {
+			CDBG("irq	camifSofIrq\n");
+			vfe31_process_camif_sof_irq();
+		}
+		kfree(qcmd);
+	}
+	CDBG("=== vfe31_do_tasklet end === \n");
+}
+
+DECLARE_TASKLET(vfe31_tasklet, vfe31_do_tasklet, 0);
+
+static irqreturn_t vfe31_parse_irq(int irq_num, void *data)
+{
+	unsigned long flags;
+	struct vfe31_irq_status irq;
+	struct vfe31_isr_queue_cmd *qcmd;
+	uint32_t *val;
+	CDBG("vfe_parse_irq\n");
+	memset(&irq, 0, sizeof(struct vfe31_irq_status));
+
+	val = (uint32_t *)(vfe31_ctrl->vfebase + VFE_IRQ_STATUS_0);
+	irq.vfeIrqStatus0 = msm_camera_io_r(val);
+
+	val = (uint32_t *)(vfe31_ctrl->vfebase + VFE_IRQ_STATUS_1);
+	irq.vfeIrqStatus1 = msm_camera_io_r(val);
+
+	if (irq.vfeIrqStatus1 & VFE_IMASK_AXI_HALT) {
+		msm_camera_io_w(VFE_IMASK_RESET,
+			vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
+		msm_camera_io_w_mb(AXI_HALT_CLEAR,
+			vfe31_ctrl->vfebase + VFE_AXI_CMD);
+	}
+
+	val = (uint32_t *)(vfe31_ctrl->vfebase + VFE_CAMIF_STATUS);
+	irq.camifStatus = msm_camera_io_r(val);
+	CDBG("camifStatus  = 0x%x\n", irq.camifStatus);
+
+	val = (uint32_t *)(vfe31_ctrl->vfebase + VFE_BUS_PING_PONG_STATUS);
+	irq.vfePingPongStatus = msm_camera_io_r(val);
+
+	/* clear the pending interrupt of the same kind.*/
+	msm_camera_io_w(irq.vfeIrqStatus0,
+		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_0);
+	msm_camera_io_w(irq.vfeIrqStatus1,
+		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_1);
+
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_IRQ_CMD);
+
+	if ((irq.vfeIrqStatus0 == 0) && (irq.vfeIrqStatus1 == 0)) {
+		CDBG("vfe_parse_irq: vfeIrqStatus0 & 1 are both 0!\n");
+		return IRQ_HANDLED;
+	}
+
+	qcmd = kzalloc(sizeof(struct vfe31_isr_queue_cmd),
+		GFP_ATOMIC);
+	if (!qcmd) {
+		pr_err("vfe_parse_irq: qcmd malloc failed!\n");
+		return IRQ_HANDLED;
+	}
+
+	if (atomic_read(&vfe31_ctrl->stop_ack_pending)) {
+		irq.vfeIrqStatus0 &= VFE_IMASK_WHILE_STOPPING_0;
+		irq.vfeIrqStatus1 &= vfe31_ctrl->while_stopping_mask;
+	}
+
+	spin_lock_irqsave(&vfe31_ctrl->xbar_lock, flags);
+	if ((irq.vfeIrqStatus0 &
+		VFE_IRQ_STATUS0_CAMIF_EOF_MASK) &&
+		vfe31_ctrl->xbar_update_pending) {
+		CDBG("irq camifEofIrq\n");
+		msm_camera_io_memcpy(vfe31_ctrl->vfebase + V31_XBAR_CFG_OFF,
+			(void *)vfe31_ctrl->xbar_cfg, V31_XBAR_CFG_LEN);
+		vfe31_ctrl->xbar_update_pending = 0;
+	}
+	spin_unlock_irqrestore(&vfe31_ctrl->xbar_lock, flags);
+	CDBG("vfe_parse_irq: Irq_status0 = 0x%x, Irq_status1 = 0x%x.\n",
+		irq.vfeIrqStatus0, irq.vfeIrqStatus1);
+
+	qcmd->vfeInterruptStatus0 = irq.vfeIrqStatus0;
+	qcmd->vfeInterruptStatus1 = irq.vfeIrqStatus1;
+	qcmd->vfePingPongStatus = irq.vfePingPongStatus;
+
+	spin_lock_irqsave(&vfe31_ctrl->tasklet_lock, flags);
+	list_add_tail(&qcmd->list, &vfe31_ctrl->tasklet_q);
+
+	atomic_add(1, &irq_cnt);
+	spin_unlock_irqrestore(&vfe31_ctrl->tasklet_lock, flags);
+	tasklet_schedule(&vfe31_tasklet);
+	return IRQ_HANDLED;
+}
+
+static void vfe31_release(struct platform_device *pdev)
+{
+	struct resource	*vfemem, *vfeio;
+
+	vfe31_reset_free_buf_queue_all();
+	CDBG("%s, free_irq\n", __func__);
+	free_irq(vfe31_ctrl->vfeirq, 0);
+	tasklet_kill(&vfe31_tasklet);
+
+	if (atomic_read(&irq_cnt))
+		pr_warning("%s, Warning IRQ Count not ZERO\n", __func__);
+
+	vfemem = vfe31_ctrl->vfemem;
+	vfeio  = vfe31_ctrl->vfeio;
+
+	msm_vpe_release();
+
+	kfree(vfe31_ctrl->extdata);
+	iounmap(vfe31_ctrl->vfebase);
+	kfree(vfe31_ctrl);
+	vfe31_ctrl = NULL;
+	release_mem_region(vfemem->start, (vfemem->end - vfemem->start) + 1);
+	CDBG("%s, msm_camio_disable\n", __func__);
+	msm_camio_disable(pdev);
+	msm_camio_set_perf_lvl(S_EXIT);
+
+	vfe_syncdata = NULL;
+}
+
+static int vfe31_resource_init(struct msm_vfe_callback *presp,
+	struct platform_device *pdev, void *sdata)
+{
+	struct resource	*vfemem, *vfeirq, *vfeio;
+	int rc;
+	struct msm_camera_sensor_info *s_info;
+	s_info = pdev->dev.platform_data;
+
+	pdev->resource = s_info->resource;
+	pdev->num_resources = s_info->num_resources;
+
+	vfemem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!vfemem) {
+		pr_err("%s: no mem resource?\n", __func__);
+		return -ENODEV;
+	}
+
+	vfeirq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!vfeirq) {
+		pr_err("%s: no irq resource?\n", __func__);
+		return -ENODEV;
+	}
+
+	vfeio = request_mem_region(vfemem->start,
+		resource_size(vfemem), pdev->name);
+	if (!vfeio) {
+		pr_err("%s: VFE region already claimed\n", __func__);
+		return -EBUSY;
+	}
+
+	vfe31_ctrl = kzalloc(sizeof(struct vfe31_ctrl_type), GFP_KERNEL);
+	if (!vfe31_ctrl) {
+		rc = -ENOMEM;
+		goto cmd_init_failed1;
+	}
+
+	vfe31_ctrl->vfeirq = vfeirq->start;
+
+	vfe31_ctrl->vfebase =
+		ioremap(vfemem->start, (vfemem->end - vfemem->start) + 1);
+	if (!vfe31_ctrl->vfebase) {
+		rc = -ENOMEM;
+		pr_err("%s: vfe ioremap failed\n", __func__);
+		goto cmd_init_failed2;
+	}
+
+	if (presp && presp->vfe_resp)
+		vfe31_ctrl->resp = presp;
+	else {
+		rc = -EINVAL;
+		goto cmd_init_failed3;
+	}
+
+	vfe31_ctrl->extdata =
+		kmalloc(sizeof(struct vfe31_frame_extra), GFP_KERNEL);
+	if (!vfe31_ctrl->extdata) {
+		rc = -ENOMEM;
+		goto cmd_init_failed3;
+	}
+
+	vfe31_ctrl->extlen = sizeof(struct vfe31_frame_extra);
+
+	spin_lock_init(&vfe31_ctrl->io_lock);
+	spin_lock_init(&vfe31_ctrl->update_ack_lock);
+	spin_lock_init(&vfe31_ctrl->tasklet_lock);
+	spin_lock_init(&vfe31_ctrl->xbar_lock);
+
+	INIT_LIST_HEAD(&vfe31_ctrl->tasklet_q);
+	vfe31_init_free_buf_queue();
+
+	vfe31_ctrl->syncdata = sdata;
+	vfe31_ctrl->vfemem = vfemem;
+	vfe31_ctrl->vfeio  = vfeio;
+	vfe31_ctrl->update_gamma = false;
+	vfe31_ctrl->update_luma = false;
+	vfe31_ctrl->s_info = s_info;
+	vfe31_ctrl->stats_comp = 0;
+	vfe31_ctrl->hfr_mode = HFR_MODE_OFF;
+	return 0;
+
+cmd_init_failed3:
+	free_irq(vfe31_ctrl->vfeirq, 0);
+	iounmap(vfe31_ctrl->vfebase);
+cmd_init_failed2:
+	kfree(vfe31_ctrl);
+cmd_init_failed1:
+	release_mem_region(vfemem->start, (vfemem->end - vfemem->start) + 1);
+	return rc;
+}
+
+static int vfe31_init(struct msm_vfe_callback *presp,
+	struct platform_device *pdev)
+{
+	int rc = 0;
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+
+	camio_clk = camdev->ioclk;
+
+	rc = vfe31_resource_init(presp, pdev, vfe_syncdata);
+	if (rc < 0)
+		return rc;
+	/* Bring up all the required GPIOs and Clocks */
+	rc = msm_camio_enable(pdev);
+	msm_camio_set_perf_lvl(S_INIT);
+	if (msm_vpe_open() < 0)
+		CDBG("%s: vpe_open failed\n", __func__);
+
+	/* TO DO: Need to release the VFE resources */
+	rc = request_irq(vfe31_ctrl->vfeirq, vfe31_parse_irq,
+			IRQF_TRIGGER_RISING, "vfe", 0);
+
+	return rc;
+}
+
+void msm_camvfe_fn_init(struct msm_camvfe_fn *fptr, void *data)
+{
+	fptr->vfe_init    = vfe31_init;
+	fptr->vfe_enable  = vfe31_enable;
+	fptr->vfe_config  = vfe31_config;
+	fptr->vfe_disable = vfe31_disable;
+	fptr->vfe_release = vfe31_release;
+	fptr->vfe_stop = vfe31_stop;
+	vfe_syncdata = data;
+}
+
+void msm_camvpe_fn_init(struct msm_camvpe_fn *fptr, void *data)
+{
+	fptr->vpe_reg		= msm_vpe_reg;
+	fptr->send_frame_to_vpe	= msm_send_frame_to_vpe;
+	fptr->vpe_config	= msm_vpe_config;
+	fptr->vpe_cfg_update	= msm_vpe_cfg_update;
+	fptr->dis		= &(vpe_ctrl->dis_en);
+	fptr->vpe_cfg_offset = msm_vpe_offset_update;
+	vpe_ctrl->syncdata = data;
+}
diff --git a/drivers/media/platform/msm/camera_v1/vfe/msm_vfe31.h b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe31.h
new file mode 100644
index 0000000..4e1a8d4
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe31.h
@@ -0,0 +1,1119 @@
+/* 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.
+ *
+ */
+
+#ifndef __MSM_VFE31_H__
+#define __MSM_VFE31_H__
+
+#define TRUE  1
+#define FALSE 0
+
+/* at start of camif,  bit 1:0 = 0x01:enable
+ * image data capture at frame boundary. */
+#define CAMIF_COMMAND_START  0x00000005
+
+/* bit 2= 0x1:clear the CAMIF_STATUS register
+ * value. */
+#define CAMIF_COMMAND_CLEAR  0x00000004
+
+/* at stop of vfe pipeline, for now it is assumed
+ * that camif will stop at any time. Bit 1:0 = 0x10:
+ * disable image data capture immediately. */
+#define CAMIF_COMMAND_STOP_IMMEDIATELY  0x00000002
+
+/* at stop of vfe pipeline, for now it is assumed
+ * that camif will stop at any time. Bit 1:0 = 0x00:
+ * disable image data capture at frame boundary */
+#define CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY  0x00000000
+
+/* to halt axi bridge */
+#define AXI_HALT  0x00000001
+
+/* clear the halt bit. */
+#define AXI_HALT_CLEAR  0x00000000
+
+/* clear axi_halt_irq */
+#define MASK_AXI_HALT_IRQ	0xFF7FFFFF
+
+/* reset the pipeline when stop command is issued.
+ * (without reset the register.) bit 26-31 = 0,
+ * domain reset, bit 0-9 = 1 for module reset, except
+ * register module. */
+#define VFE_RESET_UPON_STOP_CMD  0x000003ef
+
+/* reset the pipeline when reset command.
+ * bit 26-31 = 0, domain reset, bit 0-9 = 1 for module reset. */
+#define VFE_RESET_UPON_RESET_CMD  0x000003ff
+
+/* bit 5 is for axi status idle or busy.
+ * 1 =  halted,  0 = busy */
+#define AXI_STATUS_BUSY_MASK 0x00000020
+
+/* bit 0 & bit 1 = 1, both y and cbcr irqs need to be present
+ * for frame done interrupt */
+#define VFE_COMP_IRQ_BOTH_Y_CBCR 3
+
+/* bit 1 = 1, only cbcr irq triggers frame done interrupt */
+#define VFE_COMP_IRQ_CBCR_ONLY 2
+
+/* bit 0 = 1, only y irq triggers frame done interrupt */
+#define VFE_COMP_IRQ_Y_ONLY 1
+
+/* bit 0 = 1, PM go;   bit1 = 1, PM stop */
+#define VFE_PERFORMANCE_MONITOR_GO   0x00000001
+#define VFE_PERFORMANCE_MONITOR_STOP 0x00000002
+
+/* bit 0 = 1, test gen go;   bit1 = 1, test gen stop */
+#define VFE_TEST_GEN_GO   0x00000001
+#define VFE_TEST_GEN_STOP 0x00000002
+
+/* the chroma is assumed to be interpolated between
+ * the luma samples.  JPEG 4:2:2 */
+#define VFE_CHROMA_UPSAMPLE_INTERPOLATED 0
+
+/* constants for irq registers */
+#define VFE_DISABLE_ALL_IRQS 0
+/* bit =1 is to clear the corresponding bit in VFE_IRQ_STATUS.  */
+#define VFE_CLEAR_ALL_IRQS   0xffffffff
+
+#define VFE_IRQ_STATUS0_CAMIF_SOF_MASK            0x00000001
+#define VFE_IRQ_STATUS0_CAMIF_EOF_MASK            0x00000004
+#define VFE_IRQ_STATUS0_REG_UPDATE_MASK           0x00000020
+#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK 0x00200000
+#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK 0x00400000
+#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE2_MASK 0x00800000
+#define VFE_IRQ_STATUS1_RESET_AXI_HALT_ACK_MASK   0x00800000
+#define VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK       0x01000000
+
+#define VFE_IRQ_STATUS0_STATS_AEC     0x2000  /* bit 13 */
+#define VFE_IRQ_STATUS0_STATS_AF      0x4000  /* bit 14 */
+#define VFE_IRQ_STATUS0_STATS_AWB     0x8000  /* bit 15 */
+#define VFE_IRQ_STATUS0_STATS_RS      0x10000  /* bit 16 */
+#define VFE_IRQ_STATUS0_STATS_CS      0x20000  /* bit 17 */
+#define VFE_IRQ_STATUS0_STATS_IHIST   0x40000  /* bit 18 */
+
+#define VFE_IRQ_STATUS0_SYNC_TIMER0   0x2000000  /* bit 25 */
+#define VFE_IRQ_STATUS0_SYNC_TIMER1   0x4000000  /* bit 26 */
+#define VFE_IRQ_STATUS0_SYNC_TIMER2   0x8000000  /* bit 27 */
+#define VFE_IRQ_STATUS0_ASYNC_TIMER0  0x10000000  /* bit 28 */
+#define VFE_IRQ_STATUS0_ASYNC_TIMER1  0x20000000  /* bit 29 */
+#define VFE_IRQ_STATUS0_ASYNC_TIMER2  0x40000000  /* bit 30 */
+#define VFE_IRQ_STATUS0_ASYNC_TIMER3  0x80000000  /* bit 31 */
+
+/* imask for while waiting for stop ack,  driver has already
+ * requested stop, waiting for reset irq, and async timer irq.
+ * For irq_status_0, bit 28-31 are for async timer. For
+ * irq_status_1, bit 22 for reset irq, bit 23 for axi_halt_ack
+   irq */
+#define VFE_IMASK_WHILE_STOPPING_0  0xF0000000
+#define VFE_IMASK_WHILE_STOPPING_1  0x00C00000
+#define VFE_IMASK_RESET             0x00400000
+#define VFE_IMASK_AXI_HALT          0x00800000
+
+
+/* no error irq in mask 0 */
+#define VFE_IMASK_ERROR_ONLY_0  0x0
+/* when normal case, don't want to block error status. */
+/* bit 0-21 are error irq bits */
+#define VFE_IMASK_ERROR_ONLY_1  0x003fffff
+
+/* For BPC bit 0,bit 12-17 and bit 26 -20 are set to zero and other's 1 */
+#define BPC_MASK 0xF80C0FFE
+
+/* For BPC bit 1 and 2 are set to zero and other's 1 */
+#define ABF_MASK 0xFFFFFFF9
+
+/* For MCE enable bit 28 set to zero and other's 1 */
+#define MCE_EN_MASK 0xEFFFFFFF
+
+/* For MCE Q_K bit 28 to 31 set to zero and other's 1 */
+#define MCE_Q_K_MASK 0x0FFFFFFF
+
+#define AWB_ENABLE_MASK 0x00000080     /* bit 7 */
+#define AF_ENABLE_MASK 0x00000040      /* bit 6 */
+#define AE_ENABLE_MASK 0x00000020      /* bit 5 */
+#define IHIST_ENABLE_MASK 0x00008000   /* bit 15 */
+#define RS_ENABLE_MASK 0x00000100      /* bit 8  */
+#define CS_ENABLE_MASK 0x00000200      /* bit 9  */
+#define RS_CS_ENABLE_MASK 0x00000300   /* bit 8,9  */
+#define STATS_ENABLE_MASK 0x000483E0   /* bit 18,15,9,8,7,6,5*/
+
+#define VFE_REG_UPDATE_TRIGGER           1
+#define VFE_PM_BUF_MAX_CNT_MASK          0xFF
+#define VFE_DMI_CFG_DEFAULT              0x00000100
+#define LENS_ROLL_OFF_DELTA_TABLE_OFFSET 32
+#define VFE_AE_PINGPONG_STATUS_BIT       0x80
+#define VFE_AF_PINGPONG_STATUS_BIT       0x100
+#define VFE_AWB_PINGPONG_STATUS_BIT      0x200
+#define PINGPONG_LOWER                   0x7
+
+#define HFR_MODE_OFF 1
+
+enum VFE31_DMI_RAM_SEL {
+	 NO_MEM_SELECTED          = 0,
+	 ROLLOFF_RAM              = 0x1,
+	 RGBLUT_RAM_CH0_BANK0     = 0x2,
+	 RGBLUT_RAM_CH0_BANK1     = 0x3,
+	 RGBLUT_RAM_CH1_BANK0     = 0x4,
+	 RGBLUT_RAM_CH1_BANK1     = 0x5,
+	 RGBLUT_RAM_CH2_BANK0     = 0x6,
+	 RGBLUT_RAM_CH2_BANK1     = 0x7,
+	 STATS_HIST_RAM           = 0x8,
+	 RGBLUT_CHX_BANK0         = 0x9,
+	 RGBLUT_CHX_BANK1         = 0xa,
+	 LUMA_ADAPT_LUT_RAM_BANK0 = 0xb,
+	 LUMA_ADAPT_LUT_RAM_BANK1 = 0xc
+};
+
+enum  VFE_STATE {
+	VFE_STATE_IDLE,
+	VFE_STATE_ACTIVE
+};
+
+enum  vfe_recording_state {
+	VFE_REC_STATE_IDLE,
+	VFE_REC_STATE_START_REQUESTED,
+	VFE_REC_STATE_STARTED,
+	VFE_REC_STATE_STOP_REQUESTED,
+	VFE_REC_STATE_STOPPED,
+};
+
+#define V31_DUMMY_0               0
+#define V31_SET_CLK               1
+#define V31_RESET                 2
+#define V31_START                 3
+#define V31_TEST_GEN_START        4
+#define V31_OPERATION_CFG         5
+#define V31_AXI_OUT_CFG           6
+#define V31_CAMIF_CFG             7
+#define V31_AXI_INPUT_CFG         8
+#define V31_BLACK_LEVEL_CFG       9
+#define V31_ROLL_OFF_CFG          10
+#define V31_DEMUX_CFG             11
+#define V31_DEMOSAIC_0_CFG        12 /* general */
+#define V31_DEMOSAIC_1_CFG        13 /* ABF     */
+#define V31_DEMOSAIC_2_CFG        14 /* BPC     */
+#define V31_FOV_CFG               15
+#define V31_MAIN_SCALER_CFG       16
+#define V31_WB_CFG                17
+#define V31_COLOR_COR_CFG         18
+#define V31_RGB_G_CFG             19
+#define V31_LA_CFG                20
+#define V31_CHROMA_EN_CFG         21
+#define V31_CHROMA_SUP_CFG        22
+#define V31_MCE_CFG               23
+#define V31_SK_ENHAN_CFG          24
+#define V31_ASF_CFG               25
+#define V31_S2Y_CFG               26
+#define V31_S2CbCr_CFG            27
+#define V31_CHROMA_SUBS_CFG       28
+#define V31_OUT_CLAMP_CFG         29
+#define V31_FRAME_SKIP_CFG        30
+#define V31_DUMMY_1               31
+#define V31_DUMMY_2               32
+#define V31_DUMMY_3               33
+#define V31_UPDATE                34
+#define V31_BL_LVL_UPDATE         35
+#define V31_DEMUX_UPDATE          36
+#define V31_DEMOSAIC_1_UPDATE     37 /* BPC */
+#define V31_DEMOSAIC_2_UPDATE     38 /* ABF */
+#define V31_FOV_UPDATE            39
+#define V31_MAIN_SCALER_UPDATE    40
+#define V31_WB_UPDATE             41
+#define V31_COLOR_COR_UPDATE      42
+#define V31_RGB_G_UPDATE          43
+#define V31_LA_UPDATE             44
+#define V31_CHROMA_EN_UPDATE      45
+#define V31_CHROMA_SUP_UPDATE     46
+#define V31_MCE_UPDATE            47
+#define V31_SK_ENHAN_UPDATE       48
+#define V31_S2CbCr_UPDATE         49
+#define V31_S2Y_UPDATE            50
+#define V31_ASF_UPDATE            51
+#define V31_FRAME_SKIP_UPDATE     52
+#define V31_CAMIF_FRAME_UPDATE    53
+#define V31_STATS_AF_UPDATE       54
+#define V31_STATS_AE_UPDATE       55
+#define V31_STATS_AWB_UPDATE      56
+#define V31_STATS_RS_UPDATE       57
+#define V31_STATS_CS_UPDATE       58
+#define V31_STATS_SKIN_UPDATE     59
+#define V31_STATS_IHIST_UPDATE    60
+#define V31_DUMMY_4               61
+#define V31_EPOCH1_ACK            62
+#define V31_EPOCH2_ACK            63
+#define V31_START_RECORDING       64
+#define V31_STOP_RECORDING        65
+#define V31_DUMMY_5               66
+#define V31_DUMMY_6               67
+#define V31_CAPTURE               68
+#define V31_DUMMY_7               69
+#define V31_STOP                  70
+#define V31_GET_HW_VERSION        71
+#define V31_GET_FRAME_SKIP_COUNTS 72
+#define V31_OUTPUT1_BUFFER_ENQ    73
+#define V31_OUTPUT2_BUFFER_ENQ    74
+#define V31_OUTPUT3_BUFFER_ENQ    75
+#define V31_JPEG_OUT_BUF_ENQ      76
+#define V31_RAW_OUT_BUF_ENQ       77
+#define V31_RAW_IN_BUF_ENQ        78
+#define V31_STATS_AF_ENQ          79
+#define V31_STATS_AE_ENQ          80
+#define V31_STATS_AWB_ENQ         81
+#define V31_STATS_RS_ENQ          82
+#define V31_STATS_CS_ENQ          83
+#define V31_STATS_SKIN_ENQ        84
+#define V31_STATS_IHIST_ENQ       85
+#define V31_DUMMY_8               86
+#define V31_JPEG_ENC_CFG          87
+#define V31_DUMMY_9               88
+#define V31_STATS_AF_START        89
+#define V31_STATS_AF_STOP         90
+#define V31_STATS_AE_START        91
+#define V31_STATS_AE_STOP         92
+#define V31_STATS_AWB_START       93
+#define V31_STATS_AWB_STOP        94
+#define V31_STATS_RS_START        95
+#define V31_STATS_RS_STOP         96
+#define V31_STATS_CS_START        97
+#define V31_STATS_CS_STOP         98
+#define V31_STATS_SKIN_START      99
+#define V31_STATS_SKIN_STOP       100
+#define V31_STATS_IHIST_START     101
+#define V31_STATS_IHIST_STOP      102
+#define V31_DUMMY_10              103
+#define V31_SYNC_TIMER_SETTING    104
+#define V31_ASYNC_TIMER_SETTING   105
+#define V31_LIVESHOT              106
+#define V31_ZSL                   107
+#define V31_STEREOCAM             108
+#define V31_LA_SETUP              109
+#define V31_XBAR_CFG              110
+#define V31_EZTUNE_CFG            111
+
+#define V31_CAMIF_OFF             0x000001E4
+#define V31_CAMIF_LEN             32
+
+#define V31_DEMUX_OFF             0x00000284
+#define V31_DEMUX_LEN             20
+
+#define V31_DEMOSAIC_0_OFF        0x00000298
+#define V31_DEMOSAIC_0_LEN        4
+/* ABF     */
+#define V31_DEMOSAIC_1_OFF        0x000002A4
+#define V31_DEMOSAIC_1_LEN        180
+/* BPC     */
+#define V31_DEMOSAIC_2_OFF        0x0000029C
+#define V31_DEMOSAIC_2_LEN        8
+
+/* gamma VFE_LUT_BANK_SEL*/
+#define V31_GAMMA_CFG_OFF         0x000003BC
+#define V31_LUMA_CFG_OFF          0x000003C0
+
+#define V31_OUT_CLAMP_OFF         0x00000524
+#define V31_OUT_CLAMP_LEN         8
+
+#define V31_OPERATION_CFG_LEN     32
+
+#define V31_AXI_OUT_OFF           0x00000038
+#define V31_AXI_OUT_LEN           220
+#define V31_AXI_CH_INF_LEN        32
+#define V31_AXI_CFG_LEN           47
+
+#define V31_FRAME_SKIP_OFF        0x00000504
+#define V31_FRAME_SKIP_LEN        32
+
+#define V31_CHROMA_SUBS_OFF       0x000004F8
+#define V31_CHROMA_SUBS_LEN       12
+
+#define V31_FOV_OFF           0x00000360
+#define V31_FOV_LEN           8
+
+#define V31_MAIN_SCALER_OFF 0x00000368
+#define V31_MAIN_SCALER_LEN 28
+
+#define V31_S2Y_OFF 0x000004D0
+#define V31_S2Y_LEN 20
+
+#define V31_S2CbCr_OFF 0x000004E4
+#define V31_S2CbCr_LEN 20
+
+#define V31_CHROMA_EN_OFF 0x000003C4
+#define V31_CHROMA_EN_LEN 36
+
+#define V31_SYNC_TIMER_OFF      0x0000020C
+#define V31_SYNC_TIMER_POLARITY_OFF 0x00000234
+#define V31_TIMER_SELECT_OFF        0x0000025C
+#define V31_SYNC_TIMER_LEN 28
+
+#define V31_ASYNC_TIMER_OFF 0x00000238
+#define V31_ASYNC_TIMER_LEN 28
+
+#define V31_BLACK_LEVEL_OFF 0x00000264
+#define V31_BLACK_LEVEL_LEN 16
+
+#define V31_ROLL_OFF_CFG_OFF 0x00000274
+#define V31_ROLL_OFF_CFG_LEN 16
+
+#define V31_COLOR_COR_OFF 0x00000388
+#define V31_COLOR_COR_LEN 52
+
+#define V31_WB_OFF 0x00000384
+#define V31_WB_LEN 4
+
+#define V31_RGB_G_OFF 0x000003BC
+#define V31_RGB_G_LEN 4
+
+#define V31_LA_OFF 0x000003C0
+#define V31_LA_LEN 4
+
+#define V31_SCE_OFF 0x00000418
+#define V31_SCE_LEN 136
+
+#define V31_CHROMA_SUP_OFF 0x000003E8
+#define V31_CHROMA_SUP_LEN 12
+
+#define V31_MCE_OFF 0x000003F4
+#define V31_MCE_LEN 36
+#define V31_STATS_AF_OFF 0x0000053c
+#define V31_STATS_AF_LEN 16
+
+#define V31_STATS_AE_OFF 0x00000534
+#define V31_STATS_AE_LEN 8
+
+#define V31_STATS_AWB_OFF 0x0000054c
+#define V31_STATS_AWB_LEN 32
+
+#define V31_STATS_IHIST_OFF 0x0000057c
+#define V31_STATS_IHIST_LEN 8
+
+#define V31_STATS_RS_OFF 0x0000056c
+#define V31_STATS_RS_LEN 8
+
+#define V31_STATS_CS_OFF 0x00000574
+#define V31_STATS_CS_LEN 8
+
+#define V31_XBAR_CFG_OFF 0x00000040
+#define V31_XBAR_CFG_LEN 8
+
+#define V31_EZTUNE_CFG_OFF 0x00000010
+#define V31_EZTUNE_CFG_LEN 4
+
+#define V31_ASF_OFF 0x000004A0
+#define V31_ASF_LEN 48
+#define V31_ASF_UPDATE_LEN 36
+
+#define V31_CAPTURE_LEN 4
+
+struct vfe_cmd_hw_version {
+	uint32_t minorVersion;
+	uint32_t majorVersion;
+	uint32_t coreVersion;
+};
+
+enum VFE_AXI_OUTPUT_MODE {
+	VFE_AXI_OUTPUT_MODE_Output1,
+	VFE_AXI_OUTPUT_MODE_Output2,
+	VFE_AXI_OUTPUT_MODE_Output1AndOutput2,
+	VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2,
+	VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1,
+	VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2,
+	VFE_AXI_LAST_OUTPUT_MODE_ENUM
+};
+
+enum VFE_RAW_WR_PATH_SEL {
+	VFE_RAW_OUTPUT_DISABLED,
+	VFE_RAW_OUTPUT_ENC_CBCR_PATH,
+	VFE_RAW_OUTPUT_VIEW_CBCR_PATH,
+	VFE_RAW_OUTPUT_PATH_INVALID
+};
+
+
+#define VFE_AXI_OUTPUT_BURST_LENGTH     4
+#define VFE_MAX_NUM_FRAGMENTS_PER_FRAME 4
+#define VFE_AXI_OUTPUT_CFG_FRAME_COUNT  3
+
+struct vfe_cmds_per_write_master {
+	uint16_t imageWidth;
+	uint16_t imageHeight;
+	uint16_t outRowCount;
+	uint16_t outRowIncrement;
+	uint32_t outFragments[VFE_AXI_OUTPUT_CFG_FRAME_COUNT]
+		[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
+};
+
+struct vfe_cmds_axi_per_output_path {
+	uint8_t fragmentCount;
+	struct vfe_cmds_per_write_master firstWM;
+	struct vfe_cmds_per_write_master secondWM;
+};
+
+enum VFE_AXI_BURST_LENGTH {
+	VFE_AXI_BURST_LENGTH_IS_2  = 2,
+	VFE_AXI_BURST_LENGTH_IS_4  = 4,
+	VFE_AXI_BURST_LENGTH_IS_8  = 8,
+	VFE_AXI_BURST_LENGTH_IS_16 = 16
+};
+
+
+struct vfe_cmd_fov_crop_config {
+	uint8_t enable;
+	uint16_t firstPixel;
+	uint16_t lastPixel;
+	uint16_t firstLine;
+	uint16_t lastLine;
+};
+
+struct vfe_cmds_main_scaler_stripe_init {
+	uint16_t MNCounterInit;
+	uint16_t phaseInit;
+};
+
+struct vfe_cmds_scaler_one_dimension {
+	uint8_t  enable;
+	uint16_t inputSize;
+	uint16_t outputSize;
+	uint32_t phaseMultiplicationFactor;
+	uint8_t  interpolationResolution;
+};
+
+struct vfe_cmd_main_scaler_config {
+	uint8_t enable;
+	struct vfe_cmds_scaler_one_dimension    hconfig;
+	struct vfe_cmds_scaler_one_dimension    vconfig;
+	struct vfe_cmds_main_scaler_stripe_init MNInitH;
+	struct vfe_cmds_main_scaler_stripe_init MNInitV;
+};
+
+struct vfe_cmd_scaler2_config {
+	uint8_t enable;
+	struct vfe_cmds_scaler_one_dimension hconfig;
+	struct vfe_cmds_scaler_one_dimension vconfig;
+};
+
+
+struct vfe_cmd_frame_skip_update {
+	uint32_t output1Pattern;
+	uint32_t output2Pattern;
+};
+
+struct vfe_cmd_output_clamp_config {
+	uint8_t minCh0;
+	uint8_t minCh1;
+	uint8_t minCh2;
+	uint8_t maxCh0;
+	uint8_t maxCh1;
+	uint8_t maxCh2;
+};
+
+struct vfe_cmd_chroma_subsample_config {
+	uint8_t enable;
+	uint8_t cropEnable;
+	uint8_t vsubSampleEnable;
+	uint8_t hsubSampleEnable;
+	uint8_t vCosited;
+	uint8_t hCosited;
+	uint8_t vCositedPhase;
+	uint8_t hCositedPhase;
+	uint16_t cropWidthFirstPixel;
+	uint16_t cropWidthLastPixel;
+	uint16_t cropHeightFirstLine;
+	uint16_t cropHeightLastLine;
+};
+
+enum VFE_START_INPUT_SOURCE {
+	VFE_START_INPUT_SOURCE_CAMIF,
+	VFE_START_INPUT_SOURCE_TESTGEN,
+	VFE_START_INPUT_SOURCE_AXI,
+	VFE_START_INPUT_SOURCE_INVALID
+};
+
+enum VFE_START_PIXEL_PATTERN {
+	VFE_BAYER_RGRGRG,
+	VFE_BAYER_GRGRGR,
+	VFE_BAYER_BGBGBG,
+	VFE_BAYER_GBGBGB,
+	VFE_YUV_YCbYCr,
+	VFE_YUV_YCrYCb,
+	VFE_YUV_CbYCrY,
+	VFE_YUV_CrYCbY
+};
+
+enum VFE_BUS_RD_INPUT_PIXEL_PATTERN {
+	VFE_BAYER_RAW,
+	VFE_YUV_INTERLEAVED,
+	VFE_YUV_PSEUDO_PLANAR_Y,
+	VFE_YUV_PSEUDO_PLANAR_CBCR
+};
+
+enum VFE_YUV_INPUT_COSITING_MODE {
+	VFE_YUV_COSITED,
+	VFE_YUV_INTERPOLATED
+};
+
+
+/* 13*1  */
+#define VFE31_ROLL_OFF_INIT_TABLE_SIZE  13
+/* 13*16 */
+#define VFE31_ROLL_OFF_DELTA_TABLE_SIZE 208
+
+#define VFE31_GAMMA_NUM_ENTRIES  64
+
+#define VFE31_LA_TABLE_LENGTH    64
+
+#define VFE31_HIST_TABLE_LENGTH  256
+
+struct vfe_cmds_demosaic_abf {
+	uint8_t   enable;
+	uint8_t   forceOn;
+	uint8_t   shift;
+	uint16_t  lpThreshold;
+	uint16_t  max;
+	uint16_t  min;
+	uint8_t   ratio;
+};
+
+struct vfe_cmds_demosaic_bpc {
+	uint8_t   enable;
+	uint16_t  fmaxThreshold;
+	uint16_t  fminThreshold;
+	uint16_t  redDiffThreshold;
+	uint16_t  blueDiffThreshold;
+	uint16_t  greenDiffThreshold;
+};
+
+struct vfe_cmd_demosaic_config {
+	uint8_t   enable;
+	uint8_t   slopeShift;
+	struct vfe_cmds_demosaic_abf abfConfig;
+	struct vfe_cmds_demosaic_bpc bpcConfig;
+};
+
+struct vfe_cmd_demosaic_bpc_update {
+	struct vfe_cmds_demosaic_bpc bpcUpdate;
+};
+
+struct vfe_cmd_demosaic_abf_update {
+	struct vfe_cmds_demosaic_abf abfUpdate;
+};
+
+struct vfe_cmd_white_balance_config {
+	uint8_t  enable;
+	uint16_t ch2Gain;
+	uint16_t ch1Gain;
+	uint16_t ch0Gain;
+};
+
+enum VFE_COLOR_CORRECTION_COEF_QFACTOR {
+	COEF_IS_Q7_SIGNED,
+	COEF_IS_Q8_SIGNED,
+	COEF_IS_Q9_SIGNED,
+	COEF_IS_Q10_SIGNED
+};
+
+struct vfe_cmd_color_correction_config {
+	uint8_t     enable;
+	enum VFE_COLOR_CORRECTION_COEF_QFACTOR coefQFactor;
+	int16_t  C0;
+	int16_t  C1;
+	int16_t  C2;
+	int16_t  C3;
+	int16_t  C4;
+	int16_t  C5;
+	int16_t  C6;
+	int16_t  C7;
+	int16_t  C8;
+	int16_t  K0;
+	int16_t  K1;
+	int16_t  K2;
+};
+
+#define VFE_LA_TABLE_LENGTH 64
+
+struct vfe_cmd_la_config {
+	uint8_t enable;
+	int16_t table[VFE_LA_TABLE_LENGTH];
+};
+
+#define VFE_GAMMA_TABLE_LENGTH 256
+enum VFE_RGB_GAMMA_TABLE_SELECT {
+	RGB_GAMMA_CH0_SELECTED,
+	RGB_GAMMA_CH1_SELECTED,
+	RGB_GAMMA_CH2_SELECTED,
+	RGB_GAMMA_CH0_CH1_SELECTED,
+	RGB_GAMMA_CH0_CH2_SELECTED,
+	RGB_GAMMA_CH1_CH2_SELECTED,
+	RGB_GAMMA_CH0_CH1_CH2_SELECTED
+};
+
+struct vfe_cmd_rgb_gamma_config {
+	uint8_t enable;
+	enum VFE_RGB_GAMMA_TABLE_SELECT channelSelect;
+	int16_t table[VFE_GAMMA_TABLE_LENGTH];
+};
+
+struct vfe_cmd_chroma_enhan_config {
+	uint8_t  enable;
+	int16_t am;
+	int16_t ap;
+	int16_t bm;
+	int16_t bp;
+	int16_t cm;
+	int16_t cp;
+	int16_t dm;
+	int16_t dp;
+	int16_t kcr;
+	int16_t kcb;
+	int16_t RGBtoYConversionV0;
+	int16_t RGBtoYConversionV1;
+	int16_t RGBtoYConversionV2;
+	uint8_t RGBtoYConversionOffset;
+};
+
+struct vfe_cmd_chroma_suppression_config {
+	uint8_t enable;
+	uint8_t m1;
+	uint8_t m3;
+	uint8_t n1;
+	uint8_t n3;
+	uint8_t nn1;
+	uint8_t mm1;
+};
+
+struct vfe_cmd_asf_config {
+	uint8_t enable;
+	uint8_t smoothFilterEnabled;
+	uint8_t sharpMode;
+	uint8_t smoothCoefCenter;
+	uint8_t smoothCoefSurr;
+	uint8_t normalizeFactor;
+	uint8_t sharpK1;
+	uint8_t sharpK2;
+	uint8_t sharpThreshE1;
+	int8_t sharpThreshE2;
+	int8_t sharpThreshE3;
+	int8_t sharpThreshE4;
+	int8_t sharpThreshE5;
+	int8_t filter1Coefficients[9];
+	int8_t filter2Coefficients[9];
+	uint8_t  cropEnable;
+	uint16_t cropFirstPixel;
+	uint16_t cropLastPixel;
+	uint16_t cropFirstLine;
+	uint16_t cropLastLine;
+};
+
+struct vfe_cmd_asf_update {
+	uint8_t enable;
+	uint8_t smoothFilterEnabled;
+	uint8_t sharpMode;
+	uint8_t smoothCoefCenter;
+	uint8_t smoothCoefSurr;
+	uint8_t normalizeFactor;
+	uint8_t sharpK1;
+	uint8_t sharpK2;
+	uint8_t sharpThreshE1;
+	int8_t  sharpThreshE2;
+	int8_t  sharpThreshE3;
+	int8_t  sharpThreshE4;
+	int8_t  sharpThreshE5;
+	int8_t  filter1Coefficients[9];
+	int8_t  filter2Coefficients[9];
+	uint8_t cropEnable;
+};
+
+enum VFE_TEST_GEN_SYNC_EDGE {
+	VFE_TEST_GEN_SYNC_EDGE_ActiveHigh,
+	VFE_TEST_GEN_SYNC_EDGE_ActiveLow
+};
+
+
+struct vfe_cmd_bus_pm_start {
+	uint8_t output2YWrPmEnable;
+	uint8_t output2CbcrWrPmEnable;
+	uint8_t output1YWrPmEnable;
+	uint8_t output1CbcrWrPmEnable;
+};
+
+struct  vfe_frame_skip_counts {
+	uint32_t  totalFrameCount;
+	uint32_t  output1Count;
+	uint32_t  output2Count;
+};
+
+enum VFE_AXI_RD_UNPACK_HBI_SEL {
+	VFE_AXI_RD_HBI_32_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_64_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_128_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_256_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_512_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_1024_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_2048_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_4096_CLOCK_CYCLES
+};
+
+enum VFE31_MESSAGE_ID {
+	MSG_ID_RESET_ACK, /* 0 */
+	MSG_ID_START_ACK,
+	MSG_ID_STOP_ACK,
+	MSG_ID_UPDATE_ACK,
+	MSG_ID_OUTPUT_P,
+	MSG_ID_OUTPUT_T,
+	MSG_ID_OUTPUT_S,
+	MSG_ID_OUTPUT_V,
+	MSG_ID_SNAPSHOT_DONE,
+	MSG_ID_COMMON,
+	MSG_ID_EPOCH1, /* 10 */
+	MSG_ID_EPOCH2,
+	MSG_ID_SYNC_TIMER0_DONE,
+	MSG_ID_SYNC_TIMER1_DONE,
+	MSG_ID_SYNC_TIMER2_DONE,
+	MSG_ID_ASYNC_TIMER0_DONE,
+	MSG_ID_ASYNC_TIMER1_DONE,
+	MSG_ID_ASYNC_TIMER2_DONE,
+	MSG_ID_ASYNC_TIMER3_DONE,
+	MSG_ID_AE_OVERFLOW,
+	MSG_ID_AF_OVERFLOW, /* 20 */
+	MSG_ID_AWB_OVERFLOW,
+	MSG_ID_RS_OVERFLOW,
+	MSG_ID_CS_OVERFLOW,
+	MSG_ID_IHIST_OVERFLOW,
+	MSG_ID_SKIN_OVERFLOW,
+	MSG_ID_AXI_ERROR,
+	MSG_ID_CAMIF_OVERFLOW,
+	MSG_ID_VIOLATION,
+	MSG_ID_CAMIF_ERROR,
+	MSG_ID_BUS_OVERFLOW, /* 30 */
+	MSG_ID_SOF_ACK,
+	MSG_ID_STOP_REC_ACK,
+};
+
+struct stats_buffer {
+	uint8_t awb_ymin;
+	uint32_t aec;
+	uint32_t awb;
+	uint32_t af;
+	uint32_t ihist;
+	uint32_t rs;
+	uint32_t cs;
+	uint32_t skin;
+};
+
+struct vfe_msg_stats {
+	struct stats_buffer buff;
+	uint32_t    frameCounter;
+	uint32_t    status_bits;
+};
+
+
+struct vfe_frame_bpc_info {
+	uint32_t greenDefectPixelCount;
+	uint32_t redBlueDefectPixelCount;
+};
+
+struct vfe_frame_asf_info {
+	uint32_t  asfMaxEdge;
+	uint32_t  asfHbiCount;
+};
+
+struct vfe_msg_camif_status {
+	uint8_t  camifState;
+	uint32_t pixelCount;
+	uint32_t lineCount;
+};
+
+
+struct vfe31_irq_status {
+	uint32_t vfeIrqStatus0;
+	uint32_t vfeIrqStatus1;
+	uint32_t camifStatus;
+	uint32_t demosaicStatus;
+	uint32_t asfMaxEdge;
+	uint32_t vfePingPongStatus;
+};
+
+struct vfe_msg_output {
+	uint8_t   output_id;
+	uint32_t  p0_addr;
+	uint32_t  p1_addr;
+	uint32_t  p2_addr;
+	struct vfe_frame_bpc_info bpcInfo;
+	struct vfe_frame_asf_info asfInfo;
+	uint32_t  frameCounter;
+};
+
+struct vfe_message {
+	enum VFE31_MESSAGE_ID _d;
+	union {
+		struct vfe_msg_output              msgOut;
+		struct vfe_msg_stats               msgStats;
+		struct vfe_msg_camif_status        msgCamifError;
+   } _u;
+};
+
+/* New one for 7x30 */
+struct msm_vfe31_cmd {
+	int32_t  id;
+	uint16_t length;
+	void     *value;
+};
+
+#define V31_PREVIEW_AXI_FLAG  0x00000001
+#define V31_SNAPSHOT_AXI_FLAG (0x00000001<<1)
+
+struct vfe31_cmd_type {
+	uint16_t id;
+	uint32_t length;
+	uint32_t offset;
+	uint32_t flag;
+};
+
+struct vfe31_free_buf {
+	struct list_head node;
+	uint32_t paddr;
+	uint32_t planar0_off;
+	uint32_t planar1_off;
+	uint32_t planar2_off;
+	uint32_t cbcr_off;
+};
+
+struct vfe31_output_ch {
+	struct list_head free_buf_head;
+	spinlock_t free_buf_lock;
+	uint16_t output_fmt;
+	int8_t ch0;
+	int8_t ch1;
+	int8_t ch2;
+	uint32_t  frame_drop_cnt;
+};
+
+/* no error irq in mask 0 */
+#define VFE31_IMASK_ERROR_ONLY_0  0x0
+/* when normal case, don't want to block error status. */
+/* bit 0-21 are error irq bits */
+#define VFE31_IMASK_ERROR_ONLY_1               0x003FFFFF
+#define VFE31_IMASK_CAMIF_ERROR               (0x00000001<<0)
+#define VFE31_IMASK_STATS_CS_OVWR             (0x00000001<<1)
+#define VFE31_IMASK_STATS_IHIST_OVWR          (0x00000001<<2)
+#define VFE31_IMASK_REALIGN_BUF_Y_OVFL        (0x00000001<<3)
+#define VFE31_IMASK_REALIGN_BUF_CB_OVFL       (0x00000001<<4)
+#define VFE31_IMASK_REALIGN_BUF_CR_OVFL       (0x00000001<<5)
+#define VFE31_IMASK_VIOLATION                 (0x00000001<<6)
+#define VFE31_IMASK_IMG_MAST_0_BUS_OVFL       (0x00000001<<7)
+#define VFE31_IMASK_IMG_MAST_1_BUS_OVFL       (0x00000001<<8)
+#define VFE31_IMASK_IMG_MAST_2_BUS_OVFL       (0x00000001<<9)
+#define VFE31_IMASK_IMG_MAST_3_BUS_OVFL       (0x00000001<<10)
+#define VFE31_IMASK_IMG_MAST_4_BUS_OVFL       (0x00000001<<11)
+#define VFE31_IMASK_IMG_MAST_5_BUS_OVFL       (0x00000001<<12)
+#define VFE31_IMASK_IMG_MAST_6_BUS_OVFL       (0x00000001<<13)
+#define VFE31_IMASK_STATS_AE_BUS_OVFL         (0x00000001<<14)
+#define VFE31_IMASK_STATS_AF_BUS_OVFL         (0x00000001<<15)
+#define VFE31_IMASK_STATS_AWB_BUS_OVFL        (0x00000001<<16)
+#define VFE31_IMASK_STATS_RS_BUS_OVFL         (0x00000001<<17)
+#define VFE31_IMASK_STATS_CS_BUS_OVFL         (0x00000001<<18)
+#define VFE31_IMASK_STATS_IHIST_BUS_OVFL      (0x00000001<<19)
+#define VFE31_IMASK_STATS_SKIN_BUS_OVFL       (0x00000001<<20)
+#define VFE31_IMASK_AXI_ERROR                 (0x00000001<<21)
+
+#define VFE_COM_STATUS 0x000FE000
+
+struct vfe31_output_path {
+	uint16_t output_mode;     /* bitmask  */
+
+	struct vfe31_output_ch out0; /* preview and thumbnail */
+	struct vfe31_output_ch out1; /* snapshot */
+	struct vfe31_output_ch out2; /* video    */
+};
+
+struct vfe31_frame_extra {
+	uint32_t greenDefectPixelCount;
+	uint32_t redBlueDefectPixelCount;
+
+	uint32_t  asfMaxEdge;
+	uint32_t  asfHbiCount;
+
+	uint32_t yWrPmStats0;
+	uint32_t yWrPmStats1;
+	uint32_t cbcrWrPmStats0;
+	uint32_t cbcrWrPmStats1;
+
+	uint32_t  frameCounter;
+};
+
+#define VFE_DISABLE_ALL_IRQS             0
+#define VFE_CLEAR_ALL_IRQS               0xffffffff
+
+#define VFE_GLOBAL_RESET                 0x00000004
+#define VFE_CGC_OVERRIDE                 0x0000000C
+#define VFE_MODULE_CFG                   0x00000010
+#define VFE_CFG_OFF                      0x00000014
+#define VFE_IRQ_CMD                      0x00000018
+#define VFE_IRQ_MASK_0                   0x0000001C
+#define VFE_IRQ_MASK_1                   0x00000020
+#define VFE_IRQ_CLEAR_0                  0x00000024
+#define VFE_IRQ_CLEAR_1                  0x00000028
+#define VFE_IRQ_STATUS_0                 0x0000002C
+#define VFE_IRQ_STATUS_1                 0x00000030
+#define VFE_IRQ_COMP_MASK                0x00000034
+#define VFE_BUS_CMD                      0x00000038
+#define VFE_BUS_PING_PONG_STATUS         0x00000180
+#define VFE_BUS_OPERATION_STATUS         0x00000184
+
+#define VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_0        0x00000190
+#define VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_1        0x00000194
+
+#define VFE_AXI_CMD                      0x000001D8
+#define VFE_AXI_STATUS                   0x000001DC
+#define VFE_BUS_STATS_PING_PONG_BASE     0x000000F4
+
+#define VFE_BUS_STATS_AEC_WR_PING_ADDR   0x000000F4
+#define VFE_BUS_STATS_AEC_WR_PONG_ADDR   0x000000F8
+#define VFE_BUS_STATS_AEC_UB_CFG         0x000000FC
+#define VFE_BUS_STATS_AF_WR_PING_ADDR    0x00000100
+#define VFE_BUS_STATS_AF_WR_PONG_ADDR    0x00000104
+#define VFE_BUS_STATS_AF_UB_CFG          0x00000108
+#define VFE_BUS_STATS_AWB_WR_PING_ADDR   0x0000010C
+#define VFE_BUS_STATS_AWB_WR_PONG_ADDR   0x00000110
+#define VFE_BUS_STATS_AWB_UB_CFG         0x00000114
+#define VFE_BUS_STATS_RS_WR_PING_ADDR    0x00000118
+#define VFE_BUS_STATS_RS_WR_PONG_ADDR    0x0000011C
+#define VFE_BUS_STATS_RS_UB_CFG          0x00000120
+
+#define VFE_BUS_STATS_CS_WR_PING_ADDR    0x00000124
+#define VFE_BUS_STATS_CS_WR_PONG_ADDR    0x00000128
+#define VFE_BUS_STATS_CS_UB_CFG          0x0000012C
+#define VFE_BUS_STATS_HIST_WR_PING_ADDR  0x00000130
+#define VFE_BUS_STATS_HIST_WR_PONG_ADDR  0x00000134
+#define VFE_BUS_STATS_HIST_UB_CFG        0x00000138
+#define VFE_BUS_STATS_SKIN_WR_PING_ADDR  0x0000013C
+#define VFE_BUS_STATS_SKIN_WR_PONG_ADDR  0x00000140
+#define VFE_BUS_STATS_SKIN_UB_CFG        0x00000144
+#define VFE_BUS_PM_CMD                   0x00000188
+#define VFE_BUS_PM_CFG                   0x0000018C
+#define VFE_CAMIF_COMMAND                0x000001E0
+#define VFE_CAMIF_STATUS                 0x00000204
+#define VFE_REG_UPDATE_CMD               0x00000260
+#define VFE_DEMUX_GAIN_0                 0x00000288
+#define VFE_DEMUX_GAIN_1                 0x0000028C
+#define VFE_CHROMA_UP                    0x0000035C
+#define VFE_FRAMEDROP_ENC_Y_CFG          0x00000504
+#define VFE_FRAMEDROP_ENC_CBCR_CFG       0x00000508
+#define VFE_FRAMEDROP_ENC_Y_PATTERN      0x0000050C
+#define VFE_FRAMEDROP_ENC_CBCR_PATTERN   0x00000510
+#define VFE_FRAMEDROP_VIEW_Y             0x00000514
+#define VFE_FRAMEDROP_VIEW_CBCR          0x00000518
+#define VFE_FRAMEDROP_VIEW_Y_PATTERN     0x0000051C
+#define VFE_FRAMEDROP_VIEW_CBCR_PATTERN  0x00000520
+#define VFE_CLAMP_MAX                    0x00000524
+#define VFE_CLAMP_MIN                    0x00000528
+#define VFE_REALIGN_BUF                  0x0000052C
+#define VFE_STATS_CFG                    0x00000530
+#define VFE_STATS_AWB_SGW_CFG            0x00000554
+#define VFE_DMI_CFG                      0x00000598
+#define VFE_DMI_ADDR                     0x0000059C
+#define VFE_DMI_DATA_LO                  0x000005A4
+#define VFE_AXI_CFG                      0x00000600
+
+struct vfe_stats_control {
+	uint8_t  ackPending;
+	uint32_t nextFrameAddrBuf;
+	uint32_t droppedStatsFrameCount;
+	uint32_t bufToRender;
+};
+
+struct vfe31_ctrl_type {
+	uint16_t operation_mode;     /* streaming or snapshot */
+	struct vfe31_output_path outpath;
+
+	uint32_t vfeImaskCompositePacked;
+
+	spinlock_t  update_ack_lock;
+	spinlock_t  io_lock;
+
+	int8_t aec_ack_pending;
+	int8_t awb_ack_pending;
+	int8_t af_ack_pending;
+	int8_t ihist_ack_pending;
+	int8_t rs_ack_pending;
+	int8_t cs_ack_pending;
+
+	struct msm_vfe_callback *resp;
+	uint32_t extlen;
+	void *extdata;
+
+	int8_t start_ack_pending;
+	atomic_t stop_ack_pending;
+	int8_t reset_ack_pending;
+	int8_t update_ack_pending;
+	enum vfe_recording_state recording_state;
+	int8_t output0_available;
+	int8_t output1_available;
+	int8_t update_gamma;
+	int8_t update_luma;
+	spinlock_t  tasklet_lock;
+	struct list_head tasklet_q;
+	int vfeirq;
+	void __iomem *vfebase;
+	void *syncdata;
+
+	struct resource	*vfemem;
+	struct resource *vfeio;
+
+	uint32_t stats_comp;
+	uint32_t hfr_mode;
+	atomic_t vstate;
+	uint32_t vfe_capture_count;
+	uint32_t sync_timer_repeat_count;
+	uint32_t sync_timer_state;
+	uint32_t sync_timer_number;
+
+	uint32_t vfeFrameId;
+	uint32_t output1Pattern;
+	uint32_t output1Period;
+	uint32_t output2Pattern;
+	uint32_t output2Period;
+	uint32_t vfeFrameSkipCount;
+	uint32_t vfeFrameSkipPeriod;
+	uint32_t status_bits;
+	struct vfe_stats_control afStatsControl;
+	struct vfe_stats_control awbStatsControl;
+	struct vfe_stats_control aecStatsControl;
+	struct vfe_stats_control ihistStatsControl;
+	struct vfe_stats_control rsStatsControl;
+	struct vfe_stats_control csStatsControl;
+	struct msm_camera_sensor_info *s_info;
+	struct vfe_message vMsgHold_Snap;
+	struct vfe_message vMsgHold_Thumb;
+	int8_t xbar_update_pending;
+	uint32_t xbar_cfg[2];
+	spinlock_t xbar_lock;
+	uint32_t while_stopping_mask;
+};
+
+#define statsAeNum      0
+#define statsAfNum      1
+#define statsAwbNum     2
+#define statsRsNum      3
+#define statsCsNum      4
+#define statsIhistNum   5
+#define statsSkinNum    6
+
+struct vfe_cmd_stats_ack{
+  uint32_t  nextStatsBuf;
+};
+
+#define VFE_STATS_BUFFER_COUNT            3
+
+struct vfe_cmd_stats_buf{
+   uint32_t statsBuf[VFE_STATS_BUFFER_COUNT];
+};
+#endif /* __MSM_VFE31_H__ */
diff --git a/drivers/media/platform/msm/camera_v1/vfe/msm_vfe31_v4l2.c b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe31_v4l2.c
new file mode 100644
index 0000000..10ddd4b
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe31_v4l2.c
@@ -0,0 +1,4241 @@
+/* Copyright (c) 2012 The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/uaccess.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/atomic.h>
+#include <linux/regulator/consumer.h>
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <mach/clk.h>
+#include <mach/irqs.h>
+#include <mach/camera.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+#include <media/msm_isp.h>
+
+#include "msm.h"
+#include "msm_vfe31_v4l2.h"
+
+atomic_t irq_cnt;
+
+#define BUFF_SIZE_128 128
+
+#define VFE31_AXI_OFFSET 0x0050
+#define vfe31_get_ch_ping_addr(chn) \
+	(msm_camera_io_r(vfe31_ctrl->vfebase + 0x0050 + 0x18 * (chn)))
+#define vfe31_get_ch_pong_addr(chn) \
+	(msm_camera_io_r(vfe31_ctrl->vfebase + 0x0050 + 0x18 * (chn) + 4))
+#define vfe31_get_ch_addr(ping_pong, chn) \
+	(((ping_pong) & (1 << (chn))) == 0 ? \
+	vfe31_get_ch_pong_addr(chn) : vfe31_get_ch_ping_addr(chn))
+
+#define vfe31_put_ch_ping_addr(chn, addr) \
+	(msm_camera_io_w((addr), vfe31_ctrl->vfebase + 0x0050 + 0x18 * (chn)))
+#define vfe31_put_ch_pong_addr(chn, addr) \
+	(msm_camera_io_w((addr), \
+	vfe31_ctrl->vfebase + 0x0050 + 0x18 * (chn) + 4))
+#define vfe31_put_ch_addr(ping_pong, chn, addr) \
+	(((ping_pong) & (1 << (chn))) == 0 ?   \
+	vfe31_put_ch_pong_addr((chn), (addr)) : \
+	vfe31_put_ch_ping_addr((chn), (addr)))
+
+#define VFE_CLK_RATE	153600000
+#define CAMIF_CFG_RMSK             0x1fffff
+
+static struct vfe31_ctrl_type *vfe31_ctrl;
+static uint32_t vfe_clk_rate;
+
+struct vfe31_isr_queue_cmd {
+	struct list_head	list;
+	uint32_t		vfeInterruptStatus0;
+	uint32_t		vfeInterruptStatus1;
+};
+
+static struct vfe31_cmd_type vfe31_cmd[] = {
+/* 0*/	{VFE_CMD_DUMMY_0},
+		{VFE_CMD_SET_CLK},
+		{VFE_CMD_RESET},
+		{VFE_CMD_START},
+		{VFE_CMD_TEST_GEN_START},
+/* 5*/	{VFE_CMD_OPERATION_CFG, V31_OPERATION_CFG_LEN},
+		{VFE_CMD_AXI_OUT_CFG, V31_AXI_OUT_LEN, V31_AXI_OUT_OFF, 0xFF},
+		{VFE_CMD_CAMIF_CFG, V31_CAMIF_LEN, V31_CAMIF_OFF, 0xFF},
+		{VFE_CMD_AXI_INPUT_CFG},
+		{VFE_CMD_BLACK_LEVEL_CFG, V31_BLACK_LEVEL_LEN,
+		V31_BLACK_LEVEL_OFF,
+		0xFF},
+/*10*/  {VFE_CMD_MESH_ROLL_OFF_CFG, V31_MESH_ROLL_OFF_CFG_LEN,
+		V31_MESH_ROLL_OFF_CFG_OFF, 0xFF},
+		{VFE_CMD_DEMUX_CFG, V31_DEMUX_LEN, V31_DEMUX_OFF, 0xFF},
+		{VFE_CMD_FOV_CFG, V31_FOV_LEN, V31_FOV_OFF, 0xFF},
+		{VFE_CMD_MAIN_SCALER_CFG, V31_MAIN_SCALER_LEN,
+		V31_MAIN_SCALER_OFF, 0xFF},
+		{VFE_CMD_WB_CFG, V31_WB_LEN, V31_WB_OFF, 0xFF},
+/*15*/	{VFE_CMD_COLOR_COR_CFG, V31_COLOR_COR_LEN, V31_COLOR_COR_OFF, 0xFF},
+		{VFE_CMD_RGB_G_CFG, V31_RGB_G_LEN, V31_RGB_G_OFF, 0xFF},
+		{VFE_CMD_LA_CFG, V31_LA_LEN, V31_LA_OFF, 0xFF },
+		{VFE_CMD_CHROMA_EN_CFG, V31_CHROMA_EN_LEN, V31_CHROMA_EN_OFF,
+		0xFF},
+		{VFE_CMD_CHROMA_SUP_CFG, V31_CHROMA_SUP_LEN, V31_CHROMA_SUP_OFF,
+		0xFF},
+/*20*/	{VFE_CMD_MCE_CFG, V31_MCE_LEN, V31_MCE_OFF, 0xFF},
+		{VFE_CMD_SK_ENHAN_CFG, V31_SCE_LEN, V31_SCE_OFF, 0xFF},
+		{VFE_CMD_ASF_CFG, V31_ASF_LEN, V31_ASF_OFF, 0xFF},
+		{VFE_CMD_S2Y_CFG, V31_S2Y_LEN, V31_S2Y_OFF, 0xFF},
+		{VFE_CMD_S2CbCr_CFG, V31_S2CbCr_LEN, V31_S2CbCr_OFF, 0xFF},
+/*25*/	{VFE_CMD_CHROMA_SUBS_CFG, V31_CHROMA_SUBS_LEN, V31_CHROMA_SUBS_OFF,
+		0xFF},
+		{VFE_CMD_OUT_CLAMP_CFG, V31_OUT_CLAMP_LEN, V31_OUT_CLAMP_OFF,
+		0xFF},
+		{VFE_CMD_FRAME_SKIP_CFG, V31_FRAME_SKIP_LEN, V31_FRAME_SKIP_OFF,
+		0xFF},
+		{VFE_CMD_DUMMY_1},
+		{VFE_CMD_DUMMY_2},
+/*30*/	{VFE_CMD_DUMMY_3},
+		{VFE_CMD_UPDATE},
+		{VFE_CMD_BL_LVL_UPDATE, V31_BLACK_LEVEL_LEN,
+		V31_BLACK_LEVEL_OFF, 0xFF},
+		{VFE_CMD_DEMUX_UPDATE, V31_DEMUX_LEN, V31_DEMUX_OFF, 0xFF},
+		{VFE_CMD_FOV_UPDATE, V31_FOV_LEN, V31_FOV_OFF, 0xFF},
+/*35*/	{VFE_CMD_MAIN_SCALER_UPDATE, V31_MAIN_SCALER_LEN, V31_MAIN_SCALER_OFF,
+		0xFF},
+		{VFE_CMD_WB_UPDATE, V31_WB_LEN, V31_WB_OFF, 0xFF},
+		{VFE_CMD_COLOR_COR_UPDATE, V31_COLOR_COR_LEN, V31_COLOR_COR_OFF,
+		0xFF},
+		{VFE_CMD_RGB_G_UPDATE, V31_RGB_G_LEN, V31_CHROMA_EN_OFF, 0xFF},
+		{VFE_CMD_LA_UPDATE, V31_LA_LEN, V31_LA_OFF, 0xFF },
+/*40*/	{VFE_CMD_CHROMA_EN_UPDATE, V31_CHROMA_EN_LEN, V31_CHROMA_EN_OFF,
+		0xFF},
+		{VFE_CMD_CHROMA_SUP_UPDATE, V31_CHROMA_SUP_LEN,
+		V31_CHROMA_SUP_OFF, 0xFF},
+		{VFE_CMD_MCE_UPDATE, V31_MCE_LEN, V31_MCE_OFF, 0xFF},
+		{VFE_CMD_SK_ENHAN_UPDATE, V31_SCE_LEN, V31_SCE_OFF, 0xFF},
+		{VFE_CMD_S2CbCr_UPDATE, V31_S2CbCr_LEN, V31_S2CbCr_OFF, 0xFF},
+/*45*/	{VFE_CMD_S2Y_UPDATE, V31_S2Y_LEN, V31_S2Y_OFF, 0xFF},
+		{VFE_CMD_ASF_UPDATE, V31_ASF_UPDATE_LEN, V31_ASF_OFF, 0xFF},
+		{VFE_CMD_FRAME_SKIP_UPDATE},
+		{VFE_CMD_CAMIF_FRAME_UPDATE},
+		{VFE_CMD_STATS_AF_UPDATE, V31_STATS_AF_LEN, V31_STATS_AF_OFF},
+/*50*/	{VFE_CMD_STATS_AE_UPDATE, V31_STATS_AE_LEN, V31_STATS_AE_OFF},
+		{VFE_CMD_STATS_AWB_UPDATE, V31_STATS_AWB_LEN,
+		V31_STATS_AWB_OFF},
+		{VFE_CMD_STATS_RS_UPDATE, V31_STATS_RS_LEN, V31_STATS_RS_OFF},
+		{VFE_CMD_STATS_CS_UPDATE, V31_STATS_CS_LEN, V31_STATS_CS_OFF},
+		{VFE_CMD_STATS_SKIN_UPDATE},
+/*55*/	{VFE_CMD_STATS_IHIST_UPDATE, V31_STATS_IHIST_LEN, V31_STATS_IHIST_OFF},
+		{VFE_CMD_DUMMY_4},
+		{VFE_CMD_EPOCH1_ACK},
+		{VFE_CMD_EPOCH2_ACK},
+		{VFE_CMD_START_RECORDING},
+/*60*/	{VFE_CMD_STOP_RECORDING},
+		{VFE_CMD_DUMMY_5},
+		{VFE_CMD_DUMMY_6},
+		{VFE_CMD_CAPTURE, V31_CAPTURE_LEN, 0xFF},
+		{VFE_CMD_DUMMY_7},
+/*65*/	{VFE_CMD_STOP},
+		{VFE_CMD_GET_HW_VERSION, V31_GET_HW_VERSION_LEN,
+		V31_GET_HW_VERSION_OFF},
+		{VFE_CMD_GET_FRAME_SKIP_COUNTS},
+		{VFE_CMD_OUTPUT1_BUFFER_ENQ},
+		{VFE_CMD_OUTPUT2_BUFFER_ENQ},
+/*70*/	{VFE_CMD_OUTPUT3_BUFFER_ENQ},
+		{VFE_CMD_JPEG_OUT_BUF_ENQ},
+		{VFE_CMD_RAW_OUT_BUF_ENQ},
+		{VFE_CMD_RAW_IN_BUF_ENQ},
+		{VFE_CMD_STATS_AF_ENQ},
+/*75*/	{VFE_CMD_STATS_AE_ENQ},
+		{VFE_CMD_STATS_AWB_ENQ},
+		{VFE_CMD_STATS_RS_ENQ},
+		{VFE_CMD_STATS_CS_ENQ},
+		{VFE_CMD_STATS_SKIN_ENQ},
+/*80*/	{VFE_CMD_STATS_IHIST_ENQ},
+		{VFE_CMD_DUMMY_8},
+		{VFE_CMD_JPEG_ENC_CFG},
+		{VFE_CMD_DUMMY_9},
+		{VFE_CMD_STATS_AF_START, V31_STATS_AF_LEN, V31_STATS_AF_OFF},
+/*85*/	{VFE_CMD_STATS_AF_STOP},
+		{VFE_CMD_STATS_AE_START, V31_STATS_AE_LEN, V31_STATS_AE_OFF},
+		{VFE_CMD_STATS_AE_STOP},
+		{VFE_CMD_STATS_AWB_START, V31_STATS_AWB_LEN, V31_STATS_AWB_OFF},
+		{VFE_CMD_STATS_AWB_STOP},
+/*90*/	{VFE_CMD_STATS_RS_START, V31_STATS_RS_LEN, V31_STATS_RS_OFF},
+		{VFE_CMD_STATS_RS_STOP},
+		{VFE_CMD_STATS_CS_START, V31_STATS_CS_LEN, V31_STATS_CS_OFF},
+		{VFE_CMD_STATS_CS_STOP},
+		{VFE_CMD_STATS_SKIN_START},
+/*95*/	{VFE_CMD_STATS_SKIN_STOP},
+		{VFE_CMD_STATS_IHIST_START,
+		V31_STATS_IHIST_LEN, V31_STATS_IHIST_OFF},
+		{VFE_CMD_STATS_IHIST_STOP},
+		{VFE_CMD_DUMMY_10},
+		{VFE_CMD_SYNC_TIMER_SETTING, V31_SYNC_TIMER_LEN,
+			V31_SYNC_TIMER_OFF},
+/*100*/	{VFE_CMD_ASYNC_TIMER_SETTING, V31_ASYNC_TIMER_LEN, V31_ASYNC_TIMER_OFF},
+		{VFE_CMD_LIVESHOT},
+		{VFE_CMD_LA_SETUP},
+		{VFE_CMD_LINEARIZATION_CFG},
+		{VFE_CMD_DEMOSAICV3},
+/*105*/	{VFE_CMD_DEMOSAICV3_ABCC_CFG},
+	{VFE_CMD_DEMOSAICV3_DBCC_CFG},
+		{VFE_CMD_DEMOSAICV3_DBPC_CFG, V31_DEMOSAICV3_DBPC_LEN,
+			V31_DEMOSAICV3_DBPC_CFG_OFF},
+		{VFE_CMD_DEMOSAICV3_ABF_CFG, V31_DEMOSAICV3_ABF_LEN,
+			V31_DEMOSAICV3_ABF_OFF},
+		{VFE_CMD_DEMOSAICV3_ABCC_UPDATE},
+/*110*/	{VFE_CMD_DEMOSAICV3_DBCC_UPDATE},
+		{VFE_CMD_DEMOSAICV3_DBPC_UPDATE, V31_DEMOSAICV3_DBPC_LEN,
+			V31_DEMOSAICV3_DBPC_CFG_OFF},
+		{VFE_CMD_XBAR_CFG},
+		{VFE_CMD_MODULE_CFG, V31_MODULE_CFG_LEN, V31_MODULE_CFG_OFF},
+		{VFE_CMD_ZSL},
+/*115*/	{VFE_CMD_LINEARIZATION_UPDATE},
+		{VFE_CMD_DEMOSAICV3_ABF_UPDATE, V31_DEMOSAICV3_ABF_LEN,
+			V31_DEMOSAICV3_ABF_OFF},
+		{VFE_CMD_CLF_CFG},
+		{VFE_CMD_CLF_LUMA_UPDATE},
+		{VFE_CMD_CLF_CHROMA_UPDATE},
+/*120*/ {VFE_CMD_PCA_ROLL_OFF_CFG},
+		{VFE_CMD_PCA_ROLL_OFF_UPDATE},
+		{VFE_CMD_GET_REG_DUMP},
+		{VFE_CMD_GET_LINEARIZATON_TABLE},
+		{VFE_CMD_GET_MESH_ROLLOFF_TABLE},
+/*125*/ {VFE_CMD_GET_PCA_ROLLOFF_TABLE},
+		{VFE_CMD_GET_RGB_G_TABLE},
+		{VFE_CMD_GET_LA_TABLE},
+		{VFE_CMD_DEMOSAICV3_UPDATE},
+};
+
+uint32_t vfe31_AXI_WM_CFG[] = {
+	0x0000004C,
+	0x00000064,
+	0x0000007C,
+	0x00000094,
+	0x000000AC,
+	0x000000C4,
+	0x000000DC,
+};
+
+static const char * const vfe31_general_cmd[] = {
+	"DUMMY_0",  /* 0 */
+	"SET_CLK",
+	"RESET",
+	"START",
+	"TEST_GEN_START",
+	"OPERATION_CFG",  /* 5 */
+	"AXI_OUT_CFG",
+	"CAMIF_CFG",
+	"AXI_INPUT_CFG",
+	"BLACK_LEVEL_CFG",
+	"ROLL_OFF_CFG",  /* 10 */
+	"DEMUX_CFG",
+	"FOV_CFG",
+	"MAIN_SCALER_CFG",
+	"WB_CFG",
+	"COLOR_COR_CFG", /* 15 */
+	"RGB_G_CFG",
+	"LA_CFG",
+	"CHROMA_EN_CFG",
+	"CHROMA_SUP_CFG",
+	"MCE_CFG", /* 20 */
+	"SK_ENHAN_CFG",
+	"ASF_CFG",
+	"S2Y_CFG",
+	"S2CbCr_CFG",
+	"CHROMA_SUBS_CFG",  /* 25 */
+	"OUT_CLAMP_CFG",
+	"FRAME_SKIP_CFG",
+	"DUMMY_1",
+	"DUMMY_2",
+	"DUMMY_3",  /* 30 */
+	"UPDATE",
+	"BL_LVL_UPDATE",
+	"DEMUX_UPDATE",
+	"FOV_UPDATE",
+	"MAIN_SCALER_UPDATE",  /* 35 */
+	"WB_UPDATE",
+	"COLOR_COR_UPDATE",
+	"RGB_G_UPDATE",
+	"LA_UPDATE",
+	"CHROMA_EN_UPDATE",  /* 40 */
+	"CHROMA_SUP_UPDATE",
+	"MCE_UPDATE",
+	"SK_ENHAN_UPDATE",
+	"S2CbCr_UPDATE",
+	"S2Y_UPDATE",  /* 45 */
+	"ASF_UPDATE",
+	"FRAME_SKIP_UPDATE",
+	"CAMIF_FRAME_UPDATE",
+	"STATS_AF_UPDATE",
+	"STATS_AE_UPDATE",  /* 50 */
+	"STATS_AWB_UPDATE",
+	"STATS_RS_UPDATE",
+	"STATS_CS_UPDATE",
+	"STATS_SKIN_UPDATE",
+	"STATS_IHIST_UPDATE",  /* 55 */
+	"DUMMY_4",
+	"EPOCH1_ACK",
+	"EPOCH2_ACK",
+	"START_RECORDING",
+	"STOP_RECORDING",  /* 60 */
+	"DUMMY_5",
+	"DUMMY_6",
+	"CAPTURE",
+	"DUMMY_7",
+	"STOP",  /* 65 */
+	"GET_HW_VERSION",
+	"GET_FRAME_SKIP_COUNTS",
+	"OUTPUT1_BUFFER_ENQ",
+	"OUTPUT2_BUFFER_ENQ",
+	"OUTPUT3_BUFFER_ENQ",  /* 70 */
+	"JPEG_OUT_BUF_ENQ",
+	"RAW_OUT_BUF_ENQ",
+	"RAW_IN_BUF_ENQ",
+	"STATS_AF_ENQ",
+	"STATS_AE_ENQ",  /* 75 */
+	"STATS_AWB_ENQ",
+	"STATS_RS_ENQ",
+	"STATS_CS_ENQ",
+	"STATS_SKIN_ENQ",
+	"STATS_IHIST_ENQ",  /* 80 */
+	"DUMMY_8",
+	"JPEG_ENC_CFG",
+	"DUMMY_9",
+	"STATS_AF_START",
+	"STATS_AF_STOP",  /* 85 */
+	"STATS_AE_START",
+	"STATS_AE_STOP",
+	"STATS_AWB_START",
+	"STATS_AWB_STOP",
+	"STATS_RS_START",  /* 90 */
+	"STATS_RS_STOP",
+	"STATS_CS_START",
+	"STATS_CS_STOP",
+	"STATS_SKIN_START",
+	"STATS_SKIN_STOP",  /* 95 */
+	"STATS_IHIST_START",
+	"STATS_IHIST_STOP",
+	"DUMMY_10",
+	"SYNC_TIMER_SETTING",
+	"ASYNC_TIMER_SETTING",  /* 100 */
+	"LIVESHOT",
+	"LA_SETUP",
+	"LINEARIZATION_CFG",
+	"DEMOSAICV3",
+	"DEMOSAICV3_ABCC_CFG", /* 105 */
+	"DEMOSAICV3_DBCC_CFG",
+	"DEMOSAICV3_DBPC_CFG",
+	"DEMOSAICV3_ABF_CFG",
+	"DEMOSAICV3_ABCC_UPDATE",
+	"DEMOSAICV3_DBCC_UPDATE", /* 110 */
+	"DEMOSAICV3_DBPC_UPDATE",
+	"XBAR_CFG",
+	"EZTUNE_CFG",
+	"V31_ZSL",
+	"LINEARIZATION_UPDATE", /*115*/
+	"DEMOSAICV3_ABF_UPDATE",
+	"CLF_CFG",
+	"CLF_LUMA_UPDATE",
+	"CLF_CHROMA_UPDATE",
+	"PCA_ROLL_OFF_CFG", /*120*/
+	"PCA_ROLL_OFF_UPDATE",
+	"GET_REG_DUMP",
+	"GET_LINEARIZATON_TABLE",
+	"GET_MESH_ROLLOFF_TABLE",
+	"GET_PCA_ROLLOFF_TABLE", /*125*/
+	"GET_RGB_G_TABLE",
+	"GET_LA_TABLE",
+	"DEMOSAICV3_UPDATE",
+};
+
+
+static unsigned long vfe31_stats_dqbuf(enum msm_stats_enum_type stats_type)
+{
+	struct msm_stats_meta_buf *buf = NULL;
+	int rc = 0;
+	rc = vfe31_ctrl->stats_ops.dqbuf(vfe31_ctrl->stats_ops.stats_ctrl,
+			stats_type, &buf);
+	if (rc < 0) {
+		CDBG("%s: dq stats buf (type = %d) err = %d",
+			__func__, stats_type, rc);
+		return 0L;
+	}
+	return buf->paddr;
+}
+
+static unsigned long vfe31_stats_flush_enqueue(
+	enum msm_stats_enum_type stats_type)
+{
+	struct msm_stats_bufq *bufq = NULL;
+	struct msm_stats_meta_buf *stats_buf = NULL;
+	int rc = 0;
+	int i;
+	/*
+	 * Passing NULL for ion client as the buffers are already
+	 * mapped at this stage, client is not required, flush all
+	 * the buffers, and buffers move to PREPARE state
+	 */
+
+	rc = vfe31_ctrl->stats_ops.bufq_flush(
+			vfe31_ctrl->stats_ops.stats_ctrl, stats_type, NULL);
+	if (rc < 0) {
+		pr_err("%s: dq stats buf (type = %d) err = %d",
+			__func__, stats_type, rc);
+		return 0L;
+	}
+
+	/* Queue all the buffers back to QUEUED state */
+	bufq = vfe31_ctrl->stats_ctrl.bufq[stats_type];
+	for (i = 0; i < bufq->num_bufs; i++) {
+		stats_buf = &bufq->bufs[i];
+		rc = vfe31_ctrl->stats_ops.enqueue_buf(
+				vfe31_ctrl->stats_ops.stats_ctrl,
+				&(stats_buf->info), NULL, -1);
+		if (rc < 0) {
+			pr_err("%s: dq stats buf (type = %d) err = %d",
+				__func__, stats_type, rc);
+			return rc;
+		}
+	}
+	return 0L;
+}
+
+static unsigned long vfe31_stats_unregbuf(
+	struct msm_stats_reqbuf *req_buf, int domain_num)
+{
+	int i = 0, rc = 0;
+
+	for (i = 0; i < req_buf->num_buf; i++) {
+		rc = vfe31_ctrl->stats_ops.buf_unprepare(
+			vfe31_ctrl->stats_ops.stats_ctrl,
+			req_buf->stats_type, i,
+			vfe31_ctrl->stats_ops.client, domain_num);
+		if (rc < 0) {
+			pr_err("%s: unreg stats buf (type = %d) err = %d",
+				__func__, req_buf->stats_type, rc);
+		return rc;
+		}
+	}
+	return 0L;
+}
+
+static int vfe_stats_awb_buf_init(
+	struct vfe_cmd_stats_buf *in)
+{
+	uint32_t addr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_AWB);
+	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq awb ping buf from free buf queue", __func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR);
+	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_AWB);
+	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq awb ping buf from free buf queue", __func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR);
+	return 0;
+}
+
+static int vfe_stats_aec_buf_init(
+	struct vfe_cmd_stats_buf *in)
+{
+	uint32_t addr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_AEC);
+	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq aec ping buf from free buf queue",
+			__func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe31_ctrl->vfebase +
+		VFE_BUS_STATS_AEC_WR_PING_ADDR);
+	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_AEC);
+	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq aec pong buf from free buf queue",
+			__func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe31_ctrl->vfebase +
+		VFE_BUS_STATS_AEC_WR_PONG_ADDR);
+	return 0;
+}
+
+static int vfe_stats_af_buf_init(
+	struct vfe_cmd_stats_buf *in)
+{
+	uint32_t addr;
+	unsigned long flags;
+	int rc = 0;
+
+	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
+	rc = vfe31_stats_flush_enqueue(MSM_STATS_TYPE_AF);
+	if (rc < 0) {
+		pr_err("%s: dq stats buf err = %d",
+			__func__, rc);
+		spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
+		return -EINVAL;
+	}
+	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_AF);
+	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq af ping buf from free buf queue", __func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR);
+	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_AF);
+	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq af pong buf from free buf queue", __func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR);
+	return 0;
+}
+
+static int vfe_stats_ihist_buf_init(
+	struct vfe_cmd_stats_buf *in)
+{
+	uint32_t addr;
+	unsigned long flags;
+	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_IHIST);
+	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq ihist ping buf from free buf queue",
+			__func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_HIST_WR_PING_ADDR);
+	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_IHIST);
+	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq ihist pong buf from free buf queue", __func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_HIST_WR_PONG_ADDR);
+	return 0;
+}
+
+static int vfe_stats_rs_buf_init(struct vfe_cmd_stats_buf *in)
+{
+	uint32_t addr;
+	unsigned long flags;
+	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_RS);
+	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq rs ping buf from free buf queue", __func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_RS_WR_PING_ADDR);
+	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_RS);
+	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq rs pong buf from free buf queue", __func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_RS_WR_PONG_ADDR);
+	return 0;
+}
+
+static int vfe_stats_cs_buf_init(struct vfe_cmd_stats_buf *in)
+{
+	uint32_t addr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_CS);
+	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq cs ping buf from free buf queue", __func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_CS_WR_PING_ADDR);
+	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_CS);
+	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq cs pong buf from free buf queue", __func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_CS_WR_PONG_ADDR);
+	return 0;
+}
+
+static void vfe31_stop(void)
+{
+	uint8_t  axiBusyFlag = true;
+	unsigned long flags;
+
+	atomic_set(&vfe31_ctrl->vstate, 0);
+
+	/* for reset hw modules, and send msg when reset_irq comes.*/
+	spin_lock_irqsave(&vfe31_ctrl->stop_flag_lock, flags);
+	vfe31_ctrl->stop_ack_pending = TRUE;
+	spin_unlock_irqrestore(&vfe31_ctrl->stop_flag_lock, flags);
+
+	/* disable all interrupts.  */
+	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
+		vfe31_ctrl->vfebase + VFE_IRQ_MASK_0);
+	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
+		vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+	/* clear all pending interrupts*/
+	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
+		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_0);
+	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
+		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_1);
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_camera_io_w_mb(1,
+		vfe31_ctrl->vfebase + VFE_IRQ_CMD);
+
+	/* in either continuous or snapshot mode, stop command can be issued
+	 * at any time. stop camif immediately. */
+	msm_camera_io_w_mb(CAMIF_COMMAND_STOP_IMMEDIATELY,
+		vfe31_ctrl->vfebase + VFE_CAMIF_COMMAND);
+	/* axi halt command. */
+	msm_camera_io_w(AXI_HALT,
+		vfe31_ctrl->vfebase + VFE_AXI_CMD);
+	wmb();
+	while (axiBusyFlag) {
+		if (msm_camera_io_r(vfe31_ctrl->vfebase + VFE_AXI_STATUS) & 0x1)
+			axiBusyFlag = false;
+	}
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_camera_io_w_mb(AXI_HALT_CLEAR,
+		vfe31_ctrl->vfebase + VFE_AXI_CMD);
+
+	/* now enable only halt_irq & reset_irq */
+	msm_camera_io_w(0xf0000000,          /* this is for async timer. */
+		vfe31_ctrl->vfebase + VFE_IRQ_MASK_0);
+	msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_1,
+		vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+	msm_camera_io_w_mb(VFE_RESET_UPON_STOP_CMD,
+		vfe31_ctrl->vfebase + VFE_GLOBAL_RESET);
+}
+
+static void vfe31_subdev_notify(int id, int path, uint32_t inst_handle)
+{
+	struct msm_vfe_resp rp;
+	struct msm_frame_info frame_info;
+	unsigned long flags;
+	spin_lock_irqsave(&vfe31_ctrl->sd_notify_lock, flags);
+	memset(&rp, 0, sizeof(struct msm_vfe_resp));
+	CDBG("vfe31_subdev_notify : msgId = %d\n", id);
+	rp.evt_msg.type   = MSM_CAMERA_MSG;
+	frame_info.inst_handle = inst_handle;
+	frame_info.path = path;
+	rp.evt_msg.data = &frame_info;
+	rp.type	   = id;
+	v4l2_subdev_notify(&vfe31_ctrl->subdev, NOTIFY_VFE_BUF_EVT, &rp);
+	spin_unlock_irqrestore(&vfe31_ctrl->sd_notify_lock, flags);
+}
+
+static int vfe31_config_axi(int mode, uint32_t *ao)
+{
+	uint32_t *ch_info;
+	uint32_t *axi_cfg = ao + V31_AXI_RESERVED;
+	uint32_t bus_cmd = *axi_cfg;
+	int i;
+
+	/* Update the corresponding write masters for each output*/
+	ch_info = axi_cfg + V31_AXI_CFG_LEN;
+	vfe31_ctrl->outpath.out0.ch0 = 0x0000FFFF & *ch_info;
+	vfe31_ctrl->outpath.out0.ch1 = 0x0000FFFF & (*ch_info++ >> 16);
+	vfe31_ctrl->outpath.out0.ch2 = 0x0000FFFF & *ch_info++;
+	vfe31_ctrl->outpath.out0.inst_handle = *ch_info++;
+	vfe31_ctrl->outpath.out1.ch0 = 0x0000FFFF & *ch_info;
+	vfe31_ctrl->outpath.out1.ch1 = 0x0000FFFF & (*ch_info++ >> 16);
+	vfe31_ctrl->outpath.out1.ch2 = 0x0000FFFF & *ch_info++;
+	vfe31_ctrl->outpath.out1.inst_handle = *ch_info++;
+	vfe31_ctrl->outpath.out2.ch0 = 0x0000FFFF & *ch_info;
+	vfe31_ctrl->outpath.out2.ch1 = 0x0000FFFF & (*ch_info++ >> 16);
+	vfe31_ctrl->outpath.out2.ch2 = 0x0000FFFF & *ch_info++;
+	vfe31_ctrl->outpath.out2.inst_handle = *ch_info++;
+
+	switch (mode) {
+	case OUTPUT_PRIM:
+		vfe31_ctrl->outpath.output_mode =
+			VFE31_OUTPUT_MODE_PRIMARY;
+		break;
+	case OUTPUT_PRIM_ALL_CHNLS:
+		vfe31_ctrl->outpath.output_mode =
+			VFE31_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
+		break;
+	case OUTPUT_PRIM|OUTPUT_SEC:
+		vfe31_ctrl->outpath.output_mode =
+			VFE31_OUTPUT_MODE_PRIMARY;
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_SECONDARY;
+		break;
+	case OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS:
+		vfe31_ctrl->outpath.output_mode =
+			VFE31_OUTPUT_MODE_PRIMARY;
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_SECONDARY_ALL_CHNLS;
+		break;
+	case OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC:
+		vfe31_ctrl->outpath.output_mode =
+			VFE31_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_SECONDARY;
+		break;
+	default:
+		pr_err("%s Invalid AXI mode %d ", __func__, mode);
+		return -EINVAL;
+	}
+
+	axi_cfg++;
+	msm_camera_io_memcpy(vfe31_ctrl->vfebase +
+		vfe31_cmd[VFE_CMD_AXI_OUT_CFG].offset, axi_cfg,
+		V31_AXI_BUS_CFG_LEN);
+	axi_cfg += V31_AXI_BUS_CFG_LEN/4;
+	for (i = 0; i < ARRAY_SIZE(vfe31_AXI_WM_CFG); i++) {
+		msm_camera_io_w(*axi_cfg,
+		vfe31_ctrl->vfebase+vfe31_AXI_WM_CFG[i]);
+		axi_cfg += 3;
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase+vfe31_AXI_WM_CFG[i]+12,
+							axi_cfg, 12);
+		axi_cfg += 3;
+	}
+	msm_camera_io_w(bus_cmd, vfe31_ctrl->vfebase +
+					V31_AXI_BUS_CMD_OFF);
+
+	return 0;
+}
+
+static void vfe31_reset_internal_variables(void)
+{
+	unsigned long flags;
+	vfe31_ctrl->vfeImaskCompositePacked = 0;
+	/* state control variables */
+	vfe31_ctrl->start_ack_pending = FALSE;
+	atomic_set(&irq_cnt, 0);
+
+	spin_lock_irqsave(&vfe31_ctrl->stop_flag_lock, flags);
+	vfe31_ctrl->stop_ack_pending  = FALSE;
+	spin_unlock_irqrestore(&vfe31_ctrl->stop_flag_lock, flags);
+
+	vfe31_ctrl->reset_ack_pending  = FALSE;
+
+	spin_lock_irqsave(&vfe31_ctrl->update_ack_lock, flags);
+	vfe31_ctrl->update_ack_pending = FALSE;
+	spin_unlock_irqrestore(&vfe31_ctrl->update_ack_lock, flags);
+
+	vfe31_ctrl->recording_state = VFE_STATE_IDLE;
+	vfe31_ctrl->liveshot_state = VFE_STATE_IDLE;
+
+	atomic_set(&vfe31_ctrl->vstate, 0);
+
+	/* 0 for continuous mode, 1 for snapshot mode */
+	vfe31_ctrl->operation_mode = 0;
+	vfe31_ctrl->outpath.output_mode = 0;
+	vfe31_ctrl->vfe_capture_count = 0;
+
+	/* this is unsigned 32 bit integer. */
+	vfe31_ctrl->vfeFrameId = 0;
+	/* Stats control variables. */
+	memset(&(vfe31_ctrl->afStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe31_ctrl->awbStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe31_ctrl->aecStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe31_ctrl->ihistStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe31_ctrl->rsStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe31_ctrl->csStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	vfe31_ctrl->frame_skip_cnt = 31;
+	vfe31_ctrl->frame_skip_pattern = 0xffffffff;
+	vfe31_ctrl->snapshot_frame_cnt = 0;
+}
+
+static void vfe31_reset(void)
+{
+	vfe31_reset_internal_variables();
+	/* disable all interrupts.  vfeImaskLocal is also reset to 0
+	* to begin with. */
+	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
+		vfe31_ctrl->vfebase + VFE_IRQ_MASK_0);
+
+	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
+		vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+	/* clear all pending interrupts*/
+	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
+		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_0);
+	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
+		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_1);
+
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_IRQ_CMD);
+
+	/* enable reset_ack interrupt.  */
+	msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_1,
+	vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+	/* Write to VFE_GLOBAL_RESET_CMD to reset the vfe hardware. Once reset
+	 * is done, hardware interrupt will be generated.  VFE ist processes
+	 * the interrupt to complete the function call.  Note that the reset
+	 * function is synchronous. */
+
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_camera_io_w_mb(VFE_RESET_UPON_RESET_CMD,
+		vfe31_ctrl->vfebase + VFE_GLOBAL_RESET);
+}
+
+static int vfe31_operation_config(uint32_t *cmd)
+{
+	uint32_t *p = cmd;
+
+	vfe31_ctrl->operation_mode = *p;
+	vfe31_ctrl->stats_comp = *(++p);
+	vfe31_ctrl->hfr_mode = *(++p);
+
+	msm_camera_io_w(*(++p), vfe31_ctrl->vfebase + VFE_CFG);
+	msm_camera_io_w(*(++p), vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+	msm_camera_io_w(*(++p), vfe31_ctrl->vfebase + VFE_REALIGN_BUF);
+	msm_camera_io_w(*(++p), vfe31_ctrl->vfebase + VFE_CHROMA_UP);
+	msm_camera_io_w(*(++p), vfe31_ctrl->vfebase + VFE_STATS_CFG);
+	return 0;
+}
+
+static void msm_camera_io_dump2(void __iomem *addr, int size)
+{
+	char line_str[BUFF_SIZE_128], *p_str;
+	int i;
+	u32 *p = (u32 *) addr;
+	u32 data;
+	CDBG("%s: %p %d\n", __func__, addr, size);
+	line_str[0] = '\0';
+	p_str = line_str;
+	for (i = 0; i < size/4; i++) {
+		if (i % 4 == 0) {
+			snprintf(p_str, 12, "%08x: ", (u32) p);
+			p_str += 10;
+		}
+		data = readl_relaxed(p++);
+		snprintf(p_str, 12, "%08x ", data);
+		p_str += 9;
+		if ((i + 1) % 4 == 0) {
+			CDBG("%s\n", line_str);
+			line_str[0] = '\0';
+			p_str = line_str;
+		}
+	}
+	if (line_str[0] != '\0')
+		CDBG("%s\n", line_str);
+}
+
+static void vfe31_start_common(void)
+{
+	uint32_t irq_mask = 0x00E00021;
+	vfe31_ctrl->start_ack_pending = TRUE;
+	CDBG("VFE opertaion mode = 0x%x, output mode = 0x%x\n",
+		vfe31_ctrl->operation_mode, vfe31_ctrl->outpath.output_mode);
+	if (vfe31_ctrl->stats_comp)
+		irq_mask |= VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK;
+	else
+		irq_mask |= 0x000FE000;
+
+	msm_camera_io_w(irq_mask, vfe31_ctrl->vfebase + VFE_IRQ_MASK_0);
+	msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_1,
+		vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_CAMIF_COMMAND);
+
+	msm_camera_io_dump2(vfe31_ctrl->vfebase, vfe31_ctrl->register_total*4);
+	atomic_set(&vfe31_ctrl->vstate, 1);
+}
+
+static int vfe31_start_recording(struct msm_cam_media_controller *pmctl)
+{
+	msm_camio_bus_scale_cfg(
+		pmctl->sdata->pdata->cam_bus_scale_table, S_VIDEO);
+	vfe31_ctrl->recording_state = VFE_STATE_START_REQUESTED;
+	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	return 0;
+}
+
+static int vfe31_stop_recording(struct msm_cam_media_controller *pmctl)
+{
+	vfe31_ctrl->recording_state = VFE_STATE_STOP_REQUESTED;
+	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	msm_camio_bus_scale_cfg(
+		pmctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
+	return 0;
+}
+
+static void vfe31_start_liveshot(struct msm_cam_media_controller *pmctl)
+{
+	/* Hardcode 1 live snapshot for now. */
+	vfe31_ctrl->outpath.out0.capture_cnt = 1;
+	vfe31_ctrl->vfe_capture_count = vfe31_ctrl->outpath.out0.capture_cnt;
+
+	vfe31_ctrl->liveshot_state = VFE_STATE_START_REQUESTED;
+	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+}
+
+static int vfe31_zsl(struct msm_cam_media_controller *pmctl)
+{
+	uint32_t irq_comp_mask = 0;
+	/* capture command is valid for both idle and active state. */
+	irq_comp_mask	=
+		msm_camera_io_r(vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+
+	CDBG("%s:op mode %d O/P Mode %d\n", __func__,
+		vfe31_ctrl->operation_mode, vfe31_ctrl->outpath.output_mode);
+
+	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_PRIMARY) {
+		irq_comp_mask |= ((0x1 << (vfe31_ctrl->outpath.out0.ch0)) |
+			(0x1 << (vfe31_ctrl->outpath.out0.ch1)));
+	} else if (vfe31_ctrl->outpath.output_mode &
+		VFE31_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+		irq_comp_mask |= ((0x1 << (vfe31_ctrl->outpath.out0.ch0)) |
+			(0x1 << (vfe31_ctrl->outpath.out0.ch1)) |
+			(0x1 << (vfe31_ctrl->outpath.out0.ch2)));
+	}
+
+	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_SECONDARY) {
+		irq_comp_mask |= ((0x1 << (vfe31_ctrl->outpath.out1.ch0 + 8)) |
+			(0x1 << (vfe31_ctrl->outpath.out1.ch1 + 8)));
+	} else if (vfe31_ctrl->outpath.output_mode &
+		VFE31_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+		irq_comp_mask |= ((0x1 << (vfe31_ctrl->outpath.out1.ch0 + 8)) |
+			(0x1 << (vfe31_ctrl->outpath.out1.ch1 + 8)) |
+			(0x1 << (vfe31_ctrl->outpath.out1.ch2 + 8)));
+	}
+
+	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_PRIMARY) {
+		msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+		msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+	} else if (vfe31_ctrl->outpath.output_mode &
+		VFE31_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+		msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+		msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+		msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch2]);
+	}
+
+	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_SECONDARY) {
+		msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
+		msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
+	} else if (vfe31_ctrl->outpath.output_mode &
+		VFE31_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+		msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
+		msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
+		msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch2]);
+	}
+
+	msm_camera_io_w(irq_comp_mask, vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+	vfe31_start_common();
+	msm_camio_bus_scale_cfg(
+		pmctl->sdata->pdata->cam_bus_scale_table, S_ZSL);
+
+	msm_camera_io_w(1, vfe31_ctrl->vfebase + 0x18C);
+	msm_camera_io_w(1, vfe31_ctrl->vfebase + 0x188);
+	return 0;
+}
+static int vfe31_capture_raw(
+	struct msm_cam_media_controller *pmctl,
+	uint32_t num_frames_capture)
+{
+	uint32_t irq_comp_mask = 0;
+
+	vfe31_ctrl->outpath.out0.capture_cnt = num_frames_capture;
+	vfe31_ctrl->vfe_capture_count = num_frames_capture;
+
+	irq_comp_mask =
+		msm_camera_io_r(vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+
+	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_PRIMARY) {
+		irq_comp_mask |= (0x1 << (vfe31_ctrl->outpath.out0.ch0));
+		msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+	}
+
+	msm_camera_io_w(irq_comp_mask, vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+	msm_camio_bus_scale_cfg(
+		pmctl->sdata->pdata->cam_bus_scale_table, S_CAPTURE);
+	vfe31_start_common();
+	return 0;
+}
+
+static int vfe31_capture(
+	struct msm_cam_media_controller *pmctl,
+	uint32_t num_frames_capture)
+{
+	uint32_t irq_comp_mask = 0;
+	/* capture command is valid for both idle and active state. */
+	vfe31_ctrl->outpath.out1.capture_cnt = num_frames_capture;
+	if (vfe31_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB ||
+		vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN ||
+		vfe31_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB ||
+		vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG) {
+		vfe31_ctrl->outpath.out0.capture_cnt =
+			num_frames_capture;
+	}
+
+	vfe31_ctrl->vfe_capture_count = num_frames_capture;
+	irq_comp_mask = msm_camera_io_r(
+				vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+
+	if (vfe31_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB ||
+		vfe31_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB ||
+		vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN) {
+		if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_PRIMARY) {
+			irq_comp_mask |= (0x1 << vfe31_ctrl->outpath.out0.ch0 |
+				0x1 << vfe31_ctrl->outpath.out0.ch1);
+		}
+		if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_SECONDARY) {
+			irq_comp_mask |=
+				(0x1 << (vfe31_ctrl->outpath.out1.ch0 + 8) |
+				0x1 << (vfe31_ctrl->outpath.out1.ch1 + 8));
+		}
+		if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_PRIMARY) {
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+		}
+		if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_SECONDARY) {
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
+		}
+	}
+
+	vfe31_ctrl->vfe_capture_count = num_frames_capture;
+
+	msm_camera_io_w(irq_comp_mask, vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+	msm_camera_io_r(vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+	msm_camio_bus_scale_cfg(
+		pmctl->sdata->pdata->cam_bus_scale_table, S_CAPTURE);
+
+	vfe31_start_common();
+	/* for debug */
+	msm_camera_io_w(1, vfe31_ctrl->vfebase + 0x18C);
+	msm_camera_io_w(1, vfe31_ctrl->vfebase + 0x188);
+	return 0;
+}
+
+static int vfe31_start(struct msm_cam_media_controller *pmctl)
+{
+	uint32_t irq_comp_mask = 0;
+
+	irq_comp_mask	=
+		msm_camera_io_r(vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+
+	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_PRIMARY) {
+		irq_comp_mask |= (0x1 << vfe31_ctrl->outpath.out0.ch0 |
+			0x1 << vfe31_ctrl->outpath.out0.ch1);
+	} else if (vfe31_ctrl->outpath.output_mode &
+		VFE31_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+		irq_comp_mask |= (0x1 << vfe31_ctrl->outpath.out0.ch0 |
+			0x1 << vfe31_ctrl->outpath.out0.ch1 |
+			0x1 << vfe31_ctrl->outpath.out0.ch2);
+	}
+	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_SECONDARY) {
+		irq_comp_mask |= (0x1 << (vfe31_ctrl->outpath.out1.ch0 + 8) |
+			0x1 << (vfe31_ctrl->outpath.out1.ch1 + 8));
+	} else if (vfe31_ctrl->outpath.output_mode &
+		VFE31_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+		irq_comp_mask |= (0x1 << (vfe31_ctrl->outpath.out1.ch0 + 8) |
+			0x1 << (vfe31_ctrl->outpath.out1.ch1 + 8) |
+			0x1 << (vfe31_ctrl->outpath.out1.ch2 + 8));
+	}
+	msm_camera_io_w(irq_comp_mask, vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+
+	switch (vfe31_ctrl->operation_mode) {
+	case VFE_OUTPUTS_PREVIEW:
+	case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
+		if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_PRIMARY) {
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+		} else if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch2]);
+		}
+		break;
+	default:
+		if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_SECONDARY) {
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
+		} else if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch2]);
+		}
+		break;
+	}
+	msm_camio_bus_scale_cfg(
+		pmctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
+	vfe31_start_common();
+	return 0;
+}
+
+static void vfe31_update(void)
+{
+	unsigned long flags;
+
+	if (vfe31_ctrl->update_la) {
+		if (!msm_camera_io_r(vfe31_ctrl->vfebase + V31_LA_OFF))
+			msm_camera_io_w(1, vfe31_ctrl->vfebase + V31_LA_OFF);
+		else
+			msm_camera_io_w(0, vfe31_ctrl->vfebase + V31_LA_OFF);
+		vfe31_ctrl->update_la = false;
+	}
+
+	if (vfe31_ctrl->update_gamma) {
+		if (!msm_camera_io_r(vfe31_ctrl->vfebase + V31_RGB_G_OFF))
+			msm_camera_io_w(7, vfe31_ctrl->vfebase+V31_RGB_G_OFF);
+		else
+			msm_camera_io_w(0, vfe31_ctrl->vfebase+V31_RGB_G_OFF);
+		vfe31_ctrl->update_gamma = false;
+	}
+
+	spin_lock_irqsave(&vfe31_ctrl->update_ack_lock, flags);
+	vfe31_ctrl->update_ack_pending = TRUE;
+	spin_unlock_irqrestore(&vfe31_ctrl->update_ack_lock, flags);
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	return;
+}
+
+static void vfe31_sync_timer_stop(void)
+{
+	uint32_t value = 0;
+	vfe31_ctrl->sync_timer_state = 0;
+	if (vfe31_ctrl->sync_timer_number == 0)
+		value = 0x10000;
+	else if (vfe31_ctrl->sync_timer_number == 1)
+		value = 0x20000;
+	else if (vfe31_ctrl->sync_timer_number == 2)
+		value = 0x40000;
+
+	/* Timer Stop */
+	msm_camera_io_w(value, vfe31_ctrl->vfebase + V31_SYNC_TIMER_OFF);
+}
+
+static void vfe31_sync_timer_start(const uint32_t *tbl)
+{
+	/* set bit 8 for auto increment. */
+	uint32_t value = 1;
+	uint32_t val;
+
+	vfe31_ctrl->sync_timer_state = *tbl++;
+	vfe31_ctrl->sync_timer_repeat_count = *tbl++;
+	vfe31_ctrl->sync_timer_number = *tbl++;
+	CDBG("%s timer_state %d, repeat_cnt %d timer number %d\n",
+		 __func__, vfe31_ctrl->sync_timer_state,
+		 vfe31_ctrl->sync_timer_repeat_count,
+		 vfe31_ctrl->sync_timer_number);
+
+	if (vfe31_ctrl->sync_timer_state) { /* Start Timer */
+		value = value << vfe31_ctrl->sync_timer_number;
+	} else { /* Stop Timer */
+		CDBG("Failed to Start timer\n");
+		return;
+	}
+
+	/* Timer Start */
+	msm_camera_io_w(value, vfe31_ctrl->vfebase + V31_SYNC_TIMER_OFF);
+	/* Sync Timer Line Start */
+	value = *tbl++;
+	msm_camera_io_w(value, vfe31_ctrl->vfebase + V31_SYNC_TIMER_OFF +
+		4 + ((vfe31_ctrl->sync_timer_number) * 12));
+	/* Sync Timer Pixel Start */
+	value = *tbl++;
+	msm_camera_io_w(value, vfe31_ctrl->vfebase + V31_SYNC_TIMER_OFF +
+		 8 + ((vfe31_ctrl->sync_timer_number) * 12));
+	/* Sync Timer Pixel Duration */
+	value = *tbl++;
+	val = vfe_clk_rate / 10000;
+	val = 10000000 / val;
+	val = value * 10000 / val;
+	CDBG("%s: Pixel Clk Cycles!!! %d\n", __func__, val);
+	msm_camera_io_w(val, vfe31_ctrl->vfebase + V31_SYNC_TIMER_OFF +
+		12 + ((vfe31_ctrl->sync_timer_number) * 12));
+	/* Timer0 Active High/LOW */
+	value = *tbl++;
+	msm_camera_io_w(value,
+		vfe31_ctrl->vfebase + V31_SYNC_TIMER_POLARITY_OFF);
+	/* Selects sync timer 0 output to drive onto timer1 port */
+	value = 0;
+	msm_camera_io_w(value, vfe31_ctrl->vfebase + V31_TIMER_SELECT_OFF);
+}
+
+static void vfe31_program_dmi_cfg(enum VFE31_DMI_RAM_SEL bankSel)
+{
+	/* set bit 8 for auto increment. */
+	uint32_t value = VFE_DMI_CFG_DEFAULT;
+	value += (uint32_t)bankSel;
+	CDBG("%s: banksel = %d\n", __func__, bankSel);
+
+	msm_camera_io_w(value, vfe31_ctrl->vfebase + VFE_DMI_CFG);
+	/* by default, always starts with offset 0.*/
+	msm_camera_io_w(0, vfe31_ctrl->vfebase + VFE_DMI_ADDR);
+}
+static void vfe31_write_gamma_cfg(enum VFE31_DMI_RAM_SEL channel_sel,
+						const uint32_t *tbl)
+{
+	int i;
+	uint32_t value, value1, value2;
+	vfe31_program_dmi_cfg(channel_sel);
+	for (i = 0 ; i < (VFE31_GAMMA_NUM_ENTRIES/2) ; i++) {
+		value = *tbl++;
+		value1 = value & 0x0000FFFF;
+		value2 = (value & 0xFFFF0000)>>16;
+		msm_camera_io_w((value1),
+			vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
+		msm_camera_io_w((value2),
+			vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
+	}
+	vfe31_program_dmi_cfg(NO_MEM_SELECTED);
+}
+
+static void vfe31_read_gamma_cfg(enum VFE31_DMI_RAM_SEL channel_sel,
+	uint32_t *tbl)
+{
+	int i;
+	vfe31_program_dmi_cfg(channel_sel);
+	CDBG("%s: Gamma table channel: %d\n", __func__, channel_sel);
+	for (i = 0 ; i < VFE31_GAMMA_NUM_ENTRIES ; i++) {
+		*tbl = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
+		CDBG("%s: %08x\n", __func__, *tbl);
+		tbl++;
+	}
+	vfe31_program_dmi_cfg(NO_MEM_SELECTED);
+}
+
+static void vfe31_write_la_cfg(enum VFE31_DMI_RAM_SEL channel_sel,
+						const uint32_t *tbl)
+{
+	uint32_t i;
+	uint32_t value, value1, value2;
+
+	vfe31_program_dmi_cfg(channel_sel);
+	for (i = 0 ; i < (VFE31_LA_TABLE_LENGTH/2) ; i++) {
+		value = *tbl++;
+		value1 = value & 0x0000FFFF;
+		value2 = (value & 0xFFFF0000)>>16;
+		msm_camera_io_w((value1),
+			vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
+		msm_camera_io_w((value2),
+			vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
+	}
+	vfe31_program_dmi_cfg(NO_MEM_SELECTED);
+}
+
+static struct vfe31_output_ch *vfe31_get_ch(int path)
+{
+	struct vfe31_output_ch *ch = NULL;
+
+	if (path == VFE_MSG_OUTPUT_PRIMARY)
+		ch = &vfe31_ctrl->outpath.out0;
+	else if (path == VFE_MSG_OUTPUT_SECONDARY)
+		ch = &vfe31_ctrl->outpath.out1;
+	else
+		pr_err("%s: Invalid path %d\n", __func__, path);
+
+	BUG_ON(ch == NULL);
+	return ch;
+}
+static struct msm_free_buf *vfe31_check_free_buffer(int id, int path)
+{
+	struct vfe31_output_ch *outch = NULL;
+	struct msm_free_buf *b = NULL;
+	uint32_t inst_handle = 0;
+
+	if (path == VFE_MSG_OUTPUT_PRIMARY)
+		inst_handle = vfe31_ctrl->outpath.out0.inst_handle;
+	else
+		inst_handle = vfe31_ctrl->outpath.out1.inst_handle;
+
+	vfe31_subdev_notify(id, path, inst_handle);
+	outch = vfe31_get_ch(path);
+	if (outch->free_buf.ch_paddr[0])
+		b = &outch->free_buf;
+	return b;
+}
+static int vfe31_configure_pingpong_buffers(int id, int path)
+{
+	struct vfe31_output_ch *outch = NULL;
+	int rc = 0;
+	uint32_t inst_handle = 0;
+
+	if (path == VFE_MSG_OUTPUT_PRIMARY)
+		inst_handle = vfe31_ctrl->outpath.out0.inst_handle;
+	else
+		inst_handle = vfe31_ctrl->outpath.out1.inst_handle;
+
+	vfe31_subdev_notify(id, path, inst_handle);
+	outch = vfe31_get_ch(path);
+	if (outch->ping.ch_paddr[0] && outch->pong.ch_paddr[0]) {
+		/* Configure Preview Ping Pong */
+		CDBG("%s Configure ping/pong address for %d",
+			__func__, path);
+		vfe31_put_ch_ping_addr(outch->ch0,
+			outch->ping.ch_paddr[0]);
+		vfe31_put_ch_pong_addr(outch->ch0,
+			outch->pong.ch_paddr[0]);
+
+		if (vfe31_ctrl->operation_mode !=
+			VFE_OUTPUTS_RAW) {
+			vfe31_put_ch_ping_addr(outch->ch1,
+				outch->ping.ch_paddr[1]);
+			vfe31_put_ch_pong_addr(outch->ch1,
+				outch->pong.ch_paddr[1]);
+		}
+
+		if (outch->ping.num_planes > 2)
+			vfe31_put_ch_ping_addr(outch->ch2,
+				outch->ping.ch_paddr[2]);
+		if (outch->pong.num_planes > 2)
+			vfe31_put_ch_pong_addr(outch->ch2,
+				outch->pong.ch_paddr[2]);
+
+		/* avoid stale info */
+		memset(&outch->ping, 0, sizeof(struct msm_free_buf));
+		memset(&outch->pong, 0, sizeof(struct msm_free_buf));
+	} else {
+		pr_err("%s ping/pong addr is null!!", __func__);
+		rc = -EINVAL;
+	}
+	return rc;
+}
+
+static void vfe31_send_isp_msg(struct vfe31_ctrl_type *vctrl,
+	uint32_t isp_msg_id)
+{
+	struct isp_msg_event isp_msg_evt;
+
+	isp_msg_evt.msg_id = isp_msg_id;
+	isp_msg_evt.sof_count = vfe31_ctrl->vfeFrameId;
+	v4l2_subdev_notify(&vctrl->subdev,
+		NOTIFY_ISP_MSG_EVT, (void *)&isp_msg_evt);
+}
+
+static int vfe31_proc_general(
+	struct msm_cam_media_controller *pmctl,
+	struct msm_isp_cmd *cmd)
+{
+	int i , rc = 0;
+	uint32_t old_val = 0 , new_val = 0;
+	uint32_t *cmdp = NULL;
+	uint32_t *cmdp_local = NULL;
+	uint32_t snapshot_cnt = 0;
+	uint32_t temp1 = 0, temp2 = 0;
+
+	CDBG("vfe31_proc_general: cmdID = %s, length = %d\n",
+		vfe31_general_cmd[cmd->id], cmd->length);
+	switch (cmd->id) {
+	case VFE_CMD_RESET:
+		pr_info("vfe31_proc_general: cmdID = %s\n",
+			vfe31_general_cmd[cmd->id]);
+		vfe31_reset();
+		break;
+	case VFE_CMD_START:
+		pr_info("vfe31_proc_general: cmdID = %s\n",
+			vfe31_general_cmd[cmd->id]);
+		if ((vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_PREVIEW_AND_VIDEO) ||
+			(vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_PREVIEW))
+			/* Configure primary channel */
+			rc = vfe31_configure_pingpong_buffers(
+				VFE_MSG_START, VFE_MSG_OUTPUT_PRIMARY);
+		else
+			/* Configure secondary channel */
+			rc = vfe31_configure_pingpong_buffers(
+				VFE_MSG_START, VFE_MSG_OUTPUT_SECONDARY);
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers"
+				" for preview", __func__);
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		rc = vfe31_start(pmctl);
+		break;
+	case VFE_CMD_UPDATE:
+		vfe31_update();
+		break;
+	case VFE_CMD_CAPTURE_RAW:
+		pr_info("%s: cmdID = VFE_CMD_CAPTURE_RAW\n", __func__);
+		if (copy_from_user(&snapshot_cnt, (void __user *)(cmd->value),
+			sizeof(uint32_t))) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		rc = vfe31_configure_pingpong_buffers(VFE_MSG_CAPTURE,
+			VFE_MSG_OUTPUT_PRIMARY);
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers"
+				" for snapshot", __func__);
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		rc = vfe31_capture_raw(pmctl, snapshot_cnt);
+		break;
+	case VFE_CMD_CAPTURE:
+		if (copy_from_user(&snapshot_cnt, (void __user *)(cmd->value),
+			sizeof(uint32_t))) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+
+		if (vfe31_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB ||
+		vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG) {
+			if (snapshot_cnt != 1) {
+				pr_err("only support 1 inline snapshot\n");
+				rc = -EINVAL;
+				goto proc_general_done;
+			}
+			/* Configure primary channel for JPEG */
+			rc = vfe31_configure_pingpong_buffers(
+				VFE_MSG_JPEG_CAPTURE,
+				VFE_MSG_OUTPUT_PRIMARY);
+		} else {
+			/* Configure primary channel */
+			rc = vfe31_configure_pingpong_buffers(
+				VFE_MSG_CAPTURE,
+				VFE_MSG_OUTPUT_PRIMARY);
+		}
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers"
+				" for primary output", __func__);
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		/* Configure secondary channel */
+		rc = vfe31_configure_pingpong_buffers(VFE_MSG_CAPTURE,
+			VFE_MSG_OUTPUT_SECONDARY);
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers"
+				" for secondary output", __func__);
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		rc = vfe31_capture(pmctl, snapshot_cnt);
+		break;
+	case VFE_CMD_START_RECORDING:
+		pr_info("vfe31_proc_general: cmdID = %s\n",
+			vfe31_general_cmd[cmd->id]);
+		if (copy_from_user(&temp1, (void __user *)(cmd->value),
+				sizeof(uint32_t))) {
+			pr_err("%s Error copying inst_handle for recording\n",
+				__func__);
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		if (vfe31_ctrl->operation_mode ==
+			VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
+			vfe31_ctrl->outpath.out1.inst_handle = temp1;
+			rc = vfe31_configure_pingpong_buffers(
+				VFE_MSG_START_RECORDING,
+				VFE_MSG_OUTPUT_SECONDARY);
+		} else if (vfe31_ctrl->operation_mode ==
+			VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
+			vfe31_ctrl->outpath.out0.inst_handle = temp1;
+			rc = vfe31_configure_pingpong_buffers(
+				VFE_MSG_START_RECORDING,
+				VFE_MSG_OUTPUT_PRIMARY);
+		}
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers"
+				" for video", __func__);
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		rc = vfe31_start_recording(pmctl);
+		break;
+	case VFE_CMD_STOP_RECORDING:
+		pr_info("vfe31_proc_general: cmdID = %s\n",
+			vfe31_general_cmd[cmd->id]);
+		rc = vfe31_stop_recording(pmctl);
+		break;
+	case VFE_CMD_OPERATION_CFG:
+		if (cmd->length != V31_OPERATION_CFG_LEN) {
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(V31_OPERATION_CFG_LEN, GFP_ATOMIC);
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			V31_OPERATION_CFG_LEN)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		rc = vfe31_operation_config(cmdp);
+		break;
+
+	case VFE_CMD_STATS_AE_START:
+		rc = vfe_stats_aec_buf_init(NULL);
+		if (rc < 0) {
+			pr_err("%s: cannot config ping/pong address of AEC",
+				__func__);
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val |= AE_BG_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+		cmdp, (vfe31_cmd[cmd->id].length));
+		break;
+	case VFE_CMD_STATS_AF_START:
+		rc = vfe_stats_af_buf_init(NULL);
+		if (rc < 0) {
+			pr_err("%s: cannot config ping/pong address of AF",
+				__func__);
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val |= AF_BF_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+		cmdp, (vfe31_cmd[cmd->id].length));
+		break;
+	case VFE_CMD_STATS_AWB_START:
+		rc = vfe_stats_awb_buf_init(NULL);
+		if (rc < 0) {
+			pr_err("%s: cannot config ping/pong address of AWB",
+				__func__);
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val |= AWB_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp, (vfe31_cmd[cmd->id].length));
+		break;
+
+	case VFE_CMD_STATS_IHIST_START:
+		rc = vfe_stats_ihist_buf_init(NULL);
+		if (rc < 0) {
+			pr_err("%s: cannot config ping/pong address of IHIST",
+			__func__);
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val |= IHIST_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp, (vfe31_cmd[cmd->id].length));
+		break;
+
+	case VFE_CMD_STATS_RS_START:
+		rc = vfe_stats_rs_buf_init(NULL);
+		if (rc < 0) {
+			pr_err("%s: cannot config ping/pong address of RS",
+				__func__);
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp, (vfe31_cmd[cmd->id].length));
+		break;
+
+	case VFE_CMD_STATS_CS_START:
+		rc = vfe_stats_cs_buf_init(NULL);
+		if (rc < 0) {
+			pr_err("%s: cannot config ping/pong address of CS",
+				__func__);
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp, (vfe31_cmd[cmd->id].length));
+		break;
+
+	case VFE_CMD_MCE_UPDATE:
+	case VFE_CMD_MCE_CFG:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		/* Incrementing with 4 so as to point to the 2nd Register as
+		the 2nd register has the mce_enable bit */
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase +
+			V31_CHROMA_SUP_OFF + 4);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		new_val = *cmdp_local;
+		old_val &= MCE_EN_MASK;
+		new_val = new_val | old_val;
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + V31_CHROMA_SUP_OFF + 4,
+			&new_val, 4);
+		cmdp_local += 1;
+
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase +
+			V31_CHROMA_SUP_OFF + 8);
+		new_val = *cmdp_local;
+		old_val &= MCE_Q_K_MASK;
+		new_val = new_val | old_val;
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + V31_CHROMA_SUP_OFF + 8,
+			&new_val, 4);
+		cmdp_local += 1;
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp_local, (vfe31_cmd[cmd->id].length));
+		break;
+	case VFE_CMD_CHROMA_SUP_UPDATE:
+	case VFE_CMD_CHROMA_SUP_CFG:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		msm_camera_io_memcpy(vfe31_ctrl->vfebase + V31_CHROMA_SUP_OFF,
+			cmdp_local, 4);
+
+		cmdp_local += 1;
+		new_val = *cmdp_local;
+		/* Incrementing with 4 so as to point to the 2nd Register as
+		 * the 2nd register has the mce_enable bit
+		 */
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase +
+			V31_CHROMA_SUP_OFF + 4);
+		old_val &= ~MCE_EN_MASK;
+		new_val = new_val | old_val;
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + V31_CHROMA_SUP_OFF + 4,
+			&new_val, 4);
+		cmdp_local += 1;
+
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase +
+			V31_CHROMA_SUP_OFF + 8);
+		new_val = *cmdp_local;
+		old_val &= ~MCE_Q_K_MASK;
+		new_val = new_val | old_val;
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + V31_CHROMA_SUP_OFF + 8,
+			&new_val, 4);
+		break;
+
+	case VFE_CMD_MESH_ROLL_OFF_CFG:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value) , cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp_local, 16);
+		cmdp_local += 4;
+		vfe31_program_dmi_cfg(ROLLOFF_RAM);
+		/* for loop for extrcting init table. */
+		for (i = 0; i < (V31_MESH_ROLL_OFF_INIT_TABLE_SIZE * 2); i++) {
+			msm_camera_io_w(*cmdp_local ,
+			vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
+			cmdp_local++;
+		}
+		CDBG("done writing init table\n");
+		/* by default, always starts with offset 0. */
+		msm_camera_io_w(V31_MESH_ROLL_OFF_DELTA_TABLE_OFFSET,
+		vfe31_ctrl->vfebase + VFE_DMI_ADDR);
+		/* for loop for extracting delta table. */
+		for (i = 0; i < (V31_MESH_ROLL_OFF_DELTA_TABLE_SIZE * 2); i++) {
+			msm_camera_io_w(*cmdp_local,
+			vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
+			cmdp_local++;
+		}
+		vfe31_program_dmi_cfg(NO_MEM_SELECTED);
+		break;
+
+	case VFE_CMD_GET_MESH_ROLLOFF_TABLE:
+		temp1 = sizeof(uint32_t) * ((V31_MESH_ROLL_OFF_INIT_TABLE_SIZE *
+			2) + (V31_MESH_ROLL_OFF_DELTA_TABLE_SIZE * 2));
+		if (cmd->length != temp1) {
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		cmdp = kzalloc(temp1, GFP_KERNEL);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		vfe31_program_dmi_cfg(ROLLOFF_RAM);
+		CDBG("%s: Mesh Rolloff init Table\n", __func__);
+		for (i = 0; i < (V31_MESH_ROLL_OFF_INIT_TABLE_SIZE * 2); i++) {
+			*cmdp_local = msm_camera_io_r(
+					vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
+			CDBG("%s: %08x\n", __func__, *cmdp_local);
+			cmdp_local++;
+		}
+		msm_camera_io_w(V31_MESH_ROLL_OFF_DELTA_TABLE_OFFSET,
+			vfe31_ctrl->vfebase + VFE_DMI_ADDR);
+		CDBG("%s: Mesh Rolloff Delta Table\n", __func__);
+		for (i = 0; i < (V31_MESH_ROLL_OFF_DELTA_TABLE_SIZE * 2); i++) {
+			*cmdp_local = msm_camera_io_r(
+					vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
+			CDBG("%s: %08x\n", __func__, *cmdp_local);
+			cmdp_local++;
+		}
+		CDBG("done reading delta table\n");
+		vfe31_program_dmi_cfg(NO_MEM_SELECTED);
+		if (copy_to_user((void __user *)(cmd->value), cmdp,
+			temp1)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		break;
+	case VFE_CMD_LA_CFG:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp_local, (vfe31_cmd[cmd->id].length));
+
+		cmdp_local += 1;
+		vfe31_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK0, cmdp_local);
+		break;
+
+	case VFE_CMD_LA_UPDATE:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+
+		cmdp_local = cmdp + 1;
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + V31_LA_OFF);
+		if (old_val != 0x0)
+			vfe31_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK0,
+				cmdp_local);
+		else
+			vfe31_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK1,
+				cmdp_local);
+		vfe31_ctrl->update_la = true;
+		break;
+
+	case VFE_CMD_GET_LA_TABLE:
+		temp1 = sizeof(uint32_t) * VFE31_LA_TABLE_LENGTH / 2;
+		if (cmd->length != temp1) {
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		cmdp = kzalloc(temp1, GFP_KERNEL);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		if (msm_camera_io_r(vfe31_ctrl->vfebase + V31_LA_OFF))
+			vfe31_program_dmi_cfg(LUMA_ADAPT_LUT_RAM_BANK1);
+		else
+			vfe31_program_dmi_cfg(LUMA_ADAPT_LUT_RAM_BANK0);
+		for (i = 0 ; i < (VFE31_LA_TABLE_LENGTH / 2) ; i++) {
+			*cmdp_local = msm_camera_io_r(
+					vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
+			*cmdp_local |= (msm_camera_io_r(vfe31_ctrl->vfebase +
+				VFE_DMI_DATA_LO)) << 16;
+			cmdp_local++;
+		}
+		vfe31_program_dmi_cfg(NO_MEM_SELECTED);
+		if (copy_to_user((void __user *)(cmd->value), cmdp,
+			temp1)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		break;
+	case VFE_CMD_SK_ENHAN_CFG:
+	case VFE_CMD_SK_ENHAN_UPDATE:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_camera_io_memcpy(vfe31_ctrl->vfebase + V31_SCE_OFF,
+			cmdp, V31_SCE_LEN);
+		break;
+
+	case VFE_CMD_LIVESHOT:
+		if (copy_from_user(&temp1, (void __user *)(cmd->value),
+				sizeof(uint32_t))) {
+			pr_err("%s Error copying inst_handle for liveshot ",
+				__func__);
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		vfe31_ctrl->outpath.out0.inst_handle = temp1;
+		/* Configure primary channel */
+		rc = vfe31_configure_pingpong_buffers(VFE_MSG_CAPTURE,
+			VFE_MSG_OUTPUT_PRIMARY);
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers"
+				" for primary output", __func__);
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		vfe31_start_liveshot(pmctl);
+		break;
+
+	case VFE_CMD_DEMOSAICV3:
+		if (cmd->length != V31_DEMOSAICV3_LEN) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		new_val = *cmdp_local;
+
+		old_val = msm_camera_io_r(
+				vfe31_ctrl->vfebase + V31_DEMOSAICV3_OFF);
+		old_val &= DEMOSAIC_MASK;
+		new_val = new_val | old_val;
+		*cmdp_local = new_val;
+
+		msm_camera_io_memcpy(vfe31_ctrl->vfebase + V31_DEMOSAICV3_OFF,
+			cmdp_local, V31_DEMOSAICV3_LEN);
+		break;
+
+	case VFE_CMD_DEMOSAICV3_UPDATE:
+		if (cmd->length !=
+			V31_DEMOSAICV3_LEN * V31_DEMOSAICV3_UP_REG_CNT) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		new_val = *cmdp_local;
+
+		old_val = msm_camera_io_r(
+				vfe31_ctrl->vfebase + V31_DEMOSAICV3_OFF);
+		old_val &= DEMOSAIC_MASK;
+		new_val = new_val | old_val;
+		*cmdp_local = new_val;
+
+		msm_camera_io_memcpy(vfe31_ctrl->vfebase + V31_DEMOSAICV3_OFF,
+			cmdp_local, V31_DEMOSAICV3_LEN);
+
+		break;
+
+	case VFE_CMD_DEMOSAICV3_ABCC_CFG:
+		rc = -EFAULT;
+		break;
+
+	case VFE_CMD_DEMOSAICV3_ABF_UPDATE:/* 116 ABF update  */
+	case VFE_CMD_DEMOSAICV3_ABF_CFG: /* 108 ABF config  */
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		new_val = *cmdp_local;
+
+		old_val = msm_camera_io_r(
+				vfe31_ctrl->vfebase + V31_DEMOSAICV3_OFF);
+		old_val &= ABF_MASK;
+		new_val = new_val | old_val;
+		*cmdp_local = new_val;
+
+		msm_camera_io_memcpy(vfe31_ctrl->vfebase + V31_DEMOSAICV3_OFF,
+		    cmdp_local, 4);
+
+		cmdp_local += 1;
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp_local, (vfe31_cmd[cmd->id].length));
+		break;
+
+	case VFE_CMD_DEMOSAICV3_DBCC_CFG:
+	case VFE_CMD_DEMOSAICV3_DBCC_UPDATE:
+		return -EINVAL;
+
+	case VFE_CMD_DEMOSAICV3_DBPC_CFG:
+	case VFE_CMD_DEMOSAICV3_DBPC_UPDATE:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		new_val = *cmdp_local;
+
+		old_val = msm_camera_io_r(
+				vfe31_ctrl->vfebase + V31_DEMOSAICV3_OFF);
+		old_val &= BPC_MASK;
+
+		new_val = new_val | old_val;
+		*cmdp_local = new_val;
+		msm_camera_io_memcpy(vfe31_ctrl->vfebase + V31_DEMOSAICV3_OFF,
+					cmdp_local, V31_DEMOSAICV3_LEN);
+		cmdp_local += 1;
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + V31_DEMOSAICV3_DBPC_CFG_OFF,
+			cmdp_local, V31_DEMOSAICV3_DBPC_LEN);
+		break;
+
+	case VFE_CMD_RGB_G_CFG:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_camera_io_memcpy(vfe31_ctrl->vfebase + V31_RGB_G_OFF,
+			cmdp, 4);
+		cmdp += 1;
+
+		vfe31_write_gamma_cfg(RGBLUT_RAM_CH0_BANK0, cmdp);
+		vfe31_write_gamma_cfg(RGBLUT_RAM_CH1_BANK0, cmdp);
+		vfe31_write_gamma_cfg(RGBLUT_RAM_CH2_BANK0, cmdp);
+		cmdp -= 1;
+		break;
+
+	case VFE_CMD_RGB_G_UPDATE:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp, (void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + V31_RGB_G_OFF);
+		cmdp += 1;
+		if (old_val != 0x0) {
+			vfe31_write_gamma_cfg(RGBLUT_RAM_CH0_BANK0, cmdp);
+			vfe31_write_gamma_cfg(RGBLUT_RAM_CH1_BANK0, cmdp);
+			vfe31_write_gamma_cfg(RGBLUT_RAM_CH2_BANK0, cmdp);
+		} else {
+			vfe31_write_gamma_cfg(RGBLUT_RAM_CH0_BANK1, cmdp);
+			vfe31_write_gamma_cfg(RGBLUT_RAM_CH1_BANK1, cmdp);
+			vfe31_write_gamma_cfg(RGBLUT_RAM_CH2_BANK1, cmdp);
+		}
+		vfe31_ctrl->update_gamma = TRUE;
+		cmdp -= 1;
+		break;
+
+	case VFE_CMD_GET_RGB_G_TABLE:
+		temp1 = sizeof(uint32_t) * VFE31_GAMMA_NUM_ENTRIES * 3;
+		if (cmd->length != temp1) {
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		cmdp = kzalloc(temp1, GFP_KERNEL);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + V31_RGB_G_OFF);
+		temp2 = old_val ? RGBLUT_RAM_CH0_BANK1 :
+			RGBLUT_RAM_CH0_BANK0;
+		for (i = 0; i < 3; i++) {
+			vfe31_read_gamma_cfg(temp2,
+				cmdp_local + (VFE31_GAMMA_NUM_ENTRIES * i));
+			temp2 += 2;
+		}
+		if (copy_to_user((void __user *)(cmd->value), cmdp,
+			temp1)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		break;
+
+	case VFE_CMD_STATS_AWB_STOP:
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~AWB_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		break;
+	case VFE_CMD_STATS_AE_STOP:
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~AE_BG_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		break;
+	case VFE_CMD_STATS_AF_STOP:
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~AF_BF_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		rc = vfe31_stats_flush_enqueue(MSM_STATS_TYPE_AF);
+		if (rc < 0) {
+			pr_err("%s: dq stats buf err = %d",
+				   __func__, rc);
+			return -EINVAL;
+		}
+		break;
+
+	case VFE_CMD_STATS_IHIST_STOP:
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~IHIST_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		break;
+
+	case VFE_CMD_STATS_RS_STOP:
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~RS_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		break;
+
+	case VFE_CMD_STATS_CS_STOP:
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~CS_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		break;
+
+	case VFE_CMD_STOP:
+		pr_info("vfe31_proc_general: cmdID = %s\n",
+			vfe31_general_cmd[cmd->id]);
+		vfe31_stop();
+		break;
+
+	case VFE_CMD_SYNC_TIMER_SETTING:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp, (void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		vfe31_sync_timer_start(cmdp);
+		break;
+
+	case VFE_CMD_MODULE_CFG:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		*cmdp &= ~STATS_ENABLE_MASK;
+		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= STATS_ENABLE_MASK;
+		*cmdp |= old_val;
+
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp, (vfe31_cmd[cmd->id].length));
+		break;
+
+	case VFE_CMD_ZSL:
+		rc = vfe31_configure_pingpong_buffers(VFE_MSG_START,
+			VFE_MSG_OUTPUT_PRIMARY);
+		if (rc < 0)
+			goto proc_general_done;
+		rc = vfe31_configure_pingpong_buffers(VFE_MSG_START,
+			VFE_MSG_OUTPUT_SECONDARY);
+		if (rc < 0)
+			goto proc_general_done;
+
+		rc = vfe31_zsl(pmctl);
+		break;
+
+	case VFE_CMD_ASF_CFG:
+	case VFE_CMD_ASF_UPDATE:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp, (void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp, (vfe31_cmd[cmd->id].length));
+		cmdp_local = cmdp + V31_ASF_LEN/4;
+		break;
+
+	case VFE_CMD_GET_HW_VERSION:
+		if (cmd->length != V31_GET_HW_VERSION_LEN) {
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(V31_GET_HW_VERSION_LEN, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		*cmdp = msm_camera_io_r(
+				vfe31_ctrl->vfebase+V31_GET_HW_VERSION_OFF);
+		if (copy_to_user((void __user *)(cmd->value), cmdp,
+			V31_GET_HW_VERSION_LEN)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		break;
+	case VFE_CMD_GET_REG_DUMP:
+		temp1 = sizeof(uint32_t) * vfe31_ctrl->register_total;
+		if (cmd->length != temp1) {
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(temp1, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		msm_camera_io_dump(
+			vfe31_ctrl->vfebase, vfe31_ctrl->register_total*4);
+		CDBG("%s: %p %p %d\n", __func__, (void *)cmdp,
+			vfe31_ctrl->vfebase, temp1);
+		memcpy_fromio((void *)cmdp, vfe31_ctrl->vfebase, temp1);
+		if (copy_to_user((void __user *)(cmd->value), cmdp, temp1)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		break;
+	case VFE_CMD_FRAME_SKIP_CFG:
+		if (cmd->length != vfe31_cmd[cmd->id].length)
+			return -EINVAL;
+
+		cmdp = kmalloc(vfe31_cmd[cmd->id].length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+
+		if (copy_from_user(cmdp, (void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp, (vfe31_cmd[cmd->id].length));
+		vfe31_ctrl->frame_skip_cnt = ((uint32_t)
+			*cmdp & VFE_FRAME_SKIP_PERIOD_MASK) + 1;
+		vfe31_ctrl->frame_skip_pattern = (uint32_t)(*(cmdp + 2));
+		break;
+	default:
+		if (cmd->length != vfe31_cmd[cmd->id].length)
+			return -EINVAL;
+
+		cmdp = kmalloc(vfe31_cmd[cmd->id].length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+
+		if (copy_from_user(cmdp, (void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_camera_io_memcpy(
+			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
+			cmdp, (vfe31_cmd[cmd->id].length));
+		break;
+
+	}
+
+proc_general_done:
+	kfree(cmdp);
+
+	return rc;
+}
+
+static inline void vfe31_read_irq_status(struct vfe31_irq_status *out)
+{
+	uint32_t *temp;
+	memset(out, 0, sizeof(struct vfe31_irq_status));
+	temp = (uint32_t *)(vfe31_ctrl->vfebase + VFE_IRQ_STATUS_0);
+	out->vfeIrqStatus0 = msm_camera_io_r(temp);
+
+	temp = (uint32_t *)(vfe31_ctrl->vfebase + VFE_IRQ_STATUS_1);
+	out->vfeIrqStatus1 = msm_camera_io_r(temp);
+
+	temp = (uint32_t *)(vfe31_ctrl->vfebase + VFE_CAMIF_STATUS);
+	out->camifStatus = msm_camera_io_r(temp);
+	CDBG("camifStatus  = 0x%x\n", out->camifStatus);
+
+	/* clear the pending interrupt of the same kind.*/
+	msm_camera_io_w(out->vfeIrqStatus0,
+		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_0);
+	msm_camera_io_w(out->vfeIrqStatus1,
+		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_1);
+
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_IRQ_CMD);
+
+}
+
+static void vfe31_process_reg_update_irq(void)
+{
+	unsigned long flags;
+
+	if (vfe31_ctrl->recording_state == VFE_STATE_START_REQUESTED) {
+		if (vfe31_ctrl->operation_mode ==
+			VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+		} else if (vfe31_ctrl->operation_mode ==
+			VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
+		}
+		vfe31_ctrl->recording_state = VFE_STATE_STARTED;
+		msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+		CDBG("start video triggered .\n");
+	} else if (vfe31_ctrl->recording_state ==
+		VFE_STATE_STOP_REQUESTED) {
+		if (vfe31_ctrl->operation_mode ==
+			VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
+			msm_camera_io_w(0, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+			msm_camera_io_w(0, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+		} else if (vfe31_ctrl->operation_mode ==
+			VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
+			msm_camera_io_w(0, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
+			msm_camera_io_w(0, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
+		}
+		CDBG("stop video triggered .\n");
+	}
+
+	if (vfe31_ctrl->start_ack_pending == TRUE) {
+		vfe31_send_isp_msg(vfe31_ctrl, MSG_ID_START_ACK);
+		vfe31_ctrl->start_ack_pending = FALSE;
+	} else {
+		if (vfe31_ctrl->recording_state ==
+			VFE_STATE_STOP_REQUESTED) {
+			vfe31_ctrl->recording_state = VFE_STATE_STOPPED;
+			/* request a reg update and send STOP_REC_ACK
+			 * when we process the next reg update irq.
+			 */
+			msm_camera_io_w_mb(1,
+			vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+		} else if (vfe31_ctrl->recording_state ==
+			VFE_STATE_STOPPED) {
+			vfe31_send_isp_msg(vfe31_ctrl, MSG_ID_STOP_REC_ACK);
+			vfe31_ctrl->recording_state = VFE_STATE_IDLE;
+		}
+		spin_lock_irqsave(&vfe31_ctrl->update_ack_lock, flags);
+		if (vfe31_ctrl->update_ack_pending == TRUE) {
+			vfe31_ctrl->update_ack_pending = FALSE;
+			spin_unlock_irqrestore(
+				&vfe31_ctrl->update_ack_lock, flags);
+			vfe31_send_isp_msg(vfe31_ctrl, MSG_ID_UPDATE_ACK);
+		} else {
+			spin_unlock_irqrestore(
+				&vfe31_ctrl->update_ack_lock, flags);
+		}
+	}
+
+	if (vfe31_ctrl->liveshot_state == VFE_STATE_START_REQUESTED) {
+		pr_info("%s enabling liveshot output\n", __func__);
+		if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_PRIMARY) {
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+			msm_camera_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+			vfe31_ctrl->liveshot_state = VFE_STATE_STARTED;
+		}
+	}
+
+	if (vfe31_ctrl->liveshot_state == VFE_STATE_STARTED) {
+		vfe31_ctrl->vfe_capture_count--;
+		if (!vfe31_ctrl->vfe_capture_count)
+			vfe31_ctrl->liveshot_state = VFE_STATE_STOP_REQUESTED;
+		msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	} else if (vfe31_ctrl->liveshot_state == VFE_STATE_STOP_REQUESTED) {
+		CDBG("%s: disabling liveshot output\n", __func__);
+		if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_PRIMARY) {
+			msm_camera_io_w(0, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+			msm_camera_io_w(0, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+			vfe31_ctrl->liveshot_state = VFE_STATE_STOPPED;
+			msm_camera_io_w_mb(1, vfe31_ctrl->vfebase +
+				VFE_REG_UPDATE_CMD);
+		}
+	} else if (vfe31_ctrl->liveshot_state == VFE_STATE_STOPPED) {
+		vfe31_ctrl->liveshot_state = VFE_STATE_IDLE;
+	}
+
+	if ((vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN) ||
+		(vfe31_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB) ||
+		(vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG) ||
+		(vfe31_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB)) {
+		/* in snapshot mode */
+		/* later we need to add check for live snapshot mode. */
+		if (vfe31_ctrl->frame_skip_pattern & (0x1 <<
+			(vfe31_ctrl->snapshot_frame_cnt %
+				vfe31_ctrl->frame_skip_cnt))) {
+			/* if last frame to be captured: */
+			if (vfe31_ctrl->vfe_capture_count == 0) {
+				/* stop the bus output:write master enable = 0*/
+				if (vfe31_ctrl->outpath.output_mode &
+					VFE31_OUTPUT_MODE_PRIMARY) {
+					msm_camera_io_w(0, vfe31_ctrl->vfebase +
+						vfe31_AXI_WM_CFG[vfe31_ctrl->
+						outpath.out0.ch0]);
+					msm_camera_io_w(0, vfe31_ctrl->vfebase +
+						vfe31_AXI_WM_CFG[vfe31_ctrl->
+						outpath.out0.ch1]);
+				}
+				if (vfe31_ctrl->outpath.output_mode &
+					VFE31_OUTPUT_MODE_SECONDARY) {
+					msm_camera_io_w(0, vfe31_ctrl->vfebase +
+						vfe31_AXI_WM_CFG[vfe31_ctrl->
+						outpath.out1.ch0]);
+					msm_camera_io_w(0, vfe31_ctrl->vfebase +
+						vfe31_AXI_WM_CFG[vfe31_ctrl->
+						outpath.out1.ch1]);
+				}
+				msm_camera_io_w_mb
+				(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
+				vfe31_ctrl->vfebase + VFE_CAMIF_COMMAND);
+				vfe31_ctrl->snapshot_frame_cnt = -1;
+				vfe31_ctrl->frame_skip_cnt = 31;
+				vfe31_ctrl->frame_skip_pattern = 0xffffffff;
+			} /*if snapshot count is 0*/
+		} /*if frame is not being dropped*/
+		/* then do reg_update. */
+		msm_camera_io_w(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	} /* if snapshot mode. */
+}
+
+static void vfe31_set_default_reg_values(void)
+{
+	msm_camera_io_w(0x800080, vfe31_ctrl->vfebase + VFE_DEMUX_GAIN_0);
+	msm_camera_io_w(0x800080, vfe31_ctrl->vfebase + VFE_DEMUX_GAIN_1);
+	/* What value should we program CGC_OVERRIDE to? */
+	msm_camera_io_w(0xFFFFF, vfe31_ctrl->vfebase + VFE_CGC_OVERRIDE);
+
+	/* default frame drop period and pattern */
+	msm_camera_io_w(0x1f, vfe31_ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_CFG);
+	msm_camera_io_w(0x1f, vfe31_ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_CFG);
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe31_ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_PATTERN);
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe31_ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_PATTERN);
+	msm_camera_io_w(0x1f, vfe31_ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y);
+	msm_camera_io_w(0x1f, vfe31_ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR);
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe31_ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_PATTERN);
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe31_ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR_PATTERN);
+	msm_camera_io_w(0, vfe31_ctrl->vfebase + VFE_CLAMP_MIN);
+	msm_camera_io_w(0xFFFFFF, vfe31_ctrl->vfebase + VFE_CLAMP_MAX);
+
+	/* stats UB config */
+	msm_camera_io_w(0x3980007,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_AEC_UB_CFG);
+	msm_camera_io_w(0x3A00007,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_AF_UB_CFG);
+	msm_camera_io_w(0x3A8000F,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_AWB_UB_CFG);
+	msm_camera_io_w(0x3B80007,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_RS_UB_CFG);
+	msm_camera_io_w(0x3C0001F,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_CS_UB_CFG);
+	msm_camera_io_w(0x3E0001F,
+		vfe31_ctrl->vfebase + VFE_BUS_STATS_HIST_UB_CFG);
+}
+
+static void vfe31_process_reset_irq(void)
+{
+	unsigned long flags;
+
+	atomic_set(&vfe31_ctrl->vstate, 0);
+
+	spin_lock_irqsave(&vfe31_ctrl->stop_flag_lock, flags);
+	if (vfe31_ctrl->stop_ack_pending) {
+		vfe31_ctrl->stop_ack_pending = FALSE;
+		spin_unlock_irqrestore(&vfe31_ctrl->stop_flag_lock, flags);
+		vfe31_send_isp_msg(vfe31_ctrl, MSG_ID_STOP_ACK);
+	} else {
+		spin_unlock_irqrestore(&vfe31_ctrl->stop_flag_lock, flags);
+		/* this is from reset command. */
+		vfe31_set_default_reg_values();
+
+		/* reload all write masters. (frame & line)*/
+		msm_camera_io_w(0x7FFF, vfe31_ctrl->vfebase + VFE_BUS_CMD);
+		vfe31_send_isp_msg(vfe31_ctrl, MSG_ID_RESET_ACK);
+	}
+}
+
+static void vfe31_process_camif_sof_irq(void)
+{
+	if (vfe31_ctrl->operation_mode ==
+		VFE_OUTPUTS_RAW) {
+		if (vfe31_ctrl->start_ack_pending) {
+			vfe31_send_isp_msg(vfe31_ctrl, MSG_ID_START_ACK);
+			vfe31_ctrl->start_ack_pending = FALSE;
+		}
+		vfe31_ctrl->vfe_capture_count--;
+		/* if last frame to be captured: */
+		if (vfe31_ctrl->vfe_capture_count == 0) {
+			/* Ensure the write order while writing
+			 to the command register using the barrier */
+			msm_camera_io_w_mb(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
+				vfe31_ctrl->vfebase + VFE_CAMIF_COMMAND);
+		}
+	} /* if raw snapshot mode. */
+	if ((vfe31_ctrl->hfr_mode != HFR_MODE_OFF) &&
+		(vfe31_ctrl->operation_mode == VFE_MODE_OF_OPERATION_VIDEO) &&
+		(vfe31_ctrl->vfeFrameId % vfe31_ctrl->hfr_mode != 0)) {
+		vfe31_ctrl->vfeFrameId++;
+		CDBG("Skip the SOF notification when HFR enabled\n");
+		return;
+	}
+	vfe31_ctrl->vfeFrameId++;
+	vfe31_send_isp_msg(vfe31_ctrl, MSG_ID_SOF_ACK);
+	CDBG("camif_sof_irq, frameId = %d\n", vfe31_ctrl->vfeFrameId);
+
+	if (vfe31_ctrl->sync_timer_state) {
+		if (vfe31_ctrl->sync_timer_repeat_count == 0)
+			vfe31_sync_timer_stop();
+		else
+			vfe31_ctrl->sync_timer_repeat_count--;
+	}
+	if ((vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN) ||
+		(vfe31_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB) ||
+		(vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG) ||
+		(vfe31_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB)) {
+		if (vfe31_ctrl->frame_skip_pattern & (0x1 <<
+			(vfe31_ctrl->snapshot_frame_cnt %
+				vfe31_ctrl->frame_skip_cnt))) {
+			vfe31_ctrl->vfe_capture_count--;
+		}
+		vfe31_ctrl->snapshot_frame_cnt++;
+	}
+}
+
+static void vfe31_process_error_irq(uint32_t errStatus)
+{
+	uint32_t reg_value, read_val;
+
+	if (errStatus & VFE31_IMASK_CAMIF_ERROR) {
+		pr_err("vfe31_irq: camif errors\n");
+		reg_value = msm_camera_io_r(
+				vfe31_ctrl->vfebase + VFE_CAMIF_STATUS);
+		pr_err("camifStatus  = 0x%x\n", reg_value);
+		vfe31_send_isp_msg(vfe31_ctrl, MSG_ID_CAMIF_ERROR);
+	}
+
+	if (errStatus & VFE31_IMASK_STATS_CS_OVWR)
+		pr_err("vfe31_irq: stats cs overwrite\n");
+
+	if (errStatus & VFE31_IMASK_STATS_IHIST_OVWR)
+		pr_err("vfe31_irq: stats ihist overwrite\n");
+
+	if (errStatus & VFE31_IMASK_REALIGN_BUF_Y_OVFL)
+		pr_err("vfe31_irq: realign bug Y overflow\n");
+
+	if (errStatus & VFE31_IMASK_REALIGN_BUF_CB_OVFL)
+		pr_err("vfe31_irq: realign bug CB overflow\n");
+
+	if (errStatus & VFE31_IMASK_REALIGN_BUF_CR_OVFL)
+		pr_err("vfe31_irq: realign bug CR overflow\n");
+
+	if (errStatus & VFE31_IMASK_VIOLATION)
+		pr_err("vfe31_irq: violation interrupt\n");
+
+	if (errStatus & VFE31_IMASK_IMG_MAST_0_BUS_OVFL)
+		pr_err("vfe31_irq: image master 0 bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_IMG_MAST_1_BUS_OVFL)
+		pr_err("vfe31_irq: image master 1 bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_IMG_MAST_2_BUS_OVFL)
+		pr_err("vfe31_irq: image master 2 bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_IMG_MAST_3_BUS_OVFL)
+		pr_err("vfe31_irq: image master 3 bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_IMG_MAST_4_BUS_OVFL)
+		pr_err("vfe31_irq: image master 4 bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_IMG_MAST_5_BUS_OVFL)
+		pr_err("vfe31_irq: image master 5 bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_IMG_MAST_6_BUS_OVFL)
+		pr_err("vfe31_irq: image master 6 bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_STATS_AE_BG_BUS_OVFL)
+		pr_err("vfe31_irq: ae/bg stats bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_STATS_AF_BF_BUS_OVFL)
+		pr_err("vfe31_irq: af/bf stats bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_STATS_AWB_BUS_OVFL)
+		pr_err("vfe31_irq: awb stats bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_STATS_RS_BUS_OVFL)
+		pr_err("vfe31_irq: rs stats bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_STATS_CS_BUS_OVFL)
+		pr_err("vfe31_irq: cs stats bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_STATS_IHIST_BUS_OVFL)
+		pr_err("vfe31_irq: ihist stats bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_STATS_SKIN_BHIST_BUS_OVFL)
+		pr_err("vfe31_irq: skin/bhist stats bus overflow\n");
+
+	if (errStatus & VFE31_IMASK_AXI_ERROR) {
+		pr_err("vfe31_irq: axi error\n");
+		/* read status too when overflow happens.*/
+		read_val = msm_camera_io_r(vfe31_ctrl->vfebase +
+			VFE_BUS_PING_PONG_STATUS);
+		pr_debug("VFE_BUS_PING_PONG_STATUS = 0x%x\n", read_val);
+		read_val = msm_camera_io_r(vfe31_ctrl->vfebase +
+			VFE_BUS_OPERATION_STATUS);
+		pr_debug("VFE_BUS_OPERATION_STATUS = 0x%x\n", read_val);
+		read_val = msm_camera_io_r(vfe31_ctrl->vfebase +
+			VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_0);
+		pr_debug("VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_0 = 0x%x\n",
+			read_val);
+		read_val = msm_camera_io_r(vfe31_ctrl->vfebase +
+			VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_1);
+		pr_debug("VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_1 = 0x%x\n",
+			read_val);
+		read_val = msm_camera_io_r(vfe31_ctrl->vfebase +
+			VFE_AXI_STATUS);
+		pr_debug("VFE_AXI_STATUS = 0x%x\n", read_val);
+	}
+}
+static void vfe_send_outmsg(struct v4l2_subdev *sd, uint8_t msgid,
+	uint32_t ch0_paddr, uint32_t ch1_paddr,
+	uint32_t ch2_paddr, uint32_t inst_handle)
+{
+	struct isp_msg_output msg;
+
+	msg.output_id		= msgid;
+	msg.buf.inst_handle	= inst_handle;
+	msg.buf.ch_paddr[0]	= ch0_paddr;
+	msg.buf.ch_paddr[1]	= ch1_paddr;
+	msg.buf.ch_paddr[2]	= ch2_paddr;
+	msg.frameCounter	= vfe31_ctrl->vfeFrameId;
+
+	v4l2_subdev_notify(&vfe31_ctrl->subdev,
+		NOTIFY_VFE_MSG_OUT, &msg);
+	return;
+}
+
+static void vfe31_process_output_path_irq_0(void)
+{
+	uint32_t ping_pong;
+	uint32_t ch0_paddr, ch1_paddr, ch2_paddr;
+	uint8_t out_bool = 0;
+	struct msm_free_buf *free_buf = NULL;
+
+	free_buf = vfe31_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
+		VFE_MSG_OUTPUT_PRIMARY);
+
+	/* we render frames in the following conditions:
+	 * 1. Continuous mode and the free buffer is avaialable.
+	 * 2. In snapshot shot mode, free buffer is not always available.
+	 * when pending snapshot count is <=1,  then no need to use
+	 * free buffer.
+	 */
+	out_bool = ((vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN ||
+		vfe31_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB ||
+		vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG ||
+		vfe31_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB ||
+		vfe31_ctrl->operation_mode == VFE_OUTPUTS_RAW ||
+		vfe31_ctrl->liveshot_state == VFE_STATE_STARTED ||
+		vfe31_ctrl->liveshot_state == VFE_STATE_STOP_REQUESTED ||
+		vfe31_ctrl->liveshot_state == VFE_STATE_STOPPED) &&
+		(vfe31_ctrl->vfe_capture_count <= 1)) || free_buf;
+
+	if (out_bool) {
+		ping_pong = msm_camera_io_r(vfe31_ctrl->vfebase +
+			VFE_BUS_PING_PONG_STATUS);
+
+		/* Channel 0*/
+		ch0_paddr = vfe31_get_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out0.ch0);
+		/* Channel 1*/
+		ch1_paddr = vfe31_get_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out0.ch1);
+		/* Channel 2*/
+		ch2_paddr = vfe31_get_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out0.ch2);
+
+		CDBG("output path 0, ch0 = 0x%x, ch1 = 0x%x, ch2 = 0x%x\n",
+			ch0_paddr, ch1_paddr, ch2_paddr);
+		if (free_buf) {
+			/* Y channel */
+			vfe31_put_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out0.ch0,
+			free_buf->ch_paddr[0]);
+			/* Chroma channel */
+			vfe31_put_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out0.ch1,
+			free_buf->ch_paddr[1]);
+			if (free_buf->num_planes > 2)
+				vfe31_put_ch_addr(ping_pong,
+					vfe31_ctrl->outpath.out0.ch2,
+					free_buf->ch_paddr[2]);
+		}
+		if (vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_THUMB_AND_MAIN ||
+			vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_MAIN_AND_THUMB ||
+			vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_THUMB_AND_JPEG ||
+			vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_JPEG_AND_THUMB ||
+			vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_RAW ||
+			vfe31_ctrl->liveshot_state == VFE_STATE_STOPPED)
+			vfe31_ctrl->outpath.out0.capture_cnt--;
+
+		vfe_send_outmsg(&vfe31_ctrl->subdev,
+			MSG_ID_OUTPUT_PRIMARY, ch0_paddr,
+			ch1_paddr, ch2_paddr,
+			vfe31_ctrl->outpath.out0.inst_handle);
+
+		if (vfe31_ctrl->liveshot_state == VFE_STATE_STOPPED)
+			vfe31_ctrl->liveshot_state = VFE_STATE_IDLE;
+
+	} else {
+		vfe31_ctrl->outpath.out0.frame_drop_cnt++;
+		CDBG("path_irq_0 - no free buffer!\n");
+	}
+}
+
+static void vfe31_process_output_path_irq_1(void)
+{
+	uint32_t ping_pong;
+	uint32_t ch0_paddr, ch1_paddr, ch2_paddr;
+	/* this must be snapshot main image output. */
+	uint8_t out_bool = 0;
+	struct msm_free_buf *free_buf = NULL;
+
+	free_buf = vfe31_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
+		VFE_MSG_OUTPUT_SECONDARY);
+	out_bool = ((vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_THUMB_AND_MAIN ||
+			vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_MAIN_AND_THUMB ||
+			vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_RAW ||
+			vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_JPEG_AND_THUMB) &&
+			(vfe31_ctrl->vfe_capture_count <= 1)) || free_buf;
+
+	if (out_bool) {
+		ping_pong = msm_camera_io_r(vfe31_ctrl->vfebase +
+			VFE_BUS_PING_PONG_STATUS);
+
+		/* Y channel */
+		ch0_paddr = vfe31_get_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out1.ch0);
+		/* Chroma channel */
+		ch1_paddr = vfe31_get_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out1.ch1);
+		ch2_paddr = vfe31_get_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out1.ch2);
+
+		pr_debug("%s ch0 = 0x%x, ch1 = 0x%x, ch2 = 0x%x\n",
+			__func__, ch0_paddr, ch1_paddr, ch2_paddr);
+		if (free_buf) {
+			/* Y channel */
+			vfe31_put_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out1.ch0,
+			free_buf->ch_paddr[0]);
+			/* Chroma channel */
+			vfe31_put_ch_addr(ping_pong,
+			vfe31_ctrl->outpath.out1.ch1,
+			free_buf->ch_paddr[1]);
+			if (free_buf->num_planes > 2)
+				vfe31_put_ch_addr(ping_pong,
+					vfe31_ctrl->outpath.out1.ch2,
+					free_buf->ch_paddr[2]);
+		}
+		if (vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_THUMB_AND_MAIN ||
+			vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_MAIN_AND_THUMB ||
+			vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_RAW ||
+			vfe31_ctrl->operation_mode ==
+				VFE_OUTPUTS_JPEG_AND_THUMB)
+			vfe31_ctrl->outpath.out1.capture_cnt--;
+
+		vfe_send_outmsg(&vfe31_ctrl->subdev,
+			MSG_ID_OUTPUT_SECONDARY, ch0_paddr,
+			ch1_paddr, ch2_paddr,
+			vfe31_ctrl->outpath.out1.inst_handle);
+	} else {
+		vfe31_ctrl->outpath.out1.frame_drop_cnt++;
+		CDBG("path_irq_1 - no free buffer!\n");
+	}
+}
+
+static uint32_t  vfe31_process_stats_irq_common(uint32_t statsNum,
+	uint32_t newAddr)
+{
+
+	uint32_t pingpongStatus;
+	uint32_t returnAddr;
+	uint32_t pingpongAddr;
+
+	/* must be 0=ping, 1=pong */
+	pingpongStatus =
+		((msm_camera_io_r(vfe31_ctrl->vfebase +
+		VFE_BUS_PING_PONG_STATUS))
+		& ((uint32_t)(1<<(statsNum + 7)))) >> (statsNum + 7);
+	/* stats bits starts at 7 */
+	CDBG("statsNum %d, pingpongStatus %d\n", statsNum, pingpongStatus);
+	pingpongAddr =
+		((uint32_t)(vfe31_ctrl->vfebase +
+		VFE_BUS_STATS_PING_PONG_BASE)) +
+		(3*statsNum)*4 + (1-pingpongStatus)*4;
+	returnAddr = msm_camera_io_r((uint32_t *)pingpongAddr);
+	msm_camera_io_w(newAddr, (uint32_t *)pingpongAddr);
+	return returnAddr;
+}
+
+static void
+vfe_send_stats_msg(uint32_t bufAddress, uint32_t statsNum)
+{
+	int rc = 0;
+	void *vaddr = NULL;
+	/* fill message with right content. */
+	/* @todo This is causing issues, need further investigate */
+	/* spin_lock_irqsave(&ctrl->state_lock, flags); */
+	struct isp_msg_stats msgStats;
+	msgStats.frameCounter = vfe31_ctrl->vfeFrameId;
+	msgStats.buffer = bufAddress;
+
+	switch (statsNum) {
+	case STATS_AE_NUM:{
+		msgStats.id = MSG_ID_STATS_AEC;
+		rc = vfe31_ctrl->stats_ops.dispatch(
+				vfe31_ctrl->stats_ops.stats_ctrl,
+				MSM_STATS_TYPE_AEC,	bufAddress,
+				&msgStats.buf_idx, &vaddr, &msgStats.fd,
+				vfe31_ctrl->stats_ops.client);
+		}
+		break;
+	case STATS_AF_NUM:{
+		msgStats.id = MSG_ID_STATS_AF;
+		rc = vfe31_ctrl->stats_ops.dispatch(
+				vfe31_ctrl->stats_ops.stats_ctrl,
+				MSM_STATS_TYPE_AF, bufAddress,
+				&msgStats.buf_idx, &vaddr, &msgStats.fd,
+				vfe31_ctrl->stats_ops.client);
+		}
+		break;
+	case STATS_AWB_NUM: {
+		msgStats.id = MSG_ID_STATS_AWB;
+		rc = vfe31_ctrl->stats_ops.dispatch(
+				vfe31_ctrl->stats_ops.stats_ctrl,
+				MSM_STATS_TYPE_AWB, bufAddress,
+				&msgStats.buf_idx, &vaddr, &msgStats.fd,
+				vfe31_ctrl->stats_ops.client);
+		}
+		break;
+
+	case STATS_IHIST_NUM: {
+		msgStats.id = MSG_ID_STATS_IHIST;
+		rc = vfe31_ctrl->stats_ops.dispatch(
+				vfe31_ctrl->stats_ops.stats_ctrl,
+				MSM_STATS_TYPE_IHIST, bufAddress,
+				&msgStats.buf_idx, &vaddr, &msgStats.fd,
+				vfe31_ctrl->stats_ops.client);
+		}
+		break;
+	case STATS_RS_NUM: {
+		msgStats.id = MSG_ID_STATS_RS;
+		rc = vfe31_ctrl->stats_ops.dispatch(
+				vfe31_ctrl->stats_ops.stats_ctrl,
+				MSM_STATS_TYPE_RS, bufAddress,
+				&msgStats.buf_idx, &vaddr, &msgStats.fd,
+				vfe31_ctrl->stats_ops.client);
+		}
+		break;
+	case STATS_CS_NUM: {
+		msgStats.id = MSG_ID_STATS_CS;
+		rc = vfe31_ctrl->stats_ops.dispatch(
+				vfe31_ctrl->stats_ops.stats_ctrl,
+				MSM_STATS_TYPE_CS, bufAddress,
+				&msgStats.buf_idx, &vaddr, &msgStats.fd,
+				vfe31_ctrl->stats_ops.client);
+		}
+		break;
+
+	default:
+		goto stats_done;
+	}
+	if (rc == 0) {
+		msgStats.buffer = (uint32_t)vaddr;
+		v4l2_subdev_notify(&vfe31_ctrl->subdev,
+			NOTIFY_VFE_MSG_STATS, &msgStats);
+	} else {
+		pr_err("%s: paddr to idx mapping error, stats_id = %d,\n"
+			"paddr = 0x%d\n", __func__,
+			 msgStats.id, msgStats.buffer);
+	}
+stats_done:
+	/* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
+	return;
+}
+
+static void vfe_send_comp_stats_msg(uint32_t status_bits)
+{
+	struct msm_stats_buf msgStats;
+	uint32_t temp;
+
+	msgStats.frame_id = vfe31_ctrl->vfeFrameId;
+	msgStats.status_bits = status_bits;
+
+	msgStats.aec.buff = vfe31_ctrl->aecStatsControl.bufToRender;
+	msgStats.awb.buff = vfe31_ctrl->awbStatsControl.bufToRender;
+	msgStats.af.buff = vfe31_ctrl->afStatsControl.bufToRender;
+
+	msgStats.ihist.buff = vfe31_ctrl->ihistStatsControl.bufToRender;
+	msgStats.rs.buff = vfe31_ctrl->rsStatsControl.bufToRender;
+	msgStats.cs.buff = vfe31_ctrl->csStatsControl.bufToRender;
+
+	temp = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_STATS_AWB_SGW_CFG);
+	msgStats.awb_ymin = (0xFF00 & temp) >> 8;
+
+	v4l2_subdev_notify(&vfe31_ctrl->subdev,
+		NOTIFY_VFE_MSG_COMP_STATS, &msgStats);
+}
+
+static void vfe31_process_stats_ae_irq(void)
+{
+	unsigned long flags;
+	uint32_t addr;
+	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_AEC);
+	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
+	if (addr) {
+		vfe31_ctrl->aecStatsControl.bufToRender =
+			vfe31_process_stats_irq_common(STATS_AE_NUM,
+			addr);
+
+		vfe_send_stats_msg(vfe31_ctrl->aecStatsControl.bufToRender,
+			STATS_AE_NUM);
+	} else{
+		vfe31_ctrl->aecStatsControl.droppedStatsFrameCount++;
+		CDBG("%s: droppedStatsFrameCount = %d", __func__,
+			vfe31_ctrl->aecStatsControl.droppedStatsFrameCount);
+	}
+}
+
+static void vfe31_process_stats_awb_irq(void)
+{
+	unsigned long flags;
+	uint32_t addr;
+	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_AWB);
+	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
+	if (addr) {
+		vfe31_ctrl->awbStatsControl.bufToRender =
+			vfe31_process_stats_irq_common(STATS_AWB_NUM,
+			addr);
+
+		vfe_send_stats_msg(vfe31_ctrl->awbStatsControl.bufToRender,
+			STATS_AWB_NUM);
+	} else{
+		vfe31_ctrl->awbStatsControl.droppedStatsFrameCount++;
+		CDBG("%s: droppedStatsFrameCount = %d", __func__,
+			vfe31_ctrl->awbStatsControl.droppedStatsFrameCount);
+	}
+}
+
+static void vfe31_process_stats_af_irq(void)
+{
+	unsigned long flags;
+	uint32_t addr;
+	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_AF);
+	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
+	if (addr) {
+		vfe31_ctrl->afStatsControl.bufToRender =
+			vfe31_process_stats_irq_common(STATS_AF_NUM,
+			addr);
+
+		vfe_send_stats_msg(vfe31_ctrl->afStatsControl.bufToRender,
+			STATS_AF_NUM);
+	} else{
+		vfe31_ctrl->afStatsControl.droppedStatsFrameCount++;
+		CDBG("%s: droppedStatsFrameCount = %d", __func__,
+			vfe31_ctrl->afStatsControl.droppedStatsFrameCount);
+	}
+}
+
+static void vfe31_process_stats_ihist_irq(void)
+{
+	unsigned long flags;
+	uint32_t addr;
+	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_IHIST);
+	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
+	if (addr) {
+		vfe31_ctrl->ihistStatsControl.bufToRender =
+			  vfe31_process_stats_irq_common(STATS_IHIST_NUM,
+				addr);
+		vfe_send_stats_msg(vfe31_ctrl->ihistStatsControl.bufToRender,
+			  STATS_IHIST_NUM);
+	} else {
+		vfe31_ctrl->ihistStatsControl.droppedStatsFrameCount++;
+		CDBG("%s: droppedStatsFrameCount = %d", __func__,
+			 vfe31_ctrl->ihistStatsControl.droppedStatsFrameCount);
+	}
+}
+
+static void vfe31_process_stats_rs_irq(void)
+{
+	unsigned long flags;
+	uint32_t addr;
+	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_RS);
+	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
+	if (addr) {
+		vfe31_ctrl->rsStatsControl.bufToRender =
+			vfe31_process_stats_irq_common(STATS_RS_NUM,
+			addr);
+		vfe_send_stats_msg(vfe31_ctrl->rsStatsControl.bufToRender,
+			STATS_RS_NUM);
+	} else {
+		vfe31_ctrl->rsStatsControl.droppedStatsFrameCount++;
+		CDBG("%s: droppedStatsFrameCount = %d", __func__,
+			vfe31_ctrl->rsStatsControl.droppedStatsFrameCount);
+	}
+}
+
+static void vfe31_process_stats_cs_irq(void)
+{
+	unsigned long flags;
+	uint32_t addr;
+	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_CS);
+	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
+	if (addr) {
+		vfe31_ctrl->csStatsControl.bufToRender =
+			vfe31_process_stats_irq_common(STATS_CS_NUM,
+				addr);
+			vfe_send_stats_msg(
+				vfe31_ctrl->csStatsControl.bufToRender,
+				STATS_CS_NUM);
+	} else {
+		vfe31_ctrl->csStatsControl.droppedStatsFrameCount++;
+		CDBG("%s: droppedStatsFrameCount = %d", __func__,
+			vfe31_ctrl->csStatsControl.droppedStatsFrameCount);
+	}
+}
+
+static void vfe31_process_stats(uint32_t status_bits)
+{
+	unsigned long flags;
+	int32_t process_stats = false;
+	uint32_t addr;
+	CDBG("%s, stats = 0x%x\n", __func__, status_bits);
+
+	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
+	if (status_bits & VFE_IRQ_STATUS0_STATS_AEC) {
+		addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_AEC);
+		if (addr) {
+			vfe31_ctrl->aecStatsControl.bufToRender =
+				vfe31_process_stats_irq_common(STATS_AE_NUM,
+				addr);
+			process_stats = true;
+		} else{
+			vfe31_ctrl->aecStatsControl.bufToRender = 0;
+			vfe31_ctrl->aecStatsControl.droppedStatsFrameCount++;
+		}
+	} else {
+		vfe31_ctrl->aecStatsControl.bufToRender = 0;
+	}
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_AWB) {
+		addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_AWB);
+		if (addr) {
+			vfe31_ctrl->awbStatsControl.bufToRender =
+				vfe31_process_stats_irq_common(STATS_AWB_NUM,
+				addr);
+			process_stats = true;
+		} else{
+			vfe31_ctrl->awbStatsControl.droppedStatsFrameCount++;
+			vfe31_ctrl->awbStatsControl.bufToRender = 0;
+		}
+	} else {
+		vfe31_ctrl->awbStatsControl.bufToRender = 0;
+	}
+
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_AF) {
+		addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_AF);
+		if (addr) {
+			vfe31_ctrl->afStatsControl.bufToRender =
+				vfe31_process_stats_irq_common(STATS_AF_NUM,
+				addr);
+			process_stats = true;
+		} else {
+			vfe31_ctrl->afStatsControl.bufToRender = 0;
+			vfe31_ctrl->afStatsControl.droppedStatsFrameCount++;
+		}
+	} else {
+		vfe31_ctrl->afStatsControl.bufToRender = 0;
+	}
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_IHIST) {
+		addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_IHIST);
+		if (addr) {
+			vfe31_ctrl->ihistStatsControl.bufToRender =
+				vfe31_process_stats_irq_common(STATS_IHIST_NUM,
+				addr);
+			process_stats = true;
+		} else {
+			vfe31_ctrl->ihistStatsControl.droppedStatsFrameCount++;
+			vfe31_ctrl->ihistStatsControl.bufToRender = 0;
+		}
+	} else {
+		vfe31_ctrl->ihistStatsControl.bufToRender = 0;
+	}
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_RS) {
+		addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_RS);
+		if (!addr) {
+			vfe31_ctrl->rsStatsControl.bufToRender =
+				vfe31_process_stats_irq_common(STATS_RS_NUM,
+				addr);
+			process_stats = true;
+		} else {
+			vfe31_ctrl->rsStatsControl.droppedStatsFrameCount++;
+			vfe31_ctrl->rsStatsControl.bufToRender = 0;
+		}
+	} else {
+		vfe31_ctrl->rsStatsControl.bufToRender = 0;
+	}
+
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_CS) {
+		addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_CS);
+		if (addr) {
+			vfe31_ctrl->csStatsControl.bufToRender =
+				vfe31_process_stats_irq_common(STATS_CS_NUM,
+				addr);
+			process_stats = true;
+		} else {
+			vfe31_ctrl->csStatsControl.droppedStatsFrameCount++;
+			vfe31_ctrl->csStatsControl.bufToRender = 0;
+		}
+	} else {
+		vfe31_ctrl->csStatsControl.bufToRender = 0;
+	}
+
+	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
+	if (process_stats)
+		vfe_send_comp_stats_msg(status_bits);
+
+	return;
+}
+
+static long vfe_stats_bufq_sub_ioctl(struct msm_vfe_cfg_cmd *cmd,
+	void *ion_client, int domain_num)
+{
+	long rc = 0;
+	switch (cmd->cmd_type) {
+	case VFE_CMD_STATS_REQBUF:
+		if (!vfe31_ctrl->stats_ops.stats_ctrl) {
+			/* stats_ctrl has not been init yet */
+			rc = msm_stats_buf_ops_init(&vfe31_ctrl->stats_ctrl,
+					(struct ion_client *)ion_client,
+					&vfe31_ctrl->stats_ops);
+		if (rc < 0) {
+			pr_err("%s: cannot init stats ops", __func__);
+			goto end;
+		}
+		rc = vfe31_ctrl->stats_ops.stats_ctrl_init(
+				&vfe31_ctrl->stats_ctrl);
+		if (rc < 0) {
+			pr_err("%s: cannot init stats_ctrl ops", __func__);
+			memset(&vfe31_ctrl->stats_ops, 0,
+				sizeof(vfe31_ctrl->stats_ops));
+			goto end;
+		}
+		if (sizeof(struct msm_stats_reqbuf) != cmd->length) {
+			/* error. the length not match */
+			pr_err("%s: stats reqbuf input size = %d,\n"
+				"struct size = %d, mis match\n",
+				 __func__, cmd->length,
+				 sizeof(struct msm_stats_reqbuf));
+			rc = -EINVAL;
+			goto end;
+		}
+	}
+	rc = vfe31_ctrl->stats_ops.reqbuf(&vfe31_ctrl->stats_ctrl,
+			(struct msm_stats_reqbuf *)cmd->value,
+			vfe31_ctrl->stats_ops.client);
+	break;
+	case VFE_CMD_STATS_ENQUEUEBUF:
+		if (sizeof(struct msm_stats_buf_info) != cmd->length) {
+			/* error. the length not match */
+			pr_err("%s: stats enqueuebuf input size = %d,\n"
+				"struct size = %d, mis match\n",
+				__func__, cmd->length,
+				sizeof(struct msm_stats_buf_info));
+			rc = -EINVAL ;
+			goto end;
+		}
+		rc = vfe31_ctrl->stats_ops.enqueue_buf(&vfe31_ctrl->stats_ctrl,
+				(struct msm_stats_buf_info *)cmd->value,
+				vfe31_ctrl->stats_ops.client, domain_num);
+	break;
+	case VFE_CMD_STATS_FLUSH_BUFQ: {
+		struct msm_stats_flush_bufq *flush_req = NULL;
+		flush_req = (struct msm_stats_flush_bufq *)cmd->value;
+		if (sizeof(struct msm_stats_flush_bufq) != cmd->length) {
+			/* error. the length not match */
+			pr_err("%s: stats flush queue input size = %d,\n"
+				"struct size = %d, mitch match\n",
+				__func__, cmd->length,
+				sizeof(struct msm_stats_flush_bufq));
+			rc = -EINVAL ;
+			goto end;
+		}
+		rc = vfe31_ctrl->stats_ops.bufq_flush(&vfe31_ctrl->stats_ctrl,
+				(enum msm_stats_enum_type)flush_req->stats_type,
+				vfe31_ctrl->stats_ops.client);
+	}
+	break;
+	case VFE_CMD_STATS_UNREGBUF:
+	{
+		struct msm_stats_reqbuf *req_buf = NULL;
+		req_buf = (struct msm_stats_reqbuf *)cmd->value;
+		if (sizeof(struct msm_stats_reqbuf) != cmd->length) {
+			/* error. the length not match */
+			pr_err("%s: stats reqbuf input size = %d,\n"
+				"struct size = %d, mitch match\n",
+				 __func__, cmd->length,
+				sizeof(struct msm_stats_reqbuf));
+			rc = -EINVAL ;
+			goto end;
+		}
+		rc = vfe31_stats_unregbuf(req_buf, domain_num);
+	}
+	break;
+	default:
+		rc = -1;
+		pr_err("%s: cmd_type %d not supported", __func__,
+			cmd->cmd_type);
+	break;
+	}
+end:
+	return rc;
+}
+
+static void vfe31_process_stats_irq(uint32_t *irqstatus)
+{
+	uint32_t status_bits = VFE_COM_STATUS & *irqstatus;
+
+	if ((vfe31_ctrl->hfr_mode != HFR_MODE_OFF) &&
+		(vfe31_ctrl->vfeFrameId % vfe31_ctrl->hfr_mode != 0)) {
+		CDBG("Skip the stats when HFR enabled\n");
+		return;
+	}
+
+	vfe31_process_stats(status_bits);
+	return;
+}
+
+static void vfe31_do_tasklet(unsigned long data)
+{
+	unsigned long flags;
+
+	struct vfe31_isr_queue_cmd *qcmd = NULL;
+
+	CDBG("=== vfe31_do_tasklet start ===\n");
+
+	while (atomic_read(&irq_cnt)) {
+		spin_lock_irqsave(&vfe31_ctrl->tasklet_lock, flags);
+		qcmd = list_first_entry(&vfe31_ctrl->tasklet_q,
+			struct vfe31_isr_queue_cmd, list);
+		atomic_sub(1, &irq_cnt);
+
+		if (!qcmd) {
+			spin_unlock_irqrestore(&vfe31_ctrl->tasklet_lock,
+				flags);
+			return;
+		}
+
+		list_del(&qcmd->list);
+		spin_unlock_irqrestore(&vfe31_ctrl->tasklet_lock,
+			flags);
+
+		if (qcmd->vfeInterruptStatus0 &
+			VFE_IRQ_STATUS0_CAMIF_SOF_MASK) {
+			CDBG("irq	camifSofIrq\n");
+			vfe31_process_camif_sof_irq();
+		}
+		/* interrupt to be processed,  *qcmd has the payload.  */
+		if (qcmd->vfeInterruptStatus0 &
+			VFE_IRQ_STATUS0_REG_UPDATE_MASK) {
+			CDBG("irq	regUpdateIrq\n");
+			vfe31_process_reg_update_irq();
+		}
+
+		if (qcmd->vfeInterruptStatus1 &
+			VFE_IMASK_WHILE_STOPPING_1) {
+			CDBG("irq	resetAckIrq\n");
+			vfe31_process_reset_irq();
+		}
+
+		if (atomic_read(&vfe31_ctrl->vstate)) {
+			if (qcmd->vfeInterruptStatus1 &
+				VFE31_IMASK_ERROR_ONLY_1) {
+				pr_err("irq	errorIrq\n");
+				vfe31_process_error_irq(
+					qcmd->vfeInterruptStatus1 &
+					VFE31_IMASK_ERROR_ONLY_1);
+			}
+			/* next, check output path related interrupts. */
+			if (qcmd->vfeInterruptStatus0 &
+				VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK) {
+				CDBG("Image composite done 0 irq occured.\n");
+				vfe31_process_output_path_irq_0();
+			}
+			if (qcmd->vfeInterruptStatus0 &
+				VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK) {
+				CDBG("Image composite done 1 irq occured.\n");
+				vfe31_process_output_path_irq_1();
+			}
+			/* in snapshot mode if done then send
+			snapshot done message */
+			if (vfe31_ctrl->operation_mode ==
+					VFE_OUTPUTS_THUMB_AND_MAIN ||
+				vfe31_ctrl->operation_mode ==
+					VFE_OUTPUTS_MAIN_AND_THUMB ||
+				vfe31_ctrl->operation_mode ==
+					VFE_OUTPUTS_THUMB_AND_JPEG ||
+				vfe31_ctrl->operation_mode ==
+					VFE_OUTPUTS_JPEG_AND_THUMB ||
+				vfe31_ctrl->operation_mode ==
+					VFE_OUTPUTS_RAW) {
+				if ((vfe31_ctrl->outpath.out0.capture_cnt == 0)
+					&& (vfe31_ctrl->outpath.out1.
+					capture_cnt == 0)) {
+					msm_camera_io_w_mb(
+						CAMIF_COMMAND_STOP_IMMEDIATELY,
+						vfe31_ctrl->vfebase +
+						VFE_CAMIF_COMMAND);
+					vfe31_send_isp_msg(vfe31_ctrl,
+						MSG_ID_SNAPSHOT_DONE);
+				}
+			}
+			/* then process stats irq. */
+			if (vfe31_ctrl->stats_comp) {
+				/* process stats comb interrupt. */
+				if (qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK) {
+					CDBG("Stats composite irq occured.\n");
+					vfe31_process_stats_irq(
+						&qcmd->vfeInterruptStatus0);
+				}
+			} else {
+				/* process individual stats interrupt. */
+				if (qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_AEC) {
+					CDBG("Stats AEC irq occured.\n");
+					vfe31_process_stats_ae_irq();
+				}
+				if (qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_AWB) {
+					CDBG("Stats AWB irq occured.\n");
+					vfe31_process_stats_awb_irq();
+				}
+				if (qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_AF) {
+					CDBG("Stats AF irq occured.\n");
+					vfe31_process_stats_af_irq();
+				}
+				if (qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_IHIST) {
+					CDBG("Stats IHIST irq occured.\n");
+					vfe31_process_stats_ihist_irq();
+				}
+				if (qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_RS) {
+					CDBG("Stats RS irq occured.\n");
+					vfe31_process_stats_rs_irq();
+				}
+				if (qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_CS) {
+					CDBG("Stats CS irq occured.\n");
+					vfe31_process_stats_cs_irq();
+				}
+				if (qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_SYNC_TIMER0) {
+					CDBG("SYNC_TIMER 0 irq occured.\n");
+					vfe31_send_isp_msg(vfe31_ctrl,
+						MSG_ID_SYNC_TIMER0_DONE);
+				}
+				if (qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_SYNC_TIMER1) {
+					CDBG("SYNC_TIMER 1 irq occured.\n");
+					vfe31_send_isp_msg(vfe31_ctrl,
+						MSG_ID_SYNC_TIMER1_DONE);
+				}
+				if (qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_SYNC_TIMER2) {
+					CDBG("SYNC_TIMER 2 irq occured.\n");
+					vfe31_send_isp_msg(vfe31_ctrl,
+						MSG_ID_SYNC_TIMER2_DONE);
+				}
+			}
+		}
+		kfree(qcmd);
+	}
+	CDBG("=== vfe31_do_tasklet end ===\n");
+}
+
+DECLARE_TASKLET(vfe31_tasklet, vfe31_do_tasklet, 0);
+
+static irqreturn_t vfe31_parse_irq(int irq_num, void *data)
+{
+	unsigned long flags;
+	struct vfe31_irq_status irq;
+	struct vfe31_isr_queue_cmd *qcmd;
+
+	CDBG("vfe_parse_irq\n");
+
+	vfe31_read_irq_status(&irq);
+
+	if ((irq.vfeIrqStatus0 == 0) && (irq.vfeIrqStatus1 == 0)) {
+		CDBG("vfe_parse_irq: vfeIrqStatus0 & 1 are both 0!\n");
+		return IRQ_HANDLED;
+	}
+
+	qcmd = kzalloc(sizeof(struct vfe31_isr_queue_cmd),
+		GFP_ATOMIC);
+	if (!qcmd) {
+		pr_err("vfe_parse_irq: qcmd malloc failed!\n");
+		return IRQ_HANDLED;
+	}
+
+	spin_lock_irqsave(&vfe31_ctrl->stop_flag_lock, flags);
+	if (vfe31_ctrl->stop_ack_pending) {
+		irq.vfeIrqStatus0 &= VFE_IMASK_WHILE_STOPPING_0;
+		irq.vfeIrqStatus1 &= VFE_IMASK_WHILE_STOPPING_1;
+	}
+	spin_unlock_irqrestore(&vfe31_ctrl->stop_flag_lock, flags);
+
+	CDBG("vfe_parse_irq: Irq_status0 = 0x%x, Irq_status1 = 0x%x.\n",
+		irq.vfeIrqStatus0, irq.vfeIrqStatus1);
+
+	qcmd->vfeInterruptStatus0 = irq.vfeIrqStatus0;
+	qcmd->vfeInterruptStatus1 = irq.vfeIrqStatus1;
+
+	spin_lock_irqsave(&vfe31_ctrl->tasklet_lock, flags);
+	list_add_tail(&qcmd->list, &vfe31_ctrl->tasklet_q);
+
+	atomic_add(1, &irq_cnt);
+	spin_unlock_irqrestore(&vfe31_ctrl->tasklet_lock, flags);
+	tasklet_schedule(&vfe31_tasklet);
+	return IRQ_HANDLED;
+}
+
+static long msm_vfe_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int subdev_cmd, void *arg)
+{
+	struct msm_cam_media_controller *pmctl =
+		(struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
+	struct msm_isp_cmd vfecmd;
+	struct msm_camvfe_params *vfe_params;
+	struct msm_vfe_cfg_cmd *cmd;
+	void *data;
+
+	long rc = 0;
+	struct vfe_cmd_stats_buf *scfg = NULL;
+	struct vfe_cmd_stats_ack *sack = NULL;
+
+	if (subdev_cmd == VIDIOC_MSM_VFE_INIT) {
+		CDBG("%s init\n", __func__);
+		return msm_vfe_subdev_init(sd);
+	} else if (subdev_cmd == VIDIOC_MSM_VFE_RELEASE) {
+		msm_vfe_subdev_release(sd);
+		return 0;
+	}
+	vfe_params = (struct msm_camvfe_params *)arg;
+	cmd = vfe_params->vfe_cfg;
+	data = vfe_params->data;
+
+	switch (cmd->cmd_type) {
+	case VFE_CMD_STATS_REQBUF:
+	case VFE_CMD_STATS_ENQUEUEBUF:
+	case VFE_CMD_STATS_FLUSH_BUFQ:
+	case VFE_CMD_STATS_UNREGBUF:
+		/* for easy porting put in one envelope */
+		rc = vfe_stats_bufq_sub_ioctl(cmd, vfe_params->data,
+			pmctl->domain_num);
+		return rc;
+	default:
+		if (cmd->cmd_type != CMD_CONFIG_PING_ADDR &&
+			cmd->cmd_type != CMD_CONFIG_PONG_ADDR &&
+			cmd->cmd_type != CMD_CONFIG_FREE_BUF_ADDR &&
+			cmd->cmd_type != CMD_STATS_AEC_BUF_RELEASE &&
+			cmd->cmd_type != CMD_STATS_AWB_BUF_RELEASE &&
+			cmd->cmd_type != CMD_STATS_IHIST_BUF_RELEASE &&
+			cmd->cmd_type != CMD_STATS_RS_BUF_RELEASE &&
+			cmd->cmd_type != CMD_STATS_CS_BUF_RELEASE &&
+			cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE) {
+				if (copy_from_user(&vfecmd,
+					(void __user *)(cmd->value),
+					sizeof(vfecmd))) {
+						pr_err("%s %d: copy_from_user failed\n",
+						__func__, __LINE__);
+					return -EFAULT;
+				}
+		} else {
+			/* here eith stats release or frame release. */
+			if (cmd->cmd_type != CMD_CONFIG_PING_ADDR &&
+				cmd->cmd_type != CMD_CONFIG_PONG_ADDR &&
+				cmd->cmd_type != CMD_CONFIG_FREE_BUF_ADDR) {
+				/* then must be stats release. */
+				if (!data) {
+					pr_err("%s: data = NULL," \
+						"cmd->cmd_type = %d\n",
+						__func__, cmd->cmd_type);
+					return -EFAULT;
+				}
+				sack = kmalloc(sizeof(struct vfe_cmd_stats_ack),
+							GFP_ATOMIC);
+				if (!sack) {
+					pr_err("%s: no mem for" \
+						"cmd->cmd_type = %d\n",
+						__func__, cmd->cmd_type);
+					return -ENOMEM;
+				}
+
+				sack->nextStatsBuf = *(uint32_t *)data;
+			}
+		}
+
+		CDBG("%s: cmdType = %d\n", __func__, cmd->cmd_type);
+
+		if ((cmd->cmd_type == CMD_STATS_AF_ENABLE)    ||
+			(cmd->cmd_type == CMD_STATS_AWB_ENABLE)   ||
+			(cmd->cmd_type == CMD_STATS_IHIST_ENABLE) ||
+			(cmd->cmd_type == CMD_STATS_RS_ENABLE)    ||
+			(cmd->cmd_type == CMD_STATS_CS_ENABLE)    ||
+			(cmd->cmd_type == CMD_STATS_AEC_ENABLE)) {
+			scfg = NULL;
+			goto vfe31_config_done;
+		}
+		switch (cmd->cmd_type) {
+		case CMD_GENERAL: {
+			rc = vfe31_proc_general(pmctl, &vfecmd);
+			}
+			break;
+		case CMD_CONFIG_PING_ADDR: {
+			int path = *((int *)cmd->value);
+			struct vfe31_output_ch *outch = vfe31_get_ch(path);
+			outch->ping = *((struct msm_free_buf *)data);
+			}
+			break;
+
+		case CMD_CONFIG_PONG_ADDR: {
+			int path = *((int *)cmd->value);
+			struct vfe31_output_ch *outch = vfe31_get_ch(path);
+			outch->pong = *((struct msm_free_buf *)data);
+			}
+			break;
+
+		case CMD_CONFIG_FREE_BUF_ADDR: {
+			int path = *((int *)cmd->value);
+			struct vfe31_output_ch *outch = vfe31_get_ch(path);
+			outch->free_buf = *((struct msm_free_buf *)data);
+			}
+			break;
+
+		case CMD_SNAP_BUF_RELEASE:
+			break;
+
+		case CMD_AXI_CFG_PRIM: {
+			uint32_t *axio = NULL;
+			axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+			if (!axio) {
+				rc = -ENOMEM;
+				break;
+			}
+
+			if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+				kfree(axio);
+				rc = -EFAULT;
+				break;
+			}
+			vfe31_config_axi(OUTPUT_PRIM, axio);
+			kfree(axio);
+			}
+			break;
+
+		case CMD_AXI_CFG_PRIM_ALL_CHNLS: {
+			uint32_t *axio = NULL;
+			axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
+					GFP_ATOMIC);
+			if (!axio) {
+				rc = -ENOMEM;
+				break;
+			}
+
+			if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+				kfree(axio);
+				rc = -EFAULT;
+				break;
+			}
+			vfe31_config_axi(OUTPUT_PRIM_ALL_CHNLS, axio);
+			kfree(axio);
+		}
+			break;
+
+		case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC: {
+			uint32_t *axio = NULL;
+			axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
+					GFP_ATOMIC);
+			if (!axio) {
+				rc = -ENOMEM;
+				break;
+			}
+
+			if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+				kfree(axio);
+				rc = -EFAULT;
+				break;
+			}
+			vfe31_config_axi(OUTPUT_PRIM|OUTPUT_SEC, axio);
+			kfree(axio);
+			}
+			break;
+
+		case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC_ALL_CHNLS: {
+			uint32_t *axio = NULL;
+			axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
+					GFP_ATOMIC);
+			if (!axio) {
+				rc = -ENOMEM;
+				break;
+			}
+
+			if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+				kfree(axio);
+				rc = -EFAULT;
+				break;
+			}
+			vfe31_config_axi
+				(OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS, axio);
+			kfree(axio);
+			}
+			break;
+
+		case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC: {
+			uint32_t *axio = NULL;
+			axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+			if (!axio) {
+				rc = -ENOMEM;
+				break;
+			}
+
+			if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+				kfree(axio);
+				rc = -EFAULT;
+				break;
+			}
+			vfe31_config_axi
+				(OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC, axio);
+			kfree(axio);
+			}
+			break;
+
+		case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC_ALL_CHNLS: {
+			pr_err("%s Invalid/Unsupported AXI configuration %x",
+				__func__, cmd->cmd_type);
+			}
+			break;
+
+		case CMD_AXI_START:
+			/* No need to decouple AXI/VFE for VFE3.1*/
+			break;
+
+		case CMD_AXI_STOP:
+			/* No need to decouple AXI/VFE for VFE3.1*/
+			break;
+
+		case CMD_AXI_RESET:
+			/* No need to decouple AXI/VFE for VFE3.1*/
+			break;
+
+		default:
+			pr_err("%s Unsupported AXI configuration %x ", __func__,
+				cmd->cmd_type);
+			break;
+		}
+	}
+vfe31_config_done:
+	kfree(scfg);
+	kfree(sack);
+	CDBG("%s done: rc = %d\n", __func__, (int) rc);
+	return rc;
+}
+
+static int msm_vfe_subdev_s_crystal_freq(struct v4l2_subdev *sd,
+	u32 freq, u32 flags)
+{
+	int rc = 0;
+	int round_rate;
+
+	round_rate = clk_round_rate(vfe31_ctrl->vfe_clk[0], freq);
+	if (rc < 0) {
+		pr_err("%s: clk_round_rate failed %d\n",
+			__func__, rc);
+		return rc;
+	}
+
+	vfe_clk_rate = round_rate;
+	rc = clk_set_rate(vfe31_ctrl->vfe_clk[0], round_rate);
+	if (rc < 0)
+		pr_err("%s: clk_set_rate failed %d\n",
+			__func__, rc);
+
+	return rc;
+}
+
+static const struct v4l2_subdev_video_ops msm_vfe_subdev_video_ops = {
+	.s_crystal_freq = msm_vfe_subdev_s_crystal_freq,
+};
+
+static const struct v4l2_subdev_core_ops msm_vfe_subdev_core_ops = {
+	.ioctl = msm_vfe_subdev_ioctl,
+};
+
+static const struct v4l2_subdev_ops msm_vfe_subdev_ops = {
+	.core = &msm_vfe_subdev_core_ops,
+	.video = &msm_vfe_subdev_video_ops,
+};
+
+static struct msm_cam_clk_info vfe_clk_info[] = {
+	{"vfe_clk", VFE_CLK_RATE},
+	{"vfe_pclk", -1},
+};
+
+static struct msm_cam_clk_info vfe_camif_clk_info[] = {
+	{"camif_pad_pclk", -1},
+	{"vfe_camif_clk", -1},
+};
+
+static void msm_vfe_camio_clk_sel(enum msm_camio_clk_src_type srctype)
+{
+	struct clk *clk = NULL;
+
+	clk = vfe31_ctrl->vfe_clk[0];
+
+	if (clk != NULL) {
+		switch (srctype) {
+		case MSM_CAMIO_CLK_SRC_INTERNAL:
+			clk_set_flags(clk, 0x00000100 << 1);
+			break;
+
+		case MSM_CAMIO_CLK_SRC_EXTERNAL:
+			clk_set_flags(clk, 0x00000100);
+			break;
+
+		default:
+			break;
+		}
+	}
+}
+
+static void msm_vfe_camif_pad_reg_reset(void)
+{
+	uint32_t reg;
+
+	msm_vfe_camio_clk_sel(MSM_CAMIO_CLK_SRC_INTERNAL);
+	usleep_range(10000, 15000);
+
+	reg = (msm_camera_io_r(vfe31_ctrl->camifbase)) & CAMIF_CFG_RMSK;
+	reg |= 0x3;
+	msm_camera_io_w(reg, vfe31_ctrl->camifbase);
+	usleep_range(10000, 15000);
+
+	reg = (msm_camera_io_r(vfe31_ctrl->camifbase)) & CAMIF_CFG_RMSK;
+	reg |= 0x10;
+	msm_camera_io_w(reg, vfe31_ctrl->camifbase);
+	usleep_range(10000, 15000);
+
+	reg = (msm_camera_io_r(vfe31_ctrl->camifbase)) & CAMIF_CFG_RMSK;
+	/* Need to be uninverted*/
+	reg &= 0x03;
+	msm_camera_io_w(reg, vfe31_ctrl->camifbase);
+	usleep_range(10000, 15000);
+}
+
+int msm_vfe_subdev_init(struct v4l2_subdev *sd)
+{
+	int rc = 0;
+	struct msm_cam_media_controller *mctl;
+	mctl = v4l2_get_subdev_hostdata(sd);
+	if (mctl == NULL) {
+		rc = -EINVAL;
+		goto mctl_failed;
+	}
+
+	spin_lock_init(&vfe31_ctrl->stop_flag_lock);
+	spin_lock_init(&vfe31_ctrl->state_lock);
+	spin_lock_init(&vfe31_ctrl->stats_bufq_lock);
+	spin_lock_init(&vfe31_ctrl->io_lock);
+	spin_lock_init(&vfe31_ctrl->update_ack_lock);
+	spin_lock_init(&vfe31_ctrl->tasklet_lock);
+	spin_lock_init(&vfe31_ctrl->sd_notify_lock);
+	INIT_LIST_HEAD(&vfe31_ctrl->tasklet_q);
+
+	memset(&vfe31_ctrl->stats_ctrl, 0, sizeof(struct msm_stats_bufq_ctrl));
+	memset(&vfe31_ctrl->stats_ops, 0, sizeof(struct msm_stats_ops));
+
+	vfe31_ctrl->update_linear = false;
+	vfe31_ctrl->update_rolloff = false;
+	vfe31_ctrl->update_la = false;
+	vfe31_ctrl->update_gamma = false;
+	vfe31_ctrl->hfr_mode = HFR_MODE_OFF;
+
+	vfe31_ctrl->vfebase = ioremap(vfe31_ctrl->vfemem->start,
+		resource_size(vfe31_ctrl->vfemem));
+	if (!vfe31_ctrl->vfebase) {
+		rc = -ENOMEM;
+		pr_err("%s: vfe ioremap failed\n", __func__);
+		goto vfe_remap_failed;
+	}
+	if (!mctl->sdata->csi_if) {
+		vfe31_ctrl->camifbase = ioremap(vfe31_ctrl->camifmem->start,
+			resource_size(vfe31_ctrl->camifmem));
+		if (!vfe31_ctrl->camifbase) {
+			rc = -ENOMEM;
+			pr_err("%s: camif ioremap failed\n", __func__);
+			goto camif_remap_failed;
+		}
+	}
+
+	if (vfe31_ctrl->fs_vfe) {
+		rc = regulator_enable(vfe31_ctrl->fs_vfe);
+		if (rc) {
+			pr_err("%s: Regulator FS_VFE enable failed\n",
+							__func__);
+			goto vfe_fs_failed;
+		}
+	}
+
+	rc = msm_cam_clk_enable(&vfe31_ctrl->pdev->dev, vfe_clk_info,
+		vfe31_ctrl->vfe_clk, ARRAY_SIZE(vfe_clk_info), 1);
+	if (rc < 0)
+		goto vfe_clk_enable_failed;
+
+	if (!mctl->sdata->csi_if) {
+		rc = msm_cam_clk_enable(&vfe31_ctrl->pdev->dev,
+			vfe_camif_clk_info,
+			vfe31_ctrl->vfe_camif_clk,
+			ARRAY_SIZE(vfe_camif_clk_info), 1);
+		if (rc < 0)
+			goto vfe_camif_clk_enable_failed;
+		msm_vfe_camif_pad_reg_reset();
+	}
+
+#ifdef CONFIG_MSM_IOMMU
+	rc = iommu_attach_device(mctl->domain, vfe31_ctrl->iommu_ctx_imgwr);
+	if (rc < 0) {
+		rc = -ENODEV;
+		pr_err("%s: Device attach failed\n", __func__);
+		goto device_imgwr_attach_failed;
+	}
+	rc = iommu_attach_device(mctl->domain, vfe31_ctrl->iommu_ctx_misc);
+	if (rc < 0) {
+		rc = -ENODEV;
+		pr_err("%s: Device attach failed\n", __func__);
+		goto device_misc_attach_failed;
+	}
+#endif
+
+	msm_camio_bus_scale_cfg(
+		mctl->sdata->pdata->cam_bus_scale_table, S_INIT);
+	msm_camio_bus_scale_cfg(
+		mctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
+	vfe31_ctrl->register_total = VFE31_REGISTER_TOTAL;
+
+	enable_irq(vfe31_ctrl->vfeirq->start);
+
+	return rc;
+
+#ifdef CONFIG_MSM_IOMMU
+device_misc_attach_failed:
+	iommu_detach_device(mctl->domain, vfe31_ctrl->iommu_ctx_imgwr);
+device_imgwr_attach_failed:
+#endif
+	if (!mctl->sdata->csi_if)
+		msm_cam_clk_enable(&vfe31_ctrl->pdev->dev,
+			vfe_camif_clk_info,
+			vfe31_ctrl->vfe_camif_clk,
+			ARRAY_SIZE(vfe_camif_clk_info), 0);
+vfe_camif_clk_enable_failed:
+	msm_cam_clk_enable(&vfe31_ctrl->pdev->dev, vfe_clk_info,
+		vfe31_ctrl->vfe_clk, ARRAY_SIZE(vfe_clk_info), 0);
+vfe_clk_enable_failed:
+	regulator_disable(vfe31_ctrl->fs_vfe);
+vfe_fs_failed:
+	if (!mctl->sdata->csi_if)
+		iounmap(vfe31_ctrl->camifbase);
+camif_remap_failed:
+	iounmap(vfe31_ctrl->vfebase);
+vfe_remap_failed:
+mctl_failed:
+	return rc;
+}
+
+void msm_vfe_subdev_release(struct v4l2_subdev *sd)
+{
+	struct msm_cam_media_controller *pmctl =
+		(struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
+	disable_irq(vfe31_ctrl->vfeirq->start);
+	tasklet_kill(&vfe31_tasklet);
+
+#ifdef CONFIG_MSM_IOMMU
+	iommu_detach_device(pmctl->domain, vfe31_ctrl->iommu_ctx_misc);
+	iommu_detach_device(pmctl->domain, vfe31_ctrl->iommu_ctx_imgwr);
+#endif
+
+	if (!pmctl->sdata->csi_if)
+		msm_cam_clk_enable(&vfe31_ctrl->pdev->dev,
+			vfe_camif_clk_info,
+			vfe31_ctrl->vfe_camif_clk,
+			ARRAY_SIZE(vfe_camif_clk_info), 0);
+
+	msm_cam_clk_enable(&vfe31_ctrl->pdev->dev, vfe_clk_info,
+		vfe31_ctrl->vfe_clk, ARRAY_SIZE(vfe_clk_info), 0);
+
+	if (vfe31_ctrl->fs_vfe)
+		regulator_disable(vfe31_ctrl->fs_vfe);
+
+	CDBG("%s Releasing resources\n", __func__);
+	if (!pmctl->sdata->csi_if)
+		iounmap(vfe31_ctrl->camifbase);
+	iounmap(vfe31_ctrl->vfebase);
+
+	if (atomic_read(&irq_cnt))
+		pr_warning("%s, Warning IRQ Count not ZERO\n", __func__);
+
+	msm_camio_bus_scale_cfg(
+		pmctl->sdata->pdata->cam_bus_scale_table, S_EXIT);
+}
+
+static const struct v4l2_subdev_internal_ops msm_vfe_internal_ops;
+
+static int __devinit vfe31_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+	struct msm_cam_subdev_info sd_info;
+
+	CDBG("%s: device id = %d\n", __func__, pdev->id);
+
+	vfe31_ctrl = kzalloc(sizeof(struct vfe31_ctrl_type), GFP_KERNEL);
+	if (!vfe31_ctrl) {
+		pr_err("%s: no enough memory\n", __func__);
+		return -ENOMEM;
+	}
+
+	v4l2_subdev_init(&vfe31_ctrl->subdev, &msm_vfe_subdev_ops);
+	vfe31_ctrl->subdev.internal_ops = &msm_vfe_internal_ops;
+	vfe31_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	snprintf(vfe31_ctrl->subdev.name,
+			 sizeof(vfe31_ctrl->subdev.name), "vfe3.1");
+	v4l2_set_subdevdata(&vfe31_ctrl->subdev, vfe31_ctrl);
+	platform_set_drvdata(pdev, &vfe31_ctrl->subdev);
+
+	vfe31_ctrl->vfemem = platform_get_resource_byname(pdev,
+		IORESOURCE_MEM, "msm_vfe");
+	if (!vfe31_ctrl->vfemem) {
+		pr_err("%s: no mem resource?\n", __func__);
+		rc = -ENODEV;
+		goto vfe31_no_resource;
+	}
+	vfe31_ctrl->vfeirq = platform_get_resource_byname(pdev,
+		IORESOURCE_IRQ, "msm_vfe");
+	if (!vfe31_ctrl->vfeirq) {
+		pr_err("%s: no irq resource?\n", __func__);
+		rc = -ENODEV;
+		goto vfe31_no_resource;
+	}
+	vfe31_ctrl->camifmem = platform_get_resource_byname(pdev,
+		IORESOURCE_MEM, "msm_camif");
+	if (!vfe31_ctrl->camifmem)
+		pr_err("%s: camif not supported\n", __func__);
+
+	vfe31_ctrl->vfeio = request_mem_region(vfe31_ctrl->vfemem->start,
+		resource_size(vfe31_ctrl->vfemem), pdev->name);
+	if (!vfe31_ctrl->vfeio) {
+		pr_err("%s: no valid mem region\n", __func__);
+		rc = -EBUSY;
+		goto vfe31_no_resource;
+	}
+
+	if (vfe31_ctrl->camifmem) {
+		vfe31_ctrl->camifio = request_mem_region(
+			vfe31_ctrl->camifmem->start,
+			resource_size(vfe31_ctrl->camifmem), pdev->name);
+		if (!vfe31_ctrl->camifio) {
+			release_mem_region(vfe31_ctrl->vfemem->start,
+				resource_size(vfe31_ctrl->vfemem));
+			pr_err("%s: no valid mem region\n", __func__);
+			rc = -EBUSY;
+			goto vfe31_no_resource;
+		}
+	}
+
+	rc = request_irq(vfe31_ctrl->vfeirq->start, vfe31_parse_irq,
+		IRQF_TRIGGER_RISING, "vfe", 0);
+	if (rc < 0) {
+		if (vfe31_ctrl->camifmem) {
+			release_mem_region(vfe31_ctrl->camifmem->start,
+				resource_size(vfe31_ctrl->camifmem));
+		}
+		release_mem_region(vfe31_ctrl->vfemem->start,
+			resource_size(vfe31_ctrl->vfemem));
+		pr_err("%s: irq request fail\n", __func__);
+		rc = -EBUSY;
+		goto vfe31_no_resource;
+	}
+
+	disable_irq(vfe31_ctrl->vfeirq->start);
+
+#ifdef CONFIG_MSM_IOMMU
+	/*get device context for IOMMU*/
+	vfe31_ctrl->iommu_ctx_imgwr =
+		msm_iommu_get_ctx("vfe_imgwr"); /*re-confirm*/
+	vfe31_ctrl->iommu_ctx_misc =
+		msm_iommu_get_ctx("vfe_misc"); /*re-confirm*/
+	if (!vfe31_ctrl->iommu_ctx_imgwr || !vfe31_ctrl->iommu_ctx_misc) {
+		if (vfe31_ctrl->camifmem) {
+			release_mem_region(vfe31_ctrl->camifmem->start,
+				resource_size(vfe31_ctrl->camifmem));
+		}
+		release_mem_region(vfe31_ctrl->vfemem->start,
+			resource_size(vfe31_ctrl->vfemem));
+		pr_err("%s: No iommu fw context found\n", __func__);
+		rc = -ENODEV;
+		goto vfe31_no_resource;
+	}
+#endif
+
+	vfe31_ctrl->pdev = pdev;
+	vfe31_ctrl->fs_vfe = regulator_get(&vfe31_ctrl->pdev->dev, "vdd");
+	if (IS_ERR(vfe31_ctrl->fs_vfe)) {
+		pr_err("%s: Regulator get failed %ld\n", __func__,
+			PTR_ERR(vfe31_ctrl->fs_vfe));
+		vfe31_ctrl->fs_vfe = NULL;
+	}
+
+	sd_info.sdev_type = VFE_DEV;
+	sd_info.sd_index = 0;
+	sd_info.irq_num = vfe31_ctrl->vfeirq->start;
+	msm_cam_register_subdev_node(&vfe31_ctrl->subdev, &sd_info);
+
+	media_entity_init(&vfe31_ctrl->subdev.entity, 0, NULL, 0);
+	vfe31_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	vfe31_ctrl->subdev.entity.group_id = VFE_DEV;
+	vfe31_ctrl->subdev.entity.name = pdev->name;
+	vfe31_ctrl->subdev.entity.revision = vfe31_ctrl->subdev.devnode->num;
+	return 0;
+
+vfe31_no_resource:
+	kfree(vfe31_ctrl);
+	return 0;
+}
+
+static struct platform_driver vfe31_driver = {
+	.probe = vfe31_probe,
+	.driver = {
+	.name = MSM_VFE_DRV_NAME,
+	.owner = THIS_MODULE,
+	},
+};
+
+static int __init msm_vfe31_init_module(void)
+{
+	return platform_driver_register(&vfe31_driver);
+}
+
+static void __exit msm_vfe31_exit_module(void)
+{
+	platform_driver_unregister(&vfe31_driver);
+}
+
+module_init(msm_vfe31_init_module);
+module_exit(msm_vfe31_exit_module);
+MODULE_DESCRIPTION("VFE 3.1 driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/vfe/msm_vfe31_v4l2.h b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe31_v4l2.h
new file mode 100644
index 0000000..eea8078
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe31_v4l2.h
@@ -0,0 +1,955 @@
+/* Copyright (c) 2012 The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MSM_VFE31_V4L2_H__
+#define __MSM_VFE31_V4L2_H__
+
+#include <linux/bitops.h>
+#include "msm_vfe_stats_buf.h"
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/* This defines total number registers in VFE.
+ * Each register is 4 bytes so to get the range,
+ * multiply this number with 4. */
+#define VFE31_REGISTER_TOTAL 0x0000017F
+
+/* at start of camif,  bit 1:0 = 0x01:enable
+ * image data capture at frame boundary. */
+#define CAMIF_COMMAND_START  0x00000005
+
+/* bit 2= 0x1:clear the CAMIF_STATUS register
+ * value. */
+#define CAMIF_COMMAND_CLEAR  0x00000004
+
+/* at stop of vfe pipeline, for now it is assumed
+ * that camif will stop at any time. Bit 1:0 = 0x10:
+ * disable image data capture immediately. */
+#define CAMIF_COMMAND_STOP_IMMEDIATELY  0x00000002
+
+/* at stop of vfe pipeline, for now it is assumed
+ * that camif will stop at any time. Bit 1:0 = 0x00:
+ * disable image data capture at frame boundary */
+#define CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY  0x00000000
+
+/* to halt axi bridge */
+#define AXI_HALT  0x00000001
+
+/* clear the halt bit. */
+#define AXI_HALT_CLEAR  0x00000000
+
+/* clear axi_halt_irq */
+#define MASK_AXI_HALT_IRQ	0xFF7FFFFF
+
+/* reset the pipeline when stop command is issued.
+ * (without reset the register.) bit 26-31 = 0,
+ * domain reset, bit 0-9 = 1 for module reset, except
+ * register module. */
+#define VFE_RESET_UPON_STOP_CMD  0x000003ef
+
+/* reset the pipeline when reset command.
+ * bit 26-31 = 0, domain reset, bit 0-9 = 1 for module reset. */
+#define VFE_RESET_UPON_RESET_CMD  0x000003ff
+
+/* bit 5 is for axi status idle or busy.
+ * 1 =  halted,  0 = busy */
+#define AXI_STATUS_BUSY_MASK 0x00000020
+
+/* bit 0 & bit 1 = 1, both y and cbcr irqs need to be present
+ * for frame done interrupt */
+#define VFE_COMP_IRQ_BOTH_Y_CBCR 3
+
+/* bit 1 = 1, only cbcr irq triggers frame done interrupt */
+#define VFE_COMP_IRQ_CBCR_ONLY 2
+
+/* bit 0 = 1, only y irq triggers frame done interrupt */
+#define VFE_COMP_IRQ_Y_ONLY 1
+
+/* bit 0 = 1, PM go;   bit1 = 1, PM stop */
+#define VFE_PERFORMANCE_MONITOR_GO   0x00000001
+#define VFE_PERFORMANCE_MONITOR_STOP 0x00000002
+
+/* bit 0 = 1, test gen go;   bit1 = 1, test gen stop */
+#define VFE_TEST_GEN_GO   0x00000001
+#define VFE_TEST_GEN_STOP 0x00000002
+
+/* the chroma is assumed to be interpolated between
+ * the luma samples.  JPEG 4:2:2 */
+#define VFE_CHROMA_UPSAMPLE_INTERPOLATED 0
+
+/* constants for irq registers */
+#define VFE_DISABLE_ALL_IRQS 0
+/* bit =1 is to clear the corresponding bit in VFE_IRQ_STATUS.  */
+#define VFE_CLEAR_ALL_IRQS   0xffffffff
+
+#define VFE_IRQ_STATUS0_CAMIF_SOF_MASK            0x00000001
+#define VFE_IRQ_STATUS0_CAMIF_EOF_MASK            0x00000004
+#define VFE_IRQ_STATUS0_REG_UPDATE_MASK           0x00000020
+#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK 0x00200000
+#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK 0x00400000
+#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE2_MASK 0x00800000
+#define VFE_IRQ_STATUS1_RESET_AXI_HALT_ACK_MASK   0x00800000
+#define VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK       0x01000000
+
+#define VFE_IRQ_STATUS0_STATS_AEC     0x2000  /* bit 13 */
+#define VFE_IRQ_STATUS0_STATS_AF      0x4000  /* bit 14 */
+#define VFE_IRQ_STATUS0_STATS_AWB     0x8000  /* bit 15 */
+#define VFE_IRQ_STATUS0_STATS_RS      0x10000  /* bit 16 */
+#define VFE_IRQ_STATUS0_STATS_CS      0x20000  /* bit 17 */
+#define VFE_IRQ_STATUS0_STATS_IHIST   0x40000  /* bit 18 */
+
+#define VFE_IRQ_STATUS0_SYNC_TIMER0   0x2000000  /* bit 25 */
+#define VFE_IRQ_STATUS0_SYNC_TIMER1   0x4000000  /* bit 26 */
+#define VFE_IRQ_STATUS0_SYNC_TIMER2   0x8000000  /* bit 27 */
+#define VFE_IRQ_STATUS0_ASYNC_TIMER0  0x10000000  /* bit 28 */
+#define VFE_IRQ_STATUS0_ASYNC_TIMER1  0x20000000  /* bit 29 */
+#define VFE_IRQ_STATUS0_ASYNC_TIMER2  0x40000000  /* bit 30 */
+#define VFE_IRQ_STATUS0_ASYNC_TIMER3  0x80000000  /* bit 31 */
+
+/* imask for while waiting for stop ack,  driver has already
+ * requested stop, waiting for reset irq, and async timer irq.
+ * For irq_status_0, bit 28-31 are for async timer. For
+ * irq_status_1, bit 22 for reset irq, bit 23 for axi_halt_ack
+   irq */
+#define VFE_IMASK_WHILE_STOPPING_0  0xF0000000
+#define VFE_IMASK_WHILE_STOPPING_1  0x00C00000
+#define VFE_IMASK_RESET             0x00400000
+#define VFE_IMASK_AXI_HALT          0x00800000
+
+
+/* no error irq in mask 0 */
+#define VFE_IMASK_ERROR_ONLY_0  0x0
+/* when normal case, don't want to block error status. */
+/* bit 0-21 are error irq bits */
+#define VFE_IMASK_ERROR_ONLY_1  0x003fffff
+
+/* For BPC bit 0,bit 12-17 and bit 26 -20 are set to zero and other's 1 */
+#define BPC_MASK 0xF80C0FFE
+
+/* For BPC bit 1 and 2 are set to zero and other's 1 */
+#define ABF_MASK 0xFFFFFFF9
+
+/* For DBPC bit 0 is set to zero and other's 1 */
+#define DBPC_MASK 0xFFFFFFFE
+
+/* For DBCC bit 1 is set to zero and other's 1 */
+#define DBCC_MASK 0xFFFFFFFD
+
+/* For DBPC/ABF/DBCC/ABCC bits are set to 1 all others 0 */
+#define DEMOSAIC_MASK 0x8FFFFFFF
+/* For MCE enable bit 28 set to zero and other's 1 */
+#define MCE_EN_MASK 0xEFFFFFFF
+
+/* For MCE Q_K bit 28 to 31 set to zero and other's 1 */
+#define MCE_Q_K_MASK 0x0FFFFFFF
+
+#define AE_BG_ENABLE_MASK 0x00000020      /* bit 5 */
+#define AF_BF_ENABLE_MASK 0x00000040      /* bit 6 */
+#define AWB_ENABLE_MASK 0x00000080     /* bit 7 */
+
+#define RS_ENABLE_MASK 0x00000100      /* bit 8  */
+#define CS_ENABLE_MASK 0x00000200      /* bit 9  */
+#define RS_CS_ENABLE_MASK 0x00000300   /* bit 8,9  */
+#define IHIST_ENABLE_MASK 0x00008000   /* bit 15 */
+#define STATS_ENABLE_MASK 0x000483E0   /* bit 18,15,9,8,7,6,5*/
+
+#define VFE_REG_UPDATE_TRIGGER           1
+#define VFE_PM_BUF_MAX_CNT_MASK          0xFF
+#define VFE_DMI_CFG_DEFAULT              0x00000100
+#define VFE_AE_PINGPONG_STATUS_BIT       0x80
+#define VFE_AF_PINGPONG_STATUS_BIT       0x100
+#define VFE_AWB_PINGPONG_STATUS_BIT      0x200
+
+#define HFR_MODE_OFF 1
+#define VFE_FRAME_SKIP_PERIOD_MASK 0x0000001F /*bits 0 -4*/
+
+enum VFE31_DMI_RAM_SEL {
+	 NO_MEM_SELECTED          = 0,
+	 ROLLOFF_RAM              = 0x1,
+	 RGBLUT_RAM_CH0_BANK0     = 0x2,
+	 RGBLUT_RAM_CH0_BANK1     = 0x3,
+	 RGBLUT_RAM_CH1_BANK0     = 0x4,
+	 RGBLUT_RAM_CH1_BANK1     = 0x5,
+	 RGBLUT_RAM_CH2_BANK0     = 0x6,
+	 RGBLUT_RAM_CH2_BANK1     = 0x7,
+	 STATS_HIST_RAM           = 0x8,
+	 RGBLUT_CHX_BANK0         = 0x9,
+	 RGBLUT_CHX_BANK1         = 0xa,
+	 LUMA_ADAPT_LUT_RAM_BANK0 = 0xb,
+	 LUMA_ADAPT_LUT_RAM_BANK1 = 0xc
+};
+
+enum vfe_output_state {
+	VFE_STATE_IDLE,
+	VFE_STATE_START_REQUESTED,
+	VFE_STATE_STARTED,
+	VFE_STATE_STOP_REQUESTED,
+	VFE_STATE_STOPPED,
+};
+
+#define V31_CAMIF_OFF             0x000001E4
+#define V31_CAMIF_LEN             32
+
+#define V31_DEMUX_OFF             0x00000284
+#define V31_DEMUX_LEN             20
+
+#define V31_DEMOSAICV3_UP_REG_CNT 5
+
+#define V31_OUT_CLAMP_OFF         0x00000524
+#define V31_OUT_CLAMP_LEN         8
+
+#define V31_OPERATION_CFG_LEN     32
+
+#define V31_AXI_BUS_CMD_OFF       0x00000038
+#define V31_AXI_OUT_OFF           0x0000003C
+#define V31_AXI_OUT_LEN           240
+#define V31_AXI_CFG_LEN           47
+#define V31_AXI_RESERVED            1
+#define V31_AXI_RESERVED_LEN        4
+#define V31_AXI_BUS_CFG_LEN       16
+
+#define V31_FRAME_SKIP_OFF        0x00000504
+#define V31_FRAME_SKIP_LEN        32
+
+#define V31_CHROMA_SUBS_OFF       0x000004F8
+#define V31_CHROMA_SUBS_LEN       12
+
+#define V31_FOV_OFF           0x00000360
+#define V31_FOV_LEN           8
+
+#define V31_MAIN_SCALER_OFF 0x00000368
+#define V31_MAIN_SCALER_LEN 28
+
+#define V31_S2Y_OFF 0x000004D0
+#define V31_S2Y_LEN 20
+
+#define V31_S2CbCr_OFF 0x000004E4
+#define V31_S2CbCr_LEN 20
+
+#define V31_CHROMA_EN_OFF 0x000003C4
+#define V31_CHROMA_EN_LEN 36
+
+#define V31_SYNC_TIMER_OFF      0x0000020C
+#define V31_SYNC_TIMER_POLARITY_OFF 0x00000234
+#define V31_TIMER_SELECT_OFF        0x0000025C
+#define V31_SYNC_TIMER_LEN 28
+
+#define V31_ASYNC_TIMER_OFF 0x00000238
+#define V31_ASYNC_TIMER_LEN 28
+
+#define V31_BLACK_LEVEL_OFF 0x00000264
+#define V31_BLACK_LEVEL_LEN 16
+
+#define V31_MESH_ROLL_OFF_CFG_OFF             0x00000274
+#define V31_MESH_ROLL_OFF_CFG_LEN             16
+#define V31_MESH_ROLL_OFF_INIT_TABLE_SIZE     13
+#define V31_MESH_ROLL_OFF_DELTA_TABLE_SIZE    208
+#define V31_MESH_ROLL_OFF_DELTA_TABLE_OFFSET  32
+
+#define V31_COLOR_COR_OFF 0x00000388
+#define V31_COLOR_COR_LEN 52
+
+#define V31_WB_OFF 0x00000384
+#define V31_WB_LEN 4
+
+#define V31_RGB_G_OFF 0x000003BC
+#define V31_RGB_G_LEN 4
+
+#define V31_LA_OFF 0x000003C0
+#define V31_LA_LEN 4
+
+#define V31_SCE_OFF 0x00000418
+#define V31_SCE_LEN 136
+
+#define V31_CHROMA_SUP_OFF 0x000003E8
+#define V31_CHROMA_SUP_LEN 12
+
+#define V31_MCE_OFF 0x000003F4
+#define V31_MCE_LEN 36
+#define V31_STATS_AF_OFF 0x0000053c
+#define V31_STATS_AF_LEN 16
+
+#define V31_STATS_AE_OFF 0x00000534
+#define V31_STATS_AE_LEN 8
+
+#define V31_STATS_AWB_OFF 0x0000054c
+#define V31_STATS_AWB_LEN 32
+
+#define V31_STATS_IHIST_OFF 0x0000057c
+#define V31_STATS_IHIST_LEN 8
+
+#define V31_STATS_RS_OFF 0x0000056c
+#define V31_STATS_RS_LEN 8
+
+#define V31_STATS_CS_OFF 0x00000574
+#define V31_STATS_CS_LEN 8
+
+#define V31_ASF_OFF 0x000004A0
+#define V31_ASF_LEN 48
+#define V31_ASF_UPDATE_LEN 36
+#define V31_CAPTURE_LEN 4
+#define V31_GET_HW_VERSION_OFF 0
+#define V31_GET_HW_VERSION_LEN 4
+#define V31_DEMOSAICV3_OFF 0x00000298
+#define V31_DEMOSAICV3_LEN 4
+/* BPC     */
+#define V31_DEMOSAICV3_DBPC_CFG_OFF  0x0000029C
+#define V31_DEMOSAICV3_DBPC_LEN 8
+#define V31_XBAR_CFG_OFF 0x00000040
+/* ABF     */
+#define V31_DEMOSAICV3_ABF_OFF 0x000002A4
+#define V31_DEMOSAICV3_ABF_LEN 180
+#define V31_XBAR_CFG_LEN 8
+
+#define V31_MODULE_CFG_OFF 0x00000010
+#define V31_MODULE_CFG_LEN 4
+#define V31_EZTUNE_CFG_OFF 0x00000010
+#define V31_EZTUNE_CFG_LEN 4
+
+struct vfe_cmd_hw_version {
+	uint32_t minorVersion;
+	uint32_t majorVersion;
+	uint32_t coreVersion;
+};
+
+enum VFE_AXI_OUTPUT_MODE {
+	VFE_AXI_OUTPUT_MODE_Output1,
+	VFE_AXI_OUTPUT_MODE_Output2,
+	VFE_AXI_OUTPUT_MODE_Output1AndOutput2,
+	VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2,
+	VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1,
+	VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2,
+	VFE_AXI_LAST_OUTPUT_MODE_ENUM
+};
+
+enum VFE_RAW_WR_PATH_SEL {
+	VFE_RAW_OUTPUT_DISABLED,
+	VFE_RAW_OUTPUT_ENC_CBCR_PATH,
+	VFE_RAW_OUTPUT_VIEW_CBCR_PATH,
+	VFE_RAW_OUTPUT_PATH_INVALID
+};
+
+#define VFE_AXI_OUTPUT_BURST_LENGTH     4
+#define VFE_MAX_NUM_FRAGMENTS_PER_FRAME 4
+#define VFE_AXI_OUTPUT_CFG_FRAME_COUNT  3
+
+struct vfe_cmds_per_write_master {
+	uint16_t imageWidth;
+	uint16_t imageHeight;
+	uint16_t outRowCount;
+	uint16_t outRowIncrement;
+	uint32_t outFragments[VFE_AXI_OUTPUT_CFG_FRAME_COUNT]
+		[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
+};
+
+struct vfe_cmds_axi_per_output_path {
+	uint8_t fragmentCount;
+	struct vfe_cmds_per_write_master firstWM;
+	struct vfe_cmds_per_write_master secondWM;
+};
+
+enum VFE_AXI_BURST_LENGTH {
+	VFE_AXI_BURST_LENGTH_IS_2  = 2,
+	VFE_AXI_BURST_LENGTH_IS_4  = 4,
+	VFE_AXI_BURST_LENGTH_IS_8  = 8,
+	VFE_AXI_BURST_LENGTH_IS_16 = 16
+};
+
+struct vfe_cmd_fov_crop_config {
+	uint8_t enable;
+	uint16_t firstPixel;
+	uint16_t lastPixel;
+	uint16_t firstLine;
+	uint16_t lastLine;
+};
+
+struct vfe_cmds_main_scaler_stripe_init {
+	uint16_t MNCounterInit;
+	uint16_t phaseInit;
+};
+
+struct vfe_cmds_scaler_one_dimension {
+	uint8_t  enable;
+	uint16_t inputSize;
+	uint16_t outputSize;
+	uint32_t phaseMultiplicationFactor;
+	uint8_t  interpolationResolution;
+};
+
+struct vfe_cmd_main_scaler_config {
+	uint8_t enable;
+	struct vfe_cmds_scaler_one_dimension    hconfig;
+	struct vfe_cmds_scaler_one_dimension    vconfig;
+	struct vfe_cmds_main_scaler_stripe_init MNInitH;
+	struct vfe_cmds_main_scaler_stripe_init MNInitV;
+};
+
+struct vfe_cmd_scaler2_config {
+	uint8_t enable;
+	struct vfe_cmds_scaler_one_dimension hconfig;
+	struct vfe_cmds_scaler_one_dimension vconfig;
+};
+
+
+struct vfe_cmd_frame_skip_update {
+	uint32_t output1Pattern;
+	uint32_t output2Pattern;
+};
+
+struct vfe_cmd_output_clamp_config {
+	uint8_t minCh0;
+	uint8_t minCh1;
+	uint8_t minCh2;
+	uint8_t maxCh0;
+	uint8_t maxCh1;
+	uint8_t maxCh2;
+};
+
+struct vfe_cmd_chroma_subsample_config {
+	uint8_t enable;
+	uint8_t cropEnable;
+	uint8_t vsubSampleEnable;
+	uint8_t hsubSampleEnable;
+	uint8_t vCosited;
+	uint8_t hCosited;
+	uint8_t vCositedPhase;
+	uint8_t hCositedPhase;
+	uint16_t cropWidthFirstPixel;
+	uint16_t cropWidthLastPixel;
+	uint16_t cropHeightFirstLine;
+	uint16_t cropHeightLastLine;
+};
+
+enum VFE_START_PIXEL_PATTERN {
+	VFE_BAYER_RGRGRG,
+	VFE_BAYER_GRGRGR,
+	VFE_BAYER_BGBGBG,
+	VFE_BAYER_GBGBGB,
+	VFE_YUV_YCbYCr,
+	VFE_YUV_YCrYCb,
+	VFE_YUV_CbYCrY,
+	VFE_YUV_CrYCbY
+};
+
+enum VFE_BUS_RD_INPUT_PIXEL_PATTERN {
+	VFE_BAYER_RAW,
+	VFE_YUV_INTERLEAVED,
+	VFE_YUV_PSEUDO_PLANAR_Y,
+	VFE_YUV_PSEUDO_PLANAR_CBCR
+};
+
+enum VFE_YUV_INPUT_COSITING_MODE {
+	VFE_YUV_COSITED,
+	VFE_YUV_INTERPOLATED
+};
+
+#define VFE31_GAMMA_NUM_ENTRIES  64
+
+#define VFE31_LA_TABLE_LENGTH    64
+
+#define VFE31_HIST_TABLE_LENGTH  256
+
+struct vfe_cmds_demosaic_abf {
+	uint8_t   enable;
+	uint8_t   forceOn;
+	uint8_t   shift;
+	uint16_t  lpThreshold;
+	uint16_t  max;
+	uint16_t  min;
+	uint8_t   ratio;
+};
+
+struct vfe_cmds_demosaic_bpc {
+	uint8_t   enable;
+	uint16_t  fmaxThreshold;
+	uint16_t  fminThreshold;
+	uint16_t  redDiffThreshold;
+	uint16_t  blueDiffThreshold;
+	uint16_t  greenDiffThreshold;
+};
+
+struct vfe_cmd_demosaic_config {
+	uint8_t   enable;
+	uint8_t   slopeShift;
+	struct vfe_cmds_demosaic_abf abfConfig;
+	struct vfe_cmds_demosaic_bpc bpcConfig;
+};
+
+struct vfe_cmd_demosaic_bpc_update {
+	struct vfe_cmds_demosaic_bpc bpcUpdate;
+};
+
+struct vfe_cmd_demosaic_abf_update {
+	struct vfe_cmds_demosaic_abf abfUpdate;
+};
+
+struct vfe_cmd_white_balance_config {
+	uint8_t  enable;
+	uint16_t ch2Gain;
+	uint16_t ch1Gain;
+	uint16_t ch0Gain;
+};
+
+enum VFE_COLOR_CORRECTION_COEF_QFACTOR {
+	COEF_IS_Q7_SIGNED,
+	COEF_IS_Q8_SIGNED,
+	COEF_IS_Q9_SIGNED,
+	COEF_IS_Q10_SIGNED
+};
+
+struct vfe_cmd_color_correction_config {
+	uint8_t     enable;
+	enum VFE_COLOR_CORRECTION_COEF_QFACTOR coefQFactor;
+	int16_t  C0;
+	int16_t  C1;
+	int16_t  C2;
+	int16_t  C3;
+	int16_t  C4;
+	int16_t  C5;
+	int16_t  C6;
+	int16_t  C7;
+	int16_t  C8;
+	int16_t  K0;
+	int16_t  K1;
+	int16_t  K2;
+};
+
+#define VFE_LA_TABLE_LENGTH 64
+
+struct vfe_cmd_la_config {
+	uint8_t enable;
+	int16_t table[VFE_LA_TABLE_LENGTH];
+};
+
+#define VFE_GAMMA_TABLE_LENGTH 256
+enum VFE_RGB_GAMMA_TABLE_SELECT {
+	RGB_GAMMA_CH0_SELECTED,
+	RGB_GAMMA_CH1_SELECTED,
+	RGB_GAMMA_CH2_SELECTED,
+	RGB_GAMMA_CH0_CH1_SELECTED,
+	RGB_GAMMA_CH0_CH2_SELECTED,
+	RGB_GAMMA_CH1_CH2_SELECTED,
+	RGB_GAMMA_CH0_CH1_CH2_SELECTED
+};
+
+struct vfe_cmd_rgb_gamma_config {
+	uint8_t enable;
+	enum VFE_RGB_GAMMA_TABLE_SELECT channelSelect;
+	int16_t table[VFE_GAMMA_TABLE_LENGTH];
+};
+
+struct vfe_cmd_chroma_enhan_config {
+	uint8_t  enable;
+	int16_t am;
+	int16_t ap;
+	int16_t bm;
+	int16_t bp;
+	int16_t cm;
+	int16_t cp;
+	int16_t dm;
+	int16_t dp;
+	int16_t kcr;
+	int16_t kcb;
+	int16_t RGBtoYConversionV0;
+	int16_t RGBtoYConversionV1;
+	int16_t RGBtoYConversionV2;
+	uint8_t RGBtoYConversionOffset;
+};
+
+struct vfe_cmd_chroma_suppression_config {
+	uint8_t enable;
+	uint8_t m1;
+	uint8_t m3;
+	uint8_t n1;
+	uint8_t n3;
+	uint8_t nn1;
+	uint8_t mm1;
+};
+
+struct vfe_cmd_asf_config {
+	uint8_t enable;
+	uint8_t smoothFilterEnabled;
+	uint8_t sharpMode;
+	uint8_t smoothCoefCenter;
+	uint8_t smoothCoefSurr;
+	uint8_t normalizeFactor;
+	uint8_t sharpK1;
+	uint8_t sharpK2;
+	uint8_t sharpThreshE1;
+	int8_t sharpThreshE2;
+	int8_t sharpThreshE3;
+	int8_t sharpThreshE4;
+	int8_t sharpThreshE5;
+	int8_t filter1Coefficients[9];
+	int8_t filter2Coefficients[9];
+	uint8_t  cropEnable;
+	uint16_t cropFirstPixel;
+	uint16_t cropLastPixel;
+	uint16_t cropFirstLine;
+	uint16_t cropLastLine;
+};
+
+struct vfe_cmd_asf_update {
+	uint8_t enable;
+	uint8_t smoothFilterEnabled;
+	uint8_t sharpMode;
+	uint8_t smoothCoefCenter;
+	uint8_t smoothCoefSurr;
+	uint8_t normalizeFactor;
+	uint8_t sharpK1;
+	uint8_t sharpK2;
+	uint8_t sharpThreshE1;
+	int8_t  sharpThreshE2;
+	int8_t  sharpThreshE3;
+	int8_t  sharpThreshE4;
+	int8_t  sharpThreshE5;
+	int8_t  filter1Coefficients[9];
+	int8_t  filter2Coefficients[9];
+	uint8_t cropEnable;
+};
+
+enum VFE_TEST_GEN_SYNC_EDGE {
+	VFE_TEST_GEN_SYNC_EDGE_ActiveHigh,
+	VFE_TEST_GEN_SYNC_EDGE_ActiveLow
+};
+
+
+struct vfe_cmd_bus_pm_start {
+	uint8_t output2YWrPmEnable;
+	uint8_t output2CbcrWrPmEnable;
+	uint8_t output1YWrPmEnable;
+	uint8_t output1CbcrWrPmEnable;
+};
+
+struct  vfe_frame_skip_counts {
+	uint32_t  totalFrameCount;
+	uint32_t  output1Count;
+	uint32_t  output2Count;
+};
+
+enum VFE_AXI_RD_UNPACK_HBI_SEL {
+	VFE_AXI_RD_HBI_32_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_64_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_128_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_256_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_512_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_1024_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_2048_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_4096_CLOCK_CYCLES
+};
+
+struct vfe_frame_bpc_info {
+	uint32_t greenDefectPixelCount;
+	uint32_t redBlueDefectPixelCount;
+};
+
+struct vfe_frame_asf_info {
+	uint32_t  asfMaxEdge;
+	uint32_t  asfHbiCount;
+};
+
+struct vfe_msg_camif_status {
+	uint8_t  camifState;
+	uint32_t pixelCount;
+	uint32_t lineCount;
+};
+
+struct vfe31_irq_status {
+	uint32_t vfeIrqStatus0;
+	uint32_t vfeIrqStatus1;
+	uint32_t camifStatus;
+	uint32_t demosaicStatus;
+	uint32_t asfMaxEdge;
+};
+
+#define V31_PREVIEW_AXI_FLAG  0x00000001
+#define V31_SNAPSHOT_AXI_FLAG (0x00000001<<1)
+
+struct vfe31_cmd_type {
+	uint16_t id;
+	uint32_t length;
+	uint32_t offset;
+	uint32_t flag;
+};
+
+struct vfe31_free_buf {
+	struct list_head node;
+	uint32_t paddr;
+	uint32_t y_off;
+	uint32_t cbcr_off;
+};
+
+struct vfe31_output_ch {
+	struct list_head free_buf_queue;
+	spinlock_t free_buf_lock;
+	uint32_t inst_handle;
+	int8_t ch0;
+	int8_t ch1;
+	int8_t ch2;
+	uint32_t  capture_cnt;
+	uint32_t  frame_drop_cnt;
+	struct msm_free_buf ping;
+	struct msm_free_buf pong;
+	struct msm_free_buf free_buf;
+};
+
+/* no error irq in mask 0 */
+#define VFE31_IMASK_ERROR_ONLY_0  0x0
+/* when normal case, don't want to block error status. */
+/* bit 0-21 are error irq bits */
+#define VFE31_IMASK_ERROR_ONLY_1               0x003FFFFF
+#define VFE31_IMASK_CAMIF_ERROR               (0x00000001<<0)
+#define VFE31_IMASK_STATS_CS_OVWR             (0x00000001<<1)
+#define VFE31_IMASK_STATS_IHIST_OVWR          (0x00000001<<2)
+#define VFE31_IMASK_REALIGN_BUF_Y_OVFL        (0x00000001<<3)
+#define VFE31_IMASK_REALIGN_BUF_CB_OVFL       (0x00000001<<4)
+#define VFE31_IMASK_REALIGN_BUF_CR_OVFL       (0x00000001<<5)
+#define VFE31_IMASK_VIOLATION                 (0x00000001<<6)
+#define VFE31_IMASK_IMG_MAST_0_BUS_OVFL       (0x00000001<<7)
+#define VFE31_IMASK_IMG_MAST_1_BUS_OVFL       (0x00000001<<8)
+#define VFE31_IMASK_IMG_MAST_2_BUS_OVFL       (0x00000001<<9)
+#define VFE31_IMASK_IMG_MAST_3_BUS_OVFL       (0x00000001<<10)
+#define VFE31_IMASK_IMG_MAST_4_BUS_OVFL       (0x00000001<<11)
+#define VFE31_IMASK_IMG_MAST_5_BUS_OVFL       (0x00000001<<12)
+#define VFE31_IMASK_IMG_MAST_6_BUS_OVFL       (0x00000001<<13)
+#define VFE31_IMASK_STATS_AE_BG_BUS_OVFL         (0x00000001<<14)
+#define VFE31_IMASK_STATS_AF_BF_BUS_OVFL         (0x00000001<<15)
+#define VFE31_IMASK_STATS_AWB_BUS_OVFL        (0x00000001<<16)
+#define VFE31_IMASK_STATS_RS_BUS_OVFL         (0x00000001<<17)
+#define VFE31_IMASK_STATS_CS_BUS_OVFL         (0x00000001<<18)
+#define VFE31_IMASK_STATS_IHIST_BUS_OVFL      (0x00000001<<19)
+#define VFE31_IMASK_STATS_SKIN_BHIST_BUS_OVFL       (0x00000001<<20)
+#define VFE31_IMASK_AXI_ERROR                 (0x00000001<<21)
+
+#define VFE_COM_STATUS 0x000FE000
+
+struct vfe31_output_path {
+	uint16_t output_mode;     /* bitmask  */
+
+	struct vfe31_output_ch out0; /* preview and thumbnail */
+	struct vfe31_output_ch out1; /* snapshot */
+	struct vfe31_output_ch out2; /* video    */
+};
+
+struct vfe31_frame_extra {
+	uint32_t greenDefectPixelCount;
+	uint32_t redBlueDefectPixelCount;
+
+	uint32_t  asfMaxEdge;
+	uint32_t  asfHbiCount;
+
+	uint32_t yWrPmStats0;
+	uint32_t yWrPmStats1;
+	uint32_t cbcrWrPmStats0;
+	uint32_t cbcrWrPmStats1;
+
+	uint32_t  frameCounter;
+};
+
+#define VFE_DISABLE_ALL_IRQS             0
+#define VFE_CLEAR_ALL_IRQS               0xffffffff
+
+#define VFE_HW_VERSION					 0x00000000
+#define VFE_GLOBAL_RESET                 0x00000004
+#define VFE_MODULE_RESET				 0x00000008
+#define VFE_CGC_OVERRIDE                 0x0000000C
+#define VFE_MODULE_CFG                   0x00000010
+#define VFE_CFG				 0x00000014
+#define VFE_IRQ_CMD                      0x00000018
+#define VFE_IRQ_MASK_0                   0x0000001C
+#define VFE_IRQ_MASK_1                   0x00000020
+#define VFE_IRQ_CLEAR_0                  0x00000024
+#define VFE_IRQ_CLEAR_1                  0x00000028
+#define VFE_IRQ_STATUS_0                 0x0000002C
+#define VFE_IRQ_STATUS_1                 0x00000030
+#define VFE_IRQ_COMP_MASK                0x00000034
+#define VFE_BUS_CMD                      0x00000038
+#define VFE_BUS_PING_PONG_STATUS         0x00000180
+#define VFE_BUS_OPERATION_STATUS         0x00000184
+
+#define VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_0        0x00000190
+#define VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_1        0x00000194
+
+#define VFE_AXI_CMD                      0x000001D8
+#define VFE_AXI_STATUS                   0x000001DC
+#define VFE_BUS_STATS_PING_PONG_BASE     0x000000F4
+
+#define VFE_BUS_STATS_AEC_WR_PING_ADDR   0x000000F4
+#define VFE_BUS_STATS_AEC_WR_PONG_ADDR   0x000000F8
+#define VFE_BUS_STATS_AEC_UB_CFG         0x000000FC
+#define VFE_BUS_STATS_AF_WR_PING_ADDR    0x00000100
+#define VFE_BUS_STATS_AF_WR_PONG_ADDR    0x00000104
+#define VFE_BUS_STATS_AF_UB_CFG          0x00000108
+#define VFE_BUS_STATS_AWB_WR_PING_ADDR   0x0000010C
+#define VFE_BUS_STATS_AWB_WR_PONG_ADDR   0x00000110
+#define VFE_BUS_STATS_AWB_UB_CFG         0x00000114
+#define VFE_BUS_STATS_RS_WR_PING_ADDR    0x00000118
+#define VFE_BUS_STATS_RS_WR_PONG_ADDR    0x0000011C
+#define VFE_BUS_STATS_RS_UB_CFG          0x00000120
+
+#define VFE_BUS_STATS_CS_WR_PING_ADDR    0x00000124
+#define VFE_BUS_STATS_CS_WR_PONG_ADDR    0x00000128
+#define VFE_BUS_STATS_CS_UB_CFG          0x0000012C
+#define VFE_BUS_STATS_HIST_WR_PING_ADDR  0x00000130
+#define VFE_BUS_STATS_HIST_WR_PONG_ADDR  0x00000134
+#define VFE_BUS_STATS_HIST_UB_CFG        0x00000138
+#define VFE_BUS_STATS_SKIN_WR_PING_ADDR  0x0000013C
+#define VFE_BUS_STATS_SKIN_WR_PONG_ADDR  0x00000140
+#define VFE_BUS_STATS_SKIN_UB_CFG        0x00000144
+#define VFE_BUS_PM_CMD                   0x00000188
+#define VFE_BUS_PM_CFG                   0x0000018C
+#define VFE_CAMIF_COMMAND                0x000001E0
+#define VFE_CAMIF_STATUS                 0x00000204
+#define VFE_REG_UPDATE_CMD               0x00000260
+#define VFE_DEMUX_GAIN_0                 0x00000288
+#define VFE_DEMUX_GAIN_1                 0x0000028C
+#define VFE_CHROMA_UP                    0x0000035C
+#define VFE_FRAMEDROP_ENC_Y_CFG          0x00000504
+#define VFE_FRAMEDROP_ENC_CBCR_CFG       0x00000508
+#define VFE_FRAMEDROP_ENC_Y_PATTERN      0x0000050C
+#define VFE_FRAMEDROP_ENC_CBCR_PATTERN   0x00000510
+#define VFE_FRAMEDROP_VIEW_Y             0x00000514
+#define VFE_FRAMEDROP_VIEW_CBCR          0x00000518
+#define VFE_FRAMEDROP_VIEW_Y_PATTERN     0x0000051C
+#define VFE_FRAMEDROP_VIEW_CBCR_PATTERN  0x00000520
+#define VFE_CLAMP_MAX                    0x00000524
+#define VFE_CLAMP_MIN                    0x00000528
+#define VFE_REALIGN_BUF                  0x0000052C
+#define VFE_STATS_CFG                    0x00000530
+#define VFE_STATS_AWB_SGW_CFG            0x00000554
+#define VFE_DMI_CFG                      0x00000598
+#define VFE_DMI_ADDR                     0x0000059C
+#define VFE_DMI_DATA_LO                  0x000005A4
+#define VFE_AXI_CFG                      0x00000600
+
+#define VFE31_OUTPUT_MODE_PT		BIT(0)
+#define VFE31_OUTPUT_MODE_S			BIT(1)
+#define VFE31_OUTPUT_MODE_V			BIT(2)
+#define VFE31_OUTPUT_MODE_P			BIT(3)
+#define VFE31_OUTPUT_MODE_T			BIT(4)
+#define VFE31_OUTPUT_MODE_P_ALL_CHNLS		BIT(5)
+#define VFE31_OUTPUT_MODE_PRIMARY		BIT(6)
+#define VFE31_OUTPUT_MODE_PRIMARY_ALL_CHNLS	BIT(7)
+#define VFE31_OUTPUT_MODE_SECONDARY		BIT(8)
+#define VFE31_OUTPUT_MODE_SECONDARY_ALL_CHNLS	BIT(9)
+struct vfe_stats_control {
+	uint8_t  ackPending;
+	uint32_t nextFrameAddrBuf;
+	uint32_t droppedStatsFrameCount;
+	uint32_t bufToRender;
+};
+
+struct vfe31_ctrl_type {
+	uint16_t operation_mode;     /* streaming or snapshot */
+	struct vfe31_output_path outpath;
+
+	uint32_t vfeImaskCompositePacked;
+
+	spinlock_t  stop_flag_lock;
+	spinlock_t  update_ack_lock;
+	spinlock_t  state_lock;
+	spinlock_t  io_lock;
+	spinlock_t  stats_bufq_lock;
+
+	uint32_t extlen;
+	void *extdata;
+
+	int8_t start_ack_pending;
+	int8_t stop_ack_pending;
+	int8_t reset_ack_pending;
+	int8_t update_ack_pending;
+	enum vfe_output_state recording_state;
+	int8_t update_linear;
+	int8_t update_rolloff;
+	int8_t update_la;
+	int8_t update_gamma;
+	enum vfe_output_state liveshot_state;
+
+	spinlock_t  tasklet_lock;
+	struct list_head tasklet_q;
+	void __iomem *vfebase;
+	void __iomem *camifbase;
+	void *syncdata;
+	uint32_t register_total;
+
+	struct resource	*vfemem;
+	struct resource	*camifmem;
+	struct resource *vfeio;
+	struct resource *camifio;
+	struct resource *vfeirq;
+	struct regulator *fs_vfe;
+
+	uint32_t stats_comp;
+	atomic_t vstate;
+	uint32_t vfe_capture_count;
+	uint32_t sync_timer_repeat_count;
+	uint32_t sync_timer_state;
+	uint32_t sync_timer_number;
+
+	uint32_t vfeFrameId;
+	uint32_t output1Pattern;
+	uint32_t output1Period;
+	uint32_t output2Pattern;
+	uint32_t output2Period;
+	uint32_t vfeFrameSkipCount;
+	uint32_t vfeFrameSkipPeriod;
+	struct vfe_stats_control afStatsControl;
+	struct vfe_stats_control awbStatsControl;
+	struct vfe_stats_control aecStatsControl;
+	struct vfe_stats_control ihistStatsControl;
+	struct vfe_stats_control rsStatsControl;
+	struct vfe_stats_control csStatsControl;
+
+	/* v4l2 subdev */
+	struct v4l2_subdev subdev;
+	struct platform_device *pdev;
+	struct clk *vfe_clk[5];
+	struct clk *vfe_camif_clk[2];
+	spinlock_t  sd_notify_lock;
+	uint32_t hfr_mode;
+	uint32_t frame_skip_cnt;
+	uint32_t frame_skip_pattern;
+	uint32_t snapshot_frame_cnt;
+	struct msm_stats_bufq_ctrl stats_ctrl;
+	struct msm_stats_ops stats_ops;
+	struct device *iommu_ctx_imgwr;
+	struct device *iommu_ctx_misc;
+};
+
+enum VFE31_STATS_NUM {
+	STATS_AE_NUM,
+	STATS_AF_NUM,
+	STATS_AWB_NUM,
+	STATS_RS_NUM,
+	STATS_CS_NUM,
+	STATS_IHIST_NUM,
+	STATS_SKIN_NUM,
+	STATS_MAX_NUM,
+};
+
+struct vfe_cmd_stats_ack {
+	uint32_t  nextStatsBuf;
+};
+
+#define VFE_STATS_BUFFER_COUNT            3
+
+struct vfe_cmd_stats_buf {
+	uint32_t statsBuf[VFE_STATS_BUFFER_COUNT];
+};
+#endif /* __MSM_VFE31_H__ */
diff --git a/drivers/media/platform/msm/camera_v1/vfe/msm_vfe32.c b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe32.c
new file mode 100644
index 0000000..3570170
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe32.c
@@ -0,0 +1,6782 @@
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/atomic.h>
+#include <linux/regulator/consumer.h>
+#include <linux/clk.h>
+#include <mach/irqs.h>
+#include <mach/camera.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+#include <media/msm_isp.h>
+
+#include "msm.h"
+#include "msm_cam_server.h"
+#include "msm_vfe32.h"
+
+atomic_t irq_cnt;
+
+#define VFE32_AXI_OFFSET 0x0050
+#define vfe32_get_ch_ping_addr(base, chn) \
+	(msm_camera_io_r((base) + 0x0050 + 0x18 * (chn)))
+#define vfe32_get_ch_pong_addr(base, chn) \
+	(msm_camera_io_r((base) + 0x0050 + 0x18 * (chn) + 4))
+#define vfe32_get_ch_addr(ping_pong, base, chn) \
+	((((ping_pong) & (1 << (chn))) == 0) ? \
+	(vfe32_get_ch_pong_addr((base), chn)) : \
+	(vfe32_get_ch_ping_addr((base), chn)))
+
+#define vfe32_put_ch_ping_addr(base, chn, addr) \
+	(msm_camera_io_w((addr), (base) + 0x0050 + 0x18 * (chn)))
+#define vfe32_put_ch_pong_addr(base, chn, addr) \
+	(msm_camera_io_w((addr), (base) + 0x0050 + 0x18 * (chn) + 4))
+#define vfe32_put_ch_addr(ping_pong, base, chn, addr) \
+	(((ping_pong) & (1 << (chn))) == 0 ?   \
+	vfe32_put_ch_pong_addr((base), (chn), (addr)) : \
+	vfe32_put_ch_ping_addr((base), (chn), (addr)))
+
+static uint32_t vfe_clk_rate;
+static void vfe32_send_isp_msg(struct v4l2_subdev *sd,
+	uint32_t vfeFrameId, uint32_t isp_msg_id);
+
+
+struct vfe32_isr_queue_cmd {
+	struct list_head list;
+	uint32_t                           vfeInterruptStatus0;
+	uint32_t                           vfeInterruptStatus1;
+};
+
+static struct vfe32_cmd_type vfe32_cmd[] = {
+/* 0*/	{VFE_CMD_DUMMY_0},
+		{VFE_CMD_SET_CLK},
+		{VFE_CMD_RESET},
+		{VFE_CMD_START},
+		{VFE_CMD_TEST_GEN_START},
+/* 5*/	{VFE_CMD_OPERATION_CFG, V32_OPERATION_CFG_LEN},
+		{VFE_CMD_AXI_OUT_CFG, V32_AXI_OUT_LEN, V32_AXI_OUT_OFF, 0xFF},
+		{VFE_CMD_CAMIF_CFG, V32_CAMIF_LEN, V32_CAMIF_OFF, 0xFF},
+		{VFE_CMD_AXI_INPUT_CFG},
+		{VFE_CMD_BLACK_LEVEL_CFG, V32_BLACK_LEVEL_LEN,
+		V32_BLACK_LEVEL_OFF,
+		0xFF},
+/*10*/  {VFE_CMD_MESH_ROLL_OFF_CFG, V32_MESH_ROLL_OFF_CFG_LEN,
+		V32_MESH_ROLL_OFF_CFG_OFF, 0xFF},
+		{VFE_CMD_DEMUX_CFG, V32_DEMUX_LEN, V32_DEMUX_OFF, 0xFF},
+		{VFE_CMD_FOV_CFG, V32_FOV_LEN, V32_FOV_OFF, 0xFF},
+		{VFE_CMD_MAIN_SCALER_CFG, V32_MAIN_SCALER_LEN,
+		V32_MAIN_SCALER_OFF, 0xFF},
+		{VFE_CMD_WB_CFG, V32_WB_LEN, V32_WB_OFF, 0xFF},
+/*15*/	{VFE_CMD_COLOR_COR_CFG, V32_COLOR_COR_LEN, V32_COLOR_COR_OFF, 0xFF},
+		{VFE_CMD_RGB_G_CFG, V32_RGB_G_LEN, V32_RGB_G_OFF, 0xFF},
+		{VFE_CMD_LA_CFG, V32_LA_LEN, V32_LA_OFF, 0xFF },
+		{VFE_CMD_CHROMA_EN_CFG, V32_CHROMA_EN_LEN, V32_CHROMA_EN_OFF,
+		0xFF},
+		{VFE_CMD_CHROMA_SUP_CFG, V32_CHROMA_SUP_LEN, V32_CHROMA_SUP_OFF,
+		0xFF},
+/*20*/	{VFE_CMD_MCE_CFG, V32_MCE_LEN, V32_MCE_OFF, 0xFF},
+		{VFE_CMD_SK_ENHAN_CFG, V32_SCE_LEN, V32_SCE_OFF, 0xFF},
+		{VFE_CMD_ASF_CFG, V32_ASF_LEN, V32_ASF_OFF, 0xFF},
+		{VFE_CMD_S2Y_CFG, V32_S2Y_LEN, V32_S2Y_OFF, 0xFF},
+		{VFE_CMD_S2CbCr_CFG, V32_S2CbCr_LEN, V32_S2CbCr_OFF, 0xFF},
+/*25*/	{VFE_CMD_CHROMA_SUBS_CFG, V32_CHROMA_SUBS_LEN, V32_CHROMA_SUBS_OFF,
+		0xFF},
+		{VFE_CMD_OUT_CLAMP_CFG, V32_OUT_CLAMP_LEN, V32_OUT_CLAMP_OFF,
+		0xFF},
+		{VFE_CMD_FRAME_SKIP_CFG, V32_FRAME_SKIP_LEN, V32_FRAME_SKIP_OFF,
+		0xFF},
+		{VFE_CMD_DUMMY_1},
+		{VFE_CMD_DUMMY_2},
+/*30*/	{VFE_CMD_DUMMY_3},
+		{VFE_CMD_UPDATE},
+		{VFE_CMD_BL_LVL_UPDATE, V32_BLACK_LEVEL_LEN,
+		V32_BLACK_LEVEL_OFF, 0xFF},
+		{VFE_CMD_DEMUX_UPDATE, V32_DEMUX_LEN, V32_DEMUX_OFF, 0xFF},
+		{VFE_CMD_FOV_UPDATE, V32_FOV_LEN, V32_FOV_OFF, 0xFF},
+/*35*/	{VFE_CMD_MAIN_SCALER_UPDATE, V32_MAIN_SCALER_LEN, V32_MAIN_SCALER_OFF,
+		0xFF},
+		{VFE_CMD_WB_UPDATE, V32_WB_LEN, V32_WB_OFF, 0xFF},
+		{VFE_CMD_COLOR_COR_UPDATE, V32_COLOR_COR_LEN, V32_COLOR_COR_OFF,
+		0xFF},
+		{VFE_CMD_RGB_G_UPDATE, V32_RGB_G_LEN, V32_CHROMA_EN_OFF, 0xFF},
+		{VFE_CMD_LA_UPDATE, V32_LA_LEN, V32_LA_OFF, 0xFF },
+/*40*/	{VFE_CMD_CHROMA_EN_UPDATE, V32_CHROMA_EN_LEN, V32_CHROMA_EN_OFF,
+		0xFF},
+		{VFE_CMD_CHROMA_SUP_UPDATE, V32_CHROMA_SUP_LEN,
+		V32_CHROMA_SUP_OFF, 0xFF},
+		{VFE_CMD_MCE_UPDATE, V32_MCE_LEN, V32_MCE_OFF, 0xFF},
+		{VFE_CMD_SK_ENHAN_UPDATE, V32_SCE_LEN, V32_SCE_OFF, 0xFF},
+		{VFE_CMD_S2CbCr_UPDATE, V32_S2CbCr_LEN, V32_S2CbCr_OFF, 0xFF},
+/*45*/	{VFE_CMD_S2Y_UPDATE, V32_S2Y_LEN, V32_S2Y_OFF, 0xFF},
+		{VFE_CMD_ASF_UPDATE, V32_ASF_UPDATE_LEN, V32_ASF_OFF, 0xFF},
+		{VFE_CMD_FRAME_SKIP_UPDATE},
+		{VFE_CMD_CAMIF_FRAME_UPDATE},
+		{VFE_CMD_STATS_AF_UPDATE, V32_STATS_AF_LEN, V32_STATS_AF_OFF},
+/*50*/	{VFE_CMD_STATS_AE_UPDATE, V32_STATS_AE_LEN, V32_STATS_AE_OFF},
+		{VFE_CMD_STATS_AWB_UPDATE, V32_STATS_AWB_LEN,
+		V32_STATS_AWB_OFF},
+		{VFE_CMD_STATS_RS_UPDATE, V32_STATS_RS_LEN, V32_STATS_RS_OFF},
+		{VFE_CMD_STATS_CS_UPDATE, V32_STATS_CS_LEN, V32_STATS_CS_OFF},
+		{VFE_CMD_STATS_SKIN_UPDATE},
+/*55*/	{VFE_CMD_STATS_IHIST_UPDATE, V32_STATS_IHIST_LEN, V32_STATS_IHIST_OFF},
+		{VFE_CMD_DUMMY_4},
+		{VFE_CMD_EPOCH1_ACK},
+		{VFE_CMD_EPOCH2_ACK},
+		{VFE_CMD_START_RECORDING},
+/*60*/	{VFE_CMD_STOP_RECORDING},
+		{VFE_CMD_DUMMY_5},
+		{VFE_CMD_DUMMY_6},
+		{VFE_CMD_CAPTURE, V32_CAPTURE_LEN, 0xFF},
+		{VFE_CMD_DUMMY_7},
+/*65*/	{VFE_CMD_STOP},
+		{VFE_CMD_GET_HW_VERSION, V32_GET_HW_VERSION_LEN,
+		V32_GET_HW_VERSION_OFF},
+		{VFE_CMD_GET_FRAME_SKIP_COUNTS},
+		{VFE_CMD_OUTPUT1_BUFFER_ENQ},
+		{VFE_CMD_OUTPUT2_BUFFER_ENQ},
+/*70*/	{VFE_CMD_OUTPUT3_BUFFER_ENQ},
+		{VFE_CMD_JPEG_OUT_BUF_ENQ},
+		{VFE_CMD_RAW_OUT_BUF_ENQ},
+		{VFE_CMD_RAW_IN_BUF_ENQ},
+		{VFE_CMD_STATS_AF_ENQ},
+/*75*/	{VFE_CMD_STATS_AE_ENQ},
+		{VFE_CMD_STATS_AWB_ENQ},
+		{VFE_CMD_STATS_RS_ENQ},
+		{VFE_CMD_STATS_CS_ENQ},
+		{VFE_CMD_STATS_SKIN_ENQ},
+/*80*/	{VFE_CMD_STATS_IHIST_ENQ},
+		{VFE_CMD_DUMMY_8},
+		{VFE_CMD_JPEG_ENC_CFG},
+		{VFE_CMD_DUMMY_9},
+		{VFE_CMD_STATS_AF_START, V32_STATS_AF_LEN, V32_STATS_AF_OFF},
+/*85*/	{VFE_CMD_STATS_AF_STOP},
+		{VFE_CMD_STATS_AE_START, V32_STATS_AE_LEN, V32_STATS_AE_OFF},
+		{VFE_CMD_STATS_AE_STOP},
+		{VFE_CMD_STATS_AWB_START, V32_STATS_AWB_LEN, V32_STATS_AWB_OFF},
+		{VFE_CMD_STATS_AWB_STOP},
+/*90*/	{VFE_CMD_STATS_RS_START, V32_STATS_RS_LEN, V32_STATS_RS_OFF},
+		{VFE_CMD_STATS_RS_STOP},
+		{VFE_CMD_STATS_CS_START, V32_STATS_CS_LEN, V32_STATS_CS_OFF},
+		{VFE_CMD_STATS_CS_STOP},
+		{VFE_CMD_STATS_SKIN_START},
+/*95*/	{VFE_CMD_STATS_SKIN_STOP},
+		{VFE_CMD_STATS_IHIST_START,
+		V32_STATS_IHIST_LEN, V32_STATS_IHIST_OFF},
+		{VFE_CMD_STATS_IHIST_STOP},
+		{VFE_CMD_DUMMY_10},
+		{VFE_CMD_SYNC_TIMER_SETTING, V32_SYNC_TIMER_LEN,
+			V32_SYNC_TIMER_OFF},
+/*100*/	{VFE_CMD_ASYNC_TIMER_SETTING, V32_ASYNC_TIMER_LEN, V32_ASYNC_TIMER_OFF},
+		{VFE_CMD_LIVESHOT},
+		{VFE_CMD_LA_SETUP},
+		{VFE_CMD_LINEARIZATION_CFG, V32_LINEARIZATION_LEN1,
+			V32_LINEARIZATION_OFF1},
+		{VFE_CMD_DEMOSAICV3},
+/*105*/	{VFE_CMD_DEMOSAICV3_ABCC_CFG},
+		{VFE_CMD_DEMOSAICV3_DBCC_CFG, V32_DEMOSAICV3_DBCC_LEN,
+			V32_DEMOSAICV3_DBCC_OFF},
+		{VFE_CMD_DEMOSAICV3_DBPC_CFG},
+		{VFE_CMD_DEMOSAICV3_ABF_CFG, V32_DEMOSAICV3_ABF_LEN,
+			V32_DEMOSAICV3_ABF_OFF},
+		{VFE_CMD_DEMOSAICV3_ABCC_UPDATE},
+/*110*/	{VFE_CMD_DEMOSAICV3_DBCC_UPDATE, V32_DEMOSAICV3_DBCC_LEN,
+			V32_DEMOSAICV3_DBCC_OFF},
+		{VFE_CMD_DEMOSAICV3_DBPC_UPDATE},
+		{VFE_CMD_XBAR_CFG},
+		{VFE_CMD_MODULE_CFG, V32_MODULE_CFG_LEN, V32_MODULE_CFG_OFF},
+		{VFE_CMD_ZSL},
+/*115*/	{VFE_CMD_LINEARIZATION_UPDATE, V32_LINEARIZATION_LEN1,
+			V32_LINEARIZATION_OFF1},
+		{VFE_CMD_DEMOSAICV3_ABF_UPDATE, V32_DEMOSAICV3_ABF_LEN,
+			V32_DEMOSAICV3_ABF_OFF},
+		{VFE_CMD_CLF_CFG, V32_CLF_CFG_LEN, V32_CLF_CFG_OFF},
+		{VFE_CMD_CLF_LUMA_UPDATE, V32_CLF_LUMA_UPDATE_LEN,
+			V32_CLF_LUMA_UPDATE_OFF},
+		{VFE_CMD_CLF_CHROMA_UPDATE, V32_CLF_CHROMA_UPDATE_LEN,
+			V32_CLF_CHROMA_UPDATE_OFF},
+/*120*/ {VFE_CMD_PCA_ROLL_OFF_CFG},
+		{VFE_CMD_PCA_ROLL_OFF_UPDATE},
+		{VFE_CMD_GET_REG_DUMP},
+		{VFE_CMD_GET_LINEARIZATON_TABLE},
+		{VFE_CMD_GET_MESH_ROLLOFF_TABLE},
+/*125*/ {VFE_CMD_GET_PCA_ROLLOFF_TABLE},
+		{VFE_CMD_GET_RGB_G_TABLE},
+		{VFE_CMD_GET_LA_TABLE},
+		{VFE_CMD_DEMOSAICV3_UPDATE},
+		{VFE_CMD_ACTIVE_REGION_CFG},
+/*130*/ {VFE_CMD_COLOR_PROCESSING_CONFIG},
+		{VFE_CMD_STATS_WB_AEC_CONFIG},
+		{VFE_CMD_STATS_WB_AEC_UPDATE},
+		{VFE_CMD_Y_GAMMA_CONFIG},
+		{VFE_CMD_SCALE_OUTPUT1_CONFIG},
+/*135*/ {VFE_CMD_SCALE_OUTPUT2_CONFIG},
+		{VFE_CMD_CAPTURE_RAW},
+		{VFE_CMD_STOP_LIVESHOT},
+		{VFE_CMD_RECONFIG_VFE},
+		{VFE_CMD_STATS_REQBUF},
+/*140*/	{VFE_CMD_STATS_ENQUEUEBUF},
+		{VFE_CMD_STATS_FLUSH_BUFQ},
+		{VFE_CMD_STATS_UNREGBUF},
+		{VFE_CMD_STATS_BG_START, V32_STATS_BG_LEN, V32_STATS_BG_OFF},
+		{VFE_CMD_STATS_BG_STOP},
+		{VFE_CMD_STATS_BF_START, V32_STATS_BF_LEN, V32_STATS_BF_OFF},
+/*145*/ {VFE_CMD_STATS_BF_STOP},
+		{VFE_CMD_STATS_BHIST_START, V32_STATS_BHIST_LEN,
+			V32_STATS_BHIST_OFF},
+/*147*/	{VFE_CMD_STATS_BHIST_STOP},
+};
+
+uint32_t vfe32_AXI_WM_CFG[] = {
+	0x0000004C,
+	0x00000064,
+	0x0000007C,
+	0x00000094,
+	0x000000AC,
+	0x000000C4,
+	0x000000DC,
+};
+
+static const char * const vfe32_general_cmd[] = {
+	"DUMMY_0",  /* 0 */
+	"SET_CLK",
+	"RESET",
+	"START",
+	"TEST_GEN_START",
+	"OPERATION_CFG",  /* 5 */
+	"AXI_OUT_CFG",
+	"CAMIF_CFG",
+	"AXI_INPUT_CFG",
+	"BLACK_LEVEL_CFG",
+	"ROLL_OFF_CFG",  /* 10 */
+	"DEMUX_CFG",
+	"FOV_CFG",
+	"MAIN_SCALER_CFG",
+	"WB_CFG",
+	"COLOR_COR_CFG", /* 15 */
+	"RGB_G_CFG",
+	"LA_CFG",
+	"CHROMA_EN_CFG",
+	"CHROMA_SUP_CFG",
+	"MCE_CFG", /* 20 */
+	"SK_ENHAN_CFG",
+	"ASF_CFG",
+	"S2Y_CFG",
+	"S2CbCr_CFG",
+	"CHROMA_SUBS_CFG",  /* 25 */
+	"OUT_CLAMP_CFG",
+	"FRAME_SKIP_CFG",
+	"DUMMY_1",
+	"DUMMY_2",
+	"DUMMY_3",  /* 30 */
+	"UPDATE",
+	"BL_LVL_UPDATE",
+	"DEMUX_UPDATE",
+	"FOV_UPDATE",
+	"MAIN_SCALER_UPDATE",  /* 35 */
+	"WB_UPDATE",
+	"COLOR_COR_UPDATE",
+	"RGB_G_UPDATE",
+	"LA_UPDATE",
+	"CHROMA_EN_UPDATE",  /* 40 */
+	"CHROMA_SUP_UPDATE",
+	"MCE_UPDATE",
+	"SK_ENHAN_UPDATE",
+	"S2CbCr_UPDATE",
+	"S2Y_UPDATE",  /* 45 */
+	"ASF_UPDATE",
+	"FRAME_SKIP_UPDATE",
+	"CAMIF_FRAME_UPDATE",
+	"STATS_AF_UPDATE",
+	"STATS_AE_UPDATE",  /* 50 */
+	"STATS_AWB_UPDATE",
+	"STATS_RS_UPDATE",
+	"STATS_CS_UPDATE",
+	"STATS_SKIN_UPDATE",
+	"STATS_IHIST_UPDATE",  /* 55 */
+	"DUMMY_4",
+	"EPOCH1_ACK",
+	"EPOCH2_ACK",
+	"START_RECORDING",
+	"STOP_RECORDING",  /* 60 */
+	"DUMMY_5",
+	"DUMMY_6",
+	"CAPTURE",
+	"DUMMY_7",
+	"STOP",  /* 65 */
+	"GET_HW_VERSION",
+	"GET_FRAME_SKIP_COUNTS",
+	"OUTPUT1_BUFFER_ENQ",
+	"OUTPUT2_BUFFER_ENQ",
+	"OUTPUT3_BUFFER_ENQ",  /* 70 */
+	"JPEG_OUT_BUF_ENQ",
+	"RAW_OUT_BUF_ENQ",
+	"RAW_IN_BUF_ENQ",
+	"STATS_AF_ENQ",
+	"STATS_AE_ENQ",  /* 75 */
+	"STATS_AWB_ENQ",
+	"STATS_RS_ENQ",
+	"STATS_CS_ENQ",
+	"STATS_SKIN_ENQ",
+	"STATS_IHIST_ENQ",  /* 80 */
+	"DUMMY_8",
+	"JPEG_ENC_CFG",
+	"DUMMY_9",
+	"STATS_AF_START",
+	"STATS_AF_STOP",  /* 85 */
+	"STATS_AE_START",
+	"STATS_AE_STOP",
+	"STATS_AWB_START",
+	"STATS_AWB_STOP",
+	"STATS_RS_START",  /* 90 */
+	"STATS_RS_STOP",
+	"STATS_CS_START",
+	"STATS_CS_STOP",
+	"STATS_SKIN_START",
+	"STATS_SKIN_STOP",  /* 95 */
+	"STATS_IHIST_START",
+	"STATS_IHIST_STOP",
+	"DUMMY_10",
+	"SYNC_TIMER_SETTING",
+	"ASYNC_TIMER_SETTING",  /* 100 */
+	"LIVESHOT",
+	"LA_SETUP",
+	"LINEARIZATION_CFG",
+	"DEMOSAICV3",
+	"DEMOSAICV3_ABCC_CFG", /* 105 */
+	"DEMOSAICV3_DBCC_CFG",
+	"DEMOSAICV3_DBPC_CFG",
+	"DEMOSAICV3_ABF_CFG",
+	"DEMOSAICV3_ABCC_UPDATE",
+	"DEMOSAICV3_DBCC_UPDATE", /* 110 */
+	"DEMOSAICV3_DBPC_UPDATE",
+	"XBAR_CFG",
+	"EZTUNE_CFG",
+	"V32_ZSL",
+	"LINEARIZATION_UPDATE", /*115*/
+	"DEMOSAICV3_ABF_UPDATE",
+	"CLF_CFG",
+	"CLF_LUMA_UPDATE",
+	"CLF_CHROMA_UPDATE",
+	"PCA_ROLL_OFF_CFG", /*120*/
+	"PCA_ROLL_OFF_UPDATE",
+	"GET_REG_DUMP",
+	"GET_LINEARIZATON_TABLE",
+	"GET_MESH_ROLLOFF_TABLE",
+	"GET_PCA_ROLLOFF_TABLE", /*125*/
+	"GET_RGB_G_TABLE",
+	"GET_LA_TABLE",
+	"DEMOSAICV3_UPDATE",
+	"DUMMY_11",
+	"DUMMY_12", /*130*/
+	"DUMMY_13",
+	"DUMMY_14",
+	"DUMMY_15",
+	"DUMMY_16",
+	"DUMMY_17", /*135*/
+	"DUMMY_18",
+	"DUMMY_19",
+	"DUMMY_20",
+	"STATS_REQBUF",
+	"STATS_ENQUEUEBUF", /*140*/
+	"STATS_FLUSH_BUFQ",
+	"STATS_UNREGBUF",
+	"STATS_BG_START",
+	"STATS_BG_STOP",
+	"STATS_BF_START", /*145*/
+	"STATS_BF_STOP",
+	"STATS_BHIST_START",
+	"STATS_BHIST_STOP",
+	"RESET_2",
+};
+
+uint8_t vfe32_use_bayer_stats(struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	if (vfe32_ctrl->ver_num.main >= 4) {
+		/* VFE 4 or above uses bayer stats */
+		return TRUE;
+	} else {
+		return FALSE;
+	}
+}
+
+static void axi_enable_wm_irq(struct vfe_share_ctrl_t *share_ctrl)
+{
+	uint32_t irq_mask, irq_comp_mask = 0;
+	uint16_t vfe_output_mode =
+		share_ctrl->outpath.output_mode &
+			~(VFE32_OUTPUT_MODE_TERTIARY1|
+			VFE32_OUTPUT_MODE_TERTIARY2);
+
+	if (vfe_output_mode)
+		irq_comp_mask =
+		msm_camera_io_r(share_ctrl->vfebase +
+			VFE_IRQ_COMP_MASK);
+	irq_mask = msm_camera_io_r(share_ctrl->vfebase +
+				VFE_IRQ_MASK_0);
+
+	if (share_ctrl->outpath.output_mode &
+			VFE32_OUTPUT_MODE_PRIMARY) {
+		if (share_ctrl->current_mode == VFE_OUTPUTS_RAW)
+			irq_comp_mask |= (
+				0x1 << share_ctrl->outpath.out0.ch0);
+		else
+			irq_comp_mask |= (
+				0x1 << share_ctrl->outpath.out0.ch0 |
+				0x1 << share_ctrl->outpath.out0.ch1);
+		irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
+	} else if (share_ctrl->outpath.output_mode &
+			   VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+		irq_comp_mask |= (
+			0x1 << share_ctrl->outpath.out0.ch0 |
+			0x1 << share_ctrl->outpath.out0.ch1 |
+			0x1 << share_ctrl->outpath.out0.ch2);
+		irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
+	}
+	if (share_ctrl->outpath.output_mode &
+			VFE32_OUTPUT_MODE_SECONDARY) {
+		irq_comp_mask |= (
+			0x1 << (share_ctrl->outpath.out1.ch0 + 8) |
+			0x1 << (share_ctrl->outpath.out1.ch1 + 8));
+		irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
+	} else if (share_ctrl->outpath.output_mode &
+			VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+		irq_comp_mask |= (
+			0x1 << (share_ctrl->outpath.out1.ch0 + 8) |
+			0x1 << (share_ctrl->outpath.out1.ch1 + 8) |
+			0x1 << (share_ctrl->outpath.out1.ch2 + 8));
+		irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
+	}
+
+	if (share_ctrl->outpath.output_mode &
+		VFE32_OUTPUT_MODE_TERTIARY1) {
+		irq_mask |= (0x1 << (share_ctrl->outpath.out2.ch0 +
+			VFE_WM_OFFSET));
+	}
+
+	if (share_ctrl->outpath.output_mode &
+		VFE32_OUTPUT_MODE_TERTIARY2) {
+		irq_mask |= (0x1 << (share_ctrl->outpath.out3.ch0 +
+			VFE_WM_OFFSET));
+	}
+
+	msm_camera_io_w(irq_mask, share_ctrl->vfebase +
+			VFE_IRQ_MASK_0);
+	if (vfe_output_mode)
+		msm_camera_io_w(irq_comp_mask,
+			share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+}
+
+static void axi_disable_wm_irq(struct vfe_share_ctrl_t *share_ctrl,
+	uint16_t output_mode)
+{
+	uint32_t irq_mask, irq_comp_mask = 0;
+	uint16_t vfe_output_mode =
+		output_mode &
+			~(VFE32_OUTPUT_MODE_TERTIARY1|
+			VFE32_OUTPUT_MODE_TERTIARY2);
+	if (vfe_output_mode)
+		irq_comp_mask =
+		msm_camera_io_r(share_ctrl->vfebase +
+			VFE_IRQ_COMP_MASK);
+	irq_mask = msm_camera_io_r(share_ctrl->vfebase +
+				VFE_IRQ_MASK_0);
+
+	if (output_mode &
+			VFE32_OUTPUT_MODE_PRIMARY) {
+		irq_comp_mask &= ~(
+			0x1 << share_ctrl->outpath.out0.ch0 |
+			0x1 << share_ctrl->outpath.out0.ch1);
+		irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
+	} else if (output_mode &
+			   VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+		irq_comp_mask &= ~(
+			0x1 << share_ctrl->outpath.out0.ch0 |
+			0x1 << share_ctrl->outpath.out0.ch1 |
+			0x1 << share_ctrl->outpath.out0.ch2);
+		irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
+	}
+	if (output_mode &
+			VFE32_OUTPUT_MODE_SECONDARY) {
+		irq_comp_mask &= ~(
+			0x1 << (share_ctrl->outpath.out1.ch0 + 8) |
+			0x1 << (share_ctrl->outpath.out1.ch1 + 8));
+		irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
+	} else if (output_mode &
+			VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+		irq_comp_mask &= ~(
+			0x1 << (share_ctrl->outpath.out1.ch0 + 8) |
+			0x1 << (share_ctrl->outpath.out1.ch1 + 8) |
+			0x1 << (share_ctrl->outpath.out1.ch2 + 8));
+		irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
+	}
+	if (output_mode &
+			VFE32_OUTPUT_MODE_TERTIARY1) {
+			irq_mask &= ~(0x1 << (share_ctrl->outpath.out2.ch0 +
+				VFE_WM_OFFSET));
+	}
+	if (output_mode &
+		VFE32_OUTPUT_MODE_TERTIARY2) {
+		irq_mask &= ~(0x1 << (share_ctrl->outpath.out3.ch0 +
+			VFE_WM_OFFSET));
+	}
+	msm_camera_io_w(irq_mask, share_ctrl->vfebase +
+				VFE_IRQ_MASK_0);
+	if (vfe_output_mode)
+		msm_camera_io_w(irq_comp_mask,
+			share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+}
+
+static void axi_enable_irq(struct vfe_share_ctrl_t *share_ctrl)
+{
+	uint32_t irq_mask, irq_mask1;
+	uint32_t vfe_mode =
+		share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
+			VFE_OUTPUTS_RDI1);
+
+	if (share_ctrl->axi_ref_cnt == 1) {
+		irq_mask1 =
+			msm_camera_io_r(share_ctrl->vfebase +
+				VFE_IRQ_MASK_1);
+
+		irq_mask1 |= VFE_IMASK_WHILE_STOPPING_1;
+			msm_camera_io_w(irq_mask1, share_ctrl->vfebase +
+				VFE_IRQ_MASK_1);
+	}
+
+	if (share_ctrl->current_mode & (VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1)) {
+		irq_mask1 =
+			msm_camera_io_r(share_ctrl->vfebase +
+				VFE_IRQ_MASK_1);
+
+		if (share_ctrl->current_mode & VFE_OUTPUTS_RDI0)
+			irq_mask1 |= VFE_IRQ_STATUS1_RDI0_REG_UPDATE_MASK;
+
+		if (share_ctrl->current_mode & VFE_OUTPUTS_RDI1)
+			irq_mask1 |= VFE_IRQ_STATUS1_RDI1_REG_UPDATE_MASK;
+
+		msm_camera_io_w(irq_mask1, share_ctrl->vfebase +
+			VFE_IRQ_MASK_1);
+	}
+
+	if (vfe_mode) {
+		irq_mask =
+		msm_camera_io_r(share_ctrl->vfebase +
+			VFE_IRQ_MASK_0);
+		irq_mask |= 0x00000021;
+		if (share_ctrl->stats_comp)
+			irq_mask |= VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK;
+		else
+			irq_mask |= 0x000FE000;
+		msm_camera_io_w(irq_mask, share_ctrl->vfebase +
+			VFE_IRQ_MASK_0);
+		atomic_set(&share_ctrl->vstate, 1);
+	}
+	atomic_set(&share_ctrl->handle_common_irq, 1);
+}
+
+static void axi_clear_all_interrupts(struct vfe_share_ctrl_t *share_ctrl)
+{
+	atomic_set(&share_ctrl->handle_common_irq, 0);
+	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
+		share_ctrl->vfebase + VFE_IRQ_MASK_0);
+	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
+		share_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+	/* clear all pending interrupts*/
+	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
+		share_ctrl->vfebase + VFE_IRQ_CLEAR_0);
+	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
+		share_ctrl->vfebase + VFE_IRQ_CLEAR_1);
+	/* Ensure the write order while writing
+	*to the command register using the barrier */
+	msm_camera_io_w_mb(1,
+		share_ctrl->vfebase + VFE_IRQ_CMD);
+}
+
+static void axi_disable_irq(struct vfe_share_ctrl_t *share_ctrl,
+	uint32_t mode)
+{
+
+	/* disable all interrupts.  */
+
+	uint32_t irq_mask = 0, irq_mask1 = 0, clear_mask1 = 0;
+	uint32_t vfe_mode =
+		(mode & ~(VFE_OUTPUTS_RDI0|
+			VFE_OUTPUTS_RDI1));
+
+	if (mode & (VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1)) {
+		irq_mask1 =
+			msm_camera_io_r(share_ctrl->vfebase +
+				VFE_IRQ_MASK_1);
+
+		if (mode & VFE_OUTPUTS_RDI0) {
+			irq_mask1 &= ~(VFE_IRQ_STATUS1_RDI0_REG_UPDATE_MASK);
+			clear_mask1 |= VFE_IRQ_STATUS1_RDI0_REG_UPDATE_MASK;
+		}
+
+		if (mode & VFE_OUTPUTS_RDI1) {
+			irq_mask1 &= ~(VFE_IRQ_STATUS1_RDI1_REG_UPDATE_MASK);
+			clear_mask1 |= VFE_IRQ_STATUS1_RDI1_REG_UPDATE_MASK;
+		}
+
+		msm_camera_io_w(irq_mask1, share_ctrl->vfebase +
+			VFE_IRQ_MASK_1);
+		msm_camera_io_w(clear_mask1,
+			share_ctrl->vfebase + VFE_IRQ_CLEAR_1);
+	}
+
+	if (vfe_mode) {
+		atomic_set(&share_ctrl->vstate, 0);
+		irq_mask =
+		msm_camera_io_r(share_ctrl->vfebase +
+			VFE_IRQ_MASK_0);
+		irq_mask &= ~(0x00000021);
+		if (share_ctrl->stats_comp)
+			irq_mask &= ~(VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK);
+		else
+			irq_mask &= ~0x000FE000;
+		msm_camera_io_w(irq_mask, share_ctrl->vfebase +
+			VFE_IRQ_MASK_0);
+	}
+}
+
+static void vfe32_stop(struct vfe32_ctrl_type *vfe32_ctrl)
+{
+
+	/* in either continuous or snapshot mode, stop command can be issued
+	 * at any time. stop camif immediately. */
+	if (!vfe32_ctrl->share_ctrl->dual_enabled)
+		msm_camera_io_w_mb(CAMIF_COMMAND_STOP_IMMEDIATELY,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_CAMIF_COMMAND);
+	else
+		msm_camera_io_w(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_CAMIF_COMMAND);
+	vfe32_ctrl->share_ctrl->operation_mode &=
+		(VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1);
+}
+
+static void vfe32_subdev_notify(int id, int path, uint32_t inst_handle,
+	struct v4l2_subdev *sd, struct vfe_share_ctrl_t *share_ctrl)
+{
+	struct msm_vfe_resp rp;
+	struct msm_frame_info frame_info;
+	unsigned long flags = 0;
+	spin_lock_irqsave(&share_ctrl->sd_notify_lock, flags);
+	CDBG("vfe32_subdev_notify : msgId = %d\n", id);
+	memset(&rp, 0, sizeof(struct msm_vfe_resp));
+	rp.evt_msg.type   = MSM_CAMERA_MSG;
+	frame_info.inst_handle = inst_handle;
+	frame_info.path = path;
+	rp.evt_msg.data = &frame_info;
+	rp.type	   = id;
+	v4l2_subdev_notify(sd, NOTIFY_VFE_BUF_EVT, &rp);
+	spin_unlock_irqrestore(&share_ctrl->sd_notify_lock, flags);
+}
+
+static int vfe32_config_axi(
+	struct axi_ctrl_t *axi_ctrl, int mode, uint32_t *ao)
+{
+	uint32_t *ch_info;
+	uint32_t *axi_cfg = ao+V32_AXI_BUS_FMT_OFF;
+	int vfe_mode = (mode & ~(OUTPUT_TERT1|OUTPUT_TERT2));
+	uint32_t bus_cmd = *axi_cfg;
+	int i;
+
+	/* Update the corresponding write masters for each output*/
+	ch_info = axi_cfg + V32_AXI_CFG_LEN;
+	axi_ctrl->share_ctrl->outpath.out0.ch0 = 0x0000FFFF & *ch_info;
+	axi_ctrl->share_ctrl->outpath.out0.ch1 =
+		0x0000FFFF & (*ch_info++ >> 16);
+	axi_ctrl->share_ctrl->outpath.out0.ch2 = 0x0000FFFF & *ch_info++;
+	axi_ctrl->share_ctrl->outpath.out0.inst_handle = *ch_info++;
+
+	axi_ctrl->share_ctrl->outpath.out1.ch0 = 0x0000FFFF & *ch_info;
+	axi_ctrl->share_ctrl->outpath.out1.ch1 =
+		0x0000FFFF & (*ch_info++ >> 16);
+	axi_ctrl->share_ctrl->outpath.out1.ch2 = 0x0000FFFF & *ch_info++;
+	axi_ctrl->share_ctrl->outpath.out1.inst_handle = *ch_info++;
+
+	axi_ctrl->share_ctrl->outpath.out2.ch0 = 0x0000FFFF & *ch_info;
+	axi_ctrl->share_ctrl->outpath.out2.ch1 =
+		0x0000FFFF & (*ch_info++ >> 16);
+	axi_ctrl->share_ctrl->outpath.out2.ch2 = 0x0000FFFF & *ch_info++;
+	axi_ctrl->share_ctrl->outpath.out2.inst_handle = *ch_info++;
+
+	axi_ctrl->share_ctrl->outpath.out3.ch0 = 0x0000FFFF & *ch_info;
+	axi_ctrl->share_ctrl->outpath.out3.ch1 =
+		0x0000FFFF & (*ch_info++ >> 16);
+	axi_ctrl->share_ctrl->outpath.out3.ch2 = 0x0000FFFF & *ch_info++;
+	axi_ctrl->share_ctrl->outpath.out3.inst_handle = *ch_info++;
+
+	axi_ctrl->share_ctrl->outpath.output_mode = 0;
+
+	if (mode & OUTPUT_TERT1)
+		axi_ctrl->share_ctrl->outpath.output_mode |=
+			VFE32_OUTPUT_MODE_TERTIARY1;
+	if (mode & OUTPUT_TERT2)
+		axi_ctrl->share_ctrl->outpath.output_mode |=
+			VFE32_OUTPUT_MODE_TERTIARY2;
+	if (mode == OUTPUT_TERT1 || mode == OUTPUT_TERT1
+		|| mode == (OUTPUT_TERT1|OUTPUT_TERT2))
+			goto bus_cfg;
+
+	switch (vfe_mode) {
+	case OUTPUT_PRIM:
+		axi_ctrl->share_ctrl->outpath.output_mode |=
+			VFE32_OUTPUT_MODE_PRIMARY;
+		break;
+	case OUTPUT_PRIM_ALL_CHNLS:
+		axi_ctrl->share_ctrl->outpath.output_mode |=
+			VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
+		break;
+	case OUTPUT_PRIM|OUTPUT_SEC:
+		axi_ctrl->share_ctrl->outpath.output_mode |=
+			VFE32_OUTPUT_MODE_PRIMARY;
+		axi_ctrl->share_ctrl->outpath.output_mode |=
+			VFE32_OUTPUT_MODE_SECONDARY;
+		break;
+	case OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS:
+		axi_ctrl->share_ctrl->outpath.output_mode |=
+			VFE32_OUTPUT_MODE_PRIMARY;
+		axi_ctrl->share_ctrl->outpath.output_mode |=
+			VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS;
+		break;
+	case OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC:
+		axi_ctrl->share_ctrl->outpath.output_mode |=
+			VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
+		axi_ctrl->share_ctrl->outpath.output_mode |=
+			VFE32_OUTPUT_MODE_SECONDARY;
+		break;
+	default:
+		pr_err("%s Invalid AXI mode %d ", __func__, mode);
+		return -EINVAL;
+	}
+
+bus_cfg:
+	msm_camera_io_w(*ao, axi_ctrl->share_ctrl->vfebase +
+		VFE_BUS_IO_FORMAT_CFG);
+	axi_cfg++;
+	msm_camera_io_memcpy(axi_ctrl->share_ctrl->vfebase +
+		vfe32_cmd[VFE_CMD_AXI_OUT_CFG].offset, axi_cfg,
+		V32_AXI_BUS_CFG_LEN);
+	axi_cfg += V32_AXI_BUS_CFG_LEN/4;
+	for (i = 0; i < ARRAY_SIZE(vfe32_AXI_WM_CFG); i++) {
+		axi_cfg += 3;
+		msm_camera_io_memcpy(
+			axi_ctrl->share_ctrl->vfebase+vfe32_AXI_WM_CFG[i]+12,
+								axi_cfg, 12);
+		axi_cfg += 3;
+	}
+	msm_camera_io_w(bus_cmd, axi_ctrl->share_ctrl->vfebase +
+					V32_AXI_BUS_CMD_OFF);
+	msm_camera_io_w(*ch_info++,
+		axi_ctrl->share_ctrl->vfebase + VFE_PIXEL_IF_CFG);
+	if (msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
+		V32_GET_HW_VERSION_OFF) ==
+		VFE33_HW_NUMBER) {
+		msm_camera_io_w(*ch_info++,
+			axi_ctrl->share_ctrl->vfebase + VFE_RDI0_CFG);
+		msm_camera_io_w(*ch_info++,
+			axi_ctrl->share_ctrl->vfebase + VFE_RDI1_CFG);
+	}
+	return 0;
+}
+
+static void axi_reset_internal_variables(
+	struct axi_ctrl_t *axi_ctrl,
+	struct msm_camera_vfe_params_t vfe_params)
+{
+	if (vfe_params.operation_mode & VFE_OUTPUTS_RDI0) {
+		atomic_set(&axi_ctrl->share_ctrl->rdi0_update_ack_pending, 0);
+		axi_ctrl->share_ctrl->rdi0_capture_count = -1;
+		axi_ctrl->share_ctrl->outpath.out2.capture_cnt = -1;
+		axi_ctrl->share_ctrl->rdi0FrameId = 0;
+		axi_ctrl->share_ctrl->comp_output_mode &=
+			~VFE32_OUTPUT_MODE_TERTIARY1;
+		axi_ctrl->share_ctrl->operation_mode &=
+			~(VFE_OUTPUTS_RDI0);
+	}
+
+	if (vfe_params.operation_mode & VFE_OUTPUTS_RDI1) {
+		atomic_set(&axi_ctrl->share_ctrl->rdi1_update_ack_pending, 0);
+		axi_ctrl->share_ctrl->rdi1_capture_count = -1;
+		axi_ctrl->share_ctrl->outpath.out3.capture_cnt = -1;
+		axi_ctrl->share_ctrl->rdi1FrameId = 0;
+		axi_ctrl->share_ctrl->comp_output_mode &=
+			~VFE32_OUTPUT_MODE_TERTIARY2;
+		axi_ctrl->share_ctrl->operation_mode &=
+			~(VFE_OUTPUTS_RDI1);
+	}
+}
+
+static void axi_global_reset_internal_variables(
+	struct axi_ctrl_t *axi_ctrl)
+{
+	unsigned long flags;
+	/* state control variables */
+	axi_ctrl->share_ctrl->start_ack_pending = FALSE;
+	atomic_set(&irq_cnt, 0);
+
+	spin_lock_irqsave(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
+	axi_ctrl->share_ctrl->stop_ack_pending  = FALSE;
+	spin_unlock_irqrestore(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
+
+	init_completion(&axi_ctrl->share_ctrl->reset_complete);
+
+	spin_lock_irqsave(&axi_ctrl->share_ctrl->update_ack_lock, flags);
+	axi_ctrl->share_ctrl->update_ack_pending = FALSE;
+	spin_unlock_irqrestore(&axi_ctrl->share_ctrl->update_ack_lock, flags);
+
+	axi_ctrl->share_ctrl->recording_state = VFE_STATE_IDLE;
+	axi_ctrl->share_ctrl->liveshot_state = VFE_STATE_IDLE;
+
+	atomic_set(&axi_ctrl->share_ctrl->vstate, 0);
+	atomic_set(&axi_ctrl->share_ctrl->handle_common_irq, 0);
+	atomic_set(&axi_ctrl->share_ctrl->pix0_update_ack_pending, 0);
+	atomic_set(&axi_ctrl->share_ctrl->rdi0_update_ack_pending, 0);
+	atomic_set(&axi_ctrl->share_ctrl->rdi1_update_ack_pending, 0);
+	atomic_set(&axi_ctrl->share_ctrl->rdi2_update_ack_pending, 0);
+
+	/* 0 for continuous mode, 1 for snapshot mode */
+	axi_ctrl->share_ctrl->operation_mode = 0;
+	axi_ctrl->share_ctrl->current_mode = 0;
+	axi_ctrl->share_ctrl->outpath.output_mode = 0;
+	axi_ctrl->share_ctrl->comp_output_mode = 0;
+	axi_ctrl->share_ctrl->vfe_capture_count = 0;
+	axi_ctrl->share_ctrl->rdi0_capture_count = -1;
+	axi_ctrl->share_ctrl->rdi1_capture_count = -1;
+	axi_ctrl->share_ctrl->outpath.out0.capture_cnt = -1;
+	axi_ctrl->share_ctrl->outpath.out1.capture_cnt = -1;
+	axi_ctrl->share_ctrl->outpath.out2.capture_cnt = -1;
+	axi_ctrl->share_ctrl->outpath.out3.capture_cnt = -1;
+
+	/* this is unsigned 32 bit integer. */
+	axi_ctrl->share_ctrl->vfeFrameId = 0;
+	axi_ctrl->share_ctrl->rdi0FrameId = 0;
+	axi_ctrl->share_ctrl->rdi1FrameId = 0;
+	axi_ctrl->share_ctrl->rdi2FrameId = 0;
+}
+
+
+static void vfe32_program_dmi_cfg(
+	enum VFE32_DMI_RAM_SEL bankSel,
+	struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	/* set bit 8 for auto increment. */
+	uint32_t value = VFE_DMI_CFG_DEFAULT;
+	value += (uint32_t)bankSel;
+	CDBG("%s: banksel = %d\n", __func__, bankSel);
+
+	msm_camera_io_w(value, vfe32_ctrl->share_ctrl->vfebase +
+		VFE_DMI_CFG);
+	/* by default, always starts with offset 0.*/
+	msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
+		VFE_DMI_ADDR);
+}
+
+static void vfe32_reset_dmi_tables(
+	struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	int i = 0;
+
+	/* Reset Histogram LUTs */
+	CDBG("Reset Bayer histogram LUT : 0\n");
+	vfe32_program_dmi_cfg(STATS_BHIST_RAM0, vfe32_ctrl);
+	/* Loop for configuring LUT */
+	for (i = 0; i < 256; i++) {
+		msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
+			VFE_DMI_DATA_HI);
+		msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
+			VFE_DMI_DATA_LO);
+	}
+	vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
+
+	CDBG("Reset Bayer Histogram LUT: 1\n");
+	vfe32_program_dmi_cfg(STATS_BHIST_RAM1, vfe32_ctrl);
+	/* Loop for configuring LUT */
+	for (i = 0; i < 256; i++) {
+		msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
+			VFE_DMI_DATA_HI);
+		msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
+			VFE_DMI_DATA_LO);
+	}
+	vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
+
+	CDBG("Reset IHistogram LUT\n");
+	vfe32_program_dmi_cfg(STATS_IHIST_RAM, vfe32_ctrl);
+	/* Loop for configuring LUT */
+	for (i = 0; i < 256; i++) {
+		msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
+			VFE_DMI_DATA_HI);
+		msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
+			VFE_DMI_DATA_LO);
+	}
+	vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
+}
+
+static void vfe32_set_default_reg_values(
+	struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	msm_camera_io_w(0x800080,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_DEMUX_GAIN_0);
+	msm_camera_io_w(0x800080,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_DEMUX_GAIN_1);
+	/* What value should we program CGC_OVERRIDE to? */
+	msm_camera_io_w(0xFFFFF,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_CGC_OVERRIDE);
+
+	/* default frame drop period and pattern */
+	msm_camera_io_w(0x1f,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_CFG);
+	msm_camera_io_w(0x1f,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_CFG);
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_PATTERN);
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_FRAMEDROP_ENC_CBCR_PATTERN);
+	msm_camera_io_w(0x1f,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y);
+	msm_camera_io_w(0x1f,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR);
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_PATTERN);
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_FRAMEDROP_VIEW_CBCR_PATTERN);
+	msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase + VFE_CLAMP_MIN);
+	msm_camera_io_w(0xFFFFFF,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_CLAMP_MAX);
+
+	/* stats UB config */
+	CDBG("%s: Use bayer stats = %d\n", __func__,
+		 vfe32_use_bayer_stats(vfe32_ctrl));
+	if (!vfe32_use_bayer_stats(vfe32_ctrl)) {
+		msm_camera_io_w(0x3980007,
+			vfe32_ctrl->share_ctrl->vfebase +
+				VFE_BUS_STATS_AEC_BG_UB_CFG);
+		msm_camera_io_w(0x3A00007,
+			vfe32_ctrl->share_ctrl->vfebase +
+				VFE_BUS_STATS_AF_BF_UB_CFG);
+		msm_camera_io_w(0x3A8000F,
+			vfe32_ctrl->share_ctrl->vfebase +
+				VFE_BUS_STATS_AWB_UB_CFG);
+		msm_camera_io_w(0x3B80007,
+			vfe32_ctrl->share_ctrl->vfebase +
+				VFE_BUS_STATS_RS_UB_CFG);
+		msm_camera_io_w(0x3C0001F,
+			vfe32_ctrl->share_ctrl->vfebase +
+				VFE_BUS_STATS_CS_UB_CFG);
+		msm_camera_io_w(0x3E0001F,
+			vfe32_ctrl->share_ctrl->vfebase +
+				VFE_BUS_STATS_HIST_UB_CFG);
+	} else {
+		msm_camera_io_w(0x350001F,
+			vfe32_ctrl->share_ctrl->vfebase +
+				VFE_BUS_STATS_HIST_UB_CFG);
+		msm_camera_io_w(0x370002F,
+			vfe32_ctrl->share_ctrl->vfebase +
+				VFE_BUS_STATS_AEC_BG_UB_CFG);
+		msm_camera_io_w(0x3A0002F,
+			vfe32_ctrl->share_ctrl->vfebase +
+				VFE_BUS_STATS_AF_BF_UB_CFG);
+		msm_camera_io_w(0x3D00007,
+			vfe32_ctrl->share_ctrl->vfebase +
+				VFE_BUS_STATS_RS_UB_CFG);
+		msm_camera_io_w(0x3D8001F,
+			vfe32_ctrl->share_ctrl->vfebase +
+				VFE_BUS_STATS_CS_UB_CFG);
+		msm_camera_io_w(0x3F80007,
+			vfe32_ctrl->share_ctrl->vfebase +
+				VFE_BUS_STATS_SKIN_BHIST_UB_CFG);
+	}
+	vfe32_reset_dmi_tables(vfe32_ctrl);
+}
+
+static void vfe32_reset_internal_variables(
+	struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&vfe32_ctrl->share_ctrl->update_ack_lock,
+		flags);
+	vfe32_ctrl->share_ctrl->update_ack_pending = FALSE;
+	spin_unlock_irqrestore(&vfe32_ctrl->share_ctrl->update_ack_lock,
+		flags);
+	vfe32_ctrl->share_ctrl->vfe_capture_count = 0;
+	/* this is unsigned 32 bit integer. */
+	vfe32_ctrl->share_ctrl->vfeFrameId = 0;
+	vfe32_ctrl->share_ctrl->update_counter = 0;
+
+	/* Stats control variables. */
+	memset(&(vfe32_ctrl->afbfStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe32_ctrl->awbStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe32_ctrl->aecbgStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe32_ctrl->bhistStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe32_ctrl->ihistStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe32_ctrl->rsStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe32_ctrl->csStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+	vfe32_ctrl->share_ctrl->outpath.out0.capture_cnt = -1;
+	vfe32_ctrl->share_ctrl->outpath.out1.capture_cnt = -1;
+	vfe32_ctrl->share_ctrl->recording_state = VFE_STATE_IDLE;
+	vfe32_ctrl->share_ctrl->liveshot_state = VFE_STATE_IDLE;
+
+	atomic_set(&vfe32_ctrl->share_ctrl->vstate, 0);
+	atomic_set(&vfe32_ctrl->share_ctrl->pix0_update_ack_pending, 0);
+
+	vfe32_ctrl->frame_skip_cnt = 31;
+	vfe32_ctrl->frame_skip_pattern = 0xffffffff;
+	vfe32_ctrl->snapshot_frame_cnt = 0;
+	vfe32_set_default_reg_values(vfe32_ctrl);
+}
+
+
+static int vfe32_reset(struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	uint32_t irq_mask1, irq_mask;
+	atomic_set(&vfe32_ctrl->share_ctrl->vstate, 0);
+	msm_camera_io_w(VFE_MODULE_RESET_CMD,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_RESET);
+	msm_camera_io_w(0,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_RESET);
+
+	irq_mask =
+		msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
+			VFE_IRQ_MASK_0);
+	irq_mask &= ~(0x000FE021|VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK);
+
+	msm_camera_io_w(irq_mask, vfe32_ctrl->share_ctrl->vfebase +
+		VFE_IRQ_MASK_0);
+	vfe32_ctrl->share_ctrl->operation_mode &=
+		(VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1);
+	vfe32_ctrl->share_ctrl->comp_output_mode &=
+			(VFE32_OUTPUT_MODE_TERTIARY1|
+			VFE32_OUTPUT_MODE_TERTIARY2);
+
+	/* enable reset_ack interrupt.  */
+	irq_mask1 = msm_camera_io_r(
+		vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
+	irq_mask1 |= VFE_IMASK_WHILE_STOPPING_1;
+	msm_camera_io_w(irq_mask1,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
+	msm_camera_io_w_mb(VFE_ONLY_RESET_CMD,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_GLOBAL_RESET);
+
+	return wait_for_completion_interruptible(
+			&vfe32_ctrl->share_ctrl->reset_complete);
+}
+
+static int axi_reset(struct axi_ctrl_t *axi_ctrl,
+	struct msm_camera_vfe_params_t vfe_params)
+{
+	int rc = 0;
+	if (vfe_params.skip_reset) {
+		axi_reset_internal_variables(axi_ctrl, vfe_params);
+		return rc;
+	}
+	axi_global_reset_internal_variables(axi_ctrl);
+	/* disable all interrupts.  vfeImaskLocal is also reset to 0
+	* to begin with. */
+	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
+		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_0);
+
+	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
+		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+	/* clear all pending interrupts*/
+	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
+		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_0);
+	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
+		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_1);
+
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_camera_io_w_mb(1, axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CMD);
+
+	/* enable reset_ack interrupt.  */
+	msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_1,
+		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+	/* Write to VFE_GLOBAL_RESET_CMD to reset the vfe hardware. Once reset
+	 * is done, hardware interrupt will be generated.  VFE ist processes
+	 * the interrupt to complete the function call.  Note that the reset
+	 * function is synchronous. */
+
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_camera_io_w_mb(VFE_RESET_UPON_RESET_CMD,
+		axi_ctrl->share_ctrl->vfebase + VFE_GLOBAL_RESET);
+
+	return wait_for_completion_interruptible(
+			&axi_ctrl->share_ctrl->reset_complete);
+}
+
+static int vfe32_operation_config(uint32_t *cmd,
+			struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	uint32_t *p = cmd;
+
+	vfe32_ctrl->share_ctrl->stats_comp = *(++p);
+	vfe32_ctrl->hfr_mode = *(++p);
+
+	msm_camera_io_w(*(++p),
+		vfe32_ctrl->share_ctrl->vfebase + VFE_CFG);
+	msm_camera_io_w(*(++p),
+		vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+	msm_camera_io_w(*(++p),
+		vfe32_ctrl->share_ctrl->vfebase + VFE_REALIGN_BUF);
+	msm_camera_io_w(*(++p),
+		vfe32_ctrl->share_ctrl->vfebase + VFE_CHROMA_UP);
+	msm_camera_io_w(*(++p),
+		vfe32_ctrl->share_ctrl->vfebase + VFE_STATS_CFG);
+	return 0;
+}
+
+static unsigned long vfe32_stats_dqbuf(struct vfe32_ctrl_type *vfe32_ctrl,
+	enum msm_stats_enum_type stats_type)
+{
+	struct msm_stats_meta_buf *buf = NULL;
+	int rc = 0;
+	rc = vfe32_ctrl->stats_ops.dqbuf(
+			vfe32_ctrl->stats_ops.stats_ctrl, stats_type, &buf);
+	if (rc < 0) {
+		CDBG("%s: dq stats buf (type = %d) err = %d",
+			__func__, stats_type, rc);
+		return 0L;
+	}
+	return buf->paddr;
+}
+
+static unsigned long vfe32_stats_flush_enqueue(
+	struct vfe32_ctrl_type *vfe32_ctrl,
+	enum msm_stats_enum_type stats_type)
+{
+	struct msm_stats_bufq *bufq = NULL;
+	struct msm_stats_meta_buf *stats_buf = NULL;
+	int rc = 0;
+	int i;
+
+	/*
+	 * Passing NULL for ion client as the buffers are already
+	 * mapped at this stage, client is not required, flush all
+	 * the buffers, and buffers move to PREPARE state
+	 */
+
+	rc = vfe32_ctrl->stats_ops.bufq_flush(
+			vfe32_ctrl->stats_ops.stats_ctrl, stats_type, NULL);
+	if (rc < 0) {
+		pr_err("%s: dq stats buf (type = %d) err = %d",
+			__func__, stats_type, rc);
+		return 0L;
+	}
+	/* Queue all the buffers back to QUEUED state */
+	bufq = vfe32_ctrl->stats_ctrl.bufq[stats_type];
+	for (i = 0; i < bufq->num_bufs; i++) {
+		stats_buf = &bufq->bufs[i];
+		rc = vfe32_ctrl->stats_ops.enqueue_buf(
+				vfe32_ctrl->stats_ops.stats_ctrl,
+				&(stats_buf->info), NULL, -1);
+		if (rc < 0) {
+			pr_err("%s: dq stats buf (type = %d) err = %d",
+				 __func__, stats_type, rc);
+			return rc;
+		}
+	}
+	return 0L;
+}
+
+
+static unsigned long vfe32_stats_unregbuf(
+	struct vfe32_ctrl_type *vfe32_ctrl,
+	struct msm_stats_reqbuf *req_buf, int domain_num)
+{
+	int i = 0, rc = 0;
+
+	for (i = 0; i < req_buf->num_buf; i++) {
+		rc = vfe32_ctrl->stats_ops.buf_unprepare(
+			vfe32_ctrl->stats_ops.stats_ctrl,
+			req_buf->stats_type, i,
+			vfe32_ctrl->stats_ops.client, domain_num);
+		if (rc < 0) {
+			pr_err("%s: unreg stats buf (type = %d) err = %d",
+				__func__, req_buf->stats_type, rc);
+		return rc;
+		}
+	}
+	return 0L;
+}
+static int vfe_stats_awb_buf_init(
+	struct vfe32_ctrl_type *vfe32_ctrl,
+	struct vfe_cmd_stats_buf *in)
+{
+	uint32_t addr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_AWB);
+	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq awb ping buf from free buf queue", __func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_AWB_WR_PING_ADDR);
+	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_AWB);
+	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq awb ping buf from free buf queue",
+			__func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_AWB_WR_PONG_ADDR);
+	return 0;
+}
+
+static uint32_t vfe_stats_aec_bg_buf_init(
+	struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	uint32_t addr;
+	unsigned long flags;
+	uint32_t stats_type;
+
+	stats_type =
+		(!vfe32_use_bayer_stats(vfe32_ctrl)) ? MSM_STATS_TYPE_AEC
+			: MSM_STATS_TYPE_BG;
+	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, stats_type);
+	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq aec ping buf from free buf queue",
+			__func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_AEC_BG_WR_PING_ADDR);
+	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, stats_type);
+	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq aec pong buf from free buf queue",
+			__func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_AEC_BG_WR_PONG_ADDR);
+	return 0;
+}
+
+static int vfe_stats_af_bf_buf_init(
+	struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	uint32_t addr;
+	unsigned long flags;
+	int rc = 0;
+
+	uint32_t stats_type;
+	stats_type =
+		(!vfe32_use_bayer_stats(vfe32_ctrl)) ? MSM_STATS_TYPE_AF
+			: MSM_STATS_TYPE_BF;
+
+	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
+	rc = vfe32_stats_flush_enqueue(vfe32_ctrl, stats_type);
+	if (rc < 0) {
+		pr_err("%s: dq stats buf err = %d",
+			   __func__, rc);
+		spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
+		return -EINVAL;
+	}
+	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, stats_type);
+	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq af ping buf from free buf queue", __func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_AF_BF_WR_PING_ADDR);
+	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, stats_type);
+	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq af pong buf from free buf queue", __func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_AF_BF_WR_PONG_ADDR);
+	return 0;
+}
+
+static uint32_t vfe_stats_bhist_buf_init(
+	struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	uint32_t addr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_BHIST);
+	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq ihist ping buf from free buf queue",
+			__func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_SKIN_BHIST_WR_PING_ADDR);
+	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_BHIST);
+	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq ihist pong buf from free buf queue",
+			__func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_SKIN_BHIST_WR_PONG_ADDR);
+
+	return 0;
+}
+
+static int vfe_stats_ihist_buf_init(
+	struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	uint32_t addr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_IHIST);
+	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq ihist ping buf from free buf queue",
+			__func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_HIST_WR_PING_ADDR);
+	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_IHIST);
+	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq ihist pong buf from free buf queue",
+			__func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_HIST_WR_PONG_ADDR);
+
+	return 0;
+}
+
+static int vfe_stats_rs_buf_init(
+	struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	uint32_t addr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_RS);
+	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq rs ping buf from free buf queue", __func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_RS_WR_PING_ADDR);
+	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_RS);
+	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq rs pong buf from free buf queue", __func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_RS_WR_PONG_ADDR);
+	return 0;
+}
+
+static int vfe_stats_cs_buf_init(
+	struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	uint32_t addr;
+	unsigned long flags;
+	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_CS);
+	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq cs ping buf from free buf queue", __func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_CS_WR_PING_ADDR);
+	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_CS);
+	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq cs pong buf from free buf queue", __func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe32_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_CS_WR_PONG_ADDR);
+	return 0;
+}
+
+static void vfe32_start_common(struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	CDBG("VFE opertaion mode = 0x%x, output mode = 0x%x\n",
+		vfe32_ctrl->share_ctrl->operation_mode,
+		vfe32_ctrl->share_ctrl->outpath.output_mode);
+	msm_camera_io_w_mb(1, vfe32_ctrl->share_ctrl->vfebase +
+		VFE_CAMIF_COMMAND);
+	msm_camera_io_w_mb(VFE_AXI_CFG_MASK,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_AXI_CFG);
+}
+
+static int vfe32_start_recording(
+	struct msm_cam_media_controller *pmctl,
+	struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	vfe32_ctrl->share_ctrl->recording_state = VFE_STATE_START_REQUESTED;
+	msm_camera_io_w_mb(1,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	return 0;
+}
+
+static int vfe32_stop_recording(
+	struct msm_cam_media_controller *pmctl,
+	struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	vfe32_ctrl->share_ctrl->recording_state = VFE_STATE_STOP_REQUESTED;
+	msm_camera_io_w_mb(1,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	return 0;
+}
+
+static void vfe32_start_liveshot(
+	struct msm_cam_media_controller *pmctl,
+	struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	/* Hardcode 1 live snapshot for now. */
+	vfe32_ctrl->share_ctrl->outpath.out0.capture_cnt = 1;
+	vfe32_ctrl->share_ctrl->vfe_capture_count =
+		vfe32_ctrl->share_ctrl->outpath.out0.capture_cnt;
+
+	vfe32_ctrl->share_ctrl->liveshot_state = VFE_STATE_START_REQUESTED;
+	msm_camera_io_w_mb(1, vfe32_ctrl->
+		share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+}
+
+static void vfe32_stop_liveshot(
+	struct msm_cam_media_controller *pmctl,
+	struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	vfe32_ctrl->share_ctrl->liveshot_state = VFE_STATE_STOP_REQUESTED;
+	msm_camera_io_w_mb(1,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+}
+
+static int vfe32_zsl(
+	struct msm_cam_media_controller *pmctl,
+	struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	vfe32_ctrl->share_ctrl->start_ack_pending = TRUE;
+	vfe32_start_common(vfe32_ctrl);
+
+	msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase + 0x18C);
+	msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase + 0x188);
+	return 0;
+}
+static int vfe32_capture_raw(
+	struct msm_cam_media_controller *pmctl,
+	struct vfe32_ctrl_type *vfe32_ctrl,
+	uint32_t num_frames_capture)
+{
+	vfe32_ctrl->share_ctrl->outpath.out0.capture_cnt = num_frames_capture;
+	vfe32_ctrl->share_ctrl->vfe_capture_count = num_frames_capture;
+	vfe32_start_common(vfe32_ctrl);
+	return 0;
+}
+
+static int vfe32_capture(
+	struct msm_cam_media_controller *pmctl,
+	uint32_t num_frames_capture,
+	struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	/* capture command is valid for both idle and active state. */
+	vfe32_ctrl->share_ctrl->outpath.out1.capture_cnt = num_frames_capture;
+	if (vfe32_ctrl->share_ctrl->current_mode ==
+			VFE_OUTPUTS_MAIN_AND_THUMB ||
+		vfe32_ctrl->share_ctrl->current_mode ==
+			VFE_OUTPUTS_THUMB_AND_MAIN ||
+		vfe32_ctrl->share_ctrl->current_mode ==
+			VFE_OUTPUTS_JPEG_AND_THUMB ||
+		vfe32_ctrl->share_ctrl->current_mode ==
+			VFE_OUTPUTS_THUMB_AND_JPEG) {
+		vfe32_ctrl->share_ctrl->outpath.out0.capture_cnt =
+			num_frames_capture;
+	}
+
+	vfe32_ctrl->share_ctrl->vfe_capture_count = num_frames_capture;
+
+	vfe32_ctrl->share_ctrl->vfe_capture_count = num_frames_capture;
+
+	vfe32_start_common(vfe32_ctrl);
+	/* for debug */
+	msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase + 0x18C);
+	msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase + 0x188);
+	return 0;
+}
+
+static int vfe32_start(
+	struct msm_cam_media_controller *pmctl,
+	struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	vfe32_start_common(vfe32_ctrl);
+	return 0;
+}
+
+static void vfe32_update(struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	unsigned long flags;
+	uint32_t value = 0;
+	if (vfe32_ctrl->update_linear) {
+		if (!msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase +
+			V32_LINEARIZATION_OFF1))
+			msm_camera_io_w(1,
+				vfe32_ctrl->share_ctrl->vfebase +
+				V32_LINEARIZATION_OFF1);
+		else
+			msm_camera_io_w(0,
+				vfe32_ctrl->share_ctrl->vfebase +
+				V32_LINEARIZATION_OFF1);
+		vfe32_ctrl->update_linear = false;
+	}
+
+	if (vfe32_ctrl->update_rolloff) {
+		value = msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
+			V33_PCA_ROLL_OFF_CFG_OFF1);
+		value ^= V33_PCA_ROLL_OFF_LUT_BANK_SEL_MASK;
+		msm_camera_io_w(value, vfe32_ctrl->share_ctrl->vfebase +
+			V33_PCA_ROLL_OFF_CFG_OFF1);
+		vfe32_ctrl->update_rolloff = false;
+	}
+
+	if (vfe32_ctrl->update_la) {
+		if (!msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + V32_LA_OFF))
+			msm_camera_io_w(1,
+				vfe32_ctrl->share_ctrl->vfebase + V32_LA_OFF);
+		else
+			msm_camera_io_w(0,
+				vfe32_ctrl->share_ctrl->vfebase + V32_LA_OFF);
+		vfe32_ctrl->update_la = false;
+	}
+
+	if (vfe32_ctrl->update_gamma) {
+		value = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + V32_RGB_G_OFF);
+		value ^= V32_GAMMA_LUT_BANK_SEL_MASK;
+		msm_camera_io_w(value,
+			vfe32_ctrl->share_ctrl->vfebase + V32_RGB_G_OFF);
+		vfe32_ctrl->update_gamma = false;
+	}
+
+	spin_lock_irqsave(&vfe32_ctrl->share_ctrl->update_ack_lock, flags);
+	vfe32_ctrl->share_ctrl->update_ack_pending = TRUE;
+	spin_unlock_irqrestore(&vfe32_ctrl->share_ctrl->update_ack_lock, flags);
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_camera_io_w_mb(1,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	return;
+}
+
+static void vfe32_sync_timer_stop(struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	uint32_t value = 0;
+	vfe32_ctrl->sync_timer_state = 0;
+	if (vfe32_ctrl->sync_timer_number == 0)
+		value = 0x10000;
+	else if (vfe32_ctrl->sync_timer_number == 1)
+		value = 0x20000;
+	else if (vfe32_ctrl->sync_timer_number == 2)
+		value = 0x40000;
+
+	/* Timer Stop */
+	msm_camera_io_w(value,
+		vfe32_ctrl->share_ctrl->vfebase + V32_SYNC_TIMER_OFF);
+}
+
+static void vfe32_sync_timer_start(
+	const uint32_t *tbl,
+	struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	/* set bit 8 for auto increment. */
+	uint32_t value = 1;
+	uint32_t val;
+
+	vfe32_ctrl->sync_timer_state = *tbl++;
+	vfe32_ctrl->sync_timer_repeat_count = *tbl++;
+	vfe32_ctrl->sync_timer_number = *tbl++;
+	CDBG("%s timer_state %d, repeat_cnt %d timer number %d\n",
+		 __func__, vfe32_ctrl->sync_timer_state,
+		 vfe32_ctrl->sync_timer_repeat_count,
+		 vfe32_ctrl->sync_timer_number);
+
+	if (vfe32_ctrl->sync_timer_state) { /* Start Timer */
+		value = value << vfe32_ctrl->sync_timer_number;
+	} else { /* Stop Timer */
+		CDBG("Failed to Start timer\n");
+		return;
+	}
+
+	/* Timer Start */
+	msm_camera_io_w(value,
+		vfe32_ctrl->share_ctrl->vfebase + V32_SYNC_TIMER_OFF);
+	/* Sync Timer Line Start */
+	value = *tbl++;
+	msm_camera_io_w(value,
+		vfe32_ctrl->share_ctrl->vfebase + V32_SYNC_TIMER_OFF +
+		4 + ((vfe32_ctrl->sync_timer_number) * 12));
+	/* Sync Timer Pixel Start */
+	value = *tbl++;
+	msm_camera_io_w(value,
+			vfe32_ctrl->share_ctrl->vfebase + V32_SYNC_TIMER_OFF +
+			 8 + ((vfe32_ctrl->sync_timer_number) * 12));
+	/* Sync Timer Pixel Duration */
+	value = *tbl++;
+	val = vfe_clk_rate / 10000;
+	val = 10000000 / val;
+	val = value * 10000 / val;
+	CDBG("%s: Pixel Clk Cycles!!! %d\n", __func__, val);
+	msm_camera_io_w(val,
+		vfe32_ctrl->share_ctrl->vfebase + V32_SYNC_TIMER_OFF +
+		12 + ((vfe32_ctrl->sync_timer_number) * 12));
+	/* Timer0 Active High/LOW */
+	value = *tbl++;
+	msm_camera_io_w(value,
+		vfe32_ctrl->share_ctrl->vfebase + V32_SYNC_TIMER_POLARITY_OFF);
+	/* Selects sync timer 0 output to drive onto timer1 port */
+	value = 0;
+	msm_camera_io_w(value,
+		vfe32_ctrl->share_ctrl->vfebase + V32_TIMER_SELECT_OFF);
+}
+
+
+static void vfe32_write_gamma_cfg(
+	enum VFE32_DMI_RAM_SEL channel_sel,
+	const uint32_t *tbl,
+	struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	int i;
+	uint32_t value, value1, value2;
+	vfe32_program_dmi_cfg(channel_sel, vfe32_ctrl);
+	for (i = 0 ; i < (VFE32_GAMMA_NUM_ENTRIES/2) ; i++) {
+		value = *tbl++;
+		value1 = value & 0x0000FFFF;
+		value2 = (value & 0xFFFF0000)>>16;
+		msm_camera_io_w((value1),
+			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
+		msm_camera_io_w((value2),
+			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
+	}
+	vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
+}
+
+static void vfe32_read_gamma_cfg(
+	enum VFE32_DMI_RAM_SEL channel_sel,
+	uint32_t *tbl,
+	struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	int i;
+	vfe32_program_dmi_cfg(channel_sel, vfe32_ctrl);
+	CDBG("%s: Gamma table channel: %d\n", __func__, channel_sel);
+	for (i = 0 ; i < VFE32_GAMMA_NUM_ENTRIES ; i++) {
+		*tbl = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
+		CDBG("%s: %08x\n", __func__, *tbl);
+		tbl++;
+	}
+	vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
+}
+
+static void vfe32_write_la_cfg(
+	enum VFE32_DMI_RAM_SEL channel_sel,
+	const uint32_t *tbl,
+	struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	uint32_t i;
+	uint32_t value, value1, value2;
+
+	vfe32_program_dmi_cfg(channel_sel, vfe32_ctrl);
+	for (i = 0 ; i < (VFE32_LA_TABLE_LENGTH/2) ; i++) {
+		value = *tbl++;
+		value1 = value & 0x0000FFFF;
+		value2 = (value & 0xFFFF0000)>>16;
+		msm_camera_io_w((value1),
+			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
+		msm_camera_io_w((value2),
+			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
+	}
+	vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
+}
+
+static struct vfe32_output_ch *vfe32_get_ch(
+	int path, struct vfe_share_ctrl_t *share_ctrl)
+{
+	struct vfe32_output_ch *ch = NULL;
+
+	if (path == VFE_MSG_OUTPUT_PRIMARY)
+		ch = &share_ctrl->outpath.out0;
+	else if (path == VFE_MSG_OUTPUT_SECONDARY)
+		ch = &share_ctrl->outpath.out1;
+	else if (path == VFE_MSG_OUTPUT_TERTIARY1)
+		ch = &share_ctrl->outpath.out2;
+	else if (path == VFE_MSG_OUTPUT_TERTIARY2)
+		ch = &share_ctrl->outpath.out3;
+	else
+		pr_err("%s: Invalid path %d\n", __func__,
+			path);
+
+	BUG_ON(ch == NULL);
+	return ch;
+}
+static struct msm_free_buf *vfe32_check_free_buffer(
+	int id, int path, struct axi_ctrl_t *axi_ctrl)
+{
+	struct vfe32_output_ch *outch = NULL;
+	struct msm_free_buf *b = NULL;
+	uint32_t inst_handle = 0;
+
+	if (path == VFE_MSG_OUTPUT_PRIMARY)
+		inst_handle = axi_ctrl->share_ctrl->outpath.out0.inst_handle;
+	else if (path == VFE_MSG_OUTPUT_SECONDARY)
+		inst_handle = axi_ctrl->share_ctrl->outpath.out1.inst_handle;
+	else if (path == VFE_MSG_OUTPUT_TERTIARY1)
+		inst_handle = axi_ctrl->share_ctrl->outpath.out2.inst_handle;
+	else if (path == VFE_MSG_OUTPUT_TERTIARY2)
+		inst_handle = axi_ctrl->share_ctrl->outpath.out3.inst_handle;
+
+	vfe32_subdev_notify(id, path, inst_handle,
+		&axi_ctrl->subdev, axi_ctrl->share_ctrl);
+	outch = vfe32_get_ch(path, axi_ctrl->share_ctrl);
+	if (outch->free_buf.ch_paddr[0])
+		b = &outch->free_buf;
+	return b;
+}
+static int configure_pingpong_buffers(
+	int id, int path, struct axi_ctrl_t *axi_ctrl)
+{
+	struct vfe32_output_ch *outch = NULL;
+	int rc = 0;
+	uint32_t inst_handle = 0;
+	if (path == VFE_MSG_OUTPUT_PRIMARY)
+		inst_handle = axi_ctrl->share_ctrl->outpath.out0.inst_handle;
+	else if (path == VFE_MSG_OUTPUT_SECONDARY)
+		inst_handle = axi_ctrl->share_ctrl->outpath.out1.inst_handle;
+	else if (path == VFE_MSG_OUTPUT_TERTIARY1)
+		inst_handle = axi_ctrl->share_ctrl->outpath.out2.inst_handle;
+	else if (path == VFE_MSG_OUTPUT_TERTIARY2)
+		inst_handle = axi_ctrl->share_ctrl->outpath.out3.inst_handle;
+
+	vfe32_subdev_notify(id, path, inst_handle,
+		&axi_ctrl->subdev, axi_ctrl->share_ctrl);
+	outch = vfe32_get_ch(path, axi_ctrl->share_ctrl);
+	if (outch->ping.ch_paddr[0] && outch->pong.ch_paddr[0]) {
+		/* Configure Preview Ping Pong */
+		pr_info("%s Configure ping/pong address for %d",
+						__func__, path);
+		vfe32_put_ch_ping_addr(
+			axi_ctrl->share_ctrl->vfebase, outch->ch0,
+			outch->ping.ch_paddr[0]);
+		vfe32_put_ch_pong_addr(
+			axi_ctrl->share_ctrl->vfebase, outch->ch0,
+			outch->pong.ch_paddr[0]);
+
+		if ((axi_ctrl->share_ctrl->current_mode !=
+			VFE_OUTPUTS_RAW) && (path != VFE_MSG_OUTPUT_TERTIARY1)
+			&& (path != VFE_MSG_OUTPUT_TERTIARY2)) {
+			vfe32_put_ch_ping_addr(
+				axi_ctrl->share_ctrl->vfebase, outch->ch1,
+				outch->ping.ch_paddr[1]);
+			vfe32_put_ch_pong_addr(
+				axi_ctrl->share_ctrl->vfebase, outch->ch1,
+				outch->pong.ch_paddr[1]);
+		}
+
+		if (outch->ping.num_planes > 2)
+			vfe32_put_ch_ping_addr(
+				axi_ctrl->share_ctrl->vfebase, outch->ch2,
+				outch->ping.ch_paddr[2]);
+		if (outch->pong.num_planes > 2)
+			vfe32_put_ch_pong_addr(
+				axi_ctrl->share_ctrl->vfebase, outch->ch2,
+				outch->pong.ch_paddr[2]);
+
+		/* avoid stale info */
+		memset(&outch->ping, 0, sizeof(struct msm_free_buf));
+		memset(&outch->pong, 0, sizeof(struct msm_free_buf));
+	} else {
+		pr_err("%s ping/pong addr is null!!", __func__);
+		rc = -EINVAL;
+	}
+	return rc;
+}
+
+static void vfe32_write_linear_cfg(
+	enum VFE32_DMI_RAM_SEL channel_sel,
+	const uint32_t *tbl, struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	uint32_t i;
+
+	vfe32_program_dmi_cfg(channel_sel, vfe32_ctrl);
+	/* for loop for configuring LUT. */
+	for (i = 0 ; i < VFE32_LINEARIZATON_TABLE_LENGTH ; i++) {
+		msm_camera_io_w(*tbl,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
+		tbl++;
+	}
+	CDBG("done writing to linearization table\n");
+	vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
+}
+
+static void vfe32_send_isp_msg(
+	struct v4l2_subdev *sd,
+	uint32_t vfeFrameId,
+	uint32_t isp_msg_id)
+{
+	struct isp_msg_event isp_msg_evt;
+
+	isp_msg_evt.msg_id = isp_msg_id;
+	isp_msg_evt.sof_count = vfeFrameId;
+	v4l2_subdev_notify(sd,
+			NOTIFY_ISP_MSG_EVT,
+			(void *)&isp_msg_evt);
+}
+
+static int vfe32_proc_general(
+	struct msm_cam_media_controller *pmctl,
+	struct msm_isp_cmd *cmd,
+	struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	int i , rc = 0;
+	uint32_t old_val = 0 , new_val = 0, module_val = 0;
+	uint32_t *cmdp = NULL;
+	uint32_t *cmdp_local = NULL;
+	uint32_t snapshot_cnt = 0;
+	uint32_t temp1 = 0, temp2 = 0;
+	struct msm_camera_vfe_params_t vfe_params;
+
+	CDBG("vfe32_proc_general: cmdID = %s, length = %d\n",
+		vfe32_general_cmd[cmd->id], cmd->length);
+	switch (cmd->id) {
+	case VFE_CMD_RESET:
+		pr_info("vfe32_proc_general: cmdID = %s\n",
+			vfe32_general_cmd[cmd->id]);
+		vfe32_ctrl->share_ctrl->vfe_reset_flag = true;
+		vfe32_reset(vfe32_ctrl);
+		break;
+	case VFE_CMD_START:
+		pr_info("vfe32_proc_general: cmdID = %s\n",
+			vfe32_general_cmd[cmd->id]);
+		if (copy_from_user(&vfe_params,
+				(void __user *)(cmd->value),
+				sizeof(struct msm_camera_vfe_params_t))) {
+				rc = -EFAULT;
+				goto proc_general_done;
+		}
+
+		vfe32_ctrl->share_ctrl->current_mode =
+			vfe_params.operation_mode;
+
+		rc = vfe32_start(pmctl, vfe32_ctrl);
+		break;
+	case VFE_CMD_UPDATE:
+		vfe32_update(vfe32_ctrl);
+		break;
+	case VFE_CMD_CAPTURE_RAW:
+		pr_info("%s: cmdID = VFE_CMD_CAPTURE_RAW\n", __func__);
+		if (copy_from_user(&vfe_params,
+				(void __user *)(cmd->value),
+				sizeof(struct msm_camera_vfe_params_t))) {
+				rc = -EFAULT;
+				goto proc_general_done;
+		}
+
+		snapshot_cnt = vfe_params.capture_count;
+		vfe32_ctrl->share_ctrl->current_mode =
+			vfe_params.operation_mode;
+		rc = vfe32_capture_raw(pmctl, vfe32_ctrl, snapshot_cnt);
+		break;
+	case VFE_CMD_CAPTURE:
+		if (copy_from_user(&vfe_params,
+				(void __user *)(cmd->value),
+				sizeof(struct msm_camera_vfe_params_t))) {
+				rc = -EFAULT;
+				goto proc_general_done;
+		}
+
+		snapshot_cnt = vfe_params.capture_count;
+		vfe32_ctrl->share_ctrl->current_mode =
+			vfe_params.operation_mode;
+
+		rc = vfe32_capture(pmctl, snapshot_cnt, vfe32_ctrl);
+		break;
+	case VFE_CMD_START_RECORDING:
+		pr_info("vfe32_proc_general: cmdID = %s\n",
+			vfe32_general_cmd[cmd->id]);
+		rc = vfe32_start_recording(pmctl, vfe32_ctrl);
+		break;
+	case VFE_CMD_STOP_RECORDING:
+		pr_info("vfe32_proc_general: cmdID = %s\n",
+			vfe32_general_cmd[cmd->id]);
+		rc = vfe32_stop_recording(pmctl, vfe32_ctrl);
+		break;
+	case VFE_CMD_OPERATION_CFG: {
+		if (cmd->length != V32_OPERATION_CFG_LEN) {
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(V32_OPERATION_CFG_LEN, GFP_ATOMIC);
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			V32_OPERATION_CFG_LEN)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		rc = vfe32_operation_config(cmdp, vfe32_ctrl);
+		}
+		break;
+
+	case VFE_CMD_STATS_AE_START: {
+		if (vfe32_use_bayer_stats(vfe32_ctrl)) {
+			/* Error */
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		rc = vfe_stats_aec_bg_buf_init(vfe32_ctrl);
+		if (rc < 0) {
+			pr_err("%s: cannot config ping/pong address of AEC",
+				 __func__);
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val |= AE_BG_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
+			cmdp, (vfe32_cmd[cmd->id].length));
+		}
+		break;
+	case VFE_CMD_STATS_AF_START: {
+		if (vfe32_use_bayer_stats(vfe32_ctrl)) {
+			/* Error */
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		rc = vfe_stats_af_bf_buf_init(vfe32_ctrl);
+		if (rc < 0) {
+			pr_err("%s: cannot config ping/pong address of AF",
+				__func__);
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
+			VFE_MODULE_CFG);
+		old_val |= AF_BF_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
+			cmdp, (vfe32_cmd[cmd->id].length));
+		}
+		break;
+	case VFE_CMD_STATS_AWB_START: {
+		if (vfe32_use_bayer_stats(vfe32_ctrl)) {
+			/* Error */
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		rc = vfe_stats_awb_buf_init(vfe32_ctrl, NULL);
+		if (rc < 0) {
+			pr_err("%s: cannot config ping/pong address of AWB",
+				 __func__);
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val |= AWB_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
+			cmdp, (vfe32_cmd[cmd->id].length));
+		}
+		break;
+
+	case VFE_CMD_STATS_IHIST_START: {
+		rc = vfe_stats_ihist_buf_init(vfe32_ctrl);
+		if (rc < 0) {
+			pr_err("%s: cannot config ping/pong address of IHIST",
+				 __func__);
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val |= IHIST_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
+			cmdp, (vfe32_cmd[cmd->id].length));
+		}
+		break;
+
+
+	case VFE_CMD_STATS_RS_START: {
+		rc = vfe_stats_rs_buf_init(vfe32_ctrl);
+		if (rc < 0) {
+			pr_err("%s: cannot config ping/pong address of RS",
+				__func__);
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
+			cmdp, (vfe32_cmd[cmd->id].length));
+		}
+		break;
+
+	case VFE_CMD_STATS_CS_START: {
+		rc = vfe_stats_cs_buf_init(vfe32_ctrl);
+		if (rc < 0) {
+			pr_err("%s: cannot config ping/pong address of CS",
+				__func__);
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
+			cmdp, (vfe32_cmd[cmd->id].length));
+		}
+		break;
+
+	case VFE_CMD_STATS_BG_START:
+	case VFE_CMD_STATS_BF_START:
+	case VFE_CMD_STATS_BHIST_START: {
+		if (!vfe32_use_bayer_stats(vfe32_ctrl)) {
+			/* Error */
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + VFE_STATS_CFG);
+		module_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		if (VFE_CMD_STATS_BG_START == cmd->id) {
+			module_val |= AE_BG_ENABLE_MASK;
+			old_val |= STATS_BG_ENABLE_MASK;
+			rc = vfe_stats_aec_bg_buf_init(vfe32_ctrl);
+			if (rc < 0) {
+				pr_err("%s: cannot config ping/pong address of CS",
+					__func__);
+				goto proc_general_done;
+			}
+		} else if (VFE_CMD_STATS_BF_START == cmd->id) {
+			module_val |= AF_BF_ENABLE_MASK;
+			old_val |= STATS_BF_ENABLE_MASK;
+			rc = vfe_stats_af_bf_buf_init(vfe32_ctrl);
+			if (rc < 0) {
+				pr_err("%s: cannot config ping/pong address of CS",
+					__func__);
+				goto proc_general_done;
+			}
+		} else {
+			module_val |= SKIN_BHIST_ENABLE_MASK;
+			old_val |= STATS_BHIST_ENABLE_MASK;
+			rc = vfe_stats_bhist_buf_init(vfe32_ctrl);
+			if (rc < 0) {
+				pr_err("%s: cannot config ping/pong address of CS",
+					__func__);
+				goto proc_general_done;
+			}
+		}
+		msm_camera_io_w(old_val, vfe32_ctrl->share_ctrl->vfebase +
+			VFE_STATS_CFG);
+		msm_camera_io_w(module_val,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+				(void __user *)(cmd->value),
+				cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
+			cmdp, (vfe32_cmd[cmd->id].length));
+		}
+		break;
+	case VFE_CMD_MCE_UPDATE:
+	case VFE_CMD_MCE_CFG:{
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		/* Incrementing with 4 so as to point to the 2nd Register as
+		the 2nd register has the mce_enable bit */
+		old_val = msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
+			V32_CHROMA_SUP_OFF + 4);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		new_val = *cmdp_local;
+		old_val &= MCE_EN_MASK;
+		new_val = new_val | old_val;
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase +
+			V32_CHROMA_SUP_OFF + 4, &new_val, 4);
+		cmdp_local += 1;
+
+		old_val = msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
+			V32_CHROMA_SUP_OFF + 8);
+		new_val = *cmdp_local;
+		old_val &= MCE_Q_K_MASK;
+		new_val = new_val | old_val;
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase +
+			V32_CHROMA_SUP_OFF + 8, &new_val, 4);
+		cmdp_local += 1;
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
+			cmdp_local, (vfe32_cmd[cmd->id].length));
+		}
+		break;
+	case VFE_CMD_CHROMA_SUP_UPDATE:
+	case VFE_CMD_CHROMA_SUP_CFG:{
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		msm_camera_io_memcpy(vfe32_ctrl->share_ctrl->vfebase +
+			V32_CHROMA_SUP_OFF, cmdp_local, 4);
+
+		cmdp_local += 1;
+		new_val = *cmdp_local;
+		/* Incrementing with 4 so as to point to the 2nd Register as
+		 * the 2nd register has the mce_enable bit
+		 */
+		old_val = msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
+			V32_CHROMA_SUP_OFF + 4);
+		old_val &= ~MCE_EN_MASK;
+		new_val = new_val | old_val;
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase +
+			V32_CHROMA_SUP_OFF + 4, &new_val, 4);
+		cmdp_local += 1;
+
+		old_val = msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
+			V32_CHROMA_SUP_OFF + 8);
+		new_val = *cmdp_local;
+		old_val &= ~MCE_Q_K_MASK;
+		new_val = new_val | old_val;
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase +
+			V32_CHROMA_SUP_OFF + 8, &new_val, 4);
+		}
+		break;
+	case VFE_CMD_BLACK_LEVEL_CFG:
+		rc = -EFAULT;
+		goto proc_general_done;
+
+	case VFE_CMD_MESH_ROLL_OFF_CFG: {
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value) , cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
+			cmdp_local, 16);
+		cmdp_local += 4;
+		vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK0, vfe32_ctrl);
+		/* for loop for extrcting init table. */
+		for (i = 0; i < (V32_MESH_ROLL_OFF_INIT_TABLE_SIZE * 2); i++) {
+			msm_camera_io_w(*cmdp_local ,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
+			cmdp_local++;
+		}
+		CDBG("done writing init table\n");
+		/* by default, always starts with offset 0. */
+		msm_camera_io_w(V32_MESH_ROLL_OFF_DELTA_TABLE_OFFSET,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_ADDR);
+		/* for loop for extracting delta table. */
+		for (i = 0; i < (V32_MESH_ROLL_OFF_DELTA_TABLE_SIZE * 2); i++) {
+			msm_camera_io_w(*cmdp_local,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
+			cmdp_local++;
+		}
+		vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
+		}
+		break;
+
+	case VFE_CMD_GET_MESH_ROLLOFF_TABLE:
+		temp1 = sizeof(uint32_t) * ((V32_MESH_ROLL_OFF_INIT_TABLE_SIZE *
+			2) + (V32_MESH_ROLL_OFF_DELTA_TABLE_SIZE * 2));
+		if (cmd->length != temp1) {
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		cmdp = kzalloc(temp1, GFP_KERNEL);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK0, vfe32_ctrl);
+		CDBG("%s: Mesh Rolloff init Table\n", __func__);
+		for (i = 0; i < (V32_MESH_ROLL_OFF_INIT_TABLE_SIZE * 2); i++) {
+			*cmdp_local =
+				msm_camera_io_r(
+					vfe32_ctrl->share_ctrl->vfebase +
+					VFE_DMI_DATA_LO);
+			CDBG("%s: %08x\n", __func__, *cmdp_local);
+			cmdp_local++;
+		}
+		msm_camera_io_w(V32_MESH_ROLL_OFF_DELTA_TABLE_OFFSET,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_ADDR);
+		CDBG("%s: Mesh Rolloff Delta Table\n", __func__);
+		for (i = 0; i < (V32_MESH_ROLL_OFF_DELTA_TABLE_SIZE * 2); i++) {
+			*cmdp_local =
+				msm_camera_io_r(
+					vfe32_ctrl->share_ctrl->vfebase +
+					VFE_DMI_DATA_LO);
+			CDBG("%s: %08x\n", __func__, *cmdp_local);
+			cmdp_local++;
+		}
+		CDBG("done reading delta table\n");
+		vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
+		if (copy_to_user((void __user *)(cmd->value), cmdp,
+			temp1)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		break;
+	case VFE_CMD_LA_CFG:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
+			cmdp_local, (vfe32_cmd[cmd->id].length));
+
+		cmdp_local += 1;
+		vfe32_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK0,
+						   cmdp_local, vfe32_ctrl);
+		break;
+
+	case VFE_CMD_LA_UPDATE: {
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+
+		cmdp_local = cmdp + 1;
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + V32_LA_OFF);
+		if (old_val != 0x0)
+			vfe32_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK0,
+				cmdp_local, vfe32_ctrl);
+		else
+			vfe32_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK1,
+				cmdp_local, vfe32_ctrl);
+		}
+		vfe32_ctrl->update_la = true;
+		break;
+
+	case VFE_CMD_GET_LA_TABLE:
+		temp1 = sizeof(uint32_t) * VFE32_LA_TABLE_LENGTH / 2;
+		if (cmd->length != temp1) {
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		cmdp = kzalloc(temp1, GFP_KERNEL);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		if (msm_camera_io_r(vfe32_ctrl->
+				share_ctrl->vfebase + V32_LA_OFF))
+			vfe32_program_dmi_cfg(LUMA_ADAPT_LUT_RAM_BANK1,
+						vfe32_ctrl);
+		else
+			vfe32_program_dmi_cfg(LUMA_ADAPT_LUT_RAM_BANK0,
+						vfe32_ctrl);
+		for (i = 0 ; i < (VFE32_LA_TABLE_LENGTH / 2) ; i++) {
+			*cmdp_local =
+				msm_camera_io_r(
+					vfe32_ctrl->share_ctrl->vfebase +
+					VFE_DMI_DATA_LO);
+			*cmdp_local |= (msm_camera_io_r(
+				vfe32_ctrl->share_ctrl->vfebase +
+				VFE_DMI_DATA_LO)) << 16;
+			cmdp_local++;
+		}
+		vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
+		if (copy_to_user((void __user *)(cmd->value), cmdp,
+			temp1)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		break;
+	case VFE_CMD_SK_ENHAN_CFG:
+	case VFE_CMD_SK_ENHAN_UPDATE:{
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase + V32_SCE_OFF,
+			cmdp, V32_SCE_LEN);
+		}
+		break;
+
+	case VFE_CMD_LIVESHOT:
+		/* Configure primary channel */
+		vfe32_start_liveshot(pmctl, vfe32_ctrl);
+		break;
+
+	case VFE_CMD_LINEARIZATION_CFG:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp, (void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase +
+			V32_LINEARIZATION_OFF1,
+			cmdp_local, V32_LINEARIZATION_LEN1);
+		cmdp_local += 4;
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase +
+			V32_LINEARIZATION_OFF2,
+			cmdp_local, V32_LINEARIZATION_LEN2);
+
+		cmdp_local = cmdp + 17;
+		vfe32_write_linear_cfg(BLACK_LUT_RAM_BANK0,
+					cmdp_local, vfe32_ctrl);
+		break;
+
+	case VFE_CMD_LINEARIZATION_UPDATE:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp, (void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		cmdp_local++;
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase +
+			V32_LINEARIZATION_OFF1 + 4,
+			cmdp_local, (V32_LINEARIZATION_LEN1 - 4));
+		cmdp_local += 3;
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase +
+			V32_LINEARIZATION_OFF2,
+			cmdp_local, V32_LINEARIZATION_LEN2);
+		cmdp_local = cmdp + 17;
+		/*extracting the bank select*/
+		old_val = msm_camera_io_r(
+				vfe32_ctrl->share_ctrl->vfebase +
+				V32_LINEARIZATION_OFF1);
+
+		if (old_val != 0x0)
+			vfe32_write_linear_cfg(BLACK_LUT_RAM_BANK0,
+						cmdp_local, vfe32_ctrl);
+		else
+			vfe32_write_linear_cfg(BLACK_LUT_RAM_BANK1,
+						cmdp_local, vfe32_ctrl);
+		vfe32_ctrl->update_linear = true;
+		break;
+
+	case VFE_CMD_GET_LINEARIZATON_TABLE:
+		temp1 = sizeof(uint32_t) * VFE32_LINEARIZATON_TABLE_LENGTH;
+		if (cmd->length != temp1) {
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		cmdp = kzalloc(temp1, GFP_KERNEL);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		if (msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase +
+			V32_LINEARIZATION_OFF1))
+			vfe32_program_dmi_cfg(BLACK_LUT_RAM_BANK1, vfe32_ctrl);
+		else
+			vfe32_program_dmi_cfg(BLACK_LUT_RAM_BANK0, vfe32_ctrl);
+		CDBG("%s: Linearization Table\n", __func__);
+		for (i = 0 ; i < VFE32_LINEARIZATON_TABLE_LENGTH ; i++) {
+			*cmdp_local = msm_camera_io_r(
+				vfe32_ctrl->share_ctrl->vfebase +
+				VFE_DMI_DATA_LO);
+			CDBG("%s: %08x\n", __func__, *cmdp_local);
+			cmdp_local++;
+		}
+		vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
+		if (copy_to_user((void __user *)(cmd->value), cmdp,
+			temp1)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		break;
+	case VFE_CMD_DEMOSAICV3:
+		if (cmd->length !=
+			V32_DEMOSAICV3_0_LEN+V32_DEMOSAICV3_1_LEN) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		new_val = *cmdp_local;
+
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF);
+		old_val &= DEMOSAIC_MASK;
+		new_val = new_val | old_val;
+		*cmdp_local = new_val;
+
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF,
+			cmdp_local, V32_DEMOSAICV3_0_LEN);
+		cmdp_local += 1;
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_1_OFF,
+			cmdp_local, V32_DEMOSAICV3_1_LEN);
+		break;
+
+	case VFE_CMD_DEMOSAICV3_UPDATE:
+		if (cmd->length !=
+			V32_DEMOSAICV3_0_LEN * V32_DEMOSAICV3_UP_REG_CNT) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		new_val = *cmdp_local;
+
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF);
+		old_val &= DEMOSAIC_MASK;
+		new_val = new_val | old_val;
+		*cmdp_local = new_val;
+
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF,
+			cmdp_local, V32_DEMOSAICV3_0_LEN);
+		/* As the address space is not contiguous increment by 2
+		 * before copying to next address space */
+		cmdp_local += 1;
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_1_OFF,
+			cmdp_local, 2 * V32_DEMOSAICV3_0_LEN);
+		/* As the address space is not contiguous increment by 2
+		 * before copying to next address space */
+		cmdp_local += 2;
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_2_OFF,
+			cmdp_local, 2 * V32_DEMOSAICV3_0_LEN);
+		break;
+
+	case VFE_CMD_DEMOSAICV3_ABCC_CFG:
+		rc = -EFAULT;
+		break;
+
+	case VFE_CMD_DEMOSAICV3_ABF_UPDATE:/* 116 ABF update  */
+	case VFE_CMD_DEMOSAICV3_ABF_CFG: { /* 108 ABF config  */
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		new_val = *cmdp_local;
+
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF);
+		old_val &= ABF_MASK;
+		new_val = new_val | old_val;
+		*cmdp_local = new_val;
+
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF,
+			cmdp_local, 4);
+
+		cmdp_local += 1;
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
+			cmdp_local, (vfe32_cmd[cmd->id].length));
+		}
+		break;
+
+	case VFE_CMD_DEMOSAICV3_DBCC_CFG:
+	case VFE_CMD_DEMOSAICV3_DBCC_UPDATE:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		new_val = *cmdp_local;
+
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF);
+		old_val &= DBCC_MASK;
+
+		new_val = new_val | old_val;
+		*cmdp_local = new_val;
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF,
+			cmdp_local, 4);
+		cmdp_local += 1;
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
+			cmdp_local, (vfe32_cmd[cmd->id].length));
+		break;
+
+	case VFE_CMD_DEMOSAICV3_DBPC_CFG:
+	case VFE_CMD_DEMOSAICV3_DBPC_UPDATE:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		new_val = *cmdp_local;
+
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF);
+		old_val &= DBPC_MASK;
+
+		new_val = new_val | old_val;
+		*cmdp_local = new_val;
+		msm_camera_io_memcpy(vfe32_ctrl->share_ctrl->vfebase +
+			V32_DEMOSAICV3_0_OFF,
+			cmdp_local, V32_DEMOSAICV3_LEN);
+		cmdp_local += 1;
+		msm_camera_io_memcpy(vfe32_ctrl->share_ctrl->vfebase +
+			V32_DEMOSAICV3_DBPC_CFG_OFF,
+			cmdp_local, V32_DEMOSAICV3_DBPC_LEN);
+		cmdp_local += 1;
+		msm_camera_io_memcpy(vfe32_ctrl->share_ctrl->vfebase +
+			V32_DEMOSAICV3_DBPC_CFG_OFF0,
+			cmdp_local, V32_DEMOSAICV3_DBPC_LEN);
+		cmdp_local += 1;
+		msm_camera_io_memcpy(vfe32_ctrl->share_ctrl->vfebase +
+			V32_DEMOSAICV3_DBPC_CFG_OFF1,
+			cmdp_local, V32_DEMOSAICV3_DBPC_LEN);
+		cmdp_local += 1;
+		msm_camera_io_memcpy(vfe32_ctrl->share_ctrl->vfebase +
+			V32_DEMOSAICV3_DBPC_CFG_OFF2,
+			cmdp_local, V32_DEMOSAICV3_DBPC_LEN);
+		break;
+
+	case VFE_CMD_RGB_G_CFG: {
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase + V32_RGB_G_OFF,
+			cmdp, 4);
+		cmdp += 1;
+
+		vfe32_write_gamma_cfg(RGBLUT_RAM_CH0_BANK0, cmdp, vfe32_ctrl);
+		vfe32_write_gamma_cfg(RGBLUT_RAM_CH1_BANK0, cmdp, vfe32_ctrl);
+		vfe32_write_gamma_cfg(RGBLUT_RAM_CH2_BANK0, cmdp, vfe32_ctrl);
+		}
+	    cmdp -= 1;
+		break;
+
+	case VFE_CMD_RGB_G_UPDATE: {
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp, (void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + V32_RGB_G_OFF);
+		cmdp += 1;
+		if (old_val != 0x0) {
+			vfe32_write_gamma_cfg(
+				RGBLUT_RAM_CH0_BANK0, cmdp, vfe32_ctrl);
+			vfe32_write_gamma_cfg(
+				RGBLUT_RAM_CH1_BANK0, cmdp, vfe32_ctrl);
+			vfe32_write_gamma_cfg(
+				RGBLUT_RAM_CH2_BANK0, cmdp, vfe32_ctrl);
+		} else {
+			vfe32_write_gamma_cfg(
+				RGBLUT_RAM_CH0_BANK1, cmdp, vfe32_ctrl);
+			vfe32_write_gamma_cfg(
+				RGBLUT_RAM_CH1_BANK1, cmdp, vfe32_ctrl);
+			vfe32_write_gamma_cfg(
+				RGBLUT_RAM_CH2_BANK1, cmdp, vfe32_ctrl);
+		}
+		}
+		vfe32_ctrl->update_gamma = TRUE;
+		cmdp -= 1;
+		break;
+
+	case VFE_CMD_GET_RGB_G_TABLE:
+		temp1 = sizeof(uint32_t) * VFE32_GAMMA_NUM_ENTRIES * 3;
+		if (cmd->length != temp1) {
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		cmdp = kzalloc(temp1, GFP_KERNEL);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + V32_RGB_G_OFF);
+		temp2 = old_val ? RGBLUT_RAM_CH0_BANK1 :
+			RGBLUT_RAM_CH0_BANK0;
+		for (i = 0; i < 3; i++) {
+			vfe32_read_gamma_cfg(temp2,
+				cmdp_local + (VFE32_GAMMA_NUM_ENTRIES * i),
+				vfe32_ctrl);
+			temp2 += 2;
+		}
+		if (copy_to_user((void __user *)(cmd->value), cmdp,
+			temp1)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		break;
+
+	case VFE_CMD_STATS_AWB_STOP: {
+		if (vfe32_use_bayer_stats(vfe32_ctrl)) {
+			/* Error */
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~AWB_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		}
+		break;
+	case VFE_CMD_STATS_AE_STOP: {
+		if (vfe32_use_bayer_stats(vfe32_ctrl)) {
+			/* Error */
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~AE_BG_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		}
+		break;
+	case VFE_CMD_STATS_AF_STOP: {
+		if (vfe32_use_bayer_stats(vfe32_ctrl)) {
+			/* Error */
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~AF_BF_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		}
+		break;
+
+	case VFE_CMD_STATS_IHIST_STOP: {
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~IHIST_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		}
+		break;
+
+	case VFE_CMD_STATS_RS_STOP: {
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~RS_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		}
+		break;
+
+	case VFE_CMD_STATS_CS_STOP: {
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~CS_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		}
+		break;
+
+	case VFE_CMD_STATS_BG_STOP:
+	case VFE_CMD_STATS_BF_STOP:
+	case VFE_CMD_STATS_BHIST_STOP: {
+		if (!vfe32_use_bayer_stats(vfe32_ctrl)) {
+			/* Error */
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + VFE_STATS_CFG);
+		if (VFE_CMD_STATS_BG_STOP == cmd->id)
+			old_val &= ~STATS_BG_ENABLE_MASK;
+		else if (VFE_CMD_STATS_BF_STOP == cmd->id)
+			old_val &= ~STATS_BF_ENABLE_MASK;
+		else
+			old_val &= ~STATS_BHIST_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_STATS_CFG);
+		if (VFE_CMD_STATS_BF_STOP == cmd->id) {
+			rc = vfe32_stats_flush_enqueue(vfe32_ctrl,
+					MSM_STATS_TYPE_BF);
+			if (rc < 0) {
+				pr_err("%s: dq stats buf err = %d",
+					   __func__, rc);
+				return -EINVAL;
+			}
+		}
+		}
+		break;
+
+	case VFE_CMD_STOP:
+		pr_info("vfe32_proc_general: cmdID = %s\n",
+			vfe32_general_cmd[cmd->id]);
+		if (copy_from_user(&vfe_params,
+				(void __user *)(cmd->value),
+				sizeof(struct msm_camera_vfe_params_t))) {
+				rc = -EFAULT;
+				goto proc_general_done;
+		}
+
+		vfe32_stop(vfe32_ctrl);
+		break;
+
+	case VFE_CMD_SYNC_TIMER_SETTING:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp, (void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		vfe32_sync_timer_start(cmdp, vfe32_ctrl);
+		break;
+
+	case VFE_CMD_MODULE_CFG: {
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		*cmdp &= ~STATS_ENABLE_MASK;
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= STATS_ENABLE_MASK;
+		*cmdp |= old_val;
+
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
+			cmdp, (vfe32_cmd[cmd->id].length));
+		}
+		break;
+
+	case VFE_CMD_ZSL:
+		if (copy_from_user(&vfe_params,
+				(void __user *)(cmd->value),
+				sizeof(struct msm_camera_vfe_params_t))) {
+				rc = -EFAULT;
+				goto proc_general_done;
+		}
+
+		vfe32_ctrl->share_ctrl->current_mode =
+			vfe_params.operation_mode;
+
+		rc = vfe32_zsl(pmctl, vfe32_ctrl);
+		break;
+
+	case VFE_CMD_ASF_CFG:
+	case VFE_CMD_ASF_UPDATE:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp, (void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
+			cmdp, (vfe32_cmd[cmd->id].length));
+		cmdp_local = cmdp + V32_ASF_LEN/4;
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase +
+			V32_ASF_SPECIAL_EFX_CFG_OFF,
+			cmdp_local, V32_ASF_SPECIAL_EFX_CFG_LEN);
+		break;
+
+	case VFE_CMD_PCA_ROLL_OFF_CFG:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value) , cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+
+		cmdp_local = cmdp;
+
+		temp1 = *cmdp_local;
+		cmdp_local++;
+
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase +
+			V33_PCA_ROLL_OFF_CFG_OFF1,
+			cmdp_local, V33_PCA_ROLL_OFF_CFG_LEN1);
+		cmdp_local += 4;
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase +
+			V33_PCA_ROLL_OFF_CFG_OFF2,
+			cmdp_local, V33_PCA_ROLL_OFF_CFG_LEN2);
+
+		cmdp_local += 3;
+		CDBG("%s: start writing RollOff Ram0 table\n", __func__);
+		vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK0, vfe32_ctrl);
+		msm_camera_io_w(temp1,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_ADDR);
+		for (i = 0 ; i < V33_PCA_ROLL_OFF_TABLE_SIZE ; i++) {
+			msm_camera_io_w(*(cmdp_local + 1),
+				vfe32_ctrl->share_ctrl->vfebase +
+				VFE33_DMI_DATA_HI);
+			msm_camera_io_w(*cmdp_local,
+				vfe32_ctrl->share_ctrl->vfebase +
+				VFE33_DMI_DATA_LO);
+			cmdp_local += 2;
+		}
+		CDBG("%s: end writing RollOff Ram0 table\n", __func__);
+
+		CDBG("%s: start writing RollOff Ram1 table\n", __func__);
+		vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK0, vfe32_ctrl);
+		msm_camera_io_w(temp1,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_ADDR);
+		for (i = 0 ; i < V33_PCA_ROLL_OFF_TABLE_SIZE ; i++) {
+			msm_camera_io_w(*cmdp_local,
+				vfe32_ctrl->share_ctrl->vfebase +
+				VFE33_DMI_DATA_LO);
+			cmdp_local += 2;
+		}
+		CDBG("%s: end writing RollOff Ram1 table\n", __func__);
+
+		vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
+		break;
+
+	case VFE_CMD_PCA_ROLL_OFF_UPDATE:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value), cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+
+		cmdp_local = cmdp;
+
+		temp1 = *cmdp_local;
+		cmdp_local += 8;
+
+		temp2 = msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
+			V33_PCA_ROLL_OFF_CFG_OFF1)
+			& V33_PCA_ROLL_OFF_LUT_BANK_SEL_MASK;
+
+		CDBG("%s: start writing RollOff Ram0 table\n", __func__);
+		if (temp2)
+			vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK0, vfe32_ctrl);
+		else
+			vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK1, vfe32_ctrl);
+
+		msm_camera_io_w(temp1,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_ADDR);
+		for (i = 0 ; i < V33_PCA_ROLL_OFF_TABLE_SIZE ; i++) {
+			msm_camera_io_w(*(cmdp_local + 1),
+				vfe32_ctrl->share_ctrl->vfebase +
+				VFE33_DMI_DATA_HI);
+			msm_camera_io_w(*cmdp_local,
+				vfe32_ctrl->share_ctrl->vfebase +
+				VFE33_DMI_DATA_LO);
+			cmdp_local += 2;
+		}
+		CDBG("%s: end writing RollOff Ram0 table\n", __func__);
+
+		CDBG("%s: start writing RollOff Ram1 table\n", __func__);
+		if (temp2)
+			vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK0, vfe32_ctrl);
+		else
+			vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK1, vfe32_ctrl);
+
+		msm_camera_io_w(temp1,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_ADDR);
+		for (i = 0 ; i < V33_PCA_ROLL_OFF_TABLE_SIZE ; i++) {
+			msm_camera_io_w(*cmdp_local,
+				vfe32_ctrl->share_ctrl->vfebase +
+				VFE33_DMI_DATA_LO);
+			cmdp_local += 2;
+		}
+		CDBG("%s: end writing RollOff Ram1 table\n", __func__);
+
+		vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
+		vfe32_ctrl->update_rolloff = true;
+		break;
+	case VFE_CMD_GET_PCA_ROLLOFF_TABLE:
+		temp1 = sizeof(uint64_t) * V33_PCA_ROLL_OFF_TABLE_SIZE * 2;
+		if (cmd->length != temp1) {
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		cmdp = kzalloc(temp1, GFP_KERNEL);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		old_val = msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
+			V33_PCA_ROLL_OFF_CFG_OFF1) &
+			V33_PCA_ROLL_OFF_LUT_BANK_SEL_MASK;
+
+		if (old_val)
+			vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK1, vfe32_ctrl);
+		else
+			vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK0, vfe32_ctrl);
+
+		CDBG("%s: PCA Rolloff Ram0\n", __func__);
+		for (i = 0 ; i < V33_PCA_ROLL_OFF_TABLE_SIZE * 2; i++) {
+			temp2 = (i == (V33_PCA_ROLL_OFF_TABLE_SIZE));
+			if (old_val && temp2)
+				vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK1,
+				vfe32_ctrl);
+			else if (!old_val && temp2)
+				vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK0,
+				vfe32_ctrl);
+
+			*cmdp_local = msm_camera_io_r(
+				vfe32_ctrl->share_ctrl->vfebase +
+				VFE33_DMI_DATA_LO);
+			*(cmdp_local + 1) =
+				msm_camera_io_r(
+				vfe32_ctrl->share_ctrl->vfebase +
+				VFE33_DMI_DATA_HI);
+			CDBG("%s: %08x%08x\n", __func__,
+				*(cmdp_local + 1), *cmdp_local);
+			cmdp_local += 2;
+		}
+		vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
+		if (copy_to_user((void __user *)(cmd->value), cmdp,
+			temp1)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		break;
+	case VFE_CMD_GET_HW_VERSION:
+		if (cmd->length != V32_GET_HW_VERSION_LEN) {
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(V32_GET_HW_VERSION_LEN, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		*cmdp = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase+V32_GET_HW_VERSION_OFF);
+		if (copy_to_user((void __user *)(cmd->value), cmdp,
+			V32_GET_HW_VERSION_LEN)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		break;
+	case VFE_CMD_GET_REG_DUMP:
+		temp1 = sizeof(uint32_t) *
+			vfe32_ctrl->share_ctrl->register_total;
+		if (cmd->length != temp1) {
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(temp1, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		msm_camera_io_dump(vfe32_ctrl->share_ctrl->vfebase,
+			vfe32_ctrl->share_ctrl->register_total*4);
+		CDBG("%s: %p %p %d\n", __func__, (void *)cmdp,
+			vfe32_ctrl->share_ctrl->vfebase, temp1);
+		memcpy_fromio((void *)cmdp,
+			vfe32_ctrl->share_ctrl->vfebase, temp1);
+		if (copy_to_user((void __user *)(cmd->value), cmdp, temp1)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		break;
+	case VFE_CMD_FRAME_SKIP_CFG:
+		if (cmd->length != vfe32_cmd[cmd->id].length)
+			return -EINVAL;
+
+		cmdp = kmalloc(vfe32_cmd[cmd->id].length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+
+		if (copy_from_user((cmdp), (void __user *)cmd->value,
+				cmd->length)) {
+			rc = -EFAULT;
+			pr_err("%s copy from user failed for cmd %d",
+				__func__, cmd->id);
+			break;
+		}
+
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
+			cmdp, (vfe32_cmd[cmd->id].length));
+		vfe32_ctrl->frame_skip_cnt = ((uint32_t)
+			*cmdp & VFE_FRAME_SKIP_PERIOD_MASK) + 1;
+		vfe32_ctrl->frame_skip_pattern = (uint32_t)(*(cmdp + 2));
+		break;
+	case VFE_CMD_STOP_LIVESHOT:
+		CDBG("%s Stopping liveshot ", __func__);
+		vfe32_stop_liveshot(pmctl, vfe32_ctrl);
+		break;
+	default:
+		if (cmd->length != vfe32_cmd[cmd->id].length)
+			return -EINVAL;
+
+		cmdp = kmalloc(vfe32_cmd[cmd->id].length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+
+		if (copy_from_user((cmdp), (void __user *)cmd->value,
+				cmd->length)) {
+			rc = -EFAULT;
+			pr_err("%s copy from user failed for cmd %d",
+				__func__, cmd->id);
+			goto proc_general_done;
+		}
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase +
+			vfe32_cmd[cmd->id].offset,
+			cmdp, (vfe32_cmd[cmd->id].length));
+		break;
+
+	}
+
+proc_general_done:
+	kfree(cmdp);
+
+	return rc;
+}
+
+static inline void vfe32_read_irq_status(
+	struct axi_ctrl_t *axi_ctrl, struct vfe32_irq_status *out)
+{
+	uint32_t *temp;
+	memset(out, 0, sizeof(struct vfe32_irq_status));
+	temp = (uint32_t *)(axi_ctrl->share_ctrl->vfebase + VFE_IRQ_STATUS_0);
+	out->vfeIrqStatus0 = msm_camera_io_r(temp);
+
+	temp = (uint32_t *)(axi_ctrl->share_ctrl->vfebase + VFE_IRQ_STATUS_1);
+	out->vfeIrqStatus1 = msm_camera_io_r(temp);
+
+	temp = (uint32_t *)(axi_ctrl->share_ctrl->vfebase + VFE_CAMIF_STATUS);
+	out->camifStatus = msm_camera_io_r(temp);
+	CDBG("camifStatus  = 0x%x\n", out->camifStatus);
+
+	/* clear the pending interrupt of the same kind.*/
+	msm_camera_io_w(out->vfeIrqStatus0,
+		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_0);
+	msm_camera_io_w(out->vfeIrqStatus1,
+		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_1);
+
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_camera_io_w_mb(1, axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CMD);
+
+}
+
+void axi_stop_pix(struct vfe_share_ctrl_t *share_ctrl,
+	uint32_t vfe_mode, uint8_t cmd_type)
+{
+	uint32_t reg_update = 0x1;
+	switch (cmd_type) {
+	case AXI_CMD_RAW_CAPTURE:
+		msm_camera_io_w(0, share_ctrl->vfebase
+			+ vfe32_AXI_WM_CFG[share_ctrl->outpath.out0.ch0]);
+		break;
+	case AXI_CMD_PREVIEW: {
+		switch (vfe_mode) {
+		case VFE_OUTPUTS_PREVIEW:
+		case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
+			if (share_ctrl->comp_output_mode &
+				VFE32_OUTPUT_MODE_PRIMARY) {
+				msm_camera_io_w(0, share_ctrl->vfebase
+					+ vfe32_AXI_WM_CFG[share_ctrl->
+					outpath.out0.ch0]);
+				msm_camera_io_w(0, share_ctrl->vfebase
+					+ vfe32_AXI_WM_CFG[share_ctrl->
+					outpath.out0.ch1]);
+			} else if (share_ctrl->comp_output_mode &
+					VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+				msm_camera_io_w(0, share_ctrl->vfebase
+					+ vfe32_AXI_WM_CFG[share_ctrl->
+					outpath.out0.ch0]);
+				msm_camera_io_w(0, share_ctrl->vfebase
+					+ vfe32_AXI_WM_CFG[share_ctrl->
+					outpath.out0.ch1]);
+				msm_camera_io_w(0, share_ctrl->vfebase
+					+ vfe32_AXI_WM_CFG[share_ctrl->
+					outpath.out0.ch2]);
+			}
+			break;
+		default:
+			if (share_ctrl->comp_output_mode &
+				VFE32_OUTPUT_MODE_SECONDARY) {
+				msm_camera_io_w(0, share_ctrl->vfebase
+					+ vfe32_AXI_WM_CFG[share_ctrl->
+					outpath.out1.ch0]);
+				msm_camera_io_w(0, share_ctrl->vfebase
+					+ vfe32_AXI_WM_CFG[share_ctrl->
+					outpath.out1.ch1]);
+			} else if (share_ctrl->comp_output_mode &
+				VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+				msm_camera_io_w(0, share_ctrl->vfebase
+					+ vfe32_AXI_WM_CFG[share_ctrl->
+					outpath.out1.ch0]);
+				msm_camera_io_w(0, share_ctrl->vfebase
+					+ vfe32_AXI_WM_CFG[share_ctrl->
+					outpath.out1.ch1]);
+				msm_camera_io_w(0, share_ctrl->vfebase
+					+ vfe32_AXI_WM_CFG[share_ctrl->
+					outpath.out1.ch2]);
+			}
+			break;
+			}
+		}
+		break;
+	default:
+		if (share_ctrl->comp_output_mode &
+			VFE32_OUTPUT_MODE_PRIMARY) {
+			msm_camera_io_w(0, share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[share_ctrl->
+				outpath.out0.ch0]);
+			msm_camera_io_w(0, share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[share_ctrl->
+				outpath.out0.ch1]);
+		} else if (share_ctrl->comp_output_mode &
+				VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+			msm_camera_io_w(0, share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[share_ctrl->
+				outpath.out0.ch0]);
+			msm_camera_io_w(0, share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[share_ctrl->
+				outpath.out0.ch1]);
+			msm_camera_io_w(0, share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[share_ctrl->
+				outpath.out0.ch2]);
+		}
+
+		if (share_ctrl->comp_output_mode &
+			VFE32_OUTPUT_MODE_SECONDARY) {
+			msm_camera_io_w(0, share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[share_ctrl->
+				outpath.out1.ch0]);
+			msm_camera_io_w(0, share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[share_ctrl->outpath.out1.ch1]);
+		} else if (share_ctrl->comp_output_mode &
+			VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+			msm_camera_io_w(0, share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[share_ctrl->outpath.out1.ch0]);
+			msm_camera_io_w(0, share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[share_ctrl->outpath.out1.ch1]);
+			msm_camera_io_w(0, share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[share_ctrl->outpath.out1.ch2]);
+		}
+		break;
+	}
+
+	msm_camera_io_w_mb(reg_update,
+		share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+}
+
+void axi_stop_rdi0(struct vfe_share_ctrl_t *share_ctrl)
+{
+	uint32_t reg_update = 0x2;
+	msm_camera_io_w(0, share_ctrl->vfebase +
+		vfe32_AXI_WM_CFG[share_ctrl->outpath.out2.ch0]);
+	msm_camera_io_w_mb(reg_update,
+		share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+}
+
+void axi_stop_rdi1(struct vfe_share_ctrl_t *share_ctrl)
+{
+	uint32_t reg_update = 0x4;
+	msm_camera_io_w(0, share_ctrl->vfebase +
+		vfe32_AXI_WM_CFG[share_ctrl->outpath.out3.ch0]);
+	msm_camera_io_w_mb(reg_update,
+		share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+}
+
+void axi_stop_process(struct vfe_share_ctrl_t *share_ctrl)
+{
+	uint32_t vfe_mode =
+	share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
+		VFE_OUTPUTS_RDI1);
+
+	if (share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
+		axi_stop_rdi0(share_ctrl);
+		axi_disable_wm_irq(share_ctrl,
+			VFE32_OUTPUT_MODE_TERTIARY1);
+		share_ctrl->comp_output_mode &= ~VFE32_OUTPUT_MODE_TERTIARY1;
+		share_ctrl->operation_mode &=
+			~(VFE_OUTPUTS_RDI0);
+	}
+	if (share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
+		axi_stop_rdi1(share_ctrl);
+		axi_disable_wm_irq(share_ctrl,
+			VFE32_OUTPUT_MODE_TERTIARY2);
+		share_ctrl->comp_output_mode &= ~VFE32_OUTPUT_MODE_TERTIARY2;
+		share_ctrl->operation_mode &=
+			~(VFE_OUTPUTS_RDI1);
+	}
+	if (vfe_mode) {
+		uint16_t mode = share_ctrl->comp_output_mode &
+			~(VFE32_OUTPUT_MODE_TERTIARY1|
+			VFE32_OUTPUT_MODE_TERTIARY2);
+		axi_stop_pix(share_ctrl, vfe_mode, share_ctrl->cmd_type);
+		axi_disable_wm_irq(share_ctrl, mode);
+		share_ctrl->comp_output_mode &=
+				(VFE32_OUTPUT_MODE_TERTIARY1|
+				VFE32_OUTPUT_MODE_TERTIARY2);
+	}
+}
+
+static void vfe32_process_reg_update_irq(
+		struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	unsigned long flags;
+	struct vfe_share_ctrl_t *share_ctrl = vfe32_ctrl->share_ctrl;
+	if (atomic_read(
+		&share_ctrl->pix0_update_ack_pending) == 2) {
+		uint32_t vfe_mode =
+				share_ctrl->operation_mode & ~(VFE_OUTPUTS_RDI0|
+					VFE_OUTPUTS_RDI1);
+
+		if (share_ctrl->dual_enabled && !share_ctrl->update_counter) {
+			axi_stop_pix(share_ctrl, vfe_mode,
+				share_ctrl->cmd_type);
+			share_ctrl->update_counter++;
+		} else {
+			uint16_t output_mode =
+				share_ctrl->comp_output_mode &
+				~(VFE32_OUTPUT_MODE_TERTIARY1|
+				VFE32_OUTPUT_MODE_TERTIARY2);
+			share_ctrl->update_counter = 0;
+			if (!share_ctrl->dual_enabled)
+				axi_stop_pix(share_ctrl, vfe_mode,
+					share_ctrl->cmd_type);
+			axi_disable_wm_irq(share_ctrl, output_mode);
+			axi_disable_irq(share_ctrl, vfe_mode);
+			atomic_set(&share_ctrl->pix0_update_ack_pending, 0);
+			msm_camera_io_w_mb(
+					CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
+					share_ctrl->vfebase +
+					VFE_CAMIF_COMMAND);
+			vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+				share_ctrl->vfeFrameId,
+				MSG_ID_PIX0_UPDATE_ACK);
+			share_ctrl->comp_output_mode &=
+				(VFE32_OUTPUT_MODE_TERTIARY1|
+				VFE32_OUTPUT_MODE_TERTIARY2);
+		}
+	}  else {
+		if (share_ctrl->recording_state == VFE_STATE_START_REQUESTED) {
+			if (share_ctrl->operation_mode &
+					VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
+				msm_camera_io_w((
+					0x1 << share_ctrl->outpath.out0.ch0 |
+					0x1 << share_ctrl->outpath.out0.ch1),
+					share_ctrl->vfebase + VFE_BUS_CMD);
+				msm_camera_io_w(1,
+					share_ctrl->vfebase + vfe32_AXI_WM_CFG[
+					share_ctrl->outpath.out0.ch0]);
+				msm_camera_io_w(1,
+					share_ctrl->vfebase + vfe32_AXI_WM_CFG[
+					share_ctrl->outpath.out0.ch1]);
+			} else if (share_ctrl->operation_mode &
+					VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
+				msm_camera_io_w((
+					0x1 << share_ctrl->outpath.out1.ch0 |
+					0x1 << share_ctrl->outpath.out1.ch1),
+					share_ctrl->vfebase + VFE_BUS_CMD);
+				msm_camera_io_w(1,
+					share_ctrl->vfebase + vfe32_AXI_WM_CFG[
+					share_ctrl->outpath.out1.ch0]);
+				msm_camera_io_w(1,
+					share_ctrl->vfebase + vfe32_AXI_WM_CFG[
+					share_ctrl->outpath.out1.ch1]);
+			}
+			share_ctrl->recording_state = VFE_STATE_STARTED;
+			msm_camera_io_w_mb(1,
+				share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+			CDBG("start video triggered .\n");
+		} else if (share_ctrl->recording_state ==
+					VFE_STATE_STOP_REQUESTED) {
+			if (share_ctrl->operation_mode &
+					VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
+				msm_camera_io_w(0,
+					share_ctrl->vfebase + vfe32_AXI_WM_CFG[
+					share_ctrl->outpath.out0.ch0]);
+				msm_camera_io_w(0,
+					share_ctrl->vfebase + vfe32_AXI_WM_CFG[
+					share_ctrl->outpath.out0.ch1]);
+			} else if (share_ctrl->operation_mode &
+					VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
+				msm_camera_io_w(0,
+					share_ctrl->vfebase + vfe32_AXI_WM_CFG[
+					share_ctrl->outpath.out1.ch0]);
+				msm_camera_io_w(0,
+					share_ctrl->vfebase + vfe32_AXI_WM_CFG[
+					share_ctrl->outpath.out1.ch1]);
+			}
+			CDBG("stop video triggered .\n");
+		}
+
+		if (atomic_cmpxchg(
+		&share_ctrl->pix0_update_ack_pending, 1, 0) == 1) {
+			share_ctrl->comp_output_mode |=
+				(share_ctrl->outpath.output_mode
+				& ~(VFE32_OUTPUT_MODE_TERTIARY1|
+					VFE32_OUTPUT_MODE_TERTIARY2));
+			vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+				share_ctrl->vfeFrameId, MSG_ID_PIX0_UPDATE_ACK);
+		} else {
+			if (share_ctrl->recording_state ==
+						VFE_STATE_STOP_REQUESTED) {
+				share_ctrl->recording_state = VFE_STATE_STOPPED;
+				/* request a reg update and send STOP_REC_ACK
+				 * when we process the next reg update irq.
+				 */
+				msm_camera_io_w_mb(1, share_ctrl->vfebase +
+							VFE_REG_UPDATE_CMD);
+			} else if (share_ctrl->recording_state ==
+						VFE_STATE_STOPPED) {
+				vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+					share_ctrl->vfeFrameId,
+					MSG_ID_STOP_REC_ACK);
+				share_ctrl->recording_state = VFE_STATE_IDLE;
+			}
+			spin_lock_irqsave(
+				&share_ctrl->update_ack_lock,
+				flags);
+			if (share_ctrl->update_ack_pending == TRUE) {
+				share_ctrl->update_ack_pending = FALSE;
+				spin_unlock_irqrestore(
+					&share_ctrl->update_ack_lock, flags);
+				vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+					share_ctrl->vfeFrameId,
+					MSG_ID_UPDATE_ACK);
+			} else {
+				spin_unlock_irqrestore(
+					&share_ctrl->update_ack_lock, flags);
+			}
+		}
+
+		switch (share_ctrl->liveshot_state) {
+		case VFE_STATE_START_REQUESTED:
+			CDBG("%s enabling liveshot output\n", __func__);
+			if (share_ctrl->comp_output_mode &
+						VFE32_OUTPUT_MODE_PRIMARY) {
+				msm_camera_io_w((
+					0x1 << share_ctrl->outpath.out0.ch0 |
+					0x1 << share_ctrl->outpath.out0.ch1),
+					share_ctrl->vfebase + VFE_BUS_CMD);
+				msm_camera_io_w(1, share_ctrl->vfebase +
+					vfe32_AXI_WM_CFG[
+					share_ctrl->outpath.out0.ch0]);
+				msm_camera_io_w(1, share_ctrl->vfebase +
+					vfe32_AXI_WM_CFG[
+					share_ctrl->outpath.out0.ch1]);
+
+				share_ctrl->liveshot_state =
+					VFE_STATE_STARTED;
+			}
+			break;
+		case VFE_STATE_STARTED:
+			share_ctrl->vfe_capture_count--;
+			if (!share_ctrl->vfe_capture_count &&
+				(share_ctrl->comp_output_mode &
+					VFE32_OUTPUT_MODE_PRIMARY)) {
+				msm_camera_io_w(0, share_ctrl->vfebase +
+					vfe32_AXI_WM_CFG[
+					share_ctrl->outpath.out0.ch0]);
+				msm_camera_io_w(0, share_ctrl->vfebase +
+					vfe32_AXI_WM_CFG[
+					share_ctrl->outpath.out0.ch1]);
+			}
+			break;
+		case VFE_STATE_STOP_REQUESTED:
+			if (share_ctrl->comp_output_mode &
+					VFE32_OUTPUT_MODE_PRIMARY) {
+				/* Stop requested, stop write masters, and
+				 * trigger REG_UPDATE. Send STOP_LS_ACK in
+				 * next reg update. */
+				msm_camera_io_w(0, share_ctrl->vfebase +
+					vfe32_AXI_WM_CFG[
+					share_ctrl->outpath.out0.ch0]);
+				msm_camera_io_w(0, share_ctrl->vfebase +
+					vfe32_AXI_WM_CFG[
+					share_ctrl->outpath.out0.ch1]);
+
+				share_ctrl->liveshot_state = VFE_STATE_STOPPED;
+				msm_camera_io_w_mb(1, share_ctrl->vfebase +
+					VFE_REG_UPDATE_CMD);
+			}
+			break;
+		case VFE_STATE_STOPPED:
+			CDBG("%s Sending STOP_LS ACK\n", __func__);
+			vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+				share_ctrl->vfeFrameId, MSG_ID_STOP_LS_ACK);
+			share_ctrl->liveshot_state = VFE_STATE_IDLE;
+			break;
+		default:
+			break;
+		}
+
+		if ((share_ctrl->operation_mode & VFE_OUTPUTS_THUMB_AND_MAIN) ||
+			(share_ctrl->operation_mode &
+				VFE_OUTPUTS_MAIN_AND_THUMB) ||
+			(share_ctrl->operation_mode &
+				VFE_OUTPUTS_THUMB_AND_JPEG) ||
+			(share_ctrl->operation_mode &
+				VFE_OUTPUTS_JPEG_AND_THUMB)) {
+			/* in snapshot mode */
+			/* later we need to add check for live snapshot mode. */
+			if (vfe32_ctrl->frame_skip_pattern & (0x1 <<
+				(vfe32_ctrl->snapshot_frame_cnt %
+					vfe32_ctrl->frame_skip_cnt))) {
+				share_ctrl->vfe_capture_count--;
+				/* if last frame to be captured: */
+				if (share_ctrl->vfe_capture_count == 0) {
+					/* stop the bus output: */
+					uint32_t vfe_mode =
+						share_ctrl->operation_mode &
+							~(VFE_OUTPUTS_RDI0|
+							VFE_OUTPUTS_RDI1);
+					axi_stop_pix(share_ctrl, vfe_mode,
+						AXI_CMD_CAPTURE);
+					msm_camera_io_w_mb
+					(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
+					share_ctrl->vfebase +
+					VFE_CAMIF_COMMAND);
+					vfe32_ctrl->snapshot_frame_cnt = -1;
+					vfe32_ctrl->frame_skip_cnt = 31;
+					vfe32_ctrl->frame_skip_pattern =
+								0xffffffff;
+				} /*if snapshot count is 0*/
+			} /*if frame is not being dropped*/
+			vfe32_ctrl->snapshot_frame_cnt++;
+			/* then do reg_update. */
+			msm_camera_io_w(1,
+				share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+		} /* if snapshot mode. */
+	}
+}
+
+static void vfe32_process_rdi0_reg_update_irq(
+	struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	if (atomic_cmpxchg(
+		&vfe32_ctrl->share_ctrl->rdi0_update_ack_pending, 1, 0) == 1) {
+		vfe32_ctrl->share_ctrl->comp_output_mode |=
+			VFE32_OUTPUT_MODE_TERTIARY1;
+		vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+			vfe32_ctrl->share_ctrl->rdi0FrameId,
+			MSG_ID_RDI0_UPDATE_ACK);
+	}
+
+	if ((atomic_read(
+		&vfe32_ctrl->share_ctrl->rdi0_update_ack_pending) == 2)
+		|| (vfe32_ctrl->share_ctrl->rdi0_capture_count == 0)) {
+		axi_disable_wm_irq(vfe32_ctrl->share_ctrl,
+			VFE32_OUTPUT_MODE_TERTIARY1);
+		axi_disable_irq(vfe32_ctrl->share_ctrl, VFE_OUTPUTS_RDI0);
+		atomic_set(&vfe32_ctrl->share_ctrl->rdi0_update_ack_pending, 0);
+		vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+			vfe32_ctrl->share_ctrl->rdi0FrameId,
+			MSG_ID_RDI0_UPDATE_ACK);
+
+		if (vfe32_ctrl->share_ctrl->rdi0_capture_count == 0)
+			vfe32_ctrl->share_ctrl->rdi0_capture_count = -1;
+		if (vfe32_ctrl->share_ctrl->outpath.out2.capture_cnt
+			== 0)
+			vfe32_ctrl->share_ctrl->outpath.out2.capture_cnt = -1;
+		vfe32_ctrl->share_ctrl->comp_output_mode &=
+			~VFE32_OUTPUT_MODE_TERTIARY1;
+		vfe32_ctrl->share_ctrl->operation_mode &=
+			~(VFE_OUTPUTS_RDI0);
+	}
+
+	if (vfe32_ctrl->share_ctrl->rdi0_capture_count > 0) {
+		vfe32_ctrl->share_ctrl->rdi0_capture_count--;
+		if (!vfe32_ctrl->share_ctrl->rdi0_capture_count)
+			axi_stop_rdi0(vfe32_ctrl->share_ctrl);
+	}
+}
+
+static void vfe32_process_rdi1_reg_update_irq(
+	struct vfe32_ctrl_type *vfe32_ctrl)
+{
+
+	if (atomic_cmpxchg(
+		&vfe32_ctrl->share_ctrl->rdi1_update_ack_pending, 1, 0)
+				== 1) {
+		vfe32_ctrl->share_ctrl->comp_output_mode |=
+			VFE32_OUTPUT_MODE_TERTIARY2;
+		vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+			vfe32_ctrl->share_ctrl->rdi1FrameId,
+			MSG_ID_RDI1_UPDATE_ACK);
+	}
+
+	if ((atomic_read(
+		&vfe32_ctrl->share_ctrl->rdi1_update_ack_pending) == 2)
+		|| (vfe32_ctrl->share_ctrl->rdi1_capture_count == 0)) {
+		axi_disable_wm_irq(vfe32_ctrl->share_ctrl,
+			VFE32_OUTPUT_MODE_TERTIARY2);
+		axi_disable_irq(vfe32_ctrl->share_ctrl, VFE_OUTPUTS_RDI1);
+		atomic_set(&vfe32_ctrl->share_ctrl->rdi1_update_ack_pending, 0);
+		vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+			vfe32_ctrl->share_ctrl->rdi1FrameId,
+			MSG_ID_RDI1_UPDATE_ACK);
+
+		if (vfe32_ctrl->share_ctrl->rdi1_capture_count == 0)
+			vfe32_ctrl->share_ctrl->rdi1_capture_count = -1;
+		if (vfe32_ctrl->share_ctrl->outpath.out3.capture_cnt
+			== 0)
+			vfe32_ctrl->share_ctrl->outpath.out3.capture_cnt = -1;
+		vfe32_ctrl->share_ctrl->comp_output_mode &=
+			~VFE32_OUTPUT_MODE_TERTIARY2;
+		vfe32_ctrl->share_ctrl->operation_mode &=
+			~(VFE_OUTPUTS_RDI1);
+	}
+
+	if (vfe32_ctrl->share_ctrl->rdi1_capture_count > 0) {
+		vfe32_ctrl->share_ctrl->rdi1_capture_count--;
+		if (!vfe32_ctrl->share_ctrl->rdi1_capture_count)
+			axi_stop_rdi1(vfe32_ctrl->share_ctrl);
+	}
+}
+
+static void vfe32_process_reset_irq(
+		struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	unsigned long flags;
+
+	atomic_set(&vfe32_ctrl->share_ctrl->vstate, 0);
+	atomic_set(&vfe32_ctrl->share_ctrl->handle_common_irq, 0);
+
+	spin_lock_irqsave(&vfe32_ctrl->share_ctrl->stop_flag_lock, flags);
+	if (vfe32_ctrl->share_ctrl->stop_ack_pending) {
+		vfe32_ctrl->share_ctrl->stop_ack_pending = FALSE;
+		spin_unlock_irqrestore(
+			&vfe32_ctrl->share_ctrl->stop_flag_lock, flags);
+		if (vfe32_ctrl->share_ctrl->sync_abort)
+			complete(&vfe32_ctrl->share_ctrl->reset_complete);
+		else
+			vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+				vfe32_ctrl->share_ctrl->vfeFrameId,
+				MSG_ID_STOP_ACK);
+	} else {
+		spin_unlock_irqrestore(
+			&vfe32_ctrl->share_ctrl->stop_flag_lock, flags);
+		/* this is from reset command. */
+		vfe32_reset_internal_variables(vfe32_ctrl);
+		if (vfe32_ctrl->share_ctrl->vfe_reset_flag) {
+			vfe32_ctrl->share_ctrl->vfe_reset_flag = false;
+			msm_camera_io_w(0x7F80,
+				vfe32_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
+		} else {
+			/* reload all write masters. (frame & line)*/
+			msm_camera_io_w(0x7FFF,
+				vfe32_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
+		}
+		complete(&vfe32_ctrl->share_ctrl->reset_complete);
+	}
+}
+
+static void vfe32_process_camif_sof_irq(
+		struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	if (vfe32_ctrl->share_ctrl->operation_mode ==
+		VFE_OUTPUTS_RAW) {
+		if (atomic_cmpxchg(
+			&vfe32_ctrl->share_ctrl->pix0_update_ack_pending,
+					1, 0) == 1) {
+			vfe32_ctrl->share_ctrl->comp_output_mode |=
+				(vfe32_ctrl->share_ctrl->outpath.output_mode
+				& ~(VFE32_OUTPUT_MODE_TERTIARY1|
+				VFE32_OUTPUT_MODE_TERTIARY2));
+			vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+				vfe32_ctrl->share_ctrl->vfeFrameId,
+				MSG_ID_PIX0_UPDATE_ACK);
+		}
+
+		vfe32_ctrl->share_ctrl->vfe_capture_count--;
+		/* if last frame to be captured: */
+		if (vfe32_ctrl->share_ctrl->vfe_capture_count == 0) {
+			/* Ensure the write order while writing
+			 to the command register using the barrier */
+			msm_camera_io_w_mb(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
+			vfe32_ctrl->share_ctrl->vfebase + VFE_CAMIF_COMMAND);
+		}
+	} /* if raw snapshot mode. */
+	if ((vfe32_ctrl->hfr_mode != HFR_MODE_OFF) &&
+		(vfe32_ctrl->share_ctrl->operation_mode ==
+			VFE_MODE_OF_OPERATION_VIDEO) &&
+		(vfe32_ctrl->share_ctrl->vfeFrameId %
+			vfe32_ctrl->hfr_mode != 0)) {
+		if (vfe32_ctrl->vfe_sof_count_enable)
+			vfe32_ctrl->share_ctrl->vfeFrameId++;
+		CDBG("Skip the SOF notification when HFR enabled\n");
+		return;
+	}
+	if (vfe32_ctrl->vfe_sof_count_enable)
+		vfe32_ctrl->share_ctrl->vfeFrameId++;
+
+	vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+		vfe32_ctrl->share_ctrl->vfeFrameId, MSG_ID_SOF_ACK);
+	CDBG("camif_sof_irq, frameId = %d\n",
+		vfe32_ctrl->share_ctrl->vfeFrameId);
+
+	if (vfe32_ctrl->sync_timer_state) {
+		if (vfe32_ctrl->sync_timer_repeat_count == 0)
+			vfe32_sync_timer_stop(vfe32_ctrl);
+		else
+			vfe32_ctrl->sync_timer_repeat_count--;
+	}
+}
+
+static void vfe32_process_error_irq(
+	struct axi_ctrl_t *axi_ctrl, uint32_t errStatus)
+{
+	uint32_t reg_value;
+	if (errStatus & VFE32_IMASK_VIOLATION) {
+		pr_err("vfe32_irq: violation interrupt\n");
+		reg_value = msm_camera_io_r(
+			axi_ctrl->share_ctrl->vfebase + VFE_VIOLATION_STATUS);
+		pr_err("%s: violationStatus  = 0x%x\n", __func__, reg_value);
+	}
+
+	if (errStatus & VFE32_IMASK_CAMIF_ERROR) {
+		pr_err("vfe32_irq: camif errors\n");
+		reg_value = msm_camera_io_r(
+			axi_ctrl->share_ctrl->vfebase + VFE_CAMIF_STATUS);
+		v4l2_subdev_notify(&axi_ctrl->subdev,
+			NOTIFY_VFE_CAMIF_ERROR, (void *)NULL);
+		pr_err("camifStatus  = 0x%x\n", reg_value);
+		vfe32_send_isp_msg(&axi_ctrl->subdev,
+			axi_ctrl->share_ctrl->vfeFrameId, MSG_ID_CAMIF_ERROR);
+	}
+
+	if (errStatus & VFE32_IMASK_BHIST_OVWR)
+		pr_err("vfe32_irq: stats bhist overwrite\n");
+
+	if (errStatus & VFE32_IMASK_STATS_CS_OVWR)
+		pr_err("vfe32_irq: stats cs overwrite\n");
+
+	if (errStatus & VFE32_IMASK_STATS_IHIST_OVWR)
+		pr_err("vfe32_irq: stats ihist overwrite\n");
+
+	if (errStatus & VFE32_IMASK_REALIGN_BUF_Y_OVFL)
+		pr_err("vfe32_irq: realign bug Y overflow\n");
+
+	if (errStatus & VFE32_IMASK_REALIGN_BUF_CB_OVFL)
+		pr_err("vfe32_irq: realign bug CB overflow\n");
+
+	if (errStatus & VFE32_IMASK_REALIGN_BUF_CR_OVFL)
+		pr_err("vfe32_irq: realign bug CR overflow\n");
+
+	if (errStatus & VFE32_IMASK_STATS_AE_BG_BUS_OVFL)
+		pr_err("vfe32_irq: ae/bg stats bus overflow\n");
+
+	if (errStatus & VFE32_IMASK_STATS_AF_BF_BUS_OVFL)
+		pr_err("vfe32_irq: af/bf stats bus overflow\n");
+
+	if (errStatus & VFE32_IMASK_STATS_AWB_BUS_OVFL)
+		pr_err("vfe32_irq: awb stats bus overflow\n");
+
+	if (errStatus & VFE32_IMASK_STATS_RS_BUS_OVFL)
+		pr_err("vfe32_irq: rs stats bus overflow\n");
+
+	if (errStatus & VFE32_IMASK_STATS_CS_BUS_OVFL)
+		pr_err("vfe32_irq: cs stats bus overflow\n");
+
+	if (errStatus & VFE32_IMASK_STATS_IHIST_BUS_OVFL)
+		pr_err("vfe32_irq: ihist stats bus overflow\n");
+
+	if (errStatus & VFE32_IMASK_STATS_SKIN_BHIST_BUS_OVFL)
+		pr_err("vfe32_irq: skin/bhist stats bus overflow\n");
+}
+
+static void vfe32_process_common_error_irq(
+	struct axi_ctrl_t *axi_ctrl, uint32_t errStatus)
+{
+
+	if (errStatus & VFE32_IMASK_IMG_MAST_0_BUS_OVFL)
+		pr_err("vfe32_irq: image master 0 bus overflow\n");
+
+	if (errStatus & VFE32_IMASK_IMG_MAST_1_BUS_OVFL)
+		pr_err("vfe32_irq: image master 1 bus overflow\n");
+
+	if (errStatus & VFE32_IMASK_IMG_MAST_2_BUS_OVFL)
+		pr_err("vfe32_irq: image master 2 bus overflow\n");
+
+	if (errStatus & VFE32_IMASK_IMG_MAST_3_BUS_OVFL)
+		pr_err("vfe32_irq: image master 3 bus overflow\n");
+
+	if (errStatus & VFE32_IMASK_IMG_MAST_4_BUS_OVFL)
+		pr_err("vfe32_irq: image master 4 bus overflow\n");
+
+	if (errStatus & VFE32_IMASK_IMG_MAST_5_BUS_OVFL)
+		pr_err("vfe32_irq: image master 5 bus overflow\n");
+
+	if (errStatus & VFE32_IMASK_IMG_MAST_6_BUS_OVFL)
+		pr_err("vfe32_irq: image master 6 bus overflow\n");
+
+	if (errStatus & VFE32_IMASK_AXI_ERROR)
+		pr_err("vfe32_irq: axi error\n");
+}
+
+
+static void vfe_send_outmsg(
+	struct axi_ctrl_t *axi_ctrl, uint8_t msgid,
+	uint32_t ch0_paddr, uint32_t ch1_paddr,
+	uint32_t ch2_paddr, uint32_t inst_handle)
+{
+	struct isp_msg_output msg;
+
+	msg.output_id = msgid;
+	msg.buf.inst_handle = inst_handle;
+	msg.buf.ch_paddr[0]	= ch0_paddr;
+	msg.buf.ch_paddr[1]	= ch1_paddr;
+	msg.buf.ch_paddr[2]	= ch2_paddr;
+	switch (msgid) {
+	case MSG_ID_OUTPUT_TERTIARY1:
+		msg.frameCounter = axi_ctrl->share_ctrl->rdi0FrameId;
+		break;
+	case MSG_ID_OUTPUT_TERTIARY2:
+		msg.frameCounter = axi_ctrl->share_ctrl->rdi1FrameId;
+		break;
+	default:
+		msg.frameCounter = axi_ctrl->share_ctrl->vfeFrameId;
+		break;
+	}
+
+	v4l2_subdev_notify(&axi_ctrl->subdev,
+			NOTIFY_VFE_MSG_OUT,
+			&msg);
+	return;
+}
+
+static void vfe32_process_output_path_irq_0(
+	struct axi_ctrl_t *axi_ctrl)
+{
+	uint32_t ping_pong;
+	uint32_t ch0_paddr, ch1_paddr, ch2_paddr;
+	uint8_t out_bool = 0;
+	struct msm_free_buf *free_buf = NULL;
+	free_buf = vfe32_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
+		VFE_MSG_OUTPUT_PRIMARY, axi_ctrl);
+
+	/* we render frames in the following conditions:
+	1. Continuous mode and the free buffer is avaialable.
+	2. In snapshot shot mode, free buffer is not always available.
+	when pending snapshot count is <=1,  then no need to use
+	free buffer.
+	*/
+	out_bool = (
+		(axi_ctrl->share_ctrl->operation_mode &
+			VFE_OUTPUTS_THUMB_AND_MAIN ||
+		axi_ctrl->share_ctrl->operation_mode &
+			VFE_OUTPUTS_MAIN_AND_THUMB ||
+		axi_ctrl->share_ctrl->operation_mode &
+			VFE_OUTPUTS_THUMB_AND_JPEG ||
+		axi_ctrl->share_ctrl->operation_mode &
+			VFE_OUTPUTS_JPEG_AND_THUMB ||
+		axi_ctrl->share_ctrl->operation_mode &
+			VFE_OUTPUTS_RAW ||
+		axi_ctrl->share_ctrl->liveshot_state ==
+			VFE_STATE_STARTED ||
+		axi_ctrl->share_ctrl->liveshot_state ==
+			VFE_STATE_STOP_REQUESTED ||
+		axi_ctrl->share_ctrl->liveshot_state ==
+			VFE_STATE_STOPPED) &&
+		(axi_ctrl->share_ctrl->vfe_capture_count <= 1)) ||
+			free_buf;
+
+	if (out_bool) {
+		ping_pong = msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
+			VFE_BUS_PING_PONG_STATUS);
+
+		/* Channel 0*/
+		ch0_paddr = vfe32_get_ch_addr(
+			ping_pong, axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out0.ch0);
+		/* Channel 1*/
+		ch1_paddr = vfe32_get_ch_addr(
+			ping_pong, axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out0.ch1);
+		/* Channel 2*/
+		ch2_paddr = vfe32_get_ch_addr(
+			ping_pong, axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out0.ch2);
+
+		CDBG("output path 0, ch0 = 0x%x, ch1 = 0x%x, ch2 = 0x%x\n",
+			ch0_paddr, ch1_paddr, ch2_paddr);
+		if (free_buf) {
+			/* Y channel */
+			vfe32_put_ch_addr(ping_pong,
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out0.ch0,
+			free_buf->ch_paddr[0]);
+			/* Chroma channel */
+			vfe32_put_ch_addr(ping_pong,
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out0.ch1,
+			free_buf->ch_paddr[1]);
+			if (free_buf->num_planes > 2)
+				vfe32_put_ch_addr(ping_pong,
+					axi_ctrl->share_ctrl->vfebase,
+					axi_ctrl->share_ctrl->outpath.out0.ch2,
+					free_buf->ch_paddr[2]);
+		}
+		if (axi_ctrl->share_ctrl->operation_mode &
+				VFE_OUTPUTS_THUMB_AND_MAIN ||
+			axi_ctrl->share_ctrl->operation_mode &
+				VFE_OUTPUTS_MAIN_AND_THUMB ||
+			axi_ctrl->share_ctrl->operation_mode &
+				VFE_OUTPUTS_THUMB_AND_JPEG ||
+			axi_ctrl->share_ctrl->operation_mode &
+				VFE_OUTPUTS_JPEG_AND_THUMB ||
+			axi_ctrl->share_ctrl->operation_mode &
+				VFE_OUTPUTS_RAW ||
+			axi_ctrl->share_ctrl->liveshot_state ==
+				VFE_STATE_STOPPED)
+			axi_ctrl->share_ctrl->outpath.out0.capture_cnt--;
+
+		vfe_send_outmsg(axi_ctrl,
+			MSG_ID_OUTPUT_PRIMARY, ch0_paddr,
+			ch1_paddr, ch2_paddr,
+			axi_ctrl->share_ctrl->outpath.out0.inst_handle);
+
+	} else {
+		axi_ctrl->share_ctrl->outpath.out0.frame_drop_cnt++;
+		CDBG("path_irq_0 - no free buffer!\n");
+	}
+}
+
+static void vfe32_process_output_path_irq_1(
+	struct axi_ctrl_t *axi_ctrl)
+{
+	uint32_t ping_pong;
+	uint32_t ch0_paddr, ch1_paddr, ch2_paddr;
+	/* this must be snapshot main image output. */
+	uint8_t out_bool = 0;
+	struct msm_free_buf *free_buf = NULL;
+
+	free_buf = vfe32_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
+		VFE_MSG_OUTPUT_SECONDARY, axi_ctrl);
+	out_bool = ((axi_ctrl->share_ctrl->operation_mode &
+				VFE_OUTPUTS_THUMB_AND_MAIN ||
+			axi_ctrl->share_ctrl->operation_mode &
+				VFE_OUTPUTS_MAIN_AND_THUMB ||
+			axi_ctrl->share_ctrl->operation_mode &
+				VFE_OUTPUTS_RAW ||
+			axi_ctrl->share_ctrl->operation_mode &
+				VFE_OUTPUTS_JPEG_AND_THUMB) &&
+			(axi_ctrl->share_ctrl->vfe_capture_count <= 1)) ||
+				free_buf;
+
+	if (out_bool) {
+		ping_pong = msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
+			VFE_BUS_PING_PONG_STATUS);
+
+		/* Y channel */
+		ch0_paddr = vfe32_get_ch_addr(ping_pong,
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out1.ch0);
+		/* Chroma channel */
+		ch1_paddr = vfe32_get_ch_addr(ping_pong,
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out1.ch1);
+		ch2_paddr = vfe32_get_ch_addr(ping_pong,
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out1.ch2);
+
+		CDBG("%s ch0 = 0x%x, ch1 = 0x%x, ch2 = 0x%x\n",
+			__func__, ch0_paddr, ch1_paddr, ch2_paddr);
+		if (free_buf) {
+			/* Y channel */
+			vfe32_put_ch_addr(ping_pong,
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out1.ch0,
+			free_buf->ch_paddr[0]);
+			/* Chroma channel */
+			vfe32_put_ch_addr(ping_pong,
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out1.ch1,
+			free_buf->ch_paddr[1]);
+			if (free_buf->num_planes > 2)
+				vfe32_put_ch_addr(ping_pong,
+					axi_ctrl->share_ctrl->vfebase,
+					axi_ctrl->share_ctrl->outpath.out1.ch2,
+					free_buf->ch_paddr[2]);
+		}
+		if (axi_ctrl->share_ctrl->operation_mode &
+				VFE_OUTPUTS_THUMB_AND_MAIN ||
+			axi_ctrl->share_ctrl->operation_mode &
+				VFE_OUTPUTS_MAIN_AND_THUMB ||
+			axi_ctrl->share_ctrl->operation_mode &
+				VFE_OUTPUTS_RAW ||
+			axi_ctrl->share_ctrl->operation_mode &
+				VFE_OUTPUTS_JPEG_AND_THUMB)
+			axi_ctrl->share_ctrl->outpath.out1.capture_cnt--;
+
+		vfe_send_outmsg(axi_ctrl,
+			MSG_ID_OUTPUT_SECONDARY, ch0_paddr,
+			ch1_paddr, ch2_paddr,
+			axi_ctrl->share_ctrl->outpath.out1.inst_handle);
+
+	} else {
+		axi_ctrl->share_ctrl->outpath.out1.frame_drop_cnt++;
+		CDBG("path_irq_1 - no free buffer!\n");
+	}
+}
+
+static void vfe32_process_output_path_irq_rdi0(
+			struct axi_ctrl_t *axi_ctrl)
+{
+	uint32_t ping_pong;
+	uint32_t ch0_paddr = 0;
+	/* this must be rdi image output. */
+	struct msm_free_buf *free_buf = NULL;
+	/*RDI0*/
+	CDBG("rdi0 out irq\n");
+	if (axi_ctrl->share_ctrl->operation_mode & VFE_OUTPUTS_RDI0) {
+		free_buf = vfe32_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
+			VFE_MSG_OUTPUT_TERTIARY1, axi_ctrl);
+		if (axi_ctrl->share_ctrl->outpath.out2.capture_cnt > 0 ||
+							free_buf) {
+			ping_pong = msm_camera_io_r(axi_ctrl->
+				share_ctrl->vfebase +
+				VFE_BUS_PING_PONG_STATUS);
+
+			/* Y only channel */
+			ch0_paddr = vfe32_get_ch_addr(ping_pong,
+				axi_ctrl->share_ctrl->vfebase,
+				axi_ctrl->share_ctrl->outpath.out2.ch0);
+
+			pr_debug("%s ch0 = 0x%x\n",
+				__func__, ch0_paddr);
+
+			if (free_buf)
+				vfe32_put_ch_addr(ping_pong,
+					axi_ctrl->share_ctrl->vfebase,
+					axi_ctrl->share_ctrl->outpath.out2.ch0,
+					free_buf->ch_paddr[0]);
+			if (axi_ctrl->share_ctrl->outpath.out2.capture_cnt == 1)
+				axi_ctrl->share_ctrl->
+					outpath.out2.capture_cnt = 0;
+
+			vfe_send_outmsg(axi_ctrl,
+				MSG_ID_OUTPUT_TERTIARY1, ch0_paddr,
+				0, 0,
+				axi_ctrl->share_ctrl->outpath.out2.inst_handle);
+
+		} else {
+			axi_ctrl->share_ctrl->outpath.out2.frame_drop_cnt++;
+			pr_err("path_irq_2 irq - no free buffer for rdi0!\n");
+		}
+	}
+}
+
+static void vfe32_process_output_path_irq_rdi1(
+	struct axi_ctrl_t *axi_ctrl)
+{
+	uint32_t ping_pong;
+	uint32_t ch0_paddr = 0;
+	/* this must be rdi image output. */
+	struct msm_free_buf *free_buf = NULL;
+	/*RDI1*/
+	if (axi_ctrl->share_ctrl->operation_mode & VFE_OUTPUTS_RDI1) {
+		free_buf = vfe32_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
+			VFE_MSG_OUTPUT_TERTIARY2, axi_ctrl);
+		if (axi_ctrl->share_ctrl->outpath.out3.capture_cnt > 0 ||
+							free_buf) {
+			ping_pong = msm_camera_io_r(axi_ctrl->
+				share_ctrl->vfebase +
+				VFE_BUS_PING_PONG_STATUS);
+
+			/* Y channel */
+			ch0_paddr = vfe32_get_ch_addr(ping_pong,
+				axi_ctrl->share_ctrl->vfebase,
+				axi_ctrl->share_ctrl->outpath.out3.ch0);
+			pr_debug("%s ch0 = 0x%x\n",
+				__func__, ch0_paddr);
+
+			if (free_buf)
+				vfe32_put_ch_addr(ping_pong,
+					axi_ctrl->share_ctrl->vfebase,
+					axi_ctrl->share_ctrl->outpath.out3.ch0,
+					free_buf->ch_paddr[0]);
+			if (axi_ctrl->share_ctrl->
+					outpath.out3.capture_cnt == 1)
+				axi_ctrl->share_ctrl->
+				outpath.out3.capture_cnt = 0;
+
+			vfe_send_outmsg(axi_ctrl,
+				MSG_ID_OUTPUT_TERTIARY2, ch0_paddr,
+				0, 0,
+				axi_ctrl->share_ctrl->outpath.out3.inst_handle);
+		} else {
+			axi_ctrl->share_ctrl->outpath.out3.frame_drop_cnt++;
+			pr_err("path_irq irq - no free buffer for rdi1!\n");
+		}
+	}
+}
+
+static uint32_t  vfe32_process_stats_irq_common(
+	struct vfe32_ctrl_type *vfe32_ctrl,
+	uint32_t statsNum, uint32_t newAddr)
+{
+	uint32_t pingpongStatus;
+	uint32_t returnAddr;
+	uint32_t pingpongAddr;
+
+	/* must be 0=ping, 1=pong */
+	pingpongStatus =
+		((msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
+		VFE_BUS_PING_PONG_STATUS))
+	& ((uint32_t)(1<<(statsNum + 7)))) >> (statsNum + 7);
+	/* stats bits starts at 7 */
+	CDBG("statsNum %d, pingpongStatus %d\n", statsNum, pingpongStatus);
+	pingpongAddr =
+		((uint32_t)(vfe32_ctrl->share_ctrl->vfebase +
+				VFE_BUS_STATS_PING_PONG_BASE)) +
+				(3*statsNum)*4 + (1-pingpongStatus)*4;
+	returnAddr = msm_camera_io_r((uint32_t *)pingpongAddr);
+	msm_camera_io_w(newAddr, (uint32_t *)pingpongAddr);
+	return returnAddr;
+}
+
+static void vfe_send_stats_msg(
+	struct vfe32_ctrl_type *vfe32_ctrl,
+	uint32_t bufAddress, uint32_t statsNum)
+{
+	int rc = 0;
+	void *vaddr = NULL;
+	/* fill message with right content. */
+	/* @todo This is causing issues, need further investigate */
+	/* spin_lock_irqsave(&ctrl->state_lock, flags); */
+	struct isp_msg_stats msgStats;
+	uint32_t stats_type;
+	msgStats.frameCounter = vfe32_ctrl->share_ctrl->vfeFrameId;
+	if (vfe32_ctrl->simultaneous_sof_stat)
+		msgStats.frameCounter--;
+	msgStats.buffer = bufAddress;
+	switch (statsNum) {
+	case statsAeNum:{
+		msgStats.id =
+			(!vfe32_use_bayer_stats(vfe32_ctrl)) ? MSG_ID_STATS_AEC
+				: MSG_ID_STATS_BG;
+		stats_type =
+			(!vfe32_use_bayer_stats(vfe32_ctrl)) ?
+				MSM_STATS_TYPE_AEC : MSM_STATS_TYPE_BG;
+		rc = vfe32_ctrl->stats_ops.dispatch(
+				vfe32_ctrl->stats_ops.stats_ctrl,
+				stats_type, bufAddress,
+				&msgStats.buf_idx, &vaddr, &msgStats.fd,
+				vfe32_ctrl->stats_ops.client);
+		}
+		break;
+	case statsAfNum:{
+		msgStats.id =
+			(!vfe32_use_bayer_stats(vfe32_ctrl)) ? MSG_ID_STATS_AF
+				: MSG_ID_STATS_BF;
+		stats_type =
+			(!vfe32_use_bayer_stats(vfe32_ctrl)) ? MSM_STATS_TYPE_AF
+				: MSM_STATS_TYPE_BF;
+		rc = vfe32_ctrl->stats_ops.dispatch(
+				vfe32_ctrl->stats_ops.stats_ctrl,
+				stats_type, bufAddress,
+				&msgStats.buf_idx, &vaddr, &msgStats.fd,
+				vfe32_ctrl->stats_ops.client);
+		}
+		break;
+	case statsAwbNum: {
+		msgStats.id = MSG_ID_STATS_AWB;
+		rc = vfe32_ctrl->stats_ops.dispatch(
+				vfe32_ctrl->stats_ops.stats_ctrl,
+				MSM_STATS_TYPE_AWB, bufAddress,
+				&msgStats.buf_idx, &vaddr, &msgStats.fd,
+				vfe32_ctrl->stats_ops.client);
+		}
+		break;
+
+	case statsIhistNum: {
+		msgStats.id = MSG_ID_STATS_IHIST;
+		rc = vfe32_ctrl->stats_ops.dispatch(
+				vfe32_ctrl->stats_ops.stats_ctrl,
+				MSM_STATS_TYPE_IHIST, bufAddress,
+				&msgStats.buf_idx, &vaddr, &msgStats.fd,
+				vfe32_ctrl->stats_ops.client);
+		}
+		break;
+	case statsRsNum: {
+		msgStats.id = MSG_ID_STATS_RS;
+		rc = vfe32_ctrl->stats_ops.dispatch(
+				vfe32_ctrl->stats_ops.stats_ctrl,
+				MSM_STATS_TYPE_RS, bufAddress,
+				&msgStats.buf_idx, &vaddr, &msgStats.fd,
+				vfe32_ctrl->stats_ops.client);
+		}
+		break;
+	case statsCsNum: {
+		msgStats.id = MSG_ID_STATS_CS;
+		rc = vfe32_ctrl->stats_ops.dispatch(
+				vfe32_ctrl->stats_ops.stats_ctrl,
+				MSM_STATS_TYPE_CS, bufAddress,
+				&msgStats.buf_idx, &vaddr, &msgStats.fd,
+				vfe32_ctrl->stats_ops.client);
+		}
+		break;
+	case statsSkinNum: {
+		msgStats.id = MSG_ID_STATS_BHIST;
+		rc = vfe32_ctrl->stats_ops.dispatch(
+				vfe32_ctrl->stats_ops.stats_ctrl,
+				MSM_STATS_TYPE_BHIST, bufAddress,
+				&msgStats.buf_idx, &vaddr, &msgStats.fd,
+				vfe32_ctrl->stats_ops.client);
+		}
+		break;
+
+	default:
+		goto stats_done;
+	}
+	if (rc == 0) {
+		msgStats.buffer = (uint32_t)vaddr;
+		v4l2_subdev_notify(&vfe32_ctrl->subdev,
+			NOTIFY_VFE_MSG_STATS,
+			&msgStats);
+	} else {
+		pr_err("%s: paddr to idx mapping error, stats_id = %d, paddr = 0x%d",
+			 __func__, msgStats.id, msgStats.buffer);
+	}
+stats_done:
+	/* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
+	return;
+}
+
+static void vfe_send_comp_stats_msg(
+	struct vfe32_ctrl_type *vfe32_ctrl, uint32_t status_bits)
+{
+	struct msm_stats_buf msgStats;
+	uint32_t temp;
+
+	msgStats.frame_id = vfe32_ctrl->share_ctrl->vfeFrameId;
+	if (vfe32_ctrl->simultaneous_sof_stat)
+		msgStats.frame_id--;
+
+	msgStats.status_bits = status_bits;
+
+	msgStats.aec.buff = vfe32_ctrl->aecbgStatsControl.bufToRender;
+	msgStats.awb.buff = vfe32_ctrl->awbStatsControl.bufToRender;
+	msgStats.af.buff = vfe32_ctrl->afbfStatsControl.bufToRender;
+
+	msgStats.ihist.buff = vfe32_ctrl->ihistStatsControl.bufToRender;
+	msgStats.rs.buff = vfe32_ctrl->rsStatsControl.bufToRender;
+	msgStats.cs.buff = vfe32_ctrl->csStatsControl.bufToRender;
+
+	temp = msm_camera_io_r(
+		vfe32_ctrl->share_ctrl->vfebase + VFE_STATS_AWB_SGW_CFG);
+	msgStats.awb_ymin = (0xFF00 & temp) >> 8;
+
+	v4l2_subdev_notify(&vfe32_ctrl->subdev,
+				NOTIFY_VFE_MSG_COMP_STATS,
+				&msgStats);
+}
+
+static void vfe32_process_stats_ae_bg_irq(struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	unsigned long flags;
+	uint32_t addr;
+	uint32_t stats_type;
+	stats_type =
+		(!vfe32_use_bayer_stats(vfe32_ctrl)) ? MSM_STATS_TYPE_AEC
+			: MSM_STATS_TYPE_BG;
+	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, stats_type);
+	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
+	if (addr) {
+		vfe32_ctrl->aecbgStatsControl.bufToRender =
+			vfe32_process_stats_irq_common(vfe32_ctrl, statsAeNum,
+			addr);
+
+		vfe_send_stats_msg(vfe32_ctrl,
+			vfe32_ctrl->aecbgStatsControl.bufToRender, statsAeNum);
+	} else{
+		vfe32_ctrl->aecbgStatsControl.droppedStatsFrameCount++;
+		CDBG("%s: droppedStatsFrameCount = %d", __func__,
+			vfe32_ctrl->aecbgStatsControl.droppedStatsFrameCount);
+	}
+}
+
+static void vfe32_process_stats_awb_irq(struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	unsigned long flags;
+	uint32_t addr;
+	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_AWB);
+	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
+	if (addr) {
+		vfe32_ctrl->awbStatsControl.bufToRender =
+			vfe32_process_stats_irq_common(vfe32_ctrl, statsAwbNum,
+			addr);
+
+		vfe_send_stats_msg(vfe32_ctrl,
+			vfe32_ctrl->awbStatsControl.bufToRender, statsAwbNum);
+	} else{
+		vfe32_ctrl->awbStatsControl.droppedStatsFrameCount++;
+		CDBG("%s: droppedStatsFrameCount = %d", __func__,
+			vfe32_ctrl->awbStatsControl.droppedStatsFrameCount);
+	}
+}
+
+static void vfe32_process_stats_af_bf_irq(struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	unsigned long flags;
+	uint32_t addr;
+	uint32_t stats_type;
+	stats_type =
+		(!vfe32_use_bayer_stats(vfe32_ctrl)) ? MSM_STATS_TYPE_AF
+			: MSM_STATS_TYPE_BF;
+	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, stats_type);
+	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
+	if (addr) {
+		vfe32_ctrl->afbfStatsControl.bufToRender =
+			vfe32_process_stats_irq_common(vfe32_ctrl, statsAfNum,
+			addr);
+
+		vfe_send_stats_msg(vfe32_ctrl,
+			vfe32_ctrl->afbfStatsControl.bufToRender, statsAfNum);
+	} else{
+		vfe32_ctrl->afbfStatsControl.droppedStatsFrameCount++;
+		CDBG("%s: droppedStatsFrameCount = %d", __func__,
+			vfe32_ctrl->afbfStatsControl.droppedStatsFrameCount);
+	}
+}
+
+static void vfe32_process_stats_bhist_irq(struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	unsigned long flags;
+	uint32_t addr;
+	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_BHIST);
+	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
+	if (addr) {
+		vfe32_ctrl->bhistStatsControl.bufToRender =
+			vfe32_process_stats_irq_common(vfe32_ctrl,
+				statsSkinNum, addr);
+
+		vfe_send_stats_msg(vfe32_ctrl,
+			vfe32_ctrl->bhistStatsControl.bufToRender,
+			statsSkinNum);
+	} else{
+		vfe32_ctrl->bhistStatsControl.droppedStatsFrameCount++;
+		CDBG("%s: droppedStatsFrameCount = %d", __func__,
+			vfe32_ctrl->bhistStatsControl.droppedStatsFrameCount);
+	}
+}
+
+static void vfe32_process_stats_ihist_irq(struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	unsigned long flags;
+	uint32_t addr;
+	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_IHIST);
+	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
+	if (addr) {
+		vfe32_ctrl->ihistStatsControl.bufToRender =
+			vfe32_process_stats_irq_common(
+			vfe32_ctrl, statsIhistNum, addr);
+
+		vfe_send_stats_msg(vfe32_ctrl,
+			vfe32_ctrl->ihistStatsControl.bufToRender,
+			statsIhistNum);
+	} else {
+		vfe32_ctrl->ihistStatsControl.droppedStatsFrameCount++;
+		CDBG("%s: droppedStatsFrameCount = %d", __func__,
+			vfe32_ctrl->ihistStatsControl.droppedStatsFrameCount);
+	}
+}
+
+static void vfe32_process_stats_rs_irq(struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	unsigned long flags;
+	uint32_t addr;
+	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_RS);
+	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
+	if (addr) {
+		vfe32_ctrl->rsStatsControl.bufToRender =
+			vfe32_process_stats_irq_common(vfe32_ctrl, statsRsNum,
+			addr);
+
+		vfe_send_stats_msg(vfe32_ctrl,
+			vfe32_ctrl->rsStatsControl.bufToRender, statsRsNum);
+	} else {
+		vfe32_ctrl->rsStatsControl.droppedStatsFrameCount++;
+		CDBG("%s: droppedStatsFrameCount = %d", __func__,
+			vfe32_ctrl->rsStatsControl.droppedStatsFrameCount);
+	}
+}
+
+static void vfe32_process_stats_cs_irq(struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	unsigned long flags;
+	uint32_t addr;
+	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_CS);
+	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
+	if (addr) {
+		vfe32_ctrl->csStatsControl.bufToRender =
+			vfe32_process_stats_irq_common(vfe32_ctrl, statsCsNum,
+			addr);
+
+			vfe_send_stats_msg(vfe32_ctrl,
+				vfe32_ctrl->csStatsControl.bufToRender,
+				statsCsNum);
+	} else {
+		vfe32_ctrl->csStatsControl.droppedStatsFrameCount++;
+		CDBG("%s: droppedStatsFrameCount = %d", __func__,
+			vfe32_ctrl->csStatsControl.droppedStatsFrameCount);
+	}
+}
+
+static void vfe32_process_stats(struct vfe32_ctrl_type *vfe32_ctrl,
+	uint32_t status_bits)
+{
+	unsigned long flags;
+	int32_t process_stats = false;
+	uint32_t addr;
+	uint32_t stats_type;
+
+	CDBG("%s, stats = 0x%x\n", __func__, status_bits);
+	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
+	stats_type =
+		(!vfe32_use_bayer_stats(vfe32_ctrl)) ? MSM_STATS_TYPE_AEC
+			: MSM_STATS_TYPE_BG;
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_AEC_BG) {
+		addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl,
+				stats_type);
+		if (addr) {
+			vfe32_ctrl->aecbgStatsControl.bufToRender =
+				vfe32_process_stats_irq_common(
+				vfe32_ctrl, statsAeNum,	addr);
+			process_stats = true;
+		} else{
+			vfe32_ctrl->aecbgStatsControl.bufToRender = 0;
+			vfe32_ctrl->aecbgStatsControl.droppedStatsFrameCount++;
+		}
+	} else {
+		vfe32_ctrl->aecbgStatsControl.bufToRender = 0;
+	}
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_AWB) {
+		addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl,
+			MSM_STATS_TYPE_AWB);
+		if (addr) {
+			vfe32_ctrl->awbStatsControl.bufToRender =
+				vfe32_process_stats_irq_common(
+				vfe32_ctrl, statsAwbNum,
+				addr);
+			process_stats = true;
+		} else{
+			vfe32_ctrl->awbStatsControl.droppedStatsFrameCount++;
+			vfe32_ctrl->awbStatsControl.bufToRender = 0;
+		}
+	} else {
+		vfe32_ctrl->awbStatsControl.bufToRender = 0;
+	}
+
+	stats_type =
+		(!vfe32_use_bayer_stats(vfe32_ctrl)) ? MSM_STATS_TYPE_AF
+			: MSM_STATS_TYPE_BF;
+	if (status_bits & VFE_IRQ_STATUS0_STATS_AF_BF) {
+		addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl,
+					stats_type);
+		if (addr) {
+			vfe32_ctrl->afbfStatsControl.bufToRender =
+				vfe32_process_stats_irq_common(
+				vfe32_ctrl, statsAfNum,
+				addr);
+			process_stats = true;
+		} else {
+			vfe32_ctrl->afbfStatsControl.bufToRender = 0;
+			vfe32_ctrl->afbfStatsControl.droppedStatsFrameCount++;
+		}
+	} else {
+		vfe32_ctrl->afbfStatsControl.bufToRender = 0;
+	}
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_IHIST) {
+		addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl,
+					MSM_STATS_TYPE_IHIST);
+		if (addr) {
+			vfe32_ctrl->ihistStatsControl.bufToRender =
+				vfe32_process_stats_irq_common(
+				vfe32_ctrl, statsIhistNum,
+				addr);
+			process_stats = true;
+		} else {
+			vfe32_ctrl->ihistStatsControl.droppedStatsFrameCount++;
+			vfe32_ctrl->ihistStatsControl.bufToRender = 0;
+		}
+	} else {
+		vfe32_ctrl->ihistStatsControl.bufToRender = 0;
+	}
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_RS) {
+		addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl,
+					MSM_STATS_TYPE_RS);
+		if (addr) {
+			vfe32_ctrl->rsStatsControl.bufToRender =
+				vfe32_process_stats_irq_common(
+				vfe32_ctrl, statsRsNum,
+				addr);
+			process_stats = true;
+		} else {
+			vfe32_ctrl->rsStatsControl.droppedStatsFrameCount++;
+			vfe32_ctrl->rsStatsControl.bufToRender = 0;
+		}
+	} else {
+		vfe32_ctrl->rsStatsControl.bufToRender = 0;
+	}
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_CS) {
+		addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl,
+					MSM_STATS_TYPE_CS);
+		if (addr) {
+			vfe32_ctrl->csStatsControl.bufToRender =
+				vfe32_process_stats_irq_common(
+				vfe32_ctrl, statsCsNum,
+				addr);
+			process_stats = true;
+		} else {
+			vfe32_ctrl->csStatsControl.droppedStatsFrameCount++;
+			vfe32_ctrl->csStatsControl.bufToRender = 0;
+		}
+	} else {
+		vfe32_ctrl->csStatsControl.bufToRender = 0;
+	}
+	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
+	if (process_stats)
+		vfe_send_comp_stats_msg(vfe32_ctrl, status_bits);
+
+	return;
+}
+
+static void vfe32_process_stats_irq(
+	struct vfe32_ctrl_type *vfe32_ctrl, uint32_t irqstatus)
+{
+	uint32_t status_bits = VFE_COM_STATUS & irqstatus;
+	if ((vfe32_ctrl->hfr_mode != HFR_MODE_OFF) &&
+		(vfe32_ctrl->share_ctrl->vfeFrameId %
+		 vfe32_ctrl->hfr_mode != 0)) {
+		CDBG("Skip the stats when HFR enabled\n");
+		return;
+	}
+
+	vfe32_process_stats(vfe32_ctrl, status_bits);
+	return;
+}
+
+static void vfe32_process_irq(
+	struct vfe32_ctrl_type *vfe32_ctrl, uint32_t irqstatus)
+{
+	if (irqstatus &
+		VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK) {
+		vfe32_process_stats_irq(vfe32_ctrl, irqstatus);
+		return;
+	}
+
+	switch (irqstatus) {
+	case VFE_IRQ_STATUS0_CAMIF_SOF_MASK:
+		CDBG("irq	camifSofIrq\n");
+		vfe32_process_camif_sof_irq(vfe32_ctrl);
+		break;
+	case VFE_IRQ_STATUS0_REG_UPDATE_MASK:
+		CDBG("irq	regUpdateIrq\n");
+		vfe32_process_reg_update_irq(vfe32_ctrl);
+		break;
+	case VFE_IRQ_STATUS1_RDI0_REG_UPDATE:
+		CDBG("irq	rdi0 regUpdateIrq\n");
+		vfe32_process_rdi0_reg_update_irq(vfe32_ctrl);
+		break;
+	case VFE_IRQ_STATUS1_RDI1_REG_UPDATE:
+		CDBG("irq	rdi1 regUpdateIrq\n");
+		vfe32_process_rdi1_reg_update_irq(vfe32_ctrl);
+		break;
+	case VFE_IMASK_WHILE_STOPPING_1:
+		CDBG("irq	resetAckIrq\n");
+		vfe32_process_reset_irq(vfe32_ctrl);
+		break;
+	case VFE_IRQ_STATUS0_STATS_AEC_BG:
+		CDBG("Stats AEC irq occured.\n");
+		vfe32_process_stats_ae_bg_irq(vfe32_ctrl);
+		break;
+	case VFE_IRQ_STATUS0_STATS_AWB:
+		CDBG("Stats AWB irq occured.\n");
+		vfe32_process_stats_awb_irq(vfe32_ctrl);
+		break;
+	case VFE_IRQ_STATUS0_STATS_AF_BF:
+		CDBG("Stats AF irq occured.\n");
+		vfe32_process_stats_af_bf_irq(vfe32_ctrl);
+		break;
+	case VFE_IRQ_STATUS0_STATS_SK_BHIST:
+		CDBG("Stats BHIST irq occured.\n");
+		vfe32_process_stats_bhist_irq(vfe32_ctrl);
+		break;
+	case VFE_IRQ_STATUS0_STATS_IHIST:
+		CDBG("Stats IHIST irq occured.\n");
+		vfe32_process_stats_ihist_irq(vfe32_ctrl);
+		break;
+	case VFE_IRQ_STATUS0_STATS_RS:
+		CDBG("Stats RS irq occured.\n");
+		vfe32_process_stats_rs_irq(vfe32_ctrl);
+		break;
+	case VFE_IRQ_STATUS0_STATS_CS:
+		CDBG("Stats CS irq occured.\n");
+		vfe32_process_stats_cs_irq(vfe32_ctrl);
+		break;
+	case VFE_IRQ_STATUS0_SYNC_TIMER0:
+		CDBG("SYNC_TIMER 0 irq occured.\n");
+		vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+			vfe32_ctrl->share_ctrl->vfeFrameId,
+			MSG_ID_SYNC_TIMER0_DONE);
+		break;
+	case VFE_IRQ_STATUS0_SYNC_TIMER1:
+		CDBG("SYNC_TIMER 1 irq occured.\n");
+		vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+			vfe32_ctrl->share_ctrl->vfeFrameId,
+			MSG_ID_SYNC_TIMER1_DONE);
+		break;
+	case VFE_IRQ_STATUS0_SYNC_TIMER2:
+		CDBG("SYNC_TIMER 2 irq occured.\n");
+		vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+			vfe32_ctrl->share_ctrl->vfeFrameId,
+			MSG_ID_SYNC_TIMER2_DONE);
+		break;
+	default:
+		pr_err("Invalid IRQ status\n");
+	}
+}
+
+static void axi32_do_tasklet(unsigned long data)
+{
+	unsigned long flags;
+	struct axi_ctrl_t *axi_ctrl = (struct axi_ctrl_t *)data;
+	struct vfe32_ctrl_type *vfe32_ctrl = axi_ctrl->share_ctrl->vfe32_ctrl;
+	struct vfe32_isr_queue_cmd *qcmd = NULL;
+	int stat_interrupt;
+
+	CDBG("=== axi32_do_tasklet start ===\n");
+
+	while (atomic_read(&irq_cnt)) {
+		spin_lock_irqsave(&axi_ctrl->tasklet_lock, flags);
+		qcmd = list_first_entry(&axi_ctrl->tasklet_q,
+			struct vfe32_isr_queue_cmd, list);
+		atomic_sub(1, &irq_cnt);
+
+		if (!qcmd) {
+			spin_unlock_irqrestore(&axi_ctrl->tasklet_lock,
+				flags);
+			return;
+		}
+
+		list_del(&qcmd->list);
+		spin_unlock_irqrestore(&axi_ctrl->tasklet_lock,
+			flags);
+
+		if (axi_ctrl->share_ctrl->stats_comp) {
+			stat_interrupt = (qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK);
+		} else {
+			stat_interrupt =
+				(qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_AEC_BG) |
+				(qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_AWB) |
+				(qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_AF_BF) |
+				(qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_IHIST) |
+				(qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_RS) |
+				(qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_CS);
+		}
+		if (qcmd->vfeInterruptStatus0 &
+				VFE_IRQ_STATUS0_CAMIF_SOF_MASK) {
+			if (stat_interrupt)
+				vfe32_ctrl->simultaneous_sof_stat = 1;
+			v4l2_subdev_notify(&vfe32_ctrl->subdev,
+				NOTIFY_VFE_IRQ,
+				(void *)VFE_IRQ_STATUS0_CAMIF_SOF_MASK);
+		}
+
+		/* interrupt to be processed,  *qcmd has the payload.  */
+		if (qcmd->vfeInterruptStatus0 &
+				VFE_IRQ_STATUS0_REG_UPDATE_MASK)
+			v4l2_subdev_notify(&vfe32_ctrl->subdev,
+				NOTIFY_VFE_IRQ,
+				(void *)VFE_IRQ_STATUS0_REG_UPDATE_MASK);
+
+		if (qcmd->vfeInterruptStatus1 &
+				VFE_IRQ_STATUS1_RDI0_REG_UPDATE_MASK)
+			v4l2_subdev_notify(&vfe32_ctrl->subdev,
+				NOTIFY_VFE_IRQ,
+				(void *)VFE_IRQ_STATUS1_RDI0_REG_UPDATE);
+
+		if (qcmd->vfeInterruptStatus1 &
+				VFE_IRQ_STATUS1_RDI1_REG_UPDATE_MASK)
+			v4l2_subdev_notify(&vfe32_ctrl->subdev,
+				NOTIFY_VFE_IRQ,
+				(void *)VFE_IRQ_STATUS1_RDI1_REG_UPDATE);
+
+		if (qcmd->vfeInterruptStatus1 &
+				VFE_IMASK_WHILE_STOPPING_1)
+			v4l2_subdev_notify(&vfe32_ctrl->subdev,
+				NOTIFY_VFE_IRQ,
+				(void *)VFE_IMASK_WHILE_STOPPING_1);
+
+		if (atomic_read(&axi_ctrl->share_ctrl->handle_common_irq)) {
+			if (qcmd->vfeInterruptStatus1 &
+					VFE32_IMASK_COMMON_ERROR_ONLY_1) {
+				pr_err("irq	errorIrq\n");
+				vfe32_process_common_error_irq(
+					axi_ctrl,
+					qcmd->vfeInterruptStatus1 &
+					VFE32_IMASK_COMMON_ERROR_ONLY_1);
+			}
+
+			v4l2_subdev_notify(&axi_ctrl->subdev,
+				NOTIFY_AXI_IRQ,
+				(void *)qcmd->vfeInterruptStatus0);
+		}
+
+		if (atomic_read(&axi_ctrl->share_ctrl->vstate)) {
+			if (qcmd->vfeInterruptStatus1 &
+					VFE32_IMASK_VFE_ERROR_ONLY_1) {
+				pr_err("irq	errorIrq\n");
+				vfe32_process_error_irq(
+					axi_ctrl,
+					qcmd->vfeInterruptStatus1 &
+					VFE32_IMASK_VFE_ERROR_ONLY_1);
+			}
+
+			/* then process stats irq. */
+			if (axi_ctrl->share_ctrl->stats_comp) {
+				/* process stats comb interrupt. */
+				if (qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK) {
+					CDBG("Stats composite irq occured.\n");
+					v4l2_subdev_notify(&vfe32_ctrl->subdev,
+					NOTIFY_VFE_IRQ,
+					(void *)qcmd->vfeInterruptStatus0);
+				}
+			} else {
+				/* process individual stats interrupt. */
+				if (qcmd->vfeInterruptStatus0 &
+						VFE_IRQ_STATUS0_STATS_AEC_BG)
+					v4l2_subdev_notify(&vfe32_ctrl->subdev,
+					NOTIFY_VFE_IRQ,
+					(void *)VFE_IRQ_STATUS0_STATS_AEC_BG);
+
+				if (qcmd->vfeInterruptStatus0 &
+						VFE_IRQ_STATUS0_STATS_AWB)
+					v4l2_subdev_notify(&vfe32_ctrl->subdev,
+					NOTIFY_VFE_IRQ,
+					(void *)VFE_IRQ_STATUS0_STATS_AWB);
+
+				if (qcmd->vfeInterruptStatus0 &
+						VFE_IRQ_STATUS0_STATS_AF_BF)
+					v4l2_subdev_notify(&vfe32_ctrl->subdev,
+					NOTIFY_VFE_IRQ,
+					(void *)VFE_IRQ_STATUS0_STATS_AF_BF);
+				if (qcmd->vfeInterruptStatus0 &
+						VFE_IRQ_STATUS0_STATS_SK_BHIST)
+					v4l2_subdev_notify(&vfe32_ctrl->subdev,
+					NOTIFY_VFE_IRQ,
+					(void *)VFE_IRQ_STATUS0_STATS_SK_BHIST);
+
+				if (qcmd->vfeInterruptStatus0 &
+						VFE_IRQ_STATUS0_STATS_IHIST)
+					v4l2_subdev_notify(&vfe32_ctrl->subdev,
+					NOTIFY_VFE_IRQ,
+					(void *)VFE_IRQ_STATUS0_STATS_IHIST);
+
+				if (qcmd->vfeInterruptStatus0 &
+						VFE_IRQ_STATUS0_STATS_RS)
+					v4l2_subdev_notify(&vfe32_ctrl->subdev,
+					NOTIFY_VFE_IRQ,
+					(void *)VFE_IRQ_STATUS0_STATS_RS);
+
+				if (qcmd->vfeInterruptStatus0 &
+						VFE_IRQ_STATUS0_STATS_CS)
+					v4l2_subdev_notify(&vfe32_ctrl->subdev,
+					NOTIFY_VFE_IRQ,
+					(void *)VFE_IRQ_STATUS0_STATS_CS);
+
+				if (qcmd->vfeInterruptStatus0 &
+						VFE_IRQ_STATUS0_SYNC_TIMER0)
+					v4l2_subdev_notify(&vfe32_ctrl->subdev,
+					NOTIFY_VFE_IRQ,
+					(void *)VFE_IRQ_STATUS0_SYNC_TIMER0);
+
+				if (qcmd->vfeInterruptStatus0 &
+						VFE_IRQ_STATUS0_SYNC_TIMER1)
+					v4l2_subdev_notify(&vfe32_ctrl->subdev,
+					NOTIFY_VFE_IRQ,
+					(void *)VFE_IRQ_STATUS0_SYNC_TIMER1);
+
+				if (qcmd->vfeInterruptStatus0 &
+						VFE_IRQ_STATUS0_SYNC_TIMER2)
+					v4l2_subdev_notify(&vfe32_ctrl->subdev,
+					NOTIFY_VFE_IRQ,
+					(void *)VFE_IRQ_STATUS0_SYNC_TIMER2);
+			}
+		}
+		vfe32_ctrl->simultaneous_sof_stat = 0;
+		kfree(qcmd);
+	}
+	CDBG("=== axi32_do_tasklet end ===\n");
+}
+
+static irqreturn_t vfe32_parse_irq(int irq_num, void *data)
+{
+	unsigned long flags;
+	struct vfe32_irq_status irq;
+	struct vfe32_isr_queue_cmd *qcmd;
+	struct axi_ctrl_t *axi_ctrl = data;
+
+	CDBG("vfe_parse_irq\n");
+
+	vfe32_read_irq_status(axi_ctrl, &irq);
+
+	if ((irq.vfeIrqStatus0 == 0) && (irq.vfeIrqStatus1 == 0)) {
+		CDBG("vfe_parse_irq: vfeIrqStatus0 & 1 are both 0!\n");
+		return IRQ_HANDLED;
+	}
+
+	qcmd = kzalloc(sizeof(struct vfe32_isr_queue_cmd),
+		GFP_ATOMIC);
+	if (!qcmd) {
+		pr_err("vfe_parse_irq: qcmd malloc failed!\n");
+		return IRQ_HANDLED;
+	}
+
+	spin_lock_irqsave(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
+	if (axi_ctrl->share_ctrl->stop_ack_pending) {
+		irq.vfeIrqStatus0 &= VFE_IMASK_WHILE_STOPPING_0;
+		irq.vfeIrqStatus1 &= VFE_IMASK_WHILE_STOPPING_1;
+	}
+	spin_unlock_irqrestore(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
+
+	CDBG("vfe_parse_irq: Irq_status0 = 0x%x, Irq_status1 = 0x%x.\n",
+		irq.vfeIrqStatus0, irq.vfeIrqStatus1);
+
+	qcmd->vfeInterruptStatus0 = irq.vfeIrqStatus0;
+	qcmd->vfeInterruptStatus1 = irq.vfeIrqStatus1;
+
+	spin_lock_irqsave(&axi_ctrl->tasklet_lock, flags);
+	list_add_tail(&qcmd->list, &axi_ctrl->tasklet_q);
+
+	atomic_add(1, &irq_cnt);
+	spin_unlock_irqrestore(&axi_ctrl->tasklet_lock, flags);
+	tasklet_schedule(&axi_ctrl->vfe32_tasklet);
+	return IRQ_HANDLED;
+}
+
+int msm_axi_subdev_isr_routine(struct v4l2_subdev *sd,
+	u32 status, bool *handled)
+{
+	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+	irqreturn_t ret;
+	pr_info("%s E ", __func__);
+	ret = vfe32_parse_irq(axi_ctrl->vfeirq->start, axi_ctrl);
+	*handled = TRUE;
+	return 0;
+}
+
+static long vfe_stats_bufq_sub_ioctl(
+	struct vfe32_ctrl_type *vfe_ctrl,
+	struct msm_vfe_cfg_cmd *cmd, void *ion_client, int domain_num)
+{
+	long rc = 0;
+	switch (cmd->cmd_type) {
+	case VFE_CMD_STATS_REQBUF:
+	if (!vfe_ctrl->stats_ops.stats_ctrl) {
+		/* stats_ctrl has not been init yet */
+		rc = msm_stats_buf_ops_init(&vfe_ctrl->stats_ctrl,
+				(struct ion_client *)ion_client,
+				&vfe_ctrl->stats_ops);
+		if (rc < 0) {
+			pr_err("%s: cannot init stats ops", __func__);
+			goto end;
+		}
+		rc = vfe_ctrl->stats_ops.stats_ctrl_init(&vfe_ctrl->stats_ctrl);
+		if (rc < 0) {
+			pr_err("%s: cannot init stats_ctrl ops", __func__);
+			memset(&vfe_ctrl->stats_ops, 0,
+				sizeof(vfe_ctrl->stats_ops));
+			goto end;
+		}
+		if (sizeof(struct msm_stats_reqbuf) != cmd->length) {
+			/* error. the length not match */
+			pr_err("%s: stats reqbuf input size = %d,\n"
+				"struct size = %d, mitch match\n",
+				 __func__, cmd->length,
+				sizeof(struct msm_stats_reqbuf));
+			rc = -EINVAL ;
+			goto end;
+		}
+	}
+	rc = vfe_ctrl->stats_ops.reqbuf(
+			&vfe_ctrl->stats_ctrl,
+			(struct msm_stats_reqbuf *)cmd->value,
+			vfe_ctrl->stats_ops.client);
+	break;
+	case VFE_CMD_STATS_ENQUEUEBUF:
+	if (sizeof(struct msm_stats_buf_info) != cmd->length) {
+		/* error. the length not match */
+		pr_err("%s: stats enqueuebuf input size = %d,\n"
+			"struct size = %d, mitch match\n",
+			 __func__, cmd->length,
+			sizeof(struct msm_stats_buf_info));
+			rc = -EINVAL;
+			goto end;
+	}
+	rc = vfe_ctrl->stats_ops.enqueue_buf(
+			&vfe_ctrl->stats_ctrl,
+			(struct msm_stats_buf_info *)cmd->value,
+			vfe_ctrl->stats_ops.client, domain_num);
+	break;
+	case VFE_CMD_STATS_FLUSH_BUFQ:
+	{
+		struct msm_stats_flush_bufq *flush_req = NULL;
+		flush_req = (struct msm_stats_flush_bufq *)cmd->value;
+		if (sizeof(struct msm_stats_flush_bufq) != cmd->length) {
+			/* error. the length not match */
+			pr_err("%s: stats flush queue input size = %d,\n"
+				"struct size = %d, mitch match\n",
+				__func__, cmd->length,
+				sizeof(struct msm_stats_flush_bufq));
+			rc = -EINVAL;
+			goto end;
+	}
+	rc = vfe_ctrl->stats_ops.bufq_flush(
+			&vfe_ctrl->stats_ctrl,
+			(enum msm_stats_enum_type)flush_req->stats_type,
+			vfe_ctrl->stats_ops.client);
+	}
+	break;
+	case VFE_CMD_STATS_UNREGBUF:
+	{
+		struct msm_stats_reqbuf *req_buf = NULL;
+		req_buf = (struct msm_stats_reqbuf *)cmd->value;
+		if (sizeof(struct msm_stats_reqbuf) != cmd->length) {
+			/* error. the length not match */
+			pr_err("%s: stats reqbuf input size = %d,\n"
+				"struct size = %d, mitch match\n",
+				 __func__, cmd->length,
+				sizeof(struct msm_stats_reqbuf));
+			rc = -EINVAL ;
+			goto end;
+		}
+		rc = vfe32_stats_unregbuf(vfe_ctrl, req_buf, domain_num);
+	}
+	break;
+	default:
+		rc = -1;
+		pr_err("%s: cmd_type %d not supported", __func__,
+			cmd->cmd_type);
+	break;
+	}
+end:
+	return rc;
+}
+
+static long msm_vfe_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int subdev_cmd, void *arg)
+{
+	struct msm_cam_media_controller *pmctl =
+		(struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
+	struct vfe32_ctrl_type *vfe32_ctrl =
+		(struct vfe32_ctrl_type *)v4l2_get_subdevdata(sd);
+	struct msm_isp_cmd vfecmd;
+	struct msm_camvfe_params *vfe_params;
+	struct msm_vfe_cfg_cmd *cmd;
+	void *data;
+
+	long rc = 0;
+	struct vfe_cmd_stats_buf *scfg = NULL;
+	struct vfe_cmd_stats_ack *sack = NULL;
+
+	if (!vfe32_ctrl->share_ctrl->vfebase) {
+		pr_err("%s: base address unmapped\n", __func__);
+		return -EFAULT;
+	}
+
+	CDBG("%s\n", __func__);
+	if (subdev_cmd == VIDIOC_MSM_VFE_INIT) {
+		CDBG("%s init\n", __func__);
+		return msm_vfe_subdev_init(sd);
+	} else if (subdev_cmd == VIDIOC_MSM_VFE_RELEASE) {
+		msm_vfe_subdev_release(sd);
+		return 0;
+	}
+	vfe_params = (struct msm_camvfe_params *)arg;
+	cmd = vfe_params->vfe_cfg;
+	data = vfe_params->data;
+	switch (cmd->cmd_type) {
+	case CMD_VFE_PROCESS_IRQ:
+		vfe32_process_irq(vfe32_ctrl, (uint32_t) data);
+		return rc;
+	case VFE_CMD_STATS_REQBUF:
+	case VFE_CMD_STATS_ENQUEUEBUF:
+	case VFE_CMD_STATS_FLUSH_BUFQ:
+	case VFE_CMD_STATS_UNREGBUF:
+		/* for easy porting put in one envelope */
+		rc = vfe_stats_bufq_sub_ioctl(vfe32_ctrl,
+				cmd, vfe_params->data, pmctl->domain_num);
+		return rc;
+	default:
+		if (cmd->cmd_type != CMD_CONFIG_PING_ADDR &&
+		cmd->cmd_type != CMD_CONFIG_PONG_ADDR &&
+		cmd->cmd_type != CMD_CONFIG_FREE_BUF_ADDR &&
+		cmd->cmd_type != CMD_STATS_AEC_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_AWB_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_IHIST_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_RS_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_CS_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_BG_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_BF_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_BHIST_BUF_RELEASE &&
+		cmd->cmd_type != CMD_VFE_PIX_SOF_COUNT_UPDATE &&
+		cmd->cmd_type != CMD_VFE_COUNT_PIX_SOF_ENABLE) {
+			if (copy_from_user(&vfecmd,
+					(void __user *)(cmd->value),
+					sizeof(vfecmd))) {
+				pr_err("%s %d: copy_from_user failed\n",
+					__func__, __LINE__);
+				return -EFAULT;
+			}
+		} else {
+			/* here eith stats release or frame release. */
+			if (cmd->cmd_type != CMD_CONFIG_PING_ADDR &&
+				cmd->cmd_type != CMD_CONFIG_PONG_ADDR &&
+				cmd->cmd_type != CMD_CONFIG_FREE_BUF_ADDR) {
+				/* then must be stats release. */
+				if (!data) {
+					pr_err("%s: data = NULL, cmd->cmd_type = %d",
+						__func__, cmd->cmd_type);
+					return -EFAULT;
+				}
+				sack = kmalloc(sizeof(struct vfe_cmd_stats_ack),
+							GFP_ATOMIC);
+				if (!sack) {
+					pr_err("%s: no mem for cmd->cmd_type = %d",
+					 __func__, cmd->cmd_type);
+					return -ENOMEM;
+				}
+				sack->nextStatsBuf = *(uint32_t *)data;
+			}
+		}
+	}
+
+	CDBG("%s: cmdType = %d\n", __func__, cmd->cmd_type);
+
+	if ((cmd->cmd_type == CMD_STATS_AF_ENABLE)    ||
+		(cmd->cmd_type == CMD_STATS_AWB_ENABLE)   ||
+		(cmd->cmd_type == CMD_STATS_IHIST_ENABLE) ||
+		(cmd->cmd_type == CMD_STATS_RS_ENABLE)    ||
+		(cmd->cmd_type == CMD_STATS_CS_ENABLE)    ||
+		(cmd->cmd_type == CMD_STATS_AEC_ENABLE)   ||
+		(cmd->cmd_type == CMD_STATS_BG_ENABLE)    ||
+		(cmd->cmd_type == CMD_STATS_BF_ENABLE)    ||
+		(cmd->cmd_type == CMD_STATS_BHIST_ENABLE)) {
+		struct axidata *axid;
+		axid = data;
+		if (!axid) {
+			rc = -EFAULT;
+			goto vfe32_config_done;
+		}
+		CDBG("%s: cmdType = %d\n", __func__, cmd->cmd_type);
+
+		if ((cmd->cmd_type == CMD_STATS_AF_ENABLE)    ||
+			(cmd->cmd_type == CMD_STATS_AWB_ENABLE)   ||
+			(cmd->cmd_type == CMD_STATS_IHIST_ENABLE) ||
+			(cmd->cmd_type == CMD_STATS_RS_ENABLE)    ||
+			(cmd->cmd_type == CMD_STATS_CS_ENABLE)    ||
+			(cmd->cmd_type == CMD_STATS_AEC_ENABLE)) {
+				scfg = NULL;
+				/* individual */
+				goto vfe32_config_done;
+		}
+		switch (cmd->cmd_type) {
+		case CMD_STATS_AEC_ENABLE:
+		case CMD_STATS_BG_ENABLE:
+		case CMD_STATS_BF_ENABLE:
+		case CMD_STATS_BHIST_ENABLE:
+		case CMD_STATS_AWB_ENABLE:
+		case CMD_STATS_IHIST_ENABLE:
+		case CMD_STATS_RS_ENABLE:
+		case CMD_STATS_CS_ENABLE:
+		default:
+			pr_err("%s Unsupported cmd type %d",
+				__func__, cmd->cmd_type);
+			break;
+		}
+		goto vfe32_config_done;
+	}
+	switch (cmd->cmd_type) {
+	case CMD_GENERAL:
+		rc = vfe32_proc_general(pmctl, &vfecmd, vfe32_ctrl);
+	break;
+	case CMD_VFE_COUNT_PIX_SOF_ENABLE: {
+		int enable = *((int *)cmd->value);
+		if (enable)
+			vfe32_ctrl->vfe_sof_count_enable = TRUE;
+		else
+			vfe32_ctrl->vfe_sof_count_enable = false;
+	}
+	break;
+	case CMD_VFE_PIX_SOF_COUNT_UPDATE:
+		if (!vfe32_ctrl->vfe_sof_count_enable)
+			vfe32_ctrl->share_ctrl->vfeFrameId =
+			*((uint32_t *)vfe_params->data);
+	break;
+	case CMD_CONFIG_PING_ADDR: {
+		int path = *((int *)cmd->value);
+		struct vfe32_output_ch *outch =
+			vfe32_get_ch(path, vfe32_ctrl->share_ctrl);
+		outch->ping = *((struct msm_free_buf *)data);
+	}
+	break;
+
+	case CMD_CONFIG_PONG_ADDR: {
+		int path = *((int *)cmd->value);
+		struct vfe32_output_ch *outch =
+			vfe32_get_ch(path, vfe32_ctrl->share_ctrl);
+		outch->pong = *((struct msm_free_buf *)data);
+	}
+	break;
+
+	case CMD_CONFIG_FREE_BUF_ADDR: {
+		int path = *((int *)cmd->value);
+		struct vfe32_output_ch *outch =
+			vfe32_get_ch(path, vfe32_ctrl->share_ctrl);
+		outch->free_buf = *((struct msm_free_buf *)data);
+	}
+	break;
+
+	case CMD_SNAP_BUF_RELEASE:
+		break;
+
+	default:
+		pr_err("%s Unsupported AXI configuration %x ", __func__,
+			cmd->cmd_type);
+	break;
+	}
+vfe32_config_done:
+	kfree(scfg);
+	kfree(sack);
+	CDBG("%s done: rc = %d\n", __func__, (int) rc);
+	return rc;
+}
+
+static struct msm_cam_clk_info vfe32_clk_info[] = {
+	{"vfe_clk", 228570000},
+	{"vfe_pclk", -1},
+	{"csi_vfe_clk", -1},
+};
+
+static int msm_axi_subdev_s_crystal_freq(struct v4l2_subdev *sd,
+						u32 freq, u32 flags)
+{
+	int rc = 0;
+	int round_rate;
+	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+
+	if (axi_ctrl->share_ctrl->dual_enabled)
+		return rc;
+
+	round_rate = clk_round_rate(axi_ctrl->vfe_clk[0], freq);
+	if (rc < 0) {
+		pr_err("%s: clk_round_rate failed %d\n",
+					__func__, rc);
+		return rc;
+	}
+
+	vfe_clk_rate = round_rate;
+	rc = clk_set_rate(axi_ctrl->vfe_clk[0], round_rate);
+	if (rc < 0)
+		pr_err("%s: clk_set_rate failed %d\n",
+					__func__, rc);
+
+	return rc;
+}
+
+static const struct v4l2_subdev_core_ops msm_vfe_subdev_core_ops = {
+	.ioctl = msm_vfe_subdev_ioctl,
+};
+
+static const struct v4l2_subdev_ops msm_vfe_subdev_ops = {
+	.core = &msm_vfe_subdev_core_ops,
+};
+
+int msm_axi_subdev_init(struct v4l2_subdev *sd,
+	uint8_t dual_enabled)
+{
+	int rc = 0;
+	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+	struct msm_cam_media_controller *mctl =
+		v4l2_get_subdev_hostdata(sd);
+	if (mctl == NULL) {
+		rc = -EINVAL;
+		goto mctl_failed;
+	}
+
+	axi_ctrl->share_ctrl->axi_ref_cnt++;
+	if (axi_ctrl->share_ctrl->axi_ref_cnt > 1)
+		return rc;
+	axi_ctrl->share_ctrl->dual_enabled = dual_enabled;
+	spin_lock_init(&axi_ctrl->tasklet_lock);
+	INIT_LIST_HEAD(&axi_ctrl->tasklet_q);
+	spin_lock_init(&axi_ctrl->share_ctrl->sd_notify_lock);
+
+	axi_ctrl->share_ctrl->vfebase = ioremap(axi_ctrl->vfemem->start,
+		resource_size(axi_ctrl->vfemem));
+	if (!axi_ctrl->share_ctrl->vfebase) {
+		rc = -ENOMEM;
+		pr_err("%s: vfe ioremap failed\n", __func__);
+		goto remap_failed;
+	}
+
+	if (axi_ctrl->fs_vfe) {
+		rc = regulator_enable(axi_ctrl->fs_vfe);
+		if (rc) {
+			pr_err("%s: Regulator enable failed\n",	__func__);
+			goto fs_failed;
+		}
+	}
+
+	rc = msm_cam_clk_enable(&axi_ctrl->pdev->dev, vfe32_clk_info,
+			axi_ctrl->vfe_clk, ARRAY_SIZE(vfe32_clk_info), 1);
+	if (rc < 0)
+		goto clk_enable_failed;
+
+#ifdef CONFIG_MSM_IOMMU
+	rc = iommu_attach_device(mctl->domain, axi_ctrl->iommu_ctx_imgwr);
+	if (rc < 0) {
+		pr_err("%s: imgwr attach failed rc = %d\n", __func__, rc);
+		rc = -ENODEV;
+		goto device_imgwr_attach_failed;
+	}
+	rc = iommu_attach_device(mctl->domain, axi_ctrl->iommu_ctx_misc);
+	if (rc < 0) {
+		pr_err("%s: misc attach failed rc = %d\n", __func__, rc);
+		rc = -ENODEV;
+		goto device_misc_attach_failed;
+	}
+#endif
+
+	msm_camio_bus_scale_cfg(
+		mctl->sdata->pdata->cam_bus_scale_table, S_INIT);
+
+	if (axi_ctrl->share_ctrl->dual_enabled)
+		msm_camio_bus_scale_cfg(
+			mctl->sdata->pdata->cam_bus_scale_table, S_DUAL);
+	else
+		msm_camio_bus_scale_cfg(
+			mctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
+
+	if (msm_camera_io_r(
+		axi_ctrl->share_ctrl->vfebase + V32_GET_HW_VERSION_OFF) ==
+		VFE32_HW_NUMBER)
+		axi_ctrl->share_ctrl->register_total = VFE32_REGISTER_TOTAL;
+	else
+		axi_ctrl->share_ctrl->register_total = VFE33_REGISTER_TOTAL;
+
+	spin_lock_init(&axi_ctrl->share_ctrl->stop_flag_lock);
+	spin_lock_init(&axi_ctrl->share_ctrl->update_ack_lock);
+	spin_lock_init(&axi_ctrl->share_ctrl->start_ack_lock);
+
+	enable_irq(axi_ctrl->vfeirq->start);
+
+	return rc;
+
+#ifdef CONFIG_MSM_IOMMU
+device_misc_attach_failed:
+	iommu_detach_device(mctl->domain, axi_ctrl->iommu_ctx_imgwr);
+device_imgwr_attach_failed:
+#endif
+	msm_cam_clk_enable(&axi_ctrl->pdev->dev, vfe32_clk_info,
+			axi_ctrl->vfe_clk, ARRAY_SIZE(vfe32_clk_info), 0);
+clk_enable_failed:
+	if (axi_ctrl->fs_vfe)
+		regulator_disable(axi_ctrl->fs_vfe);
+fs_failed:
+	iounmap(axi_ctrl->share_ctrl->vfebase);
+	axi_ctrl->share_ctrl->vfebase = NULL;
+remap_failed:
+mctl_failed:
+	return rc;
+}
+
+int msm_vfe_subdev_init(struct v4l2_subdev *sd)
+{
+	int rc = 0;
+	struct vfe32_ctrl_type *vfe32_ctrl =
+		(struct vfe32_ctrl_type *)v4l2_get_subdevdata(sd);
+
+	spin_lock_init(&vfe32_ctrl->state_lock);
+	spin_lock_init(&vfe32_ctrl->stats_bufq_lock);
+
+	vfe32_ctrl->update_linear = false;
+	vfe32_ctrl->update_rolloff = false;
+	vfe32_ctrl->update_la = false;
+	vfe32_ctrl->update_gamma = false;
+	vfe32_ctrl->vfe_sof_count_enable = false;
+	vfe32_ctrl->hfr_mode = HFR_MODE_OFF;
+
+	memset(&vfe32_ctrl->stats_ctrl, 0,
+		sizeof(struct msm_stats_bufq_ctrl));
+	memset(&vfe32_ctrl->stats_ops, 0, sizeof(struct msm_stats_ops));
+
+	return rc;
+}
+
+void msm_axi_subdev_release(struct v4l2_subdev *sd)
+{
+	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+	struct msm_cam_media_controller *pmctl =
+		v4l2_get_subdev_hostdata(sd);
+
+	if (!axi_ctrl->share_ctrl->vfebase) {
+		pr_err("%s: base address unmapped\n", __func__);
+		return;
+	}
+
+	axi_ctrl->share_ctrl->axi_ref_cnt--;
+	if (axi_ctrl->share_ctrl->axi_ref_cnt > 0)
+		return;
+
+	axi_clear_all_interrupts(axi_ctrl->share_ctrl);
+	axi_ctrl->share_ctrl->dual_enabled = 0;
+	disable_irq(axi_ctrl->vfeirq->start);
+	tasklet_kill(&axi_ctrl->vfe32_tasklet);
+#ifdef CONFIG_MSM_IOMMU
+	iommu_detach_device(pmctl->domain, axi_ctrl->iommu_ctx_misc);
+	iommu_detach_device(pmctl->domain, axi_ctrl->iommu_ctx_imgwr);
+#endif
+	msm_cam_clk_enable(&axi_ctrl->pdev->dev, vfe32_clk_info,
+			axi_ctrl->vfe_clk, ARRAY_SIZE(vfe32_clk_info), 0);
+	if (axi_ctrl->fs_vfe)
+		regulator_disable(axi_ctrl->fs_vfe);
+
+	iounmap(axi_ctrl->share_ctrl->vfebase);
+	axi_ctrl->share_ctrl->vfebase = NULL;
+
+	if (atomic_read(&irq_cnt))
+		pr_warning("%s, Warning IRQ Count not ZERO\n", __func__);
+
+	msm_camio_bus_scale_cfg(
+		pmctl->sdata->pdata->cam_bus_scale_table, S_EXIT);
+
+}
+
+void msm_vfe_subdev_release(struct v4l2_subdev *sd)
+{
+	struct vfe32_ctrl_type *vfe32_ctrl =
+		(struct vfe32_ctrl_type *)v4l2_get_subdevdata(sd);
+	CDBG("vfe subdev release %p\n",
+		vfe32_ctrl->share_ctrl->vfebase);
+}
+
+void axi_abort(struct axi_ctrl_t *axi_ctrl)
+{
+	uint8_t  axi_busy_flag = true;
+	unsigned long flags;
+	/* axi halt command. */
+
+	spin_lock_irqsave(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
+	axi_ctrl->share_ctrl->stop_ack_pending  = TRUE;
+	spin_unlock_irqrestore(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
+	msm_camera_io_w(AXI_HALT,
+		axi_ctrl->share_ctrl->vfebase + VFE_AXI_CMD);
+	wmb();
+	while (axi_busy_flag) {
+		if (msm_camera_io_r(
+			axi_ctrl->share_ctrl->vfebase + VFE_AXI_STATUS) & 0x1)
+			axi_busy_flag = false;
+	}
+	/* Ensure the write order while writing
+	* to the command register using the barrier */
+	msm_camera_io_w_mb(AXI_HALT_CLEAR,
+		axi_ctrl->share_ctrl->vfebase + VFE_AXI_CMD);
+
+	/* after axi halt, then ok to apply global reset.
+	* enable reset_ack and async timer interrupt only while
+	* stopping the pipeline.*/
+	msm_camera_io_w(0xf0000000,
+		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_0);
+	msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_1,
+		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+	/* Ensure the write order while writing
+	* to the command register using the barrier */
+	msm_camera_io_w_mb(VFE_RESET_UPON_STOP_CMD,
+		axi_ctrl->share_ctrl->vfebase + VFE_GLOBAL_RESET);
+	if (axi_ctrl->share_ctrl->sync_abort)
+		wait_for_completion_interruptible(
+			&axi_ctrl->share_ctrl->reset_complete);
+}
+
+int axi_config_buffers(struct axi_ctrl_t *axi_ctrl,
+	struct msm_camera_vfe_params_t vfe_params)
+{
+	uint16_t vfe_mode = axi_ctrl->share_ctrl->current_mode
+			& ~(VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1);
+	int rc = 0;
+	switch (vfe_params.cmd_type) {
+	case AXI_CMD_PREVIEW:
+		if (vfe_mode) {
+			if ((axi_ctrl->share_ctrl->current_mode &
+				VFE_OUTPUTS_PREVIEW_AND_VIDEO) ||
+				(axi_ctrl->share_ctrl->current_mode &
+				VFE_OUTPUTS_PREVIEW))
+				/* Configure primary channel */
+				rc = configure_pingpong_buffers(
+					VFE_MSG_START,
+					VFE_MSG_OUTPUT_PRIMARY,
+					axi_ctrl);
+			else
+			/* Configure secondary channel */
+				rc = configure_pingpong_buffers(
+					VFE_MSG_START,
+					VFE_MSG_OUTPUT_SECONDARY,
+					axi_ctrl);
+		}
+		if (axi_ctrl->share_ctrl->current_mode &
+				VFE_OUTPUTS_RDI0)
+			rc = configure_pingpong_buffers(
+				VFE_MSG_START, VFE_MSG_OUTPUT_TERTIARY1,
+				axi_ctrl);
+		if (axi_ctrl->share_ctrl->current_mode &
+				VFE_OUTPUTS_RDI1)
+			rc = configure_pingpong_buffers(
+				VFE_MSG_START, VFE_MSG_OUTPUT_TERTIARY2,
+				axi_ctrl);
+
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers for preview",
+				__func__);
+			rc = -EINVAL;
+			goto config_done;
+		}
+		break;
+	case AXI_CMD_RAW_CAPTURE:
+		rc = configure_pingpong_buffers(
+			VFE_MSG_CAPTURE, VFE_MSG_OUTPUT_PRIMARY,
+			axi_ctrl);
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers for snapshot",
+				__func__);
+			rc = -EINVAL;
+			goto config_done;
+		}
+		break;
+	case AXI_CMD_ZSL:
+		rc = configure_pingpong_buffers(VFE_MSG_START,
+			VFE_MSG_OUTPUT_PRIMARY, axi_ctrl);
+		if (rc < 0)
+			goto config_done;
+		rc = configure_pingpong_buffers(VFE_MSG_START,
+			VFE_MSG_OUTPUT_SECONDARY, axi_ctrl);
+		if (rc < 0)
+			goto config_done;
+		break;
+	case AXI_CMD_RECORD:
+		if (axi_ctrl->share_ctrl->current_mode &
+			VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
+			axi_ctrl->share_ctrl->outpath.out1.inst_handle =
+				vfe_params.inst_handle;
+			rc = configure_pingpong_buffers(
+				VFE_MSG_START_RECORDING,
+				VFE_MSG_OUTPUT_SECONDARY,
+				axi_ctrl);
+		} else if (axi_ctrl->share_ctrl->current_mode &
+			VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
+			axi_ctrl->share_ctrl->outpath.out0.inst_handle =
+				vfe_params.inst_handle;
+			rc = configure_pingpong_buffers(
+				VFE_MSG_START_RECORDING,
+				VFE_MSG_OUTPUT_PRIMARY,
+				axi_ctrl);
+		}
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers for video",
+				__func__);
+			rc = -EINVAL;
+			goto config_done;
+		}
+		break;
+	case AXI_CMD_LIVESHOT:
+		axi_ctrl->share_ctrl->outpath.out0.inst_handle =
+			vfe_params.inst_handle;
+		rc = configure_pingpong_buffers(VFE_MSG_CAPTURE,
+					VFE_MSG_OUTPUT_PRIMARY, axi_ctrl);
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers for primary output",
+				__func__);
+			rc = -EINVAL;
+			goto config_done;
+		}
+		break;
+	case AXI_CMD_CAPTURE:
+		if (vfe_mode) {
+			if (axi_ctrl->share_ctrl->current_mode ==
+				VFE_OUTPUTS_JPEG_AND_THUMB ||
+			axi_ctrl->share_ctrl->current_mode ==
+				VFE_OUTPUTS_THUMB_AND_JPEG) {
+
+				/* Configure primary channel for JPEG */
+				rc = configure_pingpong_buffers(
+					VFE_MSG_JPEG_CAPTURE,
+					VFE_MSG_OUTPUT_PRIMARY,
+					axi_ctrl);
+			} else {
+				/* Configure primary channel */
+				rc = configure_pingpong_buffers(
+					VFE_MSG_CAPTURE,
+					VFE_MSG_OUTPUT_PRIMARY,
+					axi_ctrl);
+			}
+			if (rc < 0) {
+				pr_err("%s error configuring pingpong buffers for primary output",
+					__func__);
+				rc = -EINVAL;
+				goto config_done;
+			}
+			/* Configure secondary channel */
+			rc = configure_pingpong_buffers(
+					VFE_MSG_CAPTURE,
+					VFE_MSG_OUTPUT_SECONDARY,
+					axi_ctrl);
+			if (rc < 0) {
+				pr_err("%s error configuring pingpong buffers for secondary output",
+					__func__);
+				rc = -EINVAL;
+				goto config_done;
+			}
+		}
+
+		if (axi_ctrl->share_ctrl->current_mode &
+				VFE_OUTPUTS_RDI0)
+			rc = configure_pingpong_buffers(
+				VFE_MSG_CAPTURE, VFE_MSG_OUTPUT_TERTIARY1,
+				axi_ctrl);
+		if (axi_ctrl->share_ctrl->current_mode &
+				VFE_OUTPUTS_RDI1)
+			rc = configure_pingpong_buffers(
+				VFE_MSG_CAPTURE, VFE_MSG_OUTPUT_TERTIARY2,
+				axi_ctrl);
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+
+	}
+config_done:
+	return rc;
+}
+
+void axi_start(struct msm_cam_media_controller *pmctl,
+	struct axi_ctrl_t *axi_ctrl, struct msm_camera_vfe_params_t vfe_params)
+{
+	int rc = 0, bus_vector_idx = 0;
+	uint32_t reg_update = 0;
+	uint32_t vfe_mode =
+		(axi_ctrl->share_ctrl->current_mode &
+		~(VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1));
+	rc = axi_config_buffers(axi_ctrl, vfe_params);
+	if (rc < 0)
+		return;
+
+	switch (vfe_params.cmd_type) {
+	case AXI_CMD_PREVIEW:
+		if (!axi_ctrl->share_ctrl->dual_enabled)
+			msm_camio_bus_scale_cfg(
+			pmctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
+		break;
+	case AXI_CMD_CAPTURE:
+	case AXI_CMD_RAW_CAPTURE:
+		if (!axi_ctrl->share_ctrl->dual_enabled)
+			msm_camio_bus_scale_cfg(
+			pmctl->sdata->pdata->cam_bus_scale_table, S_CAPTURE);
+		break;
+	case AXI_CMD_RECORD:
+		if (cpu_is_msm8930() || cpu_is_msm8930aa() ||
+			cpu_is_msm8930ab()) {
+			if (axi_ctrl->share_ctrl->current_mode &
+				VFE_OUTPUTS_PREVIEW_AND_VIDEO
+			|| axi_ctrl->share_ctrl->current_mode &
+				VFE_OUTPUTS_VIDEO_AND_PREVIEW)
+				bus_vector_idx = S_VIDEO;
+			else
+				bus_vector_idx = S_ADV_VIDEO;
+		} else {
+			bus_vector_idx = S_VIDEO;
+		}
+		if (!axi_ctrl->share_ctrl->dual_enabled)
+			msm_camio_bus_scale_cfg(
+			pmctl->sdata->pdata->cam_bus_scale_table,
+			bus_vector_idx);
+		return;
+	case AXI_CMD_ZSL:
+		if (!axi_ctrl->share_ctrl->dual_enabled)
+			msm_camio_bus_scale_cfg(
+			pmctl->sdata->pdata->cam_bus_scale_table, S_ZSL);
+		break;
+	case AXI_CMD_LIVESHOT:
+		if (!axi_ctrl->share_ctrl->dual_enabled)
+			msm_camio_bus_scale_cfg(
+			pmctl->sdata->pdata->cam_bus_scale_table, S_LIVESHOT);
+		return;
+	default:
+		return;
+	}
+	axi_enable_wm_irq(axi_ctrl->share_ctrl);
+
+	switch (vfe_params.cmd_type) {
+	case AXI_CMD_RAW_CAPTURE:
+		msm_camera_io_w((
+			0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0),
+			axi_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
+		msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+			+ vfe32_AXI_WM_CFG[axi_ctrl->
+			share_ctrl->outpath.out0.ch0]);
+		break;
+	case AXI_CMD_PREVIEW: {
+		switch (vfe_mode) {
+		case VFE_OUTPUTS_PREVIEW:
+		case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
+			if (axi_ctrl->share_ctrl->outpath.output_mode &
+				VFE32_OUTPUT_MODE_PRIMARY) {
+				msm_camera_io_w((
+					0x1 << axi_ctrl->share_ctrl->
+							outpath.out0.ch0 |
+					0x1 << axi_ctrl->share_ctrl->
+							outpath.out0.ch1),
+					axi_ctrl->share_ctrl->vfebase +
+							VFE_BUS_CMD);
+				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+					+ vfe32_AXI_WM_CFG[axi_ctrl->
+					share_ctrl->outpath.out0.ch0]);
+				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+					+ vfe32_AXI_WM_CFG[axi_ctrl->
+					share_ctrl->outpath.out0.ch1]);
+
+
+			} else if (axi_ctrl->share_ctrl->outpath.output_mode &
+					VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+				msm_camera_io_w((
+					0x1 << axi_ctrl->share_ctrl->
+							outpath.out0.ch0 |
+					0x1 << axi_ctrl->share_ctrl->
+							outpath.out0.ch1 |
+					0x1 << axi_ctrl->share_ctrl->
+							outpath.out0.ch2),
+					axi_ctrl->share_ctrl->vfebase +
+							VFE_BUS_CMD);
+				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+					+ vfe32_AXI_WM_CFG[axi_ctrl->
+					share_ctrl->outpath.out0.ch0]);
+				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+					+ vfe32_AXI_WM_CFG[axi_ctrl->
+					share_ctrl->outpath.out0.ch1]);
+				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+					+ vfe32_AXI_WM_CFG[axi_ctrl->
+					share_ctrl->outpath.out0.ch2]);
+			}
+			break;
+		default:
+			if (axi_ctrl->share_ctrl->outpath.output_mode &
+				VFE32_OUTPUT_MODE_SECONDARY) {
+				msm_camera_io_w((
+					0x1 << axi_ctrl->share_ctrl->
+						outpath.out1.ch0 |
+					0x1 << axi_ctrl->share_ctrl->
+						outpath.out1.ch1),
+					axi_ctrl->share_ctrl->vfebase +
+						VFE_BUS_CMD);
+				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+					+ vfe32_AXI_WM_CFG[axi_ctrl->
+					share_ctrl->outpath.out1.ch0]);
+				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+					+ vfe32_AXI_WM_CFG[axi_ctrl->
+					share_ctrl->outpath.out1.ch1]);
+			} else if (axi_ctrl->share_ctrl->outpath.output_mode &
+				VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+				msm_camera_io_w((
+					0x1 << axi_ctrl->share_ctrl->
+							outpath.out1.ch0 |
+					0x1 << axi_ctrl->share_ctrl->
+							outpath.out1.ch1 |
+					0x1 << axi_ctrl->share_ctrl->
+							outpath.out1.ch2),
+					axi_ctrl->share_ctrl->vfebase +
+							VFE_BUS_CMD);
+				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+					+ vfe32_AXI_WM_CFG[axi_ctrl->
+					share_ctrl->outpath.out1.ch0]);
+				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+					+ vfe32_AXI_WM_CFG[axi_ctrl->
+					share_ctrl->outpath.out1.ch1]);
+				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+					+ vfe32_AXI_WM_CFG[axi_ctrl->
+					share_ctrl->outpath.out1.ch2]);
+			}
+			break;
+			}
+		}
+		break;
+	default:
+		if (axi_ctrl->share_ctrl->outpath.output_mode &
+			VFE32_OUTPUT_MODE_PRIMARY) {
+			msm_camera_io_w((
+				0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0 |
+				0x1 << axi_ctrl->share_ctrl->outpath.out0.ch1),
+				axi_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out0.ch0]);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out0.ch1]);
+		} else if (axi_ctrl->share_ctrl->outpath.output_mode &
+				VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+			msm_camera_io_w((
+				0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0 |
+				0x1 << axi_ctrl->share_ctrl->outpath.out0.ch1 |
+				0x1 << axi_ctrl->share_ctrl->outpath.out0.ch2),
+				axi_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out0.ch0]);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out0.ch1]);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out0.ch2]);
+		}
+
+		if (axi_ctrl->share_ctrl->outpath.output_mode &
+			VFE32_OUTPUT_MODE_SECONDARY) {
+			msm_camera_io_w((
+				0x1 << axi_ctrl->share_ctrl->outpath.out1.ch0 |
+				0x1 << axi_ctrl->share_ctrl->outpath.out1.ch1),
+				axi_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out1.ch0]);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out1.ch1]);
+		} else if (axi_ctrl->share_ctrl->outpath.output_mode &
+			VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+			msm_camera_io_w((
+				0x1 << axi_ctrl->share_ctrl->outpath.out1.ch0 |
+				0x1 << axi_ctrl->share_ctrl->outpath.out1.ch1 |
+				0x1 << axi_ctrl->share_ctrl->outpath.out1.ch2),
+				axi_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out1.ch0]);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out1.ch1]);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe32_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out1.ch2]);
+		}
+		break;
+	}
+	if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
+		axi_ctrl->share_ctrl->outpath.out2.capture_cnt =
+						vfe_params.capture_count;
+		axi_ctrl->share_ctrl->rdi0_capture_count =
+						vfe_params.capture_count;
+		msm_camera_io_w((
+				0x1 << axi_ctrl->share_ctrl->outpath.out2.ch0),
+				axi_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
+		msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+			vfe32_AXI_WM_CFG[axi_ctrl->share_ctrl->
+			outpath.out2.ch0]);
+	}
+	if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
+		axi_ctrl->share_ctrl->outpath.out3.capture_cnt =
+						vfe_params.capture_count;
+		axi_ctrl->share_ctrl->rdi1_capture_count =
+						vfe_params.capture_count;
+		msm_camera_io_w((
+				0x1 << axi_ctrl->share_ctrl->outpath.out3.ch0),
+				axi_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
+		msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+			vfe32_AXI_WM_CFG[axi_ctrl->share_ctrl->
+			outpath.out3.ch0]);
+	}
+
+	axi_enable_irq(axi_ctrl->share_ctrl);
+
+	if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
+		if (!atomic_cmpxchg(
+			&axi_ctrl->share_ctrl->rdi0_update_ack_pending,
+				0, 1))
+			reg_update |= 0x2;
+	}
+	if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
+		if (!atomic_cmpxchg(
+			&axi_ctrl->share_ctrl->rdi1_update_ack_pending,
+				0, 1))
+			reg_update |= 0x4;
+	}
+
+	if (vfe_mode) {
+		if (!atomic_cmpxchg(
+			&axi_ctrl->share_ctrl->pix0_update_ack_pending,
+				0, 1))
+			reg_update |= 0x1;
+	}
+
+	msm_camera_io_w_mb(reg_update,
+			axi_ctrl->share_ctrl->vfebase +
+			VFE_REG_UPDATE_CMD);
+	axi_ctrl->share_ctrl->operation_mode |=
+		axi_ctrl->share_ctrl->current_mode;
+}
+
+void axi_stop(struct msm_cam_media_controller *pmctl,
+	struct axi_ctrl_t *axi_ctrl, struct msm_camera_vfe_params_t vfe_params)
+{
+	uint32_t reg_update = 0;
+	uint32_t vfe_mode =
+	axi_ctrl->share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
+		VFE_OUTPUTS_RDI1);
+	int bus_vector_idx = 0;
+
+	switch (vfe_params.cmd_type) {
+	case AXI_CMD_PREVIEW:
+	case AXI_CMD_CAPTURE:
+	case AXI_CMD_RAW_CAPTURE:
+	case AXI_CMD_ZSL:
+		axi_ctrl->share_ctrl->cmd_type = vfe_params.cmd_type;
+		break;
+	case AXI_CMD_RECORD:
+		if (!axi_ctrl->share_ctrl->dual_enabled)
+			msm_camio_bus_scale_cfg(
+			pmctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
+		return;
+	case AXI_CMD_LIVESHOT:
+		if (!axi_ctrl->share_ctrl->dual_enabled) {
+			bus_vector_idx = S_VIDEO;
+
+			if (cpu_is_msm8930() || cpu_is_msm8930aa() ||
+				cpu_is_msm8930ab())
+				bus_vector_idx = S_ADV_VIDEO;
+
+			msm_camio_bus_scale_cfg(
+			pmctl->sdata->pdata->cam_bus_scale_table,
+			bus_vector_idx);
+		}
+		return;
+	default:
+		return;
+	}
+
+	if (axi_ctrl->share_ctrl->stop_immediately) {
+		axi_disable_irq(axi_ctrl->share_ctrl,
+			axi_ctrl->share_ctrl->current_mode);
+		axi_stop_process(axi_ctrl->share_ctrl);
+		return;
+	}
+
+	if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
+		msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase +
+			vfe32_AXI_WM_CFG[axi_ctrl->share_ctrl->
+				outpath.out2.ch0]);
+		if (!atomic_cmpxchg(
+			&axi_ctrl->share_ctrl->rdi0_update_ack_pending,
+				0, 2))
+			reg_update |= 0x2;
+	}
+	if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
+		msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase +
+			vfe32_AXI_WM_CFG[axi_ctrl->share_ctrl->
+				outpath.out3.ch0]);
+		if (!atomic_cmpxchg(
+			&axi_ctrl->share_ctrl->rdi1_update_ack_pending,
+				0, 2))
+			reg_update |= 0x4;
+	}
+	if (vfe_mode) {
+		if (!atomic_cmpxchg(
+			&axi_ctrl->share_ctrl->pix0_update_ack_pending,
+				0, 2))
+			reg_update |= 0x1;
+	}
+	msm_camera_io_w_mb(reg_update,
+		axi_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+}
+
+static int msm_axi_config(struct v4l2_subdev *sd, void __user *arg)
+{
+	struct msm_vfe_cfg_cmd cfgcmd;
+	struct msm_isp_cmd vfecmd;
+	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+	struct msm_cam_media_controller *pmctl =
+		(struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
+	int rc = 0, vfe_cmd_type = 0, rdi_mode = 0;
+
+	if (!axi_ctrl->share_ctrl->vfebase) {
+		pr_err("%s: base address unmapped\n", __func__);
+		return -EFAULT;
+	}
+	memset(&cfgcmd, 0, sizeof(struct msm_vfe_cfg_cmd));
+	if (NULL != arg) {
+		if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
+			ERR_COPY_FROM_USER();
+			return -EFAULT;
+		}
+	}
+	memset(&vfecmd, 0, sizeof(struct msm_isp_cmd));
+	if (NULL != cfgcmd.value) {
+		if (copy_from_user(&vfecmd,
+				(void __user *)(cfgcmd.value),
+				sizeof(vfecmd))) {
+			pr_err("%s %d: copy_from_user failed\n", __func__,
+				__LINE__);
+			return -EFAULT;
+		}
+	}
+
+	vfe_cmd_type = (cfgcmd.cmd_type & ~(CMD_AXI_CFG_TERT1|
+		CMD_AXI_CFG_TERT2));
+	switch (cfgcmd.cmd_type) {
+	case CMD_AXI_CFG_TERT1:{
+		uint32_t *axio = NULL;
+		axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			return -ENOMEM;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			return -EFAULT;
+		}
+		vfe32_config_axi(axi_ctrl, OUTPUT_TERT1, axio);
+		kfree(axio);
+		return rc;
+		}
+	case CMD_AXI_CFG_TERT2:{
+		uint32_t *axio = NULL;
+		axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio)
+			return -ENOMEM;
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			return -EFAULT;
+		}
+		vfe32_config_axi(axi_ctrl, OUTPUT_TERT2, axio);
+		kfree(axio);
+		return rc;
+		}
+	case CMD_AXI_CFG_TERT1|CMD_AXI_CFG_TERT2:{
+		uint32_t *axio = NULL;
+		axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio)
+			return -ENOMEM;
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			return -EFAULT;
+		}
+		vfe32_config_axi(axi_ctrl, OUTPUT_TERT1|OUTPUT_TERT2, axio);
+		kfree(axio);
+		return rc;
+		}
+	default:
+		if (cfgcmd.cmd_type & CMD_AXI_CFG_TERT1)
+			rdi_mode |= OUTPUT_TERT1;
+		if (cfgcmd.cmd_type & CMD_AXI_CFG_TERT2)
+			rdi_mode |= OUTPUT_TERT2;
+	}
+	switch (vfe_cmd_type) {
+	case CMD_AXI_CFG_PRIM: {
+		uint32_t *axio = NULL;
+		axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe32_config_axi(axi_ctrl, rdi_mode|OUTPUT_PRIM, axio);
+		kfree(axio);
+		break;
+		}
+	case CMD_AXI_CFG_PRIM_ALL_CHNLS: {
+		uint32_t *axio = NULL;
+		axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe32_config_axi(axi_ctrl, rdi_mode|OUTPUT_PRIM_ALL_CHNLS,
+			axio);
+		kfree(axio);
+		break;
+		}
+	case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC: {
+		uint32_t *axio = NULL;
+		axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe32_config_axi(axi_ctrl,
+			rdi_mode|OUTPUT_PRIM|OUTPUT_SEC, axio);
+		kfree(axio);
+		break;
+		}
+	case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC_ALL_CHNLS: {
+		uint32_t *axio = NULL;
+		axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe32_config_axi(axi_ctrl,
+			rdi_mode|OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS, axio);
+		kfree(axio);
+		break;
+		}
+	case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC: {
+		uint32_t *axio = NULL;
+		axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe32_config_axi(axi_ctrl,
+			rdi_mode|OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC, axio);
+		kfree(axio);
+		break;
+		}
+
+	case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC_ALL_CHNLS:
+		pr_err("%s Invalid/Unsupported AXI configuration %x",
+			__func__, cfgcmd.cmd_type);
+		break;
+	case CMD_AXI_START: {
+		struct msm_camera_vfe_params_t vfe_params;
+		if (copy_from_user(&vfe_params,
+				(void __user *)(vfecmd.value),
+				sizeof(struct msm_camera_vfe_params_t))) {
+				return -EFAULT;
+		}
+		axi_ctrl->share_ctrl->current_mode =
+			vfe_params.operation_mode;
+		axi_start(pmctl, axi_ctrl, vfe_params);
+		}
+		break;
+	case CMD_AXI_STOP: {
+		struct msm_camera_vfe_params_t vfe_params;
+		if (copy_from_user(&vfe_params,
+				(void __user *)(vfecmd.value),
+				sizeof(struct msm_camera_vfe_params_t))) {
+				return -EFAULT;
+		}
+		axi_ctrl->share_ctrl->current_mode =
+			vfe_params.operation_mode;
+		axi_ctrl->share_ctrl->stop_immediately =
+			vfe_params.stop_immediately;
+		axi_stop(pmctl, axi_ctrl, vfe_params);
+		}
+		break;
+	case CMD_AXI_RESET: {
+		struct msm_camera_vfe_params_t vfe_params;
+		if (copy_from_user(&vfe_params,
+				(void __user *)(vfecmd.value),
+				sizeof(struct msm_camera_vfe_params_t))) {
+				return -EFAULT;
+		}
+		axi_reset(axi_ctrl, vfe_params);
+		}
+		break;
+	case CMD_AXI_ABORT:
+		if (copy_from_user(&axi_ctrl->share_ctrl->sync_abort,
+				(void __user *)(vfecmd.value),
+				sizeof(uint8_t))) {
+				return -EFAULT;
+		}
+		axi_abort(axi_ctrl);
+		break;
+	default:
+		pr_err("%s Unsupported AXI configuration %x ", __func__,
+			cfgcmd.cmd_type);
+		break;
+	}
+	return rc;
+}
+
+static void msm_axi_process_irq(struct v4l2_subdev *sd, void *arg)
+{
+	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+	uint32_t irqstatus = (uint32_t) arg;
+
+	if (!axi_ctrl->share_ctrl->vfebase) {
+		pr_err("%s: base address unmapped\n", __func__);
+		return;
+	}
+
+	/* next, check output path related interrupts. */
+	if (irqstatus &
+		VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK) {
+		CDBG("Image composite done 0 irq occured.\n");
+		vfe32_process_output_path_irq_0(axi_ctrl);
+	}
+	if (irqstatus &
+		VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK) {
+		CDBG("Image composite done 1 irq occured.\n");
+		vfe32_process_output_path_irq_1(axi_ctrl);
+	}
+
+	if (axi_ctrl->share_ctrl->comp_output_mode &
+		VFE32_OUTPUT_MODE_TERTIARY1)
+		if (irqstatus & (0x1 << (axi_ctrl->share_ctrl->outpath.out2.ch0
+			+ VFE_WM_OFFSET)))
+			vfe32_process_output_path_irq_rdi0(axi_ctrl);
+	if (axi_ctrl->share_ctrl->comp_output_mode &
+		VFE32_OUTPUT_MODE_TERTIARY2)
+		if (irqstatus & (0x1 << (axi_ctrl->share_ctrl->outpath.out3.ch0
+			+ VFE_WM_OFFSET)))
+			vfe32_process_output_path_irq_rdi1(axi_ctrl);
+
+	/* in snapshot mode if done then send
+	snapshot done message */
+	if (
+		axi_ctrl->share_ctrl->operation_mode &
+			VFE_OUTPUTS_THUMB_AND_MAIN ||
+		axi_ctrl->share_ctrl->operation_mode &
+			VFE_OUTPUTS_MAIN_AND_THUMB ||
+		axi_ctrl->share_ctrl->operation_mode &
+			VFE_OUTPUTS_THUMB_AND_JPEG ||
+		axi_ctrl->share_ctrl->operation_mode &
+			VFE_OUTPUTS_JPEG_AND_THUMB ||
+		axi_ctrl->share_ctrl->operation_mode &
+			VFE_OUTPUTS_RAW) {
+		if ((axi_ctrl->share_ctrl->outpath.out0.capture_cnt == 0)
+				&& (axi_ctrl->share_ctrl->outpath.out1.
+				capture_cnt == 0)) {
+			uint32_t mode =
+				(axi_ctrl->share_ctrl->operation_mode &
+				~(VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1));
+			uint16_t output_mode =
+			axi_ctrl->share_ctrl->comp_output_mode &
+				~(VFE32_OUTPUT_MODE_TERTIARY1|
+				VFE32_OUTPUT_MODE_TERTIARY2);
+			if (!axi_ctrl->share_ctrl->dual_enabled)
+				msm_camera_io_w_mb(
+					CAMIF_COMMAND_STOP_IMMEDIATELY,
+					axi_ctrl->share_ctrl->vfebase +
+					VFE_CAMIF_COMMAND);
+			axi_disable_wm_irq(axi_ctrl->share_ctrl, output_mode);
+			axi_disable_irq(axi_ctrl->share_ctrl, mode);
+			vfe32_send_isp_msg(&axi_ctrl->subdev,
+				axi_ctrl->share_ctrl->vfeFrameId,
+				MSG_ID_PIX0_UPDATE_ACK);
+			axi_ctrl->share_ctrl->outpath.out0.
+				capture_cnt = -1;
+			axi_ctrl->share_ctrl->outpath.out1.
+				capture_cnt = -1;
+			axi_ctrl->share_ctrl->comp_output_mode &=
+				(VFE32_OUTPUT_MODE_TERTIARY1|
+				VFE32_OUTPUT_MODE_TERTIARY2);
+		}
+	}
+
+	if (axi_ctrl->share_ctrl->outpath.out2.capture_cnt == 0) {
+		axi_ctrl->share_ctrl->comp_output_mode &=
+				~VFE32_OUTPUT_MODE_TERTIARY1;
+		axi_ctrl->share_ctrl->outpath.out2.capture_cnt = -1;
+	}
+
+	if (axi_ctrl->share_ctrl->outpath.out3.capture_cnt == 0) {
+		axi_ctrl->share_ctrl->comp_output_mode &=
+				~VFE32_OUTPUT_MODE_TERTIARY2;
+		axi_ctrl->share_ctrl->outpath.out3.capture_cnt = -1;
+	}
+}
+
+static int msm_axi_buf_cfg(struct v4l2_subdev *sd, void __user *arg)
+{
+	struct msm_camvfe_params *vfe_params =
+		(struct msm_camvfe_params *)arg;
+	struct msm_vfe_cfg_cmd *cmd = vfe_params->vfe_cfg;
+	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+	void *data = vfe_params->data;
+	int rc = 0;
+
+	if (!axi_ctrl->share_ctrl->vfebase) {
+		pr_err("%s: base address unmapped\n", __func__);
+		return -EFAULT;
+	}
+
+	switch (cmd->cmd_type) {
+	case CMD_CONFIG_PING_ADDR: {
+		int path = *((int *)cmd->value);
+		struct vfe32_output_ch *outch =
+			vfe32_get_ch(path, axi_ctrl->share_ctrl);
+		outch->ping = *((struct msm_free_buf *)data);
+	}
+		break;
+
+	case CMD_CONFIG_PONG_ADDR: {
+		int path = *((int *)cmd->value);
+		struct vfe32_output_ch *outch =
+			vfe32_get_ch(path, axi_ctrl->share_ctrl);
+		outch->pong = *((struct msm_free_buf *)data);
+	}
+		break;
+
+	case CMD_CONFIG_FREE_BUF_ADDR: {
+		int path = *((int *)cmd->value);
+		struct vfe32_output_ch *outch =
+			vfe32_get_ch(path, axi_ctrl->share_ctrl);
+		outch->free_buf = *((struct msm_free_buf *)data);
+	}
+		break;
+	default:
+		pr_err("%s Unsupported AXI Buf config %x ", __func__,
+			cmd->cmd_type);
+	}
+	return rc;
+};
+
+static const struct v4l2_subdev_internal_ops msm_vfe_internal_ops;
+
+static long msm_axi_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int cmd, void *arg)
+{
+	int rc = -ENOIOCTLCMD;
+	switch (cmd) {
+	case VIDIOC_MSM_AXI_INIT: {
+		uint8_t dual_enabled;
+		if (copy_from_user(&dual_enabled,
+				(void __user *)(arg),
+				sizeof(uint8_t))) {
+				rc = -EFAULT;
+				break;
+		}
+		rc = msm_axi_subdev_init(sd, dual_enabled);
+		}
+		break;
+	case VIDIOC_MSM_AXI_CFG:
+		rc = msm_axi_config(sd, arg);
+		break;
+	case VIDIOC_MSM_AXI_IRQ:
+		msm_axi_process_irq(sd, arg);
+		rc = 0;
+		break;
+	case VIDIOC_MSM_AXI_BUF_CFG:
+		msm_axi_buf_cfg(sd, arg);
+		rc = 0;
+		break;
+	case VIDIOC_MSM_AXI_RELEASE:
+		msm_axi_subdev_release(sd);
+		rc = 0;
+		break;
+	case VIDIOC_MSM_AXI_RDI_COUNT_UPDATE: {
+		struct rdi_count_msg *msg = (struct rdi_count_msg *)arg;
+		struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+		switch (msg->rdi_interface) {
+		case RDI_0:
+			axi_ctrl->share_ctrl->rdi0FrameId = msg->count;
+			rc = 0;
+			break;
+		case RDI_1:
+			axi_ctrl->share_ctrl->rdi1FrameId = msg->count;
+			rc = 0;
+			break;
+		case RDI_2:
+			axi_ctrl->share_ctrl->rdi2FrameId = msg->count;
+			rc = 0;
+			break;
+		default:
+			pr_err("%s: Incorrect interface sent\n", __func__);
+			rc = -EINVAL;
+			break;
+		}
+		break;
+	}
+	default:
+		pr_err("%s: command %d not found\n", __func__,
+						_IOC_NR(cmd));
+		break;
+	}
+	return rc;
+}
+
+static const struct v4l2_subdev_core_ops msm_axi_subdev_core_ops = {
+	.ioctl = msm_axi_subdev_ioctl,
+	.interrupt_service_routine = msm_axi_subdev_isr_routine,
+};
+
+static const struct v4l2_subdev_video_ops msm_axi_subdev_video_ops = {
+	.s_crystal_freq = msm_axi_subdev_s_crystal_freq,
+};
+
+static const struct v4l2_subdev_ops msm_axi_subdev_ops = {
+	.core = &msm_axi_subdev_core_ops,
+	.video = &msm_axi_subdev_video_ops,
+};
+
+static const struct v4l2_subdev_internal_ops msm_axi_internal_ops;
+
+static int __devinit vfe32_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+	struct axi_ctrl_t *axi_ctrl;
+	struct vfe32_ctrl_type *vfe32_ctrl;
+	struct vfe_share_ctrl_t *share_ctrl;
+	struct intr_table_entry irq_req;
+	struct msm_cam_subdev_info sd_info;
+
+	CDBG("%s: device id = %d\n", __func__, pdev->id);
+
+	share_ctrl = kzalloc(sizeof(struct vfe_share_ctrl_t), GFP_KERNEL);
+	if (!share_ctrl) {
+		pr_err("%s: no enough memory\n", __func__);
+		return -ENOMEM;
+	}
+
+	axi_ctrl = kzalloc(sizeof(struct axi_ctrl_t), GFP_KERNEL);
+	if (!axi_ctrl) {
+		pr_err("%s: no enough memory\n", __func__);
+		kfree(share_ctrl);
+		return -ENOMEM;
+	}
+
+	vfe32_ctrl = kzalloc(sizeof(struct vfe32_ctrl_type), GFP_KERNEL);
+	if (!vfe32_ctrl) {
+		pr_err("%s: no enough memory\n", __func__);
+		kfree(share_ctrl);
+		kfree(axi_ctrl);
+		return -ENOMEM;
+	}
+
+	share_ctrl->axi_ctrl = axi_ctrl;
+	share_ctrl->vfe32_ctrl = vfe32_ctrl;
+	axi_ctrl->share_ctrl = share_ctrl;
+	vfe32_ctrl->share_ctrl = share_ctrl;
+	axi_ctrl->share_ctrl->axi_ref_cnt = 0;
+	v4l2_subdev_init(&axi_ctrl->subdev, &msm_axi_subdev_ops);
+	axi_ctrl->subdev.internal_ops = &msm_axi_internal_ops;
+	axi_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	snprintf(axi_ctrl->subdev.name,
+			 sizeof(axi_ctrl->subdev.name), "axi");
+	v4l2_set_subdevdata(&axi_ctrl->subdev, axi_ctrl);
+	axi_ctrl->pdev = pdev;
+
+	sd_info.sdev_type = AXI_DEV;
+	sd_info.sd_index = 0;
+	sd_info.irq_num = 0;
+	msm_cam_register_subdev_node(&axi_ctrl->subdev, &sd_info);
+
+	media_entity_init(&axi_ctrl->subdev.entity, 0, NULL, 0);
+	axi_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	axi_ctrl->subdev.entity.group_id = AXI_DEV;
+	axi_ctrl->subdev.entity.name = pdev->name;
+	axi_ctrl->subdev.entity.revision = axi_ctrl->subdev.devnode->num;
+
+	v4l2_subdev_init(&vfe32_ctrl->subdev, &msm_vfe_subdev_ops);
+	vfe32_ctrl->subdev.internal_ops = &msm_vfe_internal_ops;
+	vfe32_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	snprintf(vfe32_ctrl->subdev.name,
+			 sizeof(vfe32_ctrl->subdev.name), "vfe3.2");
+	v4l2_set_subdevdata(&vfe32_ctrl->subdev, vfe32_ctrl);
+	platform_set_drvdata(pdev, &vfe32_ctrl->subdev);
+
+	axi_ctrl->vfemem = platform_get_resource_byname(pdev,
+					IORESOURCE_MEM, "vfe32");
+	if (!axi_ctrl->vfemem) {
+		pr_err("%s: no mem resource?\n", __func__);
+		rc = -ENODEV;
+		goto vfe32_no_resource;
+	}
+	axi_ctrl->vfeirq = platform_get_resource_byname(pdev,
+					IORESOURCE_IRQ, "vfe32");
+	if (!axi_ctrl->vfeirq) {
+		pr_err("%s: no irq resource?\n", __func__);
+		rc = -ENODEV;
+		goto vfe32_no_resource;
+	}
+
+	axi_ctrl->vfeio = request_mem_region(axi_ctrl->vfemem->start,
+		resource_size(axi_ctrl->vfemem), pdev->name);
+	if (!axi_ctrl->vfeio) {
+		pr_err("%s: no valid mem region\n", __func__);
+		rc = -EBUSY;
+		goto vfe32_no_resource;
+	}
+
+	axi_ctrl->fs_vfe = regulator_get(&pdev->dev, "vdd");
+	if (IS_ERR(axi_ctrl->fs_vfe)) {
+		pr_err("%s: Regulator get failed %ld\n", __func__,
+			PTR_ERR(axi_ctrl->fs_vfe));
+		axi_ctrl->fs_vfe = NULL;
+	}
+
+	/* Register subdev node before requesting irq since
+	 * irq_num is needed by msm_cam_server */
+	sd_info.sdev_type = VFE_DEV;
+	sd_info.sd_index = 0;
+	sd_info.irq_num = axi_ctrl->vfeirq->start;
+	msm_cam_register_subdev_node(&vfe32_ctrl->subdev, &sd_info);
+
+	media_entity_init(&vfe32_ctrl->subdev.entity, 0, NULL, 0);
+	vfe32_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	vfe32_ctrl->subdev.entity.group_id = VFE_DEV;
+	vfe32_ctrl->subdev.entity.name = pdev->name;
+	vfe32_ctrl->subdev.entity.revision = vfe32_ctrl->subdev.devnode->num;
+
+	/* Request for this device irq from the camera server. If the
+	 * IRQ Router is present on this target, the interrupt will be
+	 * handled by the camera server and the interrupt service
+	 * routine called. If the request_irq call returns ENXIO, then
+	 * the IRQ Router hardware is not present on this target. We
+	 * have to request for the irq ourselves and register the
+	 * appropriate interrupt handler. */
+	irq_req.cam_hw_idx       = MSM_CAM_HW_VFE0;
+	irq_req.dev_name         = "vfe";
+	irq_req.irq_idx          = CAMERA_SS_IRQ_8;
+	irq_req.irq_num          = axi_ctrl->vfeirq->start;
+	irq_req.is_composite     = 0;
+	irq_req.irq_trigger_type = IRQF_TRIGGER_RISING;
+	irq_req.num_hwcore       = 1;
+	irq_req.subdev_list[0]   = &axi_ctrl->subdev;
+	irq_req.data             = (void *)axi_ctrl;
+	rc = msm_cam_server_request_irq(&irq_req);
+	if (rc == -ENXIO) {
+		/* IRQ Router hardware is not present on this hardware.
+		 * Request for the IRQ and register the interrupt handler. */
+		rc = request_irq(axi_ctrl->vfeirq->start, vfe32_parse_irq,
+			IRQF_TRIGGER_RISING, "vfe", axi_ctrl);
+		if (rc < 0) {
+			release_mem_region(axi_ctrl->vfemem->start,
+				resource_size(axi_ctrl->vfemem));
+			pr_err("%s: irq request fail\n", __func__);
+			rc = -EBUSY;
+			goto vfe32_no_resource;
+		}
+		disable_irq(axi_ctrl->vfeirq->start);
+	} else if (rc < 0) {
+		pr_err("%s Error registering irq ", __func__);
+		goto vfe32_no_resource;
+	}
+
+#ifdef CONFIG_MSM_IOMMU
+	/*get device context for IOMMU*/
+	axi_ctrl->iommu_ctx_imgwr =
+		msm_iommu_get_ctx("vfe_imgwr"); /*re-confirm*/
+	axi_ctrl->iommu_ctx_misc =
+		msm_iommu_get_ctx("vfe_misc"); /*re-confirm*/
+	if (!axi_ctrl->iommu_ctx_imgwr || !axi_ctrl->iommu_ctx_misc) {
+		release_mem_region(axi_ctrl->vfemem->start,
+			resource_size(axi_ctrl->vfemem));
+		pr_err("%s: No iommu fw context found\n", __func__);
+		rc = -ENODEV;
+		goto vfe32_no_resource;
+	}
+#endif
+
+	tasklet_init(&axi_ctrl->vfe32_tasklet,
+		axi32_do_tasklet, (unsigned long)axi_ctrl);
+
+	vfe32_ctrl->pdev = pdev;
+	/*disable bayer stats by default*/
+	vfe32_ctrl->ver_num.main = 0;
+	return 0;
+
+vfe32_no_resource:
+	kfree(vfe32_ctrl);
+	kfree(axi_ctrl);
+	return 0;
+}
+
+static struct platform_driver vfe32_driver = {
+	.probe = vfe32_probe,
+	.driver = {
+		.name = MSM_VFE_DRV_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init msm_vfe32_init_module(void)
+{
+	return platform_driver_register(&vfe32_driver);
+}
+
+static void __exit msm_vfe32_exit_module(void)
+{
+	platform_driver_unregister(&vfe32_driver);
+}
+
+module_init(msm_vfe32_init_module);
+module_exit(msm_vfe32_exit_module);
+MODULE_DESCRIPTION("VFE 3.2 driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/vfe/msm_vfe32.h b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe32.h
new file mode 100644
index 0000000..fa4e0bd
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe32.h
@@ -0,0 +1,1078 @@
+/* Copyright (c) 2011-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.
+ */
+
+#ifndef __MSM_VFE32_H__
+#define __MSM_VFE32_H__
+
+#include <linux/bitops.h>
+#include "msm_vfe_stats_buf.h"
+
+#define TRUE  1
+#define FALSE 0
+
+#define VFE32_HW_NUMBER 0x3030B
+#define VFE33_HW_NUMBER 0x30408
+
+/* This defines total number registers in VFE.
+ * Each register is 4 bytes so to get the range,
+ * multiply this number with 4. */
+#define VFE32_REGISTER_TOTAL 0x000001CD
+#define VFE33_REGISTER_TOTAL 0x000001EE
+
+/* at start of camif,  bit 1:0 = 0x01:enable
+ * image data capture at frame boundary. */
+#define CAMIF_COMMAND_START  0x00000005
+
+/* bit 2= 0x1:clear the CAMIF_STATUS register
+ * value. */
+#define CAMIF_COMMAND_CLEAR  0x00000004
+
+/* at stop of vfe pipeline, for now it is assumed
+ * that camif will stop at any time. Bit 1:0 = 0x10:
+ * disable image data capture immediately. */
+#define CAMIF_COMMAND_STOP_IMMEDIATELY  0x00000002
+
+/* at stop of vfe pipeline, for now it is assumed
+ * that camif will stop at any time. Bit 1:0 = 0x00:
+ * disable image data capture at frame boundary */
+#define CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY  0x00000000
+
+/* to halt axi bridge */
+#define AXI_HALT  0x00000001
+
+/* clear the halt bit. */
+#define AXI_HALT_CLEAR  0x00000000
+
+/* reset the pipeline when stop command is issued.
+ * (without reset the register.) bit 26-32 = 0,
+ * domain reset, bit 0-9 = 1 for module reset, except
+ * register module. */
+#define VFE_RESET_UPON_STOP_CMD  0x000003ef
+
+/* reset the pipeline when reset command.
+ * bit 26-32 = 0, domain reset, bit 0-9 = 1 for module reset. */
+#define VFE_RESET_UPON_RESET_CMD  0x000003ff
+
+/* reset the vfe only when reset command*/
+#define VFE_ONLY_RESET_CMD  0x00000002
+
+/*Vfe module reset command*/
+#define VFE_MODULE_RESET_CMD 0x07ffffff
+
+/* bit 5 is for axi status idle or busy.
+ * 1 =  halted,  0 = busy */
+#define AXI_STATUS_BUSY_MASK 0x00000020
+
+/* bit 0 & bit 1 = 1, both y and cbcr irqs need to be present
+ * for frame done interrupt */
+#define VFE_COMP_IRQ_BOTH_Y_CBCR 3
+
+/* bit 1 = 1, only cbcr irq triggers frame done interrupt */
+#define VFE_COMP_IRQ_CBCR_ONLY 2
+
+/* bit 0 = 1, only y irq triggers frame done interrupt */
+#define VFE_COMP_IRQ_Y_ONLY 1
+
+/* bit 0 = 1, PM go;   bit1 = 1, PM stop */
+#define VFE_PERFORMANCE_MONITOR_GO   0x00000001
+#define VFE_PERFORMANCE_MONITOR_STOP 0x00000002
+
+/* bit 0 = 1, test gen go;   bit1 = 1, test gen stop */
+#define VFE_TEST_GEN_GO   0x00000001
+#define VFE_TEST_GEN_STOP 0x00000002
+
+/* the chroma is assumed to be interpolated between
+ * the luma samples.  JPEG 4:2:2 */
+#define VFE_CHROMA_UPSAMPLE_INTERPOLATED 0
+
+/* wm bit offset for IRQ MASK and IRQ STATUS register */
+#define VFE_WM_OFFSET 6
+
+/* constants for irq registers */
+#define VFE_DISABLE_ALL_IRQS 0
+/* bit =1 is to clear the corresponding bit in VFE_IRQ_STATUS.  */
+#define VFE_CLEAR_ALL_IRQS   0xffffffff
+
+#define VFE_IRQ_STATUS0_CAMIF_SOF_MASK            0x00000001
+#define VFE_IRQ_STATUS0_REG_UPDATE_MASK           0x00000020
+#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK 0x00200000
+#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK 0x00400000
+#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE2_MASK 0x00800000
+#define VFE_IRQ_STATUS1_RESET_AXI_HALT_ACK_MASK   0x00800000
+#define VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK       0x01000000
+
+#define VFE_IRQ_STATUS0_STATS_AEC_BG    0x2000  /* bit 13 */
+#define VFE_IRQ_STATUS0_STATS_AF_BF     0x4000  /* bit 14 */
+#define VFE_IRQ_STATUS0_STATS_AWB       0x8000  /* bit 15 */
+#define VFE_IRQ_STATUS0_STATS_RS        0x10000  /* bit 16 */
+#define VFE_IRQ_STATUS0_STATS_CS        0x20000  /* bit 17 */
+#define VFE_IRQ_STATUS0_STATS_IHIST     0x40000  /* bit 18 */
+#define VFE_IRQ_STATUS0_STATS_SK_BHIST  0x80000 /* bit 19 */
+
+#define VFE_IRQ_STATUS0_SYNC_TIMER0   0x2000000  /* bit 25 */
+#define VFE_IRQ_STATUS0_SYNC_TIMER1   0x4000000  /* bit 26 */
+#define VFE_IRQ_STATUS0_SYNC_TIMER2   0x8000000  /* bit 27 */
+#define VFE_IRQ_STATUS0_ASYNC_TIMER0  0x10000000  /* bit 28 */
+#define VFE_IRQ_STATUS0_ASYNC_TIMER1  0x20000000  /* bit 29 */
+#define VFE_IRQ_STATUS0_ASYNC_TIMER2  0x40000000  /* bit 30 */
+#define VFE_IRQ_STATUS0_ASYNC_TIMER3  0x80000000  /* bit 32 */
+
+#define VFE_IRQ_STATUS1_RDI0_REG_UPDATE_MASK  0x4000000 /*bit 26*/
+#define VFE_IRQ_STATUS1_RDI1_REG_UPDATE_MASK  0x8000000 /*bit 27*/
+
+/*TODOs the irq status passed from axi to vfe irq handler does not account
+* for 2 irq status registers. So below macro is added to differentiate between
+* same bit set on both irq status registers. This wil be fixed later by passing
+*entire payload to vfe irq handler and parsing there instead of passing just the
+*status bit*/
+#define VFE_IRQ_STATUS1_RDI0_REG_UPDATE  0x84000000 /*bit 26*/
+#define VFE_IRQ_STATUS1_RDI1_REG_UPDATE  0x88000000 /*bit 27*/
+
+/* imask for while waiting for stop ack,  driver has already
+ * requested stop, waiting for reset irq, and async timer irq.
+ * For irq_status_0, bit 28-32 are for async timer. For
+ * irq_status_1, bit 22 for reset irq, bit 23 for axi_halt_ack
+   irq */
+#define VFE_IMASK_WHILE_STOPPING_0  0xF0000000
+#define VFE_IMASK_WHILE_STOPPING_1  0x00800000
+
+/* no error irq in mask 0 */
+#define VFE_IMASK_ERROR_ONLY_0  0x0
+/* when normal case, don't want to block error status. */
+/* bit 0-21 are error irq bits */
+#define VFE_IMASK_ERROR_ONLY_1  0x003fffff
+
+/* For BPC bit 0,bit 12-17 and bit 26 -20 are set to zero and other's 1 */
+#define BPC_MASK 0xF80C0FFE
+
+/* For ABF bit 4 is set to zero and other's 1 */
+#define ABF_MASK 0xFFFFFFF7
+
+
+/* For DBPC bit 0 is set to zero and other's 1 */
+#define DBPC_MASK 0xFFFFFFFE
+
+/* For DBPC bit 1 is set to zero and other's 1 */
+#define DBCC_MASK 0xFFFFFFFD
+
+/* For DBPC/ABF/DBCC/ABCC bits are set to 1 all others 0 */
+#define DEMOSAIC_MASK 0xF
+
+/* For MCE enable bit 28 set to zero and other's 1 */
+#define MCE_EN_MASK 0xEFFFFFFF
+
+/* For MCE Q_K bit 28 to 32 set to zero and other's 1 */
+#define MCE_Q_K_MASK 0x0FFFFFFF
+
+#define AE_BG_ENABLE_MASK 0x00000020      /* bit 5 */
+#define AF_BF_ENABLE_MASK 0x00000040      /* bit 6 */
+#define AWB_ENABLE_MASK 0x00000080     /* bit 7 */
+#define RS_ENABLE_MASK 0x00000100      /* bit 8  */
+#define CS_ENABLE_MASK 0x00000200      /* bit 9  */
+#define RS_CS_ENABLE_MASK 0x00000300   /* bit 8,9  */
+#define CLF_ENABLE_MASK 0x00002000     /* bit 13 */
+#define IHIST_ENABLE_MASK 0x00010000   /* bit 16 */
+#define SKIN_BHIST_ENABLE_MASK 0x00080000 /* bit 19 */
+#define STATS_ENABLE_MASK 0x000903E0   /* bit 19,16,9,8,7,6,5*/
+
+#define STATS_BG_ENABLE_MASK     0x00000002 /* bit 1 */
+#define STATS_BF_ENABLE_MASK     0x00000004 /* bit 2 */
+#define STATS_BHIST_ENABLE_MASK  0x00000008 /* bit 3 */
+
+#define VFE_REG_UPDATE_TRIGGER           1
+#define VFE_PM_BUF_MAX_CNT_MASK          0xFF
+#define VFE_DMI_CFG_DEFAULT              0x00000100
+#define VFE_AE_PINGPONG_STATUS_BIT       0x80
+#define VFE_AF_PINGPONG_STATUS_BIT       0x100
+#define VFE_AWB_PINGPONG_STATUS_BIT      0x200
+
+#define HFR_MODE_OFF 1
+#define VFE_FRAME_SKIP_PERIOD_MASK 0x0000001F /*bits 0 -4*/
+
+enum VFE32_DMI_RAM_SEL {
+	NO_MEM_SELECTED          = 0,
+	BLACK_LUT_RAM_BANK0      = 0x1,
+	BLACK_LUT_RAM_BANK1      = 0x2,
+	ROLLOFF_RAM0_BANK0       = 0x3,
+	DEMOSAIC_LUT_RAM_BANK0   = 0x4,
+	DEMOSAIC_LUT_RAM_BANK1   = 0x5,
+	STATS_BHIST_RAM0         = 0x6,
+	STATS_BHIST_RAM1         = 0x7,
+	RGBLUT_RAM_CH0_BANK0     = 0x8,
+	RGBLUT_RAM_CH0_BANK1     = 0x9,
+	RGBLUT_RAM_CH1_BANK0     = 0xa,
+	RGBLUT_RAM_CH1_BANK1     = 0xb,
+	RGBLUT_RAM_CH2_BANK0     = 0xc,
+	RGBLUT_RAM_CH2_BANK1     = 0xd,
+	RGBLUT_CHX_BANK0         = 0xe,
+	RGBLUT_CHX_BANK1         = 0xf,
+	STATS_IHIST_RAM          = 0x10,
+	LUMA_ADAPT_LUT_RAM_BANK0 = 0x11,
+	LUMA_ADAPT_LUT_RAM_BANK1 = 0x12,
+	ROLLOFF_RAM1_BANK0       = 0x13,
+	ROLLOFF_RAM0_BANK1       = 0x14,
+	ROLLOFF_RAM1_BANK1       = 0x15,
+};
+
+enum vfe_output_state {
+	VFE_STATE_IDLE,
+	VFE_STATE_START_REQUESTED,
+	VFE_STATE_STARTED,
+	VFE_STATE_STOP_REQUESTED,
+	VFE_STATE_STOPPED,
+};
+
+#define V32_CAMIF_OFF             0x000001E4
+#define V32_CAMIF_LEN             32
+
+#define V32_DEMUX_OFF             0x00000284
+#define V32_DEMUX_LEN             20
+
+#define V32_DEMOSAICV3_0_OFF      0x00000298
+#define V32_DEMOSAICV3_0_LEN      4
+#define V32_DEMOSAICV3_1_OFF      0x0000061C
+#define V32_DEMOSAICV3_1_LEN      88
+#define V32_DEMOSAICV3_2_OFF      0x0000066C
+#define V32_DEMOSAICV3_UP_REG_CNT 5
+/* BPC     */
+#define V32_DEMOSAIC_2_OFF        0x0000029C
+#define V32_DEMOSAIC_2_LEN        8
+
+#define V32_OUT_CLAMP_OFF         0x00000524
+#define V32_OUT_CLAMP_LEN         8
+
+#define V32_OPERATION_CFG_LEN     32
+
+#define V32_AXI_BUS_CMD_OFF       0x00000038
+#define V32_AXI_OUT_OFF           0x0000003C
+#define V32_AXI_OUT_LEN           252
+#define V32_AXI_CFG_LEN           47
+#define V32_AXI_BUS_FMT_OFF       1
+#define V32_AXI_BUS_FMT_LEN       4
+#define V32_AXI_BUS_CFG_LEN       16
+
+#define V32_FRAME_SKIP_OFF        0x00000504
+#define V32_FRAME_SKIP_LEN        32
+
+#define V32_CHROMA_SUBS_OFF       0x000004F8
+#define V32_CHROMA_SUBS_LEN       12
+
+#define V32_FOV_OFF           0x00000360
+#define V32_FOV_LEN           8
+
+#define V32_MAIN_SCALER_OFF 0x00000368
+#define V32_MAIN_SCALER_LEN 28
+
+#define V32_S2Y_OFF 0x000004D0
+#define V32_S2Y_LEN 20
+
+#define V32_S2CbCr_OFF 0x000004E4
+#define V32_S2CbCr_LEN 20
+
+#define V32_CHROMA_EN_OFF 0x000003C4
+#define V32_CHROMA_EN_LEN 36
+
+#define V32_SYNC_TIMER_OFF      0x0000020C
+#define V32_SYNC_TIMER_POLARITY_OFF 0x00000234
+#define V32_TIMER_SELECT_OFF        0x0000025C
+#define V32_SYNC_TIMER_LEN 28
+
+#define V32_ASYNC_TIMER_OFF 0x00000238
+#define V32_ASYNC_TIMER_LEN 28
+
+#define V32_BLACK_LEVEL_OFF 0x00000264
+#define V32_BLACK_LEVEL_LEN 16
+
+#define V32_MESH_ROLL_OFF_CFG_OFF             0x00000274
+#define V32_MESH_ROLL_OFF_CFG_LEN             16
+#define V32_MESH_ROLL_OFF_INIT_TABLE_SIZE     13
+#define V32_MESH_ROLL_OFF_DELTA_TABLE_SIZE    208
+#define V32_MESH_ROLL_OFF_DELTA_TABLE_OFFSET  32
+#define V32_GAMMA_LUT_BANK_SEL_MASK           0x00000007
+
+#define V33_PCA_ROLL_OFF_CFG_LEN1             16
+#define V33_PCA_ROLL_OFF_CFG_OFF1             0x00000274
+#define V33_PCA_ROLL_OFF_CFG_LEN2             12
+#define V33_PCA_ROLL_OFF_CFG_OFF2             0x000007A8
+#define V33_PCA_ROLL_OFF_TABLE_SIZE           (17 + (13*4))
+#define V33_PCA_ROLL_OFF_LUT_BANK_SEL_MASK    0x00010000
+
+#define V32_COLOR_COR_OFF 0x00000388
+#define V32_COLOR_COR_LEN 52
+
+#define V32_WB_OFF 0x00000384
+#define V32_WB_LEN 4
+
+#define V32_RGB_G_OFF 0x000003BC
+#define V32_RGB_G_LEN 4
+
+#define V32_LA_OFF 0x000003C0
+#define V32_LA_LEN 4
+
+#define V32_SCE_OFF 0x00000418
+#define V32_SCE_LEN 136
+
+#define V32_CHROMA_SUP_OFF 0x000003E8
+#define V32_CHROMA_SUP_LEN 12
+
+#define V32_MCE_OFF 0x000003F4
+#define V32_MCE_LEN 36
+#define V32_STATS_AF_OFF 0x0000053c
+#define V32_STATS_AF_LEN 16
+
+#define V32_STATS_AE_OFF 0x00000534
+#define V32_STATS_AE_LEN 8
+
+#define V32_STATS_AWB_OFF 0x0000054c
+#define V32_STATS_AWB_LEN 32
+
+#define V32_STATS_IHIST_OFF 0x0000057c
+#define V32_STATS_IHIST_LEN 8
+
+#define V32_STATS_RS_OFF 0x0000056c
+#define V32_STATS_RS_LEN 8
+
+#define V32_STATS_CS_OFF 0x00000574
+#define V32_STATS_CS_LEN 8
+
+
+#define V32_ASF_OFF 0x000004A0
+#define V32_ASF_LEN 48
+#define V32_ASF_UPDATE_LEN 36
+
+#define V32_CAPTURE_LEN 4
+
+#define V32_GET_HW_VERSION_OFF 0
+#define V32_GET_HW_VERSION_LEN 4
+
+#define V32_LINEARIZATION_OFF1 0x00000264
+#define V32_LINEARIZATION_LEN1 16
+
+#define V32_LINEARIZATION_OFF2 0x0000067C
+#define V32_LINEARIZATION_LEN2 52
+
+#define V32_DEMOSAICV3_OFF 0x00000298
+#define V32_DEMOSAICV3_LEN 4
+
+#define V32_DEMOSAICV3_DBPC_CFG_OFF  0x0000029C
+#define V32_DEMOSAICV3_DBPC_LEN 4
+
+#define V32_DEMOSAICV3_DBPC_CFG_OFF0 0x000002a0
+#define V32_DEMOSAICV3_DBPC_CFG_OFF1 0x00000604
+#define V32_DEMOSAICV3_DBPC_CFG_OFF2 0x00000608
+
+#define V32_DEMOSAICV3_DBCC_OFF 0x0000060C
+#define V32_DEMOSAICV3_DBCC_LEN 16
+
+#define V32_DEMOSAICV3_ABF_OFF 0x000002A4
+#define V32_DEMOSAICV3_ABF_LEN 180
+
+#define V32_MODULE_CFG_OFF 0x00000010
+#define V32_MODULE_CFG_LEN 4
+
+#define V32_ASF_SPECIAL_EFX_CFG_OFF 0x000005FC
+#define V32_ASF_SPECIAL_EFX_CFG_LEN 4
+
+#define V32_CLF_CFG_OFF 0x000006B0
+#define V32_CLF_CFG_LEN 72
+
+#define V32_CLF_LUMA_UPDATE_OFF 0x000006B4
+#define V32_CLF_LUMA_UPDATE_LEN 60
+
+#define V32_CLF_CHROMA_UPDATE_OFF 0x000006F0
+#define V32_CLF_CHROMA_UPDATE_LEN 8
+
+#define V32_STATS_BG_OFF 0x00000700
+#define V32_STATS_BG_LEN 12
+
+#define V32_STATS_BF_OFF 0x0000070c
+#define V32_STATS_BF_LEN 24
+
+#define V32_STATS_BHIST_OFF 0x00000724
+#define V32_STATS_BHIST_LEN 8
+
+struct vfe_cmd_hw_version {
+	uint32_t minorVersion;
+	uint32_t majorVersion;
+	uint32_t coreVersion;
+};
+
+enum VFE_AXI_OUTPUT_MODE {
+	VFE_AXI_OUTPUT_MODE_Output1,
+	VFE_AXI_OUTPUT_MODE_Output2,
+	VFE_AXI_OUTPUT_MODE_Output1AndOutput2,
+	VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2,
+	VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1,
+	VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2,
+	VFE_AXI_LAST_OUTPUT_MODE_ENUM
+};
+
+enum VFE_RAW_WR_PATH_SEL {
+	VFE_RAW_OUTPUT_DISABLED,
+	VFE_RAW_OUTPUT_ENC_CBCR_PATH,
+	VFE_RAW_OUTPUT_VIEW_CBCR_PATH,
+	VFE_RAW_OUTPUT_PATH_INVALID
+};
+
+
+#define VFE_AXI_OUTPUT_BURST_LENGTH     4
+#define VFE_MAX_NUM_FRAGMENTS_PER_FRAME 4
+#define VFE_AXI_OUTPUT_CFG_FRAME_COUNT  3
+
+struct vfe_cmds_per_write_master {
+	uint16_t imageWidth;
+	uint16_t imageHeight;
+	uint16_t outRowCount;
+	uint16_t outRowIncrement;
+	uint32_t outFragments[VFE_AXI_OUTPUT_CFG_FRAME_COUNT]
+		[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
+};
+
+struct vfe_cmds_axi_per_output_path {
+	uint8_t fragmentCount;
+	struct vfe_cmds_per_write_master firstWM;
+	struct vfe_cmds_per_write_master secondWM;
+};
+
+enum VFE_AXI_BURST_LENGTH {
+	VFE_AXI_BURST_LENGTH_IS_2  = 2,
+	VFE_AXI_BURST_LENGTH_IS_4  = 4,
+	VFE_AXI_BURST_LENGTH_IS_8  = 8,
+	VFE_AXI_BURST_LENGTH_IS_16 = 16
+};
+
+
+struct vfe_cmd_fov_crop_config {
+	uint8_t enable;
+	uint16_t firstPixel;
+	uint16_t lastPixel;
+	uint16_t firstLine;
+	uint16_t lastLine;
+};
+
+struct vfe_cmds_main_scaler_stripe_init {
+	uint16_t MNCounterInit;
+	uint16_t phaseInit;
+};
+
+struct vfe_cmds_scaler_one_dimension {
+	uint8_t  enable;
+	uint16_t inputSize;
+	uint16_t outputSize;
+	uint32_t phaseMultiplicationFactor;
+	uint8_t  interpolationResolution;
+};
+
+struct vfe_cmd_main_scaler_config {
+	uint8_t enable;
+	struct vfe_cmds_scaler_one_dimension    hconfig;
+	struct vfe_cmds_scaler_one_dimension    vconfig;
+	struct vfe_cmds_main_scaler_stripe_init MNInitH;
+	struct vfe_cmds_main_scaler_stripe_init MNInitV;
+};
+
+struct vfe_cmd_scaler2_config {
+	uint8_t enable;
+	struct vfe_cmds_scaler_one_dimension hconfig;
+	struct vfe_cmds_scaler_one_dimension vconfig;
+};
+
+
+struct vfe_cmd_frame_skip_update {
+	uint32_t output1Pattern;
+	uint32_t output2Pattern;
+};
+
+struct vfe_cmd_output_clamp_config {
+	uint8_t minCh0;
+	uint8_t minCh1;
+	uint8_t minCh2;
+	uint8_t maxCh0;
+	uint8_t maxCh1;
+	uint8_t maxCh2;
+};
+
+struct vfe_cmd_chroma_subsample_config {
+	uint8_t enable;
+	uint8_t cropEnable;
+	uint8_t vsubSampleEnable;
+	uint8_t hsubSampleEnable;
+	uint8_t vCosited;
+	uint8_t hCosited;
+	uint8_t vCositedPhase;
+	uint8_t hCositedPhase;
+	uint16_t cropWidthFirstPixel;
+	uint16_t cropWidthLastPixel;
+	uint16_t cropHeightFirstLine;
+	uint16_t cropHeightLastLine;
+};
+
+enum VFE_START_PIXEL_PATTERN {
+	VFE_BAYER_RGRGRG,
+	VFE_BAYER_GRGRGR,
+	VFE_BAYER_BGBGBG,
+	VFE_BAYER_GBGBGB,
+	VFE_YUV_YCbYCr,
+	VFE_YUV_YCrYCb,
+	VFE_YUV_CbYCrY,
+	VFE_YUV_CrYCbY
+};
+
+enum VFE_BUS_RD_INPUT_PIXEL_PATTERN {
+	VFE_BAYER_RAW,
+	VFE_YUV_INTERLEAVED,
+	VFE_YUV_PSEUDO_PLANAR_Y,
+	VFE_YUV_PSEUDO_PLANAR_CBCR
+};
+
+enum VFE_YUV_INPUT_COSITING_MODE {
+	VFE_YUV_COSITED,
+	VFE_YUV_INTERPOLATED
+};
+
+#define VFE32_GAMMA_NUM_ENTRIES  64
+
+#define VFE32_LA_TABLE_LENGTH    64
+
+#define VFE32_LINEARIZATON_TABLE_LENGTH    36
+
+struct vfe_cmds_demosaic_abf {
+	uint8_t   enable;
+	uint8_t   forceOn;
+	uint8_t   shift;
+	uint16_t  lpThreshold;
+	uint16_t  max;
+	uint16_t  min;
+	uint8_t   ratio;
+};
+
+struct vfe_cmds_demosaic_bpc {
+	uint8_t   enable;
+	uint16_t  fmaxThreshold;
+	uint16_t  fminThreshold;
+	uint16_t  redDiffThreshold;
+	uint16_t  blueDiffThreshold;
+	uint16_t  greenDiffThreshold;
+};
+
+struct vfe_cmd_demosaic_config {
+	uint8_t   enable;
+	uint8_t   slopeShift;
+	struct vfe_cmds_demosaic_abf abfConfig;
+	struct vfe_cmds_demosaic_bpc bpcConfig;
+};
+
+struct vfe_cmd_demosaic_bpc_update {
+	struct vfe_cmds_demosaic_bpc bpcUpdate;
+};
+
+struct vfe_cmd_demosaic_abf_update {
+	struct vfe_cmds_demosaic_abf abfUpdate;
+};
+
+struct vfe_cmd_white_balance_config {
+	uint8_t  enable;
+	uint16_t ch2Gain;
+	uint16_t ch1Gain;
+	uint16_t ch0Gain;
+};
+
+enum VFE_COLOR_CORRECTION_COEF_QFACTOR {
+	COEF_IS_Q7_SIGNED,
+	COEF_IS_Q8_SIGNED,
+	COEF_IS_Q9_SIGNED,
+	COEF_IS_Q10_SIGNED
+};
+
+struct vfe_cmd_color_correction_config {
+	uint8_t     enable;
+	enum VFE_COLOR_CORRECTION_COEF_QFACTOR coefQFactor;
+	int16_t  C0;
+	int16_t  C1;
+	int16_t  C2;
+	int16_t  C3;
+	int16_t  C4;
+	int16_t  C5;
+	int16_t  C6;
+	int16_t  C7;
+	int16_t  C8;
+	int16_t  K0;
+	int16_t  K1;
+	int16_t  K2;
+};
+
+#define VFE_LA_TABLE_LENGTH 64
+
+struct vfe_cmd_la_config {
+	uint8_t enable;
+	int16_t table[VFE_LA_TABLE_LENGTH];
+};
+
+#define VFE_GAMMA_TABLE_LENGTH 256
+enum VFE_RGB_GAMMA_TABLE_SELECT {
+	RGB_GAMMA_CH0_SELECTED,
+	RGB_GAMMA_CH1_SELECTED,
+	RGB_GAMMA_CH2_SELECTED,
+	RGB_GAMMA_CH0_CH1_SELECTED,
+	RGB_GAMMA_CH0_CH2_SELECTED,
+	RGB_GAMMA_CH1_CH2_SELECTED,
+	RGB_GAMMA_CH0_CH1_CH2_SELECTED
+};
+
+struct vfe_cmd_rgb_gamma_config {
+	uint8_t enable;
+	enum VFE_RGB_GAMMA_TABLE_SELECT channelSelect;
+	int16_t table[VFE_GAMMA_TABLE_LENGTH];
+};
+
+struct vfe_cmd_chroma_enhan_config {
+	uint8_t  enable;
+	int16_t am;
+	int16_t ap;
+	int16_t bm;
+	int16_t bp;
+	int16_t cm;
+	int16_t cp;
+	int16_t dm;
+	int16_t dp;
+	int16_t kcr;
+	int16_t kcb;
+	int16_t RGBtoYConversionV0;
+	int16_t RGBtoYConversionV1;
+	int16_t RGBtoYConversionV2;
+	uint8_t RGBtoYConversionOffset;
+};
+
+struct vfe_cmd_chroma_suppression_config {
+	uint8_t enable;
+	uint8_t m1;
+	uint8_t m3;
+	uint8_t n1;
+	uint8_t n3;
+	uint8_t nn1;
+	uint8_t mm1;
+};
+
+struct vfe_cmd_asf_config {
+	uint8_t enable;
+	uint8_t smoothFilterEnabled;
+	uint8_t sharpMode;
+	uint8_t smoothCoefCenter;
+	uint8_t smoothCoefSurr;
+	uint8_t normalizeFactor;
+	uint8_t sharpK1;
+	uint8_t sharpK2;
+	uint8_t sharpThreshE1;
+	int8_t sharpThreshE2;
+	int8_t sharpThreshE3;
+	int8_t sharpThreshE4;
+	int8_t sharpThreshE5;
+	int8_t filter1Coefficients[9];
+	int8_t filter2Coefficients[9];
+	uint8_t  cropEnable;
+	uint16_t cropFirstPixel;
+	uint16_t cropLastPixel;
+	uint16_t cropFirstLine;
+	uint16_t cropLastLine;
+};
+
+struct vfe_cmd_asf_update {
+	uint8_t enable;
+	uint8_t smoothFilterEnabled;
+	uint8_t sharpMode;
+	uint8_t smoothCoefCenter;
+	uint8_t smoothCoefSurr;
+	uint8_t normalizeFactor;
+	uint8_t sharpK1;
+	uint8_t sharpK2;
+	uint8_t sharpThreshE1;
+	int8_t  sharpThreshE2;
+	int8_t  sharpThreshE3;
+	int8_t  sharpThreshE4;
+	int8_t  sharpThreshE5;
+	int8_t  filter1Coefficients[9];
+	int8_t  filter2Coefficients[9];
+	uint8_t cropEnable;
+};
+
+enum VFE_TEST_GEN_SYNC_EDGE {
+	VFE_TEST_GEN_SYNC_EDGE_ActiveHigh,
+	VFE_TEST_GEN_SYNC_EDGE_ActiveLow
+};
+
+
+struct vfe_cmd_bus_pm_start {
+	uint8_t output2YWrPmEnable;
+	uint8_t output2CbcrWrPmEnable;
+	uint8_t output1YWrPmEnable;
+	uint8_t output1CbcrWrPmEnable;
+};
+
+struct  vfe_frame_skip_counts {
+	uint32_t  totalFrameCount;
+	uint32_t  output1Count;
+	uint32_t  output2Count;
+};
+
+enum VFE_AXI_RD_UNPACK_HBI_SEL {
+	VFE_AXI_RD_HBI_32_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_64_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_128_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_256_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_512_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_1024_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_2048_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_4096_CLOCK_CYCLES
+};
+
+struct vfe_frame_bpc_info {
+	uint32_t greenDefectPixelCount;
+	uint32_t redBlueDefectPixelCount;
+};
+
+struct vfe_frame_asf_info {
+	uint32_t  asfMaxEdge;
+	uint32_t  asfHbiCount;
+};
+
+struct vfe_msg_camif_status {
+	uint8_t  camifState;
+	uint32_t pixelCount;
+	uint32_t lineCount;
+};
+
+struct vfe32_irq_status {
+	uint32_t vfeIrqStatus0;
+	uint32_t vfeIrqStatus1;
+	uint32_t camifStatus;
+	uint32_t demosaicStatus;
+	uint32_t asfMaxEdge;
+};
+
+#define V32_PREVIEW_AXI_FLAG  0x00000001
+#define V32_SNAPSHOT_AXI_FLAG (0x00000001<<1)
+
+struct vfe32_cmd_type {
+	uint16_t id;
+	uint32_t length;
+	uint32_t offset;
+	uint32_t flag;
+};
+
+struct vfe32_free_buf {
+	struct list_head node;
+	uint32_t paddr;
+	uint32_t y_off;
+	uint32_t cbcr_off;
+};
+
+struct vfe32_output_ch {
+	struct list_head free_buf_queue;
+	spinlock_t free_buf_lock;
+	uint32_t inst_handle;
+	int8_t ch0;
+	int8_t ch1;
+	int8_t ch2;
+	int32_t  capture_cnt;
+	uint32_t  frame_drop_cnt;
+	struct msm_free_buf ping;
+	struct msm_free_buf pong;
+	struct msm_free_buf free_buf;
+};
+
+/* no error irq in mask 0 */
+#define VFE32_IMASK_ERROR_ONLY_0  0x0
+/* when normal case, don't want to block error status. */
+/* bit 0-21 are error irq bits */
+#define VFE32_IMASK_COMMON_ERROR_ONLY_1       0x00407F00
+#define VFE32_IMASK_VFE_ERROR_ONLY_1          0x001F80FF
+#define VFE32_IMASK_CAMIF_ERROR               (0x00000001<<0)
+#define VFE32_IMASK_BHIST_OVWR                (0x00000001<<1)
+#define VFE32_IMASK_STATS_CS_OVWR             (0x00000001<<2)
+#define VFE32_IMASK_STATS_IHIST_OVWR          (0x00000001<<3)
+#define VFE32_IMASK_REALIGN_BUF_Y_OVFL        (0x00000001<<4)
+#define VFE32_IMASK_REALIGN_BUF_CB_OVFL       (0x00000001<<5)
+#define VFE32_IMASK_REALIGN_BUF_CR_OVFL       (0x00000001<<6)
+#define VFE32_IMASK_VIOLATION                 (0x00000001<<7)
+#define VFE32_IMASK_IMG_MAST_0_BUS_OVFL       (0x00000001<<8)
+#define VFE32_IMASK_IMG_MAST_1_BUS_OVFL       (0x00000001<<9)
+#define VFE32_IMASK_IMG_MAST_2_BUS_OVFL       (0x00000001<<10)
+#define VFE32_IMASK_IMG_MAST_3_BUS_OVFL       (0x00000001<<11)
+#define VFE32_IMASK_IMG_MAST_4_BUS_OVFL       (0x00000001<<12)
+#define VFE32_IMASK_IMG_MAST_5_BUS_OVFL       (0x00000001<<13)
+#define VFE32_IMASK_IMG_MAST_6_BUS_OVFL       (0x00000001<<14)
+#define VFE32_IMASK_STATS_AE_BG_BUS_OVFL      (0x00000001<<15)
+#define VFE32_IMASK_STATS_AF_BF_BUS_OVFL      (0x00000001<<16)
+#define VFE32_IMASK_STATS_AWB_BUS_OVFL        (0x00000001<<17)
+#define VFE32_IMASK_STATS_RS_BUS_OVFL         (0x00000001<<18)
+#define VFE32_IMASK_STATS_CS_BUS_OVFL         (0x00000001<<19)
+#define VFE32_IMASK_STATS_IHIST_BUS_OVFL      (0x00000001<<20)
+#define VFE32_IMASK_STATS_SKIN_BHIST_BUS_OVFL (0x00000001<<21)
+#define VFE32_IMASK_AXI_ERROR                 (0x00000001<<22)
+
+#define VFE_COM_STATUS 0x000FE000
+
+struct vfe32_output_path {
+	uint16_t output_mode;     /* bitmask  */
+
+	struct vfe32_output_ch out0; /* preview and thumbnail */
+	struct vfe32_output_ch out1; /* snapshot */
+	struct vfe32_output_ch out2; /* rdi0    */
+	struct vfe32_output_ch out3; /* rdi01   */
+};
+
+struct vfe32_frame_extra {
+	uint32_t greenDefectPixelCount;
+	uint32_t redBlueDefectPixelCount;
+
+	uint32_t  asfMaxEdge;
+	uint32_t  asfHbiCount;
+
+	uint32_t yWrPmStats0;
+	uint32_t yWrPmStats1;
+	uint32_t cbcrWrPmStats0;
+	uint32_t cbcrWrPmStats1;
+
+	uint32_t  frameCounter;
+};
+
+#define VFE_DISABLE_ALL_IRQS            0
+#define VFE_CLEAR_ALL_IRQS              0xffffffff
+
+#define VFE_HW_VERSION			0x00000000
+#define VFE_GLOBAL_RESET                0x00000004
+#define VFE_MODULE_RESET		0x00000008
+#define VFE_CGC_OVERRIDE                0x0000000C
+#define VFE_MODULE_CFG                  0x00000010
+#define VFE_CFG				0x00000014
+#define VFE_IRQ_CMD                     0x00000018
+#define VFE_IRQ_MASK_0                  0x0000001C
+#define VFE_IRQ_MASK_1                  0x00000020
+#define VFE_IRQ_CLEAR_0                 0x00000024
+#define VFE_IRQ_CLEAR_1                 0x00000028
+#define VFE_IRQ_STATUS_0                0x0000002C
+#define VFE_IRQ_STATUS_1                0x00000030
+#define VFE_IRQ_COMP_MASK               0x00000034
+#define VFE_BUS_CMD                     0x00000038
+#define VFE_BUS_PING_PONG_STATUS        0x00000180
+#define VFE_AXI_CMD                     0x000001D8
+#define VFE_AXI_STATUS        0x000001DC
+#define VFE_BUS_STATS_PING_PONG_BASE    0x000000F4
+
+#define VFE_BUS_STATS_AEC_BG_WR_PING_ADDR    0x000000F4
+#define VFE_BUS_STATS_AEC_BG_WR_PONG_ADDR    0x000000F8
+#define VFE_BUS_STATS_AEC_BG_UB_CFG          0x000000FC
+#define VFE_BUS_STATS_AF_BF_WR_PING_ADDR     0x00000100
+#define VFE_BUS_STATS_AF_BF_WR_PONG_ADDR     0x00000104
+#define VFE_BUS_STATS_AF_BF_UB_CFG           0x00000108
+#define VFE_BUS_STATS_AWB_WR_PING_ADDR    0x0000010C
+#define VFE_BUS_STATS_AWB_WR_PONG_ADDR    0x00000110
+#define VFE_BUS_STATS_AWB_UB_CFG          0x00000114
+#define VFE_BUS_STATS_RS_WR_PING_ADDR    0x00000118
+#define VFE_BUS_STATS_RS_WR_PONG_ADDR    0x0000011C
+#define VFE_BUS_STATS_RS_UB_CFG          0x00000120
+
+#define VFE_BUS_STATS_CS_WR_PING_ADDR    0x00000124
+#define VFE_BUS_STATS_CS_WR_PONG_ADDR    0x00000128
+#define VFE_BUS_STATS_CS_UB_CFG          0x0000012C
+#define VFE_BUS_STATS_HIST_WR_PING_ADDR   0x00000130
+#define VFE_BUS_STATS_HIST_WR_PONG_ADDR   0x00000134
+#define VFE_BUS_STATS_HIST_UB_CFG          0x00000138
+#define VFE_BUS_STATS_SKIN_BHIST_WR_PING_ADDR    0x0000013C
+#define VFE_BUS_STATS_SKIN_BHIST_WR_PONG_ADDR    0x00000140
+#define VFE_BUS_STATS_SKIN_BHIST_UB_CFG          0x00000144
+#define VFE_CAMIF_COMMAND               0x000001E0
+#define VFE_CAMIF_STATUS                0x00000204
+#define VFE_REG_UPDATE_CMD              0x00000260
+#define VFE_DEMUX_GAIN_0                0x00000288
+#define VFE_DEMUX_GAIN_1                0x0000028C
+#define VFE_CHROMA_UP                   0x0000035C
+#define VFE_FRAMEDROP_ENC_Y_CFG         0x00000504
+#define VFE_FRAMEDROP_ENC_CBCR_CFG      0x00000508
+#define VFE_FRAMEDROP_ENC_Y_PATTERN     0x0000050C
+#define VFE_FRAMEDROP_ENC_CBCR_PATTERN  0x00000510
+#define VFE_FRAMEDROP_VIEW_Y            0x00000514
+#define VFE_FRAMEDROP_VIEW_CBCR         0x00000518
+#define VFE_FRAMEDROP_VIEW_Y_PATTERN    0x0000051C
+#define VFE_FRAMEDROP_VIEW_CBCR_PATTERN 0x00000520
+#define VFE_CLAMP_MAX                   0x00000524
+#define VFE_CLAMP_MIN                   0x00000528
+#define VFE_REALIGN_BUF                 0x0000052C
+#define VFE_STATS_CFG                   0x00000530
+#define VFE_STATS_AWB_SGW_CFG           0x00000554
+#define VFE_DMI_CFG                     0x00000598
+#define VFE_DMI_ADDR                    0x0000059C
+#define VFE_DMI_DATA_HI                 0x000005A0
+#define VFE_DMI_DATA_LO                 0x000005A4
+#define VFE_AXI_CFG                     0x00000600
+#define VFE_BUS_IO_FORMAT_CFG           0x000006F8
+#define VFE_PIXEL_IF_CFG                0x000006FC
+#define VFE_RDI0_CFG                    0x00000734
+#define VFE_RDI1_CFG                    0x000007A4
+
+#define VFE_VIOLATION_STATUS            0x000007B4
+
+#define VFE33_DMI_DATA_HI               0x000005A0
+#define VFE33_DMI_DATA_LO               0x000005A4
+
+#define VFE_AXI_CFG_MASK                0xFFFFFFFF
+
+#define VFE32_OUTPUT_MODE_PT			BIT(0)
+#define VFE32_OUTPUT_MODE_S			BIT(1)
+#define VFE32_OUTPUT_MODE_V			BIT(2)
+#define VFE32_OUTPUT_MODE_P			BIT(3)
+#define VFE32_OUTPUT_MODE_T			BIT(4)
+#define VFE32_OUTPUT_MODE_P_ALL_CHNLS		BIT(5)
+#define VFE32_OUTPUT_MODE_PRIMARY		BIT(6)
+#define VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS	BIT(7)
+#define VFE32_OUTPUT_MODE_SECONDARY		BIT(8)
+#define VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS	BIT(9)
+#define VFE32_OUTPUT_MODE_TERTIARY1		BIT(10)
+#define VFE32_OUTPUT_MODE_TERTIARY2		BIT(11)
+
+struct vfe_stats_control {
+	uint32_t droppedStatsFrameCount;
+	uint32_t bufToRender;
+};
+struct axi_ctrl_t;
+struct vfe32_ctrl_type;
+
+struct vfe_share_ctrl_t {
+	void __iomem *vfebase;
+	uint32_t register_total;
+
+	atomic_t vstate;
+	atomic_t handle_common_irq;
+	uint32_t vfeFrameId;
+	uint32_t rdi0FrameId;
+	uint32_t rdi1FrameId;
+	uint32_t rdi2FrameId;
+	uint32_t stats_comp;
+	spinlock_t  sd_notify_lock;
+	spinlock_t  stop_flag_lock;
+	int8_t stop_ack_pending;
+	enum vfe_output_state liveshot_state;
+	uint32_t vfe_capture_count;
+	int32_t rdi0_capture_count;
+	int32_t rdi1_capture_count;
+	uint8_t update_counter;
+
+	uint32_t operation_mode;     /* streaming or snapshot */
+	uint32_t current_mode;
+	struct vfe32_output_path outpath;
+
+	uint16_t port_info;
+	uint8_t stop_immediately;
+	uint8_t sync_abort;
+	uint16_t cmd_type;
+	uint8_t vfe_reset_flag;
+	uint8_t dual_enabled;
+
+	uint8_t axi_ref_cnt;
+	uint16_t comp_output_mode;
+
+	struct completion reset_complete;
+
+	spinlock_t  update_ack_lock;
+	spinlock_t  start_ack_lock;
+
+	struct axi_ctrl_t *axi_ctrl;
+	struct vfe32_ctrl_type *vfe32_ctrl;
+	int8_t start_ack_pending;
+	int8_t update_ack_pending;
+	enum vfe_output_state recording_state;
+
+	atomic_t pix0_update_ack_pending;
+	atomic_t rdi0_update_ack_pending;
+	atomic_t rdi1_update_ack_pending;
+	atomic_t rdi2_update_ack_pending;
+
+};
+
+struct axi_ctrl_t {
+	struct v4l2_subdev subdev;
+	struct platform_device *pdev;
+	struct resource *vfeirq;
+	spinlock_t  tasklet_lock;
+	struct list_head tasklet_q;
+
+	void *syncdata;
+
+	struct resource	*vfemem;
+	struct resource *vfeio;
+	struct regulator *fs_vfe;
+	struct clk *vfe_clk[3];
+	struct tasklet_struct vfe32_tasklet;
+	struct vfe_share_ctrl_t *share_ctrl;
+	struct device *iommu_ctx_imgwr;
+	struct device *iommu_ctx_misc;
+};
+
+struct vfe32_ctrl_type {
+	spinlock_t  state_lock;
+	spinlock_t  stats_bufq_lock;
+	uint32_t extlen;
+	void *extdata;
+
+	int8_t vfe_sof_count_enable;
+	int8_t update_linear;
+	int8_t update_rolloff;
+	int8_t update_la;
+	int8_t update_gamma;
+
+	struct vfe_share_ctrl_t *share_ctrl;
+
+	uint32_t sync_timer_repeat_count;
+	uint32_t sync_timer_state;
+	uint32_t sync_timer_number;
+
+	struct msm_ver_num_info ver_num;
+	struct vfe_stats_control afbfStatsControl;
+	struct vfe_stats_control awbStatsControl;
+	struct vfe_stats_control aecbgStatsControl;
+	struct vfe_stats_control ihistStatsControl;
+	struct vfe_stats_control rsStatsControl;
+	struct vfe_stats_control csStatsControl;
+	struct vfe_stats_control bhistStatsControl;
+
+	/* v4l2 subdev */
+	struct v4l2_subdev subdev;
+	struct platform_device *pdev;
+	uint32_t hfr_mode;
+	uint32_t frame_skip_cnt;
+	uint32_t frame_skip_pattern;
+	uint32_t snapshot_frame_cnt;
+	struct msm_stats_bufq_ctrl stats_ctrl;
+	struct msm_stats_ops stats_ops;
+
+	uint32_t simultaneous_sof_stat;
+};
+
+#define statsAeNum      0
+#define statsAfNum      1
+#define statsAwbNum     2
+#define statsRsNum      3
+#define statsCsNum      4
+#define statsIhistNum   5
+#define statsSkinNum    6
+
+struct vfe_cmd_stats_ack {
+	uint32_t  nextStatsBuf;
+};
+
+#define VFE_STATS_BUFFER_COUNT            3
+
+struct vfe_cmd_stats_buf {
+	uint32_t statsBuf[VFE_STATS_BUFFER_COUNT];
+};
+
+#endif /* __MSM_VFE32_H__ */
diff --git a/drivers/media/platform/msm/camera_v1/vfe/msm_vfe40.c b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe40.c
new file mode 100644
index 0000000..5a96a79
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe40.c
@@ -0,0 +1,6478 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/atomic.h>
+#include <linux/regulator/consumer.h>
+#include <linux/clk.h>
+#include <mach/irqs.h>
+#include <mach/camera.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+#include <media/msm_isp.h>
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
+
+#include "msm.h"
+#include "msm_cam_server.h"
+#include "msm_vfe40.h"
+
+atomic_t irq_cnt;
+
+#define VFE_WM_CFG_BASE 0x0070
+#define VFE_WM_CFG_LEN 0x0024
+
+#define vfe40_get_ch_ping_addr(base, chn) \
+	(msm_camera_io_r((base) + VFE_WM_CFG_BASE + VFE_WM_CFG_LEN * (chn)))
+#define vfe40_get_ch_pong_addr(base, chn) \
+	(msm_camera_io_r((base) + VFE_WM_CFG_BASE + VFE_WM_CFG_LEN * (chn) + 4))
+#define vfe40_get_ch_addr(ping_pong, base, chn) \
+	((((ping_pong) & (1 << (chn))) == 0) ? \
+	(vfe40_get_ch_pong_addr((base), chn)) : \
+	(vfe40_get_ch_ping_addr((base), chn)))
+
+#define vfe40_put_ch_ping_addr(base, chn, addr) \
+	(msm_camera_io_w((addr), \
+	(base) + VFE_WM_CFG_BASE + VFE_WM_CFG_LEN * (chn)))
+#define vfe40_put_ch_pong_addr(base, chn, addr) \
+	(msm_camera_io_w((addr), \
+	(base) + VFE_WM_CFG_BASE + VFE_WM_CFG_LEN * (chn) + 4))
+#define vfe40_put_ch_addr(ping_pong, base, chn, addr) \
+	(((ping_pong) & (1 << (chn))) == 0 ?   \
+	vfe40_put_ch_pong_addr((base), (chn), (addr)) : \
+	vfe40_put_ch_ping_addr((base), (chn), (addr)))
+
+static uint32_t vfe_clk_rate;
+static void vfe40_send_isp_msg(struct v4l2_subdev *sd,
+	uint32_t vfeFrameId, uint32_t isp_msg_id);
+
+
+struct vfe40_isr_queue_cmd {
+	struct list_head list;
+	uint32_t                           vfeInterruptStatus0;
+	uint32_t                           vfeInterruptStatus1;
+};
+
+static struct vfe40_cmd_type vfe40_cmd[] = {
+	[1] = {VFE_CMD_SET_CLK},
+	[2] = {VFE_CMD_RESET},
+	[3] = {VFE_CMD_START},
+	[4] = {VFE_CMD_TEST_GEN_START},
+	[5] = {VFE_CMD_OPERATION_CFG, V40_OPERATION_CFG_LEN},
+	[6] = {VFE_CMD_AXI_OUT_CFG, V40_AXI_OUT_LEN, V40_AXI_BUS_CMD_OFF, 0xFF},
+	[7] = {VFE_CMD_CAMIF_CFG, V40_CAMIF_LEN, V40_CAMIF_OFF, 0xFF},
+	[8] = {VFE_CMD_AXI_INPUT_CFG},
+	[9] = {VFE_CMD_BLACK_LEVEL_CFG},
+	[10] = {VFE_CMD_MESH_ROLL_OFF_CFG, V40_MESH_ROLL_OFF_CFG_LEN,
+		V40_MESH_ROLL_OFF_CFG_OFF, 0xFF},
+	[11] = {VFE_CMD_DEMUX_CFG, V40_DEMUX_LEN, V40_DEMUX_OFF, 0xFF},
+	[12] = {VFE_CMD_FOV_CFG},
+	[13] = {VFE_CMD_MAIN_SCALER_CFG},
+	[14] = {VFE_CMD_WB_CFG, V40_WB_LEN, V40_WB_OFF, 0xFF},
+	[15] = {VFE_CMD_COLOR_COR_CFG, V40_COLOR_COR_LEN,
+		V40_COLOR_COR_OFF, 0xFF},
+	[16] = {VFE_CMD_RGB_G_CFG, V40_RGB_G_LEN, V40_RGB_G_OFF, 0xFF},
+	[17] = {VFE_CMD_LA_CFG, V40_LA_LEN, V40_LA_OFF, 0xFF },
+	[18] = {VFE_CMD_CHROMA_EN_CFG, V40_CHROMA_EN_LEN, V40_CHROMA_EN_OFF,
+		0xFF},
+	[19] = {VFE_CMD_CHROMA_SUP_CFG, V40_CHROMA_SUP_LEN,
+		V40_CHROMA_SUP_OFF, 0xFF},
+	[20] = {VFE_CMD_MCE_CFG, V40_MCE_LEN, V40_MCE_OFF, 0xFF},
+	[21] = {VFE_CMD_SK_ENHAN_CFG, V40_SCE_LEN, V40_SCE_OFF, 0xFF},
+	[22] = {VFE_CMD_ASF_CFG, V40_ASF_LEN, V40_ASF_OFF, 0xFF},
+	[23] = {VFE_CMD_S2Y_CFG},
+	[24] = {VFE_CMD_S2CbCr_CFG},
+	[25] = {VFE_CMD_CHROMA_SUBS_CFG},
+	[26] = {VFE_CMD_OUT_CLAMP_CFG, V40_OUT_CLAMP_LEN, V40_OUT_CLAMP_OFF,
+		0xFF},
+	[27] = {VFE_CMD_FRAME_SKIP_CFG},
+	[31] = {VFE_CMD_UPDATE},
+	[32] = {VFE_CMD_BL_LVL_UPDATE},
+	[33] = {VFE_CMD_DEMUX_UPDATE, V40_DEMUX_LEN, V40_DEMUX_OFF, 0xFF},
+	[34] = {VFE_CMD_FOV_UPDATE},
+	[35] = {VFE_CMD_MAIN_SCALER_UPDATE},
+	[36] = {VFE_CMD_WB_UPDATE, V40_WB_LEN, V40_WB_OFF, 0xFF},
+	[37] = {VFE_CMD_COLOR_COR_UPDATE, V40_COLOR_COR_LEN,
+		V40_COLOR_COR_OFF, 0xFF},
+	[38] = {VFE_CMD_RGB_G_UPDATE, V40_RGB_G_LEN, V40_CHROMA_EN_OFF, 0xFF},
+	[39] = {VFE_CMD_LA_UPDATE, V40_LA_LEN, V40_LA_OFF, 0xFF },
+	[40] = {VFE_CMD_CHROMA_EN_UPDATE, V40_CHROMA_EN_LEN,
+		V40_CHROMA_EN_OFF, 0xFF},
+	[41] = {VFE_CMD_CHROMA_SUP_UPDATE, V40_CHROMA_SUP_LEN,
+		V40_CHROMA_SUP_OFF, 0xFF},
+	[42] = {VFE_CMD_MCE_UPDATE, V40_MCE_LEN, V40_MCE_OFF, 0xFF},
+	[43] = {VFE_CMD_SK_ENHAN_UPDATE, V40_SCE_LEN, V40_SCE_OFF, 0xFF},
+	[44] = {VFE_CMD_S2CbCr_UPDATE},
+	[45] = {VFE_CMD_S2Y_UPDATE},
+	[46] = {VFE_CMD_ASF_UPDATE, V40_ASF_UPDATE_LEN, V40_ASF_OFF, 0xFF},
+	[47] = {VFE_CMD_FRAME_SKIP_UPDATE},
+	[48] = {VFE_CMD_CAMIF_FRAME_UPDATE},
+	[49] = {VFE_CMD_STATS_AF_UPDATE},
+	[50] = {VFE_CMD_STATS_AE_UPDATE},
+	[51] = {VFE_CMD_STATS_AWB_UPDATE, V40_STATS_AWB_LEN,
+		V40_STATS_AWB_OFF},
+	[52] = {VFE_CMD_STATS_RS_UPDATE, V40_STATS_RS_LEN, V40_STATS_RS_OFF},
+	[53] = {VFE_CMD_STATS_CS_UPDATE, V40_STATS_CS_LEN, V40_STATS_CS_OFF},
+	[54] = {VFE_CMD_STATS_SKIN_UPDATE},
+	[55] = {VFE_CMD_STATS_IHIST_UPDATE, V40_STATS_IHIST_LEN,
+		V40_STATS_IHIST_OFF},
+	[57] = {VFE_CMD_EPOCH1_ACK},
+	[58] = {VFE_CMD_EPOCH2_ACK},
+	[59] = {VFE_CMD_START_RECORDING},
+	[60] = {VFE_CMD_STOP_RECORDING},
+	[63] = {VFE_CMD_CAPTURE, V40_CAPTURE_LEN, 0xFF},
+	[65] = {VFE_CMD_STOP},
+	[66] = {VFE_CMD_GET_HW_VERSION, V40_GET_HW_VERSION_LEN,
+		V40_GET_HW_VERSION_OFF},
+	[67] = {VFE_CMD_GET_FRAME_SKIP_COUNTS},
+	[68] = {VFE_CMD_OUTPUT1_BUFFER_ENQ},
+	[69] = {VFE_CMD_OUTPUT2_BUFFER_ENQ},
+	[70] = {VFE_CMD_OUTPUT3_BUFFER_ENQ},
+	[71] = {VFE_CMD_JPEG_OUT_BUF_ENQ},
+	[72] = {VFE_CMD_RAW_OUT_BUF_ENQ},
+	[73] = {VFE_CMD_RAW_IN_BUF_ENQ},
+	[74] = {VFE_CMD_STATS_AF_ENQ},
+	[75] = {VFE_CMD_STATS_AE_ENQ},
+	[76] = {VFE_CMD_STATS_AWB_ENQ},
+	[77] = {VFE_CMD_STATS_RS_ENQ},
+	[78] = {VFE_CMD_STATS_CS_ENQ},
+	[79] = {VFE_CMD_STATS_SKIN_ENQ},
+	[80] = {VFE_CMD_STATS_IHIST_ENQ},
+	[82] = {VFE_CMD_JPEG_ENC_CFG},
+	[84] = {VFE_CMD_STATS_AF_START},
+	[85] = {VFE_CMD_STATS_AF_STOP},
+	[86] = {VFE_CMD_STATS_AE_START},
+	[87] = {VFE_CMD_STATS_AE_STOP},
+	[88] = {VFE_CMD_STATS_AWB_START, V40_STATS_AWB_LEN, V40_STATS_AWB_OFF},
+	[89] = {VFE_CMD_STATS_AWB_STOP},
+	[90] = {VFE_CMD_STATS_RS_START, V40_STATS_RS_LEN, V40_STATS_RS_OFF},
+	[91] = {VFE_CMD_STATS_RS_STOP},
+	[92] = {VFE_CMD_STATS_CS_START, V40_STATS_CS_LEN, V40_STATS_CS_OFF},
+	[93] = {VFE_CMD_STATS_CS_STOP},
+	[94] = {VFE_CMD_STATS_SKIN_START},
+	[95] = {VFE_CMD_STATS_SKIN_STOP},
+	[96] = {VFE_CMD_STATS_IHIST_START,
+		V40_STATS_IHIST_LEN, V40_STATS_IHIST_OFF},
+	[97] = {VFE_CMD_STATS_IHIST_STOP},
+	[99] = {VFE_CMD_SYNC_TIMER_SETTING, V40_SYNC_TIMER_LEN,
+			V40_SYNC_TIMER_OFF},
+	[100] = {VFE_CMD_ASYNC_TIMER_SETTING, V40_ASYNC_TIMER_LEN,
+		V40_ASYNC_TIMER_OFF},
+	[101] = {VFE_CMD_LIVESHOT},
+	[102] = {VFE_CMD_LA_SETUP},
+	[103] = {VFE_CMD_LINEARIZATION_CFG, V40_LINEARIZATION_LEN1,
+			V40_LINEARIZATION_OFF1},
+	[104] = {VFE_CMD_DEMOSAICV3},
+	[105] = {VFE_CMD_DEMOSAICV3_ABCC_CFG},
+	[106] = {VFE_CMD_DEMOSAICV3_DBCC_CFG, V40_DEMOSAICV3_DBCC_LEN,
+			V40_DEMOSAICV3_DBCC_OFF},
+	[107] = {VFE_CMD_DEMOSAICV3_DBPC_CFG},
+	[108] = {VFE_CMD_DEMOSAICV3_ABF_CFG, V40_DEMOSAICV3_ABF_LEN,
+			V40_DEMOSAICV3_ABF_OFF},
+	[109] = {VFE_CMD_DEMOSAICV3_ABCC_UPDATE},
+	[110] = {VFE_CMD_DEMOSAICV3_DBCC_UPDATE, V40_DEMOSAICV3_DBCC_LEN,
+			V40_DEMOSAICV3_DBCC_OFF},
+	[111] = {VFE_CMD_DEMOSAICV3_DBPC_UPDATE},
+	[112] = {VFE_CMD_XBAR_CFG},
+	[113] = {VFE_CMD_MODULE_CFG, V40_MODULE_CFG_LEN, V40_MODULE_CFG_OFF},
+	[114] = {VFE_CMD_ZSL},
+	[115] = {VFE_CMD_LINEARIZATION_UPDATE, V40_LINEARIZATION_LEN1,
+			V40_LINEARIZATION_OFF1},
+	[116] = {VFE_CMD_DEMOSAICV3_ABF_UPDATE, V40_DEMOSAICV3_ABF_LEN,
+			V40_DEMOSAICV3_ABF_OFF},
+	[117] = {VFE_CMD_CLF_CFG, V40_CLF_CFG_LEN, V40_CLF_CFG_OFF},
+	[118] = {VFE_CMD_CLF_LUMA_UPDATE, V40_CLF_LUMA_UPDATE_LEN,
+			V40_CLF_LUMA_UPDATE_OFF},
+	[119] = {VFE_CMD_CLF_CHROMA_UPDATE, V40_CLF_CHROMA_UPDATE_LEN,
+			V40_CLF_CHROMA_UPDATE_OFF},
+	[120] = {VFE_CMD_PCA_ROLL_OFF_CFG},
+	[121] = {VFE_CMD_PCA_ROLL_OFF_UPDATE},
+	[122] = {VFE_CMD_GET_REG_DUMP},
+	[123] = {VFE_CMD_GET_LINEARIZATON_TABLE},
+	[124] = {VFE_CMD_GET_MESH_ROLLOFF_TABLE},
+	[125] = {VFE_CMD_GET_PCA_ROLLOFF_TABLE},
+	[126] = {VFE_CMD_GET_RGB_G_TABLE},
+	[127] = {VFE_CMD_GET_LA_TABLE},
+	[128] = {VFE_CMD_DEMOSAICV3_UPDATE},
+	[129] = {VFE_CMD_ACTIVE_REGION_CFG},
+	[130] = {VFE_CMD_COLOR_PROCESSING_CONFIG},
+	[131] = {VFE_CMD_STATS_WB_AEC_CONFIG},
+	[132] = {VFE_CMD_STATS_WB_AEC_UPDATE},
+	[133] = {VFE_CMD_Y_GAMMA_CONFIG},
+	[134] = {VFE_CMD_SCALE_OUTPUT1_CONFIG},
+	[135] = {VFE_CMD_SCALE_OUTPUT2_CONFIG},
+	[136] = {VFE_CMD_CAPTURE_RAW},
+	[137] = {VFE_CMD_STOP_LIVESHOT},
+	[138] = {VFE_CMD_RECONFIG_VFE},
+	[139] = {VFE_CMD_STATS_REQBUF},
+	[140] = {VFE_CMD_STATS_ENQUEUEBUF},
+	[141] = {VFE_CMD_STATS_FLUSH_BUFQ},
+	[142] = {VFE_CMD_STATS_UNREGBUF},
+	[143] = {VFE_CMD_STATS_BG_START, V40_STATS_BG_LEN, V40_STATS_BG_OFF},
+	[144] = {VFE_CMD_STATS_BG_STOP},
+	[145] = {VFE_CMD_STATS_BF_START, V40_STATS_BF_LEN, V40_STATS_BF_OFF},
+	[146] = {VFE_CMD_STATS_BF_STOP},
+	[147] = {VFE_CMD_STATS_BHIST_START, V40_STATS_BHIST_LEN,
+			V40_STATS_BHIST_OFF},
+	[148] = {VFE_CMD_STATS_BHIST_STOP},
+	[149] = {VFE_CMD_RESET_2},
+	[150] = {VFE_CMD_FOV_ENC_CFG, V40_FOV_ENC_LEN,
+		V40_FOV_ENC_OFF, 0xFF},
+	[151] = {VFE_CMD_FOV_VIEW_CFG, V40_FOV_VIEW_LEN,
+		V40_FOV_VIEW_OFF, 0xFF},
+	[152] = {VFE_CMD_FOV_ENC_UPDATE, V40_FOV_ENC_LEN,
+		V40_FOV_ENC_OFF, 0xFF},
+	[153] = {VFE_CMD_FOV_VIEW_UPDATE, V40_FOV_VIEW_LEN,
+		V40_FOV_VIEW_OFF, 0xFF},
+	[154] = {VFE_CMD_SCALER_ENC_CFG, V40_SCALER_ENC_LEN,
+		V40_SCALER_ENC_OFF, 0xFF},
+	[155] = {VFE_CMD_SCALER_VIEW_CFG, V40_SCALER_VIEW_LEN,
+		V40_SCALER_VIEW_OFF, 0xFF},
+	[156] = {VFE_CMD_SCALER_ENC_UPDATE, V40_SCALER_ENC_LEN,
+		V40_SCALER_ENC_OFF, 0xFF},
+	[157] = {VFE_CMD_SCALER_VIEW_UPDATE, V40_SCALER_VIEW_LEN,
+		V40_SCALER_VIEW_OFF, 0xFF},
+	[158] = {VFE_CMD_COLORXFORM_ENC_CFG, V40_COLORXFORM_ENC_CFG_LEN,
+		V40_COLORXFORM_ENC_CFG_OFF, 0xFF},
+	[159] = {VFE_CMD_COLORXFORM_VIEW_CFG, V40_COLORXFORM_VIEW_CFG_LEN,
+		V40_COLORXFORM_VIEW_CFG_OFF},
+	[160] = {VFE_CMD_COLORXFORM_ENC_UPDATE, V40_COLORXFORM_ENC_CFG_LEN,
+		V40_COLORXFORM_ENC_CFG_OFF, 0xFF},
+	[161] = {VFE_CMD_COLORXFORM_VIEW_UPDATE, V40_COLORXFORM_VIEW_CFG_LEN,
+		V40_COLORXFORM_VIEW_CFG_OFF, 0xFF},
+	[163] = {VFE_CMD_STATS_BE_START, V40_STATS_BE_LEN, V40_STATS_BE_OFF},
+	[164] = {VFE_CMD_STATS_BE_STOP},
+};
+
+static const uint32_t vfe40_AXI_WM_CFG[] = {
+	0x0000006C,
+	0x00000090,
+	0x000000B4,
+	0x000000D8,
+	0x000000FC,
+	0x00000120,
+	0x00000144,
+};
+
+static const char * const vfe40_general_cmd[] = {
+	[1] = "SET_CLK",
+	[2] = "RESET",
+	[3] = "START",
+	[4] = "TEST_GEN_START",
+	[5] = "OPERATION_CFG",  /* 5 */
+	[6] = "AXI_OUT_CFG",
+	[7] = "CAMIF_CFG",
+	[8] = "AXI_INPUT_CFG",
+	[9] = "BLACK_LEVEL_CFG",
+	[10] = "ROLL_OFF_CFG",  /* 10 */
+	[11] = "DEMUX_CFG",
+	[12] = "FOV_CFG",
+	[13] = "MAIN_SCALER_CFG",
+	[14] = "WB_CFG",
+	[15] = "COLOR_COR_CFG", /* 15 */
+	[16] = "RGB_G_CFG",
+	[17] = "LA_CFG",
+	[18] = "CHROMA_EN_CFG",
+	[19] = "CHROMA_SUP_CFG",
+	[20] = "MCE_CFG", /* 20 */
+	[21] = "SK_ENHAN_CFG",
+	[22] = "ASF_CFG",
+	[23] = "S2Y_CFG",
+	[24] = "S2CbCr_CFG",
+	[25] = "CHROMA_SUBS_CFG",  /* 25 */
+	[26] = "OUT_CLAMP_CFG",
+	[27] = "FRAME_SKIP_CFG",
+	[31] = "UPDATE",
+	[32] = "BL_LVL_UPDATE",
+	[33] = "DEMUX_UPDATE",
+	[34] = "FOV_UPDATE",
+	[35] = "MAIN_SCALER_UPDATE",  /* 35 */
+	[36] = "WB_UPDATE",
+	[37] = "COLOR_COR_UPDATE",
+	[38] = "RGB_G_UPDATE",
+	[39] = "LA_UPDATE",
+	[40] = "CHROMA_EN_UPDATE",  /* 40 */
+	[41] = "CHROMA_SUP_UPDATE",
+	[42] = "MCE_UPDATE",
+	[43] = "SK_ENHAN_UPDATE",
+	[44] = "S2CbCr_UPDATE",
+	[45] = "S2Y_UPDATE",  /* 45 */
+	[46] = "ASF_UPDATE",
+	[47] = "FRAME_SKIP_UPDATE",
+	[48] = "CAMIF_FRAME_UPDATE",
+	[49] = "STATS_AF_UPDATE",
+	[50] = "STATS_AE_UPDATE",  /* 50 */
+	[51] = "STATS_AWB_UPDATE",
+	[52] = "STATS_RS_UPDATE",
+	[53] = "STATS_CS_UPDATE",
+	[54] = "STATS_SKIN_UPDATE",
+	[55] = "STATS_IHIST_UPDATE",  /* 55 */
+	[57] = "EPOCH1_ACK",
+	[58] = "EPOCH2_ACK",
+	[59] = "START_RECORDING",
+	[60] = "STOP_RECORDING",  /* 60 */
+	[63] = "CAPTURE",
+	[65] = "STOP",  /* 65 */
+	[66] = "GET_HW_VERSION",
+	[67] = "GET_FRAME_SKIP_COUNTS",
+	[68] = "OUTPUT1_BUFFER_ENQ",
+	[69] = "OUTPUT2_BUFFER_ENQ",
+	[70] = "OUTPUT3_BUFFER_ENQ",  /* 70 */
+	[71] = "JPEG_OUT_BUF_ENQ",
+	[72] = "RAW_OUT_BUF_ENQ",
+	[73] = "RAW_IN_BUF_ENQ",
+	[74] = "STATS_AF_ENQ",
+	[75] = "STATS_AE_ENQ",  /* 75 */
+	[76] = "STATS_AWB_ENQ",
+	[77] = "STATS_RS_ENQ",
+	[78] = "STATS_CS_ENQ",
+	[79] = "STATS_SKIN_ENQ",
+	[80] = "STATS_IHIST_ENQ",  /* 80 */
+	[82] = "JPEG_ENC_CFG",
+	[84] = "STATS_AF_START",
+	[85] = "STATS_AF_STOP",  /* 85 */
+	[86] = "STATS_AE_START",
+	[87] = "STATS_AE_STOP",
+	[88] = "STATS_AWB_START",
+	[89] = "STATS_AWB_STOP",
+	[90] = "STATS_RS_START",  /* 90 */
+	[91] = "STATS_RS_STOP",
+	[92] = "STATS_CS_START",
+	[93] = "STATS_CS_STOP",
+	[94] = "STATS_SKIN_START",
+	[95] = "STATS_SKIN_STOP",  /* 95 */
+	[96] = "STATS_IHIST_START",
+	[97] = "STATS_IHIST_STOP",
+	[99] = "SYNC_TIMER_SETTING",
+	[100] = "ASYNC_TIMER_SETTING",  /* 100 */
+	[101] = "LIVESHOT",
+	[102] = "LA_SETUP",
+	[103] = "LINEARIZATION_CFG",
+	[104] = "DEMOSAICV3",
+	[105] = "DEMOSAICV3_ABCC_CFG", /* 105 */
+	[106] = "DEMOSAICV3_DBCC_CFG",
+	[107] = "DEMOSAICV3_DBPC_CFG",
+	[108] = "DEMOSAICV3_ABF_CFG",
+	[109] = "DEMOSAICV3_ABCC_UPDATE",
+	[110] = "DEMOSAICV3_DBCC_UPDATE", /* 110 */
+	[111] = "DEMOSAICV3_DBPC_UPDATE",
+	[112] = "XBAR_CFG",
+	[113] = "EZTUNE_CFG",
+	[114] = "V40_ZSL",
+	[115] = "LINEARIZATION_UPDATE", /*115*/
+	[116] = "DEMOSAICV3_ABF_UPDATE",
+	[117] = "CLF_CFG",
+	[118] = "CLF_LUMA_UPDATE",
+	[119] = "CLF_CHROMA_UPDATE",
+	[120] = "PCA_ROLL_OFF_CFG", /*120*/
+	[121] = "PCA_ROLL_OFF_UPDATE",
+	[122] = "GET_REG_DUMP",
+	[123] = "GET_LINEARIZATON_TABLE",
+	[124] = "GET_MESH_ROLLOFF_TABLE",
+	[125] = "GET_PCA_ROLLOFF_TABLE", /*125*/
+	[126] = "GET_RGB_G_TABLE",
+	[127] = "GET_LA_TABLE",
+	[128] = "DEMOSAICV3_UPDATE",
+	[139] = "STATS_REQBUF",
+	[140] = "STATS_ENQUEUEBUF", /*140*/
+	[141] = "STATS_FLUSH_BUFQ",
+	[142] = "STATS_UNREGBUF",
+	[143] = "STATS_BG_START",
+	[144] = "STATS_BG_STOP",
+	[145] = "STATS_BF_START", /*145*/
+	[146] = "STATS_BF_STOP",
+	[147] = "STATS_BHIST_START",
+	[148] = "STATS_BHIST_STOP",
+	[149] = "RESET_2",
+};
+
+/*Temporary use fixed bus vectors in VFE */
+static struct msm_bus_vectors vfe_init_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+};
+
+static struct msm_bus_vectors vfe_preview_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 27648000,
+		.ib  = 110592000,
+	},
+};
+
+static struct msm_bus_vectors vfe_video_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 274406400,
+		.ib  = 617103360,
+	},
+};
+
+static struct msm_bus_vectors vfe_liveshot_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 348192000,
+		.ib  = 617103360,
+	},
+};
+
+static struct msm_bus_vectors vfe_snapshot_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 274423680,
+		.ib  = 1097694720,
+	},
+};
+
+static struct msm_bus_vectors vfe_zsl_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 302071680,
+		.ib  = 1208286720,
+	},
+};
+
+static struct msm_bus_paths vfe_bus_client_config[] = {
+	{
+		ARRAY_SIZE(vfe_init_vectors),
+		vfe_init_vectors,
+	},
+	{
+		ARRAY_SIZE(vfe_preview_vectors),
+		vfe_preview_vectors,
+	},
+	{
+		ARRAY_SIZE(vfe_video_vectors),
+		vfe_video_vectors,
+	},
+	{
+		ARRAY_SIZE(vfe_snapshot_vectors),
+		vfe_snapshot_vectors,
+	},
+	{
+		ARRAY_SIZE(vfe_zsl_vectors),
+		vfe_zsl_vectors,
+	},
+	{
+		ARRAY_SIZE(vfe_liveshot_vectors),
+		vfe_liveshot_vectors,
+	},
+};
+
+static struct msm_bus_scale_pdata vfe_bus_client_pdata = {
+		vfe_bus_client_config,
+		ARRAY_SIZE(vfe_bus_client_config),
+		.name = "msm_camera_vfe",
+};
+
+uint8_t vfe40_use_bayer_stats(struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	if (vfe40_ctrl->ver_num.main >= 4) {
+		/* VFE 4 or above uses bayer stats */
+		return TRUE;
+	} else {
+		return FALSE;
+	}
+}
+
+static void axi_enable_irq(struct vfe_share_ctrl_t *share_ctrl)
+{
+	uint32_t irq_mask;
+	uint16_t vfe_operation_mode =
+		share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
+			VFE_OUTPUTS_RDI1);
+	irq_mask =
+		msm_camera_io_r(share_ctrl->vfebase +
+			VFE_IRQ_MASK_0);
+
+	irq_mask |= VFE_IMASK_WHILE_STOPPING_0;
+
+	if (share_ctrl->current_mode & VFE_OUTPUTS_RDI0)
+		irq_mask |= VFE_IRQ_STATUS0_RDI0_REG_UPDATE_MASK;
+
+	if (share_ctrl->current_mode & VFE_OUTPUTS_RDI1)
+		irq_mask |= VFE_IRQ_STATUS0_RDI1_REG_UPDATE_MASK;
+
+	msm_camera_io_w(irq_mask, share_ctrl->vfebase +
+		VFE_IRQ_MASK_0);
+
+	if (vfe_operation_mode) {
+		irq_mask =
+		msm_camera_io_r(share_ctrl->vfebase +
+			VFE_IRQ_MASK_0);
+		irq_mask |= 0x00000021;
+		if (share_ctrl->stats_comp)
+			irq_mask |= VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK_0;
+		else
+			irq_mask |= 0x00FF0000;
+		msm_camera_io_w(irq_mask, share_ctrl->vfebase +
+			VFE_IRQ_MASK_0);
+		atomic_set(&share_ctrl->vstate, 1);
+	}
+	atomic_set(&share_ctrl->handle_common_irq, 1);
+}
+
+static void axi_disable_irq(struct vfe_share_ctrl_t *share_ctrl)
+{
+
+	/* disable all interrupts.  */
+
+	uint32_t irq_mask = 0;
+	uint16_t vfe_operation_mode =
+		share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
+			VFE_OUTPUTS_RDI1);
+
+	if (share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
+		irq_mask =
+		msm_camera_io_r(share_ctrl->vfebase +
+			VFE_IRQ_MASK_0);
+		irq_mask &= ~(VFE_IRQ_STATUS0_RDI0_REG_UPDATE_MASK);
+		msm_camera_io_w(irq_mask, share_ctrl->vfebase +
+			VFE_IRQ_MASK_0);
+		msm_camera_io_w(VFE_IRQ_STATUS0_RDI0_REG_UPDATE_MASK,
+			share_ctrl->vfebase + VFE_IRQ_CLEAR_0);
+	}
+	if (share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
+		irq_mask =
+		msm_camera_io_r(share_ctrl->vfebase +
+			VFE_IRQ_MASK_0);
+		irq_mask &= ~(VFE_IRQ_STATUS0_RDI1_REG_UPDATE_MASK);
+		msm_camera_io_w(irq_mask, share_ctrl->vfebase +
+			VFE_IRQ_MASK_0);
+		msm_camera_io_w(VFE_IRQ_STATUS0_RDI1_REG_UPDATE_MASK,
+			share_ctrl->vfebase + VFE_IRQ_CLEAR_0);
+	}
+	if (vfe_operation_mode) {
+		atomic_set(&share_ctrl->vstate, 0);
+		irq_mask =
+		msm_camera_io_r(share_ctrl->vfebase +
+			VFE_IRQ_MASK_0);
+		irq_mask &= ~(0x00000011);
+		if (share_ctrl->stats_comp)
+			irq_mask &= ~(VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK_0);
+		else
+			irq_mask &= ~0x00FF0000;
+		msm_camera_io_w(irq_mask, share_ctrl->vfebase +
+			VFE_IRQ_MASK_0);
+	}
+
+}
+
+static void vfe40_stop(struct vfe40_ctrl_type *vfe40_ctrl)
+{
+
+	/* in either continuous or snapshot mode, stop command can be issued
+	 * at any time. stop camif immediately. */
+	msm_camera_io_w(CAMIF_COMMAND_STOP_IMMEDIATELY,
+		vfe40_ctrl->share_ctrl->vfebase + VFE_CAMIF_COMMAND);
+	vfe40_ctrl->share_ctrl->operation_mode &=
+		~(vfe40_ctrl->share_ctrl->current_mode);
+	vfe40_ctrl->share_ctrl->current_mode = 0;
+}
+
+static void vfe40_subdev_notify(int id, int path, uint32_t inst_handle,
+	struct v4l2_subdev *sd, struct vfe_share_ctrl_t *share_ctrl)
+{
+	struct msm_vfe_resp rp;
+	struct msm_frame_info frame_info;
+	unsigned long flags = 0;
+	spin_lock_irqsave(&share_ctrl->sd_notify_lock, flags);
+	CDBG("vfe40_subdev_notify : msgId = %d\n", id);
+	memset(&rp, 0, sizeof(struct msm_vfe_resp));
+	rp.evt_msg.type   = MSM_CAMERA_MSG;
+	frame_info.inst_handle = inst_handle;
+	frame_info.path = path;
+	rp.evt_msg.data = &frame_info;
+	rp.type	   = id;
+	v4l2_subdev_notify(sd, NOTIFY_VFE_BUF_EVT, &rp);
+	spin_unlock_irqrestore(&share_ctrl->sd_notify_lock, flags);
+}
+
+static int vfe40_config_axi(
+	struct axi_ctrl_t *axi_ctrl, int mode, uint32_t *ao)
+{
+	uint32_t *ch_info;
+	uint32_t *axi_cfg = ao;
+	int vfe_mode = (mode & ~(OUTPUT_TERT1|OUTPUT_TERT2));
+
+	/* Update the corresponding write masters for each output*/
+	ch_info = axi_cfg + V40_AXI_CFG_LEN;
+	axi_ctrl->share_ctrl->outpath.out0.ch0 = 0x0000FFFF & *ch_info;
+	axi_ctrl->share_ctrl->outpath.out0.ch1 =
+		0x0000FFFF & (*ch_info++ >> 16);
+	axi_ctrl->share_ctrl->outpath.out0.ch2 = 0x0000FFFF & *ch_info++;
+	axi_ctrl->share_ctrl->outpath.out0.inst_handle = *ch_info++;
+
+	axi_ctrl->share_ctrl->outpath.out1.ch0 = 0x0000FFFF & *ch_info;
+	axi_ctrl->share_ctrl->outpath.out1.ch1 =
+		0x0000FFFF & (*ch_info++ >> 16);
+	axi_ctrl->share_ctrl->outpath.out1.ch2 = 0x0000FFFF & *ch_info++;
+	axi_ctrl->share_ctrl->outpath.out1.inst_handle = *ch_info++;
+
+	axi_ctrl->share_ctrl->outpath.out2.ch0 = 0x0000FFFF & *ch_info;
+	axi_ctrl->share_ctrl->outpath.out2.ch1 =
+		0x0000FFFF & (*ch_info++ >> 16);
+	axi_ctrl->share_ctrl->outpath.out2.ch2 = 0x0000FFFF & *ch_info++;
+	axi_ctrl->share_ctrl->outpath.out2.inst_handle = *ch_info++;
+
+	axi_ctrl->share_ctrl->outpath.out3.ch0 = 0x0000FFFF & *ch_info;
+	axi_ctrl->share_ctrl->outpath.out3.ch1 =
+		0x0000FFFF & (*ch_info++ >> 16);
+	axi_ctrl->share_ctrl->outpath.out3.ch2 = 0x0000FFFF & *ch_info++;
+	axi_ctrl->share_ctrl->outpath.out3.inst_handle = *ch_info++;
+
+	axi_ctrl->share_ctrl->outpath.output_mode = 0;
+
+	if (mode & OUTPUT_TERT1)
+		axi_ctrl->share_ctrl->outpath.output_mode |=
+			VFE40_OUTPUT_MODE_TERTIARY1;
+	if (mode & OUTPUT_TERT2)
+		axi_ctrl->share_ctrl->outpath.output_mode |=
+			VFE40_OUTPUT_MODE_TERTIARY2;
+	if (mode == OUTPUT_TERT1 || mode == OUTPUT_TERT1
+		|| mode == (OUTPUT_TERT1|OUTPUT_TERT2))
+			goto bus_cfg;
+
+	switch (vfe_mode) {
+	case OUTPUT_PRIM:
+		axi_ctrl->share_ctrl->outpath.output_mode |=
+			VFE40_OUTPUT_MODE_PRIMARY;
+		break;
+	case OUTPUT_PRIM_ALL_CHNLS:
+		axi_ctrl->share_ctrl->outpath.output_mode |=
+			VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
+		break;
+	case OUTPUT_PRIM|OUTPUT_SEC:
+		axi_ctrl->share_ctrl->outpath.output_mode |=
+			VFE40_OUTPUT_MODE_PRIMARY;
+		axi_ctrl->share_ctrl->outpath.output_mode |=
+			VFE40_OUTPUT_MODE_SECONDARY;
+		break;
+	case OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS:
+		axi_ctrl->share_ctrl->outpath.output_mode |=
+			VFE40_OUTPUT_MODE_PRIMARY;
+		axi_ctrl->share_ctrl->outpath.output_mode |=
+			VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS;
+		break;
+	case OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC:
+		axi_ctrl->share_ctrl->outpath.output_mode |=
+			VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
+		axi_ctrl->share_ctrl->outpath.output_mode |=
+			VFE40_OUTPUT_MODE_SECONDARY;
+		break;
+	default:
+		pr_err("%s Invalid AXI mode %d ", __func__, mode);
+		return -EINVAL;
+	}
+
+bus_cfg:
+	msm_camera_io_memcpy(axi_ctrl->share_ctrl->vfebase +
+		vfe40_cmd[VFE_CMD_AXI_OUT_CFG].offset, axi_cfg,
+		V40_AXI_BUS_CFG_LEN);
+	msm_camera_io_w(*ch_info++,
+		axi_ctrl->share_ctrl->vfebase + VFE_RDI0_CFG);
+	msm_camera_io_w(*ch_info++,
+		axi_ctrl->share_ctrl->vfebase + VFE_RDI1_CFG);
+	msm_camera_io_w(*ch_info++,
+		axi_ctrl->share_ctrl->vfebase + VFE_RDI2_CFG);
+	return 0;
+}
+
+static void axi_reset_internal_variables(
+	struct axi_ctrl_t *axi_ctrl)
+{
+	unsigned long flags;
+	/* state control variables */
+	axi_ctrl->share_ctrl->start_ack_pending = FALSE;
+	atomic_set(&irq_cnt, 0);
+
+	spin_lock_irqsave(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
+	axi_ctrl->share_ctrl->stop_ack_pending  = FALSE;
+	spin_unlock_irqrestore(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
+
+	spin_lock_irqsave(&axi_ctrl->share_ctrl->update_ack_lock, flags);
+	axi_ctrl->share_ctrl->update_ack_pending = FALSE;
+	spin_unlock_irqrestore(&axi_ctrl->share_ctrl->update_ack_lock, flags);
+
+	axi_ctrl->share_ctrl->recording_state = VFE_STATE_IDLE;
+	axi_ctrl->share_ctrl->liveshot_state = VFE_STATE_IDLE;
+
+	atomic_set(&axi_ctrl->share_ctrl->vstate, 0);
+	atomic_set(&axi_ctrl->share_ctrl->handle_common_irq, 0);
+	atomic_set(&axi_ctrl->share_ctrl->pix0_update_ack_pending, 0);
+	atomic_set(&axi_ctrl->share_ctrl->rdi0_update_ack_pending, 0);
+	atomic_set(&axi_ctrl->share_ctrl->rdi1_update_ack_pending, 0);
+	atomic_set(&axi_ctrl->share_ctrl->rdi2_update_ack_pending, 0);
+
+	/* 0 for continuous mode, 1 for snapshot mode */
+	axi_ctrl->share_ctrl->operation_mode = 0;
+	axi_ctrl->share_ctrl->current_mode = 0;
+	axi_ctrl->share_ctrl->outpath.output_mode = 0;
+	axi_ctrl->share_ctrl->comp_output_mode = 0;
+	axi_ctrl->share_ctrl->vfe_capture_count = 0;
+
+	/* this is unsigned 32 bit integer. */
+	axi_ctrl->share_ctrl->vfeFrameId = 0;
+	axi_ctrl->share_ctrl->rdi0FrameId = 0;
+	axi_ctrl->share_ctrl->rdi1FrameId = 0;
+	axi_ctrl->share_ctrl->rdi2FrameId = 0;
+}
+
+static void vfe40_program_dmi_cfg(
+	enum VFE40_DMI_RAM_SEL bankSel,
+	struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	/* set bit 8 for auto increment. */
+	uint32_t value = VFE_DMI_CFG_DEFAULT;
+	value += (uint32_t)bankSel;
+	CDBG("%s: banksel = %d\n", __func__, bankSel);
+
+	msm_camera_io_w(value, vfe40_ctrl->share_ctrl->vfebase +
+		VFE_DMI_CFG);
+	/* by default, always starts with offset 0.*/
+	msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase +
+		VFE_DMI_ADDR);
+}
+
+static void vfe40_reset_dmi_tables(
+	struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	int i = 0;
+
+	/* Reset Histogram LUTs */
+	CDBG("Reset Bayer histogram LUT : 0\n");
+	vfe40_program_dmi_cfg(STATS_BHIST_RAM0, vfe40_ctrl);
+	/* Loop for configuring LUT */
+	for (i = 0; i < 256; i++) {
+		msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase +
+			VFE_DMI_DATA_HI);
+		msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase +
+			VFE_DMI_DATA_LO);
+	}
+	vfe40_program_dmi_cfg(NO_MEM_SELECTED, vfe40_ctrl);
+
+	CDBG("Reset Bayer Histogram LUT: 1\n");
+	vfe40_program_dmi_cfg(STATS_BHIST_RAM1, vfe40_ctrl);
+	/* Loop for configuring LUT */
+	for (i = 0; i < 256; i++) {
+		msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase +
+			VFE_DMI_DATA_HI);
+		msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase +
+			VFE_DMI_DATA_LO);
+	}
+	vfe40_program_dmi_cfg(NO_MEM_SELECTED, vfe40_ctrl);
+
+	CDBG("Reset IHistogram LUT\n");
+	vfe40_program_dmi_cfg(STATS_IHIST_RAM, vfe40_ctrl);
+	/* Loop for configuring LUT */
+	for (i = 0; i < 256; i++) {
+		msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase +
+			VFE_DMI_DATA_HI);
+		msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase +
+			VFE_DMI_DATA_LO);
+	}
+	vfe40_program_dmi_cfg(NO_MEM_SELECTED, vfe40_ctrl);
+}
+
+static void vfe40_set_default_reg_values(
+	struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	msm_camera_io_w(0x800080,
+		vfe40_ctrl->share_ctrl->vfebase + VFE_DEMUX_GAIN_0);
+	msm_camera_io_w(0x800080,
+		vfe40_ctrl->share_ctrl->vfebase + VFE_DEMUX_GAIN_1);
+	msm_camera_io_w(0x198FFFFF,
+		vfe40_ctrl->share_ctrl->vfebase + VFE_CGC_OVERRIDE);
+
+	msm_camera_io_w(0,
+		vfe40_ctrl->share_ctrl->vfebase + VFE_CLAMP_ENC_MIN);
+	msm_camera_io_w(0xFFFFFF,
+		vfe40_ctrl->share_ctrl->vfebase + VFE_CLAMP_ENC_MAX);
+	msm_camera_io_w(0,
+		vfe40_ctrl->share_ctrl->vfebase + VFE_CLAMP_VIEW_MIN);
+	msm_camera_io_w(0xFFFFFF,
+		vfe40_ctrl->share_ctrl->vfebase + VFE_CLAMP_VIEW_MAX);
+
+	/* stats UB config */
+	CDBG("%s: Use bayer stats = %d\n", __func__,
+		 vfe40_use_bayer_stats(vfe40_ctrl));
+
+	msm_camera_io_w(0x82F80007,
+		vfe40_ctrl->share_ctrl->vfebase +
+			VFE_BUS_STATS_RS_WR_UB_CFG);
+	msm_camera_io_w(0x8300000F,
+		vfe40_ctrl->share_ctrl->vfebase +
+			VFE_BUS_STATS_CS_WR_UB_CFG);
+
+	msm_camera_io_w(0x8310003F,
+		vfe40_ctrl->share_ctrl->vfebase +
+			VFE_BUS_STATS_BG_WR_UB_CFG);
+	msm_camera_io_w(0x8350003F,
+		vfe40_ctrl->share_ctrl->vfebase +
+			VFE_BUS_STATS_BE_WR_UB_CFG);
+	msm_camera_io_w(0x8390003F,
+		vfe40_ctrl->share_ctrl->vfebase +
+			VFE_BUS_STATS_BF_WR_UB_CFG);
+
+	msm_camera_io_w(0x83D0000F,
+	vfe40_ctrl->share_ctrl->vfebase +
+			VFE_BUS_STATS_HIST_WR_UB_CFG);
+	msm_camera_io_w(0x83E0000F,
+		vfe40_ctrl->share_ctrl->vfebase +
+			VFE_BUS_STATS_SKIN_WR_UB_CFG);
+
+	msm_camera_io_w(0x83F0000F,
+		vfe40_ctrl->share_ctrl->vfebase +
+			VFE_BUS_STATS_AWB_WR_UB_CFG);
+
+	/* stats frame subsample config*/
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe40_ctrl->share_ctrl->vfebase +
+			VFE_BUS_STATS_HIST_WR_FRAMEDROP_PATTERN);
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe40_ctrl->share_ctrl->vfebase +
+			VFE_BUS_STATS_BG_WR_FRAMEDROP_PATTERN);
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe40_ctrl->share_ctrl->vfebase +
+			VFE_BUS_STATS_BE_WR_FRAMEDROP_PATTERN);
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe40_ctrl->share_ctrl->vfebase +
+			VFE_BUS_STATS_BF_WR_FRAMEDROP_PATTERN);
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe40_ctrl->share_ctrl->vfebase +
+			VFE_BUS_STATS_RS_WR_FRAMEDROP_PATTERN);
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe40_ctrl->share_ctrl->vfebase +
+			VFE_BUS_STATS_CS_WR_FRAMEDROP_PATTERN);
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe40_ctrl->share_ctrl->vfebase +
+			VFE_BUS_STATS_SKIN_WR_FRAMEDROP_PATTERN);
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe40_ctrl->share_ctrl->vfebase +
+			VFE_BUS_STATS_AWB_WR_FRAMEDROP_PATTERN);
+
+	/* stats irq subsample config*/
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe40_ctrl->share_ctrl->vfebase +
+			VFE_BUS_STATS_HIST_WR_IRQ_SUBSAMPLE_PATTERN);
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe40_ctrl->share_ctrl->vfebase +
+			VFE_BUS_STATS_BG_WR_IRQ_SUBSAMPLE_PATTERN);
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe40_ctrl->share_ctrl->vfebase +
+			VFE_BUS_STATS_BE_WR_IRQ_SUBSAMPLE_PATTERN);
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe40_ctrl->share_ctrl->vfebase +
+			VFE_BUS_STATS_BF_WR_IRQ_SUBSAMPLE_PATTERN);
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe40_ctrl->share_ctrl->vfebase +
+			VFE_BUS_STATS_RS_WR_IRQ_SUBSAMPLE_PATTERN);
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe40_ctrl->share_ctrl->vfebase +
+			VFE_BUS_STATS_CS_WR_IRQ_SUBSAMPLE_PATTERN);
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe40_ctrl->share_ctrl->vfebase +
+			VFE_BUS_STATS_SKIN_WR_IRQ_SUBSAMPLE_PATTERN);
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe40_ctrl->share_ctrl->vfebase +
+			VFE_BUS_STATS_AWB_WR_IRQ_SUBSAMPLE_PATTERN);
+
+	vfe40_reset_dmi_tables(vfe40_ctrl);
+}
+
+static void vfe40_reset_internal_variables(
+	struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	/* Stats control variables. */
+	memset(&(vfe40_ctrl->bfStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe40_ctrl->awbStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe40_ctrl->bgStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe40_ctrl->beStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe40_ctrl->bhistStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe40_ctrl->ihistStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe40_ctrl->rsStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	memset(&(vfe40_ctrl->csStatsControl), 0,
+		sizeof(struct vfe_stats_control));
+
+	vfe40_ctrl->frame_skip_cnt = 31;
+	vfe40_ctrl->frame_skip_pattern = 0xffffffff;
+	vfe40_ctrl->snapshot_frame_cnt = 0;
+	vfe40_set_default_reg_values(vfe40_ctrl);
+}
+
+static int vfe40_reset(struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	uint32_t irq_mask;
+	atomic_set(&vfe40_ctrl->share_ctrl->vstate, 0);
+	msm_camera_io_w(VFE_MODULE_RESET_CMD,
+		vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_RESET);
+	msm_camera_io_w(0,
+		vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_RESET);
+
+	irq_mask =
+		msm_camera_io_r(vfe40_ctrl->share_ctrl->vfebase +
+			VFE_IRQ_MASK_0);
+	irq_mask &= ~(0x00FF0011|VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK_0);
+
+	/* enable reset_ack interrupt.  */
+	irq_mask |= VFE_IMASK_WHILE_STOPPING_0;
+	msm_camera_io_w(irq_mask, vfe40_ctrl->share_ctrl->vfebase +
+		VFE_IRQ_MASK_0);
+
+	msm_camera_io_w_mb(VFE_ONLY_RESET_CMD,
+		vfe40_ctrl->share_ctrl->vfebase + VFE_GLOBAL_RESET);
+
+	return wait_for_completion_interruptible(
+			&vfe40_ctrl->share_ctrl->reset_complete);
+}
+
+static int axi_reset(struct axi_ctrl_t *axi_ctrl)
+{
+	axi_reset_internal_variables(axi_ctrl);
+	/* disable all interrupts.  vfeImaskLocal is also reset to 0
+	* to begin with. */
+	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
+		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_0);
+
+	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
+		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+	/* clear all pending interrupts*/
+	msm_camera_io_w(VFE_CLEAR_ALL_IRQ0,
+		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_0);
+	msm_camera_io_w(VFE_CLEAR_ALL_IRQ1,
+		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_1);
+
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_camera_io_w_mb(1, axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CMD);
+
+	/* enable reset_ack interrupt.  */
+	msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_0,
+		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_0);
+
+	/* Write to VFE_GLOBAL_RESET_CMD to reset the vfe hardware. Once reset
+	 * is done, hardware interrupt will be generated.  VFE ist processes
+	 * the interrupt to complete the function call.  Note that the reset
+	 * function is synchronous. */
+
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_camera_io_w_mb(VFE_RESET_UPON_RESET_CMD,
+		axi_ctrl->share_ctrl->vfebase + VFE_GLOBAL_RESET);
+
+	return wait_for_completion_interruptible(
+			&axi_ctrl->share_ctrl->reset_complete);
+}
+
+static int vfe40_operation_config(uint32_t *cmd,
+			struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	uint32_t *p = cmd;
+
+	vfe40_ctrl->share_ctrl->stats_comp = *(++p);
+	vfe40_ctrl->hfr_mode = *(++p);
+
+	msm_camera_io_w(*(++p),
+		vfe40_ctrl->share_ctrl->vfebase + VFE_CFG);
+	msm_camera_io_w(*(++p),
+		vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+	msm_camera_io_w(*(++p),
+		vfe40_ctrl->share_ctrl->vfebase + VFE_REALIGN_BUF);
+	msm_camera_io_w(*(++p),
+		vfe40_ctrl->share_ctrl->vfebase + VFE_CHROMA_UP);
+	msm_camera_io_w(*(++p),
+		vfe40_ctrl->share_ctrl->vfebase + VFE_STATS_CFG);
+	return 0;
+}
+
+static unsigned long vfe40_stats_dqbuf(struct vfe40_ctrl_type *vfe40_ctrl,
+	enum msm_stats_enum_type stats_type)
+{
+	struct msm_stats_meta_buf *buf = NULL;
+	int rc = 0;
+	rc = vfe40_ctrl->stats_ops.dqbuf(
+			vfe40_ctrl->stats_ops.stats_ctrl, stats_type, &buf);
+	if (rc < 0) {
+		pr_err("%s: dq stats buf (type = %d) err = %d\n",
+			__func__, stats_type, rc);
+		return 0L;
+	}
+	return buf->paddr;
+}
+
+static unsigned long vfe40_stats_flush_enqueue(
+	struct vfe40_ctrl_type *vfe40_ctrl,
+	enum msm_stats_enum_type stats_type)
+{
+	struct msm_stats_bufq *bufq = NULL;
+	struct msm_stats_meta_buf *stats_buf = NULL;
+	int rc = 0;
+	int i;
+
+	/*
+	 * Passing NULL for ion client as the buffers are already
+	 * mapped at this stage, client is not required, flush all
+	 * the buffers, and buffers move to PREPARE state
+	 */
+
+	rc = vfe40_ctrl->stats_ops.bufq_flush(
+			vfe40_ctrl->stats_ops.stats_ctrl, stats_type, NULL);
+	if (rc < 0) {
+		pr_err("%s: dq stats buf (type = %d) err = %d",
+			__func__, stats_type, rc);
+		return 0L;
+	}
+	/* Queue all the buffers back to QUEUED state */
+	bufq = vfe40_ctrl->stats_ctrl.bufq[stats_type];
+	for (i = 0; i < bufq->num_bufs; i++) {
+		stats_buf = &bufq->bufs[i];
+		rc = vfe40_ctrl->stats_ops.enqueue_buf(
+				vfe40_ctrl->stats_ops.stats_ctrl,
+				&(stats_buf->info), NULL, -1);
+		if (rc < 0) {
+			pr_err("%s: dq stats buf (type = %d) err = %d",
+				 __func__, stats_type, rc);
+			return rc;
+		}
+	}
+	return 0L;
+}
+
+
+static unsigned long vfe40_stats_unregbuf(
+	struct vfe40_ctrl_type *vfe40_ctrl,
+	struct msm_stats_reqbuf *req_buf, int domain_num)
+{
+	int i = 0, rc = 0;
+
+	for (i = 0; i < req_buf->num_buf; i++) {
+		rc = vfe40_ctrl->stats_ops.buf_unprepare(
+			vfe40_ctrl->stats_ops.stats_ctrl,
+			req_buf->stats_type, i,
+			vfe40_ctrl->stats_ops.client, domain_num);
+		if (rc < 0) {
+			pr_err("%s: unreg stats buf (type = %d) err = %d",
+				__func__, req_buf->stats_type, rc);
+		return rc;
+		}
+	}
+	return 0L;
+}
+static int vfe_stats_awb_buf_init(
+	struct vfe40_ctrl_type *vfe40_ctrl,
+	struct vfe_cmd_stats_buf *in)
+{
+	uint32_t addr;
+	unsigned long flags;
+	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_AWB);
+	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq awb ping buf from free buf queue\n", __func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe40_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_AWB_WR_PING_ADDR);
+	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_AWB);
+	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq awb ping buf from free buf queue\n",
+			__func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe40_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_AWB_WR_PONG_ADDR);
+	return 0;
+}
+
+static uint32_t vfe_stats_be_buf_init(
+	struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	uint32_t addr;
+	unsigned long flags;
+	uint32_t stats_type;
+
+	stats_type = MSM_STATS_TYPE_BE;
+	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, stats_type);
+	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq BE ping buf from free buf queue\n",
+			__func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe40_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_BE_WR_PING_ADDR);
+	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, stats_type);
+	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq BE pong buf from free buf queue\n",
+			__func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe40_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_BE_WR_PONG_ADDR);
+	return 0;
+}
+
+static uint32_t vfe_stats_bg_buf_init(
+	struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	uint32_t addr;
+	unsigned long flags;
+	uint32_t stats_type;
+
+	stats_type = MSM_STATS_TYPE_BG;
+	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, stats_type);
+	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq aec/Bg ping buf from free buf queue\n",
+			__func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe40_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_BG_WR_PING_ADDR);
+	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, stats_type);
+	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq aec/Bg pong buf from free buf queue\n",
+			__func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe40_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_BG_WR_PONG_ADDR);
+	return 0;
+}
+
+static int vfe_stats_bf_buf_init(
+	struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	uint32_t addr;
+	unsigned long flags;
+	int rc = 0;
+
+	uint32_t stats_type;
+	stats_type = MSM_STATS_TYPE_BF;
+
+	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+	rc = vfe40_stats_flush_enqueue(vfe40_ctrl, stats_type);
+	if (rc < 0) {
+		pr_err("%s: dq stats buf err = %d",
+			   __func__, rc);
+		spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+		return -EINVAL;
+	}
+	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, stats_type);
+	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq af ping buf from free buf queue", __func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe40_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_BF_WR_PING_ADDR);
+	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, stats_type);
+	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq af pong buf from free buf queue", __func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe40_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_BF_WR_PONG_ADDR);
+	return 0;
+}
+
+static uint32_t vfe_stats_bhist_buf_init(
+	struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	uint32_t addr;
+	unsigned long flags;
+	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_BHIST);
+	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq ihist ping buf from free buf queue",
+			__func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe40_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_SKIN_WR_PING_ADDR);
+	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_BHIST);
+	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq ihist pong buf from free buf queue",
+			__func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe40_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_SKIN_WR_PONG_ADDR);
+
+	return 0;
+}
+
+static int vfe_stats_ihist_buf_init(
+	struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	uint32_t addr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_IHIST);
+	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq ihist ping buf from free buf queue",
+			__func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe40_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_HIST_WR_PING_ADDR);
+	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_IHIST);
+	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq Ihist pong buf from free buf queue",
+			__func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe40_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_HIST_WR_PONG_ADDR);
+
+	return 0;
+}
+
+static int vfe_stats_rs_buf_init(
+	struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	uint32_t addr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_RS);
+	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq rs ping buf from free buf queue", __func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe40_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_RS_WR_PING_ADDR);
+	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_RS);
+	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq rs pong buf from free buf queue", __func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe40_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_RS_WR_PONG_ADDR);
+	return 0;
+}
+
+static int vfe_stats_cs_buf_init(
+	struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	uint32_t addr;
+	unsigned long flags;
+	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_CS);
+	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq cs ping buf from free buf queue", __func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe40_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_CS_WR_PING_ADDR);
+	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_CS);
+	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+	if (!addr) {
+		pr_err("%s: dq cs pong buf from free buf queue", __func__);
+		return -ENOMEM;
+	}
+	msm_camera_io_w(addr,
+		vfe40_ctrl->share_ctrl->vfebase +
+		VFE_BUS_STATS_CS_WR_PONG_ADDR);
+	return 0;
+}
+
+static void vfe40_cfg_qos_parms(struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	void __iomem *vfebase = vfe40_ctrl->share_ctrl->vfebase;
+	msm_camera_io_w(0xAAAAAAAA, vfebase + VFE_0_BUS_BDG_QOS_CFG_0);
+	msm_camera_io_w(0xAAAAAAAA, vfebase + VFE_0_BUS_BDG_QOS_CFG_1);
+	msm_camera_io_w(0xAAAAAAAA, vfebase + VFE_0_BUS_BDG_QOS_CFG_2);
+	msm_camera_io_w(0xAAAAAAAA, vfebase + VFE_0_BUS_BDG_QOS_CFG_3);
+	msm_camera_io_w(0xAAAAAAAA, vfebase + VFE_0_BUS_BDG_QOS_CFG_4);
+	msm_camera_io_w(0xAAAAAAAA, vfebase + VFE_0_BUS_BDG_QOS_CFG_5);
+	msm_camera_io_w(0xAAAAAAAA, vfebase + VFE_0_BUS_BDG_QOS_CFG_6);
+	msm_camera_io_w(0x0002AAAA, vfebase + VFE_0_BUS_BDG_QOS_CFG_7);
+}
+
+static void vfe40_start_common(struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	uint16_t vfe_operation_mode =
+		vfe40_ctrl->share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
+			VFE_OUTPUTS_RDI1);
+	CDBG("VFE opertaion mode = 0x%x, output mode = 0x%x\n",
+		vfe40_ctrl->share_ctrl->current_mode,
+		vfe40_ctrl->share_ctrl->outpath.output_mode);
+
+	vfe40_cfg_qos_parms(vfe40_ctrl);
+
+	msm_camera_io_w_mb(0x1,
+			vfe40_ctrl->share_ctrl->vfebase +
+			VFE_REG_UPDATE_CMD);
+
+	msm_camera_io_w_mb(0x00003fff,
+			vfe40_ctrl->share_ctrl->vfebase +
+			V40_AXI_BUS_CMD_OFF);
+	msm_camera_io_w_mb(1,
+			vfe40_ctrl->share_ctrl->vfebase +
+			V40_BUS_PM_CMD);
+	if (vfe_operation_mode) {
+		msm_camera_io_w_mb(1, vfe40_ctrl->share_ctrl->vfebase +
+			VFE_CAMIF_COMMAND);
+	}
+
+}
+
+static int vfe40_start_recording(
+	struct msm_cam_media_controller *pmctl,
+	struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	vfe40_ctrl->share_ctrl->recording_state = VFE_STATE_START_REQUESTED;
+	msm_camera_io_w_mb(1,
+		vfe40_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	return 0;
+}
+
+static int vfe40_stop_recording(
+	struct msm_cam_media_controller *pmctl,
+	struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	vfe40_ctrl->share_ctrl->recording_state = VFE_STATE_STOP_REQUESTED;
+	msm_camera_io_w_mb(1,
+		vfe40_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	return 0;
+}
+
+static void vfe40_start_liveshot(
+	struct msm_cam_media_controller *pmctl,
+	struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	/* Hardcode 1 live snapshot for now. */
+	vfe40_ctrl->share_ctrl->outpath.out0.capture_cnt = 1;
+	vfe40_ctrl->share_ctrl->vfe_capture_count =
+		vfe40_ctrl->share_ctrl->outpath.out0.capture_cnt;
+
+	vfe40_ctrl->share_ctrl->liveshot_state = VFE_STATE_START_REQUESTED;
+	msm_camera_io_w_mb(1, vfe40_ctrl->
+		share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+}
+
+static void vfe40_stop_liveshot(
+	struct msm_cam_media_controller *pmctl,
+	struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	vfe40_ctrl->share_ctrl->liveshot_state = VFE_STATE_STOP_REQUESTED;
+	msm_camera_io_w_mb(1,
+		vfe40_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+}
+
+static int vfe40_zsl(
+	struct msm_cam_media_controller *pmctl,
+	struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	vfe40_ctrl->share_ctrl->start_ack_pending = TRUE;
+	vfe40_start_common(vfe40_ctrl);
+
+	return 0;
+}
+static int vfe40_capture_raw(
+	struct msm_cam_media_controller *pmctl,
+	struct vfe40_ctrl_type *vfe40_ctrl,
+	uint32_t num_frames_capture)
+{
+	vfe40_ctrl->share_ctrl->outpath.out0.capture_cnt = num_frames_capture;
+	vfe40_ctrl->share_ctrl->vfe_capture_count = num_frames_capture;
+	vfe40_start_common(vfe40_ctrl);
+	return 0;
+}
+
+static int vfe40_capture(
+	struct msm_cam_media_controller *pmctl,
+	uint32_t num_frames_capture,
+	struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	/* capture command is valid for both idle and active state. */
+	vfe40_ctrl->share_ctrl->outpath.out1.capture_cnt = num_frames_capture;
+	if (vfe40_ctrl->share_ctrl->current_mode ==
+			VFE_OUTPUTS_MAIN_AND_THUMB ||
+		vfe40_ctrl->share_ctrl->current_mode ==
+			VFE_OUTPUTS_THUMB_AND_MAIN ||
+		vfe40_ctrl->share_ctrl->current_mode ==
+			VFE_OUTPUTS_JPEG_AND_THUMB ||
+		vfe40_ctrl->share_ctrl->current_mode ==
+			VFE_OUTPUTS_THUMB_AND_JPEG) {
+		vfe40_ctrl->share_ctrl->outpath.out0.capture_cnt =
+			num_frames_capture;
+	}
+
+	vfe40_ctrl->share_ctrl->vfe_capture_count = num_frames_capture;
+
+
+	vfe40_start_common(vfe40_ctrl);
+	/* for debug */
+	return 0;
+}
+
+static int vfe40_start(
+	struct msm_cam_media_controller *pmctl,
+	struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	vfe40_start_common(vfe40_ctrl);
+	return 0;
+}
+
+static void vfe40_update(struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	unsigned long flags;
+	uint32_t value = 0;
+	if (vfe40_ctrl->update_linear) {
+		if (!msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase +
+			V40_LINEARIZATION_OFF1))
+			msm_camera_io_w(1,
+				vfe40_ctrl->share_ctrl->vfebase +
+				V40_LINEARIZATION_OFF1);
+		else
+			msm_camera_io_w(0,
+				vfe40_ctrl->share_ctrl->vfebase +
+				V40_LINEARIZATION_OFF1);
+		vfe40_ctrl->update_linear = false;
+	}
+
+	if (vfe40_ctrl->update_la) {
+		if (!msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase + V40_LA_OFF))
+			msm_camera_io_w(1,
+				vfe40_ctrl->share_ctrl->vfebase + V40_LA_OFF);
+		else
+			msm_camera_io_w(0,
+				vfe40_ctrl->share_ctrl->vfebase + V40_LA_OFF);
+		vfe40_ctrl->update_la = false;
+	}
+
+	if (vfe40_ctrl->update_gamma) {
+		value = msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase + V40_RGB_G_OFF);
+		value ^= V40_GAMMA_LUT_BANK_SEL_MASK;
+		msm_camera_io_w(value,
+			vfe40_ctrl->share_ctrl->vfebase + V40_RGB_G_OFF);
+		vfe40_ctrl->update_gamma = false;
+	}
+
+	spin_lock_irqsave(&vfe40_ctrl->share_ctrl->update_ack_lock, flags);
+	vfe40_ctrl->share_ctrl->update_ack_pending = TRUE;
+	spin_unlock_irqrestore(&vfe40_ctrl->share_ctrl->update_ack_lock, flags);
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_camera_io_w_mb(1,
+		vfe40_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	return;
+}
+
+static void vfe40_sync_timer_stop(struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	uint32_t value = 0;
+	vfe40_ctrl->sync_timer_state = 0;
+	if (vfe40_ctrl->sync_timer_number == 0)
+		value = 0x10000;
+	else if (vfe40_ctrl->sync_timer_number == 1)
+		value = 0x20000;
+	else if (vfe40_ctrl->sync_timer_number == 2)
+		value = 0x40000;
+
+	/* Timer Stop */
+	msm_camera_io_w(value,
+		vfe40_ctrl->share_ctrl->vfebase + V40_SYNC_TIMER_OFF);
+}
+
+static void vfe40_sync_timer_start(
+	const uint32_t *tbl,
+	struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	/* set bit 8 for auto increment. */
+	uint32_t value = 1;
+	uint32_t val;
+
+	vfe40_ctrl->sync_timer_state = *tbl++;
+	vfe40_ctrl->sync_timer_repeat_count = *tbl++;
+	vfe40_ctrl->sync_timer_number = *tbl++;
+	CDBG("%s timer_state %d, repeat_cnt %d timer number %d\n",
+		 __func__, vfe40_ctrl->sync_timer_state,
+		 vfe40_ctrl->sync_timer_repeat_count,
+		 vfe40_ctrl->sync_timer_number);
+
+	if (vfe40_ctrl->sync_timer_state) { /* Start Timer */
+		value = value << vfe40_ctrl->sync_timer_number;
+	} else { /* Stop Timer */
+		CDBG("Failed to Start timer\n");
+		return;
+	}
+
+	/* Timer Start */
+	msm_camera_io_w(value,
+		vfe40_ctrl->share_ctrl->vfebase + V40_SYNC_TIMER_OFF);
+	/* Sync Timer Line Start */
+	value = *tbl++;
+	msm_camera_io_w(value,
+		vfe40_ctrl->share_ctrl->vfebase + V40_SYNC_TIMER_OFF +
+		4 + ((vfe40_ctrl->sync_timer_number) * 12));
+	/* Sync Timer Pixel Start */
+	value = *tbl++;
+	msm_camera_io_w(value,
+			vfe40_ctrl->share_ctrl->vfebase + V40_SYNC_TIMER_OFF +
+			 8 + ((vfe40_ctrl->sync_timer_number) * 12));
+	/* Sync Timer Pixel Duration */
+	value = *tbl++;
+	val = vfe_clk_rate / 10000;
+	val = 10000000 / val;
+	val = value * 10000 / val;
+	CDBG("%s: Pixel Clk Cycles!!! %d\n", __func__, val);
+	msm_camera_io_w(val,
+		vfe40_ctrl->share_ctrl->vfebase + V40_SYNC_TIMER_OFF +
+		12 + ((vfe40_ctrl->sync_timer_number) * 12));
+	/* Timer0 Active High/LOW */
+	value = *tbl++;
+	msm_camera_io_w(value,
+		vfe40_ctrl->share_ctrl->vfebase + V40_SYNC_TIMER_POLARITY_OFF);
+	/* Selects sync timer 0 output to drive onto timer1 port */
+	value = 0;
+	msm_camera_io_w(value,
+		vfe40_ctrl->share_ctrl->vfebase + V40_TIMER_SELECT_OFF);
+}
+
+
+static void vfe40_write_gamma_cfg(
+	enum VFE40_DMI_RAM_SEL channel_sel,
+	const uint32_t *tbl,
+	struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	int i;
+	uint32_t value, value1, value2;
+	vfe40_program_dmi_cfg(channel_sel, vfe40_ctrl);
+	for (i = 0 ; i < (VFE40_GAMMA_NUM_ENTRIES/2) ; i++) {
+		value = *tbl++;
+		value1 = value & 0x0000FFFF;
+		value2 = (value & 0xFFFF0000)>>16;
+		msm_camera_io_w((value1),
+			vfe40_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
+		msm_camera_io_w((value2),
+			vfe40_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
+	}
+	vfe40_program_dmi_cfg(NO_MEM_SELECTED, vfe40_ctrl);
+}
+
+static void vfe40_read_gamma_cfg(
+	enum VFE40_DMI_RAM_SEL channel_sel,
+	uint32_t *tbl,
+	struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	int i;
+	vfe40_program_dmi_cfg(channel_sel, vfe40_ctrl);
+	CDBG("%s: Gamma table channel: %d\n", __func__, channel_sel);
+	for (i = 0 ; i < VFE40_GAMMA_NUM_ENTRIES ; i++) {
+		*tbl = msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
+		CDBG("%s: %08x\n", __func__, *tbl);
+		tbl++;
+	}
+	vfe40_program_dmi_cfg(NO_MEM_SELECTED, vfe40_ctrl);
+}
+
+static void vfe40_write_la_cfg(
+	enum VFE40_DMI_RAM_SEL channel_sel,
+	const uint32_t *tbl,
+	struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	uint32_t i;
+	uint32_t value, value1, value2;
+
+	vfe40_program_dmi_cfg(channel_sel, vfe40_ctrl);
+	for (i = 0 ; i < (VFE40_LA_TABLE_LENGTH/2) ; i++) {
+		value = *tbl++;
+		value1 = value & 0x0000FFFF;
+		value2 = (value & 0xFFFF0000)>>16;
+		msm_camera_io_w((value1),
+			vfe40_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
+		msm_camera_io_w((value2),
+			vfe40_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
+	}
+	vfe40_program_dmi_cfg(NO_MEM_SELECTED, vfe40_ctrl);
+}
+
+static struct vfe40_output_ch *vfe40_get_ch(
+	int path, struct vfe_share_ctrl_t *share_ctrl)
+{
+	struct vfe40_output_ch *ch = NULL;
+
+	if (path == VFE_MSG_OUTPUT_PRIMARY)
+		ch = &share_ctrl->outpath.out0;
+	else if (path == VFE_MSG_OUTPUT_SECONDARY)
+		ch = &share_ctrl->outpath.out1;
+	else if (path == VFE_MSG_OUTPUT_TERTIARY1)
+		ch = &share_ctrl->outpath.out2;
+	else if (path == VFE_MSG_OUTPUT_TERTIARY2)
+		ch = &share_ctrl->outpath.out3;
+	else
+		pr_err("%s: Invalid path %d\n", __func__,
+			path);
+
+	BUG_ON(ch == NULL);
+	return ch;
+}
+static struct msm_free_buf *vfe40_check_free_buffer(
+	int id, int path, struct axi_ctrl_t *axi_ctrl)
+{
+	struct vfe40_output_ch *outch = NULL;
+	struct msm_free_buf *b = NULL;
+	uint32_t inst_handle = 0;
+
+	if (path == VFE_MSG_OUTPUT_PRIMARY)
+		inst_handle = axi_ctrl->share_ctrl->outpath.out0.inst_handle;
+	else if (path == VFE_MSG_OUTPUT_SECONDARY)
+		inst_handle = axi_ctrl->share_ctrl->outpath.out1.inst_handle;
+	else if (path == VFE_MSG_OUTPUT_TERTIARY1)
+		inst_handle = axi_ctrl->share_ctrl->outpath.out2.inst_handle;
+	else if (path == VFE_MSG_OUTPUT_TERTIARY2)
+		inst_handle = axi_ctrl->share_ctrl->outpath.out3.inst_handle;
+
+	vfe40_subdev_notify(id, path, inst_handle,
+		&axi_ctrl->subdev, axi_ctrl->share_ctrl);
+	outch = vfe40_get_ch(path, axi_ctrl->share_ctrl);
+	if (outch->free_buf.ch_paddr[0])
+		b = &outch->free_buf;
+	return b;
+}
+static int configure_pingpong_buffers(
+	int id, int path, struct axi_ctrl_t *axi_ctrl)
+{
+	struct vfe40_output_ch *outch = NULL;
+	int rc = 0;
+	uint32_t inst_handle = 0;
+	if (path == VFE_MSG_OUTPUT_PRIMARY)
+		inst_handle = axi_ctrl->share_ctrl->outpath.out0.inst_handle;
+	else if (path == VFE_MSG_OUTPUT_SECONDARY)
+		inst_handle = axi_ctrl->share_ctrl->outpath.out1.inst_handle;
+	else if (path == VFE_MSG_OUTPUT_TERTIARY1)
+		inst_handle = axi_ctrl->share_ctrl->outpath.out2.inst_handle;
+	else if (path == VFE_MSG_OUTPUT_TERTIARY2)
+		inst_handle = axi_ctrl->share_ctrl->outpath.out3.inst_handle;
+
+	vfe40_subdev_notify(id, path, inst_handle,
+		&axi_ctrl->subdev, axi_ctrl->share_ctrl);
+	outch = vfe40_get_ch(path, axi_ctrl->share_ctrl);
+	if (outch->ping.ch_paddr[0] && outch->pong.ch_paddr[0]) {
+		/* Configure Preview Ping Pong */
+		pr_info("%s Configure ping/pong address for %d\n",
+						__func__, path);
+		vfe40_put_ch_ping_addr(
+			axi_ctrl->share_ctrl->vfebase, outch->ch0,
+			outch->ping.ch_paddr[0]);
+		vfe40_put_ch_pong_addr(
+			axi_ctrl->share_ctrl->vfebase, outch->ch0,
+			outch->pong.ch_paddr[0]);
+
+		if ((axi_ctrl->share_ctrl->current_mode !=
+			VFE_OUTPUTS_RAW) && (path != VFE_MSG_OUTPUT_TERTIARY1)
+			&& (path != VFE_MSG_OUTPUT_TERTIARY2)) {
+			vfe40_put_ch_ping_addr(
+				axi_ctrl->share_ctrl->vfebase, outch->ch1,
+				outch->ping.ch_paddr[1]);
+			vfe40_put_ch_pong_addr(
+				axi_ctrl->share_ctrl->vfebase, outch->ch1,
+				outch->pong.ch_paddr[1]);
+		}
+
+		if (outch->ping.num_planes > 2)
+			vfe40_put_ch_ping_addr(
+				axi_ctrl->share_ctrl->vfebase, outch->ch2,
+				outch->ping.ch_paddr[2]);
+		if (outch->pong.num_planes > 2)
+			vfe40_put_ch_pong_addr(
+				axi_ctrl->share_ctrl->vfebase, outch->ch2,
+				outch->pong.ch_paddr[2]);
+
+		/* avoid stale info */
+		memset(&outch->ping, 0, sizeof(struct msm_free_buf));
+		memset(&outch->pong, 0, sizeof(struct msm_free_buf));
+	} else {
+		pr_err("%s ping/pong addr is null!!", __func__);
+		rc = -EINVAL;
+	}
+	return rc;
+}
+
+static void vfe40_write_linear_cfg(
+	enum VFE40_DMI_RAM_SEL channel_sel,
+	const uint32_t *tbl, struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	uint32_t i;
+
+	vfe40_program_dmi_cfg(channel_sel, vfe40_ctrl);
+	/* for loop for configuring LUT. */
+	for (i = 0 ; i < VFE40_LINEARIZATON_TABLE_LENGTH ; i++) {
+		msm_camera_io_w(*tbl,
+			vfe40_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
+		tbl++;
+	}
+	CDBG("done writing to linearization table\n");
+	vfe40_program_dmi_cfg(NO_MEM_SELECTED, vfe40_ctrl);
+}
+
+static void vfe40_send_isp_msg(
+	struct v4l2_subdev *sd,
+	uint32_t vfeFrameId,
+	uint32_t isp_msg_id)
+{
+	struct isp_msg_event isp_msg_evt;
+
+	isp_msg_evt.msg_id = isp_msg_id;
+	isp_msg_evt.sof_count = vfeFrameId;
+	v4l2_subdev_notify(sd,
+			NOTIFY_ISP_MSG_EVT,
+			(void *)&isp_msg_evt);
+}
+
+static int vfe40_proc_general(
+	struct msm_cam_media_controller *pmctl,
+	struct msm_isp_cmd *cmd,
+	struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	int i , rc = 0;
+	uint32_t old_val = 0 , new_val = 0, module_val = 0;
+	uint32_t *cmdp = NULL;
+	uint32_t *cmdp_local = NULL;
+	uint32_t snapshot_cnt = 0;
+	uint32_t temp1 = 0, temp2 = 0;
+	struct msm_camera_vfe_params_t vfe_params;
+
+	CDBG("vfe40_proc_general: cmdID = %s, length = %d\n",
+		vfe40_general_cmd[cmd->id], cmd->length);
+	switch (cmd->id) {
+	case VFE_CMD_RESET:
+		pr_info("vfe40_proc_general: cmdID = %s\n",
+			vfe40_general_cmd[cmd->id]);
+		vfe40_ctrl->share_ctrl->vfe_reset_flag = true;
+		vfe40_reset(vfe40_ctrl);
+		break;
+	case VFE_CMD_START:
+		pr_info("vfe40_proc_general: cmdID = %s\n",
+			vfe40_general_cmd[cmd->id]);
+		if (copy_from_user(&vfe_params,
+				(void __user *)(cmd->value),
+				sizeof(struct msm_camera_vfe_params_t))) {
+				rc = -EFAULT;
+				goto proc_general_done;
+		}
+
+		vfe40_ctrl->share_ctrl->current_mode =
+			vfe_params.operation_mode;
+
+		rc = vfe40_start(pmctl, vfe40_ctrl);
+		break;
+	case VFE_CMD_UPDATE:
+		vfe40_update(vfe40_ctrl);
+		break;
+	case VFE_CMD_CAPTURE_RAW:
+		pr_info("%s: cmdID = VFE_CMD_CAPTURE_RAW\n", __func__);
+		if (copy_from_user(&vfe_params,
+				(void __user *)(cmd->value),
+				sizeof(struct msm_camera_vfe_params_t))) {
+				rc = -EFAULT;
+				goto proc_general_done;
+		}
+
+		snapshot_cnt = vfe_params.capture_count;
+		vfe40_ctrl->share_ctrl->current_mode =
+			vfe_params.operation_mode;
+		rc = vfe40_capture_raw(pmctl, vfe40_ctrl, snapshot_cnt);
+		break;
+	case VFE_CMD_CAPTURE:
+		pr_info("%s: cmdID = VFE_CMD_CAPTURE\n", __func__);
+		if (copy_from_user(&vfe_params,
+				(void __user *)(cmd->value),
+				sizeof(struct msm_camera_vfe_params_t))) {
+				rc = -EFAULT;
+				goto proc_general_done;
+		}
+
+		snapshot_cnt = vfe_params.capture_count;
+		vfe40_ctrl->share_ctrl->current_mode =
+			vfe_params.operation_mode;
+
+		rc = vfe40_capture(pmctl, snapshot_cnt, vfe40_ctrl);
+		break;
+	case VFE_CMD_START_RECORDING:
+		pr_info("vfe40_proc_general: cmdID = %s\n",
+			vfe40_general_cmd[cmd->id]);
+		rc = vfe40_start_recording(pmctl, vfe40_ctrl);
+		break;
+	case VFE_CMD_STOP_RECORDING:
+		pr_info("vfe40_proc_general: cmdID = %s\n",
+			vfe40_general_cmd[cmd->id]);
+		rc = vfe40_stop_recording(pmctl, vfe40_ctrl);
+		break;
+	case VFE_CMD_OPERATION_CFG: {
+		if (cmd->length != V40_OPERATION_CFG_LEN) {
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(V40_OPERATION_CFG_LEN, GFP_ATOMIC);
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			V40_OPERATION_CFG_LEN)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		rc = vfe40_operation_config(cmdp, vfe40_ctrl);
+		}
+		break;
+
+	case VFE_CMD_STATS_AE_START: {
+		if (vfe40_use_bayer_stats(vfe40_ctrl)) {
+			/* Error */
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		rc = vfe_stats_bg_buf_init(vfe40_ctrl);
+		if (rc < 0) {
+			pr_err("%s: cannot config ping/pong address of AEC",
+				 __func__);
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val |= BG_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase +
+			vfe40_cmd[cmd->id].offset,
+			cmdp, (vfe40_cmd[cmd->id].length));
+		}
+		break;
+	case VFE_CMD_STATS_AF_START: {
+		if (vfe40_use_bayer_stats(vfe40_ctrl)) {
+			/* Error */
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		rc = vfe_stats_bf_buf_init(vfe40_ctrl);
+		if (rc < 0) {
+			pr_err("%s: cannot config ping/pong address of AF",
+				__func__);
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_camera_io_r(vfe40_ctrl->share_ctrl->vfebase +
+			VFE_MODULE_CFG);
+		old_val |= BF_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase +
+			vfe40_cmd[cmd->id].offset,
+			cmdp, (vfe40_cmd[cmd->id].length));
+		}
+		break;
+	case VFE_CMD_STATS_AWB_START: {
+		rc = vfe_stats_awb_buf_init(vfe40_ctrl, NULL);
+		if (rc < 0) {
+			pr_err("%s: cannot config ping/pong address of AWB",
+				 __func__);
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val |= AWB_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase +
+			vfe40_cmd[cmd->id].offset,
+			cmdp, (vfe40_cmd[cmd->id].length));
+		}
+		break;
+
+	case VFE_CMD_STATS_IHIST_START: {
+		rc = vfe_stats_ihist_buf_init(vfe40_ctrl);
+		if (rc < 0) {
+			pr_err("%s: cannot config ping/pong address of IHIST",
+				 __func__);
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val |= IHIST_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase +
+			vfe40_cmd[cmd->id].offset,
+			cmdp, (vfe40_cmd[cmd->id].length));
+		}
+		break;
+
+
+	case VFE_CMD_STATS_RS_START: {
+		rc = vfe_stats_rs_buf_init(vfe40_ctrl);
+		if (rc < 0) {
+			pr_err("%s: cannot config ping/pong address of RS",
+				__func__);
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase +
+			vfe40_cmd[cmd->id].offset,
+			cmdp, (vfe40_cmd[cmd->id].length));
+		}
+		break;
+
+	case VFE_CMD_STATS_CS_START: {
+		rc = vfe_stats_cs_buf_init(vfe40_ctrl);
+		if (rc < 0) {
+			pr_err("%s: cannot config ping/pong address of CS",
+				__func__);
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase +
+			vfe40_cmd[cmd->id].offset,
+			cmdp, (vfe40_cmd[cmd->id].length));
+		}
+		break;
+
+	case VFE_CMD_STATS_BG_START:
+	case VFE_CMD_STATS_BE_START:
+	case VFE_CMD_STATS_BF_START:
+	case VFE_CMD_STATS_BHIST_START: {
+		old_val = msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase + VFE_STATS_CFG);
+		module_val = msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+
+		if (VFE_CMD_STATS_BE_START == cmd->id) {
+			module_val |= BE_ENABLE_MASK;
+			rc = vfe_stats_be_buf_init(vfe40_ctrl);
+			if (rc < 0) {
+				pr_err("%s: cannot config ping/pong address of BG",
+					__func__);
+				goto proc_general_done;
+			}
+		} else if (VFE_CMD_STATS_BG_START == cmd->id) {
+			module_val |= BG_ENABLE_MASK;
+			rc = vfe_stats_bg_buf_init(vfe40_ctrl);
+			if (rc < 0) {
+				pr_err("%s: cannot config ping/pong address of BG",
+					__func__);
+				goto proc_general_done;
+			}
+		} else if (VFE_CMD_STATS_BF_START == cmd->id) {
+			module_val |= BF_ENABLE_MASK;
+			rc = vfe_stats_bf_buf_init(vfe40_ctrl);
+			if (rc < 0) {
+				pr_err("%s: cannot config ping/pong address of BF",
+					__func__);
+				goto proc_general_done;
+			}
+		} else {
+			module_val |= BHIST_ENABLE_MASK;
+			old_val |= STATS_BHIST_ENABLE_MASK;
+			rc = vfe_stats_bhist_buf_init(vfe40_ctrl);
+			if (rc < 0) {
+				pr_err("%s: cannot config ping/pong address of BHist",
+					__func__);
+				goto proc_general_done;
+			}
+		}
+		msm_camera_io_w(old_val, vfe40_ctrl->share_ctrl->vfebase +
+			VFE_STATS_CFG);
+		msm_camera_io_w(module_val,
+			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+				(void __user *)(cmd->value),
+				cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase +
+			vfe40_cmd[cmd->id].offset,
+			cmdp, (vfe40_cmd[cmd->id].length));
+		}
+		break;
+	case VFE_CMD_MCE_UPDATE:
+	case VFE_CMD_MCE_CFG:{
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		/* Incrementing with 4 so as to point to the 2nd Register as
+		the 2nd register has the mce_enable bit */
+		old_val = msm_camera_io_r(vfe40_ctrl->share_ctrl->vfebase +
+			V40_CHROMA_SUP_OFF + 4);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		new_val = *cmdp_local;
+		old_val &= MCE_EN_MASK;
+		new_val = new_val | old_val;
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase +
+			V40_CHROMA_SUP_OFF + 4, &new_val, 4);
+		cmdp_local += 1;
+
+		old_val = msm_camera_io_r(vfe40_ctrl->share_ctrl->vfebase +
+			V40_CHROMA_SUP_OFF + 8);
+		new_val = *cmdp_local;
+		old_val &= MCE_Q_K_MASK;
+		new_val = new_val | old_val;
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase +
+			V40_CHROMA_SUP_OFF + 8, &new_val, 4);
+		cmdp_local += 1;
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase +
+			vfe40_cmd[cmd->id].offset,
+			cmdp_local, (vfe40_cmd[cmd->id].length));
+		}
+		break;
+	case VFE_CMD_CHROMA_SUP_UPDATE:
+	case VFE_CMD_CHROMA_SUP_CFG:{
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		msm_camera_io_memcpy(vfe40_ctrl->share_ctrl->vfebase +
+			V40_CHROMA_SUP_OFF, cmdp_local, 4);
+
+		cmdp_local += 1;
+		new_val = *cmdp_local;
+		/* Incrementing with 4 so as to point to the 2nd Register as
+		 * the 2nd register has the mce_enable bit
+		 */
+		old_val = msm_camera_io_r(vfe40_ctrl->share_ctrl->vfebase +
+			V40_CHROMA_SUP_OFF + 4);
+		old_val &= ~MCE_EN_MASK;
+		new_val = new_val | old_val;
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase +
+			V40_CHROMA_SUP_OFF + 4, &new_val, 4);
+		cmdp_local += 1;
+
+		old_val = msm_camera_io_r(vfe40_ctrl->share_ctrl->vfebase +
+			V40_CHROMA_SUP_OFF + 8);
+		new_val = *cmdp_local;
+		old_val &= ~MCE_Q_K_MASK;
+		new_val = new_val | old_val;
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase +
+			V40_CHROMA_SUP_OFF + 8, &new_val, 4);
+		}
+		break;
+	case VFE_CMD_BLACK_LEVEL_CFG:
+		rc = -EFAULT;
+		goto proc_general_done;
+
+	case VFE_CMD_MESH_ROLL_OFF_CFG: {
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value) , cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase +
+			vfe40_cmd[cmd->id].offset,
+			cmdp_local, V40_MESH_ROLL_OFF_CFG_LEN);
+		cmdp_local += 9;
+		vfe40_program_dmi_cfg(ROLLOFF_RAM0_BANK0, vfe40_ctrl);
+		/* for loop for extrcting table. */
+		for (i = 0; i < (V40_MESH_ROLL_OFF_TABLE_SIZE * 2); i++) {
+			msm_camera_io_w(*cmdp_local,
+				vfe40_ctrl->share_ctrl->vfebase +
+				VFE_DMI_DATA_LO);
+			cmdp_local++;
+		}
+		CDBG("done writing mesh table\n");
+		vfe40_program_dmi_cfg(NO_MEM_SELECTED, vfe40_ctrl);
+	}
+	break;
+	case VFE_CMD_GET_MESH_ROLLOFF_TABLE:
+		break;
+
+	case VFE_CMD_LA_CFG:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase +
+			vfe40_cmd[cmd->id].offset,
+			cmdp_local, (vfe40_cmd[cmd->id].length));
+
+		cmdp_local += 1;
+		vfe40_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK0,
+						   cmdp_local, vfe40_ctrl);
+		break;
+
+	case VFE_CMD_LA_UPDATE: {
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+
+		cmdp_local = cmdp + 1;
+		old_val = msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase + V40_LA_OFF);
+		if (old_val != 0x0)
+			vfe40_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK0,
+				cmdp_local, vfe40_ctrl);
+		else
+			vfe40_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK1,
+				cmdp_local, vfe40_ctrl);
+		}
+		vfe40_ctrl->update_la = true;
+		break;
+
+	case VFE_CMD_GET_LA_TABLE:
+		temp1 = sizeof(uint32_t) * VFE40_LA_TABLE_LENGTH / 2;
+		if (cmd->length != temp1) {
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		cmdp = kzalloc(temp1, GFP_KERNEL);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		if (msm_camera_io_r(vfe40_ctrl->
+				share_ctrl->vfebase + V40_LA_OFF))
+			vfe40_program_dmi_cfg(LUMA_ADAPT_LUT_RAM_BANK1,
+						vfe40_ctrl);
+		else
+			vfe40_program_dmi_cfg(LUMA_ADAPT_LUT_RAM_BANK0,
+						vfe40_ctrl);
+		for (i = 0 ; i < (VFE40_LA_TABLE_LENGTH / 2) ; i++) {
+			*cmdp_local =
+				msm_camera_io_r(
+					vfe40_ctrl->share_ctrl->vfebase +
+					VFE_DMI_DATA_LO);
+			*cmdp_local |= (msm_camera_io_r(
+				vfe40_ctrl->share_ctrl->vfebase +
+				VFE_DMI_DATA_LO)) << 16;
+			cmdp_local++;
+		}
+		vfe40_program_dmi_cfg(NO_MEM_SELECTED, vfe40_ctrl);
+		if (copy_to_user((void __user *)(cmd->value), cmdp,
+			temp1)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		break;
+	case VFE_CMD_SK_ENHAN_CFG:
+	case VFE_CMD_SK_ENHAN_UPDATE:{
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase + V40_SCE_OFF,
+			cmdp, V40_SCE_LEN);
+		}
+		break;
+
+	case VFE_CMD_LIVESHOT:
+		/* Configure primary channel */
+		vfe40_start_liveshot(pmctl, vfe40_ctrl);
+		break;
+
+	case VFE_CMD_LINEARIZATION_CFG:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp, (void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase +
+			V40_LINEARIZATION_OFF1,
+			cmdp_local, V40_LINEARIZATION_LEN1);
+		cmdp_local = cmdp + 17;
+		vfe40_write_linear_cfg(BLACK_LUT_RAM_BANK0,
+					cmdp_local, vfe40_ctrl);
+		break;
+
+	case VFE_CMD_LINEARIZATION_UPDATE:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp, (void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		cmdp_local++;
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase +
+			V40_LINEARIZATION_OFF1 + 4,
+			cmdp_local, (V40_LINEARIZATION_LEN1 - 4));
+		cmdp_local = cmdp + 17;
+		/*extracting the bank select*/
+		old_val = msm_camera_io_r(
+				vfe40_ctrl->share_ctrl->vfebase +
+				V40_LINEARIZATION_OFF1);
+
+		if (old_val != 0x0)
+			vfe40_write_linear_cfg(BLACK_LUT_RAM_BANK0,
+						cmdp_local, vfe40_ctrl);
+		else
+			vfe40_write_linear_cfg(BLACK_LUT_RAM_BANK1,
+						cmdp_local, vfe40_ctrl);
+		vfe40_ctrl->update_linear = true;
+		break;
+
+	case VFE_CMD_GET_LINEARIZATON_TABLE:
+		temp1 = sizeof(uint32_t) * VFE40_LINEARIZATON_TABLE_LENGTH;
+		if (cmd->length != temp1) {
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		cmdp = kzalloc(temp1, GFP_KERNEL);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		if (msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase +
+			V40_LINEARIZATION_OFF1))
+			vfe40_program_dmi_cfg(BLACK_LUT_RAM_BANK1, vfe40_ctrl);
+		else
+			vfe40_program_dmi_cfg(BLACK_LUT_RAM_BANK0, vfe40_ctrl);
+		CDBG("%s: Linearization Table\n", __func__);
+		for (i = 0 ; i < VFE40_LINEARIZATON_TABLE_LENGTH ; i++) {
+			*cmdp_local = msm_camera_io_r(
+				vfe40_ctrl->share_ctrl->vfebase +
+				VFE_DMI_DATA_LO);
+			CDBG("%s: %08x\n", __func__, *cmdp_local);
+			cmdp_local++;
+		}
+		vfe40_program_dmi_cfg(NO_MEM_SELECTED, vfe40_ctrl);
+		if (copy_to_user((void __user *)(cmd->value), cmdp,
+			temp1)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		break;
+	case VFE_CMD_DEMOSAICV3:
+		if (cmd->length !=
+			V40_DEMOSAICV3_0_LEN+V40_DEMOSAICV3_1_LEN) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		new_val = *cmdp_local;
+
+		old_val = msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase + V40_DEMOSAICV3_0_OFF);
+		old_val &= DEMOSAIC_MASK;
+		new_val = new_val | old_val;
+		*cmdp_local = new_val;
+
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase + V40_DEMOSAICV3_0_OFF,
+			cmdp_local, V40_DEMOSAICV3_0_LEN);
+		cmdp_local += 1;
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase + V40_DEMOSAICV3_1_OFF,
+			cmdp_local, V40_DEMOSAICV3_1_LEN);
+		break;
+
+	case VFE_CMD_DEMOSAICV3_UPDATE:
+		if (cmd->length !=
+			V40_DEMOSAICV3_0_LEN * V40_DEMOSAICV3_UP_REG_CNT) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		new_val = *cmdp_local;
+
+		old_val = msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase + V40_DEMOSAICV3_0_OFF);
+		old_val &= DEMOSAIC_MASK;
+		new_val = new_val | old_val;
+		*cmdp_local = new_val;
+
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase + V40_DEMOSAICV3_0_OFF,
+			cmdp_local, V40_DEMOSAICV3_0_LEN);
+		/* As the address space is not contiguous increment by 2
+		 * before copying to next address space */
+		cmdp_local += 1;
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase + V40_DEMOSAICV3_1_OFF,
+			cmdp_local, 2 * V40_DEMOSAICV3_0_LEN);
+		/* As the address space is not contiguous increment by 2
+		 * before copying to next address space */
+		cmdp_local += 2;
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase + V40_DEMOSAICV3_2_OFF,
+			cmdp_local, 2 * V40_DEMOSAICV3_0_LEN);
+		break;
+
+	case VFE_CMD_DEMOSAICV3_ABCC_CFG:
+		rc = -EFAULT;
+		break;
+
+	case VFE_CMD_DEMOSAICV3_ABF_UPDATE:/* 116 ABF update  */
+	case VFE_CMD_DEMOSAICV3_ABF_CFG: { /* 108 ABF config  */
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		new_val = *cmdp_local;
+
+		old_val = msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase + V40_DEMOSAICV3_0_OFF);
+		old_val &= ABF_MASK;
+		new_val = new_val | old_val;
+		*cmdp_local = new_val;
+
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase + V40_DEMOSAICV3_0_OFF,
+			cmdp_local, 4);
+
+		cmdp_local += 1;
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase +
+			vfe40_cmd[cmd->id].offset,
+			cmdp_local, (vfe40_cmd[cmd->id].length));
+		}
+		break;
+
+	case VFE_CMD_DEMOSAICV3_DBCC_CFG:
+	case VFE_CMD_DEMOSAICV3_DBCC_UPDATE:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		new_val = *cmdp_local;
+
+		old_val = msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase + V40_DEMOSAICV3_0_OFF);
+		old_val &= DBCC_MASK;
+
+		new_val = new_val | old_val;
+		*cmdp_local = new_val;
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase + V40_DEMOSAICV3_0_OFF,
+			cmdp_local, 4);
+		cmdp_local += 1;
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase +
+			vfe40_cmd[cmd->id].offset,
+			cmdp_local, (vfe40_cmd[cmd->id].length));
+		break;
+
+	case VFE_CMD_DEMOSAICV3_DBPC_CFG:
+	case VFE_CMD_DEMOSAICV3_DBPC_UPDATE:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		new_val = *cmdp_local;
+
+		old_val = msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase + V40_DEMOSAICV3_0_OFF);
+		old_val &= DBPC_MASK;
+
+		new_val = new_val | old_val;
+		*cmdp_local = new_val;
+		msm_camera_io_memcpy(vfe40_ctrl->share_ctrl->vfebase +
+			V40_DEMOSAICV3_0_OFF,
+			cmdp_local, V40_DEMOSAICV3_0_LEN);
+		cmdp_local += 1;
+		msm_camera_io_memcpy(vfe40_ctrl->share_ctrl->vfebase +
+			V40_DEMOSAICV3_DBPC_CFG_OFF,
+			cmdp_local, V40_DEMOSAICV3_DBPC_LEN);
+		cmdp_local += 1;
+		msm_camera_io_memcpy(vfe40_ctrl->share_ctrl->vfebase +
+			V40_DEMOSAICV3_DBPC_CFG_OFF0,
+			cmdp_local, V40_DEMOSAICV3_DBPC_LEN);
+		cmdp_local += 1;
+		msm_camera_io_memcpy(vfe40_ctrl->share_ctrl->vfebase +
+			V40_DEMOSAICV3_DBPC_CFG_OFF1,
+			cmdp_local, V40_DEMOSAICV3_DBPC_LEN);
+		cmdp_local += 1;
+		msm_camera_io_memcpy(vfe40_ctrl->share_ctrl->vfebase +
+			V40_DEMOSAICV3_DBPC_CFG_OFF2,
+			cmdp_local, V40_DEMOSAICV3_DBPC_LEN);
+		break;
+
+	case VFE_CMD_RGB_G_CFG: {
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase + V40_RGB_G_OFF,
+			cmdp, 4);
+		cmdp += 1;
+
+		vfe40_write_gamma_cfg(RGBLUT_RAM_CH0_BANK0, cmdp, vfe40_ctrl);
+		vfe40_write_gamma_cfg(RGBLUT_RAM_CH1_BANK0, cmdp, vfe40_ctrl);
+		vfe40_write_gamma_cfg(RGBLUT_RAM_CH2_BANK0, cmdp, vfe40_ctrl);
+		}
+	    cmdp -= 1;
+		break;
+
+	case VFE_CMD_RGB_G_UPDATE: {
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp, (void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+
+		old_val = msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase + V40_RGB_G_OFF);
+		cmdp += 1;
+		if (old_val != 0x0) {
+			vfe40_write_gamma_cfg(
+				RGBLUT_RAM_CH0_BANK0, cmdp, vfe40_ctrl);
+			vfe40_write_gamma_cfg(
+				RGBLUT_RAM_CH1_BANK0, cmdp, vfe40_ctrl);
+			vfe40_write_gamma_cfg(
+				RGBLUT_RAM_CH2_BANK0, cmdp, vfe40_ctrl);
+		} else {
+			vfe40_write_gamma_cfg(
+				RGBLUT_RAM_CH0_BANK1, cmdp, vfe40_ctrl);
+			vfe40_write_gamma_cfg(
+				RGBLUT_RAM_CH1_BANK1, cmdp, vfe40_ctrl);
+			vfe40_write_gamma_cfg(
+				RGBLUT_RAM_CH2_BANK1, cmdp, vfe40_ctrl);
+		}
+		}
+		vfe40_ctrl->update_gamma = TRUE;
+		cmdp -= 1;
+		break;
+
+	case VFE_CMD_GET_RGB_G_TABLE:
+		temp1 = sizeof(uint32_t) * VFE40_GAMMA_NUM_ENTRIES * 3;
+		if (cmd->length != temp1) {
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		cmdp = kzalloc(temp1, GFP_KERNEL);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+
+		old_val = msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase + V40_RGB_G_OFF);
+		temp2 = old_val ? RGBLUT_RAM_CH0_BANK1 :
+			RGBLUT_RAM_CH0_BANK0;
+		for (i = 0; i < 3; i++) {
+			vfe40_read_gamma_cfg(temp2,
+				cmdp_local + (VFE40_GAMMA_NUM_ENTRIES * i),
+				vfe40_ctrl);
+			temp2 += 2;
+		}
+		if (copy_to_user((void __user *)(cmd->value), cmdp,
+			temp1)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		break;
+
+	case VFE_CMD_STATS_AWB_STOP: {
+		old_val = msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~AWB_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		}
+		break;
+	case VFE_CMD_STATS_BG_STOP: {
+		old_val = msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~BG_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		}
+		break;
+	case VFE_CMD_STATS_BF_STOP: {
+		old_val = msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~BF_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+		vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+
+		rc = vfe40_stats_flush_enqueue(vfe40_ctrl,
+				MSM_STATS_TYPE_BF);
+		if (rc < 0) {
+			pr_err("%s: dq stats buf err = %d",
+				   __func__, rc);
+			return -EINVAL;
+			}
+		}
+		break;
+
+	case VFE_CMD_STATS_BE_STOP: {
+		old_val = msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~BE_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		}
+		break;
+
+	case VFE_CMD_STATS_IHIST_STOP: {
+		old_val = msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~IHIST_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		}
+		break;
+
+	case VFE_CMD_STATS_RS_STOP: {
+		old_val = msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~RS_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		}
+		break;
+
+	case VFE_CMD_STATS_CS_STOP: {
+		old_val = msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= ~CS_ENABLE_MASK;
+		msm_camera_io_w(old_val,
+			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		}
+		break;
+
+	case VFE_CMD_STATS_BHIST_STOP: {
+		if (!vfe40_use_bayer_stats(vfe40_ctrl)) {
+			/* Error */
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase + VFE_STATS_CFG);
+
+		if (VFE_CMD_STATS_BHIST_STOP == cmd->id)
+			old_val &= ~STATS_BHIST_ENABLE_MASK;
+
+		msm_camera_io_w(old_val,
+			vfe40_ctrl->share_ctrl->vfebase + VFE_STATS_CFG);
+		}
+		break;
+
+	case VFE_CMD_STOP:
+		pr_info("vfe40_proc_general: cmdID = %s\n",
+			vfe40_general_cmd[cmd->id]);
+		if (copy_from_user(&vfe_params,
+				(void __user *)(cmd->value),
+				sizeof(struct msm_camera_vfe_params_t))) {
+				rc = -EFAULT;
+				goto proc_general_done;
+		}
+
+		vfe40_ctrl->share_ctrl->current_mode =
+			vfe_params.operation_mode;
+		vfe40_stop(vfe40_ctrl);
+		break;
+
+	case VFE_CMD_SYNC_TIMER_SETTING:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp, (void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		vfe40_sync_timer_start(cmdp, vfe40_ctrl);
+		break;
+
+	case VFE_CMD_MODULE_CFG: {
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		*cmdp &= ~STATS_ENABLE_MASK;
+		old_val = msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+		old_val &= STATS_ENABLE_MASK;
+		*cmdp |= old_val;
+
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase +
+			vfe40_cmd[cmd->id].offset,
+			cmdp, (vfe40_cmd[cmd->id].length));
+		}
+		break;
+
+	case VFE_CMD_ZSL:
+		if (copy_from_user(&vfe_params,
+				(void __user *)(cmd->value),
+				sizeof(struct msm_camera_vfe_params_t))) {
+				rc = -EFAULT;
+				goto proc_general_done;
+		}
+
+		vfe40_ctrl->share_ctrl->current_mode =
+			vfe_params.operation_mode;
+
+		rc = vfe40_zsl(pmctl, vfe40_ctrl);
+		break;
+
+	case VFE_CMD_ASF_CFG:
+	case VFE_CMD_ASF_UPDATE:
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp, (void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase +
+			vfe40_cmd[cmd->id].offset,
+			cmdp, (vfe40_cmd[cmd->id].length));
+		cmdp_local = cmdp + V40_ASF_LEN/4;
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase +
+			V40_ASF_SPECIAL_EFX_CFG_OFF,
+			cmdp_local, V40_ASF_SPECIAL_EFX_CFG_LEN);
+		break;
+
+	case VFE_CMD_GET_HW_VERSION:
+		if (cmd->length != V40_GET_HW_VERSION_LEN) {
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(V40_GET_HW_VERSION_LEN, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		*cmdp = msm_camera_io_r(
+			vfe40_ctrl->share_ctrl->vfebase+V40_GET_HW_VERSION_OFF);
+		if (copy_to_user((void __user *)(cmd->value), cmdp,
+			V40_GET_HW_VERSION_LEN)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		break;
+	case VFE_CMD_GET_REG_DUMP:
+		temp1 = sizeof(uint32_t) *
+			vfe40_ctrl->share_ctrl->register_total;
+		if (cmd->length != temp1) {
+			rc = -EINVAL;
+			goto proc_general_done;
+		}
+		cmdp = kmalloc(temp1, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		msm_camera_io_dump(vfe40_ctrl->share_ctrl->vfebase,
+			vfe40_ctrl->share_ctrl->register_total*4);
+		CDBG("%s: %p %p %d\n", __func__, (void *)cmdp,
+			vfe40_ctrl->share_ctrl->vfebase, temp1);
+		memcpy_fromio((void *)cmdp,
+			vfe40_ctrl->share_ctrl->vfebase, temp1);
+		if (copy_to_user((void __user *)(cmd->value), cmdp, temp1)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		break;
+	case VFE_CMD_FRAME_SKIP_CFG:
+		if (cmd->length != vfe40_cmd[cmd->id].length)
+			return -EINVAL;
+
+		cmdp = kmalloc(vfe40_cmd[cmd->id].length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+
+		if (copy_from_user((cmdp), (void __user *)cmd->value,
+				cmd->length)) {
+			rc = -EFAULT;
+			pr_err("%s copy from user failed for cmd %d",
+				__func__, cmd->id);
+			break;
+		}
+
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase +
+			vfe40_cmd[cmd->id].offset,
+			cmdp, (vfe40_cmd[cmd->id].length));
+		vfe40_ctrl->frame_skip_cnt = ((uint32_t)
+			*cmdp & VFE_FRAME_SKIP_PERIOD_MASK) + 1;
+		vfe40_ctrl->frame_skip_pattern = (uint32_t)(*(cmdp + 2));
+		break;
+	case VFE_CMD_STOP_LIVESHOT:
+		CDBG("%s Stopping liveshot ", __func__);
+		vfe40_stop_liveshot(pmctl, vfe40_ctrl);
+		break;
+	default:
+		if (cmd->length != vfe40_cmd[cmd->id].length)
+			return -EINVAL;
+
+		cmdp = kmalloc(vfe40_cmd[cmd->id].length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+
+		if (copy_from_user((cmdp), (void __user *)cmd->value,
+				cmd->length)) {
+			rc = -EFAULT;
+			pr_err("%s copy from user failed for cmd %d",
+				__func__, cmd->id);
+			goto proc_general_done;
+		}
+		msm_camera_io_memcpy(
+			vfe40_ctrl->share_ctrl->vfebase +
+			vfe40_cmd[cmd->id].offset,
+			cmdp, (vfe40_cmd[cmd->id].length));
+		break;
+
+	}
+
+proc_general_done:
+	kfree(cmdp);
+
+	return rc;
+}
+
+static inline void vfe40_read_irq_status(
+	struct axi_ctrl_t *axi_ctrl, struct vfe40_irq_status *out)
+{
+	uint32_t *temp;
+	memset(out, 0, sizeof(struct vfe40_irq_status));
+	temp = (uint32_t *)(axi_ctrl->share_ctrl->vfebase + VFE_IRQ_STATUS_0);
+	out->vfeIrqStatus0 = msm_camera_io_r(temp);
+
+	temp = (uint32_t *)(axi_ctrl->share_ctrl->vfebase + VFE_IRQ_STATUS_1);
+	out->vfeIrqStatus1 = msm_camera_io_r(temp);
+
+	temp = (uint32_t *)(axi_ctrl->share_ctrl->vfebase + VFE_CAMIF_STATUS);
+	out->camifStatus = msm_camera_io_r(temp);
+	CDBG("camifStatus  = 0x%x\n", out->camifStatus);
+
+	/* clear the pending interrupt of the same kind.*/
+	msm_camera_io_w(out->vfeIrqStatus0,
+		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_0);
+	msm_camera_io_w(out->vfeIrqStatus1,
+		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_1);
+
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_camera_io_w_mb(1, axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CMD);
+
+}
+
+void axi_stop_pix(struct vfe_share_ctrl_t *share_ctrl)
+{
+	uint32_t operation_mode =
+	share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
+		VFE_OUTPUTS_RDI1);
+	uint32_t irq_comp_mask, irq_mask;
+	uint32_t reg_update = 0x1;
+
+	irq_comp_mask =
+		msm_camera_io_r(share_ctrl->vfebase +
+			VFE_IRQ_COMP_MASK);
+	irq_mask = msm_camera_io_r(share_ctrl->vfebase +
+			VFE_IRQ_MASK_0);
+
+	switch (share_ctrl->cmd_type) {
+	case AXI_CMD_PREVIEW: {
+		switch (operation_mode) {
+		case VFE_OUTPUTS_PREVIEW:
+		case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
+			if (share_ctrl->comp_output_mode &
+				VFE40_OUTPUT_MODE_PRIMARY) {
+				msm_camera_io_w(0, share_ctrl->vfebase
+					+ vfe40_AXI_WM_CFG[share_ctrl->
+					outpath.out0.ch0]);
+				msm_camera_io_w(0, share_ctrl->vfebase
+					+ vfe40_AXI_WM_CFG[share_ctrl->
+					outpath.out0.ch1]);
+				irq_comp_mask &= ~(
+					0x1 << share_ctrl->outpath.out0.ch0 |
+					0x1 << share_ctrl->outpath.out0.ch1);
+				share_ctrl->outpath.output_mode |=
+					VFE40_OUTPUT_MODE_PRIMARY;
+			} else if (share_ctrl->comp_output_mode &
+					VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+				msm_camera_io_w(0, share_ctrl->vfebase
+					+ vfe40_AXI_WM_CFG[share_ctrl->
+					outpath.out0.ch0]);
+				msm_camera_io_w(0, share_ctrl->vfebase
+					+ vfe40_AXI_WM_CFG[share_ctrl->
+					outpath.out0.ch1]);
+				msm_camera_io_w(0, share_ctrl->vfebase
+					+ vfe40_AXI_WM_CFG[share_ctrl->
+					outpath.out0.ch2]);
+				irq_comp_mask &= ~(
+					0x1 << share_ctrl->outpath.out0.ch0 |
+					0x1 << share_ctrl->outpath.out0.ch1 |
+					0x1 << share_ctrl->outpath.out0.ch2);
+				share_ctrl->outpath.output_mode |=
+					VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
+			}
+			irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
+			break;
+		default:
+			if (share_ctrl->comp_output_mode &
+				VFE40_OUTPUT_MODE_SECONDARY) {
+				msm_camera_io_w(0, share_ctrl->vfebase
+					+ vfe40_AXI_WM_CFG[share_ctrl->
+					outpath.out1.ch0]);
+				msm_camera_io_w(0, share_ctrl->vfebase
+					+ vfe40_AXI_WM_CFG[share_ctrl->
+					outpath.out1.ch1]);
+				irq_comp_mask &= ~(
+					0x1 << share_ctrl->outpath.out1.ch0 |
+					0x1 << share_ctrl->outpath.out1.ch1);
+				share_ctrl->outpath.output_mode |=
+					VFE40_OUTPUT_MODE_SECONDARY;
+			} else if (share_ctrl->comp_output_mode &
+				VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+				msm_camera_io_w(0, share_ctrl->vfebase
+					+ vfe40_AXI_WM_CFG[share_ctrl->
+					outpath.out1.ch0]);
+				msm_camera_io_w(0, share_ctrl->vfebase
+					+ vfe40_AXI_WM_CFG[share_ctrl->
+					outpath.out1.ch1]);
+				msm_camera_io_w(0, share_ctrl->vfebase
+					+ vfe40_AXI_WM_CFG[share_ctrl->
+					outpath.out1.ch2]);
+				irq_comp_mask &= ~(
+					0x1 << share_ctrl->outpath.out1.ch0 |
+					0x1 << share_ctrl->outpath.out1.ch1 |
+					0x1 << share_ctrl->outpath.out1.ch2);
+				share_ctrl->outpath.output_mode |=
+					VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS;
+			}
+			irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
+			break;
+			}
+		}
+		break;
+	default:
+		if (share_ctrl->comp_output_mode &
+			VFE40_OUTPUT_MODE_PRIMARY) {
+			msm_camera_io_w(0, share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[share_ctrl->
+				outpath.out0.ch0]);
+			msm_camera_io_w(0, share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[share_ctrl->
+				outpath.out0.ch1]);
+			irq_comp_mask &= ~(
+				0x1 << share_ctrl->outpath.out0.ch0 |
+				0x1 << share_ctrl->outpath.out0.ch1);
+			irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
+			share_ctrl->outpath.output_mode |=
+					VFE40_OUTPUT_MODE_PRIMARY;
+		} else if (share_ctrl->comp_output_mode &
+				VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+			msm_camera_io_w(0, share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[share_ctrl->
+				outpath.out0.ch0]);
+			msm_camera_io_w(0, share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[share_ctrl->
+				outpath.out0.ch1]);
+			msm_camera_io_w(0, share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[share_ctrl->
+				outpath.out0.ch2]);
+			irq_comp_mask &= ~(
+				0x1 << share_ctrl->outpath.out0.ch0 |
+				0x1 << share_ctrl->outpath.out0.ch1 |
+				0x1 << share_ctrl->outpath.out0.ch2);
+			irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
+			share_ctrl->outpath.output_mode |=
+					VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
+		}
+
+		if (share_ctrl->comp_output_mode &
+			VFE40_OUTPUT_MODE_SECONDARY) {
+			msm_camera_io_w(0, share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[share_ctrl->
+				outpath.out1.ch0]);
+			msm_camera_io_w(0, share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[share_ctrl->outpath.out1.ch1]);
+			irq_comp_mask &= ~(
+				0x1 << share_ctrl->outpath.out1.ch0 |
+				0x1 << share_ctrl->outpath.out1.ch1);
+			irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
+			share_ctrl->outpath.output_mode |=
+					VFE40_OUTPUT_MODE_SECONDARY;
+		} else if (share_ctrl->comp_output_mode &
+			VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+			msm_camera_io_w(0, share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[share_ctrl->outpath.out1.ch0]);
+			msm_camera_io_w(0, share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[share_ctrl->outpath.out1.ch1]);
+			msm_camera_io_w(0, share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[share_ctrl->outpath.out1.ch2]);
+			irq_comp_mask &= ~(
+				0x1 << share_ctrl->outpath.out1.ch0 |
+				0x1 << share_ctrl->outpath.out1.ch1 |
+				0x1 << share_ctrl->outpath.out1.ch2);
+			irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
+			share_ctrl->outpath.output_mode |=
+					VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS;
+		}
+		break;
+	}
+
+	msm_camera_io_w_mb(reg_update,
+		share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	msm_camera_io_w(irq_comp_mask,
+		share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+	msm_camera_io_w(irq_mask, share_ctrl->vfebase +
+			VFE_IRQ_MASK_0);
+}
+
+void axi_stop_rdi0(struct vfe_share_ctrl_t *share_ctrl)
+{
+	uint32_t reg_update = 0x2;
+	uint32_t irq_mask;
+	irq_mask = msm_camera_io_r(share_ctrl->vfebase +
+			VFE_IRQ_MASK_0);
+
+	if (share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
+		msm_camera_io_w(0, share_ctrl->vfebase +
+			vfe40_AXI_WM_CFG[share_ctrl->outpath.out2.ch0]);
+		irq_mask &= ~(0x1 << (share_ctrl->outpath.out2.ch0 +
+				VFE_WM_OFFSET));
+	}
+	msm_camera_io_w_mb(reg_update,
+		share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	msm_camera_io_w(irq_mask, share_ctrl->vfebase +
+			VFE_IRQ_MASK_0);
+}
+
+void axi_stop_rdi1(struct vfe_share_ctrl_t *share_ctrl)
+{
+	uint32_t reg_update = 0x4;
+	uint32_t irq_mask;
+	irq_mask = msm_camera_io_r(share_ctrl->vfebase +
+			VFE_IRQ_MASK_0);
+
+	if (share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
+		msm_camera_io_w(1, share_ctrl->vfebase +
+			vfe40_AXI_WM_CFG[share_ctrl->outpath.out3.ch0]);
+		irq_mask &= ~(0x1 << (share_ctrl->outpath.out3.ch0 +
+			VFE_WM_OFFSET));
+	}
+	msm_camera_io_w_mb(reg_update,
+		share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	msm_camera_io_w(irq_mask, share_ctrl->vfebase +
+			VFE_IRQ_MASK_0);
+}
+
+void axi_stop_process(struct vfe_share_ctrl_t *share_ctrl)
+{
+	uint32_t operation_mode =
+	share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
+		VFE_OUTPUTS_RDI1);
+
+	if (share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
+		axi_stop_rdi0(share_ctrl);
+		share_ctrl->comp_output_mode &= ~VFE40_OUTPUT_MODE_TERTIARY1;
+	}
+	if (share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
+		axi_stop_rdi1(share_ctrl);
+		share_ctrl->comp_output_mode &= ~VFE40_OUTPUT_MODE_TERTIARY2;
+	}
+	if (operation_mode) {
+		axi_stop_pix(share_ctrl);
+		share_ctrl->comp_output_mode &=
+				~(share_ctrl->outpath.output_mode);
+	}
+}
+
+static void vfe40_process_reg_update_irq(
+		struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	unsigned long flags;
+	struct vfe_share_ctrl_t *share_ctrl = vfe40_ctrl->share_ctrl;
+
+	if (atomic_cmpxchg(
+		&share_ctrl->pix0_update_ack_pending, 2, 0) == 2) {
+		axi_stop_pix(share_ctrl);
+		msm_camera_io_w_mb(
+				CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
+				share_ctrl->vfebase + VFE_CAMIF_COMMAND);
+		axi_disable_irq(share_ctrl);
+		vfe40_send_isp_msg(&vfe40_ctrl->subdev,
+			share_ctrl->vfeFrameId,
+			MSG_ID_PIX0_UPDATE_ACK);
+		share_ctrl->comp_output_mode &=
+				~(share_ctrl->outpath.output_mode);
+		share_ctrl->current_mode &=
+			(VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI0);
+	}  else {
+		if (share_ctrl->recording_state == VFE_STATE_START_REQUESTED) {
+			if (share_ctrl->operation_mode &
+				VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
+				msm_camera_io_w(1,
+					share_ctrl->vfebase + vfe40_AXI_WM_CFG[
+				share_ctrl->outpath.out0.ch0]);
+				msm_camera_io_w(1,
+					share_ctrl->vfebase + vfe40_AXI_WM_CFG[
+				share_ctrl->outpath.out0.ch1]);
+			} else if (share_ctrl->operation_mode &
+				VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
+				msm_camera_io_w(1,
+					share_ctrl->vfebase + vfe40_AXI_WM_CFG[
+				share_ctrl->outpath.out1.ch0]);
+				msm_camera_io_w(1,
+					share_ctrl->vfebase + vfe40_AXI_WM_CFG[
+				share_ctrl->outpath.out1.ch1]);
+		}
+			share_ctrl->recording_state = VFE_STATE_STARTED;
+		msm_camera_io_w_mb(1,
+				share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+		CDBG("start video triggered .\n");
+		} else if (share_ctrl->recording_state ==
+			VFE_STATE_STOP_REQUESTED) {
+			if (share_ctrl->operation_mode &
+				VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
+				msm_camera_io_w(0,
+					share_ctrl->vfebase + vfe40_AXI_WM_CFG[
+				share_ctrl->outpath.out0.ch0]);
+				msm_camera_io_w(0,
+					share_ctrl->vfebase + vfe40_AXI_WM_CFG[
+				share_ctrl->outpath.out0.ch1]);
+			} else if (share_ctrl->operation_mode &
+				VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
+				msm_camera_io_w(0,
+					share_ctrl->vfebase + vfe40_AXI_WM_CFG[
+				share_ctrl->outpath.out1.ch0]);
+				msm_camera_io_w(0,
+					share_ctrl->vfebase + vfe40_AXI_WM_CFG[
+				share_ctrl->outpath.out1.ch1]);
+		}
+		CDBG("stop video triggered .\n");
+	}
+
+		if (atomic_cmpxchg(
+			&share_ctrl->pix0_update_ack_pending, 1, 0) == 1) {
+			share_ctrl->comp_output_mode |=
+				(share_ctrl->outpath.output_mode
+				& ~(VFE40_OUTPUT_MODE_TERTIARY1|
+					VFE40_OUTPUT_MODE_TERTIARY2));
+		vfe40_send_isp_msg(&vfe40_ctrl->subdev,
+				share_ctrl->vfeFrameId, MSG_ID_PIX0_UPDATE_ACK);
+			share_ctrl->current_mode &=
+				(VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI0);
+	} else {
+		if (share_ctrl->recording_state ==
+			VFE_STATE_STOP_REQUESTED) {
+				share_ctrl->recording_state = VFE_STATE_STOPPED;
+			/* request a reg update and send STOP_REC_ACK
+			 * when we process the next reg update irq.
+			 */
+			msm_camera_io_w_mb(1, share_ctrl->vfebase +
+						VFE_REG_UPDATE_CMD);
+		} else if (share_ctrl->recording_state ==
+					VFE_STATE_STOPPED) {
+			vfe40_send_isp_msg(&vfe40_ctrl->subdev,
+					share_ctrl->vfeFrameId,
+				MSG_ID_STOP_REC_ACK);
+				share_ctrl->recording_state = VFE_STATE_IDLE;
+		}
+		spin_lock_irqsave(&share_ctrl->update_ack_lock, flags);
+		if (share_ctrl->update_ack_pending == TRUE) {
+			share_ctrl->update_ack_pending = FALSE;
+			spin_unlock_irqrestore(
+				&share_ctrl->update_ack_lock, flags);
+			vfe40_send_isp_msg(&vfe40_ctrl->subdev,
+				share_ctrl->vfeFrameId, MSG_ID_UPDATE_ACK);
+		} else {
+			spin_unlock_irqrestore(
+					&share_ctrl->update_ack_lock, flags);
+		}
+	}
+
+	switch (share_ctrl->liveshot_state) {
+	case VFE_STATE_START_REQUESTED:
+		CDBG("%s enabling liveshot output\n", __func__);
+			if (share_ctrl->comp_output_mode &
+			VFE40_OUTPUT_MODE_PRIMARY) {
+				msm_camera_io_w(1, share_ctrl->vfebase +
+					vfe40_AXI_WM_CFG[
+				share_ctrl->outpath.out0.ch0]);
+				msm_camera_io_w(1, share_ctrl->vfebase +
+					vfe40_AXI_WM_CFG[
+				share_ctrl->outpath.out0.ch1]);
+
+				share_ctrl->liveshot_state =
+				VFE_STATE_STARTED;
+				msm_camera_io_w_mb(1, share_ctrl->vfebase +
+				VFE_REG_UPDATE_CMD);
+		}
+		break;
+	case VFE_STATE_STARTED:
+		CDBG("%s disabling liveshot output\n", __func__);
+		if (share_ctrl->vfe_capture_count >= 1) {
+			if (share_ctrl->vfe_capture_count == 1 &&
+				(share_ctrl->comp_output_mode &
+				VFE40_OUTPUT_MODE_PRIMARY)) {
+				msm_camera_io_w(0, share_ctrl->vfebase +
+					vfe40_AXI_WM_CFG[
+					share_ctrl->outpath.out0.ch0]);
+				msm_camera_io_w(0, share_ctrl->vfebase +
+					vfe40_AXI_WM_CFG[
+					share_ctrl->outpath.out0.ch1]);
+				msm_camera_io_w_mb(1, share_ctrl->vfebase +
+					VFE_REG_UPDATE_CMD);
+			}
+			share_ctrl->vfe_capture_count--;
+		}
+		break;
+	case VFE_STATE_STOP_REQUESTED:
+		CDBG("%s disabling liveshot output from stream off\n",
+			__func__);
+		if (share_ctrl->comp_output_mode &
+			VFE40_OUTPUT_MODE_PRIMARY) {
+			/* Stop requested, stop write masters, and
+			 * trigger REG_UPDATE. Send STOP_LS_ACK in
+			 * next reg update. */
+			msm_camera_io_w(0, share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[
+			share_ctrl->outpath.out0.ch0]);
+			msm_camera_io_w(0, share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[
+			share_ctrl->outpath.out0.ch1]);
+			share_ctrl->liveshot_state = VFE_STATE_STOPPED;
+			msm_camera_io_w_mb(1, share_ctrl->vfebase +
+				VFE_REG_UPDATE_CMD);
+		}
+		break;
+	case VFE_STATE_STOPPED:
+		CDBG("%s Sending STOP_LS ACK\n", __func__);
+		vfe40_send_isp_msg(&vfe40_ctrl->subdev,
+			share_ctrl->vfeFrameId, MSG_ID_STOP_LS_ACK);
+			share_ctrl->liveshot_state = VFE_STATE_IDLE;
+		break;
+	default:
+		break;
+	}
+
+	if ((share_ctrl->operation_mode & VFE_OUTPUTS_THUMB_AND_MAIN) ||
+		(share_ctrl->operation_mode &
+		VFE_OUTPUTS_MAIN_AND_THUMB) ||
+		(share_ctrl->operation_mode &
+		VFE_OUTPUTS_THUMB_AND_JPEG) ||
+		(share_ctrl->operation_mode &
+		VFE_OUTPUTS_JPEG_AND_THUMB)) {
+		/* in snapshot mode */
+		/* later we need to add check for live snapshot mode. */
+		if (vfe40_ctrl->frame_skip_pattern & (0x1 <<
+			(vfe40_ctrl->snapshot_frame_cnt %
+				vfe40_ctrl->frame_skip_cnt))) {
+				share_ctrl->vfe_capture_count--;
+			/* if last frame to be captured: */
+				if (share_ctrl->vfe_capture_count == 0) {
+					/* stop the bus output: */
+					if (share_ctrl->comp_output_mode
+					& VFE40_OUTPUT_MODE_PRIMARY) {
+						msm_camera_io_w(0,
+							share_ctrl->vfebase+
+							vfe40_AXI_WM_CFG[
+							share_ctrl->
+							outpath.out0.ch0]);
+						msm_camera_io_w(0,
+							share_ctrl->vfebase+
+							vfe40_AXI_WM_CFG[
+							share_ctrl->
+							outpath.out0.ch1]);
+					}
+					if (share_ctrl->comp_output_mode &
+						VFE40_OUTPUT_MODE_SECONDARY) {
+						msm_camera_io_w(0,
+							share_ctrl->vfebase+
+							vfe40_AXI_WM_CFG[
+							share_ctrl->
+							outpath.out1.ch0]);
+						msm_camera_io_w(0,
+							share_ctrl->vfebase+
+							vfe40_AXI_WM_CFG[
+							share_ctrl->
+							outpath.out1.ch1]);
+				}
+				msm_camera_io_w_mb
+				(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
+					share_ctrl->vfebase +
+					VFE_CAMIF_COMMAND);
+				vfe40_ctrl->snapshot_frame_cnt = -1;
+				vfe40_ctrl->frame_skip_cnt = 31;
+				vfe40_ctrl->frame_skip_pattern = 0xffffffff;
+			} /*if snapshot count is 0*/
+		} /*if frame is not being dropped*/
+		vfe40_ctrl->snapshot_frame_cnt++;
+		/* then do reg_update. */
+		msm_camera_io_w(1,
+				share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+	} /* if snapshot mode. */
+}
+}
+
+static void vfe40_process_rdi0_reg_update_irq(
+	struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	if (atomic_cmpxchg(
+		&vfe40_ctrl->share_ctrl->rdi0_update_ack_pending, 2, 0) == 2) {
+		axi_stop_rdi0(vfe40_ctrl->share_ctrl);
+		axi_disable_irq(vfe40_ctrl->share_ctrl);
+		vfe40_send_isp_msg(&vfe40_ctrl->subdev,
+			vfe40_ctrl->share_ctrl->vfeFrameId,
+			MSG_ID_RDI0_UPDATE_ACK);
+		vfe40_ctrl->share_ctrl->comp_output_mode &=
+			~VFE40_OUTPUT_MODE_TERTIARY1;
+		vfe40_ctrl->share_ctrl->current_mode &=
+			~(VFE_OUTPUTS_RDI0);
+	}
+
+	if (atomic_cmpxchg(
+		&vfe40_ctrl->share_ctrl->rdi0_update_ack_pending, 1, 0) == 1) {
+		vfe40_ctrl->share_ctrl->comp_output_mode |=
+			VFE40_OUTPUT_MODE_TERTIARY1;
+		vfe40_send_isp_msg(&vfe40_ctrl->subdev,
+			vfe40_ctrl->share_ctrl->vfeFrameId,
+			MSG_ID_RDI0_UPDATE_ACK);
+		vfe40_ctrl->share_ctrl->current_mode &=
+			~(VFE_OUTPUTS_RDI0);
+	}
+}
+
+static void vfe40_process_rdi1_reg_update_irq(
+	struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	if (atomic_cmpxchg(
+		&vfe40_ctrl->share_ctrl->rdi1_update_ack_pending, 2, 0) == 2) {
+		axi_stop_rdi1(vfe40_ctrl->share_ctrl);
+		axi_disable_irq(vfe40_ctrl->share_ctrl);
+		vfe40_send_isp_msg(&vfe40_ctrl->subdev,
+			vfe40_ctrl->share_ctrl->vfeFrameId,
+			MSG_ID_RDI1_UPDATE_ACK);
+			vfe40_ctrl->share_ctrl->comp_output_mode &=
+				~VFE40_OUTPUT_MODE_TERTIARY2;
+		vfe40_ctrl->share_ctrl->current_mode &=
+			~(VFE_OUTPUTS_RDI1);
+	}
+
+	if (atomic_cmpxchg(
+		&vfe40_ctrl->share_ctrl->rdi1_update_ack_pending, 1, 0) == 1) {
+		vfe40_ctrl->share_ctrl->comp_output_mode |=
+			VFE40_OUTPUT_MODE_TERTIARY2;
+		vfe40_send_isp_msg(&vfe40_ctrl->subdev,
+			vfe40_ctrl->share_ctrl->vfeFrameId,
+			MSG_ID_RDI1_UPDATE_ACK);
+		vfe40_ctrl->share_ctrl->current_mode &=
+			~(VFE_OUTPUTS_RDI1);
+	}
+}
+
+static void vfe40_process_reset_irq(
+		struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	unsigned long flags;
+
+	atomic_set(&vfe40_ctrl->share_ctrl->vstate, 0);
+	atomic_set(&vfe40_ctrl->share_ctrl->handle_common_irq, 0);
+
+	spin_lock_irqsave(&vfe40_ctrl->share_ctrl->stop_flag_lock, flags);
+	if (vfe40_ctrl->share_ctrl->stop_ack_pending) {
+		vfe40_ctrl->share_ctrl->stop_ack_pending = FALSE;
+		spin_unlock_irqrestore(
+			&vfe40_ctrl->share_ctrl->stop_flag_lock, flags);
+		if (vfe40_ctrl->share_ctrl->sync_abort)
+			complete(&vfe40_ctrl->share_ctrl->reset_complete);
+		else
+		vfe40_send_isp_msg(&vfe40_ctrl->subdev,
+				vfe40_ctrl->share_ctrl->vfeFrameId,
+				MSG_ID_STOP_ACK);
+	} else {
+		spin_unlock_irqrestore(
+			&vfe40_ctrl->share_ctrl->stop_flag_lock, flags);
+		/* this is from reset command. */
+		vfe40_reset_internal_variables(vfe40_ctrl);
+		if (vfe40_ctrl->share_ctrl->vfe_reset_flag) {
+			vfe40_ctrl->share_ctrl->vfe_reset_flag = false;
+			msm_camera_io_w(0xFF00,
+				vfe40_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
+		} else {
+		/* reload all write masters. (frame & line)*/
+		msm_camera_io_w(0xFF7F,
+			vfe40_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
+		}
+		complete(&vfe40_ctrl->share_ctrl->reset_complete);
+	}
+}
+
+static void vfe40_process_camif_sof_irq(
+		struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	if (vfe40_ctrl->share_ctrl->operation_mode &
+		VFE_OUTPUTS_RAW) {
+		if (vfe40_ctrl->share_ctrl->start_ack_pending)
+			vfe40_ctrl->share_ctrl->start_ack_pending = FALSE;
+
+		vfe40_ctrl->share_ctrl->vfe_capture_count--;
+		/* if last frame to be captured: */
+		if (vfe40_ctrl->share_ctrl->vfe_capture_count == 0) {
+			/* Ensure the write order while writing
+			 to the command register using the barrier */
+			msm_camera_io_w_mb(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
+			vfe40_ctrl->share_ctrl->vfebase + VFE_CAMIF_COMMAND);
+		}
+	} /* if raw snapshot mode. */
+	if ((vfe40_ctrl->hfr_mode != HFR_MODE_OFF) &&
+		(vfe40_ctrl->share_ctrl->operation_mode ==
+			VFE_MODE_OF_OPERATION_VIDEO) &&
+		(vfe40_ctrl->share_ctrl->vfeFrameId %
+			vfe40_ctrl->hfr_mode != 0)) {
+		if (vfe40_ctrl->vfe_sof_count_enable)
+			vfe40_ctrl->share_ctrl->vfeFrameId++;
+		CDBG("Skip the SOF notification when HFR enabled\n");
+		return;
+	}
+
+	if (vfe40_ctrl->vfe_sof_count_enable)
+		vfe40_ctrl->share_ctrl->vfeFrameId++;
+
+	vfe40_send_isp_msg(&vfe40_ctrl->subdev,
+		vfe40_ctrl->share_ctrl->vfeFrameId, MSG_ID_SOF_ACK);
+	CDBG("camif_sof_irq, frameId = %d\n",
+		vfe40_ctrl->share_ctrl->vfeFrameId);
+
+	if (vfe40_ctrl->sync_timer_state) {
+		if (vfe40_ctrl->sync_timer_repeat_count == 0)
+			vfe40_sync_timer_stop(vfe40_ctrl);
+		else
+			vfe40_ctrl->sync_timer_repeat_count--;
+	}
+}
+
+static void vfe40_process_error_irq(
+	struct axi_ctrl_t *axi_ctrl, uint32_t errStatus)
+{
+	uint32_t reg_value;
+	if (errStatus & VFE40_IMASK_VIOLATION) {
+		pr_err("vfe40_irq: violation interrupt\n");
+		reg_value = msm_camera_io_r(
+			axi_ctrl->share_ctrl->vfebase + VFE_VIOLATION_STATUS);
+		pr_err("%s: violationStatus  = 0x%x\n", __func__, reg_value);
+	}
+
+	if (errStatus & VFE40_IMASK_CAMIF_ERROR) {
+		pr_err("vfe40_irq: camif errors\n");
+		reg_value = msm_camera_io_r(
+			axi_ctrl->share_ctrl->vfebase + VFE_CAMIF_STATUS);
+		v4l2_subdev_notify(&axi_ctrl->subdev,
+			NOTIFY_VFE_CAMIF_ERROR, (void *)NULL);
+		pr_err("camifStatus  = 0x%x\n", reg_value);
+		vfe40_send_isp_msg(&axi_ctrl->subdev,
+			axi_ctrl->share_ctrl->vfeFrameId, MSG_ID_CAMIF_ERROR);
+	}
+
+	if (errStatus & VFE40_IMASK_BHIST_OVWR)
+		pr_err("vfe40_irq: stats bhist overwrite\n");
+
+	if (errStatus & VFE40_IMASK_STATS_CS_OVWR)
+		pr_err("vfe40_irq: stats cs overwrite\n");
+
+	if (errStatus & VFE40_IMASK_STATS_IHIST_OVWR)
+		pr_err("vfe40_irq: stats ihist overwrite\n");
+
+	if (errStatus & VFE40_IMASK_REALIGN_BUF_Y_OVFL)
+		pr_err("vfe40_irq: realign bug Y overflow\n");
+
+	if (errStatus & VFE40_IMASK_REALIGN_BUF_CB_OVFL)
+		pr_err("vfe40_irq: realign bug CB overflow\n");
+
+	if (errStatus & VFE40_IMASK_REALIGN_BUF_CR_OVFL)
+		pr_err("vfe40_irq: realign bug CR overflow\n");
+
+	if (errStatus & VFE40_IMASK_STATS_BE_BUS_OVFL)
+		pr_err("vfe40_irq: be stats bus overflow\n");
+
+	if (errStatus & VFE40_IMASK_STATS_BG_BUS_OVFL)
+		pr_err("vfe40_irq: bg stats bus overflow\n");
+
+	if (errStatus & VFE40_IMASK_STATS_BF_BUS_OVFL)
+		pr_err("vfe40_irq: bf stats bus overflow\n");
+
+	if (errStatus & VFE40_IMASK_STATS_AWB_BUS_OVFL)
+		pr_err("vfe40_irq: awb stats bus overflow\n");
+
+	if (errStatus & VFE40_IMASK_STATS_RS_BUS_OVFL)
+		pr_err("vfe40_irq: rs stats bus overflow\n");
+
+	if (errStatus & VFE40_IMASK_STATS_CS_BUS_OVFL)
+		pr_err("vfe40_irq: cs stats bus overflow\n");
+
+	if (errStatus & VFE40_IMASK_STATS_IHIST_BUS_OVFL)
+		pr_err("vfe40_irq: ihist stats bus overflow\n");
+
+	if (errStatus & VFE40_IMASK_STATS_SKIN_BHIST_BUS_OVFL)
+		pr_err("vfe40_irq: skin/bhist stats bus overflow\n");
+}
+
+static void vfe40_process_common_error_irq(
+	struct axi_ctrl_t *axi_ctrl, uint32_t errStatus)
+{
+	if (errStatus & VFE40_IMASK_BUS_BDG_HALT_ACK)
+		pr_err("vfe40_irq: BUS BDG HALT ACK\n");
+
+	if (errStatus & VFE40_IMASK_IMG_MAST_0_BUS_OVFL)
+		pr_err("vfe40_irq: image master 0 bus overflow\n");
+
+	if (errStatus & VFE40_IMASK_IMG_MAST_1_BUS_OVFL)
+		pr_err("vfe40_irq: image master 1 bus overflow\n");
+
+	if (errStatus & VFE40_IMASK_IMG_MAST_2_BUS_OVFL)
+		pr_err("vfe40_irq: image master 2 bus overflow\n");
+
+	if (errStatus & VFE40_IMASK_IMG_MAST_3_BUS_OVFL)
+		pr_err("vfe40_irq: image master 3 bus overflow\n");
+
+	if (errStatus & VFE40_IMASK_IMG_MAST_4_BUS_OVFL)
+		pr_err("vfe40_irq: image master 4 bus overflow\n");
+
+	if (errStatus & VFE40_IMASK_IMG_MAST_5_BUS_OVFL)
+		pr_err("vfe40_irq: image master 5 bus overflow\n");
+
+	if (errStatus & VFE40_IMASK_IMG_MAST_6_BUS_OVFL)
+		pr_err("vfe40_irq: image master 6 bus overflow\n");
+
+}
+
+static void vfe_send_outmsg(
+	struct axi_ctrl_t *axi_ctrl, uint8_t msgid,
+	uint32_t ch0_paddr, uint32_t ch1_paddr,
+	uint32_t ch2_paddr, uint32_t inst_handle)
+{
+	struct isp_msg_output msg;
+
+	msg.output_id = msgid;
+	msg.buf.inst_handle = inst_handle;
+	msg.buf.ch_paddr[0]	= ch0_paddr;
+	msg.buf.ch_paddr[1]	= ch1_paddr;
+	msg.buf.ch_paddr[2]	= ch2_paddr;
+	switch (msgid) {
+	case MSG_ID_OUTPUT_TERTIARY1:
+		msg.frameCounter = axi_ctrl->share_ctrl->rdi0FrameId;
+		break;
+	case MSG_ID_OUTPUT_TERTIARY2:
+		msg.frameCounter = axi_ctrl->share_ctrl->rdi1FrameId;
+		break;
+	default:
+		msg.frameCounter = axi_ctrl->share_ctrl->vfeFrameId;
+		break;
+	}
+
+	v4l2_subdev_notify(&axi_ctrl->subdev,
+			NOTIFY_VFE_MSG_OUT,
+			&msg);
+	return;
+}
+
+static void vfe40_process_output_path_irq_0(
+	struct axi_ctrl_t *axi_ctrl)
+{
+	uint32_t ping_pong;
+	uint32_t ch0_paddr, ch1_paddr, ch2_paddr;
+	uint8_t out_bool = 0;
+	struct msm_free_buf *free_buf = NULL;
+
+	free_buf = vfe40_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
+		VFE_MSG_OUTPUT_PRIMARY, axi_ctrl);
+
+	/* we render frames in the following conditions:
+	1. Continuous mode and the free buffer is avaialable.
+	2. In snapshot shot mode, free buffer is not always available.
+	when pending snapshot count is <=1,  then no need to use
+	free buffer.
+	*/
+	out_bool = (
+		(axi_ctrl->share_ctrl->operation_mode &
+			VFE_OUTPUTS_THUMB_AND_MAIN ||
+		axi_ctrl->share_ctrl->operation_mode &
+			VFE_OUTPUTS_MAIN_AND_THUMB ||
+		axi_ctrl->share_ctrl->operation_mode &
+			VFE_OUTPUTS_THUMB_AND_JPEG ||
+		axi_ctrl->share_ctrl->operation_mode &
+			VFE_OUTPUTS_JPEG_AND_THUMB ||
+		axi_ctrl->share_ctrl->operation_mode &
+			VFE_OUTPUTS_RAW ||
+		axi_ctrl->share_ctrl->liveshot_state ==
+			VFE_STATE_STARTED ||
+		axi_ctrl->share_ctrl->liveshot_state ==
+			VFE_STATE_STOP_REQUESTED ||
+		axi_ctrl->share_ctrl->liveshot_state ==
+			VFE_STATE_STOPPED) &&
+		(axi_ctrl->share_ctrl->vfe_capture_count <= 1)) ||
+			free_buf;
+
+	if (out_bool) {
+		ping_pong = msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
+			VFE_BUS_PING_PONG_STATUS);
+
+		/* Channel 0*/
+		ch0_paddr = vfe40_get_ch_addr(
+			ping_pong, axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out0.ch0);
+		/* Channel 1*/
+		ch1_paddr = vfe40_get_ch_addr(
+			ping_pong, axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out0.ch1);
+		/* Channel 2*/
+		ch2_paddr = vfe40_get_ch_addr(
+			ping_pong, axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out0.ch2);
+
+		CDBG("output path 0, ch0 = 0x%x, ch1 = 0x%x, ch2 = 0x%x\n",
+			ch0_paddr, ch1_paddr, ch2_paddr);
+		if (free_buf) {
+			/* Y channel */
+			vfe40_put_ch_addr(ping_pong,
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out0.ch0,
+			free_buf->ch_paddr[0]);
+			/* Chroma channel */
+			vfe40_put_ch_addr(ping_pong,
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out0.ch1,
+			free_buf->ch_paddr[1]);
+			if (free_buf->num_planes > 2)
+				vfe40_put_ch_addr(ping_pong,
+					axi_ctrl->share_ctrl->vfebase,
+					axi_ctrl->share_ctrl->outpath.out0.ch2,
+					free_buf->ch_paddr[2]);
+		}
+		if (axi_ctrl->share_ctrl->operation_mode &
+				VFE_OUTPUTS_THUMB_AND_MAIN ||
+			axi_ctrl->share_ctrl->operation_mode &
+				VFE_OUTPUTS_MAIN_AND_THUMB ||
+			axi_ctrl->share_ctrl->operation_mode &
+				VFE_OUTPUTS_THUMB_AND_JPEG ||
+			axi_ctrl->share_ctrl->operation_mode &
+				VFE_OUTPUTS_JPEG_AND_THUMB ||
+			axi_ctrl->share_ctrl->operation_mode &
+				VFE_OUTPUTS_RAW ||
+			axi_ctrl->share_ctrl->liveshot_state ==
+				VFE_STATE_STOPPED)
+			axi_ctrl->share_ctrl->outpath.out0.capture_cnt--;
+
+		vfe_send_outmsg(axi_ctrl,
+			MSG_ID_OUTPUT_PRIMARY, ch0_paddr,
+			ch1_paddr, ch2_paddr,
+			axi_ctrl->share_ctrl->outpath.out0.inst_handle);
+
+	} else {
+		axi_ctrl->share_ctrl->outpath.out0.frame_drop_cnt++;
+		CDBG("path_irq_0 - no free buffer!\n");
+	}
+}
+
+static void vfe40_process_output_path_irq_1(
+	struct axi_ctrl_t *axi_ctrl)
+{
+	uint32_t ping_pong;
+	uint32_t ch0_paddr, ch1_paddr, ch2_paddr;
+	/* this must be snapshot main image output. */
+	uint8_t out_bool = 0;
+	struct msm_free_buf *free_buf = NULL;
+
+	free_buf = vfe40_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
+		VFE_MSG_OUTPUT_SECONDARY, axi_ctrl);
+	out_bool = ((axi_ctrl->share_ctrl->operation_mode &
+				VFE_OUTPUTS_THUMB_AND_MAIN ||
+			axi_ctrl->share_ctrl->operation_mode &
+				VFE_OUTPUTS_MAIN_AND_THUMB ||
+			axi_ctrl->share_ctrl->operation_mode &
+				VFE_OUTPUTS_RAW ||
+			axi_ctrl->share_ctrl->operation_mode &
+				VFE_OUTPUTS_JPEG_AND_THUMB) &&
+			(axi_ctrl->share_ctrl->vfe_capture_count <= 1)) ||
+				free_buf;
+
+	if (out_bool) {
+		ping_pong = msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
+			VFE_BUS_PING_PONG_STATUS);
+
+		/* Y channel */
+		ch0_paddr = vfe40_get_ch_addr(ping_pong,
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out1.ch0);
+		/* Chroma channel */
+		ch1_paddr = vfe40_get_ch_addr(ping_pong,
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out1.ch1);
+		ch2_paddr = vfe40_get_ch_addr(ping_pong,
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out1.ch2);
+
+		CDBG("%s ch0 = 0x%x, ch1 = 0x%x, ch2 = 0x%x\n",
+			__func__, ch0_paddr, ch1_paddr, ch2_paddr);
+		if (free_buf) {
+			/* Y channel */
+			vfe40_put_ch_addr(ping_pong,
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out1.ch0,
+			free_buf->ch_paddr[0]);
+			/* Chroma channel */
+			vfe40_put_ch_addr(ping_pong,
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out1.ch1,
+			free_buf->ch_paddr[1]);
+			if (free_buf->num_planes > 2)
+				vfe40_put_ch_addr(ping_pong,
+					axi_ctrl->share_ctrl->vfebase,
+					axi_ctrl->share_ctrl->outpath.out1.ch2,
+					free_buf->ch_paddr[2]);
+		}
+		if (axi_ctrl->share_ctrl->operation_mode &
+				VFE_OUTPUTS_THUMB_AND_MAIN ||
+			axi_ctrl->share_ctrl->operation_mode &
+				VFE_OUTPUTS_MAIN_AND_THUMB ||
+			axi_ctrl->share_ctrl->operation_mode &
+				VFE_OUTPUTS_RAW ||
+			axi_ctrl->share_ctrl->operation_mode &
+				VFE_OUTPUTS_JPEG_AND_THUMB)
+			axi_ctrl->share_ctrl->outpath.out1.capture_cnt--;
+
+		vfe_send_outmsg(axi_ctrl,
+			MSG_ID_OUTPUT_SECONDARY, ch0_paddr,
+			ch1_paddr, ch2_paddr,
+			axi_ctrl->share_ctrl->outpath.out1.inst_handle);
+
+	} else {
+		axi_ctrl->share_ctrl->outpath.out1.frame_drop_cnt++;
+		CDBG("path_irq_1 - no free buffer!\n");
+	}
+}
+
+static void vfe40_process_output_path_irq_rdi0(
+			struct axi_ctrl_t *axi_ctrl)
+{
+	uint32_t ping_pong;
+	uint32_t ch0_paddr = 0;
+	/* this must be rdi image output. */
+	struct msm_free_buf *free_buf = NULL;
+	/*RDI0*/
+	if (axi_ctrl->share_ctrl->operation_mode & VFE_OUTPUTS_RDI0) {
+		free_buf = vfe40_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
+			VFE_MSG_OUTPUT_TERTIARY1, axi_ctrl);
+		if (free_buf) {
+			ping_pong = msm_camera_io_r(axi_ctrl->
+				share_ctrl->vfebase +
+				VFE_BUS_PING_PONG_STATUS);
+
+			/* Y only channel */
+			ch0_paddr = vfe40_get_ch_addr(ping_pong,
+				axi_ctrl->share_ctrl->vfebase,
+				axi_ctrl->share_ctrl->outpath.out2.ch0);
+
+			pr_debug("%s ch0 = 0x%x\n",
+				__func__, ch0_paddr);
+
+			/* Y channel */
+			vfe40_put_ch_addr(ping_pong,
+				axi_ctrl->share_ctrl->vfebase,
+				axi_ctrl->share_ctrl->outpath.out2.ch0,
+				free_buf->ch_paddr[0]);
+
+			vfe_send_outmsg(axi_ctrl,
+				MSG_ID_OUTPUT_TERTIARY1, ch0_paddr,
+				0, 0,
+				axi_ctrl->share_ctrl->outpath.out2.inst_handle);
+
+		} else {
+			axi_ctrl->share_ctrl->outpath.out2.frame_drop_cnt++;
+			pr_err("path_irq_2 irq - no free buffer for rdi0!\n");
+		}
+	}
+}
+
+static void vfe40_process_output_path_irq_rdi1(
+	struct axi_ctrl_t *axi_ctrl)
+{
+	uint32_t ping_pong;
+	uint32_t ch0_paddr = 0;
+	/* this must be rdi image output. */
+	struct msm_free_buf *free_buf = NULL;
+	/*RDI1*/
+	if (axi_ctrl->share_ctrl->operation_mode & VFE_OUTPUTS_RDI1) {
+		free_buf = vfe40_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
+			VFE_MSG_OUTPUT_TERTIARY2, axi_ctrl);
+		if (free_buf) {
+			ping_pong = msm_camera_io_r(axi_ctrl->
+				share_ctrl->vfebase +
+				VFE_BUS_PING_PONG_STATUS);
+
+			/* Y channel */
+			ch0_paddr = vfe40_get_ch_addr(ping_pong,
+				axi_ctrl->share_ctrl->vfebase,
+				axi_ctrl->share_ctrl->outpath.out3.ch0);
+			pr_debug("%s ch0 = 0x%x\n",
+				__func__, ch0_paddr);
+
+			/* Y channel */
+			vfe40_put_ch_addr(ping_pong,
+				axi_ctrl->share_ctrl->vfebase,
+				axi_ctrl->share_ctrl->outpath.out3.ch0,
+				free_buf->ch_paddr[0]);
+
+			vfe_send_outmsg(axi_ctrl,
+				MSG_ID_OUTPUT_TERTIARY2, ch0_paddr,
+				0, 0,
+				axi_ctrl->share_ctrl->outpath.out3.inst_handle);
+		} else {
+			axi_ctrl->share_ctrl->outpath.out3.frame_drop_cnt++;
+			pr_err("path_irq irq - no free buffer for rdi1!\n");
+		}
+	}
+}
+
+static uint32_t  vfe40_process_stats_irq_common(
+	struct vfe40_ctrl_type *vfe40_ctrl,
+	uint32_t statsNum, uint32_t newAddr)
+{
+	uint32_t pingpongStatus;
+	uint32_t returnAddr;
+	uint32_t pingpongAddr;
+
+	/* must be 0=ping, 1=pong */
+	pingpongStatus =
+		((msm_camera_io_r(vfe40_ctrl->share_ctrl->vfebase +
+		VFE_BUS_PING_PONG_STATUS))
+	& ((uint32_t)(1<<(statsNum + 7)))) >> (statsNum + 7);
+	/* stats bits starts at 7 */
+	CDBG("%s:statsNum %d, pingpongStatus %d\n", __func__,
+		 statsNum, pingpongStatus);
+	pingpongAddr =
+		((uint32_t)(vfe40_ctrl->share_ctrl->vfebase +
+				VFE_BUS_STATS_PING_PONG_BASE)) +
+				(VFE_STATS_BUS_REG_NUM*statsNum)*4 +
+				(1-pingpongStatus)*4;
+	returnAddr = msm_camera_io_r((uint32_t *)pingpongAddr);
+	msm_camera_io_w(newAddr, (uint32_t *)pingpongAddr);
+	return returnAddr;
+}
+
+static void vfe_send_stats_msg(
+	struct vfe40_ctrl_type *vfe40_ctrl,
+	uint32_t bufAddress, uint32_t statsNum)
+{
+	int rc = 0;
+	void *vaddr = NULL;
+	/* fill message with right content. */
+	/* @todo This is causing issues, need further investigate */
+	/* spin_lock_irqsave(&ctrl->state_lock, flags); */
+	struct isp_msg_stats msgStats;
+	uint32_t stats_type;
+	msgStats.frameCounter = vfe40_ctrl->share_ctrl->vfeFrameId;
+	if (vfe40_ctrl->simultaneous_sof_stat)
+		msgStats.frameCounter--;
+	msgStats.buffer = bufAddress;
+	switch (statsNum) {
+	case statsBgNum:{
+		msgStats.id = MSG_ID_STATS_BG;
+		stats_type = MSM_STATS_TYPE_BG;
+		rc = vfe40_ctrl->stats_ops.dispatch(
+				vfe40_ctrl->stats_ops.stats_ctrl,
+				stats_type, bufAddress,
+				&msgStats.buf_idx, &vaddr, &msgStats.fd,
+				vfe40_ctrl->stats_ops.client);
+		}
+		break;
+	case statsBeNum:{
+		msgStats.id = MSG_ID_STATS_BE;
+		stats_type = MSM_STATS_TYPE_BE;
+		rc = vfe40_ctrl->stats_ops.dispatch(
+				vfe40_ctrl->stats_ops.stats_ctrl,
+				stats_type, bufAddress,
+				&msgStats.buf_idx, &vaddr, &msgStats.fd,
+				vfe40_ctrl->stats_ops.client);
+		}
+		break;
+	case statsBfNum:{
+		msgStats.id = MSG_ID_STATS_BF;
+		stats_type =  MSM_STATS_TYPE_BF;
+		rc = vfe40_ctrl->stats_ops.dispatch(
+				vfe40_ctrl->stats_ops.stats_ctrl,
+				stats_type, bufAddress,
+				&msgStats.buf_idx, &vaddr, &msgStats.fd,
+				vfe40_ctrl->stats_ops.client);
+		}
+		break;
+	case statsAwbNum: {
+		msgStats.id = MSG_ID_STATS_AWB;
+		rc = vfe40_ctrl->stats_ops.dispatch(
+				vfe40_ctrl->stats_ops.stats_ctrl,
+				MSM_STATS_TYPE_AWB, bufAddress,
+				&msgStats.buf_idx, &vaddr, &msgStats.fd,
+				vfe40_ctrl->stats_ops.client);
+		}
+		break;
+
+	case statsIhistNum: {
+		msgStats.id = MSG_ID_STATS_IHIST;
+		rc = vfe40_ctrl->stats_ops.dispatch(
+				vfe40_ctrl->stats_ops.stats_ctrl,
+				MSM_STATS_TYPE_IHIST, bufAddress,
+				&msgStats.buf_idx, &vaddr, &msgStats.fd,
+				vfe40_ctrl->stats_ops.client);
+		}
+		break;
+	case statsRsNum: {
+		msgStats.id = MSG_ID_STATS_RS;
+		rc = vfe40_ctrl->stats_ops.dispatch(
+				vfe40_ctrl->stats_ops.stats_ctrl,
+				MSM_STATS_TYPE_RS, bufAddress,
+				&msgStats.buf_idx, &vaddr, &msgStats.fd,
+				vfe40_ctrl->stats_ops.client);
+		}
+		break;
+	case statsCsNum: {
+		msgStats.id = MSG_ID_STATS_CS;
+		rc = vfe40_ctrl->stats_ops.dispatch(
+				vfe40_ctrl->stats_ops.stats_ctrl,
+				MSM_STATS_TYPE_CS, bufAddress,
+				&msgStats.buf_idx, &vaddr, &msgStats.fd,
+				vfe40_ctrl->stats_ops.client);
+		}
+		break;
+	case statsSkinNum: {
+		msgStats.id = MSG_ID_STATS_BHIST;
+		rc = vfe40_ctrl->stats_ops.dispatch(
+				vfe40_ctrl->stats_ops.stats_ctrl,
+				MSM_STATS_TYPE_BHIST, bufAddress,
+				&msgStats.buf_idx, &vaddr, &msgStats.fd,
+				vfe40_ctrl->stats_ops.client);
+		}
+		break;
+
+	default:
+		goto stats_done;
+	}
+	if (rc == 0) {
+		msgStats.buffer = (uint32_t)vaddr;
+		v4l2_subdev_notify(&vfe40_ctrl->subdev,
+			NOTIFY_VFE_MSG_STATS,
+			&msgStats);
+	} else {
+		pr_err("%s: paddr to idx mapping error, stats_id = %d, paddr = 0x%d",
+			 __func__, msgStats.id, msgStats.buffer);
+	}
+stats_done:
+	/* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
+	return;
+}
+
+static void vfe_send_comp_stats_msg(
+	struct vfe40_ctrl_type *vfe40_ctrl, uint32_t status_bits)
+{
+	struct msm_stats_buf msgStats;
+	uint32_t temp;
+
+	msgStats.frame_id = vfe40_ctrl->share_ctrl->vfeFrameId;
+	if (vfe40_ctrl->simultaneous_sof_stat)
+		msgStats.frame_id--;
+
+	msgStats.status_bits = status_bits;
+
+	msgStats.aec.buff = vfe40_ctrl->bgStatsControl.bufToRender;
+	msgStats.awb.buff = vfe40_ctrl->awbStatsControl.bufToRender;
+	msgStats.af.buff = vfe40_ctrl->bfStatsControl.bufToRender;
+
+	msgStats.ihist.buff = vfe40_ctrl->ihistStatsControl.bufToRender;
+	msgStats.rs.buff = vfe40_ctrl->rsStatsControl.bufToRender;
+	msgStats.cs.buff = vfe40_ctrl->csStatsControl.bufToRender;
+
+	temp = msm_camera_io_r(
+		vfe40_ctrl->share_ctrl->vfebase + VFE_STATS_AWB_SGW_CFG);
+	msgStats.awb_ymin = (0xFF00 & temp) >> 8;
+
+	v4l2_subdev_notify(&vfe40_ctrl->subdev,
+				NOTIFY_VFE_MSG_COMP_STATS,
+				&msgStats);
+}
+
+static void vfe40_process_stats_be_irq(struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	unsigned long flags;
+	uint32_t addr;
+	uint32_t stats_type;
+	stats_type = MSM_STATS_TYPE_BE;
+	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, stats_type);
+	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+	if (addr) {
+		vfe40_ctrl->beStatsControl.bufToRender =
+			vfe40_process_stats_irq_common(vfe40_ctrl, statsBeNum,
+			addr);
+
+		vfe_send_stats_msg(vfe40_ctrl,
+			vfe40_ctrl->beStatsControl.bufToRender, statsBeNum);
+	} else{
+		vfe40_ctrl->beStatsControl.droppedStatsFrameCount++;
+		CDBG("%s: droppedStatsFrameCount = %d", __func__,
+			vfe40_ctrl->beStatsControl.droppedStatsFrameCount);
+	}
+}
+
+static void vfe40_process_stats_bg_irq(struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	unsigned long flags;
+	uint32_t addr;
+	uint32_t stats_type;
+	stats_type = MSM_STATS_TYPE_BG;
+	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, stats_type);
+	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+	if (addr) {
+		vfe40_ctrl->bgStatsControl.bufToRender =
+			vfe40_process_stats_irq_common(vfe40_ctrl, statsBgNum,
+			addr);
+
+		vfe_send_stats_msg(vfe40_ctrl,
+			vfe40_ctrl->bgStatsControl.bufToRender, statsBgNum);
+	} else{
+		vfe40_ctrl->bgStatsControl.droppedStatsFrameCount++;
+		CDBG("%s: droppedStatsFrameCount = %d", __func__,
+			vfe40_ctrl->bgStatsControl.droppedStatsFrameCount);
+	}
+}
+
+static void vfe40_process_stats_awb_irq(struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	unsigned long flags;
+	uint32_t addr;
+	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_AWB);
+	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+	if (addr) {
+		vfe40_ctrl->awbStatsControl.bufToRender =
+			vfe40_process_stats_irq_common(vfe40_ctrl, statsAwbNum,
+			addr);
+
+		vfe_send_stats_msg(vfe40_ctrl,
+			vfe40_ctrl->awbStatsControl.bufToRender, statsAwbNum);
+	} else{
+		vfe40_ctrl->awbStatsControl.droppedStatsFrameCount++;
+		CDBG("%s: droppedStatsFrameCount = %d", __func__,
+			vfe40_ctrl->awbStatsControl.droppedStatsFrameCount);
+	}
+}
+
+static void vfe40_process_stats_bf_irq(struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	unsigned long flags;
+	uint32_t addr;
+	uint32_t stats_type;
+	stats_type = MSM_STATS_TYPE_BF;
+	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, stats_type);
+	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+	if (addr) {
+		vfe40_ctrl->bfStatsControl.bufToRender =
+			vfe40_process_stats_irq_common(vfe40_ctrl, statsBfNum,
+			addr);
+
+		vfe_send_stats_msg(vfe40_ctrl,
+			vfe40_ctrl->bfStatsControl.bufToRender, statsBfNum);
+	} else{
+		vfe40_ctrl->bfStatsControl.droppedStatsFrameCount++;
+		CDBG("%s: droppedStatsFrameCount = %d", __func__,
+			vfe40_ctrl->bfStatsControl.droppedStatsFrameCount);
+	}
+}
+
+static void vfe40_process_stats_bhist_irq(struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	unsigned long flags;
+	uint32_t addr;
+	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_BHIST);
+	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+	if (addr) {
+		vfe40_ctrl->bhistStatsControl.bufToRender =
+			vfe40_process_stats_irq_common(vfe40_ctrl,
+				statsSkinNum, addr);
+
+		vfe_send_stats_msg(vfe40_ctrl,
+			vfe40_ctrl->bhistStatsControl.bufToRender,
+			statsSkinNum);
+	} else{
+		vfe40_ctrl->bhistStatsControl.droppedStatsFrameCount++;
+		CDBG("%s: droppedStatsFrameCount = %d", __func__,
+			vfe40_ctrl->bhistStatsControl.droppedStatsFrameCount);
+	}
+}
+
+static void vfe40_process_stats_ihist_irq(struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	unsigned long flags;
+	uint32_t addr;
+	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_IHIST);
+	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+	if (addr) {
+		vfe40_ctrl->ihistStatsControl.bufToRender =
+			vfe40_process_stats_irq_common(
+			vfe40_ctrl, statsIhistNum, addr);
+
+		vfe_send_stats_msg(vfe40_ctrl,
+			vfe40_ctrl->ihistStatsControl.bufToRender,
+			statsIhistNum);
+	} else {
+		vfe40_ctrl->ihistStatsControl.droppedStatsFrameCount++;
+		CDBG("%s: droppedStatsFrameCount = %d", __func__,
+			vfe40_ctrl->ihistStatsControl.droppedStatsFrameCount);
+	}
+}
+
+static void vfe40_process_stats_rs_irq(struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	unsigned long flags;
+	uint32_t addr;
+	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_RS);
+	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+	if (addr) {
+		vfe40_ctrl->rsStatsControl.bufToRender =
+			vfe40_process_stats_irq_common(vfe40_ctrl, statsRsNum,
+			addr);
+
+		vfe_send_stats_msg(vfe40_ctrl,
+			vfe40_ctrl->rsStatsControl.bufToRender, statsRsNum);
+	} else {
+		vfe40_ctrl->rsStatsControl.droppedStatsFrameCount++;
+		CDBG("%s: droppedStatsFrameCount = %d", __func__,
+			vfe40_ctrl->rsStatsControl.droppedStatsFrameCount);
+	}
+}
+
+static void vfe40_process_stats_cs_irq(struct vfe40_ctrl_type *vfe40_ctrl)
+{
+	unsigned long flags;
+	uint32_t addr;
+	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_CS);
+	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+	if (addr) {
+		vfe40_ctrl->csStatsControl.bufToRender =
+			vfe40_process_stats_irq_common(vfe40_ctrl, statsCsNum,
+			addr);
+
+			vfe_send_stats_msg(vfe40_ctrl,
+				vfe40_ctrl->csStatsControl.bufToRender,
+				statsCsNum);
+	} else {
+		vfe40_ctrl->csStatsControl.droppedStatsFrameCount++;
+		CDBG("%s: droppedStatsFrameCount = %d", __func__,
+			vfe40_ctrl->csStatsControl.droppedStatsFrameCount);
+	}
+}
+
+static void vfe40_process_stats(struct vfe40_ctrl_type *vfe40_ctrl,
+	uint32_t status_bits)
+{
+	unsigned long flags;
+	int32_t process_stats = false;
+	uint32_t addr;
+	uint32_t stats_type;
+
+	CDBG("%s, stats = 0x%x\n", __func__, status_bits);
+	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+
+	stats_type = MSM_STATS_TYPE_BE;
+	if (status_bits & VFE_IRQ_STATUS0_STATS_BE) {
+		addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl,
+				stats_type);
+		if (addr) {
+			vfe40_ctrl->beStatsControl.bufToRender =
+				vfe40_process_stats_irq_common(
+				vfe40_ctrl, statsBeNum, addr);
+			process_stats = true;
+		} else{
+			vfe40_ctrl->beStatsControl.bufToRender = 0;
+			vfe40_ctrl->beStatsControl.droppedStatsFrameCount++;
+		}
+	} else {
+		vfe40_ctrl->beStatsControl.bufToRender = 0;
+	}
+
+	stats_type = MSM_STATS_TYPE_BG;
+	if (status_bits & VFE_IRQ_STATUS0_STATS_BG) {
+		addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl,
+				stats_type);
+		if (addr) {
+			vfe40_ctrl->bgStatsControl.bufToRender =
+				vfe40_process_stats_irq_common(
+				vfe40_ctrl, statsBgNum, addr);
+			process_stats = true;
+		} else{
+			vfe40_ctrl->bgStatsControl.bufToRender = 0;
+			vfe40_ctrl->bgStatsControl.droppedStatsFrameCount++;
+		}
+	} else {
+		vfe40_ctrl->bgStatsControl.bufToRender = 0;
+	}
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_AWB) {
+		addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl,
+			MSM_STATS_TYPE_AWB);
+		if (addr) {
+			vfe40_ctrl->awbStatsControl.bufToRender =
+				vfe40_process_stats_irq_common(
+				vfe40_ctrl, statsAwbNum,
+				addr);
+			process_stats = true;
+		} else{
+			vfe40_ctrl->awbStatsControl.droppedStatsFrameCount++;
+			vfe40_ctrl->awbStatsControl.bufToRender = 0;
+		}
+	} else {
+		vfe40_ctrl->awbStatsControl.bufToRender = 0;
+	}
+
+	stats_type = MSM_STATS_TYPE_BF;
+	if (status_bits & VFE_IRQ_STATUS0_STATS_BF) {
+		addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl,
+					stats_type);
+		if (addr) {
+			vfe40_ctrl->bfStatsControl.bufToRender =
+				vfe40_process_stats_irq_common(
+				vfe40_ctrl, statsBfNum,
+				addr);
+			process_stats = true;
+		} else {
+			vfe40_ctrl->bfStatsControl.bufToRender = 0;
+			vfe40_ctrl->bfStatsControl.droppedStatsFrameCount++;
+		}
+	} else {
+		vfe40_ctrl->bfStatsControl.bufToRender = 0;
+	}
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_IHIST) {
+		addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl,
+					MSM_STATS_TYPE_IHIST);
+		if (addr) {
+			vfe40_ctrl->ihistStatsControl.bufToRender =
+				vfe40_process_stats_irq_common(
+				vfe40_ctrl, statsIhistNum,
+				addr);
+			process_stats = true;
+		} else {
+			vfe40_ctrl->ihistStatsControl.droppedStatsFrameCount++;
+			vfe40_ctrl->ihistStatsControl.bufToRender = 0;
+		}
+	} else {
+		vfe40_ctrl->ihistStatsControl.bufToRender = 0;
+	}
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_RS) {
+		addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl,
+					MSM_STATS_TYPE_RS);
+		if (addr) {
+			vfe40_ctrl->rsStatsControl.bufToRender =
+				vfe40_process_stats_irq_common(
+				vfe40_ctrl, statsRsNum,
+				addr);
+			process_stats = true;
+		} else {
+			vfe40_ctrl->rsStatsControl.droppedStatsFrameCount++;
+			vfe40_ctrl->rsStatsControl.bufToRender = 0;
+		}
+	} else {
+		vfe40_ctrl->rsStatsControl.bufToRender = 0;
+	}
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_CS) {
+		addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl,
+					MSM_STATS_TYPE_CS);
+		if (addr) {
+			vfe40_ctrl->csStatsControl.bufToRender =
+				vfe40_process_stats_irq_common(
+				vfe40_ctrl, statsCsNum,
+				addr);
+			process_stats = true;
+		} else {
+			vfe40_ctrl->csStatsControl.droppedStatsFrameCount++;
+			vfe40_ctrl->csStatsControl.bufToRender = 0;
+		}
+	} else {
+		vfe40_ctrl->csStatsControl.bufToRender = 0;
+	}
+	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+	if (process_stats)
+		vfe_send_comp_stats_msg(vfe40_ctrl, status_bits);
+
+	return;
+}
+
+static void vfe40_process_stats_irq(
+	struct vfe40_ctrl_type *vfe40_ctrl, uint32_t irqstatus)
+{
+	uint32_t status_bits = VFE_COM_STATUS & irqstatus;
+	if ((vfe40_ctrl->hfr_mode != HFR_MODE_OFF) &&
+		(vfe40_ctrl->share_ctrl->vfeFrameId %
+		 vfe40_ctrl->hfr_mode != 0)) {
+		CDBG("Skip the stats when HFR enabled\n");
+		return;
+	}
+
+	vfe40_process_stats(vfe40_ctrl, status_bits);
+	return;
+}
+
+static void vfe40_process_irq(
+	struct vfe40_ctrl_type *vfe40_ctrl, uint32_t irqstatus)
+{
+	if (irqstatus &
+		VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK_0) {
+		vfe40_process_stats_irq(vfe40_ctrl, irqstatus);
+		return;
+	}
+
+	switch (irqstatus) {
+	case VFE_IRQ_STATUS0_CAMIF_SOF_MASK:
+		CDBG("irq	camifSofIrq\n");
+		vfe40_process_camif_sof_irq(vfe40_ctrl);
+		break;
+	case VFE_IRQ_STATUS0_REG_UPDATE_MASK:
+		CDBG("irq	regUpdateIrq\n");
+		vfe40_process_reg_update_irq(vfe40_ctrl);
+		break;
+	case VFE_IRQ_STATUS0_RDI0_REG_UPDATE:
+		CDBG("irq	rdi0 regUpdateIrq\n");
+		vfe40_process_rdi0_reg_update_irq(vfe40_ctrl);
+		break;
+	case VFE_IRQ_STATUS0_RDI1_REG_UPDATE:
+		CDBG("irq	rdi1 regUpdateIrq\n");
+		vfe40_process_rdi1_reg_update_irq(vfe40_ctrl);
+		break;
+	case VFE_IMASK_WHILE_STOPPING_0:
+		CDBG("irq	resetAckIrq\n");
+		vfe40_process_reset_irq(vfe40_ctrl);
+		break;
+	case VFE_IRQ_STATUS0_STATS_BG:
+		CDBG("Stats BG irq occured.\n");
+		vfe40_process_stats_bg_irq(vfe40_ctrl);
+		break;
+	case VFE_IRQ_STATUS0_STATS_BE:
+		CDBG("Stats BE irq occured.\n");
+		vfe40_process_stats_be_irq(vfe40_ctrl);
+		break;
+	case VFE_IRQ_STATUS0_STATS_BF:
+		CDBG("Stats BF irq occured.\n");
+		vfe40_process_stats_bf_irq(vfe40_ctrl);
+		break;
+	case VFE_IRQ_STATUS0_STATS_AWB:
+		CDBG("Stats AWB irq occured.\n");
+		vfe40_process_stats_awb_irq(vfe40_ctrl);
+		break;
+	case VFE_IRQ_STATUS0_STATS_SKIN_BHIST:
+		CDBG("Stats BHIST irq occured.\n");
+		vfe40_process_stats_bhist_irq(vfe40_ctrl);
+		break;
+	case VFE_IRQ_STATUS0_STATS_IHIST:
+		CDBG("Stats IHIST irq occured.\n");
+		vfe40_process_stats_ihist_irq(vfe40_ctrl);
+		break;
+	case VFE_IRQ_STATUS0_STATS_RS:
+		CDBG("Stats RS irq occured.\n");
+		vfe40_process_stats_rs_irq(vfe40_ctrl);
+		break;
+	case VFE_IRQ_STATUS0_STATS_CS:
+		CDBG("Stats CS irq occured.\n");
+		vfe40_process_stats_cs_irq(vfe40_ctrl);
+		break;
+	case VFE_IRQ_STATUS1_SYNC_TIMER0:
+		CDBG("SYNC_TIMER 0 irq occured.\n");
+		vfe40_send_isp_msg(&vfe40_ctrl->subdev,
+			vfe40_ctrl->share_ctrl->vfeFrameId,
+			MSG_ID_SYNC_TIMER0_DONE);
+		break;
+	case VFE_IRQ_STATUS1_SYNC_TIMER1:
+		CDBG("SYNC_TIMER 1 irq occured.\n");
+		vfe40_send_isp_msg(&vfe40_ctrl->subdev,
+			vfe40_ctrl->share_ctrl->vfeFrameId,
+			MSG_ID_SYNC_TIMER1_DONE);
+		break;
+	case VFE_IRQ_STATUS1_SYNC_TIMER2:
+		CDBG("SYNC_TIMER 2 irq occured.\n");
+		vfe40_send_isp_msg(&vfe40_ctrl->subdev,
+			vfe40_ctrl->share_ctrl->vfeFrameId,
+			MSG_ID_SYNC_TIMER2_DONE);
+		break;
+	default:
+		pr_err("Invalid IRQ status\n");
+	}
+}
+
+static void axi40_do_tasklet(unsigned long data)
+{
+	unsigned long flags;
+	struct axi_ctrl_t *axi_ctrl = (struct axi_ctrl_t *)data;
+	struct vfe40_ctrl_type *vfe40_ctrl = axi_ctrl->share_ctrl->vfe40_ctrl;
+	struct vfe40_isr_queue_cmd *qcmd = NULL;
+	int stat_interrupt;
+
+	CDBG("=== axi40_do_tasklet start ===\n");
+
+	while (atomic_read(&irq_cnt)) {
+		spin_lock_irqsave(&axi_ctrl->tasklet_lock, flags);
+		qcmd = list_first_entry(&axi_ctrl->tasklet_q,
+			struct vfe40_isr_queue_cmd, list);
+		atomic_sub(1, &irq_cnt);
+
+		if (!qcmd) {
+			spin_unlock_irqrestore(&axi_ctrl->tasklet_lock,
+				flags);
+			return;
+		}
+
+		list_del(&qcmd->list);
+		spin_unlock_irqrestore(&axi_ctrl->tasklet_lock,
+			flags);
+
+		if (axi_ctrl->share_ctrl->stats_comp) {
+			stat_interrupt = (qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK_0);
+		} else {
+			stat_interrupt =
+				(qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_BG) |
+				(qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_BE) |
+				(qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_AWB) |
+				(qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_BF) |
+				(qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_IHIST) |
+				(qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_RS) |
+				(qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_CS);
+		}
+		if (qcmd->vfeInterruptStatus0 &
+				VFE_IRQ_STATUS0_CAMIF_SOF_MASK) {
+			if (stat_interrupt)
+				vfe40_ctrl->simultaneous_sof_stat = 1;
+			v4l2_subdev_notify(&vfe40_ctrl->subdev,
+				NOTIFY_VFE_IRQ,
+				(void *)VFE_IRQ_STATUS0_CAMIF_SOF_MASK);
+		}
+
+		/* interrupt to be processed,  *qcmd has the payload.  */
+		if (qcmd->vfeInterruptStatus0 &
+				VFE_IRQ_STATUS0_REG_UPDATE_MASK)
+			v4l2_subdev_notify(&vfe40_ctrl->subdev,
+				NOTIFY_VFE_IRQ,
+				(void *)VFE_IRQ_STATUS0_REG_UPDATE_MASK);
+
+		if (qcmd->vfeInterruptStatus1 &
+				VFE_IRQ_STATUS0_RDI0_REG_UPDATE_MASK)
+			v4l2_subdev_notify(&vfe40_ctrl->subdev,
+				NOTIFY_VFE_IRQ,
+				(void *)VFE_IRQ_STATUS0_RDI0_REG_UPDATE);
+
+		if (qcmd->vfeInterruptStatus1 &
+				VFE_IRQ_STATUS0_RDI1_REG_UPDATE_MASK)
+			v4l2_subdev_notify(&vfe40_ctrl->subdev,
+				NOTIFY_VFE_IRQ,
+				(void *)VFE_IRQ_STATUS0_RDI1_REG_UPDATE);
+
+		if (qcmd->vfeInterruptStatus0 &
+				VFE_IMASK_WHILE_STOPPING_0)
+			v4l2_subdev_notify(&vfe40_ctrl->subdev,
+				NOTIFY_VFE_IRQ,
+				(void *)VFE_IMASK_WHILE_STOPPING_0);
+
+		if (atomic_read(&axi_ctrl->share_ctrl->handle_common_irq)) {
+			if (qcmd->vfeInterruptStatus1 &
+					VFE40_IMASK_COMMON_ERROR_ONLY_1) {
+				pr_err("irq	errorIrq\n");
+				vfe40_process_common_error_irq(
+					axi_ctrl,
+					qcmd->vfeInterruptStatus1 &
+					VFE40_IMASK_COMMON_ERROR_ONLY_1);
+			}
+
+			v4l2_subdev_notify(&axi_ctrl->subdev,
+				NOTIFY_AXI_IRQ,
+				(void *)qcmd->vfeInterruptStatus0);
+		}
+
+		if (atomic_read(&axi_ctrl->share_ctrl->vstate)) {
+			if (qcmd->vfeInterruptStatus1 &
+					VFE40_IMASK_VFE_ERROR_ONLY_1) {
+				pr_err("irq	errorIrq\n");
+				vfe40_process_error_irq(
+					axi_ctrl,
+					qcmd->vfeInterruptStatus1 &
+					VFE40_IMASK_VFE_ERROR_ONLY_1);
+			}
+
+			/* then process stats irq. */
+			if (axi_ctrl->share_ctrl->stats_comp) {
+				/* process stats comb interrupt. */
+				if (qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK_0) {
+					CDBG("Stats composite irq occured.\n");
+					v4l2_subdev_notify(&vfe40_ctrl->subdev,
+					NOTIFY_VFE_IRQ,
+					(void *)qcmd->vfeInterruptStatus0);
+				}
+			} else {
+				/* process individual stats interrupt. */
+				if (qcmd->vfeInterruptStatus0 &
+						VFE_IRQ_STATUS0_STATS_BG)
+					v4l2_subdev_notify(&vfe40_ctrl->subdev,
+					NOTIFY_VFE_IRQ,
+					(void *)VFE_IRQ_STATUS0_STATS_BG);
+
+				if (qcmd->vfeInterruptStatus0 &
+						VFE_IRQ_STATUS0_STATS_BE)
+					v4l2_subdev_notify(&vfe40_ctrl->subdev,
+					NOTIFY_VFE_IRQ,
+					(void *)VFE_IRQ_STATUS0_STATS_BE);
+
+				if (qcmd->vfeInterruptStatus0 &
+						VFE_IRQ_STATUS0_STATS_AWB)
+					v4l2_subdev_notify(&vfe40_ctrl->subdev,
+					NOTIFY_VFE_IRQ,
+					(void *)VFE_IRQ_STATUS0_STATS_AWB);
+
+				if (qcmd->vfeInterruptStatus0 &
+						VFE_IRQ_STATUS0_STATS_BF)
+					v4l2_subdev_notify(&vfe40_ctrl->subdev,
+					NOTIFY_VFE_IRQ,
+					(void *)VFE_IRQ_STATUS0_STATS_BF);
+				if (qcmd->vfeInterruptStatus0 &
+					VFE_IRQ_STATUS0_STATS_SKIN_BHIST)
+					v4l2_subdev_notify(&vfe40_ctrl->subdev,
+					NOTIFY_VFE_IRQ,
+					(void *)
+					VFE_IRQ_STATUS0_STATS_SKIN_BHIST);
+
+				if (qcmd->vfeInterruptStatus0 &
+						VFE_IRQ_STATUS0_STATS_IHIST)
+					v4l2_subdev_notify(&vfe40_ctrl->subdev,
+					NOTIFY_VFE_IRQ,
+					(void *)VFE_IRQ_STATUS0_STATS_IHIST);
+
+				if (qcmd->vfeInterruptStatus0 &
+						VFE_IRQ_STATUS0_STATS_RS)
+					v4l2_subdev_notify(&vfe40_ctrl->subdev,
+					NOTIFY_VFE_IRQ,
+					(void *)VFE_IRQ_STATUS0_STATS_RS);
+
+				if (qcmd->vfeInterruptStatus0 &
+						VFE_IRQ_STATUS0_STATS_CS)
+					v4l2_subdev_notify(&vfe40_ctrl->subdev,
+					NOTIFY_VFE_IRQ,
+					(void *)VFE_IRQ_STATUS0_STATS_CS);
+
+				if (qcmd->vfeInterruptStatus1 &
+						VFE_IRQ_STATUS1_SYNC_TIMER0)
+					v4l2_subdev_notify(&vfe40_ctrl->subdev,
+					NOTIFY_VFE_IRQ,
+					(void *)VFE_IRQ_STATUS1_SYNC_TIMER0);
+
+				if (qcmd->vfeInterruptStatus1 &
+						VFE_IRQ_STATUS1_SYNC_TIMER1)
+					v4l2_subdev_notify(&vfe40_ctrl->subdev,
+					NOTIFY_VFE_IRQ,
+					(void *)VFE_IRQ_STATUS1_SYNC_TIMER1);
+
+				if (qcmd->vfeInterruptStatus1 &
+						VFE_IRQ_STATUS1_SYNC_TIMER2)
+					v4l2_subdev_notify(&vfe40_ctrl->subdev,
+					NOTIFY_VFE_IRQ,
+					(void *)VFE_IRQ_STATUS1_SYNC_TIMER2);
+			}
+		}
+		vfe40_ctrl->simultaneous_sof_stat = 0;
+		kfree(qcmd);
+	}
+	CDBG("=== axi40_do_tasklet end ===\n");
+}
+
+static irqreturn_t vfe40_parse_irq(int irq_num, void *data)
+{
+	unsigned long flags;
+	struct vfe40_irq_status irq;
+	struct vfe40_isr_queue_cmd *qcmd;
+	struct axi_ctrl_t *axi_ctrl = data;
+
+	CDBG("vfe_parse_irq\n");
+
+	vfe40_read_irq_status(axi_ctrl, &irq);
+
+	if ((irq.vfeIrqStatus0 == 0) && (irq.vfeIrqStatus1 == 0)) {
+		CDBG("vfe_parse_irq: vfeIrqStatus0 & 1 are both 0!\n");
+		return IRQ_HANDLED;
+	}
+
+	qcmd = kzalloc(sizeof(struct vfe40_isr_queue_cmd),
+		GFP_ATOMIC);
+	if (!qcmd) {
+		pr_err("vfe_parse_irq: qcmd malloc failed!\n");
+		return IRQ_HANDLED;
+	}
+
+	spin_lock_irqsave(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
+	if (axi_ctrl->share_ctrl->stop_ack_pending) {
+		irq.vfeIrqStatus0 &= VFE_IMASK_WHILE_STOPPING_0;
+		irq.vfeIrqStatus1 &= VFE_IMASK_WHILE_STOPPING_1;
+	}
+	spin_unlock_irqrestore(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
+
+	CDBG("vfe_parse_irq: Irq_status0 = 0x%x, Irq_status1 = 0x%x.\n",
+		irq.vfeIrqStatus0, irq.vfeIrqStatus1);
+
+	qcmd->vfeInterruptStatus0 = irq.vfeIrqStatus0;
+	qcmd->vfeInterruptStatus1 = irq.vfeIrqStatus1;
+
+	spin_lock_irqsave(&axi_ctrl->tasklet_lock, flags);
+	list_add_tail(&qcmd->list, &axi_ctrl->tasklet_q);
+
+	atomic_add(1, &irq_cnt);
+	spin_unlock_irqrestore(&axi_ctrl->tasklet_lock, flags);
+	tasklet_schedule(&axi_ctrl->vfe40_tasklet);
+	return IRQ_HANDLED;
+}
+
+int msm_axi_subdev_isr_routine(struct v4l2_subdev *sd,
+	u32 status, bool *handled)
+{
+	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+	irqreturn_t ret;
+	CDBG("%s E ", __func__);
+	ret = vfe40_parse_irq(axi_ctrl->vfeirq->start, axi_ctrl);
+	*handled = TRUE;
+	return 0;
+}
+
+static long vfe_stats_bufq_sub_ioctl(
+	struct vfe40_ctrl_type *vfe_ctrl,
+	struct msm_vfe_cfg_cmd *cmd, void *ion_client, int domain_num)
+{
+	long rc = 0;
+	switch (cmd->cmd_type) {
+	case VFE_CMD_STATS_REQBUF:
+	if (!vfe_ctrl->stats_ops.stats_ctrl) {
+		/* stats_ctrl has not been init yet */
+		rc = msm_stats_buf_ops_init(&vfe_ctrl->stats_ctrl,
+				(struct ion_client *)ion_client,
+				&vfe_ctrl->stats_ops);
+		if (rc < 0) {
+			pr_err("%s: cannot init stats ops", __func__);
+			goto end;
+		}
+		rc = vfe_ctrl->stats_ops.stats_ctrl_init(&vfe_ctrl->stats_ctrl);
+		if (rc < 0) {
+			pr_err("%s: cannot init stats_ctrl ops", __func__);
+			memset(&vfe_ctrl->stats_ops, 0,
+				sizeof(vfe_ctrl->stats_ops));
+			goto end;
+		}
+		if (sizeof(struct msm_stats_reqbuf) != cmd->length) {
+			/* error. the length not match */
+			pr_err("%s: stats reqbuf input size = %d,\n"
+				"struct size = %d, mitch match\n",
+				 __func__, cmd->length,
+				sizeof(struct msm_stats_reqbuf));
+			rc = -EINVAL ;
+			goto end;
+		}
+	}
+	rc = vfe_ctrl->stats_ops.reqbuf(
+			&vfe_ctrl->stats_ctrl,
+			(struct msm_stats_reqbuf *)cmd->value,
+			vfe_ctrl->stats_ops.client);
+	break;
+	case VFE_CMD_STATS_ENQUEUEBUF:
+	if (sizeof(struct msm_stats_buf_info) != cmd->length) {
+		/* error. the length not match */
+		pr_err("%s: stats enqueuebuf input size = %d,\n"
+			"struct size = %d, mitch match\n",
+			 __func__, cmd->length,
+			sizeof(struct msm_stats_buf_info));
+			rc = -EINVAL;
+			goto end;
+	}
+	rc = vfe_ctrl->stats_ops.enqueue_buf(
+			&vfe_ctrl->stats_ctrl,
+			(struct msm_stats_buf_info *)cmd->value,
+			vfe_ctrl->stats_ops.client, domain_num);
+	break;
+	case VFE_CMD_STATS_FLUSH_BUFQ:
+	{
+		struct msm_stats_flush_bufq *flush_req = NULL;
+		flush_req = (struct msm_stats_flush_bufq *)cmd->value;
+		if (sizeof(struct msm_stats_flush_bufq) != cmd->length) {
+			/* error. the length not match */
+			pr_err("%s: stats flush queue input size = %d,\n"
+				"struct size = %d, mitch match\n",
+				__func__, cmd->length,
+				sizeof(struct msm_stats_flush_bufq));
+			rc = -EINVAL;
+			goto end;
+	}
+	rc = vfe_ctrl->stats_ops.bufq_flush(
+			&vfe_ctrl->stats_ctrl,
+			(enum msm_stats_enum_type)flush_req->stats_type,
+			vfe_ctrl->stats_ops.client);
+	}
+	break;
+	case VFE_CMD_STATS_UNREGBUF:
+	{
+		struct msm_stats_reqbuf *req_buf = NULL;
+		req_buf = (struct msm_stats_reqbuf *)cmd->value;
+		if (sizeof(struct msm_stats_reqbuf) != cmd->length) {
+			/* error. the length not match */
+			pr_err("%s: stats reqbuf input size = %d,\n"
+				"struct size = %d, mitch match\n",
+				 __func__, cmd->length,
+				sizeof(struct msm_stats_reqbuf));
+			rc = -EINVAL ;
+			goto end;
+		}
+		rc = vfe40_stats_unregbuf(vfe_ctrl, req_buf, domain_num);
+	}
+	break;
+	default:
+		rc = -1;
+		pr_err("%s: cmd_type %d not supported", __func__,
+			cmd->cmd_type);
+	break;
+	}
+end:
+	return rc;
+}
+
+static long msm_vfe_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int subdev_cmd, void *arg)
+{
+	struct msm_cam_media_controller *pmctl =
+		(struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
+	struct vfe40_ctrl_type *vfe40_ctrl =
+		(struct vfe40_ctrl_type *)v4l2_get_subdevdata(sd);
+	struct msm_isp_cmd vfecmd;
+	struct msm_camvfe_params *vfe_params;
+	struct msm_vfe_cfg_cmd *cmd;
+	void *data;
+
+	long rc = 0;
+	struct vfe_cmd_stats_buf *scfg = NULL;
+	struct vfe_cmd_stats_ack *sack = NULL;
+
+	if (!vfe40_ctrl->share_ctrl->vfebase) {
+		pr_err("%s: base address unmapped\n", __func__);
+		return -EFAULT;
+	}
+
+	CDBG("%s\n", __func__);
+	if (subdev_cmd == VIDIOC_MSM_VFE_INIT) {
+		CDBG("%s init\n", __func__);
+		return msm_vfe_subdev_init(sd);
+	} else if (subdev_cmd == VIDIOC_MSM_VFE_RELEASE) {
+		msm_vfe_subdev_release(sd);
+		return 0;
+	}
+	vfe_params = (struct msm_camvfe_params *)arg;
+	cmd = vfe_params->vfe_cfg;
+	data = vfe_params->data;
+	switch (cmd->cmd_type) {
+	case CMD_VFE_PROCESS_IRQ:
+		vfe40_process_irq(vfe40_ctrl, (uint32_t) data);
+		return rc;
+	case VFE_CMD_STATS_REQBUF:
+	case VFE_CMD_STATS_ENQUEUEBUF:
+	case VFE_CMD_STATS_FLUSH_BUFQ:
+	case VFE_CMD_STATS_UNREGBUF:
+		/* for easy porting put in one envelope */
+		rc = vfe_stats_bufq_sub_ioctl(vfe40_ctrl,
+				cmd, vfe_params->data, pmctl->domain_num);
+		return rc;
+	default:
+		if (cmd->cmd_type != CMD_CONFIG_PING_ADDR &&
+		cmd->cmd_type != CMD_CONFIG_PONG_ADDR &&
+		cmd->cmd_type != CMD_CONFIG_FREE_BUF_ADDR &&
+		cmd->cmd_type != CMD_STATS_AEC_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_AWB_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_IHIST_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_RS_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_CS_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_BG_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_BE_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_BF_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_BHIST_BUF_RELEASE &&
+		cmd->cmd_type != CMD_VFE_PIX_SOF_COUNT_UPDATE &&
+		cmd->cmd_type != CMD_VFE_COUNT_PIX_SOF_ENABLE) {
+			if (copy_from_user(&vfecmd,
+					(void __user *)(cmd->value),
+					sizeof(vfecmd))) {
+				pr_err("%s %d: copy_from_user failed\n",
+					__func__, __LINE__);
+				return -EFAULT;
+			}
+		} else {
+			/* here eith stats release or frame release. */
+			if (cmd->cmd_type != CMD_CONFIG_PING_ADDR &&
+				cmd->cmd_type != CMD_CONFIG_PONG_ADDR &&
+				cmd->cmd_type != CMD_CONFIG_FREE_BUF_ADDR) {
+				/* then must be stats release. */
+				if (!data) {
+					pr_err("%s: data = NULL, cmd->cmd_type = %d",
+						__func__, cmd->cmd_type);
+					return -EFAULT;
+				}
+				sack = kmalloc(sizeof(struct vfe_cmd_stats_ack),
+							GFP_ATOMIC);
+				if (!sack) {
+					pr_err("%s: no mem for cmd->cmd_type = %d",
+					 __func__, cmd->cmd_type);
+					return -ENOMEM;
+				}
+				sack->nextStatsBuf = *(uint32_t *)data;
+			}
+		}
+	}
+
+	CDBG("%s: cmdType = %d\n", __func__, cmd->cmd_type);
+
+	if ((cmd->cmd_type == CMD_STATS_AF_ENABLE)    ||
+		(cmd->cmd_type == CMD_STATS_AWB_ENABLE)   ||
+		(cmd->cmd_type == CMD_STATS_IHIST_ENABLE) ||
+		(cmd->cmd_type == CMD_STATS_RS_ENABLE)    ||
+		(cmd->cmd_type == CMD_STATS_CS_ENABLE)    ||
+		(cmd->cmd_type == CMD_STATS_AEC_ENABLE)   ||
+		(cmd->cmd_type == CMD_STATS_BG_ENABLE)    ||
+		(cmd->cmd_type == CMD_STATS_BE_ENABLE)    ||
+		(cmd->cmd_type == CMD_STATS_BF_ENABLE)    ||
+		(cmd->cmd_type == CMD_STATS_BHIST_ENABLE)) {
+		struct axidata *axid;
+		axid = data;
+		if (!axid) {
+			rc = -EFAULT;
+			goto vfe40_config_done;
+		}
+		CDBG("%s: cmdType = %d\n", __func__, cmd->cmd_type);
+
+		if ((cmd->cmd_type == CMD_STATS_AF_ENABLE)    ||
+			(cmd->cmd_type == CMD_STATS_AWB_ENABLE)   ||
+			(cmd->cmd_type == CMD_STATS_IHIST_ENABLE) ||
+			(cmd->cmd_type == CMD_STATS_RS_ENABLE)    ||
+			(cmd->cmd_type == CMD_STATS_CS_ENABLE)    ||
+			(cmd->cmd_type == CMD_STATS_AEC_ENABLE)) {
+				scfg = NULL;
+				/* individual */
+				goto vfe40_config_done;
+		}
+		switch (cmd->cmd_type) {
+		case CMD_STATS_AEC_ENABLE:
+		case CMD_STATS_BG_ENABLE:
+		case CMD_STATS_BE_ENABLE:
+		case CMD_STATS_BF_ENABLE:
+		case CMD_STATS_BHIST_ENABLE:
+		case CMD_STATS_AWB_ENABLE:
+		case CMD_STATS_IHIST_ENABLE:
+		case CMD_STATS_RS_ENABLE:
+		case CMD_STATS_CS_ENABLE:
+		default:
+			pr_err("%s Unsupported cmd type %d",
+				__func__, cmd->cmd_type);
+			break;
+		}
+		goto vfe40_config_done;
+	}
+	switch (cmd->cmd_type) {
+	case CMD_GENERAL:
+		rc = vfe40_proc_general(pmctl, &vfecmd, vfe40_ctrl);
+	break;
+	case CMD_VFE_COUNT_PIX_SOF_ENABLE: {
+		int enable = *((int *)cmd->value);
+		if (enable)
+			vfe40_ctrl->vfe_sof_count_enable = TRUE;
+		else
+			vfe40_ctrl->vfe_sof_count_enable = false;
+	}
+	break;
+	case CMD_VFE_PIX_SOF_COUNT_UPDATE:
+		if (!vfe40_ctrl->vfe_sof_count_enable)
+			vfe40_ctrl->share_ctrl->vfeFrameId =
+			*((uint32_t *)vfe_params->data);
+	break;
+	case CMD_CONFIG_PING_ADDR: {
+		int path = *((int *)cmd->value);
+		struct vfe40_output_ch *outch =
+			vfe40_get_ch(path, vfe40_ctrl->share_ctrl);
+		outch->ping = *((struct msm_free_buf *)data);
+	}
+	break;
+
+	case CMD_CONFIG_PONG_ADDR: {
+		int path = *((int *)cmd->value);
+		struct vfe40_output_ch *outch =
+			vfe40_get_ch(path, vfe40_ctrl->share_ctrl);
+		outch->pong = *((struct msm_free_buf *)data);
+	}
+	break;
+
+	case CMD_CONFIG_FREE_BUF_ADDR: {
+		int path = *((int *)cmd->value);
+		struct vfe40_output_ch *outch =
+			vfe40_get_ch(path, vfe40_ctrl->share_ctrl);
+		outch->free_buf = *((struct msm_free_buf *)data);
+	}
+	break;
+
+	case CMD_SNAP_BUF_RELEASE:
+		break;
+
+	default:
+		pr_err("%s Unsupported AXI configuration %x ", __func__,
+			cmd->cmd_type);
+	break;
+	}
+vfe40_config_done:
+	kfree(scfg);
+	kfree(sack);
+	CDBG("%s done: rc = %d\n", __func__, (int) rc);
+	return rc;
+}
+
+static struct msm_cam_clk_info vfe40_clk_info[] = {
+	{"camss_top_ahb_clk", -1},
+	{"vfe_clk_src", 266670000},
+	{"camss_vfe_vfe_clk", -1},
+	{"camss_csi_vfe_clk", -1},
+	{"iface_clk", -1},
+	{"bus_clk", -1},
+	{"alt_bus_clk", -1},
+};
+
+static int msm_axi_subdev_s_crystal_freq(struct v4l2_subdev *sd,
+						u32 freq, u32 flags)
+{
+	int rc = 0;
+	int round_rate;
+	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+
+	round_rate = clk_round_rate(axi_ctrl->vfe_clk[1], freq);
+	if (rc < 0) {
+		pr_err("%s: clk_round_rate failed %d\n",
+					__func__, rc);
+		return rc;
+	}
+
+	vfe_clk_rate = round_rate;
+	rc = clk_set_rate(axi_ctrl->vfe_clk[1], round_rate);
+	if (rc < 0)
+		pr_err("%s: clk_set_rate failed %d\n",
+					__func__, rc);
+
+	return rc;
+}
+
+static const struct v4l2_subdev_core_ops msm_vfe_subdev_core_ops = {
+	.ioctl = msm_vfe_subdev_ioctl,
+};
+
+static const struct v4l2_subdev_ops msm_vfe_subdev_ops = {
+	.core = &msm_vfe_subdev_core_ops,
+};
+
+static void msm_vfe40_init_vbif_parms(void __iomem *vfe_vbif_base)
+{
+	msm_camera_io_w(0x1,
+		vfe_vbif_base + VFE40_VBIF_CLKON);
+	msm_camera_io_w(0x01010101,
+		vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF0);
+	msm_camera_io_w(0x01010101,
+		vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF1);
+	msm_camera_io_w(0x10010110,
+		vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF2);
+	msm_camera_io_w(0x10101010,
+		vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF0);
+	msm_camera_io_w(0x10101010,
+		vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF1);
+	msm_camera_io_w(0x10101010,
+		vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF2);
+	msm_camera_io_w(0x00001010,
+		vfe_vbif_base + VFE40_VBIF_OUT_RD_LIM_CONF0);
+	msm_camera_io_w(0x00001010,
+		vfe_vbif_base + VFE40_VBIF_OUT_WR_LIM_CONF0);
+	msm_camera_io_w(0x00000707,
+		vfe_vbif_base + VFE40_VBIF_DDR_OUT_MAX_BURST);
+	msm_camera_io_w(0x00000707,
+		vfe_vbif_base + VFE40_VBIF_OCMEM_OUT_MAX_BURST);
+	msm_camera_io_w(0x00000030,
+		vfe_vbif_base + VFE40_VBIF_ARB_CTL);
+	msm_camera_io_w(0x04210842,
+		vfe_vbif_base + VFE40_VBIF_DDR_ARB_CONF0);
+	msm_camera_io_w(0x04210842,
+		vfe_vbif_base + VFE40_VBIF_DDR_ARB_CONF1);
+	msm_camera_io_w(0x00000001,
+		vfe_vbif_base + VFE40_VBIF_ROUND_ROBIN_QOS_ARB);
+	msm_camera_io_w(0x22222222,
+		vfe_vbif_base + VFE40_VBIF_OUT_AXI_AMEMTYPE_CONF0);
+	msm_camera_io_w(0x00002222,
+		vfe_vbif_base + VFE40_VBIF_OUT_AXI_AMEMTYPE_CONF1);
+	msm_camera_io_w(0x00000FFF,
+		vfe_vbif_base + VFE40_VBIF_OUT_AXI_AOOO_EN);
+	msm_camera_io_w(0x0FFF0FFF,
+		vfe_vbif_base + VFE40_VBIF_OUT_AXI_AOOO);
+}
+
+int msm_axi_subdev_init(struct v4l2_subdev *sd)
+{
+	int rc = 0;
+	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+	struct msm_cam_media_controller *mctl;
+	mctl = v4l2_get_subdev_hostdata(sd);
+	if (mctl == NULL) {
+		pr_err("%s: mctl is NULL\n", __func__);
+		rc = -EINVAL;
+		goto mctl_failed;
+	}
+	axi_ctrl->share_ctrl->axi_ref_cnt++;
+	if (axi_ctrl->share_ctrl->axi_ref_cnt > 1)
+		return rc;
+
+	spin_lock_init(&axi_ctrl->tasklet_lock);
+	INIT_LIST_HEAD(&axi_ctrl->tasklet_q);
+	spin_lock_init(&axi_ctrl->share_ctrl->sd_notify_lock);
+
+	axi_ctrl->share_ctrl->vfebase = ioremap(axi_ctrl->vfemem->start,
+		resource_size(axi_ctrl->vfemem));
+	if (!axi_ctrl->share_ctrl->vfebase) {
+		rc = -ENOMEM;
+		pr_err("%s: vfe ioremap failed\n", __func__);
+		goto remap_failed;
+	}
+
+	axi_ctrl->share_ctrl->vfe_vbif_base =
+		ioremap(axi_ctrl->vfe_vbif_mem->start,
+			resource_size(axi_ctrl->vfe_vbif_mem));
+	if (!axi_ctrl->share_ctrl->vfe_vbif_base) {
+		rc = -ENOMEM;
+		pr_err("%s: vfe ioremap failed\n", __func__);
+		goto remap_failed;
+	}
+
+	if (axi_ctrl->fs_vfe) {
+		rc = regulator_enable(axi_ctrl->fs_vfe);
+		if (rc) {
+			pr_err("%s: Regulator enable failed\n",	__func__);
+			goto fs_failed;
+		}
+	}
+
+	rc = msm_cam_clk_enable(&axi_ctrl->pdev->dev, vfe40_clk_info,
+			axi_ctrl->vfe_clk, ARRAY_SIZE(vfe40_clk_info), 1);
+	if (rc < 0)
+		goto clk_enable_failed;
+
+	axi_ctrl->bus_perf_client =
+		msm_bus_scale_register_client(&vfe_bus_client_pdata);
+	if (!axi_ctrl->bus_perf_client) {
+		pr_err("%s: Registration Failed!\n", __func__);
+		axi_ctrl->bus_perf_client = 0;
+		goto bus_scale_register_failed;
+	}
+
+	msm_camera_bus_scale_cfg(axi_ctrl->bus_perf_client, S_PREVIEW);
+
+	rc = iommu_attach_device(mctl->domain, axi_ctrl->iommu_ctx);
+	if (rc < 0) {
+		pr_err("%s: imgwr attach failed rc = %d\n", __func__, rc);
+		rc = -ENODEV;
+		goto device_imgwr_attach_failed;
+	}
+
+	msm_vfe40_init_vbif_parms(axi_ctrl->share_ctrl->vfe_vbif_base);
+
+	axi_ctrl->share_ctrl->register_total = VFE40_REGISTER_TOTAL;
+
+	spin_lock_init(&axi_ctrl->share_ctrl->stop_flag_lock);
+	spin_lock_init(&axi_ctrl->share_ctrl->update_ack_lock);
+	spin_lock_init(&axi_ctrl->share_ctrl->start_ack_lock);
+	init_completion(&axi_ctrl->share_ctrl->reset_complete);
+
+	if (!axi_ctrl->use_irq_router)
+		enable_irq(axi_ctrl->vfeirq->start);
+
+	return rc;
+
+bus_scale_register_failed:
+	msm_cam_clk_enable(&axi_ctrl->pdev->dev, vfe40_clk_info,
+		axi_ctrl->vfe_clk, ARRAY_SIZE(vfe40_clk_info), 0);
+clk_enable_failed:
+	if (axi_ctrl->fs_vfe)
+		regulator_disable(axi_ctrl->fs_vfe);
+fs_failed:
+	iounmap(axi_ctrl->share_ctrl->vfebase);
+	axi_ctrl->share_ctrl->vfebase = NULL;
+remap_failed:
+	iommu_detach_device(mctl->domain, axi_ctrl->iommu_ctx);
+device_imgwr_attach_failed:
+	if (!axi_ctrl->use_irq_router)
+		disable_irq(axi_ctrl->vfeirq->start);
+mctl_failed:
+	return rc;
+}
+
+int msm_vfe_subdev_init(struct v4l2_subdev *sd)
+{
+	int rc = 0;
+	struct vfe40_ctrl_type *vfe40_ctrl =
+		(struct vfe40_ctrl_type *)v4l2_get_subdevdata(sd);
+
+	spin_lock_init(&vfe40_ctrl->state_lock);
+	spin_lock_init(&vfe40_ctrl->stats_bufq_lock);
+
+	vfe40_ctrl->update_linear = false;
+	vfe40_ctrl->update_rolloff = false;
+	vfe40_ctrl->update_la = false;
+	vfe40_ctrl->update_gamma = false;
+	vfe40_ctrl->vfe_sof_count_enable = true;
+	vfe40_ctrl->hfr_mode = HFR_MODE_OFF;
+
+	memset(&vfe40_ctrl->stats_ctrl, 0,
+		   sizeof(struct msm_stats_bufq_ctrl));
+	memset(&vfe40_ctrl->stats_ops, 0, sizeof(struct msm_stats_ops));
+
+	return rc;
+}
+
+void msm_axi_subdev_release(struct v4l2_subdev *sd)
+{
+	struct msm_cam_media_controller *pmctl =
+		(struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
+	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+	if (!axi_ctrl->share_ctrl->vfebase) {
+		pr_err("%s: base address unmapped\n", __func__);
+		return;
+	}
+
+	CDBG("%s, free_irq\n", __func__);
+	axi_ctrl->share_ctrl->axi_ref_cnt--;
+	if (axi_ctrl->share_ctrl->axi_ref_cnt > 0)
+		return;
+	if (!axi_ctrl->use_irq_router)
+		disable_irq(axi_ctrl->vfeirq->start);
+	tasklet_kill(&axi_ctrl->vfe40_tasklet);
+
+	iommu_detach_device(pmctl->domain, axi_ctrl->iommu_ctx);
+
+	msm_cam_clk_enable(&axi_ctrl->pdev->dev, vfe40_clk_info,
+			axi_ctrl->vfe_clk, ARRAY_SIZE(vfe40_clk_info), 0);
+	if (axi_ctrl->fs_vfe)
+		regulator_disable(axi_ctrl->fs_vfe);
+
+	iounmap(axi_ctrl->share_ctrl->vfebase);
+	iounmap(axi_ctrl->share_ctrl->vfe_vbif_base);
+	axi_ctrl->share_ctrl->vfebase = NULL;
+
+	if (atomic_read(&irq_cnt))
+		pr_warning("%s, Warning IRQ Count not ZERO\n", __func__);
+
+	msm_camera_bus_scale_cfg(axi_ctrl->bus_perf_client, S_EXIT);
+	axi_ctrl->bus_perf_client = 0;
+
+	msm_vfe_subdev_release(&axi_ctrl->share_ctrl->vfe40_ctrl->subdev);
+}
+
+void msm_vfe_subdev_release(struct v4l2_subdev *sd)
+{
+	struct vfe40_ctrl_type *vfe40_ctrl =
+		(struct vfe40_ctrl_type *)v4l2_get_subdevdata(sd);
+	CDBG("vfe subdev release %p\n",
+		vfe40_ctrl->share_ctrl->vfebase);
+}
+
+void axi_abort(struct axi_ctrl_t *axi_ctrl)
+{
+	uint8_t  axi_busy_flag = true;
+	unsigned long flags;
+	/* axi halt command. */
+
+	spin_lock_irqsave(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
+	axi_ctrl->share_ctrl->stop_ack_pending  = TRUE;
+	spin_unlock_irqrestore(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
+	msm_camera_io_w(AXI_HALT,
+		axi_ctrl->share_ctrl->vfebase + VFE_AXI_CMD);
+	wmb();
+	while (axi_busy_flag) {
+		if (msm_camera_io_r(
+			axi_ctrl->share_ctrl->vfebase + VFE_AXI_STATUS) & 0x1)
+			axi_busy_flag = false;
+	}
+	/* Ensure the write order while writing
+	* to the command register using the barrier */
+	msm_camera_io_w_mb(AXI_HALT_CLEAR,
+		axi_ctrl->share_ctrl->vfebase + VFE_AXI_CMD);
+
+	/* after axi halt, then ok to apply global reset.
+	* enable reset_ack and async timer interrupt only while
+	* stopping the pipeline.*/
+	msm_camera_io_w(0x80000000,
+		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_0);
+	msm_camera_io_w(0xF0000000,
+		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+	/* Ensure the write order while writing
+	* to the command register using the barrier */
+	msm_camera_io_w_mb(VFE_RESET_UPON_STOP_CMD,
+		axi_ctrl->share_ctrl->vfebase + VFE_GLOBAL_RESET);
+	if (axi_ctrl->share_ctrl->sync_abort)
+		wait_for_completion_interruptible(
+			&axi_ctrl->share_ctrl->reset_complete);
+}
+
+int axi_config_buffers(struct axi_ctrl_t *axi_ctrl,
+	struct msm_camera_vfe_params_t vfe_params)
+{
+	uint16_t vfe_mode = axi_ctrl->share_ctrl->current_mode
+			& ~(VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1);
+	int rc = 0;
+	switch (vfe_params.cmd_type) {
+	case AXI_CMD_PREVIEW:
+		if (vfe_mode) {
+			if ((axi_ctrl->share_ctrl->current_mode &
+				VFE_OUTPUTS_PREVIEW_AND_VIDEO) ||
+				(axi_ctrl->share_ctrl->current_mode &
+				VFE_OUTPUTS_PREVIEW))
+				/* Configure primary channel */
+				rc = configure_pingpong_buffers(
+					VFE_MSG_START,
+					VFE_MSG_OUTPUT_PRIMARY,
+					axi_ctrl);
+			else
+			/* Configure secondary channel */
+				rc = configure_pingpong_buffers(
+					VFE_MSG_START,
+					VFE_MSG_OUTPUT_SECONDARY,
+					axi_ctrl);
+		}
+		if (axi_ctrl->share_ctrl->current_mode &
+				VFE_OUTPUTS_RDI0)
+			rc = configure_pingpong_buffers(
+				VFE_MSG_START, VFE_MSG_OUTPUT_TERTIARY1,
+				axi_ctrl);
+		if (axi_ctrl->share_ctrl->current_mode &
+				VFE_OUTPUTS_RDI1)
+			rc = configure_pingpong_buffers(
+				VFE_MSG_START, VFE_MSG_OUTPUT_TERTIARY2,
+				axi_ctrl);
+
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers for preview",
+				__func__);
+			rc = -EINVAL;
+			goto config_done;
+		}
+		break;
+	case AXI_CMD_RAW_CAPTURE:
+		rc = configure_pingpong_buffers(
+			VFE_MSG_CAPTURE, VFE_MSG_OUTPUT_PRIMARY,
+			axi_ctrl);
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers for snapshot",
+				__func__);
+			rc = -EINVAL;
+			goto config_done;
+		}
+		break;
+	case AXI_CMD_ZSL:
+		rc = configure_pingpong_buffers(VFE_MSG_START,
+			VFE_MSG_OUTPUT_PRIMARY, axi_ctrl);
+		if (rc < 0)
+			goto config_done;
+		rc = configure_pingpong_buffers(VFE_MSG_START,
+			VFE_MSG_OUTPUT_SECONDARY, axi_ctrl);
+		if (rc < 0)
+			goto config_done;
+		break;
+	case AXI_CMD_RECORD:
+		if (axi_ctrl->share_ctrl->current_mode &
+			VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
+			axi_ctrl->share_ctrl->outpath.out1.inst_handle =
+				vfe_params.inst_handle;
+			rc = configure_pingpong_buffers(
+				VFE_MSG_START_RECORDING,
+				VFE_MSG_OUTPUT_SECONDARY,
+				axi_ctrl);
+		} else if (axi_ctrl->share_ctrl->current_mode &
+			VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
+			axi_ctrl->share_ctrl->outpath.out0.inst_handle =
+				vfe_params.inst_handle;
+			rc = configure_pingpong_buffers(
+				VFE_MSG_START_RECORDING,
+				VFE_MSG_OUTPUT_PRIMARY,
+				axi_ctrl);
+		}
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers for video",
+				__func__);
+			rc = -EINVAL;
+			goto config_done;
+		}
+		break;
+	case AXI_CMD_LIVESHOT:
+		axi_ctrl->share_ctrl->outpath.out0.inst_handle =
+			vfe_params.inst_handle;
+		rc = configure_pingpong_buffers(VFE_MSG_CAPTURE,
+					VFE_MSG_OUTPUT_PRIMARY, axi_ctrl);
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers for primary output",
+				__func__);
+			rc = -EINVAL;
+			goto config_done;
+		}
+		break;
+	case AXI_CMD_CAPTURE:
+		if (axi_ctrl->share_ctrl->current_mode ==
+			VFE_OUTPUTS_JPEG_AND_THUMB ||
+		axi_ctrl->share_ctrl->current_mode ==
+			VFE_OUTPUTS_THUMB_AND_JPEG) {
+
+			/* Configure primary channel for JPEG */
+			rc = configure_pingpong_buffers(
+				VFE_MSG_JPEG_CAPTURE,
+				VFE_MSG_OUTPUT_PRIMARY,
+				axi_ctrl);
+		} else {
+			/* Configure primary channel */
+			rc = configure_pingpong_buffers(
+				VFE_MSG_CAPTURE,
+				VFE_MSG_OUTPUT_PRIMARY,
+				axi_ctrl);
+		}
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers for primary output",
+				__func__);
+			rc = -EINVAL;
+			goto config_done;
+		}
+		/* Configure secondary channel */
+		rc = configure_pingpong_buffers(
+				VFE_MSG_CAPTURE, VFE_MSG_OUTPUT_SECONDARY,
+				axi_ctrl);
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers for secondary output",
+				__func__);
+			rc = -EINVAL;
+			goto config_done;
+		}
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+
+	}
+config_done:
+	return rc;
+}
+
+void axi_start(struct msm_cam_media_controller *pmctl,
+	struct axi_ctrl_t *axi_ctrl, struct msm_camera_vfe_params_t vfe_params)
+{
+	uint32_t irq_comp_mask = 0, irq_mask = 0;
+	int rc = 0;
+	uint32_t reg_update = 0;
+	uint16_t operation_mode =
+		(axi_ctrl->share_ctrl->current_mode &
+		~(VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1));
+	rc = axi_config_buffers(axi_ctrl, vfe_params);
+	if (rc < 0)
+		return;
+
+	switch (vfe_params.cmd_type) {
+	case AXI_CMD_PREVIEW:
+		msm_camera_bus_scale_cfg(axi_ctrl->bus_perf_client, S_PREVIEW);
+		break;
+	case AXI_CMD_CAPTURE:
+	case AXI_CMD_RAW_CAPTURE:
+		msm_camera_bus_scale_cfg(axi_ctrl->bus_perf_client, S_CAPTURE);
+		break;
+	case AXI_CMD_RECORD:
+		msm_camera_bus_scale_cfg(axi_ctrl->bus_perf_client, S_VIDEO);
+		return;
+	case AXI_CMD_ZSL:
+		msm_camera_bus_scale_cfg(axi_ctrl->bus_perf_client, S_ZSL);
+		break;
+	case AXI_CMD_LIVESHOT:
+		msm_camera_bus_scale_cfg(axi_ctrl->bus_perf_client, S_LIVESHOT);
+		return;
+	default:
+		return;
+	}
+
+	irq_comp_mask =
+		msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
+			VFE_IRQ_COMP_MASK);
+	irq_mask = msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
+			VFE_IRQ_MASK_0);
+
+	if (axi_ctrl->share_ctrl->outpath.output_mode &
+			VFE40_OUTPUT_MODE_PRIMARY) {
+		if (vfe_params.cmd_type == AXI_CMD_RAW_CAPTURE) {
+			irq_comp_mask |=
+				0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0;
+		} else {
+			irq_comp_mask |= (
+				0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0 |
+				0x1 << axi_ctrl->share_ctrl->outpath.out0.ch1);
+		}
+		irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
+	} else if (axi_ctrl->share_ctrl->outpath.output_mode &
+			   VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+		irq_comp_mask |= (
+			0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0 |
+			0x1 << axi_ctrl->share_ctrl->outpath.out0.ch1 |
+			0x1 << axi_ctrl->share_ctrl->outpath.out0.ch2);
+		irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
+	}
+	if (axi_ctrl->share_ctrl->outpath.output_mode &
+			VFE40_OUTPUT_MODE_SECONDARY) {
+		irq_comp_mask |= (
+			0x1 << (axi_ctrl->share_ctrl->outpath.out1.ch0 + 8) |
+			0x1 << (axi_ctrl->share_ctrl->outpath.out1.ch1 + 8));
+		irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
+	} else if (axi_ctrl->share_ctrl->outpath.output_mode &
+			VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+		irq_comp_mask |= (
+			0x1 << (axi_ctrl->share_ctrl->outpath.out1.ch0 + 8) |
+			0x1 << (axi_ctrl->share_ctrl->outpath.out1.ch1 + 8) |
+			0x1 << (axi_ctrl->share_ctrl->outpath.out1.ch2 + 8));
+		irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
+	}
+	if (axi_ctrl->share_ctrl->outpath.output_mode &
+		VFE40_OUTPUT_MODE_TERTIARY1) {
+		irq_mask |= (0x1 << (axi_ctrl->share_ctrl->outpath.out2.ch0 +
+			VFE_WM_OFFSET));
+	}
+	if (axi_ctrl->share_ctrl->outpath.output_mode &
+		VFE40_OUTPUT_MODE_TERTIARY2) {
+		irq_mask |= (0x1 << (axi_ctrl->share_ctrl->outpath.out3.ch0 +
+			VFE_WM_OFFSET));
+	}
+
+	msm_camera_io_w(irq_comp_mask,
+		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+	msm_camera_io_w(irq_mask, axi_ctrl->share_ctrl->vfebase +
+			VFE_IRQ_MASK_0);
+
+	switch (vfe_params.cmd_type) {
+	case AXI_CMD_PREVIEW: {
+		switch (operation_mode) {
+		case VFE_OUTPUTS_PREVIEW:
+		case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
+			if (axi_ctrl->share_ctrl->outpath.output_mode &
+				VFE40_OUTPUT_MODE_PRIMARY) {
+				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+					+ vfe40_AXI_WM_CFG[axi_ctrl->
+					share_ctrl->outpath.out0.ch0]);
+				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+					+ vfe40_AXI_WM_CFG[axi_ctrl->
+					share_ctrl->outpath.out0.ch1]);
+			} else if (axi_ctrl->share_ctrl->outpath.output_mode &
+					VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+					+ vfe40_AXI_WM_CFG[axi_ctrl->
+					share_ctrl->outpath.out0.ch0]);
+				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+					+ vfe40_AXI_WM_CFG[axi_ctrl->
+					share_ctrl->outpath.out0.ch1]);
+				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+					+ vfe40_AXI_WM_CFG[axi_ctrl->
+					share_ctrl->outpath.out0.ch2]);
+			}
+			break;
+		default:
+			if (axi_ctrl->share_ctrl->outpath.output_mode &
+				VFE40_OUTPUT_MODE_SECONDARY) {
+				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+					+ vfe40_AXI_WM_CFG[axi_ctrl->
+					share_ctrl->outpath.out1.ch0]);
+				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+					+ vfe40_AXI_WM_CFG[axi_ctrl->
+					share_ctrl->outpath.out1.ch1]);
+			} else if (axi_ctrl->share_ctrl->outpath.output_mode &
+				VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+					+ vfe40_AXI_WM_CFG[axi_ctrl->
+					share_ctrl->outpath.out1.ch0]);
+				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+					+ vfe40_AXI_WM_CFG[axi_ctrl->
+					share_ctrl->outpath.out1.ch1]);
+				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+					+ vfe40_AXI_WM_CFG[axi_ctrl->
+					share_ctrl->outpath.out1.ch2]);
+			}
+			break;
+			}
+		}
+		break;
+	default:
+		if (axi_ctrl->share_ctrl->outpath.output_mode &
+			VFE40_OUTPUT_MODE_PRIMARY) {
+			if (vfe_params.cmd_type == AXI_CMD_RAW_CAPTURE) {
+				msm_camera_io_w(1,
+					axi_ctrl->share_ctrl->vfebase +
+					vfe40_AXI_WM_CFG[axi_ctrl->
+					share_ctrl->outpath.out0.ch0]);
+			} else {
+				msm_camera_io_w(1,
+					axi_ctrl->share_ctrl->vfebase +
+					vfe40_AXI_WM_CFG[axi_ctrl
+					->share_ctrl->outpath.out0.ch0]);
+				msm_camera_io_w(1,
+					axi_ctrl->share_ctrl->vfebase +
+					vfe40_AXI_WM_CFG[axi_ctrl->
+					share_ctrl->outpath.out0.ch1]);
+			}
+		} else if (axi_ctrl->share_ctrl->outpath.output_mode &
+				VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out0.ch0]);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out0.ch1]);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out0.ch2]);
+		}
+
+		if (axi_ctrl->share_ctrl->outpath.output_mode &
+			VFE40_OUTPUT_MODE_SECONDARY) {
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out1.ch0]);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out1.ch1]);
+		} else if (axi_ctrl->share_ctrl->outpath.output_mode &
+			VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out1.ch0]);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out1.ch1]);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out1.ch2]);
+		}
+		break;
+	}
+
+	if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI0)
+		msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+			vfe40_AXI_WM_CFG[axi_ctrl->share_ctrl->
+			outpath.out2.ch0]);
+	if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI1)
+		msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+			vfe40_AXI_WM_CFG[axi_ctrl->share_ctrl->
+			outpath.out3.ch0]);
+
+	if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
+		irq_mask |= VFE_IRQ_STATUS0_RDI0_REG_UPDATE_MASK;
+		if (!atomic_cmpxchg(
+			&axi_ctrl->share_ctrl->rdi0_update_ack_pending,
+				0, 1))
+			reg_update |= 0x2;
+	}
+	if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
+		irq_mask |= VFE_IRQ_STATUS0_RDI1_REG_UPDATE_MASK;
+		if (!atomic_cmpxchg(
+			&axi_ctrl->share_ctrl->rdi1_update_ack_pending,
+				0, 1))
+			reg_update |= 0x4;
+	}
+	msm_camera_io_w(irq_mask, axi_ctrl->share_ctrl->vfebase +
+		VFE_IRQ_MASK_0);
+	if (operation_mode) {
+		if (!atomic_cmpxchg(
+			&axi_ctrl->share_ctrl->pix0_update_ack_pending,
+				0, 1))
+			reg_update |= 0x1;
+	}
+
+	msm_camera_io_w_mb(reg_update,
+			axi_ctrl->share_ctrl->vfebase +
+			VFE_REG_UPDATE_CMD);
+	axi_ctrl->share_ctrl->operation_mode |=
+		axi_ctrl->share_ctrl->current_mode;
+	axi_enable_irq(axi_ctrl->share_ctrl);
+}
+
+void axi_stop(struct msm_cam_media_controller *pmctl,
+	struct axi_ctrl_t *axi_ctrl, struct msm_camera_vfe_params_t vfe_params)
+{
+	uint32_t reg_update = 0;
+	uint32_t operation_mode =
+	axi_ctrl->share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
+		VFE_OUTPUTS_RDI1);
+
+	switch (vfe_params.cmd_type) {
+	case AXI_CMD_PREVIEW:
+	case AXI_CMD_CAPTURE:
+	case AXI_CMD_RAW_CAPTURE:
+	case AXI_CMD_ZSL:
+		break;
+	case AXI_CMD_RECORD:
+		msm_camera_bus_scale_cfg(axi_ctrl->bus_perf_client, S_PREVIEW);
+		return;
+	case AXI_CMD_LIVESHOT:
+		msm_camera_bus_scale_cfg(axi_ctrl->bus_perf_client, S_VIDEO);
+		return;
+	default:
+		return;
+	}
+
+	if (axi_ctrl->share_ctrl->stop_immediately) {
+		axi_disable_irq(axi_ctrl->share_ctrl);
+		axi_stop_process(axi_ctrl->share_ctrl);
+		return;
+	}
+
+	if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
+		if (!atomic_cmpxchg(
+			&axi_ctrl->share_ctrl->rdi0_update_ack_pending, 0, 2))
+			reg_update |= 0x2;
+	}
+	if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
+		if (!atomic_cmpxchg(
+			&axi_ctrl->share_ctrl->rdi1_update_ack_pending, 0, 2))
+			reg_update |= 0x4;
+	}
+	if (operation_mode) {
+		if (!atomic_cmpxchg(
+			&axi_ctrl->share_ctrl->pix0_update_ack_pending, 0, 2))
+			reg_update |= 0x1;
+	}
+	msm_camera_io_w_mb(reg_update,
+		axi_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+}
+
+static int msm_axi_config(struct v4l2_subdev *sd, void __user *arg)
+{
+	struct msm_vfe_cfg_cmd cfgcmd;
+	struct msm_isp_cmd vfecmd;
+	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+	struct msm_cam_media_controller *pmctl =
+		(struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
+	int rc = 0, vfe_cmd_type = 0, rdi_mode = 0;
+
+	if (!axi_ctrl->share_ctrl->vfebase) {
+		pr_err("%s: base address unmapped\n", __func__);
+		return -EFAULT;
+	}
+	memset(&cfgcmd, 0, sizeof(struct msm_vfe_cfg_cmd));
+	if (NULL != arg) {
+		if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
+			ERR_COPY_FROM_USER();
+			return -EFAULT;
+		}
+	}
+	memset(&vfecmd, 0, sizeof(struct msm_isp_cmd));
+	if (NULL != cfgcmd.value) {
+		if (copy_from_user(&vfecmd,
+				(void __user *)(cfgcmd.value),
+				sizeof(vfecmd))) {
+			pr_err("%s %d: copy_from_user failed\n", __func__,
+				__LINE__);
+			return -EFAULT;
+		}
+	}
+
+	vfe_cmd_type = (cfgcmd.cmd_type & ~(CMD_AXI_CFG_TERT1|
+		CMD_AXI_CFG_TERT2));
+	switch (cfgcmd.cmd_type) {
+	case CMD_AXI_CFG_TERT1:{
+		uint32_t *axio = NULL;
+		axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio)
+			return -ENOMEM;
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			return -EFAULT;
+		}
+		vfe40_config_axi(axi_ctrl, OUTPUT_TERT1, axio);
+		kfree(axio);
+		return rc;
+		}
+	case CMD_AXI_CFG_TERT2:{
+		uint32_t *axio = NULL;
+		axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio)
+			return -ENOMEM;
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			return -EFAULT;
+		}
+		vfe40_config_axi(axi_ctrl, OUTPUT_TERT2, axio);
+		kfree(axio);
+		return rc;
+		}
+	case CMD_AXI_CFG_TERT1|CMD_AXI_CFG_TERT2:{
+		uint32_t *axio = NULL;
+		axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio)
+			return -ENOMEM;
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			return -EFAULT;
+		}
+		vfe40_config_axi(axi_ctrl, OUTPUT_TERT1|OUTPUT_TERT2, axio);
+		kfree(axio);
+		return rc;
+		}
+	default:
+		if (cfgcmd.cmd_type & CMD_AXI_CFG_TERT1)
+			rdi_mode |= OUTPUT_TERT1;
+		if (cfgcmd.cmd_type & CMD_AXI_CFG_TERT2)
+			rdi_mode |= OUTPUT_TERT2;
+	}
+	switch (vfe_cmd_type) {
+	case CMD_AXI_CFG_PRIM: {
+		uint32_t *axio = NULL;
+		axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe40_config_axi(axi_ctrl, rdi_mode|OUTPUT_PRIM, axio);
+		kfree(axio);
+		break;
+		}
+	case CMD_AXI_CFG_PRIM_ALL_CHNLS: {
+		uint32_t *axio = NULL;
+		axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe40_config_axi(axi_ctrl, rdi_mode|OUTPUT_PRIM_ALL_CHNLS,
+			axio);
+		kfree(axio);
+		break;
+		}
+	case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC: {
+		uint32_t *axio = NULL;
+		axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe40_config_axi(axi_ctrl,
+			rdi_mode|OUTPUT_PRIM|OUTPUT_SEC, axio);
+		kfree(axio);
+		break;
+		}
+	case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC_ALL_CHNLS: {
+		uint32_t *axio = NULL;
+		axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe40_config_axi(axi_ctrl,
+			rdi_mode|OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS, axio);
+		kfree(axio);
+		break;
+		}
+	case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC: {
+		uint32_t *axio = NULL;
+		axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe40_config_axi(axi_ctrl,
+			rdi_mode|OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC, axio);
+		kfree(axio);
+		break;
+		}
+
+	case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC_ALL_CHNLS:
+		pr_err("%s Invalid/Unsupported AXI configuration %x",
+			__func__, cfgcmd.cmd_type);
+		break;
+	case CMD_AXI_START: {
+		struct msm_camera_vfe_params_t vfe_params;
+		if (copy_from_user(&vfe_params,
+				(void __user *)(vfecmd.value),
+				sizeof(struct msm_camera_vfe_params_t))) {
+				return -EFAULT;
+		}
+		axi_ctrl->share_ctrl->current_mode =
+			vfe_params.operation_mode;
+		axi_start(pmctl, axi_ctrl, vfe_params);
+		}
+		break;
+	case CMD_AXI_STOP: {
+		struct msm_camera_vfe_params_t vfe_params;
+		if (copy_from_user(&vfe_params,
+				(void __user *)(vfecmd.value),
+				sizeof(struct msm_camera_vfe_params_t))) {
+				return -EFAULT;
+		}
+		axi_ctrl->share_ctrl->current_mode =
+			vfe_params.operation_mode;
+		axi_ctrl->share_ctrl->stop_immediately =
+			vfe_params.stop_immediately;
+		axi_stop(pmctl, axi_ctrl, vfe_params);
+		}
+		break;
+	case CMD_AXI_RESET:
+		axi_reset(axi_ctrl);
+		break;
+	case CMD_AXI_ABORT:
+		if (copy_from_user(&axi_ctrl->share_ctrl->sync_abort,
+				(void __user *)(vfecmd.value),
+				sizeof(uint8_t))) {
+				return -EFAULT;
+		}
+		axi_abort(axi_ctrl);
+		break;
+	default:
+		pr_err("%s Unsupported AXI configuration %x ", __func__,
+			cfgcmd.cmd_type);
+		break;
+	}
+	return rc;
+}
+
+static void msm_axi_process_irq(struct v4l2_subdev *sd, void *arg)
+{
+	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+	uint32_t irqstatus = (uint32_t) arg;
+
+	if (!axi_ctrl->share_ctrl->vfebase) {
+		pr_err("%s: base address unmapped\n", __func__);
+		return;
+	}
+
+	/* next, check output path related interrupts. */
+	if (irqstatus &
+		VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK) {
+		CDBG("Image composite done 0 irq occured.\n");
+		vfe40_process_output_path_irq_0(axi_ctrl);
+	}
+	if (irqstatus &
+		VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK) {
+		CDBG("Image composite done 1 irq occured.\n");
+		vfe40_process_output_path_irq_1(axi_ctrl);
+	}
+
+	if (axi_ctrl->share_ctrl->comp_output_mode &
+		VFE40_OUTPUT_MODE_TERTIARY1)
+		if (irqstatus & (0x1 << (axi_ctrl->share_ctrl->outpath.out2.ch0
+			+ VFE_WM_OFFSET)))
+			vfe40_process_output_path_irq_rdi0(axi_ctrl);
+	if (axi_ctrl->share_ctrl->comp_output_mode &
+		VFE40_OUTPUT_MODE_TERTIARY2)
+		if (irqstatus & (0x1 << (axi_ctrl->share_ctrl->outpath.out3.ch0
+			+ VFE_WM_OFFSET)))
+			vfe40_process_output_path_irq_rdi1(axi_ctrl);
+
+	/* in snapshot mode if done then send
+	snapshot done message */
+	if (
+		axi_ctrl->share_ctrl->operation_mode &
+			VFE_OUTPUTS_THUMB_AND_MAIN ||
+		axi_ctrl->share_ctrl->operation_mode &
+			VFE_OUTPUTS_MAIN_AND_THUMB ||
+		axi_ctrl->share_ctrl->operation_mode &
+			VFE_OUTPUTS_THUMB_AND_JPEG ||
+		axi_ctrl->share_ctrl->operation_mode &
+			VFE_OUTPUTS_JPEG_AND_THUMB ||
+		axi_ctrl->share_ctrl->operation_mode &
+			VFE_OUTPUTS_RAW) {
+		if ((axi_ctrl->share_ctrl->outpath.out0.capture_cnt == 0)
+				&& (axi_ctrl->share_ctrl->outpath.out1.
+				capture_cnt == 0)) {
+			msm_camera_io_w_mb(
+				CAMIF_COMMAND_STOP_IMMEDIATELY,
+				axi_ctrl->share_ctrl->vfebase +
+				VFE_CAMIF_COMMAND);
+			axi_disable_irq(axi_ctrl->share_ctrl);
+			vfe40_send_isp_msg(&axi_ctrl->subdev,
+				axi_ctrl->share_ctrl->vfeFrameId,
+				MSG_ID_PIX0_UPDATE_ACK);
+			vfe40_send_isp_msg(&axi_ctrl->subdev,
+				axi_ctrl->share_ctrl->vfeFrameId,
+				MSG_ID_SNAPSHOT_DONE);
+		}
+	}
+}
+
+static int msm_axi_buf_cfg(struct v4l2_subdev *sd, void __user *arg)
+{
+	struct msm_camvfe_params *vfe_params =
+		(struct msm_camvfe_params *)arg;
+	struct msm_vfe_cfg_cmd *cmd = vfe_params->vfe_cfg;
+	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+	void *data = vfe_params->data;
+	int rc = 0;
+
+	if (!axi_ctrl->share_ctrl->vfebase) {
+		pr_err("%s: base address unmapped\n", __func__);
+		return -EFAULT;
+	}
+
+	switch (cmd->cmd_type) {
+	case CMD_CONFIG_PING_ADDR: {
+		int path = *((int *)cmd->value);
+		struct vfe40_output_ch *outch =
+			vfe40_get_ch(path, axi_ctrl->share_ctrl);
+		outch->ping = *((struct msm_free_buf *)data);
+	}
+		break;
+
+	case CMD_CONFIG_PONG_ADDR: {
+		int path = *((int *)cmd->value);
+		struct vfe40_output_ch *outch =
+			vfe40_get_ch(path, axi_ctrl->share_ctrl);
+		outch->pong = *((struct msm_free_buf *)data);
+	}
+		break;
+
+	case CMD_CONFIG_FREE_BUF_ADDR: {
+		int path = *((int *)cmd->value);
+		struct vfe40_output_ch *outch =
+			vfe40_get_ch(path, axi_ctrl->share_ctrl);
+		outch->free_buf = *((struct msm_free_buf *)data);
+	}
+		break;
+	default:
+		pr_err("%s Unsupported AXI Buf config %x ", __func__,
+			cmd->cmd_type);
+	}
+	return rc;
+};
+
+static const struct v4l2_subdev_internal_ops msm_vfe_internal_ops;
+
+static long msm_axi_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int cmd, void *arg)
+{
+	int rc = -ENOIOCTLCMD;
+	switch (cmd) {
+	case VIDIOC_MSM_AXI_INIT:
+		rc = msm_axi_subdev_init(sd);
+		break;
+	case VIDIOC_MSM_AXI_CFG:
+		rc = msm_axi_config(sd, arg);
+		break;
+	case VIDIOC_MSM_AXI_IRQ:
+		msm_axi_process_irq(sd, arg);
+		rc = 0;
+		break;
+	case VIDIOC_MSM_AXI_BUF_CFG:
+		msm_axi_buf_cfg(sd, arg);
+		rc = 0;
+		break;
+	case VIDIOC_MSM_AXI_RELEASE:
+		msm_axi_subdev_release(sd);
+		rc = 0;
+		break;
+	case VIDIOC_MSM_AXI_RDI_COUNT_UPDATE: {
+		struct rdi_count_msg *msg = (struct rdi_count_msg *)arg;
+		struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+		switch (msg->rdi_interface) {
+		case RDI_0:
+			axi_ctrl->share_ctrl->rdi0FrameId = msg->count;
+			rc = 0;
+			break;
+		case RDI_1:
+			axi_ctrl->share_ctrl->rdi1FrameId = msg->count;
+			rc = 0;
+			break;
+		case RDI_2:
+			axi_ctrl->share_ctrl->rdi2FrameId = msg->count;
+			rc = 0;
+			break;
+		default:
+			pr_err("%s: Incorrect interface sent\n", __func__);
+			rc = -EINVAL;
+			break;
+		}
+		break;
+	}
+	default:
+		pr_err("%s: command %d not found\n", __func__,
+						_IOC_NR(cmd));
+		break;
+	}
+	return rc;
+}
+
+static const struct v4l2_subdev_core_ops msm_axi_subdev_core_ops = {
+	.ioctl = msm_axi_subdev_ioctl,
+	.interrupt_service_routine = msm_axi_subdev_isr_routine,
+};
+
+static const struct v4l2_subdev_video_ops msm_axi_subdev_video_ops = {
+	.s_crystal_freq = msm_axi_subdev_s_crystal_freq,
+};
+
+static const struct v4l2_subdev_ops msm_axi_subdev_ops = {
+	.core = &msm_axi_subdev_core_ops,
+	.video = &msm_axi_subdev_video_ops,
+};
+
+static const struct v4l2_subdev_internal_ops msm_axi_internal_ops;
+
+static int __devinit vfe40_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+	struct axi_ctrl_t *axi_ctrl;
+	struct vfe40_ctrl_type *vfe40_ctrl;
+	struct vfe_share_ctrl_t *share_ctrl;
+	struct intr_table_entry irq_req;
+	struct msm_cam_subdev_info sd_info;
+	CDBG("%s: device id = %d\n", __func__, pdev->id);
+
+	share_ctrl = kzalloc(sizeof(struct vfe_share_ctrl_t), GFP_KERNEL);
+	if (!share_ctrl) {
+		pr_err("%s: no enough memory\n", __func__);
+		return -ENOMEM;
+	}
+
+	axi_ctrl = kzalloc(sizeof(struct axi_ctrl_t), GFP_KERNEL);
+	if (!axi_ctrl) {
+		pr_err("%s: no enough memory\n", __func__);
+		kfree(share_ctrl);
+		return -ENOMEM;
+	}
+
+	vfe40_ctrl = kzalloc(sizeof(struct vfe40_ctrl_type), GFP_KERNEL);
+	if (!vfe40_ctrl) {
+		pr_err("%s: no enough memory\n", __func__);
+		kfree(share_ctrl);
+		kfree(axi_ctrl);
+		return -ENOMEM;
+	}
+
+	if (pdev->dev.of_node)
+		of_property_read_u32((&pdev->dev)->of_node,
+			"cell-index", &pdev->id);
+
+	share_ctrl->axi_ctrl = axi_ctrl;
+	share_ctrl->vfe40_ctrl = vfe40_ctrl;
+	axi_ctrl->share_ctrl = share_ctrl;
+	vfe40_ctrl->share_ctrl = share_ctrl;
+	axi_ctrl->share_ctrl->axi_ref_cnt = 0;
+	v4l2_subdev_init(&axi_ctrl->subdev, &msm_axi_subdev_ops);
+	axi_ctrl->subdev.internal_ops = &msm_axi_internal_ops;
+	axi_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	snprintf(axi_ctrl->subdev.name,
+			 sizeof(axi_ctrl->subdev.name), "axi");
+	v4l2_set_subdevdata(&axi_ctrl->subdev, axi_ctrl);
+	axi_ctrl->pdev = pdev;
+
+	sd_info.sdev_type = AXI_DEV;
+	sd_info.sd_index = pdev->id;
+	sd_info.irq_num = 0;
+	msm_cam_register_subdev_node(&axi_ctrl->subdev, &sd_info);
+
+	media_entity_init(&axi_ctrl->subdev.entity, 0, NULL, 0);
+	axi_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	axi_ctrl->subdev.entity.group_id = AXI_DEV;
+	axi_ctrl->subdev.entity.name = pdev->name;
+	axi_ctrl->subdev.entity.revision = axi_ctrl->subdev.devnode->num;
+
+	v4l2_subdev_init(&vfe40_ctrl->subdev, &msm_vfe_subdev_ops);
+	vfe40_ctrl->subdev.internal_ops = &msm_vfe_internal_ops;
+	vfe40_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	snprintf(vfe40_ctrl->subdev.name,
+			 sizeof(vfe40_ctrl->subdev.name), "vfe4.0");
+	v4l2_set_subdevdata(&vfe40_ctrl->subdev, vfe40_ctrl);
+	platform_set_drvdata(pdev, &vfe40_ctrl->subdev);
+
+	axi_ctrl->vfemem = platform_get_resource_byname(pdev,
+					IORESOURCE_MEM, "vfe");
+	if (!axi_ctrl->vfemem) {
+		pr_err("%s: no mem resource?\n", __func__);
+		rc = -ENODEV;
+		goto vfe40_no_resource;
+	}
+
+	axi_ctrl->vfe_vbif_mem = platform_get_resource_byname(pdev,
+					IORESOURCE_MEM, "vfe_vbif");
+	if (!axi_ctrl->vfe_vbif_mem) {
+		pr_err("%s: no mem resource?\n", __func__);
+		rc = -ENODEV;
+		goto vfe40_no_resource;
+	}
+
+	axi_ctrl->vfeirq = platform_get_resource_byname(pdev,
+					IORESOURCE_IRQ, "vfe");
+	if (!axi_ctrl->vfeirq) {
+		pr_err("%s: no irq resource?\n", __func__);
+		rc = -ENODEV;
+		goto vfe40_no_resource;
+	}
+
+	axi_ctrl->vfeio = request_mem_region(axi_ctrl->vfemem->start,
+		resource_size(axi_ctrl->vfemem), pdev->name);
+	if (!axi_ctrl->vfeio) {
+		pr_err("%s: no valid mem region\n", __func__);
+		rc = -EBUSY;
+		goto vfe40_no_resource;
+	}
+
+	axi_ctrl->fs_vfe = regulator_get(&pdev->dev, "vdd");
+	if (IS_ERR(axi_ctrl->fs_vfe)) {
+		pr_err("%s: Regulator get failed %ld\n", __func__,
+			PTR_ERR(axi_ctrl->fs_vfe));
+		axi_ctrl->fs_vfe = NULL;
+	}
+
+	/* Register subdev node before requesting irq since
+	 * irq_num is needed by msm_cam_server */
+	sd_info.sdev_type = VFE_DEV;
+	sd_info.sd_index = pdev->id;
+	sd_info.irq_num = axi_ctrl->vfeirq->start;
+	msm_cam_register_subdev_node(&vfe40_ctrl->subdev, &sd_info);
+
+	media_entity_init(&vfe40_ctrl->subdev.entity, 0, NULL, 0);
+	vfe40_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	vfe40_ctrl->subdev.entity.group_id = VFE_DEV;
+	vfe40_ctrl->subdev.entity.name = pdev->name;
+	vfe40_ctrl->subdev.entity.revision = vfe40_ctrl->subdev.devnode->num;
+
+	/* Request for this device irq from the camera server. If the
+	 * IRQ Router is present on this target, the interrupt will be
+	 * handled by the camera server and the interrupt service
+	 * routine called. If the request_irq call returns ENXIO, then
+	 * the IRQ Router hardware is not present on this target. We
+	 * have to request for the irq ourselves and register the
+	 * appropriate interrupt handler. */
+	axi_ctrl->use_irq_router = true;
+	irq_req.cam_hw_idx       = MSM_CAM_HW_VFE0 + pdev->id;
+	irq_req.dev_name         = "vfe";
+	irq_req.irq_idx          = CAMERA_SS_IRQ_8;
+	irq_req.irq_num          = axi_ctrl->vfeirq->start;
+	irq_req.is_composite     = 0;
+	irq_req.irq_trigger_type = IRQF_TRIGGER_RISING;
+	irq_req.num_hwcore       = 1;
+	irq_req.subdev_list[0]   = &axi_ctrl->subdev;
+	irq_req.data             = (void *)axi_ctrl;
+	rc = msm_cam_server_request_irq(&irq_req);
+	if (rc == -ENXIO) {
+		/* IRQ Router hardware is not present on this hardware.
+		 * Request for the IRQ and register the interrupt handler. */
+		axi_ctrl->use_irq_router = false;
+		rc = request_irq(axi_ctrl->vfeirq->start, vfe40_parse_irq,
+			IRQF_TRIGGER_RISING, "vfe", axi_ctrl);
+		if (rc < 0) {
+			release_mem_region(axi_ctrl->vfemem->start,
+				resource_size(axi_ctrl->vfemem));
+			pr_err("%s: irq request fail\n", __func__);
+			rc = -EBUSY;
+			goto vfe40_no_resource;
+		}
+		disable_irq(axi_ctrl->vfeirq->start);
+	} else if (rc < 0) {
+		pr_err("%s Error registering irq ", __func__);
+		goto vfe40_no_resource;
+	}
+
+	/*get device context for IOMMU*/
+	if (pdev->id == 0)
+		axi_ctrl->iommu_ctx = msm_iommu_get_ctx("vfe0");
+	else if (pdev->id == 1)
+		axi_ctrl->iommu_ctx = msm_iommu_get_ctx("vfe1");
+	if (!axi_ctrl->iommu_ctx) {
+		release_mem_region(axi_ctrl->vfemem->start,
+			resource_size(axi_ctrl->vfemem));
+		pr_err("%s: No iommu fw context found\n", __func__);
+		rc = -ENODEV;
+		goto vfe40_no_resource;
+	}
+
+	tasklet_init(&axi_ctrl->vfe40_tasklet,
+		axi40_do_tasklet, (unsigned long)axi_ctrl);
+
+	vfe40_ctrl->pdev = pdev;
+	/*enable bayer stats by default*/
+	vfe40_ctrl->ver_num.main = 4;
+
+	return 0;
+
+vfe40_no_resource:
+	kfree(vfe40_ctrl);
+	kfree(axi_ctrl);
+	return 0;
+}
+
+static const struct of_device_id msm_vfe_dt_match[] = {
+	{.compatible = "qcom,vfe40"},
+};
+
+MODULE_DEVICE_TABLE(of, msm_vfe_dt_match);
+
+static struct platform_driver vfe40_driver = {
+	.probe = vfe40_probe,
+	.driver = {
+		.name = MSM_VFE_DRV_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = msm_vfe_dt_match,
+	},
+};
+
+static int __init msm_vfe40_init_module(void)
+{
+	return platform_driver_register(&vfe40_driver);
+}
+
+static void __exit msm_vfe40_exit_module(void)
+{
+	platform_driver_unregister(&vfe40_driver);
+}
+
+module_init(msm_vfe40_init_module);
+module_exit(msm_vfe40_exit_module);
+MODULE_DESCRIPTION("VFE 4.0 driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/vfe/msm_vfe40.h b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe40.h
new file mode 100644
index 0000000..2b32203
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe40.h
@@ -0,0 +1,1063 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MSM_VFE40_H__
+#define __MSM_VFE40_H__
+
+#include <linux/bitops.h>
+#include "msm_vfe_stats_buf.h"
+
+#define TRUE  1
+#define FALSE 0
+
+#define VFE40_HW_NUMBER 0x10000015
+
+/* This defines total number registers in VFE.
+ * Each register is 4 bytes so to get the range,
+ * multiply this number with 4. */
+#define VFE40_REGISTER_TOTAL 0x00000320
+
+/* at stop of vfe pipeline, for now it is assumed
+ * that camif will stop at any time. Bit 1:0 = 0x10:
+ * disable image data capture immediately. */
+#define CAMIF_COMMAND_STOP_IMMEDIATELY  0x00000002
+
+/* at stop of vfe pipeline, for now it is assumed
+ * that camif will stop at any time. Bit 1:0 = 0x00:
+ * disable image data capture at frame boundary */
+#define CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY  0x00000000
+
+/* to halt axi bridge */
+#define AXI_HALT  0x00000001
+
+/* clear the halt bit. */
+#define AXI_HALT_CLEAR  0x00000000
+
+/* reset the pipeline when stop command is issued.
+ * (without reset the register.) bit 26-32 = 0,
+ * domain reset, bit 0-9 = 1 for module reset, except
+ * register module. */
+#define VFE_RESET_UPON_STOP_CMD  0x000003ef
+
+/* reset the pipeline when reset command.
+ * bit 26-32 = 0, domain reset, bit 0-9 = 1 for module reset. */
+#define VFE_RESET_UPON_RESET_CMD  0x000003ff
+
+/* reset the vfe only when reset command*/
+#define VFE_ONLY_RESET_CMD  0x00000002
+
+/*Vfe module reset command*/
+#define VFE_MODULE_RESET_CMD 0x07ffffff
+
+/* wm bit offset for IRQ MASK and IRQ STATUS register */
+#define VFE_WM_OFFSET 6
+
+/* constants for irq registers */
+#define VFE_DISABLE_ALL_IRQS 0
+/* bit =1 is to clear the corresponding bit in VFE_IRQ_STATUS.  */
+#define VFE_CLEAR_ALL_IRQ0   0xffff7fff
+#define VFE_CLEAR_ALL_IRQ1   0xffffffff
+
+#define VFE_IRQ_STATUS0_CAMIF_SOF_MASK            (0x00000001<<0)
+#define VFE_IRQ_STATUS0_REG_UPDATE_MASK           (0x00000001<<4)
+#define VFE_IRQ_STATUS0_RDI0_REG_UPDATE_MASK      (0x00000001<<5)
+#define VFE_IRQ_STATUS0_RDI1_REG_UPDATE_MASK      (0x00000001<<6)
+#define VFE_IRQ_STATUS0_RDI2_REG_UPDATE_MASK      (0x00000001<<7)
+#define VFE_IRQ_STATUS0_STATS_BE                  (0x00000001<<16)
+#define VFE_IRQ_STATUS0_STATS_BG                  (0x00000001<<17)
+#define VFE_IRQ_STATUS0_STATS_BF                  (0x00000001<<18)
+#define VFE_IRQ_STATUS0_STATS_AWB                 (0x00000001<<19)
+#define VFE_IRQ_STATUS0_STATS_RS                  (0x00000001<<20)
+#define VFE_IRQ_STATUS0_STATS_CS                  (0x00000001<<21)
+#define VFE_IRQ_STATUS0_STATS_IHIST               (0x00000001<<22)
+#define VFE_IRQ_STATUS0_STATS_SKIN_BHIST          (0x00000001<<23)
+#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK (0x00000001<<25)
+#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK (0x00000001<<26)
+#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE2_MASK (0x00000001<<27)
+#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE3_MASK (0x00000001<<28)
+#define VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK_0     (0x00000001<<29)
+#define VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK_1     (0x00000001<<30)
+#define VFE_IRQ_STATUS0_RESET_AXI_HALT_ACK_MASK   (0x00000001<<31)
+
+#define VFE_IRQ_STATUS1_SYNC_TIMER0               (0x00000001<<25)
+#define VFE_IRQ_STATUS1_SYNC_TIMER1               (0x00000001<<26)
+#define VFE_IRQ_STATUS1_SYNC_TIMER2               (0x00000001<<27)
+#define VFE_IRQ_STATUS1_ASYNC_TIMER0              (0x00000001<<28)
+#define VFE_IRQ_STATUS1_ASYNC_TIMER1              (0x00000001<<29)
+#define VFE_IRQ_STATUS1_ASYNC_TIMER2              (0x00000001<<30)
+#define VFE_IRQ_STATUS1_ASYNC_TIMER3              (0x00000001<<31)
+
+/*TODOs the irq status passed from axi to vfe irq handler does not account
+* for 2 irq status registers. So below macro is added to differentiate between
+* same bit set on both irq status registers. This wil be fixed later by passing
+*entire payload to vfe irq handler and parsing there instead of passing just the
+*status bit*/
+
+#define VFE_IRQ_STATUS0_RDI0_REG_UPDATE  VFE_IRQ_STATUS0_RDI0_REG_UPDATE_MASK
+#define VFE_IRQ_STATUS0_RDI1_REG_UPDATE  VFE_IRQ_STATUS0_RDI1_REG_UPDATE_MASK
+
+/* imask for while waiting for stop ack,  driver has already
+ * requested stop, waiting for reset irq, and async timer irq.
+ * For irq_status_1, bit 28-32 are for async timer. For
+ * irq_status_0, bit 31 for reset irq, bit 23 for axi_halt_ack
+   irq */
+#define VFE_IMASK_WHILE_STOPPING_0  0x80000000
+#define VFE_IMASK_WHILE_STOPPING_1  0xF0000000
+
+/* For ABF bit 4 is set to zero and other's 1 */
+#define ABF_MASK 0xFFFFFFF7
+
+/* For DBPC bit 0 is set to zero and other's 1 */
+#define DBPC_MASK 0xFFFFFFFE
+
+/* For DBPC bit 1 is set to zero and other's 1 */
+#define DBCC_MASK 0xFFFFFFFD
+
+/* For DBPC/ABF/DBCC/ABCC bits are set to 1 all others 0 */
+#define DEMOSAIC_MASK 0xF
+
+/* For MCE enable bit 28 set to zero and other's 1 */
+#define MCE_EN_MASK 0xEFFFFFFF
+
+/* For MCE Q_K bit 28 to 32 set to zero and other's 1 */
+#define MCE_Q_K_MASK 0x0FFFFFFF
+
+#define BE_ENABLE_MASK    (0x00000001<<5)
+#define BG_ENABLE_MASK    (0x00000001<<6)
+#define BF_ENABLE_MASK    (0x00000001<<7)
+#define AWB_ENABLE_MASK   (0x00000001<<8)
+#define RS_ENABLE_MASK    (0x00000001<<9)
+#define CS_ENABLE_MASK    (0x00000001<<10)
+#define CLF_ENABLE_MASK   (0x00000001<<12)
+#define IHIST_ENABLE_MASK (0x00000001<<15)
+#define BHIST_ENABLE_MASK (0x00000001<<18)
+#define RS_CS_ENABLE_MASK (RS_ENABLE_MASK|CS_ENABLE_MASK)
+#define STATS_ENABLE_MASK 0x000487E0   /* bit 18,15,10,9,8,7,6,5*/
+
+#define STATS_BHIST_ENABLE_MASK (0x00000001<<1)
+
+#define VFE_DMI_CFG_DEFAULT              0x00000100
+
+#define HFR_MODE_OFF 1
+#define VFE_FRAME_SKIP_PERIOD_MASK 0x0000001F /*bits 0 -4*/
+
+enum VFE40_DMI_RAM_SEL {
+	NO_MEM_SELECTED          = 0,
+	BLACK_LUT_RAM_BANK0      = 0x1,
+	BLACK_LUT_RAM_BANK1      = 0x2,
+	ROLLOFF_RAM0_BANK0       = 0x3,
+	ROLLOFF_RAM0_BANK1       = 0x4,
+	DEMOSAIC_LUT_RAM_BANK0   = 0x5,
+	DEMOSAIC_LUT_RAM_BANK1   = 0x6,
+	STATS_BHIST_RAM0         = 0x7,
+	STATS_BHIST_RAM1         = 0x8,
+	RGBLUT_RAM_CH0_BANK0     = 0x9,
+	RGBLUT_RAM_CH0_BANK1     = 0xa,
+	RGBLUT_RAM_CH1_BANK0     = 0xb,
+	RGBLUT_RAM_CH1_BANK1     = 0xc,
+	RGBLUT_RAM_CH2_BANK0     = 0xd,
+	RGBLUT_RAM_CH2_BANK1     = 0xe,
+	RGBLUT_CHX_BANK0         = 0xf,
+	RGBLUT_CHX_BANK1         = 0x10,
+	STATS_IHIST_RAM          = 0x11,
+	LUMA_ADAPT_LUT_RAM_BANK0 = 0x12,
+	LUMA_ADAPT_LUT_RAM_BANK1 = 0x13,
+};
+
+enum vfe_output_state {
+	VFE_STATE_IDLE,
+	VFE_STATE_START_REQUESTED,
+	VFE_STATE_STARTED,
+	VFE_STATE_STOP_REQUESTED,
+	VFE_STATE_STOPPED,
+};
+
+#define V40_CAMIF_OFF             0x000002F8
+#define V40_CAMIF_LEN             36
+
+#define V40_DEMUX_OFF             0x00000424
+#define V40_DEMUX_LEN             28
+
+#define V40_DEMOSAICV3_0_OFF      0x00000440
+#define V40_DEMOSAICV3_0_LEN      4
+#define V40_DEMOSAICV3_1_OFF      0x00000518
+#define V40_DEMOSAICV3_1_LEN      88
+#define V40_DEMOSAICV3_2_OFF      0x00000568
+#define V40_DEMOSAICV3_UP_REG_CNT 5
+
+#define V40_OUT_CLAMP_OFF         0x00000874
+#define V40_OUT_CLAMP_LEN         16
+
+#define V40_OPERATION_CFG_LEN     32
+
+#define V40_AXI_BUS_CMD_OFF       0x0000004C
+#define V40_AXI_BUS_CFG_LEN       284
+#define V40_AXI_OUT_LEN           344
+#define V40_AXI_CFG_LEN           71
+
+#define V40_BUS_PM_CMD            0x00000270
+#define V40_FOV_ENC_OFF           0x00000854
+#define V40_FOV_ENC_LEN           16
+#define V40_FOV_VIEW_OFF          0x00000864
+#define V40_FOV_VIEW_LEN          16
+
+#define V40_SCALER_ENC_OFF 0x0000075C
+#define V40_SCALER_ENC_LEN 72
+
+#define V40_SCALER_VIEW_OFF 0x000007A4
+#define V40_SCALER_VIEW_LEN 72
+
+#define V40_COLORXFORM_ENC_CFG_OFF 0x0000071C
+#define V40_COLORXFORM_ENC_CFG_LEN 32
+
+#define V40_COLORXFORM_VIEW_CFG_OFF 0x0000073C
+#define V40_COLORXFORM_VIEW_CFG_LEN 32
+
+#define V40_CHROMA_EN_OFF 0x00000640
+#define V40_CHROMA_EN_LEN 36
+
+#define V40_SYNC_TIMER_OFF      0x00000324
+#define V40_SYNC_TIMER_POLARITY_OFF 0x0000034C
+#define V40_TIMER_SELECT_OFF        0x00000374
+#define V40_SYNC_TIMER_LEN 28
+
+#define V40_ASYNC_TIMER_OFF 0x00000350
+#define V40_ASYNC_TIMER_LEN 28
+
+/* use 10x13 mesh table in vfe40*/
+#define V40_MESH_ROLL_OFF_CFG_OFF             0x00000400
+#define V40_MESH_ROLL_OFF_CFG_LEN             36
+#define V40_MESH_ROLL_OFF_TABLE_SIZE          130
+
+#define V40_COLOR_COR_OFF 0x000005D0
+#define V40_COLOR_COR_LEN 52
+
+#define V40_WB_OFF 0x00000580
+#define V40_WB_LEN 4
+
+#define V40_RGB_G_OFF 0x00000638
+#define V40_RGB_G_LEN 4
+#define V40_GAMMA_LUT_BANK_SEL_MASK           0x00000007
+
+#define V40_LA_OFF 0x0000063C
+#define V40_LA_LEN 4
+
+#define V40_SCE_OFF 0x00000694
+#define V40_SCE_LEN 136
+
+#define V40_CHROMA_SUP_OFF 0x00000664
+#define V40_CHROMA_SUP_LEN 12
+
+#define V40_MCE_OFF 0x00000670
+#define V40_MCE_LEN 36
+
+#define V40_STATS_BE_OFF 0x0000088C
+#define V40_STATS_BE_LEN 12
+
+#define V40_STATS_BG_OFF 0x00000898
+#define V40_STATS_BG_LEN 12
+
+#define V40_STATS_BF_OFF 0x000008A4
+#define V40_STATS_BF_LEN 24
+
+#define V40_STATS_BHIST_OFF 0x000008BC
+#define V40_STATS_BHIST_LEN 8
+
+#define V40_STATS_AWB_OFF 0x000008C4
+#define V40_STATS_AWB_LEN 32
+
+#define V40_STATS_RS_OFF 0x000008E4
+#define V40_STATS_RS_LEN 8
+
+#define V40_STATS_CS_OFF 0x000008EC
+#define V40_STATS_CS_LEN 8
+
+#define V40_STATS_IHIST_OFF 0x000008F4
+#define V40_STATS_IHIST_LEN 8
+
+#define V40_STATS_SKIN_OFF 0x000008FC
+#define V40_STATS_SKIN_LEN 20
+
+#define V40_ASF_OFF 0x000007EC
+#define V40_ASF_LEN 48
+#define V40_ASF_UPDATE_LEN 36
+
+#define V40_CAPTURE_LEN 4
+
+#define V40_GET_HW_VERSION_OFF 0
+#define V40_GET_HW_VERSION_LEN 4
+
+#define V40_LINEARIZATION_OFF1 0x0000037C
+#define V40_LINEARIZATION_LEN1 68
+
+#define V40_DEMOSAICV3_DBPC_CFG_OFF  0x00000444
+#define V40_DEMOSAICV3_DBPC_LEN 4
+
+#define V40_DEMOSAICV3_DBPC_CFG_OFF0 0x00000448
+#define V40_DEMOSAICV3_DBPC_CFG_OFF1 0x0000044C
+#define V40_DEMOSAICV3_DBPC_CFG_OFF2 0x00000450
+
+#define V40_DEMOSAICV3_DBCC_OFF 0x00000454
+#define V40_DEMOSAICV3_DBCC_LEN 16
+
+#define V40_DEMOSAICV3_ABF_OFF 0x00000464
+#define V40_DEMOSAICV3_ABF_LEN 180
+
+#define V40_MODULE_CFG_OFF 0x00000018
+#define V40_MODULE_CFG_LEN 4
+
+#define V40_ASF_SPECIAL_EFX_CFG_OFF 0x0000081C
+#define V40_ASF_SPECIAL_EFX_CFG_LEN 4
+
+#define V40_CLF_CFG_OFF 0x00000588
+#define V40_CLF_CFG_LEN 72
+
+#define V40_CLF_LUMA_UPDATE_OFF 0x0000058C
+#define V40_CLF_LUMA_UPDATE_LEN 60
+
+#define V40_CLF_CHROMA_UPDATE_OFF 0x000005C8
+#define V40_CLF_CHROMA_UPDATE_LEN 8
+
+#define VFE40_GAMMA_NUM_ENTRIES  64
+
+#define VFE40_LA_TABLE_LENGTH    64
+
+#define VFE40_LINEARIZATON_TABLE_LENGTH    36
+
+struct vfe_cmd_hw_version {
+	uint32_t minorVersion;
+	uint32_t majorVersion;
+	uint32_t coreVersion;
+};
+
+enum VFE_AXI_OUTPUT_MODE {
+	VFE_AXI_OUTPUT_MODE_Output1,
+	VFE_AXI_OUTPUT_MODE_Output2,
+	VFE_AXI_OUTPUT_MODE_Output1AndOutput2,
+	VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2,
+	VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1,
+	VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2,
+	VFE_AXI_LAST_OUTPUT_MODE_ENUM
+};
+
+enum VFE_RAW_WR_PATH_SEL {
+	VFE_RAW_OUTPUT_DISABLED,
+	VFE_RAW_OUTPUT_ENC_CBCR_PATH,
+	VFE_RAW_OUTPUT_VIEW_CBCR_PATH,
+	VFE_RAW_OUTPUT_PATH_INVALID
+};
+
+
+#define VFE_AXI_OUTPUT_BURST_LENGTH     4
+#define VFE_MAX_NUM_FRAGMENTS_PER_FRAME 4
+#define VFE_AXI_OUTPUT_CFG_FRAME_COUNT  3
+
+struct vfe_cmds_per_write_master {
+	uint16_t imageWidth;
+	uint16_t imageHeight;
+	uint16_t outRowCount;
+	uint16_t outRowIncrement;
+	uint32_t outFragments[VFE_AXI_OUTPUT_CFG_FRAME_COUNT]
+		[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
+};
+
+struct vfe_cmds_axi_per_output_path {
+	uint8_t fragmentCount;
+	struct vfe_cmds_per_write_master firstWM;
+	struct vfe_cmds_per_write_master secondWM;
+};
+
+enum VFE_AXI_BURST_LENGTH {
+	VFE_AXI_BURST_LENGTH_IS_2  = 2,
+	VFE_AXI_BURST_LENGTH_IS_4  = 4,
+	VFE_AXI_BURST_LENGTH_IS_8  = 8,
+	VFE_AXI_BURST_LENGTH_IS_16 = 16
+};
+
+
+struct vfe_cmd_fov_crop_config {
+	uint8_t enable;
+	uint16_t firstPixel;
+	uint16_t lastPixel;
+	uint16_t firstLine;
+	uint16_t lastLine;
+};
+
+struct vfe_cmds_main_scaler_stripe_init {
+	uint16_t MNCounterInit;
+	uint16_t phaseInit;
+};
+
+struct vfe_cmds_scaler_one_dimension {
+	uint8_t  enable;
+	uint16_t inputSize;
+	uint16_t outputSize;
+	uint32_t phaseMultiplicationFactor;
+	uint8_t  interpolationResolution;
+};
+
+struct vfe_cmd_main_scaler_config {
+	uint8_t enable;
+	struct vfe_cmds_scaler_one_dimension    hconfig;
+	struct vfe_cmds_scaler_one_dimension    vconfig;
+	struct vfe_cmds_main_scaler_stripe_init MNInitH;
+	struct vfe_cmds_main_scaler_stripe_init MNInitV;
+};
+
+struct vfe_cmd_scaler2_config {
+	uint8_t enable;
+	struct vfe_cmds_scaler_one_dimension hconfig;
+	struct vfe_cmds_scaler_one_dimension vconfig;
+};
+
+
+struct vfe_cmd_frame_skip_update {
+	uint32_t output1Pattern;
+	uint32_t output2Pattern;
+};
+
+struct vfe_cmd_output_clamp_config {
+	uint8_t minCh0;
+	uint8_t minCh1;
+	uint8_t minCh2;
+	uint8_t maxCh0;
+	uint8_t maxCh1;
+	uint8_t maxCh2;
+};
+
+struct vfe_cmd_chroma_subsample_config {
+	uint8_t enable;
+	uint8_t cropEnable;
+	uint8_t vsubSampleEnable;
+	uint8_t hsubSampleEnable;
+	uint8_t vCosited;
+	uint8_t hCosited;
+	uint8_t vCositedPhase;
+	uint8_t hCositedPhase;
+	uint16_t cropWidthFirstPixel;
+	uint16_t cropWidthLastPixel;
+	uint16_t cropHeightFirstLine;
+	uint16_t cropHeightLastLine;
+};
+
+enum VFE_START_PIXEL_PATTERN {
+	VFE_BAYER_RGRGRG,
+	VFE_BAYER_GRGRGR,
+	VFE_BAYER_BGBGBG,
+	VFE_BAYER_GBGBGB,
+	VFE_YUV_YCbYCr,
+	VFE_YUV_YCrYCb,
+	VFE_YUV_CbYCrY,
+	VFE_YUV_CrYCbY
+};
+
+enum VFE_BUS_RD_INPUT_PIXEL_PATTERN {
+	VFE_BAYER_RAW,
+	VFE_YUV_INTERLEAVED,
+	VFE_YUV_PSEUDO_PLANAR_Y,
+	VFE_YUV_PSEUDO_PLANAR_CBCR
+};
+
+enum VFE_YUV_INPUT_COSITING_MODE {
+	VFE_YUV_COSITED,
+	VFE_YUV_INTERPOLATED
+};
+
+struct vfe_cmds_demosaic_abf {
+	uint8_t   enable;
+	uint8_t   forceOn;
+	uint8_t   shift;
+	uint16_t  lpThreshold;
+	uint16_t  max;
+	uint16_t  min;
+	uint8_t   ratio;
+};
+
+struct vfe_cmds_demosaic_bpc {
+	uint8_t   enable;
+	uint16_t  fmaxThreshold;
+	uint16_t  fminThreshold;
+	uint16_t  redDiffThreshold;
+	uint16_t  blueDiffThreshold;
+	uint16_t  greenDiffThreshold;
+};
+
+struct vfe_cmd_demosaic_config {
+	uint8_t   enable;
+	uint8_t   slopeShift;
+	struct vfe_cmds_demosaic_abf abfConfig;
+	struct vfe_cmds_demosaic_bpc bpcConfig;
+};
+
+struct vfe_cmd_demosaic_bpc_update {
+	struct vfe_cmds_demosaic_bpc bpcUpdate;
+};
+
+struct vfe_cmd_demosaic_abf_update {
+	struct vfe_cmds_demosaic_abf abfUpdate;
+};
+
+struct vfe_cmd_white_balance_config {
+	uint8_t  enable;
+	uint16_t ch2Gain;
+	uint16_t ch1Gain;
+	uint16_t ch0Gain;
+};
+
+enum VFE_COLOR_CORRECTION_COEF_QFACTOR {
+	COEF_IS_Q7_SIGNED,
+	COEF_IS_Q8_SIGNED,
+	COEF_IS_Q9_SIGNED,
+	COEF_IS_Q10_SIGNED
+};
+
+struct vfe_cmd_color_correction_config {
+	uint8_t     enable;
+	enum VFE_COLOR_CORRECTION_COEF_QFACTOR coefQFactor;
+	int16_t  C0;
+	int16_t  C1;
+	int16_t  C2;
+	int16_t  C3;
+	int16_t  C4;
+	int16_t  C5;
+	int16_t  C6;
+	int16_t  C7;
+	int16_t  C8;
+	int16_t  K0;
+	int16_t  K1;
+	int16_t  K2;
+};
+
+#define VFE_LA_TABLE_LENGTH 64
+
+struct vfe_cmd_la_config {
+	uint8_t enable;
+	int16_t table[VFE_LA_TABLE_LENGTH];
+};
+
+#define VFE_GAMMA_TABLE_LENGTH 256
+enum VFE_RGB_GAMMA_TABLE_SELECT {
+	RGB_GAMMA_CH0_SELECTED,
+	RGB_GAMMA_CH1_SELECTED,
+	RGB_GAMMA_CH2_SELECTED,
+	RGB_GAMMA_CH0_CH1_SELECTED,
+	RGB_GAMMA_CH0_CH2_SELECTED,
+	RGB_GAMMA_CH1_CH2_SELECTED,
+	RGB_GAMMA_CH0_CH1_CH2_SELECTED
+};
+
+struct vfe_cmd_rgb_gamma_config {
+	uint8_t enable;
+	enum VFE_RGB_GAMMA_TABLE_SELECT channelSelect;
+	int16_t table[VFE_GAMMA_TABLE_LENGTH];
+};
+
+struct vfe_cmd_chroma_enhan_config {
+	uint8_t  enable;
+	int16_t am;
+	int16_t ap;
+	int16_t bm;
+	int16_t bp;
+	int16_t cm;
+	int16_t cp;
+	int16_t dm;
+	int16_t dp;
+	int16_t kcr;
+	int16_t kcb;
+	int16_t RGBtoYConversionV0;
+	int16_t RGBtoYConversionV1;
+	int16_t RGBtoYConversionV2;
+	uint8_t RGBtoYConversionOffset;
+};
+
+struct vfe_cmd_chroma_suppression_config {
+	uint8_t enable;
+	uint8_t m1;
+	uint8_t m3;
+	uint8_t n1;
+	uint8_t n3;
+	uint8_t nn1;
+	uint8_t mm1;
+};
+
+struct vfe_cmd_asf_config {
+	uint8_t enable;
+	uint8_t smoothFilterEnabled;
+	uint8_t sharpMode;
+	uint8_t smoothCoefCenter;
+	uint8_t smoothCoefSurr;
+	uint8_t normalizeFactor;
+	uint8_t sharpK1;
+	uint8_t sharpK2;
+	uint8_t sharpThreshE1;
+	int8_t sharpThreshE2;
+	int8_t sharpThreshE3;
+	int8_t sharpThreshE4;
+	int8_t sharpThreshE5;
+	int8_t filter1Coefficients[9];
+	int8_t filter2Coefficients[9];
+	uint8_t  cropEnable;
+	uint16_t cropFirstPixel;
+	uint16_t cropLastPixel;
+	uint16_t cropFirstLine;
+	uint16_t cropLastLine;
+};
+
+struct vfe_cmd_asf_update {
+	uint8_t enable;
+	uint8_t smoothFilterEnabled;
+	uint8_t sharpMode;
+	uint8_t smoothCoefCenter;
+	uint8_t smoothCoefSurr;
+	uint8_t normalizeFactor;
+	uint8_t sharpK1;
+	uint8_t sharpK2;
+	uint8_t sharpThreshE1;
+	int8_t  sharpThreshE2;
+	int8_t  sharpThreshE3;
+	int8_t  sharpThreshE4;
+	int8_t  sharpThreshE5;
+	int8_t  filter1Coefficients[9];
+	int8_t  filter2Coefficients[9];
+	uint8_t cropEnable;
+};
+
+enum VFE_TEST_GEN_SYNC_EDGE {
+	VFE_TEST_GEN_SYNC_EDGE_ActiveHigh,
+	VFE_TEST_GEN_SYNC_EDGE_ActiveLow
+};
+
+
+struct vfe_cmd_bus_pm_start {
+	uint8_t output2YWrPmEnable;
+	uint8_t output2CbcrWrPmEnable;
+	uint8_t output1YWrPmEnable;
+	uint8_t output1CbcrWrPmEnable;
+};
+
+struct  vfe_frame_skip_counts {
+	uint32_t  totalFrameCount;
+	uint32_t  output1Count;
+	uint32_t  output2Count;
+};
+
+enum VFE_AXI_RD_UNPACK_HBI_SEL {
+	VFE_AXI_RD_HBI_32_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_64_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_128_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_256_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_512_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_1024_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_2048_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_4096_CLOCK_CYCLES
+};
+
+struct vfe_frame_bpc_info {
+	uint32_t greenDefectPixelCount;
+	uint32_t redBlueDefectPixelCount;
+};
+
+struct vfe_frame_asf_info {
+	uint32_t  asfMaxEdge;
+	uint32_t  asfHbiCount;
+};
+
+struct vfe_msg_camif_status {
+	uint8_t  camifState;
+	uint32_t pixelCount;
+	uint32_t lineCount;
+};
+
+struct vfe40_irq_status {
+	uint32_t vfeIrqStatus0;
+	uint32_t vfeIrqStatus1;
+	uint32_t camifStatus;
+	uint32_t demosaicStatus;
+	uint32_t asfMaxEdge;
+};
+
+#define V40_PREVIEW_AXI_FLAG  0x00000001
+#define V40_SNAPSHOT_AXI_FLAG (0x00000001<<1)
+
+struct vfe40_cmd_type {
+	uint16_t id;
+	uint32_t length;
+	uint32_t offset;
+	uint32_t flag;
+};
+
+struct vfe40_free_buf {
+	struct list_head node;
+	uint32_t paddr;
+	uint32_t y_off;
+	uint32_t cbcr_off;
+};
+
+struct vfe40_output_ch {
+	struct list_head free_buf_queue;
+	spinlock_t free_buf_lock;
+	uint32_t inst_handle;
+	int8_t ch0;
+	int8_t ch1;
+	int8_t ch2;
+	uint32_t  capture_cnt;
+	uint32_t  frame_drop_cnt;
+	struct msm_free_buf ping;
+	struct msm_free_buf pong;
+	struct msm_free_buf free_buf;
+};
+
+/* no error irq in mask 0 */
+#define VFE40_IMASK_ERROR_ONLY_0  0x0
+/* when normal case, don't want to block error status. */
+/* bit 0-21 are error irq bits */
+#define VFE40_IMASK_COMMON_ERROR_ONLY_1       0x0000FF00
+#define VFE40_IMASK_VFE_ERROR_ONLY_1          0x00FF01FF
+#define VFE40_IMASK_CAMIF_ERROR               (0x00000001<<0)
+#define VFE40_IMASK_BHIST_OVWR                (0x00000001<<1)
+#define VFE40_IMASK_STATS_CS_OVWR             (0x00000001<<2)
+#define VFE40_IMASK_STATS_IHIST_OVWR          (0x00000001<<3)
+#define VFE40_IMASK_REALIGN_BUF_Y_OVFL        (0x00000001<<4)
+#define VFE40_IMASK_REALIGN_BUF_CB_OVFL       (0x00000001<<5)
+#define VFE40_IMASK_REALIGN_BUF_CR_OVFL       (0x00000001<<6)
+#define VFE40_IMASK_VIOLATION                 (0x00000001<<7)
+#define VFE40_IMASK_BUS_BDG_HALT_ACK          (0x00000001<<8)
+#define VFE40_IMASK_IMG_MAST_0_BUS_OVFL       (0x00000001<<9)
+#define VFE40_IMASK_IMG_MAST_1_BUS_OVFL       (0x00000001<<10)
+#define VFE40_IMASK_IMG_MAST_2_BUS_OVFL       (0x00000001<<11)
+#define VFE40_IMASK_IMG_MAST_3_BUS_OVFL       (0x00000001<<12)
+#define VFE40_IMASK_IMG_MAST_4_BUS_OVFL       (0x00000001<<13)
+#define VFE40_IMASK_IMG_MAST_5_BUS_OVFL       (0x00000001<<14)
+#define VFE40_IMASK_IMG_MAST_6_BUS_OVFL       (0x00000001<<15)
+#define VFE40_IMASK_STATS_BE_BUS_OVFL         (0x00000001<<16)
+#define VFE40_IMASK_STATS_BG_BUS_OVFL         (0x00000001<<17)
+#define VFE40_IMASK_STATS_BF_BUS_OVFL         (0x00000001<<18)
+#define VFE40_IMASK_STATS_AWB_BUS_OVFL        (0x00000001<<19)
+#define VFE40_IMASK_STATS_RS_BUS_OVFL         (0x00000001<<10)
+#define VFE40_IMASK_STATS_CS_BUS_OVFL         (0x00000001<<21)
+#define VFE40_IMASK_STATS_IHIST_BUS_OVFL      (0x00000001<<22)
+#define VFE40_IMASK_STATS_SKIN_BHIST_BUS_OVFL (0x00000001<<23)
+
+#define VFE_COM_STATUS 0x000FE000
+
+struct vfe40_output_path {
+	uint16_t output_mode;     /* bitmask  */
+
+	struct vfe40_output_ch out0; /* preview and thumbnail */
+	struct vfe40_output_ch out1; /* snapshot */
+	struct vfe40_output_ch out2; /* rdi0    */
+	struct vfe40_output_ch out3; /* rdi01   */
+};
+
+struct vfe40_frame_extra {
+	uint32_t greenDefectPixelCount;
+	uint32_t redBlueDefectPixelCount;
+
+	uint32_t  asfMaxEdge;
+	uint32_t  asfHbiCount;
+
+	uint32_t yWrPmStats0;
+	uint32_t yWrPmStats1;
+	uint32_t cbcrWrPmStats0;
+	uint32_t cbcrWrPmStats1;
+
+	uint32_t  frameCounter;
+};
+
+#define VFE_HW_VERSION			0x00000000
+#define VFE_GLOBAL_RESET                0x0000000C
+#define VFE_MODULE_RESET                0x00000010
+#define VFE_CGC_OVERRIDE                0x00000014
+#define VFE_MODULE_CFG                  0x00000018
+#define VFE_CFG				            0x0000001C
+#define VFE_IRQ_CMD                     0x00000024
+#define VFE_IRQ_MASK_0                  0x00000028
+#define VFE_IRQ_MASK_1                  0x0000002C
+#define VFE_IRQ_CLEAR_0                 0x00000030
+#define VFE_IRQ_CLEAR_1                 0x00000034
+#define VFE_IRQ_STATUS_0                0x00000038
+#define VFE_IRQ_STATUS_1                0x0000003C
+#define VFE_IRQ_COMP_MASK               0x00000040
+#define VFE_BUS_CMD                     0x0000004C
+#define VFE_BUS_PING_PONG_STATUS        0x00000268
+#define VFE_AXI_CMD                     0x000002C0
+#define VFE_AXI_STATUS                  0x000002E4
+#define VFE_BUS_STATS_PING_PONG_BASE    0x00000168
+
+#define VFE_BUS_STATS_BE_WR_PING_ADDR    0x00000168
+#define VFE_BUS_STATS_BE_WR_PONG_ADDR    0x0000016C
+#define VFE_BUS_STATS_BE_WR_ADDR_CFG    0x00000170
+#define VFE_BUS_STATS_BE_WR_UB_CFG          0x00000174
+#define VFE_BUS_STATS_BE_WR_FRAMEDROP_PATTERN  0x00000178
+#define VFE_BUS_STATS_BE_WR_IRQ_SUBSAMPLE_PATTERN 0x0000017C
+
+#define VFE_BUS_STATS_BG_WR_PING_ADDR     0x00000180
+#define VFE_BUS_STATS_BG_WR_PONG_ADDR     0x00000184
+#define VFE_BUS_STATS_BG_WR_ADDR_CFG      0x00000188
+#define VFE_BUS_STATS_BG_WR_UB_CFG        0x0000018C
+#define VFE_BUS_STATS_BG_WR_FRAMEDROP_PATTERN 0x00000190
+#define VFE_BUS_STATS_BG_WR_IRQ_SUBSAMPLE_PATTERN 0x00000194
+
+#define VFE_BUS_STATS_BF_WR_PING_ADDR     0x00000198
+#define VFE_BUS_STATS_BF_WR_PONG_ADDR     0x0000019C
+#define VFE_BUS_STATS_BF_WR_ADDR_CFG      0x000001A0
+#define VFE_BUS_STATS_BF_WR_UB_CFG        0x000001A4
+#define VFE_BUS_STATS_BF_WR_FRAMEDROP_PATTERN  0x000001A8
+#define VFE_BUS_STATS_BF_WR_IRQ_SUBSAMPLE_PATTERN  0x000001AC
+
+#define VFE_BUS_STATS_AWB_WR_PING_ADDR    0x000001B0
+#define VFE_BUS_STATS_AWB_WR_PONG_ADDR    0x000001B4
+#define VFE_BUS_STATS_AWB_WR_ADDR_CFG     0x000001B8
+#define VFE_BUS_STATS_AWB_WR_UB_CFG       0x000001BC
+#define VFE_BUS_STATS_AWB_WR_FRAMEDROP_PATTERN  0x000001C0
+#define VFE_BUS_STATS_AWB_WR_IRQ_SUBSAMPLE_PATTERN  0x000001C4
+
+#define VFE_BUS_STATS_RS_WR_PING_ADDR     0x000001C8
+#define VFE_BUS_STATS_RS_WR_PONG_ADDR     0x000001CC
+#define VFE_BUS_STATS_RS_WR_ADDR_CFG      0x000001D0
+#define VFE_BUS_STATS_RS_WR_UB_CFG    0x000001D4
+#define VFE_BUS_STATS_RS_WR_FRAMEDROP_PATTERN      0x000001D8
+#define VFE_BUS_STATS_RS_WR_IRQ_SUBSAMPLE_PATTERN  0x000001DC
+
+#define VFE_BUS_STATS_CS_WR_PING_ADDR     0x000001E0
+#define VFE_BUS_STATS_CS_WR_PONG_ADDR     0x000001E4
+#define VFE_BUS_STATS_CS_WR_ADDR_CFG      0x000001E8
+#define VFE_BUS_STATS_CS_WR_UB_CFG        0x000001EC
+#define VFE_BUS_STATS_CS_WR_FRAMEDROP_PATTERN     0x000001F0
+#define VFE_BUS_STATS_CS_WR_IRQ_SUBSAMPLE_PATTERN 0x000001F4
+
+#define VFE_BUS_STATS_HIST_WR_PING_ADDR   0x000001F8
+#define VFE_BUS_STATS_HIST_WR_PONG_ADDR   0x000001FC
+#define VFE_BUS_STATS_HIST_WR_ADDR_CFG    0x00000200
+#define VFE_BUS_STATS_HIST_WR_UB_CFG      0x00000204
+#define VFE_BUS_STATS_HIST_WR_FRAMEDROP_PATTERN      0x00000208
+#define VFE_BUS_STATS_HIST_WR_IRQ_SUBSAMPLE_PATTERN  0x0000020C
+
+
+#define VFE_BUS_STATS_SKIN_WR_PING_ADDR   0x00000210
+#define VFE_BUS_STATS_SKIN_WR_PONG_ADDR   0x00000214
+#define VFE_BUS_STATS_SKIN_WR_ADDR_CFG    0x00000218
+#define VFE_BUS_STATS_SKIN_WR_UB_CFG      0x0000021C
+#define VFE_BUS_STATS_SKIN_WR_FRAMEDROP_PATTERN       0x00000220
+#define VFE_BUS_STATS_SKIN_WR_IRQ_SUBSAMPLE_PATTERN   0x00000224
+
+#define VFE_0_BUS_BDG_QOS_CFG_0     0x000002C4
+#define VFE_0_BUS_BDG_QOS_CFG_1     0x000002C8
+#define VFE_0_BUS_BDG_QOS_CFG_2     0x000002CC
+#define VFE_0_BUS_BDG_QOS_CFG_3     0x000002D0
+#define VFE_0_BUS_BDG_QOS_CFG_4     0x000002D4
+#define VFE_0_BUS_BDG_QOS_CFG_5     0x000002D8
+#define VFE_0_BUS_BDG_QOS_CFG_6     0x000002DC
+#define VFE_0_BUS_BDG_QOS_CFG_7     0x000002E0
+
+#define VFE_CAMIF_COMMAND               0x000002F4
+#define VFE_CAMIF_STATUS                0x0000031C
+#define VFE_REG_UPDATE_CMD              0x00000378
+#define VFE_DEMUX_GAIN_0                0x00000428
+#define VFE_DEMUX_GAIN_1                0x0000042C
+#define VFE_CHROMA_UP                   0x0000057C
+
+#define VFE_CLAMP_ENC_MAX               0x00000874
+#define VFE_CLAMP_ENC_MIN               0x00000878
+#define VFE_CLAMP_VIEW_MAX              0x0000087C
+#define VFE_CLAMP_VIEW_MIN              0x00000880
+
+#define VFE_REALIGN_BUF                 0x00000884
+#define VFE_STATS_CFG                   0x00000888
+#define VFE_STATS_AWB_SGW_CFG           0x000008CC
+#define VFE_DMI_CFG                     0x00000910
+#define VFE_DMI_ADDR                    0x00000914
+#define VFE_DMI_DATA_HI                 0x00000918
+#define VFE_DMI_DATA_LO                 0x0000091C
+#define VFE_BUS_IO_FORMAT_CFG           0x00000054
+#define VFE_RDI0_CFG                    0x000002E8
+#define VFE_RDI1_CFG                    0x000002EC
+#define VFE_RDI2_CFG                    0x000002F0
+
+#define VFE_VIOLATION_STATUS            0x00000048
+
+#define VFE40_DMI_DATA_HI               0x00000918
+#define VFE40_DMI_DATA_LO               0x0000091C
+
+#define VFE40_OUTPUT_MODE_PT			BIT(0)
+#define VFE40_OUTPUT_MODE_S			BIT(1)
+#define VFE40_OUTPUT_MODE_V			BIT(2)
+#define VFE40_OUTPUT_MODE_P			BIT(3)
+#define VFE40_OUTPUT_MODE_T			BIT(4)
+#define VFE40_OUTPUT_MODE_P_ALL_CHNLS		BIT(5)
+#define VFE40_OUTPUT_MODE_PRIMARY		BIT(6)
+#define VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS	BIT(7)
+#define VFE40_OUTPUT_MODE_SECONDARY		BIT(8)
+#define VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS	BIT(9)
+#define VFE40_OUTPUT_MODE_TERTIARY1		BIT(10)
+#define VFE40_OUTPUT_MODE_TERTIARY2		BIT(11)
+
+#define VFE40_VBIF_CLKON					0x4
+#define VFE40_VBIF_IN_RD_LIM_CONF0			0xB0
+#define VFE40_VBIF_IN_RD_LIM_CONF1			0xB4
+#define VFE40_VBIF_IN_RD_LIM_CONF2			0xB8
+#define VFE40_VBIF_IN_WR_LIM_CONF0			0xC0
+#define VFE40_VBIF_IN_WR_LIM_CONF1			0xC4
+#define VFE40_VBIF_IN_WR_LIM_CONF2			0xC8
+#define VFE40_VBIF_OUT_RD_LIM_CONF0			0xD0
+#define VFE40_VBIF_OUT_WR_LIM_CONF0			0xD4
+#define VFE40_VBIF_DDR_OUT_MAX_BURST		0xD8
+#define VFE40_VBIF_OCMEM_OUT_MAX_BURST		0xDC
+#define VFE40_VBIF_ARB_CTL					0xF0
+#define VFE40_VBIF_DDR_ARB_CONF0			0xF4
+#define VFE40_VBIF_DDR_ARB_CONF1			0xF8
+#define VFE40_VBIF_ROUND_ROBIN_QOS_ARB		0x124
+#define VFE40_VBIF_OUT_AXI_AMEMTYPE_CONF0	0x160
+#define VFE40_VBIF_OUT_AXI_AMEMTYPE_CONF1	0x164
+#define VFE40_VBIF_OUT_AXI_AOOO_EN			0x178
+#define VFE40_VBIF_OUT_AXI_AOOO				0x17C
+
+struct vfe_stats_control {
+	uint32_t droppedStatsFrameCount;
+	uint32_t bufToRender;
+};
+struct axi_ctrl_t;
+struct vfe40_ctrl_type;
+
+struct vfe_share_ctrl_t {
+	void __iomem *vfebase;
+	void __iomem *vfe_vbif_base;
+	uint32_t register_total;
+
+	atomic_t vstate;
+	atomic_t handle_common_irq;
+	uint32_t vfeFrameId;
+	uint32_t rdi0FrameId;
+	uint32_t rdi1FrameId;
+	uint32_t rdi2FrameId;
+	uint32_t stats_comp;
+	spinlock_t  sd_notify_lock;
+	spinlock_t  stop_flag_lock;
+	int8_t stop_ack_pending;
+	enum vfe_output_state liveshot_state;
+	uint32_t vfe_capture_count;
+
+	uint32_t operation_mode;     /* streaming or snapshot */
+	uint32_t current_mode;
+	struct vfe40_output_path outpath;
+
+	uint16_t port_info;
+	uint8_t stop_immediately;
+	uint8_t sync_abort;
+	uint16_t cmd_type;
+	uint8_t vfe_reset_flag;
+
+	uint8_t axi_ref_cnt;
+	uint16_t comp_output_mode;
+
+	struct completion reset_complete;
+
+	spinlock_t  update_ack_lock;
+	spinlock_t  start_ack_lock;
+
+	struct axi_ctrl_t *axi_ctrl;
+	struct vfe40_ctrl_type *vfe40_ctrl;
+	int8_t start_ack_pending;
+	int8_t update_ack_pending;
+	enum vfe_output_state recording_state;
+
+	atomic_t pix0_update_ack_pending;
+	atomic_t rdi0_update_ack_pending;
+	atomic_t rdi1_update_ack_pending;
+	atomic_t rdi2_update_ack_pending;
+};
+
+struct axi_ctrl_t {
+	struct v4l2_subdev subdev;
+	struct platform_device *pdev;
+	struct resource *vfeirq;
+	spinlock_t  tasklet_lock;
+	struct list_head tasklet_q;
+
+	void *syncdata;
+
+	struct resource	*vfemem;
+	struct resource	*vfe_vbif_mem;
+	struct resource *vfeio;
+	struct resource *vfe_vbif_io;
+	struct regulator *fs_vfe;
+	struct clk *vfe_clk[7];
+	struct tasklet_struct vfe40_tasklet;
+	struct vfe_share_ctrl_t *share_ctrl;
+	struct device *iommu_ctx;
+	uint32_t bus_perf_client;
+	uint32_t use_irq_router;
+};
+
+struct vfe40_ctrl_type {
+	spinlock_t  state_lock;
+	spinlock_t  stats_bufq_lock;
+	uint32_t extlen;
+	void *extdata;
+
+	int8_t vfe_sof_count_enable;
+	int8_t update_linear;
+	int8_t update_rolloff;
+	int8_t update_la;
+	int8_t update_gamma;
+
+	struct vfe_share_ctrl_t *share_ctrl;
+
+	uint32_t sync_timer_repeat_count;
+	uint32_t sync_timer_state;
+	uint32_t sync_timer_number;
+
+	struct msm_ver_num_info ver_num;
+	struct vfe_stats_control beStatsControl;
+	struct vfe_stats_control bfStatsControl;
+	struct vfe_stats_control awbStatsControl;
+	struct vfe_stats_control bgStatsControl;
+	struct vfe_stats_control ihistStatsControl;
+	struct vfe_stats_control rsStatsControl;
+	struct vfe_stats_control csStatsControl;
+	struct vfe_stats_control bhistStatsControl;
+
+	/* v4l2 subdev */
+	struct v4l2_subdev subdev;
+	struct platform_device *pdev;
+	uint32_t hfr_mode;
+	uint32_t frame_skip_cnt;
+	uint32_t frame_skip_pattern;
+	uint32_t snapshot_frame_cnt;
+	struct msm_stats_bufq_ctrl stats_ctrl;
+	struct msm_stats_ops stats_ops;
+
+	uint32_t simultaneous_sof_stat;
+};
+
+#define statsBeNum      0
+#define statsBgNum      1
+#define statsBfNum      2
+#define statsAwbNum     3
+#define statsRsNum      4
+#define statsCsNum      5
+#define statsIhistNum   6
+#define statsSkinNum    7
+
+#define VFE_STATS_BUS_REG_NUM  6
+
+struct vfe_cmd_stats_ack {
+	uint32_t  nextStatsBuf;
+};
+
+#define VFE_STATS_BUFFER_COUNT            3
+
+struct vfe_cmd_stats_buf {
+	uint32_t statsBuf[VFE_STATS_BUFFER_COUNT];
+};
+
+#endif /* __MSM_VFE40_H__ */
diff --git a/drivers/media/platform/msm/camera_v1/vfe/msm_vfe40_axi.c b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe40_axi.c
new file mode 100644
index 0000000..88a219c
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe40_axi.c
@@ -0,0 +1,824 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/atomic.h>
+#include <linux/regulator/consumer.h>
+#include <linux/clk.h>
+#include <mach/irqs.h>
+#include <mach/camera.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+#include <media/msm_isp.h>
+
+#include "msm.h"
+#include "msm_vfe40.h"
+
+static int msm_axi_subdev_s_crystal_freq(struct v4l2_subdev *sd,
+						u32 freq, u32 flags)
+{
+	int rc = 0;
+	int round_rate;
+	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+
+	round_rate = clk_round_rate(axi_ctrl->vfe_clk[0], freq);
+	if (rc < 0) {
+		pr_err("%s: clk_round_rate failed %d\n",
+					__func__, rc);
+		return rc;
+	}
+
+	axi_ctrl->share_ctrl->vfe_clk_rate = round_rate;
+	rc = clk_set_rate(axi_ctrl->vfe_clk[0], round_rate);
+	if (rc < 0)
+		pr_err("%s: clk_set_rate failed %d\n",
+					__func__, rc);
+
+	return rc;
+}
+
+void axi_start(struct axi_ctrl_t *axi_ctrl)
+{
+	switch (axi_ctrl->share_ctrl->operation_mode) {
+	case VFE_OUTPUTS_PREVIEW:
+	case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
+		if (axi_ctrl->share_ctrl->outpath.output_mode &
+			VFE40_OUTPUT_MODE_PRIMARY) {
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out0.ch0]);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out0.ch1]);
+		} else if (axi_ctrl->share_ctrl->outpath.output_mode &
+				VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out0.ch0]);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out0.ch1]);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out0.ch2]);
+		}
+		break;
+	default:
+		if (axi_ctrl->share_ctrl->outpath.output_mode &
+			VFE40_OUTPUT_MODE_SECONDARY) {
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out1.ch0]);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out1.ch1]);
+		} else if (axi_ctrl->share_ctrl->outpath.output_mode &
+			VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out1.ch0]);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out1.ch1]);
+			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+				vfe40_AXI_WM_CFG[axi_ctrl->
+				share_ctrl->outpath.out1.ch2]);
+		}
+		break;
+	}
+}
+
+void axi_stop(struct axi_ctrl_t *axi_ctrl)
+{
+	uint8_t  axiBusyFlag = true;
+	/* axi halt command. */
+	msm_camera_io_w(AXI_HALT,
+		axi_ctrl->share_ctrl->vfebase + VFE_AXI_CMD);
+	wmb();
+	while (axiBusyFlag) {
+		if (msm_camera_io_r(
+			axi_ctrl->share_ctrl->vfebase + VFE_AXI_STATUS) & 0x1)
+			axiBusyFlag = false;
+	}
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_camera_io_w_mb(AXI_HALT_CLEAR,
+		axi_ctrl->share_ctrl->vfebase + VFE_AXI_CMD);
+
+	/* after axi halt, then ok to apply global reset. */
+	/* enable reset_ack and async timer interrupt only while
+	stopping the pipeline.*/
+	msm_camera_io_w(0xf0000000,
+		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_0);
+	msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_1,
+		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+	/* Ensure the write order while writing
+	to the command register using the barrier */
+	msm_camera_io_w_mb(VFE_RESET_UPON_STOP_CMD,
+		axi_ctrl->share_ctrl->vfebase + VFE_GLOBAL_RESET);
+}
+
+static int vfe40_config_axi(
+	struct axi_ctrl_t *axi_ctrl, int mode, uint32_t *ao)
+{
+	uint32_t *ch_info;
+	uint32_t *axi_cfg = ao;
+
+	/* Update the corresponding write masters for each output*/
+	ch_info = axi_cfg + V40_AXI_CFG_LEN;
+	axi_ctrl->share_ctrl->outpath.out0.ch0 = 0x0000FFFF & *ch_info;
+	axi_ctrl->share_ctrl->outpath.out0.ch1 =
+		0x0000FFFF & (*ch_info++ >> 16);
+	axi_ctrl->share_ctrl->outpath.out0.ch2 = 0x0000FFFF & *ch_info;
+	axi_ctrl->share_ctrl->outpath.out0.image_mode =
+		0x0000FFFF & (*ch_info++ >> 16);
+	axi_ctrl->share_ctrl->outpath.out1.ch0 = 0x0000FFFF & *ch_info;
+	axi_ctrl->share_ctrl->outpath.out1.ch1 =
+		0x0000FFFF & (*ch_info++ >> 16);
+	axi_ctrl->share_ctrl->outpath.out1.ch2 = 0x0000FFFF & *ch_info;
+	axi_ctrl->share_ctrl->outpath.out1.image_mode =
+		0x0000FFFF & (*ch_info++ >> 16);
+	axi_ctrl->share_ctrl->outpath.out2.ch0 = 0x0000FFFF & *ch_info;
+	axi_ctrl->share_ctrl->outpath.out2.ch1 =
+		0x0000FFFF & (*ch_info++ >> 16);
+	axi_ctrl->share_ctrl->outpath.out2.ch2 = 0x0000FFFF & *ch_info++;
+
+	switch (mode) {
+	case OUTPUT_PRIM:
+		axi_ctrl->share_ctrl->outpath.output_mode =
+			VFE40_OUTPUT_MODE_PRIMARY;
+		break;
+	case OUTPUT_PRIM_ALL_CHNLS:
+		axi_ctrl->share_ctrl->outpath.output_mode =
+			VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
+		break;
+	case OUTPUT_PRIM|OUTPUT_SEC:
+		axi_ctrl->share_ctrl->outpath.output_mode =
+			VFE40_OUTPUT_MODE_PRIMARY;
+		axi_ctrl->share_ctrl->outpath.output_mode |=
+			VFE40_OUTPUT_MODE_SECONDARY;
+		break;
+	case OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS:
+		axi_ctrl->share_ctrl->outpath.output_mode =
+			VFE40_OUTPUT_MODE_PRIMARY;
+		axi_ctrl->share_ctrl->outpath.output_mode |=
+			VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS;
+		break;
+	case OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC:
+		axi_ctrl->share_ctrl->outpath.output_mode =
+			VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
+		axi_ctrl->share_ctrl->outpath.output_mode |=
+			VFE40_OUTPUT_MODE_SECONDARY;
+		break;
+	default:
+		pr_err("%s Invalid AXI mode %d ", __func__, mode);
+		return -EINVAL;
+	}
+	msm_camera_io_w(*ao, axi_ctrl->share_ctrl->vfebase +
+		VFE_BUS_IO_FORMAT_CFG);
+	msm_camera_io_memcpy(axi_ctrl->share_ctrl->vfebase +
+		vfe40_cmd[VFE_CMD_AXI_OUT_CFG].offset, axi_cfg,
+		vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length - V40_AXI_CH_INF_LEN);
+	msm_camera_io_w(*ch_info++,
+		axi_ctrl->share_ctrl->vfebase + VFE_RDI0_CFG);
+	if (msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
+		V40_GET_HW_VERSION_OFF) ==
+		VFE40_HW_NUMBER) {
+		msm_camera_io_w(*ch_info++,
+			axi_ctrl->share_ctrl->vfebase + VFE_RDI1_CFG);
+		msm_camera_io_w(*ch_info++,
+			axi_ctrl->share_ctrl->vfebase + VFE_RDI2_CFG);
+	}
+	return 0;
+}
+
+static int msm_axi_config(struct v4l2_subdev *sd, void __user *arg)
+{
+	struct msm_vfe_cfg_cmd cfgcmd;
+	struct msm_isp_cmd vfecmd;
+	int rc = 0;
+	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+
+	if (!axi_ctrl->share_ctrl->vfebase) {
+		pr_err("%s: base address unmapped\n", __func__);
+		return -EFAULT;
+	}
+	if (NULL != arg) {
+		if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
+			ERR_COPY_FROM_USER();
+			return -EFAULT;
+		}
+	}
+	if (NULL != cfgcmd.value) {
+		if (copy_from_user(&vfecmd,
+				(void __user *)(cfgcmd.value),
+				sizeof(vfecmd))) {
+			pr_err("%s %d: copy_from_user failed\n", __func__,
+				__LINE__);
+			return -EFAULT;
+		}
+	}
+
+	switch (cfgcmd.cmd_type) {
+	case CMD_AXI_CFG_PRIM: {
+		uint32_t *axio = NULL;
+		axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe40_config_axi(axi_ctrl, OUTPUT_PRIM, axio);
+		kfree(axio);
+	}
+		break;
+	case CMD_AXI_CFG_PRIM_ALL_CHNLS: {
+		uint32_t *axio = NULL;
+		axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe40_config_axi(axi_ctrl, OUTPUT_PRIM_ALL_CHNLS, axio);
+		kfree(axio);
+	}
+		break;
+	case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC: {
+		uint32_t *axio = NULL;
+		axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe40_config_axi(axi_ctrl, OUTPUT_PRIM|OUTPUT_SEC, axio);
+		kfree(axio);
+	}
+		break;
+	case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC_ALL_CHNLS: {
+		uint32_t *axio = NULL;
+		axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe40_config_axi(axi_ctrl,
+			OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS, axio);
+		kfree(axio);
+	}
+		break;
+	case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC: {
+		uint32_t *axio = NULL;
+		axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe40_config_axi(axi_ctrl,
+			OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC, axio);
+		kfree(axio);
+	}
+		break;
+	case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC_ALL_CHNLS:
+		pr_err("%s Invalid/Unsupported AXI configuration %x",
+			__func__, cfgcmd.cmd_type);
+		break;
+	case CMD_AXI_START:
+		axi_start(axi_ctrl);
+		break;
+	case CMD_AXI_STOP:
+		axi_stop(axi_ctrl);
+		break;
+	case CMD_AXI_RESET:
+		break;
+	default:
+		pr_err("%s Unsupported AXI configuration %x ", __func__,
+			cfgcmd.cmd_type);
+		break;
+	}
+	return rc;
+}
+
+static struct msm_free_buf *vfe40_check_free_buffer(
+	int id, int path, struct axi_ctrl_t *axi_ctrl)
+{
+	struct vfe40_output_ch *outch = NULL;
+	struct msm_free_buf *b = NULL;
+	uint32_t image_mode = 0;
+
+	if (path == VFE_MSG_OUTPUT_PRIMARY)
+		image_mode = axi_ctrl->share_ctrl->outpath.out0.image_mode;
+	else
+		image_mode = axi_ctrl->share_ctrl->outpath.out1.image_mode;
+
+	vfe40_subdev_notify(id, path, image_mode,
+		&axi_ctrl->subdev, axi_ctrl->share_ctrl);
+	outch = vfe40_get_ch(path, axi_ctrl->share_ctrl);
+	if (outch->free_buf.ch_paddr[0])
+		b = &outch->free_buf;
+	return b;
+}
+
+static void vfe_send_outmsg(
+	struct axi_ctrl_t *axi_ctrl, uint8_t msgid,
+	uint32_t ch0_paddr, uint32_t ch1_paddr,
+	uint32_t ch2_paddr, uint32_t image_mode)
+{
+	struct isp_msg_output msg;
+
+	msg.output_id = msgid;
+	msg.buf.image_mode = image_mode;
+	msg.buf.ch_paddr[0]	= ch0_paddr;
+	msg.buf.ch_paddr[1]	= ch1_paddr;
+	msg.buf.ch_paddr[2]	= ch2_paddr;
+	msg.frameCounter = axi_ctrl->share_ctrl->vfeFrameId;
+
+	v4l2_subdev_notify(&axi_ctrl->subdev,
+			NOTIFY_VFE_MSG_OUT,
+			&msg);
+	return;
+}
+
+static void vfe40_process_output_path_irq_0(
+	struct axi_ctrl_t *axi_ctrl)
+{
+	uint32_t ping_pong;
+	uint32_t ch0_paddr, ch1_paddr, ch2_paddr;
+	uint8_t out_bool = 0;
+	struct msm_free_buf *free_buf = NULL;
+
+	free_buf = vfe40_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
+		VFE_MSG_OUTPUT_PRIMARY, axi_ctrl);
+
+	/* we render frames in the following conditions:
+	1. Continuous mode and the free buffer is avaialable.
+	2. In snapshot shot mode, free buffer is not always available.
+	when pending snapshot count is <=1,  then no need to use
+	free buffer.
+	*/
+	out_bool = (
+		(axi_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_THUMB_AND_MAIN ||
+		axi_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_MAIN_AND_THUMB ||
+		axi_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_THUMB_AND_JPEG ||
+		axi_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_JPEG_AND_THUMB ||
+		axi_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_RAW ||
+		axi_ctrl->share_ctrl->liveshot_state ==
+			VFE_STATE_STARTED ||
+		axi_ctrl->share_ctrl->liveshot_state ==
+			VFE_STATE_STOP_REQUESTED ||
+		axi_ctrl->share_ctrl->liveshot_state ==
+			VFE_STATE_STOPPED) &&
+		(axi_ctrl->share_ctrl->vfe_capture_count <= 1)) ||
+			free_buf;
+
+	if (out_bool) {
+		ping_pong = msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
+			VFE_BUS_PING_PONG_STATUS);
+
+		/* Channel 0*/
+		ch0_paddr = vfe40_get_ch_addr(
+			ping_pong, axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out0.ch0);
+		/* Channel 1*/
+		ch1_paddr = vfe40_get_ch_addr(
+			ping_pong, axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out0.ch1);
+		/* Channel 2*/
+		ch2_paddr = vfe40_get_ch_addr(
+			ping_pong, axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out0.ch2);
+
+		CDBG("output path 0, ch0 = 0x%x, ch1 = 0x%x, ch2 = 0x%x\n",
+			ch0_paddr, ch1_paddr, ch2_paddr);
+		if (free_buf) {
+			/* Y channel */
+			vfe40_put_ch_addr(ping_pong,
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out0.ch0,
+			free_buf->ch_paddr[0]);
+			/* Chroma channel */
+			vfe40_put_ch_addr(ping_pong,
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out0.ch1,
+			free_buf->ch_paddr[1]);
+			if (free_buf->num_planes > 2)
+				vfe40_put_ch_addr(ping_pong,
+					axi_ctrl->share_ctrl->vfebase,
+					axi_ctrl->share_ctrl->outpath.out0.ch2,
+					free_buf->ch_paddr[2]);
+		}
+		if (axi_ctrl->share_ctrl->operation_mode ==
+				VFE_OUTPUTS_THUMB_AND_MAIN ||
+			axi_ctrl->share_ctrl->operation_mode ==
+				VFE_OUTPUTS_MAIN_AND_THUMB ||
+			axi_ctrl->share_ctrl->operation_mode ==
+				VFE_OUTPUTS_THUMB_AND_JPEG ||
+			axi_ctrl->share_ctrl->operation_mode ==
+				VFE_OUTPUTS_JPEG_AND_THUMB ||
+			axi_ctrl->share_ctrl->operation_mode ==
+				VFE_OUTPUTS_RAW ||
+			axi_ctrl->share_ctrl->liveshot_state ==
+				VFE_STATE_STOPPED)
+			axi_ctrl->share_ctrl->outpath.out0.capture_cnt--;
+
+		vfe_send_outmsg(axi_ctrl,
+			MSG_ID_OUTPUT_PRIMARY, ch0_paddr,
+			ch1_paddr, ch2_paddr,
+			axi_ctrl->share_ctrl->outpath.out0.image_mode);
+
+		if (axi_ctrl->share_ctrl->liveshot_state == VFE_STATE_STOPPED)
+			axi_ctrl->share_ctrl->liveshot_state = VFE_STATE_IDLE;
+
+	} else {
+		axi_ctrl->share_ctrl->outpath.out0.frame_drop_cnt++;
+		CDBG("path_irq_0 - no free buffer!\n");
+	}
+}
+
+static void vfe40_process_output_path_irq_1(
+	struct axi_ctrl_t *axi_ctrl)
+{
+	uint32_t ping_pong;
+	uint32_t ch0_paddr, ch1_paddr, ch2_paddr;
+	/* this must be snapshot main image output. */
+	uint8_t out_bool = 0;
+	struct msm_free_buf *free_buf = NULL;
+
+	free_buf = vfe40_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
+		VFE_MSG_OUTPUT_SECONDARY, axi_ctrl);
+	out_bool = ((axi_ctrl->share_ctrl->operation_mode ==
+				VFE_OUTPUTS_THUMB_AND_MAIN ||
+			axi_ctrl->share_ctrl->operation_mode ==
+				VFE_OUTPUTS_MAIN_AND_THUMB ||
+			axi_ctrl->share_ctrl->operation_mode ==
+				VFE_OUTPUTS_RAW ||
+			axi_ctrl->share_ctrl->operation_mode ==
+				VFE_OUTPUTS_JPEG_AND_THUMB) &&
+			(axi_ctrl->share_ctrl->vfe_capture_count <= 1)) ||
+				free_buf;
+
+	if (out_bool) {
+		ping_pong = msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
+			VFE_BUS_PING_PONG_STATUS);
+
+		/* Y channel */
+		ch0_paddr = vfe40_get_ch_addr(ping_pong,
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out1.ch0);
+		/* Chroma channel */
+		ch1_paddr = vfe40_get_ch_addr(ping_pong,
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out1.ch1);
+		ch2_paddr = vfe40_get_ch_addr(ping_pong,
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out1.ch2);
+
+		CDBG("%s ch0 = 0x%x, ch1 = 0x%x, ch2 = 0x%x\n",
+			__func__, ch0_paddr, ch1_paddr, ch2_paddr);
+		if (free_buf) {
+			/* Y channel */
+			vfe40_put_ch_addr(ping_pong,
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out1.ch0,
+			free_buf->ch_paddr[0]);
+			/* Chroma channel */
+			vfe40_put_ch_addr(ping_pong,
+			axi_ctrl->share_ctrl->vfebase,
+			axi_ctrl->share_ctrl->outpath.out1.ch1,
+			free_buf->ch_paddr[1]);
+			if (free_buf->num_planes > 2)
+				vfe40_put_ch_addr(ping_pong,
+					axi_ctrl->share_ctrl->vfebase,
+					axi_ctrl->share_ctrl->outpath.out1.ch2,
+					free_buf->ch_paddr[2]);
+		}
+		if (axi_ctrl->share_ctrl->operation_mode ==
+				VFE_OUTPUTS_THUMB_AND_MAIN ||
+			axi_ctrl->share_ctrl->operation_mode ==
+				VFE_OUTPUTS_MAIN_AND_THUMB ||
+			axi_ctrl->share_ctrl->operation_mode ==
+				VFE_OUTPUTS_RAW ||
+			axi_ctrl->share_ctrl->operation_mode ==
+				VFE_OUTPUTS_JPEG_AND_THUMB)
+			axi_ctrl->share_ctrl->outpath.out1.capture_cnt--;
+
+		vfe_send_outmsg(axi_ctrl,
+			MSG_ID_OUTPUT_SECONDARY, ch0_paddr,
+			ch1_paddr, ch2_paddr,
+			axi_ctrl->share_ctrl->outpath.out1.image_mode);
+
+	} else {
+		axi_ctrl->share_ctrl->outpath.out1.frame_drop_cnt++;
+		CDBG("path_irq_1 - no free buffer!\n");
+	}
+}
+
+static void msm_axi_process_irq(struct v4l2_subdev *sd, void *arg)
+{
+	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+	uint32_t irqstatus = (uint32_t) arg;
+
+	if (!axi_ctrl->share_ctrl->vfebase) {
+		pr_err("%s: base address unmapped\n", __func__);
+		return;
+	}
+	/* next, check output path related interrupts. */
+	if (irqstatus &
+		VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK) {
+		CDBG("Image composite done 0 irq occured.\n");
+		vfe40_process_output_path_irq_0(axi_ctrl);
+	}
+	if (irqstatus &
+		VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK) {
+		CDBG("Image composite done 1 irq occured.\n");
+		vfe40_process_output_path_irq_1(axi_ctrl);
+	}
+	/* in snapshot mode if done then send
+	snapshot done message */
+	if (axi_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_THUMB_AND_MAIN ||
+		axi_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_MAIN_AND_THUMB ||
+		axi_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_THUMB_AND_JPEG ||
+		axi_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_JPEG_AND_THUMB ||
+		axi_ctrl->share_ctrl->operation_mode ==
+			VFE_OUTPUTS_RAW) {
+		if ((axi_ctrl->share_ctrl->outpath.out0.capture_cnt == 0)
+				&& (axi_ctrl->share_ctrl->outpath.out1.
+				capture_cnt == 0)) {
+			msm_camera_io_w_mb(
+				CAMIF_COMMAND_STOP_IMMEDIATELY,
+				axi_ctrl->share_ctrl->vfebase +
+				VFE_CAMIF_COMMAND);
+			vfe40_send_isp_msg(&axi_ctrl->subdev,
+				axi_ctrl->share_ctrl->vfeFrameId,
+				MSG_ID_SNAPSHOT_DONE);
+		}
+	}
+}
+
+static int msm_axi_buf_cfg(struct v4l2_subdev *sd, void __user *arg)
+{
+	struct msm_camvfe_params *vfe_params =
+		(struct msm_camvfe_params *)arg;
+	struct msm_vfe_cfg_cmd *cmd = vfe_params->vfe_cfg;
+	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+	void *data = vfe_params->data;
+	int rc = 0;
+
+	if (!axi_ctrl->share_ctrl->vfebase) {
+		pr_err("%s: base address unmapped\n", __func__);
+		return -EFAULT;
+	}
+
+	switch (cmd->cmd_type) {
+	case CMD_CONFIG_PING_ADDR: {
+		int path = *((int *)cmd->value);
+		struct vfe40_output_ch *outch =
+			vfe40_get_ch(path, axi_ctrl->share_ctrl);
+		outch->ping = *((struct msm_free_buf *)data);
+	}
+		break;
+
+	case CMD_CONFIG_PONG_ADDR: {
+		int path = *((int *)cmd->value);
+		struct vfe40_output_ch *outch =
+			vfe40_get_ch(path, axi_ctrl->share_ctrl);
+		outch->pong = *((struct msm_free_buf *)data);
+	}
+		break;
+
+	case CMD_CONFIG_FREE_BUF_ADDR: {
+		int path = *((int *)cmd->value);
+		struct vfe40_output_ch *outch =
+			vfe40_get_ch(path, axi_ctrl->share_ctrl);
+		outch->free_buf = *((struct msm_free_buf *)data);
+	}
+		break;
+	default:
+		pr_err("%s Unsupported AXI Buf config %x ", __func__,
+			cmd->cmd_type);
+	}
+	return rc;
+};
+
+static struct msm_cam_clk_info vfe40_clk_info[] = {
+	{"vfe_clk_src", 266670000},
+	{"camss_vfe_vfe_clk", -1},
+	{"camss_csi_vfe_clk", -1},
+	{"top_clk", -1},
+	{"iface_clk", -1},
+	{"bus_clk", -1},
+};
+
+int msm_axi_subdev_init(struct v4l2_subdev *sd,
+			struct msm_cam_media_controller *mctl)
+{
+	int rc = 0;
+	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+	v4l2_set_subdev_hostdata(sd, mctl);
+	spin_lock_init(&axi_ctrl->tasklet_lock);
+	INIT_LIST_HEAD(&axi_ctrl->tasklet_q);
+	spin_lock_init(&axi_ctrl->share_ctrl->sd_notify_lock);
+
+	axi_ctrl->share_ctrl->vfebase = ioremap(axi_ctrl->vfemem->start,
+		resource_size(axi_ctrl->vfemem));
+	if (!axi_ctrl->share_ctrl->vfebase) {
+		rc = -ENOMEM;
+		pr_err("%s: vfe ioremap failed\n", __func__);
+		goto remap_failed;
+	}
+
+	if (axi_ctrl->fs_vfe == NULL) {
+		axi_ctrl->fs_vfe =
+			regulator_get(&axi_ctrl->pdev->dev, "vdd");
+		if (IS_ERR(axi_ctrl->fs_vfe)) {
+			pr_err("%s: Regulator FS_VFE get failed %ld\n",
+				__func__, PTR_ERR(axi_ctrl->fs_vfe));
+			axi_ctrl->fs_vfe = NULL;
+			goto fs_failed;
+		} else if (regulator_enable(axi_ctrl->fs_vfe)) {
+			pr_err("%s: Regulator FS_VFE enable failed\n",
+							__func__);
+			regulator_put(axi_ctrl->fs_vfe);
+			axi_ctrl->fs_vfe = NULL;
+			goto fs_failed;
+		}
+	}
+	rc = msm_cam_clk_enable(&axi_ctrl->pdev->dev, vfe40_clk_info,
+			axi_ctrl->vfe_clk, ARRAY_SIZE(vfe40_clk_info), 1);
+	if (rc < 0)
+			goto clk_enable_failed;
+
+	msm_camio_bus_scale_cfg(
+		mctl->sdata->pdata->cam_bus_scale_table, S_INIT);
+	msm_camio_bus_scale_cfg(
+		mctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
+
+	axi_ctrl->share_ctrl->register_total = VFE40_REGISTER_TOTAL;
+
+	enable_irq(axi_ctrl->vfeirq->start);
+
+	return rc;
+clk_enable_failed:
+	regulator_disable(axi_ctrl->fs_vfe);
+	regulator_put(axi_ctrl->fs_vfe);
+	axi_ctrl->fs_vfe = NULL;
+fs_failed:
+	iounmap(axi_ctrl->share_ctrl->vfebase);
+	axi_ctrl->share_ctrl->vfebase = NULL;
+remap_failed:
+	disable_irq(axi_ctrl->vfeirq->start);
+	return rc;
+}
+
+void msm_axi_subdev_release(struct v4l2_subdev *sd)
+{
+	struct msm_cam_media_controller *pmctl =
+		(struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
+	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+	if (!axi_ctrl->share_ctrl->vfebase) {
+		pr_err("%s: base address unmapped\n", __func__);
+		return;
+	}
+
+	CDBG("%s, free_irq\n", __func__);
+	disable_irq(axi_ctrl->vfeirq->start);
+	tasklet_kill(&axi_ctrl->vfe40_tasklet);
+	msm_cam_clk_enable(&axi_ctrl->pdev->dev, vfe40_clk_info,
+		axi_ctrl->vfe_clk, ARRAY_SIZE(vfe40_clk_info), 0);
+
+	if (axi_ctrl->fs_vfe) {
+		regulator_disable(axi_ctrl->fs_vfe);
+		regulator_put(axi_ctrl->fs_vfe);
+		axi_ctrl->fs_vfe = NULL;
+	}
+	iounmap(axi_ctrl->share_ctrl->vfebase);
+	axi_ctrl->share_ctrl->vfebase = NULL;
+
+	if (atomic_read(&axi_ctrl->share_ctrl->irq_cnt))
+		pr_warning("%s, Warning IRQ Count not ZERO\n", __func__);
+
+	msm_camio_bus_scale_cfg(
+		pmctl->sdata->pdata->cam_bus_scale_table, S_EXIT);
+}
+
+static long msm_axi_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int cmd, void *arg)
+{
+	int rc = -ENOIOCTLCMD;
+	switch (cmd) {
+	case VIDIOC_MSM_AXI_INIT:
+		rc = msm_axi_subdev_init(sd,
+			(struct msm_cam_media_controller *)arg);
+		break;
+	case VIDIOC_MSM_AXI_CFG:
+		rc = msm_axi_config(sd, arg);
+		break;
+	case VIDIOC_MSM_AXI_IRQ:
+		msm_axi_process_irq(sd, arg);
+		rc = 0;
+		break;
+	case VIDIOC_MSM_AXI_BUF_CFG:
+		msm_axi_buf_cfg(sd, arg);
+		rc = 0;
+		break;
+	case VIDIOC_MSM_AXI_RELEASE:
+		msm_axi_subdev_release(sd);
+		rc = 0;
+		break;
+	default:
+		pr_err("%s: command not found\n", __func__);
+	}
+	return rc;
+}
+
+static const struct v4l2_subdev_core_ops msm_axi_subdev_core_ops = {
+	.ioctl = msm_axi_subdev_ioctl,
+};
+
+static const struct v4l2_subdev_video_ops msm_axi_subdev_video_ops = {
+	.s_crystal_freq = msm_axi_subdev_s_crystal_freq,
+};
+
+static const struct v4l2_subdev_ops msm_axi_subdev_ops = {
+	.core = &msm_axi_subdev_core_ops,
+	.video = &msm_axi_subdev_video_ops,
+};
+
+static const struct v4l2_subdev_internal_ops msm_axi_internal_ops;
+
+void vfe40_axi_probe(struct axi_ctrl_t *axi_ctrl)
+{
+	struct msm_cam_subdev_info sd_info;
+	v4l2_subdev_init(&axi_ctrl->subdev, &msm_axi_subdev_ops);
+	axi_ctrl->subdev.internal_ops = &msm_axi_internal_ops;
+	axi_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	snprintf(axi_ctrl->subdev.name,
+			 sizeof(axi_ctrl->subdev.name), "axi");
+	v4l2_set_subdevdata(&axi_ctrl->subdev, axi_ctrl);
+
+	sd_info.sdev_type = AXI_DEV;
+	sd_info.sd_index = axi_ctrl->pdev->id;
+	sd_info.irq_num = 0;
+	msm_cam_register_subdev_node(&axi_ctrl->subdev, &sd_info);
+}
diff --git a/drivers/media/platform/msm/camera_v1/vfe/msm_vfe7x.c b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe7x.c
new file mode 100644
index 0000000..bbf9d1b
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe7x.c
@@ -0,0 +1,786 @@
+/* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/msm_adsp.h>
+#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/android_pmem.h>
+#include <linux/slab.h>
+#include <mach/msm_adsp.h>
+#include <mach/clk.h>
+#include <linux/delay.h>
+#include <linux/wait.h>
+#include "msm_vfe7x.h"
+#include <linux/pm_qos.h>
+
+#define QDSP_CMDQUEUE 25
+
+#define VFE_RESET_CMD 0
+#define VFE_START_CMD 1
+#define VFE_STOP_CMD  2
+#define VFE_FRAME_ACK 20
+#define STATS_AF_ACK  21
+#define STATS_WE_ACK  22
+
+#define MSG_STOP_ACK  1
+#define MSG_SNAPSHOT  2
+#define MSG_OUTPUT1   6
+#define MSG_OUTPUT2   7
+#define MSG_STATS_AF  8
+#define MSG_STATS_WE  9
+#define MSG_OUTPUT_S  10
+#define MSG_OUTPUT_T  11
+
+#define VFE_ADSP_EVENT 0xFFFF
+#define SNAPSHOT_MASK_MODE 0x00000002
+#define MSM_AXI_QOS_PREVIEW	192000
+#define MSM_AXI_QOS_SNAPSHOT	192000
+
+
+static struct msm_adsp_module *qcam_mod;
+static struct msm_adsp_module *vfe_mod;
+static struct msm_vfe_callback *resp;
+static void *extdata;
+static uint32_t extlen;
+
+struct mutex vfe_lock;
+static void     *vfe_syncdata;
+static uint8_t vfestopped;
+static uint32_t vfetask_state;
+static int cnt;
+
+static struct stop_event stopevent;
+
+unsigned long paddr_s_y;
+unsigned long paddr_s_cbcr;
+unsigned long paddr_t_y;
+unsigned long paddr_t_cbcr;
+
+static void vfe_7x_convert(struct msm_vfe_phy_info *pinfo,
+		enum vfe_resp_msg type,
+		void *data, void **ext, int32_t *elen)
+{
+	switch (type) {
+	case VFE_MSG_OUTPUT_P: {
+		pinfo->p0_phy = ((struct vfe_endframe *)data)->y_address;
+		pinfo->p1_phy =
+			((struct vfe_endframe *)data)->cbcr_address;
+		pinfo->p2_phy = pinfo->p0_phy;
+		pinfo->output_id = OUTPUT_TYPE_P;
+
+		CDBG("vfe_7x_convert, y_phy = 0x%x, cbcr_phy = 0x%x\n",
+				 pinfo->p0_phy, pinfo->p1_phy);
+
+		((struct vfe_frame_extra *)extdata)->bl_evencol =
+		((struct vfe_endframe *)data)->blacklevelevencolumn;
+
+		((struct vfe_frame_extra *)extdata)->bl_oddcol =
+		((struct vfe_endframe *)data)->blackleveloddcolumn;
+
+		((struct vfe_frame_extra *)extdata)->g_def_p_cnt =
+		((struct vfe_endframe *)data)->greendefectpixelcount;
+
+		((struct vfe_frame_extra *)extdata)->r_b_def_p_cnt =
+		((struct vfe_endframe *)data)->redbluedefectpixelcount;
+
+		*ext  = extdata;
+		*elen = extlen;
+	}
+		break;
+
+	case VFE_MSG_OUTPUT_S: {
+		pinfo->p0_phy = paddr_s_y;
+		pinfo->p1_phy = paddr_s_cbcr;
+		pinfo->p2_phy = pinfo->p0_phy;
+		pinfo->output_id = OUTPUT_TYPE_S;
+		CDBG("vfe_7x_convert: y_phy = 0x%x cbcr_phy = 0x%x\n",
+					pinfo->p0_phy, pinfo->p1_phy);
+	}
+		break;
+
+	case VFE_MSG_OUTPUT_T: {
+		pinfo->p0_phy = paddr_t_y;
+		pinfo->p1_phy = paddr_t_cbcr;
+		pinfo->p2_phy = pinfo->p0_phy;
+		pinfo->output_id = OUTPUT_TYPE_T;
+		CDBG("vfe_7x_convert: y_phy = 0x%x cbcr_phy = 0x%x\n",
+					pinfo->p0_phy, pinfo->p1_phy);
+	}
+		break;
+
+	case VFE_MSG_STATS_AF:
+	case VFE_MSG_STATS_WE:
+		pinfo->sbuf_phy = *(uint32_t *)data;
+		break;
+
+	default:
+		break;
+	} /* switch */
+}
+
+static void vfe_7x_ops(void *driver_data, unsigned id, size_t len,
+		void (*getevent)(void *ptr, size_t len))
+{
+	uint32_t evt_buf[3];
+	struct msm_vfe_resp *rp;
+	void *data;
+	CDBG("%s:id=%d\n", __func__, id);
+
+	len = (id == VFE_ADSP_EVENT) ? 0 : len;
+	data = resp->vfe_alloc(sizeof(struct msm_vfe_resp) + len,
+		vfe_syncdata,  GFP_ATOMIC);
+
+	if (!data) {
+		pr_err("%s: rp: cannot allocate buffer\n", __func__);
+		return;
+	}
+	rp = (struct msm_vfe_resp *)data;
+	rp->evt_msg.len = len;
+
+	if (id == VFE_ADSP_EVENT) {
+		/* event */
+		rp->type           = VFE_EVENT;
+		rp->evt_msg.type   = MSM_CAMERA_EVT;
+		getevent(evt_buf, sizeof(evt_buf));
+		rp->evt_msg.msg_id = evt_buf[0];
+	CDBG("%s:event:msg_id=%d\n", __func__, rp->evt_msg.msg_id);
+		resp->vfe_resp(rp, MSM_CAM_Q_VFE_EVT, vfe_syncdata,
+		GFP_ATOMIC);
+	} else {
+		/* messages */
+		rp->evt_msg.type   = MSM_CAMERA_MSG;
+		rp->evt_msg.msg_id = id;
+		rp->evt_msg.data = rp + 1;
+		getevent(rp->evt_msg.data, len);
+	CDBG("%s:messages:msg_id=%d\n", __func__, rp->evt_msg.msg_id);
+
+		switch (rp->evt_msg.msg_id) {
+		case MSG_SNAPSHOT:
+			update_axi_qos(MSM_AXI_QOS_PREVIEW);
+			vfe_7x_ops(driver_data, MSG_OUTPUT_S, len, getevent);
+			vfe_7x_ops(driver_data, MSG_OUTPUT_T, len, getevent);
+			rp->type = VFE_MSG_SNAPSHOT;
+			break;
+
+		case MSG_OUTPUT_S:
+			rp->type = VFE_MSG_OUTPUT_S;
+			vfe_7x_convert(&(rp->phy), VFE_MSG_OUTPUT_S,
+				rp->evt_msg.data, &(rp->extdata),
+				&(rp->extlen));
+			break;
+
+		case MSG_OUTPUT_T:
+			rp->type = VFE_MSG_OUTPUT_T;
+			vfe_7x_convert(&(rp->phy), VFE_MSG_OUTPUT_T,
+				rp->evt_msg.data, &(rp->extdata),
+				&(rp->extlen));
+			break;
+
+		case MSG_OUTPUT1:
+		case MSG_OUTPUT2:
+			rp->type = VFE_MSG_OUTPUT_P;
+			vfe_7x_convert(&(rp->phy), VFE_MSG_OUTPUT_P,
+				rp->evt_msg.data, &(rp->extdata),
+				&(rp->extlen));
+			break;
+
+		case MSG_STATS_AF:
+			rp->type = VFE_MSG_STATS_AF;
+			vfe_7x_convert(&(rp->phy), VFE_MSG_STATS_AF,
+					rp->evt_msg.data, NULL, NULL);
+			break;
+
+		case MSG_STATS_WE:
+			rp->type = VFE_MSG_STATS_WE;
+			vfe_7x_convert(&(rp->phy), VFE_MSG_STATS_WE,
+					rp->evt_msg.data, NULL, NULL);
+
+			CDBG("MSG_STATS_WE: phy = 0x%x\n", rp->phy.sbuf_phy);
+			break;
+
+		case MSG_STOP_ACK:
+			rp->type = VFE_MSG_GENERAL;
+			stopevent.state = 1;
+			wake_up(&stopevent.wait);
+			break;
+
+
+		default:
+			rp->type = VFE_MSG_GENERAL;
+			break;
+		}
+		resp->vfe_resp(rp, MSM_CAM_Q_VFE_MSG, vfe_syncdata, GFP_ATOMIC);
+	}
+}
+
+static struct msm_adsp_ops vfe_7x_sync = {
+	.event = vfe_7x_ops,
+};
+
+static int vfe_7x_enable(struct camera_enable_cmd *enable)
+{
+	int rc = -EFAULT;
+
+	if (!strcmp(enable->name, "QCAMTASK"))
+		rc = msm_adsp_enable(qcam_mod);
+	else if (!strcmp(enable->name, "VFETASK")) {
+		rc = msm_adsp_enable(vfe_mod);
+		vfetask_state = 1;
+	}
+
+	if (!cnt) {
+		add_axi_qos();
+		cnt++;
+	}
+	return rc;
+}
+
+static int vfe_7x_disable(struct camera_enable_cmd *enable,
+		struct platform_device *dev __attribute__((unused)))
+{
+	int rc = -EFAULT;
+
+	if (!strcmp(enable->name, "QCAMTASK"))
+		rc = msm_adsp_disable(qcam_mod);
+	else if (!strcmp(enable->name, "VFETASK")) {
+		rc = msm_adsp_disable(vfe_mod);
+		vfetask_state = 0;
+	}
+
+	return rc;
+}
+
+static int vfe_7x_stop(void)
+{
+	int rc = 0;
+	uint32_t stopcmd = VFE_STOP_CMD;
+	rc = msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
+				&stopcmd, sizeof(uint32_t));
+	if (rc < 0) {
+		CDBG("%s:%d: failed rc = %d \n", __func__, __LINE__, rc);
+		return rc;
+	}
+
+	stopevent.state = 0;
+	rc = wait_event_timeout(stopevent.wait,
+		stopevent.state != 0,
+		msecs_to_jiffies(stopevent.timeout));
+
+	return rc;
+}
+
+static void vfe_7x_release(struct platform_device *pdev)
+{
+	mutex_lock(&vfe_lock);
+	vfe_syncdata = NULL;
+	mutex_unlock(&vfe_lock);
+
+	if (!vfestopped) {
+		CDBG("%s:%d:Calling vfe_7x_stop()\n", __func__, __LINE__);
+		vfe_7x_stop();
+	} else
+		vfestopped = 0;
+
+	msm_adsp_disable(qcam_mod);
+	msm_adsp_disable(vfe_mod);
+	vfetask_state = 0;
+
+	msm_adsp_put(qcam_mod);
+	msm_adsp_put(vfe_mod);
+
+	msm_camio_disable(pdev);
+
+	kfree(extdata);
+	extlen = 0;
+
+	/* Release AXI */
+	release_axi_qos();
+	cnt = 0;
+}
+
+static int vfe_7x_init(struct msm_vfe_callback *presp,
+	struct platform_device *dev)
+{
+	int rc = 0;
+
+	init_waitqueue_head(&stopevent.wait);
+	stopevent.timeout = 200;
+	stopevent.state = 0;
+
+	if (presp && presp->vfe_resp)
+		resp = presp;
+	else
+		return -EFAULT;
+
+	/* Bring up all the required GPIOs and Clocks */
+	rc = msm_camio_enable(dev);
+	if (rc < 0)
+		return rc;
+	msm_camio_camif_pad_reg_reset();
+
+	extlen = sizeof(struct vfe_frame_extra);
+
+	extdata =
+		kmalloc(extlen, GFP_ATOMIC);
+	if (!extdata) {
+		rc = -ENOMEM;
+		goto init_fail;
+	}
+
+	rc = msm_adsp_get("QCAMTASK", &qcam_mod, &vfe_7x_sync, NULL);
+	if (rc) {
+		rc = -EBUSY;
+		goto get_qcam_fail;
+	}
+
+	rc = msm_adsp_get("VFETASK", &vfe_mod, &vfe_7x_sync, NULL);
+	if (rc) {
+		rc = -EBUSY;
+		goto get_vfe_fail;
+	}
+
+	return 0;
+
+get_vfe_fail:
+	msm_adsp_put(qcam_mod);
+get_qcam_fail:
+	kfree(extdata);
+init_fail:
+	extlen = 0;
+	return rc;
+}
+
+static int vfe_7x_config_axi(int mode,
+	struct axidata *ad, struct axiout *ao)
+{
+	struct msm_pmem_region *regptr;
+	unsigned long *bptr;
+	int    cnt;
+
+	int rc = 0;
+
+	if (mode == OUTPUT_1 || mode == OUTPUT_1_AND_2) {
+		regptr = ad->region;
+
+		CDBG("bufnum1 = %d\n", ad->bufnum1);
+		if (mode == OUTPUT_1_AND_2) {
+			paddr_t_y = regptr->paddr + regptr->info.planar0_off;
+			paddr_t_cbcr = regptr->paddr + regptr->info.planar1_off;
+		}
+
+		CDBG("config_axi1: O1, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
+			regptr->paddr, regptr->info.planar0_off,
+			regptr->info.planar1_off);
+
+		bptr = &ao->output1buffer1_y_phy;
+		for (cnt = 0; cnt < ad->bufnum1; cnt++) {
+			*bptr = regptr->paddr + regptr->info.planar0_off;
+			bptr++;
+			*bptr = regptr->paddr + regptr->info.planar1_off;
+
+			bptr++;
+			regptr++;
+		}
+
+		regptr--;
+		for (cnt = 0; cnt < (8 - ad->bufnum1); cnt++) {
+			*bptr = regptr->paddr + regptr->info.planar0_off;
+			bptr++;
+			*bptr = regptr->paddr + regptr->info.planar1_off;
+			bptr++;
+		}
+	} /* if OUTPUT1 or Both */
+
+	if (mode == OUTPUT_2 || mode == OUTPUT_1_AND_2) {
+		regptr = &(ad->region[ad->bufnum1]);
+
+		CDBG("bufnum2 = %d\n", ad->bufnum2);
+		paddr_s_y = regptr->paddr +  regptr->info.planar0_off;
+		paddr_s_cbcr = regptr->paddr +  regptr->info.planar1_off;
+		CDBG("config_axi2: O2, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
+			regptr->paddr, regptr->info.planar0_off,
+			regptr->info.planar1_off);
+
+		bptr = &ao->output2buffer1_y_phy;
+		for (cnt = 0; cnt < ad->bufnum2; cnt++) {
+			*bptr = regptr->paddr + regptr->info.planar0_off;
+			bptr++;
+			*bptr = regptr->paddr + regptr->info.planar1_off;
+
+			bptr++;
+			regptr++;
+		}
+
+		regptr--;
+		for (cnt = 0; cnt < (8 - ad->bufnum2); cnt++) {
+			*bptr = regptr->paddr + regptr->info.planar0_off;
+			bptr++;
+			*bptr = regptr->paddr + regptr->info.planar1_off;
+			bptr++;
+		}
+	}
+
+	return rc;
+}
+
+static int vfe_7x_config(struct msm_vfe_cfg_cmd *cmd, void *data)
+{
+	struct msm_pmem_region *regptr;
+	unsigned char buf[256];
+
+	struct vfe_stats_ack sack;
+	struct axidata *axid;
+	uint32_t i, op_mode;
+	uint32_t *_mode;
+
+	struct vfe_stats_we_cfg *scfg = NULL;
+	struct vfe_stats_af_cfg *sfcfg = NULL;
+
+	struct axiout *axio = NULL;
+	void   *cmd_data = NULL;
+	void   *cmd_data_alloc = NULL;
+	long rc = 0;
+	struct msm_vfe_command_7k *vfecmd;
+
+	vfecmd =
+			kmalloc(sizeof(struct msm_vfe_command_7k),
+				GFP_ATOMIC);
+	if (!vfecmd) {
+		pr_err("vfecmd alloc failed!\n");
+		return -ENOMEM;
+	}
+
+	if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
+	    cmd->cmd_type != CMD_STATS_BUF_RELEASE &&
+	    cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE) {
+		if (copy_from_user(vfecmd,
+				(void __user *)(cmd->value),
+				sizeof(struct msm_vfe_command_7k))) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+	}
+
+	switch (cmd->cmd_type) {
+	case CMD_STATS_AEC_AWB_ENABLE:
+	case CMD_STATS_AXI_CFG: {
+		axid = data;
+		if (!axid) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+
+		scfg =
+			kmalloc(sizeof(struct vfe_stats_we_cfg),
+				GFP_ATOMIC);
+		if (!scfg) {
+			rc = -ENOMEM;
+			goto config_failure;
+		}
+
+		if (copy_from_user(scfg,
+					(void __user *)(vfecmd->value),
+					vfecmd->length)) {
+
+			rc = -EFAULT;
+			goto config_done;
+		}
+
+		CDBG("STATS_ENABLE: bufnum = %d, enabling = %d\n",
+			axid->bufnum1, scfg->wb_expstatsenable);
+
+		if (axid->bufnum1 > 0) {
+			regptr = axid->region;
+
+			for (i = 0; i < axid->bufnum1; i++) {
+
+				CDBG("STATS_ENABLE, phy = 0x%lx\n",
+					regptr->paddr);
+
+				scfg->wb_expstatoutputbuffer[i] =
+					(void *)regptr->paddr;
+				regptr++;
+			}
+
+			cmd_data = scfg;
+
+		} else {
+			rc = -EINVAL;
+			goto config_done;
+		}
+	}
+		break;
+
+	case CMD_STATS_AF_ENABLE:
+	case CMD_STATS_AF_AXI_CFG: {
+		axid = data;
+		if (!axid) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+
+		sfcfg =
+			kmalloc(sizeof(struct vfe_stats_af_cfg),
+				GFP_ATOMIC);
+
+		if (!sfcfg) {
+			rc = -ENOMEM;
+			goto config_failure;
+		}
+
+		if (copy_from_user(sfcfg,
+					(void __user *)(vfecmd->value),
+					vfecmd->length)) {
+
+			rc = -EFAULT;
+			goto config_done;
+		}
+
+		CDBG("AF_ENABLE: bufnum = %d, enabling = %d\n",
+			axid->bufnum1, sfcfg->af_enable);
+
+		if (axid->bufnum1 > 0) {
+			regptr = &axid->region[0];
+
+			for (i = 0; i < axid->bufnum1; i++) {
+
+				CDBG("STATS_ENABLE, phy = 0x%lx\n",
+					regptr->paddr);
+
+				sfcfg->af_outbuf[i] =
+					(void *)regptr->paddr;
+
+				regptr++;
+			}
+
+			cmd_data = sfcfg;
+
+		} else {
+			rc = -EINVAL;
+			goto config_done;
+		}
+	}
+		break;
+
+	case CMD_FRAME_BUF_RELEASE: {
+		struct msm_frame *b;
+		unsigned long p;
+		struct vfe_outputack fack;
+		if (!data)  {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+
+		b = (struct msm_frame *)(cmd->value);
+		p = *(unsigned long *)data;
+
+		fack.header = VFE_FRAME_ACK;
+
+		fack.output2newybufferaddress =
+			(void *)(p + b->planar0_off);
+
+		fack.output2newcbcrbufferaddress =
+			(void *)(p + b->planar1_off);
+
+		vfecmd->queue = QDSP_CMDQUEUE;
+		vfecmd->length = sizeof(struct vfe_outputack);
+		cmd_data = &fack;
+	}
+		break;
+
+	case CMD_SNAP_BUF_RELEASE:
+		break;
+
+	case CMD_STATS_BUF_RELEASE: {
+		CDBG("vfe_7x_config: CMD_STATS_BUF_RELEASE\n");
+		if (!data) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+
+		sack.header = STATS_WE_ACK;
+		sack.bufaddr = (void *)*(uint32_t *)data;
+
+		vfecmd->queue  = QDSP_CMDQUEUE;
+		vfecmd->length = sizeof(struct vfe_stats_ack);
+		cmd_data = &sack;
+	}
+		break;
+
+	case CMD_STATS_AF_BUF_RELEASE: {
+		CDBG("vfe_7x_config: CMD_STATS_AF_BUF_RELEASE\n");
+		if (!data) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+
+		sack.header = STATS_AF_ACK;
+		sack.bufaddr = (void *)*(uint32_t *)data;
+
+		vfecmd->queue  = QDSP_CMDQUEUE;
+		vfecmd->length = sizeof(struct vfe_stats_ack);
+		cmd_data = &sack;
+	}
+		break;
+
+	case CMD_GENERAL:
+	case CMD_STATS_DISABLE: {
+		if (vfecmd->length > 256) {
+			cmd_data_alloc =
+			cmd_data = kmalloc(vfecmd->length, GFP_ATOMIC);
+			if (!cmd_data) {
+				rc = -ENOMEM;
+				goto config_failure;
+			}
+		} else
+			cmd_data = buf;
+
+		if (copy_from_user(cmd_data,
+					(void __user *)(vfecmd->value),
+					vfecmd->length)) {
+
+			rc = -EFAULT;
+			goto config_done;
+		}
+
+		if (vfecmd->queue == QDSP_CMDQUEUE) {
+			switch (*(uint32_t *)cmd_data) {
+			case VFE_RESET_CMD:
+				msm_camio_vfe_blk_reset();
+				vfestopped = 0;
+				break;
+
+			case VFE_START_CMD:
+				_mode = (uint32_t *)cmd_data;
+				op_mode = *(++_mode);
+				if (op_mode & SNAPSHOT_MASK_MODE) {
+					/* request AXI bus for snapshot */
+					if (update_axi_qos(MSM_AXI_QOS_SNAPSHOT)
+						< 0) {
+						rc = -EFAULT;
+						goto config_failure;
+					}
+				} else {
+					/* request AXI bus for snapshot */
+					if (update_axi_qos(MSM_AXI_QOS_PREVIEW)
+						< 0) {
+						rc = -EFAULT;
+						goto config_failure;
+					}
+				}
+				msm_camio_camif_pad_reg_reset_2();
+				vfestopped = 0;
+				break;
+
+			case VFE_STOP_CMD:
+				vfestopped = 1;
+				goto config_send;
+
+			default:
+				break;
+			}
+		} /* QDSP_CMDQUEUE */
+	}
+		break;
+	case CMD_AXI_CFG_PREVIEW:
+	case CMD_RAW_PICT_AXI_CFG: {
+		axid = data;
+		if (!axid) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+
+		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			goto config_failure;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd->value),
+					sizeof(struct axiout))) {
+			rc = -EFAULT;
+			goto config_done;
+		}
+
+		vfe_7x_config_axi(OUTPUT_2, axid, axio);
+		cmd_data = axio;
+	}
+		break;
+
+	case CMD_AXI_CFG_SNAP: {
+		axid = data;
+		if (!axid) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+
+		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			goto config_failure;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd->value),
+					sizeof(struct axiout))) {
+			rc = -EFAULT;
+			goto config_done;
+		}
+
+		vfe_7x_config_axi(OUTPUT_1_AND_2, axid, axio);
+
+		cmd_data = axio;
+	}
+		break;
+
+	default:
+		break;
+	} /* switch */
+
+	if (vfestopped)
+		goto config_done;
+
+config_send:
+	CDBG("send adsp command = %d\n", *(uint32_t *)cmd_data);
+	if (vfetask_state)
+		rc = msm_adsp_write(vfe_mod, vfecmd->queue,
+					cmd_data, vfecmd->length);
+config_done:
+	if (cmd_data_alloc != NULL)
+		kfree(cmd_data_alloc);
+
+config_failure:
+	kfree(scfg);
+	kfree(axio);
+	kfree(vfecmd);
+	return rc;
+}
+
+void msm_camvfe_fn_init(struct msm_camvfe_fn *fptr, void *data)
+{
+	mutex_init(&vfe_lock);
+	fptr->vfe_init    = vfe_7x_init;
+	fptr->vfe_enable  = vfe_7x_enable;
+	fptr->vfe_config  = vfe_7x_config;
+	fptr->vfe_disable = vfe_7x_disable;
+	fptr->vfe_release = vfe_7x_release;
+	vfe_syncdata = data;
+}
+
+void msm_camvpe_fn_init(struct msm_camvpe_fn *fptr, void *data)
+{
+	fptr->vpe_reg		= NULL;
+	fptr->send_frame_to_vpe	= NULL;
+	fptr->vpe_config	= NULL;
+	fptr->vpe_cfg_update	= NULL;
+	fptr->dis		= NULL;
+}
diff --git a/drivers/media/platform/msm/camera_v1/vfe/msm_vfe7x.h b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe7x.h
new file mode 100644
index 0000000..944bfea
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe7x.h
@@ -0,0 +1,265 @@
+/* Copyright (c) 2009, 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 __MSM_VFE7X_H__
+#define __MSM_VFE7X_H__
+#include <media/msm_camera.h>
+#include <mach/camera.h>
+
+struct vfe_frame_extra {
+	uint32_t  bl_evencol;
+	uint32_t  bl_oddcol;
+	uint16_t  g_def_p_cnt;
+	uint16_t  r_b_def_p_cnt;
+};
+
+struct vfe_endframe {
+	uint32_t      y_address;
+	uint32_t      cbcr_address;
+
+	unsigned int  blacklevelevencolumn:23;
+	uint16_t      reserved1:9;
+	unsigned int  blackleveloddcolumn:23;
+	uint16_t      reserved2:9;
+
+	uint16_t      greendefectpixelcount:8;
+	uint16_t      reserved3:8;
+	uint16_t      redbluedefectpixelcount:8;
+	uint16_t      reserved4:8;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_outputack {
+	uint32_t  header;
+	void      *output2newybufferaddress;
+	void      *output2newcbcrbufferaddress;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_stats_ack {
+	uint32_t header;
+	/* MUST BE 64 bit ALIGNED */
+	void     *bufaddr;
+} __attribute__((packed, aligned(4)));
+
+/* AXI Output Config Command sent to DSP */
+struct axiout {
+	uint32_t            cmdheader:32;
+	int 		    outputmode:3;
+	uint8_t             format:2;
+	uint32_t            /* reserved */ : 27;
+
+	/* AXI Output 1 Y Configuration, Part 1 */
+	uint32_t            out1yimageheight:12;
+	uint32_t            /* reserved */ : 4;
+	uint32_t            out1yimagewidthin64bitwords:10;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 1 Y Configuration, Part 2 */
+	uint8_t             out1yburstlen:2;
+	uint32_t            out1ynumrows:12;
+	uint32_t            out1yrowincin64bitincs:12;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 1 CbCr Configuration, Part 1 */
+	uint32_t            out1cbcrimageheight:12;
+	uint32_t            /* reserved */ : 4;
+	uint32_t            out1cbcrimagewidthin64bitwords:10;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 1 CbCr Configuration, Part 2 */
+	uint8_t             out1cbcrburstlen:2;
+	uint32_t            out1cbcrnumrows:12;
+	uint32_t            out1cbcrrowincin64bitincs:12;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 2 Y Configuration, Part 1 */
+	uint32_t            out2yimageheight:12;
+	uint32_t            /* reserved */ : 4;
+	uint32_t            out2yimagewidthin64bitwords:10;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 2 Y Configuration, Part 2 */
+	uint8_t             out2yburstlen:2;
+	uint32_t            out2ynumrows:12;
+	uint32_t            out2yrowincin64bitincs:12;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 2 CbCr Configuration, Part 1 */
+	uint32_t            out2cbcrimageheight:12;
+	uint32_t            /* reserved */ : 4;
+	uint32_t            out2cbcrimagewidtein64bitwords:10;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 2 CbCr Configuration, Part 2 */
+	uint8_t             out2cbcrburstlen:2;
+	uint32_t            out2cbcrnumrows:12;
+	uint32_t            out2cbcrrowincin64bitincs:12;
+	uint32_t            /* reserved */ : 6;
+
+	/* Address configuration:
+	 * output1 phisycal address */
+	unsigned long   output1buffer1_y_phy;
+	unsigned long   output1buffer1_cbcr_phy;
+	unsigned long   output1buffer2_y_phy;
+	unsigned long   output1buffer2_cbcr_phy;
+	unsigned long   output1buffer3_y_phy;
+	unsigned long   output1buffer3_cbcr_phy;
+	unsigned long   output1buffer4_y_phy;
+	unsigned long   output1buffer4_cbcr_phy;
+	unsigned long   output1buffer5_y_phy;
+	unsigned long   output1buffer5_cbcr_phy;
+	unsigned long   output1buffer6_y_phy;
+	unsigned long   output1buffer6_cbcr_phy;
+	unsigned long   output1buffer7_y_phy;
+	unsigned long   output1buffer7_cbcr_phy;
+	unsigned long   output1buffer8_y_phy;
+	unsigned long   output1buffer8_cbcr_phy;
+
+	/* output2 phisycal address */
+	unsigned long   output2buffer1_y_phy;
+	unsigned long   output2buffer1_cbcr_phy;
+	unsigned long   output2buffer2_y_phy;
+	unsigned long   output2buffer2_cbcr_phy;
+	unsigned long   output2buffer3_y_phy;
+	unsigned long   output2buffer3_cbcr_phy;
+	unsigned long   output2buffer4_y_phy;
+	unsigned long   output2buffer4_cbcr_phy;
+	unsigned long   output2buffer5_y_phy;
+	unsigned long   output2buffer5_cbcr_phy;
+	unsigned long   output2buffer6_y_phy;
+	unsigned long   output2buffer6_cbcr_phy;
+	unsigned long   output2buffer7_y_phy;
+	unsigned long   output2buffer7_cbcr_phy;
+	unsigned long   output2buffer8_y_phy;
+	unsigned long   output2buffer8_cbcr_phy;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_stats_we_cfg {
+	uint32_t       header;
+
+	/* White Balance/Exposure Statistic Selection */
+	uint8_t        wb_expstatsenable:1;
+	uint8_t        wb_expstatbuspriorityselection:1;
+	unsigned int   wb_expstatbuspriorityvalue:4;
+	unsigned int   /* reserved */ : 26;
+
+	/* White Balance/Exposure Statistic Configuration, Part 1 */
+	uint8_t        exposurestatregions:1;
+	uint8_t        exposurestatsubregions:1;
+	unsigned int   /* reserved */ : 14;
+
+	unsigned int   whitebalanceminimumy:8;
+	unsigned int   whitebalancemaximumy:8;
+
+	/* White Balance/Exposure Statistic Configuration, Part 2 */
+	uint8_t wb_expstatslopeofneutralregionline[
+		NUM_WB_EXP_NEUTRAL_REGION_LINES];
+
+	/* White Balance/Exposure Statistic Configuration, Part 3 */
+	unsigned int   wb_expstatcrinterceptofneutralregionline2:12;
+	unsigned int   /* reserved */ : 4;
+	unsigned int   wb_expstatcbinterceptofneutralreginnline1:12;
+	unsigned int    /* reserved */ : 4;
+
+	/* White Balance/Exposure Statistic Configuration, Part 4 */
+	unsigned int   wb_expstatcrinterceptofneutralregionline4:12;
+	unsigned int   /* reserved */ : 4;
+	unsigned int   wb_expstatcbinterceptofneutralregionline3:12;
+	unsigned int   /* reserved */ : 4;
+
+	/* White Balance/Exposure Statistic Output Buffer Header */
+	unsigned int   wb_expmetricheaderpattern:8;
+	unsigned int   /* reserved */ : 24;
+
+	/* White Balance/Exposure Statistic Output Buffers-MUST
+	* BE 64 bit ALIGNED */
+	void  *wb_expstatoutputbuffer[NUM_WB_EXP_STAT_OUTPUT_BUFFERS];
+} __attribute__((packed, aligned(4)));
+
+struct vfe_stats_af_cfg {
+	uint32_t header;
+
+	/* Autofocus Statistic Selection */
+	uint8_t       af_enable:1;
+	uint8_t       af_busprioritysel:1;
+	unsigned int  af_buspriorityval:4;
+	unsigned int  /* reserved */ : 26;
+
+	/* Autofocus Statistic Configuration, Part 1 */
+	unsigned int  af_singlewinvoffset:12;
+	unsigned int  /* reserved */ : 4;
+	unsigned int  af_singlewinhoffset:12;
+	unsigned int  /* reserved */ : 3;
+	uint8_t       af_winmode:1;
+
+	/* Autofocus Statistic Configuration, Part 2 */
+	unsigned int  af_singglewinvh:11;
+	unsigned int  /* reserved */ : 5;
+	unsigned int  af_singlewinhw:11;
+	unsigned int  /* reserved */ : 5;
+
+	/* Autofocus Statistic Configuration, Parts 3-6 */
+	uint8_t       af_multiwingrid[NUM_AUTOFOCUS_MULTI_WINDOW_GRIDS];
+
+	/* Autofocus Statistic Configuration, Part 7 */
+	signed int    af_metrichpfcoefa00:5;
+	signed int    af_metrichpfcoefa04:5;
+	unsigned int  af_metricmaxval:11;
+	uint8_t       af_metricsel:1;
+	unsigned int  /* reserved */ : 10;
+
+	/* Autofocus Statistic Configuration, Part 8 */
+	signed int    af_metrichpfcoefa20:5;
+	signed int    af_metrichpfcoefa21:5;
+	signed int    af_metrichpfcoefa22:5;
+	signed int    af_metrichpfcoefa23:5;
+	signed int    af_metrichpfcoefa24:5;
+	unsigned int  /* reserved */ : 7;
+
+	/* Autofocus Statistic Output Buffer Header */
+	unsigned int  af_metrichp:8;
+	unsigned int  /* reserved */ : 24;
+
+	/* Autofocus Statistic Output Buffers - MUST BE 64 bit ALIGNED!!! */
+	void *af_outbuf[NUM_AF_STAT_OUTPUT_BUFFERS];
+} __attribute__((packed, aligned(4))); /* VFE_StatsAutofocusConfigCmdType */
+
+struct msm_camera_frame_msg {
+	unsigned long   output_y_address;
+	unsigned long   output_cbcr_address;
+
+	unsigned int    blacklevelevenColumn:23;
+	uint16_t        reserved1:9;
+	unsigned int    blackleveloddColumn:23;
+	uint16_t        reserved2:9;
+
+	uint16_t        greendefectpixelcount:8;
+	uint16_t        reserved3:8;
+	uint16_t        redbluedefectpixelcount:8;
+	uint16_t        reserved4:8;
+} __attribute__((packed, aligned(4)));
+
+/* New one for 7k */
+struct msm_vfe_command_7k {
+	uint16_t queue;
+	uint16_t length;
+	void     *value;
+};
+
+struct stop_event {
+  wait_queue_head_t wait;
+	int state;
+  int timeout;
+};
+
+
+#endif /* __MSM_VFE7X_H__ */
diff --git a/drivers/media/platform/msm/camera_v1/vfe/msm_vfe7x27a.c b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe7x27a.c
new file mode 100644
index 0000000..0279c78
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe7x27a.c
@@ -0,0 +1,745 @@
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/msm_adsp.h>
+#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/android_pmem.h>
+#include <linux/slab.h>
+#include <linux/pm_qos.h>
+#include <linux/delay.h>
+#include <linux/wait.h>
+#include <mach/msm_adsp.h>
+#include <mach/clk.h>
+#include <mach/camera.h>
+#include "msm_vfe7x27a.h"
+
+#define QDSP_CMDQUEUE 25
+
+#define VFE_RESET_CMD 0
+#define VFE_START_CMD 1
+#define VFE_STOP_CMD  2
+#define VFE_FRAME_ACK 20
+#define STATS_AF_ACK  21
+#define STATS_WE_ACK  22
+
+#define MSG_STOP_ACK  1
+#define MSG_SNAPSHOT  2
+#define MSG_OUTPUT1   6
+#define MSG_OUTPUT2   7
+#define MSG_STATS_AF  8
+#define MSG_STATS_WE  9
+#define MSG_OUTPUT_S  23
+#define MSG_OUTPUT_T  22
+#define MSG_SOF       15
+
+#define VFE_ADSP_EVENT 0xFFFF
+#define SNAPSHOT_MASK_MODE 0x00000002
+#define MSM_AXI_QOS_PREVIEW	122000
+#define MSM_AXI_QOS_SNAPSHOT	192000
+
+
+static struct msm_adsp_module *qcam_mod;
+static struct msm_adsp_module *vfe_mod;
+static struct msm_vfe_callback *resp;
+static void *extdata;
+static uint32_t extlen;
+
+struct mutex vfe_lock;
+static void     *vfe_syncdata;
+static uint8_t vfestopped;
+
+static struct stop_event stopevent;
+
+unsigned long paddr_s_y;
+unsigned long paddr_s_cbcr;
+unsigned long paddr_t_y;
+unsigned long paddr_t_cbcr;
+static uint32_t op_mode;
+
+static void vfe_7x_convert(struct msm_vfe_phy_info *pinfo,
+		enum vfe_resp_msg type,
+		void *data, void **ext, int32_t *elen)
+{
+	switch (type) {
+	case VFE_MSG_OUTPUT_P: {
+		pinfo->p0_phy = ((struct vfe_endframe *)data)->y_address;
+		pinfo->p1_phy =
+			((struct vfe_endframe *)data)->cbcr_address;
+		pinfo->p2_phy = pinfo->p0_phy;
+		pinfo->output_id = OUTPUT_TYPE_P;
+
+		CDBG("vfe_7x_convert, y_phy = 0x%x, cbcr_phy = 0x%x\n",
+				 pinfo->p0_phy, pinfo->p1_phy);
+
+		memcpy(((struct vfe_frame_extra *)extdata),
+			&((struct vfe_endframe *)data)->extra,
+			sizeof(struct vfe_frame_extra));
+
+		*ext  = extdata;
+		*elen = extlen;
+		pinfo->frame_id =
+				((struct vfe_frame_extra *)extdata)->frame_id;
+	}
+		break;
+	case VFE_MSG_OUTPUT_S: {
+		pinfo->p0_phy = paddr_s_y;
+		pinfo->p1_phy = paddr_s_cbcr;
+		pinfo->p2_phy = pinfo->p0_phy;
+		pinfo->output_id = OUTPUT_TYPE_S;
+		CDBG("vfe_7x_convert: y_phy = 0x%x cbcr_phy = 0x%x\n",
+					pinfo->p0_phy, pinfo->p1_phy);
+	}
+		break;
+	case VFE_MSG_OUTPUT_T: {
+		pinfo->p0_phy = paddr_t_y;
+		pinfo->p1_phy = paddr_t_cbcr;
+		pinfo->p2_phy = pinfo->p0_phy;
+		pinfo->output_id = OUTPUT_TYPE_T;
+		CDBG("vfe_7x_convert: y_phy = 0x%x cbcr_phy = 0x%x\n",
+					pinfo->p0_phy, pinfo->p1_phy);
+	}
+		break;
+	case VFE_MSG_STATS_AF:
+	case VFE_MSG_STATS_WE:
+		pinfo->sbuf_phy = *(uint32_t *)data;
+		pinfo->frame_id = *(((uint32_t *)data) + 1);
+		CDBG("frame id = %d\n", pinfo->frame_id);
+		break;
+	default:
+		break;
+	}
+}
+
+static void vfe_7x_ops(void *driver_data, unsigned id, size_t len,
+		void (*getevent)(void *ptr, size_t len))
+{
+	uint32_t evt_buf[3];
+	struct msm_vfe_resp *rp;
+	void *data;
+	CDBG("%s:id=%d\n", __func__, id);
+
+	len = (id == VFE_ADSP_EVENT) ? 0 : len;
+	data = resp->vfe_alloc(sizeof(struct msm_vfe_resp) + len,
+		vfe_syncdata,  GFP_ATOMIC);
+
+	if (!data) {
+		pr_err("%s: rp: cannot allocate buffer\n", __func__);
+		return;
+	}
+	rp = data;
+	rp->evt_msg.len = len;
+
+	if (id == VFE_ADSP_EVENT) {
+		/* event */
+		rp->type           = VFE_EVENT;
+		rp->evt_msg.type   = MSM_CAMERA_EVT;
+		getevent(evt_buf, sizeof(evt_buf));
+		rp->evt_msg.msg_id = evt_buf[0];
+		CDBG("%s:event:msg_id=%d\n", __func__, rp->evt_msg.msg_id);
+		resp->vfe_resp(rp, MSM_CAM_Q_VFE_EVT, vfe_syncdata,
+		GFP_ATOMIC);
+	} else {
+		/* messages */
+		rp->evt_msg.type   = MSM_CAMERA_MSG;
+		rp->evt_msg.msg_id = id;
+		rp->evt_msg.data = rp + 1;
+		getevent(rp->evt_msg.data, len);
+		CDBG("%s:messages:msg_id=%d\n", __func__, rp->evt_msg.msg_id);
+
+		switch (rp->evt_msg.msg_id) {
+		case MSG_SNAPSHOT:
+			msm_camio_set_perf_lvl(S_PREVIEW);
+			vfe_7x_ops(driver_data, MSG_OUTPUT_S, len, getevent);
+			vfe_7x_ops(driver_data, MSG_OUTPUT_T, len, getevent);
+			rp->type = VFE_MSG_SNAPSHOT;
+			break;
+		case MSG_OUTPUT_S:
+			rp->type = VFE_MSG_OUTPUT_S;
+			vfe_7x_convert(&(rp->phy), VFE_MSG_OUTPUT_S,
+					rp->evt_msg.data, &(rp->extdata),
+					&(rp->extlen));
+			break;
+		case MSG_OUTPUT_T:
+			rp->type = VFE_MSG_OUTPUT_T;
+			vfe_7x_convert(&(rp->phy), VFE_MSG_OUTPUT_T,
+					rp->evt_msg.data, &(rp->extdata),
+					&(rp->extlen));
+			break;
+		case MSG_OUTPUT1:
+		case MSG_OUTPUT2:
+			if (op_mode & SNAPSHOT_MASK_MODE) {
+				resp->vfe_free(data);
+				return;
+			}
+			rp->type = VFE_MSG_OUTPUT_P;
+			vfe_7x_convert(&(rp->phy), VFE_MSG_OUTPUT_P,
+				rp->evt_msg.data, &(rp->extdata),
+				&(rp->extlen));
+			break;
+		case MSG_STATS_AF:
+			rp->type = VFE_MSG_STATS_AF;
+			vfe_7x_convert(&(rp->phy), VFE_MSG_STATS_AF,
+					rp->evt_msg.data, NULL, NULL);
+			break;
+		case MSG_STATS_WE:
+			rp->type = VFE_MSG_STATS_WE;
+			vfe_7x_convert(&(rp->phy), VFE_MSG_STATS_WE,
+					rp->evt_msg.data, NULL, NULL);
+
+			CDBG("MSG_STATS_WE: phy = 0x%x\n", rp->phy.sbuf_phy);
+			break;
+		case MSG_STOP_ACK:
+			rp->type = VFE_MSG_GENERAL;
+			stopevent.state = 1;
+			wake_up(&stopevent.wait);
+			break;
+		default:
+			rp->type = VFE_MSG_GENERAL;
+			break;
+		}
+		if (id != MSG_SOF)
+			resp->vfe_resp(rp, MSM_CAM_Q_VFE_MSG,
+					vfe_syncdata, GFP_ATOMIC);
+	}
+}
+
+static struct msm_adsp_ops vfe_7x_sync = {
+	.event = vfe_7x_ops,
+};
+
+static int vfe_7x_enable(struct camera_enable_cmd *enable)
+{
+	int rc = -EFAULT;
+	static int cnt;
+
+	if (!strcmp(enable->name, "QCAMTASK"))
+		rc = msm_adsp_enable(qcam_mod);
+	else if (!strcmp(enable->name, "VFETASK"))
+		rc = msm_adsp_enable(vfe_mod);
+
+	if (!cnt) {
+		msm_camio_set_perf_lvl(S_INIT);
+		cnt++;
+	}
+	return rc;
+}
+
+static int vfe_7x_disable(struct camera_enable_cmd *enable,
+		struct platform_device *dev __attribute__((unused)))
+{
+	int rc = -EFAULT;
+
+	if (!strcmp(enable->name, "QCAMTASK"))
+		rc = msm_adsp_disable(qcam_mod);
+	else if (!strcmp(enable->name, "VFETASK"))
+		rc = msm_adsp_disable(vfe_mod);
+
+	return rc;
+}
+
+static int vfe_7x_stop(void)
+{
+	int rc = 0;
+	uint32_t stopcmd = VFE_STOP_CMD;
+	rc = msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
+				&stopcmd, sizeof(uint32_t));
+	if (rc < 0) {
+		CDBG("%s:%d: failed rc = %d\n", __func__, __LINE__, rc);
+		return rc;
+	}
+
+	stopevent.state = 0;
+	rc = wait_event_timeout(stopevent.wait,
+		stopevent.state != 0,
+		msecs_to_jiffies(stopevent.timeout));
+
+	return rc;
+}
+
+static void vfe_7x_release(struct platform_device *pdev)
+{
+	mutex_lock(&vfe_lock);
+	vfe_syncdata = NULL;
+	mutex_unlock(&vfe_lock);
+
+	if (!vfestopped) {
+		CDBG("%s:%d:Calling vfe_7x_stop()\n", __func__, __LINE__);
+		vfe_7x_stop();
+	} else
+		vfestopped = 0;
+
+	msm_adsp_disable(qcam_mod);
+	msm_adsp_disable(vfe_mod);
+
+	msm_adsp_put(qcam_mod);
+	msm_adsp_put(vfe_mod);
+
+	msm_camio_disable(pdev);
+
+	kfree(extdata);
+	extlen = 0;
+
+	msm_camio_set_perf_lvl(S_EXIT);
+}
+
+static int vfe_7x_init(struct msm_vfe_callback *presp,
+	struct platform_device *dev)
+{
+	int rc = 0;
+
+	init_waitqueue_head(&stopevent.wait);
+	stopevent.timeout = 200;
+	stopevent.state = 0;
+
+	if (presp && presp->vfe_resp)
+		resp = presp;
+	else
+		return -EFAULT;
+
+	/* Bring up all the required GPIOs and Clocks */
+	rc = msm_camio_enable(dev);
+	if (rc < 0)
+		return rc;
+
+	extlen = sizeof(struct vfe_frame_extra);
+
+	extdata = kmalloc(extlen, GFP_ATOMIC);
+	if (!extdata) {
+		rc = -ENOMEM;
+		goto init_fail;
+	}
+
+	rc = msm_adsp_get("QCAMTASK", &qcam_mod, &vfe_7x_sync, NULL);
+	if (rc) {
+		rc = -EBUSY;
+		goto get_qcam_fail;
+	}
+
+	rc = msm_adsp_get("VFETASK", &vfe_mod, &vfe_7x_sync, NULL);
+	if (rc) {
+		rc = -EBUSY;
+		goto get_vfe_fail;
+	}
+
+	return 0;
+
+get_vfe_fail:
+	msm_adsp_put(qcam_mod);
+get_qcam_fail:
+	kfree(extdata);
+init_fail:
+	extlen = 0;
+	return rc;
+}
+
+static int vfe_7x_config_axi(int mode,
+	struct axidata *ad, struct axiout *ao)
+{
+	struct msm_pmem_region *regptr;
+	unsigned long *bptr;
+	int    cnt;
+
+	int rc = 0;
+
+	if (mode == OUTPUT_1 || mode == OUTPUT_1_AND_2) {
+		regptr = ad->region;
+
+		CDBG("bufnum1 = %d\n", ad->bufnum1);
+		if (mode == OUTPUT_1_AND_2) {
+			paddr_t_y = regptr->paddr + regptr->info.planar0_off;
+			paddr_t_cbcr = regptr->paddr +
+			regptr->info.planar1_off;
+		}
+
+		CDBG("config_axi1: O1, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
+			regptr->paddr, regptr->info.planar0_off,
+			regptr->info.planar1_off);
+
+		bptr = &ao->output1buffer1_y_phy;
+		for (cnt = 0; cnt < ad->bufnum1; cnt++) {
+			*bptr = regptr->paddr + regptr->info.planar0_off;
+			bptr++;
+			*bptr = regptr->paddr + regptr->info.planar1_off;
+
+			bptr++;
+			regptr++;
+		}
+
+		regptr--;
+		for (cnt = 0; cnt < (8 - ad->bufnum1); cnt++) {
+			*bptr = regptr->paddr + regptr->info.planar0_off;
+			bptr++;
+			*bptr = regptr->paddr + regptr->info.planar1_off;
+			bptr++;
+		}
+	}
+
+	if (mode == OUTPUT_2 || mode == OUTPUT_1_AND_2) {
+		regptr = &(ad->region[ad->bufnum1]);
+
+		CDBG("bufnum2 = %d\n", ad->bufnum2);
+		paddr_s_y = regptr->paddr +  regptr->info.planar0_off;
+		paddr_s_cbcr = regptr->paddr +  regptr->info.planar1_off;
+
+		CDBG("config_axi2: O2, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
+			regptr->paddr, regptr->info.planar0_off,
+			regptr->info.planar1_off);
+
+		bptr = &ao->output2buffer1_y_phy;
+		for (cnt = 0; cnt < ad->bufnum2; cnt++) {
+			*bptr = regptr->paddr + regptr->info.planar0_off;
+			bptr++;
+			*bptr = regptr->paddr + regptr->info.planar1_off;
+
+			bptr++;
+			regptr++;
+		}
+
+		regptr--;
+		for (cnt = 0; cnt < (8 - ad->bufnum2); cnt++) {
+			*bptr = regptr->paddr + regptr->info.planar0_off;
+			bptr++;
+			*bptr = regptr->paddr + regptr->info.planar1_off;
+			bptr++;
+		}
+	}
+
+	return rc;
+}
+
+static int vfe_7x_config(struct msm_vfe_cfg_cmd *cmd, void *data)
+{
+	struct msm_pmem_region *regptr;
+	unsigned char buf[256];
+
+	struct vfe_stats_ack sack;
+	struct axidata *axid;
+	uint32_t i;
+	uint32_t *_mode;
+
+	struct vfe_stats_we_cfg *scfg = NULL;
+	struct vfe_stats_af_cfg *sfcfg = NULL;
+
+	struct axiout *axio = NULL;
+	void   *cmd_data = NULL;
+	void   *cmd_data_alloc = NULL;
+	long rc = 0;
+	struct msm_vfe_command_7k *vfecmd;
+
+	vfecmd = kmalloc(sizeof(struct msm_vfe_command_7k), GFP_ATOMIC);
+	if (!vfecmd) {
+		pr_err("vfecmd alloc failed!\n");
+		return -ENOMEM;
+	}
+
+	if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
+	    cmd->cmd_type != CMD_STATS_BUF_RELEASE &&
+	    cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE) {
+		if (copy_from_user(vfecmd,
+				(void __user *)(cmd->value),
+				sizeof(struct msm_vfe_command_7k))) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+	}
+
+	switch (cmd->cmd_type) {
+	case CMD_STATS_AEC_AWB_ENABLE:
+	case CMD_STATS_AXI_CFG: {
+		axid = data;
+		if (!axid) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+
+		scfg =
+			kmalloc(sizeof(struct vfe_stats_we_cfg),
+				GFP_ATOMIC);
+		if (!scfg) {
+			rc = -ENOMEM;
+			goto config_failure;
+		}
+
+		if (copy_from_user(scfg,
+					(void __user *)(vfecmd->value),
+					vfecmd->length)) {
+
+			rc = -EFAULT;
+			goto config_done;
+		}
+
+		CDBG("STATS_ENABLE: bufnum = %d, enabling = %d\n",
+			axid->bufnum1, scfg->wb_expstatsenable);
+
+		if (axid->bufnum1 > 0) {
+			regptr = axid->region;
+
+			for (i = 0; i < axid->bufnum1; i++) {
+
+				CDBG("STATS_ENABLE, phy = 0x%lx\n",
+					regptr->paddr);
+
+				scfg->wb_expstatoutputbuffer[i] =
+					(void *)regptr->paddr;
+				regptr++;
+			}
+
+			cmd_data = scfg;
+
+		} else {
+			rc = -EINVAL;
+			goto config_done;
+		}
+	}
+		break;
+	case CMD_STATS_AF_ENABLE:
+	case CMD_STATS_AF_AXI_CFG: {
+		axid = data;
+		if (!axid) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+
+		sfcfg =
+			kmalloc(sizeof(struct vfe_stats_af_cfg),
+				GFP_ATOMIC);
+
+		if (!sfcfg) {
+			rc = -ENOMEM;
+			goto config_failure;
+		}
+
+		if (copy_from_user(sfcfg,
+					(void __user *)(vfecmd->value),
+					vfecmd->length)) {
+
+			rc = -EFAULT;
+			goto config_done;
+		}
+
+		CDBG("AF_ENABLE: bufnum = %d, enabling = %d\n",
+			axid->bufnum1, sfcfg->af_enable);
+
+		if (axid->bufnum1 > 0) {
+			regptr = &axid->region[0];
+
+			for (i = 0; i < axid->bufnum1; i++) {
+
+				CDBG("STATS_ENABLE, phy = 0x%lx\n",
+					regptr->paddr);
+
+				sfcfg->af_outbuf[i] =
+					(void *)regptr->paddr;
+
+				regptr++;
+			}
+
+			cmd_data = sfcfg;
+
+		} else {
+			rc = -EINVAL;
+			goto config_done;
+		}
+	}
+		break;
+	case CMD_FRAME_BUF_RELEASE: {
+		struct msm_frame *b;
+		unsigned long p;
+		struct vfe_outputack fack;
+		if (!data)  {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+
+		b = (struct msm_frame *)(cmd->value);
+		p = *(unsigned long *)data;
+
+		fack.header = VFE_FRAME_ACK;
+
+		fack.output2newybufferaddress =
+			(void *)(p + b->planar0_off);
+
+		fack.output2newcbcrbufferaddress =
+			(void *)(p + b->planar1_off);
+
+		vfecmd->queue = QDSP_CMDQUEUE;
+		vfecmd->length = sizeof(struct vfe_outputack);
+		cmd_data = &fack;
+	}
+		break;
+	case CMD_SNAP_BUF_RELEASE:
+		break;
+	case CMD_STATS_BUF_RELEASE: {
+		CDBG("vfe_7x_config: CMD_STATS_BUF_RELEASE\n");
+		if (!data) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+
+		sack.header = STATS_WE_ACK;
+		sack.bufaddr = (void *)*(uint32_t *)data;
+
+		vfecmd->queue  = QDSP_CMDQUEUE;
+		vfecmd->length = sizeof(struct vfe_stats_ack);
+		cmd_data = &sack;
+	}
+		break;
+	case CMD_STATS_AF_BUF_RELEASE: {
+		CDBG("vfe_7x_config: CMD_STATS_AF_BUF_RELEASE\n");
+		if (!data) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+
+		sack.header = STATS_AF_ACK;
+		sack.bufaddr = (void *)*(uint32_t *)data;
+
+		vfecmd->queue  = QDSP_CMDQUEUE;
+		vfecmd->length = sizeof(struct vfe_stats_ack);
+		cmd_data = &sack;
+	}
+		break;
+	case CMD_GENERAL:
+	case CMD_STATS_DISABLE: {
+		if (vfecmd->length > 256) {
+			cmd_data_alloc =
+			cmd_data = kmalloc(vfecmd->length, GFP_ATOMIC);
+			if (!cmd_data) {
+				rc = -ENOMEM;
+				goto config_failure;
+			}
+		} else
+			cmd_data = buf;
+
+		if (copy_from_user(cmd_data,
+					(void __user *)(vfecmd->value),
+					vfecmd->length)) {
+
+			rc = -EFAULT;
+			goto config_done;
+		}
+
+		if (vfecmd->queue == QDSP_CMDQUEUE) {
+			switch (*(uint32_t *)cmd_data) {
+			case VFE_RESET_CMD:
+				msm_camio_vfe_blk_reset();
+				vfestopped = 0;
+				break;
+			case VFE_START_CMD:
+				_mode = (uint32_t *)cmd_data;
+				op_mode = *(++_mode);
+				if (op_mode & SNAPSHOT_MASK_MODE)
+					msm_camio_set_perf_lvl(S_CAPTURE);
+				else
+					msm_camio_set_perf_lvl(S_PREVIEW);
+				vfestopped = 0;
+				break;
+			case VFE_STOP_CMD:
+				vfestopped = 1;
+				goto config_send;
+
+			default:
+				break;
+			}
+		} /* QDSP_CMDQUEUE */
+	}
+		break;
+	case CMD_AXI_CFG_PREVIEW:
+	case CMD_RAW_PICT_AXI_CFG: {
+		axid = data;
+		if (!axid) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+
+		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			goto config_failure;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd->value),
+					sizeof(struct axiout))) {
+			rc = -EFAULT;
+			goto config_done;
+		}
+
+		vfe_7x_config_axi(OUTPUT_2, axid, axio);
+		cmd_data = axio;
+	}
+		break;
+	case CMD_AXI_CFG_SNAP: {
+		axid = data;
+		if (!axid) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+
+		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			goto config_failure;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd->value),
+					sizeof(struct axiout))) {
+			rc = -EFAULT;
+			goto config_done;
+		}
+
+		vfe_7x_config_axi(OUTPUT_1_AND_2, axid, axio);
+
+		cmd_data = axio;
+	}
+		break;
+	default:
+		break;
+	}
+
+	if (vfestopped)
+		goto config_done;
+
+config_send:
+	CDBG("send adsp command = %d\n", *(uint32_t *)cmd_data);
+	rc = msm_adsp_write(vfe_mod, vfecmd->queue,
+				cmd_data, vfecmd->length);
+
+config_done:
+	kfree(cmd_data_alloc);
+
+config_failure:
+	kfree(scfg);
+	kfree(axio);
+	kfree(vfecmd);
+	return rc;
+}
+
+void msm_camvfe_fn_init(struct msm_camvfe_fn *fptr, void *data)
+{
+	mutex_init(&vfe_lock);
+	fptr->vfe_init    = vfe_7x_init;
+	fptr->vfe_enable  = vfe_7x_enable;
+	fptr->vfe_config  = vfe_7x_config;
+	fptr->vfe_disable = vfe_7x_disable;
+	fptr->vfe_release = vfe_7x_release;
+	vfe_syncdata = data;
+}
+
+void msm_camvpe_fn_init(struct msm_camvpe_fn *fptr, void *data)
+{
+	fptr->vpe_reg		= NULL;
+	fptr->send_frame_to_vpe	= NULL;
+	fptr->vpe_config	= NULL;
+	fptr->vpe_cfg_update	= NULL;
+	fptr->dis		= NULL;
+}
diff --git a/drivers/media/platform/msm/camera_v1/vfe/msm_vfe7x27a.h b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe7x27a.h
new file mode 100644
index 0000000..fbebb60
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe7x27a.h
@@ -0,0 +1,300 @@
+/* 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.
+ */
+
+#ifndef __MSM_VFE7X_H__
+#define __MSM_VFE7X_H__
+#include <media/msm_camera.h>
+#include <mach/camera.h>
+
+struct vfe_frame_extra {
+	uint32_t	bl_evencol:23;
+	uint32_t	rvd1:9;
+	uint32_t	bl_oddcol:23;
+	uint32_t	rvd2:9;
+
+	uint32_t	d_dbpc_stats_hot:16;
+	uint32_t	d_dbpc_stats_cold:16;
+
+	uint32_t	d_dbpc_stats_0_hot:10;
+	uint32_t	rvd3:6;
+	uint32_t	d_dbpc_stats_0_cold:10;
+	uint32_t	rvd4:6;
+	uint32_t	d_dbpc_stats_1_hot:10;
+	uint32_t	rvd5:6;
+	uint32_t	d_dbpc_stats_1_cold:10;
+	uint32_t	rvd6:6;
+
+	uint32_t	asf_max_edge;
+
+	uint32_t	e_y_wm_pm_stats_0:21;
+	uint32_t	rvd7:11;
+	uint32_t	e_y_wm_pm_stats_1_bl:8;
+	uint32_t	rvd8:8;
+	uint32_t	e_y_wm_pm_stats_1_nl:12;
+	uint32_t	rvd9:4;
+
+	uint32_t	e_cbcr_wm_pm_stats_0:21;
+	uint32_t	rvd10:11;
+	uint32_t	e_cbcr_wm_pm_stats_1_bl:8;
+	uint32_t	rvd11:8;
+	uint32_t	e_cbcr_wm_pm_stats_1_nl:12;
+	uint32_t	rvd12:4;
+
+	uint32_t	v_y_wm_pm_stats_0:21;
+	uint32_t	rvd13:11;
+	uint32_t	v_y_wm_pm_stats_1_bl:8;
+	uint32_t	rvd14:8;
+	uint32_t	v_y_wm_pm_stats_1_nl:12;
+	uint32_t	rvd15:4;
+
+	uint32_t	v_cbcr_wm_pm_stats_0:21;
+	uint32_t	rvd16:11;
+	uint32_t	v_cbcr_wm_pm_stats_1_bl:8;
+	uint32_t	rvd17:8;
+	uint32_t	v_cbcr_wm_pm_stats_1_nl:12;
+	uint32_t	rvd18:4;
+
+	uint32_t      frame_id;
+};
+
+struct vfe_endframe {
+	uint32_t      y_address;
+	uint32_t      cbcr_address;
+
+	struct vfe_frame_extra extra;
+} __packed;
+
+struct vfe_outputack {
+	uint32_t  header;
+	void      *output2newybufferaddress;
+	void      *output2newcbcrbufferaddress;
+} __packed;
+
+struct vfe_stats_ack {
+	uint32_t header;
+	/* MUST BE 64 bit ALIGNED */
+	void     *bufaddr;
+} __packed;
+
+/* AXI Output Config Command sent to DSP */
+struct axiout {
+	uint32_t            cmdheader:32;
+	int                 outputmode:3;
+	uint8_t             format:2;
+	uint32_t            /* reserved */ : 27;
+
+	/* AXI Output 1 Y Configuration, Part 1 */
+	uint32_t            out1yimageheight:12;
+	uint32_t            /* reserved */ : 4;
+	uint32_t            out1yimagewidthin64bitwords:10;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 1 Y Configuration, Part 2 */
+	uint8_t             out1yburstlen:2;
+	uint32_t            out1ynumrows:12;
+	uint32_t            out1yrowincin64bitincs:12;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 1 CbCr Configuration, Part 1 */
+	uint32_t            out1cbcrimageheight:12;
+	uint32_t            /* reserved */ : 4;
+	uint32_t            out1cbcrimagewidthin64bitwords:10;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 1 CbCr Configuration, Part 2 */
+	uint8_t             out1cbcrburstlen:2;
+	uint32_t            out1cbcrnumrows:12;
+	uint32_t            out1cbcrrowincin64bitincs:12;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 2 Y Configuration, Part 1 */
+	uint32_t            out2yimageheight:12;
+	uint32_t            /* reserved */ : 4;
+	uint32_t            out2yimagewidthin64bitwords:10;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 2 Y Configuration, Part 2 */
+	uint8_t             out2yburstlen:2;
+	uint32_t            out2ynumrows:12;
+	uint32_t            out2yrowincin64bitincs:12;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 2 CbCr Configuration, Part 1 */
+	uint32_t            out2cbcrimageheight:12;
+	uint32_t            /* reserved */ : 4;
+	uint32_t            out2cbcrimagewidtein64bitwords:10;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 2 CbCr Configuration, Part 2 */
+	uint8_t             out2cbcrburstlen:2;
+	uint32_t            out2cbcrnumrows:12;
+	uint32_t            out2cbcrrowincin64bitincs:12;
+	uint32_t            /* reserved */ : 6;
+
+	/* Address configuration:
+	 * output1 phisycal address */
+	unsigned long   output1buffer1_y_phy;
+	unsigned long   output1buffer1_cbcr_phy;
+	unsigned long   output1buffer2_y_phy;
+	unsigned long   output1buffer2_cbcr_phy;
+	unsigned long   output1buffer3_y_phy;
+	unsigned long   output1buffer3_cbcr_phy;
+	unsigned long   output1buffer4_y_phy;
+	unsigned long   output1buffer4_cbcr_phy;
+	unsigned long   output1buffer5_y_phy;
+	unsigned long   output1buffer5_cbcr_phy;
+	unsigned long   output1buffer6_y_phy;
+	unsigned long   output1buffer6_cbcr_phy;
+	unsigned long   output1buffer7_y_phy;
+	unsigned long   output1buffer7_cbcr_phy;
+	unsigned long   output1buffer8_y_phy;
+	unsigned long   output1buffer8_cbcr_phy;
+
+	/* output2 phisycal address */
+	unsigned long   output2buffer1_y_phy;
+	unsigned long   output2buffer1_cbcr_phy;
+	unsigned long   output2buffer2_y_phy;
+	unsigned long   output2buffer2_cbcr_phy;
+	unsigned long   output2buffer3_y_phy;
+	unsigned long   output2buffer3_cbcr_phy;
+	unsigned long   output2buffer4_y_phy;
+	unsigned long   output2buffer4_cbcr_phy;
+	unsigned long   output2buffer5_y_phy;
+	unsigned long   output2buffer5_cbcr_phy;
+	unsigned long   output2buffer6_y_phy;
+	unsigned long   output2buffer6_cbcr_phy;
+	unsigned long   output2buffer7_y_phy;
+	unsigned long   output2buffer7_cbcr_phy;
+	unsigned long   output2buffer8_y_phy;
+	unsigned long   output2buffer8_cbcr_phy;
+} __packed;
+
+struct vfe_stats_we_cfg {
+	uint32_t       header;
+
+	/* White Balance/Exposure Statistic Selection */
+	uint8_t        wb_expstatsenable:1;
+	uint8_t        wb_expstatbuspriorityselection:1;
+	unsigned int   wb_expstatbuspriorityvalue:4;
+	unsigned int   /* reserved */ : 26;
+
+	/* White Balance/Exposure Statistic Configuration, Part 1 */
+	uint8_t        exposurestatregions:1;
+	uint8_t        exposurestatsubregions:1;
+	unsigned int   /* reserved */ : 14;
+
+	unsigned int   whitebalanceminimumy:8;
+	unsigned int   whitebalancemaximumy:8;
+
+	/* White Balance/Exposure Statistic Configuration, Part 2 */
+	uint8_t wb_expstatslopeofneutralregionline[
+		NUM_WB_EXP_NEUTRAL_REGION_LINES];
+
+	/* White Balance/Exposure Statistic Configuration, Part 3 */
+	unsigned int   wb_expstatcrinterceptofneutralregionline2:12;
+	unsigned int   /* reserved */ : 4;
+	unsigned int   wb_expstatcbinterceptofneutralreginnline1:12;
+	unsigned int    /* reserved */ : 4;
+
+	/* White Balance/Exposure Statistic Configuration, Part 4 */
+	unsigned int   wb_expstatcrinterceptofneutralregionline4:12;
+	unsigned int   /* reserved */ : 4;
+	unsigned int   wb_expstatcbinterceptofneutralregionline3:12;
+	unsigned int   /* reserved */ : 4;
+
+	/* White Balance/Exposure Statistic Output Buffer Header */
+	unsigned int   wb_expmetricheaderpattern:8;
+	unsigned int   /* reserved */ : 24;
+
+	/* White Balance/Exposure Statistic Output Buffers-MUST
+	* BE 64 bit ALIGNED */
+	void  *wb_expstatoutputbuffer[NUM_WB_EXP_STAT_OUTPUT_BUFFERS];
+} __packed;
+
+struct vfe_stats_af_cfg {
+	uint32_t header;
+
+	/* Autofocus Statistic Selection */
+	uint8_t       af_enable:1;
+	uint8_t       af_busprioritysel:1;
+	unsigned int  af_buspriorityval:4;
+	unsigned int  /* reserved */ : 26;
+
+	/* Autofocus Statistic Configuration, Part 1 */
+	unsigned int  af_singlewinvoffset:12;
+	unsigned int  /* reserved */ : 4;
+	unsigned int  af_singlewinhoffset:12;
+	unsigned int  /* reserved */ : 3;
+	uint8_t       af_winmode:1;
+
+	/* Autofocus Statistic Configuration, Part 2 */
+	unsigned int  af_singglewinvh:11;
+	unsigned int  /* reserved */ : 5;
+	unsigned int  af_singlewinhw:11;
+	unsigned int  /* reserved */ : 5;
+
+	/* Autofocus Statistic Configuration, Parts 3-6 */
+	uint8_t       af_multiwingrid[NUM_AUTOFOCUS_MULTI_WINDOW_GRIDS];
+
+	/* Autofocus Statistic Configuration, Part 7 */
+	signed int    af_metrichpfcoefa00:5;
+	signed int    af_metrichpfcoefa04:5;
+	unsigned int  af_metricmaxval:11;
+	uint8_t       af_metricsel:1;
+	unsigned int  /* reserved */ : 10;
+
+	/* Autofocus Statistic Configuration, Part 8 */
+	signed int    af_metrichpfcoefa20:5;
+	signed int    af_metrichpfcoefa21:5;
+	signed int    af_metrichpfcoefa22:5;
+	signed int    af_metrichpfcoefa23:5;
+	signed int    af_metrichpfcoefa24:5;
+	unsigned int  /* reserved */ : 7;
+
+	/* Autofocus Statistic Output Buffer Header */
+	unsigned int  af_metrichp:8;
+	unsigned int  /* reserved */ : 24;
+
+	/* Autofocus Statistic Output Buffers - MUST BE 64 bit ALIGNED!!! */
+	void *af_outbuf[NUM_AF_STAT_OUTPUT_BUFFERS];
+} __packed; /* VFE_StatsAutofocusConfigCmdType */
+
+struct msm_camera_frame_msg {
+	unsigned long   output_y_address;
+	unsigned long   output_cbcr_address;
+
+	unsigned int    blacklevelevenColumn:23;
+	uint16_t        reserved1:9;
+	unsigned int    blackleveloddColumn:23;
+	uint16_t        reserved2:9;
+
+	uint16_t        greendefectpixelcount:8;
+	uint16_t        reserved3:8;
+	uint16_t        redbluedefectpixelcount:8;
+	uint16_t        reserved4:8;
+} __packed;
+
+/* New one for 7k */
+struct msm_vfe_command_7k {
+	uint16_t queue;
+	uint16_t length;
+	void     *value;
+};
+
+struct stop_event {
+	wait_queue_head_t wait;
+	int state;
+	int timeout;
+};
+
+
+#endif /* __MSM_VFE7X_H__ */
diff --git a/drivers/media/platform/msm/camera_v1/vfe/msm_vfe7x27a_v4l2.c b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe7x27a_v4l2.c
new file mode 100644
index 0000000..f3388d9
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe7x27a_v4l2.c
@@ -0,0 +1,2479 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/msm_adsp.h>
+#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/android_pmem.h>
+#include <linux/slab.h>
+#include <linux/pm_qos.h>
+#include <linux/delay.h>
+#include <linux/wait.h>
+#include <linux/module.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+#include <media/msm_isp.h>
+#include <mach/msm_adsp.h>
+#include <linux/clk.h>
+#include <mach/clk.h>
+#include <mach/camera.h>
+#include "msm_vfe7x27a_v4l2.h"
+#include "msm.h"
+
+/* ADSP Messages */
+#define MSG_RESET_ACK  0
+#define MSG_STOP_ACK  1
+#define MSG_SNAPSHOT  2
+#define MSG_ILLEGAL_COMMAND  3
+#define MSG_START_ACK  4
+#define MSG_UPDATE_ACK  5
+#define MSG_OUTPUT1  6
+#define MSG_OUTPUT2  7
+#define MSG_STATS_AF  8
+#define MSG_STATS_WE  9
+#define MSG_STATS_HISTOGRAM  10
+#define MSG_EPOCH1  11
+#define MSG_EPOCH2  12
+#define MSG_VFE_ERROR 13
+#define MSG_SYNC_TIMER1_DONE  14
+#define MSG_SYNC_TIMER2_DONE  15
+#define MSG_ASYNC_TIMER1_DONE  16
+#define MSG_ASYNC_TIMER2_DONE  17
+#define MSG_CAPTURE_COMPLETE  18
+#define MSG_TABLE_CMD_ACK  19
+#define MSG_EXP_TIMEOUT_ACK  20
+#define MSG_SOF  21
+#define MSG_OUTPUT_T  22
+#define MSG_OUTPUT_S  23
+
+#define VFE_ADSP_EVENT 0xFFFF
+#define SNAPSHOT_MASK_MODE 0x00000001
+#define MSM_AXI_QOS_PREVIEW	122000
+#define MSM_AXI_QOS_SNAPSHOT	192000
+
+
+#define QDSP_CMDQUEUE 25
+#define QDSP_SCALEQUEUE 26
+#define QDSP_TABLEQUEUE 27
+
+/* ADSP Scler queue Cmd IDs */
+#define VFE_SCALE_OUTPUT1_CONFIG  0
+#define VFE_SCALE_OUTPUT2_CONFIG  1
+#define VFE_SCALE_MAX  0xFFFFFFFF
+
+/* ADSP table queue Cmd IDs */
+#define VFE_AXI_INPUT_CONFIG  0
+#define VFE_AXI_OUTPUT_CONFIG  1
+#define VFE_RGB_GAMMA_CONFIG  2
+#define VFE_Y_GAMMA_CONFIG  3
+#define VFE_ROLL_OFF_CONFIG  4
+#define VFE_DEMOSAICv3_BPC_CFG  6
+#define VFE_DEMOSAICv3_ABF_CFG  7
+#define VFE_DEMOSAICv3_CFG  8
+#define VFE_MAX  0xFFFFFFFF
+
+/* ADSP cfg queue cmd IDs */
+#define VFE_RESET  0
+#define VFE_START  1
+#define VFE_STOP  2
+#define VFE_UPDATE  3
+#define VFE_CAMIF_CONFIG  4
+#define VFE_ACTIVE_REGION_CONFIG  5
+#define VFE_DEMOSAIC_CONFIG  6
+#define VFE_INPUT_FORMAT_CONFIG  7
+#define VFE_OUTPUT_CLAMP_CONFIG  8
+#define VFE_CHROMA_SUBSAMPLE_CONFIG  9
+#define VFE_BLACK_LEVEL_CONFIG  10
+#define VFE_WHITE_BALANCE_CONFIG  11
+#define VFE_COLOR_PROCESSING_CONFIG  12
+#define VFE_ADAPTIVE_FILTER_CONFIG  13
+#define VFE_FRAME_SKIP_CONFIG  14
+#define VFE_FOV_CROP  15
+#define VFE_STATS_AUTOFOCUS_CONFIG  16
+#define VFE_STATS_WB_EXP_CONFIG  17
+#define VFE_STATS_HISTOGRAM_CONFIG  18
+#define VFE_OUTPUT1_ACK  19
+#define VFE_OUTPUT2_ACK  20
+#define VFE_STATS_AUTOFOCUS_ACK  21
+#define VFE_STATS_WB_EXP_ACK  22
+#define VFE_EPOCH1_ACK  23
+#define VFE_EPOCH2_ACK  24
+#define VFE_UPDATE_CAMIF_FRAME_CONFIG  25
+#define VFE_SYNC_TIMER1_CONFIG  26
+#define VFE_SYNC_TIMER2_CONFIG  27
+#define VFE_ASYNC_TIMER1_START  28
+#define VFE_ASYNC_TIMER2_START  29
+#define VFE_STATS_AUTOFOCUS_UPDATE  30
+#define VFE_STATS_WB_EXP_UPDATE  31
+#define VFE_ROLL_OFF_UPDATE  33
+#define VFE_DEMOSAICv3_BPC_UPDATE  34
+#define VFE_TESTGEN_START  35
+#define VFE_STATS_MA  0xFFFFFFFF
+
+struct msg_id_map msgs_map[] = {
+	{MSG_RESET_ACK, MSG_ID_RESET_ACK},
+	{MSG_STOP_ACK, MSG_ID_STOP_ACK},
+	{MSG_SNAPSHOT, MSG_ID_SNAPSHOT_DONE},
+	{MSG_ILLEGAL_COMMAND, VFE_MAX},
+	{MSG_START_ACK, MSG_ID_START_ACK},
+	{MSG_UPDATE_ACK, MSG_ID_UPDATE_ACK},
+	{MSG_OUTPUT1, VFE_MAX},
+	{MSG_OUTPUT2, VFE_MAX},
+	{MSG_STATS_AF, MSG_ID_STATS_AF},
+	{MSG_STATS_WE, MSG_ID_STATS_AWB_AEC},
+	{MSG_STATS_HISTOGRAM, MSG_ID_STATS_IHIST},
+	{MSG_EPOCH1, MSG_ID_EPOCH1},
+	{MSG_EPOCH2, MSG_ID_EPOCH2},
+	{MSG_VFE_ERROR, MSG_ID_CAMIF_ERROR},
+	{MSG_SYNC_TIMER1_DONE, MSG_ID_SYNC_TIMER1_DONE},
+	{MSG_SYNC_TIMER2_DONE, MSG_ID_SYNC_TIMER2_DONE},
+	{MSG_ASYNC_TIMER1_DONE, MSG_ID_ASYNC_TIMER1_DONE},
+	{MSG_ASYNC_TIMER2_DONE, MSG_ID_ASYNC_TIMER2_DONE},
+	{MSG_CAPTURE_COMPLETE, MSG_CAPTURE_COMPLETE},
+	{MSG_TABLE_CMD_ACK, MSG_TABLE_CMD_ACK},
+	{MSG_EXP_TIMEOUT_ACK, MSG_EXP_TIMEOUT_ACK},
+	{MSG_SOF, MSG_ID_SOF_ACK},
+	{MSG_OUTPUT_T, MSG_ID_OUTPUT_T},
+	{MSG_OUTPUT_S, MSG_ID_OUTPUT_S},
+};
+
+struct cmd_id_map cmds_map[] = {
+	{VFE_CMD_DUMMY_0, VFE_MAX, VFE_MAX},
+	{VFE_CMD_SET_CLK, VFE_MAX, VFE_MAX},
+	{VFE_CMD_RESET, VFE_RESET, QDSP_CMDQUEUE,
+			"VFE_CMD_RESET", "VFE_RESET"},
+	{VFE_CMD_START, VFE_START, QDSP_CMDQUEUE,
+			"VFE_CMD_START", "VFE_START"},
+	{VFE_CMD_TEST_GEN_START, VFE_TESTGEN_START, QDSP_CMDQUEUE,
+		"VFE_CMD_TEST_GEN_START", "VFE_TESTGEN_START"},
+	{VFE_CMD_OPERATION_CFG, VFE_MAX , VFE_MAX},
+	{VFE_CMD_AXI_OUT_CFG, VFE_AXI_OUTPUT_CONFIG, QDSP_TABLEQUEUE,
+		"VFE_CMD_AXI_OUT_CFG", "VFE_AXI_OUTPUT_CONFIG"},
+	{VFE_CMD_CAMIF_CFG, VFE_CAMIF_CONFIG, QDSP_CMDQUEUE,
+			"VFE_CMD_CAMIF_CFG", "VFE_CAMIF_CONFIG"},
+	{VFE_CMD_AXI_INPUT_CFG, VFE_AXI_INPUT_CONFIG, QDSP_TABLEQUEUE,
+		"VFE_CMD_AXI_INPUT_CFG", "VFE_AXI_INPUT_CONFIG"},
+	{VFE_CMD_BLACK_LEVEL_CFG, VFE_BLACK_LEVEL_CONFIG, QDSP_CMDQUEUE,
+		"VFE_CMD_BLACK_LEVEL_CFG", "VFE_BLACK_LEVEL_CONFIG"},
+	{VFE_CMD_MESH_ROLL_OFF_CFG, VFE_ROLL_OFF_CONFIG, QDSP_TABLEQUEUE,
+		"VFE_CMD_MESH_ROLL_OFF_CFG", "VFE_ROLL_OFF_CONFIG"},
+	{VFE_CMD_DEMUX_CFG, VFE_INPUT_FORMAT_CONFIG, QDSP_CMDQUEUE,
+		"VFE_CMD_DEMUX_CFG", "VFE_INPUT_FORMAT_CONFIG"},
+	{VFE_CMD_FOV_CFG, VFE_FOV_CROP, QDSP_CMDQUEUE,
+		"VFE_CMD_FOV_CFG", "VFE_FOV_CROP"},
+	{VFE_CMD_MAIN_SCALER_CFG, VFE_MAX, VFE_MAX},
+	{VFE_CMD_WB_CFG, VFE_WHITE_BALANCE_CONFIG, QDSP_CMDQUEUE,
+		"VFE_CMD_WB_CFG", "VFE_WHITE_BALANCE_CONFIG"},
+	{VFE_CMD_COLOR_COR_CFG, VFE_MAX, VFE_MAX},
+	{VFE_CMD_RGB_G_CFG, VFE_RGB_GAMMA_CONFIG, QDSP_TABLEQUEUE,
+		"VFE_CMD_RGB_G_CFG", "VFE_RGB_GAMMA_CONFIG"},
+	{VFE_CMD_LA_CFG, VFE_MAX, VFE_MAX},
+	{VFE_CMD_CHROMA_EN_CFG, VFE_MAX, VFE_MAX},
+	{VFE_CMD_CHROMA_SUP_CFG, VFE_MAX, VFE_MAX},
+	{VFE_CMD_MCE_CFG, VFE_MAX, VFE_MAX},
+	{VFE_CMD_SK_ENHAN_CFG, VFE_MAX, VFE_MAX},
+	{VFE_CMD_ASF_CFG, VFE_ADAPTIVE_FILTER_CONFIG, QDSP_CMDQUEUE,
+		"VFE_CMD_ASF_CFG", "VFE_ADAPTIVE_FILTER_CONFIG"},
+	{VFE_CMD_S2Y_CFG, VFE_MAX, VFE_MAX},
+	{VFE_CMD_S2CbCr_CFG, VFE_MAX, VFE_MAX},
+	{VFE_CMD_CHROMA_SUBS_CFG, VFE_CHROMA_SUBSAMPLE_CONFIG, QDSP_CMDQUEUE,
+		"VFE_CMD_CHROMA_SUBS_CFG", "VFE_CHROMA_SUBSAMPLE_CONFIG"},
+	{VFE_CMD_OUT_CLAMP_CFG, VFE_OUTPUT_CLAMP_CONFIG, QDSP_CMDQUEUE,
+		"VFE_CMD_OUT_CLAMP_CFG", "VFE_OUTPUT_CLAMP_CONFIG"},
+	{VFE_CMD_FRAME_SKIP_CFG, VFE_FRAME_SKIP_CONFIG, QDSP_CMDQUEUE,
+		"VFE_CMD_FRAME_SKIP_CFG", "VFE_FRAME_SKIP_CONFIG"},
+	{VFE_CMD_DUMMY_1, VFE_MAX, VFE_MAX},
+	{VFE_CMD_DUMMY_2, VFE_MAX, VFE_MAX},
+	{VFE_CMD_DUMMY_3, VFE_MAX, VFE_MAX},
+	{VFE_CMD_UPDATE, VFE_UPDATE, QDSP_CMDQUEUE,
+		"VFE_CMD_UPDATE", "VFE_UPDATE"},
+	{VFE_CMD_BL_LVL_UPDATE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_DEMUX_UPDATE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_FOV_UPDATE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_MAIN_SCALER_UPDATE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_WB_UPDATE, VFE_WHITE_BALANCE_CONFIG, QDSP_CMDQUEUE,
+		"VFE_CMD_WB_UPDATE", "VFE_WHITE_BALANCE_CONFIG"},
+	{VFE_CMD_COLOR_COR_UPDATE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_RGB_G_UPDATE, VFE_RGB_GAMMA_CONFIG, QDSP_TABLEQUEUE,
+		"VFE_CMD_RGB_G_UPDATE", "VFE_RGB_GAMMA_CONFIG"},
+	{VFE_CMD_LA_UPDATE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_CHROMA_EN_UPDATE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_CHROMA_SUP_UPDATE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_MCE_UPDATE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_SK_ENHAN_UPDATE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_S2CbCr_UPDATE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_S2Y_UPDATE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_ASF_UPDATE, VFE_ADAPTIVE_FILTER_CONFIG, QDSP_CMDQUEUE,
+		"VFE_CMD_ASF_UPDATE", "VFE_ADAPTIVE_FILTER_CONFIG"},
+	{VFE_CMD_FRAME_SKIP_UPDATE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_CAMIF_FRAME_UPDATE, VFE_UPDATE_CAMIF_FRAME_CONFIG,
+		QDSP_CMDQUEUE, "VFE_CMD_CAMIF_FRAME_UPDATE",
+		"VFE_UPDATE_CAMIF_FRAME_CONFIG"},
+	{VFE_CMD_STATS_AF_UPDATE, VFE_STATS_AUTOFOCUS_UPDATE, QDSP_CMDQUEUE,
+		"VFE_CMD_STATS_AF_UPDATE", "VFE_STATS_AUTOFOCUS_UPDATE"},
+	{VFE_CMD_STATS_AE_UPDATE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_STATS_AWB_UPDATE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_STATS_RS_UPDATE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_STATS_CS_UPDATE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_STATS_SKIN_UPDATE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_STATS_IHIST_UPDATE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_DUMMY_4, VFE_MAX, VFE_MAX},
+	{VFE_CMD_EPOCH1_ACK, VFE_EPOCH1_ACK, QDSP_CMDQUEUE,
+			"VFE_CMD_EPOCH1_ACK", "VFE_EPOCH1_ACK"},
+	{VFE_CMD_EPOCH2_ACK, VFE_EPOCH2_ACK, QDSP_CMDQUEUE,
+			"VFE_CMD_EPOCH2_ACK", "VFE_EPOCH2_ACK"},
+	{VFE_CMD_START_RECORDING, VFE_MAX, VFE_MAX},
+	{VFE_CMD_STOP_RECORDING, VFE_MAX , VFE_MAX},
+	{VFE_CMD_DUMMY_5, VFE_MAX, VFE_MAX},
+	{VFE_CMD_DUMMY_6, VFE_MAX, VFE_MAX},
+	{VFE_CMD_CAPTURE, VFE_START, QDSP_CMDQUEUE,
+			"VFE_CMD_CAPTURE", "VFE_START"},
+	{VFE_CMD_DUMMY_7, VFE_MAX, VFE_MAX},
+	{VFE_CMD_STOP, VFE_STOP, QDSP_CMDQUEUE, "VFE_CMD_STOP", "VFE_STOP"},
+	{VFE_CMD_GET_HW_VERSION, VFE_MAX, VFE_MAX},
+	{VFE_CMD_GET_FRAME_SKIP_COUNTS, VFE_MAX, VFE_MAX},
+	{VFE_CMD_OUTPUT1_BUFFER_ENQ, VFE_MAX, VFE_MAX},
+	{VFE_CMD_OUTPUT2_BUFFER_ENQ, VFE_MAX, VFE_MAX},
+	{VFE_CMD_OUTPUT3_BUFFER_ENQ, VFE_MAX, VFE_MAX},
+	{VFE_CMD_JPEG_OUT_BUF_ENQ, VFE_MAX, VFE_MAX},
+	{VFE_CMD_RAW_OUT_BUF_ENQ, VFE_MAX, VFE_MAX},
+	{VFE_CMD_RAW_IN_BUF_ENQ, VFE_MAX, VFE_MAX},
+	{VFE_CMD_STATS_AF_ENQ, VFE_MAX, VFE_MAX},
+	{VFE_CMD_STATS_AE_ENQ, VFE_MAX, VFE_MAX},
+	{VFE_CMD_STATS_AWB_ENQ, VFE_MAX, VFE_MAX},
+	{VFE_CMD_STATS_RS_ENQ, VFE_MAX, VFE_MAX},
+	{VFE_CMD_STATS_CS_ENQ, VFE_MAX, VFE_MAX},
+	{VFE_CMD_STATS_SKIN_ENQ, VFE_MAX, VFE_MAX},
+	{VFE_CMD_STATS_IHIST_ENQ, VFE_MAX, VFE_MAX},
+	{VFE_CMD_DUMMY_8, VFE_MAX, VFE_MAX},
+	{VFE_CMD_JPEG_ENC_CFG, VFE_MAX, VFE_MAX},
+	{VFE_CMD_DUMMY_9, VFE_MAX, VFE_MAX},
+	{VFE_CMD_STATS_AF_START, VFE_STATS_AUTOFOCUS_CONFIG, QDSP_CMDQUEUE,
+		"VFE_CMD_STATS_AF_START", "VFE_STATS_AUTOFOCUS_CONFIG"},
+	{VFE_CMD_STATS_AF_STOP, VFE_STATS_AUTOFOCUS_CONFIG, QDSP_CMDQUEUE,
+		"VFE_CMD_STATS_AF_STOP", "VFE_STATS_AUTOFOCUS_CONFIG"},
+	{VFE_CMD_STATS_AE_START, VFE_MAX, VFE_MAX},
+	{VFE_CMD_STATS_AE_STOP, VFE_MAX, VFE_MAX},
+	{VFE_CMD_STATS_AWB_START, VFE_MAX, VFE_MAX},
+	{VFE_CMD_STATS_AWB_STOP, VFE_MAX, VFE_MAX},
+	{VFE_CMD_STATS_RS_START, VFE_MAX, VFE_MAX},
+	{VFE_CMD_STATS_RS_STOP, VFE_MAX, VFE_MAX},
+	{VFE_CMD_STATS_CS_START, VFE_MAX, VFE_MAX},
+	{VFE_CMD_STATS_CS_STOP, VFE_MAX, VFE_MAX},
+	{VFE_CMD_STATS_SKIN_START, VFE_MAX, VFE_MAX},
+	{VFE_CMD_STATS_SKIN_STOP, VFE_MAX, VFE_MAX},
+	{VFE_CMD_STATS_IHIST_START, VFE_STATS_HISTOGRAM_CONFIG, QDSP_CMDQUEUE,
+		"VFE_CMD_STATS_IHIST_START", "VFE_STATS_HISTOGRAM_CONFIG"},
+	{VFE_CMD_STATS_IHIST_STOP, VFE_MAX, VFE_MAX},
+	{VFE_CMD_DUMMY_10, VFE_MAX, VFE_MAX},
+	{VFE_CMD_SYNC_TIMER_SETTING, VFE_MAX, VFE_MAX},
+	{VFE_CMD_ASYNC_TIMER_SETTING, VFE_MAX, VFE_MAX},
+	{VFE_CMD_LIVESHOT, VFE_MAX, VFE_MAX},
+	{VFE_CMD_LA_SETUP, VFE_MAX, VFE_MAX},
+	{VFE_CMD_LINEARIZATION_CFG, VFE_MAX, VFE_MAX},
+	{VFE_CMD_DEMOSAICV3, VFE_DEMOSAICv3_CFG, QDSP_TABLEQUEUE,
+		"VFE_CMD_DEMOSAICV3", "VFE_DEMOSAICv3_CFG"},
+	{VFE_CMD_DEMOSAICV3_ABCC_CFG, VFE_MAX, VFE_MAX},
+	{VFE_CMD_DEMOSAICV3_DBCC_CFG, VFE_MAX, VFE_MAX},
+	{VFE_CMD_DEMOSAICV3_DBPC_CFG, VFE_DEMOSAICv3_BPC_CFG, QDSP_TABLEQUEUE,
+		"VFE_CMD_DEMOSAICV3_DBPC_CFG", "VFE_DEMOSAICv3_BPC_CFG"},
+	{VFE_CMD_DEMOSAICV3_ABF_CFG, VFE_DEMOSAICv3_ABF_CFG, QDSP_TABLEQUEUE,
+		"VFE_CMD_DEMOSAICV3_ABF_CFG", "VFE_DEMOSAICv3_ABF_CFG"},
+	{VFE_CMD_DEMOSAICV3_ABCC_UPDATE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_DEMOSAICV3_DBCC_UPDATE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_DEMOSAICV3_DBPC_UPDATE, VFE_DEMOSAICv3_BPC_UPDATE,
+		QDSP_CMDQUEUE, "VFE_CMD_DEMOSAICV3_DBPC_UPDATE",
+		"VFE_DEMOSAICv3_BPC_UPDATE"},
+	{VFE_CMD_XBAR_CFG, VFE_MAX, VFE_MAX},
+	{VFE_CMD_MODULE_CFG, VFE_MAX, VFE_MAX},
+	{VFE_CMD_ZSL, VFE_START, QDSP_CMDQUEUE,
+			"VFE_CMD_ZSL", "VFE_START"},
+	{VFE_CMD_LINEARIZATION_UPDATE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_DEMOSAICV3_ABF_UPDATE, VFE_DEMOSAICv3_ABF_CFG,
+		QDSP_TABLEQUEUE, "VFE_CMD_DEMOSAICV3_ABF_UPDATE",
+		"VFE_DEMOSAICv3_ABF_CFG"},
+	{VFE_CMD_CLF_CFG, VFE_MAX, VFE_MAX},
+	{VFE_CMD_CLF_LUMA_UPDATE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_CLF_CHROMA_UPDATE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_PCA_ROLL_OFF_CFG, VFE_MAX, VFE_MAX},
+	{VFE_CMD_PCA_ROLL_OFF_UPDATE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_GET_REG_DUMP, VFE_MAX, VFE_MAX},
+	{VFE_CMD_GET_LINEARIZATON_TABLE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_GET_MESH_ROLLOFF_TABLE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_GET_PCA_ROLLOFF_TABLE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_GET_RGB_G_TABLE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_GET_LA_TABLE, VFE_MAX, VFE_MAX},
+	{VFE_CMD_DEMOSAICV3_UPDATE, VFE_DEMOSAICv3_CFG, QDSP_TABLEQUEUE,
+		"VFE_CMD_DEMOSAICV3_UPDATE", "VFE_DEMOSAICv3_CFG"},
+	{VFE_CMD_ACTIVE_REGION_CFG, VFE_ACTIVE_REGION_CONFIG, QDSP_CMDQUEUE,
+		"VFE_CMD_ACTIVE_REGION_CFG", "VFE_ACTIVE_REGION_CONFIG"},
+	{VFE_CMD_COLOR_PROCESSING_CONFIG, VFE_COLOR_PROCESSING_CONFIG,
+		QDSP_CMDQUEUE, "VFE_CMD_COLOR_PROCESSING_CONFIG",
+		"VFE_COLOR_PROCESSING_CONFIG"},
+	{VFE_CMD_STATS_WB_AEC_CONFIG, VFE_STATS_WB_EXP_CONFIG, QDSP_CMDQUEUE,
+		"VFE_CMD_STATS_WB_AEC_CONFIG", "VFE_STATS_WB_EXP_CONFIG"},
+	{VFE_CMD_STATS_WB_AEC_UPDATE, VFE_STATS_WB_EXP_UPDATE, QDSP_CMDQUEUE,
+		"VFE_CMD_STATS_WB_AEC_UPDATE", "VFE_STATS_WB_EXP_UPDATE"},
+	{VFE_CMD_Y_GAMMA_CONFIG, VFE_Y_GAMMA_CONFIG, QDSP_TABLEQUEUE,
+		"VFE_CMD_Y_GAMMA_CONFIG", "VFE_Y_GAMMA_CONFIG"},
+	{VFE_CMD_SCALE_OUTPUT1_CONFIG, VFE_SCALE_OUTPUT1_CONFIG,
+		QDSP_SCALEQUEUE, "VFE_CMD_SCALE_OUTPUT1_CONFIG",
+		"VFE_SCALE_OUTPUT1_CONFIG"},
+	{VFE_CMD_SCALE_OUTPUT2_CONFIG, VFE_SCALE_OUTPUT2_CONFIG,
+		QDSP_SCALEQUEUE, "VFE_CMD_SCALE_OUTPUT2_CONFIG",
+		"VFE_SCALE_OUTPUT2_CONFIG"},
+	{VFE_CMD_CAPTURE_RAW, VFE_START, QDSP_CMDQUEUE,
+			"VFE_CMD_CAPTURE_RAW", "VFE_START"},
+	{VFE_CMD_STOP_LIVESHOT, VFE_MAX, VFE_MAX},
+	{VFE_CMD_RECONFIG_VFE, VFE_MAX, VFE_MAX},
+};
+
+
+static struct msm_adsp_module *qcam_mod;
+static struct msm_adsp_module *vfe_mod;
+static void *extdata;
+static uint32_t extlen;
+
+struct mutex vfe_lock;
+static uint8_t vfestopped;
+
+static struct stop_event stopevent;
+
+static uint32_t op_mode;
+static uint32_t raw_mode;
+static struct vfe2x_ctrl_type *vfe2x_ctrl;
+
+static unsigned long vfe2x_stats_dqbuf(enum msm_stats_enum_type stats_type)
+{
+	struct msm_stats_meta_buf *buf = NULL;
+	int rc = 0;
+
+	rc = vfe2x_ctrl->stats_ops.dqbuf(vfe2x_ctrl->stats_ops.stats_ctrl,
+							  stats_type, &buf);
+	if (rc < 0) {
+		CDBG("%s: dq stats buf (type = %d) err = %d",
+			   __func__, stats_type, rc);
+		return 0;
+	}
+	return buf->paddr;
+}
+
+static unsigned long vfe2x_stats_flush_enqueue(
+	enum msm_stats_enum_type stats_type)
+{
+	struct msm_stats_bufq *bufq = NULL;
+	struct msm_stats_meta_buf *stats_buf = NULL;
+	int rc = 0;
+	int i;
+
+	/*
+	 * Passing NULL for ion client as the buffers are already
+	 * mapped at this stage, client is not required, flush all
+	 * the buffers, and buffers move to PREPARE state
+	 */
+	rc = vfe2x_ctrl->stats_ops.bufq_flush(
+			vfe2x_ctrl->stats_ops.stats_ctrl,
+			stats_type, NULL);
+	if (rc < 0) {
+		pr_err("%s: dq stats buf (type = %d) err = %d",
+			 __func__, stats_type, rc);
+		return 0L;
+	}
+
+	/* Queue all the buffers back to QUEUED state */
+	bufq = vfe2x_ctrl->stats_ctrl.bufq[stats_type];
+	for (i = 0; i < bufq->num_bufs; i++) {
+		stats_buf = &bufq->bufs[i];
+		rc = vfe2x_ctrl->stats_ops.enqueue_buf(
+				vfe2x_ctrl->stats_ops.stats_ctrl,
+				&(stats_buf->info), NULL, -1);
+			if (rc < 0) {
+				pr_err("%s: dq stats buf (type = %d) err = %d",
+					 __func__, stats_type, rc);
+				return rc;
+			}
+	}
+	return 0L;
+}
+
+static unsigned long vfe2x_stats_unregbuf(
+	struct msm_stats_reqbuf *req_buf)
+{
+	int i = 0, rc = 0;
+
+	for (i = 0; i < req_buf->num_buf; i++) {
+		rc = vfe2x_ctrl->stats_ops.buf_unprepare(
+			vfe2x_ctrl->stats_ops.stats_ctrl,
+			req_buf->stats_type, i,
+			vfe2x_ctrl->stats_ops.client, -1);
+		if (rc < 0) {
+			pr_err("%s: unreg stats buf (type = %d) err = %d",
+				__func__, req_buf->stats_type, rc);
+		return rc;
+		}
+	}
+	return 0L;
+}
+
+static int vfe2x_stats_buf_init(enum msm_stats_enum_type type)
+{
+	unsigned long flags;
+	int i = 0, rc = 0;
+	if (type == MSM_STATS_TYPE_AF) {
+		spin_lock_irqsave(&vfe2x_ctrl->stats_bufq_lock, flags);
+		rc = vfe2x_stats_flush_enqueue(MSM_STATS_TYPE_AF);
+		if (rc < 0) {
+			pr_err("%s: dq stats buf err = %d",
+				 __func__, rc);
+			spin_unlock_irqrestore(&vfe2x_ctrl->stats_bufq_lock,
+				flags);
+			return -EINVAL;
+		}
+		spin_unlock_irqrestore(&vfe2x_ctrl->stats_bufq_lock, flags);
+	}
+	for (i = 0; i < 3; i++) {
+		spin_lock_irqsave(&vfe2x_ctrl->stats_bufq_lock, flags);
+		if (type == MSM_STATS_TYPE_AE_AW)
+			vfe2x_ctrl->stats_we_buf_ptr[i] =
+				vfe2x_stats_dqbuf(type);
+		else
+			vfe2x_ctrl->stats_af_buf_ptr[i] =
+				vfe2x_stats_dqbuf(type);
+		spin_unlock_irqrestore(&vfe2x_ctrl->stats_bufq_lock, flags);
+		if (!vfe2x_ctrl->stats_we_buf_ptr[i]) {
+			pr_err("%s: dq error type %d ", __func__, type);
+			return -ENOMEM;
+		}
+	}
+	return rc;
+}
+
+static unsigned long vfe2x_stats_enqueuebuf(
+	struct msm_stats_buf_info *info, struct vfe_stats_ack *sack)
+{
+	struct msm_stats_bufq *bufq = NULL;
+	struct msm_stats_meta_buf *stats_buf = NULL;
+	struct msm_stats_meta_buf *buf = NULL;
+	int rc = 0;
+
+	bufq = vfe2x_ctrl->stats_ctrl.bufq[info->type];
+	stats_buf = &bufq->bufs[info->buf_idx];
+
+	CDBG("vfe2x_stats_enqueuebuf: %d\n", stats_buf->state);
+	if (stats_buf->state == MSM_STATS_BUFFER_STATE_INITIALIZED ||
+		stats_buf->state == MSM_STATS_BUFFER_STATE_PREPARED) {
+		rc = vfe2x_ctrl->stats_ops.enqueue_buf(
+				&vfe2x_ctrl->stats_ctrl,
+				info, vfe2x_ctrl->stats_ops.client, -1);
+		if (rc < 0) {
+			pr_err("%s: enqueue_buf (type = %d), index : %d, err = %d",
+				 __func__, info->type, info->buf_idx, rc);
+			return rc;
+		}
+
+	} else {
+		rc = vfe2x_ctrl->stats_ops.querybuf(
+				vfe2x_ctrl->stats_ops.stats_ctrl, info, &buf);
+		if (rc < 0) {
+			pr_err("%s: querybuf (type = %d), index : %d, err = %d",
+				__func__, info->type, info->buf_idx, rc);
+			return rc;
+	}
+		stats_buf->state = MSM_STATS_BUFFER_STATE_DEQUEUED;
+	if (info->type == MSM_STATS_TYPE_AE_AW) {
+		sack->header = VFE_STATS_WB_EXP_ACK;
+		sack->bufaddr = (void *)(uint32_t *)buf->paddr;
+	} else if (info->type == MSM_STATS_TYPE_AF) {
+		sack->header = VFE_STATS_AUTOFOCUS_ACK;
+		sack->bufaddr = (void *)(uint32_t *)buf->paddr;
+	} else
+		pr_err("%s: Invalid stats: should never come here\n", __func__);
+	}
+	return 0L;
+}
+
+static long vfe2x_stats_bufq_sub_ioctl(struct msm_vfe_cfg_cmd *cmd,
+	void *ion_client)
+{
+	long rc = 0;
+
+	switch (cmd->cmd_type) {
+	case VFE_CMD_STATS_REQBUF:
+		if (!vfe2x_ctrl->stats_ops.stats_ctrl) {
+			/* stats_ctrl has not been init yet */
+			rc = msm_stats_buf_ops_init(
+					&vfe2x_ctrl->stats_ctrl,
+					(struct ion_client *)ion_client,
+					&vfe2x_ctrl->stats_ops);
+			if (rc < 0) {
+				pr_err("%s: cannot init stats ops", __func__);
+				goto end;
+			}
+			rc = vfe2x_ctrl->stats_ops.stats_ctrl_init(
+					&vfe2x_ctrl->stats_ctrl);
+			if (rc < 0) {
+				pr_err("%s: cannot init stats_ctrl ops",
+					 __func__);
+				memset(&vfe2x_ctrl->stats_ops, 0,
+				sizeof(vfe2x_ctrl->stats_ops));
+				goto end;
+			}
+			if (sizeof(struct msm_stats_reqbuf) != cmd->length) {
+				/* error. the length not match */
+				pr_err("%s: stats reqbuf input size = %d,\n"
+					"struct size = %d, mismatch\n",
+					__func__, cmd->length,
+					sizeof(struct msm_stats_reqbuf));
+				rc = -EINVAL;
+				goto end;
+			}
+		}
+		rc = vfe2x_ctrl->stats_ops.reqbuf(
+				&vfe2x_ctrl->stats_ctrl,
+				(struct msm_stats_reqbuf *)cmd->value,
+				vfe2x_ctrl->stats_ops.client);
+		break;
+		case VFE_CMD_STATS_ENQUEUEBUF: {
+			if (sizeof(struct msm_stats_buf_info) != cmd->length) {
+				/* error. the length not match */
+				pr_err("%s: stats enqueuebuf input size = %d,\n"
+					"struct size = %d, mismatch\n",
+					 __func__, cmd->length,
+					sizeof(struct msm_stats_buf_info));
+				rc = -EINVAL;
+				goto end;
+		}
+		rc = vfe2x_ctrl->stats_ops.enqueue_buf(
+				&vfe2x_ctrl->stats_ctrl,
+				(struct msm_stats_buf_info *)cmd->value,
+				vfe2x_ctrl->stats_ops.client, -1);
+	}
+	break;
+	case VFE_CMD_STATS_FLUSH_BUFQ: {
+		struct msm_stats_flush_bufq *flush_req = NULL;
+		flush_req = (struct msm_stats_flush_bufq *)cmd->value;
+		if (sizeof(struct msm_stats_flush_bufq) != cmd->length) {
+			/* error. the length not match */
+			pr_err("%s: stats flush queue input size = %d,\n"
+				"struct size = %d, mismatch\n",
+				__func__, cmd->length,
+				sizeof(struct msm_stats_flush_bufq));
+				rc = -EINVAL;
+				goto end;
+		}
+		rc = vfe2x_ctrl->stats_ops.bufq_flush(
+				&vfe2x_ctrl->stats_ctrl,
+				(enum msm_stats_enum_type)flush_req->stats_type,
+				vfe2x_ctrl->stats_ops.client);
+	}
+	break;
+	case VFE_CMD_STATS_UNREGBUF:
+	{
+		struct msm_stats_reqbuf *req_buf = NULL;
+		req_buf = (struct msm_stats_reqbuf *)cmd->value;
+		if (sizeof(struct msm_stats_reqbuf) != cmd->length) {
+			/* error. the length not match */
+			pr_err("%s: stats reqbuf input size = %d,\n"
+				"struct size = %d, mitch match\n",
+				 __func__, cmd->length,
+				sizeof(struct msm_stats_reqbuf));
+			rc = -EINVAL ;
+			goto end;
+		}
+		rc = vfe2x_stats_unregbuf(req_buf);
+	}
+	break;
+	default:
+		rc = -1;
+		pr_err("%s: cmd_type %d not supported",
+			 __func__, cmd->cmd_type);
+	break;
+	}
+end:
+	return rc;
+}
+
+static void vfe2x_send_isp_msg(
+	struct vfe2x_ctrl_type *vctrl,
+	uint32_t isp_msg_id)
+{
+	struct isp_msg_event isp_msg_evt;
+
+	isp_msg_evt.msg_id = isp_msg_id;
+	isp_msg_evt.sof_count = vfe2x_ctrl->vfeFrameId;
+	v4l2_subdev_notify(&vctrl->subdev,
+			NOTIFY_ISP_MSG_EVT,
+			(void *)&isp_msg_evt);
+}
+
+static void vfe_send_outmsg(struct v4l2_subdev *sd, uint8_t msgid,
+		uint32_t ch0_paddr, uint32_t ch1_paddr)
+{
+	struct isp_msg_output msg;
+
+	msg.output_id = msgid;
+	msg.buf.inst_handle = 0;
+	msg.buf.ch_paddr[0]     = ch0_paddr;
+	msg.buf.ch_paddr[1]     = ch1_paddr;
+	msg.frameCounter = vfe2x_ctrl->vfeFrameId;
+
+	v4l2_subdev_notify(&vfe2x_ctrl->subdev,
+			NOTIFY_VFE_MSG_OUT,
+			&msg);
+	return;
+}
+
+static void vfe_send_stats_msg(uint32_t buf_addr, uint32_t msg_id)
+{
+	struct isp_msg_stats msg_stats;
+	void *vaddr = NULL;
+	int rc;
+
+	msg_stats.frameCounter = vfe2x_ctrl->vfeFrameId;
+	msg_stats.buffer       = buf_addr;
+	msg_stats.id           = msg_id;
+
+	if (MSG_ID_STATS_AWB_AEC == msg_id)
+		rc = vfe2x_ctrl->stats_ops.dispatch(
+			vfe2x_ctrl->stats_ops.stats_ctrl,
+			MSM_STATS_TYPE_AE_AW, buf_addr,
+			&msg_stats.buf_idx, &vaddr, &msg_stats.fd,
+			vfe2x_ctrl->stats_ops.client);
+	else if (MSG_ID_STATS_AF == msg_id)
+		rc = vfe2x_ctrl->stats_ops.dispatch(
+			vfe2x_ctrl->stats_ops.stats_ctrl,
+			MSM_STATS_TYPE_AF, buf_addr,
+			&msg_stats.buf_idx, &vaddr, &msg_stats.fd,
+			vfe2x_ctrl->stats_ops.client);
+
+	v4l2_subdev_notify(&vfe2x_ctrl->subdev,
+				NOTIFY_VFE_MSG_STATS,
+				&msg_stats);
+}
+
+static void vfe_7x_ops(void *driver_data, unsigned id, size_t len,
+		void (*getevent)(void *ptr, size_t len))
+{
+	uint32_t evt_buf[3];
+	void *data = NULL;
+	struct buf_info *outch = NULL;
+	uint32_t y_phy, cbcr_phy;
+	static uint32_t liveshot_y_phy;
+	static struct vfe_endframe liveshot_swap;
+	struct table_cmd *table_pending = NULL;
+	unsigned long flags;
+	void   *cmd_data = NULL;
+	unsigned char buf[256];
+	struct msm_free_buf *free_buf = NULL;
+	struct vfe_outputack fack;
+	int i;
+
+	CDBG("%s:id=%d\n", __func__, id);
+	if (id != VFE_ADSP_EVENT) {
+		data = kzalloc(len, GFP_ATOMIC);
+		if (!data) {
+			pr_err("%s: rp: cannot allocate buffer\n", __func__);
+			return;
+		}
+	}
+	if (id == VFE_ADSP_EVENT) {
+		/* event */
+		getevent(evt_buf, sizeof(evt_buf));
+		CDBG("%s:event:msg_id=%d\n", __func__, id);
+	} else {
+		/* messages */
+		getevent(data, len);
+		CDBG("%s:messages:msg_id=%d\n", __func__, id);
+
+		switch (id) {
+		case MSG_SNAPSHOT:
+			while (vfe2x_ctrl->snap.frame_cnt <
+				vfe2x_ctrl->num_snap) {
+				vfe_7x_ops(driver_data, MSG_OUTPUT_S, len,
+					getevent);
+				if (!raw_mode)
+					vfe_7x_ops(driver_data, MSG_OUTPUT_T,
+						len, getevent);
+			}
+			vfe2x_send_isp_msg(vfe2x_ctrl, MSG_ID_SNAPSHOT_DONE);
+			kfree(data);
+			return;
+		case MSG_OUTPUT_S:
+			outch = &vfe2x_ctrl->snap;
+			if (outch->frame_cnt == 0) {
+				y_phy = outch->ping.ch_paddr[0];
+				cbcr_phy = outch->ping.ch_paddr[1];
+			} else if (outch->frame_cnt == 1) {
+				y_phy = outch->pong.ch_paddr[0];
+				cbcr_phy = outch->pong.ch_paddr[1];
+			} else if (outch->frame_cnt == 2) {
+				y_phy = outch->free_buf.ch_paddr[0];
+				cbcr_phy = outch->free_buf.ch_paddr[1];
+			} else {
+				y_phy = outch->free_buf_arr[outch->frame_cnt
+					- 3].ch_paddr[0];
+				cbcr_phy = outch->free_buf_arr[outch->frame_cnt
+					- 3].ch_paddr[1];
+			}
+			outch->frame_cnt++;
+			CDBG("MSG_OUTPUT_S: %x %x %d\n",
+				(unsigned int)y_phy, (unsigned int)cbcr_phy,
+					outch->frame_cnt);
+			vfe_send_outmsg(&vfe2x_ctrl->subdev,
+					MSG_ID_OUTPUT_PRIMARY,
+						y_phy, cbcr_phy);
+			break;
+		case MSG_OUTPUT_T:
+			outch = &vfe2x_ctrl->thumb;
+			if (outch->frame_cnt == 0) {
+				y_phy = outch->ping.ch_paddr[0];
+				cbcr_phy = outch->ping.ch_paddr[1];
+			} else if (outch->frame_cnt == 1) {
+				y_phy = outch->pong.ch_paddr[0];
+				cbcr_phy = outch->pong.ch_paddr[1];
+			} else if (outch->frame_cnt == 2) {
+				y_phy = outch->free_buf.ch_paddr[0];
+				cbcr_phy = outch->free_buf.ch_paddr[1];
+			} else {
+				y_phy = outch->free_buf_arr[outch->frame_cnt
+					- 3].ch_paddr[0];
+				cbcr_phy = outch->free_buf_arr[outch->frame_cnt
+					- 3].ch_paddr[1];
+			}
+			outch->frame_cnt++;
+			CDBG("MSG_OUTPUT_T: %x %x %d\n",
+				(unsigned int)y_phy, (unsigned int)cbcr_phy,
+				outch->frame_cnt);
+			vfe_send_outmsg(&vfe2x_ctrl->subdev,
+						MSG_ID_OUTPUT_SECONDARY,
+							y_phy, cbcr_phy);
+			break;
+		case MSG_OUTPUT1:
+			if (op_mode & SNAPSHOT_MASK_MODE) {
+				kfree(data);
+				return;
+			} else {
+				free_buf = vfe2x_check_free_buffer(
+							VFE_MSG_OUTPUT_IRQ,
+							VFE_MSG_OUTPUT_SECONDARY
+							);
+				CDBG("free_buf = %x\n",
+						(unsigned int) free_buf);
+				if (free_buf) {
+					fack.header = VFE_OUTPUT1_ACK;
+
+					fack.output2newybufferaddress =
+						(void *)(free_buf->ch_paddr[0]);
+
+					fack.output2newcbcrbufferaddress =
+						(void *)(free_buf->ch_paddr[1]);
+
+					cmd_data = &fack;
+					len = sizeof(fack);
+					msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
+							cmd_data, len);
+			      } else {
+					fack.header = VFE_OUTPUT1_ACK;
+					fack.output2newybufferaddress =
+					(void *)
+				((struct vfe_endframe *)data)->y_address;
+					fack.output2newcbcrbufferaddress =
+					(void *)
+				((struct vfe_endframe *)data)->cbcr_address;
+					cmd_data = &fack;
+					len = sizeof(fack);
+					msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
+						cmd_data, len);
+					if (!vfe2x_ctrl->zsl_mode) {
+						kfree(data);
+						return;
+					}
+				}
+			}
+			y_phy = ((struct vfe_endframe *)data)->y_address;
+			cbcr_phy = ((struct vfe_endframe *)data)->cbcr_address;
+
+
+			CDBG("vfe_7x_convert, y_phy = 0x%x, cbcr_phy = 0x%x\n",
+				 y_phy, cbcr_phy);
+			if (free_buf) {
+				for (i = 0; i < 3; i++) {
+					if (vfe2x_ctrl->free_buf.buf[i].
+							ch_paddr[0] == y_phy) {
+						vfe2x_ctrl->free_buf.
+							buf[i].ch_paddr[0] =
+							free_buf->ch_paddr[0];
+						vfe2x_ctrl->free_buf.
+							buf[i].ch_paddr[1] =
+							free_buf->ch_paddr[1];
+						break;
+					}
+				}
+				if (i == 3)
+					CDBG("Address doesnt match\n");
+			}
+			memcpy(((struct vfe_frame_extra *)extdata),
+				&((struct vfe_endframe *)data)->extra,
+				sizeof(struct vfe_frame_extra));
+
+			vfe2x_ctrl->vfeFrameId =
+				((struct vfe_frame_extra *)extdata)->frame_id;
+			vfe_send_outmsg(&vfe2x_ctrl->subdev,
+						MSG_ID_OUTPUT_SECONDARY,
+						y_phy, cbcr_phy);
+			break;
+		case MSG_OUTPUT2:
+			if (op_mode & SNAPSHOT_MASK_MODE) {
+				kfree(data);
+				return;
+			}
+			if (vfe2x_ctrl->liveshot_enabled)
+				free_buf = vfe2x_check_free_buffer(
+					VFE_MSG_OUTPUT_IRQ,
+					VFE_MSG_V2X_LIVESHOT_PRIMARY);
+			else
+				free_buf = vfe2x_check_free_buffer(
+					VFE_MSG_OUTPUT_IRQ,
+					VFE_MSG_OUTPUT_PRIMARY);
+			CDBG("free_buf = %x\n",
+					(unsigned int) free_buf);
+			spin_lock_irqsave(
+					&vfe2x_ctrl->liveshot_enabled_lock,
+					flags);
+			if (!vfe2x_ctrl->liveshot_enabled) {
+				spin_unlock_irqrestore(
+						&vfe2x_ctrl->
+						liveshot_enabled_lock,
+						flags);
+				if (free_buf) {
+					fack.header = VFE_OUTPUT2_ACK;
+
+					fack.output2newybufferaddress =
+						(void *)
+						(free_buf->ch_paddr[0]);
+
+					fack.output2newcbcrbufferaddress =
+						(void *)
+						(free_buf->ch_paddr[1]);
+
+					cmd_data = &fack;
+					len = sizeof(fack);
+					msm_adsp_write(vfe_mod,
+							QDSP_CMDQUEUE,
+							cmd_data, len);
+				} else {
+					fack.header = VFE_OUTPUT2_ACK;
+					fack.output2newybufferaddress =
+						(void *)
+						((struct vfe_endframe *)
+						 data)->y_address;
+					fack.output2newcbcrbufferaddress =
+						(void *)
+						((struct vfe_endframe *)
+						 data)->cbcr_address;
+					cmd_data = &fack;
+					len = sizeof(fack);
+					msm_adsp_write(vfe_mod,
+							QDSP_CMDQUEUE,
+							cmd_data, len);
+					if (!vfe2x_ctrl->zsl_mode) {
+						kfree(data);
+						return;
+					}
+				}
+			} else { /* Live snapshot */
+				spin_unlock_irqrestore(
+						&vfe2x_ctrl->
+						liveshot_enabled_lock,
+						flags);
+				if (free_buf) {
+					/* liveshot_swap to enqueue
+					   when liveshot snapshot buffer
+					   is obtainedi from adsp */
+					liveshot_swap.y_address =
+						((struct vfe_endframe *)
+						 data)->y_address;
+					liveshot_swap.cbcr_address =
+						((struct vfe_endframe *)
+						 data)->cbcr_address;
+
+					fack.header = VFE_OUTPUT2_ACK;
+
+					fack.output2newybufferaddress =
+						(void *)
+						(free_buf->ch_paddr[0]);
+
+					fack.output2newcbcrbufferaddress =
+						(void *)
+						(free_buf->ch_paddr[1]);
+
+					liveshot_y_phy =
+						(uint32_t)
+						fack.output2newybufferaddress;
+
+					cmd_data = &fack;
+					len = sizeof(fack);
+					msm_adsp_write(vfe_mod,
+							QDSP_CMDQUEUE,
+							cmd_data, len);
+				} else if (liveshot_y_phy !=
+						((struct vfe_endframe *)
+						 data)->y_address) {
+
+					fack.header = VFE_OUTPUT2_ACK;
+					fack.output2newybufferaddress =
+						(void *)
+						((struct vfe_endframe *)
+						 data)->y_address;
+
+					fack.output2newcbcrbufferaddress =
+						(void *)
+						((struct vfe_endframe *)
+						 data)->cbcr_address;
+
+					cmd_data = &fack;
+					len = sizeof(fack);
+					msm_adsp_write(vfe_mod,
+							QDSP_CMDQUEUE,
+							cmd_data, len);
+					kfree(data);
+					return;
+				} else {
+					/* Enque data got
+					 * during freebuf */
+					fack.header = VFE_OUTPUT2_ACK;
+					fack.output2newybufferaddress =
+						(void *)
+						(liveshot_swap.y_address);
+
+					fack.output2newcbcrbufferaddress =
+						(void *)
+						(liveshot_swap.cbcr_address);
+					cmd_data = &fack;
+					len = sizeof(fack);
+					msm_adsp_write(vfe_mod,
+							QDSP_CMDQUEUE,
+							cmd_data, len);
+				}
+			}
+			y_phy = ((struct vfe_endframe *)data)->
+				y_address;
+			cbcr_phy = ((struct vfe_endframe *)data)->
+				cbcr_address;
+
+
+			CDBG("MSG_OUT2:y_phy= 0x%x, cbcr_phy= 0x%x\n",
+					y_phy, cbcr_phy);
+			if (free_buf) {
+				for (i = 0; i < 3; i++) {
+					if (vfe2x_ctrl->free_buf.buf[i].
+							ch_paddr[0] == y_phy) {
+						vfe2x_ctrl->free_buf.
+							buf[i].ch_paddr[0] =
+							free_buf->ch_paddr[0];
+						vfe2x_ctrl->free_buf.
+							buf[i].ch_paddr[1] =
+							free_buf->ch_paddr[1];
+						break;
+					}
+				}
+				if (i == 3)
+					CDBG("Address doesnt match\n");
+			}
+			memcpy(((struct vfe_frame_extra *)extdata),
+					&((struct vfe_endframe *)data)->extra,
+					sizeof(struct vfe_frame_extra));
+
+			vfe2x_ctrl->vfeFrameId =
+				((struct vfe_frame_extra *)extdata)->
+				frame_id;
+
+			if (!vfe2x_ctrl->liveshot_enabled) {
+				/* Liveshot not enalbed */
+				vfe_send_outmsg(&vfe2x_ctrl->subdev,
+						MSG_ID_OUTPUT_PRIMARY,
+						y_phy, cbcr_phy);
+			} else if (liveshot_y_phy == y_phy) {
+				vfe_send_outmsg(&vfe2x_ctrl->subdev,
+						MSG_ID_OUTPUT_PRIMARY,
+						y_phy, cbcr_phy);
+			}
+			break;
+		case MSG_RESET_ACK:
+		case MSG_START_ACK:
+		case MSG_UPDATE_ACK:
+		case MSG_VFE_ERROR:
+		case MSG_SYNC_TIMER1_DONE:
+		case MSG_SYNC_TIMER2_DONE:
+			vfe2x_send_isp_msg(vfe2x_ctrl, msgs_map[id].isp_id);
+			if (id == MSG_START_ACK)
+				vfe2x_ctrl->vfe_started = 1;
+			if (id == MSG_VFE_ERROR) {
+				uint16_t *ptr;
+				struct vfe_error_msg *VFE_ErrorMessageBuffer
+					= data;
+				ptr = data;
+				CDBG("Error: %x %x\n", ptr[0], ptr[1]);
+				CDBG("CAMIF_Error              = %d\n",
+					VFE_ErrorMessageBuffer->camif_error);
+				CDBG("output1YBusOverflow      = %d\n",
+					VFE_ErrorMessageBuffer->
+					output1ybusoverflow);
+				CDBG("output1CbCrBusOverflow   = %d\n",
+					VFE_ErrorMessageBuffer->
+					output1cbcrbusoverflow);
+				CDBG("output2YBusOverflow      = %d\n",
+					VFE_ErrorMessageBuffer->
+					output2ybusoverflow);
+				CDBG("output2CbCrBusOverflow   = %d\n",
+						VFE_ErrorMessageBuffer->
+						output2cbcrbusoverflow);
+				CDBG("autofocusStatBusOverflow = %d\n",
+						VFE_ErrorMessageBuffer->
+						autofocusstatbusoverflow);
+				CDBG("WB_EXPStatBusOverflow    = %d\n",
+						VFE_ErrorMessageBuffer->
+						wb_expstatbusoverflow);
+				CDBG("AXIError                 = %d\n",
+						VFE_ErrorMessageBuffer->
+						axierror);
+				CDBG("CAMIF_Staus              = %d\n",
+						VFE_ErrorMessageBuffer->
+						camif_staus);
+				CDBG("pixel_count              = %d\n",
+						VFE_ErrorMessageBuffer->
+						pixel_count);
+				CDBG("line_count               = %d\n",
+						VFE_ErrorMessageBuffer->
+						line_count);
+			}
+			break;
+		case MSG_SOF:
+			vfe2x_ctrl->vfeFrameId++;
+			if (vfe2x_ctrl->vfeFrameId == 0)
+				vfe2x_ctrl->vfeFrameId = 1; /* wrapped back */
+			if ((op_mode & SNAPSHOT_MASK_MODE) && !raw_mode
+				&& (vfe2x_ctrl->num_snap <= 1)) {
+				CDBG("Ignore SOF for snapshot\n");
+				kfree(data);
+				return;
+			}
+			vfe2x_send_isp_msg(vfe2x_ctrl, MSG_ID_SOF_ACK);
+			if (raw_mode)
+				vfe2x_send_isp_msg(vfe2x_ctrl,
+						MSG_ID_START_ACK);
+			break;
+		case MSG_STOP_ACK:
+			stopevent.state = 1;
+			vfe2x_ctrl->vfe_started = 0;
+			wake_up(&stopevent.wait);
+			vfe2x_send_isp_msg(vfe2x_ctrl, MSG_ID_STOP_ACK);
+			break;
+		case MSG_STATS_AF:
+		case MSG_STATS_WE:
+			vfe_send_stats_msg(*(uint32_t *)data,
+						msgs_map[id].isp_id);
+			break;
+		default:
+			if (MSG_TABLE_CMD_ACK != id)
+				vfe2x_send_isp_msg(vfe2x_ctrl,
+						msgs_map[id].isp_id);
+			break;
+		}
+	}
+	if (MSG_TABLE_CMD_ACK == id) {
+		spin_lock_irqsave(&vfe2x_ctrl->table_lock, flags);
+		vfe2x_ctrl->tableack_pending = 0;
+		if (list_empty(&vfe2x_ctrl->table_q)) {
+			if (vfe2x_ctrl->start_pending) {
+				CDBG("Send START\n");
+				cmd_data = buf;
+				*(uint32_t *)cmd_data = VFE_START;
+				memcpy(((char *)cmd_data) + 4,
+					&vfe2x_ctrl->start_cmd,
+					sizeof(vfe2x_ctrl->start_cmd));
+				/* Send Start cmd here */
+				len  = sizeof(vfe2x_ctrl->start_cmd) + 4;
+				msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
+						cmd_data, len);
+				vfe2x_ctrl->start_pending = 0;
+			} else if (vfe2x_ctrl->stop_pending) {
+				CDBG("Send STOP\n");
+				cmd_data = buf;
+				*(uint32_t *)cmd_data = VFE_STOP;
+				/* Send Stop cmd here */
+				len  = 4;
+				msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
+						cmd_data, len);
+				vfe2x_ctrl->stop_pending = 0;
+			} else if (vfe2x_ctrl->update_pending) {
+				CDBG("Send Update\n");
+				cmd_data = buf;
+				*(uint32_t *)cmd_data = VFE_UPDATE;
+				/* Send Update cmd here */
+				len  = 4;
+				msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
+						cmd_data, len);
+				vfe2x_ctrl->update_pending = 0;
+			}
+			spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
+			kfree(data);
+			return;
+		}
+		table_pending = list_first_entry(&vfe2x_ctrl->table_q,
+					struct table_cmd, list);
+		if (!table_pending) {
+			spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
+			kfree(data);
+			return;
+		}
+		msm_adsp_write(vfe_mod, table_pending->queue,
+				table_pending->cmd, table_pending->size);
+		list_del(&table_pending->list);
+		kfree(table_pending->cmd);
+		kfree(table_pending);
+		vfe2x_ctrl->tableack_pending = 1;
+		spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
+	} else if (!vfe2x_ctrl->tableack_pending) {
+		if (!list_empty(&vfe2x_ctrl->table_q)) {
+			kfree(data);
+			return;
+		}
+	}
+	kfree(data);
+}
+
+static struct msm_adsp_ops vfe_7x_sync = {
+	.event = vfe_7x_ops,
+};
+
+static int vfe_7x_config_axi(int mode,
+	struct buf_info *ad, struct axiout *ao)
+{
+	unsigned long *bptr;
+	int    cnt;
+	int rc = 0;
+	int o_mode = 0;
+	unsigned long flags;
+
+	if (op_mode & SNAPSHOT_MASK_MODE)
+		o_mode = SNAPSHOT_MASK_MODE;
+
+	if ((o_mode == SNAPSHOT_MASK_MODE) && (vfe2x_ctrl->num_snap > 1)) {
+		CDBG("%s: BURST mode freebuf cnt %d", __func__,
+			ad->free_buf_cnt);
+		/* Burst */
+		if (mode == OUTPUT_SEC) {
+			ao->output1buffer1_y_phy = ad->ping.ch_paddr[0];
+			ao->output1buffer1_cbcr_phy = ad->ping.ch_paddr[1];
+			ao->output1buffer2_y_phy = ad->pong.ch_paddr[0];
+			ao->output1buffer2_cbcr_phy = ad->pong.ch_paddr[1];
+			ao->output1buffer3_y_phy = ad->free_buf.ch_paddr[0];
+			ao->output1buffer3_cbcr_phy = ad->free_buf.ch_paddr[1];
+			bptr = &ao->output1buffer4_y_phy;
+			for (cnt = 0; cnt < 5; cnt++) {
+				*bptr = (cnt < ad->free_buf_cnt-3) ?
+					ad->free_buf_arr[cnt].ch_paddr[0] :
+						ad->pong.ch_paddr[0];
+				bptr++;
+				*bptr = (cnt < ad->free_buf_cnt-3) ?
+					ad->free_buf_arr[cnt].ch_paddr[1] :
+						ad->pong.ch_paddr[1];
+				bptr++;
+			}
+			CDBG("%x %x\n", (unsigned int)ao->output1buffer1_y_phy,
+				(unsigned int)ao->output1buffer1_cbcr_phy);
+			CDBG("%x %x\n", (unsigned int)ao->output1buffer2_y_phy,
+				(unsigned int)ao->output1buffer2_cbcr_phy);
+			CDBG("%x %x\n", (unsigned int)ao->output1buffer3_y_phy,
+				(unsigned int)ao->output1buffer3_cbcr_phy);
+			CDBG("%x %x\n", (unsigned int)ao->output1buffer4_y_phy,
+				(unsigned int)ao->output1buffer4_cbcr_phy);
+			CDBG("%x %x\n", (unsigned int)ao->output1buffer5_y_phy,
+				(unsigned int)ao->output1buffer5_cbcr_phy);
+			CDBG("%x %x\n", (unsigned int)ao->output1buffer6_y_phy,
+				(unsigned int)ao->output1buffer6_cbcr_phy);
+			CDBG("%x %x\n", (unsigned int)ao->output1buffer7_y_phy,
+				(unsigned int)ao->output1buffer7_cbcr_phy);
+		} else { /*Primary*/
+			ao->output2buffer1_y_phy = ad->ping.ch_paddr[0];
+			ao->output2buffer1_cbcr_phy = ad->ping.ch_paddr[1];
+			ao->output2buffer2_y_phy = ad->pong.ch_paddr[0];
+			ao->output2buffer2_cbcr_phy = ad->pong.ch_paddr[1];
+			ao->output2buffer3_y_phy = ad->free_buf.ch_paddr[0];
+			ao->output2buffer3_cbcr_phy = ad->free_buf.ch_paddr[1];
+			bptr = &ao->output2buffer4_y_phy;
+			for (cnt = 0; cnt < 5; cnt++) {
+				*bptr = (cnt < ad->free_buf_cnt-3) ?
+					ad->free_buf_arr[cnt].ch_paddr[0] :
+						ad->pong.ch_paddr[0];
+				bptr++;
+				*bptr = (cnt < ad->free_buf_cnt-3) ?
+					ad->free_buf_arr[cnt].ch_paddr[1] :
+						ad->pong.ch_paddr[1];
+				bptr++;
+			}
+			CDBG("%x %x\n", (unsigned int)ao->output2buffer1_y_phy,
+				(unsigned int)ao->output2buffer1_cbcr_phy);
+			CDBG("%x %x\n", (unsigned int)ao->output2buffer2_y_phy,
+				(unsigned int)ao->output2buffer2_cbcr_phy);
+			CDBG("%x %x\n", (unsigned int)ao->output2buffer3_y_phy,
+				(unsigned int)ao->output2buffer3_cbcr_phy);
+			CDBG("%x %x\n", (unsigned int)ao->output2buffer4_y_phy,
+				(unsigned int)ao->output2buffer4_cbcr_phy);
+			CDBG("%x %x\n", (unsigned int)ao->output2buffer5_y_phy,
+				(unsigned int)ao->output2buffer5_cbcr_phy);
+			CDBG("%x %x\n", (unsigned int)ao->output2buffer6_y_phy,
+				(unsigned int)ao->output2buffer6_cbcr_phy);
+			CDBG("%x %x\n", (unsigned int)ao->output2buffer7_y_phy,
+				(unsigned int)ao->output2buffer7_cbcr_phy);
+		}
+	} else if (mode == OUTPUT_SEC) {
+		/* Thumbnail */
+		if (vfe2x_ctrl->zsl_mode) {
+			ao->output1buffer1_y_phy = ad->ping.ch_paddr[0];
+			ao->output1buffer1_cbcr_phy = ad->ping.ch_paddr[1];
+			ao->output1buffer2_y_phy = ad->pong.ch_paddr[0];
+			ao->output1buffer2_cbcr_phy = ad->pong.ch_paddr[1];
+			ao->output1buffer3_y_phy = ad->free_buf.ch_paddr[0];
+			ao->output1buffer3_cbcr_phy = ad->free_buf.ch_paddr[1];
+			bptr = &ao->output1buffer4_y_phy;
+			for (cnt = 0; cnt < 5; cnt++) {
+				*bptr = ad->pong.ch_paddr[0];
+				bptr++;
+				*bptr = ad->pong.ch_paddr[1];
+				bptr++;
+			}
+		} else {
+			ao->output1buffer1_y_phy = ad->ping.ch_paddr[0];
+			ao->output1buffer1_cbcr_phy = ad->ping.ch_paddr[1];
+			ao->output1buffer2_y_phy = ad->pong.ch_paddr[0];
+			ao->output1buffer2_cbcr_phy = ad->pong.ch_paddr[1];
+			bptr = &ao->output1buffer3_y_phy;
+			for (cnt = 0; cnt < 6; cnt++) {
+				*bptr = ad->pong.ch_paddr[0];
+				bptr++;
+				*bptr = ad->pong.ch_paddr[1];
+				bptr++;
+			}
+		}
+	} else if (mode == OUTPUT_PRIM && o_mode != SNAPSHOT_MASK_MODE) {
+		/* Preview */
+		ao->output2buffer1_y_phy = ad->ping.ch_paddr[0];
+		ao->output2buffer1_cbcr_phy = ad->ping.ch_paddr[1];
+		ao->output2buffer2_y_phy = ad->pong.ch_paddr[0];
+		ao->output2buffer2_cbcr_phy = ad->pong.ch_paddr[1];
+		spin_lock_irqsave(&vfe2x_ctrl->liveshot_enabled_lock,
+				flags);
+		if (vfe2x_ctrl->liveshot_enabled) { /* Live shot */
+			ao->output2buffer3_y_phy = ad->pong.ch_paddr[0];
+			ao->output2buffer3_cbcr_phy = ad->pong.ch_paddr[1];
+		} else {
+			ao->output2buffer3_y_phy = ad->free_buf.ch_paddr[0];
+			ao->output2buffer3_cbcr_phy = ad->free_buf.ch_paddr[1];
+		}
+		spin_unlock_irqrestore(&vfe2x_ctrl->liveshot_enabled_lock,
+				flags);
+		bptr = &ao->output2buffer4_y_phy;
+		for (cnt = 0; cnt < 5; cnt++) {
+			*bptr = ad->pong.ch_paddr[0];
+			bptr++;
+			*bptr = ad->pong.ch_paddr[1];
+			bptr++;
+		}
+		CDBG("%x %x\n", (unsigned int)ao->output2buffer1_y_phy,
+			(unsigned int)ao->output2buffer1_cbcr_phy);
+		CDBG("%x %x\n", (unsigned int)ao->output2buffer2_y_phy,
+			(unsigned int)ao->output2buffer2_cbcr_phy);
+		CDBG("%x %x\n", (unsigned int)ao->output2buffer3_y_phy,
+			(unsigned int)ao->output2buffer3_cbcr_phy);
+		CDBG("%x %x\n", (unsigned int)ao->output2buffer4_y_phy,
+			(unsigned int)ao->output2buffer4_cbcr_phy);
+		CDBG("%x %x\n", (unsigned int)ao->output2buffer5_y_phy,
+			(unsigned int)ao->output2buffer5_cbcr_phy);
+		CDBG("%x %x\n", (unsigned int)ao->output2buffer6_y_phy,
+			(unsigned int)ao->output2buffer6_cbcr_phy);
+		CDBG("%x %x\n", (unsigned int)ao->output2buffer7_y_phy,
+			(unsigned int)ao->output2buffer7_cbcr_phy);
+		vfe2x_ctrl->free_buf.buf[0].ch_paddr[0] = ad->ping.ch_paddr[0];
+		vfe2x_ctrl->free_buf.buf[0].ch_paddr[1] = ad->ping.ch_paddr[1];
+		vfe2x_ctrl->free_buf.buf[1].ch_paddr[0] = ad->pong.ch_paddr[0];
+		vfe2x_ctrl->free_buf.buf[1].ch_paddr[1] = ad->pong.ch_paddr[1];
+		vfe2x_ctrl->free_buf.buf[2].ch_paddr[0] =
+			ad->free_buf.ch_paddr[0];
+		vfe2x_ctrl->free_buf.buf[2].ch_paddr[1] =
+			ad->free_buf.ch_paddr[1];
+	} else if (mode == OUTPUT_PRIM && o_mode == SNAPSHOT_MASK_MODE) {
+		vfe2x_ctrl->reconfig_vfe = 0;
+		if (raw_mode) {
+			ao->output2buffer1_y_phy = ad->ping.ch_paddr[0];
+			ao->output2buffer1_cbcr_phy = ad->ping.ch_paddr[0];
+			ao->output2buffer2_y_phy = ad->pong.ch_paddr[0];
+			ao->output2buffer2_cbcr_phy = ad->pong.ch_paddr[0];
+		} else {
+			ao->output2buffer1_y_phy = ad->ping.ch_paddr[0];
+			ao->output2buffer1_cbcr_phy = ad->ping.ch_paddr[1];
+			ao->output2buffer2_y_phy = ad->pong.ch_paddr[0];
+			ao->output2buffer2_cbcr_phy = ad->pong.ch_paddr[1];
+	}
+		bptr = &ao->output2buffer3_y_phy;
+		for (cnt = 0; cnt < 6; cnt++) {
+			*bptr = ad->pong.ch_paddr[0];
+			bptr++;
+			*bptr = ad->pong.ch_paddr[1];
+			bptr++;
+		}
+	}
+
+	return rc;
+}
+
+static void vfe2x_subdev_notify(int id, int path)
+{
+	struct msm_vfe_resp rp;
+	unsigned long flags = 0;
+	spin_lock_irqsave(&vfe2x_ctrl->sd_notify_lock, flags);
+	memset(&rp, 0, sizeof(struct msm_vfe_resp));
+	CDBG("vfe2x_subdev_notify : msgId = %d\n", id);
+	rp.evt_msg.type   = MSM_CAMERA_MSG;
+	rp.evt_msg.msg_id = path;
+	rp.evt_msg.data = NULL;
+	rp.type	   = id;
+	v4l2_subdev_notify(&vfe2x_ctrl->subdev, NOTIFY_VFE_BUF_EVT, &rp);
+	spin_unlock_irqrestore(&vfe2x_ctrl->sd_notify_lock, flags);
+}
+
+static struct msm_free_buf *vfe2x_check_free_buffer(int id, int path)
+{
+	struct buf_info *outch = NULL;
+
+	vfe2x_subdev_notify(id, path);
+	if (op_mode & SNAPSHOT_MASK_MODE) {
+		if (path == VFE_MSG_OUTPUT_PRIMARY ||
+				path == VFE_MSG_V2X_LIVESHOT_PRIMARY)
+			outch = &vfe2x_ctrl->snap;
+		else if (path == VFE_MSG_OUTPUT_SECONDARY)
+			outch = &vfe2x_ctrl->thumb;
+	} else {
+		if (path == VFE_MSG_OUTPUT_PRIMARY ||
+				path == VFE_MSG_V2X_LIVESHOT_PRIMARY) {
+			if (vfe2x_ctrl->zsl_mode)
+				outch = &vfe2x_ctrl->zsl_prim;
+			else
+				outch = &vfe2x_ctrl->prev;
+		} else if (path == VFE_MSG_OUTPUT_SECONDARY)
+				outch = &vfe2x_ctrl->zsl_sec;
+	}
+	if (outch->free_buf.ch_paddr[0])
+		return &outch->free_buf;
+
+	return NULL;
+}
+
+static int vfe2x_configure_pingpong_buffers(int id, int path)
+{
+	struct buf_info *outch = NULL;
+	int rc = 0;
+
+	vfe2x_subdev_notify(id, path);
+	CDBG("Opmode = %d\n", op_mode);
+	if (op_mode & SNAPSHOT_MASK_MODE) {
+		if (path == VFE_MSG_OUTPUT_PRIMARY ||
+				path == VFE_MSG_V2X_LIVESHOT_PRIMARY)
+			outch = &vfe2x_ctrl->snap;
+		else if (path == VFE_MSG_OUTPUT_SECONDARY)
+			outch = &vfe2x_ctrl->thumb;
+	} else {
+		if (path == VFE_MSG_OUTPUT_PRIMARY ||
+				path == VFE_MSG_V2X_LIVESHOT_PRIMARY) {
+			if (vfe2x_ctrl->zsl_mode)
+				outch = &vfe2x_ctrl->zsl_prim;
+			else
+				outch = &vfe2x_ctrl->prev;
+		} else if (path == VFE_MSG_OUTPUT_SECONDARY)
+			outch = &vfe2x_ctrl->zsl_sec;
+	}
+	if (outch->ping.ch_paddr[0] && outch->pong.ch_paddr[0]) {
+		/* Configure Preview Ping Pong */
+		CDBG("%s Configure ping/pong address for %d",
+						__func__, path);
+	} else {
+		pr_err("%s ping/pong addr is null!!", __func__);
+		rc = -EINVAL;
+	}
+	return rc;
+}
+
+static struct buf_info *vfe2x_get_ch(int path)
+{
+	struct buf_info *ch = NULL;
+
+	CDBG("path = %d op_mode = %d\n", path, op_mode);
+	/* TODO: Remove Mode specific stuff */
+	if (op_mode & SNAPSHOT_MASK_MODE) {
+		if (path == VFE_MSG_OUTPUT_SECONDARY)
+			ch = &vfe2x_ctrl->thumb;
+		else if (path == VFE_MSG_OUTPUT_PRIMARY ||
+					path == VFE_MSG_V2X_LIVESHOT_PRIMARY)
+			ch = &vfe2x_ctrl->snap;
+	} else {
+		if (path == VFE_MSG_OUTPUT_PRIMARY ||
+					path == VFE_MSG_V2X_LIVESHOT_PRIMARY) {
+			if (vfe2x_ctrl->zsl_mode)
+				ch = &vfe2x_ctrl->zsl_prim;
+			else
+				ch = &vfe2x_ctrl->prev;
+		} else if (path == VFE_MSG_OUTPUT_SECONDARY)
+			ch = &vfe2x_ctrl->zsl_sec;
+	}
+
+	BUG_ON(ch == NULL);
+	return ch;
+}
+
+static long msm_vfe_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int subdev_cmd, void *arg)
+{
+	struct msm_isp_cmd vfecmd;
+	struct msm_camvfe_params *vfe_params;
+	struct msm_vfe_cfg_cmd *cmd;
+	struct table_cmd *table_pending;
+	long rc = 0;
+	void *data;
+
+	struct msm_pmem_region *regptr;
+	unsigned char buf[256];
+
+	struct vfe_stats_ack sack;
+	struct axidata *axid;
+	uint32_t i;
+	uint32_t header = 0;
+	uint32_t queue = 0;
+	struct vfe_stats_we_cfg *scfg = NULL;
+	struct vfe_stats_af_cfg *sfcfg = NULL;
+
+	struct axiout *axio = NULL;
+	void   *cmd_data = NULL;
+	void   *cmd_data_alloc = NULL;
+	unsigned long flags;
+	struct msm_free_buf *free_buf = NULL;
+	struct vfe_outputack fack;
+
+	CDBG("msm_vfe_subdev_ioctl is called\n");
+	if (subdev_cmd == VIDIOC_MSM_VFE_INIT) {
+		CDBG("%s init\n", __func__);
+		return msm_vfe_subdev_init(sd);
+	} else if (subdev_cmd == VIDIOC_MSM_VFE_RELEASE) {
+		msm_vfe_subdev_release(sd);
+		return 0;
+	}
+
+	vfe_params = (struct msm_camvfe_params *)arg;
+	cmd = vfe_params->vfe_cfg;
+	data = vfe_params->data;
+
+	if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE &&
+		cmd->cmd_type != CMD_CONFIG_PING_ADDR &&
+		cmd->cmd_type != CMD_CONFIG_PONG_ADDR &&
+		cmd->cmd_type != CMD_CONFIG_FREE_BUF_ADDR &&
+		cmd->cmd_type != CMD_VFE_BUFFER_RELEASE &&
+		cmd->cmd_type != VFE_CMD_STATS_REQBUF &&
+		cmd->cmd_type != VFE_CMD_STATS_FLUSH_BUFQ &&
+		cmd->cmd_type != VFE_CMD_STATS_UNREGBUF &&
+		cmd->cmd_type != VFE_CMD_STATS_ENQUEUEBUF) {
+		if (copy_from_user(&vfecmd,
+			   (void __user *)(cmd->value),
+			   sizeof(vfecmd))) {
+			pr_err("copy_from_user in msm_vfe_subdev_ioctl fail\n");
+			return -EFAULT;
+		}
+	}
+	switch (cmd->cmd_type) {
+	case VFE_CMD_STATS_REQBUF:
+	case VFE_CMD_STATS_FLUSH_BUFQ:
+	case VFE_CMD_STATS_UNREGBUF:
+		/* for easy porting put in one envelope */
+		rc = vfe2x_stats_bufq_sub_ioctl(cmd, vfe_params->data);
+		return rc;
+	case VFE_CMD_STATS_ENQUEUEBUF:
+		if (sizeof(struct msm_stats_buf_info) != cmd->length) {
+			/* error. the length not match */
+			pr_err("%s: stats enqueuebuf input size = %d,\n"
+				"struct size = %d, mitch match\n",\
+				__func__, cmd->length,
+				sizeof(struct msm_stats_buf_info));
+			rc = -EINVAL;
+			return rc;
+		}
+		sack.header = 0;
+		sack.bufaddr = NULL;
+		rc = vfe2x_stats_enqueuebuf(cmd->value, &sack);
+		if (rc < 0) {
+			pr_err("%s: error", __func__);
+			rc = -EINVAL;
+			return rc;
+		}
+		if (sack.header != 0 && sack.bufaddr != NULL) {
+			queue  = QDSP_CMDQUEUE;
+			vfecmd.length = sizeof(struct vfe_stats_ack) - 4;
+			cmd_data = &sack;
+		} else {
+			return 0;
+		}
+	break;
+	case CMD_VFE_BUFFER_RELEASE: {
+		if (!(vfe2x_ctrl->vfe_started) || op_mode == 1)
+			return 0;
+		if (op_mode & SNAPSHOT_MASK_MODE) {
+			free_buf = vfe2x_check_free_buffer(
+					VFE_MSG_OUTPUT_IRQ,
+					VFE_MSG_OUTPUT_SECONDARY);
+		} else {
+			free_buf = vfe2x_check_free_buffer(
+					VFE_MSG_OUTPUT_IRQ,
+					VFE_MSG_OUTPUT_PRIMARY);
+			if (free_buf) {
+				fack.header = VFE_OUTPUT2_ACK;
+
+				fack.output2newybufferaddress =
+						(void *)(free_buf->ch_paddr[0]);
+
+				fack.output2newcbcrbufferaddress =
+						(void *)(free_buf->ch_paddr[1]);
+
+				cmd_data = &fack;
+				vfecmd.length = sizeof(fack) - 4;
+				queue = QDSP_CMDQUEUE;
+			}
+		}
+	}
+	break;
+	case CMD_CONFIG_PING_ADDR: {
+		int path = *((int *)cmd->value);
+		struct buf_info *outch = vfe2x_get_ch(path);
+		outch->ping = *((struct msm_free_buf *)data);
+	}
+		return 0;
+	case CMD_CONFIG_PONG_ADDR: {
+		int path = *((int *)cmd->value);
+		struct buf_info *outch = vfe2x_get_ch(path);
+		outch->pong = *((struct msm_free_buf *)data);
+	}
+		return 0;
+
+	case CMD_AXI_START:
+	case CMD_AXI_STOP:
+	case CMD_AXI_RESET:
+		return 0;
+
+	case CMD_CONFIG_FREE_BUF_ADDR: {
+		int path = *((int *)cmd->value);
+		struct buf_info *outch = vfe2x_get_ch(path);
+		if ((op_mode & SNAPSHOT_MASK_MODE) &&
+			(vfe2x_ctrl->num_snap > 1)) {
+			CDBG("%s: CMD_CONFIG_FREE_BUF_ADDR Burst mode %d",
+					__func__, outch->free_buf_cnt);
+			if (outch->free_buf_cnt <= 0)
+				outch->free_buf =
+					*((struct msm_free_buf *)data);
+			else
+				outch->free_buf_arr[outch->free_buf_cnt-1] =
+					*((struct msm_free_buf *)data);
+			++outch->free_buf_cnt;
+		} else {
+			outch->free_buf = *((struct msm_free_buf *)data);
+		}
+	}
+		return 0;
+
+	case CMD_STATS_AXI_CFG: {
+		axid = data;
+		if (!axid) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+
+		scfg =
+			kmalloc(sizeof(struct vfe_stats_we_cfg),
+				GFP_ATOMIC);
+		if (!scfg) {
+			rc = -ENOMEM;
+			goto config_failure;
+		}
+
+		if (copy_from_user((char *)scfg + 4,
+					(void __user *)(vfecmd.value),
+					vfecmd.length)) {
+
+			rc = -EFAULT;
+			goto config_done;
+		}
+
+		CDBG("STATS_ENABLE: bufnum = %d, enabling = %d\n",
+			axid->bufnum1, scfg->wb_expstatsenable);
+
+		header = cmds_map[vfecmd.id].vfe_id;
+		queue = cmds_map[vfecmd.id].queue;
+		if (header == -1 && queue == -1) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+		*(uint32_t *)scfg = header;
+		if (axid->bufnum1 > 0) {
+			regptr = axid->region;
+
+			for (i = 0; i < axid->bufnum1; i++) {
+
+				CDBG("STATS_ENABLE, phy = 0x%lx\n",
+					regptr->paddr);
+
+				scfg->wb_expstatoutputbuffer[i] =
+					(void *)regptr->paddr;
+				regptr++;
+			}
+
+			cmd_data = scfg;
+
+		} else {
+			rc = -EINVAL;
+			goto config_done;
+		}
+	}
+		break;
+	case CMD_STATS_AEC_AWB_ENABLE: {
+		pr_err("CMD_STATS_AEC_AWB_ENABLE\n");
+		scfg =
+			kmalloc(sizeof(struct vfe_stats_we_cfg),
+				GFP_ATOMIC);
+		if (!scfg) {
+			rc = -ENOMEM;
+			goto config_failure;
+		}
+
+		if (copy_from_user((char *)scfg + 4,
+					(void __user *)(vfecmd.value),
+					vfecmd.length)) {
+
+			rc = -EFAULT;
+			goto config_done;
+		}
+
+		header = cmds_map[vfecmd.id].vfe_id;
+		queue = cmds_map[vfecmd.id].queue;
+		if (header == -1 && queue == -1) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+		*(uint32_t *)scfg = header;
+		rc = vfe2x_stats_buf_init(MSM_STATS_TYPE_AE_AW);
+		if (rc < 0) {
+			pr_err("%s: cannot config ping/pong address of AWB",
+				 __func__);
+			goto config_failure;
+		}
+		scfg->wb_expstatoutputbuffer[0] =
+			(void *)vfe2x_ctrl->stats_we_buf_ptr[0];
+		scfg->wb_expstatoutputbuffer[1] =
+			(void *)vfe2x_ctrl->stats_we_buf_ptr[1];
+		scfg->wb_expstatoutputbuffer[2] =
+			(void *)vfe2x_ctrl->stats_we_buf_ptr[2];
+		cmd_data = scfg;
+	}
+	break;
+	case CMD_STATS_AF_ENABLE:
+	case CMD_STATS_AF_AXI_CFG: {
+		CDBG("CMD_STATS_AF_ENABLE CMD_STATS_AF_AXI_CFG\n");
+		sfcfg =
+			kmalloc(sizeof(struct vfe_stats_af_cfg),
+				GFP_ATOMIC);
+
+		if (!sfcfg) {
+			rc = -ENOMEM;
+			goto config_failure;
+		}
+
+		if (copy_from_user((char *)sfcfg + 4,
+					(void __user *)(vfecmd.value),
+					vfecmd.length)) {
+
+			rc = -EFAULT;
+			goto config_done;
+		}
+
+		header = cmds_map[vfecmd.id].vfe_id;
+		queue = cmds_map[vfecmd.id].queue;
+		if (header == -1 && queue == -1) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+		*(uint32_t *)sfcfg = header;
+		rc = vfe2x_stats_buf_init(MSM_STATS_TYPE_AF);
+		sfcfg->af_outbuf[0] = (void *)vfe2x_ctrl->stats_af_buf_ptr[0];
+		sfcfg->af_outbuf[1] = (void *)vfe2x_ctrl->stats_af_buf_ptr[1];
+		sfcfg->af_outbuf[2] = (void *)vfe2x_ctrl->stats_af_buf_ptr[2];
+		if (rc < 0) {
+			pr_err("%s: cannot config ping/pong address of AWB",
+				__func__);
+			goto config_failure;
+		}
+		cmd_data = sfcfg;
+	}
+		break;
+	case CMD_SNAP_BUF_RELEASE:
+		break;
+	case CMD_STATS_BUF_RELEASE: {
+		CDBG("vfe_7x_config: CMD_STATS_BUF_RELEASE\n");
+		if (!data) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+
+		sack.header = VFE_STATS_WB_EXP_ACK;
+		sack.bufaddr = (void *)*(uint32_t *)data;
+
+		queue  = QDSP_CMDQUEUE;
+		vfecmd.length = sizeof(struct vfe_stats_ack) - 4;
+		cmd_data = &sack;
+	}
+		break;
+	case CMD_STATS_AF_BUF_RELEASE: {
+		CDBG("vfe_7x_config: CMD_STATS_AF_BUF_RELEASE\n");
+		if (!data) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+
+		sack.header = VFE_STATS_AUTOFOCUS_ACK;
+		sack.bufaddr = (void *)*(uint32_t *)data;
+
+		queue  = QDSP_CMDQUEUE;
+		vfecmd.length = sizeof(struct vfe_stats_ack) - 4;
+		cmd_data = &sack;
+	}
+		break;
+	case CMD_GENERAL:
+	case CMD_STATS_DISABLE: {
+		CDBG("CMD_GENERAL:%d %d\n", vfecmd.id, vfecmd.length);
+		if (vfecmd.id == VFE_CMD_OPERATION_CFG) {
+			if (copy_from_user(&vfe2x_ctrl->start_cmd,
+						(void __user *)(vfecmd.value),
+							vfecmd.length))
+				rc = -EFAULT;
+			op_mode = vfe2x_ctrl->start_cmd.mode_of_operation;
+			vfe2x_ctrl->snap.free_buf_cnt = 0;
+			vfe2x_ctrl->thumb.free_buf_cnt = 0;
+			vfe2x_ctrl->snap.frame_cnt = 0;
+			vfe2x_ctrl->thumb.frame_cnt = 0;
+			vfe2x_ctrl->num_snap =
+				vfe2x_ctrl->start_cmd.snap_number;
+			return rc;
+		}
+		if (vfecmd.id == VFE_CMD_RECONFIG_VFE) {
+			CDBG("VFE is RECONFIGURED\n");
+			vfe2x_ctrl->reconfig_vfe = 1;
+			return 0;
+		}
+		if (vfecmd.id == VFE_CMD_LIVESHOT) {
+			CDBG("live shot enabled\n");
+			spin_lock_irqsave(&vfe2x_ctrl->liveshot_enabled_lock,
+					flags);
+			vfe2x_ctrl->liveshot_enabled = 1;
+			spin_unlock_irqrestore(&vfe2x_ctrl->
+					liveshot_enabled_lock,
+					flags);
+			return 0;
+		}
+		if (vfecmd.id == VFE_CMD_STOP_LIVESHOT) {
+			CDBG("live shot disabled\n");
+			spin_lock_irqsave(&vfe2x_ctrl->liveshot_enabled_lock,
+					flags);
+			vfe2x_ctrl->liveshot_enabled = 0;
+			spin_unlock_irqrestore(
+					&vfe2x_ctrl->liveshot_enabled_lock,
+					flags);
+			return 0;
+		}
+		if (vfecmd.length > 256 - 4) {
+			cmd_data_alloc =
+			cmd_data = kmalloc(vfecmd.length + 4, GFP_ATOMIC);
+			if (!cmd_data) {
+				rc = -ENOMEM;
+				goto config_failure;
+			}
+		} else
+			cmd_data = buf;
+
+		if (copy_from_user(((char *)cmd_data) + 4,
+					(void __user *)(vfecmd.value),
+					vfecmd.length)) {
+
+			rc = -EFAULT;
+			goto config_done;
+		}
+		header = cmds_map[vfecmd.id].vfe_id;
+		queue = cmds_map[vfecmd.id].queue;
+		if (header == -1 && queue == -1) {
+			rc = -EFAULT;
+			goto config_done;
+		}
+		CDBG("%s %s\n", cmds_map[vfecmd.id].isp_id_name,
+			cmds_map[vfecmd.id].vfe_id_name);
+		*(uint32_t *)cmd_data = header;
+		if (queue == QDSP_CMDQUEUE) {
+			switch (vfecmd.id) {
+			case VFE_CMD_RESET:
+				msm_camio_vfe_blk_reset_2();
+				vfestopped = 0;
+				break;
+			case VFE_CMD_START:
+			case VFE_CMD_CAPTURE:
+			case VFE_CMD_CAPTURE_RAW:
+			case VFE_CMD_ZSL:
+				spin_lock_irqsave(&vfe2x_ctrl->table_lock,
+									flags);
+				if ((!list_empty(&vfe2x_ctrl->table_q)) ||
+						vfe2x_ctrl->tableack_pending) {
+					CDBG("start pending\n");
+					vfe2x_ctrl->start_pending = 1;
+					spin_unlock_irqrestore(
+						&vfe2x_ctrl->table_lock,
+								flags);
+					return 0;
+				}
+				spin_unlock_irqrestore(&vfe2x_ctrl->table_lock,
+									flags);
+				vfecmd.length = sizeof(vfe2x_ctrl->start_cmd);
+				memcpy(((char *)cmd_data) + 4,
+					&vfe2x_ctrl->start_cmd,
+					sizeof(vfe2x_ctrl->start_cmd));
+				if (op_mode & SNAPSHOT_MASK_MODE)
+					msm_camio_set_perf_lvl(S_CAPTURE);
+				else
+					msm_camio_set_perf_lvl(S_PREVIEW);
+				vfestopped = 0;
+				break;
+			case VFE_CMD_STOP:
+				vfestopped = 1;
+				spin_lock_irqsave(&vfe2x_ctrl->table_lock,
+						flags);
+				if (op_mode & SNAPSHOT_MASK_MODE) {
+					vfe2x_ctrl->stop_pending = 0;
+					spin_unlock_irqrestore(
+							&vfe2x_ctrl->table_lock,
+							flags);
+					return 0;
+				}
+				if ((!list_empty(&vfe2x_ctrl->table_q)) ||
+						vfe2x_ctrl->tableack_pending) {
+					CDBG("stop pending\n");
+					vfe2x_ctrl->stop_pending = 1;
+					spin_unlock_irqrestore(
+							&vfe2x_ctrl->table_lock,
+							flags);
+					return 0;
+				}
+				spin_unlock_irqrestore(&vfe2x_ctrl->table_lock,
+						flags);
+				vfe2x_ctrl->vfe_started = 0;
+				goto config_send;
+			case VFE_CMD_UPDATE:
+				spin_lock_irqsave(&vfe2x_ctrl->table_lock,
+						flags);
+				if ((!list_empty(&vfe2x_ctrl->table_q)) ||
+						vfe2x_ctrl->tableack_pending) {
+					CDBG("update pending\n");
+					vfe2x_ctrl->update_pending = 0;
+					vfe2x_send_isp_msg(vfe2x_ctrl,
+						msgs_map[MSG_UPDATE_ACK].
+						isp_id);
+					spin_unlock_irqrestore(
+							&vfe2x_ctrl->table_lock,
+							flags);
+					return 0;
+				}
+				spin_unlock_irqrestore(&vfe2x_ctrl->table_lock,
+						flags);
+				goto config_send;
+			default:
+				break;
+			}
+		} /* QDSP_CMDQUEUE */
+	}
+		break;
+	case CMD_AXI_CFG_SEC: {
+		CDBG("CMD_AXI_CFG_SEC\n");
+		raw_mode = 0;
+		vfe2x_ctrl->zsl_mode = 0;
+		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
+		if (!axio) {
+			pr_err("NULL axio\n");
+			rc = -ENOMEM;
+			goto config_failure;
+		}
+
+		if (copy_from_user((char *)axio + 4,
+					(void __user *)(vfecmd.value),
+					sizeof(struct axiout))) {
+			CDBG("copy_from_user failed\n");
+			rc = -EFAULT;
+			goto config_done;
+		}
+		if (op_mode & SNAPSHOT_MASK_MODE)
+			rc = vfe2x_configure_pingpong_buffers(
+						VFE_MSG_CAPTURE,
+						VFE_MSG_OUTPUT_SECONDARY);
+		else
+			rc = vfe2x_configure_pingpong_buffers(
+						VFE_MSG_PREVIEW,
+						VFE_MSG_OUTPUT_SECONDARY);
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers"
+				" for preview", __func__);
+			rc = -EINVAL;
+			goto config_done;
+		}
+
+		if (!(op_mode & SNAPSHOT_MASK_MODE))
+			free_buf = vfe2x_check_free_buffer(
+					VFE_MSG_OUTPUT_IRQ,
+					VFE_MSG_OUTPUT_SECONDARY);
+		header = cmds_map[vfecmd.id].vfe_id;
+		queue = cmds_map[vfecmd.id].queue;
+		if (header == -1 && queue == -1) {
+			rc = -EFAULT;
+			goto config_done;
+		}
+		*(uint32_t *)axio = header;
+		if (op_mode & SNAPSHOT_MASK_MODE)
+			vfe_7x_config_axi(OUTPUT_SEC,
+					&vfe2x_ctrl->thumb, axio);
+		else
+			vfe_7x_config_axi(OUTPUT_SEC,
+					&vfe2x_ctrl->video, axio);
+		cmd_data = axio;
+	}
+		break;
+	case CMD_AXI_CFG_PRIM: {
+		CDBG("CMD_AXI_CFG_PRIM : %d\n", op_mode);
+		raw_mode = 0;
+		vfe2x_ctrl->zsl_mode = 0;
+		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
+		if (!axio) {
+			pr_err("NULL axio\n");
+			rc = -ENOMEM;
+			goto config_failure;
+		}
+
+		if (copy_from_user((char *)axio + 4,
+					(void __user *)(vfecmd.value),
+					sizeof(struct axiout))) {
+			pr_err("copy_from_user failed\n");
+			rc = -EFAULT;
+			goto config_done;
+		}
+		if (!vfe2x_ctrl->reconfig_vfe) {
+			if (op_mode & SNAPSHOT_MASK_MODE)
+				rc = vfe2x_configure_pingpong_buffers(
+						VFE_MSG_CAPTURE,
+						VFE_MSG_OUTPUT_PRIMARY);
+			else
+				rc = vfe2x_configure_pingpong_buffers(
+						VFE_MSG_PREVIEW,
+						VFE_MSG_OUTPUT_PRIMARY);
+			if (rc < 0) {
+				pr_err("%s error configuring pingpong buffers"
+					" for preview", __func__);
+				rc = -EINVAL;
+				goto config_done;
+			}
+			if (!(op_mode & SNAPSHOT_MASK_MODE))
+				free_buf = vfe2x_check_free_buffer(
+					VFE_MSG_OUTPUT_IRQ,
+					VFE_MSG_OUTPUT_PRIMARY);
+		} else {
+			vfe2x_ctrl->prev.ping.ch_paddr[0] =
+				vfe2x_ctrl->free_buf.buf[0].ch_paddr[0];
+			vfe2x_ctrl->prev.ping.ch_paddr[1] =
+				vfe2x_ctrl->free_buf.buf[0].ch_paddr[1];
+			vfe2x_ctrl->prev.pong.ch_paddr[0] =
+				vfe2x_ctrl->free_buf.buf[1].ch_paddr[0];
+			vfe2x_ctrl->prev.pong.ch_paddr[1] =
+				vfe2x_ctrl->free_buf.buf[1].ch_paddr[1];
+			vfe2x_ctrl->prev.free_buf.ch_paddr[0] =
+				vfe2x_ctrl->free_buf.buf[2].ch_paddr[0];
+			vfe2x_ctrl->prev.free_buf.ch_paddr[1] =
+				vfe2x_ctrl->free_buf.buf[2].ch_paddr[1];
+			vfe2x_ctrl->reconfig_vfe = 0;
+		}
+		header = cmds_map[vfecmd.id].vfe_id;
+		queue = cmds_map[vfecmd.id].queue;
+		if (header == -1 && queue == -1) {
+			rc = -EFAULT;
+			goto config_done;
+		}
+		*(uint32_t *)axio = header;
+		if (op_mode & SNAPSHOT_MASK_MODE)
+			vfe_7x_config_axi(OUTPUT_PRIM, &vfe2x_ctrl->snap, axio);
+		else
+			vfe_7x_config_axi(OUTPUT_PRIM, &vfe2x_ctrl->prev, axio);
+		cmd_data = axio;
+	}
+		break;
+	case CMD_AXI_CFG_ZSL: {
+		CDBG("CMD_AXI_CFG_ZSL: %d\n", op_mode);
+		raw_mode = 0;
+		vfe2x_ctrl->zsl_mode = 1;
+		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
+		if (!axio) {
+			pr_err("NULL axio\n");
+			rc = -ENOMEM;
+			goto config_failure;
+		}
+
+		if (copy_from_user((char *)axio + 4,
+					(void __user *)(vfecmd.value),
+					sizeof(struct axiout))) {
+			pr_err("copy_from_user failed\n");
+			rc = -EFAULT;
+			goto config_done;
+		}
+		if (!vfe2x_ctrl->reconfig_vfe) {
+				rc = vfe2x_configure_pingpong_buffers(
+						VFE_MSG_PREVIEW,
+						VFE_MSG_OUTPUT_PRIMARY);
+				rc = vfe2x_configure_pingpong_buffers(
+						VFE_MSG_PREVIEW,
+						VFE_MSG_OUTPUT_SECONDARY);
+			if (rc < 0) {
+				pr_err("%s error configuring pingpong buffers"
+					" for preview", __func__);
+				rc = -EINVAL;
+				goto config_done;
+			}
+				free_buf = vfe2x_check_free_buffer(
+					VFE_MSG_OUTPUT_IRQ,
+					VFE_MSG_OUTPUT_PRIMARY);
+				free_buf = vfe2x_check_free_buffer(
+					VFE_MSG_OUTPUT_IRQ,
+					VFE_MSG_OUTPUT_SECONDARY);
+		} else {
+			vfe2x_ctrl->prev.ping.ch_paddr[0] =
+				vfe2x_ctrl->free_buf.buf[0].ch_paddr[0];
+			vfe2x_ctrl->prev.ping.ch_paddr[1] =
+				vfe2x_ctrl->free_buf.buf[0].ch_paddr[1];
+			vfe2x_ctrl->prev.pong.ch_paddr[0] =
+				vfe2x_ctrl->free_buf.buf[1].ch_paddr[0];
+			vfe2x_ctrl->prev.pong.ch_paddr[1] =
+				vfe2x_ctrl->free_buf.buf[1].ch_paddr[1];
+			vfe2x_ctrl->prev.free_buf.ch_paddr[0] =
+				vfe2x_ctrl->free_buf.buf[2].ch_paddr[0];
+			vfe2x_ctrl->prev.free_buf.ch_paddr[1] =
+				vfe2x_ctrl->free_buf.buf[2].ch_paddr[1];
+			vfe2x_ctrl->reconfig_vfe = 0;
+		}
+		header = cmds_map[vfecmd.id].vfe_id;
+		queue = cmds_map[vfecmd.id].queue;
+		if (header == -1 && queue == -1) {
+			rc = -EFAULT;
+			goto config_done;
+		}
+		*(uint32_t *)axio = header;
+		vfe_7x_config_axi(OUTPUT_PRIM, &vfe2x_ctrl->zsl_prim, axio);
+		vfe_7x_config_axi(OUTPUT_SEC, &vfe2x_ctrl->zsl_sec, axio);
+		cmd_data = axio;
+	}
+		break;
+	case CMD_AXI_CFG_SEC|CMD_AXI_CFG_PRIM: {
+		CDBG("CMD_AXI_CFG_SEC|PRIM\n");
+		raw_mode = 0;
+		vfe2x_ctrl->zsl_mode = 0;
+		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
+		if (!axio) {
+			pr_err("NULL axio\n");
+			rc = -ENOMEM;
+			goto config_failure;
+		}
+
+		if (copy_from_user((char *)axio + 4,
+					(void __user *)(vfecmd.value),
+					sizeof(struct axiout))) {
+			pr_err("copy_from_user failed\n");
+			rc = -EFAULT;
+			goto config_done;
+		}
+		if (op_mode & SNAPSHOT_MASK_MODE)
+			rc = vfe2x_configure_pingpong_buffers(
+						VFE_MSG_CAPTURE,
+						VFE_MSG_OUTPUT_SECONDARY);
+		else
+			rc = vfe2x_configure_pingpong_buffers(
+						VFE_MSG_PREVIEW,
+						VFE_MSG_OUTPUT_SECONDARY);
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers"
+				" for preview", __func__);
+			rc = -EINVAL;
+			goto config_done;
+		}
+
+		if (!(op_mode & SNAPSHOT_MASK_MODE)) {
+			free_buf = vfe2x_check_free_buffer(
+					VFE_MSG_OUTPUT_IRQ,
+					VFE_MSG_OUTPUT_SECONDARY);
+		} else if ((op_mode & SNAPSHOT_MASK_MODE) &&
+				(vfe2x_ctrl->num_snap > 1)) {
+			int i = 0;
+			CDBG("Burst mode AXI config SEC snap cnt %d\n",
+				vfe2x_ctrl->num_snap);
+			for (i = 0; i < vfe2x_ctrl->num_snap - 2; i++) {
+				free_buf = vfe2x_check_free_buffer(
+					VFE_MSG_OUTPUT_IRQ,
+					VFE_MSG_OUTPUT_SECONDARY);
+			}
+		}
+		header = cmds_map[vfecmd.id].vfe_id;
+		queue = cmds_map[vfecmd.id].queue;
+		if (header == -1 && queue == -1) {
+			rc = -EFAULT;
+			goto config_done;
+		}
+		*(uint32_t *)axio = header;
+		if (op_mode & SNAPSHOT_MASK_MODE)
+			vfe_7x_config_axi(OUTPUT_SEC, &vfe2x_ctrl->thumb, axio);
+		else
+			vfe_7x_config_axi(OUTPUT_SEC, &vfe2x_ctrl->prev, axio);
+
+		if (op_mode & SNAPSHOT_MASK_MODE)
+			rc = vfe2x_configure_pingpong_buffers(
+						VFE_MSG_CAPTURE,
+						VFE_MSG_OUTPUT_PRIMARY);
+		else
+			rc = vfe2x_configure_pingpong_buffers(
+						VFE_MSG_PREVIEW,
+						VFE_MSG_OUTPUT_PRIMARY);
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers"
+				" for preview", __func__);
+			rc = -EINVAL;
+			goto config_done;
+		}
+
+		if (!(op_mode & SNAPSHOT_MASK_MODE)) {
+			free_buf = vfe2x_check_free_buffer(
+					VFE_MSG_OUTPUT_IRQ,
+					VFE_MSG_OUTPUT_PRIMARY);
+		} else if ((op_mode & SNAPSHOT_MASK_MODE) &&
+				(vfe2x_ctrl->num_snap > 1)) {
+			int i = 0;
+			CDBG("Burst mode AXI config PRIM snap cnt %d\n",
+				vfe2x_ctrl->num_snap);
+			for (i = 0; i < vfe2x_ctrl->num_snap - 2; i++) {
+				free_buf = vfe2x_check_free_buffer(
+					VFE_MSG_OUTPUT_IRQ,
+					VFE_MSG_OUTPUT_PRIMARY);
+			}
+		}
+
+		if (op_mode & SNAPSHOT_MASK_MODE)
+			vfe_7x_config_axi(OUTPUT_PRIM,
+					&vfe2x_ctrl->snap, axio);
+		else
+			vfe_7x_config_axi(OUTPUT_PRIM,
+					&vfe2x_ctrl->prev, axio);
+		cmd_data = axio;
+	}
+		break;
+	case CMD_RAW_PICT_AXI_CFG: {
+		CDBG("CMD_RAW_PICT_AXI_CFG:%d\n", op_mode);
+		raw_mode = 1;
+		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			goto config_failure;
+		}
+
+		if (copy_from_user((char *)axio + 4,
+					(void __user *)(vfecmd.value),
+					sizeof(struct axiout))) {
+			rc = -EFAULT;
+			goto config_done;
+		}
+		header = cmds_map[vfecmd.id].vfe_id;
+		queue = cmds_map[vfecmd.id].queue;
+		rc = vfe2x_configure_pingpong_buffers(VFE_MSG_CAPTURE,
+						VFE_MSG_OUTPUT_PRIMARY);
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers"
+				" for preview", __func__);
+			rc = -EINVAL;
+			goto config_done;
+		}
+		if (header == -1 && queue == -1) {
+			rc = -EFAULT;
+			goto config_done;
+		}
+		*(uint32_t *)axio = header;
+		vfe_7x_config_axi(OUTPUT_PRIM, &vfe2x_ctrl->snap, axio);
+		cmd_data = axio;
+	}
+		break;
+	default:
+		break;
+	}
+
+	if (vfestopped)
+		goto config_done;
+
+config_send:
+	CDBG("send adsp command = %d\n", *(uint32_t *)cmd_data);
+	spin_lock_irqsave(&vfe2x_ctrl->table_lock, flags);
+	if (queue == QDSP_TABLEQUEUE &&
+			vfe2x_ctrl->tableack_pending) {
+		CDBG("store table cmd\n");
+		table_pending = kzalloc(sizeof(struct table_cmd), GFP_ATOMIC);
+		if (!table_pending) {
+			rc = -ENOMEM;
+			spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
+			goto config_done;
+		}
+		table_pending->cmd = kzalloc(vfecmd.length + 4, GFP_ATOMIC);
+		if (!table_pending->cmd) {
+			kfree(table_pending);
+			rc = -ENOMEM;
+			spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
+			goto config_done;
+		}
+		memcpy(table_pending->cmd, cmd_data, vfecmd.length + 4);
+		table_pending->queue = queue;
+		table_pending->size = vfecmd.length + 4;
+		list_add_tail(&table_pending->list, &vfe2x_ctrl->table_q);
+		spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
+	} else {
+		if (queue == QDSP_TABLEQUEUE) {
+			CDBG("sending table cmd\n");
+			vfe2x_ctrl->tableack_pending = 1;
+			rc = msm_adsp_write(vfe_mod, queue,
+				cmd_data, vfecmd.length + 4);
+			spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
+		} else {
+			if (*(uint32_t *)cmd_data == VFE_OUTPUT2_ACK) {
+				uint32_t *ptr = cmd_data;
+				CDBG("%x %x %x\n", ptr[0], ptr[1], ptr[2]);
+			}
+			CDBG("send n-table cmd\n");
+			rc = msm_adsp_write(vfe_mod, queue,
+				cmd_data, vfecmd.length + 4);
+			spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
+			CDBG("%x\n", vfecmd.length + 4);
+		}
+	}
+
+config_done:
+	kfree(cmd_data_alloc);
+
+config_failure:
+	kfree(scfg);
+	kfree(axio);
+	kfree(sfcfg);
+	return rc;
+}
+
+static struct msm_cam_clk_info vfe2x_clk_info[] = {
+	{"vfe_clk", 192000000},
+};
+
+int msm_vfe_subdev_init(struct v4l2_subdev *sd)
+{
+	int rc = 0;
+	struct msm_cam_media_controller *mctl;
+	mctl = v4l2_get_subdev_hostdata(sd);
+	if (mctl == NULL) {
+		pr_err("%s: mctl is NULL\n", __func__);
+		rc = -EINVAL;
+		goto mctl_failed;
+	}
+
+	spin_lock_init(&vfe2x_ctrl->sd_notify_lock);
+	spin_lock_init(&vfe2x_ctrl->table_lock);
+	spin_lock_init(&vfe2x_ctrl->vfe_msg_lock);
+	spin_lock_init(&vfe2x_ctrl->liveshot_enabled_lock);
+	init_waitqueue_head(&stopevent.wait);
+	INIT_LIST_HEAD(&vfe2x_ctrl->table_q);
+	INIT_LIST_HEAD(&vfe2x_ctrl->vfe_msg_q);
+	stopevent.timeout = 200;
+	stopevent.state = 0;
+	vfe2x_ctrl->vfe_started = 0;
+
+	memset(&vfe2x_ctrl->stats_ctrl, 0, sizeof(struct msm_stats_bufq_ctrl));
+	memset(&vfe2x_ctrl->stats_ops, 0, sizeof(struct msm_stats_ops));
+
+	CDBG("msm_cam_clk_enable: enable vfe_clk\n");
+	rc = msm_cam_clk_enable(&vfe2x_ctrl->pdev->dev, vfe2x_clk_info,
+			vfe2x_ctrl->vfe_clk, ARRAY_SIZE(vfe2x_clk_info), 1);
+	if (rc < 0)
+		return rc;
+
+	msm_camio_set_perf_lvl(S_INIT);
+
+	/* TODO : check is it required */
+	extlen = sizeof(struct vfe_frame_extra);
+
+	extdata = kmalloc(extlen, GFP_ATOMIC);
+	if (!extdata) {
+		rc = -ENOMEM;
+		goto init_fail;
+	}
+
+	rc = msm_adsp_get("QCAMTASK", &qcam_mod, &vfe_7x_sync, NULL);
+	if (rc) {
+		rc = -EBUSY;
+		goto get_qcam_fail;
+	}
+
+	rc = msm_adsp_get("VFETASK", &vfe_mod, &vfe_7x_sync, NULL);
+	if (rc) {
+		rc = -EBUSY;
+		goto get_vfe_fail;
+	}
+	msm_adsp_enable(qcam_mod);
+	msm_adsp_enable(vfe_mod);
+	return 0;
+
+get_vfe_fail:
+	msm_adsp_put(qcam_mod);
+get_qcam_fail:
+	kfree(extdata);
+init_fail:
+	extlen = 0;
+mctl_failed:
+	return rc;
+}
+
+int msm_vpe_subdev_init(struct v4l2_subdev *sd)
+{
+	return 0;
+}
+
+void msm_vpe_subdev_release(struct v4l2_subdev *sd)
+{
+	return;
+}
+
+void msm_vfe_subdev_release(struct v4l2_subdev *sd)
+{
+	CDBG("msm_cam_clk_enable: disable vfe_clk\n");
+	msm_cam_clk_enable(&vfe2x_ctrl->pdev->dev, vfe2x_clk_info,
+			vfe2x_ctrl->vfe_clk, ARRAY_SIZE(vfe2x_clk_info), 0);
+	msm_adsp_disable(qcam_mod);
+	msm_adsp_disable(vfe_mod);
+
+	msm_adsp_put(qcam_mod);
+	msm_adsp_put(vfe_mod);
+
+	kfree(extdata);
+	msm_camio_set_perf_lvl(S_EXIT);
+	return;
+}
+
+static int msm_vfe_subdev_s_crystal_freq(struct v4l2_subdev *sd,
+	u32 freq, u32 flags)
+{
+	int rc = 0;
+	int round_rate;
+
+	round_rate = clk_round_rate(vfe2x_ctrl->vfe_clk[0], freq);
+	if (rc < 0) {
+		pr_err("%s: clk_round_rate failed %d\n",
+			__func__, rc);
+		return rc;
+	}
+
+	rc = clk_set_rate(vfe2x_ctrl->vfe_clk[0], round_rate);
+	if (rc < 0)
+		pr_err("%s: clk_set_rate failed %d\n",
+			__func__, rc);
+
+	return rc;
+}
+
+static const struct v4l2_subdev_video_ops msm_vfe_subdev_video_ops = {
+	.s_crystal_freq = msm_vfe_subdev_s_crystal_freq,
+};
+
+static const struct v4l2_subdev_core_ops msm_vfe_subdev_core_ops = {
+	.ioctl = msm_vfe_subdev_ioctl,
+};
+
+static const struct v4l2_subdev_ops msm_vfe_subdev_ops = {
+	.core = &msm_vfe_subdev_core_ops,
+	.video = &msm_vfe_subdev_video_ops,
+};
+
+static const struct v4l2_subdev_internal_ops msm_vfe_internal_ops;
+
+static int __devinit vfe2x_probe(struct platform_device *pdev)
+{
+	struct msm_cam_subdev_info sd_info;
+
+	CDBG("%s: device id = %d\n", __func__, pdev->id);
+	vfe2x_ctrl = kzalloc(sizeof(struct vfe2x_ctrl_type), GFP_KERNEL);
+	if (!vfe2x_ctrl) {
+		pr_err("%s: no enough memory\n", __func__);
+		return -ENOMEM;
+	}
+
+	v4l2_subdev_init(&vfe2x_ctrl->subdev, &msm_vfe_subdev_ops);
+	vfe2x_ctrl->subdev.internal_ops = &msm_vfe_internal_ops;
+	vfe2x_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	snprintf(vfe2x_ctrl->subdev.name,
+			 sizeof(vfe2x_ctrl->subdev.name), "vfe2.x");
+	v4l2_set_subdevdata(&vfe2x_ctrl->subdev, vfe2x_ctrl);
+	platform_set_drvdata(pdev, &vfe2x_ctrl->subdev);
+
+	vfe2x_ctrl->pdev = pdev;
+	sd_info.sdev_type = VFE_DEV;
+	sd_info.sd_index = 0;
+	sd_info.irq_num = 0;
+	msm_cam_register_subdev_node(&vfe2x_ctrl->subdev, &sd_info);
+
+	media_entity_init(&vfe2x_ctrl->subdev.entity, 0, NULL, 0);
+	vfe2x_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	vfe2x_ctrl->subdev.entity.group_id = VFE_DEV;
+	vfe2x_ctrl->subdev.entity.name = pdev->name;
+	vfe2x_ctrl->subdev.entity.revision = vfe2x_ctrl->subdev.devnode->num;
+	return 0;
+}
+
+static struct platform_driver vfe2x_driver = {
+	.probe = vfe2x_probe,
+	.driver = {
+		.name = MSM_VFE_DRV_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init msm_vfe2x_init_module(void)
+{
+	return platform_driver_register(&vfe2x_driver);
+}
+
+static void __exit msm_vfe2x_exit_module(void)
+{
+	platform_driver_unregister(&vfe2x_driver);
+}
+
+module_init(msm_vfe2x_init_module);
+module_exit(msm_vfe2x_exit_module);
+MODULE_DESCRIPTION("VFE 2.x driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v1/vfe/msm_vfe7x27a_v4l2.h b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe7x27a_v4l2.h
new file mode 100644
index 0000000..78b1929
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe7x27a_v4l2.h
@@ -0,0 +1,431 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MSM_VFE7X_H__
+#define __MSM_VFE7X_H__
+#include <media/msm_camera.h>
+#include <mach/camera.h>
+#include <linux/list.h>
+#include "msm.h"
+#include "msm_vfe_stats_buf.h"
+
+/*8 DSP buffers, 3 - ping, pong, free*/
+#define FREE_BUF_ARR_SIZE 5
+
+struct cmd_id_map {
+	uint32_t isp_id;
+	uint32_t vfe_id;
+	uint32_t queue;
+	char isp_id_name[64];
+	char vfe_id_name[64];
+} __packed;
+
+struct msg_id_map {
+	uint32_t vfe_id;
+	uint32_t isp_id;
+} __packed;
+
+struct table_cmd {
+	struct list_head list;
+	void *cmd;
+	int size;
+	int queue;
+} __packed;
+
+struct vfe_msg {
+	struct list_head list;
+	void *cmd;
+	int len;
+	int id;
+} __packed;
+
+struct buf_info {
+	/* Buffer */
+	struct msm_free_buf ping;
+	struct msm_free_buf pong;
+	struct msm_free_buf free_buf;
+	/*Array for holding the free buffer if more than one*/
+	struct msm_free_buf free_buf_arr[FREE_BUF_ARR_SIZE];
+	int free_buf_cnt;
+	int frame_cnt;
+} __packed;
+
+struct prev_free_buf_info {
+	struct msm_free_buf buf[3];
+};
+
+struct vfe_cmd_start {
+	uint32_t input_source:1;
+	uint32_t mode_of_operation:1;
+	uint32_t snap_number:4;
+	uint32_t /* reserved */ : 26;
+
+	/* Image Pipeline Modules */
+	uint32_t blacklevel_correction_enable:1;
+	uint32_t lens_rolloff_correction_enable:1;
+	uint32_t white_balance_enable:1;
+	uint32_t rgb_gamma_enable:1;
+	uint32_t luma_noise_reductionpath_enable:1;
+	uint32_t adaptive_spatialfilter_enable:1;
+	uint32_t chroma_subsample_enable:1;
+	uint32_t /* reserved */ : 25;
+
+	/* The dimension fed to the statistics module */
+	uint32_t last_pixel:12;
+	uint32_t /* reserved */ : 4;
+	uint32_t last_line:12;
+	uint32_t /* reserved */ : 4;
+} __packed;
+
+struct vfe2x_ctrl_type {
+	struct buf_info prev;
+	struct buf_info video;
+	struct buf_info snap;
+	struct buf_info raw;
+	struct buf_info thumb;
+	struct prev_free_buf_info free_buf;
+	struct buf_info zsl_prim;
+	struct buf_info zsl_sec;
+	struct prev_free_buf_info zsl_free_buf[2];
+
+
+	spinlock_t  table_lock;
+	struct list_head table_q;
+	uint32_t tableack_pending;
+	uint32_t vfeFrameId;
+
+	spinlock_t vfe_msg_lock;
+	struct list_head vfe_msg_q;
+
+	struct vfe_cmd_start start_cmd;
+	uint32_t start_pending;
+	uint32_t vfe_started;
+	uint32_t stop_pending;
+	uint32_t update_pending;
+
+	spinlock_t liveshot_enabled_lock;
+	uint32_t liveshot_enabled;
+
+	/* v4l2 subdev */
+	struct v4l2_subdev subdev;
+	struct platform_device *pdev;
+	struct clk *vfe_clk[3];
+	spinlock_t  sd_notify_lock;
+	uint32_t    reconfig_vfe;
+	uint32_t    zsl_mode;
+	spinlock_t  stats_bufq_lock;
+	struct msm_stats_bufq_ctrl stats_ctrl;
+	struct msm_stats_ops stats_ops;
+	unsigned long stats_we_buf_ptr[3];
+	unsigned long stats_af_buf_ptr[3];
+	int num_snap;
+} __packed;
+
+struct vfe_frame_extra {
+	uint32_t	bl_evencol:23;
+	uint32_t	rvd1:9;
+	uint32_t	bl_oddcol:23;
+	uint32_t	rvd2:9;
+
+	uint32_t	d_dbpc_stats_hot:16;
+	uint32_t	d_dbpc_stats_cold:16;
+
+	uint32_t	d_dbpc_stats_0_hot:10;
+	uint32_t	rvd3:6;
+	uint32_t	d_dbpc_stats_0_cold:10;
+	uint32_t	rvd4:6;
+	uint32_t	d_dbpc_stats_1_hot:10;
+	uint32_t	rvd5:6;
+	uint32_t	d_dbpc_stats_1_cold:10;
+	uint32_t	rvd6:6;
+
+	uint32_t	asf_max_edge;
+
+	uint32_t	e_y_wm_pm_stats_0:21;
+	uint32_t	rvd7:11;
+	uint32_t	e_y_wm_pm_stats_1_bl:8;
+	uint32_t	rvd8:8;
+	uint32_t	e_y_wm_pm_stats_1_nl:12;
+	uint32_t	rvd9:4;
+
+	uint32_t	e_cbcr_wm_pm_stats_0:21;
+	uint32_t	rvd10:11;
+	uint32_t	e_cbcr_wm_pm_stats_1_bl:8;
+	uint32_t	rvd11:8;
+	uint32_t	e_cbcr_wm_pm_stats_1_nl:12;
+	uint32_t	rvd12:4;
+
+	uint32_t	v_y_wm_pm_stats_0:21;
+	uint32_t	rvd13:11;
+	uint32_t	v_y_wm_pm_stats_1_bl:8;
+	uint32_t	rvd14:8;
+	uint32_t	v_y_wm_pm_stats_1_nl:12;
+	uint32_t	rvd15:4;
+
+	uint32_t	v_cbcr_wm_pm_stats_0:21;
+	uint32_t	rvd16:11;
+	uint32_t	v_cbcr_wm_pm_stats_1_bl:8;
+	uint32_t	rvd17:8;
+	uint32_t	v_cbcr_wm_pm_stats_1_nl:12;
+	uint32_t	rvd18:4;
+
+	uint32_t      frame_id;
+} __packed;
+
+struct vfe_endframe {
+	uint32_t      y_address;
+	uint32_t      cbcr_address;
+
+	struct vfe_frame_extra extra;
+} __packed;
+
+struct vfe_outputack {
+	uint32_t  header;
+	void      *output2newybufferaddress;
+	void      *output2newcbcrbufferaddress;
+} __packed;
+
+struct vfe_stats_ack {
+	uint32_t header;
+	/* MUST BE 64 bit ALIGNED */
+	void     *bufaddr;
+} __packed;
+
+/* AXI Output Config Command sent to DSP */
+struct axiout {
+	uint32_t            cmdheader:32;
+	int                 outputmode:3;
+	uint8_t             format:2;
+	uint32_t            /* reserved */ : 27;
+
+	/* AXI Output 1 Y Configuration, Part 1 */
+	uint32_t            out1yimageheight:12;
+	uint32_t            /* reserved */ : 4;
+	uint32_t            out1yimagewidthin64bitwords:10;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 1 Y Configuration, Part 2 */
+	uint8_t             out1yburstlen:2;
+	uint32_t            out1ynumrows:12;
+	uint32_t            out1yrowincin64bitincs:12;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 1 CbCr Configuration, Part 1 */
+	uint32_t            out1cbcrimageheight:12;
+	uint32_t            /* reserved */ : 4;
+	uint32_t            out1cbcrimagewidthin64bitwords:10;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 1 CbCr Configuration, Part 2 */
+	uint8_t             out1cbcrburstlen:2;
+	uint32_t            out1cbcrnumrows:12;
+	uint32_t            out1cbcrrowincin64bitincs:12;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 2 Y Configuration, Part 1 */
+	uint32_t            out2yimageheight:12;
+	uint32_t            /* reserved */ : 4;
+	uint32_t            out2yimagewidthin64bitwords:10;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 2 Y Configuration, Part 2 */
+	uint8_t             out2yburstlen:2;
+	uint32_t            out2ynumrows:12;
+	uint32_t            out2yrowincin64bitincs:12;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 2 CbCr Configuration, Part 1 */
+	uint32_t            out2cbcrimageheight:12;
+	uint32_t            /* reserved */ : 4;
+	uint32_t            out2cbcrimagewidtein64bitwords:10;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 2 CbCr Configuration, Part 2 */
+	uint8_t             out2cbcrburstlen:2;
+	uint32_t            out2cbcrnumrows:12;
+	uint32_t            out2cbcrrowincin64bitincs:12;
+	uint32_t            /* reserved */ : 6;
+
+	/* Address configuration:
+	 * output1 phisycal address */
+	unsigned long   output1buffer1_y_phy;
+	unsigned long   output1buffer1_cbcr_phy;
+	unsigned long   output1buffer2_y_phy;
+	unsigned long   output1buffer2_cbcr_phy;
+	unsigned long   output1buffer3_y_phy;
+	unsigned long   output1buffer3_cbcr_phy;
+	unsigned long   output1buffer4_y_phy;
+	unsigned long   output1buffer4_cbcr_phy;
+	unsigned long   output1buffer5_y_phy;
+	unsigned long   output1buffer5_cbcr_phy;
+	unsigned long   output1buffer6_y_phy;
+	unsigned long   output1buffer6_cbcr_phy;
+	unsigned long   output1buffer7_y_phy;
+	unsigned long   output1buffer7_cbcr_phy;
+	unsigned long   output1buffer8_y_phy;
+	unsigned long   output1buffer8_cbcr_phy;
+
+	/* output2 phisycal address */
+	unsigned long   output2buffer1_y_phy;
+	unsigned long   output2buffer1_cbcr_phy;
+	unsigned long   output2buffer2_y_phy;
+	unsigned long   output2buffer2_cbcr_phy;
+	unsigned long   output2buffer3_y_phy;
+	unsigned long   output2buffer3_cbcr_phy;
+	unsigned long   output2buffer4_y_phy;
+	unsigned long   output2buffer4_cbcr_phy;
+	unsigned long   output2buffer5_y_phy;
+	unsigned long   output2buffer5_cbcr_phy;
+	unsigned long   output2buffer6_y_phy;
+	unsigned long   output2buffer6_cbcr_phy;
+	unsigned long   output2buffer7_y_phy;
+	unsigned long   output2buffer7_cbcr_phy;
+	unsigned long   output2buffer8_y_phy;
+	unsigned long   output2buffer8_cbcr_phy;
+} __packed;
+
+struct vfe_stats_we_cfg {
+	uint32_t       header;
+
+	/* White Balance/Exposure Statistic Selection */
+	uint8_t        wb_expstatsenable:1;
+	uint8_t        wb_expstatbuspriorityselection:1;
+	unsigned int   wb_expstatbuspriorityvalue:4;
+	unsigned int   /* reserved */ : 26;
+
+	/* White Balance/Exposure Statistic Configuration, Part 1 */
+	uint8_t        exposurestatregions:1;
+	uint8_t        exposurestatsubregions:1;
+	unsigned int   /* reserved */ : 14;
+
+	unsigned int   whitebalanceminimumy:8;
+	unsigned int   whitebalancemaximumy:8;
+
+	/* White Balance/Exposure Statistic Configuration, Part 2 */
+	uint8_t wb_expstatslopeofneutralregionline[
+		NUM_WB_EXP_NEUTRAL_REGION_LINES];
+
+	/* White Balance/Exposure Statistic Configuration, Part 3 */
+	unsigned int   wb_expstatcrinterceptofneutralregionline2:12;
+	unsigned int   /* reserved */ : 4;
+	unsigned int   wb_expstatcbinterceptofneutralreginnline1:12;
+	unsigned int    /* reserved */ : 4;
+
+	/* White Balance/Exposure Statistic Configuration, Part 4 */
+	unsigned int   wb_expstatcrinterceptofneutralregionline4:12;
+	unsigned int   /* reserved */ : 4;
+	unsigned int   wb_expstatcbinterceptofneutralregionline3:12;
+	unsigned int   /* reserved */ : 4;
+
+	/* White Balance/Exposure Statistic Output Buffer Header */
+	unsigned int   wb_expmetricheaderpattern:8;
+	unsigned int   /* reserved */ : 24;
+
+	/* White Balance/Exposure Statistic Output Buffers-MUST
+	* BE 64 bit ALIGNED */
+	void  *wb_expstatoutputbuffer[NUM_WB_EXP_STAT_OUTPUT_BUFFERS];
+} __packed;
+
+struct vfe_stats_af_cfg {
+	uint32_t header;
+
+	/* Autofocus Statistic Selection */
+	uint8_t       af_enable:1;
+	uint8_t       af_busprioritysel:1;
+	unsigned int  af_buspriorityval:4;
+	unsigned int  /* reserved */ : 26;
+
+	/* Autofocus Statistic Configuration, Part 1 */
+	unsigned int  af_singlewinvoffset:12;
+	unsigned int  /* reserved */ : 4;
+	unsigned int  af_singlewinhoffset:12;
+	unsigned int  /* reserved */ : 3;
+	uint8_t       af_winmode:1;
+
+	/* Autofocus Statistic Configuration, Part 2 */
+	unsigned int  af_singglewinvh:11;
+	unsigned int  /* reserved */ : 5;
+	unsigned int  af_singlewinhw:11;
+	unsigned int  /* reserved */ : 5;
+
+	/* Autofocus Statistic Configuration, Parts 3-6 */
+	uint8_t       af_multiwingrid[NUM_AUTOFOCUS_MULTI_WINDOW_GRIDS];
+
+	/* Autofocus Statistic Configuration, Part 7 */
+	signed int    af_metrichpfcoefa00:5;
+	signed int    af_metrichpfcoefa04:5;
+	unsigned int  af_metricmaxval:11;
+	uint8_t       af_metricsel:1;
+	unsigned int  /* reserved */ : 10;
+
+	/* Autofocus Statistic Configuration, Part 8 */
+	signed int    af_metrichpfcoefa20:5;
+	signed int    af_metrichpfcoefa21:5;
+	signed int    af_metrichpfcoefa22:5;
+	signed int    af_metrichpfcoefa23:5;
+	signed int    af_metrichpfcoefa24:5;
+	unsigned int  /* reserved */ : 7;
+
+	/* Autofocus Statistic Output Buffer Header */
+	unsigned int  af_metrichp:8;
+	unsigned int  /* reserved */ : 24;
+
+	/* Autofocus Statistic Output Buffers - MUST BE 64 bit ALIGNED!!! */
+	void *af_outbuf[NUM_AF_STAT_OUTPUT_BUFFERS];
+} __packed; /* VFE_StatsAutofocusConfigCmdType */
+
+struct msm_camera_frame_msg {
+	unsigned long   output_y_address;
+	unsigned long   output_cbcr_address;
+
+	unsigned int    blacklevelevenColumn:23;
+	uint16_t        reserved1:9;
+	unsigned int    blackleveloddColumn:23;
+	uint16_t        reserved2:9;
+
+	uint16_t        greendefectpixelcount:8;
+	uint16_t        reserved3:8;
+	uint16_t        redbluedefectpixelcount:8;
+	uint16_t        reserved4:8;
+} __packed;
+
+/* New one for 7k */
+struct msm_vfe_command_7k {
+	uint16_t queue;
+	uint16_t length;
+	void     *value;
+};
+
+struct stop_event {
+	wait_queue_head_t wait;
+	int state;
+	int timeout;
+};
+struct vfe_error_msg {
+	unsigned int camif_error:1;
+	unsigned int output1ybusoverflow:1;
+	unsigned int output1cbcrbusoverflow:1;
+	unsigned int output2ybusoverflow:1;
+	unsigned int output2cbcrbusoverflow:1;
+	unsigned int autofocusstatbusoverflow:1;
+	unsigned int wb_expstatbusoverflow:1;
+	unsigned int axierror:1;
+	unsigned int /* reserved */ : 24;
+	unsigned int camif_staus:1;
+	unsigned int pixel_count:14;
+	unsigned int line_count:14;
+	unsigned int /*reserved */ : 3;
+} __packed;
+
+static struct msm_free_buf *vfe2x_check_free_buffer(int id, int path);
+
+#endif /* __MSM_VFE7X_H__ */
diff --git a/drivers/media/platform/msm/camera_v1/vfe/msm_vfe8x.c b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe8x.c
new file mode 100644
index 0000000..953d634
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe8x.c
@@ -0,0 +1,843 @@
+/* Copyright (c) 2009, 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/interrupt.h>
+#include <mach/irqs.h>
+#include "msm_vfe8x_proc.h"
+#include <linux/pm_qos.h>
+
+#define ON  1
+#define OFF 0
+
+static const char *vfe_general_cmd[] = {
+	"START",  /* 0 */
+	"RESET",
+	"AXI_INPUT_CONFIG",
+	"CAMIF_CONFIG",
+	"AXI_OUTPUT_CONFIG",
+	"BLACK_LEVEL_CONFIG",  /* 5 */
+	"ROLL_OFF_CONFIG",
+	"DEMUX_CHANNEL_GAIN_CONFIG",
+	"DEMOSAIC_CONFIG",
+	"FOV_CROP_CONFIG",
+	"MAIN_SCALER_CONFIG",  /* 10 */
+	"WHITE_BALANCE_CONFIG",
+	"COLOR_CORRECTION_CONFIG",
+	"LA_CONFIG",
+	"RGB_GAMMA_CONFIG",
+	"CHROMA_ENHAN_CONFIG",  /* 15 */
+	"CHROMA_SUPPRESSION_CONFIG",
+	"ASF_CONFIG",
+	"SCALER2Y_CONFIG",
+	"SCALER2CbCr_CONFIG",
+	"CHROMA_SUBSAMPLE_CONFIG",  /* 20 */
+	"FRAME_SKIP_CONFIG",
+	"OUTPUT_CLAMP_CONFIG",
+	"TEST_GEN_START",
+	"UPDATE",
+	"OUTPUT1_ACK",  /* 25 */
+	"OUTPUT2_ACK",
+	"EPOCH1_ACK",
+	"EPOCH2_ACK",
+	"STATS_AUTOFOCUS_ACK",
+	"STATS_WB_EXP_ACK",  /* 30 */
+	"BLACK_LEVEL_UPDATE",
+	"DEMUX_CHANNEL_GAIN_UPDATE",
+	"DEMOSAIC_BPC_UPDATE",
+	"DEMOSAIC_ABF_UPDATE",
+	"FOV_CROP_UPDATE",  /* 35 */
+	"WHITE_BALANCE_UPDATE",
+	"COLOR_CORRECTION_UPDATE",
+	"LA_UPDATE",
+	"RGB_GAMMA_UPDATE",
+	"CHROMA_ENHAN_UPDATE",  /* 40 */
+	"CHROMA_SUPPRESSION_UPDATE",
+	"MAIN_SCALER_UPDATE",
+	"SCALER2CbCr_UPDATE",
+	"SCALER2Y_UPDATE",
+	"ASF_UPDATE",  /* 45 */
+	"FRAME_SKIP_UPDATE",
+	"CAMIF_FRAME_UPDATE",
+	"STATS_AUTOFOCUS_UPDATE",
+	"STATS_WB_EXP_UPDATE",
+	"STOP",  /* 50 */
+	"GET_HW_VERSION",
+	"STATS_SETTING",
+	"STATS_AUTOFOCUS_START",
+	"STATS_AUTOFOCUS_STOP",
+	"STATS_WB_EXP_START",  /* 55 */
+	"STATS_WB_EXP_STOP",
+	"ASYNC_TIMER_SETTING",
+};
+
+static void     *vfe_syncdata;
+
+static int vfe_enable(struct camera_enable_cmd *enable)
+{
+	return 0;
+}
+
+static int vfe_disable(struct camera_enable_cmd *enable,
+	struct platform_device *dev)
+{
+	vfe_stop();
+	msm_camio_disable(dev);
+	return 0;
+}
+
+static void vfe_release(struct platform_device *dev)
+{
+	msm_camio_disable(dev);
+	vfe_cmd_release(dev);
+	update_axi_qos(PM_QOS_DEFAULT_VALUE);
+	vfe_syncdata = NULL;
+}
+
+static void vfe_config_axi(int mode,
+			   struct axidata *ad,
+			   struct vfe_cmd_axi_output_config *ao)
+{
+	struct msm_pmem_region *regptr, *regptr1;
+	int i, j;
+	uint32_t *p1, *p2;
+
+	if (mode == OUTPUT_1 || mode == OUTPUT_1_AND_2) {
+		regptr = ad->region;
+		for (i = 0; i < ad->bufnum1; i++) {
+
+			p1 = &(ao->output1.outputY.outFragments[i][0]);
+			p2 = &(ao->output1.outputCbcr.outFragments[i][0]);
+
+			for (j = 0; j < ao->output1.fragmentCount; j++) {
+
+				*p1 = regptr->paddr + regptr->info.planar0_off;
+				p1++;
+
+				*p2 = regptr->paddr + regptr->info.planar1_off;
+				p2++;
+			}
+			regptr++;
+		}
+	} /* if OUTPUT1 or Both */
+
+	if (mode == OUTPUT_2 || mode == OUTPUT_1_AND_2) {
+
+		regptr = &(ad->region[ad->bufnum1]);
+		CDBG("bufnum2 = %d\n", ad->bufnum2);
+
+		for (i = 0; i < ad->bufnum2; i++) {
+
+			p1 = &(ao->output2.outputY.outFragments[i][0]);
+			p2 = &(ao->output2.outputCbcr.outFragments[i][0]);
+
+			CDBG("config_axi: O2, phy = 0x%lx, y_off = %d, "\
+			     "cbcr_off = %d\n", regptr->paddr,
+				regptr->info.planar0_off,
+				regptr->info.planar1_off);
+
+			for (j = 0; j < ao->output2.fragmentCount; j++) {
+
+				*p1 = regptr->paddr + regptr->info.planar0_off;
+				CDBG("vfe_config_axi: p1 = 0x%x\n", *p1);
+				p1++;
+
+				*p2 = regptr->paddr + regptr->info.planar1_off;
+				CDBG("vfe_config_axi: p2 = 0x%x\n", *p2);
+				p2++;
+			}
+			regptr++;
+		}
+	}
+	/* For video configuration */
+	if (mode == OUTPUT_1_AND_3) {
+		/* this is preview buffer. */
+		regptr =  &(ad->region[0]);
+		/* this is video buffer. */
+		regptr1 = &(ad->region[ad->bufnum1]);
+		CDBG("bufnum1 = %d\n", ad->bufnum1);
+		CDBG("bufnum2 = %d\n", ad->bufnum2);
+
+	for (i = 0; i < ad->bufnum1; i++) {
+		p1 = &(ao->output1.outputY.outFragments[i][0]);
+		p2 = &(ao->output1.outputCbcr.outFragments[i][0]);
+
+		CDBG("config_axi: O1, phy = 0x%lx, y_off = %d, "\
+			 "cbcr_off = %d\n", regptr->paddr,
+			 regptr->info.planar0_off, regptr->info.planar1_off);
+
+			for (j = 0; j < ao->output1.fragmentCount; j++) {
+
+				*p1 = regptr->paddr + regptr->info.planar0_off;
+				CDBG("vfe_config_axi: p1 = 0x%x\n", *p1);
+				p1++;
+
+				*p2 = regptr->paddr + regptr->info.planar1_off;
+				CDBG("vfe_config_axi: p2 = 0x%x\n", *p2);
+				p2++;
+			}
+			regptr++;
+		}
+	for (i = 0; i < ad->bufnum2; i++) {
+		p1 = &(ao->output2.outputY.outFragments[i][0]);
+		p2 = &(ao->output2.outputCbcr.outFragments[i][0]);
+
+		CDBG("config_axi: O2, phy = 0x%lx, y_off = %d, "\
+			 "cbcr_off = %d\n", regptr1->paddr,
+			 regptr1->info.planar0_off, regptr1->info.planar1_off);
+
+			for (j = 0; j < ao->output2.fragmentCount; j++) {
+				*p1 = regptr1->paddr +
+					regptr1->info.planar0_off;
+				CDBG("vfe_config_axi: p1 = 0x%x\n", *p1);
+				p1++;
+				*p2 = regptr1->paddr +
+					r1->info.planar1_off;
+				CDBG("vfe_config_axi: p2 = 0x%x\n", *p2);
+				p2++;
+			}
+			regptr1++;
+		}
+	}
+
+}
+
+#define CHECKED_COPY_FROM_USER(in) {					\
+	if (cmd->length != sizeof(*(in))) {				\
+		pr_err("msm_camera: %s:%d cmd %d: user data size %d "	\
+			"!= kernel data size %d\n",			\
+			__func__, __LINE__,				\
+			cmd->id, cmd->length, sizeof(*(in)));		\
+		rc = -EIO;						\
+		break;							\
+	}								\
+	if (copy_from_user((in), (void __user *)cmd->value,		\
+			sizeof(*(in)))) {				\
+		rc = -EFAULT;						\
+		break;							\
+	}								\
+}
+
+static int vfe_proc_general(struct msm_vfe_command_8k *cmd)
+{
+	int rc = 0;
+
+	CDBG("%s: cmdID = %s\n", __func__, vfe_general_cmd[cmd->id]);
+
+	switch (cmd->id) {
+	case VFE_CMD_ID_RESET:
+		msm_camio_vfe_blk_reset();
+		msm_camio_camif_pad_reg_reset_2();
+		vfe_reset();
+		break;
+
+	case VFE_CMD_ID_START: {
+		struct vfe_cmd_start start;
+			CHECKED_COPY_FROM_USER(&start);
+
+		/* msm_camio_camif_pad_reg_reset_2(); */
+		msm_camio_camif_pad_reg_reset();
+		vfe_start(&start);
+	}
+		break;
+
+	case VFE_CMD_ID_CAMIF_CONFIG: {
+		struct vfe_cmd_camif_config camif;
+			CHECKED_COPY_FROM_USER(&camif);
+
+		vfe_camif_config(&camif);
+	}
+		break;
+
+	case VFE_CMD_ID_BLACK_LEVEL_CONFIG: {
+		struct vfe_cmd_black_level_config bl;
+			CHECKED_COPY_FROM_USER(&bl);
+
+		vfe_black_level_config(&bl);
+	}
+		break;
+
+	case VFE_CMD_ID_ROLL_OFF_CONFIG:{
+			/* rolloff is too big to be on the stack */
+			struct vfe_cmd_roll_off_config *rolloff =
+			    kmalloc(sizeof(struct vfe_cmd_roll_off_config),
+				    GFP_KERNEL);
+			if (!rolloff) {
+				pr_err("%s: out of memory\n", __func__);
+				rc = -ENOMEM;
+				break;
+			}
+			/* Wrap CHECKED_COPY_FROM_USER() in a do-while(0) loop
+			 * to make sure we free rolloff when copy_from_user()
+			 * fails.
+			 */
+			do {
+				CHECKED_COPY_FROM_USER(rolloff);
+				vfe_roll_off_config(rolloff);
+			} while (0);
+			kfree(rolloff);
+	}
+		break;
+
+	case VFE_CMD_ID_DEMUX_CHANNEL_GAIN_CONFIG: {
+		struct vfe_cmd_demux_channel_gain_config demuxc;
+			CHECKED_COPY_FROM_USER(&demuxc);
+
+		/* demux is always enabled.  */
+		vfe_demux_channel_gain_config(&demuxc);
+	}
+		break;
+
+	case VFE_CMD_ID_DEMOSAIC_CONFIG: {
+		struct vfe_cmd_demosaic_config demosaic;
+			CHECKED_COPY_FROM_USER(&demosaic);
+
+		vfe_demosaic_config(&demosaic);
+	}
+		break;
+
+	case VFE_CMD_ID_FOV_CROP_CONFIG:
+	case VFE_CMD_ID_FOV_CROP_UPDATE: {
+		struct vfe_cmd_fov_crop_config fov;
+			CHECKED_COPY_FROM_USER(&fov);
+
+		vfe_fov_crop_config(&fov);
+	}
+		break;
+
+	case VFE_CMD_ID_MAIN_SCALER_CONFIG:
+	case VFE_CMD_ID_MAIN_SCALER_UPDATE: {
+		struct vfe_cmd_main_scaler_config mainds;
+			CHECKED_COPY_FROM_USER(&mainds);
+
+		vfe_main_scaler_config(&mainds);
+	}
+		break;
+
+	case VFE_CMD_ID_WHITE_BALANCE_CONFIG:
+	case VFE_CMD_ID_WHITE_BALANCE_UPDATE: {
+		struct vfe_cmd_white_balance_config wb;
+			CHECKED_COPY_FROM_USER(&wb);
+
+		vfe_white_balance_config(&wb);
+	}
+		break;
+
+	case VFE_CMD_ID_COLOR_CORRECTION_CONFIG:
+	case VFE_CMD_ID_COLOR_CORRECTION_UPDATE: {
+		struct vfe_cmd_color_correction_config cc;
+			CHECKED_COPY_FROM_USER(&cc);
+
+		vfe_color_correction_config(&cc);
+	}
+		break;
+
+	case VFE_CMD_ID_LA_CONFIG: {
+		struct vfe_cmd_la_config la;
+			CHECKED_COPY_FROM_USER(&la);
+
+		vfe_la_config(&la);
+	}
+		break;
+
+	case VFE_CMD_ID_RGB_GAMMA_CONFIG: {
+		struct vfe_cmd_rgb_gamma_config rgb;
+			CHECKED_COPY_FROM_USER(&rgb);
+
+		rc = vfe_rgb_gamma_config(&rgb);
+	}
+		break;
+
+	case VFE_CMD_ID_CHROMA_ENHAN_CONFIG:
+	case VFE_CMD_ID_CHROMA_ENHAN_UPDATE: {
+		struct vfe_cmd_chroma_enhan_config chrom;
+			CHECKED_COPY_FROM_USER(&chrom);
+
+		vfe_chroma_enhan_config(&chrom);
+	}
+		break;
+
+	case VFE_CMD_ID_CHROMA_SUPPRESSION_CONFIG:
+	case VFE_CMD_ID_CHROMA_SUPPRESSION_UPDATE: {
+		struct vfe_cmd_chroma_suppression_config chromsup;
+			CHECKED_COPY_FROM_USER(&chromsup);
+
+		vfe_chroma_sup_config(&chromsup);
+	}
+		break;
+
+	case VFE_CMD_ID_ASF_CONFIG: {
+		struct vfe_cmd_asf_config asf;
+			CHECKED_COPY_FROM_USER(&asf);
+
+		vfe_asf_config(&asf);
+	}
+		break;
+
+	case VFE_CMD_ID_SCALER2Y_CONFIG:
+	case VFE_CMD_ID_SCALER2Y_UPDATE: {
+		struct vfe_cmd_scaler2_config ds2y;
+			CHECKED_COPY_FROM_USER(&ds2y);
+
+		vfe_scaler2y_config(&ds2y);
+	}
+		break;
+
+	case VFE_CMD_ID_SCALER2CbCr_CONFIG:
+	case VFE_CMD_ID_SCALER2CbCr_UPDATE: {
+		struct vfe_cmd_scaler2_config ds2cbcr;
+			CHECKED_COPY_FROM_USER(&ds2cbcr);
+
+		vfe_scaler2cbcr_config(&ds2cbcr);
+	}
+		break;
+
+	case VFE_CMD_ID_CHROMA_SUBSAMPLE_CONFIG: {
+		struct vfe_cmd_chroma_subsample_config sub;
+			CHECKED_COPY_FROM_USER(&sub);
+
+		vfe_chroma_subsample_config(&sub);
+	}
+		break;
+
+	case VFE_CMD_ID_FRAME_SKIP_CONFIG: {
+		struct vfe_cmd_frame_skip_config fskip;
+			CHECKED_COPY_FROM_USER(&fskip);
+
+		vfe_frame_skip_config(&fskip);
+	}
+		break;
+
+	case VFE_CMD_ID_OUTPUT_CLAMP_CONFIG: {
+		struct vfe_cmd_output_clamp_config clamp;
+			CHECKED_COPY_FROM_USER(&clamp);
+
+		vfe_output_clamp_config(&clamp);
+	}
+		break;
+
+	/* module update commands */
+	case VFE_CMD_ID_BLACK_LEVEL_UPDATE: {
+		struct vfe_cmd_black_level_config blk;
+			CHECKED_COPY_FROM_USER(&blk);
+
+		vfe_black_level_update(&blk);
+	}
+		break;
+
+	case VFE_CMD_ID_DEMUX_CHANNEL_GAIN_UPDATE: {
+		struct vfe_cmd_demux_channel_gain_config dmu;
+			CHECKED_COPY_FROM_USER(&dmu);
+
+		vfe_demux_channel_gain_update(&dmu);
+	}
+		break;
+
+	case VFE_CMD_ID_DEMOSAIC_BPC_UPDATE: {
+		struct vfe_cmd_demosaic_bpc_update demo_bpc;
+			CHECKED_COPY_FROM_USER(&demo_bpc);
+
+		vfe_demosaic_bpc_update(&demo_bpc);
+	}
+		break;
+
+	case VFE_CMD_ID_DEMOSAIC_ABF_UPDATE: {
+		struct vfe_cmd_demosaic_abf_update demo_abf;
+			CHECKED_COPY_FROM_USER(&demo_abf);
+
+		vfe_demosaic_abf_update(&demo_abf);
+	}
+		break;
+
+	case VFE_CMD_ID_LA_UPDATE: {
+		struct vfe_cmd_la_config la;
+			CHECKED_COPY_FROM_USER(&la);
+
+		vfe_la_update(&la);
+	}
+		break;
+
+	case VFE_CMD_ID_RGB_GAMMA_UPDATE: {
+		struct vfe_cmd_rgb_gamma_config rgb;
+			CHECKED_COPY_FROM_USER(&rgb);
+
+		rc = vfe_rgb_gamma_update(&rgb);
+	}
+		break;
+
+	case VFE_CMD_ID_ASF_UPDATE: {
+		struct vfe_cmd_asf_update asf;
+			CHECKED_COPY_FROM_USER(&asf);
+
+		vfe_asf_update(&asf);
+	}
+		break;
+
+	case VFE_CMD_ID_FRAME_SKIP_UPDATE: {
+		struct vfe_cmd_frame_skip_update fskip;
+			CHECKED_COPY_FROM_USER(&fskip);
+			/* Start recording */
+			if (fskip.output2Pattern == 0xffffffff)
+				update_axi_qos(MSM_AXI_QOS_RECORDING);
+			 else if (fskip.output2Pattern == 0)
+				update_axi_qos(MSM_AXI_QOS_PREVIEW);
+
+		vfe_frame_skip_update(&fskip);
+	}
+		break;
+
+	case VFE_CMD_ID_CAMIF_FRAME_UPDATE: {
+		struct vfe_cmds_camif_frame fup;
+			CHECKED_COPY_FROM_USER(&fup);
+
+		vfe_camif_frame_update(&fup);
+	}
+		break;
+
+	/* stats update commands */
+	case VFE_CMD_ID_STATS_AUTOFOCUS_UPDATE: {
+		struct vfe_cmd_stats_af_update afup;
+			CHECKED_COPY_FROM_USER(&afup);
+
+		vfe_stats_update_af(&afup);
+	}
+		break;
+
+	case VFE_CMD_ID_STATS_WB_EXP_UPDATE: {
+		struct vfe_cmd_stats_wb_exp_update wbexp;
+			CHECKED_COPY_FROM_USER(&wbexp);
+
+		vfe_stats_update_wb_exp(&wbexp);
+	}
+		break;
+
+	/* control of start, stop, update, etc... */
+	case VFE_CMD_ID_STOP:
+		vfe_stop();
+		break;
+
+	case VFE_CMD_ID_GET_HW_VERSION:
+		break;
+
+	/* stats */
+	case VFE_CMD_ID_STATS_SETTING: {
+		struct vfe_cmd_stats_setting stats;
+			CHECKED_COPY_FROM_USER(&stats);
+
+		vfe_stats_setting(&stats);
+	}
+		break;
+
+	case VFE_CMD_ID_STATS_AUTOFOCUS_START: {
+		struct vfe_cmd_stats_af_start af;
+			CHECKED_COPY_FROM_USER(&af);
+
+		vfe_stats_start_af(&af);
+	}
+		break;
+
+	case VFE_CMD_ID_STATS_AUTOFOCUS_STOP:
+		vfe_stats_af_stop();
+		break;
+
+	case VFE_CMD_ID_STATS_WB_EXP_START: {
+		struct vfe_cmd_stats_wb_exp_start awexp;
+			CHECKED_COPY_FROM_USER(&awexp);
+
+		vfe_stats_start_wb_exp(&awexp);
+	}
+		break;
+
+	case VFE_CMD_ID_STATS_WB_EXP_STOP:
+		vfe_stats_wb_exp_stop();
+		break;
+
+	case VFE_CMD_ID_ASYNC_TIMER_SETTING:
+		break;
+
+	case VFE_CMD_ID_UPDATE:
+		vfe_update();
+		break;
+
+	/* test gen */
+	case VFE_CMD_ID_TEST_GEN_START:
+		break;
+
+/*
+  acknowledge from upper layer
+	these are not in general command.
+
+	case VFE_CMD_ID_OUTPUT1_ACK:
+		break;
+	case VFE_CMD_ID_OUTPUT2_ACK:
+		break;
+	case VFE_CMD_ID_EPOCH1_ACK:
+		break;
+	case VFE_CMD_ID_EPOCH2_ACK:
+		break;
+	case VFE_CMD_ID_STATS_AUTOFOCUS_ACK:
+		break;
+	case VFE_CMD_ID_STATS_WB_EXP_ACK:
+		break;
+*/
+
+	default:
+		pr_err("%s: invalid cmd id %d\n", __func__, cmd->id);
+		rc = -EINVAL;
+		break;
+	} /* switch */
+
+	return rc;
+}
+
+static int vfe_config(struct msm_vfe_cfg_cmd *cmd, void *data)
+{
+	struct msm_pmem_region *regptr;
+	struct msm_vfe_command_8k vfecmd;
+	struct vfe_cmd_axi_output_config axio;
+	struct axidata *axid = data;
+
+	int rc = 0;
+
+
+	if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_BUF_RELEASE &&
+		cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE) {
+
+		if (copy_from_user(&vfecmd,
+			(void __user *)(cmd->value), sizeof(vfecmd))) {
+			pr_err("%s %d: copy_from_user failed\n",
+				__func__, __LINE__);
+			return -EFAULT;
+		}
+	}
+
+	CDBG("%s: cmdType = %d\n", __func__, cmd->cmd_type);
+
+	switch (cmd->cmd_type) {
+	case CMD_GENERAL:
+		rc = vfe_proc_general(&vfecmd);
+		break;
+
+	case CMD_STATS_ENABLE:
+	case CMD_STATS_AXI_CFG: {
+			int i;
+			struct vfe_cmd_stats_setting scfg;
+
+			BUG_ON(!axid);
+
+			if (vfecmd.length != sizeof(scfg)) {
+				pr_err
+				("msm_camera: %s: cmd %d: user-space "\
+				"data size %d != kernel data size %d\n",
+				__func__,
+				cmd->cmd_type, vfecmd.length,
+				sizeof(scfg));
+				return -EIO;
+			}
+
+			if (copy_from_user(&scfg,
+				(void __user *)(vfecmd.value),
+				sizeof(scfg))) {
+				pr_err("%s %d: copy_from_user failed\n",
+				__func__, __LINE__);
+			return -EFAULT;
+		}
+
+		regptr = axid->region;
+		if (axid->bufnum1 > 0) {
+			for (i = 0; i < axid->bufnum1; i++) {
+					scfg.awbBuffer[i] =
+					(uint32_t)(regptr->paddr);
+				regptr++;
+			}
+		}
+
+		if (axid->bufnum2 > 0) {
+			for (i = 0; i < axid->bufnum2; i++) {
+					scfg.afBuffer[i] =
+					(uint32_t)(regptr->paddr);
+				regptr++;
+			}
+		}
+
+			vfe_stats_setting(&scfg);
+	}
+		break;
+
+	case CMD_STATS_AF_AXI_CFG:
+		break;
+
+	case CMD_FRAME_BUF_RELEASE: {
+		/* preview buffer release */
+		struct msm_frame *b;
+		unsigned long p;
+		struct vfe_cmd_output_ack fack;
+
+			BUG_ON(!data);
+
+		b = (struct msm_frame *)(cmd->value);
+		p = *(unsigned long *)data;
+
+			fack.ybufaddr[0] = (uint32_t) (p + b->planar0_off);
+
+			fack.chromabufaddr[0] = (uint32_t) (p + b->planar1_off);
+
+		if (b->path == OUTPUT_TYPE_P)
+			vfe_output_p_ack(&fack);
+
+		if ((b->path == OUTPUT_TYPE_V)
+			 || (b->path == OUTPUT_TYPE_S))
+			vfe_output_v_ack(&fack);
+	}
+		break;
+
+	case CMD_SNAP_BUF_RELEASE:
+		break;
+
+	case CMD_STATS_BUF_RELEASE: {
+		struct vfe_cmd_stats_wb_exp_ack sack;
+
+			BUG_ON(!data);
+
+		sack.nextWbExpOutputBufferAddr = *(uint32_t *)data;
+		vfe_stats_wb_exp_ack(&sack);
+	}
+		break;
+
+	case CMD_STATS_AF_BUF_RELEASE: {
+		struct vfe_cmd_stats_af_ack ack;
+
+			BUG_ON(!data);
+
+		ack.nextAFOutputBufferAddr = *(uint32_t *)data;
+		vfe_stats_af_ack(&ack);
+	}
+		break;
+
+	case CMD_AXI_CFG_PREVIEW:
+	case CMD_RAW_PICT_AXI_CFG: {
+
+			BUG_ON(!axid);
+
+			if (copy_from_user(&axio, (void __user *)(vfecmd.value),
+				sizeof(axio))) {
+				pr_err("%s %d: copy_from_user failed\n",
+					__func__, __LINE__);
+			return -EFAULT;
+		}
+			/* Validate the data from user space */
+			if (axio.output2.fragmentCount <
+				VFE_MIN_NUM_FRAGMENTS_PER_FRAME ||
+				axio.output2.fragmentCount >
+				VFE_MAX_NUM_FRAGMENTS_PER_FRAME)
+				return -EINVAL;
+
+			vfe_config_axi(OUTPUT_2, axid, &axio);
+			axio.outputDataSize = 0;
+			vfe_axi_output_config(&axio);
+	}
+		break;
+
+	case CMD_AXI_CFG_SNAP: {
+
+			BUG_ON(!axid);
+
+			if (copy_from_user(&axio, (void __user *)(vfecmd.value),
+				sizeof(axio))) {
+				pr_err("%s %d: copy_from_user failed\n",
+					__func__, __LINE__);
+			return -EFAULT;
+		}
+			/* Validate the data from user space */
+			if (axio.output1.fragmentCount <
+				VFE_MIN_NUM_FRAGMENTS_PER_FRAME ||
+				axio.output1.fragmentCount >
+				VFE_MAX_NUM_FRAGMENTS_PER_FRAME ||
+				axio.output2.fragmentCount <
+				VFE_MIN_NUM_FRAGMENTS_PER_FRAME ||
+				axio.output2.fragmentCount >
+				VFE_MAX_NUM_FRAGMENTS_PER_FRAME)
+				return -EINVAL;
+
+			vfe_config_axi(OUTPUT_1_AND_2, axid, &axio);
+			vfe_axi_output_config(&axio);
+	}
+		break;
+
+	case CMD_AXI_CFG_VIDEO: {
+			BUG_ON(!axid);
+
+			if (copy_from_user(&axio, (void __user *)(vfecmd.value),
+				sizeof(axio))) {
+				pr_err("%s %d: copy_from_user failed\n",
+					__func__, __LINE__);
+			return -EFAULT;
+		}
+			/* Validate the data from user space */
+			if (axio.output1.fragmentCount <
+				VFE_MIN_NUM_FRAGMENTS_PER_FRAME ||
+				axio.output1.fragmentCount >
+				VFE_MAX_NUM_FRAGMENTS_PER_FRAME ||
+				axio.output2.fragmentCount <
+				VFE_MIN_NUM_FRAGMENTS_PER_FRAME ||
+				axio.output2.fragmentCount >
+				VFE_MAX_NUM_FRAGMENTS_PER_FRAME)
+				return -EINVAL;
+
+			vfe_config_axi(OUTPUT_1_AND_3, axid, &axio);
+			axio.outputDataSize = 0;
+			vfe_axi_output_config(&axio);
+	}
+		break;
+
+	default:
+		break;
+	} /* switch */
+
+	return rc;
+}
+
+static int vfe_init(struct msm_vfe_callback *presp, struct platform_device *dev)
+{
+	int rc = 0;
+
+	rc = vfe_cmd_init(presp, dev, vfe_syncdata);
+	if (rc < 0)
+		return rc;
+
+	/* Bring up all the required GPIOs and Clocks */
+	rc = msm_camio_enable(dev);
+
+	return rc;
+}
+
+void msm_camvfe_fn_init(struct msm_camvfe_fn *fptr, void *data)
+{
+	fptr->vfe_init    = vfe_init;
+	fptr->vfe_enable  = vfe_enable;
+	fptr->vfe_config  = vfe_config;
+	fptr->vfe_disable = vfe_disable;
+	fptr->vfe_release = vfe_release;
+	vfe_syncdata = data;
+}
+
+void msm_camvpe_fn_init(struct msm_camvpe_fn *fptr, void *data)
+{
+	fptr->vpe_reg		= NULL;
+	fptr->send_frame_to_vpe	= NULL;
+	fptr->vpe_config	= NULL;
+	fptr->vpe_cfg_update	= NULL;
+	fptr->dis		= NULL;
+}
diff --git a/drivers/media/platform/msm/camera_v1/vfe/msm_vfe8x.h b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe8x.h
new file mode 100644
index 0000000..54e9c95
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe8x.h
@@ -0,0 +1,909 @@
+/* Copyright (c) 2009, 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 __MSM_VFE8X_H__
+#define __MSM_VFE8X_H__
+
+#define TRUE  1
+#define FALSE 0
+#define boolean uint8_t
+
+enum  VFE_STATE {
+	VFE_STATE_IDLE,
+	VFE_STATE_ACTIVE
+};
+
+enum vfe_cmd_id {
+	/*
+	*Important! Command_ID are arranged in order.
+	*Don't change!*/
+	VFE_CMD_ID_START,
+	VFE_CMD_ID_RESET,
+
+	/* bus and camif config */
+	VFE_CMD_ID_AXI_INPUT_CONFIG,
+	VFE_CMD_ID_CAMIF_CONFIG,
+	VFE_CMD_ID_AXI_OUTPUT_CONFIG,
+
+	/* module config  */
+	VFE_CMD_ID_BLACK_LEVEL_CONFIG,
+	VFE_CMD_ID_ROLL_OFF_CONFIG,
+	VFE_CMD_ID_DEMUX_CHANNEL_GAIN_CONFIG,
+	VFE_CMD_ID_DEMOSAIC_CONFIG,
+	VFE_CMD_ID_FOV_CROP_CONFIG,
+	VFE_CMD_ID_MAIN_SCALER_CONFIG,
+	VFE_CMD_ID_WHITE_BALANCE_CONFIG,
+	VFE_CMD_ID_COLOR_CORRECTION_CONFIG,
+	VFE_CMD_ID_LA_CONFIG,
+	VFE_CMD_ID_RGB_GAMMA_CONFIG,
+	VFE_CMD_ID_CHROMA_ENHAN_CONFIG,
+	VFE_CMD_ID_CHROMA_SUPPRESSION_CONFIG,
+	VFE_CMD_ID_ASF_CONFIG,
+	VFE_CMD_ID_SCALER2Y_CONFIG,
+	VFE_CMD_ID_SCALER2CbCr_CONFIG,
+	VFE_CMD_ID_CHROMA_SUBSAMPLE_CONFIG,
+	VFE_CMD_ID_FRAME_SKIP_CONFIG,
+	VFE_CMD_ID_OUTPUT_CLAMP_CONFIG,
+
+	/* test gen */
+	VFE_CMD_ID_TEST_GEN_START,
+
+	VFE_CMD_ID_UPDATE,
+
+	/* ackownledge from upper layer */
+	VFE_CMD_ID_OUTPUT1_ACK,
+	VFE_CMD_ID_OUTPUT2_ACK,
+	VFE_CMD_ID_EPOCH1_ACK,
+	VFE_CMD_ID_EPOCH2_ACK,
+	VFE_CMD_ID_STATS_AUTOFOCUS_ACK,
+	VFE_CMD_ID_STATS_WB_EXP_ACK,
+
+	/* module update commands */
+	VFE_CMD_ID_BLACK_LEVEL_UPDATE,
+	VFE_CMD_ID_DEMUX_CHANNEL_GAIN_UPDATE,
+	VFE_CMD_ID_DEMOSAIC_BPC_UPDATE,
+	VFE_CMD_ID_DEMOSAIC_ABF_UPDATE,
+	VFE_CMD_ID_FOV_CROP_UPDATE,
+	VFE_CMD_ID_WHITE_BALANCE_UPDATE,
+	VFE_CMD_ID_COLOR_CORRECTION_UPDATE,
+	VFE_CMD_ID_LA_UPDATE,
+	VFE_CMD_ID_RGB_GAMMA_UPDATE,
+	VFE_CMD_ID_CHROMA_ENHAN_UPDATE,
+	VFE_CMD_ID_CHROMA_SUPPRESSION_UPDATE,
+	VFE_CMD_ID_MAIN_SCALER_UPDATE,
+	VFE_CMD_ID_SCALER2CbCr_UPDATE,
+	VFE_CMD_ID_SCALER2Y_UPDATE,
+	VFE_CMD_ID_ASF_UPDATE,
+	VFE_CMD_ID_FRAME_SKIP_UPDATE,
+	VFE_CMD_ID_CAMIF_FRAME_UPDATE,
+
+	/* stats update commands */
+	VFE_CMD_ID_STATS_AUTOFOCUS_UPDATE,
+	VFE_CMD_ID_STATS_WB_EXP_UPDATE,
+
+	/* control of start, stop, update, etc... */
+  VFE_CMD_ID_STOP,
+	VFE_CMD_ID_GET_HW_VERSION,
+
+	/* stats */
+	VFE_CMD_ID_STATS_SETTING,
+	VFE_CMD_ID_STATS_AUTOFOCUS_START,
+	VFE_CMD_ID_STATS_AUTOFOCUS_STOP,
+	VFE_CMD_ID_STATS_WB_EXP_START,
+	VFE_CMD_ID_STATS_WB_EXP_STOP,
+
+	VFE_CMD_ID_ASYNC_TIMER_SETTING,
+
+	/* max id  */
+	VFE_CMD_ID_MAX
+};
+
+struct vfe_cmd_hw_version {
+	uint32_t minorVersion;
+	uint32_t majorVersion;
+	uint32_t coreVersion;
+};
+
+enum VFE_CAMIF_SYNC_EDGE {
+	VFE_CAMIF_SYNC_EDGE_ActiveHigh,
+	VFE_CAMIF_SYNC_EDGE_ActiveLow
+};
+
+enum VFE_CAMIF_SYNC_MODE {
+	VFE_CAMIF_SYNC_MODE_APS,
+	VFE_CAMIF_SYNC_MODE_EFS,
+	VFE_CAMIF_SYNC_MODE_ELS,
+	VFE_CAMIF_SYNC_MODE_ILLEGAL
+};
+
+struct vfe_cmds_camif_efs {
+	uint8_t efsendofline;
+	uint8_t efsstartofline;
+	uint8_t efsendofframe;
+	uint8_t efsstartofframe;
+};
+
+struct vfe_cmds_camif_frame {
+	uint16_t pixelsPerLine;
+	uint16_t linesPerFrame;
+};
+
+struct vfe_cmds_camif_window {
+	uint16_t firstpixel;
+	uint16_t lastpixel;
+	uint16_t firstline;
+	uint16_t lastline;
+};
+
+enum CAMIF_SUBSAMPLE_FRAME_SKIP {
+	CAMIF_SUBSAMPLE_FRAME_SKIP_0,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_AllFrames,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_2Frame,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_3Frame,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_4Frame,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_5Frame,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_6Frame,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_7Frame,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_8Frame,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_9Frame,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_10Frame,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_11Frame,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_12Frame,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_13Frame,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_14Frame,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_15Frame
+};
+
+struct vfe_cmds_camif_subsample {
+	uint16_t pixelskipmask;
+	uint16_t lineskipmask;
+	enum CAMIF_SUBSAMPLE_FRAME_SKIP frameskip;
+	uint8_t frameskipmode;
+	uint8_t pixelskipwrap;
+};
+
+struct vfe_cmds_camif_epoch {
+	uint8_t  enable;
+	uint16_t lineindex;
+};
+
+struct vfe_cmds_camif_cfg {
+	enum VFE_CAMIF_SYNC_EDGE  vSyncEdge;
+	enum VFE_CAMIF_SYNC_EDGE  hSyncEdge;
+	enum VFE_CAMIF_SYNC_MODE  syncMode;
+	uint8_t vfeSubSampleEnable;
+	uint8_t busSubSampleEnable;
+	uint8_t irqSubSampleEnable;
+	uint8_t binningEnable;
+	uint8_t misrEnable;
+};
+
+struct vfe_cmd_camif_config {
+	struct vfe_cmds_camif_cfg camifConfig;
+	struct vfe_cmds_camif_efs EFS;
+	struct vfe_cmds_camif_frame     frame;
+	struct vfe_cmds_camif_window    window;
+	struct vfe_cmds_camif_subsample subsample;
+	struct vfe_cmds_camif_epoch     epoch1;
+	struct vfe_cmds_camif_epoch     epoch2;
+};
+
+enum VFE_AXI_OUTPUT_MODE {
+	VFE_AXI_OUTPUT_MODE_Output1,
+	VFE_AXI_OUTPUT_MODE_Output2,
+	VFE_AXI_OUTPUT_MODE_Output1AndOutput2,
+	VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2,
+	VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1,
+	VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2,
+	VFE_AXI_LAST_OUTPUT_MODE_ENUM
+};
+
+enum VFE_RAW_WR_PATH_SEL {
+	VFE_RAW_OUTPUT_DISABLED,
+	VFE_RAW_OUTPUT_ENC_CBCR_PATH,
+	VFE_RAW_OUTPUT_VIEW_CBCR_PATH,
+	VFE_RAW_OUTPUT_PATH_INVALID
+};
+
+enum VFE_RAW_PIXEL_DATA_SIZE {
+	VFE_RAW_PIXEL_DATA_SIZE_8BIT,
+	VFE_RAW_PIXEL_DATA_SIZE_10BIT,
+	VFE_RAW_PIXEL_DATA_SIZE_12BIT,
+};
+
+#define VFE_AXI_OUTPUT_BURST_LENGTH     4
+#define VFE_MAX_NUM_FRAGMENTS_PER_FRAME 4
+#define VFE_MIN_NUM_FRAGMENTS_PER_FRAME 1
+#define VFE_AXI_OUTPUT_CFG_FRAME_COUNT  3
+
+struct vfe_cmds_axi_out_per_component {
+	uint16_t imageWidth;
+	uint16_t imageHeight;
+	uint16_t outRowCount;
+	uint16_t outRowIncrement;
+	uint32_t outFragments[VFE_AXI_OUTPUT_CFG_FRAME_COUNT]
+		[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
+};
+
+struct vfe_cmds_axi_per_output_path {
+	uint8_t fragmentCount;
+	struct vfe_cmds_axi_out_per_component outputY;
+	struct vfe_cmds_axi_out_per_component outputCbcr;
+};
+
+enum VFE_AXI_BURST_LENGTH {
+	VFE_AXI_BURST_LENGTH_IS_2  = 2,
+	VFE_AXI_BURST_LENGTH_IS_4  = 4,
+	VFE_AXI_BURST_LENGTH_IS_8  = 8,
+	VFE_AXI_BURST_LENGTH_IS_16 = 16
+};
+
+struct vfe_cmd_axi_output_config {
+	enum VFE_AXI_BURST_LENGTH burstLength;
+	enum VFE_AXI_OUTPUT_MODE outputMode;
+	enum VFE_RAW_PIXEL_DATA_SIZE outputDataSize;
+	struct vfe_cmds_axi_per_output_path output1;
+	struct vfe_cmds_axi_per_output_path output2;
+};
+
+struct vfe_cmd_fov_crop_config {
+	uint8_t enable;
+	uint16_t firstPixel;
+	uint16_t lastPixel;
+	uint16_t firstLine;
+	uint16_t lastLine;
+};
+
+struct vfe_cmds_main_scaler_stripe_init {
+	uint16_t MNCounterInit;
+	uint16_t phaseInit;
+};
+
+struct vfe_cmds_scaler_one_dimension {
+	uint8_t  enable;
+	uint16_t inputSize;
+	uint16_t outputSize;
+	uint32_t phaseMultiplicationFactor;
+	uint8_t  interpolationResolution;
+};
+
+struct vfe_cmd_main_scaler_config {
+	uint8_t enable;
+	struct vfe_cmds_scaler_one_dimension    hconfig;
+	struct vfe_cmds_scaler_one_dimension    vconfig;
+	struct vfe_cmds_main_scaler_stripe_init MNInitH;
+	struct vfe_cmds_main_scaler_stripe_init MNInitV;
+};
+
+struct vfe_cmd_scaler2_config {
+	uint8_t enable;
+	struct vfe_cmds_scaler_one_dimension hconfig;
+	struct vfe_cmds_scaler_one_dimension vconfig;
+};
+
+struct vfe_cmd_frame_skip_config {
+	uint8_t output1Period;
+	uint32_t output1Pattern;
+	uint8_t output2Period;
+	uint32_t output2Pattern;
+};
+
+struct vfe_cmd_frame_skip_update {
+	uint32_t output1Pattern;
+	uint32_t output2Pattern;
+};
+
+struct vfe_cmd_output_clamp_config {
+	uint8_t minCh0;
+	uint8_t minCh1;
+	uint8_t minCh2;
+	uint8_t maxCh0;
+	uint8_t maxCh1;
+	uint8_t maxCh2;
+};
+
+struct vfe_cmd_chroma_subsample_config {
+	uint8_t enable;
+	uint8_t cropEnable;
+	uint8_t vsubSampleEnable;
+	uint8_t hsubSampleEnable;
+	uint8_t vCosited;
+	uint8_t hCosited;
+	uint8_t vCositedPhase;
+	uint8_t hCositedPhase;
+	uint16_t cropWidthFirstPixel;
+	uint16_t cropWidthLastPixel;
+	uint16_t cropHeightFirstLine;
+	uint16_t cropHeightLastLine;
+};
+
+enum VFE_START_INPUT_SOURCE {
+	VFE_START_INPUT_SOURCE_CAMIF,
+	VFE_START_INPUT_SOURCE_TESTGEN,
+	VFE_START_INPUT_SOURCE_AXI,
+	VFE_START_INPUT_SOURCE_INVALID
+};
+
+enum VFE_START_OPERATION_MODE {
+	VFE_START_OPERATION_MODE_CONTINUOUS,
+	VFE_START_OPERATION_MODE_SNAPSHOT
+};
+
+enum VFE_START_PIXEL_PATTERN {
+	VFE_BAYER_RGRGRG,
+	VFE_BAYER_GRGRGR,
+	VFE_BAYER_BGBGBG,
+	VFE_BAYER_GBGBGB,
+	VFE_YUV_YCbYCr,
+	VFE_YUV_YCrYCb,
+	VFE_YUV_CbYCrY,
+	VFE_YUV_CrYCbY
+};
+
+enum VFE_BUS_RD_INPUT_PIXEL_PATTERN {
+	VFE_BAYER_RAW,
+	VFE_YUV_INTERLEAVED,
+	VFE_YUV_PSEUDO_PLANAR_Y,
+	VFE_YUV_PSEUDO_PLANAR_CBCR
+};
+
+enum VFE_YUV_INPUT_COSITING_MODE {
+	VFE_YUV_COSITED,
+	VFE_YUV_INTERPOLATED
+};
+
+struct vfe_cmd_start {
+	enum VFE_START_INPUT_SOURCE inputSource;
+	enum VFE_START_OPERATION_MODE operationMode;
+	uint8_t     snapshotCount;
+	enum VFE_START_PIXEL_PATTERN pixel;
+	enum VFE_YUV_INPUT_COSITING_MODE yuvInputCositingMode;
+};
+
+struct vfe_cmd_output_ack {
+	uint32_t ybufaddr[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
+	uint32_t chromabufaddr[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
+};
+
+#define VFE_STATS_BUFFER_COUNT 3
+
+struct vfe_cmd_stats_setting {
+	uint16_t frameHDimension;
+	uint16_t frameVDimension;
+	uint8_t  afBusPrioritySelection;
+	uint8_t  afBusPriority;
+	uint8_t  awbBusPrioritySelection;
+	uint8_t  awbBusPriority;
+	uint8_t  histBusPrioritySelection;
+	uint8_t  histBusPriority;
+	uint32_t afBuffer[VFE_STATS_BUFFER_COUNT];
+	uint32_t awbBuffer[VFE_STATS_BUFFER_COUNT];
+	uint32_t histBuffer[VFE_STATS_BUFFER_COUNT];
+};
+
+struct vfe_cmd_stats_af_start {
+	uint8_t  enable;
+	uint8_t  windowMode;
+	uint16_t windowHOffset;
+	uint16_t windowVOffset;
+	uint16_t windowWidth;
+	uint16_t windowHeight;
+	uint8_t  gridForMultiWindows[16];
+	uint8_t     metricSelection;
+	int16_t  metricMax;
+	int8_t   highPassCoef[7];
+	int8_t   bufferHeader;
+};
+
+struct vfe_cmd_stats_af_update {
+	uint8_t  windowMode;
+	uint16_t windowHOffset;
+	uint16_t windowVOffset;
+	uint16_t windowWidth;
+	uint16_t windowHeight;
+};
+
+struct vfe_cmd_stats_wb_exp_start {
+	uint8_t   enable;
+	uint8_t   wbExpRegions;
+	uint8_t   wbExpSubRegion;
+	uint8_t   awbYMin;
+	uint8_t   awbYMax;
+	int8_t    awbMCFG[4];
+	int16_t   awbCCFG[4];
+	int8_t    axwHeader;
+};
+
+struct vfe_cmd_stats_wb_exp_update {
+	uint8_t wbExpRegions;
+	uint8_t wbExpSubRegion;
+	int8_t  awbYMin;
+	int8_t  awbYMax;
+	int8_t  awbMCFG[4];
+	int16_t awbCCFG[4];
+};
+
+struct vfe_cmd_stats_af_ack {
+	uint32_t nextAFOutputBufferAddr;
+};
+
+struct vfe_cmd_stats_wb_exp_ack {
+	uint32_t  nextWbExpOutputBufferAddr;
+};
+
+struct vfe_cmd_black_level_config {
+	uint8_t  enable;
+	uint16_t evenEvenAdjustment;
+	uint16_t evenOddAdjustment;
+	uint16_t oddEvenAdjustment;
+	uint16_t oddOddAdjustment;
+};
+
+/* 13*1  */
+#define  VFE_ROLL_OFF_INIT_TABLE_SIZE  13
+/* 13*16 */
+#define  VFE_ROLL_OFF_DELTA_TABLE_SIZE 208
+
+struct vfe_cmd_roll_off_config {
+	uint8_t  enable;
+	uint16_t gridWidth;
+	uint16_t gridHeight;
+	uint16_t  yDelta;
+	uint8_t  gridXIndex;
+	uint8_t  gridYIndex;
+	uint16_t gridPixelXIndex;
+	uint16_t gridPixelYIndex;
+	uint16_t yDeltaAccum;
+	uint16_t initTableR[VFE_ROLL_OFF_INIT_TABLE_SIZE];
+	uint16_t initTableGr[VFE_ROLL_OFF_INIT_TABLE_SIZE];
+	uint16_t initTableB[VFE_ROLL_OFF_INIT_TABLE_SIZE];
+	uint16_t initTableGb[VFE_ROLL_OFF_INIT_TABLE_SIZE];
+	int16_t  deltaTableR[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
+	int16_t  deltaTableGr[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
+	int16_t  deltaTableB[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
+	int16_t  deltaTableGb[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
+};
+
+struct vfe_cmd_demux_channel_gain_config {
+	uint16_t ch0EvenGain;
+	uint16_t ch0OddGain;
+	uint16_t ch1Gain;
+	uint16_t ch2Gain;
+};
+
+struct vfe_cmds_demosaic_abf {
+	uint8_t   enable;
+	uint8_t   forceOn;
+	uint8_t   shift;
+	uint16_t  lpThreshold;
+	uint16_t  max;
+	uint16_t  min;
+	uint8_t   ratio;
+};
+
+struct vfe_cmds_demosaic_bpc {
+	uint8_t   enable;
+	uint16_t  fmaxThreshold;
+	uint16_t  fminThreshold;
+	uint16_t  redDiffThreshold;
+	uint16_t  blueDiffThreshold;
+	uint16_t  greenDiffThreshold;
+};
+
+struct vfe_cmd_demosaic_config {
+	uint8_t   enable;
+	uint8_t   slopeShift;
+	struct vfe_cmds_demosaic_abf abfConfig;
+	struct vfe_cmds_demosaic_bpc bpcConfig;
+};
+
+struct vfe_cmd_demosaic_bpc_update {
+	struct vfe_cmds_demosaic_bpc bpcUpdate;
+};
+
+struct vfe_cmd_demosaic_abf_update {
+	struct vfe_cmds_demosaic_abf abfUpdate;
+};
+
+struct vfe_cmd_white_balance_config {
+	uint8_t  enable;
+	uint16_t ch2Gain;
+	uint16_t ch1Gain;
+	uint16_t ch0Gain;
+};
+
+enum VFE_COLOR_CORRECTION_COEF_QFACTOR {
+	COEF_IS_Q7_SIGNED,
+	COEF_IS_Q8_SIGNED,
+	COEF_IS_Q9_SIGNED,
+	COEF_IS_Q10_SIGNED
+};
+
+struct vfe_cmd_color_correction_config {
+	uint8_t     enable;
+	enum VFE_COLOR_CORRECTION_COEF_QFACTOR coefQFactor;
+	int16_t  C0;
+	int16_t  C1;
+	int16_t  C2;
+	int16_t  C3;
+	int16_t  C4;
+	int16_t  C5;
+	int16_t  C6;
+	int16_t  C7;
+	int16_t  C8;
+	int16_t  K0;
+	int16_t  K1;
+	int16_t  K2;
+};
+
+#define VFE_LA_TABLE_LENGTH 256
+struct vfe_cmd_la_config {
+	uint8_t enable;
+	int16_t table[VFE_LA_TABLE_LENGTH];
+};
+
+#define VFE_GAMMA_TABLE_LENGTH 256
+enum VFE_RGB_GAMMA_TABLE_SELECT {
+	RGB_GAMMA_CH0_SELECTED,
+	RGB_GAMMA_CH1_SELECTED,
+	RGB_GAMMA_CH2_SELECTED,
+	RGB_GAMMA_CH0_CH1_SELECTED,
+	RGB_GAMMA_CH0_CH2_SELECTED,
+	RGB_GAMMA_CH1_CH2_SELECTED,
+	RGB_GAMMA_CH0_CH1_CH2_SELECTED
+};
+
+struct vfe_cmd_rgb_gamma_config {
+	uint8_t enable;
+	enum VFE_RGB_GAMMA_TABLE_SELECT channelSelect;
+	int16_t table[VFE_GAMMA_TABLE_LENGTH];
+};
+
+struct vfe_cmd_chroma_enhan_config {
+	uint8_t  enable;
+	int16_t am;
+	int16_t ap;
+	int16_t bm;
+	int16_t bp;
+	int16_t cm;
+	int16_t cp;
+	int16_t dm;
+	int16_t dp;
+	int16_t kcr;
+	int16_t kcb;
+	int16_t RGBtoYConversionV0;
+	int16_t RGBtoYConversionV1;
+	int16_t RGBtoYConversionV2;
+	uint8_t RGBtoYConversionOffset;
+};
+
+struct vfe_cmd_chroma_suppression_config {
+	uint8_t enable;
+	uint8_t m1;
+	uint8_t m3;
+	uint8_t n1;
+	uint8_t n3;
+	uint8_t nn1;
+	uint8_t mm1;
+};
+
+struct vfe_cmd_asf_config {
+	uint8_t enable;
+	uint8_t smoothFilterEnabled;
+	uint8_t sharpMode;
+	uint8_t smoothCoefCenter;
+	uint8_t smoothCoefSurr;
+	uint8_t normalizeFactor;
+	uint8_t sharpK1;
+	uint8_t sharpK2;
+	uint8_t sharpThreshE1;
+	int8_t sharpThreshE2;
+	int8_t sharpThreshE3;
+	int8_t sharpThreshE4;
+	int8_t sharpThreshE5;
+	int8_t filter1Coefficients[9];
+	int8_t filter2Coefficients[9];
+	uint8_t  cropEnable;
+	uint16_t cropFirstPixel;
+	uint16_t cropLastPixel;
+	uint16_t cropFirstLine;
+	uint16_t cropLastLine;
+};
+
+struct vfe_cmd_asf_update {
+	uint8_t enable;
+	uint8_t smoothFilterEnabled;
+	uint8_t sharpMode;
+	uint8_t smoothCoefCenter;
+	uint8_t smoothCoefSurr;
+	uint8_t normalizeFactor;
+	uint8_t sharpK1;
+	uint8_t sharpK2;
+	uint8_t sharpThreshE1;
+	int8_t  sharpThreshE2;
+	int8_t  sharpThreshE3;
+	int8_t  sharpThreshE4;
+	int8_t  sharpThreshE5;
+	int8_t  filter1Coefficients[9];
+	int8_t  filter2Coefficients[9];
+	uint8_t cropEnable;
+};
+
+enum VFE_TEST_GEN_SYNC_EDGE {
+	VFE_TEST_GEN_SYNC_EDGE_ActiveHigh,
+	VFE_TEST_GEN_SYNC_EDGE_ActiveLow
+};
+
+struct vfe_cmd_test_gen_start {
+	uint8_t pixelDataSelect;
+	uint8_t systematicDataSelect;
+	enum VFE_TEST_GEN_SYNC_EDGE  hsyncEdge;
+	enum VFE_TEST_GEN_SYNC_EDGE  vsyncEdge;
+	uint16_t numFrame;
+	enum VFE_RAW_PIXEL_DATA_SIZE pixelDataSize;
+	uint16_t imageWidth;
+	uint16_t imageHeight;
+	uint32_t startOfFrameOffset;
+	uint32_t endOfFrameNOffset;
+	uint16_t startOfLineOffset;
+	uint16_t endOfLineNOffset;
+	uint16_t hbi;
+	uint8_t  vblEnable;
+	uint16_t vbl;
+	uint8_t  startOfFrameDummyLine;
+	uint8_t  endOfFrameDummyLine;
+	uint8_t  unicolorBarEnable;
+	uint8_t  colorBarsSplitEnable;
+	uint8_t  unicolorBarSelect;
+	enum VFE_START_PIXEL_PATTERN  colorBarsPixelPattern;
+	uint8_t  colorBarsRotatePeriod;
+	uint16_t testGenRandomSeed;
+};
+
+struct vfe_cmd_bus_pm_start {
+	uint8_t output2YWrPmEnable;
+	uint8_t output2CbcrWrPmEnable;
+	uint8_t output1YWrPmEnable;
+	uint8_t output1CbcrWrPmEnable;
+};
+
+struct vfe_cmd_camif_frame_update {
+	struct vfe_cmds_camif_frame camifFrame;
+};
+
+struct vfe_cmd_sync_timer_setting {
+	uint8_t  whichSyncTimer;
+	uint8_t  operation;
+	uint8_t  polarity;
+	uint16_t repeatCount;
+	uint16_t hsyncCount;
+	uint32_t pclkCount;
+	uint32_t outputDuration;
+};
+
+struct vfe_cmd_async_timer_setting {
+	uint8_t  whichAsyncTimer;
+	uint8_t  operation;
+	uint8_t  polarity;
+	uint16_t repeatCount;
+	uint16_t inactiveCount;
+	uint32_t activeCount;
+};
+
+struct  vfe_frame_skip_counts {
+	uint32_t  totalFrameCount;
+	uint32_t  output1Count;
+	uint32_t  output2Count;
+};
+
+enum VFE_AXI_RD_UNPACK_HBI_SEL {
+	VFE_AXI_RD_HBI_32_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_64_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_128_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_256_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_512_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_1024_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_2048_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_4096_CLOCK_CYCLES
+};
+
+struct vfe_cmd_axi_input_config {
+	uint32_t  fragAddr[4];
+	uint8_t   totalFragmentCount;
+	uint16_t  ySize;
+	uint16_t  xOffset;
+	uint16_t  xSize;
+	uint16_t  rowIncrement;
+	uint16_t  numOfRows;
+	enum VFE_AXI_BURST_LENGTH burstLength;
+	uint8_t   unpackPhase;
+	enum VFE_AXI_RD_UNPACK_HBI_SEL unpackHbi;
+	enum VFE_RAW_PIXEL_DATA_SIZE   pixelSize;
+	uint8_t   padRepeatCountLeft;
+	uint8_t   padRepeatCountRight;
+	uint8_t   padRepeatCountTop;
+	uint8_t   padRepeatCountBottom;
+	uint8_t   padLeftComponentSelectCycle0;
+	uint8_t   padLeftComponentSelectCycle1;
+	uint8_t   padLeftComponentSelectCycle2;
+	uint8_t   padLeftComponentSelectCycle3;
+	uint8_t   padLeftStopCycle0;
+	uint8_t   padLeftStopCycle1;
+	uint8_t   padLeftStopCycle2;
+	uint8_t   padLeftStopCycle3;
+	uint8_t   padRightComponentSelectCycle0;
+	uint8_t   padRightComponentSelectCycle1;
+	uint8_t   padRightComponentSelectCycle2;
+	uint8_t   padRightComponentSelectCycle3;
+	uint8_t   padRightStopCycle0;
+	uint8_t   padRightStopCycle1;
+	uint8_t   padRightStopCycle2;
+	uint8_t   padRightStopCycle3;
+	uint8_t   padTopLineCount;
+	uint8_t   padBottomLineCount;
+};
+
+struct vfe_interrupt_status {
+	uint8_t camifErrorIrq;
+	uint8_t camifSofIrq;
+	uint8_t camifEolIrq;
+	uint8_t camifEofIrq;
+	uint8_t camifEpoch1Irq;
+	uint8_t camifEpoch2Irq;
+	uint8_t camifOverflowIrq;
+	uint8_t ceIrq;
+	uint8_t regUpdateIrq;
+	uint8_t resetAckIrq;
+	uint8_t encYPingpongIrq;
+	uint8_t encCbcrPingpongIrq;
+	uint8_t viewYPingpongIrq;
+	uint8_t viewCbcrPingpongIrq;
+	uint8_t rdPingpongIrq;
+	uint8_t afPingpongIrq;
+	uint8_t awbPingpongIrq;
+	uint8_t histPingpongIrq;
+	uint8_t encIrq;
+	uint8_t viewIrq;
+	uint8_t busOverflowIrq;
+	uint8_t afOverflowIrq;
+	uint8_t awbOverflowIrq;
+	uint8_t syncTimer0Irq;
+	uint8_t syncTimer1Irq;
+	uint8_t syncTimer2Irq;
+	uint8_t asyncTimer0Irq;
+	uint8_t asyncTimer1Irq;
+	uint8_t asyncTimer2Irq;
+	uint8_t asyncTimer3Irq;
+	uint8_t axiErrorIrq;
+	uint8_t violationIrq;
+	uint8_t anyErrorIrqs;
+	uint8_t anyOutput1PathIrqs;
+	uint8_t anyOutput2PathIrqs;
+	uint8_t anyOutputPathIrqs;
+	uint8_t anyAsyncTimerIrqs;
+	uint8_t anySyncTimerIrqs;
+	uint8_t anyIrqForActiveStatesOnly;
+};
+
+enum VFE_MESSAGE_ID {
+	VFE_MSG_ID_RESET_ACK,
+	VFE_MSG_ID_START_ACK,
+	VFE_MSG_ID_STOP_ACK,
+	VFE_MSG_ID_UPDATE_ACK,
+	VFE_MSG_ID_OUTPUT_P,
+	VFE_MSG_ID_OUTPUT_V,
+	VFE_MSG_ID_OUTPUT_S,
+	VFE_MSG_ID_OUTPUT_T,
+	VFE_MSG_ID_SNAPSHOT_DONE,
+	VFE_MSG_ID_STATS_AUTOFOCUS,
+	VFE_MSG_ID_STATS_WB_EXP,
+	VFE_MSG_ID_EPOCH1,
+	VFE_MSG_ID_EPOCH2,
+	VFE_MSG_ID_SYNC_TIMER0_DONE,
+	VFE_MSG_ID_SYNC_TIMER1_DONE,
+	VFE_MSG_ID_SYNC_TIMER2_DONE,
+	VFE_MSG_ID_ASYNC_TIMER0_DONE,
+	VFE_MSG_ID_ASYNC_TIMER1_DONE,
+	VFE_MSG_ID_ASYNC_TIMER2_DONE,
+	VFE_MSG_ID_ASYNC_TIMER3_DONE,
+	VFE_MSG_ID_AF_OVERFLOW,
+	VFE_MSG_ID_AWB_OVERFLOW,
+	VFE_MSG_ID_AXI_ERROR,
+	VFE_MSG_ID_CAMIF_OVERFLOW,
+	VFE_MSG_ID_VIOLATION,
+	VFE_MSG_ID_CAMIF_ERROR,
+	VFE_MSG_ID_BUS_OVERFLOW,
+	VFE_MSG_ID_SOF_ACK,
+};
+
+struct vfe_msg_stats_autofocus {
+	uint32_t    afBuffer;
+	uint32_t    frameCounter;
+};
+
+struct vfe_msg_stats_wb_exp {
+	uint32_t awbBuffer;
+	uint32_t frameCounter;
+};
+
+struct vfe_frame_bpc_info {
+	uint32_t greenDefectPixelCount;
+	uint32_t redBlueDefectPixelCount;
+};
+
+struct vfe_frame_asf_info {
+	uint32_t  asfMaxEdge;
+	uint32_t  asfHbiCount;
+};
+
+struct vfe_msg_camif_status {
+	uint8_t  camifState;
+	uint32_t pixelCount;
+	uint32_t lineCount;
+};
+
+struct vfe_bus_pm_per_path {
+	uint32_t yWrPmStats0;
+	uint32_t yWrPmStats1;
+	uint32_t cbcrWrPmStats0;
+	uint32_t cbcrWrPmStats1;
+};
+
+struct vfe_bus_performance_monitor {
+	struct vfe_bus_pm_per_path encPathPmInfo;
+	struct vfe_bus_pm_per_path viewPathPmInfo;
+};
+
+struct vfe_irq_thread_msg {
+	uint32_t  vfeIrqStatus;
+	uint32_t  camifStatus;
+	uint32_t  demosaicStatus;
+	uint32_t  asfMaxEdge;
+	struct vfe_bus_performance_monitor pmInfo;
+};
+
+struct vfe_msg_output {
+	uint32_t  yBuffer;
+	uint32_t  cbcrBuffer;
+	struct vfe_frame_bpc_info bpcInfo;
+	struct vfe_frame_asf_info asfInfo;
+	uint32_t  frameCounter;
+	struct vfe_bus_pm_per_path pmData;
+};
+
+struct vfe_message {
+	enum VFE_MESSAGE_ID _d;
+	union {
+		struct vfe_msg_output              msgOutput1;
+		struct vfe_msg_output              msgOutput2;
+		struct vfe_msg_stats_autofocus     msgStatsAf;
+		struct vfe_msg_stats_wb_exp        msgStatsWbExp;
+		struct vfe_msg_camif_status        msgCamifError;
+		struct vfe_bus_performance_monitor msgBusOverflow;
+   } _u;
+};
+
+/* New one for 8k */
+struct msm_vfe_command_8k {
+	int id;
+	uint16_t length;
+	void     *value;
+};
+
+struct vfe_frame_extra {
+	struct vfe_frame_bpc_info bpcInfo;
+	struct vfe_frame_asf_info asfInfo;
+	uint32_t  frameCounter;
+	struct vfe_bus_pm_per_path pmData;
+};
+#endif /* __MSM_VFE8X_H__ */
diff --git a/drivers/media/platform/msm/camera_v1/vfe/msm_vfe8x_proc.c b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe8x_proc.c
new file mode 100644
index 0000000..4ebb30d
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe8x_proc.c
@@ -0,0 +1,3889 @@
+/* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include "msm_vfe8x_proc.h"
+#include <media/msm_camera.h>
+#include <mach/board.h>
+
+struct isr_queue_cmd {
+	struct list_head list;
+	struct vfe_interrupt_status vfeInterruptStatus;
+	struct vfe_frame_asf_info vfeAsfFrameInfo;
+	struct vfe_frame_bpc_info vfeBpcFrameInfo;
+	struct vfe_msg_camif_status vfeCamifStatusLocal;
+	struct vfe_bus_performance_monitor vfePmData;
+};
+
+struct msm_vfe8x_ctrl {
+	/* bit 1:0 ENC_IRQ_MASK = 0x11:
+	 * generate IRQ when both y and cbcr frame is ready. */
+
+	/* bit 1:0 VIEW_IRQ_MASK= 0x11:
+	 * generate IRQ when both y and cbcr frame is ready. */
+	struct vfe_irq_composite_mask_config vfeIrqCompositeMaskLocal;
+	struct vfe_module_enable vfeModuleEnableLocal;
+	struct vfe_camif_cfg_data   vfeCamifConfigLocal;
+	struct vfe_interrupt_mask   vfeImaskLocal;
+	struct vfe_stats_cmd_data   vfeStatsCmdLocal;
+	struct vfe_bus_cfg_data     vfeBusConfigLocal;
+	struct vfe_cmd_bus_pm_start vfeBusPmConfigLocal;
+	struct vfe_bus_cmd_data     vfeBusCmdLocal;
+	enum vfe_interrupt_name     vfeInterruptNameLocal;
+	uint32_t vfeLaBankSel;
+	struct vfe_gamma_lut_sel  vfeGammaLutSel;
+
+	boolean vfeStartAckPendingFlag;
+	boolean vfeStopAckPending;
+	boolean vfeResetAckPending;
+	boolean vfeUpdateAckPending;
+
+	enum VFE_AXI_OUTPUT_MODE        axiOutputMode;
+	enum VFE_START_OPERATION_MODE   vfeOperationMode;
+
+	atomic_t vfe_serv_interrupt;
+
+	uint32_t            vfeSnapShotCount;
+	uint32_t            vfeRequestedSnapShotCount;
+	boolean             vfeStatsPingPongReloadFlag;
+	uint32_t            vfeFrameId;
+
+	struct vfe_cmd_frame_skip_config vfeFrameSkip;
+	uint32_t vfeFrameSkipPattern;
+	uint8_t  vfeFrameSkipCount;
+	uint8_t  vfeFrameSkipPeriod;
+
+	boolean  vfeTestGenStartFlag;
+	uint32_t vfeImaskPacked;
+	uint32_t vfeImaskCompositePacked;
+	enum VFE_RAW_PIXEL_DATA_SIZE       axiInputDataSize;
+	struct vfe_irq_thread_msg          vfeIrqThreadMsgLocal;
+
+	struct vfe_output_path_combo  viewPath;
+	struct vfe_output_path_combo  encPath;
+	struct vfe_frame_skip_counts vfeDroppedFrameCounts;
+	struct vfe_stats_control afStatsControl;
+	struct vfe_stats_control awbStatsControl;
+
+	enum VFE_STATE  vstate;
+
+	struct msm_vfe_callback *resp;
+	struct vfe_frame_extra extdata;
+
+	struct isr_queue_cmd irqs[10];
+	spinlock_t irqs_lock;
+	int irq_get;
+	int irq_put;
+
+	int vfeirq;
+	void __iomem *vfebase;
+
+	void *syncdata;
+};
+
+static struct msm_vfe8x_ctrl *ctrl;
+static spinlock_t msm_vfe_ctrl_lock;
+
+static void vfe_prog_hw(uint8_t *hwreg, uint32_t *inptr, uint32_t regcnt)
+{
+	/* unsigned long flags; */
+	uint32_t i;
+	uint32_t *p;
+
+	/* @todo This is causing issues, need further investigate */
+	/* spin_lock_irqsave(&ctrl->io_lock, flags); */
+
+	p = (uint32_t *)(hwreg);
+	for (i = 0; i < (regcnt >> 2); i++)
+		writel(*inptr++, p++);
+		/* *p++ = *inptr++; */
+
+	/* spin_unlock_irqrestore(&ctrl->io_lock, flags); */
+}
+
+static void
+vfe_set_bus_pipo_addr(struct vfe_output_path_combo *vpath,
+	struct vfe_output_path_combo *epath)
+{
+	vpath->yPath.hwRegPingAddress = (uint8_t *)
+		(ctrl->vfebase + VFE_BUS_VIEW_Y_WR_PING_ADDR);
+	vpath->yPath.hwRegPongAddress = (uint8_t *)
+		(ctrl->vfebase + VFE_BUS_VIEW_Y_WR_PONG_ADDR);
+	vpath->cbcrPath.hwRegPingAddress = (uint8_t *)
+		(ctrl->vfebase + VFE_BUS_VIEW_CBCR_WR_PING_ADDR);
+	vpath->cbcrPath.hwRegPongAddress = (uint8_t *)
+		(ctrl->vfebase + VFE_BUS_VIEW_CBCR_WR_PONG_ADDR);
+
+	epath->yPath.hwRegPingAddress = (uint8_t *)
+		(ctrl->vfebase + VFE_BUS_ENC_Y_WR_PING_ADDR);
+	epath->yPath.hwRegPongAddress = (uint8_t *)
+		(ctrl->vfebase + VFE_BUS_ENC_Y_WR_PONG_ADDR);
+	epath->cbcrPath.hwRegPingAddress = (uint8_t *)
+		(ctrl->vfebase + VFE_BUS_ENC_CBCR_WR_PING_ADDR);
+	epath->cbcrPath.hwRegPongAddress = (uint8_t *)
+		(ctrl->vfebase + VFE_BUS_ENC_CBCR_WR_PONG_ADDR);
+}
+
+static void vfe_axi_output(struct vfe_cmd_axi_output_config *in,
+	struct vfe_output_path_combo *out1,
+	struct vfe_output_path_combo *out2, uint16_t out)
+{
+	struct vfe_axi_out_cfg cmd;
+
+	uint16_t temp;
+	uint32_t burstLength;
+
+	memset(&cmd, 0, sizeof(cmd));
+	/* force it to burst length 4, hardware does not support it. */
+	burstLength = 1;
+
+	/* AXI Output 2 Y Configuration*/
+	/* VFE_BUS_ENC_Y_WR_PING_ADDR  */
+	cmd.out2YPingAddr = out2->yPath.addressBuffer[0];
+
+	/* VFE_BUS_ENC_Y_WR_PONG_ADDR  */
+	cmd.out2YPongAddr = out2->yPath.addressBuffer[1];
+
+	/* VFE_BUS_ENC_Y_WR_IMAGE_SIZE */
+	cmd.out2YImageHeight = in->output2.outputY.imageHeight;
+	/* convert the image width and row increment to be in
+	 * unit of 64bit (8 bytes) */
+	temp = (in->output2.outputY.imageWidth + (out - 1)) / out;
+	cmd.out2YImageWidthin64bit = temp;
+
+	/* VFE_BUS_ENC_Y_WR_BUFFER_CFG */
+	cmd.out2YBurstLength = burstLength;
+	cmd.out2YNumRows = in->output2.outputY.outRowCount;
+	temp = (in->output2.outputY.outRowIncrement + (out - 1)) / out;
+	cmd.out2YRowIncrementIn64bit = temp;
+
+	/* AXI Output 2 Cbcr Configuration*/
+	/* VFE_BUS_ENC_Cbcr_WR_PING_ADDR  */
+	cmd.out2CbcrPingAddr = out2->cbcrPath.addressBuffer[0];
+
+	/* VFE_BUS_ENC_Cbcr_WR_PONG_ADDR  */
+	cmd.out2CbcrPongAddr = out2->cbcrPath.addressBuffer[1];
+
+	/* VFE_BUS_ENC_Cbcr_WR_IMAGE_SIZE */
+	cmd.out2CbcrImageHeight = in->output2.outputCbcr.imageHeight;
+	temp = (in->output2.outputCbcr.imageWidth + (out - 1)) / out;
+	cmd.out2CbcrImageWidthIn64bit = temp;
+
+	/* VFE_BUS_ENC_Cbcr_WR_BUFFER_CFG */
+	cmd.out2CbcrBurstLength = burstLength;
+	cmd.out2CbcrNumRows = in->output2.outputCbcr.outRowCount;
+	temp = (in->output2.outputCbcr.outRowIncrement + (out - 1)) / out;
+	cmd.out2CbcrRowIncrementIn64bit = temp;
+
+	/* AXI Output 1 Y Configuration */
+	/* VFE_BUS_VIEW_Y_WR_PING_ADDR  */
+	cmd.out1YPingAddr = out1->yPath.addressBuffer[0];
+
+	/* VFE_BUS_VIEW_Y_WR_PONG_ADDR */
+	cmd.out1YPongAddr = out1->yPath.addressBuffer[1];
+
+	/* VFE_BUS_VIEW_Y_WR_IMAGE_SIZE */
+	cmd.out1YImageHeight = in->output1.outputY.imageHeight;
+	temp = (in->output1.outputY.imageWidth + (out - 1)) / out;
+	cmd.out1YImageWidthin64bit = temp;
+
+	/* VFE_BUS_VIEW_Y_WR_BUFFER_CFG     */
+	cmd.out1YBurstLength = burstLength;
+	cmd.out1YNumRows = in->output1.outputY.outRowCount;
+
+	temp = (in->output1.outputY.outRowIncrement + (out - 1)) / out;
+	cmd.out1YRowIncrementIn64bit = temp;
+
+	/* AXI Output 1 Cbcr Configuration*/
+	cmd.out1CbcrPingAddr = out1->cbcrPath.addressBuffer[0];
+
+	/* VFE_BUS_VIEW_Cbcr_WR_PONG_ADDR  */
+	cmd.out1CbcrPongAddr = out1->cbcrPath.addressBuffer[1];
+
+	/* VFE_BUS_VIEW_Cbcr_WR_IMAGE_SIZE */
+	cmd.out1CbcrImageHeight = in->output1.outputCbcr.imageHeight;
+	temp = (in->output1.outputCbcr.imageWidth + (out - 1)) / out;
+	cmd.out1CbcrImageWidthIn64bit = temp;
+
+	cmd.out1CbcrBurstLength = burstLength;
+	cmd.out1CbcrNumRows = in->output1.outputCbcr.outRowCount;
+	temp = (in->output1.outputCbcr.outRowIncrement + (out - 1)) / out;
+
+	cmd.out1CbcrRowIncrementIn64bit = temp;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_BUS_ENC_Y_WR_PING_ADDR,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+static void vfe_reg_bus_cfg(struct vfe_bus_cfg_data *in)
+{
+	struct vfe_axi_bus_cfg cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.stripeRdPathEn      = in->stripeRdPathEn;
+	cmd.encYWrPathEn        = in->encYWrPathEn;
+	cmd.encCbcrWrPathEn     = in->encCbcrWrPathEn;
+	cmd.viewYWrPathEn       = in->viewYWrPathEn;
+	cmd.viewCbcrWrPathEn    = in->viewCbcrWrPathEn;
+	cmd.rawPixelDataSize    = (uint32_t)in->rawPixelDataSize;
+	cmd.rawWritePathSelect  = (uint32_t)in->rawWritePathSelect;
+
+	/*  program vfe_bus_cfg */
+	writel(*((uint32_t *)&cmd), ctrl->vfebase + VFE_BUS_CFG);
+}
+
+static void vfe_reg_camif_config(struct vfe_camif_cfg_data *in)
+{
+	struct VFE_CAMIFConfigType cfg;
+
+	memset(&cfg, 0, sizeof(cfg));
+
+	cfg.VSyncEdge = in->camifCfgFromCmd.vSyncEdge;
+
+	cfg.HSyncEdge = in->camifCfgFromCmd.hSyncEdge;
+
+	cfg.syncMode = in->camifCfgFromCmd.syncMode;
+
+	cfg.vfeSubsampleEnable = in->camifCfgFromCmd.vfeSubSampleEnable;
+
+	cfg.busSubsampleEnable = in->camifCfgFromCmd.busSubSampleEnable;
+
+	cfg.camif2vfeEnable = in->camif2OutputEnable;
+
+	cfg.camif2busEnable = in->camif2BusEnable;
+
+	cfg.irqSubsampleEnable = in->camifCfgFromCmd.irqSubSampleEnable;
+
+	cfg.binningEnable = in->camifCfgFromCmd.binningEnable;
+
+	cfg.misrEnable = in->camifCfgFromCmd.misrEnable;
+
+	/*  program camif_config */
+	writel(*((uint32_t *)&cfg), ctrl->vfebase + CAMIF_CONFIG);
+}
+
+static void vfe_reg_bus_cmd(struct vfe_bus_cmd_data *in)
+{
+	struct vfe_buscmd cmd;
+	memset(&cmd, 0, sizeof(cmd));
+
+	cmd.stripeReload        = in->stripeReload;
+	cmd.busPingpongReload   = in->busPingpongReload;
+	cmd.statsPingpongReload = in->statsPingpongReload;
+
+	writel(*((uint32_t *)&cmd), ctrl->vfebase + VFE_BUS_CMD);
+
+	CDBG("bus command = 0x%x\n", (*((uint32_t *)&cmd)));
+
+	/* this is needed, as the control bits are pulse based.
+	 * Don't want to reload bus pingpong again. */
+	in->busPingpongReload = 0;
+	in->statsPingpongReload = 0;
+	in->stripeReload = 0;
+}
+
+static void vfe_reg_module_cfg(struct vfe_module_enable *in)
+{
+	struct vfe_mod_enable ena;
+
+	memset(&ena, 0, sizeof(ena));
+
+	ena.blackLevelCorrectionEnable = in->blackLevelCorrectionEnable;
+	ena.lensRollOffEnable          = in->lensRollOffEnable;
+	ena.demuxEnable                = in->demuxEnable;
+	ena.chromaUpsampleEnable       = in->chromaUpsampleEnable;
+	ena.demosaicEnable             = in->demosaicEnable;
+	ena.statsEnable                = in->statsEnable;
+	ena.cropEnable                 = in->cropEnable;
+	ena.mainScalerEnable           = in->mainScalerEnable;
+	ena.whiteBalanceEnable         = in->whiteBalanceEnable;
+	ena.colorCorrectionEnable      = in->colorCorrectionEnable;
+	ena.yHistEnable                = in->yHistEnable;
+	ena.skinToneEnable             = in->skinToneEnable;
+	ena.lumaAdaptationEnable       = in->lumaAdaptationEnable;
+	ena.rgbLUTEnable               = in->rgbLUTEnable;
+	ena.chromaEnhanEnable          = in->chromaEnhanEnable;
+	ena.asfEnable                  = in->asfEnable;
+	ena.chromaSuppressionEnable    = in->chromaSuppressionEnable;
+	ena.chromaSubsampleEnable      = in->chromaSubsampleEnable;
+	ena.scaler2YEnable             = in->scaler2YEnable;
+	ena.scaler2CbcrEnable          = in->scaler2CbcrEnable;
+
+	writel(*((uint32_t *)&ena), ctrl->vfebase + VFE_MODULE_CFG);
+}
+
+static void vfe_program_dmi_cfg(enum VFE_DMI_RAM_SEL bankSel)
+{
+	/* set bit 8 for auto increment. */
+	uint32_t value = (uint32_t) ctrl->vfebase + VFE_DMI_CFG_DEFAULT;
+
+	value += (uint32_t)bankSel;
+	/* CDBG("dmi cfg input bank is  0x%x\n", bankSel); */
+
+	writel(value, ctrl->vfebase + VFE_DMI_CFG);
+	writel(0, ctrl->vfebase + VFE_DMI_ADDR);
+}
+
+static void vfe_write_lens_roll_off_table(struct vfe_cmd_roll_off_config *in)
+{
+	uint16_t i;
+	uint32_t data;
+
+	uint16_t *initGr = in->initTableGr;
+	uint16_t *initGb = in->initTableGb;
+	uint16_t *initB =  in->initTableB;
+	uint16_t *initR =  in->initTableR;
+
+	int16_t *pDeltaGr = in->deltaTableGr;
+	int16_t *pDeltaGb = in->deltaTableGb;
+	int16_t *pDeltaB =  in->deltaTableB;
+	int16_t *pDeltaR =  in->deltaTableR;
+
+	vfe_program_dmi_cfg(ROLLOFF_RAM);
+
+	/* first pack and write init table */
+	for (i = 0; i < VFE_ROLL_OFF_INIT_TABLE_SIZE; i++) {
+		data = (((uint32_t)(*initR)) & 0x0000FFFF) |
+			(((uint32_t)(*initGr)) << 16);
+		initR++;
+		initGr++;
+
+		writel(data, ctrl->vfebase + VFE_DMI_DATA_LO);
+
+		data = (((uint32_t)(*initB)) & 0x0000FFFF) |
+			(((uint32_t)(*initGb))<<16);
+		initB++;
+		initGb++;
+
+		writel(data, ctrl->vfebase + VFE_DMI_DATA_LO);
+	}
+
+	/* there are gaps between the init table and delta table,
+	 * set the offset for delta table. */
+	writel(LENS_ROLL_OFF_DELTA_TABLE_OFFSET, ctrl->vfebase + VFE_DMI_ADDR);
+
+	/* pack and write delta table */
+	for (i = 0; i < VFE_ROLL_OFF_DELTA_TABLE_SIZE; i++) {
+		data = (((int)(*pDeltaR)) & 0x0000FFFF) |
+			(((int)(*pDeltaGr))<<16);
+		pDeltaR++;
+		pDeltaGr++;
+
+		writel(data, ctrl->vfebase + VFE_DMI_DATA_LO);
+
+		data = (((int)(*pDeltaB)) & 0x0000FFFF) |
+			(((int)(*pDeltaGb))<<16);
+		pDeltaB++;
+		pDeltaGb++;
+
+		writel(data, ctrl->vfebase + VFE_DMI_DATA_LO);
+	}
+
+	/* After DMI transfer, to make it safe, need to set the
+	 * DMI_CFG to unselect any SRAM
+	 */
+	/* unselect the SRAM Bank. */
+	writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG);
+}
+
+static void vfe_set_default_reg_values(void)
+{
+	writel(0x800080, ctrl->vfebase + VFE_DEMUX_GAIN_0);
+	writel(0x800080, ctrl->vfebase + VFE_DEMUX_GAIN_1);
+	writel(0xFFFFF, ctrl->vfebase + VFE_CGC_OVERRIDE);
+
+	/* default frame drop period and pattern */
+	writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_CFG);
+	writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_CFG);
+	writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_PATTERN);
+	writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_PATTERN);
+	writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_CFG);
+	writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR_CFG);
+	writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_PATTERN);
+	writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR_PATTERN);
+	writel(0, ctrl->vfebase + VFE_CLAMP_MIN_CFG);
+	writel(0xFFFFFF, ctrl->vfebase + VFE_CLAMP_MAX_CFG);
+}
+
+static void vfe_config_demux(uint32_t period, uint32_t even, uint32_t odd)
+{
+	writel(period, ctrl->vfebase + VFE_DEMUX_CFG);
+	writel(even, ctrl->vfebase + VFE_DEMUX_EVEN_CFG);
+	writel(odd, ctrl->vfebase + VFE_DEMUX_ODD_CFG);
+}
+
+static void vfe_pm_stop(void)
+{
+	writel(VFE_PERFORMANCE_MONITOR_STOP, ctrl->vfebase + VFE_BUS_PM_CMD);
+}
+
+static void vfe_camif_stop_immediately(void)
+{
+	writel(CAMIF_COMMAND_STOP_IMMEDIATELY, ctrl->vfebase + CAMIF_COMMAND);
+	writel(0, ctrl->vfebase + VFE_CGC_OVERRIDE);
+}
+
+static void vfe_program_reg_update_cmd(uint32_t value)
+{
+	writel(value, ctrl->vfebase + VFE_REG_UPDATE_CMD);
+}
+
+static void vfe_program_global_reset_cmd(uint32_t value)
+{
+	writel(value, ctrl->vfebase + VFE_GLOBAL_RESET_CMD);
+}
+
+static void vfe_program_axi_cmd(uint32_t value)
+{
+	writel(value, ctrl->vfebase + VFE_AXI_CMD);
+}
+
+static void vfe_program_irq_composite_mask(uint32_t value)
+{
+	writel(value, ctrl->vfebase + VFE_IRQ_COMPOSITE_MASK);
+}
+
+static inline void vfe_program_irq_mask(uint32_t value)
+{
+	writel(value, ctrl->vfebase + VFE_IRQ_MASK);
+}
+
+static uint32_t vfe_read_axi_status(void)
+{
+	return readl(ctrl->vfebase + VFE_AXI_STATUS);
+}
+
+static void
+vfe_set_stats_pingpong_address(struct vfe_stats_control *afControl,
+	struct vfe_stats_control *awbControl)
+{
+	afControl->hwRegPingAddress = (uint8_t *)
+		(ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR);
+	afControl->hwRegPongAddress = (uint8_t *)
+		(ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR);
+
+	awbControl->hwRegPingAddress = (uint8_t *)
+		(ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR);
+	awbControl->hwRegPongAddress = (uint8_t *)
+		(ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR);
+}
+
+static void vfe_program_lut_bank_sel(struct vfe_gamma_lut_sel *in)
+{
+	struct VFE_GammaLutSelect_ConfigCmdType cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+
+	cmd.ch0BankSelect = in->ch0BankSelect;
+	cmd.ch1BankSelect = in->ch1BankSelect;
+	cmd.ch2BankSelect = in->ch2BankSelect;
+	CDBG("VFE gamma lut bank selection is 0x%x\n", *((uint32_t *)&cmd));
+	vfe_prog_hw(ctrl->vfebase + VFE_LUT_BANK_SEL,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+static void vfe_program_stats_cmd(struct vfe_stats_cmd_data *in)
+{
+	struct VFE_StatsCmdType stats;
+	memset(&stats, 0, sizeof(stats));
+
+	stats.autoFocusEnable        = in->autoFocusEnable;
+	stats.axwEnable              = in->axwEnable;
+	stats.histEnable             = in->histEnable;
+	stats.clearHistEnable        = in->clearHistEnable;
+	stats.histAutoClearEnable    = in->histAutoClearEnable;
+	stats.colorConversionEnable  = in->colorConversionEnable;
+
+	writel(*((uint32_t *)&stats), ctrl->vfebase + VFE_STATS_CMD);
+}
+
+static void vfe_pm_start(struct vfe_cmd_bus_pm_start *in)
+{
+	struct VFE_Bus_Pm_ConfigCmdType cmd;
+	memset(&cmd, 0, sizeof(struct VFE_Bus_Pm_ConfigCmdType));
+
+	cmd.output2YWrPmEnable     = in->output2YWrPmEnable;
+	cmd.output2CbcrWrPmEnable  = in->output2CbcrWrPmEnable;
+	cmd.output1YWrPmEnable     = in->output1YWrPmEnable;
+	cmd.output1CbcrWrPmEnable  = in->output1CbcrWrPmEnable;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_BUS_PM_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+static void vfe_8k_pm_start(struct vfe_cmd_bus_pm_start *in)
+{
+	in->output1CbcrWrPmEnable = ctrl->vfeBusConfigLocal.viewCbcrWrPathEn;
+	in->output1YWrPmEnable    = ctrl->vfeBusConfigLocal.viewYWrPathEn;
+	in->output2CbcrWrPmEnable = ctrl->vfeBusConfigLocal.encCbcrWrPathEn;
+	in->output2YWrPmEnable    = ctrl->vfeBusConfigLocal.encYWrPathEn;
+
+	if (in->output1CbcrWrPmEnable || in->output1YWrPmEnable)
+		ctrl->viewPath.pmEnabled = TRUE;
+
+	if (in->output2CbcrWrPmEnable || in->output2YWrPmEnable)
+		ctrl->encPath.pmEnabled = TRUE;
+
+	vfe_pm_start(in);
+
+	writel(VFE_PERFORMANCE_MONITOR_GO, ctrl->vfebase + VFE_BUS_PM_CMD);
+}
+
+static uint32_t vfe_irq_pack(struct vfe_interrupt_mask data)
+{
+	struct vfe_irqenable packedData;
+
+	memset(&packedData, 0, sizeof(packedData));
+
+	packedData.camifErrorIrq          = data.camifErrorIrq;
+	packedData.camifSofIrq            = data.camifSofIrq;
+	packedData.camifEolIrq            = data.camifEolIrq;
+	packedData.camifEofIrq            = data.camifEofIrq;
+	packedData.camifEpoch1Irq         = data.camifEpoch1Irq;
+	packedData.camifEpoch2Irq         = data.camifEpoch2Irq;
+	packedData.camifOverflowIrq       = data.camifOverflowIrq;
+	packedData.ceIrq                  = data.ceIrq;
+	packedData.regUpdateIrq           = data.regUpdateIrq;
+	packedData.resetAckIrq            = data.resetAckIrq;
+	packedData.encYPingpongIrq        = data.encYPingpongIrq;
+	packedData.encCbcrPingpongIrq     = data.encCbcrPingpongIrq;
+	packedData.viewYPingpongIrq       = data.viewYPingpongIrq;
+	packedData.viewCbcrPingpongIrq    = data.viewCbcrPingpongIrq;
+	packedData.rdPingpongIrq          = data.rdPingpongIrq;
+	packedData.afPingpongIrq          = data.afPingpongIrq;
+	packedData.awbPingpongIrq         = data.awbPingpongIrq;
+	packedData.histPingpongIrq        = data.histPingpongIrq;
+	packedData.encIrq                 = data.encIrq;
+	packedData.viewIrq                = data.viewIrq;
+	packedData.busOverflowIrq         = data.busOverflowIrq;
+	packedData.afOverflowIrq          = data.afOverflowIrq;
+	packedData.awbOverflowIrq         = data.awbOverflowIrq;
+	packedData.syncTimer0Irq          = data.syncTimer0Irq;
+	packedData.syncTimer1Irq          = data.syncTimer1Irq;
+	packedData.syncTimer2Irq          = data.syncTimer2Irq;
+	packedData.asyncTimer0Irq         = data.asyncTimer0Irq;
+	packedData.asyncTimer1Irq         = data.asyncTimer1Irq;
+	packedData.asyncTimer2Irq         = data.asyncTimer2Irq;
+	packedData.asyncTimer3Irq         = data.asyncTimer3Irq;
+	packedData.axiErrorIrq            = data.axiErrorIrq;
+	packedData.violationIrq           = data.violationIrq;
+
+	return *((uint32_t *)&packedData);
+}
+
+static uint32_t
+vfe_irq_composite_pack(struct vfe_irq_composite_mask_config data)
+{
+	struct VFE_Irq_Composite_MaskType packedData;
+
+	memset(&packedData, 0, sizeof(packedData));
+
+	packedData.encIrqComMaskBits   = data.encIrqComMask;
+	packedData.viewIrqComMaskBits  = data.viewIrqComMask;
+	packedData.ceDoneSelBits       = data.ceDoneSel;
+
+	return *((uint32_t *)&packedData);
+}
+
+static void vfe_addr_convert(struct msm_vfe_phy_info *pinfo,
+				enum vfe_resp_msg type, void *data, void **ext,
+				int *elen)
+{
+	switch (type) {
+	case VFE_MSG_OUTPUT_P:
+	case VFE_MSG_OUTPUT_V:{
+		pinfo->planar0_off =
+			((struct vfe_message *)data)->_u.msgOutput2.yBuffer;
+		pinfo->planar1_off =
+			((struct vfe_message *)data)->_u.msgOutput2.
+			cbcrBuffer;
+		pinfo->planar2_off = pinfo->planar0_off;
+		ctrl->extdata.bpcInfo =
+			((struct vfe_message *)data)->_u.msgOutput2.bpcInfo;
+		ctrl->extdata.asfInfo =
+			((struct vfe_message *)data)->_u.msgOutput2.asfInfo;
+		ctrl->extdata.frameCounter =
+			((struct vfe_message *)data)->_u.msgOutput2.
+			frameCounter;
+		ctrl->extdata.pmData =
+		((struct vfe_message *)data)->_u.msgOutput2.pmData;
+		*ext = &ctrl->extdata;
+		*elen = sizeof(ctrl->extdata);
+	}
+		break;
+
+	case VFE_MSG_STATS_AF:
+		pinfo->sbuf_phy =
+		((struct vfe_message *)data)->_u.msgStatsAf.afBuffer;
+		break;
+
+	case VFE_MSG_STATS_WE:
+		pinfo->sbuf_phy =
+		((struct vfe_message *)data)->_u.msgStatsWbExp.awbBuffer;
+		break;
+
+	default:
+		break;
+	} /* switch */
+}
+
+static boolean vfe_send_preview_msg(struct msm_vfe_resp *rp,
+			struct vfe_message *msg, void *data);
+static boolean vfe_send_video_msg(struct msm_vfe_resp *rp,
+			struct vfe_message *msg, void *data);
+static boolean vfe_send_mainimage_msg(struct msm_vfe_resp *rp,
+			struct vfe_message *msg, void *data);
+static boolean vfe_send_thumbnail_msg(struct msm_vfe_resp *rp,
+			struct vfe_message *msg, void *data);
+static boolean vfe_send_af_stats_msg(struct msm_vfe_resp *rp,
+			struct vfe_message *msg, void *data);
+static boolean vfe_send_awb_stats_msg(struct msm_vfe_resp *rp,
+			struct vfe_message *msg, void *data);
+static boolean vfe_send_camif_error_msg(struct msm_vfe_resp *rp,
+			struct vfe_message *msg, void *data);
+static boolean vfe_send_bus_overflow_msg(struct msm_vfe_resp *rp,
+			struct vfe_message *msg, void *data);
+static boolean vfe_send_sof_msg(struct msm_vfe_resp *rp,
+			struct vfe_message *msg, void *data);
+
+static boolean invalid(struct msm_vfe_resp *rp,
+		struct vfe_message *_m, void *_d)
+{
+	BUG_ON(1); /* this function should not be called. */
+	return FALSE;
+}
+
+static struct {
+	boolean (*fn)(struct msm_vfe_resp *rp, struct vfe_message *msg,
+		void *data);
+	enum vfe_resp_msg rt; /* reponse type */
+} vfe_funcs[] = {
+	[VFE_MSG_ID_RESET_ACK] = { NULL, VFE_MSG_GENERAL },
+	[VFE_MSG_ID_START_ACK] = { NULL, VFE_MSG_GENERAL },
+	[VFE_MSG_ID_STOP_ACK] = { NULL, VFE_MSG_GENERAL },
+	[VFE_MSG_ID_UPDATE_ACK] = { NULL, VFE_MSG_GENERAL },
+	[VFE_MSG_ID_OUTPUT_P] = { vfe_send_preview_msg, VFE_MSG_OUTPUT_P },
+	[VFE_MSG_ID_OUTPUT_V] = { vfe_send_video_msg, VFE_MSG_OUTPUT_V },
+	[VFE_MSG_ID_OUTPUT_S] = { vfe_send_mainimage_msg, VFE_MSG_OUTPUT_S },
+	[VFE_MSG_ID_OUTPUT_T] = { vfe_send_thumbnail_msg, VFE_MSG_OUTPUT_T },
+	[VFE_MSG_ID_SNAPSHOT_DONE] = { NULL, VFE_MSG_SNAPSHOT },
+	[VFE_MSG_ID_STATS_AUTOFOCUS] = { vfe_send_af_stats_msg,
+		VFE_MSG_STATS_AF },
+	[VFE_MSG_ID_STATS_WB_EXP] = { vfe_send_awb_stats_msg,
+		VFE_MSG_STATS_WE },
+	[VFE_MSG_ID_EPOCH1] = { NULL, VFE_MSG_GENERAL },
+	[VFE_MSG_ID_EPOCH2] = { NULL, VFE_MSG_GENERAL },
+	[VFE_MSG_ID_SYNC_TIMER0_DONE] = { invalid },
+	[VFE_MSG_ID_SYNC_TIMER1_DONE] = { invalid },
+	[VFE_MSG_ID_SYNC_TIMER2_DONE] = { invalid },
+	[VFE_MSG_ID_ASYNC_TIMER0_DONE] = { invalid },
+	[VFE_MSG_ID_ASYNC_TIMER1_DONE] = { invalid },
+	[VFE_MSG_ID_ASYNC_TIMER2_DONE] = { invalid },
+	[VFE_MSG_ID_ASYNC_TIMER3_DONE] = { invalid },
+	[VFE_MSG_ID_AF_OVERFLOW] = { NULL, VFE_MSG_GENERAL },
+	[VFE_MSG_ID_AWB_OVERFLOW] = { NULL, VFE_MSG_GENERAL },
+	[VFE_MSG_ID_AXI_ERROR] = { NULL, VFE_MSG_GENERAL },
+	[VFE_MSG_ID_CAMIF_OVERFLOW] = { NULL, VFE_MSG_GENERAL },
+	[VFE_MSG_ID_VIOLATION] = { invalid },
+	[VFE_MSG_ID_CAMIF_ERROR] = { vfe_send_camif_error_msg,
+		VFE_MSG_GENERAL },
+	[VFE_MSG_ID_BUS_OVERFLOW] = { vfe_send_bus_overflow_msg,
+		VFE_MSG_GENERAL },
+	[VFE_MSG_ID_SOF_ACK] = { vfe_send_sof_msg,
+		VFE_MSG_GENERAL },
+};
+
+static void vfe_proc_ops(enum VFE_MESSAGE_ID id, void *data)
+{
+	struct msm_vfe_resp *rp;
+	struct vfe_message *msg;
+
+	if (id >= ARRAY_SIZE(vfe_funcs) || vfe_funcs[id].fn == invalid) {
+		pr_err("%s: invalid VFE message id %d\n", __func__, id);
+		return;
+	}
+
+	/* In 8k, OUTPUT1 & OUTPUT2 messages arrive before SNAPSHOT_DONE.
+	 * We don't send such messages to the user.  Note that we can do
+	 * this in the vfe_func[] callback, but that would cause us to
+	 * allocate and then immediately free the msm_vfe_resp structure,
+	 * which is wasteful.
+	 */
+	if ((ctrl->vfeOperationMode == VFE_START_OPERATION_MODE_SNAPSHOT) &&
+			(id == VFE_MSG_ID_OUTPUT_T ||
+			 id == VFE_MSG_ID_OUTPUT_S))
+		return;
+
+	rp = ctrl->resp->vfe_alloc(sizeof(*rp) +
+					(vfe_funcs[id].fn ? sizeof(*msg) : 0),
+					ctrl->syncdata,
+					GFP_ATOMIC);
+	if (!rp) {
+		pr_err("%s: out of memory\n", __func__);
+		return;
+	}
+
+	rp->type = vfe_funcs[id].rt;
+	rp->evt_msg.type = MSM_CAMERA_MSG;
+	rp->evt_msg.msg_id = id;
+
+	if (!vfe_funcs[id].fn) {
+		rp->evt_msg.len = 0;
+		rp->evt_msg.data = 0;
+	} else {
+		/* populate the message accordingly */
+		if (vfe_funcs[id].fn)
+			rp->evt_msg.data = msg =
+				(struct vfe_message *)(rp + 1);
+		else
+			rp->evt_msg.data = msg = 0;
+		rp->evt_msg.len = sizeof(*msg);
+		msg->_d = id;
+		if (vfe_funcs[id].fn(rp, msg, data) == FALSE) {
+			pr_warning("%s: freeing memory: handler for %d "
+				"returned false\n", __func__, id);
+			ctrl->resp->vfe_free(rp);
+			return;
+		}
+}
+
+	ctrl->resp->vfe_resp(rp, MSM_CAM_Q_VFE_MSG, ctrl->syncdata, GFP_KERNEL);
+}
+
+static boolean vfe_send_bus_overflow_msg(struct msm_vfe_resp *rp,
+			struct vfe_message *msg,
+			void *data)
+{
+#if 0
+	memcpy(&(msg->_u.msgBusOverflow),
+		&ctrl->vfePmData, sizeof(ctrl->vfePmData));
+#endif
+	return TRUE;
+}
+
+static boolean vfe_send_sof_msg(struct msm_vfe_resp *rp,
+			struct vfe_message *msg,
+			void *data)
+{
+	return TRUE;
+}
+static boolean vfe_send_camif_error_msg(struct msm_vfe_resp *rp,
+			struct vfe_message *msg,
+			void *data)
+{
+#if 0
+	memcpy(&(msg->_u.msgCamifError),
+	       &ctrl->vfeCamifStatusLocal, sizeof(ctrl->vfeCamifStatusLocal));
+#endif
+	return TRUE;
+}
+
+static void vfe_process_error_irq(struct vfe_interrupt_status *irqstatus)
+{
+	/* all possible error irq.  Note error irqs are not enabled, it is
+	 * checked only when other interrupts are present. */
+	if (irqstatus->afOverflowIrq)
+		vfe_proc_ops(VFE_MSG_ID_AF_OVERFLOW, NULL);
+
+	if (irqstatus->awbOverflowIrq)
+		vfe_proc_ops(VFE_MSG_ID_AWB_OVERFLOW, NULL);
+
+	if (irqstatus->axiErrorIrq)
+		vfe_proc_ops(VFE_MSG_ID_AXI_ERROR, NULL);
+
+	if (irqstatus->busOverflowIrq)
+		vfe_proc_ops(VFE_MSG_ID_BUS_OVERFLOW, NULL);
+
+	if (irqstatus->camifErrorIrq) {
+		CDBG("vfe_irq: camif errors\n");
+		vfe_proc_ops(VFE_MSG_ID_CAMIF_ERROR, NULL);
+	}
+
+	if (irqstatus->camifOverflowIrq)
+		vfe_proc_ops(VFE_MSG_ID_CAMIF_OVERFLOW, NULL);
+
+	if (irqstatus->violationIrq)
+		pr_err("%s: violation irq\n", __func__);
+}
+
+static void vfe_process_camif_sof_irq(void)
+{
+	/* increment the frame id number. */
+	ctrl->vfeFrameId++;
+
+	CDBG("camif_sof_irq, frameId = %d\n", ctrl->vfeFrameId);
+
+	/* In snapshot mode, if frame skip is programmed,
+	* need to check it accordingly to stop camif at
+	* correct frame boundary. For the dropped frames,
+	* there won't be any output path irqs, but there is
+	* still SOF irq, which can help us determine when
+	* to stop the camif.
+	*/
+	if (ctrl->vfeOperationMode) {
+		if ((1 << ctrl->vfeFrameSkipCount)&ctrl->vfeFrameSkipPattern) {
+
+			ctrl->vfeSnapShotCount--;
+			if (ctrl->vfeSnapShotCount == 0)
+				/* terminate vfe pipeline at frame boundary. */
+				writel(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
+					ctrl->vfebase + CAMIF_COMMAND);
+		}
+
+		/* update frame skip counter for bit checking. */
+		ctrl->vfeFrameSkipCount++;
+		if (ctrl->vfeFrameSkipCount == (ctrl->vfeFrameSkipPeriod + 1))
+			ctrl->vfeFrameSkipCount = 0;
+	}
+	vfe_proc_ops(VFE_MSG_ID_SOF_ACK, NULL);
+}
+
+static boolean vfe_get_af_pingpong_status(void)
+{
+	uint32_t busPingPongStatus =
+		readl(ctrl->vfebase + VFE_BUS_PINGPONG_STATUS);
+	return !!(busPingPongStatus & VFE_AF_PINGPONG_STATUS_BIT);
+}
+
+static uint32_t vfe_read_af_buf_addr(boolean pipo)
+{
+	if (pipo == FALSE)
+		return readl(ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR);
+	else
+		return readl(ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR);
+}
+
+static void vfe_update_af_buf_addr(boolean pipo, uint32_t addr)
+{
+	if (pipo == FALSE)
+		writel(addr, ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR);
+	else
+		writel(addr, ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR);
+}
+
+static boolean vfe_send_af_stats_msg(struct msm_vfe_resp *rp,
+		struct vfe_message *msg, void *data)
+{
+	uint32_t afBufAddress = (uint32_t)data;
+
+	/* fill message with right content. */
+	/* @todo This is causing issues, need further investigate */
+	/* spin_lock_irqsave(&ctrl->state_lock, flags); */
+	if (ctrl->vstate != VFE_STATE_ACTIVE)
+		return FALSE;
+
+	msg->_u.msgStatsAf.afBuffer = afBufAddress;
+	msg->_u.msgStatsAf.frameCounter = ctrl->vfeFrameId;
+
+	ctrl->afStatsControl.ackPending = TRUE;
+
+	vfe_addr_convert(&(rp->phy), rp->type, msg, NULL, NULL);
+	/* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
+	return TRUE;
+}
+
+static void vfe_process_stats_af_irq(void)
+{
+	boolean bufferAvailable;
+
+	if (!(ctrl->afStatsControl.ackPending)) {
+
+		/* read hardware status. */
+		ctrl->afStatsControl.pingPongStatus =
+			vfe_get_af_pingpong_status();
+
+		bufferAvailable = (ctrl->afStatsControl.pingPongStatus) ^ 1;
+
+		ctrl->afStatsControl.bufToRender =
+			vfe_read_af_buf_addr(bufferAvailable);
+
+		/* update the same buffer address (ping or pong) */
+		vfe_update_af_buf_addr(bufferAvailable,
+			ctrl->afStatsControl.nextFrameAddrBuf);
+
+		vfe_proc_ops(VFE_MSG_ID_STATS_AUTOFOCUS,
+			(void *)ctrl->afStatsControl.bufToRender);
+	} else
+		ctrl->afStatsControl.droppedStatsFrameCount++;
+}
+
+static boolean vfe_get_awb_pingpong_status(void)
+{
+	uint32_t busPingPongStatus =
+
+		readl(ctrl->vfebase + VFE_BUS_PINGPONG_STATUS);
+
+	return !!(busPingPongStatus & VFE_AWB_PINGPONG_STATUS_BIT);
+
+}
+
+static uint32_t vfe_read_awb_buf_addr(boolean pingpong)
+{
+	if (pingpong == FALSE)
+		return readl(ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR);
+	else
+		return readl(ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR);
+}
+
+static void vfe_update_awb_buf_addr(boolean pingpong, uint32_t addr)
+{
+	if (pingpong == FALSE)
+		writel(addr, ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR);
+	else
+		writel(addr, ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR);
+}
+
+static boolean vfe_send_awb_stats_msg(struct msm_vfe_resp *rp,
+		struct vfe_message *msg, void *data)
+{
+	uint32_t awbBufAddress = (uint32_t)data;
+
+	/* fill message with right content. */
+	/* @todo This is causing issues, need further investigate */
+	/* spin_lock_irqsave(&ctrl->state_lock, flags); */
+	if (ctrl->vstate != VFE_STATE_ACTIVE)
+		return FALSE;
+
+	msg->_u.msgStatsWbExp.awbBuffer = awbBufAddress;
+	msg->_u.msgStatsWbExp.frameCounter = ctrl->vfeFrameId;
+
+
+	ctrl->awbStatsControl.ackPending = TRUE;
+
+	vfe_addr_convert(&(rp->phy),
+			rp->type, msg,
+			NULL, NULL);
+
+	return TRUE;
+}
+
+static void vfe_process_stats_awb_irq(void)
+{
+	boolean bufferAvailable;
+
+	if (!(ctrl->awbStatsControl.ackPending)) {
+
+		ctrl->awbStatsControl.pingPongStatus =
+			vfe_get_awb_pingpong_status();
+
+		bufferAvailable = (ctrl->awbStatsControl.pingPongStatus) ^ 1;
+
+		ctrl->awbStatsControl.bufToRender =
+			vfe_read_awb_buf_addr(bufferAvailable);
+
+		vfe_update_awb_buf_addr(bufferAvailable,
+			ctrl->awbStatsControl.nextFrameAddrBuf);
+
+		vfe_proc_ops(VFE_MSG_ID_STATS_WB_EXP,
+			(void *)ctrl->awbStatsControl.bufToRender);
+
+	} else
+		ctrl->awbStatsControl.droppedStatsFrameCount++;
+}
+
+static void vfe_write_gamma_table(uint8_t channel,
+	boolean bank, int16_t *pTable)
+{
+	uint16_t i;
+
+	enum VFE_DMI_RAM_SEL dmiRamSel = NO_MEM_SELECTED;
+
+	switch (channel) {
+	case 0:
+		if (bank == 0)
+			dmiRamSel = RGBLUT_RAM_CH0_BANK0;
+		else
+			dmiRamSel = RGBLUT_RAM_CH0_BANK1;
+		break;
+
+	case 1:
+		if (bank == 0)
+			dmiRamSel = RGBLUT_RAM_CH1_BANK0;
+		else
+			dmiRamSel = RGBLUT_RAM_CH1_BANK1;
+		break;
+
+	case 2:
+		if (bank == 0)
+			dmiRamSel = RGBLUT_RAM_CH2_BANK0;
+		else
+			dmiRamSel = RGBLUT_RAM_CH2_BANK1;
+		break;
+
+	default:
+		break;
+	}
+
+	vfe_program_dmi_cfg(dmiRamSel);
+
+	for (i = 0; i < VFE_GAMMA_TABLE_LENGTH; i++) {
+		writel((uint32_t)(*pTable), ctrl->vfebase + VFE_DMI_DATA_LO);
+		pTable++;
+	}
+
+	/* After DMI transfer, need to set the DMI_CFG to unselect any SRAM
+	unselect the SRAM Bank. */
+	writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG);
+}
+
+static void vfe_prog_hw_testgen_cmd(uint32_t value)
+{
+	writel(value, ctrl->vfebase + VFE_HW_TESTGEN_CMD);
+}
+
+static inline void vfe_read_irq_status(struct vfe_irq_thread_msg *out)
+{
+	uint32_t *temp;
+
+	memset(out, 0, sizeof(struct vfe_irq_thread_msg));
+
+	temp = (uint32_t *)(ctrl->vfebase + VFE_IRQ_STATUS);
+	out->vfeIrqStatus = readl(temp);
+
+	temp = (uint32_t *)(ctrl->vfebase + CAMIF_STATUS);
+	out->camifStatus = readl(temp);
+
+/*	this for YUV performance tuning
+	writel(0x7, ctrl->vfebase + CAMIF_COMMAND);
+	writel(0x3, ctrl->vfebase + CAMIF_COMMAND);
+	CDBG("camifStatus  = 0x%x\n", out->camifStatus);
+*/
+/*
+	temp = (uint32_t *)(ctrl->vfebase + VFE_DEMOSAIC_STATUS);
+	out->demosaicStatus = readl(temp);
+
+	temp = (uint32_t *)(ctrl->vfebase + VFE_ASF_MAX_EDGE);
+	out->asfMaxEdge = readl(temp);
+
+	temp = (uint32_t *)(ctrl->vfebase + VFE_BUS_ENC_Y_WR_PM_STATS_0);
+*/
+
+#if 0
+	out->pmInfo.encPathPmInfo.yWrPmStats0      = readl(temp++);
+	out->pmInfo.encPathPmInfo.yWrPmStats1      = readl(temp++);
+	out->pmInfo.encPathPmInfo.cbcrWrPmStats0   = readl(temp++);
+	out->pmInfo.encPathPmInfo.cbcrWrPmStats1   = readl(temp++);
+	out->pmInfo.viewPathPmInfo.yWrPmStats0     = readl(temp++);
+	out->pmInfo.viewPathPmInfo.yWrPmStats1     = readl(temp++);
+	out->pmInfo.viewPathPmInfo.cbcrWrPmStats0  = readl(temp++);
+	out->pmInfo.viewPathPmInfo.cbcrWrPmStats1  = readl(temp);
+#endif /* if 0 Jeff */
+}
+
+static void
+vfe_parse_interrupt_status(struct vfe_interrupt_status *ret,
+uint32_t irqStatusIn)
+{
+	struct vfe_irqenable hwstat;
+	boolean temp;
+
+	memset(&hwstat, 0, sizeof(hwstat));
+	memset(ret, 0, sizeof(*ret));
+
+	hwstat = *((struct vfe_irqenable *)(&irqStatusIn));
+
+	ret->camifErrorIrq = hwstat.camifErrorIrq;
+	ret->camifSofIrq = hwstat.camifSofIrq;
+	ret->camifEolIrq = hwstat.camifEolIrq;
+	ret->camifEofIrq = hwstat.camifEofIrq;
+	ret->camifEpoch1Irq = hwstat.camifEpoch1Irq;
+	ret->camifEpoch2Irq = hwstat.camifEpoch2Irq;
+	ret->camifOverflowIrq = hwstat.camifOverflowIrq;
+	ret->ceIrq = hwstat.ceIrq;
+	ret->regUpdateIrq = hwstat.regUpdateIrq;
+	ret->resetAckIrq = hwstat.resetAckIrq;
+	ret->encYPingpongIrq = hwstat.encYPingpongIrq;
+	ret->encCbcrPingpongIrq = hwstat.encCbcrPingpongIrq;
+	ret->viewYPingpongIrq = hwstat.viewYPingpongIrq;
+	ret->viewCbcrPingpongIrq = hwstat.viewCbcrPingpongIrq;
+	ret->rdPingpongIrq = hwstat.rdPingpongIrq;
+	ret->afPingpongIrq = hwstat.afPingpongIrq;
+	ret->awbPingpongIrq = hwstat.awbPingpongIrq;
+	ret->histPingpongIrq = hwstat.histPingpongIrq;
+	ret->encIrq = hwstat.encIrq;
+	ret->viewIrq = hwstat.viewIrq;
+	ret->busOverflowIrq = hwstat.busOverflowIrq;
+	ret->afOverflowIrq = hwstat.afOverflowIrq;
+	ret->awbOverflowIrq = hwstat.awbOverflowIrq;
+	ret->syncTimer0Irq = hwstat.syncTimer0Irq;
+	ret->syncTimer1Irq = hwstat.syncTimer1Irq;
+	ret->syncTimer2Irq = hwstat.syncTimer2Irq;
+	ret->asyncTimer0Irq = hwstat.asyncTimer0Irq;
+	ret->asyncTimer1Irq = hwstat.asyncTimer1Irq;
+	ret->asyncTimer2Irq = hwstat.asyncTimer2Irq;
+	ret->asyncTimer3Irq = hwstat.asyncTimer3Irq;
+	ret->axiErrorIrq = hwstat.axiErrorIrq;
+	ret->violationIrq = hwstat.violationIrq;
+
+	/* logic OR of any error bits
+	 * although each irq corresponds to a bit, the data type here is a
+	 * boolean already. hence use logic operation.
+	 */
+	temp =
+	    ret->camifErrorIrq ||
+	    ret->camifOverflowIrq ||
+	    ret->afOverflowIrq ||
+	    ret->awbOverflowIrq ||
+	    ret->awbPingpongIrq ||
+	    ret->afPingpongIrq ||
+	    ret->busOverflowIrq || ret->axiErrorIrq || ret->violationIrq;
+
+	ret->anyErrorIrqs = temp;
+
+	/* logic OR of any output path bits*/
+	temp = ret->encYPingpongIrq || ret->encCbcrPingpongIrq || ret->encIrq;
+
+	ret->anyOutput2PathIrqs = temp;
+
+	temp = ret->viewYPingpongIrq || ret->viewCbcrPingpongIrq ||
+		ret->viewIrq;
+
+	ret->anyOutput1PathIrqs = temp;
+
+	ret->anyOutputPathIrqs =
+	    ret->anyOutput1PathIrqs || ret->anyOutput2PathIrqs;
+
+	/* logic OR of any sync timer bits*/
+	temp = ret->syncTimer0Irq || ret->syncTimer1Irq || ret->syncTimer2Irq;
+
+	ret->anySyncTimerIrqs = temp;
+
+	/* logic OR of any async timer bits*/
+	temp =
+	    ret->asyncTimer0Irq ||
+	    ret->asyncTimer1Irq || ret->asyncTimer2Irq || ret->asyncTimer3Irq;
+
+	ret->anyAsyncTimerIrqs = temp;
+
+	/* bool for all interrupts that are not allowed in idle state */
+	temp =
+	    ret->anyErrorIrqs ||
+	    ret->anyOutputPathIrqs ||
+	    ret->anySyncTimerIrqs ||
+	    ret->regUpdateIrq ||
+	    ret->awbPingpongIrq ||
+	    ret->afPingpongIrq ||
+	    ret->camifSofIrq || ret->camifEpoch2Irq || ret->camifEpoch1Irq;
+
+	ret->anyIrqForActiveStatesOnly = temp;
+}
+
+static void
+vfe_get_asf_frame_info(struct vfe_frame_asf_info *rc,
+struct vfe_irq_thread_msg *in)
+{
+	struct vfe_asf_info     asfInfoTemp;
+
+	memset(rc, 0, sizeof(*rc));
+	memset(&asfInfoTemp, 0, sizeof(asfInfoTemp));
+
+	asfInfoTemp = *((struct vfe_asf_info *)(&(in->asfMaxEdge)));
+
+	rc->asfHbiCount = asfInfoTemp.HBICount;
+	rc->asfMaxEdge = asfInfoTemp.maxEdge;
+}
+
+static void
+vfe_get_demosaic_frame_info(struct vfe_frame_bpc_info *rc,
+struct vfe_irq_thread_msg *in)
+{
+	struct vfe_bps_info     bpcInfoTemp;
+
+	memset(rc, 0, sizeof(*rc));
+	memset(&bpcInfoTemp, 0, sizeof(bpcInfoTemp));
+
+	bpcInfoTemp = *((struct vfe_bps_info *)(&(in->demosaicStatus)));
+
+	rc->greenDefectPixelCount = bpcInfoTemp.greenBadPixelCount;
+
+	rc->redBlueDefectPixelCount = bpcInfoTemp.RedBlueBadPixelCount;
+}
+
+static void
+vfe_get_camif_status(struct vfe_msg_camif_status *rc,
+struct vfe_irq_thread_msg *in)
+{
+	struct vfe_camif_stats camifStatusTemp;
+
+	memset(rc, 0, sizeof(*rc));
+	memset(&camifStatusTemp, 0, sizeof(camifStatusTemp));
+
+	camifStatusTemp = *((struct vfe_camif_stats *)(&(in->camifStatus)));
+
+	rc->camifState = (boolean) camifStatusTemp.camifHalt;
+	rc->lineCount = camifStatusTemp.lineCount;
+	rc->pixelCount = camifStatusTemp.pixelCount;
+}
+
+static void
+vfe_get_performance_monitor_data(struct vfe_bus_performance_monitor *rc,
+		struct vfe_irq_thread_msg *in)
+{
+	memset(rc, 0, sizeof(*rc));
+
+	rc->encPathPmInfo.yWrPmStats0 = in->pmInfo.encPathPmInfo.yWrPmStats0;
+	rc->encPathPmInfo.yWrPmStats1 = in->pmInfo.encPathPmInfo.yWrPmStats1;
+	rc->encPathPmInfo.cbcrWrPmStats0 =
+		in->pmInfo.encPathPmInfo.cbcrWrPmStats0;
+	rc->encPathPmInfo.cbcrWrPmStats1 =
+		in->pmInfo.encPathPmInfo.cbcrWrPmStats1;
+	rc->viewPathPmInfo.yWrPmStats0 = in->pmInfo.viewPathPmInfo.yWrPmStats0;
+	rc->viewPathPmInfo.yWrPmStats1 = in->pmInfo.viewPathPmInfo.yWrPmStats1;
+	rc->viewPathPmInfo.cbcrWrPmStats0 =
+		in->pmInfo.viewPathPmInfo.cbcrWrPmStats0;
+	rc->viewPathPmInfo.cbcrWrPmStats1 =
+	    in->pmInfo.viewPathPmInfo.cbcrWrPmStats1;
+}
+
+static void vfe_process_reg_update_irq(void)
+{
+	CDBG("vfe_process_reg_update_irq: ackPendingFlag is %d\n",
+	ctrl->vfeStartAckPendingFlag);
+	if (ctrl->vfeStartAckPendingFlag == TRUE) {
+		vfe_proc_ops(VFE_MSG_ID_START_ACK, NULL);
+		ctrl->vfeStartAckPendingFlag = FALSE;
+	} else
+		vfe_proc_ops(VFE_MSG_ID_UPDATE_ACK, NULL);
+}
+
+static void vfe_process_reset_irq(void)
+{
+	/* unsigned long flags; */
+
+	/* @todo This is causing issues, need further investigate */
+	/* spin_lock_irqsave(&ctrl->state_lock, flags); */
+	ctrl->vstate = VFE_STATE_IDLE;
+	/* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
+
+	if (ctrl->vfeStopAckPending == TRUE) {
+		ctrl->vfeStopAckPending = FALSE;
+		vfe_proc_ops(VFE_MSG_ID_STOP_ACK, NULL);
+	} else {
+		vfe_set_default_reg_values();
+		vfe_proc_ops(VFE_MSG_ID_RESET_ACK, NULL);
+	}
+}
+
+static void vfe_process_pingpong_irq(struct vfe_output_path *in,
+	uint8_t fragmentCount)
+{
+	uint16_t circularIndex;
+	uint32_t nextFragmentAddr;
+
+	/* get next fragment address from circular buffer */
+	circularIndex    = (in->fragIndex) % (2 * fragmentCount);
+	nextFragmentAddr = in->addressBuffer[circularIndex];
+
+	in->fragIndex = circularIndex + 1;
+
+	/* use next fragment to program hardware ping/pong address. */
+	if (in->hwCurrentFlag == ping) {
+		writel(nextFragmentAddr, in->hwRegPingAddress);
+		in->hwCurrentFlag = pong;
+
+	} else {
+		writel(nextFragmentAddr, in->hwRegPongAddress);
+		in->hwCurrentFlag = ping;
+	}
+}
+
+static boolean vfe_send_video_msg(struct msm_vfe_resp *rp,
+		struct vfe_message *msg, void *data)
+{
+	struct vfe_msg_output *pPayload = data;
+
+	if (ctrl->vstate != VFE_STATE_ACTIVE)
+		return FALSE;
+	memcpy(&(msg->_u),
+		(void *)pPayload, sizeof(struct vfe_msg_output));
+
+	rp->phy.output_id = OUTPUT_TYPE_V;
+	CDBG("vfe_send_video_msg rp->type= %d\n", rp->type);
+
+	vfe_addr_convert(&(rp->phy),
+			rp->type, msg,
+			&(rp->extdata), &(rp->extlen));
+	return TRUE;
+}
+
+static boolean vfe_send_preview_msg(struct msm_vfe_resp *rp,
+		struct vfe_message *msg, void *data)
+{
+	struct vfe_msg_output *pPayload = data;
+
+	if (ctrl->vstate != VFE_STATE_ACTIVE)
+		return FALSE;
+
+	memcpy(&(msg->_u), (void *)pPayload, sizeof(struct vfe_msg_output));
+
+	rp->phy.output_id = OUTPUT_TYPE_P;
+	CDBG("vfe_send_preview_msg rp->type= %d\n", rp->type);
+
+	vfe_addr_convert(&(rp->phy),
+			rp->type, msg,
+			&(rp->extdata), &(rp->extlen));
+
+	return TRUE;
+}
+
+
+static boolean vfe_send_thumbnail_msg(struct msm_vfe_resp *rp,
+		struct vfe_message *msg, void *data)
+{
+	struct vfe_msg_output *pPayload = data;
+
+	if (ctrl->vstate != VFE_STATE_ACTIVE)
+		return FALSE;
+
+	memcpy(&(msg->_u), (void *)pPayload, sizeof(struct vfe_msg_output));
+
+	rp->phy.output_id = OUTPUT_TYPE_T;
+	CDBG("vfe_send_thumbnail_msg rp->type= %d\n", rp->type);
+
+	if (ctrl->viewPath.snapshotPendingCount <= 1)
+		ctrl->viewPath.ackPending = FALSE;
+
+	vfe_addr_convert(&(rp->phy),
+			rp->type, msg,
+			&(rp->extdata), &(rp->extlen));
+	return TRUE;
+}
+
+static boolean vfe_send_mainimage_msg(struct msm_vfe_resp *rp,
+		struct vfe_message *msg, void *data)
+{
+	struct vfe_msg_output *pPayload = data;
+
+	if (ctrl->vstate != VFE_STATE_ACTIVE)
+		return FALSE;
+
+	memcpy(&(msg->_u), (void *)pPayload, sizeof(struct vfe_msg_output));
+
+	rp->phy.output_id = OUTPUT_TYPE_S;
+	CDBG("vfe_send_mainimage_msg rp->type= %d\n", rp->type);
+
+	if (ctrl->encPath.snapshotPendingCount <= 1) {
+		ctrl->encPath.ackPending = FALSE;
+	}
+
+	vfe_addr_convert(&(rp->phy),
+			rp->type, msg,
+			&(rp->extdata), &(rp->extlen));
+
+	return TRUE;
+}
+
+static void vfe_send_output_msg(boolean whichOutputPath,
+	uint32_t yPathAddr, uint32_t cbcrPathAddr)
+{
+	struct vfe_msg_output msgPayload;
+
+	msgPayload.yBuffer = yPathAddr;
+	msgPayload.cbcrBuffer = cbcrPathAddr;
+
+	/* asf info is common for both output1 and output2 */
+#if 0
+	msgPayload.asfInfo.asfHbiCount = ctrl->vfeAsfFrameInfo.asfHbiCount;
+	msgPayload.asfInfo.asfMaxEdge = ctrl->vfeAsfFrameInfo.asfMaxEdge;
+
+	/* demosaic info is common for both output1 and output2 */
+	msgPayload.bpcInfo.greenDefectPixelCount =
+		ctrl->vfeBpcFrameInfo.greenDefectPixelCount;
+	msgPayload.bpcInfo.redBlueDefectPixelCount =
+		ctrl->vfeBpcFrameInfo.redBlueDefectPixelCount;
+#endif /* if 0 */
+
+	/* frame ID is common for both paths. */
+	msgPayload.frameCounter = ctrl->vfeFrameId;
+
+	if (whichOutputPath) {
+		/* msgPayload.pmData = ctrl->vfePmData.encPathPmInfo; */
+		ctrl->encPath.ackPending = TRUE;
+
+		if (ctrl->vfeOperationMode == 0) {
+			if (ctrl->axiOutputMode ==
+				VFE_AXI_OUTPUT_MODE_Output1AndOutput2) {
+				/* video mode */
+				vfe_proc_ops(VFE_MSG_ID_OUTPUT_V, &msgPayload);
+			} else{
+				/* preview mode */
+				vfe_proc_ops(VFE_MSG_ID_OUTPUT_P, &msgPayload);
+			}
+		} else {
+			vfe_proc_ops(VFE_MSG_ID_OUTPUT_S, &msgPayload);
+		}
+
+	} else {
+		/* physical output1 path from vfe */
+		ctrl->viewPath.ackPending = TRUE;
+
+		if (ctrl->vfeOperationMode == 0) {
+			vfe_proc_ops(VFE_MSG_ID_OUTPUT_P, &msgPayload);
+			CDBG(" video mode display output.\n");
+
+		} else{
+			vfe_proc_ops(VFE_MSG_ID_OUTPUT_T, &msgPayload);
+			CDBG(" snapshot mode thumbnail output.\n");
+		}
+	}
+}
+
+static void vfe_process_frame_done_irq_multi_frag(struct vfe_output_path_combo
+						  *in)
+{
+	uint32_t yAddress, cbcrAddress;
+	uint16_t idx;
+	uint32_t *ptrY;
+	uint32_t *ptrCbcr;
+	const uint32_t *ptrSrc;
+	uint8_t i;
+
+	if (!in->ackPending) {
+
+		idx = (in->currentFrame) * (in->fragCount);
+
+		/* Send output message. */
+		yAddress = in->yPath.addressBuffer[idx];
+		cbcrAddress = in->cbcrPath.addressBuffer[idx];
+
+		/* copy next frame to current frame. */
+		ptrSrc  = in->nextFrameAddrBuf;
+		ptrY = (uint32_t *)&in->yPath.addressBuffer[idx];
+		ptrCbcr = (uint32_t *)&in->cbcrPath.addressBuffer[idx];
+
+		/* Copy Y address */
+		for (i = 0; i < in->fragCount; i++)
+			*ptrY++ = *ptrSrc++;
+
+		/* Copy Cbcr address */
+		for (i = 0; i < in->fragCount; i++)
+			*ptrCbcr++ = *ptrSrc++;
+
+		vfe_send_output_msg(in->whichOutputPath, yAddress, cbcrAddress);
+
+	} else {
+		if (in->whichOutputPath == 0)
+			ctrl->vfeDroppedFrameCounts.output1Count++;
+
+		if (in->whichOutputPath == 1)
+			ctrl->vfeDroppedFrameCounts.output2Count++;
+	}
+
+	/* toggle current frame. */
+	in->currentFrame = in->currentFrame^1;
+
+	if (ctrl->vfeOperationMode)
+		in->snapshotPendingCount--;
+}
+
+static void vfe_process_frame_done_irq_no_frag_io(
+		struct vfe_output_path_combo *in,
+		uint32_t *pNextAddr,
+	uint32_t *pdestRenderAddr)
+{
+	uint32_t busPingPongStatus;
+	uint32_t tempAddress;
+
+	/* 1. read hw status register. */
+	busPingPongStatus = readl(ctrl->vfebase + VFE_BUS_PINGPONG_STATUS);
+
+	CDBG("hardware status is 0x%x\n", busPingPongStatus);
+
+	/* 2. determine ping or pong */
+	/* use cbcr status */
+	busPingPongStatus = busPingPongStatus & (1<<(in->cbcrStatusBit));
+
+	/* 3. read out address and update address */
+	if (busPingPongStatus == 0) {
+		/* hw is working on ping, render pong buffer */
+		/* a. read out pong address */
+		/* read out y address. */
+		tempAddress = readl(in->yPath.hwRegPongAddress);
+
+		CDBG("pong 1 addr = 0x%x\n", tempAddress);
+		*pdestRenderAddr++ = tempAddress;
+		/* read out cbcr address. */
+		tempAddress = readl(in->cbcrPath.hwRegPongAddress);
+
+		CDBG("pong 2 addr = 0x%x\n", tempAddress);
+		*pdestRenderAddr = tempAddress;
+
+		/* b. update pong address */
+		writel(*pNextAddr++, in->yPath.hwRegPongAddress);
+		writel(*pNextAddr, in->cbcrPath.hwRegPongAddress);
+	} else {
+		/* hw is working on pong, render ping buffer */
+
+		/* a. read out ping address */
+		tempAddress = readl(in->yPath.hwRegPingAddress);
+		CDBG("ping 1 addr = 0x%x\n", tempAddress);
+		*pdestRenderAddr++ = tempAddress;
+		tempAddress = readl(in->cbcrPath.hwRegPingAddress);
+
+		CDBG("ping 2 addr = 0x%x\n", tempAddress);
+		*pdestRenderAddr = tempAddress;
+
+		/* b. update ping address */
+		writel(*pNextAddr++, in->yPath.hwRegPingAddress);
+		CDBG("NextAddress = 0x%x\n", *pNextAddr);
+		writel(*pNextAddr, in->cbcrPath.hwRegPingAddress);
+	}
+}
+
+static void vfe_process_frame_done_irq_no_frag(struct vfe_output_path_combo *in)
+{
+	uint32_t addressToRender[2];
+
+	if (!in->ackPending) {
+		vfe_process_frame_done_irq_no_frag_io(in,
+						      in->nextFrameAddrBuf,
+						      addressToRender);
+
+		/* use addressToRender to send out message. */
+		vfe_send_output_msg(in->whichOutputPath,
+				addressToRender[0], addressToRender[1]);
+
+	} else {
+		/* ackPending is still there, accumulate dropped frame count.
+		 * These count can be read through ioctrl command. */
+		CDBG("waiting frame ACK\n");
+
+		if (in->whichOutputPath == 0)
+			ctrl->vfeDroppedFrameCounts.output1Count++;
+
+		if (in->whichOutputPath == 1)
+			ctrl->vfeDroppedFrameCounts.output2Count++;
+	}
+
+	/* in case of multishot when upper layer did not ack, there will still
+	 * be a snapshot done msg sent out, even though the number of frames
+	 * sent out may be less than the desired number of frames.  snapshot
+	 * done msg would be helpful to indicate that vfe pipeline has stop,
+	 * and in good known state.
+	 */
+	if (ctrl->vfeOperationMode)
+		in->snapshotPendingCount--;
+}
+
+static void vfe_process_output_path_irq(struct vfe_interrupt_status *irqstatus)
+{
+	/* unsigned long flags; */
+
+	/* process the view path interrupts */
+	if (irqstatus->anyOutput1PathIrqs) {
+		if (ctrl->viewPath.multiFrag) {
+
+			if (irqstatus->viewCbcrPingpongIrq)
+				vfe_process_pingpong_irq(&
+							 (ctrl->viewPath.
+							  cbcrPath),
+							 ctrl->viewPath.
+							 fragCount);
+
+			if (irqstatus->viewYPingpongIrq)
+				vfe_process_pingpong_irq(&
+							 (ctrl->viewPath.yPath),
+							 ctrl->viewPath.
+							 fragCount);
+
+			if (irqstatus->viewIrq)
+				vfe_process_frame_done_irq_multi_frag(&ctrl->
+								      viewPath);
+
+		} else {
+			/* typical case for no fragment,
+			 only frame done irq is enabled. */
+			if (irqstatus->viewIrq)
+				vfe_process_frame_done_irq_no_frag(&ctrl->
+								   viewPath);
+		}
+	}
+
+	/* process the encoder path interrupts */
+	if (irqstatus->anyOutput2PathIrqs) {
+		if (ctrl->encPath.multiFrag) {
+			if (irqstatus->encCbcrPingpongIrq)
+				vfe_process_pingpong_irq(&
+							 (ctrl->encPath.
+							  cbcrPath),
+							 ctrl->encPath.
+							 fragCount);
+
+			if (irqstatus->encYPingpongIrq)
+				vfe_process_pingpong_irq(&(ctrl->encPath.yPath),
+							 ctrl->encPath.
+							 fragCount);
+
+			if (irqstatus->encIrq)
+				vfe_process_frame_done_irq_multi_frag(&ctrl->
+								      encPath);
+
+		} else {
+			if (irqstatus->encIrq)
+				vfe_process_frame_done_irq_no_frag(&ctrl->
+								   encPath);
+		}
+	}
+
+	if (ctrl->vfeOperationMode) {
+		if ((ctrl->encPath.snapshotPendingCount == 0) &&
+				(ctrl->viewPath.snapshotPendingCount == 0)) {
+
+			/* @todo This is causing issues, further investigate */
+			/* spin_lock_irqsave(&ctrl->state_lock, flags); */
+			ctrl->vstate = VFE_STATE_IDLE;
+			/* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
+
+			vfe_proc_ops(VFE_MSG_ID_SNAPSHOT_DONE, NULL);
+			vfe_camif_stop_immediately();
+			vfe_prog_hw_testgen_cmd(VFE_TEST_GEN_STOP);
+			vfe_pm_stop();
+		}
+	}
+}
+
+static void __vfe_do_tasklet(struct isr_queue_cmd *qcmd)
+{
+	if (qcmd->vfeInterruptStatus.regUpdateIrq) {
+		CDBG("irq regUpdateIrq\n");
+		vfe_process_reg_update_irq();
+	}
+
+	if (qcmd->vfeInterruptStatus.resetAckIrq) {
+		CDBG("%s: process resetAckIrq\n", __func__);
+		vfe_process_reset_irq();
+	}
+
+	if (ctrl->vstate != VFE_STATE_ACTIVE)
+		return;
+
+#if 0
+	if (qcmd->vfeInterruptStatus.camifEpoch1Irq)
+		vfe_proc_ops(VFE_MSG_ID_EPOCH1);
+
+	if (qcmd->vfeInterruptStatus.camifEpoch2Irq)
+		vfe_proc_ops(VFE_MSG_ID_EPOCH2);
+#endif /* Jeff */
+
+	/* next, check output path related interrupts. */
+	if (qcmd->vfeInterruptStatus.anyOutputPathIrqs) {
+		CDBG("irq: anyOutputPathIrqs\n");
+		vfe_process_output_path_irq(&qcmd->vfeInterruptStatus);
+	}
+
+	if (qcmd->vfeInterruptStatus.afPingpongIrq)
+		vfe_process_stats_af_irq();
+
+	if (qcmd->vfeInterruptStatus.awbPingpongIrq)
+		vfe_process_stats_awb_irq();
+
+	/* any error irqs*/
+	if (qcmd->vfeInterruptStatus.anyErrorIrqs)
+		vfe_process_error_irq(&qcmd->vfeInterruptStatus);
+
+#if 0
+	if (qcmd->vfeInterruptStatus.anySyncTimerIrqs)
+		vfe_process_sync_timer_irq();
+
+	if (qcmd->vfeInterruptStatus.anyAsyncTimerIrqs)
+		vfe_process_async_timer_irq();
+#endif /* Jeff */
+
+	if (qcmd->vfeInterruptStatus.camifSofIrq) {
+		CDBG("irq: camifSofIrq\n");
+		vfe_process_camif_sof_irq();
+	}
+}
+
+static struct isr_queue_cmd *get_irq_cmd_nosync(void)
+{
+	int old_get = ctrl->irq_get++;
+	ctrl->irq_get = ctrl->irq_get % ARRAY_SIZE(ctrl->irqs);
+	if (ctrl->irq_get == ctrl->irq_put) {
+		pr_err("%s: out of irq command packets\n", __func__);
+		ctrl->irq_get = old_get;
+		return NULL;
+	}
+
+	return ctrl->irqs + old_get;
+}
+
+static struct isr_queue_cmd *next_irq_cmd(void)
+{
+	unsigned long flags;
+	struct isr_queue_cmd *cmd;
+	spin_lock_irqsave(&ctrl->irqs_lock, flags);
+	if (ctrl->irq_get == ctrl->irq_put) {
+		spin_unlock_irqrestore(&ctrl->irqs_lock, flags);
+		return NULL; /* already empty */
+	}
+	cmd = ctrl->irqs + ctrl->irq_put;
+	spin_unlock_irqrestore(&ctrl->irqs_lock, flags);
+	return cmd;
+}
+
+static void put_irq_cmd(void)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&ctrl->irqs_lock, flags);
+	if (ctrl->irq_get == ctrl->irq_put) {
+		spin_unlock_irqrestore(&ctrl->irqs_lock, flags);
+		return; /* already empty */
+	}
+	ctrl->irq_put++;
+	ctrl->irq_put %= ARRAY_SIZE(ctrl->irqs);
+	spin_unlock_irqrestore(&ctrl->irqs_lock, flags);
+}
+
+static void vfe_do_tasklet(unsigned long data)
+{
+	int cnt = 0;
+	unsigned long flags;
+	struct isr_queue_cmd *qcmd = NULL;
+
+	spin_lock_irqsave(&msm_vfe_ctrl_lock, flags);
+	if (!ctrl) {
+		spin_unlock_irqrestore(&msm_vfe_ctrl_lock, flags);
+		return;
+	}
+
+	CDBG("%s\n", __func__);
+
+	while ((qcmd = next_irq_cmd())) {
+		__vfe_do_tasklet(qcmd);
+		put_irq_cmd();
+		cnt++;
+	}
+
+	if (cnt > ARRAY_SIZE(ctrl->irqs)/2)
+		CDBG("%s: serviced %d vfe interrupts\n", __func__, cnt);
+
+	spin_unlock_irqrestore(&msm_vfe_ctrl_lock, flags);
+}
+
+DECLARE_TASKLET(vfe_tasklet, vfe_do_tasklet, 0);
+
+static irqreturn_t vfe_parse_irq(int irq_num, void *data)
+{
+	unsigned long flags;
+	uint32_t irqStatusLocal;
+	struct vfe_irq_thread_msg irq;
+	struct isr_queue_cmd *qcmd;
+
+	CDBG("vfe_parse_irq\n");
+
+	if (!atomic_read(&ctrl->vfe_serv_interrupt))
+		return IRQ_HANDLED;
+
+	vfe_read_irq_status(&irq);
+
+	if (irq.vfeIrqStatus == 0) {
+		CDBG("vfe_parse_irq: irq.vfeIrqStatus is 0\n");
+		return IRQ_HANDLED;
+	}
+
+	if (ctrl->vfeStopAckPending)
+		irqStatusLocal = (VFE_IMASK_WHILE_STOPPING & irq.vfeIrqStatus);
+	else
+		irqStatusLocal =
+			((ctrl->vfeImaskPacked | VFE_IMASK_ERROR_ONLY) &
+				irq.vfeIrqStatus);
+
+	spin_lock_irqsave(&ctrl->irqs_lock, flags);
+	qcmd = get_irq_cmd_nosync();
+	if (!qcmd) {
+		spin_unlock_irqrestore(&ctrl->irqs_lock, flags);
+		goto done;
+	}
+	/* first parse the interrupt status to local data structures. */
+	vfe_parse_interrupt_status(&qcmd->vfeInterruptStatus, irqStatusLocal);
+	vfe_get_asf_frame_info(&qcmd->vfeAsfFrameInfo, &irq);
+	vfe_get_demosaic_frame_info(&qcmd->vfeBpcFrameInfo, &irq);
+	vfe_get_camif_status(&qcmd->vfeCamifStatusLocal, &irq);
+	vfe_get_performance_monitor_data(&qcmd->vfePmData, &irq);
+	spin_unlock_irqrestore(&ctrl->irqs_lock, flags);
+	tasklet_schedule(&vfe_tasklet);
+
+done:
+	/* clear the pending interrupt of the same kind.*/
+	writel(irq.vfeIrqStatus, ctrl->vfebase + VFE_IRQ_CLEAR);
+
+	return IRQ_HANDLED;
+}
+
+int vfe_cmd_init(struct msm_vfe_callback *presp,
+	struct platform_device *pdev, void *sdata)
+{
+	struct resource	*vfemem, *vfeirq, *vfeio;
+	int rc;
+	struct msm_camera_sensor_info *s_info;
+	s_info = pdev->dev.platform_data;
+
+	pdev->resource = s_info->resource;
+	pdev->num_resources = s_info->num_resources;
+
+	vfemem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!vfemem) {
+		pr_err("%s: no mem resource\n", __func__);
+		return -ENODEV;
+	}
+
+	vfeirq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!vfeirq) {
+		pr_err("%s: no irq resource\n", __func__);
+		return -ENODEV;
+	}
+
+	vfeio = request_mem_region(vfemem->start,
+		resource_size(vfemem), pdev->name);
+	if (!vfeio) {
+		pr_err("%s: VFE region already claimed\n", __func__);
+		return -EBUSY;
+	}
+
+	ctrl = kzalloc(sizeof(struct msm_vfe8x_ctrl), GFP_KERNEL);
+	if (!ctrl) {
+		pr_err("%s: out of memory\n", __func__);
+		rc = -ENOMEM;
+		goto cmd_init_failed1;
+	}
+	atomic_set(&ctrl->vfe_serv_interrupt, 0);
+	ctrl->vfeirq  = vfeirq->start;
+
+	ctrl->vfebase =
+		ioremap(vfemem->start, (vfemem->end - vfemem->start) + 1);
+	if (!ctrl->vfebase) {
+		pr_err("%s: ioremap failed\n", __func__);
+		rc = -ENOMEM;
+		goto cmd_init_failed2;
+	}
+
+	rc = request_irq(ctrl->vfeirq, vfe_parse_irq,
+		IRQF_TRIGGER_RISING, "vfe", 0);
+	if (rc < 0) {
+		pr_err("%s: request_irq(%d) failed\n", __func__, ctrl->vfeirq);
+		goto cmd_init_failed2;
+	}
+
+	if (presp && presp->vfe_resp)
+		ctrl->resp = presp;
+	else {
+		pr_err("%s: no vfe_resp function\n", __func__);
+
+		rc = -EIO;
+		goto cmd_init_failed3;
+	}
+
+	ctrl->syncdata = sdata;
+	return 0;
+
+cmd_init_failed3:
+	disable_irq(ctrl->vfeirq);
+	free_irq(ctrl->vfeirq, 0);
+	iounmap(ctrl->vfebase);
+cmd_init_failed2:
+	kfree(ctrl);
+cmd_init_failed1:
+	release_mem_region(vfemem->start, (vfemem->end - vfemem->start) + 1);
+	return rc;
+}
+
+void vfe_cmd_release(struct platform_device *dev)
+{
+	struct resource	*mem;
+	unsigned long flags;
+	atomic_set(&ctrl->vfe_serv_interrupt, 0);
+	disable_irq(ctrl->vfeirq);
+	free_irq(ctrl->vfeirq, 0);
+
+	iounmap(ctrl->vfebase);
+	mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	release_mem_region(mem->start, (mem->end - mem->start) + 1);
+
+	spin_lock_irqsave(&msm_vfe_ctrl_lock, flags);
+	kfree(ctrl);
+	ctrl = 0;
+	spin_unlock_irqrestore(&msm_vfe_ctrl_lock, flags);
+}
+
+void vfe_stats_af_stop(void)
+{
+	ctrl->vfeStatsCmdLocal.autoFocusEnable = FALSE;
+	ctrl->vfeImaskLocal.afPingpongIrq = FALSE;
+}
+
+void vfe_stop(void)
+{
+	int spin_cnt = 0;
+	uint32_t vfeAxiStauts;
+
+	/* for reset hw modules, and send msg when reset_irq comes.*/
+	ctrl->vfeStopAckPending = TRUE;
+
+	ctrl->vfeStatsPingPongReloadFlag = FALSE;
+	vfe_pm_stop();
+
+	/* disable all interrupts.  */
+	vfe_program_irq_mask(VFE_DISABLE_ALL_IRQS);
+
+	/* in either continuous or snapshot mode, stop command can be issued
+	 * at any time.
+	 */
+	vfe_camif_stop_immediately();
+	vfe_program_axi_cmd(AXI_HALT);
+	vfe_prog_hw_testgen_cmd(VFE_TEST_GEN_STOP);
+
+	do {
+		vfeAxiStauts = vfe_read_axi_status();
+		spin_cnt++;
+	} while (!(vfeAxiStauts & AXI_STATUS_BUSY_MASK));
+	if (spin_cnt > 1)
+		pr_warning("%s: spin_cnt %d\n", __func__, spin_cnt);
+
+	vfe_program_axi_cmd(AXI_HALT_CLEAR);
+
+	/* clear all pending interrupts */
+	writel(VFE_CLEAR_ALL_IRQS, ctrl->vfebase + VFE_IRQ_CLEAR);
+
+	/* enable reset_ack and async timer interrupt only while stopping
+	 * the pipeline.
+	 */
+	vfe_program_irq_mask(VFE_IMASK_WHILE_STOPPING);
+
+	vfe_program_global_reset_cmd(VFE_RESET_UPON_STOP_CMD);
+}
+
+void vfe_update(void)
+{
+	ctrl->vfeModuleEnableLocal.statsEnable =
+		ctrl->vfeStatsCmdLocal.autoFocusEnable |
+		ctrl->vfeStatsCmdLocal.axwEnable;
+
+	vfe_reg_module_cfg(&ctrl->vfeModuleEnableLocal);
+
+	vfe_program_stats_cmd(&ctrl->vfeStatsCmdLocal);
+
+	ctrl->vfeImaskPacked = vfe_irq_pack(ctrl->vfeImaskLocal);
+	vfe_program_irq_mask(ctrl->vfeImaskPacked);
+
+	if ((ctrl->vfeModuleEnableLocal.statsEnable == TRUE) &&
+			(ctrl->vfeStatsPingPongReloadFlag == FALSE)) {
+		ctrl->vfeStatsPingPongReloadFlag = TRUE;
+
+		ctrl->vfeBusCmdLocal.statsPingpongReload = TRUE;
+		vfe_reg_bus_cmd(&ctrl->vfeBusCmdLocal);
+	}
+
+	vfe_program_reg_update_cmd(VFE_REG_UPDATE_TRIGGER);
+}
+
+int vfe_rgb_gamma_update(struct vfe_cmd_rgb_gamma_config *in)
+{
+	int rc = 0;
+
+	ctrl->vfeModuleEnableLocal.rgbLUTEnable = in->enable;
+
+	switch (in->channelSelect) {
+	case RGB_GAMMA_CH0_SELECTED:
+		ctrl->vfeGammaLutSel.ch0BankSelect ^= 1;
+		vfe_write_gamma_table(0,
+				      ctrl->vfeGammaLutSel.ch0BankSelect,
+				      in->table);
+		break;
+
+	case RGB_GAMMA_CH1_SELECTED:
+		ctrl->vfeGammaLutSel.ch1BankSelect ^= 1;
+		vfe_write_gamma_table(1,
+				      ctrl->vfeGammaLutSel.ch1BankSelect,
+				      in->table);
+		break;
+
+	case RGB_GAMMA_CH2_SELECTED:
+		ctrl->vfeGammaLutSel.ch2BankSelect ^= 1;
+		vfe_write_gamma_table(2,
+				      ctrl->vfeGammaLutSel.ch2BankSelect,
+				      in->table);
+		break;
+
+	case RGB_GAMMA_CH0_CH1_SELECTED:
+		ctrl->vfeGammaLutSel.ch0BankSelect ^= 1;
+		ctrl->vfeGammaLutSel.ch1BankSelect ^= 1;
+		vfe_write_gamma_table(0, ctrl->vfeGammaLutSel.ch0BankSelect,
+			in->table);
+		vfe_write_gamma_table(1, ctrl->vfeGammaLutSel.ch1BankSelect,
+			in->table);
+		break;
+
+	case RGB_GAMMA_CH0_CH2_SELECTED:
+		ctrl->vfeGammaLutSel.ch0BankSelect ^= 1;
+		ctrl->vfeGammaLutSel.ch2BankSelect ^= 1;
+		vfe_write_gamma_table(0, ctrl->vfeGammaLutSel.ch0BankSelect,
+			in->table);
+		vfe_write_gamma_table(2, ctrl->vfeGammaLutSel.ch2BankSelect,
+			in->table);
+		break;
+
+	case RGB_GAMMA_CH1_CH2_SELECTED:
+		ctrl->vfeGammaLutSel.ch1BankSelect ^= 1;
+		ctrl->vfeGammaLutSel.ch2BankSelect ^= 1;
+		vfe_write_gamma_table(1, ctrl->vfeGammaLutSel.ch1BankSelect,
+			in->table);
+		vfe_write_gamma_table(2, ctrl->vfeGammaLutSel.ch2BankSelect,
+			in->table);
+		break;
+
+	case RGB_GAMMA_CH0_CH1_CH2_SELECTED:
+		ctrl->vfeGammaLutSel.ch0BankSelect ^= 1;
+		ctrl->vfeGammaLutSel.ch1BankSelect ^= 1;
+		ctrl->vfeGammaLutSel.ch2BankSelect ^= 1;
+		vfe_write_gamma_table(0, ctrl->vfeGammaLutSel.ch0BankSelect,
+			in->table);
+		vfe_write_gamma_table(1, ctrl->vfeGammaLutSel.ch1BankSelect,
+			in->table);
+		vfe_write_gamma_table(2, ctrl->vfeGammaLutSel.ch2BankSelect,
+			in->table);
+		break;
+
+	default:
+		pr_err("%s: invalid gamma channel %d\n", __func__,
+			in->channelSelect);
+		return -EINVAL;
+	} /* switch */
+
+	/* update the gammaLutSel register. */
+	vfe_program_lut_bank_sel(&ctrl->vfeGammaLutSel);
+
+	return rc;
+}
+
+int vfe_rgb_gamma_config(struct vfe_cmd_rgb_gamma_config *in)
+{
+	int rc = 0;
+
+	ctrl->vfeModuleEnableLocal.rgbLUTEnable = in->enable;
+
+	switch (in->channelSelect) {
+	case RGB_GAMMA_CH0_SELECTED:
+vfe_write_gamma_table(0, 0, in->table);
+break;
+
+	case RGB_GAMMA_CH1_SELECTED:
+		vfe_write_gamma_table(1, 0, in->table);
+		break;
+
+	case RGB_GAMMA_CH2_SELECTED:
+		vfe_write_gamma_table(2, 0, in->table);
+		break;
+
+	case RGB_GAMMA_CH0_CH1_SELECTED:
+		vfe_write_gamma_table(0, 0, in->table);
+		vfe_write_gamma_table(1, 0, in->table);
+		break;
+
+	case RGB_GAMMA_CH0_CH2_SELECTED:
+		vfe_write_gamma_table(0, 0, in->table);
+		vfe_write_gamma_table(2, 0, in->table);
+		break;
+
+	case RGB_GAMMA_CH1_CH2_SELECTED:
+		vfe_write_gamma_table(1, 0, in->table);
+		vfe_write_gamma_table(2, 0, in->table);
+		break;
+
+	case RGB_GAMMA_CH0_CH1_CH2_SELECTED:
+		vfe_write_gamma_table(0, 0, in->table);
+		vfe_write_gamma_table(1, 0, in->table);
+		vfe_write_gamma_table(2, 0, in->table);
+		break;
+
+	default:
+		pr_err("%s: invalid gamma channel %d\n", __func__,
+			in->channelSelect);
+		rc = -EINVAL;
+		break;
+	} /* switch */
+
+	return rc;
+}
+
+void vfe_stats_af_ack(struct vfe_cmd_stats_af_ack *in)
+{
+	ctrl->afStatsControl.nextFrameAddrBuf = in->nextAFOutputBufferAddr;
+	ctrl->afStatsControl.ackPending = FALSE;
+}
+
+void vfe_stats_wb_exp_ack(struct vfe_cmd_stats_wb_exp_ack *in)
+{
+	ctrl->awbStatsControl.nextFrameAddrBuf = in->nextWbExpOutputBufferAddr;
+	ctrl->awbStatsControl.ackPending = FALSE;
+}
+
+
+void vfe_output_v_ack(struct vfe_cmd_output_ack *in)
+{
+	const uint32_t *psrc;
+	uint32_t *pdest;
+	uint8_t i;
+
+	pdest = ctrl->encPath.nextFrameAddrBuf;
+
+	CDBG("video_frame_ack: ack addr = 0x%x\n", in->ybufaddr[0]);
+
+	psrc = in->ybufaddr;
+	for (i = 0; i < ctrl->encPath.fragCount; i++)
+		*pdest++ = *psrc++;
+
+	psrc = in->chromabufaddr;
+	for (i = 0; i < ctrl->encPath.fragCount; i++)
+		*pdest++ = *psrc++;
+
+	ctrl->encPath.ackPending = FALSE;
+}
+
+void vfe_output_p_ack(struct vfe_cmd_output_ack *in)
+{
+	const uint32_t *psrc;
+	uint32_t *pdest;
+	uint8_t i;
+
+	if (ctrl->axiOutputMode == VFE_AXI_OUTPUT_MODE_Output1AndOutput2) {
+		/* video mode, preview comes from output1 path */
+
+	pdest = ctrl->viewPath.nextFrameAddrBuf;
+
+	psrc = in->ybufaddr;
+	for (i = 0; i < ctrl->viewPath.fragCount; i++)
+		*pdest++ = *psrc++;
+
+	psrc = in->chromabufaddr;
+	for (i = 0; i < ctrl->viewPath.fragCount; i++)
+		*pdest++ = *psrc++;
+
+	ctrl->viewPath.ackPending = FALSE;
+
+	} else { /* preview mode, preview comes from output2 path. */
+		pdest = ctrl->encPath.nextFrameAddrBuf;
+
+		psrc = in->ybufaddr;
+		for (i = 0; i < ctrl->encPath.fragCount; i++)
+			*pdest++ = *psrc++;
+
+		psrc = in->chromabufaddr;
+		for (i = 0; i < ctrl->encPath.fragCount; i++)
+			*pdest++ = *psrc++;
+
+		ctrl->encPath.ackPending = FALSE;
+
+	}
+}
+
+void vfe_start(struct vfe_cmd_start *in)
+{
+	uint32_t  pmstatus = 0;
+	boolean rawmode;
+	uint32_t  demperiod = 0;
+	uint32_t  demeven = 0;
+	uint32_t  demodd = 0;
+
+	/* derived from other commands.  (camif config, axi output config,
+	 * etc)
+	*/
+	struct vfe_cfg hwcfg;
+	struct vfe_upsample_cfg chromupcfg;
+
+	CDBG("vfe_start operationMode = %d\n", in->operationMode);
+
+	memset(&hwcfg, 0, sizeof(hwcfg));
+	memset(&chromupcfg, 0, sizeof(chromupcfg));
+
+	switch (in->pixel) {
+	case VFE_BAYER_RGRGRG:
+		demperiod = 1;
+		demeven = 0xC9;
+		demodd = 0xAC;
+		break;
+
+	case VFE_BAYER_GRGRGR:
+		demperiod = 1;
+		demeven = 0x9C;
+		demodd = 0xCA;
+		break;
+
+	case VFE_BAYER_BGBGBG:
+		demperiod = 1;
+		demeven = 0xCA;
+		demodd = 0x9C;
+		break;
+
+	case VFE_BAYER_GBGBGB:
+		demperiod = 1;
+		demeven = 0xAC;
+		demodd = 0xC9;
+		break;
+
+	case VFE_YUV_YCbYCr:
+		demperiod = 3;
+		demeven = 0x9CAC;
+		demodd = 0x9CAC;
+		break;
+
+	case VFE_YUV_YCrYCb:
+		demperiod = 3;
+		demeven = 0xAC9C;
+		demodd = 0xAC9C;
+		break;
+
+	case VFE_YUV_CbYCrY:
+		demperiod = 3;
+		demeven = 0xC9CA;
+		demodd = 0xC9CA;
+		break;
+
+	case VFE_YUV_CrYCbY:
+		demperiod = 3;
+		demeven = 0xCAC9;
+		demodd = 0xCAC9;
+		break;
+
+	default:
+		return;
+	}
+
+	vfe_config_demux(demperiod, demeven, demodd);
+
+	vfe_program_lut_bank_sel(&ctrl->vfeGammaLutSel);
+
+	/* save variables to local. */
+	ctrl->vfeOperationMode = in->operationMode;
+	if (ctrl->vfeOperationMode == VFE_START_OPERATION_MODE_SNAPSHOT) {
+
+		update_axi_qos(MSM_AXI_QOS_SNAPSHOT);
+		/* in snapshot mode, initialize snapshot count*/
+		ctrl->vfeSnapShotCount = in->snapshotCount;
+
+		/* save the requested count, this is temporarily done, to
+		help with HJR / multishot. */
+		ctrl->vfeRequestedSnapShotCount = ctrl->vfeSnapShotCount;
+
+		CDBG("requested snapshot count = %d\n", ctrl->vfeSnapShotCount);
+
+		/* Assumption is to have the same pattern and period for both
+		paths, if both paths are used. */
+		if (ctrl->viewPath.pathEnabled) {
+			ctrl->viewPath.snapshotPendingCount = in->snapshotCount;
+
+			ctrl->vfeFrameSkipPattern =
+				ctrl->vfeFrameSkip.output1Pattern;
+			ctrl->vfeFrameSkipPeriod =
+				ctrl->vfeFrameSkip.output1Period;
+		}
+
+		if (ctrl->encPath.pathEnabled) {
+			ctrl->encPath.snapshotPendingCount = in->snapshotCount;
+
+			ctrl->vfeFrameSkipPattern =
+				ctrl->vfeFrameSkip.output2Pattern;
+			ctrl->vfeFrameSkipPeriod =
+				ctrl->vfeFrameSkip.output2Period;
+		}
+	} else
+		update_axi_qos(MSM_AXI_QOS_PREVIEW);
+
+	/* enable color conversion for bayer sensor
+	if stats enabled, need to do color conversion. */
+	if (in->pixel <= VFE_BAYER_GBGBGB)
+		ctrl->vfeStatsCmdLocal.colorConversionEnable = TRUE;
+
+	vfe_program_stats_cmd(&ctrl->vfeStatsCmdLocal);
+
+	if (in->pixel >= VFE_YUV_YCbYCr)
+		ctrl->vfeModuleEnableLocal.chromaUpsampleEnable = TRUE;
+
+	ctrl->vfeModuleEnableLocal.demuxEnable = TRUE;
+
+	/* if any stats module is enabled, the main bit is enabled. */
+	ctrl->vfeModuleEnableLocal.statsEnable =
+		ctrl->vfeStatsCmdLocal.autoFocusEnable |
+		ctrl->vfeStatsCmdLocal.axwEnable;
+
+	vfe_reg_module_cfg(&ctrl->vfeModuleEnableLocal);
+
+	/* in case of offline processing, do not need to config camif. Having
+	 * bus output enabled in camif_config register might confuse the
+	 * hardware?
+	 */
+	if (in->inputSource != VFE_START_INPUT_SOURCE_AXI) {
+		vfe_reg_camif_config(&ctrl->vfeCamifConfigLocal);
+	} else {
+		/* offline processing, enable axi read */
+		ctrl->vfeBusConfigLocal.stripeRdPathEn = TRUE;
+		ctrl->vfeBusCmdLocal.stripeReload = TRUE;
+		ctrl->vfeBusConfigLocal.rawPixelDataSize =
+			ctrl->axiInputDataSize;
+	}
+
+	vfe_reg_bus_cfg(&ctrl->vfeBusConfigLocal);
+
+	/* directly from start command */
+	hwcfg.pixelPattern = in->pixel;
+	hwcfg.inputSource = in->inputSource;
+	writel(*(uint32_t *)&hwcfg, ctrl->vfebase + VFE_CFG);
+
+	/* regardless module enabled or not, it does not hurt
+	 * to program the cositing mode. */
+	chromupcfg.chromaCositingForYCbCrInputs = in->yuvInputCositingMode;
+
+	writel(*(uint32_t *)&chromupcfg,
+		ctrl->vfebase + VFE_CHROMA_UPSAMPLE_CFG);
+
+	/* MISR to monitor the axi read. */
+	writel(0xd8, ctrl->vfebase + VFE_BUS_MISR_MAST_CFG_0);
+
+	/* clear all pending interrupts. */
+	writel(VFE_CLEAR_ALL_IRQS, ctrl->vfebase + VFE_IRQ_CLEAR);
+
+	/*  define how composite interrupt work.  */
+	ctrl->vfeImaskCompositePacked =
+		vfe_irq_composite_pack(ctrl->vfeIrqCompositeMaskLocal);
+
+	vfe_program_irq_composite_mask(ctrl->vfeImaskCompositePacked);
+
+	/*  enable all necessary interrupts.      */
+	ctrl->vfeImaskLocal.camifSofIrq  = TRUE;
+	ctrl->vfeImaskLocal.regUpdateIrq = TRUE;
+	ctrl->vfeImaskLocal.resetAckIrq  = TRUE;
+
+	ctrl->vfeImaskPacked = vfe_irq_pack(ctrl->vfeImaskLocal);
+	vfe_program_irq_mask(ctrl->vfeImaskPacked);
+
+	/* enable bus performance monitor */
+	vfe_8k_pm_start(&ctrl->vfeBusPmConfigLocal);
+
+	/* trigger vfe reg update */
+	ctrl->vfeStartAckPendingFlag = TRUE;
+
+	/* write bus command to trigger reload of ping pong buffer. */
+	ctrl->vfeBusCmdLocal.busPingpongReload = TRUE;
+
+	if (ctrl->vfeModuleEnableLocal.statsEnable == TRUE) {
+		ctrl->vfeBusCmdLocal.statsPingpongReload = TRUE;
+		ctrl->vfeStatsPingPongReloadFlag = TRUE;
+	}
+
+	writel(VFE_REG_UPDATE_TRIGGER, ctrl->vfebase + VFE_REG_UPDATE_CMD);
+
+	/* program later than the reg update. */
+	vfe_reg_bus_cmd(&ctrl->vfeBusCmdLocal);
+
+	if ((in->inputSource ==
+			 VFE_START_INPUT_SOURCE_CAMIF) ||
+	    (in->inputSource == VFE_START_INPUT_SOURCE_TESTGEN))
+		writel(CAMIF_COMMAND_START, ctrl->vfebase + CAMIF_COMMAND);
+
+	/* start test gen if it is enabled */
+	if (ctrl->vfeTestGenStartFlag == TRUE) {
+		ctrl->vfeTestGenStartFlag = FALSE;
+		vfe_prog_hw_testgen_cmd(VFE_TEST_GEN_GO);
+	}
+
+	CDBG("ctrl->axiOutputMode = %d\n", ctrl->axiOutputMode);
+	if (ctrl->axiOutputMode == VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2) {
+		/* raw dump mode */
+		rawmode = TRUE;
+
+		while (rawmode) {
+			pmstatus =
+				readl(ctrl->vfebase +
+					VFE_BUS_ENC_CBCR_WR_PM_STATS_1);
+
+			if ((pmstatus & VFE_PM_BUF_MAX_CNT_MASK) != 0)
+				rawmode = FALSE;
+		}
+
+		vfe_proc_ops(VFE_MSG_ID_START_ACK, NULL);
+		ctrl->vfeStartAckPendingFlag = FALSE;
+	}
+
+	ctrl->vstate = VFE_STATE_ACTIVE;
+}
+
+void vfe_la_update(struct vfe_cmd_la_config *in)
+{
+	int16_t *pTable;
+	enum VFE_DMI_RAM_SEL dmiRamSel;
+	int i;
+
+	pTable = in->table;
+	ctrl->vfeModuleEnableLocal.lumaAdaptationEnable = in->enable;
+
+	/* toggle the bank to be used. */
+	ctrl->vfeLaBankSel ^= 1;
+
+	if (ctrl->vfeLaBankSel == 0)
+		dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK0;
+	else
+		dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK1;
+
+	/* configure the DMI_CFG to select right sram */
+	vfe_program_dmi_cfg(dmiRamSel);
+
+	for (i = 0; i < VFE_LA_TABLE_LENGTH; i++) {
+		writel((uint32_t)(*pTable), ctrl->vfebase + VFE_DMI_DATA_LO);
+		pTable++;
+	}
+
+	/* After DMI transfer, to make it safe, need to set
+	 * the DMI_CFG to unselect any SRAM */
+	writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG);
+	writel(ctrl->vfeLaBankSel, ctrl->vfebase + VFE_LA_CFG);
+}
+
+void vfe_la_config(struct vfe_cmd_la_config *in)
+{
+	uint16_t i;
+	int16_t  *pTable;
+	enum VFE_DMI_RAM_SEL dmiRamSel;
+
+	pTable = in->table;
+	ctrl->vfeModuleEnableLocal.lumaAdaptationEnable = in->enable;
+
+	if (ctrl->vfeLaBankSel == 0)
+		dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK0;
+	else
+		dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK1;
+
+	/* configure the DMI_CFG to select right sram */
+	vfe_program_dmi_cfg(dmiRamSel);
+
+	for (i = 0; i < VFE_LA_TABLE_LENGTH; i++) {
+		writel((uint32_t)(*pTable), ctrl->vfebase + VFE_DMI_DATA_LO);
+		pTable++;
+	}
+
+	/* After DMI transfer, to make it safe, need to set the
+	 * DMI_CFG to unselect any SRAM */
+	writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG);
+
+	/* can only be bank 0 or bank 1 for now. */
+	writel(ctrl->vfeLaBankSel, ctrl->vfebase + VFE_LA_CFG);
+	CDBG("VFE Luma adaptation bank selection is 0x%x\n",
+			 *(uint32_t *)&ctrl->vfeLaBankSel);
+}
+
+void vfe_test_gen_start(struct vfe_cmd_test_gen_start *in)
+{
+	struct VFE_TestGen_ConfigCmdType cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+
+	cmd.numFrame              = in->numFrame;
+	cmd.pixelDataSelect       = in->pixelDataSelect;
+	cmd.systematicDataSelect  = in->systematicDataSelect;
+	cmd.pixelDataSize         = (uint32_t)in->pixelDataSize;
+	cmd.hsyncEdge             = (uint32_t)in->hsyncEdge;
+	cmd.vsyncEdge             = (uint32_t)in->vsyncEdge;
+	cmd.imageWidth            = in->imageWidth;
+	cmd.imageHeight           = in->imageHeight;
+	cmd.sofOffset             = in->startOfFrameOffset;
+	cmd.eofNOffset            = in->endOfFrameNOffset;
+	cmd.solOffset             = in->startOfLineOffset;
+	cmd.eolNOffset            = in->endOfLineNOffset;
+	cmd.hBlankInterval        = in->hbi;
+	cmd.vBlankInterval        = in->vbl;
+	cmd.vBlankIntervalEnable  = in->vblEnable;
+	cmd.sofDummy              = in->startOfFrameDummyLine;
+	cmd.eofDummy              = in->endOfFrameDummyLine;
+	cmd.unicolorBarSelect     = in->unicolorBarSelect;
+	cmd.unicolorBarEnable     = in->unicolorBarEnable;
+	cmd.splitEnable           = in->colorBarsSplitEnable;
+	cmd.pixelPattern          = (uint32_t)in->colorBarsPixelPattern;
+	cmd.rotatePeriod          = in->colorBarsRotatePeriod;
+	cmd.randomSeed            = in->testGenRandomSeed;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_HW_TESTGEN_CFG,
+		(uint32_t *) &cmd, sizeof(cmd));
+}
+
+void vfe_frame_skip_update(struct vfe_cmd_frame_skip_update *in)
+{
+	struct VFE_FRAME_SKIP_UpdateCmdType cmd;
+
+	cmd.yPattern    = in->output1Pattern;
+	cmd.cbcrPattern = in->output1Pattern;
+	vfe_prog_hw(ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_PATTERN,
+		(uint32_t *)&cmd, sizeof(cmd));
+
+	cmd.yPattern    = in->output2Pattern;
+	cmd.cbcrPattern = in->output2Pattern;
+	vfe_prog_hw(ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_PATTERN,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_frame_skip_config(struct vfe_cmd_frame_skip_config *in)
+{
+	struct vfe_frame_skip_cfg cmd;
+	memset(&cmd, 0, sizeof(cmd));
+
+	ctrl->vfeFrameSkip = *in;
+
+	cmd.output2YPeriod     = in->output2Period;
+	cmd.output2CbCrPeriod  = in->output2Period;
+	cmd.output2YPattern    = in->output2Pattern;
+	cmd.output2CbCrPattern = in->output2Pattern;
+	cmd.output1YPeriod     = in->output1Period;
+	cmd.output1CbCrPeriod  = in->output1Period;
+	cmd.output1YPattern    = in->output1Pattern;
+	cmd.output1CbCrPattern = in->output1Pattern;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_output_clamp_config(struct vfe_cmd_output_clamp_config *in)
+{
+	struct vfe_output_clamp_cfg cmd;
+	memset(&cmd, 0, sizeof(cmd));
+
+	cmd.yChanMax  = in->maxCh0;
+	cmd.cbChanMax = in->maxCh1;
+	cmd.crChanMax = in->maxCh2;
+
+	cmd.yChanMin  = in->minCh0;
+	cmd.cbChanMin = in->minCh1;
+	cmd.crChanMin = in->minCh2;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_CLAMP_MAX_CFG, (uint32_t *)&cmd,
+		sizeof(cmd));
+}
+
+void vfe_camif_frame_update(struct vfe_cmds_camif_frame *in)
+{
+	struct vfe_camifframe_update cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+
+	cmd.pixelsPerLine = in->pixelsPerLine;
+	cmd.linesPerFrame = in->linesPerFrame;
+
+	vfe_prog_hw(ctrl->vfebase + CAMIF_FRAME_CONFIG, (uint32_t *)&cmd,
+		sizeof(cmd));
+}
+
+void vfe_color_correction_config(struct vfe_cmd_color_correction_config *in)
+{
+	struct vfe_color_correction_cfg cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	ctrl->vfeModuleEnableLocal.colorCorrectionEnable = in->enable;
+
+	cmd.c0 = in->C0;
+	cmd.c1 = in->C1;
+	cmd.c2 = in->C2;
+	cmd.c3 = in->C3;
+	cmd.c4 = in->C4;
+	cmd.c5 = in->C5;
+	cmd.c6 = in->C6;
+	cmd.c7 = in->C7;
+	cmd.c8 = in->C8;
+
+	cmd.k0 = in->K0;
+	cmd.k1 = in->K1;
+	cmd.k2 = in->K2;
+
+	cmd.coefQFactor = in->coefQFactor;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_COLOR_CORRECT_COEFF_0,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_demosaic_abf_update(struct vfe_cmd_demosaic_abf_update *in)
+{
+struct vfe_demosaic_cfg cmd;
+	struct vfe_demosaic_abf_cfg cmdabf;
+	uint32_t temp;
+
+	memset(&cmd, 0, sizeof(cmd));
+	temp = readl(ctrl->vfebase + VFE_DEMOSAIC_CFG);
+
+	cmd = *((struct vfe_demosaic_cfg *)(&temp));
+	cmd.abfEnable       = in->abfUpdate.enable;
+	cmd.forceAbfOn      = in->abfUpdate.forceOn;
+	cmd.abfShift        = in->abfUpdate.shift;
+	vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+
+	cmdabf.lpThreshold  = in->abfUpdate.lpThreshold;
+	cmdabf.ratio        = in->abfUpdate.ratio;
+	cmdabf.minValue     = in->abfUpdate.min;
+	cmdabf.maxValue     = in->abfUpdate.max;
+	vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_ABF_CFG_0,
+		(uint32_t *)&cmdabf, sizeof(cmdabf));
+}
+
+void vfe_demosaic_bpc_update(struct vfe_cmd_demosaic_bpc_update *in)
+{
+	struct vfe_demosaic_cfg cmd;
+	struct vfe_demosaic_bpc_cfg cmdbpc;
+	uint32_t temp;
+
+	memset(&cmd, 0, sizeof(cmd));
+
+	temp = readl(ctrl->vfebase + VFE_DEMOSAIC_CFG);
+
+	cmd = *((struct vfe_demosaic_cfg *)(&temp));
+	cmd.badPixelCorrEnable = in->bpcUpdate.enable;
+	cmd.fminThreshold      = in->bpcUpdate.fminThreshold;
+	cmd.fmaxThreshold      = in->bpcUpdate.fmaxThreshold;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+
+	cmdbpc.blueDiffThreshold  = in->bpcUpdate.blueDiffThreshold;
+	cmdbpc.redDiffThreshold   = in->bpcUpdate.redDiffThreshold;
+	cmdbpc.greenDiffThreshold = in->bpcUpdate.greenDiffThreshold;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_BPC_CFG_0,
+		(uint32_t *)&cmdbpc, sizeof(cmdbpc));
+}
+
+void vfe_demosaic_config(struct vfe_cmd_demosaic_config *in)
+{
+	struct vfe_demosaic_cfg cmd;
+	struct vfe_demosaic_bpc_cfg cmd_bpc;
+	struct vfe_demosaic_abf_cfg cmd_abf;
+
+	memset(&cmd, 0, sizeof(cmd));
+	memset(&cmd_bpc, 0, sizeof(cmd_bpc));
+	memset(&cmd_abf, 0, sizeof(cmd_abf));
+
+	ctrl->vfeModuleEnableLocal.demosaicEnable = in->enable;
+
+	cmd.abfEnable          = in->abfConfig.enable;
+	cmd.badPixelCorrEnable = in->bpcConfig.enable;
+	cmd.forceAbfOn         = in->abfConfig.forceOn;
+	cmd.abfShift           = in->abfConfig.shift;
+	cmd.fminThreshold      = in->bpcConfig.fminThreshold;
+	cmd.fmaxThreshold      = in->bpcConfig.fmaxThreshold;
+	cmd.slopeShift         = in->slopeShift;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+
+	cmd_abf.lpThreshold = in->abfConfig.lpThreshold;
+	cmd_abf.ratio       = in->abfConfig.ratio;
+	cmd_abf.minValue    = in->abfConfig.min;
+	cmd_abf.maxValue    = in->abfConfig.max;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_ABF_CFG_0,
+		(uint32_t *)&cmd_abf, sizeof(cmd_abf));
+
+	cmd_bpc.blueDiffThreshold   = in->bpcConfig.blueDiffThreshold;
+	cmd_bpc.redDiffThreshold    = in->bpcConfig.redDiffThreshold;
+	cmd_bpc.greenDiffThreshold  = in->bpcConfig.greenDiffThreshold;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_BPC_CFG_0,
+		(uint32_t *)&cmd_bpc, sizeof(cmd_bpc));
+}
+
+void vfe_demux_channel_gain_update(struct vfe_cmd_demux_channel_gain_config *in)
+{
+	struct vfe_demux_cfg cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+
+	cmd.ch0EvenGain  = in->ch0EvenGain;
+	cmd.ch0OddGain   = in->ch0OddGain;
+	cmd.ch1Gain      = in->ch1Gain;
+	cmd.ch2Gain      = in->ch2Gain;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_DEMUX_GAIN_0,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_demux_channel_gain_config(struct vfe_cmd_demux_channel_gain_config *in)
+{
+	struct vfe_demux_cfg cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+
+	cmd.ch0EvenGain = in->ch0EvenGain;
+	cmd.ch0OddGain  = in->ch0OddGain;
+	cmd.ch1Gain     = in->ch1Gain;
+	cmd.ch2Gain     = in->ch2Gain;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_DEMUX_GAIN_0,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_black_level_update(struct vfe_cmd_black_level_config *in)
+{
+	struct vfe_blacklevel_cfg cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	ctrl->vfeModuleEnableLocal.blackLevelCorrectionEnable = in->enable;
+
+	cmd.evenEvenAdjustment = in->evenEvenAdjustment;
+	cmd.evenOddAdjustment  = in->evenOddAdjustment;
+	cmd.oddEvenAdjustment  = in->oddEvenAdjustment;
+	cmd.oddOddAdjustment   = in->oddOddAdjustment;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_BLACK_EVEN_EVEN_VALUE,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_black_level_config(struct vfe_cmd_black_level_config *in)
+{
+	struct vfe_blacklevel_cfg cmd;
+	memset(&cmd, 0, sizeof(cmd));
+
+	ctrl->vfeModuleEnableLocal.blackLevelCorrectionEnable = in->enable;
+
+	cmd.evenEvenAdjustment = in->evenEvenAdjustment;
+	cmd.evenOddAdjustment  = in->evenOddAdjustment;
+	cmd.oddEvenAdjustment  = in->oddEvenAdjustment;
+	cmd.oddOddAdjustment   = in->oddOddAdjustment;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_BLACK_EVEN_EVEN_VALUE,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_asf_update(struct vfe_cmd_asf_update *in)
+{
+	struct vfe_asf_update cmd;
+	memset(&cmd, 0, sizeof(cmd));
+
+	ctrl->vfeModuleEnableLocal.asfEnable = in->enable;
+
+	cmd.smoothEnable     = in->smoothFilterEnabled;
+	cmd.sharpMode        = in->sharpMode;
+	cmd.smoothCoeff0     = in->smoothCoefCenter;
+	cmd.smoothCoeff1     = in->smoothCoefSurr;
+	cmd.cropEnable       = in->cropEnable;
+	cmd.sharpThresholdE1 = in->sharpThreshE1;
+	cmd.sharpDegreeK1    = in->sharpK1;
+	cmd.sharpDegreeK2    = in->sharpK2;
+	cmd.normalizeFactor  = in->normalizeFactor;
+	cmd.sharpThresholdE2 = in->sharpThreshE2;
+	cmd.sharpThresholdE3 = in->sharpThreshE3;
+	cmd.sharpThresholdE4 = in->sharpThreshE4;
+	cmd.sharpThresholdE5 = in->sharpThreshE5;
+	cmd.F1Coeff0         = in->filter1Coefficients[0];
+	cmd.F1Coeff1         = in->filter1Coefficients[1];
+	cmd.F1Coeff2         = in->filter1Coefficients[2];
+	cmd.F1Coeff3         = in->filter1Coefficients[3];
+	cmd.F1Coeff4         = in->filter1Coefficients[4];
+	cmd.F1Coeff5         = in->filter1Coefficients[5];
+	cmd.F1Coeff6         = in->filter1Coefficients[6];
+	cmd.F1Coeff7         = in->filter1Coefficients[7];
+	cmd.F1Coeff8         = in->filter1Coefficients[8];
+	cmd.F2Coeff0         = in->filter2Coefficients[0];
+	cmd.F2Coeff1         = in->filter2Coefficients[1];
+	cmd.F2Coeff2         = in->filter2Coefficients[2];
+	cmd.F2Coeff3         = in->filter2Coefficients[3];
+	cmd.F2Coeff4         = in->filter2Coefficients[4];
+	cmd.F2Coeff5         = in->filter2Coefficients[5];
+	cmd.F2Coeff6         = in->filter2Coefficients[6];
+	cmd.F2Coeff7         = in->filter2Coefficients[7];
+	cmd.F2Coeff8         = in->filter2Coefficients[8];
+
+	vfe_prog_hw(ctrl->vfebase + VFE_ASF_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_asf_config(struct vfe_cmd_asf_config *in)
+{
+	struct vfe_asf_update     cmd;
+	struct vfe_asfcrop_cfg cmd2;
+
+	memset(&cmd, 0, sizeof(cmd));
+	memset(&cmd2, 0, sizeof(cmd2));
+
+	ctrl->vfeModuleEnableLocal.asfEnable = in->enable;
+
+	cmd.smoothEnable       = in->smoothFilterEnabled;
+	cmd.sharpMode          = in->sharpMode;
+	cmd.smoothCoeff0       = in->smoothCoefCenter;
+	cmd.smoothCoeff1       = in->smoothCoefSurr;
+	cmd.cropEnable         = in->cropEnable;
+	cmd.sharpThresholdE1   = in->sharpThreshE1;
+	cmd.sharpDegreeK1      = in->sharpK1;
+	cmd.sharpDegreeK2      = in->sharpK2;
+	cmd.normalizeFactor    = in->normalizeFactor;
+	cmd.sharpThresholdE2   = in->sharpThreshE2;
+	cmd.sharpThresholdE3   = in->sharpThreshE3;
+	cmd.sharpThresholdE4   = in->sharpThreshE4;
+	cmd.sharpThresholdE5   = in->sharpThreshE5;
+	cmd.F1Coeff0           = in->filter1Coefficients[0];
+	cmd.F1Coeff1           = in->filter1Coefficients[1];
+	cmd.F1Coeff2           = in->filter1Coefficients[2];
+	cmd.F1Coeff3           = in->filter1Coefficients[3];
+	cmd.F1Coeff4           = in->filter1Coefficients[4];
+	cmd.F1Coeff5           = in->filter1Coefficients[5];
+	cmd.F1Coeff6           = in->filter1Coefficients[6];
+	cmd.F1Coeff7           = in->filter1Coefficients[7];
+	cmd.F1Coeff8           = in->filter1Coefficients[8];
+	cmd.F2Coeff0           = in->filter2Coefficients[0];
+	cmd.F2Coeff1           = in->filter2Coefficients[1];
+	cmd.F2Coeff2           = in->filter2Coefficients[2];
+	cmd.F2Coeff3           = in->filter2Coefficients[3];
+	cmd.F2Coeff4           = in->filter2Coefficients[4];
+	cmd.F2Coeff5           = in->filter2Coefficients[5];
+	cmd.F2Coeff6           = in->filter2Coefficients[6];
+	cmd.F2Coeff7           = in->filter2Coefficients[7];
+	cmd.F2Coeff8           = in->filter2Coefficients[8];
+
+	vfe_prog_hw(ctrl->vfebase + VFE_ASF_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+
+	cmd2.firstLine  = in->cropFirstLine;
+	cmd2.lastLine   = in->cropLastLine;
+	cmd2.firstPixel = in->cropFirstPixel;
+	cmd2.lastPixel  = in->cropLastPixel;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_ASF_CROP_WIDTH_CFG,
+		(uint32_t *)&cmd2, sizeof(cmd2));
+}
+
+void vfe_white_balance_config(struct vfe_cmd_white_balance_config *in)
+{
+	struct vfe_wb_cfg cmd;
+	memset(&cmd, 0, sizeof(cmd));
+
+	ctrl->vfeModuleEnableLocal.whiteBalanceEnable = in->enable;
+
+	cmd.ch0Gain = in->ch0Gain;
+	cmd.ch1Gain = in->ch1Gain;
+	cmd.ch2Gain = in->ch2Gain;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_WB_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_chroma_sup_config(struct vfe_cmd_chroma_suppression_config *in)
+{
+	struct vfe_chroma_suppress_cfg cmd;
+	memset(&cmd, 0, sizeof(cmd));
+
+	ctrl->vfeModuleEnableLocal.chromaSuppressionEnable = in->enable;
+
+	cmd.m1  = in->m1;
+	cmd.m3  = in->m3;
+	cmd.n1  = in->n1;
+	cmd.n3  = in->n3;
+	cmd.mm1 = in->mm1;
+	cmd.nn1 = in->nn1;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_CHROMA_SUPPRESS_CFG_0,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_roll_off_config(struct vfe_cmd_roll_off_config *in)
+{
+	struct vfe_rolloff_cfg cmd;
+	memset(&cmd, 0, sizeof(cmd));
+
+	ctrl->vfeModuleEnableLocal.lensRollOffEnable = in->enable;
+
+	cmd.gridWidth   = in->gridWidth;
+	cmd.gridHeight  = in->gridHeight;
+	cmd.yDelta      = in->yDelta;
+	cmd.gridX       = in->gridXIndex;
+	cmd.gridY       = in->gridYIndex;
+	cmd.pixelX      = in->gridPixelXIndex;
+	cmd.pixelY      = in->gridPixelYIndex;
+	cmd.yDeltaAccum = in->yDeltaAccum;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_ROLLOFF_CFG_0,
+		(uint32_t *)&cmd, sizeof(cmd));
+
+	vfe_write_lens_roll_off_table(in);
+}
+
+void vfe_chroma_subsample_config(struct vfe_cmd_chroma_subsample_config *in)
+{
+	struct vfe_chromasubsample_cfg cmd;
+	memset(&cmd, 0, sizeof(cmd));
+
+	ctrl->vfeModuleEnableLocal.chromaSubsampleEnable = in->enable;
+
+	cmd.hCositedPhase       = in->hCositedPhase;
+	cmd.vCositedPhase       = in->vCositedPhase;
+	cmd.hCosited            = in->hCosited;
+	cmd.vCosited            = in->vCosited;
+	cmd.hsubSampleEnable    = in->hsubSampleEnable;
+	cmd.vsubSampleEnable    = in->vsubSampleEnable;
+	cmd.cropEnable          = in->cropEnable;
+	cmd.cropWidthLastPixel  = in->cropWidthLastPixel;
+	cmd.cropWidthFirstPixel = in->cropWidthFirstPixel;
+	cmd.cropHeightLastLine  = in->cropHeightLastLine;
+	cmd.cropHeightFirstLine = in->cropHeightFirstLine;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_CHROMA_SUBSAMPLE_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_chroma_enhan_config(struct vfe_cmd_chroma_enhan_config *in)
+{
+	struct vfe_chroma_enhance_cfg cmd;
+	struct vfe_color_convert_cfg cmd2;
+
+	memset(&cmd, 0, sizeof(cmd));
+	memset(&cmd2, 0, sizeof(cmd2));
+
+	ctrl->vfeModuleEnableLocal.chromaEnhanEnable = in->enable;
+
+	cmd.ap             = in->ap;
+	cmd.am             = in->am;
+	cmd.bp             = in->bp;
+	cmd.bm             = in->bm;
+	cmd.cp             = in->cp;
+	cmd.cm             = in->cm;
+	cmd.dp             = in->dp;
+	cmd.dm             = in->dm;
+	cmd.kcb            = in->kcb;
+	cmd.kcr            = in->kcr;
+
+	cmd2.v0            = in->RGBtoYConversionV0;
+	cmd2.v1            = in->RGBtoYConversionV1;
+	cmd2.v2            = in->RGBtoYConversionV2;
+	cmd2.ConvertOffset = in->RGBtoYConversionOffset;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_CHROMA_ENHAN_A,
+		(uint32_t *)&cmd, sizeof(cmd));
+
+	vfe_prog_hw(ctrl->vfebase + VFE_COLOR_CONVERT_COEFF_0,
+		(uint32_t *)&cmd2, sizeof(cmd2));
+}
+
+void vfe_scaler2cbcr_config(struct vfe_cmd_scaler2_config *in)
+{
+	struct vfe_scaler2_cfg cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+
+	ctrl->vfeModuleEnableLocal.scaler2CbcrEnable = in->enable;
+
+	cmd.hEnable              = in->hconfig.enable;
+	cmd.vEnable              = in->vconfig.enable;
+	cmd.inWidth              = in->hconfig.inputSize;
+	cmd.outWidth             = in->hconfig.outputSize;
+	cmd.horizPhaseMult       = in->hconfig.phaseMultiplicationFactor;
+	cmd.horizInterResolution = in->hconfig.interpolationResolution;
+	cmd.inHeight             = in->vconfig.inputSize;
+	cmd.outHeight            = in->vconfig.outputSize;
+	cmd.vertPhaseMult        = in->vconfig.phaseMultiplicationFactor;
+	cmd.vertInterResolution  = in->vconfig.interpolationResolution;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_SCALE_CBCR_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_scaler2y_config(struct vfe_cmd_scaler2_config *in)
+{
+	struct vfe_scaler2_cfg cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+
+	ctrl->vfeModuleEnableLocal.scaler2YEnable = in->enable;
+
+	cmd.hEnable               = in->hconfig.enable;
+	cmd.vEnable               = in->vconfig.enable;
+	cmd.inWidth               = in->hconfig.inputSize;
+	cmd.outWidth              = in->hconfig.outputSize;
+	cmd.horizPhaseMult        = in->hconfig.phaseMultiplicationFactor;
+	cmd.horizInterResolution  = in->hconfig.interpolationResolution;
+	cmd.inHeight              = in->vconfig.inputSize;
+	cmd.outHeight             = in->vconfig.outputSize;
+	cmd.vertPhaseMult         = in->vconfig.phaseMultiplicationFactor;
+	cmd.vertInterResolution   = in->vconfig.interpolationResolution;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_SCALE_Y_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_main_scaler_config(struct vfe_cmd_main_scaler_config *in)
+{
+	struct vfe_main_scaler_cfg cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+
+	ctrl->vfeModuleEnableLocal.mainScalerEnable = in->enable;
+
+	cmd.hEnable              = in->hconfig.enable;
+	cmd.vEnable              = in->vconfig.enable;
+	cmd.inWidth              = in->hconfig.inputSize;
+	cmd.outWidth             = in->hconfig.outputSize;
+	cmd.horizPhaseMult       = in->hconfig.phaseMultiplicationFactor;
+	cmd.horizInterResolution = in->hconfig.interpolationResolution;
+	cmd.horizMNInit          = in->MNInitH.MNCounterInit;
+	cmd.horizPhaseInit       = in->MNInitH.phaseInit;
+	cmd.inHeight             = in->vconfig.inputSize;
+	cmd.outHeight            = in->vconfig.outputSize;
+	cmd.vertPhaseMult        = in->vconfig.phaseMultiplicationFactor;
+	cmd.vertInterResolution  = in->vconfig.interpolationResolution;
+	cmd.vertMNInit           = in->MNInitV.MNCounterInit;
+	cmd.vertPhaseInit        = in->MNInitV.phaseInit;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_SCALE_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_stats_wb_exp_stop(void)
+{
+	ctrl->vfeStatsCmdLocal.axwEnable = FALSE;
+	ctrl->vfeImaskLocal.awbPingpongIrq = FALSE;
+}
+
+void vfe_stats_update_wb_exp(struct vfe_cmd_stats_wb_exp_update *in)
+{
+	struct vfe_statsawb_update   cmd;
+	struct vfe_statsawbae_update cmd2;
+
+	memset(&cmd, 0, sizeof(cmd));
+	memset(&cmd2, 0, sizeof(cmd2));
+
+	cmd.m1  = in->awbMCFG[0];
+	cmd.m2  = in->awbMCFG[1];
+	cmd.m3  = in->awbMCFG[2];
+	cmd.m4  = in->awbMCFG[3];
+	cmd.c1  = in->awbCCFG[0];
+	cmd.c2  = in->awbCCFG[1];
+	cmd.c3  = in->awbCCFG[2];
+	cmd.c4  = in->awbCCFG[3];
+	vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWB_MCFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+
+	cmd2.aeRegionCfg    = in->wbExpRegions;
+	cmd2.aeSubregionCfg = in->wbExpSubRegion;
+	cmd2.awbYMin        = in->awbYMin;
+	cmd2.awbYMax        = in->awbYMax;
+	vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWBAE_CFG,
+		(uint32_t *)&cmd2, sizeof(cmd2));
+}
+
+void vfe_stats_update_af(struct vfe_cmd_stats_af_update *in)
+{
+	struct vfe_statsaf_update cmd;
+	memset(&cmd, 0, sizeof(cmd));
+
+	cmd.windowVOffset = in->windowVOffset;
+	cmd.windowHOffset = in->windowHOffset;
+	cmd.windowMode    = in->windowMode;
+	cmd.windowHeight  = in->windowHeight;
+	cmd.windowWidth   = in->windowWidth;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_STATS_AF_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_stats_start_wb_exp(struct vfe_cmd_stats_wb_exp_start *in)
+{
+	struct vfe_statsawb_update   cmd;
+	struct vfe_statsawbae_update cmd2;
+	struct vfe_statsaxw_hdr_cfg  cmd3;
+
+	ctrl->vfeStatsCmdLocal.axwEnable   =  in->enable;
+	ctrl->vfeImaskLocal.awbPingpongIrq = TRUE;
+
+	memset(&cmd, 0, sizeof(cmd));
+	memset(&cmd2, 0, sizeof(cmd2));
+	memset(&cmd3, 0, sizeof(cmd3));
+
+	cmd.m1  = in->awbMCFG[0];
+	cmd.m2  = in->awbMCFG[1];
+	cmd.m3  = in->awbMCFG[2];
+	cmd.m4  = in->awbMCFG[3];
+	cmd.c1  = in->awbCCFG[0];
+	cmd.c2  = in->awbCCFG[1];
+	cmd.c3  = in->awbCCFG[2];
+	cmd.c4  = in->awbCCFG[3];
+	vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWB_MCFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+
+	cmd2.aeRegionCfg     = in->wbExpRegions;
+	cmd2.aeSubregionCfg  = in->wbExpSubRegion;
+	cmd2.awbYMin         = in->awbYMin;
+	cmd2.awbYMax         = in->awbYMax;
+	vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWBAE_CFG,
+		(uint32_t *)&cmd2, sizeof(cmd2));
+
+	cmd3.axwHeader       = in->axwHeader;
+	vfe_prog_hw(ctrl->vfebase + VFE_STATS_AXW_HEADER,
+		(uint32_t *)&cmd3, sizeof(cmd3));
+}
+
+void vfe_stats_start_af(struct vfe_cmd_stats_af_start *in)
+{
+	struct vfe_statsaf_update cmd;
+	struct vfe_statsaf_cfg    cmd2;
+
+	memset(&cmd, 0, sizeof(cmd));
+	memset(&cmd2, 0, sizeof(cmd2));
+
+	ctrl->vfeStatsCmdLocal.autoFocusEnable = in->enable;
+	ctrl->vfeImaskLocal.afPingpongIrq = TRUE;
+
+	cmd.windowVOffset = in->windowVOffset;
+	cmd.windowHOffset = in->windowHOffset;
+	cmd.windowMode    = in->windowMode;
+	cmd.windowHeight  = in->windowHeight;
+	cmd.windowWidth   = in->windowWidth;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_STATS_AF_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+
+	cmd2.a00       = in->highPassCoef[0];
+	cmd2.a04       = in->highPassCoef[1];
+	cmd2.a20       = in->highPassCoef[2];
+	cmd2.a21       = in->highPassCoef[3];
+	cmd2.a22       = in->highPassCoef[4];
+	cmd2.a23       = in->highPassCoef[5];
+	cmd2.a24       = in->highPassCoef[6];
+	cmd2.fvMax     = in->metricMax;
+	cmd2.fvMetric  = in->metricSelection;
+	cmd2.afHeader  = in->bufferHeader;
+	cmd2.entry00   = in->gridForMultiWindows[0];
+	cmd2.entry01   = in->gridForMultiWindows[1];
+	cmd2.entry02   = in->gridForMultiWindows[2];
+	cmd2.entry03   = in->gridForMultiWindows[3];
+	cmd2.entry10   = in->gridForMultiWindows[4];
+	cmd2.entry11   = in->gridForMultiWindows[5];
+	cmd2.entry12   = in->gridForMultiWindows[6];
+	cmd2.entry13   = in->gridForMultiWindows[7];
+	cmd2.entry20   = in->gridForMultiWindows[8];
+	cmd2.entry21   = in->gridForMultiWindows[9];
+	cmd2.entry22   = in->gridForMultiWindows[10];
+	cmd2.entry23   = in->gridForMultiWindows[11];
+	cmd2.entry30   = in->gridForMultiWindows[12];
+	cmd2.entry31   = in->gridForMultiWindows[13];
+	cmd2.entry32   = in->gridForMultiWindows[14];
+	cmd2.entry33   = in->gridForMultiWindows[15];
+
+	vfe_prog_hw(ctrl->vfebase + VFE_STATS_AF_GRID_0,
+		(uint32_t *)&cmd2, sizeof(cmd2));
+}
+
+void vfe_stats_setting(struct vfe_cmd_stats_setting *in)
+{
+	struct vfe_statsframe cmd1;
+	struct vfe_busstats_wrprio cmd2;
+
+	memset(&cmd1, 0, sizeof(cmd1));
+	memset(&cmd2, 0, sizeof(cmd2));
+
+	ctrl->afStatsControl.addressBuffer[0] = in->afBuffer[0];
+	ctrl->afStatsControl.addressBuffer[1] = in->afBuffer[1];
+	ctrl->afStatsControl.nextFrameAddrBuf = in->afBuffer[2];
+
+	ctrl->awbStatsControl.addressBuffer[0] = in->awbBuffer[0];
+	ctrl->awbStatsControl.addressBuffer[1] = in->awbBuffer[1];
+	ctrl->awbStatsControl.nextFrameAddrBuf = in->awbBuffer[2];
+
+	cmd1.lastPixel = in->frameHDimension;
+	cmd1.lastLine  = in->frameVDimension;
+	vfe_prog_hw(ctrl->vfebase + VFE_STATS_FRAME_SIZE,
+		(uint32_t *)&cmd1, sizeof(cmd1));
+
+	cmd2.afBusPriority    = in->afBusPriority;
+	cmd2.awbBusPriority   = in->awbBusPriority;
+	cmd2.histBusPriority  = in->histBusPriority;
+	cmd2.afBusPriorityEn  = in->afBusPrioritySelection;
+	cmd2.awbBusPriorityEn = in->awbBusPrioritySelection;
+	cmd2.histBusPriorityEn = in->histBusPrioritySelection;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_BUS_STATS_WR_PRIORITY,
+		(uint32_t *)&cmd2, sizeof(cmd2));
+
+	/* Program the bus ping pong address for statistics modules. */
+	writel(in->afBuffer[0], ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR);
+	writel(in->afBuffer[1], ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR);
+	writel(in->awbBuffer[0],
+		ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR);
+	writel(in->awbBuffer[1],
+		ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR);
+	writel(in->histBuffer[0],
+		ctrl->vfebase + VFE_BUS_STATS_HIST_WR_PING_ADDR);
+	writel(in->histBuffer[1],
+		ctrl->vfebase + VFE_BUS_STATS_HIST_WR_PONG_ADDR);
+}
+
+void vfe_axi_input_config(struct vfe_cmd_axi_input_config *in)
+{
+	struct VFE_AxiInputCmdType cmd;
+	uint32_t xSizeWord, axiRdUnpackPattern;
+	uint8_t  axiInputPpw;
+	uint32_t busPingpongRdIrqEnable;
+
+	ctrl->vfeImaskLocal.rdPingpongIrq = TRUE;
+
+	switch (in->pixelSize) {
+	case VFE_RAW_PIXEL_DATA_SIZE_10BIT:
+		ctrl->axiInputDataSize = VFE_RAW_PIXEL_DATA_SIZE_10BIT;
+		break;
+
+	case VFE_RAW_PIXEL_DATA_SIZE_12BIT:
+		ctrl->axiInputDataSize = VFE_RAW_PIXEL_DATA_SIZE_12BIT;
+		break;
+
+	case VFE_RAW_PIXEL_DATA_SIZE_8BIT:
+	default:
+		ctrl->axiInputDataSize = VFE_RAW_PIXEL_DATA_SIZE_8BIT;
+		break;
+	}
+
+	memset(&cmd, 0, sizeof(cmd));
+
+	switch (in->pixelSize) {
+	case VFE_RAW_PIXEL_DATA_SIZE_10BIT:
+		axiInputPpw = 6;
+		axiRdUnpackPattern = 0xD43210;
+		break;
+
+	case VFE_RAW_PIXEL_DATA_SIZE_12BIT:
+		axiInputPpw = 5;
+		axiRdUnpackPattern = 0xC3210;
+		break;
+
+	case VFE_RAW_PIXEL_DATA_SIZE_8BIT:
+	default:
+		axiInputPpw = 8;
+		axiRdUnpackPattern = 0xF6543210;
+		break;
+	}
+
+	xSizeWord =
+		((((in->xOffset % axiInputPpw) + in->xSize) +
+			(axiInputPpw-1)) / axiInputPpw) - 1;
+
+	cmd.stripeStartAddr0  = in->fragAddr[0];
+	cmd.stripeStartAddr1  = in->fragAddr[1];
+	cmd.stripeStartAddr2  = in->fragAddr[2];
+	cmd.stripeStartAddr3  = in->fragAddr[3];
+	cmd.ySize             = in->ySize;
+	cmd.yOffsetDelta      = 0;
+	cmd.xSizeWord         = xSizeWord;
+	cmd.burstLength       = 1;
+	cmd.NumOfRows         = in->numOfRows;
+	cmd.RowIncrement = (in->rowIncrement + (axiInputPpw - 1)) / axiInputPpw;
+	cmd.mainUnpackHeight  = in->ySize;
+	cmd.mainUnpackWidth   = in->xSize - 1;
+	cmd.mainUnpackHbiSel  = (uint32_t)in->unpackHbi;
+	cmd.mainUnpackPhase   = in->unpackPhase;
+	cmd.unpackPattern     = axiRdUnpackPattern;
+	cmd.padLeft           = in->padRepeatCountLeft;
+	cmd.padRight          = in->padRepeatCountRight;
+	cmd.padTop            = in->padRepeatCountTop;
+	cmd.padBottom         = in->padRepeatCountBottom;
+	cmd.leftUnpackPattern0   = in->padLeftComponentSelectCycle0;
+	cmd.leftUnpackPattern1   = in->padLeftComponentSelectCycle1;
+	cmd.leftUnpackPattern2   = in->padLeftComponentSelectCycle2;
+	cmd.leftUnpackPattern3   = in->padLeftComponentSelectCycle3;
+	cmd.leftUnpackStop0      = in->padLeftStopCycle0;
+	cmd.leftUnpackStop1      = in->padLeftStopCycle1;
+	cmd.leftUnpackStop2      = in->padLeftStopCycle2;
+	cmd.leftUnpackStop3      = in->padLeftStopCycle3;
+	cmd.rightUnpackPattern0  = in->padRightComponentSelectCycle0;
+	cmd.rightUnpackPattern1  = in->padRightComponentSelectCycle1;
+	cmd.rightUnpackPattern2  = in->padRightComponentSelectCycle2;
+	cmd.rightUnpackPattern3  = in->padRightComponentSelectCycle3;
+	cmd.rightUnpackStop0     = in->padRightStopCycle0;
+	cmd.rightUnpackStop1     = in->padRightStopCycle1;
+	cmd.rightUnpackStop2     = in->padRightStopCycle2;
+	cmd.rightUnpackStop3     = in->padRightStopCycle3;
+	cmd.topUnapckPattern     = in->padTopLineCount;
+	cmd.bottomUnapckPattern  = in->padBottomLineCount;
+
+	/*  program vfe_bus_cfg */
+	vfe_prog_hw(ctrl->vfebase + VFE_BUS_STRIPE_RD_ADDR_0,
+		(uint32_t *)&cmd, sizeof(cmd));
+
+	/* hacking code, put it to default value */
+	busPingpongRdIrqEnable = 0xf;
+
+	writel(busPingpongRdIrqEnable, ctrl->vfebase + VFE_BUS_PINGPONG_IRQ_EN);
+}
+
+void vfe_axi_output_config(struct vfe_cmd_axi_output_config *in)
+{
+	/* local variable  */
+	uint32_t *pcircle;
+	uint32_t *pdest;
+	uint32_t *psrc;
+	uint8_t  i;
+	uint8_t  fcnt;
+	uint16_t axioutpw = 8;
+
+	/* parameters check, condition and usage mode check */
+	ctrl->encPath.fragCount = in->output2.fragmentCount;
+	if (ctrl->encPath.fragCount > 1)
+		ctrl->encPath.multiFrag = TRUE;
+
+	ctrl->viewPath.fragCount = in->output1.fragmentCount;
+	if (ctrl->viewPath.fragCount > 1)
+		ctrl->viewPath.multiFrag = TRUE;
+
+	/* VFE_BUS_CFG.  raw data size */
+	ctrl->vfeBusConfigLocal.rawPixelDataSize = in->outputDataSize;
+
+	switch (in->outputDataSize) {
+	case VFE_RAW_PIXEL_DATA_SIZE_8BIT:
+		axioutpw = 8;
+		break;
+
+	case VFE_RAW_PIXEL_DATA_SIZE_10BIT:
+		axioutpw = 6;
+		break;
+
+	case VFE_RAW_PIXEL_DATA_SIZE_12BIT:
+		axioutpw = 5;
+		break;
+	}
+
+	ctrl->axiOutputMode = in->outputMode;
+
+	CDBG("axiOutputMode = %d\n", ctrl->axiOutputMode);
+
+	switch (ctrl->axiOutputMode) {
+	case VFE_AXI_OUTPUT_MODE_Output1: {
+		ctrl->vfeCamifConfigLocal.camif2BusEnable   = FALSE;
+		ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE;
+		ctrl->vfeBusConfigLocal.rawWritePathSelect  =
+			VFE_RAW_OUTPUT_DISABLED;
+
+		ctrl->encPath.pathEnabled                   = FALSE;
+		ctrl->vfeImaskLocal.encIrq                  = FALSE;
+		ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
+			VFE_COMP_IRQ_BOTH_Y_CBCR;
+
+		ctrl->vfeBusConfigLocal.encYWrPathEn          = FALSE;
+		ctrl->vfeBusConfigLocal.encCbcrWrPathEn       = FALSE;
+		ctrl->viewPath.pathEnabled                    = TRUE;
+		ctrl->vfeImaskLocal.viewIrq                   = TRUE;
+		ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
+			VFE_COMP_IRQ_BOTH_Y_CBCR;
+
+		ctrl->vfeBusConfigLocal.viewYWrPathEn    = TRUE;
+		ctrl->vfeBusConfigLocal.viewCbcrWrPathEn = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
+				ctrl->encPath.multiFrag)
+			ctrl->vfeImaskLocal.encYPingpongIrq    = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
+				ctrl->encPath.multiFrag)
+			ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
+				ctrl->viewPath.multiFrag)
+			ctrl->vfeImaskLocal.viewYPingpongIrq   = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
+				ctrl->viewPath.multiFrag)
+			ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE;
+	} /* VFE_AXI_OUTPUT_MODE_Output1 */
+		break;
+
+	case VFE_AXI_OUTPUT_MODE_Output2: {
+		ctrl->vfeCamifConfigLocal.camif2BusEnable   = FALSE;
+		ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE;
+		ctrl->vfeBusConfigLocal.rawWritePathSelect  =
+			VFE_RAW_OUTPUT_DISABLED;
+
+		ctrl->encPath.pathEnabled                   = TRUE;
+		ctrl->vfeImaskLocal.encIrq                  = TRUE;
+		ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
+			VFE_COMP_IRQ_BOTH_Y_CBCR;
+
+		ctrl->vfeBusConfigLocal.encYWrPathEn        = TRUE;
+		ctrl->vfeBusConfigLocal.encCbcrWrPathEn     = TRUE;
+
+		ctrl->viewPath.pathEnabled                   = FALSE;
+		ctrl->vfeImaskLocal.viewIrq                  = FALSE;
+		ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
+			VFE_COMP_IRQ_BOTH_Y_CBCR;
+
+		ctrl->vfeBusConfigLocal.viewYWrPathEn        = FALSE;
+		ctrl->vfeBusConfigLocal.viewCbcrWrPathEn     = FALSE;
+
+		if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
+				ctrl->encPath.multiFrag)
+			ctrl->vfeImaskLocal.encYPingpongIrq    = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
+				ctrl->encPath.multiFrag)
+			ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
+				ctrl->viewPath.multiFrag)
+			ctrl->vfeImaskLocal.viewYPingpongIrq   = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
+				ctrl->viewPath.multiFrag)
+			ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE;
+	} /* VFE_AXI_OUTPUT_MODE_Output2 */
+			break;
+
+	case VFE_AXI_OUTPUT_MODE_Output1AndOutput2: {
+		ctrl->vfeCamifConfigLocal.camif2BusEnable    = FALSE;
+		ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE;
+		ctrl->vfeBusConfigLocal.rawWritePathSelect   =
+			VFE_RAW_OUTPUT_DISABLED;
+
+		ctrl->encPath.pathEnabled                    = TRUE;
+		ctrl->vfeImaskLocal.encIrq                   = TRUE;
+		ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
+			VFE_COMP_IRQ_BOTH_Y_CBCR;
+
+		ctrl->vfeBusConfigLocal.encYWrPathEn         = TRUE;
+		ctrl->vfeBusConfigLocal.encCbcrWrPathEn      = TRUE;
+		ctrl->viewPath.pathEnabled                   = TRUE;
+		ctrl->vfeImaskLocal.viewIrq                  = TRUE;
+		ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
+			VFE_COMP_IRQ_BOTH_Y_CBCR;
+
+		ctrl->vfeBusConfigLocal.viewYWrPathEn        = TRUE;
+		ctrl->vfeBusConfigLocal.viewCbcrWrPathEn     = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
+				ctrl->encPath.multiFrag)
+			ctrl->vfeImaskLocal.encYPingpongIrq    = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
+				ctrl->encPath.multiFrag)
+			ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
+				ctrl->viewPath.multiFrag)
+			ctrl->vfeImaskLocal.viewYPingpongIrq   = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
+				ctrl->viewPath.multiFrag)
+			ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE;
+	} /* VFE_AXI_OUTPUT_MODE_Output1AndOutput2 */
+		break;
+
+	case VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2: {
+		/* For raw snapshot, we need both ping and pong buffer
+		 * initialized to the same address. Otherwise, if we
+		 * leave the pong buffer to NULL, there will be axi_error.
+		 * Note that ideally we should deal with this at upper layer,
+		 * which is in msm_vfe8x.c */
+		if (!in->output2.outputCbcr.outFragments[1][0]) {
+			in->output2.outputCbcr.outFragments[1][0] =
+				in->output2.outputCbcr.outFragments[0][0];
+		}
+
+		ctrl->vfeCamifConfigLocal.camif2BusEnable   = TRUE;
+		ctrl->vfeCamifConfigLocal.camif2OutputEnable = FALSE;
+		ctrl->vfeBusConfigLocal.rawWritePathSelect  =
+			VFE_RAW_OUTPUT_ENC_CBCR_PATH;
+
+		ctrl->encPath.pathEnabled                   = TRUE;
+		ctrl->vfeImaskLocal.encIrq                  = TRUE;
+		ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
+			VFE_COMP_IRQ_CBCR_ONLY;
+
+		ctrl->vfeBusConfigLocal.encYWrPathEn        = FALSE;
+		ctrl->vfeBusConfigLocal.encCbcrWrPathEn     = TRUE;
+
+		ctrl->viewPath.pathEnabled                   = FALSE;
+		ctrl->vfeImaskLocal.viewIrq                  = FALSE;
+		ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
+			VFE_COMP_IRQ_BOTH_Y_CBCR;
+
+		ctrl->vfeBusConfigLocal.viewYWrPathEn        = FALSE;
+		ctrl->vfeBusConfigLocal.viewCbcrWrPathEn     = FALSE;
+
+		if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
+				ctrl->encPath.multiFrag)
+			ctrl->vfeImaskLocal.encYPingpongIrq    = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
+				ctrl->encPath.multiFrag)
+			ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
+				ctrl->viewPath.multiFrag)
+			ctrl->vfeImaskLocal.viewYPingpongIrq   = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
+				ctrl->viewPath.multiFrag)
+			ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE;
+	} /* VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2 */
+		break;
+
+	case VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1: {
+		ctrl->vfeCamifConfigLocal.camif2BusEnable   = TRUE;
+		ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE;
+		ctrl->vfeBusConfigLocal.rawWritePathSelect  =
+			VFE_RAW_OUTPUT_VIEW_CBCR_PATH;
+
+		ctrl->encPath.pathEnabled                   = TRUE;
+		ctrl->vfeImaskLocal.encIrq                  = TRUE;
+		ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
+			VFE_COMP_IRQ_BOTH_Y_CBCR;
+
+		ctrl->vfeBusConfigLocal.encYWrPathEn        = TRUE;
+		ctrl->vfeBusConfigLocal.encCbcrWrPathEn     = TRUE;
+
+		ctrl->viewPath.pathEnabled                   = TRUE;
+		ctrl->vfeImaskLocal.viewIrq                  = TRUE;
+		ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
+			VFE_COMP_IRQ_CBCR_ONLY;
+
+		ctrl->vfeBusConfigLocal.viewYWrPathEn        = FALSE;
+		ctrl->vfeBusConfigLocal.viewCbcrWrPathEn     = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
+				ctrl->encPath.multiFrag)
+			ctrl->vfeImaskLocal.encYPingpongIrq    = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
+				ctrl->encPath.multiFrag)
+			ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
+				ctrl->viewPath.multiFrag)
+			ctrl->vfeImaskLocal.viewYPingpongIrq   = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
+				ctrl->viewPath.multiFrag)
+			ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE;
+	} /* VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1 */
+		break;
+
+	case VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2: {
+		ctrl->vfeCamifConfigLocal.camif2BusEnable   = TRUE;
+		ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE;
+		ctrl->vfeBusConfigLocal.rawWritePathSelect  =
+			VFE_RAW_OUTPUT_ENC_CBCR_PATH;
+
+		ctrl->encPath.pathEnabled                     = TRUE;
+		ctrl->vfeImaskLocal.encIrq                    = TRUE;
+		ctrl->vfeIrqCompositeMaskLocal.encIrqComMask  =
+			VFE_COMP_IRQ_CBCR_ONLY;
+
+		ctrl->vfeBusConfigLocal.encYWrPathEn          = FALSE;
+		ctrl->vfeBusConfigLocal.encCbcrWrPathEn       = TRUE;
+
+		ctrl->viewPath.pathEnabled                    = TRUE;
+		ctrl->vfeImaskLocal.viewIrq                   = TRUE;
+
+		ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
+			VFE_COMP_IRQ_BOTH_Y_CBCR;
+
+		ctrl->vfeBusConfigLocal.viewYWrPathEn         = TRUE;
+		ctrl->vfeBusConfigLocal.viewCbcrWrPathEn      = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
+				ctrl->encPath.multiFrag)
+			ctrl->vfeImaskLocal.encYPingpongIrq       = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
+				ctrl->encPath.multiFrag)
+			ctrl->vfeImaskLocal.encCbcrPingpongIrq    = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
+				ctrl->viewPath.multiFrag)
+			ctrl->vfeImaskLocal.viewYPingpongIrq      = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
+				ctrl->viewPath.multiFrag)
+			ctrl->vfeImaskLocal.viewCbcrPingpongIrq   = TRUE;
+	} /* VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2 */
+		break;
+
+	case VFE_AXI_LAST_OUTPUT_MODE_ENUM:
+		break;
+	} /* switch */
+
+	/* Save the addresses for each path. */
+	/* output2 path */
+	fcnt = ctrl->encPath.fragCount;
+
+	pcircle = ctrl->encPath.yPath.addressBuffer;
+	pdest = ctrl->encPath.nextFrameAddrBuf;
+
+	psrc = &(in->output2.outputY.outFragments[0][0]);
+	for (i = 0; i < fcnt; i++)
+		*pcircle++ = *psrc++;
+
+	psrc = &(in->output2.outputY.outFragments[1][0]);
+	for (i = 0; i < fcnt; i++)
+		*pcircle++ = *psrc++;
+
+	psrc = &(in->output2.outputY.outFragments[2][0]);
+	for (i = 0; i < fcnt; i++)
+		*pdest++ = *psrc++;
+
+	pcircle = ctrl->encPath.cbcrPath.addressBuffer;
+
+	psrc = &(in->output2.outputCbcr.outFragments[0][0]);
+	for (i = 0; i < fcnt; i++)
+		*pcircle++ = *psrc++;
+
+	psrc = &(in->output2.outputCbcr.outFragments[1][0]);
+	for (i = 0; i < fcnt; i++)
+		*pcircle++ = *psrc++;
+
+	psrc = &(in->output2.outputCbcr.outFragments[2][0]);
+	for (i = 0; i < fcnt; i++)
+		*pdest++ = *psrc++;
+
+	vfe_set_bus_pipo_addr(&ctrl->viewPath, &ctrl->encPath);
+
+	ctrl->encPath.ackPending = FALSE;
+	ctrl->encPath.currentFrame = ping;
+	ctrl->encPath.whichOutputPath = 1;
+	ctrl->encPath.yPath.fragIndex = 2;
+	ctrl->encPath.cbcrPath.fragIndex = 2;
+	ctrl->encPath.yPath.hwCurrentFlag = ping;
+	ctrl->encPath.cbcrPath.hwCurrentFlag = ping;
+
+	/* output1 path */
+	pcircle = ctrl->viewPath.yPath.addressBuffer;
+	pdest = ctrl->viewPath.nextFrameAddrBuf;
+	fcnt = ctrl->viewPath.fragCount;
+
+	psrc = &(in->output1.outputY.outFragments[0][0]);
+	for (i = 0; i < fcnt; i++)
+		*pcircle++ = *psrc++;
+
+	psrc = &(in->output1.outputY.outFragments[1][0]);
+	for (i = 0; i < fcnt; i++)
+		*pcircle++ = *psrc++;
+
+	psrc = &(in->output1.outputY.outFragments[2][0]);
+	for (i = 0; i < fcnt; i++)
+		*pdest++ = *psrc++;
+
+	pcircle = ctrl->viewPath.cbcrPath.addressBuffer;
+
+	psrc = &(in->output1.outputCbcr.outFragments[0][0]);
+	for (i = 0; i < fcnt; i++)
+		*pcircle++ = *psrc++;
+
+	psrc = &(in->output1.outputCbcr.outFragments[1][0]);
+	for (i = 0; i < fcnt; i++)
+		*pcircle++ = *psrc++;
+
+	psrc = &(in->output1.outputCbcr.outFragments[2][0]);
+	for (i = 0; i < fcnt; i++)
+		*pdest++ = *psrc++;
+
+	ctrl->viewPath.ackPending = FALSE;
+	ctrl->viewPath.currentFrame = ping;
+	ctrl->viewPath.whichOutputPath = 0;
+	ctrl->viewPath.yPath.fragIndex = 2;
+	ctrl->viewPath.cbcrPath.fragIndex = 2;
+	ctrl->viewPath.yPath.hwCurrentFlag = ping;
+	ctrl->viewPath.cbcrPath.hwCurrentFlag = ping;
+
+	/* call to program the registers. */
+	vfe_axi_output(in, &ctrl->viewPath, &ctrl->encPath, axioutpw);
+}
+
+void vfe_camif_config(struct vfe_cmd_camif_config *in)
+{
+	struct vfe_camifcfg cmd;
+	memset(&cmd, 0, sizeof(cmd));
+
+	CDBG("camif.frame pixelsPerLine = %d\n", in->frame.pixelsPerLine);
+	CDBG("camif.frame linesPerFrame = %d\n", in->frame.linesPerFrame);
+	CDBG("camif.window firstpixel = %d\n", in->window.firstpixel);
+	CDBG("camif.window lastpixel = %d\n",  in->window.lastpixel);
+	CDBG("camif.window firstline = %d\n",  in->window.firstline);
+	CDBG("camif.window lastline = %d\n",   in->window.lastline);
+
+	/* determine if epoch interrupt needs to be enabled.  */
+	if ((in->epoch1.enable == TRUE) &&
+	    (in->epoch1.lineindex <= in->frame.linesPerFrame))
+		ctrl->vfeImaskLocal.camifEpoch1Irq = 1;
+
+	if ((in->epoch2.enable == TRUE) &&
+	    (in->epoch2.lineindex <= in->frame.linesPerFrame)) {
+		ctrl->vfeImaskLocal.camifEpoch2Irq = 1;
+	}
+
+	/*  save the content to program CAMIF_CONFIG seperately. */
+	ctrl->vfeCamifConfigLocal.camifCfgFromCmd = in->camifConfig;
+
+	/* EFS_Config */
+	cmd.efsEndOfLine     = in->EFS.efsendofline;
+	cmd.efsStartOfLine   = in->EFS.efsstartofline;
+	cmd.efsEndOfFrame    = in->EFS.efsendofframe;
+	cmd.efsStartOfFrame  = in->EFS.efsstartofframe;
+
+	/* Frame Config */
+	cmd.frameConfigPixelsPerLine = in->frame.pixelsPerLine;
+	cmd.frameConfigLinesPerFrame = in->frame.linesPerFrame;
+
+	/* Window Width Config */
+	cmd.windowWidthCfgLastPixel  = in->window.lastpixel;
+	cmd.windowWidthCfgFirstPixel = in->window.firstpixel;
+
+	/* Window Height Config */
+	cmd.windowHeightCfglastLine   = in->window.lastline;
+	cmd.windowHeightCfgfirstLine  = in->window.firstline;
+
+	/* Subsample 1 Config */
+	cmd.subsample1CfgPixelSkip = in->subsample.pixelskipmask;
+	cmd.subsample1CfgLineSkip  = in->subsample.lineskipmask;
+
+	/* Subsample 2 Config */
+	cmd.subsample2CfgFrameSkip      = in->subsample.frameskip;
+	cmd.subsample2CfgFrameSkipMode  = in->subsample.frameskipmode;
+	cmd.subsample2CfgPixelSkipWrap  = in->subsample.pixelskipwrap;
+
+	/* Epoch Interrupt */
+	cmd.epoch1Line = in->epoch1.lineindex;
+	cmd.epoch2Line = in->epoch2.lineindex;
+
+	vfe_prog_hw(ctrl->vfebase + CAMIF_EFS_CONFIG,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_fov_crop_config(struct vfe_cmd_fov_crop_config *in)
+{
+	struct vfe_fov_crop_cfg cmd;
+	memset(&cmd, 0, sizeof(cmd));
+
+	ctrl->vfeModuleEnableLocal.cropEnable = in->enable;
+
+	/* FOV Corp, Part 1 */
+	cmd.lastPixel  = in->lastPixel;
+	cmd.firstPixel = in->firstPixel;
+
+	/* FOV Corp, Part 2 */
+	cmd.lastLine   = in->lastLine;
+	cmd.firstLine  = in->firstLine;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_CROP_WIDTH_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_get_hw_version(struct vfe_cmd_hw_version *out)
+{
+	uint32_t vfeHwVersionPacked;
+	struct vfe_hw_ver ver;
+
+	vfeHwVersionPacked = readl(ctrl->vfebase + VFE_HW_VERSION);
+
+	ver = *((struct vfe_hw_ver *)&vfeHwVersionPacked);
+
+	out->coreVersion  = ver.coreVersion;
+	out->minorVersion = ver.minorVersion;
+	out->majorVersion = ver.majorVersion;
+}
+
+static void vfe_reset_internal_variables(void)
+{
+	/* local variables to program the hardware. */
+	ctrl->vfeImaskPacked = 0;
+	ctrl->vfeImaskCompositePacked = 0;
+
+	/* FALSE = disable,  1 = enable. */
+	memset(&ctrl->vfeModuleEnableLocal, 0,
+		sizeof(ctrl->vfeModuleEnableLocal));
+
+	/* 0 = disable, 1 = enable */
+	memset(&ctrl->vfeCamifConfigLocal, 0,
+		sizeof(ctrl->vfeCamifConfigLocal));
+	/* 0 = disable, 1 = enable */
+	memset(&ctrl->vfeImaskLocal, 0, sizeof(ctrl->vfeImaskLocal));
+	memset(&ctrl->vfeStatsCmdLocal, 0, sizeof(ctrl->vfeStatsCmdLocal));
+	memset(&ctrl->vfeBusConfigLocal, 0, sizeof(ctrl->vfeBusConfigLocal));
+	memset(&ctrl->vfeBusPmConfigLocal, 0,
+		sizeof(ctrl->vfeBusPmConfigLocal));
+	memset(&ctrl->vfeBusCmdLocal, 0, sizeof(ctrl->vfeBusCmdLocal));
+	memset(&ctrl->vfeInterruptNameLocal, 0,
+		sizeof(ctrl->vfeInterruptNameLocal));
+	memset(&ctrl->vfeDroppedFrameCounts, 0,
+		sizeof(ctrl->vfeDroppedFrameCounts));
+	memset(&ctrl->vfeIrqThreadMsgLocal, 0,
+		sizeof(ctrl->vfeIrqThreadMsgLocal));
+
+	/* state control variables */
+	ctrl->vfeStartAckPendingFlag = FALSE;
+	ctrl->vfeStopAckPending = FALSE;
+	ctrl->vfeIrqCompositeMaskLocal.ceDoneSel = 0;
+	ctrl->vfeIrqCompositeMaskLocal.encIrqComMask = VFE_COMP_IRQ_BOTH_Y_CBCR;
+	ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
+		VFE_COMP_IRQ_BOTH_Y_CBCR;
+
+	ctrl->vstate = VFE_STATE_IDLE;
+
+	ctrl->axiOutputMode = VFE_AXI_LAST_OUTPUT_MODE_ENUM;
+	/* 0 for continuous mode, 1 for snapshot mode */
+	ctrl->vfeOperationMode = VFE_START_OPERATION_MODE_CONTINUOUS;
+	ctrl->vfeSnapShotCount = 0;
+	ctrl->vfeStatsPingPongReloadFlag = FALSE;
+	/* this is unsigned 32 bit integer. */
+	ctrl->vfeFrameId = 0;
+	ctrl->vfeFrameSkip.output1Pattern = 0xffffffff;
+	ctrl->vfeFrameSkip.output1Period  = 31;
+	ctrl->vfeFrameSkip.output2Pattern = 0xffffffff;
+	ctrl->vfeFrameSkip.output2Period  = 31;
+	ctrl->vfeFrameSkipPattern = 0xffffffff;
+	ctrl->vfeFrameSkipCount   = 0;
+	ctrl->vfeFrameSkipPeriod  = 31;
+
+	memset((void *)&ctrl->encPath, 0, sizeof(ctrl->encPath));
+	memset((void *)&ctrl->viewPath, 0, sizeof(ctrl->viewPath));
+
+	ctrl->encPath.whichOutputPath  = 1;
+	ctrl->encPath.cbcrStatusBit    = 5;
+	ctrl->viewPath.whichOutputPath = 0;
+	ctrl->viewPath.cbcrStatusBit   = 7;
+
+	ctrl->vfeTestGenStartFlag = FALSE;
+
+	/* default to bank 0. */
+	ctrl->vfeLaBankSel = 0;
+
+	/* default to bank 0 for all channels. */
+	memset(&ctrl->vfeGammaLutSel, 0, sizeof(ctrl->vfeGammaLutSel));
+
+	/* Stats control variables. */
+	memset(&ctrl->afStatsControl, 0, sizeof(ctrl->afStatsControl));
+	memset(&ctrl->awbStatsControl, 0, sizeof(ctrl->awbStatsControl));
+	vfe_set_stats_pingpong_address(&ctrl->afStatsControl,
+		&ctrl->awbStatsControl);
+}
+
+void vfe_reset(void)
+{
+	spin_lock_init(&msm_vfe_ctrl_lock);
+	vfe_reset_internal_variables();
+
+	atomic_set(&ctrl->vfe_serv_interrupt, 1);
+	ctrl->vfeImaskLocal.resetAckIrq = TRUE;
+	ctrl->vfeImaskPacked = vfe_irq_pack(ctrl->vfeImaskLocal);
+
+	/* disable all interrupts. */
+	writel(VFE_DISABLE_ALL_IRQS, ctrl->vfebase + VFE_IRQ_COMPOSITE_MASK);
+
+	/* clear all pending interrupts*/
+	writel(VFE_CLEAR_ALL_IRQS, ctrl->vfebase + VFE_IRQ_CLEAR);
+
+	/* enable reset_ack interrupt.  */
+	writel(ctrl->vfeImaskPacked, ctrl->vfebase + VFE_IRQ_MASK);
+
+	writel(VFE_RESET_UPON_RESET_CMD, ctrl->vfebase + VFE_GLOBAL_RESET_CMD);
+}
diff --git a/drivers/media/platform/msm/camera_v1/vfe/msm_vfe8x_proc.h b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe8x_proc.h
new file mode 100644
index 0000000..4e18c7c
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe8x_proc.h
@@ -0,0 +1,1563 @@
+/* Copyright (c) 2009, 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 __MSM_VFE8X_REG_H__
+#define __MSM_VFE8X_REG_H__
+
+#include <mach/msm_iomap.h>
+#include <mach/camera.h>
+#include "msm_vfe8x.h"
+
+
+#define MSM_AXI_QOS_PREVIEW		128000
+#define MSM_AXI_QOS_SNAPSHOT	128000
+#define MSM_AXI_QOS_RECORDING	128000
+
+
+/* at start of camif,  bit 1:0 = 0x01:enable
+ * image data capture at frame boundary. */
+#define CAMIF_COMMAND_START  0x00000005
+
+/* bit 2= 0x1:clear the CAMIF_STATUS register
+ * value. */
+#define CAMIF_COMMAND_CLEAR  0x00000004
+
+/* at stop of vfe pipeline, for now it is assumed
+ * that camif will stop at any time. Bit 1:0 = 0x10:
+ * disable image data capture immediately. */
+#define CAMIF_COMMAND_STOP_IMMEDIATELY  0x00000002
+
+/* at stop of vfe pipeline, for now it is assumed
+ * that camif will stop at any time. Bit 1:0 = 0x00:
+ * disable image data capture at frame boundary */
+#define CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY  0x00000000
+
+/* to halt axi bridge */
+#define AXI_HALT  0x00000001
+
+/* clear the halt bit. */
+#define AXI_HALT_CLEAR  0x00000000
+
+/* reset the pipeline when stop command is issued.
+ * (without reset the register.) bit 26-31 = 0,
+ * domain reset, bit 0-9 = 1 for module reset, except
+ * register module. */
+#define VFE_RESET_UPON_STOP_CMD  0x000003ef
+
+/* reset the pipeline when reset command.
+ * bit 26-31 = 0, domain reset, bit 0-9 = 1 for module reset. */
+#define VFE_RESET_UPON_RESET_CMD  0x000003ff
+
+/* bit 5 is for axi status idle or busy.
+ * 1 =  halted,  0 = busy */
+#define AXI_STATUS_BUSY_MASK 0x00000020
+
+/* bit 0 & bit 1 = 1, both y and cbcr irqs need to be present
+ * for frame done interrupt */
+#define VFE_COMP_IRQ_BOTH_Y_CBCR 3
+
+/* bit 1 = 1, only cbcr irq triggers frame done interrupt */
+#define VFE_COMP_IRQ_CBCR_ONLY 2
+
+/* bit 0 = 1, only y irq triggers frame done interrupt */
+#define VFE_COMP_IRQ_Y_ONLY 1
+
+/* bit 0 = 1, PM go;   bit1 = 1, PM stop */
+#define VFE_PERFORMANCE_MONITOR_GO   0x00000001
+#define VFE_PERFORMANCE_MONITOR_STOP 0x00000002
+
+/* bit 0 = 1, test gen go;   bit1 = 1, test gen stop */
+#define VFE_TEST_GEN_GO   0x00000001
+#define VFE_TEST_GEN_STOP 0x00000002
+
+/* the chroma is assumed to be interpolated between
+ * the luma samples.  JPEG 4:2:2 */
+#define VFE_CHROMA_UPSAMPLE_INTERPOLATED 0
+
+/* constants for irq registers */
+#define VFE_DISABLE_ALL_IRQS 0
+/* bit =1 is to clear the corresponding bit in VFE_IRQ_STATUS.  */
+#define VFE_CLEAR_ALL_IRQS   0xffffffff
+/* imask for while waiting for stop ack,  driver has already
+ * requested stop, waiting for reset irq,
+ * bit 29,28,27,26 for async timer, bit 9 for reset */
+#define VFE_IMASK_WHILE_STOPPING  0x3c000200
+
+/* when normal case, don't want to block error status.
+ * bit 0,6,20,21,22,30,31 */
+#define VFE_IMASK_ERROR_ONLY             0xC0700041
+#define VFE_REG_UPDATE_TRIGGER           1
+#define VFE_PM_BUF_MAX_CNT_MASK          0xFF
+#define VFE_DMI_CFG_DEFAULT              0x00000100
+#define LENS_ROLL_OFF_DELTA_TABLE_OFFSET 32
+#define VFE_AF_PINGPONG_STATUS_BIT       0x100
+#define VFE_AWB_PINGPONG_STATUS_BIT      0x200
+
+/* VFE I/O registers */
+enum {
+	VFE_HW_VERSION                    = 0x00000000,
+	VFE_GLOBAL_RESET_CMD              = 0x00000004,
+	VFE_MODULE_RESET                  = 0x00000008,
+	VFE_CGC_OVERRIDE                  = 0x0000000C,
+	VFE_MODULE_CFG                    = 0x00000010,
+	VFE_CFG                           = 0x00000014,
+	VFE_IRQ_MASK                      = 0x00000018,
+	VFE_IRQ_CLEAR                     = 0x0000001C,
+VFE_IRQ_STATUS                    = 0x00000020,
+VFE_IRQ_COMPOSITE_MASK            = 0x00000024,
+VFE_BUS_CMD                       = 0x00000028,
+VFE_BUS_CFG                       = 0x0000002C,
+VFE_BUS_ENC_Y_WR_PING_ADDR        = 0x00000030,
+VFE_BUS_ENC_Y_WR_PONG_ADDR        = 0x00000034,
+VFE_BUS_ENC_Y_WR_IMAGE_SIZE       = 0x00000038,
+VFE_BUS_ENC_Y_WR_BUFFER_CFG       = 0x0000003C,
+VFE_BUS_ENC_CBCR_WR_PING_ADDR     = 0x00000040,
+VFE_BUS_ENC_CBCR_WR_PONG_ADDR     = 0x00000044,
+VFE_BUS_ENC_CBCR_WR_IMAGE_SIZE    = 0x00000048,
+VFE_BUS_ENC_CBCR_WR_BUFFER_CFG    = 0x0000004C,
+VFE_BUS_VIEW_Y_WR_PING_ADDR       = 0x00000050,
+VFE_BUS_VIEW_Y_WR_PONG_ADDR       = 0x00000054,
+VFE_BUS_VIEW_Y_WR_IMAGE_SIZE      = 0x00000058,
+VFE_BUS_VIEW_Y_WR_BUFFER_CFG      = 0x0000005C,
+VFE_BUS_VIEW_CBCR_WR_PING_ADDR    = 0x00000060,
+VFE_BUS_VIEW_CBCR_WR_PONG_ADDR    = 0x00000064,
+VFE_BUS_VIEW_CBCR_WR_IMAGE_SIZE   = 0x00000068,
+VFE_BUS_VIEW_CBCR_WR_BUFFER_CFG   = 0x0000006C,
+VFE_BUS_STATS_AF_WR_PING_ADDR     = 0x00000070,
+VFE_BUS_STATS_AF_WR_PONG_ADDR     = 0x00000074,
+VFE_BUS_STATS_AWB_WR_PING_ADDR    = 0x00000078,
+VFE_BUS_STATS_AWB_WR_PONG_ADDR    = 0x0000007C,
+VFE_BUS_STATS_HIST_WR_PING_ADDR   = 0x00000080,
+VFE_BUS_STATS_HIST_WR_PONG_ADDR   = 0x00000084,
+VFE_BUS_STATS_WR_PRIORITY         = 0x00000088,
+VFE_BUS_STRIPE_RD_ADDR_0          = 0x0000008C,
+VFE_BUS_STRIPE_RD_ADDR_1          = 0x00000090,
+VFE_BUS_STRIPE_RD_ADDR_2          = 0x00000094,
+VFE_BUS_STRIPE_RD_ADDR_3          = 0x00000098,
+VFE_BUS_STRIPE_RD_VSIZE           = 0x0000009C,
+VFE_BUS_STRIPE_RD_HSIZE           = 0x000000A0,
+VFE_BUS_STRIPE_RD_BUFFER_CFG      = 0x000000A4,
+VFE_BUS_STRIPE_RD_UNPACK_CFG      = 0x000000A8,
+VFE_BUS_STRIPE_RD_UNPACK          = 0x000000AC,
+VFE_BUS_STRIPE_RD_PAD_SIZE        = 0x000000B0,
+VFE_BUS_STRIPE_RD_PAD_L_UNPACK    = 0x000000B4,
+VFE_BUS_STRIPE_RD_PAD_R_UNPACK    = 0x000000B8,
+VFE_BUS_STRIPE_RD_PAD_TB_UNPACK   = 0x000000BC,
+VFE_BUS_PINGPONG_IRQ_EN           = 0x000000C0,
+VFE_BUS_PINGPONG_STATUS           = 0x000000C4,
+VFE_BUS_PM_CMD                    = 0x000000C8,
+VFE_BUS_PM_CFG                    = 0x000000CC,
+VFE_BUS_ENC_Y_WR_PM_STATS_0       = 0x000000D0,
+VFE_BUS_ENC_Y_WR_PM_STATS_1       = 0x000000D4,
+VFE_BUS_ENC_CBCR_WR_PM_STATS_0    = 0x000000D8,
+VFE_BUS_ENC_CBCR_WR_PM_STATS_1    = 0x000000DC,
+VFE_BUS_VIEW_Y_WR_PM_STATS_0      = 0x000000E0,
+VFE_BUS_VIEW_Y_WR_PM_STATS_1      = 0x000000E4,
+VFE_BUS_VIEW_CBCR_WR_PM_STATS_0   = 0x000000E8,
+VFE_BUS_VIEW_CBCR_WR_PM_STATS_1   = 0x000000EC,
+VFE_BUS_MISR_CFG                  = 0x000000F4,
+VFE_BUS_MISR_MAST_CFG_0           = 0x000000F8,
+VFE_BUS_MISR_MAST_CFG_1           = 0x000000FC,
+VFE_BUS_MISR_RD_VAL               = 0x00000100,
+VFE_AXI_CMD                       = 0x00000104,
+VFE_AXI_CFG                       = 0x00000108,
+VFE_AXI_STATUS                    = 0x0000010C,
+CAMIF_COMMAND                     = 0x00000110,
+CAMIF_CONFIG                      = 0x00000114,
+CAMIF_EFS_CONFIG                  = 0x00000118,
+CAMIF_FRAME_CONFIG                = 0x0000011C,
+CAMIF_WINDOW_WIDTH_CONFIG         = 0x00000120,
+CAMIF_WINDOW_HEIGHT_CONFIG        = 0x00000124,
+CAMIF_SUBSAMPLE1_CONFIG           = 0x00000128,
+CAMIF_SUBSAMPLE2_CONFIG           = 0x0000012C,
+CAMIF_EPOCH_IRQ                   = 0x00000130,
+CAMIF_STATUS                      = 0x00000134,
+CAMIF_MISR                        = 0x00000138,
+VFE_SYNC_TIMER_CMD                = 0x0000013C,
+VFE_SYNC_TIMER0_LINE_START        = 0x00000140,
+VFE_SYNC_TIMER0_PIXEL_START       = 0x00000144,
+VFE_SYNC_TIMER0_PIXEL_DURATION    = 0x00000148,
+VFE_SYNC_TIMER1_LINE_START        = 0x0000014C,
+VFE_SYNC_TIMER1_PIXEL_START       = 0x00000150,
+VFE_SYNC_TIMER1_PIXEL_DURATION    = 0x00000154,
+VFE_SYNC_TIMER2_LINE_START        = 0x00000158,
+VFE_SYNC_TIMER2_PIXEL_START       = 0x0000015C,
+VFE_SYNC_TIMER2_PIXEL_DURATION    = 0x00000160,
+VFE_SYNC_TIMER_POLARITY           = 0x00000164,
+VFE_ASYNC_TIMER_CMD               = 0x00000168,
+VFE_ASYNC_TIMER0_CFG_0            = 0x0000016C,
+VFE_ASYNC_TIMER0_CFG_1            = 0x00000170,
+VFE_ASYNC_TIMER1_CFG_0            = 0x00000174,
+VFE_ASYNC_TIMER1_CFG_1            = 0x00000178,
+VFE_ASYNC_TIMER2_CFG_0            = 0x0000017C,
+VFE_ASYNC_TIMER2_CFG_1            = 0x00000180,
+VFE_ASYNC_TIMER3_CFG_0            = 0x00000184,
+VFE_ASYNC_TIMER3_CFG_1            = 0x00000188,
+VFE_TIMER_SEL                     = 0x0000018C,
+VFE_REG_UPDATE_CMD                = 0x00000190,
+VFE_BLACK_EVEN_EVEN_VALUE         = 0x00000194,
+VFE_BLACK_EVEN_ODD_VALUE          = 0x00000198,
+VFE_BLACK_ODD_EVEN_VALUE          = 0x0000019C,
+VFE_BLACK_ODD_ODD_VALUE           = 0x000001A0,
+VFE_ROLLOFF_CFG_0                 = 0x000001A4,
+VFE_ROLLOFF_CFG_1                 = 0x000001A8,
+VFE_ROLLOFF_CFG_2                 = 0x000001AC,
+VFE_DEMUX_CFG                     = 0x000001B0,
+VFE_DEMUX_GAIN_0                  = 0x000001B4,
+VFE_DEMUX_GAIN_1                  = 0x000001B8,
+VFE_DEMUX_EVEN_CFG                = 0x000001BC,
+VFE_DEMUX_ODD_CFG                 = 0x000001C0,
+VFE_DEMOSAIC_CFG                  = 0x000001C4,
+VFE_DEMOSAIC_ABF_CFG_0            = 0x000001C8,
+VFE_DEMOSAIC_ABF_CFG_1            = 0x000001CC,
+VFE_DEMOSAIC_BPC_CFG_0            = 0x000001D0,
+VFE_DEMOSAIC_BPC_CFG_1            = 0x000001D4,
+VFE_DEMOSAIC_STATUS               = 0x000001D8,
+VFE_CHROMA_UPSAMPLE_CFG           = 0x000001DC,
+VFE_CROP_WIDTH_CFG                = 0x000001E0,
+VFE_CROP_HEIGHT_CFG               = 0x000001E4,
+VFE_COLOR_CORRECT_COEFF_0         = 0x000001E8,
+VFE_COLOR_CORRECT_COEFF_1         = 0x000001EC,
+VFE_COLOR_CORRECT_COEFF_2         = 0x000001F0,
+VFE_COLOR_CORRECT_COEFF_3         = 0x000001F4,
+VFE_COLOR_CORRECT_COEFF_4         = 0x000001F8,
+VFE_COLOR_CORRECT_COEFF_5         = 0x000001FC,
+VFE_COLOR_CORRECT_COEFF_6         = 0x00000200,
+VFE_COLOR_CORRECT_COEFF_7         = 0x00000204,
+VFE_COLOR_CORRECT_COEFF_8         = 0x00000208,
+VFE_COLOR_CORRECT_OFFSET_0        = 0x0000020C,
+VFE_COLOR_CORRECT_OFFSET_1        = 0x00000210,
+VFE_COLOR_CORRECT_OFFSET_2        = 0x00000214,
+VFE_COLOR_CORRECT_COEFF_Q         = 0x00000218,
+VFE_LA_CFG                        = 0x0000021C,
+VFE_LUT_BANK_SEL                  = 0x00000220,
+VFE_CHROMA_ENHAN_A                = 0x00000224,
+VFE_CHROMA_ENHAN_B                = 0x00000228,
+VFE_CHROMA_ENHAN_C                = 0x0000022C,
+VFE_CHROMA_ENHAN_D                = 0x00000230,
+VFE_CHROMA_ENHAN_K                = 0x00000234,
+VFE_COLOR_CONVERT_COEFF_0         = 0x00000238,
+VFE_COLOR_CONVERT_COEFF_1         = 0x0000023C,
+VFE_COLOR_CONVERT_COEFF_2         = 0x00000240,
+VFE_COLOR_CONVERT_OFFSET          = 0x00000244,
+VFE_ASF_CFG                       = 0x00000248,
+VFE_ASF_SHARP_CFG_0               = 0x0000024C,
+VFE_ASF_SHARP_CFG_1               = 0x00000250,
+VFE_ASF_SHARP_COEFF_0             = 0x00000254,
+VFE_ASF_SHARP_COEFF_1             = 0x00000258,
+VFE_ASF_SHARP_COEFF_2             = 0x0000025C,
+VFE_ASF_SHARP_COEFF_3             = 0x00000260,
+VFE_ASF_MAX_EDGE                  = 0x00000264,
+VFE_ASF_CROP_WIDTH_CFG            = 0x00000268,
+VFE_ASF_CROP_HEIGHT_CFG           = 0x0000026C,
+VFE_SCALE_CFG                     = 0x00000270,
+VFE_SCALE_H_IMAGE_SIZE_CFG        = 0x00000274,
+VFE_SCALE_H_PHASE_CFG             = 0x00000278,
+VFE_SCALE_H_STRIPE_CFG            = 0x0000027C,
+VFE_SCALE_V_IMAGE_SIZE_CFG        = 0x00000280,
+VFE_SCALE_V_PHASE_CFG             = 0x00000284,
+VFE_SCALE_V_STRIPE_CFG            = 0x00000288,
+VFE_SCALE_Y_CFG                   = 0x0000028C,
+VFE_SCALE_Y_H_IMAGE_SIZE_CFG      = 0x00000290,
+VFE_SCALE_Y_H_PHASE_CFG           = 0x00000294,
+VFE_SCALE_Y_V_IMAGE_SIZE_CFG      = 0x00000298,
+VFE_SCALE_Y_V_PHASE_CFG           = 0x0000029C,
+VFE_SCALE_CBCR_CFG                = 0x000002A0,
+VFE_SCALE_CBCR_H_IMAGE_SIZE_CFG   = 0x000002A4,
+VFE_SCALE_CBCR_H_PHASE_CFG        = 0x000002A8,
+VFE_SCALE_CBCR_V_IMAGE_SIZE_CFG   = 0x000002AC,
+VFE_SCALE_CBCR_V_PHASE_CFG        = 0x000002B0,
+VFE_WB_CFG                        = 0x000002B4,
+VFE_CHROMA_SUPPRESS_CFG_0         = 0x000002B8,
+VFE_CHROMA_SUPPRESS_CFG_1         = 0x000002BC,
+VFE_CHROMA_SUBSAMPLE_CFG          = 0x000002C0,
+VFE_CHROMA_SUB_CROP_WIDTH_CFG     = 0x000002C4,
+VFE_CHROMA_SUB_CROP_HEIGHT_CFG    = 0x000002C8,
+VFE_FRAMEDROP_ENC_Y_CFG           = 0x000002CC,
+VFE_FRAMEDROP_ENC_CBCR_CFG        = 0x000002D0,
+VFE_FRAMEDROP_ENC_Y_PATTERN       = 0x000002D4,
+VFE_FRAMEDROP_ENC_CBCR_PATTERN    = 0x000002D8,
+VFE_FRAMEDROP_VIEW_Y_CFG          = 0x000002DC,
+VFE_FRAMEDROP_VIEW_CBCR_CFG       = 0x000002E0,
+VFE_FRAMEDROP_VIEW_Y_PATTERN      = 0x000002E4,
+VFE_FRAMEDROP_VIEW_CBCR_PATTERN   = 0x000002E8,
+VFE_CLAMP_MAX_CFG                 = 0x000002EC,
+VFE_CLAMP_MIN_CFG                 = 0x000002F0,
+VFE_STATS_CMD                     = 0x000002F4,
+VFE_STATS_AF_CFG                  = 0x000002F8,
+VFE_STATS_AF_DIM                  = 0x000002FC,
+VFE_STATS_AF_GRID_0               = 0x00000300,
+VFE_STATS_AF_GRID_1               = 0x00000304,
+VFE_STATS_AF_GRID_2               = 0x00000308,
+VFE_STATS_AF_GRID_3               = 0x0000030C,
+VFE_STATS_AF_HEADER               = 0x00000310,
+VFE_STATS_AF_COEF0                = 0x00000314,
+VFE_STATS_AF_COEF1                = 0x00000318,
+VFE_STATS_AWBAE_CFG               = 0x0000031C,
+VFE_STATS_AXW_HEADER              = 0x00000320,
+VFE_STATS_AWB_MCFG                = 0x00000324,
+VFE_STATS_AWB_CCFG1               = 0x00000328,
+VFE_STATS_AWB_CCFG2               = 0x0000032C,
+VFE_STATS_HIST_HEADER             = 0x00000330,
+VFE_STATS_HIST_INNER_OFFSET       = 0x00000334,
+VFE_STATS_HIST_INNER_DIM          = 0x00000338,
+VFE_STATS_FRAME_SIZE              = 0x0000033C,
+VFE_DMI_CFG                       = 0x00000340,
+VFE_DMI_ADDR                      = 0x00000344,
+VFE_DMI_DATA_HI                   = 0x00000348,
+VFE_DMI_DATA_LO                   = 0x0000034C,
+VFE_DMI_RAM_AUTO_LOAD_CMD         = 0x00000350,
+VFE_DMI_RAM_AUTO_LOAD_STATUS      = 0x00000354,
+VFE_DMI_RAM_AUTO_LOAD_CFG         = 0x00000358,
+VFE_DMI_RAM_AUTO_LOAD_SEED        = 0x0000035C,
+VFE_TESTBUS_SEL                   = 0x00000360,
+VFE_TESTGEN_CFG                   = 0x00000364,
+VFE_SW_TESTGEN_CMD                = 0x00000368,
+VFE_HW_TESTGEN_CMD                = 0x0000036C,
+VFE_HW_TESTGEN_CFG                = 0x00000370,
+VFE_HW_TESTGEN_IMAGE_CFG          = 0x00000374,
+VFE_HW_TESTGEN_SOF_OFFSET_CFG     = 0x00000378,
+VFE_HW_TESTGEN_EOF_NOFFSET_CFG    = 0x0000037C,
+VFE_HW_TESTGEN_SOL_OFFSET_CFG     = 0x00000380,
+VFE_HW_TESTGEN_EOL_NOFFSET_CFG    = 0x00000384,
+VFE_HW_TESTGEN_HBI_CFG            = 0x00000388,
+VFE_HW_TESTGEN_VBL_CFG            = 0x0000038C,
+VFE_HW_TESTGEN_SOF_DUMMY_LINE_CFG2 = 0x00000390,
+VFE_HW_TESTGEN_EOF_DUMMY_LINE_CFG2 = 0x00000394,
+VFE_HW_TESTGEN_COLOR_BARS_CFG     = 0x00000398,
+VFE_HW_TESTGEN_RANDOM_CFG         = 0x0000039C,
+VFE_SPARE                         = 0x000003A0,
+};
+
+#define ping 0x0
+#define pong 0x1
+
+struct vfe_bus_cfg_data {
+	boolean                  stripeRdPathEn;
+	boolean                  encYWrPathEn;
+	boolean                  encCbcrWrPathEn;
+	boolean                  viewYWrPathEn;
+	boolean                  viewCbcrWrPathEn;
+	enum VFE_RAW_PIXEL_DATA_SIZE rawPixelDataSize;
+	enum VFE_RAW_WR_PATH_SEL     rawWritePathSelect;
+};
+
+struct vfe_camif_cfg_data {
+	boolean camif2OutputEnable;
+	boolean camif2BusEnable;
+	struct vfe_cmds_camif_cfg camifCfgFromCmd;
+};
+
+struct vfe_irq_composite_mask_config {
+	uint8_t encIrqComMask;
+	uint8_t viewIrqComMask;
+	uint8_t ceDoneSel;
+};
+
+/* define a structure for each output path.*/
+struct vfe_output_path {
+	uint32_t addressBuffer[8];
+	uint16_t fragIndex;
+	boolean  hwCurrentFlag;
+	uint8_t  *hwRegPingAddress;
+	uint8_t  *hwRegPongAddress;
+};
+
+struct vfe_output_path_combo {
+	boolean           whichOutputPath;
+	boolean           pathEnabled;
+	boolean           multiFrag;
+	uint8_t           fragCount;
+	boolean           ackPending;
+	uint8_t           currentFrame;
+	uint32_t          nextFrameAddrBuf[8];
+	struct vfe_output_path   yPath;
+	struct vfe_output_path   cbcrPath;
+	uint8_t           snapshotPendingCount;
+	boolean           pmEnabled;
+	uint8_t           cbcrStatusBit;
+};
+
+struct vfe_stats_control {
+	boolean  ackPending;
+	uint32_t addressBuffer[2];
+	uint32_t nextFrameAddrBuf;
+	boolean  pingPongStatus;
+	uint8_t  *hwRegPingAddress;
+	uint8_t  *hwRegPongAddress;
+	uint32_t droppedStatsFrameCount;
+	uint32_t bufToRender;
+};
+
+struct vfe_gamma_lut_sel {
+	boolean  ch0BankSelect;
+	boolean  ch1BankSelect;
+	boolean  ch2BankSelect;
+};
+
+struct vfe_interrupt_mask {
+	boolean  camifErrorIrq;
+	boolean  camifSofIrq;
+	boolean  camifEolIrq;
+	boolean  camifEofIrq;
+	boolean  camifEpoch1Irq;
+	boolean  camifEpoch2Irq;
+	boolean  camifOverflowIrq;
+	boolean  ceIrq;
+	boolean  regUpdateIrq;
+	boolean  resetAckIrq;
+	boolean  encYPingpongIrq;
+	boolean  encCbcrPingpongIrq;
+	boolean  viewYPingpongIrq;
+	boolean  viewCbcrPingpongIrq;
+	boolean  rdPingpongIrq;
+	boolean  afPingpongIrq;
+	boolean  awbPingpongIrq;
+	boolean  histPingpongIrq;
+	boolean  encIrq;
+	boolean  viewIrq;
+	boolean  busOverflowIrq;
+	boolean  afOverflowIrq;
+	boolean  awbOverflowIrq;
+	boolean  syncTimer0Irq;
+	boolean  syncTimer1Irq;
+	boolean  syncTimer2Irq;
+	boolean  asyncTimer0Irq;
+	boolean  asyncTimer1Irq;
+	boolean  asyncTimer2Irq;
+	boolean  asyncTimer3Irq;
+	boolean  axiErrorIrq;
+	boolean  violationIrq;
+};
+
+enum vfe_interrupt_name {
+	CAMIF_ERROR_IRQ,
+	CAMIF_SOF_IRQ,
+	CAMIF_EOL_IRQ,
+	CAMIF_EOF_IRQ,
+	CAMIF_EPOCH1_IRQ,
+	CAMIF_EPOCH2_IRQ,
+	CAMIF_OVERFLOW_IRQ,
+	CE_IRQ,
+	REG_UPDATE_IRQ,
+	RESET_ACK_IRQ,
+	ENC_Y_PINGPONG_IRQ,
+	ENC_CBCR_PINGPONG_IRQ,
+	VIEW_Y_PINGPONG_IRQ,
+	VIEW_CBCR_PINGPONG_IRQ,
+	RD_PINGPONG_IRQ,
+	AF_PINGPONG_IRQ,
+	AWB_PINGPONG_IRQ,
+	HIST_PINGPONG_IRQ,
+	ENC_IRQ,
+	VIEW_IRQ,
+	BUS_OVERFLOW_IRQ,
+	AF_OVERFLOW_IRQ,
+	AWB_OVERFLOW_IRQ,
+	SYNC_TIMER0_IRQ,
+	SYNC_TIMER1_IRQ,
+	SYNC_TIMER2_IRQ,
+	ASYNC_TIMER0_IRQ,
+	ASYNC_TIMER1_IRQ,
+	ASYNC_TIMER2_IRQ,
+	ASYNC_TIMER3_IRQ,
+	AXI_ERROR_IRQ,
+	VIOLATION_IRQ
+};
+
+enum VFE_DMI_RAM_SEL {
+	NO_MEM_SELECTED          = 0,
+	ROLLOFF_RAM              = 0x1,
+	RGBLUT_RAM_CH0_BANK0     = 0x2,
+	RGBLUT_RAM_CH0_BANK1     = 0x3,
+	RGBLUT_RAM_CH1_BANK0     = 0x4,
+	RGBLUT_RAM_CH1_BANK1     = 0x5,
+	RGBLUT_RAM_CH2_BANK0     = 0x6,
+	RGBLUT_RAM_CH2_BANK1     = 0x7,
+	STATS_HIST_CB_EVEN_RAM   = 0x8,
+	STATS_HIST_CB_ODD_RAM    = 0x9,
+	STATS_HIST_CR_EVEN_RAM   = 0xa,
+	STATS_HIST_CR_ODD_RAM    = 0xb,
+	RGBLUT_CHX_BANK0         = 0xc,
+	RGBLUT_CHX_BANK1         = 0xd,
+	LUMA_ADAPT_LUT_RAM_BANK0 = 0xe,
+	LUMA_ADAPT_LUT_RAM_BANK1 = 0xf
+};
+
+struct vfe_module_enable {
+	boolean  blackLevelCorrectionEnable;
+	boolean  lensRollOffEnable;
+	boolean  demuxEnable;
+	boolean  chromaUpsampleEnable;
+	boolean  demosaicEnable;
+	boolean  statsEnable;
+	boolean  cropEnable;
+	boolean  mainScalerEnable;
+	boolean  whiteBalanceEnable;
+	boolean  colorCorrectionEnable;
+	boolean  yHistEnable;
+	boolean  skinToneEnable;
+	boolean  lumaAdaptationEnable;
+	boolean  rgbLUTEnable;
+	boolean  chromaEnhanEnable;
+	boolean  asfEnable;
+	boolean  chromaSuppressionEnable;
+	boolean  chromaSubsampleEnable;
+	boolean  scaler2YEnable;
+	boolean  scaler2CbcrEnable;
+};
+
+struct vfe_bus_cmd_data {
+	boolean  stripeReload;
+	boolean  busPingpongReload;
+	boolean  statsPingpongReload;
+};
+
+struct vfe_stats_cmd_data {
+	boolean  autoFocusEnable;
+	boolean  axwEnable;
+	boolean  histEnable;
+	boolean  clearHistEnable;
+	boolean  histAutoClearEnable;
+	boolean  colorConversionEnable;
+};
+
+struct vfe_hw_ver {
+	uint32_t minorVersion:8;
+	uint32_t majorVersion:8;
+	uint32_t coreVersion:4;
+	uint32_t /* reserved */ : 12;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_cfg {
+	uint32_t pixelPattern:3;
+	uint32_t /* reserved */ : 13;
+	uint32_t inputSource:2;
+	uint32_t /* reserved */ : 14;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_buscmd {
+	uint32_t  stripeReload:1;
+	uint32_t  /* reserved */ : 3;
+	uint32_t  busPingpongReload:1;
+	uint32_t  statsPingpongReload:1;
+	uint32_t  /* reserved */ : 26;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_Irq_Composite_MaskType {
+	uint32_t  encIrqComMaskBits:2;
+	uint32_t  viewIrqComMaskBits:2;
+	uint32_t  ceDoneSelBits:5;
+	uint32_t  /* reserved */ : 23;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_mod_enable {
+	uint32_t blackLevelCorrectionEnable:1;
+	uint32_t lensRollOffEnable:1;
+	uint32_t demuxEnable:1;
+	uint32_t chromaUpsampleEnable:1;
+	uint32_t demosaicEnable:1;
+	uint32_t statsEnable:1;
+	uint32_t cropEnable:1;
+	uint32_t mainScalerEnable:1;
+	uint32_t whiteBalanceEnable:1;
+	uint32_t colorCorrectionEnable:1;
+	uint32_t yHistEnable:1;
+	uint32_t skinToneEnable:1;
+	uint32_t lumaAdaptationEnable:1;
+	uint32_t rgbLUTEnable:1;
+	uint32_t chromaEnhanEnable:1;
+	uint32_t asfEnable:1;
+	uint32_t chromaSuppressionEnable:1;
+	uint32_t chromaSubsampleEnable:1;
+	uint32_t scaler2YEnable:1;
+	uint32_t scaler2CbcrEnable:1;
+	uint32_t /* reserved */ : 14;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_irqenable {
+	uint32_t camifErrorIrq:1;
+	uint32_t camifSofIrq:1;
+	uint32_t camifEolIrq:1;
+	uint32_t camifEofIrq:1;
+	uint32_t camifEpoch1Irq:1;
+	uint32_t camifEpoch2Irq:1;
+	uint32_t camifOverflowIrq:1;
+	uint32_t ceIrq:1;
+	uint32_t regUpdateIrq:1;
+	uint32_t resetAckIrq:1;
+	uint32_t encYPingpongIrq:1;
+	uint32_t encCbcrPingpongIrq:1;
+	uint32_t viewYPingpongIrq:1;
+	uint32_t viewCbcrPingpongIrq:1;
+	uint32_t rdPingpongIrq:1;
+	uint32_t afPingpongIrq:1;
+	uint32_t awbPingpongIrq:1;
+	uint32_t histPingpongIrq:1;
+	uint32_t encIrq:1;
+	uint32_t viewIrq:1;
+	uint32_t busOverflowIrq:1;
+	uint32_t afOverflowIrq:1;
+	uint32_t awbOverflowIrq:1;
+	uint32_t syncTimer0Irq:1;
+	uint32_t syncTimer1Irq:1;
+	uint32_t syncTimer2Irq:1;
+	uint32_t asyncTimer0Irq:1;
+	uint32_t asyncTimer1Irq:1;
+	uint32_t asyncTimer2Irq:1;
+	uint32_t asyncTimer3Irq:1;
+	uint32_t axiErrorIrq:1;
+	uint32_t violationIrq:1;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_upsample_cfg {
+	uint32_t chromaCositingForYCbCrInputs:1;
+	uint32_t /* reserved */ : 31;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_CAMIFConfigType {
+	/* CAMIF Config */
+	uint32_t  /* reserved */ : 1;
+	uint32_t  VSyncEdge:1;
+	uint32_t  HSyncEdge:1;
+	uint32_t  syncMode:2;
+	uint32_t  vfeSubsampleEnable:1;
+	uint32_t  /* reserved */ : 1;
+	uint32_t  busSubsampleEnable:1;
+	uint32_t  camif2vfeEnable:1;
+	uint32_t  /* reserved */ : 1;
+	uint32_t  camif2busEnable:1;
+	uint32_t  irqSubsampleEnable:1;
+	uint32_t  binningEnable:1;
+	uint32_t  /* reserved */ : 18;
+	uint32_t  misrEnable:1;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_camifcfg {
+	/* EFS_Config */
+	uint32_t efsEndOfLine:8;
+	uint32_t efsStartOfLine:8;
+	uint32_t efsEndOfFrame:8;
+	uint32_t efsStartOfFrame:8;
+	/* Frame Config */
+	uint32_t frameConfigPixelsPerLine:14;
+	uint32_t /* reserved */ : 2;
+	uint32_t frameConfigLinesPerFrame:14;
+	uint32_t /* reserved */ : 2;
+	/* Window Width Config */
+	uint32_t windowWidthCfgLastPixel:14;
+	uint32_t /* reserved */ : 2;
+	uint32_t windowWidthCfgFirstPixel:14;
+	uint32_t /* reserved */ : 2;
+	/* Window Height Config */
+	uint32_t windowHeightCfglastLine:14;
+	uint32_t /* reserved */ : 2;
+	uint32_t windowHeightCfgfirstLine:14;
+	uint32_t /* reserved */ : 2;
+	/* Subsample 1 Config */
+	uint32_t subsample1CfgPixelSkip:16;
+	uint32_t subsample1CfgLineSkip:16;
+	/* Subsample 2 Config */
+	uint32_t subsample2CfgFrameSkip:4;
+	uint32_t subsample2CfgFrameSkipMode:1;
+	uint32_t subsample2CfgPixelSkipWrap:1;
+	uint32_t /* reserved */ : 26;
+	/* Epoch Interrupt */
+	uint32_t epoch1Line:14;
+	uint32_t /* reserved */ : 2;
+	uint32_t epoch2Line:14;
+	uint32_t /* reserved */ : 2;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_camifframe_update {
+	uint32_t pixelsPerLine:14;
+	uint32_t /* reserved */ : 2;
+	uint32_t linesPerFrame:14;
+	uint32_t /* reserved */ : 2;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_axi_bus_cfg {
+	uint32_t  stripeRdPathEn:1;
+	uint32_t  /* reserved */ : 3;
+	uint32_t  encYWrPathEn:1;
+	uint32_t  encCbcrWrPathEn:1;
+	uint32_t  viewYWrPathEn:1;
+	uint32_t  viewCbcrWrPathEn:1;
+	uint32_t  rawPixelDataSize:2;
+	uint32_t  rawWritePathSelect:2;
+	uint32_t  /* reserved */ : 20;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_axi_out_cfg {
+	uint32_t  out2YPingAddr:32;
+	uint32_t  out2YPongAddr:32;
+	uint32_t  out2YImageHeight:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  out2YImageWidthin64bit:10;
+	uint32_t  /* reserved */ : 6;
+	uint32_t  out2YBurstLength:2;
+	uint32_t  /* reserved */ : 2;
+	uint32_t  out2YNumRows:12;
+	uint32_t  out2YRowIncrementIn64bit:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  out2CbcrPingAddr:32;
+	uint32_t  out2CbcrPongAddr:32;
+	uint32_t  out2CbcrImageHeight:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  out2CbcrImageWidthIn64bit:10;
+	uint32_t  /* reserved */ : 6;
+	uint32_t  out2CbcrBurstLength:2;
+	uint32_t  /* reserved */ : 2;
+	uint32_t  out2CbcrNumRows:12;
+	uint32_t  out2CbcrRowIncrementIn64bit:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  out1YPingAddr:32;
+	uint32_t  out1YPongAddr:32;
+	uint32_t  out1YImageHeight:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  out1YImageWidthin64bit:10;
+	uint32_t  /* reserved */ : 6;
+	uint32_t  out1YBurstLength:2;
+	uint32_t  /* reserved */ : 2;
+	uint32_t  out1YNumRows:12;
+	uint32_t  out1YRowIncrementIn64bit:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  out1CbcrPingAddr:32;
+	uint32_t  out1CbcrPongAddr:32;
+	uint32_t  out1CbcrImageHeight:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  out1CbcrImageWidthIn64bit:10;
+	uint32_t  /* reserved */ : 6;
+	uint32_t  out1CbcrBurstLength:2;
+	uint32_t  /* reserved */ : 2;
+	uint32_t  out1CbcrNumRows:12;
+	uint32_t  out1CbcrRowIncrementIn64bit:12;
+	uint32_t  /* reserved */ : 4;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_output_clamp_cfg {
+	/* Output Clamp Maximums */
+	uint32_t yChanMax:8;
+	uint32_t cbChanMax:8;
+	uint32_t crChanMax:8;
+	uint32_t /* reserved */ : 8;
+	/* Output Clamp Minimums */
+	uint32_t yChanMin:8;
+	uint32_t cbChanMin:8;
+	uint32_t crChanMin:8;
+	uint32_t /* reserved */ : 8;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_fov_crop_cfg {
+	uint32_t lastPixel:12;
+	uint32_t /* reserved */ : 4;
+	uint32_t firstPixel:12;
+	uint32_t /* reserved */ : 4;
+
+	/* FOV Corp, Part 2 */
+	uint32_t lastLine:12;
+	uint32_t /* reserved */ : 4;
+	uint32_t firstLine:12;
+	uint32_t /* reserved */ : 4;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_FRAME_SKIP_UpdateCmdType {
+	uint32_t  yPattern:32;
+	uint32_t  cbcrPattern:32;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_frame_skip_cfg {
+	/* Frame Drop Enc (output2) */
+	uint32_t output2YPeriod:5;
+	uint32_t /* reserved */	: 27;
+	uint32_t output2CbCrPeriod:5;
+	uint32_t /* reserved */ : 27;
+	uint32_t output2YPattern:32;
+	uint32_t output2CbCrPattern:32;
+	/* Frame Drop View (output1) */
+	uint32_t output1YPeriod:5;
+	uint32_t /* reserved */ : 27;
+	uint32_t output1CbCrPeriod:5;
+	uint32_t /* reserved */ : 27;
+	uint32_t output1YPattern:32;
+	uint32_t output1CbCrPattern:32;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_main_scaler_cfg {
+	/* Scaler Enable Config */
+	uint32_t hEnable:1;
+	uint32_t vEnable:1;
+	uint32_t /* reserved */ : 30;
+	/* Scale H Image Size Config */
+	uint32_t inWidth:12;
+	uint32_t /* reserved */ : 4;
+	uint32_t outWidth:12;
+	uint32_t /* reserved */ : 4;
+	/* Scale H Phase Config */
+	uint32_t horizPhaseMult:18;
+	uint32_t /* reserved */ : 2;
+	uint32_t horizInterResolution:2;
+	uint32_t /* reserved */ : 10;
+	/* Scale H Stripe Config */
+	uint32_t horizMNInit:12;
+	uint32_t /* reserved */ : 4;
+	uint32_t horizPhaseInit:15;
+	uint32_t /* reserved */ : 1;
+	/* Scale V Image Size Config */
+	uint32_t inHeight:12;
+	uint32_t /* reserved */ : 4;
+	uint32_t outHeight:12;
+	uint32_t /* reserved */ : 4;
+	/* Scale V Phase Config */
+	uint32_t vertPhaseMult:18;
+	uint32_t /* reserved */ : 2;
+	uint32_t vertInterResolution:2;
+	uint32_t /* reserved */ : 10;
+	/* Scale V Stripe Config */
+	uint32_t vertMNInit:12;
+	uint32_t /* reserved */ : 4;
+	uint32_t vertPhaseInit:15;
+	uint32_t /* reserved */ : 1;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_scaler2_cfg {
+	/* Scaler   Enable Config */
+	uint32_t  hEnable:1;
+	uint32_t  vEnable:1;
+	uint32_t  /* reserved */ : 30;
+	/* Scaler   H Image Size Config */
+	uint32_t  inWidth:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  outWidth:12;
+	uint32_t  /* reserved */ : 4;
+	/* Scaler   H Phase Config */
+	uint32_t  horizPhaseMult:18;
+	uint32_t  /* reserved */ : 2;
+	uint32_t  horizInterResolution:2;
+	uint32_t  /* reserved */ : 10;
+	/* Scaler   V Image Size Config */
+	uint32_t  inHeight:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  outHeight:12;
+	uint32_t  /* reserved */ : 4;
+	/* Scaler   V Phase Config */
+	uint32_t  vertPhaseMult:18;
+	uint32_t  /* reserved */ : 2;
+	uint32_t  vertInterResolution:2;
+	uint32_t  /* reserved */ : 10;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_rolloff_cfg {
+	/* Rolloff 0 Config */
+	uint32_t  gridWidth:9;
+	uint32_t  gridHeight:9;
+	uint32_t  yDelta:9;
+	uint32_t  /* reserved */ : 5;
+	/* Rolloff 1 Config*/
+	uint32_t  gridX:4;
+	uint32_t  gridY:4;
+	uint32_t  pixelX:9;
+	uint32_t  /* reserved */ : 3;
+	uint32_t  pixelY:9;
+	uint32_t  /* reserved */ : 3;
+	/* Rolloff 2 Config */
+	uint32_t  yDeltaAccum:12;
+	uint32_t  /* reserved */ : 20;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_asf_update {
+	/* ASF Config Command */
+	uint32_t smoothEnable:1;
+	uint32_t sharpMode:2;
+	uint32_t /* reserved */ : 1;
+	uint32_t smoothCoeff1:4;
+	uint32_t smoothCoeff0:8;
+	uint32_t pipeFlushCount:12;
+	uint32_t pipeFlushOvd:1;
+	uint32_t flushHaltOvd:1;
+	uint32_t cropEnable:1;
+	uint32_t /* reserved */ : 1;
+	/* Sharpening Config 0 */
+	uint32_t sharpThresholdE1:7;
+	uint32_t /* reserved */ : 1;
+	uint32_t sharpDegreeK1:5;
+	uint32_t /* reserved */ : 3;
+	uint32_t sharpDegreeK2:5;
+	uint32_t /* reserved */ : 3;
+	uint32_t normalizeFactor:7;
+	uint32_t /* reserved */ : 1;
+	/* Sharpening Config 1 */
+	uint32_t sharpThresholdE2:8;
+	uint32_t sharpThresholdE3:8;
+	uint32_t sharpThresholdE4:8;
+	uint32_t sharpThresholdE5:8;
+	/* Sharpening Coefficients 0 */
+	uint32_t F1Coeff0:6;
+	uint32_t F1Coeff1:6;
+	uint32_t F1Coeff2:6;
+	uint32_t F1Coeff3:6;
+	uint32_t F1Coeff4:6;
+	uint32_t /* reserved */ : 2;
+	/* Sharpening Coefficients 1 */
+	uint32_t F1Coeff5:6;
+	uint32_t F1Coeff6:6;
+	uint32_t F1Coeff7:6;
+	uint32_t F1Coeff8:7;
+	uint32_t /* reserved */ : 7;
+	/* Sharpening Coefficients 2 */
+	uint32_t F2Coeff0:6;
+	uint32_t F2Coeff1:6;
+	uint32_t F2Coeff2:6;
+	uint32_t F2Coeff3:6;
+	uint32_t F2Coeff4:6;
+	uint32_t /* reserved */ : 2;
+	/* Sharpening Coefficients 3 */
+	uint32_t F2Coeff5:6;
+	uint32_t F2Coeff6:6;
+	uint32_t F2Coeff7:6;
+	uint32_t F2Coeff8:7;
+	uint32_t /* reserved */ : 7;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_asfcrop_cfg {
+	/* ASF Crop Width Config */
+	uint32_t lastPixel:12;
+	uint32_t /* reserved */ : 4;
+	uint32_t firstPixel:12;
+	uint32_t /* reserved */ : 4;
+	/* ASP Crop Height Config */
+	uint32_t lastLine:12;
+	uint32_t /* reserved */ : 4;
+	uint32_t firstLine:12;
+	uint32_t /* reserved */ : 4;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_chroma_suppress_cfg {
+	/* Chroma Suppress 0 Config */
+	uint32_t m1:8;
+	uint32_t m3:8;
+	uint32_t n1:3;
+	uint32_t /* reserved */ : 1;
+	uint32_t n3:3;
+	uint32_t /* reserved */ : 9;
+	/* Chroma Suppress 1 Config */
+	uint32_t mm1:8;
+	uint32_t nn1:3;
+	uint32_t /* reserved */ : 21;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_chromasubsample_cfg {
+	/* Chroma Subsample Selection */
+	uint32_t  hCositedPhase:1;
+	uint32_t  vCositedPhase:1;
+	uint32_t  hCosited:1;
+	uint32_t  vCosited:1;
+	uint32_t  hsubSampleEnable:1;
+	uint32_t  vsubSampleEnable:1;
+	uint32_t  cropEnable:1;
+	uint32_t  /* reserved */ : 25;
+	uint32_t  cropWidthLastPixel:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  cropWidthFirstPixel:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  cropHeightLastLine:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  cropHeightFirstLine:12;
+	uint32_t  /* reserved */ : 4;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_blacklevel_cfg {
+	/* Black Even-Even Value Config */
+	uint32_t    evenEvenAdjustment:9;
+	uint32_t   /* reserved */ : 23;
+	/* Black Even-Odd Value Config */
+	uint32_t    evenOddAdjustment:9;
+	uint32_t   /* reserved */ : 23;
+	/* Black Odd-Even Value Config */
+	uint32_t    oddEvenAdjustment:9;
+	uint32_t   /* reserved */ : 23;
+	/* Black Odd-Odd Value Config */
+	uint32_t    oddOddAdjustment:9;
+	uint32_t   /* reserved */ : 23;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_demux_cfg {
+	/* Demux Gain 0 Config */
+	uint32_t  ch0EvenGain:10;
+	uint32_t  /* reserved */ : 6;
+	uint32_t  ch0OddGain:10;
+	uint32_t  /* reserved */ : 6;
+	/* Demux Gain 1 Config */
+	uint32_t  ch1Gain:10;
+	uint32_t  /* reserved */ : 6;
+	uint32_t  ch2Gain:10;
+	uint32_t  /* reserved */ : 6;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_bps_info {
+  uint32_t greenBadPixelCount:8;
+  uint32_t /* reserved */ : 8;
+  uint32_t RedBlueBadPixelCount:8;
+  uint32_t /* reserved */ : 8;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_demosaic_cfg {
+	/* Demosaic Config */
+	uint32_t abfEnable:1;
+	uint32_t badPixelCorrEnable:1;
+	uint32_t forceAbfOn:1;
+	uint32_t /* reserved */ : 1;
+	uint32_t abfShift:4;
+	uint32_t fminThreshold:7;
+	uint32_t /* reserved */ : 1;
+	uint32_t fmaxThreshold:7;
+	uint32_t /* reserved */ : 5;
+	uint32_t slopeShift:3;
+	uint32_t /* reserved */ : 1;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_demosaic_bpc_cfg {
+	/* Demosaic BPC Config 0 */
+	uint32_t blueDiffThreshold:12;
+	uint32_t redDiffThreshold:12;
+	uint32_t /* reserved */ : 8;
+	/* Demosaic BPC Config 1 */
+	uint32_t greenDiffThreshold:12;
+	uint32_t /* reserved */ : 20;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_demosaic_abf_cfg {
+	/* Demosaic ABF Config 0 */
+	uint32_t lpThreshold:10;
+	uint32_t /* reserved */ : 22;
+	/* Demosaic ABF Config 1 */
+	uint32_t ratio:4;
+	uint32_t minValue:10;
+	uint32_t /* reserved */ : 2;
+	uint32_t maxValue:10;
+	uint32_t /* reserved */ : 6;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_color_correction_cfg {
+	/* Color Corr. Coefficient 0 Config */
+	uint32_t   c0:12;
+	uint32_t   /* reserved */ : 20;
+	/* Color Corr. Coefficient 1 Config */
+	uint32_t   c1:12;
+	uint32_t   /* reserved */ : 20;
+	/* Color Corr. Coefficient 2 Config */
+	uint32_t   c2:12;
+	uint32_t   /* reserved */ : 20;
+	/* Color Corr. Coefficient 3 Config */
+	uint32_t   c3:12;
+	uint32_t   /* reserved */ : 20;
+	/* Color Corr. Coefficient 4 Config */
+	uint32_t   c4:12;
+	uint32_t   /* reserved */ : 20;
+	/* Color Corr. Coefficient 5 Config */
+	uint32_t   c5:12;
+	uint32_t   /* reserved */ : 20;
+	/* Color Corr. Coefficient 6 Config */
+	uint32_t   c6:12;
+	uint32_t   /* reserved */ : 20;
+	/* Color Corr. Coefficient 7 Config */
+	uint32_t   c7:12;
+	uint32_t   /* reserved */ : 20;
+	/* Color Corr. Coefficient 8 Config */
+	uint32_t   c8:12;
+	uint32_t   /* reserved */ : 20;
+	/* Color Corr. Offset 0 Config */
+	uint32_t   k0:11;
+	uint32_t   /* reserved */ : 21;
+	/* Color Corr. Offset 1 Config */
+	uint32_t   k1:11;
+	uint32_t   /* reserved */ : 21;
+	/* Color Corr. Offset 2 Config */
+	uint32_t   k2:11;
+	uint32_t   /* reserved */ : 21;
+	/* Color Corr. Coefficient Q Config */
+	uint32_t   coefQFactor:2;
+	uint32_t   /* reserved */ : 30;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_LumaAdaptation_ConfigCmdType {
+	/* LA Config */
+	uint32_t   lutBankSelect:1;
+	uint32_t   /* reserved */ : 31;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_wb_cfg {
+	/* WB Config */
+	uint32_t ch0Gain:9;
+	uint32_t ch1Gain:9;
+	uint32_t ch2Gain:9;
+	uint32_t /* reserved */ : 5;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_GammaLutSelect_ConfigCmdType {
+	/* LUT Bank Select Config */
+	uint32_t   ch0BankSelect:1;
+	uint32_t   ch1BankSelect:1;
+	uint32_t   ch2BankSelect:1;
+	uint32_t   /* reserved */ : 29;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_chroma_enhance_cfg {
+	/* Chroma Enhance A Config */
+	uint32_t ap:11;
+	uint32_t /* reserved */ : 5;
+	uint32_t am:11;
+	uint32_t /* reserved */ : 5;
+	/* Chroma Enhance B Config */
+	uint32_t bp:11;
+	uint32_t /* reserved */ : 5;
+	uint32_t bm:11;
+	uint32_t /* reserved */ : 5;
+	/* Chroma Enhance C Config */
+	uint32_t cp:11;
+	uint32_t /* reserved */ : 5;
+	uint32_t cm:11;
+	uint32_t /* reserved */ : 5;
+	/* Chroma Enhance D Config */
+	uint32_t dp:11;
+	uint32_t /* reserved */ : 5;
+	uint32_t dm:11;
+	uint32_t /* reserved */ : 5;
+	/* Chroma Enhance K Config */
+	uint32_t kcb:11;
+	uint32_t /* reserved */ : 5;
+	uint32_t kcr:11;
+	uint32_t /* reserved */ : 5;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_color_convert_cfg {
+	/* Conversion Coefficient 0 */
+	uint32_t v0:12;
+	uint32_t /* reserved */ : 20;
+	/* Conversion Coefficient 1 */
+	uint32_t v1:12;
+	uint32_t /* reserved */ : 20;
+	/* Conversion Coefficient 2 */
+	uint32_t v2:12;
+	uint32_t /* reserved */ : 20;
+	/* Conversion Offset */
+	uint32_t ConvertOffset:8;
+	uint32_t /* reserved */ : 24;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_SyncTimer_ConfigCmdType {
+	/* Timer Line Start Config */
+	uint32_t       timerLineStart:12;
+	uint32_t       /* reserved */ : 20;
+	/* Timer Pixel Start Config */
+	uint32_t       timerPixelStart:18;
+	uint32_t       /* reserved */ : 14;
+	/* Timer Pixel Duration Config */
+	uint32_t       timerPixelDuration:28;
+	uint32_t       /* reserved */ : 4;
+	/* Sync Timer Polarity Config */
+	uint32_t       timer0Polarity:1;
+	uint32_t       timer1Polarity:1;
+	uint32_t       timer2Polarity:1;
+	uint32_t       /* reserved */ : 29;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_AsyncTimer_ConfigCmdType {
+	/* Async Timer Config 0 */
+	uint32_t     inactiveLength:20;
+	uint32_t     numRepetition:10;
+	uint32_t     /* reserved */ : 1;
+	uint32_t     polarity:1;
+	/* Async Timer Config 1 */
+	uint32_t     activeLength:20;
+	uint32_t     /* reserved */ : 12;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_AWBAEStatistics_ConfigCmdType {
+	/* AWB autoexposure Config */
+	uint32_t    aeRegionConfig:1;
+	uint32_t    aeSubregionConfig:1;
+	uint32_t    /* reserved */ : 14;
+	uint32_t    awbYMin:8;
+	uint32_t    awbYMax:8;
+	/* AXW Header */
+	uint32_t    axwHeader:8;
+	uint32_t    /* reserved */ : 24;
+	/* AWB Mconfig */
+	uint32_t    m4:8;
+	uint32_t    m3:8;
+	uint32_t    m2:8;
+	uint32_t    m1:8;
+	/* AWB Cconfig */
+	uint32_t    c2:12;
+	uint32_t    /* reserved */ : 4;
+	uint32_t    c1:12;
+	uint32_t    /* reserved */ : 4;
+	/* AWB Cconfig 2 */
+	uint32_t    c4:12;
+	uint32_t    /* reserved */ : 4;
+	uint32_t    c3:12;
+	uint32_t    /* reserved */ : 4;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_TestGen_ConfigCmdType {
+	/* HW Test Gen Config */
+	uint32_t   numFrame:10;
+	uint32_t   /* reserved */ : 2;
+	uint32_t   pixelDataSelect:1;
+	uint32_t   systematicDataSelect:1;
+	uint32_t   /* reserved */ : 2;
+	uint32_t   pixelDataSize:2;
+	uint32_t   hsyncEdge:1;
+	uint32_t   vsyncEdge:1;
+	uint32_t   /* reserved */ : 12;
+	/* HW Test Gen Image Config */
+	uint32_t   imageWidth:14;
+	uint32_t   /* reserved */ : 2;
+	uint32_t   imageHeight:14;
+	uint32_t   /* reserved */ : 2;
+	/* SOF Offset Config */
+	uint32_t   sofOffset:24;
+	uint32_t   /* reserved */ : 8;
+	/* EOF NOffset Config */
+	uint32_t   eofNOffset:24;
+	uint32_t   /* reserved */ : 8;
+	/* SOL Offset Config */
+	uint32_t   solOffset:9;
+	uint32_t   /* reserved */ : 23;
+	/* EOL NOffset Config */
+	uint32_t   eolNOffset:9;
+	uint32_t   /* reserved */ : 23;
+	/* HBI Config */
+	uint32_t   hBlankInterval:14;
+	uint32_t   /* reserved */ : 18;
+	/* VBL Config */
+	uint32_t   vBlankInterval:14;
+	uint32_t   /* reserved */ : 2;
+	uint32_t   vBlankIntervalEnable:1;
+	uint32_t   /* reserved */ : 15;
+	/* SOF Dummy Line Config */
+	uint32_t   sofDummy:8;
+	uint32_t   /* reserved */ : 24;
+	/* EOF Dummy Line Config */
+	uint32_t   eofDummy:8;
+	uint32_t   /* reserved */ : 24;
+	/* Color Bars Config */
+	uint32_t   unicolorBarSelect:3;
+	uint32_t   /* reserved */ : 1;
+	uint32_t   unicolorBarEnable:1;
+	uint32_t   splitEnable:1;
+	uint32_t   pixelPattern:2;
+	uint32_t   rotatePeriod:6;
+	uint32_t   /* reserved */ : 18;
+	/* Random Config */
+	uint32_t   randomSeed:16;
+	uint32_t   /* reserved */ : 16;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_Bus_Pm_ConfigCmdType {
+	/* VFE Bus Performance Monitor Config */
+	uint32_t  output2YWrPmEnable:1;
+	uint32_t  output2CbcrWrPmEnable:1;
+	uint32_t  output1YWrPmEnable:1;
+	uint32_t  output1CbcrWrPmEnable:1;
+	uint32_t  /* reserved */ : 28;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_asf_info {
+	/* asf max edge  */
+	uint32_t maxEdge:13;
+	uint32_t /* reserved */ : 3;
+	/* HBi count  */
+	uint32_t HBICount:12;
+	uint32_t /* reserved */ : 4;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_camif_stats {
+  uint32_t  pixelCount:14;
+  uint32_t  /* reserved */ : 2;
+  uint32_t  lineCount:14;
+  uint32_t  /* reserved */ : 1;
+  uint32_t  camifHalt:1;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_StatsCmdType {
+	uint32_t  autoFocusEnable:1;
+	uint32_t  axwEnable:1;
+	uint32_t  histEnable:1;
+	uint32_t  clearHistEnable:1;
+	uint32_t  histAutoClearEnable:1;
+	uint32_t  colorConversionEnable:1;
+	uint32_t  /* reserved */ : 26;
+} __attribute__((packed, aligned(4)));
+
+
+struct vfe_statsframe {
+	uint32_t lastPixel:12;
+	uint32_t /* reserved */ : 4;
+	uint32_t lastLine:12;
+	uint32_t /* reserved */ : 4;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_busstats_wrprio {
+	uint32_t afBusPriority:4;
+	uint32_t awbBusPriority:4;
+	uint32_t histBusPriority:4;
+	uint32_t afBusPriorityEn:1;
+	uint32_t awbBusPriorityEn:1;
+	uint32_t histBusPriorityEn:1;
+	uint32_t /* reserved */ : 17;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_statsaf_update {
+	/* VFE_STATS_AF_CFG */
+	uint32_t windowVOffset:12;
+	uint32_t /* reserved */ : 4;
+	uint32_t windowHOffset:12;
+	uint32_t /* reserved */ : 3;
+	uint32_t windowMode:1;
+
+	/* VFE_STATS_AF_DIM */
+	uint32_t windowHeight:12;
+	uint32_t /* reserved */ : 4;
+	uint32_t windowWidth:12;
+	uint32_t /* reserved */ : 4;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_statsaf_cfg {
+	/* VFE_STATS_AF_GRID_0 */
+	uint32_t  entry00:8;
+	uint32_t  entry01:8;
+	uint32_t  entry02:8;
+	uint32_t  entry03:8;
+
+	/* VFE_STATS_AF_GRID_1 */
+	uint32_t  entry10:8;
+	uint32_t  entry11:8;
+	uint32_t  entry12:8;
+	uint32_t  entry13:8;
+
+	/* VFE_STATS_AF_GRID_2 */
+	uint32_t  entry20:8;
+	uint32_t  entry21:8;
+	uint32_t  entry22:8;
+	uint32_t  entry23:8;
+
+	/* VFE_STATS_AF_GRID_3 */
+	uint32_t  entry30:8;
+	uint32_t  entry31:8;
+	uint32_t  entry32:8;
+	uint32_t  entry33:8;
+
+	/* VFE_STATS_AF_HEADER */
+	uint32_t  afHeader:8;
+	uint32_t  /* reserved */ : 24;
+	/*  VFE_STATS_AF_COEF0 */
+	uint32_t  a00:5;
+	uint32_t  a04:5;
+	uint32_t  fvMax:11;
+	uint32_t  fvMetric:1;
+	uint32_t  /* reserved */ : 10;
+
+	/* VFE_STATS_AF_COEF1 */
+	uint32_t  a20:5;
+	uint32_t  a21:5;
+	uint32_t  a22:5;
+	uint32_t  a23:5;
+	uint32_t  a24:5;
+	uint32_t  /* reserved */ : 7;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_statsawbae_update {
+	uint32_t  aeRegionCfg:1;
+	uint32_t  aeSubregionCfg:1;
+	uint32_t  /* reserved */ : 14;
+	uint32_t  awbYMin:8;
+	uint32_t  awbYMax:8;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_statsaxw_hdr_cfg {
+	/* Stats AXW Header Config */
+	uint32_t axwHeader:8;
+	uint32_t /* reserved */ : 24;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_statsawb_update {
+	/* AWB MConfig */
+	uint32_t  m4:8;
+	uint32_t  m3:8;
+	uint32_t  m2:8;
+	uint32_t  m1:8;
+
+	/* AWB CConfig1 */
+	uint32_t  c2:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  c1:12;
+	uint32_t  /* reserved */ : 4;
+
+	/* AWB CConfig2 */
+	uint32_t  c4:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  c3:12;
+	uint32_t  /* reserved */ : 4;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_SyncTimerCmdType {
+	uint32_t  hsyncCount:12;
+	uint32_t  /* reserved */ : 20;
+	uint32_t  pclkCount:18;
+	uint32_t  /* reserved */ : 14;
+	uint32_t  outputDuration:28;
+	uint32_t  /* reserved */ : 4;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_AsyncTimerCmdType {
+	/*  config 0 */
+	uint32_t    inactiveCount:20;
+	uint32_t    repeatCount:10;
+	uint32_t    /* reserved */ : 1;
+	uint32_t    polarity:1;
+	/*  config 1 */
+	uint32_t    activeCount:20;
+	uint32_t    /* reserved */ : 12;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_AxiInputCmdType {
+	uint32_t   stripeStartAddr0:32;
+	uint32_t   stripeStartAddr1:32;
+	uint32_t   stripeStartAddr2:32;
+	uint32_t   stripeStartAddr3:32;
+
+	uint32_t   ySize:12;
+	uint32_t   yOffsetDelta:12;
+	uint32_t   /* reserved */ : 8;
+
+	/* bus_stripe_rd_hSize */
+	uint32_t   /* reserved */ : 16;
+	uint32_t   xSizeWord:10;
+	uint32_t   /* reserved */ : 6;
+
+	/* bus_stripe_rd_buffer_cfg */
+	uint32_t   burstLength:2;
+	uint32_t   /* reserved */ : 2;
+	uint32_t   NumOfRows:12;
+	uint32_t   RowIncrement:12;
+	uint32_t   /* reserved */ : 4;
+
+	/* bus_stripe_rd_unpack_cfg */
+	uint32_t   mainUnpackHeight:12;
+	uint32_t   mainUnpackWidth:13;
+	uint32_t   mainUnpackHbiSel:3;
+	uint32_t   mainUnpackPhase:3;
+	uint32_t   /* reserved */ : 1;
+
+	/* bus_stripe_rd_unpack */
+	uint32_t   unpackPattern:32;
+
+	/* bus_stripe_rd_pad_size */
+	uint32_t   padLeft:7;
+	uint32_t   /* reserved */ : 1;
+	uint32_t   padRight:7;
+	uint32_t   /* reserved */ : 1;
+	uint32_t   padTop:7;
+	uint32_t   /* reserved */ : 1;
+	uint32_t   padBottom:7;
+	uint32_t   /* reserved */ : 1;
+
+	/* bus_stripe_rd_pad_L_unpack */
+	uint32_t   leftUnpackPattern0:4;
+	uint32_t   leftUnpackPattern1:4;
+	uint32_t   leftUnpackPattern2:4;
+	uint32_t   leftUnpackPattern3:4;
+	uint32_t   leftUnpackStop0:1;
+	uint32_t   leftUnpackStop1:1;
+	uint32_t   leftUnpackStop2:1;
+	uint32_t   leftUnpackStop3:1;
+	uint32_t   /* reserved */ : 12;
+
+	/* bus_stripe_rd_pad_R_unpack */
+	uint32_t   rightUnpackPattern0:4;
+	uint32_t   rightUnpackPattern1:4;
+	uint32_t   rightUnpackPattern2:4;
+	uint32_t   rightUnpackPattern3:4;
+	uint32_t   rightUnpackStop0:1;
+	uint32_t   rightUnpackStop1:1;
+	uint32_t   rightUnpackStop2:1;
+	uint32_t   rightUnpackStop3:1;
+	uint32_t   /* reserved */ : 12;
+
+	/* bus_stripe_rd_pad_tb_unpack */
+	uint32_t   topUnapckPattern:4;
+	uint32_t   /* reserved */ : 12;
+	uint32_t   bottomUnapckPattern:4;
+	uint32_t   /* reserved */ : 12;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_AxiRdFragIrqEnable {
+	uint32_t stripeRdFragirq0Enable:1;
+	uint32_t stripeRdFragirq1Enable:1;
+	uint32_t stripeRdFragirq2Enable:1;
+	uint32_t stripeRdFragirq3Enable:1;
+	uint32_t   /* reserved */ : 28;
+} __attribute__((packed, aligned(4)));
+
+int vfe_cmd_init(struct msm_vfe_callback *, struct platform_device *, void *);
+void vfe_stats_af_stop(void);
+void vfe_stop(void);
+void vfe_update(void);
+int vfe_rgb_gamma_update(struct vfe_cmd_rgb_gamma_config *);
+int vfe_rgb_gamma_config(struct vfe_cmd_rgb_gamma_config *);
+void vfe_stats_wb_exp_ack(struct vfe_cmd_stats_wb_exp_ack *);
+void vfe_stats_af_ack(struct vfe_cmd_stats_af_ack *);
+void vfe_start(struct vfe_cmd_start *);
+void vfe_la_update(struct vfe_cmd_la_config *);
+void vfe_la_config(struct vfe_cmd_la_config *);
+void vfe_test_gen_start(struct vfe_cmd_test_gen_start *);
+void vfe_frame_skip_update(struct vfe_cmd_frame_skip_update *);
+void vfe_frame_skip_config(struct vfe_cmd_frame_skip_config *);
+void vfe_output_clamp_config(struct vfe_cmd_output_clamp_config *);
+void vfe_camif_frame_update(struct vfe_cmds_camif_frame *);
+void vfe_color_correction_config(struct vfe_cmd_color_correction_config *);
+void vfe_demosaic_abf_update(struct vfe_cmd_demosaic_abf_update *);
+void vfe_demosaic_bpc_update(struct vfe_cmd_demosaic_bpc_update *);
+void vfe_demosaic_config(struct vfe_cmd_demosaic_config *);
+void vfe_demux_channel_gain_update(struct vfe_cmd_demux_channel_gain_config *);
+void vfe_demux_channel_gain_config(struct vfe_cmd_demux_channel_gain_config *);
+void vfe_black_level_update(struct vfe_cmd_black_level_config *);
+void vfe_black_level_config(struct vfe_cmd_black_level_config *);
+void vfe_asf_update(struct vfe_cmd_asf_update *);
+void vfe_asf_config(struct vfe_cmd_asf_config *);
+void vfe_white_balance_config(struct vfe_cmd_white_balance_config *);
+void vfe_chroma_sup_config(struct vfe_cmd_chroma_suppression_config *);
+void vfe_roll_off_config(struct vfe_cmd_roll_off_config *);
+void vfe_chroma_subsample_config(struct vfe_cmd_chroma_subsample_config *);
+void vfe_chroma_enhan_config(struct vfe_cmd_chroma_enhan_config *);
+void vfe_scaler2cbcr_config(struct vfe_cmd_scaler2_config *);
+void vfe_scaler2y_config(struct vfe_cmd_scaler2_config *);
+void vfe_main_scaler_config(struct vfe_cmd_main_scaler_config *);
+void vfe_stats_wb_exp_stop(void);
+void vfe_stats_update_wb_exp(struct vfe_cmd_stats_wb_exp_update *);
+void vfe_stats_update_af(struct vfe_cmd_stats_af_update *);
+void vfe_stats_start_wb_exp(struct vfe_cmd_stats_wb_exp_start *);
+void vfe_stats_start_af(struct vfe_cmd_stats_af_start *);
+void vfe_stats_setting(struct vfe_cmd_stats_setting *);
+void vfe_axi_input_config(struct vfe_cmd_axi_input_config *);
+void vfe_axi_output_config(struct vfe_cmd_axi_output_config *);
+void vfe_camif_config(struct vfe_cmd_camif_config *);
+void vfe_fov_crop_config(struct vfe_cmd_fov_crop_config *);
+void vfe_get_hw_version(struct vfe_cmd_hw_version *);
+void vfe_reset(void);
+void vfe_cmd_release(struct platform_device *);
+void vfe_output_p_ack(struct vfe_cmd_output_ack *);
+void vfe_output_v_ack(struct vfe_cmd_output_ack *);
+#endif /* __MSM_VFE8X_REG_H__ */
diff --git a/drivers/media/platform/msm/camera_v1/vfe/msm_vfe_stats_buf.c b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe_stats_buf.c
new file mode 100644
index 0000000..a6807ed
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe_stats_buf.c
@@ -0,0 +1,513 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/workqueue.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/ioctl.h>
+#include <linux/spinlock.h>
+#include <linux/videodev2.h>
+#include <linux/proc_fs.h>
+#include <linux/vmalloc.h>
+
+#include <media/v4l2-dev.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
+
+#include <linux/android_pmem.h>
+#include <media/msm_camera.h>
+#include <media/msm_isp.h>
+#include "msm.h"
+#include "msm_vfe_stats_buf.h"
+
+#ifdef CONFIG_MSM_CAMERA_DEBUG
+	#define D(fmt, args...) pr_debug("msm_stats: " fmt, ##args)
+#else
+	#define D(fmt, args...) do {} while (0)
+#endif
+
+static int msm_stats_init(struct msm_stats_bufq_ctrl *stats_ctrl)
+{
+	int rc = 0;
+	/* cannot get spinlock here */
+	if (stats_ctrl->init_done > 0) {
+		pr_err("%s: already initialized stats ctrl. no op", __func__);
+		return 0;
+	}
+	memset(stats_ctrl,  0,  sizeof(struct msm_stats_bufq_ctrl));
+	spin_lock_init(&stats_ctrl->lock);
+	stats_ctrl->init_done = 1;
+	return rc;
+}
+
+static int msm_stats_reqbuf(struct msm_stats_bufq_ctrl *stats_ctrl,
+	struct msm_stats_reqbuf *reqbuf,
+	struct ion_client *client)
+{
+	int rc = 0;
+	struct msm_stats_bufq *bufq;
+	struct msm_stats_meta_buf *bufs;
+	int idx = reqbuf->stats_type;
+	int i;
+
+	D("%s: type : %d, buf num : %d\n", __func__,
+		reqbuf->stats_type, reqbuf->num_buf);
+	if (reqbuf->num_buf > 0) {
+		if (stats_ctrl->bufq[idx]) {
+			/* already in use. Error */
+			pr_err("%s: stats type %d aleady requested",
+				 __func__, reqbuf->stats_type);
+			rc = -EEXIST;
+			goto end;
+		} else {
+			/* good case */
+			bufq = (struct msm_stats_bufq *)
+				kzalloc(
+					sizeof(struct msm_stats_bufq),
+					GFP_KERNEL);
+			if (!bufq) {
+				/* no memory */
+				rc = -ENOMEM;
+				pr_err("%s: no mem for stats type %d",
+					__func__, reqbuf->stats_type);
+				goto end;
+			}
+			bufs = (struct msm_stats_meta_buf *)
+				kzalloc((reqbuf->num_buf *
+					sizeof(struct msm_stats_meta_buf)),
+					GFP_KERNEL);
+			if (!bufs) {
+				/* no memory */
+				rc = -ENOMEM;
+				pr_err("%s: no mem for stats buf, stats type = %d",
+					__func__, reqbuf->stats_type);
+				kfree(bufq);
+				goto end;
+			}
+			/* init bufq list head */
+			INIT_LIST_HEAD(&bufq->head);
+			/* set the meta buf state to initialized */
+			bufq->num_bufs = reqbuf->num_buf;
+			for (i = 0; i < reqbuf->num_buf; i++)
+				bufs[i].state =
+					MSM_STATS_BUFFER_STATE_INITIALIZED;
+			bufq->bufs = bufs;
+			bufq->num_bufs = reqbuf->num_buf;
+			bufq->type = reqbuf->stats_type;
+			stats_ctrl->bufq[idx] = bufq;
+			/* done reqbuf (larger than zero case) */
+			goto end;
+		}
+	} else if (reqbuf->num_buf == 0) {
+		if (stats_ctrl->bufq[idx] == NULL) {
+			/* double free case? */
+			pr_err("%s: stats type %d aleady freed",
+				 __func__, reqbuf->stats_type);
+			rc = -ENXIO;
+			goto end;
+		} else {
+			/* good case. need to de-reqbuf */
+			kfree(stats_ctrl->bufq[idx]->bufs);
+			kfree(stats_ctrl->bufq[idx]);
+			stats_ctrl->bufq[idx] = NULL;
+			goto end;
+		}
+	} else {
+		/* error case */
+		pr_err("%s: stats type = %d, req_num_buf = %d, error",
+			   __func__, reqbuf->stats_type, reqbuf->num_buf);
+		rc = -EPERM;
+		goto end;
+	}
+end:
+	return rc;
+}
+static int msm_stats_deinit(struct msm_stats_bufq_ctrl *stats_ctrl)
+{
+	int rc = 0;
+	int i;
+
+	if (stats_ctrl->init_done == 0) {
+		pr_err("%s: not inited yet. no op", __func__);
+		return 0;
+	}
+	/* safe guard in case deallocate memory not done yet. */
+	for (i = 0; i < MSM_STATS_TYPE_MAX; i++) {
+		if (stats_ctrl->bufq[i]) {
+			if (stats_ctrl->bufq[i]->bufs) {
+				rc = -1;
+				pr_err("%s: stats type = %d, buf not freed yet",
+					 __func__, i);
+				BUG_ON(stats_ctrl->bufq[i]->bufs);
+			} else {
+				rc = -1;
+				pr_err("%s: stats type = %d, bufq not freed yet",
+					__func__, i);
+				BUG_ON(stats_ctrl->bufq[i]);
+			}
+		}
+	}
+	memset(stats_ctrl,  0,  sizeof(struct msm_stats_bufq_ctrl));
+	return rc;
+}
+
+#ifdef CONFIG_ANDROID_PMEM
+static int msm_stats_check_pmem_info(struct msm_stats_buf_info *info, int len)
+{
+	if (info->offset < len &&
+		info->offset + info->len <= len &&
+		info->planar0_off < len && info->planar1_off < len)
+		return 0;
+
+	pr_err("%s: check failed: off %d len %d y %d cbcr %d (total len %d)\n",
+		   __func__,
+		   info->offset,
+		   info->len,
+		   info->planar0_off,
+		   info->planar1_off,
+		   len);
+	return -EINVAL;
+}
+#endif
+
+static int msm_stats_buf_prepare(struct msm_stats_bufq_ctrl *stats_ctrl,
+	struct msm_stats_buf_info *info, struct ion_client *client,
+	int domain_num)
+{
+	unsigned long paddr;
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
+	unsigned long kvstart;
+	struct file *file;
+#endif
+	int rc = 0;
+	unsigned long len;
+	struct msm_stats_bufq *bufq = NULL;
+	struct msm_stats_meta_buf *stats_buf = NULL;
+
+	D("%s: type : %d, buf num : %d\n", __func__,
+		info->type, info->buf_idx);
+
+	bufq = stats_ctrl->bufq[info->type];
+	stats_buf = &bufq->bufs[info->buf_idx];
+	if (stats_buf->state == MSM_STATS_BUFFER_STATE_UNUSED) {
+		pr_err("%s: need reqbuf first, stats type = %d",
+			__func__, info->type);
+		rc = -1;
+		goto out1;
+	}
+	if (stats_buf->state != MSM_STATS_BUFFER_STATE_INITIALIZED) {
+		D("%s: stats already mapped, no op, stats type = %d",
+			__func__, info->type);
+		goto out1;
+	}
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	stats_buf->handle = ion_import_dma_buf(client, info->fd);
+	if (IS_ERR_OR_NULL(stats_buf->handle)) {
+		rc = -EINVAL;
+		pr_err("%s: stats_buf has null/error ION handle %p",
+			   __func__, stats_buf->handle);
+		goto out1;
+	}
+	if (ion_map_iommu(client, stats_buf->handle,
+			domain_num, 0, SZ_4K,
+			0, &paddr, &len, 0, 0) < 0) {
+		rc = -EINVAL;
+		pr_err("%s: cannot map address", __func__);
+		goto out2;
+	}
+#elif CONFIG_ANDROID_PMEM
+	rc = get_pmem_file(info->fd, &paddr, &kvstart, &len, &file);
+	if (rc < 0) {
+		pr_err("%s: get_pmem_file fd %d error %d\n",
+			   __func__, info->fd, rc);
+		goto out1;
+	}
+	stats_buf->file = file;
+#else
+	paddr = 0;
+	file = NULL;
+	kvstart = 0;
+#endif
+	if (!info->len)
+		info->len = len;
+	rc = msm_stats_check_pmem_info(info, len);
+	if (rc < 0) {
+		pr_err("%s: msm_stats_check_pmem_info err = %d", __func__, rc);
+		goto out3;
+	}
+	paddr += info->offset;
+	len = info->len;
+	stats_buf->paddr = paddr;
+	stats_buf->len = len;
+	memcpy(&stats_buf->info, info, sizeof(stats_buf->info));
+	D("%s Adding buf to list with type %d\n", __func__,
+	  stats_buf->info.type);
+	D("%s pmem_stats address is 0x%ld\n", __func__, paddr);
+	stats_buf->state = MSM_STATS_BUFFER_STATE_PREPARED;
+	return 0;
+out3:
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	ion_unmap_iommu(client, stats_buf->handle, domain_num, 0);
+#endif
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+out2:
+	ion_free(client, stats_buf->handle);
+#elif CONFIG_ANDROID_PMEM
+	put_pmem_file(stats_buf->file);
+#endif
+out1:
+	return rc;
+}
+static int msm_stats_buf_unprepare(struct msm_stats_bufq_ctrl *stats_ctrl,
+	enum msm_stats_enum_type stats_type, int buf_idx,
+	struct ion_client *client, int domain_num)
+{
+	int rc = 0;
+	struct msm_stats_bufq *bufq = NULL;
+	struct msm_stats_meta_buf *stats_buf = NULL;
+
+	D("%s: type : %d, idx : %d\n", __func__, stats_type, buf_idx);
+	bufq = stats_ctrl->bufq[stats_type];
+	stats_buf = &bufq->bufs[buf_idx];
+	if (stats_buf->state == MSM_STATS_BUFFER_STATE_UNUSED) {
+		pr_err("%s: need reqbuf first, stats type = %d",
+			__func__, stats_type);
+		rc = -1;
+		goto end;
+	}
+	if (stats_buf->state == MSM_STATS_BUFFER_STATE_INITIALIZED) {
+		D("%s: stats already mapped, no op, stats type = %d",
+			__func__, stats_type);
+		goto end;
+	}
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	ion_unmap_iommu(client, stats_buf->handle,
+					domain_num, 0);
+	ion_free(client, stats_buf->handle);
+#else
+	put_pmem_file(stats_buf->file);
+#endif
+	if (stats_buf->state == MSM_STATS_BUFFER_STATE_QUEUED) {
+		/* buf queued need delete from list */
+		D("%s: delete stats buf, type = %d, idx = %d",
+		  __func__,  stats_type,  buf_idx);
+		list_del_init(&stats_buf->list);
+	}
+end:
+	return rc;
+}
+
+static int msm_stats_bufq_flush(struct msm_stats_bufq_ctrl *stats_ctrl,
+	enum msm_stats_enum_type stats_type, struct ion_client *client)
+{
+	int rc = 0;
+	int i;
+	struct msm_stats_bufq *bufq = NULL;
+	struct msm_stats_meta_buf *stats_buf = NULL;
+
+	D("%s: type : %d\n", __func__, stats_type);
+	bufq = stats_ctrl->bufq[stats_type];
+
+	for (i = 0; i < bufq->num_bufs; i++) {
+		stats_buf = &bufq->bufs[i];
+		switch (stats_buf->state) {
+		case MSM_STATS_BUFFER_STATE_QUEUED:
+			/* buf queued in stats free queue */
+			stats_buf->state = MSM_STATS_BUFFER_STATE_PREPARED;
+			list_del_init(&stats_buf->list);
+			break;
+		case MSM_STATS_BUFFER_STATE_DEQUEUED:
+			/* if stats buf in VFE reset the state */
+			stats_buf->state = MSM_STATS_BUFFER_STATE_PREPARED;
+			break;
+		case MSM_STATS_BUFFER_STATE_DISPATCHED:
+			/* if stats buf in userspace reset the state */
+			stats_buf->state = MSM_STATS_BUFFER_STATE_PREPARED;
+			break;
+		default:
+			break;
+		}
+	}
+	return rc;
+}
+
+static int msm_stats_dqbuf(struct msm_stats_bufq_ctrl *stats_ctrl,
+	enum msm_stats_enum_type stats_type,
+	struct msm_stats_meta_buf **pp_stats_buf)
+{
+	int rc = 0;
+	struct msm_stats_bufq *bufq = NULL;
+	struct msm_stats_meta_buf *stats_buf = NULL;
+
+	D("%s: type : %d\n", __func__, stats_type);
+	*pp_stats_buf = NULL;
+	bufq = stats_ctrl->bufq[stats_type];
+
+	list_for_each_entry(stats_buf, &bufq->head, list) {
+		if (stats_buf->state == MSM_STATS_BUFFER_STATE_QUEUED) {
+			/* found one buf */
+			list_del_init(&stats_buf->list);
+			*pp_stats_buf = stats_buf;
+			break;
+		}
+	}
+	if (!(*pp_stats_buf)) {
+		D("%s: no free stats buf, type = %d",
+			__func__, stats_type);
+		rc = -1;
+		return rc;
+	}
+	stats_buf->state = MSM_STATS_BUFFER_STATE_DEQUEUED;
+	return rc;
+}
+
+
+static int msm_stats_querybuf(struct msm_stats_bufq_ctrl *stats_ctrl,
+	struct msm_stats_buf_info *info,
+	struct msm_stats_meta_buf **pp_stats_buf)
+{
+	int rc = 0;
+	struct msm_stats_bufq *bufq = NULL;
+
+	*pp_stats_buf = NULL;
+	D("%s: stats type : %d, buf_idx : %d", __func__, info->type,
+		   info->buf_idx);
+	bufq = stats_ctrl->bufq[info->type];
+	*pp_stats_buf = &bufq->bufs[info->buf_idx];
+
+	return rc;
+}
+
+static int msm_stats_qbuf(struct msm_stats_bufq_ctrl *stats_ctrl,
+	enum msm_stats_enum_type stats_type,
+	int buf_idx)
+{
+	int rc = 0;
+	struct msm_stats_bufq *bufq = NULL;
+	struct msm_stats_meta_buf *stats_buf = NULL;
+	D("%s: stats type : %d, buf_idx : %d", __func__, stats_type,
+		   buf_idx);
+
+	bufq = stats_ctrl->bufq[stats_type];
+	if (!bufq) {
+		pr_err("%s: null bufq, stats type = %d", __func__, stats_type);
+		rc = -1;
+		goto end;
+	}
+	if (buf_idx >= bufq->num_bufs) {
+		pr_err("%s: stats type = %d, its idx %d larger than buf count %d",
+			   __func__, stats_type, buf_idx, bufq->num_bufs);
+		rc = -1;
+		goto end;
+	}
+	stats_buf = &bufq->bufs[buf_idx];
+	switch (stats_buf->state) {
+	case MSM_STATS_BUFFER_STATE_PREPARED:
+	case MSM_STATS_BUFFER_STATE_DEQUEUED:
+	case MSM_STATS_BUFFER_STATE_DISPATCHED:
+		stats_buf->state = MSM_STATS_BUFFER_STATE_QUEUED;
+		list_add_tail(&stats_buf->list, &bufq->head);
+		break;
+	default:
+		pr_err("%s: incorrect state = %d, stats type = %d, cannot qbuf",
+			   __func__, stats_buf->state, stats_type);
+		rc = -1;
+		break;
+	}
+end:
+	return rc;
+}
+
+static int msm_stats_buf_dispatch(struct msm_stats_bufq_ctrl *stats_ctrl,
+	enum msm_stats_enum_type stats_type,
+	unsigned long phy_addr, int *buf_idx,
+	void **vaddr, int *fd,
+	struct ion_client *client)
+{
+	int rc = 0;
+	int i;
+	struct msm_stats_bufq *bufq = NULL;
+	struct msm_stats_meta_buf *stats_buf = NULL;
+	D("%s: stats type : %d\n", __func__, stats_type);
+
+	*buf_idx = -1;
+	*vaddr = NULL;
+	*fd = 0;
+	bufq = stats_ctrl->bufq[stats_type];
+	for (i = 0; i < bufq->num_bufs; i++) {
+		if (bufq->bufs[i].paddr == phy_addr) {
+			stats_buf = &bufq->bufs[i];
+			*buf_idx = i;
+			*vaddr = stats_buf->info.vaddr;
+			*fd = stats_buf->info.fd;
+			break;
+		}
+	}
+	if (!stats_buf) {
+		pr_err("%s: no match, phy_addr = 0x%ld, stats_type = %d",
+			   __func__, phy_addr, stats_type);
+		return -EFAULT;
+	}
+	switch (stats_buf->state) {
+	case MSM_STATS_BUFFER_STATE_DEQUEUED:
+		stats_buf->state = MSM_STATS_BUFFER_STATE_DISPATCHED;
+		break;
+	default:
+		pr_err("%s: type = %d, idx = %d, cur_state = %d,\n"
+			   "cannot set state to DISPATCHED\n",
+			   __func__, stats_type, *buf_idx, stats_buf->state);
+		rc = -EFAULT;
+		break;
+	}
+	return rc;
+}
+static int msm_stats_enqueue_buf(struct msm_stats_bufq_ctrl *stats_ctrl,
+	struct msm_stats_buf_info *info, struct ion_client *client,
+	int domain_num)
+{
+	int rc = 0;
+	D("%s: stats type : %d, idx : %d\n", __func__,
+		info->type, info->buf_idx);
+	rc = msm_stats_buf_prepare(stats_ctrl, info, client, domain_num);
+	if (rc < 0) {
+		pr_err("%s: buf_prepare failed, rc = %d", __func__, rc);
+		return -EINVAL;
+	}
+	rc = msm_stats_qbuf(stats_ctrl,   info->type, info->buf_idx);
+	if (rc < 0) {
+		pr_err("%s: msm_stats_qbuf failed, rc = %d", __func__, rc);
+		return -EINVAL;
+	}
+	return rc;
+}
+
+int msm_stats_buf_ops_init(struct msm_stats_bufq_ctrl *stats_ctrl,
+	struct ion_client *client, struct msm_stats_ops *ops)
+{
+	ops->stats_ctrl = stats_ctrl;
+	ops->client = client;
+	ops->enqueue_buf = msm_stats_enqueue_buf;
+	ops->qbuf = msm_stats_qbuf;
+	ops->dqbuf = msm_stats_dqbuf;
+	ops->bufq_flush = msm_stats_bufq_flush;
+	ops->buf_unprepare = msm_stats_buf_unprepare;
+	ops->buf_prepare = msm_stats_buf_prepare;
+	ops->reqbuf = msm_stats_reqbuf;
+	ops->querybuf = msm_stats_querybuf;
+	ops->dispatch = msm_stats_buf_dispatch;
+	ops->stats_ctrl_init = msm_stats_init;
+	ops->stats_ctrl_deinit = msm_stats_deinit;
+	return 0;
+}
+
diff --git a/drivers/media/platform/msm/camera_v1/vfe/msm_vfe_stats_buf.h b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe_stats_buf.h
new file mode 100644
index 0000000..6a1c79d
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vfe/msm_vfe_stats_buf.h
@@ -0,0 +1,93 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _MSM_STATS_BUF_H_
+#define _MSM_STATS_BUF_H_
+
+enum msm_stats_buffer_state {
+	MSM_STATS_BUFFER_STATE_UNUSED,	  /* not used */
+	MSM_STATS_BUFFER_STATE_INITIALIZED,	   /* REQBUF done */
+	MSM_STATS_BUFFER_STATE_PREPARED,	/* BUF mapped */
+	MSM_STATS_BUFFER_STATE_QUEUED,	  /* buf queued */
+	MSM_STATS_BUFFER_STATE_DEQUEUED,	/* in use in VFE */
+	MSM_STATS_BUFFER_STATE_DISPATCHED,	  /* sent to userspace */
+};
+
+struct msm_stats_meta_buf {
+	struct list_head list;
+	enum msm_stats_buffer_state state;
+	int type;
+	int fd;
+	uint32_t offset;
+	unsigned long paddr;
+	unsigned long len;
+	struct file *file;
+	struct msm_stats_buf_info info;
+	struct ion_handle *handle;
+};
+
+struct msm_stats_bufq {
+	struct list_head head;
+	int num_bufs;
+	int type;
+	struct msm_stats_meta_buf *bufs;
+};
+
+
+struct msm_stats_bufq_ctrl {
+	/* not use spin lock for now. Assume vfe holds spin lock */
+	spinlock_t lock;
+	int init_done;
+	struct msm_stats_bufq *bufq[MSM_STATS_TYPE_MAX];
+};
+
+struct msm_stats_ops {
+	struct msm_stats_bufq_ctrl *stats_ctrl;
+	struct ion_client *client;
+	int (*enqueue_buf) (struct msm_stats_bufq_ctrl *stats_ctrl,
+				struct msm_stats_buf_info *info,
+				struct ion_client *client, int domain_num);
+	int (*qbuf) (struct msm_stats_bufq_ctrl *stats_ctrl,
+				 enum msm_stats_enum_type stats_type,
+				 int buf_idx);
+	int (*dqbuf) (struct msm_stats_bufq_ctrl *stats_ctrl,
+				  enum msm_stats_enum_type stats_type,
+				  struct msm_stats_meta_buf **pp_stats_buf);
+	int (*bufq_flush) (struct msm_stats_bufq_ctrl *stats_ctrl,
+					   enum msm_stats_enum_type stats_type,
+					   struct ion_client *client);
+	int (*buf_unprepare) (struct msm_stats_bufq_ctrl *stats_ctrl,
+		enum msm_stats_enum_type stats_type,
+		int buf_idx,
+		struct ion_client *client, int domain_num);
+	int (*buf_prepare) (struct msm_stats_bufq_ctrl *stats_ctrl,
+				struct msm_stats_buf_info *info,
+				struct ion_client *client, int domain_num);
+	int (*reqbuf) (struct msm_stats_bufq_ctrl *stats_ctrl,
+				   struct msm_stats_reqbuf *reqbuf,
+				   struct ion_client *client);
+	int (*dispatch) (struct msm_stats_bufq_ctrl *stats_ctrl,
+		enum msm_stats_enum_type stats_type,
+		unsigned long phy_addr, int *buf_idx, void **vaddr, int *fd,
+		struct ion_client *client);
+	int (*querybuf) (struct msm_stats_bufq_ctrl *stats_ctrl,
+		struct msm_stats_buf_info *info,
+		struct msm_stats_meta_buf **pp_stats_buf);
+	int (*stats_ctrl_init) (struct msm_stats_bufq_ctrl *stats_ctrl);
+	int (*stats_ctrl_deinit) (struct msm_stats_bufq_ctrl *stats_ctrl);
+};
+
+int msm_stats_buf_ops_init(struct msm_stats_bufq_ctrl *stats_ctrl,
+	struct ion_client *client, struct msm_stats_ops *ops);
+
+#endif /* _MSM_STATS_BUF_H_ */
diff --git a/drivers/media/platform/msm/camera_v1/vx6953.c b/drivers/media/platform/msm/camera_v1/vx6953.c
new file mode 100644
index 0000000..cc09a0d
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vx6953.c
@@ -0,0 +1,3667 @@
+/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <media/msm_camera.h>
+#include <mach/gpio.h>
+#include <mach/camera.h>
+#include <linux/slab.h>
+#include "vx6953.h"
+
+/*=============================================================
+	SENSOR REGISTER DEFINES
+==============================================================*/
+
+#define REG_GROUPED_PARAMETER_HOLD			0x0104
+#define GROUPED_PARAMETER_HOLD_OFF			0x00
+#define GROUPED_PARAMETER_HOLD				0x01
+#define REG_MODE_SELECT					0x0100
+#define MODE_SELECT_STANDBY_MODE			0x00
+#define MODE_SELECT_STREAM				0x01
+/* Integration Time */
+#define REG_COARSE_INTEGRATION_TIME_HI			0x0202
+#define REG_COARSE_INTEGRATION_TIME_LO			0x0203
+/* Gain */
+#define REG_ANALOGUE_GAIN_CODE_GLOBAL_HI		0x0204
+#define REG_ANALOGUE_GAIN_CODE_GLOBAL_LO		0x0205
+/* Digital Gain */
+#define REG_DIGITAL_GAIN_GREEN_R_HI			0x020E
+#define REG_DIGITAL_GAIN_GREEN_R_LO			0x020F
+#define REG_DIGITAL_GAIN_RED_HI				0x0210
+#define REG_DIGITAL_GAIN_RED_LO				0x0211
+#define REG_DIGITAL_GAIN_BLUE_HI			0x0212
+#define REG_DIGITAL_GAIN_BLUE_LO			0x0213
+#define REG_DIGITAL_GAIN_GREEN_B_HI			0x0214
+#define REG_DIGITAL_GAIN_GREEN_B_LO			0x0215
+/* output bits setting */
+#define REG_0x0112					0x0112
+#define REG_0x0113					0x0113
+/* PLL registers */
+#define REG_VT_PIX_CLK_DIV				0x0301
+#define REG_PRE_PLL_CLK_DIV				0x0305
+#define REG_PLL_MULTIPLIER				0x0307
+#define REG_OP_PIX_CLK_DIV				0x0309
+#define REG_0x034c					0x034c
+#define REG_0x034d					0x034d
+#define REG_0x034e					0x034e
+#define REG_0x034f					0x034f
+#define REG_0x0387					0x0387
+#define REG_0x0383					0x0383
+#define REG_FRAME_LENGTH_LINES_HI			0x0340
+#define REG_FRAME_LENGTH_LINES_LO			0x0341
+#define REG_LINE_LENGTH_PCK_HI				0x0342
+#define REG_LINE_LENGTH_PCK_LO				0x0343
+#define REG_0x3030					0x3030
+#define REG_0x0111					0x0111
+#define REG_0x0136					0x0136
+#define REG_0x0137					0x0137
+#define REG_0x0b00					0x0b00
+#define REG_0x3001					0x3001
+#define REG_0x3004					0x3004
+#define REG_0x3007					0x3007
+#define REG_0x301a					0x301a
+#define REG_0x3101					0x3101
+#define REG_0x3364					0x3364
+#define REG_0x3365					0x3365
+#define REG_0x0b83					0x0b83
+#define REG_0x0b84					0x0b84
+#define REG_0x0b85					0x0b85
+#define REG_0x0b88					0x0b88
+#define REG_0x0b89					0x0b89
+#define REG_0x0b8a					0x0b8a
+#define REG_0x3005					0x3005
+#define REG_0x3010					0x3010
+#define REG_0x3036					0x3036
+#define REG_0x3041					0x3041
+#define REG_0x0b80					0x0b80
+#define REG_0x0900					0x0900
+#define REG_0x0901					0x0901
+#define REG_0x0902					0x0902
+#define REG_0x3016					0x3016
+#define REG_0x301d					0x301d
+#define REG_0x317e					0x317e
+#define REG_0x317f					0x317f
+#define REG_0x3400					0x3400
+#define REG_0x303a					0x303a
+#define REG_0x1716					0x1716
+#define REG_0x1717					0x1717
+#define REG_0x1718					0x1718
+#define REG_0x1719					0x1719
+#define REG_0x3006					0x3006
+#define REG_0x301b					0x301b
+#define REG_0x3098					0x3098
+#define REG_0x309d					0x309d
+#define REG_0x3011					0x3011
+#define REG_0x3035					0x3035
+#define REG_0x3045					0x3045
+#define REG_0x3210					0x3210
+#define	REG_0x0111					0x0111
+#define REG_0x3410					0x3410
+#define REG_0x0b06					0x0b06
+#define REG_0x0b07					0x0b07
+#define REG_0x0b08					0x0b08
+#define REG_0x0b09					0x0b09
+#define REG_0x3640					0x3640
+/* Test Pattern */
+#define REG_TEST_PATTERN_MODE				0x0601
+
+/*============================================================================
+							 TYPE DECLARATIONS
+============================================================================*/
+
+/* 16bit address - 8 bit context register structure */
+#define	VX6953_STM5M0EDOF_OFFSET	9
+#define	Q8		0x00000100
+#define	Q10		0x00000400
+#define	VX6953_STM5M0EDOF_MAX_SNAPSHOT_EXPOSURE_LINE_COUNT	2922
+#define	VX6953_STM5M0EDOF_DEFAULT_MASTER_CLK_RATE	24000000
+#define	VX6953_STM5M0EDOF_OP_PIXEL_CLOCK_RATE	79800000
+#define	VX6953_STM5M0EDOF_VT_PIXEL_CLOCK_RATE	88670000
+/* Full	Size */
+#define	VX6953_FULL_SIZE_WIDTH	2608
+#define	VX6953_FULL_SIZE_HEIGHT		1960
+#define	VX6953_FULL_SIZE_DUMMY_PIXELS	1
+#define	VX6953_FULL_SIZE_DUMMY_LINES	0
+/* Quarter Size	*/
+#define	VX6953_QTR_SIZE_WIDTH	1304
+#define	VX6953_QTR_SIZE_HEIGHT		980
+#define	VX6953_QTR_SIZE_DUMMY_PIXELS	1
+#define	VX6953_QTR_SIZE_DUMMY_LINES		0
+/* Blanking	as measured	on the scope */
+/* Full	Size */
+#define	VX6953_HRZ_FULL_BLK_PIXELS	348
+#define	VX6953_VER_FULL_BLK_LINES	40
+/* Quarter Size	*/
+#define	VX6953_HRZ_QTR_BLK_PIXELS	1628
+#define	VX6953_VER_QTR_BLK_LINES	28
+#define	MAX_LINE_LENGTH_PCK		8190
+#define	MAX_FRAME_LENGTH_LINES	16383
+#define	VX6953_REVISION_NUMBER_CUT2	0x10/*revision number	for	Cut2.0*/
+#define	VX6953_REVISION_NUMBER_CUT3	0x20/*revision number	for	Cut3.0*/
+/* FIXME: Changes from here */
+struct vx6953_work_t {
+	struct work_struct work;
+};
+
+static struct vx6953_work_t *vx6953_sensorw;
+static struct i2c_client *vx6953_client;
+
+struct vx6953_ctrl_t {
+	const struct  msm_camera_sensor_info *sensordata;
+
+	uint32_t sensormode;
+	uint32_t fps_divider;   	/* init to 1 * 0x00000400 */
+	uint32_t pict_fps_divider;  /* init to 1 * 0x00000400 */
+	uint16_t fps;
+
+	int16_t curr_lens_pos;
+	uint16_t curr_step_pos;
+	uint16_t my_reg_gain;
+	uint32_t my_reg_line_count;
+	uint16_t total_lines_per_frame;
+
+	enum vx6953_resolution_t prev_res;
+	enum vx6953_resolution_t pict_res;
+	enum vx6953_resolution_t curr_res;
+	enum vx6953_test_mode_t  set_test;
+	enum sensor_revision_t sensor_type;
+
+	enum edof_mode_t edof_mode;
+
+	unsigned short imgaddr;
+};
+
+
+static uint8_t vx6953_stm5m0edof_delay_msecs_stdby;
+static uint16_t vx6953_stm5m0edof_delay_msecs_stream = 20;
+static uint8_t count;
+static struct vx6953_ctrl_t *vx6953_ctrl;
+static DECLARE_WAIT_QUEUE_HEAD(vx6953_wait_queue);
+DEFINE_MUTEX(vx6953_mut);
+static struct vx6953_i2c_reg_conf patch_tbl_cut2[] = {
+	{0xFB94, 0},	/*intialise Data Xfer Status reg*/
+	{0xFB95, 0},	/*gain 1	  (0x00)*/
+	{0xFB96, 0},	/*gain 1.07   (0x10)*/
+	{0xFB97, 0},	/*gain 1.14   (0x20)*/
+	{0xFB98, 0},	/*gain 1.23   (0x30)*/
+	{0xFB99, 0},	/*gain 1.33   (0x40)*/
+	{0xFB9A, 0},	/*gain 1.45   (0x50)*/
+	{0xFB9B, 0},	/*gain 1.6    (0x60)*/
+	{0xFB9C, 0},	/*gain 1.78   (0x70)*/
+	{0xFB9D, 2},	/*gain 2	  (0x80)*/
+	{0xFB9E, 2},	/*gain 2.29   (0x90)*/
+	{0xFB9F, 3},	/*gain 2.67   (0xA0)*/
+	{0xFBA0, 3},	/*gain 3.2    (0xB0)*/
+	{0xFBA1, 4},	/*gain 4	  (0xC0)*/
+	{0xFBA2, 7},	/*gain 5.33   (0xD0)*/
+	{0xFBA3, 10},	/*gain 8	  (0xE0)*/
+	{0xFBA4, 11},	/*gain 9.14   (0xE4)*/
+	{0xFBA5, 13},	/*gain 10.67  (0xE8)*/
+	{0xFBA6, 15},	/*gain 12.8   (0xEC)*/
+	{0xFBA7, 19},	/*gain 16     (0xF0)*/
+	{0xF800, 0x12},
+	{0xF801, 0x06},
+	{0xF802, 0xf7},
+	{0xF803, 0x90},
+	{0xF804, 0x02},
+	{0xF805, 0x05},
+	{0xF806, 0xe0},
+	{0xF807, 0xff},
+	{0xF808, 0x65},
+	{0xF809, 0x7d},
+	{0xF80A, 0x70},
+	{0xF80B, 0x03},
+	{0xF80C, 0x02},
+	{0xF80D, 0xf9},
+	{0xF80E, 0x1c},
+	{0xF80F, 0x8f},
+	{0xF810, 0x7d},
+	{0xF811, 0xe4},
+	{0xF812, 0xf5},
+	{0xF813, 0x7a},
+	{0xF814, 0x75},
+	{0xF815, 0x78},
+	{0xF816, 0x30},
+	{0xF817, 0x75},
+	{0xF818, 0x79},
+	{0xF819, 0x53},
+	{0xF81A, 0x85},
+	{0xF81B, 0x79},
+	{0xF81C, 0x82},
+	{0xF81D, 0x85},
+	{0xF81E, 0x78},
+	{0xF81F, 0x83},
+	{0xF820, 0xe0},
+	{0xF821, 0xc3},
+	{0xF822, 0x95},
+	{0xF823, 0x7b},
+	{0xF824, 0xf0},
+	{0xF825, 0x74},
+	{0xF826, 0x02},
+	{0xF827, 0x25},
+	{0xF828, 0x79},
+	{0xF829, 0xf5},
+	{0xF82A, 0x79},
+	{0xF82B, 0xe4},
+	{0xF82C, 0x35},
+	{0xF82D, 0x78},
+	{0xF82E, 0xf5},
+	{0xF82F, 0x78},
+	{0xF830, 0x05},
+	{0xF831, 0x7a},
+	{0xF832, 0xe5},
+	{0xF833, 0x7a},
+	{0xF834, 0xb4},
+	{0xF835, 0x08},
+	{0xF836, 0xe3},
+	{0xF837, 0xe5},
+	{0xF838, 0x7d},
+	{0xF839, 0x70},
+	{0xF83A, 0x04},
+	{0xF83B, 0xff},
+	{0xF83C, 0x02},
+	{0xF83D, 0xf8},
+	{0xF83E, 0xe4},
+	{0xF83F, 0xe5},
+	{0xF840, 0x7d},
+	{0xF841, 0xb4},
+	{0xF842, 0x10},
+	{0xF843, 0x05},
+	{0xF844, 0x7f},
+	{0xF845, 0x01},
+	{0xF846, 0x02},
+	{0xF847, 0xf8},
+	{0xF848, 0xe4},
+	{0xF849, 0xe5},
+	{0xF84A, 0x7d},
+	{0xF84B, 0xb4},
+	{0xF84C, 0x20},
+	{0xF84D, 0x05},
+	{0xF84E, 0x7f},
+	{0xF84F, 0x02},
+	{0xF850, 0x02},
+	{0xF851, 0xf8},
+	{0xF852, 0xe4},
+	{0xF853, 0xe5},
+	{0xF854, 0x7d},
+	{0xF855, 0xb4},
+	{0xF856, 0x30},
+	{0xF857, 0x05},
+	{0xF858, 0x7f},
+	{0xF859, 0x03},
+	{0xF85A, 0x02},
+	{0xF85B, 0xf8},
+	{0xF85C, 0xe4},
+	{0xF85D, 0xe5},
+	{0xF85E, 0x7d},
+	{0xF85F, 0xb4},
+	{0xF860, 0x40},
+	{0xF861, 0x04},
+	{0xF862, 0x7f},
+	{0xF863, 0x04},
+	{0xF864, 0x80},
+	{0xF865, 0x7e},
+	{0xF866, 0xe5},
+	{0xF867, 0x7d},
+	{0xF868, 0xb4},
+	{0xF869, 0x50},
+	{0xF86A, 0x04},
+	{0xF86B, 0x7f},
+	{0xF86C, 0x05},
+	{0xF86D, 0x80},
+	{0xF86E, 0x75},
+	{0xF86F, 0xe5},
+	{0xF870, 0x7d},
+	{0xF871, 0xb4},
+	{0xF872, 0x60},
+	{0xF873, 0x04},
+	{0xF874, 0x7f},
+	{0xF875, 0x06},
+	{0xF876, 0x80},
+	{0xF877, 0x6c},
+	{0xF878, 0xe5},
+	{0xF879, 0x7d},
+	{0xF87A, 0xb4},
+	{0xF87B, 0x70},
+	{0xF87C, 0x04},
+	{0xF87D, 0x7f},
+	{0xF87E, 0x07},
+	{0xF87F, 0x80},
+	{0xF880, 0x63},
+	{0xF881, 0xe5},
+	{0xF882, 0x7d},
+	{0xF883, 0xb4},
+	{0xF884, 0x80},
+	{0xF885, 0x04},
+	{0xF886, 0x7f},
+	{0xF887, 0x08},
+	{0xF888, 0x80},
+	{0xF889, 0x5a},
+	{0xF88A, 0xe5},
+	{0xF88B, 0x7d},
+	{0xF88C, 0xb4},
+	{0xF88D, 0x90},
+	{0xF88E, 0x04},
+	{0xF88F, 0x7f},
+	{0xF890, 0x09},
+	{0xF891, 0x80},
+	{0xF892, 0x51},
+	{0xF893, 0xe5},
+	{0xF894, 0x7d},
+	{0xF895, 0xb4},
+	{0xF896, 0xa0},
+	{0xF897, 0x04},
+	{0xF898, 0x7f},
+	{0xF899, 0x0a},
+	{0xF89A, 0x80},
+	{0xF89B, 0x48},
+	{0xF89C, 0xe5},
+	{0xF89D, 0x7d},
+	{0xF89E, 0xb4},
+	{0xF89F, 0xb0},
+	{0xF8A0, 0x04},
+	{0xF8A1, 0x7f},
+	{0xF8A2, 0x0b},
+	{0xF8A3, 0x80},
+	{0xF8A4, 0x3f},
+	{0xF8A5, 0xe5},
+	{0xF8A6, 0x7d},
+	{0xF8A7, 0xb4},
+	{0xF8A8, 0xc0},
+	{0xF8A9, 0x04},
+	{0xF8AA, 0x7f},
+	{0xF8AB, 0x0c},
+	{0xF8AC, 0x80},
+	{0xF8AD, 0x36},
+	{0xF8AE, 0xe5},
+	{0xF8AF, 0x7d},
+	{0xF8B0, 0xb4},
+	{0xF8B1, 0xd0},
+	{0xF8B2, 0x04},
+	{0xF8B3, 0x7f},
+	{0xF8B4, 0x0d},
+	{0xF8B5, 0x80},
+	{0xF8B6, 0x2d},
+	{0xF8B7, 0xe5},
+	{0xF8B8, 0x7d},
+	{0xF8B9, 0xb4},
+	{0xF8BA, 0xe0},
+	{0xF8BB, 0x04},
+	{0xF8BC, 0x7f},
+	{0xF8BD, 0x0e},
+	{0xF8BE, 0x80},
+	{0xF8BF, 0x24},
+	{0xF8C0, 0xe5},
+	{0xF8C1, 0x7d},
+	{0xF8C2, 0xb4},
+	{0xF8C3, 0xe4},
+	{0xF8C4, 0x04},
+	{0xF8C5, 0x7f},
+	{0xF8C6, 0x0f},
+	{0xF8C7, 0x80},
+	{0xF8C8, 0x1b},
+	{0xF8C9, 0xe5},
+	{0xF8CA, 0x7d},
+	{0xF8CB, 0xb4},
+	{0xF8CC, 0xe8},
+	{0xF8CD, 0x04},
+	{0xF8CE, 0x7f},
+	{0xF8CF, 0x10},
+	{0xF8D0, 0x80},
+	{0xF8D1, 0x12},
+	{0xF8D2, 0xe5},
+	{0xF8D3, 0x7d},
+	{0xF8D4, 0xb4},
+	{0xF8D5, 0xec},
+	{0xF8D6, 0x04},
+	{0xF8D7, 0x7f},
+	{0xF8D8, 0x11},
+	{0xF8D9, 0x80},
+	{0xF8DA, 0x09},
+	{0xF8DB, 0xe5},
+	{0xF8DC, 0x7d},
+	{0xF8DD, 0x7f},
+	{0xF8DE, 0x00},
+	{0xF8DF, 0xb4},
+	{0xF8E0, 0xf0},
+	{0xF8E1, 0x02},
+	{0xF8E2, 0x7f},
+	{0xF8E3, 0x12},
+	{0xF8E4, 0x8f},
+	{0xF8E5, 0x7c},
+	{0xF8E6, 0xef},
+	{0xF8E7, 0x24},
+	{0xF8E8, 0x95},
+	{0xF8E9, 0xff},
+	{0xF8EA, 0xe4},
+	{0xF8EB, 0x34},
+	{0xF8EC, 0xfb},
+	{0xF8ED, 0x8f},
+	{0xF8EE, 0x82},
+	{0xF8EF, 0xf5},
+	{0xF8F0, 0x83},
+	{0xF8F1, 0xe4},
+	{0xF8F2, 0x93},
+	{0xF8F3, 0xf5},
+	{0xF8F4, 0x7c},
+	{0xF8F5, 0xf5},
+	{0xF8F6, 0x7b},
+	{0xF8F7, 0xe4},
+	{0xF8F8, 0xf5},
+	{0xF8F9, 0x7a},
+	{0xF8FA, 0x75},
+	{0xF8FB, 0x78},
+	{0xF8FC, 0x30},
+	{0xF8FD, 0x75},
+	{0xF8FE, 0x79},
+	{0xF8FF, 0x53},
+	{0xF900, 0x85},
+	{0xF901, 0x79},
+	{0xF902, 0x82},
+	{0xF903, 0x85},
+	{0xF904, 0x78},
+	{0xF905, 0x83},
+	{0xF906, 0xe0},
+	{0xF907, 0x25},
+	{0xF908, 0x7c},
+	{0xF909, 0xf0},
+	{0xF90A, 0x74},
+	{0xF90B, 0x02},
+	{0xF90C, 0x25},
+	{0xF90D, 0x79},
+	{0xF90E, 0xf5},
+	{0xF90F, 0x79},
+	{0xF910, 0xe4},
+	{0xF911, 0x35},
+	{0xF912, 0x78},
+	{0xF913, 0xf5},
+	{0xF914, 0x78},
+	{0xF915, 0x05},
+	{0xF916, 0x7a},
+	{0xF917, 0xe5},
+	{0xF918, 0x7a},
+	{0xF919, 0xb4},
+	{0xF91A, 0x08},
+	{0xF91B, 0xe4},
+	{0xF91C, 0x02},
+	{0xF91D, 0x18},
+	{0xF91E, 0x32},
+	{0xF91F, 0x22},
+	{0xF920, 0xf0},
+	{0xF921, 0x90},
+	{0xF922, 0xa0},
+	{0xF923, 0xf8},
+	{0xF924, 0xe0},
+	{0xF925, 0x70},
+	{0xF926, 0x02},
+	{0xF927, 0xa3},
+	{0xF928, 0xe0},
+	{0xF929, 0x70},
+	{0xF92A, 0x0a},
+	{0xF92B, 0x90},
+	{0xF92C, 0xa1},
+	{0xF92D, 0x10},
+	{0xF92E, 0xe0},
+	{0xF92F, 0xfe},
+	{0xF930, 0xa3},
+	{0xF931, 0xe0},
+	{0xF932, 0xff},
+	{0xF933, 0x80},
+	{0xF934, 0x04},
+	{0xF935, 0x7e},
+	{0xF936, 0x00},
+	{0xF937, 0x7f},
+	{0xF938, 0x00},
+	{0xF939, 0x8e},
+	{0xF93A, 0x7e},
+	{0xF93B, 0x8f},
+	{0xF93C, 0x7f},
+	{0xF93D, 0x90},
+	{0xF93E, 0x36},
+	{0xF93F, 0x0d},
+	{0xF940, 0xe0},
+	{0xF941, 0x44},
+	{0xF942, 0x02},
+	{0xF943, 0xf0},
+	{0xF944, 0x90},
+	{0xF945, 0x36},
+	{0xF946, 0x0e},
+	{0xF947, 0xe5},
+	{0xF948, 0x7e},
+	{0xF949, 0xf0},
+	{0xF94A, 0xa3},
+	{0xF94B, 0xe5},
+	{0xF94C, 0x7f},
+	{0xF94D, 0xf0},
+	{0xF94E, 0xe5},
+	{0xF94F, 0x3a},
+	{0xF950, 0x60},
+	{0xF951, 0x0c},
+	{0xF952, 0x90},
+	{0xF953, 0x36},
+	{0xF954, 0x09},
+	{0xF955, 0xe0},
+	{0xF956, 0x70},
+	{0xF957, 0x06},
+	{0xF958, 0x90},
+	{0xF959, 0x36},
+	{0xF95A, 0x08},
+	{0xF95B, 0xf0},
+	{0xF95C, 0xf5},
+	{0xF95D, 0x3a},
+	{0xF95E, 0x02},
+	{0xF95F, 0x03},
+	{0xF960, 0x94},
+	{0xF961, 0x22},
+	{0xF962, 0x78},
+	{0xF963, 0x07},
+	{0xF964, 0xe6},
+	{0xF965, 0xd3},
+	{0xF966, 0x94},
+	{0xF967, 0x00},
+	{0xF968, 0x40},
+	{0xF969, 0x16},
+	{0xF96A, 0x16},
+	{0xF96B, 0xe6},
+	{0xF96C, 0x90},
+	{0xF96D, 0x30},
+	{0xF96E, 0xa1},
+	{0xF96F, 0xf0},
+	{0xF970, 0x90},
+	{0xF971, 0x43},
+	{0xF972, 0x83},
+	{0xF973, 0xe0},
+	{0xF974, 0xb4},
+	{0xF975, 0x01},
+	{0xF976, 0x0f},
+	{0xF977, 0x90},
+	{0xF978, 0x43},
+	{0xF979, 0x87},
+	{0xF97A, 0xe0},
+	{0xF97B, 0xb4},
+	{0xF97C, 0x01},
+	{0xF97D, 0x08},
+	{0xF97E, 0x80},
+	{0xF97F, 0x00},
+	{0xF980, 0x90},
+	{0xF981, 0x30},
+	{0xF982, 0xa0},
+	{0xF983, 0x74},
+	{0xF984, 0x01},
+	{0xF985, 0xf0},
+	{0xF986, 0x22},
+	{0xF987, 0xf0},
+	{0xF988, 0x90},
+	{0xF989, 0x35},
+	{0xF98A, 0xba},
+	{0xF98B, 0xe0},
+	{0xF98C, 0xb4},
+	{0xF98D, 0x0a},
+	{0xF98E, 0x0d},
+	{0xF98F, 0xa3},
+	{0xF990, 0xe0},
+	{0xF991, 0xb4},
+	{0xF992, 0x01},
+	{0xF993, 0x08},
+	{0xF994, 0x90},
+	{0xF995, 0xfb},
+	{0xF996, 0x94},
+	{0xF997, 0xe0},
+	{0xF998, 0x90},
+	{0xF999, 0x35},
+	{0xF99A, 0xb8},
+	{0xF99B, 0xf0},
+	{0xF99C, 0xd0},
+	{0xF99D, 0xd0},
+	{0xF99E, 0xd0},
+	{0xF99F, 0x82},
+	{0xF9A0, 0xd0},
+	{0xF9A1, 0x83},
+	{0xF9A2, 0xd0},
+	{0xF9A3, 0xe0},
+	{0xF9A4, 0x32},
+	{0xF9A5, 0x22},
+	{0xF9A6, 0xe5},
+	{0xF9A7, 0x7f},
+	{0xF9A8, 0x45},
+	{0xF9A9, 0x7e},
+	{0xF9AA, 0x60},
+	{0xF9AB, 0x15},
+	{0xF9AC, 0x90},
+	{0xF9AD, 0x01},
+	{0xF9AE, 0x00},
+	{0xF9AF, 0xe0},
+	{0xF9B0, 0x70},
+	{0xF9B1, 0x0f},
+	{0xF9B2, 0x90},
+	{0xF9B3, 0xa0},
+	{0xF9B4, 0xf8},
+	{0xF9B5, 0xe5},
+	{0xF9B6, 0x7e},
+	{0xF9B7, 0xf0},
+	{0xF9B8, 0xa3},
+	{0xF9B9, 0xe5},
+	{0xF9BA, 0x7f},
+	{0xF9BB, 0xf0},
+	{0xF9BC, 0xe4},
+	{0xF9BD, 0xf5},
+	{0xF9BE, 0x7e},
+	{0xF9BF, 0xf5},
+	{0xF9C0, 0x7f},
+	{0xF9C1, 0x22},
+	{0xF9C2, 0x02},
+	{0xF9C3, 0x0e},
+	{0xF9C4, 0x79},
+	{0xF9C5, 0x22},
+	/* Offsets:*/
+	{0x35C6, 0x00},/* FIDDLEDARKCAL*/
+	{0x35C7, 0x00},
+	{0x35C8, 0x01},/*STOREDISTANCEATSTOPSTREAMING*/
+	{0x35C9, 0x20},
+	{0x35CA, 0x01},/*BRUCEFIX*/
+	{0x35CB, 0x62},
+	{0x35CC, 0x01},/*FIXDATAXFERSTATUSREG*/
+	{0x35CD, 0x87},
+	{0x35CE, 0x01},/*FOCUSDISTANCEUPDATE*/
+	{0x35CF, 0xA6},
+	{0x35D0, 0x01},/*SKIPEDOFRESET*/
+	{0x35D1, 0xC2},
+	{0x35D2, 0x00},
+	{0x35D3, 0xFB},
+	{0x35D4, 0x00},
+	{0x35D5, 0x94},
+	{0x35D6, 0x00},
+	{0x35D7, 0xFB},
+	{0x35D8, 0x00},
+	{0x35D9, 0x94},
+	{0x35DA, 0x00},
+	{0x35DB, 0xFB},
+	{0x35DC, 0x00},
+	{0x35DD, 0x94},
+	{0x35DE, 0x00},
+	{0x35DF, 0xFB},
+	{0x35E0, 0x00},
+	{0x35E1, 0x94},
+	{0x35E6, 0x18},/* FIDDLEDARKCAL*/
+	{0x35E7, 0x2F},
+	{0x35E8, 0x03},/* STOREDISTANCEATSTOPSTREAMING*/
+	{0x35E9, 0x93},
+	{0x35EA, 0x18},/* BRUCEFIX*/
+	{0x35EB, 0x99},
+	{0x35EC, 0x00},/* FIXDATAXFERSTATUSREG*/
+	{0x35ED, 0xA3},
+	{0x35EE, 0x21},/* FOCUSDISTANCEUPDATE*/
+	{0x35EF, 0x5B},
+	{0x35F0, 0x0E},/* SKIPEDOFRESET*/
+	{0x35F1, 0x74},
+	{0x35F2, 0x04},
+	{0x35F3, 0x64},
+	{0x35F4, 0x04},
+	{0x35F5, 0x65},
+	{0x35F6, 0x04},
+	{0x35F7, 0x7B},
+	{0x35F8, 0x04},
+	{0x35F9, 0x7C},
+	{0x35FA, 0x04},
+	{0x35FB, 0xDD},
+	{0x35FC, 0x04},
+	{0x35FD, 0xDE},
+	{0x35FE, 0x04},
+	{0x35FF, 0xEF},
+	{0x3600, 0x04},
+	{0x3601, 0xF0},
+	/*Jump/Data:*/
+	{0x35C2, 0x3F},/* Jump Reg*/
+	{0x35C3, 0xFF},/* Jump Reg*/
+	{0x35C4, 0x3F},/* Data Reg*/
+	{0x35C5, 0xC0},/* Data Reg*/
+	{0x35C0, 0x01},/* Enable*/
+
+};
+
+static struct vx6953_i2c_reg_conf cut3_cali_data[] = {
+		{0x360A, 0x07 },
+		{0x3530, 0x07 },
+		{0x35B5, 0x00 },
+		{0x35BC, 0x00 },
+		{0xAFF8, 0x00 },
+		{0xAFF9, 0x01 },
+		{0xF800, 0x90 },
+		{0xF801, 0x30 },
+		{0xF802, 0x31 },
+		{0xF803, 0xe0 },
+		{0xF804, 0xf5 },
+		{0xF805, 0x7d },
+		{0xF806, 0xb4 },
+		{0xF807, 0x01 },
+		{0xF808, 0x06 },
+		{0xF809, 0x75 },
+		{0xF80A, 0x7d },
+		{0xF80B, 0x03 },
+		{0xF80C, 0x74 },
+		{0xF80D, 0x03 },
+		{0xF80E, 0xf0 },
+		{0xF80F, 0x90 },
+		{0xF810, 0x30 },
+		{0xF811, 0x04 },
+		{0xF812, 0x74 },
+		{0xF813, 0x33 },
+		{0xF814, 0xf0 },
+		{0xF815, 0x90 },
+		{0xF816, 0x30 },
+		{0xF817, 0x06 },
+		{0xF818, 0xe4 },
+		{0xF819, 0xf0 },
+		{0xF81A, 0xa3 },
+		{0xF81B, 0x74 },
+		{0xF81C, 0x08 },
+		{0xF81D, 0xf0 },
+		{0xF81E, 0x90 },
+		{0xF81F, 0x30 },
+		{0xF820, 0x10 },
+		{0xF821, 0xe4 },
+		{0xF822, 0xf0 },
+		{0xF823, 0xa3 },
+		{0xF824, 0xf0 },
+		{0xF825, 0x90 },
+		{0xF826, 0x30 },
+		{0xF827, 0x16 },
+		{0xF828, 0x74 },
+		{0xF829, 0x1e },
+		{0xF82A, 0xf0 },
+		{0xF82B, 0x90 },
+		{0xF82C, 0x30 },
+		{0xF82D, 0x1a },
+		{0xF82E, 0x74 },
+		{0xF82F, 0x6a },
+		{0xF830, 0xf0 },
+		{0xF831, 0x90 },
+		{0xF832, 0x30 },
+		{0xF833, 0x30 },
+		{0xF834, 0x74 },
+		{0xF835, 0x08 },
+		{0xF836, 0xf0 },
+		{0xF837, 0x90 },
+		{0xF838, 0x30 },
+		{0xF839, 0x36 },
+		{0xF83A, 0x74 },
+		{0xF83B, 0x2c },
+		{0xF83C, 0xf0 },
+		{0xF83D, 0x90 },
+		{0xF83E, 0x30 },
+		{0xF83F, 0x41 },
+		{0xF840, 0xe4 },
+		{0xF841, 0xf0 },
+		{0xF842, 0xa3 },
+		{0xF843, 0x74 },
+		{0xF844, 0x24 },
+		{0xF845, 0xf0 },
+		{0xF846, 0x90 },
+		{0xF847, 0x30 },
+		{0xF848, 0x45 },
+		{0xF849, 0x74 },
+		{0xF84A, 0x81 },
+		{0xF84B, 0xf0 },
+		{0xF84C, 0x90 },
+		{0xF84D, 0x30 },
+		{0xF84E, 0x98 },
+		{0xF84F, 0x74 },
+		{0xF850, 0x01 },
+		{0xF851, 0xf0 },
+		{0xF852, 0x90 },
+		{0xF853, 0x30 },
+		{0xF854, 0x9d },
+		{0xF855, 0x74 },
+		{0xF856, 0x05 },
+		{0xF857, 0xf0 },
+		{0xF858, 0xe5 },
+		{0xF859, 0x7d },
+		{0xF85A, 0x70 },
+		{0xF85B, 0x22 },
+		{0xF85C, 0x90 },
+		{0xF85D, 0x02 },
+		{0xF85E, 0x00 },
+		{0xF85F, 0x74 },
+		{0xF860, 0x02 },
+		{0xF861, 0xf0 },
+		{0xF862, 0xa3 },
+		{0xF863, 0x74 },
+		{0xF864, 0x54 },
+		{0xF865, 0xf0 },
+		{0xF866, 0x90 },
+		{0xF867, 0x30 },
+		{0xF868, 0x05 },
+		{0xF869, 0x74 },
+		{0xF86A, 0x01 },
+		{0xF86B, 0xf0 },
+		{0xF86C, 0x90 },
+		{0xF86D, 0x30 },
+		{0xF86E, 0x1b },
+		{0xF86F, 0x74 },
+		{0xF870, 0x29 },
+		{0xF871, 0xf0 },
+		{0xF872, 0x90 },
+		{0xF873, 0x30 },
+		{0xF874, 0x30 },
+		{0xF875, 0xe4 },
+		{0xF876, 0xf0 },
+		{0xF877, 0x90 },
+		{0xF878, 0x30 },
+		{0xF879, 0x35 },
+		{0xF87A, 0x04 },
+		{0xF87B, 0xf0 },
+		{0xF87C, 0x80 },
+		{0xF87D, 0x69 },
+		{0xF87E, 0xe5 },
+		{0xF87F, 0x7d },
+		{0xF880, 0x64 },
+		{0xF881, 0x02 },
+		{0xF882, 0x70 },
+		{0xF883, 0x3c },
+		{0xF884, 0x90 },
+		{0xF885, 0x02 },
+		{0xF886, 0x00 },
+		{0xF887, 0x74 },
+		{0xF888, 0x04 },
+		{0xF889, 0xf0 },
+		{0xF88A, 0xa3 },
+		{0xF88B, 0x74 },
+		{0xF88C, 0x10 },
+		{0xF88D, 0xf0 },
+		{0xF88E, 0x90 },
+		{0xF88F, 0x30 },
+		{0xF890, 0x04 },
+		{0xF891, 0x74 },
+		{0xF892, 0x34 },
+		{0xF893, 0xf0 },
+		{0xF894, 0xa3 },
+		{0xF895, 0x74 },
+		{0xF896, 0x07 },
+		{0xF897, 0xf0 },
+		{0xF898, 0x90 },
+		{0xF899, 0x30 },
+		{0xF89A, 0x10 },
+		{0xF89B, 0x74 },
+		{0xF89C, 0x10 },
+		{0xF89D, 0xf0 },
+		{0xF89E, 0x90 },
+		{0xF89F, 0x30 },
+		{0xF8A0, 0x16 },
+		{0xF8A1, 0x74 },
+		{0xF8A2, 0x1f },
+		{0xF8A3, 0xf0 },
+		{0xF8A4, 0x90 },
+		{0xF8A5, 0x30 },
+		{0xF8A6, 0x1a },
+		{0xF8A7, 0x74 },
+		{0xF8A8, 0x62 },
+		{0xF8A9, 0xf0 },
+		{0xF8AA, 0xa3 },
+		{0xF8AB, 0x74 },
+		{0xF8AC, 0x2a },
+		{0xF8AD, 0xf0 },
+		{0xF8AE, 0x90 },
+		{0xF8AF, 0x30 },
+		{0xF8B0, 0x35 },
+		{0xF8B1, 0x74 },
+		{0xF8B2, 0x04 },
+		{0xF8B3, 0xf0 },
+		{0xF8B4, 0x90 },
+		{0xF8B5, 0x30 },
+		{0xF8B6, 0x41 },
+		{0xF8B7, 0x74 },
+		{0xF8B8, 0x60 },
+		{0xF8B9, 0xf0 },
+		{0xF8BA, 0xa3 },
+		{0xF8BB, 0x74 },
+		{0xF8BC, 0x64 },
+		{0xF8BD, 0xf0 },
+		{0xF8BE, 0x80 },
+		{0xF8BF, 0x27 },
+		{0xF8C0, 0xe5 },
+		{0xF8C1, 0x7d },
+		{0xF8C2, 0xb4 },
+		{0xF8C3, 0x03 },
+		{0xF8C4, 0x22 },
+		{0xF8C5, 0x90 },
+		{0xF8C6, 0x02 },
+		{0xF8C7, 0x00 },
+		{0xF8C8, 0x74 },
+		{0xF8C9, 0x02 },
+		{0xF8CA, 0xf0 },
+		{0xF8CB, 0xa3 },
+		{0xF8CC, 0x74 },
+		{0xF8CD, 0x26 },
+		{0xF8CE, 0xf0 },
+		{0xF8CF, 0x90 },
+		{0xF8D0, 0x30 },
+		{0xF8D1, 0x05 },
+		{0xF8D2, 0x74 },
+		{0xF8D3, 0x03 },
+		{0xF8D4, 0xf0 },
+		{0xF8D5, 0x90 },
+		{0xF8D6, 0x30 },
+		{0xF8D7, 0x11 },
+		{0xF8D8, 0x74 },
+		{0xF8D9, 0x01 },
+		{0xF8DA, 0xf0 },
+		{0xF8DB, 0x90 },
+		{0xF8DC, 0x30 },
+		{0xF8DD, 0x1b },
+		{0xF8DE, 0x74 },
+		{0xF8DF, 0x2a },
+		{0xF8E0, 0xf0 },
+		{0xF8E1, 0x90 },
+		{0xF8E2, 0x30 },
+		{0xF8E3, 0x35 },
+		{0xF8E4, 0x74 },
+		{0xF8E5, 0x03 },
+		{0xF8E6, 0xf0 },
+		{0xF8E7, 0x90 },
+		{0xF8E8, 0x41 },
+		{0xF8E9, 0x01 },
+		{0xF8EA, 0xe0 },
+		{0xF8EB, 0xf5 },
+		{0xF8EC, 0x79 },
+		{0xF8ED, 0x90 },
+		{0xF8EE, 0x43 },
+		{0xF8EF, 0x87 },
+		{0xF8F0, 0xe0 },
+		{0xF8F1, 0xf5 },
+		{0xF8F2, 0x7a },
+		{0xF8F3, 0x90 },
+		{0xF8F4, 0x42 },
+		{0xF8F5, 0x05 },
+		{0xF8F6, 0xe0 },
+		{0xF8F7, 0xf5 },
+		{0xF8F8, 0x7b },
+		{0xF8F9, 0x22 },
+		{0xF8FA, 0x78 },
+		{0xF8FB, 0x07 },
+		{0xF8FC, 0xe6 },
+		{0xF8FD, 0xf5 },
+		{0xF8FE, 0x7c },
+		{0xF8FF, 0xe5 },
+		{0xF900, 0x7c },
+		{0xF901, 0x60 },
+		{0xF902, 0x1e },
+		{0xF903, 0x90 },
+		{0xF904, 0x43 },
+		{0xF905, 0x83 },
+		{0xF906, 0xe0 },
+		{0xF907, 0xb4 },
+		{0xF908, 0x01 },
+		{0xF909, 0x17 },
+		{0xF90A, 0x90 },
+		{0xF90B, 0x43 },
+		{0xF90C, 0x87 },
+		{0xF90D, 0xe0 },
+		{0xF90E, 0xb4 },
+		{0xF90F, 0x01 },
+		{0xF910, 0x10 },
+		{0xF911, 0x15 },
+		{0xF912, 0x7c },
+		{0xF913, 0x90 },
+		{0xF914, 0x30 },
+		{0xF915, 0xa1 },
+		{0xF916, 0xe5 },
+		{0xF917, 0x7c },
+		{0xF918, 0xf0 },
+		{0xF919, 0x90 },
+		{0xF91A, 0x30 },
+		{0xF91B, 0xa0 },
+		{0xF91C, 0x74 },
+		{0xF91D, 0x01 },
+		{0xF91E, 0xf0 },
+		{0xF91F, 0x80 },
+		{0xF920, 0x05 },
+		{0xF921, 0xe4 },
+		{0xF922, 0x90 },
+		{0xF923, 0x30 },
+		{0xF924, 0xa0 },
+		{0xF925, 0xf0 },
+		{0xF926, 0x90 },
+		{0xF927, 0x41 },
+		{0xF928, 0x01 },
+		{0xF929, 0xe0 },
+		{0xF92A, 0xfc },
+		{0xF92B, 0x54 },
+		{0xF92C, 0x02 },
+		{0xF92D, 0xfe },
+		{0xF92E, 0xe5 },
+		{0xF92F, 0x79 },
+		{0xF930, 0x54 },
+		{0xF931, 0x02 },
+		{0xF932, 0xb5 },
+		{0xF933, 0x06 },
+		{0xF934, 0x0f },
+		{0xF935, 0x90 },
+		{0xF936, 0x43 },
+		{0xF937, 0x87 },
+		{0xF938, 0xe0 },
+		{0xF939, 0xb5 },
+		{0xF93A, 0x7a },
+		{0xF93B, 0x08 },
+		{0xF93C, 0x90 },
+		{0xF93D, 0x42 },
+		{0xF93E, 0x05 },
+		{0xF93F, 0xe0 },
+		{0xF940, 0x65 },
+		{0xF941, 0x7b },
+		{0xF942, 0x60 },
+		{0xF943, 0x0b },
+		{0xF944, 0x90 },
+		{0xF945, 0x30 },
+		{0xF946, 0x50 },
+		{0xF947, 0xe0 },
+		{0xF948, 0x54 },
+		{0xF949, 0xf9 },
+		{0xF94A, 0x44 },
+		{0xF94B, 0x02 },
+		{0xF94C, 0xf0 },
+		{0xF94D, 0x80 },
+		{0xF94E, 0x09 },
+		{0xF94F, 0x90 },
+		{0xF950, 0x30 },
+		{0xF951, 0x50 },
+		{0xF952, 0xe0 },
+		{0xF953, 0x54 },
+		{0xF954, 0xf9 },
+		{0xF955, 0x44 },
+		{0xF956, 0x04 },
+		{0xF957, 0xf0 },
+		{0xF958, 0x8c },
+		{0xF959, 0x79 },
+		{0xF95A, 0x90 },
+		{0xF95B, 0x43 },
+		{0xF95C, 0x87 },
+		{0xF95D, 0xe0 },
+		{0xF95E, 0xf5 },
+		{0xF95F, 0x7a },
+		{0xF960, 0x90 },
+		{0xF961, 0x42 },
+		{0xF962, 0x05 },
+		{0xF963, 0xe0 },
+		{0xF964, 0xf5 },
+		{0xF965, 0x7b },
+		{0xF966, 0x22 },
+		{0xF967, 0xc3 },
+		{0xF968, 0x90 },
+		{0xF969, 0x0b },
+		{0xF96A, 0x89 },
+		{0xF96B, 0xe0 },
+		{0xF96C, 0x94 },
+		{0xF96D, 0x1e },
+		{0xF96E, 0x90 },
+		{0xF96F, 0x0b },
+		{0xF970, 0x88 },
+		{0xF971, 0xe0 },
+		{0xF972, 0x94 },
+		{0xF973, 0x00 },
+		{0xF974, 0x50 },
+		{0xF975, 0x06 },
+		{0xF976, 0x7e },
+		{0xF977, 0x00 },
+		{0xF978, 0x7f },
+		{0xF979, 0x01 },
+		{0xF97A, 0x80 },
+		{0xF97B, 0x3d },
+		{0xF97C, 0xc3 },
+		{0xF97D, 0x90 },
+		{0xF97E, 0x0b },
+		{0xF97F, 0x89 },
+		{0xF980, 0xe0 },
+		{0xF981, 0x94 },
+		{0xF982, 0x3c },
+		{0xF983, 0x90 },
+		{0xF984, 0x0b },
+		{0xF985, 0x88 },
+		{0xF986, 0xe0 },
+		{0xF987, 0x94 },
+		{0xF988, 0x00 },
+		{0xF989, 0x50 },
+		{0xF98A, 0x06 },
+		{0xF98B, 0x7e },
+		{0xF98C, 0x00 },
+		{0xF98D, 0x7f },
+		{0xF98E, 0x02 },
+		{0xF98F, 0x80 },
+		{0xF990, 0x28 },
+		{0xF991, 0xc3 },
+		{0xF992, 0x90 },
+		{0xF993, 0x0b },
+		{0xF994, 0x89 },
+		{0xF995, 0xe0 },
+		{0xF996, 0x94 },
+		{0xF997, 0xfa },
+		{0xF998, 0x90 },
+		{0xF999, 0x0b },
+		{0xF99A, 0x88 },
+		{0xF99B, 0xe0 },
+		{0xF99C, 0x94 },
+		{0xF99D, 0x00 },
+		{0xF99E, 0x50 },
+		{0xF99F, 0x06 },
+		{0xF9A0, 0x7e },
+		{0xF9A1, 0x00 },
+		{0xF9A2, 0x7f },
+		{0xF9A3, 0x03 },
+		{0xF9A4, 0x80 },
+		{0xF9A5, 0x13 },
+		{0xF9A6, 0xc3 },
+		{0xF9A7, 0x90 },
+		{0xF9A8, 0x0b },
+		{0xF9A9, 0x88 },
+		{0xF9AA, 0xe0 },
+		{0xF9AB, 0x94 },
+		{0xF9AC, 0x80 },
+		{0xF9AD, 0x50 },
+		{0xF9AE, 0x06 },
+		{0xF9AF, 0x7e },
+		{0xF9B0, 0x00 },
+		{0xF9B1, 0x7f },
+		{0xF9B2, 0x04 },
+		{0xF9B3, 0x80 },
+		{0xF9B4, 0x04 },
+		{0xF9B5, 0xae },
+		{0xF9B6, 0x7e },
+		{0xF9B7, 0xaf },
+		{0xF9B8, 0x7f },
+		{0xF9B9, 0x90 },
+		{0xF9BA, 0xa0 },
+		{0xF9BB, 0xf8 },
+		{0xF9BC, 0xee },
+		{0xF9BD, 0xf0 },
+		{0xF9BE, 0xa3 },
+		{0xF9BF, 0xef },
+		{0xF9C0, 0xf0 },
+		{0xF9C1, 0x22 },
+		{0xF9C2, 0x90 },
+		{0xF9C3, 0x33 },
+		{0xF9C4, 0x82 },
+		{0xF9C5, 0xe0 },
+		{0xF9C6, 0xff },
+		{0xF9C7, 0x64 },
+		{0xF9C8, 0x01 },
+		{0xF9C9, 0x70 },
+		{0xF9CA, 0x30 },
+		{0xF9CB, 0xe5 },
+		{0xF9CC, 0x7f },
+		{0xF9CD, 0x64 },
+		{0xF9CE, 0x02 },
+		{0xF9CF, 0x45 },
+		{0xF9D0, 0x7e },
+		{0xF9D1, 0x70 },
+		{0xF9D2, 0x04 },
+		{0xF9D3, 0x7d },
+		{0xF9D4, 0x1e },
+		{0xF9D5, 0x80 },
+		{0xF9D6, 0x1d },
+		{0xF9D7, 0xe5 },
+		{0xF9D8, 0x7f },
+		{0xF9D9, 0x64 },
+		{0xF9DA, 0x03 },
+		{0xF9DB, 0x45 },
+		{0xF9DC, 0x7e },
+		{0xF9DD, 0x70 },
+		{0xF9DE, 0x04 },
+		{0xF9DF, 0x7d },
+		{0xF9E0, 0x3c },
+		{0xF9E1, 0x80 },
+		{0xF9E2, 0x11 },
+		{0xF9E3, 0xe5 },
+		{0xF9E4, 0x7f },
+		{0xF9E5, 0x64 },
+		{0xF9E6, 0x04 },
+		{0xF9E7, 0x45 },
+		{0xF9E8, 0x7e },
+		{0xF9E9, 0x70 },
+		{0xF9EA, 0x04 },
+		{0xF9EB, 0x7d },
+		{0xF9EC, 0xfa },
+		{0xF9ED, 0x80 },
+		{0xF9EE, 0x05 },
+		{0xF9EF, 0x90 },
+		{0xF9F0, 0x33 },
+		{0xF9F1, 0x81 },
+		{0xF9F2, 0xe0 },
+		{0xF9F3, 0xfd },
+		{0xF9F4, 0xae },
+		{0xF9F5, 0x05 },
+		{0xF9F6, 0x90 },
+		{0xF9F7, 0x33 },
+		{0xF9F8, 0x81 },
+		{0xF9F9, 0xed },
+		{0xF9FA, 0xf0 },
+		{0xF9FB, 0xef },
+		{0xF9FC, 0xb4 },
+		{0xF9FD, 0x01 },
+		{0xF9FE, 0x10 },
+		{0xF9FF, 0x90 },
+		{0xFA00, 0x01 },
+		{0xFA01, 0x00 },
+		{0xFA02, 0xe0 },
+		{0xFA03, 0x60 },
+		{0xFA04, 0x0a },
+		{0xFA05, 0x90 },
+		{0xFA06, 0xa1 },
+		{0xFA07, 0x10 },
+		{0xFA08, 0xe0 },
+		{0xFA09, 0xf5 },
+		{0xFA0A, 0x7e },
+		{0xFA0B, 0xa3 },
+		{0xFA0C, 0xe0 },
+		{0xFA0D, 0xf5 },
+		{0xFA0E, 0x7f },
+		{0xFA0F, 0x22 },
+		{0xFA10, 0x12 },
+		{0xFA11, 0x2f },
+		{0xFA12, 0x4d },
+		{0xFA13, 0x90 },
+		{0xFA14, 0x35 },
+		{0xFA15, 0x38 },
+		{0xFA16, 0xe0 },
+		{0xFA17, 0x70 },
+		{0xFA18, 0x05 },
+		{0xFA19, 0x12 },
+		{0xFA1A, 0x00 },
+		{0xFA1B, 0x0e },
+		{0xFA1C, 0x80 },
+		{0xFA1D, 0x03 },
+		{0xFA1E, 0x12 },
+		{0xFA1F, 0x07 },
+		{0xFA20, 0xc9 },
+		{0xFA21, 0x90 },
+		{0xFA22, 0x40 },
+		{0xFA23, 0x06 },
+		{0xFA24, 0xe0 },
+		{0xFA25, 0xf4 },
+		{0xFA26, 0x54 },
+		{0xFA27, 0x02 },
+		{0xFA28, 0xff },
+		{0xFA29, 0xe0 },
+		{0xFA2A, 0x54 },
+		{0xFA2B, 0x01 },
+		{0xFA2C, 0x4f },
+		{0xFA2D, 0x90 },
+		{0xFA2E, 0x31 },
+		{0xFA2F, 0x32 },
+		{0xFA30, 0xf0 },
+		{0xFA31, 0x90 },
+		{0xFA32, 0xfa },
+		{0xFA33, 0x9d },
+		{0xFA34, 0xe0 },
+		{0xFA35, 0x70 },
+		{0xFA36, 0x03 },
+		{0xFA37, 0x12 },
+		{0xFA38, 0x27 },
+		{0xFA39, 0x27 },
+		{0xFA3A, 0x02 },
+		{0xFA3B, 0x05 },
+		{0xFA3C, 0xac },
+		{0xFA3D, 0x22 },
+		{0xFA3E, 0xf0 },
+		{0xFA3F, 0xe5 },
+		{0xFA40, 0x3a },
+		{0xFA41, 0xb4 },
+		{0xFA42, 0x06 },
+		{0xFA43, 0x06 },
+		{0xFA44, 0x63 },
+		{0xFA45, 0x3e },
+		{0xFA46, 0x02 },
+		{0xFA47, 0x12 },
+		{0xFA48, 0x03 },
+		{0xFA49, 0xea },
+		{0xFA4A, 0x02 },
+		{0xFA4B, 0x17 },
+		{0xFA4C, 0x4a },
+		{0xFA4D, 0x22 },
+		{0x35C9, 0xFA },
+		{0x35CA, 0x01 },
+		{0x35CB, 0x67 },
+		{0x35CC, 0x01 },
+		{0x35CD, 0xC2 },
+		{0x35CE, 0x02 },
+		{0x35CF, 0x10 },
+		{0x35D0, 0x02 },
+		{0x35D1, 0x3E },
+		{0x35D3, 0xF6 },
+		{0x35D5, 0x07 },
+		{0x35D7, 0xA3 },
+		{0x35DB, 0x02 },
+		{0x35DD, 0x06 },
+		{0x35DF, 0x27 },
+		{0x35E6, 0x28 },
+		{0x35E7, 0x76 },
+		{0x35E8, 0x2A },
+		{0x35E9, 0x15 },
+		{0x35EA, 0x2D },
+		{0x35EB, 0x07 },
+		{0x35EC, 0x04 },
+		{0x35ED, 0x43 },
+		{0x35EE, 0x05 },
+		{0x35EF, 0xA9 },
+		{0x35F0, 0x17 },
+		{0x35F1, 0x41 },
+		{0x35F2, 0x24 },
+		{0x35F3, 0x88 },
+		{0x35F4, 0x01 },
+		{0x35F5, 0x54 },
+		{0x35F6, 0x01 },
+		{0x35F7, 0x55 },
+		{0x35F8, 0x2E },
+		{0x35F9, 0xF2 },
+		{0x35FA, 0x06 },
+		{0x35FB, 0x02 },
+		{0x35FC, 0x06 },
+		{0x35FD, 0x03 },
+		{0x35FE, 0x06 },
+		{0x35FF, 0x04 },
+		{0x3600, 0x0F },
+		{0x3601, 0x48 },
+		{0x3602, 0x0F },
+		{0x3603, 0x49 },
+		{0x3604, 0x0F },
+		{0x3605, 0x4A },
+		{0x35C2, 0xFF },
+		{0x35C3, 0xFF },
+		{0x35C4, 0xFF },
+		{0x35C5, 0xC0 },
+		{0x35C0, 0x01 },
+
+
+		{0xa098, 0x02 },
+		{0xa099, 0x87 },
+		{0xa09c, 0x00 },
+		{0xa09d, 0xc5 },
+		{0xa4ec, 0x05 },
+		{0xa4ed, 0x05 },
+		{0xa4f0, 0x04 },
+		{0xa4f1, 0x04 },
+		{0xa4f4, 0x04 },
+		{0xa4f5, 0x05 },
+		{0xa4f8, 0x05 },
+		{0xa4f9, 0x07 },
+		{0xa4fc, 0x07 },
+		{0xa4fd, 0x07 },
+		{0xa500, 0x07 },
+		{0xa501, 0x07 },
+		{0xa504, 0x08 },
+		{0xa505, 0x08 },
+		{0xa518, 0x01 },
+		{0xa519, 0x02 },
+		{0xa51c, 0x01 },
+		{0xa51d, 0x00 },
+		{0xa534, 0x00 },
+		{0xa535, 0x04 },
+		{0xa538, 0x04 },
+		{0xa539, 0x03 },
+		{0xa53c, 0x05 },
+		{0xa53d, 0x07 },
+		{0xa540, 0x07 },
+		{0xa541, 0x06 },
+		{0xa544, 0x07 },
+		{0xa545, 0x06 },
+		{0xa548, 0x05 },
+		{0xa549, 0x06 },
+		{0xa54c, 0x06 },
+		{0xa54d, 0x07 },
+		{0xa550, 0x07 },
+		{0xa551, 0x04 },
+		{0xa554, 0x04 },
+		{0xa555, 0x04 },
+		{0xa558, 0x05 },
+		{0xa559, 0x06 },
+		{0xa55c, 0x07 },
+		{0xa55d, 0x07 },
+		{0xa56c, 0x00 },
+		{0xa56d, 0x0a },
+		{0xa570, 0x08 },
+		{0xa571, 0x05 },
+		{0xa574, 0x04 },
+		{0xa575, 0x03 },
+		{0xa578, 0x04 },
+		{0xa579, 0x04 },
+		{0xa58c, 0x1f },
+		{0xa58d, 0x1b },
+		{0xa590, 0x17 },
+		{0xa591, 0x13 },
+		{0xa594, 0x10 },
+		{0xa595, 0x0d },
+		{0xa598, 0x0f },
+		{0xa599, 0x11 },
+		{0xa59c, 0x03 },
+		{0xa59d, 0x03 },
+		{0xa5a0, 0x03 },
+		{0xa5a1, 0x03 },
+		{0xa5a4, 0x03 },
+		{0xa5a5, 0x04 },
+		{0xa5a8, 0x05 },
+		{0xa5a9, 0x00 },
+		{0xa5ac, 0x00 },
+		{0xa5ad, 0x00 },
+		{0xa5b0, 0x00 },
+		{0xa5b1, 0x00 },
+		{0xa5b4, 0x00 },
+		{0xa5b5, 0x00 },
+		{0xa5c4, 0x1f },
+		{0xa5c5, 0x13 },
+		{0xa5c8, 0x14 },
+		{0xa5c9, 0x14 },
+		{0xa5cc, 0x14 },
+		{0xa5cd, 0x13 },
+		{0xa5d0, 0x17 },
+		{0xa5d1, 0x1a },
+		{0xa5f4, 0x05 },
+		{0xa5f5, 0x05 },
+		{0xa5f8, 0x05 },
+		{0xa5f9, 0x06 },
+		{0xa5fc, 0x06 },
+		{0xa5fd, 0x06 },
+		{0xa600, 0x06 },
+		{0xa601, 0x06 },
+		{0xa608, 0x07 },
+		{0xa609, 0x08 },
+		{0xa60c, 0x08 },
+		{0xa60d, 0x07 },
+		{0xa63c, 0x00 },
+		{0xa63d, 0x02 },
+		{0xa640, 0x02 },
+		{0xa641, 0x02 },
+		{0xa644, 0x02 },
+		{0xa645, 0x02 },
+		{0xa648, 0x03 },
+		{0xa649, 0x04 },
+		{0xa64c, 0x0a },
+		{0xa64d, 0x09 },
+		{0xa650, 0x08 },
+		{0xa651, 0x09 },
+		{0xa654, 0x09 },
+		{0xa655, 0x0a },
+		{0xa658, 0x0a },
+		{0xa659, 0x0a },
+		{0xa65c, 0x0a },
+		{0xa65d, 0x09 },
+		{0xa660, 0x09 },
+		{0xa661, 0x09 },
+		{0xa664, 0x09 },
+		{0xa665, 0x08 },
+		{0xa680, 0x01 },
+		{0xa681, 0x02 },
+		{0xa694, 0x1f },
+		{0xa695, 0x10 },
+		{0xa698, 0x0e },
+		{0xa699, 0x0c },
+		{0xa69c, 0x0d },
+		{0xa69d, 0x0d },
+		{0xa6a0, 0x0f },
+		{0xa6a1, 0x11 },
+		{0xa6a4, 0x00 },
+		{0xa6a5, 0x00 },
+		{0xa6a8, 0x00 },
+		{0xa6a9, 0x00 },
+		{0xa6ac, 0x00 },
+		{0xa6ad, 0x00 },
+		{0xa6b0, 0x00 },
+		{0xa6b1, 0x04 },
+		{0xa6b4, 0x04 },
+		{0xa6b5, 0x04 },
+		{0xa6b8, 0x04 },
+		{0xa6b9, 0x04 },
+		{0xa6bc, 0x05 },
+		{0xa6bd, 0x05 },
+		{0xa6c0, 0x1f },
+		{0xa6c1, 0x1f },
+		{0xa6c4, 0x1f },
+		{0xa6c5, 0x1f },
+		{0xa6c8, 0x1f },
+		{0xa6c9, 0x1f },
+		{0xa6cc, 0x1f },
+		{0xa6cd, 0x0b },
+		{0xa6d0, 0x0c },
+		{0xa6d1, 0x0d },
+		{0xa6d4, 0x0d },
+		{0xa6d5, 0x0d },
+		{0xa6d8, 0x11 },
+		{0xa6d9, 0x14 },
+		{0xa6fc, 0x02 },
+		{0xa6fd, 0x03 },
+		{0xa700, 0x03 },
+		{0xa701, 0x03 },
+		{0xa704, 0x03 },
+		{0xa705, 0x04 },
+		{0xa708, 0x05 },
+		{0xa709, 0x02 },
+		{0xa70c, 0x02 },
+		{0xa70d, 0x02 },
+		{0xa710, 0x03 },
+		{0xa711, 0x04 },
+		{0xa714, 0x04 },
+		{0xa715, 0x04 },
+		{0xa744, 0x00 },
+		{0xa745, 0x03 },
+		{0xa748, 0x04 },
+		{0xa749, 0x04 },
+		{0xa74c, 0x05 },
+		{0xa74d, 0x06 },
+		{0xa750, 0x07 },
+		{0xa751, 0x07 },
+		{0xa754, 0x05 },
+		{0xa755, 0x05 },
+		{0xa758, 0x05 },
+		{0xa759, 0x05 },
+		{0xa75c, 0x05 },
+		{0xa75d, 0x06 },
+		{0xa760, 0x07 },
+		{0xa761, 0x07 },
+		{0xa764, 0x06 },
+		{0xa765, 0x05 },
+		{0xa768, 0x05 },
+		{0xa769, 0x05 },
+		{0xa76c, 0x06 },
+		{0xa76d, 0x07 },
+		{0xa77c, 0x00 },
+		{0xa77d, 0x05 },
+		{0xa780, 0x05 },
+		{0xa781, 0x05 },
+		{0xa784, 0x05 },
+		{0xa785, 0x04 },
+		{0xa788, 0x05 },
+		{0xa789, 0x06 },
+		{0xa79c, 0x1f },
+		{0xa79d, 0x15 },
+		{0xa7a0, 0x13 },
+		{0xa7a1, 0x10 },
+		{0xa7a4, 0x0f },
+		{0xa7a5, 0x0d },
+		{0xa7a8, 0x11 },
+		{0xa7a9, 0x14 },
+		{0xa7ac, 0x02 },
+		{0xa7ad, 0x02 },
+		{0xa7b0, 0x02 },
+		{0xa7b1, 0x02 },
+		{0xa7b4, 0x02 },
+		{0xa7b5, 0x03 },
+		{0xa7b8, 0x03 },
+		{0xa7b9, 0x00 },
+		{0xa7bc, 0x00 },
+		{0xa7bd, 0x00 },
+		{0xa7c0, 0x00 },
+		{0xa7c1, 0x00 },
+		{0xa7c4, 0x00 },
+		{0xa7c5, 0x00 },
+		{0xa7d4, 0x1f },
+		{0xa7d5, 0x0d },
+		{0xa7d8, 0x0f },
+		{0xa7d9, 0x10 },
+		{0xa7dc, 0x10 },
+		{0xa7dd, 0x10 },
+		{0xa7e0, 0x13 },
+		{0xa7e1, 0x16 },
+		{0xa7f4, 0x00 },
+		{0xa7f5, 0x03 },
+		{0xa7f8, 0x04 },
+		{0xa7f9, 0x04 },
+		{0xa7fc, 0x04 },
+		{0xa7fd, 0x03 },
+		{0xa800, 0x03 },
+		{0xa801, 0x03 },
+		{0xa804, 0x03 },
+		{0xa805, 0x03 },
+		{0xa808, 0x03 },
+		{0xa809, 0x03 },
+		{0xa80c, 0x03 },
+		{0xa80d, 0x04 },
+		{0xa810, 0x04 },
+		{0xa811, 0x0a },
+		{0xa814, 0x0a },
+		{0xa815, 0x0a },
+		{0xa818, 0x0f },
+		{0xa819, 0x14 },
+		{0xa81c, 0x14 },
+		{0xa81d, 0x14 },
+		{0xa82c, 0x00 },
+		{0xa82d, 0x04 },
+		{0xa830, 0x02 },
+		{0xa831, 0x00 },
+		{0xa834, 0x00 },
+		{0xa835, 0x00 },
+		{0xa838, 0x00 },
+		{0xa839, 0x00 },
+		{0xa840, 0x1f },
+		{0xa841, 0x1f },
+		{0xa848, 0x1f },
+		{0xa849, 0x1f },
+		{0xa84c, 0x1f },
+		{0xa84d, 0x0c },
+		{0xa850, 0x0c },
+		{0xa851, 0x0c },
+		{0xa854, 0x0c },
+		{0xa855, 0x0c },
+		{0xa858, 0x0c },
+		{0xa859, 0x0c },
+		{0xa85c, 0x0c },
+		{0xa85d, 0x0c },
+		{0xa860, 0x0c },
+		{0xa861, 0x0c },
+		{0xa864, 0x0c },
+		{0xa865, 0x0c },
+		{0xa868, 0x0c },
+		{0xa869, 0x0c },
+		{0xa86c, 0x0c },
+		{0xa86d, 0x0c },
+		{0xa870, 0x0c },
+		{0xa871, 0x0c },
+		{0xa874, 0x0c },
+		{0xa875, 0x0c },
+		{0xa878, 0x1f },
+		{0xa879, 0x1f },
+		{0xa87c, 0x1f },
+		{0xa87d, 0x1f },
+		{0xa880, 0x1f },
+		{0xa881, 0x1f },
+		{0xa884, 0x1f },
+		{0xa885, 0x0c },
+		{0xa888, 0x0c },
+		{0xa889, 0x0c },
+		{0xa88c, 0x0c },
+		{0xa88d, 0x0c },
+		{0xa890, 0x0c },
+		{0xa891, 0x0c },
+		{0xa898, 0x1f },
+		{0xa899, 0x1f },
+		{0xa8a0, 0x1f },
+		{0xa8a1, 0x1f },
+		{0xa8a4, 0x1f },
+		{0xa8a5, 0x0c },
+		{0xa8a8, 0x0c },
+		{0xa8a9, 0x0c },
+		{0xa8ac, 0x0c },
+		{0xa8ad, 0x0c },
+		{0xa8b0, 0x0c },
+		{0xa8b1, 0x0c },
+		{0xa8b4, 0x0c },
+		{0xa8b5, 0x0c },
+		{0xa8b8, 0x0c },
+		{0xa8b9, 0x0c },
+		{0xa8bc, 0x0c },
+		{0xa8bd, 0x0c },
+		{0xa8c0, 0x0c },
+		{0xa8c1, 0x0c },
+		{0xa8c4, 0x0c },
+		{0xa8c5, 0x0c },
+		{0xa8c8, 0x0c },
+		{0xa8c9, 0x0c },
+		{0xa8cc, 0x0c },
+		{0xa8cd, 0x0c },
+		{0xa8d0, 0x1f },
+		{0xa8d1, 0x1f },
+		{0xa8d4, 0x1f },
+		{0xa8d5, 0x1f },
+		{0xa8d8, 0x1f },
+		{0xa8d9, 0x1f },
+		{0xa8dc, 0x1f },
+		{0xa8dd, 0x0c },
+		{0xa8e0, 0x0c },
+		{0xa8e1, 0x0c },
+		{0xa8e4, 0x0c },
+		{0xa8e5, 0x0c },
+		{0xa8e8, 0x0c },
+		{0xa8e9, 0x0c },
+		{0xa8f0, 0x1f },
+		{0xa8f1, 0x1f },
+		{0xa8f8, 0x1f },
+		{0xa8f9, 0x1f },
+		{0xa8fc, 0x1f },
+		{0xa8fd, 0x0c },
+		{0xa900, 0x0c },
+		{0xa901, 0x0c },
+		{0xa904, 0x0c },
+		{0xa905, 0x0c },
+		{0xa908, 0x0c },
+		{0xa909, 0x0c },
+		{0xa90c, 0x0c },
+		{0xa90d, 0x0c },
+		{0xa910, 0x0c },
+		{0xa911, 0x0c },
+		{0xa914, 0x0c },
+		{0xa915, 0x0c },
+		{0xa918, 0x0c },
+		{0xa919, 0x0c },
+		{0xa91c, 0x0c },
+		{0xa91d, 0x0c },
+		{0xa920, 0x0c },
+		{0xa921, 0x0c },
+		{0xa924, 0x0c },
+		{0xa925, 0x0c },
+		{0xa928, 0x1f },
+		{0xa929, 0x1f },
+		{0xa92c, 0x1f },
+		{0xa92d, 0x1f },
+		{0xa930, 0x1f },
+		{0xa931, 0x1f },
+		{0xa934, 0x1f },
+		{0xa935, 0x0c },
+		{0xa938, 0x0c },
+		{0xa939, 0x0c },
+		{0xa93c, 0x0c },
+		{0xa93d, 0x0c },
+		{0xa940, 0x0c },
+		{0xa941, 0x0c },
+		{0xa96c, 0x0d },
+		{0xa96d, 0x16 },
+		{0xa970, 0x19 },
+		{0xa971, 0x0e },
+		{0xa974, 0x16 },
+		{0xa975, 0x1a },
+		{0xa978, 0x0d },
+		{0xa979, 0x15 },
+		{0xa97c, 0x19 },
+		{0xa97d, 0x0d },
+		{0xa980, 0x15 },
+		{0xa981, 0x1a },
+		{0xa984, 0x0d },
+		{0xa985, 0x15 },
+		{0xa988, 0x1a },
+		{0xa989, 0x0d },
+		{0xa98c, 0x15 },
+		{0xa98d, 0x1a },
+		{0xa990, 0x0b },
+		{0xa991, 0x11 },
+		{0xa994, 0x02 },
+		{0xa995, 0x0e },
+		{0xa998, 0x16 },
+		{0xa999, 0x02 },
+		{0xa99c, 0x0c },
+		{0xa99d, 0x13 },
+		{0xa9a0, 0x02 },
+		{0xa9a1, 0x0c },
+		{0xa9a4, 0x12 },
+		{0xa9a5, 0x02 },
+		{0xa9a8, 0x0c },
+		{0xa9a9, 0x12 },
+		{0xa9ac, 0x02 },
+		{0xa9ad, 0x0c },
+		{0xa9b0, 0x12 },
+		{0xa9b1, 0x02 },
+		{0xa9b4, 0x10 },
+		{0xa9b5, 0x1e },
+		{0xa9b8, 0x0f },
+		{0xa9b9, 0x13 },
+		{0xa9bc, 0x20 },
+		{0xa9bd, 0x10 },
+		{0xa9c0, 0x11 },
+		{0xa9c1, 0x1e },
+		{0xa9c4, 0x10 },
+		{0xa9c5, 0x11 },
+		{0xa9c8, 0x1e },
+		{0xa9c9, 0x10 },
+		{0xa9cc, 0x11 },
+		{0xa9cd, 0x20 },
+		{0xa9d0, 0x10 },
+		{0xa9d1, 0x13 },
+		{0xa9d4, 0x24 },
+		{0xa9d5, 0x10 },
+		{0xa9f0, 0x02 },
+		{0xa9f1, 0x01 },
+		{0xa9f8, 0x19 },
+		{0xa9f9, 0x0b },
+		{0xa9fc, 0x0a },
+		{0xa9fd, 0x07 },
+		{0xaa00, 0x0c },
+		{0xaa01, 0x0e },
+		{0xaa08, 0x0c },
+		{0xaa09, 0x06 },
+		{0xaa0c, 0x0c },
+		{0xaa0d, 0x0a },
+		{0xaa24, 0x10 },
+		{0xaa25, 0x12 },
+		{0xaa28, 0x0b },
+		{0xaa29, 0x07 },
+		{0xaa2c, 0x10 },
+		{0xaa2d, 0x14 },
+		{0xaa34, 0x0e },
+		{0xaa35, 0x0e },
+		{0xaa38, 0x07 },
+		{0xaa39, 0x07 },
+		{0xaa3c, 0x0e },
+		{0xaa3d, 0x0c },
+		{0xaa48, 0x09 },
+		{0xaa49, 0x0c },
+		{0xaa4c, 0x0c },
+		{0xaa4d, 0x07 },
+		{0xaa54, 0x08 },
+		{0xaa55, 0x06 },
+		{0xaa58, 0x04 },
+		{0xaa59, 0x05 },
+		{0xaa5c, 0x06 },
+		{0xaa5d, 0x06 },
+		{0xaa68, 0x05 },
+		{0xaa69, 0x05 },
+		{0xaa6c, 0x04 },
+		{0xaa6d, 0x05 },
+		{0xaa74, 0x06 },
+		{0xaa75, 0x04 },
+		{0xaa78, 0x05 },
+		{0xaa79, 0x05 },
+		{0xaa7c, 0x04 },
+		{0xaa7d, 0x06 },
+		{0xac18, 0x14 },
+		{0xac19, 0x00 },
+		{0xac1c, 0x14 },
+		{0xac1d, 0x00 },
+		{0xac20, 0x14 },
+		{0xac21, 0x00 },
+		{0xac24, 0x14 },
+		{0xac25, 0x00 },
+		{0xac28, 0x14 },
+		{0xac29, 0x00 },
+		{0xac2c, 0x14 },
+		{0xac2d, 0x00 },
+		{0xac34, 0x16 },
+		{0xac35, 0x00 },
+		{0xac38, 0x16 },
+		{0xac39, 0x00 },
+		{0xac3c, 0x16 },
+		{0xac3d, 0x00 },
+		{0xac40, 0x16 },
+		{0xac41, 0x00 },
+		{0xac44, 0x16 },
+		{0xac45, 0x00 },
+		{0xac48, 0x16 },
+		{0xac49, 0x00 },
+		{0xac50, 0x1b },
+		{0xac51, 0x00 },
+		{0xac54, 0x1b },
+		{0xac55, 0x00 },
+		{0xac58, 0x1b },
+		{0xac59, 0x00 },
+		{0xac5c, 0x1b },
+		{0xac5d, 0x00 },
+		{0xac60, 0x1b },
+		{0xac61, 0x00 },
+		{0xac64, 0x1b },
+		{0xac65, 0x00 },
+		{0xac74, 0x09 },
+		{0xac75, 0x0c },
+		{0xac78, 0x0f },
+		{0xac79, 0x11 },
+		{0xac7c, 0x12 },
+		{0xac7d, 0x14 },
+		{0xac80, 0x09 },
+		{0xac81, 0x0c },
+		{0xac84, 0x0f },
+		{0xac85, 0x11 },
+		{0xac88, 0x12 },
+		{0xac89, 0x14 },
+		{0xac8c, 0x09 },
+		{0xac8d, 0x0c },
+		{0xac90, 0x0f },
+		{0xac91, 0x11 },
+		{0xac94, 0x12 },
+		{0xac95, 0x14 },
+		{0xac98, 0x09 },
+		{0xac99, 0x0c },
+		{0xac9c, 0x0f },
+		{0xac9d, 0x11 },
+		{0xaca0, 0x12 },
+		{0xaca1, 0x14 },
+		{0xaca4, 0x09 },
+		{0xaca5, 0x0c },
+		{0xaca8, 0x0f },
+		{0xaca9, 0x11 },
+		{0xacac, 0x12 },
+		{0xacad, 0x14 },
+		{0xacb0, 0x07 },
+		{0xacb1, 0x09 },
+		{0xacb4, 0x0c },
+		{0xacb5, 0x0d },
+		{0xacb8, 0x0d },
+		{0xacb9, 0x0e },
+		{0xacbc, 0x05 },
+		{0xacbd, 0x07 },
+		{0xacc0, 0x0a },
+		{0xacc1, 0x0b },
+		{0xacc4, 0x0b },
+		{0xacc5, 0x0c },
+		{0xacc8, 0x03 },
+		{0xacc9, 0x04 },
+		{0xaccc, 0x07 },
+		{0xaccd, 0x08 },
+		{0xacd0, 0x09 },
+		{0xacd1, 0x09 },
+		{0x35B5, 0x01 },
+		{0x35BC, 0x01 },
+		{0x360A, 0x02 },
+		{0xFA9B, 0x01 },
+};
+
+#define NUM_LSC_CAST_REGS      33
+
+enum LSC_Cast_t{
+	cast_H = 0,
+	cast_U30,
+	cast_CW,
+	cast_D,
+	cast_MAX
+};
+
+static short int LSC_CorrectionForCast[cast_MAX][NUM_LSC_CAST_REGS] = {
+	{-30, -20,  8, 11, -16, -26, -35, -53, -9, -10, 44, 57, -39,
+		-14, 50, -173, -38, -32, -1, 9, 39, 51, -33, -49, -28,
+		-22, 7, 11, -21, 17, -62, -56, 0},
+	{-29, -18,  6,  1,  17, -35, -77, 0, 5, -17, -6, -22, -41, -1,
+		-37, 83, -38, -32, 1, -2, 15, 25, -67, 19, -28, -22, 5,
+		2, -18, 21, -86, 0, 0},
+	{-10, -15, -4, -6,  -8,  -3, -63, 8, 25, -9, -39, -51, -9,
+		0, -21, 112, -10, -23, -7, -9, 10, 18, -11, 23, -10,
+		-15, -4, -6, -10, -3, -52, 7, 0},
+	{  5,   3, -4, -5,  -1,   3,   4, 8, 12, 3, -22, -21, 7, 17,
+		2, 35, 8, 2, -3, -2, -9, -5, 10, 4, 9, 2, -4, -5,
+		-2, 0, -6, 9, 0}
+};
+
+static unsigned short LSC_CastRegs[] = {
+	0xFB7E,			/* H   */
+	0xFB3C,			/* U30 */
+	0xFAFA,			/* CW  */
+	0xFAB8			/* D65 */
+};
+
+/*=============================================================*/
+
+static int vx6953_i2c_rxdata(unsigned short saddr,
+	unsigned char *rxdata, int length)
+{
+	struct i2c_msg msgs[] = {
+		{
+			.addr  = saddr,
+			.flags = 0,
+			.len   = 2,
+			.buf   = rxdata,
+		},
+		{
+			.addr  = saddr,
+			.flags = I2C_M_RD,
+			.len   = 2,
+			.buf   = rxdata,
+		},
+	};
+	if (i2c_transfer(vx6953_client->adapter, msgs, 2) < 0) {
+		CDBG("vx6953_i2c_rxdata failed!\n");
+		return -EIO;
+	}
+	return 0;
+}
+static int32_t vx6953_i2c_txdata(unsigned short saddr,
+				unsigned char *txdata, int length)
+{
+	struct i2c_msg msg[] = {
+		{
+			.addr = saddr,
+			.flags = 0,
+			.len = length,
+			.buf = txdata,
+		 },
+	};
+	if (i2c_transfer(vx6953_client->adapter, msg, 1) < 0) {
+		CDBG("vx6953_i2c_txdata faild 0x%x\n", vx6953_client->addr);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+
+static int32_t vx6953_i2c_read(unsigned short raddr,
+	unsigned short *rdata, int rlen)
+{
+	int32_t rc = 0;
+	unsigned char buf[2];
+	if (!rdata)
+		return -EIO;
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (raddr & 0xFF00) >> 8;
+	buf[1] = (raddr & 0x00FF);
+	rc = vx6953_i2c_rxdata(vx6953_client->addr>>1, buf, rlen);
+	if (rc < 0) {
+		CDBG("vx6953_i2c_read 0x%x failed!\n", raddr);
+		return rc;
+	}
+	*rdata = (rlen == 2 ? buf[0] << 8 | buf[1] : buf[0]);
+	return rc;
+}
+static int32_t vx6953_i2c_write_b_sensor(unsigned short waddr, uint8_t bdata)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[3];
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00) >> 8;
+	buf[1] = (waddr & 0x00FF);
+	buf[2] = bdata;
+	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
+	rc = vx6953_i2c_txdata(vx6953_client->addr>>1, buf, 3);
+	if (rc < 0) {
+		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
+			waddr, bdata);
+	}
+	return rc;
+}
+static int32_t vx6953_i2c_write_w_sensor(unsigned short waddr, uint16_t wdata)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[4];
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00) >> 8;
+	buf[1] = (waddr & 0x00FF);
+	buf[2] = (wdata & 0xFF00) >> 8;
+	buf[3] = (wdata & 0x00FF);
+	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, wdata);
+	rc = vx6953_i2c_txdata(vx6953_client->addr>>1, buf, 4);
+	if (rc < 0) {
+		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
+			waddr, wdata);
+	}
+	return rc;
+}
+static int32_t vx6953_i2c_write_seq_sensor(unsigned short waddr,
+	uint8_t *bdata, uint16_t len)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[len+2];
+	int i;
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00) >> 8;
+	buf[1] = (waddr & 0x00FF);
+	for (i = 2; i < len+2; i++)
+		buf[i] = *bdata++;
+	rc = vx6953_i2c_txdata(vx6953_client->addr>>1, buf, len+2);
+	if (rc < 0) {
+		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
+			 waddr, bdata[0]);
+	}
+	return rc;
+}
+
+static int32_t vx6953_i2c_write_w_table(struct vx6953_i2c_reg_conf const
+					 *reg_conf_tbl, int num)
+{
+	int i;
+	int32_t rc = -EIO;
+	for (i = 0; i < num; i++) {
+		rc = vx6953_i2c_write_b_sensor(reg_conf_tbl->waddr,
+			reg_conf_tbl->wdata);
+		if (rc < 0)
+			break;
+		reg_conf_tbl++;
+	}
+	return rc;
+}
+
+static void vx6953_get_pict_fps(uint16_t fps, uint16_t *pfps)
+{
+	/* input fps is preview fps in Q8 format */
+	uint16_t preview_frame_length_lines, snapshot_frame_length_lines;
+	uint16_t preview_line_length_pck, snapshot_line_length_pck;
+	uint32_t divider, d1, d2;
+	/* Total frame_length_lines and line_length_pck for preview */
+	preview_frame_length_lines = VX6953_QTR_SIZE_HEIGHT +
+		VX6953_VER_QTR_BLK_LINES;
+	preview_line_length_pck = VX6953_QTR_SIZE_WIDTH +
+		VX6953_HRZ_QTR_BLK_PIXELS;
+	/* Total frame_length_lines and line_length_pck for snapshot */
+	snapshot_frame_length_lines = VX6953_FULL_SIZE_HEIGHT +
+		VX6953_VER_FULL_BLK_LINES;
+	snapshot_line_length_pck = VX6953_FULL_SIZE_WIDTH +
+		VX6953_HRZ_FULL_BLK_PIXELS;
+	d1 = preview_frame_length_lines * 0x00000400/
+		snapshot_frame_length_lines;
+	d2 = preview_line_length_pck * 0x00000400/
+		snapshot_line_length_pck;
+	divider = d1 * d2 / 0x400;
+	/*Verify PCLK settings and frame sizes.*/
+	*pfps = (uint16_t) (fps * divider / 0x400);
+	/* 2 is the ratio of no.of snapshot channels
+	to number of preview channels */
+
+}
+
+static uint16_t vx6953_get_prev_lines_pf(void)
+{
+	if (vx6953_ctrl->prev_res == QTR_SIZE)
+		return VX6953_QTR_SIZE_HEIGHT + VX6953_VER_QTR_BLK_LINES;
+	else
+		return VX6953_FULL_SIZE_HEIGHT + VX6953_VER_FULL_BLK_LINES;
+
+}
+
+static uint16_t vx6953_get_prev_pixels_pl(void)
+{
+	if (vx6953_ctrl->prev_res == QTR_SIZE)
+		return VX6953_QTR_SIZE_WIDTH + VX6953_HRZ_QTR_BLK_PIXELS;
+	else
+		return VX6953_FULL_SIZE_WIDTH + VX6953_HRZ_FULL_BLK_PIXELS;
+}
+
+static uint16_t vx6953_get_pict_lines_pf(void)
+{
+		if (vx6953_ctrl->pict_res == QTR_SIZE)
+			return VX6953_QTR_SIZE_HEIGHT +
+				VX6953_VER_QTR_BLK_LINES;
+		else
+			return VX6953_FULL_SIZE_HEIGHT +
+				VX6953_VER_FULL_BLK_LINES;
+}
+
+static uint16_t vx6953_get_pict_pixels_pl(void)
+{
+	if (vx6953_ctrl->pict_res == QTR_SIZE)
+		return VX6953_QTR_SIZE_WIDTH +
+			VX6953_HRZ_QTR_BLK_PIXELS;
+	else
+		return VX6953_FULL_SIZE_WIDTH +
+			VX6953_HRZ_FULL_BLK_PIXELS;
+}
+
+static uint32_t vx6953_get_pict_max_exp_lc(void)
+{
+	if (vx6953_ctrl->pict_res == QTR_SIZE)
+		return (VX6953_QTR_SIZE_HEIGHT +
+			VX6953_VER_QTR_BLK_LINES)*24;
+	else
+		return (VX6953_FULL_SIZE_HEIGHT +
+			VX6953_VER_FULL_BLK_LINES)*24;
+}
+
+static int32_t vx6953_set_fps(struct fps_cfg	*fps)
+{
+	uint16_t total_lines_per_frame;
+	int32_t rc = 0;
+	total_lines_per_frame = (uint16_t)((VX6953_QTR_SIZE_HEIGHT +
+		VX6953_VER_QTR_BLK_LINES) * vx6953_ctrl->fps_divider/0x400);
+
+	vx6953_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
+		GROUPED_PARAMETER_HOLD);
+	if (vx6953_i2c_write_b_sensor(REG_FRAME_LENGTH_LINES_HI,
+		((total_lines_per_frame & 0xFF00) >> 8)) < 0)
+		return rc;
+	if (vx6953_i2c_write_b_sensor(REG_FRAME_LENGTH_LINES_LO,
+		(total_lines_per_frame & 0x00FF)) < 0)
+		return rc;
+	vx6953_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
+		GROUPED_PARAMETER_HOLD_OFF);
+	return rc;
+}
+
+static int32_t vx6953_write_exp_gain(uint16_t gain, uint32_t line)
+{
+	uint16_t line_length_pck, frame_length_lines;
+	uint8_t gain_hi, gain_lo;
+	uint8_t intg_time_hi, intg_time_lo;
+	uint8_t frame_length_lines_hi = 0, frame_length_lines_lo = 0;
+	int32_t rc = 0;
+	if (vx6953_ctrl->sensormode != SENSOR_SNAPSHOT_MODE) {
+		frame_length_lines = VX6953_QTR_SIZE_HEIGHT +
+		VX6953_VER_QTR_BLK_LINES;
+		line_length_pck = VX6953_QTR_SIZE_WIDTH +
+			VX6953_HRZ_QTR_BLK_PIXELS;
+		if (line > (frame_length_lines -
+			VX6953_STM5M0EDOF_OFFSET)) {
+			vx6953_ctrl->fps = (uint16_t) (30 * Q8 *
+			(frame_length_lines - VX6953_STM5M0EDOF_OFFSET)/
+			line);
+		} else {
+			vx6953_ctrl->fps = (uint16_t) (30 * Q8);
+		}
+	} else {
+		frame_length_lines = VX6953_FULL_SIZE_HEIGHT +
+				VX6953_VER_FULL_BLK_LINES;
+		line_length_pck = VX6953_FULL_SIZE_WIDTH +
+				VX6953_HRZ_FULL_BLK_PIXELS;
+	}
+
+	vx6953_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
+		GROUPED_PARAMETER_HOLD);
+	if ((line + VX6953_STM5M0EDOF_OFFSET) > MAX_FRAME_LENGTH_LINES) {
+		frame_length_lines = MAX_FRAME_LENGTH_LINES;
+		line = MAX_FRAME_LENGTH_LINES - VX6953_STM5M0EDOF_OFFSET;
+	} else if ((line + VX6953_STM5M0EDOF_OFFSET) > frame_length_lines) {
+		frame_length_lines = line + VX6953_STM5M0EDOF_OFFSET;
+		line = frame_length_lines;
+	}
+
+	frame_length_lines_hi = (uint8_t) ((frame_length_lines &
+		0xFF00) >> 8);
+	frame_length_lines_lo = (uint8_t) (frame_length_lines &
+		0x00FF);
+	vx6953_i2c_write_b_sensor(REG_FRAME_LENGTH_LINES_HI,
+		frame_length_lines_hi);
+	vx6953_i2c_write_b_sensor(REG_FRAME_LENGTH_LINES_LO,
+		frame_length_lines_lo);
+
+	/* update analogue gain registers */
+	gain_hi = (uint8_t) ((gain & 0xFF00) >> 8);
+	gain_lo = (uint8_t) (gain & 0x00FF);
+	vx6953_i2c_write_b_sensor(REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
+		gain_lo);
+	vx6953_i2c_write_b_sensor(REG_DIGITAL_GAIN_GREEN_R_LO, gain_hi);
+	vx6953_i2c_write_b_sensor(REG_DIGITAL_GAIN_RED_LO, gain_hi);
+	vx6953_i2c_write_b_sensor(REG_DIGITAL_GAIN_BLUE_LO, gain_hi);
+	vx6953_i2c_write_b_sensor(REG_DIGITAL_GAIN_GREEN_B_LO, gain_hi);
+	CDBG("%s, gain_hi 0x%x, gain_lo 0x%x\n", __func__,
+		gain_hi, gain_lo);
+	/* update line count registers */
+	intg_time_hi = (uint8_t) (((uint16_t)line & 0xFF00) >> 8);
+	intg_time_lo = (uint8_t) ((uint16_t)line & 0x00FF);
+	vx6953_i2c_write_b_sensor(REG_COARSE_INTEGRATION_TIME_HI,
+		intg_time_hi);
+	vx6953_i2c_write_b_sensor(REG_COARSE_INTEGRATION_TIME_LO,
+		intg_time_lo);
+	vx6953_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
+		GROUPED_PARAMETER_HOLD_OFF);
+
+	return rc;
+}
+
+static int32_t vx6953_set_pict_exp_gain(uint16_t gain, uint32_t line)
+{
+	int32_t rc = 0;
+	rc = vx6953_write_exp_gain(gain, line);
+	return rc;
+} /* endof vx6953_set_pict_exp_gain*/
+
+static int32_t vx6953_move_focus(int direction,
+	int32_t num_steps)
+{
+	return 0;
+}
+
+
+static int32_t vx6953_set_default_focus(uint8_t af_step)
+{
+	return 0;
+}
+
+static int32_t vx6953_test(enum vx6953_test_mode_t mo)
+{
+	int32_t rc = 0;
+	if (mo == TEST_OFF)
+		return rc;
+	else {
+		/* REG_0x30D8[4] is TESBYPEN: 0: Normal Operation,
+		1: Bypass Signal Processing
+		REG_0x30D8[5] is EBDMASK: 0:
+		Output Embedded data, 1: No output embedded data */
+		if (vx6953_i2c_write_b_sensor(REG_TEST_PATTERN_MODE,
+			(uint8_t) mo) < 0) {
+			return rc;
+		}
+	}
+	return rc;
+}
+
+static int vx6953_enable_edof(enum edof_mode_t edof_mode)
+{
+	int rc = 0;
+	if (edof_mode == VX6953_EDOF_ESTIMATION) {
+		/* EDof Estimation mode for preview */
+		if (vx6953_i2c_write_b_sensor(REG_0x0b80, 0x02) < 0)
+			return rc;
+		CDBG("VX6953_EDOF_ESTIMATION");
+	} else if (edof_mode == VX6953_EDOF_APPLICATION) {
+		/* EDof Application mode for Capture */
+		if (vx6953_i2c_write_b_sensor(REG_0x0b80, 0x01) < 0)
+			return rc;
+		CDBG("VX6953_EDOF_APPLICATION");
+	} else {
+		/* EDOF disabled */
+		if (vx6953_i2c_write_b_sensor(REG_0x0b80, 0x00) < 0)
+			return rc;
+		CDBG("VX6953_EDOF_DISABLE");
+	}
+	return rc;
+}
+
+static int32_t vx6953_patch_for_cut2(void)
+{
+	int32_t rc = 0;
+	rc = vx6953_i2c_write_w_table(patch_tbl_cut2,
+		ARRAY_SIZE(patch_tbl_cut2));
+	if (rc < 0)
+		return rc;
+
+	return rc;
+}
+
+static int32_t vx6953_lsc_patch(void)
+{
+	int32_t rc = 0;
+	int i, j;
+	short int  v;
+	unsigned short version = 0;
+	unsigned short LSC_Raw[NUM_LSC_CAST_REGS];
+	unsigned short LSC_Fixed[NUM_LSC_CAST_REGS];
+
+	vx6953_i2c_read(0x10, &version, 1);
+	CDBG("Cut 3 Version %d\n", version);
+	if (version != 1)
+		return 0;
+
+	vx6953_i2c_write_b_sensor(0x3640, 0x00);
+	for (j = cast_H; j < cast_MAX; j++) {
+		for (i = 0; i < NUM_LSC_CAST_REGS; i++) {
+			rc = vx6953_i2c_read(LSC_CastRegs[cast_D]+(2*i),
+								&LSC_Raw[i], 2);
+			if (rc < 0)
+				return rc;
+			v = LSC_Raw[i];
+			v +=  LSC_CorrectionForCast[j][i];
+			LSC_Fixed[i] = (unsigned short) v;
+		}
+		for (i = 0; i < NUM_LSC_CAST_REGS; i++) {
+			rc = vx6953_i2c_write_w_sensor(LSC_CastRegs[j]+(2*i),
+								LSC_Fixed[i]);
+			if (rc < 0)
+				return rc;
+		}
+	}
+	CDBG("vx6953_lsc_patch done\n");
+	return rc;
+}
+
+static int32_t vx6953_sensor_setting(int update_type, int rt)
+{
+
+	int32_t rc = 0;
+	unsigned short frame_cnt;
+	struct msm_camera_csi_params vx6953_csi_params;
+	if (vx6953_ctrl->sensor_type != VX6953_STM5M0EDOF_CUT_2) {
+		switch (update_type) {
+		case REG_INIT:
+		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
+			struct vx6953_i2c_reg_conf init_tbl[] = {
+				{REG_0x0112,
+					vx6953_regs.reg_pat_init[0].
+					reg_0x0112},
+				{REG_0x0113,
+					vx6953_regs.reg_pat_init[0].
+					reg_0x0113},
+				{REG_VT_PIX_CLK_DIV,
+					vx6953_regs.reg_pat_init[0].
+					vt_pix_clk_div},
+				{0x303, 0x01},
+				{0x30b, 0x01},
+				{REG_PRE_PLL_CLK_DIV,
+					vx6953_regs.reg_pat_init[0].
+					pre_pll_clk_div},
+				{REG_PLL_MULTIPLIER,
+					vx6953_regs.reg_pat_init[0].
+					pll_multiplier},
+				{REG_OP_PIX_CLK_DIV,
+					vx6953_regs.reg_pat_init[0].
+					op_pix_clk_div},
+				{REG_0x3210, 0x01},
+				{REG_0x0111,
+					vx6953_regs.reg_pat_init[0].
+					reg_0x0111},
+				{REG_0x0b00,
+					vx6953_regs.reg_pat_init[0].
+					reg_0x0b00},
+				{REG_0x0136,
+					vx6953_regs.reg_pat_init[0].
+					reg_0x0136},
+				{REG_0x0137,
+					vx6953_regs.reg_pat_init[0].
+					reg_0x0137},
+				{REG_0x0b06,
+					vx6953_regs.reg_pat_init[0].
+					reg_0x0b06},
+				{REG_0x0b07,
+					vx6953_regs.reg_pat_init[0].
+					reg_0x0b07},
+				{REG_0x0b08,
+					vx6953_regs.reg_pat_init[0].
+					reg_0x0b08},
+				{REG_0x0b09,
+					vx6953_regs.reg_pat_init[0].
+					reg_0x0b09},
+				{REG_0x0b83,
+					vx6953_regs.reg_pat_init[0].
+					reg_0x0b83},
+				{REG_0x0b84,
+					vx6953_regs.reg_pat_init[0].
+					reg_0x0b84},
+				{REG_0x0b85,
+					vx6953_regs.reg_pat_init[0].
+					reg_0x0b85},
+				{REG_0x0b88,
+					vx6953_regs.reg_pat_init[0].
+					reg_0x0b88},
+				{REG_0x0b89,
+					vx6953_regs.reg_pat_init[0].
+					reg_0x0b89},
+				{REG_0x0b8a,
+					vx6953_regs.reg_pat_init[0].
+					reg_0x0b8a},
+				{0x3393, 0x06},
+				{0x3394, 0x07},
+				{0x338d, 0x08},
+				{0x338e, 0x08},
+				{0x338f, 0x00},
+			};
+			/* reset fps_divider */
+			vx6953_ctrl->fps = 30 * Q8;
+			/* stop streaming */
+
+			count = 0;
+			CDBG("Init vx6953_sensor_setting standby\n");
+			if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
+				MODE_SELECT_STANDBY_MODE) < 0)
+				return rc;
+			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+			vx6953_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
+			GROUPED_PARAMETER_HOLD);
+
+			rc = vx6953_i2c_write_w_table(cut3_cali_data,
+				ARRAY_SIZE(cut3_cali_data));
+
+			vx6953_lsc_patch();
+
+			vx6953_i2c_write_w_sensor(0x100A, 0x07A3);
+			vx6953_i2c_write_w_sensor(0x114A, 0x002A);
+			vx6953_i2c_write_w_sensor(0x1716, 0x0204);
+			vx6953_i2c_write_w_sensor(0x1718, 0x0880);
+
+			rc = vx6953_i2c_write_w_table(&init_tbl[0],
+				ARRAY_SIZE(init_tbl));
+			if (rc < 0)
+				return rc;
+
+			msleep(10);
+
+		}
+		return rc;
+		case UPDATE_PERIODIC:
+		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
+			struct vx6953_i2c_reg_conf preview_mode_tbl[] = {
+				{0x200, 0x02},
+				{0x201, 0x26},
+				{REG_COARSE_INTEGRATION_TIME_HI,
+					vx6953_regs.reg_pat[rt].
+					coarse_integration_time_hi},
+				{REG_COARSE_INTEGRATION_TIME_LO,
+					vx6953_regs.reg_pat[rt].
+					coarse_integration_time_lo},
+				{REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
+					vx6953_regs.reg_pat[rt].
+					analogue_gain_code_global},
+				{REG_FRAME_LENGTH_LINES_HI,
+					vx6953_regs.reg_pat[rt].
+					frame_length_lines_hi},
+				{REG_FRAME_LENGTH_LINES_LO,
+					vx6953_regs.reg_pat[rt].
+					frame_length_lines_lo},
+				{REG_LINE_LENGTH_PCK_HI,
+					vx6953_regs.reg_pat[rt].
+					line_length_pck_hi},
+				{REG_LINE_LENGTH_PCK_LO,
+					vx6953_regs.reg_pat[rt].
+					line_length_pck_lo},
+				{REG_0x0b80,
+					vx6953_regs.reg_pat[rt].
+					reg_0x0b80},
+				{REG_0x0900,
+					vx6953_regs.reg_pat[rt].
+					reg_0x0900},
+				{REG_0x0901,
+					vx6953_regs.reg_pat[rt].
+					reg_0x0901},
+				{REG_0x0902,
+					vx6953_regs.reg_pat[rt].
+					reg_0x0902},
+				{REG_0x0383,
+					vx6953_regs.reg_pat[rt].
+					reg_0x0383},
+				{REG_0x0387,
+					vx6953_regs.reg_pat[rt].
+					reg_0x0387},
+				{REG_0x034c,
+					vx6953_regs.reg_pat[rt].
+					reg_0x034c},
+				{REG_0x034d,
+					vx6953_regs.reg_pat[rt].
+					reg_0x034d},
+				{REG_0x034e,
+					vx6953_regs.reg_pat[rt].
+					reg_0x034e},
+				{REG_0x034f,
+					vx6953_regs.reg_pat[rt].
+					reg_0x034f},
+				{REG_0x3640, 0x00},
+			};
+
+			struct vx6953_i2c_reg_conf snapshot_mode_tbl[] = {
+				{0x0200, 0x02},
+				{0x0201, 0x54},
+				{REG_COARSE_INTEGRATION_TIME_HI,
+					vx6953_regs.reg_pat[rt].
+					coarse_integration_time_hi},
+				{REG_COARSE_INTEGRATION_TIME_LO,
+					vx6953_regs.reg_pat[rt].
+					coarse_integration_time_lo},
+				{REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
+					vx6953_regs.reg_pat[rt].
+					analogue_gain_code_global},
+				{REG_FRAME_LENGTH_LINES_HI,
+					vx6953_regs.reg_pat[rt].
+					frame_length_lines_hi},
+				{REG_FRAME_LENGTH_LINES_LO,
+					vx6953_regs.reg_pat[rt].
+					frame_length_lines_lo},
+				{REG_LINE_LENGTH_PCK_HI,
+					vx6953_regs.reg_pat[rt].
+					line_length_pck_hi},
+				{REG_LINE_LENGTH_PCK_LO,
+					vx6953_regs.reg_pat[rt].
+					line_length_pck_lo},
+				{REG_0x0b80,
+					vx6953_regs.reg_pat[rt].
+					reg_0x0b80},
+				{REG_0x0900,
+					vx6953_regs.reg_pat[rt].
+					reg_0x0900},
+				{REG_0x0901,
+					vx6953_regs.reg_pat[rt].
+					reg_0x0901},
+				{REG_0x0902,
+					vx6953_regs.reg_pat[rt].
+					reg_0x0902},
+				{REG_0x0383,
+					vx6953_regs.reg_pat[rt].
+					reg_0x0383},
+				{REG_0x0387,
+					vx6953_regs.reg_pat[rt].
+					reg_0x0387},
+				{REG_0x034c,
+					vx6953_regs.reg_pat[rt].
+					reg_0x034c},
+				{REG_0x034d,
+					vx6953_regs.reg_pat[rt].
+					reg_0x034d},
+				{REG_0x034e,
+					vx6953_regs.reg_pat[rt].
+					reg_0x034e},
+				{REG_0x034f,
+					vx6953_regs.reg_pat[rt].
+					reg_0x034f},
+				{0x3140, 0x01},
+				{REG_0x3640, 0x00},
+			};
+			/* stop streaming */
+
+			if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
+				MODE_SELECT_STANDBY_MODE) < 0)
+				return rc;
+			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+
+			if (count == 0) {
+				vx6953_csi_params.data_format = CSI_8BIT;
+				vx6953_csi_params.lane_cnt = 1;
+				vx6953_csi_params.lane_assign = 0xe4;
+				vx6953_csi_params.dpcm_scheme = 0;
+				vx6953_csi_params.settle_cnt = 7;
+				rc = msm_camio_csi_config(&vx6953_csi_params);
+				if (rc < 0)
+					CDBG("config csi controller failed\n");
+
+				msleep(20);
+				count = 1;
+			}
+
+			vx6953_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
+			GROUPED_PARAMETER_HOLD);
+
+			if (rt == RES_PREVIEW) {
+				rc = vx6953_i2c_write_w_table(
+					&preview_mode_tbl[0],
+					ARRAY_SIZE(preview_mode_tbl));
+				if (rc < 0)
+					return rc;
+			}
+			if (rt == RES_CAPTURE) {
+				rc = vx6953_i2c_write_w_table(
+					&snapshot_mode_tbl[0],
+					ARRAY_SIZE(snapshot_mode_tbl));
+				if (rc < 0)
+					return rc;
+			}
+
+			vx6953_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
+			GROUPED_PARAMETER_HOLD_OFF);
+
+			/* Start sensor streaming */
+			if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
+				MODE_SELECT_STREAM) < 0)
+				return rc;
+			msleep(10);
+
+			if (vx6953_i2c_read(0x0005, &frame_cnt, 1) < 0)
+				return rc;
+
+			while (frame_cnt == 0xFF) {
+				if (vx6953_i2c_read(0x0005, &frame_cnt, 1) < 0)
+					return rc;
+				CDBG("frame_cnt=%d\n", frame_cnt);
+				msleep(2);
+			}
+		}
+		return rc;
+		default:
+			return rc;
+		}
+	} else {
+		switch (update_type) {
+		case REG_INIT:
+		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
+			struct vx6953_i2c_reg_conf init_tbl[] = {
+			{REG_0x0112,
+				vx6953_regs.reg_pat_init[0].reg_0x0112},
+			{REG_0x0113,
+				vx6953_regs.reg_pat_init[0].reg_0x0113},
+			{REG_VT_PIX_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				vt_pix_clk_div},
+			{REG_PRE_PLL_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				pre_pll_clk_div},
+			{REG_PLL_MULTIPLIER,
+				vx6953_regs.reg_pat_init[0].
+				pll_multiplier},
+			{REG_OP_PIX_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				op_pix_clk_div},
+			{REG_COARSE_INTEGRATION_TIME_HI,
+				vx6953_regs.reg_pat[rt].
+				coarse_integration_time_hi},
+			{REG_COARSE_INTEGRATION_TIME_LO,
+				vx6953_regs.reg_pat[rt].
+				coarse_integration_time_lo},
+			{REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
+				vx6953_regs.reg_pat[rt].
+				analogue_gain_code_global},
+			{REG_0x3030,
+				vx6953_regs.reg_pat_init[0].reg_0x3030},
+			/* 953 specific registers */
+			{REG_0x0111,
+				vx6953_regs.reg_pat_init[0].reg_0x0111},
+			{REG_0x0b00,
+				vx6953_regs.reg_pat_init[0].reg_0x0b00},
+			{REG_0x3001,
+				vx6953_regs.reg_pat_init[0].reg_0x3001},
+			{REG_0x3004,
+				vx6953_regs.reg_pat_init[0].reg_0x3004},
+			{REG_0x3007,
+				vx6953_regs.reg_pat_init[0].reg_0x3007},
+			{REG_0x3016,
+				vx6953_regs.reg_pat_init[0].reg_0x3016},
+			{REG_0x301d,
+				vx6953_regs.reg_pat_init[0].reg_0x301d},
+			{REG_0x317e,
+				vx6953_regs.reg_pat_init[0].reg_0x317e},
+			{REG_0x317f,
+				vx6953_regs.reg_pat_init[0].reg_0x317f},
+			{REG_0x3400,
+				vx6953_regs.reg_pat_init[0].reg_0x3400},
+			/* DEFCOR settings */
+			/*Single Defect Correction Weight DISABLE*/
+			{0x0b06,
+				vx6953_regs.reg_pat_init[0].reg_0x0b06},
+			/*Single_defect_correct_weight = auto*/
+			{0x0b07,
+				vx6953_regs.reg_pat_init[0].reg_0x0b07},
+			/*Dynamic couplet correction ENABLED*/
+			{0x0b08,
+				vx6953_regs.reg_pat_init[0].reg_0x0b08},
+			/*Dynamic couplet correction weight*/
+			{0x0b09,
+				vx6953_regs.reg_pat_init[0].reg_0x0b09},
+			/* Clock Setup */
+			/* Tell sensor ext clk is 24MHz*/
+			{0x0136,
+				vx6953_regs.reg_pat_init[0].reg_0x0136},
+			{0x0137,
+				vx6953_regs.reg_pat_init[0].reg_0x0137},
+			/* The white balance gains must be written
+			to the sensor every frame. */
+			/* Edof */
+			{REG_0x0b83,
+				vx6953_regs.reg_pat_init[0].reg_0x0b83},
+			{REG_0x0b84,
+				vx6953_regs.reg_pat_init[0].reg_0x0b84},
+			{0x0b85,
+				vx6953_regs.reg_pat_init[0].reg_0x0b85},
+			{0x0b88,
+				vx6953_regs.reg_pat_init[0].reg_0x0b88},
+			{0x0b89,
+				vx6953_regs.reg_pat_init[0].reg_0x0b89},
+			{REG_0x0b8a,
+				vx6953_regs.reg_pat_init[0].reg_0x0b8a},
+			/* Mode specific regieters */
+			{REG_FRAME_LENGTH_LINES_HI,
+				vx6953_regs.reg_pat[rt].
+				frame_length_lines_hi},
+			{REG_FRAME_LENGTH_LINES_LO,
+				vx6953_regs.reg_pat[rt].
+				frame_length_lines_lo},
+			{REG_LINE_LENGTH_PCK_HI,
+				vx6953_regs.reg_pat[rt].
+				line_length_pck_hi},
+			{REG_LINE_LENGTH_PCK_LO,
+				vx6953_regs.reg_pat[rt].
+				line_length_pck_lo},
+			{REG_0x3005,
+				vx6953_regs.reg_pat[rt].reg_0x3005},
+			{0x3010,
+				vx6953_regs.reg_pat[rt].reg_0x3010},
+			{REG_0x3011,
+				vx6953_regs.reg_pat[rt].reg_0x3011},
+			{REG_0x301a,
+				vx6953_regs.reg_pat[rt].reg_0x301a},
+			{REG_0x3035,
+				vx6953_regs.reg_pat[rt].reg_0x3035},
+			{REG_0x3036,
+				vx6953_regs.reg_pat[rt].reg_0x3036},
+			{REG_0x3041,
+				vx6953_regs.reg_pat[rt].reg_0x3041},
+			{0x3042,
+				vx6953_regs.reg_pat[rt].reg_0x3042},
+			{REG_0x3045,
+				vx6953_regs.reg_pat[rt].reg_0x3045},
+			/*EDOF: Estimation settings for Preview mode
+			Application settings for capture mode
+			(standard settings - Not tuned) */
+			{REG_0x0b80,
+				vx6953_regs.reg_pat[rt].reg_0x0b80},
+			{REG_0x0900,
+				vx6953_regs.reg_pat[rt].reg_0x0900},
+			{REG_0x0901,
+				vx6953_regs.reg_pat[rt].reg_0x0901},
+			{REG_0x0902,
+				vx6953_regs.reg_pat[rt].reg_0x0902},
+			{REG_0x0383,
+				vx6953_regs.reg_pat[rt].reg_0x0383},
+			{REG_0x0387,
+				vx6953_regs.reg_pat[rt].reg_0x0387},
+			/* Change output size / frame rate */
+			{REG_0x034c,
+				vx6953_regs.reg_pat[rt].reg_0x034c},
+			{REG_0x034d,
+				vx6953_regs.reg_pat[rt].reg_0x034d},
+			{REG_0x034e,
+				vx6953_regs.reg_pat[rt].reg_0x034e},
+			{REG_0x034f,
+				vx6953_regs.reg_pat[rt].reg_0x034f},
+			{REG_0x1716,
+				vx6953_regs.reg_pat[rt].reg_0x1716},
+			{REG_0x1717,
+				vx6953_regs.reg_pat[rt].reg_0x1717},
+			{REG_0x1718,
+				vx6953_regs.reg_pat[rt].reg_0x1718},
+			{REG_0x1719,
+				vx6953_regs.reg_pat[rt].reg_0x1719},
+			};
+						/* reset fps_divider */
+			vx6953_ctrl->fps = 30 * Q8;
+			/* stop streaming */
+
+			/* Reset everything first */
+			if (vx6953_i2c_write_b_sensor(0x103, 0x01) < 0) {
+				CDBG("S/W reset failed\n");
+				return rc;
+			} else
+				CDBG("S/W reset successful\n");
+
+			msleep(10);
+
+			CDBG("Init vx6953_sensor_setting standby\n");
+			if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
+				MODE_SELECT_STANDBY_MODE) < 0)
+				return rc;
+				/*vx6953_stm5m0edof_delay_msecs_stdby*/
+			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+			vx6953_patch_for_cut2();
+			rc = vx6953_i2c_write_w_table(&init_tbl[0],
+				ARRAY_SIZE(init_tbl));
+			if (rc < 0)
+				return rc;
+				msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+		}
+	return rc;
+	case UPDATE_PERIODIC:
+		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
+			struct vx6953_i2c_reg_conf init_mode_tbl[] =  {
+			{REG_0x0112,
+				vx6953_regs.reg_pat_init[0].reg_0x0112},
+			{REG_0x0113,
+				vx6953_regs.reg_pat_init[0].reg_0x0113},
+			{REG_VT_PIX_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				vt_pix_clk_div},
+			{REG_PRE_PLL_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				pre_pll_clk_div},
+			{REG_PLL_MULTIPLIER,
+				vx6953_regs.reg_pat_init[0].
+				pll_multiplier},
+			{REG_OP_PIX_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				op_pix_clk_div},
+			{REG_COARSE_INTEGRATION_TIME_HI,
+				vx6953_regs.reg_pat[rt].
+				coarse_integration_time_hi},
+			{REG_COARSE_INTEGRATION_TIME_LO,
+				vx6953_regs.reg_pat[rt].
+				coarse_integration_time_lo},
+			{REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
+				vx6953_regs.reg_pat[rt].
+				analogue_gain_code_global},
+			{REG_0x3030,
+				vx6953_regs.reg_pat_init[0].reg_0x3030},
+			/* 953 specific registers */
+			{REG_0x0111,
+				vx6953_regs.reg_pat_init[0].reg_0x0111},
+			{REG_0x0b00,
+				vx6953_regs.reg_pat_init[0].reg_0x0b00},
+			{REG_0x3001,
+				vx6953_regs.reg_pat_init[0].reg_0x3001},
+			{REG_0x3004,
+				vx6953_regs.reg_pat_init[0].reg_0x3004},
+			{REG_0x3007,
+				vx6953_regs.reg_pat_init[0].reg_0x3007},
+			{REG_0x3016,
+				vx6953_regs.reg_pat_init[0].reg_0x3016},
+			{REG_0x301d,
+				vx6953_regs.reg_pat_init[0].reg_0x301d},
+			{REG_0x317e,
+				vx6953_regs.reg_pat_init[0].reg_0x317e},
+			{REG_0x317f,
+				vx6953_regs.reg_pat_init[0].reg_0x317f},
+			{REG_0x3400,
+				vx6953_regs.reg_pat_init[0].reg_0x3400},
+			{0x0b06,
+				vx6953_regs.reg_pat_init[0].reg_0x0b06},
+			/*Single_defect_correct_weight = auto*/
+			{0x0b07,
+				vx6953_regs.reg_pat_init[0].reg_0x0b07},
+			/*Dynamic couplet correction ENABLED*/
+			{0x0b08,
+				vx6953_regs.reg_pat_init[0].reg_0x0b08},
+			/*Dynamic couplet correction weight*/
+			{0x0b09,
+				vx6953_regs.reg_pat_init[0].reg_0x0b09},
+			/* Clock Setup */
+			/* Tell sensor ext clk is 24MHz*/
+			{0x0136,
+				vx6953_regs.reg_pat_init[0].reg_0x0136},
+			{0x0137,
+				vx6953_regs.reg_pat_init[0].reg_0x0137},
+			/* The white balance gains must be written
+			to the sensor every frame. */
+			/* Edof */
+			{REG_0x0b83,
+				vx6953_regs.reg_pat_init[0].reg_0x0b83},
+			{REG_0x0b84,
+				vx6953_regs.reg_pat_init[0].reg_0x0b84},
+			{0x0b85,
+				vx6953_regs.reg_pat_init[0].reg_0x0b85},
+			{0x0b88,
+				vx6953_regs.reg_pat_init[0].reg_0x0b88},
+			{0x0b89,
+				vx6953_regs.reg_pat_init[0].reg_0x0b89},
+			{REG_0x0b8a,
+				vx6953_regs.reg_pat_init[0].reg_0x0b8a},
+			/* Mode specific regieters */
+			{REG_FRAME_LENGTH_LINES_HI,
+				vx6953_regs.reg_pat[rt].
+				frame_length_lines_hi},
+			{REG_FRAME_LENGTH_LINES_LO,
+				vx6953_regs.reg_pat[rt].
+				frame_length_lines_lo},
+			{REG_LINE_LENGTH_PCK_HI,
+				vx6953_regs.reg_pat[rt].
+				line_length_pck_hi},
+			{REG_LINE_LENGTH_PCK_LO,
+				vx6953_regs.reg_pat[rt].
+				line_length_pck_lo},
+			{REG_0x3005,
+				vx6953_regs.reg_pat[rt].reg_0x3005},
+			{0x3010,
+				vx6953_regs.reg_pat[rt].reg_0x3010},
+			{REG_0x3011,
+				vx6953_regs.reg_pat[rt].reg_0x3011},
+			{REG_0x301a,
+				vx6953_regs.reg_pat[rt].reg_0x301a},
+			{REG_0x3035,
+				vx6953_regs.reg_pat[rt].reg_0x3035},
+			{REG_0x3036,
+				vx6953_regs.reg_pat[rt].reg_0x3036},
+			{REG_0x3041,
+				vx6953_regs.reg_pat[rt].reg_0x3041},
+			{0x3042,
+				vx6953_regs.reg_pat[rt].reg_0x3042},
+			{REG_0x3045,
+				vx6953_regs.reg_pat[rt].reg_0x3045},
+			/*EDOF: Estimation settings for Preview mode
+			Application settings for capture mode
+			(standard settings - Not tuned) */
+			{REG_0x0b80,
+				vx6953_regs.reg_pat[rt].reg_0x0b80},
+			{REG_0x0900,
+				vx6953_regs.reg_pat[rt].reg_0x0900},
+			{REG_0x0901,
+				vx6953_regs.reg_pat[rt].reg_0x0901},
+			{REG_0x0902,
+				vx6953_regs.reg_pat[rt].reg_0x0902},
+			{REG_0x0383,
+				vx6953_regs.reg_pat[rt].reg_0x0383},
+			{REG_0x0387,
+				vx6953_regs.reg_pat[rt].reg_0x0387},
+			/* Change output size / frame rate */
+			{REG_0x034c,
+				vx6953_regs.reg_pat[rt].reg_0x034c},
+			{REG_0x034d,
+				vx6953_regs.reg_pat[rt].reg_0x034d},
+			{REG_0x034e,
+				vx6953_regs.reg_pat[rt].reg_0x034e},
+			{REG_0x034f,
+				vx6953_regs.reg_pat[rt].reg_0x034f},
+			{REG_0x1716,
+				vx6953_regs.reg_pat[rt].reg_0x1716},
+			{REG_0x1717,
+				vx6953_regs.reg_pat[rt].reg_0x1717},
+			{REG_0x1718,
+				vx6953_regs.reg_pat[rt].reg_0x1718},
+			{REG_0x1719,
+				vx6953_regs.reg_pat[rt].reg_0x1719},
+			};
+			struct vx6953_i2c_reg_conf mode_tbl[] = {
+			{REG_0x0112,
+				vx6953_regs.reg_pat_init[0].reg_0x0112},
+			{REG_0x0113,
+				vx6953_regs.reg_pat_init[0].reg_0x0113},
+			{REG_VT_PIX_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				vt_pix_clk_div},
+			{REG_PRE_PLL_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				pre_pll_clk_div},
+			{REG_PLL_MULTIPLIER,
+				vx6953_regs.reg_pat_init[0].
+				pll_multiplier},
+			{REG_OP_PIX_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				op_pix_clk_div},
+		/* Mode specific regieters */
+			{REG_FRAME_LENGTH_LINES_HI,
+				vx6953_regs.reg_pat[rt].frame_length_lines_hi},
+			{REG_FRAME_LENGTH_LINES_LO,
+				vx6953_regs.reg_pat[rt].frame_length_lines_lo},
+			{REG_LINE_LENGTH_PCK_HI,
+				vx6953_regs.reg_pat[rt].line_length_pck_hi},
+			{REG_LINE_LENGTH_PCK_LO,
+				vx6953_regs.reg_pat[rt].line_length_pck_lo},
+			{REG_0x3005, vx6953_regs.reg_pat[rt].reg_0x3005},
+			{0x3010, vx6953_regs.reg_pat[rt].reg_0x3010},
+			{REG_0x3011, vx6953_regs.reg_pat[rt].reg_0x3011},
+			{REG_0x301a, vx6953_regs.reg_pat[rt].reg_0x301a},
+			{REG_0x3035, vx6953_regs.reg_pat[rt].reg_0x3035},
+			{REG_0x3036, vx6953_regs.reg_pat[rt].reg_0x3036},
+			{REG_0x3041, vx6953_regs.reg_pat[rt].reg_0x3041},
+			{0x3042, vx6953_regs.reg_pat[rt].reg_0x3042},
+			{REG_0x3045, vx6953_regs.reg_pat[rt].reg_0x3045},
+			/*EDOF: Estimation settings for Preview mode
+			Application settings for capture
+			mode(standard settings - Not tuned) */
+			{REG_0x0b80, vx6953_regs.reg_pat[rt].reg_0x0b80},
+			{REG_0x0900, vx6953_regs.reg_pat[rt].reg_0x0900},
+			{REG_0x0901, vx6953_regs.reg_pat[rt].reg_0x0901},
+			{REG_0x0902, vx6953_regs.reg_pat[rt].reg_0x0902},
+			{REG_0x0383, vx6953_regs.reg_pat[rt].reg_0x0383},
+			{REG_0x0387, vx6953_regs.reg_pat[rt].reg_0x0387},
+			/* Change output size / frame rate */
+			{REG_0x034c, vx6953_regs.reg_pat[rt].reg_0x034c},
+			{REG_0x034d, vx6953_regs.reg_pat[rt].reg_0x034d},
+			{REG_0x034e, vx6953_regs.reg_pat[rt].reg_0x034e},
+			{REG_0x034f, vx6953_regs.reg_pat[rt].reg_0x034f},
+			/*{0x200, vx6953_regs.reg_pat[rt].reg_0x0200},
+			{0x201, vx6953_regs.reg_pat[rt].reg_0x0201},*/
+			{REG_0x1716, vx6953_regs.reg_pat[rt].reg_0x1716},
+			{REG_0x1717, vx6953_regs.reg_pat[rt].reg_0x1717},
+			{REG_0x1718, vx6953_regs.reg_pat[rt].reg_0x1718},
+			{REG_0x1719, vx6953_regs.reg_pat[rt].reg_0x1719},
+			};
+			/* stop streaming */
+			msleep(5);
+
+			/* Reset everything first */
+			if (vx6953_i2c_write_b_sensor(0x103, 0x01) < 0) {
+				CDBG("S/W reset failed\n");
+				return rc;
+			} else
+				CDBG("S/W reset successful\n");
+
+			msleep(10);
+
+			if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
+				MODE_SELECT_STANDBY_MODE) < 0)
+				return rc;
+			/*vx6953_stm5m0edof_delay_msecs_stdby*/
+			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+
+
+			vx6953_csi_params.data_format = CSI_8BIT;
+			vx6953_csi_params.lane_cnt = 1;
+			vx6953_csi_params.lane_assign = 0xe4;
+			vx6953_csi_params.dpcm_scheme = 0;
+			vx6953_csi_params.settle_cnt = 7;
+			rc = msm_camio_csi_config(&vx6953_csi_params);
+			if (rc < 0)
+				return rc;
+
+			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+
+			vx6953_patch_for_cut2();
+			rc = vx6953_i2c_write_w_table(&init_mode_tbl[0],
+				ARRAY_SIZE(init_mode_tbl));
+			if (rc < 0)
+				return rc;
+
+			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+
+			rc = vx6953_i2c_write_w_table(&mode_tbl[0],
+				ARRAY_SIZE(mode_tbl));
+			if (rc < 0)
+				return rc;
+
+			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+
+			/* Start sensor streaming */
+			if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
+				MODE_SELECT_STREAM) < 0)
+				return rc;
+			msleep(vx6953_stm5m0edof_delay_msecs_stream);
+
+			if (vx6953_i2c_read(0x0005, &frame_cnt, 1) < 0)
+				return rc;
+
+			while (frame_cnt == 0xFF) {
+				if (vx6953_i2c_read(0x0005, &frame_cnt, 1) < 0)
+					return rc;
+				CDBG("frame_cnt=%d", frame_cnt);
+				msleep(10);
+			}
+		}
+		return rc;
+	default:
+		return rc;
+	}
+	}
+	return rc;
+}
+
+
+static int32_t vx6953_video_config(int mode)
+{
+
+	int32_t	rc = 0;
+	int	rt;
+	/* change sensor resolution	if needed */
+	if (vx6953_ctrl->curr_res != vx6953_ctrl->prev_res) {
+		if (vx6953_ctrl->prev_res == QTR_SIZE) {
+			rt = RES_PREVIEW;
+			vx6953_stm5m0edof_delay_msecs_stdby	=
+				((((2 * 1000 * vx6953_ctrl->fps_divider) /
+				   vx6953_ctrl->fps) * Q8) / Q10) + 1;
+		} else {
+			rt = RES_CAPTURE;
+			vx6953_stm5m0edof_delay_msecs_stdby	=
+				((((1000 * vx6953_ctrl->fps_divider) /
+				   vx6953_ctrl->fps) * Q8) / Q10) + 1;
+		}
+		if (vx6953_sensor_setting(UPDATE_PERIODIC, rt) < 0)
+			return rc;
+	}
+	if (vx6953_ctrl->set_test) {
+		if (vx6953_test(vx6953_ctrl->set_test) < 0)
+			return	rc;
+	}
+	vx6953_ctrl->edof_mode = VX6953_EDOF_ESTIMATION;
+	rc = vx6953_enable_edof(vx6953_ctrl->edof_mode);
+	if (rc < 0)
+		return rc;
+	vx6953_ctrl->curr_res = vx6953_ctrl->prev_res;
+	vx6953_ctrl->sensormode = mode;
+	return rc;
+}
+
+static int32_t vx6953_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+	int rt;
+	/*change sensor resolution if needed */
+	if (vx6953_ctrl->curr_res != vx6953_ctrl->pict_res) {
+		if (vx6953_ctrl->pict_res == QTR_SIZE) {
+			rt = RES_PREVIEW;
+			vx6953_stm5m0edof_delay_msecs_stdby =
+				((((2 * 1000 * vx6953_ctrl->fps_divider) /
+				vx6953_ctrl->fps) * Q8) / Q10) + 1;
+		} else {
+			rt = RES_CAPTURE;
+			vx6953_stm5m0edof_delay_msecs_stdby =
+				((((1000 * vx6953_ctrl->fps_divider) /
+				vx6953_ctrl->fps) * Q8) / Q10) + 1;
+		}
+	if (vx6953_sensor_setting(UPDATE_PERIODIC, rt) < 0)
+		return rc;
+	}
+
+	vx6953_ctrl->edof_mode = VX6953_EDOF_APPLICATION;
+	if (vx6953_enable_edof(vx6953_ctrl->edof_mode) < 0)
+		return rc;
+	vx6953_ctrl->curr_res = vx6953_ctrl->pict_res;
+	vx6953_ctrl->sensormode = mode;
+	return rc;
+} /*end of vx6953_snapshot_config*/
+
+static int32_t vx6953_raw_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+	int rt;
+	/* change sensor resolution if needed */
+	if (vx6953_ctrl->curr_res != vx6953_ctrl->pict_res) {
+		if (vx6953_ctrl->pict_res == QTR_SIZE) {
+			rt = RES_PREVIEW;
+			vx6953_stm5m0edof_delay_msecs_stdby =
+				((((2 * 1000 * vx6953_ctrl->fps_divider)/
+				vx6953_ctrl->fps) * Q8) / Q10) + 1;
+		} else {
+			rt = RES_CAPTURE;
+			vx6953_stm5m0edof_delay_msecs_stdby =
+				((((1000 * vx6953_ctrl->fps_divider)/
+				vx6953_ctrl->fps) * Q8) / Q10) + 1;
+		}
+		if (vx6953_sensor_setting(UPDATE_PERIODIC, rt) < 0)
+			return rc;
+	}
+	vx6953_ctrl->edof_mode = VX6953_EDOF_APPLICATION;
+	if (vx6953_enable_edof(vx6953_ctrl->edof_mode) < 0)
+		return rc;
+	vx6953_ctrl->curr_res = vx6953_ctrl->pict_res;
+	vx6953_ctrl->sensormode = mode;
+	return rc;
+} /*end of vx6953_raw_snapshot_config*/
+static int32_t vx6953_set_sensor_mode(int mode,
+	int res)
+{
+	int32_t rc = 0;
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		rc = vx6953_video_config(mode);
+		break;
+	case SENSOR_SNAPSHOT_MODE:
+		rc = vx6953_snapshot_config(mode);
+		break;
+	case SENSOR_RAW_SNAPSHOT_MODE:
+		rc = vx6953_raw_snapshot_config(mode);
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+static int32_t vx6953_power_down(void)
+{
+	return 0;
+}
+
+
+static int vx6953_probe_init_done(const struct msm_camera_sensor_info *data)
+{
+	gpio_set_value_cansleep(data->sensor_reset, 0);
+	gpio_free(data->sensor_reset);
+	return 0;
+}
+static int vx6953_probe_init_sensor(const struct msm_camera_sensor_info *data)
+{
+	int32_t rc = 0;
+	unsigned short chipidl, chipidh;
+	CDBG("%s: %d\n", __func__, __LINE__);
+	rc = gpio_request(data->sensor_reset, "vx6953");
+	CDBG(" vx6953_probe_init_sensor \n");
+	if (!rc) {
+		CDBG("sensor_reset = %d\n", rc);
+		CDBG(" vx6953_probe_init_sensor 1\n");
+		gpio_direction_output(data->sensor_reset, 0);
+		msleep(10);
+		CDBG(" vx6953_probe_init_sensor 1\n");
+		gpio_set_value_cansleep(data->sensor_reset, 1);
+	} else {
+		CDBG(" vx6953_probe_init_sensor 2\n");
+		goto init_probe_done;
+	}
+	msleep(20);
+	CDBG(" vx6953_probe_init_sensor is called\n");
+	/* 3. Read sensor Model ID: */
+	rc = vx6953_i2c_read(0x0000, &chipidh, 1);
+	if (rc < 0) {
+		CDBG(" vx6953_probe_init_sensor 3\n");
+		goto init_probe_fail;
+	}
+	rc = vx6953_i2c_read(0x0001, &chipidl, 1);
+	if (rc < 0) {
+		CDBG(" vx6953_probe_init_sensor4\n");
+		goto init_probe_fail;
+	}
+	CDBG("vx6953 model_id = 0x%x  0x%x\n", chipidh, chipidl);
+	/* 4. Compare sensor ID to VX6953 ID: */
+	if (chipidh != 0x03 || chipidl != 0xB9) {
+		rc = -ENODEV;
+		CDBG("vx6953_probe_init_sensor fail chip id doesnot match\n");
+		goto init_probe_fail;
+	}
+	goto init_probe_done;
+init_probe_fail:
+	CDBG(" vx6953_probe_init_sensor fails\n");
+	vx6953_probe_init_done(data);
+init_probe_done:
+	CDBG(" vx6953_probe_init_sensor finishes\n");
+	return rc;
+	}
+/* camsensor_iu060f_vx6953_reset */
+int vx6953_sensor_open_init(const struct msm_camera_sensor_info *data)
+{
+	unsigned short revision_number;
+	int32_t rc = 0;
+
+	CDBG("%s: %d\n", __func__, __LINE__);
+	CDBG("Calling vx6953_sensor_open_init\n");
+	vx6953_ctrl = kzalloc(sizeof(struct vx6953_ctrl_t), GFP_KERNEL);
+	if (!vx6953_ctrl) {
+		CDBG("vx6953_init failed!\n");
+		rc = -ENOMEM;
+		goto init_done;
+	}
+	vx6953_ctrl->fps_divider = 1 * 0x00000400;
+	vx6953_ctrl->pict_fps_divider = 1 * 0x00000400;
+	vx6953_ctrl->set_test = TEST_OFF;
+	vx6953_ctrl->prev_res = QTR_SIZE;
+	vx6953_ctrl->pict_res = FULL_SIZE;
+	vx6953_ctrl->curr_res = INVALID_SIZE;
+	vx6953_ctrl->sensor_type = VX6953_STM5M0EDOF_CUT_2;
+	vx6953_ctrl->edof_mode = VX6953_EDOF_ESTIMATION;
+	if (data)
+		vx6953_ctrl->sensordata = data;
+	if (rc < 0) {
+		CDBG("Calling vx6953_sensor_open_init fail1\n");
+		return rc;
+	}
+	CDBG("%s: %d\n", __func__, __LINE__);
+	/* enable mclk first */
+	msm_camio_clk_rate_set(VX6953_STM5M0EDOF_DEFAULT_MASTER_CLK_RATE);
+	CDBG("%s: %d\n", __func__, __LINE__);
+	rc = vx6953_probe_init_sensor(data);
+	if (rc < 0) {
+		CDBG("Calling vx6953_sensor_open_init fail3\n");
+		goto init_fail;
+	}
+	if (vx6953_i2c_read(0x0002, &revision_number, 1) < 0)
+		return rc;
+		CDBG("sensor revision number major = 0x%x\n", revision_number);
+	if (vx6953_i2c_read(0x0018, &revision_number, 1) < 0)
+		return rc;
+		CDBG("sensor revision number = 0x%x\n", revision_number);
+	if (revision_number == VX6953_REVISION_NUMBER_CUT3) {
+		vx6953_ctrl->sensor_type = VX6953_STM5M0EDOF_CUT_3;
+		CDBG("VX6953 EDof Cut 3.0 sensor\n ");
+	} else if (revision_number == VX6953_REVISION_NUMBER_CUT2) {
+		vx6953_ctrl->sensor_type = VX6953_STM5M0EDOF_CUT_2;
+		CDBG("VX6953 EDof Cut 2.0 sensor\n ");
+	} else {/* Cut1.0 reads 0x00 for register 0x0018*/
+		vx6953_ctrl->sensor_type = VX6953_STM5M0EDOF_CUT_1;
+		CDBG("VX6953 EDof Cut 1.0 sensor\n ");
+	}
+	if (vx6953_ctrl->prev_res == QTR_SIZE) {
+		if (vx6953_sensor_setting(REG_INIT, RES_PREVIEW) < 0)
+			return rc;
+	} else {
+		if (vx6953_sensor_setting(REG_INIT, RES_CAPTURE) < 0)
+			return rc;
+	}
+	vx6953_ctrl->fps = 30*Q8;
+	if (rc < 0)
+		goto init_fail;
+	else
+		goto init_done;
+init_fail:
+	CDBG("init_fail\n");
+	vx6953_probe_init_done(data);
+	kfree(vx6953_ctrl);
+init_done:
+	CDBG("init_done\n");
+	return rc;
+} /*endof vx6953_sensor_open_init*/
+
+static int vx6953_init_client(struct i2c_client *client)
+{
+	/* Initialize the MSM_CAMI2C Chip */
+	init_waitqueue_head(&vx6953_wait_queue);
+	return 0;
+}
+
+static const struct i2c_device_id vx6953_i2c_id[] = {
+	{"vx6953", 0},
+	{ }
+};
+
+static int vx6953_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+	CDBG("vx6953_probe called!\n");
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		CDBG("i2c_check_functionality failed\n");
+		goto probe_failure;
+	}
+
+	vx6953_sensorw = kzalloc(sizeof(struct vx6953_work_t), GFP_KERNEL);
+	if (!vx6953_sensorw) {
+		CDBG("kzalloc failed.\n");
+		rc = -ENOMEM;
+		goto probe_failure;
+	}
+
+	i2c_set_clientdata(client, vx6953_sensorw);
+	vx6953_init_client(client);
+	vx6953_client = client;
+
+	msleep(50);
+
+	CDBG("vx6953_probe successed! rc = %d\n", rc);
+	return 0;
+
+probe_failure:
+	CDBG("vx6953_probe failed! rc = %d\n", rc);
+	return rc;
+}
+
+static int vx6953_send_wb_info(struct wb_info_cfg *wb)
+{
+	unsigned short read_data;
+	uint8_t temp[8];
+	int rc = 0;
+	int i = 0;
+
+	/* red_gain */
+	temp[2] = wb->red_gain >> 8;
+	temp[3] = wb->red_gain & 0xFF;
+
+	/* green_gain */
+	temp[0] = wb->green_gain >> 8;
+	temp[1] = wb->green_gain & 0xFF;
+	temp[6] = temp[0];
+	temp[7] = temp[1];
+
+	/* blue_gain */
+	temp[4] = wb->blue_gain >> 8;
+	temp[5] = wb->blue_gain & 0xFF;
+	rc = vx6953_i2c_write_seq_sensor(0x0B8E, &temp[0], 8);
+
+	for (i = 0; i < 6; i++) {
+		rc = vx6953_i2c_read(0x0B8E + i, &read_data, 1);
+		CDBG("%s addr 0x%x val %d \n", __func__, 0x0B8E + i, read_data);
+	}
+	rc = vx6953_i2c_read(0x0B82, &read_data, 1);
+	CDBG("%s addr 0x%x val %d \n", __func__, 0x0B82, read_data);
+	if (rc < 0)
+		return rc;
+	return rc;
+} /*end of vx6953_snapshot_config*/
+
+static int __exit vx6953_remove(struct i2c_client *client)
+{
+	struct vx6953_work_t_t *sensorw = i2c_get_clientdata(client);
+	free_irq(client->irq, sensorw);
+	vx6953_client = NULL;
+	kfree(sensorw);
+	return 0;
+}
+
+static struct i2c_driver vx6953_i2c_driver = {
+	.id_table = vx6953_i2c_id,
+	.probe  = vx6953_i2c_probe,
+	.remove = __exit_p(vx6953_i2c_remove),
+	.driver = {
+		.name = "vx6953",
+	},
+};
+
+int vx6953_sensor_config(void __user *argp)
+{
+	struct sensor_cfg_data cdata;
+	long   rc = 0;
+	if (copy_from_user(&cdata,
+		(void *)argp,
+		sizeof(struct sensor_cfg_data)))
+		return -EFAULT;
+	mutex_lock(&vx6953_mut);
+	CDBG("vx6953_sensor_config: cfgtype = %d\n",
+	cdata.cfgtype);
+		switch (cdata.cfgtype) {
+		case CFG_GET_PICT_FPS:
+			vx6953_get_pict_fps(
+				cdata.cfg.gfps.prevfps,
+				&(cdata.cfg.gfps.pictfps));
+
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_GET_PREV_L_PF:
+			cdata.cfg.prevl_pf =
+			vx6953_get_prev_lines_pf();
+
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_GET_PREV_P_PL:
+			cdata.cfg.prevp_pl =
+				vx6953_get_prev_pixels_pl();
+
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_GET_PICT_L_PF:
+			cdata.cfg.pictl_pf =
+				vx6953_get_pict_lines_pf();
+
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_GET_PICT_P_PL:
+			cdata.cfg.pictp_pl =
+				vx6953_get_pict_pixels_pl();
+
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_GET_PICT_MAX_EXP_LC:
+			cdata.cfg.pict_max_exp_lc =
+				vx6953_get_pict_max_exp_lc();
+
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_SET_FPS:
+		case CFG_SET_PICT_FPS:
+			rc = vx6953_set_fps(&(cdata.cfg.fps));
+			break;
+
+		case CFG_SET_EXP_GAIN:
+			rc =
+				vx6953_write_exp_gain(
+					cdata.cfg.exp_gain.gain,
+					cdata.cfg.exp_gain.line);
+			break;
+
+		case CFG_SET_PICT_EXP_GAIN:
+			rc =
+				vx6953_set_pict_exp_gain(
+				cdata.cfg.exp_gain.gain,
+				cdata.cfg.exp_gain.line);
+			break;
+
+		case CFG_SET_MODE:
+			rc = vx6953_set_sensor_mode(cdata.mode,
+					cdata.rs);
+			break;
+
+		case CFG_PWR_DOWN:
+			rc = vx6953_power_down();
+			break;
+
+		case CFG_MOVE_FOCUS:
+			rc =
+				vx6953_move_focus(
+				cdata.cfg.focus.dir,
+				cdata.cfg.focus.steps);
+			break;
+
+		case CFG_SET_DEFAULT_FOCUS:
+			rc =
+				vx6953_set_default_focus(
+				cdata.cfg.focus.steps);
+			break;
+
+		case CFG_SET_EFFECT:
+			rc = vx6953_set_default_focus(
+				cdata.cfg.effect);
+			break;
+
+
+		case CFG_SEND_WB_INFO:
+			rc = vx6953_send_wb_info(
+				&(cdata.cfg.wb_info));
+			break;
+
+		default:
+			rc = -EFAULT;
+			break;
+		}
+
+	mutex_unlock(&vx6953_mut);
+
+	return rc;
+}
+
+
+
+
+static int vx6953_sensor_release(void)
+{
+	int rc = -EBADF;
+	mutex_lock(&vx6953_mut);
+	vx6953_power_down();
+	gpio_direction_output(vx6953_ctrl->sensordata->sensor_reset, 0);
+	gpio_free(vx6953_ctrl->sensordata->sensor_reset);
+	kfree(vx6953_ctrl);
+	vx6953_ctrl = NULL;
+	CDBG("vx6953_release completed\n");
+	mutex_unlock(&vx6953_mut);
+
+	return rc;
+}
+
+static int vx6953_sensor_probe(const struct msm_camera_sensor_info *info,
+		struct msm_sensor_ctrl *s)
+{
+	int rc = 0;
+	rc = i2c_add_driver(&vx6953_i2c_driver);
+	if (rc < 0 || vx6953_client == NULL) {
+		rc = -ENOTSUPP;
+		goto probe_fail;
+	}
+	msm_camio_clk_rate_set(24000000);
+	rc = vx6953_probe_init_sensor(info);
+	if (rc < 0)
+		goto probe_fail;
+	s->s_init = vx6953_sensor_open_init;
+	s->s_release = vx6953_sensor_release;
+	s->s_config  = vx6953_sensor_config;
+	s->s_mount_angle  = info->sensor_platform_info->mount_angle;
+	vx6953_probe_init_done(info);
+	return rc;
+
+probe_fail:
+	CDBG("vx6953_sensor_probe: SENSOR PROBE FAILS!\n");
+	return rc;
+}
+
+static int __vx6953_probe(struct platform_device *pdev)
+{
+	return msm_camera_drv_start(pdev, vx6953_sensor_probe);
+}
+
+static struct platform_driver msm_camera_driver = {
+	.probe = __vx6953_probe,
+	.driver = {
+		.name = "msm_camera_vx6953",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init vx6953_init(void)
+{
+	return platform_driver_register(&msm_camera_driver);
+}
+
+module_init(vx6953_init);
+void vx6953_exit(void)
+{
+	i2c_del_driver(&vx6953_i2c_driver);
+}
+
+
diff --git a/drivers/media/platform/msm/camera_v1/vx6953.h b/drivers/media/platform/msm/camera_v1/vx6953.h
new file mode 100644
index 0000000..175facc
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vx6953.h
@@ -0,0 +1,136 @@
+/* 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.
+ *
+ */
+
+#ifndef VX6953_H
+#define VX6953_H
+#include <linux/types.h>
+#include <mach/board.h>
+extern struct vx6953_reg vx6953_regs;
+struct reg_struct_init {
+	uint8_t reg_0x0112;      /* 0x0112*/
+	uint8_t reg_0x0113;      /* 0x0113*/
+	uint8_t vt_pix_clk_div;  /* 0x0301*/
+	uint8_t pre_pll_clk_div; /* 0x0305*/
+	uint8_t pll_multiplier;  /* 0x0307*/
+	uint8_t op_pix_clk_div;  /* 0x0309*/
+	uint8_t reg_0x3030;      /*0x3030*/
+	uint8_t reg_0x0111;      /*0x0111*/
+	uint8_t reg_0x0b00;      /*0x0b00*/
+	uint8_t reg_0x3001;      /*0x3001*/
+	uint8_t reg_0x3004;      /*0x3004*/
+	uint8_t reg_0x3007;      /*0x3007*/
+	uint8_t reg_0x3016;      /*0x3016*/
+	uint8_t reg_0x301d;      /*0x301d*/
+	uint8_t reg_0x317e;      /*0x317E*/
+	uint8_t reg_0x317f;      /*0x317F*/
+	uint8_t reg_0x3400;      /*0x3400*/
+	uint8_t reg_0x0b06;      /*0x0b06*/
+	uint8_t reg_0x0b07;      /*0x0b07*/
+	uint8_t reg_0x0b08;      /*0x0b08*/
+	uint8_t reg_0x0b09;      /*0x0b09*/
+	uint8_t reg_0x0136;
+	uint8_t reg_0x0137;
+	/* Edof */
+	uint8_t reg_0x0b83;      /*0x0b83*/
+	uint8_t reg_0x0b84;      /*0x0b84*/
+	uint8_t reg_0x0b85;      /*0x0b85*/
+	uint8_t reg_0x0b88;      /*0x0b88*/
+	uint8_t reg_0x0b89;      /*0x0b89*/
+	uint8_t reg_0x0b8a;      /*0x0b8a*/
+	};
+struct reg_struct {
+	uint8_t coarse_integration_time_hi; /*REG_COARSE_INTEGRATION_TIME_HI*/
+	uint8_t coarse_integration_time_lo; /*REG_COARSE_INTEGRATION_TIME_LO*/
+	uint8_t analogue_gain_code_global;
+	uint8_t frame_length_lines_hi; /* 0x0340*/
+	uint8_t frame_length_lines_lo; /* 0x0341*/
+	uint8_t line_length_pck_hi;    /* 0x0342*/
+	uint8_t line_length_pck_lo;    /* 0x0343*/
+	uint8_t reg_0x3005;   /* 0x3005*/
+	uint8_t reg_0x3010;  /* 0x3010*/
+	uint8_t reg_0x3011;  /* 0x3011*/
+	uint8_t reg_0x301a;  /* 0x301a*/
+	uint8_t reg_0x3035;  /* 0x3035*/
+	uint8_t reg_0x3036;   /* 0x3036*/
+	uint8_t reg_0x3041;  /*0x3041*/
+	uint8_t reg_0x3042;  /*0x3042*/
+	uint8_t reg_0x3045;  /*0x3045*/
+	uint8_t reg_0x0b80;   /* 0x0b80*/
+	uint8_t reg_0x0900;   /*0x0900*/
+	uint8_t reg_0x0901;   /* 0x0901*/
+	uint8_t reg_0x0902;   /*0x0902*/
+	uint8_t reg_0x0383;   /*0x0383*/
+	uint8_t reg_0x0387;   /* 0x0387*/
+	uint8_t reg_0x034c;   /* 0x034c*/
+	uint8_t reg_0x034d;   /*0x034d*/
+	uint8_t reg_0x034e;   /* 0x034e*/
+	uint8_t reg_0x034f;   /* 0x034f*/
+	uint8_t reg_0x1716; /*0x1716*/
+	uint8_t reg_0x1717; /*0x1717*/
+	uint8_t reg_0x1718; /*0x1718*/
+	uint8_t reg_0x1719; /*0x1719*/
+	uint8_t reg_0x3210;/*0x3210*/
+	uint8_t reg_0x111; /*0x111*/
+	uint8_t reg_0x3410;  /*0x3410*/
+	uint8_t reg_0x3098;
+	uint8_t reg_0x309D;
+	uint8_t reg_0x0200;
+	uint8_t reg_0x0201;
+	};
+struct vx6953_i2c_reg_conf {
+	unsigned short waddr;
+	unsigned short wdata;
+};
+
+enum vx6953_test_mode_t {
+	TEST_OFF,
+	TEST_1,
+	TEST_2,
+	TEST_3
+};
+
+enum vx6953_resolution_t {
+	QTR_SIZE,
+	FULL_SIZE,
+	INVALID_SIZE
+};
+enum vx6953_setting {
+	RES_PREVIEW,
+	RES_CAPTURE
+};
+enum mt9p012_reg_update {
+	/* Sensor egisters that need to be updated during initialization */
+	REG_INIT,
+	/* Sensor egisters that needs periodic I2C writes */
+	UPDATE_PERIODIC,
+	/* All the sensor Registers will be updated */
+	UPDATE_ALL,
+	/* Not valid update */
+	UPDATE_INVALID
+};
+
+enum sensor_revision_t {
+	VX6953_STM5M0EDOF_CUT_1,
+	VX6953_STM5M0EDOF_CUT_2,
+	VX6953_STM5M0EDOF_CUT_3
+};
+enum edof_mode_t {
+	VX6953_EDOF_DISABLE,       /* 0x00 */
+	VX6953_EDOF_APPLICATION,   /* 0x01 */
+	VX6953_EDOF_ESTIMATION     /* 0x02 */
+};
+struct vx6953_reg {
+	const struct reg_struct_init  *reg_pat_init;
+	const struct reg_struct  *reg_pat;
+};
+#endif /* VX6953_H */
diff --git a/drivers/media/platform/msm/camera_v1/vx6953_reg.c b/drivers/media/platform/msm/camera_v1/vx6953_reg.c
new file mode 100644
index 0000000..eee6904
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vx6953_reg.c
@@ -0,0 +1,135 @@
+/* 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 "vx6953.h"
+const struct reg_struct_init vx6953_reg_init[1] = {
+	{
+		10,			/*REG = 0x0112 , 10 bit */
+		10,			/*REG = 0x0113*/
+		9,			/*REG = 0x0301 vt_pix_clk_div*/
+		4,		/*REG = 0x0305 pre_pll_clk_div*/
+		133,		/*REG = 0x0307 pll_multiplier*/
+		10,		/*REG = 0x0309 op_pix_clk_div*/
+		0x08,		/*REG = 0x3030*/
+		0x02,		/*REG = 0x0111*/
+		0x01,		/*REG = 0x0b00 ,lens shading off */
+		0x30,		/*REG = 0x3001*/
+		0x33,		/*REG = 0x3004*/
+		0x09,		/*REG = 0x3007*/
+		0x1F,		/*REG = 0x3016*/
+		0x03,		/*REG = 0x301d*/
+		0x11,		/*REG = 0x317E*/
+		0x09,		/*REG = 0x317F*/
+		0x38,		/*REG = 0x3400*/
+		0x00,		/*REG_0x0b06*/
+		0x80,		/*REG_0x0b07*/
+		0x01,		/*REG_0x0b08*/
+		0x4F,		/*REG_0x0b09*/
+		0x18,		/*REG_0x0136*/
+		0x00,		/*/REG_0x0137*/
+		0x20,		/*REG = 0x0b83*/
+		0x90,		/*REG = 0x0b84*/
+		0x20,		/*REG = 0x0b85*/
+		0x80,		/*REG = 0x0b88*/
+		0x00,		/*REG = 0x0b89*/
+		0x00,		/*REG = 0x0b8a*/
+	}
+};
+const struct reg_struct vx6953_reg_pat[2] = {
+	{/* Preview */
+		0x03,	/*REG = 0x0202 coarse integration_time_hi*/
+		0xd0,	/*REG = 0x0203 coarse_integration_time_lo*/
+		0xc0,	/*REG = 0x0205 analogue_gain_code_global*/
+		0x03,	/*REG = 0x0340 frame_length_lines_hi*/
+		0xf0,	/*REG = 0x0341 frame_length_lines_lo*/
+		0x0b,	/*REG = 0x0342  line_length_pck_hi*/
+		0x74,	/*REG = 0x0343  line_length_pck_lo*/
+		0x03,	/*REG = 0x3005*/
+		0x00,	/*REG = 0x3010*/
+		0x01,	/*REG = 0x3011*/
+		0x6a,	/*REG = 0x301a*/
+		0x03,	/*REG = 0x3035*/
+		0x2c,	/*REG = 0x3036*/
+		0x00,	/*REG = 0x3041*/
+		0x24,	/*REG = 0x3042*/
+		0x81,	/*REG = 0x3045*/
+		0x02,	/*REG = 0x0b80 edof estimate*/
+		0x01,	/*REG = 0x0900*/
+		0x22,	/*REG = 0x0901*/
+		0x04,	/*REG = 0x0902*/
+		0x03,	/*REG = 0x0383*/
+		0x03,	/*REG = 0x0387*/
+		0x05,	/*REG = 0x034c*/
+		0x18,	/*REG = 0x034d*/
+		0x03,	/*REG = 0x034e*/
+		0xd4,	/*REG = 0x034f*/
+		0x02,	/*0x1716*/
+		0x04,	/*0x1717*/
+		0x08,	/*0x1718*/
+		0x2c,	/*0x1719*/
+		0x01,   /*0x3210*/
+		0x02,   /*0x111*/
+		0x01,   /*0x3410*/
+		0x01,   /*0x3098*/
+		0x05,   /*0x309D*/
+		0x02,
+		0x04,
+	},
+	{ /* Snapshot */
+		0x07,/*REG = 0x0202 coarse_integration_time_hi*/
+		0x00,/*REG = 0x0203 coarse_integration_time_lo*/
+		0xc0,/*REG = 0x0205 analogue_gain_code_global*/
+		0x07,/*REG = 0x0340 frame_length_lines_hi*/
+		0xd0,/*REG = 0x0341 frame_length_lines_lo*/
+		0x0b,/*REG = 0x0342 line_length_pck_hi*/
+		0x8c,/*REG = 0x0343 line_length_pck_lo*/
+		0x01,/*REG = 0x3005*/
+		0x00,/*REG = 0x3010*/
+		0x00,/*REG = 0x3011*/
+		0x55,/*REG = 0x301a*/
+		0x01,/*REG = 0x3035*/
+		0x23,/*REG = 0x3036*/
+		0x00,/*REG = 0x3041*/
+		0x24,/*REG = 0x3042*/
+		0xb7,/*REG = 0x3045*/
+		0x01,/*REG = 0x0b80 edof application*/
+		0x00,/*REG = 0x0900*/
+		0x00,/*REG = 0x0901*/
+		0x00,/*REG = 0x0902*/
+		0x01,/*REG = 0x0383*/
+		0x01,/*REG = 0x0387*/
+		0x0A,/*REG = 0x034c*/
+		0x30,/*REG = 0x034d*/
+		0x07,/*REG = 0x034e*/
+		0xA8,/*REG = 0x034f*/
+		0x02,/*0x1716*/
+		0x0d,/*0x1717*/
+		0x07,/*0x1718*/
+		0x7d,/*0x1719*/
+		0x01,/*0x3210*/
+		0x02,/*0x111*/
+		0x01,/*0x3410*/
+		0x01,/*0x3098*/
+		0x05, /*0x309D*/
+		0x02,
+		0x00,
+	}
+};
+
+
+
+struct vx6953_reg vx6953_regs = {
+	.reg_pat_init = &vx6953_reg_init[0],
+	.reg_pat = &vx6953_reg_pat[0],
+};
diff --git a/drivers/media/platform/msm/camera_v1/vx6953_reg_v4l2.c b/drivers/media/platform/msm/camera_v1/vx6953_reg_v4l2.c
new file mode 100644
index 0000000..8b1c1be
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vx6953_reg_v4l2.c
@@ -0,0 +1,135 @@
+/* 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 "vx6953_v4l2.h"
+const struct reg_struct_init vx6953_reg_init[1] = {
+	{
+		10,			/*REG = 0x0112 , 10 bit */
+		10,			/*REG = 0x0113*/
+		9,			/*REG = 0x0301 vt_pix_clk_div*/
+		4,		/*REG = 0x0305 pre_pll_clk_div*/
+		133,		/*REG = 0x0307 pll_multiplier*/
+		10,		/*REG = 0x0309 op_pix_clk_div*/
+		0x08,		/*REG = 0x3030*/
+		0x02,		/*REG = 0x0111*/
+		0x01,		/*REG = 0x0b00 ,lens shading off */
+		0x30,		/*REG = 0x3001*/
+		0x33,		/*REG = 0x3004*/
+		0x09,		/*REG = 0x3007*/
+		0x1F,		/*REG = 0x3016*/
+		0x03,		/*REG = 0x301d*/
+		0x11,		/*REG = 0x317E*/
+		0x09,		/*REG = 0x317F*/
+		0x38,		/*REG = 0x3400*/
+		0x00,		/*REG_0x0b06*/
+		0x80,		/*REG_0x0b07*/
+		0x01,		/*REG_0x0b08*/
+		0x4F,		/*REG_0x0b09*/
+		0x18,		/*REG_0x0136*/
+		0x00,		/*/REG_0x0137*/
+		0x20,		/*REG = 0x0b83*/
+		0x90,		/*REG = 0x0b84*/
+		0x20,		/*REG = 0x0b85*/
+		0x80,		/*REG = 0x0b88*/
+		0x00,		/*REG = 0x0b89*/
+		0x00,		/*REG = 0x0b8a*/
+	}
+};
+const struct reg_struct vx6953_reg_pat[2] = {
+	{/* Preview */
+		0x03,	/*REG = 0x0202 coarse integration_time_hi*/
+		0xd0,	/*REG = 0x0203 coarse_integration_time_lo*/
+		0xc0,	/*REG = 0x0205 analogue_gain_code_global*/
+		0x03,	/*REG = 0x0340 frame_length_lines_hi*/
+		0xf0,	/*REG = 0x0341 frame_length_lines_lo*/
+		0x0b,	/*REG = 0x0342  line_length_pck_hi*/
+		0xa5,	/*REG = 0x0343  line_length_pck_lo*/
+		0x03,	/*REG = 0x3005*/
+		0x00,	/*REG = 0x3010*/
+		0x01,	/*REG = 0x3011*/
+		0x6a,	/*REG = 0x301a*/
+		0x03,	/*REG = 0x3035*/
+		0x2c,	/*REG = 0x3036*/
+		0x00,	/*REG = 0x3041*/
+		0x24,	/*REG = 0x3042*/
+		0x81,	/*REG = 0x3045*/
+		0x02,	/*REG = 0x0b80 edof estimate*/
+		0x01,	/*REG = 0x0900*/
+		0x22,	/*REG = 0x0901*/
+		0x04,	/*REG = 0x0902*/
+		0x03,	/*REG = 0x0383*/
+		0x03,	/*REG = 0x0387*/
+		0x05,	/*REG = 0x034c*/
+		0x18,	/*REG = 0x034d*/
+		0x03,	/*REG = 0x034e*/
+		0xd4,	/*REG = 0x034f*/
+		0x02,	/*0x1716*/
+		0x04,	/*0x1717*/
+		0x08,	/*0x1718*/
+		0x80,	/*0x1719*/
+		0x01,   /*0x3210*/
+		0x02,   /*0x111*/
+		0x01,   /*0x3410*/
+		0x01,   /*0x3098*/
+		0x05,   /*0x309D*/
+		0x02,
+		0x04,
+	},
+	{ /* Snapshot */
+		0x07,/*REG = 0x0202 coarse_integration_time_hi*/
+		0x00,/*REG = 0x0203 coarse_integration_time_lo*/
+		0xc0,/*REG = 0x0205 analogue_gain_code_global*/
+		0x07,/*REG = 0x0340 frame_length_lines_hi*/
+		0xd0,/*REG = 0x0341 frame_length_lines_lo*/
+		0x0b,/*REG = 0x0342 line_length_pck_hi*/
+		0x8c,/*REG = 0x0343 line_length_pck_lo*/
+		0x01,/*REG = 0x3005*/
+		0x00,/*REG = 0x3010*/
+		0x00,/*REG = 0x3011*/
+		0x55,/*REG = 0x301a*/
+		0x01,/*REG = 0x3035*/
+		0x23,/*REG = 0x3036*/
+		0x00,/*REG = 0x3041*/
+		0x24,/*REG = 0x3042*/
+		0xb7,/*REG = 0x3045*/
+		0x01,/*REG = 0x0b80 edof application*/
+		0x00,/*REG = 0x0900*/
+		0x00,/*REG = 0x0901*/
+		0x00,/*REG = 0x0902*/
+		0x01,/*REG = 0x0383*/
+		0x01,/*REG = 0x0387*/
+		0x0A,/*REG = 0x034c*/
+		0x30,/*REG = 0x034d*/
+		0x07,/*REG = 0x034e*/
+		0xA8,/*REG = 0x034f*/
+		0x02,/*0x1716*/
+		0x0d,/*0x1717*/
+		0x07,/*0x1718*/
+		0x7d,/*0x1719*/
+		0x01,/*0x3210*/
+		0x02,/*0x111*/
+		0x01,/*0x3410*/
+		0x01,/*0x3098*/
+		0x05, /*0x309D*/
+		0x02,
+		0x00,
+	}
+};
+
+
+
+struct vx6953_reg vx6953_regs = {
+	.reg_pat_init = &vx6953_reg_init[0],
+	.reg_pat = &vx6953_reg_pat[0],
+};
diff --git a/drivers/media/platform/msm/camera_v1/vx6953_v4l2.c b/drivers/media/platform/msm/camera_v1/vx6953_v4l2.c
new file mode 100644
index 0000000..7913752
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vx6953_v4l2.c
@@ -0,0 +1,4149 @@
+/* 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/delay.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <media/v4l2-subdev.h>
+#include <media/msm_camera.h>
+#include <mach/gpio.h>
+#include <mach/camera.h>
+#include <linux/slab.h>
+#include "vx6953_v4l2.h"
+#include "msm.h"
+
+#define V4L2_IDENT_VX6953  50000
+
+/*=============================================================
+	SENSOR REGISTER DEFINES
+==============================================================*/
+
+#define REG_GROUPED_PARAMETER_HOLD			0x0104
+#define GROUPED_PARAMETER_HOLD_OFF			0x00
+#define GROUPED_PARAMETER_HOLD				0x01
+#define REG_MODE_SELECT					0x0100
+#define MODE_SELECT_STANDBY_MODE			0x00
+#define MODE_SELECT_STREAM				0x01
+/* Integration Time */
+#define REG_COARSE_INTEGRATION_TIME_HI			0x0202
+#define REG_COARSE_INTEGRATION_TIME_LO			0x0203
+/* Gain */
+#define REG_ANALOGUE_GAIN_CODE_GLOBAL_HI		0x0204
+#define REG_ANALOGUE_GAIN_CODE_GLOBAL_LO		0x0205
+/* Digital Gain */
+#define REG_DIGITAL_GAIN_GREEN_R_HI			0x020E
+#define REG_DIGITAL_GAIN_GREEN_R_LO			0x020F
+#define REG_DIGITAL_GAIN_RED_HI				0x0210
+#define REG_DIGITAL_GAIN_RED_LO				0x0211
+#define REG_DIGITAL_GAIN_BLUE_HI			0x0212
+#define REG_DIGITAL_GAIN_BLUE_LO			0x0213
+#define REG_DIGITAL_GAIN_GREEN_B_HI			0x0214
+#define REG_DIGITAL_GAIN_GREEN_B_LO			0x0215
+/* output bits setting */
+#define REG_0x0112					0x0112
+#define REG_0x0113					0x0113
+/* PLL registers */
+#define REG_VT_PIX_CLK_DIV				0x0301
+#define REG_PRE_PLL_CLK_DIV				0x0305
+#define REG_PLL_MULTIPLIER				0x0307
+#define REG_OP_PIX_CLK_DIV				0x0309
+#define REG_0x034c					0x034c
+#define REG_0x034d					0x034d
+#define REG_0x034e					0x034e
+#define REG_0x034f					0x034f
+#define REG_0x0387					0x0387
+#define REG_0x0383					0x0383
+#define REG_FRAME_LENGTH_LINES_HI			0x0340
+#define REG_FRAME_LENGTH_LINES_LO			0x0341
+#define REG_LINE_LENGTH_PCK_HI				0x0342
+#define REG_LINE_LENGTH_PCK_LO				0x0343
+#define REG_0x3030					0x3030
+#define REG_0x0111					0x0111
+#define REG_0x0136					0x0136
+#define REG_0x0137					0x0137
+#define REG_0x0b00					0x0b00
+#define REG_0x3001					0x3001
+#define REG_0x3004					0x3004
+#define REG_0x3007					0x3007
+#define REG_0x301a					0x301a
+#define REG_0x3101					0x3101
+#define REG_0x3364					0x3364
+#define REG_0x3365					0x3365
+#define REG_0x0b83					0x0b83
+#define REG_0x0b84					0x0b84
+#define REG_0x0b85					0x0b85
+#define REG_0x0b88					0x0b88
+#define REG_0x0b89					0x0b89
+#define REG_0x0b8a					0x0b8a
+#define REG_0x3005					0x3005
+#define REG_0x3010					0x3010
+#define REG_0x3036					0x3036
+#define REG_0x3041					0x3041
+#define REG_0x0b80					0x0b80
+#define REG_0x0900					0x0900
+#define REG_0x0901					0x0901
+#define REG_0x0902					0x0902
+#define REG_0x3016					0x3016
+#define REG_0x301d					0x301d
+#define REG_0x317e					0x317e
+#define REG_0x317f					0x317f
+#define REG_0x3400					0x3400
+#define REG_0x303a					0x303a
+#define REG_0x1716					0x1716
+#define REG_0x1717					0x1717
+#define REG_0x1718					0x1718
+#define REG_0x1719					0x1719
+#define REG_0x3006					0x3006
+#define REG_0x301b					0x301b
+#define REG_0x3098					0x3098
+#define REG_0x309d					0x309d
+#define REG_0x3011					0x3011
+#define REG_0x3035					0x3035
+#define REG_0x3045					0x3045
+#define REG_0x3210					0x3210
+#define	REG_0x0111					0x0111
+#define REG_0x3410					0x3410
+/* Test Pattern */
+#define REG_TEST_PATTERN_MODE				0x0601
+
+/*============================================================================
+							 TYPE DECLARATIONS
+============================================================================*/
+
+/* 16bit address - 8 bit context register structure */
+#define	VX6953_STM5M0EDOF_OFFSET	9
+#define	Q8		0x00000100
+#define	Q10		0x00000400
+#define	VX6953_STM5M0EDOF_MAX_SNAPSHOT_EXPOSURE_LINE_COUNT	2922
+#define	VX6953_STM5M0EDOF_DEFAULT_MASTER_CLK_RATE	24000000
+#define	VX6953_STM5M0EDOF_OP_PIXEL_CLOCK_RATE	79800000
+#define	VX6953_STM5M0EDOF_VT_PIXEL_CLOCK_RATE	88670000
+/* Full	Size */
+#define	VX6953_FULL_SIZE_WIDTH	2608
+#define	VX6953_FULL_SIZE_HEIGHT		1960
+#define	VX6953_FULL_SIZE_DUMMY_PIXELS	1
+#define	VX6953_FULL_SIZE_DUMMY_LINES	0
+/* Quarter Size	*/
+#define	VX6953_QTR_SIZE_WIDTH	1304
+#define	VX6953_QTR_SIZE_HEIGHT		980
+#define	VX6953_QTR_SIZE_DUMMY_PIXELS	1
+#define	VX6953_QTR_SIZE_DUMMY_LINES		0
+/* Blanking	as measured	on the scope */
+/* Full	Size */
+#define	VX6953_HRZ_FULL_BLK_PIXELS	348
+#define	VX6953_VER_FULL_BLK_LINES	40
+/* Quarter Size	*/
+#define	VX6953_HRZ_QTR_BLK_PIXELS	1628
+#define	VX6953_VER_QTR_BLK_LINES	28
+#define	MAX_LINE_LENGTH_PCK		8190
+#define	VX6953_REVISION_NUMBER_CUT2	0x10/*revision number	for	Cut2.0*/
+#define	VX6953_REVISION_NUMBER_CUT3	0x20/*revision number	for	Cut3.0*/
+/* FIXME: Changes from here */
+struct vx6953_work_t {
+	struct work_struct work;
+};
+
+static struct vx6953_work_t *vx6953_sensorw;
+static struct i2c_client *vx6953_client;
+
+struct vx6953_ctrl_t {
+	const struct  msm_camera_sensor_info *sensordata;
+
+	uint32_t sensormode;
+	uint32_t fps_divider;  /* init to 1 * 0x00000400 */
+	uint32_t pict_fps_divider;  /* init to 1 * 0x00000400 */
+	uint16_t fps;
+
+	int16_t curr_lens_pos;
+	uint16_t curr_step_pos;
+	uint16_t my_reg_gain;
+	uint32_t my_reg_line_count;
+	uint16_t total_lines_per_frame;
+
+	enum vx6953_resolution_t prev_res;
+	enum vx6953_resolution_t pict_res;
+	enum vx6953_resolution_t curr_res;
+	enum vx6953_test_mode_t  set_test;
+	enum sensor_revision_t sensor_type;
+
+	enum edof_mode_t edof_mode;
+
+	unsigned short imgaddr;
+
+	struct v4l2_subdev *sensor_dev;
+	struct vx6953_format *fmt;
+};
+
+
+static uint8_t vx6953_stm5m0edof_delay_msecs_stdby;
+static uint16_t vx6953_stm5m0edof_delay_msecs_stream = 20;
+
+static struct vx6953_ctrl_t *vx6953_ctrl;
+static DECLARE_WAIT_QUEUE_HEAD(vx6953_wait_queue);
+DEFINE_MUTEX(vx6953_mut);
+static struct vx6953_i2c_reg_conf patch_tbl_cut2[] = {
+	{0xFB94, 0},	/*intialise Data Xfer Status reg*/
+	{0xFB95, 0},	/*gain 1	  (0x00)*/
+	{0xFB96, 0},	/*gain 1.07   (0x10)*/
+	{0xFB97, 0},	/*gain 1.14   (0x20)*/
+	{0xFB98, 0},	/*gain 1.23   (0x30)*/
+	{0xFB99, 0},	/*gain 1.33   (0x40)*/
+	{0xFB9A, 0},	/*gain 1.45   (0x50)*/
+	{0xFB9B, 0},	/*gain 1.6    (0x60)*/
+	{0xFB9C, 0},	/*gain 1.78   (0x70)*/
+	{0xFB9D, 2},	/*gain 2	  (0x80)*/
+	{0xFB9E, 2},	/*gain 2.29   (0x90)*/
+	{0xFB9F, 3},	/*gain 2.67   (0xA0)*/
+	{0xFBA0, 3},	/*gain 3.2    (0xB0)*/
+	{0xFBA1, 4},	/*gain 4	  (0xC0)*/
+	{0xFBA2, 7},	/*gain 5.33   (0xD0)*/
+	{0xFBA3, 10},	/*gain 8	  (0xE0)*/
+	{0xFBA4, 11},	/*gain 9.14   (0xE4)*/
+	{0xFBA5, 13},	/*gain 10.67  (0xE8)*/
+	{0xFBA6, 15},	/*gain 12.8   (0xEC)*/
+	{0xFBA7, 19},	/*gain 16     (0xF0)*/
+	{0xF800, 0x12},
+	{0xF801, 0x06},
+	{0xF802, 0xf7},
+	{0xF803, 0x90},
+	{0xF804, 0x02},
+	{0xF805, 0x05},
+	{0xF806, 0xe0},
+	{0xF807, 0xff},
+	{0xF808, 0x65},
+	{0xF809, 0x7d},
+	{0xF80A, 0x70},
+	{0xF80B, 0x03},
+	{0xF80C, 0x02},
+	{0xF80D, 0xf9},
+	{0xF80E, 0x1c},
+	{0xF80F, 0x8f},
+	{0xF810, 0x7d},
+	{0xF811, 0xe4},
+	{0xF812, 0xf5},
+	{0xF813, 0x7a},
+	{0xF814, 0x75},
+	{0xF815, 0x78},
+	{0xF816, 0x30},
+	{0xF817, 0x75},
+	{0xF818, 0x79},
+	{0xF819, 0x53},
+	{0xF81A, 0x85},
+	{0xF81B, 0x79},
+	{0xF81C, 0x82},
+	{0xF81D, 0x85},
+	{0xF81E, 0x78},
+	{0xF81F, 0x83},
+	{0xF820, 0xe0},
+	{0xF821, 0xc3},
+	{0xF822, 0x95},
+	{0xF823, 0x7b},
+	{0xF824, 0xf0},
+	{0xF825, 0x74},
+	{0xF826, 0x02},
+	{0xF827, 0x25},
+	{0xF828, 0x79},
+	{0xF829, 0xf5},
+	{0xF82A, 0x79},
+	{0xF82B, 0xe4},
+	{0xF82C, 0x35},
+	{0xF82D, 0x78},
+	{0xF82E, 0xf5},
+	{0xF82F, 0x78},
+	{0xF830, 0x05},
+	{0xF831, 0x7a},
+	{0xF832, 0xe5},
+	{0xF833, 0x7a},
+	{0xF834, 0xb4},
+	{0xF835, 0x08},
+	{0xF836, 0xe3},
+	{0xF837, 0xe5},
+	{0xF838, 0x7d},
+	{0xF839, 0x70},
+	{0xF83A, 0x04},
+	{0xF83B, 0xff},
+	{0xF83C, 0x02},
+	{0xF83D, 0xf8},
+	{0xF83E, 0xe4},
+	{0xF83F, 0xe5},
+	{0xF840, 0x7d},
+	{0xF841, 0xb4},
+	{0xF842, 0x10},
+	{0xF843, 0x05},
+	{0xF844, 0x7f},
+	{0xF845, 0x01},
+	{0xF846, 0x02},
+	{0xF847, 0xf8},
+	{0xF848, 0xe4},
+	{0xF849, 0xe5},
+	{0xF84A, 0x7d},
+	{0xF84B, 0xb4},
+	{0xF84C, 0x20},
+	{0xF84D, 0x05},
+	{0xF84E, 0x7f},
+	{0xF84F, 0x02},
+	{0xF850, 0x02},
+	{0xF851, 0xf8},
+	{0xF852, 0xe4},
+	{0xF853, 0xe5},
+	{0xF854, 0x7d},
+	{0xF855, 0xb4},
+	{0xF856, 0x30},
+	{0xF857, 0x05},
+	{0xF858, 0x7f},
+	{0xF859, 0x03},
+	{0xF85A, 0x02},
+	{0xF85B, 0xf8},
+	{0xF85C, 0xe4},
+	{0xF85D, 0xe5},
+	{0xF85E, 0x7d},
+	{0xF85F, 0xb4},
+	{0xF860, 0x40},
+	{0xF861, 0x04},
+	{0xF862, 0x7f},
+	{0xF863, 0x04},
+	{0xF864, 0x80},
+	{0xF865, 0x7e},
+	{0xF866, 0xe5},
+	{0xF867, 0x7d},
+	{0xF868, 0xb4},
+	{0xF869, 0x50},
+	{0xF86A, 0x04},
+	{0xF86B, 0x7f},
+	{0xF86C, 0x05},
+	{0xF86D, 0x80},
+	{0xF86E, 0x75},
+	{0xF86F, 0xe5},
+	{0xF870, 0x7d},
+	{0xF871, 0xb4},
+	{0xF872, 0x60},
+	{0xF873, 0x04},
+	{0xF874, 0x7f},
+	{0xF875, 0x06},
+	{0xF876, 0x80},
+	{0xF877, 0x6c},
+	{0xF878, 0xe5},
+	{0xF879, 0x7d},
+	{0xF87A, 0xb4},
+	{0xF87B, 0x70},
+	{0xF87C, 0x04},
+	{0xF87D, 0x7f},
+	{0xF87E, 0x07},
+	{0xF87F, 0x80},
+	{0xF880, 0x63},
+	{0xF881, 0xe5},
+	{0xF882, 0x7d},
+	{0xF883, 0xb4},
+	{0xF884, 0x80},
+	{0xF885, 0x04},
+	{0xF886, 0x7f},
+	{0xF887, 0x08},
+	{0xF888, 0x80},
+	{0xF889, 0x5a},
+	{0xF88A, 0xe5},
+	{0xF88B, 0x7d},
+	{0xF88C, 0xb4},
+	{0xF88D, 0x90},
+	{0xF88E, 0x04},
+	{0xF88F, 0x7f},
+	{0xF890, 0x09},
+	{0xF891, 0x80},
+	{0xF892, 0x51},
+	{0xF893, 0xe5},
+	{0xF894, 0x7d},
+	{0xF895, 0xb4},
+	{0xF896, 0xa0},
+	{0xF897, 0x04},
+	{0xF898, 0x7f},
+	{0xF899, 0x0a},
+	{0xF89A, 0x80},
+	{0xF89B, 0x48},
+	{0xF89C, 0xe5},
+	{0xF89D, 0x7d},
+	{0xF89E, 0xb4},
+	{0xF89F, 0xb0},
+	{0xF8A0, 0x04},
+	{0xF8A1, 0x7f},
+	{0xF8A2, 0x0b},
+	{0xF8A3, 0x80},
+	{0xF8A4, 0x3f},
+	{0xF8A5, 0xe5},
+	{0xF8A6, 0x7d},
+	{0xF8A7, 0xb4},
+	{0xF8A8, 0xc0},
+	{0xF8A9, 0x04},
+	{0xF8AA, 0x7f},
+	{0xF8AB, 0x0c},
+	{0xF8AC, 0x80},
+	{0xF8AD, 0x36},
+	{0xF8AE, 0xe5},
+	{0xF8AF, 0x7d},
+	{0xF8B0, 0xb4},
+	{0xF8B1, 0xd0},
+	{0xF8B2, 0x04},
+	{0xF8B3, 0x7f},
+	{0xF8B4, 0x0d},
+	{0xF8B5, 0x80},
+	{0xF8B6, 0x2d},
+	{0xF8B7, 0xe5},
+	{0xF8B8, 0x7d},
+	{0xF8B9, 0xb4},
+	{0xF8BA, 0xe0},
+	{0xF8BB, 0x04},
+	{0xF8BC, 0x7f},
+	{0xF8BD, 0x0e},
+	{0xF8BE, 0x80},
+	{0xF8BF, 0x24},
+	{0xF8C0, 0xe5},
+	{0xF8C1, 0x7d},
+	{0xF8C2, 0xb4},
+	{0xF8C3, 0xe4},
+	{0xF8C4, 0x04},
+	{0xF8C5, 0x7f},
+	{0xF8C6, 0x0f},
+	{0xF8C7, 0x80},
+	{0xF8C8, 0x1b},
+	{0xF8C9, 0xe5},
+	{0xF8CA, 0x7d},
+	{0xF8CB, 0xb4},
+	{0xF8CC, 0xe8},
+	{0xF8CD, 0x04},
+	{0xF8CE, 0x7f},
+	{0xF8CF, 0x10},
+	{0xF8D0, 0x80},
+	{0xF8D1, 0x12},
+	{0xF8D2, 0xe5},
+	{0xF8D3, 0x7d},
+	{0xF8D4, 0xb4},
+	{0xF8D5, 0xec},
+	{0xF8D6, 0x04},
+	{0xF8D7, 0x7f},
+	{0xF8D8, 0x11},
+	{0xF8D9, 0x80},
+	{0xF8DA, 0x09},
+	{0xF8DB, 0xe5},
+	{0xF8DC, 0x7d},
+	{0xF8DD, 0x7f},
+	{0xF8DE, 0x00},
+	{0xF8DF, 0xb4},
+	{0xF8E0, 0xf0},
+	{0xF8E1, 0x02},
+	{0xF8E2, 0x7f},
+	{0xF8E3, 0x12},
+	{0xF8E4, 0x8f},
+	{0xF8E5, 0x7c},
+	{0xF8E6, 0xef},
+	{0xF8E7, 0x24},
+	{0xF8E8, 0x95},
+	{0xF8E9, 0xff},
+	{0xF8EA, 0xe4},
+	{0xF8EB, 0x34},
+	{0xF8EC, 0xfb},
+	{0xF8ED, 0x8f},
+	{0xF8EE, 0x82},
+	{0xF8EF, 0xf5},
+	{0xF8F0, 0x83},
+	{0xF8F1, 0xe4},
+	{0xF8F2, 0x93},
+	{0xF8F3, 0xf5},
+	{0xF8F4, 0x7c},
+	{0xF8F5, 0xf5},
+	{0xF8F6, 0x7b},
+	{0xF8F7, 0xe4},
+	{0xF8F8, 0xf5},
+	{0xF8F9, 0x7a},
+	{0xF8FA, 0x75},
+	{0xF8FB, 0x78},
+	{0xF8FC, 0x30},
+	{0xF8FD, 0x75},
+	{0xF8FE, 0x79},
+	{0xF8FF, 0x53},
+	{0xF900, 0x85},
+	{0xF901, 0x79},
+	{0xF902, 0x82},
+	{0xF903, 0x85},
+	{0xF904, 0x78},
+	{0xF905, 0x83},
+	{0xF906, 0xe0},
+	{0xF907, 0x25},
+	{0xF908, 0x7c},
+	{0xF909, 0xf0},
+	{0xF90A, 0x74},
+	{0xF90B, 0x02},
+	{0xF90C, 0x25},
+	{0xF90D, 0x79},
+	{0xF90E, 0xf5},
+	{0xF90F, 0x79},
+	{0xF910, 0xe4},
+	{0xF911, 0x35},
+	{0xF912, 0x78},
+	{0xF913, 0xf5},
+	{0xF914, 0x78},
+	{0xF915, 0x05},
+	{0xF916, 0x7a},
+	{0xF917, 0xe5},
+	{0xF918, 0x7a},
+	{0xF919, 0xb4},
+	{0xF91A, 0x08},
+	{0xF91B, 0xe4},
+	{0xF91C, 0x02},
+	{0xF91D, 0x18},
+	{0xF91E, 0x32},
+	{0xF91F, 0x22},
+	{0xF920, 0xf0},
+	{0xF921, 0x90},
+	{0xF922, 0xa0},
+	{0xF923, 0xf8},
+	{0xF924, 0xe0},
+	{0xF925, 0x70},
+	{0xF926, 0x02},
+	{0xF927, 0xa3},
+	{0xF928, 0xe0},
+	{0xF929, 0x70},
+	{0xF92A, 0x0a},
+	{0xF92B, 0x90},
+	{0xF92C, 0xa1},
+	{0xF92D, 0x10},
+	{0xF92E, 0xe0},
+	{0xF92F, 0xfe},
+	{0xF930, 0xa3},
+	{0xF931, 0xe0},
+	{0xF932, 0xff},
+	{0xF933, 0x80},
+	{0xF934, 0x04},
+	{0xF935, 0x7e},
+	{0xF936, 0x00},
+	{0xF937, 0x7f},
+	{0xF938, 0x00},
+	{0xF939, 0x8e},
+	{0xF93A, 0x7e},
+	{0xF93B, 0x8f},
+	{0xF93C, 0x7f},
+	{0xF93D, 0x90},
+	{0xF93E, 0x36},
+	{0xF93F, 0x0d},
+	{0xF940, 0xe0},
+	{0xF941, 0x44},
+	{0xF942, 0x02},
+	{0xF943, 0xf0},
+	{0xF944, 0x90},
+	{0xF945, 0x36},
+	{0xF946, 0x0e},
+	{0xF947, 0xe5},
+	{0xF948, 0x7e},
+	{0xF949, 0xf0},
+	{0xF94A, 0xa3},
+	{0xF94B, 0xe5},
+	{0xF94C, 0x7f},
+	{0xF94D, 0xf0},
+	{0xF94E, 0xe5},
+	{0xF94F, 0x3a},
+	{0xF950, 0x60},
+	{0xF951, 0x0c},
+	{0xF952, 0x90},
+	{0xF953, 0x36},
+	{0xF954, 0x09},
+	{0xF955, 0xe0},
+	{0xF956, 0x70},
+	{0xF957, 0x06},
+	{0xF958, 0x90},
+	{0xF959, 0x36},
+	{0xF95A, 0x08},
+	{0xF95B, 0xf0},
+	{0xF95C, 0xf5},
+	{0xF95D, 0x3a},
+	{0xF95E, 0x02},
+	{0xF95F, 0x03},
+	{0xF960, 0x94},
+	{0xF961, 0x22},
+	{0xF962, 0x78},
+	{0xF963, 0x07},
+	{0xF964, 0xe6},
+	{0xF965, 0xd3},
+	{0xF966, 0x94},
+	{0xF967, 0x00},
+	{0xF968, 0x40},
+	{0xF969, 0x16},
+	{0xF96A, 0x16},
+	{0xF96B, 0xe6},
+	{0xF96C, 0x90},
+	{0xF96D, 0x30},
+	{0xF96E, 0xa1},
+	{0xF96F, 0xf0},
+	{0xF970, 0x90},
+	{0xF971, 0x43},
+	{0xF972, 0x83},
+	{0xF973, 0xe0},
+	{0xF974, 0xb4},
+	{0xF975, 0x01},
+	{0xF976, 0x0f},
+	{0xF977, 0x90},
+	{0xF978, 0x43},
+	{0xF979, 0x87},
+	{0xF97A, 0xe0},
+	{0xF97B, 0xb4},
+	{0xF97C, 0x01},
+	{0xF97D, 0x08},
+	{0xF97E, 0x80},
+	{0xF97F, 0x00},
+	{0xF980, 0x90},
+	{0xF981, 0x30},
+	{0xF982, 0xa0},
+	{0xF983, 0x74},
+	{0xF984, 0x01},
+	{0xF985, 0xf0},
+	{0xF986, 0x22},
+	{0xF987, 0xf0},
+	{0xF988, 0x90},
+	{0xF989, 0x35},
+	{0xF98A, 0xba},
+	{0xF98B, 0xe0},
+	{0xF98C, 0xb4},
+	{0xF98D, 0x0a},
+	{0xF98E, 0x0d},
+	{0xF98F, 0xa3},
+	{0xF990, 0xe0},
+	{0xF991, 0xb4},
+	{0xF992, 0x01},
+	{0xF993, 0x08},
+	{0xF994, 0x90},
+	{0xF995, 0xfb},
+	{0xF996, 0x94},
+	{0xF997, 0xe0},
+	{0xF998, 0x90},
+	{0xF999, 0x35},
+	{0xF99A, 0xb8},
+	{0xF99B, 0xf0},
+	{0xF99C, 0xd0},
+	{0xF99D, 0xd0},
+	{0xF99E, 0xd0},
+	{0xF99F, 0x82},
+	{0xF9A0, 0xd0},
+	{0xF9A1, 0x83},
+	{0xF9A2, 0xd0},
+	{0xF9A3, 0xe0},
+	{0xF9A4, 0x32},
+	{0xF9A5, 0x22},
+	{0xF9A6, 0xe5},
+	{0xF9A7, 0x7f},
+	{0xF9A8, 0x45},
+	{0xF9A9, 0x7e},
+	{0xF9AA, 0x60},
+	{0xF9AB, 0x15},
+	{0xF9AC, 0x90},
+	{0xF9AD, 0x01},
+	{0xF9AE, 0x00},
+	{0xF9AF, 0xe0},
+	{0xF9B0, 0x70},
+	{0xF9B1, 0x0f},
+	{0xF9B2, 0x90},
+	{0xF9B3, 0xa0},
+	{0xF9B4, 0xf8},
+	{0xF9B5, 0xe5},
+	{0xF9B6, 0x7e},
+	{0xF9B7, 0xf0},
+	{0xF9B8, 0xa3},
+	{0xF9B9, 0xe5},
+	{0xF9BA, 0x7f},
+	{0xF9BB, 0xf0},
+	{0xF9BC, 0xe4},
+	{0xF9BD, 0xf5},
+	{0xF9BE, 0x7e},
+	{0xF9BF, 0xf5},
+	{0xF9C0, 0x7f},
+	{0xF9C1, 0x22},
+	{0xF9C2, 0x02},
+	{0xF9C3, 0x0e},
+	{0xF9C4, 0x79},
+	{0xF9C5, 0x22},
+	/* Offsets:*/
+	{0x35C6, 0x00},/* FIDDLEDARKCAL*/
+	{0x35C7, 0x00},
+	{0x35C8, 0x01},/*STOREDISTANCEATSTOPSTREAMING*/
+	{0x35C9, 0x20},
+	{0x35CA, 0x01},/*BRUCEFIX*/
+	{0x35CB, 0x62},
+	{0x35CC, 0x01},/*FIXDATAXFERSTATUSREG*/
+	{0x35CD, 0x87},
+	{0x35CE, 0x01},/*FOCUSDISTANCEUPDATE*/
+	{0x35CF, 0xA6},
+	{0x35D0, 0x01},/*SKIPEDOFRESET*/
+	{0x35D1, 0xC2},
+	{0x35D2, 0x00},
+	{0x35D3, 0xFB},
+	{0x35D4, 0x00},
+	{0x35D5, 0x94},
+	{0x35D6, 0x00},
+	{0x35D7, 0xFB},
+	{0x35D8, 0x00},
+	{0x35D9, 0x94},
+	{0x35DA, 0x00},
+	{0x35DB, 0xFB},
+	{0x35DC, 0x00},
+	{0x35DD, 0x94},
+	{0x35DE, 0x00},
+	{0x35DF, 0xFB},
+	{0x35E0, 0x00},
+	{0x35E1, 0x94},
+	{0x35E6, 0x18},/* FIDDLEDARKCAL*/
+	{0x35E7, 0x2F},
+	{0x35E8, 0x03},/* STOREDISTANCEATSTOPSTREAMING*/
+	{0x35E9, 0x93},
+	{0x35EA, 0x18},/* BRUCEFIX*/
+	{0x35EB, 0x99},
+	{0x35EC, 0x00},/* FIXDATAXFERSTATUSREG*/
+	{0x35ED, 0xA3},
+	{0x35EE, 0x21},/* FOCUSDISTANCEUPDATE*/
+	{0x35EF, 0x5B},
+	{0x35F0, 0x0E},/* SKIPEDOFRESET*/
+	{0x35F1, 0x74},
+	{0x35F2, 0x04},
+	{0x35F3, 0x64},
+	{0x35F4, 0x04},
+	{0x35F5, 0x65},
+	{0x35F6, 0x04},
+	{0x35F7, 0x7B},
+	{0x35F8, 0x04},
+	{0x35F9, 0x7C},
+	{0x35FA, 0x04},
+	{0x35FB, 0xDD},
+	{0x35FC, 0x04},
+	{0x35FD, 0xDE},
+	{0x35FE, 0x04},
+	{0x35FF, 0xEF},
+	{0x3600, 0x04},
+	{0x3601, 0xF0},
+	/*Jump/Data:*/
+	{0x35C2, 0x3F},/* Jump Reg*/
+	{0x35C3, 0xFF},/* Jump Reg*/
+	{0x35C4, 0x3F},/* Data Reg*/
+	{0x35C5, 0xC0},/* Data Reg*/
+	{0x35C0, 0x01},/* Enable*/
+
+};
+
+static struct vx6953_i2c_reg_conf edof_tbl[] = {
+	{0xa098, 0x02},
+	{0xa099, 0x87},
+	{0xa09c, 0x00},
+	{0xa09d, 0xc5},
+	{0xa4ec, 0x05},
+	{0xa4ed, 0x05},
+	{0xa4f0, 0x04},
+	{0xa4f1, 0x04},
+	{0xa4f4, 0x04},
+	{0xa4f5, 0x05},
+	{0xa4f8, 0x05},
+	{0xa4f9, 0x07},
+	{0xa4fc, 0x07},
+	{0xa4fd, 0x07},
+	{0xa500, 0x07},
+	{0xa501, 0x07},
+	{0xa504, 0x08},
+	{0xa505, 0x08},
+	{0xa518, 0x01},
+	{0xa519, 0x02},
+	{0xa51c, 0x01},
+	{0xa51d, 0x00},
+	{0xa534, 0x00},
+	{0xa535, 0x04},
+	{0xa538, 0x04},
+	{0xa539, 0x03},
+	{0xa53c, 0x05},
+	{0xa53d, 0x07},
+	{0xa540, 0x07},
+	{0xa541, 0x06},
+	{0xa544, 0x07},
+	{0xa545, 0x06},
+	{0xa548, 0x05},
+	{0xa549, 0x06},
+	{0xa54c, 0x06},
+	{0xa54d, 0x07},
+	{0xa550, 0x07},
+	{0xa551, 0x04},
+	{0xa554, 0x04},
+	{0xa555, 0x04},
+	{0xa558, 0x05},
+	{0xa559, 0x06},
+	{0xa55c, 0x07},
+	{0xa55d, 0x07},
+	{0xa56c, 0x00},
+	{0xa56d, 0x0a},
+	{0xa570, 0x08},
+	{0xa571, 0x05},
+	{0xa574, 0x04},
+	{0xa575, 0x03},
+	{0xa578, 0x04},
+	{0xa579, 0x04},
+	{0xa58c, 0x1f},
+	{0xa58d, 0x1b},
+	{0xa590, 0x17},
+	{0xa591, 0x13},
+	{0xa594, 0x10},
+	{0xa595, 0x0d},
+	{0xa598, 0x0f},
+	{0xa599, 0x11},
+	{0xa59c, 0x03},
+	{0xa59d, 0x03},
+	{0xa5a0, 0x03},
+	{0xa5a1, 0x03},
+	{0xa5a4, 0x03},
+	{0xa5a5, 0x04},
+	{0xa5a8, 0x05},
+	{0xa5a9, 0x00},
+	{0xa5ac, 0x00},
+	{0xa5ad, 0x00},
+	{0xa5b0, 0x00},
+	{0xa5b1, 0x00},
+	{0xa5b4, 0x00},
+	{0xa5b5, 0x00},
+	{0xa5c4, 0x1f},
+	{0xa5c5, 0x13},
+	{0xa5c8, 0x14},
+	{0xa5c9, 0x14},
+	{0xa5cc, 0x14},
+	{0xa5cd, 0x13},
+	{0xa5d0, 0x17},
+	{0xa5d1, 0x1a},
+	{0xa5f4, 0x05},
+	{0xa5f5, 0x05},
+	{0xa5f8, 0x05},
+	{0xa5f9, 0x06},
+	{0xa5fc, 0x06},
+	{0xa5fd, 0x06},
+	{0xa600, 0x06},
+	{0xa601, 0x06},
+	{0xa608, 0x07},
+	{0xa609, 0x08},
+	{0xa60c, 0x08},
+	{0xa60d, 0x07},
+	{0xa63c, 0x00},
+	{0xa63d, 0x02},
+	{0xa640, 0x02},
+	{0xa641, 0x02},
+	{0xa644, 0x02},
+	{0xa645, 0x02},
+	{0xa648, 0x03},
+	{0xa649, 0x04},
+	{0xa64c, 0x0a},
+	{0xa64d, 0x09},
+	{0xa650, 0x08},
+	{0xa651, 0x09},
+	{0xa654, 0x09},
+	{0xa655, 0x0a},
+	{0xa658, 0x0a},
+	{0xa659, 0x0a},
+	{0xa65c, 0x0a},
+	{0xa65d, 0x09},
+	{0xa660, 0x09},
+	{0xa661, 0x09},
+	{0xa664, 0x09},
+	{0xa665, 0x08},
+	{0xa680, 0x01},
+	{0xa681, 0x02},
+	{0xa694, 0x1f},
+	{0xa695, 0x10},
+	{0xa698, 0x0e},
+	{0xa699, 0x0c},
+	{0xa69c, 0x0d},
+	{0xa69d, 0x0d},
+	{0xa6a0, 0x0f},
+	{0xa6a1, 0x11},
+	{0xa6a4, 0x00},
+	{0xa6a5, 0x00},
+	{0xa6a8, 0x00},
+	{0xa6a9, 0x00},
+	{0xa6ac, 0x00},
+	{0xa6ad, 0x00},
+	{0xa6b0, 0x00},
+	{0xa6b1, 0x04},
+	{0xa6b4, 0x04},
+	{0xa6b5, 0x04},
+	{0xa6b8, 0x04},
+	{0xa6b9, 0x04},
+	{0xa6bc, 0x05},
+	{0xa6bd, 0x05},
+	{0xa6c0, 0x1f},
+	{0xa6c1, 0x1f},
+	{0xa6c4, 0x1f},
+	{0xa6c5, 0x1f},
+	{0xa6c8, 0x1f},
+	{0xa6c9, 0x1f},
+	{0xa6cc, 0x1f},
+	{0xa6cd, 0x0b},
+	{0xa6d0, 0x0c},
+	{0xa6d1, 0x0d},
+	{0xa6d4, 0x0d},
+	{0xa6d5, 0x0d},
+	{0xa6d8, 0x11},
+	{0xa6d9, 0x14},
+	{0xa6fc, 0x02},
+	{0xa6fd, 0x03},
+	{0xa700, 0x03},
+	{0xa701, 0x03},
+	{0xa704, 0x03},
+	{0xa705, 0x04},
+	{0xa708, 0x05},
+	{0xa709, 0x02},
+	{0xa70c, 0x02},
+	{0xa70d, 0x02},
+	{0xa710, 0x03},
+	{0xa711, 0x04},
+	{0xa714, 0x04},
+	{0xa715, 0x04},
+	{0xa744, 0x00},
+	{0xa745, 0x03},
+	{0xa748, 0x04},
+	{0xa749, 0x04},
+	{0xa74c, 0x05},
+	{0xa74d, 0x06},
+	{0xa750, 0x07},
+	{0xa751, 0x07},
+	{0xa754, 0x05},
+	{0xa755, 0x05},
+	{0xa758, 0x05},
+	{0xa759, 0x05},
+	{0xa75c, 0x05},
+	{0xa75d, 0x06},
+	{0xa760, 0x07},
+	{0xa761, 0x07},
+	{0xa764, 0x06},
+	{0xa765, 0x05},
+	{0xa768, 0x05},
+	{0xa769, 0x05},
+	{0xa76c, 0x06},
+	{0xa76d, 0x07},
+	{0xa77c, 0x00},
+	{0xa77d, 0x05},
+	{0xa780, 0x05},
+	{0xa781, 0x05},
+	{0xa784, 0x05},
+	{0xa785, 0x04},
+	{0xa788, 0x05},
+	{0xa789, 0x06},
+	{0xa79c, 0x1f},
+	{0xa79d, 0x15},
+	{0xa7a0, 0x13},
+	{0xa7a1, 0x10},
+	{0xa7a4, 0x0f},
+	{0xa7a5, 0x0d},
+	{0xa7a8, 0x11},
+	{0xa7a9, 0x14},
+	{0xa7ac, 0x02},
+	{0xa7ad, 0x02},
+	{0xa7b0, 0x02},
+	{0xa7b1, 0x02},
+	{0xa7b4, 0x02},
+	{0xa7b5, 0x03},
+	{0xa7b8, 0x03},
+	{0xa7b9, 0x00},
+	{0xa7bc, 0x00},
+	{0xa7bd, 0x00},
+	{0xa7c0, 0x00},
+	{0xa7c1, 0x00},
+	{0xa7c4, 0x00},
+	{0xa7c5, 0x00},
+	{0xa7d4, 0x1f},
+	{0xa7d5, 0x0d},
+	{0xa7d8, 0x0f},
+	{0xa7d9, 0x10},
+	{0xa7dc, 0x10},
+	{0xa7dd, 0x10},
+	{0xa7e0, 0x13},
+	{0xa7e1, 0x16},
+	{0xa7f4, 0x00},
+	{0xa7f5, 0x03},
+	{0xa7f8, 0x04},
+	{0xa7f9, 0x04},
+	{0xa7fc, 0x04},
+	{0xa7fd, 0x03},
+	{0xa800, 0x03},
+	{0xa801, 0x03},
+	{0xa804, 0x03},
+	{0xa805, 0x03},
+	{0xa808, 0x03},
+	{0xa809, 0x03},
+	{0xa80c, 0x03},
+	{0xa80d, 0x04},
+	{0xa810, 0x04},
+	{0xa811, 0x0a},
+	{0xa814, 0x0a},
+	{0xa815, 0x0a},
+	{0xa818, 0x0f},
+	{0xa819, 0x14},
+	{0xa81c, 0x14},
+	{0xa81d, 0x14},
+	{0xa82c, 0x00},
+	{0xa82d, 0x04},
+	{0xa830, 0x02},
+	{0xa831, 0x00},
+	{0xa834, 0x00},
+	{0xa835, 0x00},
+	{0xa838, 0x00},
+	{0xa839, 0x00},
+	{0xa840, 0x1f},
+	{0xa841, 0x1f},
+	{0xa848, 0x1f},
+	{0xa849, 0x1f},
+	{0xa84c, 0x1f},
+	{0xa84d, 0x0c},
+	{0xa850, 0x0c},
+	{0xa851, 0x0c},
+	{0xa854, 0x0c},
+	{0xa855, 0x0c},
+	{0xa858, 0x0c},
+	{0xa859, 0x0c},
+	{0xa85c, 0x0c},
+	{0xa85d, 0x0c},
+	{0xa860, 0x0c},
+	{0xa861, 0x0c},
+	{0xa864, 0x0c},
+	{0xa865, 0x0c},
+	{0xa868, 0x0c},
+	{0xa869, 0x0c},
+	{0xa86c, 0x0c},
+	{0xa86d, 0x0c},
+	{0xa870, 0x0c},
+	{0xa871, 0x0c},
+	{0xa874, 0x0c},
+	{0xa875, 0x0c},
+	{0xa878, 0x1f},
+	{0xa879, 0x1f},
+	{0xa87c, 0x1f},
+	{0xa87d, 0x1f},
+	{0xa880, 0x1f},
+	{0xa881, 0x1f},
+	{0xa884, 0x1f},
+	{0xa885, 0x0c},
+	{0xa888, 0x0c},
+	{0xa889, 0x0c},
+	{0xa88c, 0x0c},
+	{0xa88d, 0x0c},
+	{0xa890, 0x0c},
+	{0xa891, 0x0c},
+	{0xa898, 0x1f},
+	{0xa899, 0x1f},
+	{0xa8a0, 0x1f},
+	{0xa8a1, 0x1f},
+	{0xa8a4, 0x1f},
+	{0xa8a5, 0x0c},
+	{0xa8a8, 0x0c},
+	{0xa8a9, 0x0c},
+	{0xa8ac, 0x0c},
+	{0xa8ad, 0x0c},
+	{0xa8b0, 0x0c},
+	{0xa8b1, 0x0c},
+	{0xa8b4, 0x0c},
+	{0xa8b5, 0x0c},
+	{0xa8b8, 0x0c},
+	{0xa8b9, 0x0c},
+	{0xa8bc, 0x0c},
+	{0xa8bd, 0x0c},
+	{0xa8c0, 0x0c},
+	{0xa8c1, 0x0c},
+	{0xa8c4, 0x0c},
+	{0xa8c5, 0x0c},
+	{0xa8c8, 0x0c},
+	{0xa8c9, 0x0c},
+	{0xa8cc, 0x0c},
+	{0xa8cd, 0x0c},
+	{0xa8d0, 0x1f},
+	{0xa8d1, 0x1f},
+	{0xa8d4, 0x1f},
+	{0xa8d5, 0x1f},
+	{0xa8d8, 0x1f},
+	{0xa8d9, 0x1f},
+	{0xa8dc, 0x1f},
+	{0xa8dd, 0x0c},
+	{0xa8e0, 0x0c},
+	{0xa8e1, 0x0c},
+	{0xa8e4, 0x0c},
+	{0xa8e5, 0x0c},
+	{0xa8e8, 0x0c},
+	{0xa8e9, 0x0c},
+	{0xa8f0, 0x1f},
+	{0xa8f1, 0x1f},
+	{0xa8f8, 0x1f},
+	{0xa8f9, 0x1f},
+	{0xa8fc, 0x1f},
+	{0xa8fd, 0x0c},
+	{0xa900, 0x0c},
+	{0xa901, 0x0c},
+	{0xa904, 0x0c},
+	{0xa905, 0x0c},
+	{0xa908, 0x0c},
+	{0xa909, 0x0c},
+	{0xa90c, 0x0c},
+	{0xa90d, 0x0c},
+	{0xa910, 0x0c},
+	{0xa911, 0x0c},
+	{0xa914, 0x0c},
+	{0xa915, 0x0c},
+	{0xa918, 0x0c},
+	{0xa919, 0x0c},
+	{0xa91c, 0x0c},
+	{0xa91d, 0x0c},
+	{0xa920, 0x0c},
+	{0xa921, 0x0c},
+	{0xa924, 0x0c},
+	{0xa925, 0x0c},
+	{0xa928, 0x1f},
+	{0xa929, 0x1f},
+	{0xa92c, 0x1f},
+	{0xa92d, 0x1f},
+	{0xa930, 0x1f},
+	{0xa931, 0x1f},
+	{0xa934, 0x1f},
+	{0xa935, 0x0c},
+	{0xa938, 0x0c},
+	{0xa939, 0x0c},
+	{0xa93c, 0x0c},
+	{0xa93d, 0x0c},
+	{0xa940, 0x0c},
+	{0xa941, 0x0c},
+	{0xa96c, 0x0d},
+	{0xa96d, 0x16},
+	{0xa970, 0x19},
+	{0xa971, 0x0e},
+	{0xa974, 0x16},
+	{0xa975, 0x1a},
+	{0xa978, 0x0d},
+	{0xa979, 0x15},
+	{0xa97c, 0x19},
+	{0xa97d, 0x0d},
+	{0xa980, 0x15},
+	{0xa981, 0x1a},
+	{0xa984, 0x0d},
+	{0xa985, 0x15},
+	{0xa988, 0x1a},
+	{0xa989, 0x0d},
+	{0xa98c, 0x15},
+	{0xa98d, 0x1a},
+	{0xa990, 0x0b},
+	{0xa991, 0x11},
+	{0xa994, 0x02},
+	{0xa995, 0x0e},
+	{0xa998, 0x16},
+	{0xa999, 0x02},
+	{0xa99c, 0x0c},
+	{0xa99d, 0x13},
+	{0xa9a0, 0x02},
+	{0xa9a1, 0x0c},
+	{0xa9a4, 0x12},
+	{0xa9a5, 0x02},
+	{0xa9a8, 0x0c},
+	{0xa9a9, 0x12},
+	{0xa9ac, 0x02},
+	{0xa9ad, 0x0c},
+	{0xa9b0, 0x12},
+	{0xa9b1, 0x02},
+	{0xa9b4, 0x10},
+	{0xa9b5, 0x1e},
+	{0xa9b8, 0x0f},
+	{0xa9b9, 0x13},
+	{0xa9bc, 0x20},
+	{0xa9bd, 0x10},
+	{0xa9c0, 0x11},
+	{0xa9c1, 0x1e},
+	{0xa9c4, 0x10},
+	{0xa9c5, 0x11},
+	{0xa9c8, 0x1e},
+	{0xa9c9, 0x10},
+	{0xa9cc, 0x11},
+	{0xa9cd, 0x20},
+	{0xa9d0, 0x10},
+	{0xa9d1, 0x13},
+	{0xa9d4, 0x24},
+	{0xa9d5, 0x10},
+	{0xa9f0, 0x02},
+	{0xa9f1, 0x01},
+	{0xa9f8, 0x19},
+	{0xa9f9, 0x0b},
+	{0xa9fc, 0x0a},
+	{0xa9fd, 0x07},
+	{0xaa00, 0x0c},
+	{0xaa01, 0x0e},
+	{0xaa08, 0x0c},
+	{0xaa09, 0x06},
+	{0xaa0c, 0x0c},
+	{0xaa0d, 0x0a},
+	{0xaa24, 0x10},
+	{0xaa25, 0x12},
+	{0xaa28, 0x0b},
+	{0xaa29, 0x07},
+	{0xaa2c, 0x10},
+	{0xaa2d, 0x14},
+	{0xaa34, 0x0e},
+	{0xaa35, 0x0e},
+	{0xaa38, 0x07},
+	{0xaa39, 0x07},
+	{0xaa3c, 0x0e},
+	{0xaa3d, 0x0c},
+	{0xaa48, 0x09},
+	{0xaa49, 0x0c},
+	{0xaa4c, 0x0c},
+	{0xaa4d, 0x07},
+	{0xaa54, 0x08},
+	{0xaa55, 0x06},
+	{0xaa58, 0x04},
+	{0xaa59, 0x05},
+	{0xaa5c, 0x06},
+	{0xaa5d, 0x06},
+	{0xaa68, 0x05},
+	{0xaa69, 0x05},
+	{0xaa6c, 0x04},
+	{0xaa6d, 0x05},
+	{0xaa74, 0x06},
+	{0xaa75, 0x04},
+	{0xaa78, 0x05},
+	{0xaa79, 0x05},
+	{0xaa7c, 0x04},
+	{0xaa7d, 0x06},
+	{0xac18, 0x14},
+	{0xac19, 0x00},
+	{0xac1c, 0x14},
+	{0xac1d, 0x00},
+	{0xac20, 0x14},
+	{0xac21, 0x00},
+	{0xac24, 0x14},
+	{0xac25, 0x00},
+	{0xac28, 0x14},
+	{0xac29, 0x00},
+	{0xac2c, 0x14},
+	{0xac2d, 0x00},
+	{0xac34, 0x16},
+	{0xac35, 0x00},
+	{0xac38, 0x16},
+	{0xac39, 0x00},
+	{0xac3c, 0x16},
+	{0xac3d, 0x00},
+	{0xac40, 0x16},
+	{0xac41, 0x00},
+	{0xac44, 0x16},
+	{0xac45, 0x00},
+	{0xac48, 0x16},
+	{0xac49, 0x00},
+	{0xac50, 0x1b},
+	{0xac51, 0x00},
+	{0xac54, 0x1b},
+	{0xac55, 0x00},
+	{0xac58, 0x1b},
+	{0xac59, 0x00},
+	{0xac5c, 0x1b},
+	{0xac5d, 0x00},
+	{0xac60, 0x1b},
+	{0xac61, 0x00},
+	{0xac64, 0x1b},
+	{0xac65, 0x00},
+	{0xac74, 0x09},
+	{0xac75, 0x0c},
+	{0xac78, 0x0f},
+	{0xac79, 0x11},
+	{0xac7c, 0x12},
+	{0xac7d, 0x14},
+	{0xac80, 0x09},
+	{0xac81, 0x0c},
+	{0xac84, 0x0f},
+	{0xac85, 0x11},
+	{0xac88, 0x12},
+	{0xac89, 0x14},
+	{0xac8c, 0x09},
+	{0xac8d, 0x0c},
+	{0xac90, 0x0f},
+	{0xac91, 0x11},
+	{0xac94, 0x12},
+	{0xac95, 0x14},
+	{0xac98, 0x09},
+	{0xac99, 0x0c},
+	{0xac9c, 0x0f},
+	{0xac9d, 0x11},
+	{0xaca0, 0x12},
+	{0xaca1, 0x14},
+	{0xaca4, 0x09},
+	{0xaca5, 0x0c},
+	{0xaca8, 0x0f},
+	{0xaca9, 0x11},
+	{0xacac, 0x12},
+	{0xacad, 0x14},
+	{0xacb0, 0x07},
+	{0xacb1, 0x09},
+	{0xacb4, 0x0c},
+	{0xacb5, 0x0d},
+	{0xacb8, 0x0d},
+	{0xacb9, 0x0e},
+	{0xacbc, 0x05},
+	{0xacbd, 0x07},
+	{0xacc0, 0x0a},
+	{0xacc1, 0x0b},
+	{0xacc4, 0x0b},
+	{0xacc5, 0x0c},
+	{0xacc8, 0x03},
+	{0xacc9, 0x04},
+	{0xaccc, 0x07},
+	{0xaccd, 0x08},
+	{0xacd0, 0x09},
+	{0xacd1, 0x09}
+};
+
+static struct vx6953_i2c_reg_conf patch_tbl_cut3[] = {
+	{0xF800, 0x90},
+	{0xF801, 0x30},
+	{0xF802, 0x31},
+	{0xF803, 0xe0},
+	{0xF804, 0xf5},
+	{0xF805, 0x7d},
+	{0xF806, 0xb4},
+	{0xF807, 0x01},
+	{0xF808, 0x06},
+	{0xF809, 0x75},
+	{0xF80A, 0x7d},
+	{0xF80B, 0x03},
+	{0xF80C, 0x74},
+	{0xF80D, 0x03},
+	{0xF80E, 0xf0},
+	{0xF80F, 0x90},
+	{0xF810, 0x30},
+	{0xF811, 0x04},
+	{0xF812, 0x74},
+	{0xF813, 0x33},
+	{0xF814, 0xf0},
+	{0xF815, 0x90},
+	{0xF816, 0x30},
+	{0xF817, 0x06},
+	{0xF818, 0xe4},
+	{0xF819, 0xf0},
+	{0xF81A, 0xa3},
+	{0xF81B, 0x74},
+	{0xF81C, 0x09},
+	{0xF81D, 0xf0},
+	{0xF81E, 0x90},
+	{0xF81F, 0x30},
+	{0xF820, 0x10},
+	{0xF821, 0xe4},
+	{0xF822, 0xf0},
+	{0xF823, 0xa3},
+	{0xF824, 0xf0},
+	{0xF825, 0x90},
+	{0xF826, 0x30},
+	{0xF827, 0x16},
+	{0xF828, 0x74},
+	{0xF829, 0x1e},
+	{0xF82A, 0xf0},
+	{0xF82B, 0x90},
+	{0xF82C, 0x30},
+	{0xF82D, 0x1a},
+	{0xF82E, 0x74},
+	{0xF82F, 0x6a},
+	{0xF830, 0xf0},
+	{0xF831, 0xa3},
+	{0xF832, 0x74},
+	{0xF833, 0x29},
+	{0xF834, 0xf0},
+	{0xF835, 0x90},
+	{0xF836, 0x30},
+	{0xF837, 0x30},
+	{0xF838, 0x74},
+	{0xF839, 0x08},
+	{0xF83A, 0xf0},
+	{0xF83B, 0x90},
+	{0xF83C, 0x30},
+	{0xF83D, 0x36},
+	{0xF83E, 0x74},
+	{0xF83F, 0x2c},
+	{0xF840, 0xf0},
+	{0xF841, 0x90},
+	{0xF842, 0x30},
+	{0xF843, 0x41},
+	{0xF844, 0xe4},
+	{0xF845, 0xf0},
+	{0xF846, 0xa3},
+	{0xF847, 0x74},
+	{0xF848, 0x24},
+	{0xF849, 0xf0},
+	{0xF84A, 0x90},
+	{0xF84B, 0x30},
+	{0xF84C, 0x45},
+	{0xF84D, 0x74},
+	{0xF84E, 0x81},
+	{0xF84F, 0xf0},
+	{0xF850, 0x90},
+	{0xF851, 0x30},
+	{0xF852, 0x98},
+	{0xF853, 0x74},
+	{0xF854, 0x01},
+	{0xF855, 0xf0},
+	{0xF856, 0x90},
+	{0xF857, 0x30},
+	{0xF858, 0x9d},
+	{0xF859, 0x74},
+	{0xF85A, 0x05},
+	{0xF85B, 0xf0},
+	{0xF85C, 0xe5},
+	{0xF85D, 0x7d},
+	{0xF85E, 0x70},
+	{0xF85F, 0x10},
+	{0xF860, 0x90},
+	{0xF861, 0x30},
+	{0xF862, 0x05},
+	{0xF863, 0x04},
+	{0xF864, 0xf0},
+	{0xF865, 0x90},
+	{0xF866, 0x30},
+	{0xF867, 0x30},
+	{0xF868, 0xe4},
+	{0xF869, 0xf0},
+	{0xF86A, 0x90},
+	{0xF86B, 0x30},
+	{0xF86C, 0x35},
+	{0xF86D, 0x04},
+	{0xF86E, 0xf0},
+	{0xF86F, 0x22},
+	{0xF870, 0xe5},
+	{0xF871, 0x7d},
+	{0xF872, 0x64},
+	{0xF873, 0x02},
+	{0xF874, 0x70},
+	{0xF875, 0x2d},
+	{0xF876, 0x90},
+	{0xF877, 0x30},
+	{0xF878, 0x04},
+	{0xF879, 0x74},
+	{0xF87A, 0x34},
+	{0xF87B, 0xf0},
+	{0xF87C, 0xa3},
+	{0xF87D, 0x74},
+	{0xF87E, 0x07},
+	{0xF87F, 0xf0},
+	{0xF880, 0x90},
+	{0xF881, 0x30},
+	{0xF882, 0x10},
+	{0xF883, 0x74},
+	{0xF884, 0x10},
+	{0xF885, 0xf0},
+	{0xF886, 0x90},
+	{0xF887, 0x30},
+	{0xF888, 0x16},
+	{0xF889, 0x74},
+	{0xF88A, 0x1f},
+	{0xF88B, 0xf0},
+	{0xF88C, 0x90},
+	{0xF88D, 0x30},
+	{0xF88E, 0x1a},
+	{0xF88F, 0x74},
+	{0xF890, 0x62},
+	{0xF891, 0xf0},
+	{0xF892, 0x90},
+	{0xF893, 0x30},
+	{0xF894, 0x35},
+	{0xF895, 0x74},
+	{0xF896, 0x04},
+	{0xF897, 0xf0},
+	{0xF898, 0x90},
+	{0xF899, 0x30},
+	{0xF89A, 0x41},
+	{0xF89B, 0x74},
+	{0xF89C, 0x60},
+	{0xF89D, 0xf0},
+	{0xF89E, 0xa3},
+	{0xF89F, 0x74},
+	{0xF8A0, 0x64},
+	{0xF8A1, 0xf0},
+	{0xF8A2, 0x22},
+	{0xF8A3, 0xe5},
+	{0xF8A4, 0x7d},
+	{0xF8A5, 0xb4},
+	{0xF8A6, 0x03},
+	{0xF8A7, 0x12},
+	{0xF8A8, 0x90},
+	{0xF8A9, 0x30},
+	{0xF8AA, 0x05},
+	{0xF8AB, 0x74},
+	{0xF8AC, 0x03},
+	{0xF8AD, 0xf0},
+	{0xF8AE, 0x90},
+	{0xF8AF, 0x30},
+	{0xF8B0, 0x11},
+	{0xF8B1, 0x74},
+	{0xF8B2, 0x01},
+	{0xF8B3, 0xf0},
+	{0xF8B4, 0x90},
+	{0xF8B5, 0x30},
+	{0xF8B6, 0x35},
+	{0xF8B7, 0x74},
+	{0xF8B8, 0x03},
+	{0xF8B9, 0xf0},
+	{0xF8BA, 0x22},
+	{0xF8BB, 0xc3},
+	{0xF8BC, 0x90},
+	{0xF8BD, 0x0b},
+	{0xF8BE, 0x89},
+	{0xF8BF, 0xe0},
+	{0xF8C0, 0x94},
+	{0xF8C1, 0x1e},
+	{0xF8C2, 0x90},
+	{0xF8C3, 0x0b},
+	{0xF8C4, 0x88},
+	{0xF8C5, 0xe0},
+	{0xF8C6, 0x94},
+	{0xF8C7, 0x00},
+	{0xF8C8, 0x50},
+	{0xF8C9, 0x06},
+	{0xF8CA, 0x7e},
+	{0xF8CB, 0x00},
+	{0xF8CC, 0x7f},
+	{0xF8CD, 0x01},
+	{0xF8CE, 0x80},
+	{0xF8CF, 0x3d},
+	{0xF8D0, 0xc3},
+	{0xF8D1, 0x90},
+	{0xF8D2, 0x0b},
+	{0xF8D3, 0x89},
+	{0xF8D4, 0xe0},
+	{0xF8D5, 0x94},
+	{0xF8D6, 0x3c},
+	{0xF8D7, 0x90},
+	{0xF8D8, 0x0b},
+	{0xF8D9, 0x88},
+	{0xF8DA, 0xe0},
+	{0xF8DB, 0x94},
+	{0xF8DC, 0x00},
+	{0xF8DD, 0x50},
+	{0xF8DE, 0x06},
+	{0xF8DF, 0x7e},
+	{0xF8E0, 0x00},
+	{0xF8E1, 0x7f},
+	{0xF8E2, 0x02},
+	{0xF8E3, 0x80},
+	{0xF8E4, 0x28},
+	{0xF8E5, 0xc3},
+	{0xF8E6, 0x90},
+	{0xF8E7, 0x0b},
+	{0xF8E8, 0x89},
+	{0xF8E9, 0xe0},
+	{0xF8EA, 0x94},
+	{0xF8EB, 0xfa},
+	{0xF8EC, 0x90},
+	{0xF8ED, 0x0b},
+	{0xF8EE, 0x88},
+	{0xF8EF, 0xe0},
+	{0xF8F0, 0x94},
+	{0xF8F1, 0x00},
+	{0xF8F2, 0x50},
+	{0xF8F3, 0x06},
+	{0xF8F4, 0x7e},
+	{0xF8F5, 0x00},
+	{0xF8F6, 0x7f},
+	{0xF8F7, 0x03},
+	{0xF8F8, 0x80},
+	{0xF8F9, 0x13},
+	{0xF8FA, 0xc3},
+	{0xF8FB, 0x90},
+	{0xF8FC, 0x0b},
+	{0xF8FD, 0x88},
+	{0xF8FE, 0xe0},
+	{0xF8FF, 0x94},
+	{0xF900, 0x80},
+	{0xF901, 0x50},
+	{0xF902, 0x06},
+	{0xF903, 0x7e},
+	{0xF904, 0x00},
+	{0xF905, 0x7f},
+	{0xF906, 0x04},
+	{0xF907, 0x80},
+	{0xF908, 0x04},
+	{0xF909, 0xae},
+	{0xF90A, 0x7e},
+	{0xF90B, 0xaf},
+	{0xF90C, 0x7f},
+	{0xF90D, 0x90},
+	{0xF90E, 0xa0},
+	{0xF90F, 0xf8},
+	{0xF910, 0xee},
+	{0xF911, 0xf0},
+	{0xF912, 0xa3},
+	{0xF913, 0xef},
+	{0xF914, 0xf0},
+	{0xF915, 0x22},
+	{0xF916, 0x90},
+	{0xF917, 0x33},
+	{0xF918, 0x82},
+	{0xF919, 0xe0},
+	{0xF91A, 0xff},
+	{0xF91B, 0x64},
+	{0xF91C, 0x01},
+	{0xF91D, 0x70},
+	{0xF91E, 0x30},
+	{0xF91F, 0xe5},
+	{0xF920, 0x7f},
+	{0xF921, 0x64},
+	{0xF922, 0x02},
+	{0xF923, 0x45},
+	{0xF924, 0x7e},
+	{0xF925, 0x70},
+	{0xF926, 0x04},
+	{0xF927, 0x7d},
+	{0xF928, 0x1e},
+	{0xF929, 0x80},
+	{0xF92A, 0x1d},
+	{0xF92B, 0xe5},
+	{0xF92C, 0x7f},
+	{0xF92D, 0x64},
+	{0xF92E, 0x03},
+	{0xF92F, 0x45},
+	{0xF930, 0x7e},
+	{0xF931, 0x70},
+	{0xF932, 0x04},
+	{0xF933, 0x7d},
+	{0xF934, 0x3c},
+	{0xF935, 0x80},
+	{0xF936, 0x11},
+	{0xF937, 0xe5},
+	{0xF938, 0x7f},
+	{0xF939, 0x64},
+	{0xF93A, 0x04},
+	{0xF93B, 0x45},
+	{0xF93C, 0x7e},
+	{0xF93D, 0x70},
+	{0xF93E, 0x04},
+	{0xF93F, 0x7d},
+	{0xF940, 0xfa},
+	{0xF941, 0x80},
+	{0xF942, 0x05},
+	{0xF943, 0x90},
+	{0xF944, 0x33},
+	{0xF945, 0x81},
+	{0xF946, 0xe0},
+	{0xF947, 0xfd},
+	{0xF948, 0xae},
+	{0xF949, 0x05},
+	{0xF94A, 0x90},
+	{0xF94B, 0x33},
+	{0xF94C, 0x81},
+	{0xF94D, 0xed},
+	{0xF94E, 0xf0},
+	{0xF94F, 0xef},
+	{0xF950, 0xb4},
+	{0xF951, 0x01},
+	{0xF952, 0x10},
+	{0xF953, 0x90},
+	{0xF954, 0x01},
+	{0xF955, 0x00},
+	{0xF956, 0xe0},
+	{0xF957, 0x60},
+	{0xF958, 0x0a},
+	{0xF959, 0x90},
+	{0xF95A, 0xa1},
+	{0xF95B, 0x10},
+	{0xF95C, 0xe0},
+	{0xF95D, 0xf5},
+	{0xF95E, 0x7e},
+	{0xF95F, 0xa3},
+	{0xF960, 0xe0},
+	{0xF961, 0xf5},
+	{0xF962, 0x7f},
+	{0xF963, 0x22},
+	{0xF964, 0x12},
+	{0xF965, 0x2f},
+	{0xF966, 0x4d},
+	{0xF967, 0x90},
+	{0xF968, 0x35},
+	{0xF969, 0x38},
+	{0xF96A, 0xe0},
+	{0xF96B, 0x70},
+	{0xF96C, 0x05},
+	{0xF96D, 0x12},
+	{0xF96E, 0x00},
+	{0xF96F, 0x0e},
+	{0xF970, 0x80},
+	{0xF971, 0x03},
+	{0xF972, 0x12},
+	{0xF973, 0x07},
+	{0xF974, 0xc9},
+	{0xF975, 0x90},
+	{0xF976, 0x40},
+	{0xF977, 0x06},
+	{0xF978, 0xe0},
+	{0xF979, 0xf4},
+	{0xF97A, 0x54},
+	{0xF97B, 0x02},
+	{0xF97C, 0xff},
+	{0xF97D, 0xe0},
+	{0xF97E, 0x54},
+	{0xF97F, 0x01},
+	{0xF980, 0x4f},
+	{0xF981, 0x90},
+	{0xF982, 0x31},
+	{0xF983, 0x32},
+	{0xF984, 0xf0},
+	{0xF985, 0x90},
+	{0xF986, 0xfa},
+	{0xF987, 0x9d},
+	{0xF988, 0xe0},
+	{0xF989, 0x70},
+	{0xF98A, 0x03},
+	{0xF98B, 0x12},
+	{0xF98C, 0x27},
+	{0xF98D, 0x27},
+	{0xF98E, 0x02},
+	{0xF98F, 0x05},
+	{0xF990, 0xac},
+	{0xF991, 0x22},
+	{0xF992, 0x78},
+	{0xF993, 0x07},
+	{0xF994, 0xe6},
+	{0xF995, 0xf5},
+	{0xF996, 0x7c},
+	{0xF997, 0xe5},
+	{0xF998, 0x7c},
+	{0xF999, 0x60},
+	{0xF99A, 0x1d},
+	{0xF99B, 0x90},
+	{0xF99C, 0x43},
+	{0xF99D, 0x83},
+	{0xF99E, 0xe0},
+	{0xF99F, 0xb4},
+	{0xF9A0, 0x01},
+	{0xF9A1, 0x16},
+	{0xF9A2, 0x90},
+	{0xF9A3, 0x43},
+	{0xF9A4, 0x87},
+	{0xF9A5, 0xe0},
+	{0xF9A6, 0xb4},
+	{0xF9A7, 0x01},
+	{0xF9A8, 0x0f},
+	{0xF9A9, 0x15},
+	{0xF9AA, 0x7c},
+	{0xF9AB, 0x90},
+	{0xF9AC, 0x30},
+	{0xF9AD, 0xa1},
+	{0xF9AE, 0xe5},
+	{0xF9AF, 0x7c},
+	{0xF9B0, 0xf0},
+	{0xF9B1, 0x90},
+	{0xF9B2, 0x30},
+	{0xF9B3, 0xa0},
+	{0xF9B4, 0x74},
+	{0xF9B5, 0x01},
+	{0xF9B6, 0xf0},
+	{0xF9B7, 0x22},
+	{0xF9B8, 0xe4},
+	{0xF9B9, 0x90},
+	{0xF9BA, 0x30},
+	{0xF9BB, 0xa0},
+	{0xF9BC, 0xf0},
+	{0xF9BD, 0x22},
+	{0xF9BE, 0xf0},
+	{0xF9BF, 0xe5},
+	{0xF9C0, 0x3a},
+	{0xF9C1, 0xb4},
+	{0xF9C2, 0x06},
+	{0xF9C3, 0x06},
+	{0xF9C4, 0x63},
+	{0xF9C5, 0x3e},
+	{0xF9C6, 0x02},
+	{0xF9C7, 0x12},
+	{0xF9C8, 0x03},
+	{0xF9C9, 0xea},
+	{0xF9CA, 0x02},
+	{0xF9CB, 0x17},
+	{0xF9CC, 0x4a},
+	{0xF9CD, 0x22},
+	{0x35C9, 0xBB},
+	{0x35CA, 0x01},
+	{0x35CB, 0x16},
+	{0x35CC, 0x01},
+	{0x35CD, 0x64},
+	{0x35CE, 0x01},
+	{0x35CF, 0x92},
+	{0x35D0, 0x01},
+	{0x35D1, 0xBE},
+	{0x35D3, 0xF6},
+	{0x35D5, 0x07},
+	{0x35D7, 0xA3},
+	{0x35DB, 0x02},
+	{0x35DD, 0x06},
+	{0x35DF, 0x1B},
+	{0x35E6, 0x28},
+	{0x35E7, 0x76},
+	{0x35E8, 0x2D},
+	{0x35E9, 0x07},
+	{0x35EA, 0x04},
+	{0x35EB, 0x43},
+	{0x35EC, 0x05},
+	{0x35ED, 0xA9},
+	{0x35EE, 0x2A},
+	{0x35EF, 0x15},
+	{0x35F0, 0x17},
+	{0x35F1, 0x41},
+	{0x35F2, 0x24},
+	{0x35F3, 0x88},
+	{0x35F4, 0x01},
+	{0x35F5, 0x54},
+	{0x35F6, 0x01},
+	{0x35F7, 0x55},
+	{0x35F8, 0x2E},
+	{0x35F9, 0xF2},
+	{0x35FA, 0x06},
+	{0x35FB, 0x02},
+	{0x35FC, 0x06},
+	{0x35FD, 0x03},
+	{0x35FE, 0x06},
+	{0x35FF, 0x04},
+	{0x35C2, 0x1F},
+	{0x35C3, 0xFF},
+	{0x35C4, 0x1F},
+	{0x35C5, 0xC0},
+	{0x35C0, 0x01},
+};
+
+struct vx6953_format {
+	enum v4l2_mbus_pixelcode code;
+	enum v4l2_colorspace colorspace;
+	u16 fmt;
+	u16 order;
+};
+
+static const struct vx6953_format vx6953_cfmts[] = {
+	{
+	.code   = V4L2_MBUS_FMT_YUYV8_2X8,
+	.colorspace = V4L2_COLORSPACE_JPEG,
+	.fmt    = 1,
+	.order    = 0,
+	}
+	/* more can be supported, to be added later */
+};
+
+
+/*=============================================================*/
+
+static int vx6953_i2c_rxdata(unsigned short saddr,
+	unsigned char *rxdata, int length)
+{
+	struct i2c_msg msgs[] = {
+		{
+			.addr  = saddr,
+			.flags = 0,
+			.len   = 2,
+			.buf   = rxdata,
+		},
+		{
+			.addr  = saddr,
+			.flags = I2C_M_RD,
+			.len   = 2,
+			.buf   = rxdata,
+		},
+	};
+	if (i2c_transfer(vx6953_client->adapter, msgs, 2) < 0) {
+		CDBG("vx6953_i2c_rxdata failed!\n");
+		return -EIO;
+	}
+	return 0;
+}
+static int32_t vx6953_i2c_txdata(unsigned short saddr,
+				unsigned char *txdata, int length)
+{
+	struct i2c_msg msg[] = {
+		{
+			.addr = saddr,
+			.flags = 0,
+			.len = length,
+			.buf = txdata,
+		 },
+	};
+	if (i2c_transfer(vx6953_client->adapter, msg, 1) < 0) {
+		CDBG("vx6953_i2c_txdata faild 0x%x\n", vx6953_client->addr);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+
+static int32_t vx6953_i2c_read(unsigned short raddr,
+	unsigned short *rdata, int rlen)
+{
+	int32_t rc = 0;
+	unsigned char buf[2];
+	if (!rdata)
+		return -EIO;
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (raddr & 0xFF00) >> 8;
+	buf[1] = (raddr & 0x00FF);
+	rc = vx6953_i2c_rxdata(vx6953_client->addr>>1, buf, rlen);
+	if (rc < 0) {
+		CDBG("vx6953_i2c_read 0x%x failed!\n", raddr);
+		return rc;
+	}
+	*rdata = (rlen == 2 ? buf[0] << 8 | buf[1] : buf[0]);
+	return rc;
+}
+static int32_t vx6953_i2c_write_b_sensor(unsigned short waddr, uint8_t bdata)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[3];
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00) >> 8;
+	buf[1] = (waddr & 0x00FF);
+	buf[2] = bdata;
+	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
+	rc = vx6953_i2c_txdata(vx6953_client->addr>>1, buf, 3);
+	if (rc < 0) {
+		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
+			waddr, bdata);
+	}
+	return rc;
+}
+static int32_t vx6953_i2c_write_seq_sensor(unsigned short waddr,
+	uint8_t *bdata, uint16_t len)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[len+2];
+	int i;
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00) >> 8;
+	buf[1] = (waddr & 0x00FF);
+	for (i = 2; i < len+2; i++)
+		buf[i] = *bdata++;
+	rc = vx6953_i2c_txdata(vx6953_client->addr>>1, buf, len+2);
+	if (rc < 0) {
+		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
+			 waddr, bdata[0]);
+	}
+	return rc;
+}
+
+static int32_t vx6953_i2c_write_w_table(struct vx6953_i2c_reg_conf const
+					 *reg_conf_tbl, int num)
+{
+	int i;
+	int32_t rc = -EIO;
+	for (i = 0; i < num; i++) {
+		rc = vx6953_i2c_write_b_sensor(reg_conf_tbl->waddr,
+			reg_conf_tbl->wdata);
+		if (rc < 0)
+			break;
+		reg_conf_tbl++;
+	}
+	return rc;
+}
+
+static void vx6953_get_pict_fps(uint16_t fps, uint16_t *pfps)
+{
+	/* input fps is preview fps in Q8 format */
+	uint16_t preview_frame_length_lines, snapshot_frame_length_lines;
+	uint16_t preview_line_length_pck, snapshot_line_length_pck;
+	uint32_t divider, d1, d2;
+	/* Total frame_length_lines and line_length_pck for preview */
+	preview_frame_length_lines = VX6953_QTR_SIZE_HEIGHT +
+		VX6953_VER_QTR_BLK_LINES;
+	preview_line_length_pck = VX6953_QTR_SIZE_WIDTH +
+		VX6953_HRZ_QTR_BLK_PIXELS;
+	/* Total frame_length_lines and line_length_pck for snapshot */
+	snapshot_frame_length_lines = VX6953_FULL_SIZE_HEIGHT +
+		VX6953_VER_FULL_BLK_LINES;
+	snapshot_line_length_pck = VX6953_FULL_SIZE_WIDTH +
+		VX6953_HRZ_FULL_BLK_PIXELS;
+	d1 = preview_frame_length_lines * 0x00000400/
+		snapshot_frame_length_lines;
+	d2 = preview_line_length_pck * 0x00000400/
+		snapshot_line_length_pck;
+	divider = d1 * d2 / 0x400;
+	/*Verify PCLK settings and frame sizes.*/
+	*pfps = (uint16_t) (fps * divider / 0x400);
+	/* 2 is the ratio of no.of snapshot channels
+	to number of preview channels */
+
+}
+
+static uint16_t vx6953_get_prev_lines_pf(void)
+{
+	if (vx6953_ctrl->prev_res == QTR_SIZE)
+		return VX6953_QTR_SIZE_HEIGHT + VX6953_VER_QTR_BLK_LINES;
+	else
+		return VX6953_FULL_SIZE_HEIGHT + VX6953_VER_FULL_BLK_LINES;
+
+}
+
+static uint16_t vx6953_get_prev_pixels_pl(void)
+{
+	if (vx6953_ctrl->prev_res == QTR_SIZE)
+		return VX6953_QTR_SIZE_WIDTH + VX6953_HRZ_QTR_BLK_PIXELS;
+	else
+		return VX6953_FULL_SIZE_WIDTH + VX6953_HRZ_FULL_BLK_PIXELS;
+}
+
+static uint16_t vx6953_get_pict_lines_pf(void)
+{
+		if (vx6953_ctrl->pict_res == QTR_SIZE)
+			return VX6953_QTR_SIZE_HEIGHT +
+				VX6953_VER_QTR_BLK_LINES;
+		else
+			return VX6953_FULL_SIZE_HEIGHT +
+				VX6953_VER_FULL_BLK_LINES;
+}
+
+static uint16_t vx6953_get_pict_pixels_pl(void)
+{
+	if (vx6953_ctrl->pict_res == QTR_SIZE)
+		return VX6953_QTR_SIZE_WIDTH +
+			VX6953_HRZ_QTR_BLK_PIXELS;
+	else
+		return VX6953_FULL_SIZE_WIDTH +
+			VX6953_HRZ_FULL_BLK_PIXELS;
+}
+
+static uint32_t vx6953_get_pict_max_exp_lc(void)
+{
+	if (vx6953_ctrl->pict_res == QTR_SIZE)
+		return (VX6953_QTR_SIZE_HEIGHT +
+			VX6953_VER_QTR_BLK_LINES)*24;
+	else
+		return (VX6953_FULL_SIZE_HEIGHT +
+			VX6953_VER_FULL_BLK_LINES)*24;
+}
+
+static int32_t vx6953_set_fps(struct fps_cfg	*fps)
+{
+	uint16_t total_lines_per_frame;
+	int32_t rc = 0;
+	total_lines_per_frame = (uint16_t)((VX6953_QTR_SIZE_HEIGHT +
+		VX6953_VER_QTR_BLK_LINES) * vx6953_ctrl->fps_divider/0x400);
+	if (vx6953_i2c_write_b_sensor(REG_FRAME_LENGTH_LINES_HI,
+		((total_lines_per_frame & 0xFF00) >> 8)) < 0)
+		return rc;
+	if (vx6953_i2c_write_b_sensor(REG_FRAME_LENGTH_LINES_LO,
+		(total_lines_per_frame & 0x00FF)) < 0)
+		return rc;
+	return rc;
+}
+
+static int32_t vx6953_write_exp_gain(uint16_t gain, uint32_t line)
+{
+	uint16_t line_length_pck, frame_length_lines;
+	uint8_t gain_hi, gain_lo;
+	uint8_t intg_time_hi, intg_time_lo;
+	uint8_t line_length_pck_hi = 0, line_length_pck_lo = 0;
+	uint16_t line_length_ratio = 1 * Q8;
+	int32_t rc = 0;
+	if (vx6953_ctrl->sensormode != SENSOR_SNAPSHOT_MODE) {
+		frame_length_lines = VX6953_QTR_SIZE_HEIGHT +
+		VX6953_VER_QTR_BLK_LINES;
+		line_length_pck = VX6953_QTR_SIZE_WIDTH +
+			VX6953_HRZ_QTR_BLK_PIXELS;
+		if (line > (frame_length_lines -
+			VX6953_STM5M0EDOF_OFFSET)) {
+			vx6953_ctrl->fps = (uint16_t) (30 * Q8 *
+			(frame_length_lines - VX6953_STM5M0EDOF_OFFSET)/
+			line);
+		} else {
+			vx6953_ctrl->fps = (uint16_t) (30 * Q8);
+		}
+	} else {
+		frame_length_lines = VX6953_FULL_SIZE_HEIGHT +
+				VX6953_VER_FULL_BLK_LINES;
+		line_length_pck = VX6953_FULL_SIZE_WIDTH +
+				VX6953_HRZ_FULL_BLK_PIXELS;
+	}
+	/* calculate line_length_ratio */
+	if ((frame_length_lines - VX6953_STM5M0EDOF_OFFSET) < line) {
+		line_length_ratio = (line*Q8) /
+			(frame_length_lines - VX6953_STM5M0EDOF_OFFSET);
+		line = frame_length_lines - VX6953_STM5M0EDOF_OFFSET;
+	} else {
+		line_length_ratio = 1*Q8;
+	}
+	vx6953_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
+		GROUPED_PARAMETER_HOLD);
+	line_length_pck = (line_length_pck >
+		MAX_LINE_LENGTH_PCK) ?
+		MAX_LINE_LENGTH_PCK : line_length_pck;
+	line_length_pck = (uint16_t) (line_length_pck *
+		line_length_ratio/Q8);
+	line_length_pck_hi = (uint8_t) ((line_length_pck &
+		0xFF00) >> 8);
+	line_length_pck_lo = (uint8_t) (line_length_pck &
+		0x00FF);
+	vx6953_i2c_write_b_sensor(REG_LINE_LENGTH_PCK_HI,
+		line_length_pck_hi);
+	vx6953_i2c_write_b_sensor(REG_LINE_LENGTH_PCK_LO,
+		line_length_pck_lo);
+	/* update analogue gain registers */
+	gain_hi = (uint8_t) ((gain & 0xFF00) >> 8);
+	gain_lo = (uint8_t) (gain & 0x00FF);
+	vx6953_i2c_write_b_sensor(REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
+		gain_lo);
+	vx6953_i2c_write_b_sensor(REG_DIGITAL_GAIN_GREEN_R_LO, gain_hi);
+	vx6953_i2c_write_b_sensor(REG_DIGITAL_GAIN_RED_LO, gain_hi);
+	vx6953_i2c_write_b_sensor(REG_DIGITAL_GAIN_BLUE_LO, gain_hi);
+	vx6953_i2c_write_b_sensor(REG_DIGITAL_GAIN_GREEN_B_LO, gain_hi);
+	CDBG("%s, gain_hi 0x%x, gain_lo 0x%x\n", __func__,
+		gain_hi, gain_lo);
+	/* update line count registers */
+	intg_time_hi = (uint8_t) (((uint16_t)line & 0xFF00) >> 8);
+	intg_time_lo = (uint8_t) ((uint16_t)line & 0x00FF);
+	vx6953_i2c_write_b_sensor(REG_COARSE_INTEGRATION_TIME_HI,
+		intg_time_hi);
+	vx6953_i2c_write_b_sensor(REG_COARSE_INTEGRATION_TIME_LO,
+		intg_time_lo);
+	vx6953_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
+		GROUPED_PARAMETER_HOLD_OFF);
+
+	return rc;
+}
+
+static int32_t vx6953_set_pict_exp_gain(uint16_t gain, uint32_t line)
+{
+	int32_t rc = 0;
+	rc = vx6953_write_exp_gain(gain, line);
+	return rc;
+} /* endof vx6953_set_pict_exp_gain*/
+
+static int32_t vx6953_move_focus(int direction,
+	int32_t num_steps)
+{
+	return 0;
+}
+
+
+static int32_t vx6953_set_default_focus(uint8_t af_step)
+{
+	return 0;
+}
+
+static int32_t vx6953_test(enum vx6953_test_mode_t mo)
+{
+	int32_t rc = 0;
+	if (mo == TEST_OFF)
+		return rc;
+	else {
+		/* REG_0x30D8[4] is TESBYPEN: 0: Normal Operation,
+		1: Bypass Signal Processing
+		REG_0x30D8[5] is EBDMASK: 0:
+		Output Embedded data, 1: No output embedded data */
+		if (vx6953_i2c_write_b_sensor(REG_TEST_PATTERN_MODE,
+			(uint8_t) mo) < 0) {
+			return rc;
+		}
+	}
+	return rc;
+}
+
+static int vx6953_enable_edof(enum edof_mode_t edof_mode)
+{
+	int rc = 0;
+	if (edof_mode == VX6953_EDOF_ESTIMATION) {
+		/* EDof Estimation mode for preview */
+		if (vx6953_i2c_write_b_sensor(REG_0x0b80, 0x02) < 0)
+			return rc;
+		CDBG("VX6953_EDOF_ESTIMATION");
+	} else if (edof_mode == VX6953_EDOF_APPLICATION) {
+		/* EDof Application mode for Capture */
+		if (vx6953_i2c_write_b_sensor(REG_0x0b80, 0x01) < 0)
+			return rc;
+		CDBG("VX6953_EDOF_APPLICATION");
+	} else {
+		/* EDOF disabled */
+		if (vx6953_i2c_write_b_sensor(REG_0x0b80, 0x00) < 0)
+			return rc;
+		CDBG("VX6953_EDOF_DISABLE");
+	}
+	return rc;
+}
+
+static int32_t vx6953_patch_for_cut2(void)
+{
+	int32_t rc = 0;
+	rc = vx6953_i2c_write_w_table(patch_tbl_cut2,
+		ARRAY_SIZE(patch_tbl_cut2));
+	if (rc < 0)
+		return rc;
+
+	return rc;
+}
+static int32_t vx6953_patch_for_cut3(void)
+{
+	int32_t rc = 0;
+	rc = vx6953_i2c_write_w_table(patch_tbl_cut3,
+		ARRAY_SIZE(patch_tbl_cut3));
+	if (rc < 0)
+		return rc;
+
+	return rc;
+}
+static int32_t vx6953_sensor_setting(int update_type, int rt)
+{
+
+	int32_t rc = 0;
+	unsigned short frame_cnt;
+	struct msm_camera_csi_params vx6953_csi_params;
+	if (vx6953_ctrl->sensor_type != VX6953_STM5M0EDOF_CUT_2) {
+		switch (update_type) {
+		case REG_INIT:
+		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
+			struct vx6953_i2c_reg_conf init_tbl[] = {
+			{REG_0x0112,
+				vx6953_regs.reg_pat_init[0].reg_0x0112},
+			{0x6003, 0x01},
+			{REG_0x0113,
+				vx6953_regs.reg_pat_init[0].reg_0x0113},
+			{REG_VT_PIX_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				vt_pix_clk_div},
+			{REG_PRE_PLL_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				pre_pll_clk_div},
+			{REG_PLL_MULTIPLIER,
+				vx6953_regs.reg_pat_init[0].
+				pll_multiplier},
+			{REG_OP_PIX_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				op_pix_clk_div},
+			{REG_COARSE_INTEGRATION_TIME_HI,
+				vx6953_regs.reg_pat[rt].
+				coarse_integration_time_hi},
+			{REG_COARSE_INTEGRATION_TIME_LO,
+				vx6953_regs.reg_pat[rt].
+				coarse_integration_time_lo},
+			{REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
+				vx6953_regs.reg_pat[rt].
+				analogue_gain_code_global},
+			{REG_0x3030,
+				vx6953_regs.reg_pat_init[0].reg_0x3030},
+			/* 953 specific registers */
+			{REG_0x0111,
+				vx6953_regs.reg_pat_init[0].reg_0x0111},
+			{REG_0x0b00,
+				vx6953_regs.reg_pat_init[0].reg_0x0b00},
+			{REG_0x3001,
+				vx6953_regs.reg_pat_init[0].reg_0x3001},
+			{REG_0x3004,
+				vx6953_regs.reg_pat_init[0].reg_0x3004},
+			{0x3006, 0x00},
+			{REG_0x3007,
+				vx6953_regs.reg_pat_init[0].reg_0x3007},
+			{0x301b, 0x29},
+			/* DEFCOR settings */
+			/*Single Defect Correction Weight DISABLE*/
+			{0x0b06,
+				vx6953_regs.reg_pat_init[0].reg_0x0b06},
+			/*Single_defect_correct_weight = auto*/
+			{0x0b07,
+				vx6953_regs.reg_pat_init[0].reg_0x0b07},
+			/*Dynamic couplet correction ENABLED*/
+			{0x0b08,
+				vx6953_regs.reg_pat_init[0].reg_0x0b08},
+			/*Dynamic couplet correction weight*/
+			{0x0b09,
+				vx6953_regs.reg_pat_init[0].reg_0x0b09},
+			/* Clock Setup */
+			/* Tell sensor ext clk is 24MHz*/
+			{REG_0x0136,
+				vx6953_regs.reg_pat_init[0].reg_0x0136},
+			{REG_0x0137,
+				vx6953_regs.reg_pat_init[0].reg_0x0137},
+			/* The white balance gains must be written
+			to the sensor every frame. */
+			/* Edof */
+			{REG_0x0b83,
+				vx6953_regs.reg_pat_init[0].reg_0x0b83},
+			{REG_0x0b84,
+				vx6953_regs.reg_pat_init[0].reg_0x0b84},
+			{REG_0x0b85,
+				vx6953_regs.reg_pat_init[0].reg_0x0b85},
+			{REG_0x0b88,
+				vx6953_regs.reg_pat_init[0].reg_0x0b88},
+			{REG_0x0b89,
+				vx6953_regs.reg_pat_init[0].reg_0x0b89},
+			{REG_0x0b8a,
+				vx6953_regs.reg_pat_init[0].reg_0x0b8a},
+			/* Mode specific regieters */
+			{REG_FRAME_LENGTH_LINES_HI,
+				vx6953_regs.reg_pat[rt].
+				frame_length_lines_hi},
+			{REG_FRAME_LENGTH_LINES_LO,
+				vx6953_regs.reg_pat[rt].
+				frame_length_lines_lo},
+			{REG_LINE_LENGTH_PCK_HI,
+				vx6953_regs.reg_pat[rt].
+				line_length_pck_hi},
+			{REG_LINE_LENGTH_PCK_LO,
+				vx6953_regs.reg_pat[rt].
+				line_length_pck_lo},
+			{REG_0x3005,
+				vx6953_regs.reg_pat[rt].reg_0x3005},
+			{0x3010,
+				vx6953_regs.reg_pat[rt].reg_0x3010},
+			{REG_0x3011,
+				vx6953_regs.reg_pat[rt].reg_0x3011},
+			{REG_0x301a,
+				vx6953_regs.reg_pat[rt].reg_0x301a},
+			{REG_0x3035,
+				vx6953_regs.reg_pat[rt].reg_0x3035},
+			{REG_0x3036,
+				vx6953_regs.reg_pat[rt].reg_0x3036},
+			{REG_0x3041,
+				vx6953_regs.reg_pat[rt].reg_0x3041},
+			{0x3042,
+				vx6953_regs.reg_pat[rt].reg_0x3042},
+			{REG_0x3045,
+				vx6953_regs.reg_pat[rt].reg_0x3045},
+			/*EDOF: Estimation settings for Preview mode
+			Application settings for capture mode
+			(standard settings - Not tuned) */
+			{REG_0x0b80,
+				vx6953_regs.reg_pat[rt].reg_0x0b80},
+			{REG_0x0900,
+				vx6953_regs.reg_pat[rt].reg_0x0900},
+			{REG_0x0901,
+				vx6953_regs.reg_pat[rt].reg_0x0901},
+			{REG_0x0902,
+				vx6953_regs.reg_pat[rt].reg_0x0902},
+			{REG_0x0383,
+				vx6953_regs.reg_pat[rt].reg_0x0383},
+			{REG_0x0387,
+				vx6953_regs.reg_pat[rt].reg_0x0387},
+			/* Change output size / frame rate */
+			{REG_0x034c,
+				vx6953_regs.reg_pat[rt].reg_0x034c},
+			{REG_0x034d,
+				vx6953_regs.reg_pat[rt].reg_0x034d},
+			{REG_0x034e,
+				vx6953_regs.reg_pat[rt].reg_0x034e},
+			{REG_0x034f,
+				vx6953_regs.reg_pat[rt].reg_0x034f},
+			};
+			/* reset fps_divider */
+			vx6953_ctrl->fps = 30 * Q8;
+			/* stop streaming */
+
+			/* Reset everything first */
+			if (vx6953_i2c_write_b_sensor(0x103, 0x01) < 0) {
+				CDBG("S/W reset failed\n");
+				return rc;
+			} else
+				CDBG("S/W reset successful\n");
+
+			msleep(10);
+
+			CDBG("Init vx6953_sensor_setting standby\n");
+			if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
+				MODE_SELECT_STANDBY_MODE) < 0)
+				return rc;
+			/*vx6953_stm5m0edof_delay_msecs_stdby*/
+			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+
+
+
+			vx6953_patch_for_cut3();
+			rc = vx6953_i2c_write_w_table(&init_tbl[0],
+				ARRAY_SIZE(init_tbl));
+			if (rc < 0)
+				return rc;
+
+			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+
+			vx6953_i2c_write_b_sensor(0x0b80, 0x00);
+			vx6953_i2c_write_b_sensor(0x3388, 0x03);
+			vx6953_i2c_write_b_sensor(0x3640, 0x00);
+
+			rc = vx6953_i2c_write_w_table(&edof_tbl[0],
+				ARRAY_SIZE(edof_tbl));
+			vx6953_i2c_write_b_sensor(0x3388, 0x00);
+
+		}
+		return rc;
+		case UPDATE_PERIODIC:
+		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
+			struct vx6953_i2c_reg_conf preview_mode_tbl[] = {
+			{REG_0x0112,
+				vx6953_regs.reg_pat_init[0].reg_0x0112},
+			{0x6003, 0x01},
+			{REG_0x0113,
+				vx6953_regs.reg_pat_init[0].reg_0x0113},
+			{REG_VT_PIX_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				vt_pix_clk_div},
+			{REG_PRE_PLL_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				pre_pll_clk_div},
+			{REG_PLL_MULTIPLIER,
+				vx6953_regs.reg_pat_init[0].
+				pll_multiplier},
+			{REG_OP_PIX_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				op_pix_clk_div},
+
+			{REG_COARSE_INTEGRATION_TIME_HI,
+				vx6953_regs.reg_pat[rt].
+				coarse_integration_time_hi},
+			{REG_COARSE_INTEGRATION_TIME_LO,
+				vx6953_regs.reg_pat[rt].
+				coarse_integration_time_lo},
+			{REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
+				vx6953_regs.reg_pat[rt].
+				analogue_gain_code_global},
+
+			{REG_0x3210, vx6953_regs.reg_pat[rt].reg_0x3210},
+			{REG_0x0111, vx6953_regs.reg_pat[rt].reg_0x111},
+			{REG_0x3410, vx6953_regs.reg_pat[rt].reg_0x3410},
+
+			{REG_0x3004,
+				vx6953_regs.reg_pat_init[0].reg_0x3004},
+			{REG_0x3006, 0x00},
+			{REG_0x3007,
+				vx6953_regs.reg_pat_init[0].reg_0x3007},
+			{REG_0x301b, 0x29},
+			{REG_0x3036,
+				vx6953_regs.reg_pat[rt].reg_0x3036},
+			{REG_0x3045, vx6953_regs.reg_pat[rt].reg_0x3045},
+			{REG_0x3098, vx6953_regs.reg_pat[rt].reg_0x3098},
+			{REG_0x309d, vx6953_regs.reg_pat[rt].reg_0x309D},
+
+			{REG_0x0900, vx6953_regs.reg_pat[rt].reg_0x0900},
+			{REG_0x0901, vx6953_regs.reg_pat[rt].reg_0x0901},
+			{REG_0x0902, vx6953_regs.reg_pat[rt].reg_0x0902},
+			{REG_0x0383, vx6953_regs.reg_pat[rt].reg_0x0383},
+			{REG_0x0387, vx6953_regs.reg_pat[rt].reg_0x0387},
+
+			{REG_FRAME_LENGTH_LINES_HI,
+				vx6953_regs.reg_pat[rt].
+				frame_length_lines_hi},
+			{REG_FRAME_LENGTH_LINES_LO,
+				vx6953_regs.reg_pat[rt].
+				frame_length_lines_lo},
+			{REG_LINE_LENGTH_PCK_HI,
+				vx6953_regs.reg_pat[rt].
+				line_length_pck_hi},
+			{REG_LINE_LENGTH_PCK_LO,
+				vx6953_regs.reg_pat[rt].
+				line_length_pck_lo},
+			{REG_0x034c,
+				vx6953_regs.reg_pat[rt].reg_0x034c},
+			{REG_0x034d,
+				vx6953_regs.reg_pat[rt].reg_0x034d},
+			{REG_0x034e,
+				vx6953_regs.reg_pat[rt].reg_0x034e},
+			{REG_0x034f,
+				vx6953_regs.reg_pat[rt].reg_0x034f},
+
+			{REG_0x3005, vx6953_regs.reg_pat[rt].reg_0x3005},
+			{REG_0x3010, vx6953_regs.reg_pat[rt].reg_0x3010},
+			{REG_0x3011, vx6953_regs.reg_pat[rt].reg_0x3011},
+			{REG_0x301a, vx6953_regs.reg_pat[rt].reg_0x301a},
+			{REG_0x3030, 0x08},
+			{REG_0x3035, vx6953_regs.reg_pat[rt].reg_0x3035},
+			{REG_0x3041, vx6953_regs.reg_pat[rt].reg_0x3041},
+			{0x3042, vx6953_regs.reg_pat[rt].reg_0x3042},
+
+			{0x200, vx6953_regs.reg_pat[rt].reg_0x0200},
+			{0x201, vx6953_regs.reg_pat[rt].reg_0x0201},
+
+			{0x0b06,
+				vx6953_regs.reg_pat_init[0].reg_0x0b06},
+			/*Single_defect_correct_weight = auto*/
+			{0x0b07,
+				vx6953_regs.reg_pat_init[0].reg_0x0b07},
+			/*Dynamic couplet correction ENABLED*/
+			{0x0b08,
+				vx6953_regs.reg_pat_init[0].reg_0x0b08},
+			/*Dynamic couplet correction weight*/
+			{0x0b09,
+				vx6953_regs.reg_pat_init[0].reg_0x0b09},
+
+			{REG_0x0136,
+				vx6953_regs.reg_pat_init[0].reg_0x0136},
+			{REG_0x0137,
+				vx6953_regs.reg_pat_init[0].reg_0x0137},
+
+			/*EDOF: Estimation settings for Preview mode
+			Application settings for capture
+			mode(standard settings - Not tuned) */
+			{REG_0x0b80, vx6953_regs.reg_pat[rt].reg_0x0b80},
+			{REG_0x0b83,
+				vx6953_regs.reg_pat_init[0].reg_0x0b83},
+			{REG_0x0b84,
+				vx6953_regs.reg_pat_init[0].reg_0x0b84},
+			{REG_0x0b85,
+				vx6953_regs.reg_pat_init[0].reg_0x0b85},
+			{REG_0x0b88,
+				vx6953_regs.reg_pat_init[0].reg_0x0b88},
+			{REG_0x0b89,
+				vx6953_regs.reg_pat_init[0].reg_0x0b89},
+			{REG_0x0b8a,
+				vx6953_regs.reg_pat_init[0].reg_0x0b8a},
+			{0x3393, 0x06}, /* man_spec_edof_ctrl_edof*/
+			{0x3394, 0x07}, /* man_spec_edof_ctrl_edof*/
+			};
+
+			struct vx6953_i2c_reg_conf snapshot_mode_tbl[] = {
+			{REG_MODE_SELECT,	MODE_SELECT_STANDBY_MODE},
+			{REG_0x0112,
+				vx6953_regs.reg_pat_init[0].reg_0x0112},
+			{0x6003, 0x01},
+			{REG_0x0113,
+				vx6953_regs.reg_pat_init[0].reg_0x0113},
+			{REG_VT_PIX_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				vt_pix_clk_div},
+			{0x303,	1}, /* VT_SYS_CLK_DIV */
+			{REG_PRE_PLL_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				pre_pll_clk_div},
+			{REG_PLL_MULTIPLIER,
+				vx6953_regs.reg_pat_init[0].
+				pll_multiplier},
+			{REG_OP_PIX_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				op_pix_clk_div},
+			{0x30b,	1},
+			{REG_COARSE_INTEGRATION_TIME_HI,
+				vx6953_regs.reg_pat[rt].
+				coarse_integration_time_hi},
+			{REG_COARSE_INTEGRATION_TIME_LO,
+				vx6953_regs.reg_pat[rt].
+				coarse_integration_time_lo},
+			{REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
+				vx6953_regs.reg_pat[rt].
+				analogue_gain_code_global},
+			{REG_LINE_LENGTH_PCK_HI,
+				vx6953_regs.reg_pat[rt].
+				line_length_pck_hi},
+			{REG_LINE_LENGTH_PCK_LO,
+				vx6953_regs.reg_pat[rt].
+				line_length_pck_lo},
+			{REG_FRAME_LENGTH_LINES_HI,
+				vx6953_regs.reg_pat[rt].
+				frame_length_lines_hi},
+			{REG_FRAME_LENGTH_LINES_LO,
+				vx6953_regs.reg_pat[rt].
+				frame_length_lines_lo},
+			{REG_0x3210, vx6953_regs.reg_pat[rt].reg_0x3210},
+			{REG_0x0111, vx6953_regs.reg_pat[rt].reg_0x111},
+
+			{REG_0x0b00,
+				vx6953_regs.reg_pat_init[0].reg_0x0b00},
+			{0x3140, 0x01},  /* AV2X2 block enabled */
+			{REG_0x3410, vx6953_regs.reg_pat[rt].reg_0x3410},
+			{0x0b06,
+				vx6953_regs.reg_pat_init[0].reg_0x0b06},
+			/*Single_defect_correct_weight = auto*/
+			{0x0b07,
+				vx6953_regs.reg_pat_init[0].reg_0x0b07},
+			/*Dynamic couplet correction ENABLED*/
+			{0x0b08,
+				vx6953_regs.reg_pat_init[0].reg_0x0b08},
+			/*Dynamic couplet correction weight*/
+			{0x0b09,
+				vx6953_regs.reg_pat_init[0].reg_0x0b09},
+
+
+			{REG_0x3004,
+				vx6953_regs.reg_pat_init[0].reg_0x3004},
+			{REG_0x3006, 0x00},
+			{REG_0x3007,
+				vx6953_regs.reg_pat_init[0].reg_0x3007},
+			{0x301A, 0x6A},
+			{REG_0x301b, 0x29},
+			{REG_0x3036,
+				vx6953_regs.reg_pat[rt].reg_0x3036},
+			{REG_0x3045, vx6953_regs.reg_pat[rt].reg_0x3045},
+			{REG_0x3098, vx6953_regs.reg_pat[rt].reg_0x3098},
+			{REG_0x309d, vx6953_regs.reg_pat[rt].reg_0x309D},
+
+			{REG_0x0136,
+				vx6953_regs.reg_pat_init[0].reg_0x0136},
+			{REG_0x0137,
+				vx6953_regs.reg_pat_init[0].reg_0x0137},
+
+			{REG_0x0b80, vx6953_regs.reg_pat[rt].reg_0x0b80},
+			{REG_0x0b83,
+				vx6953_regs.reg_pat_init[0].reg_0x0b83},
+			{REG_0x0b84,
+				vx6953_regs.reg_pat_init[0].reg_0x0b84},
+			{REG_0x0b85,
+				vx6953_regs.reg_pat_init[0].reg_0x0b85},
+			{REG_0x0b88,
+				vx6953_regs.reg_pat_init[0].reg_0x0b88},
+			{REG_0x0b89,
+				vx6953_regs.reg_pat_init[0].reg_0x0b89},
+			{REG_0x0b8a,
+				vx6953_regs.reg_pat_init[0].reg_0x0b8a},
+			{0x3393, 0x06}, /* man_spec_edof_ctrl*/
+			{0x3394, 0x07}, /* man_spec_edof_ctrl*/
+			};
+			/* stop streaming */
+			msleep(5);
+
+			/* Reset everything first */
+
+			if (vx6953_i2c_write_b_sensor(0x103, 0x01) < 0) {
+				CDBG("S/W reset failed\n");
+				return rc;
+			} else
+				CDBG("S/W reset successful\n");
+
+			msleep(10);
+
+			if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
+				MODE_SELECT_STANDBY_MODE) < 0)
+				return rc;
+			/*vx6953_stm5m0edof_delay_msecs_stdby*/
+			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+
+			vx6953_csi_params.data_format = CSI_8BIT;
+			vx6953_csi_params.lane_cnt = 1;
+			vx6953_csi_params.lane_assign = 0xe4;
+			vx6953_csi_params.dpcm_scheme = 0;
+			vx6953_csi_params.settle_cnt = 7;
+			rc = msm_camio_csi_config(&vx6953_csi_params);
+			if (rc < 0)
+				CDBG(" config csi controller failed\n");
+
+			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+
+			vx6953_patch_for_cut3();
+
+			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+
+			if (rt == RES_PREVIEW) {
+				rc = vx6953_i2c_write_w_table(
+					&preview_mode_tbl[0],
+					ARRAY_SIZE(preview_mode_tbl));
+				if (rc < 0)
+					return rc;
+			}
+			if (rt == RES_CAPTURE) {
+				rc = vx6953_i2c_write_w_table(
+					&snapshot_mode_tbl[0],
+					ARRAY_SIZE(snapshot_mode_tbl));
+				if (rc < 0)
+					return rc;
+			}
+			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+
+			/* Start sensor streaming */
+			if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
+				MODE_SELECT_STREAM) < 0)
+				return rc;
+			msleep(vx6953_stm5m0edof_delay_msecs_stream);
+			/* man_spec_edof_ctrl_tune_smooth_lowlight*/
+			vx6953_i2c_write_b_sensor(0x338d, 0x08);
+			/* man_spec_edof_ctrl_tune_smooth_indoor*/
+			vx6953_i2c_write_b_sensor(0x338e, 0x08);
+			/* man_spec_edof_ctrl_tune_smooth_outdoor*/
+			vx6953_i2c_write_b_sensor(0x338f, 0x00);
+			/*Apply Capture FPGA state machine reset*/
+			vx6953_i2c_write_b_sensor(0x16, 0x00);
+			msleep(100);
+			vx6953_i2c_write_b_sensor(0x16, 0x01);
+
+			if (vx6953_i2c_read(0x0005, &frame_cnt, 1) < 0)
+				return rc;
+
+			while (frame_cnt == 0xFF) {
+				if (vx6953_i2c_read(0x0005, &frame_cnt, 1) < 0)
+					return rc;
+				CDBG("frame_cnt=%d", frame_cnt);
+				msleep(10);
+			}
+		}
+		return rc;
+		default:
+			return rc;
+		}
+	} else {
+		switch (update_type) {
+		case REG_INIT:
+		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
+			struct vx6953_i2c_reg_conf init_tbl[] = {
+			{REG_0x0112,
+				vx6953_regs.reg_pat_init[0].reg_0x0112},
+			{REG_0x0113,
+				vx6953_regs.reg_pat_init[0].reg_0x0113},
+			{REG_VT_PIX_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				vt_pix_clk_div},
+			{REG_PRE_PLL_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				pre_pll_clk_div},
+			{REG_PLL_MULTIPLIER,
+				vx6953_regs.reg_pat_init[0].
+				pll_multiplier},
+			{REG_OP_PIX_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				op_pix_clk_div},
+			{REG_COARSE_INTEGRATION_TIME_HI,
+				vx6953_regs.reg_pat[rt].
+				coarse_integration_time_hi},
+			{REG_COARSE_INTEGRATION_TIME_LO,
+				vx6953_regs.reg_pat[rt].
+				coarse_integration_time_lo},
+			{REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
+				vx6953_regs.reg_pat[rt].
+				analogue_gain_code_global},
+			{REG_0x3030,
+				vx6953_regs.reg_pat_init[0].reg_0x3030},
+			/* 953 specific registers */
+			{REG_0x0111,
+				vx6953_regs.reg_pat_init[0].reg_0x0111},
+			{REG_0x0b00,
+				vx6953_regs.reg_pat_init[0].reg_0x0b00},
+			{REG_0x3001,
+				vx6953_regs.reg_pat_init[0].reg_0x3001},
+			{REG_0x3004,
+				vx6953_regs.reg_pat_init[0].reg_0x3004},
+			{REG_0x3007,
+				vx6953_regs.reg_pat_init[0].reg_0x3007},
+			{REG_0x3016,
+				vx6953_regs.reg_pat_init[0].reg_0x3016},
+			{REG_0x301d,
+				vx6953_regs.reg_pat_init[0].reg_0x301d},
+			{REG_0x317e,
+				vx6953_regs.reg_pat_init[0].reg_0x317e},
+			{REG_0x317f,
+				vx6953_regs.reg_pat_init[0].reg_0x317f},
+			{REG_0x3400,
+				vx6953_regs.reg_pat_init[0].reg_0x3400},
+			/* DEFCOR settings */
+			/*Single Defect Correction Weight DISABLE*/
+			{0x0b06,
+				vx6953_regs.reg_pat_init[0].reg_0x0b06},
+			/*Single_defect_correct_weight = auto*/
+			{0x0b07,
+				vx6953_regs.reg_pat_init[0].reg_0x0b07},
+			/*Dynamic couplet correction ENABLED*/
+			{0x0b08,
+				vx6953_regs.reg_pat_init[0].reg_0x0b08},
+			/*Dynamic couplet correction weight*/
+			{0x0b09,
+				vx6953_regs.reg_pat_init[0].reg_0x0b09},
+			/* Clock Setup */
+			/* Tell sensor ext clk is 24MHz*/
+			{0x0136,
+				vx6953_regs.reg_pat_init[0].reg_0x0136},
+			{0x0137,
+				vx6953_regs.reg_pat_init[0].reg_0x0137},
+			/* The white balance gains must be written
+			to the sensor every frame. */
+			/* Edof */
+			{REG_0x0b83,
+				vx6953_regs.reg_pat_init[0].reg_0x0b83},
+			{REG_0x0b84,
+				vx6953_regs.reg_pat_init[0].reg_0x0b84},
+			{0x0b85,
+				vx6953_regs.reg_pat_init[0].reg_0x0b85},
+			{0x0b88,
+				vx6953_regs.reg_pat_init[0].reg_0x0b88},
+			{0x0b89,
+				vx6953_regs.reg_pat_init[0].reg_0x0b89},
+			{REG_0x0b8a,
+				vx6953_regs.reg_pat_init[0].reg_0x0b8a},
+			/* Mode specific regieters */
+			{REG_FRAME_LENGTH_LINES_HI,
+				vx6953_regs.reg_pat[rt].
+				frame_length_lines_hi},
+			{REG_FRAME_LENGTH_LINES_LO,
+				vx6953_regs.reg_pat[rt].
+				frame_length_lines_lo},
+			{REG_LINE_LENGTH_PCK_HI,
+				vx6953_regs.reg_pat[rt].
+				line_length_pck_hi},
+			{REG_LINE_LENGTH_PCK_LO,
+				vx6953_regs.reg_pat[rt].
+				line_length_pck_lo},
+			{REG_0x3005,
+				vx6953_regs.reg_pat[rt].reg_0x3005},
+			{0x3010,
+				vx6953_regs.reg_pat[rt].reg_0x3010},
+			{REG_0x3011,
+				vx6953_regs.reg_pat[rt].reg_0x3011},
+			{REG_0x301a,
+				vx6953_regs.reg_pat[rt].reg_0x301a},
+			{REG_0x3035,
+				vx6953_regs.reg_pat[rt].reg_0x3035},
+			{REG_0x3036,
+				vx6953_regs.reg_pat[rt].reg_0x3036},
+			{REG_0x3041,
+				vx6953_regs.reg_pat[rt].reg_0x3041},
+			{0x3042,
+				vx6953_regs.reg_pat[rt].reg_0x3042},
+			{REG_0x3045,
+				vx6953_regs.reg_pat[rt].reg_0x3045},
+			/*EDOF: Estimation settings for Preview mode
+			Application settings for capture mode
+			(standard settings - Not tuned) */
+			{REG_0x0b80,
+				vx6953_regs.reg_pat[rt].reg_0x0b80},
+			{REG_0x0900,
+				vx6953_regs.reg_pat[rt].reg_0x0900},
+			{REG_0x0901,
+				vx6953_regs.reg_pat[rt].reg_0x0901},
+			{REG_0x0902,
+				vx6953_regs.reg_pat[rt].reg_0x0902},
+			{REG_0x0383,
+				vx6953_regs.reg_pat[rt].reg_0x0383},
+			{REG_0x0387,
+				vx6953_regs.reg_pat[rt].reg_0x0387},
+			/* Change output size / frame rate */
+			{REG_0x034c,
+				vx6953_regs.reg_pat[rt].reg_0x034c},
+			{REG_0x034d,
+				vx6953_regs.reg_pat[rt].reg_0x034d},
+			{REG_0x034e,
+				vx6953_regs.reg_pat[rt].reg_0x034e},
+			{REG_0x034f,
+				vx6953_regs.reg_pat[rt].reg_0x034f},
+			{REG_0x1716,
+				vx6953_regs.reg_pat[rt].reg_0x1716},
+			{REG_0x1717,
+				vx6953_regs.reg_pat[rt].reg_0x1717},
+			{REG_0x1718,
+				vx6953_regs.reg_pat[rt].reg_0x1718},
+			{REG_0x1719,
+				vx6953_regs.reg_pat[rt].reg_0x1719},
+			};
+			/* reset fps_divider */
+			vx6953_ctrl->fps = 30 * Q8;
+			/* stop streaming */
+
+			/* Reset everything first */
+			if (vx6953_i2c_write_b_sensor(0x103, 0x01) < 0) {
+				CDBG("S/W reset failed\n");
+				return rc;
+			} else
+				CDBG("S/W reset successful\n");
+
+			msleep(10);
+
+			CDBG("Init vx6953_sensor_setting standby\n");
+			if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
+				MODE_SELECT_STANDBY_MODE) < 0)
+				return rc;
+				/*vx6953_stm5m0edof_delay_msecs_stdby*/
+			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+			vx6953_patch_for_cut2();
+			rc = vx6953_i2c_write_w_table(&init_tbl[0],
+				ARRAY_SIZE(init_tbl));
+			if (rc < 0)
+				return rc;
+				msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+		}
+		return rc;
+		case UPDATE_PERIODIC:
+		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
+			struct vx6953_i2c_reg_conf init_mode_tbl[] =  {
+			{REG_0x0112,
+				vx6953_regs.reg_pat_init[0].reg_0x0112},
+			{REG_0x0113,
+				vx6953_regs.reg_pat_init[0].reg_0x0113},
+			{REG_VT_PIX_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				vt_pix_clk_div},
+			{REG_PRE_PLL_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				pre_pll_clk_div},
+			{REG_PLL_MULTIPLIER,
+				vx6953_regs.reg_pat_init[0].
+				pll_multiplier},
+			{REG_OP_PIX_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				op_pix_clk_div},
+			{REG_COARSE_INTEGRATION_TIME_HI,
+				vx6953_regs.reg_pat[rt].
+				coarse_integration_time_hi},
+			{REG_COARSE_INTEGRATION_TIME_LO,
+				vx6953_regs.reg_pat[rt].
+				coarse_integration_time_lo},
+			{REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
+				vx6953_regs.reg_pat[rt].
+				analogue_gain_code_global},
+			{REG_0x3030,
+				vx6953_regs.reg_pat_init[0].reg_0x3030},
+			/* 953 specific registers */
+			{REG_0x0111,
+				vx6953_regs.reg_pat_init[0].reg_0x0111},
+			{REG_0x0b00,
+				vx6953_regs.reg_pat_init[0].reg_0x0b00},
+			{REG_0x3001,
+				vx6953_regs.reg_pat_init[0].reg_0x3001},
+			{REG_0x3004,
+				vx6953_regs.reg_pat_init[0].reg_0x3004},
+			{REG_0x3007,
+				vx6953_regs.reg_pat_init[0].reg_0x3007},
+			{REG_0x3016,
+				vx6953_regs.reg_pat_init[0].reg_0x3016},
+			{REG_0x301d,
+				vx6953_regs.reg_pat_init[0].reg_0x301d},
+			{REG_0x317e,
+				vx6953_regs.reg_pat_init[0].reg_0x317e},
+			{REG_0x317f,
+				vx6953_regs.reg_pat_init[0].reg_0x317f},
+			{REG_0x3400,
+				vx6953_regs.reg_pat_init[0].reg_0x3400},
+			{0x0b06,
+				vx6953_regs.reg_pat_init[0].reg_0x0b06},
+			/*Single_defect_correct_weight = auto*/
+			{0x0b07,
+				vx6953_regs.reg_pat_init[0].reg_0x0b07},
+			/*Dynamic couplet correction ENABLED*/
+			{0x0b08,
+				vx6953_regs.reg_pat_init[0].reg_0x0b08},
+			/*Dynamic couplet correction weight*/
+			{0x0b09,
+				vx6953_regs.reg_pat_init[0].reg_0x0b09},
+			/* Clock Setup */
+			/* Tell sensor ext clk is 24MHz*/
+			{0x0136,
+				vx6953_regs.reg_pat_init[0].reg_0x0136},
+			{0x0137,
+				vx6953_regs.reg_pat_init[0].reg_0x0137},
+			/* The white balance gains must be written
+			to the sensor every frame. */
+			/* Edof */
+			{REG_0x0b83,
+				vx6953_regs.reg_pat_init[0].reg_0x0b83},
+			{REG_0x0b84,
+				vx6953_regs.reg_pat_init[0].reg_0x0b84},
+			{0x0b85,
+				vx6953_regs.reg_pat_init[0].reg_0x0b85},
+			{0x0b88,
+				vx6953_regs.reg_pat_init[0].reg_0x0b88},
+			{0x0b89,
+				vx6953_regs.reg_pat_init[0].reg_0x0b89},
+			{REG_0x0b8a,
+				vx6953_regs.reg_pat_init[0].reg_0x0b8a},
+			/* Mode specific regieters */
+			{REG_FRAME_LENGTH_LINES_HI,
+				vx6953_regs.reg_pat[rt].
+				frame_length_lines_hi},
+			{REG_FRAME_LENGTH_LINES_LO,
+				vx6953_regs.reg_pat[rt].
+				frame_length_lines_lo},
+			{REG_LINE_LENGTH_PCK_HI,
+				vx6953_regs.reg_pat[rt].
+				line_length_pck_hi},
+			{REG_LINE_LENGTH_PCK_LO,
+				vx6953_regs.reg_pat[rt].
+				line_length_pck_lo},
+			{REG_0x3005,
+				vx6953_regs.reg_pat[rt].reg_0x3005},
+			{0x3010,
+				vx6953_regs.reg_pat[rt].reg_0x3010},
+			{REG_0x3011,
+				vx6953_regs.reg_pat[rt].reg_0x3011},
+			{REG_0x301a,
+				vx6953_regs.reg_pat[rt].reg_0x301a},
+			{REG_0x3035,
+				vx6953_regs.reg_pat[rt].reg_0x3035},
+			{REG_0x3036,
+				vx6953_regs.reg_pat[rt].reg_0x3036},
+			{REG_0x3041,
+				vx6953_regs.reg_pat[rt].reg_0x3041},
+			{0x3042,
+				vx6953_regs.reg_pat[rt].reg_0x3042},
+			{REG_0x3045,
+				vx6953_regs.reg_pat[rt].reg_0x3045},
+			/*EDOF: Estimation settings for Preview mode
+			Application settings for capture mode
+			(standard settings - Not tuned) */
+			{REG_0x0b80,
+				vx6953_regs.reg_pat[rt].reg_0x0b80},
+			{REG_0x0900,
+				vx6953_regs.reg_pat[rt].reg_0x0900},
+			{REG_0x0901,
+				vx6953_regs.reg_pat[rt].reg_0x0901},
+			{REG_0x0902,
+				vx6953_regs.reg_pat[rt].reg_0x0902},
+			{REG_0x0383,
+				vx6953_regs.reg_pat[rt].reg_0x0383},
+			{REG_0x0387,
+				vx6953_regs.reg_pat[rt].reg_0x0387},
+			/* Change output size / frame rate */
+			{REG_0x034c,
+				vx6953_regs.reg_pat[rt].reg_0x034c},
+			{REG_0x034d,
+				vx6953_regs.reg_pat[rt].reg_0x034d},
+			{REG_0x034e,
+				vx6953_regs.reg_pat[rt].reg_0x034e},
+			{REG_0x034f,
+				vx6953_regs.reg_pat[rt].reg_0x034f},
+			{REG_0x1716,
+				vx6953_regs.reg_pat[rt].reg_0x1716},
+			{REG_0x1717,
+				vx6953_regs.reg_pat[rt].reg_0x1717},
+			{REG_0x1718,
+				vx6953_regs.reg_pat[rt].reg_0x1718},
+			{REG_0x1719,
+				vx6953_regs.reg_pat[rt].reg_0x1719},
+			};
+			struct vx6953_i2c_reg_conf mode_tbl[] = {
+			{REG_0x0112,
+				vx6953_regs.reg_pat_init[0].reg_0x0112},
+			{REG_0x0113,
+				vx6953_regs.reg_pat_init[0].reg_0x0113},
+			{REG_VT_PIX_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				vt_pix_clk_div},
+			{REG_PRE_PLL_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				pre_pll_clk_div},
+			{REG_PLL_MULTIPLIER,
+				vx6953_regs.reg_pat_init[0].
+				pll_multiplier},
+			{REG_OP_PIX_CLK_DIV,
+				vx6953_regs.reg_pat_init[0].
+				op_pix_clk_div},
+		/* Mode specific regieters */
+			{REG_FRAME_LENGTH_LINES_HI,
+				vx6953_regs.reg_pat[rt].frame_length_lines_hi},
+			{REG_FRAME_LENGTH_LINES_LO,
+				vx6953_regs.reg_pat[rt].frame_length_lines_lo},
+			{REG_LINE_LENGTH_PCK_HI,
+				vx6953_regs.reg_pat[rt].line_length_pck_hi},
+			{REG_LINE_LENGTH_PCK_LO,
+				vx6953_regs.reg_pat[rt].line_length_pck_lo},
+			{REG_0x3005, vx6953_regs.reg_pat[rt].reg_0x3005},
+			{0x3010, vx6953_regs.reg_pat[rt].reg_0x3010},
+			{REG_0x3011, vx6953_regs.reg_pat[rt].reg_0x3011},
+			{REG_0x301a, vx6953_regs.reg_pat[rt].reg_0x301a},
+			{REG_0x3035, vx6953_regs.reg_pat[rt].reg_0x3035},
+			{REG_0x3036, vx6953_regs.reg_pat[rt].reg_0x3036},
+			{REG_0x3041, vx6953_regs.reg_pat[rt].reg_0x3041},
+			{0x3042, vx6953_regs.reg_pat[rt].reg_0x3042},
+			{REG_0x3045, vx6953_regs.reg_pat[rt].reg_0x3045},
+			/*EDOF: Estimation settings for Preview mode
+			Application settings for capture
+			mode(standard settings - Not tuned) */
+			{REG_0x0b80, vx6953_regs.reg_pat[rt].reg_0x0b80},
+			{REG_0x0900, vx6953_regs.reg_pat[rt].reg_0x0900},
+			{REG_0x0901, vx6953_regs.reg_pat[rt].reg_0x0901},
+			{REG_0x0902, vx6953_regs.reg_pat[rt].reg_0x0902},
+			{REG_0x0383, vx6953_regs.reg_pat[rt].reg_0x0383},
+			{REG_0x0387, vx6953_regs.reg_pat[rt].reg_0x0387},
+			/* Change output size / frame rate */
+			{REG_0x034c, vx6953_regs.reg_pat[rt].reg_0x034c},
+			{REG_0x034d, vx6953_regs.reg_pat[rt].reg_0x034d},
+			{REG_0x034e, vx6953_regs.reg_pat[rt].reg_0x034e},
+			{REG_0x034f, vx6953_regs.reg_pat[rt].reg_0x034f},
+			/*{0x200, vx6953_regs.reg_pat[rt].reg_0x0200},
+			{0x201, vx6953_regs.reg_pat[rt].reg_0x0201},*/
+			{REG_0x1716, vx6953_regs.reg_pat[rt].reg_0x1716},
+			{REG_0x1717, vx6953_regs.reg_pat[rt].reg_0x1717},
+			{REG_0x1718, vx6953_regs.reg_pat[rt].reg_0x1718},
+			{REG_0x1719, vx6953_regs.reg_pat[rt].reg_0x1719},
+			};
+			/* stop streaming */
+			msleep(5);
+
+			/* Reset everything first */
+			if (vx6953_i2c_write_b_sensor(0x103, 0x01) < 0) {
+				CDBG("S/W reset failed\n");
+				return rc;
+			} else
+				CDBG("S/W reset successful\n");
+
+			msleep(10);
+
+			if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
+				MODE_SELECT_STANDBY_MODE) < 0)
+				return rc;
+			/*vx6953_stm5m0edof_delay_msecs_stdby*/
+			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+
+			vx6953_csi_params.data_format = CSI_8BIT;
+			vx6953_csi_params.lane_cnt = 1;
+			vx6953_csi_params.lane_assign = 0xe4;
+			vx6953_csi_params.dpcm_scheme = 0;
+			vx6953_csi_params.settle_cnt = 7;
+			rc = msm_camio_csi_config(&vx6953_csi_params);
+			if (rc < 0)
+				CDBG(" config csi controller failed\n");
+
+			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+
+			vx6953_patch_for_cut2();
+			rc = vx6953_i2c_write_w_table(&init_mode_tbl[0],
+				ARRAY_SIZE(init_mode_tbl));
+			if (rc < 0)
+				return rc;
+
+			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+
+			rc = vx6953_i2c_write_w_table(&mode_tbl[0],
+				ARRAY_SIZE(mode_tbl));
+			if (rc < 0)
+				return rc;
+
+			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+
+			/* Start sensor streaming */
+			if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
+				MODE_SELECT_STREAM) < 0)
+				return rc;
+			msleep(vx6953_stm5m0edof_delay_msecs_stream);
+
+			if (vx6953_i2c_read(0x0005, &frame_cnt, 1) < 0)
+				return rc;
+
+			while (frame_cnt == 0xFF) {
+				if (vx6953_i2c_read(0x0005, &frame_cnt, 1) < 0)
+					return rc;
+				CDBG("frame_cnt=%d", frame_cnt);
+				msleep(10);
+			}
+		}
+		return rc;
+		default:
+		return rc;
+	}
+	}
+	return rc;
+}
+
+
+static int32_t vx6953_video_config(int mode)
+{
+
+	int32_t	rc = 0;
+	int	rt;
+	/* change sensor resolution	if needed */
+	if (vx6953_ctrl->prev_res == QTR_SIZE) {
+		rt = RES_PREVIEW;
+		vx6953_stm5m0edof_delay_msecs_stdby	=
+			((((2 * 1000 * vx6953_ctrl->fps_divider) /
+			vx6953_ctrl->fps) * Q8) / Q10) + 1;
+	} else {
+		rt = RES_CAPTURE;
+		vx6953_stm5m0edof_delay_msecs_stdby	=
+			((((1000 * vx6953_ctrl->fps_divider) /
+			vx6953_ctrl->fps) * Q8) / Q10) + 1;
+	}
+	if (vx6953_sensor_setting(UPDATE_PERIODIC, rt) < 0)
+		return rc;
+	if (vx6953_ctrl->set_test) {
+		if (vx6953_test(vx6953_ctrl->set_test) < 0)
+			return	rc;
+	}
+	vx6953_ctrl->edof_mode = VX6953_EDOF_ESTIMATION;
+	rc = vx6953_enable_edof(vx6953_ctrl->edof_mode);
+	if (rc < 0)
+		return rc;
+	vx6953_ctrl->curr_res = vx6953_ctrl->prev_res;
+	vx6953_ctrl->sensormode = mode;
+	return rc;
+}
+
+static int32_t vx6953_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+	int rt;
+	/*change sensor resolution if needed */
+	if (vx6953_ctrl->curr_res != vx6953_ctrl->pict_res) {
+		if (vx6953_ctrl->pict_res == QTR_SIZE) {
+			rt = RES_PREVIEW;
+			vx6953_stm5m0edof_delay_msecs_stdby =
+				((((2 * 1000 * vx6953_ctrl->fps_divider) /
+				vx6953_ctrl->fps) * Q8) / Q10) + 1;
+		} else {
+			rt = RES_CAPTURE;
+			vx6953_stm5m0edof_delay_msecs_stdby =
+				((((1000 * vx6953_ctrl->fps_divider) /
+				vx6953_ctrl->fps) * Q8) / Q10) + 1;
+		}
+	if (vx6953_sensor_setting(UPDATE_PERIODIC, rt) < 0)
+		return rc;
+	}
+
+	vx6953_ctrl->edof_mode = VX6953_EDOF_APPLICATION;
+	if (vx6953_enable_edof(vx6953_ctrl->edof_mode) < 0)
+		return rc;
+	vx6953_ctrl->curr_res = vx6953_ctrl->pict_res;
+	vx6953_ctrl->sensormode = mode;
+	return rc;
+} /*end of vx6953_snapshot_config*/
+
+static int32_t vx6953_raw_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+	int rt;
+	/* change sensor resolution if needed */
+	if (vx6953_ctrl->curr_res != vx6953_ctrl->pict_res) {
+		if (vx6953_ctrl->pict_res == QTR_SIZE) {
+			rt = RES_PREVIEW;
+			vx6953_stm5m0edof_delay_msecs_stdby =
+				((((2 * 1000 * vx6953_ctrl->fps_divider)/
+				vx6953_ctrl->fps) * Q8) / Q10) + 1;
+		} else {
+			rt = RES_CAPTURE;
+			vx6953_stm5m0edof_delay_msecs_stdby =
+				((((1000 * vx6953_ctrl->fps_divider)/
+				vx6953_ctrl->fps) * Q8) / Q10) + 1;
+		}
+		if (vx6953_sensor_setting(UPDATE_PERIODIC, rt) < 0)
+			return rc;
+	}
+	vx6953_ctrl->edof_mode = VX6953_EDOF_APPLICATION;
+	if (vx6953_enable_edof(vx6953_ctrl->edof_mode) < 0)
+		return rc;
+	vx6953_ctrl->curr_res = vx6953_ctrl->pict_res;
+	vx6953_ctrl->sensormode = mode;
+	return rc;
+} /*end of vx6953_raw_snapshot_config*/
+static int32_t vx6953_set_sensor_mode(int mode,
+	int res)
+{
+	int32_t rc = 0;
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		rc = vx6953_video_config(mode);
+		break;
+	case SENSOR_SNAPSHOT_MODE:
+		rc = vx6953_snapshot_config(mode);
+		break;
+	case SENSOR_RAW_SNAPSHOT_MODE:
+		rc = vx6953_raw_snapshot_config(mode);
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+static int32_t vx6953_power_down(void)
+{
+	vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
+	MODE_SELECT_STANDBY_MODE);
+	return 0;
+}
+
+
+static int vx6953_probe_init_done(const struct msm_camera_sensor_info *data)
+{
+	gpio_free(data->sensor_reset);
+	kfree(vx6953_ctrl);
+	vx6953_ctrl = NULL;
+	return 0;
+}
+static int vx6953_probe_init_sensor(const struct msm_camera_sensor_info *data)
+{
+	unsigned short revision_number;
+	int32_t rc = 0;
+	unsigned short chipidl, chipidh;
+	CDBG("%s: %d\n", __func__, __LINE__);
+	rc = gpio_request(data->sensor_reset, "vx6953");
+	CDBG(" vx6953_probe_init_sensor\n");
+	if (!rc) {
+		CDBG("sensor_reset = %d\n", rc);
+		CDBG(" vx6953_probe_init_sensor 1\n");
+		gpio_direction_output(data->sensor_reset, 0);
+		msleep(50);
+		CDBG(" vx6953_probe_init_sensor 1\n");
+		gpio_direction_output(data->sensor_reset, 1);
+		msleep(13);
+	} else {
+		CDBG(" vx6953_probe_init_sensor 2\n");
+		goto init_probe_done;
+	}
+	msleep(20);
+	CDBG(" vx6953_probe_init_sensor is called\n");
+	/* 3. Read sensor Model ID: */
+	rc = vx6953_i2c_read(0x0000, &chipidh, 1);
+	if (rc < 0) {
+		CDBG(" vx6953_probe_init_sensor 3\n");
+		goto init_probe_fail;
+	}
+	rc = vx6953_i2c_read(0x0001, &chipidl, 1);
+	if (rc < 0) {
+		CDBG(" vx6953_probe_init_sensor4\n");
+		goto init_probe_fail;
+	}
+	CDBG("vx6953 model_id = 0x%x  0x%x\n", chipidh, chipidl);
+	/* 4. Compare sensor ID to VX6953 ID: */
+	if (chipidh != 0x03 || chipidl != 0xB9) {
+		rc = -ENODEV;
+		CDBG("vx6953_probe_init_sensor fail chip id doesnot match\n");
+		goto init_probe_fail;
+	}
+
+	vx6953_ctrl = kzalloc(sizeof(struct vx6953_ctrl_t), GFP_KERNEL);
+	if (!vx6953_ctrl) {
+		CDBG("vx6953_init failed!\n");
+		rc = -ENOMEM;
+	}
+	vx6953_ctrl->fps_divider = 1 * 0x00000400;
+	vx6953_ctrl->pict_fps_divider = 1 * 0x00000400;
+	vx6953_ctrl->set_test = TEST_OFF;
+	vx6953_ctrl->prev_res = QTR_SIZE;
+	vx6953_ctrl->pict_res = FULL_SIZE;
+	vx6953_ctrl->curr_res = INVALID_SIZE;
+	vx6953_ctrl->sensor_type = VX6953_STM5M0EDOF_CUT_2;
+	vx6953_ctrl->edof_mode = VX6953_EDOF_ESTIMATION;
+
+	if (data)
+		vx6953_ctrl->sensordata = data;
+
+	if (vx6953_i2c_read(0x0002, &revision_number, 1) < 0)
+		return rc;
+		CDBG("sensor revision number major = 0x%x\n", revision_number);
+	if (vx6953_i2c_read(0x0018, &revision_number, 1) < 0)
+		return rc;
+		CDBG("sensor revision number = 0x%x\n", revision_number);
+	if (revision_number == VX6953_REVISION_NUMBER_CUT3) {
+		vx6953_ctrl->sensor_type = VX6953_STM5M0EDOF_CUT_3;
+		CDBG("VX6953 EDof Cut 3.0 sensor\n ");
+	} else if (revision_number == VX6953_REVISION_NUMBER_CUT2) {
+		vx6953_ctrl->sensor_type = VX6953_STM5M0EDOF_CUT_2;
+		CDBG("VX6953 EDof Cut 2.0 sensor\n ");
+	} else {/* Cut1.0 reads 0x00 for register 0x0018*/
+		vx6953_ctrl->sensor_type = VX6953_STM5M0EDOF_CUT_1;
+		CDBG("VX6953 EDof Cut 1.0 sensor\n ");
+	}
+
+	if (vx6953_ctrl->prev_res == QTR_SIZE) {
+		if (vx6953_sensor_setting(REG_INIT, RES_PREVIEW) < 0)
+			goto init_probe_fail;
+	} else {
+		if (vx6953_sensor_setting(REG_INIT, RES_CAPTURE) < 0)
+			goto init_probe_fail;
+	}
+
+	goto init_probe_done;
+init_probe_fail:
+	CDBG(" vx6953_probe_init_sensor fails\n");
+	gpio_direction_output(data->sensor_reset, 0);
+	vx6953_probe_init_done(data);
+init_probe_done:
+	CDBG(" vx6953_probe_init_sensor finishes\n");
+	return rc;
+	}
+/* camsensor_iu060f_vx6953_reset */
+int vx6953_sensor_open_init(const struct msm_camera_sensor_info *data)
+{
+	unsigned short revision_number;
+	int32_t rc = 0;
+
+	CDBG("%s: %d\n", __func__, __LINE__);
+	CDBG("Calling vx6953_sensor_open_init\n");
+	rc = gpio_request(data->sensor_reset, "vx6953");
+	if (!rc)
+		CDBG("vx6953 gpio_request fail\n");
+
+	vx6953_ctrl = kzalloc(sizeof(struct vx6953_ctrl_t), GFP_KERNEL);
+	if (!vx6953_ctrl) {
+		CDBG("vx6953_init failed!\n");
+		rc = -ENOMEM;
+		goto init_done;
+	}
+	vx6953_ctrl->fps_divider = 1 * 0x00000400;
+	vx6953_ctrl->pict_fps_divider = 1 * 0x00000400;
+	vx6953_ctrl->set_test = TEST_OFF;
+	vx6953_ctrl->prev_res = QTR_SIZE;
+	vx6953_ctrl->pict_res = FULL_SIZE;
+	vx6953_ctrl->curr_res = INVALID_SIZE;
+	vx6953_ctrl->sensor_type = VX6953_STM5M0EDOF_CUT_2;
+	vx6953_ctrl->edof_mode = VX6953_EDOF_ESTIMATION;
+	if (data)
+		vx6953_ctrl->sensordata = data;
+	if (rc < 0) {
+		CDBG("Calling vx6953_sensor_open_init fail1\n");
+		return rc;
+	}
+	CDBG("%s: %d\n", __func__, __LINE__);
+	/* enable mclk first */
+	msm_camio_clk_rate_set(VX6953_STM5M0EDOF_DEFAULT_MASTER_CLK_RATE);
+	CDBG("%s: %d\n", __func__, __LINE__);
+	if (vx6953_i2c_read(0x0002, &revision_number, 1) < 0)
+		return rc;
+		CDBG("sensor revision number major = 0x%x\n", revision_number);
+	if (vx6953_i2c_read(0x0018, &revision_number, 1) < 0)
+		return rc;
+		CDBG("sensor revision number = 0x%x\n", revision_number);
+	if (revision_number == VX6953_REVISION_NUMBER_CUT3) {
+		vx6953_ctrl->sensor_type = VX6953_STM5M0EDOF_CUT_3;
+		CDBG("VX6953 EDof Cut 3.0 sensor\n ");
+	} else if (revision_number == VX6953_REVISION_NUMBER_CUT2) {
+		vx6953_ctrl->sensor_type = VX6953_STM5M0EDOF_CUT_2;
+		CDBG("VX6953 EDof Cut 2.0 sensor\n ");
+	} else {/* Cut1.0 reads 0x00 for register 0x0018*/
+		vx6953_ctrl->sensor_type = VX6953_STM5M0EDOF_CUT_1;
+		CDBG("VX6953 EDof Cut 1.0 sensor\n ");
+	}
+
+	vx6953_ctrl->fps = 30*Q8;
+	if (rc < 0)
+		goto init_fail;
+	else
+		goto init_done;
+init_fail:
+	CDBG("init_fail\n");
+	gpio_direction_output(data->sensor_reset, 0);
+	vx6953_probe_init_done(data);
+init_done:
+	CDBG("init_done\n");
+	return rc;
+} /*endof vx6953_sensor_open_init*/
+
+static int vx6953_init_client(struct i2c_client *client)
+{
+	/* Initialize the MSM_CAMI2C Chip */
+	init_waitqueue_head(&vx6953_wait_queue);
+	return 0;
+}
+
+static const struct i2c_device_id vx6953_i2c_id[] = {
+	{"vx6953", 0},
+	{ }
+};
+
+static int vx6953_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+	CDBG("vx6953_probe called!\n");
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		CDBG("i2c_check_functionality failed\n");
+		goto probe_failure;
+	}
+
+	vx6953_sensorw = kzalloc(sizeof(struct vx6953_work_t), GFP_KERNEL);
+	if (!vx6953_sensorw) {
+		CDBG("kzalloc failed.\n");
+		rc = -ENOMEM;
+		goto probe_failure;
+	}
+
+	i2c_set_clientdata(client, vx6953_sensorw);
+	vx6953_init_client(client);
+	vx6953_client = client;
+
+	msleep(50);
+
+	CDBG("vx6953_probe successed! rc = %d\n", rc);
+	return 0;
+
+probe_failure:
+	CDBG("vx6953_probe failed! rc = %d\n", rc);
+	return rc;
+}
+
+static int vx6953_send_wb_info(struct wb_info_cfg *wb)
+{
+	unsigned short read_data;
+	uint8_t temp[8];
+	int rc = 0;
+	int i = 0;
+
+	/* red_gain */
+	temp[2] = wb->red_gain >> 8;
+	temp[3] = wb->red_gain & 0xFF;
+
+	/* green_gain */
+	temp[0] = wb->green_gain >> 8;
+	temp[1] = wb->green_gain & 0xFF;
+	temp[6] = temp[0];
+	temp[7] = temp[1];
+
+	/* blue_gain */
+	temp[4] = wb->blue_gain >> 8;
+	temp[5] = wb->blue_gain & 0xFF;
+	rc = vx6953_i2c_write_seq_sensor(0x0B8E, &temp[0], 8);
+
+	for (i = 0; i < 6; i++) {
+		rc = vx6953_i2c_read(0x0B8E + i, &read_data, 1);
+		CDBG("%s addr 0x%x val %d\n", __func__, 0x0B8E + i, read_data);
+	}
+	rc = vx6953_i2c_read(0x0B82, &read_data, 1);
+	CDBG("%s addr 0x%x val %d\n", __func__, 0x0B82, read_data);
+	if (rc < 0)
+		return rc;
+	return rc;
+} /*end of vx6953_snapshot_config*/
+
+static int __exit vx6953_remove(struct i2c_client *client)
+{
+	struct vx6953_work_t_t *sensorw = i2c_get_clientdata(client);
+	free_irq(client->irq, sensorw);
+	vx6953_client = NULL;
+	kfree(sensorw);
+	return 0;
+}
+
+static struct i2c_driver vx6953_i2c_driver = {
+	.id_table = vx6953_i2c_id,
+	.probe  = vx6953_i2c_probe,
+	.remove = __exit_p(vx6953_i2c_remove),
+	.driver = {
+		.name = "vx6953",
+	},
+};
+
+static int vx6953_sensor_config(void __user *argp)
+{
+	struct sensor_cfg_data cdata;
+	long   rc = 0;
+	if (copy_from_user(&cdata,
+		(void *)argp,
+		sizeof(struct sensor_cfg_data)))
+		return -EFAULT;
+	mutex_lock(&vx6953_mut);
+	CDBG("vx6953_sensor_config: cfgtype = %d\n",
+	cdata.cfgtype);
+		switch (cdata.cfgtype) {
+		case CFG_GET_PICT_FPS:
+			vx6953_get_pict_fps(
+				cdata.cfg.gfps.prevfps,
+				&(cdata.cfg.gfps.pictfps));
+
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_GET_PREV_L_PF:
+			cdata.cfg.prevl_pf =
+			vx6953_get_prev_lines_pf();
+
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_GET_PREV_P_PL:
+			cdata.cfg.prevp_pl =
+				vx6953_get_prev_pixels_pl();
+
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_GET_PICT_L_PF:
+			cdata.cfg.pictl_pf =
+				vx6953_get_pict_lines_pf();
+
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_GET_PICT_P_PL:
+			cdata.cfg.pictp_pl =
+				vx6953_get_pict_pixels_pl();
+
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_GET_PICT_MAX_EXP_LC:
+			cdata.cfg.pict_max_exp_lc =
+				vx6953_get_pict_max_exp_lc();
+
+			if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+				rc = -EFAULT;
+			break;
+
+		case CFG_SET_FPS:
+		case CFG_SET_PICT_FPS:
+			rc = vx6953_set_fps(&(cdata.cfg.fps));
+			break;
+
+		case CFG_SET_EXP_GAIN:
+			rc =
+				vx6953_write_exp_gain(
+					cdata.cfg.exp_gain.gain,
+					cdata.cfg.exp_gain.line);
+			break;
+
+		case CFG_SET_PICT_EXP_GAIN:
+			rc =
+				vx6953_set_pict_exp_gain(
+				cdata.cfg.exp_gain.gain,
+				cdata.cfg.exp_gain.line);
+			break;
+
+		case CFG_SET_MODE:
+			rc = vx6953_set_sensor_mode(cdata.mode,
+					cdata.rs);
+			break;
+
+		case CFG_PWR_DOWN:
+			rc = vx6953_power_down();
+			break;
+
+		case CFG_MOVE_FOCUS:
+			rc =
+				vx6953_move_focus(
+				cdata.cfg.focus.dir,
+				cdata.cfg.focus.steps);
+			break;
+
+		case CFG_SET_DEFAULT_FOCUS:
+			rc =
+				vx6953_set_default_focus(
+				cdata.cfg.focus.steps);
+			break;
+
+		case CFG_SET_EFFECT:
+			rc = vx6953_set_default_focus(
+				cdata.cfg.effect);
+			break;
+
+
+		case CFG_SEND_WB_INFO:
+			rc = vx6953_send_wb_info(
+				&(cdata.cfg.wb_info));
+			break;
+
+		default:
+			rc = -EFAULT;
+			break;
+		}
+
+	mutex_unlock(&vx6953_mut);
+
+	return rc;
+}
+
+
+
+
+static int vx6953_sensor_release(void)
+{
+	int rc = -EBADF;
+	mutex_lock(&vx6953_mut);
+	vx6953_power_down();
+	gpio_free(vx6953_ctrl->sensordata->sensor_reset);
+	kfree(vx6953_ctrl);
+	vx6953_ctrl = NULL;
+	CDBG("vx6953_release completed\n");
+	mutex_unlock(&vx6953_mut);
+
+	return rc;
+}
+
+static int vx6953_g_chip_ident(struct v4l2_subdev *sd,
+			struct v4l2_dbg_chip_ident *id)
+{
+	/* TODO: Need to add this ID in v4l2-chip-ident.h */
+	id->ident    = V4L2_IDENT_VX6953;
+	id->revision = 0;
+
+	return 0;
+}
+
+static int vx6953_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *param)
+{
+	int ret = 0;
+	/* return current mode value */
+	param->parm.capture.capturemode = vx6953_ctrl->sensormode;
+	return ret;
+}
+
+static int vx6953_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *param)
+{
+	/* set the desired mode */
+	/* right now, the only purpose is to set the desired mode -
+	 preview or snapshot */
+	vx6953_ctrl->sensormode = param->parm.capture.capturemode;
+	return 0;
+}
+
+static int vx6953_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	long rc = 0;
+	int mode = vx6953_ctrl->sensormode;
+	int rt = RES_PREVIEW;
+	unsigned short frame_cnt;
+	struct msm_camera_csi_params vx6953_csi_params;
+
+	CDBG("mode = %d, enable = %d\n", mode, enable);
+
+	if (!enable) {
+		/* turn off streaming */
+		/* TODO: Make call to I2C write to turn streaming off */
+		/* rc = vx6953_i2c_write_b_sensor(); */
+
+		struct vx6953_i2c_reg_conf init_tbl[] = {
+			{REG_0x0112,
+			vx6953_regs.reg_pat_init[0].reg_0x0112},
+			{0x6003, 0x01},
+			{REG_0x0113,
+			vx6953_regs.reg_pat_init[0].reg_0x0113},
+			{REG_VT_PIX_CLK_DIV,
+			vx6953_regs.reg_pat_init[0].
+			vt_pix_clk_div},
+			{REG_PRE_PLL_CLK_DIV,
+			vx6953_regs.reg_pat_init[0].
+			pre_pll_clk_div},
+			{REG_PLL_MULTIPLIER,
+			vx6953_regs.reg_pat_init[0].
+			pll_multiplier},
+			{REG_OP_PIX_CLK_DIV,
+			vx6953_regs.reg_pat_init[0].
+			op_pix_clk_div},
+			{REG_COARSE_INTEGRATION_TIME_HI,
+			vx6953_regs.reg_pat[rt].
+			coarse_integration_time_hi},
+			{REG_COARSE_INTEGRATION_TIME_LO,
+			vx6953_regs.reg_pat[rt].
+			coarse_integration_time_lo},
+			{REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
+			vx6953_regs.reg_pat[rt].
+			analogue_gain_code_global},
+			{REG_0x3030,
+			vx6953_regs.reg_pat_init[0].reg_0x3030},
+			/* 953 specific registers */
+			{REG_0x0111,
+			vx6953_regs.reg_pat_init[0].reg_0x0111},
+			{REG_0x0b00,
+			vx6953_regs.reg_pat_init[0].reg_0x0b00},
+			{REG_0x3001,
+			vx6953_regs.reg_pat_init[0].reg_0x3001},
+			{REG_0x3004,
+			vx6953_regs.reg_pat_init[0].reg_0x3004},
+			{0x3006, 0x00},
+			{REG_0x3007,
+			vx6953_regs.reg_pat_init[0].reg_0x3007},
+			{0x301b, 0x29},
+			/* DEFCOR settings */
+			/*Single Defect Correction Weight DISABLE*/
+			{0x0b06,
+			vx6953_regs.reg_pat_init[0].reg_0x0b06},
+			/*Single_defect_correct_weight = auto*/
+			{0x0b07,
+			vx6953_regs.reg_pat_init[0].reg_0x0b07},
+			/*Dynamic couplet correction ENABLED*/
+			{0x0b08,
+			vx6953_regs.reg_pat_init[0].reg_0x0b08},
+			/*Dynamic couplet correction weight*/
+			{0x0b09,
+			vx6953_regs.reg_pat_init[0].reg_0x0b09},
+			/* Clock Setup */
+			/* Tell sensor ext clk is 24MHz*/
+			{REG_0x0136,
+			vx6953_regs.reg_pat_init[0].reg_0x0136},
+			{REG_0x0137,
+			vx6953_regs.reg_pat_init[0].reg_0x0137},
+			/* The white balance gains must be written
+			 to the sensor every frame. */
+			/* Edof */
+			{REG_0x0b83,
+			vx6953_regs.reg_pat_init[0].reg_0x0b83},
+			{REG_0x0b84,
+			vx6953_regs.reg_pat_init[0].reg_0x0b84},
+			{REG_0x0b85,
+			vx6953_regs.reg_pat_init[0].reg_0x0b85},
+			{REG_0x0b88,
+			vx6953_regs.reg_pat_init[0].reg_0x0b88},
+			{REG_0x0b89,
+			vx6953_regs.reg_pat_init[0].reg_0x0b89},
+			{REG_0x0b8a,
+			vx6953_regs.reg_pat_init[0].reg_0x0b8a},
+			/* Mode specific regieters */
+			{REG_FRAME_LENGTH_LINES_HI,
+			vx6953_regs.reg_pat[rt].
+			frame_length_lines_hi},
+			{REG_FRAME_LENGTH_LINES_LO,
+			vx6953_regs.reg_pat[rt].
+			frame_length_lines_lo},
+			{REG_LINE_LENGTH_PCK_HI,
+			vx6953_regs.reg_pat[rt].
+			line_length_pck_hi},
+			{REG_LINE_LENGTH_PCK_LO,
+			vx6953_regs.reg_pat[rt].
+			line_length_pck_lo},
+			{REG_0x3005,
+			vx6953_regs.reg_pat[rt].reg_0x3005},
+			{0x3010,
+			vx6953_regs.reg_pat[rt].reg_0x3010},
+			{REG_0x3011,
+			vx6953_regs.reg_pat[rt].reg_0x3011},
+			{REG_0x301a,
+			vx6953_regs.reg_pat[rt].reg_0x301a},
+			{REG_0x3035,
+			vx6953_regs.reg_pat[rt].reg_0x3035},
+			{REG_0x3036,
+			vx6953_regs.reg_pat[rt].reg_0x3036},
+			{REG_0x3041,
+			vx6953_regs.reg_pat[rt].reg_0x3041},
+			{0x3042,
+			vx6953_regs.reg_pat[rt].reg_0x3042},
+			{REG_0x3045,
+			vx6953_regs.reg_pat[rt].reg_0x3045},
+			/*EDOF: Estimation settings for Preview mode
+			  Application settings for capture mode
+			  (standard settings - Not tuned) */
+			{REG_0x0b80,
+			vx6953_regs.reg_pat[rt].reg_0x0b80},
+			{REG_0x0900,
+			vx6953_regs.reg_pat[rt].reg_0x0900},
+			{REG_0x0901,
+			vx6953_regs.reg_pat[rt].reg_0x0901},
+			{REG_0x0902,
+			vx6953_regs.reg_pat[rt].reg_0x0902},
+			{REG_0x0383,
+			vx6953_regs.reg_pat[rt].reg_0x0383},
+			{REG_0x0387,
+			vx6953_regs.reg_pat[rt].reg_0x0387},
+			/* Change output size / frame rate */
+			{REG_0x034c,
+			vx6953_regs.reg_pat[rt].reg_0x034c},
+			{REG_0x034d,
+			vx6953_regs.reg_pat[rt].reg_0x034d},
+			{REG_0x034e,
+			vx6953_regs.reg_pat[rt].reg_0x034e},
+			{REG_0x034f,
+			vx6953_regs.reg_pat[rt].reg_0x034f},
+		};
+		/* reset fps_divider */
+		vx6953_ctrl->fps = 30 * Q8;
+		/* stop streaming */
+
+		/* Reset everything first */
+		if (vx6953_i2c_write_b_sensor(0x103, 0x01) < 0) {
+			CDBG("S/W reset failed\n");
+			return rc;
+		} else
+			CDBG("S/W reset successful\n");
+
+		msleep(10);
+
+		CDBG("Init vx6953_sensor_setting standby\n");
+		if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
+				    MODE_SELECT_STANDBY_MODE) < 0)
+			return rc;
+
+		/*vx6953_stm5m0edof_delay_msecs_stdby*/
+		msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+
+		vx6953_csi_params.data_format = CSI_8BIT;
+		vx6953_csi_params.lane_cnt = 1;
+		vx6953_csi_params.lane_assign = 0xe4;
+		vx6953_csi_params.dpcm_scheme = 0;
+		vx6953_csi_params.settle_cnt = 7;
+		rc = msm_camio_csi_config(&vx6953_csi_params);
+		if (rc < 0)
+			CDBG(" config csi controller failed\n");
+		msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+
+		vx6953_patch_for_cut3();
+		rc = vx6953_i2c_write_w_table(&init_tbl[0],
+					    ARRAY_SIZE(init_tbl));
+		if (rc < 0)
+			return rc;
+
+		msleep(vx6953_stm5m0edof_delay_msecs_stdby);
+
+		vx6953_i2c_write_b_sensor(0x0b80, 0x00);
+		vx6953_i2c_write_b_sensor(0x3388, 0x03);
+		vx6953_i2c_write_b_sensor(0x3640, 0x00);
+		return rc;
+	} else {
+		/* Start sensor streaming */
+		if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
+					    MODE_SELECT_STREAM) < 0)
+			return rc;
+		CDBG("Init vx6953_sensor_setting stream\n");
+		msleep(vx6953_stm5m0edof_delay_msecs_stream);
+		if (vx6953_i2c_read(0x0005, &frame_cnt, 1) < 0)
+			return rc;
+
+		rc = vx6953_i2c_write_w_table(&edof_tbl[0],
+					    ARRAY_SIZE(edof_tbl));
+		vx6953_i2c_write_b_sensor(0x3388, 0x00);
+
+		while (frame_cnt == 0xFF) {
+			if (vx6953_i2c_read(0x0005, &frame_cnt, 1) < 0)
+				return rc;
+			CDBG("frame_cnt=%d", frame_cnt);
+			msleep(10);
+		}
+
+		/* set desired mode */
+		switch (mode) {
+		case SENSOR_PREVIEW_MODE:
+			CDBG("SENSOR_PREVIEW_MODE\n");
+			rc = vx6953_video_config(mode);
+			break;
+		case SENSOR_SNAPSHOT_MODE:
+			CDBG("SENSOR_SNAPSHOT_MODE\n");
+			rc = vx6953_snapshot_config(mode);
+			break;
+		case SENSOR_RAW_SNAPSHOT_MODE:
+			CDBG("SENSOR_RAW_SNAPSHOT_MODE\n");
+			rc = vx6953_raw_snapshot_config(mode);
+			break;
+		default:
+			CDBG("default\n");
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static void vx6953_frame_check(u32 *width, u32 *height)
+{
+	/* get mode first */
+	int mode = vx6953_ctrl->sensormode;
+
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		if (*width > VX6953_QTR_SIZE_WIDTH)
+			*width = VX6953_QTR_SIZE_WIDTH;
+
+		if (*height > VX6953_QTR_SIZE_HEIGHT)
+			*height = VX6953_QTR_SIZE_HEIGHT;
+		break;
+	case SENSOR_SNAPSHOT_MODE:
+	case SENSOR_RAW_SNAPSHOT_MODE:
+		if (*width > VX6953_HRZ_FULL_BLK_PIXELS)
+			*width = VX6953_HRZ_FULL_BLK_PIXELS;
+
+		if (*height > VX6953_VER_FULL_BLK_LINES)
+			*height = VX6953_VER_FULL_BLK_LINES;
+		break;
+	default:
+		break;
+	}
+}
+
+
+static int vx6953_set_params(struct i2c_client *client, u32 width, u32 height,
+			     enum v4l2_mbus_pixelcode code)
+{
+	int i;
+	vx6953_ctrl->fmt = NULL;
+
+	/*
+	 * frame size check
+	 */
+	vx6953_frame_check(&width, &height);
+
+	/*
+	 * get color format
+	 */
+	for (i = 0; i < ARRAY_SIZE(vx6953_cfmts); i++)
+		if (vx6953_cfmts[i].code == code)
+			break;
+	if (i == ARRAY_SIZE(vx6953_cfmts))
+		return -EINVAL;
+
+	/* sensor supports one fixed size depending upon the mode */
+	switch (vx6953_ctrl->sensormode) {
+	case SENSOR_PREVIEW_MODE:
+		vx6953_video_config(vx6953_ctrl->sensormode);
+		break;
+	case SENSOR_SNAPSHOT_MODE:
+		vx6953_snapshot_config(vx6953_ctrl->sensormode);
+		break;
+	case SENSOR_RAW_SNAPSHOT_MODE:
+		vx6953_raw_snapshot_config(vx6953_ctrl->sensormode);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* why need this ? vx6953_ctrl->fmt = &(vx6953_cfmts[i]); */
+
+	return 0;
+}
+
+static int vx6953_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
+{
+	/* right now we are not supporting, probably vfe can take care */
+	return -EINVAL;
+}
+
+static int vx6953_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+{
+	return -EINVAL;
+}
+
+static int vx6953_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+{
+	return -EINVAL;
+}
+
+static int vx6953_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
+{
+	/* by this time vx6953_client should already be set */
+	struct i2c_client *client = vx6953_client;
+
+	/* currently sensor supports fixed dimensions only
+	 * depending upon the mode*/
+	if (!vx6953_ctrl->fmt) {
+		int ret = vx6953_set_params(client, VX6953_QTR_SIZE_WIDTH,
+						VX6953_QTR_SIZE_HEIGHT,
+						V4L2_MBUS_FMT_YUYV8_2X8);
+		if (ret < 0)
+			return ret;
+	}
+
+	mf->width = vx6953_get_pict_pixels_pl();
+	mf->height  = vx6953_get_pict_lines_pf();
+	/* TODO: set colorspace */
+	mf->code  = vx6953_ctrl->fmt->code;
+	mf->field = V4L2_FIELD_NONE;
+
+	return 0;
+}
+
+static int vx6953_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
+{
+	/* by this time vx6953_client should already be set */
+	struct i2c_client *client = vx6953_client;
+
+	/* TODO: We need to define this function */
+	/* TODO: set colorspace */
+	return vx6953_set_params(client, mf->width, mf->height, mf->code);
+}
+
+static int vx6953_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(vx6953_cfmts); i++)
+		if (mf->code == vx6953_cfmts[i].code)
+			break;
+
+	if (i == ARRAY_SIZE(vx6953_cfmts))
+		return -EINVAL;
+
+	/* check that frame is within max sensor supported frame size */
+	vx6953_frame_check(&mf->width, &mf->height);
+
+	/* TODO: set colorspace */
+	mf->field = V4L2_FIELD_NONE;
+
+	return 0;
+}
+
+static int vx6953_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
+			   enum v4l2_mbus_pixelcode *code)
+{
+	printk(KERN_DEBUG "Index is %d\n", index);
+	if ((unsigned int)index >= ARRAY_SIZE(vx6953_cfmts))
+		return -EINVAL;
+
+	*code = vx6953_cfmts[index].code;
+	return 0;
+}
+
+static struct v4l2_subdev_core_ops vx6953_subdev_core_ops = {
+	.g_chip_ident = vx6953_g_chip_ident,
+};
+
+static struct v4l2_subdev_video_ops vx6953_subdev_video_ops = {
+	.g_parm			   = vx6953_g_parm,
+	.s_parm			   = vx6953_s_parm,
+	.s_stream = vx6953_s_stream,
+	.g_mbus_fmt = vx6953_g_fmt,
+	.s_mbus_fmt = vx6953_s_fmt,
+	.try_mbus_fmt = vx6953_try_fmt,
+	.cropcap  = vx6953_cropcap,
+	.g_crop   = vx6953_g_crop,
+	.s_crop   = vx6953_s_crop,
+	.enum_mbus_fmt  = vx6953_enum_fmt,
+};
+
+static struct v4l2_subdev_ops vx6953_subdev_ops = {
+	.core = &vx6953_subdev_core_ops,
+	.video  = &vx6953_subdev_video_ops,
+};
+
+static int vx6953_sensor_probe(const struct msm_camera_sensor_info *info,
+		struct msm_sensor_ctrl *s)
+{
+	int rc = 0;
+	rc = i2c_add_driver(&vx6953_i2c_driver);
+	if (rc < 0 || vx6953_client == NULL) {
+		rc = -ENOTSUPP;
+		goto probe_fail;
+	}
+	msm_camio_clk_rate_set(24000000);
+	rc = vx6953_probe_init_sensor(info);
+	if (rc < 0)
+		goto probe_fail;
+	s->s_init = vx6953_sensor_open_init;
+	s->s_release = vx6953_sensor_release;
+	s->s_config  = vx6953_sensor_config;
+	vx6953_probe_init_done(info);
+	return rc;
+
+probe_fail:
+	CDBG("vx6953_sensor_probe: SENSOR PROBE FAILS!\n");
+	return rc;
+}
+
+
+static int vx6953_sensor_probe_cb(const struct msm_camera_sensor_info *info,
+	struct v4l2_subdev *sdev, struct msm_sensor_ctrl *s)
+{
+	int rc = 0;
+	rc = vx6953_sensor_probe(info, s);
+	if (rc < 0)
+		return rc;
+
+	vx6953_ctrl = kzalloc(sizeof(struct vx6953_ctrl_t), GFP_KERNEL);
+	if (!vx6953_ctrl) {
+		CDBG("vx6953_sensor_probe failed!\n");
+		return -ENOMEM;
+	}
+
+	/* probe is successful, init a v4l2 subdevice */
+	printk(KERN_DEBUG "going into v4l2_i2c_subdev_init\n");
+	if (sdev) {
+		v4l2_i2c_subdev_init(sdev, vx6953_client,
+						&vx6953_subdev_ops);
+		vx6953_ctrl->sensor_dev = sdev;
+	}
+	return rc;
+}
+
+static int __vx6953_probe(struct platform_device *pdev)
+{
+	return msm_sensor_register(pdev, vx6953_sensor_probe_cb);
+}
+
+static struct platform_driver msm_camera_driver = {
+	.probe = __vx6953_probe,
+	.driver = {
+		.name = "msm_camera_vx6953",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init vx6953_init(void)
+{
+	return platform_driver_register(&msm_camera_driver);
+}
+
+module_init(vx6953_init);
+void vx6953_exit(void)
+{
+	i2c_del_driver(&vx6953_i2c_driver);
+}
+
+
diff --git a/drivers/media/platform/msm/camera_v1/vx6953_v4l2.h b/drivers/media/platform/msm/camera_v1/vx6953_v4l2.h
new file mode 100644
index 0000000..4c7e90f
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v1/vx6953_v4l2.h
@@ -0,0 +1,136 @@
+/* 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.
+ *
+ */
+
+#ifndef VX6953_V4L2_H
+#define VX6953_V4L2_H
+#include <linux/types.h>
+#include <mach/board.h>
+extern struct vx6953_reg vx6953_regs;
+struct reg_struct_init {
+	uint8_t reg_0x0112;      /* 0x0112*/
+	uint8_t reg_0x0113;      /* 0x0113*/
+	uint8_t vt_pix_clk_div;  /* 0x0301*/
+	uint8_t pre_pll_clk_div; /* 0x0305*/
+	uint8_t pll_multiplier;  /* 0x0307*/
+	uint8_t op_pix_clk_div;  /* 0x0309*/
+	uint8_t reg_0x3030;      /*0x3030*/
+	uint8_t reg_0x0111;      /*0x0111*/
+	uint8_t reg_0x0b00;      /*0x0b00*/
+	uint8_t reg_0x3001;      /*0x3001*/
+	uint8_t reg_0x3004;      /*0x3004*/
+	uint8_t reg_0x3007;      /*0x3007*/
+	uint8_t reg_0x3016;      /*0x3016*/
+	uint8_t reg_0x301d;      /*0x301d*/
+	uint8_t reg_0x317e;      /*0x317E*/
+	uint8_t reg_0x317f;      /*0x317F*/
+	uint8_t reg_0x3400;      /*0x3400*/
+	uint8_t reg_0x0b06;      /*0x0b06*/
+	uint8_t reg_0x0b07;      /*0x0b07*/
+	uint8_t reg_0x0b08;      /*0x0b08*/
+	uint8_t reg_0x0b09;      /*0x0b09*/
+	uint8_t reg_0x0136;
+	uint8_t reg_0x0137;
+	/* Edof */
+	uint8_t reg_0x0b83;      /*0x0b83*/
+	uint8_t reg_0x0b84;      /*0x0b84*/
+	uint8_t reg_0x0b85;      /*0x0b85*/
+	uint8_t reg_0x0b88;      /*0x0b88*/
+	uint8_t reg_0x0b89;      /*0x0b89*/
+	uint8_t reg_0x0b8a;      /*0x0b8a*/
+	};
+struct reg_struct {
+	uint8_t coarse_integration_time_hi; /*REG_COARSE_INTEGRATION_TIME_HI*/
+	uint8_t coarse_integration_time_lo; /*REG_COARSE_INTEGRATION_TIME_LO*/
+	uint8_t analogue_gain_code_global;
+	uint8_t frame_length_lines_hi; /* 0x0340*/
+	uint8_t frame_length_lines_lo; /* 0x0341*/
+	uint8_t line_length_pck_hi;    /* 0x0342*/
+	uint8_t line_length_pck_lo;    /* 0x0343*/
+	uint8_t reg_0x3005;   /* 0x3005*/
+	uint8_t reg_0x3010;  /* 0x3010*/
+	uint8_t reg_0x3011;  /* 0x3011*/
+	uint8_t reg_0x301a;  /* 0x301a*/
+	uint8_t reg_0x3035;  /* 0x3035*/
+	uint8_t reg_0x3036;   /* 0x3036*/
+	uint8_t reg_0x3041;  /*0x3041*/
+	uint8_t reg_0x3042;  /*0x3042*/
+	uint8_t reg_0x3045;  /*0x3045*/
+	uint8_t reg_0x0b80;   /* 0x0b80*/
+	uint8_t reg_0x0900;   /*0x0900*/
+	uint8_t reg_0x0901;   /* 0x0901*/
+	uint8_t reg_0x0902;   /*0x0902*/
+	uint8_t reg_0x0383;   /*0x0383*/
+	uint8_t reg_0x0387;   /* 0x0387*/
+	uint8_t reg_0x034c;   /* 0x034c*/
+	uint8_t reg_0x034d;   /*0x034d*/
+	uint8_t reg_0x034e;   /* 0x034e*/
+	uint8_t reg_0x034f;   /* 0x034f*/
+	uint8_t reg_0x1716; /*0x1716*/
+	uint8_t reg_0x1717; /*0x1717*/
+	uint8_t reg_0x1718; /*0x1718*/
+	uint8_t reg_0x1719; /*0x1719*/
+	uint8_t reg_0x3210;/*0x3210*/
+	uint8_t reg_0x111; /*0x111*/
+	uint8_t reg_0x3410;  /*0x3410*/
+	uint8_t reg_0x3098;
+	uint8_t reg_0x309D;
+	uint8_t reg_0x0200;
+	uint8_t reg_0x0201;
+	};
+struct vx6953_i2c_reg_conf {
+	unsigned short waddr;
+	unsigned short wdata;
+};
+
+enum vx6953_test_mode_t {
+	TEST_OFF,
+	TEST_1,
+	TEST_2,
+	TEST_3
+};
+
+enum vx6953_resolution_t {
+	QTR_SIZE,
+	FULL_SIZE,
+	INVALID_SIZE
+};
+enum vx6953_setting {
+	RES_PREVIEW,
+	RES_CAPTURE
+};
+enum mt9p012_reg_update {
+	/* Sensor egisters that need to be updated during initialization */
+	REG_INIT,
+	/* Sensor egisters that needs periodic I2C writes */
+	UPDATE_PERIODIC,
+	/* All the sensor Registers will be updated */
+	UPDATE_ALL,
+	/* Not valid update */
+	UPDATE_INVALID
+};
+
+enum sensor_revision_t {
+	VX6953_STM5M0EDOF_CUT_1,
+	VX6953_STM5M0EDOF_CUT_2,
+	VX6953_STM5M0EDOF_CUT_3
+};
+enum edof_mode_t {
+	VX6953_EDOF_DISABLE,       /* 0x00 */
+	VX6953_EDOF_APPLICATION,   /* 0x01 */
+	VX6953_EDOF_ESTIMATION     /* 0x02 */
+};
+struct vx6953_reg {
+	const struct reg_struct_init  *reg_pat_init;
+	const struct reg_struct  *reg_pat;
+};
+#endif /* VX6953_H */
diff --git a/drivers/media/platform/msm/camera_v2/Kconfig b/drivers/media/platform/msm/camera_v2/Kconfig
new file mode 100644
index 0000000..e4777e6
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/Kconfig
@@ -0,0 +1,128 @@
+config MSM_CAMERA_SENSOR
+	    bool "Qualcomm MSM camera sensor support"
+	    depends on MSMB_CAMERA
+        ---help---
+          This flag enables support for Camera Sensor.
+          The sensor driver is capable of providing real time
+          data for camera support. The driver support V4L2
+          subdev APIs.
+
+config MSM_CPP
+        bool "Qualcomm MSM Camera Post Processing Engine support"
+        depends on MSMB_CAMERA
+        ---help---
+          Enable support for Camera Post-processing Engine
+          The Post processing engine is capable of scaling
+          and cropping image. The driver support V4L2 subdev
+          APIs.
+
+config MSM_CCI
+        bool "Qualcomm MSM Camera Control Interface support"
+        depends on MSMB_CAMERA
+        ---help---
+          Enable support for Camera Control Interface driver only
+          for those platforms that have hardware support. This driver
+          is responsible for handling I2C read and write on the I2C
+          bus. It is also responsible for synchronization with
+          GPIO and data frames.
+
+config MSM_CSI20_HEADER
+        bool "Qualcomm MSM CSI 2.0 Header"
+        depends on MSMB_CAMERA
+        ---help---
+          Enable support for CSI drivers to include 2.0
+          header. This header has register macros and its
+          values and bit mask for register configuration bits
+          This config macro is required targets based on 8960,
+          8930 and 8064 platforms.
+
+config MSM_CSI30_HEADER
+        bool "Qualcomm MSM CSI 3.0 Header"
+        depends on MSMB_CAMERA
+        ---help---
+          Enable support for CSI drivers to include 3.0
+          header. This header has register macros and its
+          values and bit mask for register configuration bits
+          This config macro is required for targets based on
+          8064 platforms.
+
+config MSM_CSIPHY
+        bool "Qualcomm MSM Camera Serial Interface Physical receiver support"
+        depends on MSMB_CAMERA
+        ---help---
+          Enable support for Camera Serial Interface
+          Physical receiver. It deserializes packets and
+          supports detection of packet start and stop
+          signalling.
+
+config MSM_CSID
+        bool "Qualcomm MSM Camera Serial Interface decoder support"
+        depends on MSMB_CAMERA
+        ---help---
+          Enable support for Camera Serial Interface decoder.
+          It supports lane merging and decoding of packets
+          based on cid which is mapped to a virtual channel
+          and datatype.
+
+config MSM_ISPIF
+        bool "Qualcomm MSM Image Signal Processing interface support"
+        depends on MSMB_CAMERA
+        ---help---
+          Enable support for Image Signal Processing interface module.
+          This module acts as a crossbar between CSID and VFE. Output
+          of any CID of CSID can be routed to of of pixel or raw
+          data interface in VFE.
+
+config S5K3L1YX
+	bool "Sensor S5K3L1YX (BAYER 12M)"
+	depends on MSMB_CAMERA
+	---help---
+		Samsung 12 MP Bayer Sensor with auto focus, uses
+		4 mipi lanes, preview config = 1984 * 1508 at 30 fps,
+		snapshot config = 4000 * 3000 at 20 fps,
+		hfr video at 60, 90 and 120 fps.
+
+config IMX135
+	bool "Sensor IMX135 (BAYER 12M)"
+	depends on MSMB_CAMERA
+	---help---
+		Sony 12 MP Bayer Sensor with auto focus, uses
+		4 mipi lanes, preview config = 2104 x 1560 at 49 fps,
+		snapshot config = 4208 x 3120 at 24 fps,
+		Video HDR support.
+
+config OV2720
+	bool "Sensor OV2720 (BAYER 2M)"
+	depends on MSMB_CAMERA
+	---help---
+		OmniVision 2 MP Bayer Sensor, supports 2 mipi lanes,
+		preview and snapshot config at 1932 * 1092 at 30 fps,
+		hfr video at 60, 90 and 120 fps. This sensor driver does
+		not support auto focus.
+
+config MT9M114
+	bool "Sensor MT9M114 (YUV 1.26MP)"
+	depends on MSMB_CAMERA
+	---help---
+		MT9M114 is Aptina YUV sensor. It supports 1.26 MP preview
+		and snapshot. The preview and snapshot resolution shall be
+		1280 * 270. It does not support auto focus. It supports
+		few special effects like saturation.
+
+config MSM_V4L2_VIDEO_OVERLAY_DEVICE
+	tristate "Qualcomm MSM V4l2 video overlay device"
+	---help---
+	  Enables support for the MSM V4L2 video
+	  overlay driver. This allows video rendering
+	  apps to render overlaid video using Video4Linux2
+	  APIs, by using /dev/videoX device
+
+config MSMB_JPEG
+	tristate "Qualcomm MSM Jpeg Encoder Engine support"
+	depends on MSMB_CAMERA && ARCH_MSM8974
+	---help---
+	  Enable support for Jpeg Encoder/Decoder
+	  Engine for 8974.
+	  This module serves as the common driver
+	  for the JPEG 1.0 encoder and decoder.
+
diff --git a/drivers/media/platform/msm/camera_v2/Makefile b/drivers/media/platform/msm/camera_v2/Makefile
new file mode 100644
index 0000000..a1c5ea5
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/Makefile
@@ -0,0 +1,18 @@
+ccflags-y += -Idrivers/media/platform/msm/camera_v2
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/codecs
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/isps
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/pproc
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/msm_vb2
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/camera
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/jpeg_10
+
+obj-$(CONFIG_MSMB_CAMERA) += msm.o
+obj-$(CONFIG_MSMB_CAMERA) += camera/
+obj-$(CONFIG_MSMB_CAMERA) += msm_vb2/
+obj-$(CONFIG_MSMB_CAMERA) += sensor/
+obj-$(CONFIG_MSMB_CAMERA) += isp/
+obj-$(CONFIG_MSMB_CAMERA) += ispif/
+obj-$(CONFIG_MSMB_JPEG) += jpeg_10/
+obj-$(CONFIG_MSMB_CAMERA) += msm_buf_mgr/
+obj-$(CONFIG_MSMB_CAMERA) += pproc/
diff --git a/drivers/media/platform/msm/camera_v2/camera/Makefile b/drivers/media/platform/msm/camera_v2/camera/Makefile
new file mode 100644
index 0000000..bd70750
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/camera/Makefile
@@ -0,0 +1,3 @@
+ccflags-y += -Idrivers/media/platform/msm/camera_v2
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/msm_vb2
+obj-$(CONFIG_MSMB_CAMERA) += camera.o
diff --git a/drivers/media/platform/msm/camera_v2/camera/camera.c b/drivers/media/platform/msm/camera_v2/camera/camera.c
new file mode 100644
index 0000000..63ab4bf
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/camera/camera.c
@@ -0,0 +1,700 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+
+#include <linux/of.h>
+#include <linux/module.h>
+#include <linux/workqueue.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/ioctl.h>
+#include <linux/spinlock.h>
+#include <linux/proc_fs.h>
+#include <linux/atomic.h>
+#include <linux/wait.h>
+#include <linux/videodev2.h>
+#include <linux/msm_ion.h>
+#include <linux/iommu.h>
+#include <linux/platform_device.h>
+#include <media/v4l2-fh.h>
+
+#include "camera.h"
+#include "msm.h"
+#include "msm_vb2.h"
+
+#define fh_to_private(__fh) \
+	container_of(__fh, struct camera_v4l2_private, fh)
+
+struct camera_v4l2_private {
+	struct v4l2_fh fh;
+	unsigned int stream_id;
+	struct vb2_queue vb2_q;
+};
+
+static void camera_pack_event(struct file *filep, int evt_id,
+	int command, struct v4l2_event *event)
+{
+	struct msm_v4l2_event_data *event_data =
+		(struct msm_v4l2_event_data *)&event->u.data[0];
+	struct msm_video_device *pvdev = video_drvdata(filep);
+	struct camera_v4l2_private *sp = fh_to_private(filep->private_data);
+
+	/* always MSM_CAMERA_V4L2_EVENT_TYPE */
+	event->type = MSM_CAMERA_V4L2_EVENT_TYPE;
+	event->id = evt_id;
+	event_data->command = command;
+	event_data->session_id = pvdev->vdev->num;
+	event_data->stream_id = sp->stream_id;
+}
+
+static int camera_check_event_status(struct v4l2_event *event)
+{
+	struct msm_v4l2_event_data *event_data =
+		(struct msm_v4l2_event_data *)&event->u.data[0];
+
+	if (event_data->status > MSM_CAMERA_ERR_EVT_BASE)
+		return -EFAULT;
+
+	return 0;
+}
+
+static int camera_v4l2_querycap(struct file *filep, void *fh,
+	struct v4l2_capability *cap)
+{
+	int rc;
+	struct v4l2_event event;
+
+	/* can use cap->driver to make differentiation */
+	camera_pack_event(filep, MSM_CAMERA_GET_PARM,
+		MSM_CAMERA_PRIV_QUERY_CAP, &event);
+
+	rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
+	if (rc < 0)
+		return rc;
+
+	rc = camera_check_event_status(&event);
+
+	return rc;
+}
+
+static int camera_v4l2_s_crop(struct file *filep, void *fh,
+	struct v4l2_crop *crop)
+{
+	int rc = 0;
+	struct v4l2_event event;
+
+	if (crop->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+
+		camera_pack_event(filep, MSM_CAMERA_SET_PARM,
+			MSM_CAMERA_PRIV_S_CROP, &event);
+
+		rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
+		if (rc < 0)
+			return rc;
+
+		rc = camera_check_event_status(&event);
+	}
+
+	return rc;
+}
+
+static int camera_v4l2_g_crop(struct file *filep, void *fh,
+	struct v4l2_crop *crop)
+{
+	int rc = 0;
+	struct v4l2_event event;
+
+	if (crop->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+		camera_pack_event(filep, MSM_CAMERA_GET_PARM,
+			MSM_CAMERA_PRIV_G_CROP, &event);
+
+		rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
+		if (rc < 0)
+			return rc;
+
+		rc = camera_check_event_status(&event);
+	}
+
+	return rc;
+}
+
+static int camera_v4l2_queryctrl(struct file *filep, void *fh,
+	struct v4l2_queryctrl *ctrl)
+{
+	int rc = 0;
+	struct v4l2_event event;
+
+	if (ctrl->type == V4L2_CTRL_TYPE_MENU) {
+
+		camera_pack_event(filep, MSM_CAMERA_GET_PARM,
+			ctrl->id, &event);
+
+		rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
+		if (rc < 0)
+			return rc;
+
+		rc = camera_check_event_status(&event);
+	}
+
+	return rc;
+}
+
+static int camera_v4l2_g_ctrl(struct file *filep, void *fh,
+	struct v4l2_control *ctrl)
+{
+	int rc = 0;
+	struct v4l2_event event;
+
+	if (ctrl->id >= V4L2_CID_PRIVATE_BASE) {
+		camera_pack_event(filep, MSM_CAMERA_GET_PARM, ctrl->id, &event);
+
+		rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
+		if (rc < 0)
+			return rc;
+
+		rc = camera_check_event_status(&event);
+	}
+
+	return rc;
+}
+
+static int camera_v4l2_s_ctrl(struct file *filep, void *fh,
+	struct v4l2_control *ctrl)
+{
+	int rc = 0;
+	struct v4l2_event event;
+	if (ctrl->id >= V4L2_CID_PRIVATE_BASE) {
+		camera_pack_event(filep, MSM_CAMERA_SET_PARM, ctrl->id, &event);
+
+		rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
+		if (rc < 0)
+			return rc;
+
+		rc = camera_check_event_status(&event);
+	}
+
+	return rc;
+}
+
+static int camera_v4l2_reqbufs(struct file *filep, void *fh,
+	struct v4l2_requestbuffers *req)
+{
+	struct camera_v4l2_private *sp = fh_to_private(fh);
+
+	return vb2_reqbufs(&sp->vb2_q, req);
+}
+
+static int camera_v4l2_querybuf(struct file *filep, void *fh,
+	struct v4l2_buffer *pb)
+{
+	return 0;
+}
+
+static int camera_v4l2_qbuf(struct file *filep, void *fh,
+	struct v4l2_buffer *pb)
+{
+	struct camera_v4l2_private *sp = fh_to_private(fh);
+
+	return vb2_qbuf(&sp->vb2_q, pb);
+}
+
+static int camera_v4l2_dqbuf(struct file *filep, void *fh,
+	struct v4l2_buffer *pb)
+{
+	struct camera_v4l2_private *sp = fh_to_private(fh);
+
+	return vb2_dqbuf(&sp->vb2_q, pb, filep->f_flags & O_NONBLOCK);
+}
+
+static int camera_v4l2_streamon(struct file *filep, void *fh,
+	enum v4l2_buf_type buf_type)
+{
+	struct v4l2_event event;
+	int rc;
+	struct camera_v4l2_private *sp = fh_to_private(fh);
+
+	rc = vb2_streamon(&sp->vb2_q, buf_type);
+	camera_pack_event(filep, MSM_CAMERA_SET_PARM,
+		MSM_CAMERA_PRIV_STREAM_ON, &event);
+
+	rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
+	if (rc < 0)
+		return rc;
+
+	rc = camera_check_event_status(&event);
+	return rc;
+}
+
+static int camera_v4l2_streamoff(struct file *filep, void *fh,
+		enum v4l2_buf_type buf_type)
+{
+	struct v4l2_event event;
+	int rc;
+	struct camera_v4l2_private *sp = fh_to_private(fh);
+
+	camera_pack_event(filep, MSM_CAMERA_SET_PARM,
+		MSM_CAMERA_PRIV_STREAM_OFF, &event);
+
+	rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
+	if (rc < 0)
+		return rc;
+
+	rc = camera_check_event_status(&event);
+	vb2_streamoff(&sp->vb2_q, buf_type);
+	return rc;
+}
+
+static int camera_v4l2_g_fmt_vid_cap_mplane(struct file *filep, void *fh,
+	struct v4l2_format *pfmt)
+{
+	int rc = -EINVAL;
+
+	if (pfmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+		struct v4l2_event event;
+
+		camera_pack_event(filep, MSM_CAMERA_GET_PARM,
+			MSM_CAMERA_PRIV_G_FMT, &event);
+
+		rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
+		if (rc < 0)
+			return rc;
+
+		rc = camera_check_event_status(&event);
+	}
+
+	return rc;
+}
+
+static int camera_v4l2_s_fmt_vid_cap_mplane(struct file *filep, void *fh,
+	struct v4l2_format *pfmt)
+{
+	int rc = 0;
+	int i = 0;
+	struct v4l2_event event;
+	struct camera_v4l2_private *sp = fh_to_private(fh);
+	struct msm_v4l2_format_data *user_fmt;
+
+	if (pfmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+
+		if (WARN_ON(!sp->vb2_q.drv_priv))
+			return -ENOMEM;
+
+		memcpy(sp->vb2_q.drv_priv, pfmt->fmt.raw_data,
+			sizeof(struct msm_v4l2_format_data));
+		user_fmt = (struct msm_v4l2_format_data *)sp->vb2_q.drv_priv;
+
+		pr_debug("%s: num planes :%c\n", __func__,
+					user_fmt->num_planes);
+		for (i = 0; i < user_fmt->num_planes; i++)
+			pr_debug("%s: plane size[%d]\n", __func__,
+					user_fmt->plane_sizes[i]);
+
+		camera_pack_event(filep, MSM_CAMERA_SET_PARM,
+			MSM_CAMERA_PRIV_S_FMT, &event);
+
+		rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
+		if (rc < 0)
+			goto set_fmt_fail;
+
+		rc = camera_check_event_status(&event);
+		if (rc < 0)
+			goto set_fmt_fail;
+	}
+
+	return rc;
+
+set_fmt_fail:
+	kfree(sp->vb2_q.drv_priv);
+	return rc;
+}
+
+static int camera_v4l2_try_fmt_vid_cap_mplane(struct file *filep, void *fh,
+	struct v4l2_format *pfmt)
+{
+	return 0;
+}
+
+
+static int camera_v4l2_g_parm(struct file *filep, void *fh,
+	struct v4l2_streamparm *a)
+{
+	/* TODO */
+	return 0;
+}
+
+static int camera_v4l2_s_parm(struct file *filep, void *fh,
+	struct v4l2_streamparm *parm)
+{
+	int rc = 0;
+	struct v4l2_event event;
+	struct msm_v4l2_event_data *event_data =
+		(struct msm_v4l2_event_data *)&event.u.data[0];
+	struct camera_v4l2_private *sp = fh_to_private(fh);
+
+	camera_pack_event(filep, MSM_CAMERA_SET_PARM,
+		MSM_CAMERA_PRIV_NEW_STREAM, &event);
+
+	rc = msm_create_stream(event_data->session_id,
+		event_data->stream_id, &sp->vb2_q);
+	if (rc < 0)
+		return rc;
+
+	rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
+	if (rc < 0)
+		goto error;
+
+	rc = camera_check_event_status(&event);
+	if (rc < 0)
+		goto error;
+
+	/* use stream_id as stream index */
+	parm->parm.capture.extendedmode = sp->stream_id;
+
+	return rc;
+
+error:
+	msm_delete_stream(event_data->session_id,
+		event_data->stream_id);
+	return rc;
+}
+
+static int camera_v4l2_subscribe_event(struct v4l2_fh *fh,
+	struct v4l2_event_subscription *sub)
+{
+	int rc = 0;
+	struct camera_v4l2_private *sp = fh_to_private(fh);
+
+	rc = v4l2_event_subscribe(&sp->fh, sub, 5);
+
+	return rc;
+}
+
+static int camera_v4l2_unsubscribe_event(struct v4l2_fh *fh,
+	struct v4l2_event_subscription *sub)
+{
+	int rc = 0;
+	struct camera_v4l2_private *sp = fh_to_private(fh);
+
+	rc = v4l2_event_unsubscribe(&sp->fh, sub);
+
+	return rc;
+}
+
+static const struct v4l2_ioctl_ops camera_v4l2_ioctl_ops = {
+	.vidioc_querycap = camera_v4l2_querycap,
+	.vidioc_s_crop = camera_v4l2_s_crop,
+	.vidioc_g_crop = camera_v4l2_g_crop,
+	.vidioc_queryctrl = camera_v4l2_queryctrl,
+	.vidioc_g_ctrl = camera_v4l2_g_ctrl,
+	.vidioc_s_ctrl = camera_v4l2_s_ctrl,
+	.vidioc_reqbufs = camera_v4l2_reqbufs,
+	.vidioc_querybuf = camera_v4l2_querybuf,
+	.vidioc_qbuf = camera_v4l2_qbuf,
+	.vidioc_dqbuf = camera_v4l2_dqbuf,
+	.vidioc_streamon =  camera_v4l2_streamon,
+	.vidioc_streamoff = camera_v4l2_streamoff,
+	.vidioc_g_fmt_vid_cap_mplane = camera_v4l2_g_fmt_vid_cap_mplane,
+	.vidioc_s_fmt_vid_cap_mplane = camera_v4l2_s_fmt_vid_cap_mplane,
+	.vidioc_try_fmt_vid_cap_mplane = camera_v4l2_try_fmt_vid_cap_mplane,
+
+	/* Stream type-dependent parameter ioctls */
+	.vidioc_g_parm = camera_v4l2_g_parm,
+	.vidioc_s_parm = camera_v4l2_s_parm,
+
+	/* event subscribe/unsubscribe */
+	.vidioc_subscribe_event = camera_v4l2_subscribe_event,
+	.vidioc_unsubscribe_event = camera_v4l2_unsubscribe_event,
+};
+
+static int camera_v4l2_fh_open(struct file *filep)
+{
+	struct msm_video_device *pvdev = video_drvdata(filep);
+	struct camera_v4l2_private *sp;
+
+	sp = kzalloc(sizeof(*sp), GFP_KERNEL);
+	if (!sp)
+		return -ENOMEM;
+
+	filep->private_data = &sp->fh;
+
+	/* stream_id = open id */
+	sp->stream_id = atomic_read(&pvdev->opened);
+
+	v4l2_fh_init(&sp->fh, pvdev->vdev);
+	v4l2_fh_add(&sp->fh);
+
+	return 0;
+}
+
+static int camera_v4l2_fh_release(struct file *filep)
+{
+	struct camera_v4l2_private *sp = fh_to_private(filep->private_data);
+
+	if (sp) {
+		v4l2_fh_del(&sp->fh);
+		v4l2_fh_exit(&sp->fh);
+	}
+
+	kfree(sp);
+	return 0;
+}
+
+static int camera_v4l2_vb2_q_init(struct file *filep)
+{
+	struct camera_v4l2_private *sp = fh_to_private(filep->private_data);
+	struct vb2_queue *q = &sp->vb2_q;
+
+	memset(q, 0, sizeof(struct vb2_queue));
+
+	/* free up this buffer when stream is done */
+	q->drv_priv =
+		kzalloc(sizeof(struct msm_v4l2_format_data), GFP_KERNEL);
+	if (!q->drv_priv)
+		return -ENOMEM;
+
+	q->mem_ops = msm_vb2_get_q_mem_ops();
+	q->ops = msm_vb2_get_q_ops();
+
+	/* default queue type */
+	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+	q->io_modes = VB2_USERPTR;
+	q->io_flags = 0;
+	q->buf_struct_size = sizeof(struct msm_vb2_buffer);
+	vb2_queue_init(q);
+
+	return 0;
+}
+
+static void camera_v4l2_vb2_q_release(struct file *filep)
+{
+	struct camera_v4l2_private *sp = filep->private_data;
+
+	kfree(sp->vb2_q.drv_priv);
+	vb2_queue_release(&sp->vb2_q);
+}
+
+static int camera_v4l2_open(struct file *filep)
+{
+	int rc = 0;
+	struct v4l2_event event;
+	struct msm_video_device *pvdev = video_drvdata(filep);
+	BUG_ON(!pvdev);
+
+	rc = camera_v4l2_fh_open(filep);
+	if (rc < 0)
+		goto fh_open_fail;
+
+	/* every stream has a vb2 queue */
+	rc = camera_v4l2_vb2_q_init(filep);
+	if (rc < 0)
+		goto vb2_q_fail;
+
+	if (!atomic_read(&pvdev->opened)) {
+
+		/* create a new session when first opened */
+		rc = msm_create_session(pvdev->vdev->num, pvdev->vdev);
+		if (rc < 0)
+			goto session_fail;
+
+		rc = msm_create_command_ack_q(pvdev->vdev->num, 0);
+		if (rc < 0)
+			goto command_ack_q_fail;
+
+		camera_pack_event(filep, MSM_CAMERA_NEW_SESSION, 0, &event);
+		rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
+		if (rc < 0)
+			goto post_fail;
+
+		rc = camera_check_event_status(&event);
+		if (rc < 0)
+			goto post_fail;
+	} else {
+		rc = msm_create_command_ack_q(pvdev->vdev->num,
+			atomic_read(&pvdev->opened));
+		if (rc < 0)
+			goto session_fail;
+	}
+
+	atomic_add(1, &pvdev->opened);
+	return rc;
+
+post_fail:
+	msm_delete_command_ack_q(pvdev->vdev->num, 0);
+command_ack_q_fail:
+	msm_destroy_session(pvdev->vdev->num);
+session_fail:
+	camera_v4l2_vb2_q_release(filep);
+vb2_q_fail:
+	camera_v4l2_fh_release(filep);
+fh_open_fail:
+	return rc;
+}
+
+static unsigned int camera_v4l2_poll(struct file *filep,
+	struct poll_table_struct *wait)
+{
+	int rc = 0;
+	struct camera_v4l2_private *sp = fh_to_private(filep->private_data);
+
+	rc = vb2_poll(&sp->vb2_q, filep, wait);
+
+	poll_wait(filep, &sp->fh.wait, wait);
+	if (v4l2_event_pending(&sp->fh))
+		rc |= POLLPRI;
+
+	return rc;
+}
+
+static int camera_v4l2_close(struct file *filep)
+{
+	int rc = 0;
+	struct v4l2_event event;
+	struct msm_video_device *pvdev = video_drvdata(filep);
+	struct camera_v4l2_private *sp = fh_to_private(filep->private_data);
+
+	BUG_ON(!pvdev);
+
+	atomic_sub_return(1, &pvdev->opened);
+
+	if (atomic_read(&pvdev->opened) == 0) {
+
+		camera_pack_event(filep, MSM_CAMERA_DEL_SESSION, 0, &event);
+
+		/* Donot wait, imaging server may have crashed */
+		msm_post_event(&event, -1);
+
+		/* This should take care of both normal close
+		 * and application crashes */
+		msm_destroy_session(pvdev->vdev->num);
+
+	} else {
+		camera_pack_event(filep, MSM_CAMERA_SET_PARM,
+			MSM_CAMERA_PRIV_DEL_STREAM, &event);
+
+		/* Donot wait, imaging server may have crashed */
+		msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
+
+		msm_delete_command_ack_q(pvdev->vdev->num,
+			sp->stream_id);
+
+		msm_delete_stream(pvdev->vdev->num, sp->stream_id);
+	}
+
+	camera_v4l2_vb2_q_release(filep);
+	camera_v4l2_fh_release(filep);
+
+	return rc;
+}
+
+static struct v4l2_file_operations camera_v4l2_fops = {
+	.owner   = THIS_MODULE,
+	.open	= camera_v4l2_open,
+	.poll	= camera_v4l2_poll,
+	.release = camera_v4l2_close,
+	.ioctl   = video_ioctl2,
+};
+
+int camera_init_v4l2(struct device *dev, unsigned int *session)
+{
+	struct msm_video_device *pvdev;
+	struct v4l2_device *v4l2_dev;
+	int rc = 0;
+
+	pvdev = kzalloc(sizeof(struct msm_video_device),
+		GFP_KERNEL);
+	if (WARN_ON(!pvdev)) {
+		rc = -ENOMEM;
+		goto init_end;
+	}
+
+	pvdev->vdev = video_device_alloc();
+	if (WARN_ON(!pvdev->vdev)) {
+		rc = -ENOMEM;
+		goto video_fail;
+	}
+
+	v4l2_dev = kzalloc(sizeof(struct v4l2_device), GFP_KERNEL);
+	if (WARN_ON(!v4l2_dev)) {
+		rc = -ENOMEM;
+		goto v4l2_fail;
+	}
+
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	v4l2_dev->mdev = kzalloc(sizeof(struct media_device),
+							 GFP_KERNEL);
+	if (!v4l2_dev->mdev) {
+		rc = -ENOMEM;
+		goto mdev_fail;
+	}
+	strlcpy(v4l2_dev->mdev->model, MSM_CAMERA_NAME,
+			sizeof(v4l2_dev->mdev->model));
+
+	v4l2_dev->mdev->dev = dev;
+
+	rc = media_device_register(v4l2_dev->mdev);
+	if (WARN_ON(rc < 0))
+		goto media_fail;
+
+	rc = media_entity_init(&pvdev->vdev->entity, 0, NULL, 0);
+	if (WARN_ON(rc < 0))
+		goto entity_fail;
+	pvdev->vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
+	pvdev->vdev->entity.group_id = QCAMERA_VNODE_GROUP_ID;
+#endif
+
+	v4l2_dev->notify = NULL;
+	pvdev->vdev->v4l2_dev = v4l2_dev;
+
+	rc = v4l2_device_register(dev, pvdev->vdev->v4l2_dev);
+	if (WARN_ON(rc < 0))
+		goto register_fail;
+
+	strlcpy(pvdev->vdev->name, "msm-sensor", sizeof(pvdev->vdev->name));
+	pvdev->vdev->release  = video_device_release;
+	pvdev->vdev->fops     = &camera_v4l2_fops;
+	pvdev->vdev->ioctl_ops = &camera_v4l2_ioctl_ops;
+	pvdev->vdev->minor     = -1;
+	pvdev->vdev->vfl_type  = VFL_TYPE_GRABBER;
+	rc = video_register_device(pvdev->vdev,
+		VFL_TYPE_GRABBER, -1);
+	if (WARN_ON(rc < 0))
+		goto video_register_fail;
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	/* FIXME: How to get rid of this messy? */
+	pvdev->vdev->entity.name = video_device_node_name(pvdev->vdev);
+#endif
+
+	*session = pvdev->vdev->num;
+	atomic_set(&pvdev->opened, 0);
+	video_set_drvdata(pvdev->vdev, pvdev);
+	goto init_end;
+
+video_register_fail:
+	v4l2_device_unregister(pvdev->vdev->v4l2_dev);
+register_fail:
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&pvdev->vdev->entity);
+entity_fail:
+	media_device_unregister(v4l2_dev->mdev);
+media_fail:
+	kfree(v4l2_dev->mdev);
+mdev_fail:
+#endif
+	kfree(v4l2_dev);
+v4l2_fail:
+	video_device_release(pvdev->vdev);
+video_fail:
+	kfree(pvdev);
+init_end:
+	return rc;
+}
diff --git a/drivers/media/platform/msm/camera_v2/camera/camera.h b/drivers/media/platform/msm/camera_v2/camera/camera.h
new file mode 100644
index 0000000..ac860a4
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/camera/camera.h
@@ -0,0 +1,23 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CAMERA_H
+#define _CAMERA_H
+
+enum stream_state {
+	START_STREAM = 0,
+	STOP_STREAM,
+};
+
+int camera_init_v4l2(struct device *dev, unsigned int *session);
+
+#endif /*_CAMERA_H */
diff --git a/drivers/media/platform/msm/camera_v2/isp/Makefile b/drivers/media/platform/msm/camera_v2/isp/Makefile
new file mode 100644
index 0000000..f6e7cc4
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/isp/Makefile
@@ -0,0 +1,4 @@
+ccflags-y += -Idrivers/media/platform/msm/camera_v2
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io
+obj-$(CONFIG_MSMB_CAMERA) += msm_isp.o msm_buf_mgr.o msm_isp_util.o msm_isp_axi_util.o msm_isp_stats_util.o
+obj-$(CONFIG_MSMB_CAMERA) += msm_isp40.o msm_isp32.o
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
new file mode 100644
index 0000000..8ce8dbf
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
@@ -0,0 +1,691 @@
+/* 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/workqueue.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/ioctl.h>
+#include <linux/spinlock.h>
+#include <linux/videodev2.h>
+#include <linux/proc_fs.h>
+#include <linux/videodev2.h>
+#include <linux/vmalloc.h>
+#include <linux/android_pmem.h>
+
+#include <media/v4l2-dev.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
+#include <media/videobuf2-core.h>
+#include <media/msm_camera.h>
+#include <media/msm_isp.h>
+
+#include <mach/iommu.h>
+
+#include "msm.h"
+#include "msm_buf_mgr.h"
+
+/*#define CONFIG_MSM_ISP_DBG*/
+#undef CDBG
+#ifdef CONFIG_MSM_ISP_DBG
+#define CDBG(fmt, args...) pr_err(fmt, ##args)
+#else
+#define CDBG(fmt, args...) do { } while (0)
+#endif
+
+static struct msm_isp_bufq *msm_isp_get_bufq(
+	struct msm_isp_buf_mgr *buf_mgr,
+	uint32_t bufq_handle)
+{
+	struct msm_isp_bufq *bufq = NULL;
+	uint32_t bufq_index = bufq_handle & 0xFF;
+	if (bufq_index > buf_mgr->num_buf_q)
+		return bufq;
+
+	bufq = &buf_mgr->bufq[bufq_index];
+	if (bufq->bufq_handle == bufq_handle)
+		return bufq;
+
+	return NULL;
+}
+
+static struct msm_isp_buffer *msm_isp_get_buf_ptr(
+	struct msm_isp_buf_mgr *buf_mgr,
+	uint32_t bufq_handle, uint32_t buf_index)
+{
+	struct msm_isp_bufq *bufq = NULL;
+	struct msm_isp_buffer *buf_info = NULL;
+
+	bufq = msm_isp_get_bufq(buf_mgr, bufq_handle);
+	if (!bufq) {
+		pr_err("%s: Invalid bufq\n", __func__);
+		return buf_info;
+	}
+
+	if (bufq->num_bufs <= buf_index) {
+		pr_err("%s: Invalid buf index\n", __func__);
+		return buf_info;
+	}
+	buf_info = &bufq->bufs[buf_index];
+	return buf_info;
+}
+
+static uint32_t msm_isp_get_buf_handle(
+	struct msm_isp_buf_mgr *buf_mgr)
+{
+	int i;
+	if ((buf_mgr->buf_handle_cnt << 8) == 0)
+		buf_mgr->buf_handle_cnt++;
+
+	for (i = 0; i < buf_mgr->num_buf_q; i++) {
+		if (buf_mgr->bufq[i].bufq_handle == 0) {
+			memset(&buf_mgr->bufq[i],
+				0, sizeof(struct msm_isp_bufq));
+			buf_mgr->bufq[i].bufq_handle =
+				(++buf_mgr->buf_handle_cnt) << 8 | i;
+			return buf_mgr->bufq[i].bufq_handle;
+		}
+	}
+	return 0;
+}
+
+static int msm_isp_free_buf_handle(struct msm_isp_buf_mgr *buf_mgr,
+	uint32_t bufq_handle)
+{
+	struct msm_isp_bufq *bufq =
+		msm_isp_get_bufq(buf_mgr, bufq_handle);
+	if (!bufq)
+		return -EINVAL;
+	memset(bufq, 0, sizeof(struct msm_isp_bufq));
+	return 0;
+}
+
+static int msm_isp_prepare_v4l2_buf(struct msm_isp_buf_mgr *buf_mgr,
+	struct msm_isp_buffer *buf_info,
+	struct v4l2_buffer *v4l2_buf)
+{
+	int i, rc = -1;
+	struct msm_isp_buffer_mapped_info *mapped_info;
+	for (i = 0; i < v4l2_buf->length; i++) {
+		mapped_info = &buf_info->mapped_info[i];
+		mapped_info->handle =
+		ion_import_dma_buf(buf_mgr->client,
+			v4l2_buf->m.planes[i].m.userptr);
+		if (IS_ERR_OR_NULL(mapped_info->handle)) {
+			pr_err("%s: buf has null/error ION handle %p\n",
+				__func__, mapped_info->handle);
+			goto ion_map_error;
+		}
+		if (ion_map_iommu(buf_mgr->client, mapped_info->handle,
+				buf_mgr->iommu_domain_num, 0, SZ_4K,
+				0, &(mapped_info->paddr),
+				&(mapped_info->len), 0, 0) < 0) {
+			rc = -EINVAL;
+			pr_err("%s: cannot map address", __func__);
+			ion_free(buf_mgr->client, mapped_info->handle);
+			goto ion_map_error;
+		}
+		mapped_info->paddr += v4l2_buf->m.planes[i].data_offset;
+		CDBG("%s: plane: %d addr:%lu\n",
+			__func__, i, mapped_info->paddr);
+	}
+	buf_info->num_planes = v4l2_buf->length;
+	return 0;
+ion_map_error:
+	for (--i; i >= 0; 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);
+	}
+	return rc;
+}
+
+static void msm_isp_unprepare_v4l2_buf(
+	struct msm_isp_buf_mgr *buf_mgr,
+	struct msm_isp_buffer *buf_info)
+{
+	int i;
+	struct msm_isp_buffer_mapped_info *mapped_info;
+	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);
+	}
+	return;
+}
+
+static int msm_isp_buf_prepare(struct msm_isp_buf_mgr *buf_mgr,
+	struct msm_isp_qbuf_info *info, struct vb2_buffer *vb2_buf)
+{
+	int rc = -1;
+	struct msm_isp_buffer *buf_info = NULL;
+	struct v4l2_buffer *buf = NULL;
+	struct v4l2_plane *plane = NULL;
+
+	buf_info = msm_isp_get_buf_ptr(buf_mgr,
+		info->handle, info->buf_idx);
+	if (!buf_info) {
+		pr_err("Invalid buffer prepare\n");
+		return rc;
+	}
+
+	if (buf_info->state == MSM_ISP_BUFFER_STATE_DIVERTED)
+		return buf_info->state;
+
+	if (buf_info->state != MSM_ISP_BUFFER_STATE_INITIALIZED) {
+		pr_err("%s: Invalid buffer state: %d\n",
+			__func__, buf_info->state);
+		return rc;
+	}
+
+	if (vb2_buf) {
+		buf = &vb2_buf->v4l2_buf;
+		buf_info->vb2_buf = vb2_buf;
+	} else {
+		buf = &info->buffer;
+		plane =
+			kzalloc(sizeof(struct v4l2_plane) * buf->length,
+				GFP_KERNEL);
+		if (!plane) {
+			pr_err("%s: Cannot alloc plane: %d\n",
+			__func__, buf_info->state);
+			return rc;
+		}
+		if (copy_from_user(plane,
+				(void __user *)(buf->m.planes),
+			sizeof(struct v4l2_plane) * buf->length)) {
+			kfree(plane);
+			return rc;
+		}
+		buf->m.planes = plane;
+	}
+
+	rc = msm_isp_prepare_v4l2_buf(buf_mgr, buf_info, buf);
+	if (rc < 0) {
+		pr_err("%s: Prepare buffer error\n", __func__);
+		kfree(plane);
+		return rc;
+	}
+	buf_info->state = MSM_ISP_BUFFER_STATE_PREPARED;
+	kfree(plane);
+	return rc;
+}
+
+static int msm_isp_buf_unprepare(struct msm_isp_buf_mgr *buf_mgr,
+	uint32_t buf_handle)
+{
+	int rc = -1, i;
+	struct msm_isp_bufq *bufq = NULL;
+	struct msm_isp_buffer *buf_info = NULL;
+	bufq = msm_isp_get_bufq(buf_mgr, buf_handle);
+	if (!bufq) {
+		pr_err("%s: Invalid bufq\n", __func__);
+		return rc;
+	}
+
+	for (i = 0; i < bufq->num_bufs; i++) {
+		buf_info = msm_isp_get_buf_ptr(buf_mgr, buf_handle, i);
+		if (buf_info->state == MSM_ISP_BUFFER_STATE_UNUSED ||
+				buf_info->state ==
+					MSM_ISP_BUFFER_STATE_INITIALIZED)
+			continue;
+		msm_isp_unprepare_v4l2_buf(buf_mgr, buf_info);
+	}
+	return 0;
+}
+
+static int msm_isp_get_buf(struct msm_isp_buf_mgr *buf_mgr,
+	uint32_t bufq_handle, struct msm_isp_buffer **buf_info)
+{
+	int rc = -1;
+	struct msm_isp_buffer *temp_buf_info;
+	struct msm_isp_bufq *bufq = NULL;
+	struct vb2_buffer *vb2_buf = NULL;
+	bufq = msm_isp_get_bufq(buf_mgr, bufq_handle);
+	if (!bufq) {
+		pr_err("%s: Invalid bufq\n", __func__);
+		return rc;
+	}
+
+	*buf_info = NULL;
+	if (BUF_SRC(bufq->stream_id)) {
+		list_for_each_entry(temp_buf_info, &bufq->head, list) {
+			if (temp_buf_info->state ==
+					MSM_ISP_BUFFER_STATE_QUEUED) {
+				/* found one buf */
+				list_del_init(&temp_buf_info->list);
+				*buf_info = temp_buf_info;
+				break;
+			}
+		}
+	} else {
+		vb2_buf = buf_mgr->vb2_ops->get_buf(
+			bufq->session_id, bufq->stream_id);
+		if (vb2_buf) {
+			if (vb2_buf->v4l2_buf.index < bufq->num_bufs) {
+				*buf_info =
+					&bufq->bufs[vb2_buf->v4l2_buf.index];
+				(*buf_info)->vb2_buf = vb2_buf;
+			} else {
+				pr_err("%s: Incorrect buf index %d\n",
+					__func__, vb2_buf->v4l2_buf.index);
+				return -EINVAL;
+			}
+		}
+	}
+
+	if (!(*buf_info))
+		return rc;
+
+
+	(*buf_info)->state = MSM_ISP_BUFFER_STATE_DEQUEUED;
+	return 0;
+}
+
+static int msm_isp_put_buf(struct msm_isp_buf_mgr *buf_mgr,
+	uint32_t bufq_handle, uint32_t buf_index)
+{
+	int rc = -1;
+	struct msm_isp_bufq *bufq = NULL;
+	struct msm_isp_buffer *buf_info = NULL;
+
+	bufq = msm_isp_get_bufq(buf_mgr, bufq_handle);
+	if (!bufq) {
+		pr_err("%s: Invalid bufq\n", __func__);
+		return rc;
+	}
+
+	buf_info = msm_isp_get_buf_ptr(buf_mgr, bufq_handle, buf_index);
+	if (!buf_info) {
+		pr_err("%s: buf not found\n", __func__);
+		return rc;
+	}
+
+	switch (buf_info->state) {
+	case MSM_ISP_BUFFER_STATE_PREPARED:
+	case MSM_ISP_BUFFER_STATE_DEQUEUED:
+	case MSM_ISP_BUFFER_STATE_DISPATCHED:
+	case MSM_ISP_BUFFER_STATE_DIVERTED:
+		if (BUF_SRC(bufq->stream_id))
+			list_add_tail(&buf_info->list, &bufq->head);
+		else
+			buf_mgr->vb2_ops->put_buf(buf_info->vb2_buf,
+				bufq->session_id, bufq->stream_id);
+		buf_info->state = MSM_ISP_BUFFER_STATE_QUEUED;
+		rc = 0;
+		break;
+	default:
+		pr_err("%s: incorrect state = %d",
+			__func__, buf_info->state);
+		break;
+	}
+
+	return rc;
+}
+
+static int msm_isp_buf_done(struct msm_isp_buf_mgr *buf_mgr,
+	uint32_t bufq_handle, uint32_t buf_index,
+	struct timeval *tv, uint32_t frame_id)
+{
+	int rc = -1;
+	struct msm_isp_bufq *bufq = NULL;
+	struct msm_isp_buffer *buf_info = NULL;
+
+	bufq = msm_isp_get_bufq(buf_mgr, bufq_handle);
+	if (!bufq) {
+		pr_err("Invalid bufq\n");
+		return rc;
+	}
+
+	buf_info = msm_isp_get_buf_ptr(buf_mgr, bufq_handle, buf_index);
+	if (!buf_info) {
+		pr_err("%s: buf not found\n", __func__);
+		return rc;
+	}
+
+	if (buf_info->state == MSM_ISP_BUFFER_STATE_DEQUEUED ||
+		buf_info->state == MSM_ISP_BUFFER_STATE_DIVERTED) {
+		buf_info->state = MSM_ISP_BUFFER_STATE_DISPATCHED;
+		if ((BUF_SRC(bufq->stream_id))) {
+			rc = msm_isp_put_buf(buf_mgr, buf_info->bufq_handle,
+						buf_info->buf_idx);
+			if (rc < 0) {
+				pr_err("%s: Buf put failed\n", __func__);
+				return rc;
+			}
+		} else {
+			buf_info->vb2_buf->v4l2_buf.timestamp = *tv;
+			buf_info->vb2_buf->v4l2_buf.sequence  = frame_id;
+			buf_mgr->vb2_ops->buf_done(buf_info->vb2_buf,
+				bufq->session_id, bufq->stream_id);
+		}
+	}
+
+	return 0;
+}
+
+static int msm_isp_flush_buf(struct msm_isp_buf_mgr *buf_mgr,
+		uint32_t bufq_handle, enum msm_isp_buffer_flush_t flush_type)
+{
+	int rc = -1, i;
+	struct msm_isp_bufq *bufq = NULL;
+	struct msm_isp_buffer *buf_info = NULL;
+
+	bufq = msm_isp_get_bufq(buf_mgr, bufq_handle);
+	if (!bufq) {
+		pr_err("Invalid bufq\n");
+		return rc;
+	}
+
+	for (i = 0; i < bufq->num_bufs; i++) {
+		buf_info = msm_isp_get_buf_ptr(buf_mgr, bufq_handle, i);
+		if (!buf_info) {
+			pr_err("%s: buf not found\n", __func__);
+			continue;
+		}
+
+		if (flush_type == MSM_ISP_BUFFER_FLUSH_DIVERTED &&
+			buf_info->state == MSM_ISP_BUFFER_STATE_DIVERTED) {
+			buf_info->state = MSM_ISP_BUFFER_STATE_QUEUED;
+		} else if (flush_type == MSM_ISP_BUFFER_FLUSH_ALL &&
+			(buf_info->state == MSM_ISP_BUFFER_STATE_DEQUEUED ||
+			buf_info->state == MSM_ISP_BUFFER_STATE_DIVERTED ||
+			buf_info->state == MSM_ISP_BUFFER_STATE_DISPATCHED)) {
+			buf_info->state = MSM_ISP_BUFFER_STATE_QUEUED;
+		}
+	}
+	return 0;
+}
+
+static int msm_isp_buf_divert(struct msm_isp_buf_mgr *buf_mgr,
+	uint32_t bufq_handle, uint32_t buf_index,
+	struct timeval *tv, uint32_t frame_id)
+{
+	int rc = -1;
+	struct msm_isp_bufq *bufq = NULL;
+	struct msm_isp_buffer *buf_info = NULL;
+
+	bufq = msm_isp_get_bufq(buf_mgr, bufq_handle);
+	if (!bufq) {
+		pr_err("Invalid bufq\n");
+		return rc;
+	}
+
+	buf_info = msm_isp_get_buf_ptr(buf_mgr, bufq_handle, buf_index);
+	if (!buf_info) {
+		pr_err("%s: buf not found\n", __func__);
+		return rc;
+	}
+
+	if (buf_info->state == MSM_ISP_BUFFER_STATE_DEQUEUED) {
+		buf_info->state = MSM_ISP_BUFFER_STATE_DIVERTED;
+		buf_info->tv = tv;
+		buf_info->frame_id = frame_id;
+	}
+
+	return 0;
+}
+
+static int msm_isp_buf_enqueue(struct msm_isp_buf_mgr *buf_mgr,
+	struct msm_isp_qbuf_info *info)
+{
+	int rc = -1, buf_state;
+	struct msm_isp_bufq *bufq = NULL;
+	struct msm_isp_buffer *buf_info = NULL;
+	buf_state = msm_isp_buf_prepare(buf_mgr, info, NULL);
+	if (buf_state < 0) {
+		pr_err("%s: Buf prepare failed\n", __func__);
+		return -EINVAL;
+	}
+
+	if (buf_state == MSM_ISP_BUFFER_STATE_DIVERTED) {
+		buf_info = msm_isp_get_buf_ptr(buf_mgr,
+						info->handle, info->buf_idx);
+		if (info->dirty_buf)
+			msm_isp_put_buf(buf_mgr, info->handle, info->buf_idx);
+		else
+			msm_isp_buf_done(buf_mgr, info->handle, info->buf_idx,
+				buf_info->tv, buf_info->frame_id);
+	} else {
+		bufq = msm_isp_get_bufq(buf_mgr, info->handle);
+		if (BUF_SRC(bufq->stream_id)) {
+			rc = msm_isp_put_buf(buf_mgr,
+					info->handle, info->buf_idx);
+			if (rc < 0) {
+				pr_err("%s: Buf put failed\n", __func__);
+				return rc;
+			}
+		}
+	}
+	return rc;
+}
+
+static int msm_isp_get_bufq_handle(struct msm_isp_buf_mgr *buf_mgr,
+	uint32_t session_id, uint32_t stream_id)
+{
+	int i;
+	for (i = 0; i < buf_mgr->num_buf_q; i++) {
+		if (buf_mgr->bufq[i].session_id == session_id &&
+			buf_mgr->bufq[i].stream_id == stream_id) {
+			return buf_mgr->bufq[i].bufq_handle;
+		}
+	}
+	return 0;
+}
+
+static int msm_isp_request_bufq(struct msm_isp_buf_mgr *buf_mgr,
+	struct msm_isp_buf_request *buf_request)
+{
+	int rc = -1, i;
+	struct msm_isp_bufq *bufq = NULL;
+	CDBG("%s: E\n", __func__);
+
+	if (!buf_request->num_buf) {
+		pr_err("Invalid buffer request\n");
+		return rc;
+	}
+
+	buf_request->handle = msm_isp_get_buf_handle(buf_mgr);
+	if (!buf_request->handle) {
+		pr_err("Invalid buffer handle\n");
+		return rc;
+	}
+
+	bufq = msm_isp_get_bufq(buf_mgr, buf_request->handle);
+	if (!bufq) {
+		pr_err("Invalid buffer queue\n");
+		return rc;
+	}
+
+	bufq->bufs = kzalloc(sizeof(struct msm_isp_buffer) *
+		buf_request->num_buf, GFP_KERNEL);
+	if (!bufq->bufs) {
+		pr_err("No free memory for buf info\n");
+		msm_isp_free_buf_handle(buf_mgr, buf_request->handle);
+		return rc;
+	}
+
+	bufq->bufq_handle = buf_request->handle;
+	bufq->session_id = buf_request->session_id;
+	bufq->stream_id = buf_request->stream_id;
+	bufq->num_bufs = buf_request->num_buf;
+	INIT_LIST_HEAD(&bufq->head);
+	for (i = 0; i < buf_request->num_buf; i++) {
+		bufq->bufs[i].state = MSM_ISP_BUFFER_STATE_INITIALIZED;
+		bufq->bufs[i].bufq_handle = bufq->bufq_handle;
+		bufq->bufs[i].buf_idx = i;
+	}
+
+	return 0;
+}
+
+static int msm_isp_release_bufq(struct msm_isp_buf_mgr *buf_mgr,
+	uint32_t bufq_handle)
+{
+	struct msm_isp_bufq *bufq = NULL;
+	int rc = -1;
+	bufq = msm_isp_get_bufq(buf_mgr, bufq_handle);
+	if (!bufq) {
+		pr_err("Invalid bufq release\n");
+		return rc;
+	}
+
+	msm_isp_buf_unprepare(buf_mgr, bufq_handle);
+
+	kfree(bufq->bufs);
+	msm_isp_free_buf_handle(buf_mgr, bufq_handle);
+	return 0;
+}
+
+static void msm_isp_release_all_bufq(
+	struct msm_isp_buf_mgr *buf_mgr)
+{
+	struct msm_isp_bufq *bufq = NULL;
+	int i;
+	for (i = 0; i < buf_mgr->num_buf_q; i++) {
+		bufq = &buf_mgr->bufq[i];
+		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);
+	}
+}
+
+static int msm_isp_attach_ctx(struct msm_isp_buf_mgr *buf_mgr,
+	struct device *iommu_ctx)
+{
+	int rc;
+	rc = iommu_attach_device(buf_mgr->iommu_domain, iommu_ctx);
+	if (rc) {
+		pr_err("%s: Iommu attach error\n", __func__);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static void msm_isp_detach_ctx(struct msm_isp_buf_mgr *buf_mgr,
+	struct device *iommu_ctx)
+{
+	iommu_detach_device(buf_mgr->iommu_domain, iommu_ctx);
+}
+
+static int msm_isp_init_isp_buf_mgr(
+	struct msm_isp_buf_mgr *buf_mgr,
+	const char *ctx_name, uint16_t num_buf_q)
+{
+	int rc = -1;
+	if (!num_buf_q) {
+		pr_err("Invalid buffer queue number\n");
+		return rc;
+	}
+
+	CDBG("%s: E\n", __func__);
+	buf_mgr->num_buf_q = num_buf_q;
+	buf_mgr->bufq =
+		kzalloc(sizeof(struct msm_isp_bufq) * num_buf_q,
+		GFP_KERNEL);
+	if (!buf_mgr->bufq) {
+		pr_err("Bufq malloc error\n");
+		goto bufq_error;
+	}
+	buf_mgr->client = msm_ion_client_create(-1, ctx_name);
+	buf_mgr->buf_handle_cnt = 0;
+
+	return 0;
+bufq_error:
+	return rc;
+}
+
+static int msm_isp_deinit_isp_buf_mgr(
+	struct msm_isp_buf_mgr *buf_mgr)
+{
+	msm_isp_release_all_bufq(buf_mgr);
+	ion_client_destroy(buf_mgr->client);
+	kfree(buf_mgr->bufq);
+	buf_mgr->num_buf_q = 0;
+	return 0;
+}
+
+int msm_isp_proc_buf_cmd(struct msm_isp_buf_mgr *buf_mgr,
+	unsigned int cmd, void *arg)
+{
+	switch (cmd) {
+	case VIDIOC_MSM_ISP_REQUEST_BUF: {
+		struct msm_isp_buf_request *buf_req = arg;
+		buf_mgr->ops->request_buf(buf_mgr, buf_req);
+		break;
+	}
+	case VIDIOC_MSM_ISP_ENQUEUE_BUF: {
+		struct msm_isp_qbuf_info *qbuf_info = arg;
+		buf_mgr->ops->enqueue_buf(buf_mgr, qbuf_info);
+		break;
+	}
+	case VIDIOC_MSM_ISP_RELEASE_BUF: {
+		struct msm_isp_buf_request *buf_req = arg;
+		buf_mgr->ops->release_buf(buf_mgr, buf_req->handle);
+		break;
+	}
+	}
+	return 0;
+}
+
+static struct msm_isp_buf_ops isp_buf_ops = {
+	.request_buf = msm_isp_request_bufq,
+	.enqueue_buf = msm_isp_buf_enqueue,
+	.release_buf = msm_isp_release_bufq,
+	.get_bufq_handle = msm_isp_get_bufq_handle,
+	.get_buf = msm_isp_get_buf,
+	.put_buf = msm_isp_put_buf,
+	.flush_buf = msm_isp_flush_buf,
+	.buf_done = msm_isp_buf_done,
+	.buf_divert = msm_isp_buf_divert,
+	.attach_ctx = msm_isp_attach_ctx,
+	.detach_ctx = msm_isp_detach_ctx,
+	.buf_mgr_init = msm_isp_init_isp_buf_mgr,
+	.buf_mgr_deinit = msm_isp_deinit_isp_buf_mgr,
+};
+
+int msm_isp_create_isp_buf_mgr(
+	struct msm_isp_buf_mgr *buf_mgr,
+	struct msm_sd_req_vb2_q *vb2_ops,
+	struct msm_iova_layout *iova_layout)
+{
+	int rc = 0;
+	if (buf_mgr->init_done)
+		return rc;
+
+	buf_mgr->iommu_domain_num = msm_register_domain(iova_layout);
+	if (buf_mgr->iommu_domain_num < 0) {
+		pr_err("%s: Invalid iommu domain number\n", __func__);
+		rc = -1;
+		goto iommu_domain_error;
+	}
+
+	buf_mgr->iommu_domain = msm_get_iommu_domain(
+		buf_mgr->iommu_domain_num);
+	if (!buf_mgr->iommu_domain) {
+		pr_err("%s: Invalid iommu domain\n", __func__);
+		rc = -1;
+		goto iommu_domain_error;
+	}
+
+	buf_mgr->ops = &isp_buf_ops;
+	buf_mgr->vb2_ops = vb2_ops;
+	buf_mgr->init_done = 1;
+	buf_mgr->ref_count = 0;
+	return 0;
+iommu_domain_error:
+	return rc;
+}
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
new file mode 100644
index 0000000..244a1e2
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h
@@ -0,0 +1,136 @@
+/* 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 _MSM_ISP_BUF_H_
+#define _MSM_ISP_BUF_H_
+
+#include <media/msmb_isp.h>
+#include <mach/iommu_domains.h>
+#include "msm_sd.h"
+
+/*Buffer source can be from userspace / HAL*/
+#define BUF_SRC(id) (id & ISP_NATIVE_BUF_BIT)
+
+struct msm_isp_buf_mgr;
+
+enum msm_isp_buffer_state {
+	MSM_ISP_BUFFER_STATE_UNUSED,         /* not used */
+	MSM_ISP_BUFFER_STATE_INITIALIZED,    /* REQBUF done */
+	MSM_ISP_BUFFER_STATE_PREPARED,       /* BUF mapped */
+	MSM_ISP_BUFFER_STATE_QUEUED,         /* buf queued */
+	MSM_ISP_BUFFER_STATE_DEQUEUED,       /* in use in VFE */
+	MSM_ISP_BUFFER_STATE_DIVERTED,       /* Sent to other hardware*/
+	MSM_ISP_BUFFER_STATE_DISPATCHED,     /* Sent to HAL*/
+};
+
+enum msm_isp_buffer_flush_t {
+	MSM_ISP_BUFFER_FLUSH_DIVERTED,
+	MSM_ISP_BUFFER_FLUSH_ALL,
+};
+
+struct msm_isp_buffer_mapped_info {
+	unsigned long len;
+	unsigned long paddr;
+	struct ion_handle *handle;
+};
+
+struct msm_isp_buffer {
+	/*Common Data structure*/
+	int num_planes;
+	struct msm_isp_buffer_mapped_info mapped_info[VIDEO_MAX_PLANES];
+	int buf_idx;
+	uint32_t bufq_handle;
+	uint32_t frame_id;
+	struct timeval *tv;
+
+	/*Native buffer*/
+	struct list_head list;
+	enum msm_isp_buffer_state state;
+
+	/*Vb2 buffer data*/
+	struct vb2_buffer *vb2_buf;
+
+};
+
+struct msm_isp_bufq {
+	uint32_t session_id;
+	uint32_t stream_id;
+	uint32_t num_bufs;
+	uint32_t bufq_handle;
+	struct msm_isp_buffer *bufs;
+
+	/*Native buffer queue*/
+	struct list_head head;
+};
+
+struct msm_isp_buf_ops {
+	int (*request_buf) (struct msm_isp_buf_mgr *buf_mgr,
+		struct msm_isp_buf_request *buf_request);
+
+	int (*enqueue_buf) (struct msm_isp_buf_mgr *buf_mgr,
+		struct msm_isp_qbuf_info *info);
+
+	int (*release_buf) (struct msm_isp_buf_mgr *buf_mgr,
+		uint32_t bufq_handle);
+
+	int (*get_bufq_handle) (struct msm_isp_buf_mgr *buf_mgr,
+		uint32_t session_id, uint32_t stream_id);
+
+	int (*get_buf) (struct msm_isp_buf_mgr *buf_mgr,
+		uint32_t bufq_handle, struct msm_isp_buffer **buf_info);
+
+	int (*put_buf) (struct msm_isp_buf_mgr *buf_mgr,
+		uint32_t bufq_handle, uint32_t buf_index);
+
+	int (*flush_buf) (struct msm_isp_buf_mgr *buf_mgr,
+		uint32_t bufq_handle, enum msm_isp_buffer_flush_t flush_type);
+
+	int (*buf_done) (struct msm_isp_buf_mgr *buf_mgr,
+		uint32_t bufq_handle, uint32_t buf_index,
+		struct timeval *tv, uint32_t frame_id);
+	int (*buf_divert) (struct msm_isp_buf_mgr *buf_mgr,
+		uint32_t bufq_handle, uint32_t buf_index,
+		struct timeval *tv, uint32_t frame_id);
+	int (*attach_ctx) (struct msm_isp_buf_mgr *buf_mgr,
+		struct device *iommu_ctx);
+	void (*detach_ctx) (struct msm_isp_buf_mgr *buf_mgr,
+		struct device *iommu_ctx);
+	int (*buf_mgr_init) (struct msm_isp_buf_mgr *buf_mgr,
+		const char *ctx_name, uint16_t num_buf_q);
+	int (*buf_mgr_deinit) (struct msm_isp_buf_mgr *buf_mgr);
+};
+
+struct msm_isp_buf_mgr {
+	int init_done;
+	uint32_t ref_count;
+	spinlock_t lock;
+	uint16_t num_buf_q;
+	struct msm_isp_bufq *bufq;
+
+	struct ion_client *client;
+	struct msm_isp_buf_ops *ops;
+	uint32_t buf_handle_cnt;
+
+	struct msm_sd_req_vb2_q *vb2_ops;
+
+	/*IOMMU specific*/
+	int iommu_domain_num;
+	struct iommu_domain *iommu_domain;
+};
+
+int msm_isp_create_isp_buf_mgr(struct msm_isp_buf_mgr *buf_mgr,
+	struct msm_sd_req_vb2_q *vb2_ops, struct msm_iova_layout *iova_layout);
+
+int msm_isp_proc_buf_cmd(struct msm_isp_buf_mgr *buf_mgr,
+	unsigned int cmd, void *arg);
+
+#endif /* _MSM_ISP_BUF_H_ */
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
new file mode 100644
index 0000000..ff86aae
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
@@ -0,0 +1,168 @@
+/* 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/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/debugfs.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-device.h>
+#include <mach/board.h>
+#include <mach/vreg.h>
+#include <mach/iommu.h>
+
+#include "msm_isp.h"
+#include "msm_isp_util.h"
+#include "msm_isp_axi_util.h"
+#include "msm_isp_stats_util.h"
+#include "msm_sd.h"
+#include "msm_isp40.h"
+#include "msm_isp32.h"
+
+static struct msm_sd_req_vb2_q vfe_vb2_ops;
+
+static const struct of_device_id msm_vfe_dt_match[] = {
+	{
+		.compatible = "qcom,vfe40",
+		.data = &vfe40_hw_info,
+	},
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, msm_vfe_dt_match);
+
+static const struct platform_device_id msm_vfe_dev_id[] = {
+	{"msm_vfe32", (kernel_ulong_t) &vfe32_hw_info},
+	{}
+};
+
+static struct msm_isp_buf_mgr vfe_buf_mgr;
+
+static int __devinit vfe_probe(struct platform_device *pdev)
+{
+	struct vfe_device *vfe_dev;
+	/*struct msm_cam_subdev_info sd_info;*/
+	const struct of_device_id *match_dev;
+	int rc = 0;
+
+	struct msm_iova_partition vfe_partition = {
+		.start = SZ_128K,
+		.size = SZ_2G - SZ_128K,
+	};
+	struct msm_iova_layout vfe_layout = {
+		.partitions = &vfe_partition,
+		.npartitions = 1,
+		.client_name = "vfe",
+		.domain_flags = 0,
+	};
+
+	vfe_dev = kzalloc(sizeof(struct vfe_device), GFP_KERNEL);
+	if (!vfe_dev) {
+		pr_err("%s: no enough memory\n", __func__);
+		return -ENOMEM;
+	}
+
+	if (pdev->dev.of_node) {
+		of_property_read_u32((&pdev->dev)->of_node,
+			"cell-index", &pdev->id);
+		match_dev = of_match_device(msm_vfe_dt_match, &pdev->dev);
+		vfe_dev->hw_info =
+			(struct msm_vfe_hardware_info *) match_dev->data;
+	} else {
+		vfe_dev->hw_info = (struct msm_vfe_hardware_info *)
+			platform_get_device_id(pdev)->driver_data;
+	}
+
+	if (!vfe_dev->hw_info) {
+		pr_err("%s: No vfe hardware info\n", __func__);
+		return -EINVAL;
+	}
+	ISP_DBG("%s: device id = %d\n", __func__, pdev->id);
+
+	vfe_dev->pdev = pdev;
+	rc = vfe_dev->hw_info->vfe_ops.core_ops.get_platform_data(vfe_dev);
+	if (rc < 0) {
+		pr_err("%s: failed to get platform resources\n", __func__);
+		kfree(vfe_dev);
+		return -ENOMEM;
+	}
+
+	INIT_LIST_HEAD(&vfe_dev->tasklet_q);
+	tasklet_init(&vfe_dev->vfe_tasklet,
+		msm_isp_do_tasklet, (unsigned long)vfe_dev);
+
+	v4l2_subdev_init(&vfe_dev->subdev.sd, vfe_dev->hw_info->subdev_ops);
+	vfe_dev->subdev.sd.internal_ops =
+		vfe_dev->hw_info->subdev_internal_ops;
+	snprintf(vfe_dev->subdev.sd.name,
+		ARRAY_SIZE(vfe_dev->subdev.sd.name),
+		"vfe");
+	vfe_dev->subdev.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	vfe_dev->subdev.sd.flags |= V4L2_SUBDEV_FL_HAS_EVENTS;
+	v4l2_set_subdevdata(&vfe_dev->subdev.sd, vfe_dev);
+	platform_set_drvdata(pdev, &vfe_dev->subdev.sd);
+	mutex_init(&vfe_dev->mutex);
+	spin_lock_init(&vfe_dev->tasklet_lock);
+	spin_lock_init(&vfe_dev->shared_data_lock);
+	media_entity_init(&vfe_dev->subdev.sd.entity, 0, NULL, 0);
+	vfe_dev->subdev.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	vfe_dev->subdev.sd.entity.group_id = MSM_CAMERA_SUBDEV_VFE;
+	vfe_dev->subdev.sd.entity.name = pdev->name;
+	rc = msm_sd_register(&vfe_dev->subdev);
+	if (rc != 0) {
+		pr_err("%s: msm_sd_register error = %d\n", __func__, rc);
+		kfree(vfe_dev);
+		goto end;
+	}
+
+	vfe_dev->buf_mgr = &vfe_buf_mgr;
+	v4l2_subdev_notify(&vfe_dev->subdev.sd,
+		MSM_SD_NOTIFY_REQ_CB, &vfe_vb2_ops);
+	rc = msm_isp_create_isp_buf_mgr(vfe_dev->buf_mgr,
+		&vfe_vb2_ops, &vfe_layout);
+	if (rc < 0) {
+		pr_err("%s: Unable to create buffer manager\n", __func__);
+		kfree(vfe_dev);
+		return -EINVAL;
+	}
+	vfe_dev->vfe_open_cnt = 0;
+end:
+	return rc;
+}
+
+static struct platform_driver vfe_driver = {
+	.probe = vfe_probe,
+	.driver = {
+		.name = "msm_vfe",
+		.owner = THIS_MODULE,
+		.of_match_table = msm_vfe_dt_match,
+	},
+	.id_table = msm_vfe_dev_id,
+};
+
+static int __init msm_vfe_init_module(void)
+{
+	return platform_driver_register(&vfe_driver);
+}
+
+static void __exit msm_vfe_exit_module(void)
+{
+	platform_driver_unregister(&vfe_driver);
+}
+
+module_init(msm_vfe_init_module);
+module_exit(msm_vfe_exit_module);
+MODULE_DESCRIPTION("MSM VFE driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
new file mode 100644
index 0000000..69d523c
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
@@ -0,0 +1,391 @@
+/* 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 __MSM_VFE_H__
+#define __MSM_VFE_H__
+
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/completion.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <media/v4l2-subdev.h>
+#include <media/msmb_isp.h>
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
+
+#include "msm_buf_mgr.h"
+
+#define MAX_IOMMU_CTX 2
+#define MAX_NUM_WM 7
+#define MAX_NUM_RDI 3
+#define MAX_NUM_RDI_MASTER 3
+#define MAX_NUM_COMPOSITE_MASK 4
+#define MAX_NUM_STATS_COMP_MASK 2
+#define MAX_INIT_FRAME_DROP 31
+#define ISP_SUB(a) ((a > 0) ? a-1 : 0)
+
+#define VFE_PING_FLAG 0xFFFFFFFF
+#define VFE_PONG_FLAG 0x0
+
+struct vfe_device;
+struct msm_vfe_axi_stream;
+struct msm_vfe_stats_stream;
+
+struct vfe_subscribe_info {
+	struct v4l2_fh *vfh;
+	uint32_t active;
+};
+
+enum msm_isp_camif_update_state {
+	NO_UPDATE,
+	ENABLE_CAMIF,
+	DISABLE_CAMIF,
+	DISABLE_CAMIF_IMMEDIATELY
+};
+
+struct msm_isp_timestamp {
+	/*Monotonic clock for v4l2 buffer*/
+	struct timeval buf_time;
+	/*Wall clock for userspace event*/
+	struct timeval event_time;
+};
+
+struct msm_vfe_irq_ops {
+	void (*read_irq_status) (struct vfe_device *vfe_dev,
+		uint32_t *irq_status0, uint32_t *irq_status1);
+	void (*process_reg_update) (struct vfe_device *vfe_dev,
+		uint32_t irq_status0, uint32_t irq_status1,
+		struct msm_isp_timestamp *ts);
+	void (*process_reset_irq) (struct vfe_device *vfe_dev,
+		uint32_t irq_status0, uint32_t irq_status1);
+	void (*process_halt_irq) (struct vfe_device *vfe_dev,
+		uint32_t irq_status0, uint32_t irq_status1);
+	void (*process_camif_irq) (struct vfe_device *vfe_dev,
+		uint32_t irq_status0, uint32_t irq_status1,
+		struct msm_isp_timestamp *ts);
+	void (*process_axi_irq) (struct vfe_device *vfe_dev,
+		uint32_t irq_status0, uint32_t irq_status1,
+		struct msm_isp_timestamp *ts);
+	void (*process_stats_irq) (struct vfe_device *vfe_dev,
+		uint32_t irq_status0, uint32_t irq_status1,
+		struct msm_isp_timestamp *ts);
+};
+
+struct msm_vfe_axi_ops {
+	void (*reload_wm) (struct vfe_device *vfe_dev,
+		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,
+		struct msm_vfe_axi_stream_request_cmd *stream_req_cmd);
+	void (*cfg_framedrop) (struct vfe_device *vfe_dev,
+		struct msm_vfe_axi_stream *stream_info);
+	void (*clear_framedrop) (struct vfe_device *vfe_dev,
+		struct msm_vfe_axi_stream *stream_info);
+	void (*cfg_comp_mask) (struct vfe_device *vfe_dev,
+		struct msm_vfe_axi_stream *stream_info);
+	void (*clear_comp_mask) (struct vfe_device *vfe_dev,
+		struct msm_vfe_axi_stream *stream_info);
+	void (*cfg_wm_irq_mask) (struct vfe_device *vfe_dev,
+		struct msm_vfe_axi_stream *stream_info);
+	void (*clear_wm_irq_mask) (struct vfe_device *vfe_dev,
+		struct msm_vfe_axi_stream *stream_info);
+
+	void (*cfg_wm_reg) (struct vfe_device *vfe_dev,
+		struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd,
+		uint8_t plane_idx);
+	void (*clear_wm_reg) (struct vfe_device *vfe_dev,
+		struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx);
+
+	void (*cfg_wm_xbar_reg) (struct vfe_device *vfe_dev,
+		struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd,
+		uint8_t plane_idx);
+	void (*clear_wm_xbar_reg) (struct vfe_device *vfe_dev,
+		struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx);
+
+	void (*cfg_ub) (struct vfe_device *vfe_dev);
+
+	void (*update_ping_pong_addr) (struct vfe_device *vfe_dev,
+		uint8_t wm_idx, uint32_t pingpong_status, unsigned long paddr);
+
+	uint32_t (*get_wm_mask) (uint32_t irq_status0, uint32_t irq_status1);
+	uint32_t (*get_comp_mask) (uint32_t irq_status0, uint32_t irq_status1);
+	uint32_t (*get_pingpong_status) (struct vfe_device *vfe_dev);
+	long (*halt) (struct vfe_device *vfe_dev);
+};
+
+struct msm_vfe_core_ops {
+	void (*reg_update) (struct vfe_device *vfe_dev);
+	long (*reset_hw) (struct vfe_device *vfe_dev);
+	int (*init_hw) (struct vfe_device *vfe_dev);
+	void (*init_hw_reg) (struct vfe_device *vfe_dev);
+	void (*release_hw) (struct vfe_device *vfe_dev);
+	void (*cfg_camif) (struct vfe_device *vfe_dev,
+		struct msm_vfe_pix_cfg *pix_cfg);
+	void (*update_camif_state) (struct vfe_device *vfe_dev,
+		enum msm_isp_camif_update_state update_state);
+	void (*cfg_rdi_reg) (struct vfe_device *vfe_dev,
+		struct msm_vfe_rdi_cfg *rdi_cfg,
+		enum msm_vfe_input_src input_src);
+	int (*get_platform_data) (struct vfe_device *vfe_dev);
+	void (*get_error_mask) (uint32_t *error_mask0, uint32_t *error_mask1);
+	void (*process_error_status) (struct vfe_device *vfe_dev);
+};
+struct msm_vfe_stats_ops {
+	int (*get_stats_idx) (enum msm_isp_stats_type stats_type);
+	void (*cfg_framedrop) (struct vfe_device *vfe_dev,
+		struct msm_vfe_stats_stream *stream_info);
+	void (*clear_framedrop) (struct vfe_device *vfe_dev,
+		struct msm_vfe_stats_stream *stream_info);
+	void (*cfg_comp_mask) (struct vfe_device *vfe_dev);
+	void (*cfg_wm_irq_mask) (struct vfe_device *vfe_dev,
+		struct msm_vfe_stats_stream *stream_info);
+	void (*clear_wm_irq_mask) (struct vfe_device *vfe_dev,
+		struct msm_vfe_stats_stream *stream_info);
+
+	void (*cfg_wm_reg) (struct vfe_device *vfe_dev,
+		struct msm_vfe_stats_stream *stream_info);
+	void (*clear_wm_reg) (struct vfe_device *vfe_dev,
+		struct msm_vfe_stats_stream *stream_info);
+
+	void (*cfg_ub) (struct vfe_device *vfe_dev);
+
+	void (*enable_module) (struct vfe_device *vfe_dev,
+		uint32_t stats_mask, uint8_t enable);
+
+	void (*update_ping_pong_addr) (struct vfe_device *vfe_dev,
+		struct msm_vfe_stats_stream *stream_info,
+		uint32_t pingpong_status, unsigned long paddr);
+
+	uint32_t (*get_frame_id) (struct vfe_device *vfe_dev);
+	uint32_t (*get_wm_mask) (uint32_t irq_status0, uint32_t irq_status1);
+	uint32_t (*get_comp_mask) (uint32_t irq_status0, uint32_t irq_status1);
+	uint32_t (*get_pingpong_status) (struct vfe_device *vfe_dev);
+};
+
+struct msm_vfe_ops {
+	struct msm_vfe_irq_ops irq_ops;
+	struct msm_vfe_axi_ops axi_ops;
+	struct msm_vfe_core_ops core_ops;
+	struct msm_vfe_stats_ops stats_ops;
+};
+
+struct msm_vfe_hardware_info {
+	int num_iommu_ctx;
+	struct msm_vfe_ops vfe_ops;
+	struct msm_vfe_axi_hardware_info *axi_hw_info;
+	struct msm_vfe_stats_hardware_info *stats_hw_info;
+	struct v4l2_subdev_internal_ops *subdev_internal_ops;
+	struct v4l2_subdev_ops *subdev_ops;
+	uint32_t dmi_reg_offset;
+};
+
+struct msm_vfe_axi_hardware_info {
+	uint8_t num_wm;
+	uint8_t num_rdi;
+	uint8_t num_rdi_master;
+	uint8_t num_comp_mask;
+	uint32_t min_wm_ub;
+};
+
+enum msm_vfe_axi_state {
+	AVALIABLE,
+	INACTIVE,
+	ACTIVE,
+	PAUSE,
+	START_PENDING,
+	STOP_PENDING,
+	STOPPING,
+	PAUSE_PENDING,
+};
+
+#define VFE_NO_DROP            0xFFFFFFFF
+#define VFE_DROP_EVERY_2FRAME  0x55555555
+#define VFE_DROP_EVERY_4FRAME  0x11111111
+#define VFE_DROP_EVERY_8FRAME  0x01010101
+#define VFE_DROP_EVERY_16FRAME 0x00010001
+#define VFE_DROP_EVERY_32FRAME 0x00000001
+
+enum msm_vfe_axi_stream_type {
+	CONTINUOUS_STREAM,
+	BURST_STREAM,
+};
+
+struct msm_vfe_axi_stream {
+	uint32_t frame_id;
+	enum msm_vfe_axi_state state;
+	enum msm_vfe_axi_stream_src stream_src;
+	uint8_t num_planes;
+	uint8_t wm[MAX_PLANES_PER_STREAM];
+	uint8_t comp_mask_index;
+	struct msm_isp_buffer *buf[2];
+	uint32_t session_id;
+	uint32_t stream_id;
+	uint32_t bufq_handle;
+	uint32_t stream_handle;
+	uint8_t buf_divert;
+	enum msm_vfe_axi_stream_type stream_type;
+
+	uint32_t frame_based;
+	uint32_t framedrop_period;
+	uint32_t framedrop_pattern;
+	uint32_t num_burst_capture;/*number of frame to capture*/
+	uint32_t init_frame_drop;
+	uint32_t burst_frame_count;/*number of sof before burst stop*/
+	uint8_t framedrop_update;
+
+	/*Run time update variables*/
+	uint32_t runtime_init_frame_drop;
+	uint32_t runtime_burst_frame_count;/*number of sof before burst stop*/
+	uint8_t runtime_framedrop_update;
+};
+
+struct msm_vfe_axi_composite_info {
+	uint32_t stream_handle;
+	uint32_t stream_composite_mask;
+};
+
+struct msm_vfe_src_info {
+	unsigned long frame_id;
+	uint8_t active;
+	uint8_t pix_stream_count;
+	uint8_t raw_stream_count;
+	enum msm_vfe_inputmux input_mux;
+};
+
+enum msm_wm_ub_cfg_type {
+	MSM_WM_UB_CFG_DEFAULT,
+	MSM_WM_UB_EQUAL_SLICING,
+	MSM_WM_UB_CFG_MAX_NUM
+};
+
+struct msm_vfe_axi_shared_data {
+	struct msm_vfe_axi_hardware_info *hw_info;
+	struct msm_vfe_axi_stream stream_info[MAX_NUM_STREAM];
+	uint32_t free_wm[MAX_NUM_WM];
+	uint32_t wm_image_size[MAX_NUM_WM];
+	enum msm_wm_ub_cfg_type wm_ub_cfg_policy;
+	uint8_t num_used_wm;
+	uint8_t num_active_stream;
+	struct msm_vfe_axi_composite_info
+		composite_info[MAX_NUM_COMPOSITE_MASK];
+	uint8_t num_used_composite_mask;
+	uint32_t stream_update;
+	struct msm_vfe_src_info src_info[VFE_SRC_MAX];
+	uint16_t stream_handle_cnt;
+	unsigned long event_mask;
+};
+
+struct msm_vfe_stats_hardware_info {
+	uint32_t stats_capability_mask;
+	uint32_t stats_ping_pong_offset;
+	uint8_t num_stats_type;
+	uint8_t num_stats_comp_mask;
+};
+
+enum msm_vfe_stats_state {
+	STATS_AVALIABLE,
+	STATS_INACTIVE,
+	STATS_ACTIVE,
+	STATS_START_PENDING,
+	STATS_STOP_PENDING,
+	STATS_STOPPING,
+};
+
+struct msm_vfe_stats_stream {
+	uint32_t session_id;
+	uint32_t stream_id;
+	uint32_t stream_handle;
+	enum msm_isp_stats_type stats_type;
+	enum msm_vfe_stats_state state;
+	uint32_t framedrop_pattern;
+	uint32_t irq_subsample_pattern;
+
+	struct msm_isp_buffer *buf[2];
+	uint32_t bufq_handle;
+};
+
+struct msm_vfe_stats_shared_data {
+	struct msm_vfe_stats_stream stream_info[MSM_ISP_STATS_MAX];
+	enum msm_vfe_stats_pipeline_policy stats_pipeline_policy;
+	uint32_t comp_framedrop_pattern;
+	uint32_t comp_irq_subsample_pattern;
+	uint8_t num_active_stream;
+	uint16_t stream_handle_cnt;
+};
+
+struct msm_vfe_tasklet_queue_cmd {
+	struct list_head list;
+	uint32_t vfeInterruptStatus0;
+	uint32_t vfeInterruptStatus1;
+	struct msm_isp_timestamp ts;
+	uint8_t cmd_used;
+};
+
+#define MSM_VFE_TASKLETQ_SIZE 200
+
+struct msm_vfe_error_info {
+	uint32_t error_mask0;
+	uint32_t error_mask1;
+	uint32_t violation_status;
+	uint32_t camif_status;
+	uint32_t stream_framedrop_count[MAX_NUM_STREAM];
+	uint32_t stats_framedrop_count[MSM_ISP_STATS_MAX];
+	uint32_t info_dump_frame_count;
+	uint32_t error_count;
+};
+
+struct vfe_device {
+	struct platform_device *pdev;
+	struct msm_sd_subdev subdev;
+	struct resource *vfe_irq;
+	struct resource *vfe_mem;
+	struct resource *vfe_vbif_mem;
+	struct resource *vfe_io;
+	struct resource *vfe_vbif_io;
+	void __iomem *vfe_base;
+	void __iomem *vfe_vbif_base;
+
+	struct device *iommu_ctx[MAX_IOMMU_CTX];
+
+	struct regulator *fs_vfe;
+	struct clk *vfe_clk[7];
+
+	uint32_t bus_perf_client;
+
+	struct completion reset_complete;
+	struct completion halt_complete;
+	struct completion stream_config_complete;
+	struct mutex mutex;
+
+	atomic_t irq_cnt;
+	uint8_t taskletq_idx;
+	spinlock_t  tasklet_lock;
+	spinlock_t  shared_data_lock;
+	struct list_head tasklet_q;
+	struct tasklet_struct vfe_tasklet;
+	struct msm_vfe_tasklet_queue_cmd
+		tasklet_queue_cmd[MSM_VFE_TASKLETQ_SIZE];
+
+	struct msm_vfe_hardware_info *hw_info;
+
+	struct msm_vfe_axi_shared_data axi_data;
+	struct msm_vfe_stats_shared_data stats_data;
+	struct msm_vfe_error_info error_info;
+	struct msm_isp_buf_mgr *buf_mgr;
+	int dump_reg;
+	uint32_t vfe_open_cnt;
+};
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
new file mode 100644
index 0000000..b981653
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
@@ -0,0 +1,1092 @@
+/* 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/platform_device.h>
+#include <mach/iommu.h>
+
+#include "msm_isp32.h"
+#include "msm_isp_util.h"
+#include "msm_isp_axi_util.h"
+#include "msm_isp_stats_util.h"
+#include "msm_isp.h"
+#include "msm.h"
+#include "msm_camera_io_util.h"
+
+#define VFE32_BURST_LEN 3
+#define VFE32_UB_SIZE 1024
+#define VFE32_EQUAL_SLICE_UB 117
+#define VFE32_WM_BASE(idx) (0x4C + 0x18 * idx)
+#define VFE32_RDI_BASE(idx) (idx ? 0x734 + 0x4 * (idx - 1) : 0x06FC)
+#define VFE32_XBAR_BASE(idx) (0x40 + 0x4 * (idx / 4))
+#define VFE32_XBAR_SHIFT(idx) ((idx % 4) * 8)
+#define VFE32_PING_PONG_BASE(wm, ping_pong) \
+	(VFE32_WM_BASE(wm) + 0x4 * (1 + (~(ping_pong >> wm) & 0x1)))
+
+#define VFE32_NUM_STATS_TYPE 7
+#define VFE32_STATS_PING_PONG_OFFSET 7
+#define VFE32_STATS_BASE(idx) (0xF4 + 0xC * idx)
+#define VFE32_STATS_PING_PONG_BASE(idx, ping_pong) \
+	(VFE32_STATS_BASE(idx) + 0x4 * \
+	(~(ping_pong >> (idx + VFE32_STATS_PING_PONG_OFFSET)) & 0x1))
+
+/*Temporary use fixed bus vectors in VFE */
+static struct msm_bus_vectors msm_vfe32_init_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+};
+
+static struct msm_bus_vectors msm_vfe32_preview_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 1027648000,
+		.ib  = 1105920000,
+	},
+};
+
+static struct msm_bus_paths msm_vfe32_bus_client_config[] = {
+	{
+		ARRAY_SIZE(msm_vfe32_init_vectors),
+		msm_vfe32_init_vectors,
+	},
+	{
+		ARRAY_SIZE(msm_vfe32_preview_vectors),
+		msm_vfe32_preview_vectors,
+	},
+};
+
+static struct msm_bus_scale_pdata msm_vfe32_bus_client_pdata = {
+		msm_vfe32_bus_client_config,
+		ARRAY_SIZE(msm_vfe32_bus_client_config),
+		.name = "msm_camera_vfe",
+};
+
+static struct msm_cam_clk_info msm_vfe32_clk_info[] = {
+	{"vfe_clk", 266667000},
+	{"vfe_pclk", -1},
+	{"csi_vfe_clk", -1},
+};
+
+static int msm_vfe32_init_hardware(struct vfe_device *vfe_dev)
+{
+	int rc = -1;
+
+	vfe_dev->bus_perf_client =
+		msm_bus_scale_register_client(&msm_vfe32_bus_client_pdata);
+	if (!vfe_dev->bus_perf_client) {
+		pr_err("%s: Registration Failed!\n", __func__);
+		vfe_dev->bus_perf_client = 0;
+		goto bus_scale_register_failed;
+	}
+	msm_bus_scale_client_update_request(vfe_dev->bus_perf_client, 1);
+
+	if (vfe_dev->fs_vfe) {
+		rc = regulator_enable(vfe_dev->fs_vfe);
+		if (rc) {
+			pr_err("%s: Regulator enable failed\n", __func__);
+			goto fs_failed;
+		}
+	}
+
+	rc = msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe32_clk_info,
+		 vfe_dev->vfe_clk, ARRAY_SIZE(msm_vfe32_clk_info), 1);
+	if (rc < 0)
+		goto clk_enable_failed;
+
+	vfe_dev->vfe_base = ioremap(vfe_dev->vfe_mem->start,
+		resource_size(vfe_dev->vfe_mem));
+	if (!vfe_dev->vfe_base) {
+		rc = -ENOMEM;
+		pr_err("%s: vfe ioremap failed\n", __func__);
+		goto vfe_remap_failed;
+	}
+
+	rc = request_irq(vfe_dev->vfe_irq->start, msm_isp_process_irq,
+					 IRQF_TRIGGER_RISING, "vfe", vfe_dev);
+	if (rc < 0) {
+		pr_err("%s: irq request failed\n", __func__);
+		goto irq_req_failed;
+	}
+
+	return rc;
+irq_req_failed:
+	iounmap(vfe_dev->vfe_base);
+vfe_remap_failed:
+	msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe32_clk_info,
+		 vfe_dev->vfe_clk, ARRAY_SIZE(msm_vfe32_clk_info), 0);
+clk_enable_failed:
+	regulator_disable(vfe_dev->fs_vfe);
+fs_failed:
+	msm_bus_scale_client_update_request(vfe_dev->bus_perf_client, 0);
+	msm_bus_scale_unregister_client(vfe_dev->bus_perf_client);
+bus_scale_register_failed:
+	return rc;
+}
+
+static void msm_vfe32_release_hardware(struct vfe_device *vfe_dev)
+{
+	free_irq(vfe_dev->vfe_irq->start, vfe_dev);
+	tasklet_kill(&vfe_dev->vfe_tasklet);
+	iounmap(vfe_dev->vfe_base);
+	msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe32_clk_info,
+		 vfe_dev->vfe_clk, ARRAY_SIZE(msm_vfe32_clk_info), 0);
+	regulator_disable(vfe_dev->fs_vfe);
+	msm_bus_scale_client_update_request(vfe_dev->bus_perf_client, 0);
+	msm_bus_scale_unregister_client(vfe_dev->bus_perf_client);
+}
+
+static void msm_vfe32_init_hardware_reg(struct vfe_device *vfe_dev)
+{
+	/* CGC_OVERRIDE */
+	msm_camera_io_w(0x07FFFFFF, vfe_dev->vfe_base + 0xC);
+	/* BUS_CFG */
+	msm_camera_io_w(0x00000001, vfe_dev->vfe_base + 0x3C);
+	msm_camera_io_w(0x00000025, vfe_dev->vfe_base + 0x1C);
+	msm_camera_io_w_mb(0x1DFFFFFF, vfe_dev->vfe_base + 0x20);
+	msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x24);
+	msm_camera_io_w_mb(0x1FFFFFFF, vfe_dev->vfe_base + 0x28);
+}
+
+static void msm_vfe32_process_reset_irq(struct vfe_device *vfe_dev,
+	uint32_t irq_status0, uint32_t irq_status1)
+{
+	if (irq_status1 & BIT(23))
+		complete(&vfe_dev->reset_complete);
+}
+
+static void msm_vfe32_process_halt_irq(struct vfe_device *vfe_dev,
+	uint32_t irq_status0, uint32_t irq_status1)
+{
+	if (irq_status1 & BIT(24))
+		complete(&vfe_dev->halt_complete);
+}
+
+static void msm_vfe32_process_camif_irq(struct vfe_device *vfe_dev,
+	uint32_t irq_status0, uint32_t irq_status1,
+	struct msm_isp_timestamp *ts)
+{
+	if (!(irq_status0 & 0x1F))
+		return;
+
+	if (irq_status0 & BIT(0)) {
+		ISP_DBG("%s: PIX0 frame id: %lu\n", __func__,
+			vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id);
+		msm_isp_sof_notify(vfe_dev, VFE_PIX_0, ts);
+		ISP_DBG("%s: SOF IRQ\n", __func__);
+		if (vfe_dev->axi_data.src_info[VFE_PIX_0].raw_stream_count > 0
+			&& vfe_dev->axi_data.src_info[VFE_PIX_0].
+			pix_stream_count == 0) {
+			msm_isp_sof_notify(vfe_dev, VFE_PIX_0, ts);
+			msm_isp_update_framedrop_reg(vfe_dev);
+		}
+	}
+}
+
+static void msm_vfe32_process_violation_status(struct vfe_device *vfe_dev)
+{
+	uint32_t violation_status = vfe_dev->error_info.violation_status;
+	if (!violation_status)
+		return;
+
+	if (violation_status & BIT(0))
+		pr_err("%s: black violation\n", __func__);
+	if (violation_status & BIT(1))
+		pr_err("%s: rolloff violation\n", __func__);
+	if (violation_status & BIT(2))
+		pr_err("%s: demux violation\n", __func__);
+	if (violation_status & BIT(3))
+		pr_err("%s: demosaic violation\n", __func__);
+	if (violation_status & BIT(4))
+		pr_err("%s: crop violation\n", __func__);
+	if (violation_status & BIT(5))
+		pr_err("%s: scale violation\n", __func__);
+	if (violation_status & BIT(6))
+		pr_err("%s: wb violation\n", __func__);
+	if (violation_status & BIT(7))
+		pr_err("%s: clf violation\n", __func__);
+	if (violation_status & BIT(8))
+		pr_err("%s: matrix violation\n", __func__);
+	if (violation_status & BIT(9))
+		pr_err("%s: rgb lut violation\n", __func__);
+	if (violation_status & BIT(10))
+		pr_err("%s: la violation\n", __func__);
+	if (violation_status & BIT(11))
+		pr_err("%s: chroma enhance violation\n", __func__);
+	if (violation_status & BIT(12))
+		pr_err("%s: chroma supress mce violation\n", __func__);
+	if (violation_status & BIT(13))
+		pr_err("%s: skin enhance violation\n", __func__);
+	if (violation_status & BIT(14))
+		pr_err("%s: asf violation\n", __func__);
+	if (violation_status & BIT(15))
+		pr_err("%s: scale y violation\n", __func__);
+	if (violation_status & BIT(16))
+		pr_err("%s: scale cbcr violation\n", __func__);
+	if (violation_status & BIT(17))
+		pr_err("%s: chroma subsample violation\n", __func__);
+	if (violation_status & BIT(18))
+		pr_err("%s: framedrop enc y violation\n", __func__);
+	if (violation_status & BIT(19))
+		pr_err("%s: framedrop enc cbcr violation\n", __func__);
+	if (violation_status & BIT(20))
+		pr_err("%s: framedrop view y violation\n", __func__);
+	if (violation_status & BIT(21))
+		pr_err("%s: framedrop view cbcr violation\n", __func__);
+	if (violation_status & BIT(22))
+		pr_err("%s: realign buf y violation\n", __func__);
+	if (violation_status & BIT(23))
+		pr_err("%s: realign buf cb violation\n", __func__);
+	if (violation_status & BIT(24))
+		pr_err("%s: realign buf cr violation\n", __func__);
+}
+
+static void msm_vfe32_process_error_status(struct vfe_device *vfe_dev)
+{
+	uint32_t error_status1 = vfe_dev->error_info.error_mask1;
+
+	if (error_status1 & BIT(0))
+		pr_err("%s: camif error status: 0x%x\n",
+			__func__, vfe_dev->error_info.camif_status);
+	if (error_status1 & BIT(1))
+		pr_err("%s: stats bhist overwrite\n", __func__);
+	if (error_status1 & BIT(2))
+		pr_err("%s: stats cs overwrite\n", __func__);
+	if (error_status1 & BIT(3))
+		pr_err("%s: stats ihist overwrite\n", __func__);
+	if (error_status1 & BIT(4))
+		pr_err("%s: realign buf y overflow\n", __func__);
+	if (error_status1 & BIT(5))
+		pr_err("%s: realign buf cb overflow\n", __func__);
+	if (error_status1 & BIT(6))
+		pr_err("%s: realign buf cr overflow\n", __func__);
+	if (error_status1 & BIT(7)) {
+		pr_err("%s: violation\n", __func__);
+		msm_vfe32_process_violation_status(vfe_dev);
+	}
+	if (error_status1 & BIT(8))
+		pr_err("%s: image master 0 bus overflow\n", __func__);
+	if (error_status1 & BIT(9))
+		pr_err("%s: image master 1 bus overflow\n", __func__);
+	if (error_status1 & BIT(10))
+		pr_err("%s: image master 2 bus overflow\n", __func__);
+	if (error_status1 & BIT(11))
+		pr_err("%s: image master 3 bus overflow\n", __func__);
+	if (error_status1 & BIT(12))
+		pr_err("%s: image master 4 bus overflow\n", __func__);
+	if (error_status1 & BIT(13))
+		pr_err("%s: image master 5 bus overflow\n", __func__);
+	if (error_status1 & BIT(14))
+		pr_err("%s: image master 6 bus overflow\n", __func__);
+	if (error_status1 & BIT(15))
+		pr_err("%s: status ae/bg bus overflow\n", __func__);
+	if (error_status1 & BIT(16))
+		pr_err("%s: status af/bf bus overflow\n", __func__);
+	if (error_status1 & BIT(17))
+		pr_err("%s: status awb bus overflow\n", __func__);
+	if (error_status1 & BIT(18))
+		pr_err("%s: status rs bus overflow\n", __func__);
+	if (error_status1 & BIT(19))
+		pr_err("%s: status cs bus overflow\n", __func__);
+	if (error_status1 & BIT(20))
+		pr_err("%s: status ihist bus overflow\n", __func__);
+	if (error_status1 & BIT(21))
+		pr_err("%s: status skin bhist bus overflow\n", __func__);
+	if (error_status1 & BIT(22))
+		pr_err("%s: axi error\n", __func__);
+}
+
+static void msm_vfe32_read_irq_status(struct vfe_device *vfe_dev,
+	uint32_t *irq_status0, uint32_t *irq_status1)
+{
+	*irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x2C);
+	*irq_status1 = msm_camera_io_r(vfe_dev->vfe_base + 0x30);
+	msm_camera_io_w(*irq_status0, vfe_dev->vfe_base + 0x24);
+	msm_camera_io_w(*irq_status1, vfe_dev->vfe_base + 0x28);
+	msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x18);
+
+	if (*irq_status1 & BIT(0))
+		vfe_dev->error_info.camif_status =
+			msm_camera_io_r(vfe_dev->vfe_base + 0x204);
+
+	if (*irq_status1 & BIT(7))
+		vfe_dev->error_info.violation_status |=
+			msm_camera_io_r(vfe_dev->vfe_base + 0x7B4);
+}
+
+static void msm_vfe32_process_reg_update(struct vfe_device *vfe_dev,
+	uint32_t irq_status0, uint32_t irq_status1,
+	struct msm_isp_timestamp *ts)
+{
+	if (!(irq_status0 & 0x20) && !(irq_status1 & 0x1C000000))
+		return;
+
+	if (irq_status0 & BIT(5))
+		msm_isp_sof_notify(vfe_dev, VFE_PIX_0, ts);
+	if (irq_status1 & BIT(26))
+		msm_isp_sof_notify(vfe_dev, VFE_RAW_0, ts);
+	if (irq_status1 & BIT(27))
+		msm_isp_sof_notify(vfe_dev, VFE_RAW_1, ts);
+	if (irq_status1 & BIT(28))
+		msm_isp_sof_notify(vfe_dev, VFE_RAW_2, ts);
+
+	if (vfe_dev->axi_data.stream_update)
+		msm_isp_axi_stream_update(vfe_dev);
+	msm_isp_update_framedrop_reg(vfe_dev);
+	msm_isp_update_error_frame_count(vfe_dev);
+
+	vfe_dev->hw_info->vfe_ops.core_ops.
+		reg_update(vfe_dev);
+	return;
+}
+
+static void msm_vfe32_reg_update(
+	struct vfe_device *vfe_dev)
+{
+	msm_camera_io_w_mb(0xF, vfe_dev->vfe_base + 0x260);
+}
+
+static long msm_vfe32_reset_hardware(struct vfe_device *vfe_dev)
+{
+	init_completion(&vfe_dev->reset_complete);
+	msm_camera_io_w_mb(0x3FF, vfe_dev->vfe_base + 0x4);
+	return wait_for_completion_interruptible_timeout(
+	   &vfe_dev->reset_complete, msecs_to_jiffies(50));
+}
+
+static void msm_vfe32_axi_reload_wm(
+	struct vfe_device *vfe_dev, uint32_t reload_mask)
+{
+	msm_camera_io_w_mb(reload_mask, vfe_dev->vfe_base + 0x38);
+}
+
+static void msm_vfe32_axi_enable_wm(struct vfe_device *vfe_dev,
+	uint8_t wm_idx, uint8_t enable)
+{
+	uint32_t val = msm_camera_io_r(
+	   vfe_dev->vfe_base + VFE32_WM_BASE(wm_idx));
+	if (enable)
+		val |= 0x1;
+	else
+		val &= ~0x1;
+	msm_camera_io_w_mb(val,
+		vfe_dev->vfe_base + VFE32_WM_BASE(wm_idx));
+}
+
+static void msm_vfe32_axi_cfg_comp_mask(struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream *stream_info)
+{
+	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
+	uint32_t comp_mask, comp_mask_index =
+		stream_info->comp_mask_index;
+	uint32_t irq_mask;
+
+	comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x34);
+	comp_mask &= ~(0x7F << (comp_mask_index * 8));
+	comp_mask |= (axi_data->composite_info[comp_mask_index].
+		stream_composite_mask << (comp_mask_index * 8));
+	msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x34);
+
+	irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x1C);
+	irq_mask |= BIT(comp_mask_index + 21);
+	msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x1C);
+}
+
+static void msm_vfe32_axi_clear_comp_mask(struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream *stream_info)
+{
+	uint32_t comp_mask, comp_mask_index = stream_info->comp_mask_index;
+	uint32_t irq_mask;
+
+	comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x34);
+	comp_mask &= ~(0x7F << (comp_mask_index * 8));
+	msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x34);
+
+	irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x1C);
+	irq_mask &= ~BIT(comp_mask_index + 21);
+	msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x1C);
+}
+
+static void msm_vfe32_axi_cfg_wm_irq_mask(struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream *stream_info)
+{
+	uint32_t irq_mask;
+	irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x1C);
+	irq_mask |= BIT(stream_info->wm[0] + 6);
+	msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x1C);
+}
+
+static void msm_vfe32_axi_clear_wm_irq_mask(struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream *stream_info)
+{
+	uint32_t irq_mask;
+	irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x1C);
+	irq_mask &= ~BIT(stream_info->wm[0] + 6);
+	msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x1C);
+}
+
+static void msm_vfe32_cfg_framedrop(struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream *stream_info)
+{
+	uint32_t framedrop_pattern = 0, framedrop_period = 0;
+
+	if (stream_info->runtime_init_frame_drop == 0) {
+		framedrop_pattern = stream_info->framedrop_pattern;
+		framedrop_period = stream_info->framedrop_period;
+	}
+
+	if (stream_info->stream_type == BURST_STREAM &&
+		stream_info->runtime_burst_frame_count == 0) {
+		framedrop_pattern = 0;
+		framedrop_period = 0;
+	}
+
+	if (stream_info->stream_src == PIX_ENCODER) {
+		msm_camera_io_w(framedrop_period, vfe_dev->vfe_base + 0x504);
+		msm_camera_io_w(framedrop_period, vfe_dev->vfe_base + 0x508);
+		msm_camera_io_w(framedrop_pattern, vfe_dev->vfe_base + 0x50C);
+		msm_camera_io_w(framedrop_pattern, vfe_dev->vfe_base + 0x510);
+	} else if (stream_info->stream_src == PIX_VIEWFINDER) {
+		msm_camera_io_w(framedrop_period, vfe_dev->vfe_base + 0x514);
+		msm_camera_io_w(framedrop_period, vfe_dev->vfe_base + 0x518);
+		msm_camera_io_w(framedrop_pattern, vfe_dev->vfe_base + 0x51C);
+		msm_camera_io_w(framedrop_pattern, vfe_dev->vfe_base + 0x520);
+	}
+	msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x260);
+}
+
+static void msm_vfe32_clear_framedrop(struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream *stream_info)
+{
+	if (stream_info->stream_src == PIX_ENCODER) {
+		msm_camera_io_w(0, vfe_dev->vfe_base + 0x50C);
+		msm_camera_io_w(0, vfe_dev->vfe_base + 0x510);
+	} else if (stream_info->stream_src == PIX_VIEWFINDER) {
+		msm_camera_io_w(0, vfe_dev->vfe_base + 0x51C);
+		msm_camera_io_w(0, vfe_dev->vfe_base + 0x520);
+	}
+}
+
+static void msm_vfe32_cfg_io_format(struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream_request_cmd *stream_req_cmd)
+{
+	int bpp, bpp_reg = 0;
+	uint32_t io_format_reg;
+	bpp = msm_isp_get_bit_per_pixel(stream_req_cmd->output_format);
+
+	switch (bpp) {
+	case 8:
+		bpp_reg = 0;
+		break;
+	case 10:
+		bpp_reg = 1 << 0;
+		break;
+	case 12:
+		bpp_reg = 1 << 1;
+		break;
+	}
+	io_format_reg = msm_camera_io_r(vfe_dev->vfe_base + 0x6F8);
+	switch (stream_req_cmd->stream_src) {
+	case CAMIF_RAW:
+		io_format_reg &= 0xFFFFCFFF;
+		io_format_reg |= bpp_reg << 12;
+		break;
+	case IDEAL_RAW:
+		io_format_reg &= 0xFFFFFFC8;
+		io_format_reg |= bpp_reg << 4;
+		break;
+	case PIX_ENCODER:
+	case PIX_VIEWFINDER:
+	case RDI_INTF_0:
+	case RDI_INTF_1:
+	case RDI_INTF_2:
+	default:
+		pr_err("%s: Invalid stream source\n", __func__);
+		return;
+	}
+	msm_camera_io_w(io_format_reg, vfe_dev->vfe_base + 0x6F8);
+}
+
+static void msm_vfe32_cfg_camif(struct vfe_device *vfe_dev,
+	struct msm_vfe_pix_cfg *pix_cfg)
+{
+	uint16_t first_pixel, last_pixel, first_line, last_line;
+	struct msm_vfe_camif_cfg *camif_cfg = &pix_cfg->camif_cfg;
+	uint32_t val;
+
+	first_pixel = camif_cfg->first_pixel;
+	last_pixel = camif_cfg->last_pixel;
+	first_line = camif_cfg->first_line;
+	last_line = camif_cfg->last_line;
+
+	msm_camera_io_w(pix_cfg->input_mux << 16 | pix_cfg->pixel_pattern,
+					vfe_dev->vfe_base + 0x14);
+
+	msm_camera_io_w(camif_cfg->lines_per_frame << 16 |
+					camif_cfg->pixels_per_line,
+					vfe_dev->vfe_base + 0x1EC);
+
+	msm_camera_io_w(first_pixel << 16 | last_pixel,
+					vfe_dev->vfe_base + 0x1F0);
+
+	msm_camera_io_w(first_line << 16 | last_line,
+					vfe_dev->vfe_base + 0x1F4);
+
+	val = msm_camera_io_r(vfe_dev->vfe_base + 0x6FC);
+	val &= 0xFFFFFFFC;
+	val |= camif_cfg->camif_input;
+	msm_camera_io_w(val, vfe_dev->vfe_base + 0x6FC);
+}
+
+static void msm_vfe32_update_camif_state(
+	struct vfe_device *vfe_dev,
+	enum msm_isp_camif_update_state update_state)
+{
+	uint32_t val;
+	bool bus_en, vfe_en;
+	if (update_state == NO_UPDATE)
+		return;
+
+	val = msm_camera_io_r(vfe_dev->vfe_base + 0x1E4);
+	if (update_state == ENABLE_CAMIF) {
+		bus_en =
+		((vfe_dev->axi_data.src_info[
+			VFE_PIX_0].raw_stream_count > 0) ? 1 : 0);
+		vfe_en =
+		((vfe_dev->axi_data.src_info[
+			VFE_PIX_0].pix_stream_count > 0) ? 1 : 0);
+		val &= 0xFFFFFF3F;
+		val = val | bus_en << 7 | vfe_en << 6;
+		msm_camera_io_w(val, vfe_dev->vfe_base + 0x1E4);
+		msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x1E0);
+		vfe_dev->axi_data.src_info[VFE_PIX_0].active = 1;
+	} else if (update_state == DISABLE_CAMIF) {
+		msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x1E0);
+		vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0;
+	} else if (update_state == DISABLE_CAMIF_IMMEDIATELY) {
+		msm_camera_io_w_mb(0x2, vfe_dev->vfe_base + 0x1E0);
+		vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0;
+	}
+}
+
+static void msm_vfe32_cfg_rdi_reg(struct vfe_device *vfe_dev,
+	struct msm_vfe_rdi_cfg *rdi_cfg, enum msm_vfe_input_src input_src)
+{
+	uint8_t rdi = input_src - VFE_RAW_0;
+	uint32_t rdi_reg_cfg;
+	rdi_reg_cfg = msm_camera_io_r(
+		vfe_dev->vfe_base + VFE32_RDI_BASE(0));
+	rdi_reg_cfg &= ~(BIT(16 + rdi));
+	rdi_reg_cfg |= rdi_cfg->frame_based << (16 + rdi);
+	msm_camera_io_w(rdi_reg_cfg,
+		vfe_dev->vfe_base + VFE32_RDI_BASE(0));
+
+	rdi_reg_cfg = msm_camera_io_r(
+		vfe_dev->vfe_base + VFE32_RDI_BASE(rdi));
+	rdi_reg_cfg &= 0x70003;
+	rdi_reg_cfg |= (rdi * 3) << 28 | rdi_cfg->cid << 4 | 0x4;
+	msm_camera_io_w(
+		rdi_reg_cfg, vfe_dev->vfe_base + VFE32_RDI_BASE(rdi));
+
+}
+
+static void msm_vfe32_axi_cfg_wm_reg(
+	struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd,
+	uint8_t plane_idx)
+{
+	uint32_t val;
+	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
+	struct msm_vfe_axi_stream *stream_info =
+		&axi_data->stream_info[
+			(stream_cfg_cmd->axi_stream_handle & 0xFF)];
+	uint32_t wm_base = VFE32_WM_BASE(stream_info->wm[plane_idx]);
+
+	if (!stream_info->frame_based) {
+		/*WR_IMAGE_SIZE*/
+		val =
+			((msm_isp_cal_word_per_line(
+			stream_cfg_cmd->output_format,
+			stream_cfg_cmd->plane_cfg[plane_idx].
+			output_width)+1)/2 - 1) << 16 |
+			(stream_cfg_cmd->plane_cfg[plane_idx].
+			output_height - 1);
+		msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x10);
+
+		/*WR_BUFFER_CFG*/
+		val =
+			msm_isp_cal_word_per_line(
+			stream_cfg_cmd->output_format,
+			stream_cfg_cmd->plane_cfg[plane_idx].
+			output_stride) << 16 |
+			(stream_cfg_cmd->plane_cfg[plane_idx].
+			output_height - 1) << 4 | VFE32_BURST_LEN >> 2;
+		msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x14);
+	} else {
+		msm_camera_io_w(0x2, vfe_dev->vfe_base + wm_base);
+		val =
+			msm_isp_cal_word_per_line(
+			stream_cfg_cmd->output_format,
+			stream_cfg_cmd->plane_cfg[plane_idx].
+			output_width) << 16 |
+			(stream_cfg_cmd->plane_cfg[plane_idx].
+			output_height - 1) << 4 | VFE32_BURST_LEN >> 2;
+		msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x14);
+	}
+	return;
+}
+
+static void msm_vfe32_axi_clear_wm_reg(
+	struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx)
+{
+	uint32_t val = 0;
+	uint32_t wm_base = VFE32_WM_BASE(stream_info->wm[plane_idx]);
+	/*WR_IMAGE_SIZE*/
+	msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x10);
+	/*WR_BUFFER_CFG*/
+	msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x14);
+	return;
+}
+
+static void msm_vfe32_axi_cfg_wm_xbar_reg(
+	struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd,
+	uint8_t plane_idx)
+{
+	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
+	struct msm_vfe_axi_stream *stream_info =
+	 &axi_data->stream_info[(stream_cfg_cmd->axi_stream_handle & 0xFF)];
+	struct msm_vfe_axi_plane_cfg *plane_cfg =
+		&stream_cfg_cmd->plane_cfg[plane_idx];
+	uint8_t wm = stream_info->wm[plane_idx];
+	uint32_t xbar_cfg = 0;
+	uint32_t xbar_reg_cfg = 0;
+
+	switch (stream_cfg_cmd->stream_src) {
+	case PIX_ENCODER:
+	case PIX_VIEWFINDER: {
+		if (plane_cfg->output_plane_format != CRCB_PLANE &&
+			plane_cfg->output_plane_format != CBCR_PLANE) {
+			/*SINGLE_STREAM_SEL*/
+			xbar_cfg |= plane_cfg->output_plane_format << 5;
+		} else {
+			switch (stream_cfg_cmd->output_format) {
+			case V4L2_PIX_FMT_NV12:
+			case V4L2_PIX_FMT_NV16:
+				xbar_cfg |= 0x3 << 3; /*PAIR_STREAM_SWAP_CTRL*/
+				break;
+			}
+			xbar_cfg |= BIT(1); /*PAIR_STREAM_EN*/
+		}
+		if (stream_cfg_cmd->stream_src == PIX_VIEWFINDER)
+			xbar_cfg |= 0x1; /*VIEW_STREAM_EN*/
+		break;
+	}
+	case CAMIF_RAW:
+		xbar_cfg = 0x60;
+		break;
+	case IDEAL_RAW:
+		xbar_cfg = 0x80;
+		break;
+	case RDI_INTF_0:
+		xbar_cfg = 0xA0;
+		break;
+	case RDI_INTF_1:
+		xbar_cfg = 0xC0;
+		break;
+	case RDI_INTF_2:
+		xbar_cfg = 0xE0;
+		break;
+	default:
+		pr_err("%s: Invalid stream src\n", __func__);
+	}
+	xbar_reg_cfg = msm_camera_io_r(vfe_dev->vfe_base + VFE32_XBAR_BASE(wm));
+	xbar_reg_cfg &= ~(0xFF << VFE32_XBAR_SHIFT(wm));
+	xbar_reg_cfg |= (xbar_cfg << VFE32_XBAR_SHIFT(wm));
+	msm_camera_io_w(xbar_reg_cfg, vfe_dev->vfe_base + VFE32_XBAR_BASE(wm));
+	return;
+}
+
+static void msm_vfe32_axi_clear_wm_xbar_reg(
+	struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx)
+{
+	uint8_t wm = stream_info->wm[plane_idx];
+	uint32_t xbar_reg_cfg = 0;
+
+	xbar_reg_cfg = msm_camera_io_r(vfe_dev->vfe_base + VFE32_XBAR_BASE(wm));
+	xbar_reg_cfg &= ~(0xFF << VFE32_XBAR_SHIFT(wm));
+	msm_camera_io_w(xbar_reg_cfg, vfe_dev->vfe_base + VFE32_XBAR_BASE(wm));
+}
+
+static void msm_vfe32_cfg_axi_ub(struct vfe_device *vfe_dev)
+{
+	int i;
+	uint32_t ub_offset = 0;
+	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
+	for (i = 0; i < axi_data->hw_info->num_wm; i++) {
+		msm_camera_io_w(ub_offset << 16 | (VFE32_EQUAL_SLICE_UB - 1),
+			vfe_dev->vfe_base + VFE32_WM_BASE(i) + 0xC);
+		ub_offset += VFE32_EQUAL_SLICE_UB;
+	}
+}
+
+static void msm_vfe32_update_ping_pong_addr(struct vfe_device *vfe_dev,
+		uint8_t wm_idx, uint32_t pingpong_status, unsigned long paddr)
+{
+	msm_camera_io_w(paddr, vfe_dev->vfe_base +
+		VFE32_PING_PONG_BASE(wm_idx, pingpong_status));
+}
+
+static long msm_vfe32_axi_halt(struct vfe_device *vfe_dev)
+{
+	uint32_t halt_mask;
+	halt_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x20);
+	halt_mask |= BIT(24);
+	msm_camera_io_w_mb(halt_mask, vfe_dev->vfe_base + 0x20);
+	init_completion(&vfe_dev->halt_complete);
+	/*TD: Need to fix crashes with this*/
+	/*msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x1D8);*/
+	return wait_for_completion_interruptible_timeout(
+		&vfe_dev->halt_complete, msecs_to_jiffies(500));
+}
+
+static uint32_t msm_vfe32_get_wm_mask(
+	uint32_t irq_status0, uint32_t irq_status1)
+{
+	return (irq_status0 >> 6) & 0x7F;
+}
+
+static uint32_t msm_vfe32_get_comp_mask(
+	uint32_t irq_status0, uint32_t irq_status1)
+{
+	return (irq_status0 >> 21) & 0x7;
+}
+
+static uint32_t msm_vfe32_get_pingpong_status(struct vfe_device *vfe_dev)
+{
+	return msm_camera_io_r(vfe_dev->vfe_base + 0x180);
+}
+
+static int msm_vfe32_get_stats_idx(enum msm_isp_stats_type stats_type)
+{
+	switch (stats_type) {
+	case MSM_ISP_STATS_AEC:
+	case MSM_ISP_STATS_BG:
+		return 0;
+	case MSM_ISP_STATS_AF:
+	case MSM_ISP_STATS_BF:
+		return 1;
+	case MSM_ISP_STATS_AWB:
+		return 2;
+	case MSM_ISP_STATS_RS:
+		return 3;
+	case MSM_ISP_STATS_CS:
+		return 4;
+	case MSM_ISP_STATS_IHIST:
+		return 5;
+	case MSM_ISP_STATS_SKIN:
+	case MSM_ISP_STATS_BHIST:
+		return 6;
+	default:
+		pr_err("%s: Invalid stats type\n", __func__);
+		return -EINVAL;
+	}
+}
+
+static void msm_vfe32_stats_cfg_comp_mask(struct vfe_device *vfe_dev)
+{
+	return;
+}
+
+static void msm_vfe32_stats_cfg_wm_irq_mask(struct vfe_device *vfe_dev,
+	struct msm_vfe_stats_stream *stream_info)
+{
+	uint32_t irq_mask;
+	irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x1C);
+	irq_mask |= BIT(STATS_IDX(stream_info->stream_handle) + 13);
+	msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x1C);
+	return;
+}
+
+static void msm_vfe32_stats_clear_wm_irq_mask(struct vfe_device *vfe_dev,
+	struct msm_vfe_stats_stream *stream_info)
+{
+	uint32_t irq_mask;
+	irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x1C);
+	irq_mask &= ~(BIT(STATS_IDX(stream_info->stream_handle) + 13));
+	msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x1C);
+	return;
+}
+
+static void msm_vfe32_stats_cfg_wm_reg(struct vfe_device *vfe_dev,
+	struct msm_vfe_stats_stream *stream_info)
+{
+	/*Nothing to configure for VFE3.x*/
+	return;
+}
+
+static void msm_vfe32_stats_clear_wm_reg(struct vfe_device *vfe_dev,
+	struct msm_vfe_stats_stream *stream_info)
+{
+	/*Nothing to configure for VFE3.x*/
+	return;
+}
+
+static void msm_vfe32_stats_cfg_ub(struct vfe_device *vfe_dev)
+{
+	int i;
+	uint32_t ub_offset = VFE32_UB_SIZE;
+	uint32_t ub_size[VFE32_NUM_STATS_TYPE] = {
+		64, /*MSM_ISP_STATS_BG*/
+		64, /*MSM_ISP_STATS_BF*/
+		16, /*MSM_ISP_STATS_AWB*/
+		8,  /*MSM_ISP_STATS_RS*/
+		16, /*MSM_ISP_STATS_CS*/
+		16, /*MSM_ISP_STATS_IHIST*/
+		16, /*MSM_ISP_STATS_BHIST*/
+	};
+
+	for (i = 0; i < VFE32_NUM_STATS_TYPE; i++) {
+		ub_offset -= ub_size[i];
+		msm_camera_io_w(ub_offset << 16 | (ub_size[i] - 1),
+			vfe_dev->vfe_base + VFE32_STATS_BASE(i) + 0x8);
+	}
+	return;
+}
+
+static void msm_vfe32_stats_enable_module(struct vfe_device *vfe_dev,
+	uint32_t stats_mask, uint8_t enable)
+{
+	int i;
+	uint32_t module_cfg, module_cfg_mask = 0;
+
+	for (i = 0; i < VFE32_NUM_STATS_TYPE; i++) {
+		if ((stats_mask >> i) & 0x1) {
+			switch (i) {
+			case 0:
+			case 1:
+			case 2:
+			case 3:
+			case 4:
+				module_cfg_mask |= 1 << (5 + i);
+				break;
+			case 5:
+				module_cfg_mask |= 1 << 16;
+				break;
+			case 6:
+				module_cfg_mask |= 1 << 19;
+				break;
+			default:
+				pr_err("%s: Invalid stats mask\n", __func__);
+				return;
+			}
+		}
+	}
+
+	module_cfg = msm_camera_io_r(vfe_dev->vfe_base + 0x10);
+	if (enable)
+		module_cfg |= module_cfg_mask;
+	else
+		module_cfg &= ~module_cfg_mask;
+	msm_camera_io_w(module_cfg, vfe_dev->vfe_base + 0x10);
+}
+
+static void msm_vfe32_stats_update_ping_pong_addr(struct vfe_device *vfe_dev,
+	struct msm_vfe_stats_stream *stream_info, uint32_t pingpong_status,
+	unsigned long paddr)
+{
+	int stats_idx = STATS_IDX(stream_info->stream_handle);
+	msm_camera_io_w(paddr, vfe_dev->vfe_base +
+		VFE32_STATS_PING_PONG_BASE(stats_idx, pingpong_status));
+}
+
+static uint32_t msm_vfe32_stats_get_wm_mask(uint32_t irq_status0,
+	uint32_t irq_status1)
+{
+	return (irq_status0 >> 13) & 0x7F;
+}
+
+static uint32_t msm_vfe32_stats_get_comp_mask(uint32_t irq_status0,
+	uint32_t irq_status1)
+{
+	return (irq_status0 >> 24) & 0x1;
+}
+
+static uint32_t msm_vfe32_stats_get_frame_id(struct vfe_device *vfe_dev)
+{
+	return vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id;
+}
+
+static int msm_vfe32_get_platform_data(struct vfe_device *vfe_dev)
+{
+	int rc = 0;
+	vfe_dev->vfe_mem = platform_get_resource_byname(vfe_dev->pdev,
+					IORESOURCE_MEM, "vfe");
+	if (!vfe_dev->vfe_mem) {
+		pr_err("%s: no mem resource?\n", __func__);
+		rc = -ENODEV;
+		goto vfe_no_resource;
+	}
+
+	vfe_dev->vfe_irq = platform_get_resource_byname(vfe_dev->pdev,
+					IORESOURCE_IRQ, "vfe");
+	if (!vfe_dev->vfe_irq) {
+		pr_err("%s: no irq resource?\n", __func__);
+		rc = -ENODEV;
+		goto vfe_no_resource;
+	}
+
+	vfe_dev->fs_vfe = regulator_get(&vfe_dev->pdev->dev, "vdd");
+	if (IS_ERR(vfe_dev->fs_vfe)) {
+		pr_err("%s: Regulator get failed %ld\n", __func__,
+			PTR_ERR(vfe_dev->fs_vfe));
+		vfe_dev->fs_vfe = NULL;
+		rc = -ENODEV;
+		goto vfe_no_resource;
+	}
+
+	vfe_dev->iommu_ctx[0] = msm_iommu_get_ctx("vfe_imgwr");
+	if (!vfe_dev->iommu_ctx[0]) {
+		pr_err("%s: no iommux ctx resource?\n", __func__);
+		rc = -ENODEV;
+		goto vfe_no_resource;
+	}
+
+	vfe_dev->iommu_ctx[1] = msm_iommu_get_ctx("vfe_misc");
+	if (!vfe_dev->iommu_ctx[1]) {
+		pr_err("%s: no iommux ctx resource?\n", __func__);
+		rc = -ENODEV;
+		goto vfe_no_resource;
+	}
+
+vfe_no_resource:
+	return rc;
+}
+
+static void msm_vfe32_get_error_mask(uint32_t *error_mask0,
+	uint32_t *error_mask1)
+{
+	*error_mask0 = 0x00000000;
+	*error_mask1 = 0x007FFFFF;
+}
+
+struct msm_vfe_axi_hardware_info msm_vfe32_axi_hw_info = {
+	.num_wm = 7,
+	.num_comp_mask = 3,
+	.num_rdi = 3,
+	.num_rdi_master = 3,
+};
+
+static struct msm_vfe_stats_hardware_info msm_vfe32_stats_hw_info = {
+	.stats_capability_mask =
+		1 << MSM_ISP_STATS_AEC | 1 << MSM_ISP_STATS_BG |
+		1 << MSM_ISP_STATS_AF | 1 << MSM_ISP_STATS_BF |
+		1 << MSM_ISP_STATS_AWB | 1 << MSM_ISP_STATS_IHIST |
+		1 << MSM_ISP_STATS_RS | 1 << MSM_ISP_STATS_CS |
+		1 << MSM_ISP_STATS_SKIN | 1 << MSM_ISP_STATS_BHIST,
+	.stats_ping_pong_offset = VFE32_STATS_PING_PONG_OFFSET,
+	.num_stats_type = VFE32_NUM_STATS_TYPE,
+	.num_stats_comp_mask = 0,
+};
+
+static struct v4l2_subdev_core_ops msm_vfe32_subdev_core_ops = {
+	.ioctl = msm_isp_ioctl,
+	.subscribe_event = msm_isp_subscribe_event,
+	.unsubscribe_event = msm_isp_unsubscribe_event,
+};
+
+static struct v4l2_subdev_ops msm_vfe32_subdev_ops = {
+	.core = &msm_vfe32_subdev_core_ops,
+};
+
+static struct v4l2_subdev_internal_ops msm_vfe32_internal_ops = {
+	.open = msm_isp_open_node,
+	.close = msm_isp_close_node,
+};
+
+struct msm_vfe_hardware_info vfe32_hw_info = {
+	.num_iommu_ctx = 2,
+	.vfe_ops = {
+		.irq_ops = {
+			.read_irq_status = msm_vfe32_read_irq_status,
+			.process_camif_irq = msm_vfe32_process_camif_irq,
+			.process_reset_irq = msm_vfe32_process_reset_irq,
+			.process_halt_irq = msm_vfe32_process_halt_irq,
+			.process_reg_update = msm_vfe32_process_reg_update,
+			.process_axi_irq = msm_isp_process_axi_irq,
+			.process_stats_irq = msm_isp_process_stats_irq,
+		},
+		.axi_ops = {
+			.reload_wm = msm_vfe32_axi_reload_wm,
+			.enable_wm = msm_vfe32_axi_enable_wm,
+			.cfg_io_format = msm_vfe32_cfg_io_format,
+			.cfg_comp_mask = msm_vfe32_axi_cfg_comp_mask,
+			.clear_comp_mask = msm_vfe32_axi_clear_comp_mask,
+			.cfg_wm_irq_mask = msm_vfe32_axi_cfg_wm_irq_mask,
+			.clear_wm_irq_mask = msm_vfe32_axi_clear_wm_irq_mask,
+			.cfg_framedrop = msm_vfe32_cfg_framedrop,
+			.clear_framedrop = msm_vfe32_clear_framedrop,
+			.cfg_wm_reg = msm_vfe32_axi_cfg_wm_reg,
+			.clear_wm_reg = msm_vfe32_axi_clear_wm_reg,
+			.cfg_wm_xbar_reg = msm_vfe32_axi_cfg_wm_xbar_reg,
+			.clear_wm_xbar_reg = msm_vfe32_axi_clear_wm_xbar_reg,
+			.cfg_ub = msm_vfe32_cfg_axi_ub,
+			.update_ping_pong_addr =
+				msm_vfe32_update_ping_pong_addr,
+			.get_comp_mask = msm_vfe32_get_comp_mask,
+			.get_wm_mask = msm_vfe32_get_wm_mask,
+			.get_pingpong_status = msm_vfe32_get_pingpong_status,
+			.halt = msm_vfe32_axi_halt,
+		},
+		.core_ops = {
+			.reg_update = msm_vfe32_reg_update,
+			.cfg_camif = msm_vfe32_cfg_camif,
+			.update_camif_state = msm_vfe32_update_camif_state,
+			.cfg_rdi_reg = msm_vfe32_cfg_rdi_reg,
+			.reset_hw = msm_vfe32_reset_hardware,
+			.init_hw = msm_vfe32_init_hardware,
+			.init_hw_reg = msm_vfe32_init_hardware_reg,
+			.release_hw = msm_vfe32_release_hardware,
+			.get_platform_data = msm_vfe32_get_platform_data,
+			.get_error_mask = msm_vfe32_get_error_mask,
+			.process_error_status = msm_vfe32_process_error_status,
+		},
+		.stats_ops = {
+			.get_stats_idx = msm_vfe32_get_stats_idx,
+			.cfg_comp_mask = msm_vfe32_stats_cfg_comp_mask,
+			.cfg_wm_irq_mask = msm_vfe32_stats_cfg_wm_irq_mask,
+			.clear_wm_irq_mask = msm_vfe32_stats_clear_wm_irq_mask,
+			.cfg_wm_reg = msm_vfe32_stats_cfg_wm_reg,
+			.clear_wm_reg = msm_vfe32_stats_clear_wm_reg,
+			.cfg_ub = msm_vfe32_stats_cfg_ub,
+			.enable_module = msm_vfe32_stats_enable_module,
+			.update_ping_pong_addr =
+				msm_vfe32_stats_update_ping_pong_addr,
+			.get_comp_mask = msm_vfe32_stats_get_comp_mask,
+			.get_wm_mask = msm_vfe32_stats_get_wm_mask,
+			.get_frame_id = msm_vfe32_stats_get_frame_id,
+			.get_pingpong_status = msm_vfe32_get_pingpong_status,
+		},
+	},
+	.dmi_reg_offset = 0x5A0,
+	.axi_hw_info = &msm_vfe32_axi_hw_info,
+	.stats_hw_info = &msm_vfe32_stats_hw_info,
+	.subdev_ops = &msm_vfe32_subdev_ops,
+	.subdev_internal_ops = &msm_vfe32_internal_ops,
+};
+EXPORT_SYMBOL(vfe32_hw_info);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.h
new file mode 100644
index 0000000..0535048
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.h
@@ -0,0 +1,17 @@
+/* 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 __MSM_ISP32_H__
+#define __MSM_ISP32_H__
+
+extern struct msm_vfe_hardware_info vfe32_hw_info;
+#endif /* __MSM_ISP32_H__ */
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
new file mode 100644
index 0000000..1d931df
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
@@ -0,0 +1,1313 @@
+/* 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 <mach/iommu.h>
+
+#include "msm_isp40.h"
+#include "msm_isp_util.h"
+#include "msm_isp_axi_util.h"
+#include "msm_isp_stats_util.h"
+#include "msm_isp.h"
+#include "msm.h"
+#include "msm_camera_io_util.h"
+
+/*#define CONFIG_MSM_ISP_DBG*/
+#undef CDBG
+#ifdef CONFIG_MSM_ISP_DBG
+#define CDBG(fmt, args...) pr_err(fmt, ##args)
+#else
+#define CDBG(fmt, args...) do { } while (0)
+#endif
+
+#define VFE40_BURST_LEN 3
+#define VFE40_STATS_BURST_LEN 2
+#define VFE40_UB_SIZE 1536
+#define VFE40_EQUAL_SLICE_UB 286
+#define VFE40_WM_BASE(idx) (0x6C + 0x24 * idx)
+#define VFE40_RDI_BASE(idx) (0x2E8 + 0x4 * idx)
+#define VFE40_XBAR_BASE(idx) (0x58 + 0x4 * (idx / 2))
+#define VFE40_XBAR_SHIFT(idx) ((idx%2) ? 16 : 0)
+#define VFE40_PING_PONG_BASE(wm, ping_pong) \
+	(VFE40_WM_BASE(wm) + 0x4 * (1 + (~(ping_pong >> wm) & 0x1)))
+
+#define VFE40_NUM_STATS_TYPE 8
+#define VFE40_STATS_PING_PONG_OFFSET 8
+#define VFE40_STATS_BASE(idx) (0x168 + 0x18 * idx)
+#define VFE40_STATS_PING_PONG_BASE(idx, ping_pong) \
+	(VFE40_STATS_BASE(idx) + 0x4 * \
+	(~(ping_pong >> (idx + VFE40_STATS_PING_PONG_OFFSET)) & 0x1))
+
+#define VFE40_VBIF_CLKON                    0x4
+#define VFE40_VBIF_IN_RD_LIM_CONF0          0xB0
+#define VFE40_VBIF_IN_RD_LIM_CONF1          0xB4
+#define VFE40_VBIF_IN_RD_LIM_CONF2          0xB8
+#define VFE40_VBIF_IN_WR_LIM_CONF0          0xC0
+#define VFE40_VBIF_IN_WR_LIM_CONF1          0xC4
+#define VFE40_VBIF_IN_WR_LIM_CONF2          0xC8
+#define VFE40_VBIF_OUT_RD_LIM_CONF0         0xD0
+#define VFE40_VBIF_OUT_WR_LIM_CONF0         0xD4
+#define VFE40_VBIF_DDR_OUT_MAX_BURST        0xD8
+#define VFE40_VBIF_OCMEM_OUT_MAX_BURST      0xDC
+#define VFE40_VBIF_ARB_CTL                  0xF0
+#define VFE40_VBIF_ROUND_ROBIN_QOS_ARB      0x124
+#define VFE40_VBIF_OUT_AXI_AMEMTYPE_CONF0   0x160
+#define VFE40_VBIF_OUT_AXI_AMEMTYPE_CONF1   0x164
+#define VFE40_VBIF_OUT_AXI_AOOO_EN          0x178
+#define VFE40_VBIF_OUT_AXI_AOOO             0x17C
+
+#define VFE40_BUS_BDG_QOS_CFG_0     0x000002C4
+#define VFE40_BUS_BDG_QOS_CFG_1     0x000002C8
+#define VFE40_BUS_BDG_QOS_CFG_2     0x000002CC
+#define VFE40_BUS_BDG_QOS_CFG_3     0x000002D0
+#define VFE40_BUS_BDG_QOS_CFG_4     0x000002D4
+#define VFE40_BUS_BDG_QOS_CFG_5     0x000002D8
+#define VFE40_BUS_BDG_QOS_CFG_6     0x000002DC
+#define VFE40_BUS_BDG_QOS_CFG_7     0x000002E0
+
+/*Temporary use fixed bus vectors in VFE */
+static struct msm_bus_vectors msm_vfe40_init_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+};
+
+static struct msm_bus_vectors msm_vfe40_preview_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 1027648000,
+		.ib  = 1105920000,
+	},
+};
+
+static struct msm_bus_paths msm_vfe40_bus_client_config[] = {
+	{
+		ARRAY_SIZE(msm_vfe40_init_vectors),
+		msm_vfe40_init_vectors,
+	},
+	{
+		ARRAY_SIZE(msm_vfe40_preview_vectors),
+		msm_vfe40_preview_vectors,
+	},
+};
+
+static struct msm_bus_scale_pdata msm_vfe40_bus_client_pdata = {
+	msm_vfe40_bus_client_config,
+	ARRAY_SIZE(msm_vfe40_bus_client_config),
+	.name = "msm_camera_vfe",
+};
+
+static struct msm_cam_clk_info msm_vfe40_clk_info[] = {
+	{"camss_top_ahb_clk", -1},
+	{"vfe_clk_src", 266670000},
+	{"camss_vfe_vfe_clk", -1},
+	{"camss_csi_vfe_clk", -1},
+	{"iface_clk", -1},
+	{"bus_clk", -1},
+	{"alt_bus_clk", -1},
+};
+
+static void msm_vfe40_init_qos_parms(struct vfe_device *vfe_dev)
+{
+	void __iomem *vfebase = vfe_dev->vfe_base;
+	msm_camera_io_w(0xAAAAAAAA, vfebase + VFE40_BUS_BDG_QOS_CFG_0);
+	msm_camera_io_w(0xAAAAAAAA, vfebase + VFE40_BUS_BDG_QOS_CFG_1);
+	msm_camera_io_w(0xAAAAAAAA, vfebase + VFE40_BUS_BDG_QOS_CFG_2);
+	msm_camera_io_w(0xAAAAAAAA, vfebase + VFE40_BUS_BDG_QOS_CFG_3);
+	msm_camera_io_w(0xAAAAAAAA, vfebase + VFE40_BUS_BDG_QOS_CFG_4);
+	msm_camera_io_w(0xAAAAAAAA, vfebase + VFE40_BUS_BDG_QOS_CFG_5);
+	msm_camera_io_w(0xAAAAAAAA, vfebase + VFE40_BUS_BDG_QOS_CFG_6);
+	msm_camera_io_w(0x0002AAAA, vfebase + VFE40_BUS_BDG_QOS_CFG_7);
+}
+
+static void msm_vfe40_init_vbif_parms(
+	void __iomem *vfe_vbif_base)
+{
+	msm_camera_io_w(0x1,
+		vfe_vbif_base + VFE40_VBIF_CLKON);
+	msm_camera_io_w(0x01010101,
+		vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF0);
+	msm_camera_io_w(0x01010101,
+		vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF1);
+	msm_camera_io_w(0x10010110,
+		vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF2);
+	msm_camera_io_w(0x10101010,
+		vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF0);
+	msm_camera_io_w(0x10101010,
+		vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF1);
+	msm_camera_io_w(0x10101010,
+		vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF2);
+	msm_camera_io_w(0x00001010,
+		vfe_vbif_base + VFE40_VBIF_OUT_RD_LIM_CONF0);
+	msm_camera_io_w(0x00001010,
+		vfe_vbif_base + VFE40_VBIF_OUT_WR_LIM_CONF0);
+	msm_camera_io_w(0x00000707,
+		vfe_vbif_base + VFE40_VBIF_DDR_OUT_MAX_BURST);
+	msm_camera_io_w(0x00000707,
+		vfe_vbif_base + VFE40_VBIF_OCMEM_OUT_MAX_BURST);
+	msm_camera_io_w(0x00000030,
+		vfe_vbif_base + VFE40_VBIF_ARB_CTL);
+	msm_camera_io_w(0x00000FFF,
+		vfe_vbif_base + VFE40_VBIF_OUT_AXI_AOOO_EN);
+	msm_camera_io_w(0x0FFF0FFF,
+		vfe_vbif_base + VFE40_VBIF_OUT_AXI_AOOO);
+	msm_camera_io_w(0x00000001,
+		vfe_vbif_base + VFE40_VBIF_ROUND_ROBIN_QOS_ARB);
+	msm_camera_io_w(0x22222222,
+		vfe_vbif_base + VFE40_VBIF_OUT_AXI_AMEMTYPE_CONF0);
+	msm_camera_io_w(0x00002222,
+		vfe_vbif_base + VFE40_VBIF_OUT_AXI_AMEMTYPE_CONF1);
+}
+
+static int msm_vfe40_init_hardware(struct vfe_device *vfe_dev)
+{
+	int rc = -1;
+
+	vfe_dev->bus_perf_client =
+		msm_bus_scale_register_client(&msm_vfe40_bus_client_pdata);
+	if (!vfe_dev->bus_perf_client) {
+		pr_err("%s: Registration Failed!\n", __func__);
+		vfe_dev->bus_perf_client = 0;
+		goto bus_scale_register_failed;
+	}
+	msm_bus_scale_client_update_request(
+		vfe_dev->bus_perf_client, 1);
+
+	if (vfe_dev->fs_vfe) {
+		rc = regulator_enable(vfe_dev->fs_vfe);
+		if (rc) {
+			pr_err("%s: Regulator enable failed\n", __func__);
+			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);
+	if (rc < 0)
+		goto clk_enable_failed;
+
+	vfe_dev->vfe_base = ioremap(vfe_dev->vfe_mem->start,
+		resource_size(vfe_dev->vfe_mem));
+	if (!vfe_dev->vfe_base) {
+		rc = -ENOMEM;
+		pr_err("%s: vfe ioremap failed\n", __func__);
+		goto vfe_remap_failed;
+	}
+
+	vfe_dev->vfe_vbif_base = ioremap(vfe_dev->vfe_vbif_mem->start,
+		resource_size(vfe_dev->vfe_vbif_mem));
+	if (!vfe_dev->vfe_vbif_base) {
+		rc = -ENOMEM;
+		pr_err("%s: vfe ioremap failed\n", __func__);
+		goto vbif_remap_failed;
+	}
+
+	rc = request_irq(vfe_dev->vfe_irq->start, msm_isp_process_irq,
+		IRQF_TRIGGER_RISING, "vfe", vfe_dev);
+	if (rc < 0) {
+		pr_err("%s: irq request failed\n", __func__);
+		goto irq_req_failed;
+	}
+
+	msm_vfe40_init_qos_parms(vfe_dev);
+	msm_vfe40_init_vbif_parms(vfe_dev->vfe_vbif_base);
+	return rc;
+irq_req_failed:
+	iounmap(vfe_dev->vfe_vbif_base);
+vbif_remap_failed:
+	iounmap(vfe_dev->vfe_base);
+vfe_remap_failed:
+	msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe40_clk_info,
+		vfe_dev->vfe_clk, ARRAY_SIZE(msm_vfe40_clk_info), 0);
+clk_enable_failed:
+	regulator_disable(vfe_dev->fs_vfe);
+fs_failed:
+	msm_bus_scale_client_update_request(vfe_dev->bus_perf_client, 0);
+	msm_bus_scale_unregister_client(vfe_dev->bus_perf_client);
+bus_scale_register_failed:
+	return rc;
+}
+
+static void msm_vfe40_release_hardware(struct vfe_device *vfe_dev)
+{
+	free_irq(vfe_dev->vfe_irq->start, vfe_dev);
+	tasklet_kill(&vfe_dev->vfe_tasklet);
+	iounmap(vfe_dev->vfe_vbif_base);
+	iounmap(vfe_dev->vfe_base);
+	msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe40_clk_info,
+		vfe_dev->vfe_clk, ARRAY_SIZE(msm_vfe40_clk_info), 0);
+	regulator_disable(vfe_dev->fs_vfe);
+	msm_bus_scale_client_update_request(vfe_dev->bus_perf_client, 0);
+	msm_bus_scale_unregister_client(vfe_dev->bus_perf_client);
+}
+
+static void msm_vfe40_init_hardware_reg(struct vfe_device *vfe_dev)
+{
+	/* CGC_OVERRIDE */
+	msm_camera_io_w(0x3FFFFFFF, vfe_dev->vfe_base + 0x14);
+	msm_camera_io_w(0xC001FF7F, vfe_dev->vfe_base + 0x974);
+	/* BUS_CFG */
+	msm_camera_io_w(0x10000001, vfe_dev->vfe_base + 0x50);
+	msm_camera_io_w(0x800000F3, vfe_dev->vfe_base + 0x28);
+	msm_camera_io_w_mb(0xFEFFFFFF, vfe_dev->vfe_base + 0x2C);
+	msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x30);
+	msm_camera_io_w_mb(0xFEFFFFFF, vfe_dev->vfe_base + 0x34);
+}
+
+static void msm_vfe40_process_reset_irq(struct vfe_device *vfe_dev,
+	uint32_t irq_status0, uint32_t irq_status1)
+{
+	if (irq_status0 & (1 << 31))
+		complete(&vfe_dev->reset_complete);
+}
+
+static void msm_vfe40_process_halt_irq(struct vfe_device *vfe_dev,
+	uint32_t irq_status0, uint32_t irq_status1)
+{
+	if (irq_status1 & (1 << 8))
+		complete(&vfe_dev->halt_complete);
+}
+
+static void msm_vfe40_process_camif_irq(struct vfe_device *vfe_dev,
+	uint32_t irq_status0, uint32_t irq_status1,
+	struct msm_isp_timestamp *ts)
+{
+	if (!(irq_status0 & 0xF))
+		return;
+
+	if (irq_status0 & (1 << 0)) {
+		ISP_DBG("%s: SOF IRQ\n", __func__);
+		if (vfe_dev->axi_data.src_info[VFE_PIX_0].raw_stream_count > 0
+			&& vfe_dev->axi_data.src_info[VFE_PIX_0].
+			pix_stream_count == 0) {
+			msm_isp_sof_notify(vfe_dev, VFE_PIX_0, ts);
+			msm_isp_update_framedrop_reg(vfe_dev);
+		}
+	}
+	if (irq_status0 & (1 << 1))
+		ISP_DBG("%s: EOF IRQ\n", __func__);
+	if (irq_status0 & (1 << 2))
+		ISP_DBG("%s: EPOCH0 IRQ\n", __func__);
+	if (irq_status0 & (1 << 3))
+		ISP_DBG("%s: EPOCH1 IRQ\n", __func__);
+}
+
+static void msm_vfe40_process_violation_status(
+	struct vfe_device *vfe_dev)
+{
+	uint32_t violation_status = vfe_dev->error_info.violation_status;
+	if (!violation_status)
+		return;
+
+	if (violation_status & (1 << 0))
+		pr_err("%s: camif violation\n", __func__);
+	if (violation_status & (1 << 1))
+		pr_err("%s: black violation\n", __func__);
+	if (violation_status & (1 << 2))
+		pr_err("%s: rolloff violation\n", __func__);
+	if (violation_status & (1 << 3))
+		pr_err("%s: demux violation\n", __func__);
+	if (violation_status & (1 << 4))
+		pr_err("%s: demosaic violation\n", __func__);
+	if (violation_status & (1 << 5))
+		pr_err("%s: wb violation\n", __func__);
+	if (violation_status & (1 << 6))
+		pr_err("%s: clf violation\n", __func__);
+	if (violation_status & (1 << 7))
+		pr_err("%s: color correct violation\n", __func__);
+	if (violation_status & (1 << 8))
+		pr_err("%s: rgb lut violation\n", __func__);
+	if (violation_status & (1 << 9))
+		pr_err("%s: la violation\n", __func__);
+	if (violation_status & (1 << 10))
+		pr_err("%s: chroma enhance violation\n", __func__);
+	if (violation_status & (1 << 11))
+		pr_err("%s: chroma supress mce violation\n", __func__);
+	if (violation_status & (1 << 12))
+		pr_err("%s: skin enhance violation\n", __func__);
+	if (violation_status & (1 << 13))
+		pr_err("%s: color tranform enc violation\n", __func__);
+	if (violation_status & (1 << 14))
+		pr_err("%s: color tranform view violation\n", __func__);
+	if (violation_status & (1 << 15))
+		pr_err("%s: scale enc y violation\n", __func__);
+	if (violation_status & (1 << 16))
+		pr_err("%s: scale enc cbcr violation\n", __func__);
+	if (violation_status & (1 << 17))
+		pr_err("%s: scale view y violation\n", __func__);
+	if (violation_status & (1 << 18))
+		pr_err("%s: scale view cbcr violation\n", __func__);
+	if (violation_status & (1 << 19))
+		pr_err("%s: asf enc violation\n", __func__);
+	if (violation_status & (1 << 20))
+		pr_err("%s: asf view violation\n", __func__);
+	if (violation_status & (1 << 21))
+		pr_err("%s: crop enc y violation\n", __func__);
+	if (violation_status & (1 << 22))
+		pr_err("%s: crop enc cbcr violation\n", __func__);
+	if (violation_status & (1 << 23))
+		pr_err("%s: crop view y violation\n", __func__);
+	if (violation_status & (1 << 24))
+		pr_err("%s: crop view cbcr violation\n", __func__);
+	if (violation_status & (1 << 25))
+		pr_err("%s: realign buf y violation\n", __func__);
+	if (violation_status & (1 << 26))
+		pr_err("%s: realign buf cb violation\n", __func__);
+	if (violation_status & (1 << 27))
+		pr_err("%s: realign buf cr violation\n", __func__);
+}
+
+static void msm_vfe40_process_error_status(struct vfe_device *vfe_dev)
+{
+	uint32_t error_status1 = vfe_dev->error_info.error_mask1;
+	if (error_status1 & (1 << 0))
+		pr_err("%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__);
+	if (error_status1 & (1 << 2))
+		pr_err("%s: stats cs overwrite\n", __func__);
+	if (error_status1 & (1 << 3))
+		pr_err("%s: stats ihist overwrite\n", __func__);
+	if (error_status1 & (1 << 4))
+		pr_err("%s: realign buf y overflow\n", __func__);
+	if (error_status1 & (1 << 5))
+		pr_err("%s: realign buf cb overflow\n", __func__);
+	if (error_status1 & (1 << 6))
+		pr_err("%s: realign buf cr overflow\n", __func__);
+	if (error_status1 & (1 << 7)) {
+		pr_err("%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__);
+	if (error_status1 & (1 << 10))
+		pr_err("%s: image master 1 bus overflow\n", __func__);
+	if (error_status1 & (1 << 11))
+		pr_err("%s: image master 2 bus overflow\n", __func__);
+	if (error_status1 & (1 << 12))
+		pr_err("%s: image master 3 bus overflow\n", __func__);
+	if (error_status1 & (1 << 13))
+		pr_err("%s: image master 4 bus overflow\n", __func__);
+	if (error_status1 & (1 << 14))
+		pr_err("%s: image master 5 bus overflow\n", __func__);
+	if (error_status1 & (1 << 15))
+		pr_err("%s: image master 6 bus overflow\n", __func__);
+	if (error_status1 & (1 << 16))
+		pr_err("%s: status be bus overflow\n", __func__);
+	if (error_status1 & (1 << 17))
+		pr_err("%s: status bg bus overflow\n", __func__);
+	if (error_status1 & (1 << 18))
+		pr_err("%s: status bf bus overflow\n", __func__);
+	if (error_status1 & (1 << 19))
+		pr_err("%s: status awb bus overflow\n", __func__);
+	if (error_status1 & (1 << 20))
+		pr_err("%s: status rs bus overflow\n", __func__);
+	if (error_status1 & (1 << 21))
+		pr_err("%s: status cs bus overflow\n", __func__);
+	if (error_status1 & (1 << 22))
+		pr_err("%s: status ihist bus overflow\n", __func__);
+	if (error_status1 & (1 << 23))
+		pr_err("%s: status skin bhist bus overflow\n", __func__);
+}
+
+static void msm_vfe40_read_irq_status(struct vfe_device *vfe_dev,
+	uint32_t *irq_status0, uint32_t *irq_status1)
+{
+	*irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x38);
+	*irq_status1 = msm_camera_io_r(vfe_dev->vfe_base + 0x3C);
+	msm_camera_io_w(*irq_status0, vfe_dev->vfe_base + 0x30);
+	msm_camera_io_w(*irq_status1, vfe_dev->vfe_base + 0x34);
+	msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x24);
+
+	if (*irq_status1 & (1 << 0))
+		vfe_dev->error_info.camif_status =
+		msm_camera_io_r(vfe_dev->vfe_base + 0x31C);
+
+	if (*irq_status1 & (1 << 7))
+		vfe_dev->error_info.violation_status |=
+		msm_camera_io_r(vfe_dev->vfe_base + 0x48);
+
+}
+
+static void msm_vfe40_process_reg_update(struct vfe_device *vfe_dev,
+	uint32_t irq_status0, uint32_t irq_status1,
+	struct msm_isp_timestamp *ts)
+{
+	if (!(irq_status0 & 0xF0))
+		return;
+
+	if (irq_status0 & BIT(4))
+		msm_isp_sof_notify(vfe_dev, VFE_PIX_0, ts);
+	if (irq_status0 & BIT(5))
+		msm_isp_sof_notify(vfe_dev, VFE_RAW_0, ts);
+	if (irq_status0 & BIT(6))
+		msm_isp_sof_notify(vfe_dev, VFE_RAW_1, ts);
+	if (irq_status0 & BIT(7))
+		msm_isp_sof_notify(vfe_dev, VFE_RAW_2, ts);
+
+	if (vfe_dev->axi_data.stream_update)
+		msm_isp_axi_stream_update(vfe_dev);
+	msm_isp_update_framedrop_reg(vfe_dev);
+	msm_isp_update_error_frame_count(vfe_dev);
+
+	vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev);
+	return;
+}
+
+static void msm_vfe40_reg_update(struct vfe_device *vfe_dev)
+{
+	msm_camera_io_w_mb(0xF, vfe_dev->vfe_base + 0x378);
+}
+
+static long msm_vfe40_reset_hardware(struct vfe_device *vfe_dev)
+{
+	init_completion(&vfe_dev->reset_complete);
+	msm_camera_io_w_mb(0x1FF, vfe_dev->vfe_base + 0xC);
+	return wait_for_completion_interruptible_timeout(
+		&vfe_dev->reset_complete, msecs_to_jiffies(50));
+}
+
+static void msm_vfe40_axi_reload_wm(
+	struct vfe_device *vfe_dev, uint32_t reload_mask)
+{
+	msm_camera_io_w_mb(reload_mask, vfe_dev->vfe_base + 0x4C);
+}
+
+static void msm_vfe40_axi_enable_wm(struct vfe_device *vfe_dev,
+	uint8_t wm_idx, uint8_t enable)
+{
+	uint32_t val;
+	val = msm_camera_io_r(vfe_dev->vfe_base + VFE40_WM_BASE(wm_idx));
+	if (enable)
+		val |= 0x1;
+	else
+		val &= ~0x1;
+	msm_camera_io_w_mb(val,
+		vfe_dev->vfe_base + VFE40_WM_BASE(wm_idx));
+}
+
+static void msm_vfe40_axi_cfg_comp_mask(struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream *stream_info)
+{
+	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
+	uint32_t comp_mask, comp_mask_index =
+		stream_info->comp_mask_index;
+	uint32_t irq_mask;
+
+	comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x40);
+	comp_mask &= ~(0x7F << (comp_mask_index * 8));
+	comp_mask |= (axi_data->composite_info[comp_mask_index].
+	stream_composite_mask << (comp_mask_index * 8));
+	msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x40);
+
+	irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28);
+	irq_mask |= 1 << (comp_mask_index + 25);
+	msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x28);
+}
+
+static void msm_vfe40_axi_clear_comp_mask(struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream *stream_info)
+{
+	uint32_t comp_mask, comp_mask_index = stream_info->comp_mask_index;
+	uint32_t irq_mask;
+
+	comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x40);
+	comp_mask &= ~(0x7F << (comp_mask_index * 8));
+	msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x40);
+
+	irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28);
+	irq_mask &= ~(1 << (comp_mask_index + 25));
+	msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x28);
+}
+
+static void msm_vfe40_axi_cfg_wm_irq_mask(struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream *stream_info)
+{
+	uint32_t irq_mask;
+	irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28);
+	irq_mask |= 1 << (stream_info->wm[0] + 8);
+	msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x28);
+}
+
+static void msm_vfe40_axi_clear_wm_irq_mask(struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream *stream_info)
+{
+	uint32_t irq_mask;
+	irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28);
+	irq_mask &= ~(1 << (stream_info->wm[0] + 8));
+	msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x28);
+}
+
+static void msm_vfe40_cfg_framedrop(struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream *stream_info)
+{
+	uint32_t i, temp;
+	uint32_t framedrop_pattern = 0, framedrop_period = 0;
+
+	if (stream_info->runtime_init_frame_drop == 0) {
+		framedrop_pattern = stream_info->framedrop_pattern;
+		framedrop_period = stream_info->framedrop_period;
+	}
+
+	if (stream_info->stream_type == BURST_STREAM &&
+			stream_info->runtime_burst_frame_count == 0) {
+		framedrop_pattern = 0;
+		framedrop_period = 0;
+	}
+
+	for (i = 0; i < stream_info->num_planes; i++) {
+		msm_camera_io_w(framedrop_pattern, vfe_dev->vfe_base +
+			VFE40_WM_BASE(stream_info->wm[i]) + 0x1C);
+		temp = msm_camera_io_r(vfe_dev->vfe_base +
+			VFE40_WM_BASE(stream_info->wm[i]) + 0xC);
+		temp &= 0xFFFFFF83;
+		msm_camera_io_w(temp | framedrop_period << 2,
+		vfe_dev->vfe_base + VFE40_WM_BASE(stream_info->wm[i]) + 0xC);
+	}
+
+	msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x378);
+}
+
+static void msm_vfe40_clear_framedrop(struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream *stream_info)
+{
+	uint32_t i;
+	for (i = 0; i < stream_info->num_planes; i++)
+		msm_camera_io_w(0, vfe_dev->vfe_base +
+			VFE40_WM_BASE(stream_info->wm[i]) + 0x1C);
+}
+
+static void msm_vfe40_cfg_io_format(struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream_request_cmd *stream_req_cmd)
+{
+	int bpp, bpp_reg = 0;
+	uint32_t io_format_reg;
+	bpp = msm_isp_get_bit_per_pixel(stream_req_cmd->output_format);
+
+	switch (bpp) {
+	case 8:
+		bpp_reg = 0;
+		break;
+	case 10:
+		bpp_reg = 1 << 0;
+		break;
+	case 12:
+		bpp_reg = 1 << 1;
+		break;
+	}
+	io_format_reg = msm_camera_io_r(vfe_dev->vfe_base + 0x54);
+	switch (stream_req_cmd->stream_src) {
+	case CAMIF_RAW:
+		io_format_reg &= 0xFFFFCFFF;
+		io_format_reg |= bpp_reg << 12;
+		break;
+	case IDEAL_RAW:
+		io_format_reg &= 0xFFFFFFC8;
+		io_format_reg |= bpp_reg << 4;
+		break;
+	case PIX_ENCODER:
+	case PIX_VIEWFINDER:
+	case RDI_INTF_0:
+	case RDI_INTF_1:
+	case RDI_INTF_2:
+	default:
+		pr_err("%s: Invalid stream source\n", __func__);
+		return;
+	}
+	msm_camera_io_w(io_format_reg, vfe_dev->vfe_base + 0x54);
+}
+
+static void msm_vfe40_cfg_camif(struct vfe_device *vfe_dev,
+	struct msm_vfe_pix_cfg *pix_cfg)
+{
+	uint16_t first_pixel, last_pixel, first_line, last_line;
+	struct msm_vfe_camif_cfg *camif_cfg = &pix_cfg->camif_cfg;
+	uint32_t val;
+
+	first_pixel = camif_cfg->first_pixel;
+	last_pixel = camif_cfg->last_pixel;
+	first_line = camif_cfg->first_line;
+	last_line = camif_cfg->last_line;
+
+	msm_camera_io_w(pix_cfg->input_mux << 16 | pix_cfg->pixel_pattern,
+		vfe_dev->vfe_base + 0x1C);
+
+	msm_camera_io_w(camif_cfg->lines_per_frame << 16 |
+		camif_cfg->pixels_per_line, vfe_dev->vfe_base + 0x300);
+
+	msm_camera_io_w(first_pixel << 16 | last_pixel,
+	vfe_dev->vfe_base + 0x304);
+
+	msm_camera_io_w(first_line << 16 | last_line,
+	vfe_dev->vfe_base + 0x308);
+
+	msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x314);
+
+	val = msm_camera_io_r(vfe_dev->vfe_base + 0x2E8);
+	val |= camif_cfg->camif_input;
+	msm_camera_io_w(val, vfe_dev->vfe_base + 0x2E8);
+
+	switch (pix_cfg->input_mux) {
+	case CAMIF:
+		val = 0x01;
+		msm_camera_io_w(val, vfe_dev->vfe_base + 0x2F4);
+		break;
+	case TESTGEN:
+		val = 0x01;
+		msm_camera_io_w(val, vfe_dev->vfe_base + 0x93C);
+		break;
+	case EXTERNAL_READ:
+	default:
+		pr_err("%s: not supported input_mux %d\n",
+			__func__, pix_cfg->input_mux);
+		break;
+	}
+}
+
+static void msm_vfe40_update_camif_state(struct vfe_device *vfe_dev,
+	enum msm_isp_camif_update_state update_state)
+{
+	uint32_t val;
+	bool bus_en, vfe_en;
+	if (update_state == NO_UPDATE)
+		return;
+
+	val = msm_camera_io_r(vfe_dev->vfe_base + 0x2F8);
+	if (update_state == ENABLE_CAMIF) {
+		bus_en =
+			((vfe_dev->axi_data.
+			src_info[VFE_PIX_0].raw_stream_count > 0) ? 1 : 0);
+		vfe_en =
+			((vfe_dev->axi_data.
+			src_info[VFE_PIX_0].pix_stream_count > 0) ? 1 : 0);
+		val &= 0xFFFFFF3F;
+		val = val | bus_en << 7 | vfe_en << 6;
+		msm_camera_io_w(val, vfe_dev->vfe_base + 0x2F8);
+		msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x2F4);
+		vfe_dev->axi_data.src_info[VFE_PIX_0].active = 1;
+	} else if (update_state == DISABLE_CAMIF) {
+		msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x2F4);
+		vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0;
+	} else if (update_state == DISABLE_CAMIF_IMMEDIATELY) {
+		msm_camera_io_w_mb(0x2, vfe_dev->vfe_base + 0x2F4);
+		vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0;
+	}
+}
+
+static void msm_vfe40_cfg_rdi_reg(
+	struct vfe_device *vfe_dev, struct msm_vfe_rdi_cfg *rdi_cfg,
+	enum msm_vfe_input_src input_src)
+{
+	uint8_t rdi = input_src - VFE_RAW_0;
+	uint32_t rdi_reg_cfg;
+	rdi_reg_cfg = msm_camera_io_r(
+		vfe_dev->vfe_base + VFE40_RDI_BASE(0));
+	rdi_reg_cfg &= ~(BIT(16 + rdi));
+	rdi_reg_cfg |= rdi_cfg->frame_based << (16 + rdi);
+	msm_camera_io_w(rdi_reg_cfg,
+		vfe_dev->vfe_base + VFE40_RDI_BASE(0));
+
+	rdi_reg_cfg = msm_camera_io_r(
+		vfe_dev->vfe_base + VFE40_RDI_BASE(rdi));
+	rdi_reg_cfg &= 0x70003;
+	rdi_reg_cfg |= (rdi * 3) << 28 | rdi_cfg->cid << 4 | 0x4;
+	msm_camera_io_w(
+		rdi_reg_cfg, vfe_dev->vfe_base + VFE40_RDI_BASE(rdi));
+}
+
+static void msm_vfe40_axi_cfg_wm_reg(
+	struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd,
+	uint8_t plane_idx)
+{
+	uint32_t val;
+	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
+	struct msm_vfe_axi_stream *stream_info =
+		&axi_data->stream_info[
+			(stream_cfg_cmd->axi_stream_handle & 0xFF)];
+	uint32_t wm_base = VFE40_WM_BASE(stream_info->wm[plane_idx]);
+
+	if (!stream_info->frame_based) {
+		/*WR_IMAGE_SIZE*/
+		val =
+			((msm_isp_cal_word_per_line(
+				stream_cfg_cmd->output_format,
+				stream_cfg_cmd->plane_cfg[plane_idx].
+				output_width)+1)/2 - 1) << 16 |
+				(stream_cfg_cmd->plane_cfg[plane_idx].
+				output_height - 1);
+		msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x14);
+
+		/*WR_BUFFER_CFG*/
+		val =
+			msm_isp_cal_word_per_line(stream_cfg_cmd->output_format,
+			stream_cfg_cmd->plane_cfg[
+				plane_idx].output_stride) << 16 |
+			(stream_cfg_cmd->plane_cfg[
+				plane_idx].output_height - 1) << 4 |
+			VFE40_BURST_LEN;
+		msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x18);
+	} else {
+		msm_camera_io_w(0x2, vfe_dev->vfe_base + wm_base);
+		val =
+			msm_isp_cal_word_per_line(stream_cfg_cmd->output_format,
+			stream_cfg_cmd->plane_cfg[
+				plane_idx].output_width) << 16 |
+			(stream_cfg_cmd->plane_cfg[
+				plane_idx].output_height - 1) << 4 |
+			VFE40_BURST_LEN;
+		msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x18);
+	}
+
+	/*WR_IRQ_SUBSAMPLE_PATTERN*/
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe_dev->vfe_base + wm_base + 0x20);
+	/* TD: Add IRQ subsample pattern */
+	return;
+}
+
+static void msm_vfe40_axi_clear_wm_reg(
+	struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx)
+{
+	uint32_t val = 0;
+	uint32_t wm_base = VFE40_WM_BASE(stream_info->wm[plane_idx]);
+	/*WR_ADDR_CFG*/
+	msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0xC);
+	/*WR_IMAGE_SIZE*/
+	msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x14);
+	/*WR_BUFFER_CFG*/
+	msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x18);
+	/*WR_IRQ_SUBSAMPLE_PATTERN*/
+	msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x20);
+	return;
+}
+
+static void msm_vfe40_axi_cfg_wm_xbar_reg(
+	struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd,
+	uint8_t plane_idx)
+{
+	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
+	struct msm_vfe_axi_stream *stream_info =
+		&axi_data->stream_info[
+			(stream_cfg_cmd->axi_stream_handle & 0xFF)];
+	struct msm_vfe_axi_plane_cfg *plane_cfg =
+		&stream_cfg_cmd->plane_cfg[plane_idx];
+	uint8_t wm = stream_info->wm[plane_idx];
+	uint32_t xbar_cfg = 0;
+	uint32_t xbar_reg_cfg = 0;
+
+	switch (stream_cfg_cmd->stream_src) {
+	case PIX_ENCODER:
+	case PIX_VIEWFINDER: {
+		if (plane_cfg->output_plane_format != CRCB_PLANE &&
+			plane_cfg->output_plane_format != CBCR_PLANE) {
+			/*SINGLE_STREAM_SEL*/
+			xbar_cfg |= plane_cfg->output_plane_format << 8;
+		} else {
+			switch (stream_cfg_cmd->output_format) {
+			case V4L2_PIX_FMT_NV12:
+			case V4L2_PIX_FMT_NV16:
+				xbar_cfg |= 0x3 << 4; /*PAIR_STREAM_SWAP_CTRL*/
+				break;
+			}
+			xbar_cfg |= 0x1 << 1; /*PAIR_STREAM_EN*/
+		}
+		if (stream_cfg_cmd->stream_src == PIX_VIEWFINDER)
+			xbar_cfg |= 0x1; /*VIEW_STREAM_EN*/
+		break;
+	}
+	case CAMIF_RAW:
+		xbar_cfg = 0x300;
+		break;
+	case IDEAL_RAW:
+		xbar_cfg = 0x400;
+		break;
+	case RDI_INTF_0:
+		xbar_cfg = 0x500;
+		break;
+	case RDI_INTF_1:
+		xbar_cfg = 0x600;
+		break;
+	case RDI_INTF_2:
+		xbar_cfg = 0x700;
+		break;
+	default:
+		pr_err("%s: Invalid stream src\n", __func__);
+		break;
+	}
+	xbar_reg_cfg =
+		msm_camera_io_r(vfe_dev->vfe_base + VFE40_XBAR_BASE(wm));
+	xbar_reg_cfg &= ~(0xFFFF << VFE40_XBAR_SHIFT(wm));
+	xbar_reg_cfg |= (xbar_cfg << VFE40_XBAR_SHIFT(wm));
+	msm_camera_io_w(xbar_reg_cfg,
+		vfe_dev->vfe_base + VFE40_XBAR_BASE(wm));
+	return;
+}
+
+static void msm_vfe40_axi_clear_wm_xbar_reg(
+	struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx)
+{
+	uint8_t wm = stream_info->wm[plane_idx];
+	uint32_t xbar_reg_cfg = 0;
+
+	xbar_reg_cfg =
+		msm_camera_io_r(vfe_dev->vfe_base + VFE40_XBAR_BASE(wm));
+	xbar_reg_cfg &= ~(0xFFFF << VFE40_XBAR_SHIFT(wm));
+	msm_camera_io_w(xbar_reg_cfg,
+		vfe_dev->vfe_base + VFE40_XBAR_BASE(wm));
+}
+
+#define MSM_ISP40_TOTAL_WM_UB 819
+
+static void msm_vfe40_cfg_axi_ub_equal_default(
+	struct vfe_device *vfe_dev)
+{
+	int i;
+	uint32_t ub_offset = 0;
+	struct msm_vfe_axi_shared_data *axi_data =
+		&vfe_dev->axi_data;
+	uint32_t total_image_size = 0;
+	uint8_t num_used_wms = 0;
+	uint32_t prop_size = 0;
+	uint32_t wm_ub_size;
+	uint32_t delta;
+
+	for (i = 0; i < axi_data->hw_info->num_wm; i++) {
+		if (axi_data->free_wm[i] > 0) {
+			num_used_wms++;
+			total_image_size += axi_data->wm_image_size[i];
+		}
+	}
+	prop_size = MSM_ISP40_TOTAL_WM_UB -
+		axi_data->hw_info->min_wm_ub * num_used_wms;
+	for (i = 0; i < axi_data->hw_info->num_wm; i++) {
+		if (axi_data->free_wm[i]) {
+			delta =
+				(axi_data->wm_image_size[i] *
+					prop_size)/total_image_size;
+			wm_ub_size = axi_data->hw_info->min_wm_ub + delta;
+			msm_camera_io_w(ub_offset << 16 | (wm_ub_size - 1),
+				vfe_dev->vfe_base + VFE40_WM_BASE(i) + 0x10);
+			ub_offset += wm_ub_size;
+		} else
+			msm_camera_io_w(0,
+				vfe_dev->vfe_base + VFE40_WM_BASE(i) + 0x10);
+	}
+}
+
+static void msm_vfe40_cfg_axi_ub_equal_slicing(
+	struct vfe_device *vfe_dev)
+{
+	int i;
+	uint32_t ub_offset = 0;
+	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
+	for (i = 0; i < axi_data->hw_info->num_wm; i++) {
+		msm_camera_io_w(ub_offset << 16 | (VFE40_EQUAL_SLICE_UB - 1),
+			vfe_dev->vfe_base + VFE40_WM_BASE(i) + 0x10);
+		ub_offset += VFE40_EQUAL_SLICE_UB;
+	}
+}
+
+static void msm_vfe40_cfg_axi_ub(struct vfe_device *vfe_dev)
+{
+	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
+	axi_data->wm_ub_cfg_policy = MSM_WM_UB_EQUAL_SLICING;
+	if (axi_data->wm_ub_cfg_policy == MSM_WM_UB_EQUAL_SLICING)
+		msm_vfe40_cfg_axi_ub_equal_slicing(vfe_dev);
+	else
+		msm_vfe40_cfg_axi_ub_equal_default(vfe_dev);
+}
+
+static void msm_vfe40_update_ping_pong_addr(
+	struct vfe_device *vfe_dev,
+	uint8_t wm_idx, uint32_t pingpong_status, unsigned long paddr)
+{
+	msm_camera_io_w(paddr, vfe_dev->vfe_base +
+		VFE40_PING_PONG_BASE(wm_idx, pingpong_status));
+}
+
+static long msm_vfe40_axi_halt(struct vfe_device *vfe_dev)
+{
+	uint32_t halt_mask;
+	halt_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x2C);
+	halt_mask |= (1 << 8);
+	msm_camera_io_w_mb(halt_mask, vfe_dev->vfe_base + 0x2C);
+	init_completion(&vfe_dev->halt_complete);
+	msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x2C0);
+	return wait_for_completion_interruptible_timeout(
+		&vfe_dev->halt_complete, msecs_to_jiffies(500));
+}
+
+static uint32_t msm_vfe40_get_wm_mask(
+	uint32_t irq_status0, uint32_t irq_status1)
+{
+	return (irq_status0 >> 8) & 0x7F;
+}
+
+static uint32_t msm_vfe40_get_comp_mask(
+	uint32_t irq_status0, uint32_t irq_status1)
+{
+	return (irq_status0 >> 25) & 0xF;
+}
+
+static uint32_t msm_vfe40_get_pingpong_status(
+	struct vfe_device *vfe_dev)
+{
+	return msm_camera_io_r(vfe_dev->vfe_base + 0x268);
+}
+
+static int msm_vfe40_get_stats_idx(enum msm_isp_stats_type stats_type)
+{
+	switch (stats_type) {
+	case MSM_ISP_STATS_BE:
+		return 0;
+	case MSM_ISP_STATS_BG:
+		return 1;
+	case MSM_ISP_STATS_BF:
+		return 2;
+	case MSM_ISP_STATS_AWB:
+		return 3;
+	case MSM_ISP_STATS_RS:
+		return 4;
+	case MSM_ISP_STATS_CS:
+		return 5;
+	case MSM_ISP_STATS_IHIST:
+		return 6;
+	case MSM_ISP_STATS_BHIST:
+		return 7;
+	default:
+		pr_err("%s: Invalid stats type\n", __func__);
+		return -EINVAL;
+	}
+}
+
+static void msm_vfe40_stats_cfg_comp_mask(struct vfe_device *vfe_dev)
+{
+	if (vfe_dev->stats_data.stats_pipeline_policy == STATS_COMP_ALL)
+		msm_camera_io_w(0x00FF0000, vfe_dev->vfe_base + 0x44);
+	else
+		msm_camera_io_w(0x00000000, vfe_dev->vfe_base + 0x44);
+}
+
+static void msm_vfe40_stats_cfg_wm_irq_mask(
+	struct vfe_device *vfe_dev,
+	struct msm_vfe_stats_stream *stream_info)
+{
+	uint32_t irq_mask;
+	irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28);
+	irq_mask |= 1 << (STATS_IDX(stream_info->stream_handle) + 16);
+	msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x28);
+}
+
+static void msm_vfe40_stats_clear_wm_irq_mask(
+	struct vfe_device *vfe_dev,
+	struct msm_vfe_stats_stream *stream_info)
+{
+	uint32_t irq_mask;
+	irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28);
+	irq_mask &= ~(1 << (STATS_IDX(stream_info->stream_handle) + 16));
+	msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x28);
+}
+
+static void msm_vfe40_stats_cfg_wm_reg(
+	struct vfe_device *vfe_dev,
+	struct msm_vfe_stats_stream *stream_info)
+{
+	int stats_idx = STATS_IDX(stream_info->stream_handle);
+	uint32_t stats_base = VFE40_STATS_BASE(stats_idx);
+
+	/*WR_ADDR_CFG*/
+	msm_camera_io_w(0x7C, vfe_dev->vfe_base + stats_base + 0x8);
+	/*WR_IRQ_FRAMEDROP_PATTERN*/
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe_dev->vfe_base + stats_base + 0x10);
+	/*WR_IRQ_SUBSAMPLE_PATTERN*/
+	msm_camera_io_w(0xFFFFFFFF,
+		vfe_dev->vfe_base + stats_base + 0x14);
+}
+
+static void msm_vfe40_stats_clear_wm_reg(
+	struct vfe_device *vfe_dev,
+	struct msm_vfe_stats_stream *stream_info)
+{
+	uint32_t val = 0;
+	int stats_idx = STATS_IDX(stream_info->stream_handle);
+	uint32_t stats_base = VFE40_STATS_BASE(stats_idx);
+
+	/*WR_ADDR_CFG*/
+	msm_camera_io_w(val, vfe_dev->vfe_base + stats_base + 0x8);
+	/*WR_IRQ_FRAMEDROP_PATTERN*/
+	msm_camera_io_w(val, vfe_dev->vfe_base + stats_base + 0x10);
+	/*WR_IRQ_SUBSAMPLE_PATTERN*/
+	msm_camera_io_w(val, vfe_dev->vfe_base + stats_base + 0x14);
+}
+
+static void msm_vfe40_stats_cfg_ub(struct vfe_device *vfe_dev)
+{
+	int i;
+	uint32_t ub_offset = VFE40_UB_SIZE;
+	uint32_t ub_size[VFE40_NUM_STATS_TYPE] = {
+		64, /*MSM_ISP_STATS_BE*/
+		128, /*MSM_ISP_STATS_BG*/
+		128, /*MSM_ISP_STATS_BF*/
+		16, /*MSM_ISP_STATS_AWB*/
+		8,  /*MSM_ISP_STATS_RS*/
+		16, /*MSM_ISP_STATS_CS*/
+		16, /*MSM_ISP_STATS_IHIST*/
+		16, /*MSM_ISP_STATS_BHIST*/
+	};
+
+	for (i = 0; i < VFE40_NUM_STATS_TYPE; i++) {
+		ub_offset -= ub_size[i];
+		msm_camera_io_w(VFE40_STATS_BURST_LEN << 30 |
+			ub_offset << 16 | (ub_size[i] - 1),
+			vfe_dev->vfe_base + VFE40_STATS_BASE(i) + 0xC);
+	}
+}
+
+static void msm_vfe40_stats_enable_module(struct vfe_device *vfe_dev,
+	uint32_t stats_mask, uint8_t enable)
+{
+	int i;
+	uint32_t module_cfg, module_cfg_mask = 0;
+
+	for (i = 0; i < VFE40_NUM_STATS_TYPE; i++) {
+		if ((stats_mask >> i) & 0x1) {
+			switch (i) {
+			case 0:
+			case 1:
+			case 2:
+			case 3:
+			case 4:
+			case 5:
+				module_cfg_mask |= 1 << (5 + i);
+				break;
+			case 6:
+				module_cfg_mask |= 1 << 15;
+				break;
+			case 7:
+				module_cfg_mask |= 1 << 18;
+				break;
+			default:
+				pr_err("%s: Invalid stats mask\n", __func__);
+				return;
+			}
+		}
+	}
+
+	module_cfg = msm_camera_io_r(vfe_dev->vfe_base + 0x18);
+	if (enable)
+		module_cfg |= module_cfg_mask;
+	else
+		module_cfg &= ~module_cfg_mask;
+	msm_camera_io_w(module_cfg, vfe_dev->vfe_base + 0x18);
+}
+
+static void msm_vfe40_stats_update_ping_pong_addr(
+	struct vfe_device *vfe_dev, struct msm_vfe_stats_stream *stream_info,
+	uint32_t pingpong_status, unsigned long paddr)
+{
+	int stats_idx = STATS_IDX(stream_info->stream_handle);
+	msm_camera_io_w(paddr, vfe_dev->vfe_base +
+		VFE40_STATS_PING_PONG_BASE(stats_idx, pingpong_status));
+}
+
+static uint32_t msm_vfe40_stats_get_wm_mask(
+	uint32_t irq_status0, uint32_t irq_status1)
+{
+	return (irq_status0 >> 16) & 0xFF;
+}
+
+static uint32_t msm_vfe40_stats_get_comp_mask(
+	uint32_t irq_status0, uint32_t irq_status1)
+{
+	return (irq_status0 >> 29) & 0x3;
+}
+
+static uint32_t msm_vfe40_stats_get_frame_id(
+	struct vfe_device *vfe_dev)
+{
+	return vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id;
+}
+
+static int msm_vfe40_get_platform_data(struct vfe_device *vfe_dev)
+{
+	int rc = 0;
+	vfe_dev->vfe_mem = platform_get_resource_byname(vfe_dev->pdev,
+		IORESOURCE_MEM, "vfe");
+	if (!vfe_dev->vfe_mem) {
+		pr_err("%s: no mem resource?\n", __func__);
+		rc = -ENODEV;
+		goto vfe_no_resource;
+	}
+
+	vfe_dev->vfe_vbif_mem = platform_get_resource_byname(
+		vfe_dev->pdev,
+		IORESOURCE_MEM, "vfe_vbif");
+	if (!vfe_dev->vfe_vbif_mem) {
+		pr_err("%s: no mem resource?\n", __func__);
+		rc = -ENODEV;
+		goto vfe_no_resource;
+	}
+
+	vfe_dev->vfe_irq = platform_get_resource_byname(vfe_dev->pdev,
+		IORESOURCE_IRQ, "vfe");
+	if (!vfe_dev->vfe_irq) {
+		pr_err("%s: no irq resource?\n", __func__);
+		rc = -ENODEV;
+		goto vfe_no_resource;
+	}
+
+	vfe_dev->fs_vfe = regulator_get(&vfe_dev->pdev->dev, "vdd");
+	if (IS_ERR(vfe_dev->fs_vfe)) {
+		pr_err("%s: Regulator get failed %ld\n", __func__,
+		PTR_ERR(vfe_dev->fs_vfe));
+		vfe_dev->fs_vfe = NULL;
+		rc = -ENODEV;
+		goto vfe_no_resource;
+	}
+
+	if (vfe_dev->pdev->id == 0)
+		vfe_dev->iommu_ctx[0] = msm_iommu_get_ctx("vfe0");
+	else if (vfe_dev->pdev->id == 1)
+		vfe_dev->iommu_ctx[0] = msm_iommu_get_ctx("vfe1");
+	if (!vfe_dev->iommu_ctx[0]) {
+		pr_err("%s: cannot get iommu_ctx\n", __func__);
+		rc = -ENODEV;
+		goto vfe_no_resource;
+	}
+
+vfe_no_resource:
+	return rc;
+}
+
+static void msm_vfe40_get_error_mask(
+	uint32_t *error_mask0, uint32_t *error_mask1)
+{
+	*error_mask0 = 0x00000000;
+	*error_mask1 = 0x00FFFEFF;
+}
+
+static struct msm_vfe_axi_hardware_info msm_vfe40_axi_hw_info = {
+	.num_wm = 4,
+	.num_comp_mask = 4,
+	.num_rdi = 3,
+	.num_rdi_master = 3,
+	.min_wm_ub = 64,
+};
+
+static struct msm_vfe_stats_hardware_info msm_vfe40_stats_hw_info = {
+	.stats_capability_mask =
+		1 << MSM_ISP_STATS_BE | 1 << MSM_ISP_STATS_BF |
+		1 << MSM_ISP_STATS_BG | 1 << MSM_ISP_STATS_BHIST |
+		1 << MSM_ISP_STATS_AWB | 1 << MSM_ISP_STATS_IHIST |
+		1 << MSM_ISP_STATS_RS | 1 << MSM_ISP_STATS_CS,
+	.stats_ping_pong_offset = VFE40_STATS_PING_PONG_OFFSET,
+	.num_stats_type = VFE40_NUM_STATS_TYPE,
+	.num_stats_comp_mask = 2,
+};
+
+static struct v4l2_subdev_core_ops msm_vfe40_subdev_core_ops = {
+	.ioctl = msm_isp_ioctl,
+	.subscribe_event = msm_isp_subscribe_event,
+	.unsubscribe_event = msm_isp_unsubscribe_event,
+};
+
+static struct v4l2_subdev_ops msm_vfe40_subdev_ops = {
+	.core = &msm_vfe40_subdev_core_ops,
+};
+
+static struct v4l2_subdev_internal_ops msm_vfe40_internal_ops = {
+	.open = msm_isp_open_node,
+	.close = msm_isp_close_node,
+};
+
+struct msm_vfe_hardware_info vfe40_hw_info = {
+	.num_iommu_ctx = 1,
+	.vfe_ops = {
+		.irq_ops = {
+			.read_irq_status = msm_vfe40_read_irq_status,
+			.process_camif_irq = msm_vfe40_process_camif_irq,
+			.process_reset_irq = msm_vfe40_process_reset_irq,
+			.process_halt_irq = msm_vfe40_process_halt_irq,
+			.process_reset_irq = msm_vfe40_process_reset_irq,
+			.process_reg_update = msm_vfe40_process_reg_update,
+			.process_axi_irq = msm_isp_process_axi_irq,
+			.process_stats_irq = msm_isp_process_stats_irq,
+		},
+		.axi_ops = {
+			.reload_wm = msm_vfe40_axi_reload_wm,
+			.enable_wm = msm_vfe40_axi_enable_wm,
+			.cfg_io_format = msm_vfe40_cfg_io_format,
+			.cfg_comp_mask = msm_vfe40_axi_cfg_comp_mask,
+			.clear_comp_mask = msm_vfe40_axi_clear_comp_mask,
+			.cfg_wm_irq_mask = msm_vfe40_axi_cfg_wm_irq_mask,
+			.clear_wm_irq_mask = msm_vfe40_axi_clear_wm_irq_mask,
+			.cfg_framedrop = msm_vfe40_cfg_framedrop,
+			.clear_framedrop = msm_vfe40_clear_framedrop,
+			.cfg_wm_reg = msm_vfe40_axi_cfg_wm_reg,
+			.clear_wm_reg = msm_vfe40_axi_clear_wm_reg,
+			.cfg_wm_xbar_reg = msm_vfe40_axi_cfg_wm_xbar_reg,
+			.clear_wm_xbar_reg = msm_vfe40_axi_clear_wm_xbar_reg,
+			.cfg_ub = msm_vfe40_cfg_axi_ub,
+			.update_ping_pong_addr =
+				msm_vfe40_update_ping_pong_addr,
+			.get_comp_mask = msm_vfe40_get_comp_mask,
+			.get_wm_mask = msm_vfe40_get_wm_mask,
+			.get_pingpong_status = msm_vfe40_get_pingpong_status,
+			.halt = msm_vfe40_axi_halt,
+		},
+		.core_ops = {
+			.reg_update = msm_vfe40_reg_update,
+			.cfg_camif = msm_vfe40_cfg_camif,
+			.update_camif_state = msm_vfe40_update_camif_state,
+			.cfg_rdi_reg = msm_vfe40_cfg_rdi_reg,
+			.reset_hw = msm_vfe40_reset_hardware,
+			.init_hw = msm_vfe40_init_hardware,
+			.init_hw_reg = msm_vfe40_init_hardware_reg,
+			.release_hw = msm_vfe40_release_hardware,
+			.get_platform_data = msm_vfe40_get_platform_data,
+			.get_error_mask = msm_vfe40_get_error_mask,
+			.process_error_status = msm_vfe40_process_error_status,
+		},
+		.stats_ops = {
+			.get_stats_idx = msm_vfe40_get_stats_idx,
+			.cfg_comp_mask = msm_vfe40_stats_cfg_comp_mask,
+			.cfg_wm_irq_mask = msm_vfe40_stats_cfg_wm_irq_mask,
+			.clear_wm_irq_mask = msm_vfe40_stats_clear_wm_irq_mask,
+			.cfg_wm_reg = msm_vfe40_stats_cfg_wm_reg,
+			.clear_wm_reg = msm_vfe40_stats_clear_wm_reg,
+			.cfg_ub = msm_vfe40_stats_cfg_ub,
+			.enable_module = msm_vfe40_stats_enable_module,
+			.update_ping_pong_addr =
+				msm_vfe40_stats_update_ping_pong_addr,
+			.get_comp_mask = msm_vfe40_stats_get_comp_mask,
+			.get_wm_mask = msm_vfe40_stats_get_wm_mask,
+			.get_frame_id = msm_vfe40_stats_get_frame_id,
+			.get_pingpong_status = msm_vfe40_get_pingpong_status,
+		},
+	},
+	.dmi_reg_offset = 0x918,
+	.axi_hw_info = &msm_vfe40_axi_hw_info,
+	.stats_hw_info = &msm_vfe40_stats_hw_info,
+	.subdev_ops = &msm_vfe40_subdev_ops,
+	.subdev_internal_ops = &msm_vfe40_internal_ops,
+};
+EXPORT_SYMBOL(vfe40_hw_info);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.h
new file mode 100644
index 0000000..e9b1518
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.h
@@ -0,0 +1,17 @@
+/* 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 __MSM_ISP40_H__
+#define __MSM_ISP40_H__
+
+extern struct msm_vfe_hardware_info vfe40_hw_info;
+#endif /* __MSM_ISP40_H__ */
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
new file mode 100644
index 0000000..f08644f
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
@@ -0,0 +1,1016 @@
+/* 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/io.h>
+#include <media/v4l2-subdev.h>
+#include "msm_isp_util.h"
+#include "msm_isp_axi_util.h"
+
+#define SRC_TO_INTF(src) \
+	((src < RDI_INTF_0) ? VFE_PIX_0 : \
+	(VFE_RAW_0 + src - RDI_INTF_0))
+
+int msm_isp_axi_create_stream(
+	struct msm_vfe_axi_shared_data *axi_data,
+	struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd)
+{
+	int i, rc = -1;
+	for (i = 0; i < MAX_NUM_STREAM; i++) {
+		if (axi_data->stream_info[i].state == AVALIABLE)
+			break;
+	}
+
+	if (i == MAX_NUM_STREAM) {
+		pr_err("%s: No free stream\n", __func__);
+		return rc;
+	}
+
+	if ((axi_data->stream_handle_cnt << 8) == 0)
+		axi_data->stream_handle_cnt++;
+
+	stream_cfg_cmd->axi_stream_handle =
+		(++axi_data->stream_handle_cnt) << 8 | i;
+
+	memset(&axi_data->stream_info[i], 0,
+		   sizeof(struct msm_vfe_axi_stream));
+	axi_data->stream_info[i].session_id = stream_cfg_cmd->session_id;
+	axi_data->stream_info[i].stream_id = stream_cfg_cmd->stream_id;
+	axi_data->stream_info[i].buf_divert = stream_cfg_cmd->buf_divert;
+	axi_data->stream_info[i].state = INACTIVE;
+	axi_data->stream_info[i].stream_handle =
+		stream_cfg_cmd->axi_stream_handle;
+	return 0;
+}
+
+void msm_isp_axi_destroy_stream(
+	struct msm_vfe_axi_shared_data *axi_data, int stream_idx)
+{
+	if (axi_data->stream_info[stream_idx].state != AVALIABLE) {
+		axi_data->stream_info[stream_idx].state = AVALIABLE;
+		axi_data->stream_info[stream_idx].stream_handle = 0;
+	} else {
+		pr_err("%s: stream does not exist\n", __func__);
+	}
+}
+
+int msm_isp_validate_axi_request(struct msm_vfe_axi_shared_data *axi_data,
+	struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd)
+{
+	int rc = -1;
+	struct msm_vfe_axi_stream *stream_info =
+		&axi_data->stream_info[
+			(stream_cfg_cmd->axi_stream_handle & 0xFF)];
+
+	switch (stream_cfg_cmd->output_format) {
+	case V4L2_PIX_FMT_SBGGR8:
+	case V4L2_PIX_FMT_SGBRG8:
+	case V4L2_PIX_FMT_SGRBG8:
+	case V4L2_PIX_FMT_SRGGB8:
+	case V4L2_PIX_FMT_SBGGR10:
+	case V4L2_PIX_FMT_SGBRG10:
+	case V4L2_PIX_FMT_SGRBG10:
+	case V4L2_PIX_FMT_SRGGB10:
+	case V4L2_PIX_FMT_SBGGR12:
+	case V4L2_PIX_FMT_SGBRG12:
+	case V4L2_PIX_FMT_SGRBG12:
+	case V4L2_PIX_FMT_SRGGB12:
+	case V4L2_PIX_FMT_QBGGR8:
+	case V4L2_PIX_FMT_QGBRG8:
+	case V4L2_PIX_FMT_QGRBG8:
+	case V4L2_PIX_FMT_QRGGB8:
+	case V4L2_PIX_FMT_QBGGR10:
+	case V4L2_PIX_FMT_QGBRG10:
+	case V4L2_PIX_FMT_QGRBG10:
+	case V4L2_PIX_FMT_QRGGB10:
+	case V4L2_PIX_FMT_QBGGR12:
+	case V4L2_PIX_FMT_QGBRG12:
+	case V4L2_PIX_FMT_QGRBG12:
+	case V4L2_PIX_FMT_QRGGB12:
+		stream_info->num_planes = 1;
+		break;
+	case V4L2_PIX_FMT_NV12:
+	case V4L2_PIX_FMT_NV21:
+		stream_info->num_planes = 2;
+		break;
+	/*TD: Add more image format*/
+	default:
+		pr_err("%s: Invalid output format\n", __func__);
+		return rc;
+	}
+
+	if (axi_data->hw_info->num_wm - axi_data->num_used_wm <
+		stream_info->num_planes) {
+		pr_err("%s: No free write masters\n", __func__);
+		return rc;
+	}
+
+	if ((stream_info->num_planes > 1) &&
+			(axi_data->hw_info->num_comp_mask -
+			axi_data->num_used_composite_mask < 1)) {
+		pr_err("%s: No free composite mask\n", __func__);
+		return rc;
+	}
+
+	if (stream_cfg_cmd->init_frame_drop >= MAX_INIT_FRAME_DROP) {
+		pr_err("%s: Invalid skip pattern\n", __func__);
+		return rc;
+	}
+
+	if (stream_cfg_cmd->frame_skip_pattern >= MAX_SKIP) {
+		pr_err("%s: Invalid skip pattern\n", __func__);
+		return rc;
+	}
+
+	stream_info->stream_src = stream_cfg_cmd->stream_src;
+	stream_info->frame_based = stream_cfg_cmd->frame_base;
+	return 0;
+}
+
+static uint32_t msm_isp_axi_get_plane_size(
+	struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd, int plane_idx)
+{
+	uint32_t size = 0;
+	struct msm_vfe_axi_plane_cfg *plane_cfg = stream_cfg_cmd->plane_cfg;
+	switch (stream_cfg_cmd->output_format) {
+	case V4L2_PIX_FMT_SBGGR8:
+	case V4L2_PIX_FMT_SGBRG8:
+	case V4L2_PIX_FMT_SGRBG8:
+	case V4L2_PIX_FMT_SRGGB8:
+	case V4L2_PIX_FMT_QBGGR8:
+	case V4L2_PIX_FMT_QGBRG8:
+	case V4L2_PIX_FMT_QGRBG8:
+	case V4L2_PIX_FMT_QRGGB8:
+		size = plane_cfg[plane_idx].output_height *
+		plane_cfg[plane_idx].output_width;
+		break;
+	case V4L2_PIX_FMT_SBGGR10:
+	case V4L2_PIX_FMT_SGBRG10:
+	case V4L2_PIX_FMT_SGRBG10:
+	case V4L2_PIX_FMT_SRGGB10:
+	case V4L2_PIX_FMT_QBGGR10:
+	case V4L2_PIX_FMT_QGBRG10:
+	case V4L2_PIX_FMT_QGRBG10:
+	case V4L2_PIX_FMT_QRGGB10:
+		/* TODO: fix me */
+		size = plane_cfg[plane_idx].output_height *
+		plane_cfg[plane_idx].output_width;
+		break;
+	case V4L2_PIX_FMT_SBGGR12:
+	case V4L2_PIX_FMT_SGBRG12:
+	case V4L2_PIX_FMT_SGRBG12:
+	case V4L2_PIX_FMT_SRGGB12:
+	case V4L2_PIX_FMT_QBGGR12:
+	case V4L2_PIX_FMT_QGBRG12:
+	case V4L2_PIX_FMT_QGRBG12:
+	case V4L2_PIX_FMT_QRGGB12:
+		/* TODO: fix me */
+		size = plane_cfg[plane_idx].output_height *
+		plane_cfg[plane_idx].output_width;
+		break;
+	case V4L2_PIX_FMT_NV12:
+	case V4L2_PIX_FMT_NV21:
+		if (plane_cfg[plane_idx].output_plane_format == Y_PLANE)
+			size = plane_cfg[plane_idx].output_height *
+				plane_cfg[plane_idx].output_width;
+		else
+			size = plane_cfg[plane_idx].output_height *
+				plane_cfg[plane_idx].output_width / 2;
+		break;
+	/*TD: Add more image format*/
+	default:
+		pr_err("%s: Invalid output format\n", __func__);
+		break;
+	}
+	return size;
+}
+
+void msm_isp_axi_reserve_wm(struct msm_vfe_axi_shared_data *axi_data,
+	struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd)
+{
+	int i, j;
+	struct msm_vfe_axi_stream *stream_info =
+		&axi_data->stream_info[
+			(stream_cfg_cmd->axi_stream_handle & 0xFF)];
+
+	for (i = 0; i < stream_info->num_planes; i++) {
+		for (j = 0; j < axi_data->hw_info->num_wm; j++) {
+			if (!axi_data->free_wm[j]) {
+				axi_data->free_wm[j] =
+					stream_cfg_cmd->axi_stream_handle;
+				axi_data->wm_image_size[j] =
+					msm_isp_axi_get_plane_size(
+						stream_cfg_cmd, i);
+				axi_data->num_used_wm++;
+				break;
+			}
+		}
+		stream_info->wm[i] = j;
+	}
+}
+
+void msm_isp_axi_free_wm(struct msm_vfe_axi_shared_data *axi_data,
+	struct msm_vfe_axi_stream *stream_info)
+{
+	int i;
+	for (i = 0; i < stream_info->num_planes; i++) {
+		axi_data->free_wm[stream_info->wm[i]] = 0;
+		axi_data->num_used_wm--;
+	}
+}
+
+void msm_isp_axi_reserve_comp_mask(
+	struct msm_vfe_axi_shared_data *axi_data,
+	struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd)
+{
+	int i;
+	uint8_t comp_mask = 0;
+	struct msm_vfe_axi_stream *stream_info =
+		&axi_data->stream_info[
+			(stream_cfg_cmd->axi_stream_handle & 0xFF)];
+	for (i = 0; i < stream_info->num_planes; i++)
+		comp_mask |= 1 << stream_info->wm[i];
+
+	for (i = 0; i < axi_data->hw_info->num_comp_mask; i++) {
+		if (!axi_data->composite_info[i].stream_handle) {
+			axi_data->composite_info[i].stream_handle =
+			stream_cfg_cmd->axi_stream_handle;
+			axi_data->composite_info[i].
+				stream_composite_mask = comp_mask;
+			axi_data->num_used_composite_mask++;
+			break;
+		}
+	}
+	stream_info->comp_mask_index = i;
+	return;
+}
+
+void msm_isp_axi_free_comp_mask(struct msm_vfe_axi_shared_data *axi_data,
+	struct msm_vfe_axi_stream *stream_info)
+{
+	axi_data->composite_info[stream_info->comp_mask_index].
+		stream_composite_mask = 0;
+	axi_data->composite_info[stream_info->comp_mask_index].
+		stream_handle = 0;
+	axi_data->num_used_composite_mask--;
+}
+
+int msm_isp_axi_check_stream_state(
+	struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd)
+{
+	int rc = 0, i;
+	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
+	struct msm_vfe_axi_stream *stream_info;
+	enum msm_vfe_axi_state valid_state =
+		(stream_cfg_cmd->cmd == START_STREAM) ? INACTIVE : ACTIVE;
+
+	for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
+		stream_info = &axi_data->stream_info[
+			(stream_cfg_cmd->stream_handle[i] & 0xFF)];
+		if (stream_info->state != valid_state) {
+			pr_err("%s: Invalid stream state\n", __func__);
+			rc = -EINVAL;
+			break;
+		}
+
+		if (stream_cfg_cmd->cmd == START_STREAM) {
+			stream_info->bufq_handle =
+				vfe_dev->buf_mgr->ops->get_bufq_handle(
+			vfe_dev->buf_mgr, stream_info->session_id,
+			stream_info->stream_id);
+			if (stream_info->bufq_handle == 0) {
+				pr_err("%s: Stream has no valid buffer queue\n",
+					__func__);
+				rc = -EINVAL;
+				break;
+			}
+		}
+	}
+	return rc;
+}
+
+void msm_isp_update_framedrop_reg(struct vfe_device *vfe_dev)
+{
+	int i;
+	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
+	struct msm_vfe_axi_stream *stream_info;
+	for (i = 0; i < MAX_NUM_STREAM; i++) {
+		stream_info = &axi_data->stream_info[i];
+		if (stream_info->state != ACTIVE)
+			continue;
+
+		if (stream_info->runtime_framedrop_update) {
+			stream_info->runtime_init_frame_drop--;
+			if (stream_info->runtime_init_frame_drop == 0) {
+				stream_info->runtime_framedrop_update = 0;
+				vfe_dev->hw_info->vfe_ops.axi_ops.
+				cfg_framedrop(vfe_dev, stream_info);
+			}
+		}
+		if (stream_info->stream_type == BURST_STREAM) {
+			stream_info->runtime_burst_frame_count--;
+			if (stream_info->runtime_burst_frame_count == 0) {
+				vfe_dev->hw_info->vfe_ops.axi_ops.
+				cfg_framedrop(vfe_dev, stream_info);
+				vfe_dev->hw_info->vfe_ops.core_ops.
+				 reg_update(vfe_dev);
+			}
+		}
+	}
+}
+
+static void msm_isp_reset_framedrop(struct vfe_device *vfe_dev,
+			struct msm_vfe_axi_stream *stream_info)
+{
+	stream_info->runtime_init_frame_drop = stream_info->init_frame_drop;
+	stream_info->runtime_burst_frame_count =
+		stream_info->burst_frame_count;
+	stream_info->runtime_framedrop_update = stream_info->framedrop_update;
+	vfe_dev->hw_info->vfe_ops.axi_ops.cfg_framedrop(vfe_dev, stream_info);
+}
+
+void msm_isp_sof_notify(struct vfe_device *vfe_dev,
+	enum msm_vfe_input_src frame_src, struct msm_isp_timestamp *ts) {
+	struct msm_isp_event_data sof_event;
+	switch (frame_src) {
+	case VFE_PIX_0:
+		ISP_DBG("%s: PIX0 frame id: %lu\n", __func__,
+			vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id);
+		vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id++;
+		if (vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id == 0)
+			vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id = 1;
+		break;
+	case VFE_RAW_0:
+	case VFE_RAW_1:
+	case VFE_RAW_2:
+		ISP_DBG("%s: RDI%d frame id: %lu\n",
+			__func__, frame_src - VFE_RAW_0,
+			vfe_dev->axi_data.src_info[frame_src].frame_id);
+		vfe_dev->axi_data.src_info[frame_src].frame_id++;
+		if (vfe_dev->axi_data.src_info[frame_src].frame_id == 0)
+			vfe_dev->axi_data.src_info[frame_src].frame_id = 1;
+		break;
+	default:
+		pr_err("%s: invalid frame src %d received\n",
+			__func__, frame_src);
+		break;
+	}
+
+	sof_event.frame_id = vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id;
+	sof_event.timestamp = ts->event_time;
+	msm_isp_send_event(vfe_dev, ISP_EVENT_SOF, &sof_event);
+}
+
+uint32_t msm_isp_get_framedrop_period(
+	enum msm_vfe_frame_skip_pattern frame_skip_pattern)
+{
+	switch (frame_skip_pattern) {
+	case NO_SKIP:
+	case EVERY_2FRAME:
+	case EVERY_3FRAME:
+	case EVERY_4FRAME:
+	case EVERY_5FRAME:
+	case EVERY_6FRAME:
+	case EVERY_7FRAME:
+	case EVERY_8FRAME:
+		return frame_skip_pattern + 1;
+	case EVERY_16FRAME:
+		return 16;
+		break;
+	case EVERY_32FRAME:
+		return 32;
+		break;
+	default:
+		return 1;
+	}
+	return 1;
+}
+
+void msm_isp_calculate_framedrop(
+	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[
+		(stream_cfg_cmd->axi_stream_handle & 0xFF)];
+	uint32_t framedrop_period = msm_isp_get_framedrop_period(
+	   stream_cfg_cmd->frame_skip_pattern);
+
+	stream_info->framedrop_pattern = 0x1;
+	stream_info->framedrop_period = framedrop_period - 1;
+
+	if (stream_cfg_cmd->init_frame_drop < framedrop_period) {
+		stream_info->framedrop_pattern <<=
+			stream_cfg_cmd->init_frame_drop;
+		stream_info->init_frame_drop = 0;
+		stream_info->framedrop_update = 0;
+	} else {
+		stream_info->init_frame_drop = stream_cfg_cmd->init_frame_drop;
+		stream_info->framedrop_update = 1;
+	}
+
+	if (stream_cfg_cmd->burst_count > 0) {
+		stream_info->stream_type = BURST_STREAM;
+		stream_info->num_burst_capture =
+			stream_cfg_cmd->burst_count;
+		stream_info->burst_frame_count =
+		stream_cfg_cmd->init_frame_drop +
+			(stream_cfg_cmd->burst_count - 1) *
+			framedrop_period + 1;
+	} else {
+		stream_info->stream_type = CONTINUOUS_STREAM;
+		stream_info->burst_frame_count = 0;
+		stream_info->num_burst_capture = 0;
+	}
+}
+
+int msm_isp_request_axi_stream(struct vfe_device *vfe_dev, void *arg)
+{
+	int rc = 0, i;
+	struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd = arg;
+	struct msm_vfe_axi_stream *stream_info;
+
+	rc = msm_isp_axi_create_stream(
+		&vfe_dev->axi_data, stream_cfg_cmd);
+	if (rc) {
+		pr_err("%s: create stream failed\n", __func__);
+		return rc;
+	}
+
+	rc = msm_isp_validate_axi_request(
+		&vfe_dev->axi_data, stream_cfg_cmd);
+	if (rc) {
+		pr_err("%s: Request validation failed\n", __func__);
+		msm_isp_axi_destroy_stream(&vfe_dev->axi_data,
+			(stream_cfg_cmd->axi_stream_handle & 0xFF));
+		return rc;
+	}
+
+	stream_info =
+		&vfe_dev->axi_data.
+			stream_info[(stream_cfg_cmd->axi_stream_handle & 0xFF)];
+	msm_isp_axi_reserve_wm(&vfe_dev->axi_data, stream_cfg_cmd);
+
+	if (stream_cfg_cmd->stream_src == CAMIF_RAW ||
+		stream_cfg_cmd->stream_src == IDEAL_RAW)
+			vfe_dev->hw_info->vfe_ops.axi_ops.
+				cfg_io_format(vfe_dev, stream_cfg_cmd);
+
+	msm_isp_calculate_framedrop(&vfe_dev->axi_data, stream_cfg_cmd);
+
+	if (stream_info->num_planes > 1) {
+		msm_isp_axi_reserve_comp_mask(
+			&vfe_dev->axi_data, stream_cfg_cmd);
+		vfe_dev->hw_info->vfe_ops.axi_ops.
+		cfg_comp_mask(vfe_dev, stream_info);
+	} else {
+		vfe_dev->hw_info->vfe_ops.axi_ops.
+			cfg_wm_irq_mask(vfe_dev, stream_info);
+	}
+
+	for (i = 0; i < stream_info->num_planes; i++) {
+		vfe_dev->hw_info->vfe_ops.axi_ops.
+			cfg_wm_reg(vfe_dev, stream_cfg_cmd, i);
+
+		vfe_dev->hw_info->vfe_ops.axi_ops.
+			cfg_wm_xbar_reg(vfe_dev, stream_cfg_cmd, i);
+	}
+	return rc;
+}
+
+int msm_isp_release_axi_stream(struct vfe_device *vfe_dev, void *arg)
+{
+	int rc = 0, i;
+	struct msm_vfe_axi_stream_release_cmd *stream_release_cmd = arg;
+	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
+	struct msm_vfe_axi_stream *stream_info =
+		&axi_data->stream_info[
+		(stream_release_cmd->stream_handle & 0xFF)];
+	struct msm_vfe_axi_stream_cfg_cmd stream_cfg;
+
+	if (stream_info->state == AVALIABLE) {
+		pr_err("%s: Stream already released\n", __func__);
+		return -EINVAL;
+	} else if (stream_info->state != INACTIVE) {
+		stream_cfg.cmd = STOP_STREAM;
+		stream_cfg.num_streams = 1;
+		stream_cfg.stream_handle[0] = stream_release_cmd->stream_handle;
+		msm_isp_cfg_axi_stream(vfe_dev, (void *) &stream_cfg);
+	}
+
+	for (i = 0; i < stream_info->num_planes; i++) {
+		vfe_dev->hw_info->vfe_ops.axi_ops.
+			clear_wm_reg(vfe_dev, stream_info, i);
+
+		vfe_dev->hw_info->vfe_ops.axi_ops.
+		clear_wm_xbar_reg(vfe_dev, stream_info, i);
+	}
+
+	if (stream_info->num_planes > 1) {
+		msm_isp_axi_free_comp_mask(&vfe_dev->axi_data, stream_info);
+		vfe_dev->hw_info->vfe_ops.axi_ops.
+		clear_comp_mask(vfe_dev, stream_info);
+	} else {
+		vfe_dev->hw_info->vfe_ops.axi_ops.
+		clear_wm_irq_mask(vfe_dev, stream_info);
+	}
+
+	vfe_dev->hw_info->vfe_ops.axi_ops.clear_framedrop(vfe_dev, stream_info);
+	msm_isp_axi_free_wm(axi_data, stream_info);
+
+	msm_isp_axi_destroy_stream(&vfe_dev->axi_data,
+		(stream_release_cmd->stream_handle & 0xFF));
+
+	return rc;
+}
+
+void msm_isp_axi_stream_enable_cfg(
+	struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream *stream_info,
+	uint32_t *wm_reload_mask)
+{
+	int i;
+	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
+	if (stream_info->state == INACTIVE)
+		return;
+	for (i = 0; i < stream_info->num_planes; i++) {
+		/*TD: Frame base command*/
+		if (stream_info->state == START_PENDING)
+			vfe_dev->hw_info->vfe_ops.axi_ops.
+				enable_wm(vfe_dev, stream_info->wm[i], 1);
+		else
+			vfe_dev->hw_info->vfe_ops.axi_ops.
+				enable_wm(vfe_dev, stream_info->wm[i], 0);
+
+		*wm_reload_mask |= (1 << stream_info->wm[i]);
+	}
+
+	if (stream_info->state == START_PENDING) {
+		axi_data->num_active_stream++;
+		stream_info->state = ACTIVE;
+	} else {
+		axi_data->num_active_stream--;
+		stream_info->state = INACTIVE;
+	}
+}
+
+void msm_isp_axi_stream_update(struct vfe_device *vfe_dev)
+{
+	int i;
+	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
+	uint32_t wm_reload_mask = 0x0;
+	for (i = 0; i < MAX_NUM_STREAM; i++) {
+		if (axi_data->stream_info[i].state == START_PENDING ||
+				axi_data->stream_info[i].state ==
+					STOP_PENDING) {
+			msm_isp_axi_stream_enable_cfg(
+				vfe_dev, &axi_data->stream_info[i],
+				&wm_reload_mask);
+			if (axi_data->stream_info[i].state == STOP_PENDING)
+				axi_data->stream_info[i].state = STOPPING;
+		}
+	}
+	/*Reload AXI*/
+	vfe_dev->hw_info->vfe_ops.axi_ops.
+		reload_wm(vfe_dev, wm_reload_mask);
+	if (vfe_dev->axi_data.stream_update) {
+		vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev);
+		ISP_DBG("%s: send update complete\n", __func__);
+		vfe_dev->axi_data.stream_update = 0;
+		complete(&vfe_dev->stream_config_complete);
+	}
+}
+
+static void msm_isp_cfg_pong_address(struct vfe_device *vfe_dev,
+		struct msm_vfe_axi_stream *stream_info)
+{
+	int i;
+	struct msm_isp_buffer *buf = stream_info->buf[1];
+	for (i = 0; i < stream_info->num_planes; i++)
+		vfe_dev->hw_info->vfe_ops.axi_ops.update_ping_pong_addr(
+		vfe_dev, stream_info->wm[i],
+		VFE_PING_FLAG, buf->mapped_info[i].paddr);
+	stream_info->buf[0] = buf;
+}
+
+static void msm_isp_get_done_buf(struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_status,
+	struct msm_isp_buffer **done_buf)
+{
+	uint32_t pingpong_bit = 0, i;
+	pingpong_bit = (~(pingpong_status >> stream_info->wm[0]) & 0x1);
+	for (i = 0; i < stream_info->num_planes; i++) {
+		if (pingpong_bit !=
+			(~(pingpong_status >> stream_info->wm[i]) & 0x1)) {
+			pr_warn("%s: Write master ping pong mismatch. Status: 0x%x\n",
+				__func__, pingpong_status);
+		}
+	}
+	*done_buf = stream_info->buf[pingpong_bit];
+}
+
+static int msm_isp_cfg_ping_pong_address(struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_status)
+{
+	int i, rc = -1;
+	struct msm_isp_buffer *buf = NULL;
+	uint32_t pingpong_bit = 0;
+	uint32_t bufq_handle = stream_info->bufq_handle;
+	uint32_t stream_idx = stream_info->stream_handle & 0xFF;
+
+	rc = vfe_dev->buf_mgr->ops->get_buf(
+		vfe_dev->buf_mgr, bufq_handle, &buf);
+	if (rc < 0) {
+		vfe_dev->error_info.
+			stream_framedrop_count[stream_idx]++;
+		return rc;
+	}
+
+	if (buf->num_planes != stream_info->num_planes) {
+		pr_err("%s: Invalid buffer\n", __func__);
+		rc = -EINVAL;
+		goto buf_error;
+	}
+
+	for (i = 0; i < stream_info->num_planes; i++)
+		vfe_dev->hw_info->vfe_ops.axi_ops.update_ping_pong_addr(
+		vfe_dev, stream_info->wm[i],
+		pingpong_status, buf->mapped_info[i].paddr);
+
+	pingpong_bit = (~(pingpong_status >> stream_info->wm[0]) & 0x1);
+	stream_info->buf[pingpong_bit] = buf;
+	return 0;
+buf_error:
+	vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr,
+		buf->bufq_handle, buf->buf_idx);
+	return rc;
+}
+
+static void msm_isp_process_done_buf(struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream *stream_info, struct msm_isp_buffer *buf,
+	struct msm_isp_timestamp *ts)
+{
+	struct msm_isp_event_data buf_event;
+	uint32_t stream_idx = stream_info->stream_handle & 0xFF;
+	uint32_t frame_id = vfe_dev->axi_data.
+		src_info[SRC_TO_INTF(stream_info->stream_src)].frame_id;
+
+	if (buf && ts) {
+		if (stream_info->buf_divert) {
+			vfe_dev->buf_mgr->ops->buf_divert(vfe_dev->buf_mgr,
+				buf->bufq_handle, buf->buf_idx,
+				&ts->buf_time, frame_id);
+			buf_event.frame_id = frame_id;
+			buf_event.timestamp = ts->buf_time;
+			buf_event.u.buf_done.session_id =
+				stream_info->session_id;
+			buf_event.u.buf_done.stream_id =
+				stream_info->stream_id;
+			buf_event.u.buf_done.handle =
+				stream_info->bufq_handle;
+			buf_event.u.buf_done.buf_idx = buf->buf_idx;
+			msm_isp_send_event(vfe_dev, ISP_EVENT_BUF_DIVERT +
+					stream_idx, &buf_event);
+		} else {
+			vfe_dev->buf_mgr->ops->buf_done(vfe_dev->buf_mgr,
+				buf->bufq_handle, buf->buf_idx,
+				&ts->buf_time, frame_id);
+		}
+	}
+}
+
+enum msm_isp_camif_update_state
+	msm_isp_update_camif_output_count(
+	struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd)
+{
+	int i;
+	struct msm_vfe_axi_stream *stream_info;
+	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
+	uint8_t cur_pix_count = axi_data->src_info[VFE_PIX_0].
+		pix_stream_count;
+	uint8_t cur_raw_count = axi_data->src_info[VFE_PIX_0].
+		raw_stream_count;
+	uint8_t pix_stream_cnt = 0;
+	for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
+		stream_info =
+			&axi_data->stream_info[
+			(stream_cfg_cmd->stream_handle[i] & 0xFF)];
+		if (stream_info->stream_src  < RDI_INTF_0)
+			pix_stream_cnt++;
+		if (stream_info->stream_src == PIX_ENCODER ||
+				stream_info->stream_src == PIX_VIEWFINDER) {
+			if (stream_cfg_cmd->cmd == START_STREAM)
+				vfe_dev->axi_data.src_info[VFE_PIX_0].
+					pix_stream_count++;
+			else
+				vfe_dev->axi_data.src_info[VFE_PIX_0].
+					pix_stream_count--;
+		} else if (stream_info->stream_src == CAMIF_RAW ||
+				stream_info->stream_src == IDEAL_RAW) {
+			if (stream_cfg_cmd->cmd == START_STREAM)
+				vfe_dev->axi_data.src_info[VFE_PIX_0].
+					raw_stream_count++;
+			else
+				vfe_dev->axi_data.src_info[VFE_PIX_0].
+					raw_stream_count--;
+		}
+	}
+	if (pix_stream_cnt) {
+		if ((cur_pix_count + cur_raw_count == 0) &&
+				(axi_data->src_info[VFE_PIX_0].
+				pix_stream_count +
+				axi_data->src_info[VFE_PIX_0].
+					raw_stream_count != 0)) {
+			return ENABLE_CAMIF;
+		}
+
+		if ((cur_pix_count + cur_raw_count != 0) &&
+				(axi_data->src_info[VFE_PIX_0].
+				pix_stream_count +
+				axi_data->src_info[VFE_PIX_0].
+					raw_stream_count == 0)) {
+			return DISABLE_CAMIF;
+		}
+	}
+
+	return NO_UPDATE;
+}
+
+void msm_camera_io_dump_2(void __iomem *addr, int size)
+{
+	char line_str[128], *p_str;
+	int i;
+	u32 *p = (u32 *) addr;
+	u32 data;
+	ISP_DBG("%s: %p %d\n", __func__, addr, size);
+	line_str[0] = '\0';
+	p_str = line_str;
+	for (i = 0; i < size/4; i++) {
+		if (i % 4 == 0) {
+			snprintf(p_str, 12, "%08x: ", (u32) p);
+			p_str += 10;
+		}
+		data = readl_relaxed(p++);
+		snprintf(p_str, 12, "%08x ", data);
+		p_str += 9;
+		if ((i + 1) % 4 == 0) {
+			ISP_DBG("%s\n", line_str);
+			line_str[0] = '\0';
+			p_str = line_str;
+		}
+	}
+	if (line_str[0] != '\0')
+		ISP_DBG("%s\n", line_str);
+}
+
+int msm_isp_cfg_axi_stream(struct vfe_device *vfe_dev, void *arg)
+{
+	int rc = 0, i;
+	struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd = arg;
+	uint32_t wm_reload_mask = 0x0;
+	struct msm_vfe_axi_stream *stream_info;
+	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
+	uint8_t src_state;
+	enum msm_isp_camif_update_state camif_update;
+	uint8_t wait_for_complete = 0;
+	rc = msm_isp_axi_check_stream_state(vfe_dev, stream_cfg_cmd);
+	if (rc < 0) {
+		pr_err("%s: Invalid stream state\n", __func__);
+		return rc;
+	}
+
+	if (axi_data->num_active_stream == 0) {
+		/*Configure UB*/
+		vfe_dev->hw_info->vfe_ops.axi_ops.cfg_ub(vfe_dev);
+	}
+
+	camif_update =
+		msm_isp_update_camif_output_count(vfe_dev, stream_cfg_cmd);
+
+	if (camif_update == DISABLE_CAMIF)
+		vfe_dev->hw_info->vfe_ops.core_ops.
+			update_camif_state(vfe_dev, DISABLE_CAMIF);
+
+	/*
+	* Stream start either immediately or at reg update
+	* Depends on whether the stream src is active
+	* If source is on, start and stop have to be done during reg update
+	* If source is off, start can happen immediately or during reg update
+	* stop has to be done immediately.
+	*/
+	for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
+		stream_info =
+			&axi_data->stream_info[
+				(stream_cfg_cmd->stream_handle[i] & 0xFF)];
+
+		if (stream_info->stream_src < RDI_INTF_0)
+			src_state = axi_data->src_info[0].active;
+		else
+			src_state = axi_data->src_info[
+			(stream_info->stream_src - RDI_INTF_0)].active;
+
+		stream_info->state = (stream_cfg_cmd->cmd == START_STREAM) ?
+			START_PENDING : STOP_PENDING;
+
+		if (stream_cfg_cmd->cmd == START_STREAM) {
+			/*Configure framedrop*/
+			msm_isp_reset_framedrop(vfe_dev, stream_info);
+
+			/*Set address for both PING & PONG register */
+			rc = msm_isp_cfg_ping_pong_address(vfe_dev,
+				stream_info, VFE_PONG_FLAG);
+			if (rc < 0) {
+				pr_err("%s: No buffer for start stream\n",
+					   __func__);
+				return rc;
+			}
+			/* For burst stream of one capture, only one buffer
+			 * is allocated. Duplicate ping buffer address to pong
+			 * buffer to ensure hardware write to a valid address
+			 */
+			if (stream_info->stream_type == BURST_STREAM &&
+				stream_info->num_burst_capture <= 1) {
+				msm_isp_cfg_pong_address(vfe_dev, stream_info);
+			} else {
+				rc = msm_isp_cfg_ping_pong_address(vfe_dev,
+					stream_info, VFE_PING_FLAG);
+			}
+		}
+		if (src_state && camif_update != DISABLE_CAMIF) {
+			/*On the fly stream start/stop */
+			wait_for_complete = 1;
+		} else {
+			if (vfe_dev->dump_reg &&
+				stream_cfg_cmd->cmd == START_STREAM)
+				msm_camera_io_dump_2(vfe_dev->vfe_base, 0x900);
+			/*Configure AXI start bits to start immediately*/
+			msm_isp_axi_stream_enable_cfg(
+				vfe_dev, stream_info, &wm_reload_mask);
+		}
+	}
+	if (!wait_for_complete) {
+		/*Reload AXI*/
+		if (stream_cfg_cmd->cmd == START_STREAM)
+			vfe_dev->hw_info->vfe_ops.axi_ops.
+			reload_wm(vfe_dev, wm_reload_mask);
+
+		vfe_dev->hw_info->vfe_ops.core_ops.
+			reg_update(vfe_dev);
+
+		if (camif_update == ENABLE_CAMIF)
+			vfe_dev->hw_info->vfe_ops.core_ops.
+				update_camif_state(vfe_dev, camif_update);
+	} else {
+		unsigned long flags;
+		spin_lock_irqsave(&vfe_dev->shared_data_lock, flags);
+		init_completion(&vfe_dev->stream_config_complete);
+		axi_data->stream_update = 1;
+		spin_unlock_irqrestore(&vfe_dev->shared_data_lock, flags);
+		/*Reload AXI*/
+		if (stream_cfg_cmd->cmd == START_STREAM)
+			vfe_dev->hw_info->vfe_ops.axi_ops.
+			reload_wm(vfe_dev, wm_reload_mask);
+		vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev);
+		rc = wait_for_completion_interruptible_timeout(
+			&vfe_dev->stream_config_complete,
+			msecs_to_jiffies(500));
+		if (rc == 0) {
+			pr_err("%s: wait timeout\n", __func__);
+			rc = -1;
+		} else {
+			rc = 0;
+		}
+	}
+	return rc;
+}
+
+int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg)
+{
+	int rc = 0;
+	struct msm_vfe_axi_stream *stream_info;
+	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
+	struct msm_vfe_axi_stream_update_cmd *update_cmd = arg;
+	stream_info = &axi_data->stream_info[
+			(update_cmd->stream_handle & 0xFF)];
+	if (stream_info->state != ACTIVE && stream_info->state != INACTIVE) {
+		pr_err("%s: Invalid stream state\n", __func__);
+		return -EINVAL;
+	}
+
+	switch (update_cmd->update_type) {
+	case ENABLE_STREAM_BUF_DIVERT:
+		stream_info->buf_divert = 1;
+		break;
+	case DISABLE_STREAM_BUF_DIVERT:
+		stream_info->buf_divert = 0;
+		vfe_dev->buf_mgr->ops->flush_buf(vfe_dev->buf_mgr,
+				stream_info->bufq_handle,
+				MSM_ISP_BUFFER_FLUSH_DIVERTED);
+		break;
+	case UPDATE_STREAM_FRAMEDROP_PATTERN: {
+		uint32_t framedrop_period =
+			msm_isp_get_framedrop_period(update_cmd->skip_pattern);
+		stream_info->runtime_init_frame_drop = 0;
+		stream_info->framedrop_pattern = 0x1;
+		stream_info->framedrop_period = framedrop_period - 1;
+		vfe_dev->hw_info->vfe_ops.axi_ops.
+			cfg_framedrop(vfe_dev, stream_info);
+		break;
+	}
+	default:
+		pr_err("%s: Invalid update type\n", __func__);
+		return -EINVAL;
+	}
+	return rc;
+}
+
+void msm_isp_process_axi_irq(struct vfe_device *vfe_dev,
+	uint32_t irq_status0, uint32_t irq_status1,
+	struct msm_isp_timestamp *ts)
+{
+	int i, rc = 0;
+	struct msm_isp_buffer *done_buf = NULL;
+	uint32_t comp_mask = 0, wm_mask = 0;
+	uint32_t pingpong_status, stream_idx;
+	struct msm_vfe_axi_stream *stream_info;
+	struct msm_vfe_axi_composite_info *comp_info;
+	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
+
+	comp_mask = vfe_dev->hw_info->vfe_ops.axi_ops.
+		get_comp_mask(irq_status0, irq_status1);
+	wm_mask = vfe_dev->hw_info->vfe_ops.axi_ops.
+		get_wm_mask(irq_status0, irq_status1);
+	if (!(comp_mask || wm_mask))
+		return;
+
+	ISP_DBG("%s: status: 0x%x\n", __func__, irq_status0);
+	pingpong_status =
+		vfe_dev->hw_info->vfe_ops.axi_ops.get_pingpong_status(vfe_dev);
+
+	for (i = 0; i < axi_data->hw_info->num_comp_mask; i++) {
+		comp_info = &axi_data->composite_info[i];
+		if (comp_mask & (1 << i)) {
+			if (!comp_info->stream_handle) {
+				pr_err("%s: Invalid handle for composite irq\n",
+					__func__);
+			} else {
+				stream_idx = comp_info->stream_handle & 0xFF;
+				stream_info =
+					&axi_data->stream_info[stream_idx];
+				ISP_DBG("%s: stream%d frame id: 0x%x\n",
+					__func__,
+					stream_idx, stream_info->frame_id);
+				stream_info->frame_id++;
+				msm_isp_get_done_buf(vfe_dev, stream_info,
+					pingpong_status, &done_buf);
+				if (stream_info->stream_type ==
+					CONTINUOUS_STREAM ||
+					stream_info->num_burst_capture > 1) {
+					rc = msm_isp_cfg_ping_pong_address(
+							vfe_dev, stream_info,
+							pingpong_status);
+				}
+				if (done_buf && !rc)
+					msm_isp_process_done_buf(vfe_dev,
+					stream_info, done_buf, ts);
+			}
+		}
+		wm_mask &= ~(comp_info->stream_composite_mask);
+	}
+
+	for (i = 0; i < axi_data->hw_info->num_wm; i++) {
+		if (wm_mask & (1 << i)) {
+			if (!axi_data->free_wm[i]) {
+				pr_err("%s: Invalid handle for wm irq\n",
+					__func__);
+				continue;
+			}
+			stream_idx = axi_data->free_wm[i] & 0xFF;
+			stream_info = &axi_data->stream_info[stream_idx];
+			ISP_DBG("%s: stream%d frame id: 0x%x\n",
+				__func__,
+				stream_idx, stream_info->frame_id);
+			stream_info->frame_id++;
+			msm_isp_get_done_buf(vfe_dev, stream_info,
+						pingpong_status, &done_buf);
+			if (stream_info->stream_type == CONTINUOUS_STREAM ||
+				stream_info->num_burst_capture > 1) {
+				rc = msm_isp_cfg_ping_pong_address(vfe_dev,
+					stream_info, pingpong_status);
+			}
+			if (done_buf && !rc)
+				msm_isp_process_done_buf(vfe_dev,
+				stream_info, done_buf, ts);
+		}
+	}
+	return;
+}
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h
new file mode 100644
index 0000000..ba845bc
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h
@@ -0,0 +1,61 @@
+/* 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 __MSM_ISP_AXI_UTIL_H__
+#define __MSM_ISP_AXI_UTIL_H__
+
+#include "msm_isp.h"
+
+int msm_isp_axi_create_stream(
+	struct msm_vfe_axi_shared_data *axi_data,
+	struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd);
+
+void msm_isp_axi_destroy_stream(
+	struct msm_vfe_axi_shared_data *axi_data, int stream_idx);
+
+int msm_isp_validate_axi_request(
+	struct msm_vfe_axi_shared_data *axi_data,
+	struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd);
+
+void msm_isp_axi_reserve_wm(
+	struct msm_vfe_axi_shared_data *axi_data,
+	struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd);
+
+void msm_isp_axi_reserve_rdi(
+	struct msm_vfe_axi_shared_data *axi_data,
+	struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd);
+
+void msm_isp_axi_reserve_comp_mask(
+	struct msm_vfe_axi_shared_data *axi_data,
+	struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd);
+
+int msm_isp_axi_check_stream_state(
+	struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd);
+
+int msm_isp_request_axi_stream(struct vfe_device *vfe_dev, void *arg);
+int msm_isp_cfg_axi_stream(struct vfe_device *vfe_dev, void *arg);
+int msm_isp_release_axi_stream(struct vfe_device *vfe_dev, void *arg);
+int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg);
+
+void msm_isp_axi_stream_enable_cfg(struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream *stream_info,
+	uint32_t *wm_reload_mask);
+
+void msm_isp_axi_stream_update(struct vfe_device *vfe_dev);
+
+void msm_isp_update_framedrop_reg(struct vfe_device *vfe_dev);
+void msm_isp_sof_notify(struct vfe_device *vfe_dev,
+	enum msm_vfe_input_src frame_src, struct msm_isp_timestamp *ts);
+void msm_isp_process_axi_irq(struct vfe_device *vfe_dev,
+	uint32_t irq_status0, uint32_t irq_status1,
+	struct msm_isp_timestamp *ts);
+#endif /* __MSM_ISP_AXI_UTIL_H__ */
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
new file mode 100644
index 0000000..a29fe9c
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
@@ -0,0 +1,352 @@
+/* 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/io.h>
+#include <media/v4l2-subdev.h>
+#include "msm_isp_util.h"
+#include "msm_isp_stats_util.h"
+
+static int msm_isp_stats_cfg_ping_pong_address(struct vfe_device *vfe_dev,
+	struct msm_vfe_stats_stream *stream_info, uint32_t pingpong_status,
+	struct msm_isp_buffer **done_buf)
+{
+	int rc = -1;
+	struct msm_isp_buffer *buf;
+	uint32_t pingpong_bit = 0;
+	uint32_t bufq_handle = stream_info->bufq_handle;
+	uint32_t stats_pingpong_offset =
+		STATS_IDX(stream_info->stream_handle) +
+		vfe_dev->hw_info->stats_hw_info->stats_ping_pong_offset;
+
+	pingpong_bit = (~(pingpong_status >> stats_pingpong_offset) & 0x1);
+	rc = vfe_dev->buf_mgr->ops->get_buf(
+		vfe_dev->buf_mgr, bufq_handle, &buf);
+	if (rc < 0) {
+		vfe_dev->error_info.stats_framedrop_count[
+			STATS_IDX(stream_info->stream_handle)]++;
+		return rc;
+	}
+
+	if (buf->num_planes != 1) {
+		pr_err("%s: Invalid buffer\n", __func__);
+		rc = -EINVAL;
+		goto buf_error;
+	}
+
+	vfe_dev->hw_info->vfe_ops.stats_ops.update_ping_pong_addr(
+		vfe_dev, stream_info,
+		pingpong_status, buf->mapped_info[0].paddr);
+
+	if (stream_info->buf[pingpong_bit] && done_buf)
+		*done_buf = stream_info->buf[pingpong_bit];
+
+	stream_info->buf[pingpong_bit] = buf;
+	return 0;
+buf_error:
+	vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr,
+		buf->bufq_handle, buf->buf_idx);
+	return rc;
+}
+
+void msm_isp_process_stats_irq(struct vfe_device *vfe_dev,
+	uint32_t irq_status0, uint32_t irq_status1,
+	struct msm_isp_timestamp *ts)
+{
+	int i;
+	struct msm_isp_event_data buf_event;
+	struct msm_isp_stats_event *stats_event = &buf_event.u.stats;
+	struct msm_isp_buffer *done_buf;
+	struct msm_vfe_stats_stream *stream_info = NULL;
+	uint32_t pingpong_status;
+	uint32_t stats_comp_mask = 0, stats_irq_mask = 0;
+	stats_comp_mask = vfe_dev->hw_info->vfe_ops.stats_ops.
+		get_comp_mask(irq_status0, irq_status1);
+	stats_irq_mask = vfe_dev->hw_info->vfe_ops.stats_ops.
+		get_wm_mask(irq_status0, irq_status1);
+	if (!(stats_comp_mask || stats_irq_mask))
+		return;
+	ISP_DBG("%s: status: 0x%x\n", __func__, irq_status0);
+
+	if (vfe_dev->stats_data.stats_pipeline_policy == STATS_COMP_ALL) {
+		if (!stats_comp_mask)
+			return;
+		stats_irq_mask = 0xFFFFFFFF;
+	}
+
+	memset(&buf_event, 0, sizeof(struct msm_isp_event_data));
+	pingpong_status = vfe_dev->hw_info->
+		vfe_ops.stats_ops.get_pingpong_status(vfe_dev);
+
+	for (i = 0; i < vfe_dev->hw_info->stats_hw_info->num_stats_type; i++) {
+		if (!(stats_irq_mask & (1 << i)))
+			continue;
+		stream_info = &vfe_dev->stats_data.stream_info[i];
+		done_buf = NULL;
+		msm_isp_stats_cfg_ping_pong_address(vfe_dev,
+			stream_info, pingpong_status, &done_buf);
+		if (done_buf) {
+			stats_event->stats_mask |= 1 << stream_info->stats_type;
+			stats_event->stats_buf_idxs[stream_info->stats_type] =
+				done_buf->buf_idx;
+			vfe_dev->buf_mgr->ops->buf_divert(vfe_dev->buf_mgr,
+				done_buf->bufq_handle, done_buf->buf_idx,
+				&ts->buf_time, vfe_dev->axi_data.
+				src_info[VFE_PIX_0].frame_id);
+		}
+	}
+
+	if (stats_event->stats_mask) {
+		buf_event.timestamp = ts->event_time;
+		buf_event.frame_id =
+			vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id;
+		msm_isp_send_event(vfe_dev, ISP_EVENT_STATS_NOTIFY +
+				stream_info->stats_type, &buf_event);
+	}
+}
+
+int msm_isp_stats_create_stream(struct vfe_device *vfe_dev,
+	struct msm_vfe_stats_stream_request_cmd *stream_req_cmd)
+{
+	int rc = -1;
+	struct msm_vfe_stats_stream *stream_info = NULL;
+	struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
+	uint32_t stats_idx;
+
+	if (!(vfe_dev->hw_info->stats_hw_info->stats_capability_mask &
+		(1 << stream_req_cmd->stats_type))) {
+		pr_err("%s: Stats type not supported\n", __func__);
+		return rc;
+	}
+
+	stats_idx = vfe_dev->hw_info->vfe_ops.stats_ops.
+		get_stats_idx(stream_req_cmd->stats_type);
+
+	stream_info = &stats_data->stream_info[stats_idx];
+	if (stream_info->state != STATS_AVALIABLE) {
+		pr_err("%s: Stats already requested\n", __func__);
+		return rc;
+	}
+
+	if (stats_data->stats_pipeline_policy != STATS_COMP_ALL) {
+		if (stream_req_cmd->framedrop_pattern >= MAX_SKIP) {
+			pr_err("%s: Invalid framedrop pattern\n", __func__);
+			return rc;
+		}
+
+		if (stream_req_cmd->irq_subsample_pattern >= MAX_SKIP) {
+			pr_err("%s: Invalid irq subsample pattern\n", __func__);
+			return rc;
+		}
+	} else {
+		if (stats_data->comp_framedrop_pattern >= MAX_SKIP) {
+			pr_err("%s: Invalid comp framedrop pattern\n",
+				__func__);
+			return rc;
+		}
+
+		if (stats_data->comp_irq_subsample_pattern >= MAX_SKIP) {
+			pr_err("%s: Invalid comp irq subsample pattern\n",
+				__func__);
+			return rc;
+		}
+		stream_req_cmd->framedrop_pattern =
+			vfe_dev->stats_data.comp_framedrop_pattern;
+		stream_req_cmd->irq_subsample_pattern =
+			vfe_dev->stats_data.comp_irq_subsample_pattern;
+	}
+
+	stream_info->session_id = stream_req_cmd->session_id;
+	stream_info->stream_id = stream_req_cmd->stream_id;
+	stream_info->stats_type = stream_req_cmd->stats_type;
+	stream_info->framedrop_pattern = stream_req_cmd->framedrop_pattern;
+	stream_info->irq_subsample_pattern =
+		stream_req_cmd->irq_subsample_pattern;
+	stream_info->state = STATS_INACTIVE;
+
+	if ((vfe_dev->stats_data.stream_handle_cnt << 8) == 0)
+		vfe_dev->stats_data.stream_handle_cnt++;
+
+	stream_req_cmd->stream_handle =
+		(++vfe_dev->stats_data.stream_handle_cnt) << 8 | stats_idx;
+
+	stream_info->stream_handle = stream_req_cmd->stream_handle;
+	return 0;
+}
+
+int msm_isp_request_stats_stream(struct vfe_device *vfe_dev, void *arg)
+{
+	int rc = 0;
+	struct msm_vfe_stats_stream_request_cmd *stream_req_cmd = arg;
+	struct msm_vfe_stats_stream *stream_info = NULL;
+	struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
+	uint32_t stats_idx;
+
+	rc = msm_isp_stats_create_stream(vfe_dev, stream_req_cmd);
+	if (rc < 0) {
+		pr_err("%s: create stream failed\n", __func__);
+		return rc;
+	}
+
+	stats_idx = STATS_IDX(stream_req_cmd->stream_handle);
+	stream_info = &stats_data->stream_info[stats_idx];
+
+	switch (stream_info->framedrop_pattern) {
+	case NO_SKIP:
+		stream_info->framedrop_pattern = VFE_NO_DROP;
+		break;
+	case EVERY_2FRAME:
+		stream_info->framedrop_pattern = VFE_DROP_EVERY_2FRAME;
+		break;
+	case EVERY_4FRAME:
+		stream_info->framedrop_pattern = VFE_DROP_EVERY_4FRAME;
+		break;
+	case EVERY_8FRAME:
+		stream_info->framedrop_pattern = VFE_DROP_EVERY_8FRAME;
+		break;
+	case EVERY_16FRAME:
+		stream_info->framedrop_pattern = VFE_DROP_EVERY_16FRAME;
+		break;
+	case EVERY_32FRAME:
+		stream_info->framedrop_pattern = VFE_DROP_EVERY_32FRAME;
+		break;
+	default:
+		stream_info->framedrop_pattern = VFE_NO_DROP;
+		break;
+	}
+
+	if (stats_data->stats_pipeline_policy == STATS_COMP_NONE)
+		vfe_dev->hw_info->vfe_ops.stats_ops.
+			cfg_wm_irq_mask(vfe_dev, stream_info);
+
+	vfe_dev->hw_info->vfe_ops.stats_ops.cfg_wm_reg(vfe_dev, stream_info);
+	return rc;
+}
+
+int msm_isp_release_stats_stream(struct vfe_device *vfe_dev, void *arg)
+{
+	int rc = -1;
+	struct msm_vfe_stats_stream_cfg_cmd stream_cfg_cmd;
+	struct msm_vfe_stats_stream_release_cmd *stream_release_cmd = arg;
+	struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
+	int stats_idx = STATS_IDX(stream_release_cmd->stream_handle);
+	struct msm_vfe_stats_stream *stream_info =
+		&stats_data->stream_info[stats_idx];
+
+	if (stream_info->state == STATS_AVALIABLE) {
+		pr_err("%s: stream already release\n", __func__);
+		return rc;
+	} else if (stream_info->state != STATS_INACTIVE) {
+		stream_cfg_cmd.enable = 0;
+		stream_cfg_cmd.num_streams = 1;
+		stream_cfg_cmd.stream_handle[0] =
+			stream_release_cmd->stream_handle;
+		rc = msm_isp_cfg_stats_stream(vfe_dev, &stream_cfg_cmd);
+	}
+
+	if (stats_data->stats_pipeline_policy == STATS_COMP_NONE)
+		vfe_dev->hw_info->vfe_ops.stats_ops.
+			clear_wm_irq_mask(vfe_dev, stream_info);
+
+	vfe_dev->hw_info->vfe_ops.stats_ops.clear_wm_reg(vfe_dev, stream_info);
+	memset(stream_info, 0, sizeof(struct msm_vfe_stats_stream));
+	return 0;
+}
+
+int msm_isp_cfg_stats_stream(struct vfe_device *vfe_dev, void *arg)
+{
+	int i, rc = 0;
+	struct msm_vfe_stats_stream_cfg_cmd *stream_cfg_cmd = arg;
+	struct msm_vfe_stats_stream *stream_info;
+	struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
+	int idx;
+	uint32_t stats_mask = 0;
+
+	if (stats_data->num_active_stream == 0)
+		vfe_dev->hw_info->vfe_ops.stats_ops.cfg_ub(vfe_dev);
+
+	for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
+		idx = STATS_IDX(stream_cfg_cmd->stream_handle[i]);
+		stream_info = &stats_data->stream_info[idx];
+		if (stream_info->stream_handle !=
+				stream_cfg_cmd->stream_handle[i]) {
+			pr_err("%s: Invalid stream handle: 0x%x received\n",
+				__func__, stream_cfg_cmd->stream_handle[i]);
+			continue;
+		}
+
+		if (stream_cfg_cmd->enable) {
+			stream_info->bufq_handle =
+				vfe_dev->buf_mgr->ops->get_bufq_handle(
+				vfe_dev->buf_mgr, stream_info->session_id,
+				stream_info->stream_id);
+				if (stream_info->bufq_handle == 0) {
+					pr_err("%s: no buf configured for stream: 0x%x\n",
+						__func__,
+						stream_info->stream_handle);
+					return -EINVAL;
+				}
+
+			msm_isp_stats_cfg_ping_pong_address(vfe_dev,
+				stream_info, VFE_PING_FLAG, NULL);
+			msm_isp_stats_cfg_ping_pong_address(vfe_dev,
+				stream_info, VFE_PONG_FLAG, NULL);
+			stream_info->state = STATS_START_PENDING;
+			stats_data->num_active_stream++;
+		} else {
+			stream_info->state = STATS_STOP_PENDING;
+			stats_data->num_active_stream--;
+		}
+		stats_mask |= 1 << idx;
+	}
+	vfe_dev->hw_info->vfe_ops.stats_ops.
+		enable_module(vfe_dev, stats_mask, stream_cfg_cmd->enable);
+	return rc;
+}
+
+int msm_isp_cfg_stats_comp_policy(struct vfe_device *vfe_dev, void *arg)
+{
+	int rc = -1;
+	struct msm_vfe_stats_comp_policy_cfg *policy_cfg_cmd = arg;
+	struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
+
+	if (stats_data->num_active_stream != 0) {
+		pr_err("%s: Cannot update policy when there are active streams\n",
+			   __func__);
+		return rc;
+	}
+
+	if (policy_cfg_cmd->stats_pipeline_policy >= MAX_STATS_POLICY) {
+		pr_err("%s: Invalid stats composite policy\n", __func__);
+		return rc;
+	}
+
+	if (policy_cfg_cmd->comp_framedrop_pattern >= MAX_SKIP) {
+		pr_err("%s: Invalid comp framedrop pattern\n", __func__);
+		return rc;
+	}
+
+	if (policy_cfg_cmd->comp_irq_subsample_pattern >= MAX_SKIP) {
+		pr_err("%s: Invalid comp irq subsample pattern\n", __func__);
+		return rc;
+	}
+
+	stats_data->stats_pipeline_policy =
+		policy_cfg_cmd->stats_pipeline_policy;
+	stats_data->comp_framedrop_pattern =
+		policy_cfg_cmd->comp_framedrop_pattern;
+	stats_data->comp_irq_subsample_pattern =
+		policy_cfg_cmd->comp_irq_subsample_pattern;
+
+	vfe_dev->hw_info->vfe_ops.stats_ops.cfg_comp_mask(vfe_dev);
+
+	return 0;
+}
+
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.h
new file mode 100644
index 0000000..13e1fd6
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.h
@@ -0,0 +1,25 @@
+/* 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 __MSM_ISP_STATS_UTIL_H__
+#define __MSM_ISP_STATS_UTIL_H__
+
+#include "msm_isp.h"
+#define STATS_IDX(idx) (idx & 0xFF)
+
+void msm_isp_process_stats_irq(struct vfe_device *vfe_dev,
+	uint32_t irq_status0, uint32_t irq_status1,
+	struct msm_isp_timestamp *ts);
+int msm_isp_cfg_stats_stream(struct vfe_device *vfe_dev, void *arg);
+int msm_isp_release_stats_stream(struct vfe_device *vfe_dev, void *arg);
+int msm_isp_request_stats_stream(struct vfe_device *vfe_dev, void *arg);
+int msm_isp_cfg_stats_comp_policy(struct vfe_device *vfe_dev, void *arg);
+#endif /* __MSM_ISP_STATS_UTIL_H__ */
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
new file mode 100644
index 0000000..bbdfaa6
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -0,0 +1,688 @@
+/* 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/io.h>
+#include <media/v4l2-subdev.h>
+
+#include "msm.h"
+#include "msm_isp_util.h"
+#include "msm_isp_axi_util.h"
+#include "msm_isp_stats_util.h"
+#include "msm_camera_io_util.h"
+
+#define MAX_ISP_V4l2_EVENTS 100
+
+static inline void msm_isp_get_timestamp(struct msm_isp_timestamp *time_stamp)
+{
+	struct timespec ts;
+	ktime_get_ts(&ts);
+	time_stamp->buf_time.tv_sec = ts.tv_sec;
+	time_stamp->buf_time.tv_usec = ts.tv_nsec/1000;
+	do_gettimeofday(&(time_stamp->event_time));
+}
+
+int msm_isp_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+	struct v4l2_event_subscription *sub)
+{
+	struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd);
+	int rc = 0;
+	rc = v4l2_event_subscribe(fh, sub, MAX_ISP_V4l2_EVENTS);
+	if (rc == 0) {
+		if (sub->type == V4L2_EVENT_ALL) {
+			int i;
+
+			vfe_dev->axi_data.event_mask = 0;
+			for (i = 0; i < ISP_EVENT_MAX; i++)
+				vfe_dev->axi_data.event_mask |= (1 << i);
+		} else {
+			int event_idx = sub->type - ISP_EVENT_BASE;
+
+			vfe_dev->axi_data.event_mask |= (1 << event_idx);
+		}
+	}
+	return rc;
+}
+
+int msm_isp_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+	struct v4l2_event_subscription *sub)
+{
+	struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd);
+	int rc = 0;
+
+	rc = v4l2_event_unsubscribe(fh, sub);
+	if (sub->type == V4L2_EVENT_ALL) {
+		vfe_dev->axi_data.event_mask = 0;
+	} else {
+		int event_idx = sub->type - ISP_EVENT_BASE;
+
+		vfe_dev->axi_data.event_mask &= ~(1 << event_idx);
+	}
+	return rc;
+}
+
+int msm_isp_cfg_pix(struct vfe_device *vfe_dev,
+	struct msm_vfe_pix_cfg *pix_cfg)
+{
+	int rc = 0;
+	/*TD Validate config info
+	 * should check if all streams are off */
+
+	vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux = pix_cfg->input_mux;
+
+	vfe_dev->hw_info->vfe_ops.core_ops.cfg_camif(vfe_dev, pix_cfg);
+	return rc;
+}
+
+int msm_isp_cfg_rdi(struct vfe_device *vfe_dev,
+	struct msm_vfe_rdi_cfg *rdi_cfg, enum msm_vfe_input_src input_src)
+{
+	int rc = 0;
+	/*TD Validate config info
+	 * should check if all streams are off */
+
+	vfe_dev->hw_info->vfe_ops.core_ops.
+		cfg_rdi_reg(vfe_dev, rdi_cfg, input_src);
+	return rc;
+}
+
+int msm_isp_cfg_input(struct vfe_device *vfe_dev, void *arg)
+{
+	int rc = 0;
+	struct msm_vfe_input_cfg *input_cfg = arg;
+
+	switch (input_cfg->input_src) {
+	case VFE_PIX_0:
+		msm_isp_cfg_pix(vfe_dev, &input_cfg->d.pix_cfg);
+		break;
+	case VFE_RAW_0:
+	case VFE_RAW_1:
+	case VFE_RAW_2:
+		msm_isp_cfg_rdi(vfe_dev, &input_cfg->d.rdi_cfg,
+						input_cfg->input_src);
+		break;
+	case VFE_SRC_MAX:
+		break;
+	}
+	return rc;
+}
+
+long msm_isp_ioctl(struct v4l2_subdev *sd,
+	unsigned int cmd, void *arg)
+{
+	long rc = 0;
+	struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd);
+
+	mutex_lock(&vfe_dev->mutex);
+	ISP_DBG("%s cmd: %d\n", __func__, cmd);
+	switch (cmd) {
+	case VIDIOC_MSM_VFE_REG_CFG: {
+		rc = msm_isp_proc_cmd(vfe_dev, arg);
+		break;
+	}
+	case VIDIOC_MSM_ISP_REQUEST_BUF:
+	case VIDIOC_MSM_ISP_ENQUEUE_BUF:
+	case VIDIOC_MSM_ISP_RELEASE_BUF: {
+		rc = msm_isp_proc_buf_cmd(vfe_dev->buf_mgr, cmd, arg);
+		break;
+	}
+	case VIDIOC_MSM_ISP_REQUEST_STREAM:
+		rc = msm_isp_request_axi_stream(vfe_dev, arg);
+		break;
+	case VIDIOC_MSM_ISP_RELEASE_STREAM:
+		rc = msm_isp_release_axi_stream(vfe_dev, arg);
+		break;
+	case VIDIOC_MSM_ISP_CFG_STREAM:
+		rc = msm_isp_cfg_axi_stream(vfe_dev, arg);
+		break;
+	case VIDIOC_MSM_ISP_INPUT_CFG:
+		rc = msm_isp_cfg_input(vfe_dev, arg);
+		break;
+	case VIDIOC_MSM_ISP_SET_SRC_STATE:
+		msm_isp_set_src_state(vfe_dev, arg);
+		break;
+	case VIDIOC_MSM_ISP_REQUEST_STATS_STREAM:
+		rc = msm_isp_request_stats_stream(vfe_dev, arg);
+		break;
+	case VIDIOC_MSM_ISP_RELEASE_STATS_STREAM:
+		rc = msm_isp_release_stats_stream(vfe_dev, arg);
+		break;
+	case VIDIOC_MSM_ISP_CFG_STATS_STREAM:
+		rc = msm_isp_cfg_stats_stream(vfe_dev, arg);
+		break;
+	case VIDIOC_MSM_ISP_CFG_STATS_COMP_POLICY:
+		rc = msm_isp_cfg_stats_comp_policy(vfe_dev, arg);
+		break;
+	case VIDIOC_MSM_ISP_UPDATE_STREAM:
+		rc = msm_isp_update_axi_stream(vfe_dev, arg);
+		break;
+	default:
+		pr_err("%s: Invalid ISP command\n", __func__);
+		rc = -EINVAL;
+	}
+
+	mutex_unlock(&vfe_dev->mutex);
+	return rc;
+}
+
+static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
+	struct msm_vfe_reg_cfg_cmd *reg_cfg_cmd,
+	uint32_t *cfg_data, uint32_t cmd_len)
+{
+	switch (reg_cfg_cmd->cmd_type) {
+	case VFE_WRITE: {
+		if (resource_size(vfe_dev->vfe_mem) <
+			(reg_cfg_cmd->u.rw_info.reg_offset +
+			reg_cfg_cmd->u.rw_info.len)) {
+			pr_err("%s: Invalid length\n", __func__);
+			return -EINVAL;
+		}
+		msm_camera_io_memcpy(vfe_dev->vfe_base +
+			reg_cfg_cmd->u.rw_info.reg_offset,
+			cfg_data + reg_cfg_cmd->u.rw_info.cmd_data_offset/4,
+			reg_cfg_cmd->u.rw_info.len);
+		break;
+	}
+	case VFE_WRITE_MB: {
+		uint32_t *data_ptr = cfg_data +
+			reg_cfg_cmd->u.rw_info.cmd_data_offset/4;
+		msm_camera_io_w_mb(*data_ptr, vfe_dev->vfe_base +
+			reg_cfg_cmd->u.rw_info.reg_offset);
+		break;
+	}
+	case VFE_CFG_MASK: {
+		uint32_t temp;
+		temp = msm_camera_io_r(vfe_dev->vfe_base +
+			reg_cfg_cmd->u.mask_info.reg_offset);
+		temp &= ~reg_cfg_cmd->u.mask_info.mask;
+		temp |= reg_cfg_cmd->u.mask_info.val;
+		msm_camera_io_w(temp, vfe_dev->vfe_base +
+			reg_cfg_cmd->u.mask_info.reg_offset);
+		break;
+	}
+	case VFE_WRITE_DMI_16BIT:
+	case VFE_WRITE_DMI_32BIT:
+	case VFE_WRITE_DMI_64BIT: {
+		int i;
+		uint32_t *hi_tbl_ptr = NULL, *lo_tbl_ptr = NULL;
+		uint32_t hi_val, lo_val, lo_val1;
+		if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT) {
+			if (reg_cfg_cmd->u.dmi_info.hi_tbl_offset +
+				reg_cfg_cmd->u.dmi_info.len > cmd_len) {
+				pr_err("Invalid Hi Table out of bounds\n");
+				return -EINVAL;
+			}
+			hi_tbl_ptr = cfg_data +
+				reg_cfg_cmd->u.dmi_info.hi_tbl_offset/4;
+		}
+
+		if (reg_cfg_cmd->u.dmi_info.lo_tbl_offset +
+			reg_cfg_cmd->u.dmi_info.len > cmd_len) {
+			pr_err("Invalid Lo Table out of bounds\n");
+			return -EINVAL;
+		}
+		lo_tbl_ptr = cfg_data +
+			reg_cfg_cmd->u.dmi_info.lo_tbl_offset/4;
+
+		for (i = 0; i < reg_cfg_cmd->u.dmi_info.len/4; i++) {
+			lo_val = *lo_tbl_ptr++;
+			if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_16BIT) {
+				lo_val1 = lo_val & 0x0000FFFF;
+				lo_val = (lo_val & 0xFFFF0000)>>16;
+				msm_camera_io_w(lo_val1, vfe_dev->vfe_base +
+					vfe_dev->hw_info->dmi_reg_offset + 0x4);
+			} else if (reg_cfg_cmd->cmd_type ==
+					VFE_WRITE_DMI_64BIT) {
+				hi_val = *hi_tbl_ptr++;
+				msm_camera_io_w(hi_val, vfe_dev->vfe_base +
+					   vfe_dev->hw_info->dmi_reg_offset);
+			}
+			msm_camera_io_w(lo_val, vfe_dev->vfe_base +
+					vfe_dev->hw_info->dmi_reg_offset + 0x4);
+		}
+		break;
+	}
+	case VFE_READ_DMI_16BIT:
+	case VFE_READ_DMI_32BIT:
+	case VFE_READ_DMI_64BIT: {
+		int i;
+		uint32_t *hi_tbl_ptr = NULL, *lo_tbl_ptr = NULL;
+		uint32_t hi_val, lo_val, lo_val1;
+		if (reg_cfg_cmd->cmd_type == VFE_READ_DMI_64BIT) {
+			if (reg_cfg_cmd->u.dmi_info.hi_tbl_offset +
+				reg_cfg_cmd->u.dmi_info.len > cmd_len) {
+				pr_err("Invalid Hi Table out of bounds\n");
+				return -EINVAL;
+			}
+			hi_tbl_ptr = cfg_data +
+				reg_cfg_cmd->u.dmi_info.hi_tbl_offset/4;
+		}
+
+		if (reg_cfg_cmd->u.dmi_info.lo_tbl_offset +
+			reg_cfg_cmd->u.dmi_info.len > cmd_len) {
+			pr_err("Invalid Lo Table out of bounds\n");
+			return -EINVAL;
+		}
+		lo_tbl_ptr = cfg_data +
+			reg_cfg_cmd->u.dmi_info.lo_tbl_offset/4;
+
+		for (i = 0; i < reg_cfg_cmd->u.dmi_info.len/4; i++) {
+			if (reg_cfg_cmd->cmd_type == VFE_READ_DMI_64BIT) {
+				hi_val = msm_camera_io_r(vfe_dev->vfe_base +
+					vfe_dev->hw_info->dmi_reg_offset);
+				*hi_tbl_ptr++ = hi_val;
+			}
+
+			lo_val = msm_camera_io_r(vfe_dev->vfe_base +
+					vfe_dev->hw_info->dmi_reg_offset + 0x4);
+
+			if (reg_cfg_cmd->cmd_type == VFE_READ_DMI_16BIT) {
+				lo_val1 = msm_camera_io_r(vfe_dev->vfe_base +
+					vfe_dev->hw_info->dmi_reg_offset + 0x4);
+				lo_val |= lo_val1 << 16;
+			}
+			*lo_tbl_ptr++ = lo_val;
+		}
+		break;
+	}
+	case VFE_READ: {
+		int i;
+		uint32_t *data_ptr = cfg_data +
+			reg_cfg_cmd->u.rw_info.cmd_data_offset/4;
+		for (i = 0; i < reg_cfg_cmd->u.rw_info.len/4; i++)
+			*data_ptr++ = msm_camera_io_r(vfe_dev->vfe_base +
+				reg_cfg_cmd->u.rw_info.reg_offset++);
+		break;
+	}
+	}
+	return 0;
+}
+
+int msm_isp_proc_cmd(struct vfe_device *vfe_dev, void *arg)
+{
+	int rc = 0, i;
+	struct msm_vfe_cfg_cmd2 *proc_cmd = arg;
+	struct msm_vfe_reg_cfg_cmd *reg_cfg_cmd;
+	uint32_t *cfg_data;
+
+	reg_cfg_cmd = kzalloc(sizeof(struct msm_vfe_reg_cfg_cmd)*
+		proc_cmd->num_cfg, GFP_KERNEL);
+	if (!reg_cfg_cmd) {
+		pr_err("%s: reg_cfg alloc failed\n", __func__);
+		rc = -ENOMEM;
+		goto reg_cfg_failed;
+	}
+
+	cfg_data = kzalloc(proc_cmd->cmd_len, GFP_KERNEL);
+	if (!cfg_data) {
+		pr_err("%s: cfg_data alloc failed\n", __func__);
+		rc = -ENOMEM;
+		goto cfg_data_failed;
+	}
+
+	if (copy_from_user(reg_cfg_cmd,
+		(void __user *)(proc_cmd->cfg_cmd),
+		sizeof(struct msm_vfe_reg_cfg_cmd) * proc_cmd->num_cfg)) {
+		rc = -EFAULT;
+		goto copy_cmd_failed;
+	}
+
+	if (copy_from_user(cfg_data,
+			(void __user *)(proc_cmd->cfg_data),
+			proc_cmd->cmd_len)) {
+		rc = -EFAULT;
+		goto copy_cmd_failed;
+	}
+
+	for (i = 0; i < proc_cmd->num_cfg; i++)
+		msm_isp_send_hw_cmd(vfe_dev, &reg_cfg_cmd[i],
+			cfg_data, proc_cmd->cmd_len);
+
+	if (copy_to_user(proc_cmd->cfg_data,
+			cfg_data, proc_cmd->cmd_len)) {
+		rc = -EFAULT;
+		goto copy_cmd_failed;
+	}
+
+copy_cmd_failed:
+	kfree(cfg_data);
+cfg_data_failed:
+	kfree(reg_cfg_cmd);
+reg_cfg_failed:
+	return rc;
+}
+
+int msm_isp_send_event(struct vfe_device *vfe_dev,
+	uint32_t event_type,
+	struct msm_isp_event_data *event_data)
+{
+	struct v4l2_event isp_event;
+	memset(&isp_event, 0, sizeof(struct v4l2_event));
+	isp_event.id = 0;
+	isp_event.type = event_type;
+	memcpy(&isp_event.u.data[0], event_data,
+		sizeof(struct msm_isp_event_data));
+	v4l2_event_queue(vfe_dev->subdev.sd.devnode, &isp_event);
+	return 0;
+}
+
+#define CAL_WORD(width, M, N) ((width * M + N - 1) / N)
+
+int msm_isp_cal_word_per_line(uint32_t output_format,
+	uint32_t pixel_per_line)
+{
+	int val = -1;
+	switch (output_format) {
+	case V4L2_PIX_FMT_SBGGR8:
+	case V4L2_PIX_FMT_SGBRG8:
+	case V4L2_PIX_FMT_SGRBG8:
+	case V4L2_PIX_FMT_SRGGB8:
+	case V4L2_PIX_FMT_QBGGR8:
+	case V4L2_PIX_FMT_QGBRG8:
+	case V4L2_PIX_FMT_QGRBG8:
+	case V4L2_PIX_FMT_QRGGB8:
+		val = CAL_WORD(pixel_per_line, 1, 8);
+		break;
+	case V4L2_PIX_FMT_SBGGR10:
+	case V4L2_PIX_FMT_SGBRG10:
+	case V4L2_PIX_FMT_SGRBG10:
+	case V4L2_PIX_FMT_SRGGB10:
+		val = CAL_WORD(pixel_per_line, 5, 32);
+		break;
+	case V4L2_PIX_FMT_SBGGR12:
+	case V4L2_PIX_FMT_SGBRG12:
+	case V4L2_PIX_FMT_SGRBG12:
+	case V4L2_PIX_FMT_SRGGB12:
+		val = CAL_WORD(pixel_per_line, 3, 16);
+		break;
+	case V4L2_PIX_FMT_QBGGR10:
+	case V4L2_PIX_FMT_QGBRG10:
+	case V4L2_PIX_FMT_QGRBG10:
+	case V4L2_PIX_FMT_QRGGB10:
+		val = CAL_WORD(pixel_per_line, 1, 6);
+		break;
+	case V4L2_PIX_FMT_QBGGR12:
+	case V4L2_PIX_FMT_QGBRG12:
+	case V4L2_PIX_FMT_QGRBG12:
+	case V4L2_PIX_FMT_QRGGB12:
+		val = CAL_WORD(pixel_per_line, 1, 5);
+		break;
+	case V4L2_PIX_FMT_NV12:
+	case V4L2_PIX_FMT_NV21:
+		val = CAL_WORD(pixel_per_line, 1, 8);
+		break;
+		/*TD: Add more image format*/
+	default:
+		pr_err("%s: Invalid output format\n", __func__);
+		break;
+	}
+	return val;
+}
+
+int msm_isp_get_bit_per_pixel(uint32_t output_format)
+{
+	switch (output_format) {
+	case V4L2_PIX_FMT_SBGGR8:
+	case V4L2_PIX_FMT_SGBRG8:
+	case V4L2_PIX_FMT_SGRBG8:
+	case V4L2_PIX_FMT_SRGGB8:
+	case V4L2_PIX_FMT_QBGGR8:
+	case V4L2_PIX_FMT_QGBRG8:
+	case V4L2_PIX_FMT_QGRBG8:
+	case V4L2_PIX_FMT_QRGGB8:
+		return 8;
+	case V4L2_PIX_FMT_SBGGR10:
+	case V4L2_PIX_FMT_SGBRG10:
+	case V4L2_PIX_FMT_SGRBG10:
+	case V4L2_PIX_FMT_SRGGB10:
+	case V4L2_PIX_FMT_QBGGR10:
+	case V4L2_PIX_FMT_QGBRG10:
+	case V4L2_PIX_FMT_QGRBG10:
+	case V4L2_PIX_FMT_QRGGB10:
+		return 10;
+	case V4L2_PIX_FMT_SBGGR12:
+	case V4L2_PIX_FMT_SGBRG12:
+	case V4L2_PIX_FMT_SGRBG12:
+	case V4L2_PIX_FMT_SRGGB12:
+	case V4L2_PIX_FMT_QBGGR12:
+	case V4L2_PIX_FMT_QGBRG12:
+	case V4L2_PIX_FMT_QGRBG12:
+	case V4L2_PIX_FMT_QRGGB12:
+		return 12;
+	case V4L2_PIX_FMT_NV12:
+	case V4L2_PIX_FMT_NV21:
+		return 8;
+		/*TD: Add more image format*/
+	default:
+		pr_err("%s: Invalid output format\n", __func__);
+		break;
+	}
+	return -EINVAL;
+}
+
+void msm_isp_update_error_frame_count(struct vfe_device *vfe_dev)
+{
+	struct msm_vfe_error_info *error_info = &vfe_dev->error_info;
+	error_info->info_dump_frame_count++;
+	if (error_info->info_dump_frame_count == 0)
+		error_info->info_dump_frame_count++;
+}
+
+void msm_isp_process_error_info(struct vfe_device *vfe_dev)
+{
+	int i;
+	struct msm_vfe_error_info *error_info = &vfe_dev->error_info;
+	if (error_info->error_count == 1 ||
+		!(error_info->info_dump_frame_count % 100)) {
+		vfe_dev->hw_info->vfe_ops.core_ops.
+			process_error_status(vfe_dev);
+		error_info->error_mask0 = 0;
+		error_info->error_mask1 = 0;
+		error_info->camif_status = 0;
+		error_info->violation_status = 0;
+		for (i = 0; i < MAX_NUM_STREAM; i++) {
+			if (error_info->stream_framedrop_count[i] != 0) {
+				pr_err("%s: Stream[%d]: dropped %d frames\n",
+					__func__, i,
+					error_info->stream_framedrop_count[i]);
+				error_info->stream_framedrop_count[i] = 0;
+			}
+		}
+		for (i = 0; i < MSM_ISP_STATS_MAX; i++) {
+			if (error_info->stats_framedrop_count[i] != 0) {
+				pr_err("%s: Stats stream[%d]: dropped %d frames\n",
+					__func__, i,
+					error_info->stats_framedrop_count[i]);
+				error_info->stats_framedrop_count[i] = 0;
+			}
+		}
+	}
+}
+
+static inline void msm_isp_update_error_info(struct vfe_device *vfe_dev,
+	uint32_t error_mask0, uint32_t error_mask1)
+{
+	vfe_dev->error_info.error_mask0 |= error_mask0;
+	vfe_dev->error_info.error_mask1 |= error_mask1;
+	vfe_dev->error_info.error_count++;
+}
+
+irqreturn_t msm_isp_process_irq(int irq_num, void *data)
+{
+	unsigned long flags;
+	struct msm_vfe_tasklet_queue_cmd *queue_cmd;
+	struct vfe_device *vfe_dev = (struct vfe_device *) data;
+	uint32_t irq_status0, irq_status1;
+	uint32_t error_mask0, error_mask1;
+
+	vfe_dev->hw_info->vfe_ops.irq_ops.
+		read_irq_status(vfe_dev, &irq_status0, &irq_status1);
+	vfe_dev->hw_info->vfe_ops.core_ops.
+		get_error_mask(&error_mask0, &error_mask1);
+	error_mask0 &= irq_status0;
+	error_mask1 &= irq_status1;
+	irq_status0 &= ~error_mask0;
+	irq_status1 &= ~error_mask1;
+	if ((error_mask0 != 0) || (error_mask1 != 0))
+		msm_isp_update_error_info(vfe_dev, error_mask0, error_mask1);
+
+	if ((irq_status0 == 0) && (irq_status1 == 0) &&
+		(!((error_mask0 != 0) || (error_mask1 != 0)) &&
+		 vfe_dev->error_info.error_count == 1)) {
+		ISP_DBG("%s: irq_status0 & 1 are both 0!\n", __func__);
+		return IRQ_HANDLED;
+	}
+
+	spin_lock_irqsave(&vfe_dev->tasklet_lock, flags);
+	queue_cmd = &vfe_dev->tasklet_queue_cmd[vfe_dev->taskletq_idx];
+	if (queue_cmd->cmd_used) {
+		pr_err("%s: Tasklet queue overflow\n", __func__);
+		list_del(&queue_cmd->list);
+	} else {
+		atomic_add(1, &vfe_dev->irq_cnt);
+	}
+	queue_cmd->vfeInterruptStatus0 = irq_status0;
+	queue_cmd->vfeInterruptStatus1 = irq_status1;
+	msm_isp_get_timestamp(&queue_cmd->ts);
+	queue_cmd->cmd_used = 1;
+	vfe_dev->taskletq_idx =
+		(vfe_dev->taskletq_idx + 1) % MSM_VFE_TASKLETQ_SIZE;
+	list_add_tail(&queue_cmd->list, &vfe_dev->tasklet_q);
+	spin_unlock_irqrestore(&vfe_dev->tasklet_lock, flags);
+	tasklet_schedule(&vfe_dev->vfe_tasklet);
+	return IRQ_HANDLED;
+}
+
+void msm_isp_do_tasklet(unsigned long data)
+{
+	unsigned long flags;
+	struct vfe_device *vfe_dev = (struct vfe_device *) data;
+	struct msm_vfe_irq_ops *irq_ops = &vfe_dev->hw_info->vfe_ops.irq_ops;
+	struct msm_vfe_tasklet_queue_cmd *queue_cmd;
+	struct msm_isp_timestamp ts;
+	uint32_t irq_status0, irq_status1;
+	while (atomic_read(&vfe_dev->irq_cnt)) {
+		spin_lock_irqsave(&vfe_dev->tasklet_lock, flags);
+		queue_cmd = list_first_entry(&vfe_dev->tasklet_q,
+		struct msm_vfe_tasklet_queue_cmd, list);
+		if (!queue_cmd) {
+			atomic_set(&vfe_dev->irq_cnt, 0);
+			spin_unlock_irqrestore(&vfe_dev->tasklet_lock, flags);
+			return;
+		}
+		atomic_sub(1, &vfe_dev->irq_cnt);
+		list_del(&queue_cmd->list);
+		queue_cmd->cmd_used = 0;
+		irq_status0 = queue_cmd->vfeInterruptStatus0;
+		irq_status1 = queue_cmd->vfeInterruptStatus1;
+		ts = queue_cmd->ts;
+		spin_unlock_irqrestore(&vfe_dev->tasklet_lock, flags);
+		ISP_DBG("%s: status0: 0x%x status1: 0x%x\n",
+			__func__, irq_status0, irq_status1);
+		irq_ops->process_reset_irq(vfe_dev,
+			irq_status0, irq_status1);
+		irq_ops->process_halt_irq(vfe_dev,
+			irq_status0, irq_status1);
+		irq_ops->process_camif_irq(vfe_dev,
+			irq_status0, irq_status1, &ts);
+		irq_ops->process_axi_irq(vfe_dev,
+			irq_status0, irq_status1, &ts);
+		irq_ops->process_stats_irq(vfe_dev,
+			irq_status0, irq_status1, &ts);
+		irq_ops->process_reg_update(vfe_dev,
+			irq_status0, irq_status1, &ts);
+		msm_isp_process_error_info(vfe_dev);
+	}
+}
+
+void msm_isp_set_src_state(struct vfe_device *vfe_dev, void *arg)
+{
+	struct msm_vfe_axi_src_state *src_state = arg;
+	vfe_dev->axi_data.src_info[src_state->input_src].active =
+	src_state->src_active;
+}
+
+int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	uint32_t i;
+	struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd);
+	long rc;
+	ISP_DBG("%s\n", __func__);
+
+	mutex_lock(&vfe_dev->mutex);
+	if (vfe_dev->vfe_open_cnt == 1) {
+		pr_err("VFE already open\n");
+		mutex_unlock(&vfe_dev->mutex);
+		return -ENODEV;
+	}
+
+	if (vfe_dev->hw_info->vfe_ops.core_ops.init_hw(vfe_dev) < 0) {
+		pr_err("%s: init hardware failed\n", __func__);
+		mutex_unlock(&vfe_dev->mutex);
+		return -EBUSY;
+	}
+
+	rc = vfe_dev->hw_info->vfe_ops.core_ops.reset_hw(vfe_dev);
+	if (rc <= 0) {
+		pr_err("%s: reset timeout\n", __func__);
+		mutex_unlock(&vfe_dev->mutex);
+		return -EINVAL;
+	}
+	vfe_dev->hw_info->vfe_ops.core_ops.init_hw_reg(vfe_dev);
+
+	for (i = 0; i < vfe_dev->hw_info->num_iommu_ctx; i++)
+		vfe_dev->buf_mgr->ops->attach_ctx(vfe_dev->buf_mgr,
+			vfe_dev->iommu_ctx[i]);
+	vfe_dev->buf_mgr->ops->buf_mgr_init(vfe_dev->buf_mgr, "msm_isp", 14);
+
+	memset(&vfe_dev->axi_data, 0, sizeof(struct msm_vfe_axi_shared_data));
+	memset(&vfe_dev->stats_data, 0,
+		sizeof(struct msm_vfe_stats_shared_data));
+	memset(&vfe_dev->error_info, 0, sizeof(vfe_dev->error_info));
+	vfe_dev->axi_data.hw_info = vfe_dev->hw_info->axi_hw_info;
+
+	ISP_DBG("%s: HW Version: 0x%x\n",
+		__func__, msm_camera_io_r(vfe_dev->vfe_base));
+
+	vfe_dev->vfe_open_cnt++;
+	vfe_dev->taskletq_idx = 0;
+	mutex_unlock(&vfe_dev->mutex);
+	return 0;
+}
+
+int msm_isp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	int i;
+	long rc;
+	struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd);
+	ISP_DBG("%s\n", __func__);
+	mutex_lock(&vfe_dev->mutex);
+	if (vfe_dev->vfe_open_cnt == 0) {
+		pr_err("%s: Invalid close\n", __func__);
+		mutex_unlock(&vfe_dev->mutex);
+		return -ENODEV;
+	}
+
+	rc = vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev);
+	if (rc <= 0)
+		pr_err("%s: halt timeout\n", __func__);
+
+	vfe_dev->buf_mgr->ops->buf_mgr_deinit(vfe_dev->buf_mgr);
+
+	for (i = vfe_dev->hw_info->num_iommu_ctx - 1; i >= 0; i--)
+		vfe_dev->buf_mgr->ops->detach_ctx(vfe_dev->buf_mgr,
+			vfe_dev->iommu_ctx[i]);
+
+	vfe_dev->hw_info->vfe_ops.core_ops.release_hw(vfe_dev);
+
+	vfe_dev->vfe_open_cnt--;
+	mutex_unlock(&vfe_dev->mutex);
+	return 0;
+}
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h
new file mode 100644
index 0000000..3dac7e0
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h
@@ -0,0 +1,45 @@
+/* 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 __MSM_ISP_UTIL_H__
+#define __MSM_ISP_UTIL_H__
+
+#include "msm_isp.h"
+
+/* #define CONFIG_MSM_ISP_DBG 1 */
+
+#ifdef CONFIG_MSM_ISP_DBG
+#define ISP_DBG(fmt, args...) printk(fmt, ##args)
+#else
+#define ISP_DBG(fmt, args...) pr_debug(fmt, ##args)
+#endif
+
+int msm_isp_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+	struct v4l2_event_subscription *sub);
+
+int msm_isp_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+	struct v4l2_event_subscription *sub);
+
+int msm_isp_proc_cmd(struct vfe_device *vfe_dev, void *arg);
+int msm_isp_send_event(struct vfe_device *vfe_dev,
+	uint32_t type, struct msm_isp_event_data *event_data);
+int msm_isp_cal_word_per_line(uint32_t output_format,
+	uint32_t pixel_per_line);
+int msm_isp_get_bit_per_pixel(uint32_t output_format);
+irqreturn_t msm_isp_process_irq(int irq_num, void *data);
+void msm_isp_set_src_state(struct vfe_device *vfe_dev, void *arg);
+void msm_isp_do_tasklet(unsigned long data);
+void msm_isp_update_error_frame_count(struct vfe_device *vfe_dev);
+void msm_isp_process_error_info(struct vfe_device *vfe_dev);
+int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh);
+int msm_isp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh);
+long msm_isp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg);
+#endif /* __MSM_ISP_UTIL_H__ */
diff --git a/drivers/media/platform/msm/camera_v2/ispif/Makefile b/drivers/media/platform/msm/camera_v2/ispif/Makefile
new file mode 100644
index 0000000..443911f
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/ispif/Makefile
@@ -0,0 +1,3 @@
+ccflags-y += -Idrivers/media/platform/msm/camera_v2
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io
+obj-$(CONFIG_MSM_CSID) += msm_ispif.o
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
new file mode 100644
index 0000000..691edc3
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
@@ -0,0 +1,1003 @@
+/* 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/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/jiffies.h>
+#include <linux/of.h>
+#include <linux/videodev2.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+#include "msm_ispif.h"
+#include "msm.h"
+#include "msm_sd.h"
+#include "msm_camera_io_util.h"
+
+#ifdef CONFIG_MSM_ISPIF_V1
+#include "msm_ispif_hwreg_v1.h"
+#else
+#include "msm_ispif_hwreg_v2.h"
+#endif
+
+#define V4L2_IDENT_ISPIF                      50001
+#define MSM_ISPIF_DRV_NAME                    "msm_ispif"
+
+#define ISPIF_INTF_CMD_DISABLE_FRAME_BOUNDARY 0x00
+#define ISPIF_INTF_CMD_ENABLE_FRAME_BOUNDARY  0x01
+#define ISPIF_INTF_CMD_DISABLE_IMMEDIATELY    0x02
+
+#undef CDBG
+#ifdef CONFIG_MSMB_CAMERA_DEBUG
+#define CDBG(fmt, args...) pr_debug(fmt, ##args)
+#else
+#define CDBG(fmt, args...) do { } while (0)
+#endif
+
+static void msm_ispif_io_dump_reg(struct ispif_device *ispif)
+{
+	if (!ispif->enb_dump_reg)
+		return;
+	msm_camera_io_dump(ispif->base, 0x250);
+}
+
+static inline int msm_ispif_is_intf_valid(uint32_t csid_version,
+	uint8_t intf_type)
+{
+	return (csid_version <= CSID_VERSION_V2 && intf_type != VFE0) ?
+		false : true;
+}
+
+static int msm_ispif_intf_reset(struct ispif_device *ispif,
+	struct msm_ispif_param_data *params)
+{
+
+	int i, rc = 0;
+	enum msm_ispif_intftype intf_type;
+	uint32_t data = STROBED_RST_EN;
+
+	for (i = 0; i < params->num; i++) {
+		intf_type = params->entries[i].intftype;
+		ispif->sof_count[params->vfe_intf].sof_cnt[intf_type] = 0;
+		switch (intf_type) {
+		case PIX0:
+			data |= (PIX_0_VFE_RST_STB | PIX_0_CSID_RST_STB);
+			break;
+		case RDI0:
+			data |= (RDI_0_VFE_RST_STB | RDI_0_CSID_RST_STB);
+			break;
+		case PIX1:
+			data |= (PIX_1_VFE_RST_STB | PIX_1_CSID_RST_STB);
+			break;
+		case RDI1:
+			data |= (RDI_1_VFE_RST_STB | RDI_1_CSID_RST_STB);
+			break;
+		case RDI2:
+			data |= (RDI_2_VFE_RST_STB | RDI_2_CSID_RST_STB);
+			break;
+		default:
+			rc = -EINVAL;
+			break;
+		}
+	}
+	if (data > 0x1) {
+		unsigned long jiffes = msecs_to_jiffies(500);
+		long lrc = 0;
+		unsigned long flags;
+
+		spin_lock_irqsave(&ispif->auto_complete_lock, flags);
+		ispif->wait_timeout = 0;
+		init_completion(&ispif->reset_complete);
+		spin_unlock_irqrestore(&ispif->auto_complete_lock, flags);
+
+		if (params->vfe_intf == VFE0)
+			msm_camera_io_w(data, ispif->base + ISPIF_RST_CMD_ADDR);
+		else
+			msm_camera_io_w(data, ispif->base +
+				ISPIF_RST_CMD_1_ADDR);
+		lrc = wait_for_completion_interruptible_timeout(
+			&ispif->reset_complete, jiffes);
+		if (lrc < 0 || !lrc) {
+			pr_err("%s: wait timeout ret = %ld\n", __func__, lrc);
+			rc = -EIO;
+
+			spin_lock_irqsave(&ispif->auto_complete_lock, flags);
+			ispif->wait_timeout = 1;
+			spin_unlock_irqrestore(
+				&ispif->auto_complete_lock, flags);
+		}
+	}
+	return rc;
+}
+
+static int msm_ispif_reset(struct ispif_device *ispif)
+{
+	int rc = 0;
+	long lrc = 0;
+	unsigned long jiffes = msecs_to_jiffies(500);
+	unsigned long flags;
+
+	spin_lock_irqsave(&ispif->auto_complete_lock, flags);
+	ispif->wait_timeout = 0;
+	init_completion(&ispif->reset_complete);
+	spin_unlock_irqrestore(&ispif->auto_complete_lock, flags);
+
+	BUG_ON(!ispif);
+
+	memset(ispif->sof_count, 0, sizeof(ispif->sof_count));
+
+	msm_camera_io_w(ISPIF_RST_CMD_MASK, ispif->base + ISPIF_RST_CMD_ADDR);
+
+	if (ispif->csid_version >= CSID_VERSION_V3)
+		msm_camera_io_w_mb(ISPIF_RST_CMD_1_MASK, ispif->base +
+			ISPIF_RST_CMD_1_ADDR);
+
+	lrc = wait_for_completion_interruptible_timeout(
+		&ispif->reset_complete, jiffes);
+
+	if (lrc < 0 || !lrc) {
+		pr_err("%s: wait timeout ret = %ld\n", __func__, lrc);
+		rc = -EIO;
+
+		spin_lock_irqsave(&ispif->auto_complete_lock, flags);
+		ispif->wait_timeout = 1;
+		spin_unlock_irqrestore(&ispif->auto_complete_lock, flags);
+	}
+
+	return rc;
+}
+
+static int msm_ispif_subdev_g_chip_ident(struct v4l2_subdev *sd,
+	struct v4l2_dbg_chip_ident *chip)
+{
+	BUG_ON(!chip);
+	chip->ident = V4L2_IDENT_ISPIF;
+	chip->revision = 0;
+	return 0;
+}
+
+static void msm_ispif_sel_csid_core(struct ispif_device *ispif,
+	uint8_t intftype, uint8_t csid, uint8_t vfe_intf)
+{
+	int rc = 0;
+	uint32_t data;
+
+	BUG_ON(!ispif);
+
+	if (!msm_ispif_is_intf_valid(ispif->csid_version, vfe_intf)) {
+		pr_err("%s: invalid interface type\n", __func__);
+		return;
+	}
+
+	if (ispif->csid_version <= CSID_VERSION_V2) {
+		if (ispif->ispif_clk[intftype] == NULL) {
+			CDBG("%s: ispif NULL clk\n", __func__);
+			return;
+		}
+
+		rc = clk_set_rate(ispif->ispif_clk[intftype], csid);
+		if (rc) {
+			pr_err("%s: clk_set_rate failed %d\n", __func__, rc);
+			return;
+		}
+	}
+
+	data = msm_camera_io_r(ispif->base + ISPIF_INPUT_SEL_ADDR +
+		(0x200 * vfe_intf));
+	switch (intftype) {
+	case PIX0:
+		data &= ~(BIT(1) | BIT(0));
+		data |= csid;
+		break;
+	case RDI0:
+		data &= ~(BIT(5) | BIT(4));
+		data |= (csid << 4);
+		break;
+	case PIX1:
+		data &= ~(BIT(9) | BIT(8));
+		data |= (csid << 8);
+		break;
+	case RDI1:
+		data &= ~(BIT(13) | BIT(12));
+		data |= (csid << 12);
+		break;
+	case RDI2:
+		data &= ~(BIT(21) | BIT(20));
+		data |= (csid << 20);
+		break;
+	}
+	if (data)
+		msm_camera_io_w_mb(data, ispif->base + ISPIF_INPUT_SEL_ADDR +
+			(0x200 * vfe_intf));
+}
+
+static void msm_ispif_enable_intf_cids(struct ispif_device *ispif,
+	uint8_t intftype, uint16_t cid_mask, uint8_t vfe_intf, uint8_t enable)
+{
+	uint32_t intf_addr, data;
+
+	BUG_ON(!ispif);
+
+	if (!msm_ispif_is_intf_valid(ispif->csid_version, vfe_intf)) {
+		pr_err("%s: invalid interface type\n", __func__);
+		return;
+	}
+
+	switch (intftype) {
+	case PIX0:
+		intf_addr = ISPIF_PIX_0_INTF_CID_MASK_ADDR + (0x200 * vfe_intf);
+		break;
+	case RDI0:
+		intf_addr = ISPIF_RDI_0_INTF_CID_MASK_ADDR + (0x200 * vfe_intf);
+		break;
+	case PIX1:
+		intf_addr = ISPIF_PIX_1_INTF_CID_MASK_ADDR + (0x200 * vfe_intf);
+		break;
+	case RDI1:
+		intf_addr = ISPIF_RDI_1_INTF_CID_MASK_ADDR + (0x200 * vfe_intf);
+		break;
+	case RDI2:
+		intf_addr = ISPIF_RDI_2_INTF_CID_MASK_ADDR + (0x200 * vfe_intf);
+		break;
+	default:
+		pr_err("%s: invalid intftype=%d\n", __func__, intftype);
+		BUG_ON(1);
+		return;
+	}
+
+	data = msm_camera_io_r(ispif->base + intf_addr);
+	if (enable)
+		data |= cid_mask;
+	else
+		data &= ~cid_mask;
+	msm_camera_io_w_mb(data, ispif->base + intf_addr);
+}
+
+static int msm_ispif_validate_intf_status(struct ispif_device *ispif,
+	uint8_t intftype, uint8_t vfe_intf)
+{
+	int rc = 0;
+	uint32_t data = 0;
+
+	BUG_ON(!ispif);
+
+	if (!msm_ispif_is_intf_valid(ispif->csid_version, vfe_intf)) {
+		pr_err("%s: invalid interface type\n", __func__);
+		return -EINVAL;
+	}
+
+	switch (intftype) {
+	case PIX0:
+		data = msm_camera_io_r(ispif->base +
+			ISPIF_PIX_0_STATUS_ADDR + (0x200 * vfe_intf));
+		break;
+	case RDI0:
+		data = msm_camera_io_r(ispif->base +
+			ISPIF_RDI_0_STATUS_ADDR + (0x200 * vfe_intf));
+		break;
+	case PIX1:
+		data = msm_camera_io_r(ispif->base +
+			ISPIF_PIX_1_STATUS_ADDR + (0x200 * vfe_intf));
+		break;
+	case RDI1:
+		data = msm_camera_io_r(ispif->base +
+			ISPIF_RDI_1_STATUS_ADDR + (0x200 * vfe_intf));
+		break;
+	case RDI2:
+		data = msm_camera_io_r(ispif->base +
+			ISPIF_RDI_2_STATUS_ADDR + (0x200 * vfe_intf));
+		break;
+	}
+	if ((data & 0xf) != 0xf)
+		rc = -EBUSY;
+	return rc;
+}
+
+static uint16_t msm_ispif_get_cids_mask_from_cfg(
+	struct msm_ispif_params_entry *entry)
+{
+	int i;
+	uint16_t cids_mask = 0;
+
+	BUG_ON(!entry);
+
+	for (i = 0; i < entry->num_cids; i++)
+		cids_mask |= (1 << entry->cids[i]);
+
+	return cids_mask;
+}
+
+static int msm_ispif_config(struct ispif_device *ispif,
+	struct msm_ispif_param_data *params)
+{
+	int rc = 0, i = 0;
+	uint16_t cid_mask;
+	enum msm_ispif_intftype intftype;
+	enum msm_ispif_vfe_intf vfe_intf;
+
+	BUG_ON(!ispif);
+	BUG_ON(!params);
+
+	vfe_intf = params->vfe_intf;
+	if (!msm_ispif_is_intf_valid(ispif->csid_version, vfe_intf)) {
+		pr_err("%s: invalid interface type\n", __func__);
+		return -EINVAL;
+	}
+
+	msm_camera_io_w(0x0, ispif->base + ISPIF_IRQ_MASK_ADDR);
+	msm_camera_io_w(0x0, ispif->base + ISPIF_IRQ_MASK_1_ADDR);
+	msm_camera_io_w_mb(0x0, ispif->base + ISPIF_IRQ_MASK_2_ADDR);
+
+	for (i = 0; i < params->num; i++) {
+		intftype = params->entries[i].intftype;
+
+		vfe_intf = params->vfe_intf;
+
+		CDBG("%s intftype %x, vfe_intf %d, csid %d\n", __func__,
+			intftype, vfe_intf, params->entries[i].csid);
+
+		if ((intftype >= INTF_MAX) || (vfe_intf >= VFE_MAX) ||
+			(ispif->csid_version <= CSID_VERSION_V2 &&
+			(vfe_intf > VFE0))) {
+			pr_err("%s: VFEID %d and CSID version %d mismatch\n",
+				__func__, vfe_intf, ispif->csid_version);
+			return -EINVAL;
+		}
+
+		rc = msm_ispif_validate_intf_status(ispif, intftype, vfe_intf);
+		if (rc) {
+			pr_err("%s:validate_intf_status failed, rc = %d\n",
+				__func__, rc);
+			return rc;
+		}
+
+		msm_ispif_sel_csid_core(ispif, intftype,
+			params->entries[i].csid, vfe_intf);
+		cid_mask = msm_ispif_get_cids_mask_from_cfg(
+				&params->entries[i]);
+		msm_ispif_enable_intf_cids(ispif, intftype,
+			cid_mask, vfe_intf, 1);
+	}
+
+	msm_camera_io_w(ISPIF_IRQ_STATUS_MASK, ispif->base +
+		ISPIF_IRQ_MASK_ADDR);
+
+	msm_camera_io_w(ISPIF_IRQ_STATUS_MASK, ispif->base +
+		ISPIF_IRQ_CLEAR_ADDR);
+
+	msm_camera_io_w(ISPIF_IRQ_STATUS_1_MASK, ispif->base +
+		ISPIF_IRQ_MASK_1_ADDR);
+
+	msm_camera_io_w(ISPIF_IRQ_STATUS_1_MASK, ispif->base +
+		ISPIF_IRQ_CLEAR_1_ADDR);
+
+	msm_camera_io_w(ISPIF_IRQ_STATUS_2_MASK, ispif->base +
+		ISPIF_IRQ_MASK_2_ADDR);
+
+	msm_camera_io_w(ISPIF_IRQ_STATUS_2_MASK, ispif->base +
+		ISPIF_IRQ_CLEAR_2_ADDR);
+
+	msm_camera_io_w_mb(ISPIF_IRQ_GLOBAL_CLEAR_CMD, ispif->base +
+		ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR);
+
+	return rc;
+}
+
+static void msm_ispif_intf_cmd(struct ispif_device *ispif, uint32_t cmd_bits,
+	struct msm_ispif_param_data *params)
+{
+	uint8_t vc;
+	int i, k;
+	enum msm_ispif_intftype intf_type;
+	enum msm_ispif_cid cid;
+	enum msm_ispif_vfe_intf vfe_intf = params->vfe_intf;
+
+	BUG_ON(!ispif);
+	BUG_ON(!params);
+
+	if (!msm_ispif_is_intf_valid(ispif->csid_version, vfe_intf)) {
+		pr_err("%s: invalid interface type\n", __func__);
+		return;
+	}
+
+	for (i = 0; i < params->num; i++) {
+		intf_type = params->entries[i].intftype;
+		for (k = 0; k < params->entries[i].num_cids; k++) {
+			cid = params->entries[i].cids[k];
+			vc = cid % 4;
+			if (intf_type == RDI2) {
+				/* zero out two bits */
+				ispif->applied_intf_cmd[vfe_intf].intf_cmd1 &=
+					~(0x3 << (vc * 2 + 8));
+				/* set cmd bits */
+				ispif->applied_intf_cmd[vfe_intf].intf_cmd1 |=
+					(cmd_bits << (vc * 2 + 8));
+			} else {
+				/* zero 2 bits */
+				ispif->applied_intf_cmd[vfe_intf].intf_cmd &=
+					~(0x3 << (vc * 2 + intf_type * 8));
+				/* set cmd bits */
+				ispif->applied_intf_cmd[vfe_intf].intf_cmd |=
+					(cmd_bits << (vc * 2 + intf_type * 8));
+			}
+		}
+	}
+	/* cmd for PIX0, PIX1, RDI0, RDI1 */
+	if (ispif->applied_intf_cmd[vfe_intf].intf_cmd != 0xFFFFFFFF) {
+		msm_camera_io_w_mb(ispif->applied_intf_cmd[vfe_intf].intf_cmd,
+			ispif->base + ISPIF_INTF_CMD_ADDR +
+			(0x200 * vfe_intf));
+	}
+	/* cmd for RDI2 */
+	if (ispif->applied_intf_cmd[vfe_intf].intf_cmd1 != 0xFFFFFFFF)
+		msm_camera_io_w_mb(ispif->applied_intf_cmd[vfe_intf].intf_cmd1,
+			ispif->base + ISPIF_INTF_CMD_1_ADDR +
+			(0x200 * vfe_intf));
+}
+
+static int msm_ispif_stop_immediately(struct ispif_device *ispif,
+	struct msm_ispif_param_data *params)
+{
+	int i, rc = 0;
+	uint16_t cid_mask = 0;
+
+	BUG_ON(!ispif);
+	BUG_ON(!params);
+
+	msm_ispif_intf_cmd(ispif, ISPIF_INTF_CMD_DISABLE_IMMEDIATELY, params);
+
+	/* after stop the interface we need to unmask the CID enable bits */
+	for (i = 0; i < params->num; i++) {
+		cid_mask = msm_ispif_get_cids_mask_from_cfg(
+			&params->entries[i]);
+		msm_ispif_enable_intf_cids(ispif, params->entries[i].intftype,
+			cid_mask, params->vfe_intf, 0);
+	}
+	return rc;
+}
+
+static int msm_ispif_start_frame_boundary(struct ispif_device *ispif,
+	struct msm_ispif_param_data *params)
+{
+	int rc;
+
+	rc = msm_ispif_intf_reset(ispif, params);
+	if (rc) {
+		pr_err("%s: msm_ispif_intf_reset failed. rc=%d\n",
+			__func__, rc);
+		return rc;
+	}
+
+	msm_ispif_intf_cmd(ispif, ISPIF_INTF_CMD_ENABLE_FRAME_BOUNDARY, params);
+	return rc;
+}
+
+static int msm_ispif_stop_frame_boundary(struct ispif_device *ispif,
+	struct msm_ispif_param_data *params)
+{
+	int i, rc = 0;
+	uint16_t cid_mask = 0;
+	uint32_t intf_addr;
+
+	BUG_ON(!ispif);
+	BUG_ON(!params);
+
+	if (!msm_ispif_is_intf_valid(ispif->csid_version, params->vfe_intf)) {
+		pr_err("%s: invalid interface type\n", __func__);
+		return -EINVAL;
+	}
+
+	msm_ispif_intf_cmd(ispif,
+		ISPIF_INTF_CMD_DISABLE_FRAME_BOUNDARY, params);
+
+	for (i = 0; i < params->num; i++) {
+		cid_mask =
+			msm_ispif_get_cids_mask_from_cfg(&params->entries[i]);
+
+		switch (params->entries[i].intftype) {
+		case PIX0:
+			intf_addr = ISPIF_PIX_0_STATUS_ADDR +
+				(0x200 * params->vfe_intf);
+			break;
+		case RDI0:
+			intf_addr = ISPIF_RDI_0_STATUS_ADDR +
+				(0x200 * params->vfe_intf);
+			break;
+		case PIX1:
+			intf_addr = ISPIF_PIX_1_STATUS_ADDR +
+				(0x200 * params->vfe_intf);
+			break;
+		case RDI1:
+			intf_addr = ISPIF_RDI_1_STATUS_ADDR +
+				(0x200 * params->vfe_intf);
+			break;
+		case RDI2:
+			intf_addr = ISPIF_RDI_2_STATUS_ADDR +
+				(0x200 * params->vfe_intf);
+			break;
+		default:
+			pr_err("%s: invalid intftype=%d\n", __func__,
+				params->entries[i].intftype);
+			return -EPERM;
+		}
+
+		/* todo_bug_fix? very bad. use readl_poll_timeout */
+		while ((msm_camera_io_r(ispif->base + intf_addr) & 0xF) != 0xF)
+			CDBG("%s: Wait for %d Idle\n", __func__,
+				params->entries[i].intftype);
+
+		/* disable CIDs in CID_MASK register */
+		msm_ispif_enable_intf_cids(ispif, params->entries[i].intftype,
+			cid_mask, params->vfe_intf, 0);
+	}
+	return rc;
+}
+
+static void ispif_process_irq(struct ispif_device *ispif,
+	struct ispif_irq_status *out, enum msm_ispif_vfe_intf vfe_id)
+{
+	BUG_ON(!ispif);
+	BUG_ON(!out);
+
+	if (out[vfe_id].ispifIrqStatus0 &
+			ISPIF_IRQ_STATUS_PIX_SOF_MASK) {
+		ispif->sof_count[vfe_id].sof_cnt[PIX0]++;
+	}
+	if (out[vfe_id].ispifIrqStatus0 &
+			ISPIF_IRQ_STATUS_RDI0_SOF_MASK) {
+		ispif->sof_count[vfe_id].sof_cnt[RDI0]++;
+	}
+	if (out[vfe_id].ispifIrqStatus1 &
+			ISPIF_IRQ_STATUS_RDI1_SOF_MASK) {
+		ispif->sof_count[vfe_id].sof_cnt[RDI1]++;
+	}
+	if (out[vfe_id].ispifIrqStatus2 &
+			ISPIF_IRQ_STATUS_RDI2_SOF_MASK) {
+		ispif->sof_count[vfe_id].sof_cnt[RDI2]++;
+	}
+}
+
+static inline void msm_ispif_read_irq_status(struct ispif_irq_status *out,
+	void *data)
+{
+	struct ispif_device *ispif = (struct ispif_device *)data;
+
+	BUG_ON(!ispif);
+	BUG_ON(!out);
+
+	out[VFE0].ispifIrqStatus0 = msm_camera_io_r(ispif->base +
+		ISPIF_IRQ_STATUS_ADDR);
+	msm_camera_io_w(out[VFE0].ispifIrqStatus0,
+		ispif->base + ISPIF_IRQ_CLEAR_ADDR);
+
+	out[VFE0].ispifIrqStatus1 = msm_camera_io_r(ispif->base +
+		ISPIF_IRQ_STATUS_1_ADDR);
+	msm_camera_io_w(out[VFE0].ispifIrqStatus1,
+		ispif->base + ISPIF_IRQ_CLEAR_1_ADDR);
+
+	out[VFE0].ispifIrqStatus2 = msm_camera_io_r(ispif->base +
+		ISPIF_IRQ_STATUS_2_ADDR);
+	msm_camera_io_w_mb(out[VFE0].ispifIrqStatus2,
+		ispif->base + ISPIF_IRQ_CLEAR_2_ADDR);
+
+	if (out[VFE0].ispifIrqStatus0 & ISPIF_IRQ_STATUS_MASK) {
+		if (out[VFE0].ispifIrqStatus0 & RESET_DONE_IRQ) {
+			unsigned long flags;
+			spin_lock_irqsave(&ispif->auto_complete_lock, flags);
+			if (ispif->wait_timeout == 0)
+				complete(&ispif->reset_complete);
+			spin_unlock_irqrestore(
+				&ispif->auto_complete_lock, flags);
+		}
+
+		if (out[VFE0].ispifIrqStatus0 & PIX_INTF_0_OVERFLOW_IRQ)
+			pr_err("%s: VFE0 pix0 overflow.\n", __func__);
+
+		if (out[VFE0].ispifIrqStatus0 & RAW_INTF_0_OVERFLOW_IRQ)
+			pr_err("%s: VFE0 rdi0 overflow.\n", __func__);
+
+		if (out[VFE0].ispifIrqStatus1 & RAW_INTF_1_OVERFLOW_IRQ)
+			pr_err("%s: VFE0 rdi1 overflow.\n", __func__);
+
+		if (out[VFE0].ispifIrqStatus2 & RAW_INTF_2_OVERFLOW_IRQ)
+			pr_err("%s: VFE0 rdi2 overflow.\n", __func__);
+
+		ispif_process_irq(ispif, out, VFE0);
+	}
+	if (ispif->csid_version >= CSID_VERSION_V3) {
+		out[VFE1].ispifIrqStatus0 = msm_camera_io_r(ispif->base +
+			ISPIF_IRQ_STATUS_ADDR + 0x200);
+		msm_camera_io_w(out[VFE1].ispifIrqStatus0,
+			ispif->base + ISPIF_IRQ_CLEAR_ADDR + 0x200);
+
+		out[VFE1].ispifIrqStatus1 = msm_camera_io_r(ispif->base +
+			ISPIF_IRQ_STATUS_1_ADDR + 0x200);
+		msm_camera_io_w(out[VFE1].ispifIrqStatus1,
+
+				ispif->base + ISPIF_IRQ_CLEAR_1_ADDR + 0x200);
+		out[VFE1].ispifIrqStatus2 = msm_camera_io_r(ispif->base +
+			ISPIF_IRQ_STATUS_2_ADDR + 0x200);
+		msm_camera_io_w_mb(out[VFE1].ispifIrqStatus2,
+			ispif->base + ISPIF_IRQ_CLEAR_2_ADDR + 0x200);
+
+		if (out[VFE1].ispifIrqStatus0 & PIX_INTF_0_OVERFLOW_IRQ)
+			pr_err("%s: VFE1 pix0 overflow.\n", __func__);
+
+		if (out[VFE1].ispifIrqStatus0 & RAW_INTF_0_OVERFLOW_IRQ)
+			pr_err("%s: VFE1 rdi0 overflow.\n", __func__);
+
+		if (out[VFE1].ispifIrqStatus1 & RAW_INTF_1_OVERFLOW_IRQ)
+			pr_err("%s: VFE1 rdi1 overflow.\n", __func__);
+
+		if (out[VFE1].ispifIrqStatus2 & RAW_INTF_2_OVERFLOW_IRQ)
+			pr_err("%s: VFE1 rdi2 overflow.\n", __func__);
+
+		ispif_process_irq(ispif, out, VFE1);
+	}
+	msm_camera_io_w_mb(ISPIF_IRQ_GLOBAL_CLEAR_CMD, ispif->base +
+		ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR);
+}
+
+static irqreturn_t msm_io_ispif_irq(int irq_num, void *data)
+{
+	struct ispif_irq_status irq[VFE_MAX];
+
+	msm_ispif_read_irq_status(irq, data);
+	return IRQ_HANDLED;
+}
+
+static struct msm_cam_clk_info ispif_8960_clk_info[] = {
+	{"csi_pix_clk", 0},
+	{"csi_rdi_clk", 0},
+	{"csi_pix1_clk", 0},
+	{"csi_rdi1_clk", 0},
+	{"csi_rdi2_clk", 0},
+};
+static struct msm_cam_clk_info ispif_8974_clk_info[] = {
+	{"camss_vfe_vfe_clk", -1},
+	{"camss_csi_vfe_clk", -1},
+	{"camss_vfe_vfe_clk1", -1},
+	{"camss_csi_vfe_clk1", -1},
+};
+
+static int msm_ispif_init(struct ispif_device *ispif,
+	uint32_t csid_version)
+{
+	int rc = 0;
+
+	BUG_ON(!ispif);
+
+	if (ispif->ispif_state == ISPIF_POWER_UP) {
+		pr_err("%s: ispif already initted state = %d\n", __func__,
+			ispif->ispif_state);
+		rc = -EPERM;
+		return rc;
+	}
+
+	/* can we set to zero? */
+	ispif->applied_intf_cmd[VFE0].intf_cmd  = 0xFFFFFFFF;
+	ispif->applied_intf_cmd[VFE0].intf_cmd1 = 0xFFFFFFFF;
+	ispif->applied_intf_cmd[VFE1].intf_cmd  = 0xFFFFFFFF;
+	ispif->applied_intf_cmd[VFE1].intf_cmd1 = 0xFFFFFFFF;
+	memset(ispif->sof_count, 0, sizeof(ispif->sof_count));
+
+	ispif->csid_version = csid_version;
+	if (ispif->csid_version < CSID_VERSION_V2) {
+		rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_8960_clk_info,
+			ispif->ispif_clk, 2, 1);
+		if (rc) {
+			pr_err("%s: cannot enable clock, error = %d\n",
+				__func__, rc);
+			goto end;
+		}
+	} else if (ispif->csid_version == CSID_VERSION_V2) {
+		rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_8960_clk_info,
+			ispif->ispif_clk, ARRAY_SIZE(ispif_8960_clk_info), 1);
+		if (rc) {
+			pr_err("%s: cannot enable clock, error = %d\n",
+				__func__, rc);
+			goto end;
+		}
+	} else if (ispif->csid_version >= CSID_VERSION_V3) {
+		rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_8974_clk_info,
+			ispif->ispif_clk, ARRAY_SIZE(ispif_8974_clk_info), 1);
+		if (rc) {
+			pr_err("%s: cannot enable clock, error = %d\n",
+				__func__, rc);
+			goto end;
+		}
+	} else {
+		pr_err("%s: unsupported version=%d\n", __func__,
+			ispif->csid_version);
+		goto end;
+	}
+	ispif->base = ioremap(ispif->mem->start,
+		resource_size(ispif->mem));
+	if (!ispif->base) {
+		rc = -ENOMEM;
+		pr_err("%s: nomem\n", __func__);
+		goto error_clk;
+	}
+	rc = request_irq(ispif->irq->start, msm_io_ispif_irq,
+		IRQF_TRIGGER_RISING, "ispif", ispif);
+	if (rc) {
+		pr_err("%s: request_irq error = %d\n", __func__, rc);
+		goto error_irq;
+	}
+
+	rc = msm_ispif_reset(ispif);
+	if (rc == 0) {
+		ispif->ispif_state = ISPIF_POWER_UP;
+		CDBG("%s: power up done\n", __func__);
+		goto end;
+	}
+	free_irq(ispif->irq->start, ispif);
+error_irq:
+	iounmap(ispif->base);
+error_clk:
+	if (ispif->csid_version < CSID_VERSION_V2) {
+		msm_cam_clk_enable(&ispif->pdev->dev, ispif_8960_clk_info,
+		ispif->ispif_clk, 2, 0);
+	} else if (ispif->csid_version == CSID_VERSION_V2) {
+		msm_cam_clk_enable(&ispif->pdev->dev, ispif_8960_clk_info,
+		ispif->ispif_clk, ARRAY_SIZE(ispif_8960_clk_info), 0);
+	} else if (ispif->csid_version >= CSID_VERSION_V3) {
+		msm_cam_clk_enable(&ispif->pdev->dev, ispif_8974_clk_info,
+			ispif->ispif_clk, ARRAY_SIZE(ispif_8974_clk_info), 0);
+	}
+end:
+	return rc;
+}
+
+static void msm_ispif_release(struct ispif_device *ispif)
+{
+	BUG_ON(!ispif);
+
+	if (ispif->ispif_state != ISPIF_POWER_UP) {
+		pr_err("%s: ispif invalid state %d\n", __func__,
+			ispif->ispif_state);
+		return;
+	}
+
+	/* make sure no streaming going on */
+	msm_ispif_reset(ispif);
+
+	free_irq(ispif->irq->start, ispif);
+
+	iounmap(ispif->base);
+
+	if (ispif->csid_version < CSID_VERSION_V2) {
+		msm_cam_clk_enable(&ispif->pdev->dev, ispif_8960_clk_info,
+		ispif->ispif_clk, 2, 0);
+	} else if (ispif->csid_version == CSID_VERSION_V2) {
+		msm_cam_clk_enable(&ispif->pdev->dev, ispif_8960_clk_info,
+			ispif->ispif_clk, ARRAY_SIZE(ispif_8960_clk_info), 0);
+	} else if (ispif->csid_version >= CSID_VERSION_V3) {
+		msm_cam_clk_enable(&ispif->pdev->dev, ispif_8974_clk_info,
+			ispif->ispif_clk, ARRAY_SIZE(ispif_8974_clk_info), 0);
+	}
+	ispif->ispif_state = ISPIF_POWER_DOWN;
+}
+
+static long msm_ispif_cmd(struct v4l2_subdev *sd, void *arg)
+{
+	long rc = 0;
+	struct ispif_cfg_data *pcdata = (struct ispif_cfg_data *)arg;
+	struct ispif_device *ispif =
+		(struct ispif_device *)v4l2_get_subdevdata(sd);
+
+	BUG_ON(!sd);
+	BUG_ON(!pcdata);
+
+	mutex_lock(&ispif->mutex);
+
+	switch (pcdata->cfg_type) {
+	case ISPIF_ENABLE_REG_DUMP:
+		ispif->enb_dump_reg = pcdata->reg_dump; /* save dump config */
+		break;
+	case ISPIF_INIT:
+		rc = msm_ispif_init(ispif, pcdata->csid_version);
+		msm_ispif_io_dump_reg(ispif);
+		break;
+	case ISPIF_CFG:
+		rc = msm_ispif_config(ispif, &pcdata->params);
+		msm_ispif_io_dump_reg(ispif);
+		break;
+	case ISPIF_START_FRAME_BOUNDARY:
+		rc = msm_ispif_start_frame_boundary(ispif, &pcdata->params);
+		msm_ispif_io_dump_reg(ispif);
+		break;
+	case ISPIF_STOP_FRAME_BOUNDARY:
+		rc = msm_ispif_stop_frame_boundary(ispif, &pcdata->params);
+		msm_ispif_io_dump_reg(ispif);
+		break;
+	case ISPIF_STOP_IMMEDIATELY:
+		rc = msm_ispif_stop_immediately(ispif, &pcdata->params);
+		msm_ispif_io_dump_reg(ispif);
+		break;
+	case ISPIF_RELEASE:
+		msm_ispif_release(ispif);
+		break;
+	default:
+		pr_err("%s: invalid cfg_type\n", __func__);
+		rc = -EINVAL;
+		break;
+	}
+	mutex_unlock(&ispif->mutex);
+	return rc;
+}
+
+static long msm_ispif_subdev_ioctl(struct v4l2_subdev *sd,
+	unsigned int cmd, void *arg)
+{
+	switch (cmd) {
+	case VIDIOC_MSM_ISPIF_CFG:
+		return msm_ispif_cmd(sd, arg);
+	default:
+		pr_err("%s: invalid cmd received\n", __func__);
+		return -ENOIOCTLCMD;
+	}
+}
+
+static int ispif_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	struct ispif_device *ispif = v4l2_get_subdevdata(sd);
+
+	mutex_lock(&ispif->mutex);
+	/* mem remap is done in init when the clock is on */
+	ispif->open_cnt++;
+	mutex_unlock(&ispif->mutex);
+	return 0;
+}
+
+static int ispif_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	int rc = 0;
+	struct ispif_device *ispif = v4l2_get_subdevdata(sd);
+
+	if (!ispif) {
+		pr_err("%s: invalid input\n", __func__);
+		return -EINVAL;
+	}
+
+	mutex_lock(&ispif->mutex);
+	if (ispif->open_cnt == 0) {
+		pr_err("%s: Invalid close\n", __func__);
+		rc = -ENODEV;
+		goto end;
+	}
+	ispif->open_cnt--;
+	if (ispif->open_cnt == 0)
+		msm_ispif_release(ispif);
+end:
+	mutex_unlock(&ispif->mutex);
+	return rc;
+}
+
+static struct v4l2_subdev_core_ops msm_ispif_subdev_core_ops = {
+	.g_chip_ident = &msm_ispif_subdev_g_chip_ident,
+	.ioctl = &msm_ispif_subdev_ioctl,
+};
+
+static const struct v4l2_subdev_ops msm_ispif_subdev_ops = {
+	.core = &msm_ispif_subdev_core_ops,
+};
+
+static const struct v4l2_subdev_internal_ops msm_ispif_internal_ops = {
+	.open = ispif_open_node,
+	.close = ispif_close_node,
+};
+
+static int __devinit ispif_probe(struct platform_device *pdev)
+{
+	int rc;
+	struct ispif_device *ispif;
+
+	ispif = kzalloc(sizeof(struct ispif_device), GFP_KERNEL);
+	if (!ispif) {
+		pr_err("%s: no enough memory\n", __func__);
+		return -ENOMEM;
+	}
+
+	v4l2_subdev_init(&ispif->msm_sd.sd, &msm_ispif_subdev_ops);
+	ispif->msm_sd.sd.internal_ops = &msm_ispif_internal_ops;
+	ispif->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+
+	snprintf(ispif->msm_sd.sd.name,
+		ARRAY_SIZE(ispif->msm_sd.sd.name), MSM_ISPIF_DRV_NAME);
+	v4l2_set_subdevdata(&ispif->msm_sd.sd, ispif);
+
+	platform_set_drvdata(pdev, &ispif->msm_sd.sd);
+	mutex_init(&ispif->mutex);
+
+	media_entity_init(&ispif->msm_sd.sd.entity, 0, NULL, 0);
+	ispif->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	ispif->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_ISPIF;
+	ispif->msm_sd.sd.entity.name = pdev->name;
+	rc = msm_sd_register(&ispif->msm_sd);
+	if (rc) {
+		pr_err("%s: msm_sd_register error = %d\n", __func__, rc);
+		goto error_sd_register;
+	}
+
+	if (pdev->dev.of_node)
+		of_property_read_u32((&pdev->dev)->of_node,
+		"cell-index", &pdev->id);
+
+	ispif->mem = platform_get_resource_byname(pdev,
+		IORESOURCE_MEM, "ispif");
+	if (!ispif->mem) {
+		pr_err("%s: no mem resource?\n", __func__);
+		rc = -ENODEV;
+		goto error;
+	}
+	ispif->irq = platform_get_resource_byname(pdev,
+		IORESOURCE_IRQ, "ispif");
+	if (!ispif->irq) {
+		pr_err("%s: no irq resource?\n", __func__);
+		rc = -ENODEV;
+		goto error;
+	}
+	ispif->io = request_mem_region(ispif->mem->start,
+		resource_size(ispif->mem), pdev->name);
+	if (!ispif->io) {
+		pr_err("%s: no valid mem region\n", __func__);
+		rc = -EBUSY;
+		goto error;
+	}
+
+	ispif->pdev = pdev;
+	ispif->ispif_state = ISPIF_POWER_DOWN;
+	ispif->open_cnt = 0;
+	spin_lock_init(&ispif->auto_complete_lock);
+	ispif->wait_timeout = 0;
+	return 0;
+
+error:
+	msm_sd_unregister(&ispif->msm_sd);
+error_sd_register:
+	mutex_destroy(&ispif->mutex);
+	kfree(ispif);
+	return rc;
+}
+
+static const struct of_device_id msm_ispif_dt_match[] = {
+	{.compatible = "qcom,ispif"},
+};
+
+MODULE_DEVICE_TABLE(of, msm_ispif_dt_match);
+
+static struct platform_driver ispif_driver = {
+	.probe = ispif_probe,
+	.driver = {
+		.name = MSM_ISPIF_DRV_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = msm_ispif_dt_match,
+	},
+};
+
+static int __init msm_ispif_init_module(void)
+{
+	return platform_driver_register(&ispif_driver);
+}
+
+static void __exit msm_ispif_exit_module(void)
+{
+	platform_driver_unregister(&ispif_driver);
+}
+
+module_init(msm_ispif_init_module);
+module_exit(msm_ispif_exit_module);
+MODULE_DESCRIPTION("MSM ISP Interface driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.h b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.h
new file mode 100644
index 0000000..f8c3cce
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.h
@@ -0,0 +1,61 @@
+/* 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 MSM_ISPIF_H
+#define MSM_ISPIF_H
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <media/v4l2-subdev.h>
+#include <media/msmb_ispif.h>
+#include "msm_sd.h"
+
+struct ispif_irq_status {
+	uint32_t ispifIrqStatus0;
+	uint32_t ispifIrqStatus1;
+	uint32_t ispifIrqStatus2;
+};
+
+enum msm_ispif_state_t {
+	ISPIF_POWER_UP,
+	ISPIF_POWER_DOWN,
+};
+struct ispif_sof_count {
+	uint32_t sof_cnt[INTF_MAX];
+};
+
+struct ispif_intf_cmd {
+	uint32_t intf_cmd;
+	uint32_t intf_cmd1;
+};
+
+struct ispif_device {
+	struct platform_device *pdev;
+	struct msm_sd_subdev msm_sd;
+	struct resource *mem;
+	struct resource *irq;
+	struct resource *io;
+	void __iomem *base;
+	struct mutex mutex;
+	uint8_t start_ack_pending;
+	struct completion reset_complete;
+	spinlock_t auto_complete_lock;
+	uint8_t wait_timeout;
+	uint32_t csid_version;
+	int enb_dump_reg;
+	uint32_t open_cnt;
+	struct ispif_sof_count sof_count[VFE_MAX];
+	struct ispif_intf_cmd applied_intf_cmd[VFE_MAX];
+	enum msm_ispif_state_t ispif_state;
+	struct clk *ispif_clk[INTF_MAX];
+};
+#endif
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v1.h b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v1.h
new file mode 100644
index 0000000..cdbebea
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v1.h
@@ -0,0 +1,94 @@
+/* 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 __MSM_ISPIF_HWREG_V1_H__
+#define __MSM_ISPIF_HWREG_V1_H__
+
+/* common registers */
+#define ISPIF_RST_CMD_ADDR                  0x0000
+#define ISPIF_RST_CMD_1_ADDR                0x0000 /* undefined */
+#define ISPIF_INTF_CMD_ADDR                 0x0004
+#define ISPIF_INTF_CMD_1_ADDR               0x0030
+#define ISPIF_CTRL_ADDR                     0x0008
+#define ISPIF_INPUT_SEL_ADDR                0x000C
+#define ISPIF_PIX_0_INTF_CID_MASK_ADDR      0x0010
+#define ISPIF_RDI_0_INTF_CID_MASK_ADDR      0x0014
+#define ISPIF_PIX_1_INTF_CID_MASK_ADDR      0x0038
+#define ISPIF_RDI_1_INTF_CID_MASK_ADDR      0x003C
+#define ISPIF_RDI_2_INTF_CID_MASK_ADDR      0x0044
+#define ISPIF_PIX_0_STATUS_ADDR             0x0024
+#define ISPIF_RDI_0_STATUS_ADDR             0x0028
+#define ISPIF_PIX_1_STATUS_ADDR             0x0060
+#define ISPIF_RDI_1_STATUS_ADDR             0x0064
+#define ISPIF_RDI_2_STATUS_ADDR             0x006C
+#define ISPIF_IRQ_MASK_ADDR                 0x0100
+#define ISPIF_IRQ_CLEAR_ADDR                0x0104
+#define ISPIF_IRQ_STATUS_ADDR               0x0108
+#define ISPIF_IRQ_MASK_1_ADDR               0x010C
+#define ISPIF_IRQ_CLEAR_1_ADDR              0x0110
+#define ISPIF_IRQ_STATUS_1_ADDR             0x0114
+#define ISPIF_IRQ_MASK_2_ADDR               0x0118
+#define ISPIF_IRQ_CLEAR_2_ADDR              0x011C
+#define ISPIF_IRQ_STATUS_2_ADDR             0x0120
+#define ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR     0x0124
+
+/*ISPIF RESET BITS*/
+#define VFE_CLK_DOMAIN_RST                 BIT(31)
+#define RDI_CLK_DOMAIN_RST                 BIT(30)
+#define PIX_CLK_DOMAIN_RST                 BIT(29)
+#define AHB_CLK_DOMAIN_RST                 BIT(28)
+#define RDI_1_CLK_DOMAIN_RST               BIT(27)
+#define PIX_1_CLK_DOMAIN_RST               BIT(26)
+#define RDI_2_CLK_DOMAIN_RST               BIT(25)
+#define RDI_2_MISR_RST_STB                 BIT(20)
+#define RDI_2_VFE_RST_STB                  BIT(19)
+#define RDI_2_CSID_RST_STB                 BIT(18)
+#define RDI_1_MISR_RST_STB                 BIT(14)
+#define RDI_1_VFE_RST_STB                  BIT(13)
+#define RDI_1_CSID_RST_STB                 BIT(12)
+#define PIX_1_VFE_RST_STB                  BIT(10)
+#define PIX_1_CSID_RST_STB                 BIT(9)
+#define RDI_0_MISR_RST_STB                 BIT(8)
+#define RDI_0_VFE_RST_STB                  BIT(7)
+#define RDI_0_CSID_RST_STB                 BIT(6)
+#define PIX_0_MISR_RST_STB                 BIT(5)
+#define PIX_0_VFE_RST_STB                  BIT(4)
+#define PIX_0_CSID_RST_STB                 BIT(3)
+#define SW_REG_RST_STB                     BIT(2)
+#define MISC_LOGIC_RST_STB                 BIT(1)
+#define STROBED_RST_EN                     BIT(0)
+
+#define ISPIF_RST_CMD_MASK              0xFE1C77FF
+#define ISPIF_RST_CMD_1_MASK            0xFFFFFFFF /* undefined */
+
+/* irq_mask_0 */
+#define PIX_INTF_0_OVERFLOW_IRQ            BIT(12)
+#define RAW_INTF_0_OVERFLOW_IRQ            BIT(25)
+#define RESET_DONE_IRQ                     BIT(27)
+/* irq_mask_1 */
+#define PIX_INTF_1_OVERFLOW_IRQ            BIT(12)
+#define RAW_INTF_1_OVERFLOW_IRQ            BIT(25)
+/* irq_mask_2 */
+#define RAW_INTF_2_OVERFLOW_IRQ            BIT(12)
+
+#define ISPIF_IRQ_STATUS_MASK           0x0A493249
+#define ISPIF_IRQ_STATUS_1_MASK         0x02493249
+#define ISPIF_IRQ_STATUS_2_MASK         0x00001249
+
+#define ISPIF_IRQ_STATUS_PIX_SOF_MASK     0x000249
+#define ISPIF_IRQ_STATUS_RDI0_SOF_MASK    0x492000
+#define ISPIF_IRQ_STATUS_RDI1_SOF_MASK    0x492000
+#define ISPIF_IRQ_STATUS_RDI2_SOF_MASK    0x000249
+
+#define ISPIF_IRQ_GLOBAL_CLEAR_CMD        0x000001
+
+#endif /* __MSM_ISPIF_HWREG_V1_H__ */
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v2.h b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v2.h
new file mode 100644
index 0000000..37b19f5
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v2.h
@@ -0,0 +1,98 @@
+/* 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 __MSM_ISPIF_HWREG_V2_H__
+#define __MSM_ISPIF_HWREG_V2_H__
+
+/* common registers */
+#define ISPIF_RST_CMD_ADDR                       0x008
+#define ISPIF_RST_CMD_1_ADDR                     0x00C
+#define ISPIF_INTF_CMD_ADDR                      0x248
+#define ISPIF_INTF_CMD_1_ADDR                    0x24C
+#define ISPIF_CTRL_ADDR                          0x008
+#define ISPIF_INPUT_SEL_ADDR                     0x244
+#define ISPIF_PIX_0_INTF_CID_MASK_ADDR           0x254
+#define ISPIF_RDI_0_INTF_CID_MASK_ADDR           0x264
+#define ISPIF_PIX_1_INTF_CID_MASK_ADDR           0x258
+#define ISPIF_RDI_1_INTF_CID_MASK_ADDR           0x268
+#define ISPIF_RDI_2_INTF_CID_MASK_ADDR           0x26C
+#define ISPIF_PIX_0_STATUS_ADDR                  0x2C0
+#define ISPIF_RDI_0_STATUS_ADDR                  0x2D0
+#define ISPIF_PIX_1_STATUS_ADDR                  0x2C4
+#define ISPIF_RDI_1_STATUS_ADDR                  0x2D4
+#define ISPIF_RDI_2_STATUS_ADDR                  0x2D8
+#define ISPIF_IRQ_MASK_ADDR                      0x208
+#define ISPIF_IRQ_CLEAR_ADDR                     0x230
+#define ISPIF_IRQ_STATUS_ADDR                    0x21C
+#define ISPIF_IRQ_MASK_1_ADDR                    0x20C
+#define ISPIF_IRQ_CLEAR_1_ADDR                   0x234
+#define ISPIF_IRQ_STATUS_1_ADDR                  0x220
+#define ISPIF_IRQ_MASK_2_ADDR                    0x210
+#define ISPIF_IRQ_CLEAR_2_ADDR                   0x238
+#define ISPIF_IRQ_STATUS_2_ADDR                  0x224
+#define ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR          0x01C
+
+/* new */
+#define ISPIF_VFE_m_CTRL_0_ADDR                  0x200
+#define ISPIF_VFE_m_IRQ_MASK_0                   0x208
+#define ISPIF_VFE_m_IRQ_MASK_1                   0x20C
+#define ISPIF_VFE_m_IRQ_MASK_2                   0x210
+#define ISPIF_VFE_m_IRQ_STATUS_0                 0x21C
+#define ISPIF_VFE_m_IRQ_STATUS_1                 0x220
+#define ISPIF_VFE_m_IRQ_STATUS_2                 0x224
+#define ISPIF_VFE_m_IRQ_CLEAR_0                  0x230
+#define ISPIF_VFE_m_IRQ_CLEAR_1                  0x234
+#define ISPIF_VFE_m_IRQ_CLEAR_2                  0x238
+
+/*ISPIF RESET BITS*/
+#define VFE_CLK_DOMAIN_RST                       BIT(31)
+#define PIX_1_CLK_DOMAIN_RST                     BIT(30)
+#define PIX_CLK_DOMAIN_RST                       BIT(29)
+#define RDI_2_CLK_DOMAIN_RST                     BIT(28)
+#define RDI_1_CLK_DOMAIN_RST                     BIT(27)
+#define RDI_CLK_DOMAIN_RST                       BIT(26)
+#define AHB_CLK_DOMAIN_RST                       BIT(25)
+#define RDI_2_VFE_RST_STB                        BIT(12)
+#define RDI_2_CSID_RST_STB                       BIT(11)
+#define RDI_1_VFE_RST_STB                        BIT(10)
+#define RDI_1_CSID_RST_STB                       BIT(9)
+#define RDI_0_VFE_RST_STB                        BIT(8)
+#define RDI_0_CSID_RST_STB                       BIT(7)
+#define PIX_1_VFE_RST_STB                        BIT(6)
+#define PIX_1_CSID_RST_STB                       BIT(5)
+#define PIX_0_VFE_RST_STB                        BIT(4)
+#define PIX_0_CSID_RST_STB                       BIT(3)
+#define SW_REG_RST_STB                           BIT(2)
+#define MISC_LOGIC_RST_STB                       BIT(1)
+#define STROBED_RST_EN                           BIT(0)
+
+#define ISPIF_RST_CMD_MASK                       0xFE0F1FFF
+#define ISPIF_RST_CMD_1_MASK                     0xFC0F1FF9
+
+#define PIX_INTF_0_OVERFLOW_IRQ                  BIT(12)
+#define RAW_INTF_0_OVERFLOW_IRQ                  BIT(25)
+#define RAW_INTF_1_OVERFLOW_IRQ                  BIT(25)
+#define RAW_INTF_2_OVERFLOW_IRQ                  BIT(12)
+#define RESET_DONE_IRQ                           BIT(27)
+
+#define ISPIF_IRQ_STATUS_MASK                    0x0A493249
+#define ISPIF_IRQ_STATUS_1_MASK                  0x02493249
+#define ISPIF_IRQ_STATUS_2_MASK                  0x00001249
+
+#define ISPIF_IRQ_STATUS_PIX_SOF_MASK            0x249
+#define ISPIF_IRQ_STATUS_RDI0_SOF_MASK           0x492000
+#define ISPIF_IRQ_STATUS_RDI1_SOF_MASK           0x492000
+#define ISPIF_IRQ_STATUS_RDI2_SOF_MASK           0x249
+
+#define ISPIF_IRQ_GLOBAL_CLEAR_CMD               0x1
+
+#endif /* __MSM_ISPIF_HWREG_V2_H__ */
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/Makefile b/drivers/media/platform/msm/camera_v2/jpeg_10/Makefile
new file mode 100644
index 0000000..1d3871b
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/Makefile
@@ -0,0 +1,5 @@
+GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
+
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/jpeg_10
+
+obj-$(CONFIG_MSMB_JPEG) += msm_jpeg_dev.o msm_jpeg_sync.o msm_jpeg_core.o msm_jpeg_hw.o msm_jpeg_platform.o
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_common.h b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_common.h
similarity index 100%
rename from drivers/media/video/msm/jpeg_10/msm_jpeg_common.h
rename to drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_common.h
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_core.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_core.c
similarity index 100%
rename from drivers/media/video/msm/jpeg_10/msm_jpeg_core.c
rename to drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_core.c
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_core.h b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_core.h
similarity index 100%
rename from drivers/media/video/msm/jpeg_10/msm_jpeg_core.h
rename to drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_core.h
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_dev.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_dev.c
new file mode 100644
index 0000000..8b96227
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_dev.c
@@ -0,0 +1,297 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <mach/board.h>
+#include <linux/of.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/uaccess.h>
+#include <media/msm_jpeg.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+
+#include "msm_jpeg_sync.h"
+#include "msm_jpeg_common.h"
+
+#define MSM_JPEG_NAME "jpeg"
+#define DEV_NAME_LEN 10
+
+static int msm_jpeg_open(struct inode *inode, struct file *filp)
+{
+	int rc = 0;
+
+	struct msm_jpeg_device *pgmn_dev = container_of(inode->i_cdev,
+		struct msm_jpeg_device, cdev);
+	filp->private_data = pgmn_dev;
+
+	JPEG_DBG("%s:%d]\n", __func__, __LINE__);
+
+	rc = __msm_jpeg_open(pgmn_dev);
+
+	JPEG_DBG(KERN_INFO "%s:%d] %s open_count = %d\n", __func__, __LINE__,
+		filp->f_path.dentry->d_name.name, pgmn_dev->open_count);
+
+	return rc;
+}
+
+static int msm_jpeg_release(struct inode *inode, struct file *filp)
+{
+	int rc;
+
+	struct msm_jpeg_device *pgmn_dev = filp->private_data;
+
+	JPEG_DBG(KERN_INFO "%s:%d]\n", __func__, __LINE__);
+
+	rc = __msm_jpeg_release(pgmn_dev);
+
+	JPEG_DBG(KERN_INFO "%s:%d] %s open_count = %d\n", __func__, __LINE__,
+		filp->f_path.dentry->d_name.name, pgmn_dev->open_count);
+	return rc;
+}
+
+static long msm_jpeg_ioctl(struct file *filp, unsigned int cmd,
+	unsigned long arg)
+{
+	int rc;
+	struct msm_jpeg_device *pgmn_dev = filp->private_data;
+
+	JPEG_DBG("%s:%d] cmd=%d pgmn_dev=0x%x arg=0x%x\n", __func__,
+		__LINE__, _IOC_NR(cmd), (uint32_t)pgmn_dev, (uint32_t)arg);
+
+	rc = __msm_jpeg_ioctl(pgmn_dev, cmd, arg);
+
+	JPEG_DBG("%s:%d]\n", __func__, __LINE__);
+	return rc;
+}
+
+static const struct file_operations msm_jpeg_fops = {
+	.owner		= THIS_MODULE,
+	.open		 = msm_jpeg_open,
+	.release	= msm_jpeg_release,
+	.unlocked_ioctl = msm_jpeg_ioctl,
+};
+
+
+int msm_jpeg_subdev_init(struct v4l2_subdev *jpeg_sd)
+{
+	int rc;
+	struct msm_jpeg_device *pgmn_dev =
+		(struct msm_jpeg_device *)jpeg_sd->host_priv;
+
+	JPEG_DBG("%s:%d: jpeg_sd=0x%x pgmn_dev=0x%x\n",
+		__func__, __LINE__, (uint32_t)jpeg_sd, (uint32_t)pgmn_dev);
+	rc = __msm_jpeg_open(pgmn_dev);
+	JPEG_DBG("%s:%d: rc=%d\n",
+		__func__, __LINE__, rc);
+	return rc;
+}
+
+static long msm_jpeg_subdev_ioctl(struct v4l2_subdev *sd,
+	unsigned int cmd, void *arg)
+{
+	long rc;
+	struct msm_jpeg_device *pgmn_dev =
+		(struct msm_jpeg_device *)sd->host_priv;
+
+	JPEG_DBG("%s: cmd=%d\n", __func__, cmd);
+
+	JPEG_DBG("%s: pgmn_dev 0x%x", __func__, (uint32_t)pgmn_dev);
+
+	JPEG_DBG("%s: Calling __msm_jpeg_ioctl\n", __func__);
+
+	rc = __msm_jpeg_ioctl(pgmn_dev, cmd, (unsigned long)arg);
+	pr_debug("%s: X\n", __func__);
+	return rc;
+}
+
+void msm_jpeg_subdev_release(struct v4l2_subdev *jpeg_sd)
+{
+	int rc;
+	struct msm_jpeg_device *pgmn_dev =
+		(struct msm_jpeg_device *)jpeg_sd->host_priv;
+	JPEG_DBG("%s:pgmn_dev=0x%x", __func__, (uint32_t)pgmn_dev);
+	rc = __msm_jpeg_release(pgmn_dev);
+	JPEG_DBG("%s:rc=%d", __func__, rc);
+}
+
+static const struct v4l2_subdev_core_ops msm_jpeg_subdev_core_ops = {
+	.ioctl = msm_jpeg_subdev_ioctl,
+};
+
+static const struct v4l2_subdev_ops msm_jpeg_subdev_ops = {
+	.core = &msm_jpeg_subdev_core_ops,
+};
+
+static int msm_jpeg_init_dev(struct platform_device *pdev)
+{
+	int rc = -1;
+	struct device *dev;
+	struct msm_jpeg_device *msm_jpeg_device_p;
+	char devname[DEV_NAME_LEN];
+
+	msm_jpeg_device_p = kzalloc(sizeof(struct msm_jpeg_device), GFP_ATOMIC);
+	if (!msm_jpeg_device_p) {
+		JPEG_PR_ERR("%s: no mem\n", __func__);
+		return -EFAULT;
+	}
+
+	msm_jpeg_device_p->pdev = pdev;
+
+	if (pdev->dev.of_node)
+		of_property_read_u32((&pdev->dev)->of_node, "cell-index",
+			&pdev->id);
+
+	snprintf(devname, sizeof(devname), "%s%d", MSM_JPEG_NAME, pdev->id);
+
+	rc = __msm_jpeg_init(msm_jpeg_device_p);
+	if (rc < -1) {
+		JPEG_PR_ERR("%s: initialization failed\n", __func__);
+		goto fail;
+	}
+
+	v4l2_subdev_init(&msm_jpeg_device_p->subdev, &msm_jpeg_subdev_ops);
+	v4l2_set_subdev_hostdata(&msm_jpeg_device_p->subdev, msm_jpeg_device_p);
+	JPEG_DBG("%s: msm_jpeg_device_p 0x%x", __func__,
+			(uint32_t)msm_jpeg_device_p);
+
+	rc = alloc_chrdev_region(&msm_jpeg_device_p->msm_jpeg_devno, 0, 1,
+				devname);
+	if (rc < 0) {
+		JPEG_PR_ERR("%s: failed to allocate chrdev\n", __func__);
+		goto fail_1;
+	}
+
+	if (!msm_jpeg_device_p->msm_jpeg_class) {
+		msm_jpeg_device_p->msm_jpeg_class =
+				class_create(THIS_MODULE, devname);
+		if (IS_ERR(msm_jpeg_device_p->msm_jpeg_class)) {
+			rc = PTR_ERR(msm_jpeg_device_p->msm_jpeg_class);
+			JPEG_PR_ERR("%s: create device class failed\n",
+				__func__);
+			goto fail_2;
+		}
+	}
+
+	dev = device_create(msm_jpeg_device_p->msm_jpeg_class, NULL,
+		MKDEV(MAJOR(msm_jpeg_device_p->msm_jpeg_devno),
+		MINOR(msm_jpeg_device_p->msm_jpeg_devno)), NULL,
+		"%s%d", MSM_JPEG_NAME, pdev->id);
+	if (IS_ERR(dev)) {
+		JPEG_PR_ERR("%s: error creating device\n", __func__);
+		rc = -ENODEV;
+		goto fail_3;
+	}
+
+	cdev_init(&msm_jpeg_device_p->cdev, &msm_jpeg_fops);
+	msm_jpeg_device_p->cdev.owner = THIS_MODULE;
+	msm_jpeg_device_p->cdev.ops	 =
+		(const struct file_operations *) &msm_jpeg_fops;
+	rc = cdev_add(&msm_jpeg_device_p->cdev,
+			msm_jpeg_device_p->msm_jpeg_devno, 1);
+	if (rc < 0) {
+		JPEG_PR_ERR("%s: error adding cdev\n", __func__);
+		rc = -ENODEV;
+		goto fail_4;
+	}
+
+	platform_set_drvdata(pdev, &msm_jpeg_device_p);
+
+	JPEG_DBG("%s %s%d: success\n", __func__, MSM_JPEG_NAME, pdev->id);
+
+	return rc;
+
+fail_4:
+	device_destroy(msm_jpeg_device_p->msm_jpeg_class,
+			msm_jpeg_device_p->msm_jpeg_devno);
+
+fail_3:
+	class_destroy(msm_jpeg_device_p->msm_jpeg_class);
+
+fail_2:
+	unregister_chrdev_region(msm_jpeg_device_p->msm_jpeg_devno, 1);
+
+fail_1:
+	__msm_jpeg_exit(msm_jpeg_device_p);
+
+fail:
+	kfree(msm_jpeg_device_p);
+	return rc;
+
+}
+
+static void msm_jpeg_exit(struct msm_jpeg_device *msm_jpeg_device_p)
+{
+	cdev_del(&msm_jpeg_device_p->cdev);
+	device_destroy(msm_jpeg_device_p->msm_jpeg_class,
+			msm_jpeg_device_p->msm_jpeg_devno);
+	class_destroy(msm_jpeg_device_p->msm_jpeg_class);
+	unregister_chrdev_region(msm_jpeg_device_p->msm_jpeg_devno, 1);
+
+	__msm_jpeg_exit(msm_jpeg_device_p);
+}
+
+static int __msm_jpeg_probe(struct platform_device *pdev)
+{
+	return msm_jpeg_init_dev(pdev);
+}
+
+static int __msm_jpeg_remove(struct platform_device *pdev)
+{
+	struct msm_jpeg_device *msm_jpegd_device_p;
+
+	msm_jpegd_device_p = platform_get_drvdata(pdev);
+	if (msm_jpegd_device_p)
+		msm_jpeg_exit(msm_jpegd_device_p);
+
+	return 0;
+}
+
+static const struct of_device_id msm_jpeg_dt_match[] = {
+			{.compatible = "qcom,jpeg"},
+			{},
+};
+
+MODULE_DEVICE_TABLE(of, msm_jpeg_dt_match);
+
+static struct platform_driver msm_jpeg_driver = {
+	.probe	= __msm_jpeg_probe,
+	.remove = __msm_jpeg_remove,
+	.driver = {
+		.name = "msm_jpeg",
+		.owner = THIS_MODULE,
+		.of_match_table = msm_jpeg_dt_match,
+	},
+};
+
+static int __init msm_jpeg_driver_init(void)
+{
+	int rc;
+	rc = platform_driver_register(&msm_jpeg_driver);
+	return rc;
+}
+
+static void __exit msm_jpeg_driver_exit(void)
+{
+	platform_driver_unregister(&msm_jpeg_driver);
+}
+
+MODULE_DESCRIPTION("msm jpeg jpeg driver");
+
+module_init(msm_jpeg_driver_init);
+module_exit(msm_jpeg_driver_exit);
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw.c
similarity index 100%
rename from drivers/media/video/msm/jpeg_10/msm_jpeg_hw.c
rename to drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw.c
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.h b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw.h
similarity index 100%
rename from drivers/media/video/msm/jpeg_10/msm_jpeg_hw.h
rename to drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw.h
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw_reg.h b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw_reg.h
new file mode 100644
index 0000000..f970c79
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw_reg.h
@@ -0,0 +1,138 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_JPEG_HW_REG_H
+#define MSM_JPEG_HW_REG_H
+
+#define JPEG_REG_BASE 0
+
+#define MSM_JPEG_HW_IRQ_MASK_ADDR 0x00000018
+#define MSM_JPEG_HW_IRQ_MASK_RMSK 0xFFFFFFFF
+#define MSM_JPEG_HW_IRQ_ENABLE 0xFFFFFFFF
+
+#define MSM_JPEG_HW_IRQ_STATUS_FRAMEDONE_MASK 0x00000001
+#define MSM_JPEG_HW_IRQ_STATUS_FRAMEDONE_SHIFT 0x00000000
+
+#define MSM_JPEG_HW_IRQ_STATUS_FE_RD_DONE_MASK 0x00000010
+#define MSM_JPEG_HW_IRQ_STATUS_FE_RD_DONE_SHIFT 0x00000001
+
+#define MSM_JPEG_HW_IRQ_STATUS_FE_RTOVF_MASK 0x00000004
+#define MSM_JPEG_HW_IRQ_STATUS_FE_RTOVF_SHIFT 0x00000002
+
+#define MSM_JPEG_HW_IRQ_STATUS_FE_VFE_OVERFLOW_MASK 0x00000008
+#define MSM_JPEG_HW_IRQ_STATUS_FE_VFE_OVERFLOW_SHIFT 0x00000003
+
+#define MSM_JPEG_HW_IRQ_STATUS_WE_Y_PINGPONG_MASK 0x00000010
+#define MSM_JPEG_HW_IRQ_STATUS_WE_Y_PINGPONG_SHIFT 0x00000004
+
+#define MSM_JPEG_HW_IRQ_STATUS_WE_CBCR_PINGPONG_MASK 0x00000020
+#define MSM_JPEG_HW_IRQ_STATUS_WE_CBCR_PINGPONG_SHIFT 0x00000005
+
+#define MSM_JPEG_HW_IRQ_STATUS_RESET_ACK_MASK 0x10000000
+#define MSM_JPEG_HW_IRQ_STATUS_RESET_ACK_SHIFT 0x0000000a
+
+#define MSM_JPEG_HW_IRQ_STATUS_BUS_ERROR_MASK 0x00000800
+#define MSM_JPEG_HW_IRQ_STATUS_BUS_ERROR_SHIFT 0x0000000b
+
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_UNESCAPED_FF      (0x1<<19)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_HUFFMAN_ERROR     (0x1<<20)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_COEFFICIENT_ERR   (0x1<<21)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_MISSING_BIT_STUFF (0x1<<22)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_SCAN_UNDERFLOW    (0x1<<23)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_INVALID_RSM       (0x1<<24)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_INVALID_RSM_SEQ   (0x1<<25)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_MISSING_RSM       (0x1<<26)
+#define MSM_JPEG_HW_IRQ_STATUS_VIOLATION_MASK        (0x1<<29)
+
+#define JPEG_OFFLINE_CMD_START 0x00000001
+
+#define JPEG_RESET_DEFAULT 0x00020000
+
+#define JPEG_IRQ_DISABLE_ALL 0x00000000
+#define JPEG_IRQ_CLEAR_ALL 0xFFFFFFFF
+
+#define JPEG_PLN0_RD_PNTR_ADDR (JPEG_REG_BASE + 0x00000038)
+#define JPEG_PLN0_RD_PNTR_BMSK  0xFFFFFFFF
+
+#define JPEG_PLN0_RD_OFFSET_ADDR 0x0000003C
+#define JPEG_PLN0_RD_OFFSET_BMSK 0x1FFFFFFF
+
+#define JPEG_PLN1_RD_PNTR_ADDR (JPEG_REG_BASE + 0x00000044)
+#define JPEG_PLN1_RD_PNTR_BMSK 0xFFFFFFFF
+
+#define JPEG_PLN1_RD_OFFSET_ADDR 0x00000048
+#define JPEG_PLN1_RD_OFFSET_BMSK 0x1FFFFFFF
+
+#define JPEG_PLN2_RD_PNTR_ADDR (JPEG_REG_BASE + 0x00000050)
+#define JPEG_PLN2_RD_PNTR_BMSK 0xFFFFFFFF
+
+#define JPEG_PLN2_RD_OFFSET_ADDR 0x00000054
+#define JPEG_PLN2_RD_OFFSET_BMSK 0x1FFFFFFF
+
+#define JPEG_CMD_ADDR (JPEG_REG_BASE + 0x00000010)
+#define JPEG_CMD_BMSK 0x00000FFF
+#define JPEG_CMD_CLEAR_WRITE_PLN_QUEUES 0x700
+
+#define JPEG_PLN0_WR_PNTR_ADDR (JPEG_REG_BASE + 0x000000cc)
+#define JPEG_PLN0_WR_PNTR_BMSK 0xFFFFFFFF
+
+#define JPEG_PLN1_WR_PNTR_ADDR (JPEG_REG_BASE + 0x000000D0)
+#define JPEG_PLN1_WR_PNTR_BMSK 0xFFFFFFFF
+
+#define JPEG_PLN2_WR_PNTR_ADDR (JPEG_REG_BASE + 0x000000D4)
+#define JPEG_PLN2_WR_PNTR_BMSK 0xFFFFFFFF
+
+#define JPEG_IRQ_MASK_ADDR (JPEG_REG_BASE + 0x00000018)
+#define JPEG_IRQ_MASK_BMSK 0xFFFFFFFF
+#define JPEG_IRQ_ALLSOURCES_ENABLE 0xFFFFFFFF
+
+#define JPEG_IRQ_CLEAR_ADDR (JPEG_REG_BASE + 0x0000001c)
+#define JPEG_IRQ_CLEAR_BMSK 0xFFFFFFFF
+
+#define JPEG_RESET_CMD_ADDR (JPEG_REG_BASE + 0x00000008)
+#define JPEG_RESET_CMD_RMSK 0xFFFFFFFF
+
+#define JPEG_IRQ_STATUS_ADDR (JPEG_REG_BASE + 0x00000020)
+#define JPEG_IRQ_STATUS_BMSK 0xFFFFFFFF
+
+#define JPEG_ENCODE_OUTPUT_SIZE_STATUS_ADDR (JPEG_REG_BASE + 0x00000180)
+#define JPEG_ENCODE_OUTPUT_SIZE_STATUS_BMSK 0x1FFFFFFF
+
+#define JPEG_DECODE_MCUS_DECODED_STATUS   (JPEG_REG_BASE + 0x00000258)
+#define JPEG_DECODE_BITS_CONSUMED_STATUS  (JPEG_REG_BASE + 0x0000025C)
+#define JPEG_DECODE_PRED_Y_STATE          (JPEG_REG_BASE + 0x00000260)
+#define JPEG_DECODE_PRED_C_STATE          (JPEG_REG_BASE + 0x00000264)
+#define JPEG_DECODE_RSM_STATE             (JPEG_REG_BASE + 0x00000268)
+
+#define JPEG_HW_VERSION                   (JPEG_REG_BASE + 0x00000000)
+
+#define VBIF_BASE_ADDRESS                      0xFDA60000
+#define VBIF_REGION_SIZE                       0xC30
+#define JPEG_VBIF_CLKON                        0x4
+#define JPEG_VBIF_IN_RD_LIM_CONF0              0xB0
+#define JPEG_VBIF_IN_RD_LIM_CONF1              0xB4
+#define JPEG_VBIF_IN_RD_LIM_CONF2              0xB8
+#define JPEG_VBIF_IN_WR_LIM_CONF0              0xC0
+#define JPEG_VBIF_IN_WR_LIM_CONF1              0xC4
+#define JPEG_VBIF_IN_WR_LIM_CONF2              0xC8
+#define JPEG_VBIF_OUT_RD_LIM_CONF0             0xD0
+#define JPEG_VBIF_OUT_WR_LIM_CONF0             0xD4
+#define JPEG_VBIF_DDR_OUT_MAX_BURST            0xD8
+#define JPEG_VBIF_OCMEM_OUT_MAX_BURST          0xDC
+#define JPEG_VBIF_ARB_CTL                      0xF0
+#define JPEG_VBIF_OUT_AXI_AOOO_EN              0x178
+#define JPEG_VBIF_OUT_AXI_AOOO                 0x17c
+#define JPEG_VBIF_ROUND_ROBIN_QOS_ARB          0x124
+#define JPEG_VBIF_OUT_AXI_AMEMTYPE_CONF0       0x160
+#define JPEG_VBIF_OUT_AXI_AMEMTYPE_CONF1       0x164
+
+#endif /* MSM_JPEG_HW_REG_H */
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
new file mode 100644
index 0000000..0eb0a23
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.c
@@ -0,0 +1,344 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+
+
+#include <linux/module.h>
+#include <linux/pm_qos.h>
+#include <linux/clk.h>
+#include <mach/clk.h>
+#include <linux/io.h>
+#include <linux/android_pmem.h>
+#include <mach/camera.h>
+#include <mach/iommu_domains.h>
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
+
+#include "msm_jpeg_platform.h"
+#include "msm_jpeg_sync.h"
+#include "msm_jpeg_common.h"
+#include "msm_jpeg_hw.h"
+
+void msm_jpeg_platform_p2v(struct msm_jpeg_device *pgmn_dev, struct file  *file,
+	struct ion_handle **ionhandle, int domain_num)
+{
+	ion_unmap_iommu(pgmn_dev->jpeg_client, *ionhandle, domain_num, 0);
+	ion_free(pgmn_dev->jpeg_client, *ionhandle);
+	*ionhandle = NULL;
+}
+
+uint32_t msm_jpeg_platform_v2p(struct msm_jpeg_device *pgmn_dev, int fd,
+	uint32_t len, struct file **file_p, struct ion_handle **ionhandle,
+	int domain_num) {
+	unsigned long paddr;
+	unsigned long size;
+	int rc;
+	*ionhandle = ion_import_dma_buf(pgmn_dev->jpeg_client, fd);
+	if (IS_ERR_OR_NULL(*ionhandle))
+		return 0;
+
+	rc = ion_map_iommu(pgmn_dev->jpeg_client, *ionhandle, domain_num, 0,
+		SZ_4K, 0, &paddr, (unsigned long *)&size, 0, 0);
+	JPEG_DBG("%s:%d] addr 0x%x size %ld", __func__, __LINE__,
+		(uint32_t)paddr, size);
+
+	if (rc < 0) {
+		JPEG_PR_ERR("%s: ion_map_iommu fd %d error %d\n", __func__, fd,
+			rc);
+		goto error1;
+	}
+
+	/* validate user input */
+	if (len > size) {
+		JPEG_PR_ERR("%s: invalid offset + len\n", __func__);
+		goto error1;
+	}
+
+	return paddr;
+error1:
+	ion_free(pgmn_dev->jpeg_client, *ionhandle);
+	return 0;
+}
+
+static struct msm_cam_clk_info jpeg_8x_clk_info[] = {
+	{"core_clk", 228570000},
+	{"iface_clk", -1},
+	{"bus_clk0", -1},
+	{"alt_bus_clk", -1},
+	{"camss_top_ahb_clk", -1},
+};
+
+static void set_vbif_params(struct msm_jpeg_device *pgmn_dev,
+	 void *jpeg_vbif_base)
+{
+	writel_relaxed(0x1,
+		jpeg_vbif_base + JPEG_VBIF_CLKON);
+	writel_relaxed(0x10101010,
+		jpeg_vbif_base + JPEG_VBIF_IN_RD_LIM_CONF0);
+	writel_relaxed(0x10101010,
+		jpeg_vbif_base + JPEG_VBIF_IN_RD_LIM_CONF1);
+	writel_relaxed(0x10101010,
+		jpeg_vbif_base + JPEG_VBIF_IN_RD_LIM_CONF2);
+	writel_relaxed(0x10101010,
+		jpeg_vbif_base + JPEG_VBIF_IN_WR_LIM_CONF0);
+	writel_relaxed(0x10101010,
+		jpeg_vbif_base + JPEG_VBIF_IN_WR_LIM_CONF1);
+	writel_relaxed(0x10101010,
+		jpeg_vbif_base + JPEG_VBIF_IN_WR_LIM_CONF2);
+	writel_relaxed(0x00001010,
+		jpeg_vbif_base + JPEG_VBIF_OUT_RD_LIM_CONF0);
+	writel_relaxed(0x00000110,
+		jpeg_vbif_base + JPEG_VBIF_OUT_WR_LIM_CONF0);
+	writel_relaxed(0x00000707,
+		jpeg_vbif_base + JPEG_VBIF_DDR_OUT_MAX_BURST);
+	writel_relaxed(0x7,
+		jpeg_vbif_base + JPEG_VBIF_OCMEM_OUT_MAX_BURST);
+	writel_relaxed(0x00000030,
+		jpeg_vbif_base + JPEG_VBIF_ARB_CTL);
+	writel_relaxed(0x00000FFF,
+		jpeg_vbif_base + JPEG_VBIF_OUT_AXI_AOOO_EN);
+	writel_relaxed(0x0FFF0FFF,
+		jpeg_vbif_base + JPEG_VBIF_OUT_AXI_AOOO);
+	/*FE and WE QOS configuration need to be set when
+	QOS RR arbitration is enabled*/
+	if (pgmn_dev->hw_version == JPEG_8974_V2)
+		writel_relaxed(0x00000003,
+				jpeg_vbif_base + JPEG_VBIF_ROUND_ROBIN_QOS_ARB);
+	else
+		writel_relaxed(0x00000001,
+				jpeg_vbif_base + JPEG_VBIF_ROUND_ROBIN_QOS_ARB);
+
+	writel_relaxed(0x22222222,
+		jpeg_vbif_base + JPEG_VBIF_OUT_AXI_AMEMTYPE_CONF0);
+	writel_relaxed(0x2222,
+		jpeg_vbif_base + JPEG_VBIF_OUT_AXI_AMEMTYPE_CONF1);
+}
+
+static struct msm_bus_vectors msm_jpeg_init_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_JPEG,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+};
+
+static struct msm_bus_vectors msm_jpeg_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_JPEG,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 1027648000,
+		.ib  = 1105920000,
+	},
+};
+
+static struct msm_bus_paths msm_jpeg_bus_client_config[] = {
+	{
+		ARRAY_SIZE(msm_jpeg_init_vectors),
+		msm_jpeg_init_vectors,
+	},
+	{
+		ARRAY_SIZE(msm_jpeg_vectors),
+		msm_jpeg_vectors,
+	},
+};
+
+static struct msm_bus_scale_pdata msm_jpeg_bus_client_pdata = {
+	msm_jpeg_bus_client_config,
+	ARRAY_SIZE(msm_jpeg_bus_client_config),
+	.name = "msm_jpeg",
+};
+
+int msm_jpeg_platform_init(struct platform_device *pdev,
+	struct resource **mem,
+	void **base,
+	int *irq,
+	irqreturn_t (*handler) (int, void *),
+	void *context)
+{
+	int rc = -1;
+	int i = 0;
+	int jpeg_irq;
+	struct resource *jpeg_mem, *jpeg_io, *jpeg_irq_res;
+	void *jpeg_base;
+	struct msm_jpeg_device *pgmn_dev =
+		(struct msm_jpeg_device *) context;
+
+	jpeg_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!jpeg_mem) {
+		JPEG_PR_ERR("%s: no mem resource?\n", __func__);
+		return -ENODEV;
+	}
+
+	jpeg_irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!jpeg_irq_res) {
+		JPEG_PR_ERR("no irq resource?\n");
+		return -ENODEV;
+	}
+	jpeg_irq = jpeg_irq_res->start;
+	JPEG_DBG("%s base address: 0x%x, jpeg irq number: %d\n", __func__,
+		jpeg_mem->start, jpeg_irq);
+
+	pgmn_dev->jpeg_bus_client =
+		msm_bus_scale_register_client(&msm_jpeg_bus_client_pdata);
+	if (!pgmn_dev->jpeg_bus_client) {
+		JPEG_PR_ERR("%s: Registration Failed!\n", __func__);
+		pgmn_dev->jpeg_bus_client = 0;
+		return -EINVAL;
+	}
+	msm_bus_scale_client_update_request(
+		pgmn_dev->jpeg_bus_client, 1);
+
+	jpeg_io = request_mem_region(jpeg_mem->start,
+		resource_size(jpeg_mem), pdev->name);
+	if (!jpeg_io) {
+		JPEG_PR_ERR("%s: region already claimed\n", __func__);
+		return -EBUSY;
+	}
+
+	jpeg_base = ioremap(jpeg_mem->start, resource_size(jpeg_mem));
+	if (!jpeg_base) {
+		rc = -ENOMEM;
+		JPEG_PR_ERR("%s: ioremap failed\n", __func__);
+		goto fail_remap;
+	}
+
+	pgmn_dev->jpeg_fs = regulator_get(&pgmn_dev->pdev->dev, "vdd");
+	rc = regulator_enable(pgmn_dev->jpeg_fs);
+	if (rc) {
+		JPEG_PR_ERR("%s:%d]jpeg regulator get failed\n",
+				__func__, __LINE__);
+		goto fail_fs;
+	}
+
+	rc = msm_cam_clk_enable(&pgmn_dev->pdev->dev, jpeg_8x_clk_info,
+	 pgmn_dev->jpeg_clk, ARRAY_SIZE(jpeg_8x_clk_info), 1);
+	if (rc < 0) {
+		JPEG_PR_ERR("%s: clk failed rc = %d\n", __func__, rc);
+		goto fail_clk;
+	}
+
+	pgmn_dev->hw_version = readl_relaxed(jpeg_base +
+		JPEG_HW_VERSION);
+	JPEG_DBG_HIGH("%s:%d] jpeg HW version 0x%x", __func__, __LINE__,
+		pgmn_dev->hw_version);
+
+	pgmn_dev->jpeg_vbif = ioremap(VBIF_BASE_ADDRESS, VBIF_REGION_SIZE);
+	if (!pgmn_dev->jpeg_vbif) {
+		rc = -ENOMEM;
+		JPEG_PR_ERR("%s:%d] ioremap failed\n", __func__, __LINE__);
+		goto fail_vbif;
+	}
+	JPEG_DBG("%s:%d] jpeg_vbif 0x%x", __func__, __LINE__,
+		(uint32_t)pgmn_dev->jpeg_vbif);
+
+#ifdef CONFIG_MSM_IOMMU
+	for (i = 0; i < pgmn_dev->iommu_cnt; i++) {
+		rc = iommu_attach_device(pgmn_dev->domain,
+				pgmn_dev->iommu_ctx_arr[i]);
+		if (rc < 0) {
+			rc = -ENODEV;
+			JPEG_PR_ERR("%s: Device attach failed\n", __func__);
+			goto fail_iommu;
+		}
+		JPEG_DBG("%s:%d] dom 0x%x ctx 0x%x", __func__, __LINE__,
+					(uint32_t)pgmn_dev->domain,
+					(uint32_t)pgmn_dev->iommu_ctx_arr[i]);
+	}
+#endif
+	set_vbif_params(pgmn_dev, pgmn_dev->jpeg_vbif);
+
+	rc = request_irq(jpeg_irq, handler, IRQF_TRIGGER_RISING, "jpeg",
+		context);
+	if (rc) {
+		JPEG_PR_ERR("%s: request_irq failed, %d\n", __func__,
+			jpeg_irq);
+		goto fail_request_irq;
+	}
+
+	*mem  = jpeg_mem;
+	*base = jpeg_base;
+	*irq  = jpeg_irq;
+
+	pgmn_dev->jpeg_client = msm_ion_client_create(-1, "camera/jpeg");
+	JPEG_DBG("%s:%d] success\n", __func__, __LINE__);
+
+	return rc;
+
+fail_request_irq:
+#ifdef CONFIG_MSM_IOMMU
+	for (i = 0; i < pgmn_dev->iommu_cnt; i++) {
+		JPEG_PR_ERR("%s:%d] dom 0x%x ctx 0x%x", __func__, __LINE__,
+					(uint32_t)pgmn_dev->domain,
+					(uint32_t)pgmn_dev->iommu_ctx_arr[i]);
+		iommu_detach_device(pgmn_dev->domain,
+					pgmn_dev->iommu_ctx_arr[i]);
+	}
+#endif
+
+fail_iommu:
+	iounmap(pgmn_dev->jpeg_vbif);
+
+fail_vbif:
+	msm_cam_clk_enable(&pgmn_dev->pdev->dev, jpeg_8x_clk_info,
+	pgmn_dev->jpeg_clk, ARRAY_SIZE(jpeg_8x_clk_info), 0);
+
+fail_clk:
+	regulator_put(pgmn_dev->jpeg_fs);
+	regulator_disable(pgmn_dev->jpeg_fs);
+	pgmn_dev->jpeg_fs = NULL;
+
+fail_fs:
+	iounmap(jpeg_base);
+
+fail_remap:
+	release_mem_region(jpeg_mem->start, resource_size(jpeg_mem));
+	JPEG_DBG("%s:%d] fail\n", __func__, __LINE__);
+	return rc;
+}
+
+int msm_jpeg_platform_release(struct resource *mem, void *base, int irq,
+	void *context)
+{
+	int result = 0;
+	int i = 0;
+	struct msm_jpeg_device *pgmn_dev =
+		(struct msm_jpeg_device *) context;
+
+	free_irq(irq, context);
+
+#ifdef CONFIG_MSM_IOMMU
+	for (i = 0; i < pgmn_dev->iommu_cnt; i++) {
+		iommu_detach_device(pgmn_dev->domain,
+				pgmn_dev->iommu_ctx_arr[i]);
+		JPEG_DBG("%s:%d]", __func__, __LINE__);
+	}
+#endif
+
+	msm_bus_scale_unregister_client(pgmn_dev->jpeg_bus_client);
+	msm_cam_clk_enable(&pgmn_dev->pdev->dev, jpeg_8x_clk_info,
+	pgmn_dev->jpeg_clk, ARRAY_SIZE(jpeg_8x_clk_info), 0);
+	JPEG_DBG("%s:%d] clock disbale done", __func__, __LINE__);
+
+	if (pgmn_dev->jpeg_fs) {
+		regulator_put(pgmn_dev->jpeg_fs);
+		regulator_disable(pgmn_dev->jpeg_fs);
+		pgmn_dev->jpeg_fs = NULL;
+	}
+	iounmap(pgmn_dev->jpeg_vbif);
+	iounmap(base);
+	release_mem_region(mem->start, resource_size(mem));
+	ion_client_destroy(pgmn_dev->jpeg_client);
+	JPEG_DBG("%s:%d] success\n", __func__, __LINE__);
+	return result;
+}
+
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.h b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.h
similarity index 100%
rename from drivers/media/video/msm/jpeg_10/msm_jpeg_platform.h
rename to drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.h
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
new file mode 100644
index 0000000..15b4b25
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
@@ -0,0 +1,948 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/uaccess.h>
+#include <linux/slab.h>
+#include <media/msm_jpeg.h>
+#include "msm_jpeg_sync.h"
+#include "msm_jpeg_core.h"
+#include "msm_jpeg_platform.h"
+#include "msm_jpeg_common.h"
+
+#define JPEG_REG_SIZE 0x308
+#define JPEG_DEV_CNT 3
+#define JPEG_DEC_ID 2
+
+inline void msm_jpeg_q_init(char const *name, struct msm_jpeg_q *q_p)
+{
+	JPEG_DBG("%s:%d] %s\n", __func__, __LINE__, name);
+	q_p->name = name;
+	spin_lock_init(&q_p->lck);
+	INIT_LIST_HEAD(&q_p->q);
+	init_waitqueue_head(&q_p->wait);
+	q_p->unblck = 0;
+}
+
+inline void *msm_jpeg_q_out(struct msm_jpeg_q *q_p)
+{
+	unsigned long flags;
+	struct msm_jpeg_q_entry *q_entry_p = NULL;
+	void *data = NULL;
+
+	JPEG_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
+	spin_lock_irqsave(&q_p->lck, flags);
+	if (!list_empty(&q_p->q)) {
+		q_entry_p = list_first_entry(&q_p->q, struct msm_jpeg_q_entry,
+			list);
+		list_del_init(&q_entry_p->list);
+	}
+	spin_unlock_irqrestore(&q_p->lck, flags);
+
+	if (q_entry_p) {
+		data = q_entry_p->data;
+		kfree(q_entry_p);
+	} else {
+		JPEG_DBG("%s:%d] %s no entry\n", __func__, __LINE__,
+			q_p->name);
+	}
+
+	return data;
+}
+
+inline int msm_jpeg_q_in(struct msm_jpeg_q *q_p, void *data)
+{
+	unsigned long flags;
+
+	struct msm_jpeg_q_entry *q_entry_p;
+
+	JPEG_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
+
+	q_entry_p = kmalloc(sizeof(struct msm_jpeg_q_entry), GFP_ATOMIC);
+	if (!q_entry_p) {
+		JPEG_PR_ERR("%s: no mem\n", __func__);
+		return -EFAULT;
+	}
+	q_entry_p->data = data;
+
+	spin_lock_irqsave(&q_p->lck, flags);
+	list_add_tail(&q_entry_p->list, &q_p->q);
+	spin_unlock_irqrestore(&q_p->lck, flags);
+
+	return 0;
+}
+
+inline int msm_jpeg_q_in_buf(struct msm_jpeg_q *q_p,
+	struct msm_jpeg_core_buf *buf)
+{
+	struct msm_jpeg_core_buf *buf_p;
+
+	JPEG_DBG("%s:%d]\n", __func__, __LINE__);
+	buf_p = kmalloc(sizeof(struct msm_jpeg_core_buf), GFP_ATOMIC);
+	if (!buf_p) {
+		JPEG_PR_ERR("%s: no mem\n", __func__);
+		return -EFAULT;
+	}
+
+	memcpy(buf_p, buf, sizeof(struct msm_jpeg_core_buf));
+
+	msm_jpeg_q_in(q_p, buf_p);
+	return 0;
+}
+
+inline int msm_jpeg_q_wait(struct msm_jpeg_q *q_p)
+{
+	int tm = MAX_SCHEDULE_TIMEOUT; /* 500ms */
+	int rc;
+
+	JPEG_DBG("%s:%d] %s wait\n", __func__, __LINE__, q_p->name);
+	rc = wait_event_interruptible_timeout(q_p->wait,
+		(!list_empty_careful(&q_p->q) || q_p->unblck),
+		msecs_to_jiffies(tm));
+	JPEG_DBG("%s:%d] %s wait done\n", __func__, __LINE__, q_p->name);
+	if (list_empty_careful(&q_p->q)) {
+		if (rc == 0) {
+			rc = -ETIMEDOUT;
+			JPEG_PR_ERR("%s:%d] %s timeout\n", __func__, __LINE__,
+				q_p->name);
+		} else if (q_p->unblck) {
+			JPEG_DBG("%s:%d] %s unblock is true\n", __func__,
+				__LINE__, q_p->name);
+			q_p->unblck = 0;
+			rc = -ECANCELED;
+		} else if (rc < 0) {
+			JPEG_PR_ERR("%s:%d] %s rc %d\n", __func__, __LINE__,
+				q_p->name, rc);
+		}
+	}
+	return rc;
+}
+
+inline int msm_jpeg_q_wakeup(struct msm_jpeg_q *q_p)
+{
+	JPEG_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
+	wake_up(&q_p->wait);
+	return 0;
+}
+
+inline int msm_jpeg_q_unblock(struct msm_jpeg_q *q_p)
+{
+	JPEG_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
+	q_p->unblck = 1;
+	wake_up(&q_p->wait);
+	return 0;
+}
+
+inline void msm_jpeg_outbuf_q_cleanup(struct msm_jpeg_device *pgmn_dev,
+	struct msm_jpeg_q *q_p, int domain_num)
+{
+	struct msm_jpeg_core_buf *buf_p;
+	JPEG_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
+	do {
+		buf_p = msm_jpeg_q_out(q_p);
+		if (buf_p) {
+			msm_jpeg_platform_p2v(pgmn_dev, buf_p->file,
+				&buf_p->handle, domain_num);
+			JPEG_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
+			kfree(buf_p);
+		}
+	} while (buf_p);
+	q_p->unblck = 0;
+}
+
+inline void msm_jpeg_q_cleanup(struct msm_jpeg_q *q_p)
+{
+	void *data;
+	JPEG_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
+	do {
+		data = msm_jpeg_q_out(q_p);
+		if (data) {
+			JPEG_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
+			kfree(data);
+		}
+	} while (data);
+	q_p->unblck = 0;
+}
+
+/*************** event queue ****************/
+
+int msm_jpeg_framedone_irq(struct msm_jpeg_device *pgmn_dev,
+	struct msm_jpeg_core_buf *buf_in)
+{
+	int rc = 0;
+
+	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
+
+	if (buf_in) {
+		buf_in->vbuf.framedone_len = buf_in->framedone_len;
+		buf_in->vbuf.type = MSM_JPEG_EVT_SESSION_DONE;
+		JPEG_DBG("%s:%d] 0x%08x %d framedone_len %d\n",
+			__func__, __LINE__,
+			(int) buf_in->y_buffer_addr, buf_in->y_len,
+			buf_in->vbuf.framedone_len);
+		rc = msm_jpeg_q_in_buf(&pgmn_dev->evt_q, buf_in);
+	} else {
+		JPEG_PR_ERR("%s:%d] no output return buffer\n",
+			__func__, __LINE__);
+		rc = -1;
+	}
+
+	if (buf_in)
+		rc = msm_jpeg_q_wakeup(&pgmn_dev->evt_q);
+
+	return rc;
+}
+
+int msm_jpeg_evt_get(struct msm_jpeg_device *pgmn_dev,
+	void __user *to)
+{
+	struct msm_jpeg_core_buf *buf_p;
+	struct msm_jpeg_ctrl_cmd ctrl_cmd;
+
+	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
+
+	msm_jpeg_q_wait(&pgmn_dev->evt_q);
+	buf_p = msm_jpeg_q_out(&pgmn_dev->evt_q);
+
+	if (!buf_p) {
+		JPEG_DBG("%s:%d] no buffer\n", __func__, __LINE__);
+		return -EAGAIN;
+	}
+
+	ctrl_cmd.type = buf_p->vbuf.type;
+	kfree(buf_p);
+
+	JPEG_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
+		(int) ctrl_cmd.value, ctrl_cmd.len);
+
+	if (copy_to_user(to, &ctrl_cmd, sizeof(ctrl_cmd))) {
+		JPEG_PR_ERR("%s:%d]\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+int msm_jpeg_evt_get_unblock(struct msm_jpeg_device *pgmn_dev)
+{
+	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
+	msm_jpeg_q_unblock(&pgmn_dev->evt_q);
+	return 0;
+}
+
+void msm_jpeg_reset_ack_irq(struct msm_jpeg_device *pgmn_dev)
+{
+	JPEG_DBG("%s:%d]\n", __func__, __LINE__);
+}
+
+void msm_jpeg_err_irq(struct msm_jpeg_device *pgmn_dev,
+	int event)
+{
+	int rc = 0;
+	struct msm_jpeg_core_buf buf;
+
+	JPEG_PR_ERR("%s:%d] error: %d\n", __func__, __LINE__, event);
+
+	buf.vbuf.type = MSM_JPEG_EVT_ERR;
+	rc = msm_jpeg_q_in_buf(&pgmn_dev->evt_q, &buf);
+	if (!rc)
+		rc = msm_jpeg_q_wakeup(&pgmn_dev->evt_q);
+
+	if (!rc)
+		JPEG_PR_ERR("%s:%d] err err\n", __func__, __LINE__);
+
+	return;
+}
+
+/*************** output queue ****************/
+
+int msm_jpeg_we_pingpong_irq(struct msm_jpeg_device *pgmn_dev,
+	struct msm_jpeg_core_buf *buf_in)
+{
+	int rc = 0;
+	struct msm_jpeg_core_buf *buf_out;
+
+	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
+	if (buf_in) {
+		JPEG_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
+			(int) buf_in->y_buffer_addr, buf_in->y_len);
+		rc = msm_jpeg_q_in_buf(&pgmn_dev->output_rtn_q, buf_in);
+	} else {
+		JPEG_DBG("%s:%d] no output return buffer\n", __func__,
+			__LINE__);
+		rc = -1;
+		return rc;
+	}
+
+	buf_out = msm_jpeg_q_out(&pgmn_dev->output_buf_q);
+
+	if (buf_out) {
+		JPEG_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
+			(int) buf_out->y_buffer_addr, buf_out->y_len);
+		rc = msm_jpeg_core_we_buf_update(pgmn_dev, buf_out);
+		kfree(buf_out);
+	} else {
+		msm_jpeg_core_we_buf_reset(pgmn_dev, buf_in);
+		JPEG_DBG("%s:%d] no output buffer\n", __func__, __LINE__);
+		rc = -2;
+	}
+
+	if (buf_in)
+		rc = msm_jpeg_q_wakeup(&pgmn_dev->output_rtn_q);
+
+	return rc;
+}
+
+int msm_jpeg_output_get(struct msm_jpeg_device *pgmn_dev, void __user *to)
+{
+	struct msm_jpeg_core_buf *buf_p;
+	struct msm_jpeg_buf buf_cmd;
+
+	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
+
+	msm_jpeg_q_wait(&pgmn_dev->output_rtn_q);
+	buf_p = msm_jpeg_q_out(&pgmn_dev->output_rtn_q);
+
+	if (!buf_p) {
+		JPEG_DBG("%s:%d] no output buffer return\n",
+			__func__, __LINE__);
+		return -EAGAIN;
+	}
+
+	buf_cmd = buf_p->vbuf;
+	msm_jpeg_platform_p2v(pgmn_dev, buf_p->file, &buf_p->handle,
+		pgmn_dev->domain_num);
+	kfree(buf_p);
+
+	JPEG_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
+		(int) buf_cmd.vaddr, buf_cmd.y_len);
+
+	if (copy_to_user(to, &buf_cmd, sizeof(buf_cmd))) {
+		JPEG_PR_ERR("%s:%d]", __func__, __LINE__);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+int msm_jpeg_output_get_unblock(struct msm_jpeg_device *pgmn_dev)
+{
+	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
+	msm_jpeg_q_unblock(&pgmn_dev->output_rtn_q);
+	return 0;
+}
+
+int msm_jpeg_output_buf_enqueue(struct msm_jpeg_device *pgmn_dev,
+	void __user *arg)
+{
+	struct msm_jpeg_buf buf_cmd;
+	struct msm_jpeg_core_buf *buf_p;
+	memset(&buf_cmd, 0x0, sizeof(struct msm_jpeg_buf));
+
+	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
+	if (copy_from_user(&buf_cmd, arg, sizeof(struct msm_jpeg_buf))) {
+		JPEG_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+
+	buf_p = kmalloc(sizeof(struct msm_jpeg_core_buf), GFP_ATOMIC);
+	if (!buf_p) {
+		JPEG_PR_ERR("%s:%d] no mem\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+
+	JPEG_DBG("%s:%d] vaddr = 0x%08x y_len = %d\n, fd = %d",
+		__func__, __LINE__, (int) buf_cmd.vaddr, buf_cmd.y_len,
+		buf_cmd.fd);
+
+	buf_p->y_buffer_addr = msm_jpeg_platform_v2p(pgmn_dev, buf_cmd.fd,
+		buf_cmd.y_len + buf_cmd.cbcr_len + buf_cmd.pln2_len,
+		&buf_p->file, &buf_p->handle, pgmn_dev->domain_num);
+	if (!buf_p->y_buffer_addr) {
+		JPEG_PR_ERR("%s:%d] v2p wrong\n", __func__, __LINE__);
+		kfree(buf_p);
+		return -EFAULT;
+	}
+
+	if (buf_cmd.cbcr_len)
+		buf_p->cbcr_buffer_addr = buf_p->y_buffer_addr +
+			buf_cmd.y_len;
+	else
+		buf_p->cbcr_buffer_addr = 0x0;
+
+	if (buf_cmd.pln2_len)
+		buf_p->pln2_addr = buf_p->cbcr_buffer_addr +
+			buf_cmd.cbcr_len;
+	else
+		buf_p->pln2_addr = 0x0;
+
+	JPEG_DBG("%s:%d]After v2p pln0_addr %x pln0_len %d",
+		__func__, __LINE__, buf_p->y_buffer_addr,
+		buf_cmd.y_len);
+
+	JPEG_DBG("pl1_len %d, pln1_addr %x, pln2_adrr %x,pln2_len %d",
+		buf_cmd.cbcr_len, buf_p->cbcr_buffer_addr,
+		buf_p->pln2_addr, buf_cmd.pln2_len);
+
+	buf_p->y_len = buf_cmd.y_len;
+	buf_p->cbcr_len = buf_cmd.cbcr_len;
+	buf_p->pln2_len = buf_cmd.pln2_len;
+	buf_p->vbuf = buf_cmd;
+
+	msm_jpeg_q_in(&pgmn_dev->output_buf_q, buf_p);
+	return 0;
+}
+
+/*************** input queue ****************/
+
+int msm_jpeg_fe_pingpong_irq(struct msm_jpeg_device *pgmn_dev,
+	struct msm_jpeg_core_buf *buf_in)
+{
+	struct msm_jpeg_core_buf *buf_out;
+	int rc = 0;
+
+	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
+	if (buf_in) {
+		JPEG_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
+			(int) buf_in->y_buffer_addr, buf_in->y_len);
+		rc = msm_jpeg_q_in_buf(&pgmn_dev->input_rtn_q, buf_in);
+	} else {
+		JPEG_DBG("%s:%d] no input return buffer\n", __func__,
+			__LINE__);
+		rc = -EFAULT;
+	}
+
+	buf_out = msm_jpeg_q_out(&pgmn_dev->input_buf_q);
+
+	if (buf_out) {
+		rc = msm_jpeg_core_fe_buf_update(pgmn_dev, buf_out);
+		kfree(buf_out);
+		msm_jpeg_core_fe_start(pgmn_dev);
+	} else {
+		JPEG_DBG("%s:%d] no input buffer\n", __func__, __LINE__);
+		rc = -EFAULT;
+	}
+
+	if (buf_in)
+		rc = msm_jpeg_q_wakeup(&pgmn_dev->input_rtn_q);
+
+	return rc;
+}
+
+int msm_jpeg_input_get(struct msm_jpeg_device *pgmn_dev, void __user *to)
+{
+	struct msm_jpeg_core_buf *buf_p;
+	struct msm_jpeg_buf buf_cmd;
+
+	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
+	msm_jpeg_q_wait(&pgmn_dev->input_rtn_q);
+	buf_p = msm_jpeg_q_out(&pgmn_dev->input_rtn_q);
+
+	if (!buf_p) {
+		JPEG_DBG("%s:%d] no input buffer return\n",
+			__func__, __LINE__);
+		return -EAGAIN;
+	}
+
+	buf_cmd = buf_p->vbuf;
+	msm_jpeg_platform_p2v(pgmn_dev, buf_p->file, &buf_p->handle,
+		pgmn_dev->domain_num);
+	kfree(buf_p);
+
+	JPEG_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
+		(int) buf_cmd.vaddr, buf_cmd.y_len);
+
+	if (copy_to_user(to, &buf_cmd, sizeof(buf_cmd))) {
+		JPEG_PR_ERR("%s:%d]\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+int msm_jpeg_input_get_unblock(struct msm_jpeg_device *pgmn_dev)
+{
+	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
+	msm_jpeg_q_unblock(&pgmn_dev->input_rtn_q);
+	return 0;
+}
+
+int msm_jpeg_input_buf_enqueue(struct msm_jpeg_device *pgmn_dev,
+	void __user *arg)
+{
+	struct msm_jpeg_core_buf *buf_p;
+	struct msm_jpeg_buf buf_cmd;
+	memset(&buf_cmd, 0x0, sizeof(struct msm_jpeg_buf));
+
+	if (copy_from_user(&buf_cmd, arg, sizeof(struct msm_jpeg_buf))) {
+		JPEG_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+
+	buf_p = kmalloc(sizeof(struct msm_jpeg_core_buf), GFP_ATOMIC);
+	if (!buf_p) {
+		JPEG_PR_ERR("%s:%d] no mem\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+
+	JPEG_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
+		(int) buf_cmd.vaddr, buf_cmd.y_len);
+
+	buf_p->y_buffer_addr    = msm_jpeg_platform_v2p(pgmn_dev, buf_cmd.fd,
+		buf_cmd.y_len + buf_cmd.cbcr_len + buf_cmd.pln2_len,
+		&buf_p->file, &buf_p->handle, pgmn_dev->domain_num) +
+		buf_cmd.offset + buf_cmd.y_off;
+	buf_p->y_len          = buf_cmd.y_len;
+	buf_p->cbcr_len       = buf_cmd.cbcr_len;
+	buf_p->pln2_len       = buf_cmd.pln2_len;
+	buf_p->num_of_mcu_rows = buf_cmd.num_of_mcu_rows;
+
+	if (buf_cmd.cbcr_len)
+		buf_p->cbcr_buffer_addr = buf_p->y_buffer_addr +
+		buf_cmd.y_len + buf_cmd.cbcr_off;
+	else
+		buf_p->cbcr_buffer_addr = 0x0;
+
+	if (buf_cmd.pln2_len)
+		buf_p->pln2_addr = buf_p->cbcr_buffer_addr +
+		buf_cmd.cbcr_len + buf_cmd.pln2_off;
+	else
+		buf_p->pln2_addr = 0x0;
+
+	JPEG_DBG("%s: y_addr=%x, y_len=%x, cbcr_addr=%x, cbcr_len=%d",
+		__func__, buf_p->y_buffer_addr, buf_p->y_len,
+		buf_p->cbcr_buffer_addr, buf_p->cbcr_len);
+	JPEG_DBG("pln2_addr = %x, pln2_len = %d, fd =%d\n",
+		buf_p->pln2_addr, buf_p->pln2_len, buf_cmd.fd);
+
+	if (!buf_p->y_buffer_addr) {
+		JPEG_PR_ERR("%s:%d] v2p wrong\n", __func__, __LINE__);
+		kfree(buf_p);
+		return -EFAULT;
+	}
+	buf_p->vbuf           = buf_cmd;
+
+	msm_jpeg_q_in(&pgmn_dev->input_buf_q, buf_p);
+
+	return 0;
+}
+
+int msm_jpeg_irq(int event, void *context, void *data)
+{
+	struct msm_jpeg_device *pgmn_dev =
+		(struct msm_jpeg_device *) context;
+
+	switch (event) {
+	case MSM_JPEG_EVT_SESSION_DONE:
+		msm_jpeg_framedone_irq(pgmn_dev, data);
+		msm_jpeg_we_pingpong_irq(pgmn_dev, data);
+		break;
+
+	case MSM_JPEG_HW_MASK_COMP_FE:
+		msm_jpeg_fe_pingpong_irq(pgmn_dev, data);
+		break;
+
+	case MSM_JPEG_HW_MASK_COMP_WE:
+		msm_jpeg_we_pingpong_irq(pgmn_dev, data);
+		break;
+
+	case MSM_JPEG_HW_MASK_COMP_RESET_ACK:
+		msm_jpeg_reset_ack_irq(pgmn_dev);
+		break;
+
+	case MSM_JPEG_HW_MASK_COMP_ERR:
+	default:
+		msm_jpeg_err_irq(pgmn_dev, event);
+		break;
+	}
+
+	return 0;
+}
+
+int __msm_jpeg_open(struct msm_jpeg_device *pgmn_dev)
+{
+	int rc;
+
+	mutex_lock(&pgmn_dev->lock);
+	if (pgmn_dev->open_count) {
+		/* only open once */
+		JPEG_PR_ERR("%s:%d] busy\n", __func__, __LINE__);
+		mutex_unlock(&pgmn_dev->lock);
+		return -EBUSY;
+	}
+	pgmn_dev->open_count++;
+	mutex_unlock(&pgmn_dev->lock);
+
+	msm_jpeg_core_irq_install(msm_jpeg_irq);
+	rc = msm_jpeg_platform_init(pgmn_dev->pdev,
+		&pgmn_dev->mem, &pgmn_dev->base,
+		&pgmn_dev->irq, msm_jpeg_core_irq, pgmn_dev);
+	if (rc) {
+		JPEG_PR_ERR("%s:%d] platform_init fail %d\n", __func__,
+			__LINE__, rc);
+		return rc;
+	}
+
+	JPEG_DBG("%s:%d] platform resources - mem %p, base %p, irq %d\n",
+		__func__, __LINE__,
+		pgmn_dev->mem, pgmn_dev->base, pgmn_dev->irq);
+	pgmn_dev->res_size = resource_size(pgmn_dev->mem);
+
+	msm_jpeg_q_cleanup(&pgmn_dev->evt_q);
+	msm_jpeg_q_cleanup(&pgmn_dev->output_rtn_q);
+	msm_jpeg_outbuf_q_cleanup(pgmn_dev, &pgmn_dev->output_buf_q,
+		pgmn_dev->domain_num);
+	msm_jpeg_q_cleanup(&pgmn_dev->input_rtn_q);
+	msm_jpeg_q_cleanup(&pgmn_dev->input_buf_q);
+	msm_jpeg_core_init(pgmn_dev);
+
+	JPEG_DBG("%s:%d] success\n", __func__, __LINE__);
+	return rc;
+}
+
+int __msm_jpeg_release(struct msm_jpeg_device *pgmn_dev)
+{
+	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
+	mutex_lock(&pgmn_dev->lock);
+	if (!pgmn_dev->open_count) {
+		JPEG_PR_ERR(KERN_ERR "%s: not opened\n", __func__);
+		mutex_unlock(&pgmn_dev->lock);
+		return -EINVAL;
+	}
+	pgmn_dev->open_count--;
+	mutex_unlock(&pgmn_dev->lock);
+
+	msm_jpeg_core_release(pgmn_dev, pgmn_dev->domain_num);
+	msm_jpeg_q_cleanup(&pgmn_dev->evt_q);
+	msm_jpeg_q_cleanup(&pgmn_dev->output_rtn_q);
+	msm_jpeg_outbuf_q_cleanup(pgmn_dev, &pgmn_dev->output_buf_q,
+		pgmn_dev->domain_num);
+	msm_jpeg_q_cleanup(&pgmn_dev->input_rtn_q);
+	msm_jpeg_outbuf_q_cleanup(pgmn_dev, &pgmn_dev->input_buf_q,
+		pgmn_dev->domain_num);
+
+	JPEG_DBG("%s:%d]\n", __func__, __LINE__);
+	if (pgmn_dev->open_count)
+		JPEG_PR_ERR(KERN_ERR "%s: multiple opens\n", __func__);
+
+	msm_jpeg_platform_release(pgmn_dev->mem, pgmn_dev->base,
+		pgmn_dev->irq, pgmn_dev);
+
+	JPEG_DBG("%s:%d]\n", __func__, __LINE__);
+	return 0;
+}
+
+int msm_jpeg_ioctl_hw_cmd(struct msm_jpeg_device *pgmn_dev,
+	void * __user arg)
+{
+	struct msm_jpeg_hw_cmd hw_cmd;
+	int is_copy_to_user;
+
+	if (copy_from_user(&hw_cmd, arg, sizeof(struct msm_jpeg_hw_cmd))) {
+		JPEG_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+
+	is_copy_to_user = msm_jpeg_hw_exec_cmds(&hw_cmd, 1,
+		pgmn_dev->res_size, pgmn_dev->base);
+	JPEG_DBG("%s:%d] type %d, n %d, offset %d, mask %x, data %x,pdata %x\n",
+		__func__, __LINE__, hw_cmd.type, hw_cmd.n, hw_cmd.offset,
+		hw_cmd.mask, hw_cmd.data, (int) hw_cmd.pdata);
+
+	if (is_copy_to_user >= 0) {
+		if (copy_to_user(arg, &hw_cmd, sizeof(hw_cmd))) {
+			JPEG_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
+			return -EFAULT;
+		}
+	}
+
+	return 0;
+}
+
+int msm_jpeg_ioctl_hw_cmds(struct msm_jpeg_device *pgmn_dev,
+	void * __user arg)
+{
+	int is_copy_to_user;
+	int len;
+	uint32_t m;
+	struct msm_jpeg_hw_cmds *hw_cmds_p;
+	struct msm_jpeg_hw_cmd *hw_cmd_p;
+
+	if (copy_from_user(&m, arg, sizeof(m))) {
+		JPEG_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+
+	len = sizeof(struct msm_jpeg_hw_cmds) +
+		sizeof(struct msm_jpeg_hw_cmd) * (m - 1);
+	hw_cmds_p = kmalloc(len, GFP_KERNEL);
+	if (!hw_cmds_p) {
+		JPEG_PR_ERR("%s:%d] no mem %d\n", __func__, __LINE__, len);
+		return -EFAULT;
+	}
+
+	if (copy_from_user(hw_cmds_p, arg, len)) {
+		JPEG_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
+		kfree(hw_cmds_p);
+		return -EFAULT;
+	}
+
+	hw_cmd_p = (struct msm_jpeg_hw_cmd *) &(hw_cmds_p->hw_cmd);
+
+	is_copy_to_user = msm_jpeg_hw_exec_cmds(hw_cmd_p, m,
+		 pgmn_dev->res_size, pgmn_dev->base);
+
+	if (is_copy_to_user >= 0) {
+		if (copy_to_user(arg, hw_cmds_p, len)) {
+			JPEG_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
+			kfree(hw_cmds_p);
+			return -EFAULT;
+		}
+	}
+	kfree(hw_cmds_p);
+	return 0;
+}
+
+int msm_jpeg_start(struct msm_jpeg_device *pgmn_dev, void * __user arg)
+{
+	struct msm_jpeg_core_buf *buf_out;
+	struct msm_jpeg_core_buf *buf_out_free[2] = {NULL, NULL};
+	int i, rc;
+
+	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
+
+	pgmn_dev->release_buf = 1;
+	for (i = 0; i < 2; i++) {
+		buf_out = msm_jpeg_q_out(&pgmn_dev->input_buf_q);
+
+		if (buf_out) {
+			msm_jpeg_core_fe_buf_update(pgmn_dev, buf_out);
+			kfree(buf_out);
+		} else {
+			JPEG_DBG("%s:%d] no input buffer\n", __func__,
+					__LINE__);
+			break;
+		}
+	}
+
+	for (i = 0; i < 2; i++) {
+		buf_out_free[i] = msm_jpeg_q_out(&pgmn_dev->output_buf_q);
+
+		if (buf_out_free[i]) {
+			msm_jpeg_core_we_buf_update(pgmn_dev, buf_out_free[i]);
+			pgmn_dev->release_buf = 0;
+		} else {
+			JPEG_DBG("%s:%d] no output buffer\n",
+			__func__, __LINE__);
+			break;
+		}
+	}
+
+	for (i = 0; i < 2; i++)
+		kfree(buf_out_free[i]);
+
+	JPEG_DBG_HIGH("%s:%d] START\n", __func__, __LINE__);
+	wmb();
+	rc = msm_jpeg_ioctl_hw_cmds(pgmn_dev, arg);
+	wmb();
+	JPEG_DBG("%s:%d]", __func__, __LINE__);
+	return rc;
+}
+
+int msm_jpeg_ioctl_reset(struct msm_jpeg_device *pgmn_dev,
+	void * __user arg)
+{
+	int rc;
+	struct msm_jpeg_ctrl_cmd ctrl_cmd;
+
+	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
+	if (copy_from_user(&ctrl_cmd, arg, sizeof(ctrl_cmd))) {
+		JPEG_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+
+	pgmn_dev->op_mode = ctrl_cmd.type;
+
+	rc = msm_jpeg_core_reset(pgmn_dev, pgmn_dev->op_mode, pgmn_dev->base,
+		resource_size(pgmn_dev->mem));
+	return rc;
+}
+
+int msm_jpeg_ioctl_test_dump_region(struct msm_jpeg_device *pgmn_dev,
+	unsigned long arg)
+{
+	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
+	msm_jpeg_io_dump(pgmn_dev->base, JPEG_REG_SIZE);
+	return 0;
+}
+
+long __msm_jpeg_ioctl(struct msm_jpeg_device *pgmn_dev,
+	unsigned int cmd, unsigned long arg)
+{
+	int rc = 0;
+	switch (cmd) {
+	case MSM_JPEG_IOCTL_GET_HW_VERSION:
+		JPEG_DBG("%s:%d] VERSION 1\n", __func__, __LINE__);
+		rc = msm_jpeg_ioctl_hw_cmd(pgmn_dev, (void __user *) arg);
+		break;
+
+	case MSM_JPEG_IOCTL_RESET:
+		rc = msm_jpeg_ioctl_reset(pgmn_dev, (void __user *) arg);
+		break;
+
+	case MSM_JPEG_IOCTL_STOP:
+		rc = msm_jpeg_ioctl_hw_cmds(pgmn_dev, (void __user *) arg);
+		break;
+
+	case MSM_JPEG_IOCTL_START:
+		rc = msm_jpeg_start(pgmn_dev, (void __user *) arg);
+		break;
+
+	case MSM_JPEG_IOCTL_INPUT_BUF_ENQUEUE:
+		rc = msm_jpeg_input_buf_enqueue(pgmn_dev,
+			(void __user *) arg);
+		break;
+
+	case MSM_JPEG_IOCTL_INPUT_GET:
+		rc = msm_jpeg_input_get(pgmn_dev, (void __user *) arg);
+		break;
+
+	case MSM_JPEG_IOCTL_INPUT_GET_UNBLOCK:
+		rc = msm_jpeg_input_get_unblock(pgmn_dev);
+		break;
+
+	case MSM_JPEG_IOCTL_OUTPUT_BUF_ENQUEUE:
+		rc = msm_jpeg_output_buf_enqueue(pgmn_dev,
+			(void __user *) arg);
+		break;
+
+	case MSM_JPEG_IOCTL_OUTPUT_GET:
+		rc = msm_jpeg_output_get(pgmn_dev, (void __user *) arg);
+		break;
+
+	case MSM_JPEG_IOCTL_OUTPUT_GET_UNBLOCK:
+		rc = msm_jpeg_output_get_unblock(pgmn_dev);
+		break;
+
+	case MSM_JPEG_IOCTL_EVT_GET:
+		rc = msm_jpeg_evt_get(pgmn_dev, (void __user *) arg);
+		break;
+
+	case MSM_JPEG_IOCTL_EVT_GET_UNBLOCK:
+		rc = msm_jpeg_evt_get_unblock(pgmn_dev);
+		break;
+
+	case MSM_JPEG_IOCTL_HW_CMD:
+		rc = msm_jpeg_ioctl_hw_cmd(pgmn_dev, (void __user *) arg);
+		break;
+
+	case MSM_JPEG_IOCTL_HW_CMDS:
+		rc = msm_jpeg_ioctl_hw_cmds(pgmn_dev, (void __user *) arg);
+		break;
+
+	case MSM_JPEG_IOCTL_TEST_DUMP_REGION:
+		rc = msm_jpeg_ioctl_test_dump_region(pgmn_dev, arg);
+		break;
+
+	default:
+		JPEG_PR_ERR(KERN_INFO "%s:%d] cmd = %d not supported\n",
+			__func__, __LINE__, _IOC_NR(cmd));
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
+static int camera_register_domain(void)
+{
+	struct msm_iova_partition camera_fw_partition = {
+		.start = SZ_128K,
+		.size = SZ_2G - SZ_128K,
+	};
+
+	struct msm_iova_layout camera_fw_layout = {
+		.partitions = &camera_fw_partition,
+		.npartitions = 1,
+		.client_name = "camera_jpeg",
+		.domain_flags = 0,
+	};
+	return msm_register_domain(&camera_fw_layout);
+}
+
+int __msm_jpeg_init(struct msm_jpeg_device *pgmn_dev)
+{
+	int rc = 0, i = 0, j = 0;
+	int idx = 0;
+	char *iommu_name[JPEG_DEV_CNT] = {"jpeg_enc0", "jpeg_enc1",
+		"jpeg_dec"};
+
+	mutex_init(&pgmn_dev->lock);
+
+	pr_err("%s:%d] Jpeg Device id %d", __func__, __LINE__,
+		   pgmn_dev->pdev->id);
+	idx = pgmn_dev->pdev->id;
+	pgmn_dev->idx = idx;
+	pgmn_dev->iommu_cnt = 1;
+	pgmn_dev->decode_flag = (idx == JPEG_DEC_ID);
+
+	msm_jpeg_q_init("evt_q", &pgmn_dev->evt_q);
+	msm_jpeg_q_init("output_rtn_q", &pgmn_dev->output_rtn_q);
+	msm_jpeg_q_init("output_buf_q", &pgmn_dev->output_buf_q);
+	msm_jpeg_q_init("input_rtn_q", &pgmn_dev->input_rtn_q);
+	msm_jpeg_q_init("input_buf_q", &pgmn_dev->input_buf_q);
+
+#ifdef CONFIG_MSM_IOMMU
+	j = (pgmn_dev->iommu_cnt <= 1) ? idx : 0;
+	/*get device context for IOMMU*/
+	for (i = 0; i < pgmn_dev->iommu_cnt; i++) {
+		pgmn_dev->iommu_ctx_arr[i] = msm_iommu_get_ctx(iommu_name[j]);
+		JPEG_DBG("%s:%d] name %s", __func__, __LINE__, iommu_name[j]);
+		JPEG_DBG("%s:%d] ctx 0x%x", __func__, __LINE__,
+			(uint32_t)pgmn_dev->iommu_ctx_arr[i]);
+		if (!pgmn_dev->iommu_ctx_arr[i]) {
+			JPEG_PR_ERR("%s: No iommu fw context found\n",
+					__func__);
+			goto error;
+		}
+		j++;
+	}
+	pgmn_dev->domain_num = camera_register_domain();
+	JPEG_DBG("%s:%d] dom_num 0x%x", __func__, __LINE__,
+		pgmn_dev->domain_num);
+	if (pgmn_dev->domain_num < 0) {
+		JPEG_PR_ERR("%s: could not register domain\n", __func__);
+		goto error;
+	}
+	pgmn_dev->domain = msm_get_iommu_domain(pgmn_dev->domain_num);
+	JPEG_DBG("%s:%d] dom 0x%x", __func__, __LINE__,
+					(uint32_t)pgmn_dev->domain);
+	if (!pgmn_dev->domain) {
+		JPEG_PR_ERR("%s: cannot find domain\n", __func__);
+		goto error;
+	}
+#endif
+
+	return rc;
+error:
+	mutex_destroy(&pgmn_dev->lock);
+	return -EFAULT;
+}
+
+int __msm_jpeg_exit(struct msm_jpeg_device *pgmn_dev)
+{
+	mutex_destroy(&pgmn_dev->lock);
+	kfree(pgmn_dev);
+	return 0;
+}
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.h b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.h
new file mode 100644
index 0000000..be889cd
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.h
@@ -0,0 +1,112 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+
+
+#ifndef MSM_JPEG_SYNC_H
+#define MSM_JPEG_SYNC_H
+
+#include <linux/fs.h>
+#include <linux/list.h>
+#include <linux/cdev.h>
+#include <linux/platform_device.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+#include "msm_jpeg_hw.h"
+
+#define JPEG_8974_V1 0x10000000
+#define JPEG_8974_V2 0x10010000
+
+struct msm_jpeg_q {
+	char const	*name;
+	struct list_head  q;
+	spinlock_t	lck;
+	wait_queue_head_t wait;
+	int	       unblck;
+};
+
+struct msm_jpeg_q_entry {
+	struct list_head list;
+	void   *data;
+};
+
+struct msm_jpeg_device {
+	struct platform_device *pdev;
+	struct resource        *mem;
+	int                     irq;
+	void                   *base;
+	struct clk *jpeg_clk[5];
+	struct regulator *jpeg_fs;
+	uint32_t hw_version;
+
+	struct device *device;
+	struct cdev   cdev;
+	struct mutex  lock;
+	char	  open_count;
+	uint8_t       op_mode;
+
+	/* event queue including frame done & err indications
+	 */
+	struct msm_jpeg_q evt_q;
+
+	/* output return queue
+	 */
+	struct msm_jpeg_q output_rtn_q;
+
+	/* output buf queue
+	 */
+	struct msm_jpeg_q output_buf_q;
+
+	/* input return queue
+	 */
+	struct msm_jpeg_q input_rtn_q;
+
+	/* input buf queue
+	 */
+	struct msm_jpeg_q input_buf_q;
+
+	struct v4l2_subdev subdev;
+
+	struct class *msm_jpeg_class;
+
+	dev_t msm_jpeg_devno;
+
+	/*iommu domain and context*/
+	int domain_num;
+	int idx;
+	struct iommu_domain *domain;
+	struct device *iommu_ctx_arr[3];
+	int iommu_cnt;
+	int decode_flag;
+	struct ion_client *jpeg_client;
+	void *jpeg_vbif;
+	int release_buf;
+	struct msm_jpeg_hw_pingpong fe_pingpong_buf;
+	struct msm_jpeg_hw_pingpong we_pingpong_buf;
+	int we_pingpong_index;
+	int reset_done_ack;
+	spinlock_t reset_lock;
+	wait_queue_head_t reset_wait;
+	uint32_t res_size;
+	uint32_t jpeg_bus_client;
+};
+
+int __msm_jpeg_open(struct msm_jpeg_device *pgmn_dev);
+int __msm_jpeg_release(struct msm_jpeg_device *pgmn_dev);
+
+long __msm_jpeg_ioctl(struct msm_jpeg_device *pgmn_dev,
+	unsigned int cmd, unsigned long arg);
+
+int __msm_jpeg_init(struct msm_jpeg_device *pgmn_dev);
+int __msm_jpeg_exit(struct msm_jpeg_device *pgmn_dev);
+
+#endif /* MSM_JPEG_SYNC_H */
diff --git a/drivers/media/platform/msm/camera_v2/msm.c b/drivers/media/platform/msm/camera_v2/msm.c
new file mode 100644
index 0000000..6974cb4
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/msm.c
@@ -0,0 +1,1046 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/of.h>
+#include <linux/module.h>
+#include <linux/workqueue.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/ioctl.h>
+#include <linux/spinlock.h>
+#include <linux/proc_fs.h>
+#include <linux/atomic.h>
+#include <linux/wait.h>
+#include <linux/videodev2.h>
+#include <linux/msm_ion.h>
+#include <linux/iommu.h>
+#include <linux/platform_device.h>
+#include <media/v4l2-fh.h>
+#include "msm.h"
+#include "msm_vb2.h"
+#include "msm_sd.h"
+
+struct msm_queue_head {
+	struct list_head list;
+	spinlock_t lock;
+	int len;
+	int max;
+};
+
+/** msm_event:
+ *
+ *  event sent by imaging server
+ **/
+struct msm_event {
+	struct video_device *vdev;
+	atomic_t on_heap;
+};
+
+struct msm_command {
+	struct list_head list;
+	struct v4l2_event event;
+	atomic_t on_heap;
+};
+
+/** struct msm_command_ack
+ *
+ *  Object of command_ack_q, which is
+ *  created per open operation
+ *
+ *  contains struct msm_command
+ **/
+struct msm_command_ack {
+	struct list_head list;
+	struct msm_queue_head command_q;
+	wait_queue_head_t wait;
+	int stream_id;
+};
+
+struct msm_v4l2_subdev {
+	/* FIXME: for session close and error handling such
+	 * as daemon shutdown */
+	int    close_sequence;
+};
+
+struct msm_session {
+	struct list_head list;
+
+	/* session index */
+	unsigned int session_id;
+
+	/* event queue sent by imaging server */
+	struct msm_event event_q;
+
+	/* ACK by imaging server. Object type of
+	 * struct msm_command_ack per open,
+	 * assumption is application can send
+	 * command on every opened video node */
+	struct msm_queue_head command_ack_q;
+
+	/* real streams(either data or metadate) owned by one
+	 * session struct msm_stream */
+	struct msm_queue_head stream_q;
+};
+
+static struct v4l2_device *msm_v4l2_dev;
+
+static struct msm_queue_head *msm_session_q;
+
+/* config node envent queue */
+static struct v4l2_fh  *msm_eventq;
+spinlock_t msm_eventq_lock;
+
+static struct pid *msm_pid;
+spinlock_t msm_pid_lock;
+
+#define msm_dequeue(queue, type, member) ({				\
+	unsigned long flags;					\
+	struct msm_queue_head *__q = (queue);			\
+	type *node = 0;				\
+	spin_lock_irqsave(&__q->lock, flags);			\
+	if (!list_empty(&__q->list)) {				\
+		__q->len--;					\
+		node = list_first_entry(&__q->list,		\
+				type, member);	\
+		if ((node) && (&node->member) && (&node->member.next))	\
+			list_del_init(&node->member);			\
+	}							\
+	spin_unlock_irqrestore(&__q->lock, flags);	\
+	node;							\
+})
+
+#define msm_delete_sd_entry(queue, type, member, q_node) ({		\
+	unsigned long flags;					\
+	struct msm_queue_head *__q = (queue);			\
+	type *node = 0;				\
+	spin_lock_irqsave(&__q->lock, flags);			\
+	if (!list_empty(&__q->list)) {				\
+		list_for_each_entry(node, &__q->list, member)	\
+		if (node->sd == q_node) {				\
+			__q->len--;				\
+			list_del_init(&node->member);		\
+			kfree(node);				\
+			break;					\
+		}						\
+	}							\
+	spin_unlock_irqrestore(&__q->lock, flags);		\
+})
+
+#define msm_delete_entry(queue, type, member, q_node) ({		\
+	unsigned long flags;					\
+	struct msm_queue_head *__q = (queue);			\
+	type *node = 0;				\
+	spin_lock_irqsave(&__q->lock, flags);			\
+	if (!list_empty(&__q->list)) {				\
+		list_for_each_entry(node, &__q->list, member)	\
+		if (node == q_node) {				\
+			__q->len--;				\
+			list_del_init(&node->member);		\
+			kfree(node);				\
+			break;					\
+		}						\
+	}							\
+	spin_unlock_irqrestore(&__q->lock, flags);		\
+})
+
+#define msm_queue_drain(queue, type, member) do {			\
+	unsigned long flags;					\
+	struct msm_queue_head *__q = (queue);			\
+	type *node;				\
+	spin_lock_irqsave(&__q->lock, flags);			\
+	while (!list_empty(&__q->list)) {			\
+		__q->len--;					\
+		node = list_first_entry(&__q->list,		\
+			type, member);		\
+		if (node) {					\
+			if (&node->member) \
+				list_del_init(&node->member);		\
+			kfree(node);	\
+		}	\
+	}	\
+	spin_unlock_irqrestore(&__q->lock, flags);		\
+} while (0);
+
+typedef int (*msm_queue_func)(void *d1, void *d2);
+#define msm_queue_traverse_action(queue, type, member, func, data) do {\
+	unsigned long flags;					\
+	struct msm_queue_head *__q = (queue);			\
+	type *node = 0; \
+	msm_queue_func __f = (func); \
+	spin_lock_irqsave(&__q->lock, flags);			\
+	if (!list_empty(&__q->list)) { \
+		list_for_each_entry(node, &__q->list, member) \
+		if (node && __f)  { \
+			__f(node, data); \
+	  } \
+	} \
+	spin_unlock_irqrestore(&__q->lock, flags);			\
+} while (0)
+
+typedef int (*msm_queue_find_func)(void *d1, void *d2);
+#define msm_queue_find(queue, type, member, func, data) ({\
+	unsigned long flags;					\
+	struct msm_queue_head *__q = (queue);			\
+	type *node = 0; \
+	typeof(node) __ret = NULL; \
+	msm_queue_find_func __f = (func); \
+	spin_lock_irqsave(&__q->lock, flags);			\
+	if (!list_empty(&__q->list)) { \
+		list_for_each_entry(node, &__q->list, member) \
+		if ((__f) && __f(node, data)) { \
+			__ret = node; \
+		  break; \
+		} \
+	} \
+	spin_unlock_irqrestore(&__q->lock, flags); \
+	__ret; \
+})
+
+static void msm_init_queue(struct msm_queue_head *qhead)
+{
+	BUG_ON(!qhead);
+
+	INIT_LIST_HEAD(&qhead->list);
+	spin_lock_init(&qhead->lock);
+	qhead->len = 0;
+	qhead->max = 0;
+}
+
+static void msm_enqueue(struct msm_queue_head *qhead,
+		struct list_head *entry)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&qhead->lock, flags);
+	qhead->len++;
+	if (qhead->len > qhead->max)
+		qhead->max = qhead->len;
+	list_add_tail(entry, &qhead->list);
+	spin_unlock_irqrestore(&qhead->lock, flags);
+}
+
+/* index = session id */
+static inline int __msm_queue_find_session(void *d1, void *d2)
+{
+	struct msm_session *session = d1;
+	return (session->session_id == *(unsigned int *)d2) ? 1 : 0;
+}
+
+static inline int __msm_queue_find_stream(void *d1, void *d2)
+{
+	struct msm_stream *stream = d1;
+	return (stream->stream_id == *(unsigned int *)d2) ? 1 : 0;
+}
+
+static inline int __msm_queue_find_command_ack_q(void *d1, void *d2)
+{
+	struct msm_command_ack *ack = d1;
+	return (ack->stream_id == *(unsigned int *)d2) ? 1 : 0;
+}
+
+int msm_create_stream(unsigned int session_id,
+	unsigned int stream_id, struct vb2_queue *q)
+{
+	struct msm_session *session;
+	struct msm_stream  *stream;
+
+	session = msm_queue_find(msm_session_q, struct msm_session,
+		list, __msm_queue_find_session, &session_id);
+	if (!session)
+		return -EINVAL;
+
+	stream = kzalloc(sizeof(*stream), GFP_KERNEL);
+	if (!stream)
+		return -ENOMEM;
+
+	stream->stream_id = stream_id;
+	stream->vb2_q = q;
+	spin_lock_init(&stream->stream_lock);
+	msm_enqueue(&session->stream_q, &stream->list);
+	session->stream_q.len++;
+
+	return 0;
+}
+
+void msm_delete_stream(unsigned int session_id, unsigned int stream_id)
+{
+	struct msm_session *session = NULL;
+	struct msm_stream  *stream = NULL;
+
+	session = msm_queue_find(msm_session_q, struct msm_session,
+		list, __msm_queue_find_session, &session_id);
+	if (!session)
+		return;
+
+	stream = msm_queue_find(&session->stream_q, struct msm_stream,
+		list, __msm_queue_find_stream, &stream_id);
+	if (!stream)
+		return;
+
+	list_del_init(&stream->list);
+	session->stream_q.len--;
+	kfree(stream);
+}
+
+static void msm_sd_unregister_subdev(struct video_device *vdev)
+{
+	struct v4l2_subdev *sd = video_get_drvdata(vdev);
+	sd->devnode = NULL;
+	kfree(vdev);
+}
+
+static inline int __msm_sd_register_subdev(struct v4l2_subdev *sd)
+{
+	int rc = 0;
+	struct video_device *vdev;
+
+	if (!msm_v4l2_dev || !sd || !sd->name[0])
+		return -EINVAL;
+
+	rc = v4l2_device_register_subdev(msm_v4l2_dev, sd);
+	if (rc < 0)
+		return rc;
+
+	/* Register a device node for every subdev marked with the
+	 * V4L2_SUBDEV_FL_HAS_DEVNODE flag.
+	 */
+	if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE))
+		return rc;
+
+	vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
+	if (!vdev) {
+		rc = -ENOMEM;
+		goto clean_up;
+	}
+
+	video_set_drvdata(vdev, sd);
+	strlcpy(vdev->name, sd->name, sizeof(vdev->name));
+	vdev->v4l2_dev = msm_v4l2_dev;
+	vdev->fops = &v4l2_subdev_fops;
+	vdev->release = msm_sd_unregister_subdev;
+	rc = __video_register_device(vdev, VFL_TYPE_SUBDEV, -1, 1,
+		  sd->owner);
+	if (rc < 0) {
+		kfree(vdev);
+		goto clean_up;
+	}
+
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	sd->entity.info.v4l.major = VIDEO_MAJOR;
+	sd->entity.info.v4l.minor = vdev->minor;
+	sd->entity.name = video_device_node_name(vdev);
+#endif
+	sd->devnode = vdev;
+	return 0;
+
+clean_up:
+	if (sd->devnode)
+		video_unregister_device(sd->devnode);
+	return rc;
+}
+
+int msm_sd_register(struct msm_sd_subdev *msm_subdev)
+{
+	if (WARN_ON(!msm_subdev))
+		return -EINVAL;
+
+	if (WARN_ON(!msm_v4l2_dev) && WARN_ON(!msm_v4l2_dev->dev))
+		return -EIO;
+
+	return __msm_sd_register_subdev(&msm_subdev->sd);
+}
+
+int msm_sd_unregister(struct msm_sd_subdev *msm_subdev)
+{
+	if (WARN_ON(!msm_subdev))
+		return -EINVAL;
+
+	v4l2_device_unregister_subdev(&msm_subdev->sd);
+	return 0;
+}
+
+int msm_create_session(unsigned int session_id, struct video_device *vdev)
+{
+	struct msm_session *session = NULL;
+
+	if (!msm_session_q)
+		return -ENODEV;
+
+	session = msm_queue_find(msm_session_q, struct msm_session,
+		list, __msm_queue_find_session, &session_id);
+	if (session)
+		return -EINVAL;
+
+	session = kzalloc(sizeof(*session), GFP_KERNEL);
+	if (!session)
+		return -ENOMEM;
+
+	session->session_id = session_id;
+	session->event_q.vdev = vdev;
+	msm_init_queue(&session->command_ack_q);
+	msm_init_queue(&session->stream_q);
+	msm_enqueue(msm_session_q, &session->list);
+	return 0;
+}
+
+int msm_create_command_ack_q(unsigned int session_id, unsigned int stream_id)
+{
+	struct msm_session *session;
+	struct msm_command_ack *cmd_ack;
+
+	if (!msm_session_q)
+		return -ENODEV;
+
+	session = msm_queue_find(msm_session_q, struct msm_session,
+		list, __msm_queue_find_session, &session_id);
+	if (!session)
+		return -EINVAL;
+
+	cmd_ack = kzalloc(sizeof(*cmd_ack), GFP_KERNEL);
+	if (!cmd_ack)
+		return -ENOMEM;
+
+	msm_init_queue(&cmd_ack->command_q);
+	INIT_LIST_HEAD(&cmd_ack->list);
+	init_waitqueue_head(&cmd_ack->wait);
+	cmd_ack->stream_id = stream_id;
+
+	msm_enqueue(&session->command_ack_q, &cmd_ack->list);
+	session->command_ack_q.len++;
+
+	return 0;
+}
+
+void msm_delete_command_ack_q(unsigned int session_id, unsigned int stream_id)
+{
+	struct msm_session *session;
+	struct msm_command_ack *cmd_ack;
+
+	session = msm_queue_find(msm_session_q, struct msm_session,
+		list, __msm_queue_find_session, &session_id);
+	if (!session)
+		return;
+
+	cmd_ack = msm_queue_find(&session->command_ack_q,
+		struct msm_command_ack,	list, __msm_queue_find_command_ack_q,
+		&stream_id);
+	if (!cmd_ack)
+		return;
+
+	msm_queue_drain(&cmd_ack->command_q, struct msm_command, list);
+}
+
+static inline int __msm_v4l2_subdev_shutdown(struct v4l2_subdev *sd)
+{
+	return 0;
+}
+
+static void msm_sd_try_shutdown(void)
+{
+	unsigned long flags;
+	struct v4l2_subdev *sd;
+
+	/* release all subdev's resource */
+	spin_lock_irqsave(&msm_v4l2_dev->lock, flags);
+	if (!list_empty(&msm_v4l2_dev->subdevs)) {
+		list_for_each_entry(sd, &msm_v4l2_dev->subdevs, list)
+			__msm_v4l2_subdev_shutdown(sd);
+	}
+	spin_unlock_irqrestore(&msm_v4l2_dev->lock, flags);
+}
+
+static inline int __msm_sd_close_session_streams(struct v4l2_subdev *sd,
+	struct msm_sd_close_ioctl *sd_close)
+{
+	return 0;
+}
+
+static inline int __msm_destroy_session_streams(void *d1, void *d2)
+{
+	struct msm_stream *stream = d1;
+	struct msm_sd_close_ioctl *sd_close = d2;
+	struct v4l2_subdev *sd;
+	unsigned long flags;
+
+	sd_close->stream = stream->stream_id;
+
+	spin_lock_irqsave(&msm_v4l2_dev->lock, flags);
+	if (!list_empty(&msm_v4l2_dev->subdevs))
+		list_for_each_entry(sd, &msm_v4l2_dev->subdevs, list)
+			__msm_sd_close_session_streams(sd, sd_close);
+	spin_unlock_irqrestore(&msm_v4l2_dev->lock, flags);
+
+	return 0;
+}
+
+static void msm_destroy_session_streams(struct msm_session *session)
+{
+	struct msm_sd_close_ioctl sd_close;
+
+	/* to ensure error handling purpose, it needs to detach all subdevs
+	 * which are being connected to streams */
+	if (!session)
+		return;
+
+	sd_close.session = session->session_id;
+
+	msm_queue_traverse_action(&session->stream_q, struct msm_stream, list,
+		__msm_destroy_session_streams, &sd_close);
+
+	msm_queue_drain(&session->stream_q, struct msm_stream, list);
+}
+
+static inline int __msm_remove_session_cmd_ack_q(void *d1, void *d2)
+{
+	struct msm_command_ack *cmd_ack = d1;
+
+	msm_queue_drain(&cmd_ack->command_q, struct msm_command, list);
+
+	return 0;
+}
+
+static void msm_remove_session_cmd_ack_q(struct msm_session *session)
+{
+	if (!session)
+		return;
+
+	/* to ensure error handling purpose, it needs to detach all subdevs
+	 * which are being connected to streams */
+	msm_queue_traverse_action(&session->command_ack_q,
+		struct msm_command_ack,	list,
+		__msm_remove_session_cmd_ack_q, NULL);
+
+	msm_queue_drain(&session->command_ack_q, struct msm_command_ack, list);
+}
+
+int msm_destroy_session(unsigned int session_id)
+{
+	struct msm_session *session;
+
+	session = msm_queue_find(msm_session_q, struct msm_session,
+		list, __msm_queue_find_session, &session_id);
+	if (!session)
+		return -EINVAL;
+
+	msm_destroy_session_streams(session);
+	msm_remove_session_cmd_ack_q(session);
+
+	msm_delete_entry(msm_session_q, struct msm_session,
+		list, session);
+
+	return 0;
+}
+
+static long msm_private_ioctl(struct file *file, void *fh,
+	bool valid_prio, int cmd, void *arg)
+{
+	int rc = 0;
+	struct msm_v4l2_event_data *event_data;
+	struct msm_session *session;
+	unsigned int session_id;
+	unsigned int stream_id;
+
+	event_data = (struct msm_v4l2_event_data *)
+		((struct v4l2_event *)arg)->u.data;
+
+	session_id = event_data->session_id;
+	stream_id = event_data->stream_id;
+
+	session = msm_queue_find(msm_session_q, struct msm_session,
+		list, __msm_queue_find_session, &session_id);
+
+	if (!session)
+		return -EINVAL;
+
+	switch (cmd) {
+	case MSM_CAM_V4L2_IOCTL_NOTIFY: {
+		if (WARN_ON(!session->event_q.vdev)) {
+			rc = -EFAULT;
+			break;
+		}
+
+		v4l2_event_queue(session->event_q.vdev,
+			(struct v4l2_event *)arg);
+	}
+		break;
+
+	case MSM_CAM_V4L2_IOCTL_CMD_ACK: {
+		struct msm_command_ack *cmd_ack;
+		struct msm_command *ret_cmd;
+
+		ret_cmd = kzalloc(sizeof(*ret_cmd), GFP_KERNEL);
+		if (!ret_cmd) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		cmd_ack = msm_queue_find(&session->command_ack_q,
+			struct msm_command_ack, list,
+			__msm_queue_find_command_ack_q,
+			&stream_id);
+		if (WARN_ON(!cmd_ack)) {
+			kfree(ret_cmd);
+			rc = -EFAULT;
+			break;
+		}
+
+		ret_cmd->event = *(struct v4l2_event *)arg;
+		msm_enqueue(&cmd_ack->command_q, &ret_cmd->list);
+		wake_up(&cmd_ack->wait);
+	}
+		break;
+
+	default:
+		rc = -ENOTTY;
+		break;
+	}
+
+	return rc;
+}
+
+static int msm_unsubscribe_event(struct v4l2_fh *fh,
+	struct v4l2_event_subscription *sub)
+{
+	return v4l2_event_unsubscribe(fh, sub);
+}
+
+static int msm_subscribe_event(struct v4l2_fh *fh,
+	struct v4l2_event_subscription *sub)
+{
+	return v4l2_event_subscribe(fh, sub, 5);
+}
+
+static const struct v4l2_ioctl_ops g_msm_ioctl_ops = {
+	.vidioc_subscribe_event = msm_subscribe_event,
+	.vidioc_unsubscribe_event = msm_unsubscribe_event,
+	.vidioc_default = msm_private_ioctl,
+};
+
+static unsigned int msm_poll(struct file *f,
+	struct poll_table_struct *pll_table)
+{
+	int rc = 0;
+	struct v4l2_fh *eventq = f->private_data;
+
+	BUG_ON(!eventq);
+
+	poll_wait(f, &eventq->wait, pll_table);
+
+	if (v4l2_event_pending(eventq))
+		rc = POLLIN | POLLRDNORM;
+
+	return rc;
+}
+
+/* something seriously wrong if msm_close is triggered
+ *   !!! user space imaging server is shutdown !!!
+ */
+int msm_post_event(struct v4l2_event *event, int timeout)
+{
+	int rc = 0;
+	struct video_device *vdev;
+	struct msm_session *session;
+	struct msm_v4l2_event_data *event_data =
+		(struct msm_v4l2_event_data *)&event->u.data[0];
+	struct msm_command_ack *cmd_ack;
+	struct msm_command *cmd;
+	int session_id, stream_id;
+	unsigned long flags = 0;
+
+	session_id = event_data->session_id;
+	stream_id = event_data->stream_id;
+
+	spin_lock_irqsave(&msm_eventq_lock, flags);
+	if (!msm_eventq) {
+		spin_unlock_irqrestore(&msm_eventq_lock, flags);
+		return -ENODEV;
+	}
+	spin_unlock_irqrestore(&msm_eventq_lock, flags);
+
+	vdev = msm_eventq->vdev;
+
+	/* send to imaging server and wait for ACK */
+	session = msm_queue_find(msm_session_q, struct msm_session,
+		list, __msm_queue_find_session, &session_id);
+	if (WARN_ON(!session))
+		return -EIO;
+
+	cmd_ack = msm_queue_find(&session->command_ack_q,
+		struct msm_command_ack, list,
+		__msm_queue_find_command_ack_q, &stream_id);
+	if (WARN_ON(!cmd_ack))
+		return -EIO;
+
+	v4l2_event_queue(vdev, event);
+
+	if (timeout < 0)
+		return rc;
+
+	/* should wait on session based condition */
+	rc = wait_event_interruptible_timeout(cmd_ack->wait,
+		!list_empty_careful(&cmd_ack->command_q.list),
+		msecs_to_jiffies(timeout));
+	if (list_empty_careful(&cmd_ack->command_q.list)) {
+		if (!rc)
+			rc = -ETIMEDOUT;
+		if (rc < 0)
+			return rc;
+	}
+
+	cmd = msm_dequeue(&cmd_ack->command_q,
+		struct msm_command, list);
+	if (!cmd)
+		return -EINVAL;
+
+	event_data = (struct msm_v4l2_event_data *)cmd->event.u.data;
+
+	/* compare cmd_ret and event */
+	if (WARN_ON(event->type != cmd->event.type) ||
+			WARN_ON(event->id != cmd->event.id))
+		rc = -EINVAL;
+
+	*event = cmd->event;
+
+	kfree(cmd);
+	return rc;
+}
+
+static int __msm_close_destry_session_notify_apps(void *d1, void *d2)
+{
+	struct v4l2_event event;
+	struct msm_v4l2_event_data *event_data =
+		(struct msm_v4l2_event_data *)&event.u.data[0];
+	struct msm_session *session = d1;
+
+	event.type = MSM_CAMERA_V4L2_EVENT_TYPE;
+	event.id   = MSM_CAMERA_MSM_NOTIFY;
+	event_data->command = MSM_CAMERA_PRIV_SHUTDOWN;
+
+	v4l2_event_queue(session->event_q.vdev, &event);
+
+	msm_destroy_session_streams(session);
+	msm_remove_session_cmd_ack_q(session);
+
+	return 0;
+}
+
+static int msm_close(struct file *filep)
+{
+	int rc = 0;
+	unsigned long flags;
+	struct msm_video_device *pvdev = video_drvdata(filep);
+
+	/* 1st thing 1st, send v4l2_event to HAL immediately,
+	 * to ensure error handling purpose, it needs to detach all subdevs
+	 * which are being connected to streams */
+	msm_queue_traverse_action(msm_session_q, struct msm_session, list,
+		__msm_close_destry_session_notify_apps, NULL);
+
+	msm_queue_drain(msm_session_q, struct msm_session, list);
+
+	spin_lock_irqsave(&msm_eventq_lock, flags);
+	msm_eventq = NULL;
+	spin_unlock_irqrestore(&msm_eventq_lock, flags);
+	v4l2_fh_release(filep);
+
+	msm_sd_try_shutdown();
+
+	spin_lock_irqsave(&msm_pid_lock, flags);
+	put_pid(msm_pid);
+	msm_pid = NULL;
+	spin_unlock_irqrestore(&msm_pid_lock, flags);
+
+	atomic_set(&pvdev->opened, 0);
+
+	return rc;
+}
+
+static inline void msm_list_switch(struct list_head *l1,
+	struct list_head *l2)
+{
+	l1->next = l2->next;
+	l2->prev = l1->prev;
+	l1->prev->next = l2;
+	l2->next->prev = l1;
+	l1->prev = l2;
+	l2->next = l1;
+}
+
+static int msm_open(struct file *filep)
+{
+	int rc;
+	unsigned long flags;
+	struct msm_video_device *pvdev = video_drvdata(filep);
+
+	BUG_ON(!pvdev);
+
+	/* !!! only ONE open is allowed !!! */
+	if (atomic_read(&pvdev->opened))
+		return -EBUSY;
+
+	atomic_set(&pvdev->opened, 1);
+
+	spin_lock_irqsave(&msm_pid_lock, flags);
+	msm_pid = get_pid(task_pid(current));
+	spin_unlock_irqrestore(&msm_pid_lock, flags);
+
+	/* create event queue */
+	rc = v4l2_fh_open(filep);
+	if (rc  < 0)
+		return rc;
+
+	spin_lock_irqsave(&msm_eventq_lock, flags);
+	msm_eventq = filep->private_data;
+	spin_unlock_irqrestore(&msm_eventq_lock, flags);
+
+	return rc;
+}
+
+static struct v4l2_file_operations msm_fops = {
+	.owner  = THIS_MODULE,
+	.open   = msm_open,
+	.poll   = msm_poll,
+	.release = msm_close,
+	.ioctl   = video_ioctl2,
+};
+
+struct msm_stream *msm_get_stream(unsigned int session_id,
+	unsigned int stream_id)
+{
+	struct msm_session *session;
+	struct msm_stream *stream;
+
+	session = msm_queue_find(msm_session_q, struct msm_session,
+		list, __msm_queue_find_session, &session_id);
+	if (!session)
+		return ERR_PTR(-EINVAL);
+
+	stream = msm_queue_find(&session->stream_q, struct msm_stream,
+		list, __msm_queue_find_stream, &stream_id);
+
+	if (!stream)
+		return ERR_PTR(-EINVAL);
+
+	return stream;
+}
+
+struct vb2_queue *msm_get_stream_vb2q(unsigned int session_id,
+	unsigned int stream_id)
+{
+	struct msm_session *session;
+	struct msm_stream *stream;
+
+	session = msm_queue_find(msm_session_q, struct msm_session,
+		list, __msm_queue_find_session, &session_id);
+	if (!session)
+		return NULL;
+
+	stream = msm_queue_find(&session->stream_q, struct msm_stream,
+		list, __msm_queue_find_stream, &stream_id);
+	if (!stream)
+		return NULL;
+
+	return stream->vb2_q;
+}
+
+static struct v4l2_subdev *msm_sd_find(const char *name)
+{
+	unsigned long flags;
+	struct v4l2_subdev *subdev = NULL;
+
+	spin_lock_irqsave(&msm_v4l2_dev->lock, flags);
+	if (!list_empty(&msm_v4l2_dev->subdevs)) {
+		list_for_each_entry(subdev, &msm_v4l2_dev->subdevs, list)
+			if (!strcmp(name, subdev->name))
+				break;
+	}
+	spin_unlock_irqrestore(&msm_v4l2_dev->lock, flags);
+
+	return subdev;
+}
+
+static void msm_sd_notify(struct v4l2_subdev *sd,
+	unsigned int notification, void *arg)
+{
+	int rc = 0;
+	struct v4l2_subdev *subdev = NULL;
+
+	BUG_ON(!sd);
+	BUG_ON(!arg);
+
+	/* Check if subdev exists before processing*/
+	if (!msm_sd_find(sd->name))
+		return;
+
+	switch (notification) {
+	case MSM_SD_NOTIFY_GET_SD: {
+		struct msm_sd_req_sd *get_sd = arg;
+
+		get_sd->subdev = msm_sd_find(get_sd->name);
+		/* TODO: might need to add ref count on ret_sd */
+	}
+		break;
+
+	case MSM_SD_NOTIFY_PUT_SD: {
+		struct msm_sd_req_sd *put_sd = arg;
+		subdev = msm_sd_find(put_sd->name);
+	}
+		break;
+
+	case MSM_SD_NOTIFY_REQ_CB: {
+		struct msm_sd_req_vb2_q *req_sd = arg;
+		rc = msm_vb2_request_cb(req_sd);
+		if (rc < 0)
+			return;
+	}
+		break;
+
+	default:
+		break;
+	}
+}
+
+static int __devinit msm_probe(struct platform_device *pdev)
+{
+	struct msm_video_device *pvdev;
+	int rc = 0;
+
+	msm_v4l2_dev = kzalloc(sizeof(*msm_v4l2_dev),
+		GFP_KERNEL);
+	if (WARN_ON(!msm_v4l2_dev)) {
+		rc = -ENOMEM;
+		goto probe_end;
+	}
+
+	pvdev = kzalloc(sizeof(struct msm_video_device),
+		GFP_KERNEL);
+	if (WARN_ON(!pvdev)) {
+		rc = -ENOMEM;
+		goto pvdev_fail;
+	}
+
+	pvdev->vdev = video_device_alloc();
+	if (WARN_ON(!pvdev->vdev)) {
+		rc = -ENOMEM;
+		goto video_fail;
+	}
+
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	msm_v4l2_dev->mdev = kzalloc(sizeof(struct media_device),
+		GFP_KERNEL);
+	if (!msm_v4l2_dev->mdev) {
+		rc = -ENOMEM;
+		goto mdev_fail;
+	}
+	strlcpy(msm_v4l2_dev->mdev->model, MSM_CONFIGURATION_NAME,
+			sizeof(msm_v4l2_dev->mdev->model));
+	msm_v4l2_dev->mdev->dev = &(pdev->dev);
+
+	rc = media_device_register(msm_v4l2_dev->mdev);
+	if (WARN_ON(rc < 0))
+		goto media_fail;
+
+	if (WARN_ON((rc == media_entity_init(&pvdev->vdev->entity,
+			0, NULL, 0)) < 0))
+		goto entity_fail;
+
+	pvdev->vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
+	pvdev->vdev->entity.group_id = QCAMERA_VNODE_GROUP_ID;
+#endif
+
+	msm_v4l2_dev->notify = msm_sd_notify;
+
+	pvdev->vdev->v4l2_dev = msm_v4l2_dev;
+
+	rc = v4l2_device_register(&(pdev->dev), pvdev->vdev->v4l2_dev);
+	if (WARN_ON(rc < 0))
+		goto register_fail;
+
+	strlcpy(pvdev->vdev->name, "msm-config", sizeof(pvdev->vdev->name));
+	pvdev->vdev->release  = video_device_release;
+	pvdev->vdev->fops     = &msm_fops;
+	pvdev->vdev->ioctl_ops = &g_msm_ioctl_ops;
+	pvdev->vdev->minor     = -1;
+	pvdev->vdev->vfl_type  = VFL_TYPE_GRABBER;
+	rc = video_register_device(pvdev->vdev,
+		VFL_TYPE_GRABBER, -1);
+	if (WARN_ON(rc < 0))
+		goto v4l2_fail;
+
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	/* FIXME: How to get rid of this messy? */
+	pvdev->vdev->entity.name = video_device_node_name(pvdev->vdev);
+#endif
+
+	atomic_set(&pvdev->opened, 0);
+	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;
+
+	msm_init_queue(msm_session_q);
+	spin_lock_init(&msm_eventq_lock);
+	spin_lock_init(&msm_pid_lock);
+
+	goto probe_end;
+
+v4l2_fail:
+	v4l2_device_unregister(pvdev->vdev->v4l2_dev);
+register_fail:
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&pvdev->vdev->entity);
+entity_fail:
+	media_device_unregister(msm_v4l2_dev->mdev);
+media_fail:
+	kfree(msm_v4l2_dev->mdev);
+mdev_fail:
+#endif
+	video_device_release(pvdev->vdev);
+video_fail:
+	kfree(pvdev);
+pvdev_fail:
+	kfree(msm_v4l2_dev);
+probe_end:
+	return rc;
+}
+
+static const struct of_device_id msm_dt_match[] = {
+	{.compatible = "qcom,msm-cam"},
+}
+
+MODULE_DEVICE_TABLE(of, msm_dt_match);
+
+static struct platform_driver msm_driver = {
+	.probe = msm_probe,
+	.driver = {
+		.name = "msm",
+		.owner = THIS_MODULE,
+		.of_match_table = msm_dt_match,
+	},
+};
+
+static int __init msm_init(void)
+{
+	return platform_driver_register(&msm_driver);
+}
+
+static void __exit msm_exit(void)
+{
+	platform_driver_unregister(&msm_driver);
+}
+
+
+module_init(msm_init);
+module_exit(msm_exit);
+MODULE_DESCRIPTION("MSM V4L2 Camera");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v2/msm.h b/drivers/media/platform/msm/camera_v2/msm.h
new file mode 100644
index 0000000..eb15cab
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/msm.h
@@ -0,0 +1,55 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _MSM_H
+#define _MSM_H
+
+#include <linux/version.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+#include <linux/pm_qos.h>
+#include <linux/wakelock.h>
+#include <linux/msm_ion.h>
+#include <linux/iommu.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-fh.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-mediabus.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-msm-mem.h>
+#include <media/msmb_camera.h>
+
+#define MSM_POST_EVT_TIMEOUT 5000
+#define MSM_POST_EVT_NOTIMEOUT 0xFFFFFFFF
+
+struct msm_video_device {
+	struct video_device *vdev;
+	atomic_t opened;
+};
+
+int msm_post_event(struct v4l2_event *event, int timeout);
+int  msm_create_session(unsigned int session, struct video_device *vdev);
+int msm_destroy_session(unsigned int session_id);
+
+int msm_create_stream(unsigned int session_id,
+	unsigned int stream_id, struct vb2_queue *q);
+void msm_delete_stream(unsigned int session_id, unsigned int stream_id);
+int  msm_create_command_ack_q(unsigned int session_id, unsigned int stream_id);
+void msm_delete_command_ack_q(unsigned int session_id, unsigned int stream_id);
+struct msm_stream *msm_get_stream(unsigned int session_id,
+	unsigned int stream_id);
+struct vb2_queue *msm_get_stream_vb2q(unsigned int session_id,
+	unsigned int stream_id);
+
+#endif /*_MSM_H */
diff --git a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/Makefile b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/Makefile
new file mode 100644
index 0000000..8832457
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/Makefile
@@ -0,0 +1,2 @@
+ccflags-y += -Idrivers/media/platform/msm/camera_v2
+obj-$(CONFIG_MSMB_CAMERA) += msm_generic_buf_mgr.o
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
new file mode 100644
index 0000000..8a21512
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
@@ -0,0 +1,181 @@
+/* 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 "msm_generic_buf_mgr.h"
+
+static struct msm_buf_mngr_device *msm_buf_mngr_dev;
+
+static int msm_buf_mngr_get_buf(struct msm_buf_mngr_device *buf_mngr_dev,
+	void __user *argp)
+{
+	struct msm_buf_mngr_info *buf_info =
+		(struct msm_buf_mngr_info *)argp;
+	struct msm_get_bufs *new_entry =
+		kzalloc(sizeof(struct msm_get_bufs), GFP_KERNEL);
+
+	if (!new_entry) {
+		pr_err("%s:No mem\n", __func__);
+		return -ENOMEM;
+	}
+	INIT_LIST_HEAD(&new_entry->entry);
+	new_entry->vb2_buf = buf_mngr_dev->vb2_ops.get_buf(buf_info->session_id,
+		buf_info->stream_id);
+	if (!new_entry->vb2_buf) {
+		pr_err("%s:Get buf is null\n", __func__);
+		kfree(new_entry);
+		return -EINVAL;
+	}
+	new_entry->session_id = buf_info->session_id;
+	new_entry->stream_id = buf_info->stream_id;
+	mutex_lock(&buf_mngr_dev->buf_q_lock);
+	list_add_tail(&new_entry->entry, &buf_mngr_dev->buf_qhead);
+	mutex_unlock(&buf_mngr_dev->buf_q_lock);
+	buf_info->index = new_entry->vb2_buf->v4l2_buf.index;
+	return 0;
+}
+
+static int msm_buf_mngr_buf_done(struct msm_buf_mngr_device *buf_mngr_dev,
+	struct msm_buf_mngr_info *buf_info)
+{
+	struct msm_get_bufs *bufs, *save;
+	int ret = -EINVAL;
+
+	mutex_lock(&buf_mngr_dev->buf_q_lock);
+	list_for_each_entry_safe(bufs, save, &buf_mngr_dev->buf_qhead, entry) {
+		if ((bufs->session_id == buf_info->session_id) &&
+			(bufs->stream_id == buf_info->stream_id) &&
+			(bufs->vb2_buf->v4l2_buf.index == buf_info->index)) {
+			bufs->vb2_buf->v4l2_buf.sequence  = buf_info->frame_id;
+			bufs->vb2_buf->v4l2_buf.timestamp = buf_info->timestamp;
+			ret = buf_mngr_dev->vb2_ops.buf_done
+					(bufs->vb2_buf,
+						buf_info->session_id,
+						buf_info->stream_id);
+			list_del_init(&bufs->entry);
+			kfree(bufs);
+			break;
+		}
+	}
+	mutex_unlock(&buf_mngr_dev->buf_q_lock);
+	return ret;
+}
+
+
+static int msm_buf_mngr_put_buf(struct msm_buf_mngr_device *buf_mngr_dev,
+	struct msm_buf_mngr_info *buf_info)
+{
+	struct msm_get_bufs *bufs, *save;
+	int ret = -EINVAL;
+
+	mutex_lock(&buf_mngr_dev->buf_q_lock);
+	list_for_each_entry_safe(bufs, save, &buf_mngr_dev->buf_qhead, entry) {
+		if ((bufs->session_id == buf_info->session_id) &&
+			(bufs->stream_id == buf_info->stream_id) &&
+			(bufs->vb2_buf->v4l2_buf.index == buf_info->index)) {
+			ret = buf_mngr_dev->vb2_ops.put_buf(bufs->vb2_buf,
+				buf_info->session_id, buf_info->stream_id);
+			list_del_init(&bufs->entry);
+			kfree(bufs);
+			break;
+		}
+	}
+	mutex_unlock(&buf_mngr_dev->buf_q_lock);
+	return ret;
+}
+
+static long msm_buf_mngr_subdev_ioctl(struct v4l2_subdev *sd,
+	unsigned int cmd, void *arg)
+{
+	int rc = 0;
+	struct msm_buf_mngr_device *buf_mngr_dev = v4l2_get_subdevdata(sd);
+	void __user *argp = (void __user *)arg;
+
+	if (!buf_mngr_dev) {
+		pr_err("%s buf manager device NULL\n", __func__);
+		rc = -ENOMEM;
+		return rc;
+	}
+
+	switch (cmd) {
+	case VIDIOC_MSM_BUF_MNGR_GET_BUF:
+		rc = msm_buf_mngr_get_buf(buf_mngr_dev, argp);
+		break;
+	case VIDIOC_MSM_BUF_MNGR_BUF_DONE:
+		rc = msm_buf_mngr_buf_done(buf_mngr_dev, argp);
+		break;
+	case VIDIOC_MSM_BUF_MNGR_PUT_BUF:
+		rc = msm_buf_mngr_put_buf(buf_mngr_dev, argp);
+		break;
+	default:
+		return -ENOIOCTLCMD;
+	}
+	return rc;
+}
+
+static struct v4l2_subdev_core_ops msm_buf_mngr_subdev_core_ops = {
+	.ioctl = msm_buf_mngr_subdev_ioctl,
+};
+
+static const struct v4l2_subdev_ops msm_buf_mngr_subdev_ops = {
+	.core = &msm_buf_mngr_subdev_core_ops,
+};
+
+static const struct of_device_id msm_buf_mngr_dt_match[] = {
+	{.compatible = "qcom,msm_buf_mngr"},
+};
+
+static int __init msm_buf_mngr_init(void)
+{
+	int rc = 0;
+	msm_buf_mngr_dev = kzalloc(sizeof(*msm_buf_mngr_dev),
+		GFP_KERNEL);
+	if (WARN_ON(!msm_buf_mngr_dev)) {
+		pr_err("%s: not enough memory", __func__);
+		return -ENOMEM;
+	}
+	/* Sub-dev */
+	v4l2_subdev_init(&msm_buf_mngr_dev->subdev.sd,
+		&msm_buf_mngr_subdev_ops);
+	snprintf(msm_buf_mngr_dev->subdev.sd.name,
+		ARRAY_SIZE(msm_buf_mngr_dev->subdev.sd.name), "msm_buf_mngr");
+	msm_buf_mngr_dev->subdev.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	v4l2_set_subdevdata(&msm_buf_mngr_dev->subdev.sd, msm_buf_mngr_dev);
+
+	media_entity_init(&msm_buf_mngr_dev->subdev.sd.entity, 0, NULL, 0);
+	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;
+	rc = msm_sd_register(&msm_buf_mngr_dev->subdev);
+	if (rc != 0) {
+		pr_err("%s: msm_sd_register error = %d\n", __func__, rc);
+		goto end;
+	}
+
+	v4l2_subdev_notify(&msm_buf_mngr_dev->subdev.sd, MSM_SD_NOTIFY_REQ_CB,
+		&msm_buf_mngr_dev->vb2_ops);
+
+	INIT_LIST_HEAD(&msm_buf_mngr_dev->buf_qhead);
+	mutex_init(&msm_buf_mngr_dev->buf_q_lock);
+end:
+	return rc;
+}
+
+static void __exit msm_buf_mngr_exit(void)
+{
+	mutex_destroy(&msm_buf_mngr_dev->buf_q_lock);
+	kfree(msm_buf_mngr_dev);
+}
+
+module_init(msm_buf_mngr_init);
+module_exit(msm_buf_mngr_exit);
+MODULE_DESCRIPTION("MSM Buffer Manager");
+MODULE_LICENSE("GPL v2");
+
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
new file mode 100644
index 0000000..a2b3a7e
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.h
@@ -0,0 +1,40 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MSM_BUF_GENERIC_MNGR_H__
+#define __MSM_BUF_GENERIC_MNGR_H__
+
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <media/v4l2-subdev.h>
+#include <media/msmb_camera.h>
+#include <media/msmb_generic_buf_mgr.h>
+
+#include "msm.h"
+#include "msm_sd.h"
+
+struct msm_get_bufs {
+	struct list_head entry;
+	struct vb2_buffer *vb2_buf;
+	uint32_t session_id;
+	uint32_t stream_id;
+};
+
+struct msm_buf_mngr_device {
+	struct list_head buf_qhead;
+	struct mutex buf_q_lock;
+	struct msm_sd_subdev subdev;
+	struct msm_sd_req_vb2_q vb2_ops;
+};
+#endif
diff --git a/drivers/media/platform/msm/camera_v2/msm_sd.h b/drivers/media/platform/msm/camera_v2/msm_sd.h
new file mode 100644
index 0000000..958e030
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/msm_sd.h
@@ -0,0 +1,84 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _MSM_SD_H
+#define _MSM_SD_H
+
+#include <media/v4l2-subdev.h>
+#include <media/msmb_camera.h>
+
+/* NOTE: this header file should ONLY be included by subdev drivers */
+
+struct msm_sd_close_ioctl {
+	unsigned int session;
+	unsigned int stream;
+};
+
+#define MSM_SD_CLOSE_STREAM \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 26, struct msm_sd_close_ioctl)
+
+#define MSM_SD_CLOSE_SESSION \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 27, struct msm_sd_close_ioctl)
+
+#define MSM_SD_CLOSE_SESSION_AND_STREAM \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 28, struct msm_sd_close_ioctl)
+
+#define MSM_SD_SHUTDOWN \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 29, struct msm_sd_close_ioctl)
+
+/*
+ * This is used to install Sequence in msm_sd_register.
+ * During msm_close, proper close sequence will be triggered.
+ * For example:
+ *
+ * close_sequence = 0x00100001 (ISP)
+ * close_sequence = 0x00100002 (ISP)
+ * close_sequence = 0x00100003 (ISP)
+ * close_sequence = 0x00200001 (sensor)
+ * close_sequence = 0x00200002 (sensor)
+ * close_sequence = 0x00200003 (sensor)
+ */
+#define MSM_SD_CLOSE_1ST_CATEGORY  0x00010000
+#define MSM_SD_CLOSE_2ND_CATEGORY  0x00020000
+#define MSM_SD_CLOSE_3RD_CATEGORY  0x00030000
+
+struct msm_sd_subdev {
+	struct v4l2_subdev sd;
+	int close_seq;
+};
+
+struct msm_sd_req_sd {
+	char *name;
+	struct v4l2_subdev *subdev;
+};
+
+struct msm_sd_req_vb2_q {
+	struct vb2_buffer *(*get_buf)(int session_id, unsigned int stream_id);
+	struct vb2_queue *(*get_vb2_queue)(int session_id,
+		unsigned int stream_id);
+	int (*put_buf)(struct vb2_buffer *vb2_buf, int session_id,
+		unsigned int stream_id);
+	int (*buf_done)(struct vb2_buffer *vb2_buf, int session_id,
+		unsigned int stream_id);
+};
+
+#define MSM_SD_NOTIFY_GET_SD 0x00000001
+#define MSM_SD_NOTIFY_PUT_SD 0x00000002
+#define MSM_SD_NOTIFY_REQ_CB 0x00000003
+
+int msm_sd_register(struct msm_sd_subdev *msm_subdev);
+int msm_sd_unregister(struct msm_sd_subdev *sd);
+struct v4l2_subdev *msm_sd_get_subdev(struct v4l2_subdev *sd,
+	const char *get_name);
+void msm_sd_put_subdev(struct v4l2_subdev *sd, struct v4l2_subdev *put);
+
+#endif /*_MSM_SD_H */
diff --git a/drivers/media/platform/msm/camera_v2/msm_vb2/Makefile b/drivers/media/platform/msm/camera_v2/msm_vb2/Makefile
new file mode 100644
index 0000000..2673bdd
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/msm_vb2/Makefile
@@ -0,0 +1,3 @@
+ccflags-y += -Idrivers/media/platform/msm/camera_v2
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/msm_vb2
+obj-$(CONFIG_MSMB_CAMERA) += msm_vb2.o
diff --git a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
new file mode 100644
index 0000000..22131f8
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
@@ -0,0 +1,202 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include "msm_vb2.h"
+
+static int msm_vb2_queue_setup(struct vb2_queue *q,
+	const struct v4l2_format *fmt,
+	unsigned int *num_buffers, unsigned int *num_planes,
+	unsigned int sizes[], void *alloc_ctxs[])
+{
+	int i;
+	struct msm_v4l2_format_data *data = q->drv_priv;
+
+	if (data->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+		if (WARN_ON(data->num_planes > VIDEO_MAX_PLANES))
+			return -EINVAL;
+
+		*num_planes = data->num_planes;
+
+		for (i = 0; i < data->num_planes; i++)
+			sizes[i] = data->plane_sizes[i];
+	} else {
+		pr_err("%s: Unsupported buf type :%d\n", __func__,
+			   data->type);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+int msm_vb2_buf_init(struct vb2_buffer *vb)
+{
+	struct msm_vb2_buffer *msm_vb2_buf;
+
+	msm_vb2_buf = container_of(vb, struct msm_vb2_buffer, vb2_buf);
+	msm_vb2_buf->in_freeq = 0;
+
+	return 0;
+}
+
+static void msm_vb2_buf_queue(struct vb2_buffer *vb)
+{
+}
+
+static struct vb2_ops msm_vb2_get_q_op = {
+	.queue_setup		= msm_vb2_queue_setup,
+	.buf_init		= msm_vb2_buf_init,
+	.buf_queue              = msm_vb2_buf_queue,
+};
+
+
+struct vb2_ops *msm_vb2_get_q_ops(void)
+{
+	return &msm_vb2_get_q_op;
+}
+
+static void *msm_vb2_dma_contig_get_userptr(void *alloc_ctx,
+	unsigned long vaddr, unsigned long size, int write)
+{
+	struct msm_vb2_private_data *priv;
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return ERR_PTR(-ENOMEM);
+	priv->vaddr = (void *)vaddr;
+	priv->size = size;
+	priv->alloc_ctx = alloc_ctx;
+	return priv;
+}
+
+static void msm_vb2_dma_contig_put_userptr(void *buf_priv)
+{
+	kfree(buf_priv);
+}
+
+static struct vb2_mem_ops msm_vb2_get_q_mem_op = {
+	.get_userptr		= msm_vb2_dma_contig_get_userptr,
+	.put_userptr		= msm_vb2_dma_contig_put_userptr,
+};
+
+struct vb2_mem_ops *msm_vb2_get_q_mem_ops(void)
+{
+	return &msm_vb2_get_q_mem_op;
+}
+
+static struct vb2_queue *msm_vb2_get_queue(int session_id,
+	unsigned int stream_id)
+{
+	return msm_get_stream_vb2q(session_id, stream_id);
+}
+
+static struct vb2_buffer *msm_vb2_get_buf(int session_id,
+	unsigned int stream_id)
+{
+	struct msm_stream *stream;
+	struct vb2_buffer *vb2_buf = NULL;
+	struct msm_vb2_buffer *msm_vb2;
+	unsigned long flags;
+
+	stream = msm_get_stream(session_id, stream_id);
+	if (IS_ERR_OR_NULL(stream))
+		return NULL;
+
+	spin_lock_irqsave(&stream->stream_lock, flags);
+
+	if (!stream->vb2_q) {
+		pr_err("%s: stream q not available\n", __func__);
+		goto end;
+	}
+
+	list_for_each_entry(vb2_buf, &(stream->vb2_q->queued_list),
+		queued_entry) {
+		if (vb2_buf->state != VB2_BUF_STATE_ACTIVE)
+			continue;
+
+		msm_vb2 = container_of(vb2_buf, struct msm_vb2_buffer, vb2_buf);
+		if (msm_vb2->in_freeq)
+			continue;
+
+		msm_vb2->in_freeq = 1;
+		goto end;
+	}
+	vb2_buf = NULL;
+end:
+	spin_unlock_irqrestore(&stream->stream_lock, flags);
+	return vb2_buf;
+}
+
+static int msm_vb2_put_buf(struct vb2_buffer *vb, int session_id,
+				unsigned int stream_id)
+{
+	struct msm_vb2_buffer *msm_vb2;
+	int rc = 0;
+
+	if (vb) {
+		msm_vb2 =
+			container_of(vb, struct msm_vb2_buffer, vb2_buf);
+		if (msm_vb2->in_freeq) {
+			msm_vb2->in_freeq = 0;
+			rc = 0;
+		} else
+			rc = -EINVAL;
+	} else {
+		pr_err("%s: VB buffer is null\n", __func__);
+		rc = -EINVAL;
+	}
+	return rc;
+}
+
+static int msm_vb2_buf_done(struct vb2_buffer *vb, int session_id,
+				unsigned int stream_id)
+{
+	unsigned long flags;
+	struct msm_vb2_buffer *msm_vb2;
+	struct msm_stream *stream;
+	int rc = 0;
+
+	stream = msm_get_stream(session_id, stream_id);
+	if (IS_ERR_OR_NULL(stream))
+		return 0;
+	spin_lock_irqsave(&stream->stream_lock, flags);
+	if (vb) {
+		msm_vb2 =
+			container_of(vb, struct msm_vb2_buffer, vb2_buf);
+		/* put buf before buf done */
+		if (msm_vb2->in_freeq) {
+			vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+			msm_vb2->in_freeq = 0;
+			rc = 0;
+		} else
+			rc = -EINVAL;
+	} else {
+		pr_err("%s: VB buffer is null\n", __func__);
+		rc = -EINVAL;
+	}
+
+	spin_unlock_irqrestore(&stream->stream_lock, flags);
+	return rc;
+}
+
+int msm_vb2_request_cb(struct msm_sd_req_vb2_q *req)
+{
+	if (!req) {
+		pr_err("%s: suddev is null\n", __func__);
+		return -EINVAL;
+	}
+
+	req->get_buf = msm_vb2_get_buf;
+	req->get_vb2_queue = msm_vb2_get_queue;
+	req->put_buf = msm_vb2_put_buf;
+	req->buf_done = msm_vb2_buf_done;
+
+	return 0;
+}
+
diff --git a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.h b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.h
new file mode 100644
index 0000000..cecc85e
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.h
@@ -0,0 +1,69 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _MSM_VB_H
+#define _MSM_VB_H
+
+#include <linux/version.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+#include <linux/pm_qos.h>
+#include <linux/wakelock.h>
+#include <linux/msm_ion.h>
+#include <linux/iommu.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-fh.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-mediabus.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-msm-mem.h>
+#include <media/msmb_camera.h>
+#include <media/videobuf2-core.h>
+#include "msm.h"
+#include "msm_sd.h"
+
+struct msm_vb2_buffer {
+	/*
+	 * vb2 buffer has to be first in the structure
+	 * because both v4l2 frameworks and driver directly
+	 * cast msm_vb2_buffer to a vb2_buf.
+	 */
+	struct vb2_buffer vb2_buf;
+	struct list_head list;
+	int in_freeq;
+};
+
+struct msm_vb2_private_data {
+	void *vaddr;
+	unsigned long size;
+	/* Offset of the plane inside the buffer */
+	void *alloc_ctx;
+};
+
+struct msm_stream {
+	struct list_head list;
+
+	/* stream index per session, same
+	 * as stream_id but set through s_parm */
+	unsigned int stream_id;
+	/* vb2 buffer handling */
+	struct vb2_queue *vb2_q;
+	spinlock_t stream_lock;
+};
+
+struct vb2_ops *msm_vb2_get_q_ops(void);
+struct vb2_mem_ops *msm_vb2_get_q_mem_ops(void);
+int msm_vb2_request_cb(struct msm_sd_req_vb2_q *req_sd);
+
+#endif /*_MSM_VB_H */
diff --git a/drivers/media/platform/msm/camera_v2/pproc/Makefile b/drivers/media/platform/msm/camera_v2/pproc/Makefile
new file mode 100644
index 0000000..854e4e7
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/pproc/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_MSMB_CAMERA) += cpp/
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/Makefile b/drivers/media/platform/msm/camera_v2/pproc/cpp/Makefile
new file mode 100644
index 0000000..2f969d2
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/Makefile
@@ -0,0 +1,3 @@
+ccflags-y += -Idrivers/media/platform/msm/camera_v2
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io
+obj-$(CONFIG_MSM_CPP) += msm_cpp.o
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
new file mode 100644
index 0000000..637bce3
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
@@ -0,0 +1,1090 @@
+/* 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) "MSM-CPP %s:%d " fmt, __func__, __LINE__
+
+
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/firmware.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/module.h>
+#include <linux/regulator/consumer.h>
+#include <linux/ion.h>
+#include <linux/proc_fs.h>
+#include <linux/debugfs.h>
+#include <linux/msm_ion.h>
+#include <linux/iommu.h>
+#include <mach/iommu_domains.h>
+#include <mach/iommu.h>
+#include <mach/vreg.h>
+#include <media/msm_isp.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-ioctl.h>
+#include <media/msmb_camera.h>
+#include <media/msmb_pproc.h>
+#include "msm_cpp.h"
+#include "msm_camera_io_util.h"
+
+#define MSM_CPP_DRV_NAME "msm_cpp"
+
+#define CONFIG_MSM_CPP_DBG 0
+
+#if CONFIG_MSM_CPP_DBG
+#define CPP_DBG(fmt, args...) pr_err(fmt, ##args)
+#else
+#define CPP_DBG(fmt, args...) pr_debug(fmt, ##args)
+#endif
+
+#define ERR_USER_COPY(to) pr_err("copy %s user\n", \
+			((to) ? "to" : "from"))
+#define ERR_COPY_FROM_USER() ERR_USER_COPY(0)
+
+#define msm_dequeue(queue, member) ({	   \
+	unsigned long flags;		  \
+	struct msm_device_queue *__q = (queue);	 \
+	struct msm_queue_cmd *qcmd = 0;	   \
+	spin_lock_irqsave(&__q->lock, flags);	 \
+	if (!list_empty(&__q->list)) {		\
+		__q->len--;		 \
+		qcmd = list_first_entry(&__q->list,   \
+		struct msm_queue_cmd, member);  \
+		list_del_init(&qcmd->member);	 \
+	}			 \
+	spin_unlock_irqrestore(&__q->lock, flags);  \
+	qcmd;			 \
+})
+
+static void msm_queue_init(struct msm_device_queue *queue, const char *name)
+{
+	CPP_DBG("E\n");
+	spin_lock_init(&queue->lock);
+	queue->len = 0;
+	queue->max = 0;
+	queue->name = name;
+	INIT_LIST_HEAD(&queue->list);
+	init_waitqueue_head(&queue->wait);
+}
+
+static void msm_enqueue(struct msm_device_queue *queue,
+			struct list_head *entry)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&queue->lock, flags);
+	queue->len++;
+	if (queue->len > queue->max) {
+		queue->max = queue->len;
+		pr_info("queue %s new max is %d\n", queue->name, queue->max);
+	}
+	list_add_tail(entry, &queue->list);
+	wake_up(&queue->wait);
+	CPP_DBG("woke up %s\n", queue->name);
+	spin_unlock_irqrestore(&queue->lock, flags);
+}
+
+static struct msm_cam_clk_info cpp_clk_info[] = {
+	{"camss_top_ahb_clk", -1},
+	{"vfe_clk_src", 266670000},
+	{"camss_vfe_vfe_clk", -1},
+	{"iface_clk", -1},
+	{"cpp_core_clk", 266670000},
+	{"cpp_iface_clk", -1},
+	{"cpp_bus_clk", -1},
+	{"micro_iface_clk", -1},
+};
+static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev);
+
+static void msm_cpp_write(u32 data, void __iomem *cpp_base)
+{
+	writel_relaxed((data), cpp_base + MSM_CPP_MICRO_FIFO_RX_DATA);
+}
+
+static uint32_t msm_cpp_read(void __iomem *cpp_base)
+{
+	uint32_t tmp, retry = 0;
+	do {
+		tmp = msm_camera_io_r(cpp_base + MSM_CPP_MICRO_FIFO_TX_STAT);
+	} while (((tmp & 0x2) == 0x0) && (retry++ < 10)) ;
+	if (retry < 10) {
+		tmp = msm_camera_io_r(cpp_base + MSM_CPP_MICRO_FIFO_TX_DATA);
+		CPP_DBG("Read data: 0%x\n", tmp);
+	} else {
+		CPP_DBG("Read failed\n");
+		tmp = 0xDEADBEEF;
+	}
+
+	return tmp;
+}
+
+static void msm_cpp_poll(void __iomem *cpp_base, u32 val)
+{
+	uint32_t tmp, retry = 0;
+	do {
+		usleep_range(1000, 2000);
+		tmp = msm_cpp_read(cpp_base);
+		if (tmp != 0xDEADBEEF)
+			CPP_DBG("poll: 0%x\n", tmp);
+	} while ((tmp != val) && (retry++ < MSM_CPP_POLL_RETRIES));
+	if (retry < MSM_CPP_POLL_RETRIES)
+		CPP_DBG("Poll finished\n");
+	else
+		pr_err("Poll failed: expect: 0x%x\n", val);
+}
+
+void cpp_release_ion_client(struct kref *ref)
+{
+	struct cpp_device *cpp_dev = container_of(ref,
+		struct cpp_device, refcount);
+	pr_err("Calling ion_client_destroy\n");
+	ion_client_destroy(cpp_dev->client);
+}
+
+static int cpp_init_mem(struct cpp_device *cpp_dev)
+{
+	int rc = 0;
+
+	kref_init(&cpp_dev->refcount);
+	kref_get(&cpp_dev->refcount);
+	cpp_dev->client = msm_ion_client_create(-1, "cpp");
+
+	CPP_DBG("E\n");
+	if (!cpp_dev->domain) {
+		pr_err("domain / iommu context not found\n");
+		return  -ENODEV;
+	}
+
+	CPP_DBG("X\n");
+	return rc;
+}
+
+static void cpp_deinit_mem(struct cpp_device *cpp_dev)
+{
+	CPP_DBG("E\n");
+	kref_put(&cpp_dev->refcount, cpp_release_ion_client);
+	CPP_DBG("X\n");
+}
+
+static irqreturn_t msm_cpp_irq(int irq_num, void *data)
+{
+	uint32_t tx_level;
+	uint32_t irq_status;
+	uint32_t msg_id, cmd_len;
+	uint32_t i;
+	uint32_t tx_fifo[16];
+	struct cpp_device *cpp_dev = data;
+	irq_status = msm_camera_io_r(cpp_dev->base + MSM_CPP_MICRO_IRQGEN_STAT);
+	CPP_DBG("status: 0x%x\n", irq_status);
+	if (irq_status & 0x8) {
+		tx_level = msm_camera_io_r(cpp_dev->base +
+			MSM_CPP_MICRO_FIFO_TX_STAT) >> 2;
+		for (i = 0; i < tx_level; i++) {
+			tx_fifo[i] = msm_camera_io_r(cpp_dev->base +
+				MSM_CPP_MICRO_FIFO_TX_DATA);
+		}
+
+		for (i = 0; i < tx_level; i++) {
+			if (tx_fifo[i] == MSM_CPP_MSG_ID_CMD) {
+				cmd_len = tx_fifo[i+1];
+				msg_id = tx_fifo[i+2];
+				if (msg_id == MSM_CPP_MSG_ID_FRAME_ACK) {
+					CPP_DBG("Frame done!!\n");
+					msm_cpp_notify_frame_done(cpp_dev);
+				}
+				i += cmd_len + 2;
+			}
+		}
+	}
+	msm_camera_io_w(irq_status, cpp_dev->base + MSM_CPP_MICRO_IRQGEN_CLR);
+	return IRQ_HANDLED;
+}
+
+static void msm_cpp_boot_hw(struct cpp_device *cpp_dev)
+{
+	disable_irq(cpp_dev->irq->start);
+
+	msm_camera_io_w(0x1, cpp_dev->base + MSM_CPP_MICRO_CLKEN_CTL);
+	msm_camera_io_w(0x1, cpp_dev->base +
+				 MSM_CPP_MICRO_BOOT_START);
+	msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_CMD);
+
+	/*Trigger MC to jump to start address*/
+	msm_cpp_write(MSM_CPP_CMD_EXEC_JUMP, cpp_dev->base);
+	msm_cpp_write(MSM_CPP_JUMP_ADDRESS, cpp_dev->base);
+
+	msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_CMD);
+	msm_cpp_poll(cpp_dev->base, 0x1);
+	msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_JUMP_ACK);
+	msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_TRAILER);
+
+	/*Get Bootloader Version*/
+	msm_cpp_write(MSM_CPP_CMD_GET_BOOTLOADER_VER, cpp_dev->base);
+	pr_info("MC Bootloader Version: 0x%x\n",
+		   msm_cpp_read(cpp_dev->base));
+
+	/*Get Firmware Version*/
+	msm_cpp_write(MSM_CPP_CMD_GET_FW_VER, cpp_dev->base);
+	msm_cpp_write(MSM_CPP_MSG_ID_CMD, cpp_dev->base);
+	msm_cpp_write(0x1, cpp_dev->base);
+	msm_cpp_write(MSM_CPP_CMD_GET_FW_VER, cpp_dev->base);
+	msm_cpp_write(MSM_CPP_MSG_ID_TRAILER, cpp_dev->base);
+
+	msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_CMD);
+	msm_cpp_poll(cpp_dev->base, 0x2);
+	msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_FW_VER);
+	pr_info("CPP FW Version: 0x%x\n", msm_cpp_read(cpp_dev->base));
+	msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_TRAILER);
+	enable_irq(cpp_dev->irq->start);
+	msm_camera_io_w_mb(0x8, cpp_dev->base +
+		MSM_CPP_MICRO_IRQGEN_MASK);
+	msm_camera_io_w_mb(0xFFFF, cpp_dev->base +
+		MSM_CPP_MICRO_IRQGEN_CLR);
+}
+
+static int cpp_init_hardware(struct cpp_device *cpp_dev)
+{
+	int rc = 0;
+
+	if (cpp_dev->fs_cpp == NULL) {
+		cpp_dev->fs_cpp =
+			regulator_get(&cpp_dev->pdev->dev, "vdd");
+		if (IS_ERR(cpp_dev->fs_cpp)) {
+			pr_err("Regulator cpp vdd get failed %ld\n",
+				PTR_ERR(cpp_dev->fs_cpp));
+			cpp_dev->fs_cpp = NULL;
+			goto fs_failed;
+		} else if (regulator_enable(cpp_dev->fs_cpp)) {
+			pr_err("Regulator cpp vdd enable failed\n");
+			regulator_put(cpp_dev->fs_cpp);
+			cpp_dev->fs_cpp = NULL;
+			goto fs_failed;
+		}
+	}
+
+	rc = msm_cam_clk_enable(&cpp_dev->pdev->dev, cpp_clk_info,
+			cpp_dev->cpp_clk, ARRAY_SIZE(cpp_clk_info), 1);
+	if (rc < 0) {
+		pr_err("clk enable failed\n");
+		goto clk_failed;
+	}
+
+	cpp_dev->base = ioremap(cpp_dev->mem->start,
+		resource_size(cpp_dev->mem));
+	if (!cpp_dev->base) {
+		rc = -ENOMEM;
+		pr_err("ioremap failed\n");
+		goto remap_failed;
+	}
+
+	cpp_dev->vbif_base = ioremap(cpp_dev->vbif_mem->start,
+		resource_size(cpp_dev->vbif_mem));
+	if (!cpp_dev->vbif_base) {
+		rc = -ENOMEM;
+		pr_err("ioremap failed\n");
+		goto vbif_remap_failed;
+	}
+
+	if (cpp_dev->state != CPP_STATE_BOOT) {
+		rc = request_irq(cpp_dev->irq->start, msm_cpp_irq,
+			IRQF_TRIGGER_RISING, "cpp", cpp_dev);
+		if (rc < 0) {
+			pr_err("irq request fail\n");
+			rc = -EBUSY;
+			goto req_irq_fail;
+		}
+	}
+
+	msm_camera_io_w(0x1, cpp_dev->vbif_base + 0x4);
+	if (cpp_dev->is_firmware_loaded == 1)
+		msm_cpp_boot_hw(cpp_dev);
+	return rc;
+req_irq_fail:
+	iounmap(cpp_dev->vbif_base);
+vbif_remap_failed:
+	iounmap(cpp_dev->base);
+remap_failed:
+	msm_cam_clk_enable(&cpp_dev->pdev->dev, cpp_clk_info,
+		cpp_dev->cpp_clk, ARRAY_SIZE(cpp_clk_info), 0);
+clk_failed:
+	regulator_disable(cpp_dev->fs_cpp);
+	regulator_put(cpp_dev->fs_cpp);
+fs_failed:
+	return rc;
+}
+
+static void cpp_release_hardware(struct cpp_device *cpp_dev)
+{
+	if (cpp_dev->state != CPP_STATE_BOOT)
+		free_irq(cpp_dev->irq->start, cpp_dev);
+
+	iounmap(cpp_dev->base);
+	msm_cam_clk_enable(&cpp_dev->pdev->dev, cpp_clk_info,
+		cpp_dev->cpp_clk, ARRAY_SIZE(cpp_clk_info), 0);
+	if (0) {
+		regulator_disable(cpp_dev->fs_cpp);
+		regulator_put(cpp_dev->fs_cpp);
+		cpp_dev->fs_cpp = NULL;
+	}
+}
+
+static void cpp_load_fw(struct cpp_device *cpp_dev)
+{
+	uint32_t i;
+	uint32_t *ptr_bin = NULL;
+	int32_t rc = -EFAULT;
+	const struct firmware *fw = NULL;
+	char *fw_name_bin = "cpp_firmware_v1_1_1.fw";
+	struct device *dev = &cpp_dev->pdev->dev;
+
+	rc = request_firmware(&fw, fw_name_bin, dev);
+	if (rc) {
+		dev_err(dev, "Failed to locate blob %s from device %p, Error: %d\n",
+				fw_name_bin, dev, rc);
+	}
+
+	CPP_DBG("HW Ver:0x%x\n",
+		msm_camera_io_r(cpp_dev->base +
+		MSM_CPP_MICRO_HW_VERSION));
+
+	msm_camera_io_w(0x1, cpp_dev->base +
+					   MSM_CPP_MICRO_BOOT_START);
+	/*Enable MC clock*/
+	msm_camera_io_w(0x1, cpp_dev->base +
+					   MSM_CPP_MICRO_CLKEN_CTL);
+
+	msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_CMD);
+
+	/*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(MSM_CPP_START_ADDRESS, cpp_dev->base);
+	if (NULL != fw)
+		ptr_bin = (uint32_t *)fw->data;
+
+	for (i = 0; i < fw->size/4; i++) {
+		if (ptr_bin) {
+			msm_cpp_write(*ptr_bin, cpp_dev->base);
+			ptr_bin++;
+		}
+	}
+	if (fw)
+		release_firmware(fw);
+
+	msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_OK);
+	msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_CMD);
+
+	/*Trigger MC to jump to start address*/
+	msm_cpp_write(MSM_CPP_CMD_EXEC_JUMP, cpp_dev->base);
+	msm_cpp_write(MSM_CPP_JUMP_ADDRESS, cpp_dev->base);
+
+	msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_CMD);
+	msm_cpp_poll(cpp_dev->base, 0x1);
+	msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_JUMP_ACK);
+	msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_TRAILER);
+
+	/*Get Bootloader Version*/
+	msm_cpp_write(MSM_CPP_CMD_GET_BOOTLOADER_VER, cpp_dev->base);
+	pr_info("MC Bootloader Version: 0x%x\n",
+		   msm_cpp_read(cpp_dev->base));
+
+	/*Get Firmware Version*/
+	msm_cpp_write(MSM_CPP_CMD_GET_FW_VER, cpp_dev->base);
+	msm_cpp_write(MSM_CPP_MSG_ID_CMD, cpp_dev->base);
+	msm_cpp_write(0x1, cpp_dev->base);
+	msm_cpp_write(MSM_CPP_CMD_GET_FW_VER, cpp_dev->base);
+	msm_cpp_write(MSM_CPP_MSG_ID_TRAILER, cpp_dev->base);
+
+	msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_CMD);
+	msm_cpp_poll(cpp_dev->base, 0x2);
+	msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_FW_VER);
+	pr_info("CPP FW Version: 0x%x\n", msm_cpp_read(cpp_dev->base));
+	msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_TRAILER);
+
+	/*Disable MC clock*/
+	/*msm_camera_io_w(0x0, cpp_dev->base +
+					   MSM_CPP_MICRO_CLKEN_CTL);*/
+}
+
+static int cpp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	uint32_t i;
+	struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd);
+	CPP_DBG("E\n");
+
+	mutex_lock(&cpp_dev->mutex);
+	if (cpp_dev->cpp_open_cnt == MAX_ACTIVE_CPP_INSTANCE) {
+		pr_err("No free CPP instance\n");
+		mutex_unlock(&cpp_dev->mutex);
+		return -ENODEV;
+	}
+
+	for (i = 0; i < MAX_ACTIVE_CPP_INSTANCE; i++) {
+		if (cpp_dev->cpp_subscribe_list[i].active == 0) {
+			cpp_dev->cpp_subscribe_list[i].active = 1;
+			cpp_dev->cpp_subscribe_list[i].vfh = &fh->vfh;
+			break;
+		}
+	}
+	if (i == MAX_ACTIVE_CPP_INSTANCE) {
+		pr_err("No free instance\n");
+		mutex_unlock(&cpp_dev->mutex);
+		return -ENODEV;
+	}
+
+	CPP_DBG("open %d %p\n", i, &fh->vfh);
+	cpp_dev->cpp_open_cnt++;
+	if (cpp_dev->cpp_open_cnt == 1) {
+		cpp_init_hardware(cpp_dev);
+		cpp_init_mem(cpp_dev);
+		cpp_dev->state = CPP_STATE_IDLE;
+	}
+	mutex_unlock(&cpp_dev->mutex);
+	return 0;
+}
+
+static int cpp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	uint32_t i;
+	struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd);
+	mutex_lock(&cpp_dev->mutex);
+	for (i = 0; i < MAX_ACTIVE_CPP_INSTANCE; i++) {
+		if (cpp_dev->cpp_subscribe_list[i].vfh == &fh->vfh) {
+			cpp_dev->cpp_subscribe_list[i].active = 0;
+			cpp_dev->cpp_subscribe_list[i].vfh = NULL;
+			break;
+		}
+	}
+	if (i == MAX_ACTIVE_CPP_INSTANCE) {
+		pr_err("Invalid close\n");
+		mutex_unlock(&cpp_dev->mutex);
+		return -ENODEV;
+	}
+
+	CPP_DBG("close %d %p\n", i, &fh->vfh);
+	cpp_dev->cpp_open_cnt--;
+	if (cpp_dev->cpp_open_cnt == 0) {
+		msm_camera_io_w(0x0, cpp_dev->base + MSM_CPP_MICRO_CLKEN_CTL);
+		cpp_deinit_mem(cpp_dev);
+		cpp_release_hardware(cpp_dev);
+		cpp_dev->state = CPP_STATE_OFF;
+	}
+	mutex_unlock(&cpp_dev->mutex);
+	return 0;
+}
+
+static const struct v4l2_subdev_internal_ops msm_cpp_internal_ops = {
+	.open = cpp_open_node,
+	.close = cpp_close_node,
+};
+
+static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev)
+{
+	struct v4l2_event v4l2_evt;
+	struct msm_queue_cmd *frame_qcmd;
+	struct msm_queue_cmd *event_qcmd;
+	struct msm_cpp_frame_info_t *processed_frame;
+	struct msm_device_queue *queue = &cpp_dev->processing_q;
+
+	if (queue->len > 0) {
+		frame_qcmd = msm_dequeue(queue, list_frame);
+		processed_frame = frame_qcmd->command;
+		kfree(frame_qcmd);
+		event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_ATOMIC);
+		if (!event_qcmd) {
+			pr_err("Insufficient memory. return");
+			return -ENOMEM;
+		}
+		atomic_set(&event_qcmd->on_heap, 1);
+		event_qcmd->command = processed_frame;
+		CPP_DBG("fid %d\n", processed_frame->frame_id);
+		msm_enqueue(&cpp_dev->eventData_q, &event_qcmd->list_eventdata);
+
+		v4l2_evt.id = processed_frame->inst_id;
+		v4l2_evt.type = V4L2_EVENT_CPP_FRAME_DONE;
+		v4l2_event_queue(cpp_dev->msm_sd.sd.devnode, &v4l2_evt);
+	}
+	return 0;
+}
+
+static int msm_cpp_send_frame_to_hardware(struct cpp_device *cpp_dev)
+{
+	uint32_t i;
+	struct msm_queue_cmd *frame_qcmd;
+	struct msm_cpp_frame_info_t *process_frame;
+	struct msm_device_queue *queue;
+
+	if (cpp_dev->processing_q.len < MAX_CPP_PROCESSING_FRAME) {
+		while (cpp_dev->processing_q.len < MAX_CPP_PROCESSING_FRAME) {
+			if (cpp_dev->realtime_q.len != 0) {
+				queue = &cpp_dev->realtime_q;
+			} else if (cpp_dev->offline_q.len != 0) {
+				queue = &cpp_dev->offline_q;
+			} else {
+				pr_debug("All frames queued\n");
+				break;
+			}
+			frame_qcmd = msm_dequeue(queue, list_frame);
+			process_frame = frame_qcmd->command;
+			msm_enqueue(&cpp_dev->processing_q,
+						&frame_qcmd->list_frame);
+			msm_cpp_write(0x6, cpp_dev->base);
+			for (i = 0; i < process_frame->msg_len; i++)
+				msm_cpp_write(process_frame->cpp_cmd_msg[i],
+					cpp_dev->base);
+		}
+	}
+	return 0;
+}
+
+static int msm_cpp_cfg(struct cpp_device *cpp_dev,
+	struct msm_camera_v4l2_ioctl_t *ioctl_ptr)
+{
+	int rc = 0;
+	struct msm_queue_cmd *frame_qcmd = NULL;
+	struct msm_cpp_frame_info_t *new_frame =
+		kzalloc(sizeof(struct msm_cpp_frame_info_t), GFP_KERNEL);
+	uint32_t *cpp_frame_msg;
+	unsigned long len;
+	unsigned long in_phyaddr, out_phyaddr;
+	uint16_t num_stripes = 0;
+
+	int i = 0;
+	if (!new_frame) {
+		pr_err("Insufficient memory. return\n");
+		return -ENOMEM;
+	}
+
+	rc = (copy_from_user(new_frame, (void __user *)ioctl_ptr->ioctl_ptr,
+		sizeof(struct msm_cpp_frame_info_t)) ? -EFAULT : 0);
+	if (rc) {
+		ERR_COPY_FROM_USER();
+		rc = -EINVAL;
+		goto ERROR1;
+	}
+
+	cpp_frame_msg = kzalloc(sizeof(uint32_t)*new_frame->msg_len,
+		GFP_KERNEL);
+	if (!cpp_frame_msg) {
+		pr_err("Insufficient memory. return");
+		rc = -ENOMEM;
+		goto ERROR1;
+	}
+
+	rc = (copy_from_user(cpp_frame_msg,
+		(void __user *)new_frame->cpp_cmd_msg,
+		sizeof(uint32_t)*new_frame->msg_len) ? -EFAULT : 0);
+	if (rc) {
+		ERR_COPY_FROM_USER();
+		rc = -EINVAL;
+		goto ERROR2;
+	}
+
+	new_frame->cpp_cmd_msg = cpp_frame_msg;
+
+	CPP_DBG("CPP in_fd: %d out_fd: %d\n", new_frame->src_fd,
+		new_frame->dst_fd);
+
+	new_frame->src_ion_handle = ion_import_dma_buf(cpp_dev->client,
+		new_frame->src_fd);
+	if (IS_ERR_OR_NULL(new_frame->src_ion_handle)) {
+		pr_err("ION import failed\n");
+		rc = PTR_ERR(new_frame->src_ion_handle);
+		goto ERROR2;
+	}
+
+	rc = ion_map_iommu(cpp_dev->client, new_frame->src_ion_handle,
+		cpp_dev->domain_num, 0, SZ_4K, 0,
+		(unsigned long *)&in_phyaddr, &len, 0, 0);
+	if (rc < 0) {
+		pr_err("ION import failed\n");
+		rc = PTR_ERR(new_frame->src_ion_handle);
+		goto ERROR3;
+	}
+
+	CPP_DBG("in phy addr: 0x%x len: %ld\n", (uint32_t) in_phyaddr, len);
+	new_frame->dest_ion_handle = ion_import_dma_buf(cpp_dev->client,
+		new_frame->dst_fd);
+	if (IS_ERR_OR_NULL(new_frame->dest_ion_handle)) {
+		pr_err("ION import failed\n");
+		rc = PTR_ERR(new_frame->dest_ion_handle);
+		goto ERROR4;
+	}
+
+	rc = ion_map_iommu(cpp_dev->client, new_frame->dest_ion_handle,
+		cpp_dev->domain_num, 0, SZ_4K, 0,
+		(unsigned long *)&out_phyaddr, &len, 0, 0);
+	if (rc < 0) {
+		rc = PTR_ERR(new_frame->dest_ion_handle);
+		goto ERROR5;
+	}
+
+	CPP_DBG("out phy addr: 0x%x len: %ld\n", (uint32_t)out_phyaddr, len);
+	num_stripes = ((cpp_frame_msg[12] >> 20) & 0x3FF) +
+		((cpp_frame_msg[12] >> 10) & 0x3FF) +
+		(cpp_frame_msg[12] & 0x3FF);
+
+	for (i = 0; i < num_stripes; i++) {
+		cpp_frame_msg[133 + i * 27] += (uint32_t) in_phyaddr;
+		cpp_frame_msg[139 + i * 27] += (uint32_t) out_phyaddr;
+		cpp_frame_msg[140 + i * 27] += (uint32_t) out_phyaddr;
+		cpp_frame_msg[141 + i * 27] += (uint32_t) out_phyaddr;
+		cpp_frame_msg[142 + i * 27] += (uint32_t) out_phyaddr;
+	}
+
+	frame_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
+	if (!frame_qcmd) {
+		pr_err("Insufficient memory. return\n");
+		rc = -ENOMEM;
+		goto ERROR6;
+	}
+
+	atomic_set(&frame_qcmd->on_heap, 1);
+	frame_qcmd->command = new_frame;
+	if (new_frame->frame_type == MSM_CPP_REALTIME_FRAME) {
+		msm_enqueue(&cpp_dev->realtime_q,
+					&frame_qcmd->list_frame);
+	} else if (new_frame->frame_type == MSM_CPP_OFFLINE_FRAME) {
+		msm_enqueue(&cpp_dev->offline_q,
+					&frame_qcmd->list_frame);
+	} else {
+		pr_err("Invalid frame type\n");
+		rc = -EINVAL;
+		goto ERROR7;
+	}
+	msm_cpp_send_frame_to_hardware(cpp_dev);
+	return rc;
+ERROR7:
+	kfree(frame_qcmd);
+ERROR6:
+	ion_unmap_iommu(cpp_dev->client, new_frame->dest_ion_handle,
+		cpp_dev->domain_num, 0);
+ERROR5:
+	ion_free(cpp_dev->client, new_frame->dest_ion_handle);
+	new_frame->dest_ion_handle = NULL;
+ERROR4:
+	ion_unmap_iommu(cpp_dev->client, new_frame->src_ion_handle,
+		cpp_dev->domain_num, 0);
+ERROR3:
+	ion_free(cpp_dev->client, new_frame->src_ion_handle);
+	new_frame->src_ion_handle = NULL;
+ERROR2:
+	kfree(cpp_frame_msg);
+ERROR1:
+	kfree(new_frame);
+	return rc;
+
+}
+
+long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int cmd, void *arg)
+{
+	struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd);
+	struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
+	int rc = 0;
+
+	mutex_lock(&cpp_dev->mutex);
+	CPP_DBG("E cmd: %d\n", cmd);
+	switch (cmd) {
+	case VIDIOC_MSM_CPP_LOAD_FIRMWARE: {
+		if (cpp_dev->is_firmware_loaded == 0) {
+			disable_irq(cpp_dev->irq->start);
+			cpp_load_fw(cpp_dev);
+			enable_irq(cpp_dev->irq->start);
+			cpp_dev->is_firmware_loaded = 1;
+		}
+		break;
+	}
+	case VIDIOC_MSM_CPP_CFG:
+		rc = msm_cpp_cfg(cpp_dev, ioctl_ptr);
+		break;
+	case VIDIOC_MSM_CPP_GET_EVENTPAYLOAD: {
+		struct msm_device_queue *queue = &cpp_dev->eventData_q;
+		struct msm_queue_cmd *event_qcmd;
+		struct msm_cpp_frame_info_t *process_frame;
+		event_qcmd = msm_dequeue(queue, list_eventdata);
+		process_frame = event_qcmd->command;
+		CPP_DBG("fid %d\n", process_frame->frame_id);
+		if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
+				process_frame,
+				sizeof(struct msm_cpp_frame_info_t))) {
+					mutex_unlock(&cpp_dev->mutex);
+					return -EINVAL;
+		}
+		if (process_frame->dest_ion_handle) {
+			ion_unmap_iommu(cpp_dev->client,
+				process_frame->dest_ion_handle,
+				cpp_dev->domain_num, 0);
+			ion_free(cpp_dev->client,
+				process_frame->dest_ion_handle);
+			process_frame->dest_ion_handle = NULL;
+		}
+
+		if (process_frame->src_ion_handle) {
+			ion_unmap_iommu(cpp_dev->client,
+				process_frame->src_ion_handle,
+				cpp_dev->domain_num, 0);
+			ion_free(cpp_dev->client,
+				process_frame->src_ion_handle);
+			process_frame->src_ion_handle = NULL;
+		}
+
+		kfree(process_frame->cpp_cmd_msg);
+		kfree(process_frame);
+		kfree(event_qcmd);
+		break;
+	}
+	}
+	mutex_unlock(&cpp_dev->mutex);
+	CPP_DBG("X\n");
+	return 0;
+}
+
+int msm_cpp_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+	struct v4l2_event_subscription *sub)
+{
+	CPP_DBG("Called\n");
+	return v4l2_event_subscribe(fh, sub, MAX_CPP_V4l2_EVENTS);
+}
+
+int msm_cpp_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+	struct v4l2_event_subscription *sub)
+{
+	CPP_DBG("Called\n");
+	return v4l2_event_unsubscribe(fh, sub);
+}
+
+static struct v4l2_subdev_core_ops msm_cpp_subdev_core_ops = {
+	.ioctl = msm_cpp_subdev_ioctl,
+	.subscribe_event = msm_cpp_subscribe_event,
+	.unsubscribe_event = msm_cpp_unsubscribe_event,
+};
+
+static const struct v4l2_subdev_ops msm_cpp_subdev_ops = {
+	.core = &msm_cpp_subdev_core_ops,
+};
+
+static int msm_cpp_enable_debugfs(struct cpp_device *cpp_dev);
+
+static struct v4l2_file_operations msm_cpp_v4l2_subdev_fops;
+
+static long msm_cpp_subdev_do_ioctl(
+	struct file *file, unsigned int cmd, void *arg)
+{
+	struct video_device *vdev = video_devdata(file);
+	struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
+	struct v4l2_fh *vfh = file->private_data;
+
+	switch (cmd) {
+	case VIDIOC_DQEVENT:
+		if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS))
+			return -ENOIOCTLCMD;
+
+		return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK);
+
+	case VIDIOC_SUBSCRIBE_EVENT:
+		return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg);
+
+	case VIDIOC_UNSUBSCRIBE_EVENT:
+		return v4l2_subdev_call(sd, core, unsubscribe_event, vfh, arg);
+
+	case VIDIOC_MSM_CPP_GET_INST_INFO: {
+		uint32_t i;
+		struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd);
+		struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
+		struct msm_cpp_frame_info_t inst_info;
+		for (i = 0; i < MAX_ACTIVE_CPP_INSTANCE; i++) {
+			if (cpp_dev->cpp_subscribe_list[i].vfh == vfh) {
+				inst_info.inst_id = i;
+				break;
+			}
+		}
+		if (copy_to_user(
+				(void __user *)ioctl_ptr->ioctl_ptr, &inst_info,
+				sizeof(struct msm_cpp_frame_info_t))) {
+			return -EINVAL;
+		}
+	}
+	break;
+	default:
+		return v4l2_subdev_call(sd, core, ioctl, cmd, arg);
+	}
+
+	return 0;
+}
+
+static long msm_cpp_subdev_fops_ioctl(struct file *file, unsigned int cmd,
+	unsigned long arg)
+{
+	return video_usercopy(file, cmd, arg, msm_cpp_subdev_do_ioctl);
+}
+
+static int cpp_register_domain(void)
+{
+	struct msm_iova_partition cpp_fw_partition = {
+		.start = SZ_128K,
+		.size = SZ_2G - SZ_128K,
+	};
+	struct msm_iova_layout cpp_fw_layout = {
+		.partitions = &cpp_fw_partition,
+		.npartitions = 1,
+		.client_name = "camera_cpp",
+		.domain_flags = 0,
+	};
+
+	return msm_register_domain(&cpp_fw_layout);
+}
+
+static int __devinit cpp_probe(struct platform_device *pdev)
+{
+	struct cpp_device *cpp_dev;
+	int rc = 0;
+
+	cpp_dev = kzalloc(sizeof(struct cpp_device), GFP_KERNEL);
+	if (!cpp_dev) {
+		pr_err("no enough memory\n");
+		return -ENOMEM;
+	}
+
+	cpp_dev->cpp_clk = kzalloc(sizeof(struct clk *) *
+		ARRAY_SIZE(cpp_clk_info), GFP_KERNEL);
+	if (!cpp_dev->cpp_clk) {
+		pr_err("no enough memory\n");
+		rc = -ENOMEM;
+		goto ERROR1;
+	}
+
+	v4l2_subdev_init(&cpp_dev->msm_sd.sd, &msm_cpp_subdev_ops);
+	cpp_dev->msm_sd.sd.internal_ops = &msm_cpp_internal_ops;
+	snprintf(cpp_dev->msm_sd.sd.name, ARRAY_SIZE(cpp_dev->msm_sd.sd.name),
+		 "cpp");
+	cpp_dev->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	cpp_dev->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_EVENTS;
+	v4l2_set_subdevdata(&cpp_dev->msm_sd.sd, cpp_dev);
+	platform_set_drvdata(pdev, &cpp_dev->msm_sd.sd);
+	mutex_init(&cpp_dev->mutex);
+
+	if (pdev->dev.of_node)
+		of_property_read_u32((&pdev->dev)->of_node,
+					"cell-index", &pdev->id);
+
+	cpp_dev->pdev = pdev;
+
+	cpp_dev->mem = platform_get_resource_byname(pdev,
+					IORESOURCE_MEM, "cpp");
+	if (!cpp_dev->mem) {
+		pr_err("no mem resource?\n");
+		rc = -ENODEV;
+		goto ERROR2;
+	}
+
+	cpp_dev->vbif_mem = platform_get_resource_byname(pdev,
+					IORESOURCE_MEM, "cpp_vbif");
+	if (!cpp_dev->vbif_mem) {
+		pr_err("no mem resource?\n");
+		rc = -ENODEV;
+		goto ERROR2;
+	}
+
+	cpp_dev->irq = platform_get_resource_byname(pdev,
+					IORESOURCE_IRQ, "cpp");
+	if (!cpp_dev->irq) {
+		pr_err("%s: no irq resource?\n", __func__);
+		rc = -ENODEV;
+		goto ERROR2;
+	}
+
+	cpp_dev->io = request_mem_region(cpp_dev->mem->start,
+		resource_size(cpp_dev->mem), pdev->name);
+	if (!cpp_dev->io) {
+		pr_err("%s: no valid mem region\n", __func__);
+		rc = -EBUSY;
+		goto ERROR2;
+	}
+
+	cpp_dev->domain_num = cpp_register_domain();
+	if (cpp_dev->domain_num < 0) {
+		pr_err("%s: could not register domain\n", __func__);
+		rc = -ENODEV;
+		goto ERROR3;
+	}
+
+	cpp_dev->domain =
+		msm_get_iommu_domain(cpp_dev->domain_num);
+	if (!cpp_dev->domain) {
+		pr_err("%s: cannot find domain\n", __func__);
+		rc = -ENODEV;
+		goto ERROR3;
+	}
+
+	cpp_dev->iommu_ctx = msm_iommu_get_ctx("cpp");
+	if (!cpp_dev->iommu_ctx) {
+		pr_err("%s: cannot get iommu_ctx\n", __func__);
+		rc = -ENODEV;
+		goto ERROR3;
+	}
+
+	media_entity_init(&cpp_dev->msm_sd.sd.entity, 0, NULL, 0);
+	cpp_dev->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	cpp_dev->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_CPP;
+	cpp_dev->msm_sd.sd.entity.name = pdev->name;
+	msm_sd_register(&cpp_dev->msm_sd);
+	msm_cpp_v4l2_subdev_fops.owner = v4l2_subdev_fops.owner;
+	msm_cpp_v4l2_subdev_fops.open = v4l2_subdev_fops.open;
+	msm_cpp_v4l2_subdev_fops.unlocked_ioctl = msm_cpp_subdev_fops_ioctl;
+	msm_cpp_v4l2_subdev_fops.release = v4l2_subdev_fops.release;
+	msm_cpp_v4l2_subdev_fops.poll = v4l2_subdev_fops.poll;
+
+	cpp_dev->msm_sd.sd.devnode->fops = &msm_cpp_v4l2_subdev_fops;
+	cpp_dev->msm_sd.sd.entity.revision = cpp_dev->msm_sd.sd.devnode->num;
+	cpp_dev->state = CPP_STATE_BOOT;
+	cpp_init_hardware(cpp_dev);
+	iommu_attach_device(cpp_dev->domain, cpp_dev->iommu_ctx);
+
+	msm_camera_io_w(0x0, cpp_dev->base +
+					   MSM_CPP_MICRO_IRQGEN_MASK);
+	msm_camera_io_w(0xFFFF, cpp_dev->base +
+					   MSM_CPP_MICRO_IRQGEN_CLR);
+
+	cpp_release_hardware(cpp_dev);
+	cpp_dev->state = CPP_STATE_OFF;
+
+	msm_cpp_enable_debugfs(cpp_dev);
+	msm_queue_init(&cpp_dev->eventData_q, "eventdata");
+	msm_queue_init(&cpp_dev->offline_q, "frame");
+	msm_queue_init(&cpp_dev->realtime_q, "frame");
+	msm_queue_init(&cpp_dev->processing_q, "frame");
+	cpp_dev->cpp_open_cnt = 0;
+	cpp_dev->is_firmware_loaded = 0;
+
+	return rc;
+
+ERROR3:
+	release_mem_region(cpp_dev->mem->start, resource_size(cpp_dev->mem));
+ERROR2:
+	kfree(cpp_dev->cpp_clk);
+ERROR1:
+	kfree(cpp_dev);
+	return rc;
+}
+
+static const struct of_device_id msm_cpp_dt_match[] = {
+	{.compatible = "qcom,cpp"},
+	{}
+};
+
+static int cpp_device_remove(struct platform_device *dev)
+{
+	struct v4l2_subdev *sd = platform_get_drvdata(dev);
+	struct cpp_device  *cpp_dev;
+	if (!sd) {
+		pr_err("%s: Subdevice is NULL\n", __func__);
+		return 0;
+	}
+
+	cpp_dev = (struct cpp_device *)v4l2_get_subdevdata(sd);
+	if (!cpp_dev) {
+		pr_err("%s: cpp device is NULL\n", __func__);
+		return 0;
+	}
+
+	iommu_detach_device(cpp_dev->domain, cpp_dev->iommu_ctx);
+	msm_sd_unregister(&cpp_dev->msm_sd);
+	release_mem_region(cpp_dev->mem->start, resource_size(cpp_dev->mem));
+	mutex_destroy(&cpp_dev->mutex);
+	kfree(cpp_dev->cpp_clk);
+	kfree(cpp_dev);
+	return 0;
+}
+
+static struct platform_driver cpp_driver = {
+	.probe = cpp_probe,
+	.remove = cpp_device_remove,
+	.driver = {
+		.name = MSM_CPP_DRV_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = msm_cpp_dt_match,
+	},
+};
+
+static int __init msm_cpp_init_module(void)
+{
+	return platform_driver_register(&cpp_driver);
+}
+
+static void __exit msm_cpp_exit_module(void)
+{
+	platform_driver_unregister(&cpp_driver);
+}
+
+static int msm_cpp_debugfs_stream_s(void *data, u64 val)
+{
+	struct cpp_device *cpp_dev = data;
+	CPP_DBG("CPP processing frame E\n");
+	while (1) {
+		mutex_lock(&cpp_dev->mutex);
+		msm_cpp_notify_frame_done(cpp_dev);
+		msm_cpp_send_frame_to_hardware(cpp_dev);
+		mutex_unlock(&cpp_dev->mutex);
+		msleep(20);
+	}
+	CPP_DBG("CPP processing frame X\n");
+	return 0;
+}
+
+static int msm_cpp_debugfs_load_fw(void *data, u64 val)
+{
+	const struct firmware *fw = NULL;
+	struct cpp_device *cpp_dev = data;
+	int rc = 0;
+	CPP_DBG("%s\n", __func__);
+	rc = request_firmware(&fw, "FIRMWARE.bin", &cpp_dev->pdev->dev);
+	if (rc) {
+		pr_err("request_fw failed\n");
+	} else {
+		CPP_DBG("request ok\n");
+		release_firmware(fw);
+	}
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(cpp_debugfs_stream, NULL,
+			msm_cpp_debugfs_stream_s, "%llu\n");
+DEFINE_SIMPLE_ATTRIBUTE(cpp_debugfs_fw, NULL,
+			msm_cpp_debugfs_load_fw, "%llu\n");
+
+static int msm_cpp_enable_debugfs(struct cpp_device *cpp_dev)
+{
+	struct dentry *debugfs_base, *debugfs_test;
+	debugfs_base = debugfs_create_dir("msm_camera", NULL);
+	if (!debugfs_base)
+		return -ENOMEM;
+
+	debugfs_test = debugfs_create_file("test", S_IRUGO | S_IWUSR,
+		debugfs_base, (void *)cpp_dev, &cpp_debugfs_stream);
+	if (!debugfs_test) {
+		debugfs_remove(debugfs_base);
+		return -ENOMEM;
+	}
+
+	if (!debugfs_create_file("fw", S_IRUGO | S_IWUSR, debugfs_base,
+			(void *)cpp_dev, &cpp_debugfs_fw)) {
+		debugfs_remove(debugfs_test);
+		debugfs_remove(debugfs_base);
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+module_init(msm_cpp_init_module);
+module_exit(msm_cpp_exit_module);
+MODULE_DESCRIPTION("MSM CPP driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h
new file mode 100644
index 0000000..e8e37ed
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h
@@ -0,0 +1,156 @@
+/* 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 __MSM_CPP_H__
+#define __MSM_CPP_H__
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+#include <media/v4l2-subdev.h>
+#include "msm_sd.h"
+
+#define MAX_ACTIVE_CPP_INSTANCE 8
+#define MAX_CPP_PROCESSING_FRAME 2
+#define MAX_CPP_V4l2_EVENTS 30
+
+#define MSM_CPP_MICRO_BASE          0x4000
+#define MSM_CPP_MICRO_HW_VERSION    0x0000
+#define MSM_CPP_MICRO_IRQGEN_STAT   0x0004
+#define MSM_CPP_MICRO_IRQGEN_CLR    0x0008
+#define MSM_CPP_MICRO_IRQGEN_MASK   0x000C
+#define MSM_CPP_MICRO_FIFO_TX_DATA  0x0010
+#define MSM_CPP_MICRO_FIFO_TX_STAT  0x0014
+#define MSM_CPP_MICRO_FIFO_RX_DATA  0x0018
+#define MSM_CPP_MICRO_FIFO_RX_STAT  0x001C
+#define MSM_CPP_MICRO_BOOT_START    0x0020
+#define MSM_CPP_MICRO_BOOT_LDORG    0x0024
+#define MSM_CPP_MICRO_CLKEN_CTL     0x0030
+
+#define MSM_CPP_CMD_GET_BOOTLOADER_VER	0x1
+#define MSM_CPP_CMD_FW_LOAD				0x2
+#define MSM_CPP_CMD_EXEC_JUMP			0x3
+#define MSM_CPP_CMD_RESET_HW			0x5
+#define MSM_CPP_CMD_PROCESS_FRAME		0x6
+#define MSM_CPP_CMD_FLUSH_STREAM		0x7
+#define MSM_CPP_CMD_CFG_MEM_PARAM		0x8
+#define MSM_CPP_CMD_ERROR_REQUEST		0x9
+#define MSM_CPP_CMD_GET_STATUS			0xA
+#define MSM_CPP_CMD_GET_FW_VER			0xB
+
+#define MSM_CPP_MSG_ID_CMD          0x3E646D63
+#define MSM_CPP_MSG_ID_OK           0x0A0A4B4F
+#define MSM_CPP_MSG_ID_TRAILER      0xABCDEFAA
+
+#define MSM_CPP_MSG_ID_JUMP_ACK     0x00000001
+#define MSM_CPP_MSG_ID_FRAME_ACK    0x00000002
+#define MSM_CPP_MSG_ID_FRAME_NACK   0x00000003
+#define MSM_CPP_MSG_ID_FLUSH_ACK    0x00000004
+#define MSM_CPP_MSG_ID_FLUSH_NACK   0x00000005
+#define MSM_CPP_MSG_ID_CFG_MEM_ACK  0x00000006
+#define MSM_CPP_MSG_ID_CFG_MEM_INV  0x00000007
+#define MSM_CPP_MSG_ID_ERROR_STATUS 0x00000008
+#define MSM_CPP_MSG_ID_INVALID_CMD  0x00000009
+#define MSM_CPP_MSG_ID_GEN_STATUS   0x0000000A
+#define MSM_CPP_MSG_ID_FLUSHED      0x0000000B
+#define MSM_CPP_MSG_ID_FW_VER       0x0000000C
+
+#define MSM_CPP_JUMP_ADDRESS		0x20
+#define MSM_CPP_START_ADDRESS		0x0
+#define MSM_CPP_END_ADDRESS			0x3F00
+
+#define MSM_CPP_POLL_RETRIES		20
+
+struct cpp_subscribe_info {
+	struct v4l2_fh *vfh;
+	uint32_t active;
+};
+
+enum cpp_state {
+	CPP_STATE_BOOT,
+	CPP_STATE_IDLE,
+	CPP_STATE_ACTIVE,
+	CPP_STATE_OFF,
+};
+
+enum msm_queue {
+	MSM_CAM_Q_CTRL,     /* control command or control command status */
+	MSM_CAM_Q_VFE_EVT,  /* adsp event */
+	MSM_CAM_Q_VFE_MSG,  /* adsp message */
+	MSM_CAM_Q_V4L2_REQ, /* v4l2 request */
+	MSM_CAM_Q_VPE_MSG,  /* vpe message */
+	MSM_CAM_Q_PP_MSG,  /* pp message */
+};
+
+struct msm_queue_cmd {
+	struct list_head list_config;
+	struct list_head list_control;
+	struct list_head list_frame;
+	struct list_head list_pict;
+	struct list_head list_vpe_frame;
+	struct list_head list_eventdata;
+	enum msm_queue type;
+	void *command;
+	atomic_t on_heap;
+	struct timespec ts;
+	uint32_t error_code;
+	uint32_t trans_code;
+};
+
+struct msm_device_queue {
+	struct list_head list;
+	spinlock_t lock;
+	wait_queue_head_t wait;
+	int max;
+	int len;
+	const char *name;
+};
+
+struct cpp_device {
+	struct platform_device *pdev;
+	struct msm_sd_subdev msm_sd;
+	struct v4l2_subdev subdev;
+	struct resource *mem;
+	struct resource *irq;
+	struct resource *io;
+	struct resource	*vbif_mem;
+	struct resource *vbif_io;
+	void __iomem *vbif_base;
+	void __iomem *base;
+	struct clk **cpp_clk;
+	struct regulator *fs_cpp;
+	struct mutex mutex;
+	enum cpp_state state;
+	uint8_t is_firmware_loaded;
+
+	int domain_num;
+	struct iommu_domain *domain;
+	struct device *iommu_ctx;
+	struct ion_client *client;
+	struct kref refcount;
+
+	struct cpp_subscribe_info cpp_subscribe_list[MAX_ACTIVE_CPP_INSTANCE];
+	uint32_t cpp_open_cnt;
+
+	struct msm_device_queue eventData_q; /* V4L2 Event Payload Queue */
+
+	/* Offline Frame Queue process when realtime queue is empty */
+	struct msm_device_queue offline_q;
+	/* Realtime Frame Queue process with highest priority */
+	struct msm_device_queue realtime_q;
+	/* Processing Queue
+	 * store frame info for frames sent to microcontroller
+	 */
+	struct msm_device_queue processing_q;
+};
+#endif /* __MSM_CPP_H__ */
diff --git a/drivers/media/platform/msm/camera_v2/sensor/Makefile b/drivers/media/platform/msm/camera_v2/sensor/Makefile
new file mode 100644
index 0000000..6f941f7
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/Makefile
@@ -0,0 +1,11 @@
+ccflags-y += -Idrivers/media/platform/msm/camera_v2
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/msm_vb2
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/camera
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/cci
+obj-$(CONFIG_MSMB_CAMERA) += cci/ io/ csiphy/ csid/ actuator/ flash/
+obj-$(CONFIG_MSM_CAMERA_SENSOR) += msm_sensor.o
+obj-$(CONFIG_S5K3L1YX) += s5k3l1yx.o
+obj-$(CONFIG_IMX135) += imx135.o
+obj-$(CONFIG_OV2720) += ov2720.o
+obj-$(CONFIG_MT9M114) += mt9m114.o
diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/Makefile b/drivers/media/platform/msm/camera_v2/sensor/actuator/Makefile
new file mode 100644
index 0000000..c0d607f
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/Makefile
@@ -0,0 +1,4 @@
+ccflags-y += -Idrivers/media/platform/msm/camera_v2
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/cci
+obj-$(CONFIG_MSMB_CAMERA) += msm_actuator.o
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
new file mode 100644
index 0000000..e939c2b
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
@@ -0,0 +1,858 @@
+/* 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.
+ */
+
+#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__
+
+#include <linux/module.h>
+#include "msm_sd.h"
+#include "msm_actuator.h"
+#include "msm_cci.h"
+
+DEFINE_MSM_MUTEX(msm_actuator_mutex);
+
+/*#define MSM_ACUTUATOR_DEBUG*/
+#undef CDBG
+#ifdef MSM_ACUTUATOR_DEBUG
+#define CDBG(fmt, args...) pr_err(fmt, ##args)
+#else
+#define CDBG(fmt, args...) pr_debug(fmt, ##args)
+#endif
+
+static struct msm_actuator_ctrl_t msm_actuator_t;
+static struct msm_actuator msm_vcm_actuator_table;
+static struct msm_actuator msm_piezo_actuator_table;
+
+static struct msm_actuator *actuators[] = {
+	&msm_vcm_actuator_table,
+	&msm_piezo_actuator_table,
+};
+
+static int32_t msm_actuator_piezo_set_default_focus(
+	struct msm_actuator_ctrl_t *a_ctrl,
+	struct msm_actuator_move_params_t *move_params)
+{
+	int32_t rc = 0;
+	CDBG("Enter\n");
+
+	if (a_ctrl->curr_step_pos != 0) {
+		a_ctrl->i2c_tbl_index = 0;
+		a_ctrl->func_tbl->actuator_parse_i2c_params(a_ctrl,
+			a_ctrl->initial_code, 0, 0);
+		a_ctrl->func_tbl->actuator_parse_i2c_params(a_ctrl,
+			a_ctrl->initial_code, 0, 0);
+		rc = a_ctrl->i2c_client.i2c_func_tbl->
+			i2c_write_table_w_microdelay(
+			&a_ctrl->i2c_client, a_ctrl->i2c_reg_tbl,
+			a_ctrl->i2c_tbl_index, a_ctrl->i2c_data_type);
+		if (rc < 0) {
+			pr_err("%s: i2c write error:%d\n",
+				__func__, rc);
+			return rc;
+		}
+		a_ctrl->i2c_tbl_index = 0;
+		a_ctrl->curr_step_pos = 0;
+	}
+	CDBG("Exit\n");
+	return rc;
+}
+
+static void msm_actuator_parse_i2c_params(struct msm_actuator_ctrl_t *a_ctrl,
+	int16_t next_lens_position, uint32_t hw_params, uint16_t delay)
+{
+	struct msm_actuator_reg_params_t *write_arr = a_ctrl->reg_tbl;
+	uint32_t hw_dword = hw_params;
+	uint16_t i2c_byte1 = 0, i2c_byte2 = 0;
+	uint16_t value = 0;
+	uint32_t size = a_ctrl->reg_tbl_size, i = 0;
+	struct msm_camera_i2c_reg_tbl *i2c_tbl = a_ctrl->i2c_reg_tbl;
+	CDBG("Enter\n");
+	for (i = 0; i < size; i++) {
+		if (write_arr[i].reg_write_type == MSM_ACTUATOR_WRITE_DAC) {
+			value = (next_lens_position <<
+				write_arr[i].data_shift) |
+				((hw_dword & write_arr[i].hw_mask) >>
+				write_arr[i].hw_shift);
+
+			if (write_arr[i].reg_addr != 0xFFFF) {
+				i2c_byte1 = write_arr[i].reg_addr;
+				i2c_byte2 = value;
+				if (size != (i+1)) {
+					i2c_byte2 = value & 0xFF;
+					CDBG("byte1:0x%x, byte2:0x%x\n",
+						i2c_byte1, i2c_byte2);
+					i2c_tbl[a_ctrl->i2c_tbl_index].
+						reg_addr = i2c_byte1;
+					i2c_tbl[a_ctrl->i2c_tbl_index].
+						reg_data = i2c_byte2;
+					i2c_tbl[a_ctrl->i2c_tbl_index].
+						delay = 0;
+					a_ctrl->i2c_tbl_index++;
+					i++;
+					i2c_byte1 = write_arr[i].reg_addr;
+					i2c_byte2 = (value & 0xFF00) >> 8;
+				}
+			} else {
+				i2c_byte1 = (value & 0xFF00) >> 8;
+				i2c_byte2 = value & 0xFF;
+			}
+		} else {
+			i2c_byte1 = write_arr[i].reg_addr;
+			i2c_byte2 = (hw_dword & write_arr[i].hw_mask) >>
+				write_arr[i].hw_shift;
+		}
+		CDBG("i2c_byte1:0x%x, i2c_byte2:0x%x\n", i2c_byte1, i2c_byte2);
+		i2c_tbl[a_ctrl->i2c_tbl_index].reg_addr = i2c_byte1;
+		i2c_tbl[a_ctrl->i2c_tbl_index].reg_data = i2c_byte2;
+		i2c_tbl[a_ctrl->i2c_tbl_index].delay = delay;
+		a_ctrl->i2c_tbl_index++;
+	}
+	CDBG("Exit\n");
+}
+
+static int32_t msm_actuator_init_focus(struct msm_actuator_ctrl_t *a_ctrl,
+	uint16_t size, enum msm_actuator_data_type type,
+	struct reg_settings_t *settings)
+{
+	int32_t rc = -EFAULT;
+	int32_t i = 0;
+	CDBG("Enter\n");
+
+	for (i = 0; i < size; i++) {
+		switch (type) {
+		case MSM_ACTUATOR_BYTE_DATA:
+			rc = a_ctrl->i2c_client.i2c_func_tbl->i2c_write(
+				&a_ctrl->i2c_client,
+				settings[i].reg_addr,
+				settings[i].reg_data, MSM_CAMERA_I2C_BYTE_DATA);
+			break;
+		case MSM_ACTUATOR_WORD_DATA:
+			rc = a_ctrl->i2c_client.i2c_func_tbl->i2c_write(
+				&a_ctrl->i2c_client,
+				settings[i].reg_addr,
+				settings[i].reg_data, MSM_CAMERA_I2C_WORD_DATA);
+			break;
+		default:
+			pr_err("Unsupport data type: %d\n", type);
+			break;
+		}
+		if (rc < 0)
+			break;
+	}
+
+	a_ctrl->curr_step_pos = 0;
+	CDBG("Exit\n");
+	return rc;
+}
+
+static void msm_actuator_write_focus(
+	struct msm_actuator_ctrl_t *a_ctrl,
+	uint16_t curr_lens_pos,
+	struct damping_params_t *damping_params,
+	int8_t sign_direction,
+	int16_t code_boundary)
+{
+	int16_t next_lens_pos = 0;
+	uint16_t damping_code_step = 0;
+	uint16_t wait_time = 0;
+	CDBG("Enter\n");
+
+	damping_code_step = damping_params->damping_step;
+	wait_time = damping_params->damping_delay;
+
+	/* Write code based on damping_code_step in a loop */
+	for (next_lens_pos =
+		curr_lens_pos + (sign_direction * damping_code_step);
+		(sign_direction * next_lens_pos) <=
+			(sign_direction * code_boundary);
+		next_lens_pos =
+			(next_lens_pos +
+				(sign_direction * damping_code_step))) {
+		a_ctrl->func_tbl->actuator_parse_i2c_params(a_ctrl,
+			next_lens_pos, damping_params->hw_params, wait_time);
+		curr_lens_pos = next_lens_pos;
+	}
+
+	if (curr_lens_pos != code_boundary) {
+		a_ctrl->func_tbl->actuator_parse_i2c_params(a_ctrl,
+			code_boundary, damping_params->hw_params, wait_time);
+	}
+	CDBG("Exit\n");
+}
+
+static int32_t msm_actuator_piezo_move_focus(
+	struct msm_actuator_ctrl_t *a_ctrl,
+	struct msm_actuator_move_params_t *move_params)
+{
+	int32_t dest_step_position = move_params->dest_step_pos;
+	int32_t rc = 0;
+	int32_t num_steps = move_params->num_steps;
+	CDBG("Enter\n");
+
+	if (num_steps == 0)
+		return rc;
+
+	a_ctrl->i2c_tbl_index = 0;
+	a_ctrl->func_tbl->actuator_parse_i2c_params(a_ctrl,
+		(num_steps *
+		a_ctrl->region_params[0].code_per_step),
+		move_params->ringing_params[0].hw_params, 0);
+
+	rc = a_ctrl->i2c_client.i2c_func_tbl->i2c_write_table_w_microdelay(
+		&a_ctrl->i2c_client,
+		a_ctrl->i2c_reg_tbl, a_ctrl->i2c_tbl_index,
+		a_ctrl->i2c_data_type);
+	if (rc < 0) {
+		pr_err("i2c write error:%d\n", rc);
+		return rc;
+	}
+	a_ctrl->i2c_tbl_index = 0;
+	a_ctrl->curr_step_pos = dest_step_position;
+	CDBG("Exit\n");
+	return rc;
+}
+
+static int32_t msm_actuator_move_focus(
+	struct msm_actuator_ctrl_t *a_ctrl,
+	struct msm_actuator_move_params_t *move_params)
+{
+	int32_t rc = 0;
+	int8_t sign_dir = move_params->sign_dir;
+	uint16_t step_boundary = 0;
+	uint16_t target_step_pos = 0;
+	uint16_t target_lens_pos = 0;
+	int16_t dest_step_pos = move_params->dest_step_pos;
+	uint16_t curr_lens_pos = 0;
+	int dir = move_params->dir;
+	int32_t num_steps = move_params->num_steps;
+
+	CDBG("called, dir %d, num_steps %d\n", dir, num_steps);
+
+	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);
+
+	while (a_ctrl->curr_step_pos != dest_step_pos) {
+		step_boundary =
+			a_ctrl->region_params[a_ctrl->curr_region_index].
+			step_bound[dir];
+		if ((dest_step_pos * sign_dir) <=
+			(step_boundary * sign_dir)) {
+
+			target_step_pos = dest_step_pos;
+			target_lens_pos =
+				a_ctrl->step_position_table[target_step_pos];
+			a_ctrl->func_tbl->actuator_write_focus(a_ctrl,
+					curr_lens_pos,
+					&(move_params->
+						ringing_params[a_ctrl->
+						curr_region_index]),
+					sign_dir,
+					target_lens_pos);
+			curr_lens_pos = target_lens_pos;
+
+		} else {
+			target_step_pos = step_boundary;
+			target_lens_pos =
+				a_ctrl->step_position_table[target_step_pos];
+			a_ctrl->func_tbl->actuator_write_focus(a_ctrl,
+					curr_lens_pos,
+					&(move_params->ringing_params[a_ctrl->
+						curr_region_index]),
+					sign_dir,
+					target_lens_pos);
+			curr_lens_pos = target_lens_pos;
+
+			a_ctrl->curr_region_index += sign_dir;
+		}
+		a_ctrl->curr_step_pos = target_step_pos;
+	}
+
+	rc = a_ctrl->i2c_client.i2c_func_tbl->i2c_write_table_w_microdelay(
+		&a_ctrl->i2c_client,
+		a_ctrl->i2c_reg_tbl, a_ctrl->i2c_tbl_index,
+		a_ctrl->i2c_data_type);
+	if (rc < 0) {
+		pr_err("i2c write error:%d\n", rc);
+		return rc;
+	}
+	a_ctrl->i2c_tbl_index = 0;
+	CDBG("Exit\n");
+
+	return rc;
+}
+
+static int32_t msm_actuator_init_step_table(struct msm_actuator_ctrl_t *a_ctrl,
+	struct msm_actuator_set_info_t *set_info)
+{
+	int16_t code_per_step = 0;
+	int16_t cur_code = 0;
+	int16_t step_index = 0, region_index = 0;
+	uint16_t step_boundary = 0;
+	uint32_t max_code_size = 1;
+	uint16_t data_size = set_info->actuator_params.data_size;
+	CDBG("Enter\n");
+
+	for (; data_size > 0; data_size--)
+		max_code_size *= 2;
+
+	kfree(a_ctrl->step_position_table);
+	a_ctrl->step_position_table = NULL;
+
+	/* Fill step position table */
+	a_ctrl->step_position_table =
+		kmalloc(sizeof(uint16_t) *
+		(set_info->af_tuning_params.total_steps + 1), GFP_KERNEL);
+
+	if (a_ctrl->step_position_table == NULL)
+		return -ENOMEM;
+
+	cur_code = set_info->af_tuning_params.initial_code;
+	a_ctrl->step_position_table[step_index++] = cur_code;
+	for (region_index = 0;
+		region_index < a_ctrl->region_size;
+		region_index++) {
+		code_per_step =
+			a_ctrl->region_params[region_index].code_per_step;
+		step_boundary =
+			a_ctrl->region_params[region_index].
+			step_bound[MOVE_NEAR];
+		for (; step_index <= step_boundary;
+			step_index++) {
+			cur_code += code_per_step;
+			if (cur_code < max_code_size)
+				a_ctrl->step_position_table[step_index] =
+					cur_code;
+			else {
+				for (; step_index <
+					set_info->af_tuning_params.total_steps;
+					step_index++)
+					a_ctrl->
+						step_position_table[
+						step_index] =
+						max_code_size;
+			}
+		}
+	}
+	CDBG("Exit\n");
+	return 0;
+}
+
+static int32_t msm_actuator_set_default_focus(
+	struct msm_actuator_ctrl_t *a_ctrl,
+	struct msm_actuator_move_params_t *move_params)
+{
+	int32_t rc = 0;
+	CDBG("Enter\n");
+
+	if (a_ctrl->curr_step_pos != 0)
+		rc = a_ctrl->func_tbl->actuator_move_focus(a_ctrl, move_params);
+	CDBG("Exit\n");
+	return rc;
+}
+
+static int32_t msm_actuator_power_down(struct msm_actuator_ctrl_t *a_ctrl)
+{
+	int32_t rc = 0;
+	CDBG("Enter\n");
+	if (a_ctrl->vcm_enable) {
+		rc = gpio_direction_output(a_ctrl->vcm_pwd, 0);
+		if (!rc)
+			gpio_free(a_ctrl->vcm_pwd);
+	}
+
+	kfree(a_ctrl->step_position_table);
+	a_ctrl->step_position_table = NULL;
+	kfree(a_ctrl->i2c_reg_tbl);
+	a_ctrl->i2c_reg_tbl = NULL;
+	a_ctrl->i2c_tbl_index = 0;
+	CDBG("Exit\n");
+	return rc;
+}
+
+static int32_t msm_actuator_init(struct msm_actuator_ctrl_t *a_ctrl,
+	struct msm_actuator_set_info_t *set_info) {
+	struct reg_settings_t *init_settings = NULL;
+	int32_t rc = -EFAULT;
+	uint16_t i = 0;
+	struct msm_camera_cci_client *cci_client = NULL;
+	CDBG("Enter\n");
+
+	for (i = 0; i < ARRAY_SIZE(actuators); i++) {
+		if (set_info->actuator_params.act_type ==
+			actuators[i]->act_type) {
+			a_ctrl->func_tbl = &actuators[i]->func_tbl;
+			rc = 0;
+		}
+	}
+
+	if (rc < 0) {
+		pr_err("Actuator function table not found\n");
+		return rc;
+	}
+
+	a_ctrl->region_size = set_info->af_tuning_params.region_size;
+	if (a_ctrl->region_size > MAX_ACTUATOR_REGION) {
+		pr_err("MAX_ACTUATOR_REGION is exceeded.\n");
+		return -EFAULT;
+	}
+	a_ctrl->pwd_step = set_info->af_tuning_params.pwd_step;
+	a_ctrl->total_steps = set_info->af_tuning_params.total_steps;
+
+	if (copy_from_user(&a_ctrl->region_params,
+		(void *)set_info->af_tuning_params.region_params,
+		a_ctrl->region_size * sizeof(struct region_params_t)))
+		return -EFAULT;
+
+	if (a_ctrl->act_device_type == MSM_CAMERA_PLATFORM_DEVICE) {
+		cci_client = a_ctrl->i2c_client.cci_client;
+		cci_client->sid =
+			set_info->actuator_params.i2c_addr >> 1;
+		cci_client->retries = 3;
+		cci_client->id_map = 0;
+		cci_client->cci_i2c_master = a_ctrl->cci_master;
+	} else {
+		a_ctrl->i2c_client.client->addr =
+			set_info->actuator_params.i2c_addr;
+	}
+
+	a_ctrl->i2c_data_type = set_info->actuator_params.i2c_data_type;
+	a_ctrl->i2c_client.addr_type = set_info->actuator_params.i2c_addr_type;
+	a_ctrl->reg_tbl_size = set_info->actuator_params.reg_tbl_size;
+	if (a_ctrl->reg_tbl_size > MAX_ACTUATOR_REG_TBL_SIZE) {
+		pr_err("MAX_ACTUATOR_REG_TBL_SIZE is exceeded.\n");
+		return -EFAULT;
+	}
+
+	a_ctrl->i2c_reg_tbl =
+		kmalloc(sizeof(struct msm_camera_i2c_reg_tbl) *
+		(set_info->af_tuning_params.total_steps + 1), GFP_KERNEL);
+	if (!a_ctrl->i2c_reg_tbl) {
+		pr_err("kmalloc fail\n");
+		return -ENOMEM;
+	}
+
+	if (copy_from_user(&a_ctrl->reg_tbl,
+		(void *)set_info->actuator_params.reg_tbl_params,
+		a_ctrl->reg_tbl_size *
+		sizeof(struct msm_actuator_reg_params_t))) {
+		kfree(a_ctrl->i2c_reg_tbl);
+		return -EFAULT;
+	}
+
+	if (set_info->actuator_params.init_setting_size) {
+		if (a_ctrl->func_tbl->actuator_init_focus) {
+			init_settings = kmalloc(sizeof(struct reg_settings_t) *
+				(set_info->actuator_params.init_setting_size),
+				GFP_KERNEL);
+			if (init_settings == NULL) {
+				kfree(a_ctrl->i2c_reg_tbl);
+				pr_err("Error allocating memory for init_settings\n");
+				return -EFAULT;
+			}
+			if (copy_from_user(init_settings,
+				(void *)set_info->actuator_params.init_settings,
+				set_info->actuator_params.init_setting_size *
+				sizeof(struct reg_settings_t))) {
+				kfree(init_settings);
+				kfree(a_ctrl->i2c_reg_tbl);
+				pr_err("Error copying init_settings\n");
+				return -EFAULT;
+			}
+			rc = a_ctrl->func_tbl->actuator_init_focus(a_ctrl,
+				set_info->actuator_params.init_setting_size,
+				a_ctrl->i2c_data_type,
+				init_settings);
+			kfree(init_settings);
+			if (rc < 0) {
+				kfree(a_ctrl->i2c_reg_tbl);
+				pr_err("Error actuator_init_focus\n");
+				return -EFAULT;
+			}
+		}
+	}
+
+	a_ctrl->initial_code = set_info->af_tuning_params.initial_code;
+	if (a_ctrl->func_tbl->actuator_init_step_table)
+		rc = a_ctrl->func_tbl->
+			actuator_init_step_table(a_ctrl, set_info);
+
+	a_ctrl->curr_step_pos = 0;
+	a_ctrl->curr_region_index = 0;
+	CDBG("Exit\n");
+
+	return rc;
+}
+
+static int32_t msm_actuator_config(struct msm_actuator_ctrl_t *a_ctrl,
+	void __user *argp)
+{
+	struct msm_actuator_cfg_data *cdata =
+		(struct msm_actuator_cfg_data *)argp;
+	int32_t rc = 0;
+	mutex_lock(a_ctrl->actuator_mutex);
+	CDBG("Enter\n");
+	CDBG("%s type %d\n", __func__, cdata->cfgtype);
+	switch (cdata->cfgtype) {
+	case CFG_GET_ACTUATOR_INFO:
+		cdata->is_af_supported = 1;
+		cdata->cfg.cam_name = a_ctrl->cam_name;
+		break;
+
+	case CFG_SET_ACTUATOR_INFO:
+		rc = msm_actuator_init(a_ctrl, &cdata->cfg.set_info);
+		if (rc < 0)
+			pr_err("init table failed %d\n", rc);
+		break;
+
+	case CFG_SET_DEFAULT_FOCUS:
+		rc = a_ctrl->func_tbl->actuator_set_default_focus(a_ctrl,
+			&cdata->cfg.move);
+		if (rc < 0)
+			pr_err("move focus failed %d\n", rc);
+		break;
+
+	case CFG_MOVE_FOCUS:
+		rc = a_ctrl->func_tbl->actuator_move_focus(a_ctrl,
+			&cdata->cfg.move);
+		if (rc < 0)
+			pr_err("move focus failed %d\n", rc);
+		break;
+
+	default:
+		break;
+	}
+	mutex_unlock(a_ctrl->actuator_mutex);
+	CDBG("Exit\n");
+	return rc;
+}
+
+static int32_t msm_actuator_get_subdev_id(struct msm_actuator_ctrl_t *a_ctrl,
+	void *arg)
+{
+	uint32_t *subdev_id = (uint32_t *)arg;
+	CDBG("Enter\n");
+	if (!subdev_id) {
+		pr_err("failed\n");
+		return -EINVAL;
+	}
+	*subdev_id = a_ctrl->pdev->id;
+	CDBG("subdev_id %d\n", *subdev_id);
+	CDBG("Exit\n");
+	return 0;
+}
+
+static struct msm_camera_i2c_fn_t msm_sensor_cci_func_tbl = {
+	.i2c_read = msm_camera_cci_i2c_read,
+	.i2c_read_seq = msm_camera_cci_i2c_read_seq,
+	.i2c_write = msm_camera_cci_i2c_write,
+	.i2c_write_table = msm_camera_cci_i2c_write_table,
+	.i2c_write_seq_table = msm_camera_cci_i2c_write_seq_table,
+	.i2c_write_table_w_microdelay =
+		msm_camera_cci_i2c_write_table_w_microdelay,
+	.i2c_util = msm_sensor_cci_i2c_util,
+};
+
+static struct msm_camera_i2c_fn_t msm_sensor_qup_func_tbl = {
+	.i2c_read = msm_camera_qup_i2c_read,
+	.i2c_read_seq = msm_camera_qup_i2c_read_seq,
+	.i2c_write = msm_camera_qup_i2c_write,
+	.i2c_write_table = msm_camera_qup_i2c_write_table,
+	.i2c_write_seq_table = msm_camera_qup_i2c_write_seq_table,
+	.i2c_write_table_w_microdelay =
+		msm_camera_qup_i2c_write_table_w_microdelay,
+};
+
+static int msm_actuator_open(struct v4l2_subdev *sd,
+	struct v4l2_subdev_fh *fh) {
+	int rc = 0;
+	struct msm_actuator_ctrl_t *a_ctrl =  v4l2_get_subdevdata(sd);
+	CDBG("Enter\n");
+	if (!a_ctrl) {
+		pr_err("failed\n");
+		return -EINVAL;
+	}
+	if (a_ctrl->act_device_type == MSM_CAMERA_PLATFORM_DEVICE) {
+		rc = a_ctrl->i2c_client.i2c_func_tbl->i2c_util(
+			&a_ctrl->i2c_client, MSM_CCI_INIT);
+		if (rc < 0)
+			pr_err("cci_init failed\n");
+	}
+	CDBG("Exit\n");
+	return rc;
+}
+
+static int msm_actuator_close(struct v4l2_subdev *sd,
+	struct v4l2_subdev_fh *fh) {
+	int rc = 0;
+	struct msm_actuator_ctrl_t *a_ctrl =  v4l2_get_subdevdata(sd);
+	CDBG("Enter\n");
+	if (!a_ctrl) {
+		pr_err("failed\n");
+		return -EINVAL;
+	}
+	if (a_ctrl->act_device_type == MSM_CAMERA_PLATFORM_DEVICE) {
+		rc = a_ctrl->i2c_client.i2c_func_tbl->i2c_util(
+			&a_ctrl->i2c_client, MSM_CCI_RELEASE);
+		if (rc < 0)
+			pr_err("cci_init failed\n");
+	}
+	CDBG("Exit\n");
+	return rc;
+}
+
+static const struct v4l2_subdev_internal_ops msm_actuator_internal_ops = {
+	.open = msm_actuator_open,
+	.close = msm_actuator_close,
+};
+
+static int32_t msm_actuator_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+	struct msm_actuator_ctrl_t *act_ctrl_t = NULL;
+	CDBG("Enter\n");
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		pr_err("i2c_check_functionality failed\n");
+		goto probe_failure;
+	}
+
+	act_ctrl_t = (struct msm_actuator_ctrl_t *)(id->driver_data);
+	CDBG("client = %x\n", (unsigned int) client);
+	act_ctrl_t->i2c_client.client = client;
+	/* Set device type as I2C */
+	act_ctrl_t->act_device_type = MSM_CAMERA_I2C_DEVICE;
+	act_ctrl_t->i2c_client.i2c_func_tbl = &msm_sensor_qup_func_tbl;
+
+	/* Assign name for sub device */
+	snprintf(act_ctrl_t->msm_sd.sd.name, sizeof(act_ctrl_t->msm_sd.sd.name),
+		"%s", act_ctrl_t->i2c_driver->driver.name);
+
+	/* Initialize sub device */
+	v4l2_i2c_subdev_init(&act_ctrl_t->msm_sd.sd,
+		act_ctrl_t->i2c_client.client,
+		act_ctrl_t->act_v4l2_subdev_ops);
+	v4l2_set_subdevdata(&act_ctrl_t->msm_sd.sd, act_ctrl_t);
+	act_ctrl_t->msm_sd.sd.internal_ops = &msm_actuator_internal_ops;
+	act_ctrl_t->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	media_entity_init(&act_ctrl_t->msm_sd.sd.entity, 0, NULL, 0);
+	act_ctrl_t->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	act_ctrl_t->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_ACTUATOR;
+	msm_sd_register(&act_ctrl_t->msm_sd);
+	CDBG("succeeded\n");
+	CDBG("Exit\n");
+
+probe_failure:
+	return rc;
+}
+
+static int32_t msm_actuator_platform_probe(struct platform_device *pdev)
+{
+	int32_t rc = 0;
+	struct msm_camera_cci_client *cci_client = NULL;
+	CDBG("Enter\n");
+
+	if (!pdev->dev.of_node) {
+		pr_err("of_node NULL\n");
+		return -EINVAL;
+	}
+
+	rc = of_property_read_u32((&pdev->dev)->of_node, "cell-index",
+		&pdev->id);
+	CDBG("cell-index %d, rc %d\n", pdev->id, rc);
+	if (rc < 0) {
+		pr_err("failed rc %d\n", rc);
+		return rc;
+	}
+
+	rc = of_property_read_u32((&pdev->dev)->of_node, "qcom,cci-master",
+		&msm_actuator_t.cci_master);
+	CDBG("qcom,cci-master %d, rc %d\n", msm_actuator_t.cci_master, rc);
+	if (rc < 0) {
+		pr_err("failed rc %d\n", rc);
+		return rc;
+	}
+
+	msm_actuator_t.cam_name = pdev->id;
+
+	/* Set platform device handle */
+	msm_actuator_t.pdev = pdev;
+	/* Set device type as platform device */
+	msm_actuator_t.act_device_type = MSM_CAMERA_PLATFORM_DEVICE;
+	msm_actuator_t.i2c_client.i2c_func_tbl = &msm_sensor_cci_func_tbl;
+	msm_actuator_t.i2c_client.cci_client = kzalloc(sizeof(
+		struct msm_camera_cci_client), GFP_KERNEL);
+	if (!msm_actuator_t.i2c_client.cci_client) {
+		pr_err("failed no memory\n");
+		return -ENOMEM;
+	}
+
+	cci_client = msm_actuator_t.i2c_client.cci_client;
+	cci_client->cci_subdev = msm_cci_get_subdev();
+	v4l2_subdev_init(&msm_actuator_t.msm_sd.sd,
+		msm_actuator_t.act_v4l2_subdev_ops);
+	v4l2_set_subdevdata(&msm_actuator_t.msm_sd.sd, &msm_actuator_t);
+	msm_actuator_t.msm_sd.sd.internal_ops = &msm_actuator_internal_ops;
+	msm_actuator_t.msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	snprintf(msm_actuator_t.msm_sd.sd.name,
+		ARRAY_SIZE(msm_actuator_t.msm_sd.sd.name), "msm_actuator");
+	media_entity_init(&msm_actuator_t.msm_sd.sd.entity, 0, NULL, 0);
+	msm_actuator_t.msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	msm_actuator_t.msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_ACTUATOR;
+	msm_sd_register(&msm_actuator_t.msm_sd);
+	CDBG("Exit\n");
+	return rc;
+}
+
+static int32_t msm_actuator_power_up(struct msm_actuator_ctrl_t *a_ctrl)
+{
+	int rc = 0;
+	CDBG("%s called\n", __func__);
+
+	CDBG("vcm info: %x %x\n", a_ctrl->vcm_pwd,
+		a_ctrl->vcm_enable);
+	if (a_ctrl->vcm_enable) {
+		rc = gpio_request(a_ctrl->vcm_pwd, "msm_actuator");
+		if (!rc) {
+			CDBG("Enable VCM PWD\n");
+			gpio_direction_output(a_ctrl->vcm_pwd, 1);
+		}
+	}
+	CDBG("Exit\n");
+	return rc;
+}
+
+static const struct i2c_device_id msm_actuator_i2c_id[] = {
+	{"msm_actuator", (kernel_ulong_t)&msm_actuator_t},
+	{ }
+};
+
+static struct i2c_driver msm_actuator_i2c_driver = {
+	.id_table = msm_actuator_i2c_id,
+	.probe  = msm_actuator_i2c_probe,
+	.remove = __exit_p(msm_actuator_i2c_remove),
+	.driver = {
+		.name = "msm_actuator",
+	},
+};
+
+static const struct of_device_id msm_actuator_dt_match[] = {
+	{.compatible = "qcom,actuator", .data = &msm_actuator_t},
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, msm_actuator_dt_match);
+
+static struct platform_driver msm_actuator_platform_driver = {
+	.driver = {
+		.name = "qcom,actuator",
+		.owner = THIS_MODULE,
+		.of_match_table = msm_actuator_dt_match,
+	},
+};
+
+static int __init msm_actuator_init_module(void)
+{
+	int32_t rc = 0;
+	CDBG("Enter\n");
+	rc = platform_driver_probe(msm_actuator_t.pdriver,
+		msm_actuator_platform_probe);
+	if (!rc)
+		return rc;
+	CDBG("%s:%d rc %d\n", __func__, __LINE__, rc);
+	return i2c_add_driver(msm_actuator_t.i2c_driver);
+}
+
+static long msm_actuator_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int cmd, void *arg)
+{
+	struct msm_actuator_ctrl_t *a_ctrl = v4l2_get_subdevdata(sd);
+	void __user *argp = (void __user *)arg;
+	CDBG("Enter\n");
+	CDBG("%s:%d a_ctrl %p argp %p\n", __func__, __LINE__, a_ctrl, argp);
+	switch (cmd) {
+	case VIDIOC_MSM_SENSOR_GET_SUBDEV_ID:
+		return msm_actuator_get_subdev_id(a_ctrl, argp);
+	case VIDIOC_MSM_ACTUATOR_CFG:
+		return msm_actuator_config(a_ctrl, argp);
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
+static int32_t msm_actuator_power(struct v4l2_subdev *sd, int on)
+{
+	int rc = 0;
+	struct msm_actuator_ctrl_t *a_ctrl = v4l2_get_subdevdata(sd);
+	CDBG("Enter\n");
+	mutex_lock(a_ctrl->actuator_mutex);
+	if (on)
+		rc = msm_actuator_power_up(a_ctrl);
+	else
+		rc = msm_actuator_power_down(a_ctrl);
+	mutex_unlock(a_ctrl->actuator_mutex);
+	CDBG("Exit\n");
+	return rc;
+}
+
+static struct v4l2_subdev_core_ops msm_actuator_subdev_core_ops = {
+	.ioctl = msm_actuator_subdev_ioctl,
+	.s_power = msm_actuator_power,
+};
+
+static struct v4l2_subdev_ops msm_actuator_subdev_ops = {
+	.core = &msm_actuator_subdev_core_ops,
+};
+
+static struct msm_actuator_ctrl_t msm_actuator_t = {
+	.i2c_driver = &msm_actuator_i2c_driver,
+	.pdriver = &msm_actuator_platform_driver,
+	.act_v4l2_subdev_ops = &msm_actuator_subdev_ops,
+
+	.curr_step_pos = 0,
+	.curr_region_index = 0,
+	.actuator_mutex = &msm_actuator_mutex,
+
+};
+
+static struct msm_actuator msm_vcm_actuator_table = {
+	.act_type = ACTUATOR_VCM,
+	.func_tbl = {
+		.actuator_init_step_table = msm_actuator_init_step_table,
+		.actuator_move_focus = msm_actuator_move_focus,
+		.actuator_write_focus = msm_actuator_write_focus,
+		.actuator_set_default_focus = msm_actuator_set_default_focus,
+		.actuator_init_focus = msm_actuator_init_focus,
+		.actuator_parse_i2c_params = msm_actuator_parse_i2c_params,
+	},
+};
+
+static struct msm_actuator msm_piezo_actuator_table = {
+	.act_type = ACTUATOR_PIEZO,
+	.func_tbl = {
+		.actuator_init_step_table = NULL,
+		.actuator_move_focus = msm_actuator_piezo_move_focus,
+		.actuator_write_focus = NULL,
+		.actuator_set_default_focus =
+			msm_actuator_piezo_set_default_focus,
+		.actuator_init_focus = msm_actuator_init_focus,
+		.actuator_parse_i2c_params = msm_actuator_parse_i2c_params,
+	},
+};
+
+module_init(msm_actuator_init_module);
+MODULE_DESCRIPTION("MSM ACTUATOR");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.h b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.h
new file mode 100644
index 0000000..c616307
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.h
@@ -0,0 +1,85 @@
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef MSM_ACTUATOR_H
+#define MSM_ACTUATOR_H
+
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <mach/camera2.h>
+#include <media/v4l2-subdev.h>
+#include <media/msmb_camera.h>
+#include "msm_camera_i2c.h"
+
+#define DEFINE_MSM_MUTEX(mutexname) \
+	static struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
+
+struct msm_actuator_ctrl_t;
+
+struct msm_actuator_func_tbl {
+	int32_t (*actuator_i2c_write_b_af)(struct msm_actuator_ctrl_t *,
+			uint8_t,
+			uint8_t);
+	int32_t (*actuator_init_step_table)(struct msm_actuator_ctrl_t *,
+		struct msm_actuator_set_info_t *);
+	int32_t (*actuator_init_focus)(struct msm_actuator_ctrl_t *,
+		uint16_t, enum msm_actuator_data_type, struct reg_settings_t *);
+	int32_t (*actuator_set_default_focus) (struct msm_actuator_ctrl_t *,
+			struct msm_actuator_move_params_t *);
+	int32_t (*actuator_move_focus) (struct msm_actuator_ctrl_t *,
+			struct msm_actuator_move_params_t *);
+	void (*actuator_parse_i2c_params)(struct msm_actuator_ctrl_t *,
+			int16_t, uint32_t, uint16_t);
+	void (*actuator_write_focus)(struct msm_actuator_ctrl_t *,
+			uint16_t,
+			struct damping_params_t *,
+			int8_t,
+			int16_t);
+};
+
+struct msm_actuator {
+	enum actuator_type act_type;
+	struct msm_actuator_func_tbl func_tbl;
+};
+
+struct msm_actuator_ctrl_t {
+	struct i2c_driver *i2c_driver;
+	struct platform_driver *pdriver;
+	struct platform_device *pdev;
+	struct msm_camera_i2c_client i2c_client;
+	enum msm_camera_device_type_t act_device_type;
+	struct msm_sd_subdev msm_sd;
+	enum af_camera_name cam_name;
+	struct mutex *actuator_mutex;
+	struct msm_actuator_func_tbl *func_tbl;
+	enum msm_actuator_data_type i2c_data_type;
+	struct v4l2_subdev sdev;
+	struct v4l2_subdev_ops *act_v4l2_subdev_ops;
+
+	int16_t curr_step_pos;
+	uint16_t curr_region_index;
+	uint16_t *step_position_table;
+	struct region_params_t region_params[MAX_ACTUATOR_REGION];
+	uint16_t reg_tbl_size;
+	struct msm_actuator_reg_params_t reg_tbl[MAX_ACTUATOR_REG_TBL_SIZE];
+	uint16_t region_size;
+	void *user_data;
+	uint32_t vcm_pwd;
+	uint32_t vcm_enable;
+	uint32_t total_steps;
+	uint16_t pwd_step;
+	uint16_t initial_code;
+	struct msm_camera_i2c_reg_tbl *i2c_reg_tbl;
+	uint16_t i2c_tbl_index;
+	enum cci_i2c_master_t cci_master;
+};
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/Makefile b/drivers/media/platform/msm/camera_v2/sensor/cci/Makefile
new file mode 100644
index 0000000..d3aa498
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/cci/Makefile
@@ -0,0 +1,3 @@
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io
+obj-$(CONFIG_MSM_CCI) += msm_cci.o
diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cam_cci_hwreg.h b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cam_cci_hwreg.h
new file mode 100644
index 0000000..642df76
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cam_cci_hwreg.h
@@ -0,0 +1,60 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+   *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MSM_CAM_CCI_HWREG__
+#define __MSM_CAM_CCI_HWREG__
+
+#define CCI_HW_VERSION_ADDR                                         0x00000000
+#define CCI_RESET_CMD_ADDR                                          0x00000004
+#define CCI_RESET_CMD_RMSK                                          0xcf73f3f7
+#define CCI_M0_RESET_RMSK                                                0x3F1
+#define CCI_M1_RESET_RMSK                                              0x3F001
+#define CCI_QUEUE_START_ADDR                                        0x00000008
+#define CCI_SET_CID_SYNC_TIMER_0_ADDR                               0x00000010
+#define CCI_I2C_M0_SCL_CTL_ADDR                                     0x00000100
+#define CCI_I2C_M0_SDA_CTL_0_ADDR                                   0x00000104
+#define CCI_I2C_M0_SDA_CTL_1_ADDR                                   0x00000108
+#define CCI_I2C_M0_SDA_CTL_2_ADDR                                   0x0000010c
+#define CCI_I2C_M0_READ_DATA_ADDR                                   0x00000118
+#define CCI_I2C_M0_MISC_CTL_ADDR                                    0x00000110
+#define CCI_I2C_M0_READ_BUF_LEVEL_ADDR                              0x0000011C
+#define CCI_HALT_REQ_ADDR                                           0x00000034
+#define CCI_M0_HALT_REQ_RMSK                                               0x1
+#define CCI_M1_HALT_REQ_RMSK                                               0x2
+#define CCI_I2C_M1_SCL_CTL_ADDR                                     0x00000200
+#define CCI_I2C_M1_SDA_CTL_0_ADDR                                   0x00000204
+#define CCI_I2C_M1_SDA_CTL_1_ADDR                                   0x00000208
+#define CCI_I2C_M1_SDA_CTL_2_ADDR                                   0x0000020c
+#define CCI_I2C_M1_MISC_CTL_ADDR                                    0x00000210
+#define CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR                             0x00000304
+#define CCI_I2C_M0_Q0_CUR_CMD_ADDR                                  0x00000308
+#define CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR                            0x00000300
+#define CCI_I2C_M0_Q0_LOAD_DATA_ADDR                                0x00000310
+#define CCI_IRQ_MASK_0_ADDR                                         0x00000c04
+#define CCI_IRQ_MASK_0_RMSK                                         0x7fff7ff7
+#define CCI_IRQ_CLEAR_0_ADDR                                        0x00000c08
+#define CCI_IRQ_STATUS_0_ADDR                                       0x00000c0c
+#define CCI_IRQ_STATUS_0_I2C_M1_Q1_NACK_ERR_BMSK                    0x40000000
+#define CCI_IRQ_STATUS_0_I2C_M1_Q0_NACK_ERR_BMSK                    0x20000000
+#define CCI_IRQ_STATUS_0_I2C_M0_Q1_NACK_ERR_BMSK                    0x10000000
+#define CCI_IRQ_STATUS_0_I2C_M0_Q0_NACK_ERR_BMSK                     0x8000000
+#define CCI_IRQ_STATUS_0_I2C_M1_Q0Q1_HALT_ACK_BMSK                   0x4000000
+#define CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK_BMSK                   0x2000000
+#define CCI_IRQ_STATUS_0_RST_DONE_ACK_BMSK                           0x1000000
+#define CCI_IRQ_STATUS_0_I2C_M1_Q1_REPORT_BMSK                        0x100000
+#define CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT_BMSK                         0x10000
+#define CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK                            0x1000
+#define CCI_IRQ_STATUS_0_I2C_M0_Q1_REPORT_BMSK                           0x100
+#define CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK                            0x10
+#define CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK                               0x1
+#define CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR                               0x00000c00
+#endif /* __MSM_CAM_CCI_HWREG__ */
diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
new file mode 100644
index 0000000..12ac4cb
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
@@ -0,0 +1,984 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/of_platform.h>
+#include <media/msm_isp.h>
+#include "msm_sd.h"
+#include "msm_cci.h"
+#include "msm_cam_cci_hwreg.h"
+#include "msm_camera_io_util.h"
+
+#define V4L2_IDENT_CCI 50005
+#define CCI_I2C_QUEUE_0_SIZE 64
+#define CCI_I2C_QUEUE_1_SIZE 16
+
+#define CCI_TIMEOUT msecs_to_jiffies(100)
+
+/* TODO move this somewhere else */
+#define MSM_CCI_DRV_NAME "msm_cci"
+
+#undef CDBG
+#ifdef CONFIG_MSMB_CAMERA_DEBUG
+#define CDBG(fmt, args...) pr_debug(fmt, ##args)
+#else
+#define CDBG(fmt, args...) do { } while (0)
+#endif
+
+static struct v4l2_subdev *g_cci_subdev;
+
+static void msm_cci_set_clk_param(struct cci_device *cci_dev)
+{
+	struct msm_cci_clk_params_t *clk_params = &cci_dev->cci_clk_params;
+
+	msm_camera_io_w(clk_params->hw_thigh << 16 | clk_params->hw_tlow,
+		cci_dev->base + CCI_I2C_M0_SCL_CTL_ADDR);
+	msm_camera_io_w(clk_params->hw_tsu_sto << 16 | clk_params->hw_tsu_sta,
+		cci_dev->base + CCI_I2C_M0_SDA_CTL_0_ADDR);
+	msm_camera_io_w(clk_params->hw_thd_dat << 16 | clk_params->hw_thd_sta,
+		cci_dev->base + CCI_I2C_M0_SDA_CTL_1_ADDR);
+	msm_camera_io_w(clk_params->hw_tbuf,
+		cci_dev->base + CCI_I2C_M0_SDA_CTL_2_ADDR);
+	msm_camera_io_w(clk_params->hw_scl_stretch_en << 8 |
+		clk_params->hw_trdhld << 4 | clk_params->hw_tsp,
+		cci_dev->base + CCI_I2C_M0_MISC_CTL_ADDR);
+	msm_camera_io_w(clk_params->hw_thigh << 16 | clk_params->hw_tlow,
+		cci_dev->base + CCI_I2C_M1_SCL_CTL_ADDR);
+	msm_camera_io_w(clk_params->hw_tsu_sto << 16 | clk_params->hw_tsu_sta,
+		cci_dev->base + CCI_I2C_M1_SDA_CTL_0_ADDR);
+	msm_camera_io_w(clk_params->hw_thd_dat << 16 | clk_params->hw_thd_sta,
+		cci_dev->base + CCI_I2C_M1_SDA_CTL_1_ADDR);
+	msm_camera_io_w(clk_params->hw_tbuf,
+		cci_dev->base + CCI_I2C_M1_SDA_CTL_2_ADDR);
+	msm_camera_io_w(clk_params->hw_scl_stretch_en << 8 |
+		clk_params->hw_trdhld << 4 | clk_params->hw_tsp,
+		cci_dev->base + CCI_I2C_M1_MISC_CTL_ADDR);
+	return;
+}
+
+static int32_t msm_cci_i2c_config_sync_timer(struct v4l2_subdev *sd,
+	struct msm_camera_cci_ctrl *c_ctrl)
+{
+	struct cci_device *cci_dev;
+	cci_dev = v4l2_get_subdevdata(sd);
+	msm_camera_io_w(c_ctrl->cci_info->cid, cci_dev->base +
+		CCI_SET_CID_SYNC_TIMER_0_ADDR + (c_ctrl->cci_info->cid * 0x4));
+	return 0;
+}
+
+static int32_t msm_cci_i2c_set_freq(struct v4l2_subdev *sd,
+	struct msm_camera_cci_ctrl *c_ctrl)
+{
+	struct cci_device *cci_dev;
+	uint32_t val;
+	cci_dev = v4l2_get_subdevdata(sd);
+	val = c_ctrl->cci_info->freq;
+	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SCL_CTL_ADDR +
+		c_ctrl->cci_info->cci_i2c_master*0x100);
+	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SDA_CTL_0_ADDR +
+		c_ctrl->cci_info->cci_i2c_master*0x100);
+	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SDA_CTL_1_ADDR +
+		c_ctrl->cci_info->cci_i2c_master*0x100);
+	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SDA_CTL_2_ADDR +
+		c_ctrl->cci_info->cci_i2c_master*0x100);
+	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_MISC_CTL_ADDR +
+		c_ctrl->cci_info->cci_i2c_master*0x100);
+	return 0;
+}
+
+static void msm_cci_flush_queue(struct cci_device *cci_dev,
+	enum cci_i2c_master_t master)
+{
+	uint32_t rc = 0;
+
+	msm_camera_io_w(1 << master, cci_dev->base + CCI_HALT_REQ_ADDR);
+	rc = wait_for_completion_interruptible_timeout(
+		&cci_dev->cci_master_info[master].reset_complete, CCI_TIMEOUT);
+	if (rc <= 0)
+		pr_err("%s: wait_for_completion_interruptible_timeout %d\n",
+			__func__, __LINE__);
+	return;
+}
+
+static int32_t msm_cci_validate_queue(struct cci_device *cci_dev,
+	uint32_t len,
+	enum cci_i2c_master_t master,
+	enum cci_i2c_queue_t queue)
+{
+	int32_t rc = 0;
+	uint32_t read_val = 0;
+	uint32_t reg_offset = master * 0x200 + queue * 0x100;
+	read_val = msm_camera_io_r(cci_dev->base +
+		CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR + reg_offset);
+	CDBG("%s line %d CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR %d len %d max %d\n",
+		__func__, __LINE__, read_val, len,
+		cci_dev->cci_i2c_queue_info[master][queue].max_queue_size);
+	if ((read_val + len + 1) > cci_dev->
+		cci_i2c_queue_info[master][queue].max_queue_size) {
+		uint32_t reg_val = 0;
+		uint32_t report_val = CCI_I2C_REPORT_CMD | (1 << 8);
+		CDBG("%s:%d CCI_I2C_REPORT_CMD\n", __func__, __LINE__);
+		msm_camera_io_w(report_val,
+			cci_dev->base + CCI_I2C_M0_Q0_LOAD_DATA_ADDR +
+			reg_offset);
+		read_val++;
+		CDBG("%s:%d CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR %d\n",
+			__func__, __LINE__, read_val);
+		msm_camera_io_w(read_val, cci_dev->base +
+			CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR + reg_offset);
+		reg_val = 1 << ((master * 2) + queue);
+		CDBG("%s:%d CCI_QUEUE_START_ADDR\n", __func__, __LINE__);
+		msm_camera_io_w(reg_val, cci_dev->base + CCI_QUEUE_START_ADDR);
+		CDBG("%s line %d wait_for_completion_interruptible\n",
+			__func__, __LINE__);
+		rc = wait_for_completion_interruptible_timeout(&cci_dev->
+			cci_master_info[master].reset_complete, CCI_TIMEOUT);
+		if (rc <= 0) {
+			pr_err("%s: wait_for_completion_interruptible_timeout %d\n",
+				 __func__, __LINE__);
+			if (rc == 0)
+				rc = -ETIMEDOUT;
+			msm_cci_flush_queue(cci_dev, master);
+			return rc;
+		}
+		rc = cci_dev->cci_master_info[master].status;
+		if (rc < 0)
+			pr_err("%s failed rc %d\n", __func__, rc);
+	}
+	return rc;
+}
+
+static int32_t msm_cci_data_queue(struct cci_device *cci_dev,
+	struct msm_camera_cci_ctrl *c_ctrl, enum cci_i2c_queue_t queue)
+{
+	uint16_t i = 0, j = 0, k = 0, h = 0, len = 0;
+	int32_t rc = 0;
+	uint32_t cmd = 0;
+	uint8_t data[10];
+	uint16_t reg_addr = 0;
+	struct msm_camera_cci_i2c_write_cfg *i2c_msg =
+		&c_ctrl->cfg.cci_i2c_write_cfg;
+	uint16_t cmd_size = i2c_msg->size;
+	struct msm_camera_i2c_reg_conf *i2c_cmd = i2c_msg->reg_conf_tbl;
+	enum cci_i2c_master_t master = c_ctrl->cci_info->cci_i2c_master;
+	CDBG("%s addr type %d data type %d\n", __func__,
+		i2c_msg->addr_type, i2c_msg->data_type);
+	/* assume total size within the max queue */
+	while (cmd_size) {
+		CDBG("%s cmd_size %d addr 0x%x data 0x%x", __func__,
+			cmd_size, i2c_cmd->reg_addr, i2c_cmd->reg_data);
+		data[i++] = CCI_I2C_WRITE_CMD;
+		if (i2c_cmd->reg_addr)
+			reg_addr = i2c_cmd->reg_addr;
+		/* either byte or word addr */
+		if (i2c_msg->addr_type == MSM_CAMERA_I2C_BYTE_ADDR)
+			data[i++] = reg_addr;
+		else {
+			data[i++] = (reg_addr & 0xFF00) >> 8;
+			data[i++] = reg_addr & 0x00FF;
+		}
+		/* max of 10 data bytes */
+		do {
+			if (i2c_msg->data_type == MSM_CAMERA_I2C_BYTE_DATA) {
+				data[i++] = i2c_cmd->reg_data;
+				reg_addr++;
+			} else {
+				if ((i + 1) <= 10) {
+					data[i++] = (i2c_cmd->reg_data &
+						0xFF00) >> 8; /* MSB */
+					data[i++] = i2c_cmd->reg_data &
+						0x00FF; /* LSB */
+					reg_addr += 2;
+				} else
+					break;
+			}
+			i2c_cmd++;
+		} while (--cmd_size && !i2c_cmd->reg_addr && (i <= 10));
+		data[0] |= ((i-1) << 4);
+		len = ((i-1)/4) + 1;
+		rc = msm_cci_validate_queue(cci_dev, len, master, queue);
+		if (rc < 0) {
+			pr_err("%s: failed %d", __func__, __LINE__);
+			return rc;
+		}
+		for (h = 0, k = 0; h < len; h++) {
+			cmd = 0;
+			for (j = 0; (j < 4 && k < i); j++)
+				cmd |= (data[k++] << (j * 8));
+			CDBG("%s CCI_I2C_M0_Q0_LOAD_DATA_ADDR 0x%x\n",
+				__func__, cmd);
+			msm_camera_io_w(cmd, cci_dev->base +
+				CCI_I2C_M0_Q0_LOAD_DATA_ADDR +
+				master * 0x200 + queue * 0x100);
+		}
+		i = 0;
+	}
+	return rc;
+}
+
+static int32_t msm_cci_write_i2c_queue(struct cci_device *cci_dev,
+	uint32_t val,
+	enum cci_i2c_master_t master,
+	enum cci_i2c_queue_t queue)
+{
+	int32_t rc = 0;
+	uint32_t reg_offset = master * 0x200 + queue * 0x100;
+	CDBG("%s:%d called\n", __func__, __LINE__);
+	rc = msm_cci_validate_queue(cci_dev, 1, master, queue);
+	if (rc < 0) {
+		pr_err("%s: failed %d", __func__, __LINE__);
+		return rc;
+	}
+	CDBG("%s CCI_I2C_M0_Q0_LOAD_DATA_ADDR:val %x:%x\n",
+		__func__, CCI_I2C_M0_Q0_LOAD_DATA_ADDR +
+		reg_offset, val);
+	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_Q0_LOAD_DATA_ADDR +
+		reg_offset);
+	return rc;
+}
+
+static int32_t msm_cci_i2c_read(struct v4l2_subdev *sd,
+	struct msm_camera_cci_ctrl *c_ctrl)
+{
+	uint32_t rc = 0;
+	uint32_t val = 0;
+	int32_t read_words = 0, exp_words = 0;
+	int32_t index = 0, first_byte = 0;
+	uint32_t i = 0;
+	enum cci_i2c_master_t master;
+	enum cci_i2c_queue_t queue = QUEUE_1;
+	struct cci_device *cci_dev = NULL;
+	struct msm_camera_cci_i2c_read_cfg *read_cfg = NULL;
+	CDBG("%s line %d\n", __func__, __LINE__);
+	cci_dev = v4l2_get_subdevdata(sd);
+	master = c_ctrl->cci_info->cci_i2c_master;
+	read_cfg = &c_ctrl->cfg.cci_i2c_read_cfg;
+	mutex_lock(&cci_dev->cci_master_info[master].mutex);
+	CDBG("%s master %d, queue %d\n", __func__, master, queue);
+	CDBG("%s set param sid 0x%x retries %d id_map %d\n", __func__,
+		c_ctrl->cci_info->sid, c_ctrl->cci_info->retries,
+		c_ctrl->cci_info->id_map);
+	val = CCI_I2C_SET_PARAM_CMD | c_ctrl->cci_info->sid << 4 |
+		c_ctrl->cci_info->retries << 16 |
+		c_ctrl->cci_info->id_map << 18;
+	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
+	if (rc < 0) {
+		CDBG("%s failed line %d\n", __func__, __LINE__);
+		goto ERROR;
+	}
+
+	val = CCI_I2C_LOCK_CMD;
+	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
+	if (rc < 0) {
+		CDBG("%s failed line %d\n", __func__, __LINE__);
+		goto ERROR;
+	}
+
+	if (read_cfg->addr_type == MSM_CAMERA_I2C_BYTE_ADDR)
+		val = CCI_I2C_WRITE_CMD | (read_cfg->addr_type << 4) |
+			((read_cfg->addr & 0xFF) << 8);
+	if (read_cfg->addr_type == MSM_CAMERA_I2C_WORD_ADDR)
+		val = CCI_I2C_WRITE_CMD | (read_cfg->addr_type << 4) |
+			(((read_cfg->addr & 0xFF00) >> 8) << 8) |
+			((read_cfg->addr & 0xFF) << 16);
+	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
+	if (rc < 0) {
+		CDBG("%s failed line %d\n", __func__, __LINE__);
+		goto ERROR;
+	}
+
+	val = CCI_I2C_READ_CMD | (read_cfg->num_byte << 4);
+	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
+	if (rc < 0) {
+		CDBG("%s failed line %d\n", __func__, __LINE__);
+		goto ERROR;
+	}
+
+	val = CCI_I2C_UNLOCK_CMD;
+	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
+	if (rc < 0) {
+		CDBG("%s failed line %d\n", __func__, __LINE__);
+		goto ERROR;
+	}
+
+	val = msm_camera_io_r(cci_dev->base + CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR +
+		master * 0x200 + queue * 0x100);
+	CDBG("%s cur word cnt %x\n", __func__, val);
+	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR +
+		master * 0x200 + queue * 0x100);
+
+	val = 1 << ((master * 2) + queue);
+	msm_camera_io_w(val, cci_dev->base + CCI_QUEUE_START_ADDR);
+	CDBG("%s:%d E wait_for_completion_interruptible_timeout\n", __func__,
+		__LINE__);
+	rc = wait_for_completion_interruptible_timeout(&cci_dev->
+		cci_master_info[master].reset_complete, CCI_TIMEOUT);
+	if (rc <= 0) {
+		pr_err("%s: wait_for_completion_interruptible_timeout %d\n",
+			 __func__, __LINE__);
+		if (rc == 0)
+			rc = -ETIMEDOUT;
+		msm_cci_flush_queue(cci_dev, master);
+		goto ERROR;
+	} else {
+		rc = 0;
+	}
+	CDBG("%s:%d E wait_for_completion_interruptible_timeout\n", __func__,
+		__LINE__);
+
+	read_words = msm_camera_io_r(cci_dev->base +
+		CCI_I2C_M0_READ_BUF_LEVEL_ADDR + master * 0x100);
+	exp_words = ((read_cfg->num_byte / 4) + 1);
+	if (read_words != exp_words) {
+		pr_err("%s:%d read_words = %d, exp words = %d\n", __func__,
+			__LINE__, read_words, exp_words);
+		memset(read_cfg->data, 0, read_cfg->num_byte);
+		rc = -EINVAL;
+		goto ERROR;
+	}
+	index = 0;
+	CDBG("%s index %d num_type %d\n", __func__, index,
+		read_cfg->num_byte);
+	first_byte = 0;
+	do {
+		val = msm_camera_io_r(cci_dev->base +
+			CCI_I2C_M0_READ_DATA_ADDR + master * 0x100);
+		CDBG("%s read val %x\n", __func__, val);
+		for (i = 0; (i < 4) && (index < read_cfg->num_byte); i++) {
+			CDBG("%s i %d index %d\n", __func__, i, index);
+			if (!first_byte) {
+				CDBG("%s sid %x\n", __func__, val & 0xFF);
+				first_byte++;
+			} else {
+				read_cfg->data[index] =
+					(val  >> (i * 8)) & 0xFF;
+				CDBG("%s data[%d] %x\n", __func__, index,
+					read_cfg->data[index]);
+				index++;
+			}
+		}
+	} while (--read_words > 0);
+ERROR:
+	mutex_unlock(&cci_dev->cci_master_info[master].mutex);
+	return rc;
+}
+
+static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd,
+	struct msm_camera_cci_ctrl *c_ctrl)
+{
+	int32_t rc = 0;
+	struct cci_device *cci_dev;
+	uint32_t val;
+	enum cci_i2c_master_t master;
+	enum cci_i2c_queue_t queue = QUEUE_0;
+	cci_dev = v4l2_get_subdevdata(sd);
+	master = c_ctrl->cci_info->cci_i2c_master;
+	CDBG("%s master %d, queue %d\n", __func__, master, queue);
+	CDBG("%s set param sid 0x%x retries %d id_map %d\n", __func__,
+		c_ctrl->cci_info->sid, c_ctrl->cci_info->retries,
+		c_ctrl->cci_info->id_map);
+	mutex_lock(&cci_dev->cci_master_info[master].mutex);
+	val = CCI_I2C_SET_PARAM_CMD | c_ctrl->cci_info->sid << 4 |
+		c_ctrl->cci_info->retries << 16 |
+		c_ctrl->cci_info->id_map << 18;
+	CDBG("%s:%d CCI_I2C_SET_PARAM_CMD\n", __func__, __LINE__);
+	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
+	if (rc < 0) {
+		CDBG("%s failed line %d\n", __func__, __LINE__);
+		goto ERROR;
+	}
+
+	val = CCI_I2C_LOCK_CMD;
+	CDBG("%s:%d CCI_I2C_LOCK_CMD\n", __func__, __LINE__);
+	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
+	if (rc < 0) {
+		CDBG("%s failed line %d\n", __func__, __LINE__);
+		goto ERROR;
+	}
+
+	msm_cci_data_queue(cci_dev, c_ctrl, queue);
+	val = CCI_I2C_UNLOCK_CMD;
+	CDBG("%s:%d CCI_I2C_UNLOCK_CMD\n", __func__, __LINE__);
+	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
+	if (rc < 0) {
+		CDBG("%s failed line %d\n", __func__, __LINE__);
+		goto ERROR;
+	}
+
+	val = CCI_I2C_REPORT_CMD | (1 << 8);
+	CDBG("%s:%d CCI_I2C_REPORT_CMD\n", __func__, __LINE__);
+	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
+	if (rc < 0) {
+		CDBG("%s failed line %d\n", __func__, __LINE__);
+		goto ERROR;
+	}
+
+	val = msm_camera_io_r(cci_dev->base + CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR +
+		master * 0x200 + queue * 0x100);
+	CDBG("%s:%d cur word count %d\n", __func__, __LINE__, val);
+	CDBG("%s:%d CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR\n", __func__, __LINE__);
+	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR +
+		master * 0x200 + queue * 0x100);
+
+	val = 1 << ((master * 2) + queue);
+	CDBG("%s:%d CCI_QUEUE_START_ADDR\n", __func__, __LINE__);
+	msm_camera_io_w(val, cci_dev->base + CCI_QUEUE_START_ADDR);
+
+	CDBG("%s:%d E wait_for_completion_interruptible\n",
+		__func__, __LINE__);
+	rc = wait_for_completion_interruptible_timeout(&cci_dev->
+		cci_master_info[master].reset_complete, CCI_TIMEOUT);
+	if (rc <= 0) {
+		pr_err("%s: wait_for_completion_interruptible_timeout %d\n",
+			 __func__, __LINE__);
+		if (rc == 0)
+			rc = -ETIMEDOUT;
+		msm_cci_flush_queue(cci_dev, master);
+		goto ERROR;
+	} else {
+		rc = 0;
+	}
+	CDBG("%s:%d X wait_for_completion_interruptible\n", __func__,
+		__LINE__);
+
+ERROR:
+	mutex_unlock(&cci_dev->cci_master_info[master].mutex);
+	return rc;
+}
+
+static int msm_cci_subdev_g_chip_ident(struct v4l2_subdev *sd,
+			struct v4l2_dbg_chip_ident *chip)
+{
+	BUG_ON(!chip);
+	chip->ident = V4L2_IDENT_CCI;
+	chip->revision = 0;
+	return 0;
+}
+
+static struct msm_cam_clk_info cci_clk_info[] = {
+	{"camss_top_ahb_clk", -1},
+	{"cci_src_clk", 19200000},
+	{"cci_ahb_clk", -1},
+	{"cci_clk", -1},
+};
+
+static int32_t msm_cci_init(struct v4l2_subdev *sd)
+{
+	int rc = 0;
+	struct cci_device *cci_dev;
+	cci_dev = v4l2_get_subdevdata(sd);
+	CDBG("%s line %d\n", __func__, __LINE__);
+
+	if (!cci_dev) {
+		pr_err("%s cci device NULL\n", __func__);
+		rc = -ENOMEM;
+		return rc;
+	}
+
+	if (cci_dev->ref_count++) {
+		CDBG("%s ref_count %d\n", __func__, cci_dev->ref_count);
+		return 0;
+	}
+
+	rc = msm_camera_request_gpio_table(cci_dev->cci_gpio_tbl,
+		cci_dev->cci_gpio_tbl_size, 1);
+	if (rc < 0) {
+		cci_dev->ref_count--;
+		CDBG("%s: request gpio failed\n", __func__);
+		goto clk_enable_failed;
+	}
+
+	rc = msm_cam_clk_enable(&cci_dev->pdev->dev, cci_clk_info,
+		cci_dev->cci_clk, ARRAY_SIZE(cci_clk_info), 1);
+	if (rc < 0) {
+		cci_dev->ref_count--;
+		CDBG("%s: clk enable failed\n", __func__);
+		goto clk_enable_failed;
+	}
+
+	enable_irq(cci_dev->irq->start);
+	cci_dev->hw_version = msm_camera_io_r(cci_dev->base +
+		CCI_HW_VERSION_ADDR);
+	cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE;
+	msm_camera_io_w(CCI_RESET_CMD_RMSK, cci_dev->base + CCI_RESET_CMD_ADDR);
+	msm_camera_io_w(0x1, cci_dev->base + CCI_RESET_CMD_ADDR);
+	rc = wait_for_completion_interruptible_timeout(
+		&cci_dev->cci_master_info[MASTER_0].reset_complete,
+		CCI_TIMEOUT);
+	if (rc <= 0) {
+		pr_err("%s: wait_for_completion_interruptible_timeout %d\n",
+			 __func__, __LINE__);
+		if (rc == 0)
+			rc = -ETIMEDOUT;
+		return rc;
+	}
+	msm_cci_set_clk_param(cci_dev);
+	msm_camera_io_w(CCI_IRQ_MASK_0_RMSK,
+		cci_dev->base + CCI_IRQ_MASK_0_ADDR);
+	msm_camera_io_w(CCI_IRQ_MASK_0_RMSK,
+		cci_dev->base + CCI_IRQ_CLEAR_0_ADDR);
+	msm_camera_io_w(0x1, cci_dev->base + CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR);
+	cci_dev->cci_state = CCI_STATE_ENABLED;
+	return 0;
+
+clk_enable_failed:
+	return rc;
+}
+
+static int32_t msm_cci_release(struct v4l2_subdev *sd)
+{
+	struct cci_device *cci_dev;
+	cci_dev = v4l2_get_subdevdata(sd);
+
+	if (!cci_dev->ref_count || cci_dev->cci_state != CCI_STATE_ENABLED) {
+		pr_err("%s invalid ref count %d / cci state %d\n",
+			__func__, cci_dev->ref_count, cci_dev->cci_state);
+		return -EINVAL;
+	}
+
+	if (--cci_dev->ref_count) {
+		CDBG("%s ref_count %d\n", __func__, cci_dev->ref_count);
+		return 0;
+	}
+
+	disable_irq(cci_dev->irq->start);
+
+	msm_cam_clk_enable(&cci_dev->pdev->dev, cci_clk_info,
+		cci_dev->cci_clk, ARRAY_SIZE(cci_clk_info), 0);
+
+	msm_camera_request_gpio_table(cci_dev->cci_gpio_tbl,
+		cci_dev->cci_gpio_tbl_size, 0);
+
+	cci_dev->cci_state = CCI_STATE_DISABLED;
+	return 0;
+}
+
+static int32_t msm_cci_config(struct v4l2_subdev *sd,
+	struct msm_camera_cci_ctrl *cci_ctrl)
+{
+	int32_t rc = 0;
+	CDBG("%s line %d cmd %d\n", __func__, __LINE__,
+		cci_ctrl->cmd);
+	switch (cci_ctrl->cmd) {
+	case MSM_CCI_INIT:
+		rc = msm_cci_init(sd);
+		break;
+	case MSM_CCI_RELEASE:
+		rc = msm_cci_release(sd);
+		break;
+	case MSM_CCI_SET_SID:
+		break;
+	case MSM_CCI_SET_FREQ:
+		rc = msm_cci_i2c_set_freq(sd, cci_ctrl);
+		break;
+	case MSM_CCI_SET_SYNC_CID:
+		rc = msm_cci_i2c_config_sync_timer(sd, cci_ctrl);
+		break;
+	case MSM_CCI_I2C_READ:
+		rc = msm_cci_i2c_read(sd, cci_ctrl);
+		break;
+	case MSM_CCI_I2C_WRITE:
+		rc = msm_cci_i2c_write(sd, cci_ctrl);
+		break;
+	case MSM_CCI_GPIO_WRITE:
+		break;
+	default:
+		rc = -ENOIOCTLCMD;
+	}
+	CDBG("%s line %d rc %d\n", __func__, __LINE__, rc);
+	cci_ctrl->status = rc;
+	return rc;
+}
+
+static irqreturn_t msm_cci_irq(int irq_num, void *data)
+{
+	uint32_t irq;
+	struct cci_device *cci_dev = data;
+	irq = msm_camera_io_r(cci_dev->base + CCI_IRQ_STATUS_0_ADDR);
+	msm_camera_io_w(irq, cci_dev->base + CCI_IRQ_CLEAR_0_ADDR);
+	msm_camera_io_w(0x1, cci_dev->base + CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR);
+	msm_camera_io_w(0x0, cci_dev->base + CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR);
+	CDBG("%s CCI_I2C_M0_STATUS_ADDR = 0x%x\n", __func__, irq);
+	if (irq & CCI_IRQ_STATUS_0_RST_DONE_ACK_BMSK) {
+		if (cci_dev->cci_master_info[MASTER_0].reset_pending == TRUE) {
+			cci_dev->cci_master_info[MASTER_0].reset_pending =
+				FALSE;
+			complete(&cci_dev->cci_master_info[MASTER_0].
+				reset_complete);
+		}
+		if (cci_dev->cci_master_info[MASTER_1].reset_pending == TRUE) {
+			cci_dev->cci_master_info[MASTER_1].reset_pending =
+				FALSE;
+			complete(&cci_dev->cci_master_info[MASTER_1].
+				reset_complete);
+		}
+	} else if ((irq & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK) ||
+		(irq & CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK) ||
+		(irq & CCI_IRQ_STATUS_0_I2C_M0_Q1_REPORT_BMSK)) {
+		cci_dev->cci_master_info[MASTER_0].status = 0;
+		complete(&cci_dev->cci_master_info[MASTER_0].reset_complete);
+	} else if ((irq & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) ||
+		(irq & CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT_BMSK) ||
+		(irq & CCI_IRQ_STATUS_0_I2C_M1_Q1_REPORT_BMSK)) {
+		cci_dev->cci_master_info[MASTER_1].status = 0;
+		complete(&cci_dev->cci_master_info[MASTER_1].reset_complete);
+	} else if ((irq & CCI_IRQ_STATUS_0_I2C_M0_Q0_NACK_ERR_BMSK) ||
+		(irq & CCI_IRQ_STATUS_0_I2C_M0_Q1_NACK_ERR_BMSK)) {
+		cci_dev->cci_master_info[MASTER_0].status = -EINVAL;
+		msm_camera_io_w(CCI_M0_HALT_REQ_RMSK,
+			cci_dev->base + CCI_HALT_REQ_ADDR);
+	} else if ((irq & CCI_IRQ_STATUS_0_I2C_M1_Q0_NACK_ERR_BMSK) ||
+		(irq & CCI_IRQ_STATUS_0_I2C_M1_Q1_NACK_ERR_BMSK)) {
+		cci_dev->cci_master_info[MASTER_1].status = -EINVAL;
+		msm_camera_io_w(CCI_M1_HALT_REQ_RMSK,
+			cci_dev->base + CCI_HALT_REQ_ADDR);
+	} else if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK_BMSK) {
+		cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE;
+		msm_camera_io_w(CCI_M0_RESET_RMSK,
+			cci_dev->base + CCI_RESET_CMD_ADDR);
+	} else if (irq & CCI_IRQ_STATUS_0_I2C_M1_Q0Q1_HALT_ACK_BMSK) {
+		cci_dev->cci_master_info[MASTER_1].reset_pending = TRUE;
+		msm_camera_io_w(CCI_M1_RESET_RMSK,
+			cci_dev->base + CCI_RESET_CMD_ADDR);
+	} else {
+		pr_err("%s unhandled irq 0x%x\n", __func__, irq);
+		cci_dev->cci_master_info[MASTER_0].status = 0;
+		complete(&cci_dev->cci_master_info[MASTER_0].reset_complete);
+		cci_dev->cci_master_info[MASTER_1].status = 0;
+		complete(&cci_dev->cci_master_info[MASTER_1].reset_complete);
+	}
+	return IRQ_HANDLED;
+}
+
+static int msm_cci_irq_routine(struct v4l2_subdev *sd, u32 status,
+	bool *handled)
+{
+	struct cci_device *cci_dev = v4l2_get_subdevdata(sd);
+	irqreturn_t ret;
+	CDBG("%s line %d\n", __func__, __LINE__);
+	ret = msm_cci_irq(cci_dev->irq->start, cci_dev);
+	CDBG("%s: msm_cci_irq return %d\n", __func__, ret);
+	*handled = TRUE;
+	return 0;
+}
+
+static long msm_cci_subdev_ioctl(struct v4l2_subdev *sd,
+	unsigned int cmd, void *arg)
+{
+	int32_t rc = 0;
+	CDBG("%s line %d\n", __func__, __LINE__);
+	switch (cmd) {
+	case VIDIOC_MSM_CCI_CFG:
+		rc = msm_cci_config(sd, arg);
+		break;
+	default:
+		rc = -ENOIOCTLCMD;
+	}
+	CDBG("%s line %d rc %d\n", __func__, __LINE__, rc);
+	return rc;
+}
+
+static struct v4l2_subdev_core_ops msm_cci_subdev_core_ops = {
+	.g_chip_ident = &msm_cci_subdev_g_chip_ident,
+	.ioctl = &msm_cci_subdev_ioctl,
+	.interrupt_service_routine = msm_cci_irq_routine,
+};
+
+static const struct v4l2_subdev_ops msm_cci_subdev_ops = {
+	.core = &msm_cci_subdev_core_ops,
+};
+
+static const struct v4l2_subdev_internal_ops msm_cci_internal_ops;
+
+static void msm_cci_init_cci_params(struct cci_device *new_cci_dev)
+{
+	uint8_t i = 0, j = 0;
+	for (i = 0; i < NUM_MASTERS; i++) {
+		new_cci_dev->cci_master_info[i].status = 0;
+		mutex_init(&new_cci_dev->cci_master_info[i].mutex);
+		init_completion(&new_cci_dev->
+			cci_master_info[i].reset_complete);
+		for (j = 0; j < NUM_QUEUES; j++) {
+			if (j == QUEUE_0)
+				new_cci_dev->cci_i2c_queue_info[i][j].
+					max_queue_size = CCI_I2C_QUEUE_0_SIZE;
+			else
+				new_cci_dev->cci_i2c_queue_info[i][j].
+					max_queue_size = CCI_I2C_QUEUE_1_SIZE;
+			}
+	}
+	return;
+}
+
+static int32_t msm_cci_init_gpio_params(struct cci_device *cci_dev)
+{
+	int32_t rc = 0, i = 0;
+	uint32_t *val_array = NULL;
+	uint8_t tbl_size = 0;
+	struct device_node *of_node = cci_dev->pdev->dev.of_node;
+	struct gpio *gpio_tbl = NULL;
+
+	cci_dev->cci_gpio_tbl_size = tbl_size = of_gpio_count(of_node);
+	CDBG("%s gpio count %d\n", __func__, tbl_size);
+	if (!tbl_size) {
+		pr_err("%s:%d gpio count 0\n", __func__, __LINE__);
+		return 0;
+	}
+
+	gpio_tbl = cci_dev->cci_gpio_tbl =
+		kzalloc(sizeof(struct gpio) * tbl_size, GFP_KERNEL);
+	if (!gpio_tbl) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		return 0;
+	}
+
+	for (i = 0; i < tbl_size; i++) {
+		gpio_tbl[i].gpio = of_get_gpio(of_node, i);
+		CDBG("%s gpio_tbl[%d].gpio = %d\n", __func__, i,
+			gpio_tbl[i].gpio);
+	}
+
+	val_array = kzalloc(sizeof(uint32_t) * tbl_size, GFP_KERNEL);
+	if (!val_array) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		goto ERROR1;
+	}
+
+	rc = of_property_read_u32_array(of_node, "qcom,gpio-tbl-flags",
+		val_array, tbl_size);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < tbl_size; i++) {
+		gpio_tbl[i].flags = val_array[i];
+		CDBG("%s gpio_tbl[%d].flags = %ld\n", __func__, i,
+			gpio_tbl[i].flags);
+	}
+
+	for (i = 0; i < tbl_size; i++) {
+		rc = of_property_read_string_index(of_node,
+			"qcom,gpio-tbl-label", i, &gpio_tbl[i].label);
+		CDBG("%s gpio_tbl[%d].label = %s\n", __func__, i,
+			gpio_tbl[i].label);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR2;
+		}
+	}
+
+	kfree(val_array);
+	return rc;
+
+ERROR2:
+	kfree(val_array);
+ERROR1:
+	kfree(cci_dev->cci_gpio_tbl);
+	cci_dev->cci_gpio_tbl = NULL;
+	cci_dev->cci_gpio_tbl_size = 0;
+	return rc;
+}
+
+static void msm_cci_init_clk_params(struct cci_device *cci_dev)
+{
+	int32_t rc = 0;
+	uint32_t val = 0;
+	struct device_node *of_node = cci_dev->pdev->dev.of_node;
+
+	rc = of_property_read_u32(of_node, "qcom,hw-thigh", &val);
+	CDBG("%s qcom,hw-thigh %d, rc %d\n", __func__, val, rc);
+	if (!rc)
+		cci_dev->cci_clk_params.hw_thigh = val;
+
+	rc = of_property_read_u32(of_node, "qcom,hw-tlow", &val);
+	CDBG("%s qcom,hw-tlow %d, rc %d\n", __func__, val, rc);
+	if (!rc)
+		cci_dev->cci_clk_params.hw_tlow = val;
+
+	rc = of_property_read_u32(of_node, "qcom,hw-tsu-sto", &val);
+	CDBG("%s qcom,hw-tsu-sto %d, rc %d\n", __func__, val, rc);
+	if (!rc)
+		cci_dev->cci_clk_params.hw_tsu_sto = val;
+
+	rc = of_property_read_u32(of_node, "qcom,hw-tsu-sta", &val);
+	CDBG("%s qcom,hw-tsu-sta %d, rc %d\n", __func__, val, rc);
+	if (!rc)
+		cci_dev->cci_clk_params.hw_tsu_sta = val;
+
+	rc = of_property_read_u32(of_node, "qcom,hw-thd-dat", &val);
+	CDBG("%s qcom,hw-thd-dat %d, rc %d\n", __func__, val, rc);
+	if (!rc)
+		cci_dev->cci_clk_params.hw_thd_dat = val;
+
+	rc = of_property_read_u32(of_node, "qcom,hw-thd-sta", &val);
+	CDBG("%s qcom,hwthd-sta %d, rc %d\n", __func__, val, rc);
+	if (!rc)
+		cci_dev->cci_clk_params.hw_thd_sta = val;
+
+	rc = of_property_read_u32(of_node, "qcom,hw-tbuf", &val);
+	CDBG("%s qcom,hw-tbuf %d, rc %d\n", __func__, val, rc);
+	if (!rc)
+		cci_dev->cci_clk_params.hw_tbuf = val;
+
+	rc = of_property_read_u32(of_node, "qcom,hw-scl-stretch-en", &val);
+	CDBG("%s qcom,hw-scl-stretch-en %d, rc %d\n", __func__, val, rc);
+	if (!rc)
+		cci_dev->cci_clk_params.hw_scl_stretch_en = val;
+
+	rc = of_property_read_u32(of_node, "qcom,hw-trdhld", &val);
+	CDBG("%s qcom,hw-trdhld %d, rc %d\n", __func__, val, rc);
+	if (!rc)
+		cci_dev->cci_clk_params.hw_trdhld = val;
+
+	rc = of_property_read_u32(of_node, "qcom,hw-tsp", &val);
+	CDBG("%s qcom,hw-tsp %d, rc %d\n", __func__, val, rc);
+	if (!rc)
+		cci_dev->cci_clk_params.hw_tsp = val;
+
+	return;
+}
+
+struct v4l2_subdev *msm_cci_get_subdev(void)
+{
+	return g_cci_subdev;
+}
+
+static int __devinit msm_cci_probe(struct platform_device *pdev)
+{
+	struct cci_device *new_cci_dev;
+	int rc = 0;
+	pr_err("%s: pdev %p device id = %d\n", __func__, pdev, pdev->id);
+	new_cci_dev = kzalloc(sizeof(struct cci_device), GFP_KERNEL);
+	if (!new_cci_dev) {
+		CDBG("%s: no enough memory\n", __func__);
+		return -ENOMEM;
+	}
+	v4l2_subdev_init(&new_cci_dev->msm_sd.sd, &msm_cci_subdev_ops);
+	new_cci_dev->msm_sd.sd.internal_ops = &msm_cci_internal_ops;
+	snprintf(new_cci_dev->msm_sd.sd.name,
+			ARRAY_SIZE(new_cci_dev->msm_sd.sd.name), "msm_cci");
+	v4l2_set_subdevdata(&new_cci_dev->msm_sd.sd, new_cci_dev);
+	platform_set_drvdata(pdev, &new_cci_dev->msm_sd.sd);
+	CDBG("%s sd %p\n", __func__, &new_cci_dev->msm_sd.sd);
+	if (pdev->dev.of_node)
+		of_property_read_u32((&pdev->dev)->of_node,
+			"cell-index", &pdev->id);
+
+	new_cci_dev->mem = platform_get_resource_byname(pdev,
+					IORESOURCE_MEM, "cci");
+	if (!new_cci_dev->mem) {
+		CDBG("%s: no mem resource?\n", __func__);
+		rc = -ENODEV;
+		goto cci_no_resource;
+	}
+	new_cci_dev->irq = platform_get_resource_byname(pdev,
+					IORESOURCE_IRQ, "cci");
+	CDBG("%s line %d cci irq start %d end %d\n", __func__,
+		__LINE__,
+		new_cci_dev->irq->start,
+		new_cci_dev->irq->end);
+	if (!new_cci_dev->irq) {
+		CDBG("%s: no irq resource?\n", __func__);
+		rc = -ENODEV;
+		goto cci_no_resource;
+	}
+	new_cci_dev->io = request_mem_region(new_cci_dev->mem->start,
+		resource_size(new_cci_dev->mem), pdev->name);
+	if (!new_cci_dev->io) {
+		CDBG("%s: no valid mem region\n", __func__);
+		rc = -EBUSY;
+		goto cci_no_resource;
+	}
+
+	new_cci_dev->base = ioremap(new_cci_dev->mem->start,
+		resource_size(new_cci_dev->mem));
+	if (!new_cci_dev->base) {
+		rc = -ENOMEM;
+		goto cci_release_mem;
+	}
+	rc = request_irq(new_cci_dev->irq->start, msm_cci_irq,
+		IRQF_TRIGGER_RISING, "cci", new_cci_dev);
+	if (rc < 0) {
+		CDBG("%s: irq request fail\n", __func__);
+		rc = -EBUSY;
+		goto cci_release_mem;
+	}
+	disable_irq(new_cci_dev->irq->start);
+	msm_sd_register(&new_cci_dev->msm_sd);
+	new_cci_dev->pdev = pdev;
+	msm_cci_init_cci_params(new_cci_dev);
+	msm_cci_init_clk_params(new_cci_dev);
+	msm_cci_init_gpio_params(new_cci_dev);
+	rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+	if (rc)
+		pr_err("%s: failed to add child nodes, rc=%d\n", __func__, rc);
+	new_cci_dev->cci_state = CCI_STATE_DISABLED;
+	g_cci_subdev = &new_cci_dev->msm_sd.sd;
+	CDBG("%s cci subdev %p\n", __func__, &new_cci_dev->msm_sd.sd);
+	CDBG("%s line %d\n", __func__, __LINE__);
+	return 0;
+
+cci_release_mem:
+	release_mem_region(new_cci_dev->mem->start,
+		resource_size(new_cci_dev->mem));
+cci_no_resource:
+	kfree(new_cci_dev);
+	return 0;
+}
+
+static int __exit msm_cci_exit(struct platform_device *pdev)
+{
+	struct v4l2_subdev *subdev = platform_get_drvdata(pdev);
+	struct cci_device *cci_dev =
+		v4l2_get_subdevdata(subdev);
+	release_mem_region(cci_dev->mem->start, resource_size(cci_dev->mem));
+	kfree(cci_dev);
+	return 0;
+}
+
+static const struct of_device_id msm_cci_dt_match[] = {
+	{.compatible = "qcom,cci"},
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, msm_cci_dt_match);
+
+static struct platform_driver cci_driver = {
+	.probe = msm_cci_probe,
+	.remove = msm_cci_exit,
+	.driver = {
+		.name = MSM_CCI_DRV_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = msm_cci_dt_match,
+	},
+};
+
+static int __init msm_cci_init_module(void)
+{
+	return platform_driver_register(&cci_driver);
+}
+
+static void __exit msm_cci_exit_module(void)
+{
+	platform_driver_unregister(&cci_driver);
+}
+
+module_init(msm_cci_init_module);
+module_exit(msm_cci_exit_module);
+MODULE_DESCRIPTION("MSM CCI driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.h b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.h
new file mode 100644
index 0000000..f9e40f1
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.h
@@ -0,0 +1,185 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_CCI_H
+#define MSM_CCI_H
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <media/v4l2-subdev.h>
+#include <media/msm_cam_sensor.h>
+#include <mach/camera2.h>
+#include "msm_sd.h"
+
+#define NUM_MASTERS 2
+#define NUM_QUEUES 2
+
+#define TRUE  1
+#define FALSE 0
+
+enum cci_i2c_queue_t {
+	QUEUE_0,
+	QUEUE_1,
+};
+
+struct msm_camera_cci_client {
+	struct v4l2_subdev *cci_subdev;
+	uint32_t freq;
+	enum cci_i2c_master_t cci_i2c_master;
+	uint16_t sid;
+	uint16_t cid;
+	uint32_t timeout;
+	uint16_t retries;
+	uint16_t id_map;
+};
+
+enum msm_cci_cmd_type {
+	MSM_CCI_INIT,
+	MSM_CCI_RELEASE,
+	MSM_CCI_SET_SID,
+	MSM_CCI_SET_FREQ,
+	MSM_CCI_SET_SYNC_CID,
+	MSM_CCI_I2C_READ,
+	MSM_CCI_I2C_WRITE,
+	MSM_CCI_GPIO_WRITE,
+};
+
+struct msm_camera_cci_wait_sync_cfg {
+	uint16_t line;
+	uint16_t delay;
+};
+
+struct msm_camera_cci_gpio_cfg {
+	uint16_t gpio_queue;
+	uint16_t i2c_queue;
+};
+
+struct msm_camera_cci_i2c_write_cfg {
+	struct msm_camera_i2c_reg_conf *reg_conf_tbl;
+	enum msm_camera_i2c_reg_addr_type addr_type;
+	enum msm_camera_i2c_data_type data_type;
+	uint16_t size;
+};
+
+struct msm_camera_cci_i2c_read_cfg {
+	uint16_t addr;
+	enum msm_camera_i2c_reg_addr_type addr_type;
+	uint8_t *data;
+	uint16_t num_byte;
+};
+
+struct msm_camera_cci_i2c_queue_info {
+	uint32_t max_queue_size;
+	uint32_t report_id;
+	uint32_t irq_en;
+	uint32_t capture_rep_data;
+};
+
+struct msm_camera_cci_ctrl {
+	int32_t status;
+	struct msm_camera_cci_client *cci_info;
+	enum msm_cci_cmd_type cmd;
+	union {
+		struct msm_camera_cci_i2c_write_cfg cci_i2c_write_cfg;
+		struct msm_camera_cci_i2c_read_cfg cci_i2c_read_cfg;
+		struct msm_camera_cci_wait_sync_cfg cci_wait_sync_cfg;
+		struct msm_camera_cci_gpio_cfg gpio_cfg;
+	} cfg;
+};
+
+struct msm_camera_cci_master_info {
+	uint32_t status;
+	uint8_t reset_pending;
+	struct mutex mutex;
+	struct completion reset_complete;
+};
+
+struct msm_cci_clk_params_t {
+	uint16_t hw_thigh;
+	uint16_t hw_tlow;
+	uint16_t hw_tsu_sto;
+	uint16_t hw_tsu_sta;
+	uint16_t hw_thd_dat;
+	uint16_t hw_thd_sta;
+	uint16_t hw_tbuf;
+	uint8_t hw_scl_stretch_en;
+	uint8_t hw_trdhld;
+	uint8_t hw_tsp;
+};
+
+enum msm_cci_state_t {
+	CCI_STATE_ENABLED,
+	CCI_STATE_DISABLED,
+};
+
+struct cci_device {
+	struct platform_device *pdev;
+	struct msm_sd_subdev msm_sd;
+	struct v4l2_subdev subdev;
+	struct resource *mem;
+	struct resource *irq;
+	struct resource *io;
+	void __iomem *base;
+
+	uint32_t hw_version;
+	uint8_t ref_count;
+	enum msm_cci_state_t cci_state;
+
+	struct clk *cci_clk[5];
+	struct msm_camera_cci_i2c_queue_info
+		cci_i2c_queue_info[NUM_MASTERS][NUM_QUEUES];
+	struct msm_camera_cci_master_info cci_master_info[NUM_MASTERS];
+	struct msm_cci_clk_params_t cci_clk_params;
+	struct gpio *cci_gpio_tbl;
+	uint8_t cci_gpio_tbl_size;
+};
+
+enum msm_cci_i2c_cmd_type {
+	CCI_I2C_SET_PARAM_CMD = 1,
+	CCI_I2C_WAIT_CMD,
+	CCI_I2C_WAIT_SYNC_CMD,
+	CCI_I2C_WAIT_GPIO_EVENT_CMD,
+	CCI_I2C_TRIG_I2C_EVENT_CMD,
+	CCI_I2C_LOCK_CMD,
+	CCI_I2C_UNLOCK_CMD,
+	CCI_I2C_REPORT_CMD,
+	CCI_I2C_WRITE_CMD,
+	CCI_I2C_READ_CMD,
+	CCI_I2C_WRITE_DISABLE_P_CMD,
+	CCI_I2C_READ_DISABLE_P_CMD,
+	CCI_I2C_WRITE_CMD2,
+	CCI_I2C_WRITE_CMD3,
+	CCI_I2C_REPEAT_CMD,
+	CCI_I2C_INVALID_CMD,
+};
+
+enum msm_cci_gpio_cmd_type {
+	CCI_GPIO_SET_PARAM_CMD = 1,
+	CCI_GPIO_WAIT_CMD,
+	CCI_GPIO_WAIT_SYNC_CMD,
+	CCI_GPIO_WAIT_GPIO_IN_EVENT_CMD,
+	CCI_GPIO_WAIT_I2C_Q_TRIG_EVENT_CMD,
+	CCI_GPIO_OUT_CMD,
+	CCI_GPIO_TRIG_EVENT_CMD,
+	CCI_GPIO_REPORT_CMD,
+	CCI_GPIO_REPEAT_CMD,
+	CCI_GPIO_CONTINUE_CMD,
+	CCI_GPIO_INVALID_CMD,
+};
+
+struct v4l2_subdev *msm_cci_get_subdev(void);
+
+#define VIDIOC_MSM_CCI_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 23, struct msm_camera_cci_ctrl *)
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csid/Makefile b/drivers/media/platform/msm/camera_v2/sensor/csid/Makefile
new file mode 100644
index 0000000..572e722
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/csid/Makefile
@@ -0,0 +1,8 @@
+ccflags-y += -Idrivers/media/platform/msm/camera_v2
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io
+ifeq ($(CONFIG_MSM_CSI20_HEADER),y)
+  ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/csid/include/csi2.0
+else ifeq ($(CONFIG_MSM_CSI30_HEADER),y)
+  ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/csid/include/csi3.0
+endif
+obj-$(CONFIG_MSM_CSID) += msm_csid.o
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csid/include/csi2.0/msm_csid_hwreg.h b/drivers/media/platform/msm/camera_v2/sensor/csid/include/csi2.0/msm_csid_hwreg.h
new file mode 100644
index 0000000..87a114e
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/csid/include/csi2.0/msm_csid_hwreg.h
@@ -0,0 +1,52 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_CSID_HWREG_H
+#define MSM_CSID_HWREG_H
+
+/* MIPI	CSID registers */
+#define CSID_HW_VERSION_ADDR                        0x0
+#define CSID_CORE_CTRL_0_ADDR                       0x4
+#define CSID_CORE_CTRL_1_ADDR                       0x4
+#define CSID_RST_CMD_ADDR                           0x8
+#define CSID_CID_LUT_VC_0_ADDR                      0xc
+#define CSID_CID_LUT_VC_1_ADDR                      0x10
+#define CSID_CID_LUT_VC_2_ADDR                      0x14
+#define CSID_CID_LUT_VC_3_ADDR                      0x18
+#define CSID_CID_n_CFG_ADDR                         0x1C
+#define CSID_IRQ_CLEAR_CMD_ADDR                     0x5c
+#define CSID_IRQ_MASK_ADDR                          0x60
+#define CSID_IRQ_STATUS_ADDR                        0x64
+#define CSID_CAPTURED_UNMAPPED_LONG_PKT_HDR_ADDR    0x68
+#define CSID_CAPTURED_MMAPPED_LONG_PKT_HDR_ADDR     0x6c
+#define CSID_CAPTURED_SHORT_PKT_ADDR                0x70
+#define CSID_CAPTURED_LONG_PKT_HDR_ADDR             0x74
+#define CSID_CAPTURED_LONG_PKT_FTR_ADDR             0x78
+#define CSID_PIF_MISR_DL0_ADDR                      0x7C
+#define CSID_PIF_MISR_DL1_ADDR                      0x80
+#define CSID_PIF_MISR_DL2_ADDR                      0x84
+#define CSID_PIF_MISR_DL3_ADDR                      0x88
+#define CSID_STATS_TOTAL_PKTS_RCVD_ADDR             0x8C
+#define CSID_STATS_ECC_ADDR                         0x90
+#define CSID_STATS_CRC_ADDR                         0x94
+#define CSID_TG_CTRL_ADDR                           0x9C
+#define CSID_TG_VC_CFG_ADDR                         0xA0
+#define CSID_TG_DT_n_CFG_0_ADDR                     0xA8
+#define CSID_TG_DT_n_CFG_1_ADDR                     0xAC
+#define CSID_TG_DT_n_CFG_2_ADDR                     0xB0
+#define CSID_RST_DONE_IRQ_BITSHIFT                  11
+#define CSID_RST_STB_ALL                            0x7FFF
+#define CSID_DL_INPUT_SEL_SHIFT                     0x2
+#define CSID_PHY_SEL_SHIFT                          17
+#define CSID_VERSION                                0x02000011
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csid/include/csi3.0/msm_csid_hwreg.h b/drivers/media/platform/msm/camera_v2/sensor/csid/include/csi3.0/msm_csid_hwreg.h
new file mode 100644
index 0000000..8cea521
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/csid/include/csi3.0/msm_csid_hwreg.h
@@ -0,0 +1,52 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_CSID_HWREG_H
+#define MSM_CSID_HWREG_H
+
+/* MIPI	CSID registers */
+#define CSID_HW_VERSION_ADDR                        0x0
+#define CSID_CORE_CTRL_0_ADDR                       0x4
+#define CSID_CORE_CTRL_1_ADDR                       0x8
+#define CSID_RST_CMD_ADDR                           0xC
+#define CSID_CID_LUT_VC_0_ADDR                      0x10
+#define CSID_CID_LUT_VC_1_ADDR                      0x14
+#define CSID_CID_LUT_VC_2_ADDR                      0x18
+#define CSID_CID_LUT_VC_3_ADDR                      0x1C
+#define CSID_CID_n_CFG_ADDR                         0x20
+#define CSID_IRQ_CLEAR_CMD_ADDR                     0x60
+#define CSID_IRQ_MASK_ADDR                          0x64
+#define CSID_IRQ_STATUS_ADDR                        0x68
+#define CSID_CAPTURED_UNMAPPED_LONG_PKT_HDR_ADDR    0x6C
+#define CSID_CAPTURED_MMAPPED_LONG_PKT_HDR_ADDR     0x70
+#define CSID_CAPTURED_SHORT_PKT_ADDR                0x74
+#define CSID_CAPTURED_LONG_PKT_HDR_ADDR             0x78
+#define CSID_CAPTURED_LONG_PKT_FTR_ADDR             0x7C
+#define CSID_PIF_MISR_DL0_ADDR                      0x80
+#define CSID_PIF_MISR_DL1_ADDR                      0x84
+#define CSID_PIF_MISR_DL2_ADDR                      0x88
+#define CSID_PIF_MISR_DL3_ADDR                      0x8C
+#define CSID_STATS_TOTAL_PKTS_RCVD_ADDR             0x90
+#define CSID_STATS_ECC_ADDR                         0x94
+#define CSID_STATS_CRC_ADDR                         0x98
+#define CSID_TG_CTRL_ADDR                           0xA0
+#define CSID_TG_VC_CFG_ADDR                         0xA4
+#define CSID_TG_DT_n_CFG_0_ADDR                     0xAC
+#define CSID_TG_DT_n_CFG_1_ADDR                     0xB0
+#define CSID_TG_DT_n_CFG_2_ADDR                     0xB4
+#define CSID_RST_DONE_IRQ_BITSHIFT                  11
+#define CSID_RST_STB_ALL                            0x7FFF
+#define CSID_DL_INPUT_SEL_SHIFT                     0x4
+#define CSID_PHY_SEL_SHIFT                          17
+#define CSID_VERSION                                0x30000000
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
new file mode 100644
index 0000000..2c8c8b8
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
@@ -0,0 +1,685 @@
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/irqreturn.h>
+#include "msm_csid.h"
+#include "msm_csid_hwreg.h"
+#include "msm_sd.h"
+#include "msm_camera_io_util.h"
+
+#define V4L2_IDENT_CSID                            50002
+#define CSID_VERSION_V2                      0x02000011
+#define CSID_VERSION_V3                      0x30000000
+#define MSM_CSID_DRV_NAME                    "msm_csid"
+
+#define DBG_CSID 1
+
+#define TRUE   1
+#define FALSE  0
+
+#undef CDBG
+#ifdef CONFIG_MSMB_CAMERA_DEBUG
+#define CDBG(fmt, args...) pr_err(fmt, ##args)
+#else
+#define CDBG(fmt, args...) do { } while (0)
+#endif
+
+static uint32_t irq_count;
+
+static int msm_csid_cid_lut(
+	struct msm_camera_csid_lut_params *csid_lut_params,
+	void __iomem *csidbase)
+{
+	int rc = 0, i = 0;
+	uint32_t val = 0;
+
+	if (!csid_lut_params) {
+		pr_err("%s:%d csid_lut_params NULL\n", __func__, __LINE__);
+		return -EINVAL;
+	}
+	for (i = 0; i < csid_lut_params->num_cid && i < 16; i++) {
+		CDBG("%s lut params num_cid = %d, cid = %d, dt = %x, df = %d\n",
+			__func__,
+			csid_lut_params->num_cid,
+			csid_lut_params->vc_cfg[i]->cid,
+			csid_lut_params->vc_cfg[i]->dt,
+			csid_lut_params->vc_cfg[i]->decode_format);
+		if (csid_lut_params->vc_cfg[i]->dt < 0x12 ||
+			csid_lut_params->vc_cfg[i]->dt > 0x37) {
+			pr_err("%s: unsupported data type 0x%x\n",
+				 __func__, csid_lut_params->vc_cfg[i]->dt);
+			return rc;
+		}
+		val = msm_camera_io_r(csidbase + CSID_CID_LUT_VC_0_ADDR +
+			(csid_lut_params->vc_cfg[i]->cid >> 2) * 4)
+			& ~(0xFF << ((csid_lut_params->vc_cfg[i]->cid % 4) *
+			8));
+		val |= (csid_lut_params->vc_cfg[i]->dt <<
+			((csid_lut_params->vc_cfg[i]->cid % 4) * 8));
+		msm_camera_io_w(val, csidbase + CSID_CID_LUT_VC_0_ADDR +
+			(csid_lut_params->vc_cfg[i]->cid >> 2) * 4);
+
+		val = (csid_lut_params->vc_cfg[i]->decode_format << 4) | 0x3;
+		msm_camera_io_w(val, csidbase + CSID_CID_n_CFG_ADDR +
+			(csid_lut_params->vc_cfg[i]->cid * 4));
+	}
+	return rc;
+}
+
+#if DBG_CSID
+static void msm_csid_set_debug_reg(void __iomem *csidbase,
+	struct msm_camera_csid_params *csid_params)
+{
+	uint32_t val = 0;
+	val = ((1 << csid_params->lane_cnt) - 1) << 20;
+	msm_camera_io_w(0x7f010801 | val, csidbase + CSID_IRQ_MASK_ADDR);
+	msm_camera_io_w(0x7f010801 | val, csidbase + CSID_IRQ_CLEAR_CMD_ADDR);
+}
+#else
+static void msm_csid_set_debug_reg(void __iomem *csidbase,
+	struct msm_camera_csid_params *csid_params) {}
+#endif
+
+static void msm_csid_reset(struct csid_device *csid_dev)
+{
+	CDBG("%s:%d called\n", __func__, __LINE__);
+	msm_camera_io_w(CSID_RST_STB_ALL, csid_dev->base + CSID_RST_CMD_ADDR);
+	CDBG("%s:%d called\n", __func__, __LINE__);
+	wait_for_completion_interruptible(&csid_dev->reset_complete);
+	CDBG("%s:%d called\n", __func__, __LINE__);
+	return;
+}
+
+static int msm_csid_config(struct csid_device *csid_dev,
+	struct msm_camera_csid_params *csid_params)
+{
+	int rc = 0;
+	uint32_t val = 0;
+	void __iomem *csidbase;
+	csidbase = csid_dev->base;
+	if (!csidbase || !csid_params) {
+		pr_err("%s:%d csidbase %p, csid params %p\n", __func__,
+			__LINE__, csidbase, csid_params);
+		return -EINVAL;
+	}
+
+	CDBG("%s csid_params, lane_cnt = %d, lane_assign = %x, phy sel = %d\n",
+		__func__,
+		csid_params->lane_cnt,
+		csid_params->lane_assign,
+		csid_params->phy_sel);
+
+	msm_csid_reset(csid_dev);
+
+	val = csid_params->lane_cnt - 1;
+	val |= csid_params->lane_assign << CSID_DL_INPUT_SEL_SHIFT;
+	if (csid_dev->hw_version < 0x30000000) {
+		val |= (0xF << 10);
+		msm_camera_io_w(val, csidbase + CSID_CORE_CTRL_0_ADDR);
+	} else {
+		msm_camera_io_w(val, csidbase + CSID_CORE_CTRL_0_ADDR);
+		val = csid_params->phy_sel << CSID_PHY_SEL_SHIFT;
+		val |= 0xF;
+		msm_camera_io_w(val, csidbase + CSID_CORE_CTRL_1_ADDR);
+	}
+
+	rc = msm_csid_cid_lut(&csid_params->lut_params, csidbase);
+	if (rc < 0)
+		return rc;
+
+	msm_csid_set_debug_reg(csidbase, csid_params);
+	return rc;
+}
+
+static irqreturn_t msm_csid_irq(int irq_num, void *data)
+{
+	uint32_t irq;
+	struct csid_device *csid_dev = data;
+	void __iomem *csidbase;
+	csidbase = csid_dev->base;
+
+	if (!csid_dev) {
+		pr_err("%s:%d csid_dev NULL\n", __func__, __LINE__);
+		return IRQ_HANDLED;
+	}
+	irq = msm_camera_io_r(csid_dev->base + CSID_IRQ_STATUS_ADDR);
+	CDBG("%s CSID%d_IRQ_STATUS_ADDR = 0x%x\n",
+		 __func__, csid_dev->pdev->id, irq);
+	if (irq & (0x1 << CSID_RST_DONE_IRQ_BITSHIFT))
+			complete(&csid_dev->reset_complete);
+	if (irq & 0x1) {
+		pr_debug("%s CSID%d_IRQ_STATUS_ADDR = 0x%x\n",
+			__func__, csid_dev->pdev->id, irq);
+		irq_count++;
+	}
+	msm_camera_io_w(irq, csid_dev->base + CSID_IRQ_CLEAR_CMD_ADDR);
+	return IRQ_HANDLED;
+}
+
+static int msm_csid_irq_routine(struct v4l2_subdev *sd, u32 status,
+	bool *handled)
+{
+	struct csid_device *csid_dev = v4l2_get_subdevdata(sd);
+	irqreturn_t ret;
+	CDBG("%s E\n", __func__);
+	ret = msm_csid_irq(csid_dev->irq->start, csid_dev);
+	*handled = TRUE;
+	return 0;
+}
+
+static int msm_csid_subdev_g_chip_ident(struct v4l2_subdev *sd,
+			struct v4l2_dbg_chip_ident *chip)
+{
+	BUG_ON(!chip);
+	chip->ident = V4L2_IDENT_CSID;
+	chip->revision = 0;
+	return 0;
+}
+
+static struct msm_cam_clk_info csid_8960_clk_info[] = {
+	{"csi_src_clk", 177780000},
+	{"csi_clk", -1},
+	{"csi_phy_clk", -1},
+	{"csi_pclk", -1},
+};
+
+static struct msm_cam_clk_info csid0_8974_clk_info[] = {
+	{"camss_top_ahb_clk", -1},
+	{"ispif_ahb_clk", -1},
+	{"csi0_ahb_clk", -1},
+	{"csi0_src_clk", 200000000},
+	{"csi0_clk", -1},
+	{"csi0_phy_clk", -1},
+	{"csi0_pix_clk", -1},
+	{"csi0_rdi_clk", -1},
+};
+
+static struct msm_cam_clk_info csid1_8974_clk_info[] = {
+	{"csi1_ahb_clk", -1},
+	{"csi1_src_clk", 200000000},
+	{"csi1_clk", -1},
+	{"csi1_phy_clk", -1},
+	{"csi1_pix_clk", -1},
+	{"csi1_rdi_clk", -1},
+};
+
+static struct msm_cam_clk_info csid2_8974_clk_info[] = {
+	{"csi2_ahb_clk", -1},
+	{"csi2_src_clk", 200000000},
+	{"csi2_clk", -1},
+	{"csi2_phy_clk", -1},
+	{"csi2_pix_clk", -1},
+	{"csi2_rdi_clk", -1},
+};
+
+static struct msm_cam_clk_info csid3_8974_clk_info[] = {
+	{"csi3_ahb_clk", -1},
+	{"csi3_src_clk", 200000000},
+	{"csi3_clk", -1},
+	{"csi3_phy_clk", -1},
+	{"csi3_pix_clk", -1},
+	{"csi3_rdi_clk", -1},
+};
+
+static struct msm_cam_clk_setting csid_8974_clk_info[] = {
+	{&csid0_8974_clk_info[0], ARRAY_SIZE(csid0_8974_clk_info)},
+	{&csid1_8974_clk_info[0], ARRAY_SIZE(csid1_8974_clk_info)},
+	{&csid2_8974_clk_info[0], ARRAY_SIZE(csid2_8974_clk_info)},
+	{&csid3_8974_clk_info[0], ARRAY_SIZE(csid3_8974_clk_info)},
+};
+
+static struct camera_vreg_t csid_8960_vreg_info[] = {
+	{"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
+};
+
+static struct camera_vreg_t csid_8974_vreg_info[] = {
+	{"mipi_csi_vdd", REG_LDO, 1800000, 1800000, 12000},
+};
+
+static int msm_csid_init(struct csid_device *csid_dev, uint32_t *csid_version)
+{
+	int rc = 0;
+	uint8_t core_id = 0;
+
+	CDBG("%s:%d called\n", __func__, __LINE__);
+	if (!csid_version) {
+		pr_err("%s:%d csid_version NULL\n", __func__, __LINE__);
+		rc = -EINVAL;
+		return rc;
+	}
+	CDBG("%s:%d called\n", __func__, __LINE__);
+
+	if (csid_dev->csid_state == CSID_POWER_UP) {
+		pr_err("%s: csid invalid state %d\n", __func__,
+			csid_dev->csid_state);
+		rc = -EINVAL;
+		return rc;
+	}
+	CDBG("%s:%d called\n", __func__, __LINE__);
+
+	csid_dev->base = ioremap(csid_dev->mem->start,
+		resource_size(csid_dev->mem));
+	if (!csid_dev->base) {
+		pr_err("%s csid_dev->base NULL\n", __func__);
+		rc = -ENOMEM;
+		return rc;
+	}
+	CDBG("%s:%d called\n", __func__, __LINE__);
+
+	if (CSID_VERSION <= CSID_VERSION_V2) {
+		CDBG("%s:%d called\n", __func__, __LINE__);
+		rc = msm_camera_config_vreg(&csid_dev->pdev->dev,
+			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 1);
+		if (rc < 0) {
+			pr_err("%s: regulator on failed\n", __func__);
+			goto vreg_config_failed;
+		}
+		CDBG("%s:%d called\n", __func__, __LINE__);
+
+		rc = msm_camera_enable_vreg(&csid_dev->pdev->dev,
+			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 1);
+		if (rc < 0) {
+			pr_err("%s: regulator enable failed\n", __func__);
+			goto vreg_enable_failed;
+		}
+		CDBG("%s:%d called\n", __func__, __LINE__);
+
+		rc = msm_cam_clk_enable(&csid_dev->pdev->dev,
+			csid_8960_clk_info, csid_dev->csid_clk,
+			ARRAY_SIZE(csid_8960_clk_info), 1);
+		if (rc < 0) {
+			pr_err("%s: clock enable failed\n", __func__);
+			goto clk_enable_failed;
+		}
+		CDBG("%s:%d called\n", __func__, __LINE__);
+	} else if (CSID_VERSION >= CSID_VERSION_V3) {
+		CDBG("%s:%d called\n", __func__, __LINE__);
+		rc = msm_camera_config_vreg(&csid_dev->pdev->dev,
+			csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 1);
+		if (rc < 0) {
+			pr_err("%s: regulator on failed\n", __func__);
+			goto vreg_config_failed;
+		}
+		CDBG("%s:%d called\n", __func__, __LINE__);
+
+		rc = msm_camera_enable_vreg(&csid_dev->pdev->dev,
+			csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 1);
+		if (rc < 0) {
+			pr_err("%s: regulator enable failed\n", __func__);
+			goto vreg_enable_failed;
+		}
+		CDBG("%s:%d called\n", __func__, __LINE__);
+
+		rc = msm_cam_clk_enable(&csid_dev->pdev->dev,
+			csid_8974_clk_info[0].clk_info, csid_dev->csid0_clk,
+			csid_8974_clk_info[0].num_clk_info, 1);
+		if (rc < 0) {
+			pr_err("%s: clock enable failed\n", __func__);
+			goto csid0_clk_enable_failed;
+		}
+		CDBG("%s:%d called\n", __func__, __LINE__);
+		core_id = csid_dev->pdev->id;
+		if (core_id) {
+			CDBG("%s:%d called\n", __func__, __LINE__);
+			rc = msm_cam_clk_enable(&csid_dev->pdev->dev,
+				csid_8974_clk_info[core_id].clk_info,
+				csid_dev->csid_clk,
+				csid_8974_clk_info[core_id].num_clk_info, 1);
+			if (rc < 0) {
+				pr_err("%s: clock enable failed\n",
+					__func__);
+				goto clk_enable_failed;
+			}
+		}
+	}
+		CDBG("%s:%d called\n", __func__, __LINE__);
+
+	csid_dev->hw_version =
+		msm_camera_io_r(csid_dev->base + CSID_HW_VERSION_ADDR);
+	CDBG("%s:%d called csid_dev->hw_version %x\n", __func__, __LINE__,
+		csid_dev->hw_version);
+	*csid_version = csid_dev->hw_version;
+
+	CDBG("%s:%d called\n", __func__, __LINE__);
+	init_completion(&csid_dev->reset_complete);
+	CDBG("%s:%d called\n", __func__, __LINE__);
+
+	enable_irq(csid_dev->irq->start);
+	CDBG("%s:%d called\n", __func__, __LINE__);
+
+	msm_csid_reset(csid_dev);
+	CDBG("%s:%d called\n", __func__, __LINE__);
+	csid_dev->csid_state = CSID_POWER_UP;
+	irq_count = 0;
+	return rc;
+
+clk_enable_failed:
+	if (CSID_VERSION >= CSID_VERSION_V3) {
+		msm_cam_clk_enable(&csid_dev->pdev->dev,
+			csid_8974_clk_info[0].clk_info, csid_dev->csid0_clk,
+			csid_8974_clk_info[0].num_clk_info, 0);
+	}
+csid0_clk_enable_failed:
+	if (CSID_VERSION <= CSID_VERSION_V2) {
+		msm_camera_enable_vreg(&csid_dev->pdev->dev,
+			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 0);
+	} else if (CSID_VERSION >= CSID_VERSION_V3) {
+		msm_camera_enable_vreg(&csid_dev->pdev->dev,
+			csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 0);
+	}
+vreg_enable_failed:
+	if (CSID_VERSION <= CSID_VERSION_V2) {
+		msm_camera_config_vreg(&csid_dev->pdev->dev,
+			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 0);
+	} else if (CSID_VERSION >= CSID_VERSION_V3) {
+		msm_camera_config_vreg(&csid_dev->pdev->dev,
+			csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 0);
+	}
+vreg_config_failed:
+	iounmap(csid_dev->base);
+	csid_dev->base = NULL;
+	return rc;
+}
+
+static int msm_csid_release(struct csid_device *csid_dev)
+{
+	uint32_t irq;
+	uint8_t core_id = 0;
+
+	if (csid_dev->csid_state != CSID_POWER_UP) {
+		pr_err("%s: csid invalid state %d\n", __func__,
+			csid_dev->csid_state);
+		return -EINVAL;
+	}
+
+	irq = msm_camera_io_r(csid_dev->base + CSID_IRQ_STATUS_ADDR);
+	msm_camera_io_w(irq, csid_dev->base + CSID_IRQ_CLEAR_CMD_ADDR);
+	msm_camera_io_w(0, csid_dev->base + CSID_IRQ_MASK_ADDR);
+
+	disable_irq(csid_dev->irq->start);
+
+	if (csid_dev->hw_version <= CSID_VERSION_V2) {
+		msm_cam_clk_enable(&csid_dev->pdev->dev, csid_8960_clk_info,
+			csid_dev->csid_clk, ARRAY_SIZE(csid_8960_clk_info), 0);
+
+		msm_camera_enable_vreg(&csid_dev->pdev->dev,
+			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 0);
+
+		msm_camera_config_vreg(&csid_dev->pdev->dev,
+			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 0);
+	} else if (csid_dev->hw_version >= CSID_VERSION_V3) {
+		core_id = csid_dev->pdev->id;
+		if (core_id)
+			msm_cam_clk_enable(&csid_dev->pdev->dev,
+				csid_8974_clk_info[core_id].clk_info,
+				csid_dev->csid_clk,
+				csid_8974_clk_info[core_id].num_clk_info, 0);
+
+		msm_cam_clk_enable(&csid_dev->pdev->dev,
+			csid_8974_clk_info[0].clk_info, csid_dev->csid0_clk,
+			csid_8974_clk_info[0].num_clk_info, 0);
+
+		msm_camera_enable_vreg(&csid_dev->pdev->dev,
+			csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 0);
+
+		msm_camera_config_vreg(&csid_dev->pdev->dev,
+			csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
+			NULL, 0, &csid_dev->csi_vdd, 0);
+	}
+
+	iounmap(csid_dev->base);
+	csid_dev->base = NULL;
+	csid_dev->csid_state = CSID_POWER_DOWN;
+	return 0;
+}
+
+static long msm_csid_cmd(struct csid_device *csid_dev, void *arg)
+{
+	int rc = 0;
+	struct csid_cfg_data *cdata = (struct csid_cfg_data *)arg;
+
+	if (!csid_dev || !cdata) {
+		pr_err("%s:%d csid_dev %p, cdata %p\n", __func__, __LINE__,
+			csid_dev, cdata);
+		return -EINVAL;
+	}
+	CDBG("%s cfgtype = %d\n", __func__, cdata->cfgtype);
+	switch (cdata->cfgtype) {
+	case CSID_INIT:
+		rc = msm_csid_init(csid_dev, &cdata->cfg.csid_version);
+		CDBG("%s csid version %x\n", __func__,
+			cdata->cfg.csid_version);
+		break;
+	case CSID_CFG: {
+		struct msm_camera_csid_params csid_params;
+		struct msm_camera_csid_vc_cfg *vc_cfg = NULL;
+		int32_t i = 0;
+		if (copy_from_user(&csid_params,
+			(void *)cdata->cfg.csid_params,
+			sizeof(struct msm_camera_csid_params))) {
+			pr_err("%s: %d failed\n", __func__, __LINE__);
+			rc = -EFAULT;
+			break;
+		}
+		for (i = 0; i < csid_params.lut_params.num_cid; i++) {
+			vc_cfg = kzalloc(csid_params.lut_params.num_cid *
+				sizeof(struct msm_camera_csid_vc_cfg),
+				GFP_KERNEL);
+			if (!vc_cfg) {
+				pr_err("%s: %d failed\n", __func__, __LINE__);
+				for (i--; i >= 0; i--)
+					kfree(csid_params.lut_params.vc_cfg[i]);
+				rc = -ENOMEM;
+				break;
+			}
+			if (copy_from_user(vc_cfg,
+				(void *)csid_params.lut_params.vc_cfg[i],
+				(csid_params.lut_params.num_cid *
+				sizeof(struct msm_camera_csid_vc_cfg)))) {
+				pr_err("%s: %d failed\n", __func__, __LINE__);
+				kfree(vc_cfg);
+				for (i--; i >= 0; i--)
+					kfree(csid_params.lut_params.vc_cfg[i]);
+				rc = -EFAULT;
+				break;
+			}
+			csid_params.lut_params.vc_cfg[i] = vc_cfg;
+		}
+		rc = msm_csid_config(csid_dev, &csid_params);
+		for (i--; i >= 0; i--)
+			kfree(csid_params.lut_params.vc_cfg[i]);
+		break;
+	}
+	case CSID_RELEASE:
+		rc = msm_csid_release(csid_dev);
+		break;
+	default:
+		pr_err("%s: %d failed\n", __func__, __LINE__);
+		rc = -ENOIOCTLCMD;
+		break;
+	}
+	return rc;
+}
+
+static int32_t msm_csid_get_subdev_id(struct csid_device *csid_dev, void *arg)
+{
+	uint32_t *subdev_id = (uint32_t *)arg;
+	if (!subdev_id) {
+		pr_err("%s:%d failed\n", __func__, __LINE__);
+		return -EINVAL;
+	}
+	*subdev_id = csid_dev->pdev->id;
+	pr_debug("%s:%d subdev_id %d\n", __func__, __LINE__, *subdev_id);
+	return 0;
+}
+
+static long msm_csid_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int cmd, void *arg)
+{
+	int rc = -ENOIOCTLCMD;
+	struct csid_device *csid_dev = v4l2_get_subdevdata(sd);
+	mutex_lock(&csid_dev->mutex);
+	CDBG("%s:%d id %d\n", __func__, __LINE__, csid_dev->pdev->id);
+	switch (cmd) {
+	case VIDIOC_MSM_SENSOR_GET_SUBDEV_ID:
+		rc = msm_csid_get_subdev_id(csid_dev, arg);
+		break;
+	case VIDIOC_MSM_CSID_IO_CFG:
+		rc = msm_csid_cmd(csid_dev, arg);
+		break;
+	case VIDIOC_MSM_CSID_RELEASE:
+		rc = msm_csid_release(csid_dev);
+		break;
+	default:
+		pr_err("%s: command not found\n", __func__);
+	}
+	CDBG("%s:%d\n", __func__, __LINE__);
+	mutex_unlock(&csid_dev->mutex);
+	return rc;
+}
+
+static const struct v4l2_subdev_internal_ops msm_csid_internal_ops;
+
+static struct v4l2_subdev_core_ops msm_csid_subdev_core_ops = {
+	.g_chip_ident = &msm_csid_subdev_g_chip_ident,
+	.ioctl = &msm_csid_subdev_ioctl,
+	.interrupt_service_routine = msm_csid_irq_routine,
+};
+
+static const struct v4l2_subdev_ops msm_csid_subdev_ops = {
+	.core = &msm_csid_subdev_core_ops,
+};
+
+static int __devinit csid_probe(struct platform_device *pdev)
+{
+	struct csid_device *new_csid_dev;
+
+	int rc = 0;
+	CDBG("%s:%d called\n", __func__, __LINE__);
+	new_csid_dev = kzalloc(sizeof(struct csid_device), GFP_KERNEL);
+	if (!new_csid_dev) {
+		pr_err("%s: no enough memory\n", __func__);
+		return -ENOMEM;
+	}
+
+	v4l2_subdev_init(&new_csid_dev->msm_sd.sd, &msm_csid_subdev_ops);
+	v4l2_set_subdevdata(&new_csid_dev->msm_sd.sd, new_csid_dev);
+	platform_set_drvdata(pdev, &new_csid_dev->msm_sd.sd);
+	mutex_init(&new_csid_dev->mutex);
+
+	if (pdev->dev.of_node)
+		of_property_read_u32((&pdev->dev)->of_node,
+			"cell-index", &pdev->id);
+
+	CDBG("%s device id %d\n", __func__, pdev->id);
+	new_csid_dev->mem = platform_get_resource_byname(pdev,
+					IORESOURCE_MEM, "csid");
+	if (!new_csid_dev->mem) {
+		pr_err("%s: no mem resource?\n", __func__);
+		rc = -ENODEV;
+		goto csid_no_resource;
+	}
+	new_csid_dev->irq = platform_get_resource_byname(pdev,
+					IORESOURCE_IRQ, "csid");
+	if (!new_csid_dev->irq) {
+		pr_err("%s: no irq resource?\n", __func__);
+		rc = -ENODEV;
+		goto csid_no_resource;
+	}
+	new_csid_dev->io = request_mem_region(new_csid_dev->mem->start,
+		resource_size(new_csid_dev->mem), pdev->name);
+	if (!new_csid_dev->io) {
+		pr_err("%s: no valid mem region\n", __func__);
+		rc = -EBUSY;
+		goto csid_no_resource;
+	}
+
+	new_csid_dev->pdev = pdev;
+	new_csid_dev->msm_sd.sd.internal_ops = &msm_csid_internal_ops;
+	new_csid_dev->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	snprintf(new_csid_dev->msm_sd.sd.name,
+			ARRAY_SIZE(new_csid_dev->msm_sd.sd.name), "msm_csid");
+	media_entity_init(&new_csid_dev->msm_sd.sd.entity, 0, NULL, 0);
+	new_csid_dev->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	new_csid_dev->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_CSID;
+	msm_sd_register(&new_csid_dev->msm_sd);
+
+	rc = request_irq(new_csid_dev->irq->start, msm_csid_irq,
+		IRQF_TRIGGER_RISING, "csid", new_csid_dev);
+	if (rc < 0) {
+		release_mem_region(new_csid_dev->mem->start,
+			resource_size(new_csid_dev->mem));
+		pr_err("%s: irq request fail\n", __func__);
+		rc = -EBUSY;
+		goto csid_no_resource;
+	}
+	disable_irq(new_csid_dev->irq->start);
+	if (rc < 0) {
+		release_mem_region(new_csid_dev->mem->start,
+			resource_size(new_csid_dev->mem));
+		pr_err("%s Error registering irq ", __func__);
+		goto csid_no_resource;
+	}
+
+	new_csid_dev->csid_state = CSID_POWER_DOWN;
+	return 0;
+
+csid_no_resource:
+	mutex_destroy(&new_csid_dev->mutex);
+	kfree(new_csid_dev);
+	return 0;
+}
+
+static const struct of_device_id msm_csid_dt_match[] = {
+	{.compatible = "qcom,csid"},
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, msm_csid_dt_match);
+
+static struct platform_driver csid_driver = {
+	.probe = csid_probe,
+	.driver = {
+		.name = MSM_CSID_DRV_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = msm_csid_dt_match,
+	},
+};
+
+static int __init msm_csid_init_module(void)
+{
+	return platform_driver_register(&csid_driver);
+}
+
+static void __exit msm_csid_exit_module(void)
+{
+	platform_driver_unregister(&csid_driver);
+}
+
+module_init(msm_csid_init_module);
+module_exit(msm_csid_exit_module);
+MODULE_DESCRIPTION("MSM CSID driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.h b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.h
new file mode 100644
index 0000000..7ae1392
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.h
@@ -0,0 +1,47 @@
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_CSID_H
+#define MSM_CSID_H
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <media/v4l2-subdev.h>
+#include <media/msm_cam_sensor.h>
+#include "msm_sd.h"
+
+enum msm_csid_state_t {
+	CSID_POWER_UP,
+	CSID_POWER_DOWN,
+};
+
+struct csid_device {
+	struct platform_device *pdev;
+	struct msm_sd_subdev msm_sd;
+	struct resource *mem;
+	struct resource *irq;
+	struct resource *io;
+	struct regulator *csi_vdd;
+	void __iomem *base;
+	struct mutex mutex;
+	struct completion reset_complete;
+	uint32_t hw_version;
+	enum msm_csid_state_t csid_state;
+
+	struct clk *csid0_clk[11];
+	struct clk *csid_clk[11];
+};
+
+#define VIDIOC_MSM_CSID_RELEASE \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 5, struct v4l2_subdev*)
+#endif
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csiphy/Makefile b/drivers/media/platform/msm/camera_v2/sensor/csiphy/Makefile
new file mode 100644
index 0000000..eab1f6f
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/csiphy/Makefile
@@ -0,0 +1,8 @@
+ccflags-y += -Idrivers/media/platform/msm/camera_v2
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io
+ifeq ($(CONFIG_MSM_CSI20_HEADER),y)
+  ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/csiphy/include/csi2.0
+else ifeq ($(CONFIG_MSM_CSI30_HEADER),y)
+  ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/csiphy/include/csi3.0
+endif
+obj-$(CONFIG_MSM_CSIPHY) += msm_csiphy.o
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csiphy/include/csi2.0/msm_csiphy_hwreg.h b/drivers/media/platform/msm/camera_v2/sensor/csiphy/include/csi2.0/msm_csiphy_hwreg.h
new file mode 100644
index 0000000..e5093f8
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/csiphy/include/csi2.0/msm_csiphy_hwreg.h
@@ -0,0 +1,43 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_CSIPHY_HWREG_H
+#define MSM_CSIPHY_HWREG_H
+
+/*MIPI CSI PHY registers*/
+#define MIPI_CSIPHY_HW_VERSION_ADDR              0x180
+#define MIPI_CSIPHY_LNn_CFG1_ADDR                0x0
+#define MIPI_CSIPHY_LNn_CFG2_ADDR                0x4
+#define MIPI_CSIPHY_LNn_CFG3_ADDR                0x8
+#define MIPI_CSIPHY_LNn_CFG4_ADDR                0xC
+#define MIPI_CSIPHY_LNn_CFG5_ADDR                0x10
+#define MIPI_CSIPHY_LNCK_CFG1_ADDR               0x100
+#define MIPI_CSIPHY_LNCK_CFG2_ADDR               0x104
+#define MIPI_CSIPHY_LNCK_CFG3_ADDR               0x108
+#define MIPI_CSIPHY_LNCK_CFG4_ADDR               0x10C
+#define MIPI_CSIPHY_LNCK_CFG5_ADDR               0x110
+#define MIPI_CSIPHY_LNCK_MISC1_ADDR              0x128
+#define MIPI_CSIPHY_GLBL_RESET_ADDR              0x140
+#define MIPI_CSIPHY_GLBL_PWR_CFG_ADDR            0x144
+#define MIPI_CSIPHY_GLBL_IRQ_CMD_ADDR            0x164
+#define MIPI_CSIPHY_INTERRUPT_STATUS0_ADDR       0x180
+#define MIPI_CSIPHY_INTERRUPT_MASK0_ADDR         0x1A0
+#define MIPI_CSIPHY_INTERRUPT_MASK_VAL           0x6F
+#define MIPI_CSIPHY_INTERRUPT_MASK_ADDR          0x1A4
+#define MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR        0x1C0
+#define MIPI_CSIPHY_INTERRUPT_CLEAR_ADDR         0x1C4
+#define MIPI_CSIPHY_MODE_CONFIG_SHIFT            0x4
+#define MIPI_CSIPHY_GLBL_T_INIT_CFG0_ADDR        0x1E0
+#define MIPI_CSIPHY_T_WAKEUP_CFG0_ADDR           0x1E8
+#define CSIPHY_VERSION                           0x0
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csiphy/include/csi3.0/msm_csiphy_hwreg.h b/drivers/media/platform/msm/camera_v2/sensor/csiphy/include/csi3.0/msm_csiphy_hwreg.h
new file mode 100644
index 0000000..b90fbc5
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/csiphy/include/csi3.0/msm_csiphy_hwreg.h
@@ -0,0 +1,43 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_CSIPHY_HWREG_H
+#define MSM_CSIPHY_HWREG_H
+
+/*MIPI CSI PHY registers*/
+#define MIPI_CSIPHY_LNn_CFG1_ADDR                0x0
+#define MIPI_CSIPHY_LNn_CFG2_ADDR                0x4
+#define MIPI_CSIPHY_LNn_CFG3_ADDR                0x8
+#define MIPI_CSIPHY_LNn_CFG4_ADDR                0xC
+#define MIPI_CSIPHY_LNn_CFG5_ADDR                0x10
+#define MIPI_CSIPHY_LNCK_CFG1_ADDR               0x100
+#define MIPI_CSIPHY_LNCK_CFG2_ADDR               0x104
+#define MIPI_CSIPHY_LNCK_CFG3_ADDR               0x108
+#define MIPI_CSIPHY_LNCK_CFG4_ADDR               0x10C
+#define MIPI_CSIPHY_LNCK_CFG5_ADDR               0x110
+#define MIPI_CSIPHY_LNCK_MISC1_ADDR              0x128
+#define MIPI_CSIPHY_GLBL_RESET_ADDR              0x140
+#define MIPI_CSIPHY_GLBL_PWR_CFG_ADDR            0x144
+#define MIPI_CSIPHY_GLBL_IRQ_CMD_ADDR            0x164
+#define MIPI_CSIPHY_HW_VERSION_ADDR              0x188
+#define MIPI_CSIPHY_INTERRUPT_STATUS0_ADDR       0x18C
+#define MIPI_CSIPHY_INTERRUPT_MASK0_ADDR         0x1AC
+#define MIPI_CSIPHY_INTERRUPT_MASK_VAL           0x3F
+#define MIPI_CSIPHY_INTERRUPT_MASK_ADDR          0x1AC
+#define MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR        0x1CC
+#define MIPI_CSIPHY_INTERRUPT_CLEAR_ADDR         0x1CC
+#define MIPI_CSIPHY_MODE_CONFIG_SHIFT            0x4
+#define MIPI_CSIPHY_GLBL_T_INIT_CFG0_ADDR        0x1EC
+#define MIPI_CSIPHY_T_WAKEUP_CFG0_ADDR           0x1F4
+#define CSIPHY_VERSION                           0x10
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
new file mode 100644
index 0000000..df3ee60
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
@@ -0,0 +1,639 @@
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/module.h>
+#include <linux/irqreturn.h>
+#include <mach/vreg.h>
+#include "msm_csiphy.h"
+#include "msm_sd.h"
+#include "msm_csiphy_hwreg.h"
+#include "msm_camera_io_util.h"
+#define DBG_CSIPHY 0
+
+#define V4L2_IDENT_CSIPHY                        50003
+#define CSIPHY_VERSION_V3                        0x10
+#define MSM_CSIPHY_DRV_NAME                      "msm_csiphy"
+
+#undef CDBG
+#ifdef CONFIG_MSMB_CAMERA_DEBUG
+#define CDBG(fmt, args...) pr_err(fmt, ##args)
+#else
+#define CDBG(fmt, args...) do { } while (0)
+#endif
+
+static int msm_csiphy_lane_config(struct csiphy_device *csiphy_dev,
+	struct msm_camera_csiphy_params *csiphy_params)
+{
+	int rc = 0;
+	int j = 0;
+	uint32_t val = 0;
+	uint8_t lane_cnt = 0;
+	uint16_t lane_mask = 0;
+	void __iomem *csiphybase;
+	csiphybase = csiphy_dev->base;
+	if (!csiphybase) {
+		pr_err("%s: csiphybase NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	csiphy_dev->lane_mask[csiphy_dev->pdev->id] |= csiphy_params->lane_mask;
+	lane_mask = csiphy_dev->lane_mask[csiphy_dev->pdev->id];
+	lane_cnt = csiphy_params->lane_cnt;
+	if (csiphy_params->lane_cnt < 1 || csiphy_params->lane_cnt > 4) {
+		pr_err("%s: unsupported lane cnt %d\n",
+			__func__, csiphy_params->lane_cnt);
+		return rc;
+	}
+
+	CDBG("%s csiphy_params, mask = %x, cnt = %d, settle cnt = %x\n",
+		__func__,
+		csiphy_params->lane_mask,
+		csiphy_params->lane_cnt,
+		csiphy_params->settle_cnt);
+	msm_camera_io_w(0x1, csiphybase + MIPI_CSIPHY_GLBL_T_INIT_CFG0_ADDR);
+	msm_camera_io_w(0x1, csiphybase + MIPI_CSIPHY_T_WAKEUP_CFG0_ADDR);
+
+	if (csiphy_dev->hw_version < CSIPHY_VERSION_V3) {
+		val = 0x3;
+		msm_camera_io_w((lane_mask << 2) | val,
+				csiphybase + MIPI_CSIPHY_GLBL_PWR_CFG_ADDR);
+		msm_camera_io_w(0x10, csiphybase + MIPI_CSIPHY_LNCK_CFG2_ADDR);
+		msm_camera_io_w(csiphy_params->settle_cnt,
+			 csiphybase + MIPI_CSIPHY_LNCK_CFG3_ADDR);
+		msm_camera_io_w(0x24,
+			csiphybase + MIPI_CSIPHY_INTERRUPT_MASK0_ADDR);
+		msm_camera_io_w(0x24,
+			csiphybase + MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR);
+	} else {
+		val = 0x1;
+		msm_camera_io_w((lane_mask << 1) | val,
+				csiphybase + MIPI_CSIPHY_GLBL_PWR_CFG_ADDR);
+		msm_camera_io_w(csiphy_params->combo_mode <<
+			MIPI_CSIPHY_MODE_CONFIG_SHIFT,
+			csiphybase + MIPI_CSIPHY_GLBL_RESET_ADDR);
+	}
+
+	lane_mask &= 0x1f;
+	while (lane_mask & 0x1f) {
+		if (!(lane_mask & 0x1)) {
+			j++;
+			lane_mask >>= 1;
+			continue;
+		}
+		msm_camera_io_w(0x10,
+			csiphybase + MIPI_CSIPHY_LNn_CFG2_ADDR + 0x40*j);
+		msm_camera_io_w(csiphy_params->settle_cnt,
+			csiphybase + MIPI_CSIPHY_LNn_CFG3_ADDR + 0x40*j);
+		msm_camera_io_w(MIPI_CSIPHY_INTERRUPT_MASK_VAL, csiphybase +
+			MIPI_CSIPHY_INTERRUPT_MASK_ADDR + 0x4*j);
+		msm_camera_io_w(MIPI_CSIPHY_INTERRUPT_MASK_VAL, csiphybase +
+			MIPI_CSIPHY_INTERRUPT_CLEAR_ADDR + 0x4*j);
+		j++;
+		lane_mask >>= 1;
+	}
+	msleep(20);
+	return rc;
+}
+
+static irqreturn_t msm_csiphy_irq(int irq_num, void *data)
+{
+	uint32_t irq;
+	int i;
+	struct csiphy_device *csiphy_dev = data;
+
+	for (i = 0; i < 8; i++) {
+		irq = msm_camera_io_r(
+			csiphy_dev->base +
+			MIPI_CSIPHY_INTERRUPT_STATUS0_ADDR + 0x4*i);
+		msm_camera_io_w(irq,
+			csiphy_dev->base +
+			MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR + 0x4*i);
+		pr_err("%s MIPI_CSIPHY%d_INTERRUPT_STATUS%d = 0x%x\n",
+			 __func__, csiphy_dev->pdev->id, i, irq);
+		msm_camera_io_w(0x1, csiphy_dev->base +
+			MIPI_CSIPHY_GLBL_IRQ_CMD_ADDR);
+		msm_camera_io_w(0x0, csiphy_dev->base +
+			MIPI_CSIPHY_GLBL_IRQ_CMD_ADDR);
+		msm_camera_io_w(0x0,
+			csiphy_dev->base +
+			MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR + 0x4*i);
+	}
+	return IRQ_HANDLED;
+}
+
+static void msm_csiphy_reset(struct csiphy_device *csiphy_dev)
+{
+	msm_camera_io_w(0x1, csiphy_dev->base + MIPI_CSIPHY_GLBL_RESET_ADDR);
+	usleep_range(5000, 8000);
+	msm_camera_io_w(0x0, csiphy_dev->base + MIPI_CSIPHY_GLBL_RESET_ADDR);
+}
+
+static int msm_csiphy_subdev_g_chip_ident(struct v4l2_subdev *sd,
+			struct v4l2_dbg_chip_ident *chip)
+{
+	BUG_ON(!chip);
+	chip->ident = V4L2_IDENT_CSIPHY;
+	chip->revision = 0;
+	return 0;
+}
+
+static struct msm_cam_clk_info csiphy_8960_clk_info[] = {
+	{"csiphy_timer_src_clk", 177780000},
+	{"csiphy_timer_clk", -1},
+};
+
+static struct msm_cam_clk_info csiphy_8974_clk_info[] = {
+	{"camss_top_ahb_clk", -1},
+	{"ispif_ahb_clk", -1},
+	{"csiphy_timer_src_clk", 200000000},
+	{"csiphy_timer_clk", -1},
+};
+
+#if DBG_CSIPHY
+static int msm_csiphy_init(struct csiphy_device *csiphy_dev)
+{
+	int rc = 0;
+	if (csiphy_dev == NULL) {
+		pr_err("%s: csiphy_dev NULL\n", __func__);
+		rc = -ENOMEM;
+		return rc;
+	}
+
+	CDBG("%s:%d called\n", __func__, __LINE__);
+	if (csiphy_dev->csiphy_state == CSIPHY_POWER_UP) {
+		pr_err("%s: csiphy invalid state %d\n", __func__,
+			csiphy_dev->csiphy_state);
+		rc = -EINVAL;
+		return rc;
+	}
+	CDBG("%s:%d called\n", __func__, __LINE__);
+
+	if (csiphy_dev->ref_count++) {
+		CDBG("%s csiphy refcount = %d\n", __func__,
+			csiphy_dev->ref_count);
+		return rc;
+	}
+	CDBG("%s:%d called\n", __func__, __LINE__);
+
+	csiphy_dev->base = ioremap(csiphy_dev->mem->start,
+		resource_size(csiphy_dev->mem));
+	if (!csiphy_dev->base) {
+		pr_err("%s: csiphy_dev->base NULL\n", __func__);
+		csiphy_dev->ref_count--;
+		rc = -ENOMEM;
+		return rc;
+	}
+	CDBG("%s:%d called\n", __func__, __LINE__);
+
+	if (CSIPHY_VERSION < CSIPHY_VERSION_V3) {
+		CDBG("%s:%d called\n", __func__, __LINE__);
+		rc = msm_cam_clk_enable(&csiphy_dev->pdev->dev,
+			csiphy_8960_clk_info, csiphy_dev->csiphy_clk,
+			ARRAY_SIZE(csiphy_8960_clk_info), 1);
+	} else {
+		CDBG("%s:%d called\n", __func__, __LINE__);
+		rc = msm_cam_clk_enable(&csiphy_dev->pdev->dev,
+			csiphy_8974_clk_info, csiphy_dev->csiphy_clk,
+			ARRAY_SIZE(csiphy_8974_clk_info), 1);
+	}
+
+	CDBG("%s:%d called\n", __func__, __LINE__);
+	if (rc < 0) {
+		pr_err("%s: csiphy clk enable failed\n", __func__);
+		csiphy_dev->ref_count--;
+		iounmap(csiphy_dev->base);
+		csiphy_dev->base = NULL;
+		return rc;
+	}
+	CDBG("%s:%d called\n", __func__, __LINE__);
+
+	enable_irq(csiphy_dev->irq->start);
+
+	msm_csiphy_reset(csiphy_dev);
+
+	CDBG("%s:%d called\n", __func__, __LINE__);
+	csiphy_dev->hw_version =
+		msm_camera_io_r(csiphy_dev->base + MIPI_CSIPHY_HW_VERSION_ADDR);
+
+	CDBG("%s:%d called csiphy_dev->hw_version %x\n", __func__, __LINE__,
+		csiphy_dev->hw_version);
+	csiphy_dev->csiphy_state = CSIPHY_POWER_UP;
+	return 0;
+}
+#else
+static int msm_csiphy_init(struct csiphy_device *csiphy_dev)
+{
+	int rc = 0;
+	if (csiphy_dev == NULL) {
+		pr_err("%s: csiphy_dev NULL\n", __func__);
+		rc = -ENOMEM;
+		return rc;
+	}
+
+	CDBG("%s:%d called\n", __func__, __LINE__);
+	if (csiphy_dev->csiphy_state == CSIPHY_POWER_UP) {
+		pr_err("%s: csiphy invalid state %d\n", __func__,
+			csiphy_dev->csiphy_state);
+		rc = -EINVAL;
+		return rc;
+	}
+	CDBG("%s:%d called\n", __func__, __LINE__);
+
+	if (csiphy_dev->ref_count++) {
+		CDBG("%s csiphy refcount = %d\n", __func__,
+			csiphy_dev->ref_count);
+		return rc;
+	}
+	CDBG("%s:%d called\n", __func__, __LINE__);
+
+	csiphy_dev->base = ioremap(csiphy_dev->mem->start,
+		resource_size(csiphy_dev->mem));
+	if (!csiphy_dev->base) {
+		pr_err("%s: csiphy_dev->base NULL\n", __func__);
+		csiphy_dev->ref_count--;
+		rc = -ENOMEM;
+		return rc;
+	}
+	CDBG("%s:%d called\n", __func__, __LINE__);
+
+	if (CSIPHY_VERSION < CSIPHY_VERSION_V3) {
+		CDBG("%s:%d called\n", __func__, __LINE__);
+		rc = msm_cam_clk_enable(&csiphy_dev->pdev->dev,
+			csiphy_8960_clk_info, csiphy_dev->csiphy_clk,
+			ARRAY_SIZE(csiphy_8960_clk_info), 1);
+	} else {
+		CDBG("%s:%d called\n", __func__, __LINE__);
+		rc = msm_cam_clk_enable(&csiphy_dev->pdev->dev,
+			csiphy_8974_clk_info, csiphy_dev->csiphy_clk,
+			ARRAY_SIZE(csiphy_8974_clk_info), 1);
+	}
+
+	CDBG("%s:%d called\n", __func__, __LINE__);
+	if (rc < 0) {
+		pr_err("%s: csiphy clk enable failed\n", __func__);
+		csiphy_dev->ref_count--;
+		iounmap(csiphy_dev->base);
+		csiphy_dev->base = NULL;
+		return rc;
+	}
+	CDBG("%s:%d called\n", __func__, __LINE__);
+
+	msm_csiphy_reset(csiphy_dev);
+
+	CDBG("%s:%d called\n", __func__, __LINE__);
+	csiphy_dev->hw_version =
+		msm_camera_io_r(csiphy_dev->base + MIPI_CSIPHY_HW_VERSION_ADDR);
+
+	CDBG("%s:%d called csiphy_dev->hw_version %x\n", __func__, __LINE__,
+		csiphy_dev->hw_version);
+	csiphy_dev->csiphy_state = CSIPHY_POWER_UP;
+	return 0;
+}
+#endif
+
+#if DBG_CSIPHY
+static int msm_csiphy_release(struct csiphy_device *csiphy_dev, void *arg)
+{
+	int i = 0;
+	struct msm_camera_csi_lane_params *csi_lane_params;
+	uint16_t csi_lane_mask;
+	csi_lane_params = (struct msm_camera_csi_lane_params *)arg;
+	csi_lane_mask = csi_lane_params->csi_lane_mask;
+
+	if (!csiphy_dev || !csiphy_dev->ref_count) {
+		pr_err("%s csiphy dev NULL / ref_count ZERO\n", __func__);
+		return 0;
+	}
+
+	if (csiphy_dev->csiphy_state != CSIPHY_POWER_UP) {
+		pr_err("%s: csiphy invalid state %d\n", __func__,
+			csiphy_dev->csiphy_state);
+		return -EINVAL;
+	}
+
+	CDBG("%s csiphy_params, lane assign %x mask = %x\n",
+		__func__,
+		csi_lane_params->csi_lane_assign,
+		csi_lane_params->csi_lane_mask);
+
+	if (csiphy_dev->hw_version < CSIPHY_VERSION_V3) {
+		csiphy_dev->lane_mask[csiphy_dev->pdev->id] = 0;
+		for (i = 0; i < 4; i++)
+			msm_camera_io_w(0x0, csiphy_dev->base +
+				MIPI_CSIPHY_LNn_CFG2_ADDR + 0x40*i);
+	} else {
+		csiphy_dev->lane_mask[csiphy_dev->pdev->id] &=
+			~(csi_lane_params->csi_lane_mask);
+		i = 0;
+		while (csi_lane_mask & 0x1F) {
+			if (csi_lane_mask & 0x1) {
+				msm_camera_io_w(0x0, csiphy_dev->base +
+					MIPI_CSIPHY_LNn_CFG2_ADDR + 0x40*i);
+			}
+			csi_lane_mask >>= 1;
+			i++;
+		}
+	}
+
+	if (--csiphy_dev->ref_count) {
+		CDBG("%s csiphy refcount = %d\n", __func__,
+			csiphy_dev->ref_count);
+		return 0;
+	}
+
+	msm_camera_io_w(0x0, csiphy_dev->base + MIPI_CSIPHY_LNCK_CFG2_ADDR);
+	msm_camera_io_w(0x0, csiphy_dev->base + MIPI_CSIPHY_GLBL_PWR_CFG_ADDR);
+
+	disable_irq(csiphy_dev->irq->start);
+
+	if (CSIPHY_VERSION < CSIPHY_VERSION_V3)
+		msm_cam_clk_enable(&csiphy_dev->pdev->dev,
+			csiphy_8960_clk_info, csiphy_dev->csiphy_clk,
+			ARRAY_SIZE(csiphy_8960_clk_info), 0);
+	else
+		msm_cam_clk_enable(&csiphy_dev->pdev->dev,
+			csiphy_8974_clk_info, csiphy_dev->csiphy_clk,
+			ARRAY_SIZE(csiphy_8974_clk_info), 0);
+
+	iounmap(csiphy_dev->base);
+	csiphy_dev->base = NULL;
+	csiphy_dev->csiphy_state = CSIPHY_POWER_DOWN;
+	return 0;
+}
+#else
+static int msm_csiphy_release(struct csiphy_device *csiphy_dev, void *arg)
+{
+	int i = 0;
+	struct msm_camera_csi_lane_params *csi_lane_params;
+	uint16_t csi_lane_mask;
+	csi_lane_params = (struct msm_camera_csi_lane_params *)arg;
+	csi_lane_mask = csi_lane_params->csi_lane_mask;
+
+	if (!csiphy_dev || !csiphy_dev->ref_count) {
+		pr_err("%s csiphy dev NULL / ref_count ZERO\n", __func__);
+		return 0;
+	}
+
+	if (csiphy_dev->csiphy_state != CSIPHY_POWER_UP) {
+		pr_err("%s: csiphy invalid state %d\n", __func__,
+			csiphy_dev->csiphy_state);
+		return -EINVAL;
+	}
+
+	CDBG("%s csiphy_params, lane assign %x mask = %x\n",
+		__func__,
+		csi_lane_params->csi_lane_assign,
+		csi_lane_params->csi_lane_mask);
+
+	if (csiphy_dev->hw_version < CSIPHY_VERSION_V3) {
+		csiphy_dev->lane_mask[csiphy_dev->pdev->id] = 0;
+		for (i = 0; i < 4; i++)
+			msm_camera_io_w(0x0, csiphy_dev->base +
+				MIPI_CSIPHY_LNn_CFG2_ADDR + 0x40*i);
+	} else {
+		csiphy_dev->lane_mask[csiphy_dev->pdev->id] &=
+			~(csi_lane_params->csi_lane_mask);
+		i = 0;
+		while (csi_lane_mask & 0x1F) {
+			if (csi_lane_mask & 0x1) {
+				msm_camera_io_w(0x0, csiphy_dev->base +
+					MIPI_CSIPHY_LNn_CFG2_ADDR + 0x40*i);
+			}
+			csi_lane_mask >>= 1;
+			i++;
+		}
+	}
+
+	if (--csiphy_dev->ref_count) {
+		CDBG("%s csiphy refcount = %d\n", __func__,
+			csiphy_dev->ref_count);
+		return 0;
+	}
+
+	msm_camera_io_w(0x0, csiphy_dev->base + MIPI_CSIPHY_LNCK_CFG2_ADDR);
+	msm_camera_io_w(0x0, csiphy_dev->base + MIPI_CSIPHY_GLBL_PWR_CFG_ADDR);
+
+	if (CSIPHY_VERSION < CSIPHY_VERSION_V3)
+		msm_cam_clk_enable(&csiphy_dev->pdev->dev,
+			csiphy_8960_clk_info, csiphy_dev->csiphy_clk,
+			ARRAY_SIZE(csiphy_8960_clk_info), 0);
+	else
+		msm_cam_clk_enable(&csiphy_dev->pdev->dev,
+			csiphy_8974_clk_info, csiphy_dev->csiphy_clk,
+			ARRAY_SIZE(csiphy_8974_clk_info), 0);
+
+	iounmap(csiphy_dev->base);
+	csiphy_dev->base = NULL;
+	csiphy_dev->csiphy_state = CSIPHY_POWER_DOWN;
+	return 0;
+}
+#endif
+
+static long msm_csiphy_cmd(struct csiphy_device *csiphy_dev, void *arg)
+{
+	int rc = 0;
+	struct csiphy_cfg_data *cdata = (struct csiphy_cfg_data *)arg;
+	struct msm_camera_csiphy_params csiphy_params;
+	struct msm_camera_csi_lane_params csi_lane_params;
+	if (!csiphy_dev || !cdata) {
+		pr_err("%s: csiphy_dev NULL\n", __func__);
+		return -EINVAL;
+	}
+	switch (cdata->cfgtype) {
+	case CSIPHY_INIT:
+		rc = msm_csiphy_init(csiphy_dev);
+		break;
+	case CSIPHY_CFG:
+		if (copy_from_user(&csiphy_params,
+			(void *)cdata->cfg.csiphy_params,
+			sizeof(struct msm_camera_csiphy_params))) {
+			pr_err("%s: %d failed\n", __func__, __LINE__);
+			rc = -EFAULT;
+			break;
+		}
+		rc = msm_csiphy_lane_config(csiphy_dev, &csiphy_params);
+		break;
+	case CSIPHY_RELEASE:
+		if (copy_from_user(&csi_lane_params,
+			(void *)cdata->cfg.csi_lane_params,
+			sizeof(struct msm_camera_csi_lane_params))) {
+			pr_err("%s: %d failed\n", __func__, __LINE__);
+			rc = -EFAULT;
+			break;
+		}
+		rc = msm_csiphy_release(csiphy_dev, &csi_lane_params);
+		break;
+	default:
+		pr_err("%s: %d failed\n", __func__, __LINE__);
+		rc = -ENOIOCTLCMD;
+		break;
+	}
+	return rc;
+}
+
+static int32_t msm_csiphy_get_subdev_id(struct csiphy_device *csiphy_dev,
+	void *arg)
+{
+	uint32_t *subdev_id = (uint32_t *)arg;
+	if (!subdev_id) {
+		pr_err("%s:%d failed\n", __func__, __LINE__);
+		return -EINVAL;
+	}
+	*subdev_id = csiphy_dev->pdev->id;
+	pr_debug("%s:%d subdev_id %d\n", __func__, __LINE__, *subdev_id);
+	return 0;
+}
+
+static long msm_csiphy_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int cmd, void *arg)
+{
+	int rc = -ENOIOCTLCMD;
+	struct csiphy_device *csiphy_dev = v4l2_get_subdevdata(sd);
+	CDBG("%s:%d id %d\n", __func__, __LINE__, csiphy_dev->pdev->id);
+	mutex_lock(&csiphy_dev->mutex);
+	switch (cmd) {
+	case VIDIOC_MSM_SENSOR_GET_SUBDEV_ID:
+		rc = msm_csiphy_get_subdev_id(csiphy_dev, arg);
+		break;
+	case VIDIOC_MSM_CSIPHY_IO_CFG:
+		rc = msm_csiphy_cmd(csiphy_dev, arg);
+		break;
+	case VIDIOC_MSM_CSIPHY_RELEASE:
+		rc = msm_csiphy_release(csiphy_dev, arg);
+		break;
+	default:
+		pr_err("%s: command not found\n", __func__);
+	}
+	mutex_unlock(&csiphy_dev->mutex);
+	CDBG("%s:%d\n", __func__, __LINE__);
+	return rc;
+}
+
+static const struct v4l2_subdev_internal_ops msm_csiphy_internal_ops;
+
+static struct v4l2_subdev_core_ops msm_csiphy_subdev_core_ops = {
+	.g_chip_ident = &msm_csiphy_subdev_g_chip_ident,
+	.ioctl = &msm_csiphy_subdev_ioctl,
+};
+
+static const struct v4l2_subdev_ops msm_csiphy_subdev_ops = {
+	.core = &msm_csiphy_subdev_core_ops,
+};
+
+static int __devinit csiphy_probe(struct platform_device *pdev)
+{
+	struct csiphy_device *new_csiphy_dev;
+	int rc = 0;
+
+	new_csiphy_dev = kzalloc(sizeof(struct csiphy_device), GFP_KERNEL);
+	if (!new_csiphy_dev) {
+		pr_err("%s: no enough memory\n", __func__);
+		return -ENOMEM;
+	}
+
+	v4l2_subdev_init(&new_csiphy_dev->msm_sd.sd, &msm_csiphy_subdev_ops);
+	v4l2_set_subdevdata(&new_csiphy_dev->msm_sd.sd, new_csiphy_dev);
+	platform_set_drvdata(pdev, &new_csiphy_dev->msm_sd.sd);
+
+	mutex_init(&new_csiphy_dev->mutex);
+
+	if (pdev->dev.of_node)
+		of_property_read_u32((&pdev->dev)->of_node,
+			"cell-index", &pdev->id);
+	CDBG("%s: device id = %d\n", __func__, pdev->id);
+
+	new_csiphy_dev->mem = platform_get_resource_byname(pdev,
+					IORESOURCE_MEM, "csiphy");
+	if (!new_csiphy_dev->mem) {
+		pr_err("%s: no mem resource?\n", __func__);
+		rc = -ENODEV;
+		goto csiphy_no_resource;
+	}
+	new_csiphy_dev->irq = platform_get_resource_byname(pdev,
+					IORESOURCE_IRQ, "csiphy");
+	if (!new_csiphy_dev->irq) {
+		pr_err("%s: no irq resource?\n", __func__);
+		rc = -ENODEV;
+		goto csiphy_no_resource;
+	}
+	new_csiphy_dev->io = request_mem_region(new_csiphy_dev->mem->start,
+		resource_size(new_csiphy_dev->mem), pdev->name);
+	if (!new_csiphy_dev->io) {
+		pr_err("%s: no valid mem region\n", __func__);
+		rc = -EBUSY;
+		goto csiphy_no_resource;
+	}
+
+	rc = request_irq(new_csiphy_dev->irq->start, msm_csiphy_irq,
+		IRQF_TRIGGER_RISING, "csiphy", new_csiphy_dev);
+	if (rc < 0) {
+		release_mem_region(new_csiphy_dev->mem->start,
+			resource_size(new_csiphy_dev->mem));
+		pr_err("%s: irq request fail\n", __func__);
+		rc = -EBUSY;
+		goto csiphy_no_resource;
+	}
+	disable_irq(new_csiphy_dev->irq->start);
+
+	new_csiphy_dev->pdev = pdev;
+	new_csiphy_dev->msm_sd.sd.internal_ops = &msm_csiphy_internal_ops;
+	new_csiphy_dev->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	snprintf(new_csiphy_dev->msm_sd.sd.name,
+		ARRAY_SIZE(new_csiphy_dev->msm_sd.sd.name), "msm_csiphy");
+	media_entity_init(&new_csiphy_dev->msm_sd.sd.entity, 0, NULL, 0);
+	new_csiphy_dev->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	new_csiphy_dev->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_CSIPHY;
+
+	msm_sd_register(&new_csiphy_dev->msm_sd);
+	new_csiphy_dev->csiphy_state = CSIPHY_POWER_DOWN;
+	return 0;
+
+csiphy_no_resource:
+	mutex_destroy(&new_csiphy_dev->mutex);
+	kfree(new_csiphy_dev);
+	return 0;
+}
+
+static const struct of_device_id msm_csiphy_dt_match[] = {
+	{.compatible = "qcom,csiphy"},
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, msm_csiphy_dt_match);
+
+static struct platform_driver csiphy_driver = {
+	.probe = csiphy_probe,
+	.driver = {
+		.name = MSM_CSIPHY_DRV_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = msm_csiphy_dt_match,
+	},
+};
+
+static int __init msm_csiphy_init_module(void)
+{
+	return platform_driver_register(&csiphy_driver);
+}
+
+static void __exit msm_csiphy_exit_module(void)
+{
+	platform_driver_unregister(&csiphy_driver);
+}
+
+module_init(msm_csiphy_init_module);
+module_exit(msm_csiphy_exit_module);
+MODULE_DESCRIPTION("MSM CSIPHY driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.h b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.h
new file mode 100644
index 0000000..e19be34
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.h
@@ -0,0 +1,49 @@
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_CSIPHY_H
+#define MSM_CSIPHY_H
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <media/v4l2-subdev.h>
+#include <media/msm_cam_sensor.h>
+#include "msm_sd.h"
+
+#define MAX_CSIPHY 3
+
+enum msm_csiphy_state_t {
+	CSIPHY_POWER_UP,
+	CSIPHY_POWER_DOWN,
+};
+
+struct csiphy_device {
+	struct platform_device *pdev;
+	struct msm_sd_subdev msm_sd;
+	struct v4l2_subdev subdev;
+	struct resource *mem;
+	struct resource *irq;
+	struct resource *io;
+	void __iomem *base;
+	struct mutex mutex;
+	uint32_t hw_version;
+	enum msm_csiphy_state_t csiphy_state;
+
+	struct clk *csiphy_clk[4];
+	uint8_t ref_count;
+	uint16_t lane_mask[MAX_CSIPHY];
+};
+
+#define VIDIOC_MSM_CSIPHY_RELEASE \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 9, void *)
+#endif
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/Makefile b/drivers/media/platform/msm/camera_v2/sensor/flash/Makefile
new file mode 100644
index 0000000..4ce7372
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/Makefile
@@ -0,0 +1,4 @@
+ccflags-y += -Idrivers/media/platform/msm/camera_v2
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io
+obj-$(CONFIG_MSMB_CAMERA) += msm_led_flash.o
+obj-$(CONFIG_MSMB_CAMERA) += msm_led_trigger.o
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.c b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.c
new file mode 100644
index 0000000..9119a13
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.c
@@ -0,0 +1,88 @@
+/* Copyright (c) 2009-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) "%s:%d " fmt, __func__, __LINE__
+
+#include "msm_led_flash.h"
+
+/*#define CONFIG_MSMB_CAMERA_DEBUG*/
+#undef CDBG
+#ifdef CONFIG_MSMB_CAMERA_DEBUG
+#define CDBG(fmt, args...) pr_err(fmt, ##args)
+#else
+#define CDBG(fmt, args...) do { } while (0)
+#endif
+
+static long msm_led_flash_subdev_ioctl(struct v4l2_subdev *sd,
+	unsigned int cmd, void *arg)
+{
+	struct msm_led_flash_ctrl_t *fctrl = NULL;
+	void __user *argp = (void __user *)arg;
+	if (!sd) {
+		pr_err("sd NULL\n");
+		return -EINVAL;
+	}
+	fctrl = v4l2_get_subdevdata(sd);
+	if (!fctrl) {
+		pr_err("fctrl NULL\n");
+		return -EINVAL;
+	}
+	switch (cmd) {
+	case VIDIOC_MSM_SENSOR_GET_SUBDEV_ID:
+		return fctrl->func_tbl->flash_get_subdev_id(fctrl, argp);
+	case VIDIOC_MSM_FLASH_LED_DATA_CFG:
+		return fctrl->func_tbl->flash_led_config(fctrl, argp);
+	default:
+		pr_err("invalid cmd %d\n", cmd);
+		return -ENOIOCTLCMD;
+	}
+}
+
+static struct v4l2_subdev_core_ops msm_flash_subdev_core_ops = {
+	.ioctl = msm_led_flash_subdev_ioctl,
+};
+
+static struct v4l2_subdev_ops msm_flash_subdev_ops = {
+	.core = &msm_flash_subdev_core_ops,
+};
+
+static const struct v4l2_subdev_internal_ops msm_flash_internal_ops;
+
+int32_t msm_led_flash_create_v4lsubdev(struct platform_device *pdev, void *data)
+{
+	struct msm_led_flash_ctrl_t *fctrl =
+		(struct msm_led_flash_ctrl_t *)data;
+	CDBG("Enter\n");
+
+	if (!fctrl) {
+		pr_err("fctrl NULL\n");
+		return -EINVAL;
+	}
+
+	/* Initialize sub device */
+	v4l2_subdev_init(&fctrl->msm_sd.sd, &msm_flash_subdev_ops);
+	v4l2_set_subdevdata(&fctrl->msm_sd.sd, fctrl);
+
+	fctrl->pdev = pdev;
+	fctrl->msm_sd.sd.internal_ops = &msm_flash_internal_ops;
+	fctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	snprintf(fctrl->msm_sd.sd.name, ARRAY_SIZE(fctrl->msm_sd.sd.name),
+		"msm_flash");
+	media_entity_init(&fctrl->msm_sd.sd.entity, 0, NULL, 0);
+	fctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	fctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_LED_FLASH;
+	msm_sd_register(&fctrl->msm_sd);
+
+	CDBG("probe success\n");
+	return 0;
+}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h
new file mode 100644
index 0000000..76aa695
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h
@@ -0,0 +1,50 @@
+/* Copyright (c) 2009-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 MSM_LED_FLASH_H
+#define MSM_LED_FLASH_H
+
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+#include <media/v4l2-subdev.h>
+#include <media/msm_cam_sensor.h>
+#include "msm_sd.h"
+
+#define MAX_LED_TRIGGERS 2
+
+struct msm_led_flash_ctrl_t;
+
+struct msm_flash_fn_t {
+	int32_t (*flash_get_subdev_id)(struct msm_led_flash_ctrl_t *, void *);
+	int32_t (*flash_led_config)(struct msm_led_flash_ctrl_t *, void *);
+	int32_t (*flash_led_init)(struct msm_led_flash_ctrl_t *);
+	int32_t (*flash_led_release)(struct msm_led_flash_ctrl_t *);
+	int32_t (*flash_led_off)(struct msm_led_flash_ctrl_t *);
+	int32_t (*flash_led_low)(struct msm_led_flash_ctrl_t *);
+	int32_t (*flash_led_high)(struct msm_led_flash_ctrl_t *);
+};
+
+struct msm_led_flash_ctrl_t {
+	struct msm_camera_i2c_client *flash_i2c_client;
+	struct msm_sd_subdev msm_sd;
+	struct platform_device *pdev;
+	struct msm_flash_fn_t *func_tbl;
+	const char *led_trigger_name[MAX_LED_TRIGGERS];
+	struct led_trigger *led_trigger[MAX_LED_TRIGGERS];
+	uint32_t max_current[MAX_LED_TRIGGERS];
+	void *data;
+};
+
+int32_t msm_led_flash_create_v4lsubdev(struct platform_device *pdev,
+	void *data);
+
+#endif
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
new file mode 100644
index 0000000..1a75a5a
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_trigger.c
@@ -0,0 +1,184 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__
+
+#include <linux/module.h>
+#include "msm_led_flash.h"
+
+#define FLASH_NAME "camera-led-flash"
+
+/*#define CONFIG_MSMB_CAMERA_DEBUG*/
+#undef CDBG
+#ifdef CONFIG_MSMB_CAMERA_DEBUG
+#define CDBG(fmt, args...) pr_err(fmt, ##args)
+#else
+#define CDBG(fmt, args...) do { } while (0)
+#endif
+
+static struct msm_led_flash_ctrl_t fctrl;
+
+static int32_t msm_led_trigger_get_subdev_id(struct msm_led_flash_ctrl_t *fctrl,
+	void *arg)
+{
+	uint32_t *subdev_id = (uint32_t *)arg;
+	if (!subdev_id) {
+		pr_err("%s:%d failed\n", __func__, __LINE__);
+		return -EINVAL;
+	}
+	*subdev_id = fctrl->pdev->id;
+	CDBG("%s:%d subdev_id %d\n", __func__, __LINE__, *subdev_id);
+	return 0;
+}
+
+static int32_t msm_led_trigger_config(struct msm_led_flash_ctrl_t *fctrl,
+	void *data)
+{
+	int rc = 0;
+	struct msm_camera_led_cfg_t *cfg = (struct msm_camera_led_cfg_t *)data;
+	CDBG("called led_state %d\n", cfg->cfgtype);
+
+	if (!fctrl->led_trigger[0]) {
+		pr_err("failed\n");
+		return -EINVAL;
+	}
+	switch (cfg->cfgtype) {
+	case MSM_CAMERA_LED_OFF:
+		led_trigger_event(fctrl->led_trigger[0], 0);
+		break;
+
+	case MSM_CAMERA_LED_LOW:
+		led_trigger_event(fctrl->led_trigger[0],
+			fctrl->max_current[0] / 2);
+		break;
+
+	case MSM_CAMERA_LED_HIGH:
+		led_trigger_event(fctrl->led_trigger[0], fctrl->max_current[0]);
+		break;
+
+	case MSM_CAMERA_LED_INIT:
+	case MSM_CAMERA_LED_RELEASE:
+		led_trigger_event(fctrl->led_trigger[0], 0);
+		break;
+
+	default:
+		rc = -EFAULT;
+		break;
+	}
+	CDBG("flash_set_led_state: return %d\n", rc);
+	return rc;
+}
+
+static const struct of_device_id msm_led_trigger_dt_match[] = {
+	{.compatible = "qcom,camera-led-flash"},
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, msm_led_trigger_dt_match);
+
+static struct platform_driver msm_led_trigger_driver = {
+	.driver = {
+		.name = FLASH_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = msm_led_trigger_dt_match,
+	},
+};
+
+static int32_t msm_led_trigger_probe(struct platform_device *pdev)
+{
+	int32_t rc = 0, i = 0;
+	struct device_node *of_node = pdev->dev.of_node;
+	struct device_node *flash_src_node = NULL;
+	uint32_t count = 0;
+
+	CDBG("called\n");
+
+	if (!of_node) {
+		pr_err("of_node NULL\n");
+		return -EINVAL;
+	}
+
+	fctrl.pdev = pdev;
+
+	rc = of_property_read_u32(of_node, "cell-index", &pdev->id);
+	if (rc < 0) {
+		pr_err("failed\n");
+		return -EINVAL;
+	}
+	CDBG("pdev id %d\n", pdev->id);
+
+	if (of_get_property(of_node, "qcom,flash-source", &count)) {
+		count /= sizeof(uint32_t);
+		CDBG("count %d\n", count);
+		if (count > MAX_LED_TRIGGERS) {
+			pr_err("failed\n");
+			return -EINVAL;
+		}
+		for (i = 0; i < count; i++) {
+			flash_src_node = of_parse_phandle(of_node,
+				"qcom,flash-source", i);
+			if (!flash_src_node) {
+				pr_err("flash_src_node NULL\n");
+				continue;
+			}
+
+			rc = of_property_read_string(flash_src_node,
+				"linux,default-trigger",
+				&fctrl.led_trigger_name[i]);
+			if (rc < 0) {
+				pr_err("failed\n");
+				of_node_put(flash_src_node);
+				continue;
+			}
+
+			CDBG("default trigger %s\n", fctrl.led_trigger_name[i]);
+
+			rc = of_property_read_u32(flash_src_node,
+				"qcom,max-current", &fctrl.max_current[i]);
+			if (rc < 0) {
+				pr_err("failed rc %d\n", rc);
+				of_node_put(flash_src_node);
+				continue;
+			}
+
+			of_node_put(flash_src_node);
+
+			CDBG("max_current[%d] %d\n", i, fctrl.max_current[i]);
+
+			led_trigger_register_simple(fctrl.led_trigger_name[i],
+				&fctrl.led_trigger[i]);
+		}
+	}
+	rc = msm_led_flash_create_v4lsubdev(pdev, &fctrl);
+	return rc;
+}
+
+static int __init msm_led_trigger_add_driver(void)
+{
+	CDBG("called\n");
+	return platform_driver_probe(&msm_led_trigger_driver,
+		msm_led_trigger_probe);
+}
+
+static struct msm_flash_fn_t msm_led_trigger_func_tbl = {
+	.flash_get_subdev_id = msm_led_trigger_get_subdev_id,
+	.flash_led_config = msm_led_trigger_config,
+};
+
+static struct msm_led_flash_ctrl_t fctrl = {
+	.func_tbl = &msm_led_trigger_func_tbl,
+};
+
+module_init(msm_led_trigger_add_driver);
+MODULE_DESCRIPTION("LED TRIGGER FLASH");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v2/sensor/imx135.c b/drivers/media/platform/msm/camera_v2/sensor/imx135.c
new file mode 100644
index 0000000..c9476ee
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/imx135.c
@@ -0,0 +1,149 @@
+/* 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 "msm_sensor.h"
+#define IMX135_SENSOR_NAME "imx135"
+DEFINE_MSM_MUTEX(imx135_mut);
+
+static struct msm_sensor_ctrl_t imx135_s_ctrl;
+
+static struct msm_sensor_power_setting imx135_power_setting[] = {
+	{
+		.seq_type = SENSOR_VREG,
+		.seq_val = CAM_VDIG,
+		.config_val = 0,
+		.delay = 0,
+	},
+	{
+		.seq_type = SENSOR_VREG,
+		.seq_val = CAM_VANA,
+		.config_val = 0,
+		.delay = 0,
+	},
+	{
+		.seq_type = SENSOR_VREG,
+		.seq_val = CAM_VIO,
+		.config_val = 0,
+		.delay = 0,
+	},
+	{
+		.seq_type = SENSOR_GPIO,
+		.seq_val = SENSOR_GPIO_RESET,
+		.config_val = GPIO_OUT_LOW,
+		.delay = 1,
+	},
+	{
+		.seq_type = SENSOR_GPIO,
+		.seq_val = SENSOR_GPIO_RESET,
+		.config_val = GPIO_OUT_HIGH,
+		.delay = 30,
+	},
+	{
+		.seq_type = SENSOR_CLK,
+		.seq_val = SENSOR_CAM_MCLK,
+		.config_val = 0,
+		.delay = 1,
+	},
+	{
+		.seq_type = SENSOR_I2C_MUX,
+		.seq_val = 0,
+		.config_val = 0,
+		.delay = 0,
+	},
+};
+
+static struct v4l2_subdev_info imx135_subdev_info[] = {
+	{
+		.code = V4L2_MBUS_FMT_SBGGR10_1X10,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.fmt = 1,
+		.order = 0,
+	},
+};
+
+static const struct i2c_device_id imx135_i2c_id[] = {
+	{IMX135_SENSOR_NAME, (kernel_ulong_t)&imx135_s_ctrl},
+	{ }
+};
+
+static struct i2c_driver imx135_i2c_driver = {
+	.id_table = imx135_i2c_id,
+	.probe  = msm_sensor_i2c_probe,
+	.driver = {
+		.name = IMX135_SENSOR_NAME,
+	},
+};
+
+static struct msm_camera_i2c_client imx135_sensor_i2c_client = {
+	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+static const struct of_device_id imx135_dt_match[] = {
+	{.compatible = "qcom,imx135", .data = &imx135_s_ctrl},
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, imx135_dt_match);
+
+static struct platform_driver imx135_platform_driver = {
+	.driver = {
+		.name = "qcom,imx135",
+		.owner = THIS_MODULE,
+		.of_match_table = imx135_dt_match,
+	},
+};
+
+static int32_t imx135_platform_probe(struct platform_device *pdev)
+{
+	int32_t rc = 0;
+	const struct of_device_id *match;
+	match = of_match_device(imx135_dt_match, &pdev->dev);
+	rc = msm_sensor_platform_probe(pdev, match->data);
+	return rc;
+}
+
+static int __init imx135_init_module(void)
+{
+	int32_t rc = 0;
+	pr_info("%s:%d\n", __func__, __LINE__);
+	rc = platform_driver_probe(&imx135_platform_driver,
+		imx135_platform_probe);
+	if (!rc)
+		return rc;
+	pr_err("%s:%d rc %d\n", __func__, __LINE__, rc);
+	return i2c_add_driver(&imx135_i2c_driver);
+}
+
+static void __exit imx135_exit_module(void)
+{
+	pr_info("%s:%d\n", __func__, __LINE__);
+	if (imx135_s_ctrl.pdev) {
+		msm_sensor_free_sensor_data(&imx135_s_ctrl);
+		platform_driver_unregister(&imx135_platform_driver);
+	} else
+		i2c_del_driver(&imx135_i2c_driver);
+	return;
+}
+
+static struct msm_sensor_ctrl_t imx135_s_ctrl = {
+	.sensor_i2c_client = &imx135_sensor_i2c_client,
+	.power_setting_array.power_setting = imx135_power_setting,
+	.power_setting_array.size = ARRAY_SIZE(imx135_power_setting),
+	.msm_sensor_mutex = &imx135_mut,
+	.sensor_v4l2_subdev_info = imx135_subdev_info,
+	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(imx135_subdev_info),
+};
+
+module_init(imx135_init_module);
+module_exit(imx135_exit_module);
+MODULE_DESCRIPTION("imx135");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/Makefile b/drivers/media/platform/msm/camera_v2/sensor/io/Makefile
new file mode 100644
index 0000000..f71b09d
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/Makefile
@@ -0,0 +1,3 @@
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/cci
+obj-$(CONFIG_MSMB_CAMERA)   += msm_camera_io_util.o msm_camera_cci_i2c.o msm_camera_qup_i2c.o msm_camera_i2c_mux.o
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c
new file mode 100644
index 0000000..b07f04f
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c
@@ -0,0 +1,494 @@
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <mach/camera2.h>
+#include "msm_camera_i2c.h"
+#include "msm_cci.h"
+
+#undef CDBG
+#ifdef CONFIG_MSMB_CAMERA_DEBUG
+#define CDBG(fmt, args...) pr_debug(fmt, ##args)
+#define S_I2C_DBG(fmt, args...) pr_debug(fmt, ##args)
+#else
+#define CDBG(fmt, args...) do { } while (0)
+#define S_I2C_DBG(fmt, args...) do { } while (0)
+#endif
+
+#define I2C_COMPARE_MATCH 0
+#define I2C_COMPARE_MISMATCH 1
+#define I2C_POLL_MAX_ITERATION 20
+
+int32_t msm_camera_cci_i2c_read(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t *data,
+	enum msm_camera_i2c_data_type data_type)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[client->addr_type+data_type];
+	struct msm_camera_cci_ctrl cci_ctrl;
+
+	if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
+		&& client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
+		|| (data_type != MSM_CAMERA_I2C_BYTE_DATA
+		&& data_type != MSM_CAMERA_I2C_WORD_DATA))
+		return rc;
+
+	cci_ctrl.cmd = MSM_CCI_I2C_READ;
+	cci_ctrl.cci_info = client->cci_client;
+	cci_ctrl.cfg.cci_i2c_read_cfg.addr = addr;
+	cci_ctrl.cfg.cci_i2c_read_cfg.addr_type = client->addr_type;
+	cci_ctrl.cfg.cci_i2c_read_cfg.data = buf;
+	cci_ctrl.cfg.cci_i2c_read_cfg.num_byte = data_type;
+	rc = v4l2_subdev_call(client->cci_client->cci_subdev,
+			core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl);
+	if (rc < 0) {
+		pr_err("%s: line %d rc = %d\n", __func__, __LINE__, rc);
+		return rc;
+	}
+	rc = cci_ctrl.status;
+	if (data_type == MSM_CAMERA_I2C_BYTE_DATA)
+		*data = buf[0];
+	else
+		*data = buf[0] << 8 | buf[1];
+
+	S_I2C_DBG("%s addr = 0x%x data: 0x%x\n", __func__, addr, *data);
+	return rc;
+}
+
+int32_t msm_camera_cci_i2c_read_seq(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint8_t *data, uint16_t num_byte)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[client->addr_type+num_byte];
+	int i;
+	struct msm_camera_cci_ctrl cci_ctrl;
+
+	if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
+		&& client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
+		|| num_byte == 0)
+		return rc;
+
+	cci_ctrl.cmd = MSM_CCI_I2C_READ;
+	cci_ctrl.cci_info = client->cci_client;
+	cci_ctrl.cfg.cci_i2c_read_cfg.addr = addr;
+	cci_ctrl.cfg.cci_i2c_read_cfg.addr_type = client->addr_type;
+	cci_ctrl.cfg.cci_i2c_read_cfg.data = buf;
+	cci_ctrl.cfg.cci_i2c_read_cfg.num_byte = num_byte;
+	rc = v4l2_subdev_call(client->cci_client->cci_subdev,
+			core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl);
+	CDBG("%s line %d rc = %d\n", __func__, __LINE__, rc);
+	rc = cci_ctrl.status;
+
+	S_I2C_DBG("%s addr = 0x%x", __func__, addr);
+	for (i = 0; i < num_byte; i++) {
+		data[i] = buf[i];
+		S_I2C_DBG("Byte %d: 0x%x\n", i, buf[i]);
+		S_I2C_DBG("Data: 0x%x\n", data[i]);
+	}
+	return rc;
+}
+
+int32_t msm_camera_cci_i2c_write(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t data,
+	enum msm_camera_i2c_data_type data_type)
+{
+	int32_t rc = -EFAULT;
+	struct msm_camera_cci_ctrl cci_ctrl;
+	struct msm_camera_i2c_reg_conf reg_conf_tbl;
+
+	if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
+		&& client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
+		|| (data_type != MSM_CAMERA_I2C_BYTE_DATA
+		&& data_type != MSM_CAMERA_I2C_WORD_DATA))
+		return rc;
+
+	CDBG("%s:%d reg addr = 0x%x data type: %d\n",
+		__func__, __LINE__, addr, data_type);
+	reg_conf_tbl.reg_addr = addr;
+	reg_conf_tbl.reg_data = data;
+	cci_ctrl.cmd = MSM_CCI_I2C_WRITE;
+	cci_ctrl.cci_info = client->cci_client;
+	cci_ctrl.cfg.cci_i2c_write_cfg.reg_conf_tbl = &reg_conf_tbl;
+	cci_ctrl.cfg.cci_i2c_write_cfg.data_type = data_type;
+	cci_ctrl.cfg.cci_i2c_write_cfg.addr_type = client->addr_type;
+	cci_ctrl.cfg.cci_i2c_write_cfg.size = 1;
+	rc = v4l2_subdev_call(client->cci_client->cci_subdev,
+			core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl);
+	if (rc < 0) {
+		pr_err("%s: line %d rc = %d\n", __func__, __LINE__, rc);
+		return rc;
+	}
+	rc = cci_ctrl.status;
+	return rc;
+}
+
+int32_t msm_camera_cci_i2c_write_seq(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint8_t *data, uint16_t num_byte)
+{
+	int32_t rc = -EFAULT;
+	uint8_t i = 0;
+	struct msm_camera_cci_ctrl cci_ctrl;
+	struct msm_camera_i2c_reg_conf reg_conf_tbl[num_byte];
+
+	if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
+		&& client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
+		|| num_byte == 0)
+		return rc;
+
+	S_I2C_DBG("%s reg addr = 0x%x num bytes: %d\n",
+			  __func__, addr, num_byte);
+	memset(reg_conf_tbl, 0,
+		num_byte * sizeof(struct msm_camera_i2c_reg_conf));
+	reg_conf_tbl[0].reg_addr = addr;
+	for (i = 0; i < num_byte; i++)
+		reg_conf_tbl[i].reg_data = data[i];
+	cci_ctrl.cmd = MSM_CCI_I2C_WRITE;
+	cci_ctrl.cci_info = client->cci_client;
+	cci_ctrl.cfg.cci_i2c_write_cfg.reg_conf_tbl = reg_conf_tbl;
+	cci_ctrl.cfg.cci_i2c_write_cfg.data_type = MSM_CAMERA_I2C_BYTE_DATA;
+	cci_ctrl.cfg.cci_i2c_write_cfg.addr_type = client->addr_type;
+	cci_ctrl.cfg.cci_i2c_write_cfg.size = num_byte;
+	rc = v4l2_subdev_call(client->cci_client->cci_subdev,
+			core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl);
+	CDBG("%s line %d rc = %d\n", __func__, __LINE__, rc);
+	rc = cci_ctrl.status;
+	return rc;
+}
+
+int32_t msm_camera_cci_i2c_write_table(
+	struct msm_camera_i2c_client *client,
+	struct msm_camera_i2c_reg_setting *write_setting)
+{
+	int i;
+	int32_t rc = -EFAULT;
+	struct msm_camera_i2c_reg_array *reg_setting;
+	uint16_t client_addr_type;
+
+	if (!client || !write_setting)
+		return rc;
+
+	if ((write_setting->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
+		&& write_setting->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
+		|| (write_setting->data_type != MSM_CAMERA_I2C_BYTE_DATA
+		&& write_setting->data_type != MSM_CAMERA_I2C_WORD_DATA))
+		return rc;
+
+	reg_setting = write_setting->reg_setting;
+	client_addr_type = client->addr_type;
+	client->addr_type = write_setting->addr_type;
+
+	for (i = 0; i < write_setting->size; i++) {
+		rc = msm_camera_cci_i2c_write(client, reg_setting->reg_addr,
+			reg_setting->reg_data, write_setting->data_type);
+		if (rc < 0)
+			return rc;
+		reg_setting++;
+	}
+	if (write_setting->delay > 20)
+		msleep(write_setting->delay);
+	else if (write_setting->delay)
+		usleep_range(write_setting->delay * 1000, (write_setting->delay
+			* 1000) + 1000);
+
+	client->addr_type = client_addr_type;
+	return rc;
+}
+
+int32_t msm_camera_cci_i2c_write_seq_table(
+	struct msm_camera_i2c_client *client,
+	struct msm_camera_i2c_seq_reg_setting *write_setting)
+{
+	int i;
+	int32_t rc = -EFAULT;
+	struct msm_camera_i2c_seq_reg_array *reg_setting;
+	uint16_t client_addr_type;
+
+	if (!client || !write_setting)
+		return rc;
+
+	if ((write_setting->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
+		&& write_setting->addr_type != MSM_CAMERA_I2C_WORD_ADDR)) {
+		pr_err("%s Invalide addr type %d\n", __func__,
+			write_setting->addr_type);
+		return rc;
+	}
+
+	reg_setting = write_setting->reg_setting;
+	client_addr_type = client->addr_type;
+	client->addr_type = write_setting->addr_type;
+
+	for (i = 0; i < write_setting->size; i++) {
+		rc = msm_camera_cci_i2c_write_seq(client, reg_setting->reg_addr,
+			reg_setting->reg_data, reg_setting->reg_data_size);
+		if (rc < 0)
+			return rc;
+		reg_setting++;
+	}
+	if (write_setting->delay > 20)
+		msleep(write_setting->delay);
+	else if (write_setting->delay)
+		usleep_range(write_setting->delay * 1000, (write_setting->delay
+			* 1000) + 1000);
+
+	client->addr_type = client_addr_type;
+	return rc;
+}
+
+int32_t msm_camera_cci_i2c_write_table_w_microdelay(
+	struct msm_camera_i2c_client *client,
+	struct msm_camera_i2c_reg_tbl *reg_tbl, uint16_t size,
+	enum msm_camera_i2c_data_type data_type)
+{
+	int i;
+	int32_t rc = -EFAULT;
+
+	if (!client || !reg_tbl)
+		return rc;
+
+	if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
+		&& client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
+		|| (data_type != MSM_CAMERA_I2C_BYTE_DATA
+		&& data_type != MSM_CAMERA_I2C_WORD_DATA))
+		return rc;
+
+	for (i = 0; i < size; i++) {
+		rc = msm_camera_cci_i2c_write(client, reg_tbl->reg_addr,
+			reg_tbl->reg_data, data_type);
+		if (rc < 0)
+			return rc;
+		if (reg_tbl->delay)
+			usleep_range(reg_tbl->delay, reg_tbl->delay + 1000);
+		reg_tbl++;
+	}
+	return rc;
+}
+
+static int32_t msm_camera_cci_i2c_compare(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t data,
+	enum msm_camera_i2c_data_type data_type)
+{
+	int32_t rc;
+	uint16_t reg_data = 0;
+	int data_len = 0;
+	switch (data_type) {
+	case MSM_CAMERA_I2C_BYTE_DATA:
+	case MSM_CAMERA_I2C_WORD_DATA:
+		data_len = data_type;
+		break;
+	case MSM_CAMERA_I2C_SET_BYTE_MASK:
+	case MSM_CAMERA_I2C_UNSET_BYTE_MASK:
+		data_len = MSM_CAMERA_I2C_BYTE_DATA;
+		break;
+	case MSM_CAMERA_I2C_SET_WORD_MASK:
+	case MSM_CAMERA_I2C_UNSET_WORD_MASK:
+		data_len = MSM_CAMERA_I2C_WORD_DATA;
+		break;
+	default:
+		pr_err("%s: Unsupport data type: %d\n", __func__, data_type);
+		break;
+	}
+
+	rc = msm_camera_cci_i2c_read(client, addr, &reg_data, data_len);
+	if (rc < 0)
+		return rc;
+
+	rc = I2C_COMPARE_MISMATCH;
+	switch (data_type) {
+	case MSM_CAMERA_I2C_BYTE_DATA:
+	case MSM_CAMERA_I2C_WORD_DATA:
+		if (data == reg_data)
+			rc = I2C_COMPARE_MATCH;
+		break;
+	case MSM_CAMERA_I2C_SET_BYTE_MASK:
+	case MSM_CAMERA_I2C_SET_WORD_MASK:
+		if ((reg_data & data) == data)
+			rc = I2C_COMPARE_MATCH;
+		break;
+	case MSM_CAMERA_I2C_UNSET_BYTE_MASK:
+	case MSM_CAMERA_I2C_UNSET_WORD_MASK:
+		if (!(reg_data & data))
+			rc = I2C_COMPARE_MATCH;
+		break;
+	default:
+		pr_err("%s: Unsupport data type: %d\n", __func__, data_type);
+		break;
+	}
+
+	S_I2C_DBG("%s: Register and data match result %d\n", __func__,
+		rc);
+	return rc;
+}
+
+static int32_t msm_camera_cci_i2c_poll(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t data,
+	enum msm_camera_i2c_data_type data_type)
+{
+	int32_t rc;
+	int i;
+	S_I2C_DBG("%s: addr: 0x%x data: 0x%x dt: %d\n",
+		__func__, addr, data, data_type);
+
+	for (i = 0; i < I2C_POLL_MAX_ITERATION; i++) {
+		rc = msm_camera_cci_i2c_compare(client,
+			addr, data, data_type);
+		if (rc == 0 || rc < 0)
+			break;
+		usleep_range(10000, 11000);
+	}
+	return rc;
+}
+
+static int32_t msm_camera_cci_i2c_set_mask(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t mask,
+	enum msm_camera_i2c_data_type data_type, uint16_t set_mask)
+{
+	int32_t rc;
+	uint16_t reg_data;
+
+	rc = msm_camera_cci_i2c_read(client, addr, &reg_data, data_type);
+	if (rc < 0) {
+		S_I2C_DBG("%s read fail\n", __func__);
+		return rc;
+	}
+	S_I2C_DBG("%s addr: 0x%x data: 0x%x setmask: 0x%x\n",
+			__func__, addr, reg_data, mask);
+
+	if (set_mask)
+		reg_data |= mask;
+	else
+		reg_data &= ~mask;
+	S_I2C_DBG("%s write: 0x%x\n", __func__, reg_data);
+
+	rc = msm_camera_cci_i2c_write(client, addr, reg_data, data_type);
+	if (rc < 0)
+		S_I2C_DBG("%s write fail\n", __func__);
+
+	return rc;
+}
+
+static int32_t msm_camera_cci_i2c_set_write_mask_data(
+	struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t data, int16_t mask,
+	enum msm_camera_i2c_data_type data_type)
+{
+	int32_t rc;
+	uint16_t reg_data;
+	CDBG("%s\n", __func__);
+	if (mask == -1)
+		return 0;
+	if (mask == 0) {
+		rc = msm_camera_cci_i2c_write(client, addr, data, data_type);
+	} else {
+		rc = msm_camera_cci_i2c_read(client, addr, &reg_data,
+			data_type);
+		if (rc < 0) {
+			CDBG("%s read fail\n", __func__);
+			return rc;
+		}
+		reg_data &= ~mask;
+		reg_data |= (data & mask);
+		rc = msm_camera_cci_i2c_write(client, addr, reg_data,
+			data_type);
+		if (rc < 0)
+			CDBG("%s write fail\n", __func__);
+	}
+	return rc;
+}
+
+int32_t msm_camera_cci_i2c_write_conf_tbl(
+	struct msm_camera_i2c_client *client,
+	struct msm_camera_i2c_reg_conf *reg_conf_tbl, uint16_t size,
+	enum msm_camera_i2c_data_type data_type)
+{
+	int i;
+	int32_t rc = -EFAULT;
+	for (i = 0; i < size; i++) {
+		enum msm_camera_i2c_data_type dt;
+		if (reg_conf_tbl->cmd_type == MSM_CAMERA_I2C_CMD_POLL) {
+			rc = msm_camera_cci_i2c_poll(client,
+				reg_conf_tbl->reg_addr,
+				reg_conf_tbl->reg_data,
+				reg_conf_tbl->dt);
+		} else {
+			if (reg_conf_tbl->dt == 0)
+				dt = data_type;
+			else
+				dt = reg_conf_tbl->dt;
+			switch (dt) {
+			case MSM_CAMERA_I2C_BYTE_DATA:
+			case MSM_CAMERA_I2C_WORD_DATA:
+				rc = msm_camera_cci_i2c_write(
+					client,
+					reg_conf_tbl->reg_addr,
+					reg_conf_tbl->reg_data, dt);
+				break;
+			case MSM_CAMERA_I2C_SET_BYTE_MASK:
+				rc = msm_camera_cci_i2c_set_mask(client,
+					reg_conf_tbl->reg_addr,
+					reg_conf_tbl->reg_data,
+					MSM_CAMERA_I2C_BYTE_DATA, 1);
+				break;
+			case MSM_CAMERA_I2C_UNSET_BYTE_MASK:
+				rc = msm_camera_cci_i2c_set_mask(client,
+					reg_conf_tbl->reg_addr,
+					reg_conf_tbl->reg_data,
+					MSM_CAMERA_I2C_BYTE_DATA, 0);
+				break;
+			case MSM_CAMERA_I2C_SET_WORD_MASK:
+				rc = msm_camera_cci_i2c_set_mask(client,
+					reg_conf_tbl->reg_addr,
+					reg_conf_tbl->reg_data,
+					MSM_CAMERA_I2C_WORD_DATA, 1);
+				break;
+			case MSM_CAMERA_I2C_UNSET_WORD_MASK:
+				rc = msm_camera_cci_i2c_set_mask(client,
+					reg_conf_tbl->reg_addr,
+					reg_conf_tbl->reg_data,
+					MSM_CAMERA_I2C_WORD_DATA, 0);
+				break;
+			case MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA:
+				rc = msm_camera_cci_i2c_set_write_mask_data(
+					client,
+					reg_conf_tbl->reg_addr,
+					reg_conf_tbl->reg_data,
+					reg_conf_tbl->mask,
+					MSM_CAMERA_I2C_BYTE_DATA);
+				break;
+			default:
+				pr_err("%s: Unsupport data type: %d\n",
+					__func__, dt);
+				break;
+			}
+		}
+		if (rc < 0)
+			break;
+		reg_conf_tbl++;
+	}
+	return rc;
+}
+
+int32_t msm_sensor_cci_i2c_util(struct msm_camera_i2c_client *client,
+	uint16_t cci_cmd)
+{
+	int32_t rc = 0;
+	struct msm_camera_cci_ctrl cci_ctrl;
+
+	CDBG("%s line %d\n", __func__, __LINE__);
+	cci_ctrl.cmd = cci_cmd;
+	cci_ctrl.cci_info = client->cci_client;
+	rc = v4l2_subdev_call(client->cci_client->cci_subdev,
+			core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl);
+	if (rc < 0) {
+		pr_err("%s line %d rc = %d\n", __func__, __LINE__, rc);
+		return rc;
+	}
+	return cci_ctrl.status;
+}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h
new file mode 100644
index 0000000..26f1c4f
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h
@@ -0,0 +1,116 @@
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_CAMERA_CCI_I2C_H
+#define MSM_CAMERA_CCI_I2C_H
+
+#include <linux/delay.h>
+#include <media/v4l2-subdev.h>
+#include <media/msm_cam_sensor.h>
+
+struct msm_camera_i2c_client {
+	struct msm_camera_i2c_fn_t *i2c_func_tbl;
+	struct i2c_client *client;
+	struct msm_camera_cci_client *cci_client;
+	enum msm_camera_i2c_reg_addr_type addr_type;
+};
+
+struct msm_camera_i2c_reg_tbl {
+	uint16_t reg_addr;
+	uint16_t reg_data;
+	uint16_t delay;
+};
+
+struct msm_camera_i2c_fn_t {
+	int (*i2c_read) (struct msm_camera_i2c_client *, uint16_t, uint16_t *,
+		enum msm_camera_i2c_data_type);
+	int32_t (*i2c_read_seq)(struct msm_camera_i2c_client *, uint16_t,
+		uint8_t *, uint16_t);
+	int (*i2c_write) (struct msm_camera_i2c_client *, uint16_t, uint16_t,
+		enum msm_camera_i2c_data_type);
+	int (*i2c_write_seq) (struct msm_camera_i2c_client *, uint16_t ,
+		uint8_t *, uint16_t);
+	int32_t (*i2c_write_table)(struct msm_camera_i2c_client *,
+		struct msm_camera_i2c_reg_setting *);
+	int32_t (*i2c_write_seq_table)(struct msm_camera_i2c_client *,
+		struct msm_camera_i2c_seq_reg_setting *);
+	int32_t (*i2c_write_table_w_microdelay)
+		(struct msm_camera_i2c_client *,
+		struct msm_camera_i2c_reg_tbl *, uint16_t,
+		enum msm_camera_i2c_data_type);
+	int32_t (*i2c_util)(struct msm_camera_i2c_client *, uint16_t);
+	int32_t (*i2c_write_conf_tbl)(struct msm_camera_i2c_client *client,
+		struct msm_camera_i2c_reg_conf *reg_conf_tbl, uint16_t size,
+		enum msm_camera_i2c_data_type data_type);
+};
+
+int32_t msm_camera_cci_i2c_read(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t *data,
+	enum msm_camera_i2c_data_type data_type);
+
+int32_t msm_camera_cci_i2c_read_seq(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint8_t *data, uint16_t num_byte);
+
+int32_t msm_camera_cci_i2c_write(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t data,
+	enum msm_camera_i2c_data_type data_type);
+
+int32_t msm_camera_cci_i2c_write_seq(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint8_t *data, uint16_t num_byte);
+
+int32_t msm_camera_cci_i2c_write_table(
+	struct msm_camera_i2c_client *client,
+	struct msm_camera_i2c_reg_setting *write_setting);
+
+int32_t msm_camera_cci_i2c_write_seq_table(
+	struct msm_camera_i2c_client *client,
+	struct msm_camera_i2c_seq_reg_setting *write_setting);
+
+int32_t msm_camera_cci_i2c_write_table_w_microdelay(
+	struct msm_camera_i2c_client *client,
+	struct msm_camera_i2c_reg_tbl *reg_tbl, uint16_t size,
+	enum msm_camera_i2c_data_type data_type);
+
+int32_t msm_camera_cci_i2c_write_conf_tbl(
+	struct msm_camera_i2c_client *client,
+	struct msm_camera_i2c_reg_conf *reg_conf_tbl, uint16_t size,
+	enum msm_camera_i2c_data_type data_type);
+
+int32_t msm_sensor_cci_i2c_util(struct msm_camera_i2c_client *client,
+	uint16_t cci_cmd);
+
+int32_t msm_camera_qup_i2c_read(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t *data,
+	enum msm_camera_i2c_data_type data_type);
+
+int32_t msm_camera_qup_i2c_read_seq(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint8_t *data, uint16_t num_byte);
+
+int32_t msm_camera_qup_i2c_write(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t data,
+	enum msm_camera_i2c_data_type data_type);
+
+int32_t msm_camera_qup_i2c_write_seq(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint8_t *data, uint16_t num_byte);
+
+int32_t msm_camera_qup_i2c_write_table(struct msm_camera_i2c_client *client,
+	struct msm_camera_i2c_reg_setting *write_setting);
+
+int32_t msm_camera_qup_i2c_write_seq_table(struct msm_camera_i2c_client *client,
+	struct msm_camera_i2c_seq_reg_setting *write_setting);
+
+int32_t msm_camera_qup_i2c_write_table_w_microdelay(
+	struct msm_camera_i2c_client *client,
+	struct msm_camera_i2c_reg_tbl *reg_tbl, uint16_t size,
+	enum msm_camera_i2c_data_type data_type);
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c_mux.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c_mux.c
new file mode 100644
index 0000000..49759e6
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c_mux.c
@@ -0,0 +1,188 @@
+/* Copyright (c) 2011-2013, The Linux Foundatation. 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/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <mach/board.h>
+#include <mach/camera.h>
+#include "msm_camera_i2c_mux.h"
+
+/* TODO move this somewhere else */
+#define MSM_I2C_MUX_DRV_NAME "msm_cam_i2c_mux"
+static int msm_i2c_mux_config(struct i2c_mux_device *mux_device, uint8_t *mode)
+{
+	uint32_t val;
+	val = msm_camera_io_r(mux_device->ctl_base);
+	if (*mode == MODE_DUAL) {
+		msm_camera_io_w(val | 0x3, mux_device->ctl_base);
+	} else if (*mode == MODE_L) {
+		msm_camera_io_w(((val | 0x2) & ~(0x1)), mux_device->ctl_base);
+		val = msm_camera_io_r(mux_device->ctl_base);
+		CDBG("the camio mode config left value is %d\n", val);
+	} else {
+		msm_camera_io_w(((val | 0x1) & ~(0x2)), mux_device->ctl_base);
+		val = msm_camera_io_r(mux_device->ctl_base);
+		CDBG("the camio mode config right value is %d\n", val);
+	}
+	return 0;
+}
+
+static int msm_i2c_mux_init(struct i2c_mux_device *mux_device)
+{
+	int rc = 0, val = 0;
+	if (mux_device->use_count == 0) {
+		mux_device->ctl_base = ioremap(mux_device->ctl_mem->start,
+			resource_size(mux_device->ctl_mem));
+		if (!mux_device->ctl_base) {
+			rc = -ENOMEM;
+			return rc;
+		}
+		mux_device->rw_base = ioremap(mux_device->rw_mem->start,
+			resource_size(mux_device->rw_mem));
+		if (!mux_device->rw_base) {
+			rc = -ENOMEM;
+			iounmap(mux_device->ctl_base);
+			return rc;
+		}
+		val = msm_camera_io_r(mux_device->rw_base);
+		msm_camera_io_w((val | 0x200), mux_device->rw_base);
+	}
+	mux_device->use_count++;
+	return 0;
+};
+
+static int msm_i2c_mux_release(struct i2c_mux_device *mux_device)
+{
+	int val = 0;
+	mux_device->use_count--;
+	if (mux_device->use_count == 0) {
+		val = msm_camera_io_r(mux_device->rw_base);
+		msm_camera_io_w((val & ~0x200), mux_device->rw_base);
+		iounmap(mux_device->rw_base);
+		iounmap(mux_device->ctl_base);
+	}
+	return 0;
+}
+
+static long msm_i2c_mux_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int cmd, void *arg)
+{
+	struct i2c_mux_device *mux_device;
+	int rc = 0;
+	mux_device = v4l2_get_subdevdata(sd);
+	if (mux_device == NULL) {
+		rc = -ENOMEM;
+		return rc;
+	}
+	mutex_lock(&mux_device->mutex);
+	switch (cmd) {
+	case VIDIOC_MSM_I2C_MUX_CFG:
+		rc = msm_i2c_mux_config(mux_device, (uint8_t *) arg);
+		break;
+	case VIDIOC_MSM_I2C_MUX_INIT:
+		rc = msm_i2c_mux_init(mux_device);
+		break;
+	case VIDIOC_MSM_I2C_MUX_RELEASE:
+		rc = msm_i2c_mux_release(mux_device);
+		break;
+	default:
+		rc = -ENOIOCTLCMD;
+	}
+	mutex_unlock(&mux_device->mutex);
+	return rc;
+}
+
+static struct v4l2_subdev_core_ops msm_i2c_mux_subdev_core_ops = {
+	.ioctl = &msm_i2c_mux_subdev_ioctl,
+};
+
+static const struct v4l2_subdev_ops msm_i2c_mux_subdev_ops = {
+	.core = &msm_i2c_mux_subdev_core_ops,
+};
+
+static int __devinit i2c_mux_probe(struct platform_device *pdev)
+{
+	struct i2c_mux_device *mux_device;
+	int rc = 0;
+	CDBG("%s: device id = %d\n", __func__, pdev->id);
+	mux_device = kzalloc(sizeof(struct i2c_mux_device), GFP_KERNEL);
+	if (!mux_device) {
+		pr_err("%s: no enough memory\n", __func__);
+		return -ENOMEM;
+	}
+
+	v4l2_subdev_init(&mux_device->subdev, &msm_i2c_mux_subdev_ops);
+	v4l2_set_subdevdata(&mux_device->subdev, mux_device);
+	platform_set_drvdata(pdev, &mux_device->subdev);
+	mutex_init(&mux_device->mutex);
+
+	mux_device->ctl_mem = platform_get_resource_byname(pdev,
+					IORESOURCE_MEM, "i2c_mux_ctl");
+	if (!mux_device->ctl_mem) {
+		pr_err("%s: no mem resource?\n", __func__);
+		rc = -ENODEV;
+		goto i2c_mux_no_resource;
+	}
+	mux_device->ctl_io = request_mem_region(mux_device->ctl_mem->start,
+		resource_size(mux_device->ctl_mem), pdev->name);
+	if (!mux_device->ctl_io) {
+		pr_err("%s: no valid mem region\n", __func__);
+		rc = -EBUSY;
+		goto i2c_mux_no_resource;
+	}
+	mux_device->rw_mem = platform_get_resource_byname(pdev,
+					IORESOURCE_MEM, "i2c_mux_rw");
+	if (!mux_device->rw_mem) {
+		pr_err("%s: no mem resource?\n", __func__);
+		rc = -ENODEV;
+		goto i2c_mux_no_resource;
+	}
+	mux_device->rw_io = request_mem_region(mux_device->rw_mem->start,
+		resource_size(mux_device->rw_mem), pdev->name);
+	if (!mux_device->rw_io) {
+		pr_err("%s: no valid mem region\n", __func__);
+		rc = -EBUSY;
+		goto i2c_mux_no_resource;
+	}
+	mux_device->pdev = pdev;
+	return 0;
+
+i2c_mux_no_resource:
+	mutex_destroy(&mux_device->mutex);
+	kfree(mux_device);
+	return 0;
+}
+
+static struct platform_driver i2c_mux_driver = {
+	.probe = i2c_mux_probe,
+	.driver = {
+		.name = MSM_I2C_MUX_DRV_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init msm_camera_i2c_mux_init_module(void)
+{
+	return platform_driver_register(&i2c_mux_driver);
+}
+
+static void __exit msm_camera_i2c_mux_exit_module(void)
+{
+	platform_driver_unregister(&i2c_mux_driver);
+}
+
+module_init(msm_camera_i2c_mux_init_module);
+module_exit(msm_camera_i2c_mux_exit_module);
+MODULE_DESCRIPTION("MSM Camera I2C mux driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c_mux.h b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c_mux.h
new file mode 100644
index 0000000..30f908b
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c_mux.h
@@ -0,0 +1,46 @@
+/* Copyright (c) 2011-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.
+ */
+
+#ifndef MSM_I2C_MUX_H
+#define MSM_I2C_MUX_H
+
+#include <linux/io.h>
+#include <media/v4l2-subdev.h>
+
+struct i2c_mux_device {
+	struct platform_device *pdev;
+	struct v4l2_subdev subdev;
+	struct resource *ctl_mem;
+	struct resource *ctl_io;
+	void __iomem *ctl_base;
+	struct resource *rw_mem;
+	struct resource *rw_io;
+	void __iomem *rw_base;
+	struct mutex mutex;
+	unsigned use_count;
+};
+
+struct i2c_mux_cfg_params {
+	struct v4l2_subdev *subdev;
+	void *parms;
+};
+
+#define VIDIOC_MSM_I2C_MUX_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 13, struct i2c_mux_cfg_params)
+
+#define VIDIOC_MSM_I2C_MUX_INIT \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 14, struct v4l2_subdev*)
+
+#define VIDIOC_MSM_I2C_MUX_RELEASE \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 15, struct v4l2_subdev*)
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.c
new file mode 100644
index 0000000..7dbbc03
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.c
@@ -0,0 +1,522 @@
+/* Copyright (c) 2011-2013, The Linux Foundataion. 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/delay.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <mach/camera2.h>
+#include <mach/gpiomux.h>
+#include <mach/msm_bus.h>
+#include "msm_camera_io_util.h"
+
+#define BUFF_SIZE_128 128
+
+#undef CDBG
+#ifdef CONFIG_MSMB_CAMERA_DEBUG
+#define CDBG(fmt, args...) pr_debug(fmt, ##args)
+#else
+#define CDBG(fmt, args...) do { } while (0)
+#endif
+
+void msm_camera_io_w(u32 data, void __iomem *addr)
+{
+	CDBG("%s: %08x %08x\n", __func__, (int) (addr), (data));
+	writel_relaxed((data), (addr));
+}
+
+void msm_camera_io_w_mb(u32 data, void __iomem *addr)
+{
+	CDBG("%s: %08x %08x\n", __func__, (int) (addr), (data));
+	wmb();
+	writel_relaxed((data), (addr));
+	wmb();
+}
+
+u32 msm_camera_io_r(void __iomem *addr)
+{
+	uint32_t data = readl_relaxed(addr);
+	CDBG("%s: %08x %08x\n", __func__, (int) (addr), (data));
+	return data;
+}
+
+u32 msm_camera_io_r_mb(void __iomem *addr)
+{
+	uint32_t data;
+	rmb();
+	data = readl_relaxed(addr);
+	rmb();
+	CDBG("%s: %08x %08x\n", __func__, (int) (addr), (data));
+	return data;
+}
+
+void msm_camera_io_memcpy_toio(void __iomem *dest_addr,
+	void __iomem *src_addr, u32 len)
+{
+	int i;
+	u32 *d = (u32 *) dest_addr;
+	u32 *s = (u32 *) src_addr;
+
+	for (i = 0; i < len; i++)
+		writel_relaxed(*s++, d++);
+}
+
+void msm_camera_io_dump(void __iomem *addr, int size)
+{
+	char line_str[BUFF_SIZE_128], *p_str;
+	int i;
+	u32 *p = (u32 *) addr;
+	u32 data;
+	CDBG("%s: %p %d\n", __func__, addr, size);
+	line_str[0] = '\0';
+	p_str = line_str;
+	for (i = 0; i < size/4; i++) {
+		if (i % 4 == 0) {
+			snprintf(p_str, 12, "%08x: ", (u32) p);
+			p_str += 10;
+		}
+		data = readl_relaxed(p++);
+		snprintf(p_str, 12, "%08x ", data);
+		p_str += 9;
+		if ((i + 1) % 4 == 0) {
+			CDBG("%s\n", line_str);
+			line_str[0] = '\0';
+			p_str = line_str;
+		}
+	}
+	if (line_str[0] != '\0')
+		CDBG("%s\n", line_str);
+}
+
+void msm_camera_io_memcpy(void __iomem *dest_addr,
+	void __iomem *src_addr, u32 len)
+{
+	CDBG("%s: %p %p %d\n", __func__, dest_addr, src_addr, len);
+	msm_camera_io_memcpy_toio(dest_addr, src_addr, len / 4);
+	msm_camera_io_dump(dest_addr, len);
+}
+
+int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info,
+		struct clk **clk_ptr, int num_clk, int enable)
+{
+	int i;
+	int rc = 0;
+	if (enable) {
+		for (i = 0; i < num_clk; i++) {
+			CDBG("%s enable %s\n", __func__,
+				clk_info[i].clk_name);
+			clk_ptr[i] = clk_get(dev, clk_info[i].clk_name);
+			if (IS_ERR(clk_ptr[i])) {
+				pr_err("%s get failed\n", clk_info[i].clk_name);
+				rc = PTR_ERR(clk_ptr[i]);
+				goto cam_clk_get_err;
+			}
+			if (clk_info[i].clk_rate >= 0) {
+				rc = clk_set_rate(clk_ptr[i],
+							clk_info[i].clk_rate);
+				if (rc < 0) {
+					pr_err("%s set failed\n",
+						   clk_info[i].clk_name);
+					goto cam_clk_set_err;
+				}
+			}
+			rc = clk_prepare(clk_ptr[i]);
+			if (rc < 0) {
+				pr_err("%s prepare failed\n",
+					   clk_info[i].clk_name);
+				goto cam_clk_prepare_err;
+			}
+
+			rc = clk_enable(clk_ptr[i]);
+			if (rc < 0) {
+				pr_err("%s enable failed\n",
+					   clk_info[i].clk_name);
+				goto cam_clk_enable_err;
+			}
+			if (clk_info[i].delay > 20) {
+				msleep(clk_info[i].delay);
+			} else if (clk_info[i].delay) {
+				usleep_range(clk_info[i].delay * 1000,
+					(clk_info[i].delay * 1000) + 1000);
+			}
+		}
+	} else {
+		for (i = num_clk - 1; i >= 0; i--) {
+			if (clk_ptr[i] != NULL) {
+				CDBG("%s disable %s\n", __func__,
+					clk_info[i].clk_name);
+				clk_disable(clk_ptr[i]);
+				clk_unprepare(clk_ptr[i]);
+				clk_put(clk_ptr[i]);
+			}
+		}
+	}
+	return rc;
+
+
+cam_clk_enable_err:
+	clk_unprepare(clk_ptr[i]);
+cam_clk_prepare_err:
+cam_clk_set_err:
+	clk_put(clk_ptr[i]);
+cam_clk_get_err:
+	for (i--; i >= 0; i--) {
+		if (clk_ptr[i] != NULL) {
+			clk_disable(clk_ptr[i]);
+			clk_unprepare(clk_ptr[i]);
+			clk_put(clk_ptr[i]);
+		}
+	}
+	return rc;
+}
+
+int msm_camera_config_vreg(struct device *dev, struct camera_vreg_t *cam_vreg,
+		int num_vreg, enum msm_camera_vreg_name_t *vreg_seq,
+		int num_vreg_seq, struct regulator **reg_ptr, int config)
+{
+	int i = 0, j = 0;
+	int rc = 0;
+	struct camera_vreg_t *curr_vreg;
+
+	if (num_vreg_seq > num_vreg) {
+		pr_err("%s:%d vreg sequence invalid\n", __func__, __LINE__);
+		return -EINVAL;
+	}
+	if (!num_vreg_seq)
+		num_vreg_seq = num_vreg;
+
+	if (config) {
+		for (i = 0; i < num_vreg_seq; i++) {
+			if (vreg_seq) {
+				j = vreg_seq[i];
+				if (j >= num_vreg)
+					continue;
+			} else
+				j = i;
+			curr_vreg = &cam_vreg[j];
+			reg_ptr[j] = regulator_get(dev,
+				curr_vreg->reg_name);
+			if (IS_ERR(reg_ptr[j])) {
+				pr_err("%s: %s get failed\n",
+					 __func__,
+					 curr_vreg->reg_name);
+				reg_ptr[j] = NULL;
+				goto vreg_get_fail;
+			}
+			if (curr_vreg->type == REG_LDO) {
+				rc = regulator_set_voltage(
+					reg_ptr[j],
+					curr_vreg->min_voltage,
+					curr_vreg->max_voltage);
+				if (rc < 0) {
+					pr_err("%s: %s set voltage failed\n",
+						__func__,
+						curr_vreg->reg_name);
+					goto vreg_set_voltage_fail;
+				}
+				if (curr_vreg->op_mode >= 0) {
+					rc = regulator_set_optimum_mode(
+						reg_ptr[j],
+						curr_vreg->op_mode);
+					if (rc < 0) {
+						pr_err(
+						"%s:%s set optimum mode fail\n",
+						__func__,
+						curr_vreg->reg_name);
+						goto vreg_set_opt_mode_fail;
+					}
+				}
+			}
+		}
+	} else {
+		for (i = num_vreg_seq-1; i >= 0; i--) {
+			if (vreg_seq) {
+				j = vreg_seq[i];
+				if (j >= num_vreg)
+					continue;
+			} else
+				j = i;
+			curr_vreg = &cam_vreg[j];
+			if (reg_ptr[j]) {
+				if (curr_vreg->type == REG_LDO) {
+					if (curr_vreg->op_mode >= 0) {
+						regulator_set_optimum_mode(
+							reg_ptr[j], 0);
+					}
+					regulator_set_voltage(
+						reg_ptr[j], 0, curr_vreg->
+						max_voltage);
+				}
+				regulator_put(reg_ptr[j]);
+				reg_ptr[j] = NULL;
+			}
+		}
+	}
+	return 0;
+
+vreg_unconfig:
+if (curr_vreg->type == REG_LDO)
+	regulator_set_optimum_mode(reg_ptr[j], 0);
+
+vreg_set_opt_mode_fail:
+if (curr_vreg->type == REG_LDO)
+	regulator_set_voltage(reg_ptr[j], 0,
+		curr_vreg->max_voltage);
+
+vreg_set_voltage_fail:
+	regulator_put(reg_ptr[j]);
+	reg_ptr[j] = NULL;
+
+vreg_get_fail:
+	for (i--; i >= 0; i--) {
+		if (vreg_seq) {
+			j = vreg_seq[i];
+			if (j >= num_vreg)
+				continue;
+		} else
+			j = i;
+		curr_vreg = &cam_vreg[j];
+		goto vreg_unconfig;
+	}
+	return -ENODEV;
+}
+
+int msm_camera_enable_vreg(struct device *dev, struct camera_vreg_t *cam_vreg,
+		int num_vreg, enum msm_camera_vreg_name_t *vreg_seq,
+		int num_vreg_seq, struct regulator **reg_ptr, int enable)
+{
+	int i = 0, j = 0, rc = 0;
+
+	if (num_vreg_seq > num_vreg) {
+		pr_err("%s:%d vreg sequence invalid\n", __func__, __LINE__);
+		return -EINVAL;
+	}
+	if (!num_vreg_seq)
+		num_vreg_seq = num_vreg;
+
+	if (enable) {
+		for (i = 0; i < num_vreg_seq; i++) {
+			if (vreg_seq) {
+				j = vreg_seq[i];
+				if (j >= num_vreg)
+					continue;
+			} else
+				j = i;
+			if (IS_ERR(reg_ptr[j])) {
+				pr_err("%s: %s null regulator\n",
+					__func__, cam_vreg[j].reg_name);
+				goto disable_vreg;
+			}
+			rc = regulator_enable(reg_ptr[j]);
+			if (rc < 0) {
+				pr_err("%s: %s enable failed\n",
+					__func__, cam_vreg[j].reg_name);
+				goto disable_vreg;
+			}
+			if (cam_vreg[j].delay > 20)
+				msleep(cam_vreg[j].delay);
+			else if (cam_vreg[j].delay)
+				usleep_range(cam_vreg[j].delay * 1000,
+					(cam_vreg[j].delay * 1000) + 1000);
+		}
+	} else {
+		for (i = num_vreg_seq-1; i >= 0; i--) {
+			if (vreg_seq) {
+				j = vreg_seq[i];
+				if (j >= num_vreg)
+					continue;
+			} else
+				j = i;
+			regulator_disable(reg_ptr[j]);
+			if (cam_vreg[j].delay > 20)
+				msleep(cam_vreg[j].delay);
+			else if (cam_vreg[j].delay)
+				usleep_range(cam_vreg[j].delay * 1000,
+					(cam_vreg[j].delay * 1000) + 1000);
+		}
+	}
+	return rc;
+disable_vreg:
+	for (i--; i >= 0; i--) {
+		if (vreg_seq) {
+			j = vreg_seq[i];
+			if (j >= num_vreg)
+				continue;
+		} else
+			j = i;
+		regulator_disable(reg_ptr[j]);
+		if (cam_vreg[j].delay > 20)
+			msleep(cam_vreg[j].delay);
+		else if (cam_vreg[j].delay)
+			usleep_range(cam_vreg[j].delay * 1000,
+				(cam_vreg[j].delay * 1000) + 1000);
+	}
+	return rc;
+}
+
+void msm_camera_bus_scale_cfg(uint32_t bus_perf_client,
+		enum msm_bus_perf_setting perf_setting)
+{
+	int rc = 0;
+	if (!bus_perf_client) {
+		pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
+		return;
+	}
+
+	switch (perf_setting) {
+	case S_EXIT:
+		rc = msm_bus_scale_client_update_request(bus_perf_client, 1);
+		msm_bus_scale_unregister_client(bus_perf_client);
+		break;
+	case S_PREVIEW:
+		rc = msm_bus_scale_client_update_request(bus_perf_client, 1);
+		break;
+	case S_VIDEO:
+		rc = msm_bus_scale_client_update_request(bus_perf_client, 2);
+		break;
+	case S_CAPTURE:
+		rc = msm_bus_scale_client_update_request(bus_perf_client, 3);
+		break;
+	case S_ZSL:
+		rc = msm_bus_scale_client_update_request(bus_perf_client, 4);
+		break;
+	case S_LIVESHOT:
+		rc = msm_bus_scale_client_update_request(bus_perf_client, 5);
+		break;
+	case S_DEFAULT:
+		break;
+	default:
+		pr_warning("%s: INVALID CASE\n", __func__);
+	}
+}
+
+int msm_camera_set_gpio_table(struct msm_gpio_set_tbl *gpio_tbl,
+	uint8_t gpio_tbl_size, int gpio_en)
+{
+	int rc = 0, i;
+
+	if (gpio_en) {
+		for (i = 0; i < gpio_tbl_size; i++) {
+			gpio_set_value_cansleep(gpio_tbl[i].gpio,
+				gpio_tbl[i].flags);
+			usleep_range(gpio_tbl[i].delay,
+				gpio_tbl[i].delay + 1000);
+		}
+	} else {
+		for (i = gpio_tbl_size - 1; i >= 0; i--) {
+			if (gpio_tbl[i].flags)
+				gpio_set_value_cansleep(gpio_tbl[i].gpio,
+					GPIOF_OUT_INIT_LOW);
+		}
+	}
+	return rc;
+}
+
+int msm_camera_config_single_vreg(struct device *dev,
+	struct camera_vreg_t *cam_vreg, struct regulator **reg_ptr, int config)
+{
+	int rc = 0;
+	if (config) {
+		CDBG("%s enable %s\n", __func__, cam_vreg->reg_name);
+		*reg_ptr = regulator_get(dev, cam_vreg->reg_name);
+		if (IS_ERR(*reg_ptr)) {
+			pr_err("%s: %s get failed\n", __func__,
+				cam_vreg->reg_name);
+			*reg_ptr = NULL;
+			goto vreg_get_fail;
+		}
+		if (cam_vreg->type == REG_LDO) {
+			rc = regulator_set_voltage(
+				*reg_ptr, cam_vreg->min_voltage,
+				cam_vreg->max_voltage);
+			if (rc < 0) {
+				pr_err("%s: %s set voltage failed\n",
+					__func__, cam_vreg->reg_name);
+				goto vreg_set_voltage_fail;
+			}
+			if (cam_vreg->op_mode >= 0) {
+				rc = regulator_set_optimum_mode(*reg_ptr,
+					cam_vreg->op_mode);
+				if (rc < 0) {
+					pr_err(
+					"%s: %s set optimum mode failed\n",
+					__func__, cam_vreg->reg_name);
+					goto vreg_set_opt_mode_fail;
+				}
+			}
+		}
+		rc = regulator_enable(*reg_ptr);
+		if (rc < 0) {
+			pr_err("%s: %s enable failed\n",
+				__func__, cam_vreg->reg_name);
+			goto vreg_unconfig;
+		}
+	} else {
+		if (*reg_ptr) {
+			CDBG("%s disable %s\n", __func__, cam_vreg->reg_name);
+			regulator_disable(*reg_ptr);
+			if (cam_vreg->type == REG_LDO) {
+				if (cam_vreg->op_mode >= 0)
+					regulator_set_optimum_mode(*reg_ptr, 0);
+				regulator_set_voltage(
+					*reg_ptr, 0, cam_vreg->max_voltage);
+			}
+			regulator_put(*reg_ptr);
+			*reg_ptr = NULL;
+		}
+	}
+	return 0;
+
+vreg_unconfig:
+if (cam_vreg->type == REG_LDO)
+	regulator_set_optimum_mode(*reg_ptr, 0);
+
+vreg_set_opt_mode_fail:
+if (cam_vreg->type == REG_LDO)
+	regulator_set_voltage(*reg_ptr, 0, cam_vreg->max_voltage);
+
+vreg_set_voltage_fail:
+	regulator_put(*reg_ptr);
+	*reg_ptr = NULL;
+
+vreg_get_fail:
+	return -ENODEV;
+}
+
+int msm_camera_request_gpio_table(struct gpio *gpio_tbl, uint8_t size,
+	int gpio_en)
+{
+	int rc = 0, i = 0;
+
+	if (!gpio_tbl || !size) {
+		pr_err("%s:%d invalid gpio_tbl %p / size %d\n", __func__,
+			__LINE__, gpio_tbl, size);
+		return -EINVAL;
+	}
+	for (i = 0; i < size; i++) {
+		CDBG("%s:%d i %d, gpio %d dir %ld\n", __func__, __LINE__, i,
+			gpio_tbl[i].gpio, gpio_tbl[i].flags);
+	}
+	if (gpio_en) {
+		rc = gpio_request_array(gpio_tbl, size);
+		if (rc < 0) {
+			pr_err("%s:%d camera gpio request failed\n", __func__,
+				__LINE__);
+			return rc;
+		}
+	} else {
+		gpio_free_array(gpio_tbl, size);
+	}
+	return rc;
+}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.h b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.h
new file mode 100644
index 0000000..499a045
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.h
@@ -0,0 +1,54 @@
+/* Copyright (c) 2011-2013, The Linux Foundataion. 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 __MSM_CAMERA_IO_UTIL_H
+#define __MSM_CAMERA_IO_UTIL_H
+
+#include <linux/regulator/consumer.h>
+#include <linux/gpio.h>
+#include <mach/camera2.h>
+#include <media/msm_cam_sensor.h>
+
+void msm_camera_io_w(u32 data, void __iomem *addr);
+void msm_camera_io_w_mb(u32 data, void __iomem *addr);
+u32 msm_camera_io_r(void __iomem *addr);
+u32 msm_camera_io_r_mb(void __iomem *addr);
+void msm_camera_io_dump(void __iomem *addr, int size);
+void msm_camera_io_memcpy(void __iomem *dest_addr,
+		void __iomem *src_addr, u32 len);
+
+int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info,
+		struct clk **clk_ptr, int num_clk, int enable);
+
+int msm_camera_config_vreg(struct device *dev, struct camera_vreg_t *cam_vreg,
+		int num_vreg, enum msm_camera_vreg_name_t *vreg_seq,
+		int num_vreg_seq, struct regulator **reg_ptr, int config);
+int msm_camera_enable_vreg(struct device *dev, struct camera_vreg_t *cam_vreg,
+		int num_vreg, enum msm_camera_vreg_name_t *vreg_seq,
+		int num_vreg_seq, struct regulator **reg_ptr, int enable);
+
+void msm_camera_bus_scale_cfg(uint32_t bus_perf_client,
+		enum msm_bus_perf_setting perf_setting);
+
+int msm_camera_set_gpio_table(struct msm_gpio_set_tbl *gpio_tbl,
+	uint8_t gpio_tbl_size, int gpio_en);
+
+void msm_camera_config_single_gpio(uint16_t gpio, unsigned long flags,
+	int gpio_en);
+
+int msm_camera_config_single_vreg(struct device *dev,
+	struct camera_vreg_t *cam_vreg, struct regulator **reg_ptr, int config);
+
+int msm_camera_request_gpio_table(struct gpio *gpio_tbl, uint8_t size,
+	int gpio_en);
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c
new file mode 100644
index 0000000..55f27e0
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c
@@ -0,0 +1,332 @@
+/* Copyright (c) 2011, 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <mach/camera2.h>
+#include "msm_camera_i2c.h"
+
+#undef CDBG
+#ifdef CONFIG_MSMB_CAMERA_DEBUG
+#define CDBG(fmt, args...) pr_debug(fmt, ##args)
+#define S_I2C_DBG(fmt, args...) pr_debug(fmt, ##args)
+#else
+#define CDBG(fmt, args...) do { } while (0)
+#define S_I2C_DBG(fmt, args...) do { } while (0)
+#endif
+
+static int32_t msm_camera_qup_i2c_rxdata(
+	struct msm_camera_i2c_client *dev_client, unsigned char *rxdata,
+	int data_length)
+{
+	int32_t rc = 0;
+	uint16_t saddr = dev_client->client->addr >> 1;
+	struct i2c_msg msgs[] = {
+		{
+			.addr  = saddr,
+			.flags = 0,
+			.len   = dev_client->addr_type,
+			.buf   = rxdata,
+		},
+		{
+			.addr  = saddr,
+			.flags = I2C_M_RD,
+			.len   = data_length,
+			.buf   = rxdata,
+		},
+	};
+	rc = i2c_transfer(dev_client->client->adapter, msgs, 2);
+	if (rc < 0)
+		S_I2C_DBG("msm_camera_qup_i2c_rxdata failed 0x%x\n", saddr);
+	return rc;
+}
+
+static int32_t msm_camera_qup_i2c_txdata(
+	struct msm_camera_i2c_client *dev_client, unsigned char *txdata,
+	int length)
+{
+	int32_t rc = 0;
+	uint16_t saddr = dev_client->client->addr >> 1;
+	struct i2c_msg msg[] = {
+		{
+			.addr = saddr,
+			.flags = 0,
+			.len = length,
+			.buf = txdata,
+		 },
+	};
+	rc = i2c_transfer(dev_client->client->adapter, msg, 1);
+	if (rc < 0)
+		S_I2C_DBG("msm_camera_qup_i2c_txdata faild 0x%x\n", saddr);
+	return 0;
+}
+
+int32_t msm_camera_qup_i2c_read(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t *data,
+	enum msm_camera_i2c_data_type data_type)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[client->addr_type+data_type];
+
+	if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
+		&& client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
+		|| (data_type != MSM_CAMERA_I2C_BYTE_DATA
+		&& data_type != MSM_CAMERA_I2C_WORD_DATA))
+		return rc;
+
+	if (client->addr_type == MSM_CAMERA_I2C_BYTE_ADDR) {
+		buf[0] = addr;
+	} else if (client->addr_type == MSM_CAMERA_I2C_WORD_ADDR) {
+		buf[0] = addr >> BITS_PER_BYTE;
+		buf[1] = addr;
+	}
+	rc = msm_camera_qup_i2c_rxdata(client, buf, data_type);
+	if (rc < 0) {
+		S_I2C_DBG("%s fail\n", __func__);
+		return rc;
+	}
+
+	if (data_type == MSM_CAMERA_I2C_BYTE_DATA)
+		*data = buf[0];
+	else
+		*data = buf[0] << 8 | buf[1];
+
+	S_I2C_DBG("%s addr = 0x%x data: 0x%x\n", __func__, addr, *data);
+	return rc;
+}
+
+int32_t msm_camera_qup_i2c_read_seq(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint8_t *data, uint16_t num_byte)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[client->addr_type+num_byte];
+	int i;
+
+	if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
+		&& client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
+		|| num_byte == 0)
+		return rc;
+
+	if (client->addr_type == MSM_CAMERA_I2C_BYTE_ADDR) {
+		buf[0] = addr;
+	} else if (client->addr_type == MSM_CAMERA_I2C_WORD_ADDR) {
+		buf[0] = addr >> BITS_PER_BYTE;
+		buf[1] = addr;
+	}
+	rc = msm_camera_qup_i2c_rxdata(client, buf, num_byte);
+	if (rc < 0) {
+		S_I2C_DBG("%s fail\n", __func__);
+		return rc;
+	}
+
+	S_I2C_DBG("%s addr = 0x%x", __func__, addr);
+	for (i = 0; i < num_byte; i++) {
+		data[i] = buf[i];
+		S_I2C_DBG("Byte %d: 0x%x\n", i, buf[i]);
+		S_I2C_DBG("Data: 0x%x\n", data[i]);
+	}
+	return rc;
+}
+
+int32_t msm_camera_qup_i2c_write(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t data,
+	enum msm_camera_i2c_data_type data_type)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[client->addr_type+data_type];
+	uint8_t len = 0;
+
+	if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
+		&& client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
+		|| (data_type != MSM_CAMERA_I2C_BYTE_DATA
+		&& data_type != MSM_CAMERA_I2C_WORD_DATA))
+		return rc;
+
+	S_I2C_DBG("%s reg addr = 0x%x data type: %d\n",
+			  __func__, addr, data_type);
+	if (client->addr_type == MSM_CAMERA_I2C_BYTE_ADDR) {
+		buf[0] = addr;
+		S_I2C_DBG("%s byte %d: 0x%x\n", __func__,
+			len, buf[len]);
+		len = 1;
+	} else if (client->addr_type == MSM_CAMERA_I2C_WORD_ADDR) {
+		buf[0] = addr >> BITS_PER_BYTE;
+		buf[1] = addr;
+		S_I2C_DBG("%s byte %d: 0x%x\n", __func__,
+			len, buf[len]);
+		S_I2C_DBG("%s byte %d: 0x%x\n", __func__,
+			len+1, buf[len+1]);
+		len = 2;
+	}
+	S_I2C_DBG("Data: 0x%x\n", data);
+	if (data_type == MSM_CAMERA_I2C_BYTE_DATA) {
+		buf[len] = data;
+		S_I2C_DBG("Byte %d: 0x%x\n", len, buf[len]);
+		len += 1;
+	} else if (data_type == MSM_CAMERA_I2C_WORD_DATA) {
+		buf[len] = data >> BITS_PER_BYTE;
+		buf[len+1] = data;
+		S_I2C_DBG("Byte %d: 0x%x\n", len, buf[len]);
+		S_I2C_DBG("Byte %d: 0x%x\n", len+1, buf[len+1]);
+		len += 2;
+	}
+	rc = msm_camera_qup_i2c_txdata(client, buf, len);
+	if (rc < 0)
+		S_I2C_DBG("%s fail\n", __func__);
+	return rc;
+}
+
+int32_t msm_camera_qup_i2c_write_seq(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint8_t *data, uint16_t num_byte)
+{
+	int32_t rc = -EFAULT;
+	unsigned char buf[client->addr_type+num_byte];
+	uint8_t len = 0, i = 0;
+
+	if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
+		&& client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
+		|| num_byte == 0)
+		return rc;
+
+	S_I2C_DBG("%s reg addr = 0x%x num bytes: %d\n",
+			  __func__, addr, num_byte);
+	if (client->addr_type == MSM_CAMERA_I2C_BYTE_ADDR) {
+		buf[0] = addr;
+		S_I2C_DBG("%s byte %d: 0x%x\n", __func__,
+			len, buf[len]);
+		len = 1;
+	} else if (client->addr_type == MSM_CAMERA_I2C_WORD_ADDR) {
+		buf[0] = addr >> BITS_PER_BYTE;
+		buf[1] = addr;
+		S_I2C_DBG("%s byte %d: 0x%x\n", __func__,
+			len, buf[len]);
+		S_I2C_DBG("%s byte %d: 0x%x\n", __func__,
+			len+1, buf[len+1]);
+		len = 2;
+	}
+	for (i = 0; i < num_byte; i++) {
+		buf[i+len] = data[i];
+		S_I2C_DBG("Byte %d: 0x%x\n", i+len, buf[i+len]);
+		S_I2C_DBG("Data: 0x%x\n", data[i]);
+	}
+	rc = msm_camera_qup_i2c_txdata(client, buf, len+num_byte);
+	if (rc < 0)
+		S_I2C_DBG("%s fail\n", __func__);
+	return rc;
+}
+
+int32_t msm_camera_qup_i2c_write_table(struct msm_camera_i2c_client *client,
+	struct msm_camera_i2c_reg_setting *write_setting)
+{
+	int i;
+	int32_t rc = -EFAULT;
+	struct msm_camera_i2c_reg_array *reg_setting;
+	uint16_t client_addr_type;
+
+	if (!client || !write_setting)
+		return rc;
+
+	if ((write_setting->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
+		&& write_setting->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
+		|| (write_setting->data_type != MSM_CAMERA_I2C_BYTE_DATA
+		&& write_setting->data_type != MSM_CAMERA_I2C_WORD_DATA))
+		return rc;
+
+	reg_setting = write_setting->reg_setting;
+	client_addr_type = client->addr_type;
+	client->addr_type = write_setting->addr_type;
+
+	for (i = 0; i < write_setting->size; i++) {
+		CDBG("%s addr %x data %x\n", __func__,
+			reg_setting->reg_addr, reg_setting->reg_data);
+
+		rc = msm_camera_qup_i2c_write(client, reg_setting->reg_addr,
+			reg_setting->reg_data, write_setting->data_type);
+		if (rc < 0)
+			break;
+		reg_setting++;
+	}
+	if (write_setting->delay > 20)
+		msleep(write_setting->delay);
+	else if (write_setting->delay)
+		usleep_range(write_setting->delay * 1000, (write_setting->delay
+			* 1000) + 1000);
+
+	client->addr_type = client_addr_type;
+	return rc;
+}
+
+int32_t msm_camera_qup_i2c_write_seq_table(struct msm_camera_i2c_client *client,
+	struct msm_camera_i2c_seq_reg_setting *write_setting)
+{
+	int i;
+	int32_t rc = -EFAULT;
+	struct msm_camera_i2c_seq_reg_array *reg_setting;
+	uint16_t client_addr_type;
+
+	if (!client || !write_setting)
+		return rc;
+
+	if ((write_setting->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
+		&& write_setting->addr_type != MSM_CAMERA_I2C_WORD_ADDR)) {
+		pr_err("%s Invalide addr type %d\n", __func__,
+			write_setting->addr_type);
+		return rc;
+	}
+
+	reg_setting = write_setting->reg_setting;
+	client_addr_type = client->addr_type;
+	client->addr_type = write_setting->addr_type;
+
+	for (i = 0; i < write_setting->size; i++) {
+		rc = msm_camera_qup_i2c_write_seq(client, reg_setting->reg_addr,
+			reg_setting->reg_data, reg_setting->reg_data_size);
+		if (rc < 0)
+			break;
+		reg_setting++;
+	}
+	if (write_setting->delay > 20)
+		msleep(write_setting->delay);
+	else if (write_setting->delay)
+		usleep_range(write_setting->delay * 1000, (write_setting->delay
+			* 1000) + 1000);
+
+	client->addr_type = client_addr_type;
+	return rc;
+}
+
+int32_t msm_camera_qup_i2c_write_table_w_microdelay(
+	struct msm_camera_i2c_client *client,
+	struct msm_camera_i2c_reg_tbl *reg_tbl, uint16_t size,
+	enum msm_camera_i2c_data_type data_type)
+{
+	int i;
+	int32_t rc = -EFAULT;
+
+	if (!client || !reg_tbl)
+		return rc;
+
+	if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
+		&& client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
+		|| (data_type != MSM_CAMERA_I2C_BYTE_DATA
+		&& data_type != MSM_CAMERA_I2C_WORD_DATA))
+		return rc;
+
+	for (i = 0; i < size; i++) {
+		rc = msm_camera_qup_i2c_write(client, reg_tbl->reg_addr,
+			reg_tbl->reg_data, data_type);
+		if (rc < 0)
+			break;
+		if (reg_tbl->delay)
+			usleep_range(reg_tbl->delay, reg_tbl->delay + 1000);
+		reg_tbl++;
+	}
+	return rc;
+}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c
new file mode 100644
index 0000000..453b14a
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c
@@ -0,0 +1,1571 @@
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <mach/gpiomux.h>
+#include "msm_sensor.h"
+#include "msm_sd.h"
+#include "camera.h"
+#include "msm_cci.h"
+#include "msm_camera_io_util.h"
+#include "msm_camera_i2c_mux.h"
+
+#undef CDBG
+#ifdef CONFIG_MSMB_CAMERA_DEBUG
+#define CDBG(fmt, args...) pr_err(fmt, ##args)
+#else
+#define CDBG(fmt, args...) do { } while (0)
+#endif
+
+static int32_t msm_sensor_enable_i2c_mux(struct msm_camera_i2c_conf *i2c_conf)
+{
+	struct v4l2_subdev *i2c_mux_sd =
+		dev_get_drvdata(&i2c_conf->mux_dev->dev);
+	v4l2_subdev_call(i2c_mux_sd, core, ioctl,
+		VIDIOC_MSM_I2C_MUX_INIT, NULL);
+	v4l2_subdev_call(i2c_mux_sd, core, ioctl,
+		VIDIOC_MSM_I2C_MUX_CFG, (void *)&i2c_conf->i2c_mux_mode);
+	return 0;
+}
+
+static int32_t msm_sensor_disable_i2c_mux(struct msm_camera_i2c_conf *i2c_conf)
+{
+	struct v4l2_subdev *i2c_mux_sd =
+		dev_get_drvdata(&i2c_conf->mux_dev->dev);
+	v4l2_subdev_call(i2c_mux_sd, core, ioctl,
+				VIDIOC_MSM_I2C_MUX_RELEASE, NULL);
+	return 0;
+}
+
+static int32_t msm_sensor_get_sub_module_index(struct device_node *of_node,
+	struct  msm_camera_sensor_board_info *sensordata)
+{
+	int32_t rc = 0, i = 0;
+	uint32_t val = 0, count = 0;
+	uint32_t *val_array = NULL;
+	struct device_node *src_node = NULL;
+
+	sensordata->sensor_info = kzalloc(sizeof(struct msm_sensor_info_t),
+		GFP_KERNEL);
+	if (!sensordata->sensor_info) {
+		pr_err("%s:%d failed\n", __func__, __LINE__);
+		return -ENOMEM;
+	}
+	for (i = 0; i < SUB_MODULE_MAX; i++)
+		sensordata->sensor_info->subdev_id[i] = -1;
+
+	src_node = of_parse_phandle(of_node, "qcom,actuator-src", 0);
+	if (!src_node) {
+		CDBG("%s:%d src_node NULL\n", __func__, __LINE__);
+	} else {
+		rc = of_property_read_u32(src_node, "cell-index", &val);
+		CDBG("%s qcom,actuator cell index %d, rc %d\n", __func__,
+			val, rc);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR;
+		}
+		sensordata->sensor_info->
+			subdev_id[SUB_MODULE_ACTUATOR] = val;
+		of_node_put(src_node);
+		src_node = NULL;
+	}
+
+	if (of_property_read_bool(of_node, "qcom,eeprom-sd-index") ==
+		true) {
+		rc = of_property_read_u32(of_node, "qcom,eeprom-sd-index",
+			&val);
+		CDBG("%s qcom,eeprom-sd-index %d, rc %d\n", __func__, val, rc);
+		if (rc < 0) {
+			pr_err("%s:%d failed rc %d\n", __func__, __LINE__, rc);
+			goto ERROR;
+		}
+		sensordata->sensor_info->subdev_id[SUB_MODULE_EEPROM] = val;
+	}
+
+	src_node = of_parse_phandle(of_node, "qcom,led-flash-src", 0);
+	if (!src_node) {
+		CDBG("%s:%d src_node NULL\n", __func__, __LINE__);
+	} else {
+		rc = of_property_read_u32(src_node, "cell-index", &val);
+		CDBG("%s qcom,led flash cell index %d, rc %d\n", __func__,
+			val, rc);
+		if (rc < 0) {
+			pr_err("%s:%d failed %d\n", __func__, __LINE__, rc);
+			goto ERROR;
+		}
+		sensordata->sensor_info->
+			subdev_id[SUB_MODULE_LED_FLASH] = val;
+		of_node_put(src_node);
+		src_node = NULL;
+	}
+
+	if (of_property_read_bool(of_node, "qcom,strobe-flash-sd-index") ==
+		true) {
+		rc = of_property_read_u32(of_node, "qcom,strobe-flash-sd-index",
+			&val);
+		CDBG("%s qcom,strobe-flash-sd-index %d, rc %d\n", __func__,
+			val, rc);
+		if (rc < 0) {
+			pr_err("%s:%d failed rc %d\n", __func__, __LINE__, rc);
+			goto ERROR;
+		}
+		sensordata->sensor_info->subdev_id[SUB_MODULE_STROBE_FLASH] =
+			val;
+	}
+
+	if (of_get_property(of_node, "qcom,csiphy-sd-index", &count)) {
+		count /= sizeof(uint32_t);
+		if (count > 2) {
+			pr_err("%s qcom,csiphy-sd-index count %d > 2\n",
+				__func__, count);
+			goto ERROR;
+		}
+		val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
+		if (!val_array) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			rc = -ENOMEM;
+			goto ERROR;
+		}
+
+		rc = of_property_read_u32_array(of_node, "qcom,csiphy-sd-index",
+			val_array, count);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			kfree(val_array);
+			goto ERROR;
+		}
+		for (i = 0; i < count; i++) {
+			sensordata->sensor_info->subdev_id
+				[SUB_MODULE_CSIPHY + i] = val_array[i];
+			CDBG("%s csiphy_core[%d] = %d\n",
+				__func__, i, val_array[i]);
+		}
+		kfree(val_array);
+	} else {
+		pr_err("%s:%d qcom,csiphy-sd-index not present\n", __func__,
+			__LINE__);
+		rc = -EINVAL;
+		goto ERROR;
+	}
+
+	if (of_get_property(of_node, "qcom,csid-sd-index", &count)) {
+		count /= sizeof(uint32_t);
+		if (count > 2) {
+			pr_err("%s qcom,csid-sd-index count %d > 2\n",
+				__func__, count);
+			rc = -EINVAL;
+			goto ERROR;
+		}
+		val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
+		if (!val_array) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			rc = -ENOMEM;
+			goto ERROR;
+		}
+
+		rc = of_property_read_u32_array(of_node, "qcom,csid-sd-index",
+			val_array, count);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			kfree(val_array);
+			goto ERROR;
+		}
+		for (i = 0; i < count; i++) {
+			sensordata->sensor_info->subdev_id
+				[SUB_MODULE_CSID + i] = val_array[i];
+			CDBG("%s csid_core[%d] = %d\n",
+				__func__, i, val_array[i]);
+		}
+		kfree(val_array);
+	} else {
+		pr_err("%s:%d qcom,csid-sd-index not present\n", __func__,
+			__LINE__);
+		rc = -EINVAL;
+		goto ERROR;
+	}
+	return rc;
+ERROR:
+	kfree(sensordata->sensor_info);
+	sensordata->sensor_info = NULL;
+	return rc;
+}
+
+static int32_t msm_sensor_get_dt_csi_data(struct device_node *of_node,
+	struct  msm_camera_sensor_board_info *sensordata)
+{
+	int32_t rc = 0;
+	uint32_t val = 0;
+
+	sensordata->csi_lane_params = kzalloc(
+		sizeof(struct msm_camera_csi_lane_params), GFP_KERNEL);
+	if (!sensordata->csi_lane_params) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		goto ERROR1;
+	}
+
+	rc = of_property_read_u32(of_node, "qcom,csi-lane-assign", &val);
+	CDBG("%s qcom,csi-lane-assign %x, rc %d\n", __func__, val, rc);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	sensordata->csi_lane_params->csi_lane_assign = val;
+
+	rc = of_property_read_u32(of_node, "qcom,csi-lane-mask", &val);
+	CDBG("%s qcom,csi-lane-mask %x, rc %d\n", __func__, val, rc);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	sensordata->csi_lane_params->csi_lane_mask = val;
+
+	return rc;
+ERROR2:
+	kfree(sensordata->csi_lane_params);
+ERROR1:
+	return rc;
+}
+
+static int32_t msm_sensor_get_dt_vreg_data(struct device_node *of_node,
+	struct msm_camera_sensor_board_info *sensordata)
+{
+	int32_t rc = 0, i = 0;
+	uint32_t count = 0;
+	uint32_t *vreg_array = NULL;
+
+	count = of_property_count_strings(of_node, "qcom,cam-vreg-name");
+	CDBG("%s qcom,cam-vreg-name count %d\n", __func__, count);
+
+	if (!count)
+		return 0;
+
+	sensordata->cam_vreg = kzalloc(sizeof(struct camera_vreg_t) * count,
+		GFP_KERNEL);
+	if (!sensordata->cam_vreg) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		return -ENOMEM;
+	}
+
+	sensordata->num_vreg = count;
+	for (i = 0; i < count; i++) {
+		rc = of_property_read_string_index(of_node,
+			"qcom,cam-vreg-name", i,
+			&sensordata->cam_vreg[i].reg_name);
+		CDBG("%s reg_name[%d] = %s\n", __func__, i,
+			sensordata->cam_vreg[i].reg_name);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR1;
+		}
+	}
+
+	vreg_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
+	if (!vreg_array) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		goto ERROR1;
+	}
+
+	rc = of_property_read_u32_array(of_node, "qcom,cam-vreg-type",
+		vreg_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		sensordata->cam_vreg[i].type = vreg_array[i];
+		CDBG("%s cam_vreg[%d].type = %d\n", __func__, i,
+			sensordata->cam_vreg[i].type);
+	}
+
+	rc = of_property_read_u32_array(of_node, "qcom,cam-vreg-min-voltage",
+		vreg_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		sensordata->cam_vreg[i].min_voltage = vreg_array[i];
+		CDBG("%s cam_vreg[%d].min_voltage = %d\n", __func__,
+			i, sensordata->cam_vreg[i].min_voltage);
+	}
+
+	rc = of_property_read_u32_array(of_node, "qcom,cam-vreg-max-voltage",
+		vreg_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		sensordata->cam_vreg[i].max_voltage = vreg_array[i];
+		CDBG("%s cam_vreg[%d].max_voltage = %d\n", __func__,
+			i, sensordata->cam_vreg[i].max_voltage);
+	}
+
+	rc = of_property_read_u32_array(of_node, "qcom,cam-vreg-op-mode",
+		vreg_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		sensordata->cam_vreg[i].op_mode = vreg_array[i];
+		CDBG("%s cam_vreg[%d].op_mode = %d\n", __func__, i,
+			sensordata->cam_vreg[i].op_mode);
+	}
+
+	kfree(vreg_array);
+	return rc;
+ERROR2:
+	kfree(vreg_array);
+ERROR1:
+	kfree(sensordata->cam_vreg);
+	sensordata->num_vreg = 0;
+	return rc;
+}
+
+static int32_t msm_sensor_get_dt_gpio_req_tbl(struct device_node *of_node,
+	struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
+	uint16_t gpio_array_size)
+{
+	int32_t rc = 0, i = 0;
+	uint32_t count = 0;
+	uint32_t *val_array = NULL;
+
+	if (!of_get_property(of_node, "qcom,gpio-req-tbl-num", &count))
+		return 0;
+
+	count /= sizeof(uint32_t);
+	if (!count) {
+		pr_err("%s qcom,gpio-req-tbl-num 0\n", __func__);
+		return 0;
+	}
+
+	val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
+	if (!val_array) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		return -ENOMEM;
+	}
+
+	gconf->cam_gpio_req_tbl = kzalloc(sizeof(struct gpio) * count,
+		GFP_KERNEL);
+	if (!gconf->cam_gpio_req_tbl) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		goto ERROR1;
+	}
+	gconf->cam_gpio_req_tbl_size = count;
+
+	rc = of_property_read_u32_array(of_node, "qcom,gpio-req-tbl-num",
+		val_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		if (val_array[i] >= gpio_array_size) {
+			pr_err("%s gpio req tbl index %d invalid\n",
+				__func__, val_array[i]);
+			return -EINVAL;
+		}
+		gconf->cam_gpio_req_tbl[i].gpio = gpio_array[val_array[i]];
+		CDBG("%s cam_gpio_req_tbl[%d].gpio = %d\n", __func__, i,
+			gconf->cam_gpio_req_tbl[i].gpio);
+	}
+
+	rc = of_property_read_u32_array(of_node, "qcom,gpio-req-tbl-flags",
+		val_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		gconf->cam_gpio_req_tbl[i].flags = val_array[i];
+		CDBG("%s cam_gpio_req_tbl[%d].flags = %ld\n", __func__, i,
+			gconf->cam_gpio_req_tbl[i].flags);
+	}
+
+	for (i = 0; i < count; i++) {
+		rc = of_property_read_string_index(of_node,
+			"qcom,gpio-req-tbl-label", i,
+			&gconf->cam_gpio_req_tbl[i].label);
+		CDBG("%s cam_gpio_req_tbl[%d].label = %s\n", __func__, i,
+			gconf->cam_gpio_req_tbl[i].label);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR2;
+		}
+	}
+
+	kfree(val_array);
+	return rc;
+
+ERROR2:
+	kfree(gconf->cam_gpio_req_tbl);
+ERROR1:
+	kfree(val_array);
+	gconf->cam_gpio_req_tbl_size = 0;
+	return rc;
+}
+
+static int32_t msm_sensor_get_dt_gpio_set_tbl(struct device_node *of_node,
+	struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
+	uint16_t gpio_array_size)
+{
+	int32_t rc = 0, i = 0;
+	uint32_t count = 0;
+	uint32_t *val_array = NULL;
+
+	if (!of_get_property(of_node, "qcom,gpio-set-tbl-num", &count))
+		return 0;
+
+	count /= sizeof(uint32_t);
+	if (!count) {
+		pr_err("%s qcom,gpio-set-tbl-num 0\n", __func__);
+		return 0;
+	}
+
+	val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
+	if (!val_array) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		return -ENOMEM;
+	}
+
+	gconf->cam_gpio_set_tbl = kzalloc(sizeof(struct msm_gpio_set_tbl) *
+		count, GFP_KERNEL);
+	if (!gconf->cam_gpio_set_tbl) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		goto ERROR1;
+	}
+	gconf->cam_gpio_set_tbl_size = count;
+
+	rc = of_property_read_u32_array(of_node, "qcom,gpio-set-tbl-num",
+		val_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		if (val_array[i] >= gpio_array_size) {
+			pr_err("%s gpio set tbl index %d invalid\n",
+				__func__, val_array[i]);
+			return -EINVAL;
+		}
+		gconf->cam_gpio_set_tbl[i].gpio = gpio_array[val_array[i]];
+		CDBG("%s cam_gpio_set_tbl[%d].gpio = %d\n", __func__, i,
+			gconf->cam_gpio_set_tbl[i].gpio);
+	}
+
+	rc = of_property_read_u32_array(of_node, "qcom,gpio-set-tbl-flags",
+		val_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		gconf->cam_gpio_set_tbl[i].flags = val_array[i];
+		CDBG("%s cam_gpio_set_tbl[%d].flags = %ld\n", __func__, i,
+			gconf->cam_gpio_set_tbl[i].flags);
+	}
+
+	rc = of_property_read_u32_array(of_node, "qcom,gpio-set-tbl-delay",
+		val_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		gconf->cam_gpio_set_tbl[i].delay = val_array[i];
+		CDBG("%s cam_gpio_set_tbl[%d].delay = %d\n", __func__, i,
+			gconf->cam_gpio_set_tbl[i].delay);
+	}
+
+	kfree(val_array);
+	return rc;
+
+ERROR2:
+	kfree(gconf->cam_gpio_set_tbl);
+ERROR1:
+	kfree(val_array);
+	gconf->cam_gpio_set_tbl_size = 0;
+	return rc;
+}
+
+static int32_t msm_sensor_init_gpio_pin_tbl(struct device_node *of_node,
+	struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
+	uint16_t gpio_array_size)
+{
+	int32_t rc = 0;
+	int32_t val = 0;
+
+	gconf->gpio_num_info = kzalloc(sizeof(struct msm_camera_gpio_num_info),
+		GFP_KERNEL);
+	if (!gconf->gpio_num_info) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		return rc;
+	}
+
+	if (of_property_read_bool(of_node, "qcom,gpio-reset") == true) {
+		rc = of_property_read_u32(of_node, "qcom,gpio-reset", &val);
+		if (rc < 0) {
+			pr_err("%s:%d read qcom,gpio-reset failed rc %d\n",
+				__func__, __LINE__, rc);
+			goto ERROR;
+		} else if (val >= gpio_array_size) {
+			pr_err("%s:%d qcom,gpio-reset invalid %d\n",
+				__func__, __LINE__, val);
+			goto ERROR;
+		}
+		gconf->gpio_num_info->gpio_num[SENSOR_GPIO_RESET] =
+			gpio_array[val];
+		CDBG("%s qcom,gpio-reset %d\n", __func__,
+			gconf->gpio_num_info->gpio_num[SENSOR_GPIO_RESET]);
+	}
+
+	if (of_property_read_bool(of_node, "qcom,gpio-standby") == true) {
+		rc = of_property_read_u32(of_node, "qcom,gpio-standby", &val);
+		if (rc < 0) {
+			pr_err("%s:%d read qcom,gpio-standby failed rc %d\n",
+				__func__, __LINE__, rc);
+			goto ERROR;
+		} else if (val >= gpio_array_size) {
+			pr_err("%s:%d qcom,gpio-standby invalid %d\n",
+				__func__, __LINE__, val);
+			goto ERROR;
+		}
+		gconf->gpio_num_info->gpio_num[SENSOR_GPIO_STANDBY] =
+			gpio_array[val];
+		CDBG("%s qcom,gpio-reset %d\n", __func__,
+			gconf->gpio_num_info->gpio_num[SENSOR_GPIO_STANDBY]);
+	}
+	return rc;
+
+ERROR:
+	kfree(gconf->gpio_num_info);
+	gconf->gpio_num_info = NULL;
+	return rc;
+}
+
+static int32_t msm_sensor_get_dt_actuator_data(struct device_node *of_node,
+	struct  msm_camera_sensor_board_info *sensordata)
+{
+	int32_t rc = 0;
+	uint32_t val = 0;
+
+	rc = of_property_read_u32(of_node, "qcom,actuator-cam-name", &val);
+	CDBG("%s qcom,actuator-cam-name %d, rc %d\n", __func__, val, rc);
+	if (rc < 0)
+		return 0;
+
+	sensordata->actuator_info = kzalloc(sizeof(struct msm_actuator_info),
+		GFP_KERNEL);
+	if (!sensordata->actuator_info) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		goto ERROR;
+	}
+
+	sensordata->actuator_info->cam_name = val;
+
+	rc = of_property_read_u32(of_node, "qcom,actuator-vcm-pwd", &val);
+	CDBG("%s qcom,actuator-vcm-pwd %d, rc %d\n", __func__, val, rc);
+	if (!rc)
+		sensordata->actuator_info->vcm_pwd = val;
+
+	rc = of_property_read_u32(of_node, "qcom,actuator-vcm-enable", &val);
+	CDBG("%s qcom,actuator-vcm-enable %d, rc %d\n", __func__, val, rc);
+	if (!rc)
+		sensordata->actuator_info->vcm_enable = val;
+
+	return 0;
+ERROR:
+	return rc;
+}
+
+static int32_t msm_sensor_get_dt_data(struct platform_device *pdev,
+	struct msm_sensor_ctrl_t *s_ctrl)
+{
+	int32_t rc = 0, i = 0;
+	struct device_node *of_node = pdev->dev.of_node;
+	struct msm_camera_gpio_conf *gconf = NULL;
+	struct msm_camera_sensor_board_info *sensordata = NULL;
+	uint16_t *gpio_array = NULL;
+	uint16_t gpio_array_size = 0;
+	uint32_t id_info[3];
+
+	s_ctrl->sensordata = kzalloc(sizeof(
+		struct msm_camera_sensor_board_info),
+		GFP_KERNEL);
+	if (!s_ctrl->sensordata) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		return -ENOMEM;
+	}
+
+	sensordata = s_ctrl->sensordata;
+
+	sensordata->sensor_init_params = kzalloc(sizeof(
+		struct msm_sensor_init_params), GFP_KERNEL);
+	if (!sensordata->sensor_init_params) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		return -ENOMEM;
+	}
+
+	rc = of_property_read_string(of_node, "qcom,sensor-name",
+		&sensordata->sensor_name);
+	CDBG("%s qcom,sensor-name %s, rc %d\n", __func__,
+		sensordata->sensor_name, rc);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR1;
+	}
+
+	rc = of_property_read_u32(of_node, "qcom,sensor-mode",
+		&sensordata->sensor_init_params->modes_supported);
+	CDBG("%s qcom,sensor-mode %d, rc %d\n", __func__,
+		sensordata->sensor_init_params->modes_supported, rc);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR1;
+	}
+
+	rc = of_property_read_u32(of_node, "qcom,sensor-position",
+		&sensordata->sensor_init_params->position);
+	CDBG("%s qcom,sensor-position %d, rc %d\n", __func__,
+		sensordata->sensor_init_params->position, rc);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR1;
+	}
+
+	rc = of_property_read_u32(of_node, "qcom,mount-angle",
+		&sensordata->sensor_init_params->sensor_mount_angle);
+	CDBG("%s qcom,mount-angle %d, rc %d\n", __func__,
+		sensordata->sensor_init_params->sensor_mount_angle, rc);
+	if (rc < 0) {
+		/* Set default mount angle */
+		sensordata->sensor_init_params->sensor_mount_angle = 0;
+		rc = 0;
+	}
+
+	rc = of_property_read_u32(of_node, "qcom,cci-master",
+		&s_ctrl->cci_i2c_master);
+	CDBG("%s qcom,cci-master %d, rc %d\n", __func__, s_ctrl->cci_i2c_master,
+		rc);
+	if (rc < 0) {
+		/* Set default master 0 */
+		s_ctrl->cci_i2c_master = MASTER_0;
+		rc = 0;
+	}
+
+	rc = msm_sensor_get_sub_module_index(of_node, sensordata);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR1;
+	}
+
+	rc = msm_sensor_get_dt_csi_data(of_node, sensordata);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR1;
+	}
+
+	rc = msm_sensor_get_dt_vreg_data(of_node, sensordata);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+
+	sensordata->gpio_conf = kzalloc(sizeof(struct msm_camera_gpio_conf),
+		GFP_KERNEL);
+	if (!sensordata->gpio_conf) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		goto ERROR3;
+	}
+	gconf = sensordata->gpio_conf;
+
+	gpio_array_size = of_gpio_count(of_node);
+	CDBG("%s gpio count %d\n", __func__, gpio_array_size);
+
+	if (gpio_array_size) {
+		gpio_array = kzalloc(sizeof(uint16_t) * gpio_array_size,
+			GFP_KERNEL);
+		if (!gpio_array) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR4;
+		}
+		for (i = 0; i < gpio_array_size; i++) {
+			gpio_array[i] = of_get_gpio(of_node, i);
+			CDBG("%s gpio_array[%d] = %d\n", __func__, i,
+				gpio_array[i]);
+		}
+
+		rc = msm_sensor_get_dt_gpio_req_tbl(of_node, gconf,
+			gpio_array, gpio_array_size);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR4;
+		}
+
+		rc = msm_sensor_get_dt_gpio_set_tbl(of_node, gconf,
+			gpio_array, gpio_array_size);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR5;
+		}
+
+		rc = msm_sensor_init_gpio_pin_tbl(of_node, gconf,
+			gpio_array, gpio_array_size);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR6;
+		}
+	}
+	rc = msm_sensor_get_dt_actuator_data(of_node, sensordata);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR7;
+	}
+
+	sensordata->slave_info = kzalloc(sizeof(struct msm_camera_slave_info),
+		GFP_KERNEL);
+	if (!sensordata->slave_info) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		goto ERROR8;
+	}
+
+	rc = of_property_read_u32_array(of_node, "qcom,slave-id",
+		id_info, 3);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR9;
+	}
+
+	sensordata->slave_info->sensor_slave_addr = id_info[0];
+	sensordata->slave_info->sensor_id_reg_addr = id_info[1];
+	sensordata->slave_info->sensor_id = id_info[2];
+
+	kfree(gpio_array);
+	return rc;
+
+ERROR9:
+	kfree(s_ctrl->sensordata->slave_info);
+ERROR8:
+	kfree(s_ctrl->sensordata->actuator_info);
+ERROR7:
+	kfree(s_ctrl->sensordata->gpio_conf->gpio_num_info);
+ERROR6:
+	kfree(s_ctrl->sensordata->gpio_conf->cam_gpio_set_tbl);
+ERROR5:
+	kfree(s_ctrl->sensordata->gpio_conf->cam_gpio_req_tbl);
+ERROR4:
+	kfree(s_ctrl->sensordata->gpio_conf);
+ERROR3:
+	kfree(s_ctrl->sensordata->cam_vreg);
+ERROR2:
+	kfree(s_ctrl->sensordata->csi_lane_params);
+ERROR1:
+	kfree(s_ctrl->sensordata);
+	kfree(gpio_array);
+	return rc;
+}
+
+int32_t msm_sensor_free_sensor_data(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	if (!s_ctrl->pdev)
+		return 0;
+	kfree(s_ctrl->sensordata->slave_info);
+	kfree(s_ctrl->sensordata->actuator_info);
+	kfree(s_ctrl->sensordata->gpio_conf->gpio_num_info);
+	kfree(s_ctrl->sensordata->gpio_conf->cam_gpio_set_tbl);
+	kfree(s_ctrl->sensordata->gpio_conf->cam_gpio_req_tbl);
+	kfree(s_ctrl->sensordata->gpio_conf);
+	kfree(s_ctrl->sensordata->cam_vreg);
+	kfree(s_ctrl->sensordata->csi_lane_params);
+	kfree(s_ctrl->sensordata->sensor_info);
+	kfree(s_ctrl->sensordata->sensor_init_params);
+	kfree(s_ctrl->sensordata);
+	return 0;
+}
+
+static struct msm_cam_clk_info cam_8960_clk_info[] = {
+	[SENSOR_CAM_MCLK] = {"cam_clk", 24000000},
+};
+
+static struct msm_cam_clk_info cam_8974_clk_info[] = {
+	[SENSOR_CAM_MCLK] = {"cam_src_clk", 19200000},
+	[SENSOR_CAM_CLK] = {"cam_clk", 0},
+};
+
+int32_t msm_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	int32_t rc = 0, index = 0;
+	struct msm_sensor_power_setting_array *power_setting_array = NULL;
+	struct msm_sensor_power_setting *power_setting = NULL;
+	struct msm_camera_sensor_board_info *data = s_ctrl->sensordata;
+
+	CDBG("%s:%d\n", __func__, __LINE__);
+	power_setting_array = &s_ctrl->power_setting_array;
+
+	if (data->gpio_conf->cam_gpiomux_conf_tbl != NULL) {
+		pr_err("%s:%d mux install\n", __func__, __LINE__);
+		msm_gpiomux_install(
+			(struct msm_gpiomux_config *)
+			data->gpio_conf->cam_gpiomux_conf_tbl,
+			data->gpio_conf->cam_gpiomux_conf_tbl_size);
+	}
+
+	rc = msm_camera_request_gpio_table(
+		data->gpio_conf->cam_gpio_req_tbl,
+		data->gpio_conf->cam_gpio_req_tbl_size, 1);
+	if (rc < 0) {
+		pr_err("%s: request gpio failed\n", __func__);
+		return rc;
+	}
+	for (index = 0; index < power_setting_array->size; index++) {
+		CDBG("%s index %d\n", __func__, index);
+		power_setting = &power_setting_array->power_setting[index];
+		CDBG("%s type %d\n", __func__, power_setting->seq_type);
+		switch (power_setting->seq_type) {
+		case SENSOR_CLK:
+			if (power_setting->seq_val >= s_ctrl->clk_info_size) {
+				pr_err("%s clk index %d >= max %d\n", __func__,
+					power_setting->seq_val,
+					s_ctrl->clk_info_size);
+				goto power_up_failed;
+			}
+			if (power_setting->config_val)
+				s_ctrl->clk_info[power_setting->seq_val].
+					clk_rate = power_setting->config_val;
+
+			rc = msm_cam_clk_enable(s_ctrl->dev,
+				&s_ctrl->clk_info[0],
+				(struct clk **)&power_setting->data[0],
+				s_ctrl->clk_info_size,
+				1);
+			if (rc < 0) {
+				pr_err("%s: clk enable failed\n",
+					__func__);
+				goto power_up_failed;
+			}
+			break;
+		case SENSOR_GPIO:
+			if (power_setting->seq_val >= SENSOR_GPIO_MAX ||
+				!data->gpio_conf->gpio_num_info) {
+				pr_err("%s gpio index %d >= max %d\n", __func__,
+					power_setting->seq_val,
+					SENSOR_GPIO_MAX);
+				goto power_up_failed;
+			}
+			pr_debug("%s:%d gpio set val %d\n", __func__, __LINE__,
+				data->gpio_conf->gpio_num_info->gpio_num
+				[power_setting->seq_val]);
+			gpio_set_value_cansleep(
+				data->gpio_conf->gpio_num_info->gpio_num
+				[power_setting->seq_val],
+				power_setting->config_val);
+			break;
+		case SENSOR_VREG:
+			if (power_setting->seq_val >= CAM_VREG_MAX) {
+				pr_err("%s vreg index %d >= max %d\n", __func__,
+					power_setting->seq_val,
+					SENSOR_GPIO_MAX);
+				goto power_up_failed;
+			}
+			msm_camera_config_single_vreg(s_ctrl->dev,
+				&data->cam_vreg[power_setting->seq_val],
+				(struct regulator **)&power_setting->data[0],
+				1);
+			break;
+		case SENSOR_I2C_MUX:
+			if (data->i2c_conf && data->i2c_conf->use_i2c_mux)
+				msm_sensor_enable_i2c_mux(data->i2c_conf);
+			break;
+		default:
+			pr_err("%s error power seq type %d\n", __func__,
+				power_setting->seq_type);
+			break;
+		}
+		if (power_setting->delay > 20) {
+			msleep(power_setting->delay);
+		} else if (power_setting->delay) {
+			usleep_range(power_setting->delay * 1000,
+				(power_setting->delay * 1000) + 1000);
+		}
+	}
+
+	if (s_ctrl->sensor_device_type == MSM_CAMERA_PLATFORM_DEVICE) {
+		rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_util(
+			s_ctrl->sensor_i2c_client, MSM_CCI_INIT);
+		if (rc < 0) {
+			pr_err("%s cci_init failed\n", __func__);
+			goto power_up_failed;
+		}
+	}
+
+	if (s_ctrl->func_tbl->sensor_match_id)
+		rc = s_ctrl->func_tbl->sensor_match_id(s_ctrl);
+	else
+		rc = msm_sensor_match_id(s_ctrl);
+	if (rc < 0) {
+		pr_err("%s:%d match id failed rc %d\n", __func__, __LINE__, rc);
+		goto power_up_failed;
+	}
+
+	CDBG("%s exit\n", __func__);
+	return 0;
+power_up_failed:
+	pr_err("%s:%d failed\n", __func__, __LINE__);
+	if (s_ctrl->sensor_device_type == MSM_CAMERA_PLATFORM_DEVICE) {
+		s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_util(
+			s_ctrl->sensor_i2c_client, MSM_CCI_RELEASE);
+	}
+
+	for (index--; index >= 0; index--) {
+		CDBG("%s index %d\n", __func__, index);
+		power_setting = &power_setting_array->power_setting[index];
+		CDBG("%s type %d\n", __func__, power_setting->seq_type);
+		switch (power_setting->seq_type) {
+		case SENSOR_CLK:
+			msm_cam_clk_enable(s_ctrl->dev,
+				&s_ctrl->clk_info[0],
+				(struct clk **)&power_setting->data[0],
+				s_ctrl->clk_info_size,
+				0);
+			break;
+		case SENSOR_GPIO:
+			gpio_set_value_cansleep(
+				data->gpio_conf->gpio_num_info->gpio_num
+				[power_setting->seq_val], GPIOF_OUT_INIT_LOW);
+			break;
+		case SENSOR_VREG:
+			msm_camera_config_single_vreg(s_ctrl->dev,
+				&data->cam_vreg[power_setting->seq_val],
+				(struct regulator **)&power_setting->data[0],
+				0);
+			break;
+		case SENSOR_I2C_MUX:
+			if (data->i2c_conf && data->i2c_conf->use_i2c_mux)
+				msm_sensor_disable_i2c_mux(data->i2c_conf);
+			break;
+		default:
+			pr_err("%s error power seq type %d\n", __func__,
+				power_setting->seq_type);
+			break;
+		}
+		if (power_setting->delay > 20) {
+			msleep(power_setting->delay);
+		} else if (power_setting->delay) {
+			usleep_range(power_setting->delay * 1000,
+				(power_setting->delay * 1000) + 1000);
+		}
+	}
+	msm_camera_request_gpio_table(
+		data->gpio_conf->cam_gpio_req_tbl,
+		data->gpio_conf->cam_gpio_req_tbl_size, 0);
+	return rc;
+}
+
+int32_t msm_sensor_power_down(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	int32_t index = 0;
+	struct msm_sensor_power_setting_array *power_setting_array = NULL;
+	struct msm_sensor_power_setting *power_setting = NULL;
+	struct msm_camera_sensor_board_info *data = s_ctrl->sensordata;
+
+	CDBG("%s:%d\n", __func__, __LINE__);
+	power_setting_array = &s_ctrl->power_setting_array;
+
+	if (s_ctrl->sensor_device_type == MSM_CAMERA_PLATFORM_DEVICE) {
+		s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_util(
+			s_ctrl->sensor_i2c_client, MSM_CCI_RELEASE);
+	}
+
+	for (index = (power_setting_array->size - 1); index >= 0; index--) {
+		CDBG("%s index %d\n", __func__, index);
+		power_setting = &power_setting_array->power_setting[index];
+		CDBG("%s type %d\n", __func__, power_setting->seq_type);
+		switch (power_setting->seq_type) {
+		case SENSOR_CLK:
+			msm_cam_clk_enable(s_ctrl->dev,
+				&s_ctrl->clk_info[0],
+				(struct clk **)&power_setting->data[0],
+				s_ctrl->clk_info_size,
+				0);
+			break;
+		case SENSOR_GPIO:
+			if (power_setting->seq_val >= SENSOR_GPIO_MAX ||
+				!data->gpio_conf->gpio_num_info) {
+				pr_err("%s gpio index %d >= max %d\n", __func__,
+					power_setting->seq_val,
+					SENSOR_GPIO_MAX);
+				continue;
+			}
+			gpio_set_value_cansleep(
+				data->gpio_conf->gpio_num_info->gpio_num
+				[power_setting->seq_val], GPIOF_OUT_INIT_LOW);
+			break;
+		case SENSOR_VREG:
+			if (power_setting->seq_val >= CAM_VREG_MAX) {
+				pr_err("%s vreg index %d >= max %d\n", __func__,
+					power_setting->seq_val,
+					SENSOR_GPIO_MAX);
+				continue;
+			}
+			msm_camera_config_single_vreg(s_ctrl->dev,
+				&data->cam_vreg[power_setting->seq_val],
+				(struct regulator **)&power_setting->data[0],
+				0);
+			break;
+		case SENSOR_I2C_MUX:
+			if (data->i2c_conf && data->i2c_conf->use_i2c_mux)
+				msm_sensor_disable_i2c_mux(data->i2c_conf);
+			break;
+		default:
+			pr_err("%s error power seq type %d\n", __func__,
+				power_setting->seq_type);
+			break;
+		}
+		if (power_setting->delay > 20) {
+			msleep(power_setting->delay);
+		} else if (power_setting->delay) {
+			usleep_range(power_setting->delay * 1000,
+				(power_setting->delay * 1000) + 1000);
+		}
+	}
+	msm_camera_request_gpio_table(
+		data->gpio_conf->cam_gpio_req_tbl,
+		data->gpio_conf->cam_gpio_req_tbl_size, 0);
+	CDBG("%s exit\n", __func__);
+	return 0;
+}
+
+int32_t msm_sensor_match_id(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	int32_t rc = 0;
+	uint16_t chipid = 0;
+	rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_read(
+			s_ctrl->sensor_i2c_client,
+			s_ctrl->sensordata->slave_info->sensor_id_reg_addr,
+			&chipid, MSM_CAMERA_I2C_WORD_DATA);
+	if (rc < 0) {
+		pr_err("%s: %s: read id failed\n", __func__,
+			s_ctrl->sensordata->sensor_name);
+		return rc;
+	}
+
+	CDBG("%s: read id: %x expected id %x:\n", __func__, chipid,
+		s_ctrl->sensordata->slave_info->sensor_id);
+	if (chipid != s_ctrl->sensordata->slave_info->sensor_id) {
+		pr_err("msm_sensor_match_id chip id doesnot match\n");
+		return -ENODEV;
+	}
+	return rc;
+}
+
+static struct msm_sensor_ctrl_t *get_sctrl(struct v4l2_subdev *sd)
+{
+	return container_of(container_of(sd, struct msm_sd_subdev, sd),
+		struct msm_sensor_ctrl_t, msm_sd);
+}
+
+static void msm_sensor_stop_stream(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_write_table(
+		s_ctrl->sensor_i2c_client, &s_ctrl->stop_setting);
+	kfree(s_ctrl->stop_setting.reg_setting);
+	return;
+}
+
+static long msm_sensor_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int cmd, void *arg)
+{
+	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
+	void __user *argp = (void __user *)arg;
+	if (!s_ctrl) {
+		pr_err("%s s_ctrl NULL\n", __func__);
+		return -EBADF;
+	}
+	switch (cmd) {
+	case VIDIOC_MSM_SENSOR_CFG:
+		return s_ctrl->func_tbl->sensor_config(s_ctrl, argp);
+	case VIDIOC_MSM_SENSOR_RELEASE:
+		msm_sensor_stop_stream(s_ctrl);
+		return 0;
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
+int32_t msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl,
+	void __user *argp)
+{
+	struct sensorb_cfg_data *cdata = (struct sensorb_cfg_data *)argp;
+	long rc = 0;
+	int32_t i = 0;
+	mutex_lock(s_ctrl->msm_sensor_mutex);
+	CDBG("%s:%d %s cfgtype = %d\n", __func__, __LINE__,
+		s_ctrl->sensordata->sensor_name, cdata->cfgtype);
+	switch (cdata->cfgtype) {
+	case CFG_GET_SENSOR_INFO:
+		memcpy(cdata->cfg.sensor_info.sensor_name,
+			s_ctrl->sensordata->sensor_name,
+			sizeof(cdata->cfg.sensor_info.sensor_name));
+		cdata->cfg.sensor_info.session_id =
+			s_ctrl->sensordata->sensor_info->session_id;
+		for (i = 0; i < SUB_MODULE_MAX; i++)
+			cdata->cfg.sensor_info.subdev_id[i] =
+				s_ctrl->sensordata->sensor_info->subdev_id[i];
+		CDBG("%s:%d sensor name %s\n", __func__, __LINE__,
+			cdata->cfg.sensor_info.sensor_name);
+		CDBG("%s:%d session id %d\n", __func__, __LINE__,
+			cdata->cfg.sensor_info.session_id);
+		for (i = 0; i < SUB_MODULE_MAX; i++)
+			CDBG("%s:%d subdev_id[%d] %d\n", __func__, __LINE__, i,
+				cdata->cfg.sensor_info.subdev_id[i]);
+
+		break;
+	case CFG_GET_SENSOR_INIT_PARAMS:
+		cdata->cfg.sensor_init_params =
+			*s_ctrl->sensordata->sensor_init_params;
+		CDBG("%s:%d init params mode %d pos %d mount %d\n", __func__,
+			__LINE__,
+			cdata->cfg.sensor_init_params.modes_supported,
+			cdata->cfg.sensor_init_params.position,
+			cdata->cfg.sensor_init_params.sensor_mount_angle);
+		break;
+	case CFG_SET_SLAVE_INFO: {
+		struct msm_camera_sensor_slave_info sensor_slave_info;
+		struct msm_sensor_power_setting_array *power_setting_array;
+		int slave_index = 0;
+		if (copy_from_user(&sensor_slave_info,
+			(void *)cdata->cfg.setting,
+			sizeof(struct msm_camera_sensor_slave_info))) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			rc = -EFAULT;
+			break;
+		}
+		/* Update sensor slave address */
+		if (sensor_slave_info.slave_addr) {
+			s_ctrl->sensor_i2c_client->cci_client->sid =
+				sensor_slave_info.slave_addr >> 1;
+		}
+
+		/* Update sensor address type */
+		s_ctrl->sensor_i2c_client->addr_type =
+			sensor_slave_info.addr_type;
+
+		/* Update power up / down sequence */
+		s_ctrl->power_setting_array =
+			sensor_slave_info.power_setting_array;
+		power_setting_array = &s_ctrl->power_setting_array;
+		power_setting_array->power_setting = kzalloc(
+			power_setting_array->size *
+			sizeof(struct msm_sensor_power_setting), GFP_KERNEL);
+		if (!power_setting_array->power_setting) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			rc = -ENOMEM;
+			break;
+		}
+		if (copy_from_user(power_setting_array->power_setting,
+			(void *)
+			sensor_slave_info.power_setting_array.power_setting,
+			power_setting_array->size *
+			sizeof(struct msm_sensor_power_setting))) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			rc = -EFAULT;
+			break;
+		}
+		s_ctrl->free_power_setting = true;
+		CDBG("%s sensor id %x\n", __func__,
+			sensor_slave_info.slave_addr);
+		CDBG("%s sensor addr type %d\n", __func__,
+			sensor_slave_info.addr_type);
+		CDBG("%s sensor reg %x\n", __func__,
+			sensor_slave_info.sensor_id_info.sensor_id_reg_addr);
+		CDBG("%s sensor id %x\n", __func__,
+			sensor_slave_info.sensor_id_info.sensor_id);
+		for (slave_index = 0; slave_index <
+			power_setting_array->size; slave_index++) {
+			CDBG("%s i %d power setting %d %d %ld %d\n", __func__,
+				slave_index,
+				power_setting_array->power_setting[slave_index].
+				seq_type,
+				power_setting_array->power_setting[slave_index].
+				seq_val,
+				power_setting_array->power_setting[slave_index].
+				config_val,
+				power_setting_array->power_setting[slave_index].
+				delay);
+		}
+		break;
+	}
+	case CFG_WRITE_I2C_ARRAY: {
+		struct msm_camera_i2c_reg_setting conf_array;
+		struct msm_camera_i2c_reg_array *reg_setting = NULL;
+
+		if (copy_from_user(&conf_array,
+			(void *)cdata->cfg.setting,
+			sizeof(struct msm_camera_i2c_reg_setting))) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			rc = -EFAULT;
+			break;
+		}
+
+		reg_setting = kzalloc(conf_array.size *
+			(sizeof(struct msm_camera_i2c_reg_array)), GFP_KERNEL);
+		if (!reg_setting) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			rc = -ENOMEM;
+			break;
+		}
+		if (copy_from_user(reg_setting, (void *)conf_array.reg_setting,
+			conf_array.size *
+			sizeof(struct msm_camera_i2c_reg_array))) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			kfree(reg_setting);
+			rc = -EFAULT;
+			break;
+		}
+
+		conf_array.reg_setting = reg_setting;
+		rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_write_table(
+			s_ctrl->sensor_i2c_client, &conf_array);
+		kfree(reg_setting);
+		break;
+	}
+	case CFG_WRITE_I2C_SEQ_ARRAY: {
+		struct msm_camera_i2c_seq_reg_setting conf_array;
+		struct msm_camera_i2c_seq_reg_array *reg_setting = NULL;
+
+		if (copy_from_user(&conf_array,
+			(void *)cdata->cfg.setting,
+			sizeof(struct msm_camera_i2c_seq_reg_setting))) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			rc = -EFAULT;
+			break;
+		}
+
+		reg_setting = kzalloc(conf_array.size *
+			(sizeof(struct msm_camera_i2c_seq_reg_array)),
+			GFP_KERNEL);
+		if (!reg_setting) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			rc = -ENOMEM;
+			break;
+		}
+		if (copy_from_user(reg_setting, (void *)conf_array.reg_setting,
+			conf_array.size *
+			sizeof(struct msm_camera_i2c_seq_reg_array))) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			kfree(reg_setting);
+			rc = -EFAULT;
+			break;
+		}
+
+		conf_array.reg_setting = reg_setting;
+		rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->
+			i2c_write_seq_table(s_ctrl->sensor_i2c_client,
+			&conf_array);
+		kfree(reg_setting);
+		break;
+	}
+
+	case CFG_POWER_UP:
+		if (s_ctrl->func_tbl->sensor_power_up)
+			rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
+		else
+			rc = -EFAULT;
+		break;
+
+	case CFG_POWER_DOWN:
+		if (s_ctrl->func_tbl->sensor_power_down)
+			rc = s_ctrl->func_tbl->sensor_power_down(
+				s_ctrl);
+		else
+			rc = -EFAULT;
+		break;
+
+	case CFG_SET_STOP_STREAM_SETTING: {
+		struct msm_camera_i2c_reg_setting *stop_setting =
+			&s_ctrl->stop_setting;
+		struct msm_camera_i2c_reg_array *reg_setting = NULL;
+		if (copy_from_user(stop_setting,
+			(void *)cdata->cfg.setting,
+			sizeof(struct msm_camera_i2c_reg_setting))) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			rc = -EFAULT;
+			break;
+		}
+
+		reg_setting = stop_setting->reg_setting;
+		stop_setting->reg_setting = kzalloc(stop_setting->size *
+			(sizeof(struct msm_camera_i2c_reg_array)), GFP_KERNEL);
+		if (!stop_setting->reg_setting) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			rc = -ENOMEM;
+			break;
+		}
+		if (copy_from_user(stop_setting->reg_setting,
+			(void *)reg_setting,
+			stop_setting->size *
+			sizeof(struct msm_camera_i2c_reg_array))) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			kfree(stop_setting->reg_setting);
+			stop_setting->reg_setting = NULL;
+			stop_setting->size = 0;
+			rc = -EFAULT;
+			break;
+		}
+		break;
+	}
+	default:
+		rc = -EFAULT;
+		break;
+	}
+
+	mutex_unlock(s_ctrl->msm_sensor_mutex);
+
+	return rc;
+}
+
+static int32_t msm_sensor_power(struct v4l2_subdev *sd, int on)
+{
+	int rc = 0;
+	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
+	mutex_lock(s_ctrl->msm_sensor_mutex);
+	if (!on)
+		rc = s_ctrl->func_tbl->sensor_power_down(s_ctrl);
+	if (s_ctrl->free_power_setting == true) {
+		kfree(s_ctrl->power_setting_array.power_setting);
+		s_ctrl->free_power_setting = false;
+	}
+	mutex_unlock(s_ctrl->msm_sensor_mutex);
+	return rc;
+}
+
+static int32_t msm_sensor_v4l2_enum_fmt(struct v4l2_subdev *sd,
+	unsigned int index, enum v4l2_mbus_pixelcode *code)
+{
+	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
+
+	if ((unsigned int)index >= s_ctrl->sensor_v4l2_subdev_info_size)
+		return -EINVAL;
+
+	*code = s_ctrl->sensor_v4l2_subdev_info[index].code;
+	return 0;
+}
+
+static struct v4l2_subdev_core_ops msm_sensor_subdev_core_ops = {
+	.ioctl = msm_sensor_subdev_ioctl,
+	.s_power = msm_sensor_power,
+};
+
+static struct v4l2_subdev_video_ops msm_sensor_subdev_video_ops = {
+	.enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
+};
+
+static struct v4l2_subdev_ops msm_sensor_subdev_ops = {
+	.core = &msm_sensor_subdev_core_ops,
+	.video  = &msm_sensor_subdev_video_ops,
+};
+
+static struct msm_sensor_fn_t msm_sensor_func_tbl = {
+	.sensor_config = msm_sensor_config,
+	.sensor_power_up = msm_sensor_power_up,
+	.sensor_power_down = msm_sensor_power_down,
+	.sensor_match_id = msm_sensor_match_id,
+};
+
+static struct msm_camera_i2c_fn_t msm_sensor_cci_func_tbl = {
+	.i2c_read = msm_camera_cci_i2c_read,
+	.i2c_read_seq = msm_camera_cci_i2c_read_seq,
+	.i2c_write = msm_camera_cci_i2c_write,
+	.i2c_write_table = msm_camera_cci_i2c_write_table,
+	.i2c_write_seq_table = msm_camera_cci_i2c_write_seq_table,
+	.i2c_write_table_w_microdelay =
+		msm_camera_cci_i2c_write_table_w_microdelay,
+	.i2c_util = msm_sensor_cci_i2c_util,
+	.i2c_write_conf_tbl = msm_camera_cci_i2c_write_conf_tbl,
+};
+
+static struct msm_camera_i2c_fn_t msm_sensor_qup_func_tbl = {
+	.i2c_read = msm_camera_qup_i2c_read,
+	.i2c_read_seq = msm_camera_qup_i2c_read_seq,
+	.i2c_write = msm_camera_qup_i2c_write,
+	.i2c_write_table = msm_camera_qup_i2c_write_table,
+	.i2c_write_seq_table = msm_camera_qup_i2c_write_seq_table,
+	.i2c_write_table_w_microdelay =
+		msm_camera_qup_i2c_write_table_w_microdelay,
+};
+
+int32_t msm_sensor_platform_probe(struct platform_device *pdev, void *data)
+{
+	int32_t rc = 0;
+	struct msm_sensor_ctrl_t *s_ctrl =
+		(struct msm_sensor_ctrl_t *)data;
+	struct msm_camera_cci_client *cci_client = NULL;
+	uint32_t session_id;
+	s_ctrl->pdev = pdev;
+	s_ctrl->dev = &pdev->dev;
+	CDBG("%s called data %p\n", __func__, data);
+	CDBG("%s pdev name %s\n", __func__, pdev->id_entry->name);
+	if (pdev->dev.of_node) {
+		rc = msm_sensor_get_dt_data(pdev, s_ctrl);
+		if (rc < 0) {
+			pr_err("%s failed line %d\n", __func__, __LINE__);
+			return rc;
+		}
+	}
+	s_ctrl->sensor_device_type = MSM_CAMERA_PLATFORM_DEVICE;
+	s_ctrl->sensor_i2c_client->cci_client = kzalloc(sizeof(
+		struct msm_camera_cci_client), GFP_KERNEL);
+	if (!s_ctrl->sensor_i2c_client->cci_client) {
+		pr_err("%s failed line %d\n", __func__, __LINE__);
+		return rc;
+	}
+	/* TODO: get CCI subdev */
+	cci_client = s_ctrl->sensor_i2c_client->cci_client;
+	cci_client->cci_subdev = msm_cci_get_subdev();
+	cci_client->cci_i2c_master = s_ctrl->cci_i2c_master;
+	cci_client->sid =
+		s_ctrl->sensordata->slave_info->sensor_slave_addr >> 1;
+	cci_client->retries = 3;
+	cci_client->id_map = 0;
+	if (!s_ctrl->func_tbl)
+		s_ctrl->func_tbl = &msm_sensor_func_tbl;
+	if (!s_ctrl->sensor_i2c_client->i2c_func_tbl)
+		s_ctrl->sensor_i2c_client->i2c_func_tbl =
+			&msm_sensor_cci_func_tbl;
+	if (!s_ctrl->sensor_v4l2_subdev_ops)
+		s_ctrl->sensor_v4l2_subdev_ops = &msm_sensor_subdev_ops;
+	s_ctrl->clk_info = cam_8974_clk_info;
+	s_ctrl->clk_info_size = ARRAY_SIZE(cam_8974_clk_info);
+	rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
+	if (rc < 0) {
+		pr_err("%s %s power up failed\n", __func__,
+			s_ctrl->sensordata->sensor_name);
+		kfree(cci_client);
+		return rc;
+	}
+
+	CDBG("%s %s probe succeeded\n", __func__,
+		s_ctrl->sensordata->sensor_name);
+	v4l2_subdev_init(&s_ctrl->msm_sd.sd,
+		s_ctrl->sensor_v4l2_subdev_ops);
+	snprintf(s_ctrl->msm_sd.sd.name,
+		sizeof(s_ctrl->msm_sd.sd.name), "%s",
+		s_ctrl->sensordata->sensor_name);
+	v4l2_set_subdevdata(&s_ctrl->msm_sd.sd, pdev);
+	s_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	media_entity_init(&s_ctrl->msm_sd.sd.entity, 0, NULL, 0);
+	s_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	s_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_SENSOR;
+	s_ctrl->msm_sd.sd.entity.name =
+		s_ctrl->msm_sd.sd.name;
+
+	rc = camera_init_v4l2(&s_ctrl->pdev->dev, &session_id);
+	CDBG("%s rc %d session_id %d\n", __func__, rc, session_id);
+	s_ctrl->sensordata->sensor_info->session_id = session_id;
+	msm_sd_register(&s_ctrl->msm_sd);
+	CDBG("%s:%d\n", __func__, __LINE__);
+
+	s_ctrl->func_tbl->sensor_power_down(s_ctrl);
+	CDBG("%s:%d\n", __func__, __LINE__);
+	return rc;
+}
+
+int32_t msm_sensor_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+	struct msm_sensor_ctrl_t *s_ctrl;
+	uint32_t session_id;
+	CDBG("%s %s_i2c_probe called\n", __func__, client->name);
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		pr_err("%s %s i2c_check_functionality failed\n",
+			__func__, client->name);
+		rc = -EFAULT;
+		return rc;
+	}
+
+	s_ctrl = (struct msm_sensor_ctrl_t *)(id->driver_data);
+	if (!s_ctrl) {
+		pr_err("%s:%d sensor ctrl structure NULL\n", __func__,
+			__LINE__);
+		return -EINVAL;
+	}
+
+	s_ctrl->sensor_device_type = MSM_CAMERA_I2C_DEVICE;
+	s_ctrl->sensordata = client->dev.platform_data;
+	if (s_ctrl->sensordata == NULL) {
+		pr_err("%s %s NULL sensor data\n", __func__, client->name);
+		return -EFAULT;
+	}
+
+	if (s_ctrl->sensor_i2c_client != NULL) {
+		s_ctrl->sensor_i2c_client->client = client;
+		s_ctrl->dev = &client->dev;
+		if (s_ctrl->sensordata->slave_info->sensor_slave_addr)
+			s_ctrl->sensor_i2c_client->client->addr =
+				s_ctrl->sensordata->slave_info->
+				sensor_slave_addr;
+	} else {
+		pr_err("%s %s sensor_i2c_client NULL\n",
+			__func__, client->name);
+		rc = -EFAULT;
+		return rc;
+	}
+
+	if (!s_ctrl->func_tbl)
+		s_ctrl->func_tbl = &msm_sensor_func_tbl;
+	if (!s_ctrl->sensor_i2c_client->i2c_func_tbl)
+		s_ctrl->sensor_i2c_client->i2c_func_tbl =
+			&msm_sensor_qup_func_tbl;
+	if (!s_ctrl->sensor_v4l2_subdev_ops)
+		s_ctrl->sensor_v4l2_subdev_ops = &msm_sensor_subdev_ops;
+
+	s_ctrl->clk_info = cam_8960_clk_info;
+	s_ctrl->clk_info_size = ARRAY_SIZE(cam_8960_clk_info);
+
+	rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
+	if (rc < 0) {
+		pr_err("%s %s power up failed\n", __func__, client->name);
+		return rc;
+	}
+
+	CDBG("%s %s probe succeeded\n", __func__, client->name);
+	snprintf(s_ctrl->msm_sd.sd.name,
+		sizeof(s_ctrl->msm_sd.sd.name), "%s", id->name);
+	v4l2_i2c_subdev_init(&s_ctrl->msm_sd.sd, client,
+		s_ctrl->sensor_v4l2_subdev_ops);
+	v4l2_set_subdevdata(&s_ctrl->msm_sd.sd, client);
+	s_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	media_entity_init(&s_ctrl->msm_sd.sd.entity, 0, NULL, 0);
+	s_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	s_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_SENSOR;
+	s_ctrl->msm_sd.sd.entity.name =
+		s_ctrl->msm_sd.sd.name;
+
+	rc = camera_init_v4l2(&s_ctrl->sensor_i2c_client->client->dev,
+		&session_id);
+	CDBG("%s rc %d session_id %d\n", __func__, rc, session_id);
+	s_ctrl->sensordata->sensor_info->session_id = session_id;
+	msm_sd_register(&s_ctrl->msm_sd);
+	CDBG("%s:%d\n", __func__, __LINE__);
+
+	s_ctrl->func_tbl->sensor_power_down(s_ctrl);
+	return rc;
+}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.h b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.h
new file mode 100644
index 0000000..6c36e47d
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.h
@@ -0,0 +1,87 @@
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_SENSOR_H
+#define MSM_SENSOR_H
+
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/uaccess.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/gpio.h>
+#include <mach/camera2.h>
+#include <media/msm_cam_sensor.h>
+#include <media/v4l2-subdev.h>
+#include "msm_camera_i2c.h"
+#include "msm_sd.h"
+
+#define DEFINE_MSM_MUTEX(mutexname) \
+	static struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
+
+struct msm_sensor_ctrl_t;
+
+struct msm_sensor_fn_t {
+	int (*sensor_config) (struct msm_sensor_ctrl_t *, void __user *);
+	int (*sensor_power_down)
+		(struct msm_sensor_ctrl_t *);
+	int (*sensor_power_up) (struct msm_sensor_ctrl_t *);
+	int32_t (*sensor_match_id)(struct msm_sensor_ctrl_t *s_ctrl);
+};
+
+struct msm_sensor_ctrl_t {
+	struct platform_device *pdev;
+	enum msm_camera_device_type_t sensor_device_type;
+	enum cci_i2c_master_t cci_i2c_master;
+	struct msm_camera_sensor_board_info *sensordata;
+	struct msm_sensor_power_setting_array power_setting_array;
+	struct mutex *msm_sensor_mutex;
+
+	struct msm_camera_i2c_client *sensor_i2c_client;
+	struct device *dev;
+
+	struct msm_sd_subdev msm_sd;
+	struct v4l2_subdev_info *sensor_v4l2_subdev_info;
+	uint8_t sensor_v4l2_subdev_info_size;
+	struct v4l2_subdev_ops *sensor_v4l2_subdev_ops;
+	struct msm_sensor_fn_t *func_tbl;
+	struct msm_camera_i2c_reg_setting stop_setting;
+	bool free_power_setting;
+	struct msm_cam_clk_info *clk_info;
+	uint16_t clk_info_size;
+};
+
+int32_t msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl,
+			void __user *argp);
+
+int32_t msm_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl);
+
+int32_t msm_sensor_power_down(struct msm_sensor_ctrl_t *s_ctrl);
+
+int32_t msm_sensor_match_id(struct msm_sensor_ctrl_t *s_ctrl);
+
+int32_t msm_sensor_platform_probe(struct platform_device *pdev,
+	void *data);
+
+int32_t msm_sensor_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id);
+
+int32_t msm_sensor_free_sensor_data(struct msm_sensor_ctrl_t *s_ctrl);
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v2/sensor/mt9m114.c b/drivers/media/platform/msm/camera_v2/sensor/mt9m114.c
new file mode 100644
index 0000000..9911a59
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/mt9m114.c
@@ -0,0 +1,1452 @@
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include "msm_sensor.h"
+#include "msm_cci.h"
+#include "msm_camera_io_util.h"
+#define MT9M114_SENSOR_NAME "mt9m114"
+#define PLATFORM_DRIVER_NAME "msm_camera_mt9m114"
+#define mt9m114_obj mt9m114_##obj
+
+/*#define CONFIG_MSMB_CAMERA_DEBUG*/
+#undef CDBG
+#ifdef CONFIG_MSMB_CAMERA_DEBUG
+#define CDBG(fmt, args...) pr_err(fmt, ##args)
+#else
+#define CDBG(fmt, args...) do { } while (0)
+#endif
+
+/* Sysctl registers */
+#define MT9M114_COMMAND_REGISTER                0x0080
+#define MT9M114_COMMAND_REGISTER_APPLY_PATCH    (1 << 0)
+#define MT9M114_COMMAND_REGISTER_SET_STATE      (1 << 1)
+#define MT9M114_COMMAND_REGISTER_REFRESH        (1 << 2)
+#define MT9M114_COMMAND_REGISTER_WAIT_FOR_EVENT (1 << 3)
+#define MT9M114_COMMAND_REGISTER_OK             (1 << 15)
+
+DEFINE_MSM_MUTEX(mt9m114_mut);
+static struct msm_sensor_ctrl_t mt9m114_s_ctrl;
+
+static struct msm_sensor_power_setting mt9m114_power_setting[] = {
+	{
+		.seq_type = SENSOR_VREG,
+		.seq_val = CAM_VIO,
+		.config_val = 0,
+		.delay = 0,
+	},
+	{
+		.seq_type = SENSOR_VREG,
+		.seq_val = CAM_VDIG,
+		.config_val = 0,
+		.delay = 0,
+	},
+	{
+		.seq_type = SENSOR_VREG,
+		.seq_val = CAM_VANA,
+		.config_val = 0,
+		.delay = 0,
+	},
+	{
+		.seq_type = SENSOR_GPIO,
+		.seq_val = SENSOR_GPIO_RESET,
+		.config_val = GPIO_OUT_LOW,
+		.delay = 1,
+	},
+	{
+		.seq_type = SENSOR_GPIO,
+		.seq_val = SENSOR_GPIO_RESET,
+		.config_val = GPIO_OUT_HIGH,
+		.delay = 30,
+	},
+	{
+		.seq_type = SENSOR_CLK,
+		.seq_val = SENSOR_CAM_MCLK,
+		.config_val = 0,
+		.delay = 100,
+	},
+	{
+		.seq_type = SENSOR_I2C_MUX,
+		.seq_val = 0,
+		.config_val = 0,
+		.delay = 0,
+	},
+};
+
+static struct msm_camera_i2c_reg_conf mt9m114_720p_settings[] = {
+	{0xdc00, 0x50, MSM_CAMERA_I2C_BYTE_DATA, MSM_CAMERA_I2C_CMD_WRITE},
+	{MT9M114_COMMAND_REGISTER, MT9M114_COMMAND_REGISTER_SET_STATE,
+		MSM_CAMERA_I2C_UNSET_WORD_MASK, MSM_CAMERA_I2C_CMD_POLL},
+	{MT9M114_COMMAND_REGISTER, (MT9M114_COMMAND_REGISTER_OK |
+		MT9M114_COMMAND_REGISTER_SET_STATE), MSM_CAMERA_I2C_WORD_DATA,
+		MSM_CAMERA_I2C_CMD_WRITE},
+	{MT9M114_COMMAND_REGISTER, MT9M114_COMMAND_REGISTER_SET_STATE,
+		MSM_CAMERA_I2C_UNSET_WORD_MASK, MSM_CAMERA_I2C_CMD_POLL},
+	{0xDC01, 0x52, MSM_CAMERA_I2C_BYTE_DATA, MSM_CAMERA_I2C_CMD_POLL},
+
+	{0x098E, 0, MSM_CAMERA_I2C_BYTE_DATA},
+	{0xC800, 0x007C,},/*y_addr_start = 124*/
+	{0xC802, 0x0004,},/*x_addr_start = 4*/
+	{0xC804, 0x0353,},/*y_addr_end = 851*/
+	{0xC806, 0x050B,},/*x_addr_end = 1291*/
+	{0xC808, 0x02DC,},/*pixclk = 48000000*/
+	{0xC80A, 0x6C00,},/*pixclk = 48000000*/
+	{0xC80C, 0x0001,},/*row_speed = 1*/
+	{0xC80E, 0x00DB,},/*fine_integ_time_min = 219*/
+	{0xC810, 0x05BD,},/*fine_integ_time_max = 1469*/
+	{0xC812, 0x03E8,},/*frame_length_lines = 1000*/
+	{0xC814, 0x0640,},/*line_length_pck = 1600*/
+	{0xC816, 0x0060,},/*fine_correction = 96*/
+	{0xC818, 0x02D3,},/*cpipe_last_row = 723*/
+	{0xC826, 0x0020,},/*reg_0_data = 32*/
+	{0xC834, 0x0000,},/*sensor_control_read_mode = 0*/
+	{0xC854, 0x0000,},/*crop_window_xoffset = 0*/
+	{0xC856, 0x0000,},/*crop_window_yoffset = 0*/
+	{0xC858, 0x0500,},/*crop_window_width = 1280*/
+	{0xC85A, 0x02D0,},/*crop_window_height = 720*/
+	{0xC85C, 0x03, MSM_CAMERA_I2C_BYTE_DATA},  /*crop_cropmode = 3*/
+	{0xC868, 0x0500,},/*output_width = 1280*/
+	{0xC86A, 0x02D0,},/*output_height = 720*/
+	{0xC878, 0x00, MSM_CAMERA_I2C_BYTE_DATA},  /*aet_aemode = 0*/
+	{0xC88C, 0x1E00,},/*aet_max_frame_rate = 7680*/
+	{0xC88E, 0x1E00,},/*aet_min_frame_rate = 7680*/
+	{0xC914, 0x0000,},/*stat_awb_window_xstart = 0*/
+	{0xC916, 0x0000,},/*stat_awb_window_ystart = 0*/
+	{0xC918, 0x04FF,},/*stat_awb_window_xend = 1279*/
+	{0xC91A, 0x02CF,},/*stat_awb_window_yend = 719*/
+	{0xC91C, 0x0000,},/*stat_ae_window_xstart = 0*/
+	{0xC91E, 0x0000,},/*stat_ae_window_ystart = 0*/
+	{0xC920, 0x00FF,},/*stat_ae_window_xend = 255*/
+	{0xC922, 0x008F,},/*stat_ae_window_yend = 143*/
+};
+
+static struct msm_camera_i2c_reg_conf mt9m114_recommend_settings[] = {
+	{0x301A, 0x0200, MSM_CAMERA_I2C_SET_WORD_MASK},
+	{0x098E, 0, MSM_CAMERA_I2C_BYTE_DATA},
+	/*cam_sysctl_pll_enable = 1*/
+	{0xC97E, 0x01, MSM_CAMERA_I2C_BYTE_DATA},
+	/*cam_sysctl_pll_divider_m_n = 288*/
+	{0xC980, 0x0120,},
+	/*cam_sysctl_pll_divider_p = 1792*/
+	{0xC982, 0x0700,},
+	/*output_control = 32769*/
+	{0xC984, 0x8001,},
+	/*mipi_timing_t_hs_zero = 3840*/
+	{0xC988, 0x0F00,},
+	/*mipi_timing_t_hs_exit_hs_trail = 2823*/
+	{0xC98A, 0x0B07,},
+	/*mipi_timing_t_clk_post_clk_pre = 3329*/
+	{0xC98C, 0x0D01,},
+	/*mipi_timing_t_clk_trail_clk_zero = 1821*/
+	{0xC98E, 0x071D,},
+	/*mipi_timing_t_lpx = 6*/
+	{0xC990, 0x0006,},
+	/*mipi_timing_init_timing = 2572*/
+	{0xC992, 0x0A0C,},
+	{0xC800, 0x007C,},/*y_addr_start = 124*/
+	{0xC802, 0x0004,},/*x_addr_start = 4*/
+	{0xC804, 0x0353,},/*y_addr_end = 851*/
+	{0xC806, 0x050B,},/*x_addr_end = 1291*/
+	{0xC808, 0x02DC,},/*pixclk = 48000000*/
+	{0xC80A, 0x6C00,},/*pixclk = 48000000*/
+	{0xC80C, 0x0001,},/*row_speed = 1*/
+	{0xC80E, 0x00DB,},/*fine_integ_time_min = 219*/
+	{0xC810, 0x05BD,},/*fine_integ_time_max = 1469*/
+	{0xC812, 0x03E8,},/*frame_length_lines = 1000*/
+	{0xC814, 0x0640,},/*line_length_pck = 1600*/
+	{0xC816, 0x0060,},/*fine_correction = 96*/
+	{0xC818, 0x02D3,},/*cpipe_last_row = 723*/
+	{0xC826, 0x0020,},/*reg_0_data = 32*/
+	{0xC834, 0x0000,},/*sensor_control_read_mode = 0*/
+	{0xC854, 0x0000,},/*crop_window_xoffset = 0*/
+	{0xC856, 0x0000,},/*crop_window_yoffset = 0*/
+	{0xC858, 0x0500,},/*crop_window_width = 1280*/
+	{0xC85A, 0x02D0,},/*crop_window_height = 720*/
+	{0xC85C, 0x03, MSM_CAMERA_I2C_BYTE_DATA},  /*crop_cropmode = 3*/
+	{0xC868, 0x0500,},/*output_width = 1280*/
+	{0xC86A, 0x02D0,},/*output_height = 720*/
+	{0xC878, 0x00, MSM_CAMERA_I2C_BYTE_DATA},  /*aet_aemode = 0*/
+	{0xC88C, 0x1E00,},/*aet_max_frame_rate = 7680*/
+	{0xC88E, 0x1E00,},/*aet_min_frame_rate = 7680*/
+	{0xC914, 0x0000,},/*stat_awb_window_xstart = 0*/
+	{0xC916, 0x0000,},/*stat_awb_window_ystart = 0*/
+	{0xC918, 0x04FF,},/*stat_awb_window_xend = 1279*/
+	{0xC91A, 0x02CF,},/*stat_awb_window_yend = 719*/
+	{0xC91C, 0x0000,},/*stat_ae_window_xstart = 0*/
+	{0xC91E, 0x0000,},/*stat_ae_window_ystart = 0*/
+	{0xC920, 0x00FF,},/*stat_ae_window_xend = 255*/
+	{0xC922, 0x008F,},/*stat_ae_window_yend = 143*/
+
+	/*Sensor optimization*/
+	{0x316A, 0x8270,},
+	{0x316C, 0x8270,},
+	{0x3ED0, 0x2305,},
+	{0x3ED2, 0x77CF,},
+	{0x316E, 0x8202,},
+	{0x3180, 0x87FF,},
+	{0x30D4, 0x6080,},
+	{0xA802, 0x0008,},/*AE_TRACK_MODE*/
+	{0x3E14, 0xFF39,},
+	{0x0982, 0x0001,},/*ACCESS_CTL_STAT*/
+	{0x098A, 0x5000,},/*PHYSICAL_ADDRESS_ACCESS*/
+	{0xD000, 0x70CF,},
+	{0xD002, 0xFFFF,},
+	{0xD004, 0xC5D4,},
+	{0xD006, 0x903A,},
+	{0xD008, 0x2144,},
+	{0xD00A, 0x0C00,},
+	{0xD00C, 0x2186,},
+	{0xD00E, 0x0FF3,},
+	{0xD010, 0xB844,},
+	{0xD012, 0xB948,},
+	{0xD014, 0xE082,},
+	{0xD016, 0x20CC,},
+	{0xD018, 0x80E2,},
+	{0xD01A, 0x21CC,},
+	{0xD01C, 0x80A2,},
+	{0xD01E, 0x21CC,},
+	{0xD020, 0x80E2,},
+	{0xD022, 0xF404,},
+	{0xD024, 0xD801,},
+	{0xD026, 0xF003,},
+	{0xD028, 0xD800,},
+	{0xD02A, 0x7EE0,},
+	{0xD02C, 0xC0F1,},
+	{0xD02E, 0x08BA,},
+	{0xD030, 0x0600,},
+	{0xD032, 0xC1A1,},
+	{0xD034, 0x76CF,},
+	{0xD036, 0xFFFF,},
+	{0xD038, 0xC130,},
+	{0xD03A, 0x6E04,},
+	{0xD03C, 0xC040,},
+	{0xD03E, 0x71CF,},
+	{0xD040, 0xFFFF,},
+	{0xD042, 0xC790,},
+	{0xD044, 0x8103,},
+	{0xD046, 0x77CF,},
+	{0xD048, 0xFFFF,},
+	{0xD04A, 0xC7C0,},
+	{0xD04C, 0xE001,},
+	{0xD04E, 0xA103,},
+	{0xD050, 0xD800,},
+	{0xD052, 0x0C6A,},
+	{0xD054, 0x04E0,},
+	{0xD056, 0xB89E,},
+	{0xD058, 0x7508,},
+	{0xD05A, 0x8E1C,},
+	{0xD05C, 0x0809,},
+	{0xD05E, 0x0191,},
+	{0xD060, 0xD801,},
+	{0xD062, 0xAE1D,},
+	{0xD064, 0xE580,},
+	{0xD066, 0x20CA,},
+	{0xD068, 0x0022,},
+	{0xD06A, 0x20CF,},
+	{0xD06C, 0x0522,},
+	{0xD06E, 0x0C5C,},
+	{0xD070, 0x04E2,},
+	{0xD072, 0x21CA,},
+	{0xD074, 0x0062,},
+	{0xD076, 0xE580,},
+	{0xD078, 0xD901,},
+	{0xD07A, 0x79C0,},
+	{0xD07C, 0xD800,},
+	{0xD07E, 0x0BE6,},
+	{0xD080, 0x04E0,},
+	{0xD082, 0xB89E,},
+	{0xD084, 0x70CF,},
+	{0xD086, 0xFFFF,},
+	{0xD088, 0xC8D4,},
+	{0xD08A, 0x9002,},
+	{0xD08C, 0x0857,},
+	{0xD08E, 0x025E,},
+	{0xD090, 0xFFDC,},
+	{0xD092, 0xE080,},
+	{0xD094, 0x25CC,},
+	{0xD096, 0x9022,},
+	{0xD098, 0xF225,},
+	{0xD09A, 0x1700,},
+	{0xD09C, 0x108A,},
+	{0xD09E, 0x73CF,},
+	{0xD0A0, 0xFF00,},
+	{0xD0A2, 0x3174,},
+	{0xD0A4, 0x9307,},
+	{0xD0A6, 0x2A04,},
+	{0xD0A8, 0x103E,},
+	{0xD0AA, 0x9328,},
+	{0xD0AC, 0x2942,},
+	{0xD0AE, 0x7140,},
+	{0xD0B0, 0x2A04,},
+	{0xD0B2, 0x107E,},
+	{0xD0B4, 0x9349,},
+	{0xD0B6, 0x2942,},
+	{0xD0B8, 0x7141,},
+	{0xD0BA, 0x2A04,},
+	{0xD0BC, 0x10BE,},
+	{0xD0BE, 0x934A,},
+	{0xD0C0, 0x2942,},
+	{0xD0C2, 0x714B,},
+	{0xD0C4, 0x2A04,},
+	{0xD0C6, 0x10BE,},
+	{0xD0C8, 0x130C,},
+	{0xD0CA, 0x010A,},
+	{0xD0CC, 0x2942,},
+	{0xD0CE, 0x7142,},
+	{0xD0D0, 0x2250,},
+	{0xD0D2, 0x13CA,},
+	{0xD0D4, 0x1B0C,},
+	{0xD0D6, 0x0284,},
+	{0xD0D8, 0xB307,},
+	{0xD0DA, 0xB328,},
+	{0xD0DC, 0x1B12,},
+	{0xD0DE, 0x02C4,},
+	{0xD0E0, 0xB34A,},
+	{0xD0E2, 0xED88,},
+	{0xD0E4, 0x71CF,},
+	{0xD0E6, 0xFF00,},
+	{0xD0E8, 0x3174,},
+	{0xD0EA, 0x9106,},
+	{0xD0EC, 0xB88F,},
+	{0xD0EE, 0xB106,},
+	{0xD0F0, 0x210A,},
+	{0xD0F2, 0x8340,},
+	{0xD0F4, 0xC000,},
+	{0xD0F6, 0x21CA,},
+	{0xD0F8, 0x0062,},
+	{0xD0FA, 0x20F0,},
+	{0xD0FC, 0x0040,},
+	{0xD0FE, 0x0B02,},
+	{0xD100, 0x0320,},
+	{0xD102, 0xD901,},
+	{0xD104, 0x07F1,},
+	{0xD106, 0x05E0,},
+	{0xD108, 0xC0A1,},
+	{0xD10A, 0x78E0,},
+	{0xD10C, 0xC0F1,},
+	{0xD10E, 0x71CF,},
+	{0xD110, 0xFFFF,},
+	{0xD112, 0xC7C0,},
+	{0xD114, 0xD840,},
+	{0xD116, 0xA900,},
+	{0xD118, 0x71CF,},
+	{0xD11A, 0xFFFF,},
+	{0xD11C, 0xD02C,},
+	{0xD11E, 0xD81E,},
+	{0xD120, 0x0A5A,},
+	{0xD122, 0x04E0,},
+	{0xD124, 0xDA00,},
+	{0xD126, 0xD800,},
+	{0xD128, 0xC0D1,},
+	{0xD12A, 0x7EE0,},
+	{0x098E, 0x0000,},
+
+	{0x0982, 0x0001,},
+	{0x098A, 0x5C10,},
+	{0xDC10, 0xC0F1,},
+	{0xDC12, 0x0CDA,},
+	{0xDC14, 0x0580,},
+	{0xDC16, 0x76CF,},
+	{0xDC18, 0xFF00,},
+	{0xDC1A, 0x2184,},
+	{0xDC1C, 0x9624,},
+	{0xDC1E, 0x218C,},
+	{0xDC20, 0x8FC3,},
+	{0xDC22, 0x75CF,},
+	{0xDC24, 0xFFFF,},
+	{0xDC26, 0xE058,},
+	{0xDC28, 0xF686,},
+	{0xDC2A, 0x1550,},
+	{0xDC2C, 0x1080,},
+	{0xDC2E, 0xE001,},
+	{0xDC30, 0x1D50,},
+	{0xDC32, 0x1002,},
+	{0xDC34, 0x1552,},
+	{0xDC36, 0x1100,},
+	{0xDC38, 0x6038,},
+	{0xDC3A, 0x1D52,},
+	{0xDC3C, 0x1004,},
+	{0xDC3E, 0x1540,},
+	{0xDC40, 0x1080,},
+	{0xDC42, 0x081B,},
+	{0xDC44, 0x00D1,},
+	{0xDC46, 0x8512,},
+	{0xDC48, 0x1000,},
+	{0xDC4A, 0x00C0,},
+	{0xDC4C, 0x7822,},
+	{0xDC4E, 0x2089,},
+	{0xDC50, 0x0FC1,},
+	{0xDC52, 0x2008,},
+	{0xDC54, 0x0F81,},
+	{0xDC56, 0xFFFF,},
+	{0xDC58, 0xFF80,},
+	{0xDC5A, 0x8512,},
+	{0xDC5C, 0x1801,},
+	{0xDC5E, 0x0052,},
+	{0xDC60, 0xA512,},
+	{0xDC62, 0x1544,},
+	{0xDC64, 0x1080,},
+	{0xDC66, 0xB861,},
+	{0xDC68, 0x262F,},
+	{0xDC6A, 0xF007,},
+	{0xDC6C, 0x1D44,},
+	{0xDC6E, 0x1002,},
+	{0xDC70, 0x20CA,},
+	{0xDC72, 0x0021,},
+	{0xDC74, 0x20CF,},
+	{0xDC76, 0x04E1,},
+	{0xDC78, 0x0850,},
+	{0xDC7A, 0x04A1,},
+	{0xDC7C, 0x21CA,},
+	{0xDC7E, 0x0021,},
+	{0xDC80, 0x1542,},
+	{0xDC82, 0x1140,},
+	{0xDC84, 0x8D2C,},
+	{0xDC86, 0x6038,},
+	{0xDC88, 0x1D42,},
+	{0xDC8A, 0x1004,},
+	{0xDC8C, 0x1542,},
+	{0xDC8E, 0x1140,},
+	{0xDC90, 0xB601,},
+	{0xDC92, 0x046D,},
+	{0xDC94, 0x0580,},
+	{0xDC96, 0x78E0,},
+	{0xDC98, 0xD800,},
+	{0xDC9A, 0xB893,},
+	{0xDC9C, 0x002D,},
+	{0xDC9E, 0x04A0,},
+	{0xDCA0, 0xD900,},
+	{0xDCA2, 0x78E0,},
+	{0xDCA4, 0x72CF,},
+	{0xDCA6, 0xFFFF,},
+	{0xDCA8, 0xE058,},
+	{0xDCAA, 0x2240,},
+	{0xDCAC, 0x0340,},
+	{0xDCAE, 0xA212,},
+	{0xDCB0, 0x208A,},
+	{0xDCB2, 0x0FFF,},
+	{0xDCB4, 0x1A42,},
+	{0xDCB6, 0x0004,},
+	{0xDCB8, 0xD830,},
+	{0xDCBA, 0x1A44,},
+	{0xDCBC, 0x0002,},
+	{0xDCBE, 0xD800,},
+	{0xDCC0, 0x1A50,},
+	{0xDCC2, 0x0002,},
+	{0xDCC4, 0x1A52,},
+	{0xDCC6, 0x0004,},
+	{0xDCC8, 0x1242,},
+	{0xDCCA, 0x0140,},
+	{0xDCCC, 0x8A2C,},
+	{0xDCCE, 0x6038,},
+	{0xDCD0, 0x1A42,},
+	{0xDCD2, 0x0004,},
+	{0xDCD4, 0x1242,},
+	{0xDCD6, 0x0141,},
+	{0xDCD8, 0x70CF,},
+	{0xDCDA, 0xFF00,},
+	{0xDCDC, 0x2184,},
+	{0xDCDE, 0xB021,},
+	{0xDCE0, 0xD800,},
+	{0xDCE2, 0xB893,},
+	{0xDCE4, 0x07E5,},
+	{0xDCE6, 0x0460,},
+	{0xDCE8, 0xD901,},
+	{0xDCEA, 0x78E0,},
+	{0xDCEC, 0xC0F1,},
+	{0xDCEE, 0x0BFA,},
+	{0xDCF0, 0x05A0,},
+	{0xDCF2, 0x216F,},
+	{0xDCF4, 0x0043,},
+	{0xDCF6, 0xC1A4,},
+	{0xDCF8, 0x220A,},
+	{0xDCFA, 0x1F80,},
+	{0xDCFC, 0xFFFF,},
+	{0xDCFE, 0xE058,},
+	{0xDD00, 0x2240,},
+	{0xDD02, 0x134F,},
+	{0xDD04, 0x1A48,},
+	{0xDD06, 0x13C0,},
+	{0xDD08, 0x1248,},
+	{0xDD0A, 0x1002,},
+	{0xDD0C, 0x70CF,},
+	{0xDD0E, 0x7FFF,},
+	{0xDD10, 0xFFFF,},
+	{0xDD12, 0xE230,},
+	{0xDD14, 0xC240,},
+	{0xDD16, 0xDA00,},
+	{0xDD18, 0xF00C,},
+	{0xDD1A, 0x1248,},
+	{0xDD1C, 0x1003,},
+	{0xDD1E, 0x1301,},
+	{0xDD20, 0x04CB,},
+	{0xDD22, 0x7261,},
+	{0xDD24, 0x2108,},
+	{0xDD26, 0x0081,},
+	{0xDD28, 0x2009,},
+	{0xDD2A, 0x0080,},
+	{0xDD2C, 0x1A48,},
+	{0xDD2E, 0x10C0,},
+	{0xDD30, 0x1248,},
+	{0xDD32, 0x100B,},
+	{0xDD34, 0xC300,},
+	{0xDD36, 0x0BE7,},
+	{0xDD38, 0x90C4,},
+	{0xDD3A, 0x2102,},
+	{0xDD3C, 0x0003,},
+	{0xDD3E, 0x238C,},
+	{0xDD40, 0x8FC3,},
+	{0xDD42, 0xF6C7,},
+	{0xDD44, 0xDAFF,},
+	{0xDD46, 0x1A05,},
+	{0xDD48, 0x1082,},
+	{0xDD4A, 0xC241,},
+	{0xDD4C, 0xF005,},
+	{0xDD4E, 0x7A6F,},
+	{0xDD50, 0xC241,},
+	{0xDD52, 0x1A05,},
+	{0xDD54, 0x10C2,},
+	{0xDD56, 0x2000,},
+	{0xDD58, 0x8040,},
+	{0xDD5A, 0xDA00,},
+	{0xDD5C, 0x20C0,},
+	{0xDD5E, 0x0064,},
+	{0xDD60, 0x781C,},
+	{0xDD62, 0xC042,},
+	{0xDD64, 0x1C0E,},
+	{0xDD66, 0x3082,},
+	{0xDD68, 0x1A48,},
+	{0xDD6A, 0x13C0,},
+	{0xDD6C, 0x7548,},
+	{0xDD6E, 0x7348,},
+	{0xDD70, 0x7148,},
+	{0xDD72, 0x7648,},
+	{0xDD74, 0xF002,},
+	{0xDD76, 0x7608,},
+	{0xDD78, 0x1248,},
+	{0xDD7A, 0x1000,},
+	{0xDD7C, 0x1400,},
+	{0xDD7E, 0x300B,},
+	{0xDD80, 0x084D,},
+	{0xDD82, 0x02C5,},
+	{0xDD84, 0x1248,},
+	{0xDD86, 0x1000,},
+	{0xDD88, 0xE101,},
+	{0xDD8A, 0x1001,},
+	{0xDD8C, 0x04CB,},
+	{0xDD8E, 0x1A48,},
+	{0xDD90, 0x1000,},
+	{0xDD92, 0x7361,},
+	{0xDD94, 0x1408,},
+	{0xDD96, 0x300B,},
+	{0xDD98, 0x2302,},
+	{0xDD9A, 0x02C0,},
+	{0xDD9C, 0x780D,},
+	{0xDD9E, 0x2607,},
+	{0xDDA0, 0x903E,},
+	{0xDDA2, 0x07D6,},
+	{0xDDA4, 0xFFE3,},
+	{0xDDA6, 0x792F,},
+	{0xDDA8, 0x09CF,},
+	{0xDDAA, 0x8152,},
+	{0xDDAC, 0x1248,},
+	{0xDDAE, 0x100E,},
+	{0xDDB0, 0x2400,},
+	{0xDDB2, 0x334B,},
+	{0xDDB4, 0xE501,},
+	{0xDDB6, 0x7EE2,},
+	{0xDDB8, 0x0DBF,},
+	{0xDDBA, 0x90F2,},
+	{0xDDBC, 0x1B0C,},
+	{0xDDBE, 0x1382,},
+	{0xDDC0, 0xC123,},
+	{0xDDC2, 0x140E,},
+	{0xDDC4, 0x3080,},
+	{0xDDC6, 0x7822,},
+	{0xDDC8, 0x1A07,},
+	{0xDDCA, 0x1002,},
+	{0xDDCC, 0x124C,},
+	{0xDDCE, 0x1000,},
+	{0xDDD0, 0x120B,},
+	{0xDDD2, 0x1081,},
+	{0xDDD4, 0x1207,},
+	{0xDDD6, 0x1083,},
+	{0xDDD8, 0x2142,},
+	{0xDDDA, 0x004B,},
+	{0xDDDC, 0x781B,},
+	{0xDDDE, 0x0B21,},
+	{0xDDE0, 0x02E2,},
+	{0xDDE2, 0x1A4C,},
+	{0xDDE4, 0x1000,},
+	{0xDDE6, 0xE101,},
+	{0xDDE8, 0x0915,},
+	{0xDDEA, 0x00C2,},
+	{0xDDEC, 0xC101,},
+	{0xDDEE, 0x1204,},
+	{0xDDF0, 0x1083,},
+	{0xDDF2, 0x090D,},
+	{0xDDF4, 0x00C2,},
+	{0xDDF6, 0xE001,},
+	{0xDDF8, 0x1A4C,},
+	{0xDDFA, 0x1000,},
+	{0xDDFC, 0x1A06,},
+	{0xDDFE, 0x1002,},
+	{0xDE00, 0x234A,},
+	{0xDE02, 0x1000,},
+	{0xDE04, 0x7169,},
+	{0xDE06, 0xF008,},
+	{0xDE08, 0x2053,},
+	{0xDE0A, 0x0003,},
+	{0xDE0C, 0x6179,},
+	{0xDE0E, 0x781C,},
+	{0xDE10, 0x2340,},
+	{0xDE12, 0x104B,},
+	{0xDE14, 0x1203,},
+	{0xDE16, 0x1083,},
+	{0xDE18, 0x0BF1,},
+	{0xDE1A, 0x90C2,},
+	{0xDE1C, 0x1202,},
+	{0xDE1E, 0x1080,},
+	{0xDE20, 0x091D,},
+	{0xDE22, 0x0004,},
+	{0xDE24, 0x70CF,},
+	{0xDE26, 0xFFFF,},
+	{0xDE28, 0xC644,},
+	{0xDE2A, 0x881B,},
+	{0xDE2C, 0xE0B2,},
+	{0xDE2E, 0xD83C,},
+	{0xDE30, 0x20CA,},
+	{0xDE32, 0x0CA2,},
+	{0xDE34, 0x1A01,},
+	{0xDE36, 0x1002,},
+	{0xDE38, 0x1A4C,},
+	{0xDE3A, 0x1080,},
+	{0xDE3C, 0x02B9,},
+	{0xDE3E, 0x05A0,},
+	{0xDE40, 0xC0A4,},
+	{0xDE42, 0x78E0,},
+	{0xDE44, 0xC0F1,},
+	{0xDE46, 0xFF95,},
+	{0xDE48, 0xD800,},
+	{0xDE4A, 0x71CF,},
+	{0xDE4C, 0xFF00,},
+	{0xDE4E, 0x1FE0,},
+	{0xDE50, 0x19D0,},
+	{0xDE52, 0x001C,},
+	{0xDE54, 0x19D1,},
+	{0xDE56, 0x001C,},
+	{0xDE58, 0x70CF,},
+	{0xDE5A, 0xFFFF,},
+	{0xDE5C, 0xE058,},
+	{0xDE5E, 0x901F,},
+	{0xDE60, 0xB861,},
+	{0xDE62, 0x19D2,},
+	{0xDE64, 0x001C,},
+	{0xDE66, 0xC0D1,},
+	{0xDE68, 0x7EE0,},
+	{0xDE6A, 0x78E0,},
+	{0xDE6C, 0xC0F1,},
+	{0xDE6E, 0x0A7A,},
+	{0xDE70, 0x0580,},
+	{0xDE72, 0x70CF,},
+	{0xDE74, 0xFFFF,},
+	{0xDE76, 0xC5D4,},
+	{0xDE78, 0x9041,},
+	{0xDE7A, 0x9023,},
+	{0xDE7C, 0x75CF,},
+	{0xDE7E, 0xFFFF,},
+	{0xDE80, 0xE058,},
+	{0xDE82, 0x7942,},
+	{0xDE84, 0xB967,},
+	{0xDE86, 0x7F30,},
+	{0xDE88, 0xB53F,},
+	{0xDE8A, 0x71CF,},
+	{0xDE8C, 0xFFFF,},
+	{0xDE8E, 0xC84C,},
+	{0xDE90, 0x91D3,},
+	{0xDE92, 0x108B,},
+	{0xDE94, 0x0081,},
+	{0xDE96, 0x2615,},
+	{0xDE98, 0x1380,},
+	{0xDE9A, 0x090F,},
+	{0xDE9C, 0x0C91,},
+	{0xDE9E, 0x0A8E,},
+	{0xDEA0, 0x05A0,},
+	{0xDEA2, 0xD906,},
+	{0xDEA4, 0x7E10,},
+	{0xDEA6, 0x2615,},
+	{0xDEA8, 0x1380,},
+	{0xDEAA, 0x0A82,},
+	{0xDEAC, 0x05A0,},
+	{0xDEAE, 0xD960,},
+	{0xDEB0, 0x790F,},
+	{0xDEB2, 0x090D,},
+	{0xDEB4, 0x0133,},
+	{0xDEB6, 0xAD0C,},
+	{0xDEB8, 0xD904,},
+	{0xDEBA, 0xAD2C,},
+	{0xDEBC, 0x79EC,},
+	{0xDEBE, 0x2941,},
+	{0xDEC0, 0x7402,},
+	{0xDEC2, 0x71CF,},
+	{0xDEC4, 0xFF00,},
+	{0xDEC6, 0x2184,},
+	{0xDEC8, 0xB142,},
+	{0xDECA, 0x1906,},
+	{0xDECC, 0x0E44,},
+	{0xDECE, 0xFFDE,},
+	{0xDED0, 0x70C9,},
+	{0xDED2, 0x0A5A,},
+	{0xDED4, 0x05A0,},
+	{0xDED6, 0x8D2C,},
+	{0xDED8, 0xAD0B,},
+	{0xDEDA, 0xD800,},
+	{0xDEDC, 0xAD01,},
+	{0xDEDE, 0x0219,},
+	{0xDEE0, 0x05A0,},
+	{0xDEE2, 0xA513,},
+	{0xDEE4, 0xC0F1,},
+	{0xDEE6, 0x71CF,},
+	{0xDEE8, 0xFFFF,},
+	{0xDEEA, 0xC644,},
+	{0xDEEC, 0xA91B,},
+	{0xDEEE, 0xD902,},
+	{0xDEF0, 0x70CF,},
+	{0xDEF2, 0xFFFF,},
+	{0xDEF4, 0xC84C,},
+	{0xDEF6, 0x093E,},
+	{0xDEF8, 0x03A0,},
+	{0xDEFA, 0xA826,},
+	{0xDEFC, 0xFFDC,},
+	{0xDEFE, 0xF1B5,},
+	{0xDF00, 0xC0F1,},
+	{0xDF02, 0x09EA,},
+	{0xDF04, 0x0580,},
+	{0xDF06, 0x75CF,},
+	{0xDF08, 0xFFFF,},
+	{0xDF0A, 0xE058,},
+	{0xDF0C, 0x1540,},
+	{0xDF0E, 0x1080,},
+	{0xDF10, 0x08A7,},
+	{0xDF12, 0x0010,},
+	{0xDF14, 0x8D00,},
+	{0xDF16, 0x0813,},
+	{0xDF18, 0x009E,},
+	{0xDF1A, 0x1540,},
+	{0xDF1C, 0x1081,},
+	{0xDF1E, 0xE181,},
+	{0xDF20, 0x20CA,},
+	{0xDF22, 0x00A1,},
+	{0xDF24, 0xF24B,},
+	{0xDF26, 0x1540,},
+	{0xDF28, 0x1081,},
+	{0xDF2A, 0x090F,},
+	{0xDF2C, 0x0050,},
+	{0xDF2E, 0x1540,},
+	{0xDF30, 0x1081,},
+	{0xDF32, 0x0927,},
+	{0xDF34, 0x0091,},
+	{0xDF36, 0x1550,},
+	{0xDF38, 0x1081,},
+	{0xDF3A, 0xDE00,},
+	{0xDF3C, 0xAD2A,},
+	{0xDF3E, 0x1D50,},
+	{0xDF40, 0x1382,},
+	{0xDF42, 0x1552,},
+	{0xDF44, 0x1101,},
+	{0xDF46, 0x1D52,},
+	{0xDF48, 0x1384,},
+	{0xDF4A, 0xB524,},
+	{0xDF4C, 0x082D,},
+	{0xDF4E, 0x015F,},
+	{0xDF50, 0xFF55,},
+	{0xDF52, 0xD803,},
+	{0xDF54, 0xF033,},
+	{0xDF56, 0x1540,},
+	{0xDF58, 0x1081,},
+	{0xDF5A, 0x0967,},
+	{0xDF5C, 0x00D1,},
+	{0xDF5E, 0x1550,},
+	{0xDF60, 0x1081,},
+	{0xDF62, 0xDE00,},
+	{0xDF64, 0xAD2A,},
+	{0xDF66, 0x1D50,},
+	{0xDF68, 0x1382,},
+	{0xDF6A, 0x1552,},
+	{0xDF6C, 0x1101,},
+	{0xDF6E, 0x1D52,},
+	{0xDF70, 0x1384,},
+	{0xDF72, 0xB524,},
+	{0xDF74, 0x0811,},
+	{0xDF76, 0x019E,},
+	{0xDF78, 0xB8A0,},
+	{0xDF7A, 0xAD00,},
+	{0xDF7C, 0xFF47,},
+	{0xDF7E, 0x1D40,},
+	{0xDF80, 0x1382,},
+	{0xDF82, 0xF01F,},
+	{0xDF84, 0xFF5A,},
+	{0xDF86, 0x8D01,},
+	{0xDF88, 0x8D40,},
+	{0xDF8A, 0xE812,},
+	{0xDF8C, 0x71CF,},
+	{0xDF8E, 0xFFFF,},
+	{0xDF90, 0xC644,},
+	{0xDF92, 0x893B,},
+	{0xDF94, 0x7030,},
+	{0xDF96, 0x22D1,},
+	{0xDF98, 0x8062,},
+	{0xDF9A, 0xF20A,},
+	{0xDF9C, 0x0A0F,},
+	{0xDF9E, 0x009E,},
+	{0xDFA0, 0x71CF,},
+	{0xDFA2, 0xFFFF,},
+	{0xDFA4, 0xC84C,},
+	{0xDFA6, 0x893B,},
+	{0xDFA8, 0xE902,},
+	{0xDFAA, 0xFFCF,},
+	{0xDFAC, 0x8D00,},
+	{0xDFAE, 0xB8E7,},
+	{0xDFB0, 0x26CA,},
+	{0xDFB2, 0x1022,},
+	{0xDFB4, 0xF5E2,},
+	{0xDFB6, 0xFF3C,},
+	{0xDFB8, 0xD801,},
+	{0xDFBA, 0x1D40,},
+	{0xDFBC, 0x1002,},
+	{0xDFBE, 0x0141,},
+	{0xDFC0, 0x0580,},
+	{0xDFC2, 0x78E0,},
+	{0xDFC4, 0xC0F1,},
+	{0xDFC6, 0xC5E1,},
+	{0xDFC8, 0xFF34,},
+	{0xDFCA, 0xDD00,},
+	{0xDFCC, 0x70CF,},
+	{0xDFCE, 0xFFFF,},
+	{0xDFD0, 0xE090,},
+	{0xDFD2, 0xA8A8,},
+	{0xDFD4, 0xD800,},
+	{0xDFD6, 0xB893,},
+	{0xDFD8, 0x0C8A,},
+	{0xDFDA, 0x0460,},
+	{0xDFDC, 0xD901,},
+	{0xDFDE, 0x71CF,},
+	{0xDFE0, 0xFFFF,},
+	{0xDFE2, 0xDC10,},
+	{0xDFE4, 0xD813,},
+	{0xDFE6, 0x0B96,},
+	{0xDFE8, 0x0460,},
+	{0xDFEA, 0x72A9,},
+	{0xDFEC, 0x0119,},
+	{0xDFEE, 0x0580,},
+	{0xDFF0, 0xC0F1,},
+	{0xDFF2, 0x71CF,},
+	{0xDFF4, 0x0000,},
+	{0xDFF6, 0x5BAE,},
+	{0xDFF8, 0x7940,},
+	{0xDFFA, 0xFF9D,},
+	{0xDFFC, 0xF135,},
+	{0xDFFE, 0x78E0,},
+	{0xE000, 0xC0F1,},
+	{0xE002, 0x70CF,},
+	{0xE004, 0x0000,},
+	{0xE006, 0x5CBA,},
+	{0xE008, 0x7840,},
+	{0xE00A, 0x70CF,},
+	{0xE00C, 0xFFFF,},
+	{0xE00E, 0xE058,},
+	{0xE010, 0x8800,},
+	{0xE012, 0x0815,},
+	{0xE014, 0x001E,},
+	{0xE016, 0x70CF,},
+	{0xE018, 0xFFFF,},
+	{0xE01A, 0xC84C,},
+	{0xE01C, 0x881A,},
+	{0xE01E, 0xE080,},
+	{0xE020, 0x0EE0,},
+	{0xE022, 0xFFC1,},
+	{0xE024, 0xF121,},
+	{0xE026, 0x78E0,},
+	{0xE028, 0xC0F1,},
+	{0xE02A, 0xD900,},
+	{0xE02C, 0xF009,},
+	{0xE02E, 0x70CF,},
+	{0xE030, 0xFFFF,},
+	{0xE032, 0xE0AC,},
+	{0xE034, 0x7835,},
+	{0xE036, 0x8041,},
+	{0xE038, 0x8000,},
+	{0xE03A, 0xE102,},
+	{0xE03C, 0xA040,},
+	{0xE03E, 0x09F3,},
+	{0xE040, 0x8114,},
+	{0xE042, 0x71CF,},
+	{0xE044, 0xFFFF,},
+	{0xE046, 0xE058,},
+	{0xE048, 0x70CF,},
+	{0xE04A, 0xFFFF,},
+	{0xE04C, 0xC594,},
+	{0xE04E, 0xB030,},
+	{0xE050, 0xFFDD,},
+	{0xE052, 0xD800,},
+	{0xE054, 0xF109,},
+	{0xE056, 0x0000,},
+	{0xE058, 0x0300,},
+	{0xE05A, 0x0204,},
+	{0xE05C, 0x0700,},
+	{0xE05E, 0x0000,},
+	{0xE060, 0x0000,},
+	{0xE062, 0x0000,},
+	{0xE064, 0x0000,},
+	{0xE066, 0x0000,},
+	{0xE068, 0x0000,},
+	{0xE06A, 0x0000,},
+	{0xE06C, 0x0000,},
+	{0xE06E, 0x0000,},
+	{0xE070, 0x0000,},
+	{0xE072, 0x0000,},
+	{0xE074, 0x0000,},
+	{0xE076, 0x0000,},
+	{0xE078, 0x0000,},
+	{0xE07A, 0x0000,},
+	{0xE07C, 0x0000,},
+	{0xE07E, 0x0000,},
+	{0xE080, 0x0000,},
+	{0xE082, 0x0000,},
+	{0xE084, 0x0000,},
+	{0xE086, 0x0000,},
+	{0xE088, 0x0000,},
+	{0xE08A, 0x0000,},
+	{0xE08C, 0x0000,},
+	{0xE08E, 0x0000,},
+	{0xE090, 0x0000,},
+	{0xE092, 0x0000,},
+	{0xE094, 0x0000,},
+	{0xE096, 0x0000,},
+	{0xE098, 0x0000,},
+	{0xE09A, 0x0000,},
+	{0xE09C, 0x0000,},
+	{0xE09E, 0x0000,},
+	{0xE0A0, 0x0000,},
+	{0xE0A2, 0x0000,},
+	{0xE0A4, 0x0000,},
+	{0xE0A6, 0x0000,},
+	{0xE0A8, 0x0000,},
+	{0xE0AA, 0x0000,},
+	{0xE0AC, 0xFFFF,},
+	{0xE0AE, 0xCB68,},
+	{0xE0B0, 0xFFFF,},
+	{0xE0B2, 0xDFF0,},
+	{0xE0B4, 0xFFFF,},
+	{0xE0B6, 0xCB6C,},
+	{0xE0B8, 0xFFFF,},
+	{0xE0BA, 0xE000,},
+	{0x098E, 0x0000,},
+
+	/*MIPI setting for SOC1040*/
+	{0x3C5A, 0x0009,},
+	{0x3C44, 0x0080,},/*MIPI_CUSTOM_SHORT_PKT*/
+
+	/*[Tuning_settings]*/
+
+	/*[CCM]*/
+	{0xC892, 0x0267,},/*CAM_AWB_CCM_L_0*/
+	{0xC894, 0xFF1A,},/*CAM_AWB_CCM_L_1*/
+	{0xC896, 0xFFB3,},/*CAM_AWB_CCM_L_2*/
+	{0xC898, 0xFF80,},/*CAM_AWB_CCM_L_3*/
+	{0xC89A, 0x0166,},/*CAM_AWB_CCM_L_4*/
+	{0xC89C, 0x0003,},/*CAM_AWB_CCM_L_5*/
+	{0xC89E, 0xFF9A,},/*CAM_AWB_CCM_L_6*/
+	{0xC8A0, 0xFEB4,},/*CAM_AWB_CCM_L_7*/
+	{0xC8A2, 0x024D,},/*CAM_AWB_CCM_L_8*/
+	{0xC8A4, 0x01BF,},/*CAM_AWB_CCM_M_0*/
+	{0xC8A6, 0xFF01,},/*CAM_AWB_CCM_M_1*/
+	{0xC8A8, 0xFFF3,},/*CAM_AWB_CCM_M_2*/
+	{0xC8AA, 0xFF75,},/*CAM_AWB_CCM_M_3*/
+	{0xC8AC, 0x0198,},/*CAM_AWB_CCM_M_4*/
+	{0xC8AE, 0xFFFD,},/*CAM_AWB_CCM_M_5*/
+	{0xC8B0, 0xFF9A,},/*CAM_AWB_CCM_M_6*/
+	{0xC8B2, 0xFEE7,},/*CAM_AWB_CCM_M_7*/
+	{0xC8B4, 0x02A8,},/*CAM_AWB_CCM_M_8*/
+	{0xC8B6, 0x01D9,},/*CAM_AWB_CCM_R_0*/
+	{0xC8B8, 0xFF26,},/*CAM_AWB_CCM_R_1*/
+	{0xC8BA, 0xFFF3,},/*CAM_AWB_CCM_R_2*/
+	{0xC8BC, 0xFFB3,},/*CAM_AWB_CCM_R_3*/
+	{0xC8BE, 0x0132,},/*CAM_AWB_CCM_R_4*/
+	{0xC8C0, 0xFFE8,},/*CAM_AWB_CCM_R_5*/
+	{0xC8C2, 0xFFDA,},/*CAM_AWB_CCM_R_6*/
+	{0xC8C4, 0xFECD,},/*CAM_AWB_CCM_R_7*/
+	{0xC8C6, 0x02C2,},/*CAM_AWB_CCM_R_8*/
+	{0xC8C8, 0x0075,},/*CAM_AWB_CCM_L_RG_GAIN*/
+	{0xC8CA, 0x011C,},/*CAM_AWB_CCM_L_BG_GAIN*/
+	{0xC8CC, 0x009A,},/*CAM_AWB_CCM_M_RG_GAIN*/
+	{0xC8CE, 0x0105,},/*CAM_AWB_CCM_M_BG_GAIN*/
+	{0xC8D0, 0x00A4,},/*CAM_AWB_CCM_R_RG_GAIN*/
+	{0xC8D2, 0x00AC,},/*CAM_AWB_CCM_R_BG_GAIN*/
+	{0xC8D4, 0x0A8C,},/*CAM_AWB_CCM_L_CTEMP*/
+	{0xC8D6, 0x0F0A,},/*CAM_AWB_CCM_M_CTEMP*/
+	{0xC8D8, 0x1964,},/*CAM_AWB_CCM_R_CTEMP*/
+
+	/*[AWB]*/
+	{0xC914, 0x0000,},/*CAM_STAT_AWB_CLIP_WINDOW_XSTART*/
+	{0xC916, 0x0000,},/*CAM_STAT_AWB_CLIP_WINDOW_YSTART*/
+	{0xC918, 0x04FF,},/*CAM_STAT_AWB_CLIP_WINDOW_XEND*/
+	{0xC91A, 0x02CF,},/*CAM_STAT_AWB_CLIP_WINDOW_YEND*/
+	{0xC904, 0x0033,},/*CAM_AWB_AWB_XSHIFT_PRE_ADJ*/
+	{0xC906, 0x0040,},/*CAM_AWB_AWB_YSHIFT_PRE_ADJ*/
+	{0xC8F2, 0x03, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_AWB_AWB_XSCALE*/
+	{0xC8F3, 0x02, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_AWB_AWB_YSCALE*/
+	{0xC906, 0x003C,},/*CAM_AWB_AWB_YSHIFT_PRE_ADJ*/
+	{0xC8F4, 0x0000,},/*CAM_AWB_AWB_WEIGHTS_0*/
+	{0xC8F6, 0x0000,},/*CAM_AWB_AWB_WEIGHTS_1*/
+	{0xC8F8, 0x0000,},/*CAM_AWB_AWB_WEIGHTS_2*/
+	{0xC8FA, 0xE724,},/*CAM_AWB_AWB_WEIGHTS_3*/
+	{0xC8FC, 0x1583,},/*CAM_AWB_AWB_WEIGHTS_4*/
+	{0xC8FE, 0x2045,},/*CAM_AWB_AWB_WEIGHTS_5*/
+	{0xC900, 0x03FF,},/*CAM_AWB_AWB_WEIGHTS_6*/
+	{0xC902, 0x007C,},/*CAM_AWB_AWB_WEIGHTS_7*/
+	{0xC90C, 0x80, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_AWB_K_R_L*/
+	{0xC90D, 0x80, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_AWB_K_G_L*/
+	{0xC90E, 0x80, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_AWB_K_B_L*/
+	{0xC90F, 0x88, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_AWB_K_R_R*/
+	{0xC910, 0x80, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_AWB_K_G_R*/
+	{0xC911, 0x80, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_AWB_K_B_R*/
+
+	/*[Step7-CPIPE_Preference]*/
+	{0xC926, 0x0020,},/*CAM_LL_START_BRIGHTNESS*/
+	{0xC928, 0x009A,},/*CAM_LL_STOP_BRIGHTNESS*/
+	{0xC946, 0x0070,},/*CAM_LL_START_GAIN_METRIC*/
+	{0xC948, 0x00F3,},/*CAM_LL_STOP_GAIN_METRIC*/
+	{0xC952, 0x0020,},/*CAM_LL_START_TARGET_LUMA_BM*/
+	{0xC954, 0x009A,},/*CAM_LL_STOP_TARGET_LUMA_BM*/
+	{0xC92A, 0x80, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_SATURATION*/
+	{0xC92B, 0x4B, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_END_SATURATION*/
+	{0xC92C, 0x00, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_DESATURATION*/
+	{0xC92D, 0xFF, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_END_DESATURATION*/
+	{0xC92E, 0x3C, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_DEMOSAIC*/
+	{0xC92F, 0x02, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_AP_GAIN*/
+	{0xC930, 0x06, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_AP_THRESH*/
+	{0xC931, 0x64, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_STOP_DEMOSAIC*/
+	{0xC932, 0x01, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_STOP_AP_GAIN*/
+	{0xC933, 0x0C, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_STOP_AP_THRESH*/
+	{0xC934, 0x3C, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_NR_RED*/
+	{0xC935, 0x3C, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_NR_GREEN*/
+	{0xC936, 0x3C, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_NR_BLUE*/
+	{0xC937, 0x0F, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_NR_THRESH*/
+	{0xC938, 0x64, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_STOP_NR_RED*/
+	{0xC939, 0x64, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_STOP_NR_GREEN*/
+	{0xC93A, 0x64, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_STOP_NR_BLUE*/
+	{0xC93B, 0x32, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_STOP_NR_THRESH*/
+	{0xC93C, 0x0020,},/*CAM_LL_START_CONTRAST_BM*/
+	{0xC93E, 0x009A,},/*CAM_LL_STOP_CONTRAST_BM*/
+	{0xC940, 0x00DC,},/*CAM_LL_GAMMA*/
+	/*CAM_LL_START_CONTRAST_GRADIENT*/
+	{0xC942, 0x38, MSM_CAMERA_I2C_BYTE_DATA},
+	/*CAM_LL_STOP_CONTRAST_GRADIENT*/
+	{0xC943, 0x30, MSM_CAMERA_I2C_BYTE_DATA},
+	{0xC944, 0x50, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_CONTRAST_LUMA*/
+	{0xC945, 0x19, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_STOP_CONTRAST_LUMA*/
+	{0xC94A, 0x0230,},/*CAM_LL_START_FADE_TO_BLACK_LUMA*/
+	{0xC94C, 0x0010,},/*CAM_LL_STOP_FADE_TO_BLACK_LUMA*/
+	{0xC94E, 0x01CD,},/*CAM_LL_CLUSTER_DC_TH_BM*/
+	{0xC950, 0x05, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_CLUSTER_DC_GATE*/
+	{0xC951, 0x40, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_SUMMING_SENSITIVITY*/
+	/*CAM_AET_TARGET_AVERAGE_LUMA_DARK*/
+	{0xC87B, 0x1B, MSM_CAMERA_I2C_BYTE_DATA},
+	{0xC878, 0x0E, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_AET_AEMODE*/
+	{0xC890, 0x0080,},/*CAM_AET_TARGET_GAIN*/
+	{0xC886, 0x0100,},/*CAM_AET_AE_MAX_VIRT_AGAIN*/
+	{0xC87C, 0x005A,},/*CAM_AET_BLACK_CLIPPING_TARGET*/
+	{0xB42A, 0x05, MSM_CAMERA_I2C_BYTE_DATA},/*CCM_DELTA_GAIN*/
+	/*AE_TRACK_AE_TRACKING_DAMPENING*/
+	{0xA80A, 0x20, MSM_CAMERA_I2C_BYTE_DATA},
+	{0x3C44, 0x0080,},
+	{0x3C40, 0x0004, MSM_CAMERA_I2C_UNSET_WORD_MASK},
+	{0xA802, 0x08, MSM_CAMERA_I2C_SET_BYTE_MASK},
+	{0xC908, 0x01, MSM_CAMERA_I2C_BYTE_DATA},
+	{0xC879, 0x01, MSM_CAMERA_I2C_BYTE_DATA},
+	{0xC909, 0x01, MSM_CAMERA_I2C_UNSET_BYTE_MASK},
+	{0xA80A, 0x18, MSM_CAMERA_I2C_BYTE_DATA},
+	{0xA80B, 0x18, MSM_CAMERA_I2C_BYTE_DATA},
+	{0xAC16, 0x18, MSM_CAMERA_I2C_BYTE_DATA},
+	{0xC878, 0x08, MSM_CAMERA_I2C_SET_BYTE_MASK},
+	{0xBC02, 0x08, MSM_CAMERA_I2C_UNSET_BYTE_MASK},
+};
+
+static struct v4l2_subdev_info mt9m114_subdev_info[] = {
+	{
+		.code   = V4L2_MBUS_FMT_YUYV8_2X8,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.fmt    = 1,
+		.order    = 0,
+	},
+};
+
+static struct msm_camera_i2c_reg_conf mt9m114_config_change_settings[] = {
+	{0xdc00, 0x28, MSM_CAMERA_I2C_BYTE_DATA, MSM_CAMERA_I2C_CMD_WRITE},
+	{MT9M114_COMMAND_REGISTER, MT9M114_COMMAND_REGISTER_SET_STATE,
+		MSM_CAMERA_I2C_UNSET_WORD_MASK, MSM_CAMERA_I2C_CMD_POLL},
+	{MT9M114_COMMAND_REGISTER, (MT9M114_COMMAND_REGISTER_OK |
+		MT9M114_COMMAND_REGISTER_SET_STATE), MSM_CAMERA_I2C_WORD_DATA,
+		MSM_CAMERA_I2C_CMD_WRITE},
+	{MT9M114_COMMAND_REGISTER, MT9M114_COMMAND_REGISTER_SET_STATE,
+		MSM_CAMERA_I2C_UNSET_WORD_MASK, MSM_CAMERA_I2C_CMD_POLL},
+	{0xDC01, 0x31, MSM_CAMERA_I2C_BYTE_DATA},
+};
+
+static const struct i2c_device_id mt9m114_i2c_id[] = {
+	{MT9M114_SENSOR_NAME, (kernel_ulong_t)&mt9m114_s_ctrl},
+	{ }
+};
+
+static struct i2c_driver mt9m114_i2c_driver = {
+	.id_table = mt9m114_i2c_id,
+	.probe  = msm_sensor_i2c_probe,
+	.driver = {
+		.name = MT9M114_SENSOR_NAME,
+	},
+};
+
+static struct msm_camera_i2c_client mt9m114_sensor_i2c_client = {
+	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+static const struct of_device_id mt9m114_dt_match[] = {
+	{.compatible = "qcom,mt9m114", .data = &mt9m114_s_ctrl},
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, mt9m114_dt_match);
+
+static struct platform_driver mt9m114_platform_driver = {
+	.driver = {
+		.name = "qcom,mt9m114",
+		.owner = THIS_MODULE,
+		.of_match_table = mt9m114_dt_match,
+	},
+};
+
+static int32_t mt9m114_platform_probe(struct platform_device *pdev)
+{
+	int32_t rc;
+	const struct of_device_id *match;
+	match = of_match_device(mt9m114_dt_match, &pdev->dev);
+	rc = msm_sensor_platform_probe(pdev, match->data);
+	return rc;
+}
+
+static int __init mt9m114_init_module(void)
+{
+	int32_t rc;
+	pr_info("%s:%d\n", __func__, __LINE__);
+	rc = platform_driver_probe(&mt9m114_platform_driver,
+		mt9m114_platform_probe);
+	if (!rc)
+		return rc;
+	pr_err("%s:%d rc %d\n", __func__, __LINE__, rc);
+	return i2c_add_driver(&mt9m114_i2c_driver);
+}
+
+static void __exit mt9m114_exit_module(void)
+{
+	pr_info("%s:%d\n", __func__, __LINE__);
+	if (mt9m114_s_ctrl.pdev) {
+		msm_sensor_free_sensor_data(&mt9m114_s_ctrl);
+		platform_driver_unregister(&mt9m114_platform_driver);
+	} else
+		i2c_del_driver(&mt9m114_i2c_driver);
+	return;
+}
+
+int32_t mt9m114_sensor_config(struct msm_sensor_ctrl_t *s_ctrl,
+	void __user *argp)
+{
+	struct sensorb_cfg_data *cdata = (struct sensorb_cfg_data *)argp;
+	long rc = 0;
+	int32_t i = 0;
+	mutex_lock(s_ctrl->msm_sensor_mutex);
+	CDBG("%s:%d %s cfgtype = %d\n", __func__, __LINE__,
+		s_ctrl->sensordata->sensor_name, cdata->cfgtype);
+	switch (cdata->cfgtype) {
+	case CFG_GET_SENSOR_INFO:
+		memcpy(cdata->cfg.sensor_info.sensor_name,
+			s_ctrl->sensordata->sensor_name,
+			sizeof(cdata->cfg.sensor_info.sensor_name));
+		cdata->cfg.sensor_info.session_id =
+			s_ctrl->sensordata->sensor_info->session_id;
+		for (i = 0; i < SUB_MODULE_MAX; i++)
+			cdata->cfg.sensor_info.subdev_id[i] =
+				s_ctrl->sensordata->sensor_info->subdev_id[i];
+		CDBG("%s:%d sensor name %s\n", __func__, __LINE__,
+			cdata->cfg.sensor_info.sensor_name);
+		CDBG("%s:%d session id %d\n", __func__, __LINE__,
+			cdata->cfg.sensor_info.session_id);
+		for (i = 0; i < SUB_MODULE_MAX; i++)
+			CDBG("%s:%d subdev_id[%d] %d\n", __func__, __LINE__, i,
+				cdata->cfg.sensor_info.subdev_id[i]);
+
+		break;
+	case CFG_SET_INIT_SETTING:
+		/* 1. Write Recommend settings */
+		/* 2. Write change settings */
+		rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->
+			i2c_write_conf_tbl(
+			s_ctrl->sensor_i2c_client, mt9m114_recommend_settings,
+			ARRAY_SIZE(mt9m114_recommend_settings),
+			MSM_CAMERA_I2C_WORD_DATA);
+		rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->
+			i2c_write_conf_tbl(
+			s_ctrl->sensor_i2c_client,
+			mt9m114_config_change_settings,
+			ARRAY_SIZE(mt9m114_config_change_settings),
+			MSM_CAMERA_I2C_WORD_DATA);
+		break;
+	case CFG_SET_RESOLUTION:
+		rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->
+			i2c_write_conf_tbl(
+			s_ctrl->sensor_i2c_client, mt9m114_720p_settings,
+			ARRAY_SIZE(mt9m114_720p_settings),
+			MSM_CAMERA_I2C_WORD_DATA);
+		break;
+	case CFG_SET_STOP_STREAM:
+		break;
+	case CFG_SET_START_STREAM:
+		rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->
+			i2c_write_conf_tbl(
+			s_ctrl->sensor_i2c_client,
+			mt9m114_config_change_settings,
+			ARRAY_SIZE(mt9m114_config_change_settings),
+			MSM_CAMERA_I2C_WORD_DATA);
+		break;
+	case CFG_GET_SENSOR_INIT_PARAMS:
+		cdata->cfg.sensor_init_params =
+			*s_ctrl->sensordata->sensor_init_params;
+		CDBG("%s:%d init params mode %d pos %d mount %d\n", __func__,
+			__LINE__,
+			cdata->cfg.sensor_init_params.modes_supported,
+			cdata->cfg.sensor_init_params.position,
+			cdata->cfg.sensor_init_params.sensor_mount_angle);
+		break;
+	case CFG_SET_SLAVE_INFO: {
+		struct msm_camera_sensor_slave_info sensor_slave_info;
+		struct msm_sensor_power_setting_array *power_setting_array;
+		int slave_index = 0;
+		if (copy_from_user(&sensor_slave_info,
+		    (void *)cdata->cfg.setting,
+		    sizeof(struct msm_camera_sensor_slave_info))) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			rc = -EFAULT;
+			break;
+		}
+		/* Update sensor slave address */
+		if (sensor_slave_info.slave_addr) {
+			s_ctrl->sensor_i2c_client->cci_client->sid =
+				sensor_slave_info.slave_addr >> 1;
+		}
+
+		/* Update sensor address type */
+		s_ctrl->sensor_i2c_client->addr_type =
+			sensor_slave_info.addr_type;
+
+		/* Update power up / down sequence */
+		s_ctrl->power_setting_array =
+			sensor_slave_info.power_setting_array;
+		power_setting_array = &s_ctrl->power_setting_array;
+		power_setting_array->power_setting = kzalloc(
+			power_setting_array->size *
+			sizeof(struct msm_sensor_power_setting), GFP_KERNEL);
+		if (!power_setting_array->power_setting) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			rc = -ENOMEM;
+			break;
+		}
+		if (copy_from_user(power_setting_array->power_setting,
+		    (void *)sensor_slave_info.power_setting_array.power_setting,
+		    power_setting_array->size *
+		    sizeof(struct msm_sensor_power_setting))) {
+			kfree(power_setting_array->power_setting);
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			rc = -EFAULT;
+			break;
+		}
+		s_ctrl->free_power_setting = true;
+		CDBG("%s sensor id %x\n", __func__,
+			sensor_slave_info.slave_addr);
+		CDBG("%s sensor addr type %d\n", __func__,
+			sensor_slave_info.addr_type);
+		CDBG("%s sensor reg %x\n", __func__,
+			sensor_slave_info.sensor_id_info.sensor_id_reg_addr);
+		CDBG("%s sensor id %x\n", __func__,
+			sensor_slave_info.sensor_id_info.sensor_id);
+		for (slave_index = 0; slave_index <
+			power_setting_array->size; slave_index++) {
+			CDBG("%s i %d power setting %d %d %ld %d\n", __func__,
+				slave_index,
+				power_setting_array->power_setting[slave_index].
+				seq_type,
+				power_setting_array->power_setting[slave_index].
+				seq_val,
+				power_setting_array->power_setting[slave_index].
+				config_val,
+				power_setting_array->power_setting[slave_index].
+				delay);
+		}
+		kfree(power_setting_array->power_setting);
+		break;
+	}
+	case CFG_WRITE_I2C_ARRAY: {
+		struct msm_camera_i2c_reg_setting conf_array;
+		struct msm_camera_i2c_reg_array *reg_setting = NULL;
+
+		if (copy_from_user(&conf_array,
+			(void *)cdata->cfg.setting,
+			sizeof(struct msm_camera_i2c_reg_setting))) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			rc = -EFAULT;
+			break;
+		}
+
+		reg_setting = kzalloc(conf_array.size *
+			(sizeof(struct msm_camera_i2c_reg_array)), GFP_KERNEL);
+		if (!reg_setting) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			rc = -ENOMEM;
+			break;
+		}
+		if (copy_from_user(reg_setting, (void *)conf_array.reg_setting,
+			conf_array.size *
+			sizeof(struct msm_camera_i2c_reg_array))) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			kfree(reg_setting);
+			rc = -EFAULT;
+			break;
+		}
+
+		conf_array.reg_setting = reg_setting;
+		rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_write_table(
+			s_ctrl->sensor_i2c_client, &conf_array);
+		kfree(reg_setting);
+		break;
+	}
+	case CFG_WRITE_I2C_SEQ_ARRAY: {
+		struct msm_camera_i2c_seq_reg_setting conf_array;
+		struct msm_camera_i2c_seq_reg_array *reg_setting = NULL;
+
+		if (copy_from_user(&conf_array,
+			(void *)cdata->cfg.setting,
+			sizeof(struct msm_camera_i2c_seq_reg_setting))) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			rc = -EFAULT;
+			break;
+		}
+
+		reg_setting = kzalloc(conf_array.size *
+			(sizeof(struct msm_camera_i2c_seq_reg_array)),
+			GFP_KERNEL);
+		if (!reg_setting) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			rc = -ENOMEM;
+			break;
+		}
+		if (copy_from_user(reg_setting, (void *)conf_array.reg_setting,
+			conf_array.size *
+			sizeof(struct msm_camera_i2c_seq_reg_array))) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			kfree(reg_setting);
+			rc = -EFAULT;
+			break;
+		}
+
+		conf_array.reg_setting = reg_setting;
+		rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->
+			i2c_write_seq_table(s_ctrl->sensor_i2c_client,
+			&conf_array);
+		kfree(reg_setting);
+		break;
+	}
+
+	case CFG_POWER_UP:
+		if (s_ctrl->func_tbl->sensor_power_up)
+			rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
+		else
+			rc = -EFAULT;
+		break;
+
+	case CFG_POWER_DOWN:
+		if (s_ctrl->func_tbl->sensor_power_down)
+			rc = s_ctrl->func_tbl->sensor_power_down(
+				s_ctrl);
+		else
+			rc = -EFAULT;
+		break;
+
+	case CFG_SET_STOP_STREAM_SETTING: {
+		struct msm_camera_i2c_reg_setting *stop_setting =
+			&s_ctrl->stop_setting;
+		struct msm_camera_i2c_reg_array *reg_setting = NULL;
+		if (copy_from_user(stop_setting, (void *)cdata->cfg.setting,
+		    sizeof(struct msm_camera_i2c_reg_setting))) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			rc = -EFAULT;
+			break;
+		}
+
+		reg_setting = stop_setting->reg_setting;
+		stop_setting->reg_setting = kzalloc(stop_setting->size *
+			(sizeof(struct msm_camera_i2c_reg_array)), GFP_KERNEL);
+		if (!stop_setting->reg_setting) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			rc = -ENOMEM;
+			break;
+		}
+		if (copy_from_user(stop_setting->reg_setting,
+		    (void *)reg_setting, stop_setting->size *
+		    sizeof(struct msm_camera_i2c_reg_array))) {
+			pr_err("%s:%d failed\n", __func__, __LINE__);
+			kfree(stop_setting->reg_setting);
+			stop_setting->reg_setting = NULL;
+			stop_setting->size = 0;
+			rc = -EFAULT;
+			break;
+		}
+		break;
+	}
+	default:
+		rc = -EFAULT;
+		break;
+	}
+
+	mutex_unlock(s_ctrl->msm_sensor_mutex);
+
+	return rc;
+}
+
+static struct msm_sensor_fn_t mt9m114_sensor_func_tbl = {
+	.sensor_config = mt9m114_sensor_config,
+	.sensor_power_up = msm_sensor_power_up,
+	.sensor_power_down = msm_sensor_power_down,
+	.sensor_match_id = msm_sensor_match_id,
+};
+
+static struct msm_sensor_ctrl_t mt9m114_s_ctrl = {
+	.sensor_i2c_client = &mt9m114_sensor_i2c_client,
+	.power_setting_array.power_setting = mt9m114_power_setting,
+	.power_setting_array.size = ARRAY_SIZE(mt9m114_power_setting),
+	.msm_sensor_mutex = &mt9m114_mut,
+	.sensor_v4l2_subdev_info = mt9m114_subdev_info,
+	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(mt9m114_subdev_info),
+	.func_tbl = &mt9m114_sensor_func_tbl,
+};
+
+module_init(mt9m114_init_module);
+module_exit(mt9m114_exit_module);
+MODULE_DESCRIPTION("Aptina 1.26MP YUV sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v2/sensor/ov2720.c b/drivers/media/platform/msm/camera_v2/sensor/ov2720.c
new file mode 100644
index 0000000..d790c65
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/ov2720.c
@@ -0,0 +1,149 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include "msm_sensor.h"
+#define OV2720_SENSOR_NAME "ov2720"
+DEFINE_MSM_MUTEX(ov2720_mut);
+
+static struct msm_sensor_ctrl_t ov2720_s_ctrl;
+
+static struct msm_sensor_power_setting ov2720_power_setting[] = {
+	{
+		.seq_type = SENSOR_VREG,
+		.seq_val = CAM_VIO,
+		.config_val = 0,
+		.delay = 0,
+	},
+	{
+		.seq_type = SENSOR_VREG,
+		.seq_val = CAM_VANA,
+		.config_val = 0,
+		.delay = 0,
+	},
+	{
+		.seq_type = SENSOR_VREG,
+		.seq_val = CAM_VDIG,
+		.config_val = 0,
+		.delay = 0,
+	},
+	{
+		.seq_type = SENSOR_GPIO,
+		.seq_val = SENSOR_GPIO_RESET,
+		.config_val = GPIO_OUT_LOW,
+		.delay = 1,
+	},
+	{
+		.seq_type = SENSOR_GPIO,
+		.seq_val = SENSOR_GPIO_RESET,
+		.config_val = GPIO_OUT_HIGH,
+		.delay = 30,
+	},
+	{
+		.seq_type = SENSOR_CLK,
+		.seq_val = SENSOR_CAM_MCLK,
+		.config_val = 0,
+		.delay = 1,
+	},
+	{
+		.seq_type = SENSOR_I2C_MUX,
+		.seq_val = 0,
+		.config_val = 0,
+		.delay = 0,
+	},
+};
+
+static struct v4l2_subdev_info ov2720_subdev_info[] = {
+	{
+		.code   = V4L2_MBUS_FMT_SBGGR10_1X10,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.fmt    = 1,
+		.order    = 0,
+	},
+};
+
+static const struct i2c_device_id ov2720_i2c_id[] = {
+	{OV2720_SENSOR_NAME, (kernel_ulong_t)&ov2720_s_ctrl},
+	{ }
+};
+
+static struct i2c_driver ov2720_i2c_driver = {
+	.id_table = ov2720_i2c_id,
+	.probe  = msm_sensor_i2c_probe,
+	.driver = {
+		.name = OV2720_SENSOR_NAME,
+	},
+};
+
+static struct msm_camera_i2c_client ov2720_sensor_i2c_client = {
+	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+static const struct of_device_id ov2720_dt_match[] = {
+	{.compatible = "qcom,ov2720", .data = &ov2720_s_ctrl},
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, ov2720_dt_match);
+
+static struct platform_driver ov2720_platform_driver = {
+	.driver = {
+		.name = "qcom,ov2720",
+		.owner = THIS_MODULE,
+		.of_match_table = ov2720_dt_match,
+	},
+};
+
+static int32_t ov2720_platform_probe(struct platform_device *pdev)
+{
+	int32_t rc = 0;
+	const struct of_device_id *match;
+	match = of_match_device(ov2720_dt_match, &pdev->dev);
+	rc = msm_sensor_platform_probe(pdev, match->data);
+	return rc;
+}
+
+static int __init ov2720_init_module(void)
+{
+	int32_t rc = 0;
+	pr_info("%s:%d\n", __func__, __LINE__);
+	rc = platform_driver_probe(&ov2720_platform_driver,
+		ov2720_platform_probe);
+	if (!rc)
+		return rc;
+	pr_err("%s:%d rc %d\n", __func__, __LINE__, rc);
+	return i2c_add_driver(&ov2720_i2c_driver);
+}
+
+static void __exit ov2720_exit_module(void)
+{
+	pr_info("%s:%d\n", __func__, __LINE__);
+	if (ov2720_s_ctrl.pdev) {
+		msm_sensor_free_sensor_data(&ov2720_s_ctrl);
+		platform_driver_unregister(&ov2720_platform_driver);
+	} else
+		i2c_del_driver(&ov2720_i2c_driver);
+	return;
+}
+
+static struct msm_sensor_ctrl_t ov2720_s_ctrl = {
+	.sensor_i2c_client = &ov2720_sensor_i2c_client,
+	.power_setting_array.power_setting = ov2720_power_setting,
+	.power_setting_array.size = ARRAY_SIZE(ov2720_power_setting),
+	.msm_sensor_mutex = &ov2720_mut,
+	.sensor_v4l2_subdev_info = ov2720_subdev_info,
+	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(ov2720_subdev_info),
+};
+
+module_init(ov2720_init_module);
+module_exit(ov2720_exit_module);
+MODULE_DESCRIPTION("ov2720");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v2/sensor/s5k3l1yx.c b/drivers/media/platform/msm/camera_v2/sensor/s5k3l1yx.c
new file mode 100644
index 0000000..21a7369
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/s5k3l1yx.c
@@ -0,0 +1,167 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include "msm_sensor.h"
+#define S5K3L1YX_SENSOR_NAME "s5k3l1yx"
+DEFINE_MSM_MUTEX(s5k3l1yx_mut);
+
+static struct msm_sensor_ctrl_t s5k3l1yx_s_ctrl;
+
+static struct msm_sensor_power_setting s5k3l1yx_power_setting[] = {
+	{
+		.seq_type = SENSOR_VREG,
+		.seq_val = CAM_VDIG,
+		.config_val = 0,
+		.delay = 0,
+	},
+	{
+		.seq_type = SENSOR_VREG,
+		.seq_val = CAM_VANA,
+		.config_val = 0,
+		.delay = 0,
+	},
+	{
+		.seq_type = SENSOR_VREG,
+		.seq_val = CAM_VIO,
+		.config_val = 0,
+		.delay = 0,
+	},
+	{
+		.seq_type = SENSOR_VREG,
+		.seq_val = CAM_VAF,
+		.config_val = 0,
+		.delay = 0,
+	},
+	{
+		.seq_type = SENSOR_GPIO,
+		.seq_val = SENSOR_GPIO_RESET,
+		.config_val = GPIO_OUT_LOW,
+		.delay = 1,
+	},
+	{
+		.seq_type = SENSOR_GPIO,
+		.seq_val = SENSOR_GPIO_RESET,
+		.config_val = GPIO_OUT_HIGH,
+		.delay = 30,
+	},
+	{
+		.seq_type = SENSOR_GPIO,
+		.seq_val = SENSOR_GPIO_STANDBY,
+		.config_val = GPIO_OUT_LOW,
+		.delay = 1,
+	},
+	{
+		.seq_type = SENSOR_GPIO,
+		.seq_val = SENSOR_GPIO_STANDBY,
+		.config_val = GPIO_OUT_HIGH,
+		.delay = 30,
+	},
+	{
+		.seq_type = SENSOR_CLK,
+		.seq_val = SENSOR_CAM_MCLK,
+		.config_val = 0,
+		.delay = 1,
+	},
+	{
+		.seq_type = SENSOR_I2C_MUX,
+		.seq_val = 0,
+		.config_val = 0,
+		.delay = 0,
+	},
+};
+
+static struct v4l2_subdev_info s5k3l1yx_subdev_info[] = {
+	{
+		.code   = V4L2_MBUS_FMT_SBGGR10_1X10,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.fmt    = 1,
+		.order    = 0,
+	},
+};
+
+static const struct i2c_device_id s5k3l1yx_i2c_id[] = {
+	{S5K3L1YX_SENSOR_NAME, (kernel_ulong_t)&s5k3l1yx_s_ctrl},
+	{ }
+};
+
+static struct i2c_driver s5k3l1yx_i2c_driver = {
+	.id_table = s5k3l1yx_i2c_id,
+	.probe  = msm_sensor_i2c_probe,
+	.driver = {
+		.name = S5K3L1YX_SENSOR_NAME,
+	},
+};
+
+static struct msm_camera_i2c_client s5k3l1yx_sensor_i2c_client = {
+	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+static const struct of_device_id s5k3l1yx_dt_match[] = {
+	{.compatible = "qcom,s5k3l1yx", .data = &s5k3l1yx_s_ctrl},
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, s5k3l1yx_dt_match);
+
+static struct platform_driver s5k3l1yx_platform_driver = {
+	.driver = {
+		.name = "qcom,s5k3l1yx",
+		.owner = THIS_MODULE,
+		.of_match_table = s5k3l1yx_dt_match,
+	},
+};
+
+static int32_t s5k3l1yx_platform_probe(struct platform_device *pdev)
+{
+	int32_t rc = 0;
+	const struct of_device_id *match;
+	match = of_match_device(s5k3l1yx_dt_match, &pdev->dev);
+	rc = msm_sensor_platform_probe(pdev, match->data);
+	return rc;
+}
+
+static int __init s5k3l1yx_init_module(void)
+{
+	int32_t rc = 0;
+	pr_info("%s:%d\n", __func__, __LINE__);
+	rc = platform_driver_probe(&s5k3l1yx_platform_driver,
+		s5k3l1yx_platform_probe);
+	if (!rc)
+		return rc;
+	pr_err("%s:%d rc %d\n", __func__, __LINE__, rc);
+	return i2c_add_driver(&s5k3l1yx_i2c_driver);
+}
+
+static void __exit s5k3l1yx_exit_module(void)
+{
+	pr_info("%s:%d\n", __func__, __LINE__);
+	if (s5k3l1yx_s_ctrl.pdev) {
+		msm_sensor_free_sensor_data(&s5k3l1yx_s_ctrl);
+		platform_driver_unregister(&s5k3l1yx_platform_driver);
+	} else
+		i2c_del_driver(&s5k3l1yx_i2c_driver);
+	return;
+}
+
+static struct msm_sensor_ctrl_t s5k3l1yx_s_ctrl = {
+	.sensor_i2c_client = &s5k3l1yx_sensor_i2c_client,
+	.power_setting_array.power_setting = s5k3l1yx_power_setting,
+	.power_setting_array.size = ARRAY_SIZE(s5k3l1yx_power_setting),
+	.msm_sensor_mutex = &s5k3l1yx_mut,
+	.sensor_v4l2_subdev_info = s5k3l1yx_subdev_info,
+	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(s5k3l1yx_subdev_info),
+};
+
+module_init(s5k3l1yx_init_module);
+module_exit(s5k3l1yx_exit_module);
+MODULE_DESCRIPTION("s5k3l1yx");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/dvb/Kconfig b/drivers/media/platform/msm/dvb/Kconfig
new file mode 100644
index 0000000..e3eb391
--- /dev/null
+++ b/drivers/media/platform/msm/dvb/Kconfig
@@ -0,0 +1,11 @@
+config DVB_MPQ
+	tristate "Qualcomm Multimedia Processor DVB Adapter"
+	depends on ARCH_MSM && DVB_CORE
+	default n
+
+	help
+	  Support for Qualcomm MPQ based DVB adapter.
+	  Say Y or M if you own such a device and want to use it.
+
+source "drivers/media/platform/msm/dvb/demux/Kconfig"
+source "drivers/media/platform/msm/dvb/video/Kconfig"
diff --git a/drivers/media/dvb/mpq/Makefile b/drivers/media/platform/msm/dvb/Makefile
similarity index 100%
rename from drivers/media/dvb/mpq/Makefile
rename to drivers/media/platform/msm/dvb/Makefile
diff --git a/drivers/media/platform/msm/dvb/adapter/Makefile b/drivers/media/platform/msm/dvb/adapter/Makefile
new file mode 100644
index 0000000..dcf7cdb
--- /dev/null
+++ b/drivers/media/platform/msm/dvb/adapter/Makefile
@@ -0,0 +1,8 @@
+
+EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/
+EXTRA_CFLAGS += -Idrivers/media/platform/msm/dvb/include/
+
+obj-$(CONFIG_DVB_MPQ) += mpq-adapter.o
+
+mpq-adapter-y := mpq_adapter.o mpq_stream_buffer.o
+
diff --git a/drivers/media/platform/msm/dvb/adapter/mpq_adapter.c b/drivers/media/platform/msm/dvb/adapter/mpq_adapter.c
new file mode 100644
index 0000000..c48b7ed
--- /dev/null
+++ b/drivers/media/platform/msm/dvb/adapter/mpq_adapter.c
@@ -0,0 +1,212 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include "mpq_adapter.h"
+#include "mpq_dvb_debug.h"
+
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+/* data-structure holding MPQ adapter information */
+static struct
+{
+	/* MPQ adapter registered to dvb-core */
+	struct dvb_adapter adapter;
+
+	/* mutex protect against the data-structure */
+	struct mutex mutex;
+
+	/* List of stream interfaces registered to the MPQ adapter */
+	struct {
+		/* pointer to the stream buffer using for data tunneling */
+		struct mpq_streambuffer *stream_buffer;
+
+		/* callback triggered when the stream interface is registered */
+		mpq_adapter_stream_if_callback callback;
+
+		/* parameter passed to the callback function */
+		void *user_param;
+	} interfaces[MPQ_ADAPTER_MAX_NUM_OF_INTERFACES];
+} mpq_info;
+
+
+/**
+ * Initialize MPQ DVB adapter module.
+ *
+ * Return     error status
+ */
+static int __init mpq_adapter_init(void)
+{
+	int i;
+	int result;
+
+	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
+
+	mutex_init(&mpq_info.mutex);
+
+	/* reset stream interfaces list */
+	for (i = 0; i < MPQ_ADAPTER_MAX_NUM_OF_INTERFACES; i++) {
+		mpq_info.interfaces[i].stream_buffer = NULL;
+		mpq_info.interfaces[i].callback = NULL;
+	}
+
+	/* regsiter a new dvb-adapter to dvb-core */
+	result = dvb_register_adapter(&mpq_info.adapter,
+								  "Qualcomm DVB adapter",
+								  THIS_MODULE,
+								  NULL,
+								  adapter_nr);
+
+	if (result < 0) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: dvb_register_adapter failed, errno %d\n",
+			__func__,
+			result);
+	}
+
+	return result;
+}
+
+
+/**
+ * Cleanup MPQ DVB adapter module.
+ */
+static void __exit mpq_adapter_exit(void)
+{
+	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
+
+	/* un-regsiter adapter from dvb-core */
+	dvb_unregister_adapter(&mpq_info.adapter);
+	mutex_destroy(&mpq_info.mutex);
+}
+
+struct dvb_adapter *mpq_adapter_get(void)
+{
+	return &mpq_info.adapter;
+}
+EXPORT_SYMBOL(mpq_adapter_get);
+
+
+int mpq_adapter_register_stream_if(
+		enum mpq_adapter_stream_if interface_id,
+		struct mpq_streambuffer *stream_buffer)
+{
+	int ret;
+
+	if (interface_id >= MPQ_ADAPTER_MAX_NUM_OF_INTERFACES) {
+		ret = -EINVAL;
+		goto register_failed;
+	}
+
+	if (mutex_lock_interruptible(&mpq_info.mutex)) {
+		ret = -ERESTARTSYS;
+		goto register_failed;
+	}
+
+	if (mpq_info.interfaces[interface_id].stream_buffer != NULL) {
+		/* already registered interface */
+		ret = -EINVAL;
+		goto register_failed_unlock_mutex;
+	}
+
+	mpq_info.interfaces[interface_id].stream_buffer = stream_buffer;
+	mutex_unlock(&mpq_info.mutex);
+
+	/*
+	 * If callback is installed, trigger it to notify that
+	 * stream interface was registered.
+	 */
+	if (mpq_info.interfaces[interface_id].callback != NULL) {
+		mpq_info.interfaces[interface_id].callback(
+				interface_id,
+				mpq_info.interfaces[interface_id].user_param);
+	}
+
+	return 0;
+
+register_failed_unlock_mutex:
+	mutex_unlock(&mpq_info.mutex);
+register_failed:
+	return ret;
+}
+EXPORT_SYMBOL(mpq_adapter_register_stream_if);
+
+
+int mpq_adapter_unregister_stream_if(
+		enum mpq_adapter_stream_if interface_id)
+{
+	if (interface_id >= MPQ_ADAPTER_MAX_NUM_OF_INTERFACES)
+		return -EINVAL;
+
+	if (mutex_lock_interruptible(&mpq_info.mutex))
+		return -ERESTARTSYS;
+
+	/* clear the registered interface */
+	mpq_info.interfaces[interface_id].stream_buffer = NULL;
+
+	mutex_unlock(&mpq_info.mutex);
+
+	return 0;
+}
+EXPORT_SYMBOL(mpq_adapter_unregister_stream_if);
+
+
+int mpq_adapter_get_stream_if(
+		enum mpq_adapter_stream_if interface_id,
+		struct mpq_streambuffer **stream_buffer)
+{
+	if ((interface_id >= MPQ_ADAPTER_MAX_NUM_OF_INTERFACES) ||
+		(stream_buffer == NULL))
+		return -EINVAL;
+
+	if (mutex_lock_interruptible(&mpq_info.mutex))
+		return -ERESTARTSYS;
+
+	*stream_buffer = mpq_info.interfaces[interface_id].stream_buffer;
+
+	mutex_unlock(&mpq_info.mutex);
+
+	return 0;
+}
+EXPORT_SYMBOL(mpq_adapter_get_stream_if);
+
+
+int mpq_adapter_notify_stream_if(
+		enum mpq_adapter_stream_if interface_id,
+		mpq_adapter_stream_if_callback callback,
+		void *user_param)
+{
+	if (interface_id >= MPQ_ADAPTER_MAX_NUM_OF_INTERFACES)
+		return -EINVAL;
+
+	if (mutex_lock_interruptible(&mpq_info.mutex))
+		return -ERESTARTSYS;
+
+	mpq_info.interfaces[interface_id].callback = callback;
+	mpq_info.interfaces[interface_id].user_param = user_param;
+
+	mutex_unlock(&mpq_info.mutex);
+
+	return 0;
+}
+EXPORT_SYMBOL(mpq_adapter_notify_stream_if);
+
+
+module_init(mpq_adapter_init);
+module_exit(mpq_adapter_exit);
+
+MODULE_DESCRIPTION("Qualcomm MPQ adapter");
+MODULE_LICENSE("GPL v2");
+
diff --git a/drivers/media/platform/msm/dvb/adapter/mpq_stream_buffer.c b/drivers/media/platform/msm/dvb/adapter/mpq_stream_buffer.c
new file mode 100644
index 0000000..6ec1994
--- /dev/null
+++ b/drivers/media/platform/msm/dvb/adapter/mpq_stream_buffer.c
@@ -0,0 +1,549 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/uaccess.h>
+#include "mpq_dvb_debug.h"
+#include "mpq_stream_buffer.h"
+
+
+
+
+int mpq_streambuffer_init(
+		struct mpq_streambuffer *sbuff,
+		enum mpq_streambuffer_mode mode,
+		struct mpq_streambuffer_buffer_desc *data_buffers,
+		u32 data_buff_num,
+		void *packet_buff,
+		size_t packet_buff_size)
+{
+	if ((NULL == sbuff) || (NULL == data_buffers) || (NULL == packet_buff))
+		return -EINVAL;
+
+	if (data_buff_num > 1) {
+		if (mode != MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR)
+			return -EINVAL;
+		/* Linear buffer group */
+		dvb_ringbuffer_init(
+			&sbuff->raw_data,
+			data_buffers,
+			data_buff_num *
+			sizeof(struct mpq_streambuffer_buffer_desc));
+	} else if (data_buff_num == 1) {
+		if (mode != MPQ_STREAMBUFFER_BUFFER_MODE_RING)
+			return -EINVAL;
+		/* Single ring-buffer */
+		dvb_ringbuffer_init(&sbuff->raw_data,
+			data_buffers[0].base, data_buffers[0].size);
+	}
+	sbuff->mode = mode;
+	sbuff->buffers = data_buffers;
+	sbuff->pending_buffers_count = 0;
+	sbuff->buffers_num = data_buff_num;
+	dvb_ringbuffer_init(&sbuff->packet_data, packet_buff, packet_buff_size);
+
+	return 0;
+}
+EXPORT_SYMBOL(mpq_streambuffer_init);
+
+
+ssize_t mpq_streambuffer_pkt_next(
+		struct mpq_streambuffer *sbuff,
+		ssize_t idx, size_t *pktlen)
+{
+	return dvb_ringbuffer_pkt_next(&sbuff->packet_data, idx, pktlen);
+}
+EXPORT_SYMBOL(mpq_streambuffer_pkt_next);
+
+
+ssize_t mpq_streambuffer_pkt_read(
+		struct mpq_streambuffer *sbuff,
+		size_t idx,
+		struct mpq_streambuffer_packet_header *packet,
+		u8 *user_data)
+{
+	size_t ret;
+	size_t read_len;
+
+	/* read-out the packet header first */
+	ret = dvb_ringbuffer_pkt_read(
+				&sbuff->packet_data, idx, 0,
+				(u8 *)packet,
+				sizeof(struct mpq_streambuffer_packet_header));
+
+	/* verify length, at least packet header should exist */
+	if (ret != sizeof(struct mpq_streambuffer_packet_header))
+		return -EINVAL;
+
+	read_len = ret;
+
+	/* read-out private user-data if there are such */
+	if ((packet->user_data_len) && (user_data != NULL)) {
+		ret = dvb_ringbuffer_pkt_read(
+				&sbuff->packet_data,
+				idx,
+				sizeof(struct mpq_streambuffer_packet_header),
+				user_data,
+				packet->user_data_len);
+
+		if (ret < 0)
+			return ret;
+
+		read_len += ret;
+	}
+
+	return read_len;
+}
+EXPORT_SYMBOL(mpq_streambuffer_pkt_read);
+
+
+int mpq_streambuffer_pkt_dispose(
+			struct mpq_streambuffer *sbuff,
+			size_t idx,
+			int dispose_data)
+{
+	int ret;
+	struct mpq_streambuffer_packet_header packet;
+
+	if (NULL == sbuff)
+		return -EINVAL;
+
+	/* read-out the packet header first */
+	ret = dvb_ringbuffer_pkt_read(&sbuff->packet_data, idx,
+			0,
+			(u8 *)&packet,
+			sizeof(struct mpq_streambuffer_packet_header));
+
+	if (ret != sizeof(struct mpq_streambuffer_packet_header))
+		return -EINVAL;
+
+	if ((MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR == sbuff->mode) ||
+		(dispose_data)) {
+		/* Advance the read pointer in the raw-data buffer first */
+		ret = mpq_streambuffer_data_read_dispose(sbuff,
+				packet.raw_data_len);
+		if (ret != 0)
+			return ret;
+	}
+
+	/* Move read pointer to the next linear buffer for subsequent reads */
+	if ((MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR == sbuff->mode) &&
+		(packet.raw_data_len > 0)) {
+		struct mpq_streambuffer_buffer_desc *desc;
+
+		desc = (struct mpq_streambuffer_buffer_desc *)
+				&sbuff->raw_data.data[sbuff->raw_data.pread];
+
+		desc->write_ptr = 0;
+		desc->read_ptr = 0;
+
+		DVB_RINGBUFFER_SKIP(&sbuff->raw_data,
+				sizeof(struct mpq_streambuffer_buffer_desc));
+		sbuff->pending_buffers_count--;
+
+		wake_up_all(&sbuff->raw_data.queue);
+	}
+
+	/* Now clear the packet from the packet header */
+	dvb_ringbuffer_pkt_dispose(&sbuff->packet_data, idx);
+
+	if (sbuff->cb)
+		sbuff->cb(sbuff, sbuff->cb_user_data);
+
+	return 0;
+}
+EXPORT_SYMBOL(mpq_streambuffer_pkt_dispose);
+
+int mpq_streambuffer_pkt_write(
+			struct mpq_streambuffer *sbuff,
+			struct mpq_streambuffer_packet_header *packet,
+			u8 *user_data)
+{
+	ssize_t idx;
+	size_t len;
+
+	if ((NULL == sbuff) || (NULL == packet))
+		return -EINVAL;
+
+	len = sizeof(struct mpq_streambuffer_packet_header) +
+		packet->user_data_len;
+
+	/* Make sure enough space available for packet header */
+	if (dvb_ringbuffer_free(&sbuff->packet_data) < len)
+		return -ENOSPC;
+
+	/* Starting writing packet header */
+	idx = dvb_ringbuffer_pkt_start(&sbuff->packet_data, len);
+
+	/* Write non-user private data header */
+	dvb_ringbuffer_write(&sbuff->packet_data,
+		(u8 *)packet,
+		sizeof(struct mpq_streambuffer_packet_header));
+
+	/* Write user's own private data header */
+	dvb_ringbuffer_write(&sbuff->packet_data,
+		user_data,
+		packet->user_data_len);
+
+	dvb_ringbuffer_pkt_close(&sbuff->packet_data, idx);
+
+	/* Move write pointer to next linear buffer for subsequent writes */
+	if ((MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR == sbuff->mode) &&
+		(packet->raw_data_len > 0)) {
+		if (sbuff->pending_buffers_count == sbuff->buffers_num)
+			return -ENOSPC;
+		DVB_RINGBUFFER_PUSH(&sbuff->raw_data,
+				sizeof(struct mpq_streambuffer_buffer_desc));
+		sbuff->pending_buffers_count++;
+	}
+
+	wake_up_all(&sbuff->packet_data.queue);
+
+	return 0;
+}
+EXPORT_SYMBOL(mpq_streambuffer_pkt_write);
+
+
+ssize_t mpq_streambuffer_data_write(
+			struct mpq_streambuffer *sbuff,
+			const u8 *buf, size_t len)
+{
+	int res;
+
+	if ((NULL == sbuff) || (NULL == buf))
+		return -EINVAL;
+
+	if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
+		if (unlikely(dvb_ringbuffer_free(&sbuff->raw_data) < len))
+			return -ENOSPC;
+		/*
+		 * Secure buffers are not permitted to be mapped into kernel
+		 * memory, and so buffer base address may be NULL
+		 */
+		if (NULL == sbuff->raw_data.data)
+			return -EPERM;
+		res = dvb_ringbuffer_write(&sbuff->raw_data, buf, len);
+		wake_up_all(&sbuff->raw_data.queue);
+	} else {
+		/* Linear buffer group */
+		struct mpq_streambuffer_buffer_desc *desc;
+
+		desc = (struct mpq_streambuffer_buffer_desc *)
+				&sbuff->raw_data.data[sbuff->raw_data.pwrite];
+
+		/*
+		 * Secure buffers are not permitted to be mapped into kernel
+		 * memory, and so buffer base address may be NULL
+		 */
+		if (NULL == desc->base)
+			return -EPERM;
+
+		if ((sbuff->pending_buffers_count == sbuff->buffers_num) ||
+			((desc->size - desc->write_ptr) < len)) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: No space available! %d pending buffers out of %d total buffers. write_ptr=%d, size=%d\n",
+				__func__,
+				sbuff->pending_buffers_count,
+				sbuff->buffers_num,
+				desc->write_ptr,
+				desc->size);
+			return -ENOSPC;
+		}
+		memcpy(desc->base + desc->write_ptr, buf, len);
+		desc->write_ptr += len;
+		res = len;
+	}
+
+	return res;
+}
+EXPORT_SYMBOL(mpq_streambuffer_data_write);
+
+
+int mpq_streambuffer_data_write_deposit(
+				struct mpq_streambuffer *sbuff,
+				size_t len)
+{
+	if (NULL == sbuff)
+		return -EINVAL;
+
+	if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
+		if (unlikely(dvb_ringbuffer_free(&sbuff->raw_data) < len))
+			return -ENOSPC;
+
+		DVB_RINGBUFFER_PUSH(&sbuff->raw_data, len);
+		wake_up_all(&sbuff->raw_data.queue);
+	} else {
+		/* Linear buffer group */
+		struct mpq_streambuffer_buffer_desc *desc;
+		desc = (struct mpq_streambuffer_buffer_desc *)
+				&sbuff->raw_data.data[sbuff->raw_data.pwrite];
+
+		if ((sbuff->pending_buffers_count == sbuff->buffers_num) ||
+			 ((desc->size - desc->write_ptr) < len)) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: No space available!\n",
+				__func__);
+			return -ENOSPC;
+		}
+		desc->write_ptr += len;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(mpq_streambuffer_data_write_deposit);
+
+
+ssize_t mpq_streambuffer_data_read(
+				struct mpq_streambuffer *sbuff,
+				u8 *buf, size_t len)
+{
+	ssize_t actual_len = 0;
+
+	if ((NULL == sbuff) || (NULL == buf))
+		return -EINVAL;
+
+	if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
+		/*
+		 * Secure buffers are not permitted to be mapped into kernel
+		 * memory, and so buffer base address may be NULL
+		 */
+		if (NULL == sbuff->raw_data.data)
+			return -EPERM;
+
+		actual_len = dvb_ringbuffer_avail(&sbuff->raw_data);
+		if (actual_len < len)
+			len = actual_len;
+		if (len)
+			dvb_ringbuffer_read(&sbuff->raw_data, buf, len);
+
+		wake_up_all(&sbuff->raw_data.queue);
+	} else {
+		/* Linear buffer group */
+		struct mpq_streambuffer_buffer_desc *desc;
+
+		desc = (struct mpq_streambuffer_buffer_desc *)
+				&sbuff->raw_data.data[sbuff->raw_data.pread];
+
+		/*
+		 * Secure buffers are not permitted to be mapped into kernel
+		 * memory, and so buffer base address may be NULL
+		 */
+		if (NULL == desc->base)
+			return -EPERM;
+
+		actual_len = (desc->write_ptr - desc->read_ptr);
+		if (actual_len < len)
+			len = actual_len;
+		memcpy(buf, desc->base + desc->read_ptr, len);
+		desc->read_ptr += len;
+	}
+
+	return len;
+}
+EXPORT_SYMBOL(mpq_streambuffer_data_read);
+
+
+ssize_t mpq_streambuffer_data_read_user(
+		struct mpq_streambuffer *sbuff,
+		u8 __user *buf, size_t len)
+{
+	ssize_t actual_len = 0;
+
+	if ((NULL == sbuff) || (NULL == buf))
+		return -EINVAL;
+
+	if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
+		/*
+		 * Secure buffers are not permitted to be mapped into kernel
+		 * memory, and so buffer base address may be NULL
+		 */
+		if (NULL == sbuff->raw_data.data)
+			return -EPERM;
+
+		actual_len = dvb_ringbuffer_avail(&sbuff->raw_data);
+		if (actual_len < len)
+			len = actual_len;
+		if (len)
+			dvb_ringbuffer_read_user(&sbuff->raw_data, buf, len);
+		wake_up_all(&sbuff->raw_data.queue);
+	} else {
+		/* Linear buffer group */
+		struct mpq_streambuffer_buffer_desc *desc;
+
+		desc = (struct mpq_streambuffer_buffer_desc *)
+				&sbuff->raw_data.data[sbuff->raw_data.pread];
+
+		/*
+		 * Secure buffers are not permitted to be mapped into kernel
+		 * memory, and so buffer base address may be NULL
+		 */
+		if (NULL == desc->base)
+			return -EPERM;
+
+		actual_len = (desc->write_ptr - desc->read_ptr);
+		if (actual_len < len)
+			len = actual_len;
+		if (copy_to_user(buf, desc->base + desc->read_ptr, len))
+			return -EFAULT;
+		desc->read_ptr += len;
+	}
+
+	return len;
+}
+EXPORT_SYMBOL(mpq_streambuffer_data_read_user);
+
+
+int mpq_streambuffer_data_read_dispose(
+			struct mpq_streambuffer *sbuff,
+			size_t len)
+{
+	if (NULL == sbuff)
+		return -EINVAL;
+
+	if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
+		if (unlikely(dvb_ringbuffer_avail(&sbuff->raw_data) < len))
+			return -EINVAL;
+
+		DVB_RINGBUFFER_SKIP(&sbuff->raw_data, len);
+		wake_up_all(&sbuff->raw_data.queue);
+	} else {
+		struct mpq_streambuffer_buffer_desc *desc;
+
+		desc = (struct mpq_streambuffer_buffer_desc *)
+				&sbuff->raw_data.data[sbuff->raw_data.pread];
+		if ((desc->read_ptr + len) > desc->size)
+			desc->read_ptr = desc->size;
+		else
+			desc->read_ptr += len;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(mpq_streambuffer_data_read_dispose);
+
+
+int mpq_streambuffer_get_buffer_handle(
+	struct mpq_streambuffer *sbuff,
+	int read_buffer,
+	int *handle)
+{
+	struct mpq_streambuffer_buffer_desc *desc = NULL;
+
+	if ((NULL == sbuff) || (NULL == handle))
+		return -EINVAL;
+
+	if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
+		*handle = sbuff->buffers[0].handle;
+	} else {
+		if (read_buffer)
+			desc = (struct mpq_streambuffer_buffer_desc *)
+				&sbuff->raw_data.data[sbuff->raw_data.pread];
+		else
+			desc = (struct mpq_streambuffer_buffer_desc *)
+				&sbuff->raw_data.data[sbuff->raw_data.pwrite];
+		*handle = desc->handle;
+	}
+	return 0;
+}
+EXPORT_SYMBOL(mpq_streambuffer_get_buffer_handle);
+
+
+int mpq_streambuffer_register_pkt_dispose(
+	struct mpq_streambuffer *sbuff,
+	mpq_streambuffer_pkt_dispose_cb cb_func,
+	void *user_data)
+{
+	if ((NULL == sbuff) || (NULL == cb_func))
+		return -EINVAL;
+
+	sbuff->cb = cb_func;
+	sbuff->cb_user_data = user_data;
+
+	return 0;
+}
+EXPORT_SYMBOL(mpq_streambuffer_register_pkt_dispose);
+
+
+ssize_t mpq_streambuffer_data_free(
+	struct mpq_streambuffer *sbuff)
+{
+	struct mpq_streambuffer_buffer_desc *desc;
+
+	if (NULL == sbuff)
+		return -EINVAL;
+
+	if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode)
+		return dvb_ringbuffer_free(&sbuff->raw_data);
+
+	if (sbuff->pending_buffers_count == sbuff->buffers_num)
+		return 0;
+
+	desc = (struct mpq_streambuffer_buffer_desc *)
+		&sbuff->raw_data.data[sbuff->raw_data.pwrite];
+
+	return desc->size - desc->write_ptr;
+}
+EXPORT_SYMBOL(mpq_streambuffer_data_free);
+
+
+ssize_t mpq_streambuffer_data_avail(
+	struct mpq_streambuffer *sbuff)
+{
+	struct mpq_streambuffer_buffer_desc *desc;
+
+	if (NULL == sbuff)
+		return -EINVAL;
+
+	if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode)
+		return dvb_ringbuffer_avail(&sbuff->raw_data);
+
+	desc = (struct mpq_streambuffer_buffer_desc *)
+		&sbuff->raw_data.data[sbuff->raw_data.pread];
+
+	return desc->write_ptr - desc->read_ptr;
+}
+EXPORT_SYMBOL(mpq_streambuffer_data_avail);
+
+int mpq_streambuffer_get_data_rw_offset(
+	struct mpq_streambuffer *sbuff,
+	u32 *read_offset,
+	u32 *write_offset)
+{
+	if (NULL == sbuff)
+		return -EINVAL;
+
+	if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
+		if (read_offset)
+			*read_offset = sbuff->raw_data.pread;
+		if (write_offset)
+			*write_offset = sbuff->raw_data.pwrite;
+	} else {
+		struct mpq_streambuffer_buffer_desc *desc;
+
+		if (read_offset) {
+			desc = (struct mpq_streambuffer_buffer_desc *)
+				&sbuff->raw_data.data[sbuff->raw_data.pread];
+			*read_offset = desc->read_ptr;
+		}
+		if (write_offset) {
+			desc = (struct mpq_streambuffer_buffer_desc *)
+				&sbuff->raw_data.data[sbuff->raw_data.pwrite];
+			*write_offset = desc->write_ptr;
+		}
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(mpq_streambuffer_get_data_rw_offset);
diff --git a/drivers/media/dvb/mpq/demux/Kconfig b/drivers/media/platform/msm/dvb/demux/Kconfig
similarity index 100%
rename from drivers/media/dvb/mpq/demux/Kconfig
rename to drivers/media/platform/msm/dvb/demux/Kconfig
diff --git a/drivers/media/platform/msm/dvb/demux/Makefile b/drivers/media/platform/msm/dvb/demux/Makefile
new file mode 100644
index 0000000..e164a21
--- /dev/null
+++ b/drivers/media/platform/msm/dvb/demux/Makefile
@@ -0,0 +1,18 @@
+
+ccflags-y += -Idrivers/media/dvb/dvb-core/
+ccflags-y += -Idrivers/media/platform/msm/dvb/include/
+ccflags-y += -Idrivers/misc/
+
+obj-$(CONFIG_DVB_MPQ_DEMUX) += mpq-dmx-hw-plugin.o
+
+mpq-dmx-hw-plugin-y := mpq_dmx_plugin_common.o
+
+mpq-dmx-hw-plugin-y += mpq_sdmx.o
+
+mpq-dmx-hw-plugin-$(CONFIG_DVB_MPQ_TSPP1) += mpq_dmx_plugin_tspp_v1.o
+
+mpq-dmx-hw-plugin-$(CONFIG_DVB_MPQ_TSPP2) += mpq_dmx_plugin_tspp_v2.o
+
+mpq-dmx-hw-plugin-$(CONFIG_DVB_MPQ_TSIF) += mpq_dmx_plugin_tsif.o
+
+
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
new file mode 100644
index 0000000..9d89a7e
--- /dev/null
+++ b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
@@ -0,0 +1,4625 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/vmalloc.h>
+#include <linux/file.h>
+#include "mpq_dvb_debug.h"
+#include "mpq_dmx_plugin_common.h"
+#include "mpq_sdmx.h"
+
+#define SDMX_MAJOR_VERSION_MATCH	(3)
+
+#define TS_PACKET_HEADER_LENGTH (4)
+
+/* Length of mandatory fields that must exist in header of video PES */
+#define PES_MANDATORY_FIELDS_LEN			9
+
+#define MAX_PES_LENGTH	(SZ_64K)
+
+#define MAX_TS_PACKETS_FOR_SDMX_PROCESS	(500)
+
+/*
+ * PES header length field is 8 bits so PES header length after this field
+ * can be up to 256 bytes.
+ * Preceding fields of the PES header total to 9 bytes
+ * (including the PES header length field).
+ */
+#define MAX_PES_HEADER_LENGTH	(256 + PES_MANDATORY_FIELDS_LEN)
+
+/* TS packet with adaptation field only can take up the entire TSP */
+#define MAX_TSP_ADAPTATION_LENGTH (184)
+
+#define MAX_SDMX_METADATA_LENGTH	\
+	(TS_PACKET_HEADER_LENGTH +	\
+	MAX_TSP_ADAPTATION_LENGTH +	\
+	MAX_PES_HEADER_LENGTH)
+
+#define SDMX_METADATA_BUFFER_SIZE	(64*1024)
+#define SDMX_SECTION_BUFFER_SIZE	(64*1024)
+#define SDMX_PCR_BUFFER_SIZE		(64*1024)
+
+/*
+ * 500 PES header packets in the meta-data buffer,
+ * should be more than enough
+ */
+#define VIDEO_NUM_OF_PES_PACKETS			500
+
+#define VIDEO_META_DATA_BUFFER_SIZE              \
+	(VIDEO_NUM_OF_PES_PACKETS *                  \
+	  (DVB_RINGBUFFER_PKTHDRSIZE +               \
+	   sizeof(struct mpq_streambuffer_packet_header) + \
+	   sizeof(struct mpq_adapter_video_meta_data)))
+
+
+/* Number of demux devices, has default of linux configuration */
+static int mpq_demux_device_num = CONFIG_DVB_MPQ_NUM_DMX_DEVICES;
+module_param(mpq_demux_device_num, int, S_IRUGO);
+
+/* ION heap IDs used for allocating video output buffer */
+static int video_secure_ion_heap = ION_CP_MM_HEAP_ID;
+module_param(video_secure_ion_heap , int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(video_secure_ion_heap, "ION heap for secure video buffer allocation");
+
+static int video_nonsecure_ion_heap = ION_IOMMU_HEAP_ID;
+module_param(video_nonsecure_ion_heap, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(video_nonsecure_ion_heap, "ION heap for non-secure video buffer allocation");
+
+static int generate_es_events;
+module_param(generate_es_events, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(generate_es_events, "Generate new elementary stream data events");
+
+/* Value of TS packet scramble bits field for even key */
+static int mpq_sdmx_scramble_even = 0x2;
+module_param(mpq_sdmx_scramble_even, int, S_IRUGO | S_IWUSR);
+
+/* Value of TS packet scramble bits field for odd key */
+static int mpq_sdmx_scramble_odd = 0x3;
+module_param(mpq_sdmx_scramble_odd, int, S_IRUGO | S_IWUSR);
+
+/* Whether to use secure demux or bypass it. Use for debugging */
+static int mpq_bypass_sdmx = 1;
+module_param(mpq_bypass_sdmx, int, S_IRUGO | S_IWUSR);
+
+/* Max number of TS packets allowed as input for a single sdmx process */
+static int mpq_sdmx_proc_limit = MAX_TS_PACKETS_FOR_SDMX_PROCESS;
+module_param(mpq_sdmx_proc_limit, int, S_IRUGO | S_IWUSR);
+
+
+/**
+ * Maximum allowed framing pattern size
+ */
+#define MPQ_MAX_PATTERN_SIZE				6
+
+/**
+ * Number of patterns to look for when doing framing, per video standard
+ */
+#define MPQ_MPEG2_PATTERN_NUM				5
+#define MPQ_H264_PATTERN_NUM				5
+#define MPQ_VC1_PATTERN_NUM				3
+
+/*
+ * mpq_framing_pattern_lookup_params - framing pattern lookup parameters.
+ *
+ * @pattern: the byte pattern to look for.
+ * @mask: the byte mask to use (same length as pattern).
+ * @size: the length of the pattern, in bytes.
+ * @type: the type of the pattern.
+ */
+struct mpq_framing_pattern_lookup_params {
+	u8 pattern[MPQ_MAX_PATTERN_SIZE];
+	u8 mask[MPQ_MAX_PATTERN_SIZE];
+	size_t size;
+	enum dmx_framing_pattern_type type;
+};
+
+/*
+ * Pre-defined video framing lookup pattern information.
+ * Note: the first pattern in each patterns database must
+ * be the Sequence Header (or equivalent SPS in H.264).
+ * The code assumes this is the case when prepending
+ * Sequence Header data in case it is required.
+ */
+static const struct mpq_framing_pattern_lookup_params
+		mpeg2_patterns[MPQ_MPEG2_PATTERN_NUM] = {
+	{{0x00, 0x00, 0x01, 0xB3}, {0xFF, 0xFF, 0xFF, 0xFF}, 4,
+			DMX_FRM_MPEG2_SEQUENCE_HEADER},
+	{{0x00, 0x00, 0x01, 0xB8}, {0xFF, 0xFF, 0xFF, 0xFF}, 4,
+			DMX_FRM_MPEG2_GOP_HEADER},
+	{{0x00, 0x00, 0x01, 0x00, 0x00, 0x08},
+			{0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x38}, 6,
+			DMX_FRM_MPEG2_I_PIC},
+	{{0x00, 0x00, 0x01, 0x00, 0x00, 0x10},
+			{0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x38}, 6,
+			DMX_FRM_MPEG2_P_PIC},
+	{{0x00, 0x00, 0x01, 0x00, 0x00, 0x18},
+			{0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x38}, 6,
+			DMX_FRM_MPEG2_B_PIC}
+};
+
+static const struct mpq_framing_pattern_lookup_params
+		h264_patterns[MPQ_H264_PATTERN_NUM] = {
+	{{0x00, 0x00, 0x01, 0x07}, {0xFF, 0xFF, 0xFF, 0x1F}, 4,
+			DMX_FRM_H264_SPS},
+	{{0x00, 0x00, 0x01, 0x08}, {0xFF, 0xFF, 0xFF, 0x1F}, 4,
+			DMX_FRM_H264_PPS},
+	{{0x00, 0x00, 0x01, 0x05, 0x80}, {0xFF, 0xFF, 0xFF, 0x1F, 0x80}, 5,
+			DMX_FRM_H264_IDR_PIC},
+	{{0x00, 0x00, 0x01, 0x01, 0x80}, {0xFF, 0xFF, 0xFF, 0x1F, 0x80}, 5,
+			DMX_FRM_H264_NON_IDR_PIC}
+};
+
+static const struct mpq_framing_pattern_lookup_params
+		vc1_patterns[MPQ_VC1_PATTERN_NUM] = {
+	{{0x00, 0x00, 0x01, 0x0F}, {0xFF, 0xFF, 0xFF, 0xFF}, 4,
+			DMX_FRM_VC1_SEQUENCE_HEADER},
+	{{0x00, 0x00, 0x01, 0x0E}, {0xFF, 0xFF, 0xFF, 0xFF}, 4,
+			DMX_FRM_VC1_ENTRY_POINT_HEADER},
+	{{0x00, 0x00, 0x01, 0x0D}, {0xFF, 0xFF, 0xFF, 0xFF}, 4,
+			DMX_FRM_VC1_FRAME_START_CODE}
+};
+
+/* Global data-structure for managing demux devices */
+static struct
+{
+	/* ION demux client used for memory allocation */
+	struct ion_client *ion_client;
+
+	/* demux devices array */
+	struct mpq_demux *devices;
+
+	/* Stream buffers objects used for tunneling to decoders */
+	struct mpq_streambuffer
+		decoder_buffers[MPQ_ADAPTER_MAX_NUM_OF_INTERFACES];
+
+	/*
+	 * Indicates whether the video decoder handles framing
+	 * or we are required to provide framing information
+	 * in the meta-data passed to the decoder.
+	 */
+	int decoder_framing;
+
+	/* Indicates whether secure demux TZ application is available */
+	int secure_demux_app_loaded;
+} mpq_dmx_info;
+
+/* Check that PES header is valid and that it is a video PES */
+static int mpq_dmx_is_valid_video_pes(struct pes_packet_header *pes_header)
+{
+	/* start-code valid? */
+	if ((pes_header->packet_start_code_prefix_1 != 0) ||
+		(pes_header->packet_start_code_prefix_2 != 0) ||
+		(pes_header->packet_start_code_prefix_3 != 1))
+		return -EINVAL;
+
+	/* stream_id is video? */
+	if ((pes_header->stream_id & 0xF0) != 0xE0)
+		return -EINVAL;
+
+	return 0;
+}
+
+/* Check if a framing pattern is a video frame pattern or a header pattern */
+static inline int mpq_dmx_is_video_frame(
+				enum dmx_indexing_video_standard standard,
+				enum dmx_framing_pattern_type pattern_type)
+{
+	switch (standard) {
+	case DMX_INDEXING_MPEG2:
+		if ((pattern_type == DMX_FRM_MPEG2_I_PIC) ||
+			(pattern_type == DMX_FRM_MPEG2_P_PIC) ||
+			(pattern_type == DMX_FRM_MPEG2_B_PIC))
+			return 1;
+		return 0;
+	case DMX_INDEXING_H264:
+		if ((pattern_type == DMX_FRM_H264_IDR_PIC) ||
+			(pattern_type == DMX_FRM_H264_NON_IDR_PIC))
+			return 1;
+		return 0;
+	case DMX_INDEXING_VC1:
+		if (pattern_type == DMX_FRM_VC1_FRAME_START_CODE)
+			return 1;
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+/*
+ * mpq_framing_pattern_lookup_results - framing lookup results
+ *
+ * @offset: The offset in the buffer where the pattern was found.
+ * If a pattern is found using a prefix (i.e. started on the
+ * previous buffer), offset is zero.
+ * @type: the type of the pattern found.
+ * @used_prefix_size: the prefix size that was used to find this pattern
+ */
+struct mpq_framing_pattern_lookup_results {
+	struct {
+		u32 offset;
+		enum dmx_framing_pattern_type type;
+		u32 used_prefix_size;
+	} info[MPQ_MAX_FOUND_PATTERNS];
+};
+
+/*
+ * Check if two patterns are identical, taking mask into consideration.
+ * @pattern1: the first byte pattern to compare.
+ * @pattern2: the second byte pattern to compare.
+ * @mask: the bit mask to use.
+ * @pattern_size: the length of both patterns and the mask, in bytes.
+ *
+ * Return: 1 if patterns match, 0 otherwise.
+ */
+static inline int mpq_dmx_patterns_match(const u8 *pattern1, const u8 *pattern2,
+					const u8 *mask, size_t pattern_size)
+{
+	int i;
+
+	/*
+	 * Assumption: it is OK to access pattern1, pattern2 and mask.
+	 * This function performs no sanity checks to keep things fast.
+	 */
+
+	for (i = 0; i < pattern_size; i++)
+		if ((pattern1[i] & mask[i]) != (pattern2[i] & mask[i]))
+			return 0;
+
+	return 1;
+}
+
+/*
+ * mpq_dmx_framing_pattern_search -
+ * search for framing patterns in a given buffer.
+ *
+ * Optimized version: first search for a common substring, e.g. 0x00 0x00 0x01.
+ * If this string is found, go over all the given patterns (all must start
+ * with this string) and search for their ending in the buffer.
+ *
+ * Assumption: the patterns we look for do not spread over more than two
+ * buffers.
+ *
+ * @paterns: the full patterns information to look for.
+ * @patterns_num: the number of patterns to look for.
+ * @buf: the buffer to search.
+ * @buf_size: the size of the buffer to search. we search the entire buffer.
+ * @prefix_size_masks: a bit mask (per pattern) of possible prefix sizes to use
+ * when searching for a pattern that started at the last buffer.
+ * Updated in this function for use in the next lookup.
+ * @results: lookup results (offset, type, used_prefix_size) per found pattern,
+ * up to MPQ_MAX_FOUND_PATTERNS.
+ *
+ * Return:
+ *   Number of patterns found (up to MPQ_MAX_FOUND_PATTERNS).
+ *   0 if pattern was not found.
+ *   Negative error value on failure.
+ */
+static int mpq_dmx_framing_pattern_search(
+		const struct mpq_framing_pattern_lookup_params *patterns,
+		int patterns_num,
+		const u8 *buf,
+		size_t buf_size,
+		struct mpq_framing_prefix_size_masks *prefix_size_masks,
+		struct mpq_framing_pattern_lookup_results *results)
+{
+	int i, j;
+	unsigned int current_size;
+	u32 prefix;
+	int found = 0;
+	int start_offset = 0;
+	/* the starting common substring to look for */
+	u8 string[] = {0x00, 0x00, 0x01};
+	/* the mask for the starting string */
+	u8 string_mask[] = {0xFF, 0xFF, 0xFF};
+	/* the size of the starting string (in bytes) */
+	size_t string_size = 3;
+
+	/* sanity checks - can be commented out for optimization purposes */
+	if ((patterns == NULL) || (patterns_num <= 0) || (buf == NULL)) {
+		MPQ_DVB_ERR_PRINT("%s: invalid parameters\n", __func__);
+		return -EINVAL;
+	}
+
+	memset(results, 0, sizeof(struct mpq_framing_pattern_lookup_results));
+
+	/*
+	 * handle prefix - disregard string, simply check all patterns,
+	 * looking for a matching suffix at the very beginning of the buffer.
+	 */
+	for (j = 0; (j < patterns_num) && !found; j++) {
+		prefix = prefix_size_masks->size_mask[j];
+		current_size = 32;
+		while (prefix) {
+			if (prefix & (0x1 << (current_size - 1))) {
+				/*
+				 * check that we don't look further
+				 * than buf_size boundary
+				 */
+				if ((int)(patterns[j].size - current_size) >
+						buf_size)
+					break;
+
+				if (mpq_dmx_patterns_match(
+					(patterns[j].pattern + current_size),
+					buf, (patterns[j].mask + current_size),
+					(patterns[j].size - current_size))) {
+
+					MPQ_DVB_DBG_PRINT(
+						"%s: Found matching pattern using prefix of size %d\n",
+						__func__, current_size);
+					/*
+					 * pattern found using prefix at the
+					 * very beginning of the buffer, so
+					 * offset is 0, but we already zeroed
+					 * everything in the beginning of the
+					 * function. that's why the next line
+					 * is commented.
+					 */
+					/* results->info[found].offset = 0; */
+					results->info[found].type =
+							patterns[j].type;
+					results->info[found].used_prefix_size =
+							current_size;
+					found++;
+					/*
+					 * save offset to start looking from
+					 * in the buffer, to avoid reusing the
+					 * data of a pattern we already found.
+					 */
+					start_offset = (patterns[j].size -
+							current_size);
+
+					if (found >= MPQ_MAX_FOUND_PATTERNS)
+						goto next_prefix_lookup;
+					/*
+					 * we don't want to search for the same
+					 * pattern with several possible prefix
+					 * sizes if we have already found it,
+					 * so we break from the inner loop.
+					 * since we incremented 'found', we
+					 * will not search for additional
+					 * patterns using a prefix - that would
+					 * imply ambiguous patterns where one
+					 * pattern can be included in another.
+					 * the for loop will exit.
+					 */
+					break;
+				}
+			}
+			prefix &= ~(0x1 << (current_size - 1));
+			current_size--;
+		}
+	}
+
+	/*
+	 * Search buffer for entire pattern, starting with the string.
+	 * Note the external for loop does not execute if buf_size is
+	 * smaller than string_size (the cast to int is required, since
+	 * size_t is unsigned).
+	 */
+	for (i = start_offset; i < (int)(buf_size - string_size + 1); i++) {
+		if (mpq_dmx_patterns_match(string, (buf + i), string_mask,
+							string_size)) {
+			/* now search for patterns: */
+			for (j = 0; j < patterns_num; j++) {
+				/* avoid overflow to next buffer */
+				if ((i + patterns[j].size) > buf_size)
+					continue;
+
+				if (mpq_dmx_patterns_match(
+					(patterns[j].pattern + string_size),
+					(buf + i + string_size),
+					(patterns[j].mask + string_size),
+					(patterns[j].size - string_size))) {
+
+					results->info[found].offset = i;
+					results->info[found].type =
+						patterns[j].type;
+					/*
+					 * save offset to start next prefix
+					 * lookup, to avoid reusing the data
+					 * of any pattern we already found.
+					 */
+					if ((i + patterns[j].size) >
+							start_offset)
+						start_offset = (i +
+							patterns[j].size);
+					/*
+					 * did not use a prefix to find this
+					 * pattern, but we zeroed everything
+					 * in the beginning of the function.
+					 * So no need to zero used_prefix_size
+					 * for results->info[found]
+					 */
+
+					found++;
+					if (found >= MPQ_MAX_FOUND_PATTERNS)
+						goto next_prefix_lookup;
+					/*
+					 * theoretically we don't have to break
+					 * here, but we don't want to search
+					 * for the other matching patterns on
+					 * the very same same place in the
+					 * buffer. That would mean the
+					 * (pattern & mask) combinations are
+					 * not unique. So we break from inner
+					 * loop and move on to the next place
+					 * in the buffer.
+					 */
+					break;
+				}
+			}
+		}
+	}
+
+next_prefix_lookup:
+	/* check for possible prefix sizes for the next buffer */
+	for (j = 0; j < patterns_num; j++) {
+		prefix_size_masks->size_mask[j] = 0;
+		for (i = 1; i < patterns[j].size; i++) {
+			/*
+			 * avoid looking outside of the buffer
+			 * or reusing previously used data.
+			 */
+			if (i > (buf_size - start_offset))
+				break;
+
+			if (mpq_dmx_patterns_match(patterns[j].pattern,
+					(buf + buf_size - i),
+					patterns[j].mask, i)) {
+				prefix_size_masks->size_mask[j] |=
+						(1 << (i - 1));
+			}
+		}
+	}
+
+	return found;
+}
+
+/*
+ * mpq_dmx_get_pattern_params -
+ * get a pointer to the relevant pattern parameters structure,
+ * based on the video parameters.
+ *
+ * @video_params: the video parameters (e.g. video standard).
+ * @patterns: a pointer to a pointer to the pattern parameters,
+ * updated by this function.
+ * @patterns_num: number of patterns, updated by this function.
+ */
+static inline int mpq_dmx_get_pattern_params(
+		struct dmx_indexing_video_params *video_params,
+		const struct mpq_framing_pattern_lookup_params **patterns,
+		int *patterns_num)
+{
+	switch (video_params->standard) {
+	case DMX_INDEXING_MPEG2:
+		*patterns = mpeg2_patterns;
+		*patterns_num = MPQ_MPEG2_PATTERN_NUM;
+		break;
+	case DMX_INDEXING_H264:
+		*patterns = h264_patterns;
+		*patterns_num = MPQ_H264_PATTERN_NUM;
+		break;
+	case DMX_INDEXING_VC1:
+		*patterns = vc1_patterns;
+		*patterns_num = MPQ_VC1_PATTERN_NUM;
+		break;
+	default:
+		MPQ_DVB_ERR_PRINT("%s: invalid parameters\n", __func__);
+		*patterns = NULL;
+		*patterns_num = 0;
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/*
+ * mpq_dmx_calc_time_delta -
+ * Calculate delta in msec between two time snapshots.
+ *
+ * @curr_time: value of current time
+ * @prev_time: value of previous time
+ *
+ * Return	time-delta in msec
+ */
+static inline u32 mpq_dmx_calc_time_delta(struct timespec *curr_time,
+	struct timespec *prev_time)
+{
+	struct timespec delta_time;
+	u64 delta_time_ms;
+
+	delta_time = timespec_sub(*curr_time, *prev_time);
+
+	delta_time_ms = ((u64)delta_time.tv_sec * MSEC_PER_SEC) +
+		delta_time.tv_nsec / NSEC_PER_MSEC;
+
+	return (u32)delta_time_ms;
+}
+
+/*
+ * mpq_dmx_update_decoder_stat -
+ * Update decoder output statistics in debug-fs.
+ *
+ * @mpq_demux: mpq_demux object
+ */
+static inline void mpq_dmx_update_decoder_stat(struct mpq_demux *mpq_demux)
+{
+	struct timespec curr_time;
+	u64 delta_time_ms;
+
+	curr_time = current_kernel_time();
+	if (unlikely(!mpq_demux->decoder_out_count)) {
+		mpq_demux->decoder_out_last_time = curr_time;
+		mpq_demux->decoder_out_count++;
+		return;
+	}
+
+	/* calculate time-delta between frame */
+	delta_time_ms = mpq_dmx_calc_time_delta(&curr_time,
+		&mpq_demux->decoder_out_last_time);
+
+	mpq_demux->decoder_out_interval_sum += (u32)delta_time_ms;
+
+	mpq_demux->decoder_out_interval_average =
+	  mpq_demux->decoder_out_interval_sum /
+	  mpq_demux->decoder_out_count;
+
+	if (delta_time_ms > mpq_demux->decoder_out_interval_max)
+		mpq_demux->decoder_out_interval_max = delta_time_ms;
+
+	mpq_demux->decoder_out_last_time = curr_time;
+	mpq_demux->decoder_out_count++;
+}
+
+/*
+ * mpq_dmx_update_sdmx_stat -
+ * Update SDMX statistics in debug-fs.
+ *
+ * @mpq_demux: mpq_demux object
+ * @bytes_processed: number of bytes processed by sdmx
+ * @process_start_time: time before sdmx process was triggered
+ * @process_end_time: time after sdmx process finished
+ */
+static inline void mpq_dmx_update_sdmx_stat(struct mpq_demux *mpq_demux,
+		u32 bytes_processed, struct timespec *process_start_time,
+		struct timespec *process_end_time)
+{
+	u32 packets_num;
+	u64 process_time;
+
+	mpq_demux->sdmx_process_count++;
+	packets_num = bytes_processed / mpq_demux->demux.ts_packet_size;
+	mpq_demux->sdmx_process_packets_sum += packets_num;
+	mpq_demux->sdmx_process_packets_average =
+		mpq_demux->sdmx_process_packets_sum /
+		mpq_demux->sdmx_process_count;
+
+	process_time =
+		mpq_dmx_calc_time_delta(process_end_time, process_start_time);
+
+	mpq_demux->sdmx_process_time_sum += process_time;
+	mpq_demux->sdmx_process_time_average =
+		mpq_demux->sdmx_process_time_sum /
+		mpq_demux->sdmx_process_count;
+
+	if ((mpq_demux->sdmx_process_count == 1) ||
+		(packets_num < mpq_demux->sdmx_process_packets_min))
+		mpq_demux->sdmx_process_packets_min = packets_num;
+
+	if ((mpq_demux->sdmx_process_count == 1) ||
+		(process_time > mpq_demux->sdmx_process_time_max))
+		mpq_demux->sdmx_process_time_max = process_time;
+}
+
+/* Extend dvb-demux debugfs with HW statistics */
+void mpq_dmx_init_hw_statistics(struct mpq_demux *mpq_demux)
+{
+	/*
+	 * Extend dvb-demux debugfs with HW statistics.
+	 * Note that destruction of debugfs directory is done
+	 * when dvb-demux is terminated.
+	 */
+	mpq_demux->hw_notification_count = 0;
+	mpq_demux->hw_notification_interval = 0;
+	mpq_demux->hw_notification_size = 0;
+	mpq_demux->hw_notification_min_size = 0xFFFFFFFF;
+
+	if (mpq_demux->demux.dmx.debugfs_demux_dir == NULL)
+		return;
+
+	debugfs_create_u32(
+		"hw_notification_interval",
+		S_IRUGO|S_IWUGO,
+		mpq_demux->demux.dmx.debugfs_demux_dir,
+		&mpq_demux->hw_notification_interval);
+
+	debugfs_create_u32(
+		"hw_notification_min_interval",
+		S_IRUGO|S_IWUGO,
+		mpq_demux->demux.dmx.debugfs_demux_dir,
+		&mpq_demux->hw_notification_min_interval);
+
+	debugfs_create_u32(
+		"hw_notification_count",
+		S_IRUGO|S_IWUGO,
+		mpq_demux->demux.dmx.debugfs_demux_dir,
+		&mpq_demux->hw_notification_count);
+
+	debugfs_create_u32(
+		"hw_notification_size",
+		S_IRUGO|S_IWUGO,
+		mpq_demux->demux.dmx.debugfs_demux_dir,
+		&mpq_demux->hw_notification_size);
+
+	debugfs_create_u32(
+		"hw_notification_min_size",
+		S_IRUGO|S_IWUGO,
+		mpq_demux->demux.dmx.debugfs_demux_dir,
+		&mpq_demux->hw_notification_min_size);
+
+	debugfs_create_u32(
+		"decoder_drop_count",
+		S_IRUGO|S_IWUGO,
+		mpq_demux->demux.dmx.debugfs_demux_dir,
+		&mpq_demux->decoder_drop_count);
+
+	debugfs_create_u32(
+		"decoder_out_count",
+		S_IRUGO|S_IWUGO,
+		mpq_demux->demux.dmx.debugfs_demux_dir,
+		&mpq_demux->decoder_out_count);
+
+	debugfs_create_u32(
+		"decoder_out_interval_sum",
+		S_IRUGO|S_IWUGO,
+		mpq_demux->demux.dmx.debugfs_demux_dir,
+		&mpq_demux->decoder_out_interval_sum);
+
+	debugfs_create_u32(
+		"decoder_out_interval_average",
+		S_IRUGO|S_IWUGO,
+		mpq_demux->demux.dmx.debugfs_demux_dir,
+		&mpq_demux->decoder_out_interval_average);
+
+	debugfs_create_u32(
+		"decoder_out_interval_max",
+		S_IRUGO|S_IWUGO,
+		mpq_demux->demux.dmx.debugfs_demux_dir,
+		&mpq_demux->decoder_out_interval_max);
+
+	debugfs_create_u32(
+		"decoder_ts_errors",
+		S_IRUGO|S_IWUGO,
+		mpq_demux->demux.dmx.debugfs_demux_dir,
+		&mpq_demux->decoder_ts_errors);
+
+	debugfs_create_u32(
+		"sdmx_process_count",
+		S_IRUGO|S_IWUGO,
+		mpq_demux->demux.dmx.debugfs_demux_dir,
+		&mpq_demux->sdmx_process_count);
+
+	debugfs_create_u32(
+		"sdmx_process_time_sum",
+		S_IRUGO|S_IWUGO,
+		mpq_demux->demux.dmx.debugfs_demux_dir,
+		&mpq_demux->sdmx_process_time_sum);
+
+	debugfs_create_u32(
+		"sdmx_process_time_average",
+		S_IRUGO|S_IWUGO,
+		mpq_demux->demux.dmx.debugfs_demux_dir,
+		&mpq_demux->sdmx_process_time_average);
+
+	debugfs_create_u32(
+		"sdmx_process_time_max",
+		S_IRUGO|S_IWUGO,
+		mpq_demux->demux.dmx.debugfs_demux_dir,
+		&mpq_demux->sdmx_process_time_max);
+
+	debugfs_create_u32(
+		"sdmx_process_packets_sum",
+		S_IRUGO|S_IWUGO,
+		mpq_demux->demux.dmx.debugfs_demux_dir,
+		&mpq_demux->sdmx_process_packets_sum);
+
+	debugfs_create_u32(
+		"sdmx_process_packets_average",
+		S_IRUGO|S_IWUGO,
+		mpq_demux->demux.dmx.debugfs_demux_dir,
+		&mpq_demux->sdmx_process_packets_average);
+
+	debugfs_create_u32(
+		"sdmx_process_packets_min",
+		S_IRUGO|S_IWUGO,
+		mpq_demux->demux.dmx.debugfs_demux_dir,
+		&mpq_demux->sdmx_process_packets_min);
+}
+EXPORT_SYMBOL(mpq_dmx_init_hw_statistics);
+
+/* Update dvb-demux debugfs with HW notification statistics */
+void mpq_dmx_update_hw_statistics(struct mpq_demux *mpq_demux)
+{
+	struct timespec curr_time;
+	u64 delta_time_ms;
+
+	curr_time = current_kernel_time();
+	if (likely(mpq_demux->hw_notification_count)) {
+		/* calculate time-delta between notifications */
+		delta_time_ms = mpq_dmx_calc_time_delta(&curr_time,
+			&mpq_demux->last_notification_time);
+
+		mpq_demux->hw_notification_interval = delta_time_ms;
+
+		if ((mpq_demux->hw_notification_count == 1) ||
+			(mpq_demux->hw_notification_interval &&
+			 mpq_demux->hw_notification_interval <
+				mpq_demux->hw_notification_min_interval))
+			mpq_demux->hw_notification_min_interval =
+				mpq_demux->hw_notification_interval;
+	}
+
+	mpq_demux->hw_notification_count++;
+	mpq_demux->last_notification_time = curr_time;
+}
+EXPORT_SYMBOL(mpq_dmx_update_hw_statistics);
+
+static void mpq_sdmx_check_app_loaded(void)
+{
+	int session;
+	u32 version;
+	int ret;
+
+	ret = sdmx_open_session(&session);
+	if (ret != SDMX_SUCCESS) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: Could not initialize session with SDMX. ret = %d\n",
+			__func__, ret);
+		mpq_dmx_info.secure_demux_app_loaded = 0;
+		return;
+	}
+
+	/* Check proper sdmx major version */
+	ret = sdmx_get_version(session, &version);
+	if (ret != SDMX_SUCCESS) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: Could not get sdmx version. ret = %d\n",
+			__func__, ret);
+	} else {
+		if ((version >> 8) != SDMX_MAJOR_VERSION_MATCH)
+			MPQ_DVB_ERR_PRINT(
+				"%s: sdmx major version does not match. expected=%d, actual=%d\n",
+				__func__, SDMX_MAJOR_VERSION_MATCH,
+				(version >> 8));
+		else
+			MPQ_DVB_DBG_PRINT(
+				"%s: sdmx major version is ok = %d\n",
+				__func__, SDMX_MAJOR_VERSION_MATCH);
+	}
+
+	mpq_dmx_info.secure_demux_app_loaded = 1;
+	sdmx_close_session(session);
+}
+
+int mpq_dmx_plugin_init(mpq_dmx_init dmx_init_func)
+{
+	int i;
+	int j;
+	int result;
+	struct mpq_demux *mpq_demux;
+	struct dvb_adapter *mpq_adapter;
+	struct mpq_feed *feed;
+
+	MPQ_DVB_DBG_PRINT("%s executed, device num %d\n",
+					  __func__,
+					  mpq_demux_device_num);
+
+	mpq_adapter = mpq_adapter_get();
+
+	if (mpq_adapter == NULL) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: mpq_adapter is not valid\n",
+			__func__);
+		result = -EPERM;
+		goto init_failed;
+	}
+
+	if (mpq_demux_device_num == 0) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: mpq_demux_device_num set to 0\n",
+			__func__);
+
+		result = -EPERM;
+		goto init_failed;
+	}
+
+	mpq_dmx_info.devices = NULL;
+	mpq_dmx_info.ion_client = NULL;
+
+	mpq_dmx_info.secure_demux_app_loaded = 0;
+
+	/*
+	 * TODO: the following should be set based on the decoder:
+	 * 0 means the decoder doesn't handle framing, so framing
+	 * is done by demux. 1 means the decoder handles framing.
+	 */
+	mpq_dmx_info.decoder_framing = 0;
+
+	/* Allocate memory for all MPQ devices */
+	mpq_dmx_info.devices =
+		vzalloc(mpq_demux_device_num*sizeof(struct mpq_demux));
+
+	if (!mpq_dmx_info.devices) {
+		MPQ_DVB_ERR_PRINT(
+				"%s: failed to allocate devices memory\n",
+				__func__);
+
+		result = -ENOMEM;
+		goto init_failed;
+	}
+
+	/*
+	 * Create a new ION client used by demux to allocate memory
+	 * for decoder's buffers.
+	 */
+	mpq_dmx_info.ion_client =
+		msm_ion_client_create(UINT_MAX, "demux_client");
+
+	if (IS_ERR_OR_NULL(mpq_dmx_info.ion_client)) {
+		MPQ_DVB_ERR_PRINT(
+				"%s: msm_ion_client_create\n",
+				__func__);
+
+		result = PTR_ERR(mpq_dmx_info.ion_client);
+		if (!result)
+			result = -ENOMEM;
+		mpq_dmx_info.ion_client = NULL;
+		goto init_failed_free_demux_devices;
+	}
+
+	/* Initialize and register all demux devices to the system */
+	for (i = 0; i < mpq_demux_device_num; i++) {
+		mpq_demux = mpq_dmx_info.devices+i;
+
+		/* initialize demux source to memory by default */
+		mpq_demux->source = DMX_SOURCE_DVR0 + i;
+
+		/*
+		 * Give the plugin pointer to the ion client so
+		 * that it can allocate memory from ION if it requires so
+		 */
+		mpq_demux->ion_client = mpq_dmx_info.ion_client;
+
+		mutex_init(&mpq_demux->mutex);
+
+		mpq_demux->sdmx_filter_count = 0;
+		mpq_demux->sdmx_session_handle = SDMX_INVALID_SESSION_HANDLE;
+
+		if (mpq_demux->demux.feednum > MPQ_MAX_DMX_FILES) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: err - actual feednum (%d) larger than max, enlarge MPQ_MAX_DMX_FILES!\n",
+				__func__,
+				mpq_demux->demux.feednum);
+			result = -EINVAL;
+			goto init_failed_free_demux_devices;
+		}
+
+		/* Initialize private feed info */
+		for (j = 0; j < MPQ_MAX_DMX_FILES; j++) {
+			feed = &mpq_demux->feeds[j];
+			memset(feed, 0, sizeof(*feed));
+			feed->sdmx_filter_handle = SDMX_INVALID_FILTER_HANDLE;
+			feed->mpq_demux = mpq_demux;
+		}
+
+		/*
+		 * mpq_demux_plugin_hw_init should be implemented
+		 * by the specific plugin
+		 */
+		result = dmx_init_func(mpq_adapter, mpq_demux);
+		if (result < 0) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: dmx_init_func (errno=%d)\n",
+				__func__,
+				result);
+
+			goto init_failed_free_demux_devices;
+		}
+
+		mpq_demux->is_initialized = 1;
+
+		/*
+		 * dvb-demux is now initialized,
+		 * update back-pointers of private feeds
+		 */
+		for (j = 0; j < MPQ_MAX_DMX_FILES; j++) {
+			feed = &mpq_demux->feeds[j];
+			feed->dvb_demux_feed = &mpq_demux->demux.feed[j];
+			mpq_demux->demux.feed[j].priv = feed;
+		}
+
+		/*
+		 * Add capability of receiving input from memory.
+		 * Every demux in our system may be connected to memory input,
+		 * or any live input.
+		 */
+		mpq_demux->fe_memory.source = DMX_MEMORY_FE;
+		result =
+			mpq_demux->demux.dmx.add_frontend(
+					&mpq_demux->demux.dmx,
+					&mpq_demux->fe_memory);
+
+		if (result < 0) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: add_frontend (mem) failed (errno=%d)\n",
+				__func__,
+				result);
+
+			goto init_failed_free_demux_devices;
+		}
+	}
+
+	return 0;
+
+init_failed_free_demux_devices:
+	mpq_dmx_plugin_exit();
+init_failed:
+	return result;
+}
+EXPORT_SYMBOL(mpq_dmx_plugin_init);
+
+void mpq_dmx_plugin_exit(void)
+{
+	int i;
+	struct mpq_demux *mpq_demux;
+
+	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
+
+	if (mpq_dmx_info.ion_client != NULL) {
+		ion_client_destroy(mpq_dmx_info.ion_client);
+		mpq_dmx_info.ion_client = NULL;
+	}
+
+	if (mpq_dmx_info.devices != NULL) {
+		for (i = 0; i < mpq_demux_device_num; i++) {
+			mpq_demux = mpq_dmx_info.devices + i;
+
+			if (mpq_demux->is_initialized) {
+				mpq_demux->demux.dmx.remove_frontend(
+							&mpq_demux->demux.dmx,
+							&mpq_demux->fe_memory);
+
+				if (mpq_sdmx_is_loaded())
+					mpq_sdmx_close_session(mpq_demux);
+				mutex_destroy(&mpq_demux->mutex);
+				dvb_dmxdev_release(&mpq_demux->dmxdev);
+				dvb_dmx_release(&mpq_demux->demux);
+			}
+		}
+
+		vfree(mpq_dmx_info.devices);
+		mpq_dmx_info.devices = NULL;
+	}
+}
+EXPORT_SYMBOL(mpq_dmx_plugin_exit);
+
+
+int mpq_dmx_set_source(
+		struct dmx_demux *demux,
+		const dmx_source_t *src)
+{
+	int i;
+	int dvr_index;
+	int dmx_index;
+	struct dvb_demux *dvb_demux = demux->priv;
+	struct mpq_demux *mpq_demux;
+
+	if ((mpq_dmx_info.devices == NULL) || (dvb_demux == NULL)) {
+		MPQ_DVB_ERR_PRINT("%s: invalid parameters\n", __func__);
+		return -EINVAL;
+	}
+
+	mpq_demux = dvb_demux->priv;
+	if (mpq_demux == NULL) {
+		MPQ_DVB_ERR_PRINT("%s: invalid parameters\n", __func__);
+		return -EINVAL;
+	}
+
+	/*
+	 * For dvr sources,
+	 * verify that this source is connected to the respective demux
+	 */
+	dmx_index = mpq_demux - mpq_dmx_info.devices;
+
+	if (*src >= DMX_SOURCE_DVR0) {
+		dvr_index = *src - DMX_SOURCE_DVR0;
+
+		if (dvr_index != dmx_index) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: can't connect demux%d to dvr%d\n",
+				__func__,
+				dmx_index,
+				dvr_index);
+			return -EINVAL;
+		}
+	}
+
+	/*
+	 * For front-end sources,
+	 * verify that this source is not already set to different demux
+	 */
+	for (i = 0; i < mpq_demux_device_num; i++) {
+		if ((&mpq_dmx_info.devices[i] != mpq_demux) &&
+			(mpq_dmx_info.devices[i].source == *src)) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: demux%d source can't be set,\n"
+				"demux%d occupies this source already\n",
+				__func__,
+				dmx_index,
+				i);
+			return -EBUSY;
+		}
+	}
+
+	mpq_demux->source = *src;
+	return 0;
+}
+EXPORT_SYMBOL(mpq_dmx_set_source);
+
+/**
+ * Takes an ION allocated buffer's file descriptor and handles the details of
+ * mapping it into kernel memory and obtaining an ION handle for it.
+ * Internal helper function.
+ *
+ * @client: ION client
+ * @handle: ION file descriptor to map
+ * @priv_handle: returned ION handle. Must be freed when no longer needed
+ * @kernel_mem: returned kernel mapped pointer
+ *
+ * Note: mapping might not be possible in secured heaps/buffers, and so NULL
+ * might be returned in kernel_mem
+ *
+ * Return errors status
+ */
+static int mpq_map_buffer_to_kernel(
+	struct ion_client *client,
+	int handle,
+	struct ion_handle **priv_handle,
+	void **kernel_mem)
+{
+	struct ion_handle *ion_handle;
+	unsigned long ionflag = 0;
+	int ret;
+
+	if (client == NULL || priv_handle == NULL || kernel_mem == NULL) {
+		MPQ_DVB_ERR_PRINT("%s: invalid parameters\n", __func__);
+		return -EINVAL;
+	}
+
+	ion_handle = ion_import_dma_buf(client, handle);
+	if (IS_ERR_OR_NULL(ion_handle)) {
+		ret = PTR_ERR(ion_handle);
+		MPQ_DVB_ERR_PRINT("%s: ion_import_dma_buf failed %d\n",
+			__func__, ret);
+		if (!ret)
+			ret = -ENOMEM;
+
+		goto map_buffer_failed;
+	}
+
+	ret = ion_handle_get_flags(client, ion_handle, &ionflag);
+	if (ret) {
+		MPQ_DVB_ERR_PRINT("%s: ion_handle_get_flags failed %d\n",
+			__func__, ret);
+		goto map_buffer_failed_free_buff;
+	}
+
+	if (ionflag & ION_SECURE) {
+		MPQ_DVB_DBG_PRINT("%s: secured buffer\n", __func__);
+		*kernel_mem = NULL;
+	} else {
+		unsigned long tmp;
+		*kernel_mem = ion_map_kernel(client, ion_handle);
+		if (*kernel_mem == NULL) {
+			MPQ_DVB_ERR_PRINT("%s: ion_map_kernel failed\n",
+				__func__);
+			ret = -ENOMEM;
+			goto map_buffer_failed_free_buff;
+		}
+		ion_handle_get_size(client, ion_handle, &tmp);
+		MPQ_DVB_DBG_PRINT(
+			"%s: mapped to address 0x%p, size=%lu\n",
+			__func__, *kernel_mem, tmp);
+	}
+
+	*priv_handle = ion_handle;
+	return 0;
+
+map_buffer_failed_free_buff:
+	ion_free(client, ion_handle);
+map_buffer_failed:
+	return ret;
+}
+
+int mpq_dmx_map_buffer(struct dmx_demux *demux, struct dmx_buffer *dmx_buffer,
+		void **priv_handle, void **kernel_mem)
+{
+	struct dvb_demux *dvb_demux = demux->priv;
+	struct mpq_demux *mpq_demux;
+
+	if ((mpq_dmx_info.devices == NULL) || (dvb_demux == NULL) ||
+		(priv_handle == NULL) || (kernel_mem == NULL)) {
+		MPQ_DVB_ERR_PRINT("%s: invalid parameters\n", __func__);
+		return -EINVAL;
+	}
+
+	mpq_demux = dvb_demux->priv;
+	if (mpq_demux == NULL) {
+		MPQ_DVB_ERR_PRINT("%s: invalid parameters\n", __func__);
+		return -EINVAL;
+	}
+
+	return mpq_map_buffer_to_kernel(
+		mpq_demux->ion_client,
+		dmx_buffer->handle,
+		(struct ion_handle **)priv_handle, kernel_mem);
+}
+EXPORT_SYMBOL(mpq_dmx_map_buffer);
+
+int mpq_dmx_unmap_buffer(struct dmx_demux *demux,
+		void *priv_handle)
+{
+	struct dvb_demux *dvb_demux = demux->priv;
+	struct ion_handle *ion_handle = priv_handle;
+	struct mpq_demux *mpq_demux;
+	unsigned long ionflag = 0;
+	int ret;
+
+	if ((mpq_dmx_info.devices == NULL) || (dvb_demux == NULL) ||
+		(priv_handle == NULL)) {
+		MPQ_DVB_ERR_PRINT("%s: invalid parameters\n", __func__);
+		return -EINVAL;
+	}
+
+	mpq_demux = dvb_demux->priv;
+	if (mpq_demux == NULL) {
+		MPQ_DVB_ERR_PRINT("%s: invalid parameters\n", __func__);
+		return -EINVAL;
+	}
+
+	ret = ion_handle_get_flags(mpq_demux->ion_client, ion_handle, &ionflag);
+	if (ret) {
+		MPQ_DVB_ERR_PRINT("%s: ion_handle_get_flags failed %d\n",
+			__func__, ret);
+		return -EINVAL;
+	}
+
+	if (!(ionflag & ION_SECURE))
+		ion_unmap_kernel(mpq_demux->ion_client, ion_handle);
+
+	ion_free(mpq_demux->ion_client, ion_handle);
+
+	return 0;
+}
+EXPORT_SYMBOL(mpq_dmx_unmap_buffer);
+
+int mpq_dmx_reuse_decoder_buffer(struct dvb_demux_feed *feed, int cookie)
+{
+	struct mpq_demux *mpq_demux = feed->demux->priv;
+
+	if (!generate_es_events) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: Cannot release decoder buffer when not working with new elementary stream data events\n",
+			__func__);
+		return -EPERM;
+	}
+
+	if (cookie < 0) {
+		MPQ_DVB_ERR_PRINT("%s: invalid cookie parameter\n", __func__);
+		return -EINVAL;
+	}
+
+	if (mpq_dmx_is_video_feed(feed)) {
+		struct mpq_video_feed_info *feed_data;
+		struct mpq_feed *mpq_feed;
+		struct mpq_streambuffer *stream_buffer;
+		int ret;
+
+		mutex_lock(&mpq_demux->mutex);
+		mpq_feed = feed->priv;
+		feed_data = &mpq_feed->video_info;
+
+		spin_lock(&feed_data->video_buffer_lock);
+		stream_buffer = feed_data->video_buffer;
+		if (stream_buffer == NULL) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: invalid feed, feed_data->video_buffer is NULL\n",
+				__func__);
+			spin_unlock(&feed_data->video_buffer_lock);
+			mutex_unlock(&mpq_demux->mutex);
+			return -EINVAL;
+		}
+
+		ret = mpq_streambuffer_pkt_dispose(stream_buffer, cookie, 1);
+		spin_unlock(&feed_data->video_buffer_lock);
+		mutex_unlock(&mpq_demux->mutex);
+
+		return ret;
+	}
+
+	/* else */
+	MPQ_DVB_ERR_PRINT("%s: Invalid feed type %d\n",
+			__func__, feed->pes_type);
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL(mpq_dmx_reuse_decoder_buffer);
+
+/**
+ * Handles the details of internal decoder buffer allocation via ION.
+ * Internal helper function.
+ * @feed_data: decoder feed object
+ * @dec_buffs: buffer information
+ * @client: ION client
+ *
+ * Return error status
+ */
+static int mpq_dmx_init_internal_buffers(
+	struct mpq_video_feed_info *feed_data,
+	struct dmx_decoder_buffers *dec_buffs,
+	struct ion_client *client)
+{
+	struct ion_handle *temp_handle = NULL;
+	void *payload_buffer = NULL;
+	int actual_buffer_size = 0;
+	int ret = 0;
+
+	MPQ_DVB_DBG_PRINT("%s: Internal decoder buffer allocation\n", __func__);
+
+	actual_buffer_size = dec_buffs->buffers_size;
+	actual_buffer_size += (SZ_4K - 1);
+	actual_buffer_size &= ~(SZ_4K - 1);
+
+	temp_handle = ion_alloc(client, actual_buffer_size, SZ_4K,
+		ION_HEAP(video_secure_ion_heap) |
+		ION_HEAP(video_nonsecure_ion_heap),
+		ION_FLAG_CACHED);
+
+	if (IS_ERR_OR_NULL(temp_handle)) {
+		ret = PTR_ERR(temp_handle);
+		MPQ_DVB_ERR_PRINT("%s: FAILED to allocate payload buffer %d\n",
+			__func__, ret);
+		if (!ret)
+			ret = -ENOMEM;
+		goto end;
+	}
+
+	payload_buffer = ion_map_kernel(client, temp_handle);
+
+	if (IS_ERR_OR_NULL(payload_buffer)) {
+		ret = PTR_ERR(payload_buffer);
+		MPQ_DVB_ERR_PRINT(
+			"%s: FAILED to map payload buffer %d\n",
+			__func__, ret);
+		if (!ret)
+			ret = -ENOMEM;
+		goto init_failed_free_payload_buffer;
+	}
+	feed_data->buffer_desc.decoder_buffers_num = 1;
+	feed_data->buffer_desc.ion_handle[0] = temp_handle;
+	feed_data->buffer_desc.desc[0].base = payload_buffer;
+	feed_data->buffer_desc.desc[0].size = actual_buffer_size;
+	feed_data->buffer_desc.desc[0].read_ptr = 0;
+	feed_data->buffer_desc.desc[0].write_ptr = 0;
+	feed_data->buffer_desc.desc[0].handle =
+		ion_share_dma_buf(client, temp_handle);
+	if (IS_ERR_VALUE(feed_data->buffer_desc.desc[0].handle)) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: FAILED to share payload buffer %d\n",
+			__func__, ret);
+		ret = -ENOMEM;
+		goto init_failed_unmap_payload_buffer;
+	}
+
+	return 0;
+
+init_failed_unmap_payload_buffer:
+	ion_unmap_kernel(client, temp_handle);
+	feed_data->buffer_desc.desc[0].base = NULL;
+init_failed_free_payload_buffer:
+	ion_free(client, temp_handle);
+	feed_data->buffer_desc.ion_handle[0] = NULL;
+	feed_data->buffer_desc.desc[0].size = 0;
+	feed_data->buffer_desc.decoder_buffers_num = 0;
+end:
+	return ret;
+}
+
+/**
+ * Handles the details of external decoder buffers allocated by user.
+ * Each buffer is mapped into kernel memory and an ION handle is obtained, and
+ * decoder feed object is updated with related information.
+ * Internal helper function.
+ * @feed_data: decoder feed object
+ * @dec_buffs: buffer information
+ * @client: ION client
+ *
+ * Return error status
+ */
+static int mpq_dmx_init_external_buffers(
+	struct mpq_video_feed_info *feed_data,
+	struct dmx_decoder_buffers *dec_buffs,
+	struct ion_client *client)
+{
+	struct ion_handle *temp_handle = NULL;
+	void *payload_buffer = NULL;
+	int actual_buffer_size = 0;
+	int ret = 0;
+	int i;
+
+	/*
+	 * Payload buffer was allocated externally (through ION).
+	 * Map the ion handles to kernel memory
+	 */
+	MPQ_DVB_DBG_PRINT("%s: External decoder buffer allocation\n", __func__);
+
+	actual_buffer_size = dec_buffs->buffers_size;
+	if (!dec_buffs->is_linear) {
+		MPQ_DVB_DBG_PRINT("%s: Ex. Ring-buffer\n", __func__);
+		feed_data->buffer_desc.decoder_buffers_num = 1;
+	} else {
+		MPQ_DVB_DBG_PRINT("%s: Ex. Linear\n", __func__);
+		feed_data->buffer_desc.decoder_buffers_num =
+			dec_buffs->buffers_num;
+	}
+
+	for (i = 0; i < feed_data->buffer_desc.decoder_buffers_num; i++) {
+		ret = mpq_map_buffer_to_kernel(
+			client,
+			dec_buffs->handles[i],
+			&temp_handle,
+			&payload_buffer);
+		if (ret < 0) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: Failed mapping buffer %d\n",
+				__func__, i);
+			goto init_failed;
+		}
+		feed_data->buffer_desc.ion_handle[i] = temp_handle;
+		feed_data->buffer_desc.desc[i].base = payload_buffer;
+		feed_data->buffer_desc.desc[i].handle =
+			dec_buffs->handles[i];
+		feed_data->buffer_desc.desc[i].size =
+			dec_buffs->buffers_size;
+		feed_data->buffer_desc.desc[i].read_ptr = 0;
+		feed_data->buffer_desc.desc[i].write_ptr = 0;
+
+		MPQ_DVB_DBG_PRINT(
+			"%s: Buffer #%d: base=0x%p, handle=%d, size=%d\n",
+			__func__, i ,
+			feed_data->buffer_desc.desc[i].base,
+			feed_data->buffer_desc.desc[i].handle,
+			feed_data->buffer_desc.desc[i].size);
+	}
+
+	return 0;
+
+init_failed:
+	for (i = 0; i < feed_data->buffer_desc.decoder_buffers_num; i++) {
+		if (feed_data->buffer_desc.ion_handle[i]) {
+			if (feed_data->buffer_desc.desc[i].base) {
+				ion_unmap_kernel(client,
+					feed_data->buffer_desc.ion_handle[i]);
+				feed_data->buffer_desc.desc[i].base = NULL;
+			}
+			ion_free(client, feed_data->buffer_desc.ion_handle[i]);
+			feed_data->buffer_desc.ion_handle[i] = NULL;
+			feed_data->buffer_desc.desc[i].size = 0;
+		}
+	}
+	return ret;
+}
+
+/**
+ * Handles the details of initializing the mpq_streambuffer object according
+ * to the user decoder buffer configuration: External/Internal buffers and
+ * ring/linear buffering mode.
+ * Internal helper function.
+ * @feed:  dvb demux feed object, contains the buffers configuration
+ * @feed_data: decoder feed object
+ * @stream_buffer: stream buffer object to initialize
+ *
+ * Return error status
+ */
+static int mpq_dmx_init_streambuffer(
+	struct mpq_feed *feed,
+	struct mpq_video_feed_info *feed_data,
+	struct mpq_streambuffer *stream_buffer)
+{
+	int ret;
+	void *packet_buffer = NULL;
+	struct mpq_demux *mpq_demux = feed->mpq_demux;
+	struct ion_client *client = mpq_demux->ion_client;
+	struct dmx_decoder_buffers *dec_buffs = NULL;
+	enum mpq_streambuffer_mode mode;
+
+	dec_buffs = feed->dvb_demux_feed->feed.ts.decoder_buffers;
+
+	/* Allocate packet buffer holding the meta-data */
+	packet_buffer = vmalloc(VIDEO_META_DATA_BUFFER_SIZE);
+
+	if (packet_buffer == NULL) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: FAILED to allocate packets buffer\n",
+			__func__);
+
+		ret = -ENOMEM;
+		goto end;
+	}
+
+	MPQ_DVB_DBG_PRINT("%s: dec_buffs: num=%d, size=%d, linear=%d\n",
+			__func__,
+			dec_buffs->buffers_num,
+			dec_buffs->buffers_size,
+			dec_buffs->is_linear);
+
+	feed_data->buffer_desc.decoder_buffers_num = dec_buffs->buffers_num;
+	if (0 == dec_buffs->buffers_num)
+		ret = mpq_dmx_init_internal_buffers(
+			feed_data, dec_buffs, client);
+	else
+		ret = mpq_dmx_init_external_buffers(
+			feed_data, dec_buffs, client);
+
+	if (ret != 0)
+		goto init_failed_free_packet_buffer;
+
+	mode = dec_buffs->is_linear ? MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR :
+		MPQ_STREAMBUFFER_BUFFER_MODE_RING;
+	ret = mpq_streambuffer_init(
+			feed_data->video_buffer,
+			mode,
+			feed_data->buffer_desc.desc,
+			feed_data->buffer_desc.decoder_buffers_num,
+			packet_buffer,
+			VIDEO_META_DATA_BUFFER_SIZE);
+
+	if (ret != 0)
+		goto init_failed_free_packet_buffer;
+
+	goto end;
+
+
+init_failed_free_packet_buffer:
+	vfree(packet_buffer);
+end:
+	return ret;
+}
+
+static void mpq_dmx_release_streambuffer(
+	struct mpq_feed *feed,
+	struct mpq_video_feed_info *feed_data,
+	struct mpq_streambuffer *video_buffer,
+	struct ion_client *client)
+{
+	int buf_num = 0;
+	int i;
+	struct dmx_decoder_buffers *dec_buffs =
+		feed->dvb_demux_feed->feed.ts.decoder_buffers;
+
+	mpq_adapter_unregister_stream_if(feed_data->stream_interface);
+
+	vfree(video_buffer->packet_data.data);
+
+	buf_num = feed_data->buffer_desc.decoder_buffers_num;
+
+	for (i = 0; i < buf_num; i++) {
+		if (feed_data->buffer_desc.ion_handle[i]) {
+			if (feed_data->buffer_desc.desc[i].base) {
+				ion_unmap_kernel(client,
+					feed_data->buffer_desc.ion_handle[i]);
+				feed_data->buffer_desc.desc[i].base = NULL;
+			}
+
+			/*
+			 * Un-share the buffer if kernel it the one that
+			 * shared it.
+			 */
+			if (0 == dec_buffs->buffers_num) {
+				struct file *shared_file = fget(
+					feed_data->buffer_desc.desc[i].handle);
+
+				if (shared_file)
+					fput(shared_file);
+				else
+					MPQ_DVB_ERR_PRINT(
+						"%s: failed to get shared-file handle\n",
+						__func__);
+			}
+
+			ion_free(client, feed_data->buffer_desc.ion_handle[i]);
+			feed_data->buffer_desc.ion_handle[i] = NULL;
+			feed_data->buffer_desc.desc[i].size = 0;
+		}
+	}
+}
+
+/**
+ * mpq_dmx_init_video_feed - Initializes of video feed information
+ * used to pass data directly to decoder.
+ *
+ * @mpq_feed: The mpq feed object
+ *
+ * Return     error code.
+ */
+static int mpq_dmx_init_video_feed(struct mpq_feed *mpq_feed)
+{
+	int ret;
+	struct mpq_video_feed_info *feed_data = &mpq_feed->video_info;
+	struct mpq_demux *mpq_demux = mpq_feed->mpq_demux;
+	struct mpq_streambuffer *stream_buffer;
+
+	/* get and store framing information if required */
+	if (!mpq_dmx_info.decoder_framing) {
+		mpq_dmx_get_pattern_params(
+			&mpq_feed->dvb_demux_feed->indexing_params,
+			&feed_data->patterns, &feed_data->patterns_num);
+		if (feed_data->patterns == NULL) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: FAILED to get framing pattern parameters\n",
+				__func__);
+
+			ret = -EINVAL;
+			goto init_failed_free_priv_data;
+		}
+	}
+
+	/* Register the new stream-buffer interface to MPQ adapter */
+	switch (mpq_feed->dvb_demux_feed->pes_type) {
+	case DMX_TS_PES_VIDEO0:
+		feed_data->stream_interface =
+			MPQ_ADAPTER_VIDEO0_STREAM_IF;
+		break;
+
+	case DMX_TS_PES_VIDEO1:
+		feed_data->stream_interface =
+			MPQ_ADAPTER_VIDEO1_STREAM_IF;
+		break;
+
+	case DMX_TS_PES_VIDEO2:
+		feed_data->stream_interface =
+			MPQ_ADAPTER_VIDEO2_STREAM_IF;
+		break;
+
+	case DMX_TS_PES_VIDEO3:
+		feed_data->stream_interface =
+			MPQ_ADAPTER_VIDEO3_STREAM_IF;
+		break;
+
+	default:
+		MPQ_DVB_ERR_PRINT(
+			"%s: Invalid pes type %d\n",
+			__func__,
+			mpq_feed->dvb_demux_feed->pes_type);
+		ret = -EINVAL;
+		goto init_failed_free_priv_data;
+	}
+
+	/* make sure not occupied already */
+	stream_buffer = NULL;
+	mpq_adapter_get_stream_if(
+			feed_data->stream_interface,
+			&stream_buffer);
+	if (stream_buffer != NULL) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: Video interface %d already occupied!\n",
+			__func__,
+			feed_data->stream_interface);
+		ret = -EBUSY;
+		goto init_failed_free_priv_data;
+	}
+
+	feed_data->video_buffer =
+		&mpq_dmx_info.decoder_buffers[feed_data->stream_interface];
+
+	ret = mpq_dmx_init_streambuffer(
+		mpq_feed, feed_data, feed_data->video_buffer);
+	if (ret) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: mpq_dmx_init_streambuffer failed, err = %d\n",
+			__func__, ret);
+		goto init_failed_free_priv_data;
+	}
+
+	ret = mpq_adapter_register_stream_if(
+			feed_data->stream_interface,
+			feed_data->video_buffer);
+
+	if (ret < 0) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: mpq_adapter_register_stream_if failed, "
+			"err = %d\n",
+			__func__, ret);
+		goto init_failed_free_stream_buffer;
+	}
+
+	spin_lock_init(&feed_data->video_buffer_lock);
+
+	feed_data->pes_header_left_bytes = PES_MANDATORY_FIELDS_LEN;
+	feed_data->pes_header_offset = 0;
+	mpq_feed->dvb_demux_feed->pusi_seen = 0;
+	mpq_feed->dvb_demux_feed->peslen = 0;
+	feed_data->fullness_wait_cancel = 0;
+	mpq_streambuffer_get_data_rw_offset(feed_data->video_buffer, NULL,
+		&feed_data->frame_offset);
+	feed_data->last_pattern_offset = 0;
+	feed_data->pending_pattern_len = 0;
+	feed_data->last_framing_match_type = DMX_FRM_UNKNOWN;
+	feed_data->found_sequence_header_pattern = 0;
+	memset(&feed_data->prefix_size, 0,
+			sizeof(struct mpq_framing_prefix_size_masks));
+	feed_data->first_prefix_size = 0;
+	feed_data->saved_pts_dts_info.pts_exist = 0;
+	feed_data->saved_pts_dts_info.dts_exist = 0;
+	feed_data->new_pts_dts_info.pts_exist = 0;
+	feed_data->new_pts_dts_info.dts_exist = 0;
+	feed_data->saved_info_used = 1;
+	feed_data->new_info_exists = 0;
+	feed_data->first_pts_dts_copy = 1;
+	feed_data->tei_errs = 0;
+	feed_data->last_continuity = -1;
+	feed_data->continuity_errs = 0;
+	feed_data->ts_packets_num = 0;
+	feed_data->ts_dropped_bytes = 0;
+	feed_data->last_pkt_index = -1;
+
+	mpq_demux->decoder_drop_count = 0;
+	mpq_demux->decoder_out_count = 0;
+	mpq_demux->decoder_out_interval_sum = 0;
+	mpq_demux->decoder_out_interval_max = 0;
+	mpq_demux->decoder_ts_errors = 0;
+
+	return 0;
+
+init_failed_free_stream_buffer:
+	mpq_dmx_release_streambuffer(mpq_feed, feed_data,
+		feed_data->video_buffer, mpq_demux->ion_client);
+	mpq_adapter_unregister_stream_if(feed_data->stream_interface);
+init_failed_free_priv_data:
+	feed_data->video_buffer = NULL;
+	return ret;
+}
+
+/**
+ * mpq_dmx_terminate_video_feed - terminate video feed information
+ * that was previously initialized in mpq_dmx_init_video_feed
+ *
+ * @mpq_feed: The mpq feed used for the video TS packets
+ *
+ * Return     error code.
+ */
+static int mpq_dmx_terminate_video_feed(struct mpq_feed *mpq_feed)
+{
+	struct mpq_streambuffer *video_buffer;
+	struct mpq_video_feed_info *feed_data;
+	struct mpq_demux *mpq_demux = mpq_feed->mpq_demux;
+
+	if (mpq_feed == NULL)
+		return -EINVAL;
+
+	feed_data = &mpq_feed->video_info;
+
+	spin_lock(&feed_data->video_buffer_lock);
+	video_buffer = feed_data->video_buffer;
+	feed_data->video_buffer = NULL;
+	wake_up_all(&video_buffer->raw_data.queue);
+	spin_unlock(&feed_data->video_buffer_lock);
+
+	mpq_dmx_release_streambuffer(mpq_feed, feed_data,
+		video_buffer, mpq_demux->ion_client);
+
+	return 0;
+}
+
+/**
+ * mpq_sdmx_lookup_feed() - Search for a feed object that shares the same
+ * filter of the specified feed object, and return it
+ *
+ * @feed: dvb demux feed object
+ *
+ * Return the mpq_feed sharing the same filter's buffer or NULL if no
+ * such is found.
+ */
+static struct mpq_feed *mpq_sdmx_lookup_feed(struct dvb_demux_feed *feed)
+{
+	int i;
+	struct dvb_demux_feed *tmp;
+	struct mpq_demux *mpq_demux = feed->demux->priv;
+
+	for (i = 0; i < MPQ_MAX_DMX_FILES; i++) {
+		tmp = mpq_demux->feeds[i].dvb_demux_feed;
+		if ((tmp->state == DMX_STATE_GO) &&
+			(tmp != feed) &&
+			(tmp->feed.ts.buffer.ringbuff ==
+			feed->feed.ts.buffer.ringbuff)) {
+			MPQ_DVB_DBG_PRINT(
+				"%s: main feed pid=%d, secondary feed pid=%d\n",
+				__func__, tmp->pid, feed->pid);
+			return &mpq_demux->feeds[i];
+		}
+	}
+
+	return NULL;
+}
+
+static int mpq_sdmx_alloc_data_buf(struct mpq_feed *mpq_feed, size_t size)
+{
+	struct mpq_demux *mpq_demux = mpq_feed->mpq_demux;
+	void *buf_base;
+	int ret;
+
+	mpq_feed->sdmx_buf_handle = ion_alloc(mpq_demux->ion_client,
+		size,
+		SZ_4K,
+		ION_HEAP(ION_QSECOM_HEAP_ID),
+		0);
+	if (IS_ERR_OR_NULL(mpq_feed->sdmx_buf_handle)) {
+		ret = PTR_ERR(mpq_feed->sdmx_buf_handle);
+		MPQ_DVB_ERR_PRINT(
+			"%s: FAILED to allocate sdmx buffer %d\n",
+			__func__, ret);
+		if (!ret)
+			ret = -ENOMEM;
+		goto end;
+	}
+
+	buf_base = ion_map_kernel(mpq_demux->ion_client,
+		mpq_feed->sdmx_buf_handle);
+	if (IS_ERR_OR_NULL(buf_base)) {
+		ret = PTR_ERR(buf_base);
+		MPQ_DVB_ERR_PRINT(
+			"%s: FAILED to map sdmx buffer %d\n",
+			__func__, ret);
+		if (!ret)
+			ret = -ENOMEM;
+		goto failed_free_buf;
+	}
+
+	dvb_ringbuffer_init(&mpq_feed->sdmx_buf, buf_base, size);
+
+	return 0;
+
+failed_free_buf:
+	ion_free(mpq_demux->ion_client, mpq_feed->sdmx_buf_handle);
+	mpq_feed->sdmx_buf_handle = NULL;
+end:
+	return ret;
+}
+
+static int mpq_sdmx_free_data_buf(struct mpq_feed *mpq_feed)
+{
+	struct mpq_demux *mpq_demux = mpq_feed->mpq_demux;
+
+	if (mpq_feed->sdmx_buf_handle) {
+		ion_unmap_kernel(mpq_demux->ion_client,
+			mpq_feed->sdmx_buf_handle);
+		mpq_feed->sdmx_buf.data = NULL;
+		ion_free(mpq_demux->ion_client,
+			mpq_feed->sdmx_buf_handle);
+		mpq_feed->sdmx_buf_handle = NULL;
+	}
+
+	return 0;
+}
+
+static int mpq_sdmx_init_metadata_buffer(struct mpq_demux *mpq_demux,
+	struct mpq_feed *feed, struct sdmx_buff_descr *metadata_buff_desc)
+{
+	void *metadata_buff_base;
+	ion_phys_addr_t temp;
+	int ret;
+
+	feed->metadata_buf_handle = ion_alloc(mpq_demux->ion_client,
+		SDMX_METADATA_BUFFER_SIZE,
+		SZ_4K,
+		ION_HEAP(ION_QSECOM_HEAP_ID),
+		0);
+	if (IS_ERR_OR_NULL(feed->metadata_buf_handle)) {
+		ret = PTR_ERR(feed->metadata_buf_handle);
+		MPQ_DVB_ERR_PRINT(
+			"%s: FAILED to allocate metadata buffer %d\n",
+			__func__, ret);
+		if (!ret)
+			ret = -ENOMEM;
+		goto end;
+	}
+
+	metadata_buff_base = ion_map_kernel(mpq_demux->ion_client,
+		feed->metadata_buf_handle);
+	if (IS_ERR_OR_NULL(metadata_buff_base)) {
+		ret = PTR_ERR(metadata_buff_base);
+		MPQ_DVB_ERR_PRINT(
+			"%s: FAILED to map metadata buffer %d\n",
+			__func__, ret);
+		if (!ret)
+			ret = -ENOMEM;
+		goto failed_free_metadata_buf;
+	}
+
+	ret = ion_phys(mpq_demux->ion_client,
+		feed->metadata_buf_handle,
+		&temp,
+		&metadata_buff_desc->size);
+	if (ret) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: FAILED to get physical address %d\n",
+			__func__, ret);
+		goto failed_unmap_metadata_buf;
+	}
+	metadata_buff_desc->base_addr = (void *)temp;
+
+	dvb_ringbuffer_init(&feed->metadata_buf, metadata_buff_base,
+		SDMX_METADATA_BUFFER_SIZE);
+
+	return 0;
+
+failed_unmap_metadata_buf:
+	ion_unmap_kernel(mpq_demux->ion_client, feed->metadata_buf_handle);
+failed_free_metadata_buf:
+	ion_free(mpq_demux->ion_client, feed->metadata_buf_handle);
+	feed->metadata_buf_handle = NULL;
+end:
+	return ret;
+}
+
+static int mpq_sdmx_terminate_metadata_buffer(struct mpq_feed *mpq_feed)
+{
+	struct mpq_demux *mpq_demux = mpq_feed->mpq_demux;
+
+	if (mpq_feed->metadata_buf_handle) {
+		ion_unmap_kernel(mpq_demux->ion_client,
+			mpq_feed->metadata_buf_handle);
+		mpq_feed->metadata_buf.data = NULL;
+		ion_free(mpq_demux->ion_client,
+			mpq_feed->metadata_buf_handle);
+		mpq_feed->metadata_buf_handle = NULL;
+	}
+
+	return 0;
+}
+
+int mpq_dmx_terminate_feed(struct dvb_demux_feed *feed)
+{
+	int ret = 0;
+	struct mpq_demux *mpq_demux;
+	struct mpq_feed *mpq_feed;
+	struct mpq_feed *main_rec_feed;
+
+	if (feed == NULL)
+		return -EINVAL;
+
+	mpq_demux = feed->demux->priv;
+
+	mutex_lock(&mpq_demux->mutex);
+	mpq_feed = feed->priv;
+
+	if (mpq_feed->sdmx_filter_handle != SDMX_INVALID_FILTER_HANDLE) {
+		if (mpq_feed->filter_type == SDMX_RAW_FILTER)
+			main_rec_feed = mpq_sdmx_lookup_feed(feed);
+		else
+			main_rec_feed = NULL;
+
+		if (main_rec_feed) {
+			/* This feed is part of a recording filter */
+			MPQ_DVB_DBG_PRINT(
+				"%s: Removing raw pid %d from filter %d\n",
+				__func__, feed->pid,
+				mpq_feed->sdmx_filter_handle);
+			ret = sdmx_remove_raw_pid(
+				mpq_demux->sdmx_session_handle,
+				mpq_feed->sdmx_filter_handle, feed->pid);
+			if (ret)
+				MPQ_DVB_ERR_PRINT(
+					"%s: SDMX_remove_raw_pid failed. ret = %d\n",
+					__func__, ret);
+
+			/* If this feed that we are removing was set as primary,
+			 * now other feeds should be set as primary
+			 */
+			if (!mpq_feed->secondary_feed)
+				main_rec_feed->secondary_feed = 0;
+		} else {
+			MPQ_DVB_DBG_PRINT("%s: Removing filter %d, pid %d\n",
+				__func__, mpq_feed->sdmx_filter_handle,
+				feed->pid);
+			ret = sdmx_remove_filter(mpq_demux->sdmx_session_handle,
+				mpq_feed->sdmx_filter_handle);
+			if (ret) {
+				MPQ_DVB_ERR_PRINT(
+					"%s: SDMX_remove_filter failed. ret = %d\n",
+					__func__, ret);
+			}
+
+			mpq_demux->sdmx_filter_count--;
+			mpq_feed->sdmx_filter_handle =
+				SDMX_INVALID_FILTER_HANDLE;
+		}
+
+		mpq_sdmx_close_session(mpq_demux);
+	}
+
+	if (mpq_dmx_is_video_feed(feed)) {
+		ret = mpq_dmx_terminate_video_feed(mpq_feed);
+		if (ret)
+			MPQ_DVB_ERR_PRINT(
+				"%s: mpq_dmx_terminate_video_feed failed. ret = %d\n",
+				__func__, ret);
+	}
+
+	if (mpq_feed->sdmx_buf_handle) {
+		wake_up_all(&mpq_feed->sdmx_buf.queue);
+		mpq_sdmx_free_data_buf(mpq_feed);
+	}
+
+	mpq_sdmx_terminate_metadata_buffer(mpq_feed);
+
+	mutex_unlock(&mpq_demux->mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL(mpq_dmx_terminate_feed);
+
+int mpq_dmx_decoder_fullness_init(struct dvb_demux_feed *feed)
+{
+	if (mpq_dmx_is_video_feed(feed)) {
+		struct mpq_feed *mpq_feed;
+		struct mpq_video_feed_info *feed_data;
+
+		mpq_feed = feed->priv;
+		feed_data = &mpq_feed->video_info;
+		feed_data->fullness_wait_cancel = 0;
+
+		return 0;
+	}
+
+	/* else */
+	MPQ_DVB_DBG_PRINT(
+		"%s: Invalid feed type %d\n",
+		__func__,
+		feed->pes_type);
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL(mpq_dmx_decoder_fullness_init);
+
+/**
+ * Returns whether the free space of decoder's output
+ * buffer is larger than specific number of bytes.
+ *
+ * @sbuff: MPQ stream buffer used for decoder data.
+ * @required_space: number of required free bytes in the buffer
+ *
+ * Return 1 if required free bytes are available, 0 otherwise.
+ */
+static inline int mpq_dmx_check_decoder_fullness(
+	struct mpq_streambuffer *sbuff,
+	size_t required_space)
+{
+	u32 free = mpq_streambuffer_data_free(sbuff);
+
+	/*
+	 * For linear buffers, verify there's enough space for this TSP
+	 * and an additional buffer is free, as framing might required one
+	 * more buffer to be available.
+	 */
+	if (MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR == sbuff->mode)
+		return (free >= required_space &&
+			sbuff->pending_buffers_count < sbuff->buffers_num-1);
+	else
+		/* Ring buffer mode */
+		return (free >= required_space);
+}
+
+/**
+ * Checks whether decoder's output buffer has free space
+ * for specific number of bytes, if not, the function waits
+ * until the amount of free-space is available.
+ *
+ * @feed: decoder's feed object
+ * @required_space: number of required free bytes in the buffer
+ * @lock_feed: indicates whether mutex should be held before
+ * accessing the feed information. If the caller of this function
+ * already holds a mutex then this should be set to 0 and 1 otherwise.
+ *
+ * Return 0 if required space is available and error code
+ * in case waiting on buffer fullness was aborted.
+ */
+static int mpq_dmx_decoder_fullness_check(
+		struct dvb_demux_feed *feed,
+		size_t required_space,
+		int lock_feed)
+{
+	struct mpq_demux *mpq_demux = feed->demux->priv;
+	struct mpq_streambuffer *sbuff = NULL;
+	struct mpq_video_feed_info *feed_data;
+	struct mpq_feed *mpq_feed;
+	int ret = 0;
+
+	if (!mpq_dmx_is_video_feed(feed)) {
+		MPQ_DVB_DBG_PRINT("%s: Invalid feed type %d\n",
+			__func__,
+			feed->pes_type);
+		return -EINVAL;
+	}
+
+	if (lock_feed) {
+		mutex_lock(&mpq_demux->mutex);
+	} else if (!mutex_is_locked(&mpq_demux->mutex)) {
+		MPQ_DVB_ERR_PRINT(
+				"%s: Mutex should have been locked\n",
+				__func__);
+		return -EINVAL;
+	}
+
+	mpq_feed = feed->priv;
+	feed_data = &mpq_feed->video_info;
+
+	sbuff = feed_data->video_buffer;
+	if (sbuff == NULL) {
+		if (lock_feed)
+			mutex_unlock(&mpq_demux->mutex);
+		MPQ_DVB_ERR_PRINT("%s: mpq_streambuffer object is NULL\n",
+			__func__);
+		return -EINVAL;
+	}
+
+	if ((feed_data->video_buffer != NULL) &&
+		(!feed_data->fullness_wait_cancel) &&
+		(!mpq_dmx_check_decoder_fullness(sbuff, required_space))) {
+		DEFINE_WAIT(__wait);
+		for (;;) {
+			prepare_to_wait(&sbuff->raw_data.queue,
+				&__wait,
+				TASK_INTERRUPTIBLE);
+			if (!feed_data->video_buffer ||
+				feed_data->fullness_wait_cancel ||
+				mpq_dmx_check_decoder_fullness(sbuff,
+					required_space))
+				break;
+
+			if (!signal_pending(current)) {
+				mutex_unlock(&mpq_demux->mutex);
+				schedule();
+				mutex_lock(&mpq_demux->mutex);
+				continue;
+			}
+
+			ret = -ERESTARTSYS;
+			break;
+		}
+		finish_wait(&sbuff->raw_data.queue, &__wait);
+	}
+
+	if (ret < 0) {
+		if (lock_feed)
+			mutex_unlock(&mpq_demux->mutex);
+		return ret;
+	}
+
+	if ((feed_data->fullness_wait_cancel) ||
+		(feed_data->video_buffer == NULL)) {
+		if (lock_feed)
+			mutex_unlock(&mpq_demux->mutex);
+		return -EINVAL;
+	}
+
+	if (lock_feed)
+		mutex_unlock(&mpq_demux->mutex);
+	return 0;
+}
+
+int mpq_dmx_decoder_fullness_wait(
+		struct dvb_demux_feed *feed,
+		size_t required_space)
+{
+	return mpq_dmx_decoder_fullness_check(feed, required_space, 1);
+}
+EXPORT_SYMBOL(mpq_dmx_decoder_fullness_wait);
+
+int mpq_dmx_decoder_fullness_abort(struct dvb_demux_feed *feed)
+{
+	if (mpq_dmx_is_video_feed(feed)) {
+		struct mpq_feed *mpq_feed;
+		struct mpq_video_feed_info *feed_data;
+		struct dvb_ringbuffer *video_buff;
+
+		mpq_feed = feed->priv;
+		feed_data = &mpq_feed->video_info;
+
+		feed_data->fullness_wait_cancel = 1;
+
+		spin_lock(&feed_data->video_buffer_lock);
+		if (feed_data->video_buffer == NULL) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: video_buffer released\n",
+				__func__);
+			spin_unlock(&feed_data->video_buffer_lock);
+			return 0;
+		}
+
+		video_buff = &feed_data->video_buffer->raw_data;
+		wake_up_all(&video_buff->queue);
+		spin_unlock(&feed_data->video_buffer_lock);
+
+		return 0;
+	}
+
+	/* else */
+	MPQ_DVB_ERR_PRINT(
+		"%s: Invalid feed type %d\n",
+		__func__,
+		feed->pes_type);
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL(mpq_dmx_decoder_fullness_abort);
+
+
+static inline int mpq_dmx_parse_mandatory_pes_header(
+				struct dvb_demux_feed *feed,
+				struct mpq_video_feed_info *feed_data,
+				struct pes_packet_header *pes_header,
+				const u8 *buf,
+				u32 *ts_payload_offset,
+				int *bytes_avail)
+{
+	int left_size, copy_len;
+
+	if (feed_data->pes_header_offset < PES_MANDATORY_FIELDS_LEN) {
+		left_size =
+			PES_MANDATORY_FIELDS_LEN -
+			feed_data->pes_header_offset;
+
+		copy_len = (left_size > *bytes_avail) ?
+					*bytes_avail :
+					left_size;
+
+		memcpy((u8 *)((u8 *)pes_header + feed_data->pes_header_offset),
+				(buf + *ts_payload_offset),
+				copy_len);
+
+		feed_data->pes_header_offset += copy_len;
+
+		if (left_size > *bytes_avail)
+			return -EINVAL;
+
+		/* else - we have beginning of PES header */
+		*bytes_avail -= left_size;
+		*ts_payload_offset += left_size;
+
+		/* Make sure the PES packet is valid */
+		if (mpq_dmx_is_valid_video_pes(pes_header) < 0) {
+			/*
+			 * Since the new PES header parsing
+			 * failed, reset pusi_seen to drop all
+			 * data until next PUSI
+			 */
+			feed->pusi_seen = 0;
+			feed_data->pes_header_offset = 0;
+
+			MPQ_DVB_ERR_PRINT(
+				"%s: invalid packet\n",
+				__func__);
+
+			return -EINVAL;
+		}
+
+		feed_data->pes_header_left_bytes =
+			pes_header->pes_header_data_length;
+	}
+
+	return 0;
+}
+
+static inline void mpq_dmx_save_pts_dts(struct mpq_video_feed_info *feed_data)
+{
+	if (feed_data->new_info_exists) {
+		feed_data->saved_pts_dts_info.pts_exist =
+			feed_data->new_pts_dts_info.pts_exist;
+		feed_data->saved_pts_dts_info.pts =
+			feed_data->new_pts_dts_info.pts;
+		feed_data->saved_pts_dts_info.dts_exist =
+			feed_data->new_pts_dts_info.dts_exist;
+		feed_data->saved_pts_dts_info.dts =
+			feed_data->new_pts_dts_info.dts;
+
+		feed_data->new_info_exists = 0;
+		feed_data->saved_info_used = 0;
+	}
+}
+
+static inline void mpq_dmx_write_pts_dts(struct mpq_video_feed_info *feed_data,
+					struct dmx_pts_dts_info *info)
+{
+	if (!feed_data->saved_info_used) {
+		info->pts_exist = feed_data->saved_pts_dts_info.pts_exist;
+		info->pts = feed_data->saved_pts_dts_info.pts;
+		info->dts_exist = feed_data->saved_pts_dts_info.dts_exist;
+		info->dts = feed_data->saved_pts_dts_info.dts;
+
+		feed_data->saved_info_used = 1;
+	} else {
+		info->pts_exist = 0;
+		info->dts_exist = 0;
+	}
+}
+
+static inline void mpq_dmx_get_pts_dts(struct mpq_video_feed_info *feed_data,
+				struct pes_packet_header *pes_header)
+{
+	struct dmx_pts_dts_info *info = &(feed_data->new_pts_dts_info);
+
+	/* Get PTS/DTS information from PES header */
+
+	if ((pes_header->pts_dts_flag == 2) ||
+		(pes_header->pts_dts_flag == 3)) {
+		info->pts_exist = 1;
+
+		info->pts =
+			((u64)pes_header->pts_1 << 30) |
+			((u64)pes_header->pts_2 << 22) |
+			((u64)pes_header->pts_3 << 15) |
+			((u64)pes_header->pts_4 << 7) |
+			(u64)pes_header->pts_5;
+	} else {
+		info->pts_exist = 0;
+		info->pts = 0;
+	}
+
+	if (pes_header->pts_dts_flag == 3) {
+		info->dts_exist = 1;
+
+		info->dts =
+			((u64)pes_header->dts_1 << 30) |
+			((u64)pes_header->dts_2 << 22) |
+			((u64)pes_header->dts_3 << 15) |
+			((u64)pes_header->dts_4 << 7) |
+			(u64)pes_header->dts_5;
+	} else {
+		info->dts_exist = 0;
+		info->dts = 0;
+	}
+
+	feed_data->new_info_exists = 1;
+}
+
+static inline int mpq_dmx_parse_remaining_pes_header(
+				struct dvb_demux_feed *feed,
+				struct mpq_video_feed_info *feed_data,
+				struct pes_packet_header *pes_header,
+				const u8 *buf,
+				u32 *ts_payload_offset,
+				int *bytes_avail)
+{
+	int left_size, copy_len;
+
+	/* Remainning header bytes that need to be processed? */
+	if (!feed_data->pes_header_left_bytes)
+		return 0;
+
+	/* Did we capture the PTS value (if exists)? */
+	if ((*bytes_avail != 0) &&
+		(feed_data->pes_header_offset <
+		 (PES_MANDATORY_FIELDS_LEN+5)) &&
+		((pes_header->pts_dts_flag == 2) ||
+		 (pes_header->pts_dts_flag == 3))) {
+
+		/* 5 more bytes should be there */
+		left_size =
+			PES_MANDATORY_FIELDS_LEN + 5 -
+			feed_data->pes_header_offset;
+
+		copy_len = (left_size > *bytes_avail) ?
+					*bytes_avail :
+					left_size;
+
+		memcpy((u8 *)((u8 *)pes_header + feed_data->pes_header_offset),
+			(buf + *ts_payload_offset),
+			copy_len);
+
+		feed_data->pes_header_offset += copy_len;
+		feed_data->pes_header_left_bytes -= copy_len;
+
+		if (left_size > *bytes_avail)
+			return -EINVAL;
+
+		/* else - we have the PTS */
+		*bytes_avail -= copy_len;
+		*ts_payload_offset += copy_len;
+	}
+
+	/* Did we capture the DTS value (if exist)? */
+	if ((*bytes_avail != 0) &&
+		(feed_data->pes_header_offset <
+		 (PES_MANDATORY_FIELDS_LEN+10)) &&
+		(pes_header->pts_dts_flag == 3)) {
+
+		/* 5 more bytes should be there */
+		left_size =
+			PES_MANDATORY_FIELDS_LEN + 10 -
+			feed_data->pes_header_offset;
+
+		copy_len = (left_size > *bytes_avail) ?
+					*bytes_avail :
+					left_size;
+
+		memcpy((u8 *)((u8 *)pes_header + feed_data->pes_header_offset),
+			(buf + *ts_payload_offset),
+			copy_len);
+
+		feed_data->pes_header_offset += copy_len;
+		feed_data->pes_header_left_bytes -= copy_len;
+
+		if (left_size > *bytes_avail)
+			return -EINVAL;
+
+		/* else - we have the DTS */
+		*bytes_avail -= copy_len;
+		*ts_payload_offset += copy_len;
+	}
+
+	/* Any more header bytes?! */
+	if (feed_data->pes_header_left_bytes >= *bytes_avail) {
+		feed_data->pes_header_left_bytes -= *bytes_avail;
+		return -EINVAL;
+	}
+
+	/* get PTS/DTS information from PES header to be written later */
+	mpq_dmx_get_pts_dts(feed_data, pes_header);
+
+	/* Got PES header, process payload */
+	*bytes_avail -= feed_data->pes_header_left_bytes;
+	*ts_payload_offset += feed_data->pes_header_left_bytes;
+	feed_data->pes_header_left_bytes = 0;
+
+	return 0;
+}
+
+static void mpq_dmx_check_continuity(struct mpq_video_feed_info *feed_data,
+					int current_continuity,
+					int discontinuity_indicator)
+{
+	const int max_continuity = 0x0F; /* 4 bits in the TS packet header */
+
+	/* sanity check */
+	if (unlikely((current_continuity < 0) ||
+			(current_continuity > max_continuity))) {
+		MPQ_DVB_DBG_PRINT(
+			"%s: received invalid continuity counter value %d\n",
+					__func__, current_continuity);
+		return;
+	}
+
+	/* reset last continuity */
+	if ((feed_data->last_continuity == -1) ||
+		(discontinuity_indicator)) {
+		feed_data->last_continuity = current_continuity;
+		return;
+	}
+
+	/* check for continuity errors */
+	if (current_continuity !=
+			((feed_data->last_continuity + 1) & max_continuity))
+		feed_data->continuity_errs++;
+
+	/* save for next time */
+	feed_data->last_continuity = current_continuity;
+}
+
+static inline void mpq_dmx_prepare_es_event_data(
+			struct mpq_streambuffer_packet_header *packet,
+			struct mpq_adapter_video_meta_data *meta_data,
+			struct mpq_video_feed_info *feed_data,
+			struct mpq_streambuffer *stream_buffer,
+			struct dmx_data_ready *data)
+{
+	size_t len = 0;
+	struct dmx_pts_dts_info *pts_dts;
+
+	pts_dts = meta_data->packet_type == DMX_PES_PACKET ?
+		&meta_data->info.pes.pts_dts_info :
+		&meta_data->info.framing.pts_dts_info;
+
+	data->data_length = 0;
+	data->buf.handle = packet->raw_data_handle;
+	/* this has to succeed when called here, after packet was written */
+	data->buf.cookie = mpq_streambuffer_pkt_next(stream_buffer,
+				feed_data->last_pkt_index, &len);
+	data->buf.offset = packet->raw_data_offset;
+	data->buf.len = packet->raw_data_len;
+	data->buf.pts_exists = pts_dts->pts_exist;
+	data->buf.pts = pts_dts->pts;
+	data->buf.dts_exists = pts_dts->dts_exist;
+	data->buf.dts = pts_dts->dts;
+	data->buf.tei_counter = feed_data->tei_errs;
+	data->buf.cont_err_counter = feed_data->continuity_errs;
+	data->buf.ts_packets_num = feed_data->ts_packets_num;
+	data->buf.ts_dropped_bytes = feed_data->ts_dropped_bytes;
+	data->status = DMX_OK_DECODER_BUF;
+
+	/* save for next time: */
+	feed_data->last_pkt_index = data->buf.cookie;
+
+	/* reset counters */
+	feed_data->ts_packets_num = 0;
+	feed_data->ts_dropped_bytes = 0;
+	feed_data->tei_errs = 0;
+	feed_data->continuity_errs = 0;
+}
+
+static int mpq_dmx_process_video_packet_framing(
+			struct dvb_demux_feed *feed,
+			const u8 *buf)
+{
+	int bytes_avail;
+	u32 ts_payload_offset;
+	struct mpq_video_feed_info *feed_data;
+	const struct ts_packet_header *ts_header;
+	struct mpq_streambuffer *stream_buffer;
+	struct pes_packet_header *pes_header;
+	struct mpq_demux *mpq_demux;
+	struct mpq_feed *mpq_feed;
+
+	struct mpq_framing_pattern_lookup_results framing_res;
+	struct mpq_streambuffer_packet_header packet;
+	struct mpq_adapter_video_meta_data meta_data;
+	int bytes_written = 0;
+	int bytes_to_write = 0;
+	int found_patterns = 0;
+	int first_pattern = 0;
+	int i;
+	int is_video_frame = 0;
+	int pending_data_len = 0;
+	int ret = 0;
+	int discontinuity_indicator = 0;
+	struct dmx_data_ready data;
+
+	mpq_demux = feed->demux->priv;
+
+	mpq_feed = feed->priv;
+	feed_data = &mpq_feed->video_info;
+
+	/*
+	 * spin-lock is taken to protect against manipulation of video
+	 * output buffer by the API (terminate video feed, re-use of video
+	 * buffers). Mutex on the video-feed cannot be held here
+	 * since SW demux holds a spin-lock while calling write_to_decoder
+	 */
+	spin_lock(&feed_data->video_buffer_lock);
+	stream_buffer = feed_data->video_buffer;
+
+	if (stream_buffer == NULL) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: video_buffer released\n",
+			__func__);
+		spin_unlock(&feed_data->video_buffer_lock);
+		return 0;
+	}
+
+	ts_header = (const struct ts_packet_header *)buf;
+
+	pes_header = &feed_data->pes_header;
+
+	/* Make sure this TS packet has a payload and not scrambled */
+	if ((ts_header->sync_byte != 0x47) ||
+		(ts_header->adaptation_field_control == 0) ||
+		(ts_header->adaptation_field_control == 2) ||
+		(ts_header->transport_scrambling_control)) {
+		/* continue to next packet */
+		spin_unlock(&feed_data->video_buffer_lock);
+		return 0;
+	}
+
+	if (ts_header->payload_unit_start_indicator) { /* PUSI? */
+		if (feed->pusi_seen) { /* Did we see PUSI before? */
+			/*
+			 * Double check that we are not in middle of
+			 * previous PES header parsing.
+			 */
+			if (feed_data->pes_header_left_bytes != 0) {
+				MPQ_DVB_ERR_PRINT(
+					"%s: received PUSI"
+					"while handling PES header"
+					"of previous PES\n",
+					__func__);
+			}
+
+			feed->peslen = 0;
+			feed_data->pes_header_offset = 0;
+			feed_data->pes_header_left_bytes =
+				PES_MANDATORY_FIELDS_LEN;
+		} else {
+			feed->pusi_seen = 1;
+		}
+	}
+
+	/*
+	 * Parse PES data only if PUSI was encountered,
+	 * otherwise the data is dropped
+	 */
+	if (!feed->pusi_seen) {
+		spin_unlock(&feed_data->video_buffer_lock);
+		return 0; /* drop and wait for next packets */
+	}
+
+	ts_payload_offset = sizeof(struct ts_packet_header);
+
+	/*
+	 * Skip adaptation field if exists.
+	 * Save discontinuity indicator if exists.
+	 */
+	if (ts_header->adaptation_field_control == 3) {
+		const struct ts_adaptation_field *adaptation_field;
+		adaptation_field = (const struct ts_adaptation_field *)
+			(buf + ts_payload_offset);
+		discontinuity_indicator =
+			adaptation_field->discontinuity_indicator;
+		ts_payload_offset += buf[ts_payload_offset] + 1;
+	}
+
+	/* 188 bytes: the size of a TS packet including the TS packet header */
+	bytes_avail = 188 - ts_payload_offset;
+
+	/* Get the mandatory fields of the video PES header */
+	if (mpq_dmx_parse_mandatory_pes_header(feed, feed_data,
+						pes_header, buf,
+						&ts_payload_offset,
+						&bytes_avail)) {
+		spin_unlock(&feed_data->video_buffer_lock);
+		return 0;
+	}
+
+	if (mpq_dmx_parse_remaining_pes_header(feed, feed_data,
+						pes_header, buf,
+						&ts_payload_offset,
+						&bytes_avail)) {
+		spin_unlock(&feed_data->video_buffer_lock);
+		return 0;
+	}
+
+	/*
+	 * If we reached here,
+	 * then we are now at the PES payload data
+	 */
+	if (bytes_avail == 0) {
+		spin_unlock(&feed_data->video_buffer_lock);
+		return 0;
+	}
+
+	/*
+	 * the decoder requires demux to do framing,
+	 * so search for the patterns now.
+	 */
+	found_patterns = mpq_dmx_framing_pattern_search(
+				feed_data->patterns,
+				feed_data->patterns_num,
+				(buf + ts_payload_offset),
+				bytes_avail,
+				&feed_data->prefix_size,
+				&framing_res);
+
+	if (!(feed_data->found_sequence_header_pattern)) {
+		for (i = 0; i < found_patterns; i++) {
+			if ((framing_res.info[i].type ==
+				DMX_FRM_MPEG2_SEQUENCE_HEADER) ||
+			    (framing_res.info[i].type ==
+				DMX_FRM_H264_SPS) ||
+			    (framing_res.info[i].type ==
+				DMX_FRM_VC1_SEQUENCE_HEADER)) {
+
+				MPQ_DVB_DBG_PRINT(
+					"%s: Found Sequence Pattern, buf %p, i = %d, offset = %d, type = %d\n",
+					__func__, buf, i,
+					framing_res.info[i].offset,
+					framing_res.info[i].type);
+
+				first_pattern = i;
+				feed_data->found_sequence_header_pattern = 1;
+				ts_payload_offset +=
+					framing_res.info[i].offset;
+				bytes_avail -= framing_res.info[i].offset;
+
+				if (framing_res.info[i].used_prefix_size) {
+					feed_data->first_prefix_size =
+						framing_res.info[i].
+							used_prefix_size;
+				}
+				break;
+			}
+		}
+	}
+
+	/*
+	 * If decoder requires demux to do framing,
+	 * pass data to decoder only after sequence header
+	 * or equivalent is found. Otherwise the data is dropped.
+	 */
+	if (!(feed_data->found_sequence_header_pattern)) {
+		spin_unlock(&feed_data->video_buffer_lock);
+		return 0;
+	}
+
+	/* Update error counters based on TS header */
+	feed_data->ts_packets_num++;
+	feed_data->tei_errs += ts_header->transport_error_indicator;
+	mpq_demux->decoder_ts_errors += ts_header->transport_error_indicator;
+	mpq_dmx_check_continuity(feed_data,
+				ts_header->continuity_counter,
+				discontinuity_indicator);
+
+	/* Need to back-up the PTS information of the very first frame */
+	if (feed_data->first_pts_dts_copy) {
+		for (i = first_pattern; i < found_patterns; i++) {
+			is_video_frame = mpq_dmx_is_video_frame(
+					feed->indexing_params.standard,
+					framing_res.info[i].type);
+
+			if (is_video_frame) {
+				mpq_dmx_save_pts_dts(feed_data);
+				feed_data->first_pts_dts_copy = 0;
+				break;
+			}
+		}
+	}
+
+	/*
+	 * write prefix used to find first Sequence pattern, if needed.
+	 * feed_data->patterns[0].pattern always contains the Sequence
+	 * pattern.
+	 */
+	if (feed_data->first_prefix_size) {
+		if (mpq_streambuffer_data_write(stream_buffer,
+					(feed_data->patterns[0].pattern),
+					feed_data->first_prefix_size) < 0) {
+			mpq_demux->decoder_drop_count +=
+				feed_data->first_prefix_size;
+			feed_data->ts_dropped_bytes +=
+				feed_data->first_prefix_size;
+			MPQ_DVB_DBG_PRINT("%s: could not write prefix\n",
+				__func__);
+		} else {
+			MPQ_DVB_DBG_PRINT(
+				"%s: Writing pattern prefix of size %d\n",
+				__func__, feed_data->first_prefix_size);
+			/*
+			 * update the length of the data we report
+			 * to include the size of the prefix that was used.
+			 */
+			feed_data->pending_pattern_len +=
+				feed_data->first_prefix_size;
+		}
+	}
+
+	feed->peslen += bytes_avail;
+	pending_data_len += bytes_avail;
+
+	meta_data.packet_type = DMX_FRAMING_INFO_PACKET;
+	packet.user_data_len = sizeof(struct mpq_adapter_video_meta_data);
+
+	/*
+	 * Go over all the patterns that were found in this packet.
+	 * For each pattern found, write the relevant data to the data
+	 * buffer, then write the respective meta-data.
+	 * Each pattern can only be reported when the next pattern is found
+	 * (in order to know the data length).
+	 * There are three possible cases for each pattern:
+	 * 1. This is the very first pattern we found in any TS packet in this
+	 *    feed.
+	 * 2. This is the first pattern found in this TS packet, but we've
+	 *    already found patterns in previous packets.
+	 * 3. This is not the first pattern in this packet, i.e., we've
+	 *    already found patterns in this TS packet.
+	 */
+	for (i = first_pattern; i < found_patterns; i++) {
+		if (i == first_pattern) {
+			/*
+			 * The way to identify the very first pattern:
+			 * 1. It's the first pattern found in this packet.
+			 * 2. The pending_pattern_len, which indicates the
+			 *    data length of the previous pattern that has
+			 *    not yet been reported, is usually 0. However,
+			 *    it may be larger than 0 if a prefix was used
+			 *    to find this pattern (i.e., the pattern was
+			 *    split over two TS packets). In that case,
+			 *    pending_pattern_len equals first_prefix_size.
+			 *    first_prefix_size is set to 0 later in this
+			 *    function.
+			 */
+			if (feed_data->first_prefix_size ==
+				feed_data->pending_pattern_len) {
+				/*
+				 * This is the very first pattern, so no
+				 * previous pending frame data exists.
+				 * Update frame info and skip to the
+				 * next frame.
+				 */
+				feed_data->last_framing_match_type =
+					framing_res.info[i].type;
+				feed_data->last_pattern_offset =
+					framing_res.info[i].offset;
+				continue;
+			}
+			/*
+			 * This is the first pattern in this
+			 * packet and previous frame from
+			 * previous packet is pending for report
+			 */
+			bytes_to_write = framing_res.info[i].offset;
+		} else {
+			/*
+			 * Previous pending frame is in
+			 * the same packet
+			 */
+			bytes_to_write =
+				framing_res.info[i].offset -
+				feed_data->last_pattern_offset;
+		}
+
+		if (mpq_streambuffer_data_write(
+			stream_buffer,
+			(buf + ts_payload_offset + bytes_written),
+			bytes_to_write) < 0) {
+			mpq_demux->decoder_drop_count += bytes_to_write;
+			feed_data->ts_dropped_bytes += bytes_to_write;
+			MPQ_DVB_DBG_PRINT(
+				"%s: Couldn't write %d bytes to data buffer\n",
+				__func__, bytes_to_write);
+		} else {
+			bytes_written += bytes_to_write;
+			pending_data_len -= bytes_to_write;
+			feed_data->pending_pattern_len += bytes_to_write;
+		}
+
+		is_video_frame = mpq_dmx_is_video_frame(
+				feed->indexing_params.standard,
+				feed_data->last_framing_match_type);
+
+		if (is_video_frame == 1) {
+			mpq_dmx_write_pts_dts(feed_data,
+				&(meta_data.info.framing.pts_dts_info));
+			mpq_dmx_save_pts_dts(feed_data);
+
+			packet.raw_data_len = feed_data->pending_pattern_len;
+			packet.raw_data_offset = feed_data->frame_offset;
+			meta_data.info.framing.pattern_type =
+				feed_data->last_framing_match_type;
+
+			mpq_streambuffer_get_buffer_handle(
+				stream_buffer,
+				0,	/* current write buffer handle */
+				&packet.raw_data_handle);
+
+			mpq_dmx_update_decoder_stat(mpq_demux);
+
+			/*
+			 * writing meta-data that includes
+			 * the framing information
+			 */
+			if (mpq_streambuffer_pkt_write(stream_buffer,
+				&packet,
+				(u8 *)&meta_data) < 0) {
+				MPQ_DVB_ERR_PRINT(
+					"%s: "
+					"Couldn't write packet. "
+					"Should never happen\n",
+					__func__);
+			}
+
+			if (generate_es_events) {
+				mpq_dmx_prepare_es_event_data(
+					&packet, &meta_data, feed_data,
+					stream_buffer, &data);
+
+				feed->data_ready_cb.ts(&feed->feed.ts, &data);
+			}
+
+			feed_data->pending_pattern_len = 0;
+			mpq_streambuffer_get_data_rw_offset(
+				feed_data->video_buffer,
+				NULL,
+				&feed_data->frame_offset);
+		}
+
+		/* save the last match for next time */
+		feed_data->last_framing_match_type =
+			framing_res.info[i].type;
+		feed_data->last_pattern_offset =
+			framing_res.info[i].offset;
+	}
+
+	feed_data->first_prefix_size = 0;
+
+	if (pending_data_len) {
+		ret = mpq_streambuffer_data_write(
+			stream_buffer,
+			(buf + ts_payload_offset + bytes_written),
+			pending_data_len);
+		if (ret < 0) {
+			mpq_demux->decoder_drop_count += pending_data_len;
+			feed_data->ts_dropped_bytes += pending_data_len;
+			MPQ_DVB_DBG_PRINT(
+				"%s: Couldn't write %d bytes to data buffer\n",
+				__func__, pending_data_len);
+		} else {
+			feed_data->pending_pattern_len += pending_data_len;
+		}
+	}
+
+	spin_unlock(&feed_data->video_buffer_lock);
+	return 0;
+}
+
+static int mpq_dmx_process_video_packet_no_framing(
+			struct dvb_demux_feed *feed,
+			const u8 *buf)
+{
+	int bytes_avail;
+	u32 ts_payload_offset;
+	struct mpq_video_feed_info *feed_data;
+	const struct ts_packet_header *ts_header;
+	struct mpq_streambuffer *stream_buffer;
+	struct pes_packet_header *pes_header;
+	struct mpq_demux *mpq_demux;
+	struct mpq_feed *mpq_feed;
+	int discontinuity_indicator = 0;
+	struct dmx_data_ready data;
+
+	mpq_demux = feed->demux->priv;
+	mpq_feed = feed->priv;
+	feed_data = &mpq_feed->video_info;
+
+	/*
+	 * spin-lock is taken to protect against manipulation of video
+	 * output buffer by the API (terminate video feed, re-use of video
+	 * buffers). Mutex on the video-feed cannot be held here
+	 * since SW demux holds a spin-lock while calling write_to_decoder
+	 */
+	spin_lock(&feed_data->video_buffer_lock);
+	stream_buffer = feed_data->video_buffer;
+	if (stream_buffer == NULL) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: video_buffer released\n",
+			__func__);
+		spin_unlock(&feed_data->video_buffer_lock);
+		return 0;
+	}
+
+	ts_header = (const struct ts_packet_header *)buf;
+
+	pes_header = &feed_data->pes_header;
+
+	/* Make sure this TS packet has a payload and not scrambled */
+	if ((ts_header->sync_byte != 0x47) ||
+		(ts_header->adaptation_field_control == 0) ||
+		(ts_header->adaptation_field_control == 2) ||
+		(ts_header->transport_scrambling_control)) {
+		/* continue to next packet */
+		spin_unlock(&feed_data->video_buffer_lock);
+		return 0;
+	}
+
+	if (ts_header->payload_unit_start_indicator) { /* PUSI? */
+		if (feed->pusi_seen) { /* Did we see PUSI before? */
+			struct mpq_streambuffer_packet_header packet;
+			struct mpq_adapter_video_meta_data meta_data;
+
+			/*
+			 * Close previous PES.
+			 * Push new packet to the meta-data buffer.
+			 * Double check that we are not in middle of
+			 * previous PES header parsing.
+			 */
+
+			if (0 == feed_data->pes_header_left_bytes) {
+				packet.raw_data_len = feed->peslen;
+				mpq_streambuffer_get_buffer_handle(
+					stream_buffer,
+					0, /* current write buffer handle */
+					&packet.raw_data_handle);
+				packet.raw_data_offset =
+					feed_data->frame_offset;
+				packet.user_data_len =
+					sizeof(struct
+						mpq_adapter_video_meta_data);
+
+				mpq_dmx_write_pts_dts(feed_data,
+					&(meta_data.info.pes.pts_dts_info));
+				mpq_dmx_save_pts_dts(feed_data);
+
+				meta_data.packet_type = DMX_PES_PACKET;
+
+				mpq_dmx_update_decoder_stat(mpq_demux);
+
+				if (mpq_streambuffer_pkt_write(
+						stream_buffer,
+						&packet,
+						(u8 *)&meta_data) < 0)
+					MPQ_DVB_ERR_PRINT(
+						"%s: "
+						"Couldn't write packet. "
+						"Should never happen\n",
+						__func__);
+
+				/* Save write offset where new PES will begin */
+				mpq_streambuffer_get_data_rw_offset(
+					stream_buffer,
+					NULL,
+					&feed_data->frame_offset);
+
+				if (generate_es_events) {
+					mpq_dmx_prepare_es_event_data(
+						&packet, &meta_data,
+						feed_data,
+						stream_buffer, &data);
+
+					feed->data_ready_cb.ts(
+						&feed->feed.ts, &data);
+				}
+			} else {
+				MPQ_DVB_ERR_PRINT(
+					"%s: received PUSI"
+					"while handling PES header"
+					"of previous PES\n",
+					__func__);
+			}
+
+			/* Reset PES info */
+			feed->peslen = 0;
+			feed_data->pes_header_offset = 0;
+			feed_data->pes_header_left_bytes =
+				PES_MANDATORY_FIELDS_LEN;
+		} else {
+			feed->pusi_seen = 1;
+		}
+	}
+
+	/*
+	 * Parse PES data only if PUSI was encountered,
+	 * otherwise the data is dropped
+	 */
+	if (!feed->pusi_seen) {
+		spin_unlock(&feed_data->video_buffer_lock);
+		return 0; /* drop and wait for next packets */
+	}
+
+	ts_payload_offset = sizeof(struct ts_packet_header);
+
+	/*
+	 * Skip adaptation field if exists.
+	 * Save discontinuity indicator if exists.
+	 */
+	if (ts_header->adaptation_field_control == 3) {
+		const struct ts_adaptation_field *adaptation_field;
+		adaptation_field = (const struct ts_adaptation_field *)
+			(buf + ts_payload_offset);
+		discontinuity_indicator =
+			adaptation_field->discontinuity_indicator;
+		ts_payload_offset += buf[ts_payload_offset] + 1;
+	}
+
+	/* 188 bytes: size of a TS packet including the TS packet header */
+	bytes_avail = 188 - ts_payload_offset;
+
+	/* Get the mandatory fields of the video PES header */
+	if (mpq_dmx_parse_mandatory_pes_header(feed, feed_data,
+						pes_header, buf,
+						&ts_payload_offset,
+						&bytes_avail)) {
+		spin_unlock(&feed_data->video_buffer_lock);
+		return 0;
+	}
+
+	if (mpq_dmx_parse_remaining_pes_header(feed, feed_data,
+						pes_header, buf,
+						&ts_payload_offset,
+						&bytes_avail)) {
+		spin_unlock(&feed_data->video_buffer_lock);
+		return 0;
+	}
+
+	/*
+	 * If we reached here,
+	 * then we are now at the PES payload data
+	 */
+	if (bytes_avail == 0) {
+		spin_unlock(&feed_data->video_buffer_lock);
+		return 0;
+	}
+
+	/*
+	 * Need to back-up the PTS information
+	 * of the very first PES
+	 */
+	if (feed_data->first_pts_dts_copy) {
+		mpq_dmx_save_pts_dts(feed_data);
+		feed_data->first_pts_dts_copy = 0;
+	}
+
+	/* Update error counters based on TS header */
+	feed_data->ts_packets_num++;
+	feed_data->tei_errs += ts_header->transport_error_indicator;
+	mpq_demux->decoder_ts_errors += ts_header->transport_error_indicator;
+	mpq_dmx_check_continuity(feed_data,
+				ts_header->continuity_counter,
+				discontinuity_indicator);
+
+	if (mpq_streambuffer_data_write(
+				stream_buffer,
+				buf+ts_payload_offset,
+				bytes_avail) < 0) {
+		mpq_demux->decoder_drop_count += bytes_avail;
+		feed_data->ts_dropped_bytes += bytes_avail;
+	} else {
+		feed->peslen += bytes_avail;
+	}
+
+	spin_unlock(&feed_data->video_buffer_lock);
+
+	return 0;
+}
+
+int mpq_dmx_decoder_buffer_status(struct dvb_demux_feed *feed,
+		struct dmx_buffer_status *dmx_buffer_status)
+{
+	struct mpq_demux *mpq_demux = feed->demux->priv;
+	struct mpq_video_feed_info *feed_data;
+	struct mpq_streambuffer *video_buff;
+	struct mpq_feed *mpq_feed;
+
+	if (!mpq_dmx_is_video_feed(feed)) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: Invalid feed type %d\n",
+			__func__,
+			feed->pes_type);
+		return -EINVAL;
+	}
+
+	mutex_lock(&mpq_demux->mutex);
+
+	mpq_feed = feed->priv;
+	feed_data = &mpq_feed->video_info;
+	video_buff = feed_data->video_buffer;
+	if (!video_buff) {
+		mutex_unlock(&mpq_demux->mutex);
+		return -EINVAL;
+	}
+
+	dmx_buffer_status->error = video_buff->raw_data.error;
+
+	if (MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR == video_buff->mode) {
+		dmx_buffer_status->fullness =
+			video_buff->buffers[0].size *
+			video_buff->pending_buffers_count;
+		dmx_buffer_status->free_bytes =
+			video_buff->buffers[0].size *
+			(video_buff->buffers_num -
+			video_buff->pending_buffers_count);
+		dmx_buffer_status->size =
+			video_buff->buffers[0].size *
+			video_buff->buffers_num;
+	} else {
+		dmx_buffer_status->fullness =
+			mpq_streambuffer_data_avail(video_buff);
+		dmx_buffer_status->free_bytes =
+			mpq_streambuffer_data_free(video_buff);
+		dmx_buffer_status->size = video_buff->buffers[0].size;
+	}
+
+	mpq_streambuffer_get_data_rw_offset(
+		video_buff,
+		&dmx_buffer_status->read_offset,
+		&dmx_buffer_status->write_offset);
+
+	mutex_unlock(&mpq_demux->mutex);
+
+	return 0;
+}
+EXPORT_SYMBOL(mpq_dmx_decoder_buffer_status);
+
+int mpq_dmx_process_video_packet(
+			struct dvb_demux_feed *feed,
+			const u8 *buf)
+{
+	if (mpq_dmx_info.decoder_framing)
+		return mpq_dmx_process_video_packet_no_framing(feed, buf);
+	else
+		return mpq_dmx_process_video_packet_framing(feed, buf);
+}
+EXPORT_SYMBOL(mpq_dmx_process_video_packet);
+
+/*
+ * Extract the PCR field and discontinuity indicator from a TS packet buffer
+ * @buf: TSP buffer
+ * @pcr: returned PCR value
+ * @dci: returned discontinuity indicator
+ * Returns 1 if PCR was extracted, 0 otherwise.
+ */
+static int mpq_dmx_extract_pcr_and_dci(const u8 *buf, u64 *pcr, int *dci)
+{
+	const struct ts_packet_header *ts_header;
+	const struct ts_adaptation_field *adaptation_field;
+
+	if (buf == NULL || pcr == NULL || dci == NULL)
+		return 0;
+
+	ts_header = (const struct ts_packet_header *)buf;
+
+	/* Make sure this TS packet has a adaptation field */
+	if ((ts_header->sync_byte != 0x47) ||
+		(ts_header->adaptation_field_control == 0) ||
+		(ts_header->adaptation_field_control == 1) ||
+		ts_header->transport_error_indicator)
+		return 0;
+
+	adaptation_field = (const struct ts_adaptation_field *)
+			(buf + sizeof(struct ts_packet_header));
+
+	if ((!adaptation_field->adaptation_field_length) ||
+		(!adaptation_field->PCR_flag))
+		return 0; /* 0 adaptation field or no PCR */
+
+	*pcr = ((u64)adaptation_field->program_clock_reference_base_1) << 25;
+	*pcr += ((u64)adaptation_field->program_clock_reference_base_2) << 17;
+	*pcr += ((u64)adaptation_field->program_clock_reference_base_3) << 9;
+	*pcr += ((u64)adaptation_field->program_clock_reference_base_4) << 1;
+	*pcr += adaptation_field->program_clock_reference_base_5;
+	*pcr *= 300;
+	*pcr += (((u64)adaptation_field->program_clock_reference_ext_1) << 8) +
+		adaptation_field->program_clock_reference_ext_2;
+
+	*dci = adaptation_field->discontinuity_indicator;
+
+	return 1;
+}
+
+int mpq_dmx_process_pcr_packet(
+			struct dvb_demux_feed *feed,
+			const u8 *buf)
+{
+	u64 stc;
+	struct dmx_data_ready data;
+	struct mpq_demux *mpq_demux = feed->demux->priv;
+
+	if (0 == mpq_dmx_extract_pcr_and_dci(buf, &data.pcr.pcr,
+		&data.pcr.disc_indicator_set))
+		return 0;
+
+	/*
+	 * When we play from front-end, we configure HW
+	 * to output the extra timestamp, if we are playing
+	 * from DVR, we don't have a timestamp if the packet
+	 * format is not 192-tail.
+	 */
+	if ((mpq_demux->source >= DMX_SOURCE_DVR0) &&
+		(mpq_demux->demux.tsp_format != DMX_TSP_FORMAT_192_TAIL)) {
+		stc = 0;
+	} else {
+		stc = buf[190] << 16;
+		stc += buf[189] << 8;
+		stc += buf[188];
+		stc *= 256; /* convert from 105.47 KHZ to 27MHz */
+	}
+
+	data.data_length = 0;
+	data.pcr.stc = stc;
+	data.status = DMX_OK_PCR;
+	feed->data_ready_cb.ts(&feed->feed.ts, &data);
+
+	return 0;
+}
+EXPORT_SYMBOL(mpq_dmx_process_pcr_packet);
+
+int mpq_dmx_set_secure_mode(struct dvb_demux_feed *feed,
+	struct dmx_secure_mode *sec_mode)
+{
+	struct mpq_feed *mpq_feed;
+	struct mpq_demux *mpq_demux;
+	int ret;
+
+	if (!feed || !feed->priv || !sec_mode) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: invalid parameters\n",
+			__func__);
+		return -EINVAL;
+	}
+
+	MPQ_DVB_DBG_PRINT("%s(%d, %d, %d)\n",
+		__func__, sec_mode->pid,
+		sec_mode->is_secured,
+		sec_mode->key_ladder_id);
+
+	mpq_feed = feed->priv;
+	mpq_demux = mpq_feed->mpq_demux;
+
+	mutex_lock(&mpq_demux->mutex);
+
+	/*
+	 * If secure demux is active, set the KL now,
+	 * otherwise it will be set when secure-demux is started
+	 * (when filtering starts).
+	 */
+	if (mpq_demux->sdmx_session_handle !=
+		SDMX_INVALID_SESSION_HANDLE) {
+		if (sec_mode->is_secured) {
+			MPQ_DVB_DBG_PRINT(
+				"%s: set key-ladder %d to PID %d\n",
+				__func__,
+				sec_mode->key_ladder_id,
+				sec_mode->pid);
+			ret = sdmx_set_kl_ind(mpq_demux->sdmx_session_handle,
+				sec_mode->pid, sec_mode->key_ladder_id);
+			if (ret) {
+				MPQ_DVB_ERR_PRINT(
+					"%s: FAILED to set keyladder, ret=%d\n",
+					__func__, ret);
+				ret = -EINVAL;
+			}
+		} else {
+			MPQ_DVB_DBG_PRINT("%s: setting non-secure mode\n",
+				__func__);
+			ret = 0;
+		}
+	} else {
+		MPQ_DVB_DBG_PRINT("%s: SDMX not started yet\n", __func__);
+		ret = 0;
+	}
+
+	mutex_unlock(&mpq_demux->mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL(mpq_dmx_set_secure_mode);
+
+int mpq_sdmx_open_session(struct mpq_demux *mpq_demux)
+{
+	enum sdmx_status ret = SDMX_SUCCESS;
+	enum sdmx_proc_mode proc_mode;
+	enum sdmx_pkt_format pkt_format;
+
+	MPQ_DVB_DBG_PRINT("%s: ref_count %d\n",
+		__func__, mpq_demux->sdmx_session_ref_count);
+
+	if (mpq_demux->sdmx_session_ref_count) {
+		/* session is already open */
+		mpq_demux->sdmx_session_ref_count++;
+		return ret;
+	}
+
+	proc_mode = (mpq_demux->demux.playback_mode == DMX_PB_MODE_PUSH) ?
+		SDMX_PUSH_MODE : SDMX_PULL_MODE;
+	MPQ_DVB_DBG_PRINT(
+		"%s: Proc mode = %s\n",
+		__func__, SDMX_PUSH_MODE == proc_mode ? "Push" : "Pull");
+
+	if (mpq_demux->source < DMX_SOURCE_DVR0) {
+		pkt_format = SDMX_192_BYTE_PKT;
+	} else if (DMX_TSP_FORMAT_188 == mpq_demux->demux.tsp_format) {
+		pkt_format = SDMX_188_BYTE_PKT;
+	} else if (DMX_TSP_FORMAT_192_TAIL == mpq_demux->demux.tsp_format) {
+		pkt_format = SDMX_192_BYTE_PKT;
+	} else {
+		MPQ_DVB_ERR_PRINT("%s: invalid tsp format\n", __func__);
+		return -EINVAL;
+	}
+
+	MPQ_DVB_DBG_PRINT("%s: (%s) source, packet format: %d\n",
+		 __func__,
+		 (mpq_demux->source < DMX_SOURCE_DVR0) ?
+		 "frontend" : "DVR", pkt_format);
+
+	/* open session and set configuration */
+	ret = sdmx_open_session(&mpq_demux->sdmx_session_handle);
+	if (ret != SDMX_SUCCESS) {
+		MPQ_DVB_ERR_PRINT("%s: Could not open session. ret=%d\n",
+			__func__ , ret);
+		return ret;
+	}
+
+	MPQ_DVB_DBG_PRINT("%s: new session_handle = %d\n",
+		__func__ , mpq_demux->sdmx_session_handle);
+
+	ret = sdmx_set_session_cfg(mpq_demux->sdmx_session_handle,
+		proc_mode,
+		SDMX_PKT_ENC_MODE,
+		pkt_format,
+		mpq_sdmx_scramble_odd,
+		mpq_sdmx_scramble_even);
+	if (ret != SDMX_SUCCESS) {
+		MPQ_DVB_ERR_PRINT("%s: Could not set session config. ret=%d\n",
+			__func__, ret);
+		sdmx_close_session(mpq_demux->sdmx_session_handle);
+		mpq_demux->sdmx_session_handle = SDMX_INVALID_SESSION_HANDLE;
+		return -EINVAL;
+	}
+
+	mpq_demux->sdmx_process_count = 0;
+	mpq_demux->sdmx_process_time_sum = 0;
+	mpq_demux->sdmx_process_time_average = 0;
+	mpq_demux->sdmx_process_time_max = 0;
+	mpq_demux->sdmx_process_packets_sum = 0;
+	mpq_demux->sdmx_process_packets_average = 0;
+	mpq_demux->sdmx_process_packets_min = 0;
+
+	mpq_demux->sdmx_session_ref_count++;
+	return ret;
+}
+EXPORT_SYMBOL(mpq_sdmx_open_session);
+
+int mpq_sdmx_close_session(struct mpq_demux *mpq_demux)
+{
+	int ret = 0;
+	enum sdmx_status status;
+
+	MPQ_DVB_DBG_PRINT("%s: session_handle = %d, ref_count %d\n",
+			__func__,
+			mpq_demux->sdmx_session_handle,
+			mpq_demux->sdmx_session_ref_count);
+
+	if (!mpq_demux->sdmx_session_ref_count)
+		return -EINVAL;
+
+	if (mpq_demux->sdmx_session_ref_count == 1) {
+		status = sdmx_close_session(mpq_demux->sdmx_session_handle);
+		if (status != SDMX_SUCCESS) {
+			MPQ_DVB_ERR_PRINT("%s: sdmx_close_session failed %d\n",
+				__func__, status);
+			return -EINVAL;
+		}
+		mpq_demux->sdmx_session_handle = SDMX_INVALID_SESSION_HANDLE;
+	}
+
+	mpq_demux->sdmx_session_ref_count--;
+
+	return ret;
+}
+EXPORT_SYMBOL(mpq_sdmx_close_session);
+
+static int mpq_sdmx_init_data_buffer(struct mpq_demux *mpq_demux,
+	struct mpq_feed *feed, u32 *num_buffers,
+	struct sdmx_buff_descr *buf_desc, enum sdmx_buf_mode *buf_mode)
+{
+	struct dvb_demux_feed *dvbdmx_feed = feed->dvb_demux_feed;
+	struct dvb_ringbuffer *buffer;
+	struct mpq_video_feed_info *feed_data = &feed->video_info;
+	ion_phys_addr_t addr;
+	struct ion_handle *sdmx_buff;
+	int ret;
+	int i;
+
+	*buf_mode = SDMX_RING_BUF;
+
+	if (mpq_dmx_is_video_feed(feed->dvb_demux_feed)) {
+		if (feed_data->buffer_desc.decoder_buffers_num > 1)
+			*buf_mode = SDMX_LINEAR_GROUP_BUF;
+		*num_buffers = feed_data->buffer_desc.decoder_buffers_num;
+
+		for (i = 0; i < *num_buffers; i++) {
+			ret = ion_phys(mpq_demux->ion_client,
+				feed_data->buffer_desc.ion_handle[i],
+				&addr, &buf_desc[i].size);
+			if (ret) {
+				MPQ_DVB_ERR_PRINT(
+					"%s: FAILED to get physical buffer address, ret=%d\n",
+					__func__, ret);
+					goto end;
+			}
+			buf_desc[i].base_addr = (void *)addr;
+			buf_desc[i].size = feed_data->buffer_desc.desc[i].size;
+		}
+	} else {
+		*num_buffers = 1;
+		if (mpq_dmx_is_sec_feed(dvbdmx_feed) ||
+			mpq_dmx_is_pcr_feed(dvbdmx_feed)) {
+			buffer = &feed->sdmx_buf;
+			sdmx_buff = feed->sdmx_buf_handle;
+		} else {
+			buffer = (struct dvb_ringbuffer *)
+				dvbdmx_feed->feed.ts.buffer.ringbuff;
+			sdmx_buff = dvbdmx_feed->feed.ts.buffer.priv_handle;
+		}
+
+		if (sdmx_buff == NULL) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: Invalid buffer allocation\n",
+				__func__);
+			return -ENOMEM;
+		}
+
+		ret = ion_phys(mpq_demux->ion_client, sdmx_buff, &addr,
+			&buf_desc[0].size);
+		if (ret) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: FAILED to get physical buffer address, ret=%d\n",
+				__func__, ret);
+				goto end;
+		} else {
+			buf_desc[0].size = buffer->size;
+			buf_desc[0].base_addr = (void *)addr;
+		}
+
+	}
+	return 0;
+
+end:
+	return ret;
+}
+
+
+static int mpq_sdmx_filter_setup(struct mpq_demux *mpq_demux,
+	struct dvb_demux_feed *dvbdmx_feed)
+{
+	int ret = 0;
+	struct mpq_feed *feed;
+	struct mpq_feed *main_rec_feed;
+	struct sdmx_buff_descr metadata_buff_desc;
+	struct sdmx_buff_descr data_buff_desc[DMX_MAX_DECODER_BUFFER_NUM];
+	u32 data_buf_num = DMX_MAX_DECODER_BUFFER_NUM;
+	enum sdmx_buf_mode buf_mode;
+	enum sdmx_raw_out_format ts_out_format = SDMX_188_OUTPUT;
+	u32 filter_flags = 0;
+
+	feed = dvbdmx_feed->priv;
+
+	if (mpq_dmx_is_sec_feed(dvbdmx_feed)) {
+		feed->filter_type = SDMX_SECTION_FILTER;
+		if (dvbdmx_feed->feed.sec.check_crc)
+			filter_flags |= SDMX_FILTER_FLAG_VERIFY_SECTION_CRC;
+		MPQ_DVB_DBG_PRINT("%s: SDMX_SECTION_FILTER\n", __func__);
+	} else if (mpq_dmx_is_pcr_feed(dvbdmx_feed)) {
+		feed->filter_type = SDMX_PCR_FILTER;
+		MPQ_DVB_DBG_PRINT("%s: SDMX_PCR_FILTER\n", __func__);
+	} else if (mpq_dmx_is_video_feed(dvbdmx_feed)) {
+		feed->filter_type = SDMX_SEPARATED_PES_FILTER;
+		MPQ_DVB_DBG_PRINT("%s: SDMX_SEPARATED_PES_FILTER\n", __func__);
+	} else if (mpq_dmx_is_rec_feed(dvbdmx_feed)) {
+		feed->filter_type = SDMX_RAW_FILTER;
+		switch (dvbdmx_feed->tsp_out_format) {
+		case (DMX_TSP_FORMAT_188):
+			ts_out_format = SDMX_188_OUTPUT;
+			break;
+		case (DMX_TSP_FORMAT_192_HEAD):
+			ts_out_format = SDMX_192_HEAD_OUTPUT;
+			break;
+		case (DMX_TSP_FORMAT_192_TAIL):
+			ts_out_format = SDMX_192_TAIL_OUTPUT;
+			break;
+		default:
+			MPQ_DVB_ERR_PRINT(
+				"%s: Unsupported TS output format %d\n",
+				__func__, dvbdmx_feed->tsp_out_format);
+			return -EINVAL;
+		}
+		MPQ_DVB_DBG_PRINT("%s: SDMX_RAW_FILTER\n", __func__);
+	} else {
+		feed->filter_type = SDMX_PES_FILTER;
+		MPQ_DVB_DBG_PRINT("%s: SDMX_PES_FILTER\n", __func__);
+	}
+
+	/*
+	 * Recording feed sdmx filter handle lookup:
+	 * In case this is a recording filter with multiple feeds,
+	 * this feed is either the first feed of a new recording filter,
+	 * or it is another feed of an existing filter for which a filter was
+	 * already opened with sdmx. In such case, we need to look up in the
+	 * feed pool for a allocated feed with same output buffer (meaning they
+	 * belong to the same filter) and to use the already allocated sdmx
+	 * filter handle.
+	 */
+	if (feed->filter_type == SDMX_RAW_FILTER)
+		main_rec_feed = mpq_sdmx_lookup_feed(dvbdmx_feed);
+	else
+		main_rec_feed = NULL;
+
+	/*
+	 * If this PID is not part of existing recording filter,
+	 * configure a new filter to SDMX.
+	 */
+	if (!main_rec_feed) {
+		feed->secondary_feed = 0;
+
+		MPQ_DVB_DBG_PRINT(
+			"%s: Adding new sdmx filter, pid %d, flags=0x%X, ts_out_format=%d\n",
+			__func__, dvbdmx_feed->pid, filter_flags,
+			ts_out_format);
+
+		/* Meta-data initialization,
+		 * Recording filters do no need meta-data buffers.
+		 */
+		if (mpq_dmx_is_rec_feed(dvbdmx_feed)) {
+			metadata_buff_desc.base_addr = 0;
+			metadata_buff_desc.size = 0;
+		} else {
+			ret = mpq_sdmx_init_metadata_buffer(mpq_demux, feed,
+				&metadata_buff_desc);
+			if (ret) {
+				MPQ_DVB_ERR_PRINT(
+					"%s: Failed to initialize metadata buffer. ret=%d\n",
+					__func__, ret);
+				goto end;
+			}
+		}
+
+		ret = mpq_sdmx_init_data_buffer(mpq_demux, feed, &data_buf_num,
+			data_buff_desc, &buf_mode);
+		if (ret) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: Failed to initialize data buffer. ret=%d\n",
+				__func__, ret);
+			mpq_sdmx_terminate_metadata_buffer(feed);
+			goto end;
+		}
+		ret = sdmx_add_filter(mpq_demux->sdmx_session_handle,
+			dvbdmx_feed->pid,
+			feed->filter_type,
+			&metadata_buff_desc,
+			buf_mode,
+			data_buf_num,
+			data_buff_desc,
+			&feed->sdmx_filter_handle,
+			ts_out_format,
+			filter_flags);
+		if (ret) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: SDMX_add_filter failed. ret = %d\n",
+				__func__, ret);
+			ret = -ENODEV;
+			mpq_sdmx_terminate_metadata_buffer(feed);
+			goto end;
+		}
+
+		MPQ_DVB_DBG_PRINT(
+			"%s: feed=0x%p, filter pid=%d, handle=%d, data buffer(s)=%d, size=%d\n",
+			__func__, feed, dvbdmx_feed->pid,
+			feed->sdmx_filter_handle,
+			data_buf_num, data_buff_desc[0].size);
+
+		mpq_demux->sdmx_filter_count++;
+	} else {
+		MPQ_DVB_DBG_PRINT(
+			"%s: Adding RAW pid to sdmx, pid %d\n",
+			__func__, dvbdmx_feed->pid);
+
+		feed->secondary_feed = 1;
+		feed->sdmx_filter_handle = main_rec_feed->sdmx_filter_handle;
+		ret = sdmx_add_raw_pid(mpq_demux->sdmx_session_handle,
+			feed->sdmx_filter_handle, dvbdmx_feed->pid);
+		if (ret) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: FAILED to add raw pid, ret=%d\n",
+				__func__, ret);
+			ret = -ENODEV;
+			goto end;
+		}
+	}
+
+	/*
+	 * If pid has a key ladder id associated, we need to
+	 * set it to SDMX.
+	 */
+	if (dvbdmx_feed->secure_mode.is_secured)  {
+		MPQ_DVB_DBG_PRINT(
+				"%s: set key-ladder %d to PID %d\n",
+				__func__,
+				dvbdmx_feed->secure_mode.key_ladder_id,
+				dvbdmx_feed->secure_mode.pid);
+		ret = sdmx_set_kl_ind(
+			mpq_demux->sdmx_session_handle,
+			dvbdmx_feed->secure_mode.pid,
+			dvbdmx_feed->secure_mode.key_ladder_id);
+		if (ret) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: FAILED to set key ladder, ret=%d\n",
+				__func__, ret);
+			ret = -ENODEV;
+			goto end;
+		}
+	}
+
+end:
+	return ret;
+}
+
+int mpq_dmx_init_mpq_feed(struct dvb_demux_feed *feed)
+{
+	int ret = 0;
+	struct mpq_demux *mpq_demux = feed->demux->priv;
+	struct mpq_feed *mpq_feed = feed->priv;
+
+	mutex_lock(&mpq_demux->mutex);
+
+	if (mpq_dmx_is_video_feed(feed)) {
+		ret = mpq_dmx_init_video_feed(mpq_feed);
+
+		if (ret) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: mpq_dmx_init_video_feed failed, ret=%d\n",
+				__func__, ret);
+			goto init_mpq_feed_failed;
+		}
+	}
+
+	mpq_feed->sdmx_buf_handle = NULL;
+	mpq_feed->metadata_buf_handle = NULL;
+	mpq_feed->sdmx_filter_handle = SDMX_INVALID_FILTER_HANDLE;
+
+	if (!mpq_sdmx_is_loaded()) {
+		/* nothing more to do */
+		mpq_demux->sdmx_session_handle = SDMX_INVALID_SESSION_HANDLE;
+		mutex_unlock(&mpq_demux->mutex);
+		return ret;
+	}
+
+	/* Further initializations for secure demux */
+	ret = mpq_sdmx_open_session(mpq_demux);
+	if (ret) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: mpq_sdmx_open_session failed, ret=%d\n",
+			__func__, ret);
+
+		ret = -ENODEV;
+		goto init_mpq_feed_failed_free_video;
+	}
+
+	/* PCR and sections have internal buffer for SDMX */
+	if (mpq_dmx_is_pcr_feed(feed))
+		ret = mpq_sdmx_alloc_data_buf(mpq_feed,
+			SDMX_PCR_BUFFER_SIZE);
+	else if (mpq_dmx_is_sec_feed(feed))
+		ret = mpq_sdmx_alloc_data_buf(mpq_feed,
+			SDMX_SECTION_BUFFER_SIZE);
+	else
+		ret = 0;
+
+	if (ret) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: init buffer failed, ret=%d\n",
+			__func__, ret);
+		goto init_mpq_feed_failed_free_sdmx;
+	}
+
+	ret = mpq_sdmx_filter_setup(mpq_demux, feed);
+	if (ret) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: mpq_sdmx_filter_setup failed, ret=%d\n",
+			__func__, ret);
+		goto init_mpq_feed_failed_free_data_buff;
+	}
+
+	mutex_unlock(&mpq_demux->mutex);
+	return 0;
+
+init_mpq_feed_failed_free_data_buff:
+	mpq_sdmx_free_data_buf(mpq_feed);
+init_mpq_feed_failed_free_sdmx:
+	mpq_sdmx_close_session(mpq_demux);
+init_mpq_feed_failed_free_video:
+	if (mpq_dmx_is_video_feed(feed))
+		mpq_dmx_terminate_video_feed(mpq_feed);
+init_mpq_feed_failed:
+	mutex_unlock(&mpq_demux->mutex);
+	return ret;
+}
+EXPORT_SYMBOL(mpq_dmx_init_mpq_feed);
+
+static void mpq_sdmx_prepare_filter_status(struct mpq_demux *mpq_demux,
+	struct sdmx_filter_status *filter_sts,
+	struct mpq_feed *mpq_feed)
+{
+	struct dvb_demux_feed *feed = mpq_feed->dvb_demux_feed;
+	struct mpq_video_feed_info *feed_data;
+	struct mpq_streambuffer *sbuff;
+
+	filter_sts->filter_handle = mpq_feed->sdmx_filter_handle;
+	filter_sts->metadata_fill_count =
+		dvb_ringbuffer_avail(&mpq_feed->metadata_buf);
+	filter_sts->metadata_write_offset = mpq_feed->metadata_buf.pwrite;
+	filter_sts->error_indicators = 0;
+	filter_sts->status_indicators = 0;
+
+	MPQ_DVB_DBG_PRINT(
+		"%s: Filter meta-data buffer status: fill count = %d, write_offset = %d\n",
+		__func__, filter_sts->metadata_fill_count,
+		filter_sts->metadata_write_offset);
+
+	if (!mpq_dmx_is_video_feed(feed)) {
+		struct dvb_ringbuffer *buffer;
+
+		if (mpq_dmx_is_sec_feed(feed) ||
+			mpq_dmx_is_pcr_feed(feed)) {
+			buffer = (struct dvb_ringbuffer *)
+				&mpq_feed->sdmx_buf;
+		} else {
+			buffer = (struct dvb_ringbuffer *)
+				feed->feed.ts.buffer.ringbuff;
+		}
+
+		filter_sts->data_fill_count = dvb_ringbuffer_avail(buffer);
+		filter_sts->data_write_offset = buffer->pwrite;
+
+		MPQ_DVB_DBG_PRINT(
+			"%s: Filter buffers status: fill count = %d, write_offset = %d\n",
+			__func__, filter_sts->data_fill_count,
+			filter_sts->data_write_offset);
+
+		return;
+	}
+
+	/* Video feed - decoder buffers */
+	feed_data = &mpq_feed->video_info;
+
+	spin_lock(&mpq_feed->video_info.video_buffer_lock);
+	sbuff = feed_data->video_buffer;
+	if (sbuff == NULL) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: video_buffer released\n",
+			__func__);
+		spin_unlock(&feed_data->video_buffer_lock);
+		return;
+	}
+
+	if (feed_data->buffer_desc.decoder_buffers_num > 1) {
+		/* linear mode */
+		filter_sts->data_fill_count = sbuff->pending_buffers_count;
+		filter_sts->data_write_offset =
+			sbuff->raw_data.pwrite /
+			sizeof(struct mpq_streambuffer_buffer_desc);
+	} else {
+		/* ring buffer mode */
+		filter_sts->data_fill_count =
+			mpq_streambuffer_data_avail(sbuff);
+		mpq_streambuffer_get_data_rw_offset(sbuff, NULL,
+			&filter_sts->data_write_offset);
+
+	}
+
+	spin_unlock(&mpq_feed->video_info.video_buffer_lock);
+
+	MPQ_DVB_DBG_PRINT(
+		"%s: Decoder buffers filter status: fill count = %d, write_offset = %d\n",
+		__func__, filter_sts->data_fill_count,
+		filter_sts->data_write_offset);
+}
+
+
+static int mpq_sdmx_section_filtering(struct mpq_feed *mpq_feed,
+	struct dvb_demux_filter *f,
+	struct sdmx_metadata_header *header)
+{
+	struct dvb_demux_feed *feed = mpq_feed->dvb_demux_feed;
+	int ret;
+	u8 neq = 0;
+	u8 xor;
+	u8 tmp;
+	int i;
+
+	if (!mutex_is_locked(&mpq_feed->mpq_demux->mutex)) {
+		MPQ_DVB_ERR_PRINT(
+				"%s: Mutex should have been locked\n",
+				__func__);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < DVB_DEMUX_MASK_MAX; i++) {
+		tmp = DVB_RINGBUFFER_PEEK(&mpq_feed->sdmx_buf, i);
+		xor = f->filter.filter_value[i] ^ tmp;
+
+		if (f->maskandmode[i] & xor)
+			return 0;
+
+		neq |= f->maskandnotmode[i] & xor;
+	}
+
+	if (f->doneq && !neq)
+		return 0;
+
+	if (feed->demux->playback_mode == DMX_PB_MODE_PULL) {
+		mutex_unlock(&mpq_feed->mpq_demux->mutex);
+
+		ret = feed->demux->buffer_ctrl.sec(&f->filter,
+					header->payload_length);
+
+		mutex_lock(&mpq_feed->mpq_demux->mutex);
+
+		if (ret) {
+			MPQ_DVB_DBG_PRINT(
+				"%s: buffer_ctrl.sec aborted\n",
+				__func__);
+			return ret;
+		}
+	}
+
+	if (mpq_feed->sdmx_buf.pread + header->payload_length <
+		mpq_feed->sdmx_buf.size) {
+		feed->cb.sec(&mpq_feed->sdmx_buf.data[mpq_feed->sdmx_buf.pread],
+			header->payload_length,
+			NULL, 0, &f->filter, DMX_OK);
+	} else {
+		int split = mpq_feed->sdmx_buf.size - mpq_feed->sdmx_buf.pread;
+		feed->cb.sec(&mpq_feed->sdmx_buf.data[mpq_feed->sdmx_buf.pread],
+			split,
+			&mpq_feed->sdmx_buf.data[0],
+			header->payload_length - split,
+			&f->filter, DMX_OK);
+	}
+
+	return 0;
+}
+
+static int mpq_sdmx_check_ts_stall(struct mpq_demux *mpq_demux,
+	struct mpq_feed *mpq_feed,
+	struct sdmx_filter_status *sts,
+	size_t req,
+	int events_only)
+{
+	struct dvb_demux_feed *feed = mpq_feed->dvb_demux_feed;
+	int ret;
+
+	if (!mutex_is_locked(&mpq_feed->mpq_demux->mutex)) {
+		MPQ_DVB_ERR_PRINT(
+				"%s: Mutex should have been locked\n",
+				__func__);
+		return -EINVAL;
+	}
+
+	/*
+	 * For PULL mode need to verify there is enough space for the dmxdev
+	 * event. Also, if data buffer is full we want to stall until some
+	 * data is removed from it to prevent calling the sdmx when it cannot
+	 * output data to the still full buffer.
+	 */
+	if (mpq_demux->demux.playback_mode == DMX_PB_MODE_PULL) {
+		MPQ_DVB_DBG_PRINT("%s: Stalling for events and %d bytes\n",
+			__func__, req);
+
+		mutex_unlock(&mpq_demux->mutex);
+
+		ret = mpq_demux->demux.buffer_ctrl.ts(&feed->feed.ts, req);
+		MPQ_DVB_DBG_PRINT("%s: stall result = %d\n",
+			__func__, ret);
+
+		mutex_lock(&mpq_demux->mutex);
+
+		return ret;
+	}
+
+	return 0;
+}
+
+/* Handle filter results for filters with no extra meta-data */
+static void mpq_sdmx_pes_filter_results(struct mpq_demux *mpq_demux,
+	struct mpq_feed *mpq_feed,
+	struct sdmx_filter_status *sts)
+{
+	int ret;
+	struct sdmx_metadata_header header;
+	struct sdmx_pes_counters counters;
+	struct dmx_data_ready data_event;
+	struct dmx_data_ready pes_event;
+	struct dvb_demux_feed *feed = mpq_feed->dvb_demux_feed;
+	struct dvb_ringbuffer *buf = (struct dvb_ringbuffer *)
+				feed->feed.ts.buffer.ringbuff;
+
+	if ((!sts->metadata_fill_count) && (!sts->data_fill_count))
+		goto pes_filter_check_overflow;
+
+	MPQ_DVB_DBG_PRINT(
+		"%s: Meta: fill=%u, write=%u. Data: fill=%u, write=%u\n",
+		__func__, sts->metadata_fill_count, sts->metadata_write_offset,
+		sts->data_fill_count, sts->data_write_offset);
+
+	mpq_feed->metadata_buf.pwrite = sts->metadata_write_offset;
+
+	if ((0 == sts->metadata_fill_count) &&
+		(sts->error_indicators & SDMX_FILTER_ERR_D_BUF_FULL)) {
+		ssize_t free = dvb_ringbuffer_free(buf);
+		ret = 0;
+		if ((free + SZ_2K) < MAX_PES_LENGTH)
+			ret = mpq_sdmx_check_ts_stall(mpq_demux, mpq_feed, sts,
+				free + SZ_2K, 0);
+		else
+			MPQ_DVB_ERR_PRINT(
+				"%s: Cannot stall when free space bigger than max PES size\n",
+				__func__);
+		if (ret) {
+			MPQ_DVB_DBG_PRINT(
+				"%s: mpq_sdmx_check_ts_stall aborted\n",
+				__func__);
+			return;
+		}
+	}
+
+	while (sts->metadata_fill_count) {
+		if (dvb_ringbuffer_avail(&mpq_feed->metadata_buf) <
+			(sizeof(header) + sizeof(counters))) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: metadata_fill_count is %d but actual buffer has less than %d bytes\n",
+				__func__,
+				sts->metadata_fill_count,
+				sizeof(header) + sizeof(counters));
+			break;
+		}
+
+		dvb_ringbuffer_read(&mpq_feed->metadata_buf, (u8 *)&header,
+			sizeof(header));
+		MPQ_DVB_DBG_PRINT(
+			"%s: metadata header: start=%u, length=%u\n",
+			__func__, header.payload_start, header.payload_length);
+		sts->metadata_fill_count -= sizeof(header);
+
+		dvb_ringbuffer_read(&mpq_feed->metadata_buf, (u8 *)&counters,
+			sizeof(counters));
+		sts->metadata_fill_count -= sizeof(counters);
+
+		/* Notify new data in buffer */
+		data_event.status = DMX_OK;
+		data_event.data_length = header.payload_length;
+		ret = mpq_sdmx_check_ts_stall(mpq_demux, mpq_feed, sts,
+			data_event.data_length, 0);
+		if (ret) {
+			MPQ_DVB_DBG_PRINT(
+				"%s: mpq_sdmx_check_ts_stall aborted\n",
+				__func__);
+			return;
+		}
+
+		feed->data_ready_cb.ts(&feed->feed.ts, &data_event);
+
+		/* Notify new complete PES */
+		pes_event.status = DMX_OK_PES_END;
+		pes_event.pes_end.actual_length = header.payload_length;
+		pes_event.pes_end.start_gap = 0;
+		pes_event.data_length = 0;
+
+		/* Parse error indicators - TODO: these should be per filter */
+		if (sts->error_indicators & SDMX_FILTER_ERR_INVALID_PES_LEN)
+			pes_event.pes_end.pes_length_mismatch = 1;
+		if (sts->error_indicators & SDMX_FILTER_ERR_CONT_CNT_INVALID)
+			pes_event.pes_end.disc_indicator_set = 0;
+
+		pes_event.pes_end.stc = 0;
+		pes_event.pes_end.tei_counter = counters.transport_err_count;
+		pes_event.pes_end.cont_err_counter =
+			counters.continuity_err_count;
+		pes_event.pes_end.ts_packets_num =
+			counters.pes_ts_count;
+
+		ret = mpq_sdmx_check_ts_stall(mpq_demux, mpq_feed, sts, 0, 1);
+		if (ret) {
+			MPQ_DVB_DBG_PRINT(
+				"%s: mpq_sdmx_check_ts_stall aborted\n",
+				__func__);
+			return;
+		}
+		feed->data_ready_cb.ts(&feed->feed.ts, &pes_event);
+	}
+
+pes_filter_check_overflow:
+	if ((mpq_demux->demux.playback_mode == DMX_PB_MODE_PUSH) &&
+		(sts->error_indicators & SDMX_FILTER_ERR_D_BUF_FULL)) {
+		MPQ_DVB_ERR_PRINT("%s: DMX_OVERRUN_ERROR\n", __func__);
+		data_event.status = DMX_OVERRUN_ERROR;
+		data_event.data_length = 0;
+		feed->data_ready_cb.ts(&feed->feed.ts, &data_event);
+	}
+}
+
+static void mpq_sdmx_section_filter_results(struct mpq_demux *mpq_demux,
+	struct mpq_feed *mpq_feed,
+	struct sdmx_filter_status *sts)
+{
+	struct sdmx_metadata_header header;
+	struct dmx_data_ready event;
+	struct dvb_demux_feed *feed = mpq_feed->dvb_demux_feed;
+	struct dvb_demux_filter *f;
+	struct dmx_section_feed *sec = &feed->feed.sec;
+
+	/* Parse error indicators */
+	if (sts->error_indicators & SDMX_FILTER_ERR_SEC_VERIF_CRC32_FAIL) {
+		MPQ_DVB_DBG_PRINT("%s: Notify CRC err event\n", __func__);
+		event.status = DMX_CRC_ERROR;
+		event.data_length = 0;
+		feed->data_ready_cb.sec(&feed->filter->filter, &event);
+	}
+
+	if (sts->error_indicators & SDMX_FILTER_ERR_D_BUF_FULL)
+		MPQ_DVB_ERR_PRINT("%s: internal section buffer overflowed!\n",
+			__func__);
+
+	if ((!sts->metadata_fill_count) && (!sts->data_fill_count))
+		return;
+
+	mpq_feed->metadata_buf.pwrite = sts->metadata_write_offset;
+	mpq_feed->sdmx_buf.pwrite = sts->data_write_offset;
+
+	while (sts->metadata_fill_count) {
+		dvb_ringbuffer_read(&mpq_feed->metadata_buf, (u8 *) &header,
+			sizeof(header));
+		sts->metadata_fill_count -= sizeof(header);
+		MPQ_DVB_DBG_PRINT(
+			"%s: metadata header: start=%u, length=%u\n",
+			__func__, header.payload_start, header.payload_length);
+
+		f = feed->filter;
+		do {
+			if (mpq_sdmx_section_filtering(mpq_feed, f, &header))
+				return;
+		} while ((f = f->next) && sec->is_filtering);
+
+		DVB_RINGBUFFER_SKIP(&mpq_feed->sdmx_buf, header.payload_length);
+	}
+}
+
+static void mpq_sdmx_decoder_filter_results(struct mpq_demux *mpq_demux,
+	struct mpq_feed *mpq_feed,
+	struct sdmx_filter_status *sts)
+{
+	struct sdmx_metadata_header header;
+	struct sdmx_pes_counters counters;
+	int pes_header_offset;
+	struct ts_packet_header *ts_header;
+	struct ts_adaptation_field *ts_adapt;
+	struct pes_packet_header *pes_header;
+	u8 metadata_buf[MAX_SDMX_METADATA_LENGTH];
+	struct mpq_streambuffer *sbuf;
+	int ret;
+	int pes_cnt = 0;
+	struct dmx_data_ready data_event;
+
+	if ((!sts->metadata_fill_count) && (!sts->data_fill_count))
+		goto decoder_filter_check_overflow;
+
+	/* Update meta data buffer write pointer */
+	mpq_feed->metadata_buf.pwrite = sts->metadata_write_offset;
+
+	if ((mpq_demux->demux.playback_mode == DMX_PB_MODE_PULL) &&
+		(sts->error_indicators & SDMX_FILTER_ERR_D_LIN_BUFS_FULL)) {
+		MPQ_DVB_DBG_PRINT("%s: Decoder stall...\n", __func__);
+
+		ret = mpq_dmx_decoder_fullness_check(
+			mpq_feed->dvb_demux_feed, 0, 0);
+		if (ret) {
+			/* we reach here if demuxing was aborted */
+			MPQ_DVB_DBG_PRINT(
+				"%s: mpq_dmx_decoder_fullness_check aborted\n",
+				__func__);
+			return;
+		}
+	}
+
+	while (sts->metadata_fill_count) {
+		struct mpq_streambuffer_packet_header packet;
+		struct mpq_adapter_video_meta_data meta_data;
+
+		pes_cnt++;
+		/* Read metadata header */
+		dvb_ringbuffer_read(&mpq_feed->metadata_buf, (u8 *)&header,
+			sizeof(header));
+		sts->metadata_fill_count -= sizeof(header);
+		MPQ_DVB_DBG_PRINT(
+			"%s: metadata header: start=%u, length=%u, metadata=%u\n",
+			__func__, header.payload_start, header.payload_length,
+			header.metadata_length);
+
+		/* Read metadata - PES counters */
+		dvb_ringbuffer_read(&mpq_feed->metadata_buf, (u8 *)&counters,
+					sizeof(counters));
+		sts->metadata_fill_count -= sizeof(counters);
+
+		/* Read metadata - TS & PES headers */
+		if (header.metadata_length < MAX_SDMX_METADATA_LENGTH)
+			dvb_ringbuffer_read(&mpq_feed->metadata_buf,
+				metadata_buf,
+				header.metadata_length - sizeof(counters));
+		else
+			MPQ_DVB_ERR_PRINT(
+				"%s: meta-data size=%d is too big for meta-data buffer=%d\n",
+				__func__, header.metadata_length,
+				MAX_SDMX_METADATA_LENGTH);
+		sts->metadata_fill_count -=
+			(header.metadata_length - sizeof(counters));
+
+		ts_header = (struct ts_packet_header *)&metadata_buf[0];
+		if (1 == ts_header->adaptation_field_control) {
+			ts_adapt = NULL;
+			pes_header_offset = sizeof(*ts_header);
+		} else {
+			ts_adapt = (struct ts_adaptation_field *)
+				&metadata_buf[sizeof(*ts_header)];
+			pes_header_offset = sizeof(*ts_header) + 1 +
+				ts_adapt->adaptation_field_length;
+		}
+		pes_header = (struct pes_packet_header *)
+			&metadata_buf[pes_header_offset];
+		meta_data.packet_type = DMX_PES_PACKET;
+		if (pes_header->pts_dts_flag & 0x2) {
+			meta_data.info.pes.pts_dts_info.pts_exist = 1;
+			meta_data.info.pes.pts_dts_info.pts =
+				((u64)pes_header->pts_1 << 30) |
+				((u64)pes_header->pts_2 << 22) |
+				((u64)pes_header->pts_3 << 15) |
+				((u64)pes_header->pts_4 << 7) |
+				(u64)pes_header->pts_5;
+		} else {
+			meta_data.info.pes.pts_dts_info.pts_exist = 0;
+		}
+
+		if (pes_header->pts_dts_flag & 0x1) {
+			meta_data.info.pes.pts_dts_info.dts_exist = 1;
+			meta_data.info.pes.pts_dts_info.dts =
+				((u64)pes_header->dts_1 << 30) |
+				((u64)pes_header->dts_2 << 22) |
+				((u64)pes_header->dts_3 << 15) |
+				((u64)pes_header->dts_4 << 7) |
+				(u64)pes_header->dts_5;
+		} else {
+			meta_data.info.pes.pts_dts_info.dts_exist = 0;
+		}
+
+		spin_lock(&mpq_feed->video_info.video_buffer_lock);
+
+		mpq_feed->video_info.tei_errs =
+			counters.transport_err_count;
+		mpq_feed->video_info.continuity_errs =
+			counters.continuity_err_count;
+		mpq_feed->video_info.ts_packets_num =
+			counters.pes_ts_count;
+		mpq_feed->video_info.ts_dropped_bytes =
+			counters.drop_count * mpq_demux->demux.ts_packet_size;
+
+		sbuf = mpq_feed->video_info.video_buffer;
+		if (sbuf == NULL) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: video_buffer released\n",
+				__func__);
+			spin_unlock(&mpq_feed->video_info.video_buffer_lock);
+			return;
+		}
+
+		packet.raw_data_len = header.payload_length;
+		packet.user_data_len = sizeof(meta_data);
+		mpq_streambuffer_get_buffer_handle(sbuf, 0,
+			&packet.raw_data_handle);
+		mpq_streambuffer_get_data_rw_offset(sbuf,
+			NULL, &packet.raw_data_offset);
+		ret = mpq_streambuffer_data_write_deposit(sbuf,
+			header.payload_length);
+		if (ret) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: mpq_streambuffer_data_write_deposit failed. ret=%d\n",
+				__func__, ret);
+		}
+		mpq_dmx_update_decoder_stat(mpq_demux);
+		mpq_streambuffer_pkt_write(sbuf, &packet, (u8 *)&meta_data);
+
+		if (generate_es_events) {
+			struct dmx_data_ready data;
+			struct dvb_demux_feed *feed = mpq_feed->dvb_demux_feed;
+			mpq_dmx_prepare_es_event_data(
+				&packet, &meta_data, &mpq_feed->video_info,
+				sbuf, &data);
+			MPQ_DVB_DBG_PRINT("%s: Notify ES Event\n", __func__);
+			feed->data_ready_cb.ts(&feed->feed.ts, &data);
+		}
+
+		spin_unlock(&mpq_feed->video_info.video_buffer_lock);
+	}
+
+decoder_filter_check_overflow:
+	if ((mpq_demux->demux.playback_mode == DMX_PB_MODE_PUSH) &&
+		(sts->error_indicators & SDMX_FILTER_ERR_D_LIN_BUFS_FULL)) {
+		MPQ_DVB_ERR_PRINT("%s: DMX_OVERRUN_ERROR\n", __func__);
+		data_event.status = DMX_OVERRUN_ERROR;
+		data_event.data_length = 0;
+		mpq_feed->dvb_demux_feed->data_ready_cb.ts(
+			&mpq_feed->dvb_demux_feed->feed.ts, &data_event);
+	}
+}
+
+static void mpq_sdmx_pcr_filter_results(struct mpq_demux *mpq_demux,
+	struct mpq_feed *mpq_feed,
+	struct sdmx_filter_status *sts)
+{
+	int ret;
+	struct sdmx_metadata_header header;
+	struct dmx_data_ready data;
+	struct dvb_ringbuffer *rbuff = &mpq_feed->sdmx_buf;
+	struct dvb_demux_feed *feed = mpq_feed->dvb_demux_feed;
+	u8 buf[TS_PACKET_HEADER_LENGTH + MAX_TSP_ADAPTATION_LENGTH +
+	       TIMESTAMP_LEN];
+	size_t stc_len = 0;
+
+	if (sts->error_indicators & SDMX_FILTER_ERR_D_BUF_FULL)
+		MPQ_DVB_ERR_PRINT("%s: internal PCR buffer overflowed!\n",
+			__func__);
+
+	/* MPQ_TODO: Parse rest of error indicators ? */
+
+	if ((!sts->metadata_fill_count) && (!sts->data_fill_count))
+		return;
+
+	if (DMX_TSP_FORMAT_192_TAIL == mpq_demux->demux.tsp_format)
+		stc_len = 4;
+
+	mpq_feed->metadata_buf.pwrite = sts->metadata_write_offset;
+	rbuff->pwrite = sts->data_write_offset;
+
+	while (sts->metadata_fill_count) {
+		dvb_ringbuffer_read(&mpq_feed->metadata_buf, (u8 *) &header,
+			sizeof(header));
+		MPQ_DVB_DBG_PRINT(
+			"%s: metadata header: start=%u, length=%u\n",
+			__func__, header.payload_start, header.payload_length);
+		sts->metadata_fill_count -= sizeof(header);
+
+		dvb_ringbuffer_read(rbuff, buf, header.payload_length);
+
+		if (mpq_dmx_extract_pcr_and_dci(buf, &data.pcr.pcr,
+			&data.pcr.disc_indicator_set)) {
+
+			if (stc_len) {
+				data.pcr.stc =
+					buf[header.payload_length-2] << 16;
+				data.pcr.stc +=
+					buf[header.payload_length-3] << 8;
+				data.pcr.stc += buf[header.payload_length-4];
+				 /* convert from 105.47 KHZ to 27MHz */
+				data.pcr.stc *= 256;
+			} else {
+				data.pcr.stc = 0;
+			}
+
+			data.data_length = 0;
+			data.status = DMX_OK_PCR;
+			ret = mpq_sdmx_check_ts_stall(
+				mpq_demux, mpq_feed, sts, 0, 1);
+			if (ret) {
+				MPQ_DVB_DBG_PRINT(
+					"%s: mpq_sdmx_check_ts_stall aborted\n",
+					__func__);
+				return;
+			}
+			feed->data_ready_cb.ts(&feed->feed.ts, &data);
+		}
+	}
+}
+
+static void mpq_sdmx_raw_filter_results(struct mpq_demux *mpq_demux,
+	struct mpq_feed *mpq_feed,
+	struct sdmx_filter_status *sts)
+{
+	int ret;
+	ssize_t new_data;
+	struct dmx_data_ready data_event;
+	struct dvb_demux_feed *feed = mpq_feed->dvb_demux_feed;
+	struct dvb_ringbuffer *buf = (struct dvb_ringbuffer *)
+					feed->feed.ts.buffer.ringbuff;
+
+	if ((!sts->metadata_fill_count) && (!sts->data_fill_count))
+		goto raw_filter_check_overflow;
+
+	new_data = sts->data_write_offset -
+		buf->pwrite;
+	if (new_data < 0)
+		new_data += buf->size;
+
+	ret = mpq_sdmx_check_ts_stall(mpq_demux, mpq_feed, sts,
+		new_data + feed->demux->ts_packet_size, 0);
+	if (ret) {
+		MPQ_DVB_DBG_PRINT(
+			"%s: mpq_sdmx_check_ts_stall aborted\n",
+			__func__);
+		return;
+	}
+
+	data_event.status = DMX_OK;
+	data_event.data_length = new_data;
+	feed->data_ready_cb.ts(&feed->feed.ts, &data_event);
+	MPQ_DVB_DBG_PRINT("%s: Callback DMX_OK, size=%d\n",
+		__func__, data_event.data_length);
+
+raw_filter_check_overflow:
+	if ((mpq_demux->demux.playback_mode == DMX_PB_MODE_PUSH) &&
+		(sts->error_indicators & SDMX_FILTER_ERR_D_BUF_FULL)) {
+		MPQ_DVB_DBG_PRINT("%s: DMX_OVERRUN_ERROR\n", __func__);
+		data_event.status = DMX_OVERRUN_ERROR;
+		data_event.data_length = 0;
+		feed->data_ready_cb.ts(&feed->feed.ts, &data_event);
+	}
+}
+
+static void mpq_sdmx_process_results(struct mpq_demux *mpq_demux)
+{
+	int i;
+	int j;
+	struct sdmx_filter_status *sts;
+	struct mpq_feed *mpq_feed;
+
+	for (i = 0; i < mpq_demux->sdmx_filter_count; i++) {
+		/*
+		 * MPQ_TODO: review lookup optimization
+		 * Can have the related mpq_feed index already associated with
+		 * the filter status.
+		 */
+		sts = &mpq_demux->filters_status[i];
+		MPQ_DVB_DBG_PRINT(
+			"%s: Filter: handle=%d, status=0x%x, errors=0x%x\n",
+			__func__, sts->filter_handle, sts->status_indicators,
+			sts->error_indicators);
+		MPQ_DVB_DBG_PRINT("%s: Metadata fill count=%d (write=%d)\n",
+			__func__, sts->metadata_fill_count,
+			sts->metadata_write_offset);
+		MPQ_DVB_DBG_PRINT("%s: Data fill count=%d (write=%d)\n",
+			__func__, sts->data_fill_count, sts->data_write_offset);
+
+		for (j = 0; j < MPQ_MAX_DMX_FILES; j++) {
+			mpq_feed = &mpq_demux->feeds[j];
+			if ((mpq_feed->dvb_demux_feed->state == DMX_STATE_GO) &&
+				(sts->filter_handle ==
+					mpq_feed->sdmx_filter_handle) &&
+				(!mpq_feed->secondary_feed))
+				break;
+		}
+
+		if (j == MPQ_MAX_DMX_FILES)
+			continue;
+
+		if (sts->error_indicators & SDMX_FILTER_ERR_MD_BUF_FULL)
+			MPQ_DVB_ERR_PRINT(
+				"%s: meta-data buff for pid %d overflowed!\n",
+				__func__, mpq_feed->dvb_demux_feed->pid);
+
+		switch (mpq_feed->filter_type) {
+		case SDMX_PCR_FILTER:
+			mpq_sdmx_pcr_filter_results(mpq_demux, mpq_feed, sts);
+			break;
+		case SDMX_PES_FILTER:
+			mpq_sdmx_pes_filter_results(mpq_demux, mpq_feed,
+				sts);
+			break;
+		case SDMX_SEPARATED_PES_FILTER:
+			mpq_sdmx_decoder_filter_results(mpq_demux, mpq_feed,
+				sts);
+			break;
+		case SDMX_SECTION_FILTER:
+			mpq_sdmx_section_filter_results(mpq_demux, mpq_feed,
+				sts);
+			break;
+		case SDMX_RAW_FILTER:
+			mpq_sdmx_raw_filter_results(mpq_demux, mpq_feed, sts);
+			break;
+		default:
+			break;
+		}
+	}
+}
+
+static int mpq_sdmx_process_buffer(struct mpq_demux *mpq_demux,
+	struct sdmx_buff_descr *input,
+	u32 fill_count,
+	u32 read_offset)
+{
+	struct sdmx_filter_status *sts;
+	struct mpq_feed *mpq_feed;
+	u8 flags = 0;	/* MPQ_TODO: EOS handling */
+	u32 errors;
+	u32 status;
+	u32 prev_read_offset;
+	u32 prev_fill_count;
+	enum sdmx_status sdmx_res;
+	int i;
+	int filter_index = 0;
+	int bytes_read;
+	struct timespec process_start_time;
+	struct timespec process_end_time;
+
+	mutex_lock(&mpq_demux->mutex);
+
+	/*
+	 * All active filters may get totally closed and therefore
+	 * sdmx session may get terminated, in such case nothing to process
+	 */
+	if (mpq_demux->sdmx_session_handle == SDMX_INVALID_SESSION_HANDLE) {
+		MPQ_DVB_DBG_PRINT(
+			"%s: sdmx filters aborted, filter-count %d, session %d\n",
+			__func__, mpq_demux->sdmx_filter_count,
+			mpq_demux->sdmx_session_handle);
+		mutex_unlock(&mpq_demux->mutex);
+		return 0;
+	}
+
+	/* Build up to date filter status array */
+	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->filters_status[filter_index];
+			mpq_sdmx_prepare_filter_status(mpq_demux, sts,
+				mpq_feed);
+			filter_index++;
+		}
+	}
+
+	/* Sanity check */
+	if (filter_index != mpq_demux->sdmx_filter_count) {
+		mutex_unlock(&mpq_demux->mutex);
+		MPQ_DVB_ERR_PRINT(
+			"%s: Updated %d SDMX filters status but should be %d\n",
+			__func__, filter_index, mpq_demux->sdmx_filter_count);
+		return -ERESTART;
+	}
+
+	MPQ_DVB_DBG_PRINT(
+		"\n\n%s: Before SDMX_process: input read_offset=%u, fill count=%u\n",
+		__func__, read_offset, fill_count);
+
+	process_start_time = current_kernel_time();
+
+	prev_read_offset = read_offset;
+	prev_fill_count = fill_count;
+	sdmx_res = sdmx_process(mpq_demux->sdmx_session_handle, flags, input,
+		&fill_count, &read_offset, &errors, &status,
+		mpq_demux->sdmx_filter_count, mpq_demux->filters_status);
+
+	process_end_time = current_kernel_time();
+	mpq_dmx_update_sdmx_stat(mpq_demux, prev_fill_count,
+		&process_start_time, &process_end_time);
+
+	bytes_read = prev_fill_count - fill_count;
+
+	MPQ_DVB_DBG_PRINT(
+		"%s: SDMX result=%d, input_fill_count=%u, read_offset=%u, read %d bytes from input, status=0x%X, errors=0x%X\n",
+		__func__, sdmx_res, fill_count, read_offset, bytes_read,
+		status, errors);
+
+	if ((sdmx_res == SDMX_SUCCESS) ||
+		(sdmx_res == SDMX_STATUS_STALLED_IN_PULL_MODE)) {
+		if (sdmx_res == SDMX_STATUS_STALLED_IN_PULL_MODE)
+			MPQ_DVB_DBG_PRINT("%s: SDMX stalled for PULL mode\n",
+				__func__);
+
+		mpq_sdmx_process_results(mpq_demux);
+	} else {
+		MPQ_DVB_ERR_PRINT(
+			"%s: SDMX Process returned %d\n",
+			__func__, sdmx_res);
+	}
+
+	mutex_unlock(&mpq_demux->mutex);
+
+	return bytes_read;
+}
+
+int mpq_sdmx_process(struct mpq_demux *mpq_demux,
+	struct sdmx_buff_descr *input,
+	u32 fill_count,
+	u32 read_offset)
+{
+	int ret;
+	int todo;
+	int total_bytes_read = 0;
+	int limit = mpq_sdmx_proc_limit * mpq_demux->demux.ts_packet_size;
+
+	do {
+		todo = fill_count > limit ? limit : fill_count;
+		ret = mpq_sdmx_process_buffer(mpq_demux, input, todo,
+			read_offset);
+		if (ret > 0) {
+			total_bytes_read += ret;
+			fill_count -= ret;
+			read_offset += ret;
+			if (read_offset >= input->size)
+				read_offset -= input->size;
+		} else if (ret == 0) {
+			/* Not enough data to read (less than 1 TS packet) */
+			break;
+		} else {
+			/* Some error occurred */
+			MPQ_DVB_ERR_PRINT(
+				"%s: mpq_sdmx_process_buffer failed, returned %d\n",
+				__func__, ret);
+			break;
+		}
+	} while (fill_count > 0);
+
+	return total_bytes_read;
+}
+EXPORT_SYMBOL(mpq_sdmx_process);
+
+static int mpq_sdmx_write(struct mpq_demux *mpq_demux,
+	struct ion_handle *input_handle,
+	const char *buf,
+	size_t count)
+{
+	struct sdmx_buff_descr buf_desc;
+	struct dvb_ringbuffer *rbuf = (struct dvb_ringbuffer *)
+				mpq_demux->demux.dmx.dvr_input.ringbuff;
+	ion_phys_addr_t phys_addr;
+	u32 read_offset;
+	size_t len;
+	int ret;
+
+	if (mpq_demux == NULL || input_handle == NULL) {
+		MPQ_DVB_ERR_PRINT("%s: invalid parameters\n", __func__);
+		return -EINVAL;
+	}
+
+	ret = ion_phys(mpq_demux->ion_client, input_handle, &phys_addr, &len);
+	if (ret) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: Failed to obtain physical address of input buffer. ret = %d\n",
+			__func__, ret);
+		return ret;
+	}
+
+	buf_desc.base_addr = (void *)phys_addr;
+	buf_desc.size = rbuf->size;
+	read_offset = rbuf->pread;
+
+	return mpq_sdmx_process(mpq_demux, &buf_desc, count, read_offset);
+}
+
+int mpq_dmx_write(struct dmx_demux *demux, const char *buf, size_t count)
+{
+	struct dvb_demux *dvb_demux;
+	struct mpq_demux *mpq_demux;
+
+	if (demux == NULL)
+		return -EINVAL;
+
+	dvb_demux = demux->priv;
+	mpq_demux = dvb_demux->priv;
+
+	if (mpq_sdmx_is_loaded()) {
+		/* route through secure demux */
+		return mpq_sdmx_write(mpq_demux,
+			demux->dvr_input.priv_handle,
+			buf,
+			count);
+	} else {
+		/* route through sw filter */
+		dvb_dmx_swfilter_format(dvb_demux, buf, count,
+			dvb_demux->tsp_format);
+		if (signal_pending(current))
+			return -EINTR;
+		return count;
+	}
+}
+EXPORT_SYMBOL(mpq_dmx_write);
+
+int mpq_sdmx_is_loaded(void)
+{
+	static int sdmx_load_checked;
+
+	if (mpq_bypass_sdmx)
+		return 0;
+
+	if (!sdmx_load_checked) {
+		mpq_sdmx_check_app_loaded();
+		sdmx_load_checked = 1;
+	}
+
+	return mpq_dmx_info.secure_demux_app_loaded;
+}
+EXPORT_SYMBOL(mpq_sdmx_is_loaded);
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.h b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.h
new file mode 100644
index 0000000..2c2420b
--- /dev/null
+++ b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.h
@@ -0,0 +1,805 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _MPQ_DMX_PLUGIN_COMMON_H
+#define _MPQ_DMX_PLUGIN_COMMON_H
+
+#include <linux/msm_ion.h>
+
+#include "dvbdev.h"
+#include "dmxdev.h"
+#include "demux.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "mpq_adapter.h"
+#include "mpq_sdmx.h"
+
+/* Max number open() request can be done on demux device */
+#define MPQ_MAX_DMX_FILES				128
+
+/**
+ * TSIF alias name length
+ */
+#define TSIF_NAME_LENGTH				20
+
+#define MPQ_MAX_FOUND_PATTERNS				5
+
+/**
+ * struct ts_packet_header - Transport packet header
+ * as defined in MPEG2 transport stream standard.
+ */
+struct ts_packet_header {
+#if defined(__BIG_ENDIAN_BITFIELD)
+	unsigned sync_byte:8;
+	unsigned transport_error_indicator:1;
+	unsigned payload_unit_start_indicator:1;
+	unsigned transport_priority:1;
+	unsigned pid_msb:5;
+	unsigned pid_lsb:8;
+	unsigned transport_scrambling_control:2;
+	unsigned adaptation_field_control:2;
+	unsigned continuity_counter:4;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+	unsigned sync_byte:8;
+	unsigned pid_msb:5;
+	unsigned transport_priority:1;
+	unsigned payload_unit_start_indicator:1;
+	unsigned transport_error_indicator:1;
+	unsigned pid_lsb:8;
+	unsigned continuity_counter:4;
+	unsigned adaptation_field_control:2;
+	unsigned transport_scrambling_control:2;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+} __packed;
+
+/**
+ * struct ts_adaptation_field - Adaptation field prefix
+ * as defined in MPEG2 transport stream standard.
+ */
+struct ts_adaptation_field {
+#if defined(__BIG_ENDIAN_BITFIELD)
+	unsigned adaptation_field_length:8;
+	unsigned discontinuity_indicator:1;
+	unsigned random_access_indicator:1;
+	unsigned elementary_stream_priority_indicator:1;
+	unsigned PCR_flag:1;
+	unsigned OPCR_flag:1;
+	unsigned splicing_point_flag:1;
+	unsigned transport_private_data_flag:1;
+	unsigned adaptation_field_extension_flag:1;
+	unsigned program_clock_reference_base_1:8;
+	unsigned program_clock_reference_base_2:8;
+	unsigned program_clock_reference_base_3:8;
+	unsigned program_clock_reference_base_4:8;
+	unsigned program_clock_reference_base_5:1;
+	unsigned reserved:6;
+	unsigned program_clock_reference_ext_1:1;
+	unsigned program_clock_reference_ext_2:8;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+	unsigned adaptation_field_length:8;
+	unsigned adaptation_field_extension_flag:1;
+	unsigned transport_private_data_flag:1;
+	unsigned splicing_point_flag:1;
+	unsigned OPCR_flag:1;
+	unsigned PCR_flag:1;
+	unsigned elementary_stream_priority_indicator:1;
+	unsigned random_access_indicator:1;
+	unsigned discontinuity_indicator:1;
+	unsigned program_clock_reference_base_1:8;
+	unsigned program_clock_reference_base_2:8;
+	unsigned program_clock_reference_base_3:8;
+	unsigned program_clock_reference_base_4:8;
+	unsigned program_clock_reference_ext_1:1;
+	unsigned reserved:6;
+	unsigned program_clock_reference_base_5:1;
+	unsigned program_clock_reference_ext_2:8;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+} __packed;
+
+
+/*
+ * PES packet header containing dts and/or pts values
+ * as defined in MPEG2 transport stream standard.
+ */
+struct pes_packet_header {
+#if defined(__BIG_ENDIAN_BITFIELD)
+	unsigned packet_start_code_prefix_1:8;
+	unsigned packet_start_code_prefix_2:8;
+	unsigned packet_start_code_prefix_3:8;
+	unsigned stream_id:8;
+	unsigned pes_packet_length_msb:8;
+	unsigned pes_packet_length_lsb:8;
+	unsigned reserved_bits0:2;
+	unsigned pes_scrambling_control:2;
+	unsigned pes_priority:1;
+	unsigned data_alignment_indicator:1;
+	unsigned copyright:1;
+	unsigned original_or_copy:1;
+	unsigned pts_dts_flag:2;
+	unsigned escr_flag:1;
+	unsigned es_rate_flag:1;
+	unsigned dsm_trick_mode_flag:1;
+	unsigned additional_copy_info_flag:1;
+	unsigned pes_crc_flag:1;
+	unsigned pes_extension_flag:1;
+	unsigned pes_header_data_length:8;
+	unsigned reserved_bits1:4;
+	unsigned pts_1:3;
+	unsigned marker_bit0:1;
+	unsigned pts_2:8;
+	unsigned pts_3:7;
+	unsigned marker_bit1:1;
+	unsigned pts_4:8;
+	unsigned pts_5:7;
+	unsigned marker_bit2:1;
+	unsigned reserved_bits2:4;
+	unsigned dts_1:3;
+	unsigned marker_bit3:1;
+	unsigned dts_2:8;
+	unsigned dts_3:7;
+	unsigned marker_bit4:1;
+	unsigned dts_4:8;
+	unsigned dts_5:7;
+	unsigned marker_bit5:1;
+	unsigned reserved_bits3:4;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+	unsigned packet_start_code_prefix_1:8;
+	unsigned packet_start_code_prefix_2:8;
+	unsigned packet_start_code_prefix_3:8;
+	unsigned stream_id:8;
+	unsigned pes_packet_length_lsb:8;
+	unsigned pes_packet_length_msb:8;
+	unsigned original_or_copy:1;
+	unsigned copyright:1;
+	unsigned data_alignment_indicator:1;
+	unsigned pes_priority:1;
+	unsigned pes_scrambling_control:2;
+	unsigned reserved_bits0:2;
+	unsigned pes_extension_flag:1;
+	unsigned pes_crc_flag:1;
+	unsigned additional_copy_info_flag:1;
+	unsigned dsm_trick_mode_flag:1;
+	unsigned es_rate_flag:1;
+	unsigned escr_flag:1;
+	unsigned pts_dts_flag:2;
+	unsigned pes_header_data_length:8;
+	unsigned marker_bit0:1;
+	unsigned pts_1:3;
+	unsigned reserved_bits1:4;
+	unsigned pts_2:8;
+	unsigned marker_bit1:1;
+	unsigned pts_3:7;
+	unsigned pts_4:8;
+	unsigned marker_bit2:1;
+	unsigned pts_5:7;
+	unsigned marker_bit3:1;
+	unsigned dts_1:3;
+	unsigned reserved_bits2:4;
+	unsigned dts_2:8;
+	unsigned marker_bit4:1;
+	unsigned dts_3:7;
+	unsigned dts_4:8;
+	unsigned marker_bit5:1;
+	unsigned dts_5:7;
+	unsigned reserved_bits3:4;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+} __packed;
+
+/*
+ * mpq_framing_prefix_size_masks - possible prefix sizes.
+ *
+ * @size_mask: a bit mask (per pattern) of possible prefix sizes to use
+ * when searching for a pattern that started in the last buffer.
+ * Updated in mpq_dmx_framing_pattern_search for use in the next lookup
+ */
+struct mpq_framing_prefix_size_masks {
+	u32 size_mask[MPQ_MAX_FOUND_PATTERNS];
+};
+
+/**
+ * mpq_decoder_buffers_desc - decoder buffer(s) management information.
+ *
+ * @desc: Array of buffer descriptors as they are passed to mpq_streambuffer
+ * upon its initialization. These descriptors must remain valid as long as
+ * the mpq_streambuffer object is used.
+ * @ion_handle: Array of ION handles, one for each decoder buffer, used for
+ * kernel memory mapping or allocation. Handles are saved in order to release
+ * resources properly later on.
+ * @decoder_buffers_num: number of buffers that are managed, either externally
+ * or internally by the mpq_streambuffer object
+ */
+struct mpq_decoder_buffers_desc {
+	struct mpq_streambuffer_buffer_desc desc[DMX_MAX_DECODER_BUFFER_NUM];
+	struct ion_handle *ion_handle[DMX_MAX_DECODER_BUFFER_NUM];
+	u32 decoder_buffers_num;
+};
+
+/*
+ * mpq_video_feed_info - private data used for video feed.
+ *
+ * @video_buffer: Holds the streamer buffer shared with
+ * the decoder for feeds having the data going to the decoder.
+ * @video_buffer_lock: Lock protecting against video output buffer.
+ * The lock protects against API calls to manipulate the output buffer
+ * (initialize, free, re-use buffers) and dvb-sw demux parsing the video
+ * data through mpq_dmx_process_video_packet().
+ * @buffer_desc: Holds decoder buffer(s) information used for stream buffer.
+ * @pes_header: Used for feeds that output data to decoder,
+ * holds PES header of current processed PES.
+ * @pes_header_left_bytes: Used for feeds that output data to decoder,
+ * holds remainning PES header bytes of current processed PES.
+ * @pes_header_offset: Holds the offset within the current processed
+ * pes header.
+ * @fullness_wait_cancel: Flag used to signal to abort waiting for
+ * decoder's fullness.
+ * @stream_interface: The ID of the video stream interface registered
+ * with this stream buffer.
+ * @patterns: pointer to the framing patterns to look for.
+ * @patterns_num: number of framing patterns.
+ * @frame_offset: Saves data buffer offset to which a new frame will be written
+ * @last_pattern_offset: Holds the previous pattern offset
+ * @pending_pattern_len: Accumulated number of data bytes that will be
+ * reported for this frame.
+ * @last_framing_match_type: Used for saving the type of
+ * the previous pattern match found in this video feed.
+ * @found_sequence_header_pattern: Flag used to note that an MPEG-2
+ * Sequence Header, H.264 SPS or VC-1 Sequence Header pattern
+ * (whichever is relevant according to the video standard) had already
+ * been found.
+ * @prefix_size: a bit mask representing the size(s) of possible prefixes
+ * to the pattern, already found in the previous buffer. If bit 0 is set,
+ * a prefix of size 1 was found. If bit 1 is set, a prefix of size 2 was
+ * found, etc. This supports a prefix size of up to 32, which is more
+ * than we need. The search function updates prefix_size as needed
+ * for the next buffer search.
+ * @first_prefix_size: used to save the prefix size used to find the first
+ * pattern written to the stream buffer.
+ * @saved_pts_dts_info: used to save PTS/DTS information until it is written.
+ * @new_pts_dts_info: used to store PTS/DTS information from current PES header.
+ * @saved_info_used: indicates if saved PTS/DTS information was used.
+ * @new_info_exists: indicates if new PTS/DTS information exists in
+ * new_pts_dts_info that should be saved to saved_pts_dts_info.
+ * @first_pts_dts_copy: a flag used to indicate if PTS/DTS information needs
+ * to be copied from the currently parsed PES header to the saved_pts_dts_info.
+ * @tei_errs: Transport stream Transport Error Indicator (TEI) counter.
+ * @last_continuity: last continuity counter value found in TS packet header.
+ * Initialized to -1.
+ * @continuity_errs: Transport stream continuity error counter.
+ * @ts_packets_num: TS packets counter.
+ * @ts_dropped_bytes: counts the number of bytes dropped due to insufficient
+ * buffer space.
+ * @last_pkt_index: used to save the last streambuffer packet index reported in
+ * a new elementary stream data event.
+ */
+struct mpq_video_feed_info {
+	struct mpq_streambuffer *video_buffer;
+	spinlock_t video_buffer_lock;
+	struct mpq_decoder_buffers_desc buffer_desc;
+	struct pes_packet_header pes_header;
+	u32 pes_header_left_bytes;
+	u32 pes_header_offset;
+	int fullness_wait_cancel;
+	enum mpq_adapter_stream_if stream_interface;
+	const struct mpq_framing_pattern_lookup_params *patterns;
+	int patterns_num;
+	u32 frame_offset;
+	u32 last_pattern_offset;
+	u32 pending_pattern_len;
+	enum dmx_framing_pattern_type last_framing_match_type;
+	int found_sequence_header_pattern;
+	struct mpq_framing_prefix_size_masks prefix_size;
+	u32 first_prefix_size;
+	struct dmx_pts_dts_info saved_pts_dts_info;
+	struct dmx_pts_dts_info new_pts_dts_info;
+	int saved_info_used;
+	int new_info_exists;
+	int first_pts_dts_copy;
+	u32 tei_errs;
+	int last_continuity;
+	u32 continuity_errs;
+	u32 ts_packets_num;
+	u32 ts_dropped_bytes;
+	int last_pkt_index;
+};
+
+/**
+ * mpq feed object - mpq common plugin feed information
+ *
+ * @dvb_demux_feed: Back pointer to dvb demux level feed object
+ * @mpq_demux: Pointer to common mpq demux object
+ * @plugin_priv: Plugin specific private data
+ * @sdmx_filter_handle: Secure demux filter handle. Recording feed may share
+ * same filter handle
+ * @secondary_feed: Specifies if this feed shares filter handle with
+ * other feeds
+ * @metadata_buf: Ring buffer object for managing the metadata buffer
+ * @metadata_buf_handle: Allocation handle for the metadata buffer
+ * @sdmx_buf: Ring buffer object for intermediate output data from the sdmx
+ * @sdmx_buf_handle: Allocation handle for the sdmx intermediate data buffer
+ * @video_info: Video feed specific information
+ */
+struct mpq_feed {
+	struct dvb_demux_feed *dvb_demux_feed;
+	struct mpq_demux *mpq_demux;
+	void *plugin_priv;
+
+	/* Secure demux related */
+	int sdmx_filter_handle;
+	int secondary_feed;
+	enum sdmx_filter filter_type;
+	struct dvb_ringbuffer metadata_buf;
+	struct ion_handle *metadata_buf_handle;
+
+	struct dvb_ringbuffer sdmx_buf;
+	struct ion_handle *sdmx_buf_handle;
+
+	struct mpq_video_feed_info video_info;
+};
+
+/**
+ * struct mpq_demux - mpq demux information
+ * @demux: The dvb_demux instance used by mpq_demux
+ * @dmxdev: The dmxdev instance used by mpq_demux
+ * @fe_memory: Handle of front-end memory source to mpq_demux
+ * @source: The current source connected to the demux
+ * @is_initialized: Indicates whether this demux device was
+ *                  initialized or not.
+ * @ion_client: ION demux client used to allocate memory from ION.
+ * @mutex: Lock used to protect against private feed data
+ * @feeds: mpq common feed object pool
+ * @filters_status: Array holding buffers status for each secure demux filter.
+ * Used before each call to sdmx_process() to build up to date state.
+ * @sdmx_session_handle: Secure demux open session handle
+ * @sdmx_filter_count: Number of active secure demux filters
+ * @plugin_priv: Underlying plugin's own private data
+ * @hw_notification_interval: Notification interval in msec,
+ *                            exposed in debugfs.
+ * @hw_notification_min_interval: Minimum notification internal in msec,
+ * exposed in debugfs.
+ * @hw_notification_count: Notification count, exposed in debugfs.
+ * @hw_notification_size: Notification size in bytes, exposed in debugfs.
+ * @hw_notification_min_size: Minimum notification size in bytes,
+ *                            exposed in debugfs.
+ * @decoder_drop_count: Accumulated number of bytes dropped due to decoder
+ * buffer fullness, exposed in debugfs.
+ * @decoder_out_count: Counter incremeneted for each video frame output by
+ * demux, exposed in debugfs.
+ * @decoder_out_interval_sum: Sum of intervals (msec) holding the time between
+ * two successive video frames output, exposed in debugfs.
+ * @decoder_out_interval_average: Average interval (msec) between two
+ * successive video frames output, exposed in debugfs.
+ * @decoder_out_interval_max: Max interval (msec) between two
+ * successive video frames output, exposed in debugfs.
+ * @decoder_ts_errors: Counter for number of decoder packets with TEI bit
+ * set, exposed in debugfs.
+ * @sdmx_process_count: Total number of times sdmx_process is called.
+ * @sdmx_process_time_sum: Total time sdmx_process takes.
+ * @sdmx_process_time_average: Average time sdmx_process takes.
+ * @sdmx_process_time_max: Max time sdmx_process takes.
+ * @sdmx_process_packets_sum: Total packets number sdmx_process handled.
+ * @sdmx_process_packets_average: Average packets number sdmx_process handled.
+ * @sdmx_process_packets_min: Minimum packets number sdmx_process handled.
+ * @decoder_out_last_time: Time of last video frame output.
+ * @last_notification_time: Time of last HW notification.
+ */
+struct mpq_demux {
+	struct dvb_demux demux;
+	struct dmxdev dmxdev;
+	struct dmx_frontend fe_memory;
+	dmx_source_t source;
+	int is_initialized;
+	struct ion_client *ion_client;
+	struct mutex mutex;
+	struct mpq_feed feeds[MPQ_MAX_DMX_FILES];
+	struct sdmx_filter_status filters_status[MPQ_MAX_DMX_FILES];
+	int sdmx_session_handle;
+	int sdmx_session_ref_count;
+	int sdmx_filter_count;
+	void *plugin_priv;
+
+	/* debug-fs */
+	u32 hw_notification_interval;
+	u32 hw_notification_min_interval;
+	u32 hw_notification_count;
+	u32 hw_notification_size;
+	u32 hw_notification_min_size;
+	u32 decoder_drop_count;
+	u32 decoder_out_count;
+	u32 decoder_out_interval_sum;
+	u32 decoder_out_interval_average;
+	u32 decoder_out_interval_max;
+	u32 decoder_ts_errors;
+	u32 sdmx_process_count;
+	u32 sdmx_process_time_sum;
+	u32 sdmx_process_time_average;
+	u32 sdmx_process_time_max;
+	u32 sdmx_process_packets_sum;
+	u32 sdmx_process_packets_average;
+	u32 sdmx_process_packets_min;
+
+	struct timespec decoder_out_last_time;
+	struct timespec last_notification_time;
+};
+
+/**
+ * mpq_dmx_init - initialization and registration function of
+ * single MPQ demux device
+ *
+ * @adapter: The adapter to register mpq_demux to
+ * @mpq_demux: The mpq demux to initialize
+ *
+ * Every HW pluging need to provide implementation of such
+ * function that will be called for each demux device on the
+ * module initialization. The function mpq_demux_plugin_init
+ * should be called during the HW plugin module initialization.
+ */
+typedef int (*mpq_dmx_init)(
+				struct dvb_adapter *mpq_adapter,
+				struct mpq_demux *demux);
+
+/**
+ * mpq_demux_plugin_init - Initialize demux devices and register
+ * them to the dvb adapter.
+ *
+ * @dmx_init_func: Pointer to the function to be used
+ *  to initialize demux of the underlying HW plugin.
+ *
+ * Return     error code
+ *
+ * Should be called at the HW plugin module initialization.
+ */
+int mpq_dmx_plugin_init(mpq_dmx_init dmx_init_func);
+
+/**
+ * mpq_demux_plugin_exit - terminate demux devices.
+ *
+ * Should be called at the HW plugin module termination.
+ */
+void mpq_dmx_plugin_exit(void);
+
+/**
+ * mpq_dmx_set_source - implmenetation of set_source routine.
+ *
+ * @demux: The demux device to set its source.
+ * @src: The source to be set.
+ *
+ * Return     error code
+ *
+ * Can be used by the underlying plugins to implement kernel
+ * demux API set_source routine.
+ */
+int mpq_dmx_set_source(struct dmx_demux *demux, const dmx_source_t *src);
+
+/**
+ * mpq_dmx_map_buffer - map user-space buffer into kernel space.
+ *
+ * @demux: The demux device.
+ * @dmx_buffer: The demux buffer from user-space, assumes that
+ * buffer handle is ION file-handle.
+ * @priv_handle: Saves ION-handle of the buffer imported by this function.
+ * @kernel_mem: Saves kernel mapped address of the buffer.
+ *
+ * Return     error code
+ *
+ * The function maps the buffer into kernel memory only if the buffer
+ * was not allocated with secure flag, otherwise the returned kernel
+ * memory address is set to NULL.
+ */
+int mpq_dmx_map_buffer(struct dmx_demux *demux, struct dmx_buffer *dmx_buffer,
+		void **priv_handle, void **kernel_mem);
+
+/**
+ * mpq_dmx_unmap_buffer - unmap user-space buffer from kernel space memory.
+ *
+ * @demux: The demux device.
+ * @priv_handle: ION-handle of the buffer returned from mpq_dmx_map_buffer.
+ *
+ * Return     error code
+ *
+ * The function unmaps the buffer from kernel memory only if the buffer
+ * was not allocated with secure flag.
+ */
+int mpq_dmx_unmap_buffer(struct dmx_demux *demux, void *priv_handle);
+
+/**
+ * mpq_dmx_decoder_fullness_init - Initialize waiting
+ * mechanism on decoder's buffer fullness.
+ *
+ * @feed: The decoder's feed
+ *
+ * Return     error code.
+ */
+int mpq_dmx_decoder_fullness_init(struct dvb_demux_feed *feed);
+
+/**
+ * mpq_dmx_decoder_fullness_wait - Checks whether decoder buffer
+ * have free space as required, if not, wait for it.
+ *
+ * @feed: The decoder's feed
+ * @required_space: the required free space to wait for
+ *
+ * Return     error code.
+ */
+int mpq_dmx_decoder_fullness_wait(struct dvb_demux_feed *feed,
+		size_t required_space);
+
+/**
+ * mpq_dmx_decoder_fullness_abort - Aborts waiting
+ * on decoder's buffer fullness if any waiting is done
+ * now. After calling this, to wait again the user must
+ * call mpq_dmx_decoder_fullness_init.
+ *
+ * @feed: The decoder's feed
+ *
+ * Return     error code.
+ */
+int mpq_dmx_decoder_fullness_abort(struct dvb_demux_feed *feed);
+
+/**
+ * mpq_dmx_decoder_buffer_status - Returns the
+ * status of the decoder's buffer.
+ *
+ * @feed: The decoder's feed
+ * @dmx_buffer_status: Status of decoder's buffer
+ *
+ * Return     error code.
+ */
+int mpq_dmx_decoder_buffer_status(struct dvb_demux_feed *feed,
+		struct dmx_buffer_status *dmx_buffer_status);
+
+/**
+ * mpq_dmx_reuse_decoder_buffer - release buffer passed to decoder for reuse
+ * by the stream-buffer.
+ *
+ * @feed: The decoder's feed.
+ * @cookie: stream-buffer handle of the buffer.
+ *
+ * Return     error code
+ *
+ * The function releases the buffer provided by the stream-buffer
+ * connected to the decoder back to the stream-buffer for reuse.
+ */
+int mpq_dmx_reuse_decoder_buffer(struct dvb_demux_feed *feed, int cookie);
+
+/**
+ * mpq_dmx_process_video_packet - Assemble PES data and output it
+ * to the stream-buffer connected to the decoder.
+ *
+ * @feed: The feed used for the video TS packets
+ * @buf: The buffer holding video TS packet.
+ *
+ * Return     error code.
+ *
+ * The function assumes it receives buffer with single TS packet
+ * of the relevant PID.
+ * If the output buffer is full while assembly, the function drops
+ * the packet and does not write them to the output buffer.
+ * Scrambled packets are bypassed.
+ */
+int mpq_dmx_process_video_packet(struct dvb_demux_feed *feed, const u8 *buf);
+
+/**
+ * mpq_dmx_process_pcr_packet - Extract PCR/STC pairs from
+ * a 192 bytes packet.
+ *
+ * @feed: The feed used for the PCR TS packets
+ * @buf: The buffer holding pcr/stc packet.
+ *
+ * Return     error code.
+ *
+ * The function assumes it receives buffer with single TS packet
+ * of the relevant PID, and that it has 4 bytes
+ * suffix as extra timestamp in the following format:
+ *
+ * Byte3: TSIF flags
+ * Byte0-2: TTS, 0..2^24-1 at 105.47 Khz (27*10^6/256).
+ *
+ * The function callbacks dmxdev after extraction of the pcr/stc
+ * pair.
+ */
+int mpq_dmx_process_pcr_packet(struct dvb_demux_feed *feed, const u8 *buf);
+
+/**
+ * mpq_dmx_is_video_feed - Returns whether the PES feed
+ * is video one.
+ *
+ * @feed: The feed to be checked.
+ *
+ * Return     1 if feed is video feed, 0 otherwise.
+ */
+static inline int mpq_dmx_is_video_feed(struct dvb_demux_feed *feed)
+{
+	if (feed->type != DMX_TYPE_TS)
+		return 0;
+
+	if (feed->ts_type & (~TS_DECODER))
+		return 0;
+
+	if ((feed->pes_type == DMX_TS_PES_VIDEO0) ||
+		(feed->pes_type == DMX_TS_PES_VIDEO1) ||
+		(feed->pes_type == DMX_TS_PES_VIDEO2) ||
+		(feed->pes_type == DMX_TS_PES_VIDEO3))
+		return 1;
+
+	return 0;
+}
+
+/**
+ * mpq_dmx_is_pcr_feed - Returns whether the PES feed
+ * is PCR one.
+ *
+ * @feed: The feed to be checked.
+ *
+ * Return     1 if feed is PCR feed, 0 otherwise.
+ */
+static inline int mpq_dmx_is_pcr_feed(struct dvb_demux_feed *feed)
+{
+	if (feed->type != DMX_TYPE_TS)
+		return 0;
+
+	if (feed->ts_type & (~TS_DECODER))
+		return 0;
+
+	if ((feed->pes_type == DMX_TS_PES_PCR0) ||
+		(feed->pes_type == DMX_TS_PES_PCR1) ||
+		(feed->pes_type == DMX_TS_PES_PCR2) ||
+		(feed->pes_type == DMX_TS_PES_PCR3))
+		return 1;
+
+	return 0;
+}
+
+/**
+ * mpq_dmx_is_sec_feed - Returns whether this is a section feed
+ *
+ * @feed: The feed to be checked.
+ *
+ * Return 1 if feed is a section feed, 0 otherwise.
+ */
+static inline int mpq_dmx_is_sec_feed(struct dvb_demux_feed *feed)
+{
+	return (feed->type == DMX_TYPE_SEC);
+}
+
+/**
+ * mpq_dmx_is_rec_feed - Returns whether this is a recording feed
+ *
+ * @feed: The feed to be checked.
+ *
+ * Return 1 if feed is recording feed, 0 otherwise.
+ */
+static inline int mpq_dmx_is_rec_feed(struct dvb_demux_feed *feed)
+{
+	if (feed->type != DMX_TYPE_TS)
+		return 0;
+
+	if (feed->ts_type & (TS_DECODER | TS_PAYLOAD_ONLY))
+		return 0;
+
+	return 1;
+}
+
+/**
+ * mpq_dmx_init_hw_statistics -
+ * Extend dvb-demux debugfs with HW statistics.
+ *
+ * @mpq_demux: The mpq_demux device to initialize.
+ */
+void mpq_dmx_init_hw_statistics(struct mpq_demux *mpq_demux);
+
+/**
+ * mpq_dmx_update_hw_statistics -
+ * Update dvb-demux debugfs with HW notification statistics.
+ *
+ * @mpq_demux: The mpq_demux device to update.
+ */
+void mpq_dmx_update_hw_statistics(struct mpq_demux *mpq_demux);
+
+/**
+ * mpq_dmx_set_secure_mode - Handles set secure mode command from demux device
+ *
+ * @feed: The feed to set its secure mode
+ * @sec_mode: Secure mode details (key ladder info)
+ *
+ * Return error code
+*/
+int mpq_dmx_set_secure_mode(struct dvb_demux_feed *feed,
+		struct dmx_secure_mode *secure_mode);
+
+/**
+ * mpq_sdmx_open_session - Handle the details of opening a new secure demux
+ * session for the specified mpq demux instance. Multiple calls to this
+ * is allowed, reference counting is managed to open it only when needed.
+ *
+ * @mpq_demux: mpq demux instance
+ *
+ * Return error code
+ */
+int mpq_sdmx_open_session(struct mpq_demux *mpq_demux);
+
+/**
+ * mpq_sdmx_close_session - Closes secure demux session. The session
+ * is closed only if reference counter of the session reaches 0.
+ *
+ * @mpq_demux: mpq demux instance
+ *
+ * Return error code
+ */
+int mpq_sdmx_close_session(struct mpq_demux *mpq_demux);
+
+/**
+ * mpq_dmx_init_mpq_feed - Initialize an mpq feed object
+ * The function allocates mpq_feed object and saves in the dvb_demux_feed
+ * priv field.
+ *
+ * @feed: A dvb demux level feed parent object
+ *
+ * Return error code
+ */
+int mpq_dmx_init_mpq_feed(struct dvb_demux_feed *feed);
+
+/**
+ * mpq_dmx_terminate_feed - Destroy an mpq feed object
+ *
+ * @feed: A dvb demux level feed parent object
+ *
+ * Return error code
+ */
+int mpq_dmx_terminate_feed(struct dvb_demux_feed *feed);
+
+/**
+ * mpq_dmx_write - demux write() function implementation.
+ *
+ * A wrapper function used for writing new data into the demux via DVR.
+ * It checks where new data should actually go, the secure demux or the normal
+ * dvb demux software demux.
+ *
+ * @demux: demux interface
+ * @buf: input buffer
+ * @count: number of data bytes in input buffer
+ *
+ * Return number of bytes processed or error code
+ */
+int mpq_dmx_write(struct dmx_demux *demux, const char *buf, size_t count);
+
+/**
+ * mpq_sdmx_process - Perform demuxing process on the specified input buffer
+ * in the secure demux instance
+ *
+ * @mpq_demux: mpq demux instance
+ * @input: input buffer descriptor
+ * @fill_count: number of data bytes in input buffer that can be read
+ * @read_offset: offset in buffer for reading
+ *
+ * Return number of bytes read or error code
+ */
+int mpq_sdmx_process(struct mpq_demux *mpq_demux,
+	struct sdmx_buff_descr *input,
+	u32 fill_count,
+	u32 read_offset);
+
+/**
+ * mpq_sdmx_loaded - Returns 1 if secure demux application is loaded,
+ * 0 otherwise. This function should be used to determine whether or not
+ * processing should take place in the SDMX.
+ */
+int mpq_sdmx_is_loaded(void);
+
+
+#endif /* _MPQ_DMX_PLUGIN_COMMON_H */
+
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tsif.c b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tsif.c
new file mode 100644
index 0000000..b29759c
--- /dev/null
+++ b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tsif.c
@@ -0,0 +1,848 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/tsif_api.h>
+#include <linux/kthread.h>
+#include <linux/moduleparam.h>
+#include "mpq_dvb_debug.h"
+#include "mpq_dmx_plugin_common.h"
+
+
+/* TSIF HW configuration: */
+#define TSIF_COUNT				2
+
+/* Max number of section filters */
+#define DMX_TSIF_MAX_SECTION_FILTER_NUM	64
+
+/* When TSIF driver notifies demux that new packets are received */
+#define DMX_TSIF_PACKETS_IN_CHUNK_DEF		512
+#define DMX_TSIF_CHUNKS_IN_BUF			16
+#define DMX_TSIF_TIME_LIMIT			10000
+
+/* TSIF_DRIVER_MODE: 3 means manual control from debugfs. use 2 normally. */
+#define DMX_TSIF_DRIVER_MODE_DEF		2
+
+/* module parameters for load time configuration: */
+static int threshold = DMX_TSIF_PACKETS_IN_CHUNK_DEF;
+static int tsif_mode = DMX_TSIF_DRIVER_MODE_DEF;
+static int clock_inv;
+module_param(threshold, int, S_IRUGO);
+module_param(tsif_mode, int, S_IRUGO | S_IWUSR);
+module_param(clock_inv, int, S_IRUGO | S_IWUSR);
+
+
+/*
+ * TSIF driver information
+ */
+struct tsif_driver_info {
+	/* handler to TSIF driver */
+	void *tsif_handler;
+	/* TSIF driver data buffer pointer */
+	void *data_buffer;
+	/* TSIF driver data buffer size, in packets */
+	int buffer_size;
+	/* TSIF driver read pointer */
+	int ri;
+	/* TSIF driver write pointer */
+	int wi;
+	/* TSIF driver state */
+	enum tsif_state state;
+};
+
+
+/*
+ * The following structure hold singelton information
+ * required for dmx implementation on top of TSIF.
+ */
+static struct
+{
+	/* Information for each TSIF input processing */
+	struct {
+		/* thread processing TS packets from TSIF */
+		struct task_struct *thread;
+		wait_queue_head_t wait_queue;
+
+		/* Counter for data notifications from TSIF */
+		atomic_t data_cnt;
+
+		/* TSIF alias */
+		char name[TSIF_NAME_LENGTH];
+
+		/* TSIF driver information */
+		struct tsif_driver_info tsif_driver;
+
+		/* TSIF reference count (counts start/stop operations */
+		int ref_count;
+
+		/* Pointer to the demux connected to this TSIF */
+		struct mpq_demux *mpq_demux;
+
+		/* mutex protecting the data-structure */
+		struct mutex mutex;
+	} tsif[TSIF_COUNT];
+} mpq_dmx_tsif_info;
+
+
+/**
+ * Demux thread function handling data from specific TSIF.
+ *
+ * @arg: TSIF number
+ */
+static int mpq_dmx_tsif_thread(void *arg)
+{
+	struct mpq_demux *mpq_demux;
+	struct tsif_driver_info *tsif_driver;
+	size_t packets = 0;
+	int tsif = (int)arg;
+	int ret;
+
+	do {
+		ret = wait_event_interruptible(
+			mpq_dmx_tsif_info.tsif[tsif].wait_queue,
+			(atomic_read(
+				&mpq_dmx_tsif_info.tsif[tsif].data_cnt) != 0) ||
+			kthread_should_stop());
+
+		if ((ret < 0) || kthread_should_stop()) {
+			MPQ_DVB_DBG_PRINT("%s: exit\n", __func__);
+			break;
+		}
+
+		if (mutex_lock_interruptible(
+			&mpq_dmx_tsif_info.tsif[tsif].mutex))
+			return -ERESTARTSYS;
+
+		tsif_driver = &(mpq_dmx_tsif_info.tsif[tsif].tsif_driver);
+		mpq_demux = mpq_dmx_tsif_info.tsif[tsif].mpq_demux;
+
+		/* Check if driver handler is still valid */
+		if (tsif_driver->tsif_handler == NULL) {
+			mutex_unlock(&mpq_dmx_tsif_info.tsif[tsif].mutex);
+			MPQ_DVB_DBG_PRINT(
+				"%s: tsif was detached\n",
+				__func__);
+			continue;
+		}
+
+		tsif_get_state(
+			tsif_driver->tsif_handler, &(tsif_driver->ri),
+			&(tsif_driver->wi), &(tsif_driver->state));
+
+		if ((tsif_driver->wi == tsif_driver->ri) ||
+			(tsif_driver->state == tsif_state_stopped) ||
+			(tsif_driver->state == tsif_state_error)) {
+
+			mpq_demux->hw_notification_size = 0;
+
+			mutex_unlock(&mpq_dmx_tsif_info.tsif[tsif].mutex);
+
+			MPQ_DVB_DBG_PRINT(
+				"%s: TSIF invalid state %d, %d, %d\n",
+				__func__,
+				tsif_driver->state,
+				tsif_driver->wi,
+				tsif_driver->ri);
+			continue;
+		}
+
+		atomic_dec(&mpq_dmx_tsif_info.tsif[tsif].data_cnt);
+
+		if (tsif_driver->wi > tsif_driver->ri) {
+			packets = (tsif_driver->wi - tsif_driver->ri);
+			mpq_demux->hw_notification_size = packets;
+
+			dvb_dmx_swfilter_format(
+				&mpq_demux->demux,
+				(tsif_driver->data_buffer +
+				(tsif_driver->ri * TSIF_PKT_SIZE)),
+				(packets * TSIF_PKT_SIZE),
+				DMX_TSP_FORMAT_192_TAIL);
+
+			tsif_driver->ri =
+				(tsif_driver->ri + packets) %
+				tsif_driver->buffer_size;
+
+			tsif_reclaim_packets(
+				tsif_driver->tsif_handler,
+					tsif_driver->ri);
+		} else {
+			/*
+			 * wi < ri, means wraparound on cyclic buffer.
+			 * Handle in two stages.
+			 */
+			packets = (tsif_driver->buffer_size - tsif_driver->ri);
+			mpq_demux->hw_notification_size = packets;
+
+			dvb_dmx_swfilter_format(
+				&mpq_demux->demux,
+				(tsif_driver->data_buffer +
+				(tsif_driver->ri * TSIF_PKT_SIZE)),
+				(packets * TSIF_PKT_SIZE),
+				DMX_TSP_FORMAT_192_TAIL);
+
+			/* tsif_driver->ri should be 0 after this */
+			tsif_driver->ri =
+				(tsif_driver->ri + packets) %
+				tsif_driver->buffer_size;
+
+			packets = tsif_driver->wi;
+			if (packets > 0) {
+				mpq_demux->hw_notification_size += packets;
+
+				dvb_dmx_swfilter_format(
+					&mpq_demux->demux,
+					(tsif_driver->data_buffer +
+					(tsif_driver->ri * TSIF_PKT_SIZE)),
+					(packets * TSIF_PKT_SIZE),
+					DMX_TSP_FORMAT_192_TAIL);
+
+				tsif_driver->ri =
+					(tsif_driver->ri + packets) %
+					tsif_driver->buffer_size;
+			}
+
+			tsif_reclaim_packets(
+				tsif_driver->tsif_handler,
+				tsif_driver->ri);
+		}
+
+		mutex_unlock(&mpq_dmx_tsif_info.tsif[tsif].mutex);
+	} while (1);
+
+	return 0;
+}
+
+
+/**
+ * Callback function from TSIF driver when new data is ready.
+ *
+ * @user: user-data holding TSIF number
+ */
+static void mpq_tsif_callback(void *user)
+{
+	int tsif = (int)user;
+	struct mpq_demux *mpq_demux;
+
+	MPQ_DVB_DBG_PRINT("%s executed, tsif = %d\n", __func__,	tsif);
+
+	/* Save statistics on TSIF notifications */
+	mpq_demux = mpq_dmx_tsif_info.tsif[tsif].mpq_demux;
+	mpq_dmx_update_hw_statistics(mpq_demux);
+
+	atomic_inc(&mpq_dmx_tsif_info.tsif[tsif].data_cnt);
+	wake_up(&mpq_dmx_tsif_info.tsif[tsif].wait_queue);
+}
+
+
+/**
+ * Attach to TSIF driver and start TSIF operation.
+ *
+ * @mpq_demux: the mpq_demux we are working on.
+ *
+ * Return	error code.
+ */
+static int mpq_tsif_dmx_start(struct mpq_demux *mpq_demux)
+{
+	int ret = 0;
+	int tsif;
+	struct tsif_driver_info *tsif_driver;
+
+	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
+
+	/* determine the TSIF we are reading from */
+	if (mpq_demux->source == DMX_SOURCE_FRONT0) {
+		tsif = 0;
+	} else if (mpq_demux->source == DMX_SOURCE_FRONT1) {
+		tsif = 1;
+	} else {
+		/* invalid source */
+		MPQ_DVB_ERR_PRINT(
+			"%s: invalid input source (%d)\n",
+			__func__,
+			mpq_demux->source);
+
+		return -EINVAL;
+	}
+
+	if (mutex_lock_interruptible(&mpq_dmx_tsif_info.tsif[tsif].mutex))
+		return -ERESTARTSYS;
+
+	if (mpq_dmx_tsif_info.tsif[tsif].ref_count == 0) {
+		tsif_driver = &(mpq_dmx_tsif_info.tsif[tsif].tsif_driver);
+
+		/* Attach to TSIF driver */
+		tsif_driver->tsif_handler =
+			tsif_attach(tsif, mpq_tsif_callback, (void *)tsif);
+		if (IS_ERR_OR_NULL(tsif_driver->tsif_handler)) {
+			tsif_driver->tsif_handler = NULL;
+			mutex_unlock(&mpq_dmx_tsif_info.tsif[tsif].mutex);
+			MPQ_DVB_DBG_PRINT("%s: tsif_attach(%d) failed\n",
+					__func__, tsif);
+			return -ENODEV;
+		}
+
+		ret = tsif_set_clk_inverse(tsif_driver->tsif_handler,
+					clock_inv);
+		if (ret < 0) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: tsif_set_clk_inverse (%d) failed\n",
+				__func__, clock_inv);
+		}
+
+		/* Set TSIF driver mode */
+		ret = tsif_set_mode(tsif_driver->tsif_handler, tsif_mode);
+		if (ret < 0) {
+			MPQ_DVB_ERR_PRINT("%s: tsif_set_mode (%d) failed\n",
+				__func__, tsif_mode);
+		}
+
+		/* Set TSIF buffer configuration */
+		ret = tsif_set_buf_config(tsif_driver->tsif_handler,
+						threshold,
+						DMX_TSIF_CHUNKS_IN_BUF);
+		if (ret < 0) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: tsif_set_buf_config (%d, %d) failed\n",
+				__func__, threshold,
+				DMX_TSIF_CHUNKS_IN_BUF);
+			MPQ_DVB_ERR_PRINT("Using default TSIF driver values\n");
+		}
+
+		/* Start TSIF driver */
+		ret = tsif_start(tsif_driver->tsif_handler);
+		if (ret < 0) {
+			mutex_unlock(&mpq_dmx_tsif_info.tsif[tsif].mutex);
+			MPQ_DVB_ERR_PRINT("%s: tsif_start failed\n", __func__);
+			return ret;
+		}
+
+		/*
+		 * Get data buffer information from TSIF driver
+		 * (must be called after tsif_start)
+		 */
+		tsif_get_info(tsif_driver->tsif_handler,
+				&(tsif_driver->data_buffer),
+				&(tsif_driver->buffer_size));
+
+		/* save pointer to the mpq_demux we are working on */
+		mpq_dmx_tsif_info.tsif[tsif].mpq_demux = mpq_demux;
+	}
+	mpq_dmx_tsif_info.tsif[tsif].ref_count++;
+
+	mutex_unlock(&mpq_dmx_tsif_info.tsif[tsif].mutex);
+
+	return ret;
+}
+
+
+/**
+ * Stop TSIF operation and detach from TSIF driver.
+ *
+ * @mpq_demux: the mpq_demux we are working on.
+ *
+ * Return	error code.
+ */
+static int mpq_tsif_dmx_stop(struct mpq_demux *mpq_demux)
+{
+	int tsif;
+	struct tsif_driver_info *tsif_driver;
+
+	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
+
+	/* determine the TSIF we are reading from */
+	if (mpq_demux->source == DMX_SOURCE_FRONT0) {
+		tsif = 0;
+	} else if (mpq_demux->source == DMX_SOURCE_FRONT1) {
+		tsif = 1;
+	} else {
+		/* invalid source */
+		MPQ_DVB_ERR_PRINT(
+			"%s: invalid input source (%d)\n",
+			__func__,
+			mpq_demux->source);
+
+		return -EINVAL;
+	}
+
+	if (mutex_lock_interruptible(&mpq_dmx_tsif_info.tsif[tsif].mutex))
+		return -ERESTARTSYS;
+
+	mpq_dmx_tsif_info.tsif[tsif].ref_count--;
+
+	if (mpq_dmx_tsif_info.tsif[tsif].ref_count == 0) {
+		tsif_driver = &(mpq_dmx_tsif_info.tsif[tsif].tsif_driver);
+		tsif_stop(tsif_driver->tsif_handler);
+		tsif_detach(tsif_driver->tsif_handler);
+		tsif_driver->tsif_handler = NULL;
+		tsif_driver->data_buffer = NULL;
+		tsif_driver->buffer_size = 0;
+		atomic_set(&mpq_dmx_tsif_info.tsif[tsif].data_cnt, 0);
+		mpq_dmx_tsif_info.tsif[tsif].mpq_demux = NULL;
+	}
+
+	mutex_unlock(&mpq_dmx_tsif_info.tsif[tsif].mutex);
+
+	return 0;
+}
+
+
+/**
+ * Start filtering according to feed parameter.
+ *
+ * @feed: the feed we are working on.
+ *
+ * Return	error code.
+ */
+static int mpq_tsif_dmx_start_filtering(struct dvb_demux_feed *feed)
+{
+	int ret = 0;
+	struct mpq_demux *mpq_demux = feed->demux->priv;
+
+	MPQ_DVB_DBG_PRINT(
+		"%s(%d) executed\n",
+		__func__,
+		feed->pid);
+
+	if (mpq_demux == NULL) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: invalid mpq_demux handle\n",
+			__func__);
+
+		return -EINVAL;
+	}
+
+	if (mpq_demux->source < DMX_SOURCE_DVR0) {
+		/* Source from TSIF, need to configure TSIF hardware */
+		ret = mpq_tsif_dmx_start(mpq_demux);
+
+		if (ret < 0) {
+			MPQ_DVB_DBG_PRINT(
+				"%s: mpq_tsif_dmx_start failed(%d)\n",
+				__func__,
+				ret);
+			return ret;
+		}
+	}
+
+	/* Always feed sections/PES starting from a new one and
+	 * do not partial transfer data from older one
+	 */
+	feed->pusi_seen = 0;
+
+	ret = mpq_dmx_init_mpq_feed(feed);
+	if (ret < 0) {
+		MPQ_DVB_DBG_PRINT(
+			"%s: mpq_dmx_init_mpq_feed failed(%d)\n",
+			__func__,
+			ret);
+
+		if (mpq_demux->source < DMX_SOURCE_DVR0)
+			mpq_tsif_dmx_stop(mpq_demux);
+
+		return ret;
+	}
+
+	return ret;
+}
+
+
+/**
+ * Stop filtering according to feed parameter.
+ *
+ * @feed: the feed we are working on.
+ *
+ * Return	error code.
+ */
+static int mpq_tsif_dmx_stop_filtering(struct dvb_demux_feed *feed)
+{
+	int ret = 0;
+	struct mpq_demux *mpq_demux = feed->demux->priv;
+
+	MPQ_DVB_DBG_PRINT(
+		"%s(%d) executed\n",
+		__func__,
+		feed->pid);
+
+	if (mpq_demux == NULL) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: invalid mpq_demux handle\n",
+			__func__);
+
+		return -EINVAL;
+	}
+
+	mpq_dmx_terminate_feed(feed);
+
+	if (mpq_demux->source < DMX_SOURCE_DVR0) {
+		/* Source from TSIF, need to configure TSIF hardware */
+		ret = mpq_tsif_dmx_stop(mpq_demux);
+	}
+
+	return ret;
+}
+
+
+/**
+ * TSIF demux plugin write-to-decoder function.
+ *
+ * @feed: The feed we are working on.
+ * @buf: The data buffer to process.
+ * @len: The data buffer length.
+ *
+ * Return	error code
+ */
+static int mpq_tsif_dmx_write_to_decoder(
+					struct dvb_demux_feed *feed,
+					const u8 *buf,
+					size_t len)
+{
+	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
+
+	/*
+	 * It is assumed that this function is called once for each
+	 * TS packet of the relevant feed.
+	 */
+	if (len > TSIF_PKT_SIZE)
+		MPQ_DVB_DBG_PRINT(
+				"%s: warnning - len larger than one packet\n",
+				__func__);
+
+	if (mpq_dmx_is_video_feed(feed))
+		return mpq_dmx_process_video_packet(feed, buf);
+
+	if (mpq_dmx_is_pcr_feed(feed))
+		return mpq_dmx_process_pcr_packet(feed, buf);
+
+	return 0;
+}
+
+/**
+ * Returns demux capabilities of TSIF plugin
+ *
+ * @demux: demux device
+ * @caps: Returned capbabilities
+ *
+ * Return     error code
+ */
+static int mpq_tsif_dmx_get_caps(struct dmx_demux *demux,
+				struct dmx_caps *caps)
+{
+	struct dvb_demux *dvb_demux = demux->priv;
+
+	if ((dvb_demux == NULL) || (caps == NULL)) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: invalid parameters\n",
+			__func__);
+
+		return -EINVAL;
+	}
+
+	caps->caps = DMX_CAP_PULL_MODE | DMX_CAP_VIDEO_DECODER_DATA;
+	caps->num_decoders = MPQ_ADAPTER_MAX_NUM_OF_INTERFACES;
+	caps->num_demux_devices = CONFIG_DVB_MPQ_NUM_DMX_DEVICES;
+	caps->num_pid_filters = dvb_demux->feednum;
+	caps->num_section_filters = dvb_demux->filternum;
+	caps->num_section_filters_per_pid = dvb_demux->filternum;
+	caps->section_filter_length = DMX_FILTER_SIZE;
+	caps->num_demod_inputs = TSIF_COUNT;
+	caps->num_memory_inputs = CONFIG_DVB_MPQ_NUM_DMX_DEVICES;
+	caps->max_bitrate = 144;
+	caps->demod_input_max_bitrate = 72;
+	caps->memory_input_max_bitrate = 72;
+
+	/* Buffer requirements */
+	caps->section.flags =
+		DMX_BUFFER_EXTERNAL_SUPPORT	|
+		DMX_BUFFER_INTERNAL_SUPPORT;
+	caps->section.max_buffer_num = 1;
+	caps->section.max_size = 0xFFFFFFFF;
+	caps->section.size_alignment = 0;
+	caps->pes.flags =
+		DMX_BUFFER_EXTERNAL_SUPPORT	|
+		DMX_BUFFER_INTERNAL_SUPPORT;
+	caps->pes.max_buffer_num = 1;
+	caps->pes.max_size = 0xFFFFFFFF;
+	caps->pes.size_alignment = 0;
+	caps->recording_188_tsp.flags =
+		DMX_BUFFER_EXTERNAL_SUPPORT	|
+		DMX_BUFFER_INTERNAL_SUPPORT;
+	caps->recording_188_tsp.max_buffer_num = 1;
+	caps->recording_188_tsp.max_size = 0xFFFFFFFF;
+	caps->recording_188_tsp.size_alignment = 0;
+	caps->recording_192_tsp.flags =
+		DMX_BUFFER_EXTERNAL_SUPPORT	|
+		DMX_BUFFER_INTERNAL_SUPPORT;
+	caps->recording_192_tsp.max_buffer_num = 1;
+	caps->recording_192_tsp.max_size = 0xFFFFFFFF;
+	caps->recording_192_tsp.size_alignment = 0;
+	caps->playback_188_tsp.flags =
+		DMX_BUFFER_EXTERNAL_SUPPORT	|
+		DMX_BUFFER_INTERNAL_SUPPORT;
+	caps->playback_188_tsp.max_buffer_num = 1;
+	caps->playback_188_tsp.max_size = 0xFFFFFFFF;
+	caps->playback_188_tsp.size_alignment = 0;
+	caps->playback_192_tsp.flags =
+		DMX_BUFFER_EXTERNAL_SUPPORT	|
+		DMX_BUFFER_INTERNAL_SUPPORT;
+	caps->playback_192_tsp.max_buffer_num = 1;
+	caps->playback_192_tsp.max_size = 0xFFFFFFFF;
+	caps->playback_192_tsp.size_alignment = 0;
+	caps->decoder.flags =
+		DMX_BUFFER_CONTIGUOUS_MEM	|
+		DMX_BUFFER_SECURED_IF_DECRYPTED	|
+		DMX_BUFFER_EXTERNAL_SUPPORT	|
+		DMX_BUFFER_INTERNAL_SUPPORT	|
+		DMX_BUFFER_LINEAR_GROUP_SUPPORT;
+	caps->decoder.max_buffer_num = DMX_MAX_DECODER_BUFFER_NUM;
+	caps->decoder.max_size = 0xFFFFFFFF;
+	caps->decoder.size_alignment = SZ_4K;
+
+	return 0;
+}
+
+/**
+ * Reads TSIF STC from TSPP
+ *
+ * @demux: demux device
+ * @num: STC number. 0 for TSIF0 and 1 for TSIF1.
+ * @stc: STC value
+ * @base: divisor to get 90KHz value
+ *
+ * Return     error code
+ */
+static int mpq_tsif_dmx_get_stc(struct dmx_demux *demux, unsigned int num,
+		u64 *stc, unsigned int *base)
+{
+	struct tsif_driver_info *tsif_driver;
+	u32 tcr_counter;
+
+	if (!demux || !stc || !base)
+		return -EINVAL;
+
+	if (num == 0)
+		tsif_driver = &mpq_dmx_tsif_info.tsif[0].tsif_driver;
+	else if (num == 1)
+		tsif_driver = &mpq_dmx_tsif_info.tsif[1].tsif_driver;
+	else
+		return -EINVAL;
+
+	if (!tsif_driver->tsif_handler)
+		return -ENODEV;
+
+	tsif_get_ref_clk_counter(tsif_driver->tsif_handler, &tcr_counter);
+
+	*stc = ((u64)tcr_counter) * 256; /* conversion to 27MHz */
+	*base = 300; /* divisor to get 90KHz clock from stc value */
+
+	return 0;
+}
+
+/**
+ * Initialize a single demux device.
+ *
+ * @mpq_adapter: MPQ DVB adapter
+ * @mpq_demux: The demux device to initialize
+ *
+ * Return	error code
+ */
+static int mpq_tsif_dmx_init(
+		struct dvb_adapter *mpq_adapter,
+		struct mpq_demux *mpq_demux)
+{
+	int result;
+
+	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
+
+	/* Set the kernel-demux object capabilities */
+	mpq_demux->demux.dmx.capabilities =
+		DMX_TS_FILTERING		|
+		DMX_PES_FILTERING		|
+		DMX_SECTION_FILTERING		|
+		DMX_MEMORY_BASED_FILTERING	|
+		DMX_CRC_CHECKING		|
+		DMX_TS_DESCRAMBLING;
+
+	/* Set dvb-demux "virtual" function pointers */
+	mpq_demux->demux.priv = (void *)mpq_demux;
+	mpq_demux->demux.filternum = DMX_TSIF_MAX_SECTION_FILTER_NUM;
+	mpq_demux->demux.feednum = MPQ_MAX_DMX_FILES;
+	mpq_demux->demux.start_feed = mpq_tsif_dmx_start_filtering;
+	mpq_demux->demux.stop_feed = mpq_tsif_dmx_stop_filtering;
+	mpq_demux->demux.write_to_decoder = mpq_tsif_dmx_write_to_decoder;
+	mpq_demux->demux.decoder_fullness_init = mpq_dmx_decoder_fullness_init;
+	mpq_demux->demux.decoder_fullness_wait = mpq_dmx_decoder_fullness_wait;
+	mpq_demux->demux.decoder_fullness_abort =
+		mpq_dmx_decoder_fullness_abort;
+	mpq_demux->demux.decoder_buffer_status = mpq_dmx_decoder_buffer_status;
+	mpq_demux->demux.reuse_decoder_buffer = mpq_dmx_reuse_decoder_buffer;
+	mpq_demux->demux.set_secure_mode = NULL;
+
+	/* Initialize dvb_demux object */
+	result = dvb_dmx_init(&mpq_demux->demux);
+	if (result < 0) {
+		MPQ_DVB_ERR_PRINT("%s: dvb_dmx_init failed\n", __func__);
+		goto init_failed;
+	}
+
+	/* Now initailize the dmx-dev object */
+	mpq_demux->dmxdev.filternum = MPQ_MAX_DMX_FILES;
+	mpq_demux->dmxdev.demux = &mpq_demux->demux.dmx;
+	mpq_demux->dmxdev.capabilities =
+		DMXDEV_CAP_DUPLEX |
+		DMXDEV_CAP_PULL_MODE |
+		DMXDEV_CAP_INDEXING;
+
+	mpq_demux->dmxdev.demux->set_source = mpq_dmx_set_source;
+	mpq_demux->dmxdev.demux->get_stc = mpq_tsif_dmx_get_stc;
+	mpq_demux->dmxdev.demux->get_caps = mpq_tsif_dmx_get_caps;
+	mpq_demux->dmxdev.demux->map_buffer = mpq_dmx_map_buffer;
+	mpq_demux->dmxdev.demux->unmap_buffer = mpq_dmx_unmap_buffer;
+
+	result = dvb_dmxdev_init(&mpq_demux->dmxdev, mpq_adapter);
+	if (result < 0) {
+		MPQ_DVB_ERR_PRINT("%s: dvb_dmxdev_init failed (errno=%d)\n",
+						  __func__,
+						  result);
+		goto init_failed_dmx_release;
+	}
+
+	/* Extend dvb-demux debugfs with TSIF statistics. */
+	mpq_dmx_init_hw_statistics(mpq_demux);
+
+	return 0;
+
+init_failed_dmx_release:
+	dvb_dmx_release(&mpq_demux->demux);
+init_failed:
+	return result;
+}
+
+
+/**
+ * Module initialization function.
+ *
+ * Return	error code
+ */
+static int __init mpq_dmx_tsif_plugin_init(void)
+{
+	int i;
+	int ret;
+
+	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
+
+	/* check module parameters validity */
+	if (threshold < 1) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: invalid threshold parameter, using %d instead\n",
+			__func__, DMX_TSIF_PACKETS_IN_CHUNK_DEF);
+		threshold = DMX_TSIF_PACKETS_IN_CHUNK_DEF;
+	}
+	if ((tsif_mode < 1) || (tsif_mode > 3)) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: invalid mode parameter, using %d instead\n",
+			__func__, DMX_TSIF_DRIVER_MODE_DEF);
+		tsif_mode = DMX_TSIF_DRIVER_MODE_DEF;
+	}
+
+	for (i = 0; i < TSIF_COUNT; i++) {
+		snprintf(mpq_dmx_tsif_info.tsif[i].name,
+				TSIF_NAME_LENGTH,
+				"dmx_tsif%d",
+				i);
+
+		atomic_set(&mpq_dmx_tsif_info.tsif[i].data_cnt, 0);
+		init_waitqueue_head(&mpq_dmx_tsif_info.tsif[i].wait_queue);
+		mpq_dmx_tsif_info.tsif[i].thread =
+			kthread_run(
+				mpq_dmx_tsif_thread, (void *)i,
+				mpq_dmx_tsif_info.tsif[i].name);
+
+		if (IS_ERR(mpq_dmx_tsif_info.tsif[i].thread)) {
+			int j;
+
+			for (j = 0; j < i; j++) {
+				kthread_stop(mpq_dmx_tsif_info.tsif[j].thread);
+				mutex_destroy(&mpq_dmx_tsif_info.tsif[j].mutex);
+			}
+
+			MPQ_DVB_ERR_PRINT(
+				"%s: kthread_run failed\n",
+				__func__);
+
+			return -ENOMEM;
+		}
+
+		mutex_init(&mpq_dmx_tsif_info.tsif[i].mutex);
+
+		mpq_dmx_tsif_info.tsif[i].tsif_driver.tsif_handler = NULL;
+		mpq_dmx_tsif_info.tsif[i].ref_count = 0;
+	}
+
+	ret = mpq_dmx_plugin_init(mpq_tsif_dmx_init);
+
+	if (ret < 0) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: mpq_dmx_plugin_init failed (errno=%d)\n",
+			__func__,
+			ret);
+
+		for (i = 0; i < TSIF_COUNT; i++) {
+			kthread_stop(mpq_dmx_tsif_info.tsif[i].thread);
+			mutex_destroy(&mpq_dmx_tsif_info.tsif[i].mutex);
+		}
+	}
+
+	return ret;
+}
+
+
+/**
+ * Module exit function.
+ */
+static void __exit mpq_dmx_tsif_plugin_exit(void)
+{
+	int i;
+	struct tsif_driver_info *tsif_driver;
+
+	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
+
+	for (i = 0; i < TSIF_COUNT; i++) {
+		mutex_lock(&mpq_dmx_tsif_info.tsif[i].mutex);
+
+		tsif_driver = &(mpq_dmx_tsif_info.tsif[i].tsif_driver);
+		if (mpq_dmx_tsif_info.tsif[i].ref_count > 0) {
+			mpq_dmx_tsif_info.tsif[i].ref_count = 0;
+			if (tsif_driver->tsif_handler)
+				tsif_stop(tsif_driver->tsif_handler);
+		}
+
+		/* Detach from TSIF driver to avoid further notifications. */
+		if (tsif_driver->tsif_handler)
+			tsif_detach(tsif_driver->tsif_handler);
+
+		mutex_unlock(&mpq_dmx_tsif_info.tsif[i].mutex);
+		kthread_stop(mpq_dmx_tsif_info.tsif[i].thread);
+		mutex_destroy(&mpq_dmx_tsif_info.tsif[i].mutex);
+	}
+
+	mpq_dmx_plugin_exit();
+}
+
+
+module_init(mpq_dmx_tsif_plugin_init);
+module_exit(mpq_dmx_tsif_plugin_exit);
+
+MODULE_DESCRIPTION("Qualcomm demux TSIF HW Plugin");
+MODULE_LICENSE("GPL v2");
+
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tspp_v1.c b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tspp_v1.c
new file mode 100644
index 0000000..632e864
--- /dev/null
+++ b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tspp_v1.c
@@ -0,0 +1,1896 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kthread.h>
+#include <linux/vmalloc.h>
+#include <mach/msm_tspp.h>
+#include "mpq_dvb_debug.h"
+#include "mpq_dmx_plugin_common.h"
+
+#define TSIF_COUNT			2
+
+/* Max number of PID filters */
+#define TSPP_MAX_PID_FILTER_NUM		128
+
+/* Max number of user-defined HW PID filters */
+#define TSPP_MAX_HW_PID_FILTER_NUM	15
+
+/* HW index  of the last entry in the TSPP HW filter table */
+#define TSPP_LAST_HW_FILTER_INDEX	15
+
+/* Number of filters required to accept all packets except NULL packets */
+#define TSPP_BLOCK_NULLS_FILTERS_NUM	13
+
+/* Max number of section filters */
+#define TSPP_MAX_SECTION_FILTER_NUM	128
+
+/* For each TSIF we use a single pipe holding the data after PID filtering */
+#define TSPP_CHANNEL			0
+
+/* the channel_id set to TSPP driver based on TSIF number and channel type */
+#define TSPP_CHANNEL_ID(tsif, ch)		((tsif << 1) + ch)
+#define TSPP_GET_TSIF_NUM(ch_id)		(ch_id >> 1)
+
+/* mask that set to care for all bits in pid filter */
+#define TSPP_PID_MASK			0x1FFF
+
+/* dvb-demux defines pid 0x2000 as full capture pid */
+#define TSPP_PASS_THROUGH_PID		0x2000
+
+/* NULL packets pid */
+#define TSPP_NULL_PACKETS_PID		0x1FFF
+
+#define TSPP_RAW_TTS_SIZE		192
+#define TSPP_RAW_SIZE			188
+
+#define MAX_BAM_DESCRIPTOR_SIZE	(32*1024 - 1)
+
+#define TSPP_BUFFER_SIZE		(500 * 1024) /* 500KB */
+
+#define TSPP_DESCRIPTOR_SIZE	(TSPP_RAW_TTS_SIZE)
+
+#define TSPP_BUFFER_COUNT(buffer_size)	\
+	((buffer_size) / TSPP_RAW_TTS_SIZE)
+
+/* When TSPP notifies demux that new packets are received.
+ * Using max descriptor size (170 packets).
+ * Assuming 20MBit/sec stream, with 170 packets
+ * per descriptor there would be about 82 descriptors,
+ * Meanning about 82 notifications per second.
+ */
+#define TSPP_NOTIFICATION_SIZE(desc_size)		\
+	(MAX_BAM_DESCRIPTOR_SIZE / (desc_size))
+
+/* Channel timeout in msec */
+#define TSPP_CHANNEL_TIMEOUT			100
+
+enum mem_buffer_allocation_mode {
+	MPQ_DMX_TSPP_INTERNAL_ALLOC = 0,
+	MPQ_DMX_TSPP_CONTIGUOUS_PHYS_ALLOC = 1
+};
+
+/* module parameters for load time configuration */
+static int clock_inv;
+static int tsif_mode = 2;
+static int allocation_mode = MPQ_DMX_TSPP_INTERNAL_ALLOC;
+static int tspp_out_buffer_size = TSPP_BUFFER_SIZE;
+static int tspp_notification_size =
+	TSPP_NOTIFICATION_SIZE(TSPP_DESCRIPTOR_SIZE);
+static int tspp_channel_timeout = TSPP_CHANNEL_TIMEOUT;
+static int tspp_out_ion_heap = ION_QSECOM_HEAP_ID;
+
+module_param(tsif_mode, int, S_IRUGO | S_IWUSR);
+module_param(clock_inv, int, S_IRUGO | S_IWUSR);
+module_param(allocation_mode, int, S_IRUGO | S_IWUSR);
+module_param(tspp_out_buffer_size, int, S_IRUGO);
+module_param(tspp_notification_size, int, S_IRUGO | S_IWUSR);
+module_param(tspp_channel_timeout, int, S_IRUGO | S_IWUSR);
+module_param(tspp_out_ion_heap, int, S_IRUGO | S_IWUSR);
+
+/* The following structure hold singelton information
+ * required for dmx implementation on top of TSPP.
+ */
+static struct
+{
+	/* Information for each TSIF input processing */
+	struct {
+		/*
+		 * TSPP pipe holding all TS packets after PID filtering.
+		 * The following is reference count for number of feeds
+		 * allocated on that pipe.
+		 */
+		int channel_ref;
+
+		/* Counter for data notifications on the pipe */
+		atomic_t data_cnt;
+
+		/* ION handle used for TSPP data buffer allocation */
+		struct ion_handle *ch_mem_heap_handle;
+
+		/* TSPP data buffer heap virtual base address */
+		void *ch_mem_heap_virt_base;
+
+		/* TSPP data buffer heap physical base address */
+		ion_phys_addr_t ch_mem_heap_phys_base;
+
+		/* Buffer allocation index */
+		int buff_index;
+
+		/* Number of buffers */
+		u32 buffer_count;
+
+		/*
+		 * Array holding the IDs of the TSPP buffer descriptors in the
+		 * current aggregate, in order to release these descriptors at
+		 * the end of processing.
+		 */
+		int *aggregate_ids;
+
+		/*
+		 * Holds PIDs of allocated filters along with
+		 * how many feeds are opened on the same PID. For
+		 * TSPP HW filters, holds also the filter table index.
+		 * When pid == -1, the entry is free.
+		 */
+		struct {
+			int pid;
+			int ref_count;
+			int hw_index;
+		} filters[TSPP_MAX_PID_FILTER_NUM];
+
+		/* Indicates available/allocated filter table indexes */
+		int hw_indexes[TSPP_MAX_HW_PID_FILTER_NUM];
+
+		/* Number of currently allocated PID filters */
+		u16 current_filter_count;
+
+		/*
+		 * Flag to indicate whether the user added a filter to accept
+		 * NULL packets (PID = 0x1FFF)
+		 */
+		int pass_nulls_flag;
+
+		/*
+		 * Flag to indicate whether the user added a filter to accept
+		 * all packets (PID = 0x2000)
+		 */
+		int pass_all_flag;
+
+		/*
+		 * Flag to indicate whether the filter that accepts
+		 * all packets has already been added and is
+		 * currently enabled
+		 */
+		int accept_all_filter_exists_flag;
+
+		/* Thread processing TS packets from TSPP */
+		struct task_struct *thread;
+		wait_queue_head_t wait_queue;
+
+		/* TSIF alias */
+		char name[TSIF_NAME_LENGTH];
+
+		/* Pointer to the demux connected to this TSIF */
+		struct mpq_demux *mpq_demux;
+
+		/* Mutex protecting the data-structure */
+		struct mutex mutex;
+	} tsif[TSIF_COUNT];
+
+	/* ION client used for TSPP data buffer allocation */
+	struct ion_client *ion_client;
+} mpq_dmx_tspp_info;
+
+static void *tspp_mem_allocator(int channel_id, u32 size,
+				u32 *phys_base, void *user)
+{
+	void *virt_addr = NULL;
+	int i = TSPP_GET_TSIF_NUM(channel_id);
+
+	if (mpq_dmx_tspp_info.tsif[i].buff_index ==
+		mpq_dmx_tspp_info.tsif[i].buffer_count)
+		return NULL;
+
+	virt_addr =
+		(mpq_dmx_tspp_info.tsif[i].ch_mem_heap_virt_base +
+		(mpq_dmx_tspp_info.tsif[i].buff_index * size));
+
+	*phys_base =
+		(mpq_dmx_tspp_info.tsif[i].ch_mem_heap_phys_base +
+		(mpq_dmx_tspp_info.tsif[i].buff_index * size));
+
+	mpq_dmx_tspp_info.tsif[i].buff_index++;
+
+	return virt_addr;
+}
+
+static void tspp_mem_free(int channel_id, u32 size,
+			void *virt_base, u32 phys_base, void *user)
+{
+	int i = TSPP_GET_TSIF_NUM(channel_id);
+
+	/*
+	 * actual buffer heap free is done in mpq_dmx_tspp_plugin_exit().
+	 * we update index here, so if this function is called repetitively
+	 * for all the buffers, then afterwards tspp_mem_allocator()
+	 * can be called again.
+	 * Note: it would be incorrect to call tspp_mem_allocator()
+	 * a few times, then call tspp_mem_free(), then call
+	 * tspp_mem_allocator() again.
+	 */
+	if (mpq_dmx_tspp_info.tsif[i].buff_index > 0)
+		mpq_dmx_tspp_info.tsif[i].buff_index--;
+}
+
+/**
+ * Returns a free HW filter index that can be used.
+ *
+ * @tsif: The TSIF to allocate filter from
+ *
+ * Return  HW filter index or -ENOMEM if no filters available
+ */
+static int mpq_tspp_allocate_hw_filter_index(int tsif)
+{
+	int i;
+
+	for (i = 0; i < TSPP_MAX_HW_PID_FILTER_NUM; i++) {
+		if (mpq_dmx_tspp_info.tsif[tsif].hw_indexes[i] == 0) {
+			mpq_dmx_tspp_info.tsif[tsif].hw_indexes[i] = 1;
+			return i;
+		}
+	}
+
+	return -ENOMEM;
+}
+
+/**
+ * Releases a HW filter index for future reuse.
+ *
+ * @tsif: The TSIF from which the filter should be released
+ * @hw_index: The HW index to release
+ *
+ */
+static inline void mpq_tspp_release_hw_filter_index(int tsif, int hw_index)
+{
+	if ((hw_index >= 0) && (hw_index < TSPP_MAX_HW_PID_FILTER_NUM))
+		mpq_dmx_tspp_info.tsif[tsif].hw_indexes[hw_index] = 0;
+}
+
+
+/**
+ * Returns a free filter slot that can be used.
+ *
+ * @tsif: The TSIF to allocate filter from
+ *
+ * Return  filter index or -ENOMEM if no filters available
+ */
+static int mpq_tspp_get_free_filter_slot(int tsif)
+{
+	int slot;
+
+	for (slot = 0; slot < TSPP_MAX_PID_FILTER_NUM; slot++)
+		if (mpq_dmx_tspp_info.tsif[tsif].filters[slot].pid == -1)
+			return slot;
+
+	return -ENOMEM;
+}
+
+/**
+ * Returns filter index of specific pid.
+ *
+ * @tsif: The TSIF to which the pid is allocated
+ * @pid: The pid to search for
+ *
+ * Return  filter index or -1 if no filter available
+ */
+static int mpq_tspp_get_filter_slot(int tsif, int pid)
+{
+	int slot;
+
+	for (slot = 0; slot < TSPP_MAX_PID_FILTER_NUM; slot++)
+		if (mpq_dmx_tspp_info.tsif[tsif].filters[slot].pid == pid)
+			return slot;
+
+	return -EINVAL;
+}
+
+/**
+ * Demux TS packets from TSPP by secure-demux.
+ * The fucntion assumes the buffer is physically contiguous
+ * and that TSPP descriptors are continuous in memory.
+ *
+ * @tsif: The TSIF interface to process its packets
+ * @channel_id: the TSPP output pipe with the TS packets
+ */
+static void mpq_dmx_tspp_aggregated_process(int tsif, int channel_id)
+{
+	const struct tspp_data_descriptor *tspp_data_desc;
+	struct mpq_demux *mpq_demux = mpq_dmx_tspp_info.tsif[tsif].mpq_demux;
+	struct sdmx_buff_descr input;
+	size_t aggregate_len = 0;
+	size_t aggregate_count = 0;
+	phys_addr_t buff_start_addr;
+	phys_addr_t buff_current_addr = 0;
+	int i;
+
+	while ((tspp_data_desc = tspp_get_buffer(0, channel_id)) != NULL) {
+		if (0 == aggregate_count)
+			buff_current_addr = tspp_data_desc->phys_base;
+		mpq_dmx_tspp_info.tsif[tsif].aggregate_ids[aggregate_count] =
+			tspp_data_desc->id;
+		aggregate_len += tspp_data_desc->size;
+		aggregate_count++;
+		mpq_demux->hw_notification_size +=
+			tspp_data_desc->size / TSPP_RAW_TTS_SIZE;
+	}
+
+	if (!aggregate_count)
+		return;
+
+	buff_start_addr = mpq_dmx_tspp_info.tsif[tsif].ch_mem_heap_phys_base;
+	input.base_addr = (void *)buff_start_addr;
+	input.size = mpq_dmx_tspp_info.tsif[tsif].buffer_count *
+		TSPP_DESCRIPTOR_SIZE;
+
+	MPQ_DVB_DBG_PRINT(
+		"%s: Processing %d descriptors: %d bytes at start address 0x%x, read offset %d\n",
+		__func__, aggregate_count, aggregate_len,
+		(unsigned int)input.base_addr,
+		buff_current_addr - buff_start_addr);
+
+	mpq_sdmx_process(mpq_demux, &input, aggregate_len,
+		 buff_current_addr - buff_start_addr);
+
+	for (i = 0; i < aggregate_count; i++)
+		tspp_release_buffer(0, channel_id,
+			mpq_dmx_tspp_info.tsif[tsif].aggregate_ids[i]);
+}
+
+
+/**
+ * Demux thread function handling data from specific TSIF.
+ *
+ * @arg: TSIF number
+ */
+static int mpq_dmx_tspp_thread(void *arg)
+{
+	int tsif = (int)arg;
+	struct mpq_demux *mpq_demux;
+	const struct tspp_data_descriptor *tspp_data_desc;
+	atomic_t *data_cnt;
+	u32 notif_size;
+	int channel_id;
+	int ref_count;
+	int ret;
+	int j;
+
+	do {
+		ret = wait_event_interruptible(
+			mpq_dmx_tspp_info.tsif[tsif].wait_queue,
+			atomic_read(&mpq_dmx_tspp_info.tsif[tsif].data_cnt) ||
+			kthread_should_stop());
+
+		if ((ret < 0) || kthread_should_stop()) {
+			MPQ_DVB_ERR_PRINT("%s: exit\n", __func__);
+			break;
+		}
+
+		/* Lock against the TSPP filters data-structure */
+		if (mutex_lock_interruptible(
+			&mpq_dmx_tspp_info.tsif[tsif].mutex))
+			return -ERESTARTSYS;
+
+		channel_id = TSPP_CHANNEL_ID(tsif, TSPP_CHANNEL);
+
+		ref_count = mpq_dmx_tspp_info.tsif[tsif].channel_ref;
+		data_cnt = &mpq_dmx_tspp_info.tsif[tsif].data_cnt;
+
+		/* Make sure channel is still active */
+		if (ref_count == 0) {
+			mutex_unlock(&mpq_dmx_tspp_info.tsif[tsif].mutex);
+			continue;
+		}
+
+		atomic_dec(data_cnt);
+
+		mpq_demux = mpq_dmx_tspp_info.tsif[tsif].mpq_demux;
+		mpq_demux->hw_notification_size = 0;
+
+		if (MPQ_DMX_TSPP_CONTIGUOUS_PHYS_ALLOC != allocation_mode &&
+			mpq_sdmx_is_loaded())
+			pr_err_once(
+				"%s: TSPP Allocation mode does not support secure demux.\n",
+				__func__);
+
+		if (MPQ_DMX_TSPP_CONTIGUOUS_PHYS_ALLOC == allocation_mode &&
+			mpq_sdmx_is_loaded()) {
+			mpq_dmx_tspp_aggregated_process(tsif, channel_id);
+		} else {
+			/*
+			 * Go through all filled descriptors
+			 * and perform demuxing on them
+			 */
+			while ((tspp_data_desc = tspp_get_buffer(0, channel_id))
+					!= NULL) {
+				notif_size = tspp_data_desc->size /
+					TSPP_RAW_TTS_SIZE;
+				mpq_demux->hw_notification_size += notif_size;
+
+				for (j = 0; j < notif_size; j++)
+					dvb_dmx_swfilter_packet(
+					 &mpq_demux->demux,
+					 ((u8 *)tspp_data_desc->virt_base) +
+					 j * TSPP_RAW_TTS_SIZE,
+					 ((u8 *)tspp_data_desc->virt_base) +
+					 j * TSPP_RAW_TTS_SIZE + TSPP_RAW_SIZE);
+				/*
+				 * Notify TSPP that the buffer
+				 * is no longer needed
+				 */
+				tspp_release_buffer(0, channel_id,
+					tspp_data_desc->id);
+			}
+		}
+
+		if (mpq_demux->hw_notification_size &&
+			(mpq_demux->hw_notification_size <
+			mpq_demux->hw_notification_min_size))
+			mpq_demux->hw_notification_min_size =
+				mpq_demux->hw_notification_size;
+
+		mutex_unlock(&mpq_dmx_tspp_info.tsif[tsif].mutex);
+	} while (1);
+
+	return 0;
+}
+
+/**
+ * Callback function from TSPP when new data is ready.
+ *
+ * @channel_id: Channel with new TS packets
+ * @user: user-data holding TSIF number
+ */
+static void mpq_tspp_callback(int channel_id, void *user)
+{
+	int tsif = (int)user;
+	struct mpq_demux *mpq_demux;
+
+	/* Save statistics on TSPP notifications */
+	mpq_demux = mpq_dmx_tspp_info.tsif[tsif].mpq_demux;
+	mpq_dmx_update_hw_statistics(mpq_demux);
+
+	atomic_inc(&mpq_dmx_tspp_info.tsif[tsif].data_cnt);
+	wake_up(&mpq_dmx_tspp_info.tsif[tsif].wait_queue);
+}
+
+/**
+ * Free memory of channel output of specific TSIF.
+ *
+ * @tsif: The TSIF id to which memory should be freed.
+ */
+static void mpq_dmx_channel_mem_free(int tsif)
+{
+	MPQ_DVB_DBG_PRINT("%s(%d)\n", __func__, tsif);
+
+	mpq_dmx_tspp_info.tsif[tsif].ch_mem_heap_phys_base = 0;
+
+	if (!IS_ERR_OR_NULL(mpq_dmx_tspp_info.tsif[tsif].ch_mem_heap_handle)) {
+		if (!IS_ERR_OR_NULL(mpq_dmx_tspp_info.tsif[tsif].
+				ch_mem_heap_virt_base))
+			ion_unmap_kernel(mpq_dmx_tspp_info.ion_client,
+				mpq_dmx_tspp_info.tsif[tsif].
+					ch_mem_heap_handle);
+
+		ion_free(mpq_dmx_tspp_info.ion_client,
+			mpq_dmx_tspp_info.tsif[tsif].ch_mem_heap_handle);
+	}
+
+	mpq_dmx_tspp_info.tsif[tsif].ch_mem_heap_virt_base = NULL;
+	mpq_dmx_tspp_info.tsif[tsif].ch_mem_heap_handle = NULL;
+}
+
+/**
+ * Allocate memory for channel output of specific TSIF.
+ *
+ * @tsif: The TSIF id to which memory should be allocated.
+ *
+ * Return  error status
+ */
+static int mpq_dmx_channel_mem_alloc(int tsif)
+{
+	int result;
+	size_t len;
+
+	MPQ_DVB_DBG_PRINT("%s(%d)\n", __func__, tsif);
+
+	mpq_dmx_tspp_info.tsif[tsif].ch_mem_heap_handle =
+		ion_alloc(mpq_dmx_tspp_info.ion_client,
+		 (mpq_dmx_tspp_info.tsif[tsif].buffer_count *
+		  TSPP_DESCRIPTOR_SIZE),
+		 SZ_4K,
+		 ION_HEAP(tspp_out_ion_heap),
+		 0); /* non-cached */
+
+	if (IS_ERR_OR_NULL(mpq_dmx_tspp_info.tsif[tsif].ch_mem_heap_handle)) {
+		MPQ_DVB_ERR_PRINT("%s: ion_alloc() failed\n", __func__);
+		mpq_dmx_channel_mem_free(tsif);
+		return -ENOMEM;
+	}
+
+	/* save virtual base address of heap */
+	mpq_dmx_tspp_info.tsif[tsif].ch_mem_heap_virt_base =
+		ion_map_kernel(mpq_dmx_tspp_info.ion_client,
+			mpq_dmx_tspp_info.tsif[tsif].ch_mem_heap_handle);
+	if (IS_ERR_OR_NULL(mpq_dmx_tspp_info.tsif[tsif].
+				ch_mem_heap_virt_base)) {
+		MPQ_DVB_ERR_PRINT("%s: ion_map_kernel() failed\n", __func__);
+		mpq_dmx_channel_mem_free(tsif);
+		return -ENOMEM;
+	}
+
+	/* save physical base address of heap */
+	result = ion_phys(mpq_dmx_tspp_info.ion_client,
+		mpq_dmx_tspp_info.tsif[tsif].ch_mem_heap_handle,
+		&(mpq_dmx_tspp_info.tsif[tsif].ch_mem_heap_phys_base), &len);
+	if (result < 0) {
+		MPQ_DVB_ERR_PRINT("%s: ion_phys() failed\n", __func__);
+		mpq_dmx_channel_mem_free(tsif);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+/**
+ * Add a filter to accept all packets as the last entry
+ * of the TSPP HW filter table.
+ *
+ * @channel_id: Channel ID number.
+ * @source: TSPP source.
+ *
+ * Return  error status
+ */
+static int mpq_tspp_add_accept_all_filter(int channel_id,
+				enum tspp_source source)
+{
+	struct tspp_filter tspp_filter;
+	int tsif = TSPP_GET_TSIF_NUM(channel_id);
+	int ret;
+
+	MPQ_DVB_DBG_PRINT("%s: executed, channel id = %d, source = %d\n",
+		__func__, channel_id, source);
+
+	if (mpq_dmx_tspp_info.tsif[tsif].accept_all_filter_exists_flag) {
+		MPQ_DVB_DBG_PRINT("%s: accept all filter already exists\n",
+				__func__);
+		return 0;
+	}
+
+	/* This filter will be the last entry in the table */
+	tspp_filter.priority = TSPP_LAST_HW_FILTER_INDEX;
+	/* Pass all pids - set mask to 0 */
+	tspp_filter.pid = 0;
+	tspp_filter.mask = 0;
+	/*
+	 * Include TTS in RAW packets, if you change this to
+	 * TSPP_MODE_RAW_NO_SUFFIX you must also change TSPP_RAW_TTS_SIZE
+	 * accordingly.
+	 */
+	tspp_filter.mode = TSPP_MODE_RAW;
+	tspp_filter.source = source;
+	tspp_filter.decrypt = 0;
+
+	ret = tspp_add_filter(0, channel_id, &tspp_filter);
+	if (!ret) {
+		mpq_dmx_tspp_info.tsif[tsif].accept_all_filter_exists_flag = 1;
+		MPQ_DVB_DBG_PRINT(
+				"%s: accept all filter added successfully\n",
+				__func__);
+	}
+
+	return ret;
+}
+
+/**
+ * Remove the filter that accepts all packets from the last entry
+ * of the TSPP HW filter table.
+ *
+ * @channel_id: Channel ID number.
+ * @source: TSPP source.
+ *
+ * Return  error status
+ */
+static int mpq_tspp_remove_accept_all_filter(int channel_id,
+				enum tspp_source source)
+{
+	struct tspp_filter tspp_filter;
+	int tsif = TSPP_GET_TSIF_NUM(channel_id);
+	int ret;
+
+	MPQ_DVB_DBG_PRINT("%s: executed, channel id = %d, source = %d\n",
+		__func__, channel_id, source);
+
+	if (mpq_dmx_tspp_info.tsif[tsif].accept_all_filter_exists_flag == 0) {
+		MPQ_DVB_DBG_PRINT("%s: accept all filter doesn't exist\n",
+				__func__);
+		return 0;
+	}
+
+	tspp_filter.priority = TSPP_LAST_HW_FILTER_INDEX;
+
+	ret = tspp_remove_filter(0, channel_id, &tspp_filter);
+	if (!ret) {
+		mpq_dmx_tspp_info.tsif[tsif].accept_all_filter_exists_flag = 0;
+		MPQ_DVB_DBG_PRINT(
+			"%s: accept all filter removed successfully\n",
+			__func__);
+	}
+
+	return ret;
+}
+
+/**
+ * Add filters designed to accept all packets except NULL packets, i.e.
+ * packets with PID = 0x1FFF.
+ * This function is called after user-defined filters were removed,
+ * so it assumes that the first 13 HW filters in the TSPP filter
+ * table are free for use.
+ *
+ * @channel_id: Channel ID number.
+ * @source: TSPP source.
+ *
+ * Return  0 on success, -1 otherwise
+ */
+static int mpq_tspp_add_null_blocking_filters(int channel_id,
+				enum tspp_source source)
+{
+	struct tspp_filter tspp_filter;
+	int ret = 0;
+	int i, j;
+	u16 full_pid_mask = 0x1FFF;
+	u8 mask_shift;
+	u8 pid_shift;
+	int tsif = TSPP_GET_TSIF_NUM(channel_id);
+
+	MPQ_DVB_DBG_PRINT("%s: executed, channel id = %d, source = %d\n",
+		__func__, channel_id, source);
+
+	/*
+	 * Add a total of 13 filters that will accept packets with
+	 * every PID other than 0x1FFF, which is the NULL PID.
+	 *
+	 * Filter 0: accept all PIDs with bit 12 clear, i.e.
+	 * PID = 0x0000 .. 0x0FFF (4096 PIDs in total):
+	 * Mask = 0x1000, PID = 0x0000.
+	 *
+	 * Filter 12: Accept PID 0x1FFE:
+	 * Mask = 0x1FFF, PID = 0x1FFE.
+	 *
+	 * In general: For N = 0 .. 12,
+	 * Filter <N>: accept all PIDs with <N> MSBits set and bit <N-1> clear.
+	 * Filter <N> Mask = N+1 MSBits set, others clear.
+	 * Filter <N> PID = <N> MSBits set, others clear.
+	 */
+
+	/*
+	 * Include TTS in RAW packets, if you change this to
+	 * TSPP_MODE_RAW_NO_SUFFIX you must also change TSPP_RAW_TTS_SIZE
+	 * accordingly.
+	 */
+	tspp_filter.mode = TSPP_MODE_RAW;
+	tspp_filter.source = source;
+	tspp_filter.decrypt = 0;
+
+	for (i = 0; i < TSPP_BLOCK_NULLS_FILTERS_NUM; i++) {
+		tspp_filter.priority = mpq_tspp_allocate_hw_filter_index(tsif);
+		if (tspp_filter.priority != i) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: got unexpected HW index %d, expected %d\n",
+				__func__, tspp_filter.priority, i);
+			ret = -1;
+			break;
+		}
+		mask_shift = (TSPP_BLOCK_NULLS_FILTERS_NUM - 1 - i);
+		pid_shift = (TSPP_BLOCK_NULLS_FILTERS_NUM - i);
+		tspp_filter.mask =
+			((full_pid_mask >> mask_shift) << mask_shift);
+		tspp_filter.pid = ((full_pid_mask >> pid_shift) << pid_shift);
+
+		if (tspp_add_filter(0, channel_id, &tspp_filter)) {
+			ret = -1;
+			break;
+		}
+	}
+
+	if (ret) {
+		/* cleanup on failure */
+		for (j = 0; j < i; j++) {
+			tspp_filter.priority = j;
+			mpq_tspp_release_hw_filter_index(tsif, j);
+			tspp_remove_filter(0, channel_id, &tspp_filter);
+		}
+	} else {
+		MPQ_DVB_DBG_PRINT(
+			"%s: NULL blocking filters added successfully\n",
+			__func__);
+	}
+
+	return ret;
+}
+
+/**
+ * Remove filters designed to accept all packets except NULL packets, i.e.
+ * packets with PID = 0x1FFF.
+ *
+ * @channel_id: Channel ID number.
+ *
+ * @source: TSPP source.
+ *
+ * Return  0 on success, -1 otherwise
+ */
+static int mpq_tspp_remove_null_blocking_filters(int channel_id,
+				enum tspp_source source)
+{
+	struct tspp_filter tspp_filter;
+	int tsif = TSPP_GET_TSIF_NUM(channel_id);
+	int ret = 0;
+	int i;
+
+	MPQ_DVB_DBG_PRINT("%s: executed, channel id = %d, source = %d\n",
+		__func__, channel_id, source);
+
+	for (i = 0; i < TSPP_BLOCK_NULLS_FILTERS_NUM; i++) {
+		tspp_filter.priority = i;
+		if (tspp_remove_filter(0, channel_id, &tspp_filter)) {
+			MPQ_DVB_ERR_PRINT("%s: failed to remove filter %d\n",
+				__func__, i);
+			ret = -1;
+		}
+
+		mpq_tspp_release_hw_filter_index(tsif, i);
+	}
+
+	return ret;
+}
+
+/**
+ * Add all current user-defined filters (up to 15) as HW filters
+ *
+ * @channel_id: Channel ID number.
+ *
+ * @source: TSPP source.
+ *
+ * Return  0 on success, -1 otherwise
+ */
+static int mpq_tspp_add_all_user_filters(int channel_id,
+				enum tspp_source source)
+{
+	struct tspp_filter tspp_filter;
+	int tsif = TSPP_GET_TSIF_NUM(channel_id);
+	int slot;
+	u16 added_count = 0;
+	u16 total_filters_count = 0;
+
+	MPQ_DVB_DBG_PRINT("%s: executed\n", __func__);
+
+	/*
+	 * Include TTS in RAW packets, if you change this to
+	 * TSPP_MODE_RAW_NO_SUFFIX you must also change TSPP_RAW_TTS_SIZE
+	 * accordingly.
+	 */
+	tspp_filter.mode = TSPP_MODE_RAW;
+	tspp_filter.source = source;
+	tspp_filter.decrypt = 0;
+
+	for (slot = 0; slot < TSPP_MAX_PID_FILTER_NUM; slot++) {
+		if (mpq_dmx_tspp_info.tsif[tsif].filters[slot].pid == -1)
+			continue;
+
+		/*
+		 * count total number of user filters to verify that it is
+		 * exactly TSPP_MAX_HW_PID_FILTER_NUM as expected.
+		 */
+		total_filters_count++;
+
+		if (added_count > TSPP_MAX_HW_PID_FILTER_NUM)
+			continue;
+
+		tspp_filter.priority = mpq_tspp_allocate_hw_filter_index(tsif);
+
+		if (mpq_dmx_tspp_info.tsif[tsif].filters[slot].pid ==
+				TSPP_PASS_THROUGH_PID) {
+			/* pass all pids */
+			tspp_filter.pid = 0;
+			tspp_filter.mask = 0;
+		} else {
+			tspp_filter.pid =
+				mpq_dmx_tspp_info.tsif[tsif].filters[slot].pid;
+			tspp_filter.mask = TSPP_PID_MASK;
+		}
+
+		MPQ_DVB_DBG_PRINT(
+			"%s: adding HW filter, PID = %d, mask = 0x%X, index = %d\n",
+				__func__, tspp_filter.pid, tspp_filter.mask,
+				tspp_filter.priority);
+
+		if (!tspp_add_filter(0, channel_id, &tspp_filter)) {
+			mpq_dmx_tspp_info.tsif[tsif].filters[slot].hw_index =
+				tspp_filter.priority;
+			added_count++;
+		} else {
+			MPQ_DVB_ERR_PRINT("%s: tspp_add_filter failed\n",
+						__func__);
+		}
+	}
+
+	if ((added_count != TSPP_MAX_HW_PID_FILTER_NUM) ||
+		(added_count != total_filters_count))
+		return -EINVAL;
+
+	return 0;
+}
+
+/**
+ * Remove all user-defined HW filters
+ *
+ * @channel_id: Channel ID number.
+ *
+ * @source: TSPP source.
+ *
+ * Return  0 on success, -1 otherwise
+ */
+static int mpq_tspp_remove_all_user_filters(int channel_id,
+				enum tspp_source source)
+{
+	struct tspp_filter tspp_filter;
+	int ret = 0;
+	int tsif = TSPP_GET_TSIF_NUM(channel_id);
+	int i;
+
+	MPQ_DVB_DBG_PRINT("%s: executed\n", __func__);
+
+	for (i = 0; i < TSPP_MAX_HW_PID_FILTER_NUM; i++) {
+		tspp_filter.priority = i;
+		MPQ_DVB_DBG_PRINT("%s: Removing HW filter %d\n",
+			__func__, tspp_filter.priority);
+		if (tspp_remove_filter(0, channel_id, &tspp_filter))
+			ret = -1;
+
+		mpq_tspp_release_hw_filter_index(tsif, i);
+		mpq_dmx_tspp_info.tsif[tsif].filters[i].hw_index = -1;
+	}
+
+	return ret;
+}
+
+/**
+ * Configure TSPP channel to filter the PID of new feed.
+ *
+ * @feed: The feed to configure the channel with
+ *
+ * Return  error status
+ *
+ * The function checks if the new PID can be added to an already
+ * allocated channel, if not, a new channel is allocated and configured.
+ */
+static int mpq_tspp_dmx_add_channel(struct dvb_demux_feed *feed)
+{
+	struct mpq_demux *mpq_demux = feed->demux->priv;
+	struct tspp_select_source tspp_source;
+	struct tspp_filter tspp_filter;
+	int tsif;
+	int ret = 0;
+	int slot;
+	int channel_id;
+	int *channel_ref_count;
+	u32 buffer_size;
+	int restore_user_filters = 0;
+	int remove_accept_all_filter = 0;
+	int remove_null_blocking_filters = 0;
+
+	tspp_source.clk_inverse = clock_inv;
+	tspp_source.data_inverse = 0;
+	tspp_source.sync_inverse = 0;
+	tspp_source.enable_inverse = 0;
+
+	MPQ_DVB_DBG_PRINT("%s: executed, PID = %d\n", __func__, feed->pid);
+
+	switch (tsif_mode) {
+	case 1:
+		tspp_source.mode = TSPP_TSIF_MODE_1;
+		break;
+	case 2:
+		tspp_source.mode = TSPP_TSIF_MODE_2;
+		break;
+	default:
+		tspp_source.mode = TSPP_TSIF_MODE_LOOPBACK;
+		break;
+	}
+
+	/* determine the TSIF we are reading from */
+	if (mpq_demux->source == DMX_SOURCE_FRONT0) {
+		tsif = 0;
+		tspp_source.source = TSPP_SOURCE_TSIF0;
+	} else if (mpq_demux->source == DMX_SOURCE_FRONT1) {
+		tsif = 1;
+		tspp_source.source = TSPP_SOURCE_TSIF1;
+	} else {
+		/* invalid source */
+		MPQ_DVB_ERR_PRINT(
+			"%s: invalid input source (%d)\n",
+			__func__,
+			mpq_demux->source);
+
+		return -EINVAL;
+	}
+
+	if (mutex_lock_interruptible(&mpq_dmx_tspp_info.tsif[tsif].mutex))
+		return -ERESTARTSYS;
+
+	/*
+	 * It is possible that this PID was already requested before.
+	 * Can happen if we play and record same PES or PCR
+	 * piggypacked on video packet.
+	 */
+	slot = mpq_tspp_get_filter_slot(tsif, feed->pid);
+	if (slot >= 0) {
+		/* PID already configured */
+		mpq_dmx_tspp_info.tsif[tsif].filters[slot].ref_count++;
+		mutex_unlock(&mpq_dmx_tspp_info.tsif[tsif].mutex);
+		return 0;
+	}
+
+	channel_id = TSPP_CHANNEL_ID(tsif, TSPP_CHANNEL);
+	channel_ref_count = &mpq_dmx_tspp_info.tsif[tsif].channel_ref;
+	buffer_size = TSPP_DESCRIPTOR_SIZE;
+
+	/* check if required TSPP pipe is already allocated or not */
+	if (*channel_ref_count == 0) {
+		if (allocation_mode == MPQ_DMX_TSPP_CONTIGUOUS_PHYS_ALLOC) {
+			ret = mpq_dmx_channel_mem_alloc(tsif);
+			if (ret < 0) {
+				MPQ_DVB_ERR_PRINT(
+					"%s: mpq_dmx_channel_mem_alloc(%d) failed (%d)\n",
+					__func__,
+					channel_id,
+					ret);
+
+				goto add_channel_failed;
+			}
+		}
+
+		ret = tspp_open_channel(0, channel_id);
+		if (ret < 0) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: tspp_open_channel(%d) failed (%d)\n",
+				__func__,
+				channel_id,
+				ret);
+
+			goto add_channel_failed;
+		}
+
+		/* set TSPP source */
+		ret = tspp_open_stream(0, channel_id, &tspp_source);
+		if (ret < 0) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: tspp_select_source(%d,%d) failed (%d)\n",
+				__func__,
+				channel_id,
+				tspp_source.source,
+				ret);
+
+			goto add_channel_close_ch;
+		}
+
+		/* register notification on TS packets */
+		tspp_register_notification(0,
+					   channel_id,
+					   mpq_tspp_callback,
+					   (void *)tsif,
+					   tspp_channel_timeout);
+
+		/* register allocator and provide allocation function
+		 * that allocates from contiguous memory so that we can have
+		 * big notification size, smallest descriptor, and still provide
+		 * TZ with single big buffer based on notification size.
+		 */
+		if (allocation_mode == MPQ_DMX_TSPP_CONTIGUOUS_PHYS_ALLOC) {
+			ret = tspp_allocate_buffers(0, channel_id,
+				   mpq_dmx_tspp_info.tsif[tsif].buffer_count,
+				   buffer_size, tspp_notification_size,
+				   tspp_mem_allocator, tspp_mem_free, NULL);
+		} else {
+			ret = tspp_allocate_buffers(0, channel_id,
+				   mpq_dmx_tspp_info.tsif[tsif].buffer_count,
+				   buffer_size, tspp_notification_size,
+				   NULL, NULL, NULL);
+		}
+		if (ret < 0) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: tspp_allocate_buffers(%d) failed (%d)\n",
+				__func__,
+				channel_id,
+				ret);
+
+			goto add_channel_unregister_notif;
+		}
+
+		mpq_dmx_tspp_info.tsif[tsif].mpq_demux = mpq_demux;
+	}
+
+	/* add new PID to the existing pipe */
+	slot = mpq_tspp_get_free_filter_slot(tsif);
+	if (slot < 0) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: mpq_tspp_get_free_filter_slot(%d) failed\n",
+			__func__, tsif);
+
+		goto add_channel_unregister_notif;
+	}
+
+	if (feed->pid == TSPP_PASS_THROUGH_PID)
+		mpq_dmx_tspp_info.tsif[tsif].pass_all_flag = 1;
+	else if (feed->pid == TSPP_NULL_PACKETS_PID)
+		mpq_dmx_tspp_info.tsif[tsif].pass_nulls_flag = 1;
+
+	mpq_dmx_tspp_info.tsif[tsif].filters[slot].pid = feed->pid;
+	mpq_dmx_tspp_info.tsif[tsif].filters[slot].ref_count++;
+
+	tspp_filter.priority = -1;
+
+	if (mpq_dmx_tspp_info.tsif[tsif].current_filter_count <
+					TSPP_MAX_HW_PID_FILTER_NUM) {
+		/* HW filtering mode */
+		tspp_filter.priority = mpq_tspp_allocate_hw_filter_index(tsif);
+		if (tspp_filter.priority < 0)
+			goto add_channel_free_filter_slot;
+
+		if (feed->pid == TSPP_PASS_THROUGH_PID) {
+			/* pass all pids */
+			tspp_filter.pid = 0;
+			tspp_filter.mask = 0;
+		} else {
+			tspp_filter.pid = feed->pid;
+			tspp_filter.mask = TSPP_PID_MASK;
+		}
+
+		/*
+		 * Include TTS in RAW packets, if you change this to
+		 * TSPP_MODE_RAW_NO_SUFFIX you must also change
+		 * TSPP_RAW_TTS_SIZE accordingly.
+		 */
+		tspp_filter.mode = TSPP_MODE_RAW;
+		tspp_filter.source = tspp_source.source;
+		tspp_filter.decrypt = 0;
+		ret = tspp_add_filter(0, channel_id, &tspp_filter);
+		if (ret < 0) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: tspp_add_filter(%d) failed (%d)\n",
+				__func__,
+				channel_id,
+				ret);
+
+			goto add_channel_free_filter_slot;
+		}
+		mpq_dmx_tspp_info.tsif[tsif].filters[slot].hw_index =
+			tspp_filter.priority;
+
+		MPQ_DVB_DBG_PRINT(
+			"%s: HW filtering mode: added TSPP HW filter, PID = %d, mask = 0x%X, index = %d\n",
+			__func__, tspp_filter.pid, tspp_filter.mask,
+			tspp_filter.priority);
+	} else if (mpq_dmx_tspp_info.tsif[tsif].current_filter_count ==
+					TSPP_MAX_HW_PID_FILTER_NUM) {
+		/* Crossing the threshold - from HW to SW filtering mode */
+
+		/* Add a temporary filter to accept all packets */
+		ret = mpq_tspp_add_accept_all_filter(channel_id,
+					tspp_source.source);
+		if (ret < 0) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: mpq_tspp_add_accept_all_filter(%d, %d) failed\n",
+				__func__, channel_id, tspp_source.source);
+
+			goto add_channel_free_filter_slot;
+		}
+
+		/* Remove all existing user filters */
+		ret = mpq_tspp_remove_all_user_filters(channel_id,
+					tspp_source.source);
+		if (ret < 0) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: mpq_tspp_remove_all_user_filters(%d, %d) failed\n",
+				__func__, channel_id, tspp_source.source);
+
+			restore_user_filters = 1;
+			remove_accept_all_filter = 1;
+
+			goto add_channel_free_filter_slot;
+		}
+
+		/* Add HW filters to block NULL packets */
+		ret = mpq_tspp_add_null_blocking_filters(channel_id,
+					tspp_source.source);
+		if (ret < 0) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: mpq_tspp_add_null_blocking_filters(%d, %d) failed\n",
+				__func__, channel_id, tspp_source.source);
+
+			restore_user_filters = 1;
+			remove_accept_all_filter = 1;
+
+			goto add_channel_free_filter_slot;
+		}
+
+		/* Remove filters that accepts all packets, if necessary */
+		if ((mpq_dmx_tspp_info.tsif[tsif].pass_all_flag == 0) &&
+			(mpq_dmx_tspp_info.tsif[tsif].pass_nulls_flag == 0)) {
+
+			ret = mpq_tspp_remove_accept_all_filter(channel_id,
+						tspp_source.source);
+			if (ret < 0) {
+				MPQ_DVB_ERR_PRINT(
+					"%s: mpq_tspp_remove_accept_all_filter(%d, %d) failed\n",
+					__func__, channel_id,
+					tspp_source.source);
+
+				remove_null_blocking_filters = 1;
+				restore_user_filters = 1;
+				remove_accept_all_filter = 1;
+
+				goto add_channel_free_filter_slot;
+			}
+		}
+	} else {
+		/* Already working in SW filtering mode */
+		if (mpq_dmx_tspp_info.tsif[tsif].pass_all_flag ||
+			mpq_dmx_tspp_info.tsif[tsif].pass_nulls_flag) {
+
+			ret = mpq_tspp_add_accept_all_filter(channel_id,
+						tspp_source.source);
+			if (ret < 0) {
+				MPQ_DVB_ERR_PRINT(
+					"%s: mpq_tspp_add_accept_all_filter(%d, %d) failed\n",
+					__func__, channel_id,
+					tspp_source.source);
+
+				goto add_channel_free_filter_slot;
+			}
+		}
+	}
+
+	(*channel_ref_count)++;
+	mpq_dmx_tspp_info.tsif[tsif].current_filter_count++;
+
+	MPQ_DVB_DBG_PRINT("%s: success, current_filter_count = %d\n",
+		__func__, mpq_dmx_tspp_info.tsif[tsif].current_filter_count);
+
+	mutex_unlock(&mpq_dmx_tspp_info.tsif[tsif].mutex);
+	return 0;
+
+add_channel_free_filter_slot:
+	/* restore internal database state */
+	mpq_dmx_tspp_info.tsif[tsif].filters[slot].pid = -1;
+	mpq_dmx_tspp_info.tsif[tsif].filters[slot].ref_count--;
+
+	/* release HW index if we allocated one */
+	if (tspp_filter.priority >= 0) {
+		mpq_dmx_tspp_info.tsif[tsif].filters[slot].hw_index = -1;
+		mpq_tspp_release_hw_filter_index(tsif, tspp_filter.priority);
+	}
+
+	/* restore HW filter table state if necessary */
+	if (remove_null_blocking_filters)
+		mpq_tspp_remove_null_blocking_filters(channel_id,
+						tspp_source.source);
+
+	if (restore_user_filters)
+		mpq_tspp_add_all_user_filters(channel_id, tspp_source.source);
+
+	if (remove_accept_all_filter)
+		mpq_tspp_remove_accept_all_filter(channel_id,
+						tspp_source.source);
+
+	/* restore flags. we can only get here if we changed the flags. */
+	if (feed->pid == TSPP_PASS_THROUGH_PID)
+		mpq_dmx_tspp_info.tsif[tsif].pass_all_flag = 0;
+	else if (feed->pid == TSPP_NULL_PACKETS_PID)
+		mpq_dmx_tspp_info.tsif[tsif].pass_nulls_flag = 0;
+
+add_channel_unregister_notif:
+	if (*channel_ref_count == 0) {
+		tspp_unregister_notification(0, channel_id);
+		tspp_close_stream(0, channel_id);
+	}
+add_channel_close_ch:
+	if (*channel_ref_count == 0)
+		tspp_close_channel(0, channel_id);
+add_channel_failed:
+	if (*channel_ref_count == 0)
+		if (allocation_mode == MPQ_DMX_TSPP_CONTIGUOUS_PHYS_ALLOC)
+			mpq_dmx_channel_mem_free(tsif);
+
+	mutex_unlock(&mpq_dmx_tspp_info.tsif[tsif].mutex);
+	return ret;
+}
+
+/**
+ * Removes filter from TSPP.
+ *
+ * @feed: The feed to remove
+ *
+ * Return  error status
+ *
+ * The function checks if this is the only PID allocated within
+ * the channel, if so, the channel is closed as well.
+ */
+static int mpq_tspp_dmx_remove_channel(struct dvb_demux_feed *feed)
+{
+	int tsif;
+	int ret;
+	int channel_id;
+	int slot;
+	atomic_t *data_cnt;
+	int *channel_ref_count;
+	enum tspp_source tspp_source;
+	struct tspp_filter tspp_filter;
+	struct mpq_demux *mpq_demux = feed->demux->priv;
+	int restore_null_blocking_filters = 0;
+	int remove_accept_all_filter = 0;
+	int remove_user_filters = 0;
+	int accept_all_filter_existed = 0;
+
+	MPQ_DVB_DBG_PRINT("%s: executed, PID = %d\n", __func__, feed->pid);
+
+	/* determine the TSIF we are reading from */
+	if (mpq_demux->source == DMX_SOURCE_FRONT0) {
+		tsif = 0;
+		tspp_source = TSPP_SOURCE_TSIF0;
+	} else if (mpq_demux->source == DMX_SOURCE_FRONT1) {
+		tsif = 1;
+		tspp_source = TSPP_SOURCE_TSIF1;
+	} else {
+		/* invalid source */
+		MPQ_DVB_ERR_PRINT(
+			"%s: invalid input source (%d)\n",
+			__func__,
+			mpq_demux->source);
+
+		return -EINVAL;
+	}
+
+	if (mutex_lock_interruptible(&mpq_dmx_tspp_info.tsif[tsif].mutex))
+		return -ERESTARTSYS;
+
+	channel_id = TSPP_CHANNEL_ID(tsif, TSPP_CHANNEL);
+	channel_ref_count = &mpq_dmx_tspp_info.tsif[tsif].channel_ref;
+	data_cnt = &mpq_dmx_tspp_info.tsif[tsif].data_cnt;
+
+	/* check if required TSPP pipe is already allocated or not */
+	if (*channel_ref_count == 0) {
+		/* invalid feed provided as the channel is not allocated */
+		MPQ_DVB_ERR_PRINT(
+			"%s: invalid feed (%d)\n",
+			__func__,
+			channel_id);
+
+		ret = -EINVAL;
+		goto remove_channel_failed;
+	}
+
+	slot = mpq_tspp_get_filter_slot(tsif, feed->pid);
+
+	if (slot < 0) {
+		/* invalid feed provided as it has no filter allocated */
+		MPQ_DVB_ERR_PRINT(
+			"%s: mpq_tspp_get_filter_slot failed (%d,%d)\n",
+			__func__,
+			feed->pid,
+			tsif);
+
+		ret = -EINVAL;
+		goto remove_channel_failed;
+	}
+
+	/* since filter was found, ref_count > 0 so it's ok to decrement it */
+	mpq_dmx_tspp_info.tsif[tsif].filters[slot].ref_count--;
+
+	if (mpq_dmx_tspp_info.tsif[tsif].filters[slot].ref_count) {
+		/*
+		 * there are still references to this pid, do not
+		 * remove the filter yet
+		 */
+		mutex_unlock(&mpq_dmx_tspp_info.tsif[tsif].mutex);
+		return 0;
+	}
+
+	if (feed->pid == TSPP_PASS_THROUGH_PID)
+		mpq_dmx_tspp_info.tsif[tsif].pass_all_flag = 0;
+	else if (feed->pid == TSPP_NULL_PACKETS_PID)
+		mpq_dmx_tspp_info.tsif[tsif].pass_nulls_flag = 0;
+
+	mpq_dmx_tspp_info.tsif[tsif].filters[slot].pid = -1;
+
+	if (mpq_dmx_tspp_info.tsif[tsif].current_filter_count <=
+					TSPP_MAX_HW_PID_FILTER_NUM) {
+		/* staying in HW filtering mode */
+		tspp_filter.priority =
+			mpq_dmx_tspp_info.tsif[tsif].filters[slot].hw_index;
+		ret = tspp_remove_filter(0, channel_id, &tspp_filter);
+		if (ret < 0) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: tspp_remove_filter failed (%d,%d)\n",
+				__func__,
+				channel_id,
+				tspp_filter.priority);
+
+			goto remove_channel_failed_restore_count;
+		}
+		mpq_tspp_release_hw_filter_index(tsif, tspp_filter.priority);
+		mpq_dmx_tspp_info.tsif[tsif].filters[slot].hw_index = -1;
+
+		MPQ_DVB_DBG_PRINT(
+			"%s: HW filtering mode: Removed TSPP HW filter, PID = %d, index = %d\n",
+			__func__, feed->pid, tspp_filter.priority);
+	} else  if (mpq_dmx_tspp_info.tsif[tsif].current_filter_count ==
+					(TSPP_MAX_HW_PID_FILTER_NUM + 1)) {
+		/* Crossing the threshold - from SW to HW filtering mode */
+
+		accept_all_filter_existed =
+			mpq_dmx_tspp_info.tsif[tsif].
+				accept_all_filter_exists_flag;
+
+		/* Add a temporary filter to accept all packets */
+		ret = mpq_tspp_add_accept_all_filter(channel_id,
+					tspp_source);
+		if (ret < 0) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: mpq_tspp_add_accept_all_filter(%d, %d) failed\n",
+				__func__, channel_id, tspp_source);
+
+			goto remove_channel_failed_restore_count;
+		}
+
+		ret = mpq_tspp_remove_null_blocking_filters(channel_id,
+					tspp_source);
+		if (ret < 0) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: mpq_tspp_remove_null_blocking_filters(%d, %d) failed\n",
+				__func__, channel_id, tspp_source);
+
+			restore_null_blocking_filters = 1;
+			if (!accept_all_filter_existed)
+				remove_accept_all_filter = 1;
+
+			goto remove_channel_failed_restore_count;
+		}
+
+		ret = mpq_tspp_add_all_user_filters(channel_id,
+					tspp_source);
+		if (ret < 0) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: mpq_tspp_add_all_user_filters(%d, %d) failed\n",
+				__func__, channel_id, tspp_source);
+
+			remove_user_filters = 1;
+			restore_null_blocking_filters = 1;
+			if (!accept_all_filter_existed)
+				remove_accept_all_filter = 1;
+
+			goto remove_channel_failed_restore_count;
+		}
+
+		ret = mpq_tspp_remove_accept_all_filter(channel_id,
+					tspp_source);
+		if (ret < 0) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: mpq_tspp_remove_accept_all_filter(%d, %d) failed\n",
+				__func__, channel_id, tspp_source);
+
+			remove_user_filters = 1;
+			restore_null_blocking_filters = 1;
+			if (!accept_all_filter_existed)
+				remove_accept_all_filter = 1;
+
+			goto remove_channel_failed_restore_count;
+		}
+	} else {
+		/* staying in SW filtering mode */
+		if ((mpq_dmx_tspp_info.tsif[tsif].pass_all_flag == 0) &&
+			(mpq_dmx_tspp_info.tsif[tsif].pass_nulls_flag == 0)) {
+
+			ret = mpq_tspp_remove_accept_all_filter(channel_id,
+						tspp_source);
+			if (ret < 0) {
+				MPQ_DVB_ERR_PRINT(
+					"%s: mpq_tspp_remove_accept_all_filter(%d, %d) failed\n",
+					__func__, channel_id,
+					tspp_source);
+
+				goto remove_channel_failed_restore_count;
+			}
+		}
+	}
+
+	mpq_dmx_tspp_info.tsif[tsif].current_filter_count--;
+	(*channel_ref_count)--;
+
+	MPQ_DVB_DBG_PRINT("%s: success, current_filter_count = %d\n",
+		__func__, mpq_dmx_tspp_info.tsif[tsif].current_filter_count);
+
+	if (*channel_ref_count == 0) {
+		/* channel is not used any more, release it */
+		tspp_unregister_notification(0, channel_id);
+		tspp_close_stream(0, channel_id);
+		tspp_close_channel(0, channel_id);
+		atomic_set(data_cnt, 0);
+
+		if (allocation_mode == MPQ_DMX_TSPP_CONTIGUOUS_PHYS_ALLOC)
+			mpq_dmx_channel_mem_free(tsif);
+	}
+
+	mutex_unlock(&mpq_dmx_tspp_info.tsif[tsif].mutex);
+	return 0;
+
+remove_channel_failed_restore_count:
+	/* restore internal database state */
+	mpq_dmx_tspp_info.tsif[tsif].filters[slot].pid = feed->pid;
+	mpq_dmx_tspp_info.tsif[tsif].filters[slot].ref_count++;
+
+	if (remove_user_filters)
+		mpq_tspp_remove_all_user_filters(channel_id, tspp_source);
+
+	if (restore_null_blocking_filters)
+		mpq_tspp_add_null_blocking_filters(channel_id, tspp_source);
+
+	if (remove_accept_all_filter)
+		mpq_tspp_remove_accept_all_filter(channel_id, tspp_source);
+
+	/* restore flags. we can only get here if we changed the flags. */
+	if (feed->pid == TSPP_PASS_THROUGH_PID)
+		mpq_dmx_tspp_info.tsif[tsif].pass_all_flag = 1;
+	else if (feed->pid == TSPP_NULL_PACKETS_PID)
+		mpq_dmx_tspp_info.tsif[tsif].pass_nulls_flag = 1;
+
+remove_channel_failed:
+	mutex_unlock(&mpq_dmx_tspp_info.tsif[tsif].mutex);
+	return ret;
+}
+
+static int mpq_tspp_dmx_start_filtering(struct dvb_demux_feed *feed)
+{
+	int ret;
+	struct mpq_demux *mpq_demux = feed->demux->priv;
+
+	MPQ_DVB_DBG_PRINT(
+		"%s(pid=%d) executed\n",
+		__func__,
+		feed->pid);
+
+	if (mpq_demux == NULL) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: invalid mpq_demux handle\n",
+			__func__);
+
+		return -EINVAL;
+	}
+
+	if (mpq_demux->source < DMX_SOURCE_DVR0) {
+		/* source from TSPP, need to configure tspp pipe */
+		ret = mpq_tspp_dmx_add_channel(feed);
+
+		if (ret < 0) {
+			MPQ_DVB_DBG_PRINT(
+				"%s: mpq_tspp_dmx_add_channel failed(%d)\n",
+				__func__,
+				ret);
+			return ret;
+		}
+	}
+
+	/*
+	 * Always feed sections/PES starting from a new one and
+	 * do not partial transfer data from older one
+	 */
+	feed->pusi_seen = 0;
+
+	ret = mpq_dmx_init_mpq_feed(feed);
+	if (ret) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: mpq_dmx_init_mpq_feed failed(%d)\n",
+			__func__,
+			ret);
+		if (mpq_demux->source < DMX_SOURCE_DVR0)
+			mpq_tspp_dmx_remove_channel(feed);
+
+		return ret;
+	}
+
+	return 0;
+}
+
+static int mpq_tspp_dmx_stop_filtering(struct dvb_demux_feed *feed)
+{
+	int ret = 0;
+	struct mpq_demux *mpq_demux = feed->demux->priv;
+	MPQ_DVB_DBG_PRINT(
+		"%s(%d) executed\n",
+		__func__,
+		feed->pid);
+
+	mpq_dmx_terminate_feed(feed);
+
+	if (mpq_demux->source < DMX_SOURCE_DVR0) {
+		/* source from TSPP, need to configure tspp pipe */
+		ret = mpq_tspp_dmx_remove_channel(feed);
+	}
+
+	return ret;
+}
+
+static int mpq_tspp_dmx_write_to_decoder(
+					struct dvb_demux_feed *feed,
+					const u8 *buf,
+					size_t len)
+{
+	/*
+	 * It is assumed that this function is called once for each
+	 * TS packet of the relevant feed.
+	 */
+	if (len > TSPP_RAW_TTS_SIZE)
+		MPQ_DVB_DBG_PRINT(
+				"%s: warnning - len larger than one packet\n",
+				__func__);
+
+	if (mpq_dmx_is_video_feed(feed))
+		return mpq_dmx_process_video_packet(feed, buf);
+
+	if (mpq_dmx_is_pcr_feed(feed))
+		return mpq_dmx_process_pcr_packet(feed, buf);
+
+	return 0;
+}
+
+/**
+ * Returns demux capabilities of TSPPv1 plugin
+ *
+ * @demux: demux device
+ * @caps: Returned capbabilities
+ *
+ * Return     error code
+ */
+static int mpq_tspp_dmx_get_caps(struct dmx_demux *demux,
+				struct dmx_caps *caps)
+{
+	struct dvb_demux *dvb_demux = demux->priv;
+
+	if ((dvb_demux == NULL) || (caps == NULL)) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: invalid parameters\n",
+			__func__);
+
+		return -EINVAL;
+	}
+
+	caps->caps = DMX_CAP_PULL_MODE | DMX_CAP_VIDEO_DECODER_DATA;
+	caps->num_decoders = MPQ_ADAPTER_MAX_NUM_OF_INTERFACES;
+	caps->num_demux_devices = CONFIG_DVB_MPQ_NUM_DMX_DEVICES;
+	caps->num_pid_filters = TSPP_MAX_PID_FILTER_NUM;
+	caps->num_section_filters = dvb_demux->filternum;
+	caps->num_section_filters_per_pid = dvb_demux->filternum;
+	caps->section_filter_length = DMX_FILTER_SIZE;
+	caps->num_demod_inputs = TSIF_COUNT;
+	caps->num_memory_inputs = CONFIG_DVB_MPQ_NUM_DMX_DEVICES;
+	caps->max_bitrate = 144;
+	caps->demod_input_max_bitrate = 72;
+	caps->memory_input_max_bitrate = 72;
+
+	/* Buffer requirements */
+	caps->section.flags =
+		DMX_BUFFER_EXTERNAL_SUPPORT	|
+		DMX_BUFFER_INTERNAL_SUPPORT;
+	caps->section.max_buffer_num = 1;
+	caps->section.max_size = 0xFFFFFFFF;
+	caps->section.size_alignment = 0;
+	caps->pes.flags =
+		DMX_BUFFER_EXTERNAL_SUPPORT	|
+		DMX_BUFFER_INTERNAL_SUPPORT;
+	caps->pes.max_buffer_num = 1;
+	caps->pes.max_size = 0xFFFFFFFF;
+	caps->pes.size_alignment = 0;
+	caps->recording_188_tsp.flags =
+		DMX_BUFFER_EXTERNAL_SUPPORT	|
+		DMX_BUFFER_INTERNAL_SUPPORT;
+	caps->recording_188_tsp.max_buffer_num = 1;
+	caps->recording_188_tsp.max_size = 0xFFFFFFFF;
+	caps->recording_188_tsp.size_alignment = 0;
+	caps->recording_192_tsp.flags =
+		DMX_BUFFER_EXTERNAL_SUPPORT	|
+		DMX_BUFFER_INTERNAL_SUPPORT;
+	caps->recording_192_tsp.max_buffer_num = 1;
+	caps->recording_192_tsp.max_size = 0xFFFFFFFF;
+	caps->recording_192_tsp.size_alignment = 0;
+	caps->playback_188_tsp.flags =
+		DMX_BUFFER_EXTERNAL_SUPPORT	|
+		DMX_BUFFER_INTERNAL_SUPPORT;
+	caps->playback_188_tsp.max_buffer_num = 1;
+	caps->playback_188_tsp.max_size = 0xFFFFFFFF;
+	caps->playback_188_tsp.size_alignment = 0;
+	caps->playback_192_tsp.flags =
+		DMX_BUFFER_EXTERNAL_SUPPORT	|
+		DMX_BUFFER_INTERNAL_SUPPORT;
+	caps->playback_192_tsp.max_buffer_num = 1;
+	caps->playback_192_tsp.max_size = 0xFFFFFFFF;
+	caps->playback_192_tsp.size_alignment = 0;
+	caps->decoder.flags =
+		DMX_BUFFER_CONTIGUOUS_MEM	|
+		DMX_BUFFER_SECURED_IF_DECRYPTED	|
+		DMX_BUFFER_EXTERNAL_SUPPORT	|
+		DMX_BUFFER_INTERNAL_SUPPORT	|
+		DMX_BUFFER_LINEAR_GROUP_SUPPORT;
+	caps->decoder.max_buffer_num = DMX_MAX_DECODER_BUFFER_NUM;
+	caps->decoder.max_size = 0xFFFFFFFF;
+	caps->decoder.size_alignment = SZ_4K;
+
+	return 0;
+}
+
+
+/**
+ * Reads TSIF STC from TSPP
+ *
+ * @demux: demux device
+ * @num: STC number. 0 for TSIF0 and 1 for TSIF1.
+ * @stc: STC value
+ * @base: divisor to get 90KHz value
+ *
+ * Return     error code
+ */
+static int mpq_tspp_dmx_get_stc(struct dmx_demux *demux, unsigned int num,
+		u64 *stc, unsigned int *base)
+{
+	enum tspp_source source;
+	u32 tcr_counter;
+
+	if (!demux || !stc || !base)
+		return -EINVAL;
+
+	if (num == 0)
+		source = TSPP_SOURCE_TSIF0;
+	else if (num == 1)
+		source = TSPP_SOURCE_TSIF1;
+	else
+		return -EINVAL;
+
+	tspp_get_ref_clk_counter(0, source, &tcr_counter);
+
+	*stc = ((u64)tcr_counter) * 256; /* conversion to 27MHz */
+	*base = 300; /* divisor to get 90KHz clock from stc value */
+
+	return 0;
+}
+
+static int mpq_tspp_dmx_init(
+			struct dvb_adapter *mpq_adapter,
+			struct mpq_demux *mpq_demux)
+{
+	int result;
+
+	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
+
+	mpq_dmx_tspp_info.ion_client = mpq_demux->ion_client;
+
+	/* Set the kernel-demux object capabilities */
+	mpq_demux->demux.dmx.capabilities =
+		DMX_TS_FILTERING			|
+		DMX_PES_FILTERING			|
+		DMX_SECTION_FILTERING			|
+		DMX_MEMORY_BASED_FILTERING		|
+		DMX_CRC_CHECKING			|
+		DMX_TS_DESCRAMBLING;
+
+	/* Set dvb-demux "virtual" function pointers */
+	mpq_demux->demux.priv = (void *)mpq_demux;
+	mpq_demux->demux.filternum = TSPP_MAX_SECTION_FILTER_NUM;
+	mpq_demux->demux.feednum = MPQ_MAX_DMX_FILES;
+	mpq_demux->demux.start_feed = mpq_tspp_dmx_start_filtering;
+	mpq_demux->demux.stop_feed = mpq_tspp_dmx_stop_filtering;
+	mpq_demux->demux.write_to_decoder = mpq_tspp_dmx_write_to_decoder;
+	mpq_demux->demux.decoder_fullness_init = mpq_dmx_decoder_fullness_init;
+	mpq_demux->demux.decoder_fullness_wait = mpq_dmx_decoder_fullness_wait;
+	mpq_demux->demux.decoder_fullness_abort =
+		mpq_dmx_decoder_fullness_abort;
+	mpq_demux->demux.decoder_buffer_status = mpq_dmx_decoder_buffer_status;
+	mpq_demux->demux.reuse_decoder_buffer = mpq_dmx_reuse_decoder_buffer;
+	mpq_demux->demux.set_secure_mode = mpq_dmx_set_secure_mode;
+
+	/* Initialize dvb_demux object */
+	result = dvb_dmx_init(&mpq_demux->demux);
+	if (result < 0) {
+		MPQ_DVB_ERR_PRINT("%s: dvb_dmx_init failed\n", __func__);
+		goto init_failed;
+	}
+
+	/* Now initailize the dmx-dev object */
+	mpq_demux->dmxdev.filternum = MPQ_MAX_DMX_FILES;
+	mpq_demux->dmxdev.demux = &mpq_demux->demux.dmx;
+	mpq_demux->dmxdev.capabilities =
+		DMXDEV_CAP_DUPLEX |
+		DMXDEV_CAP_PULL_MODE |
+		DMXDEV_CAP_INDEXING;
+
+	mpq_demux->dmxdev.demux->set_source = mpq_dmx_set_source;
+	mpq_demux->dmxdev.demux->get_stc = mpq_tspp_dmx_get_stc;
+	mpq_demux->dmxdev.demux->get_caps = mpq_tspp_dmx_get_caps;
+	mpq_demux->dmxdev.demux->map_buffer = mpq_dmx_map_buffer;
+	mpq_demux->dmxdev.demux->unmap_buffer = mpq_dmx_unmap_buffer;
+	mpq_demux->dmxdev.demux->write = mpq_dmx_write;
+	result = dvb_dmxdev_init(&mpq_demux->dmxdev, mpq_adapter);
+	if (result < 0) {
+		MPQ_DVB_ERR_PRINT("%s: dvb_dmxdev_init failed (errno=%d)\n",
+						  __func__,
+						  result);
+		goto init_failed_dmx_release;
+	}
+
+	/* Extend dvb-demux debugfs with TSPP statistics. */
+	mpq_dmx_init_hw_statistics(mpq_demux);
+
+	return 0;
+
+init_failed_dmx_release:
+	dvb_dmx_release(&mpq_demux->demux);
+init_failed:
+	return result;
+}
+
+static int __init mpq_dmx_tspp_plugin_init(void)
+{
+	int i;
+	int j;
+	int ret;
+
+	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
+
+	for (i = 0; i < TSIF_COUNT; i++) {
+		mpq_dmx_tspp_info.tsif[i].buffer_count =
+				TSPP_BUFFER_COUNT(tspp_out_buffer_size);
+
+		mpq_dmx_tspp_info.tsif[i].aggregate_ids =
+			vzalloc(mpq_dmx_tspp_info.tsif[i].buffer_count *
+				sizeof(int));
+		if (NULL == mpq_dmx_tspp_info.tsif[i].aggregate_ids) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: Failed to allocate memory for buffer descriptors aggregation\n",
+				__func__);
+			for (j = 0; j < i; j++) {
+				kthread_stop(mpq_dmx_tspp_info.tsif[j].thread);
+				vfree(mpq_dmx_tspp_info.tsif[j].aggregate_ids);
+				mutex_destroy(&mpq_dmx_tspp_info.tsif[j].mutex);
+			}
+			return -ENOMEM;
+		}
+		mpq_dmx_tspp_info.tsif[i].channel_ref = 0;
+		mpq_dmx_tspp_info.tsif[i].buff_index = 0;
+		mpq_dmx_tspp_info.tsif[i].ch_mem_heap_handle = NULL;
+		mpq_dmx_tspp_info.tsif[i].ch_mem_heap_virt_base = NULL;
+		mpq_dmx_tspp_info.tsif[i].ch_mem_heap_phys_base = 0;
+		atomic_set(&mpq_dmx_tspp_info.tsif[i].data_cnt, 0);
+
+		for (j = 0; j < TSPP_MAX_PID_FILTER_NUM; j++) {
+			mpq_dmx_tspp_info.tsif[i].filters[j].pid = -1;
+			mpq_dmx_tspp_info.tsif[i].filters[j].ref_count = 0;
+			mpq_dmx_tspp_info.tsif[i].filters[j].hw_index = -1;
+		}
+
+		for (j = 0; j < TSPP_MAX_HW_PID_FILTER_NUM; j++)
+			mpq_dmx_tspp_info.tsif[i].hw_indexes[j] = 0;
+
+		mpq_dmx_tspp_info.tsif[i].current_filter_count = 0;
+		mpq_dmx_tspp_info.tsif[i].pass_nulls_flag = 0;
+		mpq_dmx_tspp_info.tsif[i].pass_all_flag = 0;
+		mpq_dmx_tspp_info.tsif[i].accept_all_filter_exists_flag = 0;
+
+		snprintf(mpq_dmx_tspp_info.tsif[i].name,
+				TSIF_NAME_LENGTH,
+				"dmx_tsif%d",
+				i);
+
+		init_waitqueue_head(&mpq_dmx_tspp_info.tsif[i].wait_queue);
+		mpq_dmx_tspp_info.tsif[i].thread =
+			kthread_run(
+				mpq_dmx_tspp_thread, (void *)i,
+				mpq_dmx_tspp_info.tsif[i].name);
+
+		if (IS_ERR(mpq_dmx_tspp_info.tsif[i].thread)) {
+			vfree(mpq_dmx_tspp_info.tsif[i].aggregate_ids);
+
+			for (j = 0; j < i; j++) {
+				kthread_stop(mpq_dmx_tspp_info.tsif[j].thread);
+				vfree(mpq_dmx_tspp_info.tsif[j].aggregate_ids);
+				mutex_destroy(&mpq_dmx_tspp_info.tsif[j].mutex);
+			}
+
+			MPQ_DVB_ERR_PRINT(
+				"%s: kthread_run failed\n",
+				__func__);
+
+			return -ENOMEM;
+		}
+
+		mutex_init(&mpq_dmx_tspp_info.tsif[i].mutex);
+	}
+
+	ret = mpq_dmx_plugin_init(mpq_tspp_dmx_init);
+
+	if (ret < 0) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: mpq_dmx_plugin_init failed (errno=%d)\n",
+			__func__,
+			ret);
+
+		for (i = 0; i < TSIF_COUNT; i++) {
+			kthread_stop(mpq_dmx_tspp_info.tsif[i].thread);
+			vfree(mpq_dmx_tspp_info.tsif[i].aggregate_ids);
+			mutex_destroy(&mpq_dmx_tspp_info.tsif[i].mutex);
+		}
+	}
+
+	return ret;
+}
+
+static void __exit mpq_dmx_tspp_plugin_exit(void)
+{
+	int i;
+
+	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
+
+	for (i = 0; i < TSIF_COUNT; i++) {
+		mutex_lock(&mpq_dmx_tspp_info.tsif[i].mutex);
+
+		/*
+		 * Note: tspp_close_channel will also free the TSPP buffers
+		 * even if we allocated them ourselves,
+		 * using our free function.
+		 */
+		if (mpq_dmx_tspp_info.tsif[i].channel_ref) {
+			tspp_unregister_notification(0,
+				TSPP_CHANNEL_ID(i, TSPP_CHANNEL));
+			tspp_close_channel(0,
+				TSPP_CHANNEL_ID(i, TSPP_CHANNEL));
+
+			if (allocation_mode ==
+				MPQ_DMX_TSPP_CONTIGUOUS_PHYS_ALLOC)
+				mpq_dmx_channel_mem_free(i);
+		}
+		if (mpq_dmx_tspp_info.tsif[i].aggregate_ids)
+			vfree(mpq_dmx_tspp_info.tsif[i].aggregate_ids);
+
+		mutex_unlock(&mpq_dmx_tspp_info.tsif[i].mutex);
+		kthread_stop(mpq_dmx_tspp_info.tsif[i].thread);
+		mutex_destroy(&mpq_dmx_tspp_info.tsif[i].mutex);
+	}
+
+	mpq_dmx_plugin_exit();
+}
+
+
+module_init(mpq_dmx_tspp_plugin_init);
+module_exit(mpq_dmx_tspp_plugin_exit);
+
+MODULE_DESCRIPTION("Qualcomm demux TSPP version 1 HW Plugin");
+MODULE_LICENSE("GPL v2");
+
+
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tspp_v2.c b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tspp_v2.c
new file mode 100644
index 0000000..60ce9e5
--- /dev/null
+++ b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tspp_v2.c
@@ -0,0 +1,185 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include "mpq_dvb_debug.h"
+#include "mpq_dmx_plugin_common.h"
+
+
+#define TSIF_COUNT				2
+
+#define BAM_INPUT_COUNT			4
+
+/* Max number of PID filters */
+#define TSPP_MAX_PID_FILTER_NUM		128
+
+/* Max number of section filters */
+#define TSPP_MAX_SECTION_FILTER_NUM		64
+
+
+static int mpq_tspp_dmx_start_filtering(struct dvb_demux_feed *feed)
+{
+	MPQ_DVB_DBG_PRINT(
+		"%s(%d) executed\n",
+		__func__,
+		feed->pid);
+
+	/* Always feed sections/PES starting from a new one and
+	 * do not partial transfer data from older one
+	 */
+	feed->pusi_seen = 0;
+	return 0;
+}
+
+static int mpq_tspp_dmx_stop_filtering(struct dvb_demux_feed *feed)
+{
+	MPQ_DVB_DBG_PRINT(
+		"%s(%d) executed\n",
+		__func__,
+		feed->pid);
+
+	return 0;
+}
+
+/**
+ * Returns demux capabilities of TSPPv2 plugin
+ *
+ * @demux: demux device
+ * @caps: Returned capbabilities
+ *
+ * Return     error code
+ */
+static int mpq_tspp_dmx_get_caps(struct dmx_demux *demux,
+				struct dmx_caps *caps)
+{
+	struct dvb_demux *dvb_demux = demux->priv;
+
+	if ((dvb_demux == NULL) || (caps == NULL)) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: invalid parameters\n",
+			__func__);
+
+		return -EINVAL;
+	}
+
+	caps->caps = DMX_CAP_PULL_MODE | DMX_CAP_VIDEO_INDEXING |
+		DMX_CAP_VIDEO_DECODER_DATA;
+	caps->num_decoders = MPQ_ADAPTER_MAX_NUM_OF_INTERFACES;
+	caps->num_demux_devices = CONFIG_DVB_MPQ_NUM_DMX_DEVICES;
+	caps->num_pid_filters = TSPP_MAX_PID_FILTER_NUM;
+	caps->num_section_filters = dvb_demux->filternum;
+	caps->num_section_filters_per_pid = dvb_demux->filternum;
+	caps->section_filter_length = DMX_FILTER_SIZE;
+	caps->num_demod_inputs = TSIF_COUNT;
+	caps->num_memory_inputs = BAM_INPUT_COUNT;
+	caps->max_bitrate = 320;
+	caps->demod_input_max_bitrate = 96;
+	caps->memory_input_max_bitrate = 80;
+
+	return 0;
+}
+
+/**
+ * Initialize a single demux device.
+ *
+ * @mpq_adapter: MPQ DVB adapter
+ * @mpq_demux: The demux device to initialize
+ *
+ * Return     error code
+ */
+static int mpq_tspp_dmx_init(
+				struct dvb_adapter *mpq_adapter,
+				struct mpq_demux *mpq_demux)
+{
+	int result;
+
+	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
+
+	/* Set the kernel-demux object capabilities */
+	mpq_demux->demux.dmx.capabilities =
+		DMX_TS_FILTERING			|
+		DMX_PES_FILTERING			|
+		DMX_SECTION_FILTERING		|
+		DMX_MEMORY_BASED_FILTERING	|
+		DMX_CRC_CHECKING			|
+		DMX_TS_DESCRAMBLING;
+
+	/* Set dvb-demux "virtual" function pointers */
+	mpq_demux->demux.priv = (void *)mpq_demux;
+	mpq_demux->demux.filternum = TSPP_MAX_SECTION_FILTER_NUM;
+	mpq_demux->demux.feednum = MPQ_MAX_DMX_FILES;
+	mpq_demux->demux.start_feed = mpq_tspp_dmx_start_filtering;
+	mpq_demux->demux.stop_feed = mpq_tspp_dmx_stop_filtering;
+	mpq_demux->demux.write_to_decoder = NULL;
+	mpq_demux->demux.decoder_fullness_init = NULL;
+	mpq_demux->demux.decoder_fullness_wait = NULL;
+	mpq_demux->demux.decoder_fullness_abort = NULL;
+	mpq_demux->demux.decoder_buffer_status = NULL;
+	mpq_demux->demux.reuse_decoder_buffer = NULL;
+	mpq_demux->demux.set_secure_mode = NULL;
+
+	/* Initialize dvb_demux object */
+	result = dvb_dmx_init(&mpq_demux->demux);
+	if (result < 0) {
+		MPQ_ERR_PRINT("%s: dvb_dmx_init failed\n", __func__);
+		goto init_failed;
+	}
+
+	/* Now initailize the dmx-dev object */
+	mpq_demux->dmxdev.filternum = MPQ_MAX_DMX_FILES;
+	mpq_demux->dmxdev.demux = &mpq_demux->demux.dmx;
+	mpq_demux->dmxdev.capabilities =
+		DMXDEV_CAP_DUPLEX |
+		DMXDEV_CAP_PULL_MODE |
+		DMXDEV_CAP_INDEXING;
+
+	mpq_demux->dmxdev.demux->set_source = mpq_dmx_set_source;
+	mpq_demux->dmxdev.demux->get_caps = mpq_tspp_dmx_get_caps;
+
+	result = dvb_dmxdev_init(&mpq_demux->dmxdev, mpq_adapter);
+	if (result < 0) {
+		MPQ_DVB_ERR_PRINT("%s: dvb_dmxdev_init failed (errno=%d)\n",
+						  __func__,
+						  result);
+
+		goto init_failed_dmx_release;
+	}
+
+	return 0;
+
+init_failed_dmx_release:
+	dvb_dmx_release(&mpq_demux->demux);
+init_failed:
+	return result;
+}
+
+static int __init mpq_dmx_tspp_plugin_init(void)
+{
+	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
+
+	return mpq_dmx_plugin_init(mpq_tspp_dmx_init);
+}
+
+static void __exit mpq_dmx_tspp_plugin_exit(void)
+{
+	MPQ_DVB_DBG_PRINT("%s executed\n", __func__);
+	mpq_dmx_plugin_exit();
+}
+
+
+module_init(mpq_dmx_tspp_plugin_init);
+module_exit(mpq_dmx_tspp_plugin_exit);
+
+MODULE_DESCRIPTION("Qualcomm demux TSPP version2 HW Plugin");
+MODULE_LICENSE("GPL v2");
+
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_sdmx.c b/drivers/media/platform/msm/dvb/demux/mpq_sdmx.c
new file mode 100644
index 0000000..946b055
--- /dev/null
+++ b/drivers/media/platform/msm/dvb/demux/mpq_sdmx.c
@@ -0,0 +1,937 @@
+/* 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/module.h>
+#include <linux/kthread.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include "qseecom_kernel.h"
+#include "mpq_sdmx.h"
+
+static struct qseecom_handle *sdmx_qseecom_handles[SDMX_MAX_SESSIONS];
+static struct mutex sdmx_lock[SDMX_MAX_SESSIONS];
+
+#define QSEECOM_ALIGN_SIZE	0x40
+#define QSEECOM_ALIGN_MASK	(QSEECOM_ALIGN_SIZE - 1)
+#define QSEECOM_ALIGN(x)	\
+	((x + QSEECOM_ALIGN_SIZE) & (~QSEECOM_ALIGN_MASK))
+
+enum sdmx_cmd_id {
+	SDMX_OPEN_SESSION_CMD,
+	SDMX_CLOSE_SESSION_CMD,
+	SDMX_SET_SESSION_CFG_CMD,
+	SDMX_ADD_FILTER_CMD,
+	SDMX_REMOVE_FILTER_CMD,
+	SDMX_SET_KL_IDX_CMD,
+	SDMX_ADD_RAW_PID_CMD,
+	SDMX_REMOVE_RAW_PID_CMD,
+	SDMX_PROCESS_CMD,
+	SDMX_GET_DBG_COUNTERS_CMD,
+	SDMX_RESET_DBG_COUNTERS_CMD,
+	SDMX_GET_VERSION_CMD
+};
+
+struct sdmx_proc_req {
+	enum sdmx_cmd_id cmd_id;
+	u32 session_handle;
+	u8 flags;
+	struct sdmx_buff_descr in_buf_descr;
+	u32 inp_fill_cnt;
+	u32 in_rd_offset;
+	u32 num_filters;
+	struct sdmx_filter_status filters_status[];
+};
+
+struct sdmx_proc_rsp {
+	enum sdmx_status ret;
+	u32 inp_fill_cnt;
+	u32 in_rd_offset;
+	u32 err_indicators;
+	u32 status_indicators;
+};
+
+struct sdmx_open_ses_req {
+	enum sdmx_cmd_id cmd_id;
+};
+
+struct sdmx_open_ses_rsp {
+	enum sdmx_status ret;
+	u32 session_handle;
+};
+
+struct sdmx_close_ses_req {
+	enum sdmx_cmd_id cmd_id;
+	u32 session_handle;
+};
+
+struct sdmx_close_ses_rsp {
+	enum sdmx_status ret;
+};
+
+struct sdmx_ses_cfg_req {
+	enum sdmx_cmd_id cmd_id;
+	u32 session_handle;
+	enum sdmx_proc_mode process_mode;
+	enum sdmx_inp_mode input_mode;
+	enum sdmx_pkt_format packet_len;
+	u8 odd_scramble_bits;
+	u8 even_scramble_bits;
+};
+
+struct sdmx_ses_cfg_rsp {
+	enum sdmx_status ret;
+};
+
+struct sdmx_set_kl_ind_req {
+	enum sdmx_cmd_id cmd_id;
+	u32 session_handle;
+	u32 pid;
+	u32 kl_index;
+};
+
+struct sdmx_set_kl_ind_rsp {
+	enum sdmx_status ret;
+};
+
+struct sdmx_add_filt_req {
+	enum sdmx_cmd_id cmd_id;
+	u32 session_handle;
+	u32 pid;
+	enum sdmx_filter filter_type;
+	struct sdmx_buff_descr meta_data_buf;
+	enum sdmx_buf_mode buffer_mode;
+	enum sdmx_raw_out_format ts_out_format;
+	u32 flags;
+	u32 num_data_bufs;
+	struct sdmx_buff_descr data_bufs[];
+};
+
+struct sdmx_add_filt_rsp {
+	enum sdmx_status ret;
+	u32 filter_handle;
+};
+
+struct sdmx_rem_filt_req {
+	enum sdmx_cmd_id cmd_id;
+	u32 session_handle;
+	u32 filter_handle;
+};
+
+struct sdmx_rem_filt_rsp {
+	enum sdmx_status ret;
+};
+
+struct sdmx_add_raw_req {
+	enum sdmx_cmd_id cmd_id;
+	u32 session_handle;
+	u32 filter_handle;
+	u32 pid;
+};
+
+struct sdmx_add_raw_rsp {
+	enum sdmx_status ret;
+};
+
+struct sdmx_rem_raw_req {
+	enum sdmx_cmd_id cmd_id;
+	u32 session_handle;
+	u32 filter_handle;
+	u32 pid;
+};
+
+struct sdmx_rem_raw_rsp {
+	enum sdmx_status ret;
+};
+
+struct sdmx_get_counters_req {
+	enum sdmx_cmd_id cmd_id;
+	u32 session_handle;
+	u32 num_filters;
+};
+
+struct sdmx_get_counters_rsp {
+	enum sdmx_status ret;
+	struct sdmx_session_dbg_counters session_counters;
+	u32 num_filters;
+	struct sdmx_filter_dbg_counters filter_counters[];
+};
+
+struct sdmx_rst_counters_req {
+	enum sdmx_cmd_id cmd_id;
+	u32 session_handle;
+};
+
+struct sdmx_rst_counters_rsp {
+	enum sdmx_status ret;
+};
+
+struct sdmx_get_version_req {
+	enum sdmx_cmd_id cmd_id;
+};
+
+struct sdmx_get_version_rsp {
+	enum sdmx_status ret;
+	int32_t version;
+};
+
+static void get_cmd_rsp_buffers(int handle_index,
+	void **cmd,
+	int *cmd_len,
+	void **rsp,
+	int *rsp_len)
+{
+	*cmd = sdmx_qseecom_handles[handle_index]->sbuf;
+
+	if (*cmd_len & QSEECOM_ALIGN_MASK)
+		*cmd_len = QSEECOM_ALIGN(*cmd_len);
+
+	*rsp = sdmx_qseecom_handles[handle_index]->sbuf + *cmd_len;
+
+	if (*rsp_len & QSEECOM_ALIGN_MASK)
+		*rsp_len = QSEECOM_ALIGN(*rsp_len);
+
+}
+
+/*
+ * Returns version of secure-demux app.
+ *
+ * @session_handle: Returned instance handle. Must not be NULL.
+ * Return error code
+ */
+int sdmx_get_version(int session_handle, int32_t *version)
+{
+	int res, cmd_len, rsp_len;
+	struct sdmx_get_version_req *cmd;
+	struct sdmx_get_version_rsp *rsp;
+	enum sdmx_status ret;
+
+	if ((session_handle < 0) || (session_handle >= SDMX_MAX_SESSIONS) ||
+		(version == NULL))
+		return SDMX_STATUS_INVALID_INPUT_PARAMS;
+
+	cmd_len = sizeof(struct sdmx_get_version_req);
+	rsp_len = sizeof(struct sdmx_get_version_rsp);
+
+	/* Lock shared memory */
+	mutex_lock(&sdmx_lock[session_handle]);
+
+	/* Get command and response buffers */
+	get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
+		(void **)&rsp, &rsp_len);
+
+	/* Populate command struct */
+	cmd->cmd_id = SDMX_GET_VERSION_CMD;
+
+	/* Issue QSEECom command */
+	res = qseecom_send_command(sdmx_qseecom_handles[session_handle],
+		(void *)cmd, cmd_len, (void *)rsp, rsp_len);
+
+	if (res < 0) {
+		mutex_unlock(&sdmx_lock[session_handle]);
+		return SDMX_STATUS_GENERAL_FAILURE;
+	}
+
+	ret = rsp->ret;
+	*version = rsp->version;
+
+	mutex_unlock(&sdmx_lock[session_handle]);
+
+	return ret;
+
+}
+EXPORT_SYMBOL(sdmx_get_version);
+
+/*
+ * Initializes a new secure demux instance and returns a handle of the instance.
+ *
+ * @session_handle: handle of a secure demux instance to get its version.
+ * Return the version if successfull or an error code.
+ */
+int sdmx_open_session(int *session_handle)
+{
+	int res, cmd_len, rsp_len;
+	enum sdmx_status ret, version_ret;
+	struct sdmx_open_ses_req *cmd;
+	struct sdmx_open_ses_rsp *rsp;
+	struct qseecom_handle *qseecom_handle = NULL;
+	int32_t version;
+
+	/* Input validation */
+	if (session_handle == NULL)
+		return SDMX_STATUS_GENERAL_FAILURE;
+
+	/* Start the TZ app */
+	res = qseecom_start_app(&qseecom_handle, "securemm", 4096);
+
+	if (res < 0)
+		return SDMX_STATUS_GENERAL_FAILURE;
+
+	cmd_len = sizeof(struct sdmx_open_ses_req);
+	rsp_len = sizeof(struct sdmx_open_ses_rsp);
+
+	/* Get command and response buffers */
+	cmd = (struct sdmx_open_ses_req *)qseecom_handle->sbuf;
+
+	if (cmd_len & QSEECOM_ALIGN_MASK)
+		cmd_len = QSEECOM_ALIGN(cmd_len);
+
+	rsp = (struct sdmx_open_ses_rsp *)qseecom_handle->sbuf + cmd_len;
+
+	if (rsp_len & QSEECOM_ALIGN_MASK)
+		rsp_len = QSEECOM_ALIGN(rsp_len);
+
+	/* Will be later overridden by SDMX response */
+	*session_handle = SDMX_INVALID_SESSION_HANDLE;
+
+	/* Populate command struct */
+	cmd->cmd_id = SDMX_OPEN_SESSION_CMD;
+
+	/* Issue QSEECom command */
+	res = qseecom_send_command(qseecom_handle, (void *)cmd, cmd_len,
+		(void *)rsp, rsp_len);
+
+	if (res < 0) {
+		qseecom_shutdown_app(&qseecom_handle);
+		return SDMX_STATUS_GENERAL_FAILURE;
+	}
+
+	/* Parse response struct */
+	*session_handle = rsp->session_handle;
+
+	/* Initialize handle and mutex */
+	sdmx_qseecom_handles[*session_handle] = qseecom_handle;
+	mutex_init(&sdmx_lock[*session_handle]);
+	ret = rsp->ret;
+
+	/* Get and print the app version */
+	version_ret = sdmx_get_version(*session_handle, &version);
+	if (SDMX_SUCCESS == version_ret)
+		pr_info("TZ SDMX version is %x.%x\n", version >> 8,
+			version & 0xFF);
+	else
+		pr_err("Error reading TZ SDMX version\n");
+
+	return ret;
+}
+EXPORT_SYMBOL(sdmx_open_session);
+
+/*
+ * Closes a secure demux instance.
+ *
+ * @session_handle: handle of a secure demux instance to close.
+ * Return error code
+ */
+int sdmx_close_session(int session_handle)
+{
+	int res, cmd_len, rsp_len;
+	struct sdmx_close_ses_req *cmd;
+	struct sdmx_close_ses_rsp *rsp;
+	enum sdmx_status ret;
+
+	if ((session_handle < 0) || (session_handle >= SDMX_MAX_SESSIONS))
+		return SDMX_STATUS_INVALID_INPUT_PARAMS;
+
+	cmd_len = sizeof(struct sdmx_close_ses_req);
+	rsp_len = sizeof(struct sdmx_close_ses_rsp);
+
+	/* Lock shared memory */
+	mutex_lock(&sdmx_lock[session_handle]);
+
+	/* Get command and response buffers */
+	get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
+		(void **)&rsp, &rsp_len);
+
+	/* Populate command struct */
+	cmd->cmd_id = SDMX_CLOSE_SESSION_CMD;
+	cmd->session_handle = session_handle;
+
+	/* Issue QSEECom command */
+	res = qseecom_send_command(sdmx_qseecom_handles[session_handle],
+		(void *)cmd, cmd_len, (void *)rsp, rsp_len);
+
+	if (res < 0) {
+		mutex_unlock(&sdmx_lock[session_handle]);
+		return SDMX_STATUS_GENERAL_FAILURE;
+	}
+
+	ret = rsp->ret;
+
+	/* Shutdown the TZ app (or at least free the current handle) */
+	res = qseecom_shutdown_app(&sdmx_qseecom_handles[session_handle]);
+	if (res < 0) {
+		mutex_unlock(&sdmx_lock[session_handle]);
+		return SDMX_STATUS_GENERAL_FAILURE;
+	}
+
+	sdmx_qseecom_handles[session_handle] = NULL;
+
+	mutex_unlock(&sdmx_lock[session_handle]);
+
+	return ret;
+}
+EXPORT_SYMBOL(sdmx_close_session);
+
+/*
+ * Configures an open secure demux instance.
+ *
+ * @session_handle: secure demux instance
+ * @proc_mode: Defines secure demux's behavior in case of output
+ *             buffer overflow.
+ * @inp_mode: Defines the input encryption settings.
+ * @pkt_format: TS packet length in input buffer.
+ * @odd_scramble_bits: Value of the scramble bits indicating the ODD key.
+ * @even_scramble_bits: Value of the scramble bits indicating the EVEN key.
+ * Return error code
+ */
+int sdmx_set_session_cfg(int session_handle,
+	enum sdmx_proc_mode proc_mode,
+	enum sdmx_inp_mode inp_mode,
+	enum sdmx_pkt_format pkt_format,
+	u8 odd_scramble_bits,
+	u8 even_scramble_bits)
+{
+	int res, cmd_len, rsp_len;
+	struct sdmx_ses_cfg_req *cmd;
+	struct sdmx_ses_cfg_rsp *rsp;
+	enum sdmx_status ret;
+
+	if ((session_handle < 0) || (session_handle >= SDMX_MAX_SESSIONS))
+		return SDMX_STATUS_INVALID_INPUT_PARAMS;
+
+	cmd_len = sizeof(struct sdmx_ses_cfg_req);
+	rsp_len = sizeof(struct sdmx_ses_cfg_rsp);
+
+	/* Lock shared memory */
+	mutex_lock(&sdmx_lock[session_handle]);
+
+	/* Get command and response buffers */
+	get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
+		(void **)&rsp, &rsp_len);
+
+	/* Populate command struct */
+	cmd->cmd_id = SDMX_SET_SESSION_CFG_CMD;
+	cmd->session_handle = session_handle;
+	cmd->process_mode = proc_mode;
+	cmd->input_mode = inp_mode;
+	cmd->packet_len = pkt_format;
+	cmd->odd_scramble_bits = odd_scramble_bits;
+	cmd->even_scramble_bits = even_scramble_bits;
+
+	/* Issue QSEECom command */
+	res = qseecom_send_command(sdmx_qseecom_handles[session_handle],
+		(void *)cmd, cmd_len, (void *)rsp, rsp_len);
+
+	if (res < 0) {
+		mutex_unlock(&sdmx_lock[session_handle]);
+		return SDMX_STATUS_GENERAL_FAILURE;
+	}
+
+	ret = rsp->ret;
+
+	mutex_unlock(&sdmx_lock[session_handle]);
+
+	return ret;
+}
+EXPORT_SYMBOL(sdmx_set_session_cfg);
+
+/*
+ * Creates a new secure demux filter and returns a filter handle
+ *
+ * @session_handle: secure demux instance
+ * @pid: pid to filter
+ * @filter_type: type of filtering
+ * @meta_data_buf: meta data buffer descriptor
+ * @data_buf_mode: data buffer mode (ring/linear)
+ * @num_data_bufs: number of data buffers (use 1 for a ring buffer)
+ * @data_bufs: data buffers descriptors array
+ * @filter_handle: returned filter handle
+ * @ts_out_format: output format for raw filters
+ * @flags: optional flags for filter
+ *	   (currently only clear section CRC verification is supported)
+ *
+ * Return error code
+ */
+int sdmx_add_filter(int session_handle,
+	u16 pid,
+	enum sdmx_filter filterype,
+	struct sdmx_buff_descr *meta_data_buf,
+	enum sdmx_buf_mode d_buf_mode,
+	u32 num_data_bufs,
+	struct sdmx_buff_descr *data_bufs,
+	int *filter_handle,
+	enum sdmx_raw_out_format ts_out_format,
+	u32 flags)
+{
+	int res, cmd_len, rsp_len;
+	struct sdmx_add_filt_req *cmd;
+	struct sdmx_add_filt_rsp *rsp;
+	enum sdmx_status ret;
+
+	if ((session_handle < 0) || (session_handle >= SDMX_MAX_SESSIONS) ||
+		(filter_handle == NULL))
+		return SDMX_STATUS_INVALID_INPUT_PARAMS;
+
+	cmd_len = sizeof(struct sdmx_add_filt_req)
+		+ num_data_bufs * sizeof(struct sdmx_buff_descr);
+	rsp_len = sizeof(struct sdmx_add_filt_rsp);
+
+	/* Will be later overridden by SDMX response */
+	*filter_handle = SDMX_INVALID_FILTER_HANDLE;
+
+	/* Lock shared memory */
+	mutex_lock(&sdmx_lock[session_handle]);
+
+	/* Get command and response buffers */
+	get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
+		(void **)&rsp, &rsp_len);
+
+	/* Populate command struct */
+	cmd->cmd_id = SDMX_ADD_FILTER_CMD;
+	cmd->session_handle = session_handle;
+	cmd->pid = (u32)pid;
+	cmd->filter_type = filterype;
+	cmd->ts_out_format = ts_out_format;
+	cmd->flags = flags;
+	if (meta_data_buf != NULL)
+		memcpy(&(cmd->meta_data_buf), meta_data_buf,
+			sizeof(struct sdmx_buff_descr));
+	else
+		memset(&(cmd->meta_data_buf), 0,
+			sizeof(struct sdmx_buff_descr));
+
+	cmd->buffer_mode = d_buf_mode;
+	cmd->num_data_bufs = num_data_bufs;
+	memcpy(cmd->data_bufs, data_bufs,
+		num_data_bufs * sizeof(struct sdmx_buff_descr));
+
+	/* Issue QSEECom command */
+	res = qseecom_send_command(sdmx_qseecom_handles[session_handle],
+		(void *)cmd, cmd_len, (void *)rsp, rsp_len);
+
+	if (res < 0) {
+		mutex_unlock(&sdmx_lock[session_handle]);
+		return SDMX_STATUS_GENERAL_FAILURE;
+	}
+
+	/* Parse response struct */
+	*filter_handle = rsp->filter_handle;
+	ret = rsp->ret;
+
+	mutex_unlock(&sdmx_lock[session_handle]);
+
+	return ret;
+}
+EXPORT_SYMBOL(sdmx_add_filter);
+
+/*
+ * Removes a secure demux filter
+ *
+ * @session_handle: secure demux instance
+ * @filter_handle: filter handle to remove
+ *
+ * Return error code
+ */
+int sdmx_remove_filter(int session_handle, int filter_handle)
+{
+	int res, cmd_len, rsp_len;
+	struct sdmx_rem_filt_req *cmd;
+	struct sdmx_rem_filt_rsp *rsp;
+	enum sdmx_status ret;
+
+	if ((session_handle < 0) || (session_handle >= SDMX_MAX_SESSIONS))
+		return SDMX_STATUS_INVALID_INPUT_PARAMS;
+
+	cmd_len = sizeof(struct sdmx_rem_filt_req);
+	rsp_len = sizeof(struct sdmx_rem_filt_rsp);
+
+	/* Lock shared memory */
+	mutex_lock(&sdmx_lock[session_handle]);
+
+	/* Get command and response buffers */
+	get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
+		(void **)&rsp, &rsp_len);
+
+	/* Populate command struct */
+	cmd->cmd_id = SDMX_REMOVE_FILTER_CMD;
+	cmd->session_handle = session_handle;
+	cmd->filter_handle = filter_handle;
+
+	/* Issue QSEECom command */
+	res = qseecom_send_command(sdmx_qseecom_handles[session_handle],
+		(void *)cmd, cmd_len, (void *)rsp, rsp_len);
+
+	if (res < 0) {
+		mutex_unlock(&sdmx_lock[session_handle]);
+		return SDMX_STATUS_GENERAL_FAILURE;
+	}
+
+	ret = rsp->ret;
+
+	mutex_unlock(&sdmx_lock[session_handle]);
+
+	return ret;
+}
+EXPORT_SYMBOL(sdmx_remove_filter);
+
+/*
+ * Associates a key ladder index for the specified pid
+ *
+ * @session_handle: secure demux instance
+ * @pid: pid
+ * @key_ladder_index: key ladder index to associate to the pid
+ *
+ * Return error code
+ *
+ * Note: if pid already has some key ladder index associated, it will be
+ * overridden.
+ */
+int sdmx_set_kl_ind(int session_handle, u16 pid, u32 key_ladder_index)
+{
+	int res, cmd_len, rsp_len;
+	struct sdmx_set_kl_ind_req *cmd;
+	struct sdmx_set_kl_ind_rsp *rsp;
+	enum sdmx_status ret;
+
+	if ((session_handle < 0) || (session_handle >= SDMX_MAX_SESSIONS))
+		return SDMX_STATUS_INVALID_INPUT_PARAMS;
+
+	cmd_len = sizeof(struct sdmx_set_kl_ind_req);
+	rsp_len = sizeof(struct sdmx_set_kl_ind_rsp);
+
+	/* Lock shared memory */
+	mutex_lock(&sdmx_lock[session_handle]);
+
+	/* Get command and response buffers */
+	get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
+		(void **)&rsp, &rsp_len);
+
+	/* Populate command struct */
+	cmd->cmd_id = SDMX_SET_KL_IDX_CMD;
+	cmd->session_handle = session_handle;
+	cmd->pid = (u32)pid;
+	cmd->kl_index = key_ladder_index;
+
+	/* Issue QSEECom command */
+	res = qseecom_send_command(sdmx_qseecom_handles[session_handle],
+		(void *)cmd, cmd_len, (void *)rsp, rsp_len);
+
+	if (res < 0) {
+		mutex_unlock(&sdmx_lock[session_handle]);
+		return SDMX_STATUS_GENERAL_FAILURE;
+	}
+
+	ret = rsp->ret;
+
+	mutex_unlock(&sdmx_lock[session_handle]);
+
+	return ret;
+}
+EXPORT_SYMBOL(sdmx_set_kl_ind);
+
+/*
+ * Adds the specified pid to an existing raw (recording) filter
+ *
+ * @session_handle: secure demux instance
+ * @filter_handle: raw filter handle
+ * @pid: pid
+ *
+ * Return error code
+ */
+int sdmx_add_raw_pid(int session_handle, int filter_handle, u16 pid)
+{
+	int res, cmd_len, rsp_len;
+	struct sdmx_add_raw_req *cmd;
+	struct sdmx_add_raw_rsp *rsp;
+	enum sdmx_status ret;
+
+	if ((session_handle < 0) || (session_handle >= SDMX_MAX_SESSIONS))
+		return SDMX_STATUS_INVALID_INPUT_PARAMS;
+
+	cmd_len = sizeof(struct sdmx_add_raw_req);
+	rsp_len = sizeof(struct sdmx_add_raw_rsp);
+
+	/* Lock shared memory */
+	mutex_lock(&sdmx_lock[session_handle]);
+
+	/* Get command and response buffers */
+	get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
+		(void **)&rsp, &rsp_len);
+
+	/* Populate command struct */
+	cmd->cmd_id = SDMX_ADD_RAW_PID_CMD;
+	cmd->session_handle = session_handle;
+	cmd->filter_handle = filter_handle;
+	cmd->pid = (u32)pid;
+
+	/* Issue QSEECom command */
+	res = qseecom_send_command(sdmx_qseecom_handles[session_handle],
+		(void *)cmd, cmd_len, (void *)rsp, rsp_len);
+
+	if (res < 0) {
+		mutex_unlock(&sdmx_lock[session_handle]);
+		return SDMX_STATUS_GENERAL_FAILURE;
+	}
+
+	ret = rsp->ret;
+
+	mutex_unlock(&sdmx_lock[session_handle]);
+
+	return ret;
+}
+EXPORT_SYMBOL(sdmx_add_raw_pid);
+
+/*
+ * Removes the specified pid from a raw (recording) filter
+ *
+ * @session_handle: secure demux instance
+ * @filter_handle: raw filter handle
+ * @pid: pid
+ *
+ * Return error code
+ */
+int sdmx_remove_raw_pid(int session_handle, int filter_handle, u16 pid)
+{
+	int res, cmd_len, rsp_len;
+	struct sdmx_rem_raw_req *cmd;
+	struct sdmx_rem_raw_rsp *rsp;
+	enum sdmx_status ret;
+
+	if ((session_handle < 0) || (session_handle >= SDMX_MAX_SESSIONS))
+		return SDMX_STATUS_INVALID_INPUT_PARAMS;
+
+	cmd_len = sizeof(struct sdmx_rem_raw_req);
+	rsp_len = sizeof(struct sdmx_rem_raw_rsp);
+
+	/* Lock shared memory */
+	mutex_lock(&sdmx_lock[session_handle]);
+
+	/* Get command and response buffers */
+	get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
+		(void **)&rsp, &rsp_len);
+
+	/* Populate command struct */
+	cmd->cmd_id = SDMX_REMOVE_RAW_PID_CMD;
+	cmd->session_handle = session_handle;
+	cmd->filter_handle = filter_handle;
+	cmd->pid = (u32)pid;
+
+	/* Issue QSEECom command */
+	res = qseecom_send_command(sdmx_qseecom_handles[session_handle],
+		(void *)cmd, cmd_len, (void *)rsp, rsp_len);
+
+	if (res < 0) {
+		mutex_unlock(&sdmx_lock[session_handle]);
+		return SDMX_STATUS_GENERAL_FAILURE;
+	}
+
+	ret = rsp->ret;
+
+	mutex_unlock(&sdmx_lock[session_handle]);
+
+	return ret;
+}
+EXPORT_SYMBOL(sdmx_remove_raw_pid);
+
+/*
+ * Call secure demux to perform processing on the specified input buffer
+ *
+ * @session_handle: secure demux instance
+ * @flags: input flags. Currently only EOS marking is supported.
+ * @input_buf_desc: input buffer descriptor
+ * @input_fill_count: number of bytes available in input buffer
+ * @input_read_offset: offset inside input buffer where data starts
+ * @error_indicators: returned general error indicators
+ * @status_indicators: returned general status indicators
+ * @num_filters: number of filters in filter status array
+ * @filter_status: filter status descriptor array
+ *
+ * Return error code
+ */
+int sdmx_process(int session_handle, u8 flags,
+	struct sdmx_buff_descr *input_buf_desc,
+	u32 *input_fill_count,
+	u32 *input_read_offset,
+	u32 *error_indicators,
+	u32 *status_indicators,
+	u32 num_filters,
+	struct sdmx_filter_status *filter_status)
+{
+	int res, cmd_len, rsp_len;
+	struct sdmx_proc_req *cmd;
+	struct sdmx_proc_rsp *rsp;
+	enum sdmx_status ret;
+
+	if ((session_handle < 0) || (session_handle >= SDMX_MAX_SESSIONS) ||
+		(input_buf_desc == NULL) ||
+		(input_fill_count == NULL) || (input_read_offset == NULL) ||
+		(error_indicators == NULL) || (status_indicators == NULL) ||
+		(filter_status == NULL))
+		return SDMX_STATUS_INVALID_INPUT_PARAMS;
+
+	cmd_len = sizeof(struct sdmx_proc_req)
+		+ num_filters * sizeof(struct sdmx_filter_status);
+	rsp_len = sizeof(struct sdmx_proc_rsp);
+
+	/* Lock shared memory */
+	mutex_lock(&sdmx_lock[session_handle]);
+
+	/* Get command and response buffers */
+	get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
+		(void **)&rsp, &rsp_len);
+
+	/* Populate command struct */
+	cmd->cmd_id = SDMX_PROCESS_CMD;
+	cmd->session_handle = session_handle;
+	cmd->flags = flags;
+	cmd->in_buf_descr.base_addr = input_buf_desc->base_addr;
+	cmd->in_buf_descr.size = input_buf_desc->size;
+	cmd->inp_fill_cnt = *input_fill_count;
+	cmd->in_rd_offset = *input_read_offset;
+	cmd->num_filters = num_filters;
+	memcpy(cmd->filters_status, filter_status,
+		num_filters * sizeof(struct sdmx_filter_status));
+
+	/* Issue QSEECom command */
+	res = qseecom_send_command(sdmx_qseecom_handles[session_handle],
+		(void *)cmd, cmd_len, (void *)rsp, rsp_len);
+
+	if (res < 0) {
+		mutex_unlock(&sdmx_lock[session_handle]);
+		return SDMX_STATUS_GENERAL_FAILURE;
+	}
+
+	/* Parse response struct */
+	*input_fill_count = rsp->inp_fill_cnt;
+	*input_read_offset = rsp->in_rd_offset;
+	*error_indicators = rsp->err_indicators;
+	*status_indicators = rsp->status_indicators;
+	memcpy(filter_status, cmd->filters_status,
+		num_filters * sizeof(struct sdmx_filter_status));
+	ret = rsp->ret;
+
+	mutex_unlock(&sdmx_lock[session_handle]);
+
+	return ret;
+}
+EXPORT_SYMBOL(sdmx_process);
+
+/*
+ * Returns session-level & filter-level debug counters
+ *
+ * @session_handle: secure demux instance
+ * @session_counters: returned session-level debug counters
+ * @num_filters: returned number of filters reported in filter_counters
+ * @filter_counters: returned filter-level debug counters array
+ *
+ * Return error code
+ */
+int sdmx_get_dbg_counters(int session_handle,
+	struct sdmx_session_dbg_counters *session_counters,
+	u32 *num_filters,
+	struct sdmx_filter_dbg_counters *filter_counters)
+{
+	int res, cmd_len, rsp_len;
+	struct sdmx_get_counters_req *cmd;
+	struct sdmx_get_counters_rsp *rsp;
+	enum sdmx_status ret;
+
+	if ((session_handle < 0) || (session_handle >= SDMX_MAX_SESSIONS) ||
+		(session_counters == NULL) || (num_filters == NULL) ||
+		(filter_counters == NULL))
+		return SDMX_STATUS_INVALID_INPUT_PARAMS;
+
+	cmd_len = sizeof(struct sdmx_get_counters_req);
+	rsp_len = sizeof(struct sdmx_get_counters_rsp)
+		+ *num_filters * sizeof(struct sdmx_filter_dbg_counters);
+
+	/* Lock shared memory */
+	mutex_lock(&sdmx_lock[session_handle]);
+
+	/* Get command and response buffers */
+	get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
+		(void **)&rsp, &rsp_len);
+
+	/* Populate command struct */
+	cmd->cmd_id = SDMX_GET_DBG_COUNTERS_CMD;
+	cmd->session_handle = session_handle;
+	cmd->num_filters = *num_filters;
+
+	/* Issue QSEECom command */
+	res = qseecom_send_command(sdmx_qseecom_handles[session_handle],
+		(void *)cmd, cmd_len, (void *)rsp, rsp_len);
+
+	if (res < 0) {
+		mutex_unlock(&sdmx_lock[session_handle]);
+		return SDMX_STATUS_GENERAL_FAILURE;
+	}
+
+	/* Parse response struct */
+	*session_counters = rsp->session_counters;
+	*num_filters = rsp->num_filters;
+	memcpy(filter_counters, rsp->filter_counters,
+		*num_filters * sizeof(struct sdmx_filter_dbg_counters));
+	ret = rsp->ret;
+
+	mutex_unlock(&sdmx_lock[session_handle]);
+
+	return ret;
+}
+EXPORT_SYMBOL(sdmx_get_dbg_counters);
+
+/*
+ * Reset debug counters
+ *
+ * @session_handle: secure demux instance
+ *
+ * Return error code
+ */
+int sdmx_reset_dbg_counters(int session_handle)
+{
+	int res, cmd_len, rsp_len;
+	struct sdmx_rst_counters_req *cmd;
+	struct sdmx_rst_counters_rsp *rsp;
+	enum sdmx_status ret;
+
+	if ((session_handle < 0) || (session_handle >= SDMX_MAX_SESSIONS))
+		return SDMX_STATUS_INVALID_INPUT_PARAMS;
+
+	cmd_len = sizeof(struct sdmx_rst_counters_req);
+	rsp_len = sizeof(struct sdmx_rst_counters_rsp);
+
+	/* Lock shared memory */
+	mutex_lock(&sdmx_lock[session_handle]);
+
+	/* Get command and response buffers */
+	get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
+		(void **)&rsp, &rsp_len);
+
+	/* Populate command struct */
+	cmd->cmd_id = SDMX_RESET_DBG_COUNTERS_CMD;
+	cmd->session_handle = session_handle;
+
+	/* Issue QSEECom command */
+	res = qseecom_send_command(sdmx_qseecom_handles[session_handle],
+		(void *)cmd, cmd_len, (void *)rsp, rsp_len);
+
+	if (res < 0) {
+		mutex_unlock(&sdmx_lock[session_handle]);
+		return SDMX_STATUS_GENERAL_FAILURE;
+	}
+
+	ret = rsp->ret;
+
+	mutex_unlock(&sdmx_lock[session_handle]);
+
+	return ret;
+}
+EXPORT_SYMBOL(sdmx_reset_dbg_counters);
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_sdmx.h b/drivers/media/platform/msm/dvb/demux/mpq_sdmx.h
new file mode 100644
index 0000000..d292992
--- /dev/null
+++ b/drivers/media/platform/msm/dvb/demux/mpq_sdmx.h
@@ -0,0 +1,254 @@
+/* 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 _MPQ_SDMX_H
+#define _MPQ_SDMX_H
+
+#include <linux/types.h>
+
+/* Constant declarations */
+#define SDMX_MAX_SESSIONS  (4)
+#define SDMX_LOOPBACK_PID  (0x2000)
+
+/* Filter-level error indicators */
+#define SDMX_FILTER_SUCCESS                       (0)
+#define SDMX_FILTER_ERR_MD_BUF_FULL               BIT(0)
+#define SDMX_FILTER_ERR_D_BUF_FULL                BIT(1)
+#define SDMX_FILTER_ERR_D_LIN_BUFS_FULL           BIT(2)
+#define SDMX_FILTER_ERR_INVALID_SCRAMBLE_BITS     BIT(3)
+#define SDMX_FILTER_ERR_KL_IND_NOT_SET            BIT(4)
+#define SDMX_FILTER_ERR_CAS_DECRYPT_ERROR         BIT(5)
+#define SDMX_FILTER_ERR_SEC_VERIF_CRC32_FAIL      BIT(6)
+#define SDMX_FILTER_ERR_SEC_INTERNAL_MALLOC_FAIL  BIT(7)
+#define SDMX_FILTER_ERR_SEC_LEN_INVALID           BIT(8)
+#define SDMX_FILTER_ERR_SEC_PUSI_PTR_INVALID      BIT(9)
+#define SDMX_FILTER_ERR_TS_SYNC_BYTE_INVALID      BIT(10)
+#define SDMX_FILTER_ERR_TS_TRANSPORT_ERR          BIT(11)
+#define SDMX_FILTER_ERR_CONT_CNT_INVALID          BIT(12)
+#define SDMX_FILTER_ERR_CONT_CNT_DUPLICATE        BIT(13)
+#define SDMX_FILTER_ERR_INVALID_PES_HDR           BIT(14)
+#define SDMX_FILTER_ERR_INVALID_PES_LEN           BIT(15)
+#define SDMX_FILTER_ERR_INVALID_PES_ENCRYPTION    BIT(16)
+#define SDMX_FILTER_ERR_SECURITY_FAULT            BIT(17)
+#define SDMX_FILTER_ERR_IN_NS_BUFFER              BIT(18)
+
+/* Filter-level status indicators */
+#define SDMX_FILTER_STATUS_EOS                    BIT(0)
+#define SDMX_FILTER_STATUS_WR_PTR_CHANGED         BIT(1)
+
+/* Filter-level flags */
+#define SDMX_FILTER_FLAG_VERIFY_SECTION_CRC	BIT(0)
+
+#define SDMX_INVALID_SESSION_HANDLE		(-1)
+#define SDMX_INVALID_FILTER_HANDLE		(-1)
+
+/* Input flags */
+#define SDMX_INPUT_FLAG_EOS BIT(0)
+
+
+enum sdmx_buf_mode {
+	SDMX_RING_BUF,
+	SDMX_LINEAR_GROUP_BUF,
+};
+
+enum sdmx_proc_mode {
+	SDMX_PUSH_MODE,
+	SDMX_PULL_MODE,
+};
+
+enum sdmx_inp_mode {
+	SDMX_PKT_ENC_MODE,
+	SDMX_BULK_ENC_MODE,
+	SDMX_CLEAR_MODE,
+};
+
+enum sdmx_pkt_format {
+	SDMX_188_BYTE_PKT = 188,
+	SDMX_192_BYTE_PKT = 192,
+	SDMX_195_BYTE_PKT = 195,
+};
+
+enum sdmx_status {
+	SDMX_SUCCESS = 0,
+	SDMX_STATUS_GENERAL_FAILURE = -1,
+	SDMX_STATUS_MAX_OPEN_SESSIONS_REACHED = -2,
+	SDMX_STATUS_INVALID_SESSION_HANDLE = -3,
+	SDMX_STATUS_INVALID_INPUT_PARAMS = -4,
+	SDMX_STATUS_UNSUPPORTED_MODE = -5,
+	SDMX_STATUS_INVALID_PID = -6,
+	SDMX_STATUS_OUT_OF_MEM = -7,
+	SDMX_STATUS_FILTER_EXISTS = -8,
+	SDMX_STATUS_INVALID_FILTER_HANDLE = -9,
+	SDMX_STATUS_MAX_RAW_PIDS_REACHED = -10,
+	SDMX_STATUS_SINGLE_PID_RAW_FILTER = -11,
+	SDMX_STATUS_INP_BUF_INVALID_PARAMS = -12,
+	SDMX_STATUS_INVALID_FILTER_CFG = -13,
+	SDMX_STATUS_STALLED_IN_PULL_MODE = -14,
+	SDMX_STATUS_SECURITY_FAULT = -15,
+	SDMX_STATUS_NS_BUFFER_ERROR = -16,
+};
+
+enum sdmx_filter {
+	SDMX_PES_FILTER,		/* Other PES */
+	SDMX_SEPARATED_PES_FILTER,	/* Separated PES (for decoder) */
+	SDMX_SECTION_FILTER,		/* Section */
+	SDMX_PCR_FILTER,		/* PCR */
+	SDMX_RAW_FILTER,		/* Recording */
+};
+
+enum sdmx_raw_out_format {
+	SDMX_188_OUTPUT,
+	SDMX_192_HEAD_OUTPUT,
+	SDMX_192_TAIL_OUTPUT
+};
+
+struct sdmx_session_dbg_counters {
+	/* Total number of TS-packets input to SDMX. */
+	u32 ts_pkt_in;
+
+	/* Total number of TS-packets filtered out by SDMX. */
+	u32 ts_pkt_out;
+};
+
+struct sdmx_filter_dbg_counters {
+	int filter_handle;
+
+	/* Number of TS-packets filtered. */
+	u32 ts_pkt_count;
+
+	/* Number of TS-packets with adaptation field only (no payload). */
+	u32 ts_pkt_no_payload;
+
+	/* Number of TS-packets with the discontinuity indicator set. */
+	u32 ts_pkt_discont;
+
+	/* Number of duplicate TS-packets detected. */
+	u32 ts_pkt_dup;
+
+	/* Number of packets not decrypted because the key wasn't ready. */
+	u32 ts_pkt_key_not_ready;
+};
+
+struct sdmx_pes_counters {
+	/* Number of TS packets with the TEI flag set */
+	u32 transport_err_count;
+
+	/* Number of TS packets with continuity counter errors */
+	u32 continuity_err_count;
+
+	/* Number of TS packets composing this PES frame */
+	u32 pes_ts_count;
+
+	/* Number of TS packets dropped due to full buffer */
+	u32 drop_count;
+};
+
+struct sdmx_buff_descr {
+	/* Physical address where buffer starts */
+	void *base_addr;
+
+	/* Total size of buffer */
+	u32 size;
+};
+
+/*
+ * Data payload residing in the data buffers is described using this meta-data
+ * header. The meta data header specifies where the payload is located in the
+ * data buffer and how big it is.
+ * The meta data header optionally carries additional relevant meta data
+ * immediately following the meta-data header.
+ */
+struct sdmx_metadata_header {
+	/*
+	 * Payload start offset inside data buffer. In case data is managed
+	 * as a linear buffer group, this specifies buffer index.
+	 */
+	u32 payload_start;
+
+	/* Payload length */
+	u32 payload_length;
+
+	/* Total metadata length (including this header, plus optional
+	 * additional metadata.
+	 */
+	u32 metadata_length;
+};
+
+
+struct sdmx_filter_status {
+	/* Secure demux filter handle */
+	int filter_handle;
+
+	/*
+	 * Number of pending bytes in filter's output data buffer.
+	 * For linear buffer mode, this is number of buffers pending.
+	 */
+	u32 data_fill_count;
+
+	/*
+	 * Offset in data buffer for next data payload to be written.
+	 * For linear buffer mode, this is a buffer index.
+	 */
+	u32 data_write_offset;
+
+	/* Number of pending bytes in filter's output meta data buffer */
+	u32 metadata_fill_count;
+
+	/* Offset in meta data buffer for next metadata header to be written */
+	u32 metadata_write_offset;
+
+	/* Errors (bitmap) reported by secure demux for this filter */
+	u32 error_indicators;
+
+	/* General status (bitmap) reported by secure demux for this filter */
+	u32 status_indicators;
+};
+
+int sdmx_open_session(int *session_handle);
+
+int sdmx_close_session(int session_handle);
+
+int sdmx_get_version(int session_handle, int32_t *version);
+
+int sdmx_set_session_cfg(int session_handle, enum sdmx_proc_mode proc_mode,
+	enum sdmx_inp_mode inp_mode, enum sdmx_pkt_format pkt_format,
+	u8 odd_scramble_bits, u8 even_scramble_bits);
+
+int sdmx_add_filter(int session_handle, u16 pid, enum sdmx_filter filter_type,
+	struct sdmx_buff_descr *meta_data_buf, enum sdmx_buf_mode data_buf_mode,
+	u32 num_data_bufs, struct sdmx_buff_descr *data_bufs,
+	int *filter_handle, enum sdmx_raw_out_format ts_out_format, u32 flags);
+
+int sdmx_remove_filter(int session_handle, int filter_handle);
+
+int sdmx_set_kl_ind(int session_handle, u16 pid, u32 key_ladder_index);
+
+int sdmx_add_raw_pid(int session_handle, int filter_handle, u16 pid);
+
+int sdmx_remove_raw_pid(int session_handle, int filter_handle, u16 pid);
+
+int sdmx_process(int session_handle, u8 flags,
+	struct sdmx_buff_descr *input_buf_desc,
+	u32 *input_fill_count, u32 *input_read_offset,
+	u32 *error_indicators,
+	u32 *status_indicators,
+	u32 num_filters,
+	struct sdmx_filter_status *filter_status);
+
+int sdmx_get_dbg_counters(int session_handle,
+	struct sdmx_session_dbg_counters *session_counters,
+	u32 *num_filters,
+	struct sdmx_filter_dbg_counters *filter_counters);
+
+int sdmx_reset_dbg_counters(int session_handle);
+
+#endif /* _MPQ_SDMX_H */
diff --git a/drivers/media/platform/msm/dvb/include/mpq_adapter.h b/drivers/media/platform/msm/dvb/include/mpq_adapter.h
new file mode 100644
index 0000000..23121b2
--- /dev/null
+++ b/drivers/media/platform/msm/dvb/include/mpq_adapter.h
@@ -0,0 +1,193 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _MPQ_ADAPTER_H
+#define _MPQ_ADAPTER_H
+
+#include "dvbdev.h"
+#include "mpq_stream_buffer.h"
+
+
+
+/** IDs of interfaces holding stream-buffers */
+enum mpq_adapter_stream_if {
+	/** Interface holding stream-buffer for video0 stream */
+	MPQ_ADAPTER_VIDEO0_STREAM_IF = 0,
+
+	/** Interface holding stream-buffer for video1 stream */
+	MPQ_ADAPTER_VIDEO1_STREAM_IF = 1,
+
+	/** Interface holding stream-buffer for video1 stream */
+	MPQ_ADAPTER_VIDEO2_STREAM_IF = 2,
+
+	/** Interface holding stream-buffer for video1 stream */
+	MPQ_ADAPTER_VIDEO3_STREAM_IF = 3,
+
+	/** Maximum number of interfaces holding stream-buffers */
+	MPQ_ADAPTER_MAX_NUM_OF_INTERFACES,
+};
+
+
+enum dmx_framing_pattern_type {
+	/* MPEG-2 */
+	DMX_FRM_MPEG2_SEQUENCE_HEADER,
+	DMX_FRM_MPEG2_GOP_HEADER,
+	DMX_FRM_MPEG2_I_PIC,
+	DMX_FRM_MPEG2_P_PIC,
+	DMX_FRM_MPEG2_B_PIC,
+	/* H.264 */
+	DMX_FRM_H264_SPS,
+	DMX_FRM_H264_PPS,
+	/* H.264 First Coded slice of an IDR Picture */
+	DMX_FRM_H264_IDR_PIC,
+	/* H.264 First Coded slice of a non-IDR Picture */
+	DMX_FRM_H264_NON_IDR_PIC,
+	/* VC-1 Sequence Header*/
+	DMX_FRM_VC1_SEQUENCE_HEADER,
+	/* VC-1 Entry Point Header (Advanced Profile only) */
+	DMX_FRM_VC1_ENTRY_POINT_HEADER,
+	/* VC-1 Frame Start Code */
+	DMX_FRM_VC1_FRAME_START_CODE,
+	/* Unknown or invalid framing information */
+	DMX_FRM_UNKNOWN
+};
+
+enum dmx_packet_type {
+	DMX_PADDING_PACKET,
+	DMX_PES_PACKET,
+	DMX_FRAMING_INFO_PACKET,
+	DMX_EOS_PACKET
+};
+
+struct dmx_pts_dts_info {
+	/** Indication whether PTS exist */
+	int pts_exist;
+
+	/** Indication whether DTS exist */
+	int dts_exist;
+
+	/** PTS value associated with the PES data if any */
+	u64 pts;
+
+	/** DTS value associated with the PES data if any */
+	u64 dts;
+};
+
+struct dmx_framing_packet_info {
+	/** framing pattern type */
+	enum dmx_framing_pattern_type pattern_type;
+	/** PTS/DTS information */
+	struct dmx_pts_dts_info pts_dts_info;
+};
+
+struct dmx_pes_packet_info {
+	/** PTS/DTS information */
+	struct dmx_pts_dts_info pts_dts_info;
+};
+
+/** The meta-data used for video interface */
+struct mpq_adapter_video_meta_data {
+	/** meta-data packet type */
+	enum dmx_packet_type packet_type;
+
+	/** packet-type specific information */
+	union {
+		struct dmx_framing_packet_info framing;
+		struct dmx_pes_packet_info pes;
+	} info;
+} __packed;
+
+
+/** Callback function to notify on registrations of specific interfaces */
+typedef void (*mpq_adapter_stream_if_callback)(
+				enum mpq_adapter_stream_if interface_id,
+				void *user_param);
+
+
+/**
+ * mpq_adapter_get - Returns pointer to Qualcomm DVB adapter
+ *
+ * Return     dvb adapter or NULL if not exist.
+ */
+struct dvb_adapter *mpq_adapter_get(void);
+
+
+/**
+ * mpq_adapter_register_stream_if - Register a stream interface.
+ *
+ * @interface_id: The interface id
+ * @stream_buffer: The buffer used for the interface
+ *
+ * Return     error status
+ *
+ * Stream interface used to connect between two units in tunneling
+ * mode using mpq_streambuffer implementation.
+ * The producer of the interface should register the new interface,
+ * consumer may get the interface using mpq_adapter_get_stream_if.
+ *
+ * Note that the function holds a pointer to this interface,
+ * stream_buffer pointer assumed to be valid as long as interface
+ * is active.
+ */
+int mpq_adapter_register_stream_if(
+		enum mpq_adapter_stream_if interface_id,
+		struct mpq_streambuffer *stream_buffer);
+
+
+/**
+ * mpq_adapter_unregister_stream_if - Un-register a stream interface.
+ *
+ * @interface_id: The interface id
+ *
+ * Return     error status
+ */
+int mpq_adapter_unregister_stream_if(
+		enum mpq_adapter_stream_if interface_id);
+
+
+/**
+ * mpq_adapter_get_stream_if - Get buffer used for a stream interface.
+ *
+ * @interface_id: The interface id
+ * @stream_buffer: The returned stream buffer
+ *
+ * Return     error status
+ */
+int mpq_adapter_get_stream_if(
+		enum mpq_adapter_stream_if interface_id,
+		struct mpq_streambuffer **stream_buffer);
+
+
+/**
+ * mpq_adapter_notify_stream_if - Register notification
+ * to be triggered when a stream interface is registered.
+ *
+ * @interface_id: The interface id
+ * @callback: The callback to be triggered when the interface is registered
+ * @user_param: A parameter that is passed back to the callback function
+ *				when triggered.
+ *
+ * Return     error status
+ *
+ * Producer may use this to register notification when desired
+ * interface registered in the system and query its information
+ * afterwards using mpq_adapter_get_stream_if.
+ * To remove the callback, this function should be called with NULL
+ * value in callback parameter.
+ */
+int mpq_adapter_notify_stream_if(
+		enum mpq_adapter_stream_if interface_id,
+		mpq_adapter_stream_if_callback callback,
+		void *user_param);
+
+#endif /* _MPQ_ADAPTER_H */
+
diff --git a/drivers/media/platform/msm/dvb/include/mpq_dvb_debug.h b/drivers/media/platform/msm/dvb/include/mpq_dvb_debug.h
new file mode 100644
index 0000000..0b00b71
--- /dev/null
+++ b/drivers/media/platform/msm/dvb/include/mpq_dvb_debug.h
@@ -0,0 +1,38 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _MPQ_DVB_DEBUG_H
+#define _MPQ_DVB_DEBUG_H
+
+/* Enable this line if you want to output debug printouts */
+#define MPG_DVB_DEBUG_ENABLE
+
+#undef MPQ_DVB_DBG_PRINT		/* undef it, just in case */
+
+#ifdef MPG_DVB_DEBUG_ENABLE
+#define MPQ_DVB_DBG_PRINT(fmt, args...) pr_debug(fmt, ## args)
+#define MPQ_DVB_ERR_PRINT(fmt, args...) pr_err(fmt, ## args)
+#else  /* MPG_DVB_DEBUG_ENABLE */
+#define MPQ_DVB_DBG_PRINT(fmt, args...)
+#define MPQ_DVB_ERR_PRINT(fmt, args...)
+#endif /* MPG_DVB_DEBUG_ENABLE */
+
+
+/*
+ * The following can be used to disable specific printout
+ * by adding a letter to the end of MPQ_DVB_DBG_PRINT
+ */
+#undef MPQ_DVB_DBG_PRINTT
+#define MPQ_DVB_DBG_PRINTT(fmt, args...)
+
+#endif /* _MPQ_DVB_DEBUG_H */
+
diff --git a/drivers/media/platform/msm/dvb/include/mpq_stream_buffer.h b/drivers/media/platform/msm/dvb/include/mpq_stream_buffer.h
new file mode 100644
index 0000000..3804fb2
--- /dev/null
+++ b/drivers/media/platform/msm/dvb/include/mpq_stream_buffer.h
@@ -0,0 +1,433 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _MPQ_STREAM_BUFFER_H
+#define _MPQ_STREAM_BUFFER_H
+
+#include "dvb_ringbuffer.h"
+
+
+/**
+ * DOC: MPQ Stream Buffer
+ *
+ * A stream buffer implementation is used to transfer data between two units
+ * such as demux and decoders. The implementation relies on dvb_ringbuffer
+ * implementation. Refer to dvb_ringbuffer.h for details.
+ *
+ * The implementation uses two dvb_ringbuffers, one to pass the
+ * raw-data (PES payload for example) and the other to pass
+ * meta-data (information from PES header for example).
+ *
+ * The meta-data uses dvb_ringbuffer packet interface. Each meta-data
+ * packet points to the data buffer, and includes the offset to the data in the
+ * buffer, the size of raw-data described by the meta-data packet, and also the
+ * size of user's own parameters if any required.
+ *
+ * Data can be managed in two ways: ring-buffer & linear buffers, as specified
+ * in initialization when calling the mpq_streambuffer_init function.
+ * For managing data as a ring buffer exactly 1 data buffer descriptor must be
+ * specified in initialization. For this mode, dvb_ringbuffer is used "as-is".
+ * For managing data in several linear buffers, an array of buffer descriptors
+ * must be passed.
+ * For both modes, data descriptor(s) must be remain valid throughout the life
+ * span of the mpq_streambuffer object.
+ * Apart from initialization API remains the same for both modes.
+ *
+ * Contrary to dvb_ringbuffer implementation, this API makes sure there's
+ * enough data to read/write when making read/write operations.
+ * Users interested to flush/reset specific buffer, check for bytes
+ * ready or space available for write should use the respective services
+ * in dvb_ringbuffer (dvb_ringbuffer_avail, dvb_ringbuffer_free,
+ * dvb_ringbuffer_reset, dvb_ringbuffer_flush,
+ * dvb_ringbuffer_flush_spinlock_wakeup).
+ *
+ * Concurrency protection is handled in the same manner as in
+ * dvb_ringbuffer implementation.
+ *
+ * Typical call flow from producer:
+ *
+ * - Start writing the raw-data of new packet, the following call is
+ *   repeated until end of data of the specific packet
+ *
+ *      mpq_streambuffer_data_write(...)
+ *
+ * - Now write a new packet describing the new available raw-data
+ *      mpq_streambuffer_pkt_write(...)
+ *
+ *   For linear buffer mode, writing a new packet with data size > 0, causes the
+ *   current buffer to be marked as pending for reading, and triggers moving to
+ *   the next available buffer, that shall now be the current write buffer.
+ *
+ * Typical call flow from consumer:
+ *
+ * - Poll for next available packet:
+ *      mpq_streambuffer_pkt_next(&streambuff,-1,&len)
+ *
+ *   In different approach, consumer can wait on event for new data and then
+ *   call mpq_streambuffer_pkt_next, waiting for data can be done as follows:
+ *
+ *      wait_event_interruptible(
+ *			streambuff->packet_data->queue,
+ *			!dvb_ringbuffer_empty(&streambuff->packet_data) ||
+ *			(streambuff->packet_data.error != 0);
+ *
+ * - Get the new packet information:
+ *      mpq_streambuffer_pkt_read(..)
+ *
+ * - Read the raw-data of the new packet. Here you can use two methods:
+ *
+ *   1. Read the data to a user supplied buffer:
+ *         mpq_streambuffer_data_read()
+ *
+ *      In this case memory copy is done, read pointer is updated in the raw
+ *      data buffer, the amount of raw-data is provided part of the
+ *      packet's information. User should then call mpq_streambuffer_pkt_dispose
+ *      with dispose_data set to 0 as the raw-data was already disposed.
+ *      Note that secure buffer cannot be accessed directly and an error will
+ *      occur.
+ *
+ *   2. Access the data directly using the raw-data address. The address
+ *      of the raw data is provided part of the packet's information. User
+ *      then should call mpq_streambuffer_pkt_dispose with dispose_data set
+ *      to 1 to dispose the packet along with it's raw-data.
+ *
+ * - Disposal of packets:
+ *      mpq_streambuffer_pkt_dispose(...)
+ *
+ *   For linear buffer mode, disposing of a packet with data size > 0, causes
+ *   the current buffer to be marked as free for writing, and triggers moving to
+ *   the next available buffer, that shall now be the current read buffer.
+
+ *
+ */
+
+struct mpq_streambuffer;
+
+typedef void (*mpq_streambuffer_pkt_dispose_cb) (
+	struct mpq_streambuffer *sbuff,
+	void *user_data);
+
+enum mpq_streambuffer_mode {
+	MPQ_STREAMBUFFER_BUFFER_MODE_RING,
+	MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR
+};
+
+/**
+ * struct mpq_streambuffer - mpq stream buffer representation
+ *
+ * @raw_data: The buffer used to hold raw-data, or linear buffer descriptors
+ * @packet_data: The buffer user to hold the meta-data
+ * @buffers: array of buffer descriptor(s) holding buffer initial & dynamic
+ *	     buffer information
+ * @mode: mpq_streambuffer buffer management work mode - Ring-buffer or Linear
+ *	  buffers
+ * @buffers_num: number of data buffers to manage
+ * @pending_buffers_count: for linear buffer management, counts the number of
+ * buffer that has been
+ */
+struct mpq_streambuffer {
+	struct dvb_ringbuffer raw_data;
+	struct dvb_ringbuffer packet_data;
+	struct mpq_streambuffer_buffer_desc *buffers;
+	enum mpq_streambuffer_mode mode;
+	u32 buffers_num;
+	u32 pending_buffers_count;
+	mpq_streambuffer_pkt_dispose_cb cb;
+	void *cb_user_data;
+};
+
+/**
+ * mpq_streambuffer_linear_desc
+ * @handle:	ION handle's file descriptor of buffer
+ * @base:	kernel mapped address to start of buffer.
+ *		Can be NULL for secured buffers
+ * @size:	size of buffer
+ * @read_ptr:	initial read pointer value (should normally be 0)
+ * @write_ptr:	initial write pointer value (should normally be 0)
+ */
+struct mpq_streambuffer_buffer_desc {
+	int	handle;
+	void	*base;
+	u32	size;
+	u32	read_ptr;
+	u32	write_ptr;
+};
+
+/**
+ * struct mpq_streambuffer_packet_header - packet header saved in packet buffer
+ * @user_data_len: length of private user (meta) data
+ * @raw_data_handle: ION handle's file descriptor of raw-data buffer
+ * @raw_data_offset: offset of raw-data from start of buffer (0 for linear)
+ * @raw_data_len: size of raw-data in the raw-data buffer (can be 0)
+ *
+ * The packet structure that is saved in each packet-buffer:
+ * user_data_len
+ * raw_data_handle
+ * raw_data_offset
+ * raw_data_len
+ * private user-data bytes
+ */
+struct mpq_streambuffer_packet_header {
+	u32 user_data_len;
+	int raw_data_handle;
+	u32 raw_data_offset;
+	u32 raw_data_len;
+} __packed;
+
+/**
+ * mpq_streambuffer_init - Initialize a new stream buffer
+ *
+ * @sbuff: The buffer to initialize
+ * @data_buffers: array of data buffer descriptor(s).
+ *		  Data descriptor(s) must be remain valid throughout the life
+ *		  span of the mpq_streambuffer object
+ * @data_buff_num: number of data buffer in array
+ * @packet_buff: The buffer holding meta-data
+ * @packet_buff_size: Size of meta-data buffer
+ *
+ * Return	Error status, -EINVAL if any of the arguments are invalid
+ *
+ * Note:
+ * for data_buff_num > 1, mpq_streambuffer object manages these buffers as a
+ * separated set of linear buffers. A linear buffer cannot wrap-around and one
+ * can only write as many data bytes as the buffer's size. Data will not be
+ * written to the next free buffer.
+ */
+int mpq_streambuffer_init(
+		struct mpq_streambuffer *sbuff,
+		enum mpq_streambuffer_mode mode,
+		struct mpq_streambuffer_buffer_desc *data_buffers,
+		u32 data_buff_num,
+		void *packet_buff,
+		size_t packet_buff_size);
+
+/**
+ * mpq_streambuffer_packet_next - Returns index of next available packet.
+ *
+ * @sbuff: The stream buffer
+ * @idx: Previous packet index or -1 to return index of the the first
+ *       available packet.
+ * @pktlen: The length of the ready packet
+ *
+ * Return index to the packet-buffer, -1 if buffer is empty
+ *
+ * After getting the index, the user of this function can either
+ * access the packet buffer directly using the returned index
+ * or ask to read the data back from the buffer using mpq_ringbuffer_pkt_read
+ */
+ssize_t mpq_streambuffer_pkt_next(
+		struct mpq_streambuffer *sbuff,
+		ssize_t idx, size_t *pktlen);
+
+/**
+ * mpq_streambuffer_pkt_read - Reads out the packet from the provided index.
+ *
+ * @sbuff: The stream buffer
+ * @idx: The index of the packet to be read
+ * @packet: The read packet's header
+ * @user_data: The read private user data
+ *
+ * Return  The actual number of bytes read, -EINVAL if the packet is
+ * already disposed or the packet-data is invalid.
+ *
+ * The packet is not disposed after this function is called, to dispose it
+ * along with the raw-data it points to use mpq_streambuffer_pkt_dispose.
+ * If there are no private user-data, the user-data pointer can be NULL.
+ * The caller of this function must make sure that the private user-data
+ * buffer has enough space for the private user-data length
+ */
+ssize_t mpq_streambuffer_pkt_read(
+		struct mpq_streambuffer *sbuff,
+		size_t idx,
+		struct mpq_streambuffer_packet_header *packet,
+		u8 *user_data);
+
+/**
+ * mpq_streambuffer_pkt_dispose - Disposes a packet from the packet buffer
+ *
+ * @sbuff: The stream buffer
+ * @idx: The index of the packet to be disposed
+ * @dispose_data: Indicates whether to update the read pointer inside the
+ * raw-data buffer for the respective data pointed by the packet.
+ *
+ * Return  error status, -EINVAL if the packet-data is invalid
+ *
+ * The function updates the read pointer inside the raw-data buffer
+ * for the respective data pointed by the packet if dispose_data is set.
+ */
+int mpq_streambuffer_pkt_dispose(
+		struct mpq_streambuffer *sbuff,
+		size_t idx,
+		int dispose_data);
+
+/**
+ * mpq_streambuffer_pkt_write - Write a new packet to the packet buffer.
+ *
+ * @sbuff: The stream buffer
+ * @packet: The packet header to write
+ * @user_data: The private user-data to be written
+ *
+ * Return  error status, -ENOSPC if there's no space to write the packet
+ */
+int mpq_streambuffer_pkt_write(
+		struct mpq_streambuffer *sbuff,
+		struct mpq_streambuffer_packet_header *packet,
+		u8 *user_data);
+
+/**
+ * mpq_streambuffer_data_write - Write data to raw-data buffer
+ *
+ * @sbuff: The stream buffer
+ * @buf: The buffer holding the data to be written
+ * @len: The length of the data buffer
+ *
+ * Return  The actual number of bytes written or -ENOSPC if
+ *			no space to write the data
+ */
+ssize_t mpq_streambuffer_data_write(
+		struct mpq_streambuffer *sbuff,
+		const u8 *buf, size_t len);
+
+/**
+ * mpq_streambuffer_data_write_deposit - Advances the raw-buffer write pointer.
+ * Assumes the raw-data was written by the user directly
+ *
+ * @sbuff: The stream buffer
+ * @len: The length of the raw-data that was already written
+ *
+ * Return  error status
+ */
+int mpq_streambuffer_data_write_deposit(
+		struct mpq_streambuffer *sbuff,
+		size_t len);
+
+/**
+ * mpq_streambuffer_data_read - Reads out raw-data to the provided buffer.
+ *
+ * @sbuff: The stream buffer
+ * @buf: The buffer to read the raw-data data to
+ * @len: The length of the buffer that will hold the raw-data
+ *
+ * Return  The actual number of bytes read or error code
+ *
+ * This function copies the data from the ring-buffer to the
+ * provided buf parameter. The user can save the extra copy by accessing
+ * the data pointer directly and reading from it, then update the
+ * read pointer by the amount of data that was read using
+ * mpq_streambuffer_data_read_dispose
+ */
+ssize_t mpq_streambuffer_data_read(
+		struct mpq_streambuffer *sbuff,
+		u8 *buf, size_t len);
+
+/**
+ * mpq_streambuffer_data_read_user
+ *
+ * Same as mpq_streambuffer_data_read except data can be copied to user-space
+ * buffer.
+ */
+ssize_t mpq_streambuffer_data_read_user(
+		struct mpq_streambuffer *sbuff,
+		u8 __user *buf, size_t len);
+
+/**
+ * mpq_streambuffer_data_read_dispose - Advances the raw-buffer read pointer.
+ * Assumes the raw-data was read by the user directly.
+ *
+ * @sbuff: The stream buffer
+ * @len: The length of the raw-data to be disposed
+ *
+ * Return  error status, -EINVAL if buffer there's no enough data to
+ *			be disposed
+ *
+ * The user can instead dispose a packet along with the data in the
+ * raw-data buffer using mpq_streambuffer_pkt_dispose.
+ */
+int mpq_streambuffer_data_read_dispose(
+		struct mpq_streambuffer *sbuff,
+		size_t len);
+/**
+ * mpq_streambuffer_get_buffer_handle - Returns the current linear buffer
+ * ION handle.
+ * @sbuff: The stream buffer
+ * @read_buffer: specifies if a read buffer handle is requested (when set),
+ *		 or a write buffer handle is requested.
+ *		 For linear buffer mode read & write buffers may be different
+ *		 buffers. For ring buffer mode, the same (single) buffer handle
+ *		 is returned.
+ * buffer handle
+ * @handle: returned handle
+ *
+ * Return error status
+ * -EINVAL is arguments are invalid.
+ * -EPERM if stream buffer specified was not initialized with linear support.
+ */
+int mpq_streambuffer_get_buffer_handle(
+	struct mpq_streambuffer *sbuff,
+	int read_buffer,
+	int *handle);
+
+/**
+ * mpq_streambuffer_data_free - Returns number of free bytes in data buffer.
+ * @sbuff: The stream buffer object
+ *
+ * Note: for linear buffer management this return number of free bytes in the
+ * current write buffer only.
+ */
+ssize_t mpq_streambuffer_data_free(
+	struct mpq_streambuffer *sbuff);
+
+/**
+ * mpq_streambuffer_data_avail - Returns number of bytes in data buffer that
+ * can be read.
+ * @sbuff: The stream buffer object
+ *
+ * Note: for linear buffer management this return number of data bytes in the
+ * current read buffer only.
+ */
+ssize_t mpq_streambuffer_data_avail(
+	struct mpq_streambuffer *sbuff);
+
+/**
+ * mpq_streambuffer_register_pkt_dispose - Registers a callback to notify on
+ * packet disposal events.
+ * can be read.
+ * @sbuff: The stream buffer object
+ * @cb_func: user callback function
+ * @user_data: user data to be passed to callback function.
+ *
+ * Returns error status
+ * -EINVAL if arguments are invalid
+ */
+int mpq_streambuffer_register_pkt_dispose(
+	struct mpq_streambuffer *sbuff,
+	mpq_streambuffer_pkt_dispose_cb cb_func,
+	void *user_data);
+
+/**
+ * mpq_streambuffer_data_rw_offset - returns read/write offsets of current data
+ * buffer.
+ * @sbuff: The stream buffer object
+ * @read_offset: returned read offset
+ * @write_offset: returned write offset
+ *
+ * Note: read offset or write offset may be NULL if not required.
+ * Returns error status
+ * -EINVAL if arguments are invalid
+ */
+int mpq_streambuffer_get_data_rw_offset(
+	struct mpq_streambuffer *sbuff,
+	u32 *read_offset,
+	u32 *write_offset);
+
+#endif /* _MPQ_STREAM_BUFFER_H */
+
diff --git a/drivers/media/dvb/mpq/video/Kconfig b/drivers/media/platform/msm/dvb/video/Kconfig
similarity index 100%
rename from drivers/media/dvb/mpq/video/Kconfig
rename to drivers/media/platform/msm/dvb/video/Kconfig
diff --git a/drivers/media/platform/msm/dvb/video/Makefile b/drivers/media/platform/msm/dvb/video/Makefile
new file mode 100644
index 0000000..7a5ecf4
--- /dev/null
+++ b/drivers/media/platform/msm/dvb/video/Makefile
@@ -0,0 +1,5 @@
+
+ccflags-y += -Idrivers/media/dvb/dvb-core/
+ccflags-y += -Idrivers/media/platform/msm/dvb/include/
+
+obj-$(CONFIG_DVB_MPQ_VIDEO) += mpq_dvb_video.o
diff --git a/drivers/media/platform/msm/dvb/video/mpq_dvb_video.c b/drivers/media/platform/msm/dvb/video/mpq_dvb_video.c
new file mode 100644
index 0000000..46002c3
--- /dev/null
+++ b/drivers/media/platform/msm/dvb/video/mpq_dvb_video.c
@@ -0,0 +1,2467 @@
+/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/firmware.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/poll.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/kthread.h>
+#include <linux/uaccess.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+#include <linux/android_pmem.h>
+#include <linux/clk.h>
+#include <linux/timer.h>
+#include <mach/msm_subsystem_map.h>
+#include <media/msm/vidc_type.h>
+#include <media/msm/vcd_api.h>
+#include <media/msm/vidc_init.h>
+#include "mpq_dvb_video_internal.h"
+
+
+#define DBG(x...) pr_debug(x)
+#define INFO(x...) pr_info(x)
+#define ERR(x...) pr_err(x)
+
+#define MPQ_VID_DEC_NAME "mpq_vidc_dec"
+static unsigned int vidc_mmu_subsystem[] = {
+	MSM_SUBSYSTEM_VIDEO};
+
+static char vid_thread_names[DVB_MPQ_NUM_VIDEO_DEVICES][10] = {
+				"dvb-vid-0",
+				"dvb-vid-1",
+				"dvb-vid-2",
+				"dvb-vid-3",
+};
+
+static enum scan_format map_scan_type(enum vdec_interlaced_format type);
+static int mpq_int_vid_dec_decode_frame(struct video_client_ctx *client_ctx,
+				struct video_data_buffer *input_frame);
+static int mpq_int_vid_dec_get_buffer_req(struct video_client_ctx *client_ctx,
+				  struct video_buffer_req *vdec_buf_req);
+
+static struct mpq_dvb_video_dev *mpq_dvb_video_device;
+
+static int mpq_get_dev_frm_client(struct video_client_ctx *client_ctx,
+				struct mpq_dvb_video_inst **dev_inst)
+{
+	int i;
+
+	for (i = 0; i < DVB_MPQ_NUM_VIDEO_DEVICES; i++) {
+		if (mpq_dvb_video_device->dev_inst[i].client_ctx ==
+						client_ctx) {
+			*dev_inst = &mpq_dvb_video_device->dev_inst[i];
+			break;
+		}
+	}
+
+	if (i == DVB_MPQ_NUM_VIDEO_DEVICES)
+		return -ENODEV;
+
+	return 0;
+}
+
+static u32 mpq_int_check_bcast_mq(struct mpq_dmx_src_data *dmx_data)
+{
+	u32 islist_empty = 0;
+	mutex_lock(&dmx_data->msg_queue_lock);
+	islist_empty = list_empty(&dmx_data->msg_queue);
+	mutex_unlock(&dmx_data->msg_queue_lock);
+
+	return !islist_empty;
+}
+
+static void mpq_get_frame_and_write(struct mpq_dvb_video_inst *dev_inst,
+				unsigned int free_buf)
+{
+	struct mpq_dmx_src_data *dmx_data = dev_inst->dmx_src_data;
+	struct mpq_streambuffer *streambuff = dmx_data->stream_buffer;
+	struct mpq_streambuffer_packet_header pkt_hdr;
+	struct mpq_adapter_video_meta_data meta_data;
+	ssize_t indx = -1;
+	ssize_t bytes_read = 0;
+	size_t pktlen = 0;
+	int frame_found = true;
+	unsigned long kernel_vaddr, phy_addr, user_vaddr;
+	int pmem_fd;
+	struct file *file;
+	s32 buffer_index = -1;
+	size_t size = 0;
+
+	do {
+		wait_event_interruptible(streambuff->packet_data.queue,
+			(!dvb_ringbuffer_empty(&streambuff->packet_data) ||
+			streambuff->packet_data.error != 0) ||
+			kthread_should_stop());
+
+		if (kthread_should_stop()) {
+			DBG("STOP signal Received\n");
+			return;
+		}
+
+		DBG("Received Free Buffer : %d\n", free_buf);
+
+		indx = mpq_streambuffer_pkt_next(streambuff, -1, &pktlen);
+
+		if (-1 == indx) {
+			DBG("Invalid Index -1\n");
+			return;
+		}
+
+		bytes_read = mpq_streambuffer_pkt_read(streambuff, indx,
+			&pkt_hdr, (u8 *)&meta_data);
+
+		switch (meta_data.packet_type) {
+		case DMX_FRAMING_INFO_PACKET:
+			switch (meta_data.info.framing.pattern_type) {
+			case DMX_FRM_H264_SPS:
+			case DMX_FRM_MPEG2_SEQUENCE_HEADER:
+			case DMX_FRM_VC1_SEQUENCE_HEADER:
+				DBG("SPS FOUND\n");
+				frame_found = false;
+				break;
+			case DMX_FRM_H264_PPS:
+			case DMX_FRM_MPEG2_GOP_HEADER:
+			case DMX_FRM_VC1_ENTRY_POINT_HEADER:
+				DBG("PPS FOUND\n");
+				frame_found = false;
+				break;
+			case DMX_FRM_H264_IDR_PIC:
+			case DMX_FRM_H264_NON_IDR_PIC:
+			case DMX_FRM_MPEG2_I_PIC:
+			case DMX_FRM_MPEG2_P_PIC:
+			case DMX_FRM_MPEG2_B_PIC:
+			case DMX_FRM_VC1_FRAME_START_CODE:
+				DBG("FRAME FOUND\n");
+				frame_found = true;
+				break;
+			default:
+				break;
+			}
+			user_vaddr = (unsigned long)
+				dmx_data->in_buffer[free_buf].bufferaddr;
+			vidc_lookup_addr_table(dev_inst->client_ctx,
+				BUFFER_TYPE_INPUT, true, &user_vaddr,
+				&kernel_vaddr,	&phy_addr, &pmem_fd, &file,
+				&buffer_index);
+			bytes_read = 0;
+			bytes_read = mpq_streambuffer_data_read(streambuff,
+						(u8 *)(kernel_vaddr + size),
+						pkt_hdr.raw_data_len);
+			DBG("Data Read : %d from Packet Size : %d\n",
+				bytes_read, pkt_hdr.raw_data_len);
+			mpq_streambuffer_pkt_dispose(streambuff, indx, 0);
+			size +=	pkt_hdr.raw_data_len;
+			dmx_data->in_buffer[free_buf].pts =
+			(meta_data.info.framing.pts_dts_info.pts_exist) ?
+			(meta_data.info.framing.pts_dts_info.pts) : 0;
+			if (frame_found) {
+				dmx_data->in_buffer[free_buf].buffer_len =
+									size;
+				dmx_data->in_buffer[free_buf].client_data =
+							(void *)free_buf;
+				DBG("Size of Data Submitted : %d\n", size);
+				mpq_int_vid_dec_decode_frame(
+						dev_inst->client_ctx,
+						&dmx_data->in_buffer[free_buf]);
+			}
+			break;
+		case DMX_EOS_PACKET:
+			break;
+		case DMX_PES_PACKET:
+		case DMX_PADDING_PACKET:
+			break;
+		}
+	} while (!frame_found);
+
+}
+
+static int mpq_bcast_data_handler(void *arg)
+{
+	struct mpq_dvb_video_inst *dev_inst = arg;
+	struct mpq_dmx_src_data *dmx_data = dev_inst->dmx_src_data;
+	struct mpq_bcast_msg *pMesg;
+	struct mpq_bcast_msg_info msg = {0};
+
+	do {
+		wait_event_interruptible(dmx_data->msg_wait,
+					((dmx_data->stream_buffer != NULL) &&
+					mpq_int_check_bcast_mq(dmx_data)) ||
+					kthread_should_stop());
+
+		if (kthread_should_stop()) {
+			DBG("STOP signal Received\n");
+			break;
+		}
+
+		mutex_lock(&dmx_data->msg_queue_lock);
+		if (!list_empty(&dmx_data->msg_queue)) {
+			pMesg = list_first_entry(&dmx_data->msg_queue,
+					struct mpq_bcast_msg, list);
+			list_del(&pMesg->list);
+			memcpy(&msg, &pMesg->info,
+				sizeof(struct mpq_bcast_msg_info));
+			kfree(pMesg);
+		}
+		mutex_unlock(&dmx_data->msg_queue_lock);
+
+		switch (msg.code) {
+		case MPQ_BCAST_MSG_IBD:
+			DBG("Received IBD Mesg for :%d\n", msg.data);
+			mpq_get_frame_and_write(dev_inst, msg.data);
+			break;
+		default:
+			DBG("Received Mesg : %d\n", msg.code);
+		}
+	} while (1);
+
+	return 0;
+}
+
+static s32 mpq_int_vid_dec_get_empty_client_index(void)
+{
+	u32 i, found = false;
+
+	for (i = 0; i < VIDC_MAX_NUM_CLIENTS; i++) {
+		if (!mpq_dvb_video_device->vdec_clients[i].vcd_handle) {
+			found = true;
+			break;
+		}
+	}
+	if (!found) {
+		ERR("%s():ERROR No space for new client\n", __func__);
+		return -ENOMEM;
+	} else {
+		DBG("%s(): available client index = %u\n", __func__, i);
+		return i;
+	}
+}
+
+static u32 mpq_int_vid_dec_get_status(u32 status)
+{
+	u32 vdec_status;
+
+	switch (status) {
+	case VCD_ERR_SEQHDR_PARSE_FAIL:
+	case VCD_ERR_BITSTREAM_ERR:
+		vdec_status = VIDEO_STATUS_BITSTREAM_ERROR;
+		break;
+	case VCD_S_SUCCESS:
+		vdec_status = VIDEO_STATUS_SUCESS;
+		break;
+	case VCD_ERR_FAIL:
+		vdec_status = VIDEO_STATUS_FAILED;
+		break;
+	case VCD_ERR_ALLOC_FAIL:
+	case VCD_ERR_MAX_CLIENT:
+		vdec_status = VIDEO_STATUS_NORESOURCE;
+		break;
+	case VCD_ERR_ILLEGAL_OP:
+		vdec_status = VIDEO_STATUS_INVALID_CMD;
+		break;
+	case VCD_ERR_ILLEGAL_PARM:
+		vdec_status = VIDEO_STATUS_INVALID_PARAM;
+		break;
+	case VCD_ERR_BAD_POINTER:
+	case VCD_ERR_BAD_HANDLE:
+		vdec_status = VIDEO_STATUS_INVALID_HANDLE;
+		break;
+	case VCD_ERR_NOT_SUPPORTED:
+		vdec_status = VIDEO_STATUS_NO_SUPPORT;
+		break;
+	case VCD_ERR_BAD_STATE:
+		vdec_status = VIDEO_STATUS_INVALID_STATE;
+		break;
+	case VCD_ERR_BUSY:
+		vdec_status = VIDEO_STATUS_BUSY;
+		break;
+	default:
+		vdec_status = VIDEO_STATUS_FAILED;
+		break;
+	}
+
+	return vdec_status;
+}
+
+static void mpq_int_vid_dec_notify_client(struct video_client_ctx *client_ctx)
+{
+	if (client_ctx)
+		complete(&client_ctx->event);
+}
+
+static void mpq_int_vid_dec_vcd_open_done(struct video_client_ctx *client_ctx,
+			   struct vcd_handle_container *handle_container)
+{
+	if (client_ctx) {
+		if (handle_container)
+			client_ctx->vcd_handle = handle_container->handle;
+		else
+			DBG("%s(): ERROR. handle_container is NULL\n",
+			    __func__);
+
+		mpq_int_vid_dec_notify_client(client_ctx);
+	} else
+		DBG("%s(): ERROR. client_ctx is NULL\n", __func__);
+}
+
+static void mpq_int_vid_dec_handle_field_drop(
+	struct video_client_ctx *client_ctx,
+	u32 event, u32 status, int64_t time_stamp)
+{
+	struct vid_dec_msg *vdec_msg;
+
+	if (!client_ctx) {
+		DBG("%s() NULL pointer\n", __func__);
+		return;
+	}
+
+	vdec_msg = kzalloc(sizeof(struct vid_dec_msg), GFP_KERNEL);
+	if (!vdec_msg) {
+		DBG("%s(): cannot allocate vid_dec_msg "\
+			" buffer\n", __func__);
+		return;
+	}
+	vdec_msg->vdec_msg_info.status_code =
+		mpq_int_vid_dec_get_status(status);
+	if (event == VCD_EVT_IND_INFO_FIELD_DROPPED) {
+		vdec_msg->vdec_msg_info.msgcode =
+			VDEC_MSG_EVT_INFO_FIELD_DROPPED;
+		vdec_msg->vdec_msg_info.msgdata.output_frame.time_stamp
+		= time_stamp;
+		DBG("Send FIELD_DROPPED message to client = %p\n",
+						client_ctx);
+	} else {
+		DBG("mpq_int_vid_dec_input_frame_done(): "\
+			"invalid event type: %d\n", event);
+		vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_INVALID;
+	}
+	vdec_msg->vdec_msg_info.msgdatasize =
+		sizeof(struct vdec_output_frameinfo);
+	mutex_lock(&client_ctx->msg_queue_lock);
+	list_add_tail(&vdec_msg->list, &client_ctx->msg_queue);
+	mutex_unlock(&client_ctx->msg_queue_lock);
+	wake_up(&client_ctx->msg_wait);
+}
+
+static void mpq_int_vid_dec_input_frame_done(
+			struct video_client_ctx *client_ctx, u32 event,
+			u32 status, struct vcd_frame_data *vcd_frame_data)
+{
+	struct vid_dec_msg *vdec_msg;
+	struct mpq_bcast_msg *bcast_msg;
+	struct mpq_dvb_video_inst *dev_inst;
+	struct mpq_dmx_src_data *dmx_data;
+	int rc = 0;
+
+	if (!client_ctx || !vcd_frame_data) {
+		DBG("mpq_int_vid_dec_input_frame_done() NULL pointer\n");
+		return;
+	}
+
+	kfree(vcd_frame_data->desc_buf);
+	vcd_frame_data->desc_buf = NULL;
+	vcd_frame_data->desc_size = 0;
+
+	rc = mpq_get_dev_frm_client(client_ctx, &dev_inst);
+	if (rc) {
+		DBG("Failed to obtain device instance\n");
+		return;
+	}
+
+	if (dev_inst->source == VIDEO_SOURCE_MEMORY) {
+		vdec_msg = kzalloc(sizeof(struct vid_dec_msg), GFP_KERNEL);
+		if (!vdec_msg) {
+			DBG("mpq_int_vid_dec_input_frame_done(): "\
+			"cannot allocate vid_dec_msg buffer\n");
+			return;
+		}
+
+		vdec_msg->vdec_msg_info.status_code =
+				mpq_int_vid_dec_get_status(status);
+
+		if (event == VCD_EVT_RESP_INPUT_DONE) {
+			vdec_msg->vdec_msg_info.msgcode =
+			VDEC_MSG_RESP_INPUT_BUFFER_DONE;
+			DBG("Send INPUT_DON message to client = %p\n",
+						client_ctx);
+
+		} else if (event == VCD_EVT_RESP_INPUT_FLUSHED) {
+			vdec_msg->vdec_msg_info.msgcode =
+					VDEC_MSG_RESP_INPUT_FLUSHED;
+			DBG("Send INPUT_FLUSHED message to client = %p\n",
+						client_ctx);
+		} else {
+			DBG("mpq_int_vid_dec_input_frame_done(): "\
+				"invalid event type: %d\n", event);
+			vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_INVALID;
+		}
+
+		vdec_msg->vdec_msg_info.msgdata.input_frame_clientdata =
+			(void *)vcd_frame_data->frm_clnt_data;
+		vdec_msg->vdec_msg_info.msgdatasize = sizeof(void *);
+
+		mutex_lock(&client_ctx->msg_queue_lock);
+		list_add_tail(&vdec_msg->list, &client_ctx->msg_queue);
+		mutex_unlock(&client_ctx->msg_queue_lock);
+		wake_up(&client_ctx->msg_wait);
+	} else {
+		if (event == VCD_EVT_RESP_INPUT_DONE) {
+			bcast_msg = kzalloc(sizeof(struct mpq_bcast_msg),
+						GFP_KERNEL);
+			if (!bcast_msg) {
+				DBG("mpq_int_vid_dec_input_frame_done(): "\
+				"cannot allocate mpq_bcast_msg buffer\n");
+				return;
+			}
+
+			bcast_msg->info.code = MPQ_BCAST_MSG_IBD;
+			bcast_msg->info.data =
+				(unsigned int)vcd_frame_data->frm_clnt_data;
+
+			dmx_data = dev_inst->dmx_src_data;
+
+			mutex_lock(&dmx_data->msg_queue_lock);
+			list_add_tail(&bcast_msg->list, &dmx_data->msg_queue);
+			mutex_unlock(&dmx_data->msg_queue_lock);
+			wake_up(&dmx_data->msg_wait);
+		}
+	}
+}
+
+static void mpq_int_vid_dec_output_frame_done(
+			struct video_client_ctx *client_ctx,
+			u32 event, u32 status,
+			struct vcd_frame_data *vcd_frame_data)
+{
+	struct vid_dec_msg *vdec_msg;
+
+	unsigned long kernel_vaddr = 0, phy_addr = 0, user_vaddr = 0;
+	int pmem_fd;
+	struct file *file;
+	s32 buffer_index = -1;
+	enum vdec_picture pic_type;
+	u32 ion_flag = 0;
+	struct ion_handle *buff_handle = NULL;
+	struct vdec_output_frameinfo  *output_frame;
+
+	if (!client_ctx || !vcd_frame_data) {
+		DBG("mpq_int_vid_dec_input_frame_done() NULL pointer\n");
+		return;
+	}
+
+	vdec_msg = kzalloc(sizeof(struct vid_dec_msg), GFP_KERNEL);
+	if (!vdec_msg) {
+		DBG("mpq_int_vid_dec_input_frame_done(): "\
+		    "cannot allocate vid_dec_msg buffer\n");
+		return;
+	}
+
+	vdec_msg->vdec_msg_info.status_code =
+			mpq_int_vid_dec_get_status(status);
+
+	if (event == VCD_EVT_RESP_OUTPUT_DONE)
+		vdec_msg->vdec_msg_info.msgcode =
+		    VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
+	else if (event == VCD_EVT_RESP_OUTPUT_FLUSHED)
+		vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_OUTPUT_FLUSHED;
+	else {
+		DBG("QVD: mpq_int_vid_dec_output_frame_done"\
+			"invalid cmd type : %d\n", event);
+		vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_INVALID;
+	}
+
+	kernel_vaddr = (unsigned long)vcd_frame_data->virtual;
+
+	if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT,
+				      false, &user_vaddr, &kernel_vaddr,
+				      &phy_addr, &pmem_fd, &file,
+				      &buffer_index) ||
+		(vcd_frame_data->flags & VCD_FRAME_FLAG_EOS)) {
+		/* Buffer address in user space */
+		vdec_msg->vdec_msg_info.msgdata.output_frame.bufferaddr =
+		    (u8 *) user_vaddr;
+		/* Data length */
+		vdec_msg->vdec_msg_info.msgdata.output_frame.len =
+		    vcd_frame_data->data_len;
+		vdec_msg->vdec_msg_info.msgdata.output_frame.flags =
+		    vcd_frame_data->flags;
+		/* Timestamp pass-through from input frame */
+		vdec_msg->vdec_msg_info.msgdata.output_frame.time_stamp =
+		    vcd_frame_data->time_stamp;
+		/* Output frame client data */
+		vdec_msg->vdec_msg_info.msgdata.output_frame.client_data =
+		    (void *)vcd_frame_data->frm_clnt_data;
+		/* Associated input frame client data */
+		vdec_msg->vdec_msg_info.msgdata.output_frame.
+		    input_frame_clientdata =
+		    (void *)vcd_frame_data->ip_frm_tag;
+		/* Decoded picture width and height */
+		vdec_msg->vdec_msg_info.msgdata.output_frame.framesize.
+		bottom =
+		    vcd_frame_data->dec_op_prop.disp_frm.bottom;
+		vdec_msg->vdec_msg_info.msgdata.output_frame.framesize.left =
+		    vcd_frame_data->dec_op_prop.disp_frm.left;
+		vdec_msg->vdec_msg_info.msgdata.output_frame.framesize.right =
+			vcd_frame_data->dec_op_prop.disp_frm.right;
+		vdec_msg->vdec_msg_info.msgdata.output_frame.framesize.top =
+			vcd_frame_data->dec_op_prop.disp_frm.top;
+		if (vcd_frame_data->interlaced) {
+			vdec_msg->vdec_msg_info.msgdata.
+				output_frame.interlaced_format =
+				VDEC_InterlaceInterleaveFrameTopFieldFirst;
+		} else {
+			vdec_msg->vdec_msg_info.msgdata.
+				output_frame.interlaced_format =
+				VDEC_InterlaceFrameProgressive;
+		}
+		/* Decoded picture type */
+		switch (vcd_frame_data->frame) {
+		case VCD_FRAME_I:
+			pic_type = PICTURE_TYPE_I;
+			break;
+		case VCD_FRAME_P:
+			pic_type = PICTURE_TYPE_P;
+			break;
+		case VCD_FRAME_B:
+			pic_type = PICTURE_TYPE_B;
+			break;
+		case VCD_FRAME_NOTCODED:
+			pic_type = PICTURE_TYPE_SKIP;
+			break;
+		case VCD_FRAME_IDR:
+			pic_type = PICTURE_TYPE_IDR;
+			break;
+		default:
+			pic_type = PICTURE_TYPE_UNKNOWN;
+		}
+		vdec_msg->vdec_msg_info.msgdata.output_frame.pic_type =
+			pic_type;
+		output_frame = &vdec_msg->vdec_msg_info.msgdata.output_frame;
+		output_frame->aspect_ratio_info.aspect_ratio =
+			vcd_frame_data->aspect_ratio_info.aspect_ratio;
+		output_frame->aspect_ratio_info.par_width =
+			vcd_frame_data->aspect_ratio_info.par_width;
+		output_frame->aspect_ratio_info.par_height =
+			vcd_frame_data->aspect_ratio_info.par_height;
+		vdec_msg->vdec_msg_info.msgdatasize =
+		    sizeof(struct vdec_output_frameinfo);
+	} else {
+		DBG("mpq_int_vid_dec_output_frame_done UVA"\
+				"can not be found\n");
+		vdec_msg->vdec_msg_info.status_code = VDEC_S_EFATAL;
+	}
+	if (vcd_frame_data->data_len > 0) {
+		ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_OUTPUT,
+				pmem_fd, kernel_vaddr, buffer_index,
+				&buff_handle);
+		if (ion_flag == ION_FLAG_CACHED && buff_handle) {
+			msm_ion_do_cache_op(
+				client_ctx->user_ion_client,
+				buff_handle,
+				(unsigned long *) kernel_vaddr,
+				(unsigned long)vcd_frame_data->data_len,
+				ION_IOC_INV_CACHES);
+		}
+	}
+	mutex_lock(&client_ctx->msg_queue_lock);
+	list_add_tail(&vdec_msg->list, &client_ctx->msg_queue);
+	mutex_unlock(&client_ctx->msg_queue_lock);
+	wake_up(&client_ctx->msg_wait);
+}
+
+static void mpq_int_vid_dec_lean_event(struct video_client_ctx *client_ctx,
+			       u32 event, u32 status)
+{
+	struct vid_dec_msg *vdec_msg;
+
+	if (!client_ctx) {
+		DBG("%s(): !client_ctx pointer\n", __func__);
+		return;
+	}
+
+	vdec_msg = kzalloc(sizeof(struct vid_dec_msg), GFP_KERNEL);
+	if (!vdec_msg) {
+		DBG("%s(): cannot allocate vid_dec_msg buffer\n",
+					__func__);
+		return;
+	}
+
+	vdec_msg->vdec_msg_info.status_code =
+			mpq_int_vid_dec_get_status(status);
+
+	switch (event) {
+	case VCD_EVT_IND_OUTPUT_RECONFIG:
+		DBG("msm_vidc_dec: Sending VDEC_MSG_EVT_CONFIG_CHANGED"\
+			 " to client");
+		vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_EVT_CONFIG_CHANGED;
+		break;
+	case VCD_EVT_IND_RESOURCES_LOST:
+		DBG("msm_vidc_dec: Sending VDEC_EVT_RESOURCES_LOST"\
+			 " to client");
+		vdec_msg->vdec_msg_info.msgcode = VDEC_EVT_RESOURCES_LOST;
+		break;
+	case VCD_EVT_RESP_FLUSH_INPUT_DONE:
+		DBG("msm_vidc_dec: Sending VDEC_MSG_RESP_FLUSH_INPUT_DONE"\
+			 " to client");
+		vdec_msg->vdec_msg_info.msgcode =
+		    VDEC_MSG_RESP_FLUSH_INPUT_DONE;
+		break;
+	case VCD_EVT_RESP_FLUSH_OUTPUT_DONE:
+		DBG("msm_vidc_dec: Sending VDEC_MSG_RESP_FLUSH_OUTPUT_DONE"\
+			 " to client");
+		vdec_msg->vdec_msg_info.msgcode =
+		    VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
+		break;
+	case VCD_EVT_IND_HWERRFATAL:
+		DBG("msm_vidc_dec: Sending VDEC_MSG_EVT_HW_ERROR"\
+			 " to client");
+		vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_EVT_HW_ERROR;
+		break;
+	case VCD_EVT_RESP_START:
+		DBG("msm_vidc_dec: Sending VDEC_MSG_RESP_START_DONE"\
+			 " to client");
+		vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_START_DONE;
+		break;
+	case VCD_EVT_RESP_STOP:
+		DBG("msm_vidc_dec: Sending VDEC_MSG_RESP_STOP_DONE"\
+			 " to client");
+		vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_STOP_DONE;
+		break;
+	case VCD_EVT_RESP_PAUSE:
+		DBG("msm_vidc_dec: Sending VDEC_MSG_RESP_PAUSE_DONE"\
+			 " to client");
+		vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_PAUSE_DONE;
+		break;
+	case VCD_EVT_IND_INFO_OUTPUT_RECONFIG:
+		DBG("msm_vidc_dec: Sending VDEC_MSG_EVT_INFO_CONFIG_CHANGED"\
+			 " to client");
+		vdec_msg->vdec_msg_info.msgcode =
+			 VDEC_MSG_EVT_INFO_CONFIG_CHANGED;
+		break;
+	default:
+		DBG("%s() : unknown event type\n", __func__);
+		break;
+	}
+
+	vdec_msg->vdec_msg_info.msgdatasize = 0;
+	if (client_ctx->stop_sync_cb &&
+	   (event == VCD_EVT_RESP_STOP || event == VCD_EVT_IND_HWERRFATAL)) {
+		client_ctx->stop_sync_cb = false;
+		complete(&client_ctx->event);
+		kfree(vdec_msg);
+		return;
+	}
+	mutex_lock(&client_ctx->msg_queue_lock);
+	list_add_tail(&vdec_msg->list, &client_ctx->msg_queue);
+	mutex_unlock(&client_ctx->msg_queue_lock);
+	wake_up(&client_ctx->msg_wait);
+}
+
+static void mpq_int_state_play(struct video_client_ctx *client_ctx,
+			       u32 event, u32 status)
+{
+	struct mpq_bcast_msg *bcast_msg;
+	struct mpq_dvb_video_inst *dev_inst;
+	int i;
+	int rc = 0;
+	struct mpq_dmx_src_data *dmx_data = NULL;
+
+	if (!client_ctx->seq_header_set) {
+		rc = mpq_get_dev_frm_client(client_ctx, &dev_inst);
+		if (rc) {
+			DBG("Failed to get dev_instance in %s\n", __func__);
+			return;
+		}
+
+		if (VIDEO_SOURCE_DEMUX == dev_inst->source) {
+			dmx_data = dev_inst->dmx_src_data;
+			for (i = 0; i < DVB_VID_NUM_IN_BUFFERS; i++) {
+				bcast_msg = kzalloc(
+						sizeof(struct mpq_bcast_msg),
+						GFP_KERNEL);
+				if (!bcast_msg) {
+					DBG("cannot allocate mpq_bcast_msg"\
+						"buffer\n");
+					return;
+				}
+
+				bcast_msg->info.code = MPQ_BCAST_MSG_IBD;
+				bcast_msg->info.data = (unsigned int)i;
+
+				mutex_lock(&dmx_data->msg_queue_lock);
+				list_add_tail(&bcast_msg->list,
+						&dmx_data->msg_queue);
+				mutex_unlock(&dmx_data->msg_queue_lock);
+				wake_up(&dmx_data->msg_wait);
+			}
+		}
+		mpq_int_vid_dec_lean_event(client_ctx, event, status);
+	} else
+		mpq_int_vid_dec_notify_client(client_ctx);
+
+}
+
+static void mpq_int_vid_dec_vcd_cb(u32 event, u32 status,
+		   void *info, size_t sz, void *handle,
+		   void *const client_data)
+{
+	struct video_client_ctx *client_ctx = client_data;
+
+	DBG("Entering %s()\n", __func__);
+
+	if (!client_ctx) {
+		DBG("%s(): client_ctx is NULL\n", __func__);
+		return;
+	}
+
+	client_ctx->event_status = status;
+
+	switch (event) {
+	case VCD_EVT_RESP_OPEN:
+		mpq_int_vid_dec_vcd_open_done(client_ctx,
+				      (struct vcd_handle_container *)
+				      info);
+		break;
+	case VCD_EVT_RESP_INPUT_DONE:
+	case VCD_EVT_RESP_INPUT_FLUSHED:
+		mpq_int_vid_dec_input_frame_done(client_ctx, event, status,
+					 (struct vcd_frame_data *)info);
+		break;
+	case VCD_EVT_IND_INFO_FIELD_DROPPED:
+		if (info)
+			mpq_int_vid_dec_handle_field_drop(client_ctx, event,
+			status,	*((int64_t *)info));
+		else
+			DBG("Wrong Payload for Field dropped\n");
+		break;
+	case VCD_EVT_RESP_OUTPUT_DONE:
+	case VCD_EVT_RESP_OUTPUT_FLUSHED:
+		mpq_int_vid_dec_output_frame_done(client_ctx, event, status,
+					  (struct vcd_frame_data *)info);
+		break;
+	case VCD_EVT_RESP_PAUSE:
+	case VCD_EVT_RESP_STOP:
+	case VCD_EVT_RESP_FLUSH_INPUT_DONE:
+	case VCD_EVT_RESP_FLUSH_OUTPUT_DONE:
+	case VCD_EVT_IND_OUTPUT_RECONFIG:
+	case VCD_EVT_IND_HWERRFATAL:
+	case VCD_EVT_IND_RESOURCES_LOST:
+	case VCD_EVT_IND_INFO_OUTPUT_RECONFIG:
+		mpq_int_vid_dec_lean_event(client_ctx, event, status);
+		break;
+	case VCD_EVT_RESP_START:
+		mpq_int_state_play(client_ctx, event, status);
+		break;
+	default:
+		DBG("%s() :  Error - Invalid event type =%u\n", __func__,
+		    event);
+		break;
+	}
+}
+
+static int mpq_int_vid_dec_set_cont_on_reconfig(
+			struct video_client_ctx *client_ctx)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	u32 vcd_status = VCD_ERR_FAIL;
+	u32 enable = true;
+	if (!client_ctx)
+		return -EINVAL;
+	vcd_property_hdr.prop_id = VCD_I_CONT_ON_RECONFIG;
+	vcd_property_hdr.sz = sizeof(u32);
+	vcd_status = vcd_set_property(client_ctx->vcd_handle,
+		&vcd_property_hdr, &enable);
+	if (vcd_status)
+		return -EIO;
+	return 0;
+}
+
+static int mpq_int_vid_dec_set_frame_resolution(
+				struct video_client_ctx *client_ctx,
+				struct vdec_picsize *video_resoultion)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_frame_size frame_resolution;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx || !video_resoultion)
+		return -EINVAL;
+
+	vcd_property_hdr.prop_id = VCD_I_FRAME_SIZE;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_frame_size);
+	frame_resolution.width = video_resoultion->frame_width;
+	frame_resolution.height = video_resoultion->frame_height;
+	frame_resolution.stride = video_resoultion->stride;
+	frame_resolution.scan_lines = video_resoultion->scan_lines;
+
+	vcd_status = vcd_set_property(client_ctx->vcd_handle,
+				      &vcd_property_hdr, &frame_resolution);
+
+	if (vcd_status)
+		return -EIO;
+	else
+		return 0;
+}
+
+static int mpq_int_set_out_buffer_req(struct video_client_ctx *client_ctx,
+					struct video_buffer_req *vdec_buf_req)
+{
+	struct vcd_buffer_requirement buffer_req;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	buffer_req.actual_count = vdec_buf_req->num_output_buffers;
+	buffer_req.align = vdec_buf_req->output_buf_prop.alignment;
+	buffer_req.max_count = vdec_buf_req->num_output_buffers;
+	buffer_req.min_count = vdec_buf_req->num_output_buffers;
+	buffer_req.sz = vdec_buf_req->output_buf_prop.buf_size;
+
+	vcd_status = vcd_set_buffer_requirements(client_ctx->vcd_handle,
+			VCD_BUFFER_OUTPUT, &buffer_req);
+	if (vcd_status)
+		return -EFAULT;
+	else
+		return 0;
+}
+
+static int mpq_int_set_full_hd_frame_resolution(
+				struct video_client_ctx *client_ctx)
+{
+	struct vdec_picsize pic_res;
+	int rc;
+
+	pic_res.frame_height = 1080;
+	pic_res.frame_width  = 1920;
+	pic_res.scan_lines   = 1080;
+	pic_res.stride       = 1920;
+
+	rc = mpq_int_vid_dec_set_frame_resolution(client_ctx,
+						&pic_res);
+	if (rc)
+		DBG("Failed in mpq_int_vid_dec_set_frame_resolution : %d\n",\
+			rc);
+
+	rc = mpq_int_vid_dec_set_cont_on_reconfig(client_ctx);
+	if (rc)
+		DBG("Failed in mpq_int_vid_dec_set_cont_on_reconfig : %d\n",\
+			rc);
+
+	return rc;
+
+}
+
+static int mpq_int_vid_dec_get_frame_resolution(
+			struct video_client_ctx *client_ctx,
+			struct video_pic_res *video_resoultion)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_frame_size frame_resolution;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx || !video_resoultion)
+		return -EINVAL;
+
+	vcd_property_hdr.prop_id = VCD_I_FRAME_SIZE;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_frame_size);
+
+	vcd_status = vcd_get_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &frame_resolution);
+
+	video_resoultion->width  = frame_resolution.width;
+	video_resoultion->height = frame_resolution.height;
+	video_resoultion->scan_lines = frame_resolution.scan_lines;
+	video_resoultion->stride = frame_resolution.stride;
+
+	if (vcd_status)
+		return -EINVAL;
+	else
+		return 0;
+}
+
+static int mpq_int_vid_dec_get_codec(struct video_client_ctx *client_ctx,
+					enum video_codec_t *video_codec)
+{
+	unsigned int result = 0;
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_codec codec;
+
+	if ((client_ctx == NULL) || (video_codec == NULL))
+		return -EINVAL;
+
+	vcd_property_hdr.prop_id = VCD_I_CODEC;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
+
+	result = vcd_get_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &codec);
+	if (result)
+		return -EINVAL;
+
+	switch (codec.codec) {
+	case VCD_CODEC_MPEG4:
+		*video_codec = VIDEO_CODECTYPE_MPEG4;
+		break;
+	case VCD_CODEC_H264:
+		*video_codec = VIDEO_CODECTYPE_H264;
+		break;
+	case VCD_CODEC_MPEG2:
+		*video_codec = VIDEO_CODECTYPE_MPEG2;
+		break;
+	case VCD_CODEC_VC1:
+		*video_codec = VIDEO_CODECTYPE_VC1;
+		break;
+	default:
+		*video_codec = VIDEO_CODECTYPE_NONE;
+		break;
+	}
+
+	return result;
+}
+
+static int mpq_int_vid_dec_set_codec(struct video_client_ctx *client_ctx,
+				enum video_codec_t video_codec)
+{
+	unsigned int result = 0;
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_codec codec;
+	unsigned int vcd_status = VCD_ERR_FAIL;
+
+	if (client_ctx == NULL)
+		return -EINVAL;
+
+	vcd_property_hdr.prop_id = VCD_I_CODEC;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
+
+	switch (video_codec) {
+	case VIDEO_CODECTYPE_MPEG4:
+		codec.codec = VCD_CODEC_MPEG4;
+		break;
+	case VIDEO_CODECTYPE_H264:
+		codec.codec = VCD_CODEC_H264;
+		break;
+	case VIDEO_CODECTYPE_MPEG2:
+		codec.codec = VCD_CODEC_MPEG2;
+		break;
+	case VIDEO_CODECTYPE_VC1:
+		codec.codec = VCD_CODEC_VC1;
+		break;
+	default:
+		result = -EINVAL;
+		break;
+	}
+
+	if (!result) {
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+					      &vcd_property_hdr, &codec);
+		if (vcd_status)
+			result = -EINVAL;
+	}
+
+	result = mpq_int_set_full_hd_frame_resolution(client_ctx);
+
+	return result;
+}
+
+static int mpq_int_vid_dec_set_output_format(
+		struct video_client_ctx *client_ctx,
+		enum video_out_format_t format)
+{
+	unsigned int result = 0;
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_buffer_format vcd_prop_buffer_format;
+	unsigned int vcd_status = VCD_ERR_FAIL;
+
+	if (client_ctx == NULL)
+		return -EINVAL;
+
+	vcd_property_hdr.prop_id = VCD_I_BUFFER_FORMAT;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_format);
+
+	switch (format) {
+	case VIDEO_YUV_FORMAT_NV12:
+		vcd_prop_buffer_format.buffer_format = VCD_BUFFER_FORMAT_NV12;
+		break;
+	case VIDEO_YUV_FORMAT_TILE_4x2:
+		vcd_prop_buffer_format.buffer_format =
+					VCD_BUFFER_FORMAT_TILE_4x2;
+		break;
+	default:
+		result = -EINVAL;
+		break;
+	}
+
+	if (!result)
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+					      &vcd_property_hdr,
+					      &vcd_prop_buffer_format);
+
+	if (vcd_status)
+		return -EINVAL;
+
+	return 0;
+
+}
+
+static int mpq_int_vid_dec_get_output_format(
+			struct video_client_ctx *client_ctx,
+			enum video_out_format_t *format)
+{
+	unsigned int result = 0;
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_buffer_format vcd_prop_buffer_format;
+
+	if ((client_ctx == NULL) || (format == NULL))
+		return -EINVAL;
+
+	vcd_property_hdr.prop_id = VCD_I_BUFFER_FORMAT;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_format);
+
+	result = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
+					&vcd_prop_buffer_format);
+
+	if (result)
+		return -EINVAL;
+
+	switch (vcd_prop_buffer_format.buffer_format) {
+	case VCD_BUFFER_FORMAT_NV12:
+		*format = VIDEO_YUV_FORMAT_NV12;
+		break;
+	case VCD_BUFFER_FORMAT_TILE_4x2:
+		*format = VIDEO_YUV_FORMAT_TILE_4x2;
+		break;
+	default:
+		result = -EINVAL;
+		break;
+	}
+
+	return result;
+}
+
+static int mpq_int_vid_dec_set_h264_mv_buffers(
+				struct video_client_ctx *client_ctx,
+				struct video_h264_mv *mv_data)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_h264_mv_buffer *vcd_h264_mv_buffer = NULL;
+	struct msm_mapped_buffer *mapped_buffer = NULL;
+	u32 vcd_status = VCD_ERR_FAIL;
+	u32 len = 0, flags = 0;
+	struct file *file;
+	int rc = 0;
+	unsigned long ionflag = 0;
+	unsigned long buffer_size = 0;
+	unsigned long iova = 0;
+
+	if (!client_ctx || !mv_data)
+		return -EINVAL;
+
+	vcd_property_hdr.prop_id = VCD_I_H264_MV_BUFFER;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_h264_mv_buffer);
+	vcd_h264_mv_buffer = &client_ctx->vcd_h264_mv_buffer;
+
+	memset(&client_ctx->vcd_h264_mv_buffer, 0,
+		   sizeof(struct vcd_property_h264_mv_buffer));
+	vcd_h264_mv_buffer->size = mv_data->size;
+	vcd_h264_mv_buffer->count = mv_data->count;
+	vcd_h264_mv_buffer->pmem_fd = mv_data->ion_fd;
+	vcd_h264_mv_buffer->offset = mv_data->offset;
+
+	if (!vcd_get_ion_status()) {
+		if (get_pmem_file(vcd_h264_mv_buffer->pmem_fd,
+			(unsigned long *) (&(vcd_h264_mv_buffer->
+			physical_addr)),
+			(unsigned long *) (&vcd_h264_mv_buffer->
+						kernel_virtual_addr),
+			(unsigned long *) (&len), &file)) {
+			ERR("%s(): get_pmem_file failed\n", __func__);
+			return -EIO;
+		}
+		put_pmem_file(file);
+		flags = MSM_SUBSYSTEM_MAP_IOVA;
+		mapped_buffer = msm_subsystem_map_buffer(
+			(unsigned long)vcd_h264_mv_buffer->physical_addr, len,
+				flags, vidc_mmu_subsystem,
+				sizeof(vidc_mmu_subsystem)/
+				sizeof(unsigned int));
+		if (IS_ERR(mapped_buffer)) {
+			ERR("buffer map failed");
+			return PTR_ERR(mapped_buffer);
+		}
+		vcd_h264_mv_buffer->client_data = (void *) mapped_buffer;
+		vcd_h264_mv_buffer->dev_addr = (u8 *)mapped_buffer->iova[0];
+	} else {
+		client_ctx->h264_mv_ion_handle = ion_import_dma_buf(
+					client_ctx->user_ion_client,
+					vcd_h264_mv_buffer->pmem_fd);
+		if (IS_ERR_OR_NULL(client_ctx->h264_mv_ion_handle)) {
+			DBG("%s(): get_ION_handle failed\n", __func__);
+			goto import_ion_error;
+		}
+		rc = ion_handle_get_flags(client_ctx->user_ion_client,
+					client_ctx->h264_mv_ion_handle,
+					&ionflag);
+		if (rc) {
+			DBG("%s():get_ION_flags fail\n",
+					 __func__);
+			goto import_ion_error;
+		}
+		vcd_h264_mv_buffer->kernel_virtual_addr =
+			(u8 *) ion_map_kernel(client_ctx->user_ion_client,
+					client_ctx->h264_mv_ion_handle);
+		if (!vcd_h264_mv_buffer->kernel_virtual_addr) {
+			DBG("%s(): get_ION_kernel virtual addr failed\n",
+				 __func__);
+			goto import_ion_error;
+		}
+
+		rc = ion_map_iommu(client_ctx->user_ion_client,
+				client_ctx->h264_mv_ion_handle,
+				VIDEO_DOMAIN, VIDEO_MAIN_POOL,
+				SZ_4K, 0, (unsigned long *)&iova,
+				(unsigned long *)&buffer_size,
+				0, 0);
+		if (rc) {
+			DBG("%s():get_ION_kernel physical addr fail\n",
+						 __func__);
+			goto ion_map_error;
+		}
+		vcd_h264_mv_buffer->physical_addr = (u8 *) iova;
+		vcd_h264_mv_buffer->client_data = NULL;
+		vcd_h264_mv_buffer->dev_addr = (u8 *) iova;
+
+	}
+	DBG("Virt: %p, Phys %p, fd: %d", vcd_h264_mv_buffer->
+		kernel_virtual_addr, vcd_h264_mv_buffer->physical_addr,
+		vcd_h264_mv_buffer->pmem_fd);
+	DBG("Dev addr %p", vcd_h264_mv_buffer->dev_addr);
+	vcd_status = vcd_set_property(client_ctx->vcd_handle,
+				      &vcd_property_hdr, vcd_h264_mv_buffer);
+
+	if (vcd_status)
+		return -EIO;
+	else
+		return 0;
+ion_map_error:
+	if (vcd_h264_mv_buffer->kernel_virtual_addr) {
+		ion_unmap_kernel(client_ctx->user_ion_client,
+				client_ctx->h264_mv_ion_handle);
+		vcd_h264_mv_buffer->kernel_virtual_addr = NULL;
+	}
+	if (!IS_ERR_OR_NULL(client_ctx->h264_mv_ion_handle)) {
+		ion_free(client_ctx->user_ion_client,
+			client_ctx->h264_mv_ion_handle);
+		 client_ctx->h264_mv_ion_handle = NULL;
+	}
+import_ion_error:
+	return -EIO;
+}
+
+static int mpq_int_vid_dec_get_h264_mv_buffer_size(
+				struct video_client_ctx *client_ctx,
+				struct video_mv_buff_size *mv_buff)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_buffer_size h264_mv_buffer_size;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx || !mv_buff)
+		return -EINVAL;
+
+	vcd_property_hdr.prop_id = VCD_I_GET_H264_MV_SIZE;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size);
+
+	h264_mv_buffer_size.width = mv_buff->width;
+	h264_mv_buffer_size.height = mv_buff->height;
+
+	vcd_status = vcd_get_property(client_ctx->vcd_handle,
+				      &vcd_property_hdr, &h264_mv_buffer_size);
+
+	mv_buff->width = h264_mv_buffer_size.width;
+	mv_buff->height = h264_mv_buffer_size.height;
+	mv_buff->size = h264_mv_buffer_size.size;
+	mv_buff->alignment = h264_mv_buffer_size.alignment;
+
+	if (vcd_status)
+		return -EIO;
+	else
+		return 0;
+}
+
+static int mpq_int_vid_dec_free_h264_mv_buffers(
+				struct video_client_ctx *client_ctx)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_buffer_size h264_mv_buffer_size;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx)
+		return -EINVAL;
+	if (client_ctx->vcd_h264_mv_buffer.client_data)
+		msm_subsystem_unmap_buffer((struct msm_mapped_buffer *)
+		client_ctx->vcd_h264_mv_buffer.client_data);
+
+	vcd_property_hdr.prop_id = VCD_I_FREE_H264_MV_BUFFER;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size);
+
+	vcd_status = vcd_set_property(client_ctx->vcd_handle,
+				      &vcd_property_hdr, &h264_mv_buffer_size);
+
+	if (!IS_ERR_OR_NULL(client_ctx->h264_mv_ion_handle)) {
+		ion_unmap_kernel(client_ctx->user_ion_client,
+					client_ctx->h264_mv_ion_handle);
+		ion_unmap_iommu(client_ctx->user_ion_client,
+				client_ctx->h264_mv_ion_handle,
+				VIDEO_DOMAIN,
+				VIDEO_MAIN_POOL);
+		ion_free(client_ctx->user_ion_client,
+					client_ctx->h264_mv_ion_handle);
+		 client_ctx->h264_mv_ion_handle = NULL;
+	}
+
+	if (vcd_status)
+		return -EIO;
+	else
+		return 0;
+}
+
+
+static int mpq_int_vid_dec_get_buffer_req(struct video_client_ctx *client_ctx,
+				  struct video_buffer_req *vdec_buf_req)
+{
+	u32 vcd_status = VCD_ERR_FAIL;
+	struct vcd_buffer_requirement vcd_buf_req;
+
+	if (!client_ctx || !vdec_buf_req)
+		return -EINVAL;
+
+	vcd_status = vcd_get_buffer_requirements(client_ctx->vcd_handle,
+					VCD_BUFFER_INPUT, &vcd_buf_req);
+
+	if (vcd_status)
+		return -EINVAL;
+
+	vdec_buf_req->input_buf_prop.alignment  = vcd_buf_req.align;
+	vdec_buf_req->input_buf_prop.buf_poolid = vcd_buf_req.buf_pool_id;
+	vdec_buf_req->input_buf_prop.buf_size   = vcd_buf_req.sz;
+	vdec_buf_req->num_input_buffers         = vcd_buf_req.actual_count;
+
+	vcd_status = vcd_get_buffer_requirements(client_ctx->vcd_handle,
+					VCD_BUFFER_OUTPUT, &vcd_buf_req);
+
+	if (vcd_status)
+		return -EINVAL;
+
+	vdec_buf_req->output_buf_prop.alignment  = vcd_buf_req.align;
+	vdec_buf_req->output_buf_prop.buf_poolid = vcd_buf_req.buf_pool_id;
+	vdec_buf_req->output_buf_prop.buf_size   = vcd_buf_req.sz;
+	vdec_buf_req->num_output_buffers         = vcd_buf_req.actual_count;
+
+	return 0;
+}
+
+static int mpq_int_vid_dec_set_buffer_req(struct video_client_ctx *client_ctx,
+				  struct video_buffer_req vdec_buf_req)
+{
+	int rc = 0;
+	struct video_buffer_req vdec_req;
+
+	rc = mpq_int_vid_dec_get_buffer_req(client_ctx, &vdec_req);
+	if (rc)
+		DBG("Failed in mpq_int_vid_dec_get_buffer_req : %d\n", rc);
+
+	vdec_req.num_output_buffers = vdec_buf_req.num_output_buffers;
+	DBG(" num_output_buffers Set to %u\n", vdec_buf_req.num_output_buffers);
+	if (!vdec_buf_req.num_output_buffers)
+		return -EINVAL;
+	rc = mpq_int_set_out_buffer_req(client_ctx, &vdec_req);
+	if (rc)
+		DBG("Failed in mpq_int_set_out_buffer_req  %d\n", rc);
+
+	return 0;
+}
+
+static int mpq_int_vid_dec_set_buffer(struct mpq_dvb_video_inst *dev_inst,
+			      struct video_data_buffer *data_buffer,
+			      enum buffer_dir dir_buffer)
+{
+	struct video_client_ctx *client_ctx =
+		(struct video_client_ctx *)dev_inst->client_ctx;
+	enum vcd_buffer_type buffer = VCD_BUFFER_INPUT;
+	u32 vcd_status = VCD_ERR_FAIL;
+	unsigned long kernel_vaddr, buf_adr_offset = 0, length;
+	int buffer_num = 0;
+
+	if (!client_ctx || !data_buffer)
+		return -EINVAL;
+
+	if (dir_buffer == BUFFER_TYPE_OUTPUT) {
+		buffer = VCD_BUFFER_OUTPUT;
+		buf_adr_offset = (unsigned long)data_buffer->offset;
+	}
+	length = data_buffer->buffer_len;
+	/*If buffer cannot be set, ignore */
+	if (!vidc_insert_addr_table(client_ctx, dir_buffer,
+		(unsigned long)data_buffer->bufferaddr,
+		&kernel_vaddr, data_buffer->ion_fd,
+		buf_adr_offset, MAX_VIDEO_NUM_OF_BUFF, length)) {
+		ERR("%s() : user_virt_addr = %p cannot be set.",
+		    __func__, data_buffer->bufferaddr);
+		return -EINVAL;
+	}
+
+	vcd_status = vcd_set_buffer(client_ctx->vcd_handle,
+		buffer, (u8 *) kernel_vaddr, data_buffer->buffer_len);
+
+	if (!vcd_status) {
+		mutex_lock(&client_ctx->enrty_queue_lock);
+		if ((VIDEO_SOURCE_DEMUX == dev_inst->source) &&
+			(BUFFER_TYPE_INPUT == dir_buffer)) {
+			buffer_num = client_ctx->num_of_input_buffers - 1;
+			memcpy(&dev_inst->dmx_src_data->in_buffer[buffer_num],
+				data_buffer,
+				sizeof(struct video_data_buffer));
+		}
+		mutex_unlock(&client_ctx->enrty_queue_lock);
+		return 0;
+	} else
+		return -EINVAL;
+}
+
+static int mpq_int_vid_dec_free_buffer(struct video_client_ctx *client_ctx,
+				struct video_data_buffer *data_buffer,
+				enum buffer_dir dir_buffer)
+
+{
+	enum vcd_buffer_type buffer = VCD_BUFFER_INPUT;
+	u32 vcd_status = VCD_ERR_FAIL;
+	unsigned long kernel_vaddr;
+
+	if (!client_ctx || !data_buffer)
+		return -EINVAL;
+
+	if (dir_buffer == BUFFER_TYPE_OUTPUT)
+		buffer = VCD_BUFFER_OUTPUT;
+
+	/*If buffer NOT set, ignore */
+	if (!vidc_delete_addr_table(client_ctx, dir_buffer,
+				(unsigned long)data_buffer->bufferaddr,
+				&kernel_vaddr)) {
+		DBG("%s() : user_virt_addr = %p has not been set.",
+		    __func__, data_buffer->bufferaddr);
+		return 0;
+	}
+	vcd_status = vcd_free_buffer(client_ctx->vcd_handle, buffer,
+					 (u8 *)kernel_vaddr);
+
+	if (vcd_status)
+		return -EIO;
+	else
+		return 0;
+}
+
+static int mpq_int_vid_dec_pause_resume(struct video_client_ctx *client_ctx,
+					u32 pause)
+{
+	u32 vcd_status;
+
+	if (!client_ctx) {
+		DBG("%s(): Invalid client_ctx\n", __func__);
+		return -EINVAL;
+	}
+
+	if (pause) {
+		DBG("msm_vidc_dec: PAUSE command from client = %p\n",
+			 client_ctx);
+		vcd_status = vcd_pause(client_ctx->vcd_handle);
+	} else {
+		DBG("msm_vidc_dec: RESUME command from client = %p\n",
+			 client_ctx);
+		vcd_status = vcd_resume(client_ctx->vcd_handle);
+	}
+
+	if (vcd_status)
+		return -EIO;
+	else
+		return 0;
+}
+
+static int mpq_int_vid_dec_start_stop(struct video_client_ctx *client_ctx,
+					u32 start)
+{
+	struct vid_dec_msg *vdec_msg = NULL;
+	u32 vcd_status;
+
+	DBG("Inside %s()", __func__);
+	if (!client_ctx) {
+		DBG("Invalid client_ctx\n");
+		return -EINVAL;
+	}
+
+	if (start) {
+		if (client_ctx->seq_header_set) {
+			DBG("%s(): Seq Hdr set: Send START_DONE to client",
+				 __func__);
+			vdec_msg = kzalloc(sizeof(*vdec_msg), GFP_KERNEL);
+			if (!vdec_msg) {
+				DBG("mpq_int_vid_dec_start_stop:"\
+				    " cannot allocate buffer\n");
+				return -ENOMEM;
+			}
+			vdec_msg->vdec_msg_info.msgcode =
+			    VDEC_MSG_RESP_START_DONE;
+			vdec_msg->vdec_msg_info.status_code = VDEC_S_SUCCESS;
+			vdec_msg->vdec_msg_info.msgdatasize = 0;
+			mutex_lock(&client_ctx->msg_queue_lock);
+			list_add_tail(&vdec_msg->list, &client_ctx->msg_queue);
+			mutex_unlock(&client_ctx->msg_queue_lock);
+
+			wake_up(&client_ctx->msg_wait);
+
+			DBG("Send START_DONE message to client = %p\n",
+			    client_ctx);
+
+		} else {
+			DBG("%s(): Calling decode_start()", __func__);
+			vcd_status =
+			    vcd_decode_start(client_ctx->vcd_handle, NULL);
+
+			if (vcd_status) {
+				DBG("%s(): vcd_decode_start failed."\
+				    " vcd_status = %u\n", __func__,
+				    vcd_status);
+				return -EIO;
+			}
+		}
+	} else {
+		DBG("%s(): Calling vcd_stop()", __func__);
+		mutex_lock(&mpq_dvb_video_device->lock);
+		vcd_status = VCD_ERR_FAIL;
+		if (!client_ctx->stop_called) {
+			client_ctx->stop_called = true;
+			vcd_status = vcd_stop(client_ctx->vcd_handle);
+		}
+		if (vcd_status) {
+			DBG("%s(): vcd_stop failed.  vcd_status = %u\n",
+				__func__, vcd_status);
+			mutex_unlock(&mpq_dvb_video_device->lock);
+			return -EIO;
+		}
+		DBG("Send STOP_DONE message to client = %p\n", client_ctx);
+		mutex_unlock(&mpq_dvb_video_device->lock);
+	}
+	return 0;
+}
+
+static int mpq_int_vid_dec_decode_frame(struct video_client_ctx *client_ctx,
+				struct video_data_buffer *input_frame)
+{
+	struct vcd_frame_data vcd_input_buffer;
+	unsigned long kernel_vaddr, phy_addr, user_vaddr;
+	int pmem_fd;
+	struct file *file;
+	s32 buffer_index = -1;
+	u32 vcd_status = VCD_ERR_FAIL;
+	u32 ion_flag = 0;
+	struct ion_handle *buff_handle = NULL;
+
+	if (!client_ctx || !input_frame)
+		return -EINVAL;
+
+	user_vaddr = (unsigned long)input_frame->bufferaddr;
+
+	if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_INPUT,
+				      true, &user_vaddr, &kernel_vaddr,
+				      &phy_addr, &pmem_fd, &file,
+				      &buffer_index)) {
+
+		/* kernel_vaddr  is found. send the frame to VCD */
+		memset((void *)&vcd_input_buffer, 0,
+		       sizeof(struct vcd_frame_data));
+		vcd_input_buffer.virtual =
+		    (u8 *) (kernel_vaddr + input_frame->offset);
+		vcd_input_buffer.offset = 0;
+		vcd_input_buffer.frm_clnt_data =
+		    (u32) input_frame->client_data;
+		vcd_input_buffer.ip_frm_tag =
+		    (u32) input_frame->client_data;
+		vcd_input_buffer.data_len = input_frame->buffer_len;
+		vcd_input_buffer.time_stamp = input_frame->pts;
+		/* Rely on VCD using the same flags as OMX */
+		vcd_input_buffer.flags = 0;
+		vcd_input_buffer.desc_buf = NULL;
+		vcd_input_buffer.desc_size = 0;
+		if (vcd_input_buffer.data_len > 0) {
+			ion_flag = vidc_get_fd_info(client_ctx,
+						BUFFER_TYPE_INPUT,
+						pmem_fd,
+						kernel_vaddr,
+						buffer_index,
+						&buff_handle);
+			if (ion_flag == ION_FLAG_CACHED && buff_handle) {
+				msm_ion_do_cache_op(
+				client_ctx->user_ion_client,
+				buff_handle,
+				(unsigned long *)kernel_vaddr,
+				(unsigned long) vcd_input_buffer.data_len,
+				ION_IOC_CLEAN_CACHES);
+			}
+		}
+		vcd_status = vcd_decode_frame(client_ctx->vcd_handle,
+					      &vcd_input_buffer);
+		if (!vcd_status)
+			return 0;
+		else {
+			DBG("%s(): vcd_decode_frame failed = %u\n", __func__,
+			    vcd_status);
+			return -EIO;
+		}
+
+	} else {
+		DBG("%s(): kernel_vaddr not found\n", __func__);
+		return -EIO;
+	}
+}
+
+static int mpq_int_vid_dec_fill_output_buffer(
+		struct video_client_ctx *client_ctx,
+		struct video_data_buffer *fill_buffer)
+{
+	unsigned long kernel_vaddr, phy_addr, user_vaddr;
+	int pmem_fd;
+	struct file *file;
+	s32 buffer_index = -1;
+	u32 vcd_status = VCD_ERR_FAIL;
+	struct ion_handle *buff_handle = NULL;
+
+	struct vcd_frame_data vcd_frame;
+
+	if (!client_ctx || !fill_buffer)
+		return -EINVAL;
+
+	user_vaddr = (unsigned long)fill_buffer->bufferaddr;
+
+	if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT,
+				      true, &user_vaddr, &kernel_vaddr,
+				      &phy_addr, &pmem_fd, &file,
+				      &buffer_index)) {
+
+		memset((void *)&vcd_frame, 0,
+		       sizeof(struct vcd_frame_data));
+		vcd_frame.virtual = (u8 *) kernel_vaddr;
+		vcd_frame.frm_clnt_data = (u32) fill_buffer->client_data;
+		vcd_frame.alloc_len = fill_buffer->buffer_len;
+		vcd_frame.ion_flag = vidc_get_fd_info(client_ctx,
+						 BUFFER_TYPE_OUTPUT,
+						pmem_fd, kernel_vaddr,
+						buffer_index,
+						&buff_handle);
+		vcd_frame.buff_ion_handle = buff_handle;
+		vcd_status = vcd_fill_output_buffer(client_ctx->vcd_handle,
+						    &vcd_frame);
+		if (!vcd_status)
+			return 0;
+		else {
+			DBG("%s(): vcd_fill_output_buffer failed = %u\n",
+			    __func__, vcd_status);
+			return -EINVAL;
+		}
+	} else {
+		DBG("%s(): kernel_vaddr not found\n", __func__);
+		return -EIO;
+	}
+}
+
+
+static int mpq_int_vid_dec_flush(struct video_client_ctx *client_ctx,
+			 enum vdec_bufferflush flush_dir)
+{
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	DBG("msm_vidc_dec: %s() called with dir = %u", __func__,
+		 flush_dir);
+	if (!client_ctx) {
+		DBG("Invalid client_ctx\n");
+		return -EINVAL;
+	}
+
+	switch (flush_dir) {
+	case VDEC_FLUSH_TYPE_INPUT:
+		vcd_status = vcd_flush(client_ctx->vcd_handle,
+					VCD_FLUSH_INPUT);
+		break;
+	case VDEC_FLUSH_TYPE_OUTPUT:
+		vcd_status = vcd_flush(client_ctx->vcd_handle,
+				       VCD_FLUSH_OUTPUT);
+		break;
+	case VDEC_FLUSH_TYPE_ALL:
+		vcd_status = vcd_flush(client_ctx->vcd_handle, VCD_FLUSH_ALL);
+		break;
+	default:
+		ERR("%s(): Inavlid flush cmd. flush_dir = %u\n", __func__,
+		    flush_dir);
+		return -EINVAL;
+		break;
+	}
+
+	if (!vcd_status)
+		return 0;
+	else {
+		DBG("%s(): vcd_flush failed. vcd_status = %u "\
+		    " flush_dir = %u\n", __func__, vcd_status, flush_dir);
+		return -EIO;
+	}
+}
+
+static u32 mpq_int_vid_dec_msg_pending(struct video_client_ctx *client_ctx)
+{
+	u32 islist_empty = 0;
+	mutex_lock(&client_ctx->msg_queue_lock);
+	islist_empty = list_empty(&client_ctx->msg_queue);
+	mutex_unlock(&client_ctx->msg_queue_lock);
+
+	if (islist_empty) {
+		DBG("%s(): vid_dec msg queue empty\n", __func__);
+		if (client_ctx->stop_msg) {
+			DBG("%s(): List empty and Stop Msg set\n",
+				__func__);
+			return client_ctx->stop_msg;
+		}
+	} else {
+		DBG("%s(): vid_dec msg queue Not empty\n", __func__);
+	}
+
+	return !islist_empty;
+}
+
+static int mpq_int_vid_dec_get_next_msg(struct video_client_ctx *client_ctx,
+				struct vdec_msginfo *vdec_msg_info)
+{
+	struct vid_dec_msg *vid_dec_msg = NULL;
+
+	if (!client_ctx)
+		return -EINVAL;
+
+	mutex_lock(&client_ctx->msg_queue_lock);
+	if (!list_empty(&client_ctx->msg_queue)) {
+		DBG("%s(): After Wait\n", __func__);
+		vid_dec_msg = list_first_entry(&client_ctx->msg_queue,
+					       struct vid_dec_msg, list);
+		list_del(&vid_dec_msg->list);
+		memcpy(vdec_msg_info, &vid_dec_msg->vdec_msg_info,
+		       sizeof(struct vdec_msginfo));
+		kfree(vid_dec_msg);
+	}
+	mutex_unlock(&client_ctx->msg_queue_lock);
+	return 0;
+}
+
+static u32 mpq_int_vid_dec_close_client(struct video_client_ctx *client_ctx)
+{
+	struct vid_dec_msg *vdec_msg;
+	u32 vcd_status;
+
+	DBG("msm_vidc_dec: Inside %s()", __func__);
+	if (!client_ctx || (!client_ctx->vcd_handle)) {
+		DBG("Invalid client_ctx\n");
+		return false;
+	}
+
+	mutex_lock(&mpq_dvb_video_device->lock);
+	if (!client_ctx->stop_called) {
+		client_ctx->stop_called = true;
+		client_ctx->stop_sync_cb = true;
+		vcd_status = vcd_stop(client_ctx->vcd_handle);
+		DBG("Stuck at the stop call\n");
+		if (!vcd_status)
+			wait_for_completion(&client_ctx->event);
+		DBG("Came out of wait event\n");
+	}
+	mutex_lock(&client_ctx->msg_queue_lock);
+	while (!list_empty(&client_ctx->msg_queue)) {
+		DBG("%s(): Delete remaining entries\n", __func__);
+		vdec_msg = list_first_entry(&client_ctx->msg_queue,
+						   struct vid_dec_msg, list);
+		if (vdec_msg) {
+			list_del(&vdec_msg->list);
+			kfree(vdec_msg);
+		}
+	}
+	mutex_unlock(&client_ctx->msg_queue_lock);
+	vcd_status = vcd_close(client_ctx->vcd_handle);
+
+	if (vcd_status) {
+		mutex_unlock(&mpq_dvb_video_device->lock);
+		return false;
+	}
+	client_ctx->user_ion_client = NULL;
+	mutex_destroy(&client_ctx->msg_queue_lock);
+	mutex_destroy(&client_ctx->enrty_queue_lock);
+	memset((void *)client_ctx, 0, sizeof(struct video_client_ctx));
+	mpq_dvb_video_device->num_clients--;
+	mutex_unlock(&mpq_dvb_video_device->lock);
+	return true;
+}
+
+static int mpq_int_vid_dec_open_client(struct video_client_ctx **vid_clnt_ctx,
+					int flags)
+{
+	int rc = 0;
+	s32 client_index;
+	struct video_client_ctx *client_ctx = NULL;
+	u8 client_count;
+
+	if (!vid_clnt_ctx) {
+		DBG("Invalid input\n");
+		return -EINVAL;
+	}
+	*vid_clnt_ctx = NULL;
+	client_count = vcd_get_num_of_clients();
+	if (client_count == VIDC_MAX_NUM_CLIENTS) {
+		ERR("ERROR : vid_dec_open() max number of clients"\
+			"limit reached\n");
+		return -ENOMEM;
+	}
+
+	DBG(" Virtual Address of ioremap is %p\n",
+				mpq_dvb_video_device->virt_base);
+	if (!mpq_dvb_video_device->num_clients)
+		if (!vidc_load_firmware())
+			return -ENOMEM;
+
+	client_index = mpq_int_vid_dec_get_empty_client_index();
+	if (client_index == -1) {
+		DBG("%s() : No free clients client_index == -1\n", __func__);
+		vidc_release_firmware();
+		return -ENOMEM;
+	}
+	client_ctx = &mpq_dvb_video_device->vdec_clients[client_index];
+	mpq_dvb_video_device->num_clients++;
+	init_completion(&client_ctx->event);
+	mutex_init(&client_ctx->msg_queue_lock);
+	mutex_init(&client_ctx->enrty_queue_lock);
+	INIT_LIST_HEAD(&client_ctx->msg_queue);
+	init_waitqueue_head(&client_ctx->msg_wait);
+	client_ctx->stop_msg = 0;
+	client_ctx->stop_called = false;
+	client_ctx->stop_sync_cb = false;
+	client_ctx->dmx_disable = 0;
+	if (vcd_get_ion_status()) {
+		client_ctx->user_ion_client = vcd_get_ion_client();
+		if (!client_ctx->user_ion_client) {
+			ERR("vcd_open ion client get failed");
+			rc = -ENOMEM;
+			goto client_failure;
+		}
+	}
+	rc = vcd_open(mpq_dvb_video_device->device_handle, true,
+				  mpq_int_vid_dec_vcd_cb, client_ctx, flags);
+	if (!rc) {
+		wait_for_completion(&client_ctx->event);
+		if (client_ctx->event_status) {
+			DBG("callback for vcd_open returned error: %u",
+				client_ctx->event_status);
+			rc = -ENODEV;
+			goto client_failure;
+		}
+	} else {
+		DBG("vcd_open returned error: %u", rc);
+		goto client_failure;
+	}
+	client_ctx->seq_header_set = false;
+	*vid_clnt_ctx = client_ctx;
+
+	return 0;
+
+client_failure:
+	vidc_release_firmware();
+	mpq_dvb_video_device->num_clients--;
+	mutex_destroy(&client_ctx->msg_queue_lock);
+	mutex_destroy(&client_ctx->enrty_queue_lock);
+	memset((void *)client_ctx, 0, sizeof(struct video_client_ctx));
+	return rc;
+}
+
+static int mpq_dvb_video_open(struct inode *inode, struct file *file)
+{
+	int rc;
+	struct mpq_dvb_video_inst *dev_inst   = NULL;
+	struct dvb_device         *device     = NULL;
+
+	DBG("Inside %s()", __func__);
+	mutex_lock(&mpq_dvb_video_device->lock);
+
+	/* Open the dvb/video instance */
+	rc = dvb_generic_open(inode, file);
+	if (rc) {
+		DBG("Failed in dvb_generic_open with return value :%d\n",
+					rc);
+		mutex_unlock(&mpq_dvb_video_device->lock);
+		return rc;
+
+	}
+
+	device   = (struct dvb_device *)file->private_data;
+	dev_inst = (struct mpq_dvb_video_inst *)device->priv;
+
+	if (dev_inst->client_ctx) {
+		dvb_generic_release(inode, file);
+		mutex_unlock(&mpq_dvb_video_device->lock);
+		return -EEXIST;
+	}
+
+	rc = mpq_int_vid_dec_open_client(&dev_inst->client_ctx, 0);
+	if (rc) {
+		dvb_generic_release(inode, file);
+		mutex_unlock(&mpq_dvb_video_device->lock);
+		return rc;
+	}
+
+	if (!dev_inst->client_ctx) {
+		dvb_generic_release(inode, file);
+		mutex_unlock(&mpq_dvb_video_device->lock);
+		return -ENOMEM;
+	}
+
+	/* Set default source to memory for easier handling */
+	dev_inst->source = VIDEO_SOURCE_MEMORY;
+
+	mutex_unlock(&mpq_dvb_video_device->lock);
+
+	return rc;
+}
+
+static int mpq_dvb_video_term_dmx_src(struct mpq_dvb_video_inst *dev_inst)
+{
+
+	struct mpq_dmx_src_data *dmx_data = dev_inst->dmx_src_data;
+
+	if (NULL == dmx_data)
+		return 0;
+
+	kthread_stop(dmx_data->data_task);
+	mutex_destroy(&dmx_data->msg_queue_lock);
+
+	kfree(dmx_data);
+	dev_inst->dmx_src_data = NULL;
+
+	return 0;
+
+}
+
+static int mpq_dvb_video_release(struct inode *inode, struct file *file)
+{
+	struct dvb_device *device = file->private_data;
+	struct mpq_dvb_video_inst *dev_inst = device->priv;
+
+	vidc_cleanup_addr_table(dev_inst->client_ctx, BUFFER_TYPE_OUTPUT);
+	vidc_cleanup_addr_table(dev_inst->client_ctx, BUFFER_TYPE_INPUT);
+	if (dev_inst->source == VIDEO_SOURCE_DEMUX)
+		mpq_dvb_video_term_dmx_src(dev_inst);
+	mpq_int_vid_dec_close_client(dev_inst->client_ctx);
+	memset((void *)dev_inst, 0, sizeof(struct mpq_dvb_video_inst));
+	vidc_release_firmware();
+	dvb_generic_release(inode, file);
+	return 0;
+}
+
+static void *mpq_int_vid_dec_map_dev_base_addr(void *device_name)
+{
+	return mpq_dvb_video_device->virt_base;
+}
+
+static int mpq_int_vid_dec_vcd_init(void)
+{
+	int rc;
+	struct vcd_init_config vcd_init_config;
+	u32 i;
+
+	/* init_timer(&hw_timer); */
+	DBG("msm_vidc_dec: Inside %s()", __func__);
+	mpq_dvb_video_device->num_clients = 0;
+
+	for (i = 0; i < VIDC_MAX_NUM_CLIENTS; i++) {
+		memset((void *)&mpq_dvb_video_device->vdec_clients[i], 0,
+		       sizeof(mpq_dvb_video_device->vdec_clients[i]));
+	}
+
+	mutex_init(&mpq_dvb_video_device->lock);
+	mpq_dvb_video_device->virt_base = vidc_get_ioaddr();
+	DBG("%s() : base address for VIDC core %u\n", __func__, \
+		(int)mpq_dvb_video_device->virt_base);
+
+	if (!mpq_dvb_video_device->virt_base) {
+		DBG("%s() : ioremap failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	vcd_init_config.device_name = "MPQ_VIDC";
+	vcd_init_config.map_dev_base_addr = mpq_int_vid_dec_map_dev_base_addr;
+	vcd_init_config.interrupt_clr = NULL;
+	vcd_init_config.register_isr = NULL;
+	vcd_init_config.deregister_isr = NULL;
+	vcd_init_config.timer_create = vidc_timer_create;
+	vcd_init_config.timer_release = vidc_timer_release;
+	vcd_init_config.timer_start = vidc_timer_start;
+	vcd_init_config.timer_stop = vidc_timer_stop;
+
+	rc = vcd_init(&vcd_init_config,
+			&mpq_dvb_video_device->device_handle);
+
+	if (rc) {
+		DBG("%s() : vcd_init failed\n", __func__);
+		mutex_destroy(&mpq_dvb_video_device->lock);
+		return -ENODEV;
+	}
+	return 0;
+}
+
+static int mpq_int_vdec_get_fps(struct video_client_ctx *client_ctx,
+				unsigned int *fps)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_frame_rate vcd_frame_rate;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (NULL == fps)
+		return -EINVAL;
+
+	vcd_property_hdr.prop_id = VCD_I_FRAME_RATE;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_frame_rate);
+	vcd_frame_rate.fps_numerator = 0;
+	vcd_frame_rate.fps_denominator = 1;
+
+	*fps = 0;
+	vcd_status = vcd_get_property(client_ctx->vcd_handle,
+				      &vcd_property_hdr, &vcd_frame_rate);
+
+	if (vcd_status)
+		return -EINVAL;
+	else {
+		*fps = (vcd_frame_rate.fps_numerator * 1000)
+			/(vcd_frame_rate.fps_denominator);
+		return 0;
+	}
+}
+
+static int mpq_dvb_video_command_handler(struct mpq_dvb_video_inst *dev_inst,
+					void *parg)
+{
+	struct video_client_ctx *client_ctx = dev_inst->client_ctx;
+	struct video_command *cmd = parg;
+	int rc = 0;
+
+	if (cmd == NULL)
+		return -EINVAL;
+
+	switch (cmd->cmd) {
+	case VIDEO_CMD_SET_CODEC:
+		DBG("cmd : VIDEO_CMD_SET_CODEC\n");
+		rc = mpq_int_vid_dec_set_codec(client_ctx, cmd->codec);
+		break;
+	case VIDEO_CMD_GET_CODEC:
+		DBG("cmd : VIDEO_CMD_GET_CODEC\n");
+		rc = mpq_int_vid_dec_get_codec(client_ctx, &cmd->codec);
+		break;
+	case VIDEO_CMD_SET_OUTPUT_FORMAT:
+		DBG("cmd : VIDEO_CMD_SET_OUTPUT_FORMAT\n");
+		rc = mpq_int_vid_dec_set_output_format(client_ctx,
+							cmd->format);
+		break;
+	case VIDEO_CMD_GET_OUTPUT_FORMAT:
+		DBG("cmd : VIDEO_CMD_GET_OUTPUT_FORMAT\n");
+		rc = mpq_int_vid_dec_get_output_format(client_ctx,
+							&cmd->format);
+		break;
+	case VIDEO_CMD_GET_PIC_RES:
+		DBG("cmd : VIDEO_CMD_GET_PIC_RES\n");
+		rc = mpq_int_vid_dec_get_frame_resolution(client_ctx,
+						&cmd->frame_res);
+		break;
+	case VIDEO_CMD_SET_INPUT_BUFFERS:
+		DBG("cmd : VIDEO_CMD_SET_INPUT_BUFFERS\n");
+		rc = mpq_int_vid_dec_set_buffer(dev_inst, &cmd->buffer,
+						BUFFER_TYPE_INPUT);
+		break;
+	case VIDEO_CMD_SET_OUTPUT_BUFFERS:
+		DBG("cmd : VIDEO_CMD_SET_OUTPUT_BUFFERS\n");
+		rc = mpq_int_vid_dec_set_buffer(dev_inst, &cmd->buffer,
+						BUFFER_TYPE_OUTPUT);
+		break;
+	case VIDEO_CMD_FREE_INPUT_BUFFERS:
+		DBG("cmd : VIDEO_CMD_FREE_INPUT_BUFFERS\n");
+		rc = mpq_int_vid_dec_free_buffer(client_ctx, &cmd->buffer,
+						BUFFER_TYPE_INPUT);
+		break;
+	case VIDEO_CMD_FREE_OUTPUT_BUFFERS:
+		DBG("cmd : VIDEO_CMD_FREE_OUTPUT_BUFFERS\n");
+		rc = mpq_int_vid_dec_free_buffer(client_ctx, &cmd->buffer,
+							BUFFER_TYPE_OUTPUT);
+		break;
+	case VIDEO_CMD_GET_BUFFER_REQ:
+		DBG("cmd : VIDEO_CMD_GET_BUFFER_REQ\n");
+		rc = mpq_int_vid_dec_get_buffer_req(client_ctx, &cmd->buf_req);
+		break;
+	case VIDEO_CMD_SET_BUFFER_COUNT:
+		DBG("cmd : VIDEO_CMD_SET_BUFFER_COUNT\n");
+		rc = mpq_int_vid_dec_set_buffer_req(client_ctx, cmd->buf_req);
+		break;
+	case VIDEO_CMD_READ_RAW_OUTPUT:
+		DBG("cmd : VIDEO_CMD_READ_RAW_OUTPUT\n");
+		rc = mpq_int_vid_dec_fill_output_buffer(client_ctx,
+							&cmd->buffer);
+		break;
+	case VIDEO_CMD_SET_H264_MV_BUFFER:
+		DBG("cmd : VIDEO_CMD_SET_H264_MV_BUFFER\n");
+		rc = mpq_int_vid_dec_set_h264_mv_buffers(client_ctx,
+							&cmd->mv_buffer_prop);
+		break;
+	case VIDEO_CMD_GET_H264_MV_BUFFER:
+		DBG("cmd : VIDEO_CMD_GET_H264_MV_BUFFER\n");
+		rc = mpq_int_vid_dec_get_h264_mv_buffer_size(client_ctx,
+							&cmd->mv_buffer_req);
+		break;
+	case VIDEO_CMD_FREE_H264_MV_BUFFER:
+		DBG("cmd : VIDEO_CMD_FREE_H264_MV_BUFFER\n");
+		rc = mpq_int_vid_dec_free_h264_mv_buffers(client_ctx);
+		break;
+	case VIDEO_CMD_CLEAR_INPUT_BUFFER:
+		DBG("cmd : VIDEO_CMD_CLEAR_INPUT_BUFFER\n");
+		rc = mpq_int_vid_dec_flush(client_ctx, VDEC_FLUSH_TYPE_INPUT);
+		break;
+	case VIDEO_CMD_CLEAR_OUTPUT_BUFFER:
+		DBG("cmd : VIDEO_CMD_CLEAR_OUTPUT_BUFFER\n");
+		rc = mpq_int_vid_dec_flush(client_ctx, VDEC_FLUSH_TYPE_OUTPUT);
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
+
+static ssize_t mpq_dvb_video_write(struct file *file, const char __user *buf,
+					size_t count, loff_t *ppos)
+{
+	int rc = 0;
+	struct dvb_device *device = file->private_data;
+	struct mpq_dvb_video_inst *dev_inst = NULL;
+
+	struct video_data_buffer *input_frame =
+				(struct video_data_buffer *)buf;
+
+	if ((device == NULL) || (input_frame == NULL))
+		return -EINVAL;
+
+	dev_inst = device->priv;
+	if (dev_inst == NULL)
+		return -EINVAL;
+
+	rc = mpq_int_vid_dec_decode_frame(dev_inst->client_ctx, input_frame);
+	if (rc)
+		return -EIO;
+
+	return input_frame->buffer_len;
+}
+
+static int mpq_dvb_video_get_event(struct video_client_ctx *client_ctx,
+				struct video_event *ev)
+{
+	int rc;
+	struct vdec_msginfo vdec_msg_info = {};
+
+	memset(ev, 0, sizeof(struct video_event));
+
+	rc = mpq_int_vid_dec_get_next_msg(client_ctx, &vdec_msg_info);
+	if (rc)
+		return rc;
+
+	ev->status = vdec_msg_info.status_code;
+	/* Map the Message here */
+	switch (vdec_msg_info.msgcode) {
+	case VDEC_MSG_INVALID:
+		DBG("VDEC_MSG_INVALID\n");
+		break;
+	case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
+		DBG("VIDEO_EVENT_INPUT_BUFFER_DONE\n");
+		ev->type = VIDEO_EVENT_INPUT_BUFFER_DONE;
+		ev->u.buffer.client_data =
+				vdec_msg_info.msgdata.input_frame_clientdata;
+		break;
+	case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
+		DBG("VIDEO_EVENT_OUTPUT_BUFFER_DONE\n");
+		ev->type = VIDEO_EVENT_OUTPUT_BUFFER_DONE;
+		ev->u.buffer.bufferaddr  =
+				vdec_msg_info.msgdata.output_frame.bufferaddr;
+		ev->u.buffer.buffer_len  =
+				vdec_msg_info.msgdata.output_frame.len;
+		ev->u.buffer.ip_buffer_tag = vdec_msg_info.msgdata.\
+					output_frame.input_frame_clientdata;
+		ev->u.buffer.client_data = vdec_msg_info.msgdata.\
+					output_frame.client_data;
+		ev->u.buffer.pts         =
+				vdec_msg_info.msgdata.output_frame.time_stamp;
+		ev->u.buffer.offset      =
+				vdec_msg_info.msgdata.output_frame.offset;
+		ev->u.buffer.interlaced_format = map_scan_type(vdec_msg_info.\
+				msgdata.output_frame.interlaced_format);
+		break;
+	case VDEC_MSG_RESP_START_DONE:
+		DBG("VIDEO_EVENT_DECODER_PLAYING\n");
+		ev->type = VIDEO_EVENT_DECODER_PLAYING;
+		break;
+	case VDEC_MSG_RESP_STOP_DONE:
+		DBG("VIDEO_EVENT_DECODER_FREEZED\n");
+		ev->type = VIDEO_EVENT_DECODER_STOPPED;
+		break;
+	case VDEC_MSG_RESP_PAUSE_DONE:
+		DBG("VDEC_MSG_RESP_PAUSE_DONE\n");
+		ev->type = VIDEO_EVENT_DECODER_FREEZED;
+		break;
+	case VDEC_MSG_RESP_RESUME_DONE:
+		DBG("VIDEO_EVENT_DECODER_RESUMED\n");
+		ev->type = VIDEO_EVENT_DECODER_RESUMED;
+		break;
+	case VDEC_MSG_EVT_CONFIG_CHANGED:
+	case VDEC_MSG_EVT_INFO_CONFIG_CHANGED:
+		DBG("VIDEO_EVENT_SEQ_HDR_FOUND\n");
+		ev->type = VIDEO_EVENT_SEQ_HDR_FOUND;
+		break;
+	case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
+		DBG("VIDEO_EVENT_OUTPUT_FLUSH_DONE\n");
+		ev->type = VIDEO_EVENT_OUTPUT_FLUSH_DONE;
+		break;
+	case VDEC_MSG_RESP_OUTPUT_FLUSHED:
+		DBG("VIDEO_EVENT_OUTPUT_FLUSHED\n");
+		ev->type = VIDEO_EVENT_OUTPUT_FLUSHED;
+		ev->u.buffer.bufferaddr  =
+				vdec_msg_info.msgdata.output_frame.bufferaddr;
+		ev->u.buffer.buffer_len  =
+				vdec_msg_info.msgdata.output_frame.len;
+		ev->u.buffer.ip_buffer_tag = vdec_msg_info.msgdata.\
+				output_frame.input_frame_clientdata;
+		ev->u.buffer.client_data = vdec_msg_info.msgdata.\
+				output_frame.client_data;
+		ev->u.buffer.pts         =
+				vdec_msg_info.msgdata.output_frame.time_stamp;
+		ev->u.buffer.offset      =
+				vdec_msg_info.msgdata.output_frame.offset;
+		ev->u.buffer.interlaced_format = map_scan_type(vdec_msg_info.\
+				msgdata.output_frame.interlaced_format);
+		break;
+	case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
+		DBG("VIDEO_EVENT_INPUT_FLUSH_DONE\n");
+		ev->type = VIDEO_EVENT_INPUT_FLUSH_DONE;
+		break;
+	case VDEC_MSG_RESP_INPUT_FLUSHED:
+		DBG("VIDEO_EVENT_INPUT_FLUSHED\n");
+		ev->type = VIDEO_EVENT_INPUT_FLUSHED;
+		ev->u.buffer.client_data =
+				vdec_msg_info.msgdata.input_frame_clientdata;
+		break;
+	}
+	return 0;
+}
+
+static enum scan_format map_scan_type(enum vdec_interlaced_format type)
+{
+	if (type == VDEC_InterlaceFrameProgressive)
+		return INTERLACE_FRAME_PROGRESSIVE;
+	if (type == VDEC_InterlaceInterleaveFrameTopFieldFirst)
+		return INTERLACE_INTERLEAVE_FRAME_TOP_FIELD_FIRST;
+	if (type == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
+		return INTERLACE_INTERLEAVE_FRAME_BOTTOM_FIELD_FIRST;
+	return INTERLACE_FRAME_PROGRESSIVE;
+}
+
+static int mpq_dvb_video_play(struct mpq_dvb_video_inst *dev_inst)
+{
+	return mpq_int_vid_dec_start_stop(dev_inst->client_ctx, true);
+}
+
+static int mpq_dvb_video_stop(struct video_client_ctx *client_ctx)
+{
+	return mpq_int_vid_dec_start_stop(client_ctx, false);
+}
+
+static void mpq_dvb_video_get_stream_if(
+				enum mpq_adapter_stream_if interface_id,
+				void *arg)
+{
+	struct mpq_dvb_video_inst *dev_inst = arg;
+
+	DBG("In mpq_dvb_video_get_stream_if : %d\n", interface_id);
+
+	mpq_adapter_get_stream_if(interface_id,
+			&dev_inst->dmx_src_data->stream_buffer);
+
+	wake_up(&dev_inst->dmx_src_data->msg_wait);
+}
+
+static int mpq_dvb_video_init_dmx_src(struct mpq_dvb_video_inst *dev_inst,
+					int device_id)
+{
+	int rc;
+
+	dev_inst->dmx_src_data =  kzalloc(sizeof(struct mpq_dmx_src_data),
+						GFP_KERNEL);
+	if (dev_inst->dmx_src_data == NULL)
+		return -ENOMEM;
+
+	rc = mpq_adapter_get_stream_if(
+		(enum mpq_adapter_stream_if)device_id,
+		&dev_inst->dmx_src_data->stream_buffer);
+
+	if (rc) {
+		kfree(dev_inst->dmx_src_data);
+		return -ENODEV;
+	} else if (dev_inst->dmx_src_data->stream_buffer == NULL) {
+		DBG("Stream Buffer is NULL. Resigtering Notifier.\n");
+		rc = mpq_adapter_notify_stream_if(
+			(enum mpq_adapter_stream_if)device_id,
+			mpq_dvb_video_get_stream_if,
+			(void *)dev_inst);
+		if (rc) {
+			kfree(dev_inst->dmx_src_data);
+			return -ENODEV;
+		}
+	}
+
+	mutex_init(&dev_inst->dmx_src_data->msg_queue_lock);
+	INIT_LIST_HEAD(&dev_inst->dmx_src_data->msg_queue);
+	init_waitqueue_head(&dev_inst->dmx_src_data->msg_wait);
+
+	dev_inst->dmx_src_data->data_task = kthread_run(
+			mpq_bcast_data_handler,	(void *)dev_inst,
+			vid_thread_names[device_id]);
+
+	return 0;
+}
+
+static int mpq_dvb_video_set_source(struct dvb_device *device,
+				video_stream_source_t source)
+{
+	int rc = 0;
+	struct mpq_dvb_video_inst *dev_inst =
+			(struct mpq_dvb_video_inst *)device->priv;
+
+	if (dev_inst->source == source)
+		return rc;
+
+	if ((VIDEO_SOURCE_MEMORY == source) &&
+		(VIDEO_SOURCE_DEMUX == dev_inst->source))
+		mpq_dvb_video_term_dmx_src(dev_inst);
+
+	dev_inst->source = source;
+	if (VIDEO_SOURCE_DEMUX == source)
+		rc = mpq_dvb_video_init_dmx_src(dev_inst, device->id);
+
+	return rc;
+}
+
+static int mpq_dvb_video_ioctl(struct file *file,
+				unsigned int cmd, void *parg)
+{
+	int rc;
+	struct dvb_device *device = (struct dvb_device *)file->private_data;
+	struct video_client_ctx *client_ctx = NULL;
+	struct mpq_dvb_video_inst *dev_inst = NULL;
+
+	if (device == NULL)
+		return -EINVAL;
+
+	dev_inst = (struct mpq_dvb_video_inst *)device->priv;
+	if (dev_inst == NULL)
+		return -EINVAL;
+
+	client_ctx = (struct video_client_ctx *)dev_inst->client_ctx;
+	if (client_ctx == NULL)
+		return -EINVAL;
+
+	switch (cmd) {
+	case VIDEO_PLAY:
+		DBG("ioctl : VIDEO_PLAY\n");
+		rc = mpq_dvb_video_play(dev_inst);
+		break;
+	case VIDEO_STOP:
+		DBG("ioctl : VIDEO_STOP\n");
+		rc = mpq_dvb_video_stop(client_ctx);
+		break;
+	case VIDEO_FREEZE:
+		DBG("ioctl : VIDEO_FREEZE\n");
+		rc = mpq_int_vid_dec_pause_resume(client_ctx, true);
+		break;
+	case VIDEO_CONTINUE:
+		DBG("ioctl : VIDEO_CONTINUE\n");
+		rc = mpq_int_vid_dec_pause_resume(client_ctx, false);
+		break;
+	case VIDEO_CLEAR_BUFFER:
+		DBG("ioctl : VIDEO_CLEAR_BUFFER\n");
+		rc = mpq_int_vid_dec_flush(client_ctx,
+				VDEC_FLUSH_TYPE_ALL);
+		break;
+	case VIDEO_COMMAND:
+	case VIDEO_TRY_COMMAND:
+		DBG("ioctl : VIDEO_COMMAND\n");
+		rc = mpq_dvb_video_command_handler(dev_inst, parg);
+		break;
+	case VIDEO_GET_FRAME_RATE:
+		DBG("ioctl : VIDEO_GET_FRAME_RATE\n");
+		rc = mpq_int_vdec_get_fps(client_ctx,
+				(unsigned int *)parg);
+		break;
+	case VIDEO_GET_EVENT:
+		DBG("ioctl : VIDEO_GET_EVENT\n");
+		rc = mpq_dvb_video_get_event(client_ctx,
+				(struct video_event *)parg);
+		break;
+	case VIDEO_SELECT_SOURCE:
+		DBG("ioctl : VIDEO_SELECT_SOURCE\n");
+		rc = mpq_dvb_video_set_source(device,
+				(video_stream_source_t)parg);
+		break;
+	default:
+		ERR("Invalid IOCTL\n");
+		rc = -EINVAL;
+	}
+
+	return rc;
+
+}
+
+static unsigned int mpq_dvb_video_poll(struct file *file, poll_table *wait)
+{
+	struct dvb_device *device = file->private_data;
+	struct video_client_ctx *client_ctx = NULL;
+	struct mpq_dvb_video_inst *dev_inst = NULL;
+	unsigned int mask = 0;
+
+	DBG("In %s\n", __func__);
+
+	if (device == NULL)
+		return -EINVAL;
+
+	dev_inst = device->priv;
+	if (dev_inst == NULL)
+		return -EINVAL;
+
+	client_ctx = dev_inst->client_ctx;
+	if (client_ctx == NULL)
+		return -EINVAL;
+
+	poll_wait(file, &client_ctx->msg_wait, wait);
+	if (mpq_int_vid_dec_msg_pending(client_ctx))
+		mask |= POLLIN;
+	else
+		mask = 0;
+
+	return mask;
+}
+
+/*
+ * Driver Registration.
+ */
+static const struct file_operations mpq_dvb_video_fops = {
+	.owner		= THIS_MODULE,
+	.write		= mpq_dvb_video_write,
+	.unlocked_ioctl	= dvb_generic_ioctl,
+	.open		= mpq_dvb_video_open,
+	.release	= mpq_dvb_video_release,
+	.poll		= mpq_dvb_video_poll,
+	.llseek		= noop_llseek,
+};
+
+static const struct dvb_device mpq_dvb_video_device_ctrl = {
+	.priv		= NULL,
+	.users		= 4,
+	.readers	= 4,	/* arbitrary */
+	.writers	= 4,
+	.fops		= &mpq_dvb_video_fops,
+	.kernel_ioctl	= mpq_dvb_video_ioctl,
+};
+
+static int __init mpq_dvb_video_init(void)
+{
+	int rc, i = 0, j;
+
+	mpq_dvb_video_device = kzalloc(sizeof(struct mpq_dvb_video_dev),
+				GFP_KERNEL);
+	if (!mpq_dvb_video_device) {
+		ERR("%s Unable to allocate memory for mpq_dvb_video_dev\n",
+		       __func__);
+		return -ENOMEM;
+	}
+
+	mpq_dvb_video_device->mpq_adapter = mpq_adapter_get();
+	if (!mpq_dvb_video_device->mpq_adapter) {
+		ERR("%s Unable to get MPQ Adapter\n", __func__);
+		rc = -ENODEV;
+		goto free_region;
+	}
+
+	rc = mpq_int_vid_dec_vcd_init();
+	if (rc)
+		goto free_region;
+
+	for (i = 0; i < DVB_MPQ_NUM_VIDEO_DEVICES; i++) {
+
+		rc = dvb_register_device(mpq_dvb_video_device->mpq_adapter,
+				&mpq_dvb_video_device->dev_inst[i].video_dev,
+				&mpq_dvb_video_device_ctrl,
+				&mpq_dvb_video_device->dev_inst[i],
+				DVB_DEVICE_VIDEO);
+
+		if (rc) {
+			ERR("Failed in %s with at %d return value :%d\n",
+				__func__, i, rc);
+			goto free_region;
+		}
+
+	}
+
+	return 0;
+
+free_region:
+	for (j = 0; j < i; j++)
+		dvb_unregister_device(
+			mpq_dvb_video_device->dev_inst[j].video_dev);
+
+	kfree(mpq_dvb_video_device);
+	return rc;
+}
+
+static void __exit mpq_dvb_video_exit(void)
+{
+	int i;
+
+	for (i = 0; i < DVB_MPQ_NUM_VIDEO_DEVICES; i++)
+		dvb_unregister_device(
+			mpq_dvb_video_device->dev_inst[i].video_dev);
+
+	mutex_destroy(&mpq_dvb_video_device->lock);
+	kfree(mpq_dvb_video_device);
+}
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MPQ DVB Video driver");
+
+module_init(mpq_dvb_video_init);
+module_exit(mpq_dvb_video_exit);
diff --git a/drivers/media/platform/msm/dvb/video/mpq_dvb_video_internal.h b/drivers/media/platform/msm/dvb/video/mpq_dvb_video_internal.h
new file mode 100644
index 0000000..7c748eb
--- /dev/null
+++ b/drivers/media/platform/msm/dvb/video/mpq_dvb_video_internal.h
@@ -0,0 +1,93 @@
+/* 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.
+ *
+ */
+
+#ifndef MPQ_DVB_VIDEO_INTERNAL_H
+#define MPQ_DVB_VIDEO_INTERNAL_H
+
+#include <linux/msm_vidc_dec.h>
+#include <media/msm/vidc_init.h>
+#include <linux/dvb/video.h>
+
+/*
+ * MPQ Specific Includes.
+ */
+#include "mpq_dvb_debug.h"
+#include "mpq_adapter.h"
+#include "mpq_stream_buffer.h"
+
+#define DVB_MPQ_NUM_VIDEO_DEVICES CONFIG_DVB_MPQ_NUM_VIDEO_DEVICES
+
+/*
+ * Input Buffer Requirements for Video Decoder.
+ */
+#define DVB_VID_NUM_IN_BUFFERS (2)
+#define DVB_VID_IN_BUFFER_SIZE (2*1024*1024)
+#define DVB_VID_IN_BUFFER_ALGN (8*1024)
+
+struct vid_dec_msg {
+	struct list_head list;
+	struct vdec_msginfo vdec_msg_info;
+};
+
+enum mpq_bcast_msgcode {
+	MPQ_BCAST_MSG_START,
+	MPQ_BCAST_MSG_IBD,
+	MPQ_BCAST_MSG_FLUSH,
+	MPQ_BCAST_MSG_TERM
+};
+
+struct mpq_bcast_msg_info {
+	enum mpq_bcast_msgcode code;
+	unsigned int data;
+};
+
+struct mpq_bcast_msg {
+	struct list_head list;
+	struct mpq_bcast_msg_info info;
+};
+
+struct mpq_dmx_src_data {
+	struct mpq_streambuffer *stream_buffer;
+	struct video_data_buffer in_buffer[DVB_VID_NUM_IN_BUFFERS];
+	struct list_head msg_queue;
+	wait_queue_head_t msg_wait;
+	struct mutex msg_queue_lock;
+	struct task_struct *data_task;
+};
+
+struct mpq_dvb_video_inst {
+	struct dvb_device  *video_dev;
+	video_stream_source_t source;
+	struct mpq_dmx_src_data *dmx_src_data;
+	struct video_client_ctx *client_ctx;
+};
+
+struct mpq_dvb_video_dev {
+
+	resource_size_t phys_base;
+	void __iomem *virt_base;
+	unsigned int irq;
+	struct clk *hclk;
+	struct clk *hclk_div2;
+	struct clk *pclk;
+	unsigned long hclk_rate;
+	struct mutex lock;
+	s32 device_handle;
+	struct dvb_adapter *mpq_adapter;
+	struct mpq_dvb_video_inst dev_inst[DVB_MPQ_NUM_VIDEO_DEVICES];
+	struct video_client_ctx vdec_clients[DVB_MPQ_NUM_VIDEO_DEVICES];
+	u32 num_clients;
+	void(*timer_handler)(void *);
+};
+
+#endif /* MPQ_DVB_VIDEO_INTERNAL_H */
diff --git a/drivers/media/platform/msm/vcap/Kconfig b/drivers/media/platform/msm/vcap/Kconfig
new file mode 100644
index 0000000..2bdcfbd
--- /dev/null
+++ b/drivers/media/platform/msm/vcap/Kconfig
@@ -0,0 +1,7 @@
+config MSM_VCAP
+	tristate "Qualcomm MSM VCAP"
+	depends on VIDEO_DEV && VIDEO_V4L2
+	default y
+	---help---
+		Enables VCAP driver. This device allows for video capture and
+		video processing using the v4l2 api
diff --git a/drivers/media/platform/msm/vcap/Makefile b/drivers/media/platform/msm/vcap/Makefile
new file mode 100644
index 0000000..b9c6e4c
--- /dev/null
+++ b/drivers/media/platform/msm/vcap/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_MSM_VCAP) += vcap_v4l2.o
+obj-$(CONFIG_MSM_VCAP) += vcap_vc.o
+obj-$(CONFIG_MSM_VCAP) += vcap_vp.o
diff --git a/drivers/media/platform/msm/vcap/vcap_v4l2.c b/drivers/media/platform/msm/vcap/vcap_v4l2.c
new file mode 100644
index 0000000..291089f
--- /dev/null
+++ b/drivers/media/platform/msm/vcap/vcap_v4l2.c
@@ -0,0 +1,2505 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/videodev2.h>
+#include <linux/platform_device.h>
+#include <linux/memory_alloc.h>
+#include <linux/ctype.h>
+#include <linux/debugfs.h>
+#include <linux/regulator/consumer.h>
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/iommu.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/irqs.h>
+#include <mach/clk.h>
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
+#include <mach/iommu.h>
+#include <mach/iommu_domains.h>
+
+#include <media/videobuf2-msm-mem.h>
+#include <media/videobuf2-vmalloc.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-fh.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-event.h>
+#include <media/vcap_v4l2.h>
+#include <media/vcap_fmt.h>
+
+#include "vcap_vc.h"
+#include "vcap_vp.h"
+
+#define NUM_INPUTS 1
+#define MSM_VCAP_DRV_NAME "msm_vcap"
+
+static struct vcap_dev *vcap_ctrl;
+
+#ifdef CONFIG_DEBUG_FS
+static struct dentry *vcap_debugfs_base;
+static struct reg_range debug_reg_range[] = {
+	{
+		VCAP_REG_RANGE_1_MIN,
+		VCAP_REG_RANGE_1_MAX,
+	},
+	{
+		VCAP_REG_RANGE_2_MIN,
+		VCAP_REG_RANGE_2_MAX,
+	},
+	{
+		VCAP_REG_RANGE_3_MIN,
+		VCAP_REG_RANGE_3_MAX,
+	},
+	{
+		VCAP_REG_RANGE_4_MIN,
+		VCAP_REG_RANGE_4_MAX,
+	},
+	{
+		VCAP_REG_RANGE_5_MIN,
+		VCAP_REG_RANGE_5_MAX,
+	},
+};
+#endif
+
+static int vcap_reg_powerup(struct vcap_dev *dev)
+{
+	dev->fs_vcap = regulator_get(dev->ddev, "fs_vcap");
+	if (IS_ERR(dev->fs_vcap)) {
+		pr_err("%s: Regulator FS_VCAP get failed %ld\n", __func__,
+			PTR_ERR(dev->fs_vcap));
+		dev->fs_vcap = NULL;
+		return -EINVAL;
+	} else if (regulator_enable(dev->fs_vcap)) {
+		pr_err("%s: Regulator FS_VCAP enable failed\n", __func__);
+		regulator_put(dev->fs_vcap);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static void vcap_reg_powerdown(struct vcap_dev *dev)
+{
+	if (dev->fs_vcap == NULL)
+		return;
+	regulator_disable(dev->fs_vcap);
+	regulator_put(dev->fs_vcap);
+	dev->fs_vcap = NULL;
+	return;
+}
+
+static int vcap_config_gpios(int on, struct vcap_platform_data *pdata)
+{
+	int i, ret;
+	int num_gpios = pdata->num_gpios;
+	unsigned *gpios = pdata->gpios;
+
+	pr_debug("GPIO config start\n");
+	if (on) {
+		for (i = 0; i < num_gpios; i++) {
+			ret = gpio_request(gpios[i], "vcap:vc");
+			if (ret) {
+				pr_err("VCAP: failed at GPIO %d to request\n",
+						gpios[i]);
+				goto gpio_failed;
+			}
+			ret = gpio_direction_input(gpios[i]);
+			if (ret) {
+				pr_err("VCAP: failed at GPIO %d to set to input\n",
+					gpios[i]);
+				i++;
+				goto gpio_failed;
+			}
+		}
+	} else {
+		for (i = 0; i < num_gpios; i++)
+			gpio_free(gpios[i]);
+	}
+	pr_debug("GPIO config exit\n");
+	return 0;
+gpio_failed:
+	for (i--; i >= 0; i--)
+		gpio_free(gpios[i]);
+	return -EINVAL;
+}
+
+static int vcap_clk_powerup(struct vcap_dev *dev, struct device *ddev,
+		unsigned long rate)
+{
+	int ret = 0;
+
+	dev->vcap_clk = clk_get(ddev, "core_clk");
+	if (IS_ERR(dev->vcap_clk)) {
+		dev->vcap_clk = NULL;
+		pr_err("%s: Could not clk_get core_clk\n", __func__);
+		clk_put(dev->vcap_clk);
+		dev->vcap_clk = NULL;
+		return -EINVAL;
+	}
+
+	clk_prepare(dev->vcap_clk);
+	ret = clk_enable(dev->vcap_clk);
+	if (ret) {
+		pr_err("%s: Failed core clk_enable %d\n", __func__, ret);
+		goto fail_vcap_clk_unprep;
+	}
+
+	rate = clk_round_rate(dev->vcap_clk, rate);
+	if (rate < 0) {
+		pr_err("%s: Failed core rnd_rate\n", __func__);
+		goto fail_vcap_clk;
+	}
+	ret = clk_set_rate(dev->vcap_clk, rate);
+	if (ret < 0) {
+		pr_err("%s: Failed core set_rate %d\n", __func__, ret);
+		goto fail_vcap_clk;
+	}
+	dev->dbg_p.clk_rate = (uint32_t) rate;
+
+	dev->vcap_npl_clk = clk_get(ddev, "vcap_npl_clk");
+	if (IS_ERR(dev->vcap_npl_clk)) {
+		dev->vcap_npl_clk = NULL;
+		pr_err("%s: Could not clk_get npl\n", __func__);
+		clk_put(dev->vcap_npl_clk);
+		dev->vcap_npl_clk = NULL;
+		goto fail_vcap_clk;
+	}
+
+	clk_prepare(dev->vcap_npl_clk);
+	ret = clk_enable(dev->vcap_npl_clk);
+	if (ret) {
+		pr_err("%s:Failed npl clk_enable %d\n", __func__, ret);
+		goto fail_vcap_npl_clk_unprep;
+	}
+
+	dev->vcap_p_clk = clk_get(ddev, "iface_clk");
+	if (IS_ERR(dev->vcap_p_clk)) {
+		dev->vcap_p_clk = NULL;
+		pr_err("%s: Could not clk_get pix(AHB)\n", __func__);
+		clk_put(dev->vcap_p_clk);
+		dev->vcap_p_clk = NULL;
+		goto fail_vcap_npl_clk;
+	}
+
+	clk_prepare(dev->vcap_p_clk);
+	ret = clk_enable(dev->vcap_p_clk);
+	if (ret) {
+		pr_err("%s: Failed pix(AHB) clk_enable %d\n", __func__, ret);
+		goto fail_vcap_p_clk_unprep;
+	}
+	return 0;
+
+fail_vcap_p_clk_unprep:
+	clk_unprepare(dev->vcap_p_clk);
+	clk_put(dev->vcap_p_clk);
+	dev->vcap_p_clk = NULL;
+
+fail_vcap_npl_clk:
+	clk_disable(dev->vcap_npl_clk);
+fail_vcap_npl_clk_unprep:
+	clk_unprepare(dev->vcap_npl_clk);
+	clk_put(dev->vcap_npl_clk);
+	dev->vcap_npl_clk = NULL;
+
+fail_vcap_clk:
+	dev->dbg_p.clk_rate = 0;
+	clk_disable(dev->vcap_clk);
+fail_vcap_clk_unprep:
+	clk_unprepare(dev->vcap_clk);
+	clk_put(dev->vcap_clk);
+	dev->vcap_clk = NULL;
+	return -EINVAL;
+}
+
+static void vcap_clk_powerdown(struct vcap_dev *dev)
+{
+	if (dev->vcap_p_clk != NULL) {
+		clk_disable(dev->vcap_p_clk);
+		clk_unprepare(dev->vcap_p_clk);
+		clk_put(dev->vcap_p_clk);
+		dev->vcap_p_clk = NULL;
+	}
+
+	if (dev->vcap_npl_clk != NULL) {
+		clk_disable(dev->vcap_npl_clk);
+		clk_unprepare(dev->vcap_npl_clk);
+		clk_put(dev->vcap_npl_clk);
+		dev->vcap_npl_clk = NULL;
+	}
+
+	if (dev->vcap_clk != NULL) {
+		clk_disable(dev->vcap_clk);
+		clk_unprepare(dev->vcap_clk);
+		clk_put(dev->vcap_clk);
+		dev->vcap_clk = NULL;
+	}
+
+	dev->dbg_p.clk_rate = 0;
+}
+
+static int vcap_get_bus_client_handle(struct vcap_dev *dev)
+{
+	struct msm_bus_scale_pdata *vcap_axi_client_pdata =
+			dev->vcap_pdata->bus_client_pdata;
+	dev->bus_client_handle =
+			msm_bus_scale_register_client(vcap_axi_client_pdata);
+
+	return 0;
+}
+
+static int vcap_enable(struct vcap_dev *dev, struct device *ddev,
+		unsigned long rate)
+{
+	int rc;
+	pr_debug("Enter %s", __func__);
+
+	rc = vcap_reg_powerup(dev);
+	if (rc < 0)
+		goto reg_failed;
+	rc = vcap_clk_powerup(dev, ddev, rate);
+	if (rc < 0)
+		goto clk_failed;
+	rc = vcap_get_bus_client_handle(dev);
+	if (rc < 0)
+		goto bus_r_failed;
+	rc = vcap_config_gpios(1, dev->vcap_pdata);
+	if (rc < 0)
+		goto gpio_failed;
+	rc = iommu_attach_device(dev->iommu_vcap_domain, dev->vc_iommu_ctx);
+	if (rc < 0)
+		goto vc_iommu_attach_failed;
+	rc = iommu_attach_device(dev->iommu_vcap_domain, dev->vp_iommu_ctx);
+	if (rc < 0)
+		goto vp_iommu_attach_failed;
+	writel_relaxed(0x00030003, VCAP_OFFSET(0xD78));
+	writel_relaxed(0x00030003, VCAP_OFFSET(0xD7C));
+	pr_debug("Success Exit %s", __func__);
+	return 0;
+
+vp_iommu_attach_failed:
+	iommu_detach_device(dev->iommu_vcap_domain, dev->vc_iommu_ctx);
+vc_iommu_attach_failed:
+	vcap_config_gpios(0, dev->vcap_pdata);
+gpio_failed:
+	msm_bus_scale_unregister_client(dev->bus_client_handle);
+	dev->bus_client_handle = 0;
+bus_r_failed:
+	vcap_clk_powerdown(dev);
+clk_failed:
+	vcap_reg_powerdown(dev);
+reg_failed:
+	return rc;
+}
+
+static int vcap_disable(struct vcap_dev *dev)
+{
+	pr_debug("Enter %s", __func__);
+	iommu_detach_device(dev->iommu_vcap_domain, dev->vp_iommu_ctx);
+	iommu_detach_device(dev->iommu_vcap_domain, dev->vc_iommu_ctx);
+
+	vcap_config_gpios(0, dev->vcap_pdata);
+
+	msm_bus_scale_unregister_client(dev->bus_client_handle);
+	dev->bus_client_handle = 0;
+	dev->dbg_p.bw_request = 0;
+	vcap_clk_powerdown(dev);
+	vcap_reg_powerdown(dev);
+	return 0;
+}
+
+static int vcap_register_domain(void)
+{
+	struct msm_iova_partition vcap_partition = {
+		.start = 0,
+		.size = SZ_2G,
+	};
+	struct msm_iova_layout vcap_layout = {
+		.partitions = &vcap_partition,
+		.npartitions = 1,
+		.client_name = "vcap",
+		.domain_flags = 0,
+	};
+
+	return msm_register_domain(&vcap_layout);
+}
+
+enum vcap_op_mode determine_mode(struct vcap_client_data *cd)
+{
+	if (cd->set_cap == 1 && cd->set_vp_o == 0 &&
+			cd->set_decode == 0)
+		return VC_VCAP_OP;
+	else if (cd->set_cap == 1 && cd->set_vp_o == 1 &&
+			cd->set_decode == 0)
+		return VC_AND_VP_VCAP_OP;
+	else if (cd->set_cap == 0 && cd->set_vp_o == 1 &&
+			cd->set_decode == 1)
+		return VP_VCAP_OP;
+	else
+		return UNKNOWN_VCAP_OP;
+}
+
+void dealloc_resources(struct vcap_client_data *cd)
+{
+	cd->set_cap = false;
+	cd->set_decode = false;
+	cd->set_vp_o = false;
+}
+
+/* VCAP Internal QBUF and DQBUF for VC + VP */
+int vcvp_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
+{
+	struct vb2_buffer *vb;
+
+	if (q->fileio) {
+		pr_debug("%s: file io in progress\n", __func__);
+		return -EBUSY;
+	}
+
+	if (b->type != q->type) {
+		pr_debug("%s: invalid buffer type\n", __func__);
+		return -EINVAL;
+	}
+
+	if (b->index >= q->num_buffers) {
+		pr_debug("%s: buffer index out of range\n", __func__);
+		return -EINVAL;
+	}
+
+	vb = q->bufs[b->index];
+	if (NULL == vb) {
+		pr_debug("%s: buffer is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	if (b->memory != q->memory) {
+		pr_debug("%s: invalid memory type\n", __func__);
+		return -EINVAL;
+	}
+
+	if (vb->state != VB2_BUF_STATE_DEQUEUED &&
+			vb->state != VB2_BUF_STATE_PREPARED) {
+		pr_err("%s: buffer already in use\n", __func__);
+		return -EINVAL;
+	}
+
+	vb->v4l2_buf.timestamp = b->timestamp;
+	vb->v4l2_buf.field = b->field;
+	list_add_tail(&vb->queued_entry, &q->queued_list);
+	vb->state = VB2_BUF_STATE_QUEUED;
+
+	if (q->streaming) {
+		vb->state = VB2_BUF_STATE_ACTIVE;
+		atomic_inc(&q->queued_count);
+		q->ops->buf_queue(vb);
+	}
+	return 0;
+}
+
+int vcvp_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b)
+{
+	struct vb2_buffer *vb = NULL;
+	unsigned long flags;
+
+	if (q->fileio) {
+		pr_debug("%s: file io in progress\n", __func__);
+		return -EBUSY;
+	}
+
+	if (b->type != q->type) {
+		pr_debug("%s: invalid buffer type\n", __func__);
+		return -EINVAL;
+	}
+
+	if (!q->streaming) {
+		pr_debug("Streaming off, will not wait for buffers\n");
+		return -EINVAL;
+	}
+
+	if (!list_empty(&q->done_list)) {
+		spin_lock_irqsave(&q->done_lock, flags);
+		vb = list_first_entry(&q->done_list, struct vb2_buffer,
+				done_entry);
+		list_del(&vb->done_entry);
+		spin_unlock_irqrestore(&q->done_lock, flags);
+
+		switch (vb->state) {
+		case VB2_BUF_STATE_DONE:
+			pr_debug("%s: Returning done buffer\n", __func__);
+			break;
+		case VB2_BUF_STATE_ERROR:
+			pr_debug("%s: Ret done buf with err\n", __func__);
+			break;
+		default:
+			pr_debug("%s: Invalid buffer state\n", __func__);
+			return -EINVAL;
+		}
+
+		memcpy(b, &vb->v4l2_buf, offsetof(struct v4l2_buffer, m));
+
+		list_del(&vb->queued_entry);
+
+		vb->state = VB2_BUF_STATE_DEQUEUED;
+		return 0;
+	}
+
+	pr_debug("%s: No buffers to dequeue\n", __func__);
+	return -EAGAIN;
+}
+
+int get_phys_addr(struct vcap_dev *dev, struct vb2_queue *q,
+				  struct v4l2_buffer *b)
+{
+	struct vb2_buffer *vb;
+	struct vcap_buffer *buf;
+	unsigned long len, offset;
+	int rc;
+
+	if (q->fileio) {
+		pr_debug("%s: file io in progress\n", __func__);
+		return -EBUSY;
+	}
+
+	if (b->type != q->type) {
+		pr_debug("%s: invalid buffer type\n", __func__);
+		return -EINVAL;
+	}
+
+	if (b->index >= q->num_buffers) {
+		pr_debug("%s: buffer index out of range\n", __func__);
+		return -EINVAL;
+	}
+
+	vb = q->bufs[b->index];
+	if (NULL == vb) {
+		pr_debug("%s: buffer is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	if (vb->state != VB2_BUF_STATE_DEQUEUED) {
+		pr_debug("%s: buffer already in use\n", __func__);
+		return -EINVAL;
+	}
+
+	buf = container_of(vb, struct vcap_buffer, vb);
+
+	buf->ion_handle = ion_import_dma_buf(dev->ion_client, b->m.userptr);
+	if (IS_ERR_OR_NULL((void *)buf->ion_handle)) {
+		pr_err("%s: Could not alloc memory\n", __func__);
+		buf->ion_handle = NULL;
+		return -ENOMEM;
+	}
+	rc = ion_map_iommu(dev->ion_client, buf->ion_handle,
+		dev->domain_num, 0, SZ_4K, 0, &buf->paddr, &len,
+		0, 0);
+	if (rc < 0) {
+		pr_err("%s: Could not get phys addr\n", __func__);
+		ion_free(dev->ion_client, buf->ion_handle);
+		buf->ion_handle = NULL;
+		return -EFAULT;
+	}
+
+	offset = b->reserved;
+	buf->paddr += offset;
+	return 0;
+}
+
+void free_ion_handle_work(struct vcap_client_data *c_data,
+	struct vb2_buffer *vb)
+{
+	struct vcap_buffer *buf;
+	struct vcap_dev *dev = c_data->dev;
+	struct ion_handle *handle;
+	unsigned long flags = 0;
+
+	buf = container_of(vb, struct vcap_buffer, vb);
+
+	spin_lock_irqsave(&c_data->cap_slock, flags);
+	handle = buf->ion_handle;
+	buf->ion_handle = NULL;
+	spin_unlock_irqrestore(&c_data->cap_slock, flags);
+
+	if (handle == NULL) {
+		pr_debug("%s: no ION handle to free\n", __func__);
+		return;
+	}
+	buf->paddr = 0;
+	ion_unmap_iommu(dev->ion_client, handle, dev->domain_num, 0);
+	ion_free(dev->ion_client, handle);
+	return;
+}
+
+int free_ion_handle(struct vcap_client_data *c_data, struct vb2_queue *q,
+					 struct v4l2_buffer *b)
+{
+	struct vb2_buffer *vb;
+
+	if (q->fileio)
+		return -EBUSY;
+
+	if (b->type != q->type)
+		return -EINVAL;
+
+	if (b->index >= q->num_buffers)
+		return -EINVAL;
+
+	vb = q->bufs[b->index];
+	if (NULL == vb)
+		return -EINVAL;
+
+	free_ion_handle_work(c_data, vb);
+	return 0;
+}
+
+void free_ion_on_q_bufs(struct vb2_queue *vq)
+{
+	struct vcap_client_data *c_data = vb2_get_drv_priv(vq);
+	struct vb2_buffer *vb;
+
+	if (!vq->streaming) {
+		list_for_each_entry(vb, &vq->queued_list, queued_entry)
+			free_ion_handle_work(c_data, vb);
+	}
+}
+
+/* VC Videobuf operations */
+static void wait_prepare(struct vb2_queue *q)
+{
+	struct vcap_client_data *c_data = vb2_get_drv_priv(q);
+	mutex_unlock(&c_data->mutex);
+}
+
+static void wait_finish(struct vb2_queue *q)
+{
+	struct vcap_client_data *c_data = vb2_get_drv_priv(q);
+	mutex_lock(&c_data->mutex);
+}
+
+static int capture_queue_setup(struct vb2_queue *vq,
+			       const struct v4l2_format *fmt,
+			       unsigned int *nbuffers,
+			       unsigned int *nplanes, unsigned int sizes[],
+			       void *alloc_ctxs[])
+{
+	*nbuffers += vcap_ctrl->vc_tot_buf;
+	if (*nbuffers > VIDEO_MAX_FRAME)
+		return -EINVAL;
+	*nplanes = 1;
+	return 0;
+}
+
+static int capture_buffer_init(struct vb2_buffer *vb)
+{
+	return 0;
+}
+
+static int capture_buffer_prepare(struct vb2_buffer *vb)
+{
+	return 0;
+}
+
+static void capture_buffer_queue(struct vb2_buffer *vb)
+{
+	struct vcap_client_data *c_data = vb2_get_drv_priv(vb->vb2_queue);
+	struct vcap_buffer *buf = container_of(vb, struct vcap_buffer, vb);
+	struct vc_action *vc_action = &c_data->vc_action;
+	struct vb2_queue *q = vb->vb2_queue;
+	unsigned long flags = 0;
+
+	spin_lock_irqsave(&c_data->cap_slock, flags);
+	list_add_tail(&buf->list, &vc_action->active);
+	spin_unlock_irqrestore(&c_data->cap_slock, flags);
+
+	if (atomic_read(&c_data->dev->vc_enabled) == 0) {
+		if (atomic_read(&q->queued_count) >= c_data->vc_action.tot_buf)
+			if (vc_hw_kick_off(c_data) == 0)
+				atomic_set(&c_data->dev->vc_enabled, 1);
+	}
+}
+
+static int capture_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+	struct vcap_client_data *c_data = vb2_get_drv_priv(vq);
+	pr_debug("VC start streaming\n");
+	return vc_start_capture(c_data);
+}
+
+static int capture_stop_streaming(struct vb2_queue *vq)
+{
+	struct vcap_client_data *c_data = vb2_get_drv_priv(vq);
+	struct vb2_buffer *vb;
+
+	vc_stop_capture(c_data);
+
+	while (!list_empty(&c_data->vc_action.active)) {
+		struct vcap_buffer *buf;
+		buf = list_entry(c_data->vc_action.active.next,
+			struct vcap_buffer, list);
+		list_del(&buf->list);
+		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+	}
+
+	/* clean ion handles */
+	list_for_each_entry(vb, &vq->queued_list, queued_entry)
+		free_ion_handle_work(c_data, vb);
+	return 0;
+}
+
+static int capture_buffer_finish(struct vb2_buffer *vb)
+{
+	return 0;
+}
+
+static void capture_buffer_cleanup(struct vb2_buffer *vb)
+{
+}
+
+static struct vb2_ops capture_video_qops = {
+	.queue_setup		= capture_queue_setup,
+	.wait_finish		= wait_finish,
+	.wait_prepare		= wait_prepare,
+	.buf_init			= capture_buffer_init,
+	.buf_prepare		= capture_buffer_prepare,
+	.buf_queue			= capture_buffer_queue,
+	.start_streaming	= capture_start_streaming,
+	.stop_streaming		= capture_stop_streaming,
+	.buf_finish			= capture_buffer_finish,
+	.buf_cleanup		= capture_buffer_cleanup,
+};
+
+/* VP I/P Videobuf operations */
+
+static int vp_in_queue_setup(struct vb2_queue *vq,
+			     const struct v4l2_format *fmt,
+			     unsigned int *nbuffers,
+			     unsigned int *nplanes, unsigned int sizes[],
+			     void *alloc_ctxs[])
+{
+	if (*nbuffers >= VIDEO_MAX_FRAME && *nbuffers < 5)
+		*nbuffers = 5;
+
+	*nplanes = 1;
+	return 0;
+}
+
+static int vp_in_buffer_init(struct vb2_buffer *vb)
+{
+	return 0;
+}
+
+static int vp_in_buffer_prepare(struct vb2_buffer *vb)
+{
+	return 0;
+}
+
+static void vp_in_buffer_queue(struct vb2_buffer *vb)
+{
+	struct vcap_client_data *cd = vb2_get_drv_priv(vb->vb2_queue);
+	struct vcap_buffer *buf = container_of(vb, struct vcap_buffer, vb);
+	struct vp_action *vp_act = &cd->vp_action;
+	struct vb2_queue *q = vb->vb2_queue;
+	unsigned long flags = 0;
+
+	spin_lock_irqsave(&cd->cap_slock, flags);
+	list_add_tail(&buf->list, &vp_act->in_active);
+	spin_unlock_irqrestore(&cd->cap_slock, flags);
+
+	if (atomic_read(&cd->dev->vp_enabled) == 0) {
+		if (cd->vp_action.vp_state == VP_FRAME1) {
+			if (atomic_read(&q->queued_count) > 1 &&
+				atomic_read(&cd->vp_out_vidq.queued_count) > 0)
+				/* Valid code flow for VC-VP mode */
+				kickoff_vp(cd);
+		} else {
+			/* VP has already kicked off just needs cont */
+			continue_vp(cd);
+		}
+	}
+}
+
+static int vp_in_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+	pr_debug("VP IN start streaming\n");
+	return 0;
+}
+
+static int vp_in_stop_streaming(struct vb2_queue *vq)
+{
+	struct vcap_client_data *c_data = vb2_get_drv_priv(vq);
+	struct vb2_buffer *vb;
+
+	pr_debug("VP IN stop streaming\n");
+	vp_stop_capture(c_data);
+
+	while (!list_empty(&c_data->vp_action.in_active)) {
+		struct vcap_buffer *buf;
+		buf = list_entry(c_data->vp_action.in_active.next,
+			struct vcap_buffer, list);
+		list_del(&buf->list);
+		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+	}
+
+	/* clean ion handles */
+	list_for_each_entry(vb, &vq->queued_list, queued_entry)
+		free_ion_handle_work(c_data, vb);
+	return 0;
+}
+
+static int vp_in_buffer_finish(struct vb2_buffer *vb)
+{
+	return 0;
+}
+
+static void vp_in_buffer_cleanup(struct vb2_buffer *vb)
+{
+}
+
+static struct vb2_ops vp_in_video_qops = {
+	.queue_setup		= vp_in_queue_setup,
+	.wait_finish		= wait_finish,
+	.wait_prepare		= wait_prepare,
+	.buf_init			= vp_in_buffer_init,
+	.buf_prepare		= vp_in_buffer_prepare,
+	.buf_queue			= vp_in_buffer_queue,
+	.start_streaming	= vp_in_start_streaming,
+	.stop_streaming		= vp_in_stop_streaming,
+	.buf_finish			= vp_in_buffer_finish,
+	.buf_cleanup		= vp_in_buffer_cleanup,
+};
+
+
+/* VP O/P Videobuf operations */
+
+static int vp_out_queue_setup(struct vb2_queue *vq,
+			      const struct v4l2_format *fmt,
+			      unsigned int *nbuffers,
+			      unsigned int *nplanes, unsigned int sizes[],
+			      void *alloc_ctxs[])
+{
+	if (*nbuffers >= VIDEO_MAX_FRAME && *nbuffers < 3)
+		*nbuffers = 3;
+
+	*nplanes = 1;
+	return 0;
+}
+
+static int vp_out_buffer_init(struct vb2_buffer *vb)
+{
+	return 0;
+}
+
+static int vp_out_buffer_prepare(struct vb2_buffer *vb)
+{
+	return 0;
+}
+
+static void vp_out_buffer_queue(struct vb2_buffer *vb)
+{
+	struct vcap_client_data *cd = vb2_get_drv_priv(vb->vb2_queue);
+	struct vcap_buffer *buf = container_of(vb, struct vcap_buffer, vb);
+	struct vp_action *vp_act = &cd->vp_action;
+	struct vb2_queue *q = vb->vb2_queue;
+	unsigned long flags = 0;
+
+	spin_lock_irqsave(&cd->cap_slock, flags);
+	list_add_tail(&buf->list, &vp_act->out_active);
+	spin_unlock_irqrestore(&cd->cap_slock, flags);
+
+	if (atomic_read(&cd->dev->vp_enabled) == 0) {
+		if (cd->vp_action.vp_state == VP_FRAME1) {
+			if (atomic_read(&q->queued_count) > 0 &&
+				atomic_read(&
+					cd->vp_in_vidq.queued_count) > 1)
+				kickoff_vp(cd);
+		} else {
+			/* VP has already kicked off just needs cont */
+			continue_vp(cd);
+		}
+	}
+}
+
+static int vp_out_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+	return 0;
+}
+
+static int vp_out_stop_streaming(struct vb2_queue *vq)
+{
+	struct vcap_client_data *c_data = vb2_get_drv_priv(vq);
+	struct vb2_buffer *vb;
+
+	pr_debug("VP OUT q stop streaming\n");
+	vp_stop_capture(c_data);
+
+	while (!list_empty(&c_data->vp_action.out_active)) {
+		struct vcap_buffer *buf;
+		buf = list_entry(c_data->vp_action.out_active.next,
+			struct vcap_buffer, list);
+		list_del(&buf->list);
+		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+	}
+
+	/* clean ion handles */
+	list_for_each_entry(vb, &vq->queued_list, queued_entry)
+		free_ion_handle_work(c_data, vb);
+	return 0;
+}
+
+static int vp_out_buffer_finish(struct vb2_buffer *vb)
+{
+	return 0;
+}
+
+static void vp_out_buffer_cleanup(struct vb2_buffer *vb)
+{
+}
+
+static struct vb2_ops vp_out_video_qops = {
+	.queue_setup		= vp_out_queue_setup,
+	.wait_finish		= wait_finish,
+	.wait_prepare		= wait_prepare,
+	.buf_init			= vp_out_buffer_init,
+	.buf_prepare		= vp_out_buffer_prepare,
+	.buf_queue			= vp_out_buffer_queue,
+	.start_streaming	= vp_out_start_streaming,
+	.stop_streaming		= vp_out_stop_streaming,
+	.buf_finish			= vp_out_buffer_finish,
+	.buf_cleanup		= vp_out_buffer_cleanup,
+};
+
+/* IOCTL vidioc handling */
+
+static int vidioc_querycap(struct file *file, void  *priv,
+					struct v4l2_capability *cap)
+{
+	struct vcap_dev *dev = video_drvdata(file);
+
+	strlcpy(cap->driver, MSM_VCAP_DRV_NAME, sizeof(cap->driver));
+	strlcpy(cap->card, MSM_VCAP_DRV_NAME, sizeof(cap->card));
+	strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info));
+	cap->version = 0x10000000;
+	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+	return 0;
+}
+
+static int vidioc_enum_input(struct file *file, void *priv,
+				struct v4l2_input *inp)
+{
+	if (inp->index >= NUM_INPUTS)
+		return -EINVAL;
+	return 0;
+}
+
+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
+					struct v4l2_format *f)
+{
+	return 0;
+}
+
+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
+			struct v4l2_format *f)
+{
+	return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+					struct v4l2_format *f)
+{
+	int size;
+	struct vcap_priv_fmt *priv_fmt;
+	struct v4l2_format_vc_ext *vc_format;
+	struct vcap_client_data *c_data = to_client_data(file->private_data);
+
+	priv_fmt = (struct vcap_priv_fmt *) f->fmt.raw_data;
+
+	switch (priv_fmt->type) {
+	case VC_TYPE:
+		vc_format = (struct v4l2_format_vc_ext *) &priv_fmt->u.timing;
+		c_data->vc_format = *vc_format;
+		c_data->stride = priv_fmt->stride;
+
+		size = (c_data->vc_format.hactive_end -
+			c_data->vc_format.hactive_start);
+		if (c_data->stride == VC_STRIDE_32)
+			size = VCAP_STRIDE_CALC(size, VCAP_STRIDE_ALIGN_32);
+		else
+			size = VCAP_STRIDE_CALC(size, VCAP_STRIDE_ALIGN_16);
+
+
+		if (c_data->vc_format.color_space)
+			size *= 3;
+		else
+			size *= 2;
+
+		priv_fmt->u.timing.bytesperline = size;
+		size *= (c_data->vc_format.vactive_end -
+			c_data->vc_format.vactive_start);
+		priv_fmt->u.timing.sizeimage = size;
+		c_data->set_cap = true;
+		break;
+	case VP_IN_TYPE:
+		c_data->vp_in_fmt.width = priv_fmt->u.pix.width;
+		c_data->vp_in_fmt.height = priv_fmt->u.pix.height;
+		c_data->vp_in_fmt.pixfmt = priv_fmt->u.pix.pixelformat;
+
+		size = c_data->vp_in_fmt.width * c_data->vp_in_fmt.height;
+		if (c_data->vp_in_fmt.pixfmt == V4L2_PIX_FMT_NV16)
+			size = size * 2;
+		else
+			size = size / 2 * 3;
+		priv_fmt->u.pix.sizeimage = size;
+		c_data->set_decode = true;
+		break;
+	case VP_OUT_TYPE:
+		c_data->vp_out_fmt.width = priv_fmt->u.pix.width;
+		c_data->vp_out_fmt.height = priv_fmt->u.pix.height;
+		c_data->vp_out_fmt.pixfmt = priv_fmt->u.pix.pixelformat;
+
+		size = c_data->vp_out_fmt.width * c_data->vp_out_fmt.height;
+		if (c_data->vp_out_fmt.pixfmt == V4L2_PIX_FMT_NV16)
+			size = size * 2;
+		else
+			size = size / 2 * 3;
+		priv_fmt->u.pix.sizeimage = size;
+		c_data->set_vp_o = true;
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int vidioc_reqbufs(struct file *file, void *priv,
+			  struct v4l2_requestbuffers *rb)
+{
+	struct vcap_client_data *c_data = to_client_data(file->private_data);
+	struct vcap_dev *dev = c_data->dev;
+	int rc;
+
+	pr_debug("VCAP: In Req Buf %08x\n", (unsigned int)rb->type);
+	c_data->op_mode = determine_mode(c_data);
+	if (c_data->op_mode == UNKNOWN_VCAP_OP) {
+		pr_err("VCAP Error: %s: VCAP in unknown mode\n", __func__);
+		return -ENOTRECOVERABLE;
+	}
+
+	switch (rb->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		if (c_data->op_mode == VC_AND_VP_VCAP_OP) {
+			if (c_data->vc_format.color_space) {
+				pr_err("VCAP Err: %s: VP No RGB support\n",
+					__func__);
+				return -ENOTRECOVERABLE;
+			}
+			if (!c_data->vc_format.mode) {
+				pr_err("VCAP Err: VP No prog support\n");
+				return -ENOTRECOVERABLE;
+			}
+			if (rb->count <= VCAP_VP_MIN_BUF) {
+				pr_err("VCAP Err: Not enough buf for VC_VP\n");
+				return -EINVAL;
+			}
+			rc = vb2_reqbufs(&c_data->vc_vidq, rb);
+			if (rc < 0)
+				return rc;
+
+			c_data->vp_in_fmt.width =
+				(c_data->vc_format.hactive_end -
+				c_data->vc_format.hactive_start);
+			c_data->vp_in_fmt.height =
+				(c_data->vc_format.vactive_end -
+				c_data->vc_format.vactive_start);
+			/* VC outputs YCbCr 4:2:2 */
+			c_data->vp_in_fmt.pixfmt = V4L2_PIX_FMT_NV16;
+			rb->type = V4L2_BUF_TYPE_INTERLACED_IN_DECODER;
+			rc = vb2_reqbufs(&c_data->vp_in_vidq, rb);
+			rb->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+			c_data->vc_action.tot_buf = dev->vc_tot_buf;
+			return rc;
+
+		} else {
+			rc = vb2_reqbufs(&c_data->vc_vidq, rb);
+			c_data->vc_action.tot_buf = dev->vc_tot_buf;
+			return rc;
+		}
+	case V4L2_BUF_TYPE_INTERLACED_IN_DECODER:
+		return vb2_reqbufs(&c_data->vp_in_vidq, rb);
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+		return vb2_reqbufs(&c_data->vp_out_vidq, rb);
+	default:
+		pr_err("VCAP Error: %s: Unknown buffer type\n", __func__);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+	struct vcap_client_data *c_data = to_client_data(file->private_data);
+
+	switch (p->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		return vb2_querybuf(&c_data->vc_vidq, p);
+	default:
+		pr_err("VCAP Error: %s: Unknown buffer type\n", __func__);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+	struct vcap_client_data *c_data = to_client_data(file->private_data);
+	struct vb2_buffer *vb;
+	struct vb2_queue *q;
+	int rc;
+
+	pr_debug("VCAP In Q Buf %08x\n", (unsigned int)p->type);
+	switch (p->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		if (c_data->op_mode == VC_AND_VP_VCAP_OP) {
+			/* If buffer in vp_in_q it will be coming back */
+			q = &c_data->vp_in_vidq;
+			if (p->index >= q->num_buffers) {
+				pr_debug("VCAP qbuf: buffer index out of range\n");
+				return -EINVAL;
+			}
+
+			vb = q->bufs[p->index];
+			if (NULL == vb) {
+				pr_debug("VCAP qbuf: buffer is NULL\n");
+				return -EINVAL;
+			}
+
+			if (vb->state != VB2_BUF_STATE_DEQUEUED) {
+				pr_debug("VCAP qbuf: buffer already in use\n");
+				return -EINVAL;
+			}
+			rc = get_phys_addr(c_data->dev, &c_data->vc_vidq, p);
+			if (rc < 0)
+				return rc;
+			rc = vcvp_qbuf(&c_data->vc_vidq, p);
+			if (rc < 0)
+				free_ion_handle(c_data,
+					&c_data->vc_vidq, p);
+			return rc;
+		}
+		rc = get_phys_addr(c_data->dev, &c_data->vc_vidq, p);
+		if (rc < 0)
+			return rc;
+		mutex_lock(&c_data->mutex);
+		rc = vb2_qbuf(&c_data->vc_vidq, p);
+		mutex_unlock(&c_data->mutex);
+		if (rc < 0)
+			free_ion_handle(c_data, &c_data->vc_vidq, p);
+		return rc;
+	case V4L2_BUF_TYPE_INTERLACED_IN_DECODER:
+		if (c_data->op_mode == VC_AND_VP_VCAP_OP)
+			return -EINVAL;
+		rc = get_phys_addr(c_data->dev, &c_data->vp_in_vidq, p);
+		if (rc < 0)
+			return rc;
+		mutex_lock(&c_data->mutex);
+		rc = vb2_qbuf(&c_data->vp_in_vidq, p);
+		mutex_unlock(&c_data->mutex);
+		if (rc < 0)
+			free_ion_handle(c_data, &c_data->vp_in_vidq, p);
+		return rc;
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+		rc = get_phys_addr(c_data->dev, &c_data->vp_out_vidq, p);
+		if (rc < 0)
+			return rc;
+		mutex_lock(&c_data->mutex);
+		rc = vb2_qbuf(&c_data->vp_out_vidq, p);
+		mutex_unlock(&c_data->mutex);
+		if (rc < 0)
+			free_ion_handle(c_data, &c_data->vp_out_vidq, p);
+		return rc;
+	default:
+		pr_err("VCAP Error: %s: Unknown buffer type\n", __func__);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+	struct vcap_client_data *c_data = to_client_data(file->private_data);
+	int rc;
+
+	if (c_data->streaming == 0)
+		return -EPERM;
+
+	pr_debug("VCAP In DQ Buf %08x\n", (unsigned int)p->type);
+	switch (p->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		if (c_data->op_mode == VC_AND_VP_VCAP_OP)
+			return -EINVAL;
+		mutex_lock(&c_data->mutex);
+		rc = vb2_dqbuf(&c_data->vc_vidq, p, file->f_flags & O_NONBLOCK);
+		mutex_unlock(&c_data->mutex);
+		if (rc < 0)
+			return rc;
+		return free_ion_handle(c_data, &c_data->vc_vidq, p);
+	case V4L2_BUF_TYPE_INTERLACED_IN_DECODER:
+		if (c_data->op_mode == VC_AND_VP_VCAP_OP)
+			return -EINVAL;
+		mutex_lock(&c_data->mutex);
+		rc = vb2_dqbuf(&c_data->vp_in_vidq, p, file->f_flags &
+				O_NONBLOCK);
+		mutex_unlock(&c_data->mutex);
+		if (rc < 0)
+			return rc;
+		return free_ion_handle(c_data, &c_data->vp_in_vidq, p);
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+		mutex_lock(&c_data->mutex);
+		rc = vb2_dqbuf(&c_data->vp_out_vidq, p, file->f_flags &
+				O_NONBLOCK);
+		mutex_unlock(&c_data->mutex);
+		if (rc < 0)
+			return rc;
+		return free_ion_handle(c_data, &c_data->vp_out_vidq, p);
+	default:
+		pr_err("VCAP Error: %s: Unknown buffer type", __func__);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/*
+ * When calling streamon on multiple queues there is a need to first verify
+ * that the steamon will succeed on all queues, similarly for streamoff
+ */
+int streamon_validate_q(struct vb2_queue *q)
+{
+	if (q->fileio) {
+		pr_debug("%s: file io in progress\n", __func__);
+		return -EBUSY;
+	}
+
+	if (q->streaming) {
+		pr_debug("%s: already streaming\n", __func__);
+		return -EBUSY;
+	}
+
+	if (V4L2_TYPE_IS_OUTPUT(q->type)) {
+		if (list_empty(&q->queued_list)) {
+			pr_debug("%s: no output buffers queued\n", __func__);
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+int request_bus_bw(struct vcap_dev *dev, unsigned long rate)
+{
+	struct msm_bus_paths *bus_vectors;
+	int idx, length;
+	bus_vectors = dev->vcap_pdata->bus_client_pdata->usecase;
+	length = dev->vcap_pdata->bus_client_pdata->num_usecases;
+	idx = 0;
+	do {
+		if (rate <= bus_vectors[idx].vectors[0].ab)
+			break;
+		idx++;
+	} while (idx < length);
+	if (idx == length) {
+		pr_info("VCAP: Defaulting to highest BW request\n");
+		idx--;
+	}
+	msm_bus_scale_client_update_request(dev->bus_client_handle, idx);
+	dev->dbg_p.bw_request = bus_vectors[idx].vectors[0].ab;
+	return 0;
+}
+
+static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct vcap_client_data *c_data = to_client_data(file->private_data);
+	struct vcap_dev *dev = c_data->dev;
+	int rc;
+	unsigned long rate;
+	long rate_rc;
+
+	pr_debug("VCAP: In Stream ON\n");
+	if (determine_mode(c_data) != c_data->op_mode) {
+		pr_err("VCAP Error: %s: s_fmt called after req_buf", __func__);
+		return -ENOTRECOVERABLE;
+	}
+
+	if (!dev->vp_dummy_complete) {
+		pr_err("VCAP Err: %s: VP dummy read not complete",
+			__func__);
+		return -EINVAL;
+	}
+
+	switch (c_data->op_mode) {
+	case VC_VCAP_OP:
+		mutex_lock(&dev->dev_mutex);
+		if (dev->vc_resource) {
+			pr_err("VCAP Err: %s: VC resource taken", __func__);
+			mutex_unlock(&dev->dev_mutex);
+			return -EBUSY;
+		}
+		dev->vc_resource = 1;
+		mutex_unlock(&dev->dev_mutex);
+
+		c_data->dev->vc_client = c_data;
+
+		if (!c_data->vc_format.clk_freq) {
+			rc = -EINVAL;
+			goto free_res;
+		}
+
+		rate = c_data->vc_format.clk_freq / 100 * 102;
+		rate_rc = clk_round_rate(dev->vcap_clk, rate);
+		if (rate_rc <= 0) {
+			pr_err("%s: Failed core rnd_rate\n", __func__);
+			rc = -EINVAL;
+			goto free_res;
+		}
+		rate = (unsigned long)rate_rc;
+		rc = clk_set_rate(dev->vcap_clk, rate);
+		if (rc < 0)
+			goto free_res;
+
+		dev->dbg_p.clk_rate = (uint32_t) rate;
+
+		rate = (c_data->vc_format.hactive_end -
+			c_data->vc_format.hactive_start);
+
+		if (c_data->vc_format.color_space)
+			rate *= 3;
+		else
+			rate *= 2;
+
+		rate *= (c_data->vc_format.vactive_end -
+			c_data->vc_format.vactive_start);
+		rate *= c_data->vc_format.frame_rate;
+		if (rate == 0)
+			goto free_res;
+
+		rc = request_bus_bw(dev, rate);
+		if (rc < 0)
+			goto free_res;
+
+		config_vc_format(c_data);
+		c_data->streaming = 1;
+		rc = vb2_streamon(&c_data->vc_vidq, i);
+		if (rc < 0)
+			goto free_res;
+		break;
+	case VP_VCAP_OP:
+		mutex_lock(&dev->dev_mutex);
+		if (dev->vp_resource) {
+			pr_err("VCAP Err: %s: VP resource taken", __func__);
+			mutex_unlock(&dev->dev_mutex);
+			return -EBUSY;
+		}
+		dev->vp_resource = 1;
+		mutex_unlock(&dev->dev_mutex);
+		c_data->dev->vp_client = c_data;
+
+		rate = 160000000;
+		rate_rc = clk_round_rate(dev->vcap_clk, rate);
+		if (rate_rc <= 0) {
+			pr_err("%s: Failed core rnd_rate\n", __func__);
+			rc = -EINVAL;
+			goto free_res;
+		}
+		rate = (unsigned long)rate_rc;
+		rc = clk_set_rate(dev->vcap_clk, rate);
+
+		dev->dbg_p.clk_rate = (uint32_t) rate;
+		if (rc < 0)
+			goto free_res;
+
+		rate = c_data->vp_out_fmt.width *
+			c_data->vp_out_fmt.height * 240;
+		rc = request_bus_bw(dev, rate);
+		if (rc < 0)
+			goto free_res;
+
+		rc = streamon_validate_q(&c_data->vp_in_vidq);
+		if (rc < 0)
+			goto free_res;
+		rc = streamon_validate_q(&c_data->vp_out_vidq);
+		if (rc < 0)
+			goto free_res;
+
+		rc = config_vp_format(c_data);
+		if (rc < 0)
+			goto free_res;
+		rc = init_motion_buf(c_data);
+		if (rc < 0)
+			goto free_res;
+		if (dev->nr_param.mode) {
+			rc = init_nr_buf(c_data);
+			if (rc < 0)
+				goto s_on_deinit_m_buf;
+		}
+
+		c_data->vp_action.vp_state = VP_FRAME1;
+		c_data->streaming = 1;
+
+		rc = vb2_streamon(&c_data->vp_in_vidq,
+				V4L2_BUF_TYPE_INTERLACED_IN_DECODER);
+		if (rc < 0)
+			goto s_on_deinit_nr_buf;
+
+		rc = vb2_streamon(&c_data->vp_out_vidq,
+				V4L2_BUF_TYPE_VIDEO_OUTPUT);
+		if (rc < 0)
+			goto s_on_deinit_nr_buf;
+		break;
+	case VC_AND_VP_VCAP_OP:
+		mutex_lock(&dev->dev_mutex);
+		if (dev->vc_resource || dev->vp_resource) {
+			pr_err("VCAP Err: %s: VC/VP resource taken",
+				__func__);
+			mutex_unlock(&dev->dev_mutex);
+			return -EBUSY;
+		}
+		dev->vc_resource = 1;
+		dev->vp_resource = 1;
+		mutex_unlock(&dev->dev_mutex);
+		c_data->dev->vc_client = c_data;
+		c_data->dev->vp_client = c_data;
+
+		if (!c_data->vc_format.clk_freq) {
+			rc = -EINVAL;
+			goto free_res;
+		}
+
+		rate = c_data->vc_format.clk_freq / 100 * 102;
+		if ((c_data->vc_format.hactive_end -
+				c_data->vc_format.hactive_start) > 539)
+			rate = 200000000;
+		rate_rc = clk_round_rate(dev->vcap_clk, rate);
+		if (rate_rc <= 0) {
+			pr_err("%s: Failed core rnd_rate\n", __func__);
+			rc = -EINVAL;
+			goto free_res;
+		}
+		rate = (unsigned long)rate_rc;
+		rc = clk_set_rate(dev->vcap_clk, rate);
+		if (rc < 0)
+			goto free_res;
+
+		dev->dbg_p.clk_rate = (uint32_t) rate;
+
+		rate = (c_data->vc_format.hactive_end -
+			c_data->vc_format.hactive_start);
+
+		if (c_data->vc_format.color_space)
+			rate *= 3;
+		else
+			rate *= 2;
+
+		rate *= (c_data->vc_format.vactive_end -
+			c_data->vc_format.vactive_start);
+		rate *= c_data->vc_format.frame_rate;
+		rate *= 2;
+		if (rate == 0)
+			goto free_res;
+
+		rc = request_bus_bw(dev, rate);
+		if (rc < 0)
+			goto free_res;
+
+		rc = streamon_validate_q(&c_data->vc_vidq);
+		if (rc < 0)
+			return rc;
+		rc = streamon_validate_q(&c_data->vp_in_vidq);
+		if (rc < 0)
+			goto free_res;
+		rc = streamon_validate_q(&c_data->vp_out_vidq);
+		if (rc < 0)
+			goto free_res;
+
+		rc = config_vc_format(c_data);
+		if (rc < 0)
+			goto free_res;
+		rc = config_vp_format(c_data);
+		if (rc < 0)
+			goto free_res;
+		rc = init_motion_buf(c_data);
+		if (rc < 0)
+			goto free_res;
+
+		if (dev->nr_param.mode) {
+			rc = init_nr_buf(c_data);
+			if (rc < 0)
+				goto s_on_deinit_m_buf;
+		}
+
+		c_data->dev->vc_to_vp_work.cd = c_data;
+		c_data->vp_action.vp_state = VP_FRAME1;
+		c_data->streaming = 1;
+
+		/* These stream on calls should not fail */
+		rc = vb2_streamon(&c_data->vc_vidq,
+				V4L2_BUF_TYPE_VIDEO_CAPTURE);
+		if (rc < 0)
+			goto s_on_deinit_nr_buf;
+
+		rc = vb2_streamon(&c_data->vp_in_vidq,
+				V4L2_BUF_TYPE_INTERLACED_IN_DECODER);
+		if (rc < 0)
+			goto s_on_deinit_nr_buf;
+
+		rc = vb2_streamon(&c_data->vp_out_vidq,
+				V4L2_BUF_TYPE_VIDEO_OUTPUT);
+		if (rc < 0)
+			goto s_on_deinit_nr_buf;
+		break;
+	default:
+		pr_err("VCAP Error: %s: Operation Mode type", __func__);
+		return -ENOTRECOVERABLE;
+	}
+	return 0;
+
+s_on_deinit_nr_buf:
+	if (dev->nr_param.mode)
+		deinit_nr_buf(c_data);
+s_on_deinit_m_buf:
+	deinit_motion_buf(c_data);
+free_res:
+	mutex_lock(&dev->dev_mutex);
+	if (c_data->op_mode == VC_VCAP_OP) {
+		dev->vc_resource = 0;
+		c_data->dev->vc_client = NULL;
+	} else if (c_data->op_mode == VP_VCAP_OP) {
+		dev->vp_resource = 0;
+		c_data->dev->vp_client = NULL;
+	} else if (c_data->op_mode == VC_AND_VP_VCAP_OP) {
+		c_data->dev->vc_client = NULL;
+		c_data->dev->vp_client = NULL;
+		dev->vc_resource = 0;
+		dev->vp_resource = 0;
+	}
+	mutex_unlock(&dev->dev_mutex);
+	return rc;
+}
+
+int streamoff_validate_q(struct vb2_queue *q)
+{
+	if (q->fileio) {
+		pr_debug("%s: file io in progress\n", __func__);
+		return -EBUSY;
+	}
+
+	if (!q->streaming) {
+		pr_debug("%s: not streaming\n", __func__);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+int streamoff_work(struct vcap_client_data *c_data)
+{
+	struct vcap_dev *dev = c_data->dev;
+	int rc;
+	switch (c_data->op_mode) {
+	case VC_VCAP_OP:
+		if (c_data != dev->vc_client) {
+			pr_err("VCAP Err: %s: VC held by other client",
+				__func__);
+			return -EBUSY;
+		}
+		mutex_lock(&dev->dev_mutex);
+		if (!dev->vc_resource) {
+			pr_err("VCAP Err: %s: VC res not acquired", __func__);
+			mutex_unlock(&dev->dev_mutex);
+			return -EBUSY;
+		}
+		dev->vc_resource = 0;
+		mutex_unlock(&dev->dev_mutex);
+		c_data->streaming = 0;
+		mutex_lock(&c_data->mutex);
+		rc = vb2_streamoff(&c_data->vc_vidq,
+				V4L2_BUF_TYPE_VIDEO_CAPTURE);
+		mutex_unlock(&c_data->mutex);
+		if (rc >= 0)
+			atomic_set(&c_data->dev->vc_enabled, 0);
+		return rc;
+	case VP_VCAP_OP:
+		if (c_data != dev->vp_client) {
+			pr_err("VCAP Err: %s: VP held by other client",
+				__func__);
+			return -EBUSY;
+		}
+		mutex_lock(&dev->dev_mutex);
+		if (!dev->vp_resource) {
+			pr_err("VCAP Err: %s: VP res not acquired", __func__);
+			mutex_unlock(&dev->dev_mutex);
+			return -EBUSY;
+		}
+		dev->vp_resource = 0;
+		mutex_unlock(&dev->dev_mutex);
+		rc = streamoff_validate_q(&c_data->vp_in_vidq);
+		if (rc < 0)
+			return rc;
+		rc = streamoff_validate_q(&c_data->vp_out_vidq);
+		if (rc < 0)
+			return rc;
+		c_data->streaming = 0;
+
+		mutex_unlock(&dev->dev_mutex);
+		/* These stream on calls should not fail */
+		rc = vb2_streamoff(&c_data->vp_in_vidq,
+				V4L2_BUF_TYPE_INTERLACED_IN_DECODER);
+		if (rc < 0) {
+			mutex_unlock(&c_data->mutex);
+			return rc;
+		}
+
+		rc = vb2_streamoff(&c_data->vp_out_vidq,
+				V4L2_BUF_TYPE_VIDEO_OUTPUT);
+		mutex_unlock(&c_data->mutex);
+		if (rc < 0)
+			return rc;
+
+		deinit_motion_buf(c_data);
+		if (dev->nr_param.mode)
+			deinit_nr_buf(c_data);
+		atomic_set(&c_data->dev->vp_enabled, 0);
+		return rc;
+	case VC_AND_VP_VCAP_OP:
+		if (c_data != dev->vp_client || c_data != dev->vc_client) {
+			pr_err("VCAP Err: %s: VC/VP held by other client",
+				__func__);
+			return -EBUSY;
+		}
+		mutex_lock(&dev->dev_mutex);
+		if (!(dev->vc_resource || dev->vp_resource)) {
+			pr_err("VCAP Err: %s: VC or VP res not acquired",
+				__func__);
+			mutex_unlock(&dev->dev_mutex);
+			return -EBUSY;
+		}
+		dev->vc_resource = 0;
+		dev->vp_resource = 0;
+		mutex_unlock(&dev->dev_mutex);
+		rc = streamoff_validate_q(&c_data->vc_vidq);
+		if (rc < 0)
+			return rc;
+		rc = streamoff_validate_q(&c_data->vp_in_vidq);
+		if (rc < 0)
+			return rc;
+		rc = streamoff_validate_q(&c_data->vp_out_vidq);
+		if (rc < 0)
+			return rc;
+
+		c_data->streaming = 0;
+		mutex_lock(&c_data->mutex);
+		/* These stream on calls should not fail */
+		rc = vb2_streamoff(&c_data->vc_vidq,
+				V4L2_BUF_TYPE_VIDEO_CAPTURE);
+		if (rc < 0) {
+			mutex_unlock(&c_data->mutex);
+			return rc;
+		}
+
+		rc = vb2_streamoff(&c_data->vp_in_vidq,
+				V4L2_BUF_TYPE_INTERLACED_IN_DECODER);
+		if (rc < 0) {
+			mutex_unlock(&c_data->mutex);
+			return rc;
+		}
+
+		rc = vb2_streamoff(&c_data->vp_out_vidq,
+				V4L2_BUF_TYPE_VIDEO_OUTPUT);
+		mutex_unlock(&c_data->mutex);
+		if (rc < 0)
+			return rc;
+
+		deinit_motion_buf(c_data);
+		if (dev->nr_param.mode)
+			deinit_nr_buf(c_data);
+		atomic_set(&c_data->dev->vc_enabled, 0);
+		atomic_set(&c_data->dev->vp_enabled, 0);
+		return rc;
+	default:
+		pr_err("VCAP Error: %s: Unknown Operation mode", __func__);
+		return -ENOTRECOVERABLE;
+	}
+}
+
+static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct vcap_client_data *c_data = to_client_data(file->private_data);
+	return streamoff_work(c_data);
+}
+
+static int vidioc_subscribe_event(struct v4l2_fh *fh,
+			struct v4l2_event_subscription *sub)
+{
+	int rc;
+	if (sub->type == V4L2_EVENT_ALL) {
+		sub->type = V4L2_EVENT_PRIVATE_START +
+				VCAP_GENERIC_NOTIFY_EVENT;
+		sub->id = 0;
+		do {
+			rc = v4l2_event_subscribe(fh, sub, 16);
+			if (rc < 0) {
+				sub->type = V4L2_EVENT_ALL;
+				v4l2_event_unsubscribe(fh, sub);
+				return rc;
+			}
+			sub->type++;
+		} while (sub->type !=
+			V4L2_EVENT_PRIVATE_START + VCAP_MAX_NOTIFY_EVENT);
+	} else {
+		rc = v4l2_event_subscribe(fh, sub, 16);
+	}
+	return rc;
+}
+
+static int vidioc_unsubscribe_event(struct v4l2_fh *fh,
+			struct v4l2_event_subscription *sub)
+{
+	return v4l2_event_unsubscribe(fh, sub);
+}
+
+static long vidioc_default(struct file *file, void *fh, bool valid_prio,
+						int cmd, void *arg)
+{
+	struct vcap_client_data *c_data = to_client_data(file->private_data);
+	struct vcap_dev *dev = c_data->dev;
+	struct nr_param *param;
+	int	val;
+	unsigned long flags = 0;
+	int ret;
+
+	switch (cmd) {
+	case VCAPIOC_NR_S_PARAMS:
+
+		if (c_data->streaming != 0 &&
+				(!(!((struct nr_param *) arg)->mode) !=
+				!(!(dev->nr_param.mode)))) {
+			pr_err("ERR: Trying to toggle on/off while VP is already running");
+			return -EBUSY;
+		}
+
+
+		spin_lock_irqsave(&c_data->cap_slock, flags);
+		ret = nr_s_param(c_data, (struct nr_param *) arg);
+		if (ret < 0) {
+			spin_unlock_irqrestore(&c_data->cap_slock, flags);
+			return ret;
+		}
+		param = (struct nr_param *) arg;
+		dev->nr_param = *param;
+		if (param->mode == NR_AUTO)
+			s_default_nr_val(&dev->nr_param);
+		dev->nr_update = true;
+		spin_unlock_irqrestore(&c_data->cap_slock, flags);
+		break;
+	case VCAPIOC_NR_G_PARAMS:
+		*((struct nr_param *)arg) = dev->nr_param;
+		if (dev->nr_param.mode != NR_DISABLE) {
+			if (c_data->streaming)
+				nr_g_param(c_data, (struct nr_param *) arg);
+			else
+				(*(struct nr_param *) arg) =
+					dev->nr_param;
+		}
+		break;
+	case VCAPIOC_S_NUM_VC_BUF:
+		val = (*(int *) arg);
+		if (val < VCAP_VC_MIN_BUF || val > VCAP_VC_MAX_BUF)
+			return -EINVAL;
+		dev->vc_tot_buf = (uint8_t) val;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/* VCAP fops */
+static void *vcap_ops_get_userptr(void *alloc_ctx, unsigned long vaddr,
+					unsigned long size, int write)
+{
+	struct vcap_buf_info *mem;
+	mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+	if (!mem)
+		return ERR_PTR(-ENOMEM);
+	mem->vaddr = vaddr;
+	mem->size = size;
+	return mem;
+}
+
+static void vcap_ops_put_userptr(void *buf_priv)
+{
+	kfree(buf_priv);
+}
+
+const struct vb2_mem_ops vcap_mem_ops = {
+	.get_userptr =		vcap_ops_get_userptr,
+	.put_userptr =		vcap_ops_put_userptr,
+};
+
+static int vcap_open(struct file *file)
+{
+	struct vcap_dev *dev = video_drvdata(file);
+	struct vcap_client_data *c_data;
+	struct vb2_queue *q;
+	int ret;
+	if (!dev)
+		return -EINVAL;
+	c_data = kzalloc(sizeof(*c_data), GFP_KERNEL);
+	if (!c_data)
+		return -ENOMEM;
+
+	c_data->dev = dev;
+
+	spin_lock_init(&c_data->cap_slock);
+	mutex_init(&c_data->mutex);
+
+	/* initialize vc queue */
+	q = &c_data->vc_vidq;
+	memset(q, 0, sizeof(c_data->vc_vidq));
+	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	q->io_modes = VB2_USERPTR;
+	q->drv_priv = c_data;
+	q->buf_struct_size = sizeof(struct vcap_buffer);
+	q->ops = &capture_video_qops;
+	q->mem_ops = &vcap_mem_ops;
+	ret = vb2_queue_init(q);
+	if (ret < 0)
+		goto vc_q_failed;
+
+	/* initialize vp in queue */
+	q = &c_data->vp_in_vidq;
+	memset(q, 0, sizeof(c_data->vp_in_vidq));
+	q->type = V4L2_BUF_TYPE_INTERLACED_IN_DECODER;
+	q->io_modes = VB2_USERPTR;
+	q->drv_priv = c_data;
+	q->buf_struct_size = sizeof(struct vcap_buffer);
+	q->ops = &vp_in_video_qops;
+	q->mem_ops = &vcap_mem_ops;
+	ret = vb2_queue_init(q);
+	if (ret < 0)
+		goto vp_in_q_failed;
+
+	/* initialize vp out queue */
+	q = &c_data->vp_out_vidq;
+	memset(q, 0, sizeof(c_data->vp_out_vidq));
+	q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+	q->io_modes = VB2_USERPTR;
+	q->drv_priv = c_data;
+	q->buf_struct_size = sizeof(struct vcap_buffer);
+	q->ops = &vp_out_video_qops;
+	q->mem_ops = &vcap_mem_ops;
+
+	ret = vb2_queue_init(q);
+	if (ret < 0)
+		goto vp_out_q_failed;
+
+	INIT_LIST_HEAD(&c_data->vc_action.active);
+	INIT_LIST_HEAD(&c_data->vp_action.in_active);
+	INIT_LIST_HEAD(&c_data->vp_action.out_active);
+
+	v4l2_fh_init(&c_data->vfh, dev->vfd);
+	v4l2_fh_add(&c_data->vfh);
+
+	mutex_lock(&dev->dev_mutex);
+	atomic_inc(&dev->open_clients);
+	ret = atomic_read(&dev->open_clients);
+	if (ret == 1) {
+		ret = vcap_enable(dev, dev->ddev, 54860000);
+		if (ret < 0) {
+			pr_err("Err: %s: Power on vcap failed", __func__);
+			mutex_unlock(&dev->dev_mutex);
+			goto vcap_power_failed;
+		}
+
+		ret = vp_dummy_event(c_data);
+		if (ret < 0) {
+			pr_err("Err: %s: Dummy Event failed", __func__);
+			mutex_unlock(&dev->dev_mutex);
+			vcap_disable(dev);
+			goto vcap_power_failed;
+		}
+	}
+	mutex_unlock(&dev->dev_mutex);
+
+	file->private_data = &c_data->vfh;
+	return 0;
+
+vcap_power_failed:
+	atomic_dec(&dev->open_clients);
+
+	v4l2_fh_del(&c_data->vfh);
+	v4l2_fh_exit(&c_data->vfh);
+	vb2_queue_release(&c_data->vp_out_vidq);
+vp_out_q_failed:
+	vb2_queue_release(&c_data->vp_in_vidq);
+vp_in_q_failed:
+	vb2_queue_release(&c_data->vc_vidq);
+vc_q_failed:
+	mutex_destroy(&c_data->mutex);
+	kfree(c_data);
+	return ret;
+}
+
+static int vcap_close(struct file *file)
+{
+	struct vcap_dev *dev = video_drvdata(file);
+	struct vcap_client_data *c_data = to_client_data(file->private_data);
+	int ret;
+
+	if (c_data == NULL)
+		return 0;
+
+	if (c_data->streaming)
+		streamoff_work(c_data);
+
+	mutex_lock(&dev->dev_mutex);
+	atomic_dec(&dev->open_clients);
+	ret = atomic_read(&dev->open_clients);
+	mutex_unlock(&dev->dev_mutex);
+	if (ret == 0) {
+		vcap_disable(dev);
+		dev->vc_tot_buf = 2;
+		dev->vp_dummy_complete = false;
+	}
+	v4l2_fh_del(&c_data->vfh);
+	v4l2_fh_exit(&c_data->vfh);
+	free_ion_on_q_bufs(&c_data->vp_out_vidq);
+	free_ion_on_q_bufs(&c_data->vp_in_vidq);
+	free_ion_on_q_bufs(&c_data->vc_vidq);
+
+	vb2_queue_release(&c_data->vp_out_vidq);
+	vb2_queue_release(&c_data->vp_in_vidq);
+	vb2_queue_release(&c_data->vc_vidq);
+	if (c_data->dev->vc_client == c_data)
+		c_data->dev->vc_client = NULL;
+	if (c_data->dev->vp_client == c_data)
+		c_data->dev->vp_client = NULL;
+	mutex_destroy(&c_data->mutex);
+	kfree(c_data);
+	return 0;
+}
+
+unsigned int poll_work(struct vb2_queue *q, struct file *file,
+	poll_table *wait, bool write_q)
+{
+	unsigned long flags;
+	struct vb2_buffer *vb = NULL;
+
+	if (q->num_buffers == 0)
+		return POLLERR;
+
+	if (list_empty(&q->queued_list))
+		return POLLERR;
+
+	poll_wait(file, &q->done_wq, wait);
+
+	spin_lock_irqsave(&q->done_lock, flags);
+	if (!list_empty(&q->done_list))
+		vb = list_first_entry(&q->done_list, struct vb2_buffer,
+					done_entry);
+	spin_unlock_irqrestore(&q->done_lock, flags);
+
+	if (vb && (vb->state == VB2_BUF_STATE_DONE
+			|| vb->state == VB2_BUF_STATE_ERROR)) {
+		return (write_q) ? POLLOUT | POLLWRNORM :
+			POLLIN | POLLRDNORM;
+	}
+	return 0;
+}
+
+static unsigned int vcap_poll(struct file *file,
+				  struct poll_table_struct *wait)
+{
+	struct vcap_client_data *c_data = to_client_data(file->private_data);
+	struct vb2_queue *q;
+	unsigned int mask = 0;
+
+	if (c_data->streaming == 0)
+		return 0;
+
+	pr_debug("%s: Enter slect/poll\n", __func__);
+
+	switch (c_data->op_mode) {
+	case VC_VCAP_OP:
+		q = &c_data->vc_vidq;
+		mask = vb2_poll(q, file, wait);
+		break;
+	case VP_VCAP_OP:
+		q = &c_data->vp_in_vidq;
+		mask = poll_work(q, file, wait, 0);
+		q = &c_data->vp_out_vidq;
+		mask |= poll_work(q, file, wait, 1);
+		break;
+	case VC_AND_VP_VCAP_OP:
+		q = &c_data->vp_out_vidq;
+		mask = poll_work(q, file, wait, 0);
+		break;
+	default:
+		pr_err("VCAP Error: %s: Unknown operation mode", __func__);
+		return POLLERR;
+	}
+	if (v4l2_event_pending(&c_data->vfh))
+		mask |= POLLPRI;
+	poll_wait(file, &(c_data->vfh.wait), wait);
+	return mask;
+}
+/* V4L2 and video device structures */
+
+static const struct v4l2_file_operations vcap_fops = {
+	.owner		= THIS_MODULE,
+	.open		= vcap_open,
+	.release	= vcap_close,
+	.poll		= vcap_poll,
+	.unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
+};
+
+static const struct v4l2_ioctl_ops vcap_ioctl_ops = {
+	.vidioc_querycap      = vidioc_querycap,
+	.vidioc_enum_input    = vidioc_enum_input,
+	.vidioc_g_fmt_vid_cap     = vidioc_g_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap   = vidioc_try_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap     = vidioc_s_fmt_vid_cap,
+	.vidioc_s_fmt_type_private     = vidioc_s_fmt_vid_cap,
+	.vidioc_g_fmt_type_private     = vidioc_g_fmt_vid_cap,
+	.vidioc_s_fmt_vid_out_mplane	= vidioc_s_fmt_vid_cap,
+	.vidioc_g_fmt_vid_out_mplane	= vidioc_g_fmt_vid_cap,
+	.vidioc_reqbufs       = vidioc_reqbufs,
+	.vidioc_querybuf      = vidioc_querybuf,
+	.vidioc_qbuf          = vidioc_qbuf,
+	.vidioc_dqbuf         = vidioc_dqbuf,
+	.vidioc_streamon      = vidioc_streamon,
+	.vidioc_streamoff     = vidioc_streamoff,
+
+	.vidioc_subscribe_event = vidioc_subscribe_event,
+	.vidioc_unsubscribe_event = vidioc_unsubscribe_event,
+	.vidioc_default = vidioc_default,
+};
+
+static struct video_device vcap_template = {
+	.name		= "vcap",
+	.fops		= &vcap_fops,
+	.ioctl_ops	= &vcap_ioctl_ops,
+	.release	= video_device_release,
+};
+
+static irqreturn_t vcap_vp_handler(int irq_num, void *data)
+{
+	return vp_handler(vcap_ctrl);
+}
+
+static irqreturn_t vcap_vc_handler(int irq_num, void *data)
+{
+	return vc_handler(vcap_ctrl);
+}
+
+#ifdef CONFIG_DEBUG_FS
+/* Query VCAP resource usage */
+static ssize_t read_dump_info(struct file *file, char __user *user_buf,
+	size_t len, loff_t *ppos)
+{
+	struct vcap_dev *dev = file->private_data;
+	char str_buf[512];
+	size_t tot_size = 0, size;
+
+	if (dev->vc_client) {
+		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
+			"VCAP: VC\n");
+		tot_size += size;
+		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
+			"vc_resourse = %d\n", dev->vc_resource);
+		tot_size += size;
+		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
+			"vc_enabled = %d\n", atomic_read(&dev->vc_enabled));
+		tot_size += size;
+		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
+			"vc_client id = %p\n", dev->vc_client);
+		tot_size += size;
+		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
+			"vc_queue_count = %d\n",
+			atomic_read(&dev->vc_client->vc_vidq.queued_count));
+		tot_size += size;
+		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
+			"vc_total_buffers = %d\n",
+			dev->vc_client->vc_action.tot_buf);
+		tot_size += size;
+	} else {
+		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
+				"VCAP: VC not in use\n");
+		tot_size += size;
+	}
+	if (dev->vp_client) {
+		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
+			"VCAP: VP\n");
+		tot_size += size;
+		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
+			"vp_resourse = %d\n", dev->vp_resource);
+		tot_size += size;
+		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
+			"vp_enabled = %d\n", atomic_read(&dev->vp_enabled));
+		tot_size += size;
+		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
+			"vp_client id = %p\n", dev->vp_client);
+		tot_size += size;
+		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
+			"vp_in_queue_count = %d\n",
+			atomic_read(
+				&dev->vp_client->vp_in_vidq.queued_count));
+		tot_size += size;
+		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
+			"vp_out_queue_count = %d\n",
+			atomic_read(
+				&dev->vp_client->vp_out_vidq.queued_count));
+		tot_size += size;
+	} else {
+		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
+			"VCAP: VP not in use\n");
+		tot_size += size;
+	}
+
+	return simple_read_from_buffer(user_buf, len, ppos, str_buf, tot_size);
+}
+
+static const struct file_operations dump_info_fops = {
+	.read =		read_dump_info,
+	.open =		simple_open,
+	.llseek =	default_llseek,
+};
+
+static int vcap_debug_clk_rate_get(void *data, u64 *val)
+{
+	struct vcap_dev *dev = data;
+	*val = (u64)dev->dbg_p.clk_rate;
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(clk_rate_fops, vcap_debug_clk_rate_get,
+	NULL, "%llu\n");
+
+static int vcap_debug_bw_req_get(void *data, u64 *val)
+{
+	struct vcap_dev *dev = data;
+	*val = (u64)dev->dbg_p.bw_request;
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(bw_req_fops, vcap_debug_bw_req_get,
+	NULL, "%llu\n");
+
+static int vcap_debug_drop_frames_get(void *data, u64 *val)
+{
+	struct vcap_dev *dev = data;
+	struct timeval tv;
+	int drop_count;
+
+	if (!dev->vc_resource)
+		return -EPERM;
+	drop_count = atomic_read(&dev->dbg_p.vc_drop_count);
+	atomic_set(&dev->dbg_p.vc_drop_count, 0);
+
+	do_gettimeofday(&tv);
+	dev->dbg_p.vc_timestamp = (uint32_t) (tv.tv_sec * VCAP_USEC +
+		tv.tv_usec);
+
+	*val = (u64)drop_count;
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(tot_frame_drop_fops, vcap_debug_drop_frames_get,
+	NULL, "%llu\n");
+
+static int vcap_debug_drop_fps_get(void *data, u64 *val)
+{
+	struct vcap_dev *dev = data;
+	struct timeval tv;
+	int drop_count;
+	uint32_t new_ts;
+
+	if (!dev->vc_resource)
+		return -EPERM;
+	drop_count = atomic_read(&dev->dbg_p.vc_drop_count);
+	atomic_set(&dev->dbg_p.vc_drop_count, 0);
+
+	do_gettimeofday(&tv);
+	new_ts = (uint32_t) (tv.tv_sec * VCAP_USEC +
+		tv.tv_usec);
+
+	if ((new_ts - dev->dbg_p.vc_timestamp) / VCAP_USEC &&
+				new_ts > dev->dbg_p.vc_timestamp)
+		drop_count /= ((new_ts - dev->dbg_p.vc_timestamp) / VCAP_USEC);
+	else
+		drop_count = 0;
+
+	dev->dbg_p.vc_timestamp = new_ts;
+	*val = (u64)drop_count;
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(drop_fps_fops, vcap_debug_drop_fps_get,
+	NULL, "%llu\n");
+
+static int vcap_debug_vp_lat_get(void *data, u64 *val)
+{
+	struct vcap_dev *dev = data;
+
+	if (!dev->vp_resource)
+		return -EPERM;
+	*val = (u64)dev->dbg_p.vp_ewma;
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(vp_lat_fops, vcap_debug_vp_lat_get,
+	NULL, "%llu\n");
+
+/* Read/Write to VCAP Registers */
+static int vcap_debug_reg_set(void *data, u64 val)
+{
+	struct vcap_dev *dev = data;
+	int i;
+	for (i = 0; i < ARRAY_SIZE(debug_reg_range); i++) {
+		if (val >= debug_reg_range[i].min_val && val <=
+				debug_reg_range[i].max_val)
+			break;
+	}
+	if (i == ARRAY_SIZE(debug_reg_range))
+		return -EINVAL;
+	dev->dbg_p.reg_addr = (uint32_t) val;
+	return 0;
+}
+
+static int vcap_debug_reg_get(void *data, u64 *val)
+{
+	struct vcap_dev *dev = data;
+	*val = (u64)dev->dbg_p.reg_addr;
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(vcap_reg_fops, vcap_debug_reg_get,
+	vcap_debug_reg_set, "0x%08llx\n")
+
+static int vcap_debug_reg_rdwr_set(void *data, u64 val)
+{
+	struct vcap_dev *dev = data;
+	u32 reg_val = (u32) val;
+
+	writel_iowmb(reg_val, VCAP_OFFSET(dev->dbg_p.reg_addr));
+	return 0;
+}
+
+static int vcap_debug_reg_rdwr_get(void *data, u64 *val)
+{
+	struct vcap_dev *dev = data;
+	*val = (u64)readl_relaxed(VCAP_OFFSET(dev->dbg_p.reg_addr));
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(vcap_reg_rdwr_fops, vcap_debug_reg_rdwr_get,
+	vcap_debug_reg_rdwr_set, "0x%08llx\n");
+
+static int vcap_debugfs_init(struct vcap_dev *dev)
+{
+	vcap_debugfs_base = debugfs_create_dir("vcap", NULL);
+	if (!vcap_debugfs_base)
+		return -ENOMEM;
+
+	if (!debugfs_create_file("dump_info", S_IRUGO,
+			vcap_debugfs_base, dev, &dump_info_fops))
+		goto error;
+
+	if (!debugfs_create_file("vcap_core_clk_rate", S_IRUGO,
+			vcap_debugfs_base, dev, &clk_rate_fops))
+		goto error;
+
+	if (!debugfs_create_file("vcap_bw_req", S_IRUGO,
+			vcap_debugfs_base, dev, &bw_req_fops))
+		goto error;
+
+	if (!debugfs_create_file("vc_total_frames_drop", S_IRUGO,
+			vcap_debugfs_base, dev, &tot_frame_drop_fops))
+		goto error;
+
+	if (!debugfs_create_file("vc_drop_fps", S_IRUGO,
+			vcap_debugfs_base, dev, &drop_fps_fops))
+		goto error;
+
+	if (!debugfs_create_file("vp_avg_completion_t", S_IRUGO,
+			vcap_debugfs_base, dev, &vp_lat_fops))
+		goto error;
+
+	if (!debugfs_create_file("vcap_reg_addr", S_IRUGO | S_IWUSR,
+			vcap_debugfs_base, dev, &vcap_reg_fops))
+		goto error;
+
+	if (!debugfs_create_file("vcap_reg_val", S_IRUGO | S_IWUSR,
+			vcap_debugfs_base, dev, &vcap_reg_rdwr_fops))
+		goto error;
+	return 0;
+
+error:
+	debugfs_remove_recursive(vcap_debugfs_base);
+	vcap_debugfs_base = NULL;
+	return -ENOMEM;
+}
+
+static void vcap_debugfs_remove(void)
+{
+	if (vcap_debugfs_base) {
+		debugfs_remove_recursive(vcap_debugfs_base);
+		vcap_debugfs_base = NULL;
+	}
+}
+#else
+
+static int vcap_debugfs_init(struct vcap_dev *dev)
+{
+	return 0;
+}
+static void vcap_debugfs_remove(void) {}
+#endif
+
+static int __devinit vcap_probe(struct platform_device *pdev)
+{
+	struct vcap_dev *dev;
+	struct video_device *vfd;
+	int ret;
+
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return -ENOMEM;
+	vcap_ctrl = dev;
+	dev->vcap_pdata = pdev->dev.platform_data;
+
+	dev->vcapmem = platform_get_resource_byname(pdev,
+			IORESOURCE_MEM, "vcap");
+	if (!dev->vcapmem) {
+		pr_err("VCAP: %s: no mem resource?\n", __func__);
+		ret = -ENODEV;
+		goto free_dev;
+	}
+
+	dev->vcapio = request_mem_region(dev->vcapmem->start,
+		resource_size(dev->vcapmem), pdev->name);
+	if (!dev->vcapio) {
+		pr_err("VCAP: %s: no valid mem region\n", __func__);
+		ret = -EBUSY;
+		goto free_dev;
+	}
+
+	dev->vcapbase = ioremap(dev->vcapmem->start,
+		resource_size(dev->vcapmem));
+	if (!dev->vcapbase) {
+		ret = -ENOMEM;
+		pr_err("VCAP: %s: vcap ioremap failed\n", __func__);
+		goto free_resource;
+	}
+
+	dev->vcirq = platform_get_resource_byname(pdev,
+					IORESOURCE_IRQ, "vc_irq");
+	if (!dev->vcirq) {
+		pr_err("%s: no vc irq resource?\n", __func__);
+		ret = -ENODEV;
+		goto free_resource;
+	}
+	dev->vpirq = platform_get_resource_byname(pdev,
+					IORESOURCE_IRQ, "vp_irq");
+	if (!dev->vpirq) {
+		pr_err("%s: no vp irq resource?\n", __func__);
+		ret = -ENODEV;
+		goto free_resource;
+	}
+
+
+	ret = request_irq(dev->vcirq->start, vcap_vc_handler,
+		IRQF_TRIGGER_HIGH, "vc_irq", 0);
+	if (ret < 0) {
+		pr_err("%s: vc irq request fail\n", __func__);
+		ret = -EBUSY;
+		goto free_resource;
+	}
+	disable_irq(dev->vcirq->start);
+
+	ret = request_irq(dev->vpirq->start, vcap_vp_handler,
+		IRQF_TRIGGER_RISING, "vp_irq", 0);
+
+	if (ret < 0) {
+		pr_err("%s: vp irq request fail\n", __func__);
+		ret = -EBUSY;
+		goto free_resource;
+	}
+	disable_irq(dev->vpirq->start);
+
+	snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name),
+			"%s", MSM_VCAP_DRV_NAME);
+
+	ret = v4l2_device_register(NULL, &dev->v4l2_dev);
+	if (ret)
+		goto free_resource;
+
+	dev->vc_iommu_ctx = msm_iommu_get_ctx("vcap_vc");
+	if (!dev->vc_iommu_ctx) {
+		pr_err("%s: No iommu vc context found\n", __func__);
+		ret = -ENODEV;
+		goto free_resource;
+	}
+
+	dev->vp_iommu_ctx = msm_iommu_get_ctx("vcap_vp");
+	if (!dev->vp_iommu_ctx) {
+		pr_err("%s: No iommu vp context found\n", __func__);
+		ret = -ENODEV;
+		goto free_resource;
+	}
+
+	dev->domain_num = vcap_register_domain();
+	if (dev->domain_num < 0) {
+		pr_err("%s: VCAP iommu domain register failed\n", __func__);
+		ret = -ENODEV;
+		goto free_resource;
+	}
+
+	dev->iommu_vcap_domain = msm_get_iommu_domain(dev->domain_num);
+	if (!dev->iommu_vcap_domain) {
+		pr_err("%s: No iommu vcap domain found\n", __func__);
+		ret = -ENODEV;
+		goto free_resource;
+	}
+
+	ret = vcap_enable(dev, &pdev->dev, 54860000);
+	if (ret)
+		goto unreg_dev;
+	msm_bus_scale_client_update_request(dev->bus_client_handle, 0);
+	dev->dbg_p.bw_request = 0;
+
+	ret = detect_vc(dev);
+
+	if (ret)
+		goto power_down;
+
+	/* init video device*/
+	vfd = video_device_alloc();
+	if (!vfd) {
+		ret = -ENOMEM;
+		goto deinit_vc;
+	}
+
+	*vfd = vcap_template;
+	vfd->v4l2_dev = &dev->v4l2_dev;
+
+	ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
+	if (ret < 0)
+		goto rel_vdev;
+
+	dev->vfd = vfd;
+	video_set_drvdata(vfd, dev);
+
+	dev->vcap_wq = create_workqueue("vcap");
+	if (!dev->vcap_wq) {
+		ret = -ENOMEM;
+		pr_err("Could not create workqueue");
+		goto rel_vdev;
+	}
+
+	dev->ion_client = msm_ion_client_create(-1, "vcap");
+	if (IS_ERR((void *)dev->ion_client)) {
+		pr_err("could not get ion client");
+		ret = PTR_ERR(dev->ion_client);
+		dev->ion_client = NULL;
+		goto rel_vcap_wq;
+	}
+
+	atomic_set(&dev->dbg_p.vc_drop_count, 0);
+	ret = vcap_debugfs_init(dev);
+	if (ret < 0)
+		pr_err("VCAP debugfs failed to load");
+
+	dev->vc_tot_buf = 2;
+	atomic_set(&dev->vc_enabled, 0);
+	atomic_set(&dev->vp_enabled, 0);
+	atomic_set(&dev->open_clients, 0);
+	dev->ddev = &pdev->dev;
+	mutex_init(&dev->dev_mutex);
+	init_waitqueue_head(&dev->vp_dummy_waitq);
+	vcap_disable(dev);
+
+	return 0;
+rel_vcap_wq:
+	destroy_workqueue(dev->vcap_wq);
+rel_vdev:
+	video_device_release(vfd);
+deinit_vc:
+	deinit_vc();
+power_down:
+	vcap_disable(dev);
+unreg_dev:
+	v4l2_device_unregister(&dev->v4l2_dev);
+free_resource:
+	iounmap(dev->vcapbase);
+	release_mem_region(dev->vcapmem->start, resource_size(dev->vcapmem));
+free_dev:
+	vcap_ctrl = NULL;
+	kfree(dev);
+	return ret;
+}
+
+static int __devexit vcap_remove(struct platform_device *pdev)
+{
+	struct vcap_dev *dev = vcap_ctrl;
+	vcap_debugfs_remove();
+	ion_client_destroy(dev->ion_client);
+	flush_workqueue(dev->vcap_wq);
+	destroy_workqueue(dev->vcap_wq);
+	video_device_release(dev->vfd);
+	deinit_vc();
+	vcap_disable(dev);
+	v4l2_device_unregister(&dev->v4l2_dev);
+	iounmap(dev->vcapbase);
+	release_mem_region(dev->vcapmem->start, resource_size(dev->vcapmem));
+	vcap_ctrl = NULL;
+	kfree(dev);
+
+	return 0;
+}
+
+struct platform_driver vcap_platform_driver = {
+	.driver		= {
+		.name	= MSM_VCAP_DRV_NAME,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= vcap_probe,
+	.remove		= vcap_remove,
+};
+
+static int __init vcap_init_module(void)
+{
+	return platform_driver_register(&vcap_platform_driver);
+}
+
+static void __exit vcap_exit_module(void)
+{
+	platform_driver_unregister(&vcap_platform_driver);
+}
+
+module_init(vcap_init_module);
+module_exit(vcap_exit_module);
+MODULE_DESCRIPTION("VCAP driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/vcap/vcap_vc.c b/drivers/media/platform/msm/vcap/vcap_vc.c
new file mode 100644
index 0000000..b64e624
--- /dev/null
+++ b/drivers/media/platform/msm/vcap/vcap_vc.c
@@ -0,0 +1,573 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
+#include <mach/camera.h>
+#include <linux/io.h>
+#include <linux/regulator/consumer.h>
+#include <mach/clk.h>
+#include <linux/clk.h>
+
+#include <media/v4l2-event.h>
+#include <media/vcap_v4l2.h>
+#include <media/vcap_fmt.h>
+#include "vcap_vc.h"
+
+void config_buffer(struct vcap_client_data *c_data,
+			struct vcap_buffer *buf,
+			void __iomem *y_addr,
+			void __iomem *c_addr)
+{
+	if (c_data->vc_format.color_space == HAL_VCAP_RGB) {
+		writel_relaxed(buf->paddr, y_addr);
+	} else {
+		int size = (c_data->vc_format.hactive_end -
+				c_data->vc_format.hactive_start);
+		if (c_data->stride == VC_STRIDE_32)
+			size = VCAP_STRIDE_CALC(size, VCAP_STRIDE_ALIGN_32);
+		else
+			size = VCAP_STRIDE_CALC(size, VCAP_STRIDE_ALIGN_16);
+		size *= (c_data->vc_format.vactive_end -
+				c_data->vc_format.vactive_start);
+		writel_relaxed(buf->paddr, y_addr);
+		writel_relaxed(buf->paddr + size, c_addr);
+	}
+}
+
+static void mov_buf_to_vp(struct work_struct *work)
+{
+	struct vp_work_t *vp_work = container_of(work, struct vp_work_t, work);
+	struct v4l2_buffer p;
+	struct vb2_buffer *vb_vc;
+	struct vcap_buffer *buf_vc;
+	struct vb2_buffer *vb_vp;
+	struct vcap_buffer *buf_vp;
+
+	int rc;
+	p.memory = V4L2_MEMORY_USERPTR;
+	while (1) {
+		p.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		if (!vp_work->cd->streaming)
+			return;
+		rc = vcvp_dqbuf(&vp_work->cd->vc_vidq, &p);
+		if (rc < 0)
+			return;
+
+		vb_vc = vp_work->cd->vc_vidq.bufs[p.index];
+		if (NULL == vb_vc) {
+			pr_debug("%s: buffer is NULL\n", __func__);
+			vcvp_qbuf(&vp_work->cd->vc_vidq, &p);
+			return;
+		}
+		buf_vc = container_of(vb_vc, struct vcap_buffer, vb);
+
+		vb_vp = vp_work->cd->vp_in_vidq.bufs[p.index];
+		if (NULL == vb_vp) {
+			pr_debug("%s: buffer is NULL\n", __func__);
+			vcvp_qbuf(&vp_work->cd->vc_vidq, &p);
+			return;
+		}
+		buf_vp = container_of(vb_vp, struct vcap_buffer, vb);
+		buf_vp->ion_handle = buf_vc->ion_handle;
+		buf_vp->paddr = buf_vc->paddr;
+		buf_vc->ion_handle = NULL;
+		buf_vc->paddr = 0;
+
+		p.type = V4L2_BUF_TYPE_INTERLACED_IN_DECODER;
+
+		/* This call should not fail */
+		rc = vcvp_qbuf(&vp_work->cd->vp_in_vidq, &p);
+		if (rc < 0) {
+			pr_err("%s: qbuf to vp_in failed\n", __func__);
+			buf_vc->ion_handle = buf_vp->ion_handle;
+			buf_vc->paddr = buf_vp->paddr;
+			buf_vp->ion_handle = NULL;
+			buf_vp->paddr = 0;
+			p.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+			vcvp_qbuf(&vp_work->cd->vc_vidq, &p);
+		}
+	}
+}
+
+static uint8_t correct_buf_num(uint32_t reg)
+{
+	int i;
+	bool block_found = false;
+	for (i = 0; i < VCAP_VC_MAX_BUF; i++) {
+		if (reg & (0x2 << i)) {
+			block_found = true;
+			continue;
+		}
+		if (block_found)
+			return i;
+	}
+	return 0;
+}
+
+static struct timeval interpolate_ts(struct timeval tv, uint32_t delta)
+{
+	if (tv.tv_usec < delta) {
+		tv.tv_sec--;
+		tv.tv_usec += VCAP_USEC - delta;
+	} else {
+		tv.tv_usec -= delta;
+	}
+	return tv;
+}
+
+inline void vc_isr_error_checking(struct vcap_dev *dev,
+		struct v4l2_event v4l2_evt, uint32_t irq)
+{
+	if (irq & 0x200) {
+		if (irq & 0x80000000) {
+			writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
+			v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
+				VCAP_VC_PIX_ERR_EVENT;
+			v4l2_event_queue(dev->vfd, &v4l2_evt);
+		}
+		if (irq & 0x40000000) {
+			writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
+			v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
+				VCAP_VC_LINE_ERR_EVENT;
+			v4l2_event_queue(dev->vfd, &v4l2_evt);
+		}
+		if (irq & 0x20000000) {
+			writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
+			v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
+				VCAP_VC_VSYNC_ERR_EVENT;
+			v4l2_event_queue(dev->vfd, &v4l2_evt);
+		}
+	}
+	if (irq & 0x00001000) {
+		writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
+		v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
+			VCAP_VC_VSYNC_SEQ_ERR;
+		v4l2_event_queue(dev->vfd, &v4l2_evt);
+	}
+	if (irq & 0x00000800) {
+		writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
+		v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
+			VCAP_VC_NPL_OFLOW_ERR_EVENT;
+		v4l2_event_queue(dev->vfd, &v4l2_evt);
+	}
+	if (irq & 0x00000400) {
+		writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
+		v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
+			VCAP_VC_LBUF_OFLOW_ERR_EVENT;
+		v4l2_event_queue(dev->vfd, &v4l2_evt);
+	}
+}
+
+inline uint8_t vc_isr_buffer_done_count(struct vcap_dev *dev,
+		struct vcap_client_data *c_data, uint32_t irq)
+{
+	int i;
+	uint8_t done_count = 0;
+	for (i = 0; i < VCAP_VC_MAX_BUF; i++) {
+		if (0x2 & (irq >> i))
+			done_count++;
+	}
+	return done_count;
+}
+
+inline bool vc_isr_verify_expect_buf_rdy(struct vcap_dev *dev,
+		struct vcap_client_data *c_data, struct v4l2_event v4l2_evt,
+		uint32_t irq, uint8_t done_count, uint8_t tot, uint8_t buf_num)
+{
+	int i;
+	/* Double check expected buffers are done */
+	for (i = 0; i < done_count; i++) {
+		if (!(irq & (0x1 << (((buf_num + i) % tot) + 1)))) {
+			v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
+				VCAP_VC_UNEXPECT_BUF_DONE;
+			v4l2_event_queue(dev->vfd, &v4l2_evt);
+			pr_debug("Unexpected buffer done\n");
+			c_data->vc_action.buf_num =
+				correct_buf_num(irq) % tot;
+			return true;
+		}
+	}
+	return false;
+}
+
+inline void vc_isr_update_timestamp(struct vcap_dev *dev,
+		struct vcap_client_data *c_data)
+{
+	uint32_t timestamp;
+
+	timestamp = readl_relaxed(VCAP_VC_TIMESTAMP);
+	if (timestamp < c_data->vc_action.last_ts) {
+		c_data->vc_action.vc_ts.tv_usec +=
+			(0xFFFFFFFF - c_data->vc_action.last_ts) +
+			timestamp + 1;
+	} else {
+		c_data->vc_action.vc_ts.tv_usec +=
+			timestamp - c_data->vc_action.last_ts;
+	}
+
+	c_data->vc_action.vc_ts.tv_sec +=
+		c_data->vc_action.vc_ts.tv_usec / VCAP_USEC;
+	c_data->vc_action.vc_ts.tv_usec =
+		c_data->vc_action.vc_ts.tv_usec % VCAP_USEC;
+	c_data->vc_action.last_ts = timestamp;
+}
+
+inline void vc_isr_no_new_buffer(struct vcap_dev *dev,
+		struct vcap_client_data *c_data, struct v4l2_event v4l2_evt)
+{
+	v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
+		VCAP_VC_BUF_OVERWRITE_EVENT;
+	v4l2_event_queue(dev->vfd, &v4l2_evt);
+
+	c_data->vc_action.field_dropped =
+		!c_data->vc_action.field_dropped;
+
+	c_data->vc_action.field1 =
+		!c_data->vc_action.field1;
+	atomic_inc(&dev->dbg_p.vc_drop_count);
+}
+
+inline void vc_isr_switch_buffers(struct vcap_dev *dev,
+		struct vcap_client_data *c_data, struct vcap_buffer *buf,
+		struct vb2_buffer *vb, uint8_t idx, int done_count, int i)
+{
+	/* Config vc with this new buffer */
+	config_buffer(c_data, buf, VCAP_VC_Y_ADDR_1 + 0x8 * idx,
+			VCAP_VC_C_ADDR_1 + 0x8 * idx);
+	vb->v4l2_buf.timestamp = interpolate_ts(
+		c_data->vc_action.vc_ts,
+		1000000 / c_data->vc_format.frame_rate *
+		(done_count - 1 - i));
+	if (c_data->vc_format.mode == HAL_VCAP_MODE_INT) {
+		if (c_data->vc_action.field1)
+			vb->v4l2_buf.field = V4L2_FIELD_TOP;
+		else
+			vb->v4l2_buf.field = V4L2_FIELD_BOTTOM;
+
+		c_data->vc_action.field1 =
+			!c_data->vc_action.field1;
+	}
+	vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+	c_data->vc_action.buf[idx] = buf;
+}
+
+inline bool vc_isr_change_buffers(struct vcap_dev *dev,
+		struct vcap_client_data *c_data, struct v4l2_event v4l2_evt,
+		int done_count, uint8_t tot, uint8_t buf_num)
+{
+	struct vb2_buffer *vb = NULL;
+	struct vcap_buffer *buf;
+	bool schedule_work = false;
+	uint8_t idx;
+	int i;
+
+	for (i = 0; i < done_count; i++) {
+		idx = (buf_num + i) % tot;
+		vb = &c_data->vc_action.buf[idx]->vb;
+		spin_lock(&c_data->cap_slock);
+		if (list_empty(&c_data->vc_action.active)) {
+			spin_unlock(&c_data->cap_slock);
+			vc_isr_no_new_buffer(dev, c_data, v4l2_evt);
+			continue;
+		}
+		if (c_data->vc_format.mode == HAL_VCAP_MODE_INT &&
+				c_data->vc_action.field_dropped) {
+			spin_unlock(&c_data->cap_slock);
+			vc_isr_no_new_buffer(dev, c_data, v4l2_evt);
+			continue;
+		}
+		buf = list_entry(c_data->vc_action.active.next,
+				struct vcap_buffer, list);
+		list_del(&buf->list);
+		spin_unlock(&c_data->cap_slock);
+		vc_isr_switch_buffers(dev, c_data, buf, vb, idx, done_count, i);
+		schedule_work = true;
+	}
+	return schedule_work;
+}
+
+irqreturn_t vc_handler(struct vcap_dev *dev)
+{
+	uint32_t irq;
+	struct vcap_client_data *c_data;
+	struct v4l2_event v4l2_evt;
+	uint8_t done_count = 0, buf_num, tot;
+	bool schedule_work = false;
+
+	v4l2_evt.id = 0;
+	irq = readl_relaxed(VCAP_VC_INT_STATUS);
+	writel_relaxed(irq, VCAP_VC_INT_CLEAR);
+
+	pr_debug("%s: irq=0x%08x\n", __func__, irq);
+
+	if (dev->vc_client == NULL) {
+		/* This should never happen */
+		pr_err("VC: There is no active vc client\n");
+		return IRQ_HANDLED;
+	}
+
+	c_data = dev->vc_client;
+	if (!c_data->streaming) {
+		pr_err("VC no longer streaming\n");
+		return IRQ_HANDLED;
+	}
+
+	if (irq == VC_VSYNC_MASK) {
+		if (c_data->vc_format.mode == HAL_VCAP_MODE_INT)
+			c_data->vc_action.field1 = irq & 0x1;
+		return IRQ_HANDLED;
+	}
+
+	if (irq & VC_ERR_MASK) {
+		vc_isr_error_checking(dev, v4l2_evt, irq);
+		return IRQ_HANDLED;
+	}
+
+	if (!(irq & VC_BUFFER_MASK)) {
+		pr_debug("No frames done\n");
+		return IRQ_HANDLED;
+	}
+
+	done_count = vc_isr_buffer_done_count(dev, c_data, irq);
+	buf_num = c_data->vc_action.buf_num;
+	tot = c_data->vc_action.tot_buf;
+
+	if (vc_isr_verify_expect_buf_rdy(dev, c_data,
+			v4l2_evt, irq, done_count, tot, buf_num))
+		return IRQ_HANDLED;
+
+	vc_isr_update_timestamp(dev, c_data);
+
+	c_data->vc_action.buf_num = (buf_num + done_count) % tot;
+
+	schedule_work = vc_isr_change_buffers(dev, c_data, v4l2_evt,
+		done_count, tot, buf_num);
+
+	if (schedule_work && c_data->op_mode == VC_AND_VP_VCAP_OP)
+		queue_work(dev->vcap_wq, &dev->vc_to_vp_work.work);
+
+	return IRQ_HANDLED;
+}
+
+int vc_start_capture(struct vcap_client_data *c_data)
+{
+	return 0;
+}
+
+int vc_hw_kick_off(struct vcap_client_data *c_data)
+{
+	struct vc_action *vc_action = &c_data->vc_action;
+	struct vcap_dev *dev;
+	struct timeval tv;
+	unsigned long flags = 0;
+	int rc, i, counter = 0;
+	struct vcap_buffer *buf;
+
+	dev = c_data->dev;
+	pr_debug("Start Kickoff\n");
+
+	if (dev->vc_client == NULL) {
+		pr_err("No active vc client\n");
+		return -ENODEV;
+	}
+	c_data->vc_action.buf_num = 0;
+	spin_lock_irqsave(&dev->vc_client->cap_slock, flags);
+	if (list_empty(&dev->vc_client->vc_action.active)) {
+		spin_unlock_irqrestore(&dev->vc_client->cap_slock, flags);
+		pr_err("%s: VC We have no more avilable buffers\n",
+				__func__);
+		return -EINVAL;
+	}
+
+	list_for_each_entry(buf, &vc_action->active, list)
+		counter++;
+
+	if (counter < c_data->vc_action.tot_buf) {
+		/* not enough buffers have been queued */
+		spin_unlock_irqrestore(&dev->vc_client->cap_slock, flags);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < c_data->vc_action.tot_buf; i++) {
+		vc_action->buf[i] = list_entry(vc_action->active.next,
+			struct vcap_buffer, list);
+		list_del(&vc_action->buf[i]->list);
+	}
+	spin_unlock_irqrestore(&dev->vc_client->cap_slock, flags);
+
+	for (i = 0; i < c_data->vc_action.tot_buf; i++) {
+		config_buffer(c_data, vc_action->buf[i],
+			VCAP_VC_Y_ADDR_1 + i * 8,
+			VCAP_VC_C_ADDR_1 + i * 8);
+	}
+
+	c_data->vc_action.last_ts = readl_relaxed(VCAP_VC_TIMESTAMP);
+	c_data->vc_action.vc_ts.tv_sec =
+		c_data->vc_action.last_ts / VCAP_USEC;
+	c_data->vc_action.vc_ts.tv_usec =
+		c_data->vc_action.last_ts % VCAP_USEC;
+
+	atomic_set(&dev->dbg_p.vc_drop_count, 0);
+	do_gettimeofday(&tv);
+	dev->dbg_p.vc_timestamp = (uint32_t) (tv.tv_sec * VCAP_USEC +
+		tv.tv_usec);
+
+	rc = 0;
+	for (i = 0; i < c_data->vc_action.tot_buf; i++)
+		rc = rc << 1 | 0x2;
+	rc |= VC_ERR_MASK;
+	rc |= VC_VSYNC_MASK;
+	writel_relaxed(rc, VCAP_VC_INT_MASK);
+
+	enable_irq(dev->vcirq->start);
+	rc = readl_relaxed(VCAP_VC_CTRL);
+	writel_iowmb(rc | 0x1, VCAP_VC_CTRL);
+
+	return 0;
+}
+
+void vc_stop_capture(struct vcap_client_data *c_data)
+{
+	struct vcap_dev *dev = c_data->dev;
+	unsigned int reg;
+	int timeout;
+
+	writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
+	writel_iowmb(0x0, VCAP_VC_INT_MASK);
+	flush_workqueue(dev->vcap_wq);
+	if (atomic_read(&dev->vc_enabled) == 1)
+		disable_irq_nosync(dev->vcirq->start);
+
+	writel_iowmb(0x00000000, VCAP_VC_CTRL);
+	writel_iowmb(0x00000001, VCAP_SW_RESET_REQ);
+	timeout = 10000;
+	while (1) {
+		reg = (readl_relaxed(VCAP_SW_RESET_STATUS) & 0x1);
+		if (!reg)
+			break;
+		timeout--;
+		if (timeout == 0) {
+			/* This should not happen */
+			pr_err("VC is not resetting properly\n");
+			writel_iowmb(0x00000000, VCAP_SW_RESET_REQ);
+			break;
+		}
+	}
+
+	reg = readl_relaxed(VCAP_VC_NPL_CTRL);
+	reg = readl_relaxed(VCAP_VC_NPL_CTRL);
+	writel_iowmb(0x00000002, VCAP_VC_NPL_CTRL);
+}
+
+int config_vc_format(struct vcap_client_data *c_data)
+{
+	struct vcap_dev *dev;
+	unsigned int rc;
+	int timeout;
+	struct v4l2_format_vc_ext *vc_format = &c_data->vc_format;
+	dev = c_data->dev;
+
+	/* restart VC */
+	writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
+	writel_iowmb(0x00000001, VCAP_SW_RESET_REQ);
+	timeout = 10000;
+	while (1) {
+		if (!(readl_relaxed(VCAP_SW_RESET_STATUS) & 0x1))
+			break;
+		timeout--;
+		if (timeout == 0) {
+			pr_err("VC is not resetting properly\n");
+			writel_iowmb(0x00000002, VCAP_VC_NPL_CTRL);
+			return -EINVAL;
+		}
+	}
+
+	rc = readl_relaxed(VCAP_VC_NPL_CTRL);
+	rc = readl_relaxed(VCAP_VC_NPL_CTRL);
+	writel_iowmb(0x00000002, VCAP_VC_NPL_CTRL);
+
+	pr_debug("%s: Starting VC configuration\n", __func__);
+	writel_iowmb(0x00000002, VCAP_VC_NPL_CTRL);
+	writel_iowmb(0x00000004 | vc_format->color_space << 1 |
+			vc_format->mode << 3 |
+			(c_data->vc_action.tot_buf - 2) << 4 |
+			vc_format->mode << 10,
+			VCAP_VC_CTRL);
+
+	writel_relaxed(vc_format->d_polar << 8 |
+			vc_format->h_polar << 4 |
+			vc_format->v_polar << 0, VCAP_VC_POLARITY);
+
+	writel_relaxed(((vc_format->htotal << 16) | vc_format->vtotal),
+			VCAP_VC_V_H_TOTAL);
+	writel_relaxed(((vc_format->hactive_end << 16) |
+			vc_format->hactive_start), VCAP_VC_H_ACTIVE);
+
+	writel_relaxed(((vc_format->vactive_end << 16) |
+			vc_format->vactive_start), VCAP_VC_V_ACTIVE);
+	writel_relaxed(((vc_format->f2_vactive_end << 16) |
+			vc_format->f2_vactive_start), VCAP_VC_V_ACTIVE_F2);
+	writel_relaxed(((vc_format->vsync_end << 16) | vc_format->vsync_start),
+			VCAP_VC_VSYNC_VPOS);
+	writel_relaxed(((vc_format->f2_vsync_v_end << 16) |
+			vc_format->f2_vsync_v_start), VCAP_VC_VSYNC_F2_VPOS);
+	writel_relaxed(((vc_format->hsync_end << 16) |
+			vc_format->hsync_start), VCAP_VC_HSYNC_HPOS);
+	writel_relaxed(((vc_format->f2_vsync_h_end << 16) |
+			vc_format->f2_vsync_h_start), VCAP_VC_VSYNC_F2_HPOS);
+	writel_iowmb(0x000033FF, VCAP_VC_BUF_CTRL);
+
+	rc = vc_format->hactive_end - vc_format->hactive_start;
+	if (c_data->stride == VC_STRIDE_32)
+		rc = VCAP_STRIDE_CALC(rc, VCAP_STRIDE_ALIGN_32);
+	else
+		rc = VCAP_STRIDE_CALC(rc, VCAP_STRIDE_ALIGN_16);
+	if (vc_format->color_space)
+		rc *= 3;
+
+	writel_relaxed(rc, VCAP_VC_Y_STRIDE);
+	writel_relaxed(rc, VCAP_VC_C_STRIDE);
+
+	writel_relaxed(0x00010033 , VCAP_OFFSET(0x0898));
+	writel_relaxed(0x00010fff , VCAP_OFFSET(0x089c));
+	writel_relaxed(0x0a418820, VCAP_VC_IN_CTRL1);
+	writel_relaxed(0x16a4a0e6, VCAP_VC_IN_CTRL2);
+	writel_relaxed(0x2307b9ac, VCAP_VC_IN_CTRL3);
+	writel_relaxed(0x2f6ad272, VCAP_VC_IN_CTRL4);
+	writel_relaxed(0x00006b38, VCAP_VC_IN_CTRL5);
+
+	writel_iowmb(0x00000001 , VCAP_OFFSET(0x0d00));
+	pr_debug("%s: Done VC configuration\n", __func__);
+
+	return 0;
+}
+
+int detect_vc(struct vcap_dev *dev)
+{
+	int result;
+	result = readl_relaxed(VCAP_HARDWARE_VERSION_REG);
+	pr_debug("Hardware version: %08x\n", result);
+	if (result != VCAP_HARDWARE_VERSION)
+		return -ENODEV;
+	INIT_WORK(&dev->vc_to_vp_work.work, mov_buf_to_vp);
+	return 0;
+}
+
+int deinit_vc(void)
+{
+	return 0;
+}
diff --git a/drivers/media/platform/msm/vcap/vcap_vc.h b/drivers/media/platform/msm/vcap/vcap_vc.h
new file mode 100644
index 0000000..20320dd
--- /dev/null
+++ b/drivers/media/platform/msm/vcap/vcap_vc.h
@@ -0,0 +1,76 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef VCAP_VC_H
+#define VCAP_VC_H
+
+#include <linux/interrupt.h>
+
+#include <media/vcap_v4l2.h>
+
+#define VCAP_HARDWARE_VERSION 0x10000000
+
+#define VCAP_HARDWARE_VERSION_REG (VCAP_BASE + 0x0000)
+
+#define VCAP_VC_CTRL (VCAP_BASE + 0x0800)
+#define VCAP_VC_NPL_CTRL (VCAP_BASE + 0x0804)
+#define VCAP_VC_POLARITY (VCAP_BASE + 0x081c)
+#define VCAP_VC_V_H_TOTAL (VCAP_BASE + 0x0820)
+#define VCAP_VC_H_ACTIVE (VCAP_BASE + 0x0824)
+#define VCAP_VC_V_ACTIVE (VCAP_BASE + 0x0828)
+#define VCAP_VC_V_ACTIVE_F2 (VCAP_BASE + 0x0830)
+#define VCAP_VC_VSYNC_VPOS (VCAP_BASE + 0x0834)
+#define VCAP_VC_VSYNC_F2_VPOS (VCAP_BASE + 0x0838)
+#define VCAP_VC_HSYNC_HPOS (VCAP_BASE + 0x0840)
+#define VCAP_VC_VSYNC_F2_HPOS (VCAP_BASE + 0x083c)
+#define VCAP_VC_BUF_CTRL (VCAP_BASE + 0x0848)
+
+#define VCAP_VC_Y_STRIDE (VCAP_BASE + 0x084c)
+#define VCAP_VC_C_STRIDE (VCAP_BASE + 0x0850)
+
+#define VCAP_VC_Y_ADDR_1 (VCAP_BASE + 0x0854)
+#define VCAP_VC_C_ADDR_1 (VCAP_BASE + 0x0858)
+#define VCAP_VC_Y_ADDR_2 (VCAP_BASE + 0x085c)
+#define VCAP_VC_C_ADDR_2 (VCAP_BASE + 0x0860)
+#define VCAP_VC_Y_ADDR_3 (VCAP_BASE + 0x0864)
+#define VCAP_VC_C_ADDR_3 (VCAP_BASE + 0x0868)
+#define VCAP_VC_Y_ADDR_4 (VCAP_BASE + 0x086c)
+#define VCAP_VC_C_ADDR_4 (VCAP_BASE + 0x0870)
+#define VCAP_VC_Y_ADDR_5 (VCAP_BASE + 0x0874)
+#define VCAP_VC_C_ADDR_5 (VCAP_BASE + 0x0878)
+#define VCAP_VC_Y_ADDR_6 (VCAP_BASE + 0x087c)
+#define VCAP_VC_C_ADDR_6 (VCAP_BASE + 0x0880)
+
+#define VCAP_VC_IN_CTRL1 (VCAP_BASE + 0x0808)
+#define VCAP_VC_IN_CTRL2 (VCAP_BASE + 0x080c)
+#define VCAP_VC_IN_CTRL3 (VCAP_BASE + 0x0810)
+#define VCAP_VC_IN_CTRL4 (VCAP_BASE + 0x0814)
+#define VCAP_VC_IN_CTRL5 (VCAP_BASE + 0x0818)
+
+#define VCAP_VC_INT_MASK (VCAP_BASE + 0x0884)
+#define VCAP_VC_INT_CLEAR (VCAP_BASE + 0x0888)
+#define VCAP_VC_INT_STATUS (VCAP_BASE + 0x088c)
+#define VCAP_VC_TIMESTAMP (VCAP_BASE + 0x0034)
+
+#define VC_BUFFER_WRITTEN (0x3 << 1)
+#define VC_BUFFER_MASK 0x7E
+#define VC_ERR_MASK 0xE0001E00
+#define VC_VSYNC_MASK 0x1
+
+int vc_start_capture(struct vcap_client_data *c_data);
+int vc_hw_kick_off(struct vcap_client_data *c_data);
+void vc_stop_capture(struct vcap_client_data *c_data);
+int config_vc_format(struct vcap_client_data *c_data);
+int detect_vc(struct vcap_dev *dev);
+int deinit_vc(void);
+irqreturn_t vc_handler(struct vcap_dev *dev);
+#endif
diff --git a/drivers/media/platform/msm/vcap/vcap_vp.c b/drivers/media/platform/msm/vcap/vcap_vp.c
new file mode 100644
index 0000000..aba7095
--- /dev/null
+++ b/drivers/media/platform/msm/vcap/vcap_vp.c
@@ -0,0 +1,897 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/camera.h>
+#include <mach/clk.h>
+
+#include <media/v4l2-event.h>
+#include <media/vcap_v4l2.h>
+#include <media/vcap_fmt.h>
+
+#include "vcap_vp.h"
+
+void config_nr_buffer(struct vcap_client_data *c_data,
+			struct vcap_buffer *buf)
+{
+	struct vcap_dev *dev = c_data->dev;
+	int size = c_data->vp_in_fmt.height * c_data->vp_in_fmt.width;
+
+	writel_relaxed(buf->paddr, VCAP_VP_NR_T2_Y_BASE_ADDR);
+	writel_relaxed(buf->paddr + size, VCAP_VP_NR_T2_C_BASE_ADDR);
+}
+
+void config_in_buffer(struct vcap_client_data *c_data,
+			struct vcap_buffer *buf)
+{
+	struct vcap_dev *dev = c_data->dev;
+	int size = c_data->vp_in_fmt.height * c_data->vp_in_fmt.width;
+
+	writel_relaxed(buf->paddr, VCAP_VP_T2_Y_BASE_ADDR);
+	writel_relaxed(buf->paddr + size, VCAP_VP_T2_C_BASE_ADDR);
+}
+
+void config_out_buffer(struct vcap_client_data *c_data,
+			struct vcap_buffer *buf)
+{
+	struct vcap_dev *dev = c_data->dev;
+	int size;
+	size = c_data->vp_out_fmt.height * c_data->vp_out_fmt.width;
+	writel_relaxed(buf->paddr, VCAP_VP_OUT_Y_BASE_ADDR);
+	writel_relaxed(buf->paddr + size, VCAP_VP_OUT_C_BASE_ADDR);
+}
+
+int vp_setup_buffers(struct vcap_client_data *c_data)
+{
+	struct vp_action *vp_act;
+	struct vcap_dev *dev;
+	unsigned long flags = 0;
+
+	if (!c_data->streaming)
+		return -ENOEXEC;
+	dev = c_data->dev;
+	pr_debug("VP: Start setup buffers\n");
+
+	if (dev->vp_shutdown) {
+		pr_debug("%s: VP shutting down, no buf setup\n",
+			__func__);
+		return -EPERM;
+	}
+
+	/* No need to verify vp_client is not NULL caller does so */
+	vp_act = &dev->vp_client->vp_action;
+
+	spin_lock_irqsave(&dev->vp_client->cap_slock, flags);
+	if (list_empty(&vp_act->in_active)) {
+		spin_unlock_irqrestore(&dev->vp_client->cap_slock, flags);
+		pr_debug("%s: VP We have no more input buffers\n",
+				__func__);
+		return -EAGAIN;
+	}
+
+	if (list_empty(&vp_act->out_active)) {
+		spin_unlock_irqrestore(&dev->vp_client->cap_slock,
+			flags);
+		pr_debug("%s: VP We have no more output buffers\n",
+		   __func__);
+		return -EAGAIN;
+	}
+
+	vp_act->bufT2 = list_entry(vp_act->in_active.next,
+			struct vcap_buffer, list);
+	list_del(&vp_act->bufT2->list);
+
+	vp_act->bufOut = list_entry(vp_act->out_active.next,
+			struct vcap_buffer, list);
+	list_del(&vp_act->bufOut->list);
+	spin_unlock_irqrestore(&dev->vp_client->cap_slock, flags);
+
+	config_in_buffer(c_data, vp_act->bufT2);
+	config_out_buffer(c_data, vp_act->bufOut);
+	return 0;
+}
+
+static void mov_buf_to_vc(struct work_struct *work)
+{
+	struct vp_work_t *vp_work = container_of(work, struct vp_work_t, work);
+	struct v4l2_buffer p;
+	struct vb2_buffer *vb_vc;
+	struct vcap_buffer *buf_vc;
+	struct vb2_buffer *vb_vp;
+	struct vcap_buffer *buf_vp;
+	int rc;
+
+	p.memory = V4L2_MEMORY_USERPTR;
+
+	/* This loop exits when there is no more buffers left */
+	while (1) {
+		p.type = V4L2_BUF_TYPE_INTERLACED_IN_DECODER;
+		if (!vp_work->cd->streaming)
+			return;
+		rc = vcvp_dqbuf(&vp_work->cd->vp_in_vidq, &p);
+		if (rc < 0)
+			return;
+
+		vb_vc = vp_work->cd->vc_vidq.bufs[p.index];
+		if (NULL == vb_vc) {
+			pr_debug("%s: buffer is NULL\n", __func__);
+			vcvp_qbuf(&vp_work->cd->vp_in_vidq, &p);
+			return;
+		}
+		buf_vc = container_of(vb_vc, struct vcap_buffer, vb);
+
+		vb_vp = vp_work->cd->vp_in_vidq.bufs[p.index];
+		if (NULL == vb_vp) {
+			pr_debug("%s: buffer is NULL\n", __func__);
+			vcvp_qbuf(&vp_work->cd->vp_in_vidq, &p);
+			return;
+		}
+		buf_vp = container_of(vb_vp, struct vcap_buffer, vb);
+		buf_vc->ion_handle = buf_vp->ion_handle;
+		buf_vc->paddr = buf_vp->paddr;
+		buf_vp->ion_handle = NULL;
+		buf_vp->paddr = 0;
+
+		p.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		/* This call should not fail */
+		rc = vcvp_qbuf(&vp_work->cd->vc_vidq, &p);
+		if (rc < 0) {
+			pr_err("%s: qbuf to vc failed\n", __func__);
+			buf_vp->ion_handle = buf_vc->ion_handle;
+			buf_vp->paddr = buf_vc->paddr;
+			buf_vc->ion_handle = NULL;
+			buf_vc->paddr = 0;
+			p.type = V4L2_BUF_TYPE_INTERLACED_IN_DECODER;
+			vcvp_qbuf(&vp_work->cd->vp_in_vidq, &p);
+		}
+	}
+}
+
+void update_nr_value(struct vcap_dev *dev)
+{
+	struct nr_param *par;
+	uint32_t val = 0;
+	par = &dev->nr_param;
+	if (par->mode == NR_MANUAL) {
+		writel_relaxed(par->window << 24 | par->decay_ratio << 20,
+			VCAP_VP_NR_CONFIG);
+		if (par->threshold)
+			val = VP_NR_DYNAMIC_THRESHOLD;
+		writel_relaxed(val |
+			par->luma.max_blend_ratio << 24 |
+			par->luma.scale_diff_ratio << 12 |
+			par->luma.diff_limit_ratio << 8  |
+			par->luma.scale_motion_ratio << 4 |
+			par->luma.blend_limit_ratio << 0,
+			VCAP_VP_NR_LUMA_CONFIG);
+		writel_relaxed(val |
+			par->chroma.max_blend_ratio << 24 |
+			par->chroma.scale_diff_ratio << 12 |
+			par->chroma.diff_limit_ratio << 8  |
+			par->chroma.scale_motion_ratio << 4 |
+			par->chroma.blend_limit_ratio << 0,
+			VCAP_VP_NR_CHROMA_CONFIG);
+	}
+	dev->nr_update = false;
+}
+
+static void vp_wq_fnc(struct work_struct *work)
+{
+	struct vp_work_t *vp_work = container_of(work, struct vp_work_t, work);
+	struct vcap_dev *dev;
+	struct vp_action *vp_act;
+	struct timeval tv;
+	unsigned long flags = 0;
+	uint32_t irq;
+	int rc;
+	bool top_field = 0;
+
+	if (vp_work && vp_work->cd && vp_work->cd->dev)
+		dev = vp_work->cd->dev;
+	else
+		return;
+
+	vp_act = &dev->vp_client->vp_action;
+
+	rc = readl_relaxed(VCAP_OFFSET(0x048));
+	while (!(rc & 0x00000100))
+		rc = readl_relaxed(VCAP_OFFSET(0x048));
+
+	irq = readl_relaxed(VCAP_VP_INT_STATUS);
+
+	writel_relaxed(0x00000000, VCAP_VP_BAL_VMOTION_STATE);
+	writel_relaxed(0x40000000, VCAP_VP_REDUCT_AVG_MOTION2);
+
+	spin_lock_irqsave(&dev->vp_client->cap_slock, flags);
+	if (dev->nr_update == true)
+		update_nr_value(dev);
+	spin_unlock_irqrestore(&dev->vp_client->cap_slock, flags);
+
+	/* Queue the done buffers */
+	if (vp_act->vp_state == VP_NORMAL &&
+			vp_act->bufNR.nr_pos != TM1_BUF) {
+		vb2_buffer_done(&vp_act->bufTm1->vb, VB2_BUF_STATE_DONE);
+		if (vp_work->cd->op_mode == VC_AND_VP_VCAP_OP)
+			queue_work(dev->vcap_wq, &dev->vp_to_vc_work.work);
+	}
+
+	if (vp_act->bufT0 != NULL && vp_act->vp_state == VP_NORMAL) {
+		vp_act->bufOut->vb.v4l2_buf.timestamp =
+			vp_act->bufT0->vb.v4l2_buf.timestamp;
+	}
+	vb2_buffer_done(&vp_act->bufOut->vb, VB2_BUF_STATE_DONE);
+
+	/* Cycle to next state */
+	if (vp_act->vp_state != VP_NORMAL)
+		vp_act->vp_state++;
+
+	/* Cycle Buffers*/
+	if (dev->nr_param.mode) {
+		if (vp_act->bufNR.nr_pos == TM1_BUF)
+			vp_act->bufNR.nr_pos = BUF_NOT_IN_USE;
+
+		if (vp_act->bufNR.nr_pos != BUF_NOT_IN_USE)
+			vp_act->bufNR.nr_pos++;
+
+		vp_act->bufTm1 = vp_act->bufT0;
+		vp_act->bufT0 = vp_act->bufT1;
+		vp_act->bufT1 = vp_act->bufNRT2;
+		vp_act->bufNRT2 = vp_act->bufT2;
+		config_nr_buffer(vp_work->cd, vp_act->bufNRT2);
+	} else {
+		vp_act->bufTm1 = vp_act->bufT0;
+		vp_act->bufT0 = vp_act->bufT1;
+		vp_act->bufT1 = vp_act->bufT2;
+	}
+
+	rc = vp_setup_buffers(vp_work->cd);
+	if (rc < 0) {
+		/* setup_buf failed because we are waiting for buffers */
+		writel_relaxed(0x00000000, VCAP_VP_INTERRUPT_ENABLE);
+		writel_iowmb(irq, VCAP_VP_INT_CLEAR);
+		atomic_set(&dev->vp_enabled, 0);
+		if (dev->vp_shutdown)
+			wake_up(&dev->vp_dummy_waitq);
+		return;
+	}
+
+	/* Config VP */
+	if (vp_act->bufT2->vb.v4l2_buf.field == V4L2_FIELD_BOTTOM)
+		top_field = 1;
+
+	writel_iowmb(0x00000000 | top_field, VCAP_VP_CTRL);
+	writel_iowmb(0x00010000 | top_field, VCAP_VP_CTRL);
+	enable_irq(dev->vpirq->start);
+
+	do_gettimeofday(&tv);
+	dev->dbg_p.vp_timestamp = (uint32_t) (tv.tv_sec * VCAP_USEC +
+	tv.tv_usec);
+
+	writel_iowmb(irq, VCAP_VP_INT_CLEAR);
+}
+
+irqreturn_t vp_handler(struct vcap_dev *dev)
+{
+	struct vcap_client_data *c_data;
+	struct vp_action *vp_act;
+	struct v4l2_event v4l2_evt;
+	uint32_t irq;
+	int rc;
+	struct timeval tv;
+	uint32_t new_ts;
+
+	irq = readl_relaxed(VCAP_VP_INT_STATUS);
+	if (dev->vp_dummy_event == true) {
+		writel_relaxed(irq, VCAP_VP_INT_CLEAR);
+		dev->vp_dummy_complete = true;
+		wake_up(&dev->vp_dummy_waitq);
+		return IRQ_HANDLED;
+	}
+
+	if (irq & 0x02000000) {
+		v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
+			VCAP_VP_REG_R_ERR_EVENT;
+		v4l2_event_queue(dev->vfd, &v4l2_evt);
+	}
+	if (irq & 0x01000000) {
+		v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
+			VCAP_VP_REG_W_ERR_EVENT;
+		v4l2_event_queue(dev->vfd, &v4l2_evt);
+	}
+	if (irq & 0x00020000) {
+		v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
+			VCAP_VP_IN_HEIGHT_ERR_EVENT;
+		v4l2_event_queue(dev->vfd, &v4l2_evt);
+	}
+	if (irq & 0x00010000) {
+		v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
+			VCAP_VP_IN_WIDTH_ERR_EVENT;
+		v4l2_event_queue(dev->vfd, &v4l2_evt);
+	}
+
+	pr_debug("%s: irq=0x%08x\n", __func__, irq);
+	if (!(irq & (VP_PIC_DONE | VP_MODE_CHANGE))) {
+		writel_relaxed(irq, VCAP_VP_INT_CLEAR);
+		pr_err("VP IRQ shows some error\n");
+		return IRQ_HANDLED;
+	}
+
+	if (dev->vp_client == NULL) {
+		writel_relaxed(irq, VCAP_VP_INT_CLEAR);
+		pr_err("VC: There is no active vp client\n");
+		return IRQ_HANDLED;
+	}
+
+	vp_act = &dev->vp_client->vp_action;
+	c_data = dev->vp_client;
+
+	if (vp_act->vp_state == VP_UNKNOWN) {
+		writel_relaxed(irq, VCAP_VP_INT_CLEAR);
+		pr_err("%s: VP is in an unknown state\n",
+				__func__);
+		return -EAGAIN;
+	}
+
+	do_gettimeofday(&tv);
+	new_ts = (uint32_t) (tv.tv_sec * VCAP_USEC +
+		tv.tv_usec);
+	if (new_ts > dev->dbg_p.vp_timestamp) {
+		dev->dbg_p.vp_ewma = ((new_ts - dev->dbg_p.vp_timestamp) /
+			10 + (dev->dbg_p.vp_ewma / 10 * 9));
+	}
+
+	dev->dbg_p.vp_timestamp = (uint32_t) (tv.tv_sec * VCAP_USEC +
+	tv.tv_usec);
+
+	INIT_WORK(&dev->vp_work.work, vp_wq_fnc);
+	dev->vp_work.cd = c_data;
+	rc = queue_work(dev->vcap_wq, &dev->vp_work.work);
+
+	disable_irq_nosync(dev->vpirq->start);
+	return IRQ_HANDLED;
+}
+
+int vp_sw_reset(struct vcap_dev *dev)
+{
+	int timeout;
+	writel_iowmb(0x00000010, VCAP_SW_RESET_REQ);
+	timeout = 10000;
+	while (1) {
+		if (!(readl_relaxed(VCAP_SW_RESET_STATUS) & 0x10))
+			break;
+		timeout--;
+		if (timeout == 0) {
+			/* This should not happen */
+			pr_err("VP is not resetting properly\n");
+			writel_iowmb(0x00000000, VCAP_SW_RESET_REQ);
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+void vp_stop_capture(struct vcap_client_data *c_data)
+{
+	struct vcap_dev *dev = c_data->dev;
+	int rc;
+
+	dev->vp_shutdown = true;
+	flush_workqueue(dev->vcap_wq);
+
+	if (atomic_read(&dev->vp_enabled) == 1) {
+		rc = wait_event_interruptible_timeout(dev->vp_dummy_waitq,
+				!atomic_read(&dev->vp_enabled),
+				msecs_to_jiffies(50));
+		if (rc == 0 && atomic_read(&dev->vp_enabled) == 1) {
+			/* This should not happen, if it does hw is stuck */
+			disable_irq_nosync(dev->vpirq->start);
+			atomic_set(&dev->vp_enabled, 0);
+			pr_err("%s: VP Timeout and VP still running\n",
+				__func__);
+		}
+	}
+
+	vp_sw_reset(dev);
+	dev->vp_shutdown = false;
+}
+
+int config_vp_format(struct vcap_client_data *c_data)
+{
+	struct vcap_dev *dev = c_data->dev;
+	int rc;
+
+	INIT_WORK(&dev->vp_to_vc_work.work, mov_buf_to_vc);
+	dev->vp_to_vc_work.cd = c_data;
+
+	/* SW restart VP */
+	rc = vp_sw_reset(dev);
+	if (rc < 0)
+		return rc;
+
+	/* Film Mode related settings */
+	writel_iowmb(0x00000000, VCAP_VP_FILM_PROJECTION_T0);
+	writel_relaxed(0x00000000, VCAP_VP_FILM_PROJECTION_T2);
+	writel_relaxed(0x00000000, VCAP_VP_FILM_PAST_MAX_PROJ);
+	writel_relaxed(0x00000000, VCAP_VP_FILM_PAST_MIN_PROJ);
+	writel_relaxed(0x00000000, VCAP_VP_FILM_SEQUENCE_HIST);
+	writel_relaxed(0x00000000, VCAP_VP_FILM_MODE_STATE);
+
+	writel_relaxed(0x00000000, VCAP_VP_BAL_VMOTION_STATE);
+	writel_relaxed(0x00000010, VCAP_VP_REDUCT_AVG_MOTION);
+	writel_relaxed(0x40000000, VCAP_VP_REDUCT_AVG_MOTION2);
+	writel_relaxed(0x40000000, VCAP_VP_NR_AVG_LUMA);
+	writel_relaxed(0x40000000, VCAP_VP_NR_AVG_CHROMA);
+	writel_relaxed(0x40000000, VCAP_VP_NR_CTRL_LUMA);
+	writel_relaxed(0x40000000, VCAP_VP_NR_CTRL_CHROMA);
+	writel_relaxed(0x00000000, VCAP_VP_BAL_AVG_BLEND);
+	writel_relaxed(0x00000000, VCAP_VP_VMOTION_HIST);
+	writel_relaxed(0x05047D19, VCAP_VP_FILM_ANALYSIS_CONFIG);
+	writel_relaxed(0x20260200, VCAP_VP_FILM_STATE_CONFIG);
+	writel_relaxed(0x23A60114, VCAP_VP_FVM_CONFIG);
+	writel_relaxed(0x03043210, VCAP_VP_FILM_ANALYSIS_CONFIG2);
+	writel_relaxed(0x04DB7A51, VCAP_VP_MIXED_ANALYSIS_CONFIG);
+	writel_relaxed(0x14224916, VCAP_VP_SPATIAL_CONFIG);
+	writel_relaxed(0x83270400, VCAP_VP_SPATIAL_CONFIG2);
+	writel_relaxed(0x0F000F92, VCAP_VP_SPATIAL_CONFIG3);
+	writel_relaxed(0x00000000, VCAP_VP_TEMPORAL_CONFIG);
+	writel_relaxed(0x00000000, VCAP_VP_PIXEL_DIFF_CONFIG);
+	writel_relaxed(0x0C090511, VCAP_VP_H_FREQ_CONFIG);
+	writel_relaxed(0x0A000000, VCAP_VP_NR_CONFIG);
+	writel_relaxed(0x008F4149, VCAP_VP_NR_LUMA_CONFIG);
+	writel_relaxed(0x008F4149, VCAP_VP_NR_CHROMA_CONFIG);
+	writel_relaxed(0x43C0FD0C, VCAP_VP_BAL_CONFIG);
+	writel_relaxed(0x00000255, VCAP_VP_BAL_MOTION_CONFIG);
+	writel_relaxed(0x24154252, VCAP_VP_BAL_LIGHT_COMB);
+	writel_relaxed(0x10024414, VCAP_VP_BAL_VMOTION_CONFIG);
+	writel_relaxed(0x00000002, VCAP_VP_NR_CONFIG2);
+	writel_relaxed((c_data->vp_out_fmt.height-1)<<16 |
+			(c_data->vp_out_fmt.width - 1), VCAP_VP_FRAME_SIZE);
+	writel_relaxed(0x00000000, VCAP_VP_SPLIT_SCRN_CTRL);
+
+	return 0;
+}
+
+int init_motion_buf(struct vcap_client_data *c_data)
+{
+	int rc;
+	struct vcap_dev *dev = c_data->dev;
+	struct ion_handle *handle = NULL;
+	unsigned long paddr, len;
+	void *vaddr;
+	size_t size = ((c_data->vp_out_fmt.width + 63) >> 6) *
+		((c_data->vp_out_fmt.height + 7) >> 3) * 16;
+
+	if (c_data->vp_action.motionHandle) {
+		pr_err("Motion buffer has already been created");
+		return -ENOEXEC;
+	}
+
+	handle = ion_alloc(dev->ion_client, size, SZ_4K,
+			ION_HEAP(ION_CP_MM_HEAP_ID), 0);
+	if (IS_ERR_OR_NULL(handle)) {
+		pr_err("%s: ion_alloc failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	vaddr = ion_map_kernel(dev->ion_client, handle);
+	if (IS_ERR(vaddr)) {
+		pr_err("%s: Map motion buffer failed\n", __func__);
+		ion_free(dev->ion_client, handle);
+		rc = -ENOMEM;
+		return rc;
+	}
+
+	memset(vaddr, 0, size);
+	ion_unmap_kernel(dev->ion_client, handle);
+
+	rc = ion_map_iommu(dev->ion_client, handle,
+		dev->domain_num, 0, SZ_4K, 0, &paddr, &len,
+		0, 0);
+	if (rc < 0) {
+		pr_err("%s: map_iommu failed\n", __func__);
+		ion_free(dev->ion_client, handle);
+		return rc;
+	}
+
+	c_data->vp_action.motionHandle = handle;
+
+	vaddr = NULL;
+
+	writel_iowmb(paddr, VCAP_VP_MOTION_EST_ADDR);
+	return 0;
+}
+
+void deinit_motion_buf(struct vcap_client_data *c_data)
+{
+	struct vcap_dev *dev = c_data->dev;
+	if (!c_data->vp_action.motionHandle) {
+		pr_err("Motion buffer has not been created");
+		return;
+	}
+
+	writel_iowmb(0x00000000, VCAP_VP_MOTION_EST_ADDR);
+	ion_unmap_iommu(dev->ion_client, c_data->vp_action.motionHandle,
+			dev->domain_num, 0);
+	ion_free(dev->ion_client, c_data->vp_action.motionHandle);
+	c_data->vp_action.motionHandle = NULL;
+	return;
+}
+
+int init_nr_buf(struct vcap_client_data *c_data)
+{
+	struct vcap_dev *dev = c_data->dev;
+	struct ion_handle *handle = NULL;
+	size_t frame_size, tot_size;
+	unsigned long paddr, len;
+	int rc;
+
+	if (c_data->vp_action.bufNR.nr_handle) {
+		pr_err("NR buffer has already been created");
+		return -ENOEXEC;
+	}
+
+	frame_size = c_data->vp_in_fmt.width * c_data->vp_in_fmt.height;
+	if (c_data->vp_in_fmt.pixfmt == V4L2_PIX_FMT_NV16)
+		tot_size = frame_size * 2;
+	else
+		tot_size = frame_size / 2 * 3;
+
+	handle = ion_alloc(dev->ion_client, tot_size, SZ_4K,
+			ION_HEAP(ION_CP_MM_HEAP_ID), 0);
+	if (IS_ERR_OR_NULL(handle)) {
+		pr_err("%s: ion_alloc failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	rc = ion_map_iommu(dev->ion_client, handle,
+		dev->domain_num, 0, SZ_4K, 0, &paddr, &len,
+		0, 0);
+	if (rc < 0) {
+		pr_err("%s: map_iommu failed\n", __func__);
+		ion_free(dev->ion_client, handle);
+		return rc;
+	}
+
+	c_data->vp_action.bufNR.nr_handle = handle;
+	update_nr_value(dev);
+
+	c_data->vp_action.bufNR.paddr = paddr;
+	rc = readl_relaxed(VCAP_VP_NR_CONFIG2);
+	rc |= (((c_data->vp_out_fmt.width / 16) << 20) | 0x1);
+	writel_relaxed(rc, VCAP_VP_NR_CONFIG2);
+	writel_relaxed(paddr, VCAP_VP_NR_T2_Y_BASE_ADDR);
+	writel_relaxed(paddr + frame_size, VCAP_VP_NR_T2_C_BASE_ADDR);
+	c_data->vp_action.bufNR.nr_pos = NRT2_BUF;
+	return 0;
+}
+
+void deinit_nr_buf(struct vcap_client_data *c_data)
+{
+	struct vcap_dev *dev = c_data->dev;
+	struct nr_buffer *buf;
+	uint32_t rc;
+
+	if (!c_data->vp_action.bufNR.nr_handle) {
+		pr_err("NR buffer has not been created");
+		return;
+	}
+	buf = &c_data->vp_action.bufNR;
+
+	rc = readl_relaxed(VCAP_VP_NR_CONFIG2);
+	rc &= !(0x0FF00001);
+	writel_relaxed(rc, VCAP_VP_NR_CONFIG2);
+
+	ion_unmap_iommu(dev->ion_client, buf->nr_handle, dev->domain_num, 0);
+	ion_free(dev->ion_client, buf->nr_handle);
+	buf->nr_handle = NULL;
+	buf->paddr = 0;
+	return;
+}
+
+int nr_s_param(struct vcap_client_data *c_data, struct nr_param *param)
+{
+	if (param->mode != NR_MANUAL)
+		return 0;
+
+	/* Verify values in range */
+	if (param->window > VP_NR_MAX_WINDOW)
+		return -EINVAL;
+	if (param->luma.max_blend_ratio > VP_NR_MAX_RATIO)
+		return -EINVAL;
+	if (param->luma.scale_diff_ratio > VP_NR_MAX_RATIO)
+		return -EINVAL;
+	if (param->luma.diff_limit_ratio > VP_NR_MAX_RATIO)
+		return -EINVAL;
+	if (param->luma.scale_motion_ratio > VP_NR_MAX_RATIO)
+		return -EINVAL;
+	if (param->luma.blend_limit_ratio > VP_NR_MAX_RATIO)
+		return -EINVAL;
+	if (param->chroma.max_blend_ratio > VP_NR_MAX_RATIO)
+		return -EINVAL;
+	if (param->chroma.scale_diff_ratio > VP_NR_MAX_RATIO)
+		return -EINVAL;
+	if (param->chroma.diff_limit_ratio > VP_NR_MAX_RATIO)
+		return -EINVAL;
+	if (param->chroma.scale_motion_ratio > VP_NR_MAX_RATIO)
+		return -EINVAL;
+	if (param->chroma.blend_limit_ratio > VP_NR_MAX_RATIO)
+		return -EINVAL;
+	return 0;
+}
+
+void nr_g_param(struct vcap_client_data *c_data, struct nr_param *param)
+{
+	struct vcap_dev *dev = c_data->dev;
+	uint32_t rc;
+	rc = readl_relaxed(VCAP_VP_NR_CONFIG);
+	param->window = BITS_VALUE(rc, 24, 4);
+	param->decay_ratio = BITS_VALUE(rc, 20, 3);
+
+	rc = readl_relaxed(VCAP_VP_NR_LUMA_CONFIG);
+	param->threshold = NR_THRESHOLD_STATIC;
+	if (BITS_VALUE(rc, 16, 1))
+		param->threshold = NR_THRESHOLD_DYNAMIC;
+	param->luma.max_blend_ratio = BITS_VALUE(rc, 24, 4);
+	param->luma.scale_diff_ratio = BITS_VALUE(rc, 12, 4);
+	param->luma.diff_limit_ratio = BITS_VALUE(rc, 8, 4);
+	param->luma.scale_motion_ratio = BITS_VALUE(rc, 4, 4);
+	param->luma.blend_limit_ratio = BITS_VALUE(rc, 0, 4);
+
+	rc = readl_relaxed(VCAP_VP_NR_CHROMA_CONFIG);
+	param->chroma.max_blend_ratio = BITS_VALUE(rc, 24, 4);
+	param->chroma.scale_diff_ratio = BITS_VALUE(rc, 12, 4);
+	param->chroma.diff_limit_ratio = BITS_VALUE(rc, 8, 4);
+	param->chroma.scale_motion_ratio = BITS_VALUE(rc, 4, 4);
+	param->chroma.blend_limit_ratio = BITS_VALUE(rc, 0, 4);
+}
+
+void s_default_nr_val(struct nr_param *param)
+{
+	param->threshold = NR_THRESHOLD_STATIC;
+	param->window = 10;
+	param->decay_ratio = 0;
+	param->luma.max_blend_ratio = 0;
+	param->luma.scale_diff_ratio = 4;
+	param->luma.diff_limit_ratio = 1;
+	param->luma.scale_motion_ratio = 4;
+	param->luma.blend_limit_ratio = 9;
+	param->chroma.max_blend_ratio = 0;
+	param->chroma.scale_diff_ratio = 4;
+	param->chroma.diff_limit_ratio = 1;
+	param->chroma.scale_motion_ratio = 4;
+	param->chroma.blend_limit_ratio = 9;
+}
+
+int vp_dummy_event(struct vcap_client_data *c_data)
+{
+	struct vcap_dev *dev = c_data->dev;
+	unsigned int width, height;
+	struct ion_handle *handle = NULL;
+	unsigned long paddr, len;
+	uint32_t reg;
+	int rc = 0;
+
+	pr_debug("%s: Start VP dummy event\n", __func__);
+	handle = ion_alloc(dev->ion_client, 0x1200, SZ_4K,
+			ION_HEAP(ION_CP_MM_HEAP_ID), 0);
+	if (IS_ERR_OR_NULL(handle)) {
+		pr_err("%s: ion_alloc failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	rc = ion_map_iommu(dev->ion_client, handle,
+		dev->domain_num, 0, SZ_4K, 0, &paddr, &len,
+		0, 0);
+	if (rc < 0) {
+		pr_err("%s: map_iommu failed\n", __func__);
+		ion_free(dev->ion_client, handle);
+		return rc;
+	}
+
+	width = c_data->vp_out_fmt.width;
+	height = c_data->vp_out_fmt.height;
+
+	c_data->vp_out_fmt.width = 0x3F;
+	c_data->vp_out_fmt.height = 0x16;
+
+	config_vp_format(c_data);
+	writel_relaxed(paddr, VCAP_VP_T1_Y_BASE_ADDR);
+	writel_relaxed(paddr + 0x2C0, VCAP_VP_T1_C_BASE_ADDR);
+	writel_relaxed(paddr + 0x440, VCAP_VP_T2_Y_BASE_ADDR);
+	writel_relaxed(paddr + 0x700, VCAP_VP_T2_C_BASE_ADDR);
+	writel_relaxed(paddr + 0x880, VCAP_VP_OUT_Y_BASE_ADDR);
+	writel_relaxed(paddr + 0xB40, VCAP_VP_OUT_C_BASE_ADDR);
+	writel_iowmb(paddr + 0x1100, VCAP_VP_MOTION_EST_ADDR);
+	writel_relaxed(4 << 20 | 0x2 << 4, VCAP_VP_IN_CONFIG);
+	writel_relaxed(4 << 20 | 0x1 << 4, VCAP_VP_OUT_CONFIG);
+
+	dev->vp_dummy_event = true;
+
+	enable_irq(dev->vpirq->start);
+	writel_relaxed(0x01100101, VCAP_VP_INTERRUPT_ENABLE);
+	writel_iowmb(0x00000000, VCAP_VP_CTRL);
+	writel_iowmb(0x00010000, VCAP_VP_CTRL);
+
+	rc = wait_event_interruptible_timeout(dev->vp_dummy_waitq,
+		dev->vp_dummy_complete, msecs_to_jiffies(50));
+	if (!rc && !dev->vp_dummy_complete) {
+		pr_err("%s: VP dummy event timeout", __func__);
+		rc = -ETIME;
+
+		vp_sw_reset(dev);
+		dev->vp_dummy_complete = false;
+	}
+
+	writel_relaxed(0x00000000, VCAP_VP_INTERRUPT_ENABLE);
+	disable_irq(dev->vpirq->start);
+	dev->vp_dummy_event = false;
+
+	reg = readl_relaxed(VCAP_OFFSET(0x0D94));
+	writel_relaxed(reg, VCAP_OFFSET(0x0D9C));
+
+	c_data->vp_out_fmt.width = width;
+	c_data->vp_out_fmt.height = height;
+	ion_unmap_iommu(dev->ion_client, handle, dev->domain_num, 0);
+	ion_free(dev->ion_client, handle);
+
+	pr_debug("%s: Exit VP dummy event\n", __func__);
+	return rc;
+}
+
+int kickoff_vp(struct vcap_client_data *c_data)
+{
+	struct vcap_dev *dev;
+	struct vp_action *vp_act;
+	struct timeval tv;
+	unsigned long flags = 0;
+	unsigned int chroma_fmt = 0;
+	int size;
+	bool top_field = 0;
+
+	if (!c_data->streaming)
+		return -ENOEXEC;
+
+	dev = c_data->dev;
+	pr_debug("Start VP Kickoff\n");
+
+	if (dev->vp_client == NULL) {
+		pr_err("No active vp client\n");
+		return -ENODEV;
+	}
+	vp_act = &dev->vp_client->vp_action;
+
+	spin_lock_irqsave(&dev->vp_client->cap_slock, flags);
+	if (list_empty(&vp_act->in_active)) {
+		spin_unlock_irqrestore(&dev->vp_client->cap_slock, flags);
+		pr_err("%s: VP We have no more input buffers\n",
+				__func__);
+		return -EAGAIN;
+	}
+
+	vp_act->bufT1 = list_entry(vp_act->in_active.next,
+			struct vcap_buffer, list);
+	list_del(&vp_act->bufT1->list);
+
+	if (list_empty(&vp_act->in_active)) {
+		spin_unlock_irqrestore(&dev->vp_client->cap_slock, flags);
+		list_add(&vp_act->bufT1->list, &vp_act->in_active);
+		pr_err("%s: VP We have no more input buffers\n",
+				__func__);
+		return -EAGAIN;
+	}
+
+	vp_act->bufT2 = list_entry(vp_act->in_active.next,
+			struct vcap_buffer, list);
+	list_del(&vp_act->bufT2->list);
+
+	if (list_empty(&vp_act->out_active)) {
+		spin_unlock_irqrestore(&dev->vp_client->cap_slock, flags);
+		list_add(&vp_act->bufT2->list, &vp_act->in_active);
+		list_add(&vp_act->bufT1->list, &vp_act->in_active);
+		pr_err("%s: VP We have no more output buffers\n",
+				__func__);
+		return -EAGAIN;
+	}
+
+	vp_act->bufOut = list_entry(vp_act->out_active.next,
+			struct vcap_buffer, list);
+	list_del(&vp_act->bufOut->list);
+	spin_unlock_irqrestore(&dev->vp_client->cap_slock, flags);
+
+	size = c_data->vp_in_fmt.height * c_data->vp_in_fmt.width;
+	writel_relaxed(vp_act->bufT1->paddr, VCAP_VP_T1_Y_BASE_ADDR);
+	writel_relaxed(vp_act->bufT1->paddr + size, VCAP_VP_T1_C_BASE_ADDR);
+
+	config_in_buffer(c_data, vp_act->bufT2);
+	config_out_buffer(c_data, vp_act->bufOut);
+
+	/* Config VP */
+	if (c_data->vp_in_fmt.pixfmt == V4L2_PIX_FMT_NV16)
+		chroma_fmt = 1;
+	writel_relaxed((c_data->vp_in_fmt.width / 16) << 20 |
+			chroma_fmt << 11 | 0x2 << 4, VCAP_VP_IN_CONFIG);
+
+	chroma_fmt = 0;
+	if (c_data->vp_out_fmt.pixfmt == V4L2_PIX_FMT_NV16)
+		chroma_fmt = 1;
+
+	writel_relaxed((c_data->vp_out_fmt.width / 16) << 20 |
+			chroma_fmt << 11 | 0x1 << 4, VCAP_VP_OUT_CONFIG);
+
+	/* Enable Interrupt */
+	if (vp_act->bufT2->vb.v4l2_buf.field == V4L2_FIELD_BOTTOM)
+		top_field = 1;
+	vp_act->vp_state = VP_FRAME2;
+	writel_relaxed(0x01100001, VCAP_VP_INTERRUPT_ENABLE);
+	writel_iowmb(0x00000000 | top_field, VCAP_VP_CTRL);
+	writel_iowmb(0x00010000 | top_field, VCAP_VP_CTRL);
+	atomic_set(&c_data->dev->vp_enabled, 1);
+	enable_irq(dev->vpirq->start);
+
+	do_gettimeofday(&tv);
+	dev->dbg_p.vp_timestamp = (uint32_t) (tv.tv_sec * VCAP_USEC +
+	tv.tv_usec);
+
+	return 0;
+}
+
+int continue_vp(struct vcap_client_data *c_data)
+{
+	struct vcap_dev *dev;
+	struct vp_action *vp_act;
+	struct timeval tv;
+	int rc;
+	bool top_field = 0;
+
+	pr_debug("Start VP Continue\n");
+	dev = c_data->dev;
+
+	if (dev->vp_client == NULL) {
+		pr_err("No active vp client\n");
+		return -ENODEV;
+	}
+	vp_act = &dev->vp_client->vp_action;
+
+	if (vp_act->vp_state == VP_UNKNOWN) {
+		pr_err("%s: VP is in an unknown state\n",
+				__func__);
+		return -EAGAIN;
+	}
+
+	rc = vp_setup_buffers(c_data);
+	if (rc < 0)
+		return rc;
+
+	if (vp_act->bufT2->vb.v4l2_buf.field == V4L2_FIELD_BOTTOM)
+		top_field = 1;
+
+	/* Config VP & Enable Interrupt */
+	writel_relaxed(0x01100001, VCAP_VP_INTERRUPT_ENABLE);
+	writel_iowmb(0x00000000 | top_field, VCAP_VP_CTRL);
+	writel_iowmb(0x00010000 | top_field, VCAP_VP_CTRL);
+
+	atomic_set(&c_data->dev->vp_enabled, 1);
+	enable_irq(dev->vpirq->start);
+
+	do_gettimeofday(&tv);
+	dev->dbg_p.vp_timestamp = (uint32_t) (tv.tv_sec * VCAP_USEC +
+	tv.tv_usec);
+
+	return 0;
+}
diff --git a/drivers/media/platform/msm/vcap/vcap_vp.h b/drivers/media/platform/msm/vcap/vcap_vp.h
new file mode 100644
index 0000000..bd825fc
--- /dev/null
+++ b/drivers/media/platform/msm/vcap/vcap_vp.h
@@ -0,0 +1,115 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef VCAP_VP_H
+#define VCAP_VP_H
+
+#include <linux/interrupt.h>
+
+#include <media/vcap_v4l2.h>
+
+#define VCAP_VP_INT_STATUS (VCAP_BASE + 0x404)
+#define VCAP_VP_INT_CLEAR (VCAP_BASE + 0x40C)
+
+#define VCAP_VP_SW_RESET (VCAP_BASE + 0x410)
+#define VCAP_VP_INTERRUPT_ENABLE (VCAP_BASE + 0x408)
+
+#define VCAP_VP_FILM_PROJECTION_T0 (VCAP_BASE + 0x50C)
+#define VCAP_VP_FILM_PROJECTION_T2 (VCAP_BASE + 0x508)
+#define VCAP_VP_FILM_PAST_MAX_PROJ (VCAP_BASE + 0x510)
+#define VCAP_VP_FILM_PAST_MIN_PROJ (VCAP_BASE + 0x514)
+#define VCAP_VP_FILM_SEQUENCE_HIST (VCAP_BASE + 0x504)
+#define VCAP_VP_FILM_MODE_STATE (VCAP_BASE + 0x500)
+
+#define VCAP_VP_BAL_VMOTION_STATE (VCAP_BASE + 0x690)
+#define VCAP_VP_REDUCT_AVG_MOTION (VCAP_BASE + 0x610)
+#define VCAP_VP_REDUCT_AVG_MOTION2 (VCAP_BASE + 0x614)
+
+#define VCAP_VP_NR_AVG_LUMA (VCAP_BASE + 0x608)
+#define VCAP_VP_NR_AVG_CHROMA (VCAP_BASE + 0x60C)
+#define VCAP_VP_NR_CTRL_LUMA (VCAP_BASE + 0x600)
+#define VCAP_VP_NR_CTRL_CHROMA (VCAP_BASE + 0x604)
+
+#define VCAP_VP_BAL_AVG_BLEND (VCAP_BASE + 0x694)
+#define VCAP_VP_VMOTION_HIST (VCAP_BASE + 0x6F8)
+
+#define VCAP_VP_MOTION_EST_ADDR (VCAP_BASE + 0x4E0)
+#define VCAP_VP_FILM_ANALYSIS_CONFIG (VCAP_BASE + 0x520)
+#define VCAP_VP_FILM_STATE_CONFIG (VCAP_BASE + 0x524)
+
+#define VCAP_VP_FVM_CONFIG (VCAP_BASE + 0x550)
+#define VCAP_VP_FILM_ANALYSIS_CONFIG2 (VCAP_BASE + 0x52C)
+#define VCAP_VP_MIXED_ANALYSIS_CONFIG (VCAP_BASE + 0x530)
+
+#define VCAP_VP_SPATIAL_CONFIG (VCAP_BASE + 0x580)
+#define VCAP_VP_SPATIAL_CONFIG2 (VCAP_BASE + 0x584)
+#define VCAP_VP_SPATIAL_CONFIG3 (VCAP_BASE + 0x588)
+#define VCAP_VP_TEMPORAL_CONFIG (VCAP_BASE + 0x5C0)
+
+#define VCAP_VP_PIXEL_DIFF_CONFIG (VCAP_BASE + 0x6FC)
+#define VCAP_VP_H_FREQ_CONFIG (VCAP_BASE + 0x528)
+#define VCAP_VP_NR_CONFIG (VCAP_BASE + 0x620)
+#define VCAP_VP_NR_LUMA_CONFIG (VCAP_BASE + 0x624)
+#define VCAP_VP_NR_CHROMA_CONFIG (VCAP_BASE + 0x628)
+#define VCAP_VP_BAL_CONFIG (VCAP_BASE + 0x680)
+#define VCAP_VP_BAL_MOTION_CONFIG (VCAP_BASE + 0x684)
+#define VCAP_VP_BAL_LIGHT_COMB (VCAP_BASE + 0x688)
+#define VCAP_VP_BAL_VMOTION_CONFIG (VCAP_BASE + 0x68C)
+
+#define VCAP_VP_NR_CONFIG2 (VCAP_BASE + 0x484)
+#define VCAP_VP_FRAME_SIZE (VCAP_BASE + 0x48C)
+#define VCAP_VP_SPLIT_SCRN_CTRL (VCAP_BASE + 0x750)
+
+#define VCAP_VP_IN_CONFIG (VCAP_BASE + 0x480)
+#define VCAP_VP_OUT_CONFIG (VCAP_BASE + 0x488)
+
+#define VCAP_VP_T2_Y_BASE_ADDR (VCAP_BASE + 0x4C0)
+#define VCAP_VP_T2_C_BASE_ADDR (VCAP_BASE + 0x4C4)
+#define VCAP_VP_OUT_Y_BASE_ADDR (VCAP_BASE + 0x4CC)
+#define VCAP_VP_OUT_C_BASE_ADDR (VCAP_BASE + 0x4D0)
+#define VCAP_VP_OUT_CR_BASE_ADDR (VCAP_BASE + 0x4D4)
+
+#define VCAP_VP_CTRL (VCAP_BASE + 0x4D8)
+
+#define VCAP_VP_T1_Y_BASE_ADDR (VCAP_BASE + 0x4A8)
+#define VCAP_VP_T1_C_BASE_ADDR (VCAP_BASE + 0x4Ac)
+#define VCAP_VP_NR_T2_Y_BASE_ADDR (VCAP_BASE + 0x4B4)
+#define VCAP_VP_NR_T2_C_BASE_ADDR (VCAP_BASE + 0x4B8)
+
+#define VP_PIC_DONE (0x1 << 0)
+#define VP_MODE_CHANGE (0x1 << 8)
+
+#define VP_NR_MAX_WINDOW 120
+#define VP_NR_MAX_RATIO  16
+#define VP_NR_DYNAMIC_THRESHOLD 0x000F0000
+
+#define BITS_MASK(start, num_of_bits) \
+	(((1 << (num_of_bits)) - 1) << (start))
+
+#define BITS_VALUE(x, start, num_of_bits)  \
+	(((x) & BITS_MASK(start, num_of_bits)) >> (start))
+
+irqreturn_t vp_handler(struct vcap_dev *dev);
+int config_vp_format(struct vcap_client_data *c_data);
+void vp_stop_capture(struct vcap_client_data *c_data);
+int init_motion_buf(struct vcap_client_data *c_data);
+void deinit_motion_buf(struct vcap_client_data *c_data);
+int init_nr_buf(struct vcap_client_data *c_data);
+void deinit_nr_buf(struct vcap_client_data *c_data);
+int nr_s_param(struct vcap_client_data *c_data, struct nr_param *param);
+void nr_g_param(struct vcap_client_data *c_data, struct nr_param *param);
+void s_default_nr_val(struct nr_param *param);
+int kickoff_vp(struct vcap_client_data *c_data);
+int continue_vp(struct vcap_client_data *c_data);
+int vp_dummy_event(struct vcap_client_data *c_data);
+
+#endif
diff --git a/drivers/media/platform/msm/vidc/Kconfig b/drivers/media/platform/msm/vidc/Kconfig
new file mode 100644
index 0000000..3fc2b9e
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/Kconfig
@@ -0,0 +1,7 @@
+#
+# VIDEO CORE
+#
+
+menuconfig MSM_VIDC_V4L2
+	bool "Qualcomm MSM V4L2 based video driver"
+		depends on (ARCH_MSM8974 || ARCH_MSM8610) && VIDEO_V4L2
diff --git a/drivers/media/platform/msm/vidc/Makefile b/drivers/media/platform/msm/vidc/Makefile
new file mode 100644
index 0000000..6977165
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/Makefile
@@ -0,0 +1,12 @@
+obj-$(CONFIG_MSM_VIDC_V4L2) := 	msm_v4l2_vidc.o \
+				msm_vidc_common.o \
+				msm_vidc.o \
+				msm_vdec.o \
+				msm_venc.o \
+				msm_smem.o \
+				msm_vidc_debug.o \
+				venus_hfi.o \
+				hfi_response_handler.o \
+				hfi_packetization.o \
+				vidc_hfi.o \
+				q6_hfi.o \
diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c
new file mode 100644
index 0000000..f23c0aa
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/hfi_packetization.c
@@ -0,0 +1,1190 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include "hfi_packetization.h"
+#include "msm_vidc_debug.h"
+#include <linux/errno.h>
+#include <mach/ocmem.h>
+
+int create_pkt_cmd_sys_init(struct hfi_cmd_sys_init_packet *pkt,
+			   u32 arch_type)
+{
+	int rc = 0;
+	if (!pkt)
+		return -EINVAL;
+
+	pkt->packet_type = HFI_CMD_SYS_INIT;
+	pkt->size = sizeof(struct hfi_cmd_sys_init_packet);
+	pkt->arch_type = arch_type;
+	return rc;
+}
+
+int create_pkt_cmd_sys_pc_prep(struct hfi_cmd_sys_pc_prep_packet *pkt)
+{
+	int rc = 0;
+	if (!pkt)
+		return -EINVAL;
+
+	pkt->packet_type = HFI_CMD_SYS_PC_PREP;
+	pkt->size = sizeof(struct hfi_cmd_sys_pc_prep_packet);
+	return rc;
+}
+
+int create_pkt_cmd_sys_idle_indicator(
+	struct hfi_cmd_sys_set_property_packet *pkt,
+	u32 enable)
+{
+	struct hfi_enable *hfi;
+	if (!pkt)
+		return -EINVAL;
+
+	pkt->size = sizeof(struct hfi_cmd_sys_set_property_packet) +
+		sizeof(struct hfi_enable) + sizeof(u32);
+	pkt->packet_type = HFI_CMD_SYS_SET_PROPERTY;
+	pkt->num_properties = 1;
+	pkt->rg_property_data[0] = HFI_PROPERTY_SYS_IDLE_INDICATOR;
+	hfi = (struct hfi_enable *) &pkt->rg_property_data[1];
+	hfi->enable = enable;
+	return 0;
+}
+
+int create_pkt_cmd_sys_debug_config(
+	struct hfi_cmd_sys_set_property_packet *pkt,
+	u32 mode)
+{
+	struct hfi_debug_config *hfi;
+	if (!pkt)
+		return -EINVAL;
+
+	pkt->size = sizeof(struct hfi_cmd_sys_set_property_packet) +
+		sizeof(struct hfi_debug_config) + sizeof(u32);
+	pkt->packet_type = HFI_CMD_SYS_SET_PROPERTY;
+	pkt->num_properties = 1;
+	pkt->rg_property_data[0] = HFI_PROPERTY_SYS_DEBUG_CONFIG;
+	hfi = (struct hfi_debug_config *) &pkt->rg_property_data[1];
+	hfi->debug_config = mode;
+	hfi->debug_mode = HFI_DEBUG_MODE_QUEUE;
+	if (msm_fw_debug_mode <= HFI_DEBUG_MODE_QDSS)
+		hfi->debug_mode = msm_fw_debug_mode;
+	return 0;
+}
+
+int create_pkt_set_cmd_sys_resource(
+		struct hfi_cmd_sys_set_resource_packet *pkt,
+		struct vidc_resource_hdr *resource_hdr,
+		void *resource_value)
+{
+	int rc = 0;
+	if (!pkt || !resource_hdr || !resource_value)
+		return -EINVAL;
+
+	pkt->packet_type = HFI_CMD_SYS_SET_RESOURCE;
+	pkt->size = sizeof(struct hfi_cmd_sys_set_resource_packet);
+	pkt->resource_handle = resource_hdr->resource_handle;
+
+	switch (resource_hdr->resource_id) {
+	case VIDC_RESOURCE_OCMEM:
+	{
+		struct hfi_resource_ocmem *hfioc_mem =
+			(struct hfi_resource_ocmem *)
+			&pkt->rg_resource_data[0];
+		struct ocmem_buf *ocmem =
+			(struct ocmem_buf *) resource_value;
+
+		pkt->resource_type = HFI_RESOURCE_OCMEM;
+		pkt->size += sizeof(struct hfi_resource_ocmem);
+		hfioc_mem->size = (u32) ocmem->len;
+		hfioc_mem->mem = (u8 *) ocmem->addr;
+		break;
+	}
+	default:
+		dprintk(VIDC_ERR, "Invalid resource_id %d",
+					resource_hdr->resource_id);
+		rc = -EINVAL;
+	}
+
+	return rc;
+}
+
+int create_pkt_cmd_sys_release_resource(
+		struct hfi_cmd_sys_release_resource_packet *pkt,
+		struct vidc_resource_hdr *resource_hdr)
+{
+	int rc = 0;
+	if (!pkt)
+		return -EINVAL;
+
+	pkt->size = sizeof(struct hfi_cmd_sys_release_resource_packet);
+	pkt->packet_type = HFI_CMD_SYS_RELEASE_RESOURCE;
+	pkt->resource_type = resource_hdr->resource_id;
+	pkt->resource_handle = resource_hdr->resource_handle;
+
+	return rc;
+}
+
+int create_pkt_cmd_sys_ping(struct hfi_cmd_sys_ping_packet *pkt)
+{
+	int rc = 0;
+	if (!pkt)
+		return -EINVAL;
+
+	pkt->size = sizeof(struct hfi_cmd_sys_ping_packet);
+	pkt->packet_type = HFI_CMD_SYS_PING;
+
+	return rc;
+}
+
+inline int create_pkt_cmd_sys_session_init(
+		struct hfi_cmd_sys_session_init_packet *pkt,
+		u32 session_id, u32 session_domain, u32 session_codec)
+{
+	int rc = 0;
+	if (!pkt)
+		return -EINVAL;
+
+	pkt->size = sizeof(struct hfi_cmd_sys_session_init_packet);
+	pkt->packet_type = HFI_CMD_SYS_SESSION_INIT;
+	pkt->session_id = session_id;
+	pkt->session_domain = session_domain;
+	pkt->session_codec = session_codec;
+
+	return rc;
+}
+
+int create_pkt_cmd_session_cmd(struct vidc_hal_session_cmd_pkt *pkt,
+			int pkt_type, u32 session_id)
+{
+	int rc = 0;
+	if (!pkt)
+		return -EINVAL;
+
+	pkt->size = sizeof(struct vidc_hal_session_cmd_pkt);
+	pkt->packet_type = pkt_type;
+	pkt->session_id = session_id;
+
+	return rc;
+}
+
+static u32 get_hfi_buffer(int hal_buffer)
+{
+	u32 buffer;
+	switch (hal_buffer) {
+	case HAL_BUFFER_INPUT:
+		buffer = HFI_BUFFER_INPUT;
+		break;
+	case HAL_BUFFER_OUTPUT:
+		buffer = HFI_BUFFER_OUTPUT;
+		break;
+	case HAL_BUFFER_OUTPUT2:
+		buffer = HFI_BUFFER_OUTPUT;
+		break;
+	case HAL_BUFFER_EXTRADATA_INPUT:
+		buffer = HFI_BUFFER_EXTRADATA_INPUT;
+		break;
+	case HAL_BUFFER_EXTRADATA_OUTPUT:
+		buffer = HFI_BUFFER_EXTRADATA_OUTPUT;
+		break;
+	case HAL_BUFFER_EXTRADATA_OUTPUT2:
+		buffer = HFI_BUFFER_EXTRADATA_OUTPUT2;
+		break;
+	case HAL_BUFFER_INTERNAL_SCRATCH:
+		buffer = HFI_BUFFER_INTERNAL_SCRATCH;
+		break;
+	case HAL_BUFFER_INTERNAL_SCRATCH_1:
+		buffer = HFI_BUFFER_INTERNAL_SCRATCH_1;
+		break;
+	case HAL_BUFFER_INTERNAL_SCRATCH_2:
+		buffer = HFI_BUFFER_INTERNAL_SCRATCH_2;
+		break;
+	case HAL_BUFFER_INTERNAL_PERSIST:
+		buffer = HFI_BUFFER_INTERNAL_PERSIST;
+		break;
+	case HAL_BUFFER_INTERNAL_PERSIST_1:
+		buffer = HFI_BUFFER_INTERNAL_PERSIST_1;
+		break;
+	default:
+		dprintk(VIDC_ERR, "Invalid buffer :0x%x\n",
+				hal_buffer);
+		buffer = 0;
+		break;
+	}
+	return buffer;
+}
+
+static int get_hfi_extradata_index(enum hal_extradata_id index)
+{
+	int ret = 0;
+	switch (index) {
+	case HAL_EXTRADATA_MB_QUANTIZATION:
+		ret = HFI_PROPERTY_PARAM_VDEC_MB_QUANTIZATION;
+		break;
+	case HAL_EXTRADATA_INTERLACE_VIDEO:
+		ret = HFI_PROPERTY_PARAM_VDEC_INTERLACE_VIDEO_EXTRADATA;
+		break;
+	case HAL_EXTRADATA_VC1_FRAMEDISP:
+		ret = HFI_PROPERTY_PARAM_VDEC_VC1_FRAMEDISP_EXTRADATA;
+		break;
+	case HAL_EXTRADATA_VC1_SEQDISP:
+		ret = HFI_PROPERTY_PARAM_VDEC_VC1_SEQDISP_EXTRADATA;
+		break;
+	case HAL_EXTRADATA_TIMESTAMP:
+		ret = HFI_PROPERTY_PARAM_VDEC_TIMESTAMP_EXTRADATA;
+		break;
+	case HAL_EXTRADATA_S3D_FRAME_PACKING:
+		ret = HFI_PROPERTY_PARAM_S3D_FRAME_PACKING_EXTRADATA;
+		break;
+	case HAL_EXTRADATA_FRAME_RATE:
+		ret = HFI_PROPERTY_PARAM_VDEC_FRAME_RATE_EXTRADATA;
+		break;
+	case HAL_EXTRADATA_PANSCAN_WINDOW:
+		ret = HFI_PROPERTY_PARAM_VDEC_PANSCAN_WNDW_EXTRADATA;
+		break;
+	case HAL_EXTRADATA_RECOVERY_POINT_SEI:
+		ret = HFI_PROPERTY_PARAM_VDEC_RECOVERY_POINT_SEI_EXTRADATA;
+		break;
+	case HAL_EXTRADATA_CLOSED_CAPTION_UD:
+		ret = HFI_PROPERTY_PARAM_VDEC_CLOSED_CAPTION_EXTRADATA;
+		break;
+	case HAL_EXTRADATA_AFD_UD:
+		ret = HFI_PROPERTY_PARAM_VDEC_AFD_EXTRADATA;
+		break;
+	case HAL_EXTRADATA_MULTISLICE_INFO:
+		ret = HFI_PROPERTY_PARAM_VENC_MULTI_SLICE_INFO;
+		break;
+	case HAL_EXTRADATA_NUM_CONCEALED_MB:
+		ret = HFI_PROPERTY_PARAM_VDEC_NUM_CONCEALED_MB;
+		break;
+	case HAL_EXTRADATA_ASPECT_RATIO:
+		ret = HFI_PROPERTY_PARAM_INDEX_EXTRADATA;
+		break;
+	default:
+		dprintk(VIDC_WARN, "Extradata index not found: %d\n", index);
+		break;
+	}
+	return ret;
+}
+
+int create_pkt_cmd_session_set_buffers(
+		struct hfi_cmd_session_set_buffers_packet *pkt,
+		u32 session_id,
+		struct vidc_buffer_addr_info *buffer_info)
+{
+	int rc = 0;
+	int i = 0;
+	if (!pkt || !session_id)
+		return -EINVAL;
+
+	pkt->packet_type = HFI_CMD_SESSION_SET_BUFFERS;
+	pkt->session_id = session_id;
+	pkt->buffer_size = buffer_info->buffer_size;
+	pkt->min_buffer_size = buffer_info->buffer_size;
+	pkt->num_buffers = buffer_info->num_buffers;
+
+	if ((buffer_info->buffer_type == HAL_BUFFER_OUTPUT) ||
+		(buffer_info->buffer_type == HAL_BUFFER_OUTPUT2)) {
+		struct hfi_buffer_info *buff;
+		pkt->extra_data_size = buffer_info->extradata_size;
+		pkt->size = sizeof(struct hfi_cmd_session_set_buffers_packet) -
+				sizeof(u32) + (buffer_info->num_buffers *
+				sizeof(struct hfi_buffer_info));
+		buff = (struct hfi_buffer_info *) pkt->rg_buffer_info;
+		for (i = 0; i < pkt->num_buffers; i++) {
+			buff->buffer_addr = buffer_info->align_device_addr;
+			buff->extra_data_addr = buffer_info->extradata_addr;
+		}
+	} else {
+		pkt->extra_data_size = 0;
+		pkt->size = sizeof(struct hfi_cmd_session_set_buffers_packet) +
+			((buffer_info->num_buffers - 1) * sizeof(u32));
+		for (i = 0; i < pkt->num_buffers; i++)
+			pkt->rg_buffer_info[i] = buffer_info->align_device_addr;
+	}
+
+	pkt->buffer_type = get_hfi_buffer(buffer_info->buffer_type);
+	if (!pkt->buffer_type)
+		return -EINVAL;
+
+	return rc;
+}
+
+int create_pkt_cmd_session_release_buffers(
+		struct hfi_cmd_session_release_buffer_packet *pkt,
+		u32 session_id, struct vidc_buffer_addr_info *buffer_info)
+{
+	int rc = 0;
+	int i = 0;
+	if (!pkt || !session_id)
+		return -EINVAL;
+
+	pkt->packet_type = HFI_CMD_SESSION_RELEASE_BUFFERS;
+	pkt->session_id = session_id;
+	pkt->buffer_size = buffer_info->buffer_size;
+	pkt->num_buffers = buffer_info->num_buffers;
+
+	if ((buffer_info->buffer_type == HAL_BUFFER_OUTPUT) ||
+		(buffer_info->buffer_type == HAL_BUFFER_OUTPUT2)) {
+		struct hfi_buffer_info *buff;
+		buff = (struct hfi_buffer_info *) pkt->rg_buffer_info;
+		for (i = 0; i < pkt->num_buffers; i++) {
+			buff->buffer_addr = buffer_info->align_device_addr;
+			buff->extra_data_addr = buffer_info->extradata_addr;
+		}
+		pkt->size = sizeof(struct hfi_cmd_session_set_buffers_packet) -
+				sizeof(u32) + (buffer_info->num_buffers *
+				sizeof(struct hfi_buffer_info));
+	} else {
+		for (i = 0; i < pkt->num_buffers; i++)
+			pkt->rg_buffer_info[i] = buffer_info->align_device_addr;
+		pkt->extra_data_size = 0;
+		pkt->size = sizeof(struct hfi_cmd_session_set_buffers_packet) +
+			((buffer_info->num_buffers - 1) * sizeof(u32));
+	}
+	pkt->response_req = buffer_info->response_required;
+	pkt->buffer_type = get_hfi_buffer(buffer_info->buffer_type);
+	if (!pkt->buffer_type)
+		return -EINVAL;
+	return rc;
+}
+
+int create_pkt_cmd_session_etb_decoder(
+	struct hfi_cmd_session_empty_buffer_compressed_packet *pkt,
+	u32 session_id, struct vidc_frame_data *input_frame)
+{
+	int rc = 0;
+	if (!pkt || !session_id)
+		return -EINVAL;
+
+	pkt->size =
+		sizeof(struct hfi_cmd_session_empty_buffer_compressed_packet);
+	pkt->packet_type = HFI_CMD_SESSION_EMPTY_BUFFER;
+	pkt->session_id = session_id;
+	pkt->time_stamp_hi = (int) (((u64)input_frame->timestamp) >> 32);
+	pkt->time_stamp_lo = (int) input_frame->timestamp;
+	pkt->flags = input_frame->flags;
+	pkt->mark_target = input_frame->mark_target;
+	pkt->mark_data = input_frame->mark_data;
+	pkt->offset = input_frame->offset;
+	pkt->alloc_len = input_frame->alloc_len;
+	pkt->filled_len = input_frame->filled_len;
+	pkt->input_tag = input_frame->clnt_data;
+	pkt->packet_buffer = (u8 *) input_frame->device_addr;
+
+	if (!pkt->packet_buffer)
+		return -EINVAL;
+	return rc;
+}
+
+int create_pkt_cmd_session_etb_encoder(
+	struct hfi_cmd_session_empty_buffer_uncompressed_plane0_packet *pkt,
+	u32 session_id, struct vidc_frame_data *input_frame)
+{
+	int rc = 0;
+	if (!pkt || !session_id)
+		return -EINVAL;
+
+	pkt->size = sizeof(struct
+		hfi_cmd_session_empty_buffer_uncompressed_plane0_packet);
+	pkt->packet_type = HFI_CMD_SESSION_EMPTY_BUFFER;
+	pkt->session_id = session_id;
+	pkt->view_id = 0;
+	pkt->time_stamp_hi = (u32)(((u64)input_frame->timestamp) >> 32);
+	pkt->time_stamp_lo = (u32)input_frame->timestamp;
+	pkt->flags = input_frame->flags;
+	pkt->mark_target = input_frame->mark_target;
+	pkt->mark_data = input_frame->mark_data;
+	pkt->offset = input_frame->offset;
+	pkt->alloc_len = input_frame->alloc_len;
+	pkt->filled_len = input_frame->filled_len;
+	pkt->input_tag = input_frame->clnt_data;
+	pkt->packet_buffer = (u8 *) input_frame->device_addr;
+
+	if (!pkt->packet_buffer)
+		return -EINVAL;
+	return rc;
+}
+
+int create_pkt_cmd_session_ftb(struct hfi_cmd_session_fill_buffer_packet *pkt,
+		u32 session_id, struct vidc_frame_data *output_frame)
+{
+	int rc = 0;
+	if (!pkt || !session_id || !output_frame)
+		return -EINVAL;
+
+	pkt->size = sizeof(struct hfi_cmd_session_fill_buffer_packet);
+	pkt->packet_type = HFI_CMD_SESSION_FILL_BUFFER;
+	pkt->session_id = session_id;
+
+	if (output_frame->buffer_type == HAL_BUFFER_OUTPUT)
+		pkt->stream_id = 0;
+	else if (output_frame->buffer_type == HAL_BUFFER_OUTPUT2)
+		pkt->stream_id = 1;
+
+	if (!output_frame->device_addr)
+		return -EINVAL;
+
+	pkt->packet_buffer = (u8 *) output_frame->device_addr;
+	pkt->extra_data_buffer = (u8 *) output_frame->extradata_addr;
+
+	pkt->alloc_len = output_frame->alloc_len;
+	pkt->filled_len = output_frame->filled_len;
+	pkt->offset = output_frame->offset;
+	dprintk(VIDC_DBG, "### Q OUTPUT BUFFER ###: %d, %d, %d\n",
+			pkt->alloc_len, pkt->filled_len, pkt->offset);
+
+	return rc;
+}
+
+int create_pkt_cmd_session_parse_seq_header(
+		struct hfi_cmd_session_parse_sequence_header_packet *pkt,
+		u32 session_id, struct vidc_seq_hdr *seq_hdr)
+{
+	int rc = 0;
+	if (!pkt || !session_id || seq_hdr)
+		return -EINVAL;
+
+	pkt->size = sizeof(struct hfi_cmd_session_parse_sequence_header_packet);
+	pkt->packet_type = HFI_CMD_SESSION_PARSE_SEQUENCE_HEADER;
+	pkt->session_id = session_id;
+	pkt->header_len = seq_hdr->seq_hdr_len;
+	if (!seq_hdr->seq_hdr)
+		return -EINVAL;
+	pkt->packet_buffer = seq_hdr->seq_hdr;
+
+	return rc;
+}
+
+int create_pkt_cmd_session_get_seq_hdr(
+		struct hfi_cmd_session_get_sequence_header_packet *pkt,
+		u32 session_id, struct vidc_seq_hdr *seq_hdr)
+{
+	int rc = 0;
+
+	if (!pkt || !session_id || !seq_hdr)
+		return -EINVAL;
+
+	pkt->size = sizeof(struct hfi_cmd_session_get_sequence_header_packet);
+	pkt->packet_type = HFI_CMD_SESSION_GET_SEQUENCE_HEADER;
+	pkt->session_id = session_id;
+	pkt->buffer_len = seq_hdr->seq_hdr_len;
+	if (!seq_hdr->seq_hdr)
+		return -EINVAL;
+	pkt->packet_buffer = seq_hdr->seq_hdr;
+
+	return rc;
+}
+
+int create_pkt_cmd_session_get_buf_req(
+		struct hfi_cmd_session_get_property_packet *pkt,
+		u32 session_id)
+{
+	int rc = 0;
+
+	if (!pkt || !session_id)
+		return -EINVAL;
+
+	pkt->size = sizeof(struct hfi_cmd_session_get_property_packet);
+	pkt->packet_type = HFI_CMD_SESSION_GET_PROPERTY;
+	pkt->session_id = session_id;
+	pkt->num_properties = 1;
+	pkt->rg_property_data[0] = HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS;
+
+	return rc;
+}
+
+int create_pkt_cmd_session_flush(struct hfi_cmd_session_flush_packet *pkt,
+			u32 session_id, enum hal_flush flush_mode)
+{
+	int rc = 0;
+	if (!pkt || !session_id)
+		return -EINVAL;
+
+	pkt->size = sizeof(struct hfi_cmd_session_flush_packet);
+	pkt->packet_type = HFI_CMD_SESSION_FLUSH;
+	pkt->session_id = session_id;
+	switch (flush_mode) {
+	case HAL_FLUSH_INPUT:
+		pkt->flush_type = HFI_FLUSH_INPUT;
+		break;
+	case HAL_FLUSH_OUTPUT:
+		pkt->flush_type = HFI_FLUSH_OUTPUT;
+		break;
+	case HAL_FLUSH_OUTPUT2:
+		pkt->flush_type = HFI_FLUSH_OUTPUT2;
+		break;
+	case HAL_FLUSH_ALL:
+		pkt->flush_type = HFI_FLUSH_ALL;
+		break;
+	default:
+		dprintk(VIDC_ERR, "Invalid flush mode: 0x%x\n", flush_mode);
+		return -EINVAL;
+	}
+	return rc;
+}
+
+int create_pkt_cmd_session_set_property(
+		struct hfi_cmd_session_set_property_packet *pkt,
+		u32 session_id, enum hal_property ptype, void *pdata)
+{
+	int rc = 0;
+	if (!pkt || !session_id)
+		return -EINVAL;
+
+	pkt->size = sizeof(struct hfi_cmd_session_set_property_packet);
+	pkt->packet_type = HFI_CMD_SESSION_SET_PROPERTY;
+	pkt->session_id = session_id;
+	pkt->num_properties = 1;
+
+	switch (ptype) {
+	case HAL_CONFIG_FRAME_RATE:
+	{
+		u32 buffer_type;
+		struct hfi_frame_rate *hfi;
+		struct hal_frame_rate *prop = (struct hal_frame_rate *) pdata;
+
+		pkt->rg_property_data[0] = HFI_PROPERTY_CONFIG_FRAME_RATE;
+		hfi = (struct hfi_frame_rate *) &pkt->rg_property_data[1];
+		buffer_type = get_hfi_buffer(prop->buffer_type);
+		if (buffer_type)
+			hfi->buffer_type = buffer_type;
+		else
+			return -EINVAL;
+
+		hfi->frame_rate = prop->frame_rate;
+		pkt->size += sizeof(u32) + sizeof(struct hfi_frame_rate);
+		break;
+	}
+	case HAL_PARAM_UNCOMPRESSED_FORMAT_SELECT:
+	{
+		u32 buffer_type;
+		struct hfi_uncompressed_format_select *hfi;
+		struct hal_uncompressed_format_select *prop =
+			(struct hal_uncompressed_format_select *) pdata;
+
+		pkt->rg_property_data[0] =
+			HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT;
+
+		hfi = (struct hfi_uncompressed_format_select *)
+					&pkt->rg_property_data[1];
+		buffer_type = get_hfi_buffer(prop->buffer_type);
+		if (buffer_type)
+			hfi->buffer_type = buffer_type;
+		else
+			return -EINVAL;
+		hfi->format = prop->format;
+		pkt->size += sizeof(u32) +
+			sizeof(struct hfi_uncompressed_format_select);
+		break;
+		}
+	case HAL_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO:
+		break;
+	case HAL_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO:
+		break;
+	case HAL_PARAM_EXTRA_DATA_HEADER_CONFIG:
+		break;
+	case HAL_PARAM_FRAME_SIZE:
+	{
+		struct hfi_frame_size *hfi;
+		struct hal_frame_size *prop = (struct hal_frame_size *) pdata;
+		u32 buffer_type;
+
+		pkt->rg_property_data[0] = HFI_PROPERTY_PARAM_FRAME_SIZE;
+		hfi = (struct hfi_frame_size *) &pkt->rg_property_data[1];
+		buffer_type = get_hfi_buffer(prop->buffer_type);
+		if (buffer_type)
+			hfi->buffer_type = buffer_type;
+		else
+			return -EINVAL;
+
+		hfi->height = prop->height;
+		hfi->width = prop->width;
+		pkt->size += sizeof(u32) + sizeof(struct hfi_frame_size);
+		break;
+	}
+	case HAL_CONFIG_REALTIME:
+	{
+		struct hfi_enable *hfi;
+		pkt->rg_property_data[0] = HFI_PROPERTY_CONFIG_REALTIME;
+		hfi = (struct hfi_enable *) &pkt->rg_property_data[1];
+		hfi->enable = ((struct hfi_enable *) pdata)->enable;
+		pkt->size += sizeof(u32) * 2;
+		break;
+	}
+	case HAL_PARAM_BUFFER_COUNT_ACTUAL:
+	{
+		struct hfi_buffer_count_actual *hfi;
+		struct hal_buffer_count_actual *prop =
+			(struct hal_buffer_count_actual *) pdata;
+		u32 buffer_type;
+		pkt->rg_property_data[0] =
+			HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL;
+		hfi = (struct hfi_buffer_count_actual *)
+			&pkt->rg_property_data[1];
+		hfi->buffer_count_actual = prop->buffer_count_actual;
+
+		buffer_type = get_hfi_buffer(prop->buffer_type);
+		if (buffer_type)
+			hfi->buffer_type = buffer_type;
+		else
+			return -EINVAL;
+
+		pkt->size += sizeof(u32) + sizeof(struct
+				hfi_buffer_count_actual);
+
+		break;
+	}
+	case HAL_PARAM_NAL_STREAM_FORMAT_SELECT:
+	{
+		struct hal_nal_stream_format_supported *prop =
+			(struct hal_nal_stream_format_supported *)pdata;
+		pkt->rg_property_data[0] =
+			HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SELECT;
+		dprintk(VIDC_DBG, "data is :%d",
+				prop->nal_stream_format_supported);
+
+		switch (prop->nal_stream_format_supported) {
+		case HAL_NAL_FORMAT_STARTCODES:
+			pkt->rg_property_data[1] =
+				HFI_NAL_FORMAT_STARTCODES;
+			break;
+		case HAL_NAL_FORMAT_ONE_NAL_PER_BUFFER:
+			pkt->rg_property_data[1] =
+				HFI_NAL_FORMAT_ONE_NAL_PER_BUFFER;
+			break;
+		case HAL_NAL_FORMAT_ONE_BYTE_LENGTH:
+			pkt->rg_property_data[1] =
+				HFI_NAL_FORMAT_ONE_BYTE_LENGTH;
+			break;
+		case HAL_NAL_FORMAT_TWO_BYTE_LENGTH:
+			pkt->rg_property_data[1] =
+				HFI_NAL_FORMAT_TWO_BYTE_LENGTH;
+			break;
+		case HAL_NAL_FORMAT_FOUR_BYTE_LENGTH:
+			pkt->rg_property_data[1] =
+				HFI_NAL_FORMAT_FOUR_BYTE_LENGTH;
+			break;
+		default:
+			dprintk(VIDC_ERR, "Invalid nal format: 0x%x",
+				  prop->nal_stream_format_supported);
+			break;
+		}
+		pkt->size += sizeof(u32) * 2;
+		break;
+	}
+	case HAL_PARAM_VDEC_OUTPUT_ORDER:
+	{
+		int *data = (int *) pdata;
+		pkt->rg_property_data[0] =
+				HFI_PROPERTY_PARAM_VDEC_OUTPUT_ORDER;
+		switch (*data) {
+		case HAL_OUTPUT_ORDER_DECODE:
+			pkt->rg_property_data[1] = HFI_OUTPUT_ORDER_DECODE;
+			break;
+		case HAL_OUTPUT_ORDER_DISPLAY:
+			pkt->rg_property_data[1] = HFI_OUTPUT_ORDER_DISPLAY;
+			break;
+		default:
+			dprintk(VIDC_ERR, "invalid output order: 0x%x",
+						  *data);
+			break;
+		}
+		pkt->size += sizeof(u32) * 2;
+		break;
+	}
+	case HAL_PARAM_VDEC_PICTURE_TYPE_DECODE:
+	{
+		struct hfi_enable_picture *hfi;
+		pkt->rg_property_data[0] =
+			HFI_PROPERTY_PARAM_VDEC_PICTURE_TYPE_DECODE;
+		hfi = (struct hfi_enable_picture *) &pkt->rg_property_data[1];
+		hfi->picture_type = (u32) pdata;
+		pkt->size += sizeof(u32) * 2;
+		break;
+	}
+	case HAL_PARAM_VDEC_OUTPUT2_KEEP_ASPECT_RATIO:
+	{
+		struct hfi_enable *hfi;
+		pkt->rg_property_data[0] =
+			HFI_PROPERTY_PARAM_VDEC_OUTPUT2_KEEP_ASPECT_RATIO;
+		hfi = (struct hfi_enable *) &pkt->rg_property_data[1];
+		hfi->enable = ((struct hfi_enable *) pdata)->enable;
+		pkt->size += sizeof(u32) * 2;
+		break;
+	}
+	case HAL_CONFIG_VDEC_POST_LOOP_DEBLOCKER:
+	{
+		struct hfi_enable *hfi;
+		pkt->rg_property_data[0] =
+			HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER;
+		hfi = (struct hfi_enable *) &pkt->rg_property_data[1];
+		hfi->enable = ((struct hfi_enable *) pdata)->enable;
+		pkt->size += sizeof(u32) * 2;
+		break;
+	}
+	case HAL_PARAM_VDEC_MULTI_STREAM:
+	{
+		struct hfi_multi_stream *hfi;
+		struct hal_multi_stream *prop =
+			(struct hal_multi_stream *) pdata;
+		u32 buffer_type;
+		pkt->rg_property_data[0] =
+			HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM;
+		hfi = (struct hfi_multi_stream *) &pkt->rg_property_data[1];
+
+		buffer_type = get_hfi_buffer(prop->buffer_type);
+		if (buffer_type)
+			hfi->buffer_type = buffer_type;
+		else
+			return -EINVAL;
+		hfi->enable = prop->enable;
+		hfi->width = prop->width;
+		hfi->height = prop->height;
+		pkt->size += sizeof(u32) + sizeof(struct hfi_multi_stream);
+		break;
+	}
+	case HAL_PARAM_VDEC_DISPLAY_PICTURE_BUFFER_COUNT:
+	{
+		struct hfi_display_picture_buffer_count *hfi;
+		struct hal_display_picture_buffer_count *prop =
+			(struct hal_display_picture_buffer_count *) pdata;
+		pkt->rg_property_data[0] =
+			HFI_PROPERTY_PARAM_VDEC_DISPLAY_PICTURE_BUFFER_COUNT;
+		hfi = (struct hfi_display_picture_buffer_count *)
+			&pkt->rg_property_data[1];
+		hfi->count = prop->count;
+		hfi->enable = prop->enable;
+		pkt->size += sizeof(u32) +
+			sizeof(struct hfi_display_picture_buffer_count);
+		break;
+	}
+	case HAL_PARAM_DIVX_FORMAT:
+	{
+		int *data = pdata;
+		pkt->rg_property_data[0] = HFI_PROPERTY_PARAM_DIVX_FORMAT;
+		switch (*data) {
+		case HAL_DIVX_FORMAT_4:
+			pkt->rg_property_data[1] = HFI_DIVX_FORMAT_4;
+			break;
+		case HAL_DIVX_FORMAT_5:
+			pkt->rg_property_data[1] = HFI_DIVX_FORMAT_5;
+			break;
+		case HAL_DIVX_FORMAT_6:
+			pkt->rg_property_data[1] = HFI_DIVX_FORMAT_6;
+			break;
+		default:
+			dprintk(VIDC_ERR, "Invalid divx format: 0x%x", *data);
+			break;
+		}
+		pkt->size += sizeof(u32) * 2;
+		break;
+	}
+	case HAL_CONFIG_VDEC_MB_ERROR_MAP_REPORTING:
+	{
+		struct hfi_enable *hfi;
+		pkt->rg_property_data[0] =
+			HFI_PROPERTY_CONFIG_VDEC_MB_ERROR_MAP_REPORTING;
+		hfi = (struct hfi_enable *) &pkt->rg_property_data[1];
+		hfi->enable = ((struct hfi_enable *) pdata)->enable;
+		pkt->size += sizeof(u32) * 2;
+		break;
+	}
+	case HAL_PARAM_VDEC_CONTINUE_DATA_TRANSFER:
+	{
+		struct hfi_enable *hfi;
+		pkt->rg_property_data[0] =
+			HFI_PROPERTY_PARAM_VDEC_CONTINUE_DATA_TRANSFER;
+		hfi = (struct hfi_enable *) &pkt->rg_property_data[1];
+		hfi->enable = ((struct hfi_enable *) pdata)->enable;
+		pkt->size += sizeof(u32) * 2;
+		break;
+	}
+	case HAL_PARAM_VDEC_SYNC_FRAME_DECODE:
+	{
+		struct hfi_enable *hfi;
+		pkt->rg_property_data[0] =
+			HFI_PROPERTY_PARAM_VDEC_THUMBNAIL_MODE;
+		hfi = (struct hfi_enable *) &pkt->rg_property_data[1];
+		hfi->enable = ((struct hfi_enable *) pdata)->enable;
+		pkt->size += sizeof(u32) * 2;
+		break;
+	}
+	case HAL_PARAM_VENC_SYNC_FRAME_SEQUENCE_HEADER:
+	{
+		struct hfi_enable *hfi;
+		pkt->rg_property_data[0] =
+			HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER;
+		hfi = (struct hfi_enable *) &pkt->rg_property_data[1];
+		hfi->enable = ((struct hfi_enable *) pdata)->enable;
+		pkt->size += sizeof(u32) * 2;
+		break;
+	}
+	case HAL_CONFIG_VENC_REQUEST_IFRAME:
+		pkt->rg_property_data[0] =
+			HFI_PROPERTY_CONFIG_VENC_REQUEST_SYNC_FRAME;
+		pkt->size += sizeof(u32);
+		break;
+	case HAL_PARAM_VENC_MPEG4_SHORT_HEADER:
+		break;
+	case HAL_PARAM_VENC_MPEG4_AC_PREDICTION:
+		break;
+	case HAL_CONFIG_VENC_TARGET_BITRATE:
+	{
+		struct hfi_bitrate *hfi;
+		pkt->rg_property_data[0] =
+			HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE;
+		hfi = (struct hfi_bitrate *) &pkt->rg_property_data[1];
+		hfi->bit_rate = ((struct hal_bitrate *)pdata)->bit_rate;
+		hfi->layer_id = ((struct hal_bitrate *)pdata)->layer_id;
+		pkt->size += sizeof(u32) + sizeof(struct hfi_bitrate);
+		break;
+	}
+	case HAL_PARAM_PROFILE_LEVEL_CURRENT:
+	{
+		struct hfi_profile_level *hfi;
+		struct hal_profile_level *prop =
+			(struct hal_profile_level *) pdata;
+		pkt->rg_property_data[0] =
+			HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT;
+		hfi = (struct hfi_profile_level *)
+			&pkt->rg_property_data[1];
+		hfi->level = (u32) prop->level;
+		hfi->profile = prop->profile;
+		if (!hfi->profile)
+			hfi->profile = HFI_H264_PROFILE_HIGH;
+		if (!hfi->level)
+			hfi->level = 1;
+		pkt->size += sizeof(u32) + sizeof(struct hfi_profile_level);
+		break;
+	}
+	case HAL_PARAM_VENC_H264_ENTROPY_CONTROL:
+	{
+		struct hfi_h264_entropy_control *hfi;
+		struct hal_h264_entropy_control *prop =
+			(struct hal_h264_entropy_control *) pdata;
+		pkt->rg_property_data[0] =
+			HFI_PROPERTY_PARAM_VENC_H264_ENTROPY_CONTROL;
+		hfi = (struct hfi_h264_entropy_control *)
+			&pkt->rg_property_data[1];
+		switch (prop->entropy_mode) {
+		case HAL_H264_ENTROPY_CAVLC:
+			hfi->cabac_model = HFI_H264_ENTROPY_CAVLC;
+			break;
+		case HAL_H264_ENTROPY_CABAC:
+			hfi->cabac_model = HFI_H264_ENTROPY_CABAC;
+			switch (prop->cabac_model) {
+			case HAL_H264_CABAC_MODEL_0:
+				hfi->cabac_model = HFI_H264_CABAC_MODEL_0;
+				break;
+			case HAL_H264_CABAC_MODEL_1:
+				hfi->cabac_model = HFI_H264_CABAC_MODEL_1;
+				break;
+			case HAL_H264_CABAC_MODEL_2:
+				hfi->cabac_model = HFI_H264_CABAC_MODEL_2;
+				break;
+			default:
+				dprintk(VIDC_ERR,
+					"Invalid cabac model 0x%x",
+					prop->entropy_mode);
+				break;
+			}
+		break;
+		default:
+			dprintk(VIDC_ERR,
+				"Invalid entropy selected: 0x%x",
+				prop->cabac_model);
+			break;
+		}
+		pkt->size += sizeof(u32) + sizeof(
+			struct hfi_h264_entropy_control);
+		break;
+	}
+	case HAL_PARAM_VENC_RATE_CONTROL:
+	{
+		u32 *rc;
+		pkt->rg_property_data[0] =
+			HFI_PROPERTY_PARAM_VENC_RATE_CONTROL;
+		rc = (u32 *)pdata;
+		switch ((enum hal_rate_control) *rc) {
+		case HAL_RATE_CONTROL_OFF:
+			pkt->rg_property_data[1] = HFI_RATE_CONTROL_OFF;
+			break;
+		case HAL_RATE_CONTROL_CBR_CFR:
+			pkt->rg_property_data[1] = HFI_RATE_CONTROL_CBR_CFR;
+			break;
+		case HAL_RATE_CONTROL_CBR_VFR:
+			pkt->rg_property_data[1] = HFI_RATE_CONTROL_CBR_VFR;
+			break;
+		case HAL_RATE_CONTROL_VBR_CFR:
+			pkt->rg_property_data[1] = HFI_RATE_CONTROL_VBR_CFR;
+			break;
+		case HAL_RATE_CONTROL_VBR_VFR:
+			pkt->rg_property_data[1] = HFI_RATE_CONTROL_VBR_VFR;
+			break;
+		default:
+			dprintk(VIDC_ERR, "Invalid Rate control setting: 0x%x",
+						  (int) pdata);
+			break;
+		}
+		pkt->size += sizeof(u32) * 2;
+		break;
+	}
+	case HAL_PARAM_VENC_MPEG4_TIME_RESOLUTION:
+	{
+		struct hfi_mpeg4_time_resolution *hfi;
+		pkt->rg_property_data[0] =
+			HFI_PROPERTY_PARAM_VENC_MPEG4_TIME_RESOLUTION;
+		hfi = (struct hfi_mpeg4_time_resolution *)
+			&pkt->rg_property_data[1];
+		hfi->time_increment_resolution =
+			((struct hal_mpeg4_time_resolution *)pdata)->
+					time_increment_resolution;
+		pkt->size += sizeof(u32) * 2;
+		break;
+	}
+	case HAL_PARAM_VENC_MPEG4_HEADER_EXTENSION:
+	{
+		struct hfi_mpeg4_header_extension *hfi;
+		pkt->rg_property_data[0] =
+			HFI_PROPERTY_PARAM_VENC_MPEG4_HEADER_EXTENSION;
+		hfi = (struct hfi_mpeg4_header_extension *)
+			&pkt->rg_property_data[1];
+		hfi->header_extension = (u32) pdata;
+		pkt->size += sizeof(u32) * 2;
+		break;
+	}
+	case HAL_PARAM_VENC_H264_DEBLOCK_CONTROL:
+	{
+		struct hfi_h264_db_control *hfi;
+		struct hal_h264_db_control *prop =
+			(struct hal_h264_db_control *) pdata;
+		pkt->rg_property_data[0] =
+			HFI_PROPERTY_PARAM_VENC_H264_DEBLOCK_CONTROL;
+		hfi = (struct hfi_h264_db_control *) &pkt->rg_property_data[1];
+		switch (prop->mode) {
+		case HAL_H264_DB_MODE_DISABLE:
+			hfi->mode = HFI_H264_DB_MODE_DISABLE;
+			break;
+		case HAL_H264_DB_MODE_SKIP_SLICE_BOUNDARY:
+			hfi->mode = HFI_H264_DB_MODE_SKIP_SLICE_BOUNDARY;
+			break;
+		case HAL_H264_DB_MODE_ALL_BOUNDARY:
+			hfi->mode = HFI_H264_DB_MODE_ALL_BOUNDARY;
+			break;
+		default:
+			dprintk(VIDC_ERR, "Invalid deblocking mode: 0x%x",
+						  prop->mode);
+			break;
+		}
+		hfi->slice_alpha_offset = prop->slice_alpha_offset;
+		hfi->slice_beta_offset = prop->slice_beta_offset;
+		pkt->size += sizeof(u32) +
+			sizeof(struct hfi_h264_db_control);
+		break;
+	}
+	case HAL_PARAM_VENC_SESSION_QP:
+	{
+		struct hfi_quantization *hfi;
+		struct hal_quantization *hal_quant =
+			(struct hal_quantization *) pdata;
+		pkt->rg_property_data[0] =
+			HFI_PROPERTY_PARAM_VENC_SESSION_QP;
+		hfi = (struct hfi_quantization *) &pkt->rg_property_data[1];
+		hfi->qp_i = hal_quant->qpi;
+		hfi->qp_p = hal_quant->qpp;
+		hfi->qp_b = hal_quant->qpb;
+		hfi->layer_id = hal_quant->layer_id;
+		pkt->size += sizeof(u32) + sizeof(struct hfi_quantization);
+		break;
+	}
+	case HAL_CONFIG_VENC_INTRA_PERIOD:
+	{
+		struct hfi_intra_period *hfi;
+		pkt->rg_property_data[0] =
+			HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD;
+		hfi = (struct hfi_intra_period *) &pkt->rg_property_data[1];
+		memcpy(hfi, (struct hfi_intra_period *) pdata,
+				sizeof(struct hfi_intra_period));
+		pkt->size += sizeof(u32) + sizeof(struct hfi_intra_period);
+		break;
+	}
+	case HAL_CONFIG_VENC_IDR_PERIOD:
+	{
+		struct hfi_idr_period *hfi;
+		pkt->rg_property_data[0] = HFI_PROPERTY_CONFIG_VENC_IDR_PERIOD;
+		hfi = (struct hfi_idr_period *) &pkt->rg_property_data[1];
+		hfi->idr_period = ((struct hfi_idr_period *) pdata)->idr_period;
+		pkt->size += sizeof(u32) * 2;
+		break;
+	}
+	case HAL_CONFIG_VPE_OPERATIONS:
+		break;
+	case HAL_PARAM_VENC_INTRA_REFRESH:
+	{
+		struct hfi_intra_refresh *hfi;
+		struct hal_intra_refresh *prop =
+			(struct hal_intra_refresh *) pdata;
+		pkt->rg_property_data[0] =
+			HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH;
+		hfi = (struct hfi_intra_refresh *) &pkt->rg_property_data[1];
+		switch (prop->mode) {
+		case HAL_INTRA_REFRESH_NONE:
+			hfi->mode = HFI_INTRA_REFRESH_NONE;
+			break;
+		case HAL_INTRA_REFRESH_ADAPTIVE:
+			hfi->mode = HFI_INTRA_REFRESH_ADAPTIVE;
+			break;
+		case HAL_INTRA_REFRESH_CYCLIC:
+			hfi->mode = HFI_INTRA_REFRESH_CYCLIC;
+			break;
+		case HAL_INTRA_REFRESH_CYCLIC_ADAPTIVE:
+			hfi->mode = HFI_INTRA_REFRESH_CYCLIC_ADAPTIVE;
+			break;
+		case HAL_INTRA_REFRESH_RANDOM:
+			hfi->mode = HFI_INTRA_REFRESH_RANDOM;
+			break;
+		default:
+			dprintk(VIDC_ERR, "Invalid intra refresh setting: 0x%x",
+				prop->mode);
+			break;
+		}
+		hfi->air_mbs = prop->air_mbs;
+		hfi->air_ref = prop->air_ref;
+		hfi->cir_mbs = prop->cir_mbs;
+		pkt->size += sizeof(u32) + sizeof(struct hfi_intra_refresh);
+		break;
+	}
+	case HAL_PARAM_VENC_MULTI_SLICE_CONTROL:
+	{
+		struct hfi_multi_slice_control *hfi;
+		struct hal_multi_slice_control *prop =
+			(struct hal_multi_slice_control *) pdata;
+		pkt->rg_property_data[0] =
+			HFI_PROPERTY_PARAM_VENC_MULTI_SLICE_CONTROL;
+		hfi = (struct hfi_multi_slice_control *)
+			&pkt->rg_property_data[1];
+		switch (prop->multi_slice) {
+		case HAL_MULTI_SLICE_OFF:
+			hfi->multi_slice = HFI_MULTI_SLICE_OFF;
+			break;
+		case HAL_MULTI_SLICE_GOB:
+			hfi->multi_slice = HFI_MULTI_SLICE_GOB;
+			break;
+		case HAL_MULTI_SLICE_BY_MB_COUNT:
+			hfi->multi_slice = HFI_MULTI_SLICE_BY_MB_COUNT;
+			break;
+		case HAL_MULTI_SLICE_BY_BYTE_COUNT:
+			hfi->multi_slice = HFI_MULTI_SLICE_BY_BYTE_COUNT;
+			break;
+		default:
+			dprintk(VIDC_ERR, "Invalid slice settings: 0x%x",
+				prop->multi_slice);
+			break;
+		}
+		hfi->slice_size = prop->slice_size;
+		pkt->size += sizeof(u32) + sizeof(struct
+					hfi_multi_slice_control);
+		break;
+	}
+	case HAL_PARAM_INDEX_EXTRADATA:
+	{
+		struct hfi_index_extradata_config *hfi;
+		struct hal_extradata_enable *extra = pdata;
+		int index = 0;
+		pkt->rg_property_data[0] =
+			get_hfi_extradata_index(extra->index);
+		hfi =
+			(struct hfi_index_extradata_config *)
+			&pkt->rg_property_data[1];
+		hfi->enable = extra->enable;
+		if (extra->index == HAL_EXTRADATA_ASPECT_RATIO)
+			index = EXTRADATA_ASPECT_RATIO;
+		else
+			index = get_hfi_extradata_index(extra->index);
+		if (index)
+			hfi->index_extra_data_id = index;
+		else {
+			dprintk(VIDC_WARN,
+				"Failed to find extradata index: %d\n",
+				index);
+			rc = -EINVAL;
+		}
+		pkt->size += sizeof(u32) +
+			sizeof(struct hfi_index_extradata_config);
+		break;
+	}
+	case HAL_CONFIG_VPE_DEINTERLACE:
+		break;
+	/* FOLLOWING PROPERTIES ARE NOT IMPLEMENTED IN CORE YET */
+	case HAL_CONFIG_BUFFER_REQUIREMENTS:
+	case HAL_CONFIG_PRIORITY:
+	case HAL_CONFIG_BATCH_INFO:
+	case HAL_PARAM_METADATA_PASS_THROUGH:
+	case HAL_SYS_IDLE_INDICATOR:
+	case HAL_PARAM_UNCOMPRESSED_FORMAT_SUPPORTED:
+	case HAL_PARAM_INTERLACE_FORMAT_SUPPORTED:
+	case HAL_PARAM_CHROMA_SITE:
+	case HAL_PARAM_PROPERTIES_SUPPORTED:
+	case HAL_PARAM_PROFILE_LEVEL_SUPPORTED:
+	case HAL_PARAM_CAPABILITY_SUPPORTED:
+	case HAL_PARAM_NAL_STREAM_FORMAT_SUPPORTED:
+	case HAL_PARAM_MULTI_VIEW_FORMAT:
+	case HAL_PARAM_MAX_SEQUENCE_HEADER_SIZE:
+	case HAL_PARAM_CODEC_SUPPORTED:
+	case HAL_PARAM_VDEC_MULTI_VIEW_SELECT:
+	case HAL_PARAM_VDEC_MB_QUANTIZATION:
+	case HAL_PARAM_VDEC_NUM_CONCEALED_MB:
+	case HAL_PARAM_VDEC_H264_ENTROPY_SWITCHING:
+	case HAL_PARAM_VENC_SLICE_DELIVERY_MODE:
+	case HAL_PARAM_VENC_MPEG4_DATA_PARTITIONING:
+	case HAL_CONFIG_BUFFER_COUNT_ACTUAL:
+	case HAL_CONFIG_VDEC_MULTI_STREAM:
+	case HAL_PARAM_VENC_MULTI_SLICE_INFO:
+	case HAL_CONFIG_VENC_TIMESTAMP_SCALE:
+	case HAL_PARAM_VENC_LOW_LATENCY:
+	default:
+		dprintk(VIDC_ERR, "DEFAULT: Calling 0x%x", ptype);
+		break;
+	}
+	return rc;
+}
+
+static int get_hfi_ssr_type(enum hal_ssr_trigger_type type)
+{
+	int rc = HFI_TEST_SSR_HW_WDOG_IRQ;
+	switch (type) {
+	case SSR_ERR_FATAL:
+		rc = HFI_TEST_SSR_SW_ERR_FATAL;
+		break;
+	case SSR_SW_DIV_BY_ZERO:
+		rc = HFI_TEST_SSR_SW_DIV_BY_ZERO;
+		break;
+	case SSR_HW_WDOG_IRQ:
+		rc = HFI_TEST_SSR_HW_WDOG_IRQ;
+		break;
+	default:
+		dprintk(VIDC_WARN,
+			"SSR trigger type not recognized, using WDOG.\n");
+	}
+	return rc;
+}
+
+int create_pkt_ssr_cmd(enum hal_ssr_trigger_type type,
+		struct hfi_cmd_sys_test_ssr_packet *pkt)
+{
+	if (!pkt) {
+		dprintk(VIDC_ERR, "Invalid params, device: %p\n", pkt);
+		return -EINVAL;
+	}
+	pkt->size = sizeof(struct hfi_cmd_sys_test_ssr_packet);
+	pkt->packet_type = HFI_CMD_SYS_TEST_SSR;
+	pkt->trigger_type = get_hfi_ssr_type(type);
+	return 0;
+}
diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.h b/drivers/media/platform/msm/vidc/hfi_packetization.h
new file mode 100644
index 0000000..df93906
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/hfi_packetization.h
@@ -0,0 +1,92 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef __HFI_PACKETIZATION__
+#define __HFI_PACKETIZATION__
+
+#include <linux/types.h>
+#include "vidc_hfi_helper.h"
+#include "vidc_hfi.h"
+#include "vidc_hfi_api.h"
+
+int create_pkt_cmd_sys_init(struct hfi_cmd_sys_init_packet *pkt,
+							   u32 arch_type);
+int create_pkt_cmd_sys_pc_prep(struct hfi_cmd_sys_pc_prep_packet *pkt);
+
+int create_pkt_cmd_sys_idle_indicator(
+		struct hfi_cmd_sys_set_property_packet *pkt,
+		u32 enable);
+
+int create_pkt_set_cmd_sys_resource(
+		struct hfi_cmd_sys_set_resource_packet *pkt,
+		struct vidc_resource_hdr *resource_hdr,
+		void *resource_value);
+
+int create_pkt_cmd_sys_debug_config(
+		struct hfi_cmd_sys_set_property_packet *pkt,
+		u32 mode);
+
+int create_pkt_cmd_sys_release_resource(
+		struct hfi_cmd_sys_release_resource_packet *pkt,
+		struct vidc_resource_hdr *resource_hdr);
+
+int create_pkt_cmd_sys_ping(struct hfi_cmd_sys_ping_packet *pkt);
+
+int create_pkt_cmd_sys_session_init(
+	struct hfi_cmd_sys_session_init_packet *pkt,
+	u32 session_id, u32 session_domain, u32 session_codec);
+
+int create_pkt_cmd_session_cmd(struct vidc_hal_session_cmd_pkt *pkt,
+			int pkt_type, u32 session_id);
+
+int create_pkt_cmd_session_set_buffers(
+		struct hfi_cmd_session_set_buffers_packet *pkt,
+		u32 session_id,
+		struct vidc_buffer_addr_info *buffer_info);
+
+int create_pkt_cmd_session_release_buffers(
+		struct hfi_cmd_session_release_buffer_packet *pkt,
+		u32 session_id, struct vidc_buffer_addr_info *buffer_info);
+
+int create_pkt_cmd_session_etb_decoder(
+	struct hfi_cmd_session_empty_buffer_compressed_packet *pkt,
+	u32 session_id, struct vidc_frame_data *input_frame);
+
+int create_pkt_cmd_session_etb_encoder(
+	struct hfi_cmd_session_empty_buffer_uncompressed_plane0_packet *pkt,
+	u32 session_id, struct vidc_frame_data *input_frame);
+
+int create_pkt_cmd_session_ftb(struct hfi_cmd_session_fill_buffer_packet *pkt,
+		u32 session_id, struct vidc_frame_data *output_frame);
+
+int create_pkt_cmd_session_parse_seq_header(
+		struct hfi_cmd_session_parse_sequence_header_packet *pkt,
+		u32 session_id, struct vidc_seq_hdr *seq_hdr);
+
+int create_pkt_cmd_session_get_seq_hdr(
+		struct hfi_cmd_session_get_sequence_header_packet *pkt,
+		u32 session_id, struct vidc_seq_hdr *seq_hdr);
+
+int create_pkt_cmd_session_get_buf_req(
+		struct hfi_cmd_session_get_property_packet *pkt,
+		u32 session_id);
+
+int create_pkt_cmd_session_flush(struct hfi_cmd_session_flush_packet *pkt,
+			u32 session_id, enum hal_flush flush_mode);
+
+int create_pkt_cmd_session_set_property(
+		struct hfi_cmd_session_set_property_packet *pkt,
+		u32 session_id, enum hal_property ptype, void *pdata);
+
+int create_pkt_ssr_cmd(enum hal_ssr_trigger_type type,
+		struct hfi_cmd_sys_test_ssr_packet *pkt);
+#endif
diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c
new file mode 100644
index 0000000..be9458d
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c
@@ -0,0 +1,941 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include "vidc_hfi_helper.h"
+#include "vidc_hfi_io.h"
+#include "msm_vidc_debug.h"
+#include "vidc_hfi.h"
+
+static enum vidc_status hfi_map_err_status(int hfi_err)
+{
+	enum vidc_status vidc_err;
+	switch (hfi_err) {
+	case HFI_ERR_NONE:
+	case HFI_ERR_SESSION_SAME_STATE_OPERATION:
+		vidc_err = VIDC_ERR_NONE;
+		break;
+	case HFI_ERR_SYS_FATAL:
+		vidc_err = VIDC_ERR_HW_FATAL;
+		break;
+	case HFI_ERR_SYS_VERSION_MISMATCH:
+	case HFI_ERR_SYS_INVALID_PARAMETER:
+	case HFI_ERR_SYS_SESSION_ID_OUT_OF_RANGE:
+	case HFI_ERR_SESSION_INVALID_PARAMETER:
+	case HFI_ERR_SESSION_INVALID_SESSION_ID:
+	case HFI_ERR_SESSION_INVALID_STREAM_ID:
+		vidc_err = VIDC_ERR_BAD_PARAM;
+		break;
+	case HFI_ERR_SYS_INSUFFICIENT_RESOURCES:
+	case HFI_ERR_SYS_UNSUPPORTED_DOMAIN:
+	case HFI_ERR_SYS_UNSUPPORTED_CODEC:
+	case HFI_ERR_SESSION_UNSUPPORTED_PROPERTY:
+	case HFI_ERR_SESSION_UNSUPPORTED_SETTING:
+	case HFI_ERR_SESSION_INSUFFICIENT_RESOURCES:
+		vidc_err = VIDC_ERR_NOT_SUPPORTED;
+		break;
+	case HFI_ERR_SYS_MAX_SESSIONS_REACHED:
+		vidc_err = VIDC_ERR_MAX_CLIENT;
+		break;
+	case HFI_ERR_SYS_SESSION_IN_USE:
+		vidc_err = VIDC_ERR_CLIENT_PRESENT;
+		break;
+	case HFI_ERR_SESSION_FATAL:
+		vidc_err = VIDC_ERR_CLIENT_FATAL;
+		break;
+	case HFI_ERR_SESSION_BAD_POINTER:
+		vidc_err = VIDC_ERR_BAD_PARAM;
+		break;
+	case HFI_ERR_SESSION_INCORRECT_STATE_OPERATION:
+		vidc_err = VIDC_ERR_BAD_STATE;
+		break;
+	case HFI_ERR_SESSION_STREAM_CORRUPT:
+	case HFI_ERR_SESSION_STREAM_CORRUPT_OUTPUT_STALLED:
+		vidc_err = VIDC_ERR_BITSTREAM_ERR;
+		break;
+	case HFI_ERR_SESSION_SYNC_FRAME_NOT_DETECTED:
+		vidc_err = VIDC_ERR_IFRAME_EXPECTED;
+		break;
+	case HFI_ERR_SESSION_EMPTY_BUFFER_DONE_OUTPUT_PENDING:
+	default:
+		vidc_err = VIDC_ERR_FAIL;
+		break;
+	}
+	return vidc_err;
+}
+
+static void hfi_process_sess_evt_seq_changed(
+		msm_vidc_callback callback, u32 device_id,
+		struct hfi_msg_event_notify_packet *pkt)
+{
+	struct msm_vidc_cb_cmd_done cmd_done;
+	struct msm_vidc_cb_event event_notify;
+	int num_properties_changed;
+	struct hfi_frame_size frame_sz;
+	u8 *data_ptr;
+	int prop_id;
+	dprintk(VIDC_DBG, "RECEIVED:EVENT_NOTIFY");
+	if (sizeof(struct hfi_msg_event_notify_packet)
+		> pkt->size) {
+		dprintk(VIDC_ERR, "hal_process_session_init_done:bad_pkt_size");
+		return;
+	}
+
+	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
+	memset(&event_notify, 0, sizeof(struct
+				msm_vidc_cb_event));
+
+	cmd_done.device_id = device_id;
+	cmd_done.session_id = ((struct hal_session *) pkt->session_id)->
+		session_id;
+	cmd_done.status = VIDC_ERR_NONE;
+	cmd_done.size = sizeof(struct msm_vidc_cb_event);
+	num_properties_changed = pkt->event_data2;
+	switch (pkt->event_data1) {
+	case HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUFFER_RESOURCES:
+		event_notify.hal_event_type =
+			HAL_EVENT_SEQ_CHANGED_SUFFICIENT_RESOURCES;
+		break;
+	case HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUFFER_RESOURCES:
+		event_notify.hal_event_type =
+			HAL_EVENT_SEQ_CHANGED_INSUFFICIENT_RESOURCES;
+		break;
+	default:
+		break;
+	}
+	if (num_properties_changed) {
+		data_ptr = (u8 *) &pkt->rg_ext_event_data[0];
+		do {
+			prop_id = (int) *((u32 *)data_ptr);
+			switch (prop_id) {
+			case HFI_PROPERTY_PARAM_FRAME_SIZE:
+				frame_sz.buffer_type =
+					(int) *((((u32 *)data_ptr)+1));
+				frame_sz.width =
+					event_notify.width =
+						*((((u32 *)data_ptr)+2));
+				frame_sz.height =
+					event_notify.height =
+						*((((u32 *)data_ptr)+3));
+				data_ptr += 4;
+			break;
+			default:
+			break;
+			}
+			num_properties_changed--;
+		} while (num_properties_changed > 0);
+	}
+	cmd_done.data = &event_notify;
+	callback(VIDC_EVENT_CHANGE, &cmd_done);
+}
+
+static void hfi_process_sys_error(
+		msm_vidc_callback callback, u32 device_id)
+{
+	struct msm_vidc_cb_cmd_done cmd_done;
+	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
+	cmd_done.device_id = device_id;
+	callback(SYS_ERROR, &cmd_done);
+}
+static void hfi_process_session_error(
+		msm_vidc_callback callback, u32 device_id,
+		struct hfi_msg_event_notify_packet *pkt)
+{
+	struct msm_vidc_cb_cmd_done cmd_done;
+	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
+	cmd_done.device_id = device_id;
+	cmd_done.session_id = ((struct hal_session *) pkt->session_id)->
+		session_id;
+	callback(SESSION_ERROR, &cmd_done);
+}
+static void hfi_process_event_notify(
+		msm_vidc_callback callback, u32 device_id,
+		struct hfi_msg_event_notify_packet *pkt)
+{
+	dprintk(VIDC_DBG, "RECVD:EVENT_NOTIFY");
+
+	if (!callback || !pkt ||
+		pkt->size < sizeof(struct hfi_msg_event_notify_packet)) {
+		dprintk(VIDC_ERR, "Invalid Params");
+		return;
+	}
+
+	switch (pkt->event_id) {
+	case HFI_EVENT_SYS_ERROR:
+		dprintk(VIDC_ERR, "HFI_EVENT_SYS_ERROR: %d\n",
+			pkt->event_data1);
+		hfi_process_sys_error(callback, device_id);
+		break;
+	case HFI_EVENT_SESSION_ERROR:
+		dprintk(VIDC_ERR, "HFI_EVENT_SESSION_ERROR");
+		hfi_process_session_error(callback, device_id, pkt);
+		break;
+	case HFI_EVENT_SESSION_SEQUENCE_CHANGED:
+		dprintk(VIDC_INFO, "HFI_EVENT_SESSION_SEQUENCE_CHANGED");
+		hfi_process_sess_evt_seq_changed(callback, device_id, pkt);
+		break;
+	case HFI_EVENT_SESSION_PROPERTY_CHANGED:
+		dprintk(VIDC_INFO, "HFI_EVENT_SESSION_PROPERTY_CHANGED");
+		break;
+	default:
+		dprintk(VIDC_WARN, "hal_process_event_notify:unkown_event_id");
+		break;
+	}
+}
+static void hfi_process_sys_init_done(
+		msm_vidc_callback callback, u32 device_id,
+		struct hfi_msg_sys_init_done_packet *pkt)
+{
+	struct msm_vidc_cb_cmd_done cmd_done;
+	struct vidc_hal_sys_init_done sys_init_done;
+	u32 rem_bytes, bytes_read = 0, num_properties;
+	u8 *data_ptr;
+	int prop_id;
+	enum vidc_status status = VIDC_ERR_NONE;
+
+	dprintk(VIDC_DBG, "RECEIVED:SYS_INIT_DONE");
+	if (sizeof(struct hfi_msg_sys_init_done_packet) > pkt->size) {
+		dprintk(VIDC_ERR, "hal_process_sys_init_done:bad_pkt_size: %d",
+				pkt->size);
+		return;
+	}
+
+	status = hfi_map_err_status((u32)pkt->error_type);
+
+	if (!status) {
+		if (pkt->num_properties == 0) {
+			dprintk(VIDC_ERR, "hal_process_sys_init_done:"
+						"no_properties");
+			status = VIDC_ERR_FAIL;
+			goto err_no_prop;
+		}
+
+		rem_bytes = pkt->size - sizeof(struct
+			hfi_msg_sys_init_done_packet) + sizeof(u32);
+
+		if (rem_bytes == 0) {
+			dprintk(VIDC_ERR, "hal_process_sys_init_done:"
+						"missing_prop_info");
+			status = VIDC_ERR_FAIL;
+			goto err_no_prop;
+		}
+		memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
+		memset(&sys_init_done, 0, sizeof(struct
+				vidc_hal_sys_init_done));
+
+		data_ptr = (u8 *) &pkt->rg_property_data[0];
+		num_properties = pkt->num_properties;
+
+		while ((num_properties != 0) && (rem_bytes >= sizeof(u32))) {
+			prop_id = *((u32 *)data_ptr);
+			data_ptr = data_ptr + 4;
+
+			switch (prop_id) {
+			case HFI_PROPERTY_PARAM_CODEC_SUPPORTED:
+			{
+				struct hfi_codec_supported *prop =
+					(struct hfi_codec_supported *) data_ptr;
+				if (rem_bytes < sizeof(struct
+						hfi_codec_supported)) {
+					status = VIDC_ERR_BAD_PARAM;
+					break;
+				}
+				sys_init_done.dec_codec_supported =
+					prop->decoder_codec_supported;
+				sys_init_done.enc_codec_supported =
+					prop->encoder_codec_supported;
+				break;
+			}
+			default:
+				dprintk(VIDC_ERR, "hal_process_sys_init_done:"
+							"bad_prop_id");
+				status = VIDC_ERR_BAD_PARAM;
+				break;
+			}
+			if (!status) {
+				rem_bytes -= bytes_read;
+				data_ptr += bytes_read;
+				num_properties--;
+			}
+		}
+	}
+err_no_prop:
+	cmd_done.device_id = device_id;
+	cmd_done.session_id = 0;
+	cmd_done.status = (u32) status;
+	cmd_done.size = sizeof(struct vidc_hal_sys_init_done);
+	cmd_done.data = (void *) &sys_init_done;
+	callback(SYS_INIT_DONE, &cmd_done);
+}
+
+static void hfi_process_sys_rel_resource_done(
+		msm_vidc_callback callback, u32 device_id,
+		struct hfi_msg_sys_release_resource_done_packet *pkt)
+{
+	struct msm_vidc_cb_cmd_done cmd_done;
+	enum vidc_status status = VIDC_ERR_NONE;
+	u32 pkt_size;
+	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
+	dprintk(VIDC_DBG, "RECEIVED:SYS_RELEASE_RESOURCE_DONE");
+	pkt_size = sizeof(struct hfi_msg_sys_release_resource_done_packet);
+	if (pkt_size > pkt->size) {
+		dprintk(VIDC_ERR,
+			"hal_process_sys_rel_resource_done:bad size:%d",
+			pkt->size);
+		return;
+	}
+	status = hfi_map_err_status((u32)pkt->error_type);
+	cmd_done.device_id = device_id;
+	cmd_done.session_id = 0;
+	cmd_done.status = (u32) status;
+	cmd_done.size = 0;
+	cmd_done.data = NULL;
+	callback(RELEASE_RESOURCE_DONE, &cmd_done);
+}
+
+enum vidc_status hfi_process_sess_init_done_prop_read(
+	struct hfi_msg_sys_session_init_done_packet *pkt,
+	struct msm_vidc_cb_cmd_done *cmddone)
+{
+	return VIDC_ERR_NONE;
+}
+
+static void hfi_process_sess_get_prop_buf_req(
+	struct hfi_msg_session_property_info_packet *prop,
+	struct buffer_requirements *buffreq)
+{
+	struct hfi_buffer_requirements *hfi_buf_req;
+	u32 req_bytes;
+
+	dprintk(VIDC_DBG, "Entered ");
+	if (!prop) {
+		dprintk(VIDC_ERR,
+			"hal_process_sess_get_prop_buf_req:bad_prop: %p",
+			prop);
+		return;
+	}
+	req_bytes = prop->size - sizeof(
+	struct hfi_msg_session_property_info_packet);
+
+	if (!req_bytes || (req_bytes % sizeof(
+		struct hfi_buffer_requirements)) ||
+		(!prop->rg_property_data[1])) {
+		dprintk(VIDC_ERR,
+			"hal_process_sess_get_prop_buf_req:bad_pkt: %d",
+			req_bytes);
+		return;
+	}
+
+	hfi_buf_req = (struct hfi_buffer_requirements *)
+		&prop->rg_property_data[1];
+
+	while (req_bytes) {
+		if ((hfi_buf_req->buffer_size) &&
+			((hfi_buf_req->buffer_count_min > hfi_buf_req->
+			buffer_count_actual)))
+				dprintk(VIDC_WARN,
+					"hal_process_sess_get_prop_buf_req:"
+					"bad_buf_req");
+
+		dprintk(VIDC_DBG, "got buffer requirements for: %d",
+					hfi_buf_req->buffer_type);
+		switch (hfi_buf_req->buffer_type) {
+		case HFI_BUFFER_INPUT:
+			memcpy(&buffreq->buffer[0], hfi_buf_req,
+				sizeof(struct hfi_buffer_requirements));
+			buffreq->buffer[0].buffer_type = HAL_BUFFER_INPUT;
+			break;
+		case HFI_BUFFER_OUTPUT:
+			memcpy(&buffreq->buffer[1], hfi_buf_req,
+			sizeof(struct hfi_buffer_requirements));
+			buffreq->buffer[1].buffer_type = HAL_BUFFER_OUTPUT;
+			break;
+		case HFI_BUFFER_OUTPUT2:
+			memcpy(&buffreq->buffer[2], hfi_buf_req,
+				sizeof(struct hfi_buffer_requirements));
+			buffreq->buffer[2].buffer_type = HAL_BUFFER_OUTPUT2;
+			break;
+		case HFI_BUFFER_EXTRADATA_INPUT:
+			memcpy(&buffreq->buffer[3], hfi_buf_req,
+				sizeof(struct hfi_buffer_requirements));
+			buffreq->buffer[3].buffer_type =
+				HAL_BUFFER_EXTRADATA_INPUT;
+			break;
+		case HFI_BUFFER_EXTRADATA_OUTPUT:
+			memcpy(&buffreq->buffer[4], hfi_buf_req,
+				sizeof(struct hfi_buffer_requirements));
+			buffreq->buffer[4].buffer_type =
+				HAL_BUFFER_EXTRADATA_OUTPUT;
+			break;
+		case HFI_BUFFER_EXTRADATA_OUTPUT2:
+			memcpy(&buffreq->buffer[5], hfi_buf_req,
+				sizeof(struct hfi_buffer_requirements));
+			buffreq->buffer[5].buffer_type =
+				HAL_BUFFER_EXTRADATA_OUTPUT2;
+			break;
+		case HFI_BUFFER_INTERNAL_SCRATCH:
+			memcpy(&buffreq->buffer[6], hfi_buf_req,
+			sizeof(struct hfi_buffer_requirements));
+			buffreq->buffer[6].buffer_type =
+				HAL_BUFFER_INTERNAL_SCRATCH;
+			break;
+		case HFI_BUFFER_INTERNAL_SCRATCH_1:
+			memcpy(&buffreq->buffer[7], hfi_buf_req,
+				sizeof(struct hfi_buffer_requirements));
+			buffreq->buffer[7].buffer_type =
+				HAL_BUFFER_INTERNAL_SCRATCH_1;
+			break;
+		case HFI_BUFFER_INTERNAL_SCRATCH_2:
+			memcpy(&buffreq->buffer[8], hfi_buf_req,
+				sizeof(struct hfi_buffer_requirements));
+			buffreq->buffer[8].buffer_type =
+				HAL_BUFFER_INTERNAL_SCRATCH_2;
+			break;
+		case HFI_BUFFER_INTERNAL_PERSIST:
+			memcpy(&buffreq->buffer[9], hfi_buf_req,
+			sizeof(struct hfi_buffer_requirements));
+			buffreq->buffer[9].buffer_type =
+				HAL_BUFFER_INTERNAL_PERSIST;
+			break;
+		case HFI_BUFFER_INTERNAL_PERSIST_1:
+			memcpy(&buffreq->buffer[10], hfi_buf_req,
+				sizeof(struct hfi_buffer_requirements));
+			buffreq->buffer[10].buffer_type =
+				HAL_BUFFER_INTERNAL_PERSIST_1;
+			break;
+		default:
+			dprintk(VIDC_ERR,
+			"hal_process_sess_get_prop_buf_req: bad_buffer_type: %d",
+			hfi_buf_req->buffer_type);
+			break;
+		}
+		req_bytes -= sizeof(struct hfi_buffer_requirements);
+		hfi_buf_req++;
+	}
+}
+
+static void hfi_process_session_prop_info(
+		msm_vidc_callback callback, u32 device_id,
+		struct hfi_msg_session_property_info_packet *pkt)
+{
+	struct msm_vidc_cb_cmd_done cmd_done;
+	struct buffer_requirements buff_req;
+
+	dprintk(VIDC_DBG, "Received SESSION_PROPERTY_INFO");
+
+	if (pkt->size < sizeof(struct hfi_msg_session_property_info_packet)) {
+		dprintk(VIDC_ERR, "hal_process_session_prop_info:bad_pkt_size");
+		return;
+	}
+
+	if (pkt->num_properties == 0) {
+		dprintk(VIDC_ERR,
+			"hal_process_session_prop_info:no_properties");
+		return;
+	}
+
+	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
+	memset(&buff_req, 0, sizeof(struct buffer_requirements));
+
+	switch (pkt->rg_property_data[0]) {
+	case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:
+		hfi_process_sess_get_prop_buf_req(pkt, &buff_req);
+		cmd_done.device_id = device_id;
+		cmd_done.session_id =
+			((struct hal_session *) pkt->session_id)->session_id;
+		cmd_done.status = VIDC_ERR_NONE;
+		cmd_done.data = &buff_req;
+		cmd_done.size = sizeof(struct buffer_requirements);
+		callback(SESSION_PROPERTY_INFO, &cmd_done);
+		break;
+	default:
+		dprintk(VIDC_ERR, "hal_process_session_prop_info:"
+					"unknown_prop_id: %d",
+				pkt->rg_property_data[0]);
+		break;
+	}
+}
+
+static void hfi_process_session_init_done(
+		msm_vidc_callback callback, u32 device_id,
+		struct hfi_msg_sys_session_init_done_packet *pkt)
+{
+	struct msm_vidc_cb_cmd_done cmd_done;
+	struct vidc_hal_session_init_done session_init_done;
+
+	dprintk(VIDC_DBG, "RECEIVED:SESSION_INIT_DONE");
+	if (sizeof(struct hfi_msg_sys_session_init_done_packet)
+		> pkt->size) {
+		dprintk(VIDC_ERR, "hal_process_session_init_done:bad_pkt_size");
+		return;
+	}
+
+	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
+	memset(&session_init_done, 0, sizeof(struct
+				vidc_hal_session_init_done));
+
+	cmd_done.device_id = device_id;
+	cmd_done.session_id =
+		((struct hal_session *) pkt->session_id)->session_id;
+	cmd_done.status = hfi_map_err_status((u32)pkt->error_type);
+	cmd_done.data = &session_init_done;
+	if (!cmd_done.status) {
+		cmd_done.status = hfi_process_sess_init_done_prop_read(
+			pkt, &cmd_done);
+	}
+	cmd_done.size = sizeof(struct vidc_hal_session_init_done);
+	callback(SESSION_INIT_DONE, &cmd_done);
+}
+
+static void hfi_process_session_load_res_done(
+		msm_vidc_callback callback, u32 device_id,
+		struct hfi_msg_session_load_resources_done_packet *pkt)
+{
+	struct msm_vidc_cb_cmd_done cmd_done;
+	dprintk(VIDC_DBG, "RECEIVED:SESSION_LOAD_RESOURCES_DONE");
+
+	if (sizeof(struct hfi_msg_session_load_resources_done_packet) !=
+		pkt->size) {
+		dprintk(VIDC_ERR, "hal_process_session_load_res_done:"
+		" bad packet size: %d", pkt->size);
+		return;
+	}
+
+	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
+
+	cmd_done.device_id = device_id;
+	cmd_done.session_id =
+		((struct hal_session *) pkt->session_id)->session_id;
+	cmd_done.status = hfi_map_err_status((u32)pkt->error_type);
+	cmd_done.data = NULL;
+	cmd_done.size = 0;
+	callback(SESSION_LOAD_RESOURCE_DONE, &cmd_done);
+}
+
+static void hfi_process_session_flush_done(
+		msm_vidc_callback callback, u32 device_id,
+		struct hfi_msg_session_flush_done_packet *pkt)
+{
+	struct msm_vidc_cb_cmd_done cmd_done;
+
+	dprintk(VIDC_DBG, "RECEIVED:SESSION_FLUSH_DONE");
+
+	if (sizeof(struct hfi_msg_session_flush_done_packet) != pkt->size) {
+		dprintk(VIDC_ERR, "hal_process_session_flush_done: "
+		"bad packet size: %d", pkt->size);
+		return;
+	}
+
+	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
+	cmd_done.device_id = device_id;
+	cmd_done.session_id =
+		((struct hal_session *) pkt->session_id)->session_id;
+	cmd_done.status = hfi_map_err_status((u32)pkt->error_type);
+	cmd_done.data = (void *) pkt->flush_type;
+	cmd_done.size = sizeof(u32);
+	callback(SESSION_FLUSH_DONE, &cmd_done);
+}
+
+static void hfi_process_session_etb_done(
+		msm_vidc_callback callback, u32 device_id,
+		struct hfi_msg_session_empty_buffer_done_packet *pkt)
+{
+	struct msm_vidc_cb_data_done data_done;
+
+	dprintk(VIDC_DBG, "RECEIVED:SESSION_ETB_DONE");
+
+	if (!pkt || pkt->size <
+		sizeof(struct hfi_msg_session_empty_buffer_done_packet)) {
+		dprintk(VIDC_ERR, "hal_process_session_etb_done:bad_pkt_size");
+		return;
+	}
+
+	memset(&data_done, 0, sizeof(struct msm_vidc_cb_data_done));
+
+	data_done.device_id = device_id;
+	data_done.session_id =
+		((struct hal_session *) pkt->session_id)->session_id;
+	data_done.status = hfi_map_err_status((u32) pkt->error_type);
+	data_done.size = sizeof(struct msm_vidc_cb_data_done);
+	data_done.clnt_data = (void *)pkt->input_tag;
+	data_done.input_done.offset = pkt->offset;
+	data_done.input_done.filled_len = pkt->filled_len;
+	data_done.input_done.packet_buffer = pkt->packet_buffer;
+	callback(SESSION_ETB_DONE, &data_done);
+}
+
+static void hfi_process_session_ftb_done(
+		msm_vidc_callback callback, u32 device_id,
+		void *msg_hdr)
+{
+	struct msm_vidc_cb_data_done data_done;
+	struct hfi_msg_session_fill_buffer_done_compressed_packet *pack =
+	(struct hfi_msg_session_fill_buffer_done_compressed_packet *) msg_hdr;
+	u32 is_decoder = ((struct hal_session *)pack->session_id)->is_decoder;
+	struct hal_session *session;
+
+	if (!msg_hdr) {
+		dprintk(VIDC_ERR, "Invalid Params");
+		return;
+	}
+
+	session = (struct hal_session *)
+		((struct hal_session *)	pack->session_id)->session_id;
+	dprintk(VIDC_DBG, "RECEIVED:SESSION_FTB_DONE");
+
+	memset(&data_done, 0, sizeof(struct msm_vidc_cb_data_done));
+
+	if (is_decoder == 0) {
+		struct hfi_msg_session_fill_buffer_done_compressed_packet *pkt =
+		(struct hfi_msg_session_fill_buffer_done_compressed_packet *)
+		msg_hdr;
+		if (sizeof(struct
+			hfi_msg_session_fill_buffer_done_compressed_packet)
+			> pkt->size) {
+			dprintk(VIDC_ERR,
+				"hal_process_session_ftb_done: bad_pkt_size");
+			return;
+		} else if (pkt->error_type != HFI_ERR_NONE) {
+			dprintk(VIDC_ERR,
+				"got buffer back with error %x",
+				pkt->error_type);
+			/* Proceed with the FBD */
+		}
+
+		data_done.device_id = device_id;
+		data_done.session_id = (u32) session;
+		data_done.status = hfi_map_err_status((u32)
+							pkt->error_type);
+		data_done.size = sizeof(struct msm_vidc_cb_data_done);
+		data_done.clnt_data = (void *) pkt->input_tag;
+
+		data_done.output_done.timestamp_hi = pkt->time_stamp_hi;
+		data_done.output_done.timestamp_lo = pkt->time_stamp_lo;
+		data_done.output_done.flags1 = pkt->flags;
+		data_done.output_done.mark_target = pkt->mark_target;
+		data_done.output_done.mark_data = pkt->mark_data;
+		data_done.output_done.stats = pkt->stats;
+		data_done.output_done.offset1 = pkt->offset;
+		data_done.output_done.alloc_len1 = pkt->alloc_len;
+		data_done.output_done.filled_len1 = pkt->filled_len;
+		data_done.output_done.picture_type = pkt->picture_type;
+		data_done.output_done.packet_buffer1 = pkt->packet_buffer;
+		data_done.output_done.extra_data_buffer =
+			pkt->extra_data_buffer;
+		dprintk(VIDC_DBG, "FBD: Received buf: %p, of len: %d\n",
+				   pkt->packet_buffer, pkt->filled_len);
+	} else if (is_decoder == 1) {
+		struct hfi_msg_session_fbd_uncompressed_plane0_packet *pkt =
+		(struct	hfi_msg_session_fbd_uncompressed_plane0_packet *)
+		msg_hdr;
+		if (sizeof(struct
+		hfi_msg_session_fbd_uncompressed_plane0_packet)
+		> pkt->size) {
+			dprintk(VIDC_ERR, "hal_process_session_ftb_done:"
+						"bad_pkt_size");
+			return;
+		}
+
+		data_done.device_id = device_id;
+		data_done.session_id = (u32) session;
+		data_done.status = hfi_map_err_status((u32)
+			pkt->error_type);
+		data_done.size = sizeof(struct msm_vidc_cb_data_done);
+		data_done.clnt_data = (void *)pkt->input_tag;
+
+		data_done.output_done.stream_id = pkt->stream_id;
+		data_done.output_done.view_id = pkt->view_id;
+		data_done.output_done.timestamp_hi = pkt->time_stamp_hi;
+		data_done.output_done.timestamp_lo = pkt->time_stamp_lo;
+		data_done.output_done.flags1 = pkt->flags;
+		data_done.output_done.mark_target = pkt->mark_target;
+		data_done.output_done.mark_data = pkt->mark_data;
+		data_done.output_done.stats = pkt->stats;
+		data_done.output_done.alloc_len1 = pkt->alloc_len;
+		data_done.output_done.filled_len1 = pkt->filled_len;
+		data_done.output_done.offset1 = pkt->offset;
+		data_done.output_done.frame_width = pkt->frame_width;
+		data_done.output_done.frame_height = pkt->frame_height;
+		data_done.output_done.start_x_coord = pkt->start_x_coord;
+		data_done.output_done.start_y_coord = pkt->start_y_coord;
+		data_done.output_done.input_tag1 = pkt->input_tag;
+		data_done.output_done.picture_type = pkt->picture_type;
+		data_done.output_done.packet_buffer1 = pkt->packet_buffer;
+		data_done.output_done.extra_data_buffer =
+			pkt->extra_data_buffer;
+
+		if (pkt->stream_id == 0)
+			data_done.output_done.buffer_type = HAL_BUFFER_OUTPUT;
+		else if (pkt->stream_id == 1)
+			data_done.output_done.buffer_type = HAL_BUFFER_OUTPUT2;
+		}
+	callback(SESSION_FTB_DONE, &data_done);
+}
+
+static void hfi_process_session_start_done(
+		msm_vidc_callback callback, u32 device_id,
+		struct hfi_msg_session_start_done_packet *pkt)
+{
+	struct msm_vidc_cb_cmd_done cmd_done;
+
+	dprintk(VIDC_DBG, "RECEIVED:SESSION_START_DONE");
+
+	if (!pkt || pkt->size !=
+		sizeof(struct hfi_msg_session_start_done_packet)) {
+		dprintk(VIDC_ERR, "hal_process_session_start_done:"
+		"bad packet/packet size: %d", pkt->size);
+		return;
+	}
+
+	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
+	cmd_done.device_id = device_id;
+	cmd_done.session_id =
+		((struct hal_session *) pkt->session_id)->session_id;
+	cmd_done.status = hfi_map_err_status((u32)pkt->error_type);
+	cmd_done.data = NULL;
+	cmd_done.size = 0;
+	callback(SESSION_START_DONE, &cmd_done);
+}
+
+static void hfi_process_session_stop_done(
+		msm_vidc_callback callback, u32 device_id,
+		struct hfi_msg_session_stop_done_packet *pkt)
+{
+	struct msm_vidc_cb_cmd_done cmd_done;
+
+	dprintk(VIDC_DBG, "RECEIVED:SESSION_STOP_DONE");
+
+	if (!pkt || pkt->size !=
+		sizeof(struct hfi_msg_session_stop_done_packet)) {
+		dprintk(VIDC_ERR, "hal_process_session_stop_done:"
+		"bad packet/packet size: %d", pkt->size);
+		return;
+	}
+
+	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
+	cmd_done.device_id = device_id;
+	cmd_done.session_id =
+		((struct hal_session *) pkt->session_id)->session_id;
+	cmd_done.status = hfi_map_err_status((u32)pkt->error_type);
+	cmd_done.data = NULL;
+	cmd_done.size = 0;
+	callback(SESSION_STOP_DONE, &cmd_done);
+}
+
+static void hfi_process_session_rel_res_done(
+		msm_vidc_callback callback, u32 device_id,
+		struct hfi_msg_session_release_resources_done_packet *pkt)
+{
+	struct msm_vidc_cb_cmd_done cmd_done;
+
+	dprintk(VIDC_DBG, "RECEIVED:SESSION_RELEASE_RESOURCES_DONE");
+
+	if (!pkt || pkt->size !=
+		sizeof(struct hfi_msg_session_release_resources_done_packet)) {
+		dprintk(VIDC_ERR, "hal_process_session_rel_res_done:"
+		"bad packet/packet size: %d", pkt->size);
+		return;
+	}
+
+	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
+	cmd_done.device_id = device_id;
+	cmd_done.session_id =
+		((struct hal_session *) pkt->session_id)->session_id;
+	cmd_done.status = hfi_map_err_status((u32)pkt->error_type);
+	cmd_done.data = NULL;
+	cmd_done.size = 0;
+	callback(SESSION_RELEASE_RESOURCE_DONE, &cmd_done);
+}
+
+static void hfi_process_session_rel_buf_done(
+		msm_vidc_callback callback, u32 device_id,
+		struct hfi_msg_session_release_buffers_done_packet *pkt)
+{
+	struct msm_vidc_cb_cmd_done cmd_done;
+	if (!pkt || pkt->size !=
+		sizeof(struct
+			   hfi_msg_session_release_buffers_done_packet)) {
+		dprintk(VIDC_ERR, "bad packet/packet size: %d", pkt->size);
+		return;
+	}
+	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
+	cmd_done.device_id = device_id;
+	cmd_done.size = sizeof(struct msm_vidc_cb_cmd_done);
+	cmd_done.session_id =
+		((struct hal_session *) pkt->session_id)->session_id;
+	cmd_done.status = hfi_map_err_status((u32)pkt->error_type);
+	if (pkt->rg_buffer_info) {
+		cmd_done.data = (void *) &pkt->rg_buffer_info;
+		cmd_done.size = sizeof(struct hfi_buffer_info);
+	} else {
+		dprintk(VIDC_ERR, "invalid payload in rel_buff_done\n");
+	}
+	callback(SESSION_RELEASE_BUFFER_DONE, &cmd_done);
+}
+
+static void hfi_process_session_end_done(
+		msm_vidc_callback callback, u32 device_id,
+		struct hfi_msg_sys_session_end_done_packet *pkt)
+{
+	struct msm_vidc_cb_cmd_done cmd_done;
+	struct hal_session *sess_close;
+
+	dprintk(VIDC_DBG, "RECEIVED:SESSION_END_DONE");
+
+	if (!pkt || pkt->size !=
+		sizeof(struct hfi_msg_sys_session_end_done_packet)) {
+		dprintk(VIDC_ERR, "hal_process_session_end_done: "
+		"bad packet/packet size: %d", pkt->size);
+		return;
+	}
+
+	sess_close = (struct hal_session *)pkt->session_id;
+	dprintk(VIDC_INFO, "deleted the session: 0x%x",
+			sess_close->session_id);
+	list_del(&sess_close->list);
+	kfree(sess_close);
+
+	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
+	cmd_done.device_id = device_id;
+	cmd_done.session_id =
+		((struct hal_session *) pkt->session_id)->session_id;
+	cmd_done.status = hfi_map_err_status((u32)pkt->error_type);
+	cmd_done.data = NULL;
+	cmd_done.size = 0;
+	callback(SESSION_END_DONE, &cmd_done);
+}
+
+static void hfi_process_session_get_seq_hdr_done(
+	msm_vidc_callback callback, u32 device_id,
+	struct hfi_msg_session_get_sequence_header_done_packet *pkt)
+{
+	struct msm_vidc_cb_data_done data_done;
+	if (!pkt || pkt->size !=
+		sizeof(struct
+		hfi_msg_session_get_sequence_header_done_packet)) {
+		dprintk(VIDC_ERR, "bad packet/packet size: %d", pkt->size);
+		return;
+	}
+	memset(&data_done, 0, sizeof(struct msm_vidc_cb_data_done));
+	data_done.device_id = device_id;
+	data_done.size = sizeof(struct msm_vidc_cb_data_done);
+	data_done.session_id =
+		((struct hal_session *) pkt->session_id)->session_id;
+	data_done.status = hfi_map_err_status((u32)pkt->error_type);
+	data_done.output_done.packet_buffer1 = pkt->sequence_header;
+	data_done.output_done.filled_len1 = pkt->header_len;
+	dprintk(VIDC_INFO, "seq_hdr: %p, Length: %d",
+		   pkt->sequence_header, pkt->header_len);
+	callback(SESSION_GET_SEQ_HDR_DONE, &data_done);
+}
+
+u32 hfi_process_msg_packet(
+		msm_vidc_callback callback, u32 device_id,
+		struct vidc_hal_msg_pkt_hdr *msg_hdr)
+{
+	u32 rc = 0;
+	if (!callback || !msg_hdr || msg_hdr->size <
+		VIDC_IFACEQ_MIN_PKT_SIZE) {
+		dprintk(VIDC_ERR, "hal_process_msg_packet:bad"
+			"packet/packet size: %d", msg_hdr->size);
+		rc = -EINVAL;
+		return rc;
+	}
+
+	dprintk(VIDC_INFO, "Received: 0x%x in ", msg_hdr->packet);
+	rc = (u32) msg_hdr->packet;
+	switch (msg_hdr->packet) {
+	case HFI_MSG_EVENT_NOTIFY:
+		hfi_process_event_notify(callback, device_id,
+			(struct hfi_msg_event_notify_packet *) msg_hdr);
+		break;
+	case  HFI_MSG_SYS_INIT_DONE:
+		hfi_process_sys_init_done(callback, device_id,
+			(struct hfi_msg_sys_init_done_packet *)
+					msg_hdr);
+		break;
+	case HFI_MSG_SYS_IDLE:
+		break;
+	case HFI_MSG_SYS_SESSION_INIT_DONE:
+		hfi_process_session_init_done(callback, device_id,
+			(struct hfi_msg_sys_session_init_done_packet *)
+					msg_hdr);
+		break;
+	case HFI_MSG_SYS_SESSION_END_DONE:
+		hfi_process_session_end_done(callback, device_id,
+			(struct hfi_msg_sys_session_end_done_packet *)
+					msg_hdr);
+		break;
+	case HFI_MSG_SESSION_LOAD_RESOURCES_DONE:
+		hfi_process_session_load_res_done(callback, device_id,
+			(struct hfi_msg_session_load_resources_done_packet *)
+					msg_hdr);
+		break;
+	case HFI_MSG_SESSION_START_DONE:
+		hfi_process_session_start_done(callback, device_id,
+			(struct hfi_msg_session_start_done_packet *)
+					msg_hdr);
+		break;
+	case HFI_MSG_SESSION_STOP_DONE:
+		hfi_process_session_stop_done(callback, device_id,
+			(struct hfi_msg_session_stop_done_packet *)
+					msg_hdr);
+		break;
+	case HFI_MSG_SESSION_EMPTY_BUFFER_DONE:
+		hfi_process_session_etb_done(callback, device_id,
+			(struct hfi_msg_session_empty_buffer_done_packet *)
+					msg_hdr);
+		break;
+	case HFI_MSG_SESSION_FILL_BUFFER_DONE:
+		hfi_process_session_ftb_done(callback, device_id, msg_hdr);
+		break;
+	case HFI_MSG_SESSION_FLUSH_DONE:
+		hfi_process_session_flush_done(callback, device_id,
+			(struct hfi_msg_session_flush_done_packet *)
+					msg_hdr);
+		break;
+	case HFI_MSG_SESSION_PROPERTY_INFO:
+		hfi_process_session_prop_info(callback, device_id,
+			(struct hfi_msg_session_property_info_packet *)
+					msg_hdr);
+		break;
+	case HFI_MSG_SESSION_RELEASE_RESOURCES_DONE:
+		hfi_process_session_rel_res_done(callback, device_id,
+			(struct hfi_msg_session_release_resources_done_packet *)
+					msg_hdr);
+		break;
+	case HFI_MSG_SYS_RELEASE_RESOURCE:
+		hfi_process_sys_rel_resource_done(callback, device_id,
+			(struct hfi_msg_sys_release_resource_done_packet *)
+			msg_hdr);
+		break;
+	case HFI_MSG_SESSION_GET_SEQUENCE_HEADER_DONE:
+		hfi_process_session_get_seq_hdr_done(
+			callback, device_id, (struct
+			hfi_msg_session_get_sequence_header_done_packet*)
+			msg_hdr);
+		break;
+	case HFI_MSG_SESSION_RELEASE_BUFFERS_DONE:
+		hfi_process_session_rel_buf_done(
+			callback, device_id, (struct
+			hfi_msg_session_release_buffers_done_packet*)
+			msg_hdr);
+		break;
+	default:
+		dprintk(VIDC_ERR, "UNKNOWN_MSG_TYPE : %d", msg_hdr->packet);
+		break;
+	}
+	return rc;
+}
diff --git a/drivers/media/platform/msm/vidc/msm_smem.c b/drivers/media/platform/msm/vidc/msm_smem.c
new file mode 100644
index 0000000..125c699
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/msm_smem.c
@@ -0,0 +1,438 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/slab.h>
+#include <mach/iommu_domains.h>
+#include "msm_smem.h"
+#include "msm_vidc_debug.h"
+
+struct smem_client {
+	int mem_type;
+	void *clnt;
+};
+
+static int get_device_address(struct ion_client *clnt,
+		struct ion_handle *hndl, int domain_num, int partition_num,
+		unsigned long align, unsigned long *iova,
+		unsigned long *buffer_size, int flags)
+{
+	int rc = 0;
+	if (!iova || !buffer_size || !hndl || !clnt) {
+		dprintk(VIDC_ERR, "Invalid params: %p, %p, %p, %p\n",
+				clnt, hndl, iova, buffer_size);
+		return -EINVAL;
+	}
+	dprintk(VIDC_DBG, "domain: %d, partition: %d\n",
+		domain_num, partition_num);
+	if (flags & SMEM_SECURE) {
+		if (flags & SMEM_INPUT)
+			rc = msm_ion_secure_buffer(clnt, hndl, 0x1, 0);
+		else
+			rc = msm_ion_secure_buffer(clnt, hndl, 0x2, 0);
+		if (rc) {
+			dprintk(VIDC_ERR, "Failed to secure memory\n");
+			goto mem_secure_failed;
+		}
+	}
+	rc = ion_map_iommu(clnt, hndl, domain_num, partition_num, align,
+			0, iova, buffer_size, 0, 0);
+	if (rc)
+		dprintk(VIDC_ERR,
+		"ion_map_iommu failed(%d).domain: %d,partition: %d\n",
+		rc, domain_num, partition_num);
+mem_secure_failed:
+	return rc;
+}
+
+static void put_device_address(struct ion_client *clnt,
+	struct ion_handle *hndl, int domain_num, int partition_num, int flags)
+{
+	ion_unmap_iommu(clnt, hndl, domain_num, partition_num);
+	if (flags & SMEM_SECURE) {
+		if (msm_ion_unsecure_buffer(clnt, hndl))
+			dprintk(VIDC_ERR, "Failed to unsecure memory\n");
+	}
+}
+
+static int ion_user_to_kernel(struct smem_client *client,
+			int fd, u32 offset, int domain, int partition,
+			struct msm_smem *mem, int flags)
+{
+	struct ion_handle *hndl;
+	unsigned long iova = 0;
+	unsigned long buffer_size = 0;
+	unsigned long ionflags = 0;
+	int rc = 0;
+	int align = SZ_4K;
+	hndl = ion_import_dma_buf(client->clnt, fd);
+	if (IS_ERR_OR_NULL(hndl)) {
+		dprintk(VIDC_ERR, "Failed to get handle: %p, %d, %d, %p\n",
+				client, fd, offset, hndl);
+		rc = -ENOMEM;
+		goto fail_import_fd;
+	}
+	mem->kvaddr = NULL;
+	mem->domain = domain;
+	mem->partition_num = partition;
+	mem->flags = flags;
+	rc = ion_handle_get_flags(client->clnt, hndl, &ionflags);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to get ion flags: %d\n", rc);
+		goto fail_map;
+	}
+	if (ION_IS_CACHED(ionflags)) {
+		mem->kvaddr = ion_map_kernel(client->clnt, hndl);
+		if (!mem->kvaddr) {
+			dprintk(VIDC_ERR,
+					"Failed to map shared mem in kernel\n");
+			rc = -EIO;
+			goto fail_map;
+		}
+	}
+	if (flags & SMEM_SECURE)
+		align = ALIGN(align, SZ_1M);
+
+	rc = get_device_address(client->clnt, hndl, mem->domain,
+		mem->partition_num, align, &iova, &buffer_size, flags);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to get device address: %d\n", rc);
+		goto fail_device_address;
+	}
+
+	mem->mem_type = client->mem_type;
+	mem->smem_priv = hndl;
+	mem->device_addr = iova;
+	mem->size = buffer_size;
+	dprintk(VIDC_DBG, "NOTE: Buffer device address: 0x%lx, size: %d\n",
+		mem->device_addr, mem->size);
+	return rc;
+fail_device_address:
+	if (mem->kvaddr)
+		ion_unmap_kernel(client->clnt, hndl);
+fail_map:
+	ion_free(client->clnt, hndl);
+fail_import_fd:
+	return rc;
+}
+
+static int alloc_ion_mem(struct smem_client *client, size_t size,
+		u32 align, u32 flags, int domain, int partition,
+		struct msm_smem *mem, int map_kernel)
+{
+	struct ion_handle *hndl;
+	unsigned long iova = 0;
+	unsigned long buffer_size = 0;
+	unsigned long ionflags = 0;
+	unsigned long heap_mask = 0;
+	int rc = 0;
+	if (flags & SMEM_CACHED)
+		ionflags = ION_SET_CACHED(ionflags);
+	else
+		ionflags = ION_SET_UNCACHED(ionflags);
+
+	align = ALIGN(align, SZ_4K);
+	size = ALIGN(size, SZ_4K);
+
+	if (flags & SMEM_SECURE) {
+		ionflags |= ION_SECURE;
+		size = ALIGN(size, SZ_1M);
+		align = ALIGN(align, SZ_1M);
+	}
+
+	heap_mask = ION_HEAP(ION_CP_MM_HEAP_ID);
+	if (!(flags & SMEM_SECURE))
+		heap_mask |= ION_HEAP(ION_IOMMU_HEAP_ID);
+
+	dprintk(VIDC_DBG, "domain: %d, partition: %d\n",
+		domain, partition);
+	hndl = ion_alloc(client->clnt, size, align, heap_mask, ionflags);
+	if (IS_ERR_OR_NULL(hndl)) {
+		dprintk(VIDC_ERR,
+		"Failed to allocate shared memory = %p, %d, %d, 0x%lx\n",
+		client, size, align, ionflags);
+		rc = -ENOMEM;
+		goto fail_shared_mem_alloc;
+	}
+	mem->mem_type = client->mem_type;
+	mem->smem_priv = hndl;
+	mem->domain = domain;
+	mem->partition_num = partition;
+	mem->flags = flags;
+	if (map_kernel) {
+		mem->kvaddr = ion_map_kernel(client->clnt, hndl);
+		if (!mem->kvaddr) {
+			dprintk(VIDC_ERR,
+				"Failed to map shared mem in kernel\n");
+			rc = -EIO;
+			goto fail_map;
+		}
+	} else
+		mem->kvaddr = NULL;
+
+	rc = get_device_address(client->clnt, hndl, mem->domain,
+		mem->partition_num, align, &iova, &buffer_size, flags);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to get device address: %d\n",
+			rc);
+		goto fail_device_address;
+	}
+	mem->device_addr = iova;
+	dprintk(VIDC_DBG,
+		"device_address = 0x%lx, kvaddr = 0x%p, size = %d\n",
+		mem->device_addr, mem->kvaddr, size);
+	mem->size = size;
+	return rc;
+fail_device_address:
+	ion_unmap_kernel(client->clnt, hndl);
+fail_map:
+	ion_free(client->clnt, hndl);
+fail_shared_mem_alloc:
+	return rc;
+}
+
+static void free_ion_mem(struct smem_client *client, struct msm_smem *mem)
+{
+	if (mem->device_addr)
+		put_device_address(client->clnt,
+			mem->smem_priv, mem->domain,
+			mem->partition_num, mem->flags);
+	if (mem->kvaddr)
+		ion_unmap_kernel(client->clnt, mem->smem_priv);
+	if (mem->smem_priv)
+		ion_free(client->clnt, mem->smem_priv);
+}
+
+static void *ion_new_client(void)
+{
+	struct ion_client *client = NULL;
+	client = msm_ion_client_create(-1, "video_client");
+	if (!client)
+		dprintk(VIDC_ERR, "Failed to create smem client\n");
+	return client;
+};
+
+static void ion_delete_client(struct smem_client *client)
+{
+	ion_client_destroy(client->clnt);
+}
+
+struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 offset,
+	int domain, int partition, int flags)
+{
+	struct smem_client *client = clt;
+	int rc = 0;
+	struct msm_smem *mem;
+	if (fd < 0) {
+		dprintk(VIDC_ERR, "Invalid fd: %d\n", fd);
+		return NULL;
+	}
+	mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+	if (!mem) {
+		dprintk(VIDC_ERR, "Failed to allocte shared mem\n");
+		return NULL;
+	}
+	switch (client->mem_type) {
+	case SMEM_ION:
+		rc = ion_user_to_kernel(clt, fd, offset,
+			domain, partition, mem, flags);
+		break;
+	default:
+		dprintk(VIDC_ERR, "Mem type not supported\n");
+		rc = -EINVAL;
+		break;
+	}
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to allocate shared memory\n");
+		kfree(mem);
+		mem = NULL;
+	}
+	return mem;
+}
+
+static int ion_cache_operations(struct smem_client *client,
+	struct msm_smem *mem, enum smem_cache_ops cache_op)
+{
+	unsigned long ionflag = 0;
+	int rc = 0;
+	int msm_cache_ops = 0;
+	if (!mem || !client) {
+		dprintk(VIDC_ERR, "Invalid params: %p, %p\n",
+			mem, client);
+		return -EINVAL;
+	}
+	rc = ion_handle_get_flags(client->clnt,	mem->smem_priv,
+		&ionflag);
+	if (rc) {
+		dprintk(VIDC_ERR,
+			"ion_handle_get_flags failed: %d\n", rc);
+		goto cache_op_failed;
+	}
+	if (ION_IS_CACHED(ionflag)) {
+		switch (cache_op) {
+		case SMEM_CACHE_CLEAN:
+			msm_cache_ops = ION_IOC_CLEAN_CACHES;
+			break;
+		case SMEM_CACHE_INVALIDATE:
+			msm_cache_ops = ION_IOC_INV_CACHES;
+			break;
+		case SMEM_CACHE_CLEAN_INVALIDATE:
+			msm_cache_ops = ION_IOC_CLEAN_INV_CACHES;
+			break;
+		default:
+			dprintk(VIDC_ERR, "cache operation not supported\n");
+			rc = -EINVAL;
+			goto cache_op_failed;
+		}
+		if (mem->kvaddr) {
+			rc = msm_ion_do_cache_op(client->clnt,
+					(struct ion_handle *)mem->smem_priv,
+					(unsigned long *) mem->kvaddr,
+					(unsigned long)mem->size,
+					msm_cache_ops);
+			if (rc) {
+				dprintk(VIDC_ERR,
+					"cache operation failed %d\n", rc);
+				goto cache_op_failed;
+			}
+		} else {
+			dprintk(VIDC_WARN,
+				"cache operation failed as no kernel mapping\n");
+		}
+	}
+cache_op_failed:
+	return rc;
+}
+
+int msm_smem_cache_operations(void *clt, struct msm_smem *mem,
+		enum smem_cache_ops cache_op)
+{
+	struct smem_client *client = clt;
+	int rc = 0;
+	if (!client) {
+		dprintk(VIDC_ERR, "Invalid params: %p\n",
+			client);
+		return -EINVAL;
+	}
+	switch (client->mem_type) {
+	case SMEM_ION:
+		rc = ion_cache_operations(client, mem, cache_op);
+		if (rc)
+			dprintk(VIDC_ERR,
+			"Failed cache operations: %d\n", rc);
+		break;
+	default:
+		dprintk(VIDC_ERR, "Mem type not supported\n");
+		break;
+	}
+	return rc;
+}
+
+void *msm_smem_new_client(enum smem_type mtype)
+{
+	struct smem_client *client = NULL;
+	void *clnt = NULL;
+	switch (mtype) {
+	case SMEM_ION:
+		clnt = ion_new_client();
+		break;
+	default:
+		dprintk(VIDC_ERR, "Mem type not supported\n");
+		break;
+	}
+	if (clnt) {
+		client = kzalloc(sizeof(*client), GFP_KERNEL);
+		if (client) {
+			client->mem_type = mtype;
+			client->clnt = clnt;
+		}
+	} else {
+		dprintk(VIDC_ERR, "Failed to create new client: mtype = %d\n",
+			mtype);
+	}
+	return client;
+};
+
+struct msm_smem *msm_smem_alloc(void *clt, size_t size, u32 align, u32 flags,
+		int domain, int partition, int map_kernel)
+{
+	struct smem_client *client;
+	int rc = 0;
+	struct msm_smem *mem;
+	client = clt;
+	if (!client) {
+		dprintk(VIDC_ERR, "Invalid  client passed\n");
+		return NULL;
+	}
+	if (!size) {
+		dprintk(VIDC_ERR, "No need to allocate memory of size: %d\n",
+			size);
+		return NULL;
+	}
+	mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+	if (!mem) {
+		dprintk(VIDC_ERR, "Failed to allocate shared mem\n");
+		return NULL;
+	}
+	switch (client->mem_type) {
+	case SMEM_ION:
+		rc = alloc_ion_mem(client, size, align, flags,
+			domain, partition, mem, map_kernel);
+		break;
+	default:
+		dprintk(VIDC_ERR, "Mem type not supported\n");
+		rc = -EINVAL;
+		break;
+	}
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to allocate shared memory\n");
+		kfree(mem);
+		mem = NULL;
+	}
+	return mem;
+}
+
+void msm_smem_free(void *clt, struct msm_smem *mem)
+{
+	struct smem_client *client = clt;
+	if (!client || !mem) {
+		dprintk(VIDC_ERR, "Invalid  client/handle passed\n");
+		return;
+	}
+	switch (client->mem_type) {
+	case SMEM_ION:
+		free_ion_mem(client, mem);
+		break;
+	default:
+		dprintk(VIDC_ERR, "Mem type not supported\n");
+		break;
+	}
+	kfree(mem);
+};
+
+void msm_smem_delete_client(void *clt)
+{
+	struct smem_client *client = clt;
+	if (!client) {
+		dprintk(VIDC_ERR, "Invalid  client passed\n");
+		return;
+	}
+	switch (client->mem_type) {
+	case SMEM_ION:
+		ion_delete_client(client);
+		break;
+	default:
+		dprintk(VIDC_ERR, "Mem type not supported\n");
+		break;
+	}
+	kfree(client);
+}
diff --git a/drivers/media/platform/msm/vidc/msm_smem.h b/drivers/media/platform/msm/vidc/msm_smem.h
new file mode 100644
index 0000000..d1c8293
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/msm_smem.h
@@ -0,0 +1,56 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef _MSM_SMEM_H_
+#define _MSM_SMEM_H_
+
+#include <linux/types.h>
+#include <linux/msm_ion.h>
+
+enum smem_type {
+	SMEM_ION,
+};
+
+enum smem_prop {
+	SMEM_CACHED = 0x1,
+	SMEM_SECURE = 0x2,
+	SMEM_INPUT = 0x4,
+};
+
+struct msm_smem {
+	int mem_type;
+	size_t size;
+	void *kvaddr;
+	unsigned long device_addr;
+	int domain;
+	int partition_num;
+	int flags;
+	void *smem_priv;
+};
+
+enum smem_cache_ops {
+	SMEM_CACHE_CLEAN,
+	SMEM_CACHE_INVALIDATE,
+	SMEM_CACHE_CLEAN_INVALIDATE,
+};
+
+
+void *msm_smem_new_client(enum smem_type mtype);
+struct msm_smem *msm_smem_alloc(void *clt, size_t size, u32 align, u32 flags,
+		int domain, int partition, int map_kernel);
+void msm_smem_free(void *clt, struct msm_smem *mem);
+void msm_smem_delete_client(void *clt);
+struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 offset, int
+		domain, int partition, int flags);
+int msm_smem_cache_operations(void *clt, struct msm_smem *mem,
+		enum smem_cache_ops);
+#endif
diff --git a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
new file mode 100644
index 0000000..181b2b6
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
@@ -0,0 +1,1428 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/ioctl.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/debugfs.h>
+#include <linux/version.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <mach/board.h>
+#include <mach/iommu.h>
+#include <mach/iommu_domains.h>
+#include <media/msm_vidc.h>
+#include "msm_vidc_internal.h"
+#include "msm_vidc_debug.h"
+#include "vidc_hfi_api.h"
+#include "msm_smem.h"
+#include "vidc_hfi_api.h"
+#include "msm_vidc_resources.h"
+
+#define BASE_DEVICE_NUMBER 32
+
+struct msm_vidc_drv *vidc_driver;
+
+struct buffer_info {
+	struct list_head list;
+	int type;
+	int num_planes;
+	int fd[VIDEO_MAX_PLANES];
+	int buff_off[VIDEO_MAX_PLANES];
+	int size[VIDEO_MAX_PLANES];
+	u32 uvaddr[VIDEO_MAX_PLANES];
+	u32 device_addr[VIDEO_MAX_PLANES];
+	struct msm_smem *handle[VIDEO_MAX_PLANES];
+};
+
+struct msm_v4l2_vid_inst {
+	struct msm_vidc_inst *vidc_inst;
+	void *mem_client;
+	struct list_head registered_bufs;
+};
+
+struct master_slave {
+	int masters_ocmem[2];
+	int masters_ddr[2];
+	int slaves_ocmem[2];
+	int slaves_ddr[2];
+};
+
+struct bus_pdata_config {
+	int *masters;
+	int *slaves;
+	char *name;
+};
+
+static struct master_slave bus_vectors_masters_slaves = {
+	.masters_ocmem = {MSM_BUS_MASTER_VIDEO_P0_OCMEM,
+				MSM_BUS_MASTER_VIDEO_P1_OCMEM},
+	.masters_ddr = {MSM_BUS_MASTER_VIDEO_P0, MSM_BUS_MASTER_VIDEO_P1},
+	.slaves_ocmem = {MSM_BUS_SLAVE_OCMEM, MSM_BUS_SLAVE_OCMEM},
+	.slaves_ddr = {MSM_BUS_SLAVE_EBI_CH0, MSM_BUS_SLAVE_EBI_CH0},
+};
+
+static struct bus_pdata_config bus_pdata_config_vector[] = {
+{
+	.masters = bus_vectors_masters_slaves.masters_ocmem,
+	.slaves = bus_vectors_masters_slaves.slaves_ocmem,
+	.name = "qcom,enc-ocmem-ab-ib",
+},
+{
+	.masters = bus_vectors_masters_slaves.masters_ocmem,
+	.slaves = bus_vectors_masters_slaves.slaves_ocmem,
+	.name = "qcom,dec-ocmem-ab-ib",
+},
+{
+	.masters = bus_vectors_masters_slaves.masters_ddr,
+	.slaves = bus_vectors_masters_slaves.slaves_ddr,
+	.name = "qcom,enc-ddr-ab-ib",
+},
+{
+	.masters = bus_vectors_masters_slaves.masters_ddr,
+	.slaves = bus_vectors_masters_slaves.slaves_ddr,
+	.name = "qcom,dec-ddr-ab-ib",
+},
+};
+
+static inline struct msm_vidc_inst *get_vidc_inst(struct file *filp, void *fh)
+{
+	return container_of(filp->private_data,
+					struct msm_vidc_inst, event_handler);
+}
+
+static inline struct msm_v4l2_vid_inst *get_v4l2_inst(struct file *filp,
+			void *fh)
+{
+	struct msm_vidc_inst *vidc_inst;
+	vidc_inst = container_of(filp->private_data,
+			struct msm_vidc_inst, event_handler);
+	return (struct msm_v4l2_vid_inst *)vidc_inst->priv;
+}
+
+struct buffer_info *get_registered_buf(struct list_head *list,
+				int fd, u32 buff_off, u32 size, int *plane)
+{
+	struct buffer_info *temp;
+	struct buffer_info *ret = NULL;
+	int i;
+	if (!list || fd < 0 || !plane) {
+		dprintk(VIDC_ERR, "Invalid input\n");
+		goto err_invalid_input;
+	}
+	*plane = 0;
+	if (!list_empty(list)) {
+		list_for_each_entry(temp, list, list) {
+			for (i = 0; (i < temp->num_planes)
+				&& (i < VIDEO_MAX_PLANES); i++) {
+				if (temp && temp->fd[i] == fd &&
+						(CONTAINS(temp->buff_off[i],
+						temp->size[i], buff_off)
+						 || CONTAINS(buff_off,
+						 size, temp->buff_off[i])
+						 || OVERLAPS(buff_off, size,
+						 temp->buff_off[i],
+						 temp->size[i]))) {
+					dprintk(VIDC_DBG,
+							"This memory region is already mapped\n");
+					ret = temp;
+					*plane = i;
+					break;
+				}
+			}
+			if (ret)
+				break;
+		}
+	}
+err_invalid_input:
+	return ret;
+}
+
+struct buffer_info *get_same_fd_buffer(struct list_head *list,
+		int fd, int *plane)
+{
+	struct buffer_info *temp;
+	struct buffer_info *ret = NULL;
+	int i;
+	if (!list || fd < 0 || !plane) {
+		dprintk(VIDC_ERR, "Invalid input\n");
+		goto err_invalid_input;
+	}
+	*plane = 0;
+	if (!list_empty(list)) {
+		list_for_each_entry(temp, list, list) {
+			for (i = 0; (i < temp->num_planes)
+				&& (i < VIDEO_MAX_PLANES); i++) {
+				if (temp && temp->fd[i] == fd)  {
+					dprintk(VIDC_INFO,
+					"Found same fd buffer\n");
+					ret = temp;
+					*plane = i;
+					break;
+				}
+			}
+			if (ret)
+				break;
+		}
+	}
+err_invalid_input:
+	return ret;
+}
+
+static struct buffer_info *device_to_uvaddr(
+	struct list_head *list, u32 device_addr)
+{
+	struct buffer_info *temp = NULL;
+	int found = 0;
+	int i;
+	if (!list || !device_addr) {
+		dprintk(VIDC_ERR, "Invalid input\n");
+		goto err_invalid_input;
+	}
+	if (!list_empty(list)) {
+		list_for_each_entry(temp, list, list) {
+			for (i = 0; (i < temp->num_planes)
+				&& (i < VIDEO_MAX_PLANES); i++) {
+				if (temp && temp->device_addr[i]
+						== device_addr)  {
+					dprintk(VIDC_INFO,
+					"Found same fd buffer\n");
+					found = 1;
+					break;
+				}
+			}
+			if (found)
+				break;
+		}
+	}
+err_invalid_input:
+	return temp;
+}
+
+static int msm_v4l2_open(struct file *filp)
+{
+	int rc = 0;
+	struct video_device *vdev = video_devdata(filp);
+	struct msm_video_device *vid_dev =
+		container_of(vdev, struct msm_video_device, vdev);
+	struct msm_vidc_core *core = video_drvdata(filp);
+	struct msm_v4l2_vid_inst *v4l2_inst = kzalloc(sizeof(*v4l2_inst),
+						GFP_KERNEL);
+	if (!v4l2_inst) {
+		dprintk(VIDC_ERR,
+			"Failed to allocate memory for this instance\n");
+		rc = -ENOMEM;
+		goto fail_nomem;
+	}
+	v4l2_inst->mem_client = msm_smem_new_client(SMEM_ION);
+	if (!v4l2_inst->mem_client) {
+		dprintk(VIDC_ERR, "Failed to create memory client\n");
+		rc = -ENOMEM;
+		goto fail_mem_client;
+	}
+
+	v4l2_inst->vidc_inst = msm_vidc_open(core->id, vid_dev->type);
+	if (!v4l2_inst->vidc_inst) {
+		dprintk(VIDC_ERR,
+		"Failed to create video instance, core: %d, type = %d\n",
+		core->id, vid_dev->type);
+		rc = -ENOMEM;
+		goto fail_open;
+	}
+	INIT_LIST_HEAD(&v4l2_inst->registered_bufs);
+	v4l2_inst->vidc_inst->priv = v4l2_inst;
+	clear_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags);
+	filp->private_data = &(v4l2_inst->vidc_inst->event_handler);
+	return rc;
+fail_open:
+	msm_smem_delete_client(v4l2_inst->mem_client);
+fail_mem_client:
+	kfree(v4l2_inst);
+fail_nomem:
+	return rc;
+}
+static int msm_v4l2_release_output_buffers(struct msm_v4l2_vid_inst *v4l2_inst)
+{
+	struct list_head *ptr, *next;
+	struct buffer_info *bi;
+	struct v4l2_buffer buffer_info;
+	struct v4l2_plane plane[VIDEO_MAX_PLANES];
+	int rc = 0;
+	int i;
+	list_for_each_safe(ptr, next, &v4l2_inst->registered_bufs) {
+		bi = list_entry(ptr, struct buffer_info, list);
+		if (bi->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+			buffer_info.type = bi->type;
+			for (i = 0; (i < bi->num_planes)
+				&& (i < VIDEO_MAX_PLANES); i++) {
+				plane[i].reserved[0] = bi->fd[i];
+				plane[i].reserved[1] = bi->buff_off[i];
+				plane[i].length = bi->size[i];
+				plane[i].m.userptr = bi->device_addr[i];
+				buffer_info.m.planes = plane;
+				dprintk(VIDC_DBG,
+					"Releasing buffer: %d, %d, %d\n",
+					buffer_info.m.planes[i].reserved[0],
+					buffer_info.m.planes[i].reserved[1],
+					buffer_info.m.planes[i].length);
+			}
+			buffer_info.length = bi->num_planes;
+			rc = msm_vidc_release_buf(v4l2_inst->vidc_inst,
+					&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);
+			list_del(&bi->list);
+			for (i = 0; i < bi->num_planes; i++) {
+				if (bi->handle[i])
+					msm_smem_free(v4l2_inst->mem_client,
+							bi->handle[i]);
+			}
+			kfree(bi);
+		}
+	}
+	return rc;
+}
+
+static int msm_v4l2_close(struct file *filp)
+{
+	int rc = 0;
+	struct list_head *ptr, *next;
+	struct buffer_info *bi;
+	struct msm_vidc_inst *vidc_inst;
+	struct msm_v4l2_vid_inst *v4l2_inst;
+	int i;
+	vidc_inst = get_vidc_inst(filp, NULL);
+	v4l2_inst = get_v4l2_inst(filp, NULL);
+	rc = msm_v4l2_release_output_buffers(v4l2_inst);
+	if (rc)
+		dprintk(VIDC_WARN,
+			"Failed in %s for release output buffers\n", __func__);
+	list_for_each_safe(ptr, next, &v4l2_inst->registered_bufs) {
+		bi = list_entry(ptr, struct buffer_info, list);
+		if (bi->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+			list_del(&bi->list);
+			for (i = 0; (i < bi->num_planes)
+				&& (i < VIDEO_MAX_PLANES); i++) {
+				if (bi->handle[i])
+					msm_smem_free(v4l2_inst->mem_client,
+							bi->handle[i]);
+			}
+			kfree(bi);
+		}
+	}
+	msm_smem_delete_client(v4l2_inst->mem_client);
+	rc = msm_vidc_close(vidc_inst);
+	kfree(v4l2_inst);
+	return rc;
+}
+
+static int msm_v4l2_querycap(struct file *filp, void *fh,
+			struct v4l2_capability *cap)
+{
+	struct msm_vidc_inst *vidc_inst = get_vidc_inst(filp, fh);
+	return msm_vidc_querycap((void *)vidc_inst, cap);
+}
+
+int msm_v4l2_enum_fmt(struct file *file, void *fh,
+					struct v4l2_fmtdesc *f)
+{
+	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	return msm_vidc_enum_fmt((void *)vidc_inst, f);
+}
+
+int msm_v4l2_s_fmt(struct file *file, void *fh,
+					struct v4l2_format *f)
+{
+	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	return msm_vidc_s_fmt((void *)vidc_inst, f);
+}
+
+int msm_v4l2_g_fmt(struct file *file, void *fh,
+					struct v4l2_format *f)
+{
+	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	return msm_vidc_g_fmt((void *)vidc_inst, f);
+}
+
+int msm_v4l2_s_ctrl(struct file *file, void *fh,
+					struct v4l2_control *a)
+{
+	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	return msm_vidc_s_ctrl((void *)vidc_inst, a);
+}
+
+int msm_v4l2_g_ctrl(struct file *file, void *fh,
+					struct v4l2_control *a)
+{
+	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	return msm_vidc_g_ctrl((void *)vidc_inst, a);
+}
+
+int msm_v4l2_reqbufs(struct file *file, void *fh,
+				struct v4l2_requestbuffers *b)
+{
+	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	struct msm_v4l2_vid_inst *v4l2_inst;
+	int rc = 0;
+	v4l2_inst = get_v4l2_inst(file, NULL);
+	if (b->count == 0)
+		rc = msm_v4l2_release_output_buffers(v4l2_inst);
+	if (rc)
+		dprintk(VIDC_WARN,
+			"Failed in %s for release output buffers\n", __func__);
+	return msm_vidc_reqbufs((void *)vidc_inst, b);
+}
+
+int msm_v4l2_prepare_buf(struct file *file, void *fh,
+				struct v4l2_buffer *b)
+{
+	struct msm_smem *handle = NULL;
+	struct buffer_info *binfo;
+	struct buffer_info *temp;
+	struct msm_vidc_inst *vidc_inst;
+	struct msm_v4l2_vid_inst *v4l2_inst;
+	int plane = 0;
+	int i, rc = 0;
+	int smem_flags = 0;
+	int domain;
+	struct hfi_device *hdev;
+
+	vidc_inst = get_vidc_inst(file, fh);
+	v4l2_inst = get_v4l2_inst(file, fh);
+	if (!v4l2_inst || !vidc_inst || !vidc_inst->core
+		|| !vidc_inst->core->device) {
+		rc = -EINVAL;
+		goto exit;
+	}
+
+	hdev = vidc_inst->core->device;
+
+	if (!v4l2_inst->mem_client) {
+		dprintk(VIDC_ERR, "Failed to get memory client\n");
+		rc = -ENOMEM;
+		goto exit;
+	}
+	binfo = kzalloc(sizeof(*binfo), GFP_KERNEL);
+	if (!binfo) {
+		dprintk(VIDC_ERR, "Out of memory\n");
+		rc = -ENOMEM;
+		goto exit;
+	}
+	if (b->length > VIDEO_MAX_PLANES) {
+		dprintk(VIDC_ERR, "Num planes exceeds max: %d, %d\n",
+			b->length, VIDEO_MAX_PLANES);
+		rc = -EINVAL;
+		goto exit;
+	}
+	for (i = 0; i < b->length; ++i) {
+		smem_flags = 0;
+		if (EXTRADATA_IDX(b->length) &&
+			(i == EXTRADATA_IDX(b->length)) &&
+			!b->m.planes[i].length) {
+			continue;
+		}
+		temp = get_registered_buf(&v4l2_inst->registered_bufs,
+				b->m.planes[i].reserved[0],
+				b->m.planes[i].reserved[1],
+				b->m.planes[i].length, &plane);
+		if (temp) {
+			dprintk(VIDC_DBG,
+				"This memory region has already been prepared\n");
+			rc = -EINVAL;
+			kfree(binfo);
+			goto exit;
+		}
+		if ((vidc_inst->mode == VIDC_SECURE)
+				&& (!EXTRADATA_IDX(b->length)
+					|| (i != EXTRADATA_IDX(b->length)))) {
+			smem_flags |= SMEM_SECURE;
+			domain = call_hfi_op(hdev, get_domain,
+					hdev->hfi_device_data, CP_MAP);
+		} else
+			domain = call_hfi_op(hdev, get_domain,
+					hdev->hfi_device_data, NS_MAP);
+
+		if (b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+			smem_flags |= SMEM_INPUT;
+
+		temp = get_same_fd_buffer(&v4l2_inst->registered_bufs,
+				b->m.planes[i].reserved[0], &plane);
+
+		if (temp) {
+			binfo->type = b->type;
+			binfo->fd[i] = b->m.planes[i].reserved[0];
+			binfo->buff_off[i] = b->m.planes[i].reserved[1];
+			binfo->size[i] = b->m.planes[i].length;
+			binfo->uvaddr[i] = b->m.planes[i].m.userptr;
+			binfo->device_addr[i] =
+			temp->handle[plane]->device_addr + binfo->buff_off[i];
+			binfo->handle[i] = NULL;
+		} else {
+			handle = msm_smem_user_to_kernel(v4l2_inst->mem_client,
+			b->m.planes[i].reserved[0],
+			b->m.planes[i].reserved[1],
+			domain,	0, smem_flags);
+			if (!handle) {
+				dprintk(VIDC_ERR,
+					"Failed to get device buffer address\n");
+				kfree(binfo);
+				goto exit;
+			}
+			binfo->type = b->type;
+			binfo->fd[i] = b->m.planes[i].reserved[0];
+			binfo->buff_off[i] = b->m.planes[i].reserved[1];
+			binfo->size[i] = b->m.planes[i].length;
+			binfo->uvaddr[i] = b->m.planes[i].m.userptr;
+			binfo->device_addr[i] =
+				handle->device_addr + binfo->buff_off[i];
+			binfo->handle[i] = handle;
+			dprintk(VIDC_DBG, "Registering buffer: %d, %d, %d\n",
+					b->m.planes[i].reserved[0],
+					b->m.planes[i].reserved[1],
+					b->m.planes[i].length);
+			rc = msm_smem_cache_operations(v4l2_inst->mem_client,
+				binfo->handle[i], SMEM_CACHE_CLEAN);
+			if (rc)
+				dprintk(VIDC_WARN,
+					"CACHE Clean failed: %d, %d, %d\n",
+					b->m.planes[i].reserved[0],
+					b->m.planes[i].reserved[1],
+					b->m.planes[i].length);
+		}
+		b->m.planes[i].m.userptr = binfo->device_addr[i];
+	}
+	binfo->num_planes = b->length;
+	list_add_tail(&binfo->list, &v4l2_inst->registered_bufs);
+	rc = msm_vidc_prepare_buf(v4l2_inst->vidc_inst, b);
+exit:
+	return rc;
+}
+
+int msm_v4l2_qbuf(struct file *file, void *fh,
+				struct v4l2_buffer *b)
+{
+	struct msm_vidc_inst *vidc_inst;
+	struct msm_v4l2_vid_inst *v4l2_inst;
+	struct buffer_info *binfo;
+	int plane = 0;
+	int rc = 0;
+	int i;
+	if (b->length > VIDEO_MAX_PLANES) {
+		dprintk(VIDC_ERR, "num planes exceeds max: %d\n",
+			b->length);
+		return -EINVAL;
+	}
+	vidc_inst = get_vidc_inst(file, fh);
+	v4l2_inst = get_v4l2_inst(file, fh);
+	for (i = 0; i < b->length; ++i) {
+		if (EXTRADATA_IDX(b->length) &&
+			(i == EXTRADATA_IDX(b->length)) &&
+			!b->m.planes[i].length) {
+			b->m.planes[i].m.userptr = 0;
+			continue;
+		}
+		binfo = get_registered_buf(&v4l2_inst->registered_bufs,
+				b->m.planes[i].reserved[0],
+				b->m.planes[i].reserved[1],
+				b->m.planes[i].length, &plane);
+		if (!binfo) {
+			dprintk(VIDC_ERR,
+				"This buffer is not registered: %d, %d, %d\n",
+				b->m.planes[i].reserved[0],
+				b->m.planes[i].reserved[1],
+				b->m.planes[i].length);
+			rc = -EINVAL;
+			goto err_invalid_buff;
+		}
+		b->m.planes[i].m.userptr = binfo->device_addr[i];
+		dprintk(VIDC_DBG, "Queueing device address = 0x%x\n",
+				binfo->device_addr[i]);
+		if (binfo->handle[i] &&
+			(b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)) {
+			rc = msm_smem_cache_operations(v4l2_inst->mem_client,
+					binfo->handle[i], SMEM_CACHE_CLEAN);
+			if (rc) {
+				dprintk(VIDC_ERR,
+					"Failed to clean caches: %d\n", rc);
+				goto err_invalid_buff;
+			}
+		}
+	}
+	rc = msm_vidc_qbuf(v4l2_inst->vidc_inst, b);
+err_invalid_buff:
+	return rc;
+}
+
+int msm_v4l2_dqbuf(struct file *file, void *fh,
+				struct v4l2_buffer *b)
+{
+	int rc = 0;
+	int i;
+	struct msm_v4l2_vid_inst *v4l2_inst;
+	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	struct buffer_info *buffer_info;
+	if (b->length > VIDEO_MAX_PLANES) {
+		dprintk(VIDC_ERR, "num planes exceed maximum: %d\n",
+			b->length);
+		return -EINVAL;
+	}
+	v4l2_inst = get_v4l2_inst(file, fh);
+	rc = msm_vidc_dqbuf((void *)vidc_inst, b);
+	if (rc) {
+		dprintk(VIDC_DBG,
+			"Failed to dqbuf, capability: %d, rc: %d\n",
+			b->type, rc);
+		goto fail_dq_buf;
+	}
+	for (i = 0; i < b->length; i++) {
+		if (EXTRADATA_IDX(b->length) &&
+				(i == EXTRADATA_IDX(b->length)) &&
+				!b->m.planes[i].m.userptr) {
+			continue;
+		}
+		buffer_info = device_to_uvaddr(
+				&v4l2_inst->registered_bufs,
+				b->m.planes[i].m.userptr);
+		b->m.planes[i].m.userptr = buffer_info->uvaddr[i];
+		if (!b->m.planes[i].m.userptr) {
+			dprintk(VIDC_ERR,
+			"Failed to find user virtual address, 0x%lx, %d, %d\n",
+			b->m.planes[i].m.userptr, b->type, i);
+			rc = -EINVAL;
+			goto fail_dq_buf;
+		}
+		if (buffer_info->handle[i] &&
+			(b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)) {
+			rc = msm_smem_cache_operations(v4l2_inst->mem_client,
+				buffer_info->handle[i], SMEM_CACHE_INVALIDATE);
+			if (rc) {
+				dprintk(VIDC_ERR,
+					"Failed to clean caches: %d\n", rc);
+				goto fail_dq_buf;
+			}
+		}
+	}
+fail_dq_buf:
+	return rc;
+}
+
+int msm_v4l2_streamon(struct file *file, void *fh,
+				enum v4l2_buf_type i)
+{
+	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	return msm_vidc_streamon((void *)vidc_inst, i);
+}
+
+int msm_v4l2_streamoff(struct file *file, void *fh,
+				enum v4l2_buf_type i)
+{
+	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	return msm_vidc_streamoff((void *)vidc_inst, i);
+}
+
+static int msm_v4l2_subscribe_event(struct v4l2_fh *fh,
+				struct v4l2_event_subscription *sub)
+{
+	struct msm_vidc_inst *vidc_inst = container_of(fh,
+			struct msm_vidc_inst, event_handler);
+	return msm_vidc_subscribe_event((void *)vidc_inst, sub);
+}
+
+static int msm_v4l2_unsubscribe_event(struct v4l2_fh *fh,
+				struct v4l2_event_subscription *sub)
+{
+	struct msm_vidc_inst *vidc_inst = container_of(fh,
+			struct msm_vidc_inst, event_handler);
+	return msm_vidc_unsubscribe_event((void *)vidc_inst, sub);
+}
+
+static int msm_v4l2_decoder_cmd(struct file *file, void *fh,
+				struct v4l2_decoder_cmd *dec)
+{
+	struct msm_v4l2_vid_inst *v4l2_inst;
+	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	int rc = 0;
+	v4l2_inst = get_v4l2_inst(file, NULL);
+	if (dec->cmd == V4L2_DEC_CMD_STOP)
+		rc = msm_v4l2_release_output_buffers(v4l2_inst);
+	if (rc)
+		dprintk(VIDC_WARN,
+			"Failed to release dec output buffers: %d\n", rc);
+	return msm_vidc_decoder_cmd((void *)vidc_inst, dec);
+}
+
+static int msm_v4l2_encoder_cmd(struct file *file, void *fh,
+				struct v4l2_encoder_cmd *enc)
+{
+	struct msm_v4l2_vid_inst *v4l2_inst;
+	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	int rc = 0;
+	v4l2_inst = get_v4l2_inst(file, NULL);
+	if (enc->cmd == V4L2_ENC_CMD_STOP)
+		rc = msm_v4l2_release_output_buffers(v4l2_inst);
+	if (rc)
+		dprintk(VIDC_WARN,
+			"Failed to release enc output buffers: %d\n", rc);
+	return msm_vidc_encoder_cmd((void *)vidc_inst, enc);
+}
+static int msm_v4l2_s_parm(struct file *file, void *fh,
+			struct v4l2_streamparm *a)
+{
+	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	return msm_vidc_s_parm((void *)vidc_inst, a);
+}
+static int msm_v4l2_g_parm(struct file *file, void *fh,
+		struct v4l2_streamparm *a)
+{
+	return 0;
+}
+static const struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = {
+	.vidioc_querycap = msm_v4l2_querycap,
+	.vidioc_enum_fmt_vid_cap_mplane = msm_v4l2_enum_fmt,
+	.vidioc_enum_fmt_vid_out_mplane = msm_v4l2_enum_fmt,
+	.vidioc_s_fmt_vid_cap_mplane = msm_v4l2_s_fmt,
+	.vidioc_s_fmt_vid_out_mplane = msm_v4l2_s_fmt,
+	.vidioc_g_fmt_vid_cap_mplane = msm_v4l2_g_fmt,
+	.vidioc_g_fmt_vid_out_mplane = msm_v4l2_g_fmt,
+	.vidioc_reqbufs = msm_v4l2_reqbufs,
+	.vidioc_prepare_buf = msm_v4l2_prepare_buf,
+	.vidioc_qbuf = msm_v4l2_qbuf,
+	.vidioc_dqbuf = msm_v4l2_dqbuf,
+	.vidioc_streamon = msm_v4l2_streamon,
+	.vidioc_streamoff = msm_v4l2_streamoff,
+	.vidioc_s_ctrl = msm_v4l2_s_ctrl,
+	.vidioc_g_ctrl = msm_v4l2_g_ctrl,
+	.vidioc_subscribe_event = msm_v4l2_subscribe_event,
+	.vidioc_unsubscribe_event = msm_v4l2_unsubscribe_event,
+	.vidioc_decoder_cmd = msm_v4l2_decoder_cmd,
+	.vidioc_encoder_cmd = msm_v4l2_encoder_cmd,
+	.vidioc_s_parm = msm_v4l2_s_parm,
+	.vidioc_g_parm = msm_v4l2_g_parm
+};
+
+static const struct v4l2_ioctl_ops msm_v4l2_enc_ioctl_ops = {
+};
+
+static unsigned int msm_v4l2_poll(struct file *filp,
+	struct poll_table_struct *pt)
+{
+	struct msm_vidc_inst *vidc_inst = get_vidc_inst(filp, NULL);
+	return msm_vidc_poll((void *)vidc_inst, filp, pt);
+}
+
+static const struct v4l2_file_operations msm_v4l2_vidc_fops = {
+	.owner = THIS_MODULE,
+	.open = msm_v4l2_open,
+	.release = msm_v4l2_close,
+	.ioctl = video_ioctl2,
+	.poll = msm_v4l2_poll,
+};
+
+void msm_vidc_release_video_device(struct video_device *pvdev)
+{
+}
+
+static size_t get_u32_array_num_elements(struct platform_device *pdev,
+					char *name)
+{
+	struct device_node *np = pdev->dev.of_node;
+	int len;
+	size_t num_elements = 0;
+	if (!of_get_property(np, name, &len)) {
+		dprintk(VIDC_ERR, "Failed to read %s from device tree\n",
+			name);
+		goto fail_read;
+	}
+
+	num_elements = len / sizeof(u32);
+	if (num_elements <= 0) {
+		dprintk(VIDC_ERR, "%s not specified in device tree\n",
+			name);
+		goto fail_read;
+	}
+	return num_elements / 2;
+
+fail_read:
+	return 0;
+}
+
+static int read_hfi_type(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	int rc = 0;
+	const char *hfi_name = NULL;
+
+	if (np) {
+		rc = of_property_read_string(np, "qcom,hfi", &hfi_name);
+		if (rc) {
+			dprintk(VIDC_ERR,
+				"Failed to read hfi from device tree\n");
+			goto err_hfi_read;
+		}
+		if (!strcmp(hfi_name, "venus"))
+			rc = VIDC_HFI_VENUS;
+		else if (!strcmp(hfi_name, "q6"))
+			rc = VIDC_HFI_Q6;
+		else
+			rc = -EINVAL;
+	} else
+		rc = VIDC_HFI_Q6;
+
+err_hfi_read:
+	return rc;
+}
+
+static inline void msm_vidc_free_freq_table(
+		struct msm_vidc_platform_resources *res)
+{
+	kfree(res->load_freq_tbl);
+	res->load_freq_tbl = NULL;
+}
+
+static inline void msm_vidc_free_iommu_maps(
+		struct msm_vidc_platform_resources *res)
+{
+	kfree(res->iommu_maps);
+	res->iommu_maps = NULL;
+}
+
+static inline void msm_vidc_free_reg_table(
+			struct msm_vidc_platform_resources *res)
+{
+	kfree(res->reg_set.reg_tbl);
+	res->reg_set.reg_tbl = NULL;
+}
+
+static inline void msm_vidc_free_bus_vectors(
+			struct msm_vidc_platform_resources *res)
+{
+	int i, j;
+	if (res->bus_pdata) {
+		for (i = 0; i < ARRAY_SIZE(bus_pdata_config_vector); i++) {
+			for (j = 0; j < res->bus_pdata[i].num_usecases; j++) {
+				kfree(res->bus_pdata[i].usecase[j].vectors);
+				res->bus_pdata[i].usecase[j].vectors = NULL;
+			}
+			kfree(res->bus_pdata[i].usecase);
+			res->bus_pdata[i].usecase = NULL;
+		}
+		kfree(res->bus_pdata);
+		res->bus_pdata = NULL;
+	}
+}
+
+static int msm_vidc_load_freq_table(struct msm_vidc_platform_resources *res)
+{
+	int rc = 0;
+	int num_elements = 0;
+	struct platform_device *pdev = res->pdev;
+
+	num_elements = get_u32_array_num_elements(pdev, "qcom,load-freq-tbl");
+	if (num_elements == 0) {
+		dprintk(VIDC_ERR, "no elements in frequency table\n");
+		return rc;
+	}
+
+	res->load_freq_tbl = kzalloc(num_elements * sizeof(*res->load_freq_tbl),
+			GFP_KERNEL);
+	if (!res->load_freq_tbl) {
+		dprintk(VIDC_ERR,
+				"%s Failed to alloc load_freq_tbl\n",
+				__func__);
+		return -ENOMEM;
+	}
+
+	if (of_property_read_u32_array(pdev->dev.of_node,
+		"qcom,load-freq-tbl", (u32 *)res->load_freq_tbl,
+		num_elements * 2)) {
+		dprintk(VIDC_ERR, "Failed to read frequency table\n");
+		msm_vidc_free_freq_table(res);
+		return -EINVAL;
+	}
+
+	res->load_freq_tbl_size = num_elements;
+	return rc;
+}
+
+static int msm_vidc_load_iommu_maps(struct msm_vidc_platform_resources *res)
+{
+	int rc = 0;
+	int num_elements = 0;
+	int i;
+	struct platform_device *pdev = res->pdev;
+	char *names[MAX_MAP] = {
+		[CP_MAP] = "qcom,vidc-cp-map",
+		[NS_MAP] = "qcom,vidc-ns-map",
+	};
+	char *contexts[MAX_MAP] = {
+		[CP_MAP] = "venus_cp",
+		[NS_MAP] = "venus_ns",
+	};
+
+
+	res->iommu_maps = kzalloc(MAX_MAP * sizeof(*res->iommu_maps),
+			GFP_KERNEL);
+	if (!res->iommu_maps) {
+		dprintk(VIDC_ERR, "%s Failed to alloc iommu_maps\n", __func__);
+		return -ENOMEM;
+	}
+
+	res->iommu_maps_size = MAX_MAP;
+	for (i = 0; i < MAX_MAP; i++) {
+		num_elements = get_u32_array_num_elements(pdev, names[i]);
+		if ((num_elements == 0)) {
+			if (i == NS_MAP) {
+				dprintk(VIDC_ERR,
+				"Domain not found in dtsi file :%s\n",
+				names[i]);
+				goto error;
+			} else
+				continue;
+		}
+		memcpy(&res->iommu_maps[i].name, names[i],
+				strlen(names[i]));
+		memcpy(&res->iommu_maps[i].ctx, contexts[i],
+				strlen(contexts[i]));
+
+		if (of_property_read_u32_array(pdev->dev.of_node, names[i],
+			res->iommu_maps[i].addr_range, num_elements * 2)) {
+			dprintk(VIDC_ERR, "Failed to read iommu map :%s\n",
+					names[i]);
+			rc = -EINVAL;
+			goto error;
+		}
+	}
+	return rc;
+error:
+	msm_vidc_free_iommu_maps(res);
+	return rc;
+}
+
+static int msm_vidc_load_reg_table(struct msm_vidc_platform_resources *res)
+{
+	struct reg_set *reg_set;
+	struct platform_device *pdev = res->pdev;
+	int i;
+	int rc = 0;
+
+	reg_set = &res->reg_set;
+	reg_set->count = get_u32_array_num_elements(pdev, "qcom,reg-presets");
+	if (reg_set->count == 0) {
+		dprintk(VIDC_DBG, "no elements in reg set\n");
+		return rc;
+	}
+
+	reg_set->reg_tbl = kzalloc(reg_set->count *
+			sizeof(*(reg_set->reg_tbl)), GFP_KERNEL);
+	if (!reg_set->reg_tbl) {
+		dprintk(VIDC_ERR, "%s Failed to alloc temp\n",
+			__func__);
+		return -ENOMEM;
+	}
+
+	if (of_property_read_u32_array(pdev->dev.of_node, "qcom,reg-presets",
+		(u32 *)reg_set->reg_tbl, reg_set->count * 2)) {
+		dprintk(VIDC_ERR, "Failed to read register table\n");
+		msm_vidc_free_reg_table(res);
+		return -EINVAL;
+	}
+	for (i = 0; i < reg_set->count; i++) {
+		dprintk(VIDC_DBG,
+			"reg = %x, value = %x\n",
+			reg_set->reg_tbl[i].reg,
+			reg_set->reg_tbl[i].value
+		);
+	}
+	return rc;
+}
+
+static void msm_vidc_free_bus_vector(struct msm_bus_scale_pdata *bus_pdata)
+{
+	int i;
+	for (i = 0; i < bus_pdata->num_usecases; i++) {
+		kfree(bus_pdata->usecase[i].vectors);
+		bus_pdata->usecase[i].vectors = NULL;
+	}
+
+	kfree(bus_pdata->usecase);
+	bus_pdata->usecase = NULL;
+}
+
+static int msm_vidc_load_bus_vector(struct platform_device *pdev,
+			struct msm_bus_scale_pdata *bus_pdata, u32 num_ports,
+			struct bus_pdata_config *bus_pdata_config)
+{
+	struct bus_values {
+	    u32 ab;
+	    u32 ib;
+	};
+	struct bus_values *values;
+	int i, j;
+	int rc = 0;
+
+	values = kzalloc(sizeof(*values) * bus_pdata->num_usecases, GFP_KERNEL);
+	if (!values) {
+		dprintk(VIDC_ERR, "%s Failed to alloc bus_values\n", __func__);
+		rc = -ENOMEM;
+		goto err_mem_alloc;
+	}
+
+	if (of_property_read_u32_array(pdev->dev.of_node,
+		    bus_pdata_config->name, (u32 *)values,
+		    bus_pdata->num_usecases * (sizeof(*values)/sizeof(u32)))) {
+		dprintk(VIDC_ERR, "%s Failed to read bus values\n", __func__);
+		rc = -EINVAL;
+		goto err_parse_dt;
+	}
+
+	bus_pdata->usecase = kzalloc(sizeof(*bus_pdata->usecase) *
+		    bus_pdata->num_usecases, GFP_KERNEL);
+	if (!bus_pdata->usecase) {
+		dprintk(VIDC_ERR,
+			"%s Failed to alloc bus_pdata usecase\n", __func__);
+		rc = -ENOMEM;
+		goto err_parse_dt;
+	}
+	bus_pdata->name = bus_pdata_config->name;
+	for (i = 0; i < bus_pdata->num_usecases; i++) {
+		bus_pdata->usecase[i].vectors = kzalloc(
+			sizeof(*bus_pdata->usecase[i].vectors) * num_ports,
+			GFP_KERNEL);
+		if (!bus_pdata->usecase) {
+			dprintk(VIDC_ERR,
+				"%s Failed to alloc bus_pdata usecase\n",
+				__func__);
+			break;
+		}
+		for (j = 0; j < num_ports; j++) {
+			bus_pdata->usecase[i].vectors[j].ab = (u64)values[i].ab
+									* 1000;
+			bus_pdata->usecase[i].vectors[j].ib = (u64)values[i].ib
+									* 1000;
+			bus_pdata->usecase[i].vectors[j].src =
+						bus_pdata_config->masters[j];
+			bus_pdata->usecase[i].vectors[j].dst =
+						bus_pdata_config->slaves[j];
+			dprintk(VIDC_DBG,
+				"ab = %llu, ib = %llu, src = %d, dst = %d\n",
+				bus_pdata->usecase[i].vectors[j].ab,
+				bus_pdata->usecase[i].vectors[j].ib,
+				bus_pdata->usecase[i].vectors[j].src,
+				bus_pdata->usecase[i].vectors[j].dst);
+		}
+		bus_pdata->usecase[i].num_paths = num_ports;
+	}
+	if (i < bus_pdata->num_usecases) {
+		for (--i; i >= 0; i--) {
+			kfree(bus_pdata->usecase[i].vectors);
+			bus_pdata->usecase[i].vectors = NULL;
+		}
+		kfree(bus_pdata->usecase);
+		bus_pdata->usecase = NULL;
+		rc = -EINVAL;
+	}
+err_parse_dt:
+	kfree(values);
+err_mem_alloc:
+	return rc;
+}
+
+static int msm_vidc_load_bus_vectors(struct msm_vidc_platform_resources *res)
+{
+	u32 num_ports = 0;
+	int rc = 0;
+	int i;
+	struct platform_device *pdev = res->pdev;
+	u32 num_bus_pdata = ARRAY_SIZE(bus_pdata_config_vector);
+
+	if (of_property_read_u32_array(pdev->dev.of_node, "qcom,bus-ports",
+			(u32 *)&num_ports, 1) || (num_ports == 0))
+		goto err_mem_alloc;
+
+	res->bus_pdata = kzalloc(sizeof(*res->bus_pdata) * num_bus_pdata,
+				GFP_KERNEL);
+	if (!res->bus_pdata) {
+		dprintk(VIDC_ERR, "Failed to alloc memory\n");
+		rc = -ENOMEM;
+		goto err_mem_alloc;
+	}
+	for (i = 0; i < num_bus_pdata; i++) {
+		res->bus_pdata[i].num_usecases = get_u32_array_num_elements(
+					pdev, bus_pdata_config_vector[i].name);
+		if (res->bus_pdata[i].num_usecases == 0) {
+			dprintk(VIDC_ERR, "no elements in %s\n",
+				bus_pdata_config_vector[i].name);
+			rc = -EINVAL;
+			break;
+		}
+
+		rc = msm_vidc_load_bus_vector(pdev, &res->bus_pdata[i],
+				num_ports, &bus_pdata_config_vector[i]);
+		if (rc) {
+			dprintk(VIDC_ERR,
+				"Failed to load bus vector: %d\n", i);
+			break;
+		}
+	}
+	if (i < num_bus_pdata) {
+		for (--i; i >= 0; i--)
+			msm_vidc_free_bus_vector(&res->bus_pdata[i]);
+		kfree(res->bus_pdata);
+		res->bus_pdata = NULL;
+	}
+err_mem_alloc:
+	return rc;
+}
+
+static int read_platform_resources_from_dt(
+		struct msm_vidc_platform_resources *res)
+{
+	struct platform_device *pdev = res->pdev;
+	struct resource *kres = NULL;
+	int rc = 0;
+
+	if (!pdev->dev.of_node) {
+		dprintk(VIDC_ERR, "DT node not found\n");
+		return -ENOENT;
+	}
+
+	res->fw_base_addr = 0x0;
+
+	kres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	res->register_base = kres ? kres->start : -1;
+	res->register_size = kres ? (kres->end + 1 - kres->start) : -1;
+
+	kres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	res->irq = kres ? kres->start : -1;
+
+	rc = msm_vidc_load_freq_table(res);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to load freq table: %d\n", rc);
+		goto err_load_freq_table;
+	}
+	rc = msm_vidc_load_iommu_maps(res);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to load iommu maps: %d\n", rc);
+		goto err_load_iommu_maps;
+	}
+	rc = msm_vidc_load_reg_table(res);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to load reg table: %d\n", rc);
+		goto err_load_reg_table;
+	}
+
+	rc = msm_vidc_load_bus_vectors(res);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to load bus vectors: %d\n", rc);
+		goto err_load_bus_vectors;
+	}
+	return rc;
+
+err_load_bus_vectors:
+	msm_vidc_free_reg_table(res);
+err_load_reg_table:
+	msm_vidc_free_iommu_maps(res);
+err_load_iommu_maps:
+	msm_vidc_free_freq_table(res);
+err_load_freq_table:
+	return rc;
+}
+
+static int read_platform_resources_from_board(
+		struct msm_vidc_platform_resources *res)
+{
+	struct resource *kres = NULL;
+	struct platform_device *pdev = res->pdev;
+	struct msm_vidc_v4l2_platform_data *pdata = pdev->dev.platform_data;
+	int64_t start, size;
+	int c = 0, rc = 0;
+
+	if (!pdata) {
+		dprintk(VIDC_ERR, "Platform data not found\n");
+		return -ENOENT;
+	}
+
+	res->fw_base_addr = 0x0;
+
+	kres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	res->register_base = kres ? kres->start : -1;
+	res->register_size = kres ? (kres->end + 1 - kres->start) : -1;
+
+	kres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	res->irq = kres ? kres->start : -1;
+
+	res->load_freq_tbl = kzalloc(pdata->num_load_table *
+			sizeof(*res->load_freq_tbl), GFP_KERNEL);
+
+	if (!res->load_freq_tbl) {
+		dprintk(VIDC_ERR, "%s Failed to alloc load_freq_tbl\n",
+				__func__);
+		return -ENOMEM;
+	}
+
+	res->load_freq_tbl_size = pdata->num_load_table;
+	for (c = 0; c > pdata->num_load_table; ++c) {
+		res->load_freq_tbl[c].load = pdata->load_table[c][0];
+		res->load_freq_tbl[c].freq = pdata->load_table[c][1];
+	}
+
+	res->iommu_maps = kzalloc(MAX_MAP *
+			sizeof(*res->iommu_maps), GFP_KERNEL);
+	if (!res->iommu_maps) {
+		dprintk(VIDC_ERR, "%s Failed to alloc iommu_maps\n",
+				__func__);
+		kfree(res->load_freq_tbl);
+		return -ENOMEM;
+	}
+
+	res->iommu_maps_size = MAX_MAP;
+
+	start = pdata->iommu_table[MSM_VIDC_V4L2_IOMMU_MAP_CP][0];
+	size = pdata->iommu_table[MSM_VIDC_V4L2_IOMMU_MAP_CP][1];
+	res->iommu_maps[CP_MAP] = (struct msm_vidc_iommu_info) {
+		.addr_range = {(u32) start, (u32) size},
+			.name = "qcom,vidc-cp-map",
+			.ctx = "venus_cp",
+	};
+
+	start = pdata->iommu_table[MSM_VIDC_V4L2_IOMMU_MAP_NS][0];
+	size = pdata->iommu_table[MSM_VIDC_V4L2_IOMMU_MAP_NS][1];
+	res->iommu_maps[NS_MAP] = (struct msm_vidc_iommu_info) {
+		.addr_range = {(u32) start, (u32) size},
+			.name = "qcom,vidc-ns-map",
+			.ctx = "venus_ns",
+	};
+	return rc;
+}
+
+static int read_platform_resources(struct msm_vidc_core *core,
+		struct platform_device *pdev)
+{
+	if (!core || !pdev) {
+		dprintk(VIDC_ERR, "%s: Invalid params %p %p\n",
+			__func__, core, pdev);
+		return -EINVAL;
+	}
+	core->hfi_type = read_hfi_type(pdev);
+	if (core->hfi_type < 0) {
+		dprintk(VIDC_ERR, "Failed to identify core type\n");
+		return core->hfi_type;
+	}
+
+	core->resources.pdev = pdev;
+	if (pdev->dev.of_node) {
+		/* Target supports DT, parse from it */
+		return read_platform_resources_from_dt(&core->resources);
+	} else {
+		/* Legacy board file usage */
+		return read_platform_resources_from_board(
+				&core->resources);
+	}
+}
+static int msm_vidc_initialize_core(struct platform_device *pdev,
+				struct msm_vidc_core *core)
+{
+	int i = 0;
+	int rc = 0;
+	if (!core)
+		return -EINVAL;
+	rc = read_platform_resources(core, pdev);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to get platform resources\n");
+		return rc;
+	}
+
+	INIT_LIST_HEAD(&core->instances);
+	mutex_init(&core->sync_lock);
+	mutex_init(&core->lock);
+
+	core->state = VIDC_CORE_UNINIT;
+	for (i = SYS_MSG_INDEX(SYS_MSG_START);
+		i <= SYS_MSG_INDEX(SYS_MSG_END); i++) {
+		init_completion(&core->completions[i]);
+	}
+
+	return rc;
+}
+
+static int __devinit msm_vidc_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+	struct msm_vidc_core *core;
+	core = kzalloc(sizeof(*core), GFP_KERNEL);
+	if (!core || !vidc_driver) {
+		dprintk(VIDC_ERR,
+			"Failed to allocate memory for device core\n");
+		rc = -ENOMEM;
+		goto err_no_mem;
+	}
+	rc = msm_vidc_initialize_core(pdev, core);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to init core\n");
+		goto err_v4l2_register;
+	}
+	rc = v4l2_device_register(&pdev->dev, &core->v4l2_dev);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to register v4l2 device\n");
+		goto err_v4l2_register;
+	}
+	core->vdev[MSM_VIDC_DECODER].vdev.release =
+		msm_vidc_release_video_device;
+	core->vdev[MSM_VIDC_DECODER].vdev.fops = &msm_v4l2_vidc_fops;
+	core->vdev[MSM_VIDC_DECODER].vdev.ioctl_ops = &msm_v4l2_ioctl_ops;
+	core->vdev[MSM_VIDC_DECODER].type = MSM_VIDC_DECODER;
+	rc = video_register_device(&core->vdev[MSM_VIDC_DECODER].vdev,
+					VFL_TYPE_GRABBER, BASE_DEVICE_NUMBER);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to register video decoder device");
+		goto err_dec_register;
+	}
+	video_set_drvdata(&core->vdev[MSM_VIDC_DECODER].vdev, core);
+
+	core->vdev[MSM_VIDC_ENCODER].vdev.release =
+		msm_vidc_release_video_device;
+	core->vdev[MSM_VIDC_ENCODER].vdev.fops = &msm_v4l2_vidc_fops;
+	core->vdev[MSM_VIDC_ENCODER].vdev.ioctl_ops = &msm_v4l2_ioctl_ops;
+	core->vdev[MSM_VIDC_ENCODER].type = MSM_VIDC_ENCODER;
+	rc = video_register_device(&core->vdev[MSM_VIDC_ENCODER].vdev,
+				VFL_TYPE_GRABBER, BASE_DEVICE_NUMBER + 1);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to register video encoder device");
+		goto err_enc_register;
+	}
+	video_set_drvdata(&core->vdev[MSM_VIDC_ENCODER].vdev, core);
+
+	core->device = vidc_hfi_initialize(core->hfi_type, core->id,
+				&core->resources, &handle_cmd_response);
+	if (!core->device) {
+		dprintk(VIDC_ERR, "Failed to create HFI device\n");
+		goto err_cores_exceeded;
+	}
+	mutex_lock(&vidc_driver->lock);
+	if (vidc_driver->num_cores  + 1 > MSM_VIDC_CORES_MAX) {
+		mutex_unlock(&vidc_driver->lock);
+		dprintk(VIDC_ERR, "Maximum cores already exist, core_no = %d\n",
+				vidc_driver->num_cores);
+		goto err_cores_exceeded;
+	}
+
+	core->id = vidc_driver->num_cores++;
+	list_add_tail(&core->list, &vidc_driver->cores);
+	mutex_unlock(&vidc_driver->lock);
+	core->debugfs_root = msm_vidc_debugfs_init_core(
+		core, vidc_driver->debugfs_root);
+	pdev->dev.platform_data = core;
+	return rc;
+
+err_cores_exceeded:
+	video_unregister_device(&core->vdev[MSM_VIDC_ENCODER].vdev);
+err_enc_register:
+	video_unregister_device(&core->vdev[MSM_VIDC_DECODER].vdev);
+err_dec_register:
+	v4l2_device_unregister(&core->v4l2_dev);
+err_v4l2_register:
+	kfree(core);
+err_no_mem:
+	return rc;
+}
+
+static int __devexit msm_vidc_remove(struct platform_device *pdev)
+{
+	int rc = 0;
+	struct msm_vidc_core *core;
+
+	if (!pdev) {
+		dprintk(VIDC_ERR, "%s invalid input %p", __func__, pdev);
+		return -EINVAL;
+	}
+	core = pdev->dev.platform_data;
+
+	if (!core) {
+		dprintk(VIDC_ERR, "%s invalid core", __func__);
+		return -EINVAL;
+	}
+
+	vidc_hfi_deinitialize(core->hfi_type, core->device);
+	video_unregister_device(&core->vdev[MSM_VIDC_ENCODER].vdev);
+	video_unregister_device(&core->vdev[MSM_VIDC_DECODER].vdev);
+	v4l2_device_unregister(&core->v4l2_dev);
+
+	msm_vidc_free_freq_table(&core->resources);
+	msm_vidc_free_iommu_maps(&core->resources);
+	msm_vidc_free_reg_table(&core->resources);
+	msm_vidc_free_bus_vectors(&core->resources);
+	kfree(core);
+	return rc;
+}
+static const struct of_device_id msm_vidc_dt_match[] = {
+	{.compatible = "qcom,msm-vidc"},
+};
+
+MODULE_DEVICE_TABLE(of, msm_vidc_dt_match);
+
+static struct platform_driver msm_vidc_driver = {
+	.probe = msm_vidc_probe,
+	.remove = msm_vidc_remove,
+	.driver = {
+		.name = "msm_vidc_v4l2",
+		.owner = THIS_MODULE,
+		.of_match_table = msm_vidc_dt_match,
+	},
+};
+
+static int __init msm_vidc_init(void)
+{
+	int rc = 0;
+	vidc_driver = kzalloc(sizeof(*vidc_driver),
+						GFP_KERNEL);
+	if (!vidc_driver) {
+		dprintk(VIDC_ERR,
+			"Failed to allocate memroy for msm_vidc_drv\n");
+		return -ENOMEM;
+	}
+
+	INIT_LIST_HEAD(&vidc_driver->cores);
+	mutex_init(&vidc_driver->lock);
+	vidc_driver->debugfs_root = debugfs_create_dir("msm_vidc", NULL);
+	if (!vidc_driver->debugfs_root)
+		dprintk(VIDC_ERR,
+			"Failed to create debugfs for msm_vidc\n");
+
+	rc = platform_driver_register(&msm_vidc_driver);
+	if (rc) {
+		dprintk(VIDC_ERR,
+			"Failed to register platform driver\n");
+		kfree(vidc_driver);
+		vidc_driver = NULL;
+	}
+
+	return rc;
+}
+
+static void __exit msm_vidc_exit(void)
+{
+	platform_driver_unregister(&msm_vidc_driver);
+	debugfs_remove_recursive(vidc_driver->debugfs_root);
+	kfree(vidc_driver);
+	vidc_driver = NULL;
+}
+
+module_init(msm_vidc_init);
+module_exit(msm_vidc_exit);
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
new file mode 100644
index 0000000..ae98afb
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -0,0 +1,1411 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/slab.h>
+
+#include "msm_vidc_internal.h"
+#include "msm_vidc_common.h"
+#include "vidc_hfi_api.h"
+#include "msm_smem.h"
+#include "msm_vidc_debug.h"
+
+#define MSM_VDEC_DVC_NAME "msm_vdec_8974"
+#define DEFAULT_HEIGHT 720
+#define DEFAULT_WIDTH 1280
+#define MAX_SUPPORTED_WIDTH 3820
+#define MAX_SUPPORTED_HEIGHT 2160
+#define MIN_NUM_OUTPUT_BUFFERS 4
+#define MAX_NUM_OUTPUT_BUFFERS 6
+
+enum msm_vdec_ctrl_cluster {
+	MSM_VDEC_CTRL_CLUSTER_MAX = 1,
+};
+
+static const char *const mpeg_video_vidc_divx_format[] = {
+	"DIVX Format 3",
+	"DIVX Format 4",
+	"DIVX Format 5",
+	"DIVX Format 6",
+	NULL
+};
+static const char *mpeg_video_stream_format[] = {
+	"NAL Format Start Codes",
+	"NAL Format One NAL Per Buffer",
+	"NAL Format One Byte Length",
+	"NAL Format Two Byte Length",
+	"NAL Format Four Byte Length",
+	NULL
+};
+static const char *const mpeg_video_output_order[] = {
+	"Display Order",
+	"Decode Order",
+	NULL
+};
+static const char *const mpeg_video_vidc_extradata[] = {
+	"Extradata none",
+	"Extradata MB Quantization",
+	"Extradata Interlace Video",
+	"Extradata VC1 Framedisp",
+	"Extradata VC1 Seqdisp",
+	"Extradata timestamp",
+	"Extradata S3D Frame Packing",
+	"Extradata Frame Rate",
+	"Extradata Panscan Window",
+	"Extradata Recovery point SEI",
+	"Extradata Closed Caption UD",
+	"Extradata AFD UD",
+	"Extradata Multislice info",
+	"Extradata number of concealed MB",
+	"Extradata metadata filler",
+	"Extradata input crop",
+	"Extradata digital zoom",
+	"Extradata aspect ratio",
+};
+
+static struct msm_vidc_ctrl msm_vdec_ctrls[] = {
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT,
+		.name = "NAL Format",
+		.type = V4L2_CTRL_TYPE_MENU,
+		.minimum = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES,
+		.maximum = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH,
+		.default_value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES,
+		.menu_skip_mask = ~(
+		(1 << V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_ONE_NAL_PER_BUFFER) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_ONE_BYTE_LENGTH) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH)
+		),
+		.qmenu = mpeg_video_stream_format,
+		.step = 0,
+		.cluster = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER,
+		.name = "Output Order",
+		.type = V4L2_CTRL_TYPE_MENU,
+		.minimum = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY,
+		.maximum = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE,
+		.default_value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY,
+		.menu_skip_mask = ~(
+			(1 << V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY) |
+			(1 << V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE)
+			),
+		.qmenu = mpeg_video_output_order,
+		.step = 0,
+		.cluster = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_PICTURE_TYPE,
+		.name = "Picture Type Decoding",
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.minimum = 1,
+		.maximum = 15,
+		.default_value = 15,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+		.cluster = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO,
+		.name = "Keep Aspect Ratio",
+		.type = V4L2_CTRL_TYPE_BOOLEAN,
+		.minimum = 0,
+		.maximum = 1,
+		.default_value = 0,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+		.cluster = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_POST_LOOP_DEBLOCKER_MODE,
+		.name = "Deblocker Mode",
+		.type = V4L2_CTRL_TYPE_BOOLEAN,
+		.minimum = 0,
+		.maximum = 1,
+		.default_value = 0,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+		.cluster = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT,
+		.name = "Divx Format",
+		.type = V4L2_CTRL_TYPE_MENU,
+		.minimum = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4,
+		.maximum = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6,
+		.default_value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4,
+		.menu_skip_mask = ~(
+			(1 << V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4) |
+			(1 << V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5) |
+			(1 << V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6)
+			),
+		.qmenu = mpeg_video_vidc_divx_format,
+		.step = 0,
+		.cluster = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_MB_ERROR_MAP_REPORTING,
+		.name = "MB Error Map Reporting",
+		.type = V4L2_CTRL_TYPE_BOOLEAN,
+		.minimum = 0,
+		.maximum = 1,
+		.default_value = 0,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+		.cluster = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER,
+		.name = "control",
+		.type = V4L2_CTRL_TYPE_BOOLEAN,
+		.minimum = 0,
+		.maximum = 1,
+		.default_value = 0,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+		.cluster = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE,
+		.name = "Sync Frame Decode",
+		.type = V4L2_CTRL_TYPE_BOOLEAN,
+		.minimum = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_DISABLE,
+		.maximum = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE,
+		.default_value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_DISABLE,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE,
+		.name = "Secure mode",
+		.type = V4L2_CTRL_TYPE_BUTTON,
+		.minimum = 0,
+		.maximum = 0,
+		.default_value = 0,
+		.step = 0,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+		.cluster = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA,
+		.name = "Extradata Type",
+		.type = V4L2_CTRL_TYPE_MENU,
+		.minimum = V4L2_MPEG_VIDC_EXTRADATA_NONE,
+		.maximum = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO,
+		.default_value = V4L2_MPEG_VIDC_EXTRADATA_NONE,
+		.menu_skip_mask = ~(
+			(1 << V4L2_MPEG_VIDC_EXTRADATA_NONE) |
+			(1 << V4L2_MPEG_VIDC_EXTRADATA_MB_QUANTIZATION) |
+			(1 << V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO) |
+			(1 << V4L2_MPEG_VIDC_EXTRADATA_VC1_FRAMEDISP) |
+			(1 << V4L2_MPEG_VIDC_EXTRADATA_VC1_SEQDISP) |
+			(1 << V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP) |
+			(1 << V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING) |
+			(1 << V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE) |
+			(1 << V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW) |
+			(1 << V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI) |
+			(1 << V4L2_MPEG_VIDC_EXTRADATA_CLOSED_CAPTION_UD) |
+			(1 << V4L2_MPEG_VIDC_EXTRADATA_AFD_UD) |
+			(1 << V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO) |
+			(1 << V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB) |
+			(1 << V4L2_MPEG_VIDC_EXTRADATA_METADATA_FILLER) |
+			(1 << V4L2_MPEG_VIDC_INDEX_EXTRADATA_INPUT_CROP) |
+			(1 << V4L2_MPEG_VIDC_INDEX_EXTRADATA_DIGITAL_ZOOM) |
+			(1 << V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO)
+			),
+		.qmenu = mpeg_video_vidc_extradata,
+		.step = 0,
+	},
+};
+
+#define NUM_CTRLS ARRAY_SIZE(msm_vdec_ctrls)
+
+static u32 get_frame_size_nv12(int plane,
+					u32 height, u32 width)
+{
+	return VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
+}
+
+static u32 get_frame_size_compressed(int plane,
+					u32 height, u32 width)
+{
+	return (MAX_SUPPORTED_WIDTH * MAX_SUPPORTED_HEIGHT * 3/2)/2;
+}
+
+static const struct msm_vidc_format vdec_formats[] = {
+	{
+		.name = "YCbCr Semiplanar 4:2:0",
+		.description = "Y/CbCr 4:2:0",
+		.fourcc = V4L2_PIX_FMT_NV12,
+		.num_planes = 2,
+		.get_frame_size = get_frame_size_nv12,
+		.type = CAPTURE_PORT,
+	},
+	{
+		.name = "Mpeg4",
+		.description = "Mpeg4 compressed format",
+		.fourcc = V4L2_PIX_FMT_MPEG4,
+		.num_planes = 1,
+		.get_frame_size = get_frame_size_compressed,
+		.type = OUTPUT_PORT,
+	},
+	{
+		.name = "Mpeg2",
+		.description = "Mpeg2 compressed format",
+		.fourcc = V4L2_PIX_FMT_MPEG2,
+		.num_planes = 1,
+		.get_frame_size = get_frame_size_compressed,
+		.type = OUTPUT_PORT,
+	},
+	{
+		.name = "H263",
+		.description = "H263 compressed format",
+		.fourcc = V4L2_PIX_FMT_H263,
+		.num_planes = 1,
+		.get_frame_size = get_frame_size_compressed,
+		.type = OUTPUT_PORT,
+	},
+	{
+		.name = "VC1",
+		.description = "VC-1 compressed format",
+		.fourcc = V4L2_PIX_FMT_VC1_ANNEX_G,
+		.num_planes = 1,
+		.get_frame_size = get_frame_size_compressed,
+		.type = OUTPUT_PORT,
+	},
+	{
+		.name = "VC1 SP",
+		.description = "VC-1 compressed format G",
+		.fourcc = V4L2_PIX_FMT_VC1_ANNEX_L,
+		.num_planes = 1,
+		.get_frame_size = get_frame_size_compressed,
+		.type = OUTPUT_PORT,
+	},
+	{
+		.name = "H264",
+		.description = "H264 compressed format",
+		.fourcc = V4L2_PIX_FMT_H264,
+		.num_planes = 1,
+		.get_frame_size = get_frame_size_compressed,
+		.type = OUTPUT_PORT,
+	},
+	{
+		.name = "VP8",
+		.description = "VP8 compressed format",
+		.fourcc = V4L2_PIX_FMT_VP8,
+		.num_planes = 1,
+		.get_frame_size = get_frame_size_compressed,
+		.type = OUTPUT_PORT,
+	},
+	{
+		.name = "DIVX 311",
+		.description = "DIVX 311 compressed format",
+		.fourcc = V4L2_PIX_FMT_DIVX_311,
+		.num_planes = 1,
+		.get_frame_size = get_frame_size_compressed,
+		.type = OUTPUT_PORT,
+	},
+	{
+		.name = "DIVX",
+		.description = "DIVX 4/5/6 compressed format",
+		.fourcc = V4L2_PIX_FMT_DIVX,
+		.num_planes = 1,
+		.get_frame_size = get_frame_size_compressed,
+		.type = OUTPUT_PORT,
+	}
+};
+
+int msm_vdec_streamon(struct msm_vidc_inst *inst, enum v4l2_buf_type i)
+{
+	int rc = 0;
+	struct buf_queue *q;
+	q = msm_comm_get_vb2q(inst, i);
+	if (!q) {
+		dprintk(VIDC_ERR,
+			"Failed to find buffer queue for type = %d\n", i);
+		return -EINVAL;
+	}
+	dprintk(VIDC_DBG, "Calling streamon\n");
+	mutex_lock(&q->lock);
+	rc = vb2_streamon(&q->vb2_bufq, i);
+	mutex_unlock(&q->lock);
+	if (rc)
+		dprintk(VIDC_ERR, "streamon failed on port: %d\n", i);
+	return rc;
+}
+
+int msm_vdec_streamoff(struct msm_vidc_inst *inst, enum v4l2_buf_type i)
+{
+	int rc = 0;
+	struct buf_queue *q;
+
+	q = msm_comm_get_vb2q(inst, i);
+	if (!q) {
+		dprintk(VIDC_ERR,
+			"Failed to find buffer queue for type = %d\n", i);
+		return -EINVAL;
+	}
+	dprintk(VIDC_DBG, "Calling streamoff\n");
+	mutex_lock(&q->lock);
+	rc = vb2_streamoff(&q->vb2_bufq, i);
+	mutex_unlock(&q->lock);
+	if (rc)
+		dprintk(VIDC_ERR, "streamoff failed on port: %d\n", i);
+	return rc;
+}
+
+int msm_vdec_prepare_buf(struct msm_vidc_inst *inst,
+					struct v4l2_buffer *b)
+{
+	int rc = 0;
+	struct vidc_buffer_addr_info buffer_info;
+	int extra_idx = 0;
+	int i;
+	struct hfi_device *hdev;
+
+	if (!inst || !inst->core || !inst->core->device) {
+		dprintk(VIDC_ERR, "%s invalid parameters", __func__);
+		return -EINVAL;
+	}
+	hdev = inst->core->device;
+
+	switch (b->type) {
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		break;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+			if (b->length != inst->fmts[CAPTURE_PORT]->num_planes) {
+				dprintk(VIDC_ERR,
+				"Planes mismatch: needed: %d, allocated: %d\n",
+				inst->fmts[CAPTURE_PORT]->num_planes,
+				b->length);
+				rc = -EINVAL;
+				break;
+			}
+			for (i = 0; (i < b->length)
+				&& (i < VIDEO_MAX_PLANES); ++i) {
+				dprintk(VIDC_DBG,
+				"prepare plane: %d, device_addr = 0x%lx, size = %d\n",
+				i, b->m.planes[i].m.userptr,
+				b->m.planes[i].length);
+			}
+			buffer_info.buffer_size = b->m.planes[0].length;
+			buffer_info.buffer_type = HAL_BUFFER_OUTPUT;
+			buffer_info.num_buffers = 1;
+			buffer_info.align_device_addr =
+				b->m.planes[0].m.userptr;
+			extra_idx = EXTRADATA_IDX(b->length);
+			if (extra_idx && (extra_idx < VIDEO_MAX_PLANES) &&
+				b->m.planes[extra_idx].m.userptr) {
+				buffer_info.extradata_addr =
+					b->m.planes[extra_idx].m.userptr;
+				dprintk(VIDC_DBG,
+				"extradata: 0x%lx\n",
+				b->m.planes[extra_idx].m.userptr);
+				buffer_info.extradata_size =
+					b->m.planes[extra_idx].length;
+			} else {
+				buffer_info.extradata_addr = 0;
+				buffer_info.extradata_size = 0;
+			}
+			rc = call_hfi_op(hdev, session_set_buffers,
+					(void *)inst->session, &buffer_info);
+			if (rc)
+				dprintk(VIDC_ERR,
+				"vidc_hal_session_set_buffers failed");
+		break;
+	default:
+		dprintk(VIDC_ERR, "Buffer type not recognized: %d\n", b->type);
+		break;
+	}
+	return rc;
+}
+
+int msm_vdec_release_buf(struct msm_vidc_inst *inst,
+					struct v4l2_buffer *b)
+{
+	int rc = 0;
+	struct vidc_buffer_addr_info buffer_info;
+	struct msm_vidc_core *core = inst->core;
+	int extra_idx = 0;
+	int i;
+	struct hfi_device *hdev;
+
+	if (!inst || !inst->core || !inst->core->device) {
+		dprintk(VIDC_ERR, "%s invalid parameters", __func__);
+		return -EINVAL;
+	}
+
+	hdev = inst->core->device;
+
+	if (inst->state == MSM_VIDC_CORE_INVALID ||
+			core->state == VIDC_CORE_INVALID) {
+		dprintk(VIDC_ERR,
+			"Core %p in bad state, ignoring release output buf\n",
+				core);
+		goto exit;
+	}
+	if (!inst->in_reconfig) {
+		rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
+		if (rc) {
+			dprintk(VIDC_ERR,
+				"Failed to move inst: %p to relase res done\n",
+				inst);
+			goto exit;
+		}
+	}
+	switch (b->type) {
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		break;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+			if (b->length !=
+				inst->fmts[CAPTURE_PORT]->num_planes) {
+				dprintk(VIDC_ERR,
+				"Planes mismatch: needed: %d, to release: %d\n",
+				inst->fmts[CAPTURE_PORT]->num_planes,
+				b->length);
+				rc = -EINVAL;
+				break;
+			}
+			for (i = 0; i < b->length; ++i) {
+				dprintk(VIDC_DBG,
+				"Release plane: %d device_addr = 0x%lx, size = %d\n",
+				i, b->m.planes[i].m.userptr,
+				b->m.planes[i].length);
+			}
+			buffer_info.buffer_size = b->m.planes[0].length;
+			buffer_info.buffer_type = HAL_BUFFER_OUTPUT;
+			buffer_info.num_buffers = 1;
+			buffer_info.align_device_addr =
+				 b->m.planes[0].m.userptr;
+			extra_idx = EXTRADATA_IDX(b->length);
+			if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)
+				&& b->m.planes[extra_idx].m.userptr)
+				buffer_info.extradata_addr =
+					b->m.planes[extra_idx].m.userptr;
+			else
+				buffer_info.extradata_addr = 0;
+			buffer_info.response_required = false;
+			rc = call_hfi_op(hdev, session_release_buffers,
+				(void *)inst->session, &buffer_info);
+			if (rc)
+				dprintk(VIDC_ERR,
+				"vidc_hal_session_release_buffers failed");
+		break;
+	default:
+		dprintk(VIDC_ERR, "Buffer type not recognized: %d\n", b->type);
+		break;
+	}
+exit:
+	return rc;
+}
+
+int msm_vdec_qbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b)
+{
+	struct buf_queue *q = NULL;
+	int rc = 0;
+	q = msm_comm_get_vb2q(inst, b->type);
+	if (!q) {
+		dprintk(VIDC_ERR, "Failed to find buffer queue for type = %d\n"
+			, b->type);
+		return -EINVAL;
+	}
+	mutex_lock(&q->lock);
+	rc = vb2_qbuf(&q->vb2_bufq, b);
+	mutex_unlock(&q->lock);
+	if (rc)
+		dprintk(VIDC_ERR, "Failed to qbuf, %d\n", rc);
+	return rc;
+}
+int msm_vdec_dqbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b)
+{
+	struct buf_queue *q = NULL;
+	int rc = 0;
+	q = msm_comm_get_vb2q(inst, b->type);
+	if (!q) {
+		dprintk(VIDC_ERR, "Failed to find buffer queue for type = %d\n"
+			, b->type);
+		return -EINVAL;
+	}
+	mutex_lock(&q->lock);
+	rc = vb2_dqbuf(&q->vb2_bufq, b, true);
+	mutex_unlock(&q->lock);
+	if (rc)
+		dprintk(VIDC_DBG, "Failed to dqbuf, %d\n", rc);
+	return rc;
+}
+
+int msm_vdec_reqbufs(struct msm_vidc_inst *inst, struct v4l2_requestbuffers *b)
+{
+	struct buf_queue *q = NULL;
+	int rc = 0;
+	if (!inst || !b) {
+		dprintk(VIDC_ERR,
+			"Invalid input, inst = %p, buffer = %p\n", inst, b);
+		return -EINVAL;
+	}
+	q = msm_comm_get_vb2q(inst, b->type);
+	if (!q) {
+		dprintk(VIDC_ERR, "Failed to find buffer queue for type = %d\n"
+			, b->type);
+		return -EINVAL;
+	}
+
+	mutex_lock(&q->lock);
+	rc = vb2_reqbufs(&q->vb2_bufq, b);
+	mutex_unlock(&q->lock);
+	if (rc)
+		dprintk(VIDC_ERR, "Failed to get reqbufs, %d\n", rc);
+	return rc;
+}
+
+int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
+{
+	const struct msm_vidc_format *fmt = NULL;
+	struct hal_frame_size frame_sz;
+	struct hfi_device *hdev;
+	int stride, scanlines;
+	int extra_idx = 0;
+	int rc = 0;
+	int ret;
+	int i;
+	if (!inst || !f || !inst->core || !inst->core->device) {
+		dprintk(VIDC_ERR,
+			"Invalid input, inst = %p, format = %p\n", inst, f);
+		return -EINVAL;
+	}
+	hdev = inst->core->device;
+	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+		fmt = inst->fmts[CAPTURE_PORT];
+	else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+		fmt = inst->fmts[OUTPUT_PORT];
+
+	if (fmt) {
+		f->fmt.pix_mp.pixelformat = fmt->fourcc;
+		f->fmt.pix_mp.num_planes = fmt->num_planes;
+		if (inst->in_reconfig == true) {
+			inst->prop.height = inst->reconfig_height;
+			inst->prop.width = inst->reconfig_width;
+		}
+		f->fmt.pix_mp.height = inst->prop.height;
+		f->fmt.pix_mp.width = inst->prop.width;
+		stride = inst->prop.width;
+		scanlines = inst->prop.height;
+		frame_sz.buffer_type = HAL_BUFFER_OUTPUT;
+		frame_sz.width = inst->prop.width;
+		frame_sz.height = inst->prop.height;
+		dprintk(VIDC_DBG, "width = %d, height = %d\n",
+				frame_sz.width, frame_sz.height);
+		ret = msm_comm_try_set_prop(inst,
+			HAL_PARAM_FRAME_SIZE, &frame_sz);
+		ret = ret || msm_comm_try_get_bufreqs(inst);
+		if (ret || (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)) {
+			for (i = 0; i < fmt->num_planes; ++i) {
+				f->fmt.pix_mp.plane_fmt[i].sizeimage =
+					fmt->get_frame_size(i,
+						f->fmt.pix_mp.height,
+						f->fmt.pix_mp.width);
+				inst->bufq[OUTPUT_PORT].
+					vb2_bufq.plane_sizes[i] =
+					f->fmt.pix_mp.plane_fmt[i].sizeimage;
+			}
+		} else {
+			switch (fmt->fourcc) {
+			case V4L2_PIX_FMT_NV12:
+				call_hfi_op(hdev, get_stride_scanline,
+					COLOR_FMT_NV12,
+					inst->prop.width, inst->prop.height,
+					&stride, &scanlines);
+				break;
+			default:
+				dprintk(VIDC_WARN,
+					"Color format not recognized\n");
+			}
+			f->fmt.pix_mp.plane_fmt[0].sizeimage =
+			inst->buff_req.buffer[HAL_BUFFER_OUTPUT].buffer_size;
+			extra_idx = EXTRADATA_IDX(fmt->num_planes);
+			if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
+				f->fmt.pix_mp.plane_fmt[extra_idx].sizeimage =
+		inst->buff_req.buffer[HAL_BUFFER_EXTRADATA_OUTPUT].buffer_size;
+			}
+			for (i = 0; i < fmt->num_planes; ++i)
+				inst->bufq[CAPTURE_PORT].
+					vb2_bufq.plane_sizes[i] =
+					f->fmt.pix_mp.plane_fmt[i].sizeimage;
+		}
+		if (stride && scanlines) {
+			f->fmt.pix_mp.plane_fmt[0].bytesperline =
+				(__u16)stride;
+			f->fmt.pix_mp.plane_fmt[0].reserved[0] =
+				(__u16)scanlines;
+		} else {
+			f->fmt.pix_mp.plane_fmt[0].bytesperline =
+				(__u16)inst->prop.width;
+			f->fmt.pix_mp.plane_fmt[0].reserved[0] =
+				(__u16)inst->prop.height;
+		}
+	} else {
+		dprintk(VIDC_ERR,
+			"Buf type not recognized, type = %d\n",
+			f->type);
+		rc = -EINVAL;
+	}
+	return rc;
+}
+int msm_vdec_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a)
+{
+	u32 us_per_frame = 0;
+	int rc = 0;
+	if (a->parm.output.timeperframe.denominator) {
+		switch (a->type) {
+		case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+			us_per_frame = a->parm.output.timeperframe.numerator/
+				a->parm.output.timeperframe.denominator;
+			break;
+		case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+			us_per_frame = a->parm.capture.timeperframe.numerator/
+				a->parm.capture.timeperframe.denominator;
+			break;
+		default:
+			dprintk(VIDC_ERR,
+				"Scale clocks : Unknown buffer type\n");
+			break;
+		}
+	}
+	if (!us_per_frame) {
+		dprintk(VIDC_ERR,
+				"Failed to scale clocks : time between frames is 0\n");
+		rc = -EINVAL;
+		goto exit;
+	}
+	inst->prop.fps = (u8) (USEC_PER_SEC / us_per_frame);
+	if (inst->prop.fps) {
+		msm_comm_scale_clocks_and_bus(inst);
+	}
+exit:
+	return rc;
+}
+int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
+{
+	const struct msm_vidc_format *fmt = NULL;
+	struct hal_frame_size frame_sz;
+	int extra_idx = 0;
+	int rc = 0;
+	int ret = 0;
+	int i;
+	if (!inst || !f) {
+		dprintk(VIDC_ERR,
+			"Invalid input, inst = %p, format = %p\n", inst, f);
+		return -EINVAL;
+	}
+	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+		struct hal_frame_size frame_sz;
+
+		fmt = msm_comm_get_pixel_fmt_fourcc(vdec_formats,
+			ARRAY_SIZE(vdec_formats), f->fmt.pix_mp.pixelformat,
+			CAPTURE_PORT);
+		if (!fmt || (fmt && fmt->type != CAPTURE_PORT)) {
+			dprintk(VIDC_ERR,
+				"Format: %d not supported on CAPTURE port\n",
+				f->fmt.pix_mp.pixelformat);
+			rc = -EINVAL;
+			goto err_invalid_fmt;
+		}
+		inst->fmts[fmt->type] = fmt;
+		frame_sz.buffer_type = HAL_BUFFER_OUTPUT;
+		frame_sz.width = inst->prop.width;
+		frame_sz.height = inst->prop.height;
+		dprintk(VIDC_DBG, "width = %d, height = %d\n",
+				frame_sz.width, frame_sz.height);
+		ret = msm_comm_try_set_prop(inst,
+			HAL_PARAM_FRAME_SIZE, &frame_sz);
+		ret = ret || msm_comm_try_get_bufreqs(inst);
+		if (ret) {
+			for (i = 0; i < fmt->num_planes; ++i) {
+				f->fmt.pix_mp.plane_fmt[i].sizeimage =
+					fmt->get_frame_size(i,
+						f->fmt.pix_mp.height,
+						f->fmt.pix_mp.width);
+			}
+		} else {
+			f->fmt.pix_mp.plane_fmt[0].sizeimage =
+			inst->buff_req.buffer[HAL_BUFFER_OUTPUT].buffer_size;
+			extra_idx = EXTRADATA_IDX(fmt->num_planes);
+			if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
+				f->fmt.pix_mp.plane_fmt[1].sizeimage =
+		inst->buff_req.buffer[HAL_BUFFER_EXTRADATA_OUTPUT].buffer_size;
+			}
+		}
+		f->fmt.pix_mp.num_planes = fmt->num_planes;
+		for (i = 0; i < fmt->num_planes; ++i) {
+			inst->bufq[CAPTURE_PORT].vb2_bufq.plane_sizes[i] =
+				f->fmt.pix_mp.plane_fmt[i].sizeimage;
+		}
+	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+		inst->prop.width = f->fmt.pix_mp.width;
+		inst->prop.height = f->fmt.pix_mp.height;
+		fmt = msm_comm_get_pixel_fmt_fourcc(vdec_formats,
+				ARRAY_SIZE(vdec_formats),
+				f->fmt.pix_mp.pixelformat,
+				OUTPUT_PORT);
+		if (!fmt || fmt->type != OUTPUT_PORT) {
+			dprintk(VIDC_ERR,
+			"Format: %d not supported on OUTPUT port\n",
+			f->fmt.pix_mp.pixelformat);
+			rc = -EINVAL;
+			goto err_invalid_fmt;
+		}
+		inst->fmts[fmt->type] = fmt;
+		rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
+		if (rc) {
+			dprintk(VIDC_ERR, "Failed to open instance\n");
+			goto err_invalid_fmt;
+		}
+		frame_sz.buffer_type = HAL_BUFFER_INPUT;
+		frame_sz.width = inst->prop.width;
+		frame_sz.height = inst->prop.height;
+		msm_comm_try_set_prop(inst, HAL_PARAM_FRAME_SIZE, &frame_sz);
+		f->fmt.pix_mp.plane_fmt[0].sizeimage =
+			fmt->get_frame_size(0, f->fmt.pix_mp.height,
+					f->fmt.pix_mp.width);
+		f->fmt.pix_mp.num_planes = fmt->num_planes;
+		for (i = 0; i < fmt->num_planes; ++i) {
+			inst->bufq[OUTPUT_PORT].vb2_bufq.plane_sizes[i] =
+				f->fmt.pix_mp.plane_fmt[i].sizeimage;
+		}
+	}
+err_invalid_fmt:
+	return rc;
+}
+
+int msm_vdec_querycap(struct msm_vidc_inst *inst, struct v4l2_capability *cap)
+{
+	if (!inst || !cap) {
+		dprintk(VIDC_ERR,
+			"Invalid input, inst = %p, cap = %p\n", inst, cap);
+		return -EINVAL;
+	}
+	strlcpy(cap->driver, MSM_VIDC_DRV_NAME, sizeof(cap->driver));
+	strlcpy(cap->card, MSM_VDEC_DVC_NAME, sizeof(cap->card));
+	cap->bus_info[0] = 0;
+	cap->version = MSM_VIDC_VERSION;
+	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
+						V4L2_CAP_VIDEO_OUTPUT_MPLANE |
+						V4L2_CAP_STREAMING;
+	memset(cap->reserved, 0, sizeof(cap->reserved));
+	return 0;
+}
+
+int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f)
+{
+	const struct msm_vidc_format *fmt = NULL;
+	int rc = 0;
+	if (!inst || !f) {
+		dprintk(VIDC_ERR,
+			"Invalid input, inst = %p, f = %p\n", inst, f);
+		return -EINVAL;
+	}
+	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+		fmt = msm_comm_get_pixel_fmt_index(vdec_formats,
+			ARRAY_SIZE(vdec_formats), f->index, CAPTURE_PORT);
+	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+		fmt = msm_comm_get_pixel_fmt_index(vdec_formats,
+			ARRAY_SIZE(vdec_formats), f->index, OUTPUT_PORT);
+		f->flags = V4L2_FMT_FLAG_COMPRESSED;
+	}
+
+	memset(f->reserved, 0 , sizeof(f->reserved));
+	if (fmt) {
+		strlcpy(f->description, fmt->description,
+				sizeof(f->description));
+		f->pixelformat = fmt->fourcc;
+	} else {
+		dprintk(VIDC_INFO, "No more formats found\n");
+		rc = -EINVAL;
+	}
+	return rc;
+}
+
+static int msm_vdec_queue_setup(struct vb2_queue *q,
+				const struct v4l2_format *fmt,
+				unsigned int *num_buffers,
+				unsigned int *num_planes, unsigned int sizes[],
+				void *alloc_ctxs[])
+{
+	int i, rc = 0;
+	struct msm_vidc_inst *inst;
+	struct hal_buffer_requirements *bufreq;
+	int extra_idx = 0;
+	struct hfi_device *hdev;
+	if (!q || !num_buffers || !num_planes
+		|| !sizes || !q->drv_priv) {
+		dprintk(VIDC_ERR, "Invalid input, q = %p, %p, %p\n",
+			q, num_buffers, num_planes);
+		return -EINVAL;
+	}
+	inst = q->drv_priv;
+
+	if (!inst || !inst->core || !inst->core->device) {
+		dprintk(VIDC_ERR, "%s invalid parameters", __func__);
+		return -EINVAL;
+	}
+
+	hdev = inst->core->device;
+
+	switch (q->type) {
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		*num_planes = inst->fmts[OUTPUT_PORT]->num_planes;
+		if (*num_buffers < MIN_NUM_OUTPUT_BUFFERS ||
+				*num_buffers > MAX_NUM_OUTPUT_BUFFERS)
+			*num_buffers = MIN_NUM_OUTPUT_BUFFERS;
+		for (i = 0; i < *num_planes; i++) {
+			sizes[i] = inst->fmts[OUTPUT_PORT]->get_frame_size(
+					i, inst->prop.height, inst->prop.width);
+		}
+		break;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+		dprintk(VIDC_DBG, "Getting bufreqs on capture plane\n");
+		*num_planes = inst->fmts[CAPTURE_PORT]->num_planes;
+		rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
+		if (rc) {
+			dprintk(VIDC_ERR, "Failed to open instance\n");
+			break;
+		}
+		rc = msm_comm_try_get_bufreqs(inst);
+		if (rc) {
+			dprintk(VIDC_ERR,
+				"Failed to get buffer requirements: %d\n", rc);
+			break;
+		}
+		mutex_lock(&inst->lock);
+		if (*num_buffers && *num_buffers >
+			inst->buff_req.buffer[HAL_BUFFER_OUTPUT].
+				buffer_count_actual) {
+			struct hal_buffer_count_actual new_buf_count;
+			enum hal_property property_id =
+				HAL_PARAM_BUFFER_COUNT_ACTUAL;
+
+			new_buf_count.buffer_type = HAL_BUFFER_OUTPUT;
+			new_buf_count.buffer_count_actual = *num_buffers;
+			rc = call_hfi_op(hdev, session_set_property,
+				inst->session, property_id, &new_buf_count);
+
+		}
+		bufreq = &inst->buff_req.buffer[HAL_BUFFER_OUTPUT];
+		if (bufreq->buffer_count_actual > *num_buffers)
+			*num_buffers =  bufreq->buffer_count_actual;
+		else
+			bufreq->buffer_count_actual = *num_buffers ;
+		mutex_unlock(&inst->lock);
+		dprintk(VIDC_DBG, "count =  %d, size = %d, alignment = %d\n",
+				inst->buff_req.buffer[1].buffer_count_actual,
+				inst->buff_req.buffer[1].buffer_size,
+				inst->buff_req.buffer[1].buffer_alignment);
+		sizes[0] = inst->buff_req.buffer[HAL_BUFFER_OUTPUT].buffer_size;
+		extra_idx =
+			EXTRADATA_IDX(inst->fmts[CAPTURE_PORT]->num_planes);
+		if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
+			sizes[extra_idx] =
+		inst->buff_req.buffer[HAL_BUFFER_EXTRADATA_OUTPUT].buffer_size;
+		}
+		break;
+	default:
+		dprintk(VIDC_ERR, "Invalid q type = %d\n", q->type);
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
+static inline int start_streaming(struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	struct vb2_buf_entry *temp;
+	struct list_head *ptr, *next;
+	inst->in_reconfig = false;
+	rc = msm_comm_set_scratch_buffers(inst);
+	if (rc) {
+		dprintk(VIDC_ERR,
+			"Failed to set scratch buffers: %d\n", rc);
+		goto fail_start;
+	}
+	rc = msm_comm_set_persist_buffers(inst);
+	if (rc) {
+		dprintk(VIDC_ERR,
+			"Failed to set persist buffers: %d\n", rc);
+		goto fail_start;
+	}
+	msm_comm_scale_clocks_and_bus(inst);
+	rc = msm_comm_try_state(inst, MSM_VIDC_START_DONE);
+	if (rc) {
+		dprintk(VIDC_ERR,
+			"Failed to move inst: %p to start done state\n", inst);
+		goto fail_start;
+	}
+
+	mutex_lock(&inst->sync_lock);
+	if (!list_empty(&inst->pendingq)) {
+		list_for_each_safe(ptr, next, &inst->pendingq) {
+			temp = list_entry(ptr, struct vb2_buf_entry, list);
+			rc = msm_comm_qbuf(temp->vb);
+			if (rc) {
+				dprintk(VIDC_ERR,
+					"Failed to qbuf to hardware\n");
+				break;
+			}
+			list_del(&temp->list);
+			kfree(temp);
+		}
+	}
+	mutex_unlock(&inst->sync_lock);
+	return rc;
+fail_start:
+	return rc;
+}
+
+static inline int stop_streaming(struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
+	if (rc)
+		dprintk(VIDC_ERR,
+			"Failed to move inst: %p to start done state\n", inst);
+	return rc;
+}
+
+static int msm_vdec_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+	struct msm_vidc_inst *inst;
+	int rc = 0;
+	if (!q || !q->drv_priv) {
+		dprintk(VIDC_ERR, "Invalid input, q = %p\n", q);
+		return -EINVAL;
+	}
+	inst = q->drv_priv;
+	dprintk(VIDC_DBG,
+		"Streamon called on: %d capability\n", q->type);
+	switch (q->type) {
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		if (inst->bufq[CAPTURE_PORT].vb2_bufq.streaming)
+			rc = start_streaming(inst);
+		break;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+		if (inst->bufq[OUTPUT_PORT].vb2_bufq.streaming)
+			rc = start_streaming(inst);
+		break;
+	default:
+		dprintk(VIDC_ERR, "Q-type is not supported: %d\n", q->type);
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
+static int msm_vdec_stop_streaming(struct vb2_queue *q)
+{
+	struct msm_vidc_inst *inst;
+	int rc = 0;
+	if (!q || !q->drv_priv) {
+		dprintk(VIDC_ERR, "Invalid input, q = %p\n", q);
+		return -EINVAL;
+	}
+	inst = q->drv_priv;
+	dprintk(VIDC_DBG, "Streamoff called on: %d capability\n", q->type);
+	switch (q->type) {
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		if (!inst->bufq[CAPTURE_PORT].vb2_bufq.streaming)
+			rc = stop_streaming(inst);
+		break;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+		if (!inst->bufq[OUTPUT_PORT].vb2_bufq.streaming)
+			rc = stop_streaming(inst);
+		break;
+	default:
+		dprintk(VIDC_ERR,
+			"Q-type is not supported: %d\n", q->type);
+		rc = -EINVAL;
+		break;
+	}
+	msm_comm_scale_clocks_and_bus(inst);
+
+	if (rc)
+		dprintk(VIDC_ERR,
+			"Failed to move inst: %p, cap = %d to state: %d\n",
+			inst, q->type, MSM_VIDC_RELEASE_RESOURCES_DONE);
+	return rc;
+}
+
+static void msm_vdec_buf_queue(struct vb2_buffer *vb)
+{
+	int rc;
+	rc = msm_comm_qbuf(vb);
+	if (rc)
+		dprintk(VIDC_ERR, "Failed to queue buffer: %d\n", rc);
+}
+
+int msm_vdec_cmd(struct msm_vidc_inst *inst, struct v4l2_decoder_cmd *dec)
+{
+	int rc = 0;
+	struct v4l2_event dqevent = {0};
+	struct msm_vidc_core *core = inst->core;
+	switch (dec->cmd) {
+	case V4L2_DEC_QCOM_CMD_FLUSH:
+		rc = msm_comm_flush(inst, dec->flags);
+		break;
+	case V4L2_DEC_CMD_STOP:
+		rc = msm_comm_release_scratch_buffers(inst);
+		if (rc)
+			dprintk(VIDC_ERR,
+				"Failed to release scratch buffers: %d\n", rc);
+		rc = msm_comm_release_persist_buffers(inst);
+		if (rc)
+			pr_err("Failed to release persist buffers: %d\n", rc);
+		if (inst->state == MSM_VIDC_CORE_INVALID ||
+			core->state == VIDC_CORE_INVALID) {
+			dprintk(VIDC_ERR,
+				"Core %p in bad state, Sending CLOSE event\n",
+					core);
+			dqevent.type = V4L2_EVENT_MSM_VIDC_CLOSE_DONE;
+			v4l2_event_queue_fh(&inst->event_handler, &dqevent);
+			goto exit;
+		}
+		rc = msm_comm_try_state(inst, MSM_VIDC_CLOSE_DONE);
+		break;
+	default:
+		dprintk(VIDC_ERR, "Unknown Decoder Command\n");
+		rc = -ENOTSUPP;
+		goto exit;
+	}
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to exec decoder cmd %d\n", dec->cmd);
+		goto exit;
+	}
+exit:
+	return rc;
+}
+
+
+static const struct vb2_ops msm_vdec_vb2q_ops = {
+	.queue_setup = msm_vdec_queue_setup,
+	.start_streaming = msm_vdec_start_streaming,
+	.buf_queue = msm_vdec_buf_queue,
+	.stop_streaming = msm_vdec_stop_streaming,
+};
+
+const struct vb2_ops *msm_vdec_get_vb2q_ops(void)
+{
+	return &msm_vdec_vb2q_ops;
+}
+
+int msm_vdec_inst_init(struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	if (!inst) {
+		dprintk(VIDC_ERR, "Invalid input = %p\n", inst);
+		return -EINVAL;
+	}
+	inst->fmts[OUTPUT_PORT] = &vdec_formats[1];
+	inst->fmts[CAPTURE_PORT] = &vdec_formats[0];
+	inst->prop.height = DEFAULT_HEIGHT;
+	inst->prop.width = DEFAULT_WIDTH;
+	inst->prop.fps = 30;
+	inst->prop.prev_time_stamp = 0;
+	return rc;
+}
+
+static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
+{
+	int rc = 0;
+	struct v4l2_control control;
+	struct hal_nal_stream_format_supported stream_format;
+	struct hal_enable_picture enable_picture;
+	struct hal_enable hal_property;/*, prop;*/
+	u32 control_idx = 0;
+	enum hal_property property_id = 0;
+	u32 property_val = 0;
+	void *pdata;
+	struct hfi_device *hdev;
+
+	if (!inst || !inst->core || !inst->core->device) {
+		dprintk(VIDC_ERR, "%s invalid parameters", __func__);
+		return -EINVAL;
+	}
+	hdev = inst->core->device;
+
+	switch (ctrl->id) {
+	case V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT:
+		property_id =
+		HAL_PARAM_NAL_STREAM_FORMAT_SELECT;
+		stream_format.nal_stream_format_supported =
+		(0x00000001 << ctrl->val);
+		pdata = &stream_format;
+		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER:
+		property_id = HAL_PARAM_VDEC_OUTPUT_ORDER;
+		property_val = ctrl->val;
+		pdata = &property_val;
+		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_PICTURE_TYPE:
+		property_id =
+			HAL_PARAM_VDEC_PICTURE_TYPE_DECODE;
+		enable_picture.picture_type = ctrl->val;
+		pdata = &enable_picture;
+		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO:
+		property_id =
+			HAL_PARAM_VDEC_OUTPUT2_KEEP_ASPECT_RATIO;
+		hal_property.enable = ctrl->val;
+		pdata = &hal_property;
+		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_POST_LOOP_DEBLOCKER_MODE:
+		property_id =
+			HAL_CONFIG_VDEC_POST_LOOP_DEBLOCKER;
+		hal_property.enable = ctrl->val;
+		pdata = &hal_property;
+		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT:
+		property_id = HAL_PARAM_DIVX_FORMAT;
+		property_val = ctrl->val;
+		pdata = &property_val;
+		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_MB_ERROR_MAP_REPORTING:
+		property_id =
+			HAL_CONFIG_VDEC_MB_ERROR_MAP_REPORTING;
+		hal_property.enable = ctrl->val;
+		pdata = &hal_property;
+		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER:
+		property_id =
+			HAL_PARAM_VDEC_CONTINUE_DATA_TRANSFER;
+		hal_property.enable = ctrl->val;
+		pdata = &hal_property;
+		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE:
+		property_id =
+			HAL_PARAM_VDEC_SYNC_FRAME_DECODE;
+		hal_property.enable = ctrl->val;
+		pdata = &hal_property;
+		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_SECURE:
+		inst->mode = VIDC_SECURE;
+		dprintk(VIDC_DBG, "Setting secure mode to :%d\n", inst->mode);
+		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA:
+	{
+		struct hal_extradata_enable extra;
+		property_id = HAL_PARAM_INDEX_EXTRADATA;
+		extra.index = msm_comm_get_hal_extradata_index(ctrl->val);
+		extra.enable = 1;
+		pdata = &extra;
+		break;
+	}
+	default:
+		break;
+	}
+
+	if (property_id) {
+		dprintk(VIDC_DBG,
+			"Control: HAL property=%d,ctrl_id=%d,ctrl_value=%d\n",
+			property_id,
+			msm_vdec_ctrls[control_idx].id,
+			control.value);
+			rc = call_hfi_op(hdev, session_set_property, (void *)
+				inst->session, property_id, pdata);
+	}
+
+	return rc;
+}
+
+static int msm_vdec_op_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	int rc = 0, c = 0;
+	struct msm_vidc_inst *inst = container_of(ctrl->handler,
+				struct msm_vidc_inst, ctrl_handler);
+	rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
+	if (rc) {
+		dprintk(VIDC_ERR,
+			"Failed to move inst: %p to start done state\n", inst);
+		goto failed_open_done;
+	}
+
+	for (c = 0; c < ctrl->ncontrols; ++c) {
+		if (ctrl->cluster[c]->is_new) {
+			rc = try_set_ctrl(inst, ctrl->cluster[c]);
+			if (rc) {
+				dprintk(VIDC_ERR, "Failed setting %x",
+						ctrl->cluster[c]->id);
+				break;
+			}
+		}
+	}
+
+failed_open_done:
+	if (rc)
+		dprintk(VIDC_ERR, "Failed to set hal property for framesize\n");
+	return rc;
+}
+
+static int msm_vdec_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
+{
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops msm_vdec_ctrl_ops = {
+
+	.s_ctrl = msm_vdec_op_s_ctrl,
+	.g_volatile_ctrl = msm_vdec_op_g_volatile_ctrl,
+};
+
+const struct v4l2_ctrl_ops *msm_vdec_get_ctrl_ops(void)
+{
+	return &msm_vdec_ctrl_ops;
+}
+
+int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl)
+{
+	return v4l2_s_ctrl(NULL, &inst->ctrl_handler, ctrl);
+}
+int msm_vdec_g_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl)
+{
+	return v4l2_g_ctrl(&inst->ctrl_handler, ctrl);
+}
+
+static struct v4l2_ctrl **get_cluster(int type, int *size)
+{
+	int c = 0, sz = 0;
+	struct v4l2_ctrl **cluster = kmalloc(sizeof(struct v4l2_ctrl *) *
+			NUM_CTRLS, GFP_KERNEL);
+
+	if (type <= 0 || !size || !cluster)
+		return NULL;
+
+	for (c = 0; c < NUM_CTRLS; c++) {
+		if (msm_vdec_ctrls[c].cluster == type) {
+			cluster[sz] = msm_vdec_ctrls[c].priv;
+			++sz;
+		}
+	}
+
+	*size = sz;
+	return cluster;
+}
+
+int msm_vdec_ctrl_init(struct msm_vidc_inst *inst)
+{
+	int idx = 0;
+	struct v4l2_ctrl_config ctrl_cfg;
+	int ret_val = 0;
+
+	ret_val = v4l2_ctrl_handler_init(&inst->ctrl_handler, NUM_CTRLS);
+
+	if (ret_val) {
+		dprintk(VIDC_ERR, "CTRL ERR: Control handler init failed, %d\n",
+				inst->ctrl_handler.error);
+		return ret_val;
+	}
+
+	for (; idx < NUM_CTRLS; idx++) {
+		struct v4l2_ctrl *ctrl = NULL;
+		if (IS_PRIV_CTRL(msm_vdec_ctrls[idx].id)) {
+			/*add private control*/
+			ctrl_cfg.def = msm_vdec_ctrls[idx].default_value;
+			ctrl_cfg.flags = 0;
+			ctrl_cfg.id = msm_vdec_ctrls[idx].id;
+			/* ctrl_cfg.is_private =
+			 * msm_vdec_ctrls[idx].is_private;
+			 * ctrl_cfg.is_volatile =
+			 * msm_vdec_ctrls[idx].is_volatile;*/
+			ctrl_cfg.max = msm_vdec_ctrls[idx].maximum;
+			ctrl_cfg.min = msm_vdec_ctrls[idx].minimum;
+			ctrl_cfg.menu_skip_mask =
+				msm_vdec_ctrls[idx].menu_skip_mask;
+			ctrl_cfg.name = msm_vdec_ctrls[idx].name;
+			ctrl_cfg.ops = &msm_vdec_ctrl_ops;
+			ctrl_cfg.step = msm_vdec_ctrls[idx].step;
+			ctrl_cfg.type = msm_vdec_ctrls[idx].type;
+			ctrl_cfg.qmenu = msm_vdec_ctrls[idx].qmenu;
+
+			ctrl = v4l2_ctrl_new_custom(&inst->ctrl_handler,
+					&ctrl_cfg, NULL);
+		} else {
+			if (msm_vdec_ctrls[idx].type == V4L2_CTRL_TYPE_MENU) {
+				ctrl = v4l2_ctrl_new_std_menu(
+					&inst->ctrl_handler,
+					&msm_vdec_ctrl_ops,
+					msm_vdec_ctrls[idx].id,
+					msm_vdec_ctrls[idx].maximum,
+					msm_vdec_ctrls[idx].menu_skip_mask,
+					msm_vdec_ctrls[idx].default_value);
+			} else {
+				ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler,
+					&msm_vdec_ctrl_ops,
+					msm_vdec_ctrls[idx].id,
+					msm_vdec_ctrls[idx].minimum,
+					msm_vdec_ctrls[idx].maximum,
+					msm_vdec_ctrls[idx].step,
+					msm_vdec_ctrls[idx].default_value);
+			}
+		}
+
+
+		msm_vdec_ctrls[idx].priv = ctrl;
+	}
+	ret_val = inst->ctrl_handler.error;
+	if (ret_val)
+		dprintk(VIDC_ERR,
+			"Error adding ctrls to ctrl handle, %d\n",
+			inst->ctrl_handler.error);
+
+	/* Construct clusters */
+	for (idx = 1; idx < MSM_VDEC_CTRL_CLUSTER_MAX; ++idx) {
+		struct msm_vidc_ctrl_cluster *temp = NULL;
+		struct v4l2_ctrl **cluster = NULL;
+		int cluster_size = 0;
+
+		cluster = get_cluster(idx, &cluster_size);
+		if (!cluster || !cluster_size) {
+			dprintk(VIDC_WARN, "Failed to setup cluster of type %d",
+					idx);
+			continue;
+		}
+
+		v4l2_ctrl_cluster(cluster_size, cluster);
+
+		temp = kzalloc(sizeof(*temp), GFP_KERNEL);
+		if (!temp) {
+			ret_val = -ENOMEM;
+			break;
+		}
+
+		temp->cluster = cluster;
+		INIT_LIST_HEAD(&temp->list);
+		list_add_tail(&temp->list, &inst->ctrl_clusters);
+	}
+	return ret_val;
+}
+
+int msm_vdec_ctrl_deinit(struct msm_vidc_inst *inst)
+{
+	struct msm_vidc_ctrl_cluster *curr, *next;
+	list_for_each_entry_safe(curr, next, &inst->ctrl_clusters, list) {
+		kfree(curr->cluster);
+		kfree(curr);
+	}
+
+	return 0;
+}
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.h b/drivers/media/platform/msm/vidc/msm_vdec.h
new file mode 100644
index 0000000..c7f8427
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/msm_vdec.h
@@ -0,0 +1,39 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef _MSM_VDEC_H_
+#define _MSM_VDEC_H_
+
+#include <media/msm_vidc.h>
+#include "msm_vidc_internal.h"
+
+int msm_vdec_inst_init(struct msm_vidc_inst *inst);
+int msm_vdec_ctrl_init(struct msm_vidc_inst *inst);
+int msm_vdec_ctrl_deinit(struct msm_vidc_inst *inst);
+int msm_vdec_querycap(void *instance, struct v4l2_capability *cap);
+int msm_vdec_enum_fmt(void *instance, struct v4l2_fmtdesc *f);
+int msm_vdec_s_fmt(void *instance, struct v4l2_format *f);
+int msm_vdec_g_fmt(void *instance, struct v4l2_format *f);
+int msm_vdec_s_ctrl(void *instance, struct v4l2_control *a);
+int msm_vdec_g_ctrl(void *instance, struct v4l2_control *a);
+int msm_vdec_reqbufs(void *instance, struct v4l2_requestbuffers *b);
+int msm_vdec_prepare_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
+int msm_vdec_release_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
+int msm_vdec_qbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
+int msm_vdec_dqbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
+int msm_vdec_streamon(struct msm_vidc_inst *inst, enum v4l2_buf_type i);
+int msm_vdec_streamoff(struct msm_vidc_inst *inst, enum v4l2_buf_type i);
+int msm_vdec_cmd(struct msm_vidc_inst *inst, struct v4l2_decoder_cmd *dec);
+int msm_vdec_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a);
+struct vb2_ops *msm_vdec_get_vb2q_ops(void);
+
+#endif
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
new file mode 100644
index 0000000..cee48c7
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -0,0 +1,2115 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/slab.h>
+
+#include "msm_vidc_internal.h"
+#include "msm_vidc_common.h"
+#include "vidc_hfi_api.h"
+#include "msm_smem.h"
+#include "msm_vidc_debug.h"
+
+#define MSM_VENC_DVC_NAME "msm_venc_8974"
+#define DEFAULT_HEIGHT 720
+#define DEFAULT_WIDTH 1280
+#define MIN_NUM_OUTPUT_BUFFERS 4
+#define MAX_NUM_OUTPUT_BUFFERS 8
+#define MIN_BIT_RATE 64000
+#define MAX_BIT_RATE 160000000
+#define DEFAULT_BIT_RATE 64000
+#define BIT_RATE_STEP 100
+#define MIN_FRAME_RATE 65536
+#define MAX_FRAME_RATE 15728640
+#define DEFAULT_FRAME_RATE 1966080
+#define DEFAULT_IR_MBS 30
+#define MAX_SLICE_BYTE_SIZE 1024
+#define MIN_SLICE_BYTE_SIZE 1024
+#define MAX_SLICE_MB_SIZE 300
+#define I_FRAME_QP 26
+#define P_FRAME_QP 28
+#define B_FRAME_QP 30
+#define MAX_INTRA_REFRESH_MBS 300
+#define L_MODE V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY
+#define CODING V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY
+
+static const char *const mpeg_video_rate_control[] = {
+	"No Rate Control",
+	"VBR VFR",
+	"VBR CFR",
+	"CBR VFR",
+	"CBR CFR",
+	NULL
+};
+
+static const char *const mpeg_video_rotation[] = {
+	"No Rotation",
+	"90 Degree Rotation",
+	"180 Degree Rotation",
+	"270 Degree Rotation",
+	NULL
+};
+
+static const char *const h264_video_entropy_cabac_model[] = {
+	"Model 0",
+	"Model 1",
+	"Model 2",
+	NULL
+};
+
+static const char *const h263_level[] = {
+	"1.0",
+	"2.0",
+	"3.0",
+	"4.0",
+	"4.5",
+	"5.0",
+	"6.0",
+	"7.0",
+};
+
+static const char *const h263_profile[] = {
+	"Baseline",
+	"H320 Coding",
+	"Backward Compatible",
+	"ISWV2",
+	"ISWV3",
+	"High Compression",
+	"Internet",
+	"Interlace",
+	"High Latency",
+};
+
+enum msm_venc_ctrl_cluster {
+	MSM_VENC_CTRL_CLUSTER_QP = 1,
+	MSM_VENC_CTRL_CLUSTER_INTRA_PERIOD,
+	MSM_VENC_CTRL_CLUSTER_H264_PROFILE_LEVEL,
+	MSM_VENC_CTRL_CLUSTER_MPEG_PROFILE_LEVEL,
+	MSM_VENC_CTRL_CLUSTER_H263_PROFILE_LEVEL,
+	MSM_VENC_CTRL_CLUSTER_H264_ENTROPY,
+	MSM_VENC_CTRL_CLUSTER_SLICING,
+	MSM_VENC_CTRL_CLUSTER_INTRA_REFRESH,
+	MSM_VENC_CTRL_CLUSTER_BITRATE,
+	MSM_VENC_CTRL_CLUSTER_MAX,
+};
+
+static struct msm_vidc_ctrl msm_venc_ctrls[] = {
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE,
+		.name = "Frame Rate",
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.minimum = MIN_FRAME_RATE,
+		.maximum = MAX_FRAME_RATE,
+		.default_value = MIN_FRAME_RATE,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+		.cluster = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD,
+		.name = "IDR Period",
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.minimum = 1,
+		.maximum = 10*MAX_FRAME_RATE,
+		.default_value = DEFAULT_FRAME_RATE,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+		.cluster = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_H264_I_PERIOD,
+		.name = "Intra Period",
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.minimum = 1,
+		.maximum = 10*MAX_FRAME_RATE,
+		.default_value = DEFAULT_FRAME_RATE,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+		.cluster = MSM_VENC_CTRL_CLUSTER_INTRA_PERIOD,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES,
+		.name = "Intra Period for P frames",
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.minimum = 0,
+		.maximum = 10*DEFAULT_FRAME_RATE,
+		.default_value = 2*DEFAULT_FRAME_RATE-1,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+		.cluster = MSM_VENC_CTRL_CLUSTER_INTRA_PERIOD,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES,
+		.name = "Intra Period for B frames",
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.minimum = 0,
+		.maximum = 2,
+		.default_value = 0,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+		.cluster = MSM_VENC_CTRL_CLUSTER_INTRA_PERIOD,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME,
+		.name = "Request I Frame",
+		.type = V4L2_CTRL_TYPE_BUTTON,
+		.minimum = 0,
+		.maximum = 0,
+		.default_value = 0,
+		.step = 0,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+		.cluster = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL,
+		.name = "Video Framerate and Bitrate Control",
+		.type = V4L2_CTRL_TYPE_MENU,
+		.minimum = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF,
+		.maximum = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR,
+		.default_value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF,
+		.step = 0,
+		.menu_skip_mask = ~(
+		(1 << V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF) |
+		(1 << V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR) |
+		(1 << V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR) |
+		(1 << V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR) |
+		(1 << V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR)
+		),
+		.qmenu = mpeg_video_rate_control,
+		.cluster = MSM_VENC_CTRL_CLUSTER_BITRATE,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
+		.name = "Bitrate Control",
+		.type = V4L2_CTRL_TYPE_MENU,
+		.minimum = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+		.maximum = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
+		.default_value = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+		.step = 0,
+		.menu_skip_mask = ~(
+		(1 << V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) |
+		(1 << V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
+		),
+		.qmenu = NULL,
+		.cluster = MSM_VENC_CTRL_CLUSTER_BITRATE,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_BITRATE,
+		.name = "Bit Rate",
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.minimum = MIN_BIT_RATE,
+		.maximum = MAX_BIT_RATE,
+		.default_value = DEFAULT_BIT_RATE,
+		.step = BIT_RATE_STEP,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+		.cluster = MSM_VENC_CTRL_CLUSTER_BITRATE,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE,
+		.name = "Entropy Mode",
+		.type = V4L2_CTRL_TYPE_MENU,
+		.minimum = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,
+		.maximum = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,
+		.default_value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,
+		.step = 0,
+		.menu_skip_mask = ~(
+		(1 << V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC) |
+		(1 << V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC)
+		),
+		.cluster = MSM_VENC_CTRL_CLUSTER_H264_ENTROPY,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL,
+		.name = "CABAC Model",
+		.type = V4L2_CTRL_TYPE_MENU,
+		.minimum = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0,
+		.maximum = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_1,
+		.default_value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0,
+		.step = 0,
+		.menu_skip_mask = ~(
+		(1 << V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0) |
+		(1 << V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_1) |
+		(1 << V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_2)
+		),
+		.qmenu = h264_video_entropy_cabac_model,
+		.cluster = MSM_VENC_CTRL_CLUSTER_H264_ENTROPY,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE,
+		.name = "MPEG4 Profile",
+		.type = V4L2_CTRL_TYPE_MENU,
+		.minimum = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE,
+		.maximum = CODING,
+		.default_value = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.cluster = MSM_VENC_CTRL_CLUSTER_MPEG_PROFILE_LEVEL,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL,
+		.name = "MPEG4 Level",
+		.type = V4L2_CTRL_TYPE_MENU,
+		.minimum = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0,
+		.maximum = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5,
+		.default_value = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.cluster = MSM_VENC_CTRL_CLUSTER_MPEG_PROFILE_LEVEL,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE,
+		.name = "H264 Profile",
+		.type = V4L2_CTRL_TYPE_MENU,
+		.minimum = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
+		.maximum = V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH,
+		.default_value = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.cluster = MSM_VENC_CTRL_CLUSTER_H264_PROFILE_LEVEL,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL,
+		.name = "H264 Level",
+		.type = V4L2_CTRL_TYPE_MENU,
+		.minimum = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
+		.maximum = V4L2_MPEG_VIDEO_H264_LEVEL_5_1,
+		.default_value = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
+		.step = 0,
+		.menu_skip_mask = 0,
+		.cluster = MSM_VENC_CTRL_CLUSTER_H264_PROFILE_LEVEL,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE,
+		.name = "H263 Profile",
+		.type = V4L2_CTRL_TYPE_MENU,
+		.minimum = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE,
+		.maximum = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY,
+		.default_value = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE,
+		.menu_skip_mask = ~(
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY)
+		),
+		.qmenu = h263_profile,
+		.cluster = MSM_VENC_CTRL_CLUSTER_H263_PROFILE_LEVEL,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL,
+		.name = "H263 Level",
+		.type = V4L2_CTRL_TYPE_MENU,
+		.minimum = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0,
+		.maximum = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0,
+		.default_value = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0,
+		.menu_skip_mask = ~(
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0) |
+		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0)
+		),
+		.qmenu = h263_level,
+		.cluster = MSM_VENC_CTRL_CLUSTER_H263_PROFILE_LEVEL,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION,
+		.name = "Rotation",
+		.type = V4L2_CTRL_TYPE_MENU,
+		.minimum = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_NONE,
+		.maximum = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_270,
+		.default_value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_NONE,
+		.step = 0,
+		.menu_skip_mask = ~(
+		(1 << V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_NONE) |
+		(1 << V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_90) |
+		(1 << V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_180) |
+		(1 << V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_270)
+		),
+		.qmenu = mpeg_video_rotation,
+		.cluster = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP,
+		.name = "I Frame Quantization",
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.minimum = 1,
+		.maximum = 51,
+		.default_value = I_FRAME_QP,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+		.cluster = MSM_VENC_CTRL_CLUSTER_QP,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP,
+		.name = "P Frame Quantization",
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.minimum = 1,
+		.maximum = 51,
+		.default_value = P_FRAME_QP,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+		.cluster = MSM_VENC_CTRL_CLUSTER_QP,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP,
+		.name = "B Frame Quantization",
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.minimum = 1,
+		.maximum = 51,
+		.default_value = B_FRAME_QP,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+		.cluster = MSM_VENC_CTRL_CLUSTER_QP,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE,
+		.name = "Slice Mode",
+		.type = V4L2_CTRL_TYPE_MENU,
+		.minimum = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
+		.maximum = V4L2_MPEG_VIDEO_MULTI_SLICE_GOB,
+		.default_value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
+		.step = 1,
+		.menu_skip_mask = ~(
+		(1 << V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) |
+		(1 << V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) |
+		(1 << V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) |
+		(1 << V4L2_MPEG_VIDEO_MULTI_SLICE_GOB)
+		),
+		.cluster = MSM_VENC_CTRL_CLUSTER_SLICING,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES,
+		.name = "Slice Byte Size",
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.minimum = MIN_SLICE_BYTE_SIZE,
+		.maximum = MAX_SLICE_BYTE_SIZE,
+		.default_value = MIN_SLICE_BYTE_SIZE,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+		.cluster = MSM_VENC_CTRL_CLUSTER_SLICING,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB,
+		.name = "Slice MB Size",
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.minimum = 1,
+		.maximum = MAX_SLICE_MB_SIZE,
+		.default_value = 1,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+		.cluster = MSM_VENC_CTRL_CLUSTER_SLICING,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_GOB,
+		.name = "Slice GOB",
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.minimum = 1,
+		.maximum = MAX_SLICE_MB_SIZE,
+		.default_value = 1,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+		.cluster = MSM_VENC_CTRL_CLUSTER_SLICING,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE,
+		.name = "Intra Refresh Mode",
+		.type = V4L2_CTRL_TYPE_MENU,
+		.minimum = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_NONE,
+		.maximum = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM,
+		.default_value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_NONE,
+		.step = 0,
+		.menu_skip_mask = ~(
+		(1 << V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_NONE) |
+		(1 << V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC) |
+		(1 << V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_ADAPTIVE) |
+		(1 << V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC_ADAPTIVE) |
+		(1 << V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM)
+		),
+		.cluster = MSM_VENC_CTRL_CLUSTER_INTRA_REFRESH,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS,
+		.name = "Intra Refresh AIR MBS",
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.minimum = 0,
+		.maximum = MAX_INTRA_REFRESH_MBS,
+		.default_value = 0,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+		.cluster = MSM_VENC_CTRL_CLUSTER_INTRA_REFRESH,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF,
+		.name = "Intra Refresh AIR REF",
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.minimum = 0,
+		.maximum = MAX_INTRA_REFRESH_MBS,
+		.default_value = 0,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+		.cluster = MSM_VENC_CTRL_CLUSTER_INTRA_REFRESH,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS,
+		.name = "Intra Refresh CIR MBS",
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.minimum = 0,
+		.maximum = MAX_INTRA_REFRESH_MBS,
+		.default_value = 0,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+		.cluster = MSM_VENC_CTRL_CLUSTER_INTRA_REFRESH,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA,
+		.name = "H.264 Loop Filter Alpha Offset",
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.minimum = -6,
+		.maximum = 6,
+		.default_value = 0,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+		.cluster = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA,
+		.name = "H.264 Loop Filter Beta Offset",
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.minimum = -6,
+		.maximum = 6,
+		.default_value = 0,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+		.cluster = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE,
+		.name = "H.264 Loop Filter Mode",
+		.type = V4L2_CTRL_TYPE_MENU,
+		.minimum = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED,
+		.maximum = L_MODE,
+		.default_value = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED,
+		.step = 1,
+		.menu_skip_mask = ~(
+		(1 << V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED) |
+		(1 << V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED) |
+		(1 << L_MODE)
+		),
+		.cluster = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE,
+		.name = "Sequence Header Mode",
+		.type = V4L2_CTRL_TYPE_MENU,
+		.minimum = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE,
+		.maximum = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME,
+		.default_value =
+			V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME,
+		.step = 1,
+		.menu_skip_mask = ~(
+		(1 << V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) |
+		(1 << V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME)
+		),
+		.cluster = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE,
+		.name = "Secure mode",
+		.type = V4L2_CTRL_TYPE_BUTTON,
+		.minimum = 0,
+		.maximum = 0,
+		.default_value = 0,
+		.step = 0,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+		.cluster = 0,
+	},
+};
+
+#define NUM_CTRLS ARRAY_SIZE(msm_venc_ctrls)
+
+static u32 get_frame_size_nv12(int plane, u32 height, u32 width)
+{
+	return VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
+}
+
+static u32 get_frame_size_nv21(int plane, u32 height, u32 width)
+{
+	return height * width * 2;
+}
+
+static u32 get_frame_size_compressed(int plane, u32 height, u32 width)
+{
+	int sz = ((height + 31) & (~31)) * ((width + 31) & (~31)) * 3/2;
+	sz = (sz + 4095) & (~4095);
+	return sz;
+}
+
+static const struct msm_vidc_format venc_formats[] = {
+	{
+		.name = "YCbCr Semiplanar 4:2:0",
+		.description = "Y/CbCr 4:2:0",
+		.fourcc = V4L2_PIX_FMT_NV12,
+		.num_planes = 1,
+		.get_frame_size = get_frame_size_nv12,
+		.type = OUTPUT_PORT,
+	},
+	{
+		.name = "Mpeg4",
+		.description = "Mpeg4 compressed format",
+		.fourcc = V4L2_PIX_FMT_MPEG4,
+		.num_planes = 1,
+		.get_frame_size = get_frame_size_compressed,
+		.type = CAPTURE_PORT,
+	},
+	{
+		.name = "H263",
+		.description = "H263 compressed format",
+		.fourcc = V4L2_PIX_FMT_H263,
+		.num_planes = 1,
+		.get_frame_size = get_frame_size_compressed,
+		.type = CAPTURE_PORT,
+	},
+	{
+		.name = "H264",
+		.description = "H264 compressed format",
+		.fourcc = V4L2_PIX_FMT_H264,
+		.num_planes = 1,
+		.get_frame_size = get_frame_size_compressed,
+		.type = CAPTURE_PORT,
+	},
+	{
+		.name = "VP8",
+		.description = "VP8 compressed format",
+		.fourcc = V4L2_PIX_FMT_VP8,
+		.num_planes = 1,
+		.get_frame_size = get_frame_size_compressed,
+		.type = CAPTURE_PORT,
+	},
+	{
+		.name = "YCrCb Semiplanar 4:2:0",
+		.description = "Y/CrCb 4:2:0",
+		.fourcc = V4L2_PIX_FMT_NV21,
+		.num_planes = 1,
+		.get_frame_size = get_frame_size_nv21,
+		.type = OUTPUT_PORT,
+	},
+};
+
+static int msm_venc_queue_setup(struct vb2_queue *q,
+				const struct v4l2_format *fmt,
+				unsigned int *num_buffers,
+				unsigned int *num_planes, unsigned int sizes[],
+				void *alloc_ctxs[])
+{
+	int i, rc = 0;
+	struct msm_vidc_inst *inst;
+	struct hal_buffer_count_actual new_buf_count;
+	enum hal_property property_id;
+	struct hfi_device *hdev;
+	if (!q || !q->drv_priv) {
+		dprintk(VIDC_ERR, "Invalid input, q = %p\n", q);
+		return -EINVAL;
+	}
+	inst = q->drv_priv;
+
+	if (!inst || !inst->core || !inst->core->device) {
+		dprintk(VIDC_ERR, "%s invalid parameters", __func__);
+		return -EINVAL;
+	}
+	hdev = inst->core->device;
+
+	switch (q->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+		*num_planes = 1;
+		if (*num_buffers < MIN_NUM_OUTPUT_BUFFERS ||
+				*num_buffers > MAX_NUM_OUTPUT_BUFFERS)
+			*num_buffers = MIN_NUM_OUTPUT_BUFFERS;
+		for (i = 0; i < *num_planes; i++) {
+			sizes[i] = inst->fmts[CAPTURE_PORT]->get_frame_size(
+					i, inst->prop.height, inst->prop.width);
+		}
+		break;
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
+		if (rc) {
+			dprintk(VIDC_ERR, "Failed to open instance\n");
+			break;
+		}
+		rc = msm_comm_try_get_bufreqs(inst);
+		if (rc) {
+			dprintk(VIDC_ERR,
+				"Failed to get buffer requirements: %d\n", rc);
+			break;
+		}
+		*num_planes = 1;
+		mutex_lock(&inst->lock);
+		*num_buffers = inst->buff_req.buffer[0].buffer_count_actual =
+			max(*num_buffers, inst->buff_req.buffer[0].
+				buffer_count_actual);
+		mutex_unlock(&inst->lock);
+		property_id = HAL_PARAM_BUFFER_COUNT_ACTUAL;
+		new_buf_count.buffer_type = HAL_BUFFER_INPUT;
+		new_buf_count.buffer_count_actual = *num_buffers;
+		rc = call_hfi_op(hdev, session_set_property, inst->session,
+					property_id, &new_buf_count);
+		dprintk(VIDC_DBG, "size = %d, alignment = %d, count = %d\n",
+				inst->buff_req.buffer[0].buffer_size,
+				inst->buff_req.buffer[0].buffer_alignment,
+				inst->buff_req.buffer[0].buffer_count_actual);
+		for (i = 0; i < *num_planes; i++) {
+			sizes[i] = inst->fmts[OUTPUT_PORT]->get_frame_size(
+					i, inst->prop.height, inst->prop.width);
+		}
+		break;
+	default:
+		dprintk(VIDC_ERR, "Invalid q type = %d\n", q->type);
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
+static inline int start_streaming(struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	struct vb2_buf_entry *temp;
+	struct list_head *ptr, *next;
+
+	rc = msm_comm_try_get_bufreqs(inst);
+	if (rc) {
+		dprintk(VIDC_ERR,
+			"Failed to get Buffer Requirements : %d\n", rc);
+		goto fail_start;
+	}
+	rc = msm_comm_set_scratch_buffers(inst);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to set scratch buffers: %d\n", rc);
+		goto fail_start;
+	}
+	rc = msm_comm_set_persist_buffers(inst);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to set persist buffers: %d\n", rc);
+		goto fail_start;
+	}
+	msm_comm_scale_clocks_and_bus(inst);
+
+	rc = msm_comm_try_state(inst, MSM_VIDC_START_DONE);
+	if (rc) {
+		dprintk(VIDC_ERR,
+			"Failed to move inst: %p to start done state\n", inst);
+		goto fail_start;
+	}
+	mutex_lock(&inst->sync_lock);
+	if (!list_empty(&inst->pendingq)) {
+		list_for_each_safe(ptr, next, &inst->pendingq) {
+			temp = list_entry(ptr, struct vb2_buf_entry, list);
+			rc = msm_comm_qbuf(temp->vb);
+			if (rc) {
+				dprintk(VIDC_ERR,
+					"Failed to qbuf to hardware\n");
+				break;
+			}
+			list_del(&temp->list);
+			kfree(temp);
+		}
+	}
+	mutex_unlock(&inst->sync_lock);
+	return rc;
+fail_start:
+	return rc;
+}
+
+static int msm_venc_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+	struct msm_vidc_inst *inst;
+	int rc = 0;
+	if (!q || !q->drv_priv) {
+		dprintk(VIDC_ERR, "Invalid input, q = %p\n", q);
+		return -EINVAL;
+	}
+	inst = q->drv_priv;
+	dprintk(VIDC_DBG, "Streamon called on: %d capability\n", q->type);
+	switch (q->type) {
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		if (inst->bufq[CAPTURE_PORT].vb2_bufq.streaming)
+			rc = start_streaming(inst);
+		break;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+		if (inst->bufq[OUTPUT_PORT].vb2_bufq.streaming)
+			rc = start_streaming(inst);
+		break;
+	default:
+		dprintk(VIDC_ERR, "Q-type is not supported: %d\n", q->type);
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
+static int msm_venc_stop_streaming(struct vb2_queue *q)
+{
+	struct msm_vidc_inst *inst;
+	int rc = 0;
+	if (!q || !q->drv_priv) {
+		dprintk(VIDC_ERR, "Invalid input, q = %p\n", q);
+		return -EINVAL;
+	}
+	inst = q->drv_priv;
+	dprintk(VIDC_DBG, "Streamoff called on: %d capability\n", q->type);
+	switch (q->type) {
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		break;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+		rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
+		break;
+	default:
+		dprintk(VIDC_ERR, "Q-type is not supported: %d\n", q->type);
+		rc = -EINVAL;
+		break;
+	}
+	msm_comm_scale_clocks_and_bus(inst);
+
+	if (rc)
+		dprintk(VIDC_ERR,
+			"Failed to move inst: %p, cap = %d to state: %d\n",
+			inst, q->type, MSM_VIDC_CLOSE_DONE);
+	return rc;
+}
+
+static void msm_venc_buf_queue(struct vb2_buffer *vb)
+{
+	int rc;
+	rc = msm_comm_qbuf(vb);
+	if (rc)
+		dprintk(VIDC_ERR, "Failed to queue buffer: %d\n", rc);
+}
+
+static const struct vb2_ops msm_venc_vb2q_ops = {
+	.queue_setup = msm_venc_queue_setup,
+	.start_streaming = msm_venc_start_streaming,
+	.buf_queue = msm_venc_buf_queue,
+	.stop_streaming = msm_venc_stop_streaming,
+};
+
+const struct vb2_ops *msm_venc_get_vb2q_ops(void)
+{
+	return &msm_venc_vb2q_ops;
+}
+
+static struct v4l2_ctrl *get_ctrl_from_cluster(int id,
+		struct v4l2_ctrl **cluster, int ncontrols)
+{
+	int c;
+
+	for (c = 0; c < ncontrols; ++c)
+		if (cluster[c]->id == id)
+			return cluster[c];
+	return NULL;
+}
+
+/* Helper function to translate V4L2_* to HAL_* */
+static inline int venc_v4l2_to_hal(int id, int value)
+{
+	switch (id) {
+	/* MPEG4 */
+	case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
+		switch (value) {
+		case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0:
+			return HAL_MPEG4_LEVEL_0;
+		case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B:
+			return HAL_MPEG4_LEVEL_0b;
+		case V4L2_MPEG_VIDEO_MPEG4_LEVEL_1:
+			return HAL_MPEG4_LEVEL_1;
+		case V4L2_MPEG_VIDEO_MPEG4_LEVEL_2:
+			return HAL_MPEG4_LEVEL_2;
+		case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3:
+			return HAL_MPEG4_LEVEL_3;
+		case V4L2_MPEG_VIDEO_MPEG4_LEVEL_4:
+			return HAL_MPEG4_LEVEL_4;
+		case V4L2_MPEG_VIDEO_MPEG4_LEVEL_5:
+			return HAL_MPEG4_LEVEL_5;
+		default:
+			goto unknown_value;
+		}
+	case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
+		switch (value) {
+		case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
+			return HAL_MPEG4_PROFILE_SIMPLE;
+		case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
+			return HAL_MPEG4_PROFILE_ADVANCEDSIMPLE;
+		default:
+			goto unknown_value;
+		}
+	/* H264 */
+	case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
+		switch (value) {
+		case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
+			return HAL_H264_PROFILE_BASELINE;
+		case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
+			return HAL_H264_PROFILE_MAIN;
+		case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
+			return HAL_H264_PROFILE_EXTENDED;
+		case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
+			return HAL_H264_PROFILE_HIGH;
+		case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
+			return HAL_H264_PROFILE_HIGH10;
+		case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
+			return HAL_H264_PROFILE_HIGH422;
+		case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
+			return HAL_H264_PROFILE_HIGH444;
+		default:
+			goto unknown_value;
+		}
+	case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
+		switch (value) {
+		case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
+			return HAL_H264_LEVEL_1;
+		case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
+			return HAL_H264_LEVEL_1b;
+		case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
+			return HAL_H264_LEVEL_11;
+		case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
+			return HAL_H264_LEVEL_12;
+		case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
+			return HAL_H264_LEVEL_13;
+		case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
+			return HAL_H264_LEVEL_2;
+		case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
+			return HAL_H264_LEVEL_21;
+		case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
+			return HAL_H264_LEVEL_22;
+		case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
+			return HAL_H264_LEVEL_3;
+		case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
+			return HAL_H264_LEVEL_31;
+		case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
+			return HAL_H264_LEVEL_32;
+		case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
+			return HAL_H264_LEVEL_4;
+		case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
+			return HAL_H264_LEVEL_41;
+		case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
+			return HAL_H264_LEVEL_42;
+		case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
+			return HAL_H264_LEVEL_5;
+		case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
+			return HAL_H264_LEVEL_51;
+		default:
+			goto unknown_value;
+		}
+		/* H263 */
+	case V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE:
+		switch (value) {
+		case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE:
+			return HAL_H263_PROFILE_BASELINE;
+		case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING:
+			return HAL_H263_PROFILE_H320CODING;
+		case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE:
+			return HAL_H263_PROFILE_BACKWARDCOMPATIBLE;
+		case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2:
+			return HAL_H263_PROFILE_ISWV2;
+		case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3:
+			return HAL_H263_PROFILE_ISWV3;
+		case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION:
+			return HAL_H263_PROFILE_HIGHCOMPRESSION;
+		case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET:
+			return HAL_H263_PROFILE_INTERNET;
+		case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE:
+			return HAL_H263_PROFILE_INTERLACE;
+		case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY:
+			return HAL_H263_PROFILE_HIGHLATENCY;
+		default:
+			goto unknown_value;
+		}
+	case V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL:
+		switch (value) {
+		case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0:
+			return HAL_H263_LEVEL_10;
+		case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0:
+			return HAL_H263_LEVEL_20;
+		case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0:
+			return HAL_H263_LEVEL_30;
+		case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0:
+			return HAL_H263_LEVEL_40;
+		case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_5:
+			return HAL_H263_LEVEL_45;
+		case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0:
+			return HAL_H263_LEVEL_50;
+		case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0:
+			return HAL_H263_LEVEL_60;
+		case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0:
+			return HAL_H263_LEVEL_70;
+		default:
+			goto unknown_value;
+		}
+	}
+
+unknown_value:
+	dprintk(VIDC_WARN, "Unknown control (%x, %d)", id, value);
+	return -EINVAL;
+}
+
+static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
+{
+	int rc = 0;
+	struct hal_frame_rate frame_rate;
+	struct hal_request_iframe request_iframe;
+	struct hal_bitrate bitrate;
+	struct hal_profile_level profile_level;
+	struct hal_h264_entropy_control h264_entropy_control;
+	struct hal_quantization quantization;
+	struct hal_intra_period intra_period;
+	struct hal_idr_period idr_period;
+	struct hal_operations operations;
+	struct hal_intra_refresh intra_refresh;
+	struct hal_multi_slice_control multi_slice_control;
+	struct hal_h264_db_control h264_db_control;
+	struct hal_enable enable;
+	u32 property_id = 0, property_val = 0;
+	void *pdata;
+	struct v4l2_ctrl *temp_ctrl = NULL;
+	struct hfi_device *hdev;
+
+	if (!inst || !inst->core || !inst->core->device) {
+		dprintk(VIDC_ERR, "%s invalid parameters", __func__);
+		return -EINVAL;
+	}
+	hdev = inst->core->device;
+
+	/* Small helper macro for quickly getting a control and err checking */
+#define TRY_GET_CTRL(__ctrl_id) ({ \
+		struct v4l2_ctrl *__temp; \
+		__temp = get_ctrl_from_cluster( \
+			__ctrl_id, \
+			ctrl->cluster, ctrl->ncontrols); \
+		if (!__temp) { \
+			dprintk(VIDC_ERR, "Can't find %s (%x) in cluster", \
+				#__ctrl_id, __ctrl_id); \
+			rc = -ENOENT; \
+			break; \
+		} \
+		__temp; \
+	})
+
+	switch (ctrl->id) {
+	case V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE:
+		property_id =
+			HAL_CONFIG_FRAME_RATE;
+		frame_rate.frame_rate = ctrl->val;
+		frame_rate.buffer_type = HAL_BUFFER_OUTPUT;
+		pdata = &frame_rate;
+		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD:
+		property_id =
+			HAL_CONFIG_VENC_IDR_PERIOD;
+		idr_period.idr_period = ctrl->val;
+		pdata = &idr_period;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD: {
+		struct v4l2_ctrl *b;
+		b = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES);
+
+		if (inst->fmts[CAPTURE_PORT]->fourcc != V4L2_PIX_FMT_H264 &&
+			inst->fmts[CAPTURE_PORT]->fourcc !=
+				V4L2_PIX_FMT_H264_NO_SC) {
+			dprintk(VIDC_ERR, "Control 0x%x only valid for H264",
+					ctrl->id);
+			rc = -ENOTSUPP;
+			break;
+		}
+
+		/*
+		 * We can't set the I-period explicitly. So set it implicitly
+		 * by setting the number of P and B frames per I-period
+		 */
+		property_id = HAL_CONFIG_VENC_INTRA_PERIOD;
+		intra_period.pframes = (ctrl->val - 1) - b->val;
+		intra_period.bframes = b->val;
+		pdata = &intra_period;
+		break;
+	}
+	case V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES:
+		temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES);
+
+		property_id =
+			HAL_CONFIG_VENC_INTRA_PERIOD;
+		intra_period.pframes = ctrl->val;
+		intra_period.bframes = temp_ctrl->val;
+		pdata = &intra_period;
+		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES:
+		temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES);
+
+		property_id =
+			HAL_CONFIG_VENC_INTRA_PERIOD;
+		intra_period.bframes = ctrl->val;
+		intra_period.pframes = temp_ctrl->val;
+		pdata = &intra_period;
+		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME:
+		property_id =
+			HAL_CONFIG_VENC_REQUEST_IFRAME;
+		request_iframe.enable = true;
+		pdata = &request_iframe;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+	{
+		bool cfr = true, cbr = true;
+		int final_mode = 0;
+
+		temp_ctrl = TRY_GET_CTRL(
+			V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL);
+
+		switch (temp_ctrl->val) {
+		case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF:
+			/* Let's assume CFR */
+		case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR:
+		case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR:
+			cfr = true;
+			break;
+		case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR:
+		case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR:
+			cfr = false;
+			break;
+		default:
+			dprintk(VIDC_WARN, "Unknown framerate mode");
+		}
+
+		switch (ctrl->val) {
+		case V4L2_MPEG_VIDEO_BITRATE_MODE_VBR:
+			cbr = false;
+			break;
+		case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR:
+			cbr = true;
+			break;
+		default:
+			dprintk(VIDC_WARN, "Unknown bitrate mode");
+		}
+
+		if (!cfr && !cbr)
+			final_mode =
+				V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR;
+		else if (!cfr && cbr)
+			final_mode =
+				V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR;
+		else if (cfr && !cbr)
+			final_mode =
+				V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR;
+		else /* ... if (cfr && cbr) */
+			final_mode =
+				V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR;
+
+		property_id = HAL_PARAM_VENC_RATE_CONTROL;
+		property_val = final_mode;
+		pdata = &property_val;
+		break;
+	}
+	case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL:
+		property_id = HAL_PARAM_VENC_RATE_CONTROL;
+		property_val = ctrl->val;
+		pdata = &property_val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE:
+		property_id =
+			HAL_CONFIG_VENC_TARGET_BITRATE;
+		bitrate.bit_rate = ctrl->val;
+		bitrate.layer_id = 0;
+		pdata = &bitrate;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
+		temp_ctrl = TRY_GET_CTRL(
+			V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL);
+
+		property_id =
+			HAL_PARAM_VENC_H264_ENTROPY_CONTROL;
+		h264_entropy_control.entropy_mode = ctrl->val;
+		h264_entropy_control.cabac_model = temp_ctrl->val;
+		pdata = &h264_entropy_control;
+		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL:
+		temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE);
+
+		property_id =
+			HAL_PARAM_VENC_H264_ENTROPY_CONTROL;
+		h264_entropy_control.cabac_model = ctrl->val;
+		h264_entropy_control.entropy_mode = temp_ctrl->val;
+		pdata = &h264_entropy_control;
+		break;
+	case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
+		temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL);
+
+		property_id =
+			HAL_PARAM_PROFILE_LEVEL_CURRENT;
+		profile_level.profile =  venc_v4l2_to_hal(ctrl->id,
+						ctrl->val);
+		profile_level.level = venc_v4l2_to_hal(
+				V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL,
+				temp_ctrl->val);
+		pdata = &profile_level;
+		break;
+	case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
+		temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE);
+
+		property_id =
+			HAL_PARAM_PROFILE_LEVEL_CURRENT;
+		profile_level.level = venc_v4l2_to_hal(ctrl->id,
+							ctrl->val);
+		profile_level.profile = venc_v4l2_to_hal(
+				V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE,
+				temp_ctrl->val);
+		pdata = &profile_level;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
+		temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_LEVEL);
+
+		property_id =
+			HAL_PARAM_PROFILE_LEVEL_CURRENT;
+		profile_level.profile = venc_v4l2_to_hal(ctrl->id,
+							ctrl->val);
+		profile_level.level = venc_v4l2_to_hal(
+				V4L2_CID_MPEG_VIDEO_H264_LEVEL,
+				temp_ctrl->val);
+		pdata = &profile_level;
+		dprintk(VIDC_DBG, "\nprofile: %d\n",
+			   profile_level.profile);
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
+		temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_PROFILE);
+
+		property_id =
+			HAL_PARAM_PROFILE_LEVEL_CURRENT;
+		profile_level.level = venc_v4l2_to_hal(ctrl->id,
+							ctrl->val);
+		profile_level.profile = venc_v4l2_to_hal(
+				V4L2_CID_MPEG_VIDEO_H264_PROFILE,
+				temp_ctrl->val);
+		pdata = &profile_level;
+		dprintk(VIDC_DBG, "\nLevel: %d\n",
+			   profile_level.level);
+		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE:
+		temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL);
+
+		property_id =
+			HAL_PARAM_PROFILE_LEVEL_CURRENT;
+		profile_level.profile = venc_v4l2_to_hal(ctrl->id,
+							ctrl->val);
+		profile_level.level = venc_v4l2_to_hal(
+				V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL,
+				temp_ctrl->val);
+		pdata = &profile_level;
+		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL:
+		temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE);
+
+		property_id =
+			HAL_PARAM_PROFILE_LEVEL_CURRENT;
+		profile_level.level = venc_v4l2_to_hal(ctrl->id,
+							ctrl->val);
+		profile_level.profile = venc_v4l2_to_hal(
+				V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE,
+				ctrl->val);
+		pdata = &profile_level;
+		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_ROTATION:
+		property_id =
+			HAL_CONFIG_VPE_OPERATIONS;
+		operations.rotate = ctrl->val;
+		pdata = &operations;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: {
+		struct v4l2_ctrl *qpp, *qpb;
+
+		qpp = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP);
+		qpb = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP);
+
+		property_id =
+			HAL_PARAM_VENC_SESSION_QP;
+		quantization.qpi = ctrl->val;
+		quantization.qpp = qpp->val;
+		quantization.qpb = qpb->val;
+		quantization.layer_id = 0;
+
+		pdata = &quantization;
+		break;
+	}
+	case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP: {
+		struct v4l2_ctrl *qpi, *qpb;
+
+		qpi = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP);
+		qpb = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP);
+
+		property_id =
+			HAL_PARAM_VENC_SESSION_QP;
+		quantization.qpp = ctrl->val;
+		quantization.qpi = qpi->val;
+		quantization.qpb = qpb->val;
+		quantization.layer_id = 0;
+
+		pdata = &quantization;
+		break;
+	}
+	case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP: {
+		struct v4l2_ctrl *qpi, *qpp;
+
+		qpi = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP);
+		qpp = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP);
+
+		property_id =
+			HAL_PARAM_VENC_SESSION_QP;
+		quantization.qpb = ctrl->val;
+		quantization.qpi = qpi->val;
+		quantization.qpp = qpp->val;
+		quantization.layer_id = 0;
+
+		pdata = &quantization;
+		break;
+	}
+	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: {
+		int temp = 0;
+
+		switch (ctrl->val) {
+		case V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB:
+			temp = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
+			break;
+		case V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES:
+			temp = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
+			break;
+		case V4L2_MPEG_VIDEO_MULTI_SLICE_GOB:
+			temp = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_GOB;
+			break;
+		case V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE:
+		default:
+			temp = 0;
+			break;
+		}
+
+		if (temp)
+			temp_ctrl = TRY_GET_CTRL(temp);
+
+		property_id =
+			HAL_PARAM_VENC_MULTI_SLICE_CONTROL;
+		multi_slice_control.multi_slice = ctrl->val;
+		multi_slice_control.slice_size = temp ? temp_ctrl->val : 0;
+
+		pdata = &multi_slice_control;
+		break;
+	}
+	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
+	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
+	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_GOB:
+		temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE);
+
+		property_id =
+			HAL_PARAM_VENC_MULTI_SLICE_CONTROL;
+		multi_slice_control.multi_slice = temp_ctrl->val;
+		multi_slice_control.slice_size = ctrl->val;
+		pdata = &multi_slice_control;
+		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE: {
+		struct v4l2_ctrl *air_mbs, *air_ref, *cir_mbs;
+		air_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS);
+		air_ref = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF);
+		cir_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS);
+
+		property_id =
+			HAL_PARAM_VENC_INTRA_REFRESH;
+
+		intra_refresh.mode = ctrl->val;
+		intra_refresh.air_mbs = air_mbs->val;
+		intra_refresh.air_ref = air_ref->val;
+		intra_refresh.cir_mbs = cir_mbs->val;
+
+		pdata = &intra_refresh;
+		break;
+	}
+	case V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS: {
+		struct v4l2_ctrl *ir_mode, *air_ref, *cir_mbs;
+		ir_mode = TRY_GET_CTRL(
+				V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE);
+		air_ref = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF);
+		cir_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS);
+
+		property_id =
+			HAL_PARAM_VENC_INTRA_REFRESH;
+		intra_refresh.air_mbs = ctrl->val;
+		intra_refresh.mode = ir_mode->val;
+		intra_refresh.air_ref = air_ref->val;
+		intra_refresh.cir_mbs = cir_mbs->val;
+
+		pdata = &intra_refresh;
+		break;
+	}
+	case V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF: {
+		struct v4l2_ctrl *ir_mode, *air_mbs, *cir_mbs;
+		ir_mode = TRY_GET_CTRL(
+				V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE);
+		air_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS);
+		cir_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS);
+
+		property_id =
+			HAL_PARAM_VENC_INTRA_REFRESH;
+		intra_refresh.air_ref = ctrl->val;
+		intra_refresh.air_mbs = air_mbs->val;
+		intra_refresh.mode = ir_mode->val;
+		intra_refresh.cir_mbs = cir_mbs->val;
+
+		pdata = &intra_refresh;
+		break;
+	}
+	case V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS: {
+		struct v4l2_ctrl *ir_mode, *air_mbs, *air_ref;
+
+		ir_mode = TRY_GET_CTRL(
+				V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE);
+		air_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS);
+		air_ref = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF);
+
+		property_id =
+			HAL_PARAM_VENC_INTRA_REFRESH;
+
+		intra_refresh.cir_mbs = ctrl->val;
+		intra_refresh.air_mbs = air_mbs->val;
+		intra_refresh.air_ref = air_ref->val;
+		intra_refresh.mode = ir_mode->val;
+
+		pdata = &intra_refresh;
+		break;
+	}
+	case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:
+		property_id =
+			HAL_PARAM_VENC_H264_DEBLOCK_CONTROL;
+		h264_db_control.mode = ctrl->val;
+		pdata = &h264_db_control;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA:
+		property_id =
+			HAL_PARAM_VENC_H264_DEBLOCK_CONTROL;
+		h264_db_control.slice_alpha_offset = ctrl->val;
+		pdata = &h264_db_control;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA:
+		property_id =
+			HAL_PARAM_VENC_H264_DEBLOCK_CONTROL;
+		h264_db_control.slice_beta_offset = ctrl->val;
+		pdata = &h264_db_control;
+		break;
+	case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
+		property_id =
+			HAL_PARAM_VENC_SYNC_FRAME_SEQUENCE_HEADER;
+
+		switch (ctrl->val) {
+		case V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE:
+			enable.enable = 0;
+			break;
+		case V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME:
+			enable.enable = 1;
+			break;
+		case V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME:
+		default:
+			rc = -ENOTSUPP;
+			break;
+		}
+		pdata = &enable;
+		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_SECURE:
+		inst->mode = VIDC_SECURE;
+		dprintk(VIDC_INFO, "Setting secure mode to :%d\n", inst->mode);
+		break;
+	default:
+		rc = -ENOTSUPP;
+		break;
+	}
+#undef TRY_GET_CTRL
+
+	if (property_id) {
+		dprintk(VIDC_DBG, "Control: HAL property=%d,ctrl_value=%d\n",
+				property_id,
+				ctrl->val);
+		rc = call_hfi_op(hdev, session_set_property,
+				(void *)inst->session, property_id, pdata);
+	}
+
+	return rc;
+}
+
+static int msm_venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+
+	int rc = 0, c = 0;
+	struct msm_vidc_inst *inst = container_of(ctrl->handler,
+					struct msm_vidc_inst, ctrl_handler);
+	rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
+
+	if (rc) {
+		dprintk(VIDC_ERR,
+			"Failed to move inst: %p to start done state\n", inst);
+		goto failed_open_done;
+	}
+
+	for (c = 0; c < ctrl->ncontrols; ++c) {
+		if (ctrl->cluster[c]->is_new) {
+			rc = try_set_ctrl(inst, ctrl->cluster[c]);
+			if (rc) {
+				dprintk(VIDC_ERR, "Failed setting %x",
+						ctrl->cluster[c]->id);
+				break;
+			}
+		}
+	}
+failed_open_done:
+	if (rc)
+		dprintk(VIDC_ERR, "Failed to set hal property\n");
+	return rc;
+}
+
+static int msm_venc_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
+{
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops msm_venc_ctrl_ops = {
+
+	.s_ctrl = msm_venc_op_s_ctrl,
+	.g_volatile_ctrl = msm_venc_op_g_volatile_ctrl,
+};
+
+const struct v4l2_ctrl_ops *msm_venc_get_ctrl_ops(void)
+{
+	return &msm_venc_ctrl_ops;
+}
+
+int msm_venc_inst_init(struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	if (!inst) {
+		dprintk(VIDC_ERR, "Invalid input = %p\n", inst);
+		return -EINVAL;
+	}
+	inst->fmts[CAPTURE_PORT] = &venc_formats[1];
+	inst->fmts[OUTPUT_PORT] = &venc_formats[0];
+	inst->prop.height = DEFAULT_HEIGHT;
+	inst->prop.width = DEFAULT_WIDTH;
+	inst->prop.fps = 30;
+	return rc;
+}
+
+int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl)
+{
+	return v4l2_s_ctrl(NULL, &inst->ctrl_handler, ctrl);
+}
+int msm_venc_g_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl)
+{
+	return v4l2_g_ctrl(&inst->ctrl_handler, ctrl);
+}
+
+int msm_venc_cmd(struct msm_vidc_inst *inst, struct v4l2_encoder_cmd *enc)
+{
+	int rc = 0;
+	struct v4l2_event dqevent = {0};
+	struct msm_vidc_core *core;
+	core = inst->core;
+	switch (enc->cmd) {
+	case V4L2_ENC_QCOM_CMD_FLUSH:
+		rc = msm_comm_flush(inst, enc->flags);
+		break;
+	case V4L2_ENC_CMD_STOP:
+		if (inst->state == MSM_VIDC_CORE_INVALID ||
+			core->state == VIDC_CORE_INVALID) {
+			dqevent.type = V4L2_EVENT_MSM_VIDC_CLOSE_DONE;
+			v4l2_event_queue_fh(&inst->event_handler, &dqevent);
+			return rc;
+		}
+		rc = msm_comm_release_scratch_buffers(inst);
+		if (rc)
+			dprintk(VIDC_ERR, "Failed to release scratch buf:%d\n",
+				rc);
+		rc = msm_comm_release_persist_buffers(inst);
+		if (rc)
+			dprintk(VIDC_ERR, "Failed to release persist buf:%d\n",
+				rc);
+		rc = msm_comm_try_state(inst, MSM_VIDC_CLOSE_DONE);
+		break;
+	}
+	if (rc)
+		dprintk(VIDC_ERR,
+			"Command: %d failed with rc = %d\n", enc->cmd, rc);
+	return rc;
+}
+
+int msm_venc_querycap(struct msm_vidc_inst *inst, struct v4l2_capability *cap)
+{
+	if (!inst || !cap) {
+		dprintk(VIDC_ERR,
+			"Invalid input, inst = %p, cap = %p\n", inst, cap);
+		return -EINVAL;
+	}
+	strlcpy(cap->driver, MSM_VIDC_DRV_NAME, sizeof(cap->driver));
+	strlcpy(cap->card, MSM_VENC_DVC_NAME, sizeof(cap->card));
+	cap->bus_info[0] = 0;
+	cap->version = MSM_VIDC_VERSION;
+	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
+						V4L2_CAP_VIDEO_OUTPUT_MPLANE |
+						V4L2_CAP_STREAMING;
+	memset(cap->reserved, 0, sizeof(cap->reserved));
+	return 0;
+}
+
+int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f)
+{
+	const struct msm_vidc_format *fmt = NULL;
+	int rc = 0;
+	if (!inst || !f) {
+		dprintk(VIDC_ERR,
+			"Invalid input, inst = %p, f = %p\n", inst, f);
+		return -EINVAL;
+	}
+	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+		fmt = msm_comm_get_pixel_fmt_index(venc_formats,
+			ARRAY_SIZE(venc_formats), f->index, CAPTURE_PORT);
+	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+		fmt = msm_comm_get_pixel_fmt_index(venc_formats,
+			ARRAY_SIZE(venc_formats), f->index, OUTPUT_PORT);
+		f->flags = V4L2_FMT_FLAG_COMPRESSED;
+	}
+
+	memset(f->reserved, 0 , sizeof(f->reserved));
+	if (fmt) {
+		strlcpy(f->description, fmt->description,
+				sizeof(f->description));
+		f->pixelformat = fmt->fourcc;
+	} else {
+		dprintk(VIDC_ERR, "No more formats found\n");
+		rc = -EINVAL;
+	}
+	return rc;
+}
+
+int msm_venc_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a)
+{
+	u32 property_id = 0, us_per_frame = 0;
+	void *pdata;
+	int rc = 0;
+	struct hal_frame_rate frame_rate;
+	struct hfi_device *hdev;
+
+	if (!inst || !inst->core || !inst->core->device) {
+		dprintk(VIDC_ERR, "%s invalid parameters", __func__);
+		return -EINVAL;
+	}
+	hdev = inst->core->device;
+
+	property_id = HAL_CONFIG_FRAME_RATE;
+	if (a->parm.output.timeperframe.denominator) {
+		switch (a->type) {
+		case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+			us_per_frame = a->parm.output.timeperframe.numerator *
+				USEC_PER_SEC / a->parm.output.\
+				timeperframe.denominator;
+			break;
+		default:
+			dprintk(VIDC_ERR,
+				"Scale clocks : Unknown buffer type\n");
+			break;
+		}
+	}
+
+	if (!us_per_frame) {
+		dprintk(VIDC_ERR,
+			"Failed to scale clocks : time between frames is 0\n");
+		rc = -EINVAL;
+		goto exit;
+	}
+	inst->prop.fps = (u8) (USEC_PER_SEC / us_per_frame);
+	if (inst->prop.fps) {
+		frame_rate.frame_rate = inst->prop.fps * (0x1<<16);
+		frame_rate.buffer_type = HAL_BUFFER_OUTPUT;
+		pdata = &frame_rate;
+		rc = call_hfi_op(hdev, session_set_property,
+				(void *)inst->session, property_id, pdata);
+
+		if (rc) {
+			dprintk(VIDC_WARN,
+				"Failed to set frame rate %d\n", rc);
+		}
+		msm_comm_scale_clocks_and_bus(inst);
+	}
+exit:
+	return rc;
+}
+int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
+{
+	const struct msm_vidc_format *fmt = NULL;
+	struct hal_frame_size frame_sz;
+	int rc = 0;
+	int i;
+	struct hfi_device *hdev;
+	if (!inst || !f) {
+		dprintk(VIDC_ERR,
+			"Invalid input, inst = %p, format = %p\n", inst, f);
+		return -EINVAL;
+	}
+
+	if (!inst->core || !inst->core->device) {
+		dprintk(VIDC_ERR, "%s invalid parameters", __func__);
+		return -EINVAL;
+	}
+	hdev = inst->core->device;
+
+	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+		fmt = msm_comm_get_pixel_fmt_fourcc(venc_formats,
+			ARRAY_SIZE(venc_formats), f->fmt.pix_mp.pixelformat,
+			CAPTURE_PORT);
+		if (fmt && fmt->type != CAPTURE_PORT) {
+			dprintk(VIDC_ERR,
+				"Format: %d not supported on CAPTURE port\n",
+				f->fmt.pix_mp.pixelformat);
+			rc = -EINVAL;
+			goto exit;
+		}
+	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+		inst->prop.width = f->fmt.pix_mp.width;
+		inst->prop.height = f->fmt.pix_mp.height;
+		frame_sz.buffer_type = HAL_BUFFER_INPUT;
+		frame_sz.width = inst->prop.width;
+		frame_sz.height = inst->prop.height;
+		dprintk(VIDC_DBG, "width = %d, height = %d\n",
+				frame_sz.width, frame_sz.height);
+		rc = call_hfi_op(hdev, session_set_property, (void *)
+			inst->session, HAL_PARAM_FRAME_SIZE, &frame_sz);
+		if (rc) {
+			dprintk(VIDC_ERR,
+				"Failed to set framesize for Output port\n");
+			goto exit;
+		}
+		frame_sz.buffer_type = HAL_BUFFER_OUTPUT;
+		rc = call_hfi_op(hdev, session_set_property, (void *)
+			inst->session, HAL_PARAM_FRAME_SIZE, &frame_sz);
+		if (rc) {
+			dprintk(VIDC_ERR,
+				"Failed to set hal property for framesize\n");
+			goto exit;
+		}
+		fmt = msm_comm_get_pixel_fmt_fourcc(venc_formats,
+			ARRAY_SIZE(venc_formats), f->fmt.pix_mp.pixelformat,
+			OUTPUT_PORT);
+		if (fmt && fmt->type != OUTPUT_PORT) {
+			dprintk(VIDC_ERR,
+				"Format: %d not supported on OUTPUT port\n",
+				f->fmt.pix_mp.pixelformat);
+			rc = -EINVAL;
+			goto exit;
+		}
+	}
+
+	if (fmt) {
+		f->fmt.pix_mp.num_planes = fmt->num_planes;
+		for (i = 0; i < fmt->num_planes; ++i) {
+			f->fmt.pix_mp.plane_fmt[i].sizeimage =
+				fmt->get_frame_size(i, f->fmt.pix_mp.height,
+						f->fmt.pix_mp.width);
+		}
+		inst->fmts[fmt->type] = fmt;
+		if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+			rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
+			if (rc) {
+				dprintk(VIDC_ERR, "Failed to open instance\n");
+				goto exit;
+			}
+		}
+	} else {
+		dprintk(VIDC_ERR, "Buf type not recognized, type = %d\n",
+					f->type);
+		rc = -EINVAL;
+	}
+exit:
+	return rc;
+}
+
+int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
+{
+	const struct msm_vidc_format *fmt = NULL;
+	int rc = 0;
+	int i;
+	if (!inst || !f) {
+		dprintk(VIDC_ERR,
+			"Invalid input, inst = %p, format = %p\n", inst, f);
+		return -EINVAL;
+	}
+	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+		fmt = inst->fmts[CAPTURE_PORT];
+	else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+		fmt = inst->fmts[OUTPUT_PORT];
+
+	if (fmt) {
+		f->fmt.pix_mp.pixelformat = fmt->fourcc;
+		f->fmt.pix_mp.height = inst->prop.height;
+		f->fmt.pix_mp.width = inst->prop.width;
+		f->fmt.pix_mp.num_planes = fmt->num_planes;
+		for (i = 0; i < fmt->num_planes; ++i) {
+			f->fmt.pix_mp.plane_fmt[i].sizeimage =
+			fmt->get_frame_size(i, inst->prop.height,
+					inst->prop.width);
+		}
+	} else {
+		dprintk(VIDC_ERR,
+			"Buf type not recognized, type = %d\n",	f->type);
+		rc = -EINVAL;
+	}
+	return rc;
+}
+
+int msm_venc_reqbufs(struct msm_vidc_inst *inst, struct v4l2_requestbuffers *b)
+{
+	struct buf_queue *q = NULL;
+	int rc = 0;
+	if (!inst || !b) {
+		dprintk(VIDC_ERR,
+			"Invalid input, inst = %p, buffer = %p\n", inst, b);
+		return -EINVAL;
+	}
+	q = msm_comm_get_vb2q(inst, b->type);
+	if (!q) {
+		dprintk(VIDC_ERR,
+		"Failed to find buffer queue for type = %d\n", b->type);
+		return -EINVAL;
+	}
+
+	mutex_lock(&q->lock);
+	rc = vb2_reqbufs(&q->vb2_bufq, b);
+	mutex_unlock(&q->lock);
+	if (rc)
+		dprintk(VIDC_ERR, "Failed to get reqbufs, %d\n", rc);
+	return rc;
+}
+
+int msm_venc_prepare_buf(struct msm_vidc_inst *inst,
+					struct v4l2_buffer *b)
+{
+	int rc = 0;
+	int i;
+	struct vidc_buffer_addr_info buffer_info;
+	struct hfi_device *hdev;
+
+	if (!inst || !inst->core || !inst->core->device) {
+		dprintk(VIDC_ERR, "%s invalid parameters", __func__);
+		return -EINVAL;
+	}
+
+	hdev = inst->core->device;
+
+	switch (b->type) {
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		break;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+		for (i = 0; i < b->length; i++) {
+			dprintk(VIDC_DBG,
+				"device_addr = %ld, size = %d\n",
+				b->m.planes[i].m.userptr,
+				b->m.planes[i].length);
+			buffer_info.buffer_size = b->m.planes[i].length;
+			buffer_info.buffer_type = HAL_BUFFER_OUTPUT;
+			buffer_info.num_buffers = 1;
+			buffer_info.align_device_addr =
+				b->m.planes[i].m.userptr;
+			buffer_info.extradata_size = 0;
+			buffer_info.extradata_addr = 0;
+			rc = call_hfi_op(hdev, session_set_buffers,
+				(void *)inst->session, &buffer_info);
+			if (rc)
+				dprintk(VIDC_ERR,
+					"vidc_hal_session_set_buffers failed");
+		}
+		break;
+	default:
+		dprintk(VIDC_ERR,
+			"Buffer type not recognized: %d\n", b->type);
+		break;
+	}
+	return rc;
+}
+
+int msm_venc_release_buf(struct msm_vidc_inst *inst,
+					struct v4l2_buffer *b)
+{
+	int rc = 0;
+	int i;
+	struct vidc_buffer_addr_info buffer_info;
+	struct hfi_device *hdev;
+
+	if (!inst || !inst->core || !inst->core->device) {
+		dprintk(VIDC_ERR, "%s invalid parameters", __func__);
+		return -EINVAL;
+	}
+
+	hdev = inst->core->device;
+
+	rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
+	if (rc) {
+		dprintk(VIDC_ERR,
+			"Failed to move inst: %p to release res done state\n",
+			inst);
+		goto exit;
+	}
+	switch (b->type) {
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		break;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+		for (i = 0; i < b->length; i++) {
+			dprintk(VIDC_DBG,
+				"Release device_addr = %ld, size = %d, %d\n",
+				b->m.planes[i].m.userptr,
+				b->m.planes[i].length, inst->state);
+			buffer_info.buffer_size = b->m.planes[i].length;
+			buffer_info.buffer_type = HAL_BUFFER_OUTPUT;
+			buffer_info.num_buffers = 1;
+			buffer_info.align_device_addr =
+				 b->m.planes[i].m.userptr;
+			buffer_info.extradata_size = 0;
+			buffer_info.extradata_addr = 0;
+			buffer_info.response_required = false;
+			rc = call_hfi_op(hdev, session_release_buffers,
+				(void *)inst->session, &buffer_info);
+			if (rc)
+				dprintk(VIDC_ERR,
+					"vidc_hal_session_release_buffers failed\n");
+		}
+		break;
+	default:
+		dprintk(VIDC_ERR, "Buffer type not recognized: %d\n", b->type);
+		break;
+	}
+exit:
+	return rc;
+}
+
+int msm_venc_qbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b)
+{
+	struct buf_queue *q = NULL;
+	int rc = 0;
+	q = msm_comm_get_vb2q(inst, b->type);
+	if (!q) {
+		dprintk(VIDC_ERR,
+			"Failed to find buffer queue for type = %d\n", b->type);
+		return -EINVAL;
+	}
+	mutex_lock(&q->lock);
+	rc = vb2_qbuf(&q->vb2_bufq, b);
+	mutex_unlock(&q->lock);
+	if (rc)
+		dprintk(VIDC_ERR, "Failed to qbuf, %d\n", rc);
+	return rc;
+}
+
+int msm_venc_dqbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b)
+{
+	struct buf_queue *q = NULL;
+	int rc = 0;
+	q = msm_comm_get_vb2q(inst, b->type);
+	if (!q) {
+		dprintk(VIDC_ERR,
+			"Failed to find buffer queue for type = %d\n", b->type);
+		return -EINVAL;
+	}
+	mutex_lock(&q->lock);
+	rc = vb2_dqbuf(&q->vb2_bufq, b, true);
+	mutex_unlock(&q->lock);
+	if (rc)
+		dprintk(VIDC_DBG, "Failed to dqbuf, %d\n", rc);
+	return rc;
+}
+
+int msm_venc_streamon(struct msm_vidc_inst *inst, enum v4l2_buf_type i)
+{
+	int rc = 0;
+	struct buf_queue *q;
+	q = msm_comm_get_vb2q(inst, i);
+	if (!q) {
+		dprintk(VIDC_ERR,
+			"Failed to find buffer queue for type = %d\n", i);
+		return -EINVAL;
+	}
+	dprintk(VIDC_DBG, "Calling streamon\n");
+	mutex_lock(&q->lock);
+	rc = vb2_streamon(&q->vb2_bufq, i);
+	mutex_unlock(&q->lock);
+	if (rc)
+		dprintk(VIDC_ERR, "streamon failed on port: %d\n", i);
+	return rc;
+}
+
+int msm_venc_streamoff(struct msm_vidc_inst *inst, enum v4l2_buf_type i)
+{
+	int rc = 0;
+	struct buf_queue *q;
+	q = msm_comm_get_vb2q(inst, i);
+	if (!q) {
+		dprintk(VIDC_ERR,
+			"Failed to find buffer queue for type = %d\n", i);
+		return -EINVAL;
+	}
+	dprintk(VIDC_DBG, "Calling streamoff on port: %d\n", i);
+	mutex_lock(&q->lock);
+	rc = vb2_streamoff(&q->vb2_bufq, i);
+	mutex_unlock(&q->lock);
+	if (rc)
+		dprintk(VIDC_ERR, "streamoff failed on port: %d\n", i);
+	return rc;
+}
+
+static struct v4l2_ctrl **get_cluster(int type, int *size)
+{
+	int c = 0, sz = 0;
+	struct v4l2_ctrl **cluster = kmalloc(sizeof(struct v4l2_ctrl *) *
+			NUM_CTRLS, GFP_KERNEL);
+
+	if (type <= 0 || !size || !cluster)
+		return NULL;
+
+	for (c = 0; c < NUM_CTRLS; c++) {
+		if (msm_venc_ctrls[c].cluster == type) {
+			cluster[sz] = msm_venc_ctrls[c].priv;
+			++sz;
+		}
+	}
+
+	*size = sz;
+	return cluster;
+}
+
+int msm_venc_ctrl_init(struct msm_vidc_inst *inst)
+{
+
+	int idx = 0;
+	struct v4l2_ctrl_config ctrl_cfg;
+	int ret_val = 0;
+	ret_val = v4l2_ctrl_handler_init(&inst->ctrl_handler, NUM_CTRLS);
+	if (ret_val) {
+		dprintk(VIDC_ERR, "CTRL ERR: Control handler init failed, %d\n",
+			inst->ctrl_handler.error);
+		return ret_val;
+	}
+
+	for (; idx < NUM_CTRLS; idx++) {
+		struct v4l2_ctrl *ctrl = NULL;
+		if (IS_PRIV_CTRL(msm_venc_ctrls[idx].id)) {
+			ctrl_cfg.def = msm_venc_ctrls[idx].default_value;
+			ctrl_cfg.flags = 0;
+			ctrl_cfg.id = msm_venc_ctrls[idx].id;
+			ctrl_cfg.max = msm_venc_ctrls[idx].maximum;
+			ctrl_cfg.min = msm_venc_ctrls[idx].minimum;
+			ctrl_cfg.menu_skip_mask =
+				msm_venc_ctrls[idx].menu_skip_mask;
+			ctrl_cfg.name = msm_venc_ctrls[idx].name;
+			ctrl_cfg.ops = &msm_venc_ctrl_ops;
+			ctrl_cfg.step = msm_venc_ctrls[idx].step;
+			ctrl_cfg.type = msm_venc_ctrls[idx].type;
+			ctrl_cfg.qmenu = msm_venc_ctrls[idx].qmenu;
+			ctrl = v4l2_ctrl_new_custom(
+					&inst->ctrl_handler,
+					&ctrl_cfg, NULL);
+		} else {
+			if (msm_venc_ctrls[idx].type == V4L2_CTRL_TYPE_MENU) {
+				ctrl = v4l2_ctrl_new_std_menu(
+					&inst->ctrl_handler,
+					&msm_venc_ctrl_ops,
+					msm_venc_ctrls[idx].id,
+					msm_venc_ctrls[idx].maximum,
+					msm_venc_ctrls[idx].menu_skip_mask,
+					msm_venc_ctrls[idx].default_value);
+			} else {
+				ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler,
+					&msm_venc_ctrl_ops,
+					msm_venc_ctrls[idx].id,
+					msm_venc_ctrls[idx].minimum,
+					msm_venc_ctrls[idx].maximum,
+					msm_venc_ctrls[idx].step,
+					msm_venc_ctrls[idx].default_value);
+			}
+		}
+		if (!ctrl) {
+			dprintk(VIDC_ERR,
+			"Failed to get ctrl for: idx: %d, %d\n",
+			idx, msm_venc_ctrls[idx].id);
+		}
+		msm_venc_ctrls[idx].priv = ctrl;
+	}
+	ret_val = inst->ctrl_handler.error;
+	if (ret_val)
+		dprintk(VIDC_ERR,
+			"CTRL ERR: Error adding ctrls to ctrl handle, %d\n",
+			inst->ctrl_handler.error);
+
+	/* Construct clusters */
+	for (idx = 1; idx < MSM_VENC_CTRL_CLUSTER_MAX; ++idx) {
+		struct msm_vidc_ctrl_cluster *temp = NULL;
+		struct v4l2_ctrl **cluster = NULL;
+		int cluster_size = 0;
+
+		cluster = get_cluster(idx, &cluster_size);
+		if (!cluster || !cluster_size) {
+			dprintk(VIDC_WARN, "Failed to setup cluster of type %d",
+					idx);
+			continue;
+		}
+		v4l2_ctrl_cluster(cluster_size, cluster);
+
+		temp = kzalloc(sizeof(*temp), GFP_KERNEL);
+		if (!temp) {
+			ret_val = -ENOMEM;
+			break;
+		}
+
+		temp->cluster = cluster;
+		INIT_LIST_HEAD(&temp->list);
+		list_add_tail(&temp->list, &inst->ctrl_clusters);
+	}
+
+	return ret_val;
+}
+
+int msm_venc_ctrl_deinit(struct msm_vidc_inst *inst)
+{
+	struct msm_vidc_ctrl_cluster *curr, *next;
+	list_for_each_entry_safe(curr, next, &inst->ctrl_clusters, list) {
+		kfree(curr->cluster);
+		kfree(curr);
+	}
+
+	return 0;
+}
diff --git a/drivers/media/platform/msm/vidc/msm_venc.h b/drivers/media/platform/msm/vidc/msm_venc.h
new file mode 100644
index 0000000..9020167
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/msm_venc.h
@@ -0,0 +1,39 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef _MSM_VENC_H_
+#define _MSM_VENC_H_
+
+#include <media/msm_vidc.h>
+#include "msm_vidc_internal.h"
+
+int msm_venc_inst_init(struct msm_vidc_inst *inst);
+int msm_venc_ctrl_init(struct msm_vidc_inst *inst);
+int msm_venc_ctrl_deinit(struct msm_vidc_inst *inst);
+int msm_venc_querycap(void *instance, struct v4l2_capability *cap);
+int msm_venc_enum_fmt(void *instance, struct v4l2_fmtdesc *f);
+int msm_venc_s_fmt(void *instance, struct v4l2_format *f);
+int msm_venc_g_fmt(void *instance, struct v4l2_format *f);
+int msm_venc_s_ctrl(void *instance, struct v4l2_control *a);
+int msm_venc_g_ctrl(void *instance, struct v4l2_control *a);
+int msm_venc_reqbufs(void *instance, struct v4l2_requestbuffers *b);
+int msm_venc_prepare_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
+int msm_venc_release_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
+int msm_venc_qbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
+int msm_venc_dqbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
+int msm_venc_streamon(struct msm_vidc_inst *inst, enum v4l2_buf_type i);
+int msm_venc_streamoff(struct msm_vidc_inst *inst, enum v4l2_buf_type i);
+int msm_venc_cmd(struct msm_vidc_inst *inst, struct v4l2_encoder_cmd *enc);
+int msm_venc_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a);
+struct vb2_ops *msm_venc_get_vb2q_ops(void);
+
+#endif
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
new file mode 100644
index 0000000..042900e
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -0,0 +1,575 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <media/msm_vidc.h>
+#include "msm_vidc_internal.h"
+#include "msm_vidc_debug.h"
+#include "msm_vdec.h"
+#include "msm_venc.h"
+#include "msm_vidc_common.h"
+#include "msm_smem.h"
+#include <linux/delay.h>
+#include "vidc_hfi_api.h"
+
+#define MAX_EVENTS 30
+
+static int get_poll_flags(void *instance)
+{
+	struct msm_vidc_inst *inst = instance;
+	struct vb2_queue *outq = &inst->bufq[OUTPUT_PORT].vb2_bufq;
+	struct vb2_queue *capq = &inst->bufq[CAPTURE_PORT].vb2_bufq;
+	struct vb2_buffer *out_vb = NULL;
+	struct vb2_buffer *cap_vb = NULL;
+	unsigned long flags;
+	int rc = 0;
+
+	if (v4l2_event_pending(&inst->event_handler))
+		rc |= POLLPRI;
+
+	spin_lock_irqsave(&capq->done_lock, flags);
+	if (!list_empty(&capq->done_list))
+		cap_vb = list_first_entry(&capq->done_list, struct vb2_buffer,
+								done_entry);
+	if (cap_vb && (cap_vb->state == VB2_BUF_STATE_DONE
+				|| cap_vb->state == VB2_BUF_STATE_ERROR))
+		rc |= POLLIN | POLLRDNORM;
+	spin_unlock_irqrestore(&capq->done_lock, flags);
+
+	spin_lock_irqsave(&outq->done_lock, flags);
+	if (!list_empty(&outq->done_list))
+		out_vb = list_first_entry(&outq->done_list, struct vb2_buffer,
+								done_entry);
+	if (out_vb && (out_vb->state == VB2_BUF_STATE_DONE
+				|| out_vb->state == VB2_BUF_STATE_ERROR))
+		rc |= POLLOUT | POLLWRNORM;
+	spin_unlock_irqrestore(&outq->done_lock, flags);
+
+	return rc;
+}
+
+int msm_vidc_poll(void *instance, struct file *filp,
+		struct poll_table_struct *wait)
+{
+	struct msm_vidc_inst *inst = instance;
+	struct vb2_queue *outq = &inst->bufq[OUTPUT_PORT].vb2_bufq;
+	struct vb2_queue *capq = &inst->bufq[CAPTURE_PORT].vb2_bufq;
+
+	poll_wait(filp, &inst->event_handler.wait, wait);
+	poll_wait(filp, &capq->done_wq, wait);
+	poll_wait(filp, &outq->done_wq, wait);
+	return get_poll_flags(inst);
+}
+
+/* Kernel client alternative for msm_vidc_poll */
+int msm_vidc_wait(void *instance)
+{
+	struct msm_vidc_inst *inst = instance;
+	int rc = 0;
+
+	wait_event(inst->kernel_event_queue, (rc = get_poll_flags(inst)));
+	return rc;
+}
+
+int msm_vidc_get_iommu_maps(void *instance,
+		struct msm_vidc_iommu_info maps[MAX_MAP])
+{
+	struct msm_vidc_inst *inst = instance;
+	struct hfi_device *hdev;
+
+	if (!inst || !maps || !inst->core || !inst->core->device)
+		return -EINVAL;
+
+	hdev = inst->core->device;
+
+	return call_hfi_op(hdev, iommu_get_map, hdev->hfi_device_data, maps);
+}
+
+int msm_vidc_querycap(void *instance, struct v4l2_capability *cap)
+{
+	struct msm_vidc_inst *inst = instance;
+
+	if (!inst || !cap)
+		return -EINVAL;
+
+	if (inst->session_type == MSM_VIDC_DECODER)
+		return msm_vdec_querycap(instance, cap);
+	else if (inst->session_type == MSM_VIDC_ENCODER)
+		return msm_venc_querycap(instance, cap);
+	return -EINVAL;
+}
+int msm_vidc_s_parm(void *instance,
+		struct v4l2_streamparm *a)
+{
+	struct msm_vidc_inst *inst = instance;
+
+	if (!inst || !a)
+		return -EINVAL;
+	if (inst->session_type == MSM_VIDC_DECODER)
+		return msm_vdec_s_parm(instance, a);
+	else if (inst->session_type == MSM_VIDC_ENCODER)
+		return msm_venc_s_parm(instance, a);
+	return -EINVAL;
+}
+int msm_vidc_enum_fmt(void *instance, struct v4l2_fmtdesc *f)
+{
+	struct msm_vidc_inst *inst = instance;
+
+	if (!inst || !f)
+		return -EINVAL;
+
+	if (inst->session_type == MSM_VIDC_DECODER)
+		return msm_vdec_enum_fmt(instance, f);
+	else if (inst->session_type == MSM_VIDC_ENCODER)
+		return msm_venc_enum_fmt(instance, f);
+	return -EINVAL;
+}
+int msm_vidc_s_fmt(void *instance, struct v4l2_format *f)
+{
+	struct msm_vidc_inst *inst = instance;
+
+	if (!inst || !f)
+		return -EINVAL;
+
+	if (inst->session_type == MSM_VIDC_DECODER)
+		return msm_vdec_s_fmt(instance, f);
+	if (inst->session_type == MSM_VIDC_ENCODER)
+		return msm_venc_s_fmt(instance, f);
+	return -EINVAL;
+}
+int msm_vidc_g_fmt(void *instance, struct v4l2_format *f)
+{
+	struct msm_vidc_inst *inst = instance;
+
+	if (!inst || !f)
+		return -EINVAL;
+
+	if (inst->session_type == MSM_VIDC_DECODER)
+		return msm_vdec_g_fmt(instance, f);
+	else if (inst->session_type == MSM_VIDC_ENCODER)
+		return msm_venc_g_fmt(instance, f);
+	return -EINVAL;
+}
+int msm_vidc_s_ctrl(void *instance, struct v4l2_control *control)
+{
+	struct msm_vidc_inst *inst = instance;
+
+	if (!inst || !control)
+		return -EINVAL;
+
+	if (inst->session_type == MSM_VIDC_DECODER)
+		return msm_vdec_s_ctrl(instance, control);
+	if (inst->session_type == MSM_VIDC_ENCODER)
+		return msm_venc_s_ctrl(instance, control);
+	return -EINVAL;
+}
+int msm_vidc_g_ctrl(void *instance, struct v4l2_control *control)
+{
+	struct msm_vidc_inst *inst = instance;
+
+	if (!inst || !control)
+		return -EINVAL;
+
+	if (inst->session_type == MSM_VIDC_DECODER)
+		return msm_vdec_g_ctrl(instance, control);
+	if (inst->session_type == MSM_VIDC_ENCODER)
+		return msm_venc_g_ctrl(instance, control);
+	return -EINVAL;
+}
+int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b)
+{
+	struct msm_vidc_inst *inst = instance;
+
+	if (!inst || !b)
+		return -EINVAL;
+
+	if (inst->session_type == MSM_VIDC_DECODER)
+		return msm_vdec_reqbufs(instance, b);
+	if (inst->session_type == MSM_VIDC_ENCODER)
+		return msm_venc_reqbufs(instance, b);
+	return -EINVAL;
+}
+
+int msm_vidc_prepare_buf(void *instance, struct v4l2_buffer *b)
+{
+	struct msm_vidc_inst *inst = instance;
+
+	if (!inst || !b)
+		return -EINVAL;
+
+	if (inst->session_type == MSM_VIDC_DECODER)
+		return msm_vdec_prepare_buf(instance, b);
+	if (inst->session_type == MSM_VIDC_ENCODER)
+		return msm_venc_prepare_buf(instance, b);
+	return -EINVAL;
+}
+
+int msm_vidc_release_buf(void *instance, struct v4l2_buffer *b)
+{
+	struct msm_vidc_inst *inst = instance;
+
+	if (!inst || !b)
+		return -EINVAL;
+
+	if (inst->session_type == MSM_VIDC_DECODER)
+		return msm_vdec_release_buf(instance, b);
+	if (inst->session_type == MSM_VIDC_ENCODER)
+		return msm_venc_release_buf(instance, b);
+	return -EINVAL;
+}
+
+int msm_vidc_encoder_cmd(void *instance, struct v4l2_encoder_cmd *enc)
+{
+	struct msm_vidc_inst *inst = instance;
+	if (inst->session_type == MSM_VIDC_ENCODER)
+		return msm_venc_cmd(instance, enc);
+	return -EINVAL;
+}
+
+int msm_vidc_decoder_cmd(void *instance, struct v4l2_decoder_cmd *dec)
+{
+	struct msm_vidc_inst *inst = instance;
+	if (inst->session_type == MSM_VIDC_DECODER)
+		return msm_vdec_cmd(instance, dec);
+	return -EINVAL;
+}
+
+int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b)
+{
+	struct msm_vidc_inst *inst = instance;
+
+	if (!inst || !b)
+		return -EINVAL;
+
+	if (inst->session_type == MSM_VIDC_DECODER)
+		return msm_vdec_qbuf(instance, b);
+	if (inst->session_type == MSM_VIDC_ENCODER)
+		return msm_venc_qbuf(instance, b);
+	return -EINVAL;
+}
+
+int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b)
+{
+	struct msm_vidc_inst *inst = instance;
+
+	if (!inst || !b)
+		return -EINVAL;
+
+	if (inst->session_type == MSM_VIDC_DECODER)
+		return msm_vdec_dqbuf(instance, b);
+	if (inst->session_type == MSM_VIDC_ENCODER)
+		return msm_venc_dqbuf(instance, b);
+	return -EINVAL;
+}
+
+int msm_vidc_streamon(void *instance, enum v4l2_buf_type i)
+{
+	struct msm_vidc_inst *inst = instance;
+
+	if (!inst)
+		return -EINVAL;
+
+	if (inst->session_type == MSM_VIDC_DECODER)
+		return msm_vdec_streamon(instance, i);
+	if (inst->session_type == MSM_VIDC_ENCODER)
+		return msm_venc_streamon(instance, i);
+	return -EINVAL;
+}
+
+int msm_vidc_streamoff(void *instance, enum v4l2_buf_type i)
+{
+	struct msm_vidc_inst *inst = instance;
+
+	if (!inst)
+		return -EINVAL;
+
+	if (inst->session_type == MSM_VIDC_DECODER)
+		return msm_vdec_streamoff(instance, i);
+	if (inst->session_type == MSM_VIDC_ENCODER)
+		return msm_venc_streamoff(instance, i);
+	return -EINVAL;
+}
+
+static void *vidc_get_userptr(void *alloc_ctx, unsigned long vaddr,
+				unsigned long size, int write)
+{
+	return (void *)0xdeadbeef;
+}
+
+static void vidc_put_userptr(void *buf_priv)
+{
+}
+
+static const struct vb2_mem_ops msm_vidc_vb2_mem_ops = {
+	.get_userptr = vidc_get_userptr,
+	.put_userptr = vidc_put_userptr,
+};
+
+static inline int vb2_bufq_init(struct msm_vidc_inst *inst,
+		enum v4l2_buf_type type, enum session_type sess)
+{
+	struct vb2_queue *q = NULL;
+	if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+		q = &inst->bufq[CAPTURE_PORT].vb2_bufq;
+	} else if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+		q = &inst->bufq[OUTPUT_PORT].vb2_bufq;
+	} else {
+		dprintk(VIDC_ERR, "buf_type = %d not recognised\n", type);
+		return -EINVAL;
+	}
+	q->type = type;
+	q->io_modes = VB2_MMAP | VB2_USERPTR;
+	q->io_flags = 0;
+	if (sess == MSM_VIDC_DECODER)
+		q->ops = msm_vdec_get_vb2q_ops();
+	else if (sess == MSM_VIDC_ENCODER)
+		q->ops = msm_venc_get_vb2q_ops();
+	q->mem_ops = &msm_vidc_vb2_mem_ops;
+	q->drv_priv = inst;
+	return vb2_queue_init(q);
+}
+
+static int setup_event_queue(void *inst,
+				struct video_device *pvdev)
+{
+	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);
+
+	return rc;
+}
+
+int msm_vidc_subscribe_event(void *inst, struct v4l2_event_subscription *sub)
+{
+	int rc = 0;
+	struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
+
+	if (!inst || !sub)
+		return -EINVAL;
+
+	rc = v4l2_event_subscribe(&vidc_inst->event_handler, sub, MAX_EVENTS);
+	return rc;
+}
+
+
+int msm_vidc_unsubscribe_event(void *inst, struct v4l2_event_subscription *sub)
+{
+	int rc = 0;
+	struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
+
+	if (!inst || !sub)
+		return -EINVAL;
+
+	rc = v4l2_event_unsubscribe(&vidc_inst->event_handler, sub);
+	return rc;
+}
+
+int msm_vidc_dqevent(void *inst, struct v4l2_event *event)
+{
+	int rc = 0;
+	struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
+
+	if (!inst || !event)
+		return -EINVAL;
+
+	rc = v4l2_event_dequeue(&vidc_inst->event_handler, event, false);
+	return rc;
+}
+
+void *msm_vidc_open(int core_id, int session_type)
+{
+	struct msm_vidc_inst *inst = NULL;
+	struct msm_vidc_core *core = NULL;
+	int rc = 0;
+	int i = 0;
+	if (core_id >= MSM_VIDC_CORES_MAX ||
+			session_type >= MSM_VIDC_MAX_DEVICES) {
+		dprintk(VIDC_ERR, "Invalid input, core_id = %d, session = %d\n",
+			core_id, session_type);
+		goto err_invalid_core;
+	}
+	core = get_vidc_core(core_id);
+	if (!core) {
+		dprintk(VIDC_ERR,
+			"Failed to find core for core_id = %d\n", core_id);
+		goto err_invalid_core;
+	}
+
+	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+	if (!inst) {
+		dprintk(VIDC_ERR, "Failed to allocate memory\n");
+		rc = -ENOMEM;
+		goto err_invalid_core;
+	}
+
+	pr_info(VIDC_DBG_TAG "Opening video instance: %p, %d\n",
+		VIDC_INFO, inst, session_type);
+	mutex_init(&inst->sync_lock);
+	mutex_init(&inst->bufq[CAPTURE_PORT].lock);
+	mutex_init(&inst->bufq[OUTPUT_PORT].lock);
+	mutex_init(&inst->lock);
+	inst->session_type = session_type;
+	INIT_LIST_HEAD(&inst->pendingq);
+	INIT_LIST_HEAD(&inst->internalbufs);
+	INIT_LIST_HEAD(&inst->persistbufs);
+	INIT_LIST_HEAD(&inst->ctrl_clusters);
+	init_waitqueue_head(&inst->kernel_event_queue);
+	inst->state = MSM_VIDC_CORE_UNINIT_DONE;
+	inst->core = core;
+
+	for (i = SESSION_MSG_INDEX(SESSION_MSG_START);
+		i <= SESSION_MSG_INDEX(SESSION_MSG_END); i++) {
+		init_completion(&inst->completions[i]);
+	}
+	inst->mem_client = msm_smem_new_client(SMEM_ION);
+	if (!inst->mem_client) {
+		dprintk(VIDC_ERR, "Failed to create memory client\n");
+		goto fail_mem_client;
+	}
+	if (session_type == MSM_VIDC_DECODER) {
+		msm_vdec_inst_init(inst);
+		msm_vdec_ctrl_init(inst);
+	} else if (session_type == MSM_VIDC_ENCODER) {
+		msm_venc_inst_init(inst);
+		msm_venc_ctrl_init(inst);
+	}
+
+	rc = vb2_bufq_init(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+			session_type);
+	if (rc) {
+		dprintk(VIDC_ERR,
+			"Failed to initialize vb2 queue on capture port\n");
+		goto fail_init;
+	}
+	rc = vb2_bufq_init(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+			session_type);
+	if (rc) {
+		dprintk(VIDC_ERR,
+			"Failed to initialize vb2 queue on capture port\n");
+		goto fail_init;
+	}
+	rc = msm_comm_try_state(inst, MSM_VIDC_CORE_INIT);
+	if (rc) {
+		dprintk(VIDC_ERR,
+			"Failed to move video instance to init state\n");
+		goto fail_init;
+	}
+	inst->debugfs_root =
+		msm_vidc_debugfs_init_inst(inst, core->debugfs_root);
+
+	setup_event_queue(inst, &core->vdev[core_id].vdev);
+
+	mutex_lock(&core->lock);
+	list_add_tail(&inst->list, &core->instances);
+	mutex_unlock(&core->lock);
+	return inst;
+fail_init:
+	msm_smem_delete_client(inst->mem_client);
+fail_mem_client:
+	kfree(inst);
+	inst = NULL;
+err_invalid_core:
+	return inst;
+}
+
+static void cleanup_instance(struct msm_vidc_inst *inst)
+{
+	struct list_head *ptr, *next;
+	struct vb2_buf_entry *entry;
+	struct internal_buf *buf;
+	if (inst) {
+		mutex_lock(&inst->lock);
+		if (!list_empty(&inst->pendingq)) {
+			list_for_each_safe(ptr, next, &inst->pendingq) {
+				entry = list_entry(ptr, struct vb2_buf_entry,
+						list);
+				list_del(&entry->list);
+				kfree(entry);
+			}
+		}
+		if (!list_empty(&inst->internalbufs)) {
+			list_for_each_safe(ptr, next, &inst->internalbufs) {
+				buf = list_entry(ptr, struct internal_buf,
+						list);
+				list_del(&buf->list);
+				mutex_unlock(&inst->lock);
+				msm_smem_free(inst->mem_client, buf->handle);
+				kfree(buf);
+				mutex_lock(&inst->lock);
+			}
+		}
+		if (!list_empty(&inst->persistbufs)) {
+			list_for_each_safe(ptr, next, &inst->persistbufs) {
+				buf = list_entry(ptr, struct internal_buf,
+						list);
+				list_del(&buf->list);
+				mutex_unlock(&inst->lock);
+				msm_smem_free(inst->mem_client, buf->handle);
+				kfree(buf);
+				mutex_lock(&inst->lock);
+			}
+		}
+		if (inst->extradata_handle) {
+			mutex_unlock(&inst->lock);
+			msm_smem_free(inst->mem_client, inst->extradata_handle);
+			mutex_lock(&inst->lock);
+		}
+		mutex_unlock(&inst->lock);
+		msm_smem_delete_client(inst->mem_client);
+		debugfs_remove_recursive(inst->debugfs_root);
+	}
+}
+
+int msm_vidc_close(void *instance)
+{
+	struct msm_vidc_inst *inst = instance;
+	struct msm_vidc_inst *temp;
+	struct msm_vidc_core *core;
+	struct list_head *ptr, *next;
+	int rc = 0;
+
+	if (!inst)
+		return -EINVAL;
+
+	core = inst->core;
+	mutex_lock(&core->sync_lock);
+	list_for_each_safe(ptr, next, &core->instances) {
+		temp = list_entry(ptr, struct msm_vidc_inst, list);
+		if (temp == inst)
+			list_del(&inst->list);
+	}
+	mutex_unlock(&core->sync_lock);
+
+	if (inst->session_type == MSM_VIDC_DECODER)
+		msm_vdec_ctrl_deinit(inst);
+	else if (inst->session_type == MSM_VIDC_ENCODER)
+		msm_venc_ctrl_deinit(inst);
+
+	cleanup_instance(inst);
+	if (inst->state != MSM_VIDC_CORE_INVALID &&
+		core->state != VIDC_CORE_INVALID)
+		rc = msm_comm_try_state(inst, MSM_VIDC_CORE_UNINIT);
+	else
+		rc = msm_comm_force_cleanup(inst);
+	if (rc)
+		dprintk(VIDC_ERR,
+			"Failed to move video instance to uninit state\n");
+	pr_info(VIDC_DBG_TAG "Closed video instance: %p\n", VIDC_INFO, inst);
+	kfree(inst);
+	return 0;
+}
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
new file mode 100644
index 0000000..8cce310
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -0,0 +1,2327 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <asm/div64.h>
+#include <mach/subsystem_restart.h>
+
+#include "msm_vidc_common.h"
+#include "vidc_hfi_api.h"
+#include "msm_smem.h"
+#include "msm_vidc_debug.h"
+
+#define HW_RESPONSE_TIMEOUT (5 * 60 * 1000)
+
+#define IS_ALREADY_IN_STATE(__p, __d) ({\
+	int __rc = (__p >= __d);\
+	__rc; \
+})
+
+#define V4L2_EVENT_SEQ_CHANGED_SUFFICIENT \
+		V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT
+#define V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT \
+		V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT
+
+#define NUM_MBS_PER_SEC(__height, __width, __fps) ({\
+	(__height >> 4) * (__width >> 4) * __fps; \
+})
+
+#define VIDC_BUS_LOAD(__height, __width, __fps, __br) ({\
+	__height * __width * __fps; \
+})
+
+#define GET_NUM_MBS(__h, __w) ({\
+	u32 __mbs = (__h >> 4) * (__w >> 4);\
+	__mbs;\
+})
+
+#define TIME_DIFF_THRESHOLD 200
+
+/*Load is in Macroblocks (MBs) per sec. This value is calculated
+ * based on one 4k video instance @ 24 fps plus one 1080p video
+ * instance @ 30fps. 1 MB = 16 X 16 pixels*/
+#define MAX_LOAD 1074240
+
+static int msm_comm_get_load(struct msm_vidc_core *core,
+	enum session_type type)
+{
+	struct msm_vidc_inst *inst = NULL;
+	int num_mbs_per_sec = 0;
+	if (!core) {
+		dprintk(VIDC_ERR, "Invalid args: %p\n", core);
+		return -EINVAL;
+	}
+	list_for_each_entry(inst, &core->instances, list) {
+		mutex_lock(&inst->lock);
+		if (inst->session_type == type &&
+			inst->state >= MSM_VIDC_OPEN_DONE &&
+			inst->state < MSM_VIDC_STOP_DONE) {
+			num_mbs_per_sec += NUM_MBS_PER_SEC(inst->prop.height,
+					inst->prop.width, inst->prop.fps);
+		}
+		mutex_unlock(&inst->lock);
+	}
+	return num_mbs_per_sec;
+}
+
+static int msm_comm_scale_bus(struct msm_vidc_core *core,
+	enum session_type type, enum mem_type mtype)
+{
+	int load;
+	int rc = 0;
+	struct hfi_device *hdev;
+
+	if (!core || type >= MSM_VIDC_MAX_DEVICES) {
+		dprintk(VIDC_ERR, "Invalid args: %p, %d\n", core, type);
+		return -EINVAL;
+	}
+
+	hdev = core->device;
+	if (!hdev) {
+		dprintk(VIDC_ERR, "Invalid device handle %p\n", hdev);
+		return -EINVAL;
+	}
+
+	load = msm_comm_get_load(core, type);
+
+	rc = call_hfi_op(hdev, scale_bus, hdev->hfi_device_data,
+					 load, type, mtype);
+	if (rc)
+		dprintk(VIDC_ERR, "Failed to scale bus: %d\n", rc);
+
+	return rc;
+}
+
+static void msm_comm_unvote_buses(struct msm_vidc_core *core,
+	enum mem_type mtype)
+{
+	int i;
+	struct hfi_device *hdev;
+
+	if (!core || !core->device) {
+		dprintk(VIDC_ERR, "%s invalid parameters", __func__);
+		return;
+	}
+	hdev = core->device;
+
+	for (i = 0; i < MSM_VIDC_MAX_DEVICES; i++) {
+		if ((mtype & DDR_MEM) &&
+			call_hfi_op(hdev, unvote_bus, hdev->hfi_device_data,
+				i, DDR_MEM))
+			dprintk(VIDC_WARN,
+				"Failed to unvote for DDR accesses\n");
+
+		if ((mtype & OCMEM_MEM) &&
+			call_hfi_op(hdev, unvote_bus, hdev->hfi_device_data,
+				i, OCMEM_MEM))
+			dprintk(VIDC_WARN,
+				"Failed to unvote for OCMEM accesses\n");
+	}
+}
+
+struct msm_vidc_core *get_vidc_core(int core_id)
+{
+	struct msm_vidc_core *core;
+	int found = 0;
+	if (core_id > MSM_VIDC_CORES_MAX) {
+		dprintk(VIDC_ERR, "Core id = %d is greater than max = %d\n",
+			core_id, MSM_VIDC_CORES_MAX);
+		return NULL;
+	}
+	mutex_lock(&vidc_driver->lock);
+	list_for_each_entry(core, &vidc_driver->cores, list) {
+		if (core && core->id == core_id)
+			found = 1;
+			break;
+	}
+	mutex_unlock(&vidc_driver->lock);
+	if (found)
+		return core;
+	return NULL;
+}
+
+const struct msm_vidc_format *msm_comm_get_pixel_fmt_index(
+	const struct msm_vidc_format fmt[], int size, int index, int fmt_type)
+{
+	int i, k = 0;
+	if (!fmt || index < 0) {
+		dprintk(VIDC_ERR, "Invalid inputs, fmt = %p, index = %d\n",
+						fmt, index);
+		return NULL;
+	}
+	for (i = 0; i < size; i++) {
+		if (fmt[i].type != fmt_type)
+			continue;
+		if (k == index)
+			break;
+		k++;
+	}
+	if (i == size) {
+		dprintk(VIDC_INFO, "Format not found\n");
+		return NULL;
+	}
+	return &fmt[i];
+}
+const struct msm_vidc_format *msm_comm_get_pixel_fmt_fourcc(
+	const struct msm_vidc_format fmt[], int size, int fourcc, int fmt_type)
+{
+	int i;
+	if (!fmt) {
+		dprintk(VIDC_ERR, "Invalid inputs, fmt = %p\n", fmt);
+		return NULL;
+	}
+	for (i = 0; i < size; i++) {
+		if (fmt[i].fourcc == fourcc)
+				break;
+	}
+	if (i == size) {
+		dprintk(VIDC_INFO, "Format not found\n");
+		return NULL;
+	}
+	return &fmt[i];
+}
+
+struct buf_queue *msm_comm_get_vb2q(
+		struct msm_vidc_inst *inst,	enum v4l2_buf_type type)
+{
+	if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+		return &inst->bufq[CAPTURE_PORT];
+	if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+		return &inst->bufq[OUTPUT_PORT];
+	return NULL;
+}
+
+static void handle_sys_init_done(enum command_response cmd, void *data)
+{
+	struct msm_vidc_cb_cmd_done *response = data;
+	struct msm_vidc_core *core;
+	struct vidc_hal_sys_init_done *sys_init_msg;
+	int index = SYS_MSG_INDEX(cmd);
+	if (!response) {
+		dprintk(VIDC_ERR,
+			"Failed to get valid response for sys init\n");
+		return;
+	}
+	core = get_vidc_core(response->device_id);
+	if (!core) {
+		dprintk(VIDC_ERR, "Wrong device_id received\n");
+		return;
+	}
+	dprintk(VIDC_DBG, "index = %d\n", index);
+	dprintk(VIDC_DBG, "ptr = %p\n", &(core->completions[index]));
+	complete(&(core->completions[index]));
+	sys_init_msg = response->data;
+	if (!sys_init_msg) {
+		dprintk(VIDC_ERR, "sys_init_done message not proper\n");
+		return;
+	}
+}
+
+static void handle_session_release_buf_done(enum command_response cmd,
+	void *data)
+{
+	struct msm_vidc_cb_cmd_done *response = data;
+	struct msm_vidc_inst *inst;
+	struct internal_buf *buf;
+	struct list_head *ptr, *next;
+	struct hal_buffer_info *buffer;
+	u32 address, buf_found = false;
+
+	if (!response || !response->data) {
+		dprintk(VIDC_ERR, "Invalid release_buf_done response\n");
+		return;
+	}
+
+	inst = (struct msm_vidc_inst *)response->session_id;
+	buffer = (struct hal_buffer_info *) response->data;
+	address = (u32) buffer->buffer_addr;
+
+	list_for_each_safe(ptr, next, &inst->internalbufs) {
+		buf = list_entry(ptr, struct internal_buf, list);
+		if (address == buf->handle->device_addr) {
+			dprintk(VIDC_DBG, "releasing scratch: 0x%x",
+					(u32) buf->handle->device_addr);
+					buf_found = true;
+		}
+	}
+
+	list_for_each_safe(ptr, next, &inst->persistbufs) {
+		buf = list_entry(ptr, struct internal_buf, list);
+		if (address == (u32) buf->handle->device_addr) {
+			dprintk(VIDC_DBG, "releasing persist: 0x%x",
+					(u32) buf->handle->device_addr);
+			buf_found = true;
+		}
+	}
+
+	if (!buf_found)
+		dprintk(VIDC_ERR, "invalid buffer received from firmware");
+	complete(&inst->completions[SESSION_MSG_INDEX(cmd)]);
+}
+
+static void handle_sys_release_res_done(
+	enum command_response cmd, void *data)
+{
+	struct msm_vidc_cb_cmd_done *response = data;
+	struct msm_vidc_core *core;
+	if (!response) {
+		dprintk(VIDC_ERR,
+			"Failed to get valid response for sys init\n");
+		return;
+	}
+	core = get_vidc_core(response->device_id);
+	if (!core) {
+		dprintk(VIDC_ERR, "Wrong device_id received\n");
+		return;
+	}
+	complete(&core->completions[SYS_MSG_INDEX(cmd)]);
+}
+
+static void change_inst_state(struct msm_vidc_inst *inst,
+	enum instance_state state)
+{
+	mutex_lock(&inst->lock);
+	dprintk(VIDC_DBG, "Moved inst: %p from state: %d to state: %d\n",
+		   inst, inst->state, state);
+	inst->state = state;
+	mutex_unlock(&inst->lock);
+}
+
+static int signal_session_msg_receipt(enum command_response cmd,
+		struct msm_vidc_inst *inst)
+{
+	if (!inst) {
+		dprintk(VIDC_ERR, "Invalid(%p) instance id\n", inst);
+		return -EINVAL;
+	}
+	complete(&inst->completions[SESSION_MSG_INDEX(cmd)]);
+	return 0;
+}
+
+static int wait_for_sess_signal_receipt(struct msm_vidc_inst *inst,
+	enum command_response cmd)
+{
+	int rc = 0;
+	rc = wait_for_completion_interruptible_timeout(
+		&inst->completions[SESSION_MSG_INDEX(cmd)],
+		msecs_to_jiffies(HW_RESPONSE_TIMEOUT));
+	if (!rc) {
+		dprintk(VIDC_ERR, "Wait interrupted or timeout: %d\n", rc);
+		rc = -EIO;
+	} else {
+		rc = 0;
+	}
+	return rc;
+}
+
+static int wait_for_state(struct msm_vidc_inst *inst,
+	enum instance_state flipped_state,
+	enum instance_state desired_state,
+	enum command_response hal_cmd)
+{
+	int rc = 0;
+	if (IS_ALREADY_IN_STATE(flipped_state, desired_state)) {
+		dprintk(VIDC_INFO, "inst: %p is already in state: %d\n",
+						inst, inst->state);
+		goto err_same_state;
+	}
+	dprintk(VIDC_DBG, "Waiting for hal_cmd: %d\n", hal_cmd);
+	rc = wait_for_sess_signal_receipt(inst, hal_cmd);
+	if (!rc)
+		change_inst_state(inst, desired_state);
+err_same_state:
+	return rc;
+}
+
+static void handle_session_init_done(enum command_response cmd, void *data)
+{
+	struct msm_vidc_cb_cmd_done *response = data;
+	struct msm_vidc_inst *inst;
+	if (response) {
+		inst = (struct msm_vidc_inst *)response->session_id;
+		signal_session_msg_receipt(cmd, inst);
+	} else {
+		dprintk(VIDC_ERR,
+			"Failed to get valid response for session init\n");
+	}
+}
+
+static void handle_event_change(enum command_response cmd, void *data)
+{
+	struct msm_vidc_cb_cmd_done *response = data;
+	struct msm_vidc_inst *inst;
+	struct v4l2_event dqevent;
+	struct v4l2_control control = {0};
+	struct msm_vidc_cb_event *event_notify;
+	int rc = 0;
+	if (response) {
+		inst = (struct msm_vidc_inst *)response->session_id;
+		dqevent.id = 0;
+		event_notify = (struct msm_vidc_cb_event *) response->data;
+		switch (event_notify->hal_event_type) {
+		case HAL_EVENT_SEQ_CHANGED_SUFFICIENT_RESOURCES:
+			dqevent.type =
+				V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT;
+			control.id =
+				V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
+			rc = v4l2_g_ctrl(&inst->ctrl_handler, &control);
+			if (rc)
+				dprintk(VIDC_WARN,
+					"Failed to get Smooth streamng flag\n");
+			if (!rc && control.value == true)
+				dqevent.type =
+					V4L2_EVENT_SEQ_CHANGED_SUFFICIENT;
+			break;
+		case HAL_EVENT_SEQ_CHANGED_INSUFFICIENT_RESOURCES:
+			dqevent.type =
+				V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT;
+			break;
+		default:
+			break;
+		}
+		inst->reconfig_height = event_notify->height;
+		inst->reconfig_width = event_notify->width;
+		inst->in_reconfig = true;
+		v4l2_event_queue_fh(&inst->event_handler, &dqevent);
+		wake_up(&inst->kernel_event_queue);
+		return;
+	} else {
+		dprintk(VIDC_ERR,
+			"Failed to get valid response for event_change\n");
+	}
+}
+
+static void handle_session_prop_info(enum command_response cmd, void *data)
+{
+	struct msm_vidc_cb_cmd_done *response = data;
+	struct msm_vidc_inst *inst;
+	int i;
+	if (!response || !response->data) {
+		dprintk(VIDC_ERR,
+			"Failed to get valid response for prop info\n");
+		return;
+	}
+	inst = (struct msm_vidc_inst *)response->session_id;
+	mutex_lock(&inst->lock);
+	memcpy(&inst->buff_req, response->data,
+			sizeof(struct buffer_requirements));
+	mutex_unlock(&inst->lock);
+	for (i = 0; i < 8; i++) {
+		dprintk(VIDC_DBG,
+			"buffer type: %d, count : %d, size: %d\n",
+			inst->buff_req.buffer[i].buffer_type,
+			inst->buff_req.buffer[i].buffer_count_actual,
+			inst->buff_req.buffer[i].buffer_size);
+	}
+	dprintk(VIDC_PROF, "Input buffers: %d, Output buffers: %d\n",
+			inst->buff_req.buffer[0].buffer_count_actual,
+			inst->buff_req.buffer[1].buffer_count_actual);
+	signal_session_msg_receipt(cmd, inst);
+}
+
+static void handle_load_resource_done(enum command_response cmd, void *data)
+{
+	struct msm_vidc_cb_cmd_done *response = data;
+	struct msm_vidc_inst *inst;
+	if (response)
+		inst = (struct msm_vidc_inst *)response->session_id;
+	else
+		dprintk(VIDC_ERR,
+			"Failed to get valid response for load resource\n");
+}
+
+static void handle_start_done(enum command_response cmd, void *data)
+{
+	struct msm_vidc_cb_cmd_done *response = data;
+	struct msm_vidc_inst *inst;
+	if (response) {
+		inst = (struct msm_vidc_inst *)response->session_id;
+		signal_session_msg_receipt(cmd, inst);
+	} else {
+		dprintk(VIDC_ERR,
+			"Failed to get valid response for start\n");
+	}
+}
+
+static void handle_stop_done(enum command_response cmd, void *data)
+{
+	struct msm_vidc_cb_cmd_done *response = data;
+	struct msm_vidc_inst *inst;
+	if (response) {
+		inst = (struct msm_vidc_inst *)response->session_id;
+		signal_session_msg_receipt(cmd, inst);
+	} else {
+		dprintk(VIDC_ERR,
+			"Failed to get valid response for stop\n");
+	}
+}
+
+static void handle_release_res_done(enum command_response cmd, void *data)
+{
+	struct msm_vidc_cb_cmd_done *response = data;
+	struct msm_vidc_inst *inst;
+	if (response) {
+		inst = (struct msm_vidc_inst *)response->session_id;
+		signal_session_msg_receipt(cmd, inst);
+	} else {
+		dprintk(VIDC_ERR,
+			"Failed to get valid response for release resource\n");
+	}
+}
+
+static void handle_session_flush(enum command_response cmd, void *data)
+{
+	struct msm_vidc_cb_cmd_done *response = data;
+	struct msm_vidc_inst *inst;
+	struct v4l2_event dqevent;
+	if (response) {
+		inst = (struct msm_vidc_inst *)response->session_id;
+		dqevent.type = V4L2_EVENT_MSM_VIDC_FLUSH_DONE;
+		dqevent.id = 0;
+		v4l2_event_queue_fh(&inst->event_handler, &dqevent);
+		wake_up(&inst->kernel_event_queue);
+	} else {
+		dprintk(VIDC_ERR, "Failed to get valid response for flush\n");
+	}
+}
+
+static void handle_session_error(enum command_response cmd, void *data)
+{
+	struct msm_vidc_cb_cmd_done *response = data;
+	struct msm_vidc_inst *inst = NULL;
+	struct v4l2_event dqevent;
+	if (response) {
+		inst = (struct msm_vidc_inst *)response->session_id;
+		if (inst) {
+			dprintk(VIDC_WARN,
+				"Session error receivd for session %p\n", inst);
+			mutex_lock(&inst->sync_lock);
+			inst->state = MSM_VIDC_CORE_INVALID;
+			mutex_unlock(&inst->sync_lock);
+			dqevent.type = V4L2_EVENT_MSM_VIDC_SYS_ERROR;
+			dqevent.id = 0;
+			v4l2_event_queue_fh(&inst->event_handler, &dqevent);
+			wake_up(&inst->kernel_event_queue);
+		}
+	} else {
+		dprintk(VIDC_ERR,
+			"Failed to get valid response for session error\n");
+	}
+}
+static void handle_sys_error(enum command_response cmd, void *data)
+{
+	struct msm_vidc_cb_cmd_done *response = data;
+	struct msm_vidc_inst *inst = NULL ;
+	struct msm_vidc_core *core = NULL;
+	struct v4l2_event dqevent;
+	if (response) {
+		core = get_vidc_core(response->device_id);
+		dprintk(VIDC_WARN, "SYS_ERROR received for core %p\n", core);
+		if (core) {
+			mutex_lock(&core->lock);
+			core->state = VIDC_CORE_INVALID;
+			mutex_unlock(&core->lock);
+			dqevent.type = V4L2_EVENT_MSM_VIDC_SYS_ERROR;
+			dqevent.id = 0;
+			list_for_each_entry(inst, &core->instances,
+					list) {
+				v4l2_event_queue_fh(&inst->event_handler,
+						&dqevent);
+
+				mutex_lock(&inst->lock);
+				inst->state = MSM_VIDC_CORE_INVALID;
+				mutex_unlock(&inst->lock);
+
+				wake_up(&inst->kernel_event_queue);
+			}
+		} else {
+			dprintk(VIDC_ERR,
+				"Got SYS_ERR but unable to identify core");
+		}
+	} else {
+		dprintk(VIDC_ERR,
+			"Failed to get valid response for sys error\n");
+	}
+}
+
+static void handle_sys_watchdog_timeout(enum command_response cmd, void *data)
+{
+	struct msm_vidc_cb_cmd_done *response = data;
+	struct msm_vidc_inst *inst;
+	struct msm_vidc_core *core = NULL;
+	struct v4l2_event dqevent;
+	dprintk(VIDC_ERR, "Venus Subsystem crashed\n");
+	core = get_vidc_core(response->device_id);
+	if (!core) {
+		dprintk(VIDC_ERR, "Wrong device_id received\n");
+		return;
+	}
+	subsystem_crashed("venus");
+	mutex_lock(&core->lock);
+	core->state = VIDC_CORE_INVALID;
+	mutex_unlock(&core->lock);
+	dqevent.type = V4L2_EVENT_MSM_VIDC_SYS_ERROR;
+	dqevent.id = 0;
+	list_for_each_entry(inst, &core->instances, list) {
+		if (inst) {
+			v4l2_event_queue_fh(&inst->event_handler, &dqevent);
+			mutex_lock(&inst->lock);
+			inst->state = MSM_VIDC_CORE_INVALID;
+			inst->session = NULL;
+			mutex_unlock(&inst->lock);
+		}
+	}
+}
+
+static void handle_session_close(enum command_response cmd, void *data)
+{
+	struct msm_vidc_cb_cmd_done *response = data;
+	struct msm_vidc_inst *inst;
+	struct v4l2_event dqevent;
+	if (response) {
+		inst = (struct msm_vidc_inst *)response->session_id;
+		signal_session_msg_receipt(cmd, inst);
+		dqevent.type = V4L2_EVENT_MSM_VIDC_CLOSE_DONE;
+		dqevent.id = 0;
+		v4l2_event_queue_fh(&inst->event_handler, &dqevent);
+		inst->session = NULL;
+		wake_up(&inst->kernel_event_queue);
+		show_stats(inst);
+	} else {
+		dprintk(VIDC_ERR,
+			"Failed to get valid response for session close\n");
+	}
+}
+
+static struct vb2_buffer *get_vb_from_device_addr(struct buf_queue *bufq,
+		u32 dev_addr)
+{
+	struct vb2_buffer *vb = NULL;
+	struct vb2_queue *q = NULL;
+	int found = 0;
+	if (!bufq) {
+		dprintk(VIDC_ERR, "Invalid parameter\n");
+		return NULL;
+	}
+	q = &bufq->vb2_bufq;
+	mutex_lock(&bufq->lock);
+	list_for_each_entry(vb, &q->queued_list, queued_entry) {
+		if (vb->v4l2_planes[0].m.userptr == dev_addr) {
+			found = 1;
+			break;
+		}
+	}
+	mutex_unlock(&bufq->lock);
+	if (!found) {
+		dprintk(VIDC_ERR,
+			"Failed to find the buffer in queued list: 0x%x, %d\n",
+			dev_addr, q->type);
+		vb = NULL;
+	}
+	return vb;
+}
+
+static void handle_ebd(enum command_response cmd, void *data)
+{
+	struct msm_vidc_cb_data_done *response = data;
+	struct vb2_buffer *vb;
+	struct msm_vidc_inst *inst;
+	if (!response) {
+		dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
+		return;
+	}
+	vb = response->clnt_data;
+	inst = (struct msm_vidc_inst *)response->session_id;
+	if (vb) {
+		mutex_lock(&inst->bufq[OUTPUT_PORT].lock);
+		vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+		mutex_unlock(&inst->bufq[OUTPUT_PORT].lock);
+		wake_up(&inst->kernel_event_queue);
+		msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_EBD);
+	}
+}
+
+static void msm_comm_update_clocks(struct msm_vidc_inst *inst,
+	u64 cur_time_stamp)
+{
+	u32 new_time_diff = 0, cur_time_diff = 0;
+	u8 updated_fps = 0;
+	struct v4l2_ctrl *ctrl = NULL;
+	u32 output_order = 0;
+
+	if (inst->session_type == MSM_VIDC_ENCODER)
+		goto exit;
+	if (cur_time_stamp >= LLONG_MAX) {
+		dprintk(VIDC_DBG,
+			"Clock scaling failed : Timestamp invalid\n");
+		goto exit;
+	}
+	ctrl = v4l2_ctrl_find(&inst->ctrl_handler,
+		V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER);
+	if (!ctrl) {
+		dprintk(VIDC_WARN, "Unable to find output order control\n");
+		dprintk(VIDC_WARN,
+			"Performance might be impacted for higher fps clips\n");
+		goto exit;
+	}
+	output_order = v4l2_ctrl_g_ctrl(ctrl);
+	if (output_order == V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY) {
+		new_time_diff =
+			(u32)(cur_time_stamp - inst->prop.prev_time_stamp);
+		inst->prop.prev_time_stamp = cur_time_stamp;
+		if (!new_time_diff)
+			goto exit;
+		if (inst->prop.fps)
+			cur_time_diff = USEC_PER_SEC / inst->prop.fps;
+		cur_time_diff = cur_time_diff > new_time_diff ?
+			cur_time_diff - new_time_diff :
+			new_time_diff - cur_time_diff;
+		if (cur_time_diff > TIME_DIFF_THRESHOLD) {
+			updated_fps = (u8) (USEC_PER_SEC / new_time_diff);
+			if (updated_fps && (updated_fps != inst->prop.fps)) {
+				inst->prop.fps = updated_fps;
+				dprintk(VIDC_DBG,
+						"Updating clocks: Decoding fps = %d\n",
+						inst->prop.fps);
+				msm_comm_scale_clocks_and_bus(inst);
+			}
+		}
+	}
+exit:
+	return;
+}
+
+static void handle_fbd(enum command_response cmd, void *data)
+{
+	struct msm_vidc_cb_data_done *response = data;
+	struct msm_vidc_inst *inst;
+	struct vb2_buffer *vb;
+	struct vidc_hal_fbd *fill_buf_done;
+
+	if (!response) {
+		dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
+		return;
+	}
+	inst = (struct msm_vidc_inst *)response->session_id;
+	fill_buf_done = (struct vidc_hal_fbd *)&response->output_done;
+	vb = get_vb_from_device_addr(&inst->bufq[CAPTURE_PORT],
+		(u32)fill_buf_done->packet_buffer1);
+	if (vb) {
+		vb->v4l2_planes[0].bytesused = fill_buf_done->filled_len1;
+		vb->v4l2_planes[0].reserved[2] = fill_buf_done->start_x_coord;
+		vb->v4l2_planes[0].reserved[3] = fill_buf_done->start_y_coord;
+		vb->v4l2_planes[0].reserved[4] = fill_buf_done->frame_width;
+		vb->v4l2_planes[0].reserved[5] = fill_buf_done->frame_height;
+		if (!(fill_buf_done->flags1 &
+			HAL_BUFFERFLAG_TIMESTAMPINVALID) &&
+			fill_buf_done->filled_len1) {
+			int64_t time_usec = fill_buf_done->timestamp_hi;
+			time_usec = (time_usec << 32) |
+				fill_buf_done->timestamp_lo;
+			vb->v4l2_buf.timestamp =
+				ns_to_timeval(time_usec * NSEC_PER_USEC);
+				msm_comm_update_clocks(inst, time_usec);
+		}
+		vb->v4l2_buf.flags = 0;
+
+		if (fill_buf_done->flags1 & HAL_BUFFERFLAG_EOS)
+			vb->v4l2_buf.flags |= V4L2_BUF_FLAG_EOS;
+		if (fill_buf_done->flags1 & HAL_BUFFERFLAG_CODECCONFIG)
+			vb->v4l2_buf.flags &= ~V4L2_QCOM_BUF_FLAG_CODECCONFIG;
+		if (fill_buf_done->flags1 & HAL_BUFFERFLAG_SYNCFRAME)
+			vb->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME;
+		if (fill_buf_done->flags1 & HAL_BUFFERFLAG_EOSEQ)
+			vb->v4l2_buf.flags |= V4L2_QCOM_BUF_FLAG_EOSEQ;
+		switch (fill_buf_done->picture_type) {
+		case HAL_PICTURE_IDR:
+		case HAL_PICTURE_I:
+			vb->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME;
+			break;
+		case HAL_PICTURE_P:
+			vb->v4l2_buf.flags |= V4L2_BUF_FLAG_PFRAME;
+			break;
+		case HAL_PICTURE_B:
+			vb->v4l2_buf.flags |= V4L2_BUF_FLAG_BFRAME;
+			break;
+		case HAL_FRAME_NOTCODED:
+		case HAL_UNUSED_PICT:
+			/* Do we need to care about these? */
+		case HAL_FRAME_YUV:
+			break;
+		default:
+			break;
+		}
+		inst->count.fbd++;
+		if (fill_buf_done->filled_len1)
+			msm_vidc_debugfs_update(inst,
+				MSM_VIDC_DEBUGFS_EVENT_FBD);
+
+		dprintk(VIDC_DBG, "Filled length = %d; flags %x\n",
+				vb->v4l2_planes[0].bytesused,
+				vb->v4l2_buf.flags);
+		mutex_lock(&inst->bufq[CAPTURE_PORT].lock);
+		vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+		mutex_unlock(&inst->bufq[CAPTURE_PORT].lock);
+		wake_up(&inst->kernel_event_queue);
+	} else {
+		/*
+		 * FIXME:
+		 * Special handling for EOS case: if we sent a 0 length input
+		 * buf with EOS set, Venus doesn't return a valid output buffer.
+		 * So pick up a random buffer that's with us, and send it to
+		 * v4l2 client with EOS flag set.
+		 *
+		 * This would normally be OK unless client decides to send
+		 * frames even after EOS.
+		 *
+		 * This should be fixed in upcoming versions of firmware
+		 */
+		if (fill_buf_done->flags1 & HAL_BUFFERFLAG_EOS
+			&& fill_buf_done->filled_len1 == 0) {
+			struct buf_queue *q = &inst->bufq[CAPTURE_PORT];
+
+			if (!list_empty(&q->vb2_bufq.queued_list)) {
+				vb = list_first_entry(&q->vb2_bufq.queued_list,
+					struct vb2_buffer, queued_entry);
+				vb->v4l2_planes[0].bytesused = 0;
+				vb->v4l2_buf.flags |= V4L2_BUF_FLAG_EOS;
+				mutex_lock(&q->lock);
+				vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+				mutex_unlock(&q->lock);
+			}
+
+		}
+	}
+}
+
+static void  handle_seq_hdr_done(enum command_response cmd, void *data)
+{
+	struct msm_vidc_cb_data_done *response = data;
+	struct msm_vidc_inst *inst;
+	struct vb2_buffer *vb;
+	struct vidc_hal_fbd *fill_buf_done;
+	if (!response) {
+		dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
+		return;
+	}
+	inst = (struct msm_vidc_inst *)response->session_id;
+	fill_buf_done = (struct vidc_hal_fbd *)&response->output_done;
+	vb = get_vb_from_device_addr(&inst->bufq[CAPTURE_PORT],
+		(u32)fill_buf_done->packet_buffer1);
+	if (!vb) {
+		dprintk(VIDC_ERR,
+				"Failed to find video buffer for seq_hdr_done");
+		return;
+	}
+
+	vb->v4l2_planes[0].bytesused = fill_buf_done->filled_len1;
+
+	vb->v4l2_buf.flags = V4L2_QCOM_BUF_FLAG_CODECCONFIG;
+
+	dprintk(VIDC_DBG, "Filled length = %d; flags %x\n",
+				vb->v4l2_planes[0].bytesused,
+				vb->v4l2_buf.flags);
+	mutex_lock(&inst->bufq[CAPTURE_PORT].lock);
+	vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+	mutex_unlock(&inst->bufq[CAPTURE_PORT].lock);
+}
+
+void handle_cmd_response(enum command_response cmd, void *data)
+{
+	dprintk(VIDC_DBG, "Command response = %d\n", cmd);
+	switch (cmd) {
+	case SYS_INIT_DONE:
+		handle_sys_init_done(cmd, data);
+		break;
+	case RELEASE_RESOURCE_DONE:
+		handle_sys_release_res_done(cmd, data);
+		break;
+	case SESSION_INIT_DONE:
+		handle_session_init_done(cmd, data);
+		break;
+	case SESSION_PROPERTY_INFO:
+		handle_session_prop_info(cmd, data);
+		break;
+	case SESSION_LOAD_RESOURCE_DONE:
+		handle_load_resource_done(cmd, data);
+		break;
+	case SESSION_START_DONE:
+		handle_start_done(cmd, data);
+		break;
+	case SESSION_ETB_DONE:
+		handle_ebd(cmd, data);
+		break;
+	case SESSION_FTB_DONE:
+		handle_fbd(cmd, data);
+		break;
+	case SESSION_STOP_DONE:
+		handle_stop_done(cmd, data);
+		break;
+	case SESSION_RELEASE_RESOURCE_DONE:
+		handle_release_res_done(cmd, data);
+		break;
+	case SESSION_END_DONE:
+		handle_session_close(cmd, data);
+		break;
+	case VIDC_EVENT_CHANGE:
+		handle_event_change(cmd, data);
+		break;
+	case SESSION_FLUSH_DONE:
+		handle_session_flush(cmd, data);
+		break;
+	case SESSION_GET_SEQ_HDR_DONE:
+		handle_seq_hdr_done(cmd, data);
+		break;
+	case SYS_WATCHDOG_TIMEOUT:
+		handle_sys_watchdog_timeout(cmd, data);
+		break;
+	case SYS_ERROR:
+		handle_sys_error(cmd, data);
+		break;
+	case SESSION_ERROR:
+		handle_session_error(cmd, data);
+		break;
+	case SESSION_RELEASE_BUFFER_DONE:
+		handle_session_release_buf_done(cmd, data);
+		break;
+	default:
+		dprintk(VIDC_ERR, "response unhandled\n");
+		break;
+	}
+}
+
+static int msm_comm_scale_clocks(struct msm_vidc_core *core)
+{
+	int num_mbs_per_sec;
+	int rc = 0;
+	struct hfi_device *hdev;
+	if (!core) {
+		dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, core);
+		return -EINVAL;
+	}
+
+	hdev = core->device;
+	if (!hdev) {
+		dprintk(VIDC_ERR, "%s Invalid device handle: %p\n",
+			__func__, hdev);
+		return -EINVAL;
+	}
+	num_mbs_per_sec = msm_comm_get_load(core, MSM_VIDC_ENCODER);
+	num_mbs_per_sec += msm_comm_get_load(core, MSM_VIDC_DECODER);
+
+	dprintk(VIDC_INFO, "num_mbs_per_sec = %d\n", num_mbs_per_sec);
+	rc = call_hfi_op(hdev, scale_clocks,
+		hdev->hfi_device_data, num_mbs_per_sec);
+	if (rc)
+		dprintk(VIDC_ERR, "Failed to set clock rate: %d\n", rc);
+	return rc;
+}
+
+void msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst)
+{
+	struct msm_vidc_core *core;
+	struct hfi_device *hdev;
+
+	if (!inst || !inst->core || !inst->core->device) {
+		dprintk(VIDC_ERR, "%s Invalid params\n", __func__);
+		return;
+	}
+	core = inst->core;
+	hdev = core->device;
+
+	if (msm_comm_scale_clocks(core)) {
+		dprintk(VIDC_WARN,
+				"Failed to scale clocks. Performance might be impacted\n");
+	}
+	if (msm_comm_scale_bus(core, inst->session_type, DDR_MEM)) {
+		dprintk(VIDC_WARN,
+				"Failed to scale DDR bus. Performance might be impacted\n");
+	}
+	if (call_hfi_op(hdev, is_ocmem_present, hdev->hfi_device_data)) {
+		if (msm_comm_scale_bus(core, inst->session_type,
+					OCMEM_MEM))
+			dprintk(VIDC_WARN,
+					"Failed to scale OCMEM bus. Performance might be impacted\n");
+	}
+}
+
+static inline unsigned long get_ocmem_requirement(u32 height, u32 width)
+{
+	int num_mbs = 0;
+	num_mbs = GET_NUM_MBS(height, width);
+	/*TODO: This should be changes once the numbers are
+	 * available from firmware*/
+	return 512 * 1024;
+}
+
+static int msm_comm_unset_ocmem(struct msm_vidc_core *core)
+{
+	int rc = 0;
+	struct hfi_device *hdev;
+
+	if (!core || !core->device) {
+		dprintk(VIDC_ERR, "%s invalid parameters", __func__);
+		return -EINVAL;
+	}
+	hdev = core->device;
+
+	if (core->state == VIDC_CORE_INVALID) {
+		dprintk(VIDC_ERR,
+				"Core is in bad state. Cannot unset ocmem\n");
+		return -EIO;
+	}
+
+	init_completion(
+		&core->completions[SYS_MSG_INDEX(RELEASE_RESOURCE_DONE)]);
+
+	rc = call_hfi_op(hdev, unset_ocmem, hdev->hfi_device_data);
+	if (rc) {
+		dprintk(VIDC_INFO, "Failed to unset OCMEM on driver\n");
+		goto release_ocmem_failed;
+	}
+	rc = wait_for_completion_timeout(
+		&core->completions[SYS_MSG_INDEX(RELEASE_RESOURCE_DONE)],
+		msecs_to_jiffies(HW_RESPONSE_TIMEOUT));
+	if (!rc) {
+		dprintk(VIDC_ERR, "Wait interrupted or timeout: %d\n", rc);
+		rc = -EIO;
+	}
+release_ocmem_failed:
+	return rc;
+}
+
+static int msm_comm_init_core_done(struct msm_vidc_inst *inst)
+{
+	struct msm_vidc_core *core = inst->core;
+	int rc = 0;
+	mutex_lock(&core->sync_lock);
+	if (core->state >= VIDC_CORE_INIT_DONE) {
+		dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n",
+				core->id, core->state);
+		goto core_already_inited;
+	}
+	dprintk(VIDC_DBG, "Waiting for SYS_INIT_DONE\n");
+	rc = wait_for_completion_timeout(
+		&core->completions[SYS_MSG_INDEX(SYS_INIT_DONE)],
+		msecs_to_jiffies(HW_RESPONSE_TIMEOUT));
+	if (!rc) {
+		dprintk(VIDC_ERR, "Wait interrupted or timeout: %d\n", rc);
+		rc = -EIO;
+		goto exit;
+	} else {
+		mutex_lock(&core->lock);
+		core->state = VIDC_CORE_INIT_DONE;
+		mutex_unlock(&core->lock);
+	}
+	dprintk(VIDC_DBG, "SYS_INIT_DONE!!!\n");
+core_already_inited:
+	change_inst_state(inst, MSM_VIDC_CORE_INIT_DONE);
+	rc = 0;
+exit:
+	mutex_unlock(&core->sync_lock);
+	return rc;
+}
+
+static int msm_comm_init_core(struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	struct msm_vidc_core *core = inst->core;
+	struct hfi_device *hdev;
+
+	if (!core || !core->device)
+		return -EINVAL;
+	hdev = core->device;
+
+	mutex_lock(&core->sync_lock);
+	if (core->state >= VIDC_CORE_INIT) {
+		dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n",
+				core->id, core->state);
+		goto core_already_inited;
+	}
+
+	rc = msm_comm_scale_bus(core, inst->session_type, DDR_MEM);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to scale DDR bus: %d\n", rc);
+		goto fail_scale_bus;
+	}
+
+	rc = call_hfi_op(hdev, load_fw, hdev->hfi_device_data);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to load video firmware\n");
+		goto fail_load_fw;
+	}
+	rc = msm_comm_scale_clocks(core);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to scale clocks: %d\n", rc);
+		goto fail_core_init;
+	}
+
+	init_completion(&core->completions[SYS_MSG_INDEX(SYS_INIT_DONE)]);
+	rc = call_hfi_op(hdev, core_init, hdev->hfi_device_data);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to init core, id = %d\n", core->id);
+		goto fail_core_init;
+	}
+	mutex_lock(&core->lock);
+	core->state = VIDC_CORE_INIT;
+	mutex_unlock(&core->lock);
+core_already_inited:
+	change_inst_state(inst, MSM_VIDC_CORE_INIT);
+	mutex_unlock(&core->sync_lock);
+	return rc;
+fail_core_init:
+	call_hfi_op(hdev, unload_fw, hdev->hfi_device_data);
+fail_load_fw:
+	msm_comm_unvote_buses(core, DDR_MEM);
+fail_scale_bus:
+	mutex_unlock(&core->sync_lock);
+	return rc;
+}
+
+static int msm_vidc_deinit_core(struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	struct msm_vidc_core *core;
+	struct hfi_device *hdev;
+
+	if (!inst || !inst->core || !inst->core->device) {
+		dprintk(VIDC_ERR, "%s invalid parameters", __func__);
+		return -EINVAL;
+	}
+
+	core = inst->core;
+	hdev = core->device;
+
+	mutex_lock(&core->sync_lock);
+	if (core->state == VIDC_CORE_UNINIT) {
+		dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n",
+				core->id, core->state);
+		goto core_already_uninited;
+	}
+	msm_comm_scale_clocks_and_bus(inst);
+	if (list_empty(&core->instances)) {
+		if (inst->state != MSM_VIDC_CORE_INVALID)
+			msm_comm_unset_ocmem(core);
+		call_hfi_op(hdev, free_ocmem, hdev->hfi_device_data);
+		dprintk(VIDC_DBG, "Calling vidc_hal_core_release\n");
+		rc = call_hfi_op(hdev, core_release, hdev->hfi_device_data);
+		if (rc) {
+			dprintk(VIDC_ERR, "Failed to release core, id = %d\n",
+							core->id);
+			goto exit;
+		}
+		mutex_lock(&core->lock);
+		core->state = VIDC_CORE_UNINIT;
+		call_hfi_op(hdev, unload_fw, hdev->hfi_device_data);
+		mutex_unlock(&core->lock);
+		msm_comm_unvote_buses(core, DDR_MEM|OCMEM_MEM);
+	}
+core_already_uninited:
+	change_inst_state(inst, MSM_VIDC_CORE_UNINIT);
+exit:
+	mutex_unlock(&core->sync_lock);
+	return rc;
+}
+
+int msm_comm_force_cleanup(struct msm_vidc_inst *inst)
+{
+	return msm_vidc_deinit_core(inst);
+}
+
+static enum hal_domain get_hal_domain(int session_type)
+{
+	enum hal_domain domain;
+	switch (session_type) {
+	case MSM_VIDC_ENCODER:
+		domain = HAL_VIDEO_DOMAIN_ENCODER;
+		break;
+	case MSM_VIDC_DECODER:
+		domain = HAL_VIDEO_DOMAIN_DECODER;
+		break;
+	default:
+		dprintk(VIDC_ERR, "Wrong domain\n");
+		domain = HAL_UNUSED_DOMAIN;
+		break;
+	}
+	return domain;
+}
+
+static enum hal_video_codec get_hal_codec_type(int fourcc)
+{
+	enum hal_video_codec codec;
+	dprintk(VIDC_DBG, "codec is 0x%x", fourcc);
+	switch (fourcc) {
+	case V4L2_PIX_FMT_H264:
+	case V4L2_PIX_FMT_H264_NO_SC:
+		codec = HAL_VIDEO_CODEC_H264;
+		break;
+	case V4L2_PIX_FMT_H263:
+		codec = HAL_VIDEO_CODEC_H263;
+		break;
+	case V4L2_PIX_FMT_MPEG1:
+		codec = HAL_VIDEO_CODEC_MPEG1;
+		break;
+	case V4L2_PIX_FMT_MPEG2:
+		codec = HAL_VIDEO_CODEC_MPEG2;
+		break;
+	case V4L2_PIX_FMT_MPEG4:
+		codec = HAL_VIDEO_CODEC_MPEG4;
+		break;
+	case V4L2_PIX_FMT_VC1_ANNEX_G:
+	case V4L2_PIX_FMT_VC1_ANNEX_L:
+		codec = HAL_VIDEO_CODEC_VC1;
+		break;
+	case V4L2_PIX_FMT_VP8:
+		codec = HAL_VIDEO_CODEC_VP8;
+		break;
+	case V4L2_PIX_FMT_DIVX_311:
+		codec = HAL_VIDEO_CODEC_DIVX_311;
+		break;
+	case V4L2_PIX_FMT_DIVX:
+		codec = HAL_VIDEO_CODEC_DIVX;
+		break;
+		/*HAL_VIDEO_CODEC_MVC
+		  HAL_VIDEO_CODEC_SPARK
+		  HAL_VIDEO_CODEC_VP6
+		  HAL_VIDEO_CODEC_VP7*/
+	default:
+		dprintk(VIDC_ERR, "Wrong codec: %d\n", fourcc);
+		codec = HAL_UNUSED_CODEC;
+	}
+	return codec;
+}
+
+static int msm_comm_session_init(int flipped_state,
+	struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	int fourcc = 0;
+	struct hfi_device *hdev;
+
+	if (!inst || !inst->core || !inst->core->device) {
+		dprintk(VIDC_ERR, "%s invalid parameters", __func__);
+		return -EINVAL;
+	}
+	hdev = inst->core->device;
+
+	if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_OPEN)) {
+		dprintk(VIDC_INFO, "inst: %p is already in state: %d\n",
+						inst, inst->state);
+		goto exit;
+	}
+	if (inst->session_type == MSM_VIDC_DECODER) {
+		fourcc = inst->fmts[OUTPUT_PORT]->fourcc;
+	} else if (inst->session_type == MSM_VIDC_ENCODER) {
+		fourcc = inst->fmts[CAPTURE_PORT]->fourcc;
+	} else {
+		dprintk(VIDC_ERR, "Invalid session\n");
+		return -EINVAL;
+	}
+	init_completion(
+		&inst->completions[SESSION_MSG_INDEX(SESSION_INIT_DONE)]);
+	inst->session = call_hfi_op(hdev, session_init, hdev->hfi_device_data,
+			(u32) inst, get_hal_domain(inst->session_type),
+			get_hal_codec_type(fourcc));
+	if (!inst->session) {
+		dprintk(VIDC_ERR,
+			"Failed to call session init for: %d, %d, %d, %d\n",
+			(int)inst->core->device, (int)inst,
+			inst->session_type, fourcc);
+		goto exit;
+	}
+	inst->ftb_count = 0;
+	change_inst_state(inst, MSM_VIDC_OPEN);
+exit:
+	return rc;
+}
+
+static int msm_vidc_load_resources(int flipped_state,
+	struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	u32 ocmem_sz = 0;
+	struct hfi_device *hdev;
+	int num_mbs_per_sec = 0;
+
+	if (!inst || !inst->core || !inst->core->device) {
+		dprintk(VIDC_ERR, "%s invalid parameters", __func__);
+		return -EINVAL;
+	}
+	num_mbs_per_sec = msm_comm_get_load(inst->core, MSM_VIDC_DECODER);
+	num_mbs_per_sec += msm_comm_get_load(inst->core, MSM_VIDC_ENCODER);
+	if (num_mbs_per_sec > MAX_LOAD) {
+		dprintk(VIDC_ERR, "HW is overloaded, needed:%d max: %d\n",
+			num_mbs_per_sec, MAX_LOAD);
+		return -ENOMEM;
+	}
+	hdev = inst->core->device;
+
+	if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_LOAD_RESOURCES)) {
+		dprintk(VIDC_INFO, "inst: %p is already in state: %d\n",
+						inst, inst->state);
+		goto exit;
+	}
+	ocmem_sz = get_ocmem_requirement(inst->prop.height, inst->prop.width);
+	rc = msm_comm_scale_bus(inst->core, inst->session_type, OCMEM_MEM);
+	if (!rc) {
+		mutex_lock(&inst->core->sync_lock);
+		rc = call_hfi_op(hdev, alloc_ocmem, hdev->hfi_device_data,
+				ocmem_sz);
+		mutex_unlock(&inst->core->sync_lock);
+		if (rc) {
+			dprintk(VIDC_WARN,
+			"Failed to allocate OCMEM. Performance will be impacted\n");
+			msm_comm_unvote_buses(inst->core, OCMEM_MEM);
+		}
+	} else {
+		dprintk(VIDC_WARN,
+		"Failed to vote for OCMEM BW. Performance will be impacted\n");
+	}
+	rc = call_hfi_op(hdev, session_load_res, (void *) inst->session);
+	if (rc) {
+		dprintk(VIDC_ERR,
+			"Failed to send load resources\n");
+		goto exit;
+	}
+	change_inst_state(inst, MSM_VIDC_LOAD_RESOURCES);
+exit:
+	return rc;
+}
+
+static int msm_vidc_start(int flipped_state, struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	struct hfi_device *hdev;
+
+	if (!inst || !inst->core || !inst->core->device) {
+		dprintk(VIDC_ERR, "%s invalid parameters", __func__);
+		return -EINVAL;
+	}
+
+	hdev = inst->core->device;
+
+	if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_START)) {
+		dprintk(VIDC_INFO,
+			"inst: %p is already in state: %d\n",
+			inst, inst->state);
+		goto exit;
+	}
+	init_completion(
+		&inst->completions[SESSION_MSG_INDEX(SESSION_START_DONE)]);
+	rc = call_hfi_op(hdev, session_start, (void *) inst->session);
+	if (rc) {
+		dprintk(VIDC_ERR,
+			"Failed to send start\n");
+		goto exit;
+	}
+	change_inst_state(inst, MSM_VIDC_START);
+exit:
+	return rc;
+}
+
+static int msm_vidc_stop(int flipped_state, struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	struct hfi_device *hdev;
+
+	if (!inst || !inst->core || !inst->core->device) {
+		dprintk(VIDC_ERR, "%s invalid parameters", __func__);
+		return -EINVAL;
+	}
+	hdev = inst->core->device;
+
+	if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_STOP)) {
+		dprintk(VIDC_INFO,
+			"inst: %p is already in state: %d\n",
+			inst, inst->state);
+		goto exit;
+	}
+	dprintk(VIDC_DBG, "Send Stop to hal\n");
+	init_completion(
+		&inst->completions[SESSION_MSG_INDEX(SESSION_STOP_DONE)]);
+	rc = call_hfi_op(hdev, session_stop, (void *) inst->session);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to send stop\n");
+		goto exit;
+	}
+	change_inst_state(inst, MSM_VIDC_STOP);
+exit:
+	return rc;
+}
+
+static int msm_vidc_release_res(int flipped_state, struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	struct hfi_device *hdev;
+
+	if (!inst || !inst->core || !inst->core->device) {
+		dprintk(VIDC_ERR, "%s invalid parameters", __func__);
+		return -EINVAL;
+	}
+	hdev = inst->core->device;
+
+	if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_RELEASE_RESOURCES)) {
+		dprintk(VIDC_INFO,
+			"inst: %p is already in state: %d\n",
+			inst, inst->state);
+		goto exit;
+	}
+	dprintk(VIDC_DBG,
+		"Send release res to hal\n");
+	init_completion(
+	&inst->completions[SESSION_MSG_INDEX(SESSION_RELEASE_RESOURCE_DONE)]);
+	rc = call_hfi_op(hdev, session_release_res, (void *) inst->session);
+	if (rc) {
+		dprintk(VIDC_ERR,
+			"Failed to send release resources\n");
+		goto exit;
+	}
+	change_inst_state(inst, MSM_VIDC_RELEASE_RESOURCES);
+exit:
+	return rc;
+}
+
+static int msm_comm_session_close(int flipped_state,
+			struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	struct hfi_device *hdev;
+
+	if (!inst || !inst->core || !inst->core->device) {
+		dprintk(VIDC_ERR, "%s invalid params", __func__);
+		return -EINVAL;
+	}
+	hdev = inst->core->device;
+	if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_CLOSE)) {
+		dprintk(VIDC_INFO,
+			"inst: %p is already in state: %d\n",
+						inst, inst->state);
+		goto exit;
+	}
+	dprintk(VIDC_DBG,
+		"Send session close to hal\n");
+	init_completion(
+		&inst->completions[SESSION_MSG_INDEX(SESSION_END_DONE)]);
+	rc = call_hfi_op(hdev, session_end, (void *) inst->session);
+	if (rc) {
+		dprintk(VIDC_ERR,
+			"Failed to send close\n");
+		goto exit;
+	}
+	change_inst_state(inst, MSM_VIDC_OPEN);
+exit:
+	return rc;
+}
+
+static int get_flipped_state(int present_state,
+	int desired_state)
+{
+	int flipped_state = present_state;
+	if (flipped_state < MSM_VIDC_STOP
+			&& desired_state > MSM_VIDC_STOP) {
+		flipped_state = MSM_VIDC_STOP + (MSM_VIDC_STOP - flipped_state);
+		flipped_state &= 0xFFFE;
+		flipped_state = flipped_state - 1;
+	} else if (flipped_state > MSM_VIDC_STOP
+			&& desired_state < MSM_VIDC_STOP) {
+		flipped_state = MSM_VIDC_STOP -
+			(flipped_state - MSM_VIDC_STOP + 1);
+		flipped_state &= 0xFFFE;
+		flipped_state = flipped_state - 1;
+	}
+	return flipped_state;
+}
+
+struct hal_buffer_requirements *get_buff_req_buffer(
+		struct msm_vidc_inst *inst, enum hal_buffer buffer_type)
+{
+	int i;
+	for (i = 0; i < HAL_BUFFER_MAX; i++) {
+		if (inst->buff_req.buffer[i].buffer_type == buffer_type)
+			return &inst->buff_req.buffer[i];
+	}
+	return NULL;
+}
+
+static int set_scratch_buffers(struct msm_vidc_inst *inst,
+	enum hal_buffer buffer_type)
+{
+	int rc = 0;
+	struct msm_smem *handle;
+	struct internal_buf *binfo;
+	struct vidc_buffer_addr_info buffer_info;
+	u32 smem_flags = 0;
+	int domain;
+	struct hal_buffer_requirements *scratch_buf;
+	int i;
+	struct hfi_device *hdev;
+
+	hdev = inst->core->device;
+
+	scratch_buf = get_buff_req_buffer(inst, buffer_type);
+	if (!scratch_buf) {
+		dprintk(VIDC_DBG,
+			"This scratch buffer not required, buffer_type: %x\n",
+			buffer_type);
+		return 0;
+	}
+	dprintk(VIDC_DBG,
+		"scratch: num = %d, size = %d\n",
+		scratch_buf->buffer_count_actual,
+		scratch_buf->buffer_size);
+
+	if (inst->mode == VIDC_SECURE) {
+		domain = call_hfi_op(hdev, get_domain,
+				hdev->hfi_device_data, CP_MAP);
+		smem_flags |= SMEM_SECURE;
+	} else
+		domain = call_hfi_op(hdev, get_domain,
+				hdev->hfi_device_data, NS_MAP);
+
+	if (scratch_buf->buffer_size) {
+		for (i = 0; i < scratch_buf->buffer_count_actual;
+				i++) {
+			handle = msm_smem_alloc(inst->mem_client,
+				scratch_buf->buffer_size, 1, smem_flags,
+				domain, 0, 0);
+			if (!handle) {
+				dprintk(VIDC_ERR,
+					"Failed to allocate scratch memory\n");
+				rc = -ENOMEM;
+				goto err_no_mem;
+			}
+			rc = msm_smem_cache_operations(inst->mem_client,
+					handle, SMEM_CACHE_CLEAN);
+			if (rc) {
+				dprintk(VIDC_WARN,
+				"Failed to clean cache may cause undefined behavior\n");
+			}
+			binfo = kzalloc(sizeof(*binfo), GFP_KERNEL);
+			if (!binfo) {
+				dprintk(VIDC_ERR, "Out of memory\n");
+				rc = -ENOMEM;
+				goto fail_kzalloc;
+			}
+			binfo->handle = handle;
+			buffer_info.buffer_size = scratch_buf->buffer_size;
+			buffer_info.buffer_type = buffer_type;
+			binfo->buffer_type = buffer_type;
+			buffer_info.num_buffers = 1;
+			buffer_info.align_device_addr = handle->device_addr;
+			dprintk(VIDC_DBG, "Scratch buffer address: %x",
+					buffer_info.align_device_addr);
+			rc = call_hfi_op(hdev, session_set_buffers,
+				(void *) inst->session, &buffer_info);
+			if (rc) {
+				dprintk(VIDC_ERR,
+					"vidc_hal_session_set_buffers failed");
+				goto fail_set_buffers;
+			}
+			mutex_lock(&inst->lock);
+			list_add_tail(&binfo->list, &inst->internalbufs);
+			mutex_unlock(&inst->lock);
+		}
+	}
+	return rc;
+fail_set_buffers:
+	kfree(binfo);
+fail_kzalloc:
+	msm_smem_free(inst->mem_client, handle);
+err_no_mem:
+	return rc;
+}
+
+static int set_persist_buffers(struct msm_vidc_inst *inst,
+	enum hal_buffer buffer_type)
+{
+	int rc = 0;
+	struct msm_smem *handle;
+	struct internal_buf *binfo;
+	struct vidc_buffer_addr_info buffer_info;
+	u32 smem_flags = 0;
+	int domain;
+	struct hal_buffer_requirements *persist_buf;
+	int i;
+	struct hfi_device *hdev;
+
+	hdev = inst->core->device;
+
+	persist_buf = get_buff_req_buffer(inst, buffer_type);
+	if (!persist_buf) {
+		dprintk(VIDC_DBG,
+			"This persist buffer not required, buffer_type: %x\n",
+			buffer_type);
+		return 0;
+	}
+
+	dprintk(VIDC_DBG,
+		"persist: num = %d, size = %d\n",
+		persist_buf->buffer_count_actual,
+		persist_buf->buffer_size);
+	if (!list_empty(&inst->persistbufs)) {
+		dprintk(VIDC_ERR,
+			"Persist buffers already allocated\n");
+		return rc;
+	}
+
+	if (inst->mode == VIDC_SECURE) {
+		domain = call_hfi_op(hdev, get_domain,
+				hdev->hfi_device_data, CP_MAP);
+		smem_flags |= SMEM_SECURE;
+	} else
+		domain = call_hfi_op(hdev, get_domain,
+				hdev->hfi_device_data, NS_MAP);
+
+	if (persist_buf->buffer_size) {
+		for (i = 0; i < persist_buf->buffer_count_actual; i++) {
+			handle = msm_smem_alloc(inst->mem_client,
+				persist_buf->buffer_size, 1, smem_flags,
+				domain, 0, 0);
+			if (!handle) {
+				dprintk(VIDC_ERR,
+					"Failed to allocate persist memory\n");
+				rc = -ENOMEM;
+				goto err_no_mem;
+			}
+			rc = msm_smem_cache_operations(inst->mem_client,
+					handle, SMEM_CACHE_CLEAN);
+			if (rc) {
+				dprintk(VIDC_WARN,
+				"Failed to clean cache may cause undefined behavior\n");
+			}
+			binfo = kzalloc(sizeof(*binfo), GFP_KERNEL);
+			if (!binfo) {
+				dprintk(VIDC_ERR, "Out of memory\n");
+				rc = -ENOMEM;
+				goto fail_kzalloc;
+			}
+			binfo->handle = handle;
+			buffer_info.buffer_size = persist_buf->buffer_size;
+			buffer_info.buffer_type = buffer_type;
+			binfo->buffer_type = buffer_type;
+			buffer_info.num_buffers = 1;
+			buffer_info.align_device_addr = handle->device_addr;
+			dprintk(VIDC_DBG, "Persist buffer address: %x",
+					buffer_info.align_device_addr);
+			rc = call_hfi_op(hdev, session_set_buffers,
+					(void *) inst->session, &buffer_info);
+			if (rc) {
+				dprintk(VIDC_ERR,
+					"vidc_hal_session_set_buffers failed");
+				goto fail_set_buffers;
+			}
+			mutex_lock(&inst->lock);
+			list_add_tail(&binfo->list, &inst->persistbufs);
+			mutex_unlock(&inst->lock);
+		}
+	}
+	return rc;
+fail_set_buffers:
+	kfree(binfo);
+fail_kzalloc:
+	msm_smem_free(inst->mem_client, handle);
+err_no_mem:
+	return rc;
+}
+
+int msm_comm_try_state(struct msm_vidc_inst *inst, int state)
+{
+	int rc = 0;
+	int flipped_state;
+	struct msm_vidc_core *core;
+	if (!inst) {
+		dprintk(VIDC_ERR,
+				"Invalid instance pointer = %p\n", inst);
+		return -EINVAL;
+	}
+	dprintk(VIDC_DBG,
+			"Trying to move inst: %p from: 0x%x to 0x%x\n",
+			inst, inst->state, state);
+	core = inst->core;
+	if (!core) {
+		dprintk(VIDC_ERR,
+				"Invalid core pointer = %p\n", inst);
+		return -EINVAL;
+	}
+	mutex_lock(&inst->sync_lock);
+	if (inst->state == MSM_VIDC_CORE_INVALID ||
+			core->state == VIDC_CORE_INVALID) {
+		dprintk(VIDC_ERR,
+				"Core is in bad state can't change the state");
+		goto exit;
+	}
+	flipped_state = get_flipped_state(inst->state, state);
+	dprintk(VIDC_DBG,
+			"flipped_state = 0x%x\n", flipped_state);
+	switch (flipped_state) {
+	case MSM_VIDC_CORE_UNINIT_DONE:
+	case MSM_VIDC_CORE_INIT:
+		rc = msm_comm_init_core(inst);
+		if (rc || state <= get_flipped_state(inst->state, state))
+			break;
+	case MSM_VIDC_CORE_INIT_DONE:
+		rc = msm_comm_init_core_done(inst);
+		if (rc || state <= get_flipped_state(inst->state, state))
+			break;
+	case MSM_VIDC_OPEN:
+		rc = msm_comm_session_init(flipped_state, inst);
+		if (rc || state <= get_flipped_state(inst->state, state))
+			break;
+	case MSM_VIDC_OPEN_DONE:
+		rc = wait_for_state(inst, flipped_state, MSM_VIDC_OPEN_DONE,
+			SESSION_INIT_DONE);
+		if (rc || state <= get_flipped_state(inst->state, state))
+			break;
+	case MSM_VIDC_LOAD_RESOURCES:
+		rc = msm_vidc_load_resources(flipped_state, inst);
+		if (rc || state <= get_flipped_state(inst->state, state))
+			break;
+	case MSM_VIDC_LOAD_RESOURCES_DONE:
+	case MSM_VIDC_START:
+		rc = msm_vidc_start(flipped_state, inst);
+		if (rc || state <= get_flipped_state(inst->state, state))
+			break;
+	case MSM_VIDC_START_DONE:
+		rc = wait_for_state(inst, flipped_state, MSM_VIDC_START_DONE,
+				SESSION_START_DONE);
+		if (rc || state <= get_flipped_state(inst->state, state))
+			break;
+	case MSM_VIDC_STOP:
+		rc = msm_vidc_stop(flipped_state, inst);
+		if (rc || state <= get_flipped_state(inst->state, state))
+			break;
+	case MSM_VIDC_STOP_DONE:
+		rc = wait_for_state(inst, flipped_state, MSM_VIDC_STOP_DONE,
+				SESSION_STOP_DONE);
+		if (rc || state <= get_flipped_state(inst->state, state))
+			break;
+		dprintk(VIDC_DBG, "Moving to Stop Done state\n");
+	case MSM_VIDC_RELEASE_RESOURCES:
+		rc = msm_vidc_release_res(flipped_state, inst);
+		if (rc || state <= get_flipped_state(inst->state, state))
+			break;
+	case MSM_VIDC_RELEASE_RESOURCES_DONE:
+		rc = wait_for_state(inst, flipped_state,
+			MSM_VIDC_RELEASE_RESOURCES_DONE,
+			SESSION_RELEASE_RESOURCE_DONE);
+		if (rc || state <= get_flipped_state(inst->state, state))
+			break;
+		dprintk(VIDC_DBG,
+				"Moving to release resources done state\n");
+	case MSM_VIDC_CLOSE:
+		rc = msm_comm_session_close(flipped_state, inst);
+		if (rc || state <= get_flipped_state(inst->state, state))
+			break;
+	case MSM_VIDC_CLOSE_DONE:
+		rc = wait_for_state(inst, flipped_state, MSM_VIDC_CLOSE_DONE,
+				SESSION_END_DONE);
+		if (rc || state <= get_flipped_state(inst->state, state))
+			break;
+	case MSM_VIDC_CORE_UNINIT:
+		dprintk(VIDC_DBG, "Sending core uninit\n");
+		rc = msm_vidc_deinit_core(inst);
+		if (rc || state == get_flipped_state(inst->state, state))
+			break;
+	default:
+		dprintk(VIDC_ERR, "State not recognized\n");
+		rc = -EINVAL;
+		break;
+	}
+exit:
+	mutex_unlock(&inst->sync_lock);
+	if (rc)
+		dprintk(VIDC_ERR,
+				"Failed to move from state: %d to %d\n",
+				inst->state, state);
+	return rc;
+}
+int msm_comm_qbuf(struct vb2_buffer *vb)
+{
+	int rc = 0;
+	struct vb2_queue *q;
+	struct msm_vidc_inst *inst;
+	struct vb2_buf_entry *entry;
+	struct vidc_frame_data frame_data;
+	struct msm_vidc_core *core;
+	struct hfi_device *hdev;
+	q = vb->vb2_queue;
+	inst = q->drv_priv;
+	if (!inst || !vb) {
+		dprintk(VIDC_ERR, "Invalid input: %p, %p\n", inst, vb);
+		return -EINVAL;
+	}
+	core = inst->core;
+	if (!core) {
+		dprintk(VIDC_ERR,
+			"Invalid input: %p, %p, %p\n", inst, core, vb);
+		return -EINVAL;
+	}
+	hdev = core->device;
+	if (!hdev) {
+		dprintk(VIDC_ERR, "Invalid input: %p", hdev);
+		return -EINVAL;
+	}
+
+	if (inst->state == MSM_VIDC_CORE_INVALID ||
+		core->state == VIDC_CORE_INVALID) {
+		dprintk(VIDC_ERR, "Core is in bad state. Can't Queue\n");
+		return -EINVAL;
+	}
+	if (inst->state != MSM_VIDC_START_DONE) {
+			entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+			if (!entry) {
+				dprintk(VIDC_ERR, "Out of memory\n");
+				goto err_no_mem;
+			}
+			entry->vb = vb;
+			mutex_lock(&inst->sync_lock);
+			list_add_tail(&entry->list, &inst->pendingq);
+			mutex_unlock(&inst->sync_lock);
+	} else {
+		int64_t time_usec = timeval_to_ns(&vb->v4l2_buf.timestamp);
+		do_div(time_usec, NSEC_PER_USEC);
+		memset(&frame_data, 0 , sizeof(struct vidc_frame_data));
+		frame_data.alloc_len = vb->v4l2_planes[0].length;
+		frame_data.filled_len = vb->v4l2_planes[0].bytesused;
+		frame_data.device_addr = vb->v4l2_planes[0].m.userptr;
+		frame_data.timestamp = time_usec;
+		frame_data.flags = 0;
+		frame_data.clnt_data = (u32)vb;
+		if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+			frame_data.buffer_type = HAL_BUFFER_INPUT;
+			if (vb->v4l2_buf.flags & V4L2_BUF_FLAG_EOS) {
+				frame_data.flags |= HAL_BUFFERFLAG_EOS;
+				dprintk(VIDC_DBG,
+					"Received EOS on output capability\n");
+			}
+
+			if (vb->v4l2_buf.flags &
+					V4L2_QCOM_BUF_FLAG_CODECCONFIG) {
+				frame_data.flags |= HAL_BUFFERFLAG_CODECCONFIG;
+				dprintk(VIDC_DBG,
+					"Received CODECCONFIG on output cap\n");
+			}
+			if (vb->v4l2_buf.flags &
+				V4L2_QCOM_BUF_TIMESTAMP_INVALID)
+				frame_data.timestamp = LLONG_MAX;
+			dprintk(VIDC_DBG,
+				"Sending etb to hal: Alloc: %d :filled: %d\n",
+				frame_data.alloc_len, frame_data.filled_len);
+			rc = call_hfi_op(hdev, session_etb, (void *)
+					inst->session, &frame_data);
+			if (!rc)
+				msm_vidc_debugfs_update(inst,
+					MSM_VIDC_DEBUGFS_EVENT_ETB);
+			dprintk(VIDC_DBG, "Sent etb to HAL\n");
+		} else if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+			struct vidc_seq_hdr seq_hdr;
+			int extra_idx = 0;
+			frame_data.filled_len = 0;
+			frame_data.offset = 0;
+			frame_data.alloc_len = vb->v4l2_planes[0].length;
+			frame_data.buffer_type = HAL_BUFFER_OUTPUT;
+			extra_idx =
+			EXTRADATA_IDX(inst->fmts[CAPTURE_PORT]->num_planes);
+			if (extra_idx && (extra_idx < VIDEO_MAX_PLANES) &&
+				vb->v4l2_planes[extra_idx].m.userptr)
+				frame_data.extradata_addr =
+					vb->v4l2_planes[extra_idx].m.userptr;
+			dprintk(VIDC_DBG,
+				"Sending ftb to hal: Alloc: %d :filled: %d",
+				frame_data.alloc_len, frame_data.filled_len);
+			dprintk(VIDC_DBG,
+				" extradata_addr: %d\n",
+				frame_data.extradata_addr);
+			if (!inst->ftb_count &&
+			   inst->session_type == MSM_VIDC_ENCODER) {
+				seq_hdr.seq_hdr = (u8 *) vb->v4l2_planes[0].
+					m.userptr;
+				seq_hdr.seq_hdr_len = vb->v4l2_planes[0].length;
+				rc = call_hfi_op(hdev, session_get_seq_hdr,
+					(void *) inst->session, &seq_hdr);
+				if (!rc) {
+					inst->vb2_seq_hdr = vb;
+					dprintk(VIDC_DBG, "Seq_hdr: %p\n",
+						inst->vb2_seq_hdr);
+				}
+			} else {
+				rc = call_hfi_op(hdev, session_ftb,
+					(void *) inst->session, &frame_data);
+			if (!rc)
+				msm_vidc_debugfs_update(inst,
+					MSM_VIDC_DEBUGFS_EVENT_FTB);
+			}
+			inst->ftb_count++;
+		} else {
+			dprintk(VIDC_ERR,
+				"This capability is not supported: %d\n",
+				q->type);
+			rc = -EINVAL;
+		}
+	}
+	if (rc)
+		dprintk(VIDC_ERR, "Failed to queue buffer\n");
+err_no_mem:
+	return rc;
+}
+
+int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	struct hfi_device *hdev;
+
+	if (!inst || !inst->core || !inst->core->device) {
+		dprintk(VIDC_ERR, "%s invalid parameters", __func__);
+		return -EINVAL;
+	}
+	hdev = inst->core->device;
+
+	mutex_lock(&inst->sync_lock);
+	if (inst->state < MSM_VIDC_OPEN_DONE || inst->state >= MSM_VIDC_CLOSE) {
+		dprintk(VIDC_ERR,
+			"Not in proper state to query buffer requirements\n");
+		rc = -EAGAIN;
+		goto exit;
+	}
+	init_completion(
+		&inst->completions[SESSION_MSG_INDEX(SESSION_PROPERTY_INFO)]);
+	rc = call_hfi_op(hdev, session_get_buf_req, (void *) inst->session);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to get property\n");
+		goto exit;
+	}
+	rc = wait_for_completion_timeout(
+		&inst->completions[SESSION_MSG_INDEX(SESSION_PROPERTY_INFO)],
+		msecs_to_jiffies(HW_RESPONSE_TIMEOUT));
+	if (!rc) {
+		dprintk(VIDC_ERR,
+			"Wait interrupted or timeout: %d\n", rc);
+		rc = -EIO;
+		goto exit;
+	}
+	rc = 0;
+exit:
+	mutex_unlock(&inst->sync_lock);
+	return rc;
+}
+
+int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst)
+{
+	struct msm_smem *handle;
+	struct list_head *ptr, *next;
+	struct internal_buf *buf;
+	struct vidc_buffer_addr_info buffer_info;
+	int rc = 0;
+	struct msm_vidc_core *core;
+	struct hfi_device *hdev;
+	if (!inst) {
+		dprintk(VIDC_ERR,
+				"Invalid instance pointer = %p\n", inst);
+		return -EINVAL;
+	}
+	core = inst->core;
+	if (!core) {
+		dprintk(VIDC_ERR,
+				"Invalid core pointer = %p\n", core);
+		return -EINVAL;
+	}
+	hdev = core->device;
+	if (!hdev) {
+		dprintk(VIDC_ERR, "Invalid device pointer = %p\n", hdev);
+		return -EINVAL;
+	}
+	mutex_lock(&inst->lock);
+	if (!list_empty(&inst->internalbufs)) {
+		list_for_each_safe(ptr, next, &inst->internalbufs) {
+			buf = list_entry(ptr, struct internal_buf,
+					list);
+			handle = buf->handle;
+			buffer_info.buffer_size = handle->size;
+			buffer_info.buffer_type = buf->buffer_type;
+			buffer_info.num_buffers = 1;
+			buffer_info.align_device_addr = handle->device_addr;
+			if (inst->state != MSM_VIDC_CORE_INVALID &&
+					core->state != VIDC_CORE_INVALID) {
+				buffer_info.response_required = true;
+				init_completion(
+				   &inst->completions[SESSION_MSG_INDEX
+				   (SESSION_RELEASE_BUFFER_DONE)]);
+				rc = call_hfi_op(hdev, session_release_buffers,
+					(void *)inst->session, &buffer_info);
+				if (rc)
+					dprintk(VIDC_WARN,
+						"Rel scrtch buf fail:0x%x, %d",
+						buffer_info.align_device_addr,
+						buffer_info.buffer_size);
+				mutex_unlock(&inst->lock);
+				rc = wait_for_sess_signal_receipt(inst,
+					SESSION_RELEASE_BUFFER_DONE);
+				mutex_lock(&inst->lock);
+			}
+			list_del(&buf->list);
+			mutex_unlock(&inst->lock);
+			msm_smem_free(inst->mem_client, buf->handle);
+			kfree(buf);
+			mutex_lock(&inst->lock);
+		}
+	}
+	mutex_unlock(&inst->lock);
+	return rc;
+}
+
+int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst)
+{
+	struct msm_smem *handle;
+	struct list_head *ptr, *next;
+	struct internal_buf *buf;
+	struct vidc_buffer_addr_info buffer_info;
+	int rc = 0;
+	struct msm_vidc_core *core;
+	struct hfi_device *hdev;
+	if (!inst) {
+		dprintk(VIDC_ERR,
+				"Invalid instance pointer = %p\n", inst);
+		return -EINVAL;
+	}
+	core = inst->core;
+	if (!core) {
+		dprintk(VIDC_ERR,
+				"Invalid core pointer = %p\n", core);
+		return -EINVAL;
+	}
+	hdev = core->device;
+	if (!hdev) {
+		dprintk(VIDC_ERR, "Invalid device pointer = %p\n", hdev);
+		return -EINVAL;
+	}
+	mutex_lock(&inst->lock);
+	if (!list_empty(&inst->persistbufs)) {
+		list_for_each_safe(ptr, next, &inst->persistbufs) {
+			buf = list_entry(ptr, struct internal_buf,
+					list);
+			handle = buf->handle;
+			buffer_info.buffer_size = handle->size;
+			buffer_info.buffer_type = buf->buffer_type;
+			buffer_info.num_buffers = 1;
+			buffer_info.align_device_addr = handle->device_addr;
+			if (inst->state != MSM_VIDC_CORE_INVALID &&
+					core->state != VIDC_CORE_INVALID) {
+				buffer_info.response_required = true;
+				init_completion(
+				   &inst->completions[SESSION_MSG_INDEX
+				   (SESSION_RELEASE_BUFFER_DONE)]);
+				rc = call_hfi_op(hdev, session_release_buffers,
+					(void *)inst->session, &buffer_info);
+				if (rc)
+					dprintk(VIDC_WARN,
+						"Rel prst buf fail:0x%x, %d",
+						buffer_info.align_device_addr,
+						buffer_info.buffer_size);
+				mutex_unlock(&inst->lock);
+				rc = wait_for_sess_signal_receipt(inst,
+					SESSION_RELEASE_BUFFER_DONE);
+				mutex_lock(&inst->lock);
+			}
+			list_del(&buf->list);
+			mutex_unlock(&inst->lock);
+			msm_smem_free(inst->mem_client, buf->handle);
+			kfree(buf);
+			mutex_lock(&inst->lock);
+		}
+	}
+	mutex_unlock(&inst->lock);
+	return rc;
+}
+
+int msm_comm_try_set_prop(struct msm_vidc_inst *inst,
+	enum hal_property ptype, void *pdata)
+{
+	int rc = 0;
+	struct hfi_device *hdev;
+	if (!inst) {
+		dprintk(VIDC_ERR, "Invalid input: %p\n", inst);
+		return -EINVAL;
+	}
+
+	if (!inst->core || !inst->core->device) {
+		dprintk(VIDC_ERR, "%s invalid parameters", __func__);
+		return -EINVAL;
+	}
+	hdev = inst->core->device;
+
+	mutex_lock(&inst->sync_lock);
+	if (inst->state < MSM_VIDC_OPEN_DONE || inst->state >= MSM_VIDC_CLOSE) {
+		dprintk(VIDC_ERR, "Not in proper state to set property\n");
+		rc = -EAGAIN;
+		goto exit;
+	}
+	rc = call_hfi_op(hdev, session_set_property, (void *)inst->session,
+			ptype, pdata);
+	if (rc)
+		dprintk(VIDC_ERR, "Failed to set hal property for framesize\n");
+exit:
+	mutex_unlock(&inst->sync_lock);
+	return rc;
+}
+
+int msm_comm_set_scratch_buffers(struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	if (!inst || !inst->core || !inst->core->device) {
+		dprintk(VIDC_ERR, "%s invalid parameters", __func__);
+		return -EINVAL;
+	}
+
+	if (msm_comm_release_scratch_buffers(inst))
+		dprintk(VIDC_WARN, "Failed to release scratch buffers\n");
+
+	rc = set_scratch_buffers(inst, HAL_BUFFER_INTERNAL_SCRATCH);
+	if (rc)
+		goto error;
+
+	rc = set_scratch_buffers(inst, HAL_BUFFER_INTERNAL_SCRATCH_1);
+	if (rc)
+		goto error;
+
+	rc = set_scratch_buffers(inst, HAL_BUFFER_INTERNAL_SCRATCH_2);
+	if (rc)
+		goto error;
+
+	return rc;
+error:
+	msm_comm_release_scratch_buffers(inst);
+	return rc;
+}
+
+int msm_comm_set_persist_buffers(struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	if (!inst || !inst->core || !inst->core->device) {
+		dprintk(VIDC_ERR, "%s invalid parameters", __func__);
+		return -EINVAL;
+	}
+
+	rc = set_persist_buffers(inst, HAL_BUFFER_INTERNAL_PERSIST);
+	if (rc)
+		goto error;
+
+	rc = set_persist_buffers(inst, HAL_BUFFER_INTERNAL_PERSIST_1);
+	if (rc)
+		goto error;
+	return rc;
+error:
+	msm_comm_release_persist_buffers(inst);
+	return rc;
+}
+
+static void msm_comm_flush_in_invalid_state(struct msm_vidc_inst *inst)
+{
+	struct v4l2_event dqevent = {0};
+	struct list_head *ptr, *next;
+	struct vb2_buffer *vb;
+	if (!list_empty(&inst->bufq[CAPTURE_PORT].
+				vb2_bufq.queued_list)) {
+		list_for_each_safe(ptr, next,
+				&inst->bufq[CAPTURE_PORT].
+				vb2_bufq.queued_list) {
+			vb = container_of(ptr,
+					struct vb2_buffer,
+					queued_entry);
+			if (vb) {
+				vb->v4l2_planes[0].bytesused = 0;
+				mutex_lock(&inst->bufq[CAPTURE_PORT].lock);
+				vb2_buffer_done(vb,
+						VB2_BUF_STATE_DONE);
+				mutex_unlock(&inst->bufq[CAPTURE_PORT].lock);
+			}
+		}
+	}
+	if (!list_empty(&inst->bufq[OUTPUT_PORT].
+				vb2_bufq.queued_list)) {
+		list_for_each_safe(ptr, next,
+				&inst->bufq[OUTPUT_PORT].
+				vb2_bufq.queued_list) {
+			vb = container_of(ptr,
+					struct vb2_buffer,
+					queued_entry);
+			if (vb) {
+				vb->v4l2_planes[0].bytesused = 0;
+				mutex_lock(&inst->bufq[OUTPUT_PORT].lock);
+				vb2_buffer_done(vb,
+						VB2_BUF_STATE_DONE);
+				mutex_unlock(&inst->bufq[OUTPUT_PORT].lock);
+			}
+		}
+	}
+	dqevent.type = V4L2_EVENT_MSM_VIDC_FLUSH_DONE;
+	dqevent.id = 0;
+	v4l2_event_queue_fh(&inst->event_handler, &dqevent);
+	return;
+}
+int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags)
+{
+	int rc =  0;
+	bool ip_flush = false;
+	bool op_flush = false;
+	struct list_head *ptr, *next;
+	struct vb2_buf_entry *temp;
+	struct mutex *lock;
+	struct msm_vidc_core *core;
+	struct hfi_device *hdev;
+	if (!inst) {
+		dprintk(VIDC_ERR,
+				"Invalid instance pointer = %p\n", inst);
+		return -EINVAL;
+	}
+	core = inst->core;
+	if (!core) {
+		dprintk(VIDC_ERR,
+				"Invalid core pointer = %p\n", core);
+		return -EINVAL;
+	}
+	hdev = core->device;
+	if (!hdev) {
+		dprintk(VIDC_ERR, "Invalid device pointer = %p", hdev);
+		return -EINVAL;
+	}
+
+	ip_flush = flags & V4L2_QCOM_CMD_FLUSH_OUTPUT;
+	op_flush = flags & V4L2_QCOM_CMD_FLUSH_CAPTURE;
+
+	if (ip_flush && !op_flush) {
+		dprintk(VIDC_INFO, "Input only flush not supported\n");
+		return 0;
+	}
+	if (inst->state == MSM_VIDC_CORE_INVALID ||
+			core->state == VIDC_CORE_INVALID) {
+		dprintk(VIDC_ERR,
+				"Core %p and inst %p are in bad state\n",
+					core, inst);
+		msm_comm_flush_in_invalid_state(inst);
+	}
+
+	mutex_lock(&inst->sync_lock);
+	if (inst->in_reconfig && !ip_flush && op_flush) {
+		if (!list_empty(&inst->pendingq)) {
+			/*Execution can never reach here since port reconfig
+			 * wont happen unless pendingq is emptied out
+			 * (both pendingq and flush being secured with same
+			 * lock). Printing a message here incase this breaks.*/
+			dprintk(VIDC_WARN,
+			"FLUSH BUG: Pending q not empty! It should be empty\n");
+		}
+		rc = call_hfi_op(hdev, session_flush, inst->session,
+				HAL_FLUSH_OUTPUT);
+	} else {
+		if (!list_empty(&inst->pendingq)) {
+			/*If flush is called after queueing buffers but before
+			 * streamon driver should flush the pending queue*/
+			list_for_each_safe(ptr, next, &inst->pendingq) {
+				temp =
+				list_entry(ptr, struct vb2_buf_entry, list);
+				if (temp->vb->v4l2_buf.type ==
+					V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+					lock = &inst->bufq[CAPTURE_PORT].lock;
+				else
+					lock = &inst->bufq[OUTPUT_PORT].lock;
+				mutex_lock(lock);
+				vb2_buffer_done(temp->vb, VB2_BUF_STATE_DONE);
+				mutex_unlock(lock);
+				list_del(&temp->list);
+				kfree(temp);
+			}
+		}
+		rc = call_hfi_op(hdev, session_flush, inst->session,
+				HAL_FLUSH_ALL);
+	}
+	mutex_unlock(&inst->sync_lock);
+	return rc;
+}
+
+
+enum hal_extradata_id msm_comm_get_hal_extradata_index(
+	enum v4l2_mpeg_vidc_extradata index)
+{
+	int ret = 0;
+	switch (index) {
+	case V4L2_MPEG_VIDC_EXTRADATA_NONE:
+		ret = HAL_EXTRADATA_NONE;
+		break;
+	case V4L2_MPEG_VIDC_EXTRADATA_MB_QUANTIZATION:
+		ret = HAL_EXTRADATA_MB_QUANTIZATION;
+		break;
+	case V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO:
+		ret = HAL_EXTRADATA_INTERLACE_VIDEO;
+		break;
+	case V4L2_MPEG_VIDC_EXTRADATA_VC1_FRAMEDISP:
+		ret = HAL_EXTRADATA_VC1_FRAMEDISP;
+		break;
+	case V4L2_MPEG_VIDC_EXTRADATA_VC1_SEQDISP:
+		ret = HAL_EXTRADATA_VC1_SEQDISP;
+		break;
+	case V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP:
+		ret = HAL_EXTRADATA_TIMESTAMP;
+		break;
+	case V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING:
+		ret = HAL_EXTRADATA_S3D_FRAME_PACKING;
+		break;
+	case V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE:
+		ret = HAL_EXTRADATA_FRAME_RATE;
+		break;
+	case V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW:
+		ret = HAL_EXTRADATA_PANSCAN_WINDOW;
+		break;
+	case V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI:
+		ret = HAL_EXTRADATA_RECOVERY_POINT_SEI;
+		break;
+	case V4L2_MPEG_VIDC_EXTRADATA_CLOSED_CAPTION_UD:
+		ret = HAL_EXTRADATA_CLOSED_CAPTION_UD;
+		break;
+	case V4L2_MPEG_VIDC_EXTRADATA_AFD_UD:
+		ret = HAL_EXTRADATA_AFD_UD;
+		break;
+	case V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO:
+		ret = HAL_EXTRADATA_MULTISLICE_INFO;
+		break;
+	case V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB:
+		ret = HAL_EXTRADATA_NUM_CONCEALED_MB;
+		break;
+	case V4L2_MPEG_VIDC_EXTRADATA_METADATA_FILLER:
+		ret = HAL_EXTRADATA_METADATA_FILLER;
+		break;
+	case V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO:
+		ret = HAL_EXTRADATA_ASPECT_RATIO;
+		break;
+	default:
+		dprintk(VIDC_WARN, "Extradata not found: %d\n", index);
+		break;
+	}
+	return ret;
+};
+
+int msm_vidc_trigger_ssr(struct msm_vidc_core *core,
+	enum hal_ssr_trigger_type type)
+{
+	int rc = 0;
+	struct hfi_device *hdev;
+	if (!core && !core->device) {
+		dprintk(VIDC_WARN, "Invalid parameters: %p\n", core);
+		return -EINVAL;
+	}
+	hdev = core->device;
+	if (core->state == VIDC_CORE_INIT_DONE)
+		rc = call_hfi_op(hdev, core_trigger_ssr,
+				hdev->hfi_device_data, type);
+	return rc;
+}
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.h b/drivers/media/platform/msm/vidc/msm_vidc_common.h
new file mode 100644
index 0000000..69f41c7
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.h
@@ -0,0 +1,46 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _MSM_VIDC_COMMON_H_
+#define _MSM_VIDC_COMMON_H_
+#include "msm_vidc_internal.h"
+struct vb2_buf_entry {
+	struct list_head list;
+	struct vb2_buffer *vb;
+};
+struct msm_vidc_core *get_vidc_core(int core_id);
+const struct msm_vidc_format *msm_comm_get_pixel_fmt_index(
+	const struct msm_vidc_format fmt[], int size, int index, int fmt_type);
+const struct msm_vidc_format *msm_comm_get_pixel_fmt_fourcc(
+	const struct msm_vidc_format fmt[], int size, int fourcc, int fmt_type);
+struct buf_queue *msm_comm_get_vb2q(
+		struct msm_vidc_inst *inst, enum v4l2_buf_type type);
+int msm_comm_try_state(struct msm_vidc_inst *inst, int state);
+int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst);
+int msm_comm_try_set_prop(struct msm_vidc_inst *inst,
+	enum hal_property ptype, void *pdata);
+int msm_comm_set_scratch_buffers(struct msm_vidc_inst *inst);
+int msm_comm_set_persist_buffers(struct msm_vidc_inst *inst);
+int msm_comm_qbuf(struct vb2_buffer *vb);
+void msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst);
+int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags);
+int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst);
+int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst);
+int msm_comm_force_cleanup(struct msm_vidc_inst *inst);
+enum hal_extradata_id msm_comm_get_hal_extradata_index(
+	enum v4l2_mpeg_vidc_extradata index);
+#define IS_PRIV_CTRL(idx) (\
+		(V4L2_CTRL_ID2CLASS(idx) == V4L2_CTRL_CLASS_MPEG) && \
+		V4L2_CTRL_DRIVER_PRIV(idx))
+
+#endif
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.c b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
new file mode 100644
index 0000000..65542bc
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
@@ -0,0 +1,297 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_vidc_debug.h"
+#include "vidc_hfi_api.h"
+
+#define MAX_DBG_BUF_SIZE 4096
+int msm_vidc_debug = 0x3;
+int msm_fw_debug = 0x18;
+int msm_fw_debug_mode = 0x1;
+int msm_fw_low_power_mode = 0x1;
+
+struct debug_buffer {
+	char ptr[MAX_DBG_BUF_SIZE];
+	char *curr;
+	u32 filled_size;
+};
+
+static struct debug_buffer dbg_buf;
+
+#define INIT_DBG_BUF(__buf) ({ \
+	__buf.curr = __buf.ptr;\
+	__buf.filled_size = 0; \
+})
+
+static int core_info_open(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return 0;
+}
+
+static u32 write_str(struct debug_buffer *buffer, const char *fmt, ...)
+{
+	va_list args;
+	u32 size;
+	va_start(args, fmt);
+	size = vscnprintf(buffer->curr, MAX_DBG_BUF_SIZE - 1, fmt, args);
+	va_end(args);
+	buffer->curr += size;
+	buffer->filled_size += size;
+	return size;
+}
+
+static ssize_t core_info_read(struct file *file, char __user *buf,
+		size_t count, loff_t *ppos)
+{
+	struct msm_vidc_core *core = file->private_data;
+	struct hfi_device *hdev;
+	int i = 0;
+	if (!core || !core->device) {
+		dprintk(VIDC_ERR, "Invalid params, core: %p\n", core);
+		return 0;
+	}
+	hdev = core->device;
+	INIT_DBG_BUF(dbg_buf);
+	write_str(&dbg_buf, "===============================\n");
+	write_str(&dbg_buf, "CORE %d: 0x%p\n", core->id, core);
+	write_str(&dbg_buf, "===============================\n");
+	write_str(&dbg_buf, "state: %d\n", core->state);
+	write_str(&dbg_buf, "base addr: 0x%x\n",
+		call_hfi_op(hdev, get_fw_info, hdev->hfi_device_data,
+					FW_BASE_ADDRESS));
+	write_str(&dbg_buf, "register_base: 0x%x\n",
+		call_hfi_op(hdev, get_fw_info, hdev->hfi_device_data,
+					FW_REGISTER_BASE));
+	write_str(&dbg_buf, "register_size: %u\n",
+		call_hfi_op(hdev, get_fw_info, hdev->hfi_device_data,
+					FW_REGISTER_SIZE));
+	write_str(&dbg_buf, "irq: %u\n",
+		call_hfi_op(hdev, get_fw_info, hdev->hfi_device_data,
+					FW_IRQ));
+	for (i = SYS_MSG_START; i < SYS_MSG_END; i++) {
+		write_str(&dbg_buf, "completions[%d]: %s\n", i,
+			completion_done(&core->completions[SYS_MSG_INDEX(i)]) ?
+			"pending" : "done");
+	}
+	return simple_read_from_buffer(buf, count, ppos,
+			dbg_buf.ptr, dbg_buf.filled_size);
+}
+
+static const struct file_operations core_info_fops = {
+	.open = core_info_open,
+	.read = core_info_read,
+};
+
+static int trigger_ssr_open(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return 0;
+}
+
+static ssize_t trigger_ssr_write(struct file *filp, const char __user *buf,
+		size_t count, loff_t *ppos) {
+	u32 ssr_trigger_val;
+	int rc;
+	struct msm_vidc_core *core = filp->private_data;
+	rc = sscanf(buf, "%d", &ssr_trigger_val);
+	if (rc < 0) {
+		dprintk(VIDC_WARN, "returning error err %d\n", rc);
+		rc = -EINVAL;
+	} else {
+		msm_vidc_trigger_ssr(core, ssr_trigger_val);
+		rc = count;
+	}
+	return rc;
+}
+
+static const struct file_operations ssr_fops = {
+	.open = trigger_ssr_open,
+	.write = trigger_ssr_write,
+};
+
+struct dentry *msm_vidc_debugfs_init_core(struct msm_vidc_core *core,
+		struct dentry *parent)
+{
+	struct dentry *dir = NULL;
+	char debugfs_name[MAX_DEBUGFS_NAME];
+	if (!core) {
+		dprintk(VIDC_ERR, "Invalid params, core: %p\n", core);
+		goto failed_create_dir;
+	}
+
+	snprintf(debugfs_name, MAX_DEBUGFS_NAME, "core%d", core->id);
+	dir = debugfs_create_dir(debugfs_name, parent);
+	if (!dir) {
+		dprintk(VIDC_ERR, "Failed to create debugfs for msm_vidc\n");
+		goto failed_create_dir;
+	}
+	if (!debugfs_create_file("info", S_IRUGO, dir, core, &core_info_fops)) {
+		dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
+		goto failed_create_dir;
+	}
+	if (!debugfs_create_u32("debug_level", S_IRUGO | S_IWUSR,
+			parent,	&msm_vidc_debug)) {
+		dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
+		goto failed_create_dir;
+	}
+	if (!debugfs_create_u32("fw_level", S_IRUGO | S_IWUSR,
+			parent, &msm_fw_debug)) {
+		dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
+		goto failed_create_dir;
+	}
+	if (!debugfs_create_file("trigger_ssr", S_IWUSR,
+			dir, core, &ssr_fops)) {
+		dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
+		goto failed_create_dir;
+	}
+	if (!debugfs_create_u32("fw_debug_mode", S_IRUGO | S_IWUSR,
+			parent, &msm_fw_debug_mode)) {
+		dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
+		goto failed_create_dir;
+	}
+	if (!debugfs_create_u32("fw_low_power_mode", S_IRUGO | S_IWUSR,
+			parent, &msm_fw_low_power_mode)) {
+		dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
+		goto failed_create_dir;
+	}
+failed_create_dir:
+	return dir;
+}
+
+static int inst_info_open(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return 0;
+}
+
+static ssize_t inst_info_read(struct file *file, char __user *buf,
+		size_t count, loff_t *ppos)
+{
+	struct msm_vidc_inst *inst = file->private_data;
+	int i, j;
+	if (!inst) {
+		dprintk(VIDC_ERR, "Invalid params, core: %p\n", inst);
+		return 0;
+	}
+	INIT_DBG_BUF(dbg_buf);
+	write_str(&dbg_buf, "===============================\n");
+	write_str(&dbg_buf, "INSTANCE: 0x%p (%s)\n", inst,
+		inst->session_type == MSM_VIDC_ENCODER ? "Encoder" : "Decoder");
+	write_str(&dbg_buf, "===============================\n");
+	write_str(&dbg_buf, "core: 0x%p\n", inst->core);
+	write_str(&dbg_buf, "height: %d\n", inst->prop.height);
+	write_str(&dbg_buf, "width: %d\n", inst->prop.width);
+	write_str(&dbg_buf, "state: %d\n", inst->state);
+	write_str(&dbg_buf, "-----------Formats-------------\n");
+	for (i = 0; i < MAX_PORT_NUM; i++) {
+		write_str(&dbg_buf, "capability: %s\n", i == OUTPUT_PORT ?
+			"Output" : "Capture");
+		write_str(&dbg_buf, "name : %s\n", inst->fmts[i]->name);
+		write_str(&dbg_buf, "planes : %d\n", inst->fmts[i]->num_planes);
+		write_str(
+		&dbg_buf, "type: %s\n", inst->fmts[i]->type == OUTPUT_PORT ?
+		"Output" : "Capture");
+		for (j = 0; j < inst->fmts[i]->num_planes; j++)
+			write_str(&dbg_buf, "size for plane %d: %u\n", j,
+			inst->fmts[i]->get_frame_size(j,
+			inst->prop.height, inst->prop.width));
+	}
+	write_str(&dbg_buf, "-------------------------------\n");
+	for (i = SESSION_MSG_START; i < SESSION_MSG_END; i++) {
+		write_str(&dbg_buf, "completions[%d]: %s\n", i,
+		completion_done(&inst->completions[SESSION_MSG_INDEX(i)]) ?
+		"pending" : "done");
+	}
+	write_str(&dbg_buf, "ETB Count: %d\n", inst->count.etb);
+	write_str(&dbg_buf, "EBD Count: %d\n", inst->count.ebd);
+	write_str(&dbg_buf, "FTB Count: %d\n", inst->count.ftb);
+	write_str(&dbg_buf, "FBD Count: %d\n", inst->count.fbd);
+	return simple_read_from_buffer(buf, count, ppos,
+		dbg_buf.ptr, dbg_buf.filled_size);
+}
+
+static const struct file_operations inst_info_fops = {
+	.open = inst_info_open,
+	.read = inst_info_read,
+};
+
+struct dentry *msm_vidc_debugfs_init_inst(struct msm_vidc_inst *inst,
+		struct dentry *parent)
+{
+	struct dentry *dir = NULL;
+	char debugfs_name[MAX_DEBUGFS_NAME];
+	if (!inst) {
+		dprintk(VIDC_ERR, "Invalid params, inst: %p\n", inst);
+		goto failed_create_dir;
+	}
+	snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%p", inst);
+	dir = debugfs_create_dir(debugfs_name, parent);
+	if (!dir) {
+		dprintk(VIDC_ERR, "Failed to create debugfs for msm_vidc\n");
+		goto failed_create_dir;
+	}
+	if (!debugfs_create_file("info", S_IRUGO, dir, inst, &inst_info_fops)) {
+		dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
+		goto failed_create_dir;
+	}
+	inst->debug.pdata[FRAME_PROCESSING].sampling = true;
+failed_create_dir:
+	return dir;
+}
+
+void msm_vidc_debugfs_update(struct msm_vidc_inst *inst,
+	enum msm_vidc_debugfs_event e)
+{
+	struct msm_vidc_debug *d = &inst->debug;
+	char a[64] = "Frame processing";
+	switch (e) {
+	case MSM_VIDC_DEBUGFS_EVENT_ETB:
+		inst->count.etb++;
+		if (inst->count.ebd && inst->count.ftb > inst->count.fbd) {
+			d->pdata[FRAME_PROCESSING].name[0] = '\0';
+			tic(inst, FRAME_PROCESSING, a);
+		}
+	break;
+	case MSM_VIDC_DEBUGFS_EVENT_EBD:
+		inst->count.ebd++;
+		if (inst->count.ebd && inst->count.ebd == inst->count.etb) {
+			toc(inst, FRAME_PROCESSING);
+			dprintk(VIDC_PROF, "EBD: FW needs input buffers\n");
+		}
+		if (inst->count.ftb == inst->count.fbd)
+			dprintk(VIDC_PROF, "EBD: FW needs output buffers\n");
+	break;
+	case MSM_VIDC_DEBUGFS_EVENT_FTB: {
+		inst->count.ftb++;
+		if (inst->count.ebd && inst->count.etb > inst->count.ebd) {
+			d->pdata[FRAME_PROCESSING].name[0] = '\0';
+			tic(inst, FRAME_PROCESSING, a);
+		}
+	}
+	break;
+	case MSM_VIDC_DEBUGFS_EVENT_FBD:
+		inst->debug.samples++;
+		if (inst->count.ebd && inst->count.fbd == inst->count.ftb) {
+			toc(inst, FRAME_PROCESSING);
+			dprintk(VIDC_PROF, "FBD: FW needs output buffers\n");
+		}
+		if (inst->count.etb == inst->count.ebd)
+			dprintk(VIDC_PROF, "FBD: FW needs input buffers\n");
+		break;
+	default:
+		dprintk(VIDC_ERR, "Invalid state in debugfs: %d\n", e);
+		break;
+	}
+}
+
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.h b/drivers/media/platform/msm/vidc/msm_vidc_debug.h
new file mode 100644
index 0000000..fb06af6
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.h
@@ -0,0 +1,109 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MSM_VIDC_DEBUG__
+#define __MSM_VIDC_DEBUG__
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include "msm_vidc_internal.h"
+
+#define VIDC_DBG_TAG "msm_vidc: %d: "
+
+/* To enable messages OR these values and
+ * echo the result to debugfs file.
+ *
+ * To enable all messages set debug_level = 0x101F
+ */
+
+enum vidc_msg_prio {
+	VIDC_ERR  = 0x0001,
+	VIDC_WARN = 0x0002,
+	VIDC_INFO = 0x0004,
+	VIDC_DBG  = 0x0008,
+	VIDC_PROF = 0x0010,
+	VIDC_FW   = 0x1000,
+};
+
+enum msm_vidc_debugfs_event {
+	MSM_VIDC_DEBUGFS_EVENT_ETB,
+	MSM_VIDC_DEBUGFS_EVENT_EBD,
+	MSM_VIDC_DEBUGFS_EVENT_FTB,
+	MSM_VIDC_DEBUGFS_EVENT_FBD,
+};
+
+extern int msm_vidc_debug;
+extern int msm_fw_debug;
+extern int msm_fw_debug_mode;
+extern int msm_fw_low_power_mode;
+
+#define dprintk(__level, __fmt, arg...)	\
+	do { \
+		if (msm_vidc_debug & __level) \
+			printk(KERN_DEBUG VIDC_DBG_TAG \
+				__fmt, __level, ## arg); \
+	} while (0)
+
+struct dentry *msm_vidc_debugfs_init_core(struct msm_vidc_core *core,
+		struct dentry *parent);
+struct dentry *msm_vidc_debugfs_init_inst(struct msm_vidc_inst *inst,
+		struct dentry *parent);
+void msm_vidc_debugfs_update(struct msm_vidc_inst *inst,
+		enum msm_vidc_debugfs_event e);
+
+static inline void tic(struct msm_vidc_inst *i, enum profiling_points p,
+				 char *b)
+{
+	struct timeval __ddl_tv;
+	if (!i->debug.pdata[p].name[0])
+		memcpy(i->debug.pdata[p].name, b, 64);
+	if ((msm_vidc_debug & VIDC_PROF) &&
+		i->debug.pdata[p].sampling) {
+		do_gettimeofday(&__ddl_tv);
+		i->debug.pdata[p].start =
+			(__ddl_tv.tv_sec * 1000) + (__ddl_tv.tv_usec / 1000);
+			i->debug.pdata[p].sampling = false;
+	}
+}
+
+static inline void toc(struct msm_vidc_inst *i, enum profiling_points p)
+{
+	struct timeval __ddl_tv;
+	if ((msm_vidc_debug & VIDC_PROF) &&
+		!i->debug.pdata[p].sampling) {
+		do_gettimeofday(&__ddl_tv);
+		i->debug.pdata[p].stop = (__ddl_tv.tv_sec * 1000)
+		+ (__ddl_tv.tv_usec / 1000);
+		i->debug.pdata[p].cumulative +=
+		(i->debug.pdata[p].stop - i->debug.pdata[p].start);
+		i->debug.pdata[p].sampling = true;
+	}
+}
+
+static inline void show_stats(struct msm_vidc_inst *i)
+{
+	int x;
+	for (x = 0; x < MAX_PROFILING_POINTS; x++) {
+		if ((i->debug.pdata[x].name[0])  &&
+			(msm_vidc_debug & VIDC_PROF)) {
+			dprintk(VIDC_PROF, "%s averaged %d ms/sample\n",
+				i->debug.pdata[x].name,
+				i->debug.pdata[x].cumulative /
+					i->debug.samples);
+			dprintk(VIDC_PROF, "%s Samples: %d",
+					i->debug.pdata[x].name,
+					i->debug.samples);
+		}
+	}
+}
+
+#endif
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
new file mode 100644
index 0000000..8238d42
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
@@ -0,0 +1,241 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _MSM_VIDC_INTERNAL_H_
+#define _MSM_VIDC_INTERNAL_H_
+
+#include <linux/list.h>
+#include <linux/types.h>
+#include <linux/completion.h>
+#include <linux/wait.h>
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
+#include <mach/ocmem.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-ctrls.h>
+#include <media/videobuf2-core.h>
+#include <media/msm_vidc.h>
+#include <media/msm_media_info.h>
+
+#include "vidc_hfi_api.h"
+#include "vidc_hfi_api.h"
+
+#define MSM_VIDC_DRV_NAME "msm_vidc_driver"
+#define MSM_VIDC_VERSION KERNEL_VERSION(0, 0, 1);
+#define MAX_DEBUGFS_NAME 50
+#define DEFAULT_TIMEOUT 3
+
+#define V4L2_EVENT_VIDC_BASE  10
+
+#define SYS_MSG_START VIDC_EVENT_CHANGE
+#define SYS_MSG_END SYS_DEBUG
+#define SESSION_MSG_START SESSION_LOAD_RESOURCE_DONE
+#define SESSION_MSG_END SESSION_PROPERTY_INFO
+#define SYS_MSG_INDEX(__msg) (__msg - SYS_MSG_START)
+#define SESSION_MSG_INDEX(__msg) (__msg - SESSION_MSG_START)
+
+#define MAX_NAME_LENGTH 64
+
+#define EXTRADATA_IDX(__num_planes) (__num_planes - 1)
+enum vidc_ports {
+	OUTPUT_PORT,
+	CAPTURE_PORT,
+	MAX_PORT_NUM
+};
+
+enum vidc_core_state {
+	VIDC_CORE_UNINIT = 0,
+	VIDC_CORE_INIT,
+	VIDC_CORE_INIT_DONE,
+	VIDC_CORE_INVALID
+};
+
+/*Donot change the enum values unless
+ * you know what you are doing*/
+enum instance_state {
+	MSM_VIDC_CORE_UNINIT_DONE = 0x0001,
+	MSM_VIDC_CORE_INIT,
+	MSM_VIDC_CORE_INIT_DONE,
+	MSM_VIDC_OPEN,
+	MSM_VIDC_OPEN_DONE,
+	MSM_VIDC_LOAD_RESOURCES,
+	MSM_VIDC_LOAD_RESOURCES_DONE,
+	MSM_VIDC_START,
+	MSM_VIDC_START_DONE,
+	MSM_VIDC_STOP,
+	MSM_VIDC_STOP_DONE,
+	MSM_VIDC_RELEASE_RESOURCES,
+	MSM_VIDC_RELEASE_RESOURCES_DONE,
+	MSM_VIDC_CLOSE,
+	MSM_VIDC_CLOSE_DONE,
+	MSM_VIDC_CORE_UNINIT,
+	MSM_VIDC_CORE_INVALID
+};
+
+struct buf_info {
+	struct list_head list;
+	struct vb2_buffer *buf;
+};
+
+struct internal_buf {
+	struct list_head list;
+	enum hal_buffer buffer_type;
+	struct msm_smem *handle;
+};
+
+struct msm_vidc_format {
+	char name[MAX_NAME_LENGTH];
+	u8 description[32];
+	u32 fourcc;
+	int num_planes;
+	int type;
+	u32 (*get_frame_size)(int plane, u32 height, u32 width);
+};
+
+struct msm_vidc_drv {
+	struct mutex lock;
+	struct list_head cores;
+	int num_cores;
+	struct dentry *debugfs_root;
+};
+
+struct msm_video_device {
+	int type;
+	struct video_device vdev;
+};
+
+struct session_prop {
+	u32 width;
+	u32 height;
+	u32 fps;
+	u32 bitrate;
+	u64 prev_time_stamp;
+};
+
+struct buf_queue {
+	struct vb2_queue vb2_bufq;
+	struct mutex lock;
+};
+
+enum profiling_points {
+	SYS_INIT = 0,
+	SESSION_INIT,
+	LOAD_RESOURCES,
+	FRAME_PROCESSING,
+	FW_IDLE,
+	MAX_PROFILING_POINTS,
+};
+
+struct buf_count {
+	int etb;
+	int ftb;
+	int fbd;
+	int ebd;
+};
+
+struct profile_data {
+	int start;
+	int stop;
+	int cumulative;
+	char name[64];
+	int sampling;
+	int average;
+};
+
+struct msm_vidc_debug {
+	struct profile_data pdata[MAX_PROFILING_POINTS];
+	int profile;
+	int samples;
+};
+
+enum msm_vidc_mode {
+	VIDC_NON_SECURE,
+	VIDC_SECURE,
+};
+
+struct msm_vidc_core {
+	struct list_head list;
+	struct mutex sync_lock, lock;
+	int id;
+	void *device;
+	struct msm_video_device vdev[MSM_VIDC_MAX_DEVICES];
+	struct v4l2_device v4l2_dev;
+	struct list_head instances;
+	struct dentry *debugfs_root;
+	enum vidc_core_state state;
+	struct completion completions[SYS_MSG_END - SYS_MSG_START + 1];
+	enum msm_vidc_hfi_type hfi_type;
+	struct msm_vidc_platform_resources resources;
+};
+
+struct msm_vidc_inst {
+	struct list_head list;
+	struct mutex sync_lock, lock;
+	struct msm_vidc_core *core;
+	int session_type;
+	void *session;
+	struct session_prop prop;
+	int state;
+	const struct msm_vidc_format *fmts[MAX_PORT_NUM];
+	struct buf_queue bufq[MAX_PORT_NUM];
+	struct list_head pendingq;
+	struct list_head internalbufs;
+	struct list_head persistbufs;
+	struct buffer_requirements buff_req;
+	void *mem_client;
+	struct v4l2_ctrl_handler ctrl_handler;
+	struct completion completions[SESSION_MSG_END - SESSION_MSG_START + 1];
+	struct list_head ctrl_clusters;
+	struct v4l2_fh event_handler;
+	struct msm_smem *extradata_handle;
+	wait_queue_head_t kernel_event_queue;
+	bool in_reconfig;
+	u32 reconfig_width;
+	u32 reconfig_height;
+	struct dentry *debugfs_root;
+	u32 ftb_count;
+	struct vb2_buffer *vb2_seq_hdr;
+	void *priv;
+	struct msm_vidc_debug debug;
+	struct buf_count count;
+	enum msm_vidc_mode mode;
+};
+
+extern struct msm_vidc_drv *vidc_driver;
+
+struct msm_vidc_ctrl_cluster {
+	struct v4l2_ctrl **cluster;
+	struct list_head list;
+};
+
+struct msm_vidc_ctrl {
+	u32 id;
+	char name[MAX_NAME_LENGTH];
+	enum v4l2_ctrl_type type;
+	s32 minimum;
+	s32 maximum;
+	s32 default_value;
+	u32 step;
+	u32 menu_skip_mask;
+	const char * const *qmenu;
+	u32 cluster;
+	struct v4l2_ctrl *priv;
+};
+
+void handle_cmd_response(enum command_response cmd, void *data);
+int msm_vidc_trigger_ssr(struct msm_vidc_core *core,
+	enum hal_ssr_trigger_type type);
+#endif
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_resources.h b/drivers/media/platform/msm/vidc/msm_vidc_resources.h
new file mode 100644
index 0000000..8fc6452
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/msm_vidc_resources.h
@@ -0,0 +1,50 @@
+/* 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 __MSM_VIDC_RESOURCES_H__
+#define __MSM_VIDC_RESOURCES_H__
+
+#include <linux/platform_device.h>
+#include <media/msm_vidc.h>
+
+struct load_freq_table {
+	u32 load;
+	u32 freq;
+};
+
+struct reg_value_pair {
+	u32 reg;
+	u32 value;
+};
+
+struct reg_set {
+	struct reg_value_pair *reg_tbl;
+	int count;
+};
+
+struct msm_vidc_platform_resources {
+	uint32_t fw_base_addr;
+	uint32_t register_base;
+	uint32_t register_size;
+	uint32_t irq;
+	struct load_freq_table *load_freq_tbl;
+	uint32_t load_freq_tbl_size;
+	struct msm_vidc_iommu_info *iommu_maps;
+	uint32_t iommu_maps_size;
+	struct reg_set reg_set;
+	struct msm_bus_scale_pdata *bus_pdata;
+	struct platform_device *pdev;
+};
+
+#endif
+
diff --git a/drivers/media/platform/msm/vidc/q6_hfi.c b/drivers/media/platform/msm/vidc/q6_hfi.c
new file mode 100644
index 0000000..25cc239
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/q6_hfi.c
@@ -0,0 +1,1258 @@
+/* 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/slab.h>
+#include <mach/qdsp6v2/apr.h>
+#include <mach/subsystem_restart.h>
+#include "hfi_packetization.h"
+#include "msm_vidc_debug.h"
+#include "q6_hfi.h"
+#include "vidc_hfi_api.h"
+
+
+static int write_queue(void *info, u8 *packet)
+{
+	u32 packet_size_in_words, new_write_idx;
+	struct q6_iface_q_info *qinfo;
+	u32 empty_space, read_idx;
+	u32 *write_ptr;
+
+	if (!info || !packet) {
+		dprintk(VIDC_ERR, "Invalid Params");
+		return -EINVAL;
+	}
+
+	qinfo = (struct q6_iface_q_info *) info;
+
+	packet_size_in_words = (*(u32 *)packet) >> 2;
+
+	if (packet_size_in_words == 0) {
+		dprintk(VIDC_ERR, "Zero packet size");
+		return -ENODATA;
+	}
+
+	read_idx = qinfo->read_idx;
+
+	empty_space = (qinfo->write_idx >=  read_idx) ?
+		(qinfo->q_size - (qinfo->write_idx -  read_idx)) :
+		(read_idx - qinfo->write_idx);
+	if (empty_space <= packet_size_in_words) {
+		dprintk(VIDC_ERR, "Insufficient size (%d) to write (%d)",
+					  empty_space, packet_size_in_words);
+		return -ENOTEMPTY;
+	}
+
+	new_write_idx = (qinfo->write_idx + packet_size_in_words);
+	write_ptr = (u32 *)(qinfo->buffer + (qinfo->write_idx << 2));
+	if (new_write_idx < qinfo->q_size) {
+		memcpy(write_ptr, packet, packet_size_in_words << 2);
+	} else {
+		new_write_idx -= qinfo->q_size;
+		memcpy(write_ptr, packet, (packet_size_in_words -
+			new_write_idx) << 2);
+		memcpy((void *)qinfo->buffer,
+			packet + ((packet_size_in_words - new_write_idx) << 2),
+			new_write_idx  << 2);
+	}
+	qinfo->write_idx = new_write_idx;
+	return 0;
+}
+
+static int read_queue(void *info, u8 *packet)
+{
+	u32 packet_size_in_words, new_read_idx;
+	u32 *read_ptr;
+	struct q6_iface_q_info *qinfo;
+
+	if (!info || !packet) {
+		dprintk(VIDC_ERR, "Invalid Params");
+		return -EINVAL;
+	}
+
+	qinfo = (struct q6_iface_q_info *) info;
+
+	if (qinfo->read_idx == qinfo->write_idx)
+		return -EPERM;
+
+	read_ptr = (u32 *)(qinfo->buffer + (qinfo->read_idx << 2));
+	packet_size_in_words = (*read_ptr) >> 2;
+	if (packet_size_in_words == 0) {
+		dprintk(VIDC_ERR, "Zero packet size");
+		return -ENODATA;
+	}
+
+	new_read_idx = qinfo->read_idx + packet_size_in_words;
+	if (new_read_idx < qinfo->q_size) {
+		memcpy(packet, read_ptr,
+			packet_size_in_words << 2);
+	} else {
+		new_read_idx -= qinfo->q_size;
+		memcpy(packet, read_ptr,
+			(packet_size_in_words - new_read_idx) << 2);
+		memcpy(packet + ((packet_size_in_words -
+			new_read_idx) << 2),
+			(u8 *)qinfo->buffer,
+			new_read_idx << 2);
+	}
+
+	qinfo->read_idx = new_read_idx;
+	return 0;
+}
+
+static int q6_hfi_iface_eventq_write(struct q6_hfi_device *device, void *pkt)
+{
+	struct q6_iface_q_info *q_info;
+	int rc = 0;
+	unsigned long flags = 0;
+
+	if (!device || !pkt) {
+		dprintk(VIDC_ERR, "Invalid Params");
+		return -EINVAL;
+	}
+
+	q_info = &device->event_queue;
+	if (!q_info->buffer) {
+		dprintk(VIDC_ERR, "cannot write to shared Q");
+		rc = -ENODATA;
+		goto err_q_write;
+	}
+
+	spin_lock_irqsave(&q_info->lock, flags);
+	rc = write_queue(q_info, (u8 *)pkt);
+	if (rc)
+		dprintk(VIDC_ERR, "q6_hfi_iface_eventq_write: queue_full");
+
+	spin_unlock_irqrestore(&q_info->lock, flags);
+err_q_write:
+	return rc;
+}
+
+static int q6_hfi_iface_eventq_read(struct q6_hfi_device *device, void *pkt)
+{
+	int rc = 0;
+	struct q6_iface_q_info *q_info;
+	unsigned long flags = 0;
+
+	if (!pkt) {
+		dprintk(VIDC_ERR, "Invalid Params");
+		return -EINVAL;
+	}
+
+	q_info = &device->event_queue;
+
+	if (!q_info->buffer) {
+		dprintk(VIDC_ERR, "cannot read from shared Q");
+		rc = -ENODATA;
+		goto read_error;
+	}
+
+	spin_lock_irqsave(&q_info->lock, flags);
+	rc = read_queue(q_info, (u8 *)pkt);
+	if (rc) {
+		dprintk(VIDC_INFO, "q6_hfi_iface_eventq_read:queue_empty");
+		rc = -ENODATA;
+	}
+	spin_unlock_irqrestore(&q_info->lock, flags);
+
+read_error:
+	return rc;
+}
+
+static void q6_hfi_core_work_handler(struct work_struct *work)
+{
+	int rc = 0;
+	struct q6_hfi_device *device = container_of(
+		work, struct q6_hfi_device, vidc_worker);
+	u8 packet[VIDC_IFACEQ_MED_PKT_SIZE];
+
+	/* need to consume all the messages from the firmware */
+	do {
+		rc = q6_hfi_iface_eventq_read(device, packet);
+		if (!rc)
+			hfi_process_msg_packet(device->callback,
+				device->device_id,
+				(struct vidc_hal_msg_pkt_hdr *) packet);
+	} while (!rc);
+
+	if (rc != -ENODATA)
+		dprintk(VIDC_ERR, "Failed to read from event queue");
+}
+
+static int q6_hfi_register_iommu_domains(struct q6_hfi_device *device)
+{
+	(void)device;
+
+	dprintk(VIDC_ERR, "Not implemented: %s", __func__);
+
+	return 0;
+}
+
+static int q6_hfi_init_resources(struct q6_hfi_device *device)
+{
+	int rc = 0;
+
+	rc = q6_hfi_register_iommu_domains(device);
+	if (rc)
+		dprintk(VIDC_ERR, "Failed to register iommu domains: %d\n", rc);
+
+	return rc;
+}
+
+static void *q6_hfi_add_device(u32 device_id,
+			hfi_cmd_response_callback callback)
+{
+	struct q6_hfi_device *hdevice = NULL;
+
+	if (device_id || !callback) {
+		dprintk(VIDC_ERR, "Invalid Paramters");
+		return NULL;
+	}
+
+	hdevice = (struct q6_hfi_device *)
+			kzalloc(sizeof(struct q6_hfi_device), GFP_KERNEL);
+	if (!hdevice) {
+		dprintk(VIDC_ERR, "failed to allocate new device");
+		goto err_alloc;
+	}
+
+	INIT_LIST_HEAD(&hal_ctxt.dev_head);
+	INIT_LIST_HEAD(&hdevice->list);
+	hdevice->device_id = device_id;
+	hdevice->callback = callback;
+
+	INIT_WORK(&hdevice->vidc_worker, q6_hfi_core_work_handler);
+	hdevice->vidc_workq = create_singlethread_workqueue(
+		"msm_vidc_workerq");
+	if (!hdevice->vidc_workq) {
+		dprintk(VIDC_ERR, ": create workq failed\n");
+		goto error_createq;
+	}
+
+	list_add_tail(&hdevice->list, &hal_ctxt.dev_head);
+	hal_ctxt.dev_count++;
+
+	return (void *) hdevice;
+error_createq:
+	kfree(hdevice);
+err_alloc:
+	return NULL;
+}
+
+static void *q6_hfi_get_device(u32 device_id,
+				hfi_cmd_response_callback callback)
+{
+	struct q6_hfi_device *device;
+	int rc = 0;
+
+	if (!callback) {
+		dprintk(VIDC_ERR, "%s Invalid params:  %p\n",
+			__func__, callback);
+		return NULL;
+	}
+
+	device = q6_hfi_add_device(device_id, &handle_cmd_response);
+	if (!device) {
+		dprintk(VIDC_ERR, "Failed to create HFI device\n");
+		return NULL;
+	}
+
+	rc = q6_hfi_init_resources(device);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to init resources: %d\n", rc);
+		goto err_fail_init_res;
+	}
+	return device;
+
+err_fail_init_res:
+	q6_hfi_delete_device(device);
+	return NULL;
+}
+
+void q6_hfi_delete_device(void *device)
+{
+	struct q6_hfi_device *close, *dev;
+
+	if (device) {
+		dev = (struct q6_hfi_device *) device;
+		list_for_each_entry(close, &hal_ctxt.dev_head, list) {
+				hal_ctxt.dev_count--;
+				list_del(&close->list);
+				destroy_workqueue(close->vidc_workq);
+				kfree(close);
+		}
+
+	}
+}
+
+static inline void q6_hfi_add_apr_hdr(struct q6_hfi_device *dev,
+			struct apr_hdr *hdr, u32 pkt_size, u32 opcode)
+{
+	hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+				APR_HDR_LEN(sizeof(struct apr_hdr)),
+				APR_PKT_VER);
+
+	hdr->src_svc = ((struct apr_svc *)dev->apr)->id;
+	hdr->src_domain = APR_DOMAIN_APPS;
+	hdr->dest_svc = APR_SVC_VIDC;
+	hdr->src_port = 0;
+	hdr->dest_port = 0;
+	hdr->pkt_size  = pkt_size;
+	hdr->token = 0;
+	hdr->opcode = opcode;
+}
+
+static int q6_hfi_apr_callback(struct apr_client_data *data, void *priv)
+{
+	struct q6_hfi_device *device = priv;
+	int rc = 0;
+
+	if (!data || !device || !data->payload_size) {
+		dprintk(VIDC_ERR, "%s - Invalid arguments", __func__);
+		return -EINVAL;
+	}
+
+	dprintk(VIDC_DBG, "%s opcode = %u payload size = %u", __func__,
+				data->opcode, data->payload_size);
+
+	rc = q6_hfi_iface_eventq_write(device, data->payload);
+	if (rc) {
+		dprintk(VIDC_ERR, "%s failed to write to event queue",
+				__func__);
+		return rc;
+	}
+	queue_work(device->vidc_workq, &device->vidc_worker);
+	return 0;
+}
+
+static void q6_release_event_queue(struct q6_hfi_device *device)
+{
+	kfree(device->event_queue.buffer);
+	device->event_queue.buffer = NULL;
+	device->event_queue.q_size = 0;
+	device->event_queue.read_idx = 0;
+	device->event_queue.write_idx = 0;
+}
+
+static int q6_init_event_queue(struct q6_hfi_device *dev)
+{
+	struct q6_iface_q_info *iface_q;
+
+	if (!dev) {
+		dprintk(VIDC_ERR, "Invalid device");
+		return -EINVAL;
+	}
+
+	iface_q = &dev->event_queue;
+	iface_q->buffer = kzalloc(Q6_IFACEQ_QUEUE_SIZE, GFP_KERNEL);
+	if (!iface_q->buffer) {
+		dprintk(VIDC_ERR, "iface_q alloc failed");
+		q6_release_event_queue(dev);
+		return -ENOMEM;
+	} else {
+		iface_q->q_size = Q6_IFACEQ_QUEUE_SIZE / 4;
+		iface_q->read_idx = 0;
+		iface_q->write_idx = 0;
+		spin_lock_init(&iface_q->lock);
+	}
+	return 0;
+}
+
+static int q6_hfi_core_init(void *device)
+{
+	struct q6_apr_cmd_sys_init_packet apr;
+	int rc = 0;
+	struct q6_hfi_device *dev = device;
+
+	if (!dev) {
+		dprintk(VIDC_ERR, "%s: invalid argument\n", __func__);
+		return -ENODEV;
+	}
+
+	INIT_LIST_HEAD(&dev->sess_head);
+
+	if (!dev->event_queue.buffer) {
+		rc = q6_init_event_queue(dev);
+		if (rc) {
+			dprintk(VIDC_ERR, "q6_init_event_queue failed");
+			goto err_core_init;
+		}
+	} else {
+		dprintk(VIDC_ERR, "queue buffer exists");
+		rc = -EEXIST;
+		goto err_core_init;
+	}
+
+	q6_hfi_add_apr_hdr(dev, &apr.hdr, sizeof(apr), HFI_CMD_SYS_INIT);
+
+	rc = create_pkt_cmd_sys_init(&apr.pkt, HFI_ARCH_OX_OFFSET);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to create sys init pkt");
+		goto err_core_init;
+	}
+
+	rc = apr_send_pkt(dev->apr, (uint32_t *)&apr);
+	if (rc != apr.hdr.pkt_size) {
+		dprintk(VIDC_ERR, "%s: apr_send_pkt failed rc: %d",
+				__func__, rc);
+		rc = -EBADE;
+	} else
+		rc = 0;
+err_core_init:
+	return rc;
+}
+
+static int q6_hfi_core_release(void *device)
+{
+	struct q6_hfi_device *dev = device;
+
+	if (!dev) {
+		dprintk(VIDC_ERR, "%s: invalid argument\n", __func__);
+		return -ENODEV;
+	}
+	q6_release_event_queue(dev);
+
+	dprintk(VIDC_DBG, "HAL exited\n");
+	return 0;
+}
+
+static int q6_hfi_core_pc_prep(void *device)
+{
+	(void) device;
+
+	/* Q6 does not support core_pc_prep*/
+	return 0;
+}
+
+static int q6_hfi_core_ping(void *device)
+{
+	(void) device;
+
+	/* Q6 does not support cmd_sys_ping */
+	return 0;
+}
+
+static void *q6_hfi_session_init(void *device, u32 session_id,
+	enum hal_domain session_type, enum hal_video_codec codec_type)
+{
+	struct q6_apr_cmd_sys_session_init_packet apr;
+	struct hal_session *new_session;
+	struct q6_hfi_device *dev = device;
+	int rc = 0;
+
+	if (!dev) {
+		dprintk(VIDC_ERR, "%s: invalid argument\n", __func__);
+		return NULL;
+	}
+
+	new_session = (struct hal_session *)
+		kzalloc(sizeof(struct hal_session), GFP_KERNEL);
+	new_session->session_id = (u32) session_id;
+	if (session_type == 1)
+		new_session->is_decoder = 0;
+	else if (session_type == 2)
+		new_session->is_decoder = 1;
+	new_session->device = dev;
+
+	q6_hfi_add_apr_hdr(dev, &apr.hdr, sizeof(apr),
+				   HFI_CMD_SYS_SESSION_INIT);
+
+	if (create_pkt_cmd_sys_session_init(&apr.pkt, (u32)new_session,
+					session_type, codec_type)) {
+		dprintk(VIDC_ERR, "session_init: failed to create packet");
+		goto err_session_init;
+	}
+
+	rc = apr_send_pkt(dev->apr, (uint32_t *)&apr);
+	if (rc != apr.hdr.pkt_size) {
+		dprintk(VIDC_ERR, "%s: apr_send_pkt failed rc: %d",
+				__func__, rc);
+		rc = -EBADE;
+		goto err_session_init;
+	}
+	list_add_tail(&new_session->list, &dev->sess_head);
+	return new_session;
+
+err_session_init:
+	kfree(new_session);
+	return NULL;
+}
+
+static int q6_hal_send_session_cmd(void *sess,
+	 int pkt_type)
+{
+	struct q6_apr_session_cmd_pkt apr;
+	int rc = 0;
+	struct hal_session *session = sess;
+	struct q6_hfi_device *dev;
+
+	if (!session || !session->device) {
+		dprintk(VIDC_ERR, "%s: invalid arguments\n", __func__);
+		return -EINVAL;
+	}
+	dev = session->device;
+
+	q6_hfi_add_apr_hdr(dev, &apr.hdr, sizeof(apr), pkt_type);
+
+	rc = create_pkt_cmd_session_cmd(&apr.pkt, pkt_type, (u32)session);
+	if (rc) {
+		dprintk(VIDC_ERR, "send session cmd: create pkt failed");
+		goto err_create_pkt;
+	}
+
+	rc = apr_send_pkt(dev->apr, (uint32_t *)&apr);
+	if (rc != apr.hdr.pkt_size) {
+		dprintk(VIDC_ERR, "%s: apr_send_pkt failed rc: %d",
+				__func__, rc);
+		rc = -EBADE;
+	} else
+		rc = 0;
+err_create_pkt:
+	return rc;
+}
+
+static int q6_hfi_session_end(void *session)
+{
+	return q6_hal_send_session_cmd(session,
+		HFI_CMD_SYS_SESSION_END);
+}
+
+static int q6_hfi_session_abort(void *session)
+{
+	return q6_hal_send_session_cmd(session,
+		HFI_CMD_SYS_SESSION_ABORT);
+}
+
+static int q6_hfi_session_set_buffers(void *sess,
+	struct vidc_buffer_addr_info *buffer_info)
+{
+	struct q6_apr_cmd_session_set_buffers_packet *apr;
+	u8 packet[VIDC_IFACEQ_VAR_LARGE_PKT_SIZE];
+	int rc = 0;
+	struct hal_session *session = sess;
+	struct q6_hfi_device *dev;
+
+	if (!session || !buffer_info || !session->device) {
+		dprintk(VIDC_ERR, "%s: invalid arguments\n", __func__);
+		return -EINVAL;
+	}
+	dev = session->device;
+
+	if (buffer_info->buffer_type == HAL_BUFFER_INPUT)
+		return 0;
+	apr = (struct q6_apr_cmd_session_set_buffers_packet *)packet;
+
+	q6_hfi_add_apr_hdr(dev, &apr->hdr, VIDC_IFACEQ_VAR_LARGE_PKT_SIZE,
+			HFI_CMD_SESSION_SET_BUFFERS);
+
+	rc = create_pkt_cmd_session_set_buffers(&apr->pkt,
+			(u32)session, buffer_info);
+	if (rc) {
+		dprintk(VIDC_ERR, "set buffers: failed to create packet");
+		goto err_create_pkt;
+	}
+
+	dprintk(VIDC_INFO, "set buffers: 0x%x", buffer_info->buffer_type);
+	rc = apr_send_pkt(dev->apr, (uint32_t *)apr);
+	if (rc != apr->hdr.pkt_size) {
+		dprintk(VIDC_ERR, "%s: apr_send_pkt failed rc: %d",
+				__func__, rc);
+		rc = -EBADE;
+	} else
+		rc = 0;
+err_create_pkt:
+	return rc;
+}
+
+static int q6_hfi_session_release_buffers(void *sess,
+	struct vidc_buffer_addr_info *buffer_info)
+{
+	struct q6_apr_cmd_session_release_buffer_packet *apr;
+	u8 packet[VIDC_IFACEQ_VAR_LARGE_PKT_SIZE];
+	int rc = 0;
+	struct hal_session *session = sess;
+	struct q6_hfi_device *dev;
+
+	if (!session || !buffer_info || !session->device) {
+		dprintk(VIDC_ERR, "%s: invalid arguments\n", __func__);
+		return -EINVAL;
+	}
+
+	dev = session->device;
+
+	if (buffer_info->buffer_type == HAL_BUFFER_INPUT)
+		return 0;
+
+	apr = (struct q6_apr_cmd_session_release_buffer_packet *) packet;
+
+	q6_hfi_add_apr_hdr(dev, &apr->hdr, VIDC_IFACEQ_VAR_LARGE_PKT_SIZE,
+					   HFI_CMD_SESSION_RELEASE_BUFFERS);
+
+	rc = create_pkt_cmd_session_release_buffers(&apr->pkt,
+					(u32)session, buffer_info);
+	if (rc) {
+		dprintk(VIDC_ERR, "release buffers: failed to create packet");
+		goto err_create_pkt;
+	}
+
+	dprintk(VIDC_INFO, "Release buffers: 0x%x", buffer_info->buffer_type);
+	rc = apr_send_pkt(dev->apr, (uint32_t *)apr);
+
+	if (rc != apr->hdr.pkt_size) {
+		dprintk(VIDC_ERR, "%s: apr_send_pkt failed rc: %d",
+				__func__, rc);
+		rc = -EBADE;
+	} else
+		rc = 0;
+err_create_pkt:
+	return rc;
+}
+
+static int q6_hfi_session_load_res(void *sess)
+{
+	return q6_hal_send_session_cmd(sess,
+		HFI_CMD_SESSION_LOAD_RESOURCES);
+}
+
+static int q6_hfi_session_release_res(void *sess)
+{
+	return q6_hal_send_session_cmd(sess,
+		HFI_CMD_SESSION_RELEASE_RESOURCES);
+}
+
+static int q6_hfi_session_start(void *sess)
+{
+	return q6_hal_send_session_cmd(sess,
+		HFI_CMD_SESSION_START);
+}
+
+static int q6_hfi_session_stop(void *sess)
+{
+	return q6_hal_send_session_cmd(sess,
+		HFI_CMD_SESSION_STOP);
+}
+
+static int q6_hfi_session_suspend(void *sess)
+{
+	return q6_hal_send_session_cmd(sess,
+		HFI_CMD_SESSION_SUSPEND);
+}
+
+static int q6_hfi_session_resume(void *sess)
+{
+	return q6_hal_send_session_cmd(sess,
+		HFI_CMD_SESSION_RESUME);
+}
+
+static int q6_hfi_session_etb(void *sess,
+			struct vidc_frame_data *input_frame)
+{
+	int rc = 0;
+	struct hal_session *session = sess;
+	struct q6_hfi_device *dev;
+
+	if (!session || !input_frame || !session->device) {
+		dprintk(VIDC_ERR, "Invalid Params");
+		return -EINVAL;
+	}
+
+	dev = session->device;
+
+	if (session->is_decoder) {
+		struct q6_apr_cmd_session_empty_buffer_compressed_packet apr;
+		q6_hfi_add_apr_hdr(dev, &apr.hdr, sizeof(apr),
+					   HFI_CMD_SESSION_EMPTY_BUFFER);
+
+		rc = create_pkt_cmd_session_etb_decoder(&apr.pkt,
+					(u32)session, input_frame);
+		if (rc) {
+			dprintk(VIDC_ERR,
+				"Session etb decoder: failed to create pkt");
+			goto err_create_pkt;
+		}
+		dprintk(VIDC_DBG, "Q DECODER INPUT BUFFER");
+		dprintk(VIDC_DBG, "addr = 0x%x ts = %lld",
+			input_frame->device_addr, input_frame->timestamp);
+		rc = apr_send_pkt(dev->apr, (uint32_t *)&apr);
+		if (rc != apr.hdr.pkt_size) {
+			dprintk(VIDC_ERR, "%s: apr_send_pkt failed rc: %d",
+					__func__, rc);
+			rc = -EBADE;
+		} else
+			rc = 0;
+	} else {
+		struct
+		q6_apr_cmd_session_empty_buffer_uncompressed_plane0_packet apr;
+		q6_hfi_add_apr_hdr(dev, &apr.hdr, sizeof(apr),
+				   HFI_CMD_SESSION_EMPTY_BUFFER);
+
+		rc =  create_pkt_cmd_session_etb_encoder(&apr.pkt,
+					(u32)session, input_frame);
+		if (rc) {
+			dprintk(VIDC_ERR,
+				"Session etb encoder: failed to create pkt");
+			goto err_create_pkt;
+		}
+		dprintk(VIDC_DBG, "Q ENCODER INPUT BUFFER");
+		rc = apr_send_pkt(dev->apr, (uint32_t *)&apr);
+		if (rc != apr.hdr.pkt_size) {
+			dprintk(VIDC_ERR, "%s: apr_send_pkt failed rc: %d",
+					__func__, rc);
+			rc = -EBADE;
+		} else
+			rc = 0;
+	}
+err_create_pkt:
+	return rc;
+}
+
+static int q6_hfi_session_ftb(void *sess,
+	struct vidc_frame_data *output_frame)
+{
+	struct q6_apr_cmd_session_fill_buffer_packet apr;
+	int rc = 0;
+	struct hal_session *session = sess;
+	struct q6_hfi_device *dev;
+
+	if (!session || !output_frame || !session->device) {
+		dprintk(VIDC_ERR, "Invalid Params");
+		return -EINVAL;
+	}
+	dev = session->device;
+
+	q6_hfi_add_apr_hdr(dev, &apr.hdr, sizeof(apr),
+				   HFI_CMD_SESSION_FILL_BUFFER);
+
+	rc = create_pkt_cmd_session_ftb(&apr.pkt, (u32)session, output_frame);
+	if (rc) {
+		dprintk(VIDC_ERR, "Session ftb: failed to create pkt");
+		goto err_create_pkt;
+	}
+
+	dprintk(VIDC_INFO, "Q OUTPUT BUFFER");
+	rc = apr_send_pkt(dev->apr, (uint32_t *)&apr);
+	if (rc != apr.hdr.pkt_size) {
+		dprintk(VIDC_ERR, "%s: apr_send_pkt failed rc: %d",
+				__func__, rc);
+		rc = -EBADE;
+	} else
+		rc = 0;
+err_create_pkt:
+	return rc;
+}
+
+static int q6_hfi_session_parse_seq_hdr(void *sess,
+	struct vidc_seq_hdr *seq_hdr)
+{
+	struct q6_apr_cmd_session_parse_sequence_header_packet *apr;
+	int rc = 0;
+	u8 packet[VIDC_IFACEQ_VAR_SMALL_PKT_SIZE];
+	struct hal_session *session = sess;
+	struct q6_hfi_device *dev;
+
+	if (!session || !seq_hdr || !session->device) {
+		dprintk(VIDC_ERR, "Invalid Params");
+		return -EINVAL;
+	}
+	dev = session->device;
+
+	apr = (struct q6_apr_cmd_session_parse_sequence_header_packet *) packet;
+
+	q6_hfi_add_apr_hdr(dev, &apr->hdr, VIDC_IFACEQ_VAR_SMALL_PKT_SIZE,
+			   HFI_CMD_SESSION_PARSE_SEQUENCE_HEADER);
+
+	rc = create_pkt_cmd_session_parse_seq_header(&apr->pkt,
+					(u32)session, seq_hdr);
+	if (rc) {
+		dprintk(VIDC_ERR,
+			"Session parse seq hdr: failed to create pkt");
+		goto err_create_pkt;
+	}
+
+	rc = apr_send_pkt(dev->apr, (uint32_t *)apr);
+	if (rc != apr->hdr.pkt_size) {
+		dprintk(VIDC_ERR, "%s: apr_send_pkt failed rc: %d",
+				__func__, rc);
+		rc = -EBADE;
+	} else
+		rc = 0;
+err_create_pkt:
+	return rc;
+}
+
+static int q6_hfi_session_get_seq_hdr(void *sess,
+	struct vidc_seq_hdr *seq_hdr)
+{
+	struct q6_apr_cmd_session_get_sequence_header_packet *apr;
+	int rc = 0;
+	u8 packet[VIDC_IFACEQ_VAR_SMALL_PKT_SIZE];
+	struct hal_session *session = sess;
+	struct q6_hfi_device *dev;
+
+	if (!session || !seq_hdr || !session->device) {
+		dprintk(VIDC_ERR, "Invalid Params");
+		return -EINVAL;
+	}
+	dev = session->device;
+
+	apr = (struct q6_apr_cmd_session_get_sequence_header_packet *) packet;
+
+	q6_hfi_add_apr_hdr(dev, &apr->hdr, VIDC_IFACEQ_VAR_SMALL_PKT_SIZE,
+				   HFI_CMD_SESSION_GET_SEQUENCE_HEADER);
+
+	rc = create_pkt_cmd_session_get_seq_hdr(&apr->pkt, (u32)session,
+						seq_hdr);
+	if (rc) {
+		dprintk(VIDC_ERR, "Session get seq hdr: failed to create pkt");
+		goto err_create_pkt;
+	}
+
+	rc = apr_send_pkt(dev->apr, (uint32_t *)apr);
+	if (rc != apr->hdr.pkt_size) {
+		dprintk(VIDC_ERR, "%s: apr_send_pkt failed rc: %d",
+				__func__, rc);
+		rc = -EBADE;
+	} else
+		rc = 0;
+err_create_pkt:
+	return rc;
+}
+
+static int q6_hfi_session_get_buf_req(void *sess)
+{
+	struct q6_apr_cmd_session_get_property_packet apr;
+	int rc = 0;
+	struct hal_session *session = sess;
+
+	struct q6_hfi_device *dev;
+
+	if (!session || !session->device) {
+		dprintk(VIDC_ERR, "Invalid Params");
+		return -EINVAL;
+	}
+	dev = session->device;
+
+	q6_hfi_add_apr_hdr(dev, &apr.hdr, sizeof(apr),
+				   HFI_CMD_SESSION_GET_PROPERTY);
+
+	rc = create_pkt_cmd_session_get_buf_req(&apr.pkt, (u32)session);
+	if (rc) {
+		dprintk(VIDC_ERR, "Session get buf req: failed to create pkt");
+		goto err_create_pkt;
+	}
+
+	rc = apr_send_pkt(dev->apr, (uint32_t *)&apr);
+	if (rc != apr.hdr.pkt_size) {
+		dprintk(VIDC_ERR, "%s: apr_send_pkt failed rc: %d",
+				__func__, rc);
+		rc = -EBADE;
+	} else
+		rc = 0;
+err_create_pkt:
+	return rc;
+}
+
+static int q6_hfi_session_flush(void *sess, enum hal_flush flush_mode)
+{
+	struct q6_apr_cmd_session_flush_packet apr;
+	int rc = 0;
+	struct hal_session *session = sess;
+	struct q6_hfi_device *dev;
+
+	if (!session || !session->device) {
+		dprintk(VIDC_ERR, "Invalid Params");
+		return -EINVAL;
+	}
+	dev = session->device;
+
+	q6_hfi_add_apr_hdr(dev, &apr.hdr, sizeof(apr),
+				   HFI_CMD_SESSION_FLUSH);
+
+	rc = create_pkt_cmd_session_flush(&apr.pkt, (u32)session, flush_mode);
+	if (rc) {
+		dprintk(VIDC_ERR, "Session flush: failed to create pkt");
+		goto err_create_pkt;
+	}
+
+	rc = apr_send_pkt(dev->apr, (uint32_t *)&apr);
+	if (rc != apr.hdr.pkt_size) {
+		dprintk(VIDC_ERR, "%s: apr_send_pkt failed rc: %d",
+				__func__, rc);
+		rc = -EBADE;
+	} else
+		rc = 0;
+
+err_create_pkt:
+	return rc;
+}
+
+static int q6_hfi_session_set_property(void *sess,
+	enum hal_property ptype, void *pdata)
+{
+	u8 packet[VIDC_IFACEQ_VAR_LARGE_PKT_SIZE];
+	struct q6_apr_cmd_session_set_property_packet *apr =
+		(struct q6_apr_cmd_session_set_property_packet *) &packet;
+	struct hal_session *session = sess;
+	int rc = 0;
+	struct q6_hfi_device *dev;
+
+	if (!session || !pdata || !session->device) {
+		dprintk(VIDC_ERR, "Invalid Params");
+		return -EINVAL;
+	}
+	dev = session->device;
+	dprintk(VIDC_DBG, "in set_prop,with prop id: 0x%x", ptype);
+
+	q6_hfi_add_apr_hdr(dev, &apr->hdr, VIDC_IFACEQ_VAR_LARGE_PKT_SIZE,
+				 HFI_CMD_SESSION_SET_PROPERTY);
+
+	rc = create_pkt_cmd_session_set_property(&apr->pkt,
+				(u32)session, ptype, pdata);
+	if (rc) {
+		dprintk(VIDC_ERR, "set property: failed to create packet");
+		goto err_create_pkt;
+	}
+
+	rc = apr_send_pkt(dev->apr, (uint32_t *)apr);
+	if (rc != apr->hdr.pkt_size) {
+		dprintk(VIDC_ERR, "%s: apr_send_pkt failed rc: %d",
+				__func__, rc);
+		rc = -EBADE;
+	} else
+		rc = 0;
+
+err_create_pkt:
+	return rc;
+}
+
+static int q6_hfi_session_get_property(void *sess,
+	enum hal_property ptype, void *pdata)
+{
+	struct hal_session *session = sess;
+	struct q6_hfi_device *dev;
+
+	if (!session || !pdata || !session->device) {
+		dprintk(VIDC_ERR, "Invalid Params");
+		return -EINVAL;
+	}
+	dev = session->device;
+
+	dprintk(VIDC_DBG, "IN func: , with property id: %d", ptype);
+
+	switch (ptype) {
+	case HAL_CONFIG_FRAME_RATE:
+		break;
+	case HAL_PARAM_UNCOMPRESSED_FORMAT_SELECT:
+		break;
+	case HAL_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO:
+		break;
+	case HAL_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO:
+		break;
+	case HAL_PARAM_EXTRA_DATA_HEADER_CONFIG:
+		break;
+	case HAL_PARAM_FRAME_SIZE:
+		break;
+	case HAL_CONFIG_REALTIME:
+		break;
+	case HAL_PARAM_BUFFER_COUNT_ACTUAL:
+		break;
+	case HAL_PARAM_NAL_STREAM_FORMAT_SELECT:
+		break;
+	case HAL_PARAM_VDEC_OUTPUT_ORDER:
+		break;
+	case HAL_PARAM_VDEC_PICTURE_TYPE_DECODE:
+		break;
+	case HAL_PARAM_VDEC_OUTPUT2_KEEP_ASPECT_RATIO:
+		break;
+	case HAL_CONFIG_VDEC_POST_LOOP_DEBLOCKER:
+		break;
+	case HAL_PARAM_VDEC_MULTI_STREAM:
+		break;
+	case HAL_PARAM_VDEC_DISPLAY_PICTURE_BUFFER_COUNT:
+		break;
+	case HAL_PARAM_DIVX_FORMAT:
+		break;
+	case HAL_CONFIG_VDEC_MB_ERROR_MAP_REPORTING:
+		break;
+	case HAL_PARAM_VDEC_CONTINUE_DATA_TRANSFER:
+		break;
+	case HAL_CONFIG_VDEC_MB_ERROR_MAP:
+		break;
+	case HAL_CONFIG_VENC_REQUEST_IFRAME:
+		break;
+	case HAL_PARAM_VENC_MPEG4_SHORT_HEADER:
+		break;
+	case HAL_PARAM_VENC_MPEG4_AC_PREDICTION:
+		break;
+	case HAL_CONFIG_VENC_TARGET_BITRATE:
+		break;
+	case HAL_PARAM_PROFILE_LEVEL_CURRENT:
+		break;
+	case HAL_PARAM_VENC_H264_ENTROPY_CONTROL:
+		break;
+	case HAL_PARAM_VENC_RATE_CONTROL:
+		break;
+	case HAL_PARAM_VENC_MPEG4_TIME_RESOLUTION:
+		break;
+	case HAL_PARAM_VENC_MPEG4_HEADER_EXTENSION:
+		break;
+	case HAL_PARAM_VENC_H264_DEBLOCK_CONTROL:
+		break;
+	case HAL_PARAM_VENC_SESSION_QP:
+		break;
+	case HAL_CONFIG_VENC_INTRA_PERIOD:
+		break;
+	case HAL_CONFIG_VENC_IDR_PERIOD:
+		break;
+	case HAL_CONFIG_VPE_OPERATIONS:
+		break;
+	case HAL_PARAM_VENC_INTRA_REFRESH:
+		break;
+	case HAL_PARAM_VENC_MULTI_SLICE_CONTROL:
+		break;
+	case HAL_CONFIG_VPE_DEINTERLACE:
+		break;
+	case HAL_SYS_DEBUG_CONFIG:
+		break;
+	/*FOLLOWING PROPERTIES ARE NOT IMPLEMENTED IN CORE YET*/
+	case HAL_CONFIG_BUFFER_REQUIREMENTS:
+	case HAL_CONFIG_PRIORITY:
+	case HAL_CONFIG_BATCH_INFO:
+	case HAL_PARAM_METADATA_PASS_THROUGH:
+	case HAL_SYS_IDLE_INDICATOR:
+	case HAL_PARAM_UNCOMPRESSED_FORMAT_SUPPORTED:
+	case HAL_PARAM_INTERLACE_FORMAT_SUPPORTED:
+	case HAL_PARAM_CHROMA_SITE:
+	case HAL_PARAM_PROPERTIES_SUPPORTED:
+	case HAL_PARAM_PROFILE_LEVEL_SUPPORTED:
+	case HAL_PARAM_CAPABILITY_SUPPORTED:
+	case HAL_PARAM_NAL_STREAM_FORMAT_SUPPORTED:
+	case HAL_PARAM_MULTI_VIEW_FORMAT:
+	case HAL_PARAM_MAX_SEQUENCE_HEADER_SIZE:
+	case HAL_PARAM_CODEC_SUPPORTED:
+	case HAL_PARAM_VDEC_MULTI_VIEW_SELECT:
+	case HAL_PARAM_VDEC_MB_QUANTIZATION:
+	case HAL_PARAM_VDEC_NUM_CONCEALED_MB:
+	case HAL_PARAM_VDEC_H264_ENTROPY_SWITCHING:
+	case HAL_PARAM_VENC_SLICE_DELIVERY_MODE:
+	case HAL_PARAM_VENC_MPEG4_DATA_PARTITIONING:
+
+	case HAL_CONFIG_BUFFER_COUNT_ACTUAL:
+	case HAL_CONFIG_VDEC_MULTI_STREAM:
+	case HAL_PARAM_VENC_MULTI_SLICE_INFO:
+	case HAL_CONFIG_VENC_TIMESTAMP_SCALE:
+	case HAL_PARAM_VENC_LOW_LATENCY:
+	default:
+		dprintk(VIDC_INFO, "DEFAULT: Calling 0x%x", ptype);
+		break;
+	}
+	return 0;
+}
+
+static int q6_hfi_scale_clocks(void *dev, int load)
+{
+	(void)dev;
+	(void)load;
+
+	/* Q6 does not support clocks scaling */
+	return 0;
+}
+
+static int q6_hfi_scale_bus(void *dev, int load,
+			enum session_type type, enum mem_type mtype)
+{
+	(void)dev;
+	(void)load;
+	(void)type;
+	(void)mtype;
+
+	/* Q6 does not support bus scaling */
+	return 0;
+
+}
+
+static int q6_hfi_unset_ocmem(void *dev)
+{
+	(void)dev;
+
+	/* Q6 does not support ocmem */
+	return -EINVAL;
+}
+
+static int q6_hfi_alloc_ocmem(void *dev, unsigned long size)
+{
+	(void)dev;
+	(void)size;
+
+	/* Q6 does not support ocmem */
+	return 0;
+}
+
+static int q6_hfi_free_ocmem(void *dev)
+{
+	(void)dev;
+
+	/* Q6 does not support ocmem */
+	return 0;
+}
+
+static int q6_hfi_is_ocmem_present(void *dev)
+{
+	(void)dev;
+
+	/* Q6 does not support ocmem */
+	return 0;
+}
+
+static int q6_hfi_get_domain(void *dev, enum msm_vidc_io_maps iomap)
+{
+	(void)dev;
+	(void)iomap;
+
+	dprintk(VIDC_ERR, "Not implemented: %s", __func__);
+
+	return 0;
+}
+
+static int q6_hfi_iommu_get_map(void *dev,
+			struct msm_vidc_iommu_info maps[MAX_MAP])
+{
+	(void)dev;
+	(void)maps;
+
+	dprintk(VIDC_ERR, "Not implemented: %s", __func__);
+
+	return 0;
+}
+
+static int q6_hfi_iommu_attach(void *dev)
+{
+	(void)dev;
+
+	dprintk(VIDC_ERR, "Not implemented: %s", __func__);
+
+	return 0;
+}
+
+static int q6_hfi_load_fw(void *dev)
+{
+	int rc = 0;
+	struct q6_hfi_device *device = dev;
+
+	if (!device)
+		return -EINVAL;
+
+	/*Set Q6 to loaded state*/
+	apr_set_q6_state(APR_SUBSYS_LOADED);
+
+	device->apr = apr_register("ADSP", "VIDC",
+				(apr_fn)q6_hfi_apr_callback,
+				0xFFFFFFFF,
+				device);
+
+	if (device->apr == NULL) {
+		dprintk(VIDC_ERR, "Failed to register with QDSP6");
+		rc = -EINVAL;
+		goto fail_apr_register;
+	}
+
+	rc = q6_hfi_iommu_attach(device);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to attach iommu");
+		goto fail_iommu_attach;
+	}
+
+	return rc;
+
+fail_iommu_attach:
+	apr_deregister(device->apr);
+fail_apr_register:
+	subsystem_put(device->resources.fw.cookie);
+	device->resources.fw.cookie = NULL;
+	return rc;
+}
+
+static void q6_hfi_unload_fw(void *hfi_device_data)
+{
+	struct q6_hfi_device *device = hfi_device_data;
+
+	if (!device)
+		return;
+	if (device->apr)
+		apr_deregister(device->apr);
+}
+
+static int q6_hfi_get_fw_info(void *dev, enum fw_info info)
+{
+	(void)dev;
+	(void)info;
+
+	return 0;
+}
+
+static void q6_init_hfi_callbacks(struct hfi_device *hdev)
+{
+	hdev->core_init = q6_hfi_core_init;
+	hdev->core_release = q6_hfi_core_release;
+	hdev->core_pc_prep = q6_hfi_core_pc_prep;
+	hdev->core_ping = q6_hfi_core_ping;
+	hdev->session_init = q6_hfi_session_init;
+	hdev->session_end = q6_hfi_session_end;
+	hdev->session_abort = q6_hfi_session_abort;
+	hdev->session_set_buffers = q6_hfi_session_set_buffers;
+	hdev->session_release_buffers = q6_hfi_session_release_buffers;
+	hdev->session_load_res = q6_hfi_session_load_res;
+	hdev->session_release_res = q6_hfi_session_release_res;
+	hdev->session_start = q6_hfi_session_start;
+	hdev->session_stop = q6_hfi_session_stop;
+	hdev->session_suspend = q6_hfi_session_suspend;
+	hdev->session_resume = q6_hfi_session_resume;
+	hdev->session_etb = q6_hfi_session_etb;
+	hdev->session_ftb = q6_hfi_session_ftb;
+	hdev->session_parse_seq_hdr = q6_hfi_session_parse_seq_hdr;
+	hdev->session_get_seq_hdr = q6_hfi_session_get_seq_hdr;
+	hdev->session_get_buf_req = q6_hfi_session_get_buf_req;
+	hdev->session_flush = q6_hfi_session_flush;
+	hdev->session_set_property = q6_hfi_session_set_property;
+	hdev->session_get_property = q6_hfi_session_get_property;
+	hdev->scale_clocks = q6_hfi_scale_clocks;
+	hdev->scale_bus = q6_hfi_scale_bus;
+	hdev->unset_ocmem = q6_hfi_unset_ocmem;
+	hdev->alloc_ocmem = q6_hfi_alloc_ocmem;
+	hdev->free_ocmem = q6_hfi_free_ocmem;
+	hdev->is_ocmem_present = q6_hfi_is_ocmem_present;
+	hdev->get_domain = q6_hfi_get_domain;
+	hdev->iommu_get_map = q6_hfi_iommu_get_map;
+	hdev->load_fw = q6_hfi_load_fw;
+	hdev->unload_fw = q6_hfi_unload_fw;
+	hdev->get_fw_info = q6_hfi_get_fw_info;
+}
+
+
+int q6_hfi_initialize(struct hfi_device *hdev, u32 device_id,
+		hfi_cmd_response_callback callback)
+{
+	int rc = 0;
+
+	if (!hdev || !callback) {
+		dprintk(VIDC_ERR, "Invalid params: %p %p\n", hdev, callback);
+		rc = -EINVAL;
+		goto err_hfi_init;
+	}
+	hdev->hfi_device_data = q6_hfi_get_device(device_id, callback);
+
+	q6_init_hfi_callbacks(hdev);
+
+err_hfi_init:
+	return rc;
+}
+
diff --git a/drivers/media/platform/msm/vidc/q6_hfi.h b/drivers/media/platform/msm/vidc/q6_hfi.h
new file mode 100644
index 0000000..551eb04
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/q6_hfi.h
@@ -0,0 +1,116 @@
+/* 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 __Q6_HFI_H__
+#define __Q6_HFI_H__
+
+#include "vidc_hfi.h"
+#include "vidc_hfi_helper.h"
+#include <mach/qdsp6v2/apr.h>
+
+#define Q6_IFACEQ_QUEUE_SIZE (8 * 1024)
+
+struct q6_resources {
+	struct msm_vidc_fw fw;
+};
+
+struct q6_iface_q_info {
+	spinlock_t lock;
+	u32 q_size;
+	u32 read_idx;
+	u32 write_idx;
+	u8 *buffer;
+};
+
+struct q6_hfi_device {
+	struct list_head list;
+	struct list_head sess_head;
+	struct q6_iface_q_info event_queue;
+	struct workqueue_struct *vidc_workq;
+	struct work_struct vidc_worker;
+	u32 device_id;
+	msm_vidc_callback callback;
+	struct q6_resources resources;
+	void *apr;
+};
+
+struct q6_apr_cmd_sys_init_packet {
+	struct apr_hdr hdr;
+	struct hfi_cmd_sys_init_packet pkt;
+};
+
+struct q6_apr_cmd_sys_session_init_packet {
+	struct apr_hdr hdr;
+	struct hfi_cmd_sys_session_init_packet pkt;
+};
+
+struct q6_apr_session_cmd_pkt {
+	struct apr_hdr hdr;
+	struct vidc_hal_session_cmd_pkt pkt;
+};
+
+struct q6_apr_cmd_session_set_buffers_packet {
+	struct apr_hdr hdr;
+	struct hfi_cmd_session_set_buffers_packet pkt;
+};
+
+struct q6_apr_cmd_session_release_buffer_packet {
+	struct apr_hdr hdr;
+	struct hfi_cmd_session_release_buffer_packet pkt;
+};
+
+struct q6_apr_cmd_session_empty_buffer_compressed_packet {
+	struct apr_hdr hdr;
+	struct hfi_cmd_session_empty_buffer_compressed_packet pkt;
+};
+
+struct q6_apr_cmd_session_empty_buffer_uncompressed_plane0_packet {
+	struct apr_hdr hdr;
+	struct hfi_cmd_session_empty_buffer_uncompressed_plane0_packet pkt;
+};
+
+struct q6_apr_cmd_session_fill_buffer_packet {
+	struct apr_hdr hdr;
+	struct hfi_cmd_session_fill_buffer_packet pkt;
+};
+
+struct q6_apr_cmd_session_parse_sequence_header_packet {
+	struct apr_hdr hdr;
+	struct hfi_cmd_session_parse_sequence_header_packet pkt;
+};
+
+struct q6_apr_cmd_session_get_sequence_header_packet {
+	struct apr_hdr hdr;
+	struct hfi_cmd_session_get_sequence_header_packet pkt;
+};
+
+struct q6_apr_cmd_session_get_property_packet {
+	struct apr_hdr hdr;
+	struct hfi_cmd_session_get_property_packet pkt;
+};
+
+struct q6_apr_cmd_session_flush_packet {
+	struct apr_hdr hdr;
+	struct hfi_cmd_session_flush_packet pkt;
+};
+
+struct q6_apr_cmd_session_set_property_packet {
+	struct apr_hdr hdr;
+	struct hfi_cmd_session_set_property_packet pkt;
+};
+
+int q6_hfi_initialize(struct hfi_device *hdev, u32 device_id,
+		hfi_cmd_response_callback callback);
+
+void q6_hfi_delete_device(void *device);
+
+#endif /*#ifndef  __Q6_HFI_H__ */
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
new file mode 100644
index 0000000..af8b761
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -0,0 +1,2863 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/iommu.h>
+#include <mach/iommu.h>
+#include <mach/iommu_domains.h>
+#include <mach/ocmem.h>
+#include <mach/scm.h>
+#include <mach/subsystem_restart.h>
+#include <asm/memory.h>
+#include "hfi_packetization.h"
+#include "venus_hfi.h"
+#include "vidc_hfi_io.h"
+#include "msm_vidc_debug.h"
+
+#define FIRMWARE_SIZE			0X00A00000
+#define REG_ADDR_OFFSET_BITMASK	0x000FFFFF
+
+/*Workaround for simulator */
+#define HFI_SIM_FW_BIAS		0x0
+
+#define SHARED_QSIZE 0x1000000
+
+static const u32 venus_qdss_entries[][2] = {
+	{0xFC307000, 0x1000},
+	{0xFC322000, 0x1000},
+	{0xFC319000, 0x1000},
+	{0xFC31A000, 0x1000},
+	{0xFC31B000, 0x1000},
+	{0xFC321000, 0x1000},
+	{0xFA180000, 0x1000},
+	{0xFA181000, 0x1000},
+};
+
+#define TZBSP_MEM_PROTECT_VIDEO_VAR 0x8
+struct tzbsp_memprot {
+	u32 cp_start;
+	u32 cp_size;
+	u32 cp_nonpixel_start;
+	u32 cp_nonpixel_size;
+};
+
+struct tzbsp_resp {
+	int ret;
+};
+
+static void venus_hfi_sim_modify_cmd_packet(u8 *packet)
+{
+	struct hfi_cmd_sys_session_init_packet *sys_init;
+	struct hal_session *sess;
+	u8 i;
+
+	if (!packet) {
+		dprintk(VIDC_ERR, "Invalid Param");
+		return;
+	}
+
+	sys_init = (struct hfi_cmd_sys_session_init_packet *)packet;
+	sess = (struct hal_session *) sys_init->session_id;
+	switch (sys_init->packet_type) {
+	case HFI_CMD_SESSION_EMPTY_BUFFER:
+		if (sess->is_decoder) {
+			struct hfi_cmd_session_empty_buffer_compressed_packet
+			*pkt = (struct
+			hfi_cmd_session_empty_buffer_compressed_packet
+			*) packet;
+			pkt->packet_buffer -= HFI_SIM_FW_BIAS;
+		} else {
+			struct
+			hfi_cmd_session_empty_buffer_uncompressed_plane0_packet
+			*pkt = (struct
+			hfi_cmd_session_empty_buffer_uncompressed_plane0_packet
+			*) packet;
+			pkt->packet_buffer -= HFI_SIM_FW_BIAS;
+		}
+		break;
+	case HFI_CMD_SESSION_FILL_BUFFER:
+	{
+		struct hfi_cmd_session_fill_buffer_packet *pkt =
+			(struct hfi_cmd_session_fill_buffer_packet *)packet;
+		pkt->packet_buffer -= HFI_SIM_FW_BIAS;
+		break;
+	}
+	case HFI_CMD_SESSION_SET_BUFFERS:
+	{
+		struct hfi_cmd_session_set_buffers_packet *pkt =
+			(struct hfi_cmd_session_set_buffers_packet *)packet;
+		if ((pkt->buffer_type == HFI_BUFFER_OUTPUT) ||
+			(pkt->buffer_type == HFI_BUFFER_OUTPUT2)) {
+			struct hfi_buffer_info *buff;
+			buff = (struct hfi_buffer_info *) pkt->rg_buffer_info;
+			buff->buffer_addr -= HFI_SIM_FW_BIAS;
+			buff->extra_data_addr -= HFI_SIM_FW_BIAS;
+		} else {
+			for (i = 0; i < pkt->num_buffers; i++)
+				pkt->rg_buffer_info[i] -= HFI_SIM_FW_BIAS;
+		}
+		break;
+	}
+	case HFI_CMD_SESSION_RELEASE_BUFFERS:
+	{
+		struct hfi_cmd_session_release_buffer_packet *pkt =
+			(struct hfi_cmd_session_release_buffer_packet *)packet;
+		if ((pkt->buffer_type == HFI_BUFFER_OUTPUT) ||
+			(pkt->buffer_type == HFI_BUFFER_OUTPUT2)) {
+			struct hfi_buffer_info *buff;
+			buff = (struct hfi_buffer_info *) pkt->rg_buffer_info;
+			buff->buffer_addr -= HFI_SIM_FW_BIAS;
+			buff->extra_data_addr -= HFI_SIM_FW_BIAS;
+		} else {
+			for (i = 0; i < pkt->num_buffers; i++)
+				pkt->rg_buffer_info[i] -= HFI_SIM_FW_BIAS;
+		}
+		break;
+	}
+	case HFI_CMD_SESSION_PARSE_SEQUENCE_HEADER:
+	{
+		struct hfi_cmd_session_parse_sequence_header_packet *pkt =
+			(struct hfi_cmd_session_parse_sequence_header_packet *)
+		packet;
+		pkt->packet_buffer -= HFI_SIM_FW_BIAS;
+		break;
+	}
+	case HFI_CMD_SESSION_GET_SEQUENCE_HEADER:
+	{
+		struct hfi_cmd_session_get_sequence_header_packet *pkt =
+			(struct hfi_cmd_session_get_sequence_header_packet *)
+		packet;
+		pkt->packet_buffer -= HFI_SIM_FW_BIAS;
+		break;
+	}
+	default:
+		break;
+	}
+}
+
+static int venus_hfi_write_queue(void *info, u8 *packet, u32 *rx_req_is_set)
+{
+	struct hfi_queue_header *queue;
+	u32 packet_size_in_words, new_write_idx;
+	struct vidc_iface_q_info *qinfo;
+	u32 empty_space, read_idx;
+	u32 *write_ptr;
+
+	if (!info || !packet || !rx_req_is_set) {
+		dprintk(VIDC_ERR, "Invalid Params");
+		return -EINVAL;
+	}
+
+	qinfo =	(struct vidc_iface_q_info *) info;
+	venus_hfi_sim_modify_cmd_packet(packet);
+
+	queue = (struct hfi_queue_header *) qinfo->q_hdr;
+
+	if (!queue) {
+		dprintk(VIDC_ERR, "queue not present");
+		return -ENOENT;
+	}
+
+	packet_size_in_words = (*(u32 *)packet) >> 2;
+	dprintk(VIDC_DBG, "Packet_size in words: %d", packet_size_in_words);
+
+	if (packet_size_in_words == 0) {
+		dprintk(VIDC_ERR, "Zero packet size");
+		return -ENODATA;
+	}
+
+	read_idx = queue->qhdr_read_idx;
+
+	empty_space = (queue->qhdr_write_idx >=  read_idx) ?
+		(queue->qhdr_q_size - (queue->qhdr_write_idx -  read_idx)) :
+		(read_idx - queue->qhdr_write_idx);
+	dprintk(VIDC_DBG, "Empty_space: %d", empty_space);
+	if (empty_space <= packet_size_in_words) {
+		queue->qhdr_tx_req =  1;
+		dprintk(VIDC_ERR, "Insufficient size (%d) to write (%d)",
+					  empty_space, packet_size_in_words);
+		return -ENOTEMPTY;
+	}
+
+	queue->qhdr_tx_req =  0;
+
+	new_write_idx = (queue->qhdr_write_idx + packet_size_in_words);
+	write_ptr = (u32 *)((qinfo->q_array.align_virtual_addr) +
+		(queue->qhdr_write_idx << 2));
+	dprintk(VIDC_DBG, "Write Ptr: %d", (u32) write_ptr);
+	if (new_write_idx < queue->qhdr_q_size) {
+		memcpy(write_ptr, packet, packet_size_in_words << 2);
+	} else {
+		new_write_idx -= queue->qhdr_q_size;
+		memcpy(write_ptr, packet, (packet_size_in_words -
+			new_write_idx) << 2);
+		memcpy((void *)qinfo->q_array.align_virtual_addr,
+			packet + ((packet_size_in_words - new_write_idx) << 2),
+			new_write_idx  << 2);
+	}
+	queue->qhdr_write_idx = new_write_idx;
+	*rx_req_is_set = (1 == queue->qhdr_rx_req) ? 1 : 0;
+	dprintk(VIDC_DBG, "Out : ");
+	return 0;
+}
+
+static void venus_hfi_hal_sim_modify_msg_packet(u8 *packet)
+{
+	struct hfi_msg_sys_session_init_done_packet *sys_idle;
+	struct hal_session *sess;
+
+	if (!packet) {
+		dprintk(VIDC_ERR, "Invalid Param: ");
+		return;
+	}
+
+	sys_idle = (struct hfi_msg_sys_session_init_done_packet *)packet;
+	sess = (struct hal_session *) sys_idle->session_id;
+
+	switch (sys_idle->packet_type) {
+	case HFI_MSG_SESSION_FILL_BUFFER_DONE:
+		if (sess->is_decoder) {
+			struct
+			hfi_msg_session_fbd_uncompressed_plane0_packet
+			*pkt_uc = (struct
+			hfi_msg_session_fbd_uncompressed_plane0_packet
+			*) packet;
+			pkt_uc->packet_buffer += HFI_SIM_FW_BIAS;
+		} else {
+			struct
+			hfi_msg_session_fill_buffer_done_compressed_packet
+			*pkt = (struct
+			hfi_msg_session_fill_buffer_done_compressed_packet
+			*) packet;
+			pkt->packet_buffer += HFI_SIM_FW_BIAS;
+		}
+		break;
+	case HFI_MSG_SESSION_EMPTY_BUFFER_DONE:
+	{
+		struct hfi_msg_session_empty_buffer_done_packet *pkt =
+		(struct hfi_msg_session_empty_buffer_done_packet *)packet;
+		pkt->packet_buffer += HFI_SIM_FW_BIAS;
+		break;
+	}
+	case HFI_MSG_SESSION_GET_SEQUENCE_HEADER_DONE:
+	{
+		struct
+		hfi_msg_session_get_sequence_header_done_packet
+		*pkt =
+		(struct hfi_msg_session_get_sequence_header_done_packet *)
+		packet;
+		pkt->sequence_header += HFI_SIM_FW_BIAS;
+		break;
+	}
+	default:
+		break;
+	}
+}
+
+static int venus_hfi_read_queue(void *info, u8 *packet, u32 *pb_tx_req_is_set)
+{
+	struct hfi_queue_header *queue;
+	u32 packet_size_in_words, new_read_idx;
+	u32 *read_ptr;
+	struct vidc_iface_q_info *qinfo;
+
+	if (!info || !packet || !pb_tx_req_is_set) {
+		dprintk(VIDC_ERR, "Invalid Params");
+		return -EINVAL;
+	}
+
+	qinfo =	(struct vidc_iface_q_info *) info;
+	queue = (struct hfi_queue_header *) qinfo->q_hdr;
+
+	if (!queue) {
+		dprintk(VIDC_ERR, "Queue memory is not allocated\n");
+		return -ENOMEM;
+	}
+
+	if (queue->qhdr_read_idx == queue->qhdr_write_idx) {
+		queue->qhdr_rx_req = 1;
+		*pb_tx_req_is_set = 0;
+		return -EPERM;
+	}
+
+	read_ptr = (u32 *)((qinfo->q_array.align_virtual_addr) +
+				(queue->qhdr_read_idx << 2));
+	packet_size_in_words = (*read_ptr) >> 2;
+	dprintk(VIDC_DBG, "packet_size_in_words: %d", packet_size_in_words);
+	if (packet_size_in_words == 0) {
+		dprintk(VIDC_ERR, "Zero packet size");
+		return -ENODATA;
+	}
+
+	new_read_idx = queue->qhdr_read_idx + packet_size_in_words;
+	dprintk(VIDC_DBG, "Read Ptr: %d", (u32) new_read_idx);
+	if (new_read_idx < queue->qhdr_q_size) {
+		memcpy(packet, read_ptr,
+			packet_size_in_words << 2);
+	} else {
+		new_read_idx -= queue->qhdr_q_size;
+		memcpy(packet, read_ptr,
+			(packet_size_in_words - new_read_idx) << 2);
+		memcpy(packet + ((packet_size_in_words -
+			new_read_idx) << 2),
+			(u8 *)qinfo->q_array.align_virtual_addr,
+			new_read_idx << 2);
+	}
+
+	queue->qhdr_read_idx = new_read_idx;
+
+	if (queue->qhdr_read_idx != queue->qhdr_write_idx)
+		queue->qhdr_rx_req = 0;
+	else
+		queue->qhdr_rx_req = 1;
+
+	*pb_tx_req_is_set = (1 == queue->qhdr_tx_req) ? 1 : 0;
+	venus_hfi_hal_sim_modify_msg_packet(packet);
+	dprintk(VIDC_DBG, "Out : ");
+	return 0;
+}
+
+static int venus_hfi_alloc(void *mem, void *clnt, u32 size, u32 align,
+						   u32 flags, int domain)
+{
+	struct vidc_mem_addr *vmem;
+	struct msm_smem *alloc;
+	int rc = 0;
+
+	if (!mem || !clnt || !size) {
+		dprintk(VIDC_ERR, "Invalid Params");
+		return -EINVAL;
+	}
+	vmem = (struct vidc_mem_addr *)mem;
+	dprintk(VIDC_INFO, "start to alloc: size:%d, Flags: %d", size, flags);
+
+	alloc  = msm_smem_alloc(clnt, size, align, flags, domain, 1, 1);
+	dprintk(VIDC_DBG, "Alloc done");
+	if (!alloc) {
+		dprintk(VIDC_ERR, "Alloc failed\n");
+		rc = -ENOMEM;
+		goto fail_smem_alloc;
+	}
+	dprintk(VIDC_DBG, "venus_hfi_alloc:ptr=%p,size=%d",
+			alloc->kvaddr, size);
+	rc = msm_smem_cache_operations(clnt, alloc,
+		SMEM_CACHE_CLEAN);
+	if (rc) {
+		dprintk(VIDC_WARN, "Failed to clean cache\n");
+		dprintk(VIDC_WARN, "This may result in undefined behavior\n");
+	}
+	vmem->mem_size = alloc->size;
+	vmem->mem_data = alloc;
+	vmem->align_virtual_addr = (u8 *) alloc->kvaddr;
+	vmem->align_device_addr = (u8 *)alloc->device_addr;
+	return rc;
+fail_smem_alloc:
+	return rc;
+}
+
+static void venus_hfi_free(struct smem_client *clnt, struct msm_smem *mem)
+{
+	msm_smem_free(clnt, mem);
+}
+
+static void venus_hfi_write_register(u8 *base_addr, u32 reg,
+				u32 value, u8 *vaddr)
+{
+	u32 hwiosymaddr = reg;
+
+	reg &= REG_ADDR_OFFSET_BITMASK;
+	if (reg == (u32)VIDC_CPU_CS_SCIACMDARG2) {
+		/* workaround to offset of FW bias */
+		struct hfi_queue_header *qhdr;
+		struct hfi_queue_table_header *qtbl_hdr =
+			(struct hfi_queue_table_header *)vaddr;
+
+		qhdr = VIDC_IFACEQ_GET_QHDR_START_ADDR(qtbl_hdr, 0);
+		qhdr->qhdr_start_addr -= HFI_SIM_FW_BIAS;
+
+		qhdr = VIDC_IFACEQ_GET_QHDR_START_ADDR(qtbl_hdr, 1);
+		qhdr->qhdr_start_addr -= HFI_SIM_FW_BIAS;
+
+		qhdr = VIDC_IFACEQ_GET_QHDR_START_ADDR(qtbl_hdr, 2);
+		qhdr->qhdr_start_addr -= HFI_SIM_FW_BIAS;
+		value -= HFI_SIM_FW_BIAS;
+	}
+
+	hwiosymaddr = ((u32)base_addr + (hwiosymaddr));
+	dprintk(VIDC_DBG, "Base addr: 0x%x, written to: 0x%x, Value: 0x%x...",
+			(u32)base_addr, hwiosymaddr, value);
+	writel_relaxed(value, hwiosymaddr);
+	wmb();
+}
+
+static int venus_hfi_read_register(u8 *base_addr, u32 reg)
+{
+	int rc = readl_relaxed((u32)base_addr + reg);
+	rmb();
+	return rc;
+}
+static inline void venus_hfi_clk_gating_on(struct venus_hfi_device *device,
+	enum vidc_clocks clk_level)
+{
+	int i;
+	struct venus_core_clock *cl;
+	if (!device) {
+		dprintk(VIDC_ERR, "Invalid params: %p\n", device);
+		return;
+	}
+	if (device->clocks_enabled == 0) {
+		dprintk(VIDC_DBG, "VCODEC clocks are already disabled");
+		goto already_disabled;
+	}
+	for (i = 0; i < clk_level; i++) {
+		cl = &device->resources.clock[i];
+		clk_disable_unprepare(cl->clk);
+	}
+already_disabled:
+	device->clocks_enabled = 0;
+}
+static inline int venus_hfi_clk_gating_off(struct venus_hfi_device *device,
+	enum vidc_clocks clk_level)
+{
+	int i;
+	struct venus_core_clock *cl;
+	int rc = 0;
+	if (!device) {
+		dprintk(VIDC_ERR, "Invalid params: %p\n", device);
+		return -EINVAL;
+	}
+	if (device->clocks_enabled == 1) {
+		dprintk(VIDC_DBG, "VCODEC clocks are already enabled");
+		goto already_enabled;
+	}
+	for (i = 0; i < clk_level; i++) {
+		cl = &device->resources.clock[i];
+		rc = clk_prepare_enable(cl->clk);
+		if (rc) {
+			dprintk(VIDC_ERR, "Failed to enable clocks\n");
+			goto fail_clk_enable;
+		} else {
+			dprintk(VIDC_DBG, "Clock: %s enabled\n", cl->name);
+		}
+	}
+already_enabled:
+	device->clocks_enabled = 1;
+	return rc;
+fail_clk_enable:
+	for (; i >= 0; i--) {
+		cl = &device->resources.clock[i];
+		clk_disable_unprepare(cl->clk);
+	}
+	return rc;
+}
+
+static unsigned long venus_hfi_get_clock_rate(struct venus_core_clock *clock,
+	int num_mbs_per_sec)
+{
+	int num_rows = clock->count;
+	struct load_freq_table *table = clock->load_freq_tbl;
+	unsigned long ret = table[num_rows-1].freq;
+	int i;
+	for (i = 0; i < num_rows; i++) {
+		if (num_mbs_per_sec > table[i].load)
+			break;
+		ret = table[i].freq;
+	}
+	dprintk(VIDC_PROF, "Required clock rate = %lu\n", ret);
+	return ret;
+}
+
+static int venus_hfi_scale_clocks(void *dev, int load)
+{
+	int rc = 0;
+	struct venus_hfi_device *device = dev;
+	device->load = load;
+	if (!device) {
+		dprintk(VIDC_ERR, "Invalid args: %p\n", device);
+		return -EINVAL;
+	}
+	rc = clk_set_rate(device->resources.clock[VCODEC_CLK].clk,
+		venus_hfi_get_clock_rate(&device->resources.clock[VCODEC_CLK],
+			load));
+	if (rc)
+		dprintk(VIDC_ERR, "Failed to set clock rate: %d\n", rc);
+	return rc;
+}
+
+static int venus_hfi_iface_cmdq_write(struct venus_hfi_device *device,
+					void *pkt)
+{
+	u32 rx_req_is_set = 0;
+	struct vidc_iface_q_info *q_info;
+	int result = -EPERM;
+	if (!device || !pkt) {
+		dprintk(VIDC_ERR, "Invalid Params");
+		return -EINVAL;
+	}
+
+	mutex_lock(&device->write_lock);
+	q_info = &device->iface_queues[VIDC_IFACEQ_CMDQ_IDX];
+	if (!q_info) {
+		dprintk(VIDC_ERR, "cannot write to shared Q's");
+		goto err_q_write;
+	}
+	result = venus_hfi_clk_gating_off(device, VCODEC_CLK);
+	if (result) {
+		dprintk(VIDC_ERR, "VCODEC clock enable failed\n");
+		goto err_q_write;
+	}
+	result = venus_hfi_scale_clocks(device, device->load);
+	if (result) {
+		dprintk(VIDC_ERR, "VCODEC clock scaling failed\n");
+		goto err_q_write;
+	}
+	if (!venus_hfi_write_queue(q_info, (u8 *)pkt, &rx_req_is_set)) {
+		if (rx_req_is_set)
+			venus_hfi_write_register(
+				device->hal_data->register_base_addr,
+				VIDC_CPU_IC_SOFTINT,
+				1 << VIDC_CPU_IC_SOFTINT_H2A_SHFT, 0);
+		result = 0;
+	} else {
+		dprintk(VIDC_ERR, "venus_hfi_iface_cmdq_write:queue_full");
+	}
+err_q_write:
+	mutex_unlock(&device->write_lock);
+	return result;
+}
+
+static int venus_hfi_iface_msgq_read(struct venus_hfi_device *device, void *pkt)
+{
+	u32 tx_req_is_set = 0;
+	int rc = 0;
+	struct vidc_iface_q_info *q_info;
+
+	if (!pkt) {
+		dprintk(VIDC_ERR, "Invalid Params");
+		return -EINVAL;
+	}
+	mutex_lock(&device->read_lock);
+	if (device->iface_queues[VIDC_IFACEQ_MSGQ_IDX].
+		q_array.align_virtual_addr == 0) {
+		dprintk(VIDC_ERR, "cannot read from shared MSG Q's");
+		rc = -ENODATA;
+		goto read_error;
+	}
+	q_info = &device->iface_queues[VIDC_IFACEQ_MSGQ_IDX];
+
+	if (!venus_hfi_read_queue(q_info, (u8 *)pkt, &tx_req_is_set)) {
+		if (tx_req_is_set)
+			venus_hfi_write_register(
+				device->hal_data->register_base_addr,
+				VIDC_CPU_IC_SOFTINT,
+				1 << VIDC_CPU_IC_SOFTINT_H2A_SHFT, 0);
+		rc = 0;
+	} else {
+		dprintk(VIDC_INFO, "venus_hfi_iface_msgq_read:queue_empty");
+		rc = -ENODATA;
+	}
+read_error:
+	mutex_unlock(&device->read_lock);
+	return rc;
+}
+
+static int venus_hfi_iface_dbgq_read(struct venus_hfi_device *device, void *pkt)
+{
+	u32 tx_req_is_set = 0;
+	int rc = 0;
+	struct vidc_iface_q_info *q_info;
+
+	if (!pkt) {
+		dprintk(VIDC_ERR, "Invalid Params");
+		return -EINVAL;
+	}
+	mutex_lock(&device->read_lock);
+	if (device->iface_queues[VIDC_IFACEQ_DBGQ_IDX].
+		q_array.align_virtual_addr == 0) {
+		dprintk(VIDC_ERR, "cannot read from shared DBG Q's");
+		rc = -ENODATA;
+		goto dbg_error;
+	}
+	q_info = &device->iface_queues[VIDC_IFACEQ_DBGQ_IDX];
+	if (!venus_hfi_read_queue(q_info, (u8 *)pkt, &tx_req_is_set)) {
+		if (tx_req_is_set)
+			venus_hfi_write_register(
+				device->hal_data->register_base_addr,
+				VIDC_CPU_IC_SOFTINT,
+				1 << VIDC_CPU_IC_SOFTINT_H2A_SHFT, 0);
+		rc = 0;
+	} else {
+		dprintk(VIDC_INFO, "venus_hfi_iface_dbgq_read:queue_empty");
+		rc = -ENODATA;
+	}
+dbg_error:
+	mutex_unlock(&device->read_lock);
+	return rc;
+}
+
+static void venus_hfi_set_queue_hdr_defaults(struct hfi_queue_header *q_hdr)
+{
+	q_hdr->qhdr_status = 0x1;
+	q_hdr->qhdr_type = VIDC_IFACEQ_DFLT_QHDR;
+	q_hdr->qhdr_q_size = VIDC_IFACEQ_QUEUE_SIZE / 4;
+	q_hdr->qhdr_pkt_size = 0;
+	q_hdr->qhdr_rx_wm = 0x1;
+	q_hdr->qhdr_tx_wm = 0x1;
+	q_hdr->qhdr_rx_req = 0x1;
+	q_hdr->qhdr_tx_req = 0x0;
+	q_hdr->qhdr_rx_irq_status = 0x0;
+	q_hdr->qhdr_tx_irq_status = 0x0;
+	q_hdr->qhdr_read_idx = 0x0;
+	q_hdr->qhdr_write_idx = 0x0;
+}
+
+static void venus_hfi_interface_queues_release(struct venus_hfi_device *device)
+{
+	int i;
+	struct hfi_mem_map_table *qdss;
+	struct hfi_mem_map *mem_map;
+	int num_entries = sizeof(venus_qdss_entries)/(2 * sizeof(u32));
+
+	if (device->qdss.mem_data) {
+		qdss = (struct hfi_mem_map_table *)
+			device->qdss.align_virtual_addr;
+		qdss->mem_map_num_entries = num_entries;
+		qdss->mem_map_table_base_addr =
+			(u32 *)((u32)device->qdss.align_device_addr +
+				sizeof(struct hfi_mem_map_table));
+		mem_map = (struct hfi_mem_map *)(qdss + 1);
+		for (i = 0; i < num_entries; i++) {
+			msm_iommu_unmap_contig_buffer(
+				(unsigned long)(mem_map[i].virtual_addr),
+				device->resources.io_map[NS_MAP].domain,
+				1, SZ_4K);
+		}
+		venus_hfi_free(device->hal_client, device->qdss.mem_data);
+	}
+	venus_hfi_free(device->hal_client, device->iface_q_table.mem_data);
+	venus_hfi_free(device->hal_client, device->sfr.mem_data);
+
+	for (i = 0; i < VIDC_IFACEQ_NUMQ; i++) {
+		device->iface_queues[i].q_hdr = NULL;
+		device->iface_queues[i].q_array.mem_data = NULL;
+		device->iface_queues[i].q_array.align_virtual_addr = NULL;
+		device->iface_queues[i].q_array.align_device_addr = NULL;
+	}
+	device->iface_q_table.align_virtual_addr = NULL;
+	device->iface_q_table.align_device_addr = NULL;
+
+	device->qdss.align_virtual_addr = NULL;
+	device->qdss.align_device_addr = NULL;
+
+	device->sfr.align_virtual_addr = NULL;
+	device->sfr.align_device_addr = NULL;
+
+	device->mem_addr.align_virtual_addr = NULL;
+	device->mem_addr.align_device_addr = NULL;
+
+	msm_smem_delete_client(device->hal_client);
+	device->hal_client = NULL;
+}
+static int venus_hfi_get_qdss_iommu_virtual_addr(struct hfi_mem_map *mem_map,
+	int domain)
+{
+	int i;
+	int rc = 0;
+	unsigned long iova = 0;
+	int num_entries = sizeof(venus_qdss_entries)/(2 * sizeof(u32));
+
+	for (i = 0; i < num_entries; i++) {
+		rc = msm_iommu_map_contig_buffer(venus_qdss_entries[i][0],
+			domain, 1 , venus_qdss_entries[i][1],
+			SZ_4K, 0, &iova);
+		if (rc) {
+			dprintk(VIDC_ERR,
+				"IOMMU QDSS mapping failed for addr 0x%x",
+				venus_qdss_entries[i][0]);
+			rc = -ENOMEM;
+			break;
+		}
+		mem_map[i].virtual_addr = (u32) iova;
+		mem_map[i].physical_addr = venus_qdss_entries[i][0];
+		mem_map[i].size = venus_qdss_entries[i][1];
+		mem_map[i].attr = 0x0;
+	}
+	if (i < num_entries) {
+		dprintk(VIDC_ERR,
+			"IOMMU QDSS mapping failed, Freeing entries %d", i);
+		for (--i; i >= 0; i--) {
+			msm_iommu_unmap_contig_buffer(
+				(unsigned long)(mem_map[i].virtual_addr),
+				domain, 1, SZ_4K);
+		}
+	}
+	return rc;
+}
+
+static int venus_hfi_interface_queues_init(struct venus_hfi_device *dev,
+					int domain)
+{
+	struct hfi_queue_table_header *q_tbl_hdr;
+	struct hfi_queue_header *q_hdr;
+	u8 i;
+	int rc = 0;
+	struct hfi_mem_map_table *qdss;
+	struct hfi_mem_map *mem_map;
+	struct vidc_iface_q_info *iface_q;
+	struct hfi_sfr_struct *vsfr;
+	struct vidc_mem_addr *mem_addr;
+	int offset = 0;
+	int num_entries = sizeof(venus_qdss_entries)/(2 * sizeof(u32));
+	mem_addr = &dev->mem_addr;
+	rc = venus_hfi_alloc((void *) mem_addr,
+			dev->hal_client, QUEUE_SIZE, 1,
+			0, domain);
+	if (rc) {
+		dprintk(VIDC_ERR, "iface_q_table_alloc_fail");
+		goto fail_alloc_queue;
+	}
+	dev->iface_q_table.align_virtual_addr = mem_addr->align_virtual_addr;
+	dev->iface_q_table.align_device_addr = mem_addr->align_device_addr;
+	dev->iface_q_table.mem_size = VIDC_IFACEQ_TABLE_SIZE;
+	dev->iface_q_table.mem_data = mem_addr->mem_data;
+	offset += dev->iface_q_table.mem_size;
+
+	for (i = 0; i < VIDC_IFACEQ_NUMQ; i++) {
+		iface_q = &dev->iface_queues[i];
+		iface_q->q_array.align_device_addr =
+			mem_addr->align_device_addr + offset;
+		iface_q->q_array.align_virtual_addr =
+			mem_addr->align_virtual_addr + offset;
+		iface_q->q_array.mem_size = VIDC_IFACEQ_QUEUE_SIZE;
+		iface_q->q_array.mem_data = NULL;
+		offset += iface_q->q_array.mem_size;
+		iface_q->q_hdr = VIDC_IFACEQ_GET_QHDR_START_ADDR(
+				dev->iface_q_table.align_virtual_addr, i);
+		venus_hfi_set_queue_hdr_defaults(iface_q->q_hdr);
+	}
+
+	rc = venus_hfi_alloc((void *) mem_addr,
+			dev->hal_client, QDSS_SIZE, 1,
+			0, domain);
+	if (rc) {
+		dprintk(VIDC_WARN,
+			"qdss_alloc_fail: QDSS messages logging will not work");
+		dev->qdss.align_device_addr = NULL;
+	} else {
+		dev->qdss.align_device_addr = mem_addr->align_device_addr;
+		dev->qdss.align_virtual_addr = mem_addr->align_virtual_addr;
+		dev->qdss.mem_size = QDSS_SIZE;
+		dev->qdss.mem_data = mem_addr->mem_data;
+	}
+	rc = venus_hfi_alloc((void *) mem_addr,
+			dev->hal_client, SFR_SIZE, 1,
+			0, domain);
+	if (rc) {
+		dprintk(VIDC_WARN, "sfr_alloc_fail: SFR not will work");
+		dev->sfr.align_device_addr = NULL;
+	} else {
+		dev->sfr.align_device_addr = mem_addr->align_device_addr;
+		dev->sfr.align_virtual_addr = mem_addr->align_virtual_addr;
+		dev->sfr.mem_size = SFR_SIZE;
+		dev->sfr.mem_data = mem_addr->mem_data;
+	}
+	q_tbl_hdr = (struct hfi_queue_table_header *)
+			dev->iface_q_table.align_virtual_addr;
+	q_tbl_hdr->qtbl_version = 0;
+	q_tbl_hdr->qtbl_size = VIDC_IFACEQ_TABLE_SIZE;
+	q_tbl_hdr->qtbl_qhdr0_offset = sizeof(
+		struct hfi_queue_table_header);
+	q_tbl_hdr->qtbl_qhdr_size = sizeof(
+		struct hfi_queue_header);
+	q_tbl_hdr->qtbl_num_q = VIDC_IFACEQ_NUMQ;
+	q_tbl_hdr->qtbl_num_active_q = VIDC_IFACEQ_NUMQ;
+
+	iface_q = &dev->iface_queues[VIDC_IFACEQ_CMDQ_IDX];
+	q_hdr = iface_q->q_hdr;
+	q_hdr->qhdr_start_addr = (u32)
+		iface_q->q_array.align_device_addr;
+	q_hdr->qhdr_type |= HFI_Q_ID_HOST_TO_CTRL_CMD_Q;
+
+	iface_q = &dev->iface_queues[VIDC_IFACEQ_MSGQ_IDX];
+	q_hdr = iface_q->q_hdr;
+	q_hdr->qhdr_start_addr = (u32)
+		iface_q->q_array.align_device_addr;
+	q_hdr->qhdr_type |= HFI_Q_ID_CTRL_TO_HOST_MSG_Q;
+
+	iface_q = &dev->iface_queues[VIDC_IFACEQ_DBGQ_IDX];
+	q_hdr = iface_q->q_hdr;
+	q_hdr->qhdr_start_addr = (u32)
+		iface_q->q_array.align_device_addr;
+	q_hdr->qhdr_type |= HFI_Q_ID_CTRL_TO_HOST_DEBUG_Q;
+
+	venus_hfi_write_register(dev->hal_data->register_base_addr,
+			VIDC_UC_REGION_ADDR,
+			(u32) dev->iface_q_table.align_device_addr, 0);
+	venus_hfi_write_register(dev->hal_data->register_base_addr,
+			VIDC_UC_REGION_SIZE, SHARED_QSIZE, 0);
+	venus_hfi_write_register(dev->hal_data->register_base_addr,
+		VIDC_CPU_CS_SCIACMDARG2,
+		(u32) dev->iface_q_table.align_device_addr,
+		dev->iface_q_table.align_virtual_addr);
+	venus_hfi_write_register(dev->hal_data->register_base_addr,
+		VIDC_CPU_CS_SCIACMDARG1, 0x01,
+		dev->iface_q_table.align_virtual_addr);
+
+	qdss = (struct hfi_mem_map_table *) dev->qdss.align_virtual_addr;
+	qdss->mem_map_num_entries = num_entries;
+	qdss->mem_map_table_base_addr =
+		(u32 *)	((u32)dev->qdss.align_device_addr +
+		sizeof(struct hfi_mem_map_table));
+	mem_map = (struct hfi_mem_map *)(qdss + 1);
+	rc = venus_hfi_get_qdss_iommu_virtual_addr(mem_map, domain);
+	if (rc) {
+		dprintk(VIDC_ERR,
+			"IOMMU mapping failed, Freeing qdss memdata");
+		venus_hfi_free(dev->hal_client, dev->qdss.mem_data);
+		dev->qdss.mem_data = NULL;
+	}
+	if (!IS_ERR_OR_NULL(dev->qdss.align_device_addr))
+		venus_hfi_write_register(dev->hal_data->register_base_addr,
+			VIDC_MMAP_ADDR,
+			(u32) dev->qdss.align_device_addr, 0);
+
+	vsfr = (struct hfi_sfr_struct *) dev->sfr.align_virtual_addr;
+	vsfr->bufSize = SFR_SIZE;
+	if (!IS_ERR_OR_NULL(dev->sfr.align_device_addr))
+		venus_hfi_write_register(dev->hal_data->register_base_addr,
+			VIDC_SFR_ADDR, (u32)dev->sfr.align_device_addr , 0);
+	return 0;
+fail_alloc_queue:
+	return -ENOMEM;
+}
+
+static int venus_hfi_core_start_cpu(struct venus_hfi_device *device)
+{
+	u32 ctrl_status = 0, count = 0, rc = 0;
+	int max_tries = 100;
+	venus_hfi_write_register(device->hal_data->register_base_addr,
+			VIDC_WRAPPER_INTR_MASK, 0x8, 0);
+	venus_hfi_write_register(device->hal_data->register_base_addr,
+			VIDC_CPU_CS_SCIACMDARG3, 1, 0);
+
+	while (!ctrl_status && count < max_tries) {
+		ctrl_status = venus_hfi_read_register(
+				device->hal_data->register_base_addr,
+				VIDC_CPU_CS_SCIACMDARG0);
+		if ((ctrl_status & 0xFE) == 0x4) {
+			dprintk(VIDC_ERR, "invalid setting for UC_REGION\n");
+			break;
+		}
+		usleep_range(500, 1000);
+		count++;
+	}
+	if (count >= max_tries)
+		rc = -ETIME;
+	return rc;
+}
+
+static void venus_hfi_set_registers(struct venus_hfi_device *device)
+{
+	struct reg_set *reg_set;
+	int i;
+
+	if (!device->res) {
+		dprintk(VIDC_ERR,
+			"device resources null, cannot set registers\n");
+		return;
+	}
+
+	reg_set = &device->res->reg_set;
+	for (i = 0; i < reg_set->count; i++) {
+		venus_hfi_write_register(device->hal_data->register_base_addr,
+				reg_set->reg_tbl[i].reg,
+				reg_set->reg_tbl[i].value, 0);
+	}
+}
+
+static int venus_hfi_sys_set_debug(struct venus_hfi_device *device, int debug)
+{
+	u8 packet[VIDC_IFACEQ_VAR_SMALL_PKT_SIZE];
+	int rc = 0;
+	struct hfi_cmd_sys_set_property_packet *pkt =
+		(struct hfi_cmd_sys_set_property_packet *) &packet;
+	rc = create_pkt_cmd_sys_debug_config(pkt, debug);
+	if (rc) {
+		dprintk(VIDC_WARN,
+			"Debug mode setting to FW failed\n");
+		return -ENOTEMPTY;
+	}
+	if (venus_hfi_iface_cmdq_write(device, pkt))
+		return -ENOTEMPTY;
+	return 0;
+}
+static int venus_hfi_sys_set_idle_message(struct venus_hfi_device *device,
+	int enable)
+{
+	u8 packet[VIDC_IFACEQ_VAR_SMALL_PKT_SIZE];
+	struct hfi_cmd_sys_set_property_packet *pkt =
+		(struct hfi_cmd_sys_set_property_packet *) &packet;
+	create_pkt_cmd_sys_idle_indicator(pkt, enable);
+	if (venus_hfi_iface_cmdq_write(device, pkt))
+		return -ENOTEMPTY;
+	return 0;
+}
+
+
+static int venus_hfi_core_init(void *device)
+{
+	struct hfi_cmd_sys_init_packet pkt;
+	int rc = 0;
+	struct venus_hfi_device *dev;
+
+	if (device) {
+		dev = device;
+	} else {
+		dprintk(VIDC_ERR, "Invalid device");
+		return -ENODEV;
+	}
+
+	dev->intr_status = 0;
+	enable_irq(dev->hal_data->irq);
+	INIT_LIST_HEAD(&dev->sess_head);
+	mutex_init(&dev->read_lock);
+	mutex_init(&dev->write_lock);
+	venus_hfi_set_registers(dev);
+
+	if (!dev->hal_client) {
+		dev->hal_client = msm_smem_new_client(SMEM_ION);
+		if (dev->hal_client == NULL) {
+			dprintk(VIDC_ERR, "Failed to alloc ION_Client");
+			rc = -ENODEV;
+			goto err_core_init;
+		}
+
+		dprintk(VIDC_DBG, "Dev_Virt: 0x%x, Reg_Virt: 0x%x",
+		dev->hal_data->device_base_addr,
+		(u32) dev->hal_data->register_base_addr);
+
+		rc = venus_hfi_interface_queues_init(dev,
+				dev->resources.io_map[NS_MAP].domain);
+		if (rc) {
+			dprintk(VIDC_ERR, "failed to init queues");
+			rc = -ENOMEM;
+			goto err_core_init;
+		}
+	} else {
+		dprintk(VIDC_ERR, "hal_client exists");
+		rc = -EEXIST;
+		goto err_core_init;
+	}
+	venus_hfi_write_register(dev->hal_data->register_base_addr,
+		VIDC_CTRL_INIT, 0x1, 0);
+	rc = venus_hfi_core_start_cpu(dev);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to start core");
+		rc = -ENODEV;
+		goto err_core_init;
+	}
+
+	rc = create_pkt_cmd_sys_init(&pkt, HFI_ARCH_OX_OFFSET);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to create sys init pkt");
+		goto err_core_init;
+	}
+	if (venus_hfi_iface_cmdq_write(dev, &pkt)) {
+		rc = -ENOTEMPTY;
+		goto err_core_init;
+	}
+	return rc;
+err_core_init:
+	disable_irq_nosync(dev->hal_data->irq);
+	return rc;
+}
+
+static int venus_hfi_core_release(void *device)
+{
+	struct venus_hfi_device *dev;
+	if (device) {
+		dev = device;
+	} else {
+		dprintk(VIDC_ERR, "invalid device");
+		return -ENODEV;
+	}
+	if (dev->hal_client) {
+		venus_hfi_write_register(dev->hal_data->register_base_addr,
+				VIDC_CPU_CS_SCIACMDARG3, 0, 0);
+		if (!(dev->intr_status & VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK))
+			disable_irq_nosync(dev->hal_data->irq);
+		dev->intr_status = 0;
+		venus_hfi_interface_queues_release(dev);
+	}
+	dprintk(VIDC_INFO, "HAL exited\n");
+	return 0;
+}
+
+int venus_hfi_core_pc_prep(void *device)
+{
+	struct hfi_cmd_sys_pc_prep_packet pkt;
+	int rc = 0;
+	struct venus_hfi_device *dev;
+
+	if (device) {
+		dev = device;
+	} else {
+		dprintk(VIDC_ERR, "invalid device");
+		return -ENODEV;
+	}
+
+	rc = create_pkt_cmd_sys_pc_prep(&pkt);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to create sys pc prep pkt");
+		goto err_create_pkt;
+	}
+
+	if (venus_hfi_iface_cmdq_write(dev, &pkt))
+		rc = -ENOTEMPTY;
+
+err_create_pkt:
+	return rc;
+}
+
+static void venus_hfi_core_clear_interrupt(struct venus_hfi_device *device)
+{
+	u32 intr_status = 0;
+
+	if (!device->callback)
+		return;
+
+	intr_status = venus_hfi_read_register(
+			device->hal_data->register_base_addr,
+			VIDC_WRAPPER_INTR_STATUS);
+
+	if ((intr_status & VIDC_WRAPPER_INTR_STATUS_A2H_BMSK) ||
+		(intr_status & VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK)) {
+		device->intr_status |= intr_status;
+		dprintk(VIDC_DBG, "INTERRUPT for device: 0x%x: "
+			"times: %d interrupt_status: %d",
+			(u32) device, ++device->reg_count, intr_status);
+	} else {
+		dprintk(VIDC_INFO, "SPURIOUS_INTR for device: 0x%x: "
+			"times: %d interrupt_status: %d",
+			(u32) device, ++device->spur_count, intr_status);
+	}
+	venus_hfi_write_register(device->hal_data->register_base_addr,
+			VIDC_CPU_CS_A2HSOFTINTCLR, 1, 0);
+	venus_hfi_write_register(device->hal_data->register_base_addr,
+			VIDC_WRAPPER_INTR_CLEAR, intr_status, 0);
+	dprintk(VIDC_DBG, "Cleared WRAPPER/A2H interrupt");
+}
+
+static int venus_hfi_core_set_resource(void *device,
+		struct vidc_resource_hdr *resource_hdr, void *resource_value)
+{
+	struct hfi_cmd_sys_set_resource_packet *pkt;
+	u8 packet[VIDC_IFACEQ_VAR_SMALL_PKT_SIZE];
+	int rc = 0;
+	struct venus_hfi_device *dev;
+
+	if (!device || !resource_hdr || !resource_value) {
+		dprintk(VIDC_ERR, "set_res: Invalid Params");
+		return -EINVAL;
+	} else {
+		dev = device;
+	}
+
+	pkt = (struct hfi_cmd_sys_set_resource_packet *) packet;
+
+	rc = create_pkt_set_cmd_sys_resource(pkt, resource_hdr,
+						resource_value);
+	if (rc) {
+		dprintk(VIDC_ERR, "set_res: failed to create packet");
+		goto err_create_pkt;
+	}
+	if (venus_hfi_iface_cmdq_write(dev, pkt))
+		rc = -ENOTEMPTY;
+
+err_create_pkt:
+	return rc;
+}
+
+static int venus_hfi_core_release_resource(void *device,
+			struct vidc_resource_hdr *resource_hdr)
+{
+	struct hfi_cmd_sys_release_resource_packet pkt;
+	int rc = 0;
+	struct venus_hfi_device *dev;
+
+	if (!device || !resource_hdr) {
+		dprintk(VIDC_ERR, "Inv-Params in rel_res");
+		return -EINVAL;
+	} else {
+		dev = device;
+	}
+
+	rc = create_pkt_cmd_sys_release_resource(&pkt, resource_hdr);
+	if (rc) {
+		dprintk(VIDC_ERR, "release_res: failed to create packet");
+		goto err_create_pkt;
+	}
+
+	if (venus_hfi_iface_cmdq_write(dev, &pkt))
+		rc = -ENOTEMPTY;
+
+err_create_pkt:
+	return rc;
+}
+
+static int venus_hfi_core_ping(void *device)
+{
+	struct hfi_cmd_sys_ping_packet pkt;
+	int rc = 0;
+	struct venus_hfi_device *dev;
+
+	if (device) {
+		dev = device;
+	} else {
+		dprintk(VIDC_ERR, "invalid device");
+		return -ENODEV;
+	}
+
+	rc = create_pkt_cmd_sys_ping(&pkt);
+	if (rc) {
+		dprintk(VIDC_ERR, "core_ping: failed to create packet");
+		goto err_create_pkt;
+	}
+
+	if (venus_hfi_iface_cmdq_write(dev, &pkt))
+		rc = -ENOTEMPTY;
+
+err_create_pkt:
+	return rc;
+}
+
+static int venus_hfi_core_trigger_ssr(void *device,
+	enum hal_ssr_trigger_type type)
+{
+	struct hfi_cmd_sys_test_ssr_packet pkt;
+	int rc = 0;
+	struct venus_hfi_device *dev;
+
+	if (device) {
+		dev = device;
+	} else {
+		dprintk(VIDC_ERR, "invalid device");
+		return -ENODEV;
+	}
+
+	rc = create_pkt_ssr_cmd(type, &pkt);
+	if (rc) {
+		dprintk(VIDC_ERR, "core_ping: failed to create packet");
+		goto err_create_pkt;
+	}
+
+	if (venus_hfi_iface_cmdq_write(dev, &pkt))
+		rc = -ENOTEMPTY;
+
+err_create_pkt:
+	return rc;
+}
+
+static int venus_hfi_session_set_property(void *sess,
+					enum hal_property ptype, void *pdata)
+{
+	u8 packet[VIDC_IFACEQ_VAR_LARGE_PKT_SIZE];
+	struct hfi_cmd_session_set_property_packet *pkt =
+		(struct hfi_cmd_session_set_property_packet *) &packet;
+	struct hal_session *session;
+	int rc = 0;
+
+	if (!sess || !pdata) {
+		dprintk(VIDC_ERR, "Invalid Params");
+		return -EINVAL;
+	} else {
+		session = sess;
+	}
+
+	dprintk(VIDC_INFO, "in set_prop,with prop id: 0x%x", ptype);
+
+	if (create_pkt_cmd_session_set_property(pkt, (u32)session, ptype,
+				pdata)) {
+		dprintk(VIDC_ERR, "set property: failed to create packet");
+		return -EINVAL;
+	}
+
+	if (venus_hfi_iface_cmdq_write(session->device, pkt))
+		return -ENOTEMPTY;
+
+	return rc;
+}
+
+static int venus_hfi_session_get_property(void *sess,
+				enum hal_property ptype, void *pdata)
+{
+	struct hal_session *session;
+
+	if (!sess || !pdata) {
+		dprintk(VIDC_ERR, "Invalid Params in ");
+		return -EINVAL;
+	} else {
+		session = sess;
+	}
+	dprintk(VIDC_INFO, "IN func: , with property id: %d", ptype);
+
+	switch (ptype) {
+	case HAL_CONFIG_FRAME_RATE:
+		break;
+	case HAL_PARAM_UNCOMPRESSED_FORMAT_SELECT:
+		break;
+	case HAL_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO:
+		break;
+	case HAL_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO:
+		break;
+	case HAL_PARAM_EXTRA_DATA_HEADER_CONFIG:
+		break;
+	case HAL_PARAM_FRAME_SIZE:
+		break;
+	case HAL_CONFIG_REALTIME:
+		break;
+	case HAL_PARAM_BUFFER_COUNT_ACTUAL:
+		break;
+	case HAL_PARAM_NAL_STREAM_FORMAT_SELECT:
+		break;
+	case HAL_PARAM_VDEC_OUTPUT_ORDER:
+		break;
+	case HAL_PARAM_VDEC_PICTURE_TYPE_DECODE:
+		break;
+	case HAL_PARAM_VDEC_OUTPUT2_KEEP_ASPECT_RATIO:
+		break;
+	case HAL_CONFIG_VDEC_POST_LOOP_DEBLOCKER:
+		break;
+	case HAL_PARAM_VDEC_MULTI_STREAM:
+		break;
+	case HAL_PARAM_VDEC_DISPLAY_PICTURE_BUFFER_COUNT:
+		break;
+	case HAL_PARAM_DIVX_FORMAT:
+		break;
+	case HAL_CONFIG_VDEC_MB_ERROR_MAP_REPORTING:
+		break;
+	case HAL_PARAM_VDEC_CONTINUE_DATA_TRANSFER:
+		break;
+	case HAL_CONFIG_VDEC_MB_ERROR_MAP:
+		break;
+	case HAL_CONFIG_VENC_REQUEST_IFRAME:
+		break;
+	case HAL_PARAM_VENC_MPEG4_SHORT_HEADER:
+		break;
+	case HAL_PARAM_VENC_MPEG4_AC_PREDICTION:
+		break;
+	case HAL_CONFIG_VENC_TARGET_BITRATE:
+		break;
+	case HAL_PARAM_PROFILE_LEVEL_CURRENT:
+		break;
+	case HAL_PARAM_VENC_H264_ENTROPY_CONTROL:
+		break;
+	case HAL_PARAM_VENC_RATE_CONTROL:
+		break;
+	case HAL_PARAM_VENC_MPEG4_TIME_RESOLUTION:
+		break;
+	case HAL_PARAM_VENC_MPEG4_HEADER_EXTENSION:
+		break;
+	case HAL_PARAM_VENC_H264_DEBLOCK_CONTROL:
+		break;
+	case HAL_PARAM_VENC_SESSION_QP:
+		break;
+	case HAL_CONFIG_VENC_INTRA_PERIOD:
+		break;
+	case HAL_CONFIG_VENC_IDR_PERIOD:
+		break;
+	case HAL_CONFIG_VPE_OPERATIONS:
+		break;
+	case HAL_PARAM_VENC_INTRA_REFRESH:
+		break;
+	case HAL_PARAM_VENC_MULTI_SLICE_CONTROL:
+		break;
+	case HAL_CONFIG_VPE_DEINTERLACE:
+		break;
+	case HAL_SYS_DEBUG_CONFIG:
+		break;
+	/*FOLLOWING PROPERTIES ARE NOT IMPLEMENTED IN CORE YET*/
+	case HAL_CONFIG_BUFFER_REQUIREMENTS:
+	case HAL_CONFIG_PRIORITY:
+	case HAL_CONFIG_BATCH_INFO:
+	case HAL_PARAM_METADATA_PASS_THROUGH:
+	case HAL_SYS_IDLE_INDICATOR:
+	case HAL_PARAM_UNCOMPRESSED_FORMAT_SUPPORTED:
+	case HAL_PARAM_INTERLACE_FORMAT_SUPPORTED:
+	case HAL_PARAM_CHROMA_SITE:
+	case HAL_PARAM_PROPERTIES_SUPPORTED:
+	case HAL_PARAM_PROFILE_LEVEL_SUPPORTED:
+	case HAL_PARAM_CAPABILITY_SUPPORTED:
+	case HAL_PARAM_NAL_STREAM_FORMAT_SUPPORTED:
+	case HAL_PARAM_MULTI_VIEW_FORMAT:
+	case HAL_PARAM_MAX_SEQUENCE_HEADER_SIZE:
+	case HAL_PARAM_CODEC_SUPPORTED:
+	case HAL_PARAM_VDEC_MULTI_VIEW_SELECT:
+	case HAL_PARAM_VDEC_MB_QUANTIZATION:
+	case HAL_PARAM_VDEC_NUM_CONCEALED_MB:
+	case HAL_PARAM_VDEC_H264_ENTROPY_SWITCHING:
+	case HAL_PARAM_VENC_SLICE_DELIVERY_MODE:
+	case HAL_PARAM_VENC_MPEG4_DATA_PARTITIONING:
+
+	case HAL_CONFIG_BUFFER_COUNT_ACTUAL:
+	case HAL_CONFIG_VDEC_MULTI_STREAM:
+	case HAL_PARAM_VENC_MULTI_SLICE_INFO:
+	case HAL_CONFIG_VENC_TIMESTAMP_SCALE:
+	case HAL_PARAM_VENC_LOW_LATENCY:
+	default:
+		dprintk(VIDC_INFO, "DEFAULT: Calling 0x%x", ptype);
+		break;
+	}
+	return 0;
+}
+
+static void *venus_hfi_session_init(void *device, u32 session_id,
+		enum hal_domain session_type, enum hal_video_codec codec_type)
+{
+	struct hfi_cmd_sys_session_init_packet pkt;
+	struct hal_session *new_session;
+	struct venus_hfi_device *dev;
+
+	if (device) {
+		dev = device;
+	} else {
+		dprintk(VIDC_ERR, "invalid device");
+		return NULL;
+	}
+
+	new_session = (struct hal_session *)
+		kzalloc(sizeof(struct hal_session), GFP_KERNEL);
+	new_session->session_id = (u32) session_id;
+	if (session_type == 1)
+		new_session->is_decoder = 0;
+	else if (session_type == 2)
+		new_session->is_decoder = 1;
+	new_session->device = dev;
+	list_add_tail(&new_session->list, &dev->sess_head);
+
+	if (create_pkt_cmd_sys_session_init(&pkt, (u32)new_session,
+			session_type, codec_type)) {
+		dprintk(VIDC_ERR, "session_init: failed to create packet");
+		goto err_session_init_fail;
+	}
+
+	if (venus_hfi_iface_cmdq_write(dev, &pkt))
+		goto err_session_init_fail;
+	if (venus_hfi_sys_set_debug(dev, msm_fw_debug))
+		dprintk(VIDC_ERR, "Setting fw_debug msg ON failed");
+	if (venus_hfi_sys_set_idle_message(dev, msm_fw_low_power_mode))
+		dprintk(VIDC_ERR, "Setting idle response ON failed");
+	return (void *) new_session;
+
+err_session_init_fail:
+	kfree(new_session);
+	return NULL;
+}
+
+static int venus_hfi_send_session_cmd(void *session_id,
+	 int pkt_type)
+{
+	struct vidc_hal_session_cmd_pkt pkt;
+	int rc = 0;
+	struct hal_session *session;
+
+	if (session_id) {
+		session = session_id;
+	} else {
+		dprintk(VIDC_ERR, "invalid session");
+		return -ENODEV;
+	}
+
+	rc = create_pkt_cmd_session_cmd(&pkt, pkt_type, (u32)session);
+	if (rc) {
+		dprintk(VIDC_ERR, "send session cmd: create pkt failed");
+		goto err_create_pkt;
+	}
+
+	if (venus_hfi_iface_cmdq_write(session->device, &pkt))
+		rc = -ENOTEMPTY;
+
+err_create_pkt:
+	return rc;
+}
+
+static int venus_hfi_session_end(void *session)
+{
+	return venus_hfi_send_session_cmd(session,
+		HFI_CMD_SYS_SESSION_END);
+}
+
+static int venus_hfi_session_abort(void *session)
+{
+	return venus_hfi_send_session_cmd(session,
+		HFI_CMD_SYS_SESSION_ABORT);
+}
+
+static int venus_hfi_session_set_buffers(void *sess,
+				struct vidc_buffer_addr_info *buffer_info)
+{
+	struct hfi_cmd_session_set_buffers_packet *pkt;
+	u8 packet[VIDC_IFACEQ_VAR_LARGE_PKT_SIZE];
+	int rc = 0;
+	struct hal_session *session;
+
+	if (!sess || !buffer_info) {
+		dprintk(VIDC_ERR, "Invalid Params");
+		return -EINVAL;
+	} else {
+		session = sess;
+	}
+
+	if (buffer_info->buffer_type == HAL_BUFFER_INPUT)
+		return 0;
+
+	pkt = (struct hfi_cmd_session_set_buffers_packet *)packet;
+
+	rc = create_pkt_cmd_session_set_buffers(pkt,
+			(u32)session, buffer_info);
+	if (rc) {
+		dprintk(VIDC_ERR, "set buffers: failed to create packet");
+		goto err_create_pkt;
+	}
+
+	dprintk(VIDC_INFO, "set buffers: 0x%x", buffer_info->buffer_type);
+	if (venus_hfi_iface_cmdq_write(session->device, pkt))
+		rc = -ENOTEMPTY;
+err_create_pkt:
+	return rc;
+}
+
+static int venus_hfi_session_release_buffers(void *sess,
+				struct vidc_buffer_addr_info *buffer_info)
+{
+	struct hfi_cmd_session_release_buffer_packet *pkt;
+	u8 packet[VIDC_IFACEQ_VAR_LARGE_PKT_SIZE];
+	int rc = 0;
+	struct hal_session *session;
+
+	if (!sess || !buffer_info) {
+		dprintk(VIDC_ERR, "Invalid Params");
+		return -EINVAL;
+	} else {
+		session = sess;
+	}
+
+	if (buffer_info->buffer_type == HAL_BUFFER_INPUT)
+		return 0;
+
+	pkt = (struct hfi_cmd_session_release_buffer_packet *) packet;
+
+	rc = create_pkt_cmd_session_release_buffers(pkt,
+					(u32)session, buffer_info);
+	if (rc) {
+		dprintk(VIDC_ERR, "release buffers: failed to create packet");
+		goto err_create_pkt;
+	}
+
+	dprintk(VIDC_INFO, "Release buffers: 0x%x", buffer_info->buffer_type);
+	if (venus_hfi_iface_cmdq_write(session->device, pkt))
+		rc = -ENOTEMPTY;
+err_create_pkt:
+	return rc;
+}
+
+static int venus_hfi_session_load_res(void *sess)
+{
+	return venus_hfi_send_session_cmd(sess,
+		HFI_CMD_SESSION_LOAD_RESOURCES);
+}
+
+static int venus_hfi_session_release_res(void *sess)
+{
+	return venus_hfi_send_session_cmd(sess,
+		HFI_CMD_SESSION_RELEASE_RESOURCES);
+}
+
+static int venus_hfi_session_start(void *sess)
+{
+	return venus_hfi_send_session_cmd(sess,
+		HFI_CMD_SESSION_START);
+}
+
+static int venus_hfi_session_stop(void *sess)
+{
+	return venus_hfi_send_session_cmd(sess,
+		HFI_CMD_SESSION_STOP);
+}
+
+static int venus_hfi_session_suspend(void *sess)
+{
+	return venus_hfi_send_session_cmd(sess,
+		HFI_CMD_SESSION_SUSPEND);
+}
+
+static int venus_hfi_session_resume(void *sess)
+{
+	return venus_hfi_send_session_cmd(sess,
+		HFI_CMD_SESSION_RESUME);
+}
+
+static int venus_hfi_session_etb(void *sess,
+				struct vidc_frame_data *input_frame)
+{
+	int rc = 0;
+	struct hal_session *session;
+
+	if (!sess || !input_frame) {
+		dprintk(VIDC_ERR, "Invalid Params");
+		return -EINVAL;
+	} else {
+		session = sess;
+	}
+
+	if (session->is_decoder) {
+		struct hfi_cmd_session_empty_buffer_compressed_packet pkt;
+
+		rc = create_pkt_cmd_session_etb_decoder(&pkt,
+					(u32)session, input_frame);
+		if (rc) {
+			dprintk(VIDC_ERR,
+			"Session etb decoder: failed to create pkt");
+			goto err_create_pkt;
+		}
+		dprintk(VIDC_DBG, "Q DECODER INPUT BUFFER");
+		if (venus_hfi_iface_cmdq_write(session->device, &pkt))
+			rc = -ENOTEMPTY;
+	} else {
+		struct hfi_cmd_session_empty_buffer_uncompressed_plane0_packet
+			pkt;
+
+		rc =  create_pkt_cmd_session_etb_encoder(&pkt,
+					(u32)session, input_frame);
+		if (rc) {
+			dprintk(VIDC_ERR,
+			"Session etb encoder: failed to create pkt");
+			goto err_create_pkt;
+		}
+		dprintk(VIDC_DBG, "Q ENCODER INPUT BUFFER");
+		if (venus_hfi_iface_cmdq_write(session->device, &pkt))
+			rc = -ENOTEMPTY;
+	}
+err_create_pkt:
+	return rc;
+}
+
+static int venus_hfi_session_ftb(void *sess,
+				struct vidc_frame_data *output_frame)
+{
+	struct hfi_cmd_session_fill_buffer_packet pkt;
+	int rc = 0;
+	struct hal_session *session;
+
+	if (!sess || !output_frame) {
+		dprintk(VIDC_ERR, "Invalid Params");
+		return -EINVAL;
+	} else {
+		session = sess;
+	}
+
+	rc = create_pkt_cmd_session_ftb(&pkt, (u32)session, output_frame);
+	if (rc) {
+		dprintk(VIDC_ERR, "Session ftb: failed to create pkt");
+		goto err_create_pkt;
+	}
+
+	if (venus_hfi_iface_cmdq_write(session->device, &pkt))
+		rc = -ENOTEMPTY;
+err_create_pkt:
+	return rc;
+}
+
+static int venus_hfi_session_parse_seq_hdr(void *sess,
+					struct vidc_seq_hdr *seq_hdr)
+{
+	struct hfi_cmd_session_parse_sequence_header_packet *pkt;
+	int rc = 0;
+	u8 packet[VIDC_IFACEQ_VAR_SMALL_PKT_SIZE];
+	struct hal_session *session;
+
+	if (!sess || !seq_hdr) {
+		dprintk(VIDC_ERR, "Invalid Params");
+		return -EINVAL;
+	} else {
+		session = sess;
+	}
+
+	pkt = (struct hfi_cmd_session_parse_sequence_header_packet *) packet;
+
+	rc = create_pkt_cmd_session_parse_seq_header(pkt, (u32)session,
+							seq_hdr);
+	if (rc) {
+		dprintk(VIDC_ERR,
+		"Session parse seq hdr: failed to create pkt");
+		goto err_create_pkt;
+	}
+
+	if (venus_hfi_iface_cmdq_write(session->device, pkt))
+		rc = -ENOTEMPTY;
+err_create_pkt:
+	return rc;
+}
+
+static int venus_hfi_session_get_seq_hdr(void *sess,
+				struct vidc_seq_hdr *seq_hdr)
+{
+	struct hfi_cmd_session_get_sequence_header_packet *pkt;
+	int rc = 0;
+	u8 packet[VIDC_IFACEQ_VAR_SMALL_PKT_SIZE];
+	struct hal_session *session;
+
+	if (!sess || !seq_hdr) {
+		dprintk(VIDC_ERR, "Invalid Params");
+		return -EINVAL;
+	} else {
+		session = sess;
+	}
+
+	pkt = (struct hfi_cmd_session_get_sequence_header_packet *) packet;
+	rc = create_pkt_cmd_session_get_seq_hdr(pkt, (u32)session, seq_hdr);
+	if (rc) {
+		dprintk(VIDC_ERR, "Session get seq hdr: failed to create pkt");
+		goto err_create_pkt;
+	}
+
+	if (venus_hfi_iface_cmdq_write(session->device, pkt))
+		rc = -ENOTEMPTY;
+err_create_pkt:
+	return rc;
+}
+
+static int venus_hfi_session_get_buf_req(void *sess)
+{
+	struct hfi_cmd_session_get_property_packet pkt;
+	int rc = 0;
+	struct hal_session *session;
+
+	if (sess) {
+		session = sess;
+	} else {
+		dprintk(VIDC_ERR, "invalid session");
+		return -ENODEV;
+	}
+
+	rc = create_pkt_cmd_session_get_buf_req(&pkt, (u32)session);
+	if (rc) {
+		dprintk(VIDC_ERR, "Session get buf req: failed to create pkt");
+		goto err_create_pkt;
+	}
+
+	if (venus_hfi_iface_cmdq_write(session->device, &pkt))
+		rc = -ENOTEMPTY;
+err_create_pkt:
+	return rc;
+}
+
+static int venus_hfi_session_flush(void *sess, enum hal_flush flush_mode)
+{
+	struct hfi_cmd_session_flush_packet pkt;
+	int rc = 0;
+	struct hal_session *session;
+
+	if (sess) {
+		session = sess;
+	} else {
+		dprintk(VIDC_ERR, "invalid session");
+		return -ENODEV;
+	}
+
+	rc = create_pkt_cmd_session_flush(&pkt, (u32)session, flush_mode);
+	if (rc) {
+		dprintk(VIDC_ERR, "Session flush: failed to create pkt");
+		goto err_create_pkt;
+	}
+
+	if (venus_hfi_iface_cmdq_write(session->device, &pkt))
+		rc = -ENOTEMPTY;
+err_create_pkt:
+	return rc;
+}
+
+static int venus_hfi_check_core_registered(
+	struct hal_device_data core, u32 fw_addr,
+	u32 reg_addr, u32 reg_size, u32 irq)
+{
+	struct venus_hfi_device *device;
+	struct list_head *curr, *next;
+
+	if (core.dev_count) {
+		list_for_each_safe(curr, next, &core.dev_head) {
+			device = list_entry(curr,
+				struct venus_hfi_device, list);
+			if (device && device->hal_data->irq == irq &&
+				(CONTAINS(device->hal_data->
+						device_base_addr,
+						FIRMWARE_SIZE, fw_addr) ||
+				CONTAINS(fw_addr, FIRMWARE_SIZE,
+						device->hal_data->
+						device_base_addr) ||
+				CONTAINS((u32)device->hal_data->
+						register_base_addr,
+						reg_size, reg_addr) ||
+				CONTAINS(reg_addr, reg_size,
+						(u32)device->hal_data->
+						register_base_addr) ||
+				OVERLAPS((u32)device->hal_data->
+						register_base_addr,
+						reg_size, reg_addr, reg_size) ||
+				OVERLAPS(reg_addr, reg_size,
+						(u32)device->hal_data->
+						register_base_addr, reg_size) ||
+				OVERLAPS(device->hal_data->
+						device_base_addr,
+						FIRMWARE_SIZE, fw_addr,
+						FIRMWARE_SIZE) ||
+				OVERLAPS(fw_addr, FIRMWARE_SIZE,
+						device->hal_data->
+						device_base_addr,
+						FIRMWARE_SIZE))) {
+				return 0;
+			} else {
+				dprintk(VIDC_INFO, "Device not registered");
+				return -EINVAL;
+			}
+		}
+	} else {
+		dprintk(VIDC_INFO, "no device Registered");
+	}
+	return -EINVAL;
+}
+
+static void venus_hfi_process_sys_watchdog_timeout(
+				struct venus_hfi_device *device)
+{
+	struct msm_vidc_cb_cmd_done cmd_done;
+	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
+	cmd_done.device_id = device->device_id;
+	device->callback(SYS_WATCHDOG_TIMEOUT, &cmd_done);
+}
+
+static int venus_hfi_is_cmd_pending(struct venus_hfi_device *dev)
+{
+	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)
+		dprintk(VIDC_ERR, "cannot read shared Q's");
+	queue = (struct hfi_queue_header *) q_info->q_hdr;
+	if (!queue) {
+		dprintk(VIDC_ERR, "queue not present");
+		return -ENOENT;
+	}
+	write_ptr = (u32)queue->qhdr_write_idx;
+	read_ptr = (u32)queue->qhdr_read_idx;
+	rc = read_ptr - write_ptr;
+	return rc;
+}
+
+static int venus_hfi_try_clk_gating(struct venus_hfi_device *device)
+{
+	int rc = 0;
+	u32 ctrl_status = 0;
+	if (!device) {
+		dprintk(VIDC_ERR, "invalid device");
+		return -ENODEV;
+	}
+	mutex_lock(&device->write_lock);
+	rc = venus_hfi_is_cmd_pending(device);
+	ctrl_status = venus_hfi_read_register(
+		device->hal_data->register_base_addr,
+		VIDC_CPU_CS_SCIACMDARG0);
+	if (((ctrl_status & VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK)
+		!= 0) && !rc)
+		venus_hfi_clk_gating_on(device, VCODEC_CLK);
+	mutex_unlock(&device->write_lock);
+	return rc;
+}
+
+static void venus_hfi_response_handler(struct venus_hfi_device *device)
+{
+	u8 packet[VIDC_IFACEQ_MED_PKT_SIZE];
+	u32 rc = 0;
+	dprintk(VIDC_INFO, "#####venus_hfi_response_handler#####\n");
+	if (device) {
+		if ((device->intr_status &
+			VIDC_WRAPPER_INTR_CLEAR_A2HWD_BMSK)) {
+			dprintk(VIDC_ERR, "Received: Watchdog timeout %s",
+				__func__);
+			venus_hfi_process_sys_watchdog_timeout(device);
+		}
+
+		while (!venus_hfi_iface_msgq_read(device, packet)) {
+			rc = hfi_process_msg_packet(device->callback,
+				device->device_id,
+				(struct vidc_hal_msg_pkt_hdr *) packet);
+			if (rc == HFI_MSG_SYS_IDLE)
+				rc = venus_hfi_try_clk_gating(device);
+
+		}
+		while (!venus_hfi_iface_dbgq_read(device, packet)) {
+			struct hfi_msg_sys_debug_packet *pkt =
+				(struct hfi_msg_sys_debug_packet *) packet;
+			dprintk(VIDC_FW, "FW-SAYS: %s", pkt->rg_msg_data);
+		}
+	} else {
+		dprintk(VIDC_ERR, "SPURIOUS_INTERRUPT");
+	}
+}
+
+static void venus_hfi_core_work_handler(struct work_struct *work)
+{
+	struct venus_hfi_device *device = list_first_entry(
+		&hal_ctxt.dev_head, struct venus_hfi_device, list);
+
+	dprintk(VIDC_INFO, " GOT INTERRUPT () ");
+	if (!device->callback) {
+		dprintk(VIDC_ERR, "No interrupt callback function: %p\n",
+				device);
+		return;
+	}
+	venus_hfi_core_clear_interrupt(device);
+	venus_hfi_response_handler(device);
+	if (!(device->intr_status & VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK))
+		enable_irq(device->hal_data->irq);
+}
+static DECLARE_WORK(venus_hfi_work, venus_hfi_core_work_handler);
+
+static irqreturn_t venus_hfi_isr(int irq, void *dev)
+{
+	struct venus_hfi_device *device = dev;
+	dprintk(VIDC_INFO, "vidc_hal_isr() %d ", irq);
+	disable_irq_nosync(irq);
+	queue_work(device->vidc_workq, &venus_hfi_work);
+	dprintk(VIDC_INFO, "vidc_hal_isr() %d ", irq);
+	return IRQ_HANDLED;
+}
+
+static int venus_hfi_init_regs_and_interrupts(
+		struct venus_hfi_device *device,
+		struct msm_vidc_platform_resources *res)
+{
+	struct hal_data *hal = NULL;
+	int rc = 0;
+
+	device->base_addr = res->fw_base_addr;
+	device->register_base = res->register_base;
+	device->register_size = res->register_size;
+	device->irq = res->irq;
+
+	rc = venus_hfi_check_core_registered(hal_ctxt, device->base_addr,
+			device->register_base, device->register_size,
+			device->irq);
+	if (!rc) {
+		dprintk(VIDC_ERR, "Core present/Already added");
+		rc = -EEXIST;
+		goto err_core_init;
+	}
+
+	dprintk(VIDC_DBG, "HAL_DATA will be assigned now");
+	hal = (struct hal_data *)
+		kzalloc(sizeof(struct hal_data), GFP_KERNEL);
+	if (!hal) {
+		dprintk(VIDC_ERR, "Failed to alloc");
+		rc = -ENOMEM;
+		goto err_core_init;
+	}
+	hal->irq = device->irq;
+	hal->device_base_addr = device->base_addr;
+	hal->register_base_addr =
+		ioremap_nocache(device->register_base, device->register_size);
+	if (!hal->register_base_addr) {
+		dprintk(VIDC_ERR,
+			"could not map reg addr %d of size %d",
+			device->register_base, device->register_size);
+		goto error_irq_fail;
+	}
+
+	device->hal_data = hal;
+	rc = request_irq(device->irq, venus_hfi_isr, IRQF_TRIGGER_HIGH,
+			"msm_vidc", device);
+	if (unlikely(rc)) {
+		dprintk(VIDC_ERR, "() :request_irq failed\n");
+		goto error_irq_fail;
+	}
+	disable_irq_nosync(device->irq);
+	return rc;
+
+error_irq_fail:
+	kfree(hal);
+err_core_init:
+	return rc;
+
+}
+
+static inline int venus_hfi_init_clocks(struct msm_vidc_platform_resources *res,
+		struct venus_hfi_device *device)
+{
+	struct venus_core_clock *cl;
+	int i;
+	int rc = 0;
+	struct venus_core_clock *clock;
+	if (!res || !device) {
+		dprintk(VIDC_ERR, "Invalid params: %p\n", device);
+		return -EINVAL;
+	}
+	clock = device->resources.clock;
+	strlcpy(clock[VCODEC_CLK].name, "core_clk",
+		sizeof(clock[VCODEC_CLK].name));
+	strlcpy(clock[VCODEC_AHB_CLK].name, "iface_clk",
+		sizeof(clock[VCODEC_AHB_CLK].name));
+	strlcpy(clock[VCODEC_AXI_CLK].name, "bus_clk",
+		sizeof(clock[VCODEC_AXI_CLK].name));
+	strlcpy(clock[VCODEC_OCMEM_CLK].name, "mem_clk",
+		sizeof(clock[VCODEC_OCMEM_CLK].name));
+
+	clock[VCODEC_CLK].count = res->load_freq_tbl_size;
+	memcpy((void *)clock[VCODEC_CLK].load_freq_tbl, res->load_freq_tbl,
+		clock[VCODEC_CLK].count * sizeof(*res->load_freq_tbl));
+
+	dprintk(VIDC_DBG, "count = %d\n", clock[VCODEC_CLK].count);
+	if (!clock[VCODEC_CLK].count) {
+		dprintk(VIDC_ERR, "Failed to read clock frequency\n");
+		goto fail_init_clocks;
+	}
+	for (i = 0; i <	clock[VCODEC_CLK].count; i++) {
+		dprintk(VIDC_DBG,
+				"load = %d, freq = %d\n",
+				clock[VCODEC_CLK].load_freq_tbl[i].load,
+				clock[VCODEC_CLK].load_freq_tbl[i].freq
+			  );
+	}
+
+	for (i = 0; i < VCODEC_MAX_CLKS; i++) {
+		cl = &device->resources.clock[i];
+		if (!cl->clk) {
+			cl->clk = devm_clk_get(&res->pdev->dev, cl->name);
+			if (IS_ERR_OR_NULL(cl->clk)) {
+				dprintk(VIDC_ERR,
+					"Failed to get clock: %s\n", cl->name);
+				rc = PTR_ERR(cl->clk);
+				break;
+			}
+		}
+	}
+
+	if (i < VCODEC_MAX_CLKS) {
+		for (--i; i >= 0; i--) {
+			cl = &device->resources.clock[i];
+			clk_put(cl->clk);
+		}
+	}
+fail_init_clocks:
+	return rc;
+}
+
+static inline void venus_hfi_deinit_clocks(struct venus_hfi_device *device)
+{
+	int i;
+	if (!device) {
+		dprintk(VIDC_ERR, "Invalid args\n");
+		return;
+	}
+	for (i = 0; i < VCODEC_MAX_CLKS; i++)
+		clk_put(device->resources.clock[i].clk);
+}
+static inline void venus_hfi_disable_clks(struct venus_hfi_device *device)
+{
+	int i;
+	struct venus_core_clock *cl;
+	if (!device) {
+		dprintk(VIDC_ERR, "Invalid params: %p\n", device);
+		return;
+	}
+	if (device->clocks_enabled) {
+		cl = &device->resources.clock[VCODEC_CLK];
+		clk_disable_unprepare(cl->clk);
+	}
+
+	for (i = VCODEC_CLK; i < VCODEC_MAX_CLKS; i++) {
+		cl = &device->resources.clock[i];
+		clk_disable_unprepare(cl->clk);
+	}
+	device->clocks_enabled = 0;
+}
+static inline int venus_hfi_enable_clks(struct venus_hfi_device *device)
+{
+	int i = 0;
+	struct venus_core_clock *cl;
+	int rc = 0;
+	if (!device) {
+		dprintk(VIDC_ERR, "Invalid params: %p\n", device);
+		return -EINVAL;
+	}
+	if (!device->clocks_enabled) {
+		cl = &device->resources.clock[VCODEC_CLK];
+		rc = clk_prepare_enable(cl->clk);
+		if (rc) {
+			dprintk(VIDC_ERR, "Failed to enable clocks\n");
+			goto fail_clk_enable;
+		} else {
+			dprintk(VIDC_DBG, "Clock: %s enabled\n", cl->name);
+		}
+	}
+	for (i = VCODEC_CLK; i < VCODEC_MAX_CLKS; i++) {
+		cl = &device->resources.clock[i];
+		rc = clk_prepare_enable(cl->clk);
+		if (rc) {
+			dprintk(VIDC_ERR, "Failed to enable clocks\n");
+			goto fail_clk_enable;
+		} else {
+			dprintk(VIDC_DBG, "Clock: %s enabled\n", cl->name);
+		}
+	}
+	device->clocks_enabled = 1;
+	return rc;
+fail_clk_enable:
+	for (; i >= 0; i--) {
+		cl = &device->resources.clock[i];
+		clk_disable_unprepare(cl->clk);
+	}
+	return rc;
+}
+static int venus_hfi_register_iommu_domains(struct venus_hfi_device *device,
+					struct msm_vidc_platform_resources *res)
+{
+	struct msm_iova_partition partition[2];
+	struct msm_iova_layout layout;
+	int rc = 0;
+	int i;
+	struct msm_vidc_iommu_info *io_map;
+
+	if (!device)
+		return -EINVAL;
+
+	io_map = device->resources.io_map;
+
+	strlcpy(io_map[CP_MAP].name, "vidc-cp-map",
+			sizeof(io_map[CP_MAP].name));
+	strlcpy(io_map[CP_MAP].ctx, "venus_cp",
+			sizeof(io_map[CP_MAP].ctx));
+	strlcpy(io_map[NS_MAP].name, "vidc-ns-map",
+			sizeof(io_map[NS_MAP].name));
+	strlcpy(io_map[NS_MAP].ctx, "venus_ns",
+			sizeof(io_map[NS_MAP].ctx));
+
+	for (i = 0; i < MAX_MAP; i++) {
+		if (!res->iommu_maps[i].addr_range[1])
+			continue;
+		memcpy(io_map[i].addr_range, &res->iommu_maps[i].addr_range,
+				sizeof(u32) * 2);
+
+		partition[0].start = io_map[i].addr_range[0];
+		if (i == NS_MAP) {
+			partition[0].size =
+				io_map[i].addr_range[1] - SHARED_QSIZE;
+			partition[1].start =
+				partition[0].start + io_map[i].addr_range[1]
+					- SHARED_QSIZE;
+			partition[1].size = SHARED_QSIZE;
+			layout.npartitions = 2;
+			layout.is_secure = 0;
+		} else {
+			partition[0].size = io_map[i].addr_range[1];
+			layout.npartitions = 1;
+			layout.is_secure = 1;
+		}
+		layout.partitions = &partition[0];
+		layout.client_name = io_map[i].name;
+		layout.domain_flags = 0;
+		dprintk(VIDC_DBG, "Registering domain 1 with: %lx, %lx, %s\n",
+			partition[0].start, partition[0].size,
+			layout.client_name);
+		dprintk(VIDC_DBG, "Registering domain 2 with: %lx, %lx, %s\n",
+			partition[1].start, partition[1].size,
+			layout.client_name);
+		io_map[i].domain = msm_register_domain(&layout);
+		if (io_map[i].domain < 0) {
+			dprintk(VIDC_ERR, "Failed to register cp domain\n");
+			rc = -EINVAL;
+			break;
+		}
+	}
+	/* There is no api provided as msm_unregister_domain, so
+	 * we are not able to unregister the previously
+	 * registered domains if any domain registration fails.*/
+	BUG_ON(i < MAX_MAP);
+	return rc;
+}
+
+static void venus_hfi_deinit_bus(struct venus_hfi_device *device)
+{
+	struct venus_bus_info *bus_info;
+	int i = 0;
+
+	if (!device)
+		return;
+
+	bus_info = &device->resources.bus_info;
+
+	for (i = 0; i < MSM_VIDC_MAX_DEVICES; i++) {
+		if (bus_info->ddr_handle[i]) {
+			msm_bus_scale_unregister_client(
+			   bus_info->ddr_handle[i]);
+			bus_info->ddr_handle[i] = 0;
+		}
+
+		if (bus_info->ocmem_handle[i]) {
+			msm_bus_scale_unregister_client(
+			   bus_info->ocmem_handle[i]);
+			bus_info->ocmem_handle[i] = 0;
+		}
+	}
+}
+
+static int venus_hfi_init_bus(struct venus_hfi_device *device)
+{
+	struct venus_bus_info *bus_info;
+	int rc = 0;
+	if ((!device) || (!device->res->bus_pdata))
+		return -EINVAL;
+
+	bus_info = &device->resources.bus_info;
+
+	bus_info->ddr_handle[MSM_VIDC_ENCODER] =
+		msm_bus_scale_register_client(&device->res->bus_pdata[2]);
+	if (!bus_info->ddr_handle[MSM_VIDC_ENCODER]) {
+		dprintk(VIDC_ERR, "Failed to register bus scale client\n");
+		goto err_init_bus;
+	}
+	bus_info->ddr_handle[MSM_VIDC_DECODER] =
+		msm_bus_scale_register_client(&device->res->bus_pdata[3]);
+	if (!bus_info->ddr_handle[MSM_VIDC_DECODER]) {
+		dprintk(VIDC_ERR, "Failed to register bus scale client\n");
+		goto err_init_bus;
+	}
+	bus_info->ocmem_handle[MSM_VIDC_ENCODER] =
+		msm_bus_scale_register_client(&device->res->bus_pdata[0]);
+	if (!bus_info->ocmem_handle[MSM_VIDC_ENCODER]) {
+		dprintk(VIDC_ERR, "Failed to register bus scale client\n");
+		goto err_init_bus;
+	}
+	bus_info->ocmem_handle[MSM_VIDC_DECODER] =
+		msm_bus_scale_register_client(&device->res->bus_pdata[1]);
+	if (!bus_info->ocmem_handle[MSM_VIDC_DECODER]) {
+		dprintk(VIDC_ERR, "Failed to register bus scale client\n");
+		goto err_init_bus;
+	}
+	return rc;
+err_init_bus:
+	venus_hfi_deinit_bus(device);
+	return -EINVAL;
+}
+
+
+static const u32 venus_hfi_bus_table[] = {
+	36000,
+	110400,
+	244800,
+	489000,
+	783360,
+	979200,
+};
+
+static int venus_hfi_get_bus_vector(int load)
+{
+	int num_rows = sizeof(venus_hfi_bus_table)/(sizeof(u32));
+	int i, j;
+	for (i = 0; i < num_rows; i++) {
+		if (load <= venus_hfi_bus_table[i])
+			break;
+	}
+	j = clamp(i, 0, num_rows-1) + 1;
+	dprintk(VIDC_DBG, "Required bus = %d\n", j);
+	return j;
+}
+
+static int venus_hfi_scale_bus(void *dev, int load,
+				enum session_type type, enum mem_type mtype)
+{
+	int rc = 0;
+	u32 handle = 0;
+	struct venus_hfi_device *device = dev;
+
+	if (!device) {
+		dprintk(VIDC_ERR, "%s invalid device handle %p",
+			__func__, device);
+		return -EINVAL;
+	}
+
+	if (mtype & DDR_MEM)
+		handle = device->resources.bus_info.ddr_handle[type];
+	if (mtype & OCMEM_MEM)
+		handle = device->resources.bus_info.ocmem_handle[type];
+
+	if (handle) {
+		rc = msm_bus_scale_client_update_request(
+				handle, venus_hfi_get_bus_vector(load));
+		if (rc)
+			dprintk(VIDC_ERR, "Failed to scale bus: %d\n", rc);
+	} else {
+		dprintk(VIDC_ERR, "Failed to scale bus, mtype: %d\n",
+				mtype);
+		rc = -EINVAL;
+	}
+
+	return rc;
+}
+
+static int venus_hfi_unvote_bus(void *dev,
+				enum session_type type, enum mem_type mtype)
+{
+	int rc = 0;
+	u32 handle = 0;
+	struct venus_hfi_device *device = dev;
+
+	if (!device) {
+		dprintk(VIDC_ERR, "%s invalid device handle %p",
+			__func__, device);
+		return -EINVAL;
+	}
+
+	if (mtype & DDR_MEM)
+		handle = device->resources.bus_info.ddr_handle[type];
+	if (mtype & OCMEM_MEM)
+		handle = device->resources.bus_info.ocmem_handle[type];
+
+	if (handle) {
+		rc = msm_bus_scale_client_update_request(
+				handle, 0);
+		if (rc)
+			dprintk(VIDC_ERR, "Failed to unvote bus: %d\n", rc);
+	} else {
+		dprintk(VIDC_ERR, "Failed to unvote bus, mtype: %d\n",
+				mtype);
+		rc = -EINVAL;
+	}
+	return rc;
+}
+
+static int venus_hfi_set_ocmem(void *dev, struct ocmem_buf *ocmem)
+{
+	struct vidc_resource_hdr rhdr;
+	struct venus_hfi_device *device = dev;
+	int rc = 0;
+	if (!device || !ocmem) {
+		dprintk(VIDC_ERR, "Invalid params, core:%p, ocmem: %p\n",
+			device, ocmem);
+		return -EINVAL;
+	}
+	rhdr.resource_id = VIDC_RESOURCE_OCMEM;
+	rhdr.resource_handle = (u32) &device->resources.ocmem;
+	rhdr.size =	ocmem->len;
+	rc = venus_hfi_core_set_resource(device, &rhdr, ocmem);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to set OCMEM on driver\n");
+		goto ocmem_set_failed;
+	}
+	dprintk(VIDC_DBG, "OCMEM set, addr = %lx, size: %ld\n",
+		ocmem->addr, ocmem->len);
+ocmem_set_failed:
+	return rc;
+}
+
+static int venus_hfi_unset_ocmem(void *dev)
+{
+	struct vidc_resource_hdr rhdr;
+	struct venus_hfi_device *device = dev;
+	int rc = 0;
+	if (!device) {
+		dprintk(VIDC_ERR, "%s Invalid params, device:%p\n",
+			__func__, device);
+		rc = -EINVAL;
+		goto ocmem_unset_failed;
+	}
+	if (!device->resources.ocmem.buf) {
+		dprintk(VIDC_INFO, "%s Trying to free OCMEM which is not set",
+			__func__);
+		rc = -EINVAL;
+		goto ocmem_unset_failed;
+	}
+
+	rhdr.resource_id = VIDC_RESOURCE_OCMEM;
+	rhdr.resource_handle = (u32) &device->resources.ocmem;
+	rc = venus_hfi_core_release_resource(device, &rhdr);
+	if (rc)
+		dprintk(VIDC_ERR, "Failed to unset OCMEM on driver\n");
+ocmem_unset_failed:
+	return rc;
+}
+
+static int venus_hfi_ocmem_notify_handler(struct notifier_block *this,
+		unsigned long event, void *data)
+{
+	struct ocmem_buf *buff = data;
+	struct venus_hfi_device *device;
+	struct venus_resources *resources;
+	struct on_chip_mem *ocmem;
+	int rc = NOTIFY_DONE;
+	if (event == OCMEM_ALLOC_GROW) {
+		ocmem = container_of(this, struct on_chip_mem, vidc_ocmem_nb);
+		if (!ocmem) {
+			dprintk(VIDC_ERR, "Wrong handler passed\n");
+			rc = NOTIFY_BAD;
+			goto err_ocmem_notify;
+		}
+		resources = container_of(ocmem,
+			struct venus_resources, ocmem);
+		device = container_of(resources,
+			struct venus_hfi_device, resources);
+		if (venus_hfi_set_ocmem(device, buff)) {
+			dprintk(VIDC_ERR, "Failed to set ocmem: %d\n", rc);
+			goto err_ocmem_notify;
+		}
+		rc = NOTIFY_OK;
+	}
+
+err_ocmem_notify:
+	return rc;
+}
+
+static void venus_hfi_ocmem_init(struct venus_hfi_device *device)
+{
+	struct on_chip_mem *ocmem;
+
+	ocmem = &device->resources.ocmem;
+	ocmem->vidc_ocmem_nb.notifier_call = venus_hfi_ocmem_notify_handler;
+	ocmem->handle =
+		ocmem_notifier_register(OCMEM_VIDEO, &ocmem->vidc_ocmem_nb);
+	if (!ocmem->handle) {
+		dprintk(VIDC_WARN, "Failed to register OCMEM notifier.");
+		dprintk(VIDC_INFO, " Performance will be impacted\n");
+	}
+}
+
+static int venus_hfi_alloc_ocmem(void *dev, unsigned long size)
+{
+	int rc = 0;
+	struct ocmem_buf *ocmem_buffer;
+	struct venus_hfi_device *device = dev;
+
+	if (!device || !size) {
+		dprintk(VIDC_ERR, "%s Invalid param, core: %p, size: %lu\n",
+			__func__, device, size);
+		return -EINVAL;
+	}
+	ocmem_buffer = device->resources.ocmem.buf;
+	if (!ocmem_buffer ||
+		ocmem_buffer->len < size) {
+		ocmem_buffer = ocmem_allocate(OCMEM_VIDEO, size);
+		if (IS_ERR_OR_NULL(ocmem_buffer)) {
+			dprintk(VIDC_ERR,
+				"ocmem_allocate_nb failed: %d\n",
+				(u32) ocmem_buffer);
+			rc = -ENOMEM;
+		}
+		device->resources.ocmem.buf = ocmem_buffer;
+		rc = venus_hfi_set_ocmem(device, ocmem_buffer);
+		if (rc) {
+			dprintk(VIDC_ERR, "Failed to set ocmem: %d\n", rc);
+			goto ocmem_set_failed;
+		}
+	} else
+		dprintk(VIDC_DBG,
+			"OCMEM is enough. reqd: %lu, available: %lu\n",
+			size, ocmem_buffer->len);
+
+ocmem_set_failed:
+	return rc;
+}
+
+static int venus_hfi_free_ocmem(void *dev)
+{
+	struct venus_hfi_device *device = dev;
+	int rc = 0;
+
+	if (!device) {
+		dprintk(VIDC_ERR, "%s invalid device handle %p",
+			__func__, device);
+		return -EINVAL;
+	}
+
+	if (device->resources.ocmem.buf) {
+		rc = ocmem_free(OCMEM_VIDEO, device->resources.ocmem.buf);
+		if (rc)
+			dprintk(VIDC_ERR, "Failed to free ocmem\n");
+		device->resources.ocmem.buf = NULL;
+	}
+	return rc;
+}
+
+static int venus_hfi_is_ocmem_present(void *dev)
+{
+	struct venus_hfi_device *device = dev;
+	if (!device) {
+		dprintk(VIDC_ERR, "%s invalid device handle %p",
+			__func__, device);
+		return -EINVAL;
+	}
+
+	return device->resources.ocmem.buf ? 1 : 0;
+}
+
+static void venus_hfi_deinit_ocmem(struct venus_hfi_device *device)
+{
+	if (device->resources.ocmem.handle)
+		ocmem_notifier_unregister(device->resources.ocmem.handle,
+				&device->resources.ocmem.vidc_ocmem_nb);
+}
+
+
+static int venus_hfi_init_resources(struct venus_hfi_device *device,
+				struct msm_vidc_platform_resources *res)
+{
+	int rc = 0;
+
+	device->res = res;
+	rc = venus_hfi_init_clocks(res, device);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to init clocks\n");
+		rc = -ENODEV;
+		goto err_init_clocks;
+	}
+
+	rc = venus_hfi_init_bus(device);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to init bus: %d\n", rc);
+		goto err_init_bus;
+	}
+
+	rc = venus_hfi_register_iommu_domains(device, res);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to register iommu domains: %d\n", rc);
+		goto err_register_iommu_domain;
+	}
+
+	venus_hfi_ocmem_init(device);
+	return rc;
+
+err_register_iommu_domain:
+	venus_hfi_deinit_bus(device);
+err_init_bus:
+	venus_hfi_deinit_clocks(device);
+err_init_clocks:
+	return rc;
+}
+
+static void venus_hfi_deinit_resources(struct venus_hfi_device *device)
+{
+	venus_hfi_deinit_ocmem(device);
+	venus_hfi_deinit_bus(device);
+	venus_hfi_deinit_clocks(device);
+}
+
+static int venus_hfi_iommu_attach(struct venus_hfi_device *device)
+{
+	int rc;
+	struct iommu_domain *domain;
+	int i;
+	struct msm_vidc_iommu_info *io_map;
+	struct device *dev;
+
+	if (!device)
+		return -EINVAL;
+
+	for (i = 0; i < MAX_MAP; i++) {
+		io_map = &device->resources.io_map[i];
+		if (!io_map->domain)
+			continue;
+		dev = msm_iommu_get_ctx(io_map->ctx);
+		domain = msm_get_iommu_domain(io_map->domain);
+		if (IS_ERR_OR_NULL(domain)) {
+			dprintk(VIDC_ERR,
+				"Failed to get domain: %s\n", io_map->name);
+			rc = PTR_ERR(domain);
+			break;
+		}
+		rc = iommu_attach_device(domain, dev);
+		if (rc) {
+			dprintk(VIDC_ERR,
+				"IOMMU attach failed: %s\n", io_map->name);
+			break;
+		}
+	}
+	if (i < MAX_MAP) {
+		i--;
+		for (; i >= 0; i--) {
+			io_map = &device->resources.io_map[i];
+			dev = msm_iommu_get_ctx(io_map->ctx);
+			domain = msm_get_iommu_domain(io_map->domain);
+			if (dev && domain)
+				iommu_detach_device(domain, dev);
+		}
+	}
+	return rc;
+}
+
+static void venus_hfi_iommu_detach(struct venus_hfi_device *device)
+{
+	struct device *dev;
+	struct iommu_domain *domain;
+	struct msm_vidc_iommu_info *io_map;
+	int i;
+
+	if (!device) {
+		dprintk(VIDC_ERR, "Invalid paramter: %p\n", device);
+		return;
+	}
+
+	for (i = 0; i < MAX_MAP; i++) {
+		io_map = &device->resources.io_map[i];
+		dev = msm_iommu_get_ctx(io_map->ctx);
+		domain = msm_get_iommu_domain(io_map->domain);
+		if (dev && domain)
+			iommu_detach_device(domain, dev);
+	}
+}
+
+static int venus_hfi_get_domain(void *dev, enum msm_vidc_io_maps iomap)
+{
+	struct venus_hfi_device *device = dev;
+	if (!device || iomap < CP_MAP || iomap >= MAX_MAP) {
+		dprintk(VIDC_ERR, "%s: Invalid parameter: %p iomap: %d\n",
+				__func__, device, iomap);
+		return -EINVAL;
+	}
+	return device->resources.io_map[iomap].domain;
+}
+
+static int venus_hfi_iommu_get_map(void *dev,
+			struct msm_vidc_iommu_info maps[MAX_MAP])
+{
+	int i = 0;
+	struct venus_hfi_device *device = dev;
+
+	if (!device || !maps) {
+		dprintk(VIDC_ERR, "%s: Invalid param device: %p maps: %p\n",
+		 __func__, device, maps);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < MAX_MAP; i++)
+		maps[i] = device->resources.io_map[i];
+
+	return 0;
+}
+
+static int protect_cp_mem(struct venus_hfi_device *device)
+{
+	struct tzbsp_memprot memprot;
+	unsigned int resp = 0;
+	int rc = 0;
+	struct msm_vidc_iommu_info *io_map;
+	if (!device)
+		return -EINVAL;
+
+	io_map = device->resources.io_map;
+	if (!io_map) {
+		dprintk(VIDC_ERR, "invalid params: %p\n", io_map);
+		return -EINVAL;
+	}
+	if (!io_map[CP_MAP].addr_range[1])
+		return 0;
+	memprot.cp_start = 0x0;
+	memprot.cp_size = io_map[CP_MAP].addr_range[0] +
+			io_map[CP_MAP].addr_range[1];
+	memprot.cp_nonpixel_start = 0;
+	memprot.cp_nonpixel_size = 0;
+
+	rc = scm_call(SCM_SVC_CP, TZBSP_MEM_PROTECT_VIDEO_VAR, &memprot,
+			sizeof(memprot), &resp, sizeof(resp));
+	if (rc)
+		dprintk(VIDC_ERR,
+		"Failed to protect memory , rc is :%d, response : %d\n",
+		rc, resp);
+	return rc;
+}
+
+static int venus_hfi_load_fw(void *dev)
+{
+	int rc = 0;
+	struct venus_hfi_device *device = dev;
+
+	if (!device) {
+		dprintk(VIDC_ERR, "%s Invalid paramter: %p\n",
+			__func__, device);
+		return -EINVAL;
+	}
+
+	rc = venus_hfi_iommu_attach(device);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to attach iommu");
+		goto fail_iommu_attach;
+	}
+
+	if (!device->resources.fw.cookie)
+		device->resources.fw.cookie = subsystem_get("venus");
+
+	if (IS_ERR_OR_NULL(device->resources.fw.cookie)) {
+		dprintk(VIDC_ERR, "Failed to download firmware\n");
+		rc = -ENOMEM;
+		goto fail_load_fw;
+	}
+	/*Clocks can be enabled only after pil_get since
+	 * gdsc is turned-on in pil_get*/
+	rc = venus_hfi_enable_clks(device);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to enable clocks: %d\n", rc);
+		goto fail_enable_clks;
+	}
+
+	rc = protect_cp_mem(device);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to protect memory\n");
+		goto fail_protect_mem;
+	}
+
+	return rc;
+fail_protect_mem:
+	venus_hfi_disable_clks(device);
+fail_enable_clks:
+	subsystem_put(device->resources.fw.cookie);
+	device->resources.fw.cookie = NULL;
+fail_load_fw:
+	venus_hfi_iommu_detach(device);
+fail_iommu_attach:
+	return rc;
+}
+
+static void venus_hfi_unload_fw(void *dev)
+{
+	struct venus_hfi_device *device = dev;
+	if (!device) {
+		dprintk(VIDC_ERR, "%s Invalid paramter: %p\n",
+			__func__, device);
+		return;
+	}
+	if (device->resources.fw.cookie) {
+		venus_hfi_disable_clks(device);
+		subsystem_put(device->resources.fw.cookie);
+		venus_hfi_iommu_detach(device);
+		device->resources.fw.cookie = NULL;
+	}
+}
+
+static int venus_hfi_get_fw_info(void *dev, enum fw_info info)
+{
+	int rc = 0;
+	struct venus_hfi_device *device = dev;
+
+	if (!device) {
+		dprintk(VIDC_ERR, "%s Invalid paramter: %p\n",
+			__func__, device);
+		return -EINVAL;
+	}
+
+	switch (info) {
+	case FW_BASE_ADDRESS:
+		rc = device->base_addr;
+		break;
+
+	case FW_REGISTER_BASE:
+		rc = device->register_base;
+		break;
+
+	case FW_REGISTER_SIZE:
+		rc = device->register_size;
+		break;
+
+	case FW_IRQ:
+		rc = device->irq;
+		break;
+
+	default:
+		dprintk(VIDC_ERR, "Invalid fw info requested");
+	}
+	return rc;
+}
+
+int venus_hfi_get_stride_scanline(int color_fmt,
+	int width, int height, int *stride, int *scanlines) {
+	*stride = VENUS_Y_STRIDE(color_fmt, width);
+	*scanlines = VENUS_Y_SCANLINES(color_fmt, height);
+	return 0;
+}
+
+static void *venus_hfi_add_device(u32 device_id,
+			struct msm_vidc_platform_resources *res,
+			hfi_cmd_response_callback callback)
+{
+	struct venus_hfi_device *hdevice = NULL;
+	int rc = 0;
+
+	if (device_id || !res || !callback) {
+		dprintk(VIDC_ERR, "Invalid Paramters");
+		return NULL;
+	}
+
+	dprintk(VIDC_INFO, "entered , device_id: %d", device_id);
+
+	hdevice = (struct venus_hfi_device *)
+			kzalloc(sizeof(struct venus_hfi_device), GFP_KERNEL);
+	if (!hdevice) {
+		dprintk(VIDC_ERR, "failed to allocate new device");
+		goto err_alloc;
+	}
+
+	rc = venus_hfi_init_regs_and_interrupts(hdevice, res);
+	if (rc)
+		goto err_init_regs;
+
+	INIT_LIST_HEAD(&hal_ctxt.dev_head);
+	INIT_LIST_HEAD(&hdevice->list);
+	list_add_tail(&hdevice->list, &hal_ctxt.dev_head);
+	hal_ctxt.dev_count++;
+	hdevice->device_id = device_id;
+
+	hdevice->callback = callback;
+
+	hdevice->vidc_workq = create_singlethread_workqueue(
+		"msm_vidc_workerq");
+	if (!hdevice->vidc_workq) {
+		dprintk(VIDC_ERR, ": create workq failed\n");
+		goto error_createq;
+	}
+
+	return (void *) hdevice;
+error_createq:
+	hal_ctxt.dev_count--;
+	list_del(&hal_ctxt.dev_head);
+err_init_regs:
+	kfree(hdevice);
+err_alloc:
+	return NULL;
+}
+
+static void *venus_hfi_get_device(u32 device_id,
+				struct msm_vidc_platform_resources *res,
+				hfi_cmd_response_callback callback)
+{
+	struct venus_hfi_device *device;
+	int rc = 0;
+
+	if (!res || !callback) {
+		dprintk(VIDC_ERR, "Invalid params: %p %p\n", res, callback);
+		return NULL;
+	}
+
+	device = venus_hfi_add_device(device_id, res, &handle_cmd_response);
+	if (!device) {
+		dprintk(VIDC_ERR, "Failed to create HFI device\n");
+		return NULL;
+	}
+
+	rc = venus_hfi_init_resources(device, res);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to init resources: %d\n", rc);
+		goto err_fail_init_res;
+	}
+	return device;
+
+err_fail_init_res:
+	venus_hfi_delete_device(device);
+	return NULL;
+}
+
+void venus_hfi_delete_device(void *device)
+{
+	struct venus_hfi_device *close, *dev;
+
+	if (device) {
+		venus_hfi_deinit_resources(device);
+		dev = (struct venus_hfi_device *) device;
+		list_for_each_entry(close, &hal_ctxt.dev_head, list) {
+			if (close->hal_data->irq == dev->hal_data->irq) {
+				hal_ctxt.dev_count--;
+				free_irq(dev->hal_data->irq, close);
+				list_del(&close->list);
+				destroy_workqueue(close->vidc_workq);
+				kfree(close->hal_data);
+				kfree(close);
+				break;
+			}
+		}
+
+	}
+}
+
+static void venus_init_hfi_callbacks(struct hfi_device *hdev)
+{
+	hdev->core_init = venus_hfi_core_init;
+	hdev->core_release = venus_hfi_core_release;
+	hdev->core_pc_prep = venus_hfi_core_pc_prep;
+	hdev->core_ping = venus_hfi_core_ping;
+	hdev->core_trigger_ssr = venus_hfi_core_trigger_ssr;
+	hdev->session_init = venus_hfi_session_init;
+	hdev->session_end = venus_hfi_session_end;
+	hdev->session_abort = venus_hfi_session_abort;
+	hdev->session_set_buffers = venus_hfi_session_set_buffers;
+	hdev->session_release_buffers = venus_hfi_session_release_buffers;
+	hdev->session_load_res = venus_hfi_session_load_res;
+	hdev->session_release_res = venus_hfi_session_release_res;
+	hdev->session_start = venus_hfi_session_start;
+	hdev->session_stop = venus_hfi_session_stop;
+	hdev->session_suspend = venus_hfi_session_suspend;
+	hdev->session_resume = venus_hfi_session_resume;
+	hdev->session_etb = venus_hfi_session_etb;
+	hdev->session_ftb = venus_hfi_session_ftb;
+	hdev->session_parse_seq_hdr = venus_hfi_session_parse_seq_hdr;
+	hdev->session_get_seq_hdr = venus_hfi_session_get_seq_hdr;
+	hdev->session_get_buf_req = venus_hfi_session_get_buf_req;
+	hdev->session_flush = venus_hfi_session_flush;
+	hdev->session_set_property = venus_hfi_session_set_property;
+	hdev->session_get_property = venus_hfi_session_get_property;
+	hdev->scale_clocks = venus_hfi_scale_clocks;
+	hdev->scale_bus = venus_hfi_scale_bus;
+	hdev->unvote_bus = venus_hfi_unvote_bus;
+	hdev->unset_ocmem = venus_hfi_unset_ocmem;
+	hdev->alloc_ocmem = venus_hfi_alloc_ocmem;
+	hdev->free_ocmem = venus_hfi_free_ocmem;
+	hdev->is_ocmem_present = venus_hfi_is_ocmem_present;
+	hdev->get_domain = venus_hfi_get_domain;
+	hdev->iommu_get_map = venus_hfi_iommu_get_map;
+	hdev->load_fw = venus_hfi_load_fw;
+	hdev->unload_fw = venus_hfi_unload_fw;
+	hdev->get_fw_info = venus_hfi_get_fw_info;
+	hdev->get_stride_scanline = venus_hfi_get_stride_scanline;
+}
+
+int venus_hfi_initialize(struct hfi_device *hdev, u32 device_id,
+		struct msm_vidc_platform_resources *res,
+		hfi_cmd_response_callback callback)
+{
+	int rc = 0;
+
+	if (!hdev || !res || !callback) {
+		dprintk(VIDC_ERR, "Invalid params: %p %p %p\n",
+			hdev, res, callback);
+		rc = -EINVAL;
+		goto err_venus_hfi_init;
+	}
+	hdev->hfi_device_data = venus_hfi_get_device(device_id, res, callback);
+
+	venus_init_hfi_callbacks(hdev);
+
+err_venus_hfi_init:
+	return rc;
+}
+
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.h b/drivers/media/platform/msm/vidc/venus_hfi.h
new file mode 100644
index 0000000..2ffb9d4
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/venus_hfi.h
@@ -0,0 +1,205 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __H_VENUS_HFI_H__
+#define __H_VENUS_HFI_H__
+
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <mach/ocmem.h>
+#include <mach/iommu_domains.h>
+
+#include "vidc_hfi_api.h"
+#include "msm_smem.h"
+#include "vidc_hfi_helper.h"
+#include "vidc_hfi_api.h"
+#include "vidc_hfi.h"
+#include "msm_vidc_resources.h"
+
+#define HFI_MASK_QHDR_TX_TYPE			0xFF000000
+#define HFI_MASK_QHDR_RX_TYPE			0x00FF0000
+#define HFI_MASK_QHDR_PRI_TYPE			0x0000FF00
+#define HFI_MASK_QHDR_Q_ID_TYPE			0x000000FF
+#define HFI_Q_ID_HOST_TO_CTRL_CMD_Q		0x00
+#define HFI_Q_ID_CTRL_TO_HOST_MSG_Q		0x01
+#define HFI_Q_ID_CTRL_TO_HOST_DEBUG_Q	0x02
+#define HFI_MASK_QHDR_STATUS			0x000000FF
+
+#define VIDC_MAX_UNCOMPRESSED_FMT_PLANES	3
+
+#define VIDC_IFACEQ_NUMQ					3
+#define VIDC_IFACEQ_CMDQ_IDX				0
+#define VIDC_IFACEQ_MSGQ_IDX				1
+#define VIDC_IFACEQ_DBGQ_IDX				2
+#define VIDC_IFACEQ_MAX_BUF_COUNT			50
+#define VIDC_IFACE_MAX_PARALLEL_CLNTS		16
+#define VIDC_IFACEQ_DFLT_QHDR				0x01010000
+
+#define VIDC_MAX_NAME_LENGTH 64
+
+struct hfi_queue_table_header {
+	u32 qtbl_version;
+	u32 qtbl_size;
+	u32 qtbl_qhdr0_offset;
+	u32 qtbl_qhdr_size;
+	u32 qtbl_num_q;
+	u32 qtbl_num_active_q;
+};
+
+struct hfi_queue_header {
+	u32 qhdr_status;
+	u32 qhdr_start_addr;
+	u32 qhdr_type;
+	u32 qhdr_q_size;
+	u32 qhdr_pkt_size;
+	u32 qhdr_pkt_drop_cnt;
+	u32 qhdr_rx_wm;
+	u32 qhdr_tx_wm;
+	u32 qhdr_rx_req;
+	u32 qhdr_tx_req;
+	u32 qhdr_rx_irq_status;
+	u32 qhdr_tx_irq_status;
+	u32 qhdr_read_idx;
+	u32 qhdr_write_idx;
+};
+
+struct hfi_mem_map_table {
+	u32 mem_map_num_entries;
+	u32 *mem_map_table_base_addr;
+};
+
+struct hfi_mem_map {
+	u32 virtual_addr;
+	u32 physical_addr;
+	u32 size;
+	u32 attr;
+};
+
+#define VIDC_IFACEQ_TABLE_SIZE (sizeof(struct hfi_queue_table_header) \
+	+ sizeof(struct hfi_queue_header) * VIDC_IFACEQ_NUMQ)
+
+#define VIDC_IFACEQ_QUEUE_SIZE	(VIDC_IFACEQ_MAX_PKT_SIZE *  \
+	VIDC_IFACEQ_MAX_BUF_COUNT * VIDC_IFACE_MAX_PARALLEL_CLNTS)
+
+#define VIDC_IFACEQ_GET_QHDR_START_ADDR(ptr, i)     \
+	(void *)((((u32)ptr) + sizeof(struct hfi_queue_table_header)) + \
+		(i * sizeof(struct hfi_queue_header)))
+
+#define QDSS_SIZE 4096
+#define SFR_SIZE 4096
+
+#define QUEUE_SIZE (VIDC_IFACEQ_TABLE_SIZE + \
+	(VIDC_IFACEQ_QUEUE_SIZE * VIDC_IFACEQ_NUMQ))
+
+enum vidc_hw_reg {
+	VIDC_HWREG_CTRL_STATUS =  0x1,
+	VIDC_HWREG_QTBL_INFO =  0x2,
+	VIDC_HWREG_QTBL_ADDR =  0x3,
+	VIDC_HWREG_CTRLR_RESET =  0x4,
+	VIDC_HWREG_IFACEQ_FWRXREQ =  0x5,
+	VIDC_HWREG_IFACEQ_FWTXREQ =  0x6,
+	VIDC_HWREG_VHI_SOFTINTEN =  0x7,
+	VIDC_HWREG_VHI_SOFTINTSTATUS =  0x8,
+	VIDC_HWREG_VHI_SOFTINTCLR =  0x9,
+	VIDC_HWREG_HVI_SOFTINTEN =  0xA,
+};
+
+struct vidc_mem_addr {
+	u8 *align_device_addr;
+	u8 *align_virtual_addr;
+	u32 mem_size;
+	struct msm_smem *mem_data;
+};
+
+struct vidc_iface_q_info {
+	void *q_hdr;
+	struct vidc_mem_addr q_array;
+};
+
+/* Internal data used in vidc_hal not exposed to msm_vidc*/
+
+struct hal_data {
+	u32 irq;
+	u32 device_base_addr;
+	u8 *register_base_addr;
+};
+
+enum vidc_clocks {
+	VCODEC_CLK,
+	VCODEC_AHB_CLK,
+	VCODEC_AXI_CLK,
+	VCODEC_OCMEM_CLK,
+	VCODEC_MAX_CLKS
+};
+
+struct venus_core_clock {
+	char name[VIDC_MAX_NAME_LENGTH];
+	struct clk *clk;
+	u32 count;
+	struct load_freq_table load_freq_tbl[8];
+};
+
+struct venus_bus_info {
+	u32 ddr_handle[MSM_VIDC_MAX_DEVICES];
+	u32 ocmem_handle[MSM_VIDC_MAX_DEVICES];
+};
+
+struct on_chip_mem {
+	struct ocmem_buf *buf;
+	struct notifier_block vidc_ocmem_nb;
+	void *handle;
+};
+
+struct venus_resources {
+	struct msm_vidc_fw fw;
+	struct msm_vidc_iommu_info io_map[MAX_MAP];
+	struct venus_core_clock clock[VCODEC_MAX_CLKS];
+	struct venus_bus_info bus_info;
+	struct on_chip_mem ocmem;
+};
+
+struct venus_hfi_device {
+	struct list_head list;
+	struct list_head sess_head;
+	u32 intr_status;
+	u32 device_id;
+	u32 load;
+	u32 clocks_enabled;
+	struct mutex read_lock;
+	struct mutex write_lock;
+	msm_vidc_callback callback;
+	struct vidc_mem_addr iface_q_table;
+	struct vidc_mem_addr qdss;
+	struct vidc_mem_addr sfr;
+	struct vidc_mem_addr mem_addr;
+	struct vidc_iface_q_info iface_queues[VIDC_IFACEQ_NUMQ];
+	struct smem_client *hal_client;
+	struct hal_data *hal_data;
+	struct workqueue_struct *vidc_workq;
+	int spur_count;
+	int reg_count;
+	u32 base_addr;
+	u32 register_base;
+	u32 register_size;
+	u32 irq;
+	struct venus_resources resources;
+	struct msm_vidc_platform_resources *res;
+};
+
+void venus_hfi_delete_device(void *device);
+int venus_hfi_initialize(struct hfi_device *hdev, u32 device_id,
+		struct msm_vidc_platform_resources *res,
+		hfi_cmd_response_callback callback);
+#endif
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi.c b/drivers/media/platform/msm/vidc/vidc_hfi.c
new file mode 100644
index 0000000..e8131dd
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/vidc_hfi.c
@@ -0,0 +1,83 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/slab.h>
+#include "msm_vidc_debug.h"
+#include "vidc_hfi_api.h"
+#include "venus_hfi.h"
+#include "q6_hfi.h"
+
+struct hal_device_data hal_ctxt;
+
+void *vidc_hfi_initialize(enum msm_vidc_hfi_type hfi_type, u32 device_id,
+			struct msm_vidc_platform_resources *res,
+			hfi_cmd_response_callback callback)
+{
+	struct hfi_device *hdev = NULL;
+	int rc = 0;
+	hdev = (struct hfi_device *)
+			kzalloc(sizeof(struct hfi_device), GFP_KERNEL);
+	if (!hdev) {
+		dprintk(VIDC_ERR, "%s: failed to allocate hdev\n", __func__);
+		return NULL;
+	}
+
+	switch (hfi_type) {
+	case VIDC_HFI_VENUS:
+		rc = venus_hfi_initialize(hdev, device_id, res, callback);
+		break;
+
+	case VIDC_HFI_Q6:
+		rc = q6_hfi_initialize(hdev, device_id, callback);
+		break;
+
+	default:
+		dprintk(VIDC_ERR, "Unsupported host-firmware interface\n");
+		goto err_hfi_init;
+	}
+
+	if (rc) {
+		dprintk(VIDC_ERR, "%s device init failed rc = %d",
+				__func__, rc);
+		goto err_hfi_init;
+	}
+
+	return hdev;
+
+err_hfi_init:
+	kfree(hdev);
+	return NULL;
+}
+
+void vidc_hfi_deinitialize(enum msm_vidc_hfi_type hfi_type,
+			struct hfi_device *hdev)
+{
+	if (!hdev) {
+		dprintk(VIDC_ERR, "%s invalid device %p", __func__, hdev);
+		return;
+	}
+
+	switch (hfi_type) {
+	case VIDC_HFI_VENUS:
+		venus_hfi_delete_device(hdev->hfi_device_data);
+		break;
+
+	case VIDC_HFI_Q6:
+		q6_hfi_delete_device(hdev->hfi_device_data);
+		break;
+
+	default:
+		dprintk(VIDC_ERR, "Unsupported host-firmware interface\n");
+	}
+	kfree(hdev);
+}
+
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi.h b/drivers/media/platform/msm/vidc/vidc_hfi.h
new file mode 100644
index 0000000..8b3e7cb
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/vidc_hfi.h
@@ -0,0 +1,838 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef __H_VIDC_HFI_H__
+#define __H_VIDC_HFI_H__
+
+#include <media/msm_media_info.h>
+#include "vidc_hfi_helper.h"
+#include "vidc_hfi_api.h"
+
+#define HFI_EVENT_SESSION_SEQUENCE_CHANGED (HFI_OX_BASE + 0x3)
+#define HFI_EVENT_SESSION_PROPERTY_CHANGED (HFI_OX_BASE + 0x4)
+
+#define HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUFFER_RESOURCES	\
+	(HFI_OX_BASE + 0x1)
+#define HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUFFER_RESOURCES	\
+	(HFI_OX_BASE + 0x2)
+
+#define HFI_BUFFERFLAG_EOS				0x00000001
+#define HFI_BUFFERFLAG_STARTTIME		0x00000002
+#define HFI_BUFFERFLAG_DECODEONLY		0x00000004
+#define HFI_BUFFERFLAG_DATACORRUPT		0x00000008
+#define HFI_BUFFERFLAG_ENDOFFRAME		0x00000010
+#define HFI_BUFFERFLAG_SYNCFRAME		0x00000020
+#define HFI_BUFFERFLAG_EXTRADATA		0x00000040
+#define HFI_BUFFERFLAG_CODECCONFIG		0x00000080
+#define HFI_BUFFERFLAG_TIMESTAMPINVALID	0x00000100
+#define HFI_BUFFERFLAG_READONLY			0x00000200
+#define HFI_BUFFERFLAG_ENDOFSUBFRAME	0x00000400
+#define HFI_BUFFERFLAG_EOSEQ			0x00200000
+#define HFI_BUFFERFLAG_DISCONTINUITY	0x80000000
+#define HFI_BUFFERFLAG_TEI				0x40000000
+
+#define HFI_ERR_SESSION_EMPTY_BUFFER_DONE_OUTPUT_PENDING	\
+	(HFI_OX_BASE + 0x1001)
+#define HFI_ERR_SESSION_SAME_STATE_OPERATION		\
+	(HFI_OX_BASE + 0x1002)
+#define HFI_ERR_SESSION_SYNC_FRAME_NOT_DETECTED		\
+	(HFI_OX_BASE + 0x1003)
+#define  HFI_ERR_SESSION_START_CODE_NOT_FOUND		\
+	(HFI_OX_BASE + 0x1004)
+
+#define HFI_BUFFER_INTERNAL_SCRATCH (HFI_OX_BASE + 0x1)
+#define HFI_BUFFER_EXTRADATA_INPUT (HFI_OX_BASE + 0x2)
+#define HFI_BUFFER_EXTRADATA_OUTPUT (HFI_OX_BASE + 0x3)
+#define HFI_BUFFER_EXTRADATA_OUTPUT2 (HFI_OX_BASE + 0x4)
+#define HFI_BUFFER_INTERNAL_SCRATCH_1 (HFI_OX_BASE + 0x5)
+#define HFI_BUFFER_INTERNAL_SCRATCH_2 (HFI_OX_BASE + 0x6)
+
+#define HFI_BUFFER_MODE_STATIC (HFI_OX_BASE + 0x1)
+#define HFI_BUFFER_MODE_RING (HFI_OX_BASE + 0x2)
+
+#define HFI_FLUSH_INPUT (HFI_OX_BASE + 0x1)
+#define HFI_FLUSH_OUTPUT (HFI_OX_BASE + 0x2)
+#define HFI_FLUSH_OUTPUT2 (HFI_OX_BASE + 0x3)
+#define HFI_FLUSH_ALL (HFI_OX_BASE + 0x4)
+
+#define HFI_EXTRADATA_NONE					0x00000000
+#define HFI_EXTRADATA_MB_QUANTIZATION		0x00000001
+#define HFI_EXTRADATA_INTERLACE_VIDEO		0x00000002
+#define HFI_EXTRADATA_VC1_FRAMEDISP			0x00000003
+#define HFI_EXTRADATA_VC1_SEQDISP			0x00000004
+#define HFI_EXTRADATA_TIMESTAMP				0x00000005
+#define HFI_EXTRADATA_S3D_FRAME_PACKING		0x00000006
+#define HFI_EXTRADATA_FRAME_RATE			0x00000007
+#define HFI_EXTRADATA_PANSCAN_WINDOW		0x00000008
+#define HFI_EXTRADATA_RECOVERY_POINT_SEI	0x00000009
+#define HFI_EXTRADATA_CLOSED_CAPTION_UD		0x0000000A
+#define HFI_EXTRADATA_AFD_UD				0x0000000B
+#define HFI_EXTRADATA_MULTISLICE_INFO		0x7F100000
+#define HFI_EXTRADATA_NUM_CONCEALED_MB		0x7F100001
+#define HFI_EXTRADATA_INDEX					0x7F100002
+#define HFI_EXTRADATA_METADATA_FILLER		0x7FE00002
+
+#define HFI_INDEX_EXTRADATA_INPUT_CROP		0x0700000E
+#define HFI_INDEX_EXTRADATA_DIGITAL_ZOOM	0x07000010
+#define HFI_INDEX_EXTRADATA_ASPECT_RATIO	0x7F100003
+
+struct hfi_buffer_alloc_mode {
+	u32 buffer_type;
+	u32 buffer_mode;
+};
+
+
+struct hfi_index_extradata_config {
+	int enable;
+	u32 index_extra_data_id;
+};
+
+struct hfi_extradata_header {
+	u32 size;
+	u32 version;
+	u32 port_index;
+	u32 type;
+	u32 data_size;
+	u8 rg_data[1];
+};
+
+#define HFI_INTERLACE_FRAME_PROGRESSIVE					0x01
+#define HFI_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST	0x02
+#define HFI_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST	0x04
+#define HFI_INTERLACE_FRAME_TOPFIELDFIRST				0x08
+#define HFI_INTERLACE_FRAME_BOTTOMFIELDFIRST			0x10
+
+#define HFI_PROPERTY_SYS_OX_START			\
+	(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + 0x0000)
+#define HFI_PROPERTY_SYS_IDLE_INDICATOR		\
+	(HFI_PROPERTY_SYS_OX_START + 0x001)
+
+#define HFI_PROPERTY_PARAM_OX_START				\
+	(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + 0x1000)
+#define HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL			\
+	(HFI_PROPERTY_PARAM_OX_START + 0x001)
+#define HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO	\
+	(HFI_PROPERTY_PARAM_OX_START + 0x002)
+#define HFI_PROPERTY_PARAM_INTERLACE_FORMAT_SUPPORTED	\
+	(HFI_PROPERTY_PARAM_OX_START + 0x003)
+#define HFI_PROPERTY_PARAM_CHROMA_SITE					\
+(HFI_PROPERTY_PARAM_OX_START + 0x004)
+#define HFI_PROPERTY_PARAM_EXTRA_DATA_HEADER_CONFIG		\
+	(HFI_PROPERTY_PARAM_OX_START + 0x005)
+#define HFI_PROPERTY_PARAM_INDEX_EXTRADATA             \
+	(HFI_PROPERTY_PARAM_OX_START + 0x006)
+#define HFI_PROPERTY_PARAM_DIVX_FORMAT					\
+	(HFI_PROPERTY_PARAM_OX_START + 0x007)
+#define HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE			\
+	(HFI_PROPERTY_PARAM_OX_START + 0x008)
+#define HFI_PROPERTY_PARAM_S3D_FRAME_PACKING_EXTRADATA	\
+	(HFI_PROPERTY_PARAM_OX_START + 0x009)
+
+#define HFI_PROPERTY_CONFIG_OX_START					\
+	(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + 0x02000)
+#define HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS			\
+	(HFI_PROPERTY_CONFIG_OX_START + 0x001)
+#define HFI_PROPERTY_CONFIG_REALTIME					\
+	(HFI_PROPERTY_CONFIG_OX_START + 0x002)
+#define HFI_PROPERTY_CONFIG_PRIORITY					\
+	(HFI_PROPERTY_CONFIG_OX_START + 0x003)
+#define HFI_PROPERTY_CONFIG_BATCH_INFO					\
+	(HFI_PROPERTY_CONFIG_OX_START + 0x004)
+
+#define HFI_PROPERTY_PARAM_VDEC_OX_START				\
+	(HFI_DOMAIN_BASE_VDEC + HFI_ARCH_OX_OFFSET + 0x3000)
+#define HFI_PROPERTY_PARAM_VDEC_CONTINUE_DATA_TRANSFER	\
+	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x001)
+#define HFI_PROPERTY_PARAM_VDEC_DISPLAY_PICTURE_BUFFER_COUNT\
+	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x002)
+#define HFI_PROPERTY_PARAM_VDEC_MULTI_VIEW_SELECT		\
+	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x003)
+#define HFI_PROPERTY_PARAM_VDEC_PICTURE_TYPE_DECODE		\
+	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x004)
+#define HFI_PROPERTY_PARAM_VDEC_OUTPUT_ORDER			\
+	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x005)
+#define HFI_PROPERTY_PARAM_VDEC_MB_QUANTIZATION			\
+	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x006)
+#define HFI_PROPERTY_PARAM_VDEC_NUM_CONCEALED_MB		\
+	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x007)
+#define HFI_PROPERTY_PARAM_VDEC_H264_ENTROPY_SWITCHING	\
+	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x008)
+#define HFI_PROPERTY_PARAM_VDEC_OUTPUT2_KEEP_ASPECT_RATIO\
+	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x009)
+#define HFI_PROPERTY_PARAM_VDEC_FRAME_RATE_EXTRADATA  \
+	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x00A)
+#define HFI_PROPERTY_PARAM_VDEC_PANSCAN_WNDW_EXTRADATA \
+	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x00B)
+#define HFI_PROPERTY_PARAM_VDEC_RECOVERY_POINT_SEI_EXTRADATA \
+	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x00C)
+#define HFI_PROPERTY_PARAM_VDEC_THUMBNAIL_MODE   \
+	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x00D)
+
+#define HFI_PROPERTY_PARAM_VDEC_FRAME_ASSEMBLY		\
+	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x00E)
+#define HFI_PROPERTY_PARAM_VDEC_CLOSED_CAPTION_EXTRADATA	\
+	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x00F)
+#define HFI_PROPERTY_PARAM_VDEC_AFD_EXTRADATA		\
+	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x010)
+#define HFI_PROPERTY_PARAM_VDEC_VC1_FRAMEDISP_EXTRADATA		\
+	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x011)
+#define HFI_PROPERTY_PARAM_VDEC_VC1_SEQDISP_EXTRADATA		\
+	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x012)
+#define HFI_PROPERTY_PARAM_VDEC_TIMESTAMP_EXTRADATA			\
+	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x013)
+#define HFI_PROPERTY_PARAM_VDEC_INTERLACE_VIDEO_EXTRADATA	\
+	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x014)
+#define HFI_PROPERTY_PARAM_VDEC_AVC_SESSION_SELECT \
+	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x015)
+
+#define HFI_PROPERTY_CONFIG_VDEC_OX_START				\
+	(HFI_DOMAIN_BASE_VDEC + HFI_ARCH_OX_OFFSET + 0x0000)
+#define HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER	\
+	(HFI_PROPERTY_CONFIG_VDEC_OX_START + 0x001)
+#define HFI_PROPERTY_CONFIG_VDEC_MB_ERROR_MAP_REPORTING	\
+	(HFI_PROPERTY_CONFIG_VDEC_OX_START + 0x002)
+#define HFI_PROPERTY_CONFIG_VDEC_MB_ERROR_MAP			\
+	(HFI_PROPERTY_CONFIG_VDEC_OX_START + 0x003)
+
+#define HFI_PROPERTY_PARAM_VENC_OX_START				\
+	(HFI_DOMAIN_BASE_VENC + HFI_ARCH_OX_OFFSET + 0x5000)
+#define  HFI_PROPERTY_PARAM_VENC_MULTI_SLICE_INFO       \
+	(HFI_PROPERTY_PARAM_VENC_OX_START + 0x001)
+#define  HFI_PROPERTY_PARAM_VENC_H264_IDR_S3D_FRAME_PACKING_NAL \
+	(HFI_PROPERTY_PARAM_VENC_OX_START + 0x002)
+
+#define HFI_PROPERTY_CONFIG_VENC_OX_START				\
+	(HFI_DOMAIN_BASE_VENC + HFI_ARCH_OX_OFFSET + 0x6000)
+#define  HFI_PROPERTY_CONFIG_VENC_FRAME_QP				\
+	(HFI_PROPERTY_CONFIG_VENC_OX_START + 0x001)
+
+#define HFI_PROPERTY_PARAM_VPE_OX_START					\
+	(HFI_DOMAIN_BASE_VPE + HFI_ARCH_OX_OFFSET + 0x7000)
+#define HFI_PROPERTY_CONFIG_VPE_OX_START				\
+	(HFI_DOMAIN_BASE_VPE + HFI_ARCH_OX_OFFSET + 0x8000)
+
+struct hfi_batch_info {
+	u32 input_batch_count;
+	u32 output_batch_count;
+};
+
+struct hfi_buffer_count_actual {
+	u32 buffer_type;
+	u32 buffer_count_actual;
+};
+
+struct hfi_buffer_requirements {
+	u32 buffer_type;
+	u32 buffer_size;
+	u32 buffer_region_size;
+	u32 buffer_hold_count;
+	u32 buffer_count_min;
+	u32 buffer_count_actual;
+	u32 contiguous;
+	u32 buffer_alignment;
+};
+
+#define HFI_CHROMA_SITE_0			(HFI_OX_BASE + 0x1)
+#define HFI_CHROMA_SITE_1			(HFI_OX_BASE + 0x2)
+#define HFI_CHROMA_SITE_2			(HFI_OX_BASE + 0x3)
+#define HFI_CHROMA_SITE_3			(HFI_OX_BASE + 0x4)
+#define HFI_CHROMA_SITE_4			(HFI_OX_BASE + 0x5)
+#define HFI_CHROMA_SITE_5			(HFI_OX_BASE + 0x6)
+
+struct hfi_data_payload {
+	u32 size;
+	u8 rg_data[1];
+};
+
+struct hfi_enable_picture {
+	u32 picture_type;
+};
+
+struct hfi_display_picture_buffer_count {
+	int enable;
+	u32 count;
+};
+
+struct hfi_extra_data_header_config {
+	u32 type;
+	u32 buffer_type;
+	u32 version;
+	u32 port_index;
+	u32 client_extra_data_id;
+};
+
+struct hfi_interlace_format_supported {
+	u32 buffer_type;
+	u32 format;
+};
+
+struct hfi_mb_error_map {
+	u32 error_map_size;
+	u8 rg_error_map[1];
+};
+
+struct hfi_metadata_pass_through {
+	int enable;
+	u32 size;
+};
+
+struct hfi_multi_view_select {
+	u32 view_index;
+};
+
+#define HFI_PRIORITY_LOW		10
+#define HFI_PRIOIRTY_MEDIUM		20
+#define HFI_PRIORITY_HIGH		30
+
+#define HFI_OUTPUT_ORDER_DISPLAY	(HFI_OX_BASE + 0x1)
+#define HFI_OUTPUT_ORDER_DECODE		(HFI_OX_BASE + 0x2)
+
+#define HFI_RATE_CONTROL_OFF		(HFI_OX_BASE + 0x1)
+#define HFI_RATE_CONTROL_VBR_VFR	(HFI_OX_BASE + 0x2)
+#define HFI_RATE_CONTROL_VBR_CFR	(HFI_OX_BASE + 0x3)
+#define HFI_RATE_CONTROL_CBR_VFR	(HFI_OX_BASE + 0x4)
+#define HFI_RATE_CONTROL_CBR_CFR	(HFI_OX_BASE + 0x5)
+
+struct hfi_uncompressed_plane_actual_constraints_info {
+	u32 buffer_type;
+	u32 num_planes;
+	struct hfi_uncompressed_plane_constraints rg_plane_format[1];
+};
+
+#define HFI_CMD_SYS_OX_START		\
+(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + HFI_CMD_START_OFFSET + 0x0000)
+#define HFI_CMD_SYS_SESSION_ABORT	(HFI_CMD_SYS_OX_START + 0x001)
+#define HFI_CMD_SYS_PING		(HFI_CMD_SYS_OX_START + 0x002)
+
+#define HFI_CMD_SESSION_OX_START	\
+(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + HFI_CMD_START_OFFSET + 0x1000)
+#define HFI_CMD_SESSION_LOAD_RESOURCES	(HFI_CMD_SESSION_OX_START + 0x001)
+#define HFI_CMD_SESSION_START		(HFI_CMD_SESSION_OX_START + 0x002)
+#define HFI_CMD_SESSION_STOP		(HFI_CMD_SESSION_OX_START + 0x003)
+#define HFI_CMD_SESSION_EMPTY_BUFFER	(HFI_CMD_SESSION_OX_START + 0x004)
+#define HFI_CMD_SESSION_FILL_BUFFER	(HFI_CMD_SESSION_OX_START + 0x005)
+#define HFI_CMD_SESSION_SUSPEND		(HFI_CMD_SESSION_OX_START + 0x006)
+#define HFI_CMD_SESSION_RESUME		(HFI_CMD_SESSION_OX_START + 0x007)
+#define HFI_CMD_SESSION_FLUSH		(HFI_CMD_SESSION_OX_START + 0x008)
+#define HFI_CMD_SESSION_GET_PROPERTY	(HFI_CMD_SESSION_OX_START + 0x009)
+#define HFI_CMD_SESSION_PARSE_SEQUENCE_HEADER	\
+	(HFI_CMD_SESSION_OX_START + 0x00A)
+#define HFI_CMD_SESSION_RELEASE_BUFFERS		\
+	(HFI_CMD_SESSION_OX_START + 0x00B)
+#define HFI_CMD_SESSION_RELEASE_RESOURCES	\
+	(HFI_CMD_SESSION_OX_START + 0x00C)
+
+#define HFI_MSG_SYS_OX_START			\
+(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + HFI_MSG_START_OFFSET + 0x0000)
+#define HFI_MSG_SYS_IDLE		(HFI_MSG_SYS_OX_START + 0x1)
+#define HFI_MSG_SYS_PING_ACK	(HFI_MSG_SYS_OX_START + 0x2)
+#define HFI_MSG_SYS_PROPERTY_INFO	(HFI_MSG_SYS_OX_START + 0x3)
+#define HFI_MSG_SYS_SESSION_ABORT_DONE	(HFI_MSG_SYS_OX_START + 0x4)
+
+#define HFI_MSG_SESSION_OX_START		\
+(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + HFI_MSG_START_OFFSET + 0x1000)
+#define HFI_MSG_SESSION_LOAD_RESOURCES_DONE	(HFI_MSG_SESSION_OX_START + 0x1)
+#define HFI_MSG_SESSION_START_DONE		(HFI_MSG_SESSION_OX_START + 0x2)
+#define HFI_MSG_SESSION_STOP_DONE		(HFI_MSG_SESSION_OX_START + 0x3)
+#define HFI_MSG_SESSION_SUSPEND_DONE	(HFI_MSG_SESSION_OX_START + 0x4)
+#define HFI_MSG_SESSION_RESUME_DONE		(HFI_MSG_SESSION_OX_START + 0x5)
+#define HFI_MSG_SESSION_FLUSH_DONE		(HFI_MSG_SESSION_OX_START + 0x6)
+#define HFI_MSG_SESSION_EMPTY_BUFFER_DONE	(HFI_MSG_SESSION_OX_START + 0x7)
+#define HFI_MSG_SESSION_FILL_BUFFER_DONE	(HFI_MSG_SESSION_OX_START + 0x8)
+#define HFI_MSG_SESSION_PROPERTY_INFO		(HFI_MSG_SESSION_OX_START + 0x9)
+#define HFI_MSG_SESSION_RELEASE_RESOURCES_DONE	\
+	(HFI_MSG_SESSION_OX_START + 0xA)
+#define HFI_MSG_SESSION_PARSE_SEQUENCE_HEADER_DONE		\
+	(HFI_MSG_SESSION_OX_START + 0xB)
+#define  HFI_MSG_SESSION_RELEASE_BUFFERS_DONE			\
+	(HFI_MSG_SESSION_OX_START + 0xC)
+
+#define VIDC_IFACEQ_MAX_PKT_SIZE                        1024
+#define VIDC_IFACEQ_MED_PKT_SIZE                        768
+#define VIDC_IFACEQ_MIN_PKT_SIZE                        8
+#define VIDC_IFACEQ_VAR_SMALL_PKT_SIZE          100
+#define VIDC_IFACEQ_VAR_LARGE_PKT_SIZE          512
+
+
+struct hfi_cmd_sys_session_abort_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+};
+
+struct hfi_cmd_sys_ping_packet {
+	u32 size;
+	u32 packet_type;
+	u32 client_data;
+};
+
+struct hfi_cmd_session_load_resources_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+};
+
+struct hfi_cmd_session_start_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+};
+
+struct hfi_cmd_session_stop_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+};
+
+struct hfi_cmd_session_empty_buffer_compressed_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 time_stamp_hi;
+	u32 time_stamp_lo;
+	u32 flags;
+	u32 mark_target;
+	u32 mark_data;
+	u32 offset;
+	u32 alloc_len;
+	u32 filled_len;
+	u32 input_tag;
+	u8 *packet_buffer;
+	u8 *extra_data_buffer;
+	u32 rgData[0];
+};
+
+struct hfi_cmd_session_empty_buffer_uncompressed_plane0_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 view_id;
+	u32 time_stamp_hi;
+	u32 time_stamp_lo;
+	u32 flags;
+	u32 mark_target;
+	u32 mark_data;
+	u32 alloc_len;
+	u32 filled_len;
+	u32 offset;
+	u32 input_tag;
+	u8 *packet_buffer;
+	u8 *extra_data_buffer;
+	u32 rgData[0];
+};
+
+struct hfi_cmd_session_empty_buffer_uncompressed_plane1_packet {
+	u32 flags;
+	u32 alloc_len;
+	u32 filled_len;
+	u32 offset;
+	u8 *packet_buffer2;
+	u32 rgData[0];
+};
+
+struct hfi_cmd_session_empty_buffer_uncompressed_plane2_packet {
+	u32 flags;
+	u32 alloc_len;
+	u32 filled_len;
+	u32 offset;
+	u8 *packet_buffer3;
+	u32 rgData[0];
+};
+
+struct hfi_cmd_session_fill_buffer_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 stream_id;
+	u32 offset;
+	u32 alloc_len;
+	u32 filled_len;
+	u32 output_tag;
+	u8 *packet_buffer;
+	u8 *extra_data_buffer;
+	u32 rgData[0];
+};
+
+struct hfi_cmd_session_flush_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 flush_type;
+};
+
+struct hfi_cmd_session_suspend_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+};
+
+struct hfi_cmd_session_resume_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+};
+
+struct hfi_cmd_session_get_property_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 num_properties;
+	u32 rg_property_data[1];
+};
+
+struct hfi_cmd_session_release_buffer_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 buffer_type;
+	u32 buffer_size;
+	u32 extra_data_size;
+	int response_req;
+	u32 num_buffers;
+	u32 rg_buffer_info[1];
+};
+
+struct hfi_cmd_session_release_resources_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+};
+
+struct hfi_cmd_session_parse_sequence_header_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 header_len;
+	u8 *packet_buffer;
+};
+
+struct hfi_msg_sys_session_abort_done_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 error_type;
+};
+
+struct hfi_msg_sys_idle_packet {
+	u32 size;
+	u32 packet_type;
+};
+
+struct hfi_msg_sys_ping_ack_packet {
+	u32 size;
+	u32 packet_type;
+	u32 client_data;
+};
+
+struct hfi_msg_sys_property_info_packet {
+	u32 size;
+	u32 packet_type;
+	u32 num_properties;
+	u32 rg_property_data[1];
+};
+
+struct hfi_msg_session_load_resources_done_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 error_type;
+};
+
+struct hfi_msg_session_start_done_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 error_type;
+};
+
+struct hfi_msg_session_stop_done_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 error_type;
+};
+
+struct hfi_msg_session_suspend_done_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 error_type;
+};
+
+struct hfi_msg_session_resume_done_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 error_type;
+};
+
+struct hfi_msg_session_flush_done_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 error_type;
+	u32 flush_type;
+};
+
+struct hfi_msg_session_empty_buffer_done_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 error_type;
+	u32 offset;
+	u32 filled_len;
+	u32 input_tag;
+	u8 *packet_buffer;
+	u8 *extra_data_buffer;
+	u32 rgData[0];
+};
+
+struct hfi_msg_session_fill_buffer_done_compressed_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 time_stamp_hi;
+	u32 time_stamp_lo;
+	u32 error_type;
+	u32 flags;
+	u32 mark_target;
+	u32 mark_data;
+	u32 stats;
+	u32 offset;
+	u32 alloc_len;
+	u32 filled_len;
+	u32 input_tag;
+	u32 output_tag;
+	u32 picture_type;
+	u8 *packet_buffer;
+	u8 *extra_data_buffer;
+	u32 rgData[0];
+};
+
+struct hfi_msg_session_fbd_uncompressed_plane0_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 stream_id;
+	u32 view_id;
+	u32 error_type;
+	u32 time_stamp_hi;
+	u32 time_stamp_lo;
+	u32 flags;
+	u32 mark_target;
+	u32 mark_data;
+	u32 stats;
+	u32 alloc_len;
+	u32 filled_len;
+	u32 offset;
+	u32 frame_width;
+	u32 frame_height;
+	u32 start_x_coord;
+	u32 start_y_coord;
+	u32 input_tag;
+	u32 input_tag2;
+	u32 output_tag;
+	u32 picture_type;
+	u8 *packet_buffer;
+	u8 *extra_data_buffer;
+	u32 rgData[0];
+};
+
+struct hfi_msg_session_fill_buffer_done_uncompressed_plane1_packet {
+	u32 flags;
+	u32 alloc_len;
+	u32 filled_len;
+	u32 offset;
+	u8 *packet_buffer2;
+	u32 rgData[0];
+};
+
+struct hfi_msg_session_fill_buffer_done_uncompressed_plane2_packet {
+	u32 flags;
+	u32 alloc_len;
+	u32 filled_len;
+	u32 offset;
+	u8 *packet_buffer3;
+	u32 rgData[0];
+};
+
+struct hfi_msg_session_parse_sequence_header_done_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 error_type;
+	u32 num_properties;
+	u32 rg_property_data[1];
+};
+
+struct hfi_msg_session_property_info_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 num_properties;
+	u32 rg_property_data[1];
+};
+
+struct hfi_msg_session_release_resources_done_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 error_type;
+};
+
+struct hfi_msg_session_release_buffers_done_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 error_type;
+	u32 num_buffers;
+	u32 rg_buffer_info[1];
+};
+
+struct hfi_extradata_mb_quantization_payload {
+	u8 rg_mb_qp[1];
+};
+
+struct hfi_extradata_vc1_pswnd {
+	u32 ps_wnd_h_offset;
+	u32 ps_wnd_v_offset;
+	u32 ps_wnd_width;
+	u32 ps_wnd_height;
+};
+
+struct hfi_extradata_vc1_framedisp_payload {
+	u32 res_pic;
+	u32 ref;
+	u32 range_map_present;
+	u32 range_map_y;
+	u32 range_map_uv;
+	u32 num_pan_scan_wnds;
+	struct hfi_extradata_vc1_pswnd rg_ps_wnd[1];
+};
+
+struct hfi_extradata_vc1_seqdisp_payload {
+	u32 prog_seg_frm;
+	u32 uv_sampling_fmt;
+	u32 color_fmt_flag;
+	u32 color_primaries;
+	u32 transfer_char;
+	u32 mat_coeff;
+	u32 aspect_ratio;
+	u32 aspect_horiz;
+	u32 aspect_vert;
+};
+
+struct hfi_extradata_timestamp_payload {
+	u32 time_stamp_low;
+	u32 time_stamp_high;
+};
+
+
+struct hfi_extradata_s3d_frame_packing_payload {
+	u32 fpa_id;
+	int cancel_flag;
+	u32 fpa_type;
+	int quin_cunx_flag;
+	u32 content_interprtation_type;
+	int spatial_flipping_flag;
+	int frame0_flipped_flag;
+	int field_views_flag;
+	int current_frame_isFrame0_flag;
+	int frame0_self_contained_flag;
+	int frame1_self_contained_flag;
+	u32 frame0_graid_pos_x;
+	u32 frame0_graid_pos_y;
+	u32 frame1_graid_pos_x;
+	u32 frame1_graid_pos_y;
+	u32 fpa_reserved_byte;
+	u32 fpa_repetition_period;
+	int fpa_extension_flag;
+};
+
+struct hfi_extradata_interlace_video_payload {
+	u32 format;
+};
+
+struct hfi_extradata_num_concealed_mb_payload {
+	u32 num_mb_concealed;
+};
+
+struct hfi_extradata_sliceinfo {
+	u32 offset_in_stream;
+	u32 slice_length;
+};
+
+struct hfi_extradata_multislice_info_payload {
+	u32 num_slices;
+	struct hfi_extradata_sliceinfo rg_slice_info[1];
+};
+
+struct hfi_index_extradata_input_crop_payload {
+	u32 size;
+	u32 version;
+	u32 port_index;
+	u32 left;
+	u32 top;
+	u32 width;
+	u32 height;
+};
+
+struct hfi_index_extradata_digital_zoom_payload {
+	u32 size;
+	u32 version;
+	u32 port_index;
+	int width;
+	int height;
+};
+
+struct hfi_index_extradata_aspect_ratio_payload {
+	u32 size;
+	u32 version;
+	u32 port_index;
+	u32 aspect_width;
+	u32 aspect_height;
+};
+struct hfi_extradata_panscan_wndw_payload {
+	u32 num_window;
+	struct hfi_extradata_vc1_pswnd wnd[1];
+};
+
+struct hfi_extradata_frame_type_payload {
+	u32 frame_rate;
+};
+
+struct hfi_extradata_recovery_point_sei_payload {
+	u32 flag;
+};
+
+struct hal_session {
+	struct list_head list;
+	u32 session_id;
+	u32 is_decoder;
+	void *device;
+};
+
+struct hal_device_data {
+	struct list_head dev_head;
+	int dev_count;
+};
+
+struct msm_vidc_fw {
+	void *cookie;
+};
+
+extern struct hal_device_data hal_ctxt;
+
+u32 hfi_process_msg_packet(msm_vidc_callback callback,
+		u32 device_id, struct vidc_hal_msg_pkt_hdr *msg_hdr);
+#endif
+
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
new file mode 100644
index 0000000..a057303
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
@@ -0,0 +1,1085 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __VIDC_HFI_API_H__
+#define __VIDC_HFI_API_H__
+
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <media/msm_vidc.h>
+#include "msm_vidc_resources.h"
+
+#define CONTAINS(__a, __sz, __t) ({\
+	int __rc = __t >= __a && \
+			__t < __a + __sz; \
+	__rc; \
+})
+
+#define OVERLAPS(__t, __tsz, __a, __asz) ({\
+	int __rc = __t <= __a && \
+			__t + __tsz >= __a + __asz; \
+	__rc; \
+})
+
+#define HAL_BUFFERFLAG_EOS              0x00000001
+#define HAL_BUFFERFLAG_STARTTIME        0x00000002
+#define HAL_BUFFERFLAG_DECODEONLY       0x00000004
+#define HAL_BUFFERFLAG_DATACORRUPT      0x00000008
+#define HAL_BUFFERFLAG_ENDOFFRAME       0x00000010
+#define HAL_BUFFERFLAG_SYNCFRAME        0x00000020
+#define HAL_BUFFERFLAG_EXTRADATA        0x00000040
+#define HAL_BUFFERFLAG_CODECCONFIG      0x00000080
+#define HAL_BUFFERFLAG_TIMESTAMPINVALID 0x00000100
+#define HAL_BUFFERFLAG_READONLY         0x00000200
+#define HAL_BUFFERFLAG_ENDOFSUBFRAME    0x00000400
+#define HAL_BUFFERFLAG_EOSEQ            0x00200000
+
+#define HAL_DEBUG_MSG_LOW				0x00000001
+#define HAL_DEBUG_MSG_MEDIUM			0x00000002
+#define HAL_DEBUG_MSG_HIGH				0x00000004
+#define HAL_DEBUG_MSG_ERROR				0x00000008
+#define HAL_DEBUG_MSG_FATAL				0x00000010
+
+enum vidc_status {
+	VIDC_ERR_NONE = 0x0,
+	VIDC_ERR_FAIL = 0x80000000,
+	VIDC_ERR_ALLOC_FAIL,
+	VIDC_ERR_ILLEGAL_OP,
+	VIDC_ERR_BAD_PARAM,
+	VIDC_ERR_BAD_HANDLE,
+	VIDC_ERR_NOT_SUPPORTED,
+	VIDC_ERR_BAD_STATE,
+	VIDC_ERR_MAX_CLIENT,
+	VIDC_ERR_IFRAME_EXPECTED,
+	VIDC_ERR_HW_FATAL,
+	VIDC_ERR_BITSTREAM_ERR,
+	VIDC_ERR_INDEX_NOMORE,
+	VIDC_ERR_SEQHDR_PARSE_FAIL,
+	VIDC_ERR_INSUFFICIENT_BUFFER,
+	VIDC_ERR_BAD_POWER_STATE,
+	VIDC_ERR_NO_VALID_SESSION,
+	VIDC_ERR_TIMEOUT,
+	VIDC_ERR_CMDQFULL,
+	VIDC_ERR_CLIENT_PRESENT = 0x90000001,
+	VIDC_ERR_CLIENT_FATAL,
+	VIDC_ERR_CMD_QUEUE_FULL,
+	VIDC_ERR_UNUSED = 0x10000000
+};
+
+enum hal_extradata_id {
+	HAL_EXTRADATA_NONE,
+	HAL_EXTRADATA_MB_QUANTIZATION,
+	HAL_EXTRADATA_INTERLACE_VIDEO,
+	HAL_EXTRADATA_VC1_FRAMEDISP,
+	HAL_EXTRADATA_VC1_SEQDISP,
+	HAL_EXTRADATA_TIMESTAMP,
+	HAL_EXTRADATA_S3D_FRAME_PACKING,
+	HAL_EXTRADATA_FRAME_RATE,
+	HAL_EXTRADATA_PANSCAN_WINDOW,
+	HAL_EXTRADATA_RECOVERY_POINT_SEI,
+	HAL_EXTRADATA_CLOSED_CAPTION_UD,
+	HAL_EXTRADATA_AFD_UD,
+	HAL_EXTRADATA_MULTISLICE_INFO,
+	HAL_EXTRADATA_INDEX,
+	HAL_EXTRADATA_NUM_CONCEALED_MB,
+	HAL_EXTRADATA_METADATA_FILLER,
+	HAL_EXTRADATA_ASPECT_RATIO,
+};
+
+enum hal_property {
+	HAL_CONFIG_FRAME_RATE = 0x04000001,
+	HAL_PARAM_UNCOMPRESSED_FORMAT_SELECT,
+	HAL_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO,
+	HAL_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO,
+	HAL_PARAM_EXTRA_DATA_HEADER_CONFIG,
+	HAL_PARAM_INDEX_EXTRADATA,
+	HAL_PARAM_FRAME_SIZE,
+	HAL_CONFIG_REALTIME,
+	HAL_PARAM_BUFFER_COUNT_ACTUAL,
+	HAL_PARAM_NAL_STREAM_FORMAT_SELECT,
+	HAL_PARAM_VDEC_OUTPUT_ORDER,
+	HAL_PARAM_VDEC_PICTURE_TYPE_DECODE,
+	HAL_PARAM_VDEC_OUTPUT2_KEEP_ASPECT_RATIO,
+	HAL_CONFIG_VDEC_POST_LOOP_DEBLOCKER,
+	HAL_PARAM_VDEC_MULTI_STREAM,
+	HAL_PARAM_VDEC_DISPLAY_PICTURE_BUFFER_COUNT,
+	HAL_PARAM_DIVX_FORMAT,
+	HAL_CONFIG_VDEC_MB_ERROR_MAP_REPORTING,
+	HAL_PARAM_VDEC_CONTINUE_DATA_TRANSFER,
+	HAL_CONFIG_VDEC_MB_ERROR_MAP,
+	HAL_CONFIG_VENC_REQUEST_IFRAME,
+	HAL_PARAM_VENC_MPEG4_SHORT_HEADER,
+	HAL_PARAM_VENC_MPEG4_AC_PREDICTION,
+	HAL_CONFIG_VENC_TARGET_BITRATE,
+	HAL_PARAM_PROFILE_LEVEL_CURRENT,
+	HAL_PARAM_VENC_H264_ENTROPY_CONTROL,
+	HAL_PARAM_VENC_RATE_CONTROL,
+	HAL_PARAM_VENC_MPEG4_TIME_RESOLUTION,
+	HAL_PARAM_VENC_MPEG4_HEADER_EXTENSION,
+	HAL_PARAM_VENC_H264_DEBLOCK_CONTROL,
+	HAL_PARAM_VENC_TEMPORAL_SPATIAL_TRADEOFF,
+	HAL_PARAM_VENC_SESSION_QP,
+	HAL_CONFIG_VENC_INTRA_PERIOD,
+	HAL_CONFIG_VENC_IDR_PERIOD,
+	HAL_CONFIG_VPE_OPERATIONS,
+	HAL_PARAM_VENC_INTRA_REFRESH,
+	HAL_PARAM_VENC_MULTI_SLICE_CONTROL,
+	HAL_CONFIG_VPE_DEINTERLACE,
+	HAL_SYS_DEBUG_CONFIG,
+	HAL_CONFIG_BUFFER_REQUIREMENTS,
+	HAL_CONFIG_PRIORITY,
+	HAL_CONFIG_BATCH_INFO,
+	HAL_PARAM_METADATA_PASS_THROUGH,
+	HAL_SYS_IDLE_INDICATOR,
+	HAL_PARAM_UNCOMPRESSED_FORMAT_SUPPORTED,
+	HAL_PARAM_INTERLACE_FORMAT_SUPPORTED,
+	HAL_PARAM_CHROMA_SITE,
+	HAL_PARAM_PROPERTIES_SUPPORTED,
+	HAL_PARAM_PROFILE_LEVEL_SUPPORTED,
+	HAL_PARAM_CAPABILITY_SUPPORTED,
+	HAL_PARAM_NAL_STREAM_FORMAT_SUPPORTED,
+	HAL_PARAM_MULTI_VIEW_FORMAT,
+	HAL_PARAM_MAX_SEQUENCE_HEADER_SIZE,
+	HAL_PARAM_CODEC_SUPPORTED,
+	HAL_PARAM_VDEC_MULTI_VIEW_SELECT,
+	HAL_PARAM_VDEC_MB_QUANTIZATION,
+	HAL_PARAM_VDEC_NUM_CONCEALED_MB,
+	HAL_PARAM_VDEC_H264_ENTROPY_SWITCHING,
+	HAL_PARAM_VENC_SLICE_DELIVERY_MODE,
+	HAL_PARAM_VENC_MPEG4_DATA_PARTITIONING,
+	HAL_CONFIG_BUFFER_COUNT_ACTUAL,
+	HAL_CONFIG_VDEC_MULTI_STREAM,
+	HAL_PARAM_VENC_MULTI_SLICE_INFO,
+	HAL_CONFIG_VENC_TIMESTAMP_SCALE,
+	HAL_PARAM_VENC_LOW_LATENCY,
+	HAL_PARAM_VENC_SYNC_FRAME_SEQUENCE_HEADER,
+	HAL_PARAM_VDEC_SYNC_FRAME_DECODE,
+};
+
+enum hal_domain {
+	HAL_VIDEO_DOMAIN_VPE,
+	HAL_VIDEO_DOMAIN_ENCODER,
+	HAL_VIDEO_DOMAIN_DECODER,
+	HAL_UNUSED_DOMAIN = 0x10000000,
+};
+
+enum hal_video_codec {
+	HAL_VIDEO_CODEC_UNKNOWN  = 0x00000000,
+	HAL_VIDEO_CODEC_MVC      = 0x00000001,
+	HAL_VIDEO_CODEC_H264     = 0x00000002,
+	HAL_VIDEO_CODEC_H263     = 0x00000004,
+	HAL_VIDEO_CODEC_MPEG1    = 0x00000008,
+	HAL_VIDEO_CODEC_MPEG2    = 0x00000010,
+	HAL_VIDEO_CODEC_MPEG4    = 0x00000020,
+	HAL_VIDEO_CODEC_DIVX_311 = 0x00000040,
+	HAL_VIDEO_CODEC_DIVX     = 0x00000080,
+	HAL_VIDEO_CODEC_VC1      = 0x00000100,
+	HAL_VIDEO_CODEC_SPARK    = 0x00000200,
+	HAL_VIDEO_CODEC_VP6      = 0x00000400,
+	HAL_VIDEO_CODEC_VP7      = 0x00000800,
+	HAL_VIDEO_CODEC_VP8      = 0x00001000,
+	HAL_UNUSED_CODEC = 0x10000000,
+};
+
+enum hal_h263_profile {
+	HAL_H263_PROFILE_BASELINE           = 0x00000001,
+	HAL_H263_PROFILE_H320CODING         = 0x00000002,
+	HAL_H263_PROFILE_BACKWARDCOMPATIBLE = 0x00000004,
+	HAL_H263_PROFILE_ISWV2              = 0x00000008,
+	HAL_H263_PROFILE_ISWV3              = 0x00000010,
+	HAL_H263_PROFILE_HIGHCOMPRESSION    = 0x00000020,
+	HAL_H263_PROFILE_INTERNET           = 0x00000040,
+	HAL_H263_PROFILE_INTERLACE          = 0x00000080,
+	HAL_H263_PROFILE_HIGHLATENCY        = 0x00000100,
+	HAL_UNUSED_H263_PROFILE = 0x10000000,
+};
+
+enum hal_h263_level {
+	HAL_H263_LEVEL_10 = 0x00000001,
+	HAL_H263_LEVEL_20 = 0x00000002,
+	HAL_H263_LEVEL_30 = 0x00000004,
+	HAL_H263_LEVEL_40 = 0x00000008,
+	HAL_H263_LEVEL_45 = 0x00000010,
+	HAL_H263_LEVEL_50 = 0x00000020,
+	HAL_H263_LEVEL_60 = 0x00000040,
+	HAL_H263_LEVEL_70 = 0x00000080,
+	HAL_UNUSED_H263_LEVEL = 0x10000000,
+};
+
+enum hal_mpeg2_profile {
+	HAL_MPEG2_PROFILE_SIMPLE  = 0x00000001,
+	HAL_MPEG2_PROFILE_MAIN    = 0x00000002,
+	HAL_MPEG2_PROFILE_422     = 0x00000004,
+	HAL_MPEG2_PROFILE_SNR     = 0x00000008,
+	HAL_MPEG2_PROFILE_SPATIAL = 0x00000010,
+	HAL_MPEG2_PROFILE_HIGH    = 0x00000020,
+	HAL_UNUSED_MPEG2_PROFILE = 0x10000000,
+};
+
+enum hal_mpeg2_level {
+	HAL_MPEG2_LEVEL_LL  = 0x00000001,
+	HAL_MPEG2_LEVEL_ML  = 0x00000002,
+	HAL_MPEG2_LEVEL_H14 = 0x00000004,
+	HAL_MPEG2_LEVEL_HL  = 0x00000008,
+	HAL_UNUSED_MEPG2_LEVEL = 0x10000000,
+};
+
+enum hal_mpeg4_profile {
+	HAL_MPEG4_PROFILE_SIMPLE           = 0x00000001,
+	HAL_MPEG4_PROFILE_ADVANCEDSIMPLE   = 0x00000002,
+	HAL_MPEG4_PROFILE_CORE             = 0x00000004,
+	HAL_MPEG4_PROFILE_MAIN             = 0x00000008,
+	HAL_MPEG4_PROFILE_NBIT             = 0x00000010,
+	HAL_MPEG4_PROFILE_SCALABLETEXTURE  = 0x00000020,
+	HAL_MPEG4_PROFILE_SIMPLEFACE       = 0x00000040,
+	HAL_MPEG4_PROFILE_SIMPLEFBA        = 0x00000080,
+	HAL_MPEG4_PROFILE_BASICANIMATED    = 0x00000100,
+	HAL_MPEG4_PROFILE_HYBRID           = 0x00000200,
+	HAL_MPEG4_PROFILE_ADVANCEDREALTIME = 0x00000400,
+	HAL_MPEG4_PROFILE_CORESCALABLE     = 0x00000800,
+	HAL_MPEG4_PROFILE_ADVANCEDCODING   = 0x00001000,
+	HAL_MPEG4_PROFILE_ADVANCEDCORE     = 0x00002000,
+	HAL_MPEG4_PROFILE_ADVANCEDSCALABLE = 0x00004000,
+	HAL_MPEG4_PROFILE_SIMPLESCALABLE   = 0x00008000,
+	HAL_UNUSED_MPEG4_PROFILE = 0x10000000,
+};
+
+enum hal_mpeg4_level {
+	HAL_MPEG4_LEVEL_0  = 0x00000001,
+	HAL_MPEG4_LEVEL_0b = 0x00000002,
+	HAL_MPEG4_LEVEL_1  = 0x00000004,
+	HAL_MPEG4_LEVEL_2  = 0x00000008,
+	HAL_MPEG4_LEVEL_3  = 0x00000010,
+	HAL_MPEG4_LEVEL_4  = 0x00000020,
+	HAL_MPEG4_LEVEL_4a = 0x00000040,
+	HAL_MPEG4_LEVEL_5  = 0x00000080,
+	HAL_MPEG4_LEVEL_VENDOR_START_UNUSED = 0x7F000000,
+	HAL_MPEG4_LEVEL_6  = 0x7F000001,
+	HAL_MPEG4_LEVEL_7  = 0x7F000002,
+	HAL_MPEG4_LEVEL_8  = 0x7F000003,
+	HAL_MPEG4_LEVEL_9  = 0x7F000004,
+	HAL_MPEG4_LEVEL_3b = 0x7F000005,
+	HAL_UNUSED_MPEG4_LEVEL = 0x10000000,
+};
+
+enum hal_h264_profile {
+	HAL_H264_PROFILE_BASELINE = 0x00000001,
+	HAL_H264_PROFILE_MAIN     = 0x00000002,
+	HAL_H264_PROFILE_HIGH     = 0x00000004,
+	HAL_H264_PROFILE_EXTENDED = 0x00000008,
+	HAL_H264_PROFILE_HIGH10   = 0x00000010,
+	HAL_H264_PROFILE_HIGH422  = 0x00000020,
+	HAL_H264_PROFILE_HIGH444  = 0x00000040,
+	HAL_H264_PROFILE_CONSTRAINED_HIGH  = 0x00000080,
+	HAL_UNUSED_H264_PROFILE = 0x10000000,
+};
+
+enum hal_h264_level {
+	HAL_H264_LEVEL_1  = 0x00000001,
+	HAL_H264_LEVEL_1b = 0x00000002,
+	HAL_H264_LEVEL_11 = 0x00000004,
+	HAL_H264_LEVEL_12 = 0x00000008,
+	HAL_H264_LEVEL_13 = 0x00000010,
+	HAL_H264_LEVEL_2  = 0x00000020,
+	HAL_H264_LEVEL_21 = 0x00000040,
+	HAL_H264_LEVEL_22 = 0x00000080,
+	HAL_H264_LEVEL_3  = 0x00000100,
+	HAL_H264_LEVEL_31 = 0x00000200,
+	HAL_H264_LEVEL_32 = 0x00000400,
+	HAL_H264_LEVEL_4  = 0x00000800,
+	HAL_H264_LEVEL_41 = 0x00001000,
+	HAL_H264_LEVEL_42 = 0x00002000,
+	HAL_H264_LEVEL_5  = 0x00004000,
+	HAL_H264_LEVEL_51 = 0x00008000,
+	HAL_UNUSED_H264_LEVEL = 0x10000000,
+};
+
+enum hal_vpx_profile {
+	HAL_VPX_PROFILE_SIMPLE    = 0x00000001,
+	HAL_VPX_PROFILE_ADVANCED  = 0x00000002,
+	HAL_VPX_PROFILE_VERSION_0 = 0x00000004,
+	HAL_VPX_PROFILE_VERSION_1 = 0x00000008,
+	HAL_VPX_PROFILE_VERSION_2 = 0x00000010,
+	HAL_VPX_PROFILE_VERSION_3 = 0x00000020,
+	HAL_VPX_PROFILE_UNUSED = 0x10000000,
+};
+
+enum hal_vc1_profile {
+	HAL_VC1_PROFILE_SIMPLE   = 0x00000001,
+	HAL_VC1_PROFILE_MAIN     = 0x00000002,
+	HAL_VC1_PROFILE_ADVANCED = 0x00000004,
+	HAL_UNUSED_VC1_PROFILE = 0x10000000,
+};
+
+enum hal_vc1_level {
+	HAL_VC1_LEVEL_LOW    = 0x00000001,
+	HAL_VC1_LEVEL_MEDIUM = 0x00000002,
+	HAL_VC1_LEVEL_HIGH   = 0x00000004,
+	HAL_VC1_LEVEL_0      = 0x00000008,
+	HAL_VC1_LEVEL_1      = 0x00000010,
+	HAL_VC1_LEVEL_2      = 0x00000020,
+	HAL_VC1_LEVEL_3      = 0x00000040,
+	HAL_VC1_LEVEL_4      = 0x00000080,
+	HAL_UNUSED_VC1_LEVEL = 0x10000000,
+};
+
+enum hal_divx_format {
+	HAL_DIVX_FORMAT_4,
+	HAL_DIVX_FORMAT_5,
+	HAL_DIVX_FORMAT_6,
+	HAL_UNUSED_DIVX_FORMAT = 0x10000000,
+};
+
+enum hal_divx_profile {
+	HAL_DIVX_PROFILE_QMOBILE  = 0x00000001,
+	HAL_DIVX_PROFILE_MOBILE   = 0x00000002,
+	HAL_DIVX_PROFILE_MT       = 0x00000004,
+	HAL_DIVX_PROFILE_HT       = 0x00000008,
+	HAL_DIVX_PROFILE_HD       = 0x00000010,
+	HAL_UNUSED_DIVX_PROFILE = 0x10000000,
+};
+
+enum hal_mvc_profile {
+	HAL_MVC_PROFILE_STEREO_HIGH  = 0x00000001,
+	HAL_MVC_PROFILE_MV_HIGH      = 0x00000002,
+	HAL_UNUSED_MVC_PROFILE = 0x10000000,
+};
+
+enum hal_mvc_level {
+	HAL_MVC_LEVEL_1  = 0x00000001,
+	HAL_MVC_LEVEL_1b = 0x00000002,
+	HAL_MVC_LEVEL_11 = 0x00000004,
+	HAL_MVC_LEVEL_12 = 0x00000008,
+	HAL_MVC_LEVEL_13 = 0x00000010,
+	HAL_MVC_LEVEL_2  = 0x00000020,
+	HAL_MVC_LEVEL_21 = 0x00000040,
+	HAL_MVC_LEVEL_22 = 0x00000080,
+	HAL_MVC_LEVEL_3  = 0x00000100,
+	HAL_MVC_LEVEL_31 = 0x00000200,
+	HAL_MVC_LEVEL_32 = 0x00000400,
+	HAL_MVC_LEVEL_4  = 0x00000800,
+	HAL_MVC_LEVEL_41 = 0x00001000,
+	HAL_MVC_LEVEL_42 = 0x00002000,
+	HAL_MVC_LEVEL_5  = 0x00004000,
+	HAL_MVC_LEVEL_51 = 0x00008000,
+	HAL_UNUSED_MVC_LEVEL = 0x10000000,
+};
+
+enum hal_buffer {
+	HAL_BUFFER_INPUT,
+	HAL_BUFFER_OUTPUT,
+	HAL_BUFFER_OUTPUT2,
+	HAL_BUFFER_EXTRADATA_INPUT,
+	HAL_BUFFER_EXTRADATA_OUTPUT,
+	HAL_BUFFER_EXTRADATA_OUTPUT2,
+	HAL_BUFFER_INTERNAL_SCRATCH,
+	HAL_BUFFER_INTERNAL_SCRATCH_1,
+	HAL_BUFFER_INTERNAL_SCRATCH_2,
+	HAL_BUFFER_INTERNAL_PERSIST,
+	HAL_BUFFER_INTERNAL_PERSIST_1,
+	HAL_BUFFER_MAX
+};
+
+struct hal_frame_rate {
+	enum hal_buffer buffer_type;
+	u32 frame_rate;
+};
+
+enum hal_uncompressed_format {
+	HAL_COLOR_FORMAT_MONOCHROME,
+	HAL_COLOR_FORMAT_NV12,
+	HAL_COLOR_FORMAT_NV21,
+	HAL_COLOR_FORMAT_NV12_4x4TILE,
+	HAL_COLOR_FORMAT_NV21_4x4TILE,
+	HAL_COLOR_FORMAT_YUYV,
+	HAL_COLOR_FORMAT_YVYU,
+	HAL_COLOR_FORMAT_UYVY,
+	HAL_COLOR_FORMAT_VYUY,
+	HAL_COLOR_FORMAT_RGB565,
+	HAL_COLOR_FORMAT_BGR565,
+	HAL_COLOR_FORMAT_RGB888,
+	HAL_COLOR_FORMAT_BGR888,
+	HAL_UNUSED_COLOR = 0x10000000,
+};
+
+enum hal_ssr_trigger_type {
+	SSR_ERR_FATAL = 1,
+	SSR_SW_DIV_BY_ZERO,
+	SSR_HW_WDOG_IRQ,
+};
+
+struct hal_uncompressed_format_select {
+	enum hal_buffer buffer_type;
+	enum hal_uncompressed_format format;
+};
+
+struct hal_uncompressed_plane_actual {
+	int actual_stride;
+	u32 actual_plane_buffer_height;
+};
+
+struct hal_uncompressed_plane_actual_info {
+	enum hal_buffer buffer_type;
+	u32 num_planes;
+	struct hal_uncompressed_plane_actual rg_plane_format[1];
+};
+
+struct hal_uncompressed_plane_constraints {
+	u32 stride_multiples;
+	u32 max_stride;
+	u32 min_plane_buffer_height_multiple;
+	u32 buffer_alignment;
+};
+
+struct hal_uncompressed_plane_actual_constraints_info {
+	enum hal_buffer buffer_type;
+	u32 num_planes;
+	struct hal_uncompressed_plane_constraints rg_plane_format[1];
+};
+
+struct hal_extra_data_header_config {
+	u32 type;
+	enum hal_buffer buffer_type;
+	u32 version;
+	u32 port_index;
+	u32 client_extradata_id;
+};
+
+struct hal_frame_size {
+	enum hal_buffer buffer_type;
+	u32 width;
+	u32 height;
+};
+
+struct hal_enable {
+	u32 enable;
+};
+
+struct hal_buffer_count_actual {
+	enum hal_buffer buffer_type;
+	u32 buffer_count_actual;
+};
+
+enum hal_nal_stream_format {
+	HAL_NAL_FORMAT_STARTCODES         = 0x00000001,
+	HAL_NAL_FORMAT_ONE_NAL_PER_BUFFER = 0x00000002,
+	HAL_NAL_FORMAT_ONE_BYTE_LENGTH    = 0x00000004,
+	HAL_NAL_FORMAT_TWO_BYTE_LENGTH    = 0x00000008,
+	HAL_NAL_FORMAT_FOUR_BYTE_LENGTH   = 0x00000010,
+};
+
+enum hal_output_order {
+	HAL_OUTPUT_ORDER_DISPLAY,
+	HAL_OUTPUT_ORDER_DECODE,
+	HAL_UNUSED_OUTPUT = 0x10000000,
+};
+
+enum hal_picture {
+	HAL_PICTURE_I = 0x01,
+	HAL_PICTURE_P = 0x02,
+	HAL_PICTURE_B = 0x04,
+	HAL_PICTURE_IDR = 0x7F001000,
+	HAL_FRAME_NOTCODED = 0x7F002000,
+	HAL_FRAME_YUV = 0x7F004000,
+	HAL_UNUSED_PICT = 0x10000000,
+};
+
+struct hal_extradata_enable {
+	u32 enable;
+	enum hal_extradata_id index;
+};
+
+struct hal_enable_picture {
+	u32 picture_type;
+};
+
+struct hal_multi_stream {
+	enum hal_buffer buffer_type;
+	u32 enable;
+	u32 width;
+	u32 height;
+};
+
+struct hal_display_picture_buffer_count {
+	u32 enable;
+	u32 count;
+};
+
+struct hal_mb_error_map {
+	u32 error_map_size;
+	u8 rg_error_map[1];
+};
+
+struct hal_request_iframe {
+	u32 enable;
+};
+
+struct hal_bitrate {
+	u32 bit_rate;
+	u32 layer_id;
+};
+
+struct hal_profile_level {
+	u32 profile;
+	u32 level;
+};
+/*
+struct hal_profile_level_range {
+	u32 profile;
+	u32 min_level;
+	u32 max_level;
+}
+
+struct hal_profile_level_supported {
+	u32 profile_count;
+	struct hal_profile_level_range profile_level[1];
+};
+*/
+enum hal_h264_entropy {
+	HAL_H264_ENTROPY_CAVLC,
+	HAL_H264_ENTROPY_CABAC,
+	HAL_UNUSED_ENTROPY = 0x10000000,
+};
+
+enum hal_h264_cabac_model {
+	HAL_H264_CABAC_MODEL_0,
+	HAL_H264_CABAC_MODEL_1,
+	HAL_H264_CABAC_MODEL_2,
+	HAL_UNUSED_CABAC = 0x10000000,
+};
+
+struct hal_h264_entropy_control {
+	enum hal_h264_entropy entropy_mode;
+	enum hal_h264_cabac_model cabac_model;
+};
+
+enum hal_rate_control {
+	HAL_RATE_CONTROL_OFF,
+	HAL_RATE_CONTROL_VBR_VFR,
+	HAL_RATE_CONTROL_VBR_CFR,
+	HAL_RATE_CONTROL_CBR_VFR,
+	HAL_RATE_CONTROL_CBR_CFR,
+	HAL_UNUSED_RC = 0x10000000,
+};
+
+struct hal_mpeg4_time_resolution {
+	u32 time_increment_resolution;
+};
+
+struct hal_mpeg4_header_extension {
+	u32 header_extension;
+};
+
+enum hal_h264_db_mode {
+	HAL_H264_DB_MODE_DISABLE,
+	HAL_H264_DB_MODE_SKIP_SLICE_BOUNDARY,
+	HAL_H264_DB_MODE_ALL_BOUNDARY,
+	HAL_UNUSED_H264_DB = 0x10000000,
+};
+
+struct hal_h264_db_control {
+	enum hal_h264_db_mode mode;
+	int slice_alpha_offset;
+	int slice_beta_offset;
+};
+
+struct hal_temporal_spatial_tradeoff {
+	u32 ts_factor;
+};
+
+struct hal_quantization {
+	u32 qpi;
+	u32 qpp;
+	u32 qpb;
+	u32 layer_id;
+};
+
+struct hal_intra_period {
+	u32 pframes;
+	u32 bframes;
+};
+
+struct hal_idr_period {
+	u32 idr_period;
+};
+
+enum hal_rotate {
+	HAL_ROTATE_NONE,
+	HAL_ROTATE_90,
+	HAL_ROTATE_180,
+	HAL_ROTATE_270,
+	HAL_UNUSED_ROTATE = 0x10000000,
+};
+
+enum hal_flip {
+	HAL_FLIP_NONE,
+	HAL_FLIP_HORIZONTAL,
+	HAL_FLIP_VERTICAL,
+	HAL_UNUSED_FLIP = 0x10000000,
+};
+
+struct hal_operations {
+	enum hal_rotate rotate;
+	enum hal_flip flip;
+};
+
+enum hal_intra_refresh_mode {
+	HAL_INTRA_REFRESH_NONE,
+	HAL_INTRA_REFRESH_CYCLIC,
+	HAL_INTRA_REFRESH_ADAPTIVE,
+	HAL_INTRA_REFRESH_CYCLIC_ADAPTIVE,
+	HAL_INTRA_REFRESH_RANDOM,
+	HAL_UNUSED_INTRA = 0x10000000,
+};
+
+struct hal_intra_refresh {
+	enum hal_intra_refresh_mode mode;
+	u32 air_mbs;
+	u32 air_ref;
+	u32 cir_mbs;
+};
+
+enum hal_multi_slice {
+	HAL_MULTI_SLICE_OFF,
+	HAL_MULTI_SLICE_BY_MB_COUNT,
+	HAL_MULTI_SLICE_BY_BYTE_COUNT,
+	HAL_MULTI_SLICE_GOB,
+	HAL_UNUSED_SLICE = 0x10000000,
+};
+
+struct hal_multi_slice_control {
+	enum hal_multi_slice multi_slice;
+	u32 slice_size;
+};
+
+struct hal_debug_config {
+	u32 debug_config;
+};
+
+struct hal_buffer_requirements {
+	enum hal_buffer buffer_type;
+	u32 buffer_size;
+	u32 buffer_region_size;
+	u32 buffer_hold_count;
+	u32 buffer_count_min;
+	u32 buffer_count_actual;
+	u32 contiguous;
+	u32 buffer_alignment;
+};
+
+enum hal_priority {/* Priority increases with number */
+	HAL_PRIORITY_LOW = 10,
+	HAL_PRIOIRTY_MEDIUM = 20,
+	HAL_PRIORITY_HIGH = 30,
+	HAL_UNUSED_PRIORITY = 0x10000000,
+};
+
+struct hal_batch_info {
+	u32 input_batch_count;
+	u32 output_batch_count;
+};
+
+struct hal_metadata_pass_through {
+	u32 enable;
+	u32 size;
+};
+
+struct hal_uncompressed_format_supported {
+	enum hal_buffer buffer_type;
+	u32 format_entries;
+	u32 rg_format_info[1];
+};
+
+enum hal_interlace_format {
+	HAL_INTERLACE_FRAME_PROGRESSIVE                 = 0x01,
+	HAL_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST    = 0x02,
+	HAL_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST = 0x04,
+	HAL_INTERLACE_FRAME_TOPFIELDFIRST               = 0x08,
+	HAL_INTERLACE_FRAME_BOTTOMFIELDFIRST            = 0x10,
+	HAL_UNUSED_INTERLACE = 0x10000000,
+};
+
+struct hal_interlace_format_supported {
+	enum hal_buffer buffer_type;
+	enum hal_interlace_format format;
+};
+
+enum hal_chroma_site {
+	HAL_CHROMA_SITE_0,
+	HAL_CHROMA_SITE_1,
+	HAL_UNUSED_CHROMA = 0x10000000,
+};
+
+struct hal_properties_supported {
+	u32 num_properties;
+	u32 rg_properties[1];
+};
+
+enum hal_capability {
+	HAL_CAPABILITY_FRAME_WIDTH,
+	HAL_CAPABILITY_FRAME_HEIGHT,
+	HAL_CAPABILITY_MBS_PER_FRAME,
+	HAL_CAPABILITY_MBS_PER_SECOND,
+	HAL_CAPABILITY_FRAMERATE,
+	HAL_CAPABILITY_SCALE_X,
+	HAL_CAPABILITY_SCALE_Y,
+	HAL_CAPABILITY_BITRATE,
+	HAL_UNUSED_CAPABILITY = 0x10000000,
+};
+
+struct hal_capability_supported {
+	enum hal_capability capability_type;
+	u32 min;
+	u32 max;
+	u32 step_size;
+};
+
+struct hal_capability_supported_info {
+	u32 num_capabilities;
+	struct hal_capability_supported rg_data[1];
+};
+
+struct hal_nal_stream_format_supported {
+	u32 nal_stream_format_supported;
+};
+
+struct hal_multi_view_format {
+	u32 views;
+	u32 rg_view_order[1];
+};
+
+struct hal_seq_header_info {
+	u32 nax_header_len;
+};
+
+struct hal_codec_supported {
+	u32 decoder_codec_supported;
+	u32 encoder_codec_supported;
+};
+
+struct hal_multi_view_select {
+	u32 view_index;
+};
+
+struct hal_timestamp_scale {
+	u32 time_stamp_scale;
+};
+
+enum vidc_resource_id {
+	VIDC_RESOURCE_OCMEM = 0x00000001,
+	VIDC_UNUSED_RESORUCE = 0x10000000,
+};
+
+struct vidc_resource_hdr {
+	enum vidc_resource_id resource_id;
+	u32 resource_handle;
+	u32 size;
+};
+
+struct vidc_buffer_addr_info {
+	enum hal_buffer buffer_type;
+	u32 buffer_size;
+	u32 num_buffers;
+	u32 align_device_addr;
+	u32 extradata_size;
+	u32 extradata_addr;
+	u32 response_required;
+};
+
+struct hal_buffer_info {
+	u32 buffer_addr;
+	u32 extra_data_addr;
+};
+
+struct vidc_frame_plane_config {
+	u32 left;
+	u32 top;
+	u32 width;
+	u32 height;
+	u32 stride;
+	u32 scan_lines;
+};
+
+struct vidc_uncompressed_frame_config {
+	struct vidc_frame_plane_config luma_plane;
+	struct vidc_frame_plane_config chroma_plane;
+};
+
+struct vidc_frame_data {
+	enum hal_buffer buffer_type;
+	u32 device_addr;
+	u32 extradata_addr;
+	int64_t timestamp;
+	u32 flags;
+	u32 offset;
+	u32 alloc_len;
+	u32 filled_len;
+	u32 mark_target;
+	u32 mark_data;
+	u32 clnt_data;
+};
+
+struct vidc_seq_hdr {
+	u8 *seq_hdr;
+	u32 seq_hdr_len;
+};
+
+enum hal_flush {
+	HAL_FLUSH_INPUT,
+	HAL_FLUSH_OUTPUT,
+	HAL_FLUSH_OUTPUT2,
+	HAL_FLUSH_ALL,
+	HAL_UNUSED_FLUSH = 0x10000000,
+};
+
+enum hal_event_type {
+	HAL_EVENT_SEQ_CHANGED_SUFFICIENT_RESOURCES,
+	HAL_EVENT_SEQ_CHANGED_INSUFFICIENT_RESOURCES,
+	HAL_UNUSED_SEQCHG = 0x10000000,
+};
+
+/* HAL Response */
+
+enum command_response {
+/* SYSTEM COMMANDS_DONE*/
+	VIDC_EVENT_CHANGE,
+	SYS_INIT_DONE,
+	SET_RESOURCE_DONE,
+	RELEASE_RESOURCE_DONE,
+	PING_ACK_DONE,
+	PC_PREP_DONE,
+	SYS_IDLE,
+	SYS_DEBUG,
+	SYS_WATCHDOG_TIMEOUT,
+	SYS_ERROR,
+/* SESSION COMMANDS_DONE */
+	SESSION_LOAD_RESOURCE_DONE,
+	SESSION_INIT_DONE,
+	SESSION_END_DONE,
+	SESSION_ABORT_DONE,
+	SESSION_START_DONE,
+	SESSION_STOP_DONE,
+	SESSION_ETB_DONE,
+	SESSION_FTB_DONE,
+	SESSION_FLUSH_DONE,
+	SESSION_SUSPEND_DONE,
+	SESSION_RESUME_DONE,
+	SESSION_SET_PROP_DONE,
+	SESSION_GET_PROP_DONE,
+	SESSION_PARSE_SEQ_HDR_DONE,
+	SESSION_GET_SEQ_HDR_DONE,
+	SESSION_RELEASE_BUFFER_DONE,
+	SESSION_RELEASE_RESOURCE_DONE,
+	SESSION_PROPERTY_INFO,
+	SESSION_ERROR,
+	RESPONSE_UNUSED = 0x10000000,
+};
+
+/* Command Callback structure */
+
+struct msm_vidc_cb_cmd_done {
+	u32 device_id;
+	u32 session_id;
+	u32 status;
+	u32 size;
+	void *data;
+};
+
+struct msm_vidc_cb_event {
+	u32 device_id;
+	u32 session_id;
+	u32 status;
+	u32 height;
+	u32 width;
+	u32 hal_event_type;
+};
+
+/* Data callback structure */
+
+struct vidc_hal_ebd {
+	u32 timestamp_hi;
+	u32 timestamp_lo;
+	u32 flags;
+	u32 mark_target;
+	u32 mark_data;
+	u32 stats;
+	u32 offset;
+	u32 alloc_len;
+	u32 filled_len;
+	enum hal_picture picture_type;
+	u8 *packet_buffer;
+	u8 *extra_data_buffer;
+};
+
+struct vidc_hal_fbd {
+	u32 stream_id;
+	u32 view_id;
+	u32 timestamp_hi;
+	u32 timestamp_lo;
+	u32 flags1;
+	u32 mark_target;
+	u32 mark_data;
+	u32 stats;
+	u32 alloc_len1;
+	u32 filled_len1;
+	u32 offset1;
+	u32 frame_width;
+	u32 frame_height;
+	u32 start_x_coord;
+	u32 start_y_coord;
+	u32 input_tag;
+	u32 input_tag1;
+	enum hal_picture picture_type;
+	u8 *packet_buffer1;
+	u8 *extra_data_buffer;
+	u32 flags2;
+	u32 alloc_len2;
+	u32 filled_len2;
+	u32 offset2;
+	u8 *packet_buffer2;
+	u32 flags3;
+	u32 alloc_len3;
+	u32 filled_len3;
+	u32 offset3;
+	u8 *packet_buffer3;
+	enum hal_buffer buffer_type;
+};
+
+struct msm_vidc_cb_data_done {
+	u32 device_id;
+	u32 session_id;
+	u32 status;
+	u32 size;
+	void *clnt_data;
+	union {
+		struct vidc_hal_ebd input_done;
+		struct vidc_hal_fbd output_done;
+	};
+};
+
+struct vidc_hal_sys_init_done {
+	u32 enc_codec_supported;
+	u32 dec_codec_supported;
+};
+
+struct vidc_hal_session_init_done {
+	struct hal_capability_supported width;
+	struct hal_capability_supported height;
+	struct hal_capability_supported mbs_per_frame;
+	struct hal_capability_supported mbs_per_sec;
+	struct hal_capability_supported frame_rate;
+	struct hal_capability_supported scale_x;
+	struct hal_capability_supported scale_y;
+	struct hal_capability_supported bitrate;
+	struct hal_uncompressed_format_supported uncomp_format;
+	struct hal_interlace_format_supported HAL_format;
+	struct hal_nal_stream_format_supported nal_stream_format;
+/*	struct hal_profile_level_supported profile_level;
+	// allocate and released memory for above. */
+	struct hal_intra_refresh intra_refresh;
+	struct hal_seq_header_info seq_hdr_info;
+};
+
+struct buffer_requirements {
+	struct hal_buffer_requirements buffer[HAL_BUFFER_MAX];
+};
+
+enum msm_vidc_hfi_type {
+	VIDC_HFI_VENUS,
+	VIDC_HFI_Q6,
+};
+
+enum mem_type {
+	DDR_MEM = 0x1,
+	OCMEM_MEM = 0x2,
+};
+
+enum fw_info {
+	FW_BASE_ADDRESS,
+	FW_REGISTER_BASE,
+	FW_REGISTER_SIZE,
+	FW_IRQ,
+	FW_INFO_MAX,
+};
+
+#define call_hfi_op(q, op, args...)			\
+	(((q)->op) ? ((q)->op(args)) : 0)
+
+struct hfi_device {
+	void *hfi_device_data;
+
+	/*Add function pointers for all the hfi functions below*/
+	int (*core_init)(void *device);
+	int (*core_release)(void *device);
+	int (*core_pc_prep)(void *device);
+	int (*core_ping)(void *device);
+	int (*core_trigger_ssr)(void *device, enum hal_ssr_trigger_type);
+	void *(*session_init)(void *device, u32 session_id,
+		enum hal_domain session_type, enum hal_video_codec codec_type);
+	int (*session_end)(void *session);
+	int (*session_abort)(void *session);
+	int (*session_set_buffers)(void *sess,
+				struct vidc_buffer_addr_info *buffer_info);
+	int (*session_release_buffers)(void *sess,
+				struct vidc_buffer_addr_info *buffer_info);
+	int (*session_load_res)(void *sess);
+	int (*session_release_res)(void *sess);
+	int (*session_start)(void *sess);
+	int (*session_stop)(void *sess);
+	int (*session_suspend)(void *sess);
+	int (*session_resume)(void *sess);
+	int (*session_etb)(void *sess,
+			struct vidc_frame_data *input_frame);
+	int (*session_ftb)(void *sess,
+			struct vidc_frame_data *output_frame);
+	int (*session_parse_seq_hdr)(void *sess,
+			struct vidc_seq_hdr *seq_hdr);
+	int (*session_get_seq_hdr)(void *sess,
+			struct vidc_seq_hdr *seq_hdr);
+	int (*session_get_buf_req)(void *sess);
+	int (*session_flush)(void *sess, enum hal_flush flush_mode);
+	int (*session_set_property)(void *sess, enum hal_property ptype,
+			void *pdata);
+	int (*session_get_property)(void *sess, enum hal_property ptype,
+			void *pdata);
+	int (*scale_clocks)(void *dev, int load);
+	int (*scale_bus)(void *dev, int load,
+			enum session_type type, enum mem_type mtype);
+	int (*unvote_bus)(void *dev, enum session_type type,
+		enum mem_type mtype);
+	int (*unset_ocmem)(void *dev);
+	int (*alloc_ocmem)(void *dev, unsigned long size);
+	int (*free_ocmem)(void *dev);
+	int (*is_ocmem_present)(void *dev);
+	int (*get_domain)(void *dev, enum msm_vidc_io_maps iomap);
+	int (*iommu_get_map)(void *dev,
+			struct msm_vidc_iommu_info maps[MAX_MAP]);
+	int (*load_fw)(void *dev);
+	void (*unload_fw)(void *dev);
+	int (*get_fw_info)(void *dev, enum fw_info info);
+	int (*get_stride_scanline)(int color_fmt, int width,
+		int height,	int *stride, int *scanlines);
+};
+
+typedef void (*hfi_cmd_response_callback) (enum command_response cmd,
+			void *data);
+typedef void (*msm_vidc_callback) (u32 response, void *callback);
+
+void *vidc_hfi_initialize(enum msm_vidc_hfi_type hfi_type, u32 device_id,
+			struct msm_vidc_platform_resources *res,
+			hfi_cmd_response_callback callback);
+void vidc_hfi_deinitialize(enum msm_vidc_hfi_type hfi_type,
+			struct hfi_device *hdev);
+
+
+#endif /*__VIDC_HFI_API_H__ */
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
new file mode 100644
index 0000000..01c5e0b
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
@@ -0,0 +1,886 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __H_VIDC_HFI_HELPER_H__
+#define __H_VIDC_HFI_HELPER_H__
+
+#define HFI_COMMON_BASE				(0)
+#define HFI_OX_BASE					(0x01000000)
+
+#define HFI_VIDEO_DOMAIN_ENCODER	(HFI_COMMON_BASE + 0x1)
+#define HFI_VIDEO_DOMAIN_DECODER	(HFI_COMMON_BASE + 0x2)
+#define HFI_VIDEO_DOMAIN_VPE		(HFI_COMMON_BASE + 0x4)
+#define HFI_VIDEO_DOMAIN_MBI		(HFI_COMMON_BASE + 0x8)
+
+#define HFI_DOMAIN_BASE_COMMON		(HFI_COMMON_BASE + 0)
+#define HFI_DOMAIN_BASE_VDEC		(HFI_COMMON_BASE + 0x01000000)
+#define HFI_DOMAIN_BASE_VENC		(HFI_COMMON_BASE + 0x02000000)
+#define HFI_DOMAIN_BASE_VPE			(HFI_COMMON_BASE + 0x03000000)
+
+#define HFI_VIDEO_ARCH_OX			(HFI_COMMON_BASE + 0x1)
+
+#define HFI_ARCH_COMMON_OFFSET		(0)
+#define HFI_ARCH_OX_OFFSET			(0x00200000)
+
+#define  HFI_CMD_START_OFFSET		(0x00010000)
+#define  HFI_MSG_START_OFFSET		(0x00020000)
+
+#define HFI_ERR_NONE						HFI_COMMON_BASE
+#define HFI_ERR_SYS_FATAL				(HFI_COMMON_BASE + 0x1)
+#define HFI_ERR_SYS_INVALID_PARAMETER		(HFI_COMMON_BASE + 0x2)
+#define HFI_ERR_SYS_VERSION_MISMATCH		(HFI_COMMON_BASE + 0x3)
+#define HFI_ERR_SYS_INSUFFICIENT_RESOURCES	(HFI_COMMON_BASE + 0x4)
+#define HFI_ERR_SYS_MAX_SESSIONS_REACHED	(HFI_COMMON_BASE + 0x5)
+#define HFI_ERR_SYS_UNSUPPORTED_CODEC		(HFI_COMMON_BASE + 0x6)
+#define HFI_ERR_SYS_SESSION_IN_USE			(HFI_COMMON_BASE + 0x7)
+#define HFI_ERR_SYS_SESSION_ID_OUT_OF_RANGE	(HFI_COMMON_BASE + 0x8)
+#define HFI_ERR_SYS_UNSUPPORTED_DOMAIN		(HFI_COMMON_BASE + 0x9)
+
+#define HFI_ERR_SESSION_FATAL			(HFI_COMMON_BASE + 0x1001)
+#define HFI_ERR_SESSION_INVALID_PARAMETER	(HFI_COMMON_BASE + 0x1002)
+#define HFI_ERR_SESSION_BAD_POINTER		(HFI_COMMON_BASE + 0x1003)
+#define HFI_ERR_SESSION_INVALID_SESSION_ID	(HFI_COMMON_BASE + 0x1004)
+#define HFI_ERR_SESSION_INVALID_STREAM_ID	(HFI_COMMON_BASE + 0x1005)
+#define HFI_ERR_SESSION_INCORRECT_STATE_OPERATION		\
+	(HFI_COMMON_BASE + 0x1006)
+#define HFI_ERR_SESSION_UNSUPPORTED_PROPERTY	(HFI_COMMON_BASE + 0x1007)
+
+#define HFI_ERR_SESSION_UNSUPPORTED_SETTING	(HFI_COMMON_BASE + 0x1008)
+
+#define HFI_ERR_SESSION_INSUFFICIENT_RESOURCES	(HFI_COMMON_BASE + 0x1009)
+
+#define HFI_ERR_SESSION_STREAM_CORRUPT_OUTPUT_STALLED	\
+	(HFI_COMMON_BASE + 0x100A)
+
+#define HFI_ERR_SESSION_STREAM_CORRUPT		(HFI_COMMON_BASE + 0x100B)
+#define HFI_ERR_SESSION_ENC_OVERFLOW		(HFI_COMMON_BASE + 0x100C)
+#define  HFI_ERR_SESSION_UNSUPPORTED_STREAM	(HFI_COMMON_BASE + 0x100D)
+
+#define HFI_EVENT_SYS_ERROR				(HFI_COMMON_BASE + 0x1)
+#define HFI_EVENT_SESSION_ERROR			(HFI_COMMON_BASE + 0x2)
+
+#define HFI_VIDEO_CODEC_H264				0x00000002
+#define HFI_VIDEO_CODEC_H263				0x00000004
+#define HFI_VIDEO_CODEC_MPEG1				0x00000008
+#define HFI_VIDEO_CODEC_MPEG2				0x00000010
+#define HFI_VIDEO_CODEC_MPEG4				0x00000020
+#define HFI_VIDEO_CODEC_DIVX_311			0x00000040
+#define HFI_VIDEO_CODEC_DIVX				0x00000080
+#define HFI_VIDEO_CODEC_VC1					0x00000100
+#define HFI_VIDEO_CODEC_SPARK				0x00000200
+#define HFI_VIDEO_CODEC_VP8					0x00001000
+
+#define HFI_H264_PROFILE_BASELINE			0x00000001
+#define HFI_H264_PROFILE_MAIN				0x00000002
+#define HFI_H264_PROFILE_HIGH				0x00000004
+#define HFI_H264_PROFILE_STEREO_HIGH		0x00000008
+#define HFI_H264_PROFILE_MULTIVIEW_HIGH		0x00000010
+#define HFI_H264_PROFILE_CONSTRAINED_BASE	0x00000020
+#define HFI_H264_PROFILE_CONSTRAINED_HIGH	0x00000040
+
+#define HFI_H264_LEVEL_1					0x00000001
+#define HFI_H264_LEVEL_1b					0x00000002
+#define HFI_H264_LEVEL_11					0x00000004
+#define HFI_H264_LEVEL_12					0x00000008
+#define HFI_H264_LEVEL_13					0x00000010
+#define HFI_H264_LEVEL_2					0x00000020
+#define HFI_H264_LEVEL_21					0x00000040
+#define HFI_H264_LEVEL_22					0x00000080
+#define HFI_H264_LEVEL_3					0x00000100
+#define HFI_H264_LEVEL_31					0x00000200
+#define HFI_H264_LEVEL_32					0x00000400
+#define HFI_H264_LEVEL_4					0x00000800
+#define HFI_H264_LEVEL_41					0x00001000
+#define HFI_H264_LEVEL_42					0x00002000
+#define HFI_H264_LEVEL_5					0x00004000
+#define HFI_H264_LEVEL_51					0x00008000
+
+#define HFI_H263_PROFILE_BASELINE			0x00000001
+
+#define HFI_H263_LEVEL_10					0x00000001
+#define HFI_H263_LEVEL_20					0x00000002
+#define HFI_H263_LEVEL_30					0x00000004
+#define HFI_H263_LEVEL_40					0x00000008
+#define HFI_H263_LEVEL_45					0x00000010
+#define HFI_H263_LEVEL_50					0x00000020
+#define HFI_H263_LEVEL_60					0x00000040
+#define HFI_H263_LEVEL_70					0x00000080
+
+#define HFI_MPEG2_PROFILE_SIMPLE			0x00000001
+#define HFI_MPEG2_PROFILE_MAIN				0x00000002
+#define HFI_MPEG2_PROFILE_422				0x00000004
+#define HFI_MPEG2_PROFILE_SNR				0x00000008
+#define HFI_MPEG2_PROFILE_SPATIAL			0x00000010
+#define HFI_MPEG2_PROFILE_HIGH				0x00000020
+
+#define HFI_MPEG2_LEVEL_LL					0x00000001
+#define HFI_MPEG2_LEVEL_ML					0x00000002
+#define HFI_MPEG2_LEVEL_H14					0x00000004
+#define HFI_MPEG2_LEVEL_HL					0x00000008
+
+#define HFI_MPEG4_PROFILE_SIMPLE			0x00000001
+#define HFI_MPEG4_PROFILE_ADVANCEDSIMPLE	0x00000002
+
+#define HFI_MPEG4_LEVEL_0					0x00000001
+#define HFI_MPEG4_LEVEL_0b					0x00000002
+#define HFI_MPEG4_LEVEL_1					0x00000004
+#define HFI_MPEG4_LEVEL_2					0x00000008
+#define HFI_MPEG4_LEVEL_3					0x00000010
+#define HFI_MPEG4_LEVEL_4					0x00000020
+#define HFI_MPEG4_LEVEL_4a					0x00000040
+#define HFI_MPEG4_LEVEL_5					0x00000080
+#define HFI_MPEG4_LEVEL_6					0x00000100
+#define HFI_MPEG4_LEVEL_7					0x00000200
+#define HFI_MPEG4_LEVEL_8					0x00000400
+#define HFI_MPEG4_LEVEL_9					0x00000800
+#define HFI_MPEG4_LEVEL_3b					0x00001000
+
+#define HFI_VC1_PROFILE_SIMPLE				0x00000001
+#define HFI_VC1_PROFILE_MAIN				0x00000002
+#define HFI_VC1_PROFILE_ADVANCED			0x00000004
+
+#define HFI_VC1_LEVEL_LOW					0x00000001
+#define HFI_VC1_LEVEL_MEDIUM				0x00000002
+#define HFI_VC1_LEVEL_HIGH					0x00000004
+#define HFI_VC1_LEVEL_0						0x00000008
+#define HFI_VC1_LEVEL_1						0x00000010
+#define HFI_VC1_LEVEL_2						0x00000020
+#define HFI_VC1_LEVEL_3						0x00000040
+#define HFI_VC1_LEVEL_4						0x00000080
+
+#define HFI_VPX_PROFILE_SIMPLE				0x00000001
+#define HFI_VPX_PROFILE_ADVANCED			0x00000002
+#define HFI_VPX_PROFILE_VERSION_0			0x00000004
+#define HFI_VPX_PROFILE_VERSION_1			0x00000008
+#define HFI_VPX_PROFILE_VERSION_2			0x00000010
+#define HFI_VPX_PROFILE_VERSION_3			0x00000020
+
+#define HFI_DIVX_FORMAT_4				(HFI_COMMON_BASE + 0x1)
+#define HFI_DIVX_FORMAT_5				(HFI_COMMON_BASE + 0x2)
+#define HFI_DIVX_FORMAT_6				(HFI_COMMON_BASE + 0x3)
+
+#define HFI_DIVX_PROFILE_QMOBILE		0x00000001
+#define HFI_DIVX_PROFILE_MOBILE			0x00000002
+#define HFI_DIVX_PROFILE_MT				0x00000004
+#define HFI_DIVX_PROFILE_HT				0x00000008
+#define HFI_DIVX_PROFILE_HD				0x00000010
+
+#define HFI_BUFFER_INPUT				(HFI_COMMON_BASE + 0x1)
+#define HFI_BUFFER_OUTPUT				(HFI_COMMON_BASE + 0x2)
+#define HFI_BUFFER_OUTPUT2				(HFI_COMMON_BASE + 0x3)
+#define HFI_BUFFER_INTERNAL_PERSIST		(HFI_COMMON_BASE + 0x4)
+#define HFI_BUFFER_INTERNAL_PERSIST_1		(HFI_COMMON_BASE + 0x5)
+
+struct hfi_buffer_info {
+	u32 buffer_addr;
+	u32 extra_data_addr;
+};
+
+#define HFI_PROPERTY_SYS_COMMON_START		\
+	(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET + 0x0000)
+#define HFI_PROPERTY_SYS_DEBUG_CONFIG		\
+	(HFI_PROPERTY_SYS_COMMON_START + 0x001)
+#define HFI_PROPERTY_SYS_RESOURCE_OCMEM_REQUIREMENT_INFO	\
+	(HFI_PROPERTY_SYS_COMMON_START + 0x002)
+#define HFI_PROPERTY_SYS_CONFIG_VCODEC_CLKFREQ				\
+	(HFI_PROPERTY_SYS_COMMON_START + 0x003)
+
+#define HFI_PROPERTY_PARAM_COMMON_START	\
+	(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET + 0x1000)
+#define HFI_PROPERTY_PARAM_FRAME_SIZE		\
+	(HFI_PROPERTY_PARAM_COMMON_START + 0x001)
+#define HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO	\
+	(HFI_PROPERTY_PARAM_COMMON_START + 0x002)
+#define HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT		\
+	(HFI_PROPERTY_PARAM_COMMON_START + 0x003)
+#define HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SUPPORTED	\
+	(HFI_PROPERTY_PARAM_COMMON_START + 0x004)
+#define HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT			\
+	(HFI_PROPERTY_PARAM_COMMON_START + 0x005)
+#define HFI_PROPERTY_PARAM_PROFILE_LEVEL_SUPPORTED			\
+	(HFI_PROPERTY_PARAM_COMMON_START + 0x006)
+#define HFI_PROPERTY_PARAM_CAPABILITY_SUPPORTED				\
+	(HFI_PROPERTY_PARAM_COMMON_START + 0x007)
+#define HFI_PROPERTY_PARAM_PROPERTIES_SUPPORTED				\
+	(HFI_PROPERTY_PARAM_COMMON_START + 0x008)
+#define HFI_PROPERTY_PARAM_CODEC_SUPPORTED			\
+	(HFI_PROPERTY_PARAM_COMMON_START + 0x009)
+#define HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SUPPORTED		\
+	(HFI_PROPERTY_PARAM_COMMON_START + 0x00A)
+#define HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SELECT			\
+	(HFI_PROPERTY_PARAM_COMMON_START + 0x00B)
+#define HFI_PROPERTY_PARAM_MULTI_VIEW_FORMAT				\
+	(HFI_PROPERTY_PARAM_COMMON_START + 0x00C)
+#define  HFI_PROPERTY_PARAM_MAX_SEQUENCE_HEADER_SIZE        \
+	(HFI_PROPERTY_PARAM_COMMON_START + 0x00D)
+#define  HFI_PROPERTY_PARAM_CODEC_MASK_SUPPORTED            \
+	(HFI_PROPERTY_PARAM_COMMON_START + 0x00E)
+#define HFI_PROPERTY_PARAM_MVC_BUFFER_LAYOUT \
+	(HFI_PROPERTY_PARAM_COMMON_START + 0x00F)
+
+#define HFI_PROPERTY_CONFIG_COMMON_START				\
+	(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET + 0x2000)
+#define HFI_PROPERTY_CONFIG_FRAME_RATE					\
+	(HFI_PROPERTY_CONFIG_COMMON_START + 0x001)
+
+#define HFI_PROPERTY_PARAM_VDEC_COMMON_START				\
+	(HFI_DOMAIN_BASE_VDEC + HFI_ARCH_COMMON_OFFSET + 0x3000)
+#define HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM				\
+	(HFI_PROPERTY_PARAM_VDEC_COMMON_START + 0x001)
+#define  HFI_PROPERTY_PARAM_VDEC_CONCEAL_COLOR              \
+	(HFI_PROPERTY_PARAM_VDEC_COMMON_START + 0x002)
+
+#define HFI_PROPERTY_CONFIG_VDEC_COMMON_START				\
+	(HFI_DOMAIN_BASE_VDEC + HFI_ARCH_COMMON_OFFSET + 0x4000)
+
+#define HFI_PROPERTY_PARAM_VENC_COMMON_START				\
+	(HFI_DOMAIN_BASE_VENC + HFI_ARCH_COMMON_OFFSET + 0x5000)
+#define HFI_PROPERTY_PARAM_VENC_SLICE_DELIVERY_MODE			\
+	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x001)
+#define HFI_PROPERTY_PARAM_VENC_H264_ENTROPY_CONTROL		\
+	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x002)
+#define HFI_PROPERTY_PARAM_VENC_H264_DEBLOCK_CONTROL		\
+	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x003)
+#define HFI_PROPERTY_PARAM_VENC_RATE_CONTROL				\
+	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x004)
+#define  HFI_PROPERTY_PARAM_VENC_H264_PICORDER_CNT_TYPE     \
+	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x005)
+#define HFI_PROPERTY_PARAM_VENC_SESSION_QP				\
+	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x006)
+#define HFI_PROPERTY_PARAM_VENC_MPEG4_AC_PREDICTION			\
+	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x007)
+#define  HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE           \
+	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x008)
+#define HFI_PROPERTY_PARAM_VENC_MPEG4_TIME_RESOLUTION		\
+	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x009)
+#define HFI_PROPERTY_PARAM_VENC_MPEG4_SHORT_HEADER			\
+	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x00A)
+#define HFI_PROPERTY_PARAM_VENC_MPEG4_HEADER_EXTENSION		\
+	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x00B)
+#define  HFI_PROPERTY_PARAM_VENC_OPEN_GOP                   \
+	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x00C)
+#define HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH				\
+	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x00D)
+#define HFI_PROPERTY_PARAM_VENC_MULTI_SLICE_CONTROL			\
+	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x00E)
+#define  HFI_PROPERTY_PARAM_VENC_VBV_HRD_BUF_SIZE           \
+	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x00F)
+#define  HFI_PROPERTY_PARAM_VENC_QUALITY_VS_SPEED           \
+	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x010)
+#define HFI_PROPERTY_PARAM_VENC_ADVANCED				\
+	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x012)
+#define  HFI_PROPERTY_PARAM_VENC_H264_SPS_ID                \
+	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x014)
+#define  HFI_PROPERTY_PARAM_VENC_H264_PPS_ID               \
+	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x015)
+#define HFI_PROPERTY_PARAM_VENC_H264_GENERATE_AUDNAL	\
+	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x016)
+#define HFI_PROPERTY_PARAM_VENC_ASPECT_RATIO			\
+	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x017)
+#define HFI_PROPERTY_PARAM_VENC_NUMREF					\
+	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x018)
+#define HFI_PROPERTY_PARAM_VENC_MULTIREF_P				\
+	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x019)
+#define HFI_PROPERTY_PARAM_VENC_HIER_P_NUM_ENH_LAYER	\
+	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01A)
+
+#define HFI_PROPERTY_PARAM_VENC_H264_NAL_SVC_EXT		\
+	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01B)
+
+#define HFI_PROPERTY_CONFIG_VENC_COMMON_START				\
+	(HFI_DOMAIN_BASE_VENC + HFI_ARCH_COMMON_OFFSET + 0x6000)
+#define HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE				\
+	(HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x001)
+#define HFI_PROPERTY_CONFIG_VENC_IDR_PERIOD				\
+	(HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x002)
+#define HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD				\
+	(HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x003)
+#define HFI_PROPERTY_CONFIG_VENC_REQUEST_SYNC_FRAME			\
+	(HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x004)
+#define  HFI_PROPERTY_CONFIG_VENC_SLICE_SIZE                \
+	(HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x005)
+#define HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE				\
+	(HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x007)
+
+#define HFI_PROPERTY_PARAM_VPE_COMMON_START				\
+	(HFI_DOMAIN_BASE_VPE + HFI_ARCH_COMMON_OFFSET + 0x7000)
+#define  HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER	\
+	(HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x008)
+
+#define HFI_PROPERTY_CONFIG_VPE_COMMON_START				\
+	(HFI_DOMAIN_BASE_VPE + HFI_ARCH_COMMON_OFFSET + 0x8000)
+#define HFI_PROPERTY_CONFIG_VPE_DEINTERLACE				\
+	(HFI_PROPERTY_CONFIG_VPE_COMMON_START + 0x001)
+#define HFI_PROPERTY_CONFIG_VPE_OPERATIONS				\
+	(HFI_PROPERTY_CONFIG_VPE_COMMON_START + 0x002)
+
+struct hfi_bitrate {
+	u32 bit_rate;
+	u32 layer_id;
+};
+
+#define HFI_CAPABILITY_FRAME_WIDTH			(HFI_COMMON_BASE + 0x1)
+#define HFI_CAPABILITY_FRAME_HEIGHT			(HFI_COMMON_BASE + 0x2)
+#define HFI_CAPABILITY_MBS_PER_FRAME		(HFI_COMMON_BASE + 0x3)
+#define HFI_CAPABILITY_MBS_PER_SECOND		(HFI_COMMON_BASE + 0x4)
+#define HFI_CAPABILITY_FRAMERATE			(HFI_COMMON_BASE + 0x5)
+#define HFI_CAPABILITY_SCALE_X				(HFI_COMMON_BASE + 0x6)
+#define HFI_CAPABILITY_SCALE_Y				(HFI_COMMON_BASE + 0x7)
+#define HFI_CAPABILITY_BITRATE				(HFI_COMMON_BASE + 0x8)
+#define  HFI_CAPABILITY_BFRAME				(HFI_COMMON_BASE + 0x9)
+#define  HFI_CAPABILITY_HIER_P_NUM_ENH_LAYERS   (HFI_COMMON_BASE + 0x10)
+
+struct hfi_capability_supported {
+	u32 capability_type;
+	u32 min;
+	u32 max;
+	u32 step_size;
+};
+
+struct hfi_capability_supported_info {
+	u32 num_capabilities;
+	struct hfi_capability_supported rg_data[1];
+};
+
+#define HFI_DEBUG_MSG_LOW					0x00000001
+#define HFI_DEBUG_MSG_MEDIUM				0x00000002
+#define HFI_DEBUG_MSG_HIGH					0x00000004
+#define HFI_DEBUG_MSG_ERROR					0x00000008
+#define HFI_DEBUG_MSG_FATAL					0x00000010
+#define HFI_DEBUG_MSG_PERF					0x00000020
+
+#define HFI_DEBUG_MODE_QUEUE				0x00000001
+#define HFI_DEBUG_MODE_QDSS					0x00000002
+
+struct hfi_debug_config {
+	u32 debug_config;
+	u32 debug_mode;
+};
+
+struct hfi_enable {
+	int enable;
+};
+
+#define HFI_H264_DB_MODE_DISABLE			(HFI_COMMON_BASE + 0x1)
+#define HFI_H264_DB_MODE_SKIP_SLICE_BOUNDARY	\
+	(HFI_COMMON_BASE + 0x2)
+#define HFI_H264_DB_MODE_ALL_BOUNDARY		(HFI_COMMON_BASE + 0x3)
+
+struct hfi_h264_db_control {
+	u32 mode;
+	int slice_alpha_offset;
+	int slice_beta_offset;
+};
+
+#define HFI_H264_ENTROPY_CAVLC				(HFI_COMMON_BASE + 0x1)
+#define HFI_H264_ENTROPY_CABAC				(HFI_COMMON_BASE + 0x2)
+
+#define HFI_H264_CABAC_MODEL_0				(HFI_COMMON_BASE + 0x1)
+#define HFI_H264_CABAC_MODEL_1				(HFI_COMMON_BASE + 0x2)
+#define HFI_H264_CABAC_MODEL_2				(HFI_COMMON_BASE + 0x3)
+
+struct hfi_h264_entropy_control {
+	u32 entropy_mode;
+	u32 cabac_model;
+};
+
+struct hfi_frame_rate {
+	u32 buffer_type;
+	u32 frame_rate;
+};
+
+#define HFI_INTRA_REFRESH_NONE				(HFI_COMMON_BASE + 0x1)
+#define HFI_INTRA_REFRESH_CYCLIC			(HFI_COMMON_BASE + 0x2)
+#define HFI_INTRA_REFRESH_ADAPTIVE			(HFI_COMMON_BASE + 0x3)
+#define HFI_INTRA_REFRESH_CYCLIC_ADAPTIVE	(HFI_COMMON_BASE + 0x4)
+#define HFI_INTRA_REFRESH_RANDOM			(HFI_COMMON_BASE + 0x5)
+
+struct hfi_intra_refresh {
+	u32 mode;
+	u32 air_mbs;
+	u32 air_ref;
+	u32 cir_mbs;
+};
+
+struct hfi_idr_period {
+	u32 idr_period;
+};
+
+struct hfi_intra_period {
+	u32 pframes;
+	u32 bframes;
+};
+
+struct hfi_mpeg4_header_extension {
+	u32 header_extension;
+};
+
+struct hfi_mpeg4_time_resolution {
+	u32 time_increment_resolution;
+};
+
+struct hfi_multi_stream {
+	u32 buffer_type;
+	u32 enable;
+	u32 width;
+	u32 height;
+};
+
+struct hfi_multi_view_format {
+	u32 views;
+	u32 rg_view_order[1];
+};
+
+#define HFI_MULTI_SLICE_OFF				(HFI_COMMON_BASE + 0x1)
+#define HFI_MULTI_SLICE_BY_MB_COUNT		(HFI_COMMON_BASE + 0x2)
+#define HFI_MULTI_SLICE_BY_BYTE_COUNT	(HFI_COMMON_BASE + 0x3)
+#define HFI_MULTI_SLICE_GOB				(HFI_COMMON_BASE + 0x4)
+
+struct hfi_multi_slice_control {
+	u32 multi_slice;
+	u32 slice_size;
+};
+
+#define HFI_NAL_FORMAT_STARTCODES			0x00000001
+#define HFI_NAL_FORMAT_ONE_NAL_PER_BUFFER	0x00000002
+#define HFI_NAL_FORMAT_ONE_BYTE_LENGTH		0x00000004
+#define HFI_NAL_FORMAT_TWO_BYTE_LENGTH		0x00000008
+#define HFI_NAL_FORMAT_FOUR_BYTE_LENGTH		0x00000010
+
+struct hfi_nal_stream_format_supported {
+	u32 nal_stream_format_supported;
+};
+
+#define HFI_PICTURE_TYPE_I					0x01
+#define HFI_PICTURE_TYPE_P					0x02
+#define HFI_PICTURE_TYPE_B					0x04
+#define HFI_PICTURE_TYPE_IDR				0x08
+
+struct hfi_profile_level {
+	u32 profile;
+	u32 level;
+};
+
+struct hfi_profile_level_supported {
+	u32 profile_count;
+	struct hfi_profile_level rg_profile_level[1];
+};
+
+struct hfi_quality_vs_speed {
+	u32 quality_vs_speed;
+};
+
+struct hfi_quantization {
+	u32 qp_i;
+	u32 qp_p;
+	u32 qp_b;
+	u32 layer_id;
+};
+
+struct hfi_quantization_range {
+	u32 min_qp;
+	u32 max_qp;
+	u32 layer_id;
+};
+
+struct hfi_frame_size {
+	u32 buffer_type;
+	u32 width;
+	u32 height;
+};
+
+#define HFI_COLOR_FORMAT_MONOCHROME			(HFI_COMMON_BASE + 0x1)
+#define HFI_COLOR_FORMAT_NV12				(HFI_COMMON_BASE + 0x2)
+#define HFI_COLOR_FORMAT_NV21				(HFI_COMMON_BASE + 0x3)
+#define HFI_COLOR_FORMAT_NV12_4x4TILE		(HFI_COMMON_BASE + 0x4)
+#define HFI_COLOR_FORMAT_NV21_4x4TILE		(HFI_COMMON_BASE + 0x5)
+#define HFI_COLOR_FORMAT_YUYV				(HFI_COMMON_BASE + 0x6)
+#define HFI_COLOR_FORMAT_YVYU				(HFI_COMMON_BASE + 0x7)
+#define HFI_COLOR_FORMAT_UYVY				(HFI_COMMON_BASE + 0x8)
+#define HFI_COLOR_FORMAT_VYUY				(HFI_COMMON_BASE + 0x9)
+#define HFI_COLOR_FORMAT_RGB565				(HFI_COMMON_BASE + 0xA)
+#define HFI_COLOR_FORMAT_BGR565				(HFI_COMMON_BASE + 0xB)
+#define HFI_COLOR_FORMAT_RGB888				(HFI_COMMON_BASE + 0xC)
+#define HFI_COLOR_FORMAT_BGR888				(HFI_COMMON_BASE + 0xD)
+
+struct hfi_uncompressed_format_select {
+	u32 buffer_type;
+	u32 format;
+};
+
+struct hfi_uncompressed_format_supported {
+	u32 buffer_type;
+	u32 format_entries;
+	u32 rg_format_info[1];
+};
+
+struct hfi_uncompressed_plane_actual {
+	int actual_stride;
+	u32 actual_plane_buffer_height;
+};
+
+struct hfi_uncompressed_plane_actual_info {
+	u32 buffer_type;
+	u32 num_planes;
+	struct hfi_uncompressed_plane_actual rg_plane_format[1];
+};
+
+struct hfi_uncompressed_plane_constraints {
+	u32 stride_multiples;
+	u32 max_stride;
+	u32 min_plane_buffer_height_multiple;
+	u32 buffer_alignment;
+};
+
+struct hfi_uncompressed_plane_info {
+	u32 format;
+	u32 num_planes;
+	struct hfi_uncompressed_plane_constraints rg_plane_format[1];
+};
+
+struct hfi_codec_supported {
+	u32 decoder_codec_supported;
+	u32 encoder_codec_supported;
+};
+
+struct hfi_properties_supported {
+	u32 num_properties;
+	u32 rg_properties[1];
+};
+
+#define HFI_ROTATE_NONE					(HFI_COMMON_BASE + 0x1)
+#define HFI_ROTATE_90					(HFI_COMMON_BASE + 0x2)
+#define HFI_ROTATE_180					(HFI_COMMON_BASE + 0x3)
+#define HFI_ROTATE_270					(HFI_COMMON_BASE + 0x4)
+
+#define HFI_FLIP_NONE					(HFI_COMMON_BASE + 0x1)
+#define HFI_FLIP_HORIZONTAL				(HFI_COMMON_BASE + 0x2)
+#define HFI_FLIP_VERTICAL				(HFI_COMMON_BASE + 0x3)
+
+struct hfi_operations {
+	u32 rotate;
+	u32 flip;
+};
+
+#define HFI_RESOURCE_OCMEM 0x00000001
+
+struct hfi_resource_ocmem {
+	u32 size;
+	u8 *mem;
+};
+
+struct hfi_resource_ocmem_requirement {
+	u32 session_domain;
+	u32 width;
+	u32 height;
+	u32 size;
+};
+
+struct hfi_resource_ocmem_requirement_info {
+	u32 num_entries;
+	struct hfi_resource_ocmem_requirement rg_requirements[1];
+};
+
+struct hfi_venc_config_advanced {
+	u8 pipe2d;
+	u8 hw_mode;
+	u8 low_delay_enforce;
+	u8 worker_vppsg_delay;
+	int close_gop;
+	int h264_constrain_intra_pred;
+	int h264_transform_8x8_flag;
+	int mpeg4_qpel_enable;
+	int multi_refp_en;
+	int qmatrix_en;
+	u8 vpp_info_packet_mode;
+	u8 ref_tile_mode;
+	u8 bitstream_flush_mode;
+	u32 vppsg_vspap_fb_sync_delay;
+	u32 rc_initial_delay;
+	u32 peak_bitrate_constraint;
+	u32 ds_display_frame_width;
+	u32 ds_display_frame_height;
+	u32 perf_tune_param_ptr;
+	u32 input_x_offset;
+	u32 input_y_offset;
+	u32 input_roi_width;
+	u32 input_roi_height;
+	u32 vsp_fifo_dma_sel;
+	u32 h264_num_ref_frames;
+};
+
+struct hfi_vbv_hrd_bufsize {
+	u32 buffer_size;
+};
+
+struct hfi_codec_mask_supported {
+	u32 codecs;
+	u32 video_domains;
+};
+
+struct hfi_seq_header_info {
+	u32 max_hader_len;
+};
+struct hfi_aspect_ratio {
+	u32 aspect_width;
+	u32 aspect_height;
+};
+#define HFI_MVC_BUFFER_LAYOUT_TOP_BOTTOM  (0)
+#define HFI_MVC_BUFFER_LAYOUT_SIDEBYSIDE  (1)
+#define HFI_MVC_BUFFER_LAYOUT_SEQ         (2)
+struct hfi_mvc_buffer_lauout_descp_type {
+	u32    layout_type;
+	u32    bright_view_first;
+	u32    ngap;
+};
+
+
+#define HFI_CMD_SYS_COMMON_START			\
+(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET + HFI_CMD_START_OFFSET \
+	+ 0x0000)
+#define HFI_CMD_SYS_INIT		(HFI_CMD_SYS_COMMON_START + 0x001)
+#define HFI_CMD_SYS_PC_PREP		(HFI_CMD_SYS_COMMON_START + 0x002)
+#define HFI_CMD_SYS_SET_RESOURCE	(HFI_CMD_SYS_COMMON_START + 0x003)
+#define HFI_CMD_SYS_RELEASE_RESOURCE (HFI_CMD_SYS_COMMON_START + 0x004)
+#define HFI_CMD_SYS_SET_PROPERTY	(HFI_CMD_SYS_COMMON_START + 0x005)
+#define HFI_CMD_SYS_GET_PROPERTY	(HFI_CMD_SYS_COMMON_START + 0x006)
+#define HFI_CMD_SYS_SESSION_INIT	(HFI_CMD_SYS_COMMON_START + 0x007)
+#define HFI_CMD_SYS_SESSION_END		(HFI_CMD_SYS_COMMON_START + 0x008)
+#define HFI_CMD_SYS_SET_BUFFERS		(HFI_CMD_SYS_COMMON_START + 0x009)
+#define HFI_CMD_SYS_TEST_START		(HFI_CMD_SYS_COMMON_START + 0x100)
+
+#define HFI_CMD_SESSION_COMMON_START		\
+	(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET +	\
+	HFI_CMD_START_OFFSET + 0x1000)
+#define HFI_CMD_SESSION_SET_PROPERTY		\
+	(HFI_CMD_SESSION_COMMON_START + 0x001)
+#define HFI_CMD_SESSION_SET_BUFFERS			\
+	(HFI_CMD_SESSION_COMMON_START + 0x002)
+#define HFI_CMD_SESSION_GET_SEQUENCE_HEADER	\
+	(HFI_CMD_SESSION_COMMON_START + 0x003)
+
+#define HFI_MSG_SYS_COMMON_START			\
+	(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET +	\
+	HFI_MSG_START_OFFSET + 0x0000)
+#define HFI_MSG_SYS_INIT_DONE			(HFI_MSG_SYS_COMMON_START + 0x1)
+#define HFI_MSG_SYS_PC_PREP_DONE		(HFI_MSG_SYS_COMMON_START + 0x2)
+#define HFI_MSG_SYS_RELEASE_RESOURCE	(HFI_MSG_SYS_COMMON_START + 0x3)
+#define HFI_MSG_SYS_DEBUG			(HFI_MSG_SYS_COMMON_START + 0x4)
+#define HFI_MSG_SYS_SESSION_INIT_DONE	(HFI_MSG_SYS_COMMON_START + 0x6)
+#define HFI_MSG_SYS_SESSION_END_DONE	(HFI_MSG_SYS_COMMON_START + 0x7)
+
+#define HFI_MSG_SESSION_COMMON_START		\
+	(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET +	\
+	HFI_MSG_START_OFFSET + 0x1000)
+#define HFI_MSG_EVENT_NOTIFY	(HFI_MSG_SESSION_COMMON_START + 0x1)
+#define HFI_MSG_SESSION_GET_SEQUENCE_HEADER_DONE	\
+	(HFI_MSG_SESSION_COMMON_START + 0x2)
+
+#define  HFI_CMD_SYS_TEST_SSR	(HFI_CMD_SYS_TEST_START + 0x1)
+#define HFI_TEST_SSR_SW_ERR_FATAL	0x1
+#define HFI_TEST_SSR_SW_DIV_BY_ZERO	0x2
+#define HFI_TEST_SSR_HW_WDOG_IRQ	0x3
+
+struct vidc_hal_msg_pkt_hdr {
+	u32 size;
+	u32 packet;
+};
+
+struct vidc_hal_session_cmd_pkt {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+};
+
+struct hfi_cmd_sys_init_packet {
+	u32 size;
+	u32 packet_type;
+	u32 arch_type;
+};
+
+struct hfi_cmd_sys_pc_prep_packet {
+	u32 size;
+	u32 packet_type;
+};
+
+struct hfi_cmd_sys_set_resource_packet {
+	u32 size;
+	u32 packet_type;
+	u32 resource_handle;
+	u32 resource_type;
+	u32 rg_resource_data[1];
+};
+
+struct hfi_cmd_sys_release_resource_packet {
+	u32 size;
+	u32 packet_type;
+	u32 resource_type;
+	u32 resource_handle;
+};
+
+struct hfi_cmd_sys_set_property_packet {
+	u32 size;
+	u32 packet_type;
+	u32 num_properties;
+	u32 rg_property_data[1];
+};
+
+struct hfi_cmd_sys_get_property_packet {
+	u32 size;
+	u32 packet_type;
+	u32 num_properties;
+	u32 rg_property_data[1];
+};
+
+struct hfi_cmd_sys_session_init_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 session_domain;
+	u32 session_codec;
+};
+
+struct hfi_cmd_sys_session_end_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+};
+
+struct hfi_cmd_sys_set_buffers_packet {
+	u32 size;
+	u32 packet_type;
+	u32 buffer_type;
+	u32 buffer_size;
+	u32 num_buffers;
+	u32 rg_buffer_addr[1];
+};
+
+struct hfi_cmd_session_set_property_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 num_properties;
+	u32 rg_property_data[0];
+};
+
+struct hfi_cmd_session_set_buffers_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 buffer_type;
+	u32 buffer_size;
+	u32 extra_data_size;
+	u32 min_buffer_size;
+	u32 num_buffers;
+	u32 rg_buffer_info[1];
+};
+
+struct hfi_cmd_session_get_sequence_header_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 buffer_len;
+	u8 *packet_buffer;
+};
+
+struct hfi_msg_event_notify_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 event_id;
+	u32 event_data1;
+	u32 event_data2;
+	u32 rg_ext_event_data[1];
+};
+
+struct hfi_msg_sys_init_done_packet {
+	u32 size;
+	u32 packet_type;
+	u32 error_type;
+	u32 num_properties;
+	u32 rg_property_data[1];
+};
+
+struct hfi_msg_sys_pc_prep_done_packet {
+	u32 size;
+	u32 packet_type;
+	u32 error_type;
+};
+
+struct hfi_msg_sys_release_resource_done_packet {
+	u32 size;
+	u32 packet_type;
+	u32 resource_handle;
+	u32 error_type;
+};
+
+struct hfi_msg_sys_session_init_done_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 error_type;
+	u32 num_properties;
+	u32 rg_property_data[1];
+};
+
+struct hfi_msg_sys_session_end_done_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 error_type;
+};
+
+struct hfi_msg_session_get_sequence_header_done_packet {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 error_type;
+	u32 header_len;
+	u8 *sequence_header;
+};
+
+struct hfi_msg_sys_debug_packet {
+	u32 size;
+	u32 packet_type;
+	u32 msg_type;
+	u32 msg_size;
+	u32 time_stamp_hi;
+	u32 time_stamp_lo;
+	u8 rg_msg_data[1];
+};
+
+enum HFI_VENUS_QTBL_STATUS {
+	HFI_VENUS_QTBL_DISABLED = 0x00,
+	HFI_VENUS_QTBL_ENABLED = 0x01,
+	HFI_VENUS_QTBL_INITIALIZING = 0x02,
+	HFI_VENUS_QTBL_DEINITIALIZING = 0x03
+};
+
+enum HFI_VENUS_CTRL_INIT_STATUS {
+	HFI_VENUS_CTRL_NOT_INIT = 0x0,
+	HFI_VENUS_CTRL_READY = 0x1,
+	HFI_VENUS_CTRL_ERROR_FATAL = 0x2
+};
+
+struct hfi_sfr_struct {
+	u32 bufSize;
+	u8 rg_data[1];
+};
+
+struct hfi_cmd_sys_test_ssr_packet {
+	u32 size;
+	u32 packet_type;
+	u32 trigger_type;
+};
+
+#endif
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_io.h b/drivers/media/platform/msm/vidc/vidc_hfi_io.h
new file mode 100644
index 0000000..eeffe35
--- /dev/null
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_io.h
@@ -0,0 +1,176 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __VIDC_HFI_IO_H__
+#define __VIDC_HFI_IO_H__
+
+#include <linux/io.h>
+
+#define VENUS_VCODEC_SS_CLOCK_HALT     0x0000000C
+#define VENUS_VPP_CORE_SW_RESET        0x00042004
+#define VENUS_VPP_CTRL_CTRL_RESET      0x00041008
+
+#define VIDC_VBIF_BASE_OFFS			0x00080000
+#define VIDC_VBIF_VERSION			(VIDC_VBIF_BASE_OFFS + 0x00)
+#define VIDC_VENUS_VBIF_DDR_OUT_MAX_BURST		\
+			(VIDC_VBIF_BASE_OFFS + 0xD8)
+#define VIDC_VENUS_VBIF_OCMEM_OUT_MAX_BURST		\
+			(VIDC_VBIF_BASE_OFFS + 0xDC)
+#define VIDC_VENUS_VBIF_ROUND_ROBIN_QOS_ARB		\
+			(VIDC_VBIF_BASE_OFFS + 0x124)
+
+#define VIDC_CPU_BASE_OFFS			0x000C0000
+#define VIDC_CPU_CS_BASE_OFFS		(VIDC_CPU_BASE_OFFS + 0x00012000)
+#define VIDC_CPU_IC_BASE_OFFS		(VIDC_CPU_BASE_OFFS + 0x0001F000)
+
+#define VIDC_CPU_CS_REMAP_OFFS		(VIDC_CPU_CS_BASE_OFFS + 0x00)
+#define VIDC_CPU_CS_TIMER_CONTROL	(VIDC_CPU_CS_BASE_OFFS + 0x04)
+#define VIDC_CPU_CS_A2HSOFTINTEN	(VIDC_CPU_CS_BASE_OFFS + 0x10)
+#define VIDC_CPU_CS_A2HSOFTINTENCLR	(VIDC_CPU_CS_BASE_OFFS + 0x14)
+#define VIDC_CPU_CS_A2HSOFTINT		(VIDC_CPU_CS_BASE_OFFS + 0x18)
+#define VIDC_CPU_CS_A2HSOFTINTCLR	(VIDC_CPU_CS_BASE_OFFS + 0x1C)
+#define VIDC_CPU_CS_SCIACMD			(VIDC_CPU_CS_BASE_OFFS + 0x48)
+
+/* HFI_CTRL_STATUS */
+#define VIDC_CPU_CS_SCIACMDARG0		(VIDC_CPU_CS_BASE_OFFS + 0x4C)
+#define VIDC_CPU_CS_SCIACMDARG0_BMSK	0xff
+#define VIDC_CPU_CS_SCIACMDARG0_SHFT	0x0
+#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK	0xfe
+#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_SHFT	0x1
+#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_STATUS_BMSK	0x1
+#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_STATUS_SHFT	0x0
+#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK     0x40000000
+
+/* HFI_QTBL_INFO */
+#define VIDC_CPU_CS_SCIACMDARG1		(VIDC_CPU_CS_BASE_OFFS + 0x50)
+
+/* HFI_QTBL_ADDR */
+#define VIDC_CPU_CS_SCIACMDARG2		(VIDC_CPU_CS_BASE_OFFS + 0x54)
+
+/* HFI_VERSION_INFO */
+#define VIDC_CPU_CS_SCIACMDARG3		(VIDC_CPU_CS_BASE_OFFS + 0x58)
+#define VIDC_CPU_IC_IRQSTATUS		(VIDC_CPU_IC_BASE_OFFS + 0x00)
+#define VIDC_CPU_IC_FIQSTATUS		(VIDC_CPU_IC_BASE_OFFS + 0x04)
+#define VIDC_CPU_IC_RAWINTR			(VIDC_CPU_IC_BASE_OFFS + 0x08)
+#define VIDC_CPU_IC_INTSELECT		(VIDC_CPU_IC_BASE_OFFS + 0x0C)
+#define VIDC_CPU_IC_INTENABLE		(VIDC_CPU_IC_BASE_OFFS + 0x10)
+#define VIDC_CPU_IC_INTENACLEAR		(VIDC_CPU_IC_BASE_OFFS + 0x14)
+#define VIDC_CPU_IC_SOFTINT			(VIDC_CPU_IC_BASE_OFFS + 0x18)
+#define VIDC_CPU_IC_SOFTINT_H2A_BMSK	0x8000
+#define VIDC_CPU_IC_SOFTINT_H2A_SHFT	0xF
+#define VIDC_CPU_IC_SOFTINTCLEAR	(VIDC_CPU_IC_BASE_OFFS + 0x1C)
+
+/*---------------------------------------------------------------------------
+ * MODULE: vidc_wrapper
+ *--------------------------------------------------------------------------*/
+#define VIDC_WRAPPER_BASE_OFFS		0x000E0000
+
+#define VIDC_WRAPPER_HW_VERSION		(VIDC_WRAPPER_BASE_OFFS + 0x00)
+#define VIDC_WRAPPER_CLOCK_CONFIG	(VIDC_WRAPPER_BASE_OFFS + 0x04)
+
+#define VIDC_WRAPPER_INTR_STATUS	(VIDC_WRAPPER_BASE_OFFS + 0x0C)
+#define VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK	0x10
+#define VIDC_WRAPPER_INTR_STATUS_A2HWD_SHFT	0x4
+#define VIDC_WRAPPER_INTR_STATUS_A2H_BMSK	0x4
+#define VIDC_WRAPPER_INTR_STATUS_A2H_SHFT	0x2
+
+#define VIDC_WRAPPER_INTR_MASK		(VIDC_WRAPPER_BASE_OFFS + 0x10)
+#define VIDC_WRAPPER_INTR_MASK_A2HWD_BMSK	0x10
+#define VIDC_WRAPPER_INTR_MASK_A2HWD_SHFT	0x4
+#define VIDC_WRAPPER_INTR_MASK_A2H_BMSK		0x4
+#define VIDC_WRAPPER_INTR_MASK_A2H_SHFT		0x2
+
+#define VIDC_WRAPPER_INTR_CLEAR		(VIDC_WRAPPER_BASE_OFFS + 0x14)
+#define VIDC_WRAPPER_INTR_CLEAR_A2HWD_BMSK	0x10
+#define VIDC_WRAPPER_INTR_CLEAR_A2HWD_SHFT	0x4
+#define VIDC_WRAPPER_INTR_CLEAR_A2H_BMSK	0x4
+#define VIDC_WRAPPER_INTR_CLEAR_A2H_SHFT	0x2
+
+#define VIDC_WRAPPER_VBIF_XIN_SW_RESET	(VIDC_WRAPPER_BASE_OFFS + 0x18)
+#define VIDC_WRAPPER_VBIF_XIN_STATUS	(VIDC_WRAPPER_BASE_OFFS + 0x1C)
+#define VIDC_WRAPPER_CPU_CLOCK_CONFIG	(VIDC_WRAPPER_BASE_OFFS + 0x2000)
+#define VIDC_WRAPPER_VBIF_XIN_CPU_SW_RESET	\
+				(VIDC_WRAPPER_BASE_OFFS + 0x2004)
+#define VIDC_WRAPPER_AXI_HALT		(VIDC_WRAPPER_BASE_OFFS + 0x2008)
+#define VIDC_WRAPPER_AXI_HALT_STATUS	(VIDC_WRAPPER_BASE_OFFS + 0x200C)
+#define VIDC_WRAPPER_CPU_CGC_DIS	(VIDC_WRAPPER_BASE_OFFS + 0x2010)
+#define VIDC_VENUS_VBIF_CLK_ON		(VIDC_VBIF_BASE_OFFS + 0x4)
+#define VIDC_VBIF_IN_RD_LIM_CONF0       (VIDC_VBIF_BASE_OFFS + 0xB0)
+#define VIDC_VBIF_IN_RD_LIM_CONF1       (VIDC_VBIF_BASE_OFFS + 0xB4)
+#define VIDC_VBIF_IN_RD_LIM_CONF2       (VIDC_VBIF_BASE_OFFS + 0xB8)
+#define VIDC_VBIF_IN_RD_LIM_CONF3       (VIDC_VBIF_BASE_OFFS + 0xBC)
+#define VIDC_VBIF_IN_WR_LIM_CONF0       (VIDC_VBIF_BASE_OFFS + 0xC0)
+#define VIDC_VBIF_IN_WR_LIM_CONF1       (VIDC_VBIF_BASE_OFFS + 0xC4)
+#define VIDC_VBIF_IN_WR_LIM_CONF2       (VIDC_VBIF_BASE_OFFS + 0xC8)
+#define VIDC_VBIF_IN_WR_LIM_CONF3       (VIDC_VBIF_BASE_OFFS + 0xCC)
+#define VIDC_VBIF_OUT_RD_LIM_CONF0      (VIDC_VBIF_BASE_OFFS + 0xD0)
+#define VIDC_VBIF_OUT_WR_LIM_CONF0      (VIDC_VBIF_BASE_OFFS + 0xD4)
+#define VIDC_VBIF_DDR_OUT_MAX_BURST     (VIDC_VBIF_BASE_OFFS + 0xD8)
+#define VIDC_VBIF_OCMEM_OUT_MAX_BURST   (VIDC_VBIF_BASE_OFFS + 0xDC)
+#define VIDC_VBIF_DDR_ARB_CONF0         (VIDC_VBIF_BASE_OFFS + 0xF4)
+#define VIDC_VBIF_DDR_ARB_CONF1         (VIDC_VBIF_BASE_OFFS + 0xF8)
+#define VIDC_VBIF_ROUND_ROBIN_QOS_ARB   (VIDC_VBIF_BASE_OFFS + 0x124)
+#define VIDC_VBIF_OUT_AXI_AOOO_EN       (VIDC_VBIF_BASE_OFFS + 0x178)
+#define VIDC_VBIF_OUT_AXI_AOOO          (VIDC_VBIF_BASE_OFFS + 0x17C)
+#define VIDC_VBIF_ARB_CTL               (VIDC_VBIF_BASE_OFFS + 0xF0)
+#define VIDC_VBIF_OUT_AXI_AMEMTYPE_CONF0 (VIDC_VBIF_BASE_OFFS + 0x160)
+#define VIDC_VBIF_OUT_AXI_AMEMTYPE_CONF1 (VIDC_VBIF_BASE_OFFS + 0x164)
+#define VIDC_VBIF_ADDR_TRANS_EN         (VIDC_VBIF_BASE_OFFS + 0xC00)
+#define VIDC_VBIF_AT_OLD_BASE           (VIDC_VBIF_BASE_OFFS + 0xC04)
+#define VIDC_VBIF_AT_OLD_HIGH           (VIDC_VBIF_BASE_OFFS + 0xC08)
+#define VIDC_VBIF_AT_NEW_BASE           (VIDC_VBIF_BASE_OFFS + 0xC10)
+#define VIDC_VBIF_AT_NEW_HIGH           (VIDC_VBIF_BASE_OFFS + 0xC18)
+
+#define VIDC_VENUS0_WRAPPER_VBIF_REQ_PRIORITY \
+	(VIDC_WRAPPER_BASE_OFFS + 0x20)
+#define VIDC_VENUS0_WRAPPER_VBIF_PRIORITY_LEVEL \
+	(VIDC_WRAPPER_BASE_OFFS + 0x24)
+
+#define VIDC_CTRL_INIT 0x000D2048
+#define VIDC_CTRL_INIT_RESERVED_BITS31_1__M 0xFFFFFFFE
+#define VIDC_CTRL_INIT_RESERVED_BITS31_1__S 1
+#define VIDC_CTRL_INIT_CTRL__M 0x00000001
+#define VIDC_CTRL_INIT_CTRL__S 0
+
+#define VIDC_CTRL_STATUS 0x000D204C
+#define VIDC_CTRL_STATUS_RESERVED_BITS31_8__M 0xFFFFFF00
+#define VIDC_CTRL_STATUS_RESERVED_BITS31_8__S 8
+#define VIDC_CTRL_ERROR_STATUS__M             0x000000FE
+#define VIDC_CTRL_ERROR_STATUS__S             1
+#define VIDC_CTRL_INIT_STATUS__M              0x00000001
+#define VIDC_CTRL_INIT_STATUS__S              0
+
+#define VIDC_QTBL_INFO 0x000D2050
+#define VIDC_QTBL_HOSTID__M 0xFF000000
+#define VIDC_QTBL_HOSTID__S 24
+#define VIDC_QTBL_INFO_RESERVED_BITS23_8__M 0x00FFFF00
+#define VIDC_QTBL_INFO_RESERVED_BITS23_8__S 8
+#define VIDC_QTBL_STATUS__M 0x000000FF
+#define VIDC_QTBL_STATUS__S 0
+
+#define VIDC_QTBL_ADDR 0x000D2054
+
+#define VIDC_VERSION_INFO 0x000D2058
+#define VIDC_VERSION_INFO_MAJOR__M  0xF0000000
+#define VIDC_VERSION_INFO_MAJOR__S  28
+#define VIDC_VERSION_INFO_MINOR__M  0x0FFFFFE0
+#define VIDC_VERSION_INFO_MINOR__S  5
+#define VIDC_VERSION_INFO_BRANCH__M 0x0000001F
+#define VIDC_VERSION_INFO_BRANCH__S 0
+
+#define VIDC_SFR_ADDR 0x000D205C
+#define VIDC_MMAP_ADDR 0x000D2060
+#define VIDC_UC_REGION_ADDR 0x000D2064
+#define VIDC_UC_REGION_SIZE 0x000D2068
+
+#endif
diff --git a/drivers/media/video/msm_wfd/Kconfig b/drivers/media/platform/msm/wfd/Kconfig
similarity index 100%
rename from drivers/media/video/msm_wfd/Kconfig
rename to drivers/media/platform/msm/wfd/Kconfig
diff --git a/drivers/media/video/msm_wfd/Makefile b/drivers/media/platform/msm/wfd/Makefile
similarity index 100%
rename from drivers/media/video/msm_wfd/Makefile
rename to drivers/media/platform/msm/wfd/Makefile
diff --git a/drivers/media/platform/msm/wfd/enc-mfc-subdev.c b/drivers/media/platform/msm/wfd/enc-mfc-subdev.c
new file mode 100644
index 0000000..fee7b47
--- /dev/null
+++ b/drivers/media/platform/msm/wfd/enc-mfc-subdev.c
@@ -0,0 +1,2564 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 and
+* only version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+*/
+
+#include <media/v4l2-subdev.h>
+#include <mach/iommu_domains.h>
+#include "enc-subdev.h"
+#include "wfd-util.h"
+#include <media/msm/vcd_api.h>
+#include <media/msm/vidc_init.h>
+#include <media/msm/vcd_property.h>
+#include <linux/time.h>
+#include <linux/ktime.h>
+
+#define VID_ENC_MAX_ENCODER_CLIENTS 1
+#define MAX_NUM_CTRLS 20
+#define V4L2_FRAME_FLAGS (V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_PFRAME | \
+		V4L2_BUF_FLAG_BFRAME | V4L2_QCOM_BUF_FLAG_CODECCONFIG)
+
+static long venc_fill_outbuf(struct v4l2_subdev *sd, void *arg);
+
+struct venc_inst {
+	struct video_client_ctx venc_client;
+	void *cbdata;
+	void (*op_buffer_done)(void *cookie, u32 status,
+			struct vb2_buffer *buf);
+	void (*ip_buffer_done)(void *cookie, u32 status,
+			struct mem_region *mregion);
+	u32 width;
+	u32 height;
+	int secure;
+	struct mem_region unqueued_op_bufs;
+	bool streaming;
+	enum venc_framerate_modes framerate_mode;
+};
+
+struct venc {
+	s32 device_handle;
+	void *virt_base;
+	struct venc_inst venc_clients[VID_ENC_MAX_ENCODER_CLIENTS];
+	struct mutex lock;
+	struct ion_client *iclient;
+};
+
+static struct venc venc_p;
+
+static void *venc_map_dev_base_addr(void *device_name)
+{
+		return venc_p.virt_base;
+}
+
+static void venc_interrupt_deregister(void)
+{
+}
+
+static void venc_interrupt_register(void *device_name)
+{
+}
+
+static void venc_interrupt_clear(void)
+{
+}
+
+int venc_load_fw(struct v4l2_subdev *sd)
+{
+	return !vidc_load_firmware();
+}
+
+static u32 venc_get_empty_client_index(void)
+{
+	u32 i;
+	u32 found = false;
+
+	for (i = 0; i < VID_ENC_MAX_ENCODER_CLIENTS; i++) {
+		if (!venc_p.venc_clients[i].venc_client.vcd_handle) {
+			found = true;
+			break;
+		}
+	}
+	if (!found) {
+		WFD_MSG_ERR("%s():ERROR No space for new client\n",
+				__func__);
+		return -ENOMEM;
+	}
+	WFD_MSG_INFO("%s(): available client index = %u\n",
+				__func__, i);
+	return i;
+}
+
+int venc_init(struct v4l2_subdev *sd, u32 val)
+{
+	struct vcd_init_config vcd_init_config;
+	mutex_init(&venc_p.lock);
+	venc_p.virt_base = vidc_get_ioaddr();
+	vcd_init_config.device_name = "VIDC";
+	vcd_init_config.map_dev_base_addr = venc_map_dev_base_addr;
+	vcd_init_config.interrupt_clr = venc_interrupt_clear;
+	vcd_init_config.register_isr = venc_interrupt_register;
+	vcd_init_config.deregister_isr = venc_interrupt_deregister;
+	vcd_init(&vcd_init_config, &venc_p.device_handle);
+	return 0;
+}
+
+static void venc_notify_client(struct video_client_ctx *client_ctx)
+{
+	if (client_ctx)
+		complete(&client_ctx->event);
+}
+
+static void venc_open_done(struct video_client_ctx *client_ctx,
+	struct vcd_handle_container *handle_container)
+{
+	if (client_ctx) {
+		if (handle_container)
+			client_ctx->vcd_handle = handle_container->handle;
+		else
+			WFD_MSG_ERR("handle_container is NULL\n");
+		venc_notify_client(client_ctx);
+	} else
+		WFD_MSG_ERR("ERROR. client_ctx is NULL");
+}
+
+static void venc_start_done(struct video_client_ctx *client_ctx, u32 status)
+{
+	if (client_ctx)
+		venc_notify_client(client_ctx);
+	else
+		WFD_MSG_ERR("ERROR. client_ctx is NULL");
+}
+
+static void venc_stop_done(struct video_client_ctx *client_ctx, u32 status)
+{
+	WFD_MSG_DBG("Inside venc_stop_done: E\n");
+	if (client_ctx)
+		venc_notify_client(client_ctx);
+	else
+		WFD_MSG_ERR("ERROR. client_ctx is NULL");
+	WFD_MSG_DBG("Inside venc_stop_done: X\n");
+}
+
+static void venc_cb(u32 event, u32 status, void *info, u32 size, void *handle,
+		void *const client_data)
+{
+	struct venc_inst *inst = client_data;
+	struct video_client_ctx *client_ctx = &inst->venc_client;
+	struct vb2_buffer *vbuf;
+	struct mem_region *mregion;
+	struct vcd_frame_data *frame_data = (struct vcd_frame_data *)info;
+
+	if (!client_ctx) {
+		WFD_MSG_ERR("Client context is NULL\n");
+		return;
+	}
+	client_ctx->event_status = status;
+	switch (event) {
+	case VCD_EVT_RESP_OPEN:
+		WFD_MSG_DBG("EVENT: open done = %d\n", event);
+		venc_open_done(client_ctx,
+				(struct vcd_handle_container *)info);
+		break;
+	case VCD_EVT_RESP_INPUT_DONE:
+	case VCD_EVT_RESP_INPUT_FLUSHED:
+		WFD_MSG_DBG("EVENT: input done = %d\n", event);
+		mregion = (struct mem_region *)
+			frame_data->frm_clnt_data;
+		inst->ip_buffer_done(inst->cbdata, status, mregion);
+		break;
+	case VCD_EVT_RESP_OUTPUT_DONE:
+	case VCD_EVT_RESP_OUTPUT_FLUSHED:
+		WFD_MSG_DBG("EVENT: output done = %d\n", event);
+		vbuf = (struct vb2_buffer *)
+			frame_data->frm_clnt_data;
+		vbuf->v4l2_planes[0].bytesused =
+			frame_data->data_len;
+
+		vbuf->v4l2_buf.flags &= ~(V4L2_FRAME_FLAGS);
+		switch (frame_data->frame) {
+		case VCD_FRAME_I:
+		case VCD_FRAME_IDR:
+			vbuf->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME;
+			break;
+		case VCD_FRAME_P:
+			vbuf->v4l2_buf.flags |= V4L2_BUF_FLAG_PFRAME;
+			break;
+		case VCD_FRAME_B:
+			vbuf->v4l2_buf.flags |= V4L2_BUF_FLAG_BFRAME;
+			break;
+		default:
+			break;
+		}
+
+		if (frame_data->flags & VCD_FRAME_FLAG_CODECCONFIG)
+			vbuf->v4l2_buf.flags |= V4L2_QCOM_BUF_FLAG_CODECCONFIG;
+
+		vbuf->v4l2_buf.timestamp =
+			ns_to_timeval(frame_data->time_stamp * NSEC_PER_USEC);
+
+		WFD_MSG_DBG("bytes used %d, ts: %d.%d, frame type is %d\n",
+				frame_data->data_len,
+				(int)vbuf->v4l2_buf.timestamp.tv_sec,
+				(int)vbuf->v4l2_buf.timestamp.tv_usec,
+				frame_data->frame);
+
+		/*
+		 * Output buffers are enc-subdev and vcd's problem, so
+		 * if buffer is cached, need to flush before giving to
+		 * client. So doing the dirty stuff in this little context
+		 */
+		{
+			unsigned long kvaddr, phys_addr;
+			s32 buffer_index = -1, ion_flags = 0;
+			struct ion_handle *ion_handle;
+			int pmem_fd;
+			struct file *filp;
+			bool rc;
+
+			rc = vidc_lookup_addr_table(client_ctx,
+					BUFFER_TYPE_OUTPUT, true,
+					(unsigned long *)&frame_data->
+					frm_clnt_data, &kvaddr, &phys_addr,
+					&pmem_fd, &filp, &buffer_index);
+
+			if (rc)
+				ion_flags = vidc_get_fd_info(client_ctx,
+					BUFFER_TYPE_OUTPUT, pmem_fd,
+					kvaddr, buffer_index, &ion_handle);
+			else
+				WFD_MSG_ERR("Got an output buffer that we " \
+						"couldn't recognize!\n");
+
+			if (msm_ion_do_cache_op(client_ctx->user_ion_client,
+				ion_handle, &kvaddr, frame_data->data_len,
+				ION_IOC_CLEAN_INV_CACHES))
+				WFD_MSG_ERR("OP buffer flush failed\n");
+
+		}
+
+		inst->op_buffer_done(inst->cbdata, status, vbuf);
+		break;
+	case VCD_EVT_RESP_START:
+		WFD_MSG_DBG("EVENT: start done = %d\n", event);
+		venc_start_done(client_ctx, status);
+		/*TODO: should wait for this event*/
+		break;
+	case VCD_EVT_RESP_STOP:
+		WFD_MSG_DBG("EVENT: not expected = %d\n", event);
+		venc_stop_done(client_ctx, status);
+		break;
+	case VCD_EVT_RESP_FLUSH_INPUT_DONE:
+	case VCD_EVT_RESP_FLUSH_OUTPUT_DONE:
+		venc_notify_client(client_ctx);
+		break;
+	case VCD_EVT_RESP_PAUSE:
+	case VCD_EVT_IND_OUTPUT_RECONFIG:
+		WFD_MSG_DBG("EVENT: not expected = %d\n", event);
+		break;
+	case VCD_EVT_IND_HWERRFATAL:
+	case VCD_EVT_IND_RESOURCES_LOST:
+		WFD_MSG_DBG("EVENT: error = %d\n", event);
+		break;
+	default:
+		WFD_MSG_ERR("Invalid event type = %u\n", event);
+		break;
+	}
+}
+
+static long venc_open(struct v4l2_subdev *sd, void *arg)
+{
+	u32 client_index;
+	int rc = 0;
+	struct venc_inst *inst;
+	struct video_client_ctx *client_ctx;
+	struct venc_msg_ops *vmops  =  arg;
+	int flags = 0;
+	mutex_lock(&venc_p.lock);
+	client_index = venc_get_empty_client_index();
+	if (client_index < 0) {
+		WFD_MSG_ERR("No free clients, client_index = %d\n",
+				client_index);
+		rc = -ENODEV;
+		goto no_free_client;
+	}
+	inst = &venc_p.venc_clients[client_index];
+	client_ctx = &inst->venc_client;
+	init_completion(&client_ctx->event);
+	mutex_init(&client_ctx->msg_queue_lock);
+	mutex_init(&client_ctx->enrty_queue_lock);
+	INIT_LIST_HEAD(&client_ctx->msg_queue);
+	init_waitqueue_head(&client_ctx->msg_wait);
+	inst->op_buffer_done = vmops->op_buffer_done;
+	inst->ip_buffer_done = vmops->ip_buffer_done;
+	INIT_LIST_HEAD(&inst->unqueued_op_bufs.list);
+	inst->cbdata = vmops->cbdata;
+	inst->secure = vmops->secure;
+	inst->streaming = false;
+	inst->framerate_mode = VENC_MODE_VFR;
+
+	if (vmops->secure) {
+		WFD_MSG_ERR("OPENING SECURE SESSION\n");
+		flags |= VCD_CP_SESSION;
+	}
+	if (vcd_get_ion_status()) {
+		client_ctx->user_ion_client = vcd_get_ion_client();
+		if (!client_ctx->user_ion_client) {
+			WFD_MSG_ERR("vcd_open ion get client failed");
+			return -EFAULT;
+		}
+	}
+
+	rc = vcd_open(venc_p.device_handle, false, venc_cb,
+				inst, flags);
+	if (rc) {
+		WFD_MSG_ERR("vcd_open failed, rc = %d\n", rc);
+		rc = -ENODEV;
+		goto no_free_client;
+	}
+	wait_for_completion(&client_ctx->event);
+	if (client_ctx->event_status) {
+		WFD_MSG_ERR("callback for vcd_open returned error: %u",
+				client_ctx->event_status);
+		goto no_free_client;
+	}
+	WFD_MSG_ERR("NOTE: client_ctx = %p\n", client_ctx);
+	vmops->cookie = inst;
+	sd->dev_priv = inst;
+no_free_client:
+	mutex_unlock(&venc_p.lock);
+	return rc;
+}
+
+static long venc_close(struct v4l2_subdev *sd, void *arg)
+{
+	long rc = 0;
+	struct venc_inst *inst;
+	struct video_client_ctx *client_ctx = NULL;
+	mutex_lock(&venc_p.lock);
+	inst = sd->dev_priv;
+	client_ctx = &inst->venc_client;
+	if (!client_ctx || !client_ctx->vcd_handle) {
+		WFD_MSG_ERR("Invalid client context in close\n");
+		rc = -ENODEV;
+		goto end;
+	}
+	rc = vcd_close(client_ctx->vcd_handle);
+	if (rc) {
+		WFD_MSG_ERR("Failed to close encoder subdevice\n");
+		goto end;
+	}
+	memset((void *)client_ctx, 0,
+			sizeof(struct video_client_ctx));
+end:
+	mutex_unlock(&venc_p.lock);
+	return rc;
+}
+
+static long venc_get_buffer_req(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0;
+	struct v4l2_requestbuffers *b = arg;
+	struct vcd_buffer_requirement buf_req;
+	struct venc_inst *inst = sd->dev_priv;
+	struct video_client_ctx *client_ctx = &inst->venc_client;
+	if (!client_ctx) {
+		WFD_MSG_ERR("Invalid client context");
+		rc = -EINVAL;
+		goto err;
+	}
+	rc = vcd_get_buffer_requirements(client_ctx->vcd_handle,
+			VCD_BUFFER_OUTPUT, &buf_req);
+	if (rc) {
+		WFD_MSG_ERR("Failed to get out buf reqs rc = %d", rc);
+		goto err;
+	}
+
+	buf_req.actual_count = b->count = max(buf_req.min_count, b->count);
+	rc = vcd_set_buffer_requirements(client_ctx->vcd_handle,
+			VCD_BUFFER_OUTPUT, &buf_req);
+	if (rc) {
+		WFD_MSG_ERR("Failed to set out buf reqs rc = %d", rc);
+		goto err;
+	}
+
+err:
+	return rc;
+}
+
+static long venc_set_buffer_req(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0;
+	struct bufreq *b = arg;
+	struct vcd_buffer_requirement buf_req;
+	struct venc_inst *inst = sd->dev_priv;
+	struct video_client_ctx *client_ctx = &inst->venc_client;
+	int aligned_width, aligned_height;
+	if (!client_ctx) {
+		WFD_MSG_ERR("Invalid client context");
+		rc = -EINVAL;
+		goto err;
+	}
+	aligned_width = ALIGN(b->width, 16);
+	aligned_height = ALIGN(b->height, 16);
+
+	if (aligned_width != b->width) {
+		WFD_MSG_ERR("Width not 16 byte aligned\n");
+		rc = -EINVAL;
+		goto err;
+	}
+
+	buf_req.actual_count = b->count;
+	buf_req.min_count = b->count;
+	buf_req.max_count = b->count;
+	buf_req.sz = ALIGN(aligned_height * aligned_width, SZ_2K)
+		+ ALIGN(aligned_height * aligned_width * 1/2, SZ_2K);
+	buf_req.align = SZ_4K;
+	inst->width = b->width;
+	inst->height = b->height;
+	rc = vcd_set_buffer_requirements(client_ctx->vcd_handle,
+			VCD_BUFFER_INPUT, &buf_req);
+	if (rc) {
+		WFD_MSG_ERR("Failed to get out buf reqs rc = %d", rc);
+		goto err;
+	}
+	b->size = buf_req.sz;
+err:
+	return rc;
+}
+
+static long venc_start(struct v4l2_subdev *sd)
+{
+	struct venc_inst *inst = sd->dev_priv;
+	struct video_client_ctx *client_ctx = &inst->venc_client;
+	struct mem_region *curr = NULL, *temp = NULL;
+	int rc;
+	if (!client_ctx) {
+		WFD_MSG_ERR("Client context is NULL");
+		return -EINVAL;
+	}
+
+	rc = vcd_encode_start(client_ctx->vcd_handle);
+	if (rc) {
+		WFD_MSG_ERR("vcd_encode_start failed, rc = %d\n", rc);
+		goto err;
+	}
+	wait_for_completion(&client_ctx->event);
+	if (client_ctx->event_status)
+		WFD_MSG_ERR("callback for vcd_encode_start returned error: %u",
+				client_ctx->event_status);
+
+	inst->streaming = true;
+	/* Push any buffers that we have held back */
+	list_for_each_entry_safe(curr, temp,
+			&inst->unqueued_op_bufs.list, list) {
+		venc_fill_outbuf(sd, curr);
+		list_del(&curr->list);
+		kfree(curr);
+	}
+err:
+	return rc;
+}
+
+static long venc_stop(struct v4l2_subdev *sd)
+{
+	struct venc_inst *inst = sd->dev_priv;
+	struct video_client_ctx *client_ctx = &inst->venc_client;
+	struct mem_region *curr = NULL, *temp = NULL;
+	int rc;
+	if (!client_ctx) {
+		WFD_MSG_ERR("Client context is NULL");
+		return -EINVAL;
+	}
+	rc = vcd_stop(client_ctx->vcd_handle);
+	wait_for_completion(&client_ctx->event);
+	inst->streaming = false;
+	/* Drop whatever frames we haven't queued */
+	list_for_each_entry_safe(curr, temp,
+			&inst->unqueued_op_bufs.list, list) {
+		inst->op_buffer_done(inst->cbdata, 0,
+				(struct vb2_buffer *)curr->cookie);
+		list_del(&curr->list);
+		kfree(curr);
+	}
+	return rc;
+}
+
+static long venc_set_codec(struct video_client_ctx *client_ctx, __s32 codec)
+{
+	struct vcd_property_codec vcd_property_codec;
+	struct vcd_property_hdr vcd_property_hdr;
+	vcd_property_hdr.prop_id = VCD_I_CODEC;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
+	vcd_property_codec.codec = VCD_CODEC_H264;
+
+	switch (codec) {
+	case V4L2_PIX_FMT_H264:
+		vcd_property_codec.codec = VCD_CODEC_H264;
+		break;
+	case V4L2_PIX_FMT_MPEG4:
+		vcd_property_codec.codec = VCD_CODEC_MPEG4;
+		break;
+	default:
+		WFD_MSG_ERR("Codec not supported, defaulting to h264\n");
+		break;
+	}
+	return vcd_set_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_property_codec);
+}
+
+static long venc_set_codec_level(struct video_client_ctx *client_ctx,
+					__s32 codec, __s32 level)
+{
+	struct vcd_property_level vcd_property_level;
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_codec vcd_property_codec;
+
+	int rc = 0;
+	int mpeg4_base = VCD_LEVEL_MPEG4_0;
+	int h264_base = VCD_LEVEL_H264_1;
+
+	/* Validate params */
+	vcd_property_hdr.prop_id = VCD_I_CODEC;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
+	rc = vcd_get_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_property_codec);
+
+	if (rc < 0) {
+		WFD_MSG_ERR("Error getting codec property");
+		rc = -EINVAL;
+		goto err;
+	}
+
+	if (!((vcd_property_codec.codec == VCD_CODEC_H264
+		&& codec == V4L2_CID_MPEG_VIDEO_H264_LEVEL) ||
+		(vcd_property_codec.codec == VCD_CODEC_MPEG4
+		&& codec == V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL))) {
+		WFD_MSG_ERR("Attempting to set %d for codec type %d",
+			codec, vcd_property_codec.codec);
+		rc = -EINVAL;
+		goto err;
+	}
+
+	/* Set property */
+	vcd_property_hdr.prop_id = VCD_I_LEVEL;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_level);
+
+	if (codec == V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL) {
+		vcd_property_level.level = mpeg4_base + level;
+
+		if (vcd_property_level.level < VCD_LEVEL_MPEG4_0
+			|| vcd_property_level.level > VCD_LEVEL_MPEG4_X) {
+			WFD_MSG_ERR("Level (%d) out of range for codec (%d)\n",
+					level, codec);
+
+			rc = -EINVAL;
+			goto err;
+		}
+	} else if (codec == V4L2_CID_MPEG_VIDEO_H264_LEVEL) {
+		vcd_property_level.level = h264_base + level;
+
+		if (vcd_property_level.level < VCD_LEVEL_H264_1
+			|| vcd_property_level.level > VCD_LEVEL_H264_5p1) {
+			WFD_MSG_ERR("Level (%d) out of range for codec (%d)\n",
+					level, codec);
+
+			rc = -EINVAL;
+			goto err;
+		}
+	} else {
+		WFD_MSG_ERR("Codec (%d) not supported, not setting level (%d)",
+				codec, level);
+		rc = -ENOTSUPP;
+		goto err;
+	}
+
+	rc = vcd_set_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_property_level);
+err:
+	return rc;
+}
+
+static long venc_get_codec_level(struct video_client_ctx *client_ctx,
+					__s32 codec, __s32 *level)
+{
+	struct vcd_property_level vcd_property_level;
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_codec vcd_property_codec;
+
+	int rc = 0;
+	int mpeg4_base = VCD_LEVEL_MPEG4_0;
+	int h264_base = VCD_LEVEL_H264_1;
+
+	/* Validate params */
+	vcd_property_hdr.prop_id = VCD_I_CODEC;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
+	rc = vcd_get_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_property_codec);
+
+	if (rc < 0) {
+		WFD_MSG_ERR("Error getting codec property");
+		rc = -EINVAL;
+		goto err;
+	}
+
+	if (!((vcd_property_codec.codec == VCD_CODEC_H264
+		&& codec == V4L2_CID_MPEG_VIDEO_H264_LEVEL) ||
+		(vcd_property_codec.codec == VCD_CODEC_MPEG4
+		&& codec == V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL))) {
+		WFD_MSG_ERR("Attempting to get %d for codec type %d",
+			codec, vcd_property_codec.codec);
+		rc = -EINVAL;
+		goto err;
+	}
+
+	vcd_property_hdr.prop_id = VCD_I_LEVEL;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_level);
+
+	rc = vcd_get_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_property_level);
+	if (rc < 0) {
+		rc = -EINVAL;
+		goto err;
+	}
+
+	if (codec == V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL) {
+		*level = vcd_property_level.level - mpeg4_base;
+	} else if (codec == V4L2_CID_MPEG_VIDEO_H264_LEVEL) {
+		*level = vcd_property_level.level - h264_base;
+	} else {
+		WFD_MSG_ERR("Codec (%d) not supported", codec);
+		rc = -ENOTSUPP;
+		goto err;
+	}
+
+err:
+	return rc;
+}
+
+static long venc_set_codec_profile(struct video_client_ctx *client_ctx,
+					__s32 codec, __s32 profile)
+{
+	struct vcd_property_profile vcd_property_profile;
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_codec vcd_property_codec;
+	struct vcd_property_i_period vcd_property_i_period;
+	int rc = 0;
+
+	/* Validate params */
+	vcd_property_hdr.prop_id = VCD_I_CODEC;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
+	rc = vcd_get_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_property_codec);
+
+	if (rc < 0) {
+		WFD_MSG_ERR("Error getting codec property");
+		rc = -EINVAL;
+		goto err_set_profile;
+	}
+
+	if (!((vcd_property_codec.codec == VCD_CODEC_H264
+		&& codec == V4L2_CID_MPEG_VIDEO_H264_PROFILE) ||
+		(vcd_property_codec.codec == VCD_CODEC_MPEG4
+		&& codec == V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE))) {
+		WFD_MSG_ERR("Attempting to set %d for codec type %d",
+			codec, vcd_property_codec.codec);
+		rc = -EINVAL;
+		goto err_set_profile;
+	}
+
+	/* Set property */
+	vcd_property_hdr.prop_id = VCD_I_PROFILE;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_profile);
+
+	if (codec == V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE) {
+		switch (profile) {
+		case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
+			vcd_property_profile.profile = VCD_PROFILE_MPEG4_SP;
+			break;
+		case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
+			vcd_property_profile.profile = VCD_PROFILE_MPEG4_ASP;
+			break;
+		default:
+			WFD_MSG_ERR("Profile %d not supported, defaulting " \
+					"to simple (%d)", profile,
+					VCD_PROFILE_MPEG4_SP);
+			vcd_property_profile.profile = VCD_PROFILE_MPEG4_SP;
+			break;
+		}
+	} else if (codec == V4L2_CID_MPEG_VIDEO_H264_PROFILE) {
+		switch (profile) {
+		case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
+			vcd_property_profile.profile =
+				VCD_PROFILE_H264_BASELINE;
+			break;
+		case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
+			vcd_property_profile.profile = VCD_PROFILE_H264_MAIN;
+			break;
+		case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
+			vcd_property_profile.profile = VCD_PROFILE_H264_HIGH;
+			break;
+		default:
+			WFD_MSG_ERR("Profile %d not supported, defaulting " \
+					"to baseline (%d)", profile,
+					VCD_PROFILE_H264_BASELINE);
+			vcd_property_profile.profile =
+				VCD_PROFILE_H264_BASELINE;
+			break;
+		}
+	} else {
+		WFD_MSG_ERR("Codec (%d) not supported, not "\
+				"setting profile (%d)",	codec, profile);
+		rc = -ENOTSUPP;
+		goto err_set_profile;
+	}
+
+	rc = vcd_set_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_property_profile);
+
+	/* Disable B-frames, since VSG doesn't support out of order i/p bufs */
+	vcd_property_hdr.prop_id = VCD_I_INTRA_PERIOD;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_i_period);
+
+	rc = vcd_get_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_property_i_period);
+	if (rc) {
+		WFD_MSG_ERR("Error getting I-period property");
+		goto err_set_profile;
+	}
+	vcd_property_i_period.b_frames = 0;
+	rc = vcd_set_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_property_i_period);
+	if (rc) {
+		WFD_MSG_ERR("Error setting I-period property");
+		goto err_set_profile;
+	}
+
+err_set_profile:
+	return rc;
+}
+
+static long venc_get_codec_profile(struct video_client_ctx *client_ctx,
+		__s32 codec, __s32 *profile)
+{
+	struct vcd_property_profile vcd_property_profile;
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_codec vcd_property_codec;
+	int rc = 0;
+
+	/* Validate params */
+	vcd_property_hdr.prop_id = VCD_I_CODEC;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
+	rc = vcd_get_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_property_codec);
+
+	if (rc < 0) {
+		WFD_MSG_ERR("Error getting codec property");
+		rc = -EINVAL;
+		goto err;
+	}
+
+	if (!((vcd_property_codec.codec == VCD_CODEC_H264
+		&& codec == V4L2_CID_MPEG_VIDEO_H264_PROFILE) ||
+		(vcd_property_codec.codec == VCD_CODEC_MPEG4
+		&& codec == V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE))) {
+		WFD_MSG_ERR("Attempting to set %d for codec type %d",
+			codec, vcd_property_codec.codec);
+		rc = -EINVAL;
+		goto err;
+	}
+
+	/* Set property */
+	vcd_property_hdr.prop_id = VCD_I_PROFILE;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_profile);
+
+	rc = vcd_get_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_property_profile);
+
+	if (rc < 0) {
+		WFD_MSG_ERR("Unable to get property");
+		rc = -EINVAL;
+		goto err;
+	}
+
+	switch (vcd_property_profile.profile) {
+	case VCD_PROFILE_MPEG4_SP:
+		*profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
+		break;
+	case VCD_PROFILE_MPEG4_ASP:
+		*profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE;
+		break;
+	case VCD_PROFILE_H264_BASELINE:
+		*profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
+		break;
+	case VCD_PROFILE_H264_MAIN:
+		*profile = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
+		break;
+	case VCD_PROFILE_H264_HIGH:
+		*profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
+		break;
+	default:
+		WFD_MSG_ERR("Unexpected profile");
+		rc = -EINVAL;
+		goto err;
+		break;
+	}
+err:
+	return rc;
+}
+
+static long venc_set_h264_intra_period(struct video_client_ctx *client_ctx,
+		__s32 period)
+{
+	struct vcd_property_i_period vcd_property_i_period;
+	struct vcd_property_codec vcd_property_codec;
+	struct vcd_property_hdr vcd_property_hdr;
+	int rc = 0;
+
+	vcd_property_hdr.prop_id = VCD_I_CODEC;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
+
+	rc = vcd_get_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_property_codec);
+
+	if (rc < 0) {
+		WFD_MSG_ERR("Error getting codec property\n");
+		goto err;
+	}
+
+	if (vcd_property_codec.codec != VCD_CODEC_H264) {
+		rc = -ENOTSUPP;
+		WFD_MSG_ERR("Control not supported for non H264 codec\n");
+		goto err;
+	}
+
+	vcd_property_hdr.prop_id = VCD_I_INTRA_PERIOD;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_i_period);
+
+	vcd_property_i_period.p_frames = period - 1;
+	vcd_property_i_period.b_frames = 0;
+
+	rc = vcd_set_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_property_i_period);
+
+	if (rc < 0) {
+		WFD_MSG_ERR("Error setting intra period\n");
+		goto err;
+	}
+
+err:
+	return rc;
+}
+
+static long venc_get_h264_intra_period(struct video_client_ctx *client_ctx,
+		__s32 *period)
+{
+	struct vcd_property_i_period vcd_property_i_period;
+	struct vcd_property_codec vcd_property_codec;
+	struct vcd_property_hdr vcd_property_hdr;
+	int rc = 0;
+
+	vcd_property_hdr.prop_id = VCD_I_CODEC;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
+
+	rc = vcd_get_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_property_codec);
+
+	if (rc < 0) {
+		WFD_MSG_ERR("Error getting codec property\n");
+		goto err;
+	}
+
+	if (vcd_property_codec.codec != VCD_CODEC_H264) {
+		rc = -ENOTSUPP;
+		WFD_MSG_ERR("Control not supported for non H264 codec\n");
+		goto err;
+	}
+
+	vcd_property_hdr.prop_id = VCD_I_INTRA_PERIOD;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_i_period);
+
+	rc = vcd_get_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_property_i_period);
+
+	if (rc < 0) {
+		WFD_MSG_ERR("Error getting intra period\n");
+		goto err;
+	}
+
+	*period = vcd_property_i_period.p_frames + 1;
+err:
+	return rc;
+}
+
+static long venc_request_frame(struct video_client_ctx *client_ctx, __s32 type)
+{
+	struct vcd_property_req_i_frame vcd_property_req_i_frame;
+	struct vcd_property_hdr vcd_property_hdr;
+
+	vcd_property_hdr.prop_id = VCD_I_REQ_IFRAME;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_req_i_frame);
+	vcd_property_req_i_frame.req_i_frame = 1;
+
+	return vcd_set_property(client_ctx->vcd_handle,
+			&vcd_property_hdr, &vcd_property_req_i_frame);
+
+}
+
+static long venc_set_bitrate(struct video_client_ctx *client_ctx,
+			__s32 bitrate)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_target_bitrate bit_rate;
+	if (!client_ctx || !bitrate)
+		return -EINVAL;
+
+	vcd_property_hdr.prop_id = VCD_I_TARGET_BITRATE;
+	vcd_property_hdr.sz =
+			sizeof(struct vcd_property_target_bitrate);
+	bit_rate.target_bitrate = bitrate;
+	return vcd_set_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &bit_rate);
+}
+
+static long venc_get_bitrate(struct video_client_ctx *client_ctx,
+			__s32 *bitrate)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_target_bitrate bit_rate;
+	int rc = 0;
+
+	if (!client_ctx || !bitrate)
+		return -EINVAL;
+
+	vcd_property_hdr.prop_id = VCD_I_TARGET_BITRATE;
+	vcd_property_hdr.sz =
+			sizeof(struct vcd_property_target_bitrate);
+	rc = vcd_get_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &bit_rate);
+
+	if (rc < 0) {
+		WFD_MSG_ERR("Failed getting property for bitrate");
+		return rc;
+	}
+
+	*bitrate = bit_rate.target_bitrate;
+	return rc;
+}
+
+static long venc_set_bitrate_mode(struct video_client_ctx *client_ctx,
+			__s32 mode)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_rate_control rate_control;
+	int rc = 0;
+
+	if (!client_ctx) {
+		rc = -EINVAL;
+		goto err;
+	}
+
+	vcd_property_hdr.prop_id = VCD_I_RATE_CONTROL;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_rate_control);
+	/*
+	 * XXX: V4L doesn't seem have a control to toggle between CFR
+	 * and VFR, so assuming worse case VFR.
+	 */
+	switch (mode) {
+	case V4L2_MPEG_VIDEO_BITRATE_MODE_VBR:
+		rate_control.rate_control = VCD_RATE_CONTROL_VBR_VFR;
+		break;
+	case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR:
+		rate_control.rate_control = VCD_RATE_CONTROL_CBR_VFR;
+		break;
+	default:
+		WFD_MSG_ERR("unknown bitrate mode %d", mode);
+		rc = -EINVAL;
+		goto err;
+	}
+
+	rc = vcd_set_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &rate_control);
+err:
+	return rc;
+}
+
+static long venc_get_bitrate_mode(struct video_client_ctx *client_ctx,
+			__s32 *mode)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_rate_control rate_control;
+	int rc = 0;
+
+	if (!client_ctx)
+		return -EINVAL;
+
+	vcd_property_hdr.prop_id = VCD_I_RATE_CONTROL;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_rate_control);
+	rc = vcd_get_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &rate_control);
+
+	switch (rate_control.rate_control) {
+	case VCD_RATE_CONTROL_CBR_VFR:
+	case VCD_RATE_CONTROL_CBR_CFR:
+		*mode = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
+		break;
+	case VCD_RATE_CONTROL_VBR_VFR:
+	case VCD_RATE_CONTROL_VBR_CFR:
+		*mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR;
+		break;
+	default:
+		WFD_MSG_ERR("unknown bitrate mode %d",
+				rate_control.rate_control);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static long venc_set_frame_size(struct video_client_ctx *client_ctx,
+				u32 height, u32 width)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_frame_size frame_size;
+	vcd_property_hdr.prop_id = VCD_I_FRAME_SIZE;
+	vcd_property_hdr.sz =
+		sizeof(struct vcd_property_frame_size);
+	frame_size.height = height;
+	frame_size.width = width;
+	return vcd_set_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &frame_size);
+}
+
+static long venc_set_format(struct v4l2_subdev *sd, void *arg)
+{
+	struct venc_inst *inst;
+	struct video_client_ctx *client_ctx;
+	struct v4l2_format *fmt = arg;
+	struct vcd_buffer_requirement buf_req;
+	int rc = 0;
+
+	inst = sd->dev_priv;
+	client_ctx = &inst->venc_client;
+	if (!inst || !client_ctx || !fmt) {
+		WFD_MSG_ERR("Invalid parameters\n");
+		return -EINVAL;
+	}
+	rc = venc_set_codec(client_ctx, fmt->fmt.pix.pixelformat);
+	if (rc) {
+		WFD_MSG_ERR("Failed to set codec, rc = %d\n", rc);
+		goto err;
+	}
+
+	rc = venc_set_frame_size(client_ctx, fmt->fmt.pix.height,
+				fmt->fmt.pix.width);
+	if (rc) {
+		WFD_MSG_ERR("Failed to set frame size, rc = %d\n", rc);
+		goto err;
+	}
+	rc = vcd_get_buffer_requirements(client_ctx->vcd_handle,
+			VCD_BUFFER_OUTPUT, &buf_req);
+	if (rc) {
+		WFD_MSG_ERR("Failed to get buf requrements, rc = %d\n", rc);
+		goto err;
+	}
+	fmt->fmt.pix.sizeimage = buf_req.sz;
+err:
+	return rc;
+}
+
+static long venc_set_framerate(struct v4l2_subdev *sd,
+				void *arg)
+{
+	struct venc_inst *inst = sd->dev_priv;
+	struct video_client_ctx *client_ctx = &inst->venc_client;
+	struct v4l2_fract *frate = arg;
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_frame_rate vcd_frame_rate;
+	struct vcd_property_vop_timing_constant_delta vcd_delta;
+	int rc;
+	vcd_property_hdr.prop_id = VCD_I_FRAME_RATE;
+	vcd_property_hdr.sz =
+				sizeof(struct vcd_property_frame_rate);
+	/* v4l2 passes in "fps" as "spf", so take reciprocal*/
+	vcd_frame_rate.fps_denominator = frate->numerator;
+	vcd_frame_rate.fps_numerator = frate->denominator;
+	rc = vcd_set_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &vcd_frame_rate);
+	if (rc) {
+		WFD_MSG_ERR("Failed to set frame rate, rc = %d\n", rc);
+		goto set_framerate_fail;
+	}
+
+	vcd_property_hdr.prop_id = VCD_I_VOP_TIMING_CONSTANT_DELTA;
+	vcd_property_hdr.sz = sizeof(vcd_delta);
+
+	vcd_delta.constant_delta = (frate->numerator * USEC_PER_SEC) /
+					frate->denominator;
+	rc = vcd_set_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &vcd_delta);
+
+	if (rc) {
+		WFD_MSG_ERR("Failed to set frame delta, rc = %d", rc);
+		goto set_framerate_fail;
+	}
+
+set_framerate_fail:
+	return rc;
+}
+
+static long venc_set_framerate_mode(struct v4l2_subdev *sd,
+				void *arg)
+{
+	struct venc_inst *inst = sd->dev_priv;
+	inst->framerate_mode = *(enum venc_framerate_modes *)arg;
+	return 0;
+}
+
+static long venc_set_qp_value(struct video_client_ctx *client_ctx,
+		__s32 frametype, __s32 qp)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_session_qp vcd_property_session_qp;
+	int rc = 0;
+
+	if (!client_ctx) {
+		WFD_MSG_ERR("Invalid parameters\n");
+		return -EINVAL;
+	}
+
+	vcd_property_hdr.prop_id = VCD_I_SESSION_QP;
+	vcd_property_hdr.sz = sizeof(vcd_property_session_qp);
+
+	rc = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
+			&vcd_property_session_qp);
+
+	if (rc) {
+		WFD_MSG_ERR("Failed to get session qp\n");
+		goto err;
+	}
+
+	switch (frametype) {
+	case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
+		vcd_property_session_qp.i_frame_qp = qp;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
+		vcd_property_session_qp.p_frame_qp = qp;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
+		vcd_property_session_qp.b_frame_qp = qp;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP:
+	case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP:
+	case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP:
+	case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP:
+	case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP:
+	case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP:
+		rc = -ENOTSUPP;
+		goto err;
+	default:
+		rc = -EINVAL;
+		goto err;
+	}
+
+
+	rc = vcd_set_property(client_ctx->vcd_handle, &vcd_property_hdr,
+			&vcd_property_session_qp);
+
+	if (rc) {
+		WFD_MSG_ERR("Failed to set session qp\n");
+		goto err;
+	}
+err:
+	return rc;
+}
+
+static long venc_get_qp_value(struct video_client_ctx *client_ctx,
+		__s32 frametype, __s32 *qp)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_session_qp vcd_property_session_qp;
+	int rc = 0;
+
+	if (!client_ctx) {
+		WFD_MSG_ERR("Invalid parameters\n");
+		return -EINVAL;
+	}
+
+	vcd_property_hdr.prop_id = VCD_I_SESSION_QP;
+	vcd_property_hdr.sz = sizeof(vcd_property_session_qp);
+
+	rc = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
+			&vcd_property_session_qp);
+
+	if (rc) {
+		WFD_MSG_ERR("Failed to get session qp\n");
+		goto err;
+	}
+
+	switch (frametype) {
+	case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP:
+	case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP:
+	case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
+		*qp = vcd_property_session_qp.i_frame_qp;
+		break;
+	case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP:
+	case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP:
+	case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
+		*qp = vcd_property_session_qp.p_frame_qp;
+		break;
+	case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP:
+	case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP:
+	case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
+		*qp = vcd_property_session_qp.b_frame_qp;
+		break;
+	default:
+		rc = -EINVAL;
+		goto err;
+	}
+
+err:
+	return rc;
+}
+
+static long venc_set_qp_range(struct video_client_ctx *client_ctx,
+		__s32 type, __s32 qp)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_qp_range vcd_property_qp_range;
+	int rc = 0;
+
+	if (!client_ctx) {
+		WFD_MSG_ERR("Invalid parameters\n");
+		return -EINVAL;
+	}
+
+	vcd_property_hdr.prop_id = VCD_I_QP_RANGE;
+	vcd_property_hdr.sz = sizeof(vcd_property_qp_range);
+
+	rc = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
+			&vcd_property_qp_range);
+
+	if (rc) {
+		WFD_MSG_ERR("Failed to get qp range\n");
+		goto err;
+	}
+
+	switch (type) {
+	case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP:
+	case V4L2_CID_MPEG_VIDEO_H263_MIN_QP:
+	case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
+		vcd_property_qp_range.min_qp = qp;
+		break;
+	case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP:
+	case V4L2_CID_MPEG_VIDEO_H263_MAX_QP:
+	case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
+		vcd_property_qp_range.max_qp = qp;
+		break;
+	default:
+		rc = -EINVAL;
+		goto err;
+	}
+
+	rc = vcd_set_property(client_ctx->vcd_handle, &vcd_property_hdr,
+			&vcd_property_qp_range);
+
+	if (rc) {
+		WFD_MSG_ERR("Failed to set qp range\n");
+		goto err;
+	}
+err:
+	return rc;
+}
+
+static long venc_get_qp_range(struct video_client_ctx *client_ctx,
+		__s32 type, __s32 *qp)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_qp_range vcd_property_qp_range;
+	int rc = 0;
+
+	if (!client_ctx) {
+		WFD_MSG_ERR("Invalid parameters\n");
+		return -EINVAL;
+	}
+
+	vcd_property_hdr.prop_id = VCD_I_QP_RANGE;
+	vcd_property_hdr.sz = sizeof(vcd_property_qp_range);
+
+	rc = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
+			&vcd_property_qp_range);
+
+	if (rc) {
+		WFD_MSG_ERR("Failed to get qp range\n");
+		goto err;
+	}
+
+	switch (type) {
+	case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP:
+	case V4L2_CID_MPEG_VIDEO_H263_MIN_QP:
+	case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
+		*qp = vcd_property_qp_range.min_qp;
+		break;
+	case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP:
+	case V4L2_CID_MPEG_VIDEO_H263_MAX_QP:
+	case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
+		*qp = vcd_property_qp_range.max_qp;
+		break;
+	default:
+		rc = -EINVAL;
+		goto err;
+	}
+
+	rc = vcd_set_property(client_ctx->vcd_handle, &vcd_property_hdr,
+			&vcd_property_qp_range);
+
+	if (rc) {
+		WFD_MSG_ERR("Failed to set qp range\n");
+		goto err;
+	}
+err:
+	return rc;
+}
+static long venc_set_max_perf_level(struct video_client_ctx *client_ctx,
+		__s32 value)
+{
+	int rc = 0;
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_perf_level perf;
+	int level = 0;
+
+	switch (value) {
+	case V4L2_CID_MPEG_VIDC_PERF_LEVEL_PERFORMANCE:
+		level = VCD_PERF_LEVEL2;
+		break;
+	case V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO:
+		level = VCD_PERF_LEVEL_TURBO;
+		break;
+	default:
+		WFD_MSG_ERR("Unknown performance level: %d\n", value);
+		rc = -ENOTSUPP;
+		goto err_set_perf_level;
+	}
+
+	vcd_property_hdr.prop_id = VCD_REQ_PERF_LEVEL;
+	vcd_property_hdr.sz =
+		sizeof(struct vcd_property_perf_level);
+	perf.level = level;
+	rc = vcd_set_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &perf);
+err_set_perf_level:
+	return rc;
+}
+
+static long venc_set_avc_delimiter(struct video_client_ctx *client_ctx,
+			__s32 flag)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_avc_delimiter_enable delimiter_flag;
+	if (!client_ctx)
+		return -EINVAL;
+
+	vcd_property_hdr.prop_id = VCD_I_ENABLE_DELIMITER_FLAG;
+	vcd_property_hdr.sz =
+			sizeof(struct vcd_property_avc_delimiter_enable);
+	delimiter_flag.avc_delimiter_enable_flag = flag;
+	return vcd_set_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &delimiter_flag);
+}
+
+static long venc_get_avc_delimiter(struct video_client_ctx *client_ctx,
+			__s32 *flag)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_avc_delimiter_enable delimiter_flag;
+	int rc = 0;
+
+	if (!client_ctx || !flag)
+		return -EINVAL;
+
+	vcd_property_hdr.prop_id = VCD_I_ENABLE_DELIMITER_FLAG;
+	vcd_property_hdr.sz =
+			sizeof(struct vcd_property_avc_delimiter_enable);
+	rc = vcd_get_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &delimiter_flag);
+
+	if (rc < 0) {
+		WFD_MSG_ERR("Failed getting property for delimiter");
+		return rc;
+	}
+
+	*flag = delimiter_flag.avc_delimiter_enable_flag;
+	return rc;
+}
+
+static long venc_set_vui_timing_info(struct video_client_ctx *client_ctx,
+			struct venc_inst *inst, __s32 flag)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_vui_timing_info_enable vui_timing_info_enable;
+
+	if (!client_ctx)
+		return -EINVAL;
+	if (inst->framerate_mode == VENC_MODE_VFR) {
+		WFD_MSG_ERR("VUI timing info not suported in VFR mode ");
+		return -EINVAL;
+	}
+	vcd_property_hdr.prop_id = VCD_I_ENABLE_VUI_TIMING_INFO;
+	vcd_property_hdr.sz =
+			sizeof(struct vcd_property_vui_timing_info_enable);
+	vui_timing_info_enable.vui_timing_info = flag;
+	return vcd_set_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vui_timing_info_enable);
+}
+
+static long venc_get_vui_timing_info(struct video_client_ctx *client_ctx,
+			__s32 *flag)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_vui_timing_info_enable vui_timing_info_enable;
+	int rc = 0;
+
+	if (!client_ctx || !flag)
+		return -EINVAL;
+
+	vcd_property_hdr.prop_id = VCD_I_ENABLE_VUI_TIMING_INFO;
+	vcd_property_hdr.sz =
+			sizeof(struct vcd_property_vui_timing_info_enable);
+	rc = vcd_get_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vui_timing_info_enable);
+
+	if (rc < 0) {
+		WFD_MSG_ERR("Failed getting property for VUI timing info");
+		return rc;
+	}
+
+	*flag = vui_timing_info_enable.vui_timing_info;
+	return rc;
+}
+
+static long venc_set_header_mode(struct video_client_ctx *client_ctx,
+		__s32 mode)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_sps_pps_for_idr_enable sps_pps_for_idr_enable;
+	int rc = 0;
+
+	if (!client_ctx) {
+		WFD_MSG_ERR("Invalid parameters\n");
+		rc = -EINVAL;
+		goto err;
+	}
+
+	vcd_property_hdr.prop_id = VCD_I_ENABLE_SPS_PPS_FOR_IDR;
+	vcd_property_hdr.sz = sizeof(sps_pps_for_idr_enable);
+	switch (mode) {
+	case V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE:
+		sps_pps_for_idr_enable.sps_pps_for_idr_enable_flag = 0;
+		break;
+	case V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME:
+		sps_pps_for_idr_enable.sps_pps_for_idr_enable_flag = 1;
+		break;
+	case V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME:
+	default:
+		WFD_MSG_ERR("Video header mode %d not supported\n",
+				mode);
+		rc = -ENOTSUPP;
+		goto err;
+	}
+
+	rc =  vcd_set_property(client_ctx->vcd_handle, &vcd_property_hdr,
+			&sps_pps_for_idr_enable);
+	if (rc) {
+		WFD_MSG_ERR("Failed to set enable_sps_pps_for_idr\n");
+		goto err;
+	}
+err:
+	return rc;
+}
+
+static long venc_get_header_mode(struct video_client_ctx *client_ctx,
+		__s32 *mode)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_sps_pps_for_idr_enable sps_pps_for_idr_enable;
+	int rc = 0;
+
+	if (!client_ctx) {
+		WFD_MSG_ERR("Invalid parameters\n");
+		rc = -EINVAL;
+		goto err;
+	}
+
+	vcd_property_hdr.prop_id = VCD_I_ENABLE_SPS_PPS_FOR_IDR;
+	vcd_property_hdr.sz = sizeof(sps_pps_for_idr_enable);
+	rc =  vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
+			&sps_pps_for_idr_enable);
+	if (rc) {
+		WFD_MSG_ERR("Failed to get sps/pps for idr enable\n");
+		goto err;
+	}
+
+	*mode = sps_pps_for_idr_enable.sps_pps_for_idr_enable_flag ?
+		V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME :
+		V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
+err:
+	return rc;
+}
+
+static long venc_set_multislicing_mode(struct video_client_ctx *client_ctx,
+			__u32 control, __s32 value)
+{
+	int rc = 0;
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_frame_size vcd_frame_size;
+	struct vcd_buffer_requirement vcd_buf_req;
+	struct vcd_property_multi_slice vcd_multi_slice;
+
+	if (!client_ctx) {
+		WFD_MSG_ERR("Invalid parameters\n");
+		rc = -EINVAL;
+		goto set_multislicing_mode_fail;
+	}
+
+	vcd_property_hdr.prop_id = VCD_I_FRAME_SIZE;
+	vcd_property_hdr.sz =
+		sizeof(vcd_frame_size);
+	rc = vcd_get_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_frame_size);
+
+	if (rc) {
+		WFD_MSG_ERR("Failed to get frame size\n");
+		goto set_multislicing_mode_fail;
+	}
+
+	rc = vcd_get_buffer_requirements(client_ctx->vcd_handle,
+			VCD_BUFFER_OUTPUT, &vcd_buf_req);
+
+	if (rc) {
+		WFD_MSG_ERR("Failed to get buf reqs\n");
+		goto set_multislicing_mode_fail;
+	}
+
+	vcd_property_hdr.prop_id = VCD_I_MULTI_SLICE;
+	vcd_property_hdr.sz = sizeof(vcd_multi_slice);
+	rc = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
+			&vcd_multi_slice);
+	if (rc) {
+		WFD_MSG_ERR("Failed to get multi slice\n");
+		goto set_multislicing_mode_fail;
+	}
+
+	switch (control) {
+	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
+		if (vcd_multi_slice.m_slice_sel !=
+				VCD_MSLICE_BY_BYTE_COUNT) {
+			WFD_MSG_ERR("Not in proper mode\n");
+			goto set_multislicing_mode_fail;
+		}
+		vcd_multi_slice.m_slice_size = value;
+		break;
+
+	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
+		if (vcd_multi_slice.m_slice_sel !=
+				VCD_MSLICE_BY_MB_COUNT) {
+			WFD_MSG_ERR("Not in proper mode\n");
+			goto set_multislicing_mode_fail;
+		}
+		vcd_multi_slice.m_slice_size = value;
+		break;
+
+	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
+		switch (value) {
+		case V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE:
+			vcd_multi_slice.m_slice_sel = VCD_MSLICE_OFF;
+			break;
+		case V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB:
+			vcd_multi_slice.m_slice_sel = VCD_MSLICE_BY_MB_COUNT;
+			/* Just a temporary size until client calls
+			 * V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB */
+			vcd_multi_slice.m_slice_size =
+				(vcd_frame_size.stride / 16) *
+				(vcd_frame_size.scan_lines / 16);
+			break;
+		case V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES:
+			vcd_multi_slice.m_slice_sel = VCD_MSLICE_BY_BYTE_COUNT;
+			/* Just a temporary size until client calls
+			 * V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES */
+			vcd_multi_slice.m_slice_size = vcd_buf_req.sz;
+			break;
+		default:
+			WFD_MSG_ERR("Unrecognized mode %d\n", value);
+			rc = -ENOTSUPP;
+			goto set_multislicing_mode_fail;
+		}
+
+		break;
+	default:
+		rc = -EINVAL;
+		goto set_multislicing_mode_fail;
+	}
+
+	rc = vcd_set_property(client_ctx->vcd_handle, &vcd_property_hdr,
+			&vcd_multi_slice);
+	if (rc) {
+		WFD_MSG_ERR("Failed to set multi slice\n");
+		goto set_multislicing_mode_fail;
+	}
+
+set_multislicing_mode_fail:
+	return rc;
+}
+
+static long venc_get_multislicing_mode(struct video_client_ctx *client_ctx,
+			__u32 control, __s32 *value)
+{
+	int rc = 0;
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_frame_size vcd_frame_size;
+	struct vcd_buffer_requirement vcd_buf_req;
+	struct vcd_property_multi_slice vcd_multi_slice;
+
+	if (!client_ctx) {
+		WFD_MSG_ERR("Invalid parameters\n");
+		rc = -EINVAL;
+		goto get_multislicing_mode_fail;
+	}
+
+	vcd_property_hdr.prop_id = VCD_I_FRAME_SIZE;
+	vcd_property_hdr.sz =
+		sizeof(vcd_frame_size);
+	rc = vcd_get_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_frame_size);
+
+	if (rc) {
+		WFD_MSG_ERR("Failed to get frame size\n");
+		goto get_multislicing_mode_fail;
+	}
+
+	vcd_property_hdr.prop_id = VCD_I_MULTI_SLICE;
+	vcd_property_hdr.sz = sizeof(vcd_multi_slice);
+	rc = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
+			&vcd_multi_slice);
+	if (rc) {
+		WFD_MSG_ERR("Failed to get multi slice\n");
+		goto get_multislicing_mode_fail;
+	}
+
+	rc = vcd_get_buffer_requirements(client_ctx->vcd_handle,
+			VCD_BUFFER_OUTPUT, &vcd_buf_req);
+
+	if (rc) {
+		WFD_MSG_ERR("Failed to get buf reqs\n");
+		goto get_multislicing_mode_fail;
+	}
+
+	switch (control) {
+	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
+		if (vcd_multi_slice.m_slice_sel == VCD_MSLICE_BY_BYTE_COUNT)
+			*value = vcd_multi_slice.m_slice_size;
+		else {
+			WFD_MSG_ERR("Invalid query when in slice mode %d\n",
+					vcd_multi_slice.m_slice_sel);
+			rc = -EINVAL;
+			goto get_multislicing_mode_fail;
+		}
+		break;
+
+	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
+		if (vcd_multi_slice.m_slice_sel == VCD_MSLICE_BY_MB_COUNT)
+			*value = vcd_multi_slice.m_slice_size;
+		else {
+			WFD_MSG_ERR("Invalid query when in slice mode %d\n",
+					vcd_multi_slice.m_slice_sel);
+			rc = -EINVAL;
+			goto get_multislicing_mode_fail;
+		}
+		break;
+
+	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
+		switch (vcd_multi_slice.m_slice_sel) {
+		case VCD_MSLICE_OFF:
+			*value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
+			break;
+		case VCD_MSLICE_BY_MB_COUNT:
+			*value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB;
+			break;
+		case VCD_MSLICE_BY_BYTE_COUNT:
+			*value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES;
+			break;
+		default:
+			WFD_MSG_ERR("Encoder in an unknown mode %d\n",
+					vcd_multi_slice.m_slice_sel);
+			rc = -ENOENT;
+			goto get_multislicing_mode_fail;
+
+		}
+		break;
+	default:
+		rc = -EINVAL;
+		goto get_multislicing_mode_fail;
+	}
+
+get_multislicing_mode_fail:
+	return rc;
+}
+
+static long venc_set_entropy_mode(struct video_client_ctx *client_ctx,
+		__s32 value)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_entropy_control entropy_control;
+	int rc = 0;
+
+	if (!client_ctx) {
+		WFD_MSG_ERR("Invalid parameters\n");
+		rc = -EINVAL;
+		goto set_entropy_mode_fail;
+	}
+
+	vcd_property_hdr.prop_id = VCD_I_ENTROPY_CTRL;
+	vcd_property_hdr.sz = sizeof(entropy_control);
+
+	switch (value) {
+	case V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC:
+		entropy_control.entropy_sel = VCD_ENTROPY_SEL_CAVLC;
+		break;
+	case V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC:
+		entropy_control.entropy_sel = VCD_ENTROPY_SEL_CABAC;
+		entropy_control.cabac_model = VCD_CABAC_MODEL_NUMBER_0;
+		break;
+	default:
+		WFD_MSG_ERR("Entropy type %d not supported\n", value);
+		rc = -ENOTSUPP;
+		goto set_entropy_mode_fail;
+	}
+	rc = vcd_set_property(client_ctx->vcd_handle, &vcd_property_hdr,
+			&entropy_control);
+	if (rc) {
+		WFD_MSG_ERR("Failed to set entropy mode\n");
+		goto set_entropy_mode_fail;
+	}
+
+set_entropy_mode_fail:
+	return rc;
+}
+
+static long venc_get_entropy_mode(struct video_client_ctx *client_ctx,
+		__s32 *value)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_entropy_control entropy_control;
+	int rc = 0;
+
+	if (!client_ctx || !value) {
+		WFD_MSG_ERR("Invalid parameters\n");
+		rc = -EINVAL;
+		goto get_entropy_mode_fail;
+	}
+
+	vcd_property_hdr.prop_id = VCD_I_ENTROPY_CTRL;
+	vcd_property_hdr.sz = sizeof(entropy_control);
+
+	rc = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
+			&entropy_control);
+
+	if (rc) {
+		WFD_MSG_ERR("Failed to get entropy mode\n");
+		goto get_entropy_mode_fail;
+	}
+
+	switch (entropy_control.entropy_sel) {
+	case VCD_ENTROPY_SEL_CAVLC:
+		*value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
+		break;
+	case VCD_ENTROPY_SEL_CABAC:
+		*value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC;
+		break;
+	default:
+		WFD_MSG_ERR("Entropy type %d not known\n",
+				entropy_control.entropy_sel);
+		rc = -EINVAL;
+		goto get_entropy_mode_fail;
+	}
+get_entropy_mode_fail:
+	return rc;
+}
+
+static long venc_set_cyclic_intra_refresh_mb(
+		struct video_client_ctx *client_ctx,
+		__s32 value)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_intra_refresh_mb_number cir_mb_num;
+	int rc = 0;
+
+	if (!client_ctx) {
+		WFD_MSG_ERR("Invalid parameters\n");
+		rc = -EINVAL;
+		goto set_cir_mbs_fail;
+	}
+
+	vcd_property_hdr.prop_id = VCD_I_INTRA_REFRESH;
+	vcd_property_hdr.sz = sizeof(cir_mb_num);
+
+	cir_mb_num.cir_mb_number = value;
+
+	rc = vcd_set_property(client_ctx->vcd_handle, &vcd_property_hdr,
+			&cir_mb_num);
+	if (rc) {
+		WFD_MSG_ERR("Failed to set CIR MBs\n");
+		goto set_cir_mbs_fail;
+	}
+
+set_cir_mbs_fail:
+	return rc;
+}
+
+static long venc_get_cyclic_intra_refresh_mb(
+		struct video_client_ctx *client_ctx,
+		__s32 *value)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_intra_refresh_mb_number cir_mb_num;
+	int rc = 0;
+
+	if (!client_ctx || !value) {
+		WFD_MSG_ERR("Invalid parameters\n");
+		rc = -EINVAL;
+		goto get_cir_mbs_fail;
+	}
+
+	vcd_property_hdr.prop_id = VCD_I_INTRA_REFRESH;
+	vcd_property_hdr.sz = sizeof(cir_mb_num);
+
+	rc = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
+			&cir_mb_num);
+	if (rc) {
+		WFD_MSG_ERR("Failed to set CIR MBs\n");
+		goto get_cir_mbs_fail;
+	}
+
+	*value = cir_mb_num.cir_mb_number;
+
+get_cir_mbs_fail:
+	return rc;
+}
+static long venc_set_input_buffer(struct v4l2_subdev *sd, void *arg)
+{
+	struct mem_region *mregion = arg;
+	struct venc_inst *inst = sd->dev_priv;
+	unsigned long paddr, kvaddr, temp;
+	struct video_client_ctx *client_ctx = &inst->venc_client;
+	int rc = 0;
+
+	if (!client_ctx || !mregion) {
+		WFD_MSG_ERR("Invalid input\n");
+		rc = -EINVAL;
+		goto ins_table_fail;
+	}
+
+	kvaddr = (unsigned long)mregion->kvaddr;
+	paddr = (unsigned long)mregion->paddr;
+
+	if (!kvaddr || !paddr) {
+		WFD_MSG_ERR("Invalid addresses\n");
+		rc = -EINVAL;
+		goto ins_table_fail;
+	}
+
+	/*
+	 * Just a note: the third arg of vidc_insert_\
+	 * addr_table_kernel is supposed to be a userspace
+	 * address that is used as a key in the table. As
+	 * these bufs never leave the kernel, we need to have
+	 * an unique value to use as a key.  So re-using kernel
+	 * virtual addr for this purpose
+	 */
+	rc = vidc_insert_addr_table_kernel(client_ctx,
+		BUFFER_TYPE_INPUT, kvaddr, kvaddr,
+		paddr, 32, mregion->size);
+
+	if (rc == (u32)false) {
+		WFD_MSG_ERR("Failed to insert input buffer into table\n");
+		rc = -EFAULT;
+		goto ins_table_fail;
+	}
+
+	rc = vcd_set_buffer(client_ctx->vcd_handle,
+			VCD_BUFFER_INPUT, (u8 *)kvaddr,
+			mregion->size);
+
+	if (rc) {
+		WFD_MSG_ERR("Failed to set input buffer\n");
+		rc = -EFAULT;
+		goto set_input_buf_fail;
+	}
+
+
+	return rc;
+
+set_input_buf_fail:
+	vidc_delete_addr_table(client_ctx, BUFFER_TYPE_INPUT,
+			kvaddr, &temp);
+ins_table_fail:
+	return rc;
+}
+
+static long venc_set_output_buffer(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0;
+	struct venc_inst *inst = sd->dev_priv;
+	struct video_client_ctx *client_ctx = &inst->venc_client;
+	struct mem_region *mregion = arg;
+	if (!client_ctx || !mregion) {
+		WFD_MSG_ERR("Invalid input\n");
+		return -EINVAL;
+	}
+	WFD_MSG_DBG("size = %u, offset = %u fd = %d\n", mregion->size,
+				mregion->offset, mregion->fd);
+	rc = vidc_insert_addr_table(client_ctx, BUFFER_TYPE_OUTPUT,
+					mregion->cookie,
+					(unsigned long *)&mregion->kvaddr,
+					mregion->fd,
+					mregion->offset,
+					32,
+					mregion->size);
+	if (rc == (u32)false) {
+		WFD_MSG_ERR("Failed to insert outbuf in table\n");
+		rc = -EINVAL;
+		goto err;
+	}
+	WFD_MSG_DBG("size = %u, %p\n", mregion->size, mregion->kvaddr);
+
+	rc = vcd_set_buffer(client_ctx->vcd_handle,
+				    VCD_BUFFER_OUTPUT, (u8 *) mregion->kvaddr,
+				    mregion->size);
+	if (rc)
+		WFD_MSG_ERR("Failed to set outbuf on encoder\n");
+err:
+	return rc;
+}
+
+static long venc_fill_outbuf(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0;
+	struct venc_inst *inst = sd->dev_priv;
+	struct video_client_ctx *client_ctx = &inst->venc_client;
+	struct mem_region *mregion = arg;
+	struct vcd_frame_data vcd_frame = {0};
+	unsigned long kernel_vaddr, phy_addr, user_vaddr;
+	int pmem_fd;
+	struct file *file;
+	s32 buffer_index = -1;
+
+	if (inst->streaming) {
+		user_vaddr = mregion->cookie;
+		rc = vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT,
+				true, &user_vaddr,
+				&kernel_vaddr, &phy_addr, &pmem_fd, &file,
+				&buffer_index);
+		if (!rc) {
+			WFD_MSG_ERR("Address lookup failed\n");
+			goto err;
+		}
+		vcd_frame.virtual = (u8 *) kernel_vaddr;
+		vcd_frame.frm_clnt_data = mregion->cookie;
+		vcd_frame.alloc_len = mregion->size;
+
+		rc = vcd_fill_output_buffer(client_ctx->vcd_handle, &vcd_frame);
+		if (rc)
+			WFD_MSG_ERR("Failed to fill output buffer on encoder");
+	} else {
+		struct mem_region *temp = kzalloc(sizeof(*temp), GFP_KERNEL);
+		*temp = *mregion;
+		INIT_LIST_HEAD(&temp->list);
+		list_add_tail(&temp->list, &inst->unqueued_op_bufs.list);
+	}
+err:
+	return rc;
+}
+
+static long venc_encode_frame(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0;
+	struct venc_inst *inst = sd->dev_priv;
+	struct video_client_ctx *client_ctx = &inst->venc_client;
+	struct venc_buf_info *venc_buf = arg;
+	struct mem_region *mregion = venc_buf->mregion;
+	struct vcd_frame_data vcd_input_buffer = {0};
+	int64_t ts = 0;
+
+	ts = venc_buf->timestamp;
+	do_div(ts, NSEC_PER_USEC);
+
+	vcd_input_buffer.virtual = mregion->kvaddr;
+	vcd_input_buffer.frm_clnt_data = (u32)mregion;
+	vcd_input_buffer.ip_frm_tag = (u32)mregion;
+	vcd_input_buffer.data_len = mregion->size;
+	vcd_input_buffer.time_stamp = ts;
+	vcd_input_buffer.offset = 0;
+
+	rc = vcd_encode_frame(client_ctx->vcd_handle,
+			&vcd_input_buffer);
+
+	if (rc)
+		WFD_MSG_ERR("encode frame failed\n");
+	return rc;
+}
+
+static long venc_alloc_recon_buffers(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0;
+	struct venc_inst *inst = sd->dev_priv;
+	struct video_client_ctx *client_ctx = &inst->venc_client;
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_buffer_size control;
+	struct vcd_property_enc_recon_buffer *ctrl = NULL;
+	unsigned long phy_addr;
+	int i = 0;
+	int heap_mask = 0;
+	u32 ion_flags = 0;
+	u32 len;
+	control.width = inst->width;
+	control.height = inst->height;
+	vcd_property_hdr.prop_id = VCD_I_GET_RECON_BUFFER_SIZE;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size);
+
+	rc = vcd_get_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &control);
+	if (rc) {
+		WFD_MSG_ERR("Failed to get recon buf size\n");
+		goto err;
+	}
+	heap_mask = ION_HEAP(ION_CP_MM_HEAP_ID);
+	heap_mask |= inst->secure ? 0 : ION_HEAP(ION_IOMMU_HEAP_ID);
+	ion_flags |= inst->secure ? ION_SECURE : 0;
+
+	if (vcd_get_ion_status()) {
+		for (i = 0; i < 4; ++i) {
+			ctrl = &client_ctx->recon_buffer[i];
+			ctrl->buffer_size = control.size;
+			ctrl->pmem_fd = 0;
+			ctrl->offset = 0;
+			ctrl->user_virtual_addr = (void *)i;
+			client_ctx->recon_buffer_ion_handle[i]
+				= ion_alloc(client_ctx->user_ion_client,
+			control.size, SZ_8K, heap_mask, ion_flags);
+
+			ctrl->kernel_virtual_addr = ion_map_kernel(
+				client_ctx->user_ion_client,
+				client_ctx->recon_buffer_ion_handle[i]);
+
+			if (IS_ERR_OR_NULL(ctrl->kernel_virtual_addr)) {
+				WFD_MSG_ERR("ion map kernel failed\n");
+				rc = -EINVAL;
+				goto free_ion_alloc;
+			}
+
+			if (inst->secure) {
+				rc = ion_phys(client_ctx->user_ion_client,
+					client_ctx->recon_buffer_ion_handle[i],
+					&phy_addr, (size_t *)&len);
+				if (rc || !phy_addr) {
+					WFD_MSG_ERR("ion physical failed\n");
+					goto unmap_ion_alloc;
+				}
+			} else {
+				rc = ion_map_iommu(client_ctx->user_ion_client,
+					client_ctx->recon_buffer_ion_handle[i],
+					VIDEO_DOMAIN, VIDEO_MAIN_POOL, SZ_4K,
+					0, &phy_addr, (unsigned long *)&len,
+					0, 0);
+				 if (rc || !phy_addr) {
+					WFD_MSG_ERR(
+						"ion map iommu failed, rc = %d, phy_addr = 0x%lx\n",
+						rc, phy_addr);
+					goto unmap_ion_alloc;
+				}
+
+			}
+			ctrl->physical_addr =  (u8 *) phy_addr;
+			ctrl->dev_addr = ctrl->physical_addr;
+			vcd_property_hdr.prop_id = VCD_I_RECON_BUFFERS;
+			vcd_property_hdr.sz =
+				sizeof(struct vcd_property_enc_recon_buffer);
+			rc = vcd_set_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, ctrl);
+			if (rc) {
+				WFD_MSG_ERR("Failed to set recon buffers\n");
+				goto unmap_ion_iommu;
+			}
+		}
+	} else {
+		WFD_MSG_ERR("PMEM not suported\n");
+		return -ENOMEM;
+	}
+	return rc;
+unmap_ion_iommu:
+	if (!inst->secure) {
+		if (client_ctx->recon_buffer_ion_handle[i]) {
+			ion_unmap_iommu(client_ctx->user_ion_client,
+				client_ctx->recon_buffer_ion_handle[i],
+				VIDEO_DOMAIN, VIDEO_MAIN_POOL);
+		}
+	}
+unmap_ion_alloc:
+	if (client_ctx->recon_buffer_ion_handle[i]) {
+		ion_unmap_kernel(client_ctx->user_ion_client,
+			client_ctx->recon_buffer_ion_handle[i]);
+		ctrl->kernel_virtual_addr = NULL;
+		ctrl->physical_addr = NULL;
+	}
+free_ion_alloc:
+	if (client_ctx->recon_buffer_ion_handle[i]) {
+		ion_free(client_ctx->user_ion_client,
+			client_ctx->recon_buffer_ion_handle[i]);
+		client_ctx->recon_buffer_ion_handle[i] = NULL;
+	}
+	WFD_MSG_ERR("Failed to allo recon buffers\n");
+err:
+	return rc;
+}
+
+static long venc_free_output_buffer(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0;
+	struct venc_inst *inst = sd->dev_priv;
+	struct video_client_ctx *client_ctx = &inst->venc_client;
+	struct mem_region *mregion = arg;
+	unsigned long kernel_vaddr, user_vaddr;
+
+	if (!client_ctx || !mregion) {
+		WFD_MSG_ERR("Invalid input\n");
+		return -EINVAL;
+	}
+
+	user_vaddr = mregion->cookie;
+	rc = vidc_delete_addr_table(client_ctx, BUFFER_TYPE_OUTPUT,
+				user_vaddr,
+				&kernel_vaddr);
+	if (!rc) {
+		WFD_MSG_ERR("Failed to delete buf from address table\n");
+		return -EINVAL;
+	}
+	return vcd_free_buffer(client_ctx->vcd_handle, VCD_BUFFER_OUTPUT,
+					 (u8 *)kernel_vaddr);
+}
+
+static long venc_flush_buffers(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0;
+	struct venc_inst *inst = sd->dev_priv;
+	struct video_client_ctx *client_ctx = &inst->venc_client;
+	if (!client_ctx) {
+		WFD_MSG_ERR("Invalid input\n");
+		return -EINVAL;
+	}
+	rc = vcd_flush(client_ctx->vcd_handle, VCD_FLUSH_INPUT);
+	if (rc) {
+		WFD_MSG_ERR("Failed to flush input buffers\n");
+		rc = -EIO;
+		goto flush_failed;
+	}
+	wait_for_completion(&client_ctx->event);
+	if (client_ctx->event_status) {
+		WFD_MSG_ERR("callback for vcd_flush input returned error: %u",
+				client_ctx->event_status);
+		rc = -EIO;
+		goto flush_failed;
+	}
+	rc = vcd_flush(client_ctx->vcd_handle, VCD_FLUSH_OUTPUT);
+	if (rc) {
+		WFD_MSG_ERR("Failed to flush output buffers\n");
+		rc = -EIO;
+		goto flush_failed;
+	}
+	wait_for_completion(&client_ctx->event);
+	if (client_ctx->event_status) {
+		WFD_MSG_ERR("callback for vcd_flush output returned error: %u",
+				client_ctx->event_status);
+		rc = -EIO;
+		goto flush_failed;
+	}
+
+flush_failed:
+	return rc;
+}
+
+static long venc_free_input_buffer(struct v4l2_subdev *sd, void *arg)
+{
+	int del_rc = 0, free_rc = 0;
+	struct venc_inst *inst = sd->dev_priv;
+	struct video_client_ctx *client_ctx = &inst->venc_client;
+	struct mem_region *mregion = arg;
+	unsigned long vidc_kvaddr;
+
+	if (!client_ctx || !mregion) {
+		WFD_MSG_ERR("Invalid input\n");
+		return -EINVAL;
+	}
+
+	del_rc = vidc_delete_addr_table(client_ctx, BUFFER_TYPE_INPUT,
+				(unsigned long)mregion->kvaddr,
+				&vidc_kvaddr);
+	/*
+	 * Even if something went wrong in when
+	 * deleting from table, call vcd_free_buf
+	 */
+	if (del_rc == (u32)false) {
+		WFD_MSG_ERR("Failed to delete buf from address table\n");
+		del_rc = -ENOKEY;
+	} else if ((u8 *)vidc_kvaddr != mregion->kvaddr) {
+		WFD_MSG_ERR("Failed to find expected buffer\n");
+		del_rc = -EINVAL;
+	} else
+		del_rc = 0;
+
+	free_rc = vcd_free_buffer(client_ctx->vcd_handle, VCD_BUFFER_INPUT,
+					 (u8 *)vidc_kvaddr);
+
+	if (free_rc) {
+		WFD_MSG_ERR("Failed to free buffer from encoder\n");
+		free_rc = -EINVAL;
+	}
+
+	return del_rc ? del_rc : free_rc;
+}
+
+static long venc_free_recon_buffers(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0;
+	struct venc_inst *inst = sd->dev_priv;
+	struct video_client_ctx *client_ctx = &inst->venc_client;
+	struct vcd_property_hdr vcd_property_hdr;
+	int i;
+
+	if (vcd_get_ion_status()) {
+		for (i = 0; i < 4; i++) {
+			vcd_property_hdr.prop_id = VCD_I_FREE_RECON_BUFFERS;
+			vcd_property_hdr.sz =
+				sizeof(struct vcd_property_buffer_size);
+			rc = vcd_set_property(client_ctx->vcd_handle,
+			&vcd_property_hdr, &client_ctx->recon_buffer[i]);
+			if (rc)
+				WFD_MSG_ERR("Failed to free recon buffer\n");
+
+			if (!IS_ERR_OR_NULL(
+				client_ctx->recon_buffer_ion_handle[i])) {
+				if (!inst->secure) {
+					ion_unmap_iommu(
+					client_ctx->user_ion_client,
+					client_ctx->recon_buffer_ion_handle[i],
+					VIDEO_DOMAIN, VIDEO_MAIN_POOL);
+				}
+				ion_unmap_kernel(client_ctx->user_ion_client,
+					client_ctx->recon_buffer_ion_handle[i]);
+				ion_free(client_ctx->user_ion_client,
+					client_ctx->recon_buffer_ion_handle[i]);
+				client_ctx->recon_buffer_ion_handle[i] = NULL;
+			}
+		}
+	}
+	return rc;
+}
+
+static long venc_set_property(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0;
+	struct venc_inst *inst = sd->dev_priv;
+	struct v4l2_control *ctrl = arg;
+	struct video_client_ctx *client_ctx = &inst->venc_client;
+	switch (ctrl->id) {
+	case V4L2_CID_MPEG_VIDEO_BITRATE:
+		rc = venc_set_bitrate(client_ctx, ctrl->value);
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+		rc = venc_set_bitrate_mode(client_ctx, ctrl->value);
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:
+		rc = venc_set_h264_intra_period(client_ctx, ctrl->value);
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
+		rc = venc_set_codec_level(client_ctx, ctrl->id, ctrl->value);
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
+		rc = venc_set_codec_profile(client_ctx, ctrl->id, ctrl->value);
+		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME:
+		rc = venc_request_frame(client_ctx, ctrl->value);
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
+	case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
+	case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
+	case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP:
+	case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP:
+	case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP:
+	case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP:
+	case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP:
+	case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP:
+		rc = venc_set_qp_value(client_ctx, ctrl->id, ctrl->value);
+		break;
+	case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP:
+	case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP:
+	case V4L2_CID_MPEG_VIDEO_H263_MIN_QP:
+	case V4L2_CID_MPEG_VIDEO_H263_MAX_QP:
+	case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
+	case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
+		rc = venc_set_qp_range(client_ctx, ctrl->id, ctrl->value);
+		break;
+	case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
+		rc = venc_set_header_mode(client_ctx, ctrl->value);
+		break;
+	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
+	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
+	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
+		rc = venc_set_multislicing_mode(client_ctx, ctrl->id,
+				ctrl->value);
+		break;
+	case V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL:
+		rc = venc_set_max_perf_level(client_ctx, ctrl->value);
+		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_H264_AU_DELIMITER:
+		rc = venc_set_avc_delimiter(client_ctx, ctrl->value);
+		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO:
+		rc = venc_set_vui_timing_info(client_ctx, inst, ctrl->value);
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
+		rc = venc_set_entropy_mode(client_ctx, ctrl->value);
+		break;
+	case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
+		rc = venc_set_cyclic_intra_refresh_mb(client_ctx, ctrl->value);
+		break;
+	default:
+		WFD_MSG_ERR("Set property not suported: %d\n", ctrl->id);
+		rc = -ENOTSUPP;
+		break;
+	}
+	return rc;
+}
+
+static long venc_get_property(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0;
+	struct venc_inst *inst = sd->dev_priv;
+	struct v4l2_control *ctrl = arg;
+	struct video_client_ctx *client_ctx = &inst->venc_client;
+
+	switch (ctrl->id) {
+	case V4L2_CID_MPEG_VIDEO_BITRATE:
+		rc = venc_get_bitrate(client_ctx, &ctrl->value);
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+		rc = venc_get_bitrate_mode(client_ctx, &ctrl->value);
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
+		rc = venc_get_codec_level(client_ctx, ctrl->id, &ctrl->value);
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
+		rc = venc_get_codec_profile(client_ctx, ctrl->id, &ctrl->value);
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:
+		rc = venc_get_h264_intra_period(client_ctx, &ctrl->value);
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
+	case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
+	case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
+	case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP:
+	case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP:
+	case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP:
+	case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP:
+	case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP:
+	case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP:
+		rc = venc_get_qp_value(client_ctx, ctrl->id, &ctrl->value);
+		break;
+	case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP:
+	case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP:
+	case V4L2_CID_MPEG_VIDEO_H263_MIN_QP:
+	case V4L2_CID_MPEG_VIDEO_H263_MAX_QP:
+	case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
+	case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
+		rc = venc_get_qp_range(client_ctx, ctrl->id, &ctrl->value);
+		break;
+	case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
+		rc = venc_get_header_mode(client_ctx, &ctrl->value);
+		break;
+	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
+	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
+	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
+		rc = venc_get_multislicing_mode(client_ctx, ctrl->id,
+				&ctrl->value);
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
+		rc = venc_get_entropy_mode(client_ctx, &ctrl->value);
+		break;
+	case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
+		rc = venc_get_cyclic_intra_refresh_mb(client_ctx, &ctrl->value);
+		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_H264_AU_DELIMITER:
+		rc = venc_get_avc_delimiter(client_ctx, &ctrl->value);
+		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO:
+		rc = venc_get_vui_timing_info(client_ctx, &ctrl->value);
+		break;
+	default:
+		WFD_MSG_ERR("Get property not suported: %d\n", ctrl->id);
+		rc = -ENOTSUPP;
+		break;
+	}
+	return rc;
+}
+
+long venc_mmap(struct v4l2_subdev *sd, void *arg)
+{
+	struct venc_inst *inst = sd->dev_priv;
+	struct mem_region_map *mmap = arg;
+	struct mem_region *mregion = NULL;
+	unsigned long rc = 0, size = 0;
+	void *paddr = NULL;
+
+	if (!sd) {
+		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+		return -EINVAL;
+	} else if (!mmap || !mmap->mregion) {
+		WFD_MSG_ERR("Memregion required for %s\n", __func__);
+		return -EINVAL;
+	}
+
+	mregion = mmap->mregion;
+	if (mregion->size % SZ_4K != 0) {
+		WFD_MSG_ERR("Memregion not aligned to %d\n", SZ_4K);
+		return -EINVAL;
+	}
+
+	if (inst->secure) {
+		rc = ion_phys(mmap->ion_client, mregion->ion_handle,
+				(unsigned long *)&paddr,
+				(size_t *)&size);
+	} else {
+		rc = ion_map_iommu(mmap->ion_client, mregion->ion_handle,
+				VIDEO_DOMAIN, VIDEO_MAIN_POOL, SZ_4K,
+				0, (unsigned long *)&paddr,
+				&size, 0, 0);
+	}
+
+	if (rc) {
+		WFD_MSG_ERR("Failed to get physical addr\n");
+		paddr = NULL;
+	} else if (size < mregion->size) {
+		WFD_MSG_ERR("Failed to map enough memory\n");
+		rc = -ENOMEM;
+	}
+
+	mregion->paddr = paddr;
+	return rc;
+}
+
+long venc_munmap(struct v4l2_subdev *sd, void *arg)
+{
+	struct venc_inst *inst = sd->dev_priv;
+	struct mem_region_map *mmap = arg;
+	struct mem_region *mregion = NULL;
+	if (!sd) {
+		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+		return -EINVAL;
+	} else if (!mregion) {
+		WFD_MSG_ERR("Memregion required for %s\n", __func__);
+		return -EINVAL;
+	}
+
+	mregion = mmap->mregion;
+	if (!inst->secure) {
+		ion_unmap_iommu(mmap->ion_client, mregion->ion_handle,
+				VIDEO_DOMAIN, VIDEO_MAIN_POOL);
+	}
+
+	return 0;
+}
+
+long venc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+	long rc = 0;
+	switch (cmd) {
+	case OPEN:
+		rc = venc_open(sd, arg);
+		break;
+	case CLOSE:
+		rc = venc_close(sd, arg);
+		break;
+	case ENCODE_START:
+		rc = venc_start(sd);
+		break;
+	case ENCODE_FRAME:
+		venc_encode_frame(sd, arg);
+		break;
+	case ENCODE_STOP:
+		rc = venc_stop(sd);
+		break;
+	case SET_PROP:
+		rc = venc_set_property(sd, arg);
+		break;
+	case GET_PROP:
+		rc = venc_get_property(sd, arg);
+		break;
+	case GET_BUFFER_REQ:
+		rc = venc_get_buffer_req(sd, arg);
+		break;
+	case SET_BUFFER_REQ:
+		rc = venc_set_buffer_req(sd, arg);
+		break;
+	case FREE_BUFFER:
+		break;
+	case FILL_OUTPUT_BUFFER:
+		rc = venc_fill_outbuf(sd, arg);
+		break;
+	case SET_FORMAT:
+		rc = venc_set_format(sd, arg);
+		break;
+	case SET_FRAMERATE:
+		rc = venc_set_framerate(sd, arg);
+		break;
+	case SET_INPUT_BUFFER:
+		rc = venc_set_input_buffer(sd, arg);
+		break;
+	case SET_OUTPUT_BUFFER:
+		rc = venc_set_output_buffer(sd, arg);
+		break;
+	case ALLOC_RECON_BUFFERS:
+		rc = venc_alloc_recon_buffers(sd, arg);
+		break;
+	case FREE_OUTPUT_BUFFER:
+		rc = venc_free_output_buffer(sd, arg);
+		break;
+	case FREE_INPUT_BUFFER:
+		rc = venc_free_input_buffer(sd, arg);
+		break;
+	case FREE_RECON_BUFFERS:
+		rc = venc_free_recon_buffers(sd, arg);
+		break;
+	case ENCODE_FLUSH:
+		rc = venc_flush_buffers(sd, arg);
+		break;
+	case ENC_MMAP:
+		rc = venc_mmap(sd, arg);
+		break;
+	case ENC_MUNMAP:
+		rc = venc_munmap(sd, arg);
+		break;
+	case SET_FRAMERATE_MODE:
+		rc = venc_set_framerate_mode(sd, arg);
+		break;
+	default:
+		rc = -1;
+		break;
+	}
+	return rc;
+}
diff --git a/drivers/media/platform/msm/wfd/enc-subdev.h b/drivers/media/platform/msm/wfd/enc-subdev.h
new file mode 100644
index 0000000..8bfb884
--- /dev/null
+++ b/drivers/media/platform/msm/wfd/enc-subdev.h
@@ -0,0 +1,119 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 and
+* only version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+*/
+
+#ifndef _WFD_ENC_SUBDEV_
+#define _WFD_ENC_SUBDEV_
+
+#include <linux/list.h>
+#include <linux/msm_ion.h>
+#include <media/v4l2-subdev.h>
+#include <media/videobuf2-core.h>
+#define VENC_MAGIC_IOCTL 'V'
+
+enum venc_framerate_modes {
+	VENC_MODE_CFR,
+	VENC_MODE_VFR,
+};
+
+struct mem_region {
+	struct list_head list;
+	u8 *kvaddr;
+	u8 *paddr;
+	u32 size;
+	u32 offset;
+	u32 fd;
+	u32 cookie;
+	struct ion_handle *ion_handle;
+};
+
+/* FIXME: need to come with a less stupid name */
+struct mem_region_map {
+	struct mem_region *mregion;
+	struct ion_client *ion_client;
+	uint32_t flags;
+	void *cookie;
+};
+
+struct bufreq {
+	u32 count;
+	u32 height;
+	u32 width;
+	u32 size;
+};
+
+struct venc_buf_info {
+	u64 timestamp;
+	struct mem_region *mregion;
+};
+
+struct venc_msg_ops {
+	void *cookie;
+	void *cbdata;
+	bool secure;
+	void (*op_buffer_done)(void *cookie, u32 status,
+			struct vb2_buffer *buf);
+	void (*ip_buffer_done)(void *cookie, u32 status,
+			struct mem_region *mregion);
+};
+
+static inline bool mem_region_equals(struct mem_region *a,
+		struct mem_region *b)
+{
+	if (a == b)
+		return true;
+	else if (a->fd || b->fd)
+		return (a->fd == b->fd) &&
+			(a->offset == b->offset);
+	else if (a->kvaddr || b->kvaddr)
+		return a->kvaddr == b->kvaddr;
+	else if (a->paddr || b->paddr)
+		return a->paddr == b->paddr;
+	else
+		return false;
+}
+
+#define OPEN  _IOR('V', 1, void *)
+#define CLOSE  _IO('V', 2)
+#define ENCODE_START  _IO('V', 3)
+#define ENCODE_FRAME  _IOW('V', 4, struct venc_buf_info *)
+#define PAUSE  _IO('V', 5)
+#define RESUME  _IO('V', 6)
+#define FLUSH  _IO('V', 7)
+#define ENCODE_STOP  _IO('V', 8)
+#define SET_PROP  _IO('V', 9)
+#define GET_PROP  _IO('V', 10)
+#define SET_BUFFER_REQ  _IOWR('V', 11, struct v4l2_requestbuffers *)
+#define GET_BUFFER_REQ  _IOWR('V', 12, struct v4l2_requestbuffers *)
+#define ALLOCATE_BUFFER  _IO('V', 13)
+#define FREE_BUFFER  _IO('V', 14)
+#define FILL_OUTPUT_BUFFER  _IO('V', 15)
+#define SET_FORMAT _IOW('V', 16, struct v4l2_format *)
+#define SET_FRAMERATE _IOW('V', 17, struct v4l2_fract *)
+#define SET_INPUT_BUFFER _IOWR('V', 18, struct mem_region *)
+#define SET_OUTPUT_BUFFER _IOWR('V', 19, struct mem_region *)
+#define ALLOC_RECON_BUFFERS _IO('V', 20)
+#define FREE_OUTPUT_BUFFER _IOWR('V', 21, struct mem_region *)
+#define FREE_INPUT_BUFFER _IOWR('V', 22, struct mem_region *)
+#define FREE_RECON_BUFFERS _IO('V', 23)
+#define ENCODE_FLUSH _IO('V', 24)
+#define ENC_MMAP _IOWR('V', 25, struct mem_region_map *)
+#define ENC_MUNMAP _IOWR('V', 26, struct mem_region_map *)
+#define SET_FRAMERATE_MODE _IO('V', 27)
+#define ENC_SECURE _IO('V', 28)
+
+extern int venc_init(struct v4l2_subdev *sd, u32 val);
+extern int venc_load_fw(struct v4l2_subdev *sd);
+extern long venc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg);
+
+
+#endif /* _WFD_ENC_SUBDEV_ */
diff --git a/drivers/media/platform/msm/wfd/enc-venus-subdev.c b/drivers/media/platform/msm/wfd/enc-venus-subdev.c
new file mode 100644
index 0000000..b41ece6
--- /dev/null
+++ b/drivers/media/platform/msm/wfd/enc-venus-subdev.c
@@ -0,0 +1,1372 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 and
+* only version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+*/
+
+#include <linux/bitmap.h>
+#include <linux/completion.h>
+#include <linux/ion.h>
+#include <linux/kthread.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <mach/iommu_domains.h>
+#include <media/msm_vidc.h>
+#include <media/v4l2-subdev.h>
+#include "enc-subdev.h"
+#include "wfd-util.h"
+
+#define BUF_TYPE_OUTPUT V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
+#define BUF_TYPE_INPUT V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
+
+static struct ion_client *venc_ion_client;
+
+struct index_bitmap {
+	unsigned long *bitmap;
+	int size;
+	int size_bits; /*Size in bits, not necessarily size/8 */
+};
+
+struct venc_inst {
+	void *vidc_context;
+	struct mutex lock;
+	struct venc_msg_ops vmops;
+	struct mem_region registered_input_bufs, registered_output_bufs;
+	struct index_bitmap free_input_indices, free_output_indices;
+	int num_output_planes, num_input_planes;
+	struct task_struct *callback_thread;
+	bool callback_thread_running;
+	struct completion dq_complete, cmd_complete;
+	bool secure;
+	int domain;
+};
+
+int venc_load_fw(struct v4l2_subdev *sd)
+{
+	/*No need to explicitly load the fw */
+	return 0;
+}
+
+int venc_init(struct v4l2_subdev *sd, u32 val)
+{
+	if (!venc_ion_client)
+		venc_ion_client = msm_ion_client_create(-1, "wfd_enc_subdev");
+
+	return venc_ion_client ? 0 : -ENOMEM;
+}
+
+static int next_free_index(struct index_bitmap *index_bitmap)
+{
+	int index = find_first_zero_bit(index_bitmap->bitmap,
+			index_bitmap->size_bits);
+
+	return (index >= index_bitmap->size_bits) ?
+		-1 : index;
+}
+
+static int mark_index_busy(struct index_bitmap *index_bitmap, int index)
+{
+	if (index > index_bitmap->size_bits) {
+		WFD_MSG_WARN("Marking unknown index as busy\n");
+		return -EINVAL;
+	}
+	set_bit(index, index_bitmap->bitmap);
+	return 0;
+}
+
+static int mark_index_free(struct index_bitmap *index_bitmap, int index)
+{
+	if (index > index_bitmap->size_bits) {
+		WFD_MSG_WARN("Marking unknown index as free\n");
+		return -EINVAL;
+	}
+	clear_bit(index, index_bitmap->bitmap);
+	return 0;
+}
+
+static int get_list_len(struct mem_region *list)
+{
+	struct mem_region *curr = NULL;
+	int index = 0;
+	list_for_each_entry(curr, &list->list, list) {
+		++index;
+	}
+
+	return index;
+}
+
+static struct mem_region *get_registered_mregion(struct mem_region *list,
+		struct mem_region *mregion)
+{
+	struct mem_region *curr = NULL;
+	list_for_each_entry(curr, &list->list, list) {
+		if (unlikely(mem_region_equals(curr, mregion)))
+			return curr;
+	}
+
+	return NULL;
+}
+
+static int venc_vidc_callback_thread(void *data)
+{
+	struct venc_inst *inst = data;
+	WFD_MSG_DBG("Starting callback thread\n");
+	while (!kthread_should_stop()) {
+		bool dequeue_buf = false;
+		struct v4l2_buffer buffer = {0};
+		struct v4l2_event event = {0};
+		int num_planes = 0;
+		int flags = msm_vidc_wait(inst->vidc_context);
+
+		if (flags & POLLERR) {
+			WFD_MSG_ERR("Encoder reported error\n");
+			break;
+		}
+
+		if (flags & POLLPRI) {
+			bool bail_out = false;
+
+			msm_vidc_dqevent(inst->vidc_context, &event);
+			if (event.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
+				WFD_MSG_DBG("enc callback thread shutting " \
+						"down normally\n");
+				bail_out = true;
+			} else {
+				WFD_MSG_ERR("Got unknown event %d, ignoring\n",
+						event.id);
+			}
+
+			complete_all(&inst->cmd_complete);
+			if (bail_out)
+				break;
+		}
+
+		if (flags & POLLIN || flags & POLLRDNORM) {
+			buffer.type = BUF_TYPE_OUTPUT;
+			dequeue_buf = true;
+			num_planes = inst->num_output_planes;
+			WFD_MSG_DBG("Output buffer ready!\n");
+		}
+
+		if (flags & POLLOUT || flags & POLLWRNORM) {
+			buffer.type = BUF_TYPE_INPUT;
+			dequeue_buf = true;
+			num_planes = inst->num_input_planes;
+			WFD_MSG_DBG("Input buffer ready!\n");
+		}
+
+		if (dequeue_buf) {
+			int rc = 0;
+			struct v4l2_plane *planes = NULL;
+			struct mem_region *curr = NULL, *mregion = NULL;
+			struct list_head *reg_bufs = NULL;
+			struct index_bitmap *bitmap = NULL;
+
+			planes = kzalloc(sizeof(*planes) * num_planes,
+					GFP_KERNEL);
+			buffer.m.planes = planes;
+			buffer.length = 1;
+			buffer.memory = V4L2_MEMORY_USERPTR;
+			rc = msm_vidc_dqbuf(inst->vidc_context, &buffer);
+
+			if (rc) {
+				WFD_MSG_ERR("Error dequeuing buffer " \
+						"from vidc: %d", rc);
+				goto abort_dequeue;
+			}
+
+			reg_bufs = buffer.type == BUF_TYPE_OUTPUT ?
+				&inst->registered_output_bufs.list :
+				&inst->registered_input_bufs.list;
+
+			bitmap = buffer.type == BUF_TYPE_OUTPUT ?
+				&inst->free_output_indices :
+				&inst->free_input_indices;
+
+			list_for_each_entry(curr, reg_bufs, list) {
+				if ((u32)curr->paddr ==
+						buffer.m.planes[0].m.userptr) {
+					mregion = curr;
+					break;
+				}
+			}
+
+			if (!mregion) {
+				WFD_MSG_ERR("Got done msg for unknown buf\n");
+				goto abort_dequeue;
+			}
+
+			if (buffer.type == BUF_TYPE_OUTPUT &&
+				inst->vmops.op_buffer_done) {
+				struct vb2_buffer *vb =
+					(struct vb2_buffer *)mregion->cookie;
+
+				vb->v4l2_buf.flags = buffer.flags;
+				vb->v4l2_buf.timestamp = buffer.timestamp;
+				vb->v4l2_planes[0].bytesused =
+					buffer.m.planes[0].bytesused;
+
+				inst->vmops.op_buffer_done(
+					inst->vmops.cbdata, 0, vb);
+			} else if (buffer.type == BUF_TYPE_INPUT &&
+					inst->vmops.ip_buffer_done) {
+				inst->vmops.ip_buffer_done(
+						inst->vmops.cbdata,
+						0, mregion);
+			}
+
+			complete_all(&inst->dq_complete);
+			mutex_lock(&inst->lock);
+			mark_index_free(bitmap, buffer.index);
+			mutex_unlock(&inst->lock);
+abort_dequeue:
+			kfree(planes);
+		}
+	}
+
+
+	WFD_MSG_DBG("Exiting callback thread\n");
+	mutex_lock(&inst->lock);
+	inst->callback_thread_running = false;
+	mutex_unlock(&inst->lock);
+	return 0;
+}
+
+static long set_default_properties(struct venc_inst *inst)
+{
+	struct v4l2_control ctrl = {0};
+
+	/* Set the IDR period as 1.  The venus core doesn't give
+	 * the sps/pps for I-frames, only IDR. */
+	ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
+	ctrl.value = 1;
+
+	return msm_vidc_s_ctrl(inst->vidc_context, &ctrl);
+}
+
+static long get_iommu_domain(struct venc_inst *inst)
+{
+	struct msm_vidc_iommu_info maps[MAX_MAP];
+	int rc = msm_vidc_get_iommu_maps(inst->vidc_context, maps);
+	if (rc) {
+		WFD_MSG_ERR("Failed to retreive domain mappings\n");
+		return rc;
+	}
+
+	return maps[inst->secure ? CP_MAP : NS_MAP].domain;
+}
+
+static long venc_open(struct v4l2_subdev *sd, void *arg)
+{
+	struct venc_inst *inst = NULL;
+	struct venc_msg_ops *vmops = arg;
+	struct v4l2_event_subscription event = {0};
+	int rc = 0;
+
+	if (!vmops) {
+		WFD_MSG_ERR("Callbacks required for %s\n", __func__);
+		rc = -EINVAL;
+		goto venc_open_fail;
+	} else if (!sd) {
+		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+		rc = -EINVAL;
+		goto venc_open_fail;
+	}
+
+	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+	if (!inst) {
+		WFD_MSG_ERR("Failed to allocate memory\n");
+		rc = -EINVAL;
+		goto venc_open_fail;
+	}
+
+	inst->secure = false;
+	inst->vmops = *vmops;
+	INIT_LIST_HEAD(&inst->registered_output_bufs.list);
+	INIT_LIST_HEAD(&inst->registered_input_bufs.list);
+	init_completion(&inst->dq_complete);
+	init_completion(&inst->cmd_complete);
+	mutex_init(&inst->lock);
+	inst->vidc_context = msm_vidc_open(MSM_VIDC_CORE_0, MSM_VIDC_ENCODER);
+	if (!inst->vidc_context) {
+		WFD_MSG_ERR("Failed to create vidc context\n");
+		rc = -ENXIO;
+		goto vidc_open_fail;
+	}
+
+	event.type = V4L2_EVENT_MSM_VIDC_CLOSE_DONE;
+	rc = msm_vidc_subscribe_event(inst->vidc_context, &event);
+	if (rc) {
+		WFD_MSG_ERR("Failed to subscribe to CLOSE_DONE event\n");
+		goto vidc_subscribe_fail;
+	}
+
+	event.type = V4L2_EVENT_MSM_VIDC_FLUSH_DONE;
+	rc = msm_vidc_subscribe_event(inst->vidc_context, &event);
+	if (rc) {
+		WFD_MSG_ERR("Failed to subscribe to FLUSH_DONE event\n");
+		goto vidc_subscribe_fail;
+	}
+
+	inst->domain = get_iommu_domain(inst);
+	if (inst->domain < 0) {
+		WFD_MSG_ERR("Failed to get domain\n");
+		goto vidc_subscribe_fail;
+	}
+
+	inst->callback_thread = kthread_run(venc_vidc_callback_thread, inst,
+					"venc_vidc_callback_thread");
+	if (IS_ERR(inst->callback_thread)) {
+		WFD_MSG_ERR("Failed to create callback thread\n");
+		rc = PTR_ERR(inst->callback_thread);
+		inst->callback_thread = NULL;
+		goto vidc_kthread_create_fail;
+	}
+	inst->callback_thread_running = true;
+
+	sd->dev_priv = inst;
+	vmops->cookie = inst;
+	return 0;
+vidc_kthread_create_fail:
+	event.type = V4L2_EVENT_MSM_VIDC_CLOSE_DONE;
+	msm_vidc_unsubscribe_event(inst->vidc_context, &event);
+
+	event.type = V4L2_EVENT_MSM_VIDC_FLUSH_DONE;
+	msm_vidc_unsubscribe_event(inst->vidc_context, &event);
+vidc_subscribe_fail:
+	msm_vidc_close(inst->vidc_context);
+vidc_open_fail:
+	kfree(inst);
+venc_open_fail:
+	return rc;
+}
+
+static long venc_close(struct v4l2_subdev *sd, void *arg)
+{
+	struct venc_inst *inst = NULL;
+	struct v4l2_event_subscription event = {0};
+	struct v4l2_encoder_cmd enc_cmd = {0};
+	int rc = 0;
+
+	if (!sd) {
+		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+		rc = -EINVAL;
+		goto venc_close_fail;
+	}
+
+	inst = (struct venc_inst *)sd->dev_priv;
+	enc_cmd.cmd = V4L2_ENC_CMD_STOP;
+	msm_vidc_encoder_cmd(inst->vidc_context, &enc_cmd);
+
+	wait_for_completion(&inst->cmd_complete);
+
+	if (inst->callback_thread && inst->callback_thread_running)
+		kthread_stop(inst->callback_thread);
+
+	event.type = V4L2_EVENT_MSM_VIDC_CLOSE_DONE;
+	rc = msm_vidc_unsubscribe_event(inst->vidc_context, &event);
+	if (rc)
+		WFD_MSG_WARN("Failed to unsubscribe close event\n");
+
+	event.type = V4L2_EVENT_MSM_VIDC_FLUSH_DONE;
+	rc = msm_vidc_unsubscribe_event(inst->vidc_context, &event);
+	if (rc)
+		WFD_MSG_WARN("Failed to unsubscribe flush event\n");
+
+	rc = msm_vidc_close(inst->vidc_context);
+	if (rc)
+		WFD_MSG_WARN("Failed to close vidc context\n");
+
+	kfree(inst);
+	sd->dev_priv = inst = NULL;
+venc_close_fail:
+	return rc;
+}
+
+static long venc_get_buffer_req(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0;
+	struct venc_inst *inst = NULL;
+	struct bufreq *bufreq = arg;
+	struct v4l2_requestbuffers v4l2_bufreq = {0};
+	struct v4l2_format v4l2_format = {0};
+
+	if (!sd) {
+		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+		rc = -EINVAL;
+		goto venc_buf_req_fail;
+	} else if (!arg) {
+		WFD_MSG_ERR("Invalid buffer requirements\n");
+		rc = -EINVAL;
+		goto venc_buf_req_fail;
+	}
+
+	inst = (struct venc_inst *)sd->dev_priv;
+	/* Get buffer count */
+	v4l2_bufreq = (struct v4l2_requestbuffers) {
+		.count = bufreq->count,
+		.type = BUF_TYPE_OUTPUT,
+		.memory = V4L2_MEMORY_USERPTR,
+	};
+
+	rc = msm_vidc_reqbufs(inst->vidc_context, &v4l2_bufreq);
+	if (rc) {
+		WFD_MSG_ERR("Failed getting buffer requirements\n");
+		goto venc_buf_req_fail;
+	}
+
+	/* Get buffer size */
+	v4l2_format.type = BUF_TYPE_OUTPUT;
+	rc = msm_vidc_g_fmt(inst->vidc_context, &v4l2_format);
+	if (rc) {
+		WFD_MSG_ERR("Failed getting OP buffer size\n");
+		goto venc_buf_req_fail;
+	}
+
+	bufreq->count = v4l2_bufreq.count;
+	bufreq->size = v4l2_format.fmt.pix_mp.plane_fmt[0].sizeimage;
+
+	inst->free_output_indices.size_bits = bufreq->count;
+	inst->free_output_indices.size = roundup(bufreq->count,
+				sizeof(unsigned long)) / sizeof(unsigned long);
+	inst->free_output_indices.bitmap = kzalloc(inst->free_output_indices.
+						size, GFP_KERNEL);
+venc_buf_req_fail:
+	return rc;
+}
+
+static long venc_set_buffer_req(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0;
+	struct venc_inst *inst = NULL;
+	struct bufreq *bufreq = arg;
+	struct v4l2_requestbuffers v4l2_bufreq = {0};
+	struct v4l2_format v4l2_format = {0};
+
+	if (!sd) {
+		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+		rc = -EINVAL;
+		goto venc_buf_req_fail;
+	} else if (!arg) {
+		WFD_MSG_ERR("Invalid buffer requirements\n");
+		rc = -EINVAL;
+		goto venc_buf_req_fail;
+	}
+
+	inst = (struct venc_inst *)sd->dev_priv;
+
+	/* Attempt to set buffer count */
+	v4l2_bufreq = (struct v4l2_requestbuffers) {
+		.count = bufreq->count,
+		.type = BUF_TYPE_INPUT,
+		.memory = V4L2_MEMORY_USERPTR,
+	};
+
+	rc = msm_vidc_reqbufs(inst->vidc_context, &v4l2_bufreq);
+	if (rc) {
+		WFD_MSG_ERR("Failed getting buffer requirements");
+		goto venc_buf_req_fail;
+	}
+
+	/* Get buffer size */
+	v4l2_format.type = BUF_TYPE_INPUT;
+	rc = msm_vidc_g_fmt(inst->vidc_context, &v4l2_format);
+	if (rc) {
+		WFD_MSG_ERR("Failed getting OP buffer size\n");
+		goto venc_buf_req_fail;
+	}
+
+	bufreq->count = v4l2_bufreq.count;
+	bufreq->size = ALIGN(v4l2_format.fmt.pix_mp.plane_fmt[0].sizeimage,
+			inst->secure ? SZ_1M : SZ_4K);
+
+	inst->free_input_indices.size_bits = bufreq->count;
+	inst->free_input_indices.size = roundup(bufreq->count,
+				sizeof(unsigned long)) / sizeof(unsigned long);
+	inst->free_input_indices.bitmap = kzalloc(inst->free_input_indices.
+						size, GFP_KERNEL);
+venc_buf_req_fail:
+	return rc;
+}
+
+static long venc_start(struct v4l2_subdev *sd)
+{
+	struct venc_inst *inst = NULL;
+	int rc = 0;
+
+	if (!sd) {
+		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+		rc = -EINVAL;
+		goto venc_start_fail;
+	}
+
+	inst = (struct venc_inst *)sd->dev_priv;
+
+	if (set_default_properties(inst))
+		WFD_MSG_WARN("Couldn't set default properties\n");
+
+	rc = msm_vidc_streamon(inst->vidc_context, BUF_TYPE_OUTPUT);
+	if (rc) {
+		WFD_MSG_ERR("Failed to streamon vidc's output port");
+		goto venc_start_fail;
+	}
+
+	rc = msm_vidc_streamon(inst->vidc_context, BUF_TYPE_INPUT);
+	if (rc) {
+		WFD_MSG_ERR("Failed to streamon vidc's input port");
+		goto venc_start_fail;
+	}
+
+venc_start_fail:
+	return rc;
+}
+
+static long venc_stop(struct v4l2_subdev *sd)
+{
+	struct venc_inst *inst = NULL;
+	int rc = 0;
+
+	if (!sd) {
+		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+		rc = -EINVAL;
+		goto venc_stop_fail;
+	}
+
+	inst = (struct venc_inst *)sd->dev_priv;
+
+	rc = msm_vidc_streamoff(inst->vidc_context, BUF_TYPE_INPUT);
+	if (rc) {
+		WFD_MSG_ERR("Failed to streamoff vidc's input port");
+		goto venc_stop_fail;
+	}
+
+	rc = msm_vidc_streamoff(inst->vidc_context, BUF_TYPE_OUTPUT);
+	if (rc) {
+		WFD_MSG_ERR("Failed to streamoff vidc's output port");
+		goto venc_stop_fail;
+	}
+
+venc_stop_fail:
+	return rc;
+}
+
+static void populate_planes(struct v4l2_plane *planes, int num_planes,
+		void *userptr, int size)
+{
+	int c = 0;
+
+	planes[0] = (struct v4l2_plane) {
+		.length = size,
+		.m.userptr = (int)userptr,
+	};
+
+	for (c = 1; c < num_planes - 1; ++c) {
+		planes[c] = (struct v4l2_plane) {
+			.length = 0,
+			.m.userptr = (int)NULL,
+		};
+	}
+}
+
+static long venc_set_input_buffer(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0;
+	struct venc_inst *inst = NULL;
+	struct v4l2_buffer buf = {0};
+	struct v4l2_plane *planes = NULL;
+	struct mem_region *mregion = arg;
+
+	if (!sd) {
+		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+		rc =  -EINVAL;
+		goto set_input_buffer_fail;
+	} else if (!arg) {
+		WFD_MSG_ERR("Invalid input buffer\n");
+		rc =  -EINVAL;
+		goto set_input_buffer_fail;
+	}
+
+	inst = (struct venc_inst *)sd->dev_priv;
+	if (get_registered_mregion(&inst->registered_input_bufs, mregion)) {
+		WFD_MSG_ERR("Duplicate input buffer\n");
+		rc = -EEXIST;
+		goto set_input_buffer_fail;
+	}
+
+	mregion = kzalloc(sizeof(*mregion), GFP_KERNEL);
+	planes = kzalloc(sizeof(*planes) * inst->num_input_planes, GFP_KERNEL);
+	if (!mregion || !planes)
+		return -ENOMEM;
+
+	*mregion = *(struct mem_region *)arg;
+	populate_planes(planes, inst->num_input_planes,
+			mregion->paddr, mregion->size);
+
+	buf = (struct v4l2_buffer) {
+		.index = get_list_len(&inst->registered_input_bufs),
+		.type = BUF_TYPE_INPUT,
+		.bytesused = 0,
+		.memory = V4L2_MEMORY_USERPTR,
+		.m.planes = planes,
+		.length = inst->num_input_planes,
+	};
+
+	WFD_MSG_DBG("Prepare %p with index, %d",
+		(void *)buf.m.planes[0].m.userptr, buf.index);
+	rc = msm_vidc_prepare_buf(inst->vidc_context, &buf);
+	if (rc) {
+		WFD_MSG_ERR("Failed to prepare input buffer\n");
+		goto set_input_buffer_fail;
+	}
+
+	list_add_tail(&mregion->list, &inst->registered_input_bufs.list);
+
+	kfree(planes);
+	return 0;
+set_input_buffer_fail:
+	kfree(mregion);
+	kfree(planes);
+	return rc;
+}
+
+static int venc_map_user_to_kernel(struct venc_inst *inst,
+		struct mem_region *mregion)
+{
+	int rc = 0;
+	unsigned long size = 0, align_req = 0;
+	if (!mregion) {
+		rc = -EINVAL;
+		goto venc_map_fail;
+	}
+
+	align_req = inst->secure ? SZ_1M : SZ_4K;
+	if (mregion->size % align_req != 0) {
+		WFD_MSG_ERR("Memregion not aligned to %ld\n", align_req);
+		rc = -EINVAL;
+		goto venc_map_fail;
+	}
+
+	mregion->ion_handle = ion_import_dma_buf(venc_ion_client, mregion->fd);
+	if (IS_ERR_OR_NULL(mregion->ion_handle)) {
+		rc = PTR_ERR(mregion->ion_handle);
+		WFD_MSG_ERR("Failed to get handle: %p, %d, %d, %d\n",
+			venc_ion_client, mregion->fd, mregion->offset, rc);
+		mregion->ion_handle = NULL;
+		goto venc_map_fail;
+	}
+
+	if (!inst->secure) {
+		mregion->kvaddr = ion_map_kernel(venc_ion_client,
+				mregion->ion_handle);
+		if (IS_ERR_OR_NULL(mregion->kvaddr)) {
+			WFD_MSG_ERR("Failed to map buffer into kernel\n");
+			rc = PTR_ERR(mregion->kvaddr);
+			mregion->kvaddr = NULL;
+			goto venc_map_fail;
+		}
+	} else {
+		mregion->kvaddr = NULL;
+	}
+
+	if (inst->secure) {
+		rc = msm_ion_secure_buffer(venc_ion_client,
+			mregion->ion_handle, VIDEO_BITSTREAM, 0);
+		if (rc) {
+			WFD_MSG_ERR("Failed to secure output buffer\n");
+			goto venc_map_iommu_map_fail;
+		}
+	}
+
+	rc = ion_map_iommu(venc_ion_client, mregion->ion_handle,
+			inst->domain, 0, align_req, 0,
+			(unsigned long *)&mregion->paddr, &size, 0, 0);
+
+	if (rc) {
+		WFD_MSG_ERR("Failed to map into iommu\n");
+		goto venc_map_iommu_map_fail;
+	} else if (size < mregion->size) {
+		WFD_MSG_ERR("Failed to iommu map the correct size\n");
+		goto venc_map_iommu_size_fail;
+	}
+
+	return 0;
+venc_map_iommu_size_fail:
+	ion_unmap_iommu(venc_ion_client, mregion->ion_handle,
+			inst->domain, 0);
+
+	if (inst->secure)
+		msm_ion_unsecure_buffer(venc_ion_client, mregion->ion_handle);
+venc_map_iommu_map_fail:
+	if (!inst->secure)
+		ion_unmap_kernel(venc_ion_client, mregion->ion_handle);
+venc_map_fail:
+	return rc;
+}
+
+static int venc_unmap_user_to_kernel(struct venc_inst *inst,
+		struct mem_region *mregion)
+{
+	if (!mregion || !mregion->ion_handle)
+		return 0;
+
+	if (mregion->paddr) {
+		ion_unmap_iommu(venc_ion_client, mregion->ion_handle,
+				inst->domain, 0);
+		mregion->paddr = NULL;
+	}
+
+	if (mregion->kvaddr) {
+		ion_unmap_kernel(venc_ion_client, mregion->ion_handle);
+		mregion->kvaddr = NULL;
+	}
+
+	if (inst->secure)
+		msm_ion_unsecure_buffer(venc_ion_client, mregion->ion_handle);
+
+	return 0;
+}
+
+static long venc_set_output_buffer(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0;
+	struct venc_inst *inst = NULL;
+	struct v4l2_buffer buf = {0};
+	struct v4l2_plane *planes = NULL;
+	struct mem_region *mregion = arg;
+
+	if (!sd) {
+		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+		rc = -EINVAL;
+		goto venc_set_output_buffer_fail;
+	} else if (!mregion) {
+		WFD_MSG_ERR("Invalid output buffer\n");
+		rc = -EINVAL;
+		goto venc_set_output_buffer_fail;
+	}
+
+	inst = (struct venc_inst *)sd->dev_priv;
+
+	/* Check if buf already registered */
+	if (get_registered_mregion(&inst->registered_output_bufs, mregion)) {
+		WFD_MSG_ERR("Duplicate output buffer\n");
+		rc = -EEXIST;
+		goto venc_set_output_buffer_fail;
+	}
+
+	mregion = kzalloc(sizeof(*mregion), GFP_KERNEL);
+	planes = kzalloc(sizeof(*planes) * inst->num_output_planes, GFP_KERNEL);
+
+	if (!mregion || !planes) {
+		WFD_MSG_ERR("Failed to allocate memory\n");
+		goto venc_set_output_buffer_fail;
+	}
+
+	*mregion = *(struct mem_region *)arg;
+	INIT_LIST_HEAD(&mregion->list);
+
+	rc = venc_map_user_to_kernel(inst, mregion);
+	if (rc) {
+		WFD_MSG_ERR("Failed to map output buffer\n");
+		goto venc_set_output_buffer_map_fail;
+	}
+
+	populate_planes(planes, inst->num_output_planes,
+			mregion->paddr, mregion->size);
+
+	buf = (struct v4l2_buffer) {
+		.index = get_list_len(&inst->registered_output_bufs),
+		.type = BUF_TYPE_OUTPUT,
+		.bytesused = 0,
+		.memory = V4L2_MEMORY_USERPTR,
+		.m.planes = planes,
+		.length = inst->num_output_planes,
+	};
+
+	WFD_MSG_DBG("Prepare %p with index, %d",
+		(void *)buf.m.planes[0].m.userptr, buf.index);
+	rc = msm_vidc_prepare_buf(inst->vidc_context, &buf);
+	if (rc) {
+		WFD_MSG_ERR("Failed to prepare output buffer\n");
+		goto venc_set_output_buffer_prepare_fail;
+	}
+
+	list_add_tail(&mregion->list, &inst->registered_output_bufs.list);
+
+	kfree(planes);
+	return 0;
+venc_set_output_buffer_prepare_fail:
+	venc_unmap_user_to_kernel(inst, mregion);
+venc_set_output_buffer_map_fail:
+	kfree(mregion);
+	kfree(planes);
+venc_set_output_buffer_fail:
+	return rc;
+}
+
+static long venc_set_format(struct v4l2_subdev *sd, void *arg)
+{
+	struct venc_inst *inst = NULL;
+	struct v4l2_format *fmt = arg, temp;
+	int rc = 0, align_req = 0;
+
+	if (!sd) {
+		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+		rc = -EINVAL;
+		goto venc_set_format_fail;
+	} else if (!fmt) {
+		WFD_MSG_ERR("Invalid format\n");
+		rc = -EINVAL;
+		goto venc_set_format_fail;
+	} else if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		WFD_MSG_ERR("Invalid buffer type %d\n", fmt->type);
+		rc = -ENOTSUPP;
+		goto venc_set_format_fail;
+	}
+
+	inst = (struct venc_inst *)sd->dev_priv;
+	temp = (struct v4l2_format) {
+		.type = BUF_TYPE_OUTPUT,
+		.fmt.pix_mp = (struct v4l2_pix_format_mplane) {
+			.width = fmt->fmt.pix.width,
+			.height = fmt->fmt.pix.height,
+			.pixelformat = fmt->fmt.pix.pixelformat,
+		},
+	};
+
+	rc = msm_vidc_s_fmt(inst->vidc_context, &temp);
+
+	if (rc) {
+		WFD_MSG_ERR("Failed to format for output port\n");
+		goto venc_set_format_fail;
+	} else if (!temp.fmt.pix_mp.num_planes) {
+		WFD_MSG_ERR("No. of planes for output buffers make no sense\n");
+		rc = -EINVAL;
+		goto venc_set_format_fail;
+	}
+
+	align_req = inst->secure ? SZ_1M : SZ_4K;
+	fmt->fmt.pix.sizeimage = ALIGN(temp.fmt.pix_mp.plane_fmt[0].sizeimage,
+					align_req);
+	inst->num_output_planes = temp.fmt.pix_mp.num_planes;
+
+	temp.type = BUF_TYPE_INPUT;
+	temp.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
+	rc = msm_vidc_s_fmt(inst->vidc_context, &temp);
+	inst->num_input_planes = temp.fmt.pix_mp.num_planes;
+
+	if (rc) {
+		WFD_MSG_ERR("Failed to format for input port\n");
+		goto venc_set_format_fail;
+	}
+venc_set_format_fail:
+	return rc;
+}
+
+static long venc_set_framerate(struct v4l2_subdev *sd, void *arg)
+{
+	struct venc_inst *inst = NULL;
+	struct v4l2_streamparm p = {0};
+
+	if (!sd) {
+		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+		return -EINVAL;
+	} else if (!arg) {
+		WFD_MSG_ERR("Invalid framerate\n");
+		return -EINVAL;
+	}
+
+	inst = (struct venc_inst *)sd->dev_priv;
+	p.type = BUF_TYPE_INPUT;
+	p.parm.output.timeperframe = *(struct v4l2_fract *)arg;
+	return msm_vidc_s_parm(inst->vidc_context, &p);
+}
+
+static long venc_fill_outbuf(struct v4l2_subdev *sd, void *arg)
+{
+	struct venc_inst *inst = NULL;
+	struct mem_region *mregion = NULL;
+	struct v4l2_buffer buffer = {0};
+	struct v4l2_plane plane = {0};
+	int index = 0, rc = 0;
+
+	if (!sd) {
+		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+		return -EINVAL;
+	} else if (!arg) {
+		WFD_MSG_ERR("Invalid output buffer ot fill\n");
+		return -EINVAL;
+	}
+
+	inst = (struct venc_inst *)sd->dev_priv;
+	mregion = get_registered_mregion(&inst->registered_output_bufs, arg);
+
+	if (!mregion) {
+		WFD_MSG_ERR("Output buffer not registered\n");
+		return -ENOENT;
+	}
+
+	plane = (struct v4l2_plane) {
+		.length = mregion->size,
+		.m.userptr = (u32)mregion->paddr,
+	};
+
+	while (true) {
+		mutex_lock(&inst->lock);
+		index = next_free_index(&inst->free_output_indices);
+		mutex_unlock(&inst->lock);
+
+		if (index < 0)
+			wait_for_completion(&inst->dq_complete);
+		else
+			break;
+	}
+
+	buffer = (struct v4l2_buffer) {
+		.index = index,
+		.type = BUF_TYPE_OUTPUT,
+		.memory = V4L2_MEMORY_USERPTR,
+		.m.planes = &plane,
+		.length = 1,
+	};
+
+	WFD_MSG_DBG("Fill buffer %p with index, %d",
+		(void *)buffer.m.planes[0].m.userptr, buffer.index);
+	rc = msm_vidc_qbuf(inst->vidc_context, &buffer);
+	if (!rc) {
+		mutex_lock(&inst->lock);
+		mark_index_busy(&inst->free_output_indices, index);
+		mutex_unlock(&inst->lock);
+	}
+	return rc;
+
+}
+
+static long venc_encode_frame(struct v4l2_subdev *sd, void *arg)
+{
+	struct venc_inst *inst = NULL;
+	struct venc_buf_info *venc_buf = arg;
+	struct mem_region *mregion = NULL;
+	struct v4l2_buffer buffer = {0};
+	struct v4l2_plane plane = {0};
+	int index = 0, rc = 0;
+
+	if (!sd) {
+		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+		return -EINVAL;
+	} else if (!venc_buf) {
+		WFD_MSG_ERR("Invalid output buffer ot fill\n");
+		return -EINVAL;
+	}
+
+	inst = (struct venc_inst *)sd->dev_priv;
+	mregion = venc_buf->mregion;
+
+	plane = (struct v4l2_plane) {
+		.length = mregion->size,
+		.m.userptr = (u32)mregion->paddr,
+		.bytesused = mregion->size,
+	};
+
+	while (true) {
+		mutex_lock(&inst->lock);
+		index = next_free_index(&inst->free_input_indices);
+		mutex_unlock(&inst->lock);
+
+		if (index < 0)
+			wait_for_completion(&inst->dq_complete);
+		else
+			break;
+	}
+
+	buffer = (struct v4l2_buffer) {
+		.index = index,
+		.type = BUF_TYPE_INPUT,
+		.timestamp = ns_to_timeval(venc_buf->timestamp),
+		.memory = V4L2_MEMORY_USERPTR,
+		.m.planes = &plane,
+		.length = 1,
+	};
+
+	WFD_MSG_DBG("Encode buffer %p with index, %d",
+		(void *)buffer.m.planes[0].m.userptr, buffer.index);
+	rc = msm_vidc_qbuf(inst->vidc_context, &buffer);
+	if (!rc) {
+		mutex_lock(&inst->lock);
+		mark_index_busy(&inst->free_input_indices, index);
+		mutex_unlock(&inst->lock);
+	}
+	return rc;
+}
+
+static long venc_alloc_recon_buffers(struct v4l2_subdev *sd, void *arg)
+{
+	/* vidc driver allocates internally on streamon */
+	return 0;
+}
+
+static long venc_free_buffer(struct venc_inst *inst, int type,
+		struct mem_region *to_free, bool unmap_user_buffer)
+{
+	struct mem_region *mregion = NULL;
+	struct mem_region *buf_list = NULL;
+
+	if (type == BUF_TYPE_OUTPUT) {
+		buf_list = &inst->registered_output_bufs;
+	} else if (type == BUF_TYPE_INPUT) {
+		buf_list = &inst->registered_input_bufs;
+	} else {
+		WFD_MSG_ERR("Trying to free a buffer of unknown type\n");
+		return -EINVAL;
+	}
+	mregion = get_registered_mregion(buf_list, to_free);
+
+	if (!mregion) {
+		WFD_MSG_ERR("Buffer not registered, cannot free\n");
+		return -ENOENT;
+	}
+
+	if (unmap_user_buffer) {
+		int rc = venc_unmap_user_to_kernel(inst, mregion);
+		if (rc)
+			WFD_MSG_WARN("Unable to unmap user buffer\n");
+	}
+
+	list_del(&mregion->list);
+	kfree(mregion);
+	return 0;
+}
+static long venc_free_output_buffer(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0;
+	struct venc_inst *inst = NULL;
+
+	if (!sd) {
+		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+		rc = -EINVAL;
+		goto venc_free_output_buffer_fail;
+	} else if (!arg) {
+		WFD_MSG_ERR("Invalid output buffer\n");
+		rc = -EINVAL;
+		goto venc_free_output_buffer_fail;
+	}
+
+	inst = (struct venc_inst *)sd->dev_priv;
+	return venc_free_buffer(inst, BUF_TYPE_OUTPUT, arg, true);
+venc_free_output_buffer_fail:
+	return rc;
+}
+
+static long venc_flush_buffers(struct v4l2_subdev *sd, void *arg)
+{
+	struct venc_inst *inst = NULL;
+	struct v4l2_encoder_cmd enc_cmd = {0};
+	int rc = 0;
+
+	if (!sd) {
+		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+		rc = -EINVAL;
+		goto venc_flush_buffers_fail;
+	}
+
+	inst = (struct venc_inst *)sd->dev_priv;
+
+	enc_cmd.cmd = V4L2_ENC_QCOM_CMD_FLUSH;
+	enc_cmd.flags = V4L2_QCOM_CMD_FLUSH_OUTPUT |
+		V4L2_QCOM_CMD_FLUSH_CAPTURE;
+	msm_vidc_encoder_cmd(inst->vidc_context, &enc_cmd);
+
+	wait_for_completion(&inst->cmd_complete);
+venc_flush_buffers_fail:
+	return rc;
+}
+
+static long venc_free_input_buffer(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0;
+	struct venc_inst *inst = NULL;
+
+	if (!sd) {
+		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+		rc = -EINVAL;
+		goto venc_free_input_buffer_fail;
+	} else if (!arg) {
+		WFD_MSG_ERR("Invalid output buffer\n");
+		rc = -EINVAL;
+		goto venc_free_input_buffer_fail;
+	}
+
+	inst = (struct venc_inst *)sd->dev_priv;
+	return venc_free_buffer(inst, BUF_TYPE_INPUT, arg, false);
+venc_free_input_buffer_fail:
+	return rc;
+}
+
+static long venc_free_recon_buffers(struct v4l2_subdev *sd, void *arg)
+{
+	/* vidc driver takes care of this */
+	return 0;
+}
+
+static long venc_set_property(struct v4l2_subdev *sd, void *arg)
+{
+	struct venc_inst *inst = NULL;
+
+	if (!sd) {
+		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+		return -EINVAL;
+	}
+
+	inst = (struct venc_inst *)sd->dev_priv;
+	return msm_vidc_s_ctrl(inst->vidc_context, (struct v4l2_control *)arg);
+}
+
+static long venc_get_property(struct v4l2_subdev *sd, void *arg)
+{
+	struct venc_inst *inst = NULL;
+
+	if (!sd) {
+		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+		return -EINVAL;
+	}
+
+	inst = (struct venc_inst *)sd->dev_priv;
+	return msm_vidc_g_ctrl(inst->vidc_context, (struct v4l2_control *)arg);
+}
+
+long venc_mmap(struct v4l2_subdev *sd, void *arg)
+{
+	struct mem_region_map *mmap = arg;
+	struct mem_region *mregion = NULL;
+	unsigned long rc = 0, size = 0, align_req = 0;
+	void *paddr = NULL;
+	struct venc_inst *inst = NULL;
+
+	if (!sd) {
+		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+		return -EINVAL;
+	} else if (!mmap || !mmap->mregion) {
+		WFD_MSG_ERR("Memregion required for %s\n", __func__);
+		return -EINVAL;
+	}
+
+	inst = (struct venc_inst *)sd->dev_priv;
+	mregion = mmap->mregion;
+
+	align_req = inst->secure ? SZ_1M : SZ_4K;
+	if (mregion->size % align_req != 0) {
+		WFD_MSG_ERR("Memregion not aligned to %ld\n", align_req);
+		rc = -EINVAL;
+		goto venc_map_bad_align;
+	}
+
+	if (inst->secure) {
+		rc = msm_ion_secure_buffer(mmap->ion_client,
+			mregion->ion_handle, VIDEO_PIXEL, 0);
+		if (rc) {
+			WFD_MSG_ERR("Failed to secure input buffer\n");
+			goto venc_map_bad_align;
+		}
+	}
+
+	rc = ion_map_iommu(mmap->ion_client, mregion->ion_handle,
+			inst->domain, 0, align_req, 0, (unsigned long *)&paddr,
+			&size, 0, 0);
+
+	if (rc) {
+		WFD_MSG_ERR("Failed to get physical addr %ld\n", rc);
+		paddr = NULL;
+		goto venc_map_bad_align;
+	} else if (size < mregion->size) {
+		WFD_MSG_ERR("Failed to map enough memory\n");
+		rc = -ENOMEM;
+		goto venc_map_iommu_size_fail;
+	}
+
+	mregion->paddr = paddr;
+	return 0;
+
+venc_map_iommu_size_fail:
+	ion_unmap_iommu(venc_ion_client, mregion->ion_handle,
+			inst->domain, 0);
+
+	if (inst->secure)
+		msm_ion_unsecure_buffer(mmap->ion_client, mregion->ion_handle);
+venc_map_bad_align:
+	return rc;
+}
+
+long venc_munmap(struct v4l2_subdev *sd, void *arg)
+{
+	struct mem_region_map *mmap = arg;
+	struct mem_region *mregion = NULL;
+	struct venc_inst *inst = NULL;
+
+	if (!sd) {
+		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+		return -EINVAL;
+	} else if (!mmap || !mmap->mregion) {
+		WFD_MSG_ERR("Memregion required for %s\n", __func__);
+		return -EINVAL;
+	}
+
+	inst = (struct venc_inst *)sd->dev_priv;
+	mregion = mmap->mregion;
+
+	if (mregion->paddr)
+		ion_unmap_iommu(mmap->ion_client, mregion->ion_handle,
+			inst->domain, 0);
+
+	if (inst->secure)
+		msm_ion_unsecure_buffer(mmap->ion_client, mregion->ion_handle);
+
+	return 0;
+}
+
+static long venc_set_framerate_mode(struct v4l2_subdev *sd,
+				void *arg)
+{
+	/* TODO: Unsupported for now, but return false success
+	 * to preserve binary compatibility for userspace apps
+	 * across targets */
+	return 0;
+}
+
+static long secure_toggle(struct venc_inst *inst, bool secure)
+{
+	if (inst->secure == secure)
+		return 0;
+
+	if (!list_empty(&inst->registered_input_bufs.list) ||
+		!list_empty(&inst->registered_output_bufs.list)) {
+		WFD_MSG_ERR(
+			"Attempt to (un)secure encoder not allowed after registering buffers"
+			);
+		return -EEXIST;
+	}
+
+	inst->secure = secure;
+	inst->domain = get_iommu_domain(inst);
+	return 0;
+}
+
+static long venc_secure(struct v4l2_subdev *sd)
+{
+	struct venc_inst *inst = NULL;
+	struct v4l2_control ctrl;
+	int rc = 0;
+
+	if (!sd) {
+		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+		return -EINVAL;
+	}
+
+	inst = sd->dev_priv;
+	rc = secure_toggle(inst, true);
+	if (rc) {
+		WFD_MSG_ERR("Failed to toggle into secure mode\n");
+		goto secure_fail;
+	}
+
+	ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
+	rc = msm_vidc_s_ctrl(inst->vidc_context, &ctrl);
+	if (rc) {
+		WFD_MSG_ERR("Failed to move vidc into secure mode\n");
+		goto secure_fail;
+	}
+
+	return 0;
+secure_fail:
+	secure_toggle(sd->dev_priv, false);
+	return rc;
+}
+
+long venc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+	long rc = 0;
+	switch (cmd) {
+	case OPEN:
+		rc = venc_open(sd, arg);
+		break;
+	case CLOSE:
+		rc = venc_close(sd, arg);
+		break;
+	case ENCODE_START:
+		rc = venc_start(sd);
+		break;
+	case ENCODE_FRAME:
+		venc_encode_frame(sd, arg);
+		break;
+	case ENCODE_STOP:
+		rc = venc_stop(sd);
+		break;
+	case SET_PROP:
+		rc = venc_set_property(sd, arg);
+		break;
+	case GET_PROP:
+		rc = venc_get_property(sd, arg);
+		break;
+	case GET_BUFFER_REQ:
+		rc = venc_get_buffer_req(sd, arg);
+		break;
+	case SET_BUFFER_REQ:
+		rc = venc_set_buffer_req(sd, arg);
+		break;
+	case FREE_BUFFER:
+		break;
+	case FILL_OUTPUT_BUFFER:
+		rc = venc_fill_outbuf(sd, arg);
+		break;
+	case SET_FORMAT:
+		rc = venc_set_format(sd, arg);
+		break;
+	case SET_FRAMERATE:
+		rc = venc_set_framerate(sd, arg);
+		break;
+	case SET_INPUT_BUFFER:
+		rc = venc_set_input_buffer(sd, arg);
+		break;
+	case SET_OUTPUT_BUFFER:
+		rc = venc_set_output_buffer(sd, arg);
+		break;
+	case ALLOC_RECON_BUFFERS:
+		rc = venc_alloc_recon_buffers(sd, arg);
+		break;
+	case FREE_OUTPUT_BUFFER:
+		rc = venc_free_output_buffer(sd, arg);
+		break;
+	case FREE_INPUT_BUFFER:
+		rc = venc_free_input_buffer(sd, arg);
+		break;
+	case FREE_RECON_BUFFERS:
+		rc = venc_free_recon_buffers(sd, arg);
+		break;
+	case ENCODE_FLUSH:
+		rc = venc_flush_buffers(sd, arg);
+		break;
+	case ENC_MMAP:
+		rc = venc_mmap(sd, arg);
+		break;
+	case ENC_MUNMAP:
+		rc = venc_munmap(sd, arg);
+		break;
+	case SET_FRAMERATE_MODE:
+		rc = venc_set_framerate_mode(sd, arg);
+		break;
+	case ENC_SECURE:
+		rc = venc_secure(sd);
+		break;
+	default:
+		WFD_MSG_ERR("Unknown ioctl %d to enc-subdev\n", cmd);
+		rc = -ENOTSUPP;
+		break;
+	}
+	return rc;
+}
diff --git a/drivers/media/platform/msm/wfd/mdp-4-subdev.c b/drivers/media/platform/msm/wfd/mdp-4-subdev.c
new file mode 100644
index 0000000..d2ecd22
--- /dev/null
+++ b/drivers/media/platform/msm/wfd/mdp-4-subdev.c
@@ -0,0 +1,313 @@
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 and
+* only version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+*/
+#include <linux/msm_mdp.h>
+#include <linux/switch.h>
+#include <mach/iommu_domains.h>
+#include <media/videobuf2-core.h>
+#include "enc-subdev.h"
+#include "mdp-subdev.h"
+#include "wfd-util.h"
+
+struct mdp_instance {
+	struct fb_info *mdp;
+	u32 height;
+	u32 width;
+	bool secure;
+	bool uses_iommu_split_domain;
+	struct switch_dev sdev;
+};
+
+int mdp_init(struct v4l2_subdev *sd, u32 val)
+{
+	return 0;
+}
+
+int mdp_open(struct v4l2_subdev *sd, void *arg)
+{
+	struct mdp_instance *inst = kzalloc(sizeof(struct mdp_instance),
+					GFP_KERNEL);
+	struct mdp_msg_ops *mops = arg;
+	int rc = 0;
+	struct fb_info *fbi = NULL;
+
+	if (!inst) {
+		WFD_MSG_ERR("Out of memory\n");
+		rc = -ENOMEM;
+		goto mdp_open_fail;
+	} else if (!mops) {
+		WFD_MSG_ERR("Invalid arguments\n");
+		rc = -EINVAL;
+		goto mdp_open_fail;
+	}
+
+	fbi = msm_fb_get_writeback_fb();
+	if (!fbi) {
+		WFD_MSG_ERR("Failed to acquire mdp instance\n");
+		rc = -ENODEV;
+		goto mdp_open_fail;
+	}
+	inst->sdev.name = "wfd";
+	/* Register wfd node to switch driver */
+	rc = switch_dev_register(&inst->sdev);
+	if (rc) {
+		WFD_MSG_ERR("WFD switch registration failed\n");
+		goto mdp_open_fail;
+	}
+	msm_fb_writeback_init(fbi);
+	inst->mdp = fbi;
+	inst->secure = mops->secure;
+	inst->uses_iommu_split_domain = mops->iommu_split_domain;
+
+	mops->cookie = inst;
+	return rc;
+mdp_open_fail:
+	kfree(inst);
+	return rc;
+}
+
+int mdp_start(struct v4l2_subdev *sd, void *arg)
+{
+	struct mdp_instance *inst = arg;
+	int rc = 0;
+	struct fb_info *fbi = NULL;
+	if (inst) {
+		rc = msm_fb_writeback_start(inst->mdp);
+		if (rc) {
+			WFD_MSG_ERR("Failed to start MDP mode\n");
+			goto exit;
+		}
+		fbi = msm_fb_get_writeback_fb();
+		if (!fbi) {
+			WFD_MSG_ERR("Failed to acquire mdp instance\n");
+			rc = -ENODEV;
+			goto exit;
+		}
+		switch_set_state(&inst->sdev, true);
+		WFD_MSG_DBG("wfd state switched to %d\n", inst->sdev.state);
+	}
+exit:
+	return rc;
+}
+int mdp_stop(struct v4l2_subdev *sd, void *arg)
+{
+	struct mdp_instance *inst = arg;
+	int rc = 0;
+	struct fb_info *fbi = NULL;
+	if (inst) {
+		rc = msm_fb_writeback_stop(inst->mdp);
+		if (rc) {
+			WFD_MSG_ERR("Failed to stop writeback mode\n");
+			return rc;
+		}
+		fbi = (struct fb_info *)inst->mdp;
+		switch_set_state(&inst->sdev, false);
+		WFD_MSG_DBG("wfd state switched to %d\n", inst->sdev.state);
+	}
+	return 0;
+}
+int mdp_close(struct v4l2_subdev *sd, void *arg)
+{
+	struct mdp_instance *inst = arg;
+	struct fb_info *fbi = NULL;
+	if (inst) {
+		fbi = (struct fb_info *)inst->mdp;
+		msm_fb_writeback_terminate(fbi);
+		kfree(inst);
+		/* Unregister wfd node from switch driver */
+		switch_dev_unregister(&inst->sdev);
+	}
+	return 0;
+}
+int mdp_q_buffer(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0;
+	struct mdp_buf_info *binfo = arg;
+	struct msmfb_data fbdata;
+	struct mdp_instance *inst;
+	if (!binfo || !binfo->inst || !binfo->cookie) {
+		WFD_MSG_ERR("Invalid argument\n");
+		return -EINVAL;
+	}
+	inst = binfo->inst;
+	fbdata.offset = binfo->offset;
+	fbdata.memory_id = binfo->fd;
+	fbdata.iova = binfo->paddr;
+	fbdata.id = 0;
+	fbdata.flags = 0;
+	fbdata.priv = (uint32_t)binfo->cookie;
+
+	WFD_MSG_INFO("queue buffer to mdp with offset = %u, fd = %u, "\
+			"priv = %p, iova = %p\n",
+			fbdata.offset, fbdata.memory_id,
+			(void *)fbdata.priv, (void *)fbdata.iova);
+	rc = msm_fb_writeback_queue_buffer(inst->mdp, &fbdata);
+
+	if (rc)
+		WFD_MSG_ERR("Failed to queue buffer\n");
+	return rc;
+}
+int mdp_dq_buffer(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0;
+	struct mdp_buf_info *obuf = arg;
+	struct msmfb_data fbdata;
+	struct mdp_instance *inst;
+	if (!arg) {
+		WFD_MSG_ERR("Invalid argument\n");
+		return -EINVAL;
+	}
+
+	inst = obuf->inst;
+	fbdata.flags = MSMFB_WRITEBACK_DEQUEUE_BLOCKING;
+	rc = msm_fb_writeback_dequeue_buffer(inst->mdp, &fbdata);
+	if (rc) {
+		WFD_MSG_ERR("Failed to dequeue buffer\n");
+		return rc;
+	}
+	WFD_MSG_DBG("dequeue buf from mdp with priv = %u\n",
+			fbdata.priv);
+	obuf->cookie = (void *)fbdata.priv;
+	return rc;
+}
+int mdp_set_prop(struct v4l2_subdev *sd, void *arg)
+{
+	struct mdp_prop *prop = (struct mdp_prop *)arg;
+	struct mdp_instance *inst = prop->inst;
+	if (!prop || !inst) {
+		WFD_MSG_ERR("Invalid arguments\n");
+		return -EINVAL;
+	}
+	inst->height = prop->height;
+	inst->width = prop->width;
+	return 0;
+}
+
+int mdp_mmap(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0, domain = -1;
+	struct mem_region_map *mmap = arg;
+	struct mem_region *mregion;
+	bool use_iommu = true;
+	struct mdp_instance *inst = NULL;
+
+	if (!mmap || !mmap->mregion || !mmap->cookie) {
+		WFD_MSG_ERR("Invalid argument\n");
+		return -EINVAL;
+	}
+
+	inst = mmap->cookie;
+	mregion = mmap->mregion;
+	if (mregion->size % SZ_4K != 0) {
+		WFD_MSG_ERR("Memregion not aligned to %d\n", SZ_4K);
+		return -EINVAL;
+	}
+
+	if (inst->uses_iommu_split_domain) {
+		if (inst->secure)
+			use_iommu = false;
+		else
+			domain = DISPLAY_WRITE_DOMAIN;
+	} else {
+		domain = DISPLAY_READ_DOMAIN;
+	}
+
+	if (use_iommu) {
+		rc = ion_map_iommu(mmap->ion_client, mregion->ion_handle,
+				domain, GEN_POOL, SZ_4K, 0,
+				(unsigned long *)&mregion->paddr,
+				(unsigned long *)&mregion->size,
+				0, 0);
+	} else {
+		rc = ion_phys(mmap->ion_client,	mregion->ion_handle,
+				(unsigned long *)&mregion->paddr,
+				(size_t *)&mregion->size);
+	}
+
+	return rc;
+}
+
+int mdp_munmap(struct v4l2_subdev *sd, void *arg)
+{
+	struct mem_region_map *mmap = arg;
+	struct mem_region *mregion;
+	bool use_iommu = false;
+	int domain = -1;
+	struct mdp_instance *inst = NULL;
+
+	if (!mmap || !mmap->mregion || !mmap->cookie) {
+		WFD_MSG_ERR("Invalid argument\n");
+		return -EINVAL;
+	}
+
+	inst = mmap->cookie;
+	mregion = mmap->mregion;
+
+	if (inst->uses_iommu_split_domain) {
+		if (inst->secure)
+			use_iommu = false;
+		else
+			domain = DISPLAY_WRITE_DOMAIN;
+	} else {
+		domain = DISPLAY_READ_DOMAIN;
+	}
+
+	if (use_iommu)
+		ion_unmap_iommu(mmap->ion_client,
+				mregion->ion_handle,
+				domain, GEN_POOL);
+
+	return 0;
+}
+
+long mdp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+	int rc = 0;
+	if (!sd) {
+		WFD_MSG_ERR("Invalid arguments\n");
+		return -EINVAL;
+	}
+	switch (cmd) {
+	case MDP_Q_BUFFER:
+		rc = mdp_q_buffer(sd, arg);
+		break;
+	case MDP_DQ_BUFFER:
+		rc = mdp_dq_buffer(sd, arg);
+		break;
+	case MDP_OPEN:
+		rc = mdp_open(sd, arg);
+		break;
+	case MDP_START:
+		rc = mdp_start(sd, arg);
+		break;
+	case MDP_STOP:
+		rc = mdp_stop(sd, arg);
+		break;
+	case MDP_SET_PROP:
+		rc = mdp_set_prop(sd, arg);
+		break;
+	case MDP_CLOSE:
+		rc = mdp_close(sd, arg);
+		break;
+	case MDP_MMAP:
+		rc = mdp_mmap(sd, arg);
+		break;
+	case MDP_MUNMAP:
+		rc = mdp_munmap(sd, arg);
+		break;
+	default:
+		WFD_MSG_ERR("IOCTL: %u not supported\n", cmd);
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
diff --git a/drivers/media/platform/msm/wfd/mdp-5-subdev.c b/drivers/media/platform/msm/wfd/mdp-5-subdev.c
new file mode 100644
index 0000000..4089a99
--- /dev/null
+++ b/drivers/media/platform/msm/wfd/mdp-5-subdev.c
@@ -0,0 +1,343 @@
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 and
+* only version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+*/
+#include <linux/msm_mdp.h>
+#include <linux/switch.h>
+#include <mach/iommu_domains.h>
+#include <media/videobuf2-core.h>
+#include "enc-subdev.h"
+#include "mdp-subdev.h"
+#include "wfd-util.h"
+
+struct mdp_instance {
+	struct fb_info *mdp;
+	u32 height;
+	u32 width;
+	bool secure;
+	struct switch_dev sdev;
+};
+
+int mdp_init(struct v4l2_subdev *sd, u32 val)
+{
+	return 0;
+}
+
+int mdp_open(struct v4l2_subdev *sd, void *arg)
+{
+	struct mdp_instance *inst = kzalloc(sizeof(struct mdp_instance),
+					GFP_KERNEL);
+	struct mdp_msg_ops *mops = arg;
+	int rc = 0;
+	struct fb_info *fbi = NULL;
+
+	if (!inst) {
+		WFD_MSG_ERR("Out of memory\n");
+		rc = -ENOMEM;
+		goto mdp_open_fail;
+	} else if (!mops) {
+		WFD_MSG_ERR("Invalid arguments\n");
+		rc = -EINVAL;
+		goto mdp_open_fail;
+	} else if (mops->secure) {
+		/* Deprecated API; use MDP_SECURE ioctl */
+		WFD_MSG_ERR("Deprecated API for securing subdevice\n");
+		return -ENOTSUPP;
+	}
+
+	fbi = msm_fb_get_writeback_fb();
+	if (!fbi) {
+		WFD_MSG_ERR("Failed to acquire mdp instance\n");
+		rc = -ENODEV;
+		goto mdp_open_fail;
+	}
+	inst->sdev.name = "wfd";
+	/* Register wfd node to switch driver */
+	rc = switch_dev_register(&inst->sdev);
+	if (rc) {
+		WFD_MSG_ERR("WFD switch registration failed\n");
+		goto mdp_open_fail;
+	}
+	msm_fb_writeback_init(fbi);
+	inst->mdp = fbi;
+	inst->secure = mops->secure;
+
+	mops->cookie = inst;
+	return rc;
+mdp_open_fail:
+	kfree(inst);
+	return rc;
+}
+
+int mdp_start(struct v4l2_subdev *sd, void *arg)
+{
+	struct mdp_instance *inst = arg;
+	int rc = 0;
+	struct fb_info *fbi = NULL;
+	if (inst) {
+		rc = msm_fb_writeback_start(inst->mdp);
+		if (rc) {
+			WFD_MSG_ERR("Failed to start MDP mode\n");
+			goto exit;
+		}
+		fbi = msm_fb_get_writeback_fb();
+		if (!fbi) {
+			WFD_MSG_ERR("Failed to acquire mdp instance\n");
+			rc = -ENODEV;
+			goto exit;
+		}
+		switch_set_state(&inst->sdev, true);
+		WFD_MSG_DBG("wfd state switched to %d\n", inst->sdev.state);
+	}
+exit:
+	return rc;
+}
+
+int mdp_stop(struct v4l2_subdev *sd, void *arg)
+{
+	struct mdp_instance *inst = arg;
+	int rc = 0;
+	struct fb_info *fbi = NULL;
+	if (inst) {
+		rc = msm_fb_writeback_stop(inst->mdp);
+		if (rc) {
+			WFD_MSG_ERR("Failed to stop writeback mode\n");
+			return rc;
+		}
+		fbi = (struct fb_info *)inst->mdp;
+		switch_set_state(&inst->sdev, false);
+		WFD_MSG_DBG("wfd state switched to %d\n", inst->sdev.state);
+	}
+	return 0;
+}
+int mdp_close(struct v4l2_subdev *sd, void *arg)
+{
+	struct mdp_instance *inst = arg;
+	struct fb_info *fbi = NULL;
+	if (inst) {
+		fbi = (struct fb_info *)inst->mdp;
+		if (inst->secure)
+			msm_fb_writeback_set_secure(inst->mdp, false);
+		msm_fb_writeback_terminate(fbi);
+		kfree(inst);
+		/* Unregister wfd node from switch driver */
+		switch_dev_unregister(&inst->sdev);
+	}
+	return 0;
+}
+int mdp_q_buffer(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0;
+	struct mdp_buf_info *binfo = arg;
+	struct msmfb_data fbdata;
+	struct mdp_instance *inst;
+	if (!binfo || !binfo->inst || !binfo->cookie) {
+		WFD_MSG_ERR("Invalid argument\n");
+		return -EINVAL;
+	}
+	inst = binfo->inst;
+	fbdata.offset = binfo->offset;
+	fbdata.memory_id = binfo->fd;
+	fbdata.iova = binfo->paddr;
+	fbdata.id = 0;
+	fbdata.flags = 0;
+	fbdata.priv = (uint32_t)binfo->cookie;
+
+	WFD_MSG_DBG("queue buffer to mdp with offset = %u, fd = %u, "\
+			"priv = %p, iova = %p\n",
+			fbdata.offset, fbdata.memory_id,
+			(void *)fbdata.priv, (void *)fbdata.iova);
+	rc = msm_fb_writeback_queue_buffer(inst->mdp, &fbdata);
+
+	if (rc)
+		WFD_MSG_ERR("Failed to queue buffer\n");
+	return rc;
+}
+int mdp_dq_buffer(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0;
+	struct mdp_buf_info *obuf = arg;
+	struct msmfb_data fbdata;
+	struct mdp_instance *inst;
+	if (!arg) {
+		WFD_MSG_ERR("Invalid argument\n");
+		return -EINVAL;
+	}
+
+	inst = obuf->inst;
+	fbdata.flags = MSMFB_WRITEBACK_DEQUEUE_BLOCKING;
+	rc = msm_fb_writeback_dequeue_buffer(inst->mdp, &fbdata);
+	if (rc) {
+		WFD_MSG_ERR("Failed to dequeue buffer\n");
+		return rc;
+	}
+	WFD_MSG_DBG("dequeue buf from mdp with priv = %u\n",
+			fbdata.priv);
+	obuf->cookie = (void *)fbdata.priv;
+	return rc;
+}
+int mdp_set_prop(struct v4l2_subdev *sd, void *arg)
+{
+	struct mdp_prop *prop = (struct mdp_prop *)arg;
+	struct mdp_instance *inst = prop->inst;
+	if (!prop || !inst) {
+		WFD_MSG_ERR("Invalid arguments\n");
+		return -EINVAL;
+	}
+	inst->height = prop->height;
+	inst->width = prop->width;
+	return 0;
+}
+
+int mdp_mmap(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0, align = 0;
+	struct mem_region_map *mmap = arg;
+	struct mem_region *mregion;
+	int domain = -1;
+	struct mdp_instance *inst = NULL;
+
+	if (!mmap || !mmap->mregion || !mmap->cookie) {
+		WFD_MSG_ERR("Invalid argument\n");
+		return -EINVAL;
+	}
+
+	inst = mmap->cookie;
+	mregion = mmap->mregion;
+	align = inst->secure ? SZ_1M : SZ_4K;
+	if (mregion->size % align != 0) {
+		WFD_MSG_ERR("Memregion not aligned to %d\n", align);
+		return -EINVAL;
+	}
+
+	if (inst->secure) {
+		rc = msm_ion_secure_buffer(mmap->ion_client,
+			mregion->ion_handle, VIDEO_PIXEL, 0);
+		if (rc) {
+			WFD_MSG_ERR("Failed to secure input buffer\n");
+			goto secure_fail;
+		}
+	}
+
+	domain = msm_fb_get_iommu_domain(inst->mdp,
+			inst->secure ? MDP_IOMMU_DOMAIN_CP :
+					MDP_IOMMU_DOMAIN_NS);
+
+	rc = ion_map_iommu(mmap->ion_client, mregion->ion_handle,
+			domain, 0, align, 0,
+			(unsigned long *)&mregion->paddr,
+			(unsigned long *)&mregion->size,
+			0, 0);
+	if (rc) {
+		WFD_MSG_ERR("Failed to map into %ssecure domain: %d\n",
+				!inst->secure ? "non" : "", rc);
+		goto iommu_fail;
+	}
+
+	return 0;
+iommu_fail:
+	if (inst->secure)
+		msm_ion_unsecure_buffer(mmap->ion_client, mregion->ion_handle);
+secure_fail:
+	return rc;
+}
+
+int mdp_munmap(struct v4l2_subdev *sd, void *arg)
+{
+	struct mem_region_map *mmap = arg;
+	struct mem_region *mregion;
+	int domain = -1;
+	struct mdp_instance *inst = NULL;
+
+	if (!mmap || !mmap->mregion || !mmap->cookie) {
+		WFD_MSG_ERR("Invalid argument\n");
+		return -EINVAL;
+	}
+
+	inst = mmap->cookie;
+	mregion = mmap->mregion;
+
+	domain = msm_fb_get_iommu_domain(inst->mdp,
+			inst->secure ? MDP_IOMMU_DOMAIN_CP :
+					MDP_IOMMU_DOMAIN_NS);
+	ion_unmap_iommu(mmap->ion_client,
+			mregion->ion_handle,
+			domain, 0);
+
+	if (inst->secure)
+		msm_ion_unsecure_buffer(mmap->ion_client, mregion->ion_handle);
+
+	return 0;
+}
+
+int mdp_secure(struct v4l2_subdev *sd, void *arg)
+{
+	struct mdp_instance *inst = NULL;
+	int rc = 0;
+
+	if (!arg) {
+		WFD_MSG_ERR("Invalid argument\n");
+		return -EINVAL;
+	}
+
+	inst = arg;
+	rc = msm_fb_writeback_set_secure(inst->mdp, true);
+	if (!rc)
+		inst->secure = true;
+
+	return rc;
+}
+
+long mdp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+	int rc = 0;
+	if (!sd) {
+		WFD_MSG_ERR("Invalid arguments\n");
+		return -EINVAL;
+	}
+	switch (cmd) {
+	case MDP_Q_BUFFER:
+		rc = mdp_q_buffer(sd, arg);
+		break;
+	case MDP_DQ_BUFFER:
+		rc = mdp_dq_buffer(sd, arg);
+		break;
+	case MDP_OPEN:
+		rc = mdp_open(sd, arg);
+		break;
+	case MDP_START:
+		rc = mdp_start(sd, arg);
+		break;
+	case MDP_STOP:
+		rc = mdp_stop(sd, arg);
+		break;
+	case MDP_SET_PROP:
+		rc = mdp_set_prop(sd, arg);
+		break;
+	case MDP_CLOSE:
+		rc = mdp_close(sd, arg);
+		break;
+	case MDP_MMAP:
+		rc = mdp_mmap(sd, arg);
+		break;
+	case MDP_MUNMAP:
+		rc = mdp_munmap(sd, arg);
+		break;
+	case MDP_SECURE:
+		rc = mdp_secure(sd, arg);
+		break;
+	default:
+		WFD_MSG_ERR("IOCTL: %u not supported\n", cmd);
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
diff --git a/drivers/media/platform/msm/wfd/mdp-dummy-subdev.c b/drivers/media/platform/msm/wfd/mdp-dummy-subdev.c
new file mode 100644
index 0000000..2242c76
--- /dev/null
+++ b/drivers/media/platform/msm/wfd/mdp-dummy-subdev.c
@@ -0,0 +1,202 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 and
+* only version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+*/
+#include <linux/list.h>
+#include <linux/msm_mdp.h>
+#include <media/videobuf2-core.h>
+
+#include "enc-subdev.h"
+#include "mdp-subdev.h"
+#include "wfd-util.h"
+
+struct mdp_buf_queue {
+	struct mdp_buf_info mdp_buf_info;
+	struct list_head node;
+};
+
+struct mdp_instance {
+	struct mdp_buf_queue mdp_bufs;
+	struct mutex mutex;
+};
+
+static int mdp_init(struct v4l2_subdev *sd, u32 val)
+{
+	return 0;
+}
+
+static int mdp_open(struct v4l2_subdev *sd, void *arg)
+{
+	struct mdp_instance *inst = kzalloc(sizeof(struct mdp_instance),
+					GFP_KERNEL);
+	void **cookie = (void **)arg;
+	int rc = 0;
+
+	if (!inst) {
+		WFD_MSG_ERR("Out of memory\n");
+		return -ENOMEM;
+	}
+
+	INIT_LIST_HEAD(&inst->mdp_bufs.node);
+	mutex_init(&inst->mutex);
+	*cookie = inst;
+	return rc;
+}
+
+static int mdp_start(struct v4l2_subdev *sd, void *arg)
+{
+	return 0;
+}
+
+static int mdp_stop(struct v4l2_subdev *sd, void *arg)
+{
+	return 0;
+}
+
+static int mdp_close(struct v4l2_subdev *sd, void *arg)
+{
+	return 0;
+}
+
+static int mdp_q_buffer(struct v4l2_subdev *sd, void *arg)
+{
+	static int foo;
+	int rc = 0;
+	struct mdp_buf_info *binfo = arg;
+	struct mdp_instance *inst = NULL;
+	struct mdp_buf_queue *new_entry = NULL;
+
+	if (!binfo || !binfo->inst || !binfo->cookie) {
+		WFD_MSG_ERR("Invalid argument\n");
+		return -EINVAL;
+	}
+
+	inst = binfo->inst;
+	new_entry = kzalloc(sizeof(*new_entry), GFP_KERNEL);
+	if (!new_entry)
+		return -ENOMEM;
+
+	new_entry->mdp_buf_info = *binfo;
+	if (binfo->kvaddr)
+		memset((void *)binfo->kvaddr, foo++, 1024);
+
+
+	mutex_lock(&inst->mutex);
+	list_add_tail(&new_entry->node, &inst->mdp_bufs.node);
+	mutex_unlock(&inst->mutex);
+
+	WFD_MSG_DBG("Queue %p with cookie %p\n",
+			(void *)binfo->paddr, (void *)binfo->cookie);
+	return rc;
+}
+
+static int mdp_dq_buffer(struct v4l2_subdev *sd, void *arg)
+{
+	struct mdp_buf_info *binfo = arg;
+	struct mdp_buf_queue *head = NULL;
+	struct mdp_instance *inst = NULL;
+
+	inst = binfo->inst;
+
+	while (head == NULL) {
+		mutex_lock(&inst->mutex);
+		if (!list_empty(&inst->mdp_bufs.node))
+			head = list_first_entry(&inst->mdp_bufs.node,
+					struct mdp_buf_queue, node);
+		mutex_unlock(&inst->mutex);
+	}
+
+	if (head == NULL)
+		return -ENOBUFS;
+
+	mutex_lock(&inst->mutex);
+	list_del(&head->node);
+	mutex_unlock(&inst->mutex);
+
+	*binfo = head->mdp_buf_info;
+	WFD_MSG_DBG("Dequeue %p with cookie %p\n",
+		(void *)binfo->paddr, (void *)binfo->cookie);
+	return 0;
+
+}
+
+static int mdp_set_prop(struct v4l2_subdev *sd, void *arg)
+{
+	return 0;
+}
+
+static int mdp_mmap(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0;
+	struct mem_region_map *mmap = arg;
+	struct mem_region *mregion;
+
+	mregion = mmap->mregion;
+	mregion->paddr = mregion->kvaddr;
+	return rc;
+}
+
+static int mdp_munmap(struct v4l2_subdev *sd, void *arg)
+{
+	/* Whatever */
+	return 0;
+}
+
+static int mdp_secure(struct v4l2_subdev *sd)
+{
+	return 0;
+}
+
+long mdp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+	int rc = 0;
+	if (!sd) {
+		WFD_MSG_ERR("Invalid arguments\n");
+		return -EINVAL;
+	}
+	switch (cmd) {
+	case MDP_Q_BUFFER:
+		rc = mdp_q_buffer(sd, arg);
+		break;
+	case MDP_DQ_BUFFER:
+		rc = mdp_dq_buffer(sd, arg);
+		break;
+	case MDP_OPEN:
+		rc = mdp_open(sd, arg);
+		break;
+	case MDP_START:
+		rc = mdp_start(sd, arg);
+		break;
+	case MDP_STOP:
+		rc = mdp_stop(sd, arg);
+		break;
+	case MDP_SET_PROP:
+		rc = mdp_set_prop(sd, arg);
+		break;
+	case MDP_CLOSE:
+		rc = mdp_close(sd, arg);
+		break;
+	case MDP_MMAP:
+		rc = mdp_mmap(sd, arg);
+		break;
+	case MDP_MUNMAP:
+		rc = mdp_munmap(sd, arg);
+		break;
+	case MDP_SECURE:
+		rc = mdp_secure(sd);
+		break;
+	default:
+		WFD_MSG_ERR("IOCTL: %u not supported\n", cmd);
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
diff --git a/drivers/media/platform/msm/wfd/mdp-subdev.h b/drivers/media/platform/msm/wfd/mdp-subdev.h
new file mode 100644
index 0000000..f2c6fb1
--- /dev/null
+++ b/drivers/media/platform/msm/wfd/mdp-subdev.h
@@ -0,0 +1,69 @@
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 and
+* only version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+*/
+
+#ifndef _WFD_MDP_SUBDEV_
+#define _WFD_MDP_SUBDEV_
+
+#include <linux/videodev2.h>
+#include <media/v4l2-subdev.h>
+
+#define MDP_MAGIC_IOCTL 'M'
+
+struct mdp_buf_info {
+	void *inst;
+	void *cookie;
+	u32 fd;
+	u32 offset;
+	u32 kvaddr;
+	u32 paddr;
+};
+
+struct mdp_prop {
+	void *inst;
+	u32 height;
+	u32 width;
+};
+
+struct mdp_msg_ops {
+	void *cookie;
+	bool secure;
+	bool iommu_split_domain;
+};
+
+static inline bool mdp_buf_info_equals(struct mdp_buf_info *a,
+		struct mdp_buf_info *b)
+{
+	return a->inst == b->inst
+		&& a->fd == b->fd
+		&& a->offset == b->offset
+		&& a->kvaddr == b->kvaddr
+		&& a->paddr == b->paddr;
+}
+
+#define MDP_Q_BUFFER  _IOW(MDP_MAGIC_IOCTL, 1, struct mdp_buf_info *)
+#define MDP_DQ_BUFFER  _IOR(MDP_MAGIC_IOCTL, 2, struct mdp_out_buf *)
+#define MDP_OPEN  _IOR(MDP_MAGIC_IOCTL, 3, void **)
+#define MDP_SET_PROP  _IOW(MDP_MAGIC_IOCTL, 4, struct mdp_prop *)
+#define MDP_CLOSE  _IOR(MDP_MAGIC_IOCTL, 5, void *)
+#define MDP_START  _IOR(MDP_MAGIC_IOCTL, 6, void *)
+#define MDP_STOP  _IOR(MDP_MAGIC_IOCTL, 7, void *)
+#define MDP_MMAP  _IOR(MDP_MAGIC_IOCTL, 8, struct mem_region_map *)
+#define MDP_MUNMAP  _IOR(MDP_MAGIC_IOCTL, 9, struct mem_region_map *)
+#define MDP_SECURE  _IO(MDP_MAGIC_IOCTL, 9)
+
+
+extern int mdp_init(struct v4l2_subdev *sd, u32 val);
+extern long mdp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg);
+
+
+#endif /* _WFD_MDP_SUBDEV_ */
diff --git a/drivers/media/platform/msm/wfd/vsg-subdev.c b/drivers/media/platform/msm/wfd/vsg-subdev.c
new file mode 100644
index 0000000..bbe2b7b
--- /dev/null
+++ b/drivers/media/platform/msm/wfd/vsg-subdev.c
@@ -0,0 +1,700 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 and
+* only version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+*/
+#include <linux/hrtimer.h>
+#include <linux/time.h>
+#include <linux/list.h>
+#include <media/videobuf2-core.h>
+#include "enc-subdev.h"
+#include "vsg-subdev.h"
+#include "wfd-util.h"
+
+#define DEFAULT_FRAME_INTERVAL (66*NSEC_PER_MSEC)
+#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
+
+static int vsg_release_input_buffer(struct vsg_context *context,
+		struct vsg_buf_info *buf)
+{
+	WFD_MSG_DBG("Releasing frame with ts %lld ms, paddr %p\n",
+			timespec_to_ns(&buf->time),
+			(void *)buf->mdp_buf_info.paddr);
+
+	if (buf->flags & VSG_NEVER_RELEASE)
+		WFD_MSG_WARN("Warning releasing buffer that's"
+				"not supposed to be released\n");
+
+	return context->vmops.release_input_frame(context->vmops.cbdata,
+			buf);
+
+}
+
+static int vsg_encode_frame(struct vsg_context *context,
+		struct vsg_buf_info *buf)
+{
+	WFD_MSG_DBG("Encoding frame with ts %lld ms, paddr %p\n",
+			timespec_to_ns(&buf->time),
+			(void *)buf->mdp_buf_info.paddr);
+
+	return context->vmops.encode_frame(context->vmops.cbdata,
+			buf);
+}
+
+static void vsg_set_last_buffer(struct vsg_context *context,
+		struct vsg_buf_info *buf)
+{
+	if (buf->flags & VSG_NEVER_SET_LAST_BUFFER)
+		WFD_MSG_WARN("Shouldn't be setting this to last buffer\n");
+
+	context->last_buffer = buf;
+
+	WFD_MSG_DBG("Setting last buffer to paddr %p\n",
+			(void *)buf->mdp_buf_info.paddr);
+}
+
+static void vsg_encode_helper_func(struct work_struct *task)
+{
+	struct vsg_encode_work *work =
+		container_of(task, struct vsg_encode_work, work);
+
+	/*
+	 * Note: don't need to lock for context below as we only
+	 * access fields that are "static".
+	 */
+	int rc = vsg_encode_frame(work->context, work->buf);
+	if (rc < 0) {
+		mutex_lock(&work->context->mutex);
+		work->context->state = VSG_STATE_ERROR;
+		mutex_unlock(&work->context->mutex);
+	}
+	kfree(work);
+}
+
+static void vsg_work_func(struct work_struct *task)
+{
+	struct vsg_work *work =
+		container_of(task, struct vsg_work, work);
+	struct vsg_encode_work *encode_work;
+	struct vsg_context *context = work->context;
+	struct vsg_buf_info *buf_info = NULL, *temp = NULL;
+	int rc = 0, count = 0;
+	mutex_lock(&context->mutex);
+
+	if (list_empty(&context->free_queue.node)) {
+		WFD_MSG_DBG("%s: queue empty doing nothing\n", __func__);
+		goto err_skip_encode;
+	} else if (context->state != VSG_STATE_STARTED) {
+		WFD_MSG_DBG("%s: vsg is stopped or in error state "
+				"doing nothing\n", __func__);
+		goto err_skip_encode;
+	}
+
+	list_for_each_entry(temp, &context->busy_queue.node, node) {
+		if (++count > MAX_BUFS_BUSY_WITH_ENC) {
+			WFD_MSG_WARN("Skipping encode, too many "
+				"buffers with encoder");
+			goto err_skip_encode;
+		}
+	}
+
+	buf_info = list_first_entry(&context->free_queue.node,
+			struct vsg_buf_info, node);
+	list_del(&buf_info->node);
+	INIT_LIST_HEAD(&buf_info->node);
+
+	ktime_get_ts(&buf_info->time);
+	hrtimer_forward_now(&context->threshold_timer, ns_to_ktime(
+				context->max_frame_interval));
+
+	temp = NULL;
+	list_for_each_entry(temp, &context->busy_queue.node, node) {
+		if (mdp_buf_info_equals(&temp->mdp_buf_info,
+					&buf_info->mdp_buf_info)) {
+			temp->flags |= VSG_NEVER_RELEASE;
+		}
+	}
+
+	if (context->last_buffer &&
+		mdp_buf_info_equals(&context->last_buffer->mdp_buf_info,
+			&buf_info->mdp_buf_info)) {
+		context->last_buffer->flags |= VSG_NEVER_RELEASE;
+	}
+
+	encode_work = kmalloc(sizeof(*encode_work), GFP_KERNEL);
+	encode_work->buf = buf_info;
+	encode_work->context = context;
+	INIT_WORK(&encode_work->work, vsg_encode_helper_func);
+	rc = queue_work(context->work_queue, &encode_work->work);
+	if (!rc) {
+		WFD_MSG_ERR("Queueing buffer for encode failed\n");
+		kfree(encode_work);
+		encode_work = NULL;
+		goto err_skip_encode;
+	}
+
+	buf_info->flags |= VSG_BUF_BEING_ENCODED;
+	if (!(buf_info->flags & VSG_NEVER_SET_LAST_BUFFER)) {
+		if (context->last_buffer) {
+			struct vsg_buf_info *old_last_buffer =
+				context->last_buffer;
+			bool last_buf_with_us = old_last_buffer &&
+				!(old_last_buffer->flags &
+					VSG_BUF_BEING_ENCODED);
+			bool can_release = old_last_buffer &&
+				!(old_last_buffer->flags &
+					VSG_NEVER_RELEASE);
+
+			if (old_last_buffer && last_buf_with_us
+				&& can_release) {
+				vsg_release_input_buffer(context,
+					old_last_buffer);
+				kfree(old_last_buffer);
+			}
+		}
+		vsg_set_last_buffer(context, buf_info);
+	}
+
+	list_add_tail(&buf_info->node, &context->busy_queue.node);
+err_skip_encode:
+	mutex_unlock(&context->mutex);
+	kfree(work);
+}
+
+static void vsg_timer_helper_func(struct work_struct *task)
+{
+	struct vsg_work *work =
+		container_of(task, struct vsg_work, work);
+	struct vsg_work *new_work = NULL;
+	struct vsg_context *context = work->context;
+	int num_bufs_to_queue = 1, c = 0;
+
+	mutex_lock(&context->mutex);
+
+	if (context->state != VSG_STATE_STARTED)
+		goto err_locked;
+
+	if (list_empty(&context->free_queue.node)
+		&& context->last_buffer) {
+		struct vsg_buf_info *info = NULL, *buf_to_encode = NULL;
+
+		if (context->mode == VSG_MODE_CFR)
+			num_bufs_to_queue = 1;
+		else if (context->mode == VSG_MODE_VFR)
+			num_bufs_to_queue = 2;
+
+		for (c = 0; c < num_bufs_to_queue; ++c) {
+			info = kzalloc(sizeof(*info), GFP_KERNEL);
+
+			if (!info) {
+				WFD_MSG_ERR("Couldn't allocate memory in %s\n",
+					__func__);
+				goto err_locked;
+			}
+
+			buf_to_encode = context->last_buffer;
+
+			info->mdp_buf_info = buf_to_encode->mdp_buf_info;
+			info->flags = 0;
+			INIT_LIST_HEAD(&info->node);
+
+			list_add_tail(&info->node, &context->free_queue.node);
+			WFD_MSG_DBG("Regenerated frame with paddr %p\n",
+				(void *)info->mdp_buf_info.paddr);
+		}
+	}
+
+	for (c = 0; c < num_bufs_to_queue; ++c) {
+		new_work = kzalloc(sizeof(*new_work), GFP_KERNEL);
+		if (!new_work) {
+			WFD_MSG_ERR("Unable to allocate memory"
+					"to queue buffer\n");
+			goto err_locked;
+		}
+
+		INIT_WORK(&new_work->work, vsg_work_func);
+		new_work->context = context;
+		queue_work(context->work_queue, &new_work->work);
+	}
+
+err_locked:
+	mutex_unlock(&context->mutex);
+	kfree(work);
+}
+
+static enum hrtimer_restart vsg_threshold_timeout_func(struct hrtimer *timer)
+{
+	struct vsg_context *context = NULL;
+	struct vsg_work *task = NULL;
+
+	task = kzalloc(sizeof(*task), GFP_ATOMIC);
+	context = container_of(timer, struct vsg_context,
+			threshold_timer);
+	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;
+
+	queue_work(context->work_queue, &task->work);
+threshold_err_bad_param:
+	hrtimer_forward_now(&context->threshold_timer, ns_to_ktime(
+				context->max_frame_interval));
+	return HRTIMER_RESTART;
+threshold_err_no_context:
+	return HRTIMER_NORESTART;
+}
+
+int vsg_init(struct v4l2_subdev *sd, u32 val)
+{
+	return 0;
+}
+
+static int vsg_open(struct v4l2_subdev *sd, void *arg)
+{
+	struct vsg_context *context = NULL;
+
+	if (!arg || !sd)
+		return -EINVAL;
+
+	context = kzalloc(sizeof(*context), GFP_KERNEL);
+	INIT_LIST_HEAD(&context->free_queue.node);
+	INIT_LIST_HEAD(&context->busy_queue.node);
+
+	context->vmops = *(struct vsg_msg_ops *)arg;
+	context->work_queue = create_singlethread_workqueue("v4l-vsg");
+
+	context->frame_interval = DEFAULT_FRAME_INTERVAL;
+	context->max_frame_interval = DEFAULT_MAX_FRAME_INTERVAL;
+
+	hrtimer_init(&context->threshold_timer, CLOCK_MONOTONIC,
+			HRTIMER_MODE_REL);
+	context->threshold_timer.function = vsg_threshold_timeout_func;
+
+	context->last_buffer = NULL;
+	context->mode = DEFAULT_MODE;
+	context->state = VSG_STATE_NONE;
+	mutex_init(&context->mutex);
+
+	sd->dev_priv = context;
+	return 0;
+}
+
+static int vsg_close(struct v4l2_subdev *sd)
+{
+	struct vsg_context *context = NULL;
+
+	if (!sd)
+		return -EINVAL;
+
+	context = (struct vsg_context *)sd->dev_priv;
+	destroy_workqueue(context->work_queue);
+	kfree(context);
+	return 0;
+}
+
+static int vsg_start(struct v4l2_subdev *sd)
+{
+	struct vsg_context *context = NULL;
+
+	if (!sd) {
+		WFD_MSG_ERR("ERROR, invalid arguments into %s\n", __func__);
+		return -EINVAL;
+	}
+
+	context = (struct vsg_context *)sd->dev_priv;
+
+	if (context->state == VSG_STATE_STARTED) {
+		WFD_MSG_ERR("VSG not stopped, start not allowed\n");
+		return -EINPROGRESS;
+	} else if (context->state == VSG_STATE_ERROR) {
+		WFD_MSG_ERR("VSG in error state, not allowed to restart\n");
+		return -ENOTRECOVERABLE;
+	}
+
+	context->state = VSG_STATE_STARTED;
+	hrtimer_start(&context->threshold_timer, ns_to_ktime(context->
+			max_frame_interval), HRTIMER_MODE_REL);
+	return 0;
+}
+
+static int vsg_stop(struct v4l2_subdev *sd)
+{
+	struct vsg_context *context = NULL;
+
+	if (!sd) {
+		WFD_MSG_ERR("ERROR, invalid arguments into %s\n", __func__);
+		return -EINVAL;
+	}
+
+	context = (struct vsg_context *)sd->dev_priv;
+
+	mutex_lock(&context->mutex);
+	context->state = VSG_STATE_STOPPED;
+	{ /*delete pending buffers as we're not going to encode them*/
+		struct list_head *pos, *next;
+		list_for_each_safe(pos, next, &context->free_queue.node) {
+			struct vsg_buf_info *temp =
+				list_entry(pos, struct vsg_buf_info, node);
+			list_del(&temp->node);
+			kfree(temp);
+		}
+	}
+
+	hrtimer_cancel(&context->threshold_timer);
+
+	mutex_unlock(&context->mutex);
+
+	flush_workqueue(context->work_queue);
+	return 0;
+}
+
+static long vsg_queue_buffer(struct v4l2_subdev *sd, void *arg)
+{
+	struct vsg_context *context = NULL;
+	struct vsg_buf_info *buf_info = kzalloc(sizeof(*buf_info), GFP_KERNEL);
+	int rc = 0;
+	bool push = false;
+
+	if (!arg || !sd) {
+		WFD_MSG_ERR("ERROR, invalid arguments into %s\n", __func__);
+		rc = -EINVAL;
+		goto queue_err_bad_param;
+	} else if (!buf_info) {
+		WFD_MSG_ERR("ERROR, out of memory in %s\n", __func__);
+		rc = -ENOMEM;
+		goto queue_err_bad_param;
+	}
+
+	context = (struct vsg_context *)sd->dev_priv;
+	mutex_lock(&context->mutex);
+
+	*buf_info = *(struct vsg_buf_info *)arg;
+	INIT_LIST_HEAD(&buf_info->node);
+	buf_info->flags = 0;
+	ktime_get_ts(&buf_info->time);
+
+	WFD_MSG_DBG("Queue frame with paddr %p\n",
+			(void *)buf_info->mdp_buf_info.paddr);
+
+	{ /*return pending buffers as we're not going to encode them*/
+		struct list_head *pos, *next;
+		list_for_each_safe(pos, next, &context->free_queue.node) {
+			struct vsg_buf_info *temp =
+				list_entry(pos, struct vsg_buf_info, node);
+			bool is_last_buffer = context->last_buffer &&
+				mdp_buf_info_equals(
+					&context->last_buffer->mdp_buf_info,
+					&temp->mdp_buf_info);
+
+			list_del(&temp->node);
+
+			if (!is_last_buffer &&
+				!(temp->flags & VSG_NEVER_RELEASE)) {
+				vsg_release_input_buffer(context, temp);
+				kfree(temp);
+			}
+		}
+	}
+
+	list_add_tail(&buf_info->node, &context->free_queue.node);
+
+	if (context->mode == VSG_MODE_VFR) {
+		if (!context->last_buffer)
+			push = true;
+		else {
+			struct timespec diff = timespec_sub(buf_info->time,
+					context->last_buffer->time);
+			struct timespec temp = ns_to_timespec(
+						context->frame_interval);
+
+			if (timespec_compare(&diff, &temp) >= 0)
+				push = true;
+		}
+	} else if (context->mode == VSG_MODE_CFR) {
+		if (!context->last_buffer) {
+			push = true;
+			/*
+			 * We need to reset the timer after pushing the buffer
+			 * otherwise, diff between two consecutive frames might
+			 * be less than max_frame_interval (for just one sample)
+			 */
+			hrtimer_forward_now(&context->threshold_timer,
+				ns_to_ktime(context->max_frame_interval));
+		}
+	}
+
+	if (push) {
+		struct vsg_work *new_work =
+			kzalloc(sizeof(*new_work), GFP_KERNEL);
+
+		INIT_WORK(&new_work->work, vsg_work_func);
+		new_work->context = context;
+		queue_work(context->work_queue, &new_work->work);
+	}
+
+	mutex_unlock(&context->mutex);
+queue_err_bad_param:
+	if (rc < 0)
+		kfree(buf_info);
+
+	return rc;
+}
+
+static long vsg_return_ip_buffer(struct v4l2_subdev *sd, void *arg)
+{
+	struct vsg_context *context = NULL;
+	struct vsg_buf_info *buf_info, *last_buffer,
+			*expected_buffer;
+	int rc = 0;
+
+	if (!arg || !sd) {
+		WFD_MSG_ERR("ERROR, invalid arguments into %s\n", __func__);
+		rc = -EINVAL;
+		goto return_ip_buf_err_bad_param;
+	}
+
+	context = (struct vsg_context *)sd->dev_priv;
+	mutex_lock(&context->mutex);
+	buf_info = (struct vsg_buf_info *)arg;
+	last_buffer = context->last_buffer;
+
+	expected_buffer = list_first_entry(&context->busy_queue.node,
+			struct vsg_buf_info, node);
+
+	WFD_MSG_DBG("Return frame with paddr %p\n",
+			(void *)buf_info->mdp_buf_info.paddr);
+
+	if (!expected_buffer) {
+		WFD_MSG_ERR("Unexpectedly received buffer from enc with "
+			"paddr %p\n", (void *)buf_info->mdp_buf_info.paddr);
+		goto return_ip_buf_bad_buf;
+	}
+
+	expected_buffer->flags &= ~VSG_BUF_BEING_ENCODED;
+	if (mdp_buf_info_equals(&expected_buffer->mdp_buf_info,
+				&buf_info->mdp_buf_info)) {
+		bool is_same_buffer = context->last_buffer &&
+			mdp_buf_info_equals(
+					&context->last_buffer->mdp_buf_info,
+					&expected_buffer->mdp_buf_info);
+
+		list_del(&expected_buffer->node);
+		if (!is_same_buffer &&
+			!(expected_buffer->flags & VSG_NEVER_RELEASE)) {
+			vsg_release_input_buffer(context, expected_buffer);
+			kfree(expected_buffer);
+		}
+	} else {
+		WFD_MSG_ERR("Returned buffer %p is not latest buffer, "
+				"expected %p\n",
+				(void *)buf_info->mdp_buf_info.paddr,
+				(void *)expected_buffer->mdp_buf_info.paddr);
+		rc = -EINVAL;
+		goto return_ip_buf_bad_buf;
+	}
+
+return_ip_buf_bad_buf:
+	mutex_unlock(&context->mutex);
+return_ip_buf_err_bad_param:
+	return rc;
+}
+
+static long vsg_set_frame_interval(struct v4l2_subdev *sd, void *arg)
+{
+	struct vsg_context *context = NULL;
+	int64_t interval;
+
+	if (!arg || !sd) {
+		WFD_MSG_ERR("ERROR, invalid arguments into %s\n", __func__);
+		return -EINVAL;
+	}
+
+	context = (struct vsg_context *)sd->dev_priv;
+	interval = *(int64_t *)arg;
+
+	if (interval <= 0) {
+		WFD_MSG_ERR("ERROR, invalid interval %lld into %s\n",
+				interval, __func__);
+		return -EINVAL;
+	}
+
+	mutex_lock(&context->mutex);
+
+	context->frame_interval = interval;
+	if (interval > context->max_frame_interval) {
+		WFD_MSG_WARN("Changing max frame interval from %lld to %lld\n",
+				context->max_frame_interval, interval);
+		context->max_frame_interval = interval;
+	}
+
+	mutex_unlock(&context->mutex);
+	return 0;
+}
+
+static long vsg_get_frame_interval(struct v4l2_subdev *sd, void *arg)
+{
+	struct vsg_context *context = NULL;
+
+	if (!arg || !sd) {
+		WFD_MSG_ERR("ERROR, invalid arguments into %s\n", __func__);
+		return -EINVAL;
+	}
+
+	context = (struct vsg_context *)sd->dev_priv;
+	mutex_lock(&context->mutex);
+	*(int64_t *)arg = context->frame_interval;
+	mutex_unlock(&context->mutex);
+
+	return 0;
+}
+
+static long vsg_set_max_frame_interval(struct v4l2_subdev *sd, void *arg)
+{
+	struct vsg_context *context = NULL;
+	int64_t interval;
+
+	if (!arg || !sd) {
+		WFD_MSG_ERR("ERROR, invalid arguments into %s\n", __func__);
+		return -EINVAL;
+	}
+
+	context = (struct vsg_context *)sd->dev_priv;
+	interval = *(int64_t *)arg;
+
+	if (interval <= 0) {
+		WFD_MSG_ERR("ERROR, invalid interval %lld into %s\n",
+				interval, __func__);
+		return -EINVAL;
+	}
+
+	mutex_lock(&context->mutex);
+
+	context->max_frame_interval = interval;
+	if (interval < context->frame_interval) {
+		WFD_MSG_WARN("Changing frame interval from %lld to %lld\n",
+				context->frame_interval, interval);
+		context->frame_interval = interval;
+	}
+
+	mutex_unlock(&context->mutex);
+
+	return 0;
+}
+
+static long vsg_get_max_frame_interval(struct v4l2_subdev *sd, void *arg)
+{
+	struct vsg_context *context = NULL;
+
+	if (!arg || !sd) {
+		WFD_MSG_ERR("ERROR, invalid arguments into %s\n", __func__);
+		return -EINVAL;
+	}
+
+	context = (struct vsg_context *)sd->dev_priv;
+	mutex_lock(&context->mutex);
+	*(int64_t *)arg = context->max_frame_interval;
+	mutex_unlock(&context->mutex);
+
+	return 0;
+}
+
+static long vsg_set_mode(struct v4l2_subdev *sd, void *arg)
+{
+	struct vsg_context *context = NULL;
+	enum vsg_modes *mode = NULL;
+	int rc = 0;
+
+	if (!arg || !sd) {
+		WFD_MSG_ERR("ERROR, invalid arguments into %s\n", __func__);
+		rc = -EINVAL;
+		goto set_mode_err_bad_parm;
+	}
+
+	context = (struct vsg_context *)sd->dev_priv;
+	mutex_lock(&context->mutex);
+	mode = arg;
+
+	switch (*mode) {
+	case VSG_MODE_CFR:
+		context->max_frame_interval = context->frame_interval;
+		/*fall through*/
+	case VSG_MODE_VFR:
+		context->mode = *mode;
+		break;
+	default:
+		context->mode = DEFAULT_MODE;
+		rc = -EINVAL;
+		goto set_mode_err_bad_mode;
+		break;
+	}
+
+set_mode_err_bad_mode:
+	mutex_unlock(&context->mutex);
+set_mode_err_bad_parm:
+	return rc;
+}
+
+long vsg_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+	int rc = 0;
+
+	WFD_MSG_DBG("VSG ioctl: %d\n", cmd);
+	if (sd == NULL)
+		return -EINVAL;
+
+	switch (cmd) {
+	case VSG_OPEN:
+		rc = vsg_open(sd, arg);
+		break;
+	case VSG_CLOSE:
+		rc = vsg_close(sd);
+		break;
+	case VSG_START:
+		rc = vsg_start(sd);
+		break;
+	case VSG_STOP:
+		rc = vsg_stop(sd);
+		break;
+	case VSG_Q_BUFFER:
+		rc = vsg_queue_buffer(sd, arg);
+		break;
+	case VSG_RETURN_IP_BUFFER:
+		rc = vsg_return_ip_buffer(sd, arg);
+		break;
+	case VSG_GET_FRAME_INTERVAL:
+		rc = vsg_get_frame_interval(sd, arg);
+		break;
+	case VSG_SET_FRAME_INTERVAL:
+		rc = vsg_set_frame_interval(sd, arg);
+		break;
+	case VSG_GET_MAX_FRAME_INTERVAL:
+		rc = vsg_get_max_frame_interval(sd, arg);
+		break;
+	case VSG_SET_MAX_FRAME_INTERVAL:
+		rc = vsg_set_max_frame_interval(sd, arg);
+		break;
+	case VSG_SET_MODE:
+		rc = vsg_set_mode(sd, arg);
+		break;
+	default:
+		rc = -ENOTSUPP;
+		break;
+	}
+
+	return rc;
+}
diff --git a/drivers/media/platform/msm/wfd/vsg-subdev.h b/drivers/media/platform/msm/wfd/vsg-subdev.h
new file mode 100644
index 0000000..f5e4f5d
--- /dev/null
+++ b/drivers/media/platform/msm/wfd/vsg-subdev.h
@@ -0,0 +1,100 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 and
+* only version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+*/
+
+#ifndef _WFD_VSG_SUBDEV_
+#define _WFD_VSG_SUBDEV_
+
+#include <linux/videodev2.h>
+#include <linux/list.h>
+#include <linux/ktime.h>
+#include <linux/workqueue.h>
+#include <media/v4l2-subdev.h>
+#include "mdp-subdev.h"
+
+#define VSG_MAGIC_IOCTL 'V'
+
+enum vsg_flags {
+	VSG_NEVER_RELEASE = 1<<0,
+	VSG_NEVER_SET_LAST_BUFFER = 1<<1,
+	VSG_BUF_BEING_ENCODED = 1<<2,
+};
+
+enum vsg_modes {
+	VSG_MODE_CFR,
+	VSG_MODE_VFR,
+};
+
+enum vsg_states {
+	VSG_STATE_NONE,
+	VSG_STATE_STARTED,
+	VSG_STATE_STOPPED,
+	VSG_STATE_ERROR
+};
+
+struct vsg_buf_info {
+	struct mdp_buf_info mdp_buf_info;
+	struct timespec time;
+	/* Internal */
+	struct list_head node;
+	uint32_t flags;
+};
+
+struct vsg_msg_ops {
+	void *cbdata;
+	int (*encode_frame)(void *cbdata, struct vsg_buf_info *buffer);
+	int (*release_input_frame)(void *cbdata, struct vsg_buf_info *buffer);
+};
+
+struct vsg_context {
+	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;
+	struct workqueue_struct *work_queue;
+	struct hrtimer threshold_timer;
+	struct mutex mutex;
+	struct vsg_buf_info *last_buffer;
+	int mode;
+	int state;
+};
+
+struct vsg_work {
+	struct vsg_context *context;
+	struct work_struct work;
+};
+
+struct vsg_encode_work {
+	struct vsg_buf_info *buf;
+	struct vsg_context *context;
+	struct work_struct work;
+};
+
+#define VSG_OPEN  _IO(VSG_MAGIC_IOCTL, 1)
+#define VSG_CLOSE  _IO(VSG_MAGIC_IOCTL, 2)
+#define VSG_START  _IO(VSG_MAGIC_IOCTL, 3)
+#define VSG_STOP  _IO(VSG_MAGIC_IOCTL, 4)
+#define VSG_Q_BUFFER  _IOW(VSG_MAGIC_IOCTL, 5, struct vsg_buf_info *)
+#define VSG_DQ_BUFFER  _IOR(VSG_MAGIC_IOCTL, 6, struct vsg_out_buf *)
+#define VSG_RETURN_IP_BUFFER _IOW(VSG_MAGIC_IOCTL, 7, struct vsg_buf_info *)
+#define VSG_ENCODE_DONE _IO(VSG_MAGIC_IOCTL, 8)
+/* Time related arguments for frame interval ioctls are always in nanosecs*/
+#define VSG_SET_FRAME_INTERVAL _IOW(VSG_MAGIC_IOCTL, 9, int64_t *)
+#define VSG_GET_FRAME_INTERVAL _IOR(VSG_MAGIC_IOCTL, 10, int64_t *)
+#define VSG_SET_MAX_FRAME_INTERVAL _IOW(VSG_MAGIC_IOCTL, 11, int64_t *)
+#define VSG_GET_MAX_FRAME_INTERVAL _IOR(VSG_MAGIC_IOCTL, 12, int64_t *)
+#define VSG_SET_MODE _IOW(VSG_MAGIC_IOCTL, 13, enum vsg_modes *)
+
+extern int vsg_init(struct v4l2_subdev *sd, u32 val);
+extern long vsg_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg);
+
+#endif /* _WFD_VSG_SUBDEV_ */
diff --git a/drivers/media/platform/msm/wfd/wfd-ioctl.c b/drivers/media/platform/msm/wfd/wfd-ioctl.c
new file mode 100644
index 0000000..9fb7c6d
--- /dev/null
+++ b/drivers/media/platform/msm/wfd/wfd-ioctl.c
@@ -0,0 +1,1713 @@
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/ioctl.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/version.h>
+#include <linux/platform_device.h>
+#include <linux/android_pmem.h>
+#include <linux/sched.h>
+#include <linux/kthread.h>
+#include <linux/time.h>
+#include <mach/board.h>
+
+#include <media/v4l2-dev.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-msm-mem.h>
+#include "wfd-util.h"
+#include "mdp-subdev.h"
+#include "enc-subdev.h"
+#include "vsg-subdev.h"
+
+#define WFD_VERSION KERNEL_VERSION(0, 0, 1)
+#define WFD_NUM_DEVICES 2
+#define WFD_DEVICE_NUMBER_BASE 38
+#define WFD_DEVICE_SECURE (WFD_DEVICE_NUMBER_BASE + 1)
+#define DEFAULT_WFD_WIDTH 1280
+#define DEFAULT_WFD_HEIGHT 720
+#define VENC_INPUT_BUFFERS 4
+
+struct wfd_device {
+	struct mutex dev_lock;
+	struct platform_device *pdev;
+	struct v4l2_device v4l2_dev;
+	struct video_device *pvdev;
+	struct v4l2_subdev mdp_sdev;
+	struct v4l2_subdev enc_sdev;
+	struct v4l2_subdev vsg_sdev;
+	struct ion_client *ion_client;
+	bool secure;
+	bool in_use;
+	bool mdp_iommu_split_domain;
+};
+
+struct mem_info {
+	u32 fd;
+	u32 offset;
+};
+
+struct mem_info_entry {
+	struct list_head list;
+	unsigned long userptr;
+	struct mem_info minfo;
+};
+
+struct mem_region_pair {
+	struct mem_region *enc;
+	struct mem_region *mdp;
+	struct list_head list;
+};
+
+struct wfd_inst {
+	struct vb2_queue vid_bufq;
+	spinlock_t inst_lock;
+	u32 buf_count;
+	struct task_struct *mdp_task;
+	void *mdp_inst;
+	void *venc_inst;
+	u32 height;
+	u32 width;
+	u32 pixelformat;
+	struct list_head minfo_list;
+	bool streamoff;
+	u32 input_bufs_allocated;
+	u32 input_buf_size;
+	u32 out_buf_size;
+	struct list_head input_mem_list;
+	struct wfd_stats stats;
+	struct completion stop_mdp_thread;
+};
+
+struct wfd_vid_buffer {
+	struct vb2_buffer    vidbuf;
+};
+
+static int wfd_vidbuf_queue_setup(struct vb2_queue *q,
+				   const struct v4l2_format *fmt,
+				   unsigned int *num_buffers,
+				   unsigned int *num_planes,
+				   unsigned int sizes[], void *alloc_ctxs[])
+{
+	struct file *priv_data = (struct file *)(q->drv_priv);
+	struct wfd_inst *inst = (struct wfd_inst *)priv_data->private_data;
+	unsigned long flags;
+	int i;
+
+	WFD_MSG_DBG("In %s\n", __func__);
+	if (num_buffers == NULL || num_planes == NULL)
+		return -EINVAL;
+
+	*num_planes = 1;
+	spin_lock_irqsave(&inst->inst_lock, flags);
+	for (i = 0; i < *num_planes; ++i) {
+		sizes[i] = inst->out_buf_size;
+		alloc_ctxs[i] = inst;
+	}
+	spin_unlock_irqrestore(&inst->inst_lock, flags);
+
+	return 0;
+}
+
+void wfd_vidbuf_wait_prepare(struct vb2_queue *q)
+{
+}
+void wfd_vidbuf_wait_finish(struct vb2_queue *q)
+{
+}
+
+static unsigned long wfd_enc_addr_to_mdp_addr(struct wfd_inst *inst,
+		unsigned long addr)
+{
+	struct list_head *ptr, *next;
+	struct mem_region_pair *mpair;
+	if (!list_empty(&inst->input_mem_list)) {
+		list_for_each_safe(ptr, next,
+				&inst->input_mem_list) {
+			mpair = list_entry(ptr, struct mem_region_pair,
+					list);
+			if (mpair->enc->paddr == (u8 *)addr)
+				return (unsigned long)mpair->mdp->paddr;
+		}
+	}
+
+	return (unsigned long)NULL;
+}
+
+static int wfd_allocate_ion_buffer(struct ion_client *client,
+		bool secure, struct mem_region *mregion)
+{
+	struct ion_handle *handle = NULL;
+	void *kvaddr = NULL;
+	unsigned int alloc_regions = 0, ion_flags = 0, align = 0;
+	int rc = 0;
+
+	alloc_regions = ION_HEAP(ION_CP_MM_HEAP_ID);
+	alloc_regions |= secure ? 0 :
+				ION_HEAP(ION_IOMMU_HEAP_ID);
+	ion_flags |= secure ? ION_SECURE : 0;
+	align = secure ? SZ_1M : SZ_4K;
+	handle = ion_alloc(client, mregion->size, align,
+			alloc_regions, ion_flags);
+
+	if (IS_ERR_OR_NULL(handle)) {
+		WFD_MSG_ERR("Failed to allocate input buffer\n");
+		rc = PTR_ERR(handle);
+		goto alloc_fail;
+	}
+
+	if (!secure) {
+		kvaddr = ion_map_kernel(client, handle);
+
+		if (IS_ERR_OR_NULL(kvaddr)) {
+			WFD_MSG_ERR("Failed to get virtual addr\n");
+			rc = PTR_ERR(kvaddr);
+			goto alloc_fail;
+		}
+	} else {
+		kvaddr = NULL;
+	}
+
+	mregion->kvaddr = kvaddr;
+	mregion->ion_handle = handle;
+
+	return rc;
+alloc_fail:
+	if (!IS_ERR_OR_NULL(handle)) {
+		if (!IS_ERR_OR_NULL(kvaddr))
+			ion_unmap_kernel(client, handle);
+
+		ion_free(client, handle);
+
+		mregion->kvaddr = NULL;
+		mregion->paddr = NULL;
+		mregion->ion_handle = NULL;
+	}
+	return rc;
+}
+
+/* Doesn't do iommu unmap */
+static int wfd_free_ion_buffer(struct ion_client *client,
+		struct mem_region *mregion)
+{
+	if (!client || !mregion) {
+		WFD_MSG_ERR("Failed to free ion buffer: "
+				"Invalid client or region");
+		return -EINVAL;
+	}
+	if (mregion->kvaddr)
+		ion_unmap_kernel(client, mregion->ion_handle);
+	ion_free(client, mregion->ion_handle);
+	return 0;
+}
+
+static int wfd_flush_ion_buffer(struct ion_client *client,
+		struct mem_region *mregion)
+{
+	if (!client || !mregion) {
+		WFD_MSG_ERR("Failed to flush ion buffer: "
+				"Invalid client or region");
+		return -EINVAL;
+	} else if (!mregion->ion_handle) {
+		WFD_MSG_ERR("Failed to flush ion buffer: "
+				"not an ion buffer");
+		return -EINVAL;
+	}
+
+	return msm_ion_do_cache_op(client,
+			mregion->ion_handle,
+			mregion->kvaddr,
+			mregion->size,
+			ION_IOC_INV_CACHES);
+
+}
+int wfd_allocate_input_buffers(struct wfd_device *wfd_dev,
+			struct wfd_inst *inst)
+{
+	int i;
+	struct mem_region *enc_mregion, *mdp_mregion;
+	struct mem_region_pair *mpair;
+	int rc;
+	unsigned long flags;
+	struct mdp_buf_info mdp_buf = {0};
+	struct mem_region_map mmap_context = {0};
+	spin_lock_irqsave(&inst->inst_lock, flags);
+	if (inst->input_bufs_allocated) {
+		spin_unlock_irqrestore(&inst->inst_lock, flags);
+		return 0;
+	}
+	inst->input_bufs_allocated = true;
+	spin_unlock_irqrestore(&inst->inst_lock, flags);
+
+	for (i = 0; i < VENC_INPUT_BUFFERS; ++i) {
+		mpair = kzalloc(sizeof(*mpair), GFP_KERNEL);
+		enc_mregion = kzalloc(sizeof(*enc_mregion), GFP_KERNEL);
+		mdp_mregion = kzalloc(sizeof(*enc_mregion), GFP_KERNEL);
+		enc_mregion->size = ALIGN(inst->input_buf_size, SZ_4K);
+
+		rc = wfd_allocate_ion_buffer(wfd_dev->ion_client,
+				wfd_dev->secure, enc_mregion);
+		if (rc) {
+			WFD_MSG_ERR("Failed to allocate input memory\n");
+			goto alloc_fail;
+		}
+
+		mmap_context.mregion = enc_mregion;
+		mmap_context.ion_client = wfd_dev->ion_client;
+		rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
+				ENC_MMAP, &mmap_context);
+		if (rc || !enc_mregion->paddr) {
+			WFD_MSG_ERR("Failed to map input memory\n");
+			goto alloc_fail;
+		}
+
+		WFD_MSG_DBG("NOTE: enc paddr = [%p->%p], kvaddr = %p\n",
+				enc_mregion->paddr, (int8_t *)
+				enc_mregion->paddr + enc_mregion->size,
+				enc_mregion->kvaddr);
+
+		rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
+				SET_INPUT_BUFFER, (void *)enc_mregion);
+		if (rc) {
+			WFD_MSG_ERR("Setting enc input buffer failed\n");
+			goto set_input_fail;
+		}
+
+		/* map the buffer from encoder to mdp */
+		mdp_mregion->kvaddr = enc_mregion->kvaddr;
+		mdp_mregion->size = enc_mregion->size;
+		mdp_mregion->offset = enc_mregion->offset;
+		mdp_mregion->fd = enc_mregion->fd;
+		mdp_mregion->cookie = 0;
+		mdp_mregion->ion_handle = enc_mregion->ion_handle;
+
+		memset(&mmap_context, 0, sizeof(mmap_context));
+		mmap_context.mregion = mdp_mregion;
+		mmap_context.ion_client = wfd_dev->ion_client;
+		mmap_context.cookie = inst->mdp_inst;
+		rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl,
+				MDP_MMAP, (void *)&mmap_context);
+
+		if (rc || !mdp_mregion->paddr) {
+			WFD_MSG_ERR(
+				"Failed to map to mdp, rc = %d, paddr = 0x%p\n",
+				rc, mdp_mregion->paddr);
+			mdp_mregion->kvaddr = NULL;
+			mdp_mregion->paddr = NULL;
+			mdp_mregion->ion_handle = NULL;
+			goto mdp_mmap_fail;
+		}
+
+		mdp_buf.inst = inst->mdp_inst;
+		mdp_buf.cookie = enc_mregion;
+		mdp_buf.kvaddr = (u32) mdp_mregion->kvaddr;
+		mdp_buf.paddr = (u32) mdp_mregion->paddr;
+
+		WFD_MSG_DBG("NOTE: mdp paddr = [%p->%p], kvaddr = %p\n",
+				mdp_mregion->paddr, (void *)
+				((int)mdp_mregion->paddr + mdp_mregion->size),
+				mdp_mregion->kvaddr);
+
+		rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl,
+				MDP_Q_BUFFER, (void *)&mdp_buf);
+		if (rc) {
+			WFD_MSG_ERR("Unable to queue the"
+					" buffer to mdp\n");
+			goto mdp_q_fail;
+		} else {
+			wfd_stats_update(&inst->stats,
+					WFD_STAT_EVENT_MDP_QUEUE);
+		}
+
+		INIT_LIST_HEAD(&mpair->list);
+		mpair->enc = enc_mregion;
+		mpair->mdp = mdp_mregion;
+		list_add_tail(&mpair->list, &inst->input_mem_list);
+
+	}
+
+	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
+			ALLOC_RECON_BUFFERS, NULL);
+	if (rc) {
+		WFD_MSG_ERR("Failed to allocate recon buffers\n");
+		goto recon_alloc_fail;
+	}
+	return rc;
+
+	/*
+	 * Clean up only the buffer that we failed in setting up.
+	 * Caller will clean up the rest by calling free_input_buffers()
+	 */
+mdp_q_fail:
+	memset(&mmap_context, 0, sizeof(mmap_context));
+	mmap_context.mregion = mdp_mregion;
+	mmap_context.ion_client = wfd_dev->ion_client;
+	mmap_context.cookie = inst->mdp_inst;
+	v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl,
+			MDP_MUNMAP, (void *)&mmap_context);
+mdp_mmap_fail:
+	v4l2_subdev_call(&wfd_dev->enc_sdev,
+			core, ioctl, FREE_INPUT_BUFFER,
+			(void *)enc_mregion);
+set_input_fail:
+	memset(&mmap_context, 0, sizeof(mmap_context));
+	mmap_context.ion_client = wfd_dev->ion_client;
+	mmap_context.mregion = enc_mregion;
+	v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
+			ENC_MUNMAP, &mmap_context);
+alloc_fail:
+	kfree(mpair);
+	kfree(enc_mregion);
+	kfree(mdp_mregion);
+recon_alloc_fail:
+	return rc;
+}
+void wfd_free_input_buffers(struct wfd_device *wfd_dev,
+			struct wfd_inst *inst)
+{
+	struct list_head *ptr, *next;
+	struct mem_region_pair *mpair;
+	unsigned long flags;
+	int rc = 0;
+	spin_lock_irqsave(&inst->inst_lock, flags);
+	if (!inst->input_bufs_allocated) {
+		spin_unlock_irqrestore(&inst->inst_lock, flags);
+		return;
+	}
+	inst->input_bufs_allocated = false;
+	spin_unlock_irqrestore(&inst->inst_lock, flags);
+	if (!list_empty(&inst->input_mem_list)) {
+		list_for_each_safe(ptr, next,
+				&inst->input_mem_list) {
+			mpair = list_entry(ptr, struct mem_region_pair,
+						list);
+
+			rc = v4l2_subdev_call(&wfd_dev->enc_sdev,
+					core, ioctl, FREE_INPUT_BUFFER,
+					(void *)mpair->enc);
+
+			if (rc)
+				WFD_MSG_ERR("Failed to free buffers "
+						"from encoder\n");
+
+			if (mpair->mdp->paddr) {
+				struct mem_region_map temp = {0};
+
+				temp.ion_client = wfd_dev->ion_client;
+				temp.mregion = mpair->mdp;
+				temp.cookie = inst->mdp_inst;
+
+				v4l2_subdev_call(&wfd_dev->mdp_sdev, core,
+						ioctl, MDP_MUNMAP,
+						(void *)&temp);
+			}
+
+			if (mpair->enc->paddr) {
+				struct mem_region_map temp = {0};
+				temp.ion_client = wfd_dev->ion_client;
+				temp.mregion = mpair->enc;
+				v4l2_subdev_call(&wfd_dev->enc_sdev,
+					core, ioctl, ENC_MUNMAP, &temp);
+			}
+
+			wfd_free_ion_buffer(wfd_dev->ion_client, mpair->enc);
+			list_del(&mpair->list);
+			kfree(mpair->enc);
+			kfree(mpair->mdp);
+			kfree(mpair);
+		}
+	}
+	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
+			FREE_RECON_BUFFERS, NULL);
+	if (rc)
+		WFD_MSG_ERR("Failed to free recon buffers\n");
+}
+
+struct mem_info *wfd_get_mem_info(struct wfd_inst *inst,
+			unsigned long userptr)
+{
+	struct mem_info_entry *temp;
+	struct mem_info *ret = NULL;
+	unsigned long flags;
+	spin_lock_irqsave(&inst->inst_lock, flags);
+	if (!list_empty(&inst->minfo_list)) {
+		list_for_each_entry(temp, &inst->minfo_list, list) {
+			if (temp && temp->userptr == userptr) {
+				ret = &temp->minfo;
+				break;
+			}
+		}
+	}
+	spin_unlock_irqrestore(&inst->inst_lock, flags);
+	return ret;
+}
+void wfd_put_mem_info(struct wfd_inst *inst,
+			struct mem_info *minfo)
+{
+	struct list_head *ptr, *next;
+	struct mem_info_entry *temp;
+	unsigned long flags;
+	spin_lock_irqsave(&inst->inst_lock, flags);
+	if (!list_empty(&inst->minfo_list)) {
+		list_for_each_safe(ptr, next,
+				&inst->minfo_list) {
+			temp = list_entry(ptr, struct mem_info_entry,
+						list);
+			if (temp && (&temp->minfo == minfo)) {
+				list_del(&temp->list);
+				kfree(temp);
+			}
+		}
+	}
+	spin_unlock_irqrestore(&inst->inst_lock, flags);
+}
+static void wfd_unregister_out_buf(struct wfd_inst *inst,
+		struct mem_info *minfo)
+{
+	if (!minfo || !inst) {
+		WFD_MSG_ERR("Invalid arguments\n");
+		return;
+	}
+	wfd_put_mem_info(inst, minfo);
+}
+int wfd_vidbuf_buf_init(struct vb2_buffer *vb)
+{
+	int rc = 0;
+	struct vb2_queue *q = vb->vb2_queue;
+	struct file *priv_data = (struct file *)(q->drv_priv);
+	struct wfd_inst *inst = (struct wfd_inst *)priv_data->private_data;
+	struct wfd_device *wfd_dev =
+		(struct wfd_device *)video_drvdata(priv_data);
+	struct mem_info *minfo = vb2_plane_cookie(vb, 0);
+	struct mem_region mregion;
+	mregion.fd = minfo->fd;
+	mregion.offset = minfo->offset;
+	mregion.cookie = (u32)vb;
+	/*TODO: should be fixed in kernel 3.2*/
+	mregion.size =  inst->out_buf_size;
+
+	if (inst && !inst->vid_bufq.streaming) {
+		rc = wfd_allocate_input_buffers(wfd_dev, inst);
+		if (rc) {
+			WFD_MSG_ERR("Failed to allocate input buffers\n");
+			goto free_input_bufs;
+		}
+		rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
+				SET_OUTPUT_BUFFER, (void *)&mregion);
+		if (rc) {
+			WFD_MSG_ERR("Failed to set output buffer\n");
+			goto free_input_bufs;
+		}
+	}
+	return rc;
+free_input_bufs:
+	wfd_free_input_buffers(wfd_dev, inst);
+	return rc;
+}
+
+int wfd_vidbuf_buf_prepare(struct vb2_buffer *vb)
+{
+	return 0;
+}
+
+int wfd_vidbuf_buf_finish(struct vb2_buffer *vb)
+{
+	return 0;
+}
+
+void wfd_vidbuf_buf_cleanup(struct vb2_buffer *vb)
+{
+	int rc = 0;
+	struct vb2_queue *q = vb->vb2_queue;
+	struct file *priv_data = (struct file *)(q->drv_priv);
+	struct wfd_device *wfd_dev =
+		(struct wfd_device *)video_drvdata(priv_data);
+	struct wfd_inst *inst = (struct wfd_inst *)priv_data->private_data;
+	struct mem_info *minfo = vb2_plane_cookie(vb, 0);
+	struct mem_region mregion;
+
+	if (minfo == NULL) {
+		WFD_MSG_DBG("not freeing buffers since allocation failed");
+		return;
+	}
+
+	mregion.fd = minfo->fd;
+	mregion.offset = minfo->offset;
+	mregion.cookie = (u32)vb;
+	mregion.size =  inst->out_buf_size;
+
+	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
+			FREE_OUTPUT_BUFFER, (void *)&mregion);
+	if (rc)
+		WFD_MSG_ERR("Failed to free output buffer\n");
+	wfd_unregister_out_buf(inst, minfo);
+}
+
+static int mdp_output_thread(void *data)
+{
+	int rc = 0, no_sig_wait = 0;
+	struct file *filp = (struct file *)data;
+	struct wfd_inst *inst = filp->private_data;
+	struct wfd_device *wfd_dev =
+		(struct wfd_device *)video_drvdata(filp);
+	struct mdp_buf_info obuf_mdp = {inst->mdp_inst, 0, 0, 0};
+	struct mem_region *mregion;
+	struct vsg_buf_info ibuf_vsg;
+	while (!kthread_should_stop()) {
+		if (rc) {
+			WFD_MSG_DBG("%s() error in output thread\n", __func__);
+			if (!no_sig_wait) {
+				wait_for_completion(&inst->stop_mdp_thread);
+				no_sig_wait = 1;
+			}
+			continue;
+		}
+		WFD_MSG_DBG("waiting for mdp output\n");
+		rc = v4l2_subdev_call(&wfd_dev->mdp_sdev,
+			core, ioctl, MDP_DQ_BUFFER, (void *)&obuf_mdp);
+
+		if (rc) {
+			if (rc != -ENOBUFS)
+				WFD_MSG_ERR("MDP reported err %d\n", rc);
+
+			WFD_MSG_ERR("Streamoff called\n");
+			continue;
+		} else {
+			wfd_stats_update(&inst->stats,
+				WFD_STAT_EVENT_MDP_DEQUEUE);
+		}
+
+		mregion = obuf_mdp.cookie;
+		if (!mregion) {
+			WFD_MSG_ERR("mdp cookie is null\n");
+			rc = -EINVAL;
+			continue;
+		}
+
+		ibuf_vsg.mdp_buf_info = obuf_mdp;
+		ibuf_vsg.mdp_buf_info.inst = inst->mdp_inst;
+		ibuf_vsg.mdp_buf_info.cookie = mregion;
+		ibuf_vsg.mdp_buf_info.kvaddr = (u32) mregion->kvaddr;
+		ibuf_vsg.mdp_buf_info.paddr =
+			(u32)wfd_enc_addr_to_mdp_addr(inst,
+					(unsigned long)mregion->paddr);
+		rc = v4l2_subdev_call(&wfd_dev->vsg_sdev,
+			core, ioctl, VSG_Q_BUFFER, (void *)&ibuf_vsg);
+
+		if (rc) {
+			WFD_MSG_ERR("Failed to queue frame to vsg\n");
+			continue;
+		} else {
+			wfd_stats_update(&inst->stats,
+				WFD_STAT_EVENT_VSG_QUEUE);
+		}
+	}
+	WFD_MSG_DBG("Exiting the thread\n");
+	return rc;
+}
+
+int wfd_vidbuf_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+	struct file *priv_data = (struct file *)(q->drv_priv);
+	struct wfd_device *wfd_dev =
+		(struct wfd_device *)video_drvdata(priv_data);
+	struct wfd_inst *inst = (struct wfd_inst *)priv_data->private_data;
+	int rc = 0;
+
+	WFD_MSG_ERR("Stream on called\n");
+	WFD_MSG_DBG("enc start\n");
+	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
+			ENCODE_START, (void *)inst->venc_inst);
+	if (rc) {
+		WFD_MSG_ERR("Failed to start encoder\n");
+		goto subdev_start_fail;
+	}
+
+	WFD_MSG_DBG("vsg start\n");
+	rc = v4l2_subdev_call(&wfd_dev->vsg_sdev, core, ioctl,
+			VSG_START, NULL);
+	if (rc) {
+		WFD_MSG_ERR("Failed to start vsg\n");
+		goto subdev_start_fail;
+	}
+	init_completion(&inst->stop_mdp_thread);
+	inst->mdp_task = kthread_run(mdp_output_thread, priv_data,
+				"mdp_output_thread");
+	if (IS_ERR(inst->mdp_task)) {
+		rc = PTR_ERR(inst->mdp_task);
+		goto subdev_start_fail;
+	}
+	WFD_MSG_DBG("mdp start\n");
+	rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl,
+			 MDP_START, (void *)inst->mdp_inst);
+	if (rc)
+		WFD_MSG_ERR("Failed to start MDP\n");
+subdev_start_fail:
+	return rc;
+}
+
+int wfd_vidbuf_stop_streaming(struct vb2_queue *q)
+{
+	struct file *priv_data = (struct file *)(q->drv_priv);
+	struct wfd_device *wfd_dev =
+		(struct wfd_device *)video_drvdata(priv_data);
+	struct wfd_inst *inst = (struct wfd_inst *)priv_data->private_data;
+	int rc = 0;
+	WFD_MSG_DBG("mdp stop\n");
+	rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl,
+			 MDP_STOP, (void *)inst->mdp_inst);
+	if (rc)
+		WFD_MSG_ERR("Failed to stop MDP\n");
+
+	WFD_MSG_DBG("vsg stop\n");
+	rc = v4l2_subdev_call(&wfd_dev->vsg_sdev, core, ioctl,
+			 VSG_STOP, NULL);
+	if (rc)
+		WFD_MSG_ERR("Failed to stop VSG\n");
+
+	complete(&inst->stop_mdp_thread);
+	kthread_stop(inst->mdp_task);
+	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
+			ENCODE_FLUSH, (void *)inst->venc_inst);
+	if (rc)
+		WFD_MSG_ERR("Failed to flush encoder\n");
+	WFD_MSG_DBG("enc stop\n");
+	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
+			ENCODE_STOP, (void *)inst->venc_inst);
+	if (rc)
+		WFD_MSG_ERR("Failed to stop encoder\n");
+
+	return rc;
+}
+
+void wfd_vidbuf_buf_queue(struct vb2_buffer *vb)
+{
+	int rc = 0;
+	struct vb2_queue *q = vb->vb2_queue;
+	struct file *priv_data = (struct file *)(q->drv_priv);
+	struct wfd_device *wfd_dev =
+		(struct wfd_device *)video_drvdata(priv_data);
+	struct wfd_inst *inst = (struct wfd_inst *)priv_data->private_data;
+	struct mem_region mregion;
+	struct mem_info *minfo = vb2_plane_cookie(vb, 0);
+	mregion.fd = minfo->fd;
+	mregion.offset = minfo->offset;
+	mregion.cookie = (u32)vb;
+	mregion.size =  inst->out_buf_size;
+	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
+			FILL_OUTPUT_BUFFER, (void *)&mregion);
+	if (rc) {
+		WFD_MSG_ERR("Failed to fill output buffer\n");
+	}
+}
+
+static struct vb2_ops wfd_vidbuf_ops = {
+	.queue_setup = wfd_vidbuf_queue_setup,
+
+	.wait_prepare = wfd_vidbuf_wait_prepare,
+	.wait_finish = wfd_vidbuf_wait_finish,
+
+	.buf_init = wfd_vidbuf_buf_init,
+	.buf_prepare = wfd_vidbuf_buf_prepare,
+	.buf_finish = wfd_vidbuf_buf_finish,
+	.buf_cleanup = wfd_vidbuf_buf_cleanup,
+
+	.start_streaming = wfd_vidbuf_start_streaming,
+	.stop_streaming = wfd_vidbuf_stop_streaming,
+
+	.buf_queue = wfd_vidbuf_buf_queue,
+};
+
+static const struct v4l2_subdev_core_ops mdp_subdev_core_ops = {
+	.init = mdp_init,
+	.ioctl = mdp_ioctl,
+};
+
+static const struct v4l2_subdev_ops mdp_subdev_ops = {
+	.core = &mdp_subdev_core_ops,
+};
+
+static const struct v4l2_subdev_core_ops enc_subdev_core_ops = {
+	.init = venc_init,
+	.load_fw = venc_load_fw,
+	.ioctl = venc_ioctl,
+};
+
+static const struct v4l2_subdev_ops enc_subdev_ops = {
+	.core = &enc_subdev_core_ops,
+};
+
+static const struct v4l2_subdev_core_ops vsg_subdev_core_ops = {
+	.init = vsg_init,
+	.ioctl = vsg_ioctl,
+};
+
+static const struct v4l2_subdev_ops vsg_subdev_ops = {
+	.core = &vsg_subdev_core_ops,
+};
+
+static int wfdioc_querycap(struct file *filp, void *fh,
+		struct v4l2_capability *cap) {
+	WFD_MSG_DBG("wfdioc_querycap: E\n");
+	memset(cap, 0, sizeof(struct v4l2_capability));
+	strlcpy(cap->driver, "wifi-display", sizeof(cap->driver));
+	strlcpy(cap->card, "msm", sizeof(cap->card));
+	cap->version = WFD_VERSION;
+	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+	WFD_MSG_DBG("wfdioc_querycap: X\n");
+	return 0;
+}
+static int wfdioc_g_fmt(struct file *filp, void *fh,
+			struct v4l2_format *fmt)
+{
+	struct wfd_inst *inst = filp->private_data;
+	unsigned long flags;
+	if (!fmt) {
+		WFD_MSG_ERR("Invalid argument\n");
+		return -EINVAL;
+	}
+	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		WFD_MSG_ERR("Only V4L2_BUF_TYPE_VIDEO_CAPTURE is supported\n");
+		return -EINVAL;
+	}
+	spin_lock_irqsave(&inst->inst_lock, flags);
+	fmt->fmt.pix.width = inst->width;
+	fmt->fmt.pix.height = inst->height;
+	fmt->fmt.pix.pixelformat = inst->pixelformat;
+	fmt->fmt.pix.sizeimage = inst->out_buf_size;
+	fmt->fmt.pix.priv = 0;
+	spin_unlock_irqrestore(&inst->inst_lock, flags);
+	return 0;
+}
+
+static int wfdioc_s_fmt(struct file *filp, void *fh,
+			struct v4l2_format *fmt)
+{
+	int rc = 0;
+	struct wfd_inst *inst = filp->private_data;
+	struct wfd_device *wfd_dev = video_drvdata(filp);
+	struct mdp_prop prop;
+	unsigned long flags;
+	struct bufreq breq;
+	if (!fmt) {
+		WFD_MSG_ERR("Invalid argument\n");
+		return -EINVAL;
+	}
+	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+		fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_H264) {
+		WFD_MSG_ERR("Only V4L2_BUF_TYPE_VIDEO_CAPTURE and "
+				"V4L2_PIX_FMT_H264 are supported\n");
+		return -EINVAL;
+	}
+
+	if (fmt->fmt.pix.width % 16) {
+		WFD_MSG_ERR("Only 16 byte aligned widths are supported\n");
+		return -ENOTSUPP;
+	}
+	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl, SET_FORMAT,
+				(void *)fmt);
+	if (rc) {
+		WFD_MSG_ERR("Failed to set format on encoder, rc = %d\n", rc);
+		return rc;
+	}
+	breq.count = VENC_INPUT_BUFFERS;
+	breq.height = fmt->fmt.pix.height;
+	breq.width = fmt->fmt.pix.width;
+	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
+			SET_BUFFER_REQ, (void *)&breq);
+	if (rc) {
+		WFD_MSG_ERR("Failed to set buffer reqs on encoder\n");
+		return rc;
+	}
+	spin_lock_irqsave(&inst->inst_lock, flags);
+	inst->input_buf_size = breq.size;
+	inst->out_buf_size = fmt->fmt.pix.sizeimage;
+	prop.height = inst->height = fmt->fmt.pix.height;
+	prop.width = inst->width = fmt->fmt.pix.width;
+	prop.inst = inst->mdp_inst;
+	spin_unlock_irqrestore(&inst->inst_lock, flags);
+	rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl, MDP_SET_PROP,
+				(void *)&prop);
+	if (rc)
+		WFD_MSG_ERR("Failed to set height/width property on mdp\n");
+	return rc;
+}
+static int wfdioc_reqbufs(struct file *filp, void *fh,
+		struct v4l2_requestbuffers *b)
+{
+	struct wfd_inst *inst = filp->private_data;
+	struct wfd_device *wfd_dev = video_drvdata(filp);
+	unsigned long flags;
+	int rc = 0;
+
+	if (b->type != V4L2_CAP_VIDEO_CAPTURE ||
+		b->memory != V4L2_MEMORY_USERPTR) {
+		WFD_MSG_ERR("Only V4L2_CAP_VIDEO_CAPTURE and "
+		"V4L2_MEMORY_USERPTR are supported\n");
+		return -EINVAL;
+	}
+	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
+			GET_BUFFER_REQ, (void *)b);
+	if (rc) {
+		WFD_MSG_ERR("Failed to get buf reqs from encoder\n");
+		return rc;
+	}
+	spin_lock_irqsave(&inst->inst_lock, flags);
+	inst->buf_count = b->count;
+	spin_unlock_irqrestore(&inst->inst_lock, flags);
+	rc = vb2_reqbufs(&inst->vid_bufq, b);
+	return rc;
+}
+static int wfd_register_out_buf(struct wfd_inst *inst,
+		struct v4l2_buffer *b)
+{
+	struct mem_info_entry *minfo_entry;
+	struct mem_info *minfo;
+	unsigned long flags;
+	if (!b || !inst || !b->reserved) {
+		WFD_MSG_ERR("Invalid arguments\n");
+		return -EINVAL;
+	}
+	minfo = wfd_get_mem_info(inst, b->m.userptr);
+	if (!minfo) {
+		minfo_entry = kzalloc(sizeof(struct mem_info_entry),
+				GFP_KERNEL);
+		if (copy_from_user(&minfo_entry->minfo, (void *)b->reserved,
+					sizeof(struct mem_info))) {
+			WFD_MSG_ERR(" copy_from_user failed. Populate"
+					" v4l2_buffer->reserved with meminfo\n");
+			return -EINVAL;
+		}
+		minfo_entry->userptr = b->m.userptr;
+		spin_lock_irqsave(&inst->inst_lock, flags);
+		list_add_tail(&minfo_entry->list, &inst->minfo_list);
+		spin_unlock_irqrestore(&inst->inst_lock, flags);
+	} else
+		WFD_MSG_DBG("Buffer already registered\n");
+
+	return 0;
+}
+static int wfdioc_qbuf(struct file *filp, void *fh,
+		struct v4l2_buffer *b)
+{
+	int rc = 0;
+	struct wfd_inst *inst = filp->private_data;
+	if (!inst || !b ||
+			(b->index < 0 || b->index >= inst->buf_count)) {
+		WFD_MSG_ERR("Invalid input parameters to QBUF IOCTL\n");
+		return -EINVAL;
+	}
+	rc = wfd_register_out_buf(inst, b);
+	if (rc) {
+		WFD_MSG_ERR("Failed to register buffer\n");
+		return rc;
+	}
+
+	rc = vb2_qbuf(&inst->vid_bufq, b);
+	if (rc)
+		WFD_MSG_ERR("Failed to queue buffer\n");
+	else
+		wfd_stats_update(&inst->stats, WFD_STAT_EVENT_CLIENT_QUEUE);
+
+	return rc;
+}
+
+static int wfdioc_streamon(struct file *filp, void *fh,
+		enum v4l2_buf_type i)
+{
+	int rc = 0;
+	struct wfd_inst *inst = filp->private_data;
+	unsigned long flags;
+	if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		WFD_MSG_ERR("stream on for buffer type = %d is not "
+			"supported.\n", i);
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&inst->inst_lock, flags);
+	inst->streamoff = false;
+	spin_unlock_irqrestore(&inst->inst_lock, flags);
+
+	rc = vb2_streamon(&inst->vid_bufq, i);
+	if (rc) {
+		WFD_MSG_ERR("videobuf_streamon failed with err = %d\n", rc);
+		goto vidbuf_streamon_failed;
+	}
+	return rc;
+
+vidbuf_streamon_failed:
+	vb2_streamoff(&inst->vid_bufq, i);
+	return rc;
+}
+static int wfdioc_streamoff(struct file *filp, void *fh,
+		enum v4l2_buf_type i)
+{
+	struct wfd_inst *inst = filp->private_data;
+	unsigned long flags;
+
+	if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		WFD_MSG_ERR("stream off for buffer type = %d is not "
+			"supported.\n", i);
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&inst->inst_lock, flags);
+	if (inst->streamoff) {
+		WFD_MSG_ERR("Module is already in streamoff state\n");
+		spin_unlock_irqrestore(&inst->inst_lock, flags);
+		return -EINVAL;
+	}
+	inst->streamoff = true;
+	spin_unlock_irqrestore(&inst->inst_lock, flags);
+	WFD_MSG_DBG("Calling videobuf_streamoff\n");
+	vb2_streamoff(&inst->vid_bufq, i);
+	return 0;
+}
+static int wfdioc_dqbuf(struct file *filp, void *fh,
+		struct v4l2_buffer *b)
+{
+	struct wfd_inst *inst = filp->private_data;
+	int rc;
+
+	WFD_MSG_DBG("Waiting to dequeue buffer\n");
+	rc = vb2_dqbuf(&inst->vid_bufq, b, 0);
+
+	if (rc)
+		WFD_MSG_ERR("Failed to dequeue buffer\n");
+	else
+		wfd_stats_update(&inst->stats, WFD_STAT_EVENT_CLIENT_DEQUEUE);
+
+	return rc;
+}
+static int wfdioc_g_ctrl(struct file *filp, void *fh,
+					struct v4l2_control *a)
+{
+	int rc = 0;
+	struct wfd_device *wfd_dev = video_drvdata(filp);
+	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core,
+			ioctl, GET_PROP, a);
+	if (rc)
+		WFD_MSG_ERR("Failed to get encoder property\n");
+	return rc;
+}
+static int wfdioc_s_ctrl(struct file *filp, void *fh,
+					struct v4l2_control *a)
+{
+	int rc = 0;
+	struct wfd_device *wfd_dev = video_drvdata(filp);
+	struct wfd_inst *inst = filp->private_data;
+
+	switch (a->id) {
+	case V4L2_CID_MPEG_VIDC_VIDEO_SECURE:
+		rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core,
+				ioctl, ENC_SECURE, NULL);
+		if (rc) {
+			WFD_MSG_ERR("Couldn't secure encoder");
+			break;
+		}
+
+		rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core,
+				ioctl, MDP_SECURE, (void *)inst->mdp_inst);
+		if (rc) {
+			WFD_MSG_ERR("Couldn't secure MDP");
+			break;
+		}
+
+		wfd_dev->secure = true;
+		break;
+	default:
+		rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core,
+				ioctl, SET_PROP, a);
+	}
+
+	if (rc)
+		WFD_MSG_ERR("Failed to set encoder property\n");
+	return rc;
+}
+
+static int wfdioc_g_parm(struct file *filp, void *fh,
+		struct v4l2_streamparm *a)
+{
+	int rc = 0;
+	struct wfd_device *wfd_dev = video_drvdata(filp);
+	struct wfd_inst *inst = filp->private_data;
+	int64_t frame_interval = 0,
+		max_frame_interval = 0; /* both in nsecs*/
+	struct v4l2_qcom_frameskip frameskip, *usr_frameskip;
+
+	usr_frameskip = (struct v4l2_qcom_frameskip *)
+			a->parm.capture.extendedmode;
+
+	if (!usr_frameskip) {
+		rc = -EINVAL;
+		goto get_parm_fail;
+	}
+	rc = v4l2_subdev_call(&wfd_dev->vsg_sdev, core,
+			ioctl, VSG_GET_FRAME_INTERVAL, &frame_interval);
+
+	if (rc < 0)
+		goto get_parm_fail;
+
+	rc = v4l2_subdev_call(&wfd_dev->vsg_sdev, core,
+			ioctl, VSG_GET_MAX_FRAME_INTERVAL, &max_frame_interval);
+
+	if (rc < 0)
+		goto get_parm_fail;
+
+	frameskip = (struct v4l2_qcom_frameskip) {
+		.maxframeinterval = max_frame_interval,
+	};
+
+	a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	a->parm.capture = (struct v4l2_captureparm) {
+		.capability = V4L2_CAP_TIMEPERFRAME,
+		.capturemode = 0,
+		.timeperframe = (struct v4l2_fract) {
+			.numerator = frame_interval,
+			.denominator = NSEC_PER_SEC,
+		},
+		.readbuffers = inst->buf_count,
+		.extendedmode = (__u32)usr_frameskip,
+		.reserved = {0}
+	};
+
+	rc = copy_to_user((void *)a->parm.capture.extendedmode,
+			&frameskip, sizeof(frameskip));
+	if (rc < 0)
+		goto get_parm_fail;
+
+get_parm_fail:
+	return rc;
+}
+
+static int wfdioc_s_parm(struct file *filp, void *fh,
+		struct v4l2_streamparm *a)
+{
+	int rc = 0;
+	struct wfd_device *wfd_dev = video_drvdata(filp);
+	struct wfd_inst *inst = filp->private_data;
+	struct v4l2_qcom_frameskip frameskip;
+	int64_t frame_interval, max_frame_interval;
+	void *extendedmode = NULL;
+	enum vsg_modes vsg_mode = VSG_MODE_VFR;
+	enum venc_framerate_modes venc_mode = VENC_MODE_VFR;
+
+
+	if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		rc = -ENOTSUPP;
+		goto set_parm_fail;
+	}
+
+	if (a->parm.capture.readbuffers == 0 ||
+		a->parm.capture.readbuffers == inst->buf_count) {
+		a->parm.capture.readbuffers = inst->buf_count;
+	} else {
+		rc = -EINVAL;
+		goto set_parm_fail;
+	}
+
+	extendedmode = (void *)a->parm.capture.extendedmode;
+	if (a->parm.capture.capability & V4L2_CAP_TIMEPERFRAME) {
+		if (a->parm.capture.timeperframe.denominator == 0) {
+			rc = -EINVAL;
+			goto set_parm_fail;
+		}
+		frame_interval =
+			a->parm.capture.timeperframe.numerator * NSEC_PER_SEC /
+			a->parm.capture.timeperframe.denominator;
+
+		rc = v4l2_subdev_call(&wfd_dev->vsg_sdev, core,
+				ioctl, VSG_SET_FRAME_INTERVAL,
+				&frame_interval);
+
+		if (rc)
+			goto set_parm_fail;
+
+		rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core,
+				ioctl, SET_FRAMERATE,
+				&a->parm.capture.timeperframe);
+
+		if (rc)
+			goto set_parm_fail;
+	}
+
+	if (a->parm.capture.capability & V4L2_CAP_QCOM_FRAMESKIP &&
+		extendedmode) {
+		rc = copy_from_user(&frameskip,
+				extendedmode, sizeof(frameskip));
+
+		if (rc)
+			goto set_parm_fail;
+
+		max_frame_interval = (int64_t)frameskip.maxframeinterval;
+		vsg_mode = VSG_MODE_VFR;
+		venc_mode = VENC_MODE_VFR;
+
+		rc = v4l2_subdev_call(&wfd_dev->vsg_sdev, core,
+				ioctl, VSG_SET_MAX_FRAME_INTERVAL,
+				&max_frame_interval);
+
+		if (rc)
+			goto set_parm_fail;
+	} else {
+		vsg_mode = VSG_MODE_CFR;
+		venc_mode = VENC_MODE_CFR;
+	}
+
+	rc = v4l2_subdev_call(&wfd_dev->vsg_sdev, core,
+			ioctl, VSG_SET_MODE, &vsg_mode);
+	if (rc) {
+		WFD_MSG_ERR("Setting FR mode for VSG failed\n");
+		goto set_parm_fail;
+	}
+
+	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core,
+			ioctl, SET_FRAMERATE_MODE,
+			&venc_mode);
+	if (rc) {
+		WFD_MSG_ERR("Setting FR mode for VENC failed\n");
+		goto set_parm_fail;
+	}
+
+set_parm_fail:
+	return rc;
+}
+
+static const struct v4l2_ioctl_ops g_wfd_ioctl_ops = {
+	.vidioc_querycap = wfdioc_querycap,
+	.vidioc_s_fmt_vid_cap = wfdioc_s_fmt,
+	.vidioc_g_fmt_vid_cap = wfdioc_g_fmt,
+	.vidioc_reqbufs = wfdioc_reqbufs,
+	.vidioc_qbuf = wfdioc_qbuf,
+	.vidioc_streamon = wfdioc_streamon,
+	.vidioc_streamoff = wfdioc_streamoff,
+	.vidioc_dqbuf = wfdioc_dqbuf,
+	.vidioc_g_ctrl = wfdioc_g_ctrl,
+	.vidioc_s_ctrl = wfdioc_s_ctrl,
+	.vidioc_g_parm = wfdioc_g_parm,
+	.vidioc_s_parm = wfdioc_s_parm,
+};
+static int wfd_set_default_properties(struct file *filp)
+{
+	unsigned long flags;
+	struct v4l2_format fmt;
+	struct v4l2_control ctrl;
+	struct wfd_inst *inst = filp->private_data;
+	if (!inst) {
+		WFD_MSG_ERR("Invalid argument\n");
+		return -EINVAL;
+	}
+	spin_lock_irqsave(&inst->inst_lock, flags);
+	fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	fmt.fmt.pix.height = inst->height = DEFAULT_WFD_HEIGHT;
+	fmt.fmt.pix.width = inst->width = DEFAULT_WFD_WIDTH;
+	fmt.fmt.pix.pixelformat = inst->pixelformat
+			= V4L2_PIX_FMT_H264;
+	spin_unlock_irqrestore(&inst->inst_lock, flags);
+	wfdioc_s_fmt(filp, filp->private_data, &fmt);
+
+	ctrl.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
+	ctrl.value = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME;
+	wfdioc_s_ctrl(filp, filp->private_data, &ctrl);
+	return 0;
+}
+static void venc_op_buffer_done(void *cookie, u32 status,
+			struct vb2_buffer *buf)
+{
+	WFD_MSG_DBG("yay!! got callback\n");
+	vb2_buffer_done(buf, VB2_BUF_STATE_DONE);
+}
+
+static void venc_ip_buffer_done(void *cookie, u32 status,
+			struct mem_region *mregion)
+{
+	struct file *filp = cookie;
+	struct wfd_inst *inst = filp->private_data;
+	struct vsg_buf_info buf;
+	struct mdp_buf_info mdp_buf = {0};
+	struct wfd_device *wfd_dev =
+		(struct wfd_device *)video_drvdata(filp);
+	int rc = 0;
+	WFD_MSG_DBG("yay!! got ip callback\n");
+	mdp_buf.inst = inst->mdp_inst;
+	mdp_buf.cookie = mregion;
+	mdp_buf.kvaddr = (u32) mregion->kvaddr;
+	mdp_buf.paddr =
+		(u32)wfd_enc_addr_to_mdp_addr(inst,
+			(unsigned long)mregion->paddr);
+	buf.mdp_buf_info = mdp_buf;
+
+	rc = v4l2_subdev_call(&wfd_dev->vsg_sdev, core,
+			ioctl, VSG_RETURN_IP_BUFFER, (void *)&buf);
+	if (rc)
+		WFD_MSG_ERR("Failed to return buffer to vsg\n");
+	else
+		wfd_stats_update(&inst->stats, WFD_STAT_EVENT_ENC_DEQUEUE);
+
+}
+
+static int vsg_release_input_frame(void *cookie, struct vsg_buf_info *buf)
+{
+	struct file *filp = cookie;
+	struct wfd_inst *inst = filp->private_data;
+	struct wfd_device *wfd_dev =
+		(struct wfd_device *)video_drvdata(filp);
+	int rc = 0;
+
+	rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core,
+			ioctl, MDP_Q_BUFFER, buf);
+	if (rc)
+		WFD_MSG_ERR("Failed to Q buffer to mdp\n");
+	else {
+		wfd_stats_update(&inst->stats, WFD_STAT_EVENT_MDP_QUEUE);
+		wfd_stats_update(&inst->stats, WFD_STAT_EVENT_VSG_DEQUEUE);
+	}
+
+	return rc;
+}
+
+static int vsg_encode_frame(void *cookie, struct vsg_buf_info *buf)
+{
+	struct file *filp = cookie;
+	struct wfd_inst *inst = filp->private_data;
+	struct wfd_device *wfd_dev =
+		(struct wfd_device *)video_drvdata(filp);
+	struct venc_buf_info venc_buf;
+	int rc = 0;
+
+	if (!buf)
+		return -EINVAL;
+
+	venc_buf = (struct venc_buf_info){
+		.timestamp = timespec_to_ns(&buf->time),
+		.mregion = buf->mdp_buf_info.cookie
+	};
+
+	wfd_flush_ion_buffer(wfd_dev->ion_client, venc_buf.mregion);
+
+	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
+			ENCODE_FRAME, &venc_buf);
+
+	if (rc)
+		WFD_MSG_ERR("Encode failed\n");
+	else
+		wfd_stats_update(&inst->stats, WFD_STAT_EVENT_ENC_QUEUE);
+
+	return rc;
+}
+
+void *wfd_vb2_mem_ops_get_userptr(void *alloc_ctx, unsigned long vaddr,
+					unsigned long size, int write)
+{
+	return wfd_get_mem_info(alloc_ctx, vaddr);
+}
+
+void wfd_vb2_mem_ops_put_userptr(void *buf_priv)
+{
+	/*TODO: Free the list*/
+}
+
+void *wfd_vb2_mem_ops_cookie(void *buf_priv)
+{
+	return buf_priv;
+}
+
+
+static struct vb2_mem_ops wfd_vb2_mem_ops = {
+	.get_userptr = wfd_vb2_mem_ops_get_userptr,
+	.put_userptr = wfd_vb2_mem_ops_put_userptr,
+	.cookie = wfd_vb2_mem_ops_cookie,
+};
+
+int wfd_initialize_vb2_queue(struct vb2_queue *q, void *priv)
+{
+	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	q->io_modes = VB2_USERPTR;
+	q->ops = &wfd_vidbuf_ops;
+	q->mem_ops = &wfd_vb2_mem_ops;
+	q->drv_priv = priv;
+	return vb2_queue_init(q);
+}
+
+static int wfd_open(struct file *filp)
+{
+	int rc = 0;
+	struct wfd_inst *inst = NULL;
+	struct wfd_device *wfd_dev = NULL;
+	struct venc_msg_ops enc_mops;
+	struct mdp_msg_ops mdp_mops;
+	struct vsg_msg_ops vsg_mops;
+
+	WFD_MSG_DBG("wfd_open: E\n");
+	wfd_dev = video_drvdata(filp);
+	if (!wfd_dev) {
+		rc = -EINVAL;
+		goto err_dev_busy;
+	}
+	mutex_lock(&wfd_dev->dev_lock);
+	if (wfd_dev->in_use) {
+		WFD_MSG_ERR("Device already in use.\n");
+		rc = -EBUSY;
+		mutex_unlock(&wfd_dev->dev_lock);
+		goto err_dev_busy;
+	}
+
+	wfd_dev->in_use = true;
+	mutex_unlock(&wfd_dev->dev_lock);
+
+	inst = kzalloc(sizeof(struct wfd_inst), GFP_KERNEL);
+	if (!inst) {
+		WFD_MSG_ERR("Could not allocate memory for "
+			"wfd instance\n");
+		rc = -ENOMEM;
+		goto err_mdp_open;
+	}
+	filp->private_data = inst;
+	spin_lock_init(&inst->inst_lock);
+	INIT_LIST_HEAD(&inst->input_mem_list);
+	INIT_LIST_HEAD(&inst->minfo_list);
+
+	wfd_stats_init(&inst->stats, MINOR(filp->f_dentry->d_inode->i_rdev));
+
+	mdp_mops.secure = wfd_dev->secure;
+	mdp_mops.iommu_split_domain = wfd_dev->mdp_iommu_split_domain;
+	rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl, MDP_OPEN,
+				(void *)&mdp_mops);
+	if (rc) {
+		WFD_MSG_ERR("Failed to open mdp subdevice: %d\n", rc);
+		goto err_mdp_open;
+	}
+	inst->mdp_inst = mdp_mops.cookie;
+
+	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, load_fw);
+	if (rc) {
+		WFD_MSG_ERR("Failed to load video encoder firmware: %d\n", rc);
+		goto err_venc;
+	}
+	enc_mops.op_buffer_done = venc_op_buffer_done;
+	enc_mops.ip_buffer_done = venc_ip_buffer_done;
+	enc_mops.cbdata = filp;
+	enc_mops.secure = wfd_dev->secure;
+	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl, OPEN,
+				(void *)&enc_mops);
+	if (rc || !enc_mops.cookie) {
+		WFD_MSG_ERR("Failed to open encoder subdevice: %d\n", rc);
+		goto err_venc;
+	}
+	inst->venc_inst = enc_mops.cookie;
+
+	vsg_mops.encode_frame = vsg_encode_frame;
+	vsg_mops.release_input_frame = vsg_release_input_frame;
+	vsg_mops.cbdata = filp;
+	rc = v4l2_subdev_call(&wfd_dev->vsg_sdev, core, ioctl, VSG_OPEN,
+				&vsg_mops);
+	if (rc) {
+		WFD_MSG_ERR("Failed to open vsg subdevice: %d\n", rc);
+		goto err_vsg_open;
+	}
+
+	wfd_initialize_vb2_queue(&inst->vid_bufq, filp);
+	wfd_set_default_properties(filp);
+	WFD_MSG_DBG("wfd_open: X\n");
+	return rc;
+
+err_vsg_open:
+	v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl, CLOSE, NULL);
+err_venc:
+	v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl,
+				MDP_CLOSE, (void *)inst->mdp_inst);
+err_mdp_open:
+	mutex_lock(&wfd_dev->dev_lock);
+	wfd_dev->in_use = false;
+	mutex_unlock(&wfd_dev->dev_lock);
+	kfree(inst);
+err_dev_busy:
+	return rc;
+}
+
+static int wfd_close(struct file *filp)
+{
+	struct wfd_inst *inst;
+	struct wfd_device *wfd_dev;
+	int rc = 0;
+	wfd_dev = video_drvdata(filp);
+	WFD_MSG_DBG("wfd_close: E\n");
+	inst = filp->private_data;
+	if (inst) {
+		wfdioc_streamoff(filp, NULL, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+		vb2_queue_release(&inst->vid_bufq);
+		wfd_free_input_buffers(wfd_dev, inst);
+
+		rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl,
+				MDP_CLOSE, (void *)inst->mdp_inst);
+		if (rc)
+			WFD_MSG_ERR("Failed to CLOSE mdp subdevice: %d\n", rc);
+
+		rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
+				CLOSE, (void *)inst->venc_inst);
+		if (rc)
+			WFD_MSG_ERR("Failed to CLOSE enc subdev: %d\n", rc);
+
+		rc = v4l2_subdev_call(&wfd_dev->vsg_sdev, core, ioctl,
+				VSG_CLOSE, NULL);
+		if (rc)
+			WFD_MSG_ERR("Failed to CLOSE vsg subdev: %d\n", rc);
+
+		wfd_stats_deinit(&inst->stats);
+		kfree(inst);
+	}
+
+	mutex_lock(&wfd_dev->dev_lock);
+	wfd_dev->in_use = false;
+	mutex_unlock(&wfd_dev->dev_lock);
+
+	WFD_MSG_DBG("wfd_close: X\n");
+	return 0;
+}
+static const struct v4l2_file_operations g_wfd_fops = {
+	.owner = THIS_MODULE,
+	.open = wfd_open,
+	.release = wfd_close,
+	.ioctl = video_ioctl2
+};
+void release_video_device(struct video_device *pvdev)
+{
+
+}
+
+static int wfd_dev_setup(struct wfd_device *wfd_dev, int dev_num,
+		struct platform_device *pdev)
+{
+	int rc = 0;
+	rc = v4l2_device_register(&pdev->dev, &wfd_dev->v4l2_dev);
+	if (rc) {
+		WFD_MSG_ERR("Failed to register the video device\n");
+		goto err_v4l2_registration;
+	}
+	wfd_dev->pvdev = video_device_alloc();
+	if (!wfd_dev->pvdev) {
+		WFD_MSG_ERR("Failed to allocate video device\n");
+		goto err_video_device_alloc;
+	}
+
+	wfd_dev->pvdev->release = release_video_device;
+	wfd_dev->pvdev->fops = &g_wfd_fops;
+	wfd_dev->pvdev->ioctl_ops = &g_wfd_ioctl_ops;
+
+	rc = video_register_device(wfd_dev->pvdev, VFL_TYPE_GRABBER,
+			dev_num);
+	if (rc) {
+		WFD_MSG_ERR("Failed to register the device\n");
+		goto err_video_register_device;
+	}
+	video_set_drvdata(wfd_dev->pvdev, wfd_dev);
+
+	v4l2_subdev_init(&wfd_dev->mdp_sdev, &mdp_subdev_ops);
+	strncpy(wfd_dev->mdp_sdev.name, "wfd-mdp", V4L2_SUBDEV_NAME_SIZE);
+	rc = v4l2_device_register_subdev(&wfd_dev->v4l2_dev,
+			&wfd_dev->mdp_sdev);
+	if (rc) {
+		WFD_MSG_ERR("Failed to register mdp subdevice: %d\n", rc);
+		goto err_mdp_register_subdev;
+	}
+
+	v4l2_subdev_init(&wfd_dev->enc_sdev, &enc_subdev_ops);
+	strncpy(wfd_dev->enc_sdev.name, "wfd-venc", V4L2_SUBDEV_NAME_SIZE);
+	rc = v4l2_device_register_subdev(&wfd_dev->v4l2_dev,
+			&wfd_dev->enc_sdev);
+	if (rc) {
+		WFD_MSG_ERR("Failed to register encoder subdevice: %d\n", rc);
+		goto err_venc_register_subdev;
+	}
+	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, init, 0);
+	if (rc) {
+		WFD_MSG_ERR("Failed to initiate encoder device %d\n", rc);
+		goto err_venc_init;
+	}
+
+	v4l2_subdev_init(&wfd_dev->vsg_sdev, &vsg_subdev_ops);
+	strncpy(wfd_dev->vsg_sdev.name, "wfd-vsg", V4L2_SUBDEV_NAME_SIZE);
+	rc = v4l2_device_register_subdev(&wfd_dev->v4l2_dev,
+			&wfd_dev->vsg_sdev);
+	if (rc) {
+		WFD_MSG_ERR("Failed to register vsg subdevice: %d\n", rc);
+		goto err_venc_init;
+	}
+
+	WFD_MSG_DBG("__wfd_probe: X\n");
+	return rc;
+
+err_venc_init:
+	v4l2_device_unregister_subdev(&wfd_dev->enc_sdev);
+err_venc_register_subdev:
+	v4l2_device_unregister_subdev(&wfd_dev->mdp_sdev);
+err_mdp_register_subdev:
+	video_unregister_device(wfd_dev->pvdev);
+err_video_register_device:
+	video_device_release(wfd_dev->pvdev);
+err_video_device_alloc:
+	v4l2_device_unregister(&wfd_dev->v4l2_dev);
+err_v4l2_registration:
+	return rc;
+}
+static int __devinit __wfd_probe(struct platform_device *pdev)
+{
+	int rc = 0, c = 0;
+	struct wfd_device *wfd_dev; /* Should be taken as an array*/
+	struct ion_client *ion_client = NULL;
+	struct msm_wfd_platform_data *wfd_priv;
+
+	WFD_MSG_DBG("__wfd_probe: E\n");
+	wfd_dev = kzalloc(sizeof(*wfd_dev)*WFD_NUM_DEVICES, GFP_KERNEL);
+	if (!wfd_dev) {
+		WFD_MSG_ERR("Could not allocate memory for "
+				"wfd device\n");
+		rc = -ENOMEM;
+		goto err_v4l2_probe;
+	}
+
+	wfd_priv = pdev->dev.platform_data;
+
+	pdev->dev.platform_data = (void *) wfd_dev;
+
+	ion_client = msm_ion_client_create(-1, "wfd");
+
+	rc = wfd_stats_setup();
+	if (rc) {
+		WFD_MSG_ERR("No debugfs support: %d\n", rc);
+		/* Don't treat this as a fatal err */
+		rc = 0;
+	}
+
+	if (!ion_client) {
+		WFD_MSG_ERR("Failed to create ion client\n");
+		rc = -ENODEV;
+		goto err_v4l2_probe;
+	}
+
+	for (c = 0; c < WFD_NUM_DEVICES; ++c) {
+		rc = wfd_dev_setup(&wfd_dev[c],
+			WFD_DEVICE_NUMBER_BASE + c, pdev);
+
+		if (rc) {
+			/* Clear out old devices */
+			for (--c; c >= 0; --c) {
+				v4l2_device_unregister_subdev(
+						&wfd_dev[c].vsg_sdev);
+				v4l2_device_unregister_subdev(
+						&wfd_dev[c].enc_sdev);
+				v4l2_device_unregister_subdev(
+						&wfd_dev[c].mdp_sdev);
+				video_unregister_device(wfd_dev[c].pvdev);
+				video_device_release(wfd_dev[c].pvdev);
+				v4l2_device_unregister(&wfd_dev[c].v4l2_dev);
+			}
+
+			goto err_v4l2_probe;
+		}
+
+		/* Other device specific stuff */
+		mutex_init(&wfd_dev[c].dev_lock);
+		wfd_dev[c].ion_client = ion_client;
+		wfd_dev[c].in_use = false;
+		if (wfd_priv && wfd_priv->wfd_check_mdp_iommu_split) {
+			wfd_dev[c].mdp_iommu_split_domain =
+				wfd_priv->wfd_check_mdp_iommu_split();
+		}
+
+		switch (WFD_DEVICE_NUMBER_BASE + c) {
+		case WFD_DEVICE_SECURE:
+			wfd_dev[c].secure = true;
+			break;
+		default:
+			break;
+		}
+
+	}
+	WFD_MSG_DBG("__wfd_probe: X\n");
+	return rc;
+err_v4l2_probe:
+	kfree(wfd_dev);
+	return rc;
+}
+
+static int __devexit __wfd_remove(struct platform_device *pdev)
+{
+	struct wfd_device *wfd_dev;
+	int c = 0;
+
+	wfd_dev = (struct wfd_device *)pdev->dev.platform_data;
+
+	WFD_MSG_DBG("Inside wfd_remove\n");
+	if (!wfd_dev) {
+		WFD_MSG_ERR("Error removing WFD device");
+		return -ENODEV;
+	}
+
+	wfd_stats_teardown();
+	for (c = 0; c < WFD_NUM_DEVICES; ++c) {
+		v4l2_device_unregister_subdev(&wfd_dev[c].vsg_sdev);
+		v4l2_device_unregister_subdev(&wfd_dev[c].enc_sdev);
+		v4l2_device_unregister_subdev(&wfd_dev[c].mdp_sdev);
+		video_unregister_device(wfd_dev[c].pvdev);
+		video_device_release(wfd_dev[c].pvdev);
+		v4l2_device_unregister(&wfd_dev[c].v4l2_dev);
+	}
+
+	kfree(wfd_dev);
+	return 0;
+}
+
+static const struct of_device_id msm_wfd_dt_match[] = {
+	{.compatible = "qcom,msm-wfd"},
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, msm_vidc_dt_match);
+
+static struct platform_driver wfd_driver = {
+	.probe =  __wfd_probe,
+	.remove = __wfd_remove,
+	.driver = {
+		.name = "msm_wfd",
+		.owner = THIS_MODULE,
+		.of_match_table = msm_wfd_dt_match,
+	}
+};
+
+static int __init wfd_init(void)
+{
+	int rc = 0;
+	WFD_MSG_DBG("Calling init function of wfd driver\n");
+	rc = platform_driver_register(&wfd_driver);
+	if (rc) {
+		WFD_MSG_ERR("failed to load the driver\n");
+		goto err_platform_registration;
+	}
+err_platform_registration:
+	return rc;
+}
+
+static void __exit wfd_exit(void)
+{
+	WFD_MSG_DBG("wfd_exit: X\n");
+	platform_driver_unregister(&wfd_driver);
+}
+
+module_init(wfd_init);
+module_exit(wfd_exit);
diff --git a/drivers/media/platform/msm/wfd/wfd-util.c b/drivers/media/platform/msm/wfd/wfd-util.c
new file mode 100644
index 0000000..965c873
--- /dev/null
+++ b/drivers/media/platform/msm/wfd/wfd-util.c
@@ -0,0 +1,221 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/debugfs.h>
+#include <linux/hrtimer.h>
+#include <linux/limits.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+
+#include "wfd-util.h"
+
+static struct dentry *wfd_debugfs_root;
+
+int wfd_stats_setup()
+{
+	wfd_debugfs_root = debugfs_create_dir("wfd", NULL);
+
+	if (wfd_debugfs_root == ERR_PTR(-ENODEV))
+		return -ENODEV;
+	else if (!wfd_debugfs_root)
+		return -ENOMEM;
+	else
+		return 0;
+}
+
+void wfd_stats_teardown()
+{
+	if (wfd_debugfs_root)
+		debugfs_remove_recursive(wfd_debugfs_root);
+}
+
+int wfd_stats_init(struct wfd_stats *stats, int device)
+{
+	char device_str[NAME_MAX] = "";
+	int rc = 0;
+
+	if (!stats) {
+		rc = -EINVAL;
+		goto wfd_stats_init_fail;
+	} else if (!wfd_debugfs_root) {
+		WFD_MSG_ERR("wfd debugfs root does not exist\n");
+		rc = -ENOENT;
+		goto wfd_stats_init_fail;
+	}
+
+	memset(stats, 0, sizeof(*stats));
+	INIT_LIST_HEAD(&stats->enc_queue);
+	mutex_init(&stats->mutex);
+
+	snprintf(device_str, sizeof(device_str), "%d", device);
+	stats->d_parent = debugfs_create_dir(device_str, wfd_debugfs_root);
+	if (IS_ERR(stats->d_parent)) {
+		rc = PTR_ERR(stats->d_parent);
+		stats->d_parent = NULL;
+		goto wfd_stats_init_fail;
+	}
+
+	stats->d_v4l2_buf_count = debugfs_create_u32("v4l2_buf_count", S_IRUGO,
+			stats->d_parent, &stats->v4l2_buf_count);
+	if (IS_ERR(stats->d_v4l2_buf_count)) {
+		rc = PTR_ERR(stats->d_v4l2_buf_count);
+		stats->d_v4l2_buf_count = NULL;
+		goto wfd_stats_init_fail;
+	}
+
+	stats->d_mdp_buf_count = debugfs_create_u32("mdp_buf_count", S_IRUGO,
+			stats->d_parent, &stats->mdp_buf_count);
+	if (IS_ERR(stats->d_mdp_buf_count)) {
+		rc = PTR_ERR(stats->d_mdp_buf_count);
+		stats->d_mdp_buf_count = NULL;
+		goto wfd_stats_init_fail;
+	}
+
+	stats->d_vsg_buf_count = debugfs_create_u32("vsg_buf_count", S_IRUGO,
+			stats->d_parent, &stats->vsg_buf_count);
+	if (IS_ERR(stats->d_vsg_buf_count)) {
+		rc = PTR_ERR(stats->d_vsg_buf_count);
+		stats->d_vsg_buf_count = NULL;
+		goto wfd_stats_init_fail;
+	}
+
+	stats->d_enc_buf_count = debugfs_create_u32("enc_buf_count", S_IRUGO,
+			stats->d_parent, &stats->enc_buf_count);
+	if (IS_ERR(stats->d_enc_buf_count)) {
+		rc = PTR_ERR(stats->d_enc_buf_count);
+		stats->d_enc_buf_count = NULL;
+		goto wfd_stats_init_fail;
+	}
+
+	stats->d_frames_encoded = debugfs_create_u32("frames_encoded", S_IRUGO,
+			stats->d_parent, &stats->frames_encoded);
+	if (IS_ERR(stats->d_frames_encoded)) {
+		rc = PTR_ERR(stats->d_frames_encoded);
+		stats->d_frames_encoded = NULL;
+		goto wfd_stats_init_fail;
+	}
+
+	stats->d_mdp_updates = debugfs_create_u32("mdp_updates", S_IRUGO,
+			stats->d_parent, &stats->mdp_updates);
+	if (IS_ERR(stats->d_mdp_updates)) {
+		rc = PTR_ERR(stats->d_mdp_updates);
+		stats->d_mdp_updates = NULL;
+		goto wfd_stats_init_fail;
+	}
+
+	stats->d_enc_avg_latency = debugfs_create_u32("enc_avg_latency",
+			S_IRUGO, stats->d_parent, &stats->enc_avg_latency);
+	if (IS_ERR(stats->d_enc_avg_latency)) {
+		rc = PTR_ERR(stats->d_enc_avg_latency);
+		stats->d_enc_avg_latency = NULL;
+		goto wfd_stats_init_fail;
+	}
+
+	return rc;
+wfd_stats_init_fail:
+	return rc;
+}
+
+int wfd_stats_update(struct wfd_stats *stats, enum wfd_stats_event event)
+{
+	int rc = 0;
+
+	mutex_lock(&stats->mutex);
+	switch (event) {
+	case WFD_STAT_EVENT_CLIENT_QUEUE:
+		stats->v4l2_buf_count++;
+		break;
+	case WFD_STAT_EVENT_CLIENT_DEQUEUE: {
+		struct wfd_stats_encode_sample *sample = NULL;
+
+		stats->v4l2_buf_count--;
+
+		if (!list_empty(&stats->enc_queue))
+			sample = list_first_entry(&stats->enc_queue,
+					struct wfd_stats_encode_sample,
+					list);
+		if (sample) {
+			ktime_t kdiff = ktime_sub(ktime_get(),
+						sample->encode_start_ts);
+			uint32_t diff = ktime_to_ms(kdiff);
+
+			stats->enc_cumulative_latency += diff;
+			stats->enc_latency_samples++;
+			stats->enc_avg_latency = stats->enc_cumulative_latency /
+				stats->enc_latency_samples;
+
+			list_del(&sample->list);
+			kfree(sample);
+			sample = NULL;
+		}
+		break;
+	}
+	case WFD_STAT_EVENT_MDP_QUEUE:
+		stats->mdp_buf_count++;
+		break;
+	case WFD_STAT_EVENT_MDP_DEQUEUE:
+		stats->mdp_buf_count--;
+		stats->mdp_updates++;
+		break;
+	case WFD_STAT_EVENT_ENC_QUEUE: {
+		struct wfd_stats_encode_sample *sample = NULL;
+
+		stats->enc_buf_count++;
+		stats->frames_encoded++;
+
+		sample = kzalloc(sizeof(*sample), GFP_KERNEL);
+		if (sample) {
+			INIT_LIST_HEAD(&sample->list);
+			sample->encode_start_ts = ktime_get();
+			list_add_tail(&sample->list, &stats->enc_queue);
+		} else {
+			WFD_MSG_WARN("Unable to measure latency\n");
+		}
+		break;
+	}
+	case WFD_STAT_EVENT_ENC_DEQUEUE:
+		stats->enc_buf_count--;
+		break;
+	case WFD_STAT_EVENT_VSG_QUEUE:
+		stats->vsg_buf_count++;
+		break;
+	case WFD_STAT_EVENT_VSG_DEQUEUE:
+		stats->vsg_buf_count--;
+		break;
+	default:
+		rc = -ENOTSUPP;
+	}
+	mutex_unlock(&stats->mutex);
+
+	return rc;
+}
+
+int wfd_stats_deinit(struct wfd_stats *stats)
+{
+	WFD_MSG_DBG("Latencies: avg enc. latency %d",
+			stats->enc_avg_latency);
+	/* Delete all debugfs files in one shot :) */
+	if (stats->d_parent)
+		debugfs_remove_recursive(stats->d_parent);
+
+	stats->d_parent =
+	stats->d_v4l2_buf_count =
+	stats->d_mdp_buf_count =
+	stats->d_vsg_buf_count =
+	stats->d_enc_buf_count =
+	stats->d_frames_encoded =
+	stats->d_mdp_updates =
+	stats->d_enc_avg_latency = NULL;
+
+	return 0;
+}
diff --git a/drivers/media/platform/msm/wfd/wfd-util.h b/drivers/media/platform/msm/wfd/wfd-util.h
new file mode 100644
index 0000000..a04e16a
--- /dev/null
+++ b/drivers/media/platform/msm/wfd/wfd-util.h
@@ -0,0 +1,87 @@
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/debugfs.h>
+#include <linux/ktime.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+
+#ifndef _WFD_UTIL_H_
+#define _WFD_UTIL_H_
+
+/*#define DEBUG_WFD*/
+
+#define WFD_TAG "wfd: "
+#define WFD_MSG_INFO(fmt...) pr_info(WFD_TAG fmt)
+#define WFD_MSG_WARN(fmt...) pr_warning(WFD_TAG fmt)
+#define WFD_MSG_ERR(fmt...) pr_err(WFD_TAG fmt)
+#define WFD_MSG_CRIT(fmt...) pr_crit(WFD_TAG fmt)
+#define WFD_MSG_DBG(fmt...) pr_debug(WFD_TAG fmt)
+
+
+struct wfd_stats_encode_sample {
+	ktime_t encode_start_ts;
+	struct list_head list;
+};
+
+struct wfd_stats {
+	struct mutex mutex;
+
+	/* Output Buffers */
+	uint32_t v4l2_buf_count;
+
+	/* Input Buffers */
+	uint32_t mdp_buf_count;
+	uint32_t vsg_buf_count;
+	uint32_t enc_buf_count;
+
+	/* Other */
+	uint32_t frames_encoded;
+	uint32_t mdp_updates;
+
+	uint32_t enc_avg_latency;
+	uint32_t enc_cumulative_latency;
+	uint32_t enc_latency_samples;
+	struct list_head enc_queue;
+
+	/* Debugfs entries */
+	struct dentry *d_parent;
+	struct dentry *d_v4l2_buf_count;
+	struct dentry *d_mdp_buf_count;
+	struct dentry *d_vsg_buf_count;
+	struct dentry *d_enc_buf_count;
+	struct dentry *d_frames_encoded;
+	struct dentry *d_mdp_updates;
+	struct dentry *d_enc_avg_latency;
+};
+
+enum wfd_stats_event {
+	WFD_STAT_EVENT_CLIENT_QUEUE,
+	WFD_STAT_EVENT_CLIENT_DEQUEUE,
+
+	WFD_STAT_EVENT_MDP_QUEUE,
+	WFD_STAT_EVENT_MDP_DEQUEUE,
+
+	WFD_STAT_EVENT_VSG_QUEUE,
+	WFD_STAT_EVENT_VSG_DEQUEUE,
+
+	WFD_STAT_EVENT_ENC_QUEUE,
+	WFD_STAT_EVENT_ENC_DEQUEUE,
+};
+
+int wfd_stats_setup(void);
+int wfd_stats_init(struct wfd_stats *, int device);
+int wfd_stats_update(struct wfd_stats *, enum wfd_stats_event);
+int wfd_stats_deinit(struct wfd_stats *);
+void wfd_stats_teardown(void);
+#endif
diff --git a/drivers/media/radio/radio-iris-transport.c b/drivers/media/radio/radio-iris-transport.c
index ed6ab4d..9a9b385 100644
--- a/drivers/media/radio/radio-iris-transport.c
+++ b/drivers/media/radio/radio-iris-transport.c
@@ -4,7 +4,7 @@
  *  FM HCI_SMD ( FM HCI Shared Memory Driver) is Qualcomm's Shared memory driver
  *  for the HCI protocol. This file is based on drivers/bluetooth/hci_vhci.c
  *
- *  Copyright (c) 2000-2001, 2011-2012 Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2000-2001, 2011-2012 The Linux Foundation. All rights reserved.
  *
  *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
  *  Copyright (C) 2004-2006  Marcel Holtmann <marcel@holtmann.org>
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index 363b541..11a8f4d 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -3956,10 +3956,16 @@
 	return 0;
 }
 
+static const struct of_device_id iris_fm_match[] = {
+	{.compatible = "qcom,iris_fm"},
+	{}
+};
+
 static struct platform_driver iris_driver = {
 	.driver = {
 		.owner  = THIS_MODULE,
 		.name   = "iris_fm",
+		.of_match_table = iris_fm_match,
 	},
 	.remove = __devexit_p(iris_remove),
 };
diff --git a/drivers/media/radio/radio-tavarua.c b/drivers/media/radio/radio-tavarua.c
index eb16f2d..a79009b 100644
--- a/drivers/media/radio/radio-tavarua.c
+++ b/drivers/media/radio/radio-tavarua.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/drivers/media/rc/keymaps/rc-philips.c b/drivers/media/rc/keymaps/rc-philips.c
index 9f63520..3bebcbf 100644
--- a/drivers/media/rc/keymaps/rc-philips.c
+++ b/drivers/media/rc/keymaps/rc-philips.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/media/rc/keymaps/rc-samsung-necx.c b/drivers/media/rc/keymaps/rc-samsung-necx.c
index 1a3d6be..3f490d9 100644
--- a/drivers/media/rc/keymaps/rc-samsung-necx.c
+++ b/drivers/media/rc/keymaps/rc-samsung-necx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/media/rc/keymaps/rc-ue-rf4ce.c b/drivers/media/rc/keymaps/rc-ue-rf4ce.c
index ea982a8..704d8b6 100644
--- a/drivers/media/rc/keymaps/rc-ue-rf4ce.c
+++ b/drivers/media/rc/keymaps/rc-ue-rf4ce.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/media/rc/user-rc-input.c b/drivers/media/rc/user-rc-input.c
index f1a9334..d02b32a 100644
--- a/drivers/media/rc/user-rc-input.c
+++ b/drivers/media/rc/user-rc-input.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 0d2d91c..a722a79 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -639,14 +639,6 @@
 	  Say Y here if you want to test video apps or debug V4L devices.
 	  In doubt, say N.
 
-config MSM_VCAP
-	tristate "Qualcomm MSM VCAP"
-	depends on VIDEO_DEV && VIDEO_V4L2
-	default y
-	---help---
-		Enables VCAP driver. This device allows for video capture and
-		video processing using the v4l2 api
-
 #
 # USB Multimedia device configuration
 #
@@ -1174,29 +1166,7 @@
 
 source "drivers/media/video/s5p-tv/Kconfig"
 
-#
-# MSM camera configuration
-#
 
-comment "Qualcomm MSM Camera And Video"
-
-menuconfig MSM_CAMERA
-	bool "Qualcomm MSM camera and video capture support"
-	depends on ARCH_MSM && VIDEO_V4L2 && I2C
-	default y
-	help
-	  Say Y here to enable selecting the video adapters for
-	  Qualcomm msm camera and video encoding
-
-config MSM_CAMERA_DEBUG
-	bool "Qualcomm MSM camera debugging with printk"
-	depends on MSM_CAMERA
-	default n
-	help
-	  Enable printk() debug for msm camera
-
-
-source "drivers/media/video/msm/Kconfig"
 
 endif # V4L_PLATFORM_DRIVERS
 endif # VIDEO_CAPTURE_DRIVERS
@@ -1260,6 +1230,3 @@
 	    conversion.
 
 endif # V4L_MEM2MEM_DRIVERS
-
-source "drivers/media/video/msm_vidc/Kconfig"
-source "drivers/media/video/msm_wfd/Kconfig"
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index fd736c3..1807467 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -170,9 +170,6 @@
 obj-$(CONFIG_VIDEO_MEM2MEM_TESTDEV) += mem2mem_testdev.o
 obj-$(CONFIG_VIDEO_CX23885) += cx23885/
 
-obj-$(CONFIG_MSM_VCAP) += vcap_v4l2.o
-obj-$(CONFIG_MSM_VCAP) += vcap_vc.o
-obj-$(CONFIG_MSM_VCAP) += vcap_vp.o
 obj-$(CONFIG_VIDEO_AK881X)		+= ak881x.o
 
 obj-$(CONFIG_VIDEO_OMAP2)		+= omap2cam.o
@@ -212,10 +209,7 @@
 
 obj-y	+= davinci/
 
-obj-$(CONFIG_MSM_CAMERA) += msm/
 obj-$(CONFIG_ARCH_OMAP)	+= omap/
-obj-$(CONFIG_MSM_VIDC_V4L2) += msm_vidc/
-obj-$(CONFIG_MSM_WFD) += msm_wfd/
 
 ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
 ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
diff --git a/drivers/media/video/msm/Kconfig b/drivers/media/video/msm/Kconfig
deleted file mode 100644
index 24f6556..0000000
--- a/drivers/media/video/msm/Kconfig
+++ /dev/null
@@ -1,418 +0,0 @@
-config MSM_CAMERA_V4L2
-        bool "MSM Camera V4L2 Interface"
-        depends on MSM_CAMERA
-        default n
-        ---help---
-          This flag enables V4L2 interface of MSM
-          camera driver. If enabled, application interacts
-          with /dev/video0 through V4L2 APIs. Otherwise,
-          native APIs are used through /dev/config0, /dev/frame0,
-          and /dev/control0.
-
-comment "Camera Sensor Selection"
-config MT9T013
-	bool "Sensor mt9t013 (BAYER 3M)"
-	depends on MSM_CAMERA && !ARCH_MSM8X60 && !ARCH_MSM8960 && !MSM_CAMERA_V4L2
-	default y
-	---help---
-	  MICRON 3M Bayer Sensor with AutoFocus
-config MT9D113
-	bool "Sensor mt9d113 (YUV 2M)"
-	depends on MSM_CAMERA && ARCH_MSM8X60 && !MSM_CAMERA_V4L2
-	default y
-	---help---
-	  MICRON 2M YUV Sensor
-	  This sensor is the front camera on QT8660.
-	  This uses csi mipi interface.
-	  This sensor is used only on QT device.
-config MT9D112
-	bool "Sensor mt9d112 (YUV 2M)"
-	depends on MSM_CAMERA && !ARCH_MSM8X60 && !ARCH_MSM8960 && !MSM_CAMERA_V4L2
-	default y
-	---help---
-	  MICRON 2M YUV Sensor
-config IMX074
-	bool "Sensor IMX074 (BAYER 13.5M)"
-	depends on MSM_CAMERA
-	---help---
-	SONY 13.5 MP Bayer Sensor
-config OV5640
-	bool "Sensor OV5640 (YUV 5M)"
-	depends on MSM_CAMERA && !MSM_CAMERA_V4L2
-	default n
-	---help---
-	Omni 5M YUV Sensor
-
-config OV5647
-	bool "Sensor ov5647 (BAYER 5M)"
-	depends on MSM_CAMERA
-	---help---
-	  OV 5M Bayer Sensor with AutoFocus
-
-config AD5046_ACT
-	bool "Lens actuator ad5046"
-	depends on MSM_CAMERA && OV5647
-	---help---
-	  ad5046 lens actuator driver for ov5647.
-	  Say Y here if this is msm7627A variant platform.
-config WEBCAM_OV7692_QRD
-	bool "Sensor OV7692 QRD(VGA YUV)"
-	depends on MSM_CAMERA && (ARCH_MSM7X27A || ARCH_MSM8X60)
-	default n
-	---help---
-	  Omni Vision VGA YUV Sensor for QRD Devices
-config MT9M114
-        bool "Sensor MT9M114 (YUV 1.26M)"
-        depends on MSM_CAMERA
-        ---help---
-        APTINA 1.26 MP yuv Sensor
-config WEBCAM_OV7692
-	bool "Sensor OV7692 (VGA YUV)"
-	depends on MSM_CAMERA && ARCH_MSM8X60 && !MSM_CAMERA_V4L2
-	default y
-	---help---
-	  Omni Vision VGA YUV Sensor.
-config WEBCAM_OV9726
-	bool "Sensor OV9726 (VGA Bayer)"
-	depends on MSM_CAMERA && (ARCH_MSM8X60 || ARCH_MSM7X30 || ARCH_MSM7X27A)
-	default n
-	---help---
-	  Omni Vision VGA Bayer Sensor.
-#	This Senosr is used as a webcam.
-#	This uses the CSI interface.
-config VX6953
-	bool "Sensor VX6953 (BAYER 5M)"
-	depends on MSM_CAMERA && (ARCH_MSM7X30 || ARCH_MSM8X60) && !MSM_CAMERA_V4L2
-	default y
-	---help---
-	STM 5M Bayer Sensor with EDOF
-config SN12M0PZ
-	bool "Sensor sn12m0pz (Bayer 12 MP)"
-	depends on MSM_CAMERA && ARCH_MSM7X30 && !MSM_CAMERA_V4L2
-	default y
-	---help---
-	  Sony 12 MP Bayer Sensor
-config MT9P012
-	bool "Sensor mt9p012 (BAYER 5M)"
-	depends on MSM_CAMERA && !ARCH_MSM8X60 && !MSM_CAMERA_V4L2
-	default y
-	---help---
-	  MICRON 5M Bayer Sensor with Autofocus
-
-choice
-	prompt "AF module"
-	depends on MT9P012 && !ARCH_MSM8X60 && !MSM_CAMERA_V4L2
-	default MSM_CAMERA_AF_FOXCONN
-
-config MSM_CAMERA_AF_FOXCONN
-	bool "FOXCONN Module"
-	help
-	  This driver supports FOXCONN AF module for 5M Bayer sensor
-
-config MSM_CAMERA_AF_BAM
-	bool "BAM Module"
-	help
-	  This driver supports BAM AF module for 5M Bayer sensor
-
-endchoice
-
-config MT9P012_KM
-	bool "Sensor mt9p012 KM module (BAYER 5M)"
-	depends on MSM_CAMERA && !ARCH_MSM8X60 && !MSM_CAMERA_V4L2
-	default y
-	---help---
-	  MICRON 5M Bayer Sensor KM modules with Autofocus
-
-config MT9E013
-	bool "Sensor mt9e013 module (BAYER 8M)"
-	depends on MSM_CAMERA && (ARCH_MSM7X30 || ARCH_MSM8X60 || ARCH_MSM7X27A)
-	default n
-	---help---
-	  Aptina 8M Bayer Sensor modules with Autofocus
-
-config IMX074_ACT
-	bool "Actuator IMX074 (BAYER 13.5M)"
-	depends on MSM_CAMERA
-	---help---
-	Actuator for SONY 13.5 MP Bayer Sensor
-
-config S5K3E2FX
-	bool "Sensor s5k3e2fx (Samsung 5M)"
-	depends on MSM_CAMERA && !ARCH_MSM8X60 && !MSM_CAMERA_V4L2
-	default y
-	---help---
-	  Samsung 5M with Autofocus
-
-config QS_S5K4E1
-	bool "Sensor qs_s5k4e1 (Samsung 5M)"
-	depends on MSM_CAMERA && ARCH_MSM8X60 && !MSM_CAMERA_V4L2
-	default y
-	---help---
-	  Samsung 5M with Autofocus
-
-config S5K4E1
-	bool "Sensor Sensor s5k4e1 (Samsung 5M)"
-	depends on MSM_CAMERA
-	default n
-	---help---
-	  Support for S5k4E1 samsung sensor driver.
-	  It is a Bayer 5MP sensor with auto focus and it supports
-	  two mipi lanes, required for msm7x2xA platform.
-	  Say Y here if this is msm7x2xA variant platform.
-
-config DW9712_ACT
-	bool "Lens actuator dw9721"
-	depends on MSM_CAMERA && S5K4E1
-	---help---
-	  dw9721 lens actuator driver for S5K4E1.
-	  Say Y here if this is msm7627A variant platform.
-
-config MSM_CAMERA_FLASH_SC628A
-	bool "Qualcomm MSM camera sc628a flash support"
-	depends on MSM_CAMERA
-	default n
-	---help---
-	  Enable support for LED flash for msm camera.
-	  It is a samtech charge pump flash driver and it
-	  supports spotlight and flash light modes with
-	  differrent current levels.
-
-config MSM_CAMERA_FLASH_TPS61310
-	bool "Qualcomm MSM camera tps61310 flash support"
-	depends on MSM_CAMERA
-	default n
-	---help---
-	  Enable support for LED flash for msm camera.
-	  It is a Texas Instruments multiple LED Flash
-	  for camera flash and video light applications.
-
-config MSM_CAMERA_LED_TRIGGER_FLASH
-	bool "Qualcomm MSM LED trigger flash support"
-	depends on MSM_CAMERA
-	default n
-	---help---
-	  Enable support for LED flash for msm camera.
-	  It creates LED trigger client, reads LED flash
-	  hardware properties provided in board file /
-	  device tree and uses these information to configure
-	  LED flash using LED trigger event function.
-
-config IMX072
-	bool "Sensor imx072 (Sony 5M)"
-	default n
-	---help---
-	  Support for IMX072 sony sensor driver.
-	  It is a Bayer 5MP sensor with auto focus and it supports
-	  two mipi lanes, required for msm7x2xA platform.
-	  Say Y here if this is msm7x2xA variant platform.
-
-config OV2720
-	bool "Sensor ov2720 (Omnivision 2MP)"
-	depends on MSM_CAMERA
-
-config OV8825
-	bool "Sensor ov8825 (Omnivision 8M)"
-	depends on MSM_CAMERA
-	---help---
-	  Support for OV8825 sensor driver.
-	  It is a Bayer 8MP sensor with auto focus and it supports
-	  two mipi lanes, required for msm8625 platform.
-	  Say Y here if this is msm8625 variant platform.
-
-config IMX135
-	bool "Sensor imx135 (Sony 13MP)"
-	depends on MSM_CAMERA
-	---help---
-	  Support for IMX135 sensor driver.
-	  This is a Sony 13MP Bayer Sensor with autofocus and video HDR
-	  support.
-	  Say Y if the platform uses IMX135 sensor.
-
-config VB6801
-	bool "Sensor vb6801"
-	depends on MSM_CAMERA && !ARCH_MSM8X60 && !MSM_CAMERA_V4L2
-	---help---
-	  5M with flash
-
-config MSM_CAMERA_FLASH
-	bool "Qualcomm MSM camera flash support"
-	depends on MSM_CAMERA
-	default y
-	---help---
-	  Enable support for LED flash for msm camera
-
-config MSM_CAMERA_SENSOR
-	bool "Qualcomm MSM camera sensor support"
-	depends on MSM_CAMERA
-
-config MSM_ACTUATOR
-	bool "Qualcomm MSM actuator support"
-	depends on MSM_CAMERA
-
-config MSM_EEPROM
-	bool "Qualcomm MSM EEPROM support"
-	depends on MSM_CAMERA
-
-config IMX074_EEPROM
-	bool "IMX074 EEPROM support"
-	depends on MSM_CAMERA
-
-config IMX091_EEPROM
-	bool "IMX091 EEPROM support"
-	depends on MSM_CAMERA
-
-config MSM_GEMINI
-	tristate "Qualcomm MSM Gemini Jpeg Engine support"
-	depends on MSM_CAMERA && (ARCH_MSM7X30 || ARCH_MSM8X60 || ARCH_MSM8960)
-	default n
-	---help---
-	  Enable support for Gemini Jpeg Engine
-
-config MSM_MERCURY
-        tristate "Qualcomm MSM Mercury Jpeg Decoder Engine support"
-        depends on MSM_CAMERA && ARCH_MSM8960
-        ---help---
-          Enable support for Mercury Jpeg Engine
-
-config MSM_JPEG
-	tristate "Qualcomm MSM Jpeg Encoder Engine support"
-	depends on MSM_CAMERA && ARCH_MSM8974
-	---help---
-          Enable support for Jpeg Encoder/Decoder
-	  Engine for 8974.
-	  This module serves as the common driver
-	  for the JPEG 1.0 encoder and decoder.
-
-config MSM_VPE
-	tristate "Qualcomm MSM Video Pre-processing Engine support"
-	depends on MSM_CAMERA && (ARCH_MSM7X30 || ARCH_MSM8X60)
-	default y
-	---help---
-	  Enable support for Video Pre-processing Engine
-
-config MSM_CAM_IRQ_ROUTER
-	bool "Enable MSM CAM IRQ Router"
-	depends on MSM_CAMERA
-	---help---
-	Enable IRQ Router for Camera. Depending on the
-	configuration, this module can handle the
-	interrupts from multiple camera hardware
-	cores and composite them into a single
-	interrupt to the MSM.
-
-config MSM_CPP
-        bool "Qualcomm MSM Camera Post Processing Engine support"
-        depends on MSM_CAMERA && MSM_CAMERA_V4L2
-        ---help---
-          Enable support for Camera Post-processing Engine
-          The Post processing engine is capable of scaling
-          and cropping image. The driver support V4L2 subdev
-          APIs.
-
-config MSM_CCI
-        bool "Qualcomm MSM Camera Control Interface support"
-        depends on MSM_CAMERA
-        ---help---
-          Enable support for Camera Control Interface driver only
-          for those platforms that have hardware support. This driver
-          is responsible for handling I2C read and write on the I2C
-          bus. It is also responsible for synchronization with
-          GPIO and data frames.
-
-config QUP_EXCLUSIVE_TO_CAMERA
-	bool "QUP exclusive to camera"
-	depends on MSM_CAMERA
-	default y
-	---help---
-	  This flag enabled states that QUP
-	  is exclusive to camera. In case this
-	  is disabled, the lvs1 voltage is enabled
-	  by QUP in the board file as QUP is used by
-	  applications other than camera.
-
-config MSM_CSI20_HEADER
-        bool "Qualcomm MSM CSI 2.0 Header"
-        depends on MSM_CAMERA
-        ---help---
-          Enable support for CSI drivers to include 2.0
-          header. This header has register macros and its
-          values and bit mask for register configuration bits
-          This config macro is required targets based on 8960,
-          8930 and 8064 platforms.
-
-config MSM_CSI30_HEADER
-        bool "Qualcomm MSM CSI 3.0 Header"
-        depends on MSM_CAMERA
-        ---help---
-          Enable support for CSI drivers to include 3.0
-          header. This header has register macros and its
-          values and bit mask for register configuration bits
-          This config macro is required for targets based on
-          8064 platforms.
-
-config MSM_CSIPHY
-        bool "Qualcomm MSM Camera Serial Interface Physical receiver support"
-        depends on MSM_CAMERA
-        ---help---
-          Enable support for Camera Serial Interface
-          Physical receiver. It deserializes packets and
-          supports detection of packet start and stop
-          signalling.
-
-config MSM_CSID
-        bool "Qualcomm MSM Camera Serial Interface decoder support"
-        depends on MSM_CAMERA
-        ---help---
-          Enable support for Camera Serial Interface decoder.
-          It supports lane merging and decoding of packets
-          based on cid which is mapped to a virtual channel
-          and datatype.
-
-config MSM_CSI2_REGISTER
-        bool "Qualcomm MSM CSI2 Register"
-        depends on MSM_CAMERA
-        ---help---
-          Register CSIPHY, CSID and ISPIF subdevices during
-          msm_open. Different CSI components are registered
-          based on platform. This macro specifies registering
-          of CSIPHY, CSID and ISPIF subdevices to receive data
-          from sensor.
-
-config MSM_ISPIF
-        bool "Qualcomm MSM Image Signal Processing interface support"
-        depends on MSM_CAMERA
-        ---help---
-          Enable support for Image Signal Processing interface module.
-          This module acts as a crossbar between CSID and VFE. Output
-          of any CID of CSID can be routed to of of pixel or raw
-          data interface in VFE.
-
-config S5K3L1YX
-	bool "Sensor S5K3L1YX (BAYER 12M)"
-	depends on MSM_CAMERA
-	---help---
-		Samsung 12 MP Bayer Sensor with auto focus, uses
-		4 mipi lanes, preview config = 1984 * 1508 at 30 fps,
-		snapshot config = 4000 * 3000 at 20 fps,
-		hfr video at 60, 90 and 120 fps.
-
-config IMX091
-        bool "Sensor imx091 (Sony 13MP)"
-        depends on MSM_CAMERA
-	---help---
-	  Sony 13MP sensor back camera that uses 4 mipi lanes,
-	  runs at 30 fps preview and 14 fps snapshot
-
-config MSM_V4L2_VIDEO_OVERLAY_DEVICE
-	tristate "Qualcomm MSM V4l2 video overlay device"
-	---help---
-	  Enables support for the MSM V4L2 video
-	  overlay driver. This allows video rendering
-	  apps to render overlaid video using Video4Linux2
-	  APIs, by using /dev/videoX device
-
-config OV7692
-	bool "Sensor OV7692 (VGA YUV)"
-	depends on MSM_CAMERA
-	---help---
-	  Omni Vision VGA YUV Sensor
diff --git a/drivers/media/video/msm/Makefile b/drivers/media/video/msm/Makefile
deleted file mode 100644
index 56d3e0c..0000000
--- a/drivers/media/video/msm/Makefile
+++ /dev/null
@@ -1,59 +0,0 @@
-GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
-
-ccflags-y += -Idrivers/media/video/msm/io
-ccflags-y += -Idrivers/media/video/msm/vfe
-obj-$(CONFIG_MSM_CAMERA) += io/
-ifeq ($(CONFIG_MSM_CAMERA_V4L2),y)
-  EXTRA_CFLAGS += -Idrivers/media/video/msm/cci
-  EXTRA_CFLAGS += -Idrivers/media/video/msm/csi
-  EXTRA_CFLAGS += -Idrivers/media/video/msm/eeprom
-  EXTRA_CFLAGS += -Idrivers/media/video/msm/sensors
-  EXTRA_CFLAGS += -Idrivers/media/video/msm/actuators
-  EXTRA_CFLAGS += -Idrivers/media/video/msm/server
-  EXTRA_CFLAGS += -Idrivers/media/video/msm/flash
-  obj-$(CONFIG_MSM_CAMERA) += msm_isp.o msm.o msm_mem.o msm_mctl.o msm_mctl_buf.o msm_mctl_pp.o
-  obj-$(CONFIG_MSM_CAMERA) += server/
-  obj-$(CONFIG_MSM_CAM_IRQ_ROUTER) += msm_camirq_router.o
-  obj-$(CONFIG_MSM_CAMERA) += cci/ eeprom/ sensors/ actuators/ csi/
-  obj-$(CONFIG_MSM_CPP) += cpp/
-  obj-$(CONFIG_MSM_CAMERA) += msm_gesture.o
-  obj-$(CONFIG_MSM_CAMERA) += flash/
-else
-  obj-$(CONFIG_MSM_CAMERA) += msm_camera.o
-endif
-obj-$(CONFIG_MSM_CAMERA) += vfe/
-obj-$(CONFIG_MSM_CAMERA) += msm_axi_qos.o gemini/ mercury/ jpeg_10/
-ifeq ($(CONFIG_MSM_CAMERA_V4L2),y)
-  obj-$(CONFIG_ARCH_MSM8X60) += msm_vpe.o
-  obj-$(CONFIG_ARCH_MSM7X30) += msm_vpe.o msm_axi_qos.o
-else
-  obj-$(CONFIG_ARCH_MSM8X60) += msm_vpe1.o
-  obj-$(CONFIG_ARCH_MSM7X30) += msm_vpe1.o
-endif
-obj-$(CONFIG_ARCH_MSM8960) += msm_vpe.o
-obj-$(CONFIG_MT9T013) += mt9t013.o mt9t013_reg.o
-obj-$(CONFIG_SN12M0PZ) += sn12m0pz.o sn12m0pz_reg.o
-obj-$(CONFIG_MT9P012) += mt9p012_reg.o
-obj-$(CONFIG_MSM_CAMERA_AF_FOXCONN) += mt9p012_fox.o
-obj-$(CONFIG_MSM_CAMERA_AF_BAM) += mt9p012_bam.o
-obj-$(CONFIG_MT9P012_KM) += mt9p012_km.o mt9p012_km_reg.o
-obj-$(CONFIG_S5K3E2FX) += s5k3e2fx.o
-#FIXME: Merge the two ifeq causes VX6953 preview not coming up.
-ifneq ($(CONFIG_MSM_CAMERA_V4L2),y)
-  obj-$(CONFIG_VX6953) += vx6953.o vx6953_reg.o
-  obj-$(CONFIG_IMX074) += imx074.o imx074_reg.o
-  obj-$(CONFIG_MT9E013) += mt9e013.o mt9e013_reg.o
-  obj-$(CONFIG_WEBCAM_OV9726) += ov9726.o ov9726_reg.o
-  obj-$(CONFIG_OV5647) += ov5647.o ov5647_reg.o
-  obj-$(CONFIG_S5K4E1) += s5k4e1.o s5k4e1_reg.o
-  obj-$(CONFIG_WEBCAM_OV7692) += ov7692.o
-  obj-$(CONFIG_WEBCAM_OV7692_QRD) += ov7692_qrd.o
-endif
-obj-$(CONFIG_QS_S5K4E1) += qs_s5k4e1.o qs_s5k4e1_reg.o
-obj-$(CONFIG_VB6801) += vb6801.o
-obj-$(CONFIG_IMX072) += imx072.o imx072_reg.o
-obj-$(CONFIG_OV5640) += ov5640.o
-obj-$(CONFIG_MT9D112) += mt9d112.o mt9d112_reg.o
-
-obj-$(CONFIG_MT9D113) += mt9d113.o mt9d113_reg.o
-obj-$(CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE) += msm_v4l2_video.o
diff --git a/drivers/media/video/msm/actuators/Makefile b/drivers/media/video/msm/actuators/Makefile
deleted file mode 100644
index 70a3a19..0000000
--- a/drivers/media/video/msm/actuators/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
-EXTRA_CFLAGS += -Idrivers/media/video/msm
-EXTRA_CFLAGS += -Idrivers/media/video/msm/io
-obj-$(CONFIG_MSM_ACTUATOR) += msm_actuator.o
diff --git a/drivers/media/video/msm/actuators/msm_actuator.c b/drivers/media/video/msm/actuators/msm_actuator.c
deleted file mode 100644
index b5bdaae..0000000
--- a/drivers/media/video/msm/actuators/msm_actuator.c
+++ /dev/null
@@ -1,692 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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 "msm_actuator.h"
-
-static struct msm_actuator_ctrl_t msm_actuator_t;
-static struct msm_actuator msm_vcm_actuator_table;
-static struct msm_actuator msm_piezo_actuator_table;
-
-static struct msm_actuator *actuators[] = {
-	&msm_vcm_actuator_table,
-	&msm_piezo_actuator_table,
-};
-
-static int32_t msm_actuator_piezo_set_default_focus(
-	struct msm_actuator_ctrl_t *a_ctrl,
-	struct msm_actuator_move_params_t *move_params)
-{
-	int32_t rc = 0;
-
-	if (a_ctrl->curr_step_pos != 0) {
-		a_ctrl->i2c_tbl_index = 0;
-		rc = a_ctrl->func_tbl->actuator_parse_i2c_params(a_ctrl,
-			a_ctrl->initial_code, 0, 0);
-		rc = a_ctrl->func_tbl->actuator_parse_i2c_params(a_ctrl,
-			a_ctrl->initial_code, 0, 0);
-		rc = msm_camera_i2c_write_table_w_microdelay(
-			&a_ctrl->i2c_client, a_ctrl->i2c_reg_tbl,
-			a_ctrl->i2c_tbl_index, a_ctrl->i2c_data_type);
-		if (rc < 0) {
-			pr_err("%s: i2c write error:%d\n",
-				__func__, rc);
-			return rc;
-		}
-		a_ctrl->i2c_tbl_index = 0;
-		a_ctrl->curr_step_pos = 0;
-	}
-	return rc;
-}
-
-static int32_t msm_actuator_parse_i2c_params(struct msm_actuator_ctrl_t *a_ctrl,
-	int16_t next_lens_position, uint32_t hw_params, uint16_t delay)
-{
-	struct msm_actuator_reg_params_t *write_arr = a_ctrl->reg_tbl;
-	uint32_t hw_dword = hw_params;
-	uint16_t i2c_byte1 = 0, i2c_byte2 = 0;
-	uint16_t value = 0;
-	uint32_t size = a_ctrl->reg_tbl_size, i = 0;
-	int32_t rc = 0;
-	struct msm_camera_i2c_reg_tbl *i2c_tbl = a_ctrl->i2c_reg_tbl;
-	CDBG("%s: IN\n", __func__);
-	for (i = 0; i < size; i++) {
-		if (write_arr[i].reg_write_type == MSM_ACTUATOR_WRITE_DAC) {
-			value = (next_lens_position <<
-				write_arr[i].data_shift) |
-				((hw_dword & write_arr[i].hw_mask) >>
-				write_arr[i].hw_shift);
-
-			if (write_arr[i].reg_addr != 0xFFFF) {
-				i2c_byte1 = write_arr[i].reg_addr;
-				i2c_byte2 = value;
-				if (size != (i+1)) {
-					i2c_byte2 = value & 0xFF;
-					CDBG("%s: byte1:0x%x, byte2:0x%x\n",
-					__func__, i2c_byte1, i2c_byte2);
-					i2c_tbl[a_ctrl->i2c_tbl_index].
-						reg_addr = i2c_byte1;
-					i2c_tbl[a_ctrl->i2c_tbl_index].
-						reg_data = i2c_byte2;
-					i2c_tbl[a_ctrl->i2c_tbl_index].
-						delay = 0;
-					a_ctrl->i2c_tbl_index++;
-					i++;
-					i2c_byte1 = write_arr[i].reg_addr;
-					i2c_byte2 = (value & 0xFF00) >> 8;
-				}
-			} else {
-				i2c_byte1 = (value & 0xFF00) >> 8;
-				i2c_byte2 = value & 0xFF;
-			}
-		} else {
-			i2c_byte1 = write_arr[i].reg_addr;
-			i2c_byte2 = (hw_dword & write_arr[i].hw_mask) >>
-				write_arr[i].hw_shift;
-		}
-		CDBG("%s: i2c_byte1:0x%x, i2c_byte2:0x%x\n", __func__,
-			i2c_byte1, i2c_byte2);
-		i2c_tbl[a_ctrl->i2c_tbl_index].reg_addr = i2c_byte1;
-		i2c_tbl[a_ctrl->i2c_tbl_index].reg_data = i2c_byte2;
-		i2c_tbl[a_ctrl->i2c_tbl_index].delay = delay;
-		a_ctrl->i2c_tbl_index++;
-	}
-		CDBG("%s: OUT\n", __func__);
-	return rc;
-}
-
-static int32_t msm_actuator_init_focus(struct msm_actuator_ctrl_t *a_ctrl,
-	uint16_t size, enum msm_actuator_data_type type,
-	struct reg_settings_t *settings)
-{
-	int32_t rc = -EFAULT;
-	int32_t i = 0;
-	CDBG("%s called\n", __func__);
-
-	for (i = 0; i < size; i++) {
-		switch (type) {
-		case MSM_ACTUATOR_BYTE_DATA:
-			rc = msm_camera_i2c_write(
-				&a_ctrl->i2c_client,
-				settings[i].reg_addr,
-				settings[i].reg_data, MSM_CAMERA_I2C_BYTE_DATA);
-			break;
-		case MSM_ACTUATOR_WORD_DATA:
-			rc = msm_camera_i2c_write(
-				&a_ctrl->i2c_client,
-				settings[i].reg_addr,
-				settings[i].reg_data, MSM_CAMERA_I2C_WORD_DATA);
-			break;
-		default:
-			pr_err("%s: Unsupport data type: %d\n",
-				__func__, type);
-			break;
-		}
-		if (rc < 0)
-			break;
-	}
-
-	a_ctrl->curr_step_pos = 0;
-	CDBG("%s Exit:%d\n", __func__, rc);
-	return rc;
-}
-
-static int32_t msm_actuator_write_focus(
-	struct msm_actuator_ctrl_t *a_ctrl,
-	uint16_t curr_lens_pos,
-	struct damping_params_t *damping_params,
-	int8_t sign_direction,
-	int16_t code_boundary)
-{
-	int32_t rc = 0;
-	int16_t next_lens_pos = 0;
-	uint16_t damping_code_step = 0;
-	uint16_t wait_time = 0;
-
-	damping_code_step = damping_params->damping_step;
-	wait_time = damping_params->damping_delay;
-
-	/* Write code based on damping_code_step in a loop */
-	for (next_lens_pos =
-		curr_lens_pos + (sign_direction * damping_code_step);
-		(sign_direction * next_lens_pos) <=
-			(sign_direction * code_boundary);
-		next_lens_pos =
-			(next_lens_pos +
-				(sign_direction * damping_code_step))) {
-		rc = a_ctrl->func_tbl->
-			actuator_parse_i2c_params(a_ctrl, next_lens_pos,
-				damping_params->hw_params, wait_time);
-		if (rc < 0) {
-			pr_err("%s: error:%d\n",
-				__func__, rc);
-			return rc;
-		}
-		curr_lens_pos = next_lens_pos;
-	}
-
-	if (curr_lens_pos != code_boundary) {
-		rc = a_ctrl->func_tbl->
-			actuator_parse_i2c_params(a_ctrl, code_boundary,
-				damping_params->hw_params, wait_time);
-	}
-	return rc;
-}
-
-static int32_t msm_actuator_piezo_move_focus(
-	struct msm_actuator_ctrl_t *a_ctrl,
-	struct msm_actuator_move_params_t *move_params)
-{
-	int32_t dest_step_position = move_params->dest_step_pos;
-	int32_t rc = 0;
-	int32_t num_steps = move_params->num_steps;
-
-	if (num_steps == 0)
-		return rc;
-
-	a_ctrl->i2c_tbl_index = 0;
-	rc = a_ctrl->func_tbl->
-		actuator_parse_i2c_params(a_ctrl,
-		(num_steps *
-		a_ctrl->region_params[0].code_per_step),
-		move_params->ringing_params[0].hw_params, 0);
-
-	rc = msm_camera_i2c_write_table_w_microdelay(&a_ctrl->i2c_client,
-		a_ctrl->i2c_reg_tbl, a_ctrl->i2c_tbl_index,
-		a_ctrl->i2c_data_type);
-	if (rc < 0) {
-		pr_err("%s: i2c write error:%d\n",
-			__func__, rc);
-		return rc;
-	}
-	a_ctrl->i2c_tbl_index = 0;
-	a_ctrl->curr_step_pos = dest_step_position;
-	return rc;
-}
-
-static int32_t msm_actuator_move_focus(
-	struct msm_actuator_ctrl_t *a_ctrl,
-	struct msm_actuator_move_params_t *move_params)
-{
-	int32_t rc = 0;
-	int8_t sign_dir = move_params->sign_dir;
-	uint16_t step_boundary = 0;
-	uint16_t target_step_pos = 0;
-	uint16_t target_lens_pos = 0;
-	int16_t dest_step_pos = move_params->dest_step_pos;
-	uint16_t curr_lens_pos = 0;
-	int dir = move_params->dir;
-	int32_t num_steps = move_params->num_steps;
-
-	CDBG("%s called, dir %d, num_steps %d\n",
-		__func__,
-		dir,
-		num_steps);
-
-	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);
-
-	while (a_ctrl->curr_step_pos != dest_step_pos) {
-		step_boundary =
-			a_ctrl->region_params[a_ctrl->curr_region_index].
-			step_bound[dir];
-		if ((dest_step_pos * sign_dir) <=
-			(step_boundary * sign_dir)) {
-
-			target_step_pos = dest_step_pos;
-			target_lens_pos =
-				a_ctrl->step_position_table[target_step_pos];
-			rc = a_ctrl->func_tbl->
-				actuator_write_focus(
-					a_ctrl,
-					curr_lens_pos,
-					&(move_params->
-						ringing_params[a_ctrl->
-						curr_region_index]),
-					sign_dir,
-					target_lens_pos);
-			if (rc < 0) {
-				pr_err("%s: error:%d\n",
-					__func__, rc);
-				return rc;
-			}
-			curr_lens_pos = target_lens_pos;
-
-		} else {
-			target_step_pos = step_boundary;
-			target_lens_pos =
-				a_ctrl->step_position_table[target_step_pos];
-			rc = a_ctrl->func_tbl->
-				actuator_write_focus(
-					a_ctrl,
-					curr_lens_pos,
-					&(move_params->
-						ringing_params[a_ctrl->
-						curr_region_index]),
-					sign_dir,
-					target_lens_pos);
-			if (rc < 0) {
-				pr_err("%s: error:%d\n",
-					__func__, rc);
-				return rc;
-			}
-			curr_lens_pos = target_lens_pos;
-
-			a_ctrl->curr_region_index += sign_dir;
-		}
-		a_ctrl->curr_step_pos = target_step_pos;
-	}
-
-	rc = msm_camera_i2c_write_table_w_microdelay(&a_ctrl->i2c_client,
-		a_ctrl->i2c_reg_tbl, a_ctrl->i2c_tbl_index,
-		a_ctrl->i2c_data_type);
-	if (rc < 0) {
-		pr_err("%s: i2c write error:%d\n",
-			__func__, rc);
-		return rc;
-	}
-	a_ctrl->i2c_tbl_index = 0;
-
-	return rc;
-}
-
-static int32_t msm_actuator_init_step_table(struct msm_actuator_ctrl_t *a_ctrl,
-	struct msm_actuator_set_info_t *set_info)
-{
-	int16_t code_per_step = 0;
-	int32_t rc = 0;
-	int16_t cur_code = 0;
-	int16_t step_index = 0, region_index = 0;
-	uint16_t step_boundary = 0;
-	uint32_t max_code_size = 1;
-	uint16_t data_size = set_info->actuator_params.data_size;
-	CDBG("%s called\n", __func__);
-
-	for (; data_size > 0; data_size--)
-		max_code_size *= 2;
-
-	kfree(a_ctrl->step_position_table);
-	a_ctrl->step_position_table = NULL;
-
-	/* Fill step position table */
-	a_ctrl->step_position_table =
-		kmalloc(sizeof(uint16_t) *
-		(set_info->af_tuning_params.total_steps + 1), GFP_KERNEL);
-
-	if (a_ctrl->step_position_table == NULL)
-		return -EFAULT;
-
-	cur_code = set_info->af_tuning_params.initial_code;
-	a_ctrl->step_position_table[step_index++] = cur_code;
-	for (region_index = 0;
-		region_index < a_ctrl->region_size;
-		region_index++) {
-		code_per_step =
-			a_ctrl->region_params[region_index].code_per_step;
-		step_boundary =
-			a_ctrl->region_params[region_index].
-			step_bound[MOVE_NEAR];
-		for (; step_index <= step_boundary;
-			step_index++) {
-			cur_code += code_per_step;
-			if (cur_code < max_code_size)
-				a_ctrl->step_position_table[step_index] =
-					cur_code;
-			else {
-				for (; step_index <
-					set_info->af_tuning_params.total_steps;
-					step_index++)
-					a_ctrl->
-						step_position_table[
-						step_index] =
-						max_code_size;
-
-				return rc;
-			}
-		}
-	}
-
-	return rc;
-}
-
-static int32_t msm_actuator_set_default_focus(
-	struct msm_actuator_ctrl_t *a_ctrl,
-	struct msm_actuator_move_params_t *move_params)
-{
-	int32_t rc = 0;
-	CDBG("%s called\n", __func__);
-
-	if (a_ctrl->curr_step_pos != 0)
-		rc = a_ctrl->func_tbl->actuator_move_focus(a_ctrl, move_params);
-	return rc;
-}
-
-static int32_t msm_actuator_power_down(struct msm_actuator_ctrl_t *a_ctrl)
-{
-	int32_t rc = 0;
-	if (a_ctrl->vcm_enable) {
-		rc = gpio_direction_output(a_ctrl->vcm_pwd, 0);
-		if (!rc)
-			gpio_free(a_ctrl->vcm_pwd);
-	}
-
-	kfree(a_ctrl->step_position_table);
-	a_ctrl->step_position_table = NULL;
-	kfree(a_ctrl->i2c_reg_tbl);
-	a_ctrl->i2c_reg_tbl = NULL;
-	a_ctrl->i2c_tbl_index = 0;
-	return rc;
-}
-
-static int32_t msm_actuator_init(struct msm_actuator_ctrl_t *a_ctrl,
-	struct msm_actuator_set_info_t *set_info) {
-	struct reg_settings_t *init_settings = NULL;
-	int32_t rc = -EFAULT;
-	uint16_t i = 0;
-	CDBG("%s: IN\n", __func__);
-
-	for (i = 0; i < ARRAY_SIZE(actuators); i++) {
-		if (set_info->actuator_params.act_type ==
-			actuators[i]->act_type) {
-			a_ctrl->func_tbl = &actuators[i]->func_tbl;
-			rc = 0;
-		}
-	}
-
-	if (rc < 0) {
-		pr_err("%s: Actuator function table not found\n", __func__);
-		return rc;
-	}
-
-	a_ctrl->region_size = set_info->af_tuning_params.region_size;
-	if (a_ctrl->region_size > MAX_ACTUATOR_REGION) {
-		pr_err("%s: MAX_ACTUATOR_REGION is exceeded.\n", __func__);
-		return -EFAULT;
-	}
-	a_ctrl->pwd_step = set_info->af_tuning_params.pwd_step;
-	a_ctrl->total_steps = set_info->af_tuning_params.total_steps;
-
-	if (copy_from_user(&a_ctrl->region_params,
-		(void *)set_info->af_tuning_params.region_params,
-		a_ctrl->region_size * sizeof(struct region_params_t)))
-		return -EFAULT;
-
-	a_ctrl->i2c_data_type = set_info->actuator_params.i2c_data_type;
-	a_ctrl->i2c_client.client->addr = set_info->actuator_params.i2c_addr;
-	a_ctrl->i2c_client.addr_type = set_info->actuator_params.i2c_addr_type;
-	a_ctrl->reg_tbl_size = set_info->actuator_params.reg_tbl_size;
-	if (a_ctrl->reg_tbl_size > MAX_ACTUATOR_REG_TBL_SIZE) {
-		pr_err("%s: MAX_ACTUATOR_REG_TBL_SIZE is exceeded.\n",
-			__func__);
-		return -EFAULT;
-	}
-
-	a_ctrl->i2c_reg_tbl =
-		kmalloc(sizeof(struct msm_camera_i2c_reg_tbl) *
-		(set_info->af_tuning_params.total_steps + 1), GFP_KERNEL);
-	if (!a_ctrl->i2c_reg_tbl) {
-		pr_err("%s kmalloc fail\n", __func__);
-		return -EFAULT;
-	}
-
-	if (copy_from_user(&a_ctrl->reg_tbl,
-		(void *)set_info->actuator_params.reg_tbl_params,
-		a_ctrl->reg_tbl_size *
-		sizeof(struct msm_actuator_reg_params_t))) {
-		kfree(a_ctrl->i2c_reg_tbl);
-		return -EFAULT;
-	}
-
-	if (set_info->actuator_params.init_setting_size) {
-		if (a_ctrl->func_tbl->actuator_init_focus) {
-			init_settings = kmalloc(sizeof(struct reg_settings_t) *
-				(set_info->actuator_params.init_setting_size),
-				GFP_KERNEL);
-			if (init_settings == NULL) {
-				kfree(a_ctrl->i2c_reg_tbl);
-				pr_err("%s Error allocating memory for init_settings\n",
-					__func__);
-				return -EFAULT;
-			}
-			if (copy_from_user(init_settings,
-				(void *)set_info->actuator_params.init_settings,
-				set_info->actuator_params.init_setting_size *
-				sizeof(struct reg_settings_t))) {
-				kfree(init_settings);
-				kfree(a_ctrl->i2c_reg_tbl);
-				pr_err("%s Error copying init_settings\n",
-					__func__);
-				return -EFAULT;
-			}
-			rc = a_ctrl->func_tbl->actuator_init_focus(a_ctrl,
-				set_info->actuator_params.init_setting_size,
-				a_ctrl->i2c_data_type,
-				init_settings);
-			kfree(init_settings);
-			if (rc < 0) {
-				kfree(a_ctrl->i2c_reg_tbl);
-				pr_err("%s Error actuator_init_focus\n",
-					__func__);
-				return -EFAULT;
-			}
-		}
-	}
-
-	a_ctrl->initial_code = set_info->af_tuning_params.initial_code;
-	if (a_ctrl->func_tbl->actuator_init_step_table)
-		rc = a_ctrl->func_tbl->
-			actuator_init_step_table(a_ctrl, set_info);
-
-	a_ctrl->curr_step_pos = 0;
-	a_ctrl->curr_region_index = 0;
-
-	return rc;
-}
-
-
-static int32_t msm_actuator_config(struct msm_actuator_ctrl_t *a_ctrl,
-							void __user *argp)
-{
-	struct msm_actuator_cfg_data cdata;
-	int32_t rc = 0;
-	if (copy_from_user(&cdata,
-		(void *)argp,
-		sizeof(struct msm_actuator_cfg_data)))
-		return -EFAULT;
-	mutex_lock(a_ctrl->actuator_mutex);
-	CDBG("%s called, type %d\n", __func__, cdata.cfgtype);
-	switch (cdata.cfgtype) {
-	case CFG_SET_ACTUATOR_INFO:
-		rc = msm_actuator_init(a_ctrl, &cdata.cfg.set_info);
-		if (rc < 0)
-			pr_err("%s init table failed %d\n", __func__, rc);
-		break;
-
-	case CFG_SET_DEFAULT_FOCUS:
-		rc = a_ctrl->func_tbl->actuator_set_default_focus(a_ctrl,
-			&cdata.cfg.move);
-		if (rc < 0)
-			pr_err("%s move focus failed %d\n", __func__, rc);
-		break;
-
-	case CFG_MOVE_FOCUS:
-		rc = a_ctrl->func_tbl->actuator_move_focus(a_ctrl,
-			&cdata.cfg.move);
-		if (rc < 0)
-			pr_err("%s move focus failed %d\n", __func__, rc);
-		break;
-
-	default:
-		break;
-	}
-	mutex_unlock(a_ctrl->actuator_mutex);
-	return rc;
-}
-
-static int32_t msm_actuator_i2c_probe(
-	struct i2c_client *client,
-	const struct i2c_device_id *id)
-{
-	int rc = 0;
-	struct msm_actuator_ctrl_t *act_ctrl_t = NULL;
-	CDBG("%s called\n", __func__);
-
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		pr_err("i2c_check_functionality failed\n");
-		goto probe_failure;
-	}
-
-	act_ctrl_t = (struct msm_actuator_ctrl_t *)(id->driver_data);
-	CDBG("%s client = %x\n",
-		__func__, (unsigned int) client);
-	act_ctrl_t->i2c_client.client = client;
-
-	/* Assign name for sub device */
-	snprintf(act_ctrl_t->sdev.name, sizeof(act_ctrl_t->sdev.name),
-			 "%s", act_ctrl_t->i2c_driver->driver.name);
-
-	/* Initialize sub device */
-	v4l2_i2c_subdev_init(&act_ctrl_t->sdev,
-		act_ctrl_t->i2c_client.client,
-		act_ctrl_t->act_v4l2_subdev_ops);
-
-	CDBG("%s succeeded\n", __func__);
-	return rc;
-
-probe_failure:
-	pr_err("%s failed! rc = %d\n", __func__, rc);
-	return rc;
-}
-
-static int32_t msm_actuator_power_up(struct msm_actuator_ctrl_t *a_ctrl)
-{
-	int rc = 0;
-	CDBG("%s called\n", __func__);
-
-	CDBG("vcm info: %x %x\n", a_ctrl->vcm_pwd,
-		a_ctrl->vcm_enable);
-	if (a_ctrl->vcm_enable) {
-		rc = gpio_request(a_ctrl->vcm_pwd, "msm_actuator");
-		if (!rc) {
-			CDBG("Enable VCM PWD\n");
-			gpio_direction_output(a_ctrl->vcm_pwd, 1);
-		}
-	}
-	return rc;
-}
-
-DEFINE_MUTEX(msm_actuator_mutex);
-
-static const struct i2c_device_id msm_actuator_i2c_id[] = {
-	{"msm_actuator", (kernel_ulong_t)&msm_actuator_t},
-	{ }
-};
-
-static struct i2c_driver msm_actuator_i2c_driver = {
-	.id_table = msm_actuator_i2c_id,
-	.probe  = msm_actuator_i2c_probe,
-	.remove = __exit_p(msm_actuator_i2c_remove),
-	.driver = {
-		.name = "msm_actuator",
-	},
-};
-
-static int __init msm_actuator_i2c_add_driver(
-	void)
-{
-	CDBG("%s called\n", __func__);
-	return i2c_add_driver(msm_actuator_t.i2c_driver);
-}
-
-static long msm_actuator_subdev_ioctl(struct v4l2_subdev *sd,
-			unsigned int cmd, void *arg)
-{
-	struct msm_actuator_ctrl_t *a_ctrl = get_actrl(sd);
-	void __user *argp = (void __user *)arg;
-	switch (cmd) {
-	case VIDIOC_MSM_ACTUATOR_CFG:
-		return msm_actuator_config(a_ctrl, argp);
-	default:
-		return -ENOIOCTLCMD;
-	}
-}
-
-static int32_t msm_actuator_power(struct v4l2_subdev *sd, int on)
-{
-	int rc = 0;
-	struct msm_actuator_ctrl_t *a_ctrl = get_actrl(sd);
-	mutex_lock(a_ctrl->actuator_mutex);
-	if (on)
-		rc = msm_actuator_power_up(a_ctrl);
-	else
-		rc = msm_actuator_power_down(a_ctrl);
-	mutex_unlock(a_ctrl->actuator_mutex);
-	return rc;
-}
-
-struct msm_actuator_ctrl_t *get_actrl(struct v4l2_subdev *sd)
-{
-	return container_of(sd, struct msm_actuator_ctrl_t, sdev);
-}
-
-static struct v4l2_subdev_core_ops msm_actuator_subdev_core_ops = {
-	.ioctl = msm_actuator_subdev_ioctl,
-	.s_power = msm_actuator_power,
-};
-
-static struct v4l2_subdev_ops msm_actuator_subdev_ops = {
-	.core = &msm_actuator_subdev_core_ops,
-};
-
-static struct msm_actuator_ctrl_t msm_actuator_t = {
-	.i2c_driver = &msm_actuator_i2c_driver,
-	.act_v4l2_subdev_ops = &msm_actuator_subdev_ops,
-
-	.curr_step_pos = 0,
-	.curr_region_index = 0,
-	.actuator_mutex = &msm_actuator_mutex,
-
-};
-
-static struct msm_actuator msm_vcm_actuator_table = {
-	.act_type = ACTUATOR_VCM,
-	.func_tbl = {
-		.actuator_init_step_table = msm_actuator_init_step_table,
-		.actuator_move_focus = msm_actuator_move_focus,
-		.actuator_write_focus = msm_actuator_write_focus,
-		.actuator_set_default_focus = msm_actuator_set_default_focus,
-		.actuator_init_focus = msm_actuator_init_focus,
-		.actuator_parse_i2c_params = msm_actuator_parse_i2c_params,
-	},
-};
-
-static struct msm_actuator msm_piezo_actuator_table = {
-	.act_type = ACTUATOR_PIEZO,
-	.func_tbl = {
-		.actuator_init_step_table = NULL,
-		.actuator_move_focus = msm_actuator_piezo_move_focus,
-		.actuator_write_focus = NULL,
-		.actuator_set_default_focus =
-			msm_actuator_piezo_set_default_focus,
-		.actuator_init_focus = msm_actuator_init_focus,
-		.actuator_parse_i2c_params = msm_actuator_parse_i2c_params,
-	},
-};
-
-subsys_initcall(msm_actuator_i2c_add_driver);
-MODULE_DESCRIPTION("MSM ACTUATOR");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/actuators/msm_actuator.h b/drivers/media/video/msm/actuators/msm_actuator.h
deleted file mode 100644
index 82157e8..0000000
--- a/drivers/media/video/msm/actuators/msm_actuator.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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 MSM_ACTUATOR_H
-#define MSM_ACTUATOR_H
-
-#include <linux/i2c.h>
-#include <mach/camera.h>
-#include <mach/gpio.h>
-#include <media/v4l2-subdev.h>
-#include <media/msm_camera.h>
-#include "msm_camera_i2c.h"
-
-#ifdef LERROR
-#undef LERROR
-#endif
-
-#ifdef LINFO
-#undef LINFO
-#endif
-
-#define LERROR(fmt, args...) pr_err(fmt, ##args)
-
-#define CONFIG_MSM_CAMERA_ACT_DBG 0
-
-#if CONFIG_MSM_CAMERA_ACT_DBG
-#define LINFO(fmt, args...) printk(fmt, ##args)
-#else
-#define LINFO(fmt, args...) CDBG(fmt, ##args)
-#endif
-
-struct msm_actuator_ctrl_t;
-
-struct msm_actuator_func_tbl {
-	int32_t (*actuator_i2c_write_b_af)(struct msm_actuator_ctrl_t *,
-			uint8_t,
-			uint8_t);
-	int32_t (*actuator_init_step_table)(struct msm_actuator_ctrl_t *,
-		struct msm_actuator_set_info_t *);
-	int32_t (*actuator_init_focus)(struct msm_actuator_ctrl_t *,
-		uint16_t, enum msm_actuator_data_type, struct reg_settings_t *);
-	int32_t (*actuator_set_default_focus) (struct msm_actuator_ctrl_t *,
-			struct msm_actuator_move_params_t *);
-	int32_t (*actuator_move_focus) (struct msm_actuator_ctrl_t *,
-			struct msm_actuator_move_params_t *);
-	int32_t (*actuator_parse_i2c_params)(struct msm_actuator_ctrl_t *,
-			int16_t, uint32_t, uint16_t);
-	int32_t (*actuator_write_focus)(struct msm_actuator_ctrl_t *,
-			uint16_t,
-			struct damping_params_t *,
-			int8_t,
-			int16_t);
-};
-
-struct msm_actuator {
-	enum actuator_type act_type;
-	struct msm_actuator_func_tbl func_tbl;
-};
-
-struct msm_actuator_ctrl_t {
-	struct i2c_driver *i2c_driver;
-	struct msm_camera_i2c_client i2c_client;
-	struct mutex *actuator_mutex;
-	struct msm_actuator_func_tbl *func_tbl;
-	enum msm_actuator_data_type i2c_data_type;
-	struct v4l2_subdev sdev;
-	struct v4l2_subdev_ops *act_v4l2_subdev_ops;
-
-	int16_t curr_step_pos;
-	uint16_t curr_region_index;
-	uint16_t *step_position_table;
-	struct region_params_t region_params[MAX_ACTUATOR_REGION];
-	uint16_t reg_tbl_size;
-	struct msm_actuator_reg_params_t reg_tbl[MAX_ACTUATOR_REG_TBL_SIZE];
-	uint16_t region_size;
-	void *user_data;
-	uint32_t vcm_pwd;
-	uint32_t vcm_enable;
-	uint32_t total_steps;
-	uint16_t pwd_step;
-	uint16_t initial_code;
-	struct msm_camera_i2c_reg_tbl *i2c_reg_tbl;
-	uint16_t i2c_tbl_index;
-};
-
-struct msm_actuator_ctrl_t *get_actrl(struct v4l2_subdev *sd);
-
-#define VIDIOC_MSM_ACTUATOR_CFG \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 11, void __user *)
-
-#endif
diff --git a/drivers/media/video/msm/cci/Makefile b/drivers/media/video/msm/cci/Makefile
deleted file mode 100644
index 195a1b2..0000000
--- a/drivers/media/video/msm/cci/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
-ccflags-y += -Idrivers/media/video/msm -Idrivers/media/video/msm/server
-obj-$(CONFIG_MSM_CCI) += msm_cci.o
diff --git a/drivers/media/video/msm/cci/msm_cam_cci_hwreg.h b/drivers/media/video/msm/cci/msm_cam_cci_hwreg.h
deleted file mode 100644
index 2d489b9..0000000
--- a/drivers/media/video/msm/cci/msm_cam_cci_hwreg.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 __MSM_CAM_CCI_HWREG__
-#define __MSM_CAM_CCI_HWREG__
-
-#define CCI_HW_VERSION_ADDR                                         0x00000000
-#define CCI_RESET_CMD_ADDR                                          0x00000004
-#define CCI_RESET_CMD_RMSK                                          0xcf73f3f7
-#define CCI_M0_RESET_RMSK                                                0x3F1
-#define CCI_M1_RESET_RMSK                                              0x3F001
-#define CCI_QUEUE_START_ADDR                                        0x00000008
-#define CCI_SET_CID_SYNC_TIMER_0_ADDR                               0x00000010
-#define CCI_I2C_M0_SCL_CTL_ADDR                                     0x00000100
-#define CCI_I2C_M0_SDA_CTL_0_ADDR                                   0x00000104
-#define CCI_I2C_M0_SDA_CTL_1_ADDR                                   0x00000108
-#define CCI_I2C_M0_SDA_CTL_2_ADDR                                   0x0000010c
-#define CCI_I2C_M0_READ_DATA_ADDR                                   0x00000118
-#define CCI_I2C_M0_MISC_CTL_ADDR                                    0x00000110
-#define CCI_I2C_M0_READ_BUF_LEVEL_ADDR                              0x0000011C
-#define CCI_HALT_REQ_ADDR                                           0x00000034
-#define CCI_M0_HALT_REQ_RMSK                                               0x1
-#define CCI_M1_HALT_REQ_RMSK                                              0x01
-#define CCI_HALT_REQ_ADDR                                           0x00000034
-#define CCI_I2C_M1_SCL_CTL_ADDR                                     0x00000200
-#define CCI_I2C_M1_SDA_CTL_0_ADDR                                   0x00000204
-#define CCI_I2C_M1_SDA_CTL_1_ADDR                                   0x00000208
-#define CCI_I2C_M1_SDA_CTL_2_ADDR                                   0x0000020c
-#define CCI_I2C_M1_MISC_CTL_ADDR                                    0x00000210
-#define CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR                             0x00000304
-#define CCI_I2C_M0_Q0_CUR_CMD_ADDR                                  0x00000308
-#define CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR                            0x00000300
-#define CCI_I2C_M0_Q0_LOAD_DATA_ADDR                                0x00000310
-#define CCI_IRQ_MASK_0_ADDR                                         0x00000c04
-#define CCI_IRQ_CLEAR_0_ADDR                                        0x00000c08
-#define CCI_IRQ_STATUS_0_ADDR                                       0x00000c0c
-#define CCI_IRQ_STATUS_0_I2C_M1_Q1_NACK_ERR_BMSK                    0x40000000
-#define CCI_IRQ_STATUS_0_I2C_M1_Q0_NACK_ERR_BMSK                    0x20000000
-#define CCI_IRQ_STATUS_0_I2C_M0_Q1_NACK_ERR_BMSK                    0x10000000
-#define CCI_IRQ_STATUS_0_I2C_M0_Q0_NACK_ERR_BMSK                     0x8000000
-#define CCI_IRQ_STATUS_0_I2C_M1_Q0Q1_HALT_ACK_BMSK                   0x4000000
-#define CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK_BMSK                   0x2000000
-#define CCI_IRQ_STATUS_0_RST_DONE_ACK_BMSK                           0x1000000
-#define CCI_IRQ_STATUS_0_I2C_M1_Q1_REPORT_BMSK                        0x100000
-#define CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT_BMSK                         0x10000
-#define CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK                            0x1000
-#define CCI_IRQ_STATUS_0_I2C_M0_Q1_REPORT_BMSK                           0x100
-#define CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK                            0x10
-#define CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK                               0x1
-#define CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR                               0x00000c00
-#endif /* __MSM_CAM_CCI_HWREG__ */
diff --git a/drivers/media/video/msm/cci/msm_cci.c b/drivers/media/video/msm/cci/msm_cci.c
deleted file mode 100644
index 09dfd7c..0000000
--- a/drivers/media/video/msm/cci/msm_cci.c
+++ /dev/null
@@ -1,769 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/delay.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <mach/board.h>
-#include <mach/camera.h>
-#include <media/msm_isp.h>
-#include "msm_cci.h"
-#include "msm.h"
-#include "msm_cam_server.h"
-#include "msm_cam_cci_hwreg.h"
-
-#define V4L2_IDENT_CCI 50005
-#define CCI_I2C_QUEUE_0_SIZE 64
-#define CCI_I2C_QUEUE_1_SIZE 16
-
-#define CCI_TIMEOUT msecs_to_jiffies(100)
-
-static void msm_cci_set_clk_param(struct cci_device *cci_dev)
-{
-	uint16_t THIGH = 78;
-	uint16_t TLOW = 114;
-	uint16_t TSUSTO = 28;
-	uint16_t TSUSTA = 28;
-	uint16_t THDDAT = 10;
-	uint16_t THDSTA = 77;
-	uint16_t TBUF = 118;
-	uint8_t HW_SCL_STRETCH_EN = 0; /*enable or disable SCL clock
-					* stretching */
-	uint8_t HW_RDHLD = 6; /* internal hold time 1-6 cycles of SDA to bridge
-			       * undefined falling SCL region */
-	uint8_t HW_TSP = 1; /* glitch filter 1-3 cycles */
-
-	msm_camera_io_w(THIGH << 16 | TLOW, cci_dev->base +
-		CCI_I2C_M0_SCL_CTL_ADDR);
-	msm_camera_io_w(TSUSTO << 16 | TSUSTA, cci_dev->base +
-		CCI_I2C_M0_SDA_CTL_0_ADDR);
-	msm_camera_io_w(THDDAT << 16 | THDSTA, cci_dev->base +
-		CCI_I2C_M0_SDA_CTL_1_ADDR);
-	msm_camera_io_w(TBUF, cci_dev->base +
-		CCI_I2C_M0_SDA_CTL_2_ADDR);
-	msm_camera_io_w(HW_SCL_STRETCH_EN << 8 | HW_RDHLD << 4 | HW_TSP,
-		cci_dev->base + CCI_I2C_M0_MISC_CTL_ADDR);
-	msm_camera_io_w(THIGH << 16 | TLOW, cci_dev->base +
-		CCI_I2C_M1_SCL_CTL_ADDR);
-	msm_camera_io_w(TSUSTO << 16 | TSUSTA, cci_dev->base +
-		CCI_I2C_M1_SDA_CTL_0_ADDR);
-	msm_camera_io_w(THDDAT << 16 | THDSTA, cci_dev->base +
-		CCI_I2C_M1_SDA_CTL_1_ADDR);
-	msm_camera_io_w(TBUF, cci_dev->base + CCI_I2C_M1_SDA_CTL_2_ADDR);
-	msm_camera_io_w(HW_SCL_STRETCH_EN << 8 | HW_RDHLD << 4 | HW_TSP,
-		cci_dev->base + CCI_I2C_M1_MISC_CTL_ADDR);
-}
-
-static int32_t msm_cci_i2c_config_sync_timer(struct v4l2_subdev *sd,
-	struct msm_camera_cci_ctrl *c_ctrl)
-{
-	struct cci_device *cci_dev;
-	cci_dev = v4l2_get_subdevdata(sd);
-	msm_camera_io_w(c_ctrl->cci_info->cid, cci_dev->base +
-		CCI_SET_CID_SYNC_TIMER_0_ADDR + (c_ctrl->cci_info->cid * 0x4));
-	return 0;
-}
-
-static int32_t msm_cci_i2c_set_freq(struct v4l2_subdev *sd,
-	struct msm_camera_cci_ctrl *c_ctrl)
-{
-	struct cci_device *cci_dev;
-	uint32_t val;
-	cci_dev = v4l2_get_subdevdata(sd);
-	val = c_ctrl->cci_info->freq;
-	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SCL_CTL_ADDR +
-		c_ctrl->cci_info->cci_i2c_master*0x100);
-	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SDA_CTL_0_ADDR +
-		c_ctrl->cci_info->cci_i2c_master*0x100);
-	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SDA_CTL_1_ADDR +
-		c_ctrl->cci_info->cci_i2c_master*0x100);
-	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SDA_CTL_2_ADDR +
-		c_ctrl->cci_info->cci_i2c_master*0x100);
-	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_MISC_CTL_ADDR +
-		c_ctrl->cci_info->cci_i2c_master*0x100);
-	return 0;
-}
-
-static int32_t msm_cci_validate_queue(struct cci_device *cci_dev,
-	uint32_t len,
-	enum cci_i2c_master_t master,
-	enum cci_i2c_queue_t queue)
-{
-	int32_t rc = 0;
-	uint32_t read_val = 0;
-	uint32_t reg_offset = master * 0x200 + queue * 0x100;
-	read_val = msm_camera_io_r(cci_dev->base +
-		CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR + reg_offset);
-	CDBG("%s line %d CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR %d len %d max %d\n",
-		__func__, __LINE__, read_val, len,
-		cci_dev->cci_i2c_queue_info[master][queue].max_queue_size);
-	if ((read_val + len + 1) > cci_dev->
-		cci_i2c_queue_info[master][queue].max_queue_size) {
-		uint32_t reg_val = 0;
-		uint32_t report_val = CCI_I2C_REPORT_CMD | (1 << 8);
-		CDBG("%s:%d CCI_I2C_REPORT_CMD\n", __func__, __LINE__);
-		msm_camera_io_w(report_val,
-			cci_dev->base + CCI_I2C_M0_Q0_LOAD_DATA_ADDR +
-			reg_offset);
-		read_val++;
-		CDBG("%s:%d CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR %d\n",
-			__func__, __LINE__, read_val);
-		msm_camera_io_w(read_val, cci_dev->base +
-			CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR + reg_offset);
-		reg_val = 1 << ((master * 2) + queue);
-		CDBG("%s:%d CCI_QUEUE_START_ADDR\n", __func__, __LINE__);
-		msm_camera_io_w(reg_val, cci_dev->base + CCI_QUEUE_START_ADDR);
-		CDBG("%s line %d wait_for_completion_interruptible\n",
-			__func__, __LINE__);
-		wait_for_completion_interruptible_timeout(&cci_dev->
-			cci_master_info[master].reset_complete, CCI_TIMEOUT);
-
-		rc = cci_dev->cci_master_info[master].status;
-		if (rc < 0)
-			pr_err("%s failed rc %d\n", __func__, rc);
-	}
-	return rc;
-}
-
-static int32_t msm_cci_data_queue(struct cci_device *cci_dev,
-	struct msm_camera_cci_ctrl *c_ctrl, enum cci_i2c_queue_t queue)
-{
-	uint16_t i = 0, j = 0, k = 0, h = 0, len = 0;
-	uint32_t cmd = 0;
-	uint8_t data[10];
-	uint16_t reg_addr = 0;
-	struct msm_camera_cci_i2c_write_cfg *i2c_msg =
-		&c_ctrl->cfg.cci_i2c_write_cfg;
-	uint16_t cmd_size = i2c_msg->size;
-	struct msm_camera_i2c_reg_conf *i2c_cmd = i2c_msg->reg_conf_tbl;
-	enum cci_i2c_master_t master = c_ctrl->cci_info->cci_i2c_master;
-	CDBG("%s addr type %d data type %d\n", __func__,
-		i2c_msg->addr_type, i2c_msg->data_type);
-	/* assume total size within the max queue */
-	while (cmd_size) {
-		CDBG("%s cmd_size %d addr 0x%x data 0x%x", __func__,
-			cmd_size, i2c_cmd->reg_addr, i2c_cmd->reg_data);
-		data[i++] = CCI_I2C_WRITE_CMD;
-		if (i2c_cmd->reg_addr)
-			reg_addr = i2c_cmd->reg_addr;
-		/* either byte or word addr */
-		if (i2c_msg->addr_type == MSM_CAMERA_I2C_BYTE_ADDR)
-			data[i++] = reg_addr;
-		else {
-			data[i++] = (reg_addr & 0xFF00) >> 8;
-			data[i++] = reg_addr & 0x00FF;
-		}
-		/* max of 10 data bytes */
-		do {
-			if (i2c_msg->data_type == MSM_CAMERA_I2C_BYTE_DATA) {
-				data[i++] = i2c_cmd->reg_data;
-				reg_addr++;
-			} else {
-				if ((i + 1) <= 10) {
-					data[i++] = (i2c_cmd->reg_data &
-						0xFF00) >> 8; /* MSB */
-					data[i++] = i2c_cmd->reg_data &
-						0x00FF; /* LSB */
-					reg_addr += 2;
-				} else
-					break;
-			}
-			i2c_cmd++;
-		} while (--cmd_size && !i2c_cmd->reg_addr && (i <= 10));
-		data[0] |= ((i-1) << 4);
-		len = ((i-1)/4) + 1;
-		msm_cci_validate_queue(cci_dev, len, master, queue);
-		for (h = 0, k = 0; h < len; h++) {
-			cmd = 0;
-			for (j = 0; (j < 4 && k < i); j++)
-				cmd |= (data[k++] << (j * 8));
-			CDBG("%s CCI_I2C_M0_Q0_LOAD_DATA_ADDR 0x%x\n",
-				__func__, cmd);
-			msm_camera_io_w(cmd, cci_dev->base +
-				CCI_I2C_M0_Q0_LOAD_DATA_ADDR +
-				master * 0x200 + queue * 0x100);
-		}
-		i = 0;
-	}
-	return 0;
-}
-
-static int32_t msm_cci_write_i2c_queue(struct cci_device *cci_dev,
-	uint32_t val,
-	enum cci_i2c_master_t master,
-	enum cci_i2c_queue_t queue)
-{
-	int32_t rc = 0;
-	uint32_t reg_offset = master * 0x200 + queue * 0x100;
-	CDBG("%s:%d called\n", __func__, __LINE__);
-	msm_cci_validate_queue(cci_dev, 1, master, queue);
-	CDBG("%s CCI_I2C_M0_Q0_LOAD_DATA_ADDR:val %x:%x\n",
-		__func__, CCI_I2C_M0_Q0_LOAD_DATA_ADDR +
-		reg_offset, val);
-	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_Q0_LOAD_DATA_ADDR +
-		reg_offset);
-	return rc;
-}
-
-static int32_t msm_cci_i2c_read(struct v4l2_subdev *sd,
-	struct msm_camera_cci_ctrl *c_ctrl)
-{
-	uint32_t rc = 0;
-	uint32_t val = 0;
-	int32_t read_words = 0, exp_words = 0;
-	int32_t index = 0, first_byte = 0;
-	uint32_t i = 0;
-	enum cci_i2c_master_t master;
-	enum cci_i2c_queue_t queue = QUEUE_1;
-	struct cci_device *cci_dev = NULL;
-	struct msm_camera_cci_i2c_read_cfg *read_cfg = NULL;
-	CDBG("%s line %d\n", __func__, __LINE__);
-	cci_dev = v4l2_get_subdevdata(sd);
-	master = c_ctrl->cci_info->cci_i2c_master;
-	read_cfg = &c_ctrl->cfg.cci_i2c_read_cfg;
-	mutex_lock(&cci_dev->cci_master_info[master].mutex);
-	CDBG("%s master %d, queue %d\n", __func__, master, queue);
-	CDBG("%s set param sid 0x%x retries %d id_map %d\n", __func__,
-		c_ctrl->cci_info->sid, c_ctrl->cci_info->retries,
-		c_ctrl->cci_info->id_map);
-	val = CCI_I2C_SET_PARAM_CMD | c_ctrl->cci_info->sid << 4 |
-		c_ctrl->cci_info->retries << 16 |
-		c_ctrl->cci_info->id_map << 18;
-	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
-	if (rc < 0) {
-		CDBG("%s failed line %d\n", __func__, __LINE__);
-		goto ERROR;
-	}
-
-	val = CCI_I2C_LOCK_CMD;
-	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
-	if (rc < 0) {
-		CDBG("%s failed line %d\n", __func__, __LINE__);
-		goto ERROR;
-	}
-
-	if (read_cfg->addr_type == MSM_CAMERA_I2C_BYTE_ADDR)
-		val = CCI_I2C_WRITE_CMD | (read_cfg->addr_type << 4) |
-			((read_cfg->addr & 0xFF) << 8);
-	if (read_cfg->addr_type == MSM_CAMERA_I2C_WORD_ADDR)
-		val = CCI_I2C_WRITE_CMD | (read_cfg->addr_type << 4) |
-			(((read_cfg->addr & 0xFF00) >> 8) << 8) |
-			((read_cfg->addr & 0xFF) << 16);
-	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
-	if (rc < 0) {
-		CDBG("%s failed line %d\n", __func__, __LINE__);
-		goto ERROR;
-	}
-
-	val = CCI_I2C_READ_CMD | (read_cfg->num_byte << 4);
-	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
-	if (rc < 0) {
-		CDBG("%s failed line %d\n", __func__, __LINE__);
-		goto ERROR;
-	}
-
-	val = CCI_I2C_UNLOCK_CMD;
-	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
-	if (rc < 0) {
-		CDBG("%s failed line %d\n", __func__, __LINE__);
-		goto ERROR;
-	}
-
-	val = msm_camera_io_r(cci_dev->base + CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR +
-		master * 0x200 + queue * 0x100);
-	CDBG("%s cur word cnt %x\n", __func__, val);
-	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR +
-		master * 0x200 + queue * 0x100);
-
-	val = 1 << ((master * 2) + queue);
-	msm_camera_io_w(val, cci_dev->base + CCI_QUEUE_START_ADDR);
-	wait_for_completion_interruptible_timeout(&cci_dev->
-		cci_master_info[master].reset_complete, CCI_TIMEOUT);
-
-	read_words = msm_camera_io_r(cci_dev->base +
-		CCI_I2C_M0_READ_BUF_LEVEL_ADDR + master * 0x100);
-	exp_words = ((read_cfg->num_byte / 4) + 1);
-	if (read_words != exp_words) {
-		pr_err("%s:%d read_words = %d, exp words = %d\n", __func__,
-			__LINE__, read_words, exp_words);
-		memset(read_cfg->data, 0, read_cfg->num_byte);
-		goto ERROR;
-	}
-	index = 0;
-	CDBG("%s index %d num_type %d\n", __func__, index,
-		read_cfg->num_byte);
-	first_byte = 0;
-	do {
-		val = msm_camera_io_r(cci_dev->base +
-			CCI_I2C_M0_READ_DATA_ADDR + master * 0x100);
-		CDBG("%s read val %x\n", __func__, val);
-		for (i = 0; (i < 4) && (index < read_cfg->num_byte); i++) {
-			CDBG("%s i %d index %d\n", __func__, i, index);
-			if (!first_byte) {
-				CDBG("%s sid %x\n", __func__, val & 0xFF);
-				first_byte++;
-			} else {
-				read_cfg->data[index] =
-					(val  >> (i * 8)) & 0xFF;
-				CDBG("%s data[%d] %x\n", __func__, index,
-					read_cfg->data[index]);
-				index++;
-			}
-		}
-	} while (--read_words > 0);
-ERROR:
-	mutex_unlock(&cci_dev->cci_master_info[master].mutex);
-	return rc;
-}
-
-static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd,
-	struct msm_camera_cci_ctrl *c_ctrl)
-{
-	int32_t rc = 0;
-	struct cci_device *cci_dev;
-	uint32_t val;
-	enum cci_i2c_master_t master;
-	enum cci_i2c_queue_t queue = QUEUE_0;
-	cci_dev = v4l2_get_subdevdata(sd);
-	master = c_ctrl->cci_info->cci_i2c_master;
-	CDBG("%s master %d, queue %d\n", __func__, master, queue);
-	CDBG("%s set param sid 0x%x retries %d id_map %d\n", __func__,
-		c_ctrl->cci_info->sid, c_ctrl->cci_info->retries,
-		c_ctrl->cci_info->id_map);
-	mutex_lock(&cci_dev->cci_master_info[master].mutex);
-	val = CCI_I2C_SET_PARAM_CMD | c_ctrl->cci_info->sid << 4 |
-		c_ctrl->cci_info->retries << 16 |
-		c_ctrl->cci_info->id_map << 18;
-	CDBG("%s:%d CCI_I2C_SET_PARAM_CMD\n", __func__, __LINE__);
-	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
-	if (rc < 0) {
-		CDBG("%s failed line %d\n", __func__, __LINE__);
-		goto ERROR;
-	}
-
-	val = CCI_I2C_LOCK_CMD;
-	CDBG("%s:%d CCI_I2C_LOCK_CMD\n", __func__, __LINE__);
-	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
-	if (rc < 0) {
-		CDBG("%s failed line %d\n", __func__, __LINE__);
-		goto ERROR;
-	}
-
-	msm_cci_data_queue(cci_dev, c_ctrl, queue);
-	val = CCI_I2C_UNLOCK_CMD;
-	CDBG("%s:%d CCI_I2C_UNLOCK_CMD\n", __func__, __LINE__);
-	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
-	if (rc < 0) {
-		CDBG("%s failed line %d\n", __func__, __LINE__);
-		goto ERROR;
-	}
-
-	val = CCI_I2C_REPORT_CMD | (1 << 8);
-	CDBG("%s:%d CCI_I2C_REPORT_CMD\n", __func__, __LINE__);
-	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
-	if (rc < 0) {
-		CDBG("%s failed line %d\n", __func__, __LINE__);
-		goto ERROR;
-	}
-
-	val = msm_camera_io_r(cci_dev->base + CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR +
-		master * 0x200 + queue * 0x100);
-	CDBG("%s:%d cur word count %d\n", __func__, __LINE__, val);
-	CDBG("%s:%d CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR\n", __func__, __LINE__);
-	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR +
-		master * 0x200 + queue * 0x100);
-
-	val = 1 << ((master * 2) + queue);
-	CDBG("%s:%d CCI_QUEUE_START_ADDR\n", __func__, __LINE__);
-	msm_camera_io_w(val, cci_dev->base + CCI_QUEUE_START_ADDR +
-		master*0x200 + queue * 0x100);
-
-	CDBG("%s line %d wait_for_completion_interruptible\n",
-		__func__, __LINE__);
-	wait_for_completion_interruptible_timeout(&cci_dev->
-		cci_master_info[master].reset_complete, CCI_TIMEOUT);
-
-ERROR:
-	mutex_unlock(&cci_dev->cci_master_info[master].mutex);
-	return rc;
-}
-
-static int msm_cci_subdev_g_chip_ident(struct v4l2_subdev *sd,
-			struct v4l2_dbg_chip_ident *chip)
-{
-	BUG_ON(!chip);
-	chip->ident = V4L2_IDENT_CCI;
-	chip->revision = 0;
-	return 0;
-}
-
-static struct msm_cam_clk_info cci_clk_info[] = {
-	{"camss_top_ahb_clk", -1},
-	{"cci_src_clk", 19200000},
-	{"cci_ahb_clk", -1},
-	{"cci_clk", -1},
-};
-
-static int32_t msm_cci_init(struct v4l2_subdev *sd)
-{
-	int rc = 0;
-	struct cci_device *cci_dev;
-	cci_dev = v4l2_get_subdevdata(sd);
-	CDBG("%s line %d\n", __func__, __LINE__);
-	if (cci_dev == NULL) {
-		rc = -ENOMEM;
-		return rc;
-	}
-	rc = msm_cam_clk_enable(&cci_dev->pdev->dev, cci_clk_info,
-		cci_dev->cci_clk, ARRAY_SIZE(cci_clk_info), 1);
-	if (rc < 0) {
-		CDBG("%s: clk enable failed\n", __func__);
-		goto clk_enable_failed;
-	}
-
-	enable_irq(cci_dev->irq->start);
-	cci_dev->hw_version = msm_camera_io_r(cci_dev->base +
-		CCI_HW_VERSION_ADDR);
-	cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE;
-	msm_camera_io_w(0xFFFFFFFF, cci_dev->base + CCI_RESET_CMD_ADDR);
-	msm_camera_io_w(0x1, cci_dev->base + CCI_RESET_CMD_ADDR);
-	wait_for_completion_interruptible_timeout(
-		&cci_dev->cci_master_info[MASTER_0].reset_complete,
-		CCI_TIMEOUT);
-	msm_cci_set_clk_param(cci_dev);
-	msm_camera_io_w(0xFFFFFFFF, cci_dev->base + CCI_IRQ_MASK_0_ADDR);
-	msm_camera_io_w(0xFFFFFFFF, cci_dev->base + CCI_IRQ_CLEAR_0_ADDR);
-	msm_camera_io_w(0x1, cci_dev->base + CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR);
-	msm_camera_io_w(0x0, cci_dev->base + CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR);
-	msm_camera_io_w(0x0, cci_dev->base + CCI_IRQ_CLEAR_0_ADDR);
-	return 0;
-
-clk_enable_failed:
-	return rc;
-}
-
-static int32_t msm_cci_release(struct v4l2_subdev *sd)
-{
-	struct cci_device *cci_dev;
-	cci_dev = v4l2_get_subdevdata(sd);
-
-	disable_irq(cci_dev->irq->start);
-
-	msm_cam_clk_enable(&cci_dev->pdev->dev, cci_clk_info,
-		cci_dev->cci_clk, ARRAY_SIZE(cci_clk_info), 0);
-
-	return 0;
-}
-
-static int32_t msm_cci_config(struct v4l2_subdev *sd,
-	struct msm_camera_cci_ctrl *cci_ctrl)
-{
-	int32_t rc = 0;
-	CDBG("%s line %d cmd %d\n", __func__, __LINE__,
-		cci_ctrl->cmd);
-	switch (cci_ctrl->cmd) {
-	case MSM_CCI_INIT:
-		rc = msm_cci_init(sd);
-		break;
-	case MSM_CCI_RELEASE:
-		rc = msm_cci_release(sd);
-		break;
-	case MSM_CCI_SET_SID:
-		break;
-	case MSM_CCI_SET_FREQ:
-		rc = msm_cci_i2c_set_freq(sd, cci_ctrl);
-		break;
-	case MSM_CCI_SET_SYNC_CID:
-		rc = msm_cci_i2c_config_sync_timer(sd, cci_ctrl);
-		break;
-	case MSM_CCI_I2C_READ:
-		rc = msm_cci_i2c_read(sd, cci_ctrl);
-		break;
-	case MSM_CCI_I2C_WRITE:
-		rc = msm_cci_i2c_write(sd, cci_ctrl);
-		break;
-	case MSM_CCI_GPIO_WRITE:
-		break;
-	default:
-		rc = -ENOIOCTLCMD;
-	}
-	CDBG("%s line %d rc %d\n", __func__, __LINE__, rc);
-	cci_ctrl->status = rc;
-	return rc;
-}
-
-static irqreturn_t msm_cci_irq(int irq_num, void *data)
-{
-	uint32_t irq;
-	struct cci_device *cci_dev = data;
-	irq = msm_camera_io_r(cci_dev->base + CCI_IRQ_STATUS_0_ADDR);
-	msm_camera_io_w(irq, cci_dev->base + CCI_IRQ_CLEAR_0_ADDR);
-	msm_camera_io_w(0x1, cci_dev->base + CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR);
-	msm_camera_io_w(0x0, cci_dev->base + CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR);
-	CDBG("%s CCI_I2C_M0_STATUS_ADDR = 0x%x\n", __func__, irq);
-	if (irq & CCI_IRQ_STATUS_0_RST_DONE_ACK_BMSK) {
-		if (cci_dev->cci_master_info[MASTER_0].reset_pending == TRUE) {
-			cci_dev->cci_master_info[MASTER_0].reset_pending =
-				FALSE;
-			complete(&cci_dev->cci_master_info[MASTER_0].
-				reset_complete);
-		}
-		if (cci_dev->cci_master_info[MASTER_1].reset_pending == TRUE) {
-			cci_dev->cci_master_info[MASTER_1].reset_pending =
-				FALSE;
-			complete(&cci_dev->cci_master_info[MASTER_1].
-				reset_complete);
-		}
-	} else if ((irq & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK) ||
-		(irq & CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK) ||
-		(irq & CCI_IRQ_STATUS_0_I2C_M0_Q1_REPORT_BMSK)) {
-		cci_dev->cci_master_info[MASTER_0].status = 0;
-		complete(&cci_dev->cci_master_info[MASTER_0].reset_complete);
-	} else if ((irq & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) ||
-		(irq & CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT_BMSK) ||
-		(irq & CCI_IRQ_STATUS_0_I2C_M1_Q1_REPORT_BMSK)) {
-		cci_dev->cci_master_info[MASTER_1].status = 0;
-		complete(&cci_dev->cci_master_info[MASTER_1].reset_complete);
-	} else if ((irq & CCI_IRQ_STATUS_0_I2C_M0_Q0_NACK_ERR_BMSK) ||
-		(irq & CCI_IRQ_STATUS_0_I2C_M0_Q1_NACK_ERR_BMSK)) {
-		cci_dev->cci_master_info[MASTER_0].status = -EINVAL;
-		msm_camera_io_w(CCI_M0_HALT_REQ_RMSK,
-			cci_dev->base + CCI_HALT_REQ_ADDR);
-	} else if ((irq & CCI_IRQ_STATUS_0_I2C_M1_Q0_NACK_ERR_BMSK) ||
-		(irq & CCI_IRQ_STATUS_0_I2C_M1_Q1_NACK_ERR_BMSK)) {
-		cci_dev->cci_master_info[MASTER_1].status = -EINVAL;
-		msm_camera_io_w(CCI_M1_HALT_REQ_RMSK,
-			cci_dev->base + CCI_HALT_REQ_ADDR);
-	} else if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK_BMSK) {
-		cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE;
-		msm_camera_io_w(CCI_M0_RESET_RMSK,
-			cci_dev->base + CCI_RESET_CMD_ADDR);
-	} else if (irq & CCI_IRQ_STATUS_0_I2C_M1_Q0Q1_HALT_ACK_BMSK) {
-		cci_dev->cci_master_info[MASTER_1].reset_pending = TRUE;
-		msm_camera_io_w(CCI_M1_RESET_RMSK,
-			cci_dev->base + CCI_RESET_CMD_ADDR);
-	} else {
-		pr_err("%s unhandled irq 0x%x\n", __func__, irq);
-		cci_dev->cci_master_info[MASTER_0].status = 0;
-		complete(&cci_dev->cci_master_info[MASTER_0].reset_complete);
-		cci_dev->cci_master_info[MASTER_1].status = 0;
-		complete(&cci_dev->cci_master_info[MASTER_1].reset_complete);
-	}
-	return IRQ_HANDLED;
-}
-
-int msm_cci_irq_routine(struct v4l2_subdev *sd, u32 status, bool *handled)
-{
-	struct cci_device *cci_dev = v4l2_get_subdevdata(sd);
-	irqreturn_t ret;
-	CDBG("%s line %d\n", __func__, __LINE__);
-	ret = msm_cci_irq(cci_dev->irq->start, cci_dev);
-	*handled = TRUE;
-	return 0;
-}
-
-static long msm_cci_subdev_ioctl(struct v4l2_subdev *sd,
-	unsigned int cmd, void *arg)
-{
-	int32_t rc = 0;
-	CDBG("%s line %d\n", __func__, __LINE__);
-	switch (cmd) {
-	case VIDIOC_MSM_CCI_CFG:
-		rc = msm_cci_config(sd, arg);
-		break;
-	default:
-		rc = -ENOIOCTLCMD;
-	}
-	CDBG("%s line %d rc %d\n", __func__, __LINE__, rc);
-	return rc;
-}
-
-static struct v4l2_subdev_core_ops msm_cci_subdev_core_ops = {
-	.g_chip_ident = &msm_cci_subdev_g_chip_ident,
-	.ioctl = &msm_cci_subdev_ioctl,
-	.interrupt_service_routine = msm_cci_irq_routine,
-};
-
-static const struct v4l2_subdev_ops msm_cci_subdev_ops = {
-	.core = &msm_cci_subdev_core_ops,
-};
-
-static const struct v4l2_subdev_internal_ops msm_cci_internal_ops;
-
-static void msm_cci_initialize_cci_params(struct cci_device *new_cci_dev)
-{
-	uint8_t i = 0, j = 0;
-	for (i = 0; i < NUM_MASTERS; i++) {
-		new_cci_dev->cci_master_info[i].status = 0;
-		mutex_init(&new_cci_dev->cci_master_info[i].mutex);
-		init_completion(&new_cci_dev->
-			cci_master_info[i].reset_complete);
-		for (j = 0; j < NUM_QUEUES; j++) {
-			if (j == QUEUE_0)
-				new_cci_dev->cci_i2c_queue_info[i][j].
-					max_queue_size = CCI_I2C_QUEUE_0_SIZE;
-			else
-				new_cci_dev->cci_i2c_queue_info[i][j].
-					max_queue_size = CCI_I2C_QUEUE_1_SIZE;
-			}
-	}
-	return;
-}
-
-static int __devinit msm_cci_probe(struct platform_device *pdev)
-{
-	struct cci_device *new_cci_dev;
-	int rc = 0;
-	struct msm_cam_subdev_info sd_info;
-	struct intr_table_entry irq_req;
-	CDBG("%s: pdev %p device id = %d\n", __func__, pdev, pdev->id);
-	new_cci_dev = kzalloc(sizeof(struct cci_device), GFP_KERNEL);
-	if (!new_cci_dev) {
-		CDBG("%s: no enough memory\n", __func__);
-		return -ENOMEM;
-	}
-	v4l2_subdev_init(&new_cci_dev->subdev, &msm_cci_subdev_ops);
-	new_cci_dev->subdev.internal_ops = &msm_cci_internal_ops;
-	new_cci_dev->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-	snprintf(new_cci_dev->subdev.name,
-			ARRAY_SIZE(new_cci_dev->subdev.name), "msm_cci");
-	v4l2_set_subdevdata(&new_cci_dev->subdev, new_cci_dev);
-	platform_set_drvdata(pdev, &new_cci_dev->subdev);
-	CDBG("%s sd %p\n", __func__, &new_cci_dev->subdev);
-	if (pdev->dev.of_node)
-		of_property_read_u32((&pdev->dev)->of_node,
-			"cell-index", &pdev->id);
-
-	new_cci_dev->mem = platform_get_resource_byname(pdev,
-					IORESOURCE_MEM, "cci");
-	if (!new_cci_dev->mem) {
-		CDBG("%s: no mem resource?\n", __func__);
-		rc = -ENODEV;
-		goto cci_no_resource;
-	}
-	new_cci_dev->irq = platform_get_resource_byname(pdev,
-					IORESOURCE_IRQ, "cci");
-	CDBG("%s line %d cci irq start %d end %d\n", __func__,
-		__LINE__,
-		new_cci_dev->irq->start,
-		new_cci_dev->irq->end);
-	if (!new_cci_dev->irq) {
-		CDBG("%s: no irq resource?\n", __func__);
-		rc = -ENODEV;
-		goto cci_no_resource;
-	}
-	new_cci_dev->io = request_mem_region(new_cci_dev->mem->start,
-		resource_size(new_cci_dev->mem), pdev->name);
-	if (!new_cci_dev->io) {
-		CDBG("%s: no valid mem region\n", __func__);
-		rc = -EBUSY;
-		goto cci_no_resource;
-	}
-
-	new_cci_dev->base = ioremap(new_cci_dev->mem->start,
-		resource_size(new_cci_dev->mem));
-	if (!new_cci_dev->base) {
-		rc = -ENOMEM;
-		goto cci_release_mem;
-	}
-
-	sd_info.sdev_type = CCI_DEV;
-	sd_info.sd_index = pdev->id;
-	sd_info.irq_num = new_cci_dev->irq->start;
-	msm_cam_register_subdev_node(&new_cci_dev->subdev, &sd_info);
-
-	irq_req.cam_hw_idx       = MSM_CAM_HW_CCI;
-	irq_req.dev_name         = "msm_cci";
-	irq_req.irq_idx          = CAMERA_SS_IRQ_1;
-	irq_req.irq_num          = new_cci_dev->irq->start;
-	irq_req.is_composite     = 0;
-	irq_req.irq_trigger_type = IRQF_TRIGGER_RISING;
-	irq_req.num_hwcore       = 1;
-	irq_req.subdev_list[0]   = &new_cci_dev->subdev;
-	irq_req.data             = (void *)new_cci_dev;
-	rc = msm_cam_server_request_irq(&irq_req);
-	if (rc == -ENXIO) {
-		/* IRQ Router hardware is not present on this hardware.
-		 * Request for the IRQ and register the interrupt handler. */
-		rc = request_irq(new_cci_dev->irq->start, msm_cci_irq,
-			IRQF_TRIGGER_RISING, "cci", new_cci_dev);
-		if (rc < 0) {
-			CDBG("%s: irq request fail\n", __func__);
-			rc = -EBUSY;
-			goto cci_release_mem;
-		}
-		disable_irq(new_cci_dev->irq->start);
-	} else if (rc < 0) {
-		CDBG("%s Error registering irq ", __func__);
-		rc = -EBUSY;
-		goto cci_release_mem;
-	}
-
-	new_cci_dev->pdev = pdev;
-	msm_cci_initialize_cci_params(new_cci_dev);
-	rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
-	if (rc)
-		pr_err("%s: failed to add child nodes, rc=%d\n", __func__, rc);
-	CDBG("%s line %d\n", __func__, __LINE__);
-	return 0;
-
-cci_release_mem:
-	release_mem_region(new_cci_dev->mem->start,
-		resource_size(new_cci_dev->mem));
-cci_no_resource:
-	kfree(new_cci_dev);
-	return 0;
-}
-
-static int __exit msm_cci_exit(struct platform_device *pdev)
-{
-	struct v4l2_subdev *subdev = platform_get_drvdata(pdev);
-	struct cci_device *cci_dev =
-		v4l2_get_subdevdata(subdev);
-	release_mem_region(cci_dev->mem->start, resource_size(cci_dev->mem));
-	kfree(cci_dev);
-	return 0;
-}
-
-static const struct of_device_id msm_cci_dt_match[] = {
-	{.compatible = "qcom,cci"},
-	{}
-};
-
-MODULE_DEVICE_TABLE(of, msm_cci_dt_match);
-
-static struct platform_driver cci_driver = {
-	.probe = msm_cci_probe,
-	.remove = msm_cci_exit,
-	.driver = {
-		.name = MSM_CCI_DRV_NAME,
-		.owner = THIS_MODULE,
-		.of_match_table = msm_cci_dt_match,
-	},
-};
-
-static int __init msm_cci_init_module(void)
-{
-	return platform_driver_register(&cci_driver);
-}
-
-static void __exit msm_cci_exit_module(void)
-{
-	platform_driver_unregister(&cci_driver);
-}
-
-module_init(msm_cci_init_module);
-module_exit(msm_cci_exit_module);
-MODULE_DESCRIPTION("MSM CCI driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/cci/msm_cci.h b/drivers/media/video/msm/cci/msm_cci.h
deleted file mode 100644
index 6955576..0000000
--- a/drivers/media/video/msm/cci/msm_cci.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 MSM_CCI_H
-#define MSM_CCI_H
-
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <media/v4l2-subdev.h>
-#include <mach/camera.h>
-
-#define NUM_MASTERS 2
-#define NUM_QUEUES 2
-
-#define TRUE  1
-#define FALSE 0
-
-struct msm_camera_cci_master_info {
-	uint32_t status;
-	uint8_t reset_pending;
-	struct mutex mutex;
-	struct completion reset_complete;
-};
-
-struct cci_device {
-	struct platform_device *pdev;
-	struct v4l2_subdev subdev;
-	struct resource *mem;
-	struct resource *irq;
-	struct resource *io;
-	void __iomem *base;
-	uint32_t hw_version;
-	struct clk *cci_clk[5];
-	struct msm_camera_cci_i2c_queue_info
-		cci_i2c_queue_info[NUM_MASTERS][NUM_QUEUES];
-	struct msm_camera_cci_master_info cci_master_info[NUM_MASTERS];
-};
-
-enum msm_cci_i2c_cmd_type {
-	CCI_I2C_SET_PARAM_CMD = 1,
-	CCI_I2C_WAIT_CMD,
-	CCI_I2C_WAIT_SYNC_CMD,
-	CCI_I2C_WAIT_GPIO_EVENT_CMD,
-	CCI_I2C_TRIG_I2C_EVENT_CMD,
-	CCI_I2C_LOCK_CMD,
-	CCI_I2C_UNLOCK_CMD,
-	CCI_I2C_REPORT_CMD,
-	CCI_I2C_WRITE_CMD,
-	CCI_I2C_READ_CMD,
-	CCI_I2C_WRITE_DISABLE_P_CMD,
-	CCI_I2C_READ_DISABLE_P_CMD,
-	CCI_I2C_WRITE_CMD2,
-	CCI_I2C_WRITE_CMD3,
-	CCI_I2C_REPEAT_CMD,
-	CCI_I2C_INVALID_CMD,
-};
-
-enum msm_cci_gpio_cmd_type {
-	CCI_GPIO_SET_PARAM_CMD = 1,
-	CCI_GPIO_WAIT_CMD,
-	CCI_GPIO_WAIT_SYNC_CMD,
-	CCI_GPIO_WAIT_GPIO_IN_EVENT_CMD,
-	CCI_GPIO_WAIT_I2C_Q_TRIG_EVENT_CMD,
-	CCI_GPIO_OUT_CMD,
-	CCI_GPIO_TRIG_EVENT_CMD,
-	CCI_GPIO_REPORT_CMD,
-	CCI_GPIO_REPEAT_CMD,
-	CCI_GPIO_CONTINUE_CMD,
-	CCI_GPIO_INVALID_CMD,
-};
-
-#define VIDIOC_MSM_CCI_CFG \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 23, struct msm_camera_cci_ctrl *)
-
-#endif
-
diff --git a/drivers/media/video/msm/cpp/Makefile b/drivers/media/video/msm/cpp/Makefile
deleted file mode 100644
index b4f1fdf..0000000
--- a/drivers/media/video/msm/cpp/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
-ccflags-y += -Idrivers/media/video/msm
-ccflags-y += -Idrivers/media/video/msm/io
-obj-$(CONFIG_MSM_CPP) += msm_cpp.o
-
diff --git a/drivers/media/video/msm/cpp/msm_cpp.c b/drivers/media/video/msm/cpp/msm_cpp.c
deleted file mode 100644
index e569388..0000000
--- a/drivers/media/video/msm/cpp/msm_cpp.c
+++ /dev/null
@@ -1,412 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/delay.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <mach/board.h>
-#include <mach/camera.h>
-#include <mach/vreg.h>
-#include <media/msm_isp.h>
-#include <linux/proc_fs.h>
-#include <linux/debugfs.h>
-
-#include "msm_cpp.h"
-#include "msm.h"
-
-#define CONFIG_MSM_CPP_DBG 0
-
-#if CONFIG_MSM_CPP_DBG
-#define CPP_DBG(fmt, args...) pr_info(fmt, ##args)
-#else
-#define CPP_DBG(fmt, args...) pr_debug(fmt, ##args)
-#endif
-
-static int cpp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
-	uint32_t i;
-	struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd);
-	CPP_DBG("%s\n", __func__);
-
-	mutex_lock(&cpp_dev->mutex);
-	if (cpp_dev->cpp_open_cnt == MAX_ACTIVE_CPP_INSTANCE) {
-		pr_err("No free CPP instance\n");
-		mutex_unlock(&cpp_dev->mutex);
-		return -ENODEV;
-	}
-
-	for (i = 0; i < MAX_ACTIVE_CPP_INSTANCE; i++) {
-		if (cpp_dev->cpp_subscribe_list[i].active == 0) {
-			cpp_dev->cpp_subscribe_list[i].active = 1;
-			cpp_dev->cpp_subscribe_list[i].vfh = &fh->vfh;
-			break;
-		}
-	}
-	if (i == MAX_ACTIVE_CPP_INSTANCE) {
-		pr_err("No free instance\n");
-		mutex_unlock(&cpp_dev->mutex);
-		return -ENODEV;
-	}
-
-	CPP_DBG("open %d %p\n", i, &fh->vfh);
-	cpp_dev->cpp_open_cnt++;
-	mutex_unlock(&cpp_dev->mutex);
-	return 0;
-}
-
-static int cpp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
-	uint32_t i;
-	struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd);
-	mutex_lock(&cpp_dev->mutex);
-	for (i = 0; i < MAX_ACTIVE_CPP_INSTANCE; i++) {
-		if (cpp_dev->cpp_subscribe_list[i].vfh == &fh->vfh) {
-			cpp_dev->cpp_subscribe_list[i].active = 0;
-			cpp_dev->cpp_subscribe_list[i].vfh = NULL;
-			break;
-		}
-	}
-	if (i == MAX_ACTIVE_CPP_INSTANCE) {
-		pr_err("Invalid close\n");
-		mutex_unlock(&cpp_dev->mutex);
-		return -ENODEV;
-	}
-
-	CPP_DBG("close %d %p\n", i, &fh->vfh);
-	cpp_dev->cpp_open_cnt--;
-	mutex_unlock(&cpp_dev->mutex);
-	return 0;
-}
-
-static const struct v4l2_subdev_internal_ops msm_cpp_internal_ops = {
-	.open = cpp_open_node,
-	.close = cpp_close_node,
-};
-
-static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev)
-{
-	struct v4l2_event v4l2_evt;
-	struct msm_queue_cmd *frame_qcmd;
-	struct msm_queue_cmd *event_qcmd;
-	struct msm_cpp_frame_info_t *processed_frame;
-	struct msm_device_queue *queue = &cpp_dev->processing_q;
-
-	if (queue->len > 0) {
-		frame_qcmd = msm_dequeue(queue, list_frame);
-		processed_frame = frame_qcmd->command;
-
-		event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
-		if (!event_qcmd) {
-			pr_err("%s Insufficient memory. return", __func__);
-			return -ENOMEM;
-		}
-		atomic_set(&event_qcmd->on_heap, 1);
-		event_qcmd->command = processed_frame;
-		CPP_DBG("fid %d\n", processed_frame->frame_id);
-		msm_enqueue(&cpp_dev->eventData_q, &event_qcmd->list_eventdata);
-
-		v4l2_evt.id = processed_frame->inst_id;
-		v4l2_evt.type = V4L2_EVENT_CPP_FRAME_DONE;
-		v4l2_event_queue(cpp_dev->subdev.devnode, &v4l2_evt);
-	}
-	return 0;
-}
-
-static int msm_cpp_send_frame_to_hardware(struct cpp_device *cpp_dev)
-{
-	struct msm_queue_cmd *frame_qcmd;
-	struct msm_cpp_frame_info_t *process_frame;
-	struct msm_device_queue *queue;
-
-	if (cpp_dev->processing_q.len < MAX_CPP_PROCESSING_FRAME) {
-		while (cpp_dev->processing_q.len < MAX_CPP_PROCESSING_FRAME) {
-			if (cpp_dev->realtime_q.len != 0) {
-				queue = &cpp_dev->realtime_q;
-			} else if (cpp_dev->offline_q.len != 0) {
-				queue = &cpp_dev->offline_q;
-			} else {
-				pr_debug("%s: All frames queued\n", __func__);
-				break;
-			}
-			frame_qcmd = msm_dequeue(queue, list_frame);
-			/*TBD Code to actually sending to harware*/
-			process_frame = frame_qcmd->command;
-
-			msm_enqueue(&cpp_dev->processing_q,
-						&frame_qcmd->list_frame);
-		}
-	}
-	return 0;
-}
-
-long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
-			unsigned int cmd, void *arg)
-{
-	struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd);
-	struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
-	int rc = 0;
-
-	CPP_DBG("%s: %d\n", __func__, __LINE__);
-	mutex_lock(&cpp_dev->mutex);
-	CPP_DBG("%s cmd: %d\n", __func__, cmd);
-	switch (cmd) {
-	case VIDIOC_MSM_CPP_CFG: {
-		struct msm_queue_cmd *frame_qcmd;
-		struct msm_cpp_frame_info_t *new_frame =
-			kzalloc(sizeof(struct msm_cpp_frame_info_t),
-					GFP_KERNEL);
-		if (!new_frame) {
-			pr_err("%s Insufficient memory. return", __func__);
-			mutex_unlock(&cpp_dev->mutex);
-			return -ENOMEM;
-		}
-
-		COPY_FROM_USER(rc, new_frame,
-			       (void __user *)ioctl_ptr->ioctl_ptr,
-			       sizeof(struct msm_cpp_frame_info_t));
-		if (rc) {
-			ERR_COPY_FROM_USER();
-			kfree(new_frame);
-			mutex_unlock(&cpp_dev->mutex);
-			return -EINVAL;
-		}
-
-		frame_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
-		if (!frame_qcmd) {
-			pr_err("%s Insufficient memory. return", __func__);
-			kfree(new_frame);
-			mutex_unlock(&cpp_dev->mutex);
-			return -ENOMEM;
-		}
-
-		atomic_set(&frame_qcmd->on_heap, 1);
-		frame_qcmd->command = new_frame;
-		if (new_frame->frame_type == MSM_CPP_REALTIME_FRAME) {
-			msm_enqueue(&cpp_dev->realtime_q,
-						&frame_qcmd->list_frame);
-		} else if (new_frame->frame_type == MSM_CPP_OFFLINE_FRAME) {
-			msm_enqueue(&cpp_dev->offline_q,
-						&frame_qcmd->list_frame);
-		} else {
-			pr_err("%s: Invalid frame type\n", __func__);
-			kfree(new_frame);
-			kfree(frame_qcmd);
-			mutex_unlock(&cpp_dev->mutex);
-			return -EINVAL;
-		}
-		break;
-	}
-	case VIDIOC_MSM_CPP_GET_EVENTPAYLOAD: {
-		struct msm_device_queue *queue = &cpp_dev->eventData_q;
-		struct msm_queue_cmd *event_qcmd;
-		struct msm_cpp_frame_info_t *process_frame;
-		event_qcmd = msm_dequeue(queue, list_eventdata);
-		process_frame = event_qcmd->command;
-		CPP_DBG("fid %d\n", process_frame->frame_id);
-		if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
-				process_frame,
-				sizeof(struct msm_cpp_frame_info_t))) {
-					mutex_unlock(&cpp_dev->mutex);
-					return -EINVAL;
-		}
-		kfree(process_frame);
-		kfree(event_qcmd);
-		break;
-	}
-	}
-	mutex_unlock(&cpp_dev->mutex);
-	CPP_DBG("%s: %d\n", __func__, __LINE__);
-	return 0;
-}
-
-int msm_cpp_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
-	struct v4l2_event_subscription *sub)
-{
-	CPP_DBG("%s\n", __func__);
-	return v4l2_event_subscribe(fh, sub, MAX_CPP_V4l2_EVENTS);
-}
-
-int msm_cpp_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
-	struct v4l2_event_subscription *sub)
-{
-	CPP_DBG("%s\n", __func__);
-	return v4l2_event_unsubscribe(fh, sub);
-}
-
-static struct v4l2_subdev_core_ops msm_cpp_subdev_core_ops = {
-	.ioctl = msm_cpp_subdev_ioctl,
-	.subscribe_event = msm_cpp_subscribe_event,
-	.unsubscribe_event = msm_cpp_unsubscribe_event,
-};
-
-static const struct v4l2_subdev_ops msm_cpp_subdev_ops = {
-	.core = &msm_cpp_subdev_core_ops,
-};
-
-static int msm_cpp_enable_debugfs(struct cpp_device *cpp_dev);
-
-static struct v4l2_file_operations msm_cpp_v4l2_subdev_fops;
-
-static long msm_cpp_subdev_do_ioctl(
-	struct file *file, unsigned int cmd, void *arg)
-{
-	struct video_device *vdev = video_devdata(file);
-	struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
-	struct v4l2_fh *vfh = file->private_data;
-
-	switch (cmd) {
-	case VIDIOC_DQEVENT:
-		if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS))
-			return -ENOIOCTLCMD;
-
-		return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK);
-
-	case VIDIOC_SUBSCRIBE_EVENT:
-		return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg);
-
-	case VIDIOC_UNSUBSCRIBE_EVENT:
-		return v4l2_subdev_call(sd, core, unsubscribe_event, vfh, arg);
-
-	case VIDIOC_MSM_CPP_GET_INST_INFO: {
-		uint32_t i;
-		struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd);
-		struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
-		struct msm_cpp_frame_info_t inst_info;
-		for (i = 0; i < MAX_ACTIVE_CPP_INSTANCE; i++) {
-			if (cpp_dev->cpp_subscribe_list[i].vfh == vfh) {
-				inst_info.inst_id = i;
-				break;
-			}
-		}
-		if (copy_to_user(
-				(void __user *)ioctl_ptr->ioctl_ptr, &inst_info,
-				sizeof(struct msm_cpp_frame_info_t))) {
-			return -EINVAL;
-		}
-	}
-	break;
-	default:
-		return v4l2_subdev_call(sd, core, ioctl, cmd, arg);
-	}
-
-	return 0;
-}
-
-static long msm_cpp_subdev_fops_ioctl(struct file *file, unsigned int cmd,
-	unsigned long arg)
-{
-	return video_usercopy(file, cmd, arg, msm_cpp_subdev_do_ioctl);
-}
-
-static int __devinit cpp_probe(struct platform_device *pdev)
-{
-	struct cpp_device *cpp_dev;
-	struct msm_cam_subdev_info sd_info;
-	int rc = 0;
-	CDBG("%s: device id = %d\n", __func__, pdev->id);
-	cpp_dev = kzalloc(sizeof(struct cpp_device), GFP_KERNEL);
-	if (!cpp_dev) {
-		pr_err("%s: no enough memory\n", __func__);
-		return -ENOMEM;
-	}
-	v4l2_subdev_init(&cpp_dev->subdev, &msm_cpp_subdev_ops);
-	cpp_dev->subdev.internal_ops = &msm_cpp_internal_ops;
-	snprintf(cpp_dev->subdev.name, ARRAY_SIZE(cpp_dev->subdev.name),
-		 "cpp");
-	cpp_dev->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-	cpp_dev->subdev.flags |= V4L2_SUBDEV_FL_HAS_EVENTS;
-	v4l2_set_subdevdata(&cpp_dev->subdev, cpp_dev);
-	platform_set_drvdata(pdev, &cpp_dev->subdev);
-	mutex_init(&cpp_dev->mutex);
-
-	cpp_dev->pdev = pdev;
-
-	media_entity_init(&cpp_dev->subdev.entity, 0, NULL, 0);
-	cpp_dev->subdev.entity.type = MEDIA_ENT_T_DEVNODE_V4L;
-	cpp_dev->subdev.entity.group_id = CPP_DEV;
-	cpp_dev->subdev.entity.name = pdev->name;
-	sd_info.sdev_type = CPP_DEV;
-	sd_info.sd_index = pdev->id;
-	msm_cam_register_subdev_node(&cpp_dev->subdev, &sd_info);
-	msm_cpp_v4l2_subdev_fops.owner = v4l2_subdev_fops.owner;
-	msm_cpp_v4l2_subdev_fops.open = v4l2_subdev_fops.open;
-	msm_cpp_v4l2_subdev_fops.unlocked_ioctl = msm_cpp_subdev_fops_ioctl;
-	msm_cpp_v4l2_subdev_fops.release = v4l2_subdev_fops.release;
-	msm_cpp_v4l2_subdev_fops.poll = v4l2_subdev_fops.poll;
-
-	cpp_dev->subdev.devnode->fops = &msm_cpp_v4l2_subdev_fops;
-	cpp_dev->subdev.entity.revision = cpp_dev->subdev.devnode->num;
-	msm_cpp_enable_debugfs(cpp_dev);
-	msm_queue_init(&cpp_dev->eventData_q, "eventdata");
-	msm_queue_init(&cpp_dev->offline_q, "frame");
-	msm_queue_init(&cpp_dev->realtime_q, "frame");
-	msm_queue_init(&cpp_dev->processing_q, "frame");
-	cpp_dev->cpp_open_cnt = 0;
-
-	return rc;
-}
-
-static struct platform_driver cpp_driver = {
-	.probe = cpp_probe,
-	.driver = {
-		.name = MSM_CPP_DRV_NAME,
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init msm_cpp_init_module(void)
-{
-	return platform_driver_register(&cpp_driver);
-}
-
-static void __exit msm_cpp_exit_module(void)
-{
-	platform_driver_unregister(&cpp_driver);
-}
-
-static int msm_cpp_debugfs_stream_s(void *data, u64 val)
-{
-	struct cpp_device *cpp_dev = data;
-	CPP_DBG("CPP processing frame E\n");
-	while (1) {
-		mutex_lock(&cpp_dev->mutex);
-		msm_cpp_notify_frame_done(cpp_dev);
-		msm_cpp_send_frame_to_hardware(cpp_dev);
-		mutex_unlock(&cpp_dev->mutex);
-		msleep(20);
-	}
-	CPP_DBG("CPP processing frame X\n");
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(cpp_debugfs_stream, NULL,
-			msm_cpp_debugfs_stream_s, "%llu\n");
-
-static int msm_cpp_enable_debugfs(struct cpp_device *cpp_dev)
-{
-	struct dentry *debugfs_base;
-	debugfs_base = debugfs_create_dir("msm_camera", NULL);
-	if (!debugfs_base)
-		return -ENOMEM;
-
-	if (!debugfs_create_file("test", S_IRUGO | S_IWUSR, debugfs_base,
-			(void *)cpp_dev, &cpp_debugfs_stream))
-		return -ENOMEM;
-
-	return 0;
-}
-
-module_init(msm_cpp_init_module);
-module_exit(msm_cpp_exit_module);
-MODULE_DESCRIPTION("MSM CPP driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/cpp/msm_cpp.h b/drivers/media/video/msm/cpp/msm_cpp.h
deleted file mode 100644
index 8c10cac..0000000
--- a/drivers/media/video/msm/cpp/msm_cpp.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/clk.h>
-#include <linux/io.h>
-#include <linux/list.h>
-#include <media/v4l2-subdev.h>
-
-#define MAX_ACTIVE_CPP_INSTANCE 8
-#define MAX_CPP_PROCESSING_FRAME 2
-#define MAX_CPP_V4l2_EVENTS 30
-
-#define MSM_CPP_MICRO_BASE          0x4000
-#define MSM_CPP_MICRO_HW_VERSION    0x0000
-#define MSM_CPP_MICRO_IRQGEN_STAT   0x0004
-#define MSM_CPP_MICRO_IRQGEN_CLR    0x0008
-#define MSM_CPP_MICRO_IRQGEN_MASK   0x000C
-#define MSM_CPP_MICRO_FIFO_TX_DATA  0x0010
-#define MSM_CPP_MICRO_FIFO_TX_STAT  0x0014
-#define MSM_CPP_MICRO_FIFO_RX_DATA  0x0018
-#define MSM_CPP_MICRO_FIFO_RX_STAT  0x001C
-#define MSM_CPP_MICRO_BOOT_START    0x0020
-#define MSM_CPP_MICRO_BOOT_LDORG    0x0024
-#define MSM_CPP_MICRO_CLKEN_CTL     0x0030
-
-struct cpp_subscribe_info {
-	struct v4l2_fh *vfh;
-	uint32_t active;
-};
-
-struct cpp_device {
-	struct platform_device *pdev;
-	struct v4l2_subdev subdev;
-	struct resource *mem;
-	struct resource *irq;
-	struct resource *io;
-	void __iomem *base;
-	struct clk *cpp_clk[2];
-	struct mutex mutex;
-
-	struct cpp_subscribe_info cpp_subscribe_list[MAX_ACTIVE_CPP_INSTANCE];
-	uint32_t cpp_open_cnt;
-
-	struct msm_device_queue eventData_q; /*V4L2 Event Payload Queue*/
-
-	/*Offline Frame Queue
-	  process when realtime queue is empty*/
-	struct msm_device_queue offline_q;
-	/*Realtime Frame Queue
-	  process with highest priority*/
-	struct msm_device_queue realtime_q;
-	/*Processing Queue
-	  store frame info for frames sent to microcontroller*/
-	struct msm_device_queue processing_q;
-};
-
diff --git a/drivers/media/video/msm/csi/Makefile b/drivers/media/video/msm/csi/Makefile
deleted file mode 100644
index 5aaaff7..0000000
--- a/drivers/media/video/msm/csi/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
-ccflags-y += -Idrivers/media/video/msm -Idrivers/media/video/msm/server
-ifeq ($(CONFIG_MSM_CSI20_HEADER),y)
-  ccflags-y += -Idrivers/media/video/msm/csi/include/csi2.0
-else ifeq ($(CONFIG_MSM_CSI30_HEADER),y)
-  ccflags-y += -Idrivers/media/video/msm/csi/include/csi3.0
-endif
-obj-$(CONFIG_MSM_CSI2_REGISTER) += msm_csi2_register.o
-obj-$(CONFIG_MSM_CSIPHY) += msm_csiphy.o
-obj-$(CONFIG_MSM_CSID) += msm_csid.o
-obj-$(CONFIG_MSM_ISPIF) += msm_ispif.o
-obj-$(CONFIG_ARCH_MSM8960) += msm_csi2_register.o msm_csiphy.o msm_csid.o msm_ispif.o
-obj-$(CONFIG_ARCH_MSM7X27A) += msm_csic_register.o msm_csic.o
-obj-$(CONFIG_ARCH_MSM8X60) += msm_csic_register.o msm_csic.o
-obj-$(CONFIG_ARCH_MSM7X30) += msm_csic_register.o msm_csic.o
diff --git a/drivers/media/video/msm/csi/include/csi2.0/msm_csid_hwreg.h b/drivers/media/video/msm/csi/include/csi2.0/msm_csid_hwreg.h
deleted file mode 100644
index 4682f8f..0000000
--- a/drivers/media/video/msm/csi/include/csi2.0/msm_csid_hwreg.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 MSM_CSID_HWREG_H
-#define MSM_CSID_HWREG_H
-
-/* MIPI	CSID registers */
-#define CSID_HW_VERSION_ADDR                        0x0
-#define CSID_CORE_CTRL_0_ADDR                       0x4
-#define CSID_CORE_CTRL_1_ADDR                       0x4
-#define CSID_RST_CMD_ADDR                           0x8
-#define CSID_CID_LUT_VC_0_ADDR                      0xc
-#define CSID_CID_LUT_VC_1_ADDR                      0x10
-#define CSID_CID_LUT_VC_2_ADDR                      0x14
-#define CSID_CID_LUT_VC_3_ADDR                      0x18
-#define CSID_CID_n_CFG_ADDR                         0x1C
-#define CSID_IRQ_CLEAR_CMD_ADDR                     0x5c
-#define CSID_IRQ_MASK_ADDR                          0x60
-#define CSID_IRQ_STATUS_ADDR                        0x64
-#define CSID_CAPTURED_UNMAPPED_LONG_PKT_HDR_ADDR    0x68
-#define CSID_CAPTURED_MMAPPED_LONG_PKT_HDR_ADDR     0x6c
-#define CSID_CAPTURED_SHORT_PKT_ADDR                0x70
-#define CSID_CAPTURED_LONG_PKT_HDR_ADDR             0x74
-#define CSID_CAPTURED_LONG_PKT_FTR_ADDR             0x78
-#define CSID_PIF_MISR_DL0_ADDR                      0x7C
-#define CSID_PIF_MISR_DL1_ADDR                      0x80
-#define CSID_PIF_MISR_DL2_ADDR                      0x84
-#define CSID_PIF_MISR_DL3_ADDR                      0x88
-#define CSID_STATS_TOTAL_PKTS_RCVD_ADDR             0x8C
-#define CSID_STATS_ECC_ADDR                         0x90
-#define CSID_STATS_CRC_ADDR                         0x94
-#define CSID_TG_CTRL_ADDR                           0x9C
-#define CSID_TG_VC_CFG_ADDR                         0xA0
-#define CSID_TG_DT_n_CFG_0_ADDR                     0xA8
-#define CSID_TG_DT_n_CFG_1_ADDR                     0xAC
-#define CSID_TG_DT_n_CFG_2_ADDR                     0xB0
-#define CSID_RST_DONE_IRQ_BITSHIFT                  11
-#define CSID_RST_STB_ALL                            0x7FFF
-#define CSID_DL_INPUT_SEL_SHIFT                     0x2
-#define CSID_PHY_SEL_SHIFT                          17
-#define CSID_VERSION                                0x02000011
-
-#endif
diff --git a/drivers/media/video/msm/csi/include/csi2.0/msm_csiphy_hwreg.h b/drivers/media/video/msm/csi/include/csi2.0/msm_csiphy_hwreg.h
deleted file mode 100644
index 2e83101..0000000
--- a/drivers/media/video/msm/csi/include/csi2.0/msm_csiphy_hwreg.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 MSM_CSIPHY_HWREG_H
-#define MSM_CSIPHY_HWREG_H
-
-/*MIPI CSI PHY registers*/
-#define MIPI_CSIPHY_HW_VERSION_ADDR              0x180
-#define MIPI_CSIPHY_LNn_CFG1_ADDR                0x0
-#define MIPI_CSIPHY_LNn_CFG2_ADDR                0x4
-#define MIPI_CSIPHY_LNn_CFG3_ADDR                0x8
-#define MIPI_CSIPHY_LNn_CFG4_ADDR                0xC
-#define MIPI_CSIPHY_LNn_CFG5_ADDR                0x10
-#define MIPI_CSIPHY_LNCK_CFG1_ADDR               0x100
-#define MIPI_CSIPHY_LNCK_CFG2_ADDR               0x104
-#define MIPI_CSIPHY_LNCK_CFG3_ADDR               0x108
-#define MIPI_CSIPHY_LNCK_CFG4_ADDR               0x10C
-#define MIPI_CSIPHY_LNCK_CFG5_ADDR               0x110
-#define MIPI_CSIPHY_LNCK_MISC1_ADDR              0x128
-#define MIPI_CSIPHY_GLBL_RESET_ADDR              0x140
-#define MIPI_CSIPHY_GLBL_PWR_CFG_ADDR            0x144
-#define MIPI_CSIPHY_GLBL_IRQ_CMD_ADDR            0x164
-#define MIPI_CSIPHY_INTERRUPT_STATUS0_ADDR       0x180
-#define MIPI_CSIPHY_INTERRUPT_MASK0_ADDR         0x1A0
-#define MIPI_CSIPHY_INTERRUPT_MASK_VAL           0x6F
-#define MIPI_CSIPHY_INTERRUPT_MASK_ADDR          0x1A4
-#define MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR        0x1C0
-#define MIPI_CSIPHY_INTERRUPT_CLEAR_ADDR         0x1C4
-#define MIPI_CSIPHY_MODE_CONFIG_SHIFT            0x4
-#define MIPI_CSIPHY_GLBL_T_INIT_CFG0_ADDR        0x1E0
-#define MIPI_CSIPHY_T_WAKEUP_CFG0_ADDR           0x1E8
-#define CSIPHY_VERSION                           0x0
-
-#endif
diff --git a/drivers/media/video/msm/csi/include/csi2.0/msm_ispif_hwreg.h b/drivers/media/video/msm/csi/include/csi2.0/msm_ispif_hwreg.h
deleted file mode 100644
index d37d67e..0000000
--- a/drivers/media/video/msm/csi/include/csi2.0/msm_ispif_hwreg.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 MSM_ISPIF_HWREG_H
-#define MSM_ISPIF_HWREG_H
-
-
-/* ISPIF registers */
-
-#define ISPIF_RST_CMD_ADDR                        0x00
-#define ISPIF_RST_CMD_1_ADDR                      0x00
-#define ISPIF_INTF_CMD_ADDR                       0x04
-#define ISPIF_INTF_CMD_1_ADDR                     0x30
-#define ISPIF_CTRL_ADDR                           0x08
-#define ISPIF_INPUT_SEL_ADDR                      0x0C
-#define ISPIF_PIX_0_INTF_CID_MASK_ADDR            0x10
-#define ISPIF_RDI_0_INTF_CID_MASK_ADDR            0x14
-#define ISPIF_PIX_1_INTF_CID_MASK_ADDR            0x38
-#define ISPIF_RDI_1_INTF_CID_MASK_ADDR            0x3C
-#define ISPIF_RDI_2_INTF_CID_MASK_ADDR            0x44
-#define ISPIF_PIX_0_STATUS_ADDR                   0x24
-#define ISPIF_RDI_0_STATUS_ADDR                   0x28
-#define ISPIF_PIX_1_STATUS_ADDR                   0x60
-#define ISPIF_RDI_1_STATUS_ADDR                   0x64
-#define ISPIF_RDI_2_STATUS_ADDR                   0x6C
-#define ISPIF_IRQ_MASK_ADDR                     0x0100
-#define ISPIF_IRQ_CLEAR_ADDR                    0x0104
-#define ISPIF_IRQ_STATUS_ADDR                   0x0108
-#define ISPIF_IRQ_MASK_1_ADDR                   0x010C
-#define ISPIF_IRQ_CLEAR_1_ADDR                  0x0110
-#define ISPIF_IRQ_STATUS_1_ADDR                 0x0114
-#define ISPIF_IRQ_MASK_2_ADDR                   0x0118
-#define ISPIF_IRQ_CLEAR_2_ADDR                  0x011C
-#define ISPIF_IRQ_STATUS_2_ADDR                 0x0120
-#define ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR         0x0124
-
-/*ISPIF RESET BITS*/
-
-#define VFE_CLK_DOMAIN_RST           31
-#define RDI_CLK_DOMAIN_RST           30
-#define PIX_CLK_DOMAIN_RST           29
-#define AHB_CLK_DOMAIN_RST           28
-#define RDI_1_CLK_DOMAIN_RST         27
-#define RDI_2_VFE_RST_STB            19
-#define RDI_2_CSID_RST_STB           18
-#define RDI_1_VFE_RST_STB            13
-#define RDI_1_CSID_RST_STB           12
-#define RDI_0_VFE_RST_STB            7
-#define RDI_0_CSID_RST_STB           6
-#define PIX_1_VFE_RST_STB            10
-#define PIX_1_CSID_RST_STB           9
-#define PIX_0_VFE_RST_STB            4
-#define PIX_0_CSID_RST_STB           3
-#define SW_REG_RST_STB               2
-#define MISC_LOGIC_RST_STB           1
-#define STROBED_RST_EN               0
-
-#define ISPIF_RST_CMD_MASK           0xFE0F1FFF
-#define ISPIF_RST_CMD_1_MASK         0xFC0F1FF9
-
-#define PIX_INTF_0_OVERFLOW_IRQ      12
-#define RAW_INTF_0_OVERFLOW_IRQ      25
-#define RAW_INTF_1_OVERFLOW_IRQ      25
-#define RAW_INTF_2_OVERFLOW_IRQ      12
-#define RESET_DONE_IRQ               27
-
-#define ISPIF_IRQ_STATUS_MASK        0x0A493249
-#define ISPIF_IRQ_STATUS_1_MASK      0x02493249
-#define ISPIF_IRQ_STATUS_2_MASK      0x00001249
-
-#define ISPIF_IRQ_STATUS_PIX_SOF_MASK	0x249
-#define ISPIF_IRQ_STATUS_RDI0_SOF_MASK	0x492000
-#define ISPIF_IRQ_STATUS_RDI1_SOF_MASK	0x492000
-#define ISPIF_IRQ_STATUS_RDI2_SOF_MASK	0x249
-
-#define ISPIF_IRQ_STATUS_SOF_MASK	0x492249
-#define ISPIF_IRQ_GLOBAL_CLEAR_CMD     0x1
-
-#endif
diff --git a/drivers/media/video/msm/csi/include/csi3.0/msm_csid_hwreg.h b/drivers/media/video/msm/csi/include/csi3.0/msm_csid_hwreg.h
deleted file mode 100644
index 11a04d5..0000000
--- a/drivers/media/video/msm/csi/include/csi3.0/msm_csid_hwreg.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 MSM_CSID_HWREG_H
-#define MSM_CSID_HWREG_H
-
-/* MIPI	CSID registers */
-#define CSID_HW_VERSION_ADDR                        0x0
-#define CSID_CORE_CTRL_0_ADDR                       0x4
-#define CSID_CORE_CTRL_1_ADDR                       0x8
-#define CSID_RST_CMD_ADDR                           0xC
-#define CSID_CID_LUT_VC_0_ADDR                      0x10
-#define CSID_CID_LUT_VC_1_ADDR                      0x14
-#define CSID_CID_LUT_VC_2_ADDR                      0x18
-#define CSID_CID_LUT_VC_3_ADDR                      0x1C
-#define CSID_CID_n_CFG_ADDR                         0x20
-#define CSID_IRQ_CLEAR_CMD_ADDR                     0x60
-#define CSID_IRQ_MASK_ADDR                          0x64
-#define CSID_IRQ_STATUS_ADDR                        0x68
-#define CSID_CAPTURED_UNMAPPED_LONG_PKT_HDR_ADDR    0x6C
-#define CSID_CAPTURED_MMAPPED_LONG_PKT_HDR_ADDR     0x70
-#define CSID_CAPTURED_SHORT_PKT_ADDR                0x74
-#define CSID_CAPTURED_LONG_PKT_HDR_ADDR             0x78
-#define CSID_CAPTURED_LONG_PKT_FTR_ADDR             0x7C
-#define CSID_PIF_MISR_DL0_ADDR                      0x80
-#define CSID_PIF_MISR_DL1_ADDR                      0x84
-#define CSID_PIF_MISR_DL2_ADDR                      0x88
-#define CSID_PIF_MISR_DL3_ADDR                      0x8C
-#define CSID_STATS_TOTAL_PKTS_RCVD_ADDR             0x90
-#define CSID_STATS_ECC_ADDR                         0x94
-#define CSID_STATS_CRC_ADDR                         0x98
-#define CSID_TG_CTRL_ADDR                           0xA0
-#define CSID_TG_VC_CFG_ADDR                         0xA4
-#define CSID_TG_DT_n_CFG_0_ADDR                     0xAC
-#define CSID_TG_DT_n_CFG_1_ADDR                     0xB0
-#define CSID_TG_DT_n_CFG_2_ADDR                     0xB4
-#define CSID_RST_DONE_IRQ_BITSHIFT                  11
-#define CSID_RST_STB_ALL                            0x7FFF
-#define CSID_DL_INPUT_SEL_SHIFT                     0x4
-#define CSID_PHY_SEL_SHIFT                          17
-#define CSID_VERSION                                0x30000000
-
-#endif
diff --git a/drivers/media/video/msm/csi/include/csi3.0/msm_csiphy_hwreg.h b/drivers/media/video/msm/csi/include/csi3.0/msm_csiphy_hwreg.h
deleted file mode 100644
index 4e640e3..0000000
--- a/drivers/media/video/msm/csi/include/csi3.0/msm_csiphy_hwreg.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 MSM_CSIPHY_HWREG_H
-#define MSM_CSIPHY_HWREG_H
-
-/*MIPI CSI PHY registers*/
-#define MIPI_CSIPHY_LNn_CFG1_ADDR                0x0
-#define MIPI_CSIPHY_LNn_CFG2_ADDR                0x4
-#define MIPI_CSIPHY_LNn_CFG3_ADDR                0x8
-#define MIPI_CSIPHY_LNn_CFG4_ADDR                0xC
-#define MIPI_CSIPHY_LNn_CFG5_ADDR                0x10
-#define MIPI_CSIPHY_LNCK_CFG1_ADDR               0x100
-#define MIPI_CSIPHY_LNCK_CFG2_ADDR               0x104
-#define MIPI_CSIPHY_LNCK_CFG3_ADDR               0x108
-#define MIPI_CSIPHY_LNCK_CFG4_ADDR               0x10C
-#define MIPI_CSIPHY_LNCK_CFG5_ADDR               0x110
-#define MIPI_CSIPHY_LNCK_MISC1_ADDR              0x128
-#define MIPI_CSIPHY_GLBL_RESET_ADDR              0x140
-#define MIPI_CSIPHY_GLBL_PWR_CFG_ADDR            0x144
-#define MIPI_CSIPHY_GLBL_IRQ_CMD_ADDR            0x164
-#define MIPI_CSIPHY_HW_VERSION_ADDR              0x188
-#define MIPI_CSIPHY_INTERRUPT_STATUS0_ADDR       0x18C
-#define MIPI_CSIPHY_INTERRUPT_MASK0_ADDR         0x1AC
-#define MIPI_CSIPHY_INTERRUPT_MASK_VAL           0x3F
-#define MIPI_CSIPHY_INTERRUPT_MASK_ADDR          0x1AC
-#define MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR        0x1CC
-#define MIPI_CSIPHY_INTERRUPT_CLEAR_ADDR         0x1CC
-#define MIPI_CSIPHY_MODE_CONFIG_SHIFT            0x4
-#define MIPI_CSIPHY_GLBL_T_INIT_CFG0_ADDR        0x1EC
-#define MIPI_CSIPHY_T_WAKEUP_CFG0_ADDR           0x1F4
-#define CSIPHY_VERSION                           0x10
-
-#endif
diff --git a/drivers/media/video/msm/csi/include/csi3.0/msm_ispif_hwreg.h b/drivers/media/video/msm/csi/include/csi3.0/msm_ispif_hwreg.h
deleted file mode 100644
index 7c09c4f..0000000
--- a/drivers/media/video/msm/csi/include/csi3.0/msm_ispif_hwreg.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 MSM_ISPIF_HWREG_H
-#define MSM_ISPIF_HWREG_H
-
-
-/* ISPIF registers */
-
-#define ISPIF_RST_CMD_ADDR                        0x08
-#define ISPIF_RST_CMD_1_ADDR                      0x0C
-#define ISPIF_INTF_CMD_ADDR                      0x248
-#define ISPIF_INTF_CMD_1_ADDR                    0x24C
-#define ISPIF_CTRL_ADDR                           0x08
-#define ISPIF_INPUT_SEL_ADDR                     0x244
-#define ISPIF_PIX_0_INTF_CID_MASK_ADDR           0x254
-#define ISPIF_RDI_0_INTF_CID_MASK_ADDR           0x264
-#define ISPIF_PIX_1_INTF_CID_MASK_ADDR           0x258
-#define ISPIF_RDI_1_INTF_CID_MASK_ADDR           0x268
-#define ISPIF_RDI_2_INTF_CID_MASK_ADDR           0x26C
-#define ISPIF_PIX_0_STATUS_ADDR                  0x2C0
-#define ISPIF_RDI_0_STATUS_ADDR                  0x2D0
-#define ISPIF_PIX_1_STATUS_ADDR                  0x2C4
-#define ISPIF_RDI_1_STATUS_ADDR                  0x2D4
-#define ISPIF_RDI_2_STATUS_ADDR                  0x2D8
-#define ISPIF_IRQ_MASK_ADDR                      0x208
-#define ISPIF_IRQ_CLEAR_ADDR                     0x230
-#define ISPIF_IRQ_STATUS_ADDR                    0x21C
-#define ISPIF_IRQ_MASK_1_ADDR                    0x20C
-#define ISPIF_IRQ_CLEAR_1_ADDR                   0x234
-#define ISPIF_IRQ_STATUS_1_ADDR                  0x220
-#define ISPIF_IRQ_MASK_2_ADDR                    0x210
-#define ISPIF_IRQ_CLEAR_2_ADDR                   0x238
-#define ISPIF_IRQ_STATUS_2_ADDR                  0x224
-#define ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR           0x1C
-
-/* new */
-#define ISPIF_VFE_m_CTRL_0_ADDR                  0x200
-#define ISPIF_VFE_m_IRQ_MASK_0                   0x208
-#define ISPIF_VFE_m_IRQ_MASK_1                   0x20C
-#define ISPIF_VFE_m_IRQ_MASK_2                   0x210
-#define ISPIF_VFE_m_IRQ_STATUS_0                 0x21C
-#define ISPIF_VFE_m_IRQ_STATUS_1                 0x220
-#define ISPIF_VFE_m_IRQ_STATUS_2                 0x224
-#define ISPIF_VFE_m_IRQ_CLEAR_0                  0x230
-#define ISPIF_VFE_m_IRQ_CLEAR_1                  0x234
-#define ISPIF_VFE_m_IRQ_CLEAR_2                  0x238
-
-/*ISPIF RESET BITS*/
-
-#define VFE_CLK_DOMAIN_RST           31
-#define RDI_CLK_DOMAIN_RST           26
-#define RDI_1_CLK_DOMAIN_RST         27
-#define RDI_2_CLK_DOMAIN_RST         28
-#define PIX_CLK_DOMAIN_RST           29
-#define PIX_1_CLK_DOMAIN_RST         30
-#define AHB_CLK_DOMAIN_RST           25
-#define RDI_2_VFE_RST_STB            12
-#define RDI_2_CSID_RST_STB           11
-#define RDI_1_VFE_RST_STB            10
-#define RDI_1_CSID_RST_STB           9
-#define RDI_0_VFE_RST_STB            8
-#define RDI_0_CSID_RST_STB           7
-#define PIX_1_VFE_RST_STB            6
-#define PIX_1_CSID_RST_STB           5
-#define PIX_0_VFE_RST_STB            4
-#define PIX_0_CSID_RST_STB           3
-#define SW_REG_RST_STB               2
-#define MISC_LOGIC_RST_STB           1
-#define STROBED_RST_EN               0
-
-#define ISPIF_RST_CMD_MASK           0xFE0F1FFF
-#define ISPIF_RST_CMD_1_MASK         0xFC0F1FF9
-
-#define PIX_INTF_0_OVERFLOW_IRQ      12
-#define RAW_INTF_0_OVERFLOW_IRQ      25
-#define RAW_INTF_1_OVERFLOW_IRQ      25
-#define RAW_INTF_2_OVERFLOW_IRQ      12
-#define RESET_DONE_IRQ               27
-
-#define ISPIF_IRQ_STATUS_MASK        0x0A493249
-#define ISPIF_IRQ_STATUS_1_MASK      0x02493249
-#define ISPIF_IRQ_STATUS_2_MASK      0x00001249
-
-#define ISPIF_IRQ_STATUS_PIX_SOF_MASK	0x249
-#define ISPIF_IRQ_STATUS_RDI0_SOF_MASK	0x492000
-#define ISPIF_IRQ_STATUS_RDI1_SOF_MASK	0x492000
-#define ISPIF_IRQ_STATUS_RDI2_SOF_MASK	0x249
-
-#define ISPIF_IRQ_STATUS_SOF_MASK	0x492249
-#define ISPIF_IRQ_GLOBAL_CLEAR_CMD     0x1
-
-#endif
diff --git a/drivers/media/video/msm/csi/msm_csi2_register.c b/drivers/media/video/msm/csi/msm_csi2_register.c
deleted file mode 100644
index 5f2183b..0000000
--- a/drivers/media/video/msm/csi/msm_csi2_register.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/device.h>
-#include "msm.h"
-#include "msm_csi_register.h"
-
-int msm_csi_register_subdevs(struct msm_cam_media_controller *p_mctl,
-	uint8_t csiphy_code_index, uint8_t csid_core_index,
-	struct msm_cam_server_dev *server_dev)
-{
-	int rc = -ENODEV;
-
-	CDBG("%s csiphy sel %d csid sel %d\n", __func__, csiphy_code_index,
-		csid_core_index);
-	/* register csiphy subdev */
-	p_mctl->csiphy_sdev = server_dev->csiphy_device[csiphy_code_index];
-	if (!p_mctl->csiphy_sdev)
-		goto out;
-	v4l2_set_subdev_hostdata(p_mctl->csiphy_sdev, p_mctl);
-
-	/* register csid subdev */
-	p_mctl->csid_sdev = server_dev->csid_device[csid_core_index];
-	if (!p_mctl->csid_sdev)
-		goto out;
-	v4l2_set_subdev_hostdata(p_mctl->csid_sdev, p_mctl);
-
-	/* register ispif subdev */
-	p_mctl->ispif_sdev = server_dev->ispif_device[0];
-	if (!p_mctl->ispif_sdev)
-		goto out;
-	v4l2_set_subdev_hostdata(p_mctl->ispif_sdev, p_mctl);
-
-	rc = 0;
-	return rc;
-out:
-	p_mctl->ispif_sdev = NULL;
-	return rc;
-}
-
diff --git a/drivers/media/video/msm/csi/msm_csi_register.h b/drivers/media/video/msm/csi/msm_csi_register.h
deleted file mode 100644
index 4214feb..0000000
--- a/drivers/media/video/msm/csi/msm_csi_register.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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.
- *
- */
-
-int msm_csi_register_subdevs(struct msm_cam_media_controller *p_mctl,
-	uint8_t csiphy_code_index, uint8_t csid_core_index,
-	struct msm_cam_server_dev *server_dev);
diff --git a/drivers/media/video/msm/csi/msm_csic.c b/drivers/media/video/msm/csi/msm_csic.c
deleted file mode 100644
index c34d9f7..0000000
--- a/drivers/media/video/msm/csi/msm_csic.c
+++ /dev/null
@@ -1,523 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/delay.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <mach/clk.h>
-#include <mach/board.h>
-#include <mach/camera.h>
-#include <media/msm_isp.h>
-#include "msm_csic.h"
-#include "msm.h"
-
-#define DBG_CSIC 0
-
-#define V4L2_IDENT_CSIC			50004
-/* MIPI	CSI controller registers */
-#define	MIPI_PHY_CONTROL		0x00000000
-#define	MIPI_PROTOCOL_CONTROL		0x00000004
-#define	MIPI_INTERRUPT_STATUS		0x00000008
-#define	MIPI_INTERRUPT_MASK		0x0000000C
-#define	MIPI_CAMERA_CNTL		0x00000024
-#define	MIPI_CALIBRATION_CONTROL	0x00000018
-#define	MIPI_PHY_D0_CONTROL2		0x00000038
-#define	MIPI_PHY_D1_CONTROL2		0x0000003C
-#define	MIPI_PHY_D2_CONTROL2		0x00000040
-#define	MIPI_PHY_D3_CONTROL2		0x00000044
-#define	MIPI_PHY_CL_CONTROL		0x00000048
-#define	MIPI_PHY_D0_CONTROL		0x00000034
-#define	MIPI_PHY_D1_CONTROL		0x00000020
-#define	MIPI_PHY_D2_CONTROL		0x0000002C
-#define	MIPI_PHY_D3_CONTROL		0x00000030
-#define	MIPI_PWR_CNTL			0x00000054
-
-/*
- * MIPI_PROTOCOL_CONTROL register bits to enable/disable the features of
- * CSI Rx Block
- */
-
-/* DPCM scheme */
-#define	MIPI_PROTOCOL_CONTROL_DPCM_SCHEME_SHFT			0x1e
-/* SW_RST to issue a SW reset to the CSI core */
-#define	MIPI_PROTOCOL_CONTROL_SW_RST_BMSK			0x8000000
-/* To Capture Long packet Header Info in MIPI_PROTOCOL_STATUS register */
-#define	MIPI_PROTOCOL_CONTROL_LONG_PACKET_HEADER_CAPTURE_BMSK	0x200000
-/* Data format for unpacking purpose */
-#define	MIPI_PROTOCOL_CONTROL_DATA_FORMAT_SHFT			0x13
-/* Enable decoding of payload based on data type filed of packet hdr */
-#define	MIPI_PROTOCOL_CONTROL_DECODE_ID_BMSK			0x40000
-/* Enable error correction on packet headers */
-#define	MIPI_PROTOCOL_CONTROL_ECC_EN_BMSK			0x20000
-
-/*
- * MIPI_CALIBRATION_CONTROL register contains control info for
- * calibration impledence controller
-*/
-
-/* Enable bit for calibration pad */
-#define	MIPI_CALIBRATION_CONTROL_SWCAL_CAL_EN_SHFT		0x16
-/* With SWCAL_STRENGTH_OVERRIDE_EN, SW_CAL_EN and MANUAL_OVERRIDE_EN
- * the hardware calibration circuitry associated with CAL_SW_HW_MODE
- * is bypassed
-*/
-#define	MIPI_CALIBRATION_CONTROL_SWCAL_STRENGTH_OVERRIDE_EN_SHFT	0x15
-/* To indicate the Calibration process is in the control of HW/SW */
-#define	MIPI_CALIBRATION_CONTROL_CAL_SW_HW_MODE_SHFT		0x14
-/* When this is set the strength value of the data and clk lane impedence
- * termination is updated with MANUAL_STRENGTH settings and calibration
- * sensing logic is idle.
-*/
-#define	MIPI_CALIBRATION_CONTROL_MANUAL_OVERRIDE_EN_SHFT	0x7
-
-/* Data lane0 control */
-/* T-hs Settle count value  for Rx */
-#define	MIPI_PHY_D0_CONTROL2_SETTLE_COUNT_SHFT			0x18
-/* Rx termination control */
-#define	MIPI_PHY_D0_CONTROL2_HS_TERM_IMP_SHFT			0x10
-/* LP Rx enable */
-#define	MIPI_PHY_D0_CONTROL2_LP_REC_EN_SHFT			0x4
-/*
- * Enable for error in sync sequence
- * 1 - one bit error in sync seq
- * 0 - requires all 8 bit correct seq
-*/
-#define	MIPI_PHY_D0_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
-
-/* Comments are same as D0 */
-#define	MIPI_PHY_D1_CONTROL2_SETTLE_COUNT_SHFT			0x18
-#define	MIPI_PHY_D1_CONTROL2_HS_TERM_IMP_SHFT			0x10
-#define	MIPI_PHY_D1_CONTROL2_LP_REC_EN_SHFT			0x4
-#define	MIPI_PHY_D1_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
-
-/* Comments are same as D0 */
-#define	MIPI_PHY_D2_CONTROL2_SETTLE_COUNT_SHFT			0x18
-#define	MIPI_PHY_D2_CONTROL2_HS_TERM_IMP_SHFT			0x10
-#define	MIPI_PHY_D2_CONTROL2_LP_REC_EN_SHFT			0x4
-#define	MIPI_PHY_D2_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
-
-/* Comments are same as D0 */
-#define	MIPI_PHY_D3_CONTROL2_SETTLE_COUNT_SHFT			0x18
-#define	MIPI_PHY_D3_CONTROL2_HS_TERM_IMP_SHFT			0x10
-#define	MIPI_PHY_D3_CONTROL2_LP_REC_EN_SHFT			0x4
-#define	MIPI_PHY_D3_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
-
-/* PHY_CL_CTRL programs the parameters of clk lane of CSIRXPHY */
-/* HS Rx termination control */
-#define	MIPI_PHY_CL_CONTROL_HS_TERM_IMP_SHFT			0x18
-/* Start signal for T-hs delay */
-#define	MIPI_PHY_CL_CONTROL_LP_REC_EN_SHFT			0x2
-
-/* PHY DATA lane 0 control */
-/*
- * HS RX equalizer strength control
- * 00 - 0db 01 - 3db 10 - 5db 11 - 7db
-*/
-#define	MIPI_PHY_D0_CONTROL_HS_REC_EQ_SHFT			0x1c
-/* PHY DATA lane 1 control */
-/* Shutdown signal for MIPI clk phy line */
-#define	MIPI_PHY_D1_CONTROL_MIPI_CLK_PHY_SHUTDOWNB_SHFT		0x9
-/* Shutdown signal for MIPI data phy line */
-#define	MIPI_PHY_D1_CONTROL_MIPI_DATA_PHY_SHUTDOWNB_SHFT	0x8
-
-#define MSM_AXI_QOS_PREVIEW 200000
-#define MSM_AXI_QOS_SNAPSHOT 200000
-#define MSM_AXI_QOS_RECORDING 200000
-
-#define MIPI_PWR_CNTL_EN	0x07
-#define MIPI_PWR_CNTL_DIS	0x0
-
-static int msm_csic_config(struct v4l2_subdev *sd,
-	struct msm_camera_csi_params *csic_params)
-{
-	int rc = 0;
-	uint32_t val = 0;
-	struct csic_device *csic_dev;
-	void __iomem *csicbase;
-	int i;
-
-	csic_dev = v4l2_get_subdevdata(sd);
-	csicbase = csic_dev->base;
-
-	/* Enable error correction for DATA lane. Applies to all data lanes */
-	msm_camera_io_w(0x4, csicbase + MIPI_PHY_CONTROL);
-
-	msm_camera_io_w(MIPI_PROTOCOL_CONTROL_SW_RST_BMSK,
-		csicbase + MIPI_PROTOCOL_CONTROL);
-
-	val = MIPI_PROTOCOL_CONTROL_LONG_PACKET_HEADER_CAPTURE_BMSK |
-		MIPI_PROTOCOL_CONTROL_DECODE_ID_BMSK |
-		MIPI_PROTOCOL_CONTROL_ECC_EN_BMSK;
-	val |= (uint32_t)(csic_params->data_format) <<
-		MIPI_PROTOCOL_CONTROL_DATA_FORMAT_SHFT;
-	val |= csic_params->dpcm_scheme <<
-		MIPI_PROTOCOL_CONTROL_DPCM_SCHEME_SHFT;
-	CDBG("%s MIPI_PROTOCOL_CONTROL val=0x%x\n", __func__, val);
-	msm_camera_io_w(val, csicbase + MIPI_PROTOCOL_CONTROL);
-
-	val = (csic_params->settle_cnt <<
-		MIPI_PHY_D0_CONTROL2_SETTLE_COUNT_SHFT) |
-		(0x0F << MIPI_PHY_D0_CONTROL2_HS_TERM_IMP_SHFT) |
-		(0x1 << MIPI_PHY_D0_CONTROL2_LP_REC_EN_SHFT) |
-		(0x1 << MIPI_PHY_D0_CONTROL2_ERR_SOT_HS_EN_SHFT);
-	CDBG("%s MIPI_PHY_D0_CONTROL2 val=0x%x\n", __func__, val);
-	for (i = 0; i < csic_params->lane_cnt; i++)
-		msm_camera_io_w(val, csicbase + MIPI_PHY_D0_CONTROL2 + i * 4);
-
-
-	val = (0x0F << MIPI_PHY_CL_CONTROL_HS_TERM_IMP_SHFT) |
-		(0x1 << MIPI_PHY_CL_CONTROL_LP_REC_EN_SHFT);
-	CDBG("%s MIPI_PHY_CL_CONTROL val=0x%x\n", __func__, val);
-	msm_camera_io_w(val, csicbase + MIPI_PHY_CL_CONTROL);
-
-	val = 0 << MIPI_PHY_D0_CONTROL_HS_REC_EQ_SHFT;
-	msm_camera_io_w(val, csicbase + MIPI_PHY_D0_CONTROL);
-
-	val = (0x1 << MIPI_PHY_D1_CONTROL_MIPI_CLK_PHY_SHUTDOWNB_SHFT) |
-		(0x1 << MIPI_PHY_D1_CONTROL_MIPI_DATA_PHY_SHUTDOWNB_SHFT);
-	CDBG("%s MIPI_PHY_D1_CONTROL val=0x%x\n", __func__, val);
-	msm_camera_io_w(val, csicbase + MIPI_PHY_D1_CONTROL);
-
-	msm_camera_io_w(0x00000000, csicbase + MIPI_PHY_D2_CONTROL);
-	msm_camera_io_w(0x00000000, csicbase + MIPI_PHY_D3_CONTROL);
-
-	/* program number of lanes and lane mapping */
-	switch (csic_params->lane_cnt) {
-	case 1:
-		msm_camera_io_w(csic_params->lane_assign << 8 | 0x4,
-			csicbase + MIPI_CAMERA_CNTL);
-		break;
-	case 2:
-		msm_camera_io_w(csic_params->lane_assign << 8 | 0x5,
-			csicbase + MIPI_CAMERA_CNTL);
-		break;
-	case 3:
-		msm_camera_io_w(csic_params->lane_assign << 8 | 0x6,
-			csicbase + MIPI_CAMERA_CNTL);
-		break;
-	case 4:
-		msm_camera_io_w(csic_params->lane_assign << 8 | 0x7,
-			csicbase + MIPI_CAMERA_CNTL);
-		break;
-	}
-
-	msm_camera_io_w(0xF077F3C0, csicbase + MIPI_INTERRUPT_MASK);
-	/*clear IRQ bits*/
-	msm_camera_io_w(0xF077F3C0, csicbase + MIPI_INTERRUPT_STATUS);
-
-	return rc;
-}
-
-static irqreturn_t msm_csic_irq(int irq_num, void *data)
-{
-	uint32_t irq;
-	struct csic_device *csic_dev = data;
-
-	pr_info("msm_csic_irq: %x\n", (unsigned int)csic_dev->base);
-	irq = msm_camera_io_r(csic_dev->base + MIPI_INTERRUPT_STATUS);
-	pr_info("%s MIPI_INTERRUPT_STATUS = 0x%x 0x%x\n",
-		__func__, irq,
-		msm_camera_io_r(csic_dev->base + MIPI_PROTOCOL_CONTROL));
-	msm_camera_io_w(irq, csic_dev->base + MIPI_INTERRUPT_STATUS);
-
-	/* TODO: Needs to send this info to upper layers */
-	if ((irq >> 19) & 0x1)
-		pr_info("Unsupported packet format is received\n");
-	return IRQ_HANDLED;
-}
-
-static int msm_csic_subdev_g_chip_ident(struct v4l2_subdev *sd,
-			struct v4l2_dbg_chip_ident *chip)
-{
-	BUG_ON(!chip);
-	chip->ident = V4L2_IDENT_CSIC;
-	chip->revision = 0;
-	return 0;
-}
-
-static struct msm_cam_clk_info csic_8x_clk_info[] = {
-	{"csi_src_clk", 384000000},
-	{"csi_clk", -1},
-	{"csi_vfe_clk", -1},
-	{"csi_pclk", -1},
-};
-
-static struct msm_cam_clk_info csic_7x_clk_info[] = {
-	{"csi_clk", 400000000},
-	{"csi_vfe_clk", -1},
-	{"csi_pclk", -1},
-};
-
-static int msm_csic_init(struct v4l2_subdev *sd)
-{
-	int rc = 0;
-	struct csic_device *csic_dev;
-	csic_dev = v4l2_get_subdevdata(sd);
-	if (csic_dev == NULL) {
-		rc = -ENOMEM;
-		return rc;
-	}
-
-	csic_dev->base = ioremap(csic_dev->mem->start,
-		resource_size(csic_dev->mem));
-	if (!csic_dev->base) {
-		rc = -ENOMEM;
-		return rc;
-	}
-
-	csic_dev->hw_version = CSIC_8X;
-	rc = msm_cam_clk_enable(&csic_dev->pdev->dev, csic_8x_clk_info,
-		csic_dev->csic_clk, ARRAY_SIZE(csic_8x_clk_info), 1);
-	if (rc < 0) {
-		csic_dev->hw_version = CSIC_7X;
-		rc = msm_cam_clk_enable(&csic_dev->pdev->dev, csic_7x_clk_info,
-			csic_dev->csic_clk, ARRAY_SIZE(csic_7x_clk_info), 1);
-		if (rc < 0) {
-			csic_dev->hw_version = 0;
-			iounmap(csic_dev->base);
-			csic_dev->base = NULL;
-			return rc;
-		}
-	}
-	if (csic_dev->hw_version == CSIC_7X)
-		msm_camio_vfe_blk_reset_3();
-
-#if DBG_CSIC
-	enable_irq(csic_dev->irq->start);
-#endif
-
-	return 0;
-}
-
-static void msm_csic_disable(struct v4l2_subdev *sd)
-{
-	uint32_t val;
-	struct csic_device *csic_dev;
-	csic_dev = v4l2_get_subdevdata(sd);
-
-	val = 0x0;
-	if (csic_dev->base != NULL) {
-		CDBG("%s MIPI_PHY_D0_CONTROL2 val=0x%x\n", __func__, val);
-		msm_camera_io_w(val, csic_dev->base + MIPI_PHY_D0_CONTROL2);
-		msm_camera_io_w(val, csic_dev->base + MIPI_PHY_D1_CONTROL2);
-		msm_camera_io_w(val, csic_dev->base + MIPI_PHY_D2_CONTROL2);
-		msm_camera_io_w(val, csic_dev->base + MIPI_PHY_D3_CONTROL2);
-		CDBG("%s MIPI_PHY_CL_CONTROL val=0x%x\n", __func__, val);
-		msm_camera_io_w(val, csic_dev->base + MIPI_PHY_CL_CONTROL);
-		msleep(20);
-		val = msm_camera_io_r(csic_dev->base + MIPI_PHY_D1_CONTROL);
-		val &=
-		~((0x1 << MIPI_PHY_D1_CONTROL_MIPI_CLK_PHY_SHUTDOWNB_SHFT)
-		|(0x1 << MIPI_PHY_D1_CONTROL_MIPI_DATA_PHY_SHUTDOWNB_SHFT));
-		CDBG("%s MIPI_PHY_D1_CONTROL val=0x%x\n", __func__, val);
-		msm_camera_io_w(val, csic_dev->base + MIPI_PHY_D1_CONTROL);
-		usleep_range(5000, 6000);
-		msm_camera_io_w(0x0, csic_dev->base + MIPI_INTERRUPT_MASK);
-		msm_camera_io_w(0x0, csic_dev->base + MIPI_INTERRUPT_STATUS);
-		msm_camera_io_w(MIPI_PROTOCOL_CONTROL_SW_RST_BMSK,
-			csic_dev->base + MIPI_PROTOCOL_CONTROL);
-
-		msm_camera_io_w(0xE400, csic_dev->base + MIPI_CAMERA_CNTL);
-	}
-}
-
-static int msm_csic_release(struct v4l2_subdev *sd)
-{
-	struct csic_device *csic_dev;
-	csic_dev = v4l2_get_subdevdata(sd);
-
-	msm_csic_disable(sd);
-#if DBG_CSIC
-	disable_irq(csic_dev->irq->start);
-#endif
-
-	if (csic_dev->hw_version == CSIC_8X) {
-		msm_cam_clk_enable(&csic_dev->pdev->dev, csic_8x_clk_info,
-			csic_dev->csic_clk, ARRAY_SIZE(csic_8x_clk_info), 0);
-	} else if (csic_dev->hw_version == CSIC_7X) {
-		msm_cam_clk_enable(&csic_dev->pdev->dev, csic_7x_clk_info,
-			csic_dev->csic_clk, ARRAY_SIZE(csic_7x_clk_info), 0);
-	}
-
-	iounmap(csic_dev->base);
-	csic_dev->base = NULL;
-	return 0;
-}
-
-static long msm_csic_cmd(struct v4l2_subdev *sd, void *arg)
-{
-	long rc = 0;
-	struct csic_cfg_data cdata;
-	struct msm_camera_csi_params csic_params;
-	if (copy_from_user(&cdata,
-		(void *)arg,
-		sizeof(struct csic_cfg_data)))
-		return -EFAULT;
-	CDBG("%s cfgtype = %d\n", __func__, cdata.cfgtype);
-	switch (cdata.cfgtype) {
-	case CSIC_INIT:
-		rc = msm_csic_init(sd);
-		break;
-	case CSIC_CFG:
-		if (copy_from_user(&csic_params,
-			(void *)cdata.csic_params,
-			sizeof(struct msm_camera_csi_params)))
-			return -EFAULT;
-		rc = msm_csic_config(sd, &csic_params);
-		break;
-	default:
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
-
-static long msm_csic_subdev_ioctl(struct v4l2_subdev *sd,
-			unsigned int cmd, void *arg)
-{
-	switch (cmd) {
-	case VIDIOC_MSM_CSIC_CFG:
-		return msm_csic_cmd(sd, arg);
-	case VIDIOC_MSM_CSIC_RELEASE:
-		return msm_csic_release(sd);
-	default:
-		return -ENOIOCTLCMD;
-	}
-}
-
-static struct v4l2_subdev_core_ops msm_csic_subdev_core_ops = {
-	.g_chip_ident = &msm_csic_subdev_g_chip_ident,
-	.ioctl = &msm_csic_subdev_ioctl,
-};
-
-static const struct v4l2_subdev_ops msm_csic_subdev_ops = {
-	.core = &msm_csic_subdev_core_ops,
-};
-
-static const struct v4l2_subdev_internal_ops msm_csic_internal_ops;
-
-static int __devinit csic_probe(struct platform_device *pdev)
-{
-	struct csic_device *new_csic_dev;
-	int rc = 0;
-	struct msm_cam_subdev_info sd_info;
-
-	CDBG("%s: device id = %d\n", __func__, pdev->id);
-	new_csic_dev = kzalloc(sizeof(struct csic_device), GFP_KERNEL);
-	if (!new_csic_dev) {
-		pr_err("%s: no enough memory\n", __func__);
-		return -ENOMEM;
-	}
-
-	v4l2_subdev_init(&new_csic_dev->subdev, &msm_csic_subdev_ops);
-	new_csic_dev->subdev.internal_ops = &msm_csic_internal_ops;
-	new_csic_dev->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-	snprintf(new_csic_dev->subdev.name,
-			ARRAY_SIZE(new_csic_dev->subdev.name), "msm_csic");
-	v4l2_set_subdevdata(&new_csic_dev->subdev, new_csic_dev);
-	platform_set_drvdata(pdev, &new_csic_dev->subdev);
-	mutex_init(&new_csic_dev->mutex);
-
-	new_csic_dev->mem = platform_get_resource_byname(pdev,
-					IORESOURCE_MEM, "csic");
-	if (!new_csic_dev->mem) {
-		pr_err("%s: no mem resource?\n", __func__);
-		rc = -ENODEV;
-		goto csic_no_resource;
-	}
-	new_csic_dev->irq = platform_get_resource_byname(pdev,
-					IORESOURCE_IRQ, "csic");
-	if (!new_csic_dev->irq) {
-		pr_err("%s: no irq resource?\n", __func__);
-		rc = -ENODEV;
-		goto csic_no_resource;
-	}
-	new_csic_dev->io = request_mem_region(new_csic_dev->mem->start,
-		resource_size(new_csic_dev->mem), pdev->name);
-	if (!new_csic_dev->io) {
-		pr_err("%s: no valid mem region\n", __func__);
-		rc = -EBUSY;
-		goto csic_no_resource;
-	}
-
-	rc = request_irq(new_csic_dev->irq->start, msm_csic_irq,
-		IRQF_TRIGGER_HIGH, "csic", new_csic_dev);
-	if (rc < 0) {
-		release_mem_region(new_csic_dev->mem->start,
-			resource_size(new_csic_dev->mem));
-		pr_err("%s: irq request fail\n", __func__);
-		rc = -EBUSY;
-		goto csic_no_resource;
-	}
-	disable_irq(new_csic_dev->irq->start);
-
-	new_csic_dev->pdev = pdev;
-
-	rc = msm_cam_clk_enable(&new_csic_dev->pdev->dev, &csic_7x_clk_info[2],
-				new_csic_dev->csic_clk, 1, 1);
-	new_csic_dev->base = ioremap(new_csic_dev->mem->start,
-		resource_size(new_csic_dev->mem));
-	if (!new_csic_dev->base) {
-		rc = -ENOMEM;
-		return rc;
-	}
-
-	msm_camera_io_w(MIPI_PWR_CNTL_DIS, new_csic_dev->base + MIPI_PWR_CNTL);
-
-	rc = msm_cam_clk_enable(&new_csic_dev->pdev->dev, &csic_7x_clk_info[2],
-				new_csic_dev->csic_clk, 1, 0);
-
-	iounmap(new_csic_dev->base);
-	new_csic_dev->base = NULL;
-	sd_info.sdev_type = CSIC_DEV;
-	sd_info.sd_index = pdev->id;
-	sd_info.irq_num = new_csic_dev->irq->start;
-	msm_cam_register_subdev_node(
-		&new_csic_dev->subdev, &sd_info);
-
-	media_entity_init(&new_csic_dev->subdev.entity, 0, NULL, 0);
-	new_csic_dev->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
-	new_csic_dev->subdev.entity.group_id = CSIC_DEV;
-	new_csic_dev->subdev.entity.name = pdev->name;
-	new_csic_dev->subdev.entity.revision =
-		new_csic_dev->subdev.devnode->num;
-	return 0;
-
-csic_no_resource:
-	mutex_destroy(&new_csic_dev->mutex);
-	kfree(new_csic_dev);
-	return 0;
-}
-
-static struct platform_driver csic_driver = {
-	.probe = csic_probe,
-	.driver = {
-		.name = MSM_CSIC_DRV_NAME,
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init msm_csic_init_module(void)
-{
-	return platform_driver_register(&csic_driver);
-}
-
-static void __exit msm_csic_exit_module(void)
-{
-	platform_driver_unregister(&csic_driver);
-}
-
-module_init(msm_csic_init_module);
-module_exit(msm_csic_exit_module);
-MODULE_DESCRIPTION("MSM csic driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/csi/msm_csic.h b/drivers/media/video/msm/csi/msm_csic.h
deleted file mode 100644
index c8f1f99..0000000
--- a/drivers/media/video/msm/csi/msm_csic.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 MSM_CSIC_H
-#define MSM_CSIC_H
-
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <media/v4l2-subdev.h>
-
-#define CSIC_7X 0x1
-#define CSIC_8X (0x1 << 1)
-
-struct csic_device {
-	struct platform_device *pdev;
-	struct v4l2_subdev subdev;
-	struct resource *mem;
-	struct resource *irq;
-	struct resource *io;
-	void __iomem *base;
-	struct mutex mutex;
-	uint32_t hw_version;
-
-	struct clk *csic_clk[5];
-};
-
-#define VIDIOC_MSM_CSIC_CFG \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 4, struct csic_cfg_data*)
-
-#define VIDIOC_MSM_CSIC_RELEASE \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 5, struct v4l2_subdev*)
-
-#endif
diff --git a/drivers/media/video/msm/csi/msm_csic_register.c b/drivers/media/video/msm/csi/msm_csic_register.c
deleted file mode 100644
index af50101..0000000
--- a/drivers/media/video/msm/csi/msm_csic_register.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/device.h>
-#include "msm.h"
-#include "msm_csi_register.h"
-
-int msm_csi_register_subdevs(struct msm_cam_media_controller *p_mctl,
-	uint8_t csiphy_code_index, uint8_t csid_core_index,
-	struct msm_cam_server_dev *server_dev)
-{
-	int rc = -ENODEV;
-
-	p_mctl->csic_sdev = server_dev->csic_device[csid_core_index];
-	if (!p_mctl->csic_sdev)
-		goto out;
-	v4l2_set_subdev_hostdata(p_mctl->csic_sdev, p_mctl);
-
-	rc = 0;
-	p_mctl->ispif_sdev = NULL;
-	return rc;
-
-out:
-	p_mctl->ispif_sdev = NULL;
-	return rc;
-}
-
diff --git a/drivers/media/video/msm/csi/msm_csid.c b/drivers/media/video/msm/csi/msm_csid.c
deleted file mode 100644
index 535ea0a..0000000
--- a/drivers/media/video/msm/csi/msm_csid.c
+++ /dev/null
@@ -1,649 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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/delay.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <mach/board.h>
-#include <mach/camera.h>
-#include <media/msm_isp.h>
-#include "msm_csid.h"
-#include "msm_csid_hwreg.h"
-#include "msm.h"
-#include "msm_cam_server.h"
-
-#define V4L2_IDENT_CSID                            50002
-#define CSID_VERSION_V2                      0x02000011
-#define CSID_VERSION_V3                      0x30000000
-
-#define DBG_CSID 0
-
-#define TRUE   1
-#define FALSE  0
-
-static int msm_csid_cid_lut(
-	struct msm_camera_csid_lut_params *csid_lut_params,
-	void __iomem *csidbase)
-{
-	int rc = 0, i = 0;
-	uint32_t val = 0;
-
-	if (!csid_lut_params) {
-		pr_err("%s:%d csid_lut_params NULL\n", __func__, __LINE__);
-		return -EINVAL;
-	}
-	for (i = 0; i < csid_lut_params->num_cid && i < 16; i++) {
-		CDBG("%s lut params num_cid = %d, cid = %d, dt = %x, df = %d\n",
-			__func__,
-			csid_lut_params->num_cid,
-			csid_lut_params->vc_cfg[i].cid,
-			csid_lut_params->vc_cfg[i].dt,
-			csid_lut_params->vc_cfg[i].decode_format);
-		if (csid_lut_params->vc_cfg[i].dt < 0x12 ||
-			csid_lut_params->vc_cfg[i].dt > 0x37) {
-			CDBG("%s: unsupported data type 0x%x\n",
-				 __func__, csid_lut_params->vc_cfg[i].dt);
-			return rc;
-		}
-		val = msm_camera_io_r(csidbase + CSID_CID_LUT_VC_0_ADDR +
-			(csid_lut_params->vc_cfg[i].cid >> 2) * 4)
-			& ~(0xFF << ((csid_lut_params->vc_cfg[i].cid % 4) * 8));
-		val |= (csid_lut_params->vc_cfg[i].dt <<
-			((csid_lut_params->vc_cfg[i].cid % 4) * 8));
-		msm_camera_io_w(val, csidbase + CSID_CID_LUT_VC_0_ADDR +
-			(csid_lut_params->vc_cfg[i].cid >> 2) * 4);
-
-		val = (csid_lut_params->vc_cfg[i].decode_format << 4) | 0x3;
-		msm_camera_io_w(val, csidbase + CSID_CID_n_CFG_ADDR +
-			(csid_lut_params->vc_cfg[i].cid * 4));
-	}
-	return rc;
-}
-
-#if DBG_CSID
-static void msm_csid_set_debug_reg(void __iomem *csidbase,
-	struct msm_camera_csid_params *csid_params)
-{
-	uint32_t val = 0;
-	val = ((1 << csid_params->lane_cnt) - 1) << 20;
-	msm_camera_io_w(0x7f010800 | val, csidbase + CSID_IRQ_MASK_ADDR);
-	msm_camera_io_w(0x7f010800 | val, csidbase + CSID_IRQ_CLEAR_CMD_ADDR);
-}
-#else
-static void msm_csid_set_debug_reg(void __iomem *csidbase,
-	struct msm_camera_csid_params *csid_params) {}
-#endif
-
-static int msm_csid_config(struct csid_device *csid_dev,
-	struct msm_camera_csid_params *csid_params)
-{
-	int rc = 0;
-	uint32_t val = 0;
-	void __iomem *csidbase;
-	csidbase = csid_dev->base;
-	if (!csidbase || !csid_params) {
-		pr_err("%s:%d csidbase %p, csid params %p\n", __func__,
-			__LINE__, csidbase, csid_params);
-		return -EINVAL;
-	}
-
-	CDBG("%s csid_params, lane_cnt = %d, lane_assign = %x, phy sel = %d\n",
-		__func__,
-		csid_params->lane_cnt,
-		csid_params->lane_assign,
-		csid_params->phy_sel);
-	val = csid_params->lane_cnt - 1;
-	val |= csid_params->lane_assign << CSID_DL_INPUT_SEL_SHIFT;
-	if (csid_dev->hw_version < 0x30000000) {
-		val |= (0xF << 10);
-		msm_camera_io_w(val, csidbase + CSID_CORE_CTRL_0_ADDR);
-	} else {
-		msm_camera_io_w(val, csidbase + CSID_CORE_CTRL_0_ADDR);
-		val = csid_params->phy_sel << CSID_PHY_SEL_SHIFT;
-		val |= 0xF;
-		msm_camera_io_w(val, csidbase + CSID_CORE_CTRL_1_ADDR);
-	}
-
-	rc = msm_csid_cid_lut(&csid_params->lut_params, csidbase);
-	if (rc < 0)
-		return rc;
-
-	msm_csid_set_debug_reg(csidbase, csid_params);
-	return rc;
-}
-
-static irqreturn_t msm_csid_irq(int irq_num, void *data)
-{
-	uint32_t irq;
-	struct csid_device *csid_dev = data;
-	if (!csid_dev) {
-		pr_err("%s:%d csid_dev NULL\n", __func__, __LINE__);
-		return IRQ_HANDLED;
-	}
-	irq = msm_camera_io_r(csid_dev->base + CSID_IRQ_STATUS_ADDR);
-	CDBG("%s CSID%d_IRQ_STATUS_ADDR = 0x%x\n",
-		 __func__, csid_dev->pdev->id, irq);
-	if (irq & (0x1 << CSID_RST_DONE_IRQ_BITSHIFT))
-			complete(&csid_dev->reset_complete);
-	msm_camera_io_w(irq, csid_dev->base + CSID_IRQ_CLEAR_CMD_ADDR);
-	return IRQ_HANDLED;
-}
-
-int msm_csid_irq_routine(struct v4l2_subdev *sd, u32 status, bool *handled)
-{
-	struct csid_device *csid_dev = v4l2_get_subdevdata(sd);
-	irqreturn_t ret;
-	CDBG("%s E\n", __func__);
-	ret = msm_csid_irq(csid_dev->irq->start, csid_dev);
-	*handled = TRUE;
-	return 0;
-}
-
-static void msm_csid_reset(struct csid_device *csid_dev)
-{
-	msm_camera_io_w(CSID_RST_STB_ALL, csid_dev->base + CSID_RST_CMD_ADDR);
-	wait_for_completion_interruptible(&csid_dev->reset_complete);
-	return;
-}
-
-static int msm_csid_subdev_g_chip_ident(struct v4l2_subdev *sd,
-			struct v4l2_dbg_chip_ident *chip)
-{
-	BUG_ON(!chip);
-	chip->ident = V4L2_IDENT_CSID;
-	chip->revision = 0;
-	return 0;
-}
-
-static struct msm_cam_clk_info csid_8960_clk_info[] = {
-	{"csi_src_clk", 177780000},
-	{"csi_clk", -1},
-	{"csi_phy_clk", -1},
-	{"csi_pclk", -1},
-};
-
-static struct msm_cam_clk_info csid0_8974_clk_info[] = {
-	{"csi0_ahb_clk", -1},
-	{"csi0_src_clk", 200000000},
-	{"csi0_clk", -1},
-	{"csi0_phy_clk", -1},
-	{"csi0_pix_clk", -1},
-	{"csi0_rdi_clk", -1},
-};
-
-static struct msm_cam_clk_info csid1_8974_clk_info[] = {
-	{"csi1_ahb_clk", -1},
-	{"csi1_src_clk", 200000000},
-	{"csi1_clk", -1},
-	{"csi1_phy_clk", -1},
-	{"csi1_pix_clk", -1},
-	{"csi1_rdi_clk", -1},
-};
-
-static struct msm_cam_clk_info csid2_8974_clk_info[] = {
-	{"csi2_ahb_clk", -1},
-	{"csi2_src_clk", 200000000},
-	{"csi2_clk", -1},
-	{"csi2_phy_clk", -1},
-	{"csi2_pix_clk", -1},
-	{"csi2_rdi_clk", -1},
-};
-
-static struct msm_cam_clk_info csid3_8974_clk_info[] = {
-	{"csi3_ahb_clk", -1},
-	{"csi3_src_clk", 200000000},
-	{"csi3_clk", -1},
-	{"csi3_phy_clk", -1},
-	{"csi3_pix_clk", -1},
-	{"csi3_rdi_clk", -1},
-};
-
-static struct msm_cam_clk_setting csid_8974_clk_info[] = {
-	{&csid0_8974_clk_info[0], ARRAY_SIZE(csid0_8974_clk_info)},
-	{&csid1_8974_clk_info[0], ARRAY_SIZE(csid1_8974_clk_info)},
-	{&csid2_8974_clk_info[0], ARRAY_SIZE(csid2_8974_clk_info)},
-	{&csid3_8974_clk_info[0], ARRAY_SIZE(csid3_8974_clk_info)},
-};
-
-static struct camera_vreg_t csid_8960_vreg_info[] = {
-	{"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
-};
-
-static struct camera_vreg_t csid_8974_vreg_info[] = {
-	{"mipi_csi_vdd", REG_LDO, 1800000, 1800000, 12000},
-};
-
-static int msm_csid_init(struct csid_device *csid_dev, uint32_t *csid_version)
-{
-	int rc = 0;
-	uint8_t core_id = 0;
-
-	if (!csid_version) {
-		pr_err("%s:%d csid_version NULL\n", __func__, __LINE__);
-		rc = -EINVAL;
-		return rc;
-	}
-
-	if (csid_dev->csid_state == CSID_POWER_UP) {
-		pr_err("%s: csid invalid state %d\n", __func__,
-			csid_dev->csid_state);
-		rc = -EINVAL;
-		return rc;
-	}
-
-	csid_dev->base = ioremap(csid_dev->mem->start,
-		resource_size(csid_dev->mem));
-	if (!csid_dev->base) {
-		pr_err("%s csid_dev->base NULL\n", __func__);
-		rc = -ENOMEM;
-		return rc;
-	}
-
-	if (CSID_VERSION <= CSID_VERSION_V2) {
-		rc = msm_camera_config_vreg(&csid_dev->pdev->dev,
-			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
-			NULL, 0, &csid_dev->csi_vdd, 1);
-		if (rc < 0) {
-			pr_err("%s: regulator on failed\n", __func__);
-			goto vreg_config_failed;
-		}
-
-		rc = msm_camera_enable_vreg(&csid_dev->pdev->dev,
-			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
-			NULL, 0, &csid_dev->csi_vdd, 1);
-		if (rc < 0) {
-			pr_err("%s: regulator enable failed\n", __func__);
-			goto vreg_enable_failed;
-		}
-
-		rc = msm_cam_clk_enable(&csid_dev->pdev->dev,
-			csid_8960_clk_info, csid_dev->csid_clk,
-			ARRAY_SIZE(csid_8960_clk_info), 1);
-		if (rc < 0) {
-			pr_err("%s: clock enable failed\n", __func__);
-			goto clk_enable_failed;
-		}
-	} else if (CSID_VERSION == CSID_VERSION_V3) {
-		rc = msm_camera_config_vreg(&csid_dev->pdev->dev,
-			csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
-			NULL, 0, &csid_dev->csi_vdd, 1);
-		if (rc < 0) {
-			pr_err("%s: regulator on failed\n", __func__);
-			goto vreg_config_failed;
-		}
-
-		rc = msm_camera_enable_vreg(&csid_dev->pdev->dev,
-			csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
-			NULL, 0, &csid_dev->csi_vdd, 1);
-		if (rc < 0) {
-			pr_err("%s: regulator enable failed\n", __func__);
-			goto vreg_enable_failed;
-		}
-
-		rc = msm_cam_clk_enable(&csid_dev->pdev->dev,
-			csid_8974_clk_info[0].clk_info, csid_dev->csid0_clk,
-			csid_8974_clk_info[0].num_clk_info, 1);
-		if (rc < 0) {
-			pr_err("%s: clock enable failed\n", __func__);
-			goto csid0_clk_enable_failed;
-		}
-		core_id = csid_dev->pdev->id;
-		if (core_id) {
-			rc = msm_cam_clk_enable(&csid_dev->pdev->dev,
-				csid_8974_clk_info[core_id].clk_info,
-				csid_dev->csid_clk,
-				csid_8974_clk_info[core_id].num_clk_info, 1);
-			if (rc < 0) {
-				pr_err("%s: clock enable failed\n",
-					__func__);
-				goto clk_enable_failed;
-			}
-		}
-	}
-
-	csid_dev->hw_version =
-		msm_camera_io_r(csid_dev->base + CSID_HW_VERSION_ADDR);
-	*csid_version = csid_dev->hw_version;
-
-	init_completion(&csid_dev->reset_complete);
-
-	enable_irq(csid_dev->irq->start);
-
-	msm_csid_reset(csid_dev);
-	csid_dev->csid_state = CSID_POWER_UP;
-	return rc;
-
-clk_enable_failed:
-	if (CSID_VERSION == CSID_VERSION_V3) {
-		msm_cam_clk_enable(&csid_dev->pdev->dev,
-			csid_8974_clk_info[0].clk_info, csid_dev->csid0_clk,
-			csid_8974_clk_info[0].num_clk_info, 0);
-	}
-csid0_clk_enable_failed:
-	if (CSID_VERSION <= CSID_VERSION_V2) {
-		msm_camera_enable_vreg(&csid_dev->pdev->dev,
-			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
-			NULL, 0, &csid_dev->csi_vdd, 0);
-	} else if (CSID_VERSION == CSID_VERSION_V3) {
-		msm_camera_enable_vreg(&csid_dev->pdev->dev,
-			csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
-			NULL, 0, &csid_dev->csi_vdd, 0);
-	}
-vreg_enable_failed:
-	if (CSID_VERSION <= CSID_VERSION_V2) {
-		msm_camera_config_vreg(&csid_dev->pdev->dev,
-			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
-			NULL, 0, &csid_dev->csi_vdd, 0);
-	} else if (CSID_VERSION == CSID_VERSION_V3) {
-		msm_camera_config_vreg(&csid_dev->pdev->dev,
-			csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
-			NULL, 0, &csid_dev->csi_vdd, 0);
-	}
-vreg_config_failed:
-	iounmap(csid_dev->base);
-	csid_dev->base = NULL;
-	return rc;
-}
-
-static int msm_csid_release(struct csid_device *csid_dev)
-{
-	uint32_t irq;
-	uint8_t core_id = 0;
-
-	if (csid_dev->csid_state != CSID_POWER_UP) {
-		pr_err("%s: csid invalid state %d\n", __func__,
-			csid_dev->csid_state);
-		return -EINVAL;
-	}
-
-	irq = msm_camera_io_r(csid_dev->base + CSID_IRQ_STATUS_ADDR);
-	msm_camera_io_w(irq, csid_dev->base + CSID_IRQ_CLEAR_CMD_ADDR);
-	msm_camera_io_w(0, csid_dev->base + CSID_IRQ_MASK_ADDR);
-
-	disable_irq(csid_dev->irq->start);
-
-	if (csid_dev->hw_version <= CSID_VERSION_V2) {
-		msm_cam_clk_enable(&csid_dev->pdev->dev, csid_8960_clk_info,
-			csid_dev->csid_clk, ARRAY_SIZE(csid_8960_clk_info), 0);
-
-		msm_camera_enable_vreg(&csid_dev->pdev->dev,
-			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
-			NULL, 0, &csid_dev->csi_vdd, 0);
-
-		msm_camera_config_vreg(&csid_dev->pdev->dev,
-			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
-			NULL, 0, &csid_dev->csi_vdd, 0);
-	} else if (csid_dev->hw_version == CSID_VERSION_V3) {
-		core_id = csid_dev->pdev->id;
-		if (core_id)
-			msm_cam_clk_enable(&csid_dev->pdev->dev,
-				csid_8974_clk_info[core_id].clk_info,
-				csid_dev->csid_clk,
-				csid_8974_clk_info[core_id].num_clk_info, 0);
-
-		msm_cam_clk_enable(&csid_dev->pdev->dev,
-			csid_8974_clk_info[0].clk_info, csid_dev->csid0_clk,
-			csid_8974_clk_info[0].num_clk_info, 0);
-
-		msm_camera_enable_vreg(&csid_dev->pdev->dev,
-			csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
-			NULL, 0, &csid_dev->csi_vdd, 0);
-
-		msm_camera_config_vreg(&csid_dev->pdev->dev,
-			csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info),
-			NULL, 0, &csid_dev->csi_vdd, 0);
-	}
-
-	iounmap(csid_dev->base);
-	csid_dev->base = NULL;
-	csid_dev->csid_state = CSID_POWER_DOWN;
-	return 0;
-}
-
-static long msm_csid_cmd(struct csid_device *csid_dev, void *arg)
-{
-	int rc = 0;
-	struct csid_cfg_data cdata;
-
-	if (!csid_dev) {
-		pr_err("%s:%d csid_dev NULL\n", __func__, __LINE__);
-		return -EINVAL;
-	}
-
-	if (copy_from_user(&cdata,
-		(void *)arg,
-		sizeof(struct csid_cfg_data))) {
-		pr_err("%s: %d failed\n", __func__, __LINE__);
-		return -EFAULT;
-	}
-	CDBG("%s cfgtype = %d\n", __func__, cdata.cfgtype);
-	switch (cdata.cfgtype) {
-	case CSID_INIT:
-		rc = msm_csid_init(csid_dev, &cdata.cfg.csid_version);
-		if (copy_to_user((void *)arg,
-			&cdata,
-			sizeof(struct csid_cfg_data))) {
-			pr_err("%s: %d failed\n", __func__, __LINE__);
-			rc = -EFAULT;
-		}
-		break;
-	case CSID_CFG: {
-		struct msm_camera_csid_params csid_params;
-		struct msm_camera_csid_vc_cfg *vc_cfg = NULL;
-		if (copy_from_user(&csid_params,
-			(void *)cdata.cfg.csid_params,
-			sizeof(struct msm_camera_csid_params))) {
-			pr_err("%s: %d failed\n", __func__, __LINE__);
-			rc = -EFAULT;
-			break;
-		}
-		vc_cfg = kzalloc(csid_params.lut_params.num_cid *
-			sizeof(struct msm_camera_csid_vc_cfg),
-			GFP_KERNEL);
-		if (!vc_cfg) {
-			pr_err("%s: %d failed\n", __func__, __LINE__);
-			rc = -ENOMEM;
-			break;
-		}
-		if (copy_from_user(vc_cfg,
-			(void *)csid_params.lut_params.vc_cfg,
-			(csid_params.lut_params.num_cid *
-			sizeof(struct msm_camera_csid_vc_cfg)))) {
-			pr_err("%s: %d failed\n", __func__, __LINE__);
-			kfree(vc_cfg);
-			rc = -EFAULT;
-			break;
-		}
-		csid_params.lut_params.vc_cfg = vc_cfg;
-		rc = msm_csid_config(csid_dev, &csid_params);
-		kfree(vc_cfg);
-		break;
-	}
-	default:
-		pr_err("%s: %d failed\n", __func__, __LINE__);
-		rc = -ENOIOCTLCMD;
-		break;
-	}
-	return rc;
-}
-
-static long msm_csid_subdev_ioctl(struct v4l2_subdev *sd,
-			unsigned int cmd, void *arg)
-{
-	int rc = -ENOIOCTLCMD;
-	struct csid_device *csid_dev = v4l2_get_subdevdata(sd);
-	mutex_lock(&csid_dev->mutex);
-	switch (cmd) {
-	case VIDIOC_MSM_CSID_CFG:
-		rc = msm_csid_cmd(csid_dev, arg);
-		break;
-	case VIDIOC_MSM_CSID_RELEASE:
-		rc = msm_csid_release(csid_dev);
-		break;
-	default:
-		pr_err("%s: command not found\n", __func__);
-	}
-	mutex_unlock(&csid_dev->mutex);
-	return rc;
-}
-
-static const struct v4l2_subdev_internal_ops msm_csid_internal_ops;
-
-static struct v4l2_subdev_core_ops msm_csid_subdev_core_ops = {
-	.g_chip_ident = &msm_csid_subdev_g_chip_ident,
-	.ioctl = &msm_csid_subdev_ioctl,
-	.interrupt_service_routine = msm_csid_irq_routine,
-};
-
-static const struct v4l2_subdev_ops msm_csid_subdev_ops = {
-	.core = &msm_csid_subdev_core_ops,
-};
-
-static int __devinit csid_probe(struct platform_device *pdev)
-{
-	struct csid_device *new_csid_dev;
-	struct msm_cam_subdev_info sd_info;
-	struct intr_table_entry irq_req;
-
-	int rc = 0;
-	CDBG("%s:%d called\n", __func__, __LINE__);
-	new_csid_dev = kzalloc(sizeof(struct csid_device), GFP_KERNEL);
-	if (!new_csid_dev) {
-		pr_err("%s: no enough memory\n", __func__);
-		return -ENOMEM;
-	}
-
-	v4l2_subdev_init(&new_csid_dev->subdev, &msm_csid_subdev_ops);
-	new_csid_dev->subdev.internal_ops = &msm_csid_internal_ops;
-	new_csid_dev->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-	snprintf(new_csid_dev->subdev.name,
-			ARRAY_SIZE(new_csid_dev->subdev.name), "msm_csid");
-	v4l2_set_subdevdata(&new_csid_dev->subdev, new_csid_dev);
-	platform_set_drvdata(pdev, &new_csid_dev->subdev);
-	mutex_init(&new_csid_dev->mutex);
-
-	if (pdev->dev.of_node)
-		of_property_read_u32((&pdev->dev)->of_node,
-			"cell-index", &pdev->id);
-
-	CDBG("%s device id %d\n", __func__, pdev->id);
-	new_csid_dev->mem = platform_get_resource_byname(pdev,
-					IORESOURCE_MEM, "csid");
-	if (!new_csid_dev->mem) {
-		pr_err("%s: no mem resource?\n", __func__);
-		rc = -ENODEV;
-		goto csid_no_resource;
-	}
-	new_csid_dev->irq = platform_get_resource_byname(pdev,
-					IORESOURCE_IRQ, "csid");
-	if (!new_csid_dev->irq) {
-		pr_err("%s: no irq resource?\n", __func__);
-		rc = -ENODEV;
-		goto csid_no_resource;
-	}
-	new_csid_dev->io = request_mem_region(new_csid_dev->mem->start,
-		resource_size(new_csid_dev->mem), pdev->name);
-	if (!new_csid_dev->io) {
-		pr_err("%s: no valid mem region\n", __func__);
-		rc = -EBUSY;
-		goto csid_no_resource;
-	}
-
-	new_csid_dev->pdev = pdev;
-	sd_info.sdev_type = CSID_DEV;
-	sd_info.sd_index = pdev->id;
-	sd_info.irq_num = new_csid_dev->irq->start;
-	msm_cam_register_subdev_node(&new_csid_dev->subdev, &sd_info);
-
-	media_entity_init(&new_csid_dev->subdev.entity, 0, NULL, 0);
-	new_csid_dev->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
-	new_csid_dev->subdev.entity.group_id = CSID_DEV;
-	new_csid_dev->subdev.entity.name = pdev->name;
-	new_csid_dev->subdev.entity.revision =
-		new_csid_dev->subdev.devnode->num;
-
-	/* Request for this device irq from the camera server. If the
-	 * IRQ Router is present on this target, the interrupt will be
-	 * handled by the camera server and the interrupt service
-	 * routine called. If the request_irq call returns ENXIO, then
-	 * the IRQ Router hardware is not present on this target. We
-	 * have to request for the irq ourselves and register the
-	 * appropriate interrupt handler. */
-	irq_req.cam_hw_idx       = MSM_CAM_HW_CSI0 + pdev->id;
-	irq_req.dev_name         = "csid";
-	irq_req.irq_idx          = CAMERA_SS_IRQ_2 + pdev->id;
-	irq_req.irq_num          = new_csid_dev->irq->start;
-	irq_req.is_composite     = 0;
-	irq_req.irq_trigger_type = IRQF_TRIGGER_RISING;
-	irq_req.num_hwcore       = 1;
-	irq_req.subdev_list[0]   = &new_csid_dev->subdev;
-	irq_req.data             = (void *)new_csid_dev;
-	rc = msm_cam_server_request_irq(&irq_req);
-	if (rc == -ENXIO) {
-		/* IRQ Router hardware is not present on this hardware.
-		 * Request for the IRQ and register the interrupt handler. */
-		rc = request_irq(new_csid_dev->irq->start, msm_csid_irq,
-			IRQF_TRIGGER_RISING, "csid", new_csid_dev);
-		if (rc < 0) {
-			release_mem_region(new_csid_dev->mem->start,
-				resource_size(new_csid_dev->mem));
-			pr_err("%s: irq request fail\n", __func__);
-			rc = -EBUSY;
-			goto csid_no_resource;
-		}
-		disable_irq(new_csid_dev->irq->start);
-	} else if (rc < 0) {
-		release_mem_region(new_csid_dev->mem->start,
-			resource_size(new_csid_dev->mem));
-		pr_err("%s Error registering irq ", __func__);
-		goto csid_no_resource;
-	}
-
-	new_csid_dev->csid_state = CSID_POWER_DOWN;
-	return 0;
-
-csid_no_resource:
-	mutex_destroy(&new_csid_dev->mutex);
-	kfree(new_csid_dev);
-	return 0;
-}
-
-static const struct of_device_id msm_csid_dt_match[] = {
-	{.compatible = "qcom,csid"},
-	{}
-};
-
-MODULE_DEVICE_TABLE(of, msm_csid_dt_match);
-
-static struct platform_driver csid_driver = {
-	.probe = csid_probe,
-	.driver = {
-		.name = MSM_CSID_DRV_NAME,
-		.owner = THIS_MODULE,
-		.of_match_table = msm_csid_dt_match,
-	},
-};
-
-static int __init msm_csid_init_module(void)
-{
-	return platform_driver_register(&csid_driver);
-}
-
-static void __exit msm_csid_exit_module(void)
-{
-	platform_driver_unregister(&csid_driver);
-}
-
-module_init(msm_csid_init_module);
-module_exit(msm_csid_exit_module);
-MODULE_DESCRIPTION("MSM CSID driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/csi/msm_csid.h b/drivers/media/video/msm/csi/msm_csid.h
deleted file mode 100644
index 46e8117..0000000
--- a/drivers/media/video/msm/csi/msm_csid.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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 MSM_CSID_H
-#define MSM_CSID_H
-
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <media/v4l2-subdev.h>
-#include <media/msm_camera.h>
-
-enum msm_csid_state_t {
-	CSID_POWER_UP,
-	CSID_POWER_DOWN,
-};
-
-struct csid_device {
-	struct platform_device *pdev;
-	struct v4l2_subdev subdev;
-	struct resource *mem;
-	struct resource *irq;
-	struct resource *io;
-	struct regulator *csi_vdd;
-	void __iomem *base;
-	struct mutex mutex;
-	struct completion reset_complete;
-	uint32_t hw_version;
-	enum msm_csid_state_t csid_state;
-
-	struct clk *csid0_clk[6];
-	struct clk *csid_clk[6];
-};
-
-#define VIDIOC_MSM_CSID_CFG \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 4, struct csic_cfg_data*)
-
-#define VIDIOC_MSM_CSID_RELEASE \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 5, struct v4l2_subdev*)
-#endif
-
diff --git a/drivers/media/video/msm/csi/msm_csiphy.c b/drivers/media/video/msm/csi/msm_csiphy.c
deleted file mode 100644
index 065ba34..0000000
--- a/drivers/media/video/msm/csi/msm_csiphy.c
+++ /dev/null
@@ -1,465 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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/delay.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/module.h>
-#include <mach/board.h>
-#include <mach/vreg.h>
-#include <media/msm_isp.h>
-#include "msm_csiphy.h"
-#include "msm.h"
-#include "msm_csiphy_hwreg.h"
-#define DBG_CSIPHY 0
-
-#define V4L2_IDENT_CSIPHY                        50003
-#define CSIPHY_VERSION_V3                        0x10
-
-int msm_csiphy_lane_config(struct csiphy_device *csiphy_dev,
-	struct msm_camera_csiphy_params *csiphy_params)
-{
-	int rc = 0;
-	int j = 0;
-	uint32_t val = 0;
-	uint8_t lane_cnt = 0;
-	uint16_t lane_mask = 0;
-	void __iomem *csiphybase;
-	csiphybase = csiphy_dev->base;
-	if (!csiphybase) {
-		pr_err("%s: csiphybase NULL\n", __func__);
-		return -EINVAL;
-	}
-
-	csiphy_dev->lane_mask[csiphy_dev->pdev->id] |= csiphy_params->lane_mask;
-	lane_mask = csiphy_dev->lane_mask[csiphy_dev->pdev->id];
-	lane_cnt = csiphy_params->lane_cnt;
-	if (csiphy_params->lane_cnt < 1 || csiphy_params->lane_cnt > 4) {
-		pr_err("%s: unsupported lane cnt %d\n",
-			__func__, csiphy_params->lane_cnt);
-		return rc;
-	}
-
-	CDBG("%s csiphy_params, mask = %x, cnt = %d, settle cnt = %x\n",
-		__func__,
-		csiphy_params->lane_mask,
-		csiphy_params->lane_cnt,
-		csiphy_params->settle_cnt);
-	msm_camera_io_w(0x1, csiphybase + MIPI_CSIPHY_GLBL_T_INIT_CFG0_ADDR);
-	msm_camera_io_w(0x1, csiphybase + MIPI_CSIPHY_T_WAKEUP_CFG0_ADDR);
-
-	if (csiphy_dev->hw_version != CSIPHY_VERSION_V3) {
-		val = 0x3;
-		msm_camera_io_w((lane_mask << 2) | val,
-				csiphybase + MIPI_CSIPHY_GLBL_PWR_CFG_ADDR);
-		msm_camera_io_w(0x10, csiphybase + MIPI_CSIPHY_LNCK_CFG2_ADDR);
-		msm_camera_io_w(csiphy_params->settle_cnt,
-			 csiphybase + MIPI_CSIPHY_LNCK_CFG3_ADDR);
-		msm_camera_io_w(0x24,
-			csiphybase + MIPI_CSIPHY_INTERRUPT_MASK0_ADDR);
-		msm_camera_io_w(0x24,
-			csiphybase + MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR);
-	} else {
-		val = 0x1;
-		msm_camera_io_w((lane_mask << 1) | val,
-				csiphybase + MIPI_CSIPHY_GLBL_PWR_CFG_ADDR);
-		msm_camera_io_w(csiphy_params->combo_mode <<
-			MIPI_CSIPHY_MODE_CONFIG_SHIFT,
-			csiphybase + MIPI_CSIPHY_GLBL_RESET_ADDR);
-	}
-
-	lane_mask &= 0x1f;
-	while (lane_mask & 0x1f) {
-		if (!(lane_mask & 0x1)) {
-			j++;
-			lane_mask >>= 1;
-			continue;
-		}
-		msm_camera_io_w(0x10,
-			csiphybase + MIPI_CSIPHY_LNn_CFG2_ADDR + 0x40*j);
-		msm_camera_io_w(csiphy_params->settle_cnt,
-			csiphybase + MIPI_CSIPHY_LNn_CFG3_ADDR + 0x40*j);
-		msm_camera_io_w(MIPI_CSIPHY_INTERRUPT_MASK_VAL, csiphybase +
-			MIPI_CSIPHY_INTERRUPT_MASK_ADDR + 0x4*j);
-		msm_camera_io_w(MIPI_CSIPHY_INTERRUPT_MASK_VAL, csiphybase +
-			MIPI_CSIPHY_INTERRUPT_CLEAR_ADDR + 0x4*j);
-		j++;
-		lane_mask >>= 1;
-	}
-	msleep(20);
-	return rc;
-}
-
-static irqreturn_t msm_csiphy_irq(int irq_num, void *data)
-{
-	uint32_t irq;
-	int i;
-	struct csiphy_device *csiphy_dev = data;
-
-	for (i = 0; i < 8; i++) {
-		irq = msm_camera_io_r(
-			csiphy_dev->base +
-			MIPI_CSIPHY_INTERRUPT_STATUS0_ADDR + 0x4*i);
-		msm_camera_io_w(irq,
-			csiphy_dev->base +
-			MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR + 0x4*i);
-		pr_err("%s MIPI_CSIPHY%d_INTERRUPT_STATUS%d = 0x%x\n",
-			 __func__, csiphy_dev->pdev->id, i, irq);
-		msm_camera_io_w(0x1, csiphy_dev->base +
-			MIPI_CSIPHY_GLBL_IRQ_CMD_ADDR);
-		msm_camera_io_w(0x0, csiphy_dev->base +
-			MIPI_CSIPHY_GLBL_IRQ_CMD_ADDR);
-		msm_camera_io_w(0x0,
-			csiphy_dev->base +
-			MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR + 0x4*i);
-	}
-	return IRQ_HANDLED;
-}
-
-static void msm_csiphy_reset(struct csiphy_device *csiphy_dev)
-{
-	msm_camera_io_w(0x1, csiphy_dev->base + MIPI_CSIPHY_GLBL_RESET_ADDR);
-	usleep_range(5000, 8000);
-	msm_camera_io_w(0x0, csiphy_dev->base + MIPI_CSIPHY_GLBL_RESET_ADDR);
-}
-
-static int msm_csiphy_subdev_g_chip_ident(struct v4l2_subdev *sd,
-			struct v4l2_dbg_chip_ident *chip)
-{
-	BUG_ON(!chip);
-	chip->ident = V4L2_IDENT_CSIPHY;
-	chip->revision = 0;
-	return 0;
-}
-
-static struct msm_cam_clk_info csiphy_8960_clk_info[] = {
-	{"csiphy_timer_src_clk", 177780000},
-	{"csiphy_timer_clk", -1},
-};
-
-static struct msm_cam_clk_info csiphy_8974_clk_info[] = {
-	{"ispif_ahb_clk", -1},
-	{"csiphy_timer_src_clk", 200000000},
-	{"csiphy_timer_clk", -1},
-};
-
-static int msm_csiphy_init(struct csiphy_device *csiphy_dev)
-{
-	int rc = 0;
-	if (csiphy_dev == NULL) {
-		pr_err("%s: csiphy_dev NULL\n", __func__);
-		rc = -ENOMEM;
-		return rc;
-	}
-
-	if (csiphy_dev->csiphy_state == CSIPHY_POWER_UP) {
-		pr_err("%s: csiphy invalid state %d\n", __func__,
-			csiphy_dev->csiphy_state);
-		rc = -EINVAL;
-		return rc;
-	}
-
-	if (csiphy_dev->ref_count++) {
-		CDBG("%s csiphy refcount = %d\n", __func__,
-			csiphy_dev->ref_count);
-		return rc;
-	}
-
-	csiphy_dev->base = ioremap(csiphy_dev->mem->start,
-		resource_size(csiphy_dev->mem));
-	if (!csiphy_dev->base) {
-		pr_err("%s: csiphy_dev->base NULL\n", __func__);
-		csiphy_dev->ref_count--;
-		rc = -ENOMEM;
-		return rc;
-	}
-
-	if (CSIPHY_VERSION != CSIPHY_VERSION_V3)
-		rc = msm_cam_clk_enable(&csiphy_dev->pdev->dev,
-			csiphy_8960_clk_info, csiphy_dev->csiphy_clk,
-			ARRAY_SIZE(csiphy_8960_clk_info), 1);
-	else
-		rc = msm_cam_clk_enable(&csiphy_dev->pdev->dev,
-			csiphy_8974_clk_info, csiphy_dev->csiphy_clk,
-			ARRAY_SIZE(csiphy_8974_clk_info), 1);
-
-	if (rc < 0) {
-		pr_err("%s: csiphy clk enable failed\n", __func__);
-		csiphy_dev->ref_count--;
-		iounmap(csiphy_dev->base);
-		csiphy_dev->base = NULL;
-		return rc;
-	}
-
-#if DBG_CSIPHY
-	enable_irq(csiphy_dev->irq->start);
-#endif
-	msm_csiphy_reset(csiphy_dev);
-
-	csiphy_dev->hw_version =
-		msm_camera_io_r(csiphy_dev->base + MIPI_CSIPHY_HW_VERSION_ADDR);
-
-	csiphy_dev->csiphy_state = CSIPHY_POWER_UP;
-	return 0;
-}
-
-static int msm_csiphy_release(struct csiphy_device *csiphy_dev, void *arg)
-{
-	int i = 0;
-	struct msm_camera_csi_lane_params *csi_lane_params;
-	uint16_t csi_lane_mask;
-	csi_lane_params = (struct msm_camera_csi_lane_params *)arg;
-	csi_lane_mask = csi_lane_params->csi_lane_mask;
-
-	if (!csiphy_dev || !csiphy_dev->ref_count) {
-		pr_err("%s csiphy dev NULL / ref_count ZERO\n", __func__);
-		return 0;
-	}
-
-	if (csiphy_dev->csiphy_state != CSIPHY_POWER_UP) {
-		pr_err("%s: csiphy invalid state %d\n", __func__,
-			csiphy_dev->csiphy_state);
-		return -EINVAL;
-	}
-
-	CDBG("%s csiphy_params, lane assign %x mask = %x\n",
-		__func__,
-		csi_lane_params->csi_lane_assign,
-		csi_lane_params->csi_lane_mask);
-
-	if (csiphy_dev->hw_version != CSIPHY_VERSION_V3) {
-		csiphy_dev->lane_mask[csiphy_dev->pdev->id] = 0;
-		for (i = 0; i < 4; i++)
-			msm_camera_io_w(0x0, csiphy_dev->base +
-				MIPI_CSIPHY_LNn_CFG2_ADDR + 0x40*i);
-	} else {
-		csiphy_dev->lane_mask[csiphy_dev->pdev->id] &=
-			~(csi_lane_params->csi_lane_mask);
-		i = 0;
-		while (csi_lane_mask & 0x1F) {
-			if (csi_lane_mask & 0x1) {
-				msm_camera_io_w(0x0, csiphy_dev->base +
-					MIPI_CSIPHY_LNn_CFG2_ADDR + 0x40*i);
-			}
-			csi_lane_mask >>= 1;
-			i++;
-		}
-	}
-
-	if (--csiphy_dev->ref_count) {
-		CDBG("%s csiphy refcount = %d\n", __func__,
-			csiphy_dev->ref_count);
-		return 0;
-	}
-
-	msm_camera_io_w(0x0, csiphy_dev->base + MIPI_CSIPHY_LNCK_CFG2_ADDR);
-	msm_camera_io_w(0x0, csiphy_dev->base + MIPI_CSIPHY_GLBL_PWR_CFG_ADDR);
-
-#if DBG_CSIPHY
-	disable_irq(csiphy_dev->irq->start);
-#endif
-	if (CSIPHY_VERSION != CSIPHY_VERSION_V3)
-		msm_cam_clk_enable(&csiphy_dev->pdev->dev,
-			csiphy_8960_clk_info, csiphy_dev->csiphy_clk,
-			ARRAY_SIZE(csiphy_8960_clk_info), 0);
-	else
-		msm_cam_clk_enable(&csiphy_dev->pdev->dev,
-			csiphy_8974_clk_info, csiphy_dev->csiphy_clk,
-			ARRAY_SIZE(csiphy_8974_clk_info), 0);
-
-	iounmap(csiphy_dev->base);
-	csiphy_dev->base = NULL;
-	csiphy_dev->csiphy_state = CSIPHY_POWER_DOWN;
-	return 0;
-}
-
-static long msm_csiphy_cmd(struct csiphy_device *csiphy_dev, void *arg)
-{
-	int rc = 0;
-	struct csiphy_cfg_data cdata;
-	struct msm_camera_csiphy_params csiphy_params;
-	if (!csiphy_dev) {
-		pr_err("%s: csiphy_dev NULL\n", __func__);
-		return -EINVAL;
-	}
-	if (copy_from_user(&cdata,
-		(void *)arg,
-		sizeof(struct csiphy_cfg_data))) {
-		pr_err("%s: %d failed\n", __func__, __LINE__);
-		return -EFAULT;
-	}
-	switch (cdata.cfgtype) {
-	case CSIPHY_INIT:
-		rc = msm_csiphy_init(csiphy_dev);
-		break;
-	case CSIPHY_CFG:
-		if (copy_from_user(&csiphy_params,
-			(void *)cdata.csiphy_params,
-			sizeof(struct msm_camera_csiphy_params))) {
-			pr_err("%s: %d failed\n", __func__, __LINE__);
-			rc = -EFAULT;
-			break;
-		}
-		rc = msm_csiphy_lane_config(csiphy_dev, &csiphy_params);
-		break;
-	default:
-		pr_err("%s: %d failed\n", __func__, __LINE__);
-		rc = -ENOIOCTLCMD;
-		break;
-	}
-	return rc;
-}
-
-static long msm_csiphy_subdev_ioctl(struct v4l2_subdev *sd,
-			unsigned int cmd, void *arg)
-{
-	int rc = -ENOIOCTLCMD;
-	struct csiphy_device *csiphy_dev = v4l2_get_subdevdata(sd);
-	mutex_lock(&csiphy_dev->mutex);
-	switch (cmd) {
-	case VIDIOC_MSM_CSIPHY_CFG:
-		rc = msm_csiphy_cmd(csiphy_dev, arg);
-		break;
-	case VIDIOC_MSM_CSIPHY_RELEASE:
-		rc = msm_csiphy_release(csiphy_dev, arg);
-		break;
-	default:
-		pr_err("%s: command not found\n", __func__);
-	}
-	mutex_unlock(&csiphy_dev->mutex);
-	return rc;
-}
-
-static const struct v4l2_subdev_internal_ops msm_csiphy_internal_ops;
-
-static struct v4l2_subdev_core_ops msm_csiphy_subdev_core_ops = {
-	.g_chip_ident = &msm_csiphy_subdev_g_chip_ident,
-	.ioctl = &msm_csiphy_subdev_ioctl,
-};
-
-static const struct v4l2_subdev_ops msm_csiphy_subdev_ops = {
-	.core = &msm_csiphy_subdev_core_ops,
-};
-
-static int __devinit csiphy_probe(struct platform_device *pdev)
-{
-	struct csiphy_device *new_csiphy_dev;
-	int rc = 0;
-	struct msm_cam_subdev_info sd_info;
-
-	new_csiphy_dev = kzalloc(sizeof(struct csiphy_device), GFP_KERNEL);
-	if (!new_csiphy_dev) {
-		pr_err("%s: no enough memory\n", __func__);
-		return -ENOMEM;
-	}
-
-	v4l2_subdev_init(&new_csiphy_dev->subdev, &msm_csiphy_subdev_ops);
-	new_csiphy_dev->subdev.internal_ops = &msm_csiphy_internal_ops;
-	new_csiphy_dev->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-	snprintf(new_csiphy_dev->subdev.name,
-			ARRAY_SIZE(new_csiphy_dev->subdev.name), "msm_csiphy");
-	v4l2_set_subdevdata(&new_csiphy_dev->subdev, new_csiphy_dev);
-	platform_set_drvdata(pdev, &new_csiphy_dev->subdev);
-
-	mutex_init(&new_csiphy_dev->mutex);
-
-	if (pdev->dev.of_node)
-		of_property_read_u32((&pdev->dev)->of_node,
-			"cell-index", &pdev->id);
-	CDBG("%s: device id = %d\n", __func__, pdev->id);
-
-	new_csiphy_dev->mem = platform_get_resource_byname(pdev,
-					IORESOURCE_MEM, "csiphy");
-	if (!new_csiphy_dev->mem) {
-		pr_err("%s: no mem resource?\n", __func__);
-		rc = -ENODEV;
-		goto csiphy_no_resource;
-	}
-	new_csiphy_dev->irq = platform_get_resource_byname(pdev,
-					IORESOURCE_IRQ, "csiphy");
-	if (!new_csiphy_dev->irq) {
-		pr_err("%s: no irq resource?\n", __func__);
-		rc = -ENODEV;
-		goto csiphy_no_resource;
-	}
-	new_csiphy_dev->io = request_mem_region(new_csiphy_dev->mem->start,
-		resource_size(new_csiphy_dev->mem), pdev->name);
-	if (!new_csiphy_dev->io) {
-		pr_err("%s: no valid mem region\n", __func__);
-		rc = -EBUSY;
-		goto csiphy_no_resource;
-	}
-
-	rc = request_irq(new_csiphy_dev->irq->start, msm_csiphy_irq,
-		IRQF_TRIGGER_RISING, "csiphy", new_csiphy_dev);
-	if (rc < 0) {
-		release_mem_region(new_csiphy_dev->mem->start,
-			resource_size(new_csiphy_dev->mem));
-		pr_err("%s: irq request fail\n", __func__);
-		rc = -EBUSY;
-		goto csiphy_no_resource;
-	}
-	disable_irq(new_csiphy_dev->irq->start);
-
-	new_csiphy_dev->pdev = pdev;
-	sd_info.sdev_type = CSIPHY_DEV;
-	sd_info.sd_index = pdev->id;
-	sd_info.irq_num = new_csiphy_dev->irq->start;
-	msm_cam_register_subdev_node(
-		&new_csiphy_dev->subdev, &sd_info);
-
-	media_entity_init(&new_csiphy_dev->subdev.entity, 0, NULL, 0);
-	new_csiphy_dev->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
-	new_csiphy_dev->subdev.entity.group_id = CSIPHY_DEV;
-	new_csiphy_dev->subdev.entity.name = pdev->name;
-	new_csiphy_dev->subdev.entity.revision =
-		new_csiphy_dev->subdev.devnode->num;
-	new_csiphy_dev->csiphy_state = CSIPHY_POWER_DOWN;
-	return 0;
-
-csiphy_no_resource:
-	mutex_destroy(&new_csiphy_dev->mutex);
-	kfree(new_csiphy_dev);
-	return 0;
-}
-
-static const struct of_device_id msm_csiphy_dt_match[] = {
-	{.compatible = "qcom,csiphy"},
-	{}
-};
-
-MODULE_DEVICE_TABLE(of, msm_csiphy_dt_match);
-
-static struct platform_driver csiphy_driver = {
-	.probe = csiphy_probe,
-	.driver = {
-		.name = MSM_CSIPHY_DRV_NAME,
-		.owner = THIS_MODULE,
-		.of_match_table = msm_csiphy_dt_match,
-	},
-};
-
-static int __init msm_csiphy_init_module(void)
-{
-	return platform_driver_register(&csiphy_driver);
-}
-
-static void __exit msm_csiphy_exit_module(void)
-{
-	platform_driver_unregister(&csiphy_driver);
-}
-
-module_init(msm_csiphy_init_module);
-module_exit(msm_csiphy_exit_module);
-MODULE_DESCRIPTION("MSM CSIPHY driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/csi/msm_csiphy.h b/drivers/media/video/msm/csi/msm_csiphy.h
deleted file mode 100644
index 2fb21d2..0000000
--- a/drivers/media/video/msm/csi/msm_csiphy.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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 MSM_CSIPHY_H
-#define MSM_CSIPHY_H
-
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <media/v4l2-subdev.h>
-#include <media/msm_camera.h>
-
-#define MAX_CSIPHY 3
-
-enum msm_csiphy_state_t {
-	CSIPHY_POWER_UP,
-	CSIPHY_POWER_DOWN,
-};
-
-struct csiphy_device {
-	struct platform_device *pdev;
-	struct v4l2_subdev subdev;
-	struct resource *mem;
-	struct resource *irq;
-	struct resource *io;
-	void __iomem *base;
-	struct mutex mutex;
-	uint32_t hw_version;
-	enum msm_csiphy_state_t csiphy_state;
-
-	struct clk *csiphy_clk[3];
-	uint8_t ref_count;
-	uint16_t lane_mask[MAX_CSIPHY];
-};
-
-#define VIDIOC_MSM_CSIPHY_CFG \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 7, struct csiphy_cfg_data*)
-
-#define VIDIOC_MSM_CSIPHY_RELEASE \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 9, void *)
-#endif
diff --git a/drivers/media/video/msm/csi/msm_ispif.c b/drivers/media/video/msm/csi/msm_ispif.c
deleted file mode 100644
index 62858a8..0000000
--- a/drivers/media/video/msm/csi/msm_ispif.c
+++ /dev/null
@@ -1,928 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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/delay.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <mach/gpio.h>
-#include <mach/camera.h>
-#include "msm_ispif.h"
-#include "msm.h"
-#include "msm_ispif_hwreg.h"
-
-#define V4L2_IDENT_ISPIF                     50001
-#define CSID_VERSION_V2                      0x02000011
-#define CSID_VERSION_V3                      0x30000000
-
-#define MAX_CID 15
-
-static atomic_t ispif_irq_cnt;
-static spinlock_t ispif_tasklet_lock;
-static struct list_head ispif_tasklet_q;
-
-static int msm_ispif_intf_reset(struct ispif_device *ispif,
-	uint16_t intfmask, uint8_t vfe_intf)
-{
-	int rc = 0;
-	uint32_t data = (0x1 << STROBED_RST_EN);
-	uint16_t intfnum = 0, mask = intfmask;
-
-	while (mask != 0) {
-		if (!(intfmask & (0x1 << intfnum))) {
-			mask >>= 1;
-			intfnum++;
-			continue;
-		}
-		switch (intfnum) {
-		case PIX0:
-			data |= (0x1 << PIX_0_VFE_RST_STB) |
-				(0x1 << PIX_0_CSID_RST_STB);
-			ispif->pix_sof_count = 0;
-			break;
-
-		case RDI0:
-			data |= (0x1 << RDI_0_VFE_RST_STB) |
-				(0x1 << RDI_0_CSID_RST_STB);
-			break;
-
-		case PIX1:
-			data |= (0x1 << PIX_1_VFE_RST_STB) |
-				(0x1 << PIX_1_CSID_RST_STB);
-			break;
-
-		case RDI1:
-			data |= (0x1 << RDI_1_VFE_RST_STB) |
-				(0x1 << RDI_1_CSID_RST_STB);
-			break;
-
-		case RDI2:
-			data |= (0x1 << RDI_2_VFE_RST_STB) |
-				(0x1 << RDI_2_CSID_RST_STB);
-			break;
-
-		default:
-			rc = -EINVAL;
-			break;
-		}
-		mask >>= 1;
-		intfnum++;
-	}	/*end while */
-	if (data > 0x1) {
-		if (vfe_intf == VFE0)
-			msm_camera_io_w(data, ispif->base + ISPIF_RST_CMD_ADDR);
-		else
-			msm_camera_io_w(data, ispif->base +
-				ISPIF_RST_CMD_1_ADDR);
-		rc = wait_for_completion_interruptible(&ispif->reset_complete);
-	}
-	return rc;
-}
-
-static int msm_ispif_reset(struct ispif_device *ispif)
-{
-	int rc = 0;
-	ispif->pix_sof_count = 0;
-	msm_camera_io_w(ISPIF_RST_CMD_MASK, ispif->base + ISPIF_RST_CMD_ADDR);
-	if (ispif->csid_version == CSID_VERSION_V3)
-		msm_camera_io_w(ISPIF_RST_CMD_1_MASK, ispif->base +
-				ISPIF_RST_CMD_1_ADDR);
-	rc = wait_for_completion_interruptible(&ispif->reset_complete);
-	return rc;
-}
-
-static int msm_ispif_subdev_g_chip_ident(struct v4l2_subdev *sd,
-			struct v4l2_dbg_chip_ident *chip)
-{
-	BUG_ON(!chip);
-	chip->ident = V4L2_IDENT_ISPIF;
-	chip->revision = 0;
-	return 0;
-}
-
-static void msm_ispif_sel_csid_core(struct ispif_device *ispif,
-	uint8_t intftype, uint8_t csid, uint8_t vfe_intf)
-{
-	int rc = 0;
-	uint32_t data = 0;
-
-	if (ispif->csid_version <= CSID_VERSION_V2) {
-		if (ispif->ispif_clk[intftype] == NULL) {
-			pr_err("%s: ispif NULL clk\n", __func__);
-			return;
-		}
-		rc = clk_set_rate(ispif->ispif_clk[intftype], csid);
-		if (rc < 0)
-			pr_err("%s: clk_set_rate failed %d\n", __func__, rc);
-	}
-	data = msm_camera_io_r(ispif->base + ISPIF_INPUT_SEL_ADDR +
-		(0x200 * vfe_intf));
-	switch (intftype) {
-	case PIX0:
-		data &= ~(0x3);
-		data |= csid;
-		break;
-
-	case RDI0:
-		data &= ~(0x3 << 4);
-		data |= (csid << 4);
-		break;
-
-	case PIX1:
-		data &= ~(0x3 << 8);
-		data |= (csid << 8);
-		break;
-
-	case RDI1:
-		data &= ~(0x3 << 12);
-		data |= (csid << 12);
-		break;
-
-	case RDI2:
-		data &= ~(0x3 << 20);
-		data |= (csid << 20);
-		break;
-	}
-	if (data) {
-		msm_camera_io_w(data, ispif->base + ISPIF_INPUT_SEL_ADDR +
-			(0x200 * vfe_intf));
-	}
-}
-
-static void msm_ispif_enable_intf_cids(struct ispif_device *ispif,
-	uint8_t intftype, uint16_t cid_mask, uint8_t vfe_intf)
-{
-	uint32_t data = 0;
-	mutex_lock(&ispif->mutex);
-	switch (intftype) {
-	case PIX0:
-		data = msm_camera_io_r(ispif->base +
-			ISPIF_PIX_0_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
-		data |= cid_mask;
-		msm_camera_io_w(data, ispif->base +
-			ISPIF_PIX_0_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
-		break;
-
-	case RDI0:
-		data = msm_camera_io_r(ispif->base +
-			ISPIF_RDI_0_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
-		data |= cid_mask;
-		msm_camera_io_w(data, ispif->base +
-			ISPIF_RDI_0_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
-		break;
-
-	case PIX1:
-		data = msm_camera_io_r(ispif->base +
-			ISPIF_PIX_1_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
-		data |= cid_mask;
-		msm_camera_io_w(data, ispif->base +
-			ISPIF_PIX_1_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
-		break;
-
-	case RDI1:
-		data = msm_camera_io_r(ispif->base +
-			ISPIF_RDI_1_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
-		data |= cid_mask;
-		msm_camera_io_w(data, ispif->base +
-			ISPIF_RDI_1_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
-		break;
-
-	case RDI2:
-		data = msm_camera_io_r(ispif->base +
-			ISPIF_RDI_2_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
-		data |= cid_mask;
-		msm_camera_io_w(data, ispif->base +
-			ISPIF_RDI_2_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
-		break;
-	}
-	mutex_unlock(&ispif->mutex);
-}
-
-static int32_t msm_ispif_validate_intf_status(struct ispif_device *ispif,
-	uint8_t intftype, uint8_t vfe_intf)
-{
-	int32_t rc = 0;
-	uint32_t data = 0;
-	mutex_lock(&ispif->mutex);
-	switch (intftype) {
-	case PIX0:
-		data = msm_camera_io_r(ispif->base +
-				ISPIF_PIX_0_STATUS_ADDR + (0x200 * vfe_intf));
-		break;
-
-	case RDI0:
-		data = msm_camera_io_r(ispif->base +
-				ISPIF_RDI_0_STATUS_ADDR + (0x200 * vfe_intf));
-		break;
-
-	case PIX1:
-		data = msm_camera_io_r(ispif->base +
-				ISPIF_PIX_1_STATUS_ADDR + (0x200 * vfe_intf));
-		break;
-
-	case RDI1:
-		data = msm_camera_io_r(ispif->base +
-				ISPIF_RDI_1_STATUS_ADDR + (0x200 * vfe_intf));
-		break;
-
-	case RDI2:
-		data = msm_camera_io_r(ispif->base +
-				ISPIF_RDI_2_STATUS_ADDR + (0x200 * vfe_intf));
-		break;
-	}
-	if ((data & 0xf) != 0xf)
-		rc = -EBUSY;
-	mutex_unlock(&ispif->mutex);
-	return rc;
-}
-
-static int msm_ispif_config(struct ispif_device *ispif,
-	struct msm_ispif_params_list *params_list)
-{
-	uint32_t params_len;
-	struct msm_ispif_params *ispif_params;
-	int rc = 0, i = 0;
-	uint8_t intftype;
-	uint8_t vfe_intf;
-	params_len = params_list->len;
-	ispif_params = params_list->params;
-	CDBG("Enable interface\n");
-	msm_camera_io_w(0x00000000, ispif->base + ISPIF_IRQ_MASK_ADDR);
-	msm_camera_io_w(0x00000000, ispif->base + ISPIF_IRQ_MASK_1_ADDR);
-	msm_camera_io_w(0x00000000, ispif->base + ISPIF_IRQ_MASK_2_ADDR);
-	for (i = 0; i < params_len; i++) {
-		intftype = ispif_params[i].intftype;
-		vfe_intf = ispif_params[i].vfe_intf;
-		CDBG("%s intftype %x, vfe_intf %d, csid %d\n", __func__,
-			intftype, vfe_intf, ispif_params[i].csid);
-		if ((intftype >= INTF_MAX) ||
-			(ispif->csid_version <= CSID_VERSION_V2 &&
-			vfe_intf > VFE0) ||
-			(ispif->csid_version == CSID_VERSION_V3 &&
-			vfe_intf >= VFE_MAX)) {
-			pr_err("%s: intftype / vfe intf not valid\n",
-				__func__);
-			return -EINVAL;
-		}
-
-		rc = msm_ispif_validate_intf_status(ispif, intftype, vfe_intf);
-		if (rc < 0) {
-			pr_err("%s:%d failed rc %d\n", __func__, __LINE__, rc);
-			return rc;
-		}
-		msm_ispif_sel_csid_core(ispif, intftype, ispif_params[i].csid,
-			vfe_intf);
-		msm_ispif_enable_intf_cids(ispif, intftype,
-			ispif_params[i].cid_mask, vfe_intf);
-	}
-
-	msm_camera_io_w(ISPIF_IRQ_STATUS_MASK, ispif->base +
-					ISPIF_IRQ_MASK_ADDR);
-	msm_camera_io_w(ISPIF_IRQ_STATUS_MASK, ispif->base +
-					ISPIF_IRQ_CLEAR_ADDR);
-	msm_camera_io_w(ISPIF_IRQ_STATUS_1_MASK, ispif->base +
-					ISPIF_IRQ_MASK_1_ADDR);
-	msm_camera_io_w(ISPIF_IRQ_STATUS_1_MASK, ispif->base +
-					ISPIF_IRQ_CLEAR_1_ADDR);
-	msm_camera_io_w(ISPIF_IRQ_STATUS_2_MASK, ispif->base +
-					ISPIF_IRQ_MASK_2_ADDR);
-	msm_camera_io_w(ISPIF_IRQ_STATUS_2_MASK, ispif->base +
-					ISPIF_IRQ_CLEAR_2_ADDR);
-	msm_camera_io_w(ISPIF_IRQ_GLOBAL_CLEAR_CMD, ispif->base +
-		 ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR);
-	return rc;
-}
-
-static uint32_t msm_ispif_get_cid_mask(struct ispif_device *ispif,
-	uint16_t intftype, uint8_t vfe_intf)
-{
-	uint32_t mask = 0;
-	switch (intftype) {
-	case PIX0:
-		mask = msm_camera_io_r(ispif->base +
-			ISPIF_PIX_0_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
-		break;
-
-	case RDI0:
-		mask = msm_camera_io_r(ispif->base +
-			ISPIF_RDI_0_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
-		break;
-
-	case PIX1:
-		mask = msm_camera_io_r(ispif->base +
-			ISPIF_PIX_1_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
-		break;
-
-	case RDI1:
-		mask = msm_camera_io_r(ispif->base +
-			ISPIF_RDI_1_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
-		break;
-
-	case RDI2:
-		mask = msm_camera_io_r(ispif->base +
-			ISPIF_RDI_2_INTF_CID_MASK_ADDR + (0x200 * vfe_intf));
-		break;
-
-	default:
-		break;
-	}
-	return mask;
-}
-
-static void msm_ispif_intf_cmd(struct ispif_device *ispif, uint16_t intfmask,
-	uint8_t intf_cmd_mask, uint8_t vfe_intf)
-{
-	uint8_t vc = 0, val = 0;
-	uint16_t mask = intfmask, intfnum = 0;
-	uint32_t cid_mask = 0;
-	uint32_t global_intf_cmd_mask1 = 0xFFFFFFFF;
-	while (mask != 0) {
-		if (!(intfmask & (0x1 << intfnum))) {
-			mask >>= 1;
-			intfnum++;
-			continue;
-		}
-
-		cid_mask = msm_ispif_get_cid_mask(ispif, intfnum, vfe_intf);
-		vc = 0;
-
-		while (cid_mask != 0) {
-			if ((cid_mask & 0xf) != 0x0) {
-				if (intfnum != RDI2) {
-					val = (intf_cmd_mask>>(vc*2)) & 0x3;
-					ispif->global_intf_cmd_mask |=
-						(0x3 << ((vc * 2) +
-						(intfnum * 8)));
-					ispif->global_intf_cmd_mask &=
-						~((0x3 & ~val) << ((vc * 2) +
-						(intfnum * 8)));
-				} else
-					global_intf_cmd_mask1 &=
-						~((0x3 & ~intf_cmd_mask)
-						<< ((vc * 2) + 8));
-			}
-			vc++;
-			cid_mask >>= 4;
-		}
-		mask >>= 1;
-		intfnum++;
-	}
-	msm_camera_io_w(ispif->global_intf_cmd_mask,
-		ispif->base + ISPIF_INTF_CMD_ADDR + (0x200 * vfe_intf));
-	if (global_intf_cmd_mask1 != 0xFFFFFFFF)
-		msm_camera_io_w(global_intf_cmd_mask1,
-			ispif->base + ISPIF_INTF_CMD_1_ADDR +
-			(0x200 * vfe_intf));
-}
-
-static int msm_ispif_abort_intf_transfer(struct ispif_device *ispif,
-	uint16_t intfmask, uint8_t vfe_intf)
-{
-	int rc = 0;
-	uint8_t intf_cmd_mask = 0xAA;
-	uint16_t intfnum = 0, mask = intfmask;
-	mutex_lock(&ispif->mutex);
-	CDBG("%s intfmask %x intf_cmd_mask %x\n", __func__, intfmask,
-		intf_cmd_mask);
-	msm_ispif_intf_cmd(ispif, intfmask, intf_cmd_mask, vfe_intf);
-	while (mask != 0) {
-		if (intfmask & (0x1 << intfnum))
-			ispif->global_intf_cmd_mask |= (0xFF << (intfnum * 8));
-		mask >>= 1;
-		intfnum++;
-		if (intfnum == RDI2)
-			break;
-	}
-	mutex_unlock(&ispif->mutex);
-	return rc;
-}
-
-static int msm_ispif_start_intf_transfer(struct ispif_device *ispif,
-	uint16_t intfmask, uint8_t vfe_intf)
-{
-	uint8_t intf_cmd_mask = 0x55;
-	int rc = 0;
-	mutex_lock(&ispif->mutex);
-	rc = msm_ispif_intf_reset(ispif, intfmask, vfe_intf);
-	CDBG("%s intfmask start after%x intf_cmd_mask %x\n", __func__, intfmask,
-		intf_cmd_mask);
-	msm_ispif_intf_cmd(ispif, intfmask, intf_cmd_mask, vfe_intf);
-	mutex_unlock(&ispif->mutex);
-	return rc;
-}
-
-static int msm_ispif_stop_intf_transfer(struct ispif_device *ispif,
-	uint16_t intfmask, uint8_t vfe_intf)
-{
-	int rc = 0;
-	uint8_t intf_cmd_mask = 0x00;
-	uint16_t intfnum = 0, mask = intfmask;
-	mutex_lock(&ispif->mutex);
-	CDBG("%s intfmask %x intf_cmd_mask %x\n", __func__, intfmask,
-		intf_cmd_mask);
-	msm_ispif_intf_cmd(ispif, intfmask, intf_cmd_mask, vfe_intf);
-	while (mask != 0) {
-		if (intfmask & (0x1 << intfnum)) {
-			switch (intfnum) {
-			case PIX0:
-				while ((msm_camera_io_r(ispif->base +
-					ISPIF_PIX_0_STATUS_ADDR +
-					(0x200 * vfe_intf))
-					& 0xf) != 0xf) {
-					CDBG("Wait for pix0 Idle\n");
-				}
-				break;
-
-			case RDI0:
-				while ((msm_camera_io_r(ispif->base +
-					ISPIF_RDI_0_STATUS_ADDR +
-					(0x200 * vfe_intf))
-					& 0xf) != 0xf) {
-					CDBG("Wait for rdi0 Idle\n");
-				}
-				break;
-
-			case PIX1:
-				while ((msm_camera_io_r(ispif->base +
-					ISPIF_PIX_1_STATUS_ADDR +
-					(0x200 * vfe_intf))
-					& 0xf) != 0xf) {
-					CDBG("Wait for pix1 Idle\n");
-				}
-				break;
-
-			case RDI1:
-				while ((msm_camera_io_r(ispif->base +
-					ISPIF_RDI_1_STATUS_ADDR +
-					(0x200 * vfe_intf))
-					& 0xf) != 0xf) {
-					CDBG("Wait for rdi1 Idle\n");
-				}
-				break;
-
-			case RDI2:
-				while ((msm_camera_io_r(ispif->base +
-					ISPIF_RDI_2_STATUS_ADDR +
-					(0x200 * vfe_intf))
-					& 0xf) != 0xf) {
-					CDBG("Wait for rdi2 Idle\n");
-				}
-				break;
-
-			default:
-				break;
-			}
-			if (intfnum != RDI2)
-				ispif->global_intf_cmd_mask |= (0xFF <<
-					(intfnum * 8));
-		}
-		mask >>= 1;
-		intfnum++;
-	}
-	mutex_unlock(&ispif->mutex);
-	return rc;
-}
-
-static int msm_ispif_subdev_video_s_stream(struct v4l2_subdev *sd,
-	int enable)
-{
-	struct ispif_device *ispif =
-			(struct ispif_device *)v4l2_get_subdevdata(sd);
-	uint32_t cmd = enable & ((1<<ISPIF_S_STREAM_SHIFT)-1);
-	uint16_t intf = enable >> ISPIF_S_STREAM_SHIFT;
-	uint8_t vfe_intf = enable >> ISPIF_VFE_INTF_SHIFT;
-	int rc = -EINVAL;
-	CDBG("%s enable %x, cmd %x, intf %x\n", __func__, enable, cmd, intf);
-	BUG_ON(!ispif);
-	if ((ispif->csid_version <= CSID_VERSION_V2 && vfe_intf > VFE0) ||
-		(ispif->csid_version == CSID_VERSION_V3 &&
-		vfe_intf >= VFE_MAX)) {
-		pr_err("%s invalid csid version %x && vfe intf %d\n", __func__,
-			ispif->csid_version, vfe_intf);
-		return rc;
-	}
-	switch (cmd) {
-	case ISPIF_ON_FRAME_BOUNDARY:
-		rc = msm_ispif_start_intf_transfer(ispif, intf, vfe_intf);
-		break;
-	case ISPIF_OFF_FRAME_BOUNDARY:
-		rc = msm_ispif_stop_intf_transfer(ispif, intf, vfe_intf);
-		break;
-	case ISPIF_OFF_IMMEDIATELY:
-		rc = msm_ispif_abort_intf_transfer(ispif, intf, vfe_intf);
-		break;
-	default:
-		break;
-	}
-	return rc;
-}
-
-static void send_rdi_sof(struct ispif_device *ispif,
-	enum msm_ispif_intftype interface, int count)
-{
-	struct rdi_count_msg sof_msg;
-	sof_msg.rdi_interface = interface;
-	sof_msg.count = count;
-	v4l2_subdev_notify(&ispif->subdev, NOTIFY_AXI_RDI_SOF_COUNT,
-					   (void *)&sof_msg);
-}
-
-static void ispif_do_tasklet(unsigned long data)
-{
-	unsigned long flags;
-
-	struct ispif_isr_queue_cmd *qcmd = NULL;
-	struct ispif_device *ispif;
-
-	ispif = (struct ispif_device *)data;
-	while (atomic_read(&ispif_irq_cnt)) {
-		spin_lock_irqsave(&ispif_tasklet_lock, flags);
-		qcmd = list_first_entry(&ispif_tasklet_q,
-			struct ispif_isr_queue_cmd, list);
-		atomic_sub(1, &ispif_irq_cnt);
-
-		if (!qcmd) {
-			spin_unlock_irqrestore(&ispif_tasklet_lock,
-				flags);
-			return;
-		}
-		list_del(&qcmd->list);
-		spin_unlock_irqrestore(&ispif_tasklet_lock,
-			flags);
-
-		kfree(qcmd);
-	}
-}
-
-static void ispif_process_irq(struct ispif_device *ispif,
-	struct ispif_irq_status *out)
-{
-	unsigned long flags;
-	struct ispif_isr_queue_cmd *qcmd;
-
-	qcmd = kzalloc(sizeof(struct ispif_isr_queue_cmd),
-		GFP_ATOMIC);
-	if (!qcmd) {
-		pr_err("ispif_process_irq: qcmd malloc failed!\n");
-		return;
-	}
-	qcmd->ispifInterruptStatus0 = out->ispifIrqStatus0;
-	qcmd->ispifInterruptStatus1 = out->ispifIrqStatus1;
-	qcmd->ispifInterruptStatus2 = out->ispifIrqStatus2;
-
-	if (qcmd->ispifInterruptStatus0 &
-			ISPIF_IRQ_STATUS_PIX_SOF_MASK) {
-			CDBG("%s: ispif PIX irq status", __func__);
-			ispif->pix_sof_count++;
-			v4l2_subdev_notify(&ispif->subdev,
-				NOTIFY_VFE_PIX_SOF_COUNT,
-				(void *)&ispif->pix_sof_count);
-	}
-
-	if (qcmd->ispifInterruptStatus0 &
-			ISPIF_IRQ_STATUS_RDI0_SOF_MASK) {
-			CDBG("%s: ispif RDI0 irq status", __func__);
-			ispif->rdi0_sof_count++;
-			send_rdi_sof(ispif, RDI_0, ispif->rdi0_sof_count);
-	}
-	if (qcmd->ispifInterruptStatus1 &
-		ISPIF_IRQ_STATUS_RDI1_SOF_MASK) {
-		CDBG("%s: ispif RDI1 irq status", __func__);
-		ispif->rdi1_sof_count++;
-		send_rdi_sof(ispif, RDI_1, ispif->rdi1_sof_count);
-	}
-	if (qcmd->ispifInterruptStatus2 &
-		ISPIF_IRQ_STATUS_RDI2_SOF_MASK) {
-		CDBG("%s: ispif RDI2 irq status", __func__);
-		ispif->rdi2_sof_count++;
-		send_rdi_sof(ispif, RDI_2, ispif->rdi2_sof_count);
-	}
-
-	spin_lock_irqsave(&ispif_tasklet_lock, flags);
-	list_add_tail(&qcmd->list, &ispif_tasklet_q);
-
-	atomic_add(1, &ispif_irq_cnt);
-	spin_unlock_irqrestore(&ispif_tasklet_lock, flags);
-	tasklet_schedule(&ispif->ispif_tasklet);
-	return;
-}
-
-static inline void msm_ispif_read_irq_status(struct ispif_irq_status *out,
-	void *data)
-{
-	uint32_t status0 = 0, status1 = 0, status2 = 0;
-	struct ispif_device *ispif = (struct ispif_device *)data;
-	out->ispifIrqStatus0 = msm_camera_io_r(ispif->base +
-		ISPIF_IRQ_STATUS_ADDR);
-	out->ispifIrqStatus1 = msm_camera_io_r(ispif->base +
-		ISPIF_IRQ_STATUS_1_ADDR);
-	out->ispifIrqStatus2 = msm_camera_io_r(ispif->base +
-		ISPIF_IRQ_STATUS_2_ADDR);
-	msm_camera_io_w(out->ispifIrqStatus0,
-		ispif->base + ISPIF_IRQ_CLEAR_ADDR);
-	msm_camera_io_w(out->ispifIrqStatus1,
-		ispif->base + ISPIF_IRQ_CLEAR_1_ADDR);
-	msm_camera_io_w(out->ispifIrqStatus2,
-		ispif->base + ISPIF_IRQ_CLEAR_2_ADDR);
-
-	CDBG("%s: irq vfe0 Irq_status0 = 0x%x, 1 = 0x%x, 2 = 0x%x\n",
-		__func__, out->ispifIrqStatus0, out->ispifIrqStatus1,
-		out->ispifIrqStatus2);
-	if (out->ispifIrqStatus0 & ISPIF_IRQ_STATUS_MASK) {
-		if (out->ispifIrqStatus0 & (0x1 << RESET_DONE_IRQ))
-			complete(&ispif->reset_complete);
-		if (out->ispifIrqStatus0 & (0x1 << PIX_INTF_0_OVERFLOW_IRQ))
-			pr_err("%s: pix intf 0 overflow.\n", __func__);
-		if (out->ispifIrqStatus0 & (0x1 << RAW_INTF_0_OVERFLOW_IRQ))
-			pr_err("%s: rdi intf 0 overflow.\n", __func__);
-		if (out->ispifIrqStatus1 & (0x1 << RAW_INTF_1_OVERFLOW_IRQ))
-			pr_err("%s: rdi intf 1 overflow.\n", __func__);
-		if (out->ispifIrqStatus2 & (0x1 << RAW_INTF_2_OVERFLOW_IRQ))
-			pr_err("%s: rdi intf 2 overflow.\n", __func__);
-		if ((out->ispifIrqStatus0 & ISPIF_IRQ_STATUS_SOF_MASK) ||
-			(out->ispifIrqStatus1 &	ISPIF_IRQ_STATUS_SOF_MASK) ||
-			(out->ispifIrqStatus2 & ISPIF_IRQ_STATUS_RDI2_SOF_MASK))
-			ispif_process_irq(ispif, out);
-	}
-	if (ispif->csid_version == CSID_VERSION_V3) {
-		status0 = msm_camera_io_r(ispif->base +
-			ISPIF_IRQ_STATUS_ADDR + 0x200);
-		msm_camera_io_w(status0,
-			ispif->base + ISPIF_IRQ_CLEAR_ADDR + 0x200);
-		status1 = msm_camera_io_r(ispif->base +
-			ISPIF_IRQ_STATUS_1_ADDR + 0x200);
-		msm_camera_io_w(status1,
-			ispif->base + ISPIF_IRQ_CLEAR_1_ADDR + 0x200);
-		status2 = msm_camera_io_r(ispif->base +
-			ISPIF_IRQ_STATUS_2_ADDR + 0x200);
-		msm_camera_io_w(status2,
-			ispif->base + ISPIF_IRQ_CLEAR_2_ADDR + 0x200);
-		CDBG("%s: irq vfe1 Irq_status0 = 0x%x, 1 = 0x%x, 2 = 0x%x\n",
-			__func__, status0, status1, status2);
-	}
-	msm_camera_io_w(ISPIF_IRQ_GLOBAL_CLEAR_CMD, ispif->base +
-		ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR);
-}
-
-static irqreturn_t msm_io_ispif_irq(int irq_num, void *data)
-{
-	struct ispif_irq_status irq;
-	msm_ispif_read_irq_status(&irq, data);
-	return IRQ_HANDLED;
-}
-
-static struct msm_cam_clk_info ispif_8960_clk_info[] = {
-	{"csi_pix_clk", 0},
-	{"csi_rdi_clk", 0},
-	{"csi_pix1_clk", 0},
-	{"csi_rdi1_clk", 0},
-	{"csi_rdi2_clk", 0},
-};
-
-static int msm_ispif_init(struct ispif_device *ispif,
-	const uint32_t *csid_version)
-{
-	int rc = 0;
-	CDBG("%s called %d\n", __func__, __LINE__);
-
-	if (ispif->ispif_state == ISPIF_POWER_UP) {
-		pr_err("%s: ispif invalid state %d\n", __func__,
-			ispif->ispif_state);
-		rc = -EINVAL;
-		return rc;
-	}
-
-	spin_lock_init(&ispif_tasklet_lock);
-	INIT_LIST_HEAD(&ispif_tasklet_q);
-	rc = request_irq(ispif->irq->start, msm_io_ispif_irq,
-		IRQF_TRIGGER_RISING, "ispif", ispif);
-	ispif->global_intf_cmd_mask = 0xFFFFFFFF;
-	init_completion(&ispif->reset_complete);
-
-	tasklet_init(&ispif->ispif_tasklet,
-		ispif_do_tasklet, (unsigned long)ispif);
-
-	ispif->csid_version = *csid_version;
-	if (ispif->csid_version < CSID_VERSION_V2) {
-		rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_8960_clk_info,
-			ispif->ispif_clk, 2, 1);
-		if (rc < 0)
-			return rc;
-	} else if (ispif->csid_version == CSID_VERSION_V2) {
-		rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_8960_clk_info,
-			ispif->ispif_clk, ARRAY_SIZE(ispif_8960_clk_info), 1);
-		if (rc < 0)
-			return rc;
-	}
-	rc = msm_ispif_reset(ispif);
-	ispif->ispif_state = ISPIF_POWER_UP;
-	return rc;
-}
-
-static void msm_ispif_release(struct ispif_device *ispif)
-{
-	if (ispif->ispif_state != ISPIF_POWER_UP) {
-		pr_err("%s: ispif invalid state %d\n", __func__,
-			ispif->ispif_state);
-		return;
-	}
-
-	CDBG("%s, free_irq\n", __func__);
-	free_irq(ispif->irq->start, ispif);
-	tasklet_kill(&ispif->ispif_tasklet);
-
-	if (ispif->csid_version < CSID_VERSION_V2) {
-		msm_cam_clk_enable(&ispif->pdev->dev, ispif_8960_clk_info,
-			ispif->ispif_clk, 2, 0);
-	} else if (ispif->csid_version == CSID_VERSION_V2) {
-		msm_cam_clk_enable(&ispif->pdev->dev, ispif_8960_clk_info,
-			ispif->ispif_clk, ARRAY_SIZE(ispif_8960_clk_info), 0);
-	}
-	ispif->ispif_state = ISPIF_POWER_DOWN;
-}
-
-static long msm_ispif_cmd(struct v4l2_subdev *sd, void *arg)
-{
-	long rc = 0;
-	struct ispif_cfg_data cdata;
-	struct ispif_device *ispif =
-		(struct ispif_device *)v4l2_get_subdevdata(sd);
-	if (copy_from_user(&cdata, (void *)arg, sizeof(struct ispif_cfg_data)))
-		return -EFAULT;
-	CDBG("%s cfgtype = %d\n", __func__, cdata.cfgtype);
-	switch (cdata.cfgtype) {
-	case ISPIF_INIT:
-		CDBG("%s csid_version = %x\n", __func__,
-			cdata.cfg.csid_version);
-		rc = msm_ispif_init(ispif, &cdata.cfg.csid_version);
-		break;
-	case ISPIF_SET_CFG:
-		CDBG("%s len = %d, intftype = %d,.cid_mask = %d, csid = %d\n",
-			__func__,
-			cdata.cfg.ispif_params.len,
-			cdata.cfg.ispif_params.params[0].intftype,
-			cdata.cfg.ispif_params.params[0].cid_mask,
-			cdata.cfg.ispif_params.params[0].csid);
-		rc = msm_ispif_config(ispif, &cdata.cfg.ispif_params);
-		break;
-
-	case ISPIF_SET_ON_FRAME_BOUNDARY:
-	case ISPIF_SET_OFF_FRAME_BOUNDARY:
-	case ISPIF_SET_OFF_IMMEDIATELY:
-		rc = msm_ispif_subdev_video_s_stream(sd, cdata.cfg.cmd);
-		break;
-	case ISPIF_RELEASE:
-		msm_ispif_release(ispif);
-		break;
-	default:
-		break;
-	}
-
-	return rc;
-}
-
-static long msm_ispif_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd,
-								void *arg)
-{
-	switch (cmd) {
-	case VIDIOC_MSM_ISPIF_CFG:
-		return msm_ispif_cmd(sd, arg);
-	default:
-		return -ENOIOCTLCMD;
-	}
-}
-
-static struct v4l2_subdev_core_ops msm_ispif_subdev_core_ops = {
-	.g_chip_ident = &msm_ispif_subdev_g_chip_ident,
-	.ioctl = &msm_ispif_subdev_ioctl,
-};
-
-static struct v4l2_subdev_video_ops msm_ispif_subdev_video_ops = {
-	.s_stream = &msm_ispif_subdev_video_s_stream,
-};
-
-static const struct v4l2_subdev_ops msm_ispif_subdev_ops = {
-	.core = &msm_ispif_subdev_core_ops,
-	.video = &msm_ispif_subdev_video_ops,
-};
-
-static const struct v4l2_subdev_internal_ops msm_ispif_internal_ops;
-
-static int __devinit ispif_probe(struct platform_device *pdev)
-{
-	int rc = 0;
-	struct msm_cam_subdev_info sd_info;
-	struct ispif_device *ispif;
-
-	CDBG("%s\n", __func__);
-	ispif = kzalloc(sizeof(struct ispif_device), GFP_KERNEL);
-	if (!ispif) {
-		pr_err("%s: no enough memory\n", __func__);
-		return -ENOMEM;
-	}
-
-	v4l2_subdev_init(&ispif->subdev, &msm_ispif_subdev_ops);
-	ispif->subdev.internal_ops = &msm_ispif_internal_ops;
-	ispif->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-	snprintf(ispif->subdev.name,
-			ARRAY_SIZE(ispif->subdev.name), "msm_ispif");
-	v4l2_set_subdevdata(&ispif->subdev, ispif);
-	platform_set_drvdata(pdev, &ispif->subdev);
-	snprintf(ispif->subdev.name, sizeof(ispif->subdev.name),
-								"ispif");
-	mutex_init(&ispif->mutex);
-
-	if (pdev->dev.of_node)
-		of_property_read_u32((&pdev->dev)->of_node,
-			"cell-index", &pdev->id);
-
-	ispif->mem = platform_get_resource_byname(pdev,
-					IORESOURCE_MEM, "ispif");
-	if (!ispif->mem) {
-		pr_err("%s: no mem resource?\n", __func__);
-		rc = -ENODEV;
-		goto ispif_no_resource;
-	}
-	ispif->irq = platform_get_resource_byname(pdev,
-					IORESOURCE_IRQ, "ispif");
-	if (!ispif->irq) {
-		pr_err("%s: no irq resource?\n", __func__);
-		rc = -ENODEV;
-		goto ispif_no_resource;
-	}
-	ispif->io = request_mem_region(ispif->mem->start,
-		resource_size(ispif->mem), pdev->name);
-	if (!ispif->io) {
-		pr_err("%s: no valid mem region\n", __func__);
-		rc = -EBUSY;
-		goto ispif_no_resource;
-	}
-	ispif->base = ioremap(ispif->mem->start,
-		resource_size(ispif->mem));
-	if (!ispif->base) {
-		rc = -ENOMEM;
-		goto ispif_no_mem;
-	}
-
-	ispif->pdev = pdev;
-	sd_info.sdev_type = ISPIF_DEV;
-	sd_info.sd_index = pdev->id;
-	sd_info.irq_num = ispif->irq->start;
-	msm_cam_register_subdev_node(&ispif->subdev, &sd_info);
-
-	media_entity_init(&ispif->subdev.entity, 0, NULL, 0);
-	ispif->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
-	ispif->subdev.entity.group_id = ISPIF_DEV;
-	ispif->subdev.entity.name = pdev->name;
-	ispif->subdev.entity.revision = ispif->subdev.devnode->num;
-	ispif->ispif_state = ISPIF_POWER_DOWN;
-	return 0;
-
-ispif_no_mem:
-	release_mem_region(ispif->mem->start,
-		resource_size(ispif->mem));
-ispif_no_resource:
-	mutex_destroy(&ispif->mutex);
-	kfree(ispif);
-	return rc;
-}
-
-static const struct of_device_id msm_ispif_dt_match[] = {
-	{.compatible = "qcom,ispif"},
-};
-
-MODULE_DEVICE_TABLE(of, msm_ispif_dt_match);
-
-static struct platform_driver ispif_driver = {
-	.probe = ispif_probe,
-	.driver = {
-		.name = MSM_ISPIF_DRV_NAME,
-		.owner = THIS_MODULE,
-		.of_match_table = msm_ispif_dt_match,
-	},
-};
-
-static int __init msm_ispif_init_module(void)
-{
-	return platform_driver_register(&ispif_driver);
-}
-
-static void __exit msm_ispif_exit_module(void)
-{
-	platform_driver_unregister(&ispif_driver);
-}
-
-module_init(msm_ispif_init_module);
-module_exit(msm_ispif_exit_module);
-MODULE_DESCRIPTION("MSM ISP Interface driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/csi/msm_ispif.h b/drivers/media/video/msm/csi/msm_ispif.h
deleted file mode 100644
index d4ca864..0000000
--- a/drivers/media/video/msm/csi/msm_ispif.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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 MSM_ISPIF_H
-#define MSM_ISPIF_H
-
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <media/v4l2-subdev.h>
-
-struct ispif_irq_status {
-	uint32_t ispifIrqStatus0;
-	uint32_t ispifIrqStatus1;
-	uint32_t ispifIrqStatus2;
-};
-
-enum msm_ispif_state_t {
-	ISPIF_POWER_UP,
-	ISPIF_POWER_DOWN,
-};
-
-struct ispif_device {
-	struct platform_device *pdev;
-	struct v4l2_subdev subdev;
-	struct resource *mem;
-	struct resource *irq;
-	struct resource *io;
-	void __iomem *base;
-	struct mutex mutex;
-	uint8_t start_ack_pending;
-	struct completion reset_complete;
-	uint32_t csid_version;
-	struct clk *ispif_clk[5];
-	uint32_t pix_sof_count;
-	uint32_t rdi0_sof_count;
-	uint32_t rdi1_sof_count;
-	uint32_t rdi2_sof_count;
-	uint32_t global_intf_cmd_mask;
-	struct tasklet_struct ispif_tasklet;
-	enum msm_ispif_state_t ispif_state;
-};
-
-struct ispif_isr_queue_cmd {
-	struct list_head list;
-	uint32_t    ispifInterruptStatus0;
-	uint32_t    ispifInterruptStatus1;
-	uint32_t    ispifInterruptStatus2;
-};
-
-#define VIDIOC_MSM_ISPIF_CFG \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 18, struct ispif_cfg_data*)
-
-#endif
diff --git a/drivers/media/video/msm/eeprom/Makefile b/drivers/media/video/msm/eeprom/Makefile
deleted file mode 100644
index f7b7f5d..0000000
--- a/drivers/media/video/msm/eeprom/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
-EXTRA_CFLAGS += -Idrivers/media/video/msm/io
-obj-$(CONFIG_MSM_EEPROM) += msm_camera_eeprom.o
-obj-$(CONFIG_IMX074_EEPROM) += imx074_eeprom.o
-obj-$(CONFIG_IMX091_EEPROM) += imx091_eeprom.o
\ No newline at end of file
diff --git a/drivers/media/video/msm/eeprom/imx074_eeprom.c b/drivers/media/video/msm/eeprom/imx074_eeprom.c
deleted file mode 100644
index a99b17e..0000000
--- a/drivers/media/video/msm/eeprom/imx074_eeprom.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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 "msm_camera_eeprom.h"
-#include "msm_camera_i2c.h"
-
-DEFINE_MUTEX(imx074_eeprom_mutex);
-static struct msm_eeprom_ctrl_t imx074_eeprom_t;
-
-static const struct i2c_device_id imx074_eeprom_i2c_id[] = {
-	{"imx074_eeprom", (kernel_ulong_t)&imx074_eeprom_t},
-	{ }
-};
-
-static struct i2c_driver imx074_eeprom_i2c_driver = {
-	.id_table = imx074_eeprom_i2c_id,
-	.probe  = msm_eeprom_i2c_probe,
-	.remove = __exit_p(imx074_eeprom_i2c_remove),
-	.driver = {
-		.name = "imx074_eeprom",
-	},
-};
-
-static int __init imx074_eeprom_i2c_add_driver(void)
-{
-	int rc = 0;
-	rc = i2c_add_driver(imx074_eeprom_t.i2c_driver);
-	return rc;
-}
-
-static struct v4l2_subdev_core_ops imx074_eeprom_subdev_core_ops = {
-	.ioctl = msm_eeprom_subdev_ioctl,
-};
-
-static struct v4l2_subdev_ops imx074_eeprom_subdev_ops = {
-	.core = &imx074_eeprom_subdev_core_ops,
-};
-
-static uint8_t imx074_wbcalib_data[6];
-static struct msm_calib_wb imx074_wb_data;
-
-static struct msm_camera_eeprom_info_t imx074_calib_supp_info = {
-	{FALSE, 0, 0, 1},
-	{TRUE, 6, 0, 1024},
-	{FALSE, 0, 0, 1},
-	{FALSE, 0, 0, 1},
-	{FALSE, 0, 0, 1},
-};
-
-static struct msm_camera_eeprom_read_t imx074_eeprom_read_tbl[] = {
-	{0x10, &imx074_wbcalib_data[0], 6, 0},
-};
-
-
-static struct msm_camera_eeprom_data_t imx074_eeprom_data_tbl[] = {
-	{&imx074_wb_data, sizeof(struct msm_calib_wb)},
-};
-
-static void imx074_format_wbdata(void)
-{
-	imx074_wb_data.r_over_g = (uint16_t)(imx074_wbcalib_data[0] << 8) |
-		imx074_wbcalib_data[1];
-	imx074_wb_data.b_over_g = (uint16_t)(imx074_wbcalib_data[2] << 8) |
-		imx074_wbcalib_data[3];
-	imx074_wb_data.gr_over_gb = (uint16_t)(imx074_wbcalib_data[4] << 8) |
-		imx074_wbcalib_data[5];
-}
-
-void imx074_format_calibrationdata(void)
-{
-	imx074_format_wbdata();
-}
-static struct msm_eeprom_ctrl_t imx074_eeprom_t = {
-	.i2c_driver = &imx074_eeprom_i2c_driver,
-	.i2c_addr = 0xA4,
-	.eeprom_v4l2_subdev_ops = &imx074_eeprom_subdev_ops,
-
-	.i2c_client = {
-		.addr_type = MSM_CAMERA_I2C_BYTE_ADDR,
-	},
-
-	.eeprom_mutex = &imx074_eeprom_mutex,
-
-	.func_tbl = {
-		.eeprom_init = NULL,
-		.eeprom_release = NULL,
-		.eeprom_get_info = msm_camera_eeprom_get_info,
-		.eeprom_get_data = msm_camera_eeprom_get_data,
-		.eeprom_set_dev_addr = NULL,
-		.eeprom_format_data = imx074_format_calibrationdata,
-	},
-	.info = &imx074_calib_supp_info,
-	.info_size = sizeof(struct msm_camera_eeprom_info_t),
-	.read_tbl = imx074_eeprom_read_tbl,
-	.read_tbl_size = ARRAY_SIZE(imx074_eeprom_read_tbl),
-	.data_tbl = imx074_eeprom_data_tbl,
-	.data_tbl_size = ARRAY_SIZE(imx074_eeprom_data_tbl),
-};
-
-subsys_initcall(imx074_eeprom_i2c_add_driver);
-MODULE_DESCRIPTION("IMX074 EEPROM");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/eeprom/imx091_eeprom.c b/drivers/media/video/msm/eeprom/imx091_eeprom.c
deleted file mode 100644
index c53eb20..0000000
--- a/drivers/media/video/msm/eeprom/imx091_eeprom.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 "msm_camera_eeprom.h"
-#include "msm_camera_i2c.h"
-
-DEFINE_MUTEX(imx091_eeprom_mutex);
-static struct msm_eeprom_ctrl_t imx091_eeprom_t;
-
-static const struct i2c_device_id imx091_eeprom_i2c_id[] = {
-	{"imx091_eeprom", (kernel_ulong_t)&imx091_eeprom_t},
-	{ }
-};
-
-static struct i2c_driver imx091_eeprom_i2c_driver = {
-	.id_table = imx091_eeprom_i2c_id,
-	.probe  = msm_eeprom_i2c_probe,
-	.remove = __exit_p(imx091_eeprom_i2c_remove),
-	.driver = {
-		.name = "imx091_eeprom",
-	},
-};
-
-static int __init imx091_eeprom_i2c_add_driver(void)
-{
-	int rc = 0;
-	rc = i2c_add_driver(imx091_eeprom_t.i2c_driver);
-	return rc;
-}
-
-static struct v4l2_subdev_core_ops imx091_eeprom_subdev_core_ops = {
-	.ioctl = msm_eeprom_subdev_ioctl,
-};
-
-static struct v4l2_subdev_ops imx091_eeprom_subdev_ops = {
-	.core = &imx091_eeprom_subdev_core_ops,
-};
-
-static uint8_t imx091_wbcalib_data[6];
-static uint8_t imx091_afcalib_data[6];
-static struct msm_calib_wb imx091_wb_data;
-static struct msm_calib_af imx091_af_data;
-
-static struct msm_camera_eeprom_info_t imx091_calib_supp_info = {
-	{TRUE, 6, 1, 1},
-	{TRUE, 6, 0, 32768},
-	{FALSE, 0, 0, 1},
-	{FALSE, 0, 0, 1},
-	{FALSE, 0, 0, 1},
-};
-
-static struct msm_camera_eeprom_read_t imx091_eeprom_read_tbl[] = {
-	{0x05, &imx091_wbcalib_data[0], 6, 0},
-	{0x0B, &imx091_afcalib_data[0], 6, 0},
-};
-
-
-static struct msm_camera_eeprom_data_t imx091_eeprom_data_tbl[] = {
-	{&imx091_wb_data, sizeof(struct msm_calib_wb)},
-	{&imx091_af_data, sizeof(struct msm_calib_af)},
-};
-
-static void imx091_format_wbdata(void)
-{
-	imx091_wb_data.r_over_g = (uint16_t)(imx091_wbcalib_data[1] << 8) |
-		(imx091_wbcalib_data[0] - 0x32);
-	imx091_wb_data.b_over_g = (uint16_t)(imx091_wbcalib_data[3] << 8) |
-		(imx091_wbcalib_data[2] - 0x32);
-	imx091_wb_data.gr_over_gb = (uint16_t)(imx091_wbcalib_data[5] << 8) |
-		(imx091_wbcalib_data[4] - 0x32);
-}
-
-static void imx091_format_afdata(void)
-{
-	imx091_af_data.inf_dac = (uint16_t)(imx091_afcalib_data[1] << 8) |
-		imx091_afcalib_data[0];
-	imx091_af_data.macro_dac = (uint16_t)(imx091_afcalib_data[3] << 8) |
-		imx091_afcalib_data[2];
-	imx091_af_data.start_dac = (uint16_t)(imx091_afcalib_data[5] << 8) |
-		imx091_afcalib_data[4];
-}
-
-void imx091_format_calibrationdata(void)
-{
-	imx091_format_wbdata();
-	imx091_format_afdata();
-}
-static struct msm_eeprom_ctrl_t imx091_eeprom_t = {
-	.i2c_driver = &imx091_eeprom_i2c_driver,
-	.i2c_addr = 0xA1,
-	.eeprom_v4l2_subdev_ops = &imx091_eeprom_subdev_ops,
-
-	.i2c_client = {
-		.addr_type = MSM_CAMERA_I2C_BYTE_ADDR,
-	},
-
-	.eeprom_mutex = &imx091_eeprom_mutex,
-
-	.func_tbl = {
-		.eeprom_init = NULL,
-		.eeprom_release = NULL,
-		.eeprom_get_info = msm_camera_eeprom_get_info,
-		.eeprom_get_data = msm_camera_eeprom_get_data,
-		.eeprom_set_dev_addr = NULL,
-		.eeprom_format_data = imx091_format_calibrationdata,
-	},
-	.info = &imx091_calib_supp_info,
-	.info_size = sizeof(struct msm_camera_eeprom_info_t),
-	.read_tbl = imx091_eeprom_read_tbl,
-	.read_tbl_size = ARRAY_SIZE(imx091_eeprom_read_tbl),
-	.data_tbl = imx091_eeprom_data_tbl,
-	.data_tbl_size = ARRAY_SIZE(imx091_eeprom_data_tbl),
-};
-
-subsys_initcall(imx091_eeprom_i2c_add_driver);
-MODULE_DESCRIPTION("imx091 EEPROM");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/eeprom/msm_camera_eeprom.c b/drivers/media/video/msm/eeprom/msm_camera_eeprom.c
deleted file mode 100644
index effae8b..0000000
--- a/drivers/media/video/msm/eeprom/msm_camera_eeprom.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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 "msm_camera_eeprom.h"
-
-int32_t msm_camera_eeprom_read(struct msm_eeprom_ctrl_t *ectrl,
-	uint32_t reg_addr, void *data, uint32_t num_byte,
-	uint16_t convert_endian)
-{
-	int rc = 0;
-	if (ectrl->func_tbl.eeprom_set_dev_addr != NULL)
-		ectrl->func_tbl.eeprom_set_dev_addr(ectrl, &reg_addr);
-
-	if (!convert_endian) {
-		rc = msm_camera_i2c_read_seq(
-			&ectrl->i2c_client, reg_addr, data, num_byte);
-	} else {
-		unsigned char buf[num_byte];
-		uint8_t *data_ptr = (uint8_t *) data;
-		int i;
-		rc = msm_camera_i2c_read_seq(
-			&ectrl->i2c_client, reg_addr, buf, num_byte);
-		for (i = 0; i < num_byte; i += 2) {
-			data_ptr[i] = buf[i+1];
-			data_ptr[i+1] = buf[i];
-		}
-	}
-	return rc;
-}
-
-int32_t msm_camera_eeprom_read_tbl(struct msm_eeprom_ctrl_t *ectrl,
-	struct msm_camera_eeprom_read_t *read_tbl, uint16_t tbl_size)
-{
-	int i, rc = 0;
-	CDBG("%s: open\n", __func__);
-	if (read_tbl == NULL)
-		return rc;
-
-	for (i = 0; i < tbl_size; i++) {
-		rc = msm_camera_eeprom_read
-			(ectrl, read_tbl[i].reg_addr,
-			read_tbl[i].dest_ptr, read_tbl[i].num_byte,
-			read_tbl[i].convert_endian);
-		if (rc < 0) {
-			pr_err("%s: read failed\n", __func__);
-			return rc;
-		}
-	}
-	CDBG("%s: done\n", __func__);
-	return rc;
-}
-
-int32_t msm_camera_eeprom_get_info(struct msm_eeprom_ctrl_t *ectrl,
-	struct msm_camera_eeprom_info_t *einfo)
-{
-	int rc = 0;
-	CDBG("%s: open\n", __func__);
-	memcpy(einfo, ectrl->info, ectrl->info_size);
-	CDBG("%s: done =%d\n", __func__, rc);
-	return rc;
-}
-
-int32_t msm_camera_eeprom_get_data(struct msm_eeprom_ctrl_t *ectrl,
-	struct msm_eeprom_data_t *edata)
-{
-	int rc = 0;
-	if (edata->index >= ectrl->data_tbl_size)
-		return -EFAULT;
-	if (copy_to_user(edata->eeprom_data,
-		ectrl->data_tbl[edata->index].data,
-		ectrl->data_tbl[edata->index].size))
-		rc = -EFAULT;
-	return rc;
-}
-
-int32_t msm_eeprom_config(struct msm_eeprom_ctrl_t *e_ctrl,
-	void __user *argp)
-{
-	struct msm_eeprom_cfg_data cdata;
-	int32_t rc = 0;
-	if (copy_from_user(&cdata,
-		(void *)argp,
-		sizeof(struct msm_eeprom_cfg_data)))
-		return -EFAULT;
-	mutex_lock(e_ctrl->eeprom_mutex);
-
-	switch (cdata.cfgtype) {
-	case CFG_GET_EEPROM_INFO:
-		if (e_ctrl->func_tbl.eeprom_get_info == NULL) {
-			rc = -EFAULT;
-			break;
-		}
-		rc = e_ctrl->func_tbl.eeprom_get_info(e_ctrl,
-			&cdata.cfg.get_info);
-		cdata.is_eeprom_supported = 1;
-		if (copy_to_user((void *)argp,
-			&cdata,
-			sizeof(struct msm_eeprom_cfg_data)))
-			rc = -EFAULT;
-		break;
-	case CFG_GET_EEPROM_DATA:
-		if (e_ctrl->func_tbl.eeprom_get_data == NULL) {
-			rc = -EFAULT;
-			break;
-		}
-		rc = e_ctrl->func_tbl.eeprom_get_data(e_ctrl,
-			&cdata.cfg.get_data);
-
-		if (copy_to_user((void *)argp,
-			&cdata,
-			sizeof(struct msm_eeprom_cfg_data)))
-			rc = -EFAULT;
-		break;
-	default:
-		break;
-	}
-	mutex_unlock(e_ctrl->eeprom_mutex);
-	return rc;
-}
-
-struct msm_eeprom_ctrl_t *get_ectrl(struct v4l2_subdev *sd)
-{
-	return container_of(sd, struct msm_eeprom_ctrl_t, sdev);
-}
-
-long msm_eeprom_subdev_ioctl(struct v4l2_subdev *sd,
-	unsigned int cmd, void *arg)
-{
-	struct msm_eeprom_ctrl_t *e_ctrl = get_ectrl(sd);
-	void __user *argp = (void __user *)arg;
-	switch (cmd) {
-	case VIDIOC_MSM_EEPROM_CFG:
-		return msm_eeprom_config(e_ctrl, argp);
-	default:
-		return -ENOIOCTLCMD;
-	}
-}
-
-int32_t msm_eeprom_i2c_probe(struct i2c_client *client,
-	const struct i2c_device_id *id)
-{
-	int rc = 0;
-	struct msm_eeprom_ctrl_t *e_ctrl_t = NULL;
-	CDBG("%s called\n", __func__);
-
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		pr_err("i2c_check_functionality failed\n");
-		goto probe_failure;
-	}
-
-	e_ctrl_t = (struct msm_eeprom_ctrl_t *)(id->driver_data);
-	e_ctrl_t->i2c_client.client = client;
-
-	if (e_ctrl_t->i2c_addr != 0)
-		e_ctrl_t->i2c_client.client->addr = e_ctrl_t->i2c_addr;
-
-	CDBG("%s client = %x\n", __func__, (unsigned int) client);
-
-	/* Assign name for sub device */
-	snprintf(e_ctrl_t->sdev.name, sizeof(e_ctrl_t->sdev.name),
-		"%s", e_ctrl_t->i2c_driver->driver.name);
-
-	if (e_ctrl_t->func_tbl.eeprom_init != NULL) {
-		rc = e_ctrl_t->func_tbl.eeprom_init(e_ctrl_t,
-			e_ctrl_t->i2c_client.client->adapter);
-	}
-	msm_camera_eeprom_read_tbl(e_ctrl_t,
-		e_ctrl_t->read_tbl,
-		e_ctrl_t->read_tbl_size);
-
-	if (e_ctrl_t->func_tbl.eeprom_format_data != NULL)
-		e_ctrl_t->func_tbl.eeprom_format_data();
-
-	if (e_ctrl_t->func_tbl.eeprom_release != NULL)
-		rc = e_ctrl_t->func_tbl.eeprom_release(e_ctrl_t);
-
-
-	/* Initialize sub device */
-	v4l2_i2c_subdev_init(&e_ctrl_t->sdev,
-		e_ctrl_t->i2c_client.client,
-		e_ctrl_t->eeprom_v4l2_subdev_ops);
-	CDBG("%s success resut=%d\n", __func__, rc);
-	return rc;
-
-probe_failure:
-	pr_err("%s failed! rc = %d\n", __func__, rc);
-	return rc;
-}
diff --git a/drivers/media/video/msm/eeprom/msm_camera_eeprom.h b/drivers/media/video/msm/eeprom/msm_camera_eeprom.h
deleted file mode 100644
index 830e5d8..0000000
--- a/drivers/media/video/msm/eeprom/msm_camera_eeprom.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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 MSM_CAMERA_EEPROM_H
-#define MSM_CAMERA_EEPROM_H
-
-#include <linux/delay.h>
-#include <mach/camera.h>
-#include <media/v4l2-subdev.h>
-#include "msm_camera_i2c.h"
-
-#define TRUE  1
-#define FALSE 0
-
-struct msm_eeprom_ctrl_t;
-
-struct msm_camera_eeprom_fn_t {
-	int32_t (*eeprom_init)
-		(struct msm_eeprom_ctrl_t *ectrl,
-		struct i2c_adapter *adapter);
-	int32_t (*eeprom_release)
-		(struct msm_eeprom_ctrl_t *ectrl);
-	int32_t (*eeprom_get_info)
-		(struct msm_eeprom_ctrl_t *ectrl,
-		 struct msm_camera_eeprom_info_t *einfo);
-	int32_t (*eeprom_get_data)
-		(struct msm_eeprom_ctrl_t *ectrl,
-		 struct msm_eeprom_data_t *edata);
-	void (*eeprom_set_dev_addr)
-		(struct msm_eeprom_ctrl_t*, uint32_t*);
-	void (*eeprom_format_data)
-		(void);
-};
-
-struct msm_camera_eeprom_read_t {
-	uint32_t reg_addr;
-	void *dest_ptr;
-	uint32_t num_byte;
-	uint16_t convert_endian;
-};
-
-struct msm_camera_eeprom_data_t {
-	void *data;
-	uint16_t size;
-};
-
-struct msm_eeprom_ctrl_t {
-	struct msm_camera_i2c_client i2c_client;
-	uint16_t i2c_addr;
-	struct i2c_driver *i2c_driver;
-	struct mutex *eeprom_mutex;
-	struct v4l2_subdev sdev;
-	struct v4l2_subdev_ops *eeprom_v4l2_subdev_ops;
-	struct msm_camera_eeprom_fn_t func_tbl;
-	struct msm_camera_eeprom_info_t *info;
-	uint16_t info_size;
-	struct msm_camera_eeprom_read_t *read_tbl;
-	uint16_t read_tbl_size;
-	struct msm_camera_eeprom_data_t *data_tbl;
-	uint16_t data_tbl_size;
-};
-
-int32_t msm_camera_eeprom_get_data(struct msm_eeprom_ctrl_t *ectrl,
-	struct msm_eeprom_data_t *edata);
-int32_t msm_camera_eeprom_get_info(struct msm_eeprom_ctrl_t *ectrl,
-	struct msm_camera_eeprom_info_t *einfo);
-int32_t msm_eeprom_i2c_probe(struct i2c_client *client,
-	const struct i2c_device_id *id);
-long msm_eeprom_subdev_ioctl(struct v4l2_subdev *sd,
-	unsigned int cmd, void *arg);
-
-#define VIDIOC_MSM_EEPROM_CFG \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 12, void __user *)
-#endif
diff --git a/drivers/media/video/msm/flash/Makefile b/drivers/media/video/msm/flash/Makefile
deleted file mode 100644
index 8d0812b..0000000
--- a/drivers/media/video/msm/flash/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
-ccflags-y += -Idrivers/media/video/msm
-ccflags-y += -Idrivers/media/video/msm/io
-obj-$(CONFIG_MSM_CAMERA_FLASH) += msm_flash.o
-obj-$(CONFIG_MSM_CAMERA_FLASH_SC628A) += sc628a.o
-obj-$(CONFIG_MSM_CAMERA_FLASH_TPS61310) += tps61310.o
-obj-$(CONFIG_MSM_CAMERA_FLASH_PMIC_FLASH) += pmic8058_flash.o
-obj-$(CONFIG_MSM_CAMERA_FLASH_SGM3141) += sgm3141.o
-obj-$(CONFIG_MSM_CAMERA_FLASH_PMIC8058_PWM) += pmic8058_pwm.o
-obj-$(CONFIG_MSM_CAMERA_LED_TRIGGER_FLASH) += led_trigger_flash.o
diff --git a/drivers/media/video/msm/gemini/Makefile b/drivers/media/video/msm/gemini/Makefile
deleted file mode 100644
index 8a7cd93..0000000
--- a/drivers/media/video/msm/gemini/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
-EXTRA_CFLAGS += -Idrivers/media/video/msm
-obj-$(CONFIG_MSM_GEMINI) += msm_gemini_dev.o msm_gemini_sync.o msm_gemini_core.o msm_gemini_hw.o msm_gemini_platform.o
diff --git a/drivers/media/video/msm/gemini/msm_gemini_common.h b/drivers/media/video/msm/gemini/msm_gemini_common.h
deleted file mode 100644
index 0ddedc5..0000000
--- a/drivers/media/video/msm/gemini/msm_gemini_common.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. 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 MSM_GEMINI_COMMON_H
-#define MSM_GEMINI_COMMON_H
-
-#define MSM_GEMINI_DEBUG
-#ifdef MSM_GEMINI_DEBUG
-#define GMN_DBG(fmt, args...) pr_debug(fmt, ##args)
-#else
-#define GMN_DBG(fmt, args...) do { } while (0)
-#endif
-
-#define GMN_PR_ERR   pr_err
-
-enum GEMINI_MODE {
-	GEMINI_MODE_DISABLE,
-	GEMINI_MODE_OFFLINE,
-	GEMINI_MODE_REALTIME,
-	GEMINI_MODE_REALTIME_ROTATION
-};
-
-enum GEMINI_ROTATION {
-	GEMINI_ROTATION_0,
-	GEMINI_ROTATION_90,
-	GEMINI_ROTATION_180,
-	GEMINI_ROTATION_270
-};
-
-#endif /* MSM_GEMINI_COMMON_H */
diff --git a/drivers/media/video/msm/gemini/msm_gemini_core.c b/drivers/media/video/msm/gemini/msm_gemini_core.c
deleted file mode 100644
index 45d3937..0000000
--- a/drivers/media/video/msm/gemini/msm_gemini_core.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. 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/sched.h>
-#include "msm_gemini_hw.h"
-#include "msm_gemini_core.h"
-#include "msm_gemini_platform.h"
-#include "msm_gemini_common.h"
-
-static struct msm_gemini_hw_pingpong fe_pingpong_buf;
-static struct msm_gemini_hw_pingpong we_pingpong_buf;
-static int we_pingpong_index;
-static int reset_done_ack;
-static spinlock_t reset_lock;
-static wait_queue_head_t reset_wait;
-
-int msm_gemini_core_reset(uint8_t op_mode, void *base, int size)
-{
-	unsigned long flags;
-	int rc = 0;
-	int tm = 500; /*500ms*/
-	memset(&fe_pingpong_buf, 0, sizeof(fe_pingpong_buf));
-	fe_pingpong_buf.is_fe = 1;
-	we_pingpong_index = 0;
-	memset(&we_pingpong_buf, 0, sizeof(we_pingpong_buf));
-	spin_lock_irqsave(&reset_lock, flags);
-	reset_done_ack = 0;
-	msm_gemini_hw_reset(base, size);
-	spin_unlock_irqrestore(&reset_lock, flags);
-	rc = wait_event_interruptible_timeout(
-			reset_wait,
-			reset_done_ack,
-			msecs_to_jiffies(tm));
-
-	if (!reset_done_ack) {
-		GMN_DBG("%s: reset ACK failed %d", __func__, rc);
-		return -EBUSY;
-	}
-
-	GMN_DBG("%s: reset_done_ack rc %d", __func__, rc);
-	spin_lock_irqsave(&reset_lock, flags);
-	reset_done_ack = 0;
-	spin_unlock_irqrestore(&reset_lock, flags);
-
-	if (op_mode == MSM_GEMINI_MODE_REALTIME_ENCODE) {
-		/* Nothing needed for fe buffer cfg, config we only */
-		msm_gemini_hw_we_buffer_cfg(1);
-	} else {
-		/* Nothing needed for fe buffer cfg, config we only */
-		msm_gemini_hw_we_buffer_cfg(0);
-	}
-
-	/* @todo wait for reset done irq */
-
-	return 0;
-}
-
-void msm_gemini_core_release(int release_buf)
-{
-	int i = 0;
-	for (i = 0; i < 2; i++) {
-		if (we_pingpong_buf.buf_status[i] && release_buf)
-			msm_gemini_platform_p2v(we_pingpong_buf.buf[i].file,
-					&we_pingpong_buf.buf[i].handle);
-		we_pingpong_buf.buf_status[i] = 0;
-	}
-}
-
-void msm_gemini_core_init(void)
-{
-	init_waitqueue_head(&reset_wait);
-	spin_lock_init(&reset_lock);
-}
-
-int msm_gemini_core_fe_start(void)
-{
-	msm_gemini_hw_fe_start();
-	return 0;
-}
-
-/* fetch engine */
-int msm_gemini_core_fe_buf_update(struct msm_gemini_core_buf *buf)
-{
-	GMN_DBG("%s:%d] 0x%08x %d 0x%08x %d\n", __func__, __LINE__,
-		(int) buf->y_buffer_addr, buf->y_len,
-		(int) buf->cbcr_buffer_addr, buf->cbcr_len);
-	return msm_gemini_hw_pingpong_update(&fe_pingpong_buf, buf);
-}
-
-void *msm_gemini_core_fe_pingpong_irq(int gemini_irq_status, void *context)
-{
-	return msm_gemini_hw_pingpong_irq(&fe_pingpong_buf);
-}
-
-/* write engine */
-int msm_gemini_core_we_buf_update(struct msm_gemini_core_buf *buf)
-{
-	int rc;
-	GMN_DBG("%s:%d] 0x%08x 0x%08x %d\n", __func__, __LINE__,
-		(int) buf->y_buffer_addr, (int) buf->cbcr_buffer_addr,
-		buf->y_len);
-	we_pingpong_buf.buf_status[we_pingpong_index] = 0;
-	we_pingpong_index = (we_pingpong_index + 1)%2;
-	rc = msm_gemini_hw_pingpong_update(&we_pingpong_buf, buf);
-	return 0;
-}
-
-int msm_gemini_core_we_buf_reset(struct msm_gemini_hw_buf *buf)
-{
-	int i = 0;
-	for (i = 0; i < 2; i++) {
-		if (we_pingpong_buf.buf[i].y_buffer_addr
-					== buf->y_buffer_addr)
-			we_pingpong_buf.buf_status[i] = 0;
-	}
-	return 0;
-}
-
-void *msm_gemini_core_we_pingpong_irq(int gemini_irq_status, void *context)
-{
-	GMN_DBG("%s:%d]\n", __func__, __LINE__);
-
-	return msm_gemini_hw_pingpong_irq(&we_pingpong_buf);
-}
-
-void *msm_gemini_core_framedone_irq(int gemini_irq_status, void *context)
-{
-	struct msm_gemini_hw_buf *buf_p;
-
-	GMN_DBG("%s:%d]\n", __func__, __LINE__);
-
-	buf_p = msm_gemini_hw_pingpong_active_buffer(&we_pingpong_buf);
-	if (buf_p) {
-		buf_p->framedone_len = msm_gemini_hw_encode_output_size();
-		GMN_DBG("%s:%d] framedone_len %d\n", __func__, __LINE__,
-			buf_p->framedone_len);
-	}
-
-	return buf_p;
-}
-
-void *msm_gemini_core_reset_ack_irq(int gemini_irq_status, void *context)
-{
-	/* @todo return the status back to msm_gemini_core_reset */
-	GMN_DBG("%s:%d]\n", __func__, __LINE__);
-	return NULL;
-}
-
-void *msm_gemini_core_err_irq(int gemini_irq_status, void *context)
-{
-	GMN_PR_ERR("%s:%d]\n", __func__, gemini_irq_status);
-	return NULL;
-}
-
-static int (*msm_gemini_irq_handler) (int, void *, void *);
-
-irqreturn_t msm_gemini_core_irq(int irq_num, void *context)
-{
-	void *data = NULL;
-	unsigned long flags;
-	int gemini_irq_status;
-
-	GMN_DBG("%s:%d] irq_num = %d\n", __func__, __LINE__, irq_num);
-
-	spin_lock_irqsave(&reset_lock, flags);
-	reset_done_ack = 1;
-	spin_unlock_irqrestore(&reset_lock, flags);
-	gemini_irq_status = msm_gemini_hw_irq_get_status();
-
-	GMN_DBG("%s:%d] gemini_irq_status = %0x\n", __func__, __LINE__,
-		gemini_irq_status);
-
-	/*For reset and framedone IRQs, clear all bits*/
-	if (gemini_irq_status & 0x400) {
-		wake_up(&reset_wait);
-		msm_gemini_hw_irq_clear(HWIO_JPEG_IRQ_CLEAR_RMSK,
-			JPEG_IRQ_CLEAR_ALL);
-	} else if (gemini_irq_status & 0x1) {
-		msm_gemini_hw_irq_clear(HWIO_JPEG_IRQ_CLEAR_RMSK,
-			JPEG_IRQ_CLEAR_ALL);
-	} else {
-		msm_gemini_hw_irq_clear(HWIO_JPEG_IRQ_CLEAR_RMSK,
-			gemini_irq_status);
-	}
-
-	if (msm_gemini_hw_irq_is_frame_done(gemini_irq_status)) {
-		data = msm_gemini_core_framedone_irq(gemini_irq_status,
-			context);
-		if (msm_gemini_irq_handler)
-			msm_gemini_irq_handler(
-				MSM_GEMINI_HW_MASK_COMP_FRAMEDONE,
-				context, data);
-	}
-
-	if (msm_gemini_hw_irq_is_fe_pingpong(gemini_irq_status)) {
-		data = msm_gemini_core_fe_pingpong_irq(gemini_irq_status,
-			context);
-		if (msm_gemini_irq_handler)
-			msm_gemini_irq_handler(MSM_GEMINI_HW_MASK_COMP_FE,
-				context, data);
-	}
-
-	if (msm_gemini_hw_irq_is_we_pingpong(gemini_irq_status) &&
-	    !msm_gemini_hw_irq_is_frame_done(gemini_irq_status)) {
-		data = msm_gemini_core_we_pingpong_irq(gemini_irq_status,
-			context);
-		if (msm_gemini_irq_handler)
-			msm_gemini_irq_handler(MSM_GEMINI_HW_MASK_COMP_WE,
-				context, data);
-	}
-
-	if (msm_gemini_hw_irq_is_reset_ack(gemini_irq_status)) {
-		data = msm_gemini_core_reset_ack_irq(gemini_irq_status,
-			context);
-		if (msm_gemini_irq_handler)
-			msm_gemini_irq_handler(
-				MSM_GEMINI_HW_MASK_COMP_RESET_ACK,
-				context, data);
-	}
-
-	/* Unexpected/unintended HW interrupt */
-	if (msm_gemini_hw_irq_is_err(gemini_irq_status)) {
-		data = msm_gemini_core_err_irq(gemini_irq_status, context);
-		if (msm_gemini_irq_handler)
-			msm_gemini_irq_handler(MSM_GEMINI_HW_MASK_COMP_ERR,
-				context, data);
-	}
-
-	return IRQ_HANDLED;
-}
-
-void msm_gemini_core_irq_install(int (*irq_handler) (int, void *, void *))
-{
-	msm_gemini_irq_handler = irq_handler;
-}
-
-void msm_gemini_core_irq_remove(void)
-{
-	msm_gemini_irq_handler = NULL;
-}
diff --git a/drivers/media/video/msm/gemini/msm_gemini_core.h b/drivers/media/video/msm/gemini/msm_gemini_core.h
deleted file mode 100644
index f240505..0000000
--- a/drivers/media/video/msm/gemini/msm_gemini_core.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. 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 MSM_GEMINI_CORE_H
-#define MSM_GEMINI_CORE_H
-
-#include <linux/interrupt.h>
-#include "msm_gemini_hw.h"
-
-#define msm_gemini_core_buf msm_gemini_hw_buf
-
-irqreturn_t msm_gemini_core_irq(int irq_num, void *context);
-
-void msm_gemini_core_irq_install(int (*irq_handler) (int, void *, void *));
-void msm_gemini_core_irq_remove(void);
-
-int msm_gemini_core_fe_buf_update(struct msm_gemini_core_buf *buf);
-int msm_gemini_core_we_buf_update(struct msm_gemini_core_buf *buf);
-int msm_gemini_core_we_buf_reset(struct msm_gemini_hw_buf *buf);
-
-int msm_gemini_core_reset(uint8_t op_mode, void *base, int size);
-int msm_gemini_core_fe_start(void);
-
-void msm_gemini_core_release(int);
-void msm_gemini_core_init(void);
-#endif /* MSM_GEMINI_CORE_H */
diff --git a/drivers/media/video/msm/gemini/msm_gemini_dev.c b/drivers/media/video/msm/gemini/msm_gemini_dev.c
deleted file mode 100644
index 01d45ed..0000000
--- a/drivers/media/video/msm/gemini/msm_gemini_dev.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. 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/module.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <mach/board.h>
-
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/device.h>
-#include <linux/uaccess.h>
-#include <media/msm_gemini.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-
-#include "msm.h"
-#include "msm_gemini_sync.h"
-#include "msm_gemini_common.h"
-
-#define MSM_GEMINI_NAME "gemini"
-
-static int msm_gemini_open(struct inode *inode, struct file *filp)
-{
-	int rc;
-
-	struct msm_gemini_device *pgmn_dev = container_of(inode->i_cdev,
-		struct msm_gemini_device, cdev);
-	filp->private_data = pgmn_dev;
-
-	GMN_DBG("%s:%d]\n", __func__, __LINE__);
-
-	rc = __msm_gemini_open(pgmn_dev);
-
-	GMN_DBG(KERN_INFO "%s:%d] %s open_count = %d\n", __func__, __LINE__,
-		filp->f_path.dentry->d_name.name, pgmn_dev->open_count);
-
-	return rc;
-}
-
-static int msm_gemini_release(struct inode *inode, struct file *filp)
-{
-	int rc;
-
-	struct msm_gemini_device *pgmn_dev = filp->private_data;
-
-	GMN_DBG(KERN_INFO "%s:%d]\n", __func__, __LINE__);
-
-	rc = __msm_gemini_release(pgmn_dev);
-
-	GMN_DBG(KERN_INFO "%s:%d] %s open_count = %d\n", __func__, __LINE__,
-		filp->f_path.dentry->d_name.name, pgmn_dev->open_count);
-	return rc;
-}
-
-static long msm_gemini_ioctl(struct file *filp, unsigned int cmd,
-	unsigned long arg)
-{
-	int rc;
-	struct msm_gemini_device *pgmn_dev = filp->private_data;
-
-	GMN_DBG("%s:%d] cmd=%d pgmn_dev=0x%x arg=0x%x\n", __func__,
-		__LINE__, _IOC_NR(cmd), (uint32_t)pgmn_dev, (uint32_t)arg);
-
-	rc = __msm_gemini_ioctl(pgmn_dev, cmd, arg);
-
-	GMN_DBG("%s:%d]\n", __func__, __LINE__);
-	return rc;
-}
-
-static const struct file_operations msm_gemini_fops = {
-	.owner	  = THIS_MODULE,
-	.open	   = msm_gemini_open,
-	.release	= msm_gemini_release,
-	.unlocked_ioctl = msm_gemini_ioctl,
-};
-
-static struct class *msm_gemini_class;
-static dev_t msm_gemini_devno;
-struct msm_gemini_device *msm_gemini_device_p;
-
-int msm_gemini_subdev_init(struct v4l2_subdev *gemini_sd)
-{
-	int rc;
-	struct msm_gemini_device *pgmn_dev =
-		(struct msm_gemini_device *)gemini_sd->host_priv;
-
-	GMN_DBG("%s:%d: gemini_sd=0x%x pgmn_dev=0x%x\n",
-		__func__, __LINE__, (uint32_t)gemini_sd, (uint32_t)pgmn_dev);
-	rc = __msm_gemini_open(pgmn_dev);
-	GMN_DBG("%s:%d: rc=%d\n",
-		__func__, __LINE__, rc);
-	return rc;
-}
-
-static long msm_gemini_subdev_ioctl(struct v4l2_subdev *sd,
-	unsigned int cmd, void *arg)
-{
-	long rc;
-	struct msm_gemini_device *pgmn_dev =
-		(struct msm_gemini_device *)sd->host_priv;
-
-	GMN_DBG("%s: cmd=%d\n", __func__, cmd);
-
-	GMN_DBG("%s: pgmn_dev 0x%x", __func__, (uint32_t)pgmn_dev);
-
-	GMN_DBG("%s: Calling __msm_gemini_ioctl\n", __func__);
-
-	rc = __msm_gemini_ioctl(pgmn_dev, cmd, (unsigned long)arg);
-	pr_debug("%s: X\n", __func__);
-	return rc;
-}
-
-void msm_gemini_subdev_release(struct v4l2_subdev *gemini_sd)
-{
-	int rc;
-	struct msm_gemini_device *pgmn_dev =
-		(struct msm_gemini_device *)gemini_sd->host_priv;
-	GMN_DBG("%s:pgmn_dev=0x%x", __func__, (uint32_t)pgmn_dev);
-	rc = __msm_gemini_release(pgmn_dev);
-	GMN_DBG("%s:rc=%d", __func__, rc);
-}
-
-static const struct v4l2_subdev_core_ops msm_gemini_subdev_core_ops = {
-	.ioctl = msm_gemini_subdev_ioctl,
-};
-
-static const struct v4l2_subdev_ops msm_gemini_subdev_ops = {
-	.core = &msm_gemini_subdev_core_ops,
-};
-
-static int msm_gemini_init(struct platform_device *pdev)
-{
-	int rc = -1;
-	struct device *dev;
-
-	GMN_DBG("%s:\n", __func__);
-	msm_gemini_device_p = __msm_gemini_init(pdev);
-	if (msm_gemini_device_p == NULL) {
-		GMN_PR_ERR("%s: initialization failed\n", __func__);
-		goto fail;
-	}
-
-	v4l2_subdev_init(&msm_gemini_device_p->subdev, &msm_gemini_subdev_ops);
-	v4l2_set_subdev_hostdata(&msm_gemini_device_p->subdev,
-		msm_gemini_device_p);
-	pr_debug("%s: msm_gemini_device_p 0x%x", __func__,
-			(uint32_t)msm_gemini_device_p);
-	GMN_DBG("%s:gemini: platform_set_drvdata\n", __func__);
-	platform_set_drvdata(pdev, &msm_gemini_device_p->subdev);
-
-	rc = alloc_chrdev_region(&msm_gemini_devno, 0, 1, MSM_GEMINI_NAME);
-	if (rc < 0) {
-		GMN_PR_ERR("%s: failed to allocate chrdev\n", __func__);
-		goto fail_1;
-	}
-
-	if (!msm_gemini_class) {
-		msm_gemini_class = class_create(THIS_MODULE, MSM_GEMINI_NAME);
-		if (IS_ERR(msm_gemini_class)) {
-			rc = PTR_ERR(msm_gemini_class);
-			GMN_PR_ERR("%s: create device class failed\n",
-				__func__);
-			goto fail_2;
-		}
-	}
-
-	dev = device_create(msm_gemini_class, NULL,
-		MKDEV(MAJOR(msm_gemini_devno), MINOR(msm_gemini_devno)), NULL,
-		"%s%d", MSM_GEMINI_NAME, 0);
-
-	if (IS_ERR(dev)) {
-		GMN_PR_ERR("%s: error creating device\n", __func__);
-		rc = -ENODEV;
-		goto fail_3;
-	}
-
-	cdev_init(&msm_gemini_device_p->cdev, &msm_gemini_fops);
-	msm_gemini_device_p->cdev.owner = THIS_MODULE;
-	msm_gemini_device_p->cdev.ops   =
-		(const struct file_operations *) &msm_gemini_fops;
-	rc = cdev_add(&msm_gemini_device_p->cdev, msm_gemini_devno, 1);
-	if (rc < 0) {
-		GMN_PR_ERR("%s: error adding cdev\n", __func__);
-		rc = -ENODEV;
-		goto fail_4;
-	}
-
-	GMN_DBG("%s %s: success\n", __func__, MSM_GEMINI_NAME);
-
-	return rc;
-
-fail_4:
-	device_destroy(msm_gemini_class, msm_gemini_devno);
-
-fail_3:
-	class_destroy(msm_gemini_class);
-
-fail_2:
-	unregister_chrdev_region(msm_gemini_devno, 1);
-
-fail_1:
-	__msm_gemini_exit(msm_gemini_device_p);
-
-fail:
-	return rc;
-}
-
-static void msm_gemini_exit(void)
-{
-	cdev_del(&msm_gemini_device_p->cdev);
-	device_destroy(msm_gemini_class, msm_gemini_devno);
-	class_destroy(msm_gemini_class);
-	unregister_chrdev_region(msm_gemini_devno, 1);
-
-	__msm_gemini_exit(msm_gemini_device_p);
-}
-
-static int __msm_gemini_probe(struct platform_device *pdev)
-{
-	return msm_gemini_init(pdev);
-}
-
-static int __msm_gemini_remove(struct platform_device *pdev)
-{
-	msm_gemini_exit();
-	return 0;
-}
-
-static struct platform_driver msm_gemini_driver = {
-	.probe  = __msm_gemini_probe,
-	.remove = __msm_gemini_remove,
-	.driver = {
-		.name = MSM_GEMINI_DRV_NAME,
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init msm_gemini_driver_init(void)
-{
-	int rc;
-	rc = platform_driver_register(&msm_gemini_driver);
-	return rc;
-}
-
-static void __exit msm_gemini_driver_exit(void)
-{
-	platform_driver_unregister(&msm_gemini_driver);
-}
-
-MODULE_DESCRIPTION("msm gemini jpeg driver");
-MODULE_VERSION("msm gemini 0.1");
-
-module_init(msm_gemini_driver_init);
-module_exit(msm_gemini_driver_exit);
-
diff --git a/drivers/media/video/msm/gemini/msm_gemini_hw.c b/drivers/media/video/msm/gemini/msm_gemini_hw.c
deleted file mode 100644
index ba8f353..0000000
--- a/drivers/media/video/msm/gemini/msm_gemini_hw.c
+++ /dev/null
@@ -1,525 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. 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/delay.h>
-#include "msm_gemini_hw.h"
-#include "msm_gemini_common.h"
-
-#include <linux/io.h>
-
-static void *gemini_region_base;
-static uint32_t gemini_region_size;
-
-int msm_gemini_hw_pingpong_update(struct msm_gemini_hw_pingpong *pingpong_hw,
-	struct msm_gemini_hw_buf *buf)
-{
-	int buf_free_index = -1;
-
-	if (!pingpong_hw->buf_status[0]) {
-		buf_free_index = 0;
-	} else if (!pingpong_hw->buf_status[1]) {
-		buf_free_index = 1;
-	} else {
-		GMN_PR_ERR("%s:%d: pingpong buffer busy\n", __func__, __LINE__);
-		return -1;
-	}
-
-	pingpong_hw->buf[buf_free_index] = *buf;
-	pingpong_hw->buf_status[buf_free_index] = 1;
-
-	if (pingpong_hw->is_fe) {
-		/* it is fe */
-		msm_gemini_hw_fe_buffer_update(
-			&pingpong_hw->buf[buf_free_index], buf_free_index);
-	} else {
-		/* it is we */
-		msm_gemini_hw_we_buffer_update(
-			&pingpong_hw->buf[buf_free_index], buf_free_index);
-	}
-	return 0;
-}
-
-void *msm_gemini_hw_pingpong_irq(struct msm_gemini_hw_pingpong *pingpong_hw)
-{
-	struct msm_gemini_hw_buf *buf_p = NULL;
-
-	if (pingpong_hw->buf_status[pingpong_hw->buf_active_index]) {
-		buf_p = &pingpong_hw->buf[pingpong_hw->buf_active_index];
-		pingpong_hw->buf_status[pingpong_hw->buf_active_index] = 0;
-	}
-
-	pingpong_hw->buf_active_index = !pingpong_hw->buf_active_index;
-
-	return (void *) buf_p;
-}
-
-void *msm_gemini_hw_pingpong_active_buffer(
-	struct msm_gemini_hw_pingpong *pingpong_hw)
-{
-	struct msm_gemini_hw_buf *buf_p = NULL;
-
-	if (pingpong_hw->buf_status[pingpong_hw->buf_active_index])
-		buf_p = &pingpong_hw->buf[pingpong_hw->buf_active_index];
-
-	return (void *) buf_p;
-}
-
-struct msm_gemini_hw_cmd hw_cmd_irq_get_status[] = {
-	/* type, repeat n times, offset, mask, data or pdata */
-	{MSM_GEMINI_HW_CMD_TYPE_READ, 1, HWIO_JPEG_IRQ_STATUS_ADDR,
-		HWIO_JPEG_IRQ_STATUS_RMSK, {0} },
-};
-
-int msm_gemini_hw_irq_get_status(void)
-{
-	uint32_t n_irq_status = 0;
-	rmb();
-	n_irq_status = msm_gemini_hw_read(&hw_cmd_irq_get_status[0]);
-	rmb();
-	return n_irq_status;
-}
-
-struct msm_gemini_hw_cmd hw_cmd_encode_output_size[] = {
-	/* type, repeat n times, offset, mask, data or pdata */
-	{MSM_GEMINI_HW_CMD_TYPE_READ, 1,
-		HWIO_JPEG_STATUS_ENCODE_OUTPUT_SIZE_ADDR,
-		HWIO_JPEG_STATUS_ENCODE_OUTPUT_SIZE_RMSK, {0} },
-};
-
-long msm_gemini_hw_encode_output_size(void)
-{
-	uint32_t encode_output_size = 0;
-
-	encode_output_size = msm_gemini_hw_read(&hw_cmd_encode_output_size[0]);
-
-	return encode_output_size;
-}
-
-struct msm_gemini_hw_cmd hw_cmd_irq_clear[] = {
-	/* type, repeat n times, offset, mask, data or pdata */
-	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_IRQ_CLEAR_ADDR,
-		HWIO_JPEG_IRQ_CLEAR_RMSK, {JPEG_IRQ_CLEAR_ALL} },
-};
-
-void msm_gemini_hw_irq_clear(uint32_t mask, uint32_t data)
-{
-	GMN_DBG("%s:%d] mask %0x data %0x", __func__, __LINE__, mask, data);
-	hw_cmd_irq_clear[0].mask = mask;
-	hw_cmd_irq_clear[0].data = data;
-	msm_gemini_hw_write(&hw_cmd_irq_clear[0]);
-}
-
-struct msm_gemini_hw_cmd hw_cmd_fe_ping_update[] = {
-	/* type, repeat n times, offset, mask, data or pdata */
-	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_FE_BUFFER_CFG_ADDR,
-		HWIO_JPEG_FE_BUFFER_CFG_RMSK, {0} },
-	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_FE_Y_PING_ADDR_ADDR,
-		HWIO_JPEG_FE_Y_PING_ADDR_RMSK, {0} },
-	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_FE_CBCR_PING_ADDR_ADDR,
-		HWIO_JPEG_FE_CBCR_PING_ADDR_RMSK, {0} },
-	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_FE_CMD_ADDR,
-		HWIO_JPEG_FE_CMD_RMSK, {JPEG_FE_CMD_BUFFERRELOAD} },
-};
-
-struct msm_gemini_hw_cmd hw_cmd_fe_pong_update[] = {
-	/* type, repeat n times, offset, mask, data or pdata */
-	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_FE_BUFFER_CFG_ADDR,
-		HWIO_JPEG_FE_BUFFER_CFG_RMSK, {0} },
-	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_FE_Y_PONG_ADDR_ADDR,
-		HWIO_JPEG_FE_Y_PONG_ADDR_RMSK, {0} },
-	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_FE_CBCR_PONG_ADDR_ADDR,
-		HWIO_JPEG_FE_CBCR_PONG_ADDR_RMSK, {0} },
-	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_FE_CMD_ADDR,
-		HWIO_JPEG_FE_CMD_RMSK, {JPEG_FE_CMD_BUFFERRELOAD} },
-};
-
-void msm_gemini_hw_fe_buffer_update(struct msm_gemini_hw_buf *p_input,
-	uint8_t pingpong_index)
-{
-	uint32_t n_reg_val = 0;
-
-	struct msm_gemini_hw_cmd *hw_cmd_p;
-
-	if (pingpong_index == 0) {
-		hw_cmd_p = &hw_cmd_fe_ping_update[0];
-		n_reg_val = ((((p_input->num_of_mcu_rows - 1) <<
-			HWIO_JPEG_FE_BUFFER_CFG_CBCR_MCU_ROWS_SHFT) &
-			HWIO_JPEG_FE_BUFFER_CFG_CBCR_MCU_ROWS_BMSK) |
-			(((p_input->num_of_mcu_rows - 1) <<
-			HWIO_JPEG_FE_BUFFER_CFG_Y_MCU_ROWS_SHFT) &
-			HWIO_JPEG_FE_BUFFER_CFG_Y_MCU_ROWS_BMSK));
-		hw_cmd_p->data = n_reg_val;
-		msm_gemini_hw_write(hw_cmd_p++);
-
-		n_reg_val = ((p_input->y_buffer_addr <<
-			HWIO_JPEG_FE_Y_PING_ADDR_FE_Y_PING_START_ADDR_SHFT) &
-			HWIO_JPEG_FE_Y_PING_ADDR_FE_Y_PING_START_ADDR_BMSK);
-		hw_cmd_p->data = n_reg_val;
-		msm_gemini_hw_write(hw_cmd_p++);
-
-		n_reg_val = ((p_input->cbcr_buffer_addr<<
-		HWIO_JPEG_FE_CBCR_PING_ADDR_FE_CBCR_PING_START_ADDR_SHFT) &
-		HWIO_JPEG_FE_CBCR_PING_ADDR_FE_CBCR_PING_START_ADDR_BMSK);
-		hw_cmd_p->data = n_reg_val;
-		msm_gemini_hw_write(hw_cmd_p++);
-
-		msm_gemini_hw_write(hw_cmd_p);
-	} else if (pingpong_index == 1) {
-		hw_cmd_p = &hw_cmd_fe_pong_update[0];
-		n_reg_val = ((((p_input->num_of_mcu_rows - 1) <<
-			HWIO_JPEG_FE_BUFFER_CFG_CBCR_MCU_ROWS_SHFT) &
-			HWIO_JPEG_FE_BUFFER_CFG_CBCR_MCU_ROWS_BMSK) |
-			(((p_input->num_of_mcu_rows - 1) <<
-			HWIO_JPEG_FE_BUFFER_CFG_Y_MCU_ROWS_SHFT) &
-			HWIO_JPEG_FE_BUFFER_CFG_Y_MCU_ROWS_BMSK));
-		hw_cmd_p->data = n_reg_val;
-		msm_gemini_hw_write(hw_cmd_p++);
-
-		n_reg_val = ((p_input->y_buffer_addr <<
-			HWIO_JPEG_FE_Y_PONG_ADDR_FE_Y_PONG_START_ADDR_SHFT) &
-			HWIO_JPEG_FE_Y_PONG_ADDR_FE_Y_PONG_START_ADDR_BMSK);
-		hw_cmd_p->data = n_reg_val;
-		msm_gemini_hw_write(hw_cmd_p++);
-
-		n_reg_val = ((p_input->cbcr_buffer_addr<<
-		HWIO_JPEG_FE_CBCR_PONG_ADDR_FE_CBCR_PONG_START_ADDR_SHFT) &
-		HWIO_JPEG_FE_CBCR_PONG_ADDR_FE_CBCR_PONG_START_ADDR_BMSK);
-		hw_cmd_p->data = n_reg_val;
-		msm_gemini_hw_write(hw_cmd_p++);
-
-		msm_gemini_hw_write(hw_cmd_p);
-	} else {
-		/* shall not get to here */
-	}
-
-	return;
-}
-
-struct msm_gemini_hw_cmd hw_cmd_fe_start[] = {
-	/* type, repeat n times, offset, mask, data or pdata */
-	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_FE_CMD_ADDR,
-		HWIO_JPEG_FE_CMD_RMSK, {JPEG_OFFLINE_CMD_START} },
-};
-
-void msm_gemini_hw_fe_start(void)
-{
-	msm_gemini_hw_write(&hw_cmd_fe_start[0]);
-
-	return;
-}
-
-struct msm_gemini_hw_cmd hw_cmd_we_buffer_cfg[] = {
-	/* type, repeat n times, offset, mask, data or pdata */
-	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_WE_Y_THRESHOLD_ADDR,
-		HWIO_JPEG_WE_Y_THRESHOLD_RMSK, {0} },
-	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_WE_Y_UB_CFG_ADDR,
-		HWIO_JPEG_WE_Y_UB_CFG_RMSK, {JPEG_WE_YUB_ENCODE} },
-	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_WE_CBCR_THRESHOLD_ADDR,
-		HWIO_JPEG_WE_CBCR_THRESHOLD_RMSK, {0} },
-};
-
-/* first dimension is WE_ASSERT_STALL_TH and WE_DEASSERT_STALL_TH
-   second dimension is for offline and real-time settings
- */
-static const uint32_t GEMINI_WE_Y_THRESHOLD[2][2] = {
-	{ 0x00000190, 0x000001ff },
-	{ 0x0000016a, 0x000001ff }
-};
-
-/* first dimension is WE_ASSERT_STALL_TH and WE_DEASSERT_STALL_TH
-   second dimension is for offline and real-time settings
- */
-static const uint32_t GEMINI_WE_CBCR_THRESHOLD[2][2] = {
-	{ 0x00000190, 0x000001ff },
-	{ 0x0000016a, 0x000001ff }
-};
-
-void msm_gemini_hw_we_buffer_cfg(uint8_t is_realtime)
-{
-	uint32_t              n_reg_val = 0;
-
-	struct msm_gemini_hw_cmd *hw_cmd_p = &hw_cmd_we_buffer_cfg[0];
-
-	n_reg_val = (((GEMINI_WE_Y_THRESHOLD[1][is_realtime] <<
-		HWIO_JPEG_WE_Y_THRESHOLD_WE_DEASSERT_STALL_TH_SHFT) &
-		HWIO_JPEG_WE_Y_THRESHOLD_WE_DEASSERT_STALL_TH_BMSK) |
-		((GEMINI_WE_Y_THRESHOLD[0][is_realtime] <<
-		HWIO_JPEG_WE_Y_THRESHOLD_WE_ASSERT_STALL_TH_SHFT) &
-		HWIO_JPEG_WE_Y_THRESHOLD_WE_ASSERT_STALL_TH_BMSK));
-	hw_cmd_p->data = n_reg_val;
-	msm_gemini_hw_write(hw_cmd_p++);
-
-	msm_gemini_hw_write(hw_cmd_p++);
-
-	/* @todo maybe not for realtime? */
-	n_reg_val = (((GEMINI_WE_CBCR_THRESHOLD[1][is_realtime] <<
-		HWIO_JPEG_WE_CBCR_THRESHOLD_WE_DEASSERT_STALL_TH_SHFT) &
-		HWIO_JPEG_WE_CBCR_THRESHOLD_WE_DEASSERT_STALL_TH_BMSK) |
-		((GEMINI_WE_CBCR_THRESHOLD[0][is_realtime] <<
-		HWIO_JPEG_WE_CBCR_THRESHOLD_WE_ASSERT_STALL_TH_SHFT) &
-		HWIO_JPEG_WE_CBCR_THRESHOLD_WE_ASSERT_STALL_TH_BMSK));
-	hw_cmd_p->data = n_reg_val;
-	msm_gemini_hw_write(hw_cmd_p);
-
-	return;
-}
-
-struct msm_gemini_hw_cmd hw_cmd_we_ping_update[] = {
-	/* type, repeat n times, offset, mask, data or pdata */
-	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_WE_Y_PING_BUFFER_CFG_ADDR,
-		HWIO_JPEG_WE_Y_PING_BUFFER_CFG_RMSK, {0} },
-	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_WE_Y_PING_ADDR_ADDR,
-		HWIO_JPEG_WE_Y_PING_ADDR_RMSK, {0} },
-};
-
-struct msm_gemini_hw_cmd hw_cmd_we_pong_update[] = {
-	/* type, repeat n times, offset, mask, data or pdata */
-	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_WE_Y_PONG_BUFFER_CFG_ADDR,
-		HWIO_JPEG_WE_Y_PONG_BUFFER_CFG_RMSK, {0} },
-	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_WE_Y_PONG_ADDR_ADDR,
-		HWIO_JPEG_WE_Y_PONG_ADDR_RMSK, {0} },
-};
-
-void msm_gemini_hw_we_buffer_update(struct msm_gemini_hw_buf *p_input,
-	uint8_t pingpong_index)
-{
-	uint32_t n_reg_val = 0;
-
-	struct msm_gemini_hw_cmd *hw_cmd_p;
-
-	if (pingpong_index == 0) {
-		hw_cmd_p = &hw_cmd_we_ping_update[0];
-
-		n_reg_val = ((p_input->y_len <<
-			HWIO_JPEG_WE_Y_PING_BUFFER_CFG_WE_BUFFER_LENGTH_SHFT) &
-			HWIO_JPEG_WE_Y_PING_BUFFER_CFG_WE_BUFFER_LENGTH_BMSK);
-		hw_cmd_p->data = n_reg_val;
-		msm_gemini_hw_write(hw_cmd_p++);
-
-		n_reg_val = p_input->y_buffer_addr;
-		hw_cmd_p->data = n_reg_val;
-		msm_gemini_hw_write(hw_cmd_p++);
-	} else if (pingpong_index == 1) {
-		hw_cmd_p = &hw_cmd_we_pong_update[0];
-
-		n_reg_val = ((p_input->y_len <<
-			HWIO_JPEG_WE_Y_PONG_BUFFER_CFG_WE_BUFFER_LENGTH_SHFT) &
-			HWIO_JPEG_WE_Y_PONG_BUFFER_CFG_WE_BUFFER_LENGTH_BMSK);
-		hw_cmd_p->data = n_reg_val;
-		msm_gemini_hw_write(hw_cmd_p++);
-
-		n_reg_val = p_input->y_buffer_addr;
-		hw_cmd_p->data = n_reg_val;
-		msm_gemini_hw_write(hw_cmd_p++);
-	} else {
-		/* shall not get to here */
-	}
-
-	return;
-}
-
-struct msm_gemini_hw_cmd hw_cmd_reset[] = {
-	/* type, repeat n times, offset, mask, data or pdata */
-	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_IRQ_MASK_ADDR,
-		HWIO_JPEG_IRQ_MASK_RMSK, {JPEG_IRQ_DISABLE_ALL} },
-	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_IRQ_CLEAR_ADDR,
-		HWIO_JPEG_IRQ_MASK_RMSK, {JPEG_IRQ_CLEAR_ALL} },
-	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_IRQ_MASK_ADDR,
-		HWIO_JPEG_IRQ_MASK_RMSK, {JPEG_IRQ_ALLSOURCES_ENABLE} },
-	{MSM_GEMINI_HW_CMD_TYPE_WRITE, 1, HWIO_JPEG_RESET_CMD_ADDR,
-		HWIO_JPEG_RESET_CMD_RMSK, {JPEG_RESET_DEFAULT} },
-};
-
-void msm_gemini_hw_init(void *base, int size)
-{
-	gemini_region_base = base;
-	gemini_region_size = size;
-}
-
-void msm_gemini_hw_reset(void *base, int size)
-{
-	struct msm_gemini_hw_cmd *hw_cmd_p;
-
-	hw_cmd_p = &hw_cmd_reset[0];
-
-	wmb();
-	msm_gemini_hw_write(hw_cmd_p++);
-	msm_gemini_hw_write(hw_cmd_p++);
-	msm_gemini_hw_write(hw_cmd_p++);
-	msm_gemini_hw_write(hw_cmd_p);
-	wmb();
-
-	return;
-}
-
-uint32_t msm_gemini_hw_read(struct msm_gemini_hw_cmd *hw_cmd_p)
-{
-	uint32_t *paddr;
-	uint32_t data;
-
-	paddr = gemini_region_base + hw_cmd_p->offset;
-
-	data = readl(paddr);
-	data &= hw_cmd_p->mask;
-
-	GMN_DBG("%s:%d] type-%d n-%d offset-0x%4x mask-0x%8x data-0x%8x\n",
-		__func__, __LINE__, hw_cmd_p->type, hw_cmd_p->n,
-		hw_cmd_p->offset, hw_cmd_p->mask, data);
-	return data;
-}
-
-void msm_gemini_hw_write(struct msm_gemini_hw_cmd *hw_cmd_p)
-{
-	uint32_t *paddr;
-	uint32_t old_data, new_data;
-
-	/* type, repeat n times, offset, mask, data or pdata */
-	GMN_DBG("%s:%d] type-%d n-%d offset-0x%4x mask-0x%8x data-0x%8x\n",
-		__func__, __LINE__, hw_cmd_p->type, hw_cmd_p->n,
-		hw_cmd_p->offset, hw_cmd_p->mask, hw_cmd_p->data);
-
-	paddr = gemini_region_base + hw_cmd_p->offset;
-
-	if (hw_cmd_p->mask == 0xffffffff) {
-		old_data = 0;
-	} else {
-		old_data = readl(paddr);
-		old_data &= ~hw_cmd_p->mask;
-	}
-
-	new_data = hw_cmd_p->data & hw_cmd_p->mask;
-	new_data |= old_data;
-	writel(new_data, paddr);
-}
-
-int msm_gemini_hw_wait(struct msm_gemini_hw_cmd *hw_cmd_p, int m_us)
-{
-	int tm = hw_cmd_p->n;
-	uint32_t data;
-	uint32_t wait_data = hw_cmd_p->data & hw_cmd_p->mask;
-
-	data = msm_gemini_hw_read(hw_cmd_p);
-	if (data != wait_data) {
-		while (tm) {
-			udelay(m_us);
-			data = msm_gemini_hw_read(hw_cmd_p);
-			if (data == wait_data)
-				break;
-			tm--;
-		}
-	}
-	hw_cmd_p->data = data;
-	return tm;
-}
-
-void msm_gemini_hw_delay(struct msm_gemini_hw_cmd *hw_cmd_p, int m_us)
-{
-	int tm = hw_cmd_p->n;
-	while (tm) {
-		udelay(m_us);
-		tm--;
-	}
-}
-
-int msm_gemini_hw_exec_cmds(struct msm_gemini_hw_cmd *hw_cmd_p, int m_cmds)
-{
-	int is_copy_to_user = -1;
-	uint32_t data;
-
-	while (m_cmds--) {
-		if (hw_cmd_p->offset > gemini_region_size) {
-			GMN_PR_ERR("%s:%d] %d exceed hw region %d\n", __func__,
-				__LINE__, hw_cmd_p->offset, gemini_region_size);
-			return -EFAULT;
-		}
-
-		switch (hw_cmd_p->type) {
-		case MSM_GEMINI_HW_CMD_TYPE_READ:
-			hw_cmd_p->data = msm_gemini_hw_read(hw_cmd_p);
-			is_copy_to_user = 1;
-			break;
-
-		case MSM_GEMINI_HW_CMD_TYPE_WRITE:
-			msm_gemini_hw_write(hw_cmd_p);
-			break;
-
-		case MSM_GEMINI_HW_CMD_TYPE_WRITE_OR:
-			data = msm_gemini_hw_read(hw_cmd_p);
-			hw_cmd_p->data = (hw_cmd_p->data & hw_cmd_p->mask) |
-				data;
-			msm_gemini_hw_write(hw_cmd_p);
-			break;
-
-		case MSM_GEMINI_HW_CMD_TYPE_UWAIT:
-			msm_gemini_hw_wait(hw_cmd_p, 1);
-			break;
-
-		case MSM_GEMINI_HW_CMD_TYPE_MWAIT:
-			msm_gemini_hw_wait(hw_cmd_p, 1000);
-			break;
-
-		case MSM_GEMINI_HW_CMD_TYPE_UDELAY:
-			msm_gemini_hw_delay(hw_cmd_p, 1);
-			break;
-
-		case MSM_GEMINI_HW_CMD_TYPE_MDELAY:
-			msm_gemini_hw_delay(hw_cmd_p, 1000);
-			break;
-
-		default:
-			GMN_PR_ERR("wrong hw command type\n");
-			break;
-		}
-
-		hw_cmd_p++;
-	}
-	return is_copy_to_user;
-}
-
-void msm_gemini_hw_region_dump(int size)
-{
-	uint32_t *p;
-	uint8_t *p8;
-
-	if (size > gemini_region_size)
-		GMN_PR_ERR("%s:%d] wrong region dump size\n",
-			__func__, __LINE__);
-
-	p = (uint32_t *) gemini_region_base;
-	while (size >= 16) {
-		GMN_DBG("0x%08X] %08X %08X %08X %08X\n",
-			gemini_region_size - size,
-			readl(p), readl(p+1), readl(p+2), readl(p+3));
-		p += 4;
-		size -= 16;
-	}
-
-	if (size > 0) {
-		uint32_t d;
-		GMN_DBG("0x%08X] ", gemini_region_size - size);
-		while (size >= 4) {
-			GMN_DBG("%08X ", readl(p++));
-			size -= 4;
-		}
-
-		d = readl(p);
-		p8 = (uint8_t *) &d;
-		while (size) {
-			GMN_DBG("%02X", *p8++);
-			size--;
-		}
-
-		GMN_DBG("\n");
-	}
-}
-
diff --git a/drivers/media/video/msm/gemini/msm_gemini_hw.h b/drivers/media/video/msm/gemini/msm_gemini_hw.h
deleted file mode 100644
index 248ba06..0000000
--- a/drivers/media/video/msm/gemini/msm_gemini_hw.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. 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 MSM_GEMINI_HW_H
-#define MSM_GEMINI_HW_H
-
-#include <media/msm_gemini.h>
-#include "msm_gemini_hw_reg.h"
-#include <linux/msm_ion.h>
-#include <mach/iommu_domains.h>
-
-struct msm_gemini_hw_buf {
-	struct msm_gemini_buf vbuf;
-	struct file  *file;
-	uint32_t framedone_len;
-	uint32_t y_buffer_addr;
-	uint32_t y_len;
-	uint32_t cbcr_buffer_addr;
-	uint32_t cbcr_len;
-	uint32_t num_of_mcu_rows;
-	struct ion_handle *handle;
-};
-
-struct msm_gemini_hw_pingpong {
-	uint8_t is_fe; /* 1: fe; 0: we */
-	struct  msm_gemini_hw_buf buf[2];
-	int     buf_status[2];
-	int     buf_active_index;
-};
-
-int msm_gemini_hw_pingpong_update(struct msm_gemini_hw_pingpong *pingpong_hw,
-	struct msm_gemini_hw_buf *buf);
-void *msm_gemini_hw_pingpong_irq(struct msm_gemini_hw_pingpong *pingpong_hw);
-void *msm_gemini_hw_pingpong_active_buffer(struct msm_gemini_hw_pingpong
-	*pingpong_hw);
-
-void msm_gemini_hw_irq_clear(uint32_t, uint32_t);
-int msm_gemini_hw_irq_get_status(void);
-long msm_gemini_hw_encode_output_size(void);
-#define MSM_GEMINI_HW_MASK_COMP_FRAMEDONE \
-		MSM_GEMINI_HW_IRQ_STATUS_FRAMEDONE_MASK
-#define MSM_GEMINI_HW_MASK_COMP_FE \
-		MSM_GEMINI_HW_IRQ_STATUS_FE_RD_DONE_MASK
-#define MSM_GEMINI_HW_MASK_COMP_WE \
-		(MSM_GEMINI_HW_IRQ_STATUS_WE_Y_PINGPONG_MASK | \
-		 MSM_GEMINI_HW_IRQ_STATUS_WE_CBCR_PINGPONG_MASK)
-#define MSM_GEMINI_HW_MASK_COMP_RESET_ACK \
-		MSM_GEMINI_HW_IRQ_STATUS_RESET_ACK_MASK
-#define MSM_GEMINI_HW_MASK_COMP_ERR \
-		(MSM_GEMINI_HW_IRQ_STATUS_FE_RTOVF_MASK | \
-		MSM_GEMINI_HW_IRQ_STATUS_FE_VFE_OVERFLOW_MASK | \
-		MSM_GEMINI_HW_IRQ_STATUS_WE_Y_BUFFER_OVERFLOW_MASK | \
-		MSM_GEMINI_HW_IRQ_STATUS_WE_CBCR_BUFFER_OVERFLOW_MASK | \
-		MSM_GEMINI_HW_IRQ_STATUS_WE_CH0_DATAFIFO_OVERFLOW_MASK | \
-		MSM_GEMINI_HW_IRQ_STATUS_WE_CH1_DATAFIFO_OVERFLOW_MASK | \
-		MSM_GEMINI_HW_IRQ_STATUS_BUS_ERROR_MASK | \
-		MSM_GEMINI_HW_IRQ_STATUS_VIOLATION_MASK)
-
-#define msm_gemini_hw_irq_is_frame_done(gemini_irq_status) \
-	(gemini_irq_status & MSM_GEMINI_HW_MASK_COMP_FRAMEDONE)
-#define msm_gemini_hw_irq_is_fe_pingpong(gemini_irq_status) \
-	(gemini_irq_status & MSM_GEMINI_HW_MASK_COMP_FE)
-#define msm_gemini_hw_irq_is_we_pingpong(gemini_irq_status) \
-	(gemini_irq_status & MSM_GEMINI_HW_MASK_COMP_WE)
-#define msm_gemini_hw_irq_is_reset_ack(gemini_irq_status) \
-	(gemini_irq_status & MSM_GEMINI_HW_MASK_COMP_RESET_ACK)
-#define msm_gemini_hw_irq_is_err(gemini_irq_status) \
-	(gemini_irq_status & MSM_GEMINI_HW_MASK_COMP_ERR)
-
-void msm_gemini_hw_fe_buffer_update(struct msm_gemini_hw_buf *p_input,
-	uint8_t pingpong_index);
-void msm_gemini_hw_we_buffer_update(struct msm_gemini_hw_buf *p_input,
-	uint8_t pingpong_index);
-
-void msm_gemini_hw_we_buffer_cfg(uint8_t is_realtime);
-
-void msm_gemini_hw_fe_start(void);
-void msm_gemini_hw_clk_cfg(void);
-
-void msm_gemini_hw_reset(void *base, int size);
-void msm_gemini_hw_irq_cfg(void);
-void msm_gemini_hw_init(void *base, int size);
-
-uint32_t msm_gemini_hw_read(struct msm_gemini_hw_cmd *hw_cmd_p);
-void msm_gemini_hw_write(struct msm_gemini_hw_cmd *hw_cmd_p);
-int msm_gemini_hw_wait(struct msm_gemini_hw_cmd *hw_cmd_p, int m_us);
-void msm_gemini_hw_delay(struct msm_gemini_hw_cmd *hw_cmd_p, int m_us);
-int msm_gemini_hw_exec_cmds(struct msm_gemini_hw_cmd *hw_cmd_p, int m_cmds);
-void msm_gemini_hw_region_dump(int size);
-
-#define MSM_GEMINI_PIPELINE_CLK_128MHZ 128 /* 8MP  128MHz */
-#define MSM_GEMINI_PIPELINE_CLK_140MHZ 140 /* 9MP  140MHz */
-#define MSM_GEMINI_PIPELINE_CLK_200MHZ 153 /* 12MP 153MHz */
-
-#endif /* MSM_GEMINI_HW_H */
diff --git a/drivers/media/video/msm/gemini/msm_gemini_hw_reg.h b/drivers/media/video/msm/gemini/msm_gemini_hw_reg.h
deleted file mode 100644
index 4bddfbb..0000000
--- a/drivers/media/video/msm/gemini/msm_gemini_hw_reg.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. 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 MSM_GEMINI_HW_REG_H
-#define MSM_GEMINI_HW_REG_H
-
-#define GEMINI_REG_BASE 0
-
-#define MSM_GEMINI_HW_IRQ_MASK_ADDR 0x00000014
-#define MSM_GEMINI_HW_IRQ_MASK_RMSK 0xffffffff
-#define MSM_GEMINI_HW_IRQ_MASK_SHFT 0
-#define MSM_GEMINI_HW_IRQ_DISABLE 0
-#define MSM_GEMINI_HW_IRQ_ENABLE 0xffffffff
-
-#define MSM_GEMINI_HW_IRQ_CLEAR_ADDR 0x00000018
-#define MSM_GEMINI_HW_IRQ_CLEAR_RMSK 0xffffffff
-#define MSM_GEMINI_HW_IRQ_CLEAR_SHFT 0
-#define MSM_GEMINI_HW_IRQ_CLEAR  0xffffffff
-
-#define MSM_GEMINI_HW_IRQ_STATUS_FRAMEDONE_MASK 0x00000001
-#define MSM_GEMINI_HW_IRQ_STATUS_FRAMEDONE_SHIFT 0x00000000
-
-#define MSM_GEMINI_HW_IRQ_STATUS_FE_RD_DONE_MASK 0x00000002
-#define MSM_GEMINI_HW_IRQ_STATUS_FE_RD_DONE_SHIFT 0x00000001
-
-#define MSM_GEMINI_HW_IRQ_STATUS_FE_RTOVF_MASK 0x00000004
-#define MSM_GEMINI_HW_IRQ_STATUS_FE_RTOVF_SHIFT 0x00000002
-
-#define MSM_GEMINI_HW_IRQ_STATUS_FE_VFE_OVERFLOW_MASK 0x00000008
-#define MSM_GEMINI_HW_IRQ_STATUS_FE_VFE_OVERFLOW_SHIFT 0x00000003
-
-#define MSM_GEMINI_HW_IRQ_STATUS_WE_Y_PINGPONG_MASK 0x00000010
-#define MSM_GEMINI_HW_IRQ_STATUS_WE_Y_PINGPONG_SHIFT 0x00000004
-
-#define MSM_GEMINI_HW_IRQ_STATUS_WE_CBCR_PINGPONG_MASK 0x00000020
-#define MSM_GEMINI_HW_IRQ_STATUS_WE_CBCR_PINGPONG_SHIFT 0x00000005
-
-#define MSM_GEMINI_HW_IRQ_STATUS_WE_Y_BUFFER_OVERFLOW_MASK 0x00000040
-#define MSM_GEMINI_HW_IRQ_STATUS_WE_Y_BUFFER_OVERFLOW_SHIFT 0x00000006
-
-#define MSM_GEMINI_HW_IRQ_STATUS_WE_CBCR_BUFFER_OVERFLOW_MASK 0x00000080
-#define MSM_GEMINI_HW_IRQ_STATUS_WE_CBCR_BUFFER_OVERFLOW_SHIFT 0x00000007
-
-#define MSM_GEMINI_HW_IRQ_STATUS_WE_CH0_DATAFIFO_OVERFLOW_MASK 0x00000100
-#define MSM_GEMINI_HW_IRQ_STATUS_WE_CH0_DATAFIFO_OVERFLOW_SHIFT 0x00000008
-
-#define MSM_GEMINI_HW_IRQ_STATUS_WE_CH1_DATAFIFO_OVERFLOW_MASK 0x00000200
-#define MSM_GEMINI_HW_IRQ_STATUS_WE_CH1_DATAFIFO_OVERFLOW_SHIFT 0x00000009
-
-#define MSM_GEMINI_HW_IRQ_STATUS_RESET_ACK_MASK 0x00000400
-#define MSM_GEMINI_HW_IRQ_STATUS_RESET_ACK_SHIFT 0x0000000a
-
-#define MSM_GEMINI_HW_IRQ_STATUS_BUS_ERROR_MASK 0x00000800
-#define MSM_GEMINI_HW_IRQ_STATUS_BUS_ERROR_SHIFT 0x0000000b
-
-#define MSM_GEMINI_HW_IRQ_STATUS_VIOLATION_MASK 0x00001000
-#define MSM_GEMINI_HW_IRQ_STATUS_VIOLATION_SHIFT 0x0000000c
-
-#define JPEG_BUS_CMD_HALT_REQ 0x00000001
-
-#define JPEG_REALTIME_CMD_STOP_FB 0x00000000
-#define JPEG_REALTIME_CMD_STOP_IM 0x00000003
-#define JPEG_REALTIME_CMD_START 0x00000001
-
-#define JPEG_OFFLINE_CMD_START 0x00000003
-
-#define JPEG_DMI_CFG_DISABLE 0x00000000
-#define JPEG_DMI_ADDR_START 0x00000000
-
-#define JPEG_FE_CMD_BUFFERRELOAD 0x00000001
-
-#define JPEG_WE_YUB_ENCODE 0x01ff0000
-
-#define JPEG_RESET_DEFAULT 0x0004ffff /* cfff? */
-
-#define JPEG_IRQ_DISABLE_ALL 0x00000000
-#define JPEG_IRQ_CLEAR_ALL 0xffffffff
-#define JPEG_IRQ_ALLSOURCES_ENABLE 0xffffffff
-
-#define HWIO_JPEG_FE_BUFFER_CFG_ADDR (GEMINI_REG_BASE + 0x00000080)
-#define HWIO_JPEG_FE_BUFFER_CFG_RMSK 0x1fff1fff
-
-#define HWIO_JPEG_FE_Y_PING_ADDR_ADDR (GEMINI_REG_BASE + 0x00000084)
-#define HWIO_JPEG_FE_Y_PING_ADDR_RMSK 0xffffffff
-
-#define HWIO_JPEG_FE_Y_PONG_ADDR_ADDR (GEMINI_REG_BASE + 0x00000088)
-#define HWIO_JPEG_FE_Y_PONG_ADDR_RMSK 0xffffffff
-
-#define HWIO_JPEG_FE_CBCR_PING_ADDR_ADDR (GEMINI_REG_BASE + 0x0000008c)
-#define HWIO_JPEG_FE_CBCR_PING_ADDR_RMSK 0xffffffff
-
-#define HWIO_JPEG_FE_CBCR_PONG_ADDR_ADDR (GEMINI_REG_BASE + 0x00000090)
-#define HWIO_JPEG_FE_CBCR_PONG_ADDR_RMSK 0xffffffff
-
-#define HWIO_JPEG_FE_CMD_ADDR (GEMINI_REG_BASE + 0x00000094)
-#define HWIO_JPEG_FE_CMD_RMSK 0x3
-
-#define HWIO_JPEG_FE_BUFFER_CFG_CBCR_MCU_ROWS_BMSK 0x1fff0000
-#define HWIO_JPEG_FE_BUFFER_CFG_CBCR_MCU_ROWS_SHFT 0x10
-#define HWIO_JPEG_FE_BUFFER_CFG_Y_MCU_ROWS_BMSK 0x1fff
-#define HWIO_JPEG_FE_BUFFER_CFG_Y_MCU_ROWS_SHFT 0
-
-#define HWIO_JPEG_FE_Y_PING_ADDR_FE_Y_PING_START_ADDR_BMSK 0xffffffff
-#define HWIO_JPEG_FE_Y_PING_ADDR_FE_Y_PING_START_ADDR_SHFT 0
-
-#define HWIO_JPEG_FE_CBCR_PING_ADDR_FE_CBCR_PING_START_ADDR_BMSK 0xffffffff
-#define HWIO_JPEG_FE_CBCR_PING_ADDR_FE_CBCR_PING_START_ADDR_SHFT 0
-
-#define HWIO_JPEG_FE_Y_PONG_ADDR_FE_Y_PONG_START_ADDR_BMSK 0xffffffff
-#define HWIO_JPEG_FE_Y_PONG_ADDR_FE_Y_PONG_START_ADDR_SHFT 0
-
-#define HWIO_JPEG_FE_CBCR_PONG_ADDR_FE_CBCR_PONG_START_ADDR_BMSK 0xffffffff
-#define HWIO_JPEG_FE_CBCR_PONG_ADDR_FE_CBCR_PONG_START_ADDR_SHFT 0
-
-#define HWIO_JPEG_WE_Y_THRESHOLD_ADDR (GEMINI_REG_BASE + 0x000000c0)
-#define HWIO_JPEG_WE_Y_THRESHOLD_RMSK 0x1ff01ff
-
-#define HWIO_JPEG_WE_CBCR_THRESHOLD_ADDR (GEMINI_REG_BASE      + 0x000000c4)
-#define HWIO_JPEG_WE_CBCR_THRESHOLD_RMSK 0x1ff01ff
-
-#define HWIO_JPEG_WE_Y_UB_CFG_ADDR (GEMINI_REG_BASE + 0x000000e8)
-#define HWIO_JPEG_WE_Y_UB_CFG_RMSK 0x1ff01ff
-
-#define HWIO_JPEG_WE_Y_THRESHOLD_WE_DEASSERT_STALL_TH_BMSK 0x1ff0000
-#define HWIO_JPEG_WE_Y_THRESHOLD_WE_DEASSERT_STALL_TH_SHFT 0x10
-#define HWIO_JPEG_WE_Y_THRESHOLD_WE_ASSERT_STALL_TH_BMSK 0x1ff
-#define HWIO_JPEG_WE_Y_THRESHOLD_WE_ASSERT_STALL_TH_SHFT 0
-
-#define HWIO_JPEG_WE_CBCR_THRESHOLD_WE_DEASSERT_STALL_TH_BMSK 0x1ff0000
-#define HWIO_JPEG_WE_CBCR_THRESHOLD_WE_DEASSERT_STALL_TH_SHFT 0x10
-#define HWIO_JPEG_WE_CBCR_THRESHOLD_WE_ASSERT_STALL_TH_BMSK 0x1ff
-#define HWIO_JPEG_WE_CBCR_THRESHOLD_WE_ASSERT_STALL_TH_SHFT 0
-
-#define HWIO_JPEG_WE_Y_PING_BUFFER_CFG_ADDR (GEMINI_REG_BASE + 0x000000c8)
-#define HWIO_JPEG_WE_Y_PING_BUFFER_CFG_RMSK 0x7fffff
-
-#define HWIO_JPEG_WE_Y_PING_ADDR_ADDR (GEMINI_REG_BASE + 0x000000d8)
-#define HWIO_JPEG_WE_Y_PING_ADDR_RMSK 0xfffffff8
-
-#define HWIO_JPEG_WE_Y_PONG_BUFFER_CFG_ADDR (GEMINI_REG_BASE + 0x000000cc)
-#define HWIO_JPEG_WE_Y_PONG_BUFFER_CFG_RMSK 0x7fffff
-
-#define HWIO_JPEG_WE_Y_PONG_ADDR_ADDR (GEMINI_REG_BASE + 0x000000dc)
-#define HWIO_JPEG_WE_Y_PONG_ADDR_RMSK 0xfffffff8
-
-#define HWIO_JPEG_WE_Y_PING_BUFFER_CFG_WE_BUFFER_LENGTH_BMSK 0x7fffff
-#define HWIO_JPEG_WE_Y_PING_BUFFER_CFG_WE_BUFFER_LENGTH_SHFT 0
-
-#define HWIO_JPEG_WE_Y_PONG_BUFFER_CFG_WE_BUFFER_LENGTH_BMSK 0x7fffff
-#define HWIO_JPEG_WE_Y_PONG_BUFFER_CFG_WE_BUFFER_LENGTH_SHFT 0
-
-#define HWIO_JPEG_IRQ_MASK_ADDR (GEMINI_REG_BASE + 0x00000014)
-#define HWIO_JPEG_IRQ_MASK_RMSK 0xffffffff
-
-#define HWIO_JPEG_IRQ_CLEAR_ADDR (GEMINI_REG_BASE + 0x00000018)
-#define HWIO_JPEG_IRQ_CLEAR_RMSK 0xffffffff
-
-#define HWIO_JPEG_RESET_CMD_ADDR (GEMINI_REG_BASE + 0x00000004)
-#define HWIO_JPEG_RESET_CMD_RMSK 0xe004ffff
-
-#define HWIO_JPEG_IRQ_STATUS_ADDR (GEMINI_REG_BASE + 0x0000001c)
-#define HWIO_JPEG_IRQ_STATUS_RMSK 0xffffffff
-
-#define HWIO_JPEG_STATUS_ENCODE_OUTPUT_SIZE_ADDR (GEMINI_REG_BASE + 0x00000034)
-#define HWIO_JPEG_STATUS_ENCODE_OUTPUT_SIZE_RMSK 0xffffff
-
-#endif /* MSM_GEMINI_HW_REG_H */
diff --git a/drivers/media/video/msm/gemini/msm_gemini_platform.c b/drivers/media/video/msm/gemini/msm_gemini_platform.c
deleted file mode 100644
index 111402b..0000000
--- a/drivers/media/video/msm/gemini/msm_gemini_platform.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. 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/pm_qos.h>
-#include <linux/clk.h>
-#include <mach/clk.h>
-#include <linux/io.h>
-#include <linux/android_pmem.h>
-#include <mach/camera.h>
-#include <mach/iommu_domains.h>
-
-#include "msm_gemini_platform.h"
-#include "msm_gemini_sync.h"
-#include "msm_gemini_common.h"
-#include "msm_gemini_hw.h"
-
-/* AXI rate in KHz */
-#define MSM_SYSTEM_BUS_RATE	160000
-struct ion_client *gemini_client;
-
-void msm_gemini_platform_p2v(struct file  *file,
-				struct ion_handle **ionhandle)
-{
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	ion_unmap_iommu(gemini_client, *ionhandle, CAMERA_DOMAIN, GEN_POOL);
-	ion_free(gemini_client, *ionhandle);
-	*ionhandle = NULL;
-#elif CONFIG_ANDROID_PMEM
-	put_pmem_file(file);
-#endif
-}
-
-uint32_t msm_gemini_platform_v2p(int fd, uint32_t len, struct file **file_p,
-				struct ion_handle **ionhandle)
-{
-	unsigned long paddr;
-	unsigned long size;
-	int rc;
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	*ionhandle = ion_import_dma_buf(gemini_client, fd);
-	if (IS_ERR_OR_NULL(*ionhandle))
-		return 0;
-
-	rc = ion_map_iommu(gemini_client, *ionhandle, CAMERA_DOMAIN, GEN_POOL,
-			SZ_4K, 0, &paddr, (unsigned long *)&size, 0, 0);
-#elif CONFIG_ANDROID_PMEM
-	unsigned long kvstart;
-	rc = get_pmem_file(fd, &paddr, &kvstart, &size, file_p);
-#else
-	rc = 0;
-	paddr = 0;
-	size = 0;
-#endif
-	if (rc < 0) {
-		GMN_PR_ERR("%s: get_pmem_file fd %d error %d\n", __func__, fd,
-			rc);
-		goto error1;
-	}
-
-	/* validate user input */
-	if (len > size) {
-		GMN_PR_ERR("%s: invalid offset + len\n", __func__);
-		goto error1;
-	}
-
-	return paddr;
-error1:
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	ion_free(gemini_client, *ionhandle);
-#endif
-	return 0;
-}
-
-static struct msm_cam_clk_info gemini_8x_clk_info[] = {
-	{"core_clk", 228571000},
-	{"iface_clk", -1},
-};
-
-static struct msm_cam_clk_info gemini_7x_clk_info[] = {
-	{"core_clk", 153600000},
-	{"iface_clk", -1},
-};
-
-static struct msm_cam_clk_info gemini_imem_clk_info[] = {
-	{"mem_clk", -1},
-};
-
-int msm_gemini_platform_init(struct platform_device *pdev,
-	struct resource **mem,
-	void **base,
-	int *irq,
-	irqreturn_t (*handler) (int, void *),
-	void *context)
-{
-	int rc = -1;
-	int gemini_irq;
-	struct resource *gemini_mem, *gemini_io, *gemini_irq_res;
-	void *gemini_base;
-	struct msm_gemini_device *pgmn_dev =
-		(struct msm_gemini_device *) context;
-
-	gemini_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!gemini_mem) {
-		GMN_PR_ERR("%s: no mem resource?\n", __func__);
-		return -ENODEV;
-	}
-
-	gemini_irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!gemini_irq_res) {
-		GMN_PR_ERR("no irq resource?\n");
-		return -ENODEV;
-	}
-	gemini_irq = gemini_irq_res->start;
-
-	gemini_io = request_mem_region(gemini_mem->start,
-		resource_size(gemini_mem), pdev->name);
-	if (!gemini_io) {
-		GMN_PR_ERR("%s: region already claimed\n", __func__);
-		return -EBUSY;
-	}
-
-	gemini_base = ioremap(gemini_mem->start, resource_size(gemini_mem));
-	if (!gemini_base) {
-		rc = -ENOMEM;
-		GMN_PR_ERR("%s: ioremap failed\n", __func__);
-		goto fail1;
-	}
-
-	pgmn_dev->hw_version = GEMINI_8X60;
-	rc = msm_cam_clk_enable(&pgmn_dev->pdev->dev, gemini_8x_clk_info,
-	 pgmn_dev->gemini_clk, ARRAY_SIZE(gemini_8x_clk_info), 1);
-	if (rc < 0) {
-		pgmn_dev->hw_version = GEMINI_7X;
-		rc = msm_cam_clk_enable(&pgmn_dev->pdev->dev,
-			gemini_7x_clk_info, pgmn_dev->gemini_clk,
-			ARRAY_SIZE(gemini_7x_clk_info), 1);
-		if (rc < 0) {
-			GMN_PR_ERR("%s: clk failed rc = %d\n", __func__, rc);
-			goto fail2;
-		}
-	} else {
-		rc = msm_cam_clk_enable(&pgmn_dev->pdev->dev,
-				gemini_imem_clk_info, &pgmn_dev->gemini_clk[2],
-				ARRAY_SIZE(gemini_imem_clk_info), 1);
-		if (!rc)
-			pgmn_dev->hw_version = GEMINI_8960;
-	}
-
-	if (pgmn_dev->hw_version != GEMINI_7X) {
-		if (pgmn_dev->gemini_fs == NULL) {
-			pgmn_dev->gemini_fs =
-				regulator_get(&pgmn_dev->pdev->dev, "vdd");
-			if (IS_ERR(pgmn_dev->gemini_fs)) {
-				pr_err("%s: Regulator FS_ijpeg get failed %ld\n",
-					__func__, PTR_ERR(pgmn_dev->gemini_fs));
-				pgmn_dev->gemini_fs = NULL;
-				goto gemini_fs_failed;
-			} else if (regulator_enable(pgmn_dev->gemini_fs)) {
-				pr_err("%s: Regulator FS_ijpeg enable failed\n",
-								__func__);
-				regulator_put(pgmn_dev->gemini_fs);
-				pgmn_dev->gemini_fs = NULL;
-				goto gemini_fs_failed;
-			}
-		}
-	}
-
-	msm_gemini_hw_init(gemini_base, resource_size(gemini_mem));
-	rc = request_irq(gemini_irq, handler, IRQF_TRIGGER_RISING, "gemini",
-		context);
-	if (rc) {
-		GMN_PR_ERR("%s: request_irq failed, %d\n", __func__,
-			gemini_irq);
-		goto fail3;
-	}
-
-	*mem  = gemini_mem;
-	*base = gemini_base;
-	*irq  = gemini_irq;
-
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	gemini_client = msm_ion_client_create(-1, "camera/gemini");
-#endif
-	GMN_DBG("%s:%d] success\n", __func__, __LINE__);
-
-	return rc;
-
-fail3:
-	if (pgmn_dev->hw_version != GEMINI_7X) {
-		regulator_disable(pgmn_dev->gemini_fs);
-		regulator_put(pgmn_dev->gemini_fs);
-		pgmn_dev->gemini_fs = NULL;
-	}
-gemini_fs_failed:
-	if (pgmn_dev->hw_version == GEMINI_8960)
-		msm_cam_clk_enable(&pgmn_dev->pdev->dev, gemini_imem_clk_info,
-		 &pgmn_dev->gemini_clk[2], ARRAY_SIZE(gemini_imem_clk_info), 0);
-	if (pgmn_dev->hw_version != GEMINI_7X)
-		msm_cam_clk_enable(&pgmn_dev->pdev->dev, gemini_8x_clk_info,
-		pgmn_dev->gemini_clk, ARRAY_SIZE(gemini_8x_clk_info), 0);
-	else
-		msm_cam_clk_enable(&pgmn_dev->pdev->dev, gemini_7x_clk_info,
-		pgmn_dev->gemini_clk, ARRAY_SIZE(gemini_7x_clk_info), 0);
-fail2:
-	iounmap(gemini_base);
-fail1:
-	release_mem_region(gemini_mem->start, resource_size(gemini_mem));
-	GMN_DBG("%s:%d] fail\n", __func__, __LINE__);
-	return rc;
-}
-
-int msm_gemini_platform_release(struct resource *mem, void *base, int irq,
-	void *context)
-{
-	int result = 0;
-	struct msm_gemini_device *pgmn_dev =
-		(struct msm_gemini_device *) context;
-
-	free_irq(irq, context);
-
-	if (pgmn_dev->hw_version != GEMINI_7X) {
-		regulator_disable(pgmn_dev->gemini_fs);
-		regulator_put(pgmn_dev->gemini_fs);
-		pgmn_dev->gemini_fs = NULL;
-	}
-
-	if (pgmn_dev->hw_version == GEMINI_8960)
-		msm_cam_clk_enable(&pgmn_dev->pdev->dev, gemini_imem_clk_info,
-		 &pgmn_dev->gemini_clk[2], ARRAY_SIZE(gemini_imem_clk_info), 0);
-	if (pgmn_dev->hw_version != GEMINI_7X)
-		msm_cam_clk_enable(&pgmn_dev->pdev->dev, gemini_8x_clk_info,
-		pgmn_dev->gemini_clk, ARRAY_SIZE(gemini_8x_clk_info), 0);
-	else
-		msm_cam_clk_enable(&pgmn_dev->pdev->dev, gemini_7x_clk_info,
-		pgmn_dev->gemini_clk, ARRAY_SIZE(gemini_7x_clk_info), 0);
-
-	iounmap(base);
-	release_mem_region(mem->start, resource_size(mem));
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	ion_client_destroy(gemini_client);
-#endif
-	GMN_DBG("%s:%d] success\n", __func__, __LINE__);
-	return result;
-}
-
diff --git a/drivers/media/video/msm/gemini/msm_gemini_platform.h b/drivers/media/video/msm/gemini/msm_gemini_platform.h
deleted file mode 100644
index d7f81aa..0000000
--- a/drivers/media/video/msm/gemini/msm_gemini_platform.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. 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 MSM_GEMINI_PLATFORM_H
-#define MSM_GEMINI_PLATFORM_H
-
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/msm_ion.h>
-#include <linux/iommu.h>
-void msm_gemini_platform_p2v(struct file  *file,
-				struct ion_handle **ionhandle);
-uint32_t msm_gemini_platform_v2p(int fd, uint32_t len, struct file **file,
-				struct ion_handle **ionhandle);
-
-int msm_gemini_platform_clk_enable(void);
-int msm_gemini_platform_clk_disable(void);
-
-int msm_gemini_platform_init(struct platform_device *pdev,
-	struct resource **mem,
-	void **base,
-	int *irq,
-	irqreturn_t (*handler) (int, void *),
-	void *context);
-int msm_gemini_platform_release(struct resource *mem, void *base, int irq,
-	void *context);
-
-#endif /* MSM_GEMINI_PLATFORM_H */
diff --git a/drivers/media/video/msm/gemini/msm_gemini_sync.c b/drivers/media/video/msm/gemini/msm_gemini_sync.c
deleted file mode 100644
index 97bb611..0000000
--- a/drivers/media/video/msm/gemini/msm_gemini_sync.c
+++ /dev/null
@@ -1,863 +0,0 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. 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/sched.h>
-#include <linux/list.h>
-#include <linux/uaccess.h>
-#include <linux/slab.h>
-#include <media/msm_gemini.h>
-#include "msm_gemini_sync.h"
-#include "msm_gemini_core.h"
-#include "msm_gemini_platform.h"
-#include "msm_gemini_common.h"
-
-static int release_buf;
-
-/*************** queue helper ****************/
-inline void msm_gemini_q_init(char const *name, struct msm_gemini_q *q_p)
-{
-	GMN_DBG("%s:%d] %s\n", __func__, __LINE__, name);
-	q_p->name = name;
-	spin_lock_init(&q_p->lck);
-	INIT_LIST_HEAD(&q_p->q);
-	init_waitqueue_head(&q_p->wait);
-	q_p->unblck = 0;
-}
-
-inline void *msm_gemini_q_out(struct msm_gemini_q *q_p)
-{
-	unsigned long flags;
-	struct msm_gemini_q_entry *q_entry_p = NULL;
-	void *data = NULL;
-
-	GMN_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
-	spin_lock_irqsave(&q_p->lck, flags);
-	if (!list_empty(&q_p->q)) {
-		q_entry_p = list_first_entry(&q_p->q, struct msm_gemini_q_entry,
-			list);
-		list_del_init(&q_entry_p->list);
-	}
-	spin_unlock_irqrestore(&q_p->lck, flags);
-
-	if (q_entry_p) {
-		data = q_entry_p->data;
-		kfree(q_entry_p);
-	} else {
-		GMN_DBG("%s:%d] %s no entry\n", __func__, __LINE__,
-			q_p->name);
-	}
-
-	return data;
-}
-
-inline int msm_gemini_q_in(struct msm_gemini_q *q_p, void *data)
-{
-	unsigned long flags;
-
-	struct msm_gemini_q_entry *q_entry_p;
-
-	GMN_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
-
-	q_entry_p = kmalloc(sizeof(struct msm_gemini_q_entry), GFP_ATOMIC);
-	if (!q_entry_p) {
-		GMN_PR_ERR("%s: no mem\n", __func__);
-		return -1;
-	}
-	q_entry_p->data = data;
-
-	spin_lock_irqsave(&q_p->lck, flags);
-	list_add_tail(&q_entry_p->list, &q_p->q);
-	spin_unlock_irqrestore(&q_p->lck, flags);
-
-	return 0;
-}
-
-inline int msm_gemini_q_in_buf(struct msm_gemini_q *q_p,
-	struct msm_gemini_core_buf *buf)
-{
-	struct msm_gemini_core_buf *buf_p;
-
-	GMN_DBG("%s:%d]\n", __func__, __LINE__);
-	buf_p = kmalloc(sizeof(struct msm_gemini_core_buf), GFP_ATOMIC);
-	if (!buf_p) {
-		GMN_PR_ERR("%s: no mem\n", __func__);
-		return -1;
-	}
-
-	memcpy(buf_p, buf, sizeof(struct msm_gemini_core_buf));
-
-	msm_gemini_q_in(q_p, buf_p);
-	return 0;
-}
-
-inline int msm_gemini_q_wait(struct msm_gemini_q *q_p)
-{
-	int tm = MAX_SCHEDULE_TIMEOUT; /* 500ms */
-	int rc;
-
-	GMN_DBG("%s:%d] %s wait\n", __func__, __LINE__, q_p->name);
-	rc = wait_event_interruptible_timeout(q_p->wait,
-		(!list_empty_careful(&q_p->q) || q_p->unblck),
-		msecs_to_jiffies(tm));
-	GMN_DBG("%s:%d] %s wait done\n", __func__, __LINE__, q_p->name);
-	if (list_empty_careful(&q_p->q)) {
-		if (rc == 0) {
-			rc = -ETIMEDOUT;
-			GMN_PR_ERR("%s:%d] %s timeout\n", __func__, __LINE__,
-				q_p->name);
-		} else if (q_p->unblck) {
-			GMN_DBG("%s:%d] %s unblock is true\n", __func__,
-				__LINE__, q_p->name);
-			q_p->unblck = 0;
-			rc = -ECANCELED;
-		} else if (rc < 0) {
-			GMN_PR_ERR("%s:%d] %s rc %d\n", __func__, __LINE__,
-				q_p->name, rc);
-		}
-	}
-	return rc;
-}
-
-inline int msm_gemini_q_wakeup(struct msm_gemini_q *q_p)
-{
-	GMN_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
-	wake_up(&q_p->wait);
-	return 0;
-}
-
-inline int msm_gemini_q_unblock(struct msm_gemini_q *q_p)
-{
-	GMN_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
-	q_p->unblck = 1;
-	wake_up(&q_p->wait);
-	return 0;
-}
-
-inline void msm_gemini_outbuf_q_cleanup(struct msm_gemini_q *q_p)
-{
-	struct msm_gemini_core_buf *buf_p;
-	GMN_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
-	do {
-		buf_p = msm_gemini_q_out(q_p);
-		if (buf_p) {
-			msm_gemini_platform_p2v(buf_p->file,
-				&buf_p->handle);
-			GMN_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
-			kfree(buf_p);
-		}
-	} while (buf_p);
-	q_p->unblck = 0;
-}
-
-inline void msm_gemini_q_cleanup(struct msm_gemini_q *q_p)
-{
-	void *data;
-	GMN_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
-	do {
-		data = msm_gemini_q_out(q_p);
-		if (data) {
-			GMN_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
-			kfree(data);
-		}
-	} while (data);
-	q_p->unblck = 0;
-}
-
-/*************** event queue ****************/
-
-int msm_gemini_framedone_irq(struct msm_gemini_device *pgmn_dev,
-	struct msm_gemini_core_buf *buf_in)
-{
-	int rc = 0;
-
-	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
-
-	if (buf_in) {
-		buf_in->vbuf.framedone_len = buf_in->framedone_len;
-		buf_in->vbuf.type = MSM_GEMINI_EVT_FRAMEDONE;
-		GMN_DBG("%s:%d] 0x%08x %d framedone_len %d\n",
-			__func__, __LINE__,
-			(int) buf_in->y_buffer_addr, buf_in->y_len,
-			buf_in->vbuf.framedone_len);
-		rc = msm_gemini_q_in_buf(&pgmn_dev->evt_q, buf_in);
-	} else {
-		GMN_PR_ERR("%s:%d] no output return buffer\n",
-			__func__, __LINE__);
-		rc = -1;
-	}
-
-	if (buf_in)
-		rc = msm_gemini_q_wakeup(&pgmn_dev->evt_q);
-
-	return rc;
-}
-
-int msm_gemini_evt_get(struct msm_gemini_device *pgmn_dev,
-	void __user *to)
-{
-	struct msm_gemini_core_buf *buf_p;
-	struct msm_gemini_ctrl_cmd ctrl_cmd;
-
-	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
-
-	msm_gemini_q_wait(&pgmn_dev->evt_q);
-	buf_p = msm_gemini_q_out(&pgmn_dev->evt_q);
-
-	if (!buf_p) {
-		GMN_DBG("%s:%d] no buffer\n", __func__, __LINE__);
-		return -EAGAIN;
-	}
-
-	memset(&ctrl_cmd, 0, sizeof(struct msm_gemini_ctrl_cmd));
-	ctrl_cmd.type = buf_p->vbuf.type;
-	kfree(buf_p);
-
-	GMN_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
-		(int) ctrl_cmd.value, ctrl_cmd.len);
-
-	if (copy_to_user(to, &ctrl_cmd, sizeof(ctrl_cmd))) {
-		GMN_PR_ERR("%s:%d]\n", __func__, __LINE__);
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
-int msm_gemini_evt_get_unblock(struct msm_gemini_device *pgmn_dev)
-{
-	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
-	msm_gemini_q_unblock(&pgmn_dev->evt_q);
-	return 0;
-}
-
-void msm_gemini_reset_ack_irq(struct msm_gemini_device *pgmn_dev)
-{
-	GMN_DBG("%s:%d]\n", __func__, __LINE__);
-}
-
-void msm_gemini_err_irq(struct msm_gemini_device *pgmn_dev,
-	int event)
-{
-	int rc = 0;
-	struct msm_gemini_core_buf buf;
-
-	GMN_PR_ERR("%s:%d] error: %d\n", __func__, __LINE__, event);
-
-	buf.vbuf.type = MSM_GEMINI_EVT_ERR;
-	rc = msm_gemini_q_in_buf(&pgmn_dev->evt_q, &buf);
-	if (!rc)
-		rc = msm_gemini_q_wakeup(&pgmn_dev->evt_q);
-
-	if (!rc)
-		GMN_PR_ERR("%s:%d] err err\n", __func__, __LINE__);
-
-	return;
-}
-
-/*************** output queue ****************/
-
-int msm_gemini_we_pingpong_irq(struct msm_gemini_device *pgmn_dev,
-	struct msm_gemini_core_buf *buf_in)
-{
-	int rc = 0;
-	struct msm_gemini_core_buf *buf_out;
-
-	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
-	if (buf_in) {
-		GMN_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
-			(int) buf_in->y_buffer_addr, buf_in->y_len);
-		rc = msm_gemini_q_in_buf(&pgmn_dev->output_rtn_q, buf_in);
-	} else {
-		GMN_DBG("%s:%d] no output return buffer\n", __func__,
-			__LINE__);
-		rc = -1;
-		return rc;
-	}
-
-	buf_out = msm_gemini_q_out(&pgmn_dev->output_buf_q);
-
-	if (buf_out) {
-		rc = msm_gemini_core_we_buf_update(buf_out);
-		kfree(buf_out);
-	} else {
-		msm_gemini_core_we_buf_reset(buf_in);
-		GMN_DBG("%s:%d] no output buffer\n", __func__, __LINE__);
-		rc = -2;
-	}
-
-	if (buf_in)
-		rc = msm_gemini_q_wakeup(&pgmn_dev->output_rtn_q);
-
-	return rc;
-}
-
-int msm_gemini_output_get(struct msm_gemini_device *pgmn_dev, void __user *to)
-{
-	struct msm_gemini_core_buf *buf_p;
-	struct msm_gemini_buf buf_cmd;
-
-	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
-
-	msm_gemini_q_wait(&pgmn_dev->output_rtn_q);
-	buf_p = msm_gemini_q_out(&pgmn_dev->output_rtn_q);
-
-	if (!buf_p) {
-		GMN_DBG("%s:%d] no output buffer return\n",
-			__func__, __LINE__);
-		return -EAGAIN;
-	}
-
-	buf_cmd = buf_p->vbuf;
-	msm_gemini_platform_p2v(buf_p->file, &buf_p->handle);
-	kfree(buf_p);
-
-	GMN_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
-		(int) buf_cmd.vaddr, buf_cmd.y_len);
-
-	if (copy_to_user(to, &buf_cmd, sizeof(buf_cmd))) {
-		GMN_PR_ERR("%s:%d]", __func__, __LINE__);
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
-int msm_gemini_output_get_unblock(struct msm_gemini_device *pgmn_dev)
-{
-	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
-	msm_gemini_q_unblock(&pgmn_dev->output_rtn_q);
-	return 0;
-}
-
-int msm_gemini_output_buf_enqueue(struct msm_gemini_device *pgmn_dev,
-	void __user *arg)
-{
-	struct msm_gemini_buf buf_cmd;
-	struct msm_gemini_core_buf *buf_p;
-
-	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
-	if (copy_from_user(&buf_cmd, arg, sizeof(struct msm_gemini_buf))) {
-		GMN_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
-		return -EFAULT;
-	}
-
-	buf_p = kmalloc(sizeof(struct msm_gemini_core_buf), GFP_ATOMIC);
-	if (!buf_p) {
-		GMN_PR_ERR("%s:%d] no mem\n", __func__, __LINE__);
-		return -1;
-	}
-
-	GMN_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__, (int) buf_cmd.vaddr,
-		buf_cmd.y_len);
-
-	buf_p->y_buffer_addr = msm_gemini_platform_v2p(buf_cmd.fd,
-		buf_cmd.y_len, &buf_p->file, &buf_p->handle);
-	if (!buf_p->y_buffer_addr) {
-		GMN_PR_ERR("%s:%d] v2p wrong\n", __func__, __LINE__);
-		kfree(buf_p);
-		return -1;
-	}
-	buf_p->y_len = buf_cmd.y_len;
-	buf_p->vbuf = buf_cmd;
-
-	msm_gemini_q_in(&pgmn_dev->output_buf_q, buf_p);
-	return 0;
-}
-
-/*************** input queue ****************/
-
-int msm_gemini_fe_pingpong_irq(struct msm_gemini_device *pgmn_dev,
-	struct msm_gemini_core_buf *buf_in)
-{
-	struct msm_gemini_core_buf *buf_out;
-	int rc = 0;
-
-	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
-	if (buf_in) {
-		GMN_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
-			(int) buf_in->y_buffer_addr, buf_in->y_len);
-		rc = msm_gemini_q_in_buf(&pgmn_dev->input_rtn_q, buf_in);
-	} else {
-		GMN_DBG("%s:%d] no input return buffer\n", __func__,
-			__LINE__);
-		rc = -1;
-	}
-
-	buf_out = msm_gemini_q_out(&pgmn_dev->input_buf_q);
-
-	if (buf_out) {
-		rc = msm_gemini_core_fe_buf_update(buf_out);
-		kfree(buf_out);
-		msm_gemini_core_fe_start();
-	} else {
-		GMN_DBG("%s:%d] no input buffer\n", __func__, __LINE__);
-		rc = -2;
-	}
-
-	if (buf_in)
-		rc = msm_gemini_q_wakeup(&pgmn_dev->input_rtn_q);
-
-	return rc;
-}
-
-int msm_gemini_input_get(struct msm_gemini_device *pgmn_dev, void __user * to)
-{
-	struct msm_gemini_core_buf *buf_p;
-	struct msm_gemini_buf buf_cmd;
-
-	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
-	msm_gemini_q_wait(&pgmn_dev->input_rtn_q);
-	buf_p = msm_gemini_q_out(&pgmn_dev->input_rtn_q);
-
-	if (!buf_p) {
-		GMN_DBG("%s:%d] no input buffer return\n",
-			__func__, __LINE__);
-		return -EAGAIN;
-	}
-
-	buf_cmd = buf_p->vbuf;
-	if (pgmn_dev->op_mode == MSM_GEMINI_MODE_OFFLINE_ENCODE ||
-		pgmn_dev->op_mode == MSM_GEMINI_MODE_OFFLINE_ROTATION) {
-		msm_gemini_platform_p2v(buf_p->file, &buf_p->handle);
-	}
-	kfree(buf_p);
-
-	GMN_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
-		(int) buf_cmd.vaddr, buf_cmd.y_len);
-
-	if (copy_to_user(to, &buf_cmd, sizeof(buf_cmd))) {
-		GMN_PR_ERR("%s:%d]\n", __func__, __LINE__);
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
-int msm_gemini_input_get_unblock(struct msm_gemini_device *pgmn_dev)
-{
-	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
-	msm_gemini_q_unblock(&pgmn_dev->input_rtn_q);
-	return 0;
-}
-
-int msm_gemini_input_buf_enqueue(struct msm_gemini_device *pgmn_dev,
-	void __user *arg)
-{
-	struct msm_gemini_core_buf *buf_p;
-	struct msm_gemini_buf buf_cmd;
-	int rc = 0;
-
-	if (copy_from_user(&buf_cmd, arg, sizeof(struct msm_gemini_buf))) {
-		GMN_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
-		return -EFAULT;
-	}
-
-	buf_p = kmalloc(sizeof(struct msm_gemini_core_buf), GFP_ATOMIC);
-	if (!buf_p) {
-		GMN_PR_ERR("%s:%d] no mem\n", __func__, __LINE__);
-		return -1;
-	}
-
-	GMN_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
-		(int) buf_cmd.vaddr, buf_cmd.y_len);
-
-	if (pgmn_dev->op_mode == MSM_GEMINI_MODE_REALTIME_ENCODE) {
-		rc = msm_iommu_map_contig_buffer(
-			(unsigned long)buf_cmd.y_off, CAMERA_DOMAIN, GEN_POOL,
-			((buf_cmd.y_len + buf_cmd.cbcr_len + 4095) & (~4095)),
-			SZ_4K, IOMMU_WRITE | IOMMU_READ,
-			(unsigned long *)&buf_p->y_buffer_addr);
-		if (rc < 0) {
-			pr_err("%s iommu mapping failed with error %d\n",
-				 __func__, rc);
-			kfree(buf_p);
-			return rc;
-		}
-	} else {
-	buf_p->y_buffer_addr    = msm_gemini_platform_v2p(buf_cmd.fd,
-		buf_cmd.y_len + buf_cmd.cbcr_len, &buf_p->file,
-		&buf_p->handle)	+ buf_cmd.offset + buf_cmd.y_off;
-	}
-	buf_p->y_len          = buf_cmd.y_len;
-
-	buf_p->cbcr_buffer_addr = buf_p->y_buffer_addr + buf_cmd.y_len +
-					buf_cmd.cbcr_off;
-	buf_p->cbcr_len       = buf_cmd.cbcr_len;
-	buf_p->num_of_mcu_rows = buf_cmd.num_of_mcu_rows;
-	GMN_DBG("%s: y_addr=%x,y_len=%x,cbcr_addr=%x,cbcr_len=%x\n", __func__,
-		buf_p->y_buffer_addr, buf_p->y_len, buf_p->cbcr_buffer_addr,
-		buf_p->cbcr_len);
-
-	if (!buf_p->y_buffer_addr || !buf_p->cbcr_buffer_addr) {
-		GMN_PR_ERR("%s:%d] v2p wrong\n", __func__, __LINE__);
-		kfree(buf_p);
-		return -1;
-	}
-	buf_p->vbuf           = buf_cmd;
-
-	msm_gemini_q_in(&pgmn_dev->input_buf_q, buf_p);
-
-	return 0;
-}
-
-int msm_gemini_irq(int event, void *context, void *data)
-{
-	struct msm_gemini_device *pgmn_dev =
-		(struct msm_gemini_device *) context;
-
-	switch (event) {
-	case MSM_GEMINI_HW_MASK_COMP_FRAMEDONE:
-		msm_gemini_framedone_irq(pgmn_dev, data);
-		msm_gemini_we_pingpong_irq(pgmn_dev, data);
-		break;
-
-	case MSM_GEMINI_HW_MASK_COMP_FE:
-		msm_gemini_fe_pingpong_irq(pgmn_dev, data);
-		break;
-
-	case MSM_GEMINI_HW_MASK_COMP_WE:
-		msm_gemini_we_pingpong_irq(pgmn_dev, data);
-		break;
-
-	case MSM_GEMINI_HW_MASK_COMP_RESET_ACK:
-		msm_gemini_reset_ack_irq(pgmn_dev);
-		break;
-
-	case MSM_GEMINI_HW_MASK_COMP_ERR:
-	default:
-		msm_gemini_err_irq(pgmn_dev, event);
-		break;
-	}
-
-	return 0;
-}
-
-int __msm_gemini_open(struct msm_gemini_device *pgmn_dev)
-{
-	int rc;
-
-	mutex_lock(&pgmn_dev->lock);
-	if (pgmn_dev->open_count) {
-		/* only open once */
-		GMN_PR_ERR("%s:%d] busy\n", __func__, __LINE__);
-		mutex_unlock(&pgmn_dev->lock);
-		return -EBUSY;
-	}
-	pgmn_dev->open_count++;
-	mutex_unlock(&pgmn_dev->lock);
-
-	msm_gemini_core_irq_install(msm_gemini_irq);
-	rc = msm_gemini_platform_init(pgmn_dev->pdev,
-		&pgmn_dev->mem, &pgmn_dev->base,
-		&pgmn_dev->irq, msm_gemini_core_irq, pgmn_dev);
-	if (rc) {
-		GMN_PR_ERR("%s:%d] platform_init fail %d\n", __func__,
-			__LINE__, rc);
-		return rc;
-	}
-
-	GMN_DBG("%s:%d] platform resources - mem %p, base %p, irq %d\n",
-		__func__, __LINE__,
-		pgmn_dev->mem, pgmn_dev->base, pgmn_dev->irq);
-
-	msm_gemini_q_cleanup(&pgmn_dev->evt_q);
-	msm_gemini_q_cleanup(&pgmn_dev->output_rtn_q);
-	msm_gemini_outbuf_q_cleanup(&pgmn_dev->output_buf_q);
-	msm_gemini_q_cleanup(&pgmn_dev->input_rtn_q);
-	msm_gemini_q_cleanup(&pgmn_dev->input_buf_q);
-	msm_gemini_core_init();
-
-	GMN_DBG("%s:%d] success\n", __func__, __LINE__);
-	return rc;
-}
-
-int __msm_gemini_release(struct msm_gemini_device *pgmn_dev)
-{
-	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
-	mutex_lock(&pgmn_dev->lock);
-	if (!pgmn_dev->open_count) {
-		GMN_PR_ERR(KERN_ERR "%s: not opened\n", __func__);
-		mutex_unlock(&pgmn_dev->lock);
-		return -EINVAL;
-	}
-	pgmn_dev->open_count--;
-	mutex_unlock(&pgmn_dev->lock);
-
-	msm_gemini_core_release(release_buf);
-	msm_gemini_q_cleanup(&pgmn_dev->evt_q);
-	msm_gemini_q_cleanup(&pgmn_dev->output_rtn_q);
-	msm_gemini_outbuf_q_cleanup(&pgmn_dev->output_buf_q);
-	msm_gemini_q_cleanup(&pgmn_dev->input_rtn_q);
-	msm_gemini_outbuf_q_cleanup(&pgmn_dev->input_buf_q);
-
-	if (pgmn_dev->open_count)
-		GMN_PR_ERR(KERN_ERR "%s: multiple opens\n", __func__);
-
-	msm_gemini_platform_release(pgmn_dev->mem, pgmn_dev->base,
-		pgmn_dev->irq, pgmn_dev);
-
-	return 0;
-}
-
-int msm_gemini_ioctl_hw_cmd(struct msm_gemini_device *pgmn_dev,
-	void * __user arg)
-{
-	struct msm_gemini_hw_cmd hw_cmd;
-	int is_copy_to_user;
-
-	if (copy_from_user(&hw_cmd, arg, sizeof(struct msm_gemini_hw_cmd))) {
-		GMN_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
-		return -EFAULT;
-	}
-
-	is_copy_to_user = msm_gemini_hw_exec_cmds(&hw_cmd, 1);
-	GMN_DBG("%s:%d] type %d, n %d, offset %d, mask %x, data %x, pdata %x\n",
-		__func__, __LINE__, hw_cmd.type, hw_cmd.n, hw_cmd.offset,
-		hw_cmd.mask, hw_cmd.data, (int) hw_cmd.pdata);
-
-	if (is_copy_to_user >= 0) {
-		if (copy_to_user(arg, &hw_cmd, sizeof(hw_cmd))) {
-			GMN_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
-			return -EFAULT;
-		}
-	}
-
-	return 0;
-}
-
-int msm_gemini_ioctl_hw_cmds(struct msm_gemini_device *pgmn_dev,
-	void * __user arg)
-{
-	int is_copy_to_user;
-	int len;
-	uint32_t m;
-	struct msm_gemini_hw_cmds *hw_cmds_p;
-	struct msm_gemini_hw_cmd *hw_cmd_p;
-
-	if (copy_from_user(&m, arg, sizeof(m))) {
-		GMN_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
-		return -EFAULT;
-	}
-
-	len = sizeof(struct msm_gemini_hw_cmds) +
-		sizeof(struct msm_gemini_hw_cmd) * (m - 1);
-	hw_cmds_p = kmalloc(len, GFP_KERNEL);
-	if (!hw_cmds_p) {
-		GMN_PR_ERR("%s:%d] no mem %d\n", __func__, __LINE__, len);
-		return -EFAULT;
-	}
-
-	if (copy_from_user(hw_cmds_p, arg, len)) {
-		GMN_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
-		kfree(hw_cmds_p);
-		return -EFAULT;
-	}
-
-	hw_cmd_p = (struct msm_gemini_hw_cmd *) &(hw_cmds_p->hw_cmd);
-
-	is_copy_to_user = msm_gemini_hw_exec_cmds(hw_cmd_p, m);
-
-	if (is_copy_to_user >= 0) {
-		if (copy_to_user(arg, hw_cmds_p, len)) {
-			GMN_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
-			kfree(hw_cmds_p);
-			return -EFAULT;
-		}
-	}
-	kfree(hw_cmds_p);
-	return 0;
-}
-
-int msm_gemini_start(struct msm_gemini_device *pgmn_dev, void * __user arg)
-{
-	struct msm_gemini_core_buf *buf_out;
-	struct msm_gemini_core_buf *buf_out_free[2] = {NULL, NULL};
-	int i, rc;
-
-	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
-
-	release_buf = 1;
-	for (i = 0; i < 2; i++) {
-		buf_out = msm_gemini_q_out(&pgmn_dev->input_buf_q);
-
-		if (buf_out) {
-			msm_gemini_core_fe_buf_update(buf_out);
-			kfree(buf_out);
-		} else {
-			GMN_DBG("%s:%d] no input buffer\n", __func__, __LINE__);
-			break;
-		}
-	}
-
-	for (i = 0; i < 2; i++) {
-		buf_out_free[i] = msm_gemini_q_out(&pgmn_dev->output_buf_q);
-
-		if (buf_out_free[i]) {
-			msm_gemini_core_we_buf_update(buf_out_free[i]);
-		} else if (i == 1) {
-			/* set the pong to same address as ping */
-			buf_out_free[0]->y_len >>= 1;
-			buf_out_free[0]->y_buffer_addr +=
-				buf_out_free[0]->y_len;
-			msm_gemini_core_we_buf_update(buf_out_free[0]);
-			/* since ping and pong are same buf release only once*/
-			release_buf = 0;
-		} else {
-			GMN_DBG("%s:%d] no output buffer\n",
-			__func__, __LINE__);
-			break;
-		}
-	}
-
-	for (i = 0; i < 2; i++)
-		kfree(buf_out_free[i]);
-
-	rc = msm_gemini_ioctl_hw_cmds(pgmn_dev, arg);
-	GMN_DBG("%s:%d]\n", __func__, __LINE__);
-	return rc;
-}
-
-int msm_gemini_ioctl_reset(struct msm_gemini_device *pgmn_dev,
-	void * __user arg)
-{
-	int rc;
-	struct msm_gemini_ctrl_cmd ctrl_cmd;
-
-	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
-	if (copy_from_user(&ctrl_cmd, arg, sizeof(ctrl_cmd))) {
-		GMN_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
-		return -EFAULT;
-	}
-
-	pgmn_dev->op_mode = ctrl_cmd.type;
-
-	rc = msm_gemini_core_reset(pgmn_dev->op_mode, pgmn_dev->base,
-		resource_size(pgmn_dev->mem));
-	return rc;
-}
-
-int msm_gemini_ioctl_test_dump_region(struct msm_gemini_device *pgmn_dev,
-	unsigned long arg)
-{
-	GMN_DBG("%s:%d] Enter\n", __func__, __LINE__);
-	msm_gemini_hw_region_dump(arg);
-	return 0;
-}
-
-long __msm_gemini_ioctl(struct msm_gemini_device *pgmn_dev,
-	unsigned int cmd, unsigned long arg)
-{
-	int rc = 0;
-	switch (cmd) {
-	case MSM_GMN_IOCTL_GET_HW_VERSION:
-		GMN_DBG("%s:%d] VERSION 1\n", __func__, __LINE__);
-		rc = msm_gemini_ioctl_hw_cmd(pgmn_dev, (void __user *) arg);
-		break;
-
-	case MSM_GMN_IOCTL_RESET:
-		rc = msm_gemini_ioctl_reset(pgmn_dev, (void __user *) arg);
-		break;
-
-	case MSM_GMN_IOCTL_STOP:
-		rc = msm_gemini_ioctl_hw_cmds(pgmn_dev, (void __user *) arg);
-		break;
-
-	case MSM_GMN_IOCTL_START:
-		rc = msm_gemini_start(pgmn_dev, (void __user *) arg);
-		break;
-
-	case MSM_GMN_IOCTL_INPUT_BUF_ENQUEUE:
-		rc = msm_gemini_input_buf_enqueue(pgmn_dev,
-			(void __user *) arg);
-		break;
-
-	case MSM_GMN_IOCTL_INPUT_GET:
-		rc = msm_gemini_input_get(pgmn_dev, (void __user *) arg);
-		break;
-
-	case MSM_GMN_IOCTL_INPUT_GET_UNBLOCK:
-		rc = msm_gemini_input_get_unblock(pgmn_dev);
-		break;
-
-	case MSM_GMN_IOCTL_OUTPUT_BUF_ENQUEUE:
-		rc = msm_gemini_output_buf_enqueue(pgmn_dev,
-			(void __user *) arg);
-		break;
-
-	case MSM_GMN_IOCTL_OUTPUT_GET:
-		rc = msm_gemini_output_get(pgmn_dev, (void __user *) arg);
-		break;
-
-	case MSM_GMN_IOCTL_OUTPUT_GET_UNBLOCK:
-		rc = msm_gemini_output_get_unblock(pgmn_dev);
-		break;
-
-	case MSM_GMN_IOCTL_EVT_GET:
-		rc = msm_gemini_evt_get(pgmn_dev, (void __user *) arg);
-		break;
-
-	case MSM_GMN_IOCTL_EVT_GET_UNBLOCK:
-		rc = msm_gemini_evt_get_unblock(pgmn_dev);
-		break;
-
-	case MSM_GMN_IOCTL_HW_CMD:
-		rc = msm_gemini_ioctl_hw_cmd(pgmn_dev, (void __user *) arg);
-		break;
-
-	case MSM_GMN_IOCTL_HW_CMDS:
-		rc = msm_gemini_ioctl_hw_cmds(pgmn_dev, (void __user *) arg);
-		break;
-
-	case MSM_GMN_IOCTL_TEST_DUMP_REGION:
-		rc = msm_gemini_ioctl_test_dump_region(pgmn_dev, arg);
-		break;
-
-	default:
-		GMN_PR_ERR(KERN_INFO "%s:%d] cmd = %d not supported\n",
-			__func__, __LINE__, _IOC_NR(cmd));
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
-
-struct msm_gemini_device *__msm_gemini_init(struct platform_device *pdev)
-{
-	struct msm_gemini_device *pgmn_dev;
-
-	pgmn_dev = kzalloc(sizeof(struct msm_gemini_device), GFP_ATOMIC);
-	if (!pgmn_dev) {
-		GMN_PR_ERR("%s:%d]no mem\n", __func__, __LINE__);
-		return NULL;
-	}
-
-	mutex_init(&pgmn_dev->lock);
-
-	pgmn_dev->pdev = pdev;
-
-	msm_gemini_q_init("evt_q", &pgmn_dev->evt_q);
-	msm_gemini_q_init("output_rtn_q", &pgmn_dev->output_rtn_q);
-	msm_gemini_q_init("output_buf_q", &pgmn_dev->output_buf_q);
-	msm_gemini_q_init("input_rtn_q", &pgmn_dev->input_rtn_q);
-	msm_gemini_q_init("input_buf_q", &pgmn_dev->input_buf_q);
-
-	return pgmn_dev;
-}
-
-int __msm_gemini_exit(struct msm_gemini_device *pgmn_dev)
-{
-	mutex_destroy(&pgmn_dev->lock);
-	kfree(pgmn_dev);
-	return 0;
-}
-
diff --git a/drivers/media/video/msm/gemini/msm_gemini_sync.h b/drivers/media/video/msm/gemini/msm_gemini_sync.h
deleted file mode 100644
index 1c6726d..0000000
--- a/drivers/media/video/msm/gemini/msm_gemini_sync.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. 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 MSM_GEMINI_SYNC_H
-#define MSM_GEMINI_SYNC_H
-
-#include <linux/fs.h>
-#include <linux/list.h>
-#include <linux/cdev.h>
-#include <linux/platform_device.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-#include "msm_gemini_core.h"
-
-#define GEMINI_7X 0x1
-#define GEMINI_8X60 (0x1 << 1)
-#define GEMINI_8960 (0x1 << 2)
-
-struct msm_gemini_q {
-	char const	*name;
-	struct list_head  q;
-	spinlock_t	lck;
-	wait_queue_head_t wait;
-	int	       unblck;
-};
-
-struct msm_gemini_q_entry {
-	struct list_head list;
-	void   *data;
-};
-
-struct msm_gemini_device {
-	struct platform_device *pdev;
-	struct resource        *mem;
-	int                     irq;
-	void                   *base;
-	struct clk *gemini_clk[3];
-	struct regulator *gemini_fs;
-	uint32_t hw_version;
-
-	struct device *device;
-	struct cdev   cdev;
-	struct mutex  lock;
-	char	  open_count;
-	uint8_t       op_mode;
-
-	/* event queue including frame done & err indications
-	 */
-	struct msm_gemini_q evt_q;
-
-	/* output return queue
-	 */
-	struct msm_gemini_q output_rtn_q;
-
-	/* output buf queue
-	 */
-	struct msm_gemini_q output_buf_q;
-
-	/* input return queue
-	 */
-	struct msm_gemini_q input_rtn_q;
-
-	/* input buf queue
-	 */
-	struct msm_gemini_q input_buf_q;
-
-	struct v4l2_subdev subdev;
-};
-
-int __msm_gemini_open(struct msm_gemini_device *pgmn_dev);
-int __msm_gemini_release(struct msm_gemini_device *pgmn_dev);
-
-long __msm_gemini_ioctl(struct msm_gemini_device *pgmn_dev,
-	unsigned int cmd, unsigned long arg);
-
-struct msm_gemini_device *__msm_gemini_init(struct platform_device *pdev);
-int __msm_gemini_exit(struct msm_gemini_device *pgmn_dev);
-
-#endif /* MSM_GEMINI_SYNC_H */
diff --git a/drivers/media/video/msm/imx072.c b/drivers/media/video/msm/imx072.c
deleted file mode 100644
index 7e34178..0000000
--- a/drivers/media/video/msm/imx072.c
+++ /dev/null
@@ -1,1184 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. 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/delay.h>
-#include <linux/debugfs.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/slab.h>
-#include <media/msm_camera.h>
-#include <mach/gpio.h>
-#include <mach/camera.h>
-#include "imx072.h"
-
-/* SENSOR REGISTER DEFINES */
-#define REG_GROUPED_PARAMETER_HOLD		0x0104
-#define GROUPED_PARAMETER_HOLD_OFF		0x00
-#define GROUPED_PARAMETER_HOLD			0x01
-/* Integration Time */
-#define REG_COARSE_INTEGRATION_TIME		0x0202
-/* Gain */
-#define REG_GLOBAL_GAIN					0x0204
-
-/* PLL registers */
-#define REG_FRAME_LENGTH_LINES			0x0340
-#define REG_LINE_LENGTH_PCK				0x0342
-
-/* 16bit address - 8 bit context register structure */
-#define Q8  0x00000100
-#define Q10 0x00000400
-#define IMX072_MASTER_CLK_RATE 24000000
-#define IMX072_OFFSET		3
-
-/* AF Total steps parameters */
-#define IMX072_AF_I2C_ADDR	0x18
-#define IMX072_TOTAL_STEPS_NEAR_TO_FAR    30
-
-static uint16_t imx072_step_position_table[IMX072_TOTAL_STEPS_NEAR_TO_FAR+1];
-static uint16_t imx072_nl_region_boundary1;
-static uint16_t imx072_nl_region_code_per_step1;
-static uint16_t imx072_l_region_code_per_step = 12;
-static uint16_t imx072_sw_damping_time_wait = 8;
-static uint16_t imx072_af_initial_code = 350;
-static uint16_t imx072_damping_threshold = 10;
-
-struct imx072_work_t {
-	struct work_struct work;
-};
-
-static struct imx072_work_t *imx072_sensorw;
-static struct i2c_client *imx072_client;
-
-struct imx072_ctrl_t {
-	const struct  msm_camera_sensor_info *sensordata;
-
-	uint32_t sensormode;
-	uint32_t fps_divider;/* init to 1 * 0x00000400 */
-	uint32_t pict_fps_divider;/* init to 1 * 0x00000400 */
-	uint16_t fps;
-
-	uint16_t curr_lens_pos;
-	uint16_t curr_step_pos;
-	uint16_t my_reg_gain;
-	uint32_t my_reg_line_count;
-	uint16_t total_lines_per_frame;
-
-	enum imx072_resolution_t prev_res;
-	enum imx072_resolution_t pict_res;
-	enum imx072_resolution_t curr_res;
-	enum imx072_test_mode_t  set_test;
-	enum imx072_cam_mode_t cam_mode;
-};
-
-static uint16_t prev_line_length_pck;
-static uint16_t prev_frame_length_lines;
-static uint16_t snap_line_length_pck;
-static uint16_t snap_frame_length_lines;
-
-static bool CSI_CONFIG;
-static struct imx072_ctrl_t *imx072_ctrl;
-static DECLARE_WAIT_QUEUE_HEAD(imx072_wait_queue);
-DEFINE_MUTEX(imx072_mut);
-
-#ifdef CONFIG_DEBUG_FS
-static int cam_debug_init(void);
-static struct dentry *debugfs_base;
-#endif
-
-static int imx072_i2c_rxdata(unsigned short saddr,
-	unsigned char *rxdata, int length)
-{
-	struct i2c_msg msgs[] = {
-		{
-			.addr  = saddr,
-			.flags = 0,
-			.len   = length,
-			.buf   = rxdata,
-		},
-		{
-			.addr  = saddr,
-			.flags = I2C_M_RD,
-			.len   = length,
-			.buf   = rxdata,
-		},
-	};
-	if (i2c_transfer(imx072_client->adapter, msgs, 2) < 0) {
-		pr_err("imx072_i2c_rxdata faild 0x%x\n", saddr);
-		return -EIO;
-	}
-	return 0;
-}
-
-static int32_t imx072_i2c_txdata(unsigned short saddr,
-				unsigned char *txdata, int length)
-{
-	struct i2c_msg msg[] = {
-		{
-			.addr = saddr,
-			.flags = 0,
-			.len = length,
-			.buf = txdata,
-		 },
-	};
-	if (i2c_transfer(imx072_client->adapter, msg, 1) < 0) {
-		pr_err("imx072_i2c_txdata faild 0x%x\n", saddr);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int32_t imx072_i2c_read(unsigned short raddr,
-	unsigned short *rdata, int rlen)
-{
-	int32_t rc = 0;
-	unsigned char buf[2];
-	if (!rdata)
-		return -EIO;
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (raddr & 0xFF00) >> 8;
-	buf[1] = (raddr & 0x00FF);
-	rc = imx072_i2c_rxdata(imx072_client->addr>>1, buf, rlen);
-	if (rc < 0) {
-		pr_err("imx072_i2c_read 0x%x failed!\n", raddr);
-		return rc;
-	}
-	*rdata = (rlen == 2 ? buf[0] << 8 | buf[1] : buf[0]);
-	CDBG("imx072_i2c_read 0x%x val = 0x%x!\n", raddr, *rdata);
-	return rc;
-}
-
-static int32_t imx072_i2c_write_w_sensor(unsigned short waddr,
-	uint16_t wdata)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[4];
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (waddr & 0xFF00) >> 8;
-	buf[1] = (waddr & 0x00FF);
-	buf[2] = (wdata & 0xFF00) >> 8;
-	buf[3] = (wdata & 0x00FF);
-	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, wdata);
-	rc = imx072_i2c_txdata(imx072_client->addr>>1, buf, 4);
-	if (rc < 0) {
-		pr_err("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
-			waddr, wdata);
-	}
-	return rc;
-}
-
-static int32_t imx072_i2c_write_b_sensor(unsigned short waddr,
-	uint8_t bdata)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[3];
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (waddr & 0xFF00) >> 8;
-	buf[1] = (waddr & 0x00FF);
-	buf[2] = bdata;
-	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
-	rc = imx072_i2c_txdata(imx072_client->addr>>1, buf, 3);
-	if (rc < 0)
-		pr_err("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
-			waddr, bdata);
-	return rc;
-}
-
-static int32_t imx072_i2c_write_b_af(uint8_t msb, uint8_t lsb)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[2];
-
-	buf[0] = msb;
-	buf[1] = lsb;
-	rc = imx072_i2c_txdata(IMX072_AF_I2C_ADDR>>1, buf, 2);
-	if (rc < 0)
-		pr_err("af_i2c_write faield msb = 0x%x lsb = 0x%x",
-			msb, lsb);
-	return rc;
-}
-
-static int32_t imx072_i2c_write_w_table(struct imx072_i2c_reg_conf const
-					 *reg_conf_tbl, int num)
-{
-	int i;
-	int32_t rc = -EIO;
-	for (i = 0; i < num; i++) {
-		rc = imx072_i2c_write_b_sensor(reg_conf_tbl->waddr,
-			reg_conf_tbl->wdata);
-		if (rc < 0)
-			break;
-		reg_conf_tbl++;
-	}
-	return rc;
-}
-
-static void imx072_group_hold_on(void)
-{
-	imx072_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
-						GROUPED_PARAMETER_HOLD);
-}
-
-static void imx072_group_hold_off(void)
-{
-	imx072_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
-						GROUPED_PARAMETER_HOLD_OFF);
-}
-
-static void imx072_start_stream(void)
-{
-	imx072_i2c_write_b_sensor(0x0100, 0x01);
-}
-
-static void imx072_stop_stream(void)
-{
-	imx072_i2c_write_b_sensor(0x0100, 0x00);
-}
-
-static void imx072_get_pict_fps(uint16_t fps, uint16_t *pfps)
-{
-	/* input fps is preview fps in Q8 format */
-	uint32_t divider, d1, d2;
-
-	d1 = prev_frame_length_lines * 0x00000400 / snap_frame_length_lines;
-	d2 = prev_line_length_pck * 0x00000400 / snap_line_length_pck;
-	divider = d1 * d2 / 0x400;
-
-	/*Verify PCLK settings and frame sizes.*/
-	*pfps = (uint16_t) (fps * divider / 0x400);
-}
-
-static uint16_t imx072_get_prev_lines_pf(void)
-{
-	return prev_frame_length_lines;
-}
-
-static uint16_t imx072_get_prev_pixels_pl(void)
-{
-	return prev_line_length_pck;
-}
-
-static uint16_t imx072_get_pict_lines_pf(void)
-{
-	return snap_frame_length_lines;
-}
-
-static uint16_t imx072_get_pict_pixels_pl(void)
-{
-	return snap_line_length_pck;
-}
-
-static uint32_t imx072_get_pict_max_exp_lc(void)
-{
-	return snap_frame_length_lines  * 24;
-}
-
-static int32_t imx072_set_fps(struct fps_cfg   *fps)
-{
-	uint16_t total_lines_per_frame;
-	int32_t rc = 0;
-	total_lines_per_frame = (uint16_t)
-		((prev_frame_length_lines *
-		imx072_ctrl->fps_divider)/0x400);
-	imx072_ctrl->fps_divider = fps->fps_div;
-	imx072_ctrl->pict_fps_divider = fps->pict_fps_div;
-
-	imx072_group_hold_on();
-	rc = imx072_i2c_write_w_sensor(REG_FRAME_LENGTH_LINES,
-							total_lines_per_frame);
-	imx072_group_hold_off();
-	return rc;
-}
-
-static int32_t imx072_write_exp_gain(uint16_t gain, uint32_t line)
-{
-	uint32_t fl_lines = 0;
-	uint8_t offset;
-	int32_t rc = 0;
-	if (imx072_ctrl->curr_res == imx072_ctrl->prev_res)
-		fl_lines = prev_frame_length_lines;
-	else if (imx072_ctrl->curr_res == imx072_ctrl->pict_res)
-		fl_lines = snap_frame_length_lines;
-	line = (line * imx072_ctrl->fps_divider) / Q10;
-	offset = IMX072_OFFSET;
-	if (line > (fl_lines - offset))
-		fl_lines = line + offset;
-
-	imx072_group_hold_on();
-	rc = imx072_i2c_write_w_sensor(REG_FRAME_LENGTH_LINES, fl_lines);
-	rc = imx072_i2c_write_w_sensor(REG_COARSE_INTEGRATION_TIME, line);
-	rc = imx072_i2c_write_w_sensor(REG_GLOBAL_GAIN, gain);
-	imx072_group_hold_off();
-	return rc;
-}
-
-static int32_t imx072_set_pict_exp_gain(uint16_t gain, uint32_t line)
-{
-	int32_t rc = 0;
-	rc = imx072_write_exp_gain(gain, line);
-	return rc;
-}
-
-static int32_t imx072_sensor_setting(int update_type, int rt)
-{
-
-	int32_t rc = 0;
-	struct msm_camera_csi_params imx072_csi_params;
-
-	imx072_stop_stream();
-	msleep(30);
-	if (update_type == REG_INIT) {
-		msleep(20);
-		CSI_CONFIG = 0;
-		imx072_i2c_write_w_table(imx072_regs.rec_settings,
-			imx072_regs.rec_size);
-	} else if (update_type == UPDATE_PERIODIC) {
-#ifdef CONFIG_DEBUG_FS
-		cam_debug_init();
-#endif
-		msleep(20);
-		if (!CSI_CONFIG) {
-			imx072_csi_params.lane_cnt = 2;
-			imx072_csi_params.data_format = CSI_10BIT;
-			imx072_csi_params.lane_assign = 0xe4;
-			imx072_csi_params.dpcm_scheme = 0;
-			imx072_csi_params.settle_cnt = 0x18;
-			msm_camio_vfe_clk_rate_set(192000000);
-			rc = msm_camio_csi_config(&imx072_csi_params);
-			msleep(100);
-			CSI_CONFIG = 1;
-		}
-		imx072_i2c_write_w_table(
-			imx072_regs.conf_array[rt].conf,
-			imx072_regs.conf_array[rt].size);
-		imx072_start_stream();
-		msleep(30);
-	}
-	return rc;
-}
-
-static int32_t imx072_video_config(int mode)
-{
-
-	int32_t rc = 0;
-	/* change sensor resolution if needed */
-	if (imx072_sensor_setting(UPDATE_PERIODIC,
-		imx072_ctrl->prev_res) < 0)
-		return rc;
-
-	imx072_ctrl->curr_res = imx072_ctrl->prev_res;
-	imx072_ctrl->sensormode = mode;
-	return rc;
-}
-
-static int32_t imx072_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-	/*change sensor resolution if needed */
-	if (imx072_ctrl->curr_res != imx072_ctrl->pict_res) {
-		if (imx072_sensor_setting(UPDATE_PERIODIC,
-					imx072_ctrl->pict_res) < 0)
-			return rc;
-	}
-
-	imx072_ctrl->curr_res = imx072_ctrl->pict_res;
-	imx072_ctrl->sensormode = mode;
-	return rc;
-}
-
-static int32_t imx072_raw_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-	/* change sensor resolution if needed */
-	if (imx072_ctrl->curr_res != imx072_ctrl->pict_res) {
-		if (imx072_sensor_setting(UPDATE_PERIODIC,
-					imx072_ctrl->pict_res) < 0)
-			return rc;
-	}
-
-	imx072_ctrl->curr_res = imx072_ctrl->pict_res;
-	imx072_ctrl->sensormode = mode;
-	return rc;
-}
-
-static int32_t imx072_mode_init(int mode, struct sensor_init_cfg init_info)
-{
-	int32_t rc = 0;
-	CDBG("%s: %d\n", __func__, __LINE__);
-	if (mode != imx072_ctrl->cam_mode) {
-		imx072_ctrl->prev_res = init_info.prev_res;
-		imx072_ctrl->pict_res = init_info.pict_res;
-		imx072_ctrl->cam_mode = mode;
-
-		prev_frame_length_lines =
-			imx072_regs.conf_array[imx072_ctrl->prev_res].
-			conf[IMX072_FRAME_LENGTH_LINES_HI].wdata << 8 |
-			imx072_regs.conf_array[imx072_ctrl->prev_res].
-			conf[IMX072_FRAME_LENGTH_LINES_LO].wdata;
-		prev_line_length_pck =
-			imx072_regs.conf_array[imx072_ctrl->prev_res].
-			conf[IMX072_LINE_LENGTH_PCK_HI].wdata << 8 |
-			imx072_regs.conf_array[imx072_ctrl->prev_res].
-			conf[IMX072_LINE_LENGTH_PCK_LO].wdata;
-		snap_frame_length_lines =
-			imx072_regs.conf_array[imx072_ctrl->pict_res].
-			conf[IMX072_FRAME_LENGTH_LINES_HI].wdata << 8 |
-			imx072_regs.conf_array[imx072_ctrl->pict_res].
-			conf[IMX072_FRAME_LENGTH_LINES_LO].wdata;
-		snap_line_length_pck =
-			imx072_regs.conf_array[imx072_ctrl->pict_res].
-			conf[IMX072_LINE_LENGTH_PCK_HI].wdata << 8 |
-			imx072_regs.conf_array[imx072_ctrl->pict_res].
-			conf[IMX072_LINE_LENGTH_PCK_LO].wdata;
-
-		rc = imx072_sensor_setting(REG_INIT,
-			imx072_ctrl->prev_res);
-	}
-	return rc;
-}
-
-static int32_t imx072_set_sensor_mode(int mode,
-	int res)
-{
-	int32_t rc = 0;
-
-	switch (mode) {
-	case SENSOR_PREVIEW_MODE:
-		imx072_ctrl->prev_res = res;
-		rc = imx072_video_config(mode);
-		break;
-	case SENSOR_SNAPSHOT_MODE:
-		imx072_ctrl->pict_res = res;
-		rc = imx072_snapshot_config(mode);
-		break;
-	case SENSOR_RAW_SNAPSHOT_MODE:
-		imx072_ctrl->pict_res = res;
-		rc = imx072_raw_snapshot_config(mode);
-		break;
-	default:
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
-
-#define DIV_CEIL(x, y) ((x/y + ((x%y) ? 1 : 0)))
-static int32_t imx072_move_focus(int direction,
-	int32_t num_steps)
-{
-	int32_t rc = 0;
-	int16_t step_direction, dest_lens_position, dest_step_position;
-	uint8_t code_val_msb, code_val_lsb;
-	int16_t next_lens_position, target_dist, small_step;
-
-	if (direction == MOVE_NEAR)
-		step_direction = 1;
-	else if (direction == MOVE_FAR)
-		step_direction = -1;
-	else {
-		pr_err("Illegal focus direction\n");
-		return -EINVAL;
-	}
-	dest_step_position = imx072_ctrl->curr_step_pos +
-			(step_direction * num_steps);
-
-	if (dest_step_position < 0)
-		dest_step_position = 0;
-	else if (dest_step_position > IMX072_TOTAL_STEPS_NEAR_TO_FAR)
-		dest_step_position = IMX072_TOTAL_STEPS_NEAR_TO_FAR;
-
-	if (dest_step_position == imx072_ctrl->curr_step_pos) {
-		CDBG("imx072 same position No-Move exit\n");
-		return rc;
-	}
-	CDBG("%s Index = [%d]\n", __func__, dest_step_position);
-
-	dest_lens_position = imx072_step_position_table[dest_step_position];
-	CDBG("%s lens_position value = %d\n", __func__, dest_lens_position);
-	target_dist = step_direction * (dest_lens_position -
-		imx072_ctrl->curr_lens_pos);
-	if (step_direction < 0 && (target_dist >=
-		(imx072_step_position_table[imx072_damping_threshold]
-			- imx072_af_initial_code))) {
-		small_step = DIV_CEIL(target_dist, 10);
-		imx072_sw_damping_time_wait = 30;
-	} else {
-		small_step = DIV_CEIL(target_dist, 4);
-		imx072_sw_damping_time_wait = 20;
-	}
-
-	CDBG("%s: small_step:%d, wait_time:%d\n", __func__, small_step,
-		imx072_sw_damping_time_wait);
-	for (next_lens_position = imx072_ctrl->curr_lens_pos +
-		(step_direction * small_step);
-		(step_direction * next_lens_position) <=
-		(step_direction * dest_lens_position);
-		next_lens_position += (step_direction * small_step)) {
-
-		code_val_msb = ((next_lens_position & 0x03F0) >> 4);
-		code_val_lsb = ((next_lens_position & 0x000F) << 4);
-		CDBG("position value = %d\n", next_lens_position);
-		CDBG("movefocus vcm_msb = %d\n", code_val_msb);
-		CDBG("movefocus vcm_lsb = %d\n", code_val_lsb);
-		rc = imx072_i2c_write_b_af(code_val_msb, code_val_lsb);
-		if (rc < 0) {
-			pr_err("imx072_move_focus failed writing i2c\n");
-			return rc;
-			}
-		imx072_ctrl->curr_lens_pos = next_lens_position;
-		usleep(imx072_sw_damping_time_wait*100);
-	}
-	if (imx072_ctrl->curr_lens_pos != dest_lens_position) {
-		code_val_msb = ((dest_lens_position & 0x03F0) >> 4);
-		code_val_lsb = ((dest_lens_position & 0x000F) << 4);
-		CDBG("position value = %d\n", dest_lens_position);
-		CDBG("movefocus vcm_msb = %d\n", code_val_msb);
-		CDBG("movefocus vcm_lsb = %d\n", code_val_lsb);
-		rc = imx072_i2c_write_b_af(code_val_msb, code_val_lsb);
-		if (rc < 0) {
-			pr_err("imx072_move_focus failed writing i2c\n");
-			return rc;
-			}
-		usleep(imx072_sw_damping_time_wait * 100);
-	}
-	imx072_ctrl->curr_lens_pos = dest_lens_position;
-	imx072_ctrl->curr_step_pos = dest_step_position;
-	return rc;
-
-}
-
-static int32_t imx072_init_focus(void)
-{
-	uint8_t i;
-	int32_t rc = 0;
-
-	imx072_step_position_table[0] = imx072_af_initial_code;
-	for (i = 1; i <= IMX072_TOTAL_STEPS_NEAR_TO_FAR; i++) {
-		if (i <= imx072_nl_region_boundary1)
-			imx072_step_position_table[i] =
-				imx072_step_position_table[i-1]
-				+ imx072_nl_region_code_per_step1;
-		else
-			imx072_step_position_table[i] =
-				imx072_step_position_table[i-1]
-				+ imx072_l_region_code_per_step;
-
-		if (imx072_step_position_table[i] > 1023)
-			imx072_step_position_table[i] = 1023;
-	}
-	imx072_ctrl->curr_lens_pos = 0;
-
-	return rc;
-}
-
-static int32_t imx072_set_default_focus(void)
-{
-	int32_t rc = 0;
-	uint8_t code_val_msb, code_val_lsb;
-	int16_t dest_lens_position = 0;
-
-	CDBG("%s Index = [%d]\n", __func__, 0);
-	if (imx072_ctrl->curr_step_pos != 0)
-		rc = imx072_move_focus(MOVE_FAR,
-		imx072_ctrl->curr_step_pos);
-	else {
-		dest_lens_position = imx072_af_initial_code;
-		code_val_msb = ((dest_lens_position & 0x03F0) >> 4);
-		code_val_lsb = ((dest_lens_position & 0x000F) << 4);
-
-		CDBG("position value = %d\n", dest_lens_position);
-		CDBG("movefocus vcm_msb = %d\n", code_val_msb);
-		CDBG("movefocus vcm_lsb = %d\n", code_val_lsb);
-		rc = imx072_i2c_write_b_af(code_val_msb, code_val_lsb);
-		if (rc < 0) {
-			pr_err("imx072_set_default_focus failed writing i2c\n");
-			return rc;
-		}
-
-		imx072_ctrl->curr_lens_pos = dest_lens_position;
-		imx072_ctrl->curr_step_pos = 0;
-
-	}
-	usleep(5000);
-	return rc;
-}
-
-static int32_t imx072_af_power_down(void)
-{
-	int32_t rc = 0;
-	int32_t i = 0;
-	int16_t dest_lens_position = imx072_af_initial_code;
-
-	if (imx072_ctrl->curr_lens_pos != 0) {
-		rc = imx072_set_default_focus();
-		CDBG("%s after imx072_set_default_focus\n", __func__);
-		msleep(40);
-		/*to avoid the sound during the power off.
-		brings the actuator to mechanical infinity gradually.*/
-		for (i = 0; i < IMX072_TOTAL_STEPS_NEAR_TO_FAR; i++) {
-			dest_lens_position = dest_lens_position -
-				(imx072_af_initial_code /
-					IMX072_TOTAL_STEPS_NEAR_TO_FAR);
-			CDBG("position value = %d\n", dest_lens_position);
-			rc = imx072_i2c_write_b_af(
-				((dest_lens_position & 0x03F0) >> 4),
-				((dest_lens_position & 0x000F) << 4));
-			CDBG("count = %d\n", i);
-			msleep(20);
-			if (rc < 0) {
-				pr_err("imx072_set_default_focus failed writing i2c\n");
-				return rc;
-			}
-		}
-		rc = imx072_i2c_write_b_af(0x00, 00);
-		msleep(40);
-	}
-	rc = imx072_i2c_write_b_af(0x80, 00);
-	return rc;
-}
-
-static int32_t imx072_power_down(void)
-{
-	int32_t rc = 0;
-
-	rc = imx072_af_power_down();
-	return rc;
-}
-
-static int imx072_probe_init_done(const struct msm_camera_sensor_info *data)
-{
-	pr_err("probe done\n");
-	gpio_free(data->sensor_reset);
-	return 0;
-}
-
-static int imx072_probe_init_sensor(
-	const struct msm_camera_sensor_info *data)
-{
-	int32_t rc = 0;
-	uint16_t chipid = 0;
-
-	CDBG("%s: %d\n", __func__, __LINE__);
-	rc = gpio_request(data->sensor_reset, "imx072");
-	CDBG(" imx072_probe_init_sensor\n");
-	if (!rc) {
-		pr_err("sensor_reset = %d\n", rc);
-		gpio_direction_output(data->sensor_reset, 0);
-		msleep(50);
-		gpio_set_value_cansleep(data->sensor_reset, 1);
-		msleep(20);
-	} else
-		goto gpio_req_fail;
-
-	CDBG(" imx072_probe_init_sensor is called\n");
-	rc = imx072_i2c_read(0x0, &chipid, 2);
-	CDBG("ID: %d\n", chipid);
-	/* 4. Compare sensor ID to IMX072 ID: */
-	if (chipid != 0x0045) {
-		rc = -ENODEV;
-		pr_err("imx072_probe_init_sensor chip id doesnot match\n");
-		goto init_probe_fail;
-	}
-
-	return rc;
-init_probe_fail:
-	pr_err(" imx072_probe_init_sensor fails\n");
-	gpio_set_value_cansleep(data->sensor_reset, 0);
-	imx072_probe_init_done(data);
-	if (data->vcm_enable) {
-		int ret = gpio_request(data->vcm_pwd, "imx072_af");
-		if (!ret) {
-			gpio_direction_output(data->vcm_pwd, 0);
-			msleep(20);
-			gpio_free(data->vcm_pwd);
-		}
-	}
-gpio_req_fail:
-	return rc;
-}
-
-int imx072_sensor_open_init(const struct msm_camera_sensor_info *data)
-{
-	int32_t rc = 0;
-
-	CDBG("%s: %d\n", __func__, __LINE__);
-	imx072_ctrl = kzalloc(sizeof(struct imx072_ctrl_t), GFP_KERNEL);
-	if (!imx072_ctrl) {
-		pr_err("imx072_init failed!\n");
-		rc = -ENOMEM;
-		goto init_done;
-	}
-	imx072_ctrl->fps_divider = 1 * 0x00000400;
-	imx072_ctrl->pict_fps_divider = 1 * 0x00000400;
-	imx072_ctrl->set_test = TEST_OFF;
-	imx072_ctrl->cam_mode = MODE_INVALID;
-
-	if (data)
-		imx072_ctrl->sensordata = data;
-	if (rc < 0) {
-		pr_err("Calling imx072_sensor_open_init fail1\n");
-		return rc;
-	}
-	CDBG("%s: %d\n", __func__, __LINE__);
-	/* enable mclk first */
-	msm_camio_clk_rate_set(IMX072_MASTER_CLK_RATE);
-	rc = imx072_probe_init_sensor(data);
-	if (rc < 0)
-		goto init_fail;
-
-	imx072_init_focus();
-	imx072_ctrl->fps = 30*Q8;
-	if (rc < 0) {
-		gpio_set_value_cansleep(data->sensor_reset, 0);
-		goto init_fail;
-	} else
-		goto init_done;
-init_fail:
-	pr_err("init_fail\n");
-	imx072_probe_init_done(data);
-init_done:
-	pr_err("init_done\n");
-	return rc;
-}
-
-static int imx072_init_client(struct i2c_client *client)
-{
-	/* Initialize the MSM_CAMI2C Chip */
-	init_waitqueue_head(&imx072_wait_queue);
-	return 0;
-}
-
-static const struct i2c_device_id imx072_i2c_id[] = {
-	{"imx072", 0},
-	{ }
-};
-
-static int imx072_i2c_probe(struct i2c_client *client,
-	const struct i2c_device_id *id)
-{
-	int rc = 0;
-	CDBG("imx072_probe called!\n");
-
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		pr_err("i2c_check_functionality failed\n");
-		goto probe_failure;
-	}
-
-	imx072_sensorw = kzalloc(sizeof(struct imx072_work_t),
-			GFP_KERNEL);
-	if (!imx072_sensorw) {
-		pr_err("kzalloc failed.\n");
-		rc = -ENOMEM;
-		goto probe_failure;
-	}
-
-	i2c_set_clientdata(client, imx072_sensorw);
-	imx072_init_client(client);
-	imx072_client = client;
-
-	msleep(50);
-
-	CDBG("imx072_probe successed! rc = %d\n", rc);
-	return 0;
-
-probe_failure:
-	pr_err("imx072_probe failed! rc = %d\n", rc);
-	return rc;
-}
-
-static int imx072_send_wb_info(struct wb_info_cfg *wb)
-{
-	return 0;
-
-}
-
-static int __exit imx072_remove(struct i2c_client *client)
-{
-	struct imx072_work_t_t *sensorw = i2c_get_clientdata(client);
-	free_irq(client->irq, sensorw);
-	imx072_client = NULL;
-	kfree(sensorw);
-	return 0;
-}
-
-static struct i2c_driver imx072_i2c_driver = {
-	.id_table = imx072_i2c_id,
-	.probe  = imx072_i2c_probe,
-	.remove = __exit_p(imx072_i2c_remove),
-	.driver = {
-		.name = "imx072",
-	},
-};
-
-int imx072_sensor_config(void __user *argp)
-{
-	struct sensor_cfg_data cdata;
-	long   rc = 0;
-	if (copy_from_user(&cdata,
-		(void *)argp,
-		sizeof(struct sensor_cfg_data)))
-		return -EFAULT;
-	mutex_lock(&imx072_mut);
-	CDBG("imx072_sensor_config: cfgtype = %d\n",
-		 cdata.cfgtype);
-	switch (cdata.cfgtype) {
-	case CFG_GET_PICT_FPS:
-		imx072_get_pict_fps(
-			cdata.cfg.gfps.prevfps,
-			&(cdata.cfg.gfps.pictfps));
-
-		if (copy_to_user((void *)argp,
-			&cdata,
-			sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-	case CFG_GET_PREV_L_PF:
-		cdata.cfg.prevl_pf =
-		imx072_get_prev_lines_pf();
-
-		if (copy_to_user((void *)argp,
-			&cdata,
-			sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-	case CFG_GET_PREV_P_PL:
-		cdata.cfg.prevp_pl =
-			imx072_get_prev_pixels_pl();
-
-		if (copy_to_user((void *)argp,
-			&cdata,
-			sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-	case CFG_GET_PICT_L_PF:
-		cdata.cfg.pictl_pf =
-			imx072_get_pict_lines_pf();
-
-		if (copy_to_user((void *)argp,
-			&cdata,
-			sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-	case CFG_GET_PICT_P_PL:
-		cdata.cfg.pictp_pl =
-			imx072_get_pict_pixels_pl();
-
-		if (copy_to_user((void *)argp,
-			&cdata,
-			sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-	case CFG_GET_PICT_MAX_EXP_LC:
-		cdata.cfg.pict_max_exp_lc =
-			imx072_get_pict_max_exp_lc();
-
-		if (copy_to_user((void *)argp,
-			&cdata,
-			sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-	case CFG_SET_FPS:
-	case CFG_SET_PICT_FPS:
-		rc = imx072_set_fps(&(cdata.cfg.fps));
-		break;
-	case CFG_SET_EXP_GAIN:
-		rc = imx072_write_exp_gain(
-			cdata.cfg.exp_gain.gain,
-			cdata.cfg.exp_gain.line);
-		break;
-	case CFG_SET_PICT_EXP_GAIN:
-		rc = imx072_set_pict_exp_gain(
-			cdata.cfg.exp_gain.gain,
-			cdata.cfg.exp_gain.line);
-		break;
-	case CFG_SET_MODE:
-		rc = imx072_set_sensor_mode(cdata.mode, cdata.rs);
-		break;
-	case CFG_PWR_DOWN:
-		rc = imx072_power_down();
-		break;
-	case CFG_MOVE_FOCUS:
-		rc = imx072_move_focus(cdata.cfg.focus.dir,
-				cdata.cfg.focus.steps);
-		break;
-	case CFG_SET_DEFAULT_FOCUS:
-		imx072_set_default_focus();
-		break;
-	case CFG_GET_AF_MAX_STEPS:
-		cdata.max_steps = IMX072_TOTAL_STEPS_NEAR_TO_FAR;
-		if (copy_to_user((void *)argp,
-			&cdata,
-			sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-	case CFG_SET_EFFECT:
-		break;
-	case CFG_SEND_WB_INFO:
-		rc = imx072_send_wb_info(
-			&(cdata.cfg.wb_info));
-	break;
-	case CFG_SENSOR_INIT:
-		rc = imx072_mode_init(cdata.mode,
-				cdata.cfg.init_info);
-	break;
-	case CFG_SET_LENS_SHADING:
-		break;
-	default:
-		rc = -EFAULT;
-		break;
-	}
-
-	mutex_unlock(&imx072_mut);
-
-	return rc;
-}
-
-static int imx072_sensor_release(void)
-{
-	int rc = -EBADF;
-	mutex_lock(&imx072_mut);
-	imx072_power_down();
-	gpio_set_value_cansleep(imx072_ctrl->sensordata->sensor_reset, 0);
-	msleep(20);
-	gpio_free(imx072_ctrl->sensordata->sensor_reset);
-	if (imx072_ctrl->sensordata->vcm_enable) {
-		gpio_set_value_cansleep(imx072_ctrl->sensordata->vcm_pwd, 0);
-		gpio_free(imx072_ctrl->sensordata->vcm_pwd);
-	}
-	kfree(imx072_ctrl);
-	imx072_ctrl = NULL;
-	pr_err("imx072_release completed\n");
-	mutex_unlock(&imx072_mut);
-
-	return rc;
-}
-
-static int imx072_sensor_probe(const struct msm_camera_sensor_info *info,
-		struct msm_sensor_ctrl *s)
-{
-	int rc = 0;
-	rc = i2c_add_driver(&imx072_i2c_driver);
-	if (rc < 0 || imx072_client == NULL) {
-		rc = -ENOTSUPP;
-		pr_err("I2C add driver failed");
-		goto probe_fail;
-	}
-	msm_camio_clk_rate_set(IMX072_MASTER_CLK_RATE);
-	rc = imx072_probe_init_sensor(info);
-	if (rc < 0)
-		goto probe_fail;
-	s->s_init = imx072_sensor_open_init;
-	s->s_release = imx072_sensor_release;
-	s->s_config  = imx072_sensor_config;
-	s->s_mount_angle = info->sensor_platform_info->mount_angle;
-
-	gpio_set_value_cansleep(info->sensor_reset, 0);
-	imx072_probe_init_done(info);
-	if (info->vcm_enable) {
-		rc = gpio_request(info->vcm_pwd, "imx072_af");
-		if (!rc) {
-			gpio_direction_output(info->vcm_pwd, 0);
-			msleep(20);
-			gpio_free(info->vcm_pwd);
-		} else
-			return rc;
-	}
-	pr_info("imx072_sensor_probe : SUCCESS\n");
-	return rc;
-
-probe_fail:
-	pr_err("imx072_sensor_probe: SENSOR PROBE FAILS!\n");
-	return rc;
-}
-
-static int __imx072_probe(struct platform_device *pdev)
-{
-	return msm_camera_drv_start(pdev, imx072_sensor_probe);
-}
-
-static struct platform_driver msm_camera_driver = {
-	.probe = __imx072_probe,
-	.driver = {
-		.name = "msm_camera_imx072",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init imx072_init(void)
-{
-	return platform_driver_register(&msm_camera_driver);
-}
-
-module_init(imx072_init);
-void imx072_exit(void)
-{
-	i2c_del_driver(&imx072_i2c_driver);
-}
-MODULE_DESCRIPTION("Aptina 8 MP Bayer sensor driver");
-MODULE_LICENSE("GPL v2");
-
-#ifdef CONFIG_DEBUG_FS
-static bool streaming = 1;
-
-static int cam_debug_stream_set(void *data, u64 val)
-{
-	int rc = 0;
-
-	if (val) {
-		imx072_start_stream();
-		streaming = 1;
-	} else {
-		imx072_stop_stream();
-		streaming = 0;
-	}
-
-	return rc;
-}
-
-static int cam_debug_stream_get(void *data, u64 *val)
-{
-	*val = streaming;
-	return 0;
-}
-DEFINE_SIMPLE_ATTRIBUTE(cam_stream, cam_debug_stream_get,
-			cam_debug_stream_set, "%llu\n");
-
-
-
-static int imx072_set_af_codestep(void *data, u64 val)
-{
-	imx072_l_region_code_per_step = val;
-	imx072_init_focus();
-	return 0;
-}
-
-static int imx072_get_af_codestep(void *data, u64 *val)
-{
-	*val = imx072_l_region_code_per_step;
-	return 0;
-}
-
-static uint16_t imx072_linear_total_step = IMX072_TOTAL_STEPS_NEAR_TO_FAR;
-static int imx072_set_linear_total_step(void *data, u64 val)
-{
-	imx072_linear_total_step = val;
-	return 0;
-}
-
-static int imx072_af_linearity_test(void *data, u64 *val)
-{
-	int i = 0;
-
-	imx072_set_default_focus();
-	msleep(3000);
-	for (i = 0; i < imx072_linear_total_step; i++) {
-		imx072_move_focus(MOVE_NEAR, 1);
-		CDBG("moved to index =[%d]\n", i);
-		msleep(1000);
-	}
-
-	for (i = 0; i < imx072_linear_total_step; i++) {
-		imx072_move_focus(MOVE_FAR, 1);
-		CDBG("moved to index =[%d]\n", i);
-		msleep(1000);
-	}
-	return 0;
-}
-
-static uint16_t imx072_step_val = IMX072_TOTAL_STEPS_NEAR_TO_FAR;
-static uint8_t imx072_step_dir = MOVE_NEAR;
-static int imx072_af_step_config(void *data, u64 val)
-{
-	imx072_step_val = val & 0xFFFF;
-	imx072_step_dir = (val >> 16) & 0x1;
-	return 0;
-}
-
-static int imx072_af_step(void *data, u64 *val)
-{
-	int i = 0;
-	int dir = MOVE_NEAR;
-	imx072_set_default_focus();
-	msleep(3000);
-	if (imx072_step_dir == 1)
-		dir = MOVE_FAR;
-
-	for (i = 0; i < imx072_step_val; i += 4) {
-		imx072_move_focus(dir, 4);
-		msleep(1000);
-	}
-	imx072_set_default_focus();
-	msleep(3000);
-	return 0;
-}
-
-static int imx072_af_set_resolution(void *data, u64 val)
-{
-	imx072_init_focus();
-	return 0;
-}
-
-static int imx072_af_get_resolution(void *data, u64 *val)
-{
-	*val = 0xFF;
-	return 0;
-}
-
-
-
-DEFINE_SIMPLE_ATTRIBUTE(af_codeperstep, imx072_get_af_codestep,
-			imx072_set_af_codestep, "%llu\n");
-
-DEFINE_SIMPLE_ATTRIBUTE(af_linear, imx072_af_linearity_test,
-			imx072_set_linear_total_step, "%llu\n");
-
-DEFINE_SIMPLE_ATTRIBUTE(af_step, imx072_af_step,
-			imx072_af_step_config, "%llu\n");
-
-DEFINE_SIMPLE_ATTRIBUTE(af_step_res, imx072_af_get_resolution,
-			imx072_af_set_resolution, "%llu\n");
-
-static int cam_debug_init(void)
-{
-	struct dentry *cam_dir;
-	debugfs_base = debugfs_create_dir("sensor", NULL);
-	if (!debugfs_base)
-		return -ENOMEM;
-
-	cam_dir = debugfs_create_dir("imx072", debugfs_base);
-	if (!cam_dir)
-		return -ENOMEM;
-
-	if (!debugfs_create_file("stream", S_IRUGO | S_IWUSR, cam_dir,
-							 NULL, &cam_stream))
-		return -ENOMEM;
-
-	if (!debugfs_create_file("af_codeperstep", S_IRUGO | S_IWUSR, cam_dir,
-							 NULL, &af_codeperstep))
-		return -ENOMEM;
-	if (!debugfs_create_file("af_linear", S_IRUGO | S_IWUSR, cam_dir,
-							 NULL, &af_linear))
-		return -ENOMEM;
-	if (!debugfs_create_file("af_step", S_IRUGO | S_IWUSR, cam_dir,
-							 NULL, &af_step))
-		return -ENOMEM;
-
-	if (!debugfs_create_file("af_step_res", S_IRUGO | S_IWUSR, cam_dir,
-							 NULL, &af_step_res))
-		return -ENOMEM;
-
-	return 0;
-}
-#endif
diff --git a/drivers/media/video/msm/imx072.h b/drivers/media/video/msm/imx072.h
deleted file mode 100644
index e3d279f..0000000
--- a/drivers/media/video/msm/imx072.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. 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 IMX072_H
-#define IMX072_H
-#include <linux/types.h>
-#include <mach/board.h>
-extern struct imx072_reg imx072_regs;
-
-struct imx072_i2c_reg_conf {
-	unsigned short waddr;
-	unsigned short wdata;
-};
-
-struct imx072_i2c_conf_array {
-	struct imx072_i2c_reg_conf *conf;
-	unsigned short size;
-};
-
-enum imx072_test_mode_t {
-	TEST_OFF,
-	TEST_1,
-	TEST_2,
-	TEST_3
-};
-
-enum imx072_resolution_t {
-	QTR_2D_SIZE,
-	FULL_2D_SIZE,
-	QTR_3D_SIZE,
-	FULL_3D_SIZE,
-	INVALID_SIZE
-};
-enum imx072_setting {
-	RES_PREVIEW,
-	RES_CAPTURE,
-	RES_3D_PREVIEW,
-	RES_3D_CAPTURE
-};
-enum imx072_cam_mode_t {
-	MODE_2D_RIGHT,
-	MODE_2D_LEFT,
-	MODE_3D,
-	MODE_INVALID
-};
-enum imx072_reg_update {
-	/* Sensor egisters that need to be updated during initialization */
-	REG_INIT,
-	/* Sensor egisters that needs periodic I2C writes */
-	UPDATE_PERIODIC,
-	/* All the sensor Registers will be updated */
-	UPDATE_ALL,
-	/* Not valid update */
-	UPDATE_INVALID
-};
-
-enum imx072_reg_mode {
-	IMX072_FRAME_LENGTH_LINES_HI = 0,
-	IMX072_FRAME_LENGTH_LINES_LO,
-	IMX072_LINE_LENGTH_PCK_HI,
-	IMX072_LINE_LENGTH_PCK_LO,
-};
-
-struct imx072_reg {
-	const struct imx072_i2c_reg_conf *rec_settings;
-	const unsigned short rec_size;
-	const struct imx072_i2c_conf_array *conf_array;
-};
-#endif /* IMX072_H */
diff --git a/drivers/media/video/msm/imx072_reg.c b/drivers/media/video/msm/imx072_reg.c
deleted file mode 100644
index ea75548..0000000
--- a/drivers/media/video/msm/imx072_reg.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. 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 "imx072.h"
-
-struct imx072_i2c_reg_conf imx072_prev_settings[] = {
-	{0x0340, 0x03},/*frame_length*/
-	{0x0341, 0xF7},/*frame_length*/
-	{0x0342, 0x0A},/*line_length*/
-	{0x0343, 0xE0},/*line_length*/
-	{0x0344, 0x00},/*x_addr_start*/
-	{0x0345, 0x00},/*x_addr_start*/
-	{0x0346, 0x00},/*y_addr_start*/
-	{0x0347, 0x00},/*y_addr_start*/
-	{0x0348, 0x0A},/*x_addr_end*/
-	{0x0349, 0x2F},/*x_addr_end*/
-	{0x034A, 0x07},/*y_addr_end*/
-	{0x034B, 0xA7},/*y_addr_end*/
-	{0x034C, 0x05},/*x_out_size*/
-	{0x034D, 0x18},/*x_out_size*/
-	{0x034E, 0x03},/*y_out_size*/
-	{0x034F, 0xD4},/*y_out_size*/
-	{0x0381, 0x01},/*x_even_inc*/
-	{0x0383, 0x03},/*x_odd_inc*/
-	{0x0385, 0x01},/*y_even_inc*/
-	{0x0387, 0x03},/*y_odd_inc*/
-	{0x3016, 0x06},/*VMODEADD*/
-	{0x3017, 0x40},
-	{0x3069, 0x24},
-	{0x306A, 0x00},
-	{0x306B, 0xCB},
-	{0x306C, 0x07},
-	{0x30E8, 0x86},
-	{0x3304, 0x03},
-	{0x3305, 0x02},
-	{0x3306, 0x0A},
-	{0x3307, 0x02},
-	{0x3308, 0x11},
-	{0x3309, 0x04},
-	{0x330A, 0x05},
-	{0x330B, 0x04},
-	{0x330C, 0x05},
-	{0x330D, 0x04},
-	{0x330E, 0x01},
-	{0x3301, 0x80},
-};
-
-struct imx072_i2c_reg_conf imx072_snap_settings[] = {
-	{0x0340, 0x07},/*frame_length*/
-	{0x0341, 0xEE},/*frame_length*/
-	{0x0342, 0x0A},/*line_length*/
-	{0x0343, 0xE0},/*line_length*/
-	{0x0344, 0x00},/*x_addr_start*/
-	{0x0345, 0x00},/*x_addr_start*/
-	{0x0346, 0x00},/*y_addr_start*/
-	{0x0347, 0x00},/*y_addr_start*/
-	{0x0348, 0x0A},/*x_addr_end*/
-	{0x0349, 0x2F},/*x_addr_end*/
-	{0x034A, 0x07},/*y_addr_end*/
-	{0x034B, 0xA7},/*y_addr_end*/
-	{0x034C, 0x0A},/*x_out_size*/
-	{0x034D, 0x30},/*x_out_size*/
-	{0x034E, 0x07},/*y_out_size*/
-	{0x034F, 0xA8},/*y_out_size*/
-	{0x0381, 0x01},/*x_even_inc*/
-	{0x0383, 0x01},/*x_odd_inc*/
-	{0x0385, 0x01},/*y_even_inc*/
-	{0x0387, 0x01},/*y_odd_inc*/
-	{0x3016, 0x06},/*VMODEADD*/
-	{0x3017, 0x40},
-	{0x3069, 0x24},
-	{0x306A, 0x00},
-	{0x306B, 0xCB},
-	{0x306C, 0x07},
-	{0x30E8, 0x06},
-	{0x3304, 0x05},
-	{0x3305, 0x04},
-	{0x3306, 0x15},
-	{0x3307, 0x02},
-	{0x3308, 0x11},
-	{0x3309, 0x07},
-	{0x330A, 0x05},
-	{0x330B, 0x04},
-	{0x330C, 0x05},
-	{0x330D, 0x04},
-	{0x330E, 0x01},
-	{0x3301, 0x00},
-};
-
-struct imx072_i2c_reg_conf imx072_recommend_settings[] = {
-	{0x0307, 0x12},
-	{0x302B, 0x4B},
-	{0x0101, 0x03},
-	{0x300A, 0x80},
-	{0x3014, 0x08},
-	{0x3015, 0x37},
-	{0x3017, 0x40},
-	{0x301C, 0x01},
-	{0x3031, 0x28},
-	{0x3040, 0x00},
-	{0x3041, 0x60},
-	{0x3051, 0x24},
-	{0x3053, 0x34},
-	{0x3055, 0x3B},
-	{0x3057, 0xC0},
-	{0x3060, 0x30},
-	{0x3065, 0x00},
-	{0x30AA, 0x88},
-	{0x30AB, 0x1C},
-	{0x30B0, 0x32},
-	{0x30B2, 0x83},
-	{0x30D3, 0x04},
-	{0x310E, 0xDD},
-	{0x31A4, 0xD8},
-	{0x31A6, 0x17},
-	{0x31AC, 0xCF},
-	{0x31AE, 0xF1},
-	{0x31B4, 0xD8},
-	{0x31B6, 0x17},
-	{0x3304, 0x05},
-	{0x3305, 0x04},
-	{0x3306, 0x15},
-	{0x3307, 0x02},
-	{0x3308, 0x11},
-	{0x3309, 0x07},
-	{0x330A, 0x05},
-	{0x330B, 0x04},
-	{0x330C, 0x05},
-	{0x330D, 0x04},
-	{0x330E, 0x01},
-	{0x30d8, 0x20},
-};
-
-struct imx072_i2c_conf_array imx072_confs[] = {
-	{&imx072_prev_settings[0], ARRAY_SIZE(imx072_prev_settings)},
-	{&imx072_snap_settings[0], ARRAY_SIZE(imx072_snap_settings)},
-};
-
-struct imx072_reg imx072_regs = {
-	.rec_settings = &imx072_recommend_settings[0],
-	.rec_size = ARRAY_SIZE(imx072_recommend_settings),
-	.conf_array = &imx072_confs[0],
-};
diff --git a/drivers/media/video/msm/imx074.c b/drivers/media/video/msm/imx074.c
deleted file mode 100644
index 636b402..0000000
--- a/drivers/media/video/msm/imx074.c
+++ /dev/null
@@ -1,1414 +0,0 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. 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/delay.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/slab.h>
-#include <media/msm_camera.h>
-#include <mach/gpio.h>
-#include <mach/camera.h>
-#include <asm/mach-types.h>
-#include "imx074.h"
-
-/*SENSOR REGISTER DEFINES*/
-#define	IMX074_EEPROM_SLAVE_ADDR			0x52
-#define REG_GROUPED_PARAMETER_HOLD			0x0104
-#define GROUPED_PARAMETER_HOLD_OFF			0x00
-#define GROUPED_PARAMETER_HOLD				0x01
-#define REG_MODE_SELECT					0x100
-#define MODE_SELECT_STANDBY_MODE			0x00
-#define MODE_SELECT_STREAM				0x01
-/* Integration Time */
-#define REG_COARSE_INTEGRATION_TIME_HI			0x0202
-#define REG_COARSE_INTEGRATION_TIME_LO			0x0203
-/* Gain */
-#define REG_ANALOGUE_GAIN_CODE_GLOBAL_HI		0x0204
-#define REG_ANALOGUE_GAIN_CODE_GLOBAL_LO		0x0205
-/* PLL registers */
-#define REG_PLL_MULTIPLIER				0x0307
-#define REG_PRE_PLL_CLK_DIV				0x0305
-#define REG_PLSTATIM					0x302b
-#define REG_3024					0x3024
-#define REG_IMAGE_ORIENTATION				0x0101
-#define REG_VNDMY_ABLMGSHLMT				0x300a
-#define REG_Y_OPBADDR_START_DI				0x3014
-#define REG_3015					0x3015
-#define REG_301C					0x301C
-#define REG_302C					0x302C
-#define REG_3031					0x3031
-#define REG_3041					0x3041
-#define REG_3051					0x3051
-#define REG_3053					0x3053
-#define REG_3057					0x3057
-#define REG_305C					0x305C
-#define REG_305D					0x305D
-#define REG_3060					0x3060
-#define REG_3065					0x3065
-#define REG_30AA					0x30AA
-#define REG_30AB					0x30AB
-#define REG_30B0					0x30B0
-#define REG_30B2					0x30B2
-#define REG_30D3					0x30D3
-#define REG_3106					0x3106
-#define REG_310C					0x310C
-#define REG_3304					0x3304
-#define REG_3305					0x3305
-#define REG_3306					0x3306
-#define REG_3307					0x3307
-#define REG_3308					0x3308
-#define REG_3309					0x3309
-#define REG_330A					0x330A
-#define REG_330B					0x330B
-#define REG_330C					0x330C
-#define REG_330D					0x330D
-#define REG_330F					0x330F
-#define REG_3381					0x3381
-
-/* mode setting */
-#define REG_FRAME_LENGTH_LINES_HI			0x0340
-#define REG_FRAME_LENGTH_LINES_LO			0x0341
-#define REG_YADDR_START					0x0347
-#define REG_YAAAR_END					0x034b
-#define REG_X_OUTPUT_SIZE_MSB				0x034c
-#define REG_X_OUTPUT_SIZE_LSB				0x034d
-#define REG_Y_OUTPUT_SIZE_MSB				0x034e
-#define REG_Y_OUTPUT_SIZE_LSB				0x034f
-#define REG_X_EVEN_INC					0x0381
-#define REG_X_ODD_INC					0x0383
-#define REG_Y_EVEN_INC					0x0385
-#define REG_Y_ODD_INC					0x0387
-#define REG_HMODEADD					0x3001
-#define REG_VMODEADD					0x3016
-#define REG_VAPPLINE_START				0x3069
-#define REG_VAPPLINE_END				0x306b
-#define REG_SHUTTER					0x3086
-#define REG_HADDAVE					0x30e8
-#define REG_LANESEL					0x3301
-/* Test Pattern */
-#define REG_TEST_PATTERN_MODE				0x0601
-
-#define REG_LINE_LENGTH_PCK_HI				0x0342
-#define REG_LINE_LENGTH_PCK_LO				0x0343
-/*..... TYPE DECLARATIONS.....*/
-#define	IMX074_OFFSET					3
-#define	IMX074_DEFAULT_MASTER_CLK_RATE			24000000
-/* Full	Size */
-#define	IMX074_FULL_SIZE_WIDTH				4208
-#define	IMX074_FULL_SIZE_HEIGHT				3120
-#define	IMX074_FULL_SIZE_DUMMY_PIXELS			0
-#define	IMX074_FULL_SIZE_DUMMY_LINES			0
-/* Quarter Size	*/
-#define	IMX074_QTR_SIZE_WIDTH				2104
-#define	IMX074_QTR_SIZE_HEIGHT				1560
-#define	IMX074_QTR_SIZE_DUMMY_PIXELS			0
-#define	IMX074_QTR_SIZE_DUMMY_LINES			0
-/* Blanking as measured	on the scope */
-/* Full	Size */
-#define	IMX074_HRZ_FULL_BLK_PIXELS			264
-#define	IMX074_VER_FULL_BLK_LINES			96
-/* Quarter Size	*/
-#define	IMX074_HRZ_QTR_BLK_PIXELS			2368
-#define	IMX074_VER_QTR_BLK_LINES			21
-#define	Q8						0x100
-#define	Q10						0x400
-#define	IMX074_AF_I2C_SLAVE_ID				0x72
-#define	IMX074_STEPS_NEAR_TO_CLOSEST_INF		52
-#define	IMX074_TOTAL_STEPS_NEAR_TO_FAR			52
-static uint32_t imx074_l_region_code_per_step = 2;
-
-struct imx074_work_t {
-	struct work_struct work;
-};
-
-static struct imx074_work_t *imx074_sensorw;
-static struct i2c_client *imx074_client;
-
-struct imx074_ctrl_t {
-	const struct msm_camera_sensor_info *sensordata;
-	uint32_t sensormode;
-	uint32_t fps_divider;/* init to 1 * 0x00000400 */
-	uint32_t pict_fps_divider;/* init to 1 * 0x00000400 */
-	uint16_t fps;
-	int16_t curr_lens_pos;
-	uint16_t curr_step_pos;
-	uint16_t my_reg_gain;
-	uint32_t my_reg_line_count;
-	uint16_t total_lines_per_frame;
-	enum imx074_resolution_t prev_res;
-	enum imx074_resolution_t pict_res;
-	enum imx074_resolution_t curr_res;
-	enum imx074_test_mode_t set_test;
-	unsigned short imgaddr;
-};
-static uint8_t imx074_delay_msecs_stdby = 5;
-static uint16_t imx074_delay_msecs_stream = 5;
-static int32_t config_csi;
-
-static struct imx074_ctrl_t *imx074_ctrl;
-static DECLARE_WAIT_QUEUE_HEAD(imx074_wait_queue);
-DEFINE_MUTEX(imx074_mut);
-
-/*=============================================================*/
-
-static int imx074_i2c_rxdata(unsigned short saddr,
-	unsigned char *rxdata, int length)
-{
-	struct i2c_msg msgs[] = {
-		{
-			.addr  = saddr,
-			.flags = 0,
-			.len   = 2,
-			.buf   = rxdata,
-		},
-		{
-			.addr  = saddr,
-			.flags = I2C_M_RD,
-			.len   = 2,
-			.buf   = rxdata,
-		},
-	};
-	if (i2c_transfer(imx074_client->adapter, msgs, 2) < 0) {
-		CDBG("imx074_i2c_rxdata failed!\n");
-		return -EIO;
-	}
-	return 0;
-}
-static int32_t imx074_i2c_txdata(unsigned short saddr,
-				unsigned char *txdata, int length)
-{
-	struct i2c_msg msg[] = {
-		{
-			.addr = saddr,
-			.flags = 0,
-			.len = length,
-			.buf = txdata,
-		 },
-	};
-	if (i2c_transfer(imx074_client->adapter, msg, 1) < 0) {
-		CDBG("imx074_i2c_txdata faild 0x%x\n", imx074_client->addr);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-
-static int32_t imx074_i2c_read(unsigned short raddr,
-	unsigned short *rdata, int rlen)
-{
-	int32_t rc = 0;
-	unsigned char buf[2];
-	if (!rdata)
-		return -EIO;
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (raddr & 0xFF00) >> 8;
-	buf[1] = (raddr & 0x00FF);
-	rc = imx074_i2c_rxdata(imx074_client->addr, buf, rlen);
-	if (rc < 0) {
-		CDBG("imx074_i2c_read 0x%x failed!\n", raddr);
-		return rc;
-	}
-	*rdata = (rlen == 2 ? buf[0] << 8 | buf[1] : buf[0]);
-	return rc;
-}
-
-static int imx074_af_i2c_rxdata_b(unsigned short saddr,
-	unsigned char *rxdata, int length)
-{
-	struct i2c_msg msgs[] = {
-		{
-		.addr  = saddr,
-		.flags = 0,
-		.len   = 1,
-		.buf   = rxdata,
-		},
-		{
-		.addr  = saddr,
-		.flags = I2C_M_RD,
-		.len   = 1,
-		.buf   = rxdata,
-		},
-	};
-
-	if (i2c_transfer(imx074_client->adapter, msgs, 2) < 0) {
-		CDBG("imx074_i2c_rxdata_b failed!\n");
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int32_t imx074_i2c_read_w_eeprom(unsigned short raddr,
-	unsigned short *rdata)
-{
-	int32_t rc;
-	unsigned char buf;
-	if (!rdata)
-		return -EIO;
-	/* Read 2 bytes in sequence */
-	buf = (raddr & 0x00FF);
-	rc = imx074_af_i2c_rxdata_b(IMX074_EEPROM_SLAVE_ADDR, &buf, 1);
-	if (rc < 0) {
-		CDBG("imx074_i2c_read_eeprom 0x%x failed!\n", raddr);
-		return rc;
-	}
-	*rdata = buf<<8;
-
-	/* Read Second byte of data */
-	buf = (raddr & 0x00FF) + 1;
-	rc = imx074_af_i2c_rxdata_b(IMX074_EEPROM_SLAVE_ADDR, &buf, 1);
-	if (rc < 0) {
-		CDBG("imx074_i2c_read_eeprom 0x%x failed!\n", raddr);
-		return rc;
-	}
-	*rdata |= buf;
-	return rc;
-}
-
-static int32_t imx074_i2c_write_b_sensor(unsigned short waddr, uint8_t bdata)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[3];
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (waddr & 0xFF00) >> 8;
-	buf[1] = (waddr & 0x00FF);
-	buf[2] = bdata;
-	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
-	rc = imx074_i2c_txdata(imx074_client->addr, buf, 3);
-	if (rc < 0) {
-		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
-			waddr, bdata);
-	}
-	return rc;
-}
-static int16_t imx074_i2c_write_b_af(unsigned short saddr,
-	unsigned short baddr, unsigned short bdata)
-{
-	int32_t rc;
-	unsigned char buf[2];
-	memset(buf, 0, sizeof(buf));
-	buf[0] = baddr;
-	buf[1] = bdata;
-	rc = imx074_i2c_txdata(saddr, buf, 2);
-	if (rc < 0)
-		CDBG("AFi2c_write failed, saddr = 0x%x addr = 0x%x, val =0x%x!",
-			saddr, baddr, bdata);
-	return rc;
-}
-
-static int32_t imx074_i2c_write_w_table(struct imx074_i2c_reg_conf const
-					 *reg_conf_tbl, int num)
-{
-	int i;
-	int32_t rc = -EIO;
-	for (i = 0; i < num; i++) {
-		rc = imx074_i2c_write_b_sensor(reg_conf_tbl->waddr,
-			reg_conf_tbl->wdata);
-		if (rc < 0)
-			break;
-		reg_conf_tbl++;
-	}
-	return rc;
-}
-static int16_t imx074_af_init(void)
-{
-	int32_t rc;
-	/* Initialize waveform */
-	rc = imx074_i2c_write_b_af(IMX074_AF_I2C_SLAVE_ID, 0x01, 0xA9);
-	rc = imx074_i2c_write_b_af(IMX074_AF_I2C_SLAVE_ID, 0x02, 0xD2);
-	rc = imx074_i2c_write_b_af(IMX074_AF_I2C_SLAVE_ID, 0x03, 0x0C);
-	rc = imx074_i2c_write_b_af(IMX074_AF_I2C_SLAVE_ID, 0x04, 0x14);
-	rc = imx074_i2c_write_b_af(IMX074_AF_I2C_SLAVE_ID, 0x05, 0xB6);
-	rc = imx074_i2c_write_b_af(IMX074_AF_I2C_SLAVE_ID, 0x06, 0x4F);
-	return rc;
-}
-
-static void imx074_get_pict_fps(uint16_t fps, uint16_t *pfps)
-{
-	/* input fps is preview fps in Q8 format */
-	uint16_t preview_frame_length_lines, snapshot_frame_length_lines;
-	uint32_t divider, d1;
-	uint32_t pclk_mult;/*Q10 */
-	/* Total frame_length_lines and line_length_pck for preview */
-	preview_frame_length_lines = IMX074_QTR_SIZE_HEIGHT +
-		IMX074_VER_QTR_BLK_LINES;
-	/* Total frame_length_lines and line_length_pck for snapshot */
-	snapshot_frame_length_lines = IMX074_FULL_SIZE_HEIGHT +
-		IMX074_VER_FULL_BLK_LINES;
-	d1 = preview_frame_length_lines * 0x00010000 /
-		snapshot_frame_length_lines;
-	pclk_mult =
-		(uint32_t) ((imx074_regs.reg_pat[RES_CAPTURE].pll_multiplier *
-		0x00010000) /
-		(imx074_regs.reg_pat[RES_PREVIEW].pll_multiplier));
-	divider = d1 * pclk_mult / 0x00010000;
-	*pfps = (uint16_t) (fps * divider / 0x00010000);
-}
-
-static uint16_t imx074_get_prev_lines_pf(void)
-{
-	if (imx074_ctrl->prev_res == QTR_SIZE)
-		return IMX074_QTR_SIZE_HEIGHT + IMX074_VER_QTR_BLK_LINES;
-	else
-		return IMX074_FULL_SIZE_HEIGHT + IMX074_VER_FULL_BLK_LINES;
-
-}
-
-static uint16_t imx074_get_prev_pixels_pl(void)
-{
-	if (imx074_ctrl->prev_res == QTR_SIZE)
-		return IMX074_QTR_SIZE_WIDTH + IMX074_HRZ_QTR_BLK_PIXELS;
-	else
-		return IMX074_FULL_SIZE_WIDTH + IMX074_HRZ_FULL_BLK_PIXELS;
-}
-
-static uint16_t imx074_get_pict_lines_pf(void)
-{
-		if (imx074_ctrl->pict_res == QTR_SIZE)
-			return IMX074_QTR_SIZE_HEIGHT +
-				IMX074_VER_QTR_BLK_LINES;
-		else
-			return IMX074_FULL_SIZE_HEIGHT +
-				IMX074_VER_FULL_BLK_LINES;
-}
-
-static uint16_t imx074_get_pict_pixels_pl(void)
-{
-	if (imx074_ctrl->pict_res == QTR_SIZE)
-		return IMX074_QTR_SIZE_WIDTH +
-			IMX074_HRZ_QTR_BLK_PIXELS;
-	else
-		return IMX074_FULL_SIZE_WIDTH +
-			IMX074_HRZ_FULL_BLK_PIXELS;
-}
-
-static uint32_t imx074_get_pict_max_exp_lc(void)
-{
-	if (imx074_ctrl->pict_res == QTR_SIZE)
-		return (IMX074_QTR_SIZE_HEIGHT +
-			IMX074_VER_QTR_BLK_LINES)*24;
-	else
-		return (IMX074_FULL_SIZE_HEIGHT +
-			IMX074_VER_FULL_BLK_LINES)*24;
-}
-
-static int32_t imx074_set_fps(struct fps_cfg	*fps)
-{
-	uint16_t total_lines_per_frame;
-	int32_t rc = 0;
-	imx074_ctrl->fps_divider = fps->fps_div;
-	imx074_ctrl->pict_fps_divider = fps->pict_fps_div;
-	if (imx074_ctrl->curr_res  == QTR_SIZE) {
-		total_lines_per_frame = (uint16_t)(((IMX074_QTR_SIZE_HEIGHT +
-			IMX074_VER_QTR_BLK_LINES) *
-			imx074_ctrl->fps_divider) / 0x400);
-	} else {
-		total_lines_per_frame = (uint16_t)(((IMX074_FULL_SIZE_HEIGHT +
-			IMX074_VER_FULL_BLK_LINES) *
-			imx074_ctrl->pict_fps_divider) / 0x400);
-	}
-	if (imx074_i2c_write_b_sensor(REG_FRAME_LENGTH_LINES_HI,
-		((total_lines_per_frame & 0xFF00) >> 8)) < 0)
-		return rc;
-	if (imx074_i2c_write_b_sensor(REG_FRAME_LENGTH_LINES_LO,
-		(total_lines_per_frame & 0x00FF)) < 0)
-		return rc;
-	return rc;
-}
-
-static int32_t imx074_write_exp_gain(uint16_t gain, uint32_t line)
-{
-	static uint16_t max_legal_gain = 0x00E0;
-	uint8_t gain_msb, gain_lsb;
-	uint8_t intg_time_msb, intg_time_lsb;
-	uint8_t frame_length_line_msb, frame_length_line_lsb;
-	uint16_t frame_length_lines;
-	int32_t rc = -1;
-
-	CDBG("imx074_write_exp_gain : gain = %d line = %d", gain, line);
-	if (imx074_ctrl->curr_res  == QTR_SIZE) {
-		frame_length_lines = IMX074_QTR_SIZE_HEIGHT +
-			IMX074_VER_QTR_BLK_LINES;
-		frame_length_lines = frame_length_lines *
-			imx074_ctrl->fps_divider / 0x400;
-	} else {
-		frame_length_lines = IMX074_FULL_SIZE_HEIGHT +
-			IMX074_VER_FULL_BLK_LINES;
-		frame_length_lines = frame_length_lines *
-			imx074_ctrl->pict_fps_divider / 0x400;
-	}
-	if (line > (frame_length_lines - IMX074_OFFSET))
-		frame_length_lines = line + IMX074_OFFSET;
-
-	CDBG("imx074 setting line = %d\n", line);
-
-
-	CDBG("imx074 setting frame_length_lines = %d\n",
-					frame_length_lines);
-
-	if (gain > max_legal_gain)
-		/* range: 0 to 224 */
-		gain = max_legal_gain;
-
-	/* update gain registers */
-	gain_msb = (uint8_t) ((gain & 0xFF00) >> 8);
-	gain_lsb = (uint8_t) (gain & 0x00FF);
-
-	frame_length_line_msb = (uint8_t) ((frame_length_lines & 0xFF00) >> 8);
-	frame_length_line_lsb = (uint8_t) (frame_length_lines & 0x00FF);
-
-	/* update line count registers */
-	intg_time_msb = (uint8_t) ((line & 0xFF00) >> 8);
-	intg_time_lsb = (uint8_t) (line & 0x00FF);
-
-	rc = imx074_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
-					GROUPED_PARAMETER_HOLD);
-	if (rc < 0)
-		return rc;
-	CDBG("imx074 setting REG_ANALOGUE_GAIN_CODE_GLOBAL_HI = 0x%X\n",
-					gain_msb);
-	rc = imx074_i2c_write_b_sensor(REG_ANALOGUE_GAIN_CODE_GLOBAL_HI,
-					gain_msb);
-	if (rc < 0)
-		return rc;
-	CDBG("imx074 setting REG_ANALOGUE_GAIN_CODE_GLOBAL_LO = 0x%X\n",
-					gain_lsb);
-	rc = imx074_i2c_write_b_sensor(REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
-					gain_lsb);
-	if (rc < 0)
-		return rc;
-
-	CDBG("imx074 setting REG_FRAME_LENGTH_LINES_HI = 0x%X\n",
-					frame_length_line_msb);
-	rc = imx074_i2c_write_b_sensor(REG_FRAME_LENGTH_LINES_HI,
-			frame_length_line_msb);
-	if (rc < 0)
-		return rc;
-
-	CDBG("imx074 setting REG_FRAME_LENGTH_LINES_LO = 0x%X\n",
-			frame_length_line_lsb);
-	rc = imx074_i2c_write_b_sensor(REG_FRAME_LENGTH_LINES_LO,
-			frame_length_line_lsb);
-	if (rc < 0)
-		return rc;
-
-	CDBG("imx074 setting REG_COARSE_INTEGRATION_TIME_HI = 0x%X\n",
-					intg_time_msb);
-	rc = imx074_i2c_write_b_sensor(REG_COARSE_INTEGRATION_TIME_HI,
-					intg_time_msb);
-	if (rc < 0)
-		return rc;
-
-	CDBG("imx074 setting REG_COARSE_INTEGRATION_TIME_LO = 0x%X\n",
-					intg_time_lsb);
-	rc = imx074_i2c_write_b_sensor(REG_COARSE_INTEGRATION_TIME_LO,
-					intg_time_lsb);
-	if (rc < 0)
-		return rc;
-
-	rc = imx074_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
-					GROUPED_PARAMETER_HOLD_OFF);
-	if (rc < 0)
-		return rc;
-
-	return rc;
-}
-
-static int32_t imx074_set_pict_exp_gain(uint16_t gain, uint32_t line)
-{
-	int32_t rc = 0;
-	rc = imx074_write_exp_gain(gain, line);
-	return rc;
-}
-
-static int32_t imx074_move_focus(int direction,
-	int32_t num_steps)
-{
-	int32_t step_direction, dest_step_position, bit_mask;
-	int32_t rc = 0;
-
-	if (num_steps == 0)
-		return rc;
-
-	if (direction == MOVE_NEAR) {
-		step_direction = 1;
-		bit_mask = 0x80;
-	} else if (direction == MOVE_FAR) {
-		step_direction = -1;
-		bit_mask = 0x00;
-	} else {
-		CDBG("imx074_move_focus: Illegal focus direction");
-		return -EINVAL;
-	}
-	dest_step_position = imx074_ctrl->curr_step_pos +
-		(step_direction * num_steps);
-	if (dest_step_position < 0)
-		dest_step_position = 0;
-	else if (dest_step_position > IMX074_TOTAL_STEPS_NEAR_TO_FAR)
-		dest_step_position = IMX074_TOTAL_STEPS_NEAR_TO_FAR;
-	rc = imx074_i2c_write_b_af(IMX074_AF_I2C_SLAVE_ID, 0x00,
-		((num_steps * imx074_l_region_code_per_step) | bit_mask));
-	CDBG("%s: Index: %d\n", __func__, dest_step_position);
-	imx074_ctrl->curr_step_pos = dest_step_position;
-	return rc;
-}
-
-
-static int32_t imx074_set_default_focus(uint8_t af_step)
-{
-	int32_t rc;
-	/* Initialize to infinity */
-	rc = imx074_i2c_write_b_af(IMX074_AF_I2C_SLAVE_ID, 0x00, 0x7F);
-	rc = imx074_i2c_write_b_af(IMX074_AF_I2C_SLAVE_ID, 0x00, 0x7F);
-	imx074_ctrl->curr_step_pos = 0;
-	return rc;
-}
-static int32_t imx074_test(enum imx074_test_mode_t mo)
-{
-	int32_t rc = 0;
-	if (mo == TEST_OFF)
-		return rc;
-	else {
-		/* Set mo to 2 inorder to enable test pattern*/
-		if (imx074_i2c_write_b_sensor(REG_TEST_PATTERN_MODE,
-			(uint8_t) mo) < 0) {
-			return rc;
-		}
-	}
-	return rc;
-}
-static int32_t imx074_sensor_setting(int update_type, int rt)
-{
-	int32_t rc = 0;
-	struct msm_camera_csi_params imx074_csi_params;
-	switch (update_type) {
-	case REG_INIT:
-		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
-			struct imx074_i2c_reg_conf init_tbl[] = {
-				{REG_PRE_PLL_CLK_DIV,
-					imx074_regs.reg_pat_init[0].
-					pre_pll_clk_div},
-				{REG_PLSTATIM,
-					imx074_regs.reg_pat_init[0].
-					plstatim},
-				{REG_3024,
-					imx074_regs.reg_pat_init[0].
-					reg_3024},
-				{REG_IMAGE_ORIENTATION,
-					imx074_regs.reg_pat_init[0].
-					image_orientation},
-				{REG_VNDMY_ABLMGSHLMT,
-					imx074_regs.reg_pat_init[0].
-					vndmy_ablmgshlmt},
-				{REG_Y_OPBADDR_START_DI,
-					imx074_regs.reg_pat_init[0].
-					y_opbaddr_start_di},
-				{REG_3015,
-					imx074_regs.reg_pat_init[0].
-					reg_0x3015},
-				{REG_301C,
-					imx074_regs.reg_pat_init[0].
-					reg_0x301c},
-				{REG_302C,
-					imx074_regs.reg_pat_init[0].
-					reg_0x302c},
-				{REG_3031,
-					imx074_regs.reg_pat_init[0].reg_0x3031},
-				{REG_3041,
-					imx074_regs.reg_pat_init[0].reg_0x3041},
-				{REG_3051,
-					imx074_regs.reg_pat_init[0].reg_0x3051},
-				{REG_3053,
-					imx074_regs.reg_pat_init[0].reg_0x3053},
-				{REG_3057,
-					imx074_regs.reg_pat_init[0].reg_0x3057},
-				{REG_305C,
-					imx074_regs.reg_pat_init[0].reg_0x305c},
-				{REG_305D,
-					imx074_regs.reg_pat_init[0].reg_0x305d},
-				{REG_3060,
-					imx074_regs.reg_pat_init[0].reg_0x3060},
-				{REG_3065,
-					imx074_regs.reg_pat_init[0].reg_0x3065},
-				{REG_30AA,
-					imx074_regs.reg_pat_init[0].reg_0x30aa},
-				{REG_30AB,
-					imx074_regs.reg_pat_init[0].reg_0x30ab},
-				{REG_30B0,
-					imx074_regs.reg_pat_init[0].reg_0x30b0},
-				{REG_30B2,
-					imx074_regs.reg_pat_init[0].reg_0x30b2},
-				{REG_30D3,
-					imx074_regs.reg_pat_init[0].reg_0x30d3},
-				{REG_3106,
-					imx074_regs.reg_pat_init[0].reg_0x3106},
-				{REG_310C,
-					imx074_regs.reg_pat_init[0].reg_0x310c},
-				{REG_3304,
-					imx074_regs.reg_pat_init[0].reg_0x3304},
-				{REG_3305,
-					imx074_regs.reg_pat_init[0].reg_0x3305},
-				{REG_3306,
-					imx074_regs.reg_pat_init[0].reg_0x3306},
-				{REG_3307,
-					imx074_regs.reg_pat_init[0].reg_0x3307},
-				{REG_3308,
-					imx074_regs.reg_pat_init[0].reg_0x3308},
-				{REG_3309,
-					imx074_regs.reg_pat_init[0].reg_0x3309},
-				{REG_330A,
-					imx074_regs.reg_pat_init[0].reg_0x330a},
-				{REG_330B,
-					imx074_regs.reg_pat_init[0].reg_0x330b},
-				{REG_330C,
-					imx074_regs.reg_pat_init[0].reg_0x330c},
-				{REG_330D,
-					imx074_regs.reg_pat_init[0].reg_0x330d},
-				{REG_330F,
-					imx074_regs.reg_pat_init[0].reg_0x330f},
-				{REG_3381,
-					imx074_regs.reg_pat_init[0].reg_0x3381},
-			};
-			struct imx074_i2c_reg_conf init_mode_tbl[] = {
-				{REG_GROUPED_PARAMETER_HOLD,
-					GROUPED_PARAMETER_HOLD},
-				{REG_PLL_MULTIPLIER,
-					imx074_regs.reg_pat[rt].
-					pll_multiplier},
-				{REG_FRAME_LENGTH_LINES_HI,
-					imx074_regs.reg_pat[rt].
-					frame_length_lines_hi},
-				{REG_FRAME_LENGTH_LINES_LO,
-					imx074_regs.reg_pat[rt].
-					frame_length_lines_lo},
-				{REG_YADDR_START ,
-					imx074_regs.reg_pat[rt].
-					y_addr_start},
-				{REG_YAAAR_END,
-					imx074_regs.reg_pat[rt].
-					y_add_end},
-				{REG_X_OUTPUT_SIZE_MSB,
-					imx074_regs.reg_pat[rt].
-					x_output_size_msb},
-				{REG_X_OUTPUT_SIZE_LSB,
-					imx074_regs.reg_pat[rt].
-					x_output_size_lsb},
-				{REG_Y_OUTPUT_SIZE_MSB,
-					imx074_regs.reg_pat[rt].
-					y_output_size_msb},
-				{REG_Y_OUTPUT_SIZE_LSB ,
-					imx074_regs.reg_pat[rt].
-					y_output_size_lsb},
-				{REG_X_EVEN_INC,
-					imx074_regs.reg_pat[rt].
-					x_even_inc},
-				{REG_X_ODD_INC,
-					imx074_regs.reg_pat[rt].
-					x_odd_inc},
-				{REG_Y_EVEN_INC,
-					imx074_regs.reg_pat[rt].
-					y_even_inc},
-				{REG_Y_ODD_INC,
-					imx074_regs.reg_pat[rt].
-					y_odd_inc},
-				{REG_HMODEADD,
-					imx074_regs.reg_pat[rt].
-					hmodeadd},
-				{REG_VMODEADD,
-					imx074_regs.reg_pat[rt].
-					vmodeadd},
-				{REG_VAPPLINE_START,
-					imx074_regs.reg_pat[rt].
-					vapplinepos_start},
-				{REG_VAPPLINE_END,
-					imx074_regs.reg_pat[rt].
-					vapplinepos_end},
-				{REG_SHUTTER,
-					imx074_regs.reg_pat[rt].
-					shutter},
-				{REG_HADDAVE,
-					imx074_regs.reg_pat[rt].
-					haddave},
-				{REG_LANESEL,
-					imx074_regs.reg_pat[rt].
-					lanesel},
-				{REG_GROUPED_PARAMETER_HOLD,
-					GROUPED_PARAMETER_HOLD_OFF},
-
-			};
-			/* reset fps_divider */
-			imx074_ctrl->fps = 30 * Q8;
-			imx074_ctrl->fps_divider = 1 * 0x400;
-			/* stop streaming */
-			rc = imx074_i2c_write_b_sensor(REG_MODE_SELECT,
-				MODE_SELECT_STANDBY_MODE);
-			if (rc < 0)
-				return rc;
-			msleep(imx074_delay_msecs_stdby);
-			rc = imx074_i2c_write_w_table(&init_tbl[0],
-				ARRAY_SIZE(init_tbl));
-			if (rc < 0)
-				return rc;
-			rc = imx074_i2c_write_w_table(&init_mode_tbl[0],
-				ARRAY_SIZE(init_mode_tbl));
-			if (rc < 0)
-				return rc;
-			rc = imx074_test(imx074_ctrl->set_test);
-			return rc;
-		}
-		break;
-	case UPDATE_PERIODIC:
-		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
-			struct imx074_i2c_reg_conf mode_tbl[] = {
-				{REG_GROUPED_PARAMETER_HOLD,
-					GROUPED_PARAMETER_HOLD},
-				{REG_PLL_MULTIPLIER,
-					imx074_regs.reg_pat[rt].
-					pll_multiplier},
-				{REG_FRAME_LENGTH_LINES_HI,
-					imx074_regs.reg_pat[rt].
-					frame_length_lines_hi},
-				{REG_FRAME_LENGTH_LINES_LO,
-					imx074_regs.reg_pat[rt].
-					frame_length_lines_lo},
-				{REG_YADDR_START ,
-					imx074_regs.reg_pat[rt].
-					y_addr_start},
-				{REG_YAAAR_END,
-					imx074_regs.reg_pat[rt].
-					y_add_end},
-				{REG_X_OUTPUT_SIZE_MSB,
-					imx074_regs.reg_pat[rt].
-					x_output_size_msb},
-				{REG_X_OUTPUT_SIZE_LSB,
-					imx074_regs.reg_pat[rt].
-					x_output_size_lsb},
-				{REG_Y_OUTPUT_SIZE_MSB,
-					imx074_regs.reg_pat[rt].
-					y_output_size_msb},
-				{REG_Y_OUTPUT_SIZE_LSB ,
-					imx074_regs.reg_pat[rt].
-					y_output_size_lsb},
-				{REG_X_EVEN_INC,
-					imx074_regs.reg_pat[rt].
-					x_even_inc},
-				{REG_X_ODD_INC,
-					imx074_regs.reg_pat[rt].
-					x_odd_inc},
-				{REG_Y_EVEN_INC,
-					imx074_regs.reg_pat[rt].
-					y_even_inc},
-				{REG_Y_ODD_INC,
-					imx074_regs.reg_pat[rt].
-					y_odd_inc},
-				{REG_HMODEADD,
-					imx074_regs.reg_pat[rt].
-					hmodeadd},
-				{REG_VMODEADD,
-					imx074_regs.reg_pat[rt].
-					vmodeadd},
-				{REG_VAPPLINE_START,
-					imx074_regs.reg_pat[rt].
-					vapplinepos_start},
-				{REG_VAPPLINE_END,
-					imx074_regs.reg_pat[rt].
-					vapplinepos_end},
-				{REG_SHUTTER,
-					imx074_regs.reg_pat[rt].
-					shutter},
-				{REG_HADDAVE,
-					imx074_regs.reg_pat[rt].
-					haddave},
-				{REG_LANESEL,
-					imx074_regs.reg_pat[rt].
-					lanesel},
-				{REG_GROUPED_PARAMETER_HOLD,
-					GROUPED_PARAMETER_HOLD_OFF},
-			};
-
-			/* stop streaming */
-			rc = imx074_i2c_write_b_sensor(REG_MODE_SELECT,
-				MODE_SELECT_STANDBY_MODE);
-			msleep(imx074_delay_msecs_stdby);
-			if (config_csi == 0) {
-				imx074_csi_params.lane_cnt = 4;
-				imx074_csi_params.data_format = CSI_10BIT;
-				imx074_csi_params.lane_assign = 0xe4;
-				imx074_csi_params.dpcm_scheme = 0;
-				imx074_csi_params.settle_cnt = 0x14;
-				rc = msm_camio_csi_config(&imx074_csi_params);
-				/*imx074_delay_msecs_stdby*/
-				msleep(imx074_delay_msecs_stream);
-				config_csi = 1;
-			}
-			rc = imx074_i2c_write_w_table(&mode_tbl[0],
-				ARRAY_SIZE(mode_tbl));
-			if (rc < 0)
-				return rc;
-			rc = imx074_i2c_write_b_sensor(REG_MODE_SELECT,
-				MODE_SELECT_STREAM);
-			if (rc < 0)
-				return rc;
-			msleep(imx074_delay_msecs_stream);
-		}
-		break;
-	default:
-		rc = -EINVAL;
-		break;
-	}
-
-	return rc;
-}
-
-
-static int32_t imx074_video_config(int mode)
-{
-
-	int32_t	rc = 0;
-	int	rt;
-	/* change sensor resolution	if needed */
-	if (imx074_ctrl->prev_res == QTR_SIZE) {
-		rt = RES_PREVIEW;
-	} else {
-		rt = RES_CAPTURE;
-	}
-	if (imx074_sensor_setting(UPDATE_PERIODIC, rt) < 0)
-		return rc;
-	imx074_ctrl->curr_res = imx074_ctrl->prev_res;
-	imx074_ctrl->sensormode = mode;
-	return rc;
-}
-
-static int32_t imx074_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-	int rt = RES_PREVIEW; /* TODO: Used without initialization, guessing. */
-	/* change sensor resolution if needed */
-	if (imx074_ctrl->curr_res != imx074_ctrl->pict_res) {
-		if (imx074_ctrl->pict_res == QTR_SIZE) {
-			rt = RES_PREVIEW;
-		} else {
-			rt = RES_CAPTURE;
-		}
-	}
-	if (imx074_sensor_setting(UPDATE_PERIODIC, rt) < 0)
-		return rc;
-	imx074_ctrl->curr_res = imx074_ctrl->pict_res;
-	imx074_ctrl->sensormode = mode;
-	return rc;
-}
-static int32_t imx074_raw_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-	int rt = RES_PREVIEW; /* TODO: Used without initialization, guessing. */
-	/* change sensor resolution if needed */
-	if (imx074_ctrl->curr_res != imx074_ctrl->pict_res) {
-		if (imx074_ctrl->pict_res == QTR_SIZE) {
-			rt = RES_PREVIEW;
-		} else {
-			rt = RES_CAPTURE;
-		}
-	}
-	if (imx074_sensor_setting(UPDATE_PERIODIC, rt) < 0)
-		return rc;
-	imx074_ctrl->curr_res = imx074_ctrl->pict_res;
-	imx074_ctrl->sensormode = mode;
-	return rc;
-}
-static int32_t imx074_set_sensor_mode(int mode,
-	int res)
-{
-	int32_t rc = 0;
-	switch (mode) {
-	case SENSOR_PREVIEW_MODE:
-		rc = imx074_video_config(mode);
-		break;
-	case SENSOR_SNAPSHOT_MODE:
-		rc = imx074_snapshot_config(mode);
-		break;
-	case SENSOR_RAW_SNAPSHOT_MODE:
-		rc = imx074_raw_snapshot_config(mode);
-		break;
-	default:
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
-static int32_t imx074_power_down(void)
-{
-	imx074_i2c_write_b_sensor(REG_MODE_SELECT,
-		MODE_SELECT_STANDBY_MODE);
-	msleep(imx074_delay_msecs_stdby);
-	return 0;
-}
-static int imx074_probe_init_done(const struct msm_camera_sensor_info *data)
-{
-	gpio_set_value_cansleep(data->sensor_reset, 0);
-	gpio_direction_input(data->sensor_reset);
-	gpio_free(data->sensor_reset);
-	return 0;
-}
-
-static int imx074_read_eeprom_data(struct sensor_cfg_data *cfg)
-{
-	int32_t rc = 0;
-	uint16_t eepromdata = 0;
-	uint8_t addr = 0;
-
-	addr = 0x10;
-	rc = imx074_i2c_read_w_eeprom(addr, &eepromdata);
-	if (rc < 0) {
-		CDBG("%s: Error Reading EEPROM @ 0x%x\n", __func__, addr);
-		return rc;
-	}
-	cfg->cfg.calib_info.r_over_g = eepromdata;
-
-	addr = 0x12;
-	rc = imx074_i2c_read_w_eeprom(addr, &eepromdata);
-	if (rc < 0) {
-		CDBG("%s: Error Reading EEPROM @ 0x%x\n", __func__, addr);
-		return rc;
-	}
-	cfg->cfg.calib_info.b_over_g = eepromdata;
-
-	addr = 0x14;
-	rc = imx074_i2c_read_w_eeprom(addr, &eepromdata);
-	if (rc < 0) {
-		CDBG("%s: Error Reading EEPROM @ 0x%x\n", __func__, addr);
-		return rc;
-	}
-	cfg->cfg.calib_info.gr_over_gb = eepromdata;
-
-	addr = 0x1A;
-	rc = imx074_i2c_read_w_eeprom(addr, &eepromdata);
-	if (rc < 0) {
-		CDBG("%s: Error Reading EEPROM @ 0x%x\n", __func__, addr);
-		return rc;
-	}
-	cfg->cfg.calib_info.macro_2_inf = eepromdata;
-
-	addr = 0x1C;
-	rc = imx074_i2c_read_w_eeprom(addr, &eepromdata);
-	if (rc < 0) {
-		CDBG("%s: Error Reading EEPROM @ 0x%x\n", __func__, addr);
-		return rc;
-	}
-	cfg->cfg.calib_info.inf_2_macro = eepromdata;
-
-	addr = 0x1E;
-	rc = imx074_i2c_read_w_eeprom(addr, &eepromdata);
-	if (rc < 0) {
-		CDBG("%s: Error Reading EEPROM @ 0x%x\n", __func__, addr);
-		return rc;
-	}
-	cfg->cfg.calib_info.stroke_amt = eepromdata;
-
-	addr = 0x20;
-	rc = imx074_i2c_read_w_eeprom(addr, &eepromdata);
-	if (rc < 0) {
-		CDBG("%s: Error Reading EEPROM @ 0x%x\n", __func__, addr);
-		return rc;
-	}
-	cfg->cfg.calib_info.af_pos_1m = eepromdata;
-
-	addr = 0x22;
-	rc = imx074_i2c_read_w_eeprom(addr, &eepromdata);
-	if (rc < 0) {
-		CDBG("%s: Error Reading EEPROM @ 0x%x\n", __func__, addr);
-		return rc;
-	}
-	cfg->cfg.calib_info.af_pos_inf = eepromdata;
-
-	return rc;
-}
-
-static int imx074_probe_init_sensor(const struct msm_camera_sensor_info *data)
-{
-	int32_t rc = 0;
-	unsigned short chipidl, chipidh;
-	CDBG("%s: %d\n", __func__, __LINE__);
-	rc = gpio_request(data->sensor_reset, "imx074");
-	CDBG(" imx074_probe_init_sensor \n");
-	if (!rc) {
-		CDBG("sensor_reset = %d\n", rc);
-		gpio_direction_output(data->sensor_reset, 0);
-		usleep_range(5000, 6000);
-		gpio_set_value_cansleep(data->sensor_reset, 1);
-		usleep_range(5000, 6000);
-	} else {
-		CDBG("gpio reset fail");
-		goto init_probe_done;
-	}
-	CDBG("imx074_probe_init_sensor is called\n");
-	/* 3. Read sensor Model ID: */
-	rc = imx074_i2c_read(0x0000, &chipidh, 1);
-	if (rc < 0) {
-		CDBG("Model read failed\n");
-		goto init_probe_fail;
-	}
-	rc = imx074_i2c_read(0x0001, &chipidl, 1);
-	if (rc < 0) {
-		CDBG("Model read failed\n");
-		goto init_probe_fail;
-	}
-	CDBG("imx074 model_id = 0x%x  0x%x\n", chipidh, chipidl);
-	/* 4. Compare sensor ID to IMX074 ID: */
-	if (chipidh != 0x00 || chipidl != 0x74) {
-		rc = -ENODEV;
-		CDBG("imx074_probe_init_sensor fail chip id doesnot match\n");
-		goto init_probe_fail;
-	}
-	goto init_probe_done;
-init_probe_fail:
-	CDBG("imx074_probe_init_sensor fails\n");
-	imx074_probe_init_done(data);
-init_probe_done:
-	CDBG(" imx074_probe_init_sensor finishes\n");
-	return rc;
-	}
-static int32_t imx074_poweron_af(void)
-{
-	int32_t rc = 0;
-	CDBG("imx074 enable AF actuator, gpio = %d\n",
-			imx074_ctrl->sensordata->vcm_pwd);
-	rc = gpio_request(imx074_ctrl->sensordata->vcm_pwd, "imx074");
-	if (!rc) {
-		gpio_direction_output(imx074_ctrl->sensordata->vcm_pwd, 1);
-		msleep(20);
-		rc = imx074_af_init();
-		if (rc < 0)
-			CDBG("imx074 AF initialisation failed\n");
-	} else {
-		CDBG("%s: AF PowerON gpio_request failed %d\n", __func__, rc);
-	 }
-	return rc;
-}
-static void imx074_poweroff_af(void)
-{
-	gpio_set_value_cansleep(imx074_ctrl->sensordata->vcm_pwd, 0);
-	gpio_free(imx074_ctrl->sensordata->vcm_pwd);
-}
-/* camsensor_iu060f_imx074_reset */
-int imx074_sensor_open_init(const struct msm_camera_sensor_info *data)
-{
-	int32_t rc = 0;
-	CDBG("%s: %d\n", __func__, __LINE__);
-	CDBG("Calling imx074_sensor_open_init\n");
-	imx074_ctrl = kzalloc(sizeof(struct imx074_ctrl_t), GFP_KERNEL);
-	if (!imx074_ctrl) {
-		CDBG("imx074_init failed!\n");
-		rc = -ENOMEM;
-		goto init_done;
-	}
-	imx074_ctrl->fps_divider = 1 * 0x00000400;
-	imx074_ctrl->pict_fps_divider = 1 * 0x00000400;
-	imx074_ctrl->fps = 30 * Q8;
-	imx074_ctrl->set_test = TEST_OFF;
-	imx074_ctrl->prev_res = QTR_SIZE;
-	imx074_ctrl->pict_res = FULL_SIZE;
-	imx074_ctrl->curr_res = INVALID_SIZE;
-	config_csi = 0;
-
-	if (data)
-		imx074_ctrl->sensordata = data;
-
-	/* enable mclk first */
-	msm_camio_clk_rate_set(IMX074_DEFAULT_MASTER_CLK_RATE);
-	usleep_range(1000, 2000);
-	rc = imx074_probe_init_sensor(data);
-	if (rc < 0) {
-		CDBG("Calling imx074_sensor_open_init fail\n");
-		goto probe_fail;
-	}
-
-	rc = imx074_sensor_setting(REG_INIT, RES_PREVIEW);
-	if (rc < 0) {
-		CDBG("imx074_sensor_setting failed\n");
-		goto init_fail;
-	}
-	if (machine_is_msm8x60_fluid())
-		rc = imx074_poweron_af();
-	else
-		rc = imx074_af_init();
-	if (rc < 0) {
-		CDBG("AF initialisation failed\n");
-		goto init_fail;
-	} else
-		goto init_done;
-probe_fail:
-	CDBG(" imx074_sensor_open_init probe fail\n");
-	kfree(imx074_ctrl);
-	return rc;
-init_fail:
-	CDBG(" imx074_sensor_open_init fail\n");
-	imx074_probe_init_done(data);
-	kfree(imx074_ctrl);
-init_done:
-	CDBG("imx074_sensor_open_init done\n");
-	return rc;
-}
-static int imx074_init_client(struct i2c_client *client)
-{
-	/* Initialize the MSM_CAMI2C Chip */
-	init_waitqueue_head(&imx074_wait_queue);
-	return 0;
-}
-
-static const struct i2c_device_id imx074_i2c_id[] = {
-	{"imx074", 0},
-	{ }
-};
-
-static int imx074_i2c_probe(struct i2c_client *client,
-	const struct i2c_device_id *id)
-{
-	int rc = 0;
-	CDBG("imx074_probe called!\n");
-
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		CDBG("i2c_check_functionality failed\n");
-		goto probe_failure;
-	}
-
-	imx074_sensorw = kzalloc(sizeof(struct imx074_work_t), GFP_KERNEL);
-	if (!imx074_sensorw) {
-		CDBG("kzalloc failed.\n");
-		rc = -ENOMEM;
-		goto probe_failure;
-	}
-
-	i2c_set_clientdata(client, imx074_sensorw);
-	imx074_init_client(client);
-	imx074_client = client;
-
-
-	CDBG("imx074_probe successed! rc = %d\n", rc);
-	return 0;
-
-probe_failure:
-	CDBG("imx074_probe failed! rc = %d\n", rc);
-	return rc;
-}
-
-static int __exit imx074_remove(struct i2c_client *client)
-{
-	struct imx074_work_t_t *sensorw = i2c_get_clientdata(client);
-	free_irq(client->irq, sensorw);
-	imx074_client = NULL;
-	kfree(sensorw);
-	return 0;
-}
-
-static struct i2c_driver imx074_i2c_driver = {
-	.id_table = imx074_i2c_id,
-	.probe  = imx074_i2c_probe,
-	.remove = __exit_p(imx074_i2c_remove),
-	.driver = {
-		.name = "imx074",
-	},
-};
-
-int imx074_sensor_config(void __user *argp)
-{
-	struct sensor_cfg_data cdata;
-	long   rc = 0;
-	if (copy_from_user(&cdata,
-		(void *)argp,
-		sizeof(struct sensor_cfg_data)))
-		return -EFAULT;
-	mutex_lock(&imx074_mut);
-	CDBG("imx074_sensor_config: cfgtype = %d\n",
-	cdata.cfgtype);
-	switch (cdata.cfgtype) {
-	case CFG_GET_PICT_FPS:
-		imx074_get_pict_fps(
-			cdata.cfg.gfps.prevfps,
-			&(cdata.cfg.gfps.pictfps));
-		if (copy_to_user((void *)argp,
-			&cdata,
-			sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-			break;
-	case CFG_GET_PREV_L_PF:
-		cdata.cfg.prevl_pf =
-			imx074_get_prev_lines_pf();
-		if (copy_to_user((void *)argp,
-			&cdata,
-			sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-			break;
-	case CFG_GET_PREV_P_PL:
-		cdata.cfg.prevp_pl =
-			imx074_get_prev_pixels_pl();
-		if (copy_to_user((void *)argp,
-			&cdata,
-			sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-			break;
-
-	case CFG_GET_PICT_L_PF:
-		cdata.cfg.pictl_pf =
-			imx074_get_pict_lines_pf();
-		if (copy_to_user((void *)argp,
-			&cdata,
-			sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-			break;
-	case CFG_GET_PICT_P_PL:
-		cdata.cfg.pictp_pl =
-			imx074_get_pict_pixels_pl();
-		if (copy_to_user((void *)argp,
-			&cdata,
-			sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-			break;
-	case CFG_GET_PICT_MAX_EXP_LC:
-		cdata.cfg.pict_max_exp_lc =
-			imx074_get_pict_max_exp_lc();
-		if (copy_to_user((void *)argp,
-			&cdata,
-			sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-			break;
-	case CFG_SET_FPS:
-	case CFG_SET_PICT_FPS:
-		rc = imx074_set_fps(&(cdata.cfg.fps));
-		break;
-	case CFG_SET_EXP_GAIN:
-		rc =
-			imx074_write_exp_gain(
-			cdata.cfg.exp_gain.gain,
-			cdata.cfg.exp_gain.line);
-			break;
-	case CFG_SET_PICT_EXP_GAIN:
-		rc =
-			imx074_set_pict_exp_gain(
-			cdata.cfg.exp_gain.gain,
-			cdata.cfg.exp_gain.line);
-			break;
-	case CFG_SET_MODE:
-		rc = imx074_set_sensor_mode(cdata.mode,
-			cdata.rs);
-			break;
-	case CFG_PWR_DOWN:
-		rc = imx074_power_down();
-			break;
-	case CFG_GET_CALIB_DATA:
-		rc = imx074_read_eeprom_data(&cdata);
-		if (rc < 0)
-			break;
-		if (copy_to_user((void *)argp,
-			&cdata,
-			sizeof(cdata)))
-			rc = -EFAULT;
-		break;
-	case CFG_MOVE_FOCUS:
-		rc =
-			imx074_move_focus(
-			cdata.cfg.focus.dir,
-			cdata.cfg.focus.steps);
-			break;
-	case CFG_SET_DEFAULT_FOCUS:
-		rc =
-			imx074_set_default_focus(
-			cdata.cfg.focus.steps);
-			break;
-	case CFG_GET_AF_MAX_STEPS:
-		cdata.max_steps = IMX074_STEPS_NEAR_TO_CLOSEST_INF;
-		if (copy_to_user((void *)argp,
-			&cdata,
-			sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-			break;
-	case CFG_SET_EFFECT:
-	default:
-		rc = -EFAULT;
-		break;
-	}
-
-	mutex_unlock(&imx074_mut);
-
-	return rc;
-}
-static int imx074_sensor_release(void)
-{
-	int rc = -EBADF;
-	mutex_lock(&imx074_mut);
-	if (machine_is_msm8x60_fluid())
-		imx074_poweroff_af();
-	imx074_power_down();
-	gpio_set_value_cansleep(imx074_ctrl->sensordata->sensor_reset, 0);
-	msleep(5);
-	gpio_direction_input(imx074_ctrl->sensordata->sensor_reset);
-	gpio_free(imx074_ctrl->sensordata->sensor_reset);
-	kfree(imx074_ctrl);
-	imx074_ctrl = NULL;
-	CDBG("imx074_release completed\n");
-	mutex_unlock(&imx074_mut);
-
-	return rc;
-}
-
-static int imx074_sensor_probe(const struct msm_camera_sensor_info *info,
-		struct msm_sensor_ctrl *s)
-{
-	int rc = 0;
-	rc = i2c_add_driver(&imx074_i2c_driver);
-	if (rc < 0 || imx074_client == NULL) {
-		rc = -ENOTSUPP;
-		goto probe_fail;
-	}
-	msm_camio_clk_rate_set(IMX074_DEFAULT_MASTER_CLK_RATE);
-	rc = imx074_probe_init_sensor(info);
-	if (rc < 0)
-		goto probe_fail;
-	s->s_init = imx074_sensor_open_init;
-	s->s_release = imx074_sensor_release;
-	s->s_config  = imx074_sensor_config;
-	s->s_mount_angle = info->sensor_platform_info->mount_angle;
-	imx074_probe_init_done(info);
-	return rc;
-
-probe_fail:
-	CDBG("imx074_sensor_probe: SENSOR PROBE FAILS!\n");
-	i2c_del_driver(&imx074_i2c_driver);
-	return rc;
-}
-
-static int __imx074_probe(struct platform_device *pdev)
-{
-
-	return msm_camera_drv_start(pdev, imx074_sensor_probe);
-}
-
-static struct platform_driver msm_camera_driver = {
-	.probe = __imx074_probe,
-	.driver = {
-		.name = "msm_camera_imx074",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init imx074_init(void)
-{
-	return platform_driver_register(&msm_camera_driver);
-}
-
-module_init(imx074_init);
-
-MODULE_DESCRIPTION("Sony 13 MP Bayer sensor driver");
-MODULE_LICENSE("GPL v2");
-
diff --git a/drivers/media/video/msm/imx074.h b/drivers/media/video/msm/imx074.h
deleted file mode 100644
index 8be0fb7..0000000
--- a/drivers/media/video/msm/imx074.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. 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 IMX074_H
-#define IMX074_H
-#include <linux/types.h>
-#include <mach/board.h>
-extern struct imx074_reg imx074_regs;
-struct reg_struct_init {
-    /* PLL setting */
-	uint8_t pre_pll_clk_div; /* 0x0305 */
-	uint8_t plstatim; /* 0x302b */
-	uint8_t reg_3024; /*ox3024*/
-	uint8_t image_orientation;  /* 0x0101*/
-	uint8_t vndmy_ablmgshlmt; /*0x300a*/
-	uint8_t y_opbaddr_start_di; /*0x3014*/
-	uint8_t reg_0x3015; /*0x3015*/
-	uint8_t reg_0x301c; /*0x301c*/
-	uint8_t reg_0x302c; /*0x302c*/
-	uint8_t reg_0x3031; /*0x3031*/
-	uint8_t reg_0x3041; /* 0x3041 */
-	uint8_t reg_0x3051; /* 0x3051 */
-	uint8_t reg_0x3053; /* 0x3053 */
-	uint8_t reg_0x3057; /* 0x3057 */
-	uint8_t reg_0x305c; /* 0x305c */
-	uint8_t reg_0x305d; /* 0x305d */
-	uint8_t reg_0x3060; /* 0x3060 */
-	uint8_t reg_0x3065; /* 0x3065 */
-	uint8_t reg_0x30aa; /* 0x30aa */
-	uint8_t reg_0x30ab;
-	uint8_t reg_0x30b0;
-	uint8_t reg_0x30b2;
-	uint8_t reg_0x30d3;
-	uint8_t reg_0x3106;
-	uint8_t reg_0x310c;
-	uint8_t reg_0x3304;
-	uint8_t reg_0x3305;
-	uint8_t reg_0x3306;
-	uint8_t reg_0x3307;
-	uint8_t reg_0x3308;
-	uint8_t reg_0x3309;
-	uint8_t reg_0x330a;
-	uint8_t reg_0x330b;
-	uint8_t reg_0x330c;
-	uint8_t reg_0x330d;
-	uint8_t reg_0x330f;
-	uint8_t reg_0x3381;
-};
-
-struct reg_struct {
-	uint8_t pll_multiplier; /* 0x0307 */
-	uint8_t frame_length_lines_hi; /* 0x0340*/
-	uint8_t frame_length_lines_lo; /* 0x0341*/
-	uint8_t y_addr_start;  /* 0x347 */
-	uint8_t y_add_end;  /* 0x034b */
-	uint8_t x_output_size_msb;  /* 0x034c */
-	uint8_t x_output_size_lsb;  /* 0x034d */
-	uint8_t y_output_size_msb; /* 0x034e */
-	uint8_t y_output_size_lsb; /* 0x034f */
-	uint8_t x_even_inc;  /* 0x0381 */
-	uint8_t x_odd_inc; /* 0x0383 */
-	uint8_t y_even_inc;  /* 0x0385 */
-	uint8_t y_odd_inc; /* 0x0387 */
-	uint8_t hmodeadd;   /* 0x3001 */
-	uint8_t vmodeadd;   /* 0x3016 */
-	uint8_t vapplinepos_start;/*ox3069*/
-	uint8_t vapplinepos_end;/*306b*/
-	uint8_t shutter;	/* 0x3086 */
-	uint8_t haddave;	/* 0x30e8 */
-	uint8_t lanesel;    /* 0x3301 */
-};
-
-struct imx074_i2c_reg_conf {
-	unsigned short waddr;
-	unsigned short wdata;
-};
-
-enum imx074_test_mode_t {
-	TEST_OFF,
-	TEST_1,
-	TEST_2,
-	TEST_3
-};
-
-enum imx074_resolution_t {
-	QTR_SIZE,
-	FULL_SIZE,
-	INVALID_SIZE
-};
-enum imx074_setting {
-	RES_PREVIEW,
-	RES_CAPTURE
-};
-enum mt9p012_reg_update {
-	/* Sensor egisters that need to be updated during initialization */
-	REG_INIT,
-	/* Sensor egisters that needs periodic I2C writes */
-	UPDATE_PERIODIC,
-	/* All the sensor Registers will be updated */
-	UPDATE_ALL,
-	/* Not valid update */
-	UPDATE_INVALID
-};
-
-struct imx074_reg {
-	const struct reg_struct_init  *reg_pat_init;
-	const struct reg_struct  *reg_pat;
-};
-#endif /* IMX074_H */
diff --git a/drivers/media/video/msm/imx074_reg.c b/drivers/media/video/msm/imx074_reg.c
deleted file mode 100644
index ccc9b2f..0000000
--- a/drivers/media/video/msm/imx074_reg.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. 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 "imx074.h"
-const struct reg_struct_init imx074_reg_init[1] = {
-	{
-		/* PLL setting */
-		0x02,	/* pll_divider 0x0305 */
-		0x4B,	/* plstatim 0x302b */
-		0x03,	/* reg_3024 */
-		0x00,	/* image_orientation 0x0101 */
-		0x80,	/* vndmy_ablmgshlmt 0x300a*/
-		0x08,	/* y_opbaddr_start_di 3014*/
-		0x37,	/* 0x3015*/
-		0x01,	/* 0x301c*/
-		0x05,	/* 0x302c*/
-		0x26,	/* 0x3031*/
-		0x60,	/* 0x3041*/
-		0x24,	/* 0x3051 CLK DIV*/
-		0x34,	/* 0x3053*/
-		0xc0,	/* 0x3057*/
-		0x09,	/* 0x305c*/
-		0x07,	/* 0x305d */
-		0x30,	/* 0x3060 */
-		0x00,	/* 0x3065 */
-		0x08,	/* 0x30aa */
-		0x1c,	/* 0x30ab */
-		0x32,	/* 0x30b0 */
-		0x83,	/* 0x30b2 */
-		0x04,	/* 0x30d3 */
-		0x78,	/* 0x3106 */
-		0x82,	/* 0x310c */
-		0x05,	/* 0x3304 */
-		0x04,	/* 0x3305 */
-		0x11,	/* 0x3306 */
-		0x02,	/* 0x3307 */
-		0x0c,	/* 0x3308 */
-		0x06,	/* 0x3309 */
-		0x08,	/* 0x330a */
-		0x04,	/* 0x330b */
-		0x08,	/* 0x330c */
-		0x06,	/* 0x330d */
-		0x01,	/* 0x330f */
-		0x00,	/* 0x3381 */
-
-	}
-};
-
-/* Preview / Snapshot register settings	*/
-const struct reg_struct	imx074_reg_pat[2] = {
-	/*preview*/
-	{
-		0x2D, /*pll_multiplier*/
-		0x06, /*frame_length_lines_hi 0x0340*/
-		0x2D, /* frame_length_lines_lo 0x0341*/
-		0x00, /* y_addr_start 0x347 */
-		0x2F, /* y_add_end 0x034b */
-		0x08, /* x_output_size_msb0x034c */
-		0x38, /* x_output_size_lsb0x034d */
-		0x06, /*  y_output_size_msb0x034e */
-		0x18, /*  y_output_size_lsb0x034f */
-		0x01, /* x_even_inc 0x0381 */
-		0x03, /* x_odd_inc 0x0383 */
-		0x01, /* y_even_inc 0x0385 */
-		0x03, /* y_odd_inc 0x0387 */
-		0x80, /* hmodeadd0x3001 */
-		0x16, /* vmodeadd0x3016 */
-		0x24, /* vapplinepos_startox3069*/
-		0x53, /* vapplinepos_end306b*/
-		0x00,/*  shutter 0x3086 */
-		0x80, /* haddave 0x30e8 */
-		0x83, /* lanesel 0x3301 */
-	},
-
-	/*snapshot*/
-	{
-		0x26, /*pll_multiplier*/
-		0x0C, /* frame_length_lines_hi 0x0340*/
-		0x90, /* frame_length_lines_lo 0x0341*/
-		0x00, /* y_addr_start 0x347 */
-		0x2F, /* y_add_end 0x034b */
-		0x10, /* x_output_size_msb0x034c */
-		0x70, /* x_output_size_lsb0x034d */
-		0x0c, /* y_output_size_msb0x034e */
-		0x30, /* y_output_size_lsb0x034f */
-		0x01, /* x_even_inc 0x0381 */
-		0x01, /* x_odd_inc 0x0383 */
-		0x01, /* y_even_inc 0x0385 */
-		0x01, /* y_odd_inc 0x0387 */
-		0x00, /* hmodeadd0x3001 */
-		0x06, /* vmodeadd0x3016 */
-		0x24, /* vapplinepos_startox3069*/
-		0x53, /* vapplinepos_end306b*/
-		0x00, /* shutter 0x3086 */
-		0x00, /* haddave 0x30e8 */
-		0x03, /* lanesel 0x3301 */
-	}
-};
-struct imx074_reg imx074_regs = {
-	.reg_pat_init = &imx074_reg_init[0],
-	.reg_pat = &imx074_reg_pat[0],
-};
diff --git a/drivers/media/video/msm/io/Makefile b/drivers/media/video/msm/io/Makefile
deleted file mode 100644
index fdff226..0000000
--- a/drivers/media/video/msm/io/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
-
-ccflags-y += -Idrivers/media/video/msm -Idrivers/media/video/msm/cci
-obj-$(CONFIG_MSM_CAMERA)   += msm_camera_io_util.o msm_camera_i2c.o
-ifeq ($(CONFIG_MSM_CAMERA_V4L2),y)
-  obj-$(CONFIG_MSM_CAMERA) += msm_camera_i2c_mux.o
-  obj-$(CONFIG_ARCH_MSM7X27A) += msm_io_7x27a_v4l2.o
-  obj-$(CONFIG_ARCH_MSM8X60) += msm_io_vfe31_v4l2.o
-  obj-$(CONFIG_ARCH_MSM7X30) += msm_io_vfe31_v4l2.o
-else
-  obj-$(CONFIG_ARCH_MSM7X27A) += msm_io_7x27a.o
-  obj-$(CONFIG_ARCH_MSM8X60) += msm_io_8x60.o
-  obj-$(CONFIG_ARCH_MSM7X30) += msm_io_vfe31.o
-endif
-obj-$(CONFIG_ARCH_MSM_ARM11) += msm_io7x.o
-obj-$(CONFIG_ARCH_QSD8X50) += msm_io8x.o
-obj-$(CONFIG_ARCH_MSM8960) += msm_io_8960.o
diff --git a/drivers/media/video/msm/io/msm_camera_i2c.c b/drivers/media/video/msm/io/msm_camera_i2c.c
deleted file mode 100644
index 9e4fcd1..0000000
--- a/drivers/media/video/msm/io/msm_camera_i2c.c
+++ /dev/null
@@ -1,606 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. 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 <mach/camera.h>
-#include "msm_camera_i2c.h"
-#include "msm.h"
-#include "msm_cci.h"
-
-int32_t msm_camera_i2c_rxdata(struct msm_camera_i2c_client *dev_client,
-	unsigned char *rxdata, int data_length)
-{
-	int32_t rc = 0;
-	uint16_t saddr = dev_client->client->addr >> 1;
-	struct i2c_msg msgs[] = {
-		{
-			.addr  = saddr,
-			.flags = 0,
-			.len   = dev_client->addr_type,
-			.buf   = rxdata,
-		},
-		{
-			.addr  = saddr,
-			.flags = I2C_M_RD,
-			.len   = data_length,
-			.buf   = rxdata,
-		},
-	};
-	rc = i2c_transfer(dev_client->client->adapter, msgs, 2);
-	if (rc < 0)
-		S_I2C_DBG("msm_camera_i2c_rxdata failed 0x%x\n", saddr);
-	return rc;
-}
-
-int32_t msm_camera_i2c_txdata(struct msm_camera_i2c_client *dev_client,
-				unsigned char *txdata, int length)
-{
-	int32_t rc = 0;
-	uint16_t saddr = dev_client->client->addr >> 1;
-	struct i2c_msg msg[] = {
-		{
-			.addr = saddr,
-			.flags = 0,
-			.len = length,
-			.buf = txdata,
-		 },
-	};
-	rc = i2c_transfer(dev_client->client->adapter, msg, 1);
-	if (rc < 0)
-		S_I2C_DBG("msm_camera_i2c_txdata faild 0x%x\n", saddr);
-	return 0;
-}
-
-int32_t msm_camera_i2c_write(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t data,
-	enum msm_camera_i2c_data_type data_type)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[client->addr_type+data_type];
-	uint8_t len = 0;
-
-	if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
-		&& client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
-		|| (data_type != MSM_CAMERA_I2C_BYTE_DATA
-		&& data_type != MSM_CAMERA_I2C_WORD_DATA))
-		return rc;
-
-	S_I2C_DBG("%s reg addr = 0x%x data type: %d\n",
-			  __func__, addr, data_type);
-	if (client->cci_client) {
-		struct msm_camera_cci_ctrl cci_ctrl;
-		struct msm_camera_i2c_reg_conf reg_conf_tbl;
-		reg_conf_tbl.reg_addr = addr;
-		reg_conf_tbl.reg_data = data;
-		cci_ctrl.cmd = MSM_CCI_I2C_WRITE;
-		cci_ctrl.cci_info = client->cci_client;
-		cci_ctrl.cfg.cci_i2c_write_cfg.reg_conf_tbl = &reg_conf_tbl;
-		cci_ctrl.cfg.cci_i2c_write_cfg.data_type = data_type;
-		cci_ctrl.cfg.cci_i2c_write_cfg.addr_type = client->addr_type;
-		cci_ctrl.cfg.cci_i2c_write_cfg.size = 1;
-		rc = v4l2_subdev_call(client->cci_client->cci_subdev,
-				core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl);
-		CDBG("%s line %d rc = %d\n", __func__, __LINE__, rc);
-		rc = cci_ctrl.status;
-	} else {
-		if (client->addr_type == MSM_CAMERA_I2C_BYTE_ADDR) {
-			buf[0] = addr;
-			S_I2C_DBG("%s byte %d: 0x%x\n", __func__,
-				len, buf[len]);
-			len = 1;
-		} else if (client->addr_type == MSM_CAMERA_I2C_WORD_ADDR) {
-			buf[0] = addr >> BITS_PER_BYTE;
-			buf[1] = addr;
-			S_I2C_DBG("%s byte %d: 0x%x\n", __func__,
-				len, buf[len]);
-			S_I2C_DBG("%s byte %d: 0x%x\n", __func__,
-				len+1, buf[len+1]);
-			len = 2;
-		}
-		S_I2C_DBG("Data: 0x%x\n", data);
-		if (data_type == MSM_CAMERA_I2C_BYTE_DATA) {
-			buf[len] = data;
-			S_I2C_DBG("Byte %d: 0x%x\n", len, buf[len]);
-			len += 1;
-		} else if (data_type == MSM_CAMERA_I2C_WORD_DATA) {
-			buf[len] = data >> BITS_PER_BYTE;
-			buf[len+1] = data;
-			S_I2C_DBG("Byte %d: 0x%x\n", len, buf[len]);
-			S_I2C_DBG("Byte %d: 0x%x\n", len+1, buf[len+1]);
-			len += 2;
-		}
-		rc = msm_camera_i2c_txdata(client, buf, len);
-		if (rc < 0)
-			S_I2C_DBG("%s fail\n", __func__);
-	}
-	return rc;
-}
-
-int32_t msm_camera_i2c_write_seq(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint8_t *data, uint16_t num_byte)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[client->addr_type+num_byte];
-	uint8_t len = 0, i = 0;
-
-	if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
-		&& client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
-		|| num_byte == 0)
-		return rc;
-
-	S_I2C_DBG("%s reg addr = 0x%x num bytes: %d\n",
-			  __func__, addr, num_byte);
-	if (client->cci_client) {
-		struct msm_camera_cci_ctrl cci_ctrl;
-		struct msm_camera_i2c_reg_conf reg_conf_tbl[num_byte];
-		reg_conf_tbl[0].reg_addr = addr;
-		for (i = 0; i < num_byte; i++)
-			reg_conf_tbl[i].reg_data = data[i];
-		cci_ctrl.cmd = MSM_CCI_I2C_WRITE;
-		cci_ctrl.cci_info = client->cci_client;
-		cci_ctrl.cfg.cci_i2c_write_cfg.reg_conf_tbl = reg_conf_tbl;
-		cci_ctrl.cfg.cci_i2c_write_cfg.size = num_byte;
-		rc = v4l2_subdev_call(client->cci_client->cci_subdev,
-				core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl);
-		CDBG("%s line %d rc = %d\n", __func__, __LINE__, rc);
-		rc = cci_ctrl.status;
-	} else {
-		if (client->addr_type == MSM_CAMERA_I2C_BYTE_ADDR) {
-			buf[0] = addr;
-			S_I2C_DBG("%s byte %d: 0x%x\n", __func__,
-				len, buf[len]);
-			len = 1;
-		} else if (client->addr_type == MSM_CAMERA_I2C_WORD_ADDR) {
-			buf[0] = addr >> BITS_PER_BYTE;
-			buf[1] = addr;
-			S_I2C_DBG("%s byte %d: 0x%x\n", __func__,
-				len, buf[len]);
-			S_I2C_DBG("%s byte %d: 0x%x\n", __func__,
-				len+1, buf[len+1]);
-			len = 2;
-		}
-		for (i = 0; i < num_byte; i++) {
-			buf[i+len] = data[i];
-			S_I2C_DBG("Byte %d: 0x%x\n", i+len, buf[i+len]);
-			S_I2C_DBG("Data: 0x%x\n", data[i]);
-		}
-		rc = msm_camera_i2c_txdata(client, buf, len+num_byte);
-		if (rc < 0)
-			S_I2C_DBG("%s fail\n", __func__);
-	}
-	return rc;
-}
-
-int32_t msm_camera_i2c_set_mask(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t mask,
-	enum msm_camera_i2c_data_type data_type, uint16_t set_mask)
-{
-	int32_t rc;
-	uint16_t reg_data;
-
-	rc = msm_camera_i2c_read(client, addr, &reg_data, data_type);
-	if (rc < 0) {
-		S_I2C_DBG("%s read fail\n", __func__);
-		return rc;
-	}
-	S_I2C_DBG("%s addr: 0x%x data: 0x%x setmask: 0x%x\n",
-			__func__, addr, reg_data, mask);
-
-	if (set_mask)
-		reg_data |= mask;
-	else
-		reg_data &= ~mask;
-	S_I2C_DBG("%s write: 0x%x\n", __func__, reg_data);
-
-	rc = msm_camera_i2c_write(client, addr, reg_data, data_type);
-	if (rc < 0)
-		S_I2C_DBG("%s write fail\n", __func__);
-
-	return rc;
-}
-int32_t msm_camera_i2c_set_write_mask_data(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t data, int16_t mask,
-	enum msm_camera_i2c_data_type data_type)
-{
-	int32_t rc;
-	uint16_t reg_data;
-	CDBG("%s\n", __func__);
-	if (mask == -1)
-		return 0;
-	if (mask == 0)
-		rc = msm_camera_i2c_write(client, addr, data, data_type);
-	else{
-		rc = msm_camera_i2c_read(client, addr, &reg_data, data_type);
-		if (rc < 0) {
-			CDBG("%s read fail\n", __func__);
-			return rc;
-		}
-		reg_data  = reg_data & mask;
-		reg_data  = (reg_data | (data & (~mask)));
-		rc = msm_camera_i2c_write(client, addr, reg_data, data_type);
-		if (rc < 0)
-			CDBG("%s write fail\n", __func__);
-	}
-	return rc;
-}
-
-int32_t msm_camera_i2c_compare(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t data,
-	enum msm_camera_i2c_data_type data_type)
-{
-	int32_t rc = -EIO;
-	uint16_t reg_data = 0;
-	int data_len = 0;
-	switch (data_type) {
-	case MSM_CAMERA_I2C_BYTE_DATA:
-	case MSM_CAMERA_I2C_WORD_DATA:
-		data_len = data_type;
-		break;
-	case MSM_CAMERA_I2C_SET_BYTE_MASK:
-	case MSM_CAMERA_I2C_UNSET_BYTE_MASK:
-		data_len = MSM_CAMERA_I2C_BYTE_DATA;
-		break;
-	case MSM_CAMERA_I2C_SET_WORD_MASK:
-	case MSM_CAMERA_I2C_UNSET_WORD_MASK:
-		data_len = MSM_CAMERA_I2C_WORD_DATA;
-		break;
-	default:
-		pr_err("%s: Unsupport data type: %d\n", __func__, data_type);
-		break;
-	}
-
-	rc = msm_camera_i2c_read(client,
-		addr, &reg_data, data_len);
-	if (rc < 0)
-		return rc;
-
-	rc = 0;
-	switch (data_type) {
-	case MSM_CAMERA_I2C_BYTE_DATA:
-	case MSM_CAMERA_I2C_WORD_DATA:
-		if (data == reg_data)
-			return rc;
-		break;
-	case MSM_CAMERA_I2C_SET_BYTE_MASK:
-	case MSM_CAMERA_I2C_SET_WORD_MASK:
-		if ((reg_data & data) == data)
-			return rc;
-		break;
-	case MSM_CAMERA_I2C_UNSET_BYTE_MASK:
-	case MSM_CAMERA_I2C_UNSET_WORD_MASK:
-		if (!(reg_data & data))
-			return rc;
-		break;
-	default:
-		pr_err("%s: Unsupport data type: %d\n", __func__, data_type);
-		break;
-	}
-
-	S_I2C_DBG("%s: Register and data does not match\n", __func__);
-	rc = 1;
-	return rc;
-}
-
-int32_t msm_camera_i2c_poll(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t data,
-	enum msm_camera_i2c_data_type data_type)
-{
-	int32_t rc = -EIO;
-	int i;
-	S_I2C_DBG("%s: addr: 0x%x data: 0x%x dt: %d\n",
-		__func__, addr, data, data_type);
-
-	for (i = 0; i < 20; i++) {
-		rc = msm_camera_i2c_compare(client,
-			addr, data, data_type);
-		if (rc == 0 || rc < 0)
-			break;
-		usleep_range(10000, 11000);
-	}
-	return rc;
-}
-
-int32_t msm_camera_i2c_write_table_w_microdelay(
-	struct msm_camera_i2c_client *client,
-	struct msm_camera_i2c_reg_tbl *reg_tbl, uint16_t size,
-	enum msm_camera_i2c_data_type data_type)
-{
-	int i;
-	int32_t rc = -EFAULT;
-
-	if (!client || !reg_tbl)
-		return rc;
-
-	if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
-		&& client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
-		|| (data_type != MSM_CAMERA_I2C_BYTE_DATA
-		&& data_type != MSM_CAMERA_I2C_WORD_DATA))
-		return rc;
-
-	for (i = 0; i < size; i++) {
-		rc = msm_camera_i2c_write(client, reg_tbl->reg_addr,
-			reg_tbl->reg_data, data_type);
-		if (rc < 0)
-			break;
-		if (reg_tbl->delay)
-			usleep_range(reg_tbl->delay, reg_tbl->delay + 1000);
-		reg_tbl++;
-	}
-	return rc;
-}
-
-int32_t msm_camera_i2c_write_bayer_table(
-	struct msm_camera_i2c_client *client,
-	struct msm_camera_i2c_reg_setting *write_setting)
-{
-	int i;
-	int32_t rc = -EFAULT;
-	struct msm_camera_i2c_reg_array *reg_setting;
-
-	if (!client || !write_setting)
-		return rc;
-
-	reg_setting = write_setting->reg_setting;
-	client->addr_type = write_setting->addr_type;
-	if ((write_setting->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
-		&& write_setting->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
-		|| (write_setting->data_type != MSM_CAMERA_I2C_BYTE_DATA
-		&& write_setting->data_type != MSM_CAMERA_I2C_WORD_DATA))
-		return rc;
-	for (i = 0; i < write_setting->size; i++) {
-		rc = msm_camera_i2c_write(client, reg_setting->reg_addr,
-			reg_setting->reg_data, write_setting->data_type);
-		if (rc < 0)
-			break;
-		reg_setting++;
-	}
-	if (write_setting->delay > 20)
-		msleep(write_setting->delay);
-	else if (write_setting->delay)
-		usleep_range(write_setting->delay * 1000, (write_setting->delay
-			* 1000) + 1000);
-	return rc;
-}
-
-int32_t msm_camera_i2c_write_tbl(struct msm_camera_i2c_client *client,
-	struct msm_camera_i2c_reg_conf *reg_conf_tbl, uint16_t size,
-	enum msm_camera_i2c_data_type data_type)
-{
-	int i;
-	int32_t rc = -EFAULT;
-	for (i = 0; i < size; i++) {
-		enum msm_camera_i2c_data_type dt;
-		if (reg_conf_tbl->cmd_type == MSM_CAMERA_I2C_CMD_POLL) {
-			rc = msm_camera_i2c_poll(client,
-				reg_conf_tbl->reg_addr,
-				reg_conf_tbl->reg_data,
-				reg_conf_tbl->dt);
-		} else {
-			if (reg_conf_tbl->dt == 0)
-				dt = data_type;
-			else
-				dt = reg_conf_tbl->dt;
-			switch (dt) {
-			case MSM_CAMERA_I2C_BYTE_DATA:
-			case MSM_CAMERA_I2C_WORD_DATA:
-				rc = msm_camera_i2c_write(
-					client,
-					reg_conf_tbl->reg_addr,
-					reg_conf_tbl->reg_data, dt);
-				break;
-			case MSM_CAMERA_I2C_SET_BYTE_MASK:
-				rc = msm_camera_i2c_set_mask(client,
-					reg_conf_tbl->reg_addr,
-					reg_conf_tbl->reg_data,
-					MSM_CAMERA_I2C_BYTE_DATA, 1);
-				break;
-			case MSM_CAMERA_I2C_UNSET_BYTE_MASK:
-				rc = msm_camera_i2c_set_mask(client,
-					reg_conf_tbl->reg_addr,
-					reg_conf_tbl->reg_data,
-					MSM_CAMERA_I2C_BYTE_DATA, 0);
-				break;
-			case MSM_CAMERA_I2C_SET_WORD_MASK:
-				rc = msm_camera_i2c_set_mask(client,
-					reg_conf_tbl->reg_addr,
-					reg_conf_tbl->reg_data,
-					MSM_CAMERA_I2C_WORD_DATA, 1);
-				break;
-			case MSM_CAMERA_I2C_UNSET_WORD_MASK:
-				rc = msm_camera_i2c_set_mask(client,
-					reg_conf_tbl->reg_addr,
-					reg_conf_tbl->reg_data,
-					MSM_CAMERA_I2C_WORD_DATA, 0);
-				break;
-			case MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA:
-				rc = msm_camera_i2c_set_write_mask_data(
-					client,
-					reg_conf_tbl->reg_addr,
-					reg_conf_tbl->reg_data,
-					reg_conf_tbl->mask,
-					MSM_CAMERA_I2C_BYTE_DATA);
-				break;
-			default:
-				pr_err("%s: Unsupport data type: %d\n",
-					__func__, dt);
-				break;
-			}
-		}
-		if (rc < 0)
-			break;
-		reg_conf_tbl++;
-	}
-	return rc;
-}
-
-int32_t msm_camera_i2c_read(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t *data,
-	enum msm_camera_i2c_data_type data_type)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[client->addr_type+data_type];
-
-	if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
-		&& client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
-		|| (data_type != MSM_CAMERA_I2C_BYTE_DATA
-		&& data_type != MSM_CAMERA_I2C_WORD_DATA))
-		return rc;
-
-	if (client->cci_client) {
-		struct msm_camera_cci_ctrl cci_ctrl;
-		cci_ctrl.cmd = MSM_CCI_I2C_READ;
-		cci_ctrl.cci_info = client->cci_client;
-		cci_ctrl.cfg.cci_i2c_read_cfg.addr = addr;
-		cci_ctrl.cfg.cci_i2c_read_cfg.addr_type = client->addr_type;
-		cci_ctrl.cfg.cci_i2c_read_cfg.data = buf;
-		cci_ctrl.cfg.cci_i2c_read_cfg.num_byte = data_type;
-		rc = v4l2_subdev_call(client->cci_client->cci_subdev,
-				core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl);
-		CDBG("%s line %d rc = %d\n", __func__, __LINE__, rc);
-		rc = cci_ctrl.status;
-	} else {
-		if (client->addr_type == MSM_CAMERA_I2C_BYTE_ADDR) {
-			buf[0] = addr;
-		} else if (client->addr_type == MSM_CAMERA_I2C_WORD_ADDR) {
-			buf[0] = addr >> BITS_PER_BYTE;
-			buf[1] = addr;
-		}
-		rc = msm_camera_i2c_rxdata(client, buf, data_type);
-		if (rc < 0) {
-			S_I2C_DBG("%s fail\n", __func__);
-			return rc;
-		}
-	}
-	if (data_type == MSM_CAMERA_I2C_BYTE_DATA)
-		*data = buf[0];
-	else
-		*data = buf[0] << 8 | buf[1];
-
-	S_I2C_DBG("%s addr = 0x%x data: 0x%x\n", __func__, addr, *data);
-	return rc;
-}
-
-int32_t msm_camera_i2c_read_seq(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint8_t *data, uint16_t num_byte)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[client->addr_type+num_byte];
-	int i;
-
-	if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
-		&& client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
-		|| num_byte == 0)
-		return rc;
-
-	if (client->cci_client) {
-		struct msm_camera_cci_ctrl cci_ctrl;
-		cci_ctrl.cmd = MSM_CCI_I2C_READ;
-		cci_ctrl.cci_info = client->cci_client;
-		cci_ctrl.cfg.cci_i2c_read_cfg.addr = addr;
-		cci_ctrl.cfg.cci_i2c_read_cfg.addr_type = client->addr_type;
-		cci_ctrl.cfg.cci_i2c_read_cfg.data = buf;
-		cci_ctrl.cfg.cci_i2c_read_cfg.num_byte = num_byte;
-		rc = v4l2_subdev_call(client->cci_client->cci_subdev,
-				core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl);
-		CDBG("%s line %d rc = %d\n", __func__, __LINE__, rc);
-		rc = cci_ctrl.status;
-	} else {
-		if (client->addr_type == MSM_CAMERA_I2C_BYTE_ADDR) {
-			buf[0] = addr;
-		} else if (client->addr_type == MSM_CAMERA_I2C_WORD_ADDR) {
-			buf[0] = addr >> BITS_PER_BYTE;
-			buf[1] = addr;
-		}
-		rc = msm_camera_i2c_rxdata(client, buf, num_byte);
-		if (rc < 0) {
-			S_I2C_DBG("%s fail\n", __func__);
-			return rc;
-		}
-	}
-
-	S_I2C_DBG("%s addr = 0x%x", __func__, addr);
-	for (i = 0; i < num_byte; i++) {
-		data[i] = buf[i];
-		S_I2C_DBG("Byte %d: 0x%x\n", i, buf[i]);
-		S_I2C_DBG("Data: 0x%x\n", data[i]);
-	}
-	return rc;
-}
-
-int32_t msm_sensor_write_conf_array(struct msm_camera_i2c_client *client,
-			struct msm_camera_i2c_conf_array *array, uint16_t index)
-{
-	int32_t rc;
-
-	rc = msm_camera_i2c_write_tbl(client,
-		(struct msm_camera_i2c_reg_conf *) array[index].conf,
-		array[index].size, array[index].data_type);
-	if (array[index].delay > 20)
-		msleep(array[index].delay);
-	else
-		usleep_range(array[index].delay*1000,
-					(array[index].delay+1)*1000);
-	return rc;
-}
-
-int32_t msm_sensor_write_enum_conf_array(struct msm_camera_i2c_client *client,
-			struct msm_camera_i2c_enum_conf_array *conf,
-			uint16_t enum_val)
-{
-	int32_t rc = -1, i;
-	for (i = 0; i < conf->num_enum; i++) {
-		if (conf->conf_enum[i] == enum_val)
-			break;
-		if (conf->conf_enum[i] > enum_val)
-			break;
-	}
-	if (i == conf->num_enum)
-		i = conf->num_enum - 1;
-
-	if (i >= conf->num_index)
-		return rc;
-	rc = msm_sensor_write_all_conf_array(client,
-		&conf->conf[i*conf->num_conf], conf->num_conf);
-
-	if (conf->delay > 20)
-		msleep(conf->delay);
-	else
-		usleep_range(conf->delay*1000,
-					(conf->delay+1)*1000);
-	return rc;
-}
-
-int32_t msm_sensor_write_all_conf_array(struct msm_camera_i2c_client *client,
-			struct msm_camera_i2c_conf_array *array, uint16_t size)
-{
-	int32_t rc = 0, i;
-	for (i = 0; i < size; i++) {
-		rc = msm_sensor_write_conf_array(client, array, i);
-		if (rc < 0)
-			break;
-	}
-	return rc;
-}
-
-int32_t msm_sensor_cci_util(struct msm_camera_i2c_client *client,
-	uint16_t cci_cmd)
-{
-	int32_t rc = 0;
-	struct msm_camera_cci_ctrl cci_ctrl;
-
-	CDBG("%s line %d\n", __func__, __LINE__);
-	cci_ctrl.cmd = cci_cmd;
-	cci_ctrl.cci_info = client->cci_client;
-	rc = v4l2_subdev_call(client->cci_client->cci_subdev,
-			core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl);
-	CDBG("%s line %d rc = %d\n", __func__, __LINE__, rc);
-	return cci_ctrl.status;
-}
diff --git a/drivers/media/video/msm/io/msm_camera_i2c.h b/drivers/media/video/msm/io/msm_camera_i2c.h
deleted file mode 100644
index 35b3bd4..0000000
--- a/drivers/media/video/msm/io/msm_camera_i2c.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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 MSM_CAMERA_I2C_H
-#define MSM_CAMERA_I2C_H
-
-#include <linux/i2c.h>
-#include <linux/delay.h>
-#include <mach/camera.h>
-#include <media/v4l2-subdev.h>
-#include <media/msm_camera.h>
-
-#define CONFIG_MSM_CAMERA_I2C_DBG 0
-
-#if CONFIG_MSM_CAMERA_I2C_DBG
-#define S_I2C_DBG(fmt, args...) printk(fmt, ##args)
-#else
-#define S_I2C_DBG(fmt, args...) CDBG(fmt, ##args)
-#endif
-
-struct msm_camera_i2c_client {
-	struct i2c_client *client;
-	struct msm_camera_cci_client *cci_client;
-	enum msm_camera_i2c_reg_addr_type addr_type;
-};
-
-struct msm_camera_i2c_reg_tbl {
-	uint16_t reg_addr;
-	uint16_t reg_data;
-	uint16_t delay;
-};
-
-struct msm_camera_i2c_conf_array {
-	struct msm_camera_i2c_reg_conf *conf;
-	uint16_t size;
-	uint16_t delay;
-	enum msm_camera_i2c_data_type data_type;
-};
-
-struct msm_camera_i2c_enum_conf_array {
-	struct msm_camera_i2c_conf_array *conf;
-	int *conf_enum;
-	uint16_t num_enum;
-	uint16_t num_index;
-	uint16_t num_conf;
-	uint16_t delay;
-	enum msm_camera_i2c_data_type data_type;
-};
-
-int32_t msm_camera_i2c_rxdata(struct msm_camera_i2c_client *client,
-	unsigned char *rxdata, int data_length);
-
-int32_t msm_camera_i2c_txdata(struct msm_camera_i2c_client *client,
-	unsigned char *txdata, int length);
-
-int32_t msm_camera_i2c_read(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t *data,
-	enum msm_camera_i2c_data_type data_type);
-
-int32_t msm_camera_i2c_read_seq(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint8_t *data, uint16_t num_byte);
-
-int32_t msm_camera_i2c_write(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t data,
-	enum msm_camera_i2c_data_type data_type);
-
-int32_t msm_camera_i2c_write_seq(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint8_t *data, uint16_t num_byte);
-
-int32_t msm_camera_i2c_set_mask(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t mask,
-	enum msm_camera_i2c_data_type data_type, uint16_t flag);
-
-int32_t msm_camera_i2c_compare(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t data,
-	enum msm_camera_i2c_data_type data_type);
-
-int32_t msm_camera_i2c_poll(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t data,
-	enum msm_camera_i2c_data_type data_type);
-
-int32_t msm_camera_i2c_write_table_w_microdelay(
-	struct msm_camera_i2c_client *client,
-	struct msm_camera_i2c_reg_tbl *reg_tbl, uint16_t size,
-	enum msm_camera_i2c_data_type data_type);
-
-int32_t msm_camera_i2c_write_bayer_table(
-	struct msm_camera_i2c_client *client,
-	struct msm_camera_i2c_reg_setting *write_setting);
-
-int32_t msm_camera_i2c_write_tbl(struct msm_camera_i2c_client *client,
-	struct msm_camera_i2c_reg_conf *reg_conf_tbl, uint16_t size,
-	enum msm_camera_i2c_data_type data_type);
-
-int32_t msm_sensor_write_conf_array(struct msm_camera_i2c_client *client,
-	struct msm_camera_i2c_conf_array *array, uint16_t index);
-
-int32_t msm_sensor_write_enum_conf_array(struct msm_camera_i2c_client *client,
-	struct msm_camera_i2c_enum_conf_array *conf, uint16_t enum_val);
-
-int32_t msm_sensor_write_all_conf_array(struct msm_camera_i2c_client *client,
-	struct msm_camera_i2c_conf_array *array, uint16_t size);
-
-int32_t msm_sensor_cci_util(struct msm_camera_i2c_client *client,
-	uint16_t cci_cmd);
-#endif
diff --git a/drivers/media/video/msm/io/msm_camera_i2c_mux.c b/drivers/media/video/msm/io/msm_camera_i2c_mux.c
deleted file mode 100644
index 60f3e10..0000000
--- a/drivers/media/video/msm/io/msm_camera_i2c_mux.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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/delay.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <mach/board.h>
-#include <mach/camera.h>
-#include "msm.h"
-#include "msm_camera_i2c_mux.h"
-
-static int msm_i2c_mux_config(struct i2c_mux_device *mux_device, uint8_t *mode)
-{
-	uint32_t val;
-	val = msm_camera_io_r(mux_device->ctl_base);
-	if (*mode == MODE_DUAL) {
-		msm_camera_io_w(val | 0x3, mux_device->ctl_base);
-	} else if (*mode == MODE_L) {
-		msm_camera_io_w(((val | 0x2) & ~(0x1)), mux_device->ctl_base);
-		val = msm_camera_io_r(mux_device->ctl_base);
-		CDBG("the camio mode config left value is %d\n", val);
-	} else {
-		msm_camera_io_w(((val | 0x1) & ~(0x2)), mux_device->ctl_base);
-		val = msm_camera_io_r(mux_device->ctl_base);
-		CDBG("the camio mode config right value is %d\n", val);
-	}
-	return 0;
-}
-
-static int msm_i2c_mux_init(struct i2c_mux_device *mux_device)
-{
-	int rc = 0, val = 0;
-	if (mux_device->use_count == 0) {
-		mux_device->ctl_base = ioremap(mux_device->ctl_mem->start,
-			resource_size(mux_device->ctl_mem));
-		if (!mux_device->ctl_base) {
-			rc = -ENOMEM;
-			return rc;
-		}
-		mux_device->rw_base = ioremap(mux_device->rw_mem->start,
-			resource_size(mux_device->rw_mem));
-		if (!mux_device->rw_base) {
-			rc = -ENOMEM;
-			iounmap(mux_device->ctl_base);
-			return rc;
-		}
-		val = msm_camera_io_r(mux_device->rw_base);
-		msm_camera_io_w((val | 0x200), mux_device->rw_base);
-	}
-	mux_device->use_count++;
-	return 0;
-};
-
-static int msm_i2c_mux_release(struct i2c_mux_device *mux_device)
-{
-	int val = 0;
-	mux_device->use_count--;
-	if (mux_device->use_count == 0) {
-		val = msm_camera_io_r(mux_device->rw_base);
-		msm_camera_io_w((val & ~0x200), mux_device->rw_base);
-		iounmap(mux_device->rw_base);
-		iounmap(mux_device->ctl_base);
-	}
-	return 0;
-}
-
-static long msm_i2c_mux_subdev_ioctl(struct v4l2_subdev *sd,
-			unsigned int cmd, void *arg)
-{
-	struct i2c_mux_device *mux_device;
-	int rc = 0;
-	mux_device = v4l2_get_subdevdata(sd);
-	if (mux_device == NULL) {
-		rc = -ENOMEM;
-		return rc;
-	}
-	mutex_lock(&mux_device->mutex);
-	switch (cmd) {
-	case VIDIOC_MSM_I2C_MUX_CFG:
-		rc = msm_i2c_mux_config(mux_device, (uint8_t *) arg);
-		break;
-	case VIDIOC_MSM_I2C_MUX_INIT:
-		rc = msm_i2c_mux_init(mux_device);
-		break;
-	case VIDIOC_MSM_I2C_MUX_RELEASE:
-		rc = msm_i2c_mux_release(mux_device);
-		break;
-	default:
-		rc = -ENOIOCTLCMD;
-	}
-	mutex_unlock(&mux_device->mutex);
-	return rc;
-}
-
-static struct v4l2_subdev_core_ops msm_i2c_mux_subdev_core_ops = {
-	.ioctl = &msm_i2c_mux_subdev_ioctl,
-};
-
-static const struct v4l2_subdev_ops msm_i2c_mux_subdev_ops = {
-	.core = &msm_i2c_mux_subdev_core_ops,
-};
-
-static int __devinit i2c_mux_probe(struct platform_device *pdev)
-{
-	struct i2c_mux_device *mux_device;
-	int rc = 0;
-	CDBG("%s: device id = %d\n", __func__, pdev->id);
-	mux_device = kzalloc(sizeof(struct i2c_mux_device), GFP_KERNEL);
-	if (!mux_device) {
-		pr_err("%s: no enough memory\n", __func__);
-		return -ENOMEM;
-	}
-
-	v4l2_subdev_init(&mux_device->subdev, &msm_i2c_mux_subdev_ops);
-	v4l2_set_subdevdata(&mux_device->subdev, mux_device);
-	platform_set_drvdata(pdev, &mux_device->subdev);
-	mutex_init(&mux_device->mutex);
-
-	mux_device->ctl_mem = platform_get_resource_byname(pdev,
-					IORESOURCE_MEM, "i2c_mux_ctl");
-	if (!mux_device->ctl_mem) {
-		pr_err("%s: no mem resource?\n", __func__);
-		rc = -ENODEV;
-		goto i2c_mux_no_resource;
-	}
-	mux_device->ctl_io = request_mem_region(mux_device->ctl_mem->start,
-		resource_size(mux_device->ctl_mem), pdev->name);
-	if (!mux_device->ctl_io) {
-		pr_err("%s: no valid mem region\n", __func__);
-		rc = -EBUSY;
-		goto i2c_mux_no_resource;
-	}
-	mux_device->rw_mem = platform_get_resource_byname(pdev,
-					IORESOURCE_MEM, "i2c_mux_rw");
-	if (!mux_device->rw_mem) {
-		pr_err("%s: no mem resource?\n", __func__);
-		rc = -ENODEV;
-		goto i2c_mux_no_resource;
-	}
-	mux_device->rw_io = request_mem_region(mux_device->rw_mem->start,
-		resource_size(mux_device->rw_mem), pdev->name);
-	if (!mux_device->rw_io) {
-		pr_err("%s: no valid mem region\n", __func__);
-		rc = -EBUSY;
-		goto i2c_mux_no_resource;
-	}
-	mux_device->pdev = pdev;
-	return 0;
-
-i2c_mux_no_resource:
-	mutex_destroy(&mux_device->mutex);
-	kfree(mux_device);
-	return 0;
-}
-
-static struct platform_driver i2c_mux_driver = {
-	.probe = i2c_mux_probe,
-	.driver = {
-		.name = MSM_I2C_MUX_DRV_NAME,
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init msm_camera_i2c_mux_init_module(void)
-{
-	return platform_driver_register(&i2c_mux_driver);
-}
-
-static void __exit msm_camera_i2c_mux_exit_module(void)
-{
-	platform_driver_unregister(&i2c_mux_driver);
-}
-
-module_init(msm_camera_i2c_mux_init_module);
-module_exit(msm_camera_i2c_mux_exit_module);
-MODULE_DESCRIPTION("MSM Camera I2C mux driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/io/msm_camera_i2c_mux.h b/drivers/media/video/msm/io/msm_camera_i2c_mux.h
deleted file mode 100644
index 94394fc..0000000
--- a/drivers/media/video/msm/io/msm_camera_i2c_mux.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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 MSM_I2C_MUX_H
-#define MSM_I2C_MUX_H
-
-#include <linux/io.h>
-#include <media/v4l2-subdev.h>
-
-struct i2c_mux_device {
-	struct platform_device *pdev;
-	struct v4l2_subdev subdev;
-	struct resource *ctl_mem;
-	struct resource *ctl_io;
-	void __iomem *ctl_base;
-	struct resource *rw_mem;
-	struct resource *rw_io;
-	void __iomem *rw_base;
-	struct mutex mutex;
-	unsigned use_count;
-};
-
-struct i2c_mux_cfg_params {
-	struct v4l2_subdev *subdev;
-	void *parms;
-};
-
-#define VIDIOC_MSM_I2C_MUX_CFG \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 13, struct i2c_mux_cfg_params)
-
-#define VIDIOC_MSM_I2C_MUX_INIT \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 14, struct v4l2_subdev*)
-
-#define VIDIOC_MSM_I2C_MUX_RELEASE \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 15, struct v4l2_subdev*)
-
-#endif
diff --git a/drivers/media/video/msm/io/msm_io7x.c b/drivers/media/video/msm/io/msm_io7x.c
deleted file mode 100644
index 8804106..0000000
--- a/drivers/media/video/msm/io/msm_io7x.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. 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/delay.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <mach/gpio.h>
-#include <mach/board.h>
-#include <mach/camera.h>
-#include <mach/clk.h>
-
-#define CAMIF_CFG_RMSK 0x1fffff
-#define CAM_SEL_BMSK 0x2
-#define CAM_PCLK_SRC_SEL_BMSK 0x60000
-#define CAM_PCLK_INVERT_BMSK 0x80000
-#define CAM_PAD_REG_SW_RESET_BMSK 0x100000
-
-#define EXT_CAM_HSYNC_POL_SEL_BMSK 0x10000
-#define EXT_CAM_VSYNC_POL_SEL_BMSK 0x8000
-#define MDDI_CLK_CHICKEN_BIT_BMSK  0x80
-
-#define CAM_SEL_SHFT 0x1
-#define CAM_PCLK_SRC_SEL_SHFT 0x11
-#define CAM_PCLK_INVERT_SHFT 0x13
-#define CAM_PAD_REG_SW_RESET_SHFT 0x14
-
-#define EXT_CAM_HSYNC_POL_SEL_SHFT 0x10
-#define EXT_CAM_VSYNC_POL_SEL_SHFT 0xF
-#define MDDI_CLK_CHICKEN_BIT_SHFT  0x7
-#define APPS_RESET_OFFSET 0x00000210
-
-static struct clk *camio_vfe_mdc_clk;
-static struct clk *camio_mdc_clk;
-static struct clk *camio_vfe_clk;
-
-static struct msm_camera_io_ext camio_ext;
-static struct resource *appio, *mdcio;
-void __iomem *appbase, *mdcbase;
-
-static struct resource *appio, *mdcio;
-void __iomem *appbase, *mdcbase;
-
-int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
-{
-	int rc = -1;
-	struct clk *clk = NULL;
-
-	switch (clktype) {
-	case CAMIO_VFE_MDC_CLK:
-		clk = camio_vfe_mdc_clk = clk_get(NULL, "vfe_mdc_clk");
-		break;
-
-	case CAMIO_MDC_CLK:
-		clk = camio_mdc_clk = clk_get(NULL, "mdc_clk");
-		break;
-
-	case CAMIO_VFE_CLK:
-		clk = camio_vfe_clk = clk_get(NULL, "vfe_clk");
-		break;
-
-	default:
-		break;
-	}
-
-	if (!IS_ERR(clk)) {
-		clk_enable(clk);
-		rc = 0;
-	}
-
-	return rc;
-}
-
-int msm_camio_clk_disable(enum msm_camio_clk_type clktype)
-{
-	int rc = -1;
-	struct clk *clk = NULL;
-
-	switch (clktype) {
-	case CAMIO_VFE_MDC_CLK:
-		clk = camio_vfe_mdc_clk;
-		break;
-
-	case CAMIO_MDC_CLK:
-		clk = camio_mdc_clk;
-		break;
-
-	case CAMIO_VFE_CLK:
-		clk = camio_vfe_clk;
-		break;
-
-	default:
-		break;
-	}
-
-	if (!IS_ERR(clk)) {
-		clk_disable(clk);
-		clk_put(clk);
-		rc = 0;
-	}
-
-	return rc;
-}
-
-void msm_camio_clk_rate_set(int rate)
-{
-	struct clk *clk = camio_vfe_clk;
-
-	if (clk != ERR_PTR(-ENOENT))
-		clk_set_rate(clk, rate);
-}
-
-int msm_camio_enable(struct platform_device *pdev)
-{
-	int rc = 0;
-	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-
-	camio_ext = camdev->ioext;
-
-	appio = request_mem_region(camio_ext.appphy,
-		camio_ext.appsz, pdev->name);
-	if (!appio) {
-		rc = -EBUSY;
-		goto enable_fail;
-	}
-
-	appbase = ioremap(camio_ext.appphy,
-		camio_ext.appsz);
-	if (!appbase) {
-		rc = -ENOMEM;
-		goto apps_no_mem;
-	}
-
-	msm_camio_clk_enable(CAMIO_VFE_CLK);
-	msm_camio_clk_enable(CAMIO_MDC_CLK);
-	return 0;
-apps_no_mem:
-	release_mem_region(camio_ext.appphy, camio_ext.appsz);
-enable_fail:
-	return rc;
-}
-
-int msm_camio_sensor_clk_on(struct platform_device *pdev)
-{
-	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-	int32_t rc = 0;
-	camio_ext = camdev->ioext;
-	mdcio = request_mem_region(camio_ext.mdcphy,
-		camio_ext.mdcsz, pdev->name);
-	if (!mdcio)
-		rc = -EBUSY;
-	mdcbase = ioremap(camio_ext.mdcphy,
-		camio_ext.mdcsz);
-	if (!mdcbase) {
-		rc = -EINVAL;
-		goto mdc_no_mem;
-	}
-	camdev->camera_gpio_on();
-	return msm_camio_clk_enable(CAMIO_VFE_MDC_CLK);
-
-mdc_no_mem:
-	release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
-	return rc;
-}
-
-int msm_camio_sensor_clk_off(struct platform_device *pdev)
-{
-	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-	camdev->camera_gpio_off();
-	iounmap(mdcbase);
-	release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
-	return msm_camio_clk_disable(CAMIO_VFE_MDC_CLK);
-}
-
-void msm_camio_disable(struct platform_device *pdev)
-{
-	iounmap(appbase);
-	release_mem_region(camio_ext.appphy, camio_ext.appsz);
-	msm_camio_clk_disable(CAMIO_VFE_CLK);
-	msm_camio_clk_disable(CAMIO_MDC_CLK);
-}
-
-void msm_disable_io_gpio_clk(struct platform_device *pdev)
-{
-	return;
-}
-
-void msm_camio_camif_pad_reg_reset(void)
-{
-	uint32_t reg;
-	uint32_t mask, value;
-
-	/* select CLKRGM_VFE_SRC_CAM_VFE_SRC:  internal source */
-	msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_INTERNAL);
-
-	reg = (msm_camera_io_r_mb(mdcbase)) & CAMIF_CFG_RMSK;
-
-	mask = CAM_SEL_BMSK |
-		CAM_PCLK_SRC_SEL_BMSK |
-		CAM_PCLK_INVERT_BMSK;
-
-	value = 1 << CAM_SEL_SHFT |
-		3 << CAM_PCLK_SRC_SEL_SHFT |
-		0 << CAM_PCLK_INVERT_SHFT;
-
-	msm_camera_io_w_mb((reg & (~mask)) | (value & mask), mdcbase);
-	usleep_range(10000, 11000);
-
-	reg = (msm_camera_io_r_mb(mdcbase)) & CAMIF_CFG_RMSK;
-	mask = CAM_PAD_REG_SW_RESET_BMSK;
-	value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
-	msm_camera_io_w_mb((reg & (~mask)) | (value & mask), mdcbase);
-	usleep_range(10000, 11000);
-
-	reg = (msm_camera_io_r_mb(mdcbase)) & CAMIF_CFG_RMSK;
-	mask = CAM_PAD_REG_SW_RESET_BMSK;
-	value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
-	msm_camera_io_w_mb((reg & (~mask)) | (value & mask), mdcbase);
-	usleep_range(10000, 11000);
-
-	msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_EXTERNAL);
-	usleep_range(10000, 11000);
-}
-
-void msm_camio_vfe_blk_reset(void)
-{
-	uint32_t val;
-
-	/* do apps reset */
-	val = msm_camera_io_r_mb(appbase + 0x00000210);
-	val |= 0x1;
-	msm_camera_io_w_mb(val, appbase + 0x00000210);
-	usleep_range(10000, 11000);
-
-	val = msm_camera_io_r_mb(appbase + 0x00000210);
-	val &= ~0x1;
-	msm_camera_io_w_mb(val, appbase + 0x00000210);
-	usleep_range(10000, 11000);
-
-	/* do axi reset */
-	val = msm_camera_io_r_mb(appbase + 0x00000208);
-	val |= 0x1;
-	msm_camera_io_w_mb(val, appbase + 0x00000208);
-	usleep_range(10000, 11000);
-
-	val = msm_camera_io_r_mb(appbase + 0x00000208);
-	val &= ~0x1;
-	msm_camera_io_w_mb(val, appbase + 0x00000208);
-	usleep_range(10000, 11000);
-}
-
-void msm_camio_camif_pad_reg_reset_2(void)
-{
-	uint32_t reg;
-	uint32_t mask, value;
-
-	reg = (msm_camera_io_r_mb(mdcbase)) & CAMIF_CFG_RMSK;
-	mask = CAM_PAD_REG_SW_RESET_BMSK;
-	value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
-	msm_camera_io_w_mb((reg & (~mask)) | (value & mask), mdcbase);
-	usleep_range(10000, 11000);
-
-	reg = (msm_camera_io_r_mb(mdcbase)) & CAMIF_CFG_RMSK;
-	mask = CAM_PAD_REG_SW_RESET_BMSK;
-	value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
-	msm_camera_io_w_mb((reg & (~mask)) | (value & mask), mdcbase);
-	usleep_range(10000, 11000);
-}
-
-void msm_camio_clk_sel(enum msm_camio_clk_src_type srctype)
-{
-	struct clk *clk = NULL;
-
-	clk = camio_vfe_clk;
-
-	if (clk != NULL && clk != ERR_PTR(-ENOENT)) {
-		switch (srctype) {
-		case MSM_CAMIO_CLK_SRC_INTERNAL:
-			clk_set_flags(clk, 0x00000100 << 1);
-			break;
-
-		case MSM_CAMIO_CLK_SRC_EXTERNAL:
-			clk_set_flags(clk, 0x00000100);
-			break;
-
-		default:
-			break;
-		}
-	}
-}
-
-int msm_camio_probe_on(struct platform_device *pdev)
-{
-	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-	camdev->camera_gpio_on();
-	return msm_camio_clk_enable(CAMIO_VFE_CLK);
-}
-
-int msm_camio_probe_off(struct platform_device *pdev)
-{
-	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-	camdev->camera_gpio_off();
-	return msm_camio_clk_disable(CAMIO_VFE_CLK);
-}
diff --git a/drivers/media/video/msm/io/msm_io8x.c b/drivers/media/video/msm/io/msm_io8x.c
deleted file mode 100644
index 5f1f34f..0000000
--- a/drivers/media/video/msm/io/msm_io8x.c
+++ /dev/null
@@ -1,331 +0,0 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. 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/delay.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <mach/gpio.h>
-#include <mach/board.h>
-#include <mach/camera.h>
-#include <mach/clk.h>
-
-#define CAMIF_CFG_RMSK 0x1fffff
-#define CAM_SEL_BMSK 0x2
-#define CAM_PCLK_SRC_SEL_BMSK 0x60000
-#define CAM_PCLK_INVERT_BMSK 0x80000
-#define CAM_PAD_REG_SW_RESET_BMSK 0x100000
-
-#define EXT_CAM_HSYNC_POL_SEL_BMSK 0x10000
-#define EXT_CAM_VSYNC_POL_SEL_BMSK 0x8000
-#define MDDI_CLK_CHICKEN_BIT_BMSK  0x80
-
-#define CAM_SEL_SHFT 0x1
-#define CAM_PCLK_SRC_SEL_SHFT 0x11
-#define CAM_PCLK_INVERT_SHFT 0x13
-#define CAM_PAD_REG_SW_RESET_SHFT 0x14
-
-#define EXT_CAM_HSYNC_POL_SEL_SHFT 0x10
-#define EXT_CAM_VSYNC_POL_SEL_SHFT 0xF
-#define MDDI_CLK_CHICKEN_BIT_SHFT  0x7
-#define APPS_RESET_OFFSET 0x00000214
-
-static struct clk *camio_vfe_mdc_clk;
-static struct clk *camio_mdc_clk;
-static struct clk *camio_vfe_clk;
-static struct clk *camio_vfe_axi_clk;
-static struct msm_camera_io_ext camio_ext;
-static struct resource *appio, *mdcio;
-
-void __iomem *appbase, *mdcbase;
-
-
-int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
-{
-	int rc = 0;
-	struct clk *clk = NULL;
-
-	switch (clktype) {
-	case CAMIO_VFE_MDC_CLK:
-		camio_vfe_mdc_clk = clk = clk_get(NULL, "vfe_mdc_clk");
-		break;
-
-	case CAMIO_MDC_CLK:
-		camio_mdc_clk = clk = clk_get(NULL, "mdc_clk");
-		break;
-
-	case CAMIO_VFE_CLK:
-		camio_vfe_clk = clk = clk_get(NULL, "vfe_clk");
-		break;
-
-	case CAMIO_VFE_AXI_CLK:
-		camio_vfe_axi_clk = clk = clk_get(NULL, "vfe_axi_clk");
-		break;
-
-	default:
-		break;
-	}
-
-	if (!IS_ERR(clk))
-		clk_enable(clk);
-	else
-		rc = -1;
-
-	return rc;
-}
-
-int msm_camio_clk_disable(enum msm_camio_clk_type clktype)
-{
-	int rc = 0;
-	struct clk *clk = NULL;
-
-	switch (clktype) {
-	case CAMIO_VFE_MDC_CLK:
-		clk = camio_vfe_mdc_clk;
-		break;
-
-	case CAMIO_MDC_CLK:
-		clk = camio_mdc_clk;
-		break;
-
-	case CAMIO_VFE_CLK:
-		clk = camio_vfe_clk;
-		break;
-
-	case CAMIO_VFE_AXI_CLK:
-		clk = camio_vfe_axi_clk;
-		break;
-
-	default:
-		break;
-	}
-
-	if (!IS_ERR(clk)) {
-		clk_disable(clk);
-		clk_put(clk);
-	} else
-		rc = -1;
-
-	return rc;
-}
-
-void msm_camio_clk_rate_set(int rate)
-{
-	struct clk *clk = camio_vfe_mdc_clk;
-
-	/* TODO: check return */
-	clk_set_rate(clk, rate);
-}
-
-int msm_camio_enable(struct platform_device *pdev)
-{
-	int rc = 0;
-
-	appio = request_mem_region(camio_ext.appphy,
-		camio_ext.appsz, pdev->name);
-	if (!appio) {
-		rc = -EBUSY;
-		goto enable_fail;
-	}
-
-	appbase = ioremap(camio_ext.appphy, camio_ext.appsz);
-	if (!appbase) {
-		rc = -ENOMEM;
-		goto apps_no_mem;
-	}
-	msm_camio_clk_enable(CAMIO_MDC_CLK);
-	msm_camio_clk_enable(CAMIO_VFE_AXI_CLK);
-	return 0;
-
-apps_no_mem:
-	release_mem_region(camio_ext.appphy, camio_ext.appsz);
-enable_fail:
-	return rc;
-}
-
-void msm_camio_disable(struct platform_device *pdev)
-{
-	iounmap(appbase);
-	release_mem_region(camio_ext.appphy, camio_ext.appsz);
-	msm_camio_clk_disable(CAMIO_MDC_CLK);
-	msm_camio_clk_disable(CAMIO_VFE_AXI_CLK);
-}
-
-int msm_camio_sensor_clk_on(struct platform_device *pdev)
-{
-
-	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-	int32_t rc = 0;
-	camio_ext = camdev->ioext;
-
-	mdcio = request_mem_region(camio_ext.mdcphy,
-		camio_ext.mdcsz, pdev->name);
-	if (!mdcio)
-		rc = -EBUSY;
-	mdcbase = ioremap(camio_ext.mdcphy,
-		camio_ext.mdcsz);
-	if (!mdcbase)
-		goto mdc_no_mem;
-	camdev->camera_gpio_on();
-
-	msm_camio_clk_enable(CAMIO_VFE_CLK);
-	msm_camio_clk_enable(CAMIO_VFE_MDC_CLK);
-	return rc;
-
-
-mdc_no_mem:
-	release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
-	return -EINVAL;
-}
-
-int msm_camio_sensor_clk_off(struct platform_device *pdev)
-{
-	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-	camdev->camera_gpio_off();
-	iounmap(mdcbase);
-	release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
-	msm_camio_clk_disable(CAMIO_VFE_CLK);
-	return msm_camio_clk_disable(CAMIO_VFE_MDC_CLK);
-
-}
-
-void msm_disable_io_gpio_clk(struct platform_device *pdev)
-{
-	return;
-}
-
-void msm_camio_camif_pad_reg_reset(void)
-{
-	uint32_t reg;
-	uint32_t mask, value;
-
-	/* select CLKRGM_VFE_SRC_CAM_VFE_SRC:  internal source */
-	msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_INTERNAL);
-
-	reg = (msm_camera_io_r_mb(mdcbase)) & CAMIF_CFG_RMSK;
-
-	mask = CAM_SEL_BMSK |
-		CAM_PCLK_SRC_SEL_BMSK |
-		CAM_PCLK_INVERT_BMSK |
-		EXT_CAM_HSYNC_POL_SEL_BMSK |
-	    EXT_CAM_VSYNC_POL_SEL_BMSK | MDDI_CLK_CHICKEN_BIT_BMSK;
-
-	value = 1 << CAM_SEL_SHFT |
-		3 << CAM_PCLK_SRC_SEL_SHFT |
-		0 << CAM_PCLK_INVERT_SHFT |
-		0 << EXT_CAM_HSYNC_POL_SEL_SHFT |
-	    0 << EXT_CAM_VSYNC_POL_SEL_SHFT | 0 << MDDI_CLK_CHICKEN_BIT_SHFT;
-	msm_camera_io_w_mb((reg & (~mask)) | (value & mask), mdcbase);
-	usleep_range(10000, 11000);
-
-	reg = (msm_camera_io_r_mb(mdcbase)) & CAMIF_CFG_RMSK;
-	mask = CAM_PAD_REG_SW_RESET_BMSK;
-	value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
-	msm_camera_io_w_mb((reg & (~mask)) | (value & mask), mdcbase);
-	usleep_range(10000, 11000);
-
-	reg = (msm_camera_io_r_mb(mdcbase)) & CAMIF_CFG_RMSK;
-	mask = CAM_PAD_REG_SW_RESET_BMSK;
-	value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
-	msm_camera_io_w_mb((reg & (~mask)) | (value & mask), mdcbase);
-	usleep_range(10000, 11000);
-
-	msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_EXTERNAL);
-
-	usleep_range(10000, 11000);
-
-	/* todo: check return */
-	if (camio_vfe_clk)
-		clk_set_rate(camio_vfe_clk, 96000000);
-}
-
-void msm_camio_vfe_blk_reset(void)
-{
-	uint32_t val;
-
-	val = msm_camera_io_r_mb(appbase + APPS_RESET_OFFSET);
-	val |= 0x1;
-	msm_camera_io_w_mb(val, appbase + APPS_RESET_OFFSET);
-	usleep_range(10000, 11000);
-
-	val = msm_camera_io_r_mb(appbase + APPS_RESET_OFFSET);
-	val &= ~0x1;
-	msm_camera_io_w_mb(val, appbase + APPS_RESET_OFFSET);
-	usleep_range(10000, 11000);
-}
-
-void msm_camio_camif_pad_reg_reset_2(void)
-{
-	uint32_t reg;
-	uint32_t mask, value;
-
-	reg = (msm_camera_io_r_mb(mdcbase)) & CAMIF_CFG_RMSK;
-	mask = CAM_PAD_REG_SW_RESET_BMSK;
-	value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
-	msm_camera_io_w_mb((reg & (~mask)) | (value & mask), mdcbase);
-	usleep_range(10000, 11000);
-
-	reg = (msm_camera_io_r_mb(mdcbase)) & CAMIF_CFG_RMSK;
-	mask = CAM_PAD_REG_SW_RESET_BMSK;
-	value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
-	msm_camera_io_w_mb((reg & (~mask)) | (value & mask), mdcbase);
-	usleep_range(10000, 11000);
-}
-
-void msm_camio_clk_sel(enum msm_camio_clk_src_type srctype)
-{
-	struct clk *clk = NULL;
-
-	clk = camio_vfe_clk;
-
-	if (clk != NULL) {
-		switch (srctype) {
-		case MSM_CAMIO_CLK_SRC_INTERNAL:
-			clk_set_flags(clk, 0x00000100 << 1);
-			break;
-
-		case MSM_CAMIO_CLK_SRC_EXTERNAL:
-			clk_set_flags(clk, 0x00000100);
-			break;
-
-		default:
-			break;
-		}
-	}
-}
-
-void msm_camio_clk_axi_rate_set(int rate)
-{
-	struct clk *clk = camio_vfe_axi_clk;
-	/* todo: check return */
-	clk_set_rate(clk, rate);
-}
-
-int msm_camio_probe_on(struct platform_device *pdev)
-{
-	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-
-	camdev->camera_gpio_on();
-	return msm_camio_clk_enable(CAMIO_VFE_MDC_CLK);
-}
-
-int msm_camio_probe_off(struct platform_device *pdev)
-{
-	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-
-	camdev->camera_gpio_off();
-	return msm_camio_clk_disable(CAMIO_VFE_MDC_CLK);
-}
diff --git a/drivers/media/video/msm/io/msm_io_7x27a.c b/drivers/media/video/msm/io/msm_io_7x27a.c
deleted file mode 100644
index 4d89c06..0000000
--- a/drivers/media/video/msm/io/msm_io_7x27a.c
+++ /dev/null
@@ -1,595 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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/delay.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/pm_qos.h>
-#include <mach/board.h>
-#include <mach/camera.h>
-#include <mach/camera.h>
-#include <mach/clk.h>
-#include <mach/msm_bus.h>
-#include <mach/msm_bus_board.h>
-
-
-/* MIPI	CSI controller registers */
-#define	MIPI_PHY_CONTROL		0x00000000
-#define	MIPI_PROTOCOL_CONTROL		0x00000004
-#define	MIPI_INTERRUPT_STATUS		0x00000008
-#define	MIPI_INTERRUPT_MASK		0x0000000C
-#define	MIPI_CAMERA_CNTL		0x00000024
-#define	MIPI_CALIBRATION_CONTROL	0x00000018
-#define	MIPI_PHY_D0_CONTROL2		0x00000038
-#define	MIPI_PHY_D1_CONTROL2		0x0000003C
-#define	MIPI_PHY_D2_CONTROL2		0x00000040
-#define	MIPI_PHY_D3_CONTROL2		0x00000044
-#define	MIPI_PHY_CL_CONTROL		0x00000048
-#define	MIPI_PHY_D0_CONTROL		0x00000034
-#define	MIPI_PHY_D1_CONTROL		0x00000020
-#define	MIPI_PHY_D2_CONTROL		0x0000002C
-#define	MIPI_PHY_D3_CONTROL		0x00000030
-#define	MIPI_PWR_CNTL			0x00000054
-
-/*
- * MIPI_PROTOCOL_CONTROL register bits to enable/disable the features of
- * CSI Rx Block
- */
-
-/* DPCM scheme */
-#define	MIPI_PROTOCOL_CONTROL_DPCM_SCHEME_SHFT			0x1e
-/* SW_RST to issue a SW reset to the CSI core */
-#define	MIPI_PROTOCOL_CONTROL_SW_RST_BMSK			0x8000000
-/* To Capture Long packet Header Info in MIPI_PROTOCOL_STATUS register */
-#define	MIPI_PROTOCOL_CONTROL_LONG_PACKET_HEADER_CAPTURE_BMSK	0x200000
-/* Data format for unpacking purpose */
-#define	MIPI_PROTOCOL_CONTROL_DATA_FORMAT_SHFT			0x13
-/* Enable decoding of payload based on data type filed of packet hdr */
-#define	MIPI_PROTOCOL_CONTROL_DECODE_ID_BMSK			0x00000
-/* Enable error correction on packet headers */
-#define	MIPI_PROTOCOL_CONTROL_ECC_EN_BMSK			0x20000
-
-/*
- * MIPI_CALIBRATION_CONTROL register contains control info for
- * calibration impledence controller
-*/
-
-/* Enable bit for calibration pad */
-#define	MIPI_CALIBRATION_CONTROL_SWCAL_CAL_EN_SHFT		0x16
-/* With SWCAL_STRENGTH_OVERRIDE_EN, SW_CAL_EN and MANUAL_OVERRIDE_EN
- * the hardware calibration circuitry associated with CAL_SW_HW_MODE
- * is bypassed
-*/
-#define	MIPI_CALIBRATION_CONTROL_SWCAL_STRENGTH_OVERRIDE_EN_SHFT	0x15
-/* To indicate the Calibration process is in the control of HW/SW */
-#define	MIPI_CALIBRATION_CONTROL_CAL_SW_HW_MODE_SHFT		0x14
-/* When this is set the strength value of the data and clk lane impedence
- * termination is updated with MANUAL_STRENGTH settings and calibration
- * sensing logic is idle.
-*/
-#define	MIPI_CALIBRATION_CONTROL_MANUAL_OVERRIDE_EN_SHFT	0x7
-
-/* Data lane0 control */
-/* T-hs Settle count value  for Rx */
-#define	MIPI_PHY_D0_CONTROL2_SETTLE_COUNT_SHFT			0x18
-/* Rx termination control */
-#define	MIPI_PHY_D0_CONTROL2_HS_TERM_IMP_SHFT			0x10
-/* LP Rx enable */
-#define	MIPI_PHY_D0_CONTROL2_LP_REC_EN_SHFT			0x4
-/*
- * Enable for error in sync sequence
- * 1 - one bit error in sync seq
- * 0 - requires all 8 bit correct seq
-*/
-#define	MIPI_PHY_D0_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
-
-/* Comments are same as D0 */
-#define	MIPI_PHY_D1_CONTROL2_SETTLE_COUNT_SHFT			0x18
-#define	MIPI_PHY_D1_CONTROL2_HS_TERM_IMP_SHFT			0x10
-#define	MIPI_PHY_D1_CONTROL2_LP_REC_EN_SHFT			0x4
-#define	MIPI_PHY_D1_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
-
-/* Comments are same as D0 */
-#define	MIPI_PHY_D2_CONTROL2_SETTLE_COUNT_SHFT			0x18
-#define	MIPI_PHY_D2_CONTROL2_HS_TERM_IMP_SHFT			0x10
-#define	MIPI_PHY_D2_CONTROL2_LP_REC_EN_SHFT			0x4
-#define	MIPI_PHY_D2_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
-
-/* Comments are same as D0 */
-#define	MIPI_PHY_D3_CONTROL2_SETTLE_COUNT_SHFT			0x18
-#define	MIPI_PHY_D3_CONTROL2_HS_TERM_IMP_SHFT			0x10
-#define	MIPI_PHY_D3_CONTROL2_LP_REC_EN_SHFT			0x4
-#define	MIPI_PHY_D3_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
-
-/* PHY_CL_CTRL programs the parameters of clk lane of CSIRXPHY */
-/* HS Rx termination control */
-#define	MIPI_PHY_CL_CONTROL_HS_TERM_IMP_SHFT			0x18
-/* Start signal for T-hs delay */
-#define	MIPI_PHY_CL_CONTROL_LP_REC_EN_SHFT			0x2
-
-/* PHY DATA lane 0 control */
-/*
- * HS RX equalizer strength control
- * 00 - 0db 01 - 3db 10 - 5db 11 - 7db
-*/
-#define	MIPI_PHY_D0_CONTROL_HS_REC_EQ_SHFT			0x1c
-
-/* PHY DATA lane 1 control */
-/* Shutdown signal for MIPI clk phy line */
-#define	MIPI_PHY_D1_CONTROL_MIPI_CLK_PHY_SHUTDOWNB_SHFT		0x9
-/* Shutdown signal for MIPI data phy line */
-#define	MIPI_PHY_D1_CONTROL_MIPI_DATA_PHY_SHUTDOWNB_SHFT	0x8
-
-#define MSM_AXI_QOS_PREVIEW 200000
-#define MSM_AXI_QOS_SNAPSHOT 200000
-#define MSM_AXI_QOS_RECORDING 200000
-
-#define MIPI_PWR_CNTL_ENA	0x07
-#define MIPI_PWR_CNTL_DIS	0x0
-
-static struct clk *camio_cam_clk;
-static struct clk *camio_vfe_clk;
-static struct clk *camio_csi_src_clk;
-static struct clk *camio_csi0_vfe_clk;
-static struct clk *camio_csi1_vfe_clk;
-static struct clk *camio_csi0_clk;
-static struct clk *camio_csi1_clk;
-static struct clk *camio_csi0_pclk;
-static struct clk *camio_csi1_pclk;
-
-static struct msm_camera_io_ext camio_ext;
-static struct msm_camera_io_clk camio_clk;
-static struct platform_device *camio_dev;
-void __iomem *csibase;
-void __iomem *appbase;
-
-
-int msm_camio_vfe_clk_rate_set(int rate)
-{
-	int rc = 0;
-	struct clk *clk = camio_vfe_clk;
-	if (rate > clk_get_rate(clk))
-		rc = clk_set_rate(clk, rate);
-	return rc;
-}
-
-int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
-{
-	int rc = 0;
-	struct clk *clk = NULL;
-
-	switch (clktype) {
-	case CAMIO_CAM_MCLK_CLK:
-		clk = clk_get(NULL, "cam_m_clk");
-		camio_cam_clk = clk;
-		msm_camio_clk_rate_set_2(clk, camio_clk.mclk_clk_rate);
-		break;
-	case CAMIO_VFE_CLK:
-		clk = clk_get(NULL, "vfe_clk");
-		camio_vfe_clk = clk;
-		msm_camio_clk_rate_set_2(clk, camio_clk.vfe_clk_rate);
-		break;
-	case CAMIO_CSI0_VFE_CLK:
-		clk = clk_get(&camio_dev->dev, "csi_vfe_clk");
-		camio_csi0_vfe_clk = clk;
-		break;
-	case CAMIO_CSI1_VFE_CLK:
-		clk = clk_get(NULL, "csi_vfe_clk");
-		camio_csi1_vfe_clk = clk;
-		break;
-	case CAMIO_CSI_SRC_CLK:
-		clk = clk_get(NULL, "csi_src_clk");
-		camio_csi_src_clk = clk;
-		break;
-	case CAMIO_CSI0_CLK:
-		clk = clk_get(&camio_dev->dev, "csi_clk");
-		camio_csi0_clk = clk;
-		msm_camio_clk_rate_set_2(clk, 400000000);
-		break;
-	case CAMIO_CSI1_CLK:
-		clk = clk_get(NULL, "csi_clk");
-		camio_csi1_clk = clk;
-		break;
-	case CAMIO_CSI0_PCLK:
-		clk = clk_get(&camio_dev->dev, "csi_pclk");
-		camio_csi0_pclk = clk;
-		break;
-	case CAMIO_CSI1_PCLK:
-		clk = clk_get(NULL, "csi_pclk");
-		camio_csi1_pclk = clk;
-		break;
-	default:
-		break;
-	}
-
-	if (!IS_ERR(clk))
-		clk_enable(clk);
-	else
-		rc = -1;
-	return rc;
-}
-
-int msm_camio_clk_disable(enum msm_camio_clk_type clktype)
-{
-	int rc = 0;
-	struct clk *clk = NULL;
-
-	switch (clktype) {
-	case CAMIO_CAM_MCLK_CLK:
-		clk = camio_cam_clk;
-		break;
-	case CAMIO_VFE_CLK:
-		clk = camio_vfe_clk;
-		break;
-	case CAMIO_CSI_SRC_CLK:
-		clk = camio_csi_src_clk;
-		break;
-	case CAMIO_CSI0_VFE_CLK:
-		clk = camio_csi0_vfe_clk;
-		break;
-	case CAMIO_CSI1_VFE_CLK:
-		clk = camio_csi1_vfe_clk;
-		break;
-	case CAMIO_CSI0_CLK:
-		clk = camio_csi0_clk;
-		break;
-	case CAMIO_CSI1_CLK:
-		clk = camio_csi1_clk;
-		break;
-	case CAMIO_CSI0_PCLK:
-		clk = camio_csi0_pclk;
-		break;
-	case CAMIO_CSI1_PCLK:
-		clk = camio_csi1_pclk;
-		break;
-	default:
-		break;
-	}
-
-	if (!IS_ERR(clk)) {
-		clk_disable(clk);
-		clk_put(clk);
-	} else
-		rc = -1;
-	return rc;
-}
-
-void msm_camio_clk_rate_set(int rate)
-{
-	struct clk *clk = camio_cam_clk;
-	clk_set_rate(clk, rate);
-}
-
-void msm_camio_clk_rate_set_2(struct clk *clk, int rate)
-{
-	clk_set_rate(clk, rate);
-}
-
-static irqreturn_t msm_io_csi_irq(int irq_num, void *data)
-{
-	uint32_t irq;
-
-	irq = msm_camera_io_r(csibase + MIPI_INTERRUPT_STATUS);
-	CDBG("%s MIPI_INTERRUPT_STATUS = 0x%x\n", __func__, irq);
-	msm_camera_io_w(irq, csibase + MIPI_INTERRUPT_STATUS);
-
-	/* TODO: Needs to send this info to upper layers */
-	if ((irq >> 19) & 0x1)
-		pr_info("Unsupported packet format is received\n");
-	return IRQ_HANDLED;
-}
-
-int msm_camio_enable(struct platform_device *pdev)
-{
-	int rc = 0;
-	const struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-	uint32_t val;
-
-	camio_dev = pdev;
-	camio_ext = camdev->ioext;
-	camio_clk = camdev->ioclk;
-
-	msm_camio_clk_enable(CAMIO_VFE_CLK);
-	msm_camio_clk_enable(CAMIO_CSI0_VFE_CLK);
-	msm_camio_clk_enable(CAMIO_CSI1_VFE_CLK);
-	msm_camio_clk_enable(CAMIO_CSI0_CLK);
-	msm_camio_clk_enable(CAMIO_CSI1_CLK);
-	msm_camio_clk_enable(CAMIO_CSI0_PCLK);
-	msm_camio_clk_enable(CAMIO_CSI1_PCLK);
-
-	csibase = ioremap(camio_ext.csiphy, camio_ext.csisz);
-	if (!csibase) {
-		rc = -ENOMEM;
-		goto csi_busy;
-	}
-	rc = request_irq(camio_ext.csiirq, msm_io_csi_irq,
-				IRQF_TRIGGER_RISING, "csi", 0);
-	if (rc < 0)
-		goto csi_irq_fail;
-
-	msleep(20);
-	val = (20 <<
-		MIPI_PHY_D0_CONTROL2_SETTLE_COUNT_SHFT) |
-		(0x0F << MIPI_PHY_D0_CONTROL2_HS_TERM_IMP_SHFT) |
-		(0x0 << MIPI_PHY_D0_CONTROL2_LP_REC_EN_SHFT) |
-		(0x1 << MIPI_PHY_D0_CONTROL2_ERR_SOT_HS_EN_SHFT);
-	CDBG("%s MIPI_PHY_D0_CONTROL2 val=0x%x\n", __func__, val);
-	msm_camera_io_w(val, csibase + MIPI_PHY_D0_CONTROL2);
-	msm_camera_io_w(val, csibase + MIPI_PHY_D1_CONTROL2);
-	msm_camera_io_w(val, csibase + MIPI_PHY_D2_CONTROL2);
-	msm_camera_io_w(val, csibase + MIPI_PHY_D3_CONTROL2);
-
-	val = (0x0F << MIPI_PHY_CL_CONTROL_HS_TERM_IMP_SHFT) |
-		(0x0 << MIPI_PHY_CL_CONTROL_LP_REC_EN_SHFT);
-	CDBG("%s MIPI_PHY_CL_CONTROL val=0x%x\n", __func__, val);
-	msm_camera_io_w(val, csibase + MIPI_PHY_CL_CONTROL);
-
-	appbase = ioremap(camio_ext.appphy,
-		camio_ext.appsz);
-	if (!appbase) {
-		rc = -ENOMEM;
-		goto csi_irq_fail;
-	}
-	return 0;
-
-csi_irq_fail:
-	iounmap(csibase);
-csi_busy:
-	msm_camio_clk_disable(CAMIO_CAM_MCLK_CLK);
-	msm_camio_clk_disable(CAMIO_VFE_CLK);
-	msm_camio_clk_disable(CAMIO_CSI0_VFE_CLK);
-	msm_camio_clk_disable(CAMIO_CSI1_VFE_CLK);
-	msm_camio_clk_disable(CAMIO_CSI0_CLK);
-	msm_camio_clk_disable(CAMIO_CSI1_CLK);
-	msm_camio_clk_disable(CAMIO_CSI0_PCLK);
-	msm_camio_clk_disable(CAMIO_CSI1_PCLK);
-	camdev->camera_gpio_off();
-	return rc;
-}
-
-void msm_camio_disable(struct platform_device *pdev)
-{
-	uint32_t val;
-
-	val = (20 <<
-		MIPI_PHY_D0_CONTROL2_SETTLE_COUNT_SHFT) |
-		(0x0F << MIPI_PHY_D0_CONTROL2_HS_TERM_IMP_SHFT) |
-		(0x0 << MIPI_PHY_D0_CONTROL2_LP_REC_EN_SHFT) |
-		(0x1 << MIPI_PHY_D0_CONTROL2_ERR_SOT_HS_EN_SHFT);
-	CDBG("%s MIPI_PHY_D0_CONTROL2 val=0x%x\n", __func__, val);
-	msm_camera_io_w(val, csibase + MIPI_PHY_D0_CONTROL2);
-	msm_camera_io_w(val, csibase + MIPI_PHY_D1_CONTROL2);
-	msm_camera_io_w(val, csibase + MIPI_PHY_D2_CONTROL2);
-	msm_camera_io_w(val, csibase + MIPI_PHY_D3_CONTROL2);
-
-	val = (0x0F << MIPI_PHY_CL_CONTROL_HS_TERM_IMP_SHFT) |
-		(0x0 << MIPI_PHY_CL_CONTROL_LP_REC_EN_SHFT);
-	CDBG("%s MIPI_PHY_CL_CONTROL val=0x%x\n", __func__, val);
-	msm_camera_io_w(val, csibase + MIPI_PHY_CL_CONTROL);
-	msleep(20);
-
-	free_irq(camio_ext.csiirq, 0);
-	iounmap(csibase);
-	iounmap(appbase);
-	CDBG("disable clocks\n");
-
-	msm_camio_clk_disable(CAMIO_VFE_CLK);
-	msm_camio_clk_disable(CAMIO_CSI0_CLK);
-	msm_camio_clk_disable(CAMIO_CSI1_CLK);
-	msm_camio_clk_disable(CAMIO_CSI0_VFE_CLK);
-	msm_camio_clk_disable(CAMIO_CSI1_VFE_CLK);
-	msm_camio_clk_disable(CAMIO_CSI0_PCLK);
-	msm_camio_clk_disable(CAMIO_CSI1_PCLK);
-}
-
-int msm_camio_sensor_clk_on(struct platform_device *pdev)
-{
-	int rc = 0;
-	const struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-	camio_dev = pdev;
-	camio_ext = camdev->ioext;
-	camio_clk = camdev->ioclk;
-
-	rc = camdev->camera_gpio_on();
-	if (rc < 0)
-		return rc;
-	return msm_camio_clk_enable(CAMIO_CAM_MCLK_CLK);
-}
-
-int msm_camio_sensor_clk_off(struct platform_device *pdev)
-{
-	const struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-	camdev->camera_gpio_off();
-	return msm_camio_clk_disable(CAMIO_CAM_MCLK_CLK);
-
-}
-
-void msm_camio_vfe_blk_reset(void)
-{
-	uint32_t val;
-
-	/* do apps reset */
-	val = msm_camera_io_r(appbase + 0x00000210);
-	val |= 0x1;
-	msm_camera_io_w(val, appbase + 0x00000210);
-	usleep_range(10000, 11000);
-
-	val = msm_camera_io_r(appbase + 0x00000210);
-	val &= ~0x1;
-	msm_camera_io_w(val, appbase + 0x00000210);
-	usleep_range(10000, 11000);
-
-	/* do axi reset */
-	val = msm_camera_io_r(appbase + 0x00000208);
-	val |= 0x1;
-	msm_camera_io_w(val, appbase + 0x00000208);
-	usleep_range(10000, 11000);
-
-	val = msm_camera_io_r(appbase + 0x00000208);
-	val &= ~0x1;
-	msm_camera_io_w(val, appbase + 0x00000208);
-	mb();
-	usleep_range(10000, 11000);
-	return;
-}
-
-int msm_camio_probe_on(struct platform_device *pdev)
-{
-	int rc = 0;
-	const struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-	camio_dev = pdev;
-	camio_ext = camdev->ioext;
-	camio_clk = camdev->ioclk;
-
-	msm_camio_clk_enable(CAMIO_CSI0_PCLK);
-	msm_camio_clk_enable(CAMIO_CSI1_PCLK);
-
-	rc = camdev->camera_gpio_on();
-	if (rc < 0)
-		return rc;
-	return msm_camio_clk_enable(CAMIO_CAM_MCLK_CLK);
-}
-
-int msm_camio_probe_off(struct platform_device *pdev)
-{
-	const struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-	camdev->camera_gpio_off();
-
-	csibase = ioremap(camdev->ioext.csiphy, camdev->ioext.csisz);
-	if (!csibase) {
-		pr_err("ioremap failed for CSIBASE\n");
-		goto ioremap_fail;
-	}
-	msm_camera_io_w(MIPI_PWR_CNTL_DIS, csibase + MIPI_PWR_CNTL);
-	iounmap(csibase);
-ioremap_fail:
-	msm_camio_clk_disable(CAMIO_CSI0_PCLK);
-	msm_camio_clk_disable(CAMIO_CSI1_PCLK);
-	return msm_camio_clk_disable(CAMIO_CAM_MCLK_CLK);
-}
-
-int msm_camio_csi_config(struct msm_camera_csi_params *csi_params)
-{
-	int rc = 0;
-	uint32_t val = 0;
-
-	CDBG("msm_camio_csi_config\n");
-
-	/* Enable error correction for DATA lane. Applies to all data lanes */
-	msm_camera_io_w(0x4, csibase + MIPI_PHY_CONTROL);
-
-	msm_camera_io_w(MIPI_PROTOCOL_CONTROL_SW_RST_BMSK,
-		csibase + MIPI_PROTOCOL_CONTROL);
-
-	val = MIPI_PROTOCOL_CONTROL_LONG_PACKET_HEADER_CAPTURE_BMSK |
-		MIPI_PROTOCOL_CONTROL_DECODE_ID_BMSK |
-		MIPI_PROTOCOL_CONTROL_ECC_EN_BMSK;
-	val |= (uint32_t)(csi_params->data_format) <<
-		MIPI_PROTOCOL_CONTROL_DATA_FORMAT_SHFT;
-	val |= csi_params->dpcm_scheme <<
-		MIPI_PROTOCOL_CONTROL_DPCM_SCHEME_SHFT;
-	CDBG("%s MIPI_PROTOCOL_CONTROL val=0x%x\n", __func__, val);
-	msm_camera_io_w(val, csibase + MIPI_PROTOCOL_CONTROL);
-
-	val = (0x1 << MIPI_CALIBRATION_CONTROL_SWCAL_CAL_EN_SHFT) |
-		(0x1 <<
-		MIPI_CALIBRATION_CONTROL_SWCAL_STRENGTH_OVERRIDE_EN_SHFT) |
-		(0x1 << MIPI_CALIBRATION_CONTROL_CAL_SW_HW_MODE_SHFT) |
-		(0x1 << MIPI_CALIBRATION_CONTROL_MANUAL_OVERRIDE_EN_SHFT);
-	CDBG("%s MIPI_CALIBRATION_CONTROL val=0x%x\n", __func__, val);
-	msm_camera_io_w(val, csibase + MIPI_CALIBRATION_CONTROL);
-
-	val = (csi_params->settle_cnt <<
-		MIPI_PHY_D0_CONTROL2_SETTLE_COUNT_SHFT) |
-		(0x0F << MIPI_PHY_D0_CONTROL2_HS_TERM_IMP_SHFT) |
-		(0x1 << MIPI_PHY_D0_CONTROL2_LP_REC_EN_SHFT) |
-		(0x1 << MIPI_PHY_D0_CONTROL2_ERR_SOT_HS_EN_SHFT);
-	CDBG("%s MIPI_PHY_D0_CONTROL2 val=0x%x\n", __func__, val);
-	msm_camera_io_w(val, csibase + MIPI_PHY_D0_CONTROL2);
-	msm_camera_io_w(val, csibase + MIPI_PHY_D1_CONTROL2);
-	msm_camera_io_w(val, csibase + MIPI_PHY_D2_CONTROL2);
-	msm_camera_io_w(val, csibase + MIPI_PHY_D3_CONTROL2);
-
-
-	val = (0x0F << MIPI_PHY_CL_CONTROL_HS_TERM_IMP_SHFT) |
-		(0x1 << MIPI_PHY_CL_CONTROL_LP_REC_EN_SHFT);
-	CDBG("%s MIPI_PHY_CL_CONTROL val=0x%x\n", __func__, val);
-	msm_camera_io_w(val, csibase + MIPI_PHY_CL_CONTROL);
-
-	val = 0 << MIPI_PHY_D0_CONTROL_HS_REC_EQ_SHFT;
-	msm_camera_io_w(val, csibase + MIPI_PHY_D0_CONTROL);
-
-	val = (0x1 << MIPI_PHY_D1_CONTROL_MIPI_CLK_PHY_SHUTDOWNB_SHFT) |
-		(0x1 << MIPI_PHY_D1_CONTROL_MIPI_DATA_PHY_SHUTDOWNB_SHFT);
-	CDBG("%s MIPI_PHY_D1_CONTROL val=0x%x\n", __func__, val);
-	msm_camera_io_w(val, csibase + MIPI_PHY_D1_CONTROL);
-
-	msm_camera_io_w(0x00000000, csibase + MIPI_PHY_D2_CONTROL);
-	msm_camera_io_w(0x00000000, csibase + MIPI_PHY_D3_CONTROL);
-
-	/* program number of lanes and lane mapping */
-	switch (csi_params->lane_cnt) {
-	case 1:
-		msm_camera_io_w(csi_params->lane_assign << 8 | 0x4,
-			csibase + MIPI_CAMERA_CNTL);
-		break;
-	case 2:
-		msm_camera_io_w(csi_params->lane_assign << 8 | 0x5,
-			csibase + MIPI_CAMERA_CNTL);
-		break;
-	case 3:
-		msm_camera_io_w(csi_params->lane_assign << 8 | 0x6,
-			csibase + MIPI_CAMERA_CNTL);
-		break;
-	case 4:
-		msm_camera_io_w(csi_params->lane_assign << 8 | 0x7,
-			csibase + MIPI_CAMERA_CNTL);
-		break;
-	}
-
-	msm_camera_io_w(0xFFFFF3FF, csibase + MIPI_INTERRUPT_MASK);
-	/*clear IRQ bits - write 1 clears the status*/
-	msm_camera_io_w(0xFFFFF3FF, csibase + MIPI_INTERRUPT_STATUS);
-
-	return rc;
-}
-
-void msm_camio_set_perf_lvl(enum msm_bus_perf_setting perf_setting)
-{
-	switch (perf_setting) {
-	case S_INIT:
-		add_axi_qos();
-		break;
-	case S_PREVIEW:
-		update_axi_qos(MSM_AXI_QOS_PREVIEW);
-		break;
-	case S_VIDEO:
-		update_axi_qos(MSM_AXI_QOS_RECORDING);
-		break;
-	case S_CAPTURE:
-		update_axi_qos(MSM_AXI_QOS_SNAPSHOT);
-		break;
-	case S_DEFAULT:
-		update_axi_qos(PM_QOS_DEFAULT_VALUE);
-		break;
-	case S_EXIT:
-		release_axi_qos();
-		break;
-	default:
-		CDBG("%s: INVALID CASE\n", __func__);
-	}
-}
diff --git a/drivers/media/video/msm/io/msm_io_7x27a_v4l2.c b/drivers/media/video/msm/io/msm_io_7x27a_v4l2.c
deleted file mode 100644
index 9e7ede4..0000000
--- a/drivers/media/video/msm/io/msm_io_7x27a_v4l2.c
+++ /dev/null
@@ -1,218 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/delay.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/pm_qos.h>
-#include <linux/module.h>
-#include <mach/board.h>
-#include <mach/camera.h>
-#include <mach/camera.h>
-#include <mach/clk.h>
-#include <mach/msm_bus.h>
-#include <mach/msm_bus_board.h>
-#include <mach/dal_axi.h>
-
-#define MSM_AXI_QOS_PREVIEW 200000
-#define MSM_AXI_QOS_SNAPSHOT 200000
-#define MSM_AXI_QOS_RECORDING 200000
-
-static struct clk *camio_cam_clk;
-static struct resource *clk_ctrl_mem;
-static struct msm_camera_io_clk camio_clk;
-static int apps_reset;
-void __iomem *appbase;
-
-void msm_camio_clk_rate_set_2(struct clk *clk, int rate)
-{
-	clk_set_rate(clk, rate);
-}
-int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
-{
-	int rc = 0;
-	struct clk *clk = NULL;
-
-	switch (clktype) {
-	case CAMIO_CAM_MCLK_CLK:
-		clk = clk_get(NULL, "cam_m_clk");
-		camio_cam_clk = clk;
-		msm_camio_clk_rate_set_2(clk, camio_clk.mclk_clk_rate);
-		break;
-	default:
-		break;
-	}
-
-	if (!IS_ERR(clk))
-		clk_enable(clk);
-	else
-		rc = -1;
-	return rc;
-}
-
-int msm_camio_clk_disable(enum msm_camio_clk_type clktype)
-{
-	int rc = 0;
-	struct clk *clk = NULL;
-
-	switch (clktype) {
-	case CAMIO_CAM_MCLK_CLK:
-		clk = camio_cam_clk;
-		break;
-	default:
-		break;
-	}
-
-	if (!IS_ERR(clk)) {
-		clk_disable(clk);
-		clk_put(clk);
-	} else
-		rc = -1;
-	return rc;
-}
-
-void msm_camio_clk_rate_set(int rate)
-{
-	struct clk *clk = camio_cam_clk;
-	clk_set_rate(clk, rate);
-}
-
-void msm_camio_vfe_blk_reset_2(void)
-{
-	uint32_t val;
-
-	/* do apps reset */
-	val = readl_relaxed(appbase + 0x00000210);
-	val |= 0x1;
-	writel_relaxed(val, appbase + 0x00000210);
-	usleep_range(10000, 11000);
-
-	val = readl_relaxed(appbase + 0x00000210);
-	val &= ~0x1;
-	writel_relaxed(val, appbase + 0x00000210);
-	usleep_range(10000, 11000);
-
-	/* do axi reset */
-	val = readl_relaxed(appbase + 0x00000208);
-	val |= 0x1;
-	writel_relaxed(val, appbase + 0x00000208);
-	usleep_range(10000, 11000);
-
-	val = readl_relaxed(appbase + 0x00000208);
-	val &= ~0x1;
-	writel_relaxed(val, appbase + 0x00000208);
-	mb();
-	usleep_range(10000, 11000);
-}
-
-void msm_camio_vfe_blk_reset_3(void)
-{
-	uint32_t val;
-
-	if (!apps_reset)
-		return;
-
-	/* do apps reset */
-	val = readl_relaxed(appbase + 0x00000210);
-	val |= 0x10A0000;
-	writel_relaxed(val, appbase + 0x00000210);
-	usleep_range(10000, 11000);
-
-	val = readl_relaxed(appbase + 0x00000210);
-	val &= ~(0x10A0000);
-	writel_relaxed(val, appbase + 0x00000210);
-	usleep_range(10000, 11000);
-	mb();
-}
-
-void msm_camio_set_perf_lvl(enum msm_bus_perf_setting perf_setting)
-{
-	switch (perf_setting) {
-	case S_INIT:
-		add_axi_qos();
-		update_axi_qos(MSM_AXI_QOS_PREVIEW);
-		axi_allocate(AXI_FLOW_VIEWFINDER_HI);
-		break;
-	case S_PREVIEW:
-		break;
-	case S_VIDEO:
-		break;
-	case S_CAPTURE:
-		break;
-	case S_DEFAULT:
-		break;
-	case S_EXIT:
-		axi_free(AXI_FLOW_VIEWFINDER_HI);
-		release_axi_qos();
-		break;
-	default:
-		CDBG("%s: INVALID CASE\n", __func__);
-	}
-}
-
-static int __devinit clkctl_probe(struct platform_device *pdev)
-{
-	int rc = 0;
-
-	apps_reset = *(int *)pdev->dev.platform_data;
-	clk_ctrl_mem = platform_get_resource_byname(pdev,
-					IORESOURCE_MEM, "clk_ctl");
-	if (!clk_ctrl_mem) {
-		pr_err("%s: no mem resource:3?\n", __func__);
-		return -ENODEV;
-	}
-
-	appbase = ioremap(clk_ctrl_mem->start,
-		resource_size(clk_ctrl_mem));
-	if (!appbase) {
-		pr_err("clkctl_probe: appbase:err\n");
-		rc = -ENOMEM;
-		goto ioremap_fail;
-	}
-	return 0;
-
-ioremap_fail:
-	msm_camio_clk_disable(CAMIO_CAM_MCLK_CLK);
-	return rc;
-}
-
-static int clkctl_remove(struct platform_device *pdev)
-{
-	if (clk_ctrl_mem)
-		iounmap(clk_ctrl_mem);
-
-	return 0;
-}
-
-static struct platform_driver clkctl_driver = {
-	.probe  = clkctl_probe,
-	.remove = clkctl_remove,
-	.driver = {
-		.name = "msm_clk_ctl",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init msm_clkctl_init_module(void)
-{
-	return platform_driver_register(&clkctl_driver);
-}
-
-static void __exit msm_clkctl_exit_module(void)
-{
-	platform_driver_unregister(&clkctl_driver);
-}
-
-module_init(msm_clkctl_init_module);
-module_exit(msm_clkctl_exit_module);
-MODULE_DESCRIPTION("CAM IO driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/io/msm_io_8960.c b/drivers/media/video/msm/io/msm_io_8960.c
deleted file mode 100644
index 1b56578..0000000
--- a/drivers/media/video/msm/io/msm_io_8960.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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/delay.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/regulator/consumer.h>
-#include <linux/mfd/pm8xxx/pm8921.h>
-#include <mach/gpio.h>
-#include <mach/gpiomux.h>
-#include <mach/board.h>
-#include <mach/camera.h>
-#include <mach/vreg.h>
-#include <mach/camera.h>
-#include <mach/clk.h>
-#include <mach/msm_bus.h>
-#include <mach/msm_bus_board.h>
-
-#define BUFF_SIZE_128 128
-
-void msm_camio_clk_rate_set_2(struct clk *clk, int rate)
-{
-	clk_set_rate(clk, rate);
-}
-
-void msm_camio_bus_scale_cfg(struct msm_bus_scale_pdata *cam_bus_scale_table,
-		enum msm_bus_perf_setting perf_setting)
-{
-	static uint32_t bus_perf_client;
-	int rc = 0;
-	switch (perf_setting) {
-	case S_INIT:
-		bus_perf_client =
-			msm_bus_scale_register_client(cam_bus_scale_table);
-		if (!bus_perf_client) {
-			CDBG("%s: Registration Failed!!!\n", __func__);
-			bus_perf_client = 0;
-			return;
-		}
-		CDBG("%s: S_INIT rc = %u\n", __func__, bus_perf_client);
-		break;
-	case S_EXIT:
-		if (bus_perf_client) {
-			CDBG("%s: S_EXIT\n", __func__);
-			msm_bus_scale_unregister_client(bus_perf_client);
-		} else
-			CDBG("%s: Bus Client NOT Registered!!!\n", __func__);
-		break;
-	case S_PREVIEW:
-		if (bus_perf_client) {
-			rc = msm_bus_scale_client_update_request(
-				bus_perf_client, 1);
-			CDBG("%s: S_PREVIEW rc = %d\n", __func__, rc);
-		} else
-			CDBG("%s: Bus Client NOT Registered!!!\n", __func__);
-		break;
-	case S_VIDEO:
-		if (bus_perf_client) {
-			rc = msm_bus_scale_client_update_request(
-				bus_perf_client, 2);
-			CDBG("%s: S_VIDEO rc = %d\n", __func__, rc);
-		} else
-			CDBG("%s: Bus Client NOT Registered!!!\n", __func__);
-		break;
-	case S_CAPTURE:
-		if (bus_perf_client) {
-			rc = msm_bus_scale_client_update_request(
-				bus_perf_client, 3);
-			CDBG("%s: S_CAPTURE rc = %d\n", __func__, rc);
-		} else
-			CDBG("%s: Bus Client NOT Registered!!!\n", __func__);
-		break;
-	case S_ZSL:
-		if (bus_perf_client) {
-			rc = msm_bus_scale_client_update_request(
-				bus_perf_client, 4);
-			CDBG("%s: S_ZSL rc = %d\n", __func__, rc);
-		} else
-			CDBG("%s: Bus Client NOT Registered!!!\n", __func__);
-		break;
-	case S_LIVESHOT:
-		if (bus_perf_client) {
-			rc = msm_bus_scale_client_update_request(
-				bus_perf_client, 5);
-			CDBG("%s: S_LIVESHOT rc = %d\n", __func__, rc);
-		} else
-			CDBG("%s: Bus Client NOT Registered!!!\n", __func__);
-		break;
-	case S_DUAL:
-		if (bus_perf_client) {
-			rc = msm_bus_scale_client_update_request(
-				bus_perf_client, 6);
-			CDBG("%s: S_DUAL rc = %d\n", __func__, rc);
-		} else
-			CDBG("%s: Bus Client NOT Registered!!!\n", __func__);
-		break;
-	case S_ADV_VIDEO:
-		if (bus_perf_client) {
-			rc = msm_bus_scale_client_update_request(
-				bus_perf_client, 7);
-			CDBG("%s: S_ADV_VIDEO rc = %d\n", __func__, rc);
-		} else
-			CDBG("%s: Bus Client NOT Registered!!!\n", __func__);
-		break;
-	case S_DEFAULT:
-		break;
-	default:
-		pr_warning("%s: INVALID CASE\n", __func__);
-	}
-}
diff --git a/drivers/media/video/msm/io/msm_io_8x60.c b/drivers/media/video/msm/io/msm_io_8x60.c
deleted file mode 100644
index baa1245..0000000
--- a/drivers/media/video/msm/io/msm_io_8x60.c
+++ /dev/null
@@ -1,820 +0,0 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. 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/delay.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/regulator/consumer.h>
-#include <mach/gpio.h>
-#include <mach/board.h>
-#include <mach/camera.h>
-#include <mach/vreg.h>
-#include <mach/camera.h>
-#include <mach/clk.h>
-#include <mach/msm_bus.h>
-#include <mach/msm_bus_board.h>
-
-
-/* MIPI	CSI	controller registers */
-#define	MIPI_PHY_CONTROL			0x00000000
-#define	MIPI_PROTOCOL_CONTROL		0x00000004
-#define	MIPI_INTERRUPT_STATUS		0x00000008
-#define	MIPI_INTERRUPT_MASK			0x0000000C
-#define	MIPI_CAMERA_CNTL			0x00000024
-#define	MIPI_CALIBRATION_CONTROL	0x00000018
-#define	MIPI_PHY_D0_CONTROL2		0x00000038
-#define	MIPI_PHY_D1_CONTROL2		0x0000003C
-#define	MIPI_PHY_D2_CONTROL2		0x00000040
-#define	MIPI_PHY_D3_CONTROL2		0x00000044
-#define	MIPI_PHY_CL_CONTROL			0x00000048
-#define	MIPI_PHY_D0_CONTROL			0x00000034
-#define	MIPI_PHY_D1_CONTROL			0x00000020
-#define	MIPI_PHY_D2_CONTROL			0x0000002C
-#define	MIPI_PHY_D3_CONTROL			0x00000030
-#define	MIPI_PROTOCOL_CONTROL_SW_RST_BMSK			0x8000000
-#define	MIPI_PROTOCOL_CONTROL_LONG_PACKET_HEADER_CAPTURE_BMSK	0x200000
-#define	MIPI_PROTOCOL_CONTROL_DATA_FORMAT_BMSK			0x180000
-#define	MIPI_PROTOCOL_CONTROL_DECODE_ID_BMSK			0x40000
-#define	MIPI_PROTOCOL_CONTROL_ECC_EN_BMSK			0x20000
-#define	MIPI_CALIBRATION_CONTROL_SWCAL_CAL_EN_SHFT		0x16
-#define	MIPI_CALIBRATION_CONTROL_SWCAL_STRENGTH_OVERRIDE_EN_SHFT	0x15
-#define	MIPI_CALIBRATION_CONTROL_CAL_SW_HW_MODE_SHFT		0x14
-#define	MIPI_CALIBRATION_CONTROL_MANUAL_OVERRIDE_EN_SHFT	0x7
-#define	MIPI_PROTOCOL_CONTROL_DATA_FORMAT_SHFT			0x13
-#define	MIPI_PROTOCOL_CONTROL_DPCM_SCHEME_SHFT			0x1e
-#define	MIPI_PHY_D0_CONTROL2_SETTLE_COUNT_SHFT			0x18
-#define	MIPI_PHY_D0_CONTROL2_HS_TERM_IMP_SHFT			0x10
-#define	MIPI_PHY_D0_CONTROL2_LP_REC_EN_SHFT				0x4
-#define	MIPI_PHY_D0_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
-#define	MIPI_PHY_D1_CONTROL2_SETTLE_COUNT_SHFT			0x18
-#define	MIPI_PHY_D1_CONTROL2_HS_TERM_IMP_SHFT			0x10
-#define	MIPI_PHY_D1_CONTROL2_LP_REC_EN_SHFT				0x4
-#define	MIPI_PHY_D1_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
-#define	MIPI_PHY_D2_CONTROL2_SETTLE_COUNT_SHFT			0x18
-#define	MIPI_PHY_D2_CONTROL2_HS_TERM_IMP_SHFT			0x10
-#define	MIPI_PHY_D2_CONTROL2_LP_REC_EN_SHFT				0x4
-#define	MIPI_PHY_D2_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
-#define	MIPI_PHY_D3_CONTROL2_SETTLE_COUNT_SHFT			0x18
-#define	MIPI_PHY_D3_CONTROL2_HS_TERM_IMP_SHFT			0x10
-#define	MIPI_PHY_D3_CONTROL2_LP_REC_EN_SHFT				0x4
-#define	MIPI_PHY_D3_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
-#define	MIPI_PHY_CL_CONTROL_HS_TERM_IMP_SHFT			0x18
-#define	MIPI_PHY_CL_CONTROL_LP_REC_EN_SHFT				0x2
-#define	MIPI_PHY_D0_CONTROL_HS_REC_EQ_SHFT				0x1c
-#define	MIPI_PHY_D1_CONTROL_MIPI_CLK_PHY_SHUTDOWNB_SHFT		0x9
-#define	MIPI_PHY_D1_CONTROL_MIPI_DATA_PHY_SHUTDOWNB_SHFT	0x8
-#define	DBG_CSI	0
-
-static struct clk *camio_cam_clk;
-static struct clk *camio_vfe_clk;
-static struct clk *camio_csi_src_clk;
-static struct clk *camio_csi0_vfe_clk;
-static struct clk *camio_csi1_vfe_clk;
-static struct clk *camio_csi0_clk;
-static struct clk *camio_csi1_clk;
-static struct clk *camio_csi0_pclk;
-static struct clk *camio_csi1_pclk;
-static struct clk *camio_vfe_pclk;
-static struct clk *camio_vpe_clk;
-static struct clk *camio_vpe_pclk;
-static struct regulator *fs_vfe;
-static struct regulator *fs_vpe;
-static struct regulator *ldo15;
-static struct regulator *lvs0;
-static struct regulator *ldo25;
-
-static struct msm_camera_io_ext camio_ext;
-static struct msm_camera_io_clk camio_clk;
-static struct platform_device *camio_dev;
-static struct resource *csiio;
-void __iomem *csibase;
-static int vpe_clk_rate;
-struct msm_bus_scale_pdata *cam_bus_scale_table;
-
-static void msm_camera_vreg_enable(void)
-{
-	ldo15 = regulator_get(NULL, "8058_l15");
-	if (IS_ERR(ldo15)) {
-		pr_err("%s: VREG LDO15 get failed\n", __func__);
-		ldo15 = NULL;
-		return;
-	}
-	if (regulator_set_voltage(ldo15, 2850000, 2850000)) {
-		pr_err("%s: VREG LDO15 set voltage failed\n",  __func__);
-		goto ldo15_disable;
-	}
-	if (regulator_enable(ldo15)) {
-		pr_err("%s: VREG LDO15 enable failed\n", __func__);
-		goto ldo15_put;
-	}
-
-	lvs0 = regulator_get(NULL, "8058_lvs0");
-	if (IS_ERR(lvs0)) {
-		pr_err("%s: VREG LVS0 get failed\n", __func__);
-		lvs0 = NULL;
-		goto ldo15_disable;
-	}
-	if (regulator_enable(lvs0)) {
-		pr_err("%s: VREG LVS0 enable failed\n", __func__);
-		goto lvs0_put;
-	}
-
-	ldo25 = regulator_get(NULL, "8058_l25");
-	if (IS_ERR(ldo25)) {
-		pr_err("%s: VREG LDO25 get failed\n", __func__);
-		ldo25 = NULL;
-		goto lvs0_disable;
-	}
-	if (regulator_set_voltage(ldo25, 1200000, 1200000)) {
-		pr_err("%s: VREG LDO25 set voltage failed\n",  __func__);
-		goto ldo25_disable;
-	}
-	if (regulator_enable(ldo25)) {
-		pr_err("%s: VREG LDO25 enable failed\n", __func__);
-		goto ldo25_put;
-	}
-
-	fs_vfe = regulator_get(NULL, "fs_vfe");
-	if (IS_ERR(fs_vfe)) {
-		CDBG("%s: Regulator FS_VFE get failed %ld\n", __func__,
-			PTR_ERR(fs_vfe));
-		fs_vfe = NULL;
-	} else if (regulator_enable(fs_vfe)) {
-		CDBG("%s: Regulator FS_VFE enable failed\n", __func__);
-		regulator_put(fs_vfe);
-	}
-	return;
-
-ldo25_disable:
-	regulator_disable(ldo25);
-ldo25_put:
-	regulator_put(ldo25);
-lvs0_disable:
-	regulator_disable(lvs0);
-lvs0_put:
-	regulator_put(lvs0);
-ldo15_disable:
-	regulator_disable(ldo15);
-ldo15_put:
-	regulator_put(ldo15);
-}
-
-static void msm_camera_vreg_disable(void)
-{
-	if (ldo15) {
-		regulator_disable(ldo15);
-		regulator_put(ldo15);
-	}
-
-	if (lvs0) {
-		regulator_disable(lvs0);
-		regulator_put(lvs0);
-	}
-
-	if (ldo25) {
-		regulator_disable(ldo25);
-		regulator_put(ldo25);
-	}
-
-	if (fs_vfe) {
-		regulator_disable(fs_vfe);
-		regulator_put(fs_vfe);
-	}
-}
-
-int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
-{
-	int rc = 0;
-	struct clk *clk = NULL;
-
-	switch (clktype) {
-	case CAMIO_CAM_MCLK_CLK:
-		camio_cam_clk =
-		clk = clk_get(NULL, "cam_clk");
-		msm_camio_clk_rate_set_2(clk, camio_clk.mclk_clk_rate);
-		break;
-
-	case CAMIO_VFE_CLK:
-		camio_vfe_clk =
-		clk = clk_get(NULL, "vfe_clk");
-		msm_camio_clk_rate_set_2(clk, camio_clk.vfe_clk_rate);
-		break;
-
-	case CAMIO_CSI0_VFE_CLK:
-		camio_csi0_vfe_clk =
-		clk = clk_get(NULL, "csi_vfe_clk");
-		break;
-
-	case CAMIO_CSI1_VFE_CLK:
-		camio_csi1_vfe_clk =
-		clk = clk_get(&camio_dev->dev, "csi_vfe_clk");
-		break;
-
-	case CAMIO_CSI_SRC_CLK:
-		camio_csi_src_clk =
-		clk = clk_get(NULL, "csi_src_clk");
-		msm_camio_clk_rate_set_2(clk, 384000000);
-		break;
-
-	case CAMIO_CSI0_CLK:
-		camio_csi0_clk =
-		clk = clk_get(NULL, "csi_clk");
-		break;
-
-	case CAMIO_CSI1_CLK:
-		camio_csi1_clk =
-		clk = clk_get(&camio_dev->dev, "csi_clk");
-		break;
-
-	case CAMIO_VFE_PCLK:
-		camio_vfe_pclk =
-		clk = clk_get(NULL, "vfe_pclk");
-		break;
-
-	case CAMIO_CSI0_PCLK:
-		camio_csi0_pclk =
-		clk = clk_get(NULL, "csi_pclk");
-		break;
-
-	case CAMIO_CSI1_PCLK:
-		camio_csi1_pclk =
-		clk = clk_get(&camio_dev->dev, "csi_pclk");
-		break;
-
-	case CAMIO_VPE_CLK:
-		camio_vpe_clk =
-		clk = clk_get(NULL, "vpe_clk");
-		vpe_clk_rate = clk_round_rate(camio_vpe_clk, vpe_clk_rate);
-		clk_set_rate(camio_vpe_clk, vpe_clk_rate);
-		break;
-
-	case CAMIO_VPE_PCLK:
-		camio_vpe_pclk =
-		clk = clk_get(NULL, "vpe_pclk");
-		break;
-
-	default:
-		break;
-	}
-
-	if (!IS_ERR(clk))
-		clk_enable(clk);
-	else
-		rc = -1;
-	return rc;
-}
-
-int msm_camio_clk_disable(enum msm_camio_clk_type clktype)
-{
-	int rc = 0;
-	struct clk *clk = NULL;
-
-	switch (clktype) {
-	case CAMIO_CAM_MCLK_CLK:
-		clk = camio_cam_clk;
-		break;
-
-	case CAMIO_VFE_CLK:
-		clk = camio_vfe_clk;
-		break;
-
-	case CAMIO_CSI_SRC_CLK:
-		clk = camio_csi_src_clk;
-		break;
-
-	case CAMIO_CSI0_VFE_CLK:
-		clk = camio_csi0_vfe_clk;
-		break;
-
-	case CAMIO_CSI1_VFE_CLK:
-		clk = camio_csi1_vfe_clk;
-		break;
-
-	case CAMIO_CSI0_CLK:
-		clk = camio_csi0_clk;
-		break;
-
-	case CAMIO_CSI1_CLK:
-		clk = camio_csi1_clk;
-		break;
-
-	case CAMIO_VFE_PCLK:
-		clk = camio_vfe_pclk;
-		break;
-
-	case CAMIO_CSI0_PCLK:
-		clk = camio_csi0_pclk;
-		break;
-
-	case CAMIO_CSI1_PCLK:
-		clk = camio_csi1_pclk;
-		break;
-
-	case CAMIO_VPE_CLK:
-		clk = camio_vpe_clk;
-		break;
-
-	case CAMIO_VPE_PCLK:
-		clk = camio_vpe_pclk;
-		break;
-
-	default:
-		break;
-	}
-
-	if (!IS_ERR(clk)) {
-		clk_disable(clk);
-		clk_put(clk);
-	} else
-		rc = -1;
-	return rc;
-}
-
-int msm_camio_vfe_clk_rate_set(int rate)
-{
-	int rc = 0;
-	struct clk *clk = camio_vfe_clk;
-	if (rate > clk_get_rate(clk))
-		rc = clk_set_rate(clk, rate);
-	return rc;
-}
-
-void msm_camio_clk_rate_set(int rate)
-{
-	struct clk *clk = camio_cam_clk;
-	clk_set_rate(clk, rate);
-}
-
-void msm_camio_clk_rate_set_2(struct clk *clk, int rate)
-{
-	clk_set_rate(clk, rate);
-}
-
-static irqreturn_t msm_io_csi_irq(int irq_num, void *data)
-{
-	uint32_t irq = 0;
-	if (csibase != NULL)
-		irq = msm_camera_io_r(csibase + MIPI_INTERRUPT_STATUS);
-	CDBG("%s MIPI_INTERRUPT_STATUS = 0x%x\n", __func__, irq);
-	if (csibase != NULL)
-		msm_camera_io_w(irq, csibase + MIPI_INTERRUPT_STATUS);
-	return IRQ_HANDLED;
-}
-
-int msm_camio_vpe_clk_disable(void)
-{
-	int rc = 0;
-	if (fs_vpe) {
-		regulator_disable(fs_vpe);
-		regulator_put(fs_vpe);
-	}
-
-	rc = msm_camio_clk_disable(CAMIO_VPE_CLK);
-	if (rc < 0)
-		return rc;
-	rc = msm_camio_clk_disable(CAMIO_VPE_PCLK);
-	return rc;
-}
-
-int msm_camio_vpe_clk_enable(uint32_t clk_rate)
-{
-	int rc = 0;
-	fs_vpe = regulator_get(NULL, "fs_vpe");
-	if (IS_ERR(fs_vpe)) {
-		CDBG("%s: Regulator FS_VPE get failed %ld\n", __func__,
-			PTR_ERR(fs_vpe));
-		fs_vpe = NULL;
-	} else if (regulator_enable(fs_vpe)) {
-		CDBG("%s: Regulator FS_VPE enable failed\n", __func__);
-		regulator_put(fs_vpe);
-	}
-
-	vpe_clk_rate = clk_rate;
-	rc = msm_camio_clk_enable(CAMIO_VPE_CLK);
-	if (rc < 0)
-		return rc;
-
-	rc = msm_camio_clk_enable(CAMIO_VPE_PCLK);
-	return rc;
-}
-
-#ifdef DBG_CSI
-static int csi_request_irq(void)
-{
-	return request_irq(camio_ext.csiirq, msm_io_csi_irq,
-		IRQF_TRIGGER_HIGH, "csi", 0);
-}
-#else
-static int csi_request_irq(void) { return 0; }
-#endif
-
-#ifdef DBG_CSI
-static void csi_free_irq(void)
-{
-	free_irq(camio_ext.csiirq, 0);
-}
-#else
-static void csi_free_irq(void) { return 0; }
-#endif
-
-int msm_camio_enable(struct platform_device *pdev)
-{
-	int rc = 0;
-	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-	camio_dev = pdev;
-	camio_ext = camdev->ioext;
-	camio_clk = camdev->ioclk;
-	cam_bus_scale_table = camdev->cam_bus_scale_table;
-
-	msm_camio_clk_enable(CAMIO_VFE_CLK);
-	msm_camio_clk_enable(CAMIO_CSI0_VFE_CLK);
-	msm_camio_clk_enable(CAMIO_CSI1_VFE_CLK);
-	msm_camio_clk_enable(CAMIO_CSI_SRC_CLK);
-	msm_camio_clk_enable(CAMIO_CSI0_CLK);
-	msm_camio_clk_enable(CAMIO_CSI1_CLK);
-	msm_camio_clk_enable(CAMIO_VFE_PCLK);
-	msm_camio_clk_enable(CAMIO_CSI0_PCLK);
-	msm_camio_clk_enable(CAMIO_CSI1_PCLK);
-
-	csiio = request_mem_region(camio_ext.csiphy,
-		camio_ext.csisz, pdev->name);
-	if (!csiio) {
-		rc = -EBUSY;
-		goto common_fail;
-	}
-	csibase = ioremap(camio_ext.csiphy,
-		camio_ext.csisz);
-	if (!csibase) {
-		rc = -ENOMEM;
-		goto csi_busy;
-	}
-	rc = csi_request_irq();
-	if (rc < 0)
-		goto csi_irq_fail;
-
-	return 0;
-
-csi_irq_fail:
-	iounmap(csibase);
-	csibase = NULL;
-csi_busy:
-	release_mem_region(camio_ext.csiphy, camio_ext.csisz);
-	csibase = NULL;
-common_fail:
-	msm_camio_clk_disable(CAMIO_CAM_MCLK_CLK);
-	msm_camio_clk_disable(CAMIO_CSI0_VFE_CLK);
-	msm_camio_clk_disable(CAMIO_CSI0_CLK);
-	msm_camio_clk_disable(CAMIO_CSI1_VFE_CLK);
-	msm_camio_clk_disable(CAMIO_CSI1_CLK);
-	msm_camio_clk_disable(CAMIO_VFE_PCLK);
-	msm_camio_clk_disable(CAMIO_CSI0_PCLK);
-	msm_camio_clk_disable(CAMIO_CSI1_PCLK);
-	msm_camera_vreg_disable();
-	camdev->camera_gpio_off();
-	return rc;
-}
-
-static void msm_camio_csi_disable(void)
-{
-	uint32_t val;
-
-	val = 0x0;
-	if (csibase != NULL) {
-		CDBG("%s MIPI_PHY_D0_CONTROL2 val=0x%x\n", __func__, val);
-		msm_camera_io_w(val, csibase + MIPI_PHY_D0_CONTROL2);
-		msm_camera_io_w(val, csibase + MIPI_PHY_D1_CONTROL2);
-		msm_camera_io_w(val, csibase + MIPI_PHY_D2_CONTROL2);
-		msm_camera_io_w(val, csibase + MIPI_PHY_D3_CONTROL2);
-		CDBG("%s MIPI_PHY_CL_CONTROL val=0x%x\n", __func__, val);
-		msm_camera_io_w(val, csibase + MIPI_PHY_CL_CONTROL);
-		msleep(20);
-		val = msm_camera_io_r(csibase + MIPI_PHY_D1_CONTROL);
-		val &=
-		~((0x1 << MIPI_PHY_D1_CONTROL_MIPI_CLK_PHY_SHUTDOWNB_SHFT)
-		|(0x1 << MIPI_PHY_D1_CONTROL_MIPI_DATA_PHY_SHUTDOWNB_SHFT));
-		CDBG("%s MIPI_PHY_D1_CONTROL val=0x%x\n", __func__, val);
-		msm_camera_io_w(val, csibase + MIPI_PHY_D1_CONTROL);
-		usleep_range(5000, 6000);
-		msm_camera_io_w(0x0, csibase + MIPI_INTERRUPT_MASK);
-		msm_camera_io_w(0x0, csibase + MIPI_INTERRUPT_STATUS);
-		csi_free_irq();
-		iounmap(csibase);
-		csibase = NULL;
-		release_mem_region(camio_ext.csiphy, camio_ext.csisz);
-	}
-}
-void msm_camio_disable(struct platform_device *pdev)
-{
-	CDBG("disable mipi\n");
-	msm_camio_csi_disable();
-	CDBG("disable clocks\n");
-	msm_camio_clk_disable(CAMIO_CSI0_VFE_CLK);
-	msm_camio_clk_disable(CAMIO_CSI0_CLK);
-	msm_camio_clk_disable(CAMIO_CSI1_VFE_CLK);
-	msm_camio_clk_disable(CAMIO_CSI1_CLK);
-	msm_camio_clk_disable(CAMIO_VFE_PCLK);
-	msm_camio_clk_disable(CAMIO_CSI0_PCLK);
-	msm_camio_clk_disable(CAMIO_CSI1_PCLK);
-	msm_camio_clk_disable(CAMIO_CSI_SRC_CLK);
-	msm_camio_clk_disable(CAMIO_VFE_CLK);
-}
-
-int msm_camio_sensor_clk_on(struct platform_device *pdev)
-{
-	int rc = 0;
-	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-	camio_dev = pdev;
-	camio_ext = camdev->ioext;
-	camio_clk = camdev->ioclk;
-
-	msm_camera_vreg_enable();
-	usleep_range(10000, 11000);
-	rc = camdev->camera_gpio_on();
-	if (rc < 0)
-		return rc;
-	return msm_camio_clk_enable(CAMIO_CAM_MCLK_CLK);
-}
-
-int msm_camio_sensor_clk_off(struct platform_device *pdev)
-{
-	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-	msm_camera_vreg_disable();
-	camdev->camera_gpio_off();
-	return msm_camio_clk_disable(CAMIO_CAM_MCLK_CLK);
-
-}
-
-void msm_camio_vfe_blk_reset(void)
-{
-	return;
-}
-
-int msm_camio_probe_on(struct platform_device *pdev)
-{
-	int rc = 0;
-	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-	camio_dev = pdev;
-	camio_ext = camdev->ioext;
-	camio_clk = camdev->ioclk;
-
-	rc = camdev->camera_gpio_on();
-	if (rc < 0)
-		return rc;
-	msm_camera_vreg_enable();
-	return msm_camio_clk_enable(CAMIO_CAM_MCLK_CLK);
-}
-
-int msm_camio_probe_off(struct platform_device *pdev)
-{
-	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-	msm_camera_vreg_disable();
-	camdev->camera_gpio_off();
-	return msm_camio_clk_disable(CAMIO_CAM_MCLK_CLK);
-}
-
-int msm_camio_csi_config(struct msm_camera_csi_params *csi_params)
-{
-	int rc = 0;
-	uint32_t val = 0;
-	int i;
-
-	CDBG("msm_camio_csi_config\n");
-	if (csibase != NULL) {
-		/* SOT_ECC_EN enable error correction for SYNC (data-lane) */
-		msm_camera_io_w(0x4, csibase + MIPI_PHY_CONTROL);
-
-		/* SW_RST to the CSI core */
-		msm_camera_io_w(MIPI_PROTOCOL_CONTROL_SW_RST_BMSK,
-		csibase + MIPI_PROTOCOL_CONTROL);
-
-		/* PROTOCOL CONTROL */
-		val = MIPI_PROTOCOL_CONTROL_LONG_PACKET_HEADER_CAPTURE_BMSK |
-			MIPI_PROTOCOL_CONTROL_DECODE_ID_BMSK |
-			MIPI_PROTOCOL_CONTROL_ECC_EN_BMSK;
-		val |= (uint32_t)(csi_params->data_format) <<
-			MIPI_PROTOCOL_CONTROL_DATA_FORMAT_SHFT;
-		val |= csi_params->dpcm_scheme <<
-			MIPI_PROTOCOL_CONTROL_DPCM_SCHEME_SHFT;
-		CDBG("%s MIPI_PROTOCOL_CONTROL val=0x%x\n", __func__, val);
-		msm_camera_io_w(val, csibase + MIPI_PROTOCOL_CONTROL);
-
-		/* settle_cnt is very sensitive to speed!
-		increase this value to run at higher speeds */
-		val = (csi_params->settle_cnt <<
-			MIPI_PHY_D0_CONTROL2_SETTLE_COUNT_SHFT) |
-			(0x0F << MIPI_PHY_D0_CONTROL2_HS_TERM_IMP_SHFT) |
-			(0x1 << MIPI_PHY_D0_CONTROL2_LP_REC_EN_SHFT) |
-			(0x1 << MIPI_PHY_D0_CONTROL2_ERR_SOT_HS_EN_SHFT);
-		CDBG("%s MIPI_PHY_D0_CONTROL2 val=0x%x\n", __func__, val);
-		for (i = 0; i < csi_params->lane_cnt; i++)
-			msm_camera_io_w(val,
-				csibase + MIPI_PHY_D0_CONTROL2 + i * 4);
-
-		val = (0x0F << MIPI_PHY_CL_CONTROL_HS_TERM_IMP_SHFT) |
-			(0x1 << MIPI_PHY_CL_CONTROL_LP_REC_EN_SHFT);
-		CDBG("%s MIPI_PHY_CL_CONTROL val=0x%x\n", __func__, val);
-		msm_camera_io_w(val, csibase + MIPI_PHY_CL_CONTROL);
-
-		val = 0 << MIPI_PHY_D0_CONTROL_HS_REC_EQ_SHFT;
-		msm_camera_io_w(val, csibase + MIPI_PHY_D0_CONTROL);
-
-		val =
-		(0x1 << MIPI_PHY_D1_CONTROL_MIPI_CLK_PHY_SHUTDOWNB_SHFT)
-		|(0x1 << MIPI_PHY_D1_CONTROL_MIPI_DATA_PHY_SHUTDOWNB_SHFT);
-		CDBG("%s MIPI_PHY_D1_CONTROL val=0x%x\n", __func__, val);
-		msm_camera_io_w(val, csibase + MIPI_PHY_D1_CONTROL);
-
-		msm_camera_io_w(0x00000000, csibase + MIPI_PHY_D2_CONTROL);
-		msm_camera_io_w(0x00000000, csibase + MIPI_PHY_D3_CONTROL);
-
-		/* halcyon only supports 1 or 2 lane */
-		switch (csi_params->lane_cnt) {
-		case 1:
-			msm_camera_io_w(csi_params->lane_assign << 8 | 0x4,
-				csibase + MIPI_CAMERA_CNTL);
-			break;
-		case 2:
-			msm_camera_io_w(csi_params->lane_assign << 8 | 0x5,
-				csibase + MIPI_CAMERA_CNTL);
-			break;
-		case 3:
-			msm_camera_io_w(csi_params->lane_assign << 8 | 0x6,
-				csibase + MIPI_CAMERA_CNTL);
-			break;
-		case 4:
-			msm_camera_io_w(csi_params->lane_assign << 8 | 0x7,
-				csibase + MIPI_CAMERA_CNTL);
-			break;
-		}
-
-		/* mask out ID_ERROR[19], DATA_CMM_ERR[11]
-		and CLK_CMM_ERR[10] - de-featured */
-		msm_camera_io_w(0xF017F3C0, csibase + MIPI_INTERRUPT_MASK);
-		/*clear IRQ bits*/
-		msm_camera_io_w(0xF017F3C0, csibase + MIPI_INTERRUPT_STATUS);
-	} else {
-		pr_info("CSIBASE is NULL");
-	}
-
-	return rc;
-}
-
-void msm_camio_set_perf_lvl(enum msm_bus_perf_setting perf_setting)
-{
-	static uint32_t bus_perf_client;
-	int rc = 0;
-	switch (perf_setting) {
-	case S_INIT:
-		bus_perf_client =
-			msm_bus_scale_register_client(cam_bus_scale_table);
-		if (!bus_perf_client) {
-			pr_err("%s: Registration Failed!!!\n", __func__);
-			bus_perf_client = 0;
-			return;
-		}
-		CDBG("%s: S_INIT rc = %u\n", __func__, bus_perf_client);
-		break;
-	case S_EXIT:
-		if (bus_perf_client) {
-			CDBG("%s: S_EXIT\n", __func__);
-			msm_bus_scale_unregister_client(bus_perf_client);
-		} else
-			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
-		break;
-	case S_PREVIEW:
-		if (bus_perf_client) {
-			rc = msm_bus_scale_client_update_request(
-				bus_perf_client, 1);
-			CDBG("%s: S_PREVIEW rc = %d\n", __func__, rc);
-		} else
-			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
-		break;
-	case S_VIDEO:
-		if (bus_perf_client) {
-			rc = msm_bus_scale_client_update_request(
-				bus_perf_client, 2);
-			CDBG("%s: S_VIDEO rc = %d\n", __func__, rc);
-		} else
-			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
-		break;
-	case S_CAPTURE:
-		if (bus_perf_client) {
-			rc = msm_bus_scale_client_update_request(
-				bus_perf_client, 3);
-			CDBG("%s: S_CAPTURE rc = %d\n", __func__, rc);
-		} else
-			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
-		break;
-
-	case S_ZSL:
-		if (bus_perf_client) {
-			rc = msm_bus_scale_client_update_request(
-				bus_perf_client, 4);
-			CDBG("%s: S_ZSL rc = %d\n", __func__, rc);
-		} else
-			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
-		break;
-	case S_STEREO_VIDEO:
-		if (bus_perf_client) {
-			rc = msm_bus_scale_client_update_request(
-				bus_perf_client, 5);
-			CDBG("%s: S_STEREO_VIDEO rc = %d\n", __func__, rc);
-		} else
-			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
-		break;
-	case S_STEREO_CAPTURE:
-		if (bus_perf_client) {
-			rc = msm_bus_scale_client_update_request(
-				bus_perf_client, 6);
-			CDBG("%s: S_STEREO_VIDEO rc = %d\n", __func__, rc);
-		} else
-			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
-		break;
-	case S_DEFAULT:
-		break;
-	default:
-		pr_warning("%s: INVALID CASE\n", __func__);
-	}
-}
-
-int msm_cam_core_reset(void)
-{
-	struct clk *clk1;
-	int rc = 0;
-	clk1 = clk_get(&camio_dev->dev, "csi_vfe_clk");
-	if (IS_ERR(clk1)) {
-		pr_err("%s: did not get csi_vfe_clk\n", __func__);
-		return PTR_ERR(clk1);
-	}
-	rc = clk_reset(clk1, CLK_RESET_ASSERT);
-	if (rc) {
-		pr_err("%s:csi_vfe_clk assert failed\n", __func__);
-		clk_put(clk1);
-		return rc;
-	}
-	usleep_range(1000, 1200);
-	rc = clk_reset(clk1, CLK_RESET_DEASSERT);
-	if (rc) {
-		pr_err("%s:csi_vfe_clk deassert failed\n", __func__);
-		clk_put(clk1);
-		return rc;
-	}
-	clk_put(clk1);
-
-	clk1 = clk_get(&camio_dev->dev, "csi_clk");
-	if (IS_ERR(clk1)) {
-		pr_err("%s: did not get csi_clk\n", __func__);
-		return PTR_ERR(clk1);
-	}
-	rc = clk_reset(clk1, CLK_RESET_ASSERT);
-	if (rc) {
-		pr_err("%s:csi_clk assert failed\n", __func__);
-		clk_put(clk1);
-		return rc;
-	}
-	usleep_range(1000, 1200);
-	rc = clk_reset(clk1, CLK_RESET_DEASSERT);
-	if (rc) {
-		pr_err("%s:csi_clk deassert failed\n", __func__);
-		clk_put(clk1);
-		return rc;
-	}
-	clk_put(clk1);
-
-	clk1 = clk_get(&camio_dev->dev, "csi_pclk");
-	if (IS_ERR(clk1)) {
-		pr_err("%s: did not get csi_pclk\n", __func__);
-		return PTR_ERR(clk1);
-	}
-	rc = clk_reset(clk1, CLK_RESET_ASSERT);
-	if (rc) {
-		pr_err("%s:csi_pclk assert failed\n", __func__);
-		clk_put(clk1);
-		return rc;
-	}
-	usleep_range(1000, 1200);
-	rc = clk_reset(clk1, CLK_RESET_DEASSERT);
-	if (rc) {
-		pr_err("%s:csi_pclk deassert failed\n", __func__);
-		clk_put(clk1);
-		return rc;
-	}
-	clk_put(clk1);
-
-	return rc;
-}
diff --git a/drivers/media/video/msm/io/msm_io_vfe31.c b/drivers/media/video/msm/io/msm_io_vfe31.c
deleted file mode 100644
index 8c733a0..0000000
--- a/drivers/media/video/msm/io/msm_io_vfe31.c
+++ /dev/null
@@ -1,776 +0,0 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. 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/delay.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/pm_qos.h>
-#include <linux/regulator/consumer.h>
-#include <mach/gpio.h>
-#include <mach/board.h>
-#include <mach/camera.h>
-#include <mach/vreg.h>
-#include <mach/clk.h>
-
-#define CAMIF_CFG_RMSK             0x1fffff
-#define CAM_SEL_BMSK               0x2
-#define CAM_PCLK_SRC_SEL_BMSK      0x60000
-#define CAM_PCLK_INVERT_BMSK       0x80000
-#define CAM_PAD_REG_SW_RESET_BMSK  0x100000
-
-#define EXT_CAM_HSYNC_POL_SEL_BMSK 0x10000
-#define EXT_CAM_VSYNC_POL_SEL_BMSK 0x8000
-#define MDDI_CLK_CHICKEN_BIT_BMSK  0x80
-
-#define CAM_SEL_SHFT               0x1
-#define CAM_PCLK_SRC_SEL_SHFT      0x11
-#define CAM_PCLK_INVERT_SHFT       0x13
-#define CAM_PAD_REG_SW_RESET_SHFT  0x14
-
-#define EXT_CAM_HSYNC_POL_SEL_SHFT 0x10
-#define EXT_CAM_VSYNC_POL_SEL_SHFT 0xF
-#define MDDI_CLK_CHICKEN_BIT_SHFT  0x7
-
-/* MIPI	CSI	controller registers */
-#define	MIPI_PHY_CONTROL			0x00000000
-#define	MIPI_PROTOCOL_CONTROL		0x00000004
-#define	MIPI_INTERRUPT_STATUS		0x00000008
-#define	MIPI_INTERRUPT_MASK			0x0000000C
-#define	MIPI_CAMERA_CNTL			0x00000024
-#define	MIPI_CALIBRATION_CONTROL	0x00000018
-#define	MIPI_PHY_D0_CONTROL2		0x00000038
-#define	MIPI_PHY_D1_CONTROL2		0x0000003C
-#define	MIPI_PHY_D2_CONTROL2		0x00000040
-#define	MIPI_PHY_D3_CONTROL2		0x00000044
-#define	MIPI_PHY_CL_CONTROL			0x00000048
-#define	MIPI_PHY_D0_CONTROL			0x00000034
-#define	MIPI_PHY_D1_CONTROL			0x00000020
-#define	MIPI_PHY_D2_CONTROL			0x0000002C
-#define	MIPI_PHY_D3_CONTROL			0x00000030
-#define	MIPI_PROTOCOL_CONTROL_SW_RST_BMSK			0x8000000
-#define	MIPI_PROTOCOL_CONTROL_LONG_PACKET_HEADER_CAPTURE_BMSK	0x200000
-#define	MIPI_PROTOCOL_CONTROL_DATA_FORMAT_BMSK			0x180000
-#define	MIPI_PROTOCOL_CONTROL_DECODE_ID_BMSK			0x40000
-#define	MIPI_PROTOCOL_CONTROL_ECC_EN_BMSK			0x20000
-#define	MIPI_CALIBRATION_CONTROL_SWCAL_CAL_EN_SHFT		0x16
-#define	MIPI_CALIBRATION_CONTROL_SWCAL_STRENGTH_OVERRIDE_EN_SHFT	0x15
-#define	MIPI_CALIBRATION_CONTROL_CAL_SW_HW_MODE_SHFT		0x14
-#define	MIPI_CALIBRATION_CONTROL_MANUAL_OVERRIDE_EN_SHFT	0x7
-#define	MIPI_PROTOCOL_CONTROL_DATA_FORMAT_SHFT			0x13
-#define	MIPI_PROTOCOL_CONTROL_DPCM_SCHEME_SHFT			0x1e
-#define	MIPI_PHY_D0_CONTROL2_SETTLE_COUNT_SHFT			0x18
-#define	MIPI_PHY_D0_CONTROL2_HS_TERM_IMP_SHFT			0x10
-#define	MIPI_PHY_D0_CONTROL2_LP_REC_EN_SHFT				0x4
-#define	MIPI_PHY_D0_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
-#define	MIPI_PHY_D1_CONTROL2_SETTLE_COUNT_SHFT			0x18
-#define	MIPI_PHY_D1_CONTROL2_HS_TERM_IMP_SHFT			0x10
-#define	MIPI_PHY_D1_CONTROL2_LP_REC_EN_SHFT				0x4
-#define	MIPI_PHY_D1_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
-#define	MIPI_PHY_D2_CONTROL2_SETTLE_COUNT_SHFT			0x18
-#define	MIPI_PHY_D2_CONTROL2_HS_TERM_IMP_SHFT			0x10
-#define	MIPI_PHY_D2_CONTROL2_LP_REC_EN_SHFT				0x4
-#define	MIPI_PHY_D2_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
-#define	MIPI_PHY_D3_CONTROL2_SETTLE_COUNT_SHFT			0x18
-#define	MIPI_PHY_D3_CONTROL2_HS_TERM_IMP_SHFT			0x10
-#define	MIPI_PHY_D3_CONTROL2_LP_REC_EN_SHFT				0x4
-#define	MIPI_PHY_D3_CONTROL2_ERR_SOT_HS_EN_SHFT			0x3
-#define	MIPI_PHY_CL_CONTROL_HS_TERM_IMP_SHFT			0x18
-#define	MIPI_PHY_CL_CONTROL_LP_REC_EN_SHFT				0x2
-#define	MIPI_PHY_D0_CONTROL_HS_REC_EQ_SHFT				0x1c
-#define	MIPI_PHY_D1_CONTROL_MIPI_CLK_PHY_SHUTDOWNB_SHFT		0x9
-#define	MIPI_PHY_D1_CONTROL_MIPI_DATA_PHY_SHUTDOWNB_SHFT	0x8
-
-#define	CAMIO_VFE_CLK_SNAP			122880000
-#define	CAMIO_VFE_CLK_PREV			122880000
-
-/* AXI rates in KHz */
-#define MSM_AXI_QOS_PREVIEW     192000
-#define MSM_AXI_QOS_SNAPSHOT    192000
-#define MSM_AXI_QOS_RECORDING   192000
-
-static struct clk *camio_vfe_mdc_clk;
-static struct clk *camio_mdc_clk;
-static struct clk *camio_vfe_clk;
-static struct clk *camio_vfe_camif_clk;
-static struct clk *camio_vfe_pbdg_clk;
-static struct clk *camio_cam_m_clk;
-static struct clk *camio_camif_pad_pbdg_clk;
-static struct clk *camio_csi_clk;
-static struct clk *camio_csi_pclk;
-static struct clk *camio_csi_vfe_clk;
-static struct clk *camio_vpe_clk;
-static struct regulator *fs_vpe;
-static struct msm_camera_io_ext camio_ext;
-static struct msm_camera_io_clk camio_clk;
-static struct resource *camifpadio, *csiio;
-void __iomem *camifpadbase, *csibase;
-static uint32_t vpe_clk_rate;
-
-static struct regulator_bulk_data regs[] = {
-	{ .supply = "gp2",  .min_uV = 2600000, .max_uV = 2600000 },
-	{ .supply = "lvsw1" },
-	{ .supply = "fs_vfe" },
-	/* sn12m0pz regulators */
-	{ .supply = "gp6",  .min_uV = 3050000, .max_uV = 3100000 },
-	{ .supply = "gp16", .min_uV = 1200000, .max_uV = 1200000 },
-};
-
-static int reg_count;
-
-static void msm_camera_vreg_enable(struct platform_device *pdev)
-{
-	int count, rc;
-
-	struct device *dev = &pdev->dev;
-
-	/* Use gp6 and gp16 if and only if dev name matches. */
-	if (!strncmp(pdev->name, "msm_camera_sn12m0pz", 20))
-		count = ARRAY_SIZE(regs);
-	else
-		count = ARRAY_SIZE(regs) - 2;
-
-	rc = regulator_bulk_get(dev, count, regs);
-
-	if (rc) {
-		dev_err(dev, "%s: could not get regulators: %d\n",
-				__func__, rc);
-		return;
-	}
-
-	rc = regulator_bulk_set_voltage(count, regs);
-
-	if (rc) {
-		dev_err(dev, "%s: could not set voltages: %d\n",
-				__func__, rc);
-		goto reg_free;
-	}
-
-	rc = regulator_bulk_enable(count, regs);
-
-	if (rc) {
-		dev_err(dev, "%s: could not enable regulators: %d\n",
-				__func__, rc);
-		goto reg_free;
-	}
-
-	reg_count = count;
-	return;
-
-reg_free:
-	regulator_bulk_free(count, regs);
-	return;
-}
-
-
-static void msm_camera_vreg_disable(void)
-{
-	regulator_bulk_disable(reg_count, regs);
-	regulator_bulk_free(reg_count, regs);
-	reg_count = 0;
-}
-
-int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
-{
-	int rc = 0;
-	struct clk *clk = NULL;
-
-	switch (clktype) {
-	case CAMIO_VFE_MDC_CLK:
-		camio_vfe_mdc_clk =
-		clk = clk_get(NULL, "vfe_mdc_clk");
-		break;
-
-	case CAMIO_MDC_CLK:
-		camio_mdc_clk =
-		clk = clk_get(NULL, "mdc_clk");
-		break;
-
-	case CAMIO_VFE_CLK:
-		camio_vfe_clk =
-		clk = clk_get(NULL, "vfe_clk");
-		msm_camio_clk_rate_set_2(clk, camio_clk.vfe_clk_rate);
-		break;
-
-	case CAMIO_VFE_CAMIF_CLK:
-		camio_vfe_camif_clk =
-		clk = clk_get(NULL, "vfe_camif_clk");
-		break;
-
-	case CAMIO_VFE_PBDG_CLK:
-		camio_vfe_pbdg_clk =
-		clk = clk_get(NULL, "vfe_pclk");
-		break;
-
-	case CAMIO_CAM_MCLK_CLK:
-		camio_cam_m_clk =
-		clk = clk_get(NULL, "cam_m_clk");
-		msm_camio_clk_rate_set_2(clk, camio_clk.mclk_clk_rate);
-		break;
-
-	case CAMIO_CAMIF_PAD_PBDG_CLK:
-		camio_camif_pad_pbdg_clk =
-		clk = clk_get(NULL, "camif_pad_pclk");
-		break;
-
-	case CAMIO_CSI0_CLK:
-		camio_csi_clk =
-		clk = clk_get(NULL, "csi_clk");
-		msm_camio_clk_rate_set_2(clk, 153600000);
-		break;
-	case CAMIO_CSI0_VFE_CLK:
-		camio_csi_vfe_clk =
-		clk = clk_get(NULL, "csi_vfe_clk");
-		break;
-	case CAMIO_CSI0_PCLK:
-		camio_csi_pclk =
-		clk = clk_get(NULL, "csi_pclk");
-		break;
-
-	case CAMIO_VPE_CLK:
-		camio_vpe_clk =
-		clk = clk_get(NULL, "vpe_clk");
-		vpe_clk_rate = clk_round_rate(clk, vpe_clk_rate);
-		clk_set_rate(clk, vpe_clk_rate);
-		break;
-	default:
-		break;
-	}
-
-	if (!IS_ERR(clk))
-		clk_prepare_enable(clk);
-	else
-		rc = -1;
-	return rc;
-}
-
-int msm_camio_clk_disable(enum msm_camio_clk_type clktype)
-{
-	int rc = 0;
-	struct clk *clk = NULL;
-
-	switch (clktype) {
-	case CAMIO_VFE_MDC_CLK:
-		clk = camio_vfe_mdc_clk;
-		break;
-
-	case CAMIO_MDC_CLK:
-		clk = camio_mdc_clk;
-		break;
-
-	case CAMIO_VFE_CLK:
-		clk = camio_vfe_clk;
-		break;
-
-	case CAMIO_VFE_CAMIF_CLK:
-		clk = camio_vfe_camif_clk;
-		break;
-
-	case CAMIO_VFE_PBDG_CLK:
-		clk = camio_vfe_pbdg_clk;
-		break;
-
-	case CAMIO_CAM_MCLK_CLK:
-		clk = camio_cam_m_clk;
-		break;
-
-	case CAMIO_CAMIF_PAD_PBDG_CLK:
-		clk = camio_camif_pad_pbdg_clk;
-		break;
-	case CAMIO_CSI0_CLK:
-		clk = camio_csi_clk;
-		break;
-	case CAMIO_CSI0_VFE_CLK:
-		clk = camio_csi_vfe_clk;
-		break;
-	case CAMIO_CSI0_PCLK:
-		clk = camio_csi_pclk;
-		break;
-	case CAMIO_VPE_CLK:
-		clk = camio_vpe_clk;
-		break;
-	default:
-		break;
-	}
-
-	if (!IS_ERR(clk)) {
-		clk_disable_unprepare(clk);
-		clk_put(clk);
-	} else {
-		rc = -1;
-	}
-
-	return rc;
-}
-
-void msm_camio_clk_rate_set(int rate)
-{
-	struct clk *clk = camio_cam_m_clk;
-	clk_set_rate(clk, rate);
-}
-
-int msm_camio_vfe_clk_rate_set(int rate)
-{
-	struct clk *clk = camio_vfe_clk;
-	return clk_set_rate(clk, rate);
-}
-
-void msm_camio_clk_rate_set_2(struct clk *clk, int rate)
-{
-	clk_set_rate(clk, rate);
-}
-
-static irqreturn_t msm_io_csi_irq(int irq_num, void *data)
-{
-	uint32_t irq;
-	irq = msm_camera_io_r(csibase + MIPI_INTERRUPT_STATUS);
-	CDBG("%s MIPI_INTERRUPT_STATUS = 0x%x\n", __func__, irq);
-	msm_camera_io_w(irq, csibase + MIPI_INTERRUPT_STATUS);
-	return IRQ_HANDLED;
-}
-
-int msm_camio_vpe_clk_disable(void)
-{
-	msm_camio_clk_disable(CAMIO_VPE_CLK);
-
-	if (fs_vpe) {
-		regulator_disable(fs_vpe);
-		regulator_put(fs_vpe);
-	}
-
-	return 0;
-}
-
-int msm_camio_vpe_clk_enable(uint32_t clk_rate)
-{
-	fs_vpe = regulator_get(NULL, "fs_vpe");
-	if (IS_ERR(fs_vpe)) {
-		pr_err("%s: Regulator FS_VPE get failed %ld\n", __func__,
-			PTR_ERR(fs_vpe));
-		fs_vpe = NULL;
-	} else if (regulator_enable(fs_vpe)) {
-		pr_err("%s: Regulator FS_VPE enable failed\n", __func__);
-		regulator_put(fs_vpe);
-	}
-
-	vpe_clk_rate = clk_rate;
-	msm_camio_clk_enable(CAMIO_VPE_CLK);
-	return 0;
-}
-
-int msm_camio_enable(struct platform_device *pdev)
-{
-	int rc = 0;
-	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	msm_camio_clk_enable(CAMIO_VFE_PBDG_CLK);
-	if (!sinfo->csi_if)
-		msm_camio_clk_enable(CAMIO_VFE_CAMIF_CLK);
-	else {
-		msm_camio_clk_enable(CAMIO_VFE_CLK);
-		csiio = request_mem_region(camio_ext.csiphy,
-			camio_ext.csisz, pdev->name);
-		if (!csiio) {
-			rc = -EBUSY;
-			goto common_fail;
-		}
-		csibase = ioremap(camio_ext.csiphy,
-			camio_ext.csisz);
-		if (!csibase) {
-			rc = -ENOMEM;
-			goto csi_busy;
-		}
-		rc = request_irq(camio_ext.csiirq, msm_io_csi_irq,
-			IRQF_TRIGGER_RISING, "csi", 0);
-		if (rc < 0)
-			goto csi_irq_fail;
-		/* enable required clocks for CSI */
-		msm_camio_clk_enable(CAMIO_CSI0_PCLK);
-		msm_camio_clk_enable(CAMIO_CSI0_VFE_CLK);
-		msm_camio_clk_enable(CAMIO_CSI0_CLK);
-	}
-	return 0;
-csi_irq_fail:
-	iounmap(csibase);
-csi_busy:
-	release_mem_region(camio_ext.csiphy, camio_ext.csisz);
-common_fail:
-	msm_camio_clk_disable(CAMIO_VFE_PBDG_CLK);
-	msm_camio_clk_disable(CAMIO_VFE_CLK);
-	return rc;
-}
-
-static void msm_camio_csi_disable(void)
-{
-	uint32_t val;
-	val = 0x0;
-	CDBG("%s MIPI_PHY_D0_CONTROL2 val=0x%x\n", __func__, val);
-	msm_camera_io_w(val, csibase + MIPI_PHY_D0_CONTROL2);
-	msm_camera_io_w(val, csibase + MIPI_PHY_D1_CONTROL2);
-	msm_camera_io_w(val, csibase + MIPI_PHY_D2_CONTROL2);
-	msm_camera_io_w(val, csibase + MIPI_PHY_D3_CONTROL2);
-
-	CDBG("%s MIPI_PHY_CL_CONTROL val=0x%x\n", __func__, val);
-	msm_camera_io_w(val, csibase + MIPI_PHY_CL_CONTROL);
-	usleep_range(9000, 10000);
-	free_irq(camio_ext.csiirq, 0);
-	iounmap(csibase);
-	release_mem_region(camio_ext.csiphy, camio_ext.csisz);
-}
-
-void msm_camio_disable(struct platform_device *pdev)
-{
-	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	if (!sinfo->csi_if) {
-		msm_camio_clk_disable(CAMIO_VFE_CAMIF_CLK);
-	} else {
-		CDBG("disable mipi\n");
-		msm_camio_csi_disable();
-		CDBG("disable clocks\n");
-		msm_camio_clk_disable(CAMIO_CSI0_PCLK);
-		msm_camio_clk_disable(CAMIO_CSI0_VFE_CLK);
-		msm_camio_clk_disable(CAMIO_CSI0_CLK);
-		msm_camio_clk_disable(CAMIO_VFE_CLK);
-	}
-	msm_camio_clk_disable(CAMIO_VFE_PBDG_CLK);
-}
-
-void msm_camio_camif_pad_reg_reset(void)
-{
-	uint32_t reg;
-
-	msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_INTERNAL);
-	usleep_range(10000, 11000);
-
-	reg = (msm_camera_io_r(camifpadbase)) & CAMIF_CFG_RMSK;
-	reg |= 0x3;
-	msm_camera_io_w(reg, camifpadbase);
-	usleep_range(10000, 11000);
-
-	reg = (msm_camera_io_r(camifpadbase)) & CAMIF_CFG_RMSK;
-	reg |= 0x10;
-	msm_camera_io_w(reg, camifpadbase);
-	usleep_range(10000, 11000);
-
-	reg = (msm_camera_io_r(camifpadbase)) & CAMIF_CFG_RMSK;
-	/* Need to be uninverted*/
-	reg &= 0x03;
-	msm_camera_io_w(reg, camifpadbase);
-	usleep_range(10000, 11000);
-}
-
-void msm_camio_vfe_blk_reset(void)
-{
-	return;
-
-
-}
-
-void msm_camio_camif_pad_reg_reset_2(void)
-{
-	uint32_t reg;
-	uint32_t mask, value;
-	reg = (msm_camera_io_r(camifpadbase)) & CAMIF_CFG_RMSK;
-	mask = CAM_PAD_REG_SW_RESET_BMSK;
-	value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
-	msm_camera_io_w((reg & (~mask)) | (value & mask), camifpadbase);
-	usleep_range(10000, 11000);
-	reg = (msm_camera_io_r(camifpadbase)) & CAMIF_CFG_RMSK;
-	mask = CAM_PAD_REG_SW_RESET_BMSK;
-	value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
-	msm_camera_io_w((reg & (~mask)) | (value & mask), camifpadbase);
-	usleep_range(10000, 11000);
-}
-
-void msm_camio_clk_sel(enum msm_camio_clk_src_type srctype)
-{
-	struct clk *clk = NULL;
-
-	clk = camio_vfe_clk;
-
-	if (clk != NULL) {
-		switch (srctype) {
-		case MSM_CAMIO_CLK_SRC_INTERNAL:
-			clk_set_flags(clk, 0x00000100 << 1);
-			break;
-
-		case MSM_CAMIO_CLK_SRC_EXTERNAL:
-			clk_set_flags(clk, 0x00000100);
-			break;
-
-		default:
-			break;
-		}
-	}
-}
-int msm_camio_probe_on(struct platform_device *pdev)
-{
-	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-	camio_clk = camdev->ioclk;
-	camio_ext = camdev->ioext;
-	camdev->camera_gpio_on();
-	msm_camera_vreg_enable(pdev);
-	return msm_camio_clk_enable(CAMIO_CAM_MCLK_CLK);
-}
-
-int msm_camio_probe_off(struct platform_device *pdev)
-{
-	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-	msm_camera_vreg_disable();
-	camdev->camera_gpio_off();
-	return msm_camio_clk_disable(CAMIO_CAM_MCLK_CLK);
-}
-
-int msm_camio_sensor_clk_on(struct platform_device *pdev)
-{
-	int rc = 0;
-	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-	camio_clk = camdev->ioclk;
-	camio_ext = camdev->ioext;
-	camdev->camera_gpio_on();
-	msm_camera_vreg_enable(pdev);
-	msm_camio_clk_enable(CAMIO_CAM_MCLK_CLK);
-	msm_camio_clk_enable(CAMIO_CAMIF_PAD_PBDG_CLK);
-	if (!sinfo->csi_if) {
-		camifpadio = request_mem_region(camio_ext.camifpadphy,
-			camio_ext.camifpadsz, pdev->name);
-		msm_camio_clk_enable(CAMIO_VFE_CLK);
-		if (!camifpadio) {
-			rc = -EBUSY;
-			goto common_fail;
-		}
-		camifpadbase = ioremap(camio_ext.camifpadphy,
-			camio_ext.camifpadsz);
-		if (!camifpadbase) {
-			CDBG("msm_camio_sensor_clk_on fail\n");
-			rc = -ENOMEM;
-			goto parallel_busy;
-		}
-	}
-	return rc;
-parallel_busy:
-	release_mem_region(camio_ext.camifpadphy, camio_ext.camifpadsz);
-	goto common_fail;
-common_fail:
-	msm_camio_clk_disable(CAMIO_CAM_MCLK_CLK);
-	msm_camio_clk_disable(CAMIO_VFE_CLK);
-	msm_camio_clk_disable(CAMIO_CAMIF_PAD_PBDG_CLK);
-	msm_camera_vreg_disable();
-	camdev->camera_gpio_off();
-	return rc;
-}
-
-int msm_camio_sensor_clk_off(struct platform_device *pdev)
-{
-	uint32_t rc = 0;
-	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-	camdev->camera_gpio_off();
-	msm_camera_vreg_disable();
-	rc = msm_camio_clk_disable(CAMIO_CAM_MCLK_CLK);
-	rc = msm_camio_clk_disable(CAMIO_CAMIF_PAD_PBDG_CLK);
-	if (!sinfo->csi_if) {
-		iounmap(camifpadbase);
-		release_mem_region(camio_ext.camifpadphy, camio_ext.camifpadsz);
-		rc = msm_camio_clk_disable(CAMIO_VFE_CLK);
-	}
-	return rc;
-}
-
-int msm_camio_csi_config(struct msm_camera_csi_params *csi_params)
-{
-	int rc = 0;
-	uint32_t val = 0;
-	int i;
-
-	CDBG("msm_camio_csi_config\n");
-
-	/* SOT_ECC_EN enable error correction for SYNC (data-lane) */
-	msm_camera_io_w(0x4, csibase + MIPI_PHY_CONTROL);
-
-	/* SW_RST to the CSI core */
-	msm_camera_io_w(MIPI_PROTOCOL_CONTROL_SW_RST_BMSK,
-		csibase + MIPI_PROTOCOL_CONTROL);
-
-	/* PROTOCOL CONTROL */
-	val = MIPI_PROTOCOL_CONTROL_LONG_PACKET_HEADER_CAPTURE_BMSK |
-		MIPI_PROTOCOL_CONTROL_DECODE_ID_BMSK |
-		MIPI_PROTOCOL_CONTROL_ECC_EN_BMSK;
-	val |= (uint32_t)(csi_params->data_format) <<
-		MIPI_PROTOCOL_CONTROL_DATA_FORMAT_SHFT;
-	val |= csi_params->dpcm_scheme <<
-		MIPI_PROTOCOL_CONTROL_DPCM_SCHEME_SHFT;
-	CDBG("%s MIPI_PROTOCOL_CONTROL val=0x%x\n", __func__, val);
-	msm_camera_io_w(val, csibase + MIPI_PROTOCOL_CONTROL);
-
-	/* SW CAL EN */
-	val = (0x1 << MIPI_CALIBRATION_CONTROL_SWCAL_CAL_EN_SHFT) |
-		(0x1 <<
-		MIPI_CALIBRATION_CONTROL_SWCAL_STRENGTH_OVERRIDE_EN_SHFT) |
-		(0x1 << MIPI_CALIBRATION_CONTROL_CAL_SW_HW_MODE_SHFT) |
-		(0x1 << MIPI_CALIBRATION_CONTROL_MANUAL_OVERRIDE_EN_SHFT);
-	CDBG("%s MIPI_CALIBRATION_CONTROL val=0x%x\n", __func__, val);
-	msm_camera_io_w(val, csibase + MIPI_CALIBRATION_CONTROL);
-
-	/* settle_cnt is very sensitive to speed!
-	increase this value to run at higher speeds */
-	val = (csi_params->settle_cnt <<
-			MIPI_PHY_D0_CONTROL2_SETTLE_COUNT_SHFT) |
-		(0x0F << MIPI_PHY_D0_CONTROL2_HS_TERM_IMP_SHFT) |
-		(0x1 << MIPI_PHY_D0_CONTROL2_LP_REC_EN_SHFT) |
-		(0x1 << MIPI_PHY_D0_CONTROL2_ERR_SOT_HS_EN_SHFT);
-	CDBG("%s MIPI_PHY_D0_CONTROL2 val=0x%x\n", __func__, val);
-	for (i = 0; i < csi_params->lane_cnt; i++)
-		msm_camera_io_w(val, csibase + MIPI_PHY_D0_CONTROL2 + i * 4);
-
-	val = (0x0F << MIPI_PHY_CL_CONTROL_HS_TERM_IMP_SHFT) |
-		(0x1 << MIPI_PHY_CL_CONTROL_LP_REC_EN_SHFT);
-	CDBG("%s MIPI_PHY_CL_CONTROL val=0x%x\n", __func__, val);
-	msm_camera_io_w(val, csibase + MIPI_PHY_CL_CONTROL);
-
-	val = 0 << MIPI_PHY_D0_CONTROL_HS_REC_EQ_SHFT;
-	msm_camera_io_w(val, csibase + MIPI_PHY_D0_CONTROL);
-
-	val = (0x1 << MIPI_PHY_D1_CONTROL_MIPI_CLK_PHY_SHUTDOWNB_SHFT) |
-		(0x1 << MIPI_PHY_D1_CONTROL_MIPI_DATA_PHY_SHUTDOWNB_SHFT);
-	CDBG("%s MIPI_PHY_D1_CONTROL val=0x%x\n", __func__, val);
-	msm_camera_io_w(val, csibase + MIPI_PHY_D1_CONTROL);
-
-	msm_camera_io_w(0x00000000, csibase + MIPI_PHY_D2_CONTROL);
-	msm_camera_io_w(0x00000000, csibase + MIPI_PHY_D3_CONTROL);
-
-	/* halcyon only supports 1 or 2 lane */
-	switch (csi_params->lane_cnt) {
-	case 1:
-		msm_camera_io_w(csi_params->lane_assign << 8 | 0x4,
-			csibase + MIPI_CAMERA_CNTL);
-		break;
-	case 2:
-		msm_camera_io_w(csi_params->lane_assign << 8 | 0x5,
-			csibase + MIPI_CAMERA_CNTL);
-		break;
-	case 3:
-		msm_camera_io_w(csi_params->lane_assign << 8 | 0x6,
-			csibase + MIPI_CAMERA_CNTL);
-		break;
-	case 4:
-		msm_camera_io_w(csi_params->lane_assign << 8 | 0x7,
-			csibase + MIPI_CAMERA_CNTL);
-		break;
-	}
-
-	/* mask out ID_ERROR[19], DATA_CMM_ERR[11]
-	and CLK_CMM_ERR[10] - de-featured */
-	msm_camera_io_w(0xFFF7F3FF, csibase + MIPI_INTERRUPT_MASK);
-	/*clear IRQ bits*/
-	msm_camera_io_w(0xFFF7F3FF, csibase + MIPI_INTERRUPT_STATUS);
-
-	return rc;
-}
-void msm_camio_set_perf_lvl(enum msm_bus_perf_setting perf_setting)
-{
-	switch (perf_setting) {
-	case S_INIT:
-		add_axi_qos();
-		break;
-	case S_PREVIEW:
-		update_axi_qos(MSM_AXI_QOS_PREVIEW);
-		break;
-	case S_VIDEO:
-		update_axi_qos(MSM_AXI_QOS_RECORDING);
-		break;
-	case S_CAPTURE:
-		update_axi_qos(MSM_AXI_QOS_SNAPSHOT);
-		break;
-	case S_DEFAULT:
-		update_axi_qos(PM_QOS_DEFAULT_VALUE);
-		break;
-	case S_EXIT:
-		release_axi_qos();
-		break;
-	default:
-		CDBG("%s: INVALID CASE\n", __func__);
-	}
-}
-
-int msm_cam_core_reset(void)
-{
-	struct clk *clk1;
-	int rc = 0;
-
-	clk1 = clk_get(NULL, "csi_vfe_clk");
-	if (IS_ERR(clk1)) {
-		pr_err("%s: did not get csi_vfe_clk\n", __func__);
-		return PTR_ERR(clk1);
-	}
-
-	rc = clk_reset(clk1, CLK_RESET_ASSERT);
-	if (rc) {
-		pr_err("%s:csi_vfe_clk assert failed\n", __func__);
-		clk_put(clk1);
-		return rc;
-	}
-	usleep_range(1000, 1200);
-	rc = clk_reset(clk1, CLK_RESET_DEASSERT);
-	if (rc) {
-		pr_err("%s:csi_vfe_clk deassert failed\n", __func__);
-		clk_put(clk1);
-		return rc;
-	}
-	clk_put(clk1);
-
-	clk1 = clk_get(NULL, "csi_clk");
-	if (IS_ERR(clk1)) {
-		pr_err("%s: did not get csi_clk\n", __func__);
-		return PTR_ERR(clk1);
-	}
-
-	rc = clk_reset(clk1, CLK_RESET_ASSERT);
-	if (rc) {
-		pr_err("%s:csi_clk assert failed\n", __func__);
-		clk_put(clk1);
-		return rc;
-	}
-	usleep_range(1000, 1200);
-	rc = clk_reset(clk1, CLK_RESET_DEASSERT);
-	if (rc) {
-		pr_err("%s:csi_clk deassert failed\n", __func__);
-		clk_put(clk1);
-		return rc;
-	}
-	clk_put(clk1);
-
-	clk1 = clk_get(NULL, "csi_pclk");
-	if (IS_ERR(clk1)) {
-		pr_err("%s: did not get csi_pclk\n", __func__);
-		return PTR_ERR(clk1);
-	}
-
-	rc = clk_reset(clk1, CLK_RESET_ASSERT);
-	if (rc) {
-		pr_err("%s:csi_pclk assert failed\n", __func__);
-		clk_put(clk1);
-		return rc;
-	}
-	usleep_range(1000, 1200);
-	rc = clk_reset(clk1, CLK_RESET_DEASSERT);
-	if (rc) {
-		pr_err("%s:csi_pclk deassert failed\n", __func__);
-		clk_put(clk1);
-		return rc;
-	}
-	clk_put(clk1);
-
-	return rc;
-}
diff --git a/drivers/media/video/msm/io/msm_io_vfe31_v4l2.c b/drivers/media/video/msm/io/msm_io_vfe31_v4l2.c
deleted file mode 100644
index 88a9316..0000000
--- a/drivers/media/video/msm/io/msm_io_vfe31_v4l2.c
+++ /dev/null
@@ -1,274 +0,0 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. 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/delay.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/regulator/consumer.h>
-#include <linux/export.h>
-#include <mach/gpio.h>
-#include <mach/board.h>
-#include <mach/camera.h>
-#include <mach/vreg.h>
-#include <mach/camera.h>
-#include <mach/clk.h>
-#include <mach/msm_bus.h>
-#include <mach/msm_bus_board.h>
-
-#include <linux/pm_qos.h>
-
-/* AXI rates in KHz */
-#define MSM_AXI_QOS_PREVIEW     192000
-#define MSM_AXI_QOS_SNAPSHOT    192000
-#define MSM_AXI_QOS_RECORDING   192000
-
-#define BUFF_SIZE_128 128
-
-static struct clk *camio_vfe_clk;
-static struct clk *camio_vpe_clk;
-static struct clk *camio_vpe_pclk;
-static struct regulator *fs_vpe;
-
-static int vpe_clk_rate;
-
-int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
-{
-	int rc = 0;
-	struct clk *clk = NULL;
-
-	switch (clktype) {
-	case CAMIO_VPE_CLK:
-		camio_vpe_clk =
-		clk = clk_get(NULL, "vpe_clk");
-		vpe_clk_rate = clk_round_rate(camio_vpe_clk, vpe_clk_rate);
-		clk_set_rate(camio_vpe_clk, vpe_clk_rate);
-		break;
-
-	case CAMIO_VPE_PCLK:
-		camio_vpe_pclk =
-		clk = clk_get(NULL, "vpe_pclk");
-		break;
-
-	default:
-		break;
-	}
-
-	if (!IS_ERR(clk)) {
-		clk_prepare(clk);
-		clk_enable(clk);
-	} else {
-		rc = -1;
-	}
-	return rc;
-}
-
-int msm_camio_clk_disable(enum msm_camio_clk_type clktype)
-{
-	int rc = 0;
-	struct clk *clk = NULL;
-
-	switch (clktype) {
-	case CAMIO_VPE_CLK:
-		clk = camio_vpe_clk;
-		break;
-
-	case CAMIO_VPE_PCLK:
-		clk = camio_vpe_pclk;
-		break;
-
-	default:
-		break;
-	}
-
-	if (!IS_ERR(clk)) {
-		clk_disable(clk);
-		clk_unprepare(clk);
-		clk_put(clk);
-	} else {
-		rc = -1;
-	}
-
-	return rc;
-}
-
-int msm_camio_vfe_clk_rate_set(int rate)
-{
-	int rc = 0;
-	struct clk *clk = camio_vfe_clk;
-	if (rate > clk_get_rate(clk))
-		rc = clk_set_rate(clk, rate);
-	return rc;
-}
-
-void msm_camio_clk_rate_set_2(struct clk *clk, int rate)
-{
-	clk_set_rate(clk, rate);
-}
-
-int msm_camio_vpe_clk_disable(void)
-{
-	int rc = 0;
-	if (fs_vpe) {
-		regulator_disable(fs_vpe);
-		regulator_put(fs_vpe);
-	}
-
-	rc = msm_camio_clk_disable(CAMIO_VPE_CLK);
-	if (rc < 0)
-		return rc;
-	rc = msm_camio_clk_disable(CAMIO_VPE_PCLK);
-	return rc;
-}
-
-int msm_camio_vpe_clk_enable(uint32_t clk_rate)
-{
-	int rc = 0;
-	fs_vpe = regulator_get(NULL, "fs_vpe");
-	if (IS_ERR(fs_vpe)) {
-		CDBG("%s: Regulator FS_VPE get failed %ld\n", __func__,
-			PTR_ERR(fs_vpe));
-		fs_vpe = NULL;
-	} else if (regulator_enable(fs_vpe)) {
-		CDBG("%s: Regulator FS_VPE enable failed\n", __func__);
-		regulator_put(fs_vpe);
-	}
-
-	vpe_clk_rate = clk_rate;
-	rc = msm_camio_clk_enable(CAMIO_VPE_CLK);
-	if (rc < 0)
-		return rc;
-
-	rc = msm_camio_clk_enable(CAMIO_VPE_PCLK);
-	return rc;
-}
-
-void msm_camio_vfe_blk_reset(void)
-{
-	return;
-}
-
-void msm_camio_vfe_blk_reset_3(void)
-{
-	return;
-}
-
-static void msm_camio_axi_cfg(enum msm_bus_perf_setting perf_setting)
-{
-	switch (perf_setting) {
-	case S_INIT:
-		add_axi_qos();
-		break;
-	case S_PREVIEW:
-		update_axi_qos(MSM_AXI_QOS_PREVIEW);
-		break;
-	case S_VIDEO:
-		update_axi_qos(MSM_AXI_QOS_RECORDING);
-		break;
-	case S_CAPTURE:
-		update_axi_qos(MSM_AXI_QOS_SNAPSHOT);
-		break;
-	case S_DEFAULT:
-		update_axi_qos(PM_QOS_DEFAULT_VALUE);
-		break;
-	case S_EXIT:
-		release_axi_qos();
-		break;
-	default:
-		CDBG("%s: INVALID CASE\n", __func__);
-	}
-}
-
-void msm_camio_bus_scale_cfg(struct msm_bus_scale_pdata *cam_bus_scale_table,
-		enum msm_bus_perf_setting perf_setting)
-{
-	static uint32_t bus_perf_client;
-	int rc = 0;
-	if (cam_bus_scale_table == NULL) {
-		msm_camio_axi_cfg(perf_setting);
-		return;
-	}
-
-	switch (perf_setting) {
-	case S_INIT:
-		bus_perf_client =
-			msm_bus_scale_register_client(cam_bus_scale_table);
-		if (!bus_perf_client) {
-			pr_err("%s: Registration Failed!!!\n", __func__);
-			bus_perf_client = 0;
-			return;
-		}
-		CDBG("%s: S_INIT rc = %u\n", __func__, bus_perf_client);
-		break;
-	case S_EXIT:
-		if (bus_perf_client) {
-			CDBG("%s: S_EXIT\n", __func__);
-			msm_bus_scale_unregister_client(bus_perf_client);
-		} else
-			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
-		break;
-	case S_PREVIEW:
-		if (bus_perf_client) {
-			rc = msm_bus_scale_client_update_request(
-				bus_perf_client, 1);
-			CDBG("%s: S_PREVIEW rc = %d\n", __func__, rc);
-		} else
-			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
-		break;
-	case S_VIDEO:
-		if (bus_perf_client) {
-			rc = msm_bus_scale_client_update_request(
-				bus_perf_client, 2);
-			CDBG("%s: S_VIDEO rc = %d\n", __func__, rc);
-		} else
-			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
-		break;
-	case S_CAPTURE:
-		if (bus_perf_client) {
-			rc = msm_bus_scale_client_update_request(
-				bus_perf_client, 3);
-			CDBG("%s: S_CAPTURE rc = %d\n", __func__, rc);
-		} else
-			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
-		break;
-
-	case S_ZSL:
-		if (bus_perf_client) {
-			rc = msm_bus_scale_client_update_request(
-				bus_perf_client, 4);
-			CDBG("%s: S_ZSL rc = %d\n", __func__, rc);
-		} else
-			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
-		break;
-	case S_STEREO_VIDEO:
-		if (bus_perf_client) {
-			rc = msm_bus_scale_client_update_request(
-				bus_perf_client, 5);
-			CDBG("%s: S_STEREO_VIDEO rc = %d\n", __func__, rc);
-		} else
-			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
-		break;
-	case S_STEREO_CAPTURE:
-		if (bus_perf_client) {
-			rc = msm_bus_scale_client_update_request(
-				bus_perf_client, 6);
-			CDBG("%s: S_STEREO_VIDEO rc = %d\n", __func__, rc);
-		} else
-			pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
-		break;
-	case S_DEFAULT:
-		break;
-	default:
-		pr_warning("%s: INVALID CASE\n", __func__);
-	}
-}
-
diff --git a/drivers/media/video/msm/jpeg_10/Makefile b/drivers/media/video/msm/jpeg_10/Makefile
deleted file mode 100644
index d99d1a4..0000000
--- a/drivers/media/video/msm/jpeg_10/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
-ccflags-y += -Idrivers/media/video/msm
-obj-$(CONFIG_MSM_JPEG) += msm_jpeg_dev.o msm_jpeg_sync.o msm_jpeg_core.o msm_jpeg_hw.o msm_jpeg_platform.o
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_dev.c b/drivers/media/video/msm/jpeg_10/msm_jpeg_dev.c
deleted file mode 100644
index 3e6e0d5..0000000
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_dev.c
+++ /dev/null
@@ -1,298 +0,0 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <mach/board.h>
-#include <linux/of.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/device.h>
-#include <linux/uaccess.h>
-#include <media/msm_jpeg.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-
-#include "msm.h"
-#include "msm_jpeg_sync.h"
-#include "msm_jpeg_common.h"
-
-#define MSM_JPEG_NAME "jpeg"
-#define DEV_NAME_LEN 10
-
-static int msm_jpeg_open(struct inode *inode, struct file *filp)
-{
-	int rc = 0;
-
-	struct msm_jpeg_device *pgmn_dev = container_of(inode->i_cdev,
-		struct msm_jpeg_device, cdev);
-	filp->private_data = pgmn_dev;
-
-	JPEG_DBG("%s:%d]\n", __func__, __LINE__);
-
-	rc = __msm_jpeg_open(pgmn_dev);
-
-	JPEG_DBG(KERN_INFO "%s:%d] %s open_count = %d\n", __func__, __LINE__,
-		filp->f_path.dentry->d_name.name, pgmn_dev->open_count);
-
-	return rc;
-}
-
-static int msm_jpeg_release(struct inode *inode, struct file *filp)
-{
-	int rc;
-
-	struct msm_jpeg_device *pgmn_dev = filp->private_data;
-
-	JPEG_DBG(KERN_INFO "%s:%d]\n", __func__, __LINE__);
-
-	rc = __msm_jpeg_release(pgmn_dev);
-
-	JPEG_DBG(KERN_INFO "%s:%d] %s open_count = %d\n", __func__, __LINE__,
-		filp->f_path.dentry->d_name.name, pgmn_dev->open_count);
-	return rc;
-}
-
-static long msm_jpeg_ioctl(struct file *filp, unsigned int cmd,
-	unsigned long arg)
-{
-	int rc;
-	struct msm_jpeg_device *pgmn_dev = filp->private_data;
-
-	JPEG_DBG("%s:%d] cmd=%d pgmn_dev=0x%x arg=0x%x\n", __func__,
-		__LINE__, _IOC_NR(cmd), (uint32_t)pgmn_dev, (uint32_t)arg);
-
-	rc = __msm_jpeg_ioctl(pgmn_dev, cmd, arg);
-
-	JPEG_DBG("%s:%d]\n", __func__, __LINE__);
-	return rc;
-}
-
-static const struct file_operations msm_jpeg_fops = {
-	.owner		= THIS_MODULE,
-	.open		 = msm_jpeg_open,
-	.release	= msm_jpeg_release,
-	.unlocked_ioctl = msm_jpeg_ioctl,
-};
-
-
-int msm_jpeg_subdev_init(struct v4l2_subdev *jpeg_sd)
-{
-	int rc;
-	struct msm_jpeg_device *pgmn_dev =
-		(struct msm_jpeg_device *)jpeg_sd->host_priv;
-
-	JPEG_DBG("%s:%d: jpeg_sd=0x%x pgmn_dev=0x%x\n",
-		__func__, __LINE__, (uint32_t)jpeg_sd, (uint32_t)pgmn_dev);
-	rc = __msm_jpeg_open(pgmn_dev);
-	JPEG_DBG("%s:%d: rc=%d\n",
-		__func__, __LINE__, rc);
-	return rc;
-}
-
-static long msm_jpeg_subdev_ioctl(struct v4l2_subdev *sd,
-	unsigned int cmd, void *arg)
-{
-	long rc;
-	struct msm_jpeg_device *pgmn_dev =
-		(struct msm_jpeg_device *)sd->host_priv;
-
-	JPEG_DBG("%s: cmd=%d\n", __func__, cmd);
-
-	JPEG_DBG("%s: pgmn_dev 0x%x", __func__, (uint32_t)pgmn_dev);
-
-	JPEG_DBG("%s: Calling __msm_jpeg_ioctl\n", __func__);
-
-	rc = __msm_jpeg_ioctl(pgmn_dev, cmd, (unsigned long)arg);
-	pr_debug("%s: X\n", __func__);
-	return rc;
-}
-
-void msm_jpeg_subdev_release(struct v4l2_subdev *jpeg_sd)
-{
-	int rc;
-	struct msm_jpeg_device *pgmn_dev =
-		(struct msm_jpeg_device *)jpeg_sd->host_priv;
-	JPEG_DBG("%s:pgmn_dev=0x%x", __func__, (uint32_t)pgmn_dev);
-	rc = __msm_jpeg_release(pgmn_dev);
-	JPEG_DBG("%s:rc=%d", __func__, rc);
-}
-
-static const struct v4l2_subdev_core_ops msm_jpeg_subdev_core_ops = {
-	.ioctl = msm_jpeg_subdev_ioctl,
-};
-
-static const struct v4l2_subdev_ops msm_jpeg_subdev_ops = {
-	.core = &msm_jpeg_subdev_core_ops,
-};
-
-static int msm_jpeg_init_dev(struct platform_device *pdev)
-{
-	int rc = -1;
-	struct device *dev;
-	struct msm_jpeg_device *msm_jpeg_device_p;
-	char devname[DEV_NAME_LEN];
-
-	msm_jpeg_device_p = kzalloc(sizeof(struct msm_jpeg_device), GFP_ATOMIC);
-	if (!msm_jpeg_device_p) {
-		JPEG_PR_ERR("%s: no mem\n", __func__);
-		return -EFAULT;
-	}
-
-	msm_jpeg_device_p->pdev = pdev;
-
-	if (pdev->dev.of_node)
-		of_property_read_u32((&pdev->dev)->of_node, "cell-index",
-			&pdev->id);
-
-	snprintf(devname, sizeof(devname), "%s%d", MSM_JPEG_NAME, pdev->id);
-
-	rc = __msm_jpeg_init(msm_jpeg_device_p);
-	if (rc < -1) {
-		JPEG_PR_ERR("%s: initialization failed\n", __func__);
-		goto fail;
-	}
-
-	v4l2_subdev_init(&msm_jpeg_device_p->subdev, &msm_jpeg_subdev_ops);
-	v4l2_set_subdev_hostdata(&msm_jpeg_device_p->subdev, msm_jpeg_device_p);
-	JPEG_DBG("%s: msm_jpeg_device_p 0x%x", __func__,
-			(uint32_t)msm_jpeg_device_p);
-
-	rc = alloc_chrdev_region(&msm_jpeg_device_p->msm_jpeg_devno, 0, 1,
-				devname);
-	if (rc < 0) {
-		JPEG_PR_ERR("%s: failed to allocate chrdev\n", __func__);
-		goto fail_1;
-	}
-
-	if (!msm_jpeg_device_p->msm_jpeg_class) {
-		msm_jpeg_device_p->msm_jpeg_class =
-				class_create(THIS_MODULE, devname);
-		if (IS_ERR(msm_jpeg_device_p->msm_jpeg_class)) {
-			rc = PTR_ERR(msm_jpeg_device_p->msm_jpeg_class);
-			JPEG_PR_ERR("%s: create device class failed\n",
-				__func__);
-			goto fail_2;
-		}
-	}
-
-	dev = device_create(msm_jpeg_device_p->msm_jpeg_class, NULL,
-		MKDEV(MAJOR(msm_jpeg_device_p->msm_jpeg_devno),
-		MINOR(msm_jpeg_device_p->msm_jpeg_devno)), NULL,
-		"%s%d", MSM_JPEG_NAME, pdev->id);
-	if (IS_ERR(dev)) {
-		JPEG_PR_ERR("%s: error creating device\n", __func__);
-		rc = -ENODEV;
-		goto fail_3;
-	}
-
-	cdev_init(&msm_jpeg_device_p->cdev, &msm_jpeg_fops);
-	msm_jpeg_device_p->cdev.owner = THIS_MODULE;
-	msm_jpeg_device_p->cdev.ops	 =
-		(const struct file_operations *) &msm_jpeg_fops;
-	rc = cdev_add(&msm_jpeg_device_p->cdev,
-			msm_jpeg_device_p->msm_jpeg_devno, 1);
-	if (rc < 0) {
-		JPEG_PR_ERR("%s: error adding cdev\n", __func__);
-		rc = -ENODEV;
-		goto fail_4;
-	}
-
-	platform_set_drvdata(pdev, &msm_jpeg_device_p);
-
-	JPEG_DBG("%s %s%d: success\n", __func__, MSM_JPEG_NAME, pdev->id);
-
-	return rc;
-
-fail_4:
-	device_destroy(msm_jpeg_device_p->msm_jpeg_class,
-			msm_jpeg_device_p->msm_jpeg_devno);
-
-fail_3:
-	class_destroy(msm_jpeg_device_p->msm_jpeg_class);
-
-fail_2:
-	unregister_chrdev_region(msm_jpeg_device_p->msm_jpeg_devno, 1);
-
-fail_1:
-	__msm_jpeg_exit(msm_jpeg_device_p);
-
-fail:
-	kfree(msm_jpeg_device_p);
-	return rc;
-
-}
-
-static void msm_jpeg_exit(struct msm_jpeg_device *msm_jpeg_device_p)
-{
-	cdev_del(&msm_jpeg_device_p->cdev);
-	device_destroy(msm_jpeg_device_p->msm_jpeg_class,
-			msm_jpeg_device_p->msm_jpeg_devno);
-	class_destroy(msm_jpeg_device_p->msm_jpeg_class);
-	unregister_chrdev_region(msm_jpeg_device_p->msm_jpeg_devno, 1);
-
-	__msm_jpeg_exit(msm_jpeg_device_p);
-}
-
-static int __msm_jpeg_probe(struct platform_device *pdev)
-{
-	return msm_jpeg_init_dev(pdev);
-}
-
-static int __msm_jpeg_remove(struct platform_device *pdev)
-{
-	struct msm_jpeg_device *msm_jpegd_device_p;
-
-	msm_jpegd_device_p = platform_get_drvdata(pdev);
-	if (msm_jpegd_device_p)
-		msm_jpeg_exit(msm_jpegd_device_p);
-
-	return 0;
-}
-
-static const struct of_device_id msm_jpeg_dt_match[] = {
-			{.compatible = "qcom,jpeg"},
-			{},
-};
-
-MODULE_DEVICE_TABLE(of, msm_jpeg_dt_match);
-
-static struct platform_driver msm_jpeg_driver = {
-	.probe	= __msm_jpeg_probe,
-	.remove = __msm_jpeg_remove,
-	.driver = {
-		.name = MSM_JPEG_DRV_NAME,
-		.owner = THIS_MODULE,
-		.of_match_table = msm_jpeg_dt_match,
-	},
-};
-
-static int __init msm_jpeg_driver_init(void)
-{
-	int rc;
-	rc = platform_driver_register(&msm_jpeg_driver);
-	return rc;
-}
-
-static void __exit msm_jpeg_driver_exit(void)
-{
-	platform_driver_unregister(&msm_jpeg_driver);
-}
-
-MODULE_DESCRIPTION("msm jpeg jpeg driver");
-
-module_init(msm_jpeg_driver_init);
-module_exit(msm_jpeg_driver_exit);
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw_reg.h b/drivers/media/video/msm/jpeg_10/msm_jpeg_hw_reg.h
deleted file mode 100644
index 31286dd..0000000
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw_reg.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#ifndef MSM_JPEG_HW_REG_H
-#define MSM_JPEG_HW_REG_H
-
-#define JPEG_REG_BASE 0
-
-#define MSM_JPEG_HW_IRQ_MASK_ADDR 0x00000018
-#define MSM_JPEG_HW_IRQ_MASK_RMSK 0xFFFFFFFF
-#define MSM_JPEG_HW_IRQ_ENABLE 0xFFFFFFFF
-
-#define MSM_JPEG_HW_IRQ_STATUS_FRAMEDONE_MASK 0x00000001
-#define MSM_JPEG_HW_IRQ_STATUS_FRAMEDONE_SHIFT 0x00000000
-
-#define MSM_JPEG_HW_IRQ_STATUS_FE_RD_DONE_MASK 0x00000010
-#define MSM_JPEG_HW_IRQ_STATUS_FE_RD_DONE_SHIFT 0x00000001
-
-#define MSM_JPEG_HW_IRQ_STATUS_FE_RTOVF_MASK 0x00000004
-#define MSM_JPEG_HW_IRQ_STATUS_FE_RTOVF_SHIFT 0x00000002
-
-#define MSM_JPEG_HW_IRQ_STATUS_FE_VFE_OVERFLOW_MASK 0x00000008
-#define MSM_JPEG_HW_IRQ_STATUS_FE_VFE_OVERFLOW_SHIFT 0x00000003
-
-#define MSM_JPEG_HW_IRQ_STATUS_WE_Y_PINGPONG_MASK 0x00000010
-#define MSM_JPEG_HW_IRQ_STATUS_WE_Y_PINGPONG_SHIFT 0x00000004
-
-#define MSM_JPEG_HW_IRQ_STATUS_WE_CBCR_PINGPONG_MASK 0x00000020
-#define MSM_JPEG_HW_IRQ_STATUS_WE_CBCR_PINGPONG_SHIFT 0x00000005
-
-#define MSM_JPEG_HW_IRQ_STATUS_RESET_ACK_MASK 0x10000000
-#define MSM_JPEG_HW_IRQ_STATUS_RESET_ACK_SHIFT 0x0000000a
-
-#define MSM_JPEG_HW_IRQ_STATUS_BUS_ERROR_MASK 0x00000800
-#define MSM_JPEG_HW_IRQ_STATUS_BUS_ERROR_SHIFT 0x0000000b
-
-#define MSM_JPEG_HW_IRQ_STATUS_DCD_UNESCAPED_FF      (0x1<<19)
-#define MSM_JPEG_HW_IRQ_STATUS_DCD_HUFFMAN_ERROR     (0x1<<20)
-#define MSM_JPEG_HW_IRQ_STATUS_DCD_COEFFICIENT_ERR   (0x1<<21)
-#define MSM_JPEG_HW_IRQ_STATUS_DCD_MISSING_BIT_STUFF (0x1<<22)
-#define MSM_JPEG_HW_IRQ_STATUS_DCD_SCAN_UNDERFLOW    (0x1<<23)
-#define MSM_JPEG_HW_IRQ_STATUS_DCD_INVALID_RSM       (0x1<<24)
-#define MSM_JPEG_HW_IRQ_STATUS_DCD_INVALID_RSM_SEQ   (0x1<<25)
-#define MSM_JPEG_HW_IRQ_STATUS_DCD_MISSING_RSM       (0x1<<26)
-#define MSM_JPEG_HW_IRQ_STATUS_VIOLATION_MASK        (0x1<<29)
-
-#define JPEG_OFFLINE_CMD_START 0x00000001
-
-#define JPEG_RESET_DEFAULT 0x00020000
-
-#define JPEG_IRQ_DISABLE_ALL 0x00000000
-#define JPEG_IRQ_CLEAR_ALL 0xFFFFFFFF
-
-#define JPEG_PLN0_RD_PNTR_ADDR (JPEG_REG_BASE + 0x00000038)
-#define JPEG_PLN0_RD_PNTR_BMSK  0xFFFFFFFF
-
-#define JPEG_PLN0_RD_OFFSET_ADDR 0x0000003C
-#define JPEG_PLN0_RD_OFFSET_BMSK 0x1FFFFFFF
-
-#define JPEG_PLN1_RD_PNTR_ADDR (JPEG_REG_BASE + 0x00000044)
-#define JPEG_PLN1_RD_PNTR_BMSK 0xFFFFFFFF
-
-#define JPEG_PLN1_RD_OFFSET_ADDR 0x00000048
-#define JPEG_PLN1_RD_OFFSET_BMSK 0x1FFFFFFF
-
-#define JPEG_PLN2_RD_PNTR_ADDR (JPEG_REG_BASE + 0x00000050)
-#define JPEG_PLN2_RD_PNTR_BMSK 0xFFFFFFFF
-
-#define JPEG_PLN2_RD_OFFSET_ADDR 0x00000054
-#define JPEG_PLN2_RD_OFFSET_BMSK 0x1FFFFFFF
-
-#define JPEG_CMD_ADDR (JPEG_REG_BASE + 0x00000010)
-#define JPEG_CMD_BMSK 0x00000FFF
-#define JPEG_CMD_CLEAR_WRITE_PLN_QUEUES 0x700
-
-#define JPEG_PLN0_WR_PNTR_ADDR (JPEG_REG_BASE + 0x000000cc)
-#define JPEG_PLN0_WR_PNTR_BMSK 0xFFFFFFFF
-
-#define JPEG_PLN1_WR_PNTR_ADDR (JPEG_REG_BASE + 0x000000D0)
-#define JPEG_PLN1_WR_PNTR_BMSK 0xFFFFFFFF
-
-#define JPEG_PLN2_WR_PNTR_ADDR (JPEG_REG_BASE + 0x000000D4)
-#define JPEG_PLN2_WR_PNTR_BMSK 0xFFFFFFFF
-
-#define JPEG_IRQ_MASK_ADDR (JPEG_REG_BASE + 0x00000018)
-#define JPEG_IRQ_MASK_BMSK 0xFFFFFFFF
-#define JPEG_IRQ_ALLSOURCES_ENABLE 0xFFFFFFFF
-
-#define JPEG_IRQ_CLEAR_ADDR (JPEG_REG_BASE + 0x0000001c)
-#define JPEG_IRQ_CLEAR_BMSK 0xFFFFFFFF
-
-#define JPEG_RESET_CMD_ADDR (JPEG_REG_BASE + 0x00000008)
-#define JPEG_RESET_CMD_RMSK 0xFFFFFFFF
-
-#define JPEG_IRQ_STATUS_ADDR (JPEG_REG_BASE + 0x00000020)
-#define JPEG_IRQ_STATUS_BMSK 0xFFFFFFFF
-
-#define JPEG_ENCODE_OUTPUT_SIZE_STATUS_ADDR (JPEG_REG_BASE + 0x00000180)
-#define JPEG_ENCODE_OUTPUT_SIZE_STATUS_BMSK 0x1FFFFFFF
-
-#define JPEG_DECODE_MCUS_DECODED_STATUS   (JPEG_REG_BASE + 0x00000258)
-#define JPEG_DECODE_BITS_CONSUMED_STATUS  (JPEG_REG_BASE + 0x0000025C)
-#define JPEG_DECODE_PRED_Y_STATE          (JPEG_REG_BASE + 0x00000260)
-#define JPEG_DECODE_PRED_C_STATE          (JPEG_REG_BASE + 0x00000264)
-#define JPEG_DECODE_RSM_STATE             (JPEG_REG_BASE + 0x00000268)
-
-#define VBIF_BASE_ADDRESS                      0xFDA60000
-#define VBIF_REGION_SIZE                       0xC30
-#define JPEG_VBIF_CLKON                        0x4
-#define JPEG_VBIF_IN_RD_LIM_CONF0              0xB0
-#define JPEG_VBIF_IN_RD_LIM_CONF1              0xB4
-#define JPEG_VBIF_IN_RD_LIM_CONF2              0xB8
-#define JPEG_VBIF_IN_WR_LIM_CONF0              0xC0
-#define JPEG_VBIF_IN_WR_LIM_CONF1              0xC4
-#define JPEG_VBIF_IN_WR_LIM_CONF2              0xC8
-#define JPEG_VBIF_OUT_RD_LIM_CONF0             0xD0
-#define JPEG_VBIF_OUT_WR_LIM_CONF0             0xD4
-#define JPEG_VBIF_DDR_OUT_MAX_BURST            0xD8
-#define JPEG_VBIF_OCMEM_OUT_MAX_BURST          0xDC
-#define JPEG_VBIF_ARB_CTL                      0xF0
-#define JPEG_VBIF_OUT_AXI_AOOO_EN              0x178
-#define JPEG_VBIF_OUT_AXI_AOOO                 0x17c
-#define JPEG_VBIF_ROUND_ROBIN_QOS_ARB          0x124
-#define JPEG_VBIF_OUT_AXI_AMEMTYPE_CONF0       0x160
-#define JPEG_VBIF_OUT_AXI_AMEMTYPE_CONF1       0x164
-
-#endif /* MSM_JPEG_HW_REG_H */
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.c b/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.c
deleted file mode 100644
index 38a0ffb..0000000
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-
-
-#include <linux/module.h>
-#include <linux/pm_qos.h>
-#include <linux/clk.h>
-#include <mach/clk.h>
-#include <linux/io.h>
-#include <linux/android_pmem.h>
-#include <mach/camera.h>
-#include <mach/iommu_domains.h>
-
-#include "msm_jpeg_platform.h"
-#include "msm_jpeg_sync.h"
-#include "msm_jpeg_common.h"
-#include "msm_jpeg_hw.h"
-
-void msm_jpeg_platform_p2v(struct msm_jpeg_device *pgmn_dev, struct file  *file,
-	struct ion_handle **ionhandle, int domain_num)
-{
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	ion_unmap_iommu(pgmn_dev->jpeg_client, *ionhandle, domain_num, 0);
-	ion_free(pgmn_dev->jpeg_client, *ionhandle);
-	*ionhandle = NULL;
-#elif CONFIG_ANDROID_PMEM
-	put_pmem_file(file);
-#endif
-}
-
-uint32_t msm_jpeg_platform_v2p(struct msm_jpeg_device *pgmn_dev, int fd,
-	uint32_t len, struct file **file_p, struct ion_handle **ionhandle,
-	int domain_num) {
-	unsigned long paddr;
-	unsigned long size;
-	int rc;
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	*ionhandle = ion_import_dma_buf(pgmn_dev->jpeg_client, fd);
-	if (IS_ERR_OR_NULL(*ionhandle))
-		return 0;
-
-	rc = ion_map_iommu(pgmn_dev->jpeg_client, *ionhandle, domain_num, 0,
-		SZ_4K, 0, &paddr, (unsigned long *)&size, 0,
-0); JPEG_DBG("%s:%d] addr 0x%x size %ld", __func__, __LINE__,
-							(uint32_t)paddr, size);
-
-#elif CONFIG_ANDROID_PMEM
-	unsigned long kvstart;
-	rc = get_pmem_file(fd, &paddr, &kvstart, &size, file_p);
-#else
-	rc = 0;
-	paddr = 0;
-	size = 0;
-#endif
-	if (rc < 0) {
-		JPEG_PR_ERR("%s: get_pmem_file fd %d error %d\n", __func__, fd,
-			rc);
-		goto error1;
-	}
-
-	/* validate user input */
-	if (len > size) {
-		JPEG_PR_ERR("%s: invalid offset + len\n", __func__);
-		goto error1;
-	}
-
-	return paddr;
-error1:
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	ion_free(pgmn_dev->jpeg_client, *ionhandle);
-#endif
-	return 0;
-}
-
-static struct msm_cam_clk_info jpeg_8x_clk_info[] = {
-	{"core_clk", 228570000},
-	{"iface_clk", -1},
-	{"bus_clk0", -1},
-	{"alt_bus_clk", -1},
-	{"camss_top_ahb_clk", -1},
-};
-
-static void set_vbif_params(void *jpeg_vbif_base)
-{
-	writel_relaxed(0x1,
-		jpeg_vbif_base + JPEG_VBIF_CLKON);
-	writel_relaxed(0x10101010,
-		jpeg_vbif_base + JPEG_VBIF_IN_RD_LIM_CONF0);
-	writel_relaxed(0x10101010,
-		jpeg_vbif_base + JPEG_VBIF_IN_RD_LIM_CONF1);
-	writel_relaxed(0x10101010,
-		jpeg_vbif_base + JPEG_VBIF_IN_RD_LIM_CONF2);
-	writel_relaxed(0x10101010,
-		jpeg_vbif_base + JPEG_VBIF_IN_WR_LIM_CONF0);
-	writel_relaxed(0x10101010,
-		jpeg_vbif_base + JPEG_VBIF_IN_WR_LIM_CONF1);
-	writel_relaxed(0x10101010,
-		jpeg_vbif_base + JPEG_VBIF_IN_WR_LIM_CONF2);
-	writel_relaxed(0x00001010,
-		jpeg_vbif_base + JPEG_VBIF_OUT_RD_LIM_CONF0);
-	writel_relaxed(0x00000110,
-		jpeg_vbif_base + JPEG_VBIF_OUT_WR_LIM_CONF0);
-	writel_relaxed(0x00000707,
-		jpeg_vbif_base + JPEG_VBIF_DDR_OUT_MAX_BURST);
-	writel_relaxed(0x7,
-		jpeg_vbif_base + JPEG_VBIF_OCMEM_OUT_MAX_BURST);
-	writel_relaxed(0x00000030,
-		jpeg_vbif_base + JPEG_VBIF_ARB_CTL);
-	writel_relaxed(0x00000FFF,
-		jpeg_vbif_base + JPEG_VBIF_OUT_AXI_AOOO_EN);
-	writel_relaxed(0x0FFF0FFF,
-		jpeg_vbif_base + JPEG_VBIF_OUT_AXI_AOOO);
-	/*FE and WE QOS configuration need to be set when
-	QOS RR arbitration is enabled*/
-	writel_relaxed(0x00000001,
-		jpeg_vbif_base + JPEG_VBIF_ROUND_ROBIN_QOS_ARB);
-	writel_relaxed(0x22222222,
-		jpeg_vbif_base + JPEG_VBIF_OUT_AXI_AMEMTYPE_CONF0);
-	writel_relaxed(0x2222,
-		jpeg_vbif_base + JPEG_VBIF_OUT_AXI_AMEMTYPE_CONF1);
-}
-
-
-int msm_jpeg_platform_init(struct platform_device *pdev,
-	struct resource **mem,
-	void **base,
-	int *irq,
-	irqreturn_t (*handler) (int, void *),
-	void *context)
-{
-	int rc = -1;
-	int i = 0;
-	int jpeg_irq;
-	struct resource *jpeg_mem, *jpeg_io, *jpeg_irq_res;
-	void *jpeg_base;
-	struct msm_jpeg_device *pgmn_dev =
-		(struct msm_jpeg_device *) context;
-
-	jpeg_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!jpeg_mem) {
-		JPEG_PR_ERR("%s: no mem resource?\n", __func__);
-		return -ENODEV;
-	}
-
-	jpeg_irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!jpeg_irq_res) {
-		JPEG_PR_ERR("no irq resource?\n");
-		return -ENODEV;
-	}
-	jpeg_irq = jpeg_irq_res->start;
-	JPEG_DBG("%s base address: 0x%x, jpeg irq number: %d\n", __func__,
-		jpeg_mem->start, jpeg_irq);
-
-	jpeg_io = request_mem_region(jpeg_mem->start,
-		resource_size(jpeg_mem), pdev->name);
-	if (!jpeg_io) {
-		JPEG_PR_ERR("%s: region already claimed\n", __func__);
-		return -EBUSY;
-	}
-
-	jpeg_base = ioremap(jpeg_mem->start, resource_size(jpeg_mem));
-	if (!jpeg_base) {
-		rc = -ENOMEM;
-		JPEG_PR_ERR("%s: ioremap failed\n", __func__);
-		goto fail1;
-	}
-
-	pgmn_dev->jpeg_vbif = ioremap(VBIF_BASE_ADDRESS, VBIF_REGION_SIZE);
-	if (!pgmn_dev->jpeg_vbif) {
-		rc = -ENOMEM;
-		JPEG_PR_ERR("%s:%d] ioremap failed\n", __func__, __LINE__);
-		goto fail1;
-	}
-	JPEG_DBG("%s:%d] jpeg_vbif 0x%x", __func__, __LINE__,
-		(uint32_t)pgmn_dev->jpeg_vbif);
-
-	pgmn_dev->jpeg_fs = regulator_get(&pgmn_dev->pdev->dev, "vdd");
-	rc = regulator_enable(pgmn_dev->jpeg_fs);
-	if (rc) {
-		JPEG_PR_ERR("%s:%d]jpeg regulator get failed\n",
-				__func__, __LINE__); }
-
-	pgmn_dev->hw_version = JPEG_8974;
-	rc = msm_cam_clk_enable(&pgmn_dev->pdev->dev, jpeg_8x_clk_info,
-	 pgmn_dev->jpeg_clk, ARRAY_SIZE(jpeg_8x_clk_info), 1);
-	if (rc < 0) {
-		JPEG_PR_ERR("%s: clk failed rc = %d\n", __func__, rc);
-		goto fail2;
-	}
-
-#ifdef CONFIG_MSM_IOMMU
-	for (i = 0; i < pgmn_dev->iommu_cnt; i++) {
-		rc = iommu_attach_device(pgmn_dev->domain,
-				pgmn_dev->iommu_ctx_arr[i]);
-		if (rc < 0) {
-			rc = -ENODEV;
-			JPEG_PR_ERR("%s: Device attach failed\n", __func__);
-			goto fail;
-		}
-		JPEG_DBG("%s:%d] dom 0x%x ctx 0x%x", __func__, __LINE__,
-					(uint32_t)pgmn_dev->domain,
-					(uint32_t)pgmn_dev->iommu_ctx_arr[i]);
-	}
-#endif
-	set_vbif_params(pgmn_dev->jpeg_vbif);
-
-	rc = request_irq(jpeg_irq, handler, IRQF_TRIGGER_RISING, "jpeg",
-		context);
-	if (rc) {
-		JPEG_PR_ERR("%s: request_irq failed, %d\n", __func__,
-			jpeg_irq);
-		goto fail3;
-	}
-
-	*mem  = jpeg_mem;
-	*base = jpeg_base;
-	*irq  = jpeg_irq;
-
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	pgmn_dev->jpeg_client = msm_ion_client_create(-1, "camera/jpeg");
-#endif
-	JPEG_DBG("%s:%d] success\n", __func__, __LINE__);
-
-	return rc;
-
-fail3:
-	msm_cam_clk_enable(&pgmn_dev->pdev->dev, jpeg_8x_clk_info,
-	pgmn_dev->jpeg_clk, ARRAY_SIZE(jpeg_8x_clk_info), 0);
-
-	regulator_put(pgmn_dev->jpeg_fs);
-	regulator_disable(pgmn_dev->jpeg_fs);
-	pgmn_dev->jpeg_fs = NULL;
-fail2:
-	iounmap(jpeg_base);
-fail1:
-#ifdef CONFIG_MSM_IOMMU
-	for (i = 0; i < pgmn_dev->iommu_cnt; i++) {
-		JPEG_PR_ERR("%s:%d] dom 0x%x ctx 0x%x", __func__, __LINE__,
-					(uint32_t)pgmn_dev->domain,
-					(uint32_t)pgmn_dev->iommu_ctx_arr[i]);
-		iommu_detach_device(pgmn_dev->domain,
-					pgmn_dev->iommu_ctx_arr[i]);
-	}
-#endif
-fail:
-	release_mem_region(jpeg_mem->start, resource_size(jpeg_mem));
-	JPEG_DBG("%s:%d] fail\n", __func__, __LINE__);
-	return rc;
-}
-
-int msm_jpeg_platform_release(struct resource *mem, void *base, int irq,
-	void *context)
-{
-	int result = 0;
-	int i = 0;
-	struct msm_jpeg_device *pgmn_dev =
-		(struct msm_jpeg_device *) context;
-
-	free_irq(irq, context);
-
-#ifdef CONFIG_MSM_IOMMU
-	for (i = 0; i < pgmn_dev->iommu_cnt; i++) {
-		iommu_detach_device(pgmn_dev->domain,
-				pgmn_dev->iommu_ctx_arr[i]);
-		JPEG_DBG("%s:%d]", __func__, __LINE__);
-	}
-#endif
-
-	msm_cam_clk_enable(&pgmn_dev->pdev->dev, jpeg_8x_clk_info,
-	pgmn_dev->jpeg_clk, ARRAY_SIZE(jpeg_8x_clk_info), 0);
-	JPEG_DBG("%s:%d] clock disbale done", __func__, __LINE__);
-
-	if (pgmn_dev->jpeg_fs) {
-		regulator_put(pgmn_dev->jpeg_fs);
-		regulator_disable(pgmn_dev->jpeg_fs);
-		pgmn_dev->jpeg_fs = NULL;
-	}
-	iounmap(pgmn_dev->jpeg_vbif);
-	iounmap(base);
-	release_mem_region(mem->start, resource_size(mem));
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	ion_client_destroy(pgmn_dev->jpeg_client);
-#endif
-	JPEG_DBG("%s:%d] success\n", __func__, __LINE__);
-	return result;
-}
-
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.c b/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.c
deleted file mode 100644
index a7a9d70..0000000
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.c
+++ /dev/null
@@ -1,949 +0,0 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/list.h>
-#include <linux/uaccess.h>
-#include <linux/slab.h>
-#include <media/msm_jpeg.h>
-#include "msm_jpeg_sync.h"
-#include "msm_jpeg_core.h"
-#include "msm_jpeg_platform.h"
-#include "msm_jpeg_common.h"
-
-#define JPEG_REG_SIZE 0x308
-#define JPEG_DEV_CNT 3
-#define JPEG_DEC_ID 2
-
-inline void msm_jpeg_q_init(char const *name, struct msm_jpeg_q *q_p)
-{
-	JPEG_DBG("%s:%d] %s\n", __func__, __LINE__, name);
-	q_p->name = name;
-	spin_lock_init(&q_p->lck);
-	INIT_LIST_HEAD(&q_p->q);
-	init_waitqueue_head(&q_p->wait);
-	q_p->unblck = 0;
-}
-
-inline void *msm_jpeg_q_out(struct msm_jpeg_q *q_p)
-{
-	unsigned long flags;
-	struct msm_jpeg_q_entry *q_entry_p = NULL;
-	void *data = NULL;
-
-	JPEG_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
-	spin_lock_irqsave(&q_p->lck, flags);
-	if (!list_empty(&q_p->q)) {
-		q_entry_p = list_first_entry(&q_p->q, struct msm_jpeg_q_entry,
-			list);
-		list_del_init(&q_entry_p->list);
-	}
-	spin_unlock_irqrestore(&q_p->lck, flags);
-
-	if (q_entry_p) {
-		data = q_entry_p->data;
-		kfree(q_entry_p);
-	} else {
-		JPEG_DBG("%s:%d] %s no entry\n", __func__, __LINE__,
-			q_p->name);
-	}
-
-	return data;
-}
-
-inline int msm_jpeg_q_in(struct msm_jpeg_q *q_p, void *data)
-{
-	unsigned long flags;
-
-	struct msm_jpeg_q_entry *q_entry_p;
-
-	JPEG_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
-
-	q_entry_p = kmalloc(sizeof(struct msm_jpeg_q_entry), GFP_ATOMIC);
-	if (!q_entry_p) {
-		JPEG_PR_ERR("%s: no mem\n", __func__);
-		return -EFAULT;
-	}
-	q_entry_p->data = data;
-
-	spin_lock_irqsave(&q_p->lck, flags);
-	list_add_tail(&q_entry_p->list, &q_p->q);
-	spin_unlock_irqrestore(&q_p->lck, flags);
-
-	return 0;
-}
-
-inline int msm_jpeg_q_in_buf(struct msm_jpeg_q *q_p,
-	struct msm_jpeg_core_buf *buf)
-{
-	struct msm_jpeg_core_buf *buf_p;
-
-	JPEG_DBG("%s:%d]\n", __func__, __LINE__);
-	buf_p = kmalloc(sizeof(struct msm_jpeg_core_buf), GFP_ATOMIC);
-	if (!buf_p) {
-		JPEG_PR_ERR("%s: no mem\n", __func__);
-		return -EFAULT;
-	}
-
-	memcpy(buf_p, buf, sizeof(struct msm_jpeg_core_buf));
-
-	msm_jpeg_q_in(q_p, buf_p);
-	return 0;
-}
-
-inline int msm_jpeg_q_wait(struct msm_jpeg_q *q_p)
-{
-	int tm = MAX_SCHEDULE_TIMEOUT; /* 500ms */
-	int rc;
-
-	JPEG_DBG("%s:%d] %s wait\n", __func__, __LINE__, q_p->name);
-	rc = wait_event_interruptible_timeout(q_p->wait,
-		(!list_empty_careful(&q_p->q) || q_p->unblck),
-		msecs_to_jiffies(tm));
-	JPEG_DBG("%s:%d] %s wait done\n", __func__, __LINE__, q_p->name);
-	if (list_empty_careful(&q_p->q)) {
-		if (rc == 0) {
-			rc = -ETIMEDOUT;
-			JPEG_PR_ERR("%s:%d] %s timeout\n", __func__, __LINE__,
-				q_p->name);
-		} else if (q_p->unblck) {
-			JPEG_DBG("%s:%d] %s unblock is true\n", __func__,
-				__LINE__, q_p->name);
-			q_p->unblck = 0;
-			rc = -ECANCELED;
-		} else if (rc < 0) {
-			JPEG_PR_ERR("%s:%d] %s rc %d\n", __func__, __LINE__,
-				q_p->name, rc);
-		}
-	}
-	return rc;
-}
-
-inline int msm_jpeg_q_wakeup(struct msm_jpeg_q *q_p)
-{
-	JPEG_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
-	wake_up(&q_p->wait);
-	return 0;
-}
-
-inline int msm_jpeg_q_unblock(struct msm_jpeg_q *q_p)
-{
-	JPEG_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
-	q_p->unblck = 1;
-	wake_up(&q_p->wait);
-	return 0;
-}
-
-inline void msm_jpeg_outbuf_q_cleanup(struct msm_jpeg_device *pgmn_dev,
-	struct msm_jpeg_q *q_p, int domain_num)
-{
-	struct msm_jpeg_core_buf *buf_p;
-	JPEG_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
-	do {
-		buf_p = msm_jpeg_q_out(q_p);
-		if (buf_p) {
-			msm_jpeg_platform_p2v(pgmn_dev, buf_p->file,
-				&buf_p->handle, domain_num);
-			JPEG_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
-			kfree(buf_p);
-		}
-	} while (buf_p);
-	q_p->unblck = 0;
-}
-
-inline void msm_jpeg_q_cleanup(struct msm_jpeg_q *q_p)
-{
-	void *data;
-	JPEG_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
-	do {
-		data = msm_jpeg_q_out(q_p);
-		if (data) {
-			JPEG_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
-			kfree(data);
-		}
-	} while (data);
-	q_p->unblck = 0;
-}
-
-/*************** event queue ****************/
-
-int msm_jpeg_framedone_irq(struct msm_jpeg_device *pgmn_dev,
-	struct msm_jpeg_core_buf *buf_in)
-{
-	int rc = 0;
-
-	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
-
-	if (buf_in) {
-		buf_in->vbuf.framedone_len = buf_in->framedone_len;
-		buf_in->vbuf.type = MSM_JPEG_EVT_SESSION_DONE;
-		JPEG_DBG("%s:%d] 0x%08x %d framedone_len %d\n",
-			__func__, __LINE__,
-			(int) buf_in->y_buffer_addr, buf_in->y_len,
-			buf_in->vbuf.framedone_len);
-		rc = msm_jpeg_q_in_buf(&pgmn_dev->evt_q, buf_in);
-	} else {
-		JPEG_PR_ERR("%s:%d] no output return buffer\n",
-			__func__, __LINE__);
-		rc = -1;
-	}
-
-	if (buf_in)
-		rc = msm_jpeg_q_wakeup(&pgmn_dev->evt_q);
-
-	return rc;
-}
-
-int msm_jpeg_evt_get(struct msm_jpeg_device *pgmn_dev,
-	void __user *to)
-{
-	struct msm_jpeg_core_buf *buf_p;
-	struct msm_jpeg_ctrl_cmd ctrl_cmd;
-
-	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
-
-	msm_jpeg_q_wait(&pgmn_dev->evt_q);
-	buf_p = msm_jpeg_q_out(&pgmn_dev->evt_q);
-
-	if (!buf_p) {
-		JPEG_DBG("%s:%d] no buffer\n", __func__, __LINE__);
-		return -EAGAIN;
-	}
-
-	ctrl_cmd.type = buf_p->vbuf.type;
-	kfree(buf_p);
-
-	JPEG_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
-		(int) ctrl_cmd.value, ctrl_cmd.len);
-
-	if (copy_to_user(to, &ctrl_cmd, sizeof(ctrl_cmd))) {
-		JPEG_PR_ERR("%s:%d]\n", __func__, __LINE__);
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
-int msm_jpeg_evt_get_unblock(struct msm_jpeg_device *pgmn_dev)
-{
-	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
-	msm_jpeg_q_unblock(&pgmn_dev->evt_q);
-	return 0;
-}
-
-void msm_jpeg_reset_ack_irq(struct msm_jpeg_device *pgmn_dev)
-{
-	JPEG_DBG("%s:%d]\n", __func__, __LINE__);
-}
-
-void msm_jpeg_err_irq(struct msm_jpeg_device *pgmn_dev,
-	int event)
-{
-	int rc = 0;
-	struct msm_jpeg_core_buf buf;
-
-	JPEG_PR_ERR("%s:%d] error: %d\n", __func__, __LINE__, event);
-
-	buf.vbuf.type = MSM_JPEG_EVT_ERR;
-	rc = msm_jpeg_q_in_buf(&pgmn_dev->evt_q, &buf);
-	if (!rc)
-		rc = msm_jpeg_q_wakeup(&pgmn_dev->evt_q);
-
-	if (!rc)
-		JPEG_PR_ERR("%s:%d] err err\n", __func__, __LINE__);
-
-	return;
-}
-
-/*************** output queue ****************/
-
-int msm_jpeg_we_pingpong_irq(struct msm_jpeg_device *pgmn_dev,
-	struct msm_jpeg_core_buf *buf_in)
-{
-	int rc = 0;
-	struct msm_jpeg_core_buf *buf_out;
-
-	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
-	if (buf_in) {
-		JPEG_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
-			(int) buf_in->y_buffer_addr, buf_in->y_len);
-		rc = msm_jpeg_q_in_buf(&pgmn_dev->output_rtn_q, buf_in);
-	} else {
-		JPEG_DBG("%s:%d] no output return buffer\n", __func__,
-			__LINE__);
-		rc = -1;
-		return rc;
-	}
-
-	buf_out = msm_jpeg_q_out(&pgmn_dev->output_buf_q);
-
-	if (buf_out) {
-		JPEG_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
-			(int) buf_out->y_buffer_addr, buf_out->y_len);
-		rc = msm_jpeg_core_we_buf_update(pgmn_dev, buf_out);
-		kfree(buf_out);
-	} else {
-		msm_jpeg_core_we_buf_reset(pgmn_dev, buf_in);
-		JPEG_DBG("%s:%d] no output buffer\n", __func__, __LINE__);
-		rc = -2;
-	}
-
-	if (buf_in)
-		rc = msm_jpeg_q_wakeup(&pgmn_dev->output_rtn_q);
-
-	return rc;
-}
-
-int msm_jpeg_output_get(struct msm_jpeg_device *pgmn_dev, void __user *to)
-{
-	struct msm_jpeg_core_buf *buf_p;
-	struct msm_jpeg_buf buf_cmd;
-
-	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
-
-	msm_jpeg_q_wait(&pgmn_dev->output_rtn_q);
-	buf_p = msm_jpeg_q_out(&pgmn_dev->output_rtn_q);
-
-	if (!buf_p) {
-		JPEG_DBG("%s:%d] no output buffer return\n",
-			__func__, __LINE__);
-		return -EAGAIN;
-	}
-
-	buf_cmd = buf_p->vbuf;
-	msm_jpeg_platform_p2v(pgmn_dev, buf_p->file, &buf_p->handle,
-		pgmn_dev->domain_num);
-	kfree(buf_p);
-
-	JPEG_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
-		(int) buf_cmd.vaddr, buf_cmd.y_len);
-
-	if (copy_to_user(to, &buf_cmd, sizeof(buf_cmd))) {
-		JPEG_PR_ERR("%s:%d]", __func__, __LINE__);
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
-int msm_jpeg_output_get_unblock(struct msm_jpeg_device *pgmn_dev)
-{
-	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
-	msm_jpeg_q_unblock(&pgmn_dev->output_rtn_q);
-	return 0;
-}
-
-int msm_jpeg_output_buf_enqueue(struct msm_jpeg_device *pgmn_dev,
-	void __user *arg)
-{
-	struct msm_jpeg_buf buf_cmd;
-	struct msm_jpeg_core_buf *buf_p;
-	memset(&buf_cmd, 0x0, sizeof(struct msm_jpeg_buf));
-
-	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
-	if (copy_from_user(&buf_cmd, arg, sizeof(struct msm_jpeg_buf))) {
-		JPEG_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
-		return -EFAULT;
-	}
-
-	buf_p = kmalloc(sizeof(struct msm_jpeg_core_buf), GFP_ATOMIC);
-	if (!buf_p) {
-		JPEG_PR_ERR("%s:%d] no mem\n", __func__, __LINE__);
-		return -EFAULT;
-	}
-
-	JPEG_DBG("%s:%d] vaddr = 0x%08x y_len = %d\n, fd = %d",
-		__func__, __LINE__, (int) buf_cmd.vaddr, buf_cmd.y_len,
-		buf_cmd.fd);
-
-	buf_p->y_buffer_addr = msm_jpeg_platform_v2p(pgmn_dev, buf_cmd.fd,
-		buf_cmd.y_len + buf_cmd.cbcr_len + buf_cmd.pln2_len,
-		&buf_p->file, &buf_p->handle, pgmn_dev->domain_num);
-	if (!buf_p->y_buffer_addr) {
-		JPEG_PR_ERR("%s:%d] v2p wrong\n", __func__, __LINE__);
-		kfree(buf_p);
-		return -EFAULT;
-	}
-
-	if (buf_cmd.cbcr_len)
-		buf_p->cbcr_buffer_addr = buf_p->y_buffer_addr +
-			buf_cmd.y_len;
-	else
-		buf_p->cbcr_buffer_addr = 0x0;
-
-	if (buf_cmd.pln2_len)
-		buf_p->pln2_addr = buf_p->cbcr_buffer_addr +
-			buf_cmd.cbcr_len;
-	else
-		buf_p->pln2_addr = 0x0;
-
-	JPEG_DBG("%s:%d]After v2p pln0_addr %x pln0_len %d",
-		__func__, __LINE__, buf_p->y_buffer_addr,
-		buf_cmd.y_len);
-
-	JPEG_DBG("pl1_len %d, pln1_addr %x, pln2_adrr %x,pln2_len %d",
-		buf_cmd.cbcr_len, buf_p->cbcr_buffer_addr,
-		buf_p->pln2_addr, buf_cmd.pln2_len);
-
-	buf_p->y_len = buf_cmd.y_len;
-	buf_p->cbcr_len = buf_cmd.cbcr_len;
-	buf_p->pln2_len = buf_cmd.pln2_len;
-	buf_p->vbuf = buf_cmd;
-
-	msm_jpeg_q_in(&pgmn_dev->output_buf_q, buf_p);
-	return 0;
-}
-
-/*************** input queue ****************/
-
-int msm_jpeg_fe_pingpong_irq(struct msm_jpeg_device *pgmn_dev,
-	struct msm_jpeg_core_buf *buf_in)
-{
-	struct msm_jpeg_core_buf *buf_out;
-	int rc = 0;
-
-	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
-	if (buf_in) {
-		JPEG_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
-			(int) buf_in->y_buffer_addr, buf_in->y_len);
-		rc = msm_jpeg_q_in_buf(&pgmn_dev->input_rtn_q, buf_in);
-	} else {
-		JPEG_DBG("%s:%d] no input return buffer\n", __func__,
-			__LINE__);
-		rc = -EFAULT;
-	}
-
-	buf_out = msm_jpeg_q_out(&pgmn_dev->input_buf_q);
-
-	if (buf_out) {
-		rc = msm_jpeg_core_fe_buf_update(pgmn_dev, buf_out);
-		kfree(buf_out);
-		msm_jpeg_core_fe_start(pgmn_dev);
-	} else {
-		JPEG_DBG("%s:%d] no input buffer\n", __func__, __LINE__);
-		rc = -EFAULT;
-	}
-
-	if (buf_in)
-		rc = msm_jpeg_q_wakeup(&pgmn_dev->input_rtn_q);
-
-	return rc;
-}
-
-int msm_jpeg_input_get(struct msm_jpeg_device *pgmn_dev, void __user *to)
-{
-	struct msm_jpeg_core_buf *buf_p;
-	struct msm_jpeg_buf buf_cmd;
-
-	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
-	msm_jpeg_q_wait(&pgmn_dev->input_rtn_q);
-	buf_p = msm_jpeg_q_out(&pgmn_dev->input_rtn_q);
-
-	if (!buf_p) {
-		JPEG_DBG("%s:%d] no input buffer return\n",
-			__func__, __LINE__);
-		return -EAGAIN;
-	}
-
-	buf_cmd = buf_p->vbuf;
-	msm_jpeg_platform_p2v(pgmn_dev, buf_p->file, &buf_p->handle,
-		pgmn_dev->domain_num);
-	kfree(buf_p);
-
-	JPEG_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
-		(int) buf_cmd.vaddr, buf_cmd.y_len);
-
-	if (copy_to_user(to, &buf_cmd, sizeof(buf_cmd))) {
-		JPEG_PR_ERR("%s:%d]\n", __func__, __LINE__);
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
-int msm_jpeg_input_get_unblock(struct msm_jpeg_device *pgmn_dev)
-{
-	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
-	msm_jpeg_q_unblock(&pgmn_dev->input_rtn_q);
-	return 0;
-}
-
-int msm_jpeg_input_buf_enqueue(struct msm_jpeg_device *pgmn_dev,
-	void __user *arg)
-{
-	struct msm_jpeg_core_buf *buf_p;
-	struct msm_jpeg_buf buf_cmd;
-	memset(&buf_cmd, 0x0, sizeof(struct msm_jpeg_buf));
-
-	if (copy_from_user(&buf_cmd, arg, sizeof(struct msm_jpeg_buf))) {
-		JPEG_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
-		return -EFAULT;
-	}
-
-	buf_p = kmalloc(sizeof(struct msm_jpeg_core_buf), GFP_ATOMIC);
-	if (!buf_p) {
-		JPEG_PR_ERR("%s:%d] no mem\n", __func__, __LINE__);
-		return -EFAULT;
-	}
-
-	JPEG_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
-		(int) buf_cmd.vaddr, buf_cmd.y_len);
-
-	buf_p->y_buffer_addr    = msm_jpeg_platform_v2p(pgmn_dev, buf_cmd.fd,
-		buf_cmd.y_len + buf_cmd.cbcr_len + buf_cmd.pln2_len,
-		&buf_p->file, &buf_p->handle, pgmn_dev->domain_num) +
-		buf_cmd.offset + buf_cmd.y_off;
-	buf_p->y_len          = buf_cmd.y_len;
-	buf_p->cbcr_len       = buf_cmd.cbcr_len;
-	buf_p->pln2_len       = buf_cmd.pln2_len;
-	buf_p->num_of_mcu_rows = buf_cmd.num_of_mcu_rows;
-
-	if (buf_cmd.cbcr_len)
-		buf_p->cbcr_buffer_addr = buf_p->y_buffer_addr +
-		buf_cmd.y_len + buf_cmd.cbcr_off;
-	else
-		buf_p->cbcr_buffer_addr = 0x0;
-
-	if (buf_cmd.pln2_len)
-		buf_p->pln2_addr = buf_p->cbcr_buffer_addr +
-		buf_cmd.cbcr_len + buf_cmd.pln2_off;
-	else
-		buf_p->pln2_addr = 0x0;
-
-	JPEG_DBG("%s: y_addr=%x, y_len=%x, cbcr_addr=%x, cbcr_len=%d",
-		__func__, buf_p->y_buffer_addr, buf_p->y_len,
-		buf_p->cbcr_buffer_addr, buf_p->cbcr_len);
-	JPEG_DBG("pln2_addr = %x, pln2_len = %d, fd =%d\n",
-		buf_p->pln2_addr, buf_p->pln2_len, buf_cmd.fd);
-
-	if (!buf_p->y_buffer_addr) {
-		JPEG_PR_ERR("%s:%d] v2p wrong\n", __func__, __LINE__);
-		kfree(buf_p);
-		return -EFAULT;
-	}
-	buf_p->vbuf           = buf_cmd;
-
-	msm_jpeg_q_in(&pgmn_dev->input_buf_q, buf_p);
-
-	return 0;
-}
-
-int msm_jpeg_irq(int event, void *context, void *data)
-{
-	struct msm_jpeg_device *pgmn_dev =
-		(struct msm_jpeg_device *) context;
-
-	switch (event) {
-	case MSM_JPEG_EVT_SESSION_DONE:
-		msm_jpeg_framedone_irq(pgmn_dev, data);
-		msm_jpeg_we_pingpong_irq(pgmn_dev, data);
-		break;
-
-	case MSM_JPEG_HW_MASK_COMP_FE:
-		msm_jpeg_fe_pingpong_irq(pgmn_dev, data);
-		break;
-
-	case MSM_JPEG_HW_MASK_COMP_WE:
-		msm_jpeg_we_pingpong_irq(pgmn_dev, data);
-		break;
-
-	case MSM_JPEG_HW_MASK_COMP_RESET_ACK:
-		msm_jpeg_reset_ack_irq(pgmn_dev);
-		break;
-
-	case MSM_JPEG_HW_MASK_COMP_ERR:
-	default:
-		msm_jpeg_err_irq(pgmn_dev, event);
-		break;
-	}
-
-	return 0;
-}
-
-int __msm_jpeg_open(struct msm_jpeg_device *pgmn_dev)
-{
-	int rc;
-
-	mutex_lock(&pgmn_dev->lock);
-	if (pgmn_dev->open_count) {
-		/* only open once */
-		JPEG_PR_ERR("%s:%d] busy\n", __func__, __LINE__);
-		mutex_unlock(&pgmn_dev->lock);
-		return -EBUSY;
-	}
-	pgmn_dev->open_count++;
-	mutex_unlock(&pgmn_dev->lock);
-
-	msm_jpeg_core_irq_install(msm_jpeg_irq);
-	rc = msm_jpeg_platform_init(pgmn_dev->pdev,
-		&pgmn_dev->mem, &pgmn_dev->base,
-		&pgmn_dev->irq, msm_jpeg_core_irq, pgmn_dev);
-	if (rc) {
-		JPEG_PR_ERR("%s:%d] platform_init fail %d\n", __func__,
-			__LINE__, rc);
-		return rc;
-	}
-
-	JPEG_DBG("%s:%d] platform resources - mem %p, base %p, irq %d\n",
-		__func__, __LINE__,
-		pgmn_dev->mem, pgmn_dev->base, pgmn_dev->irq);
-	pgmn_dev->res_size = resource_size(pgmn_dev->mem);
-
-	msm_jpeg_q_cleanup(&pgmn_dev->evt_q);
-	msm_jpeg_q_cleanup(&pgmn_dev->output_rtn_q);
-	msm_jpeg_outbuf_q_cleanup(pgmn_dev, &pgmn_dev->output_buf_q,
-		pgmn_dev->domain_num);
-	msm_jpeg_q_cleanup(&pgmn_dev->input_rtn_q);
-	msm_jpeg_q_cleanup(&pgmn_dev->input_buf_q);
-	msm_jpeg_core_init(pgmn_dev);
-
-	JPEG_DBG("%s:%d] success\n", __func__, __LINE__);
-	return rc;
-}
-
-int __msm_jpeg_release(struct msm_jpeg_device *pgmn_dev)
-{
-	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
-	mutex_lock(&pgmn_dev->lock);
-	if (!pgmn_dev->open_count) {
-		JPEG_PR_ERR(KERN_ERR "%s: not opened\n", __func__);
-		mutex_unlock(&pgmn_dev->lock);
-		return -EINVAL;
-	}
-	pgmn_dev->open_count--;
-	mutex_unlock(&pgmn_dev->lock);
-
-	msm_jpeg_core_release(pgmn_dev, pgmn_dev->domain_num);
-	msm_jpeg_q_cleanup(&pgmn_dev->evt_q);
-	msm_jpeg_q_cleanup(&pgmn_dev->output_rtn_q);
-	msm_jpeg_outbuf_q_cleanup(pgmn_dev, &pgmn_dev->output_buf_q,
-		pgmn_dev->domain_num);
-	msm_jpeg_q_cleanup(&pgmn_dev->input_rtn_q);
-	msm_jpeg_outbuf_q_cleanup(pgmn_dev, &pgmn_dev->input_buf_q,
-		pgmn_dev->domain_num);
-
-	JPEG_DBG("%s:%d]\n", __func__, __LINE__);
-	if (pgmn_dev->open_count)
-		JPEG_PR_ERR(KERN_ERR "%s: multiple opens\n", __func__);
-
-	msm_jpeg_platform_release(pgmn_dev->mem, pgmn_dev->base,
-		pgmn_dev->irq, pgmn_dev);
-
-	JPEG_DBG("%s:%d]\n", __func__, __LINE__);
-	return 0;
-}
-
-int msm_jpeg_ioctl_hw_cmd(struct msm_jpeg_device *pgmn_dev,
-	void * __user arg)
-{
-	struct msm_jpeg_hw_cmd hw_cmd;
-	int is_copy_to_user;
-
-	if (copy_from_user(&hw_cmd, arg, sizeof(struct msm_jpeg_hw_cmd))) {
-		JPEG_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
-		return -EFAULT;
-	}
-
-	is_copy_to_user = msm_jpeg_hw_exec_cmds(&hw_cmd, 1,
-		pgmn_dev->res_size, pgmn_dev->base);
-	JPEG_DBG("%s:%d] type %d, n %d, offset %d, mask %x, data %x,pdata %x\n",
-		__func__, __LINE__, hw_cmd.type, hw_cmd.n, hw_cmd.offset,
-		hw_cmd.mask, hw_cmd.data, (int) hw_cmd.pdata);
-
-	if (is_copy_to_user >= 0) {
-		if (copy_to_user(arg, &hw_cmd, sizeof(hw_cmd))) {
-			JPEG_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
-			return -EFAULT;
-		}
-	}
-
-	return 0;
-}
-
-int msm_jpeg_ioctl_hw_cmds(struct msm_jpeg_device *pgmn_dev,
-	void * __user arg)
-{
-	int is_copy_to_user;
-	int len;
-	uint32_t m;
-	struct msm_jpeg_hw_cmds *hw_cmds_p;
-	struct msm_jpeg_hw_cmd *hw_cmd_p;
-
-	if (copy_from_user(&m, arg, sizeof(m))) {
-		JPEG_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
-		return -EFAULT;
-	}
-
-	len = sizeof(struct msm_jpeg_hw_cmds) +
-		sizeof(struct msm_jpeg_hw_cmd) * (m - 1);
-	hw_cmds_p = kmalloc(len, GFP_KERNEL);
-	if (!hw_cmds_p) {
-		JPEG_PR_ERR("%s:%d] no mem %d\n", __func__, __LINE__, len);
-		return -EFAULT;
-	}
-
-	if (copy_from_user(hw_cmds_p, arg, len)) {
-		JPEG_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
-		kfree(hw_cmds_p);
-		return -EFAULT;
-	}
-
-	hw_cmd_p = (struct msm_jpeg_hw_cmd *) &(hw_cmds_p->hw_cmd);
-
-	is_copy_to_user = msm_jpeg_hw_exec_cmds(hw_cmd_p, m,
-		 pgmn_dev->res_size, pgmn_dev->base);
-
-	if (is_copy_to_user >= 0) {
-		if (copy_to_user(arg, hw_cmds_p, len)) {
-			JPEG_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
-			kfree(hw_cmds_p);
-			return -EFAULT;
-		}
-	}
-	kfree(hw_cmds_p);
-	return 0;
-}
-
-int msm_jpeg_start(struct msm_jpeg_device *pgmn_dev, void * __user arg)
-{
-	struct msm_jpeg_core_buf *buf_out;
-	struct msm_jpeg_core_buf *buf_out_free[2] = {NULL, NULL};
-	int i, rc;
-
-	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
-
-	pgmn_dev->release_buf = 1;
-	for (i = 0; i < 2; i++) {
-		buf_out = msm_jpeg_q_out(&pgmn_dev->input_buf_q);
-
-		if (buf_out) {
-			msm_jpeg_core_fe_buf_update(pgmn_dev, buf_out);
-			kfree(buf_out);
-		} else {
-			JPEG_DBG("%s:%d] no input buffer\n", __func__,
-					__LINE__);
-			break;
-		}
-	}
-
-	for (i = 0; i < 2; i++) {
-		buf_out_free[i] = msm_jpeg_q_out(&pgmn_dev->output_buf_q);
-
-		if (buf_out_free[i]) {
-			msm_jpeg_core_we_buf_update(pgmn_dev, buf_out_free[i]);
-			pgmn_dev->release_buf = 0;
-		} else {
-			JPEG_DBG("%s:%d] no output buffer\n",
-			__func__, __LINE__);
-			break;
-		}
-	}
-
-	for (i = 0; i < 2; i++)
-		kfree(buf_out_free[i]);
-
-	JPEG_DBG_HIGH("%s:%d] START\n", __func__, __LINE__);
-	wmb();
-	rc = msm_jpeg_ioctl_hw_cmds(pgmn_dev, arg);
-	wmb();
-	JPEG_DBG("%s:%d]", __func__, __LINE__);
-	return rc;
-}
-
-int msm_jpeg_ioctl_reset(struct msm_jpeg_device *pgmn_dev,
-	void * __user arg)
-{
-	int rc;
-	struct msm_jpeg_ctrl_cmd ctrl_cmd;
-
-	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
-	if (copy_from_user(&ctrl_cmd, arg, sizeof(ctrl_cmd))) {
-		JPEG_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
-		return -EFAULT;
-	}
-
-	pgmn_dev->op_mode = ctrl_cmd.type;
-
-	rc = msm_jpeg_core_reset(pgmn_dev, pgmn_dev->op_mode, pgmn_dev->base,
-		resource_size(pgmn_dev->mem));
-	return rc;
-}
-
-int msm_jpeg_ioctl_test_dump_region(struct msm_jpeg_device *pgmn_dev,
-	unsigned long arg)
-{
-	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
-	msm_jpeg_io_dump(pgmn_dev->base, JPEG_REG_SIZE);
-	return 0;
-}
-
-long __msm_jpeg_ioctl(struct msm_jpeg_device *pgmn_dev,
-	unsigned int cmd, unsigned long arg)
-{
-	int rc = 0;
-	switch (cmd) {
-	case MSM_JPEG_IOCTL_GET_HW_VERSION:
-		JPEG_DBG("%s:%d] VERSION 1\n", __func__, __LINE__);
-		rc = msm_jpeg_ioctl_hw_cmd(pgmn_dev, (void __user *) arg);
-		break;
-
-	case MSM_JPEG_IOCTL_RESET:
-		rc = msm_jpeg_ioctl_reset(pgmn_dev, (void __user *) arg);
-		break;
-
-	case MSM_JPEG_IOCTL_STOP:
-		rc = msm_jpeg_ioctl_hw_cmds(pgmn_dev, (void __user *) arg);
-		break;
-
-	case MSM_JPEG_IOCTL_START:
-		rc = msm_jpeg_start(pgmn_dev, (void __user *) arg);
-		break;
-
-	case MSM_JPEG_IOCTL_INPUT_BUF_ENQUEUE:
-		rc = msm_jpeg_input_buf_enqueue(pgmn_dev,
-			(void __user *) arg);
-		break;
-
-	case MSM_JPEG_IOCTL_INPUT_GET:
-		rc = msm_jpeg_input_get(pgmn_dev, (void __user *) arg);
-		break;
-
-	case MSM_JPEG_IOCTL_INPUT_GET_UNBLOCK:
-		rc = msm_jpeg_input_get_unblock(pgmn_dev);
-		break;
-
-	case MSM_JPEG_IOCTL_OUTPUT_BUF_ENQUEUE:
-		rc = msm_jpeg_output_buf_enqueue(pgmn_dev,
-			(void __user *) arg);
-		break;
-
-	case MSM_JPEG_IOCTL_OUTPUT_GET:
-		rc = msm_jpeg_output_get(pgmn_dev, (void __user *) arg);
-		break;
-
-	case MSM_JPEG_IOCTL_OUTPUT_GET_UNBLOCK:
-		rc = msm_jpeg_output_get_unblock(pgmn_dev);
-		break;
-
-	case MSM_JPEG_IOCTL_EVT_GET:
-		rc = msm_jpeg_evt_get(pgmn_dev, (void __user *) arg);
-		break;
-
-	case MSM_JPEG_IOCTL_EVT_GET_UNBLOCK:
-		rc = msm_jpeg_evt_get_unblock(pgmn_dev);
-		break;
-
-	case MSM_JPEG_IOCTL_HW_CMD:
-		rc = msm_jpeg_ioctl_hw_cmd(pgmn_dev, (void __user *) arg);
-		break;
-
-	case MSM_JPEG_IOCTL_HW_CMDS:
-		rc = msm_jpeg_ioctl_hw_cmds(pgmn_dev, (void __user *) arg);
-		break;
-
-	case MSM_JPEG_IOCTL_TEST_DUMP_REGION:
-		rc = msm_jpeg_ioctl_test_dump_region(pgmn_dev, arg);
-		break;
-
-	default:
-		JPEG_PR_ERR(KERN_INFO "%s:%d] cmd = %d not supported\n",
-			__func__, __LINE__, _IOC_NR(cmd));
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-static int camera_register_domain(void)
-{
-	struct msm_iova_partition camera_fw_partition = {
-		.start = SZ_128K,
-		.size = SZ_2G - SZ_128K,
-	};
-
-	struct msm_iova_layout camera_fw_layout = {
-		.partitions = &camera_fw_partition,
-		.npartitions = 1,
-		.client_name = "camera_jpeg",
-		.domain_flags = 0,
-	};
-	return msm_register_domain(&camera_fw_layout);
-}
-#endif
-
-int __msm_jpeg_init(struct msm_jpeg_device *pgmn_dev)
-{
-	int rc = 0, i = 0, j = 0;
-	int idx = 0;
-	char *iommu_name[JPEG_DEV_CNT] = {"jpeg_enc0", "jpeg_enc1",
-		"jpeg_dec"};
-
-	mutex_init(&pgmn_dev->lock);
-
-	pr_err("%s:%d] Jpeg Device id %d", __func__, __LINE__,
-		   pgmn_dev->pdev->id);
-	idx = pgmn_dev->pdev->id;
-	pgmn_dev->idx = idx;
-	pgmn_dev->iommu_cnt = 1;
-	pgmn_dev->decode_flag = (idx == JPEG_DEC_ID);
-
-	msm_jpeg_q_init("evt_q", &pgmn_dev->evt_q);
-	msm_jpeg_q_init("output_rtn_q", &pgmn_dev->output_rtn_q);
-	msm_jpeg_q_init("output_buf_q", &pgmn_dev->output_buf_q);
-	msm_jpeg_q_init("input_rtn_q", &pgmn_dev->input_rtn_q);
-	msm_jpeg_q_init("input_buf_q", &pgmn_dev->input_buf_q);
-
-#ifdef CONFIG_MSM_IOMMU
-	j = (pgmn_dev->iommu_cnt <= 1) ? idx : 0;
-	/*get device context for IOMMU*/
-	for (i = 0; i < pgmn_dev->iommu_cnt; i++) {
-		pgmn_dev->iommu_ctx_arr[i] = msm_iommu_get_ctx(iommu_name[j]);
-		JPEG_DBG("%s:%d] name %s", __func__, __LINE__, iommu_name[j]);
-		JPEG_DBG("%s:%d] ctx 0x%x", __func__, __LINE__,
-			(uint32_t)pgmn_dev->iommu_ctx_arr[i]);
-		if (!pgmn_dev->iommu_ctx_arr[i]) {
-			JPEG_PR_ERR("%s: No iommu fw context found\n",
-					__func__);
-			goto error;
-		}
-		j++;
-	}
-	pgmn_dev->domain_num = camera_register_domain();
-	JPEG_DBG("%s:%d] dom_num 0x%x", __func__, __LINE__,
-		pgmn_dev->domain_num);
-	if (pgmn_dev->domain_num < 0) {
-		JPEG_PR_ERR("%s: could not register domain\n", __func__);
-		goto error;
-	}
-	pgmn_dev->domain = msm_get_iommu_domain(pgmn_dev->domain_num);
-	JPEG_DBG("%s:%d] dom 0x%x", __func__, __LINE__,
-					(uint32_t)pgmn_dev->domain);
-	if (!pgmn_dev->domain) {
-		JPEG_PR_ERR("%s: cannot find domain\n", __func__);
-		goto error;
-	}
-#endif
-
-	return rc;
-error:
-	mutex_destroy(&pgmn_dev->lock);
-	return -EFAULT;
-}
-
-int __msm_jpeg_exit(struct msm_jpeg_device *pgmn_dev)
-{
-	mutex_destroy(&pgmn_dev->lock);
-	kfree(pgmn_dev);
-	return 0;
-}
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.h b/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.h
deleted file mode 100644
index 1ac4838..0000000
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-
-
-#ifndef MSM_JPEG_SYNC_H
-#define MSM_JPEG_SYNC_H
-
-#include <linux/fs.h>
-#include <linux/list.h>
-#include <linux/cdev.h>
-#include <linux/platform_device.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-#include "msm_jpeg_hw.h"
-
-#define JPEG_7X 0x1
-#define JPEG_8X60 (0x1 << 1)
-#define JPEG_8960 (0x1 << 2)
-#define JPEG_8974 0x1
-
-struct msm_jpeg_q {
-	char const	*name;
-	struct list_head  q;
-	spinlock_t	lck;
-	wait_queue_head_t wait;
-	int	       unblck;
-};
-
-struct msm_jpeg_q_entry {
-	struct list_head list;
-	void   *data;
-};
-
-struct msm_jpeg_device {
-	struct platform_device *pdev;
-	struct resource        *mem;
-	int                     irq;
-	void                   *base;
-	struct clk *jpeg_clk[5];
-	struct regulator *jpeg_fs;
-	uint32_t hw_version;
-
-	struct device *device;
-	struct cdev   cdev;
-	struct mutex  lock;
-	char	  open_count;
-	uint8_t       op_mode;
-
-	/* event queue including frame done & err indications
-	 */
-	struct msm_jpeg_q evt_q;
-
-	/* output return queue
-	 */
-	struct msm_jpeg_q output_rtn_q;
-
-	/* output buf queue
-	 */
-	struct msm_jpeg_q output_buf_q;
-
-	/* input return queue
-	 */
-	struct msm_jpeg_q input_rtn_q;
-
-	/* input buf queue
-	 */
-	struct msm_jpeg_q input_buf_q;
-
-	struct v4l2_subdev subdev;
-
-	struct class *msm_jpeg_class;
-
-	dev_t msm_jpeg_devno;
-
-	/*iommu domain and context*/
-	int domain_num;
-	int idx;
-	struct iommu_domain *domain;
-	struct device *iommu_ctx_arr[3];
-	int iommu_cnt;
-	int decode_flag;
-	struct ion_client *jpeg_client;
-	void *jpeg_vbif;
-	int release_buf;
-	struct msm_jpeg_hw_pingpong fe_pingpong_buf;
-	struct msm_jpeg_hw_pingpong we_pingpong_buf;
-	int we_pingpong_index;
-	int reset_done_ack;
-	spinlock_t reset_lock;
-	wait_queue_head_t reset_wait;
-	uint32_t res_size;
-};
-
-int __msm_jpeg_open(struct msm_jpeg_device *pgmn_dev);
-int __msm_jpeg_release(struct msm_jpeg_device *pgmn_dev);
-
-long __msm_jpeg_ioctl(struct msm_jpeg_device *pgmn_dev,
-	unsigned int cmd, unsigned long arg);
-
-int __msm_jpeg_init(struct msm_jpeg_device *pgmn_dev);
-int __msm_jpeg_exit(struct msm_jpeg_device *pgmn_dev);
-
-#endif /* MSM_JPEG_SYNC_H */
diff --git a/drivers/media/video/msm/mercury/Makefile b/drivers/media/video/msm/mercury/Makefile
deleted file mode 100644
index ce4c86d..0000000
--- a/drivers/media/video/msm/mercury/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
-EXTRA_CFLAGS += -Idrivers/media/video/msm
-obj-$(CONFIG_MSM_MERCURY) += msm_mercury_dev.o msm_mercury_core.o msm_mercury_hw.o msm_mercury_platform.o msm_mercury_sync.o
diff --git a/drivers/media/video/msm/mercury/msm_mercury_common.h b/drivers/media/video/msm/mercury/msm_mercury_common.h
deleted file mode 100644
index f5939c1..0000000
--- a/drivers/media/video/msm/mercury/msm_mercury_common.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 MSM_MERCURY_COMMON_H
-#define MSM_MERCURY_COMMON_H
-
-#define MSM_MERCURY_DEBUG
-#ifdef MSM_MERCURY_DEBUG
-#define MCR_DBG(fmt, args...) pr_debug(fmt, ##args)
-#else
-#define MCR_DBG(fmt, args...) do { } while (0)
-#endif
-
-#define MCR_PR_ERR   pr_err
-#endif /* MSM_MERCURY_COMMON_H */
diff --git a/drivers/media/video/msm/mercury/msm_mercury_core.c b/drivers/media/video/msm/mercury/msm_mercury_core.c
deleted file mode 100644
index a91c257..0000000
--- a/drivers/media/video/msm/mercury/msm_mercury_core.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/sched.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/clk.h>
-#include <mach/clk.h>
-#include <mach/msm_bus.h>
-#include <mach/msm_bus_board.h>
-#include "msm_mercury_hw.h"
-#include "msm_mercury_core.h"
-#include "msm_mercury_platform.h"
-#include "msm_mercury_common.h"
-
-static int reset_done_ack;
-static spinlock_t reset_lock;
-static wait_queue_head_t reset_wait;
-
-int mercury_core_reset(void)
-{
-	struct clk *clk = NULL;
-
-	/*Resettting MMSS Fabric*/
-
-	clk = clk_get(NULL, "jpegd_clk");
-
-	if (!IS_ERR(clk))
-		clk_enable(clk);
-
-	msm_bus_axi_porthalt(MSM_BUS_MASTER_JPEG_DEC);
-	clk_reset(clk, CLK_RESET_ASSERT);
-
-	/*need to have some delay here, there is no
-	 other way to know if hardware reset is complete*/
-	usleep_range(1000, 1200);
-
-	msm_bus_axi_portunhalt(MSM_BUS_MASTER_JPEG_DEC);
-	clk_reset(clk, CLK_RESET_DEASSERT);
-
-	return 0;
-}
-
-int msm_mercury_core_reset(void)
-{
-	unsigned long flags;
-	int rc = 0;
-	int tm = 500;/*500ms*/
-	MCR_DBG("\n%s\n(%d)%s()\n", __FILE__, __LINE__, __func__);
-
-	spin_lock_irqsave(&reset_lock, flags);
-	reset_done_ack = 0;
-	spin_unlock_irqrestore(&reset_lock, flags);
-
-	msm_mercury_hw_reset();
-	rc = wait_event_interruptible_timeout(reset_wait,
-		reset_done_ack,
-		msecs_to_jiffies(tm));
-
-	if (!reset_done_ack) {
-		MCR_DBG("%s: reset ACK failed %d", __func__, rc);
-		return -EBUSY;
-	}
-
-	MCR_DBG("(%d)%s() reset_done_ack rc %d\n\n", __LINE__, __func__, rc);
-	spin_lock_irqsave(&reset_lock, flags);
-	reset_done_ack = 0;
-	spin_unlock_irqrestore(&reset_lock, flags);
-
-	return 0;
-}
-
-void msm_mercury_core_init(void)
-{
-	init_waitqueue_head(&reset_wait);
-	spin_lock_init(&reset_lock);
-}
-
-static int (*msm_mercury_irq_handler) (int, void *, void *);
-
-irqreturn_t msm_mercury_core_irq(int irq_num, void *context)
-{
-	void *data = NULL;
-	unsigned long flags;
-	uint16_t mcr_rd_irq;
-	uint16_t mcr_wr_irq;
-	uint32_t jpeg_status;
-
-	MCR_DBG("\n(%d)%s() irq_number = %d", __LINE__, __func__, irq_num);
-
-	spin_lock_irqsave(&reset_lock, flags);
-	reset_done_ack = 1;
-	spin_unlock_irqrestore(&reset_lock, flags);
-
-	msm_mercury_hw_irq_get_status(&mcr_rd_irq, &mcr_wr_irq);
-	msm_mercury_hw_get_jpeg_status(&jpeg_status);
-	MCR_DBG("mercury_rd_irq = 0x%08X\n", mcr_rd_irq);
-	MCR_DBG("mercury_wr_irq = 0x%08X\n", mcr_wr_irq);
-	MCR_DBG("jpeg_status = 0x%08X\n", jpeg_status);
-	if (mcr_wr_irq & MSM_MERCURY_HW_IRQ_SW_RESET_ACK) {
-		MCR_DBG("*** SW Reset IRQ received ***\n");
-		wake_up(&reset_wait);
-		msm_mercury_hw_wr_irq_clear(MSM_MERCURY_HW_IRQ_SW_RESET_ACK);
-	}
-	if (mcr_wr_irq & MSM_MERCURY_HW_IRQ_WR_ERR_ACK) {
-		MCR_DBG("   *** Error IRQ received ***\n");
-		msm_mercury_irq_handler(MSM_MERCURY_HW_IRQ_WR_ERR_ACK,
-								context, data);
-	}
-	if (mcr_wr_irq & MSM_MERCURY_HW_IRQ_WR_EOI_ACK) {
-		MCR_DBG("   *** WE_EOI IRQ received ***\n");
-		msm_mercury_irq_handler(MSM_MERCURY_HW_IRQ_WR_EOI_ACK,
-								context, data);
-	}
-	return IRQ_HANDLED;
-}
-
-void msm_mercury_core_irq_install(int (*irq_handler) (int, void *, void *))
-{
-	msm_mercury_irq_handler = irq_handler;
-}
-
-void msm_mercury_core_irq_remove(void)
-{
-	msm_mercury_irq_handler = NULL;
-}
diff --git a/drivers/media/video/msm/mercury/msm_mercury_core.h b/drivers/media/video/msm/mercury/msm_mercury_core.h
deleted file mode 100644
index e374cee..0000000
--- a/drivers/media/video/msm/mercury/msm_mercury_core.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 MSM_MERCURY_CORE_H
-#define MSM_MERCURY_CORE_H
-
-#include <linux/interrupt.h>
-#include "msm_mercury_hw.h"
-
-#define msm_mercury_core_buf msm_mercury_hw_buf
-
-irqreturn_t msm_mercury_core_irq(int irq_num, void *context);
-
-void msm_mercury_core_irq_install(int (*irq_handler) (int, void *, void *));
-void msm_mercury_core_irq_remove(void);
-
-int msm_mercury_core_reset(void);
-void msm_mercury_core_init(void);
-
-#endif /* MSM_MERCURY_CORE_H */
diff --git a/drivers/media/video/msm/mercury/msm_mercury_dev.c b/drivers/media/video/msm/mercury/msm_mercury_dev.c
deleted file mode 100644
index df32b26..0000000
--- a/drivers/media/video/msm/mercury/msm_mercury_dev.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/module.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/device.h>
-#include <linux/uaccess.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-#include <media/msm_mercury.h>
-#include <mach/board.h>
-#include "msm_mercury_sync.h"
-#include "msm_mercury_common.h"
-#include "msm.h"
-
-#define MSM_MERCURY_NAME "mercury"
-
-static int msm_mercury_open(struct inode *inode, struct file *filp)
-{
-	int rc;
-
-	struct msm_mercury_device *pmercury_dev = container_of(inode->i_cdev,
-		struct msm_mercury_device, cdev);
-	filp->private_data = pmercury_dev;
-
-	MCR_DBG("\n---(%d)%s()\n", __LINE__, __func__);
-
-	rc = __msm_mercury_open(pmercury_dev);
-
-	MCR_DBG("%s:%d] %s open_count = %d\n", __func__, __LINE__,
-		filp->f_path.dentry->d_name.name, pmercury_dev->open_count);
-
-	return rc;
-}
-
-static int msm_mercury_release(struct inode *inode, struct file *filp)
-{
-	int rc;
-
-	struct msm_mercury_device *pmercury_dev = filp->private_data;
-
-	MCR_DBG("\n---(%d)%s()\n", __LINE__, __func__);
-
-	rc = __msm_mercury_release(pmercury_dev);
-
-	MCR_DBG("%s:%d] %s open_count = %d\n", __func__, __LINE__,
-		filp->f_path.dentry->d_name.name, pmercury_dev->open_count);
-	return rc;
-}
-
-static long msm_mercury_ioctl(struct file *filp, unsigned int cmd,
-	unsigned long arg) {
-	int rc;
-	struct msm_mercury_device *pmercury_dev = filp->private_data;
-	rc = __msm_mercury_ioctl(pmercury_dev, cmd, arg);
-	return rc;
-}
-
-static const struct file_operations msm_mercury_fops = {
-	.owner     = THIS_MODULE,
-	.open    = msm_mercury_open,
-	.release = msm_mercury_release,
-	.unlocked_ioctl = msm_mercury_ioctl,
-};
-
-static struct class *msm_mercury_class;
-static dev_t msm_mercury_devno;
-static struct msm_mercury_device *msm_mercury_device_p;
-
-int msm_mercury_subdev_init(struct v4l2_subdev *mercury_sd)
-{
-	int rc;
-	struct msm_mercury_device *pgmn_dev =
-		(struct msm_mercury_device *)mercury_sd->host_priv;
-
-	MCR_DBG("%s:%d: mercury_sd=0x%x pgmn_dev=0x%x\n",
-		__func__, __LINE__, (uint32_t)mercury_sd, (uint32_t)pgmn_dev);
-	rc = __msm_mercury_open(pgmn_dev);
-	MCR_DBG("%s:%d: rc=%d\n",
-		__func__, __LINE__, rc);
-	return rc;
-}
-
-static long msm_mercury_subdev_ioctl(struct v4l2_subdev *sd,
-	unsigned int cmd, void *arg)
-{
-	long rc;
-	struct msm_mercury_device *pgmn_dev =
-		(struct msm_mercury_device *)sd->host_priv;
-
-	MCR_DBG("%s: cmd=%d\n", __func__, cmd);
-
-	MCR_DBG("%s: pgmn_dev 0x%x", __func__, (uint32_t)pgmn_dev);
-
-	MCR_DBG("%s: Calling __msm_mercury_ioctl\n", __func__);
-
-	rc = __msm_mercury_ioctl(pgmn_dev, cmd, (unsigned long)arg);
-	pr_debug("%s: X\n", __func__);
-	return rc;
-}
-
-void msm_mercury_subdev_release(struct v4l2_subdev *mercury_sd)
-{
-	int rc;
-	struct msm_mercury_device *pgmn_dev =
-		(struct msm_mercury_device *)mercury_sd->host_priv;
-	MCR_DBG("%s:pgmn_dev=0x%x", __func__, (uint32_t)pgmn_dev);
-	rc = __msm_mercury_release(pgmn_dev);
-	MCR_DBG("%s:rc=%d", __func__, rc);
-}
-
-static const struct v4l2_subdev_core_ops msm_mercury_subdev_core_ops = {
-	.ioctl = msm_mercury_subdev_ioctl,
-};
-
-static const struct v4l2_subdev_ops msm_mercury_subdev_ops = {
-	.core = &msm_mercury_subdev_core_ops,
-};
-
-static int msm_mercury_init(struct platform_device *pdev)
-{
-	int rc = -1;
-	struct device *dev;
-
-	MCR_DBG("%s:\n", __func__);
-	msm_mercury_device_p = __msm_mercury_init(pdev);
-	if (msm_mercury_device_p == NULL) {
-		MCR_PR_ERR("%s: initialization failed\n", __func__);
-		goto fail;
-	}
-
-	v4l2_subdev_init(&msm_mercury_device_p->subdev,
-		&msm_mercury_subdev_ops);
-	v4l2_set_subdev_hostdata(&msm_mercury_device_p->subdev,
-		msm_mercury_device_p);
-	pr_debug("%s: msm_mercury_device_p 0x%x", __func__,
-		(uint32_t)msm_mercury_device_p);
-	MCR_DBG("%s:mercury: platform_set_drvdata\n", __func__);
-	platform_set_drvdata(pdev, &msm_mercury_device_p->subdev);
-
-	rc = alloc_chrdev_region(&msm_mercury_devno, 0, 1, MSM_MERCURY_NAME);
-	if (rc < 0) {
-		MCR_PR_ERR("%s: failed to allocate chrdev\n", __func__);
-		goto fail_1;
-	}
-
-	if (!msm_mercury_class) {
-		msm_mercury_class = class_create(THIS_MODULE, MSM_MERCURY_NAME);
-		if (IS_ERR(msm_mercury_class)) {
-			rc = PTR_ERR(msm_mercury_class);
-			MCR_PR_ERR("%s: create device class failed\n",
-				__func__);
-			goto fail_2;
-		}
-	}
-
-	dev = device_create(msm_mercury_class, NULL,
-		MKDEV(MAJOR(msm_mercury_devno), MINOR(msm_mercury_devno)), NULL,
-		"%s%d", MSM_MERCURY_NAME, 0);
-
-	if (IS_ERR(dev)) {
-		MCR_PR_ERR("%s: error creating device\n", __func__);
-		rc = -ENODEV;
-		goto fail_3;
-	}
-
-	cdev_init(&msm_mercury_device_p->cdev, &msm_mercury_fops);
-	msm_mercury_device_p->cdev.owner = THIS_MODULE;
-	msm_mercury_device_p->cdev.ops   =
-		(const struct file_operations *) &msm_mercury_fops;
-	rc = cdev_add(&msm_mercury_device_p->cdev, msm_mercury_devno, 1);
-	if (rc < 0) {
-		MCR_PR_ERR("%s: error adding cdev\n", __func__);
-		rc = -ENODEV;
-		goto fail_4;
-	}
-
-	MCR_DBG("%s %s: success\n", __func__, MSM_MERCURY_NAME);
-
-	return rc;
-
-fail_4:
-	device_destroy(msm_mercury_class, msm_mercury_devno);
-
-fail_3:
-	class_destroy(msm_mercury_class);
-
-fail_2:
-	unregister_chrdev_region(msm_mercury_devno, 1);
-
-fail_1:
-	__msm_mercury_exit(msm_mercury_device_p);
-
-fail:
-	return rc;
-}
-
-static void msm_mercury_exit(void)
-{
-	cdev_del(&msm_mercury_device_p->cdev);
-	device_destroy(msm_mercury_class, msm_mercury_devno);
-	class_destroy(msm_mercury_class);
-	unregister_chrdev_region(msm_mercury_devno, 1);
-
-	__msm_mercury_exit(msm_mercury_device_p);
-}
-
-static int __msm_mercury_probe(struct platform_device *pdev)
-{
-	return msm_mercury_init(pdev);
-}
-
-static int __msm_mercury_remove(struct platform_device *pdev)
-{
-	msm_mercury_exit();
-	return 0;
-}
-
-static struct platform_driver msm_mercury_driver = {
-	.probe  = __msm_mercury_probe,
-	.remove = __msm_mercury_remove,
-	.driver = {
-		.name = MSM_MERCURY_DRV_NAME,
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init msm_mercury_driver_init(void)
-{
-	int rc;
-	rc = platform_driver_register(&msm_mercury_driver);
-	return rc;
-}
-
-static void __exit msm_mercury_driver_exit(void)
-{
-	platform_driver_unregister(&msm_mercury_driver);
-}
-
-MODULE_DESCRIPTION("msm mercury jpeg driver");
-
-module_init(msm_mercury_driver_init);
-module_exit(msm_mercury_driver_exit);
diff --git a/drivers/media/video/msm/mercury/msm_mercury_hw.c b/drivers/media/video/msm/mercury/msm_mercury_hw.c
deleted file mode 100644
index 7bc4abe..0000000
--- a/drivers/media/video/msm/mercury/msm_mercury_hw.c
+++ /dev/null
@@ -1,361 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/delay.h>
-#include <linux/io.h>
-#include "msm_mercury_hw.h"
-#include "msm_mercury_common.h"
-#include "msm_mercury_hw_reg.h"
-#include "msm_mercury_macros.h"
-
-static void *mercury_region_base;
-static uint32_t mercury_region_size;
-
-
-void msm_mercury_hw_write(struct msm_mercury_hw_cmd *hw_cmd_p)
-{
-	uint32_t *paddr;
-	uint32_t old_data, new_data;
-
-	paddr = mercury_region_base + hw_cmd_p->offset;
-
-	if (hw_cmd_p->mask == 0xffffffff) {
-		old_data = 0;
-	} else {
-		old_data = readl_relaxed(paddr);
-		old_data &= ~hw_cmd_p->mask;
-	}
-
-	new_data = hw_cmd_p->data & hw_cmd_p->mask;
-	new_data |= old_data;
-	writel_relaxed(new_data, paddr);
-}
-
-uint32_t msm_mercury_hw_read(struct msm_mercury_hw_cmd *hw_cmd_p)
-{
-	uint32_t *paddr;
-	uint32_t data;
-
-	paddr = mercury_region_base + hw_cmd_p->offset;
-
-	data = readl_relaxed(paddr);
-	data &= hw_cmd_p->mask;
-
-	MCR_DBG("MERCURY_READ: offset=0x%04X data=0x%08X\n",
-		hw_cmd_p->offset, data);
-
-	return data;
-}
-
-void msm_mercury_hw_start_decode(void)
-{
-	struct msm_mercury_hw_cmd hw_cmd;
-
-	mercury_kread(JPEG_STATUS);
-	mercury_kread(RTDMA_JPEG_RD_STA_ACK);
-	mercury_kread(RTDMA_JPEG_WR_STA_ACK);
-	mercury_kread(RTDMA_JPEG_RD_BUF_Y_PNTR);
-	mercury_kread(RTDMA_JPEG_WR_BUF_Y_PNTR);
-	mercury_kread(RTDMA_JPEG_WR_BUF_U_PNTR);
-	mercury_kwrite(RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO, (7<<2));
-	return;
-}
-
-void msm_mercury_hw_bitstream_buf_cfg(uint32_t bitstream_buf_addr)
-{
-	struct msm_mercury_hw_cmd hw_cmd;
-
-	mercury_kwrite(RTDMA_JPEG_RD_BUF_Y_PNTR, bitstream_buf_addr);
-	return;
-}
-
-
-void msm_mercury_hw_output_y_buf_cfg(uint32_t y_buf_addr)
-{
-	struct msm_mercury_hw_cmd hw_cmd;
-
-	mercury_kwrite(RTDMA_JPEG_WR_BUF_Y_PNTR, y_buf_addr);
-	return;
-}
-
-void msm_mercury_hw_output_u_buf_cfg(uint32_t u_buf_addr)
-{
-	struct msm_mercury_hw_cmd hw_cmd;
-
-	mercury_kwrite(RTDMA_JPEG_WR_BUF_U_PNTR, u_buf_addr);
-	return;
-}
-
-void msm_mercury_hw_output_v_buf_cfg(uint32_t v_buf_addr)
-{
-	struct msm_mercury_hw_cmd hw_cmd;
-
-	mercury_kwrite(RTDMA_JPEG_WR_BUF_V_PNTR, v_buf_addr);
-	return;
-}
-
-int msm_mercury_hw_wait(struct msm_mercury_hw_cmd *hw_cmd_p, int m_us)
-{
-	int tm = hw_cmd_p->n;
-	uint32_t data;
-	uint32_t wait_data = hw_cmd_p->data & hw_cmd_p->mask;
-
-	data = msm_mercury_hw_read(hw_cmd_p);
-	if (data != wait_data) {
-		while (tm) {
-			udelay(m_us);
-			data = msm_mercury_hw_read(hw_cmd_p);
-			if (data == wait_data)
-				break;
-			tm--;
-		}
-	}
-	hw_cmd_p->data = data;
-	return tm;
-}
-
-void msm_mercury_hw_irq_get_status(uint16_t *rd_irq, uint16_t *wr_irq)
-{
-	struct msm_mercury_hw_cmd hw_cmd;
-	rmb();
-	mercury_kread(RTDMA_JPEG_RD_STA_ACK);
-	*rd_irq = hw_cmd.data;
-
-	mercury_kread(RTDMA_JPEG_WR_STA_ACK);
-	*wr_irq = hw_cmd.data;
-	rmb();
-}
-
-void msm_mercury_hw_get_jpeg_status(uint32_t *jpeg_status)
-{
-	struct msm_mercury_hw_cmd hw_cmd;
-
-	rmb();
-	mercury_kread(JPEG_STATUS);
-	*jpeg_status = hw_cmd.data;
-	rmb();
-}
-
-uint32_t msm_mercury_get_restartInterval(void)
-{
-	struct msm_mercury_hw_cmd hw_cmd;
-
-	rmb();
-	mercury_kread(JPEG_DRI);
-	rmb();
-	return hw_cmd.data;
-
-}
-
-void msm_mercury_hw_rd_irq_clear(uint32_t val)
-{
-	struct msm_mercury_hw_cmd hw_cmd;
-	mercury_kwrite(RTDMA_JPEG_RD_STA_ACK, val);
-}
-
-void msm_mercury_hw_wr_irq_clear(uint32_t val)
-{
-	struct msm_mercury_hw_cmd hw_cmd;
-
-	mercury_kwrite(RTDMA_JPEG_WR_STA_ACK, val);
-}
-
-void msm_mercury_hw_set_rd_irq_mask(uint32_t val)
-{
-	struct msm_mercury_hw_cmd hw_cmd;
-
-	mercury_kwrite(RTDMA_JPEG_RD_INT_EN, val);
-}
-
-void msm_mercury_hw_set_wr_irq_mask(uint32_t val)
-{
-	struct msm_mercury_hw_cmd hw_cmd;
-
-	mercury_kwrite(RTDMA_JPEG_WR_INT_EN, val);
-}
-
-void msm_mercury_set_jpeg_ctl_common(uint32_t val)
-{
-	struct msm_mercury_hw_cmd hw_cmd;
-
-	mercury_kwrite(JPEG_CTRL_COMMON, val);
-}
-
-void msm_mercury_hw_reset(void)
-{
-	uint32_t val;
-	struct msm_mercury_hw_cmd hw_cmd;
-
-	wmb();
-	/* disable all interrupts*/
-	mercury_kwrite(RTDMA_JPEG_RD_INT_EN, 0);
-
-	mercury_kwrite(RTDMA_JPEG_WR_INT_EN, 0);
-
-	/* clear pending interrupts*/
-	val = 0;
-	MEM_OUTF2(&val, RTDMA_JPEG_WR_STA_ACK,
-		SW_RESET_ABORT_RDY_ACK,
-		ERR_ACK, 1, 1);
-	MEM_OUTF2(&val, RTDMA_JPEG_WR_STA_ACK, EOF_ACK, SOF_ACK, 1, 1);
-	mercury_kwrite(RTDMA_JPEG_WR_STA_ACK, val);
-
-	val = 0;
-	MEM_OUTF2(&val, RTDMA_JPEG_RD_STA_ACK, EOF_ACK, SOF_ACK, 1, 1);
-	mercury_kwrite(RTDMA_JPEG_RD_STA_ACK, val);
-
-	/* enable SWResetAbortRdyInt for core reset*/
-	val = 0;
-	MEM_OUTF(&val, RTDMA_JPEG_WR_INT_EN, SW_RESET_ABORT_RDY_EN, 1);
-	mercury_kwrite(RTDMA_JPEG_WR_INT_EN, val);
-
-	/* Reset Core from MMSS Fabric*/
-	mercury_core_reset();
-
-	/* disable all interrupts*/
-	mercury_kwrite(RTDMA_JPEG_WR_INT_EN, 0);
-
-	/* clear pending interrupts*/
-	val = 0;
-	MEM_OUTF2(&val, RTDMA_JPEG_WR_STA_ACK,
-		SW_RESET_ABORT_RDY_ACK,
-		ERR_ACK, 1, 1);
-	MEM_OUTF2(&val, RTDMA_JPEG_WR_STA_ACK, EOF_ACK, SOF_ACK, 1, 1);
-	mercury_kwrite(RTDMA_JPEG_WR_STA_ACK, val);
-
-	val = 0;
-	MEM_OUTF2(&val, RTDMA_JPEG_RD_STA_ACK, EOF_ACK, SOF_ACK, 1, 1);
-	mercury_kwrite(RTDMA_JPEG_RD_STA_ACK, val);
-
-	/* enable neccessary interrupt source*/
-	val = 0;
-	MEM_OUTF2(&val, RTDMA_JPEG_WR_INT_EN, EOF_EN, ERR_EN, 1, 1);
-	MEM_OUTF(&val, RTDMA_JPEG_WR_INT_EN, SW_RESET_ABORT_RDY_EN, 1);
-	mercury_kwrite(RTDMA_JPEG_WR_INT_EN, val);
-
-	wmb();
-
-}
-
-void msm_mercury_hw_init(void *base, int size)
-{
-	mercury_region_base = base;
-	mercury_region_size = size;
-}
-
-
-void msm_mercury_hw_delay(struct msm_mercury_hw_cmd *hw_cmd_p, int m_us)
-{
-	int tm = hw_cmd_p->n;
-	while (tm) {
-		udelay(m_us);
-		tm--;
-	}
-}
-
-int msm_mercury_hw_exec_cmds(struct msm_mercury_hw_cmd *hw_cmd_p, int m_cmds)
-{
-	int is_copy_to_user = -1;
-	uint32_t data;
-	if (m_cmds > 1)
-		MCR_DBG("m_cmds = %d\n", m_cmds);
-
-	while (m_cmds--) {
-		if (hw_cmd_p->offset > mercury_region_size) {
-			MCR_PR_ERR("%s:%d] %d exceed hw region %d\n",
-					__func__, __LINE__, hw_cmd_p->offset,
-					mercury_region_size);
-			return -EFAULT;
-		}
-
-		switch (hw_cmd_p->type) {
-		case MSM_MERCURY_HW_CMD_TYPE_READ:
-			hw_cmd_p->data = msm_mercury_hw_read(hw_cmd_p);
-			is_copy_to_user = 1;
-			break;
-
-		case MSM_MERCURY_HW_CMD_TYPE_WRITE:
-			msm_mercury_hw_write(hw_cmd_p);
-			break;
-
-		case MSM_MERCURY_HW_CMD_TYPE_WRITE_OR:
-			data = msm_mercury_hw_read(hw_cmd_p);
-			hw_cmd_p->data = (hw_cmd_p->data & hw_cmd_p->mask) |
-				data;
-			msm_mercury_hw_write(hw_cmd_p);
-			break;
-
-		case MSM_MERCURY_HW_CMD_TYPE_UWAIT:
-			msm_mercury_hw_wait(hw_cmd_p, 1);
-			break;
-
-		case MSM_MERCURY_HW_CMD_TYPE_MWAIT:
-			msm_mercury_hw_wait(hw_cmd_p, 1000);
-			break;
-
-		case MSM_MERCURY_HW_CMD_TYPE_UDELAY:
-			msm_mercury_hw_delay(hw_cmd_p, 1);
-			break;
-
-		case MSM_MERCURY_HW_CMD_TYPE_MDELAY:
-			msm_mercury_hw_delay(hw_cmd_p, 1000);
-			break;
-
-		default:
-			MCR_DBG("wrong hw command type\n");
-			break;
-		}
-
-		hw_cmd_p++;
-	}
-	return is_copy_to_user;
-}
-
-void msm_mercury_hw_region_dump(int size)
-{
-	uint32_t *p;
-	uint8_t *p8;
-
-	MCR_DBG("(%d)%s()\n", __LINE__, __func__);
-	if (size > mercury_region_size)
-		MCR_DBG("%s:%d] wrong region dump size\n",
-			__func__, __LINE__);
-
-	p = (uint32_t *) mercury_region_base;
-	while (size >= 16) {
-		MCR_DBG("0x%08X] %08X %08X %08X %08X\n",
-			mercury_region_size - size,
-			readl_relaxed(p), readl_relaxed(p+1),
-			readl_relaxed(p+2), readl_relaxed(p+3));
-		p += 4;
-		size -= 16;
-	}
-
-	if (size > 0) {
-		uint32_t d;
-		MCR_DBG("0x%08X] ", mercury_region_size - size);
-		while (size >= 4) {
-			MCR_DBG("%08X ", readl_relaxed(p++));
-			size -= 4;
-		}
-
-		d = readl_relaxed(p);
-		p8 = (uint8_t *) &d;
-		while (size) {
-			MCR_DBG("%02X", *p8++);
-			size--;
-		}
-
-		MCR_DBG("\n");
-	}
-}
diff --git a/drivers/media/video/msm/mercury/msm_mercury_hw.h b/drivers/media/video/msm/mercury/msm_mercury_hw.h
deleted file mode 100644
index f6e3e49..0000000
--- a/drivers/media/video/msm/mercury/msm_mercury_hw.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 MSM_MERCURY_HW_H
-#define MSM_MERCURY_HW_H
-
-#include <media/msm_mercury.h>
-
-/*number of pel per block (horiz/vert)*/
-#define JPEGDEC_BLOCK_SIZE                 (8)
-/* Hardware alignment*/
-#define JPEGDEC_HW_ALIGN                   (8)
-#define JPEGDEC_HW_SAMPLING_RATIO_MAX      (4)
-
-#define MSM_MERCURY_HW_IRQ_SW_RESET_ACK    (1<<3)
-#define MSM_MERCURY_HW_IRQ_WR_ERR_ACK      (1<<2)
-#define MSM_MERCURY_HW_IRQ_WR_EOI_ACK      (1<<1)
-#define MSM_MERCURY_HW_IRQ_WR_SOF_ACK      (1<<0)
-
-#define MSM_MERCURY_HW_IRQ_RD_EOF_ACK      (1<<1)
-#define MSM_MERCURY_HW_IRQ_RD_SOF_ACK      (1<<0)
-
-extern int mercury_core_reset(void);
-
-struct msm_mercury_hw_buf {
-		struct msm_mercury_buf vbuf;
-		struct file  *file;
-		uint32_t framedone_len;
-		uint32_t y_buffer_addr;
-		uint32_t y_len;
-		uint32_t cbcr_buffer_addr;
-		uint32_t cbcr_len;
-		uint32_t num_of_mcu_rows;
-		struct msm_mapped_buffer *msm_buffer;
-		int *subsystem_id;
-		struct ion_handle *handle;
-};
-
-
-void msm_mercury_hw_reset(void);
-void msm_mercury_hw_init(void *base, int size);
-void msm_mercury_hw_rd_irq_clear(uint32_t val);
-void msm_mercury_hw_wr_irq_clear(uint32_t val);
-
-uint32_t msm_mercury_hw_read(struct msm_mercury_hw_cmd *hw_cmd_p);
-void msm_mercury_hw_write(struct msm_mercury_hw_cmd *hw_cmd_p);
-int msm_mercury_hw_wait(struct msm_mercury_hw_cmd *hw_cmd_p, int m_us);
-void msm_mercury_hw_delay(struct msm_mercury_hw_cmd *hw_cmd_p, int m_us);
-int msm_mercury_hw_exec_cmds(struct msm_mercury_hw_cmd *hw_cmd_p, int m_cmds);
-void msm_mercury_hw_region_dump(int size);
-
-
-void msm_mercury_hw_irq_get_status(uint16_t *rd_irq, uint16_t *wr_irq);
-void msm_mercury_hw_start_decode(void);
-void msm_mercury_hw_get_jpeg_status(uint32_t *jpeg_status);
-void msm_mercury_hw_output_y_buf_cfg(uint32_t y_buf_addr);
-void msm_mercury_hw_output_u_buf_cfg(uint32_t u_buf_addr);
-void msm_mercury_hw_output_v_buf_cfg(uint32_t v_buf_addr);
-void msm_mercury_hw_bitstream_buf_cfg(uint32_t bitstream_buf_addr);
-
-#endif /* MSM_MERCURY_HW_H */
diff --git a/drivers/media/video/msm/mercury/msm_mercury_hw_reg.h b/drivers/media/video/msm/mercury/msm_mercury_hw_reg.h
deleted file mode 100644
index 671bc66..0000000
--- a/drivers/media/video/msm/mercury/msm_mercury_hw_reg.h
+++ /dev/null
@@ -1,715 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 MSM_MERCURY_HW_REG_H
-#define MSM_MERCURY_HW_REG_H
-
-
-#define JPEGD_BASE  0x00000000
-
-/* Register ADDR, RMSK, and SHFT*/
-/* RW */
-#define JPEG_CTRL_COMMON                        JPEG_CTRL_COMMON
-#define HWIO_JPEG_CTRL_COMMON_ADDR            (JPEGD_BASE+0x00000000)
-#define HWIO_JPEG_CTRL_COMMON__POR                    0x00000000
-#define HWIO_JPEG_CTRL_COMMON__RMSK                   0x0000001F
-#define HWIO_JPEG_CTRL_COMMON__SHFT                            0
-/* Register Field FMSK and SHFT*/
-#define HWIO_JPEG_CTRL_COMMON__JPEG_CTRL_COMMON_ZZ_OVERRIDE_EN__BMSK 0x00000010
-#define HWIO_JPEG_CTRL_COMMON__JPEG_CTRL_COMMON_ZZ_OVERRIDE_EN__SHFT          4
-#define HWIO_JPEG_CTRL_COMMON__JPEG_CTRL_COMMON_MODE__BMSK           0x0000000F
-#define HWIO_JPEG_CTRL_COMMON__JPEG_CTRL_COMMON_MODE__SHFT                    0
-
-/* Register Field FMSK and SHFT*/
-/* RW */
-#define JPEG_CTRL_ENCODE                     JPEG_CTRL_ENCODE
-#define HWIO_JPEG_CTRL_ENCODE_ADDR        (JPEGD_BASE+0x00000008)
-#define HWIO_JPEG_CTRL_ENCODE__POR                 0x00000000
-#define HWIO_JPEG_CTRL_ENCODE__RMSK                0x00000010
-#define HWIO_JPEG_CTRL_ENCODE__SHFT                         4
-/* Register Element MIN and MAX*/
-#define HWIO_JPEG_CTRL_ENCODE___S                           4
-
-/* Register Field FMSK and SHFT*/
-#define HWIO_JPEG_CTRL_ENCODE__JPEG_CTRL_ENCODE_EOI_MARKER_EN__BMSK  0x00000010
-#define HWIO_JPEG_CTRL_ENCODE__JPEG_CTRL_ENCODE_EOI_MARKER_EN__SHFT           4
-
-/* Register Field FMSK and SHFT*/
-#define JPEG_STATUS                        JPEG_STATUS
-#define HWIO_JPEG_STATUS_ADDR        (JPEGD_BASE+0x00000010)
-#define HWIO_JPEG_STATUS__POR               0x00000000
-#define HWIO_JPEG_STATUS__RMSK              0x00003FF0
-#define HWIO_JPEG_STATUS__SHFT                       4
-/* Register Element MIN and MAX*/
-#define HWIO_JPEG_STATUS___S                         4
-
-/* Register Field FMSK and SHFT*/
-#define HWIO_JPEG_STATUS__JPEG_STATUS_REGISTER_TIMEOUT__BMSK       0x00002000
-#define HWIO_JPEG_STATUS__JPEG_STATUS_REGISTER_TIMEOUT__SHFT               13
-#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_EOI__BMSK               0x00001000
-#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_EOI__SHFT                       12
-#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_UNESCAPED_FF__BMSK  0x00000800
-#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_UNESCAPED_FF__SHFT          11
-#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_INV_HUFFCODE__BMSK  0x00000400
-#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_INV_HUFFCODE__SHFT          10
-#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_INV_MARKER__BMSK    0x00000200
-#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_INV_MARKER__SHFT             9
-#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_RSTRT_SEQ__BMSK     0x00000100
-#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_RSTRT_SEQ__SHFT              8
-#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_RSTRT_OVRFLW__BMSK  0x00000080
-#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_RSTRT_OVRFLW__SHFT           7
-#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_RSTRT_UNDFLW__BMSK  0x00000040
-#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_RSTRT_UNDFLW__SHFT           6
-#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_SCAN_OVRFLW__BMSK   0x00000020
-#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_SCAN_OVRFLW__SHFT            5
-#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_SCAN_UNDFLW__BMSK   0x00000010
-#define HWIO_JPEG_STATUS__JPEG_STATUS_DHDQ_ERR_SCAN_UNDFLW__SHFT            4
-
-/* Register ADDR, RMSK, and SHFT*/
-/* R */
-#define JPEG_SOF_REG_0                               JPEG_SOF_REG_0
-#define HWIO_JPEG_SOF_REG_0_ADDR  /* RW */               (JPEGD_BASE+0x00000014)
-#define HWIO_JPEG_SOF_REG_0__POR                         0x00000000
-#define HWIO_JPEG_SOF_REG_0__RMSK                        0x000000FF
-#define HWIO_JPEG_SOF_REG_0__SHFT                                 0
-/* Register Field FMSK and SHFT*/
-#define HWIO_JPEG_SOF_REG_0__JPEG_SOF_REG_0_NF__BMSK     0x000000FF
-#define HWIO_JPEG_SOF_REG_0__JPEG_SOF_REG_0_NF__SHFT              0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define JPEG_SOF_REG_1                               JPEG_SOF_REG_1
-#define HWIO_JPEG_SOF_REG_1_ADDR  /* RW */               (JPEGD_BASE+0x00000018)
-#define HWIO_JPEG_SOF_REG_1__POR                         0x00000000
-#define HWIO_JPEG_SOF_REG_1__RMSK                        0x00FFFFFF
-#define HWIO_JPEG_SOF_REG_1__SHFT                                 0
-/* Register Field FMSK and SHFT*/
-#define HWIO_JPEG_SOF_REG_1__JPEG_SOF_REG_1_C__BMSK      0x00FF0000
-#define HWIO_JPEG_SOF_REG_1__JPEG_SOF_REG_1_C__SHFT              16
-#define HWIO_JPEG_SOF_REG_1__JPEG_SOF_REG_1_H__BMSK      0x0000F000
-#define HWIO_JPEG_SOF_REG_1__JPEG_SOF_REG_1_H__SHFT              12
-#define HWIO_JPEG_SOF_REG_1__JPEG_SOF_REG_1_V__BMSK      0x00000F00
-#define HWIO_JPEG_SOF_REG_1__JPEG_SOF_REG_1_V__SHFT               8
-#define HWIO_JPEG_SOF_REG_1__JPEG_SOF_REG_1_TQ__BMSK     0x000000FF
-#define HWIO_JPEG_SOF_REG_1__JPEG_SOF_REG_1_TQ__SHFT              0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define JPEG_SOF_REG_2                               JPEG_SOF_REG_2
-#define HWIO_JPEG_SOF_REG_2_ADDR  /* RW */               (JPEGD_BASE+0x0000001C)
-#define HWIO_JPEG_SOF_REG_2__POR                         0x00000000
-#define HWIO_JPEG_SOF_REG_2__RMSK                        0xFFFFFFFF
-#define HWIO_JPEG_SOF_REG_2__SHFT                                 0
-/* Register Field FMSK and SHFT*/
-#define HWIO_JPEG_SOF_REG_2__JPEG_SOF_REG_2_Y__BMSK      0xFFFF0000
-#define HWIO_JPEG_SOF_REG_2__JPEG_SOF_REG_2_Y__SHFT              16
-#define HWIO_JPEG_SOF_REG_2__JPEG_SOF_REG_2_X__BMSK      0x0000FFFF
-#define HWIO_JPEG_SOF_REG_2__JPEG_SOF_REG_2_X__SHFT               0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define JPEG_SOS_REG_0                               JPEG_SOS_REG_0
-#define HWIO_JPEG_SOS_REG_0_ADDR  /* RW */               (JPEGD_BASE+0x00000020)
-#define HWIO_JPEG_SOS_REG_0__POR                         0x00000000
-#define HWIO_JPEG_SOS_REG_0__RMSK                        0xFF000000
-#define HWIO_JPEG_SOS_REG_0__SHFT                                24
-/*Register Element MIN and MAX*/
-#define HWIO_JPEG_SOS_REG_0___S                                  24
-#define HWIO_JPEG_SOS_REG_0___S                                  24
-#define HWIO_JPEG_SOS_REG_0___S                                  24
-#define HWIO_JPEG_SOS_REG_0___S                                  24
-/* Register Field FMSK and SHFT*/
-#define HWIO_JPEG_SOS_REG_0__JPEG_SOS_REG_0_NS__BMSK       0xFF000000
-#define HWIO_JPEG_SOS_REG_0__JPEG_SOS_REG_0_NS__SHFT               24
-
-/* Register ADDR, RMSK, and SHFT*/
-#define JPEG_SOS_REG_1                                   JPEG_SOS_REG_1
-#define HWIO_JPEG_SOS_REG_1_ADDR  /* RW */              (JPEGD_BASE+0x00000024)
-#define HWIO_JPEG_SOS_REG_1__POR                        0x00000000
-#define HWIO_JPEG_SOS_REG_1__RMSK                       0x0000FFFF
-#define HWIO_JPEG_SOS_REG_1__SHFT                                0
-/* Register Field FMSK and SHFT*/
-#define HWIO_JPEG_SOS_REG_1__JPEG_SOS_REG_1_CS__BMSK    0x0000FF00
-#define HWIO_JPEG_SOS_REG_1__JPEG_SOS_REG_1_CS__SHFT             8
-#define HWIO_JPEG_SOS_REG_1__JPEG_SOS_REG_1_TD__BMSK    0x000000F0
-#define HWIO_JPEG_SOS_REG_1__JPEG_SOS_REG_1_TD__SHFT             4
-#define HWIO_JPEG_SOS_REG_1__JPEG_SOS_REG_1_TA__BMSK    0x0000000F
-#define HWIO_JPEG_SOS_REG_1__JPEG_SOS_REG_1_TA__SHFT             0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define JPEG_QT_IDX                                       JPEG_QT_IDX
-#define HWIO_JPEG_QT_IDX_ADDR       (JPEGD_BASE+0x00000030)
-#define HWIO_JPEG_QT_IDX__POR                              0x00000000
-#define HWIO_JPEG_QT_IDX__RMSK                             0x0000FFFF
-#define HWIO_JPEG_QT_IDX__SHFT                                      0
-/* Register Field FMSK and SHFT*/
-#define HWIO_JPEG_QT_IDX__JPEG_QT_IDX_TABLE_1__BMSK        0x0000FF00
-#define HWIO_JPEG_QT_IDX__JPEG_QT_IDX_TABLE_1__SHFT                  8
-#define HWIO_JPEG_QT_IDX__JPEG_QT_IDX_TABLE_0__BMSK         0x000000FF
-#define HWIO_JPEG_QT_IDX__JPEG_QT_IDX_TABLE_0__SHFT                  0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define JPEG_DQT                                        JPEG_DQT
-#define HWIO_JPEG_DQT_ADDR  /* RW */                    (JPEGD_BASE+0x00000034)
-#define HWIO_JPEG_DQT__POR                              0x00000000
-#define HWIO_JPEG_DQT__RMSK                             0x0F00FFFF
-#define HWIO_JPEG_DQT__SHFT                             0
-/* Register Field FMSK and SHFT*/
-#define HWIO_JPEG_DQT__JPEG_DQT_TQ__BMSK                0x0F000000
-#define HWIO_JPEG_DQT__JPEG_DQT_TQ__SHFT                24
-#define HWIO_JPEG_DQT__JPEG_DQT_QK__BMSK                0x0000FFFF
-#define HWIO_JPEG_DQT__JPEG_DQT_QK__SHFT                0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define JPEG_DRI                                JPEG_DRI
-#define HWIO_JPEG_DRI_ADDR  /* RW */            (JPEGD_BASE+0x00000040)
-#define HWIO_JPEG_DRI__POR                      0x00000000
-#define HWIO_JPEG_DRI__RMSK                     0x0000FFFF
-#define HWIO_JPEG_DRI__SHFT                              0
-/* Register Field FMSK and SHFT*/
-#define HWIO_JPEG_DRI__JPEG_DRI_RI__BMSK        0x0000FFFF
-#define HWIO_JPEG_DRI__JPEG_DRI_RI__SHFT                 0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define JPEG_DHT_REG_0                               JPEG_DHT_REG_0
-#define HWIO_JPEG_DHT_REG_0_ADDR  /* RW */               (JPEGD_BASE+0x00000050)
-#define HWIO_JPEG_DHT_REG_0__POR                         0x00000000
-#define HWIO_JPEG_DHT_REG_0__RMSK                        0x000000FF
-#define HWIO_JPEG_DHT_REG_0__SHFT                                 0
-/* Register Field FMSK and SHFT*/
-#define HWIO_JPEG_DHT_REG_0__JPEG_DHT_REG_0_TH__BMSK     0x000000F0
-#define HWIO_JPEG_DHT_REG_0__JPEG_DHT_REG_0_TH__SHFT              4
-#define HWIO_JPEG_DHT_REG_0__JPEG_DHT_REG_0_TC__BMSK     0x0000000F
-#define HWIO_JPEG_DHT_REG_0__JPEG_DHT_REG_0_TC__SHFT              0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define JPEG_DHT_IDX                                        JPEG_DHT_IDX
-#define HWIO_JPEG_DHT_IDX_ADDR  /* RW */      (JPEGD_BASE+0x00000054)
-#define HWIO_JPEG_DHT_IDX__POR                                0x00000000
-#define HWIO_JPEG_DHT_IDX__RMSK                               0x00000FFF
-#define HWIO_JPEG_DHT_IDX__SHFT                                        0
-/* Register Field FMSK and SHFT*/
-#define HWIO_JPEG_DHT_IDX__JPEG_DHT_IDX_CCC_MAX__BMSK         0x00000F00
-#define HWIO_JPEG_DHT_IDX__JPEG_DHT_IDX_CCC_MAX__SHFT                  8
-#define HWIO_JPEG_DHT_IDX__JPEG_DHT_IDX_VIJ__BMSK             0x000000FF
-#define HWIO_JPEG_DHT_IDX__JPEG_DHT_IDX_VIJ__SHFT                      0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define JPEG_DHT_REG_1                          JPEG_DHT_REG_1
-#define HWIO_JPEG_DHT_REG_1_ADDR  /* RW */          (JPEGD_BASE+0x00000058)
-#define HWIO_JPEG_DHT_REG_1__POR                    0x00000000
-#define HWIO_JPEG_DHT_REG_1__RMSK                   0xFFFFFFFF
-#define HWIO_JPEG_DHT_REG_1__SHFT                            0
-/* Register Field FMSK and SHFT*/
-#define HWIO_JPEG_DHT_REG_1__JPEG_DHT_REG_1_VIJ_0__BMSK       0xFF000000
-#define HWIO_JPEG_DHT_REG_1__JPEG_DHT_REG_1_VIJ_0__SHFT               24
-#define HWIO_JPEG_DHT_REG_1__JPEG_DHT_REG_1_VIJ_1__BMSK       0x00FF0000
-#define HWIO_JPEG_DHT_REG_1__JPEG_DHT_REG_1_VIJ_1__SHFT               16
-#define HWIO_JPEG_DHT_REG_1__JPEG_DHT_REG_1_VIJ_2__BMSK       0x0000FF00
-#define HWIO_JPEG_DHT_REG_1__JPEG_DHT_REG_1_VIJ_2__SHFT                8
-#define HWIO_JPEG_DHT_REG_1__JPEG_DHT_REG_1_VIJ_3__BMSK       0x000000FF
-#define HWIO_JPEG_DHT_REG_1__JPEG_DHT_REG_1_VIJ_3__SHFT                0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define JPEG_DHT_CCC_MAX                          JPEG_DHT_CCC_MAX
-#define HWIO_JPEG_DHT_CCC_MAX_ADDR  /* RW */            (JPEGD_BASE+0x0000005C)
-#define HWIO_JPEG_DHT_CCC_MAX__POR                      0x00000000
-#define HWIO_JPEG_DHT_CCC_MAX__RMSK                     0xFFFFFFFF
-#define HWIO_JPEG_DHT_CCC_MAX__SHFT                              0
-/* Register Field FMSK and SHFT*/
-#define HWIO_JPEG_DHT_CCC_MAX__JPEG_DHT_CCC_MAX_MAX__BMSK    0xFFFF0000
-#define HWIO_JPEG_DHT_CCC_MAX__JPEG_DHT_CCC_MAX_MAX__SHFT            16
-#define HWIO_JPEG_DHT_CCC_MAX__JPEG_DHT_CCC_MAX_CCC__BMSK    0x0000FFFF
-#define HWIO_JPEG_DHT_CCC_MAX__JPEG_DHT_CCC_MAX_CCC__SHFT             0
-/* Register Field FMSK and SHFT*/
-#define HWIO_JPEG_DHT_CCC_MAX__JPEG_DHT_CCC_MAX_MAX__BMSK    0xFFFF0000
-#define HWIO_JPEG_DHT_CCC_MAX__JPEG_DHT_CCC_MAX_MAX__SHFT            16
-#define HWIO_JPEG_DHT_CCC_MAX__JPEG_DHT_CCC_MAX_CCC__BMSK    0x0000FFFF
-#define HWIO_JPEG_DHT_CCC_MAX__JPEG_DHT_CCC_MAX_CCC__SHFT             0
-#define HWIO_JPEG_DHT_CCC_MAX__JPEG_DHT_LI__BMSK       0x000000FF
-#define HWIO_JPEG_DHT_CCC_MAX__JPEG_DHT_LI__SHFT                0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define JPEG_DEC_SCALE                       JPEG_DEC_SCALE
-#define HWIO_JPEG_DEC_SCALE_ADDR  /* RW */       (JPEGD_BASE+0x00000060)
-#define HWIO_JPEG_DEC_SCALE__POR                 0x00000000
-#define HWIO_JPEG_DEC_SCALE__RMSK                0x00000003
-#define HWIO_JPEG_DEC_SCALE__SHFT                         0
-/* Register Field FMSK and SHFT*/
-#define HWIO_JPEG_DEC_SCALE__JPEG_DEC_SCALE_RATIO__BMSK       0x00000003
-#define HWIO_JPEG_DEC_SCALE__JPEG_DEC_SCALE_RATIO__SHFT                0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define JPEG_CONVERT                         JPEG_CONVERT
-#define HWIO_JPEG_CONVERT_ADDR  /* RW */       (JPEGD_BASE+0x00000064)
-#define HWIO_JPEG_CONVERT__POR                 0x00000000
-#define HWIO_JPEG_CONVERT__RMSK                0xFFFF13FF
-#define HWIO_JPEG_CONVERT__SHFT                         0
-/* Register Field FMSK and SHFT*/
-#define HWIO_JPEG_CONVERT__JPEG_CONVERT_MONO_CB_VALUE__BMSK      0xFF000000
-#define HWIO_JPEG_CONVERT__JPEG_CONVERT_MONO_CB_VALUE__SHFT              24
-#define HWIO_JPEG_CONVERT__JPEG_CONVERT_MONO_CR_VALUE__BMSK      0x00FF0000
-#define HWIO_JPEG_CONVERT__JPEG_CONVERT_MONO_CR_VALUE__SHFT              16
-#define HWIO_JPEG_CONVERT__JPEG_CONVERT_CLAMP_EN__BMSK           0x00001000
-#define HWIO_JPEG_CONVERT__JPEG_CONVERT_CLAMP_EN__SHFT                   12
-#define HWIO_JPEG_CONVERT__JPEG_CONVERT_CBCR_SWITCH__BMSK        0x00000200
-#define HWIO_JPEG_CONVERT__JPEG_CONVERT_CBCR_SWITCH__SHFT                 9
-#define HWIO_JPEG_CONVERT__JPEG_CONVERT_MONOCHROME_EN__BMSK      0x00000100
-#define HWIO_JPEG_CONVERT__JPEG_CONVERT_MONOCHROME_EN__SHFT               8
-#define HWIO_JPEG_CONVERT__JPEG_CONVERT_MEM_ORG__BMSK            0x000000C0
-#define HWIO_JPEG_CONVERT__JPEG_CONVERT_MEM_ORG__SHFT                     6
-#define HWIO_JPEG_CONVERT__JPEG_CONVERT_422_MCU_TYPE__BMSK       0x00000030
-#define HWIO_JPEG_CONVERT__JPEG_CONVERT_422_MCU_TYPE__SHFT                4
-#define HWIO_JPEG_CONVERT__JPEG_CONVERT_OUTPUT_FORMAT__BMSK      0x0000000C
-#define HWIO_JPEG_CONVERT__JPEG_CONVERT_OUTPUT_FORMAT__SHFT               2
-#define HWIO_JPEG_CONVERT__JPEG_CONVERT_INPUT_FORMAT__BMSK       0x00000003
-#define HWIO_JPEG_CONVERT__JPEG_CONVERT_INPUT_FORMAT__SHFT                0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define JPEG_ENC_BYTE_CNT                       JPEG_ENC_BYTE_CNT
-#define HWIO_JPEG_ENC_BYTE_CNT_ADDR  /* RW */          (JPEGD_BASE+0x00000070)
-#define HWIO_JPEG_ENC_BYTE_CNT__POR                    0x00000000
-#define HWIO_JPEG_ENC_BYTE_CNT__RMSK                   0xFFFFFFFF
-#define HWIO_JPEG_ENC_BYTE_CNT__SHFT                            0
-/* Register Field FMSK and SHFT*/
-#define HWIO_JPEG_ENC_BYTE_CNT__JPEG_ENC_BYTE_CNT_TOT__BMSK     0xFFFFFFFF
-#define HWIO_JPEG_ENC_BYTE_CNT__JPEG_ENC_BYTE_CNT_TOT__SHFT              0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define JPEG_DEBUG                                  JPEG_DEBUG
-#define HWIO_JPEG_DEBUG_ADDR  /* RW */              (JPEGD_BASE+0x00000080)
-#define HWIO_JPEG_DEBUG__POR                        0x4A504547
-#define HWIO_JPEG_DEBUG__RMSK                       0xFFFFFFFF
-#define HWIO_JPEG_DEBUG__SHFT                                0
-/* Register Field FMSK and SHFT*/
-#define HWIO_JPEG_DEBUG__JPEG_DEBUG__BMSK            0xFFFFFFFF
-#define HWIO_JPEG_DEBUG__JPEG_DEBUG__SHFT                     0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define JPEG_SPARE                                JPEG_SPARE
-#define HWIO_JPEG_SPARE_ADDR  /* RW */            (JPEGD_BASE+0x00000084)
-#define HWIO_JPEG_SPARE__POR                      0x00000000
-#define HWIO_JPEG_SPARE__RMSK                     0xFFFFFFFF
-#define HWIO_JPEG_SPARE__SHFT                              0
-/* Register Field FMSK and SHFT*/
-#define HWIO_JPEG_SPARE__JPEG_SPARE_00__BMSK            0xFFFFFFFF
-#define HWIO_JPEG_SPARE__JPEG_SPARE_00__SHFT                     0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define JPEG_REGISTER_TIMEOUT                       JPEG_REGISTER_TIMEOUT
-#define HWIO_JPEG_REGISTER_TIMEOUT_ADDR    (JPEGD_BASE+0x00000088)
-#define HWIO_JPEG_REGISTER_TIMEOUT__POR                        0x0000FFFF
-#define HWIO_JPEG_REGISTER_TIMEOUT__RMSK                       0x0000FFFF
-#define HWIO_JPEG_REGISTER_TIMEOUT__SHFT                                0
-/* Register Field FMSK and SHFT*/
-#define HWIO_JPEG_REGISTER_TIMEOUT__JPEG_TIMEOUT_VALUE__BMSK        0x0000FFFF
-#define HWIO_JPEG_REGISTER_TIMEOUT__JPEG_TIMEOUT_VALUE__SHFT                 0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define JPEGD_STATUS_BUS_DATA                     JPEGD_STATUS_BUS_DATA
-#define HWIO_JPEGD_STATUS_BUS_DATA_ADDR  /* RW */       (JPEGD_BASE+0x00000258)
-#define HWIO_JPEGD_STATUS_BUS_DATA__POR                      0x00000000
-#define HWIO_JPEGD_STATUS_BUS_DATA__RMSK                     0xFFFFFFFF
-#define HWIO_JPEGD_STATUS_BUS_DATA__SHFT                              0
-/* Register Field FMSK and SHFT*/
-#define HWIO_JPEGD_STATUS_BUS_DATA__STATUS_BUS_DATA__BMSK      0xFFFFFFFF
-#define HWIO_JPEGD_STATUS_BUS_DATA__STATUS_BUS_DATA__SHFT               0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define JPEGD_STATUS_BUS_CONFIG                     JPEGD_STATUS_BUS_CONFIG
-#define HWIO_JPEGD_STATUS_BUS_CONFIG_ADDR  /* RW */     (JPEGD_BASE+0x0000025C)
-#define HWIO_JPEGD_STATUS_BUS_CONFIG__POR                        0x00000000
-#define HWIO_JPEGD_STATUS_BUS_CONFIG__RMSK                       0x0000001F
-#define HWIO_JPEGD_STATUS_BUS_CONFIG__SHFT                                0
-/* Register Field FMSK and SHFT*/
-#define HWIO_JPEGD_STATUS_BUS_CONFIG__STATUS_BUS_SEL__BMSK         0x0000001F
-#define HWIO_JPEGD_STATUS_BUS_CONFIG__STATUS_BUS_SEL__SHFT                  0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define RTDMA_JPEG_AXI_CONFIG                       RTDMA_JPEG_AXI_CONFIG
-#define HWIO_RTDMA_JPEG_AXI_CONFIG_ADDR  /* RW */        (JPEGD_BASE+0x00000260)
-#define HWIO_RTDMA_JPEG_AXI_CONFIG__POR                        0x00000024
-#define HWIO_RTDMA_JPEG_AXI_CONFIG__RMSK                       0x00000FFF
-#define HWIO_RTDMA_JPEG_AXI_CONFIG__SHFT                                0
-/* Register Field FMSK and SHFT*/
-#define HWIO_RTDMA_JPEG_AXI_CONFIG__OUT_OF_ORDER_WR__BMSK          0x00000800
-#define HWIO_RTDMA_JPEG_AXI_CONFIG__OUT_OF_ORDER_WR__SHFT                  11
-#define HWIO_RTDMA_JPEG_AXI_CONFIG__OUT_OF_ORDER_RD__BMSK          0x00000400
-#define HWIO_RTDMA_JPEG_AXI_CONFIG__OUT_OF_ORDER_RD__SHFT                  10
-#define HWIO_RTDMA_JPEG_AXI_CONFIG__BOUND_LIMIT__BMSK              0x00000300
-#define HWIO_RTDMA_JPEG_AXI_CONFIG__BOUND_LIMIT__SHFT                       8
-#define HWIO_RTDMA_JPEG_AXI_CONFIG__PACK_TIMEOUT__BMSK             0x000000F0
-#define HWIO_RTDMA_JPEG_AXI_CONFIG__PACK_TIMEOUT__SHFT                      4
-#define HWIO_RTDMA_JPEG_AXI_CONFIG__PACK_MAX_BLEN__BMSK            0x0000000F
-#define HWIO_RTDMA_JPEG_AXI_CONFIG__PACK_MAX_BLEN__SHFT                     0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define JPEGD_CLK_CONTROL                             JPEGD_CLK_CONTROL
-#define HWIO_JPEGD_CLK_CONTROL_ADDR  /* RW */   (JPEGD_BASE+0x00000264)
-#define HWIO_JPEGD_CLK_CONTROL__POR             0x00000005
-#define HWIO_JPEGD_CLK_CONTROL__RMSK                         0x0000000F
-#define HWIO_JPEGD_CLK_CONTROL__SHFT                                  0
-/* Register Field FMSK and SHFT*/
-#define HWIO_JPEGD_CLK_CONTROL__JPEG_CLKIDLE__BMSK           0x00000008
-#define HWIO_JPEGD_CLK_CONTROL__JPEG_CLKIDLE__SHFT                    3
-#define HWIO_JPEGD_CLK_CONTROL__JPEG_CLKON__BMSK             0x00000004
-#define HWIO_JPEGD_CLK_CONTROL__JPEG_CLKON__SHFT                      2
-#define HWIO_JPEGD_CLK_CONTROL__AXI_CLKIDLE__BMSK            0x00000002
-#define HWIO_JPEGD_CLK_CONTROL__AXI_CLKIDLE__SHFT                     1
-#define HWIO_JPEGD_CLK_CONTROL__AXI_CLKON__BMSK              0x00000001
-#define HWIO_JPEGD_CLK_CONTROL__AXI_CLKON__SHFT                       0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define RTDMA_JPEG_WR_BUF_CONFIG                     RTDMA_JPEG_WR_BUF_CONFIG
-#define HWIO_RTDMA_JPEG_WR_BUF_CONFIG_ADDR  /* RW */   (JPEGD_BASE+0x00000200)
-#define HWIO_RTDMA_JPEG_WR_BUF_CONFIG__POR             0x00000000
-#define HWIO_RTDMA_JPEG_WR_BUF_CONFIG__RMSK            0x0000001F
-#define HWIO_RTDMA_JPEG_WR_BUF_CONFIG__SHFT                     0
-/* Register Field FMSK and SHFT*/
-#define HWIO_RTDMA_JPEG_WR_BUF_CONFIG__BUF_FORMAT__BMSK         0x0000001C
-#define HWIO_RTDMA_JPEG_WR_BUF_CONFIG__BUF_FORMAT__SHFT                  2
-#define HWIO_RTDMA_JPEG_WR_BUF_CONFIG__NUM_OF_PLANES__BMSK      0x00000003
-#define HWIO_RTDMA_JPEG_WR_BUF_CONFIG__NUM_OF_PLANES__SHFT               0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define RTDMA_JPEG_WR_OP                               RTDMA_JPEG_WR_OP
-#define HWIO_RTDMA_JPEG_WR_OP_ADDR  /* RW */        (JPEGD_BASE+0x00000204)
-#define HWIO_RTDMA_JPEG_WR_OP__POR                  0x00000000
-#define HWIO_RTDMA_JPEG_WR_OP__RMSK                 0x00000013
-#define HWIO_RTDMA_JPEG_WR_OP__SHFT                          0
-/* Register Field FMSK and SHFT*/
-#define HWIO_RTDMA_JPEG_WR_OP__ALIGN__BMSK          0x00000010
-#define HWIO_RTDMA_JPEG_WR_OP__ALIGN__SHFT                   4
-#define HWIO_RTDMA_JPEG_WR_OP__FLIP__BMSK           0x00000002
-#define HWIO_RTDMA_JPEG_WR_OP__FLIP__SHFT                    1
-#define HWIO_RTDMA_JPEG_WR_OP__MIRROR__BMSK         0x00000001
-#define HWIO_RTDMA_JPEG_WR_OP__MIRROR__SHFT                  0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define RTDMA_JPEG_WR_BUF_Y_PNTR                      RTDMA_JPEG_WR_BUF_Y_PNTR
-#define HWIO_RTDMA_JPEG_WR_BUF_Y_PNTR_ADDR    (JPEGD_BASE+0x00000208)
-#define HWIO_RTDMA_JPEG_WR_BUF_Y_PNTR__POR                0x00000000
-#define HWIO_RTDMA_JPEG_WR_BUF_Y_PNTR__RMSK               0xFFFFFFF8
-#define HWIO_RTDMA_JPEG_WR_BUF_Y_PNTR__SHFT                        3
-/* Register Element MIN and MAX*/
-#define HWIO_RTDMA_JPEG_WR_BUF_Y_PNTR___S                          3
-#define HWIO_RTDMA_JPEG_WR_BUF_Y_PNTR___S                          3
-#define HWIO_RTDMA_JPEG_WR_BUF_Y_PNTR___S                          3
-#define HWIO_RTDMA_JPEG_WR_BUF_Y_PNTR___S                          3
-
-/* Register Field FMSK and SHFT*/
-#define HWIO_RTDMA_JPEG_WR_BUF_Y_PNTR__PNTR__BMSK         0xFFFFFFF8
-#define HWIO_RTDMA_JPEG_WR_BUF_Y_PNTR__PNTR__SHFT                  3
-
-/* Register ADDR, RMSK, and SHFT*/
-#define RTDMA_JPEG_WR_BUF_U_PNTR                      RTDMA_JPEG_WR_BUF_U_PNTR
-#define HWIO_RTDMA_JPEG_WR_BUF_U_PNTR_ADDR  /* RW */     (JPEGD_BASE+0x0000020C)
-#define HWIO_RTDMA_JPEG_WR_BUF_U_PNTR__POR               0x00000000
-#define HWIO_RTDMA_JPEG_WR_BUF_U_PNTR__RMSK              0xFFFFFFF8
-#define HWIO_RTDMA_JPEG_WR_BUF_U_PNTR__SHFT                       3
-
-/* Register Element MIN and MAX*/
-#define HWIO_RTDMA_JPEG_WR_BUF_U_PNTR___S                         3
-#define HWIO_RTDMA_JPEG_WR_BUF_U_PNTR___S                         3
-#define HWIO_RTDMA_JPEG_WR_BUF_U_PNTR___S                         3
-#define HWIO_RTDMA_JPEG_WR_BUF_U_PNTR___S                         3
-
-/* Register Field FMSK and SHFT*/
-#define HWIO_RTDMA_JPEG_WR_BUF_U_PNTR__PNTR__BMSK        0xFFFFFFF8
-#define HWIO_RTDMA_JPEG_WR_BUF_U_PNTR__PNTR__SHFT                 3
-
-/* Register ADDR, RMSK, and SHFT*/
-#define RTDMA_JPEG_WR_BUF_V_PNTR                       RTDMA_JPEG_WR_BUF_V_PNTR
-#define HWIO_RTDMA_JPEG_WR_BUF_V_PNTR_ADDR   (JPEGD_BASE+0x00000210)
-#define HWIO_RTDMA_JPEG_WR_BUF_V_PNTR__POR                0x00000000
-#define HWIO_RTDMA_JPEG_WR_BUF_V_PNTR__RMSK               0xFFFFFFF8
-#define HWIO_RTDMA_JPEG_WR_BUF_V_PNTR__SHFT                        3
-
-/* Register Element MIN and MAX*/
-#define HWIO_RTDMA_JPEG_WR_BUF_V_PNTR___S                          3
-#define HWIO_RTDMA_JPEG_WR_BUF_V_PNTR___S                          3
-#define HWIO_RTDMA_JPEG_WR_BUF_V_PNTR___S                          3
-#define HWIO_RTDMA_JPEG_WR_BUF_V_PNTR___S                          3
-
-/* Register Field FMSK and SHFT*/
-#define HWIO_RTDMA_JPEG_WR_BUF_V_PNTR__PNTR__BMSK         0xFFFFFFF8
-#define HWIO_RTDMA_JPEG_WR_BUF_V_PNTR__PNTR__SHFT                  3
-
-/* Register ADDR, RMSK, and SHFT*/
-#define RTDMA_JPEG_WR_BUF_PITCH                         RTDMA_JPEG_WR_BUF_PITCH
-#define HWIO_RTDMA_JPEG_WR_BUF_PITCH_ADDR  /* RW */    (JPEGD_BASE+0x00000214)
-#define HWIO_RTDMA_JPEG_WR_BUF_PITCH__POR              0x00000000
-#define HWIO_RTDMA_JPEG_WR_BUF_PITCH__RMSK             0x00003FF8
-#define HWIO_RTDMA_JPEG_WR_BUF_PITCH__SHFT                      3
-
-/* Register Element MIN and MAX*/
-#define HWIO_RTDMA_JPEG_WR_BUF_PITCH___S                        3
-#define HWIO_RTDMA_JPEG_WR_BUF_PITCH___S                        3
-#define HWIO_RTDMA_JPEG_WR_BUF_PITCH___S                        3
-#define HWIO_RTDMA_JPEG_WR_BUF_PITCH___S                        3
-
-/* Register Field FMSK and SHFT*/
-#define HWIO_RTDMA_JPEG_WR_BUF_PITCH__PITCH__BMSK          0x00003FF8
-#define HWIO_RTDMA_JPEG_WR_BUF_PITCH__PITCH__SHFT                   3
-
-/* Register ADDR, RMSK, and SHFT*/
-#define RTDMA_JPEG_WR_PLANE_SIZE                      RTDMA_JPEG_WR_PLANE_SIZE
-#define HWIO_RTDMA_JPEG_WR_PLANE_SIZE_ADDR  /* RW */  (JPEGD_BASE+0x00000218)
-#define HWIO_RTDMA_JPEG_WR_PLANE_SIZE__POR            0x00000000
-#define HWIO_RTDMA_JPEG_WR_PLANE_SIZE__RMSK           0x1FFF1FFF
-#define HWIO_RTDMA_JPEG_WR_PLANE_SIZE__SHFT                    0
-
-/* Register Field FMSK and SHFT*/
-#define HWIO_RTDMA_JPEG_WR_PLANE_SIZE__PLANE_VSIZE__BMSK       0x1FFF0000
-#define HWIO_RTDMA_JPEG_WR_PLANE_SIZE__PLANE_VSIZE__SHFT               16
-#define HWIO_RTDMA_JPEG_WR_PLANE_SIZE__PLANE_HSIZE__BMSK       0x00001FFF
-#define HWIO_RTDMA_JPEG_WR_PLANE_SIZE__PLANE_HSIZE__SHFT                0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define RTDMA_JPEG_WR_BLOCK_SIZE                      RTDMA_JPEG_WR_BLOCK_SIZE
-#define HWIO_RTDMA_JPEG_WR_BLOCK_SIZE_ADDR  /* RW */    (JPEGD_BASE+0x0000021C)
-#define HWIO_RTDMA_JPEG_WR_BLOCK_SIZE__POR              0x00000000
-#define HWIO_RTDMA_JPEG_WR_BLOCK_SIZE__RMSK             0x00000FFF
-#define HWIO_RTDMA_JPEG_WR_BLOCK_SIZE__SHFT                      0
-
-/* Register Field FMSK and SHFT*/
-#define HWIO_RTDMA_JPEG_WR_BLOCK_SIZE__BLOCK_VSIZE__BMSK           0x00000FC0
-#define HWIO_RTDMA_JPEG_WR_BLOCK_SIZE__BLOCK_VSIZE__SHFT                    6
-#define HWIO_RTDMA_JPEG_WR_BLOCK_SIZE__BLOCK_HSIZE__BMSK           0x0000003F
-#define HWIO_RTDMA_JPEG_WR_BLOCK_SIZE__BLOCK_HSIZE__SHFT                    0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define RTDMA_JPEG_WR_BUFFER_SIZE                      RTDMA_JPEG_WR_BUFFER_SIZE
-#define HWIO_RTDMA_JPEG_WR_BUFFER_SIZE_ADDR  /* RW */   (JPEGD_BASE+0x00000220)
-#define HWIO_RTDMA_JPEG_WR_BUFFER_SIZE__POR             0x00000000
-#define HWIO_RTDMA_JPEG_WR_BUFFER_SIZE__RMSK            0x00001FFF
-#define HWIO_RTDMA_JPEG_WR_BUFFER_SIZE__SHFT                     0
-
-/* Register Field FMSK and SHFT*/
-#define HWIO_RTDMA_JPEG_WR_BUFFER_SIZE__BUFFER_VSIZE__BMSK         0x00001FFF
-#define HWIO_RTDMA_JPEG_WR_BUFFER_SIZE__BUFFER_VSIZE__SHFT                  0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define RTDMA_JPEG_WR_STA_ACK                      RTDMA_JPEG_WR_STA_ACK
-#define HWIO_RTDMA_JPEG_WR_STA_ACK_ADDR  /* RW */   (JPEGD_BASE+0x00000224)
-#define HWIO_RTDMA_JPEG_WR_STA_ACK__POR             0x00000000
-#define HWIO_RTDMA_JPEG_WR_STA_ACK__RMSK            0x0000000F
-#define HWIO_RTDMA_JPEG_WR_STA_ACK__SHFT                     3
-
-/* Register Element MIN and MAX*/
-#define HWIO_RTDMA_JPEG_WR_STA_ACK___S                       3
-#define HWIO_RTDMA_JPEG_WR_STA_ACK___S                       3
-#define HWIO_RTDMA_JPEG_WR_STA_ACK___S                       3
-#define HWIO_RTDMA_JPEG_WR_STA_ACK___S                       3
-
-/* Register Field FMSK and SHFT*/
-#define HWIO_RTDMA_JPEG_WR_STA_ACK__SW_RESET_ABORT_RDY_STA__BMSK   0x00000008
-#define HWIO_RTDMA_JPEG_WR_STA_ACK__SW_RESET_ABORT_RDY_STA__SHFT            3
-#define HWIO_RTDMA_JPEG_WR_STA_ACK__SW_RESET_ABORT_RDY_ACK__BMSK   0x00000008
-#define HWIO_RTDMA_JPEG_WR_STA_ACK__SW_RESET_ABORT_RDY_ACK__SHFT            3
-#define HWIO_RTDMA_JPEG_WR_STA_ACK__ERR_STA__BMSK                  0x00000004
-#define HWIO_RTDMA_JPEG_WR_STA_ACK__ERR_STA__SHFT                           2
-#define HWIO_RTDMA_JPEG_WR_STA_ACK__ERR_ACK__BMSK                  0x00000004
-#define HWIO_RTDMA_JPEG_WR_STA_ACK__ERR_ACK__SHFT                           2
-#define HWIO_RTDMA_JPEG_WR_STA_ACK__EOF_STA__BMSK                  0x00000002
-#define HWIO_RTDMA_JPEG_WR_STA_ACK__EOF_STA__SHFT                           1
-#define HWIO_RTDMA_JPEG_WR_STA_ACK__EOF_ACK__BMSK                  0x00000002
-#define HWIO_RTDMA_JPEG_WR_STA_ACK__EOF_ACK__SHFT                           1
-#define HWIO_RTDMA_JPEG_WR_STA_ACK__SOF_STA__BMSK                  0x00000001
-#define HWIO_RTDMA_JPEG_WR_STA_ACK__SOF_STA__SHFT                           0
-#define HWIO_RTDMA_JPEG_WR_STA_ACK__SOF_ACK__BMSK           0x00000001
-#define HWIO_RTDMA_JPEG_WR_STA_ACK__SOF_ACK__SHFT                    0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define RTDMA_JPEG_WR_INT_EN                      RTDMA_JPEG_WR_INT_EN
-#define HWIO_RTDMA_JPEG_WR_INT_EN_ADDR  /* W */        (JPEGD_BASE+0x00000228)
-#define HWIO_RTDMA_JPEG_WR_INT_EN__POR                 0x00000000
-#define HWIO_RTDMA_JPEG_WR_INT_EN__RMSK                0x0000000F
-#define HWIO_RTDMA_JPEG_WR_INT_EN__SHFT                         0
-
-/* Register Field FMSK and SHFT*/
-#define HWIO_RTDMA_JPEG_WR_INT_EN__SW_RESET_ABORT_RDY_EN__BMSK 0x00000008
-#define HWIO_RTDMA_JPEG_WR_INT_EN__SW_RESET_ABORT_RDY_EN__SHFT          3
-#define HWIO_RTDMA_JPEG_WR_INT_EN__ERR_EN__BMSK                0x00000004
-#define HWIO_RTDMA_JPEG_WR_INT_EN__ERR_EN__SHFT                         2
-#define HWIO_RTDMA_JPEG_WR_INT_EN__EOF_EN__BMSK                0x00000002
-#define HWIO_RTDMA_JPEG_WR_INT_EN__EOF_EN__SHFT                         1
-#define HWIO_RTDMA_JPEG_WR_INT_EN__SOF_EN__BMSK                0x00000001
-#define HWIO_RTDMA_JPEG_WR_INT_EN__SOF_EN__SHFT                         0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define RTDMA_JPEG_RD_BUF_CONFIG                     RTDMA_JPEG_RD_BUF_CONFIG
-#define HWIO_RTDMA_JPEG_RD_BUF_CONFIG_ADDR  /* RW */     (JPEGD_BASE+0x00000100)
-#define HWIO_RTDMA_JPEG_RD_BUF_CONFIG__POR               0x00000000
-#define HWIO_RTDMA_JPEG_RD_BUF_CONFIG__RMSK              0x0000001F
-#define HWIO_RTDMA_JPEG_RD_BUF_CONFIG__SHFT                       0
-
-/* Register Field FMSK and SHFT*/
-#define HWIO_RTDMA_JPEG_RD_BUF_CONFIG__BUF_FORMAT__BMSK          0x0000001C
-#define HWIO_RTDMA_JPEG_RD_BUF_CONFIG__BUF_FORMAT__SHFT                   2
-#define HWIO_RTDMA_JPEG_RD_BUF_CONFIG__NUM_OF_PLANES__BMSK       0x00000003
-#define HWIO_RTDMA_JPEG_RD_BUF_CONFIG__NUM_OF_PLANES__SHFT                0
-
-/* Register ADDR, RMSK, and SHFT, W */
-#define RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO   RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO
-#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO_ADDR  (JPEGD_BASE+0x00000104)
-#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO__POR            0x00000000
-#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO__RMSK           0x0000001C
-#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO__SHFT                    2
-
-/* Register Element MIN and MAX*/
-#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO___S                      2
-#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO___S                      2
-#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO___S                      2
-#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO___S                      2
-
-/* Register Field FMSK and SHFT*/
-#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO__BUF_APPLY__BMSK   0x00000010
-#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO__BUF_APPLY__SHFT            4
-#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO__BUF_EOF__BMSK     0x00000008
-#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO__BUF_EOF__SHFT              3
-#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO__BUF_SOF__BMSK     0x00000004
-#define HWIO_RTDMA_JPEG_RD_BUF_MNGR_BUF_ID_FIFO__BUF_SOF__SHFT              2
-
-/* Register ADDR, RMSK, and SHFT*/
-#define RTDMA_JPEG_RD_BUF_Y_PNTR                        RTDMA_JPEG_RD_BUF_Y_PNTR
-#define HWIO_RTDMA_JPEG_RD_BUF_Y_PNTR_ADDR  /* RW */   (JPEGD_BASE+0x0000010C)
-#define HWIO_RTDMA_JPEG_RD_BUF_Y_PNTR__POR             0x00000000
-#define HWIO_RTDMA_JPEG_RD_BUF_Y_PNTR__RMSK            0xFFFFFFF8
-#define HWIO_RTDMA_JPEG_RD_BUF_Y_PNTR__SHFT                     3
-
-/* Register Element MIN and MAX*/
-#define HWIO_RTDMA_JPEG_RD_BUF_Y_PNTR___S                       3
-#define HWIO_RTDMA_JPEG_RD_BUF_Y_PNTR___S                       3
-#define HWIO_RTDMA_JPEG_RD_BUF_Y_PNTR___S                       3
-#define HWIO_RTDMA_JPEG_RD_BUF_Y_PNTR___S                       3
-
-/* Register Field FMSK and SHFT*/
-#define HWIO_RTDMA_JPEG_RD_BUF_Y_PNTR__PNTR__BMSK      0xFFFFFFF8
-#define HWIO_RTDMA_JPEG_RD_BUF_Y_PNTR__PNTR__SHFT               3
-
-/* Register ADDR, RMSK, and SHFT*/
-#define RTDMA_JPEG_RD_BUF_U_PNTR                     RTDMA_JPEG_RD_BUF_U_PNTR
-#define HWIO_RTDMA_JPEG_RD_BUF_U_PNTR_ADDR  /* RW */ (JPEGD_BASE+0x00000110)
-#define HWIO_RTDMA_JPEG_RD_BUF_U_PNTR__POR           0x00000000
-#define HWIO_RTDMA_JPEG_RD_BUF_U_PNTR__RMSK          0xFFFFFFF8
-#define HWIO_RTDMA_JPEG_RD_BUF_U_PNTR__SHFT                   3
-
-/* Register Element MIN and MAX*/
-#define HWIO_RTDMA_JPEG_RD_BUF_U_PNTR___S                     3
-#define HWIO_RTDMA_JPEG_RD_BUF_U_PNTR___S                     3
-#define HWIO_RTDMA_JPEG_RD_BUF_U_PNTR___S                     3
-#define HWIO_RTDMA_JPEG_RD_BUF_U_PNTR___S                     3
-
-/* Register Field FMSK and SHFT*/
-#define HWIO_RTDMA_JPEG_RD_BUF_U_PNTR__PNTR__BMSK        0xFFFFFFF8
-#define HWIO_RTDMA_JPEG_RD_BUF_U_PNTR__PNTR__SHFT               3
-
-/* Register ADDR, RMSK, and SHFT*/
-#define RTDMA_JPEG_RD_BUF_V_PNTR                     RTDMA_JPEG_RD_BUF_V_PNTR
-#define HWIO_RTDMA_JPEG_RD_BUF_V_PNTR_ADDR  /* RW */    (JPEGD_BASE+0x00000114)
-#define HWIO_RTDMA_JPEG_RD_BUF_V_PNTR__POR              0x00000000
-#define HWIO_RTDMA_JPEG_RD_BUF_V_PNTR__RMSK             0xFFFFFFF8
-#define HWIO_RTDMA_JPEG_RD_BUF_V_PNTR__SHFT                      3
-
-/* Register Element MIN and MAX*/
-#define HWIO_RTDMA_JPEG_RD_BUF_V_PNTR___S                        3
-#define HWIO_RTDMA_JPEG_RD_BUF_V_PNTR___S                        3
-#define HWIO_RTDMA_JPEG_RD_BUF_V_PNTR___S                        3
-#define HWIO_RTDMA_JPEG_RD_BUF_V_PNTR___S                        3
-
-/* Register Field FMSK and SHFT*/
-#define HWIO_RTDMA_JPEG_RD_BUF_V_PNTR__PNTR__BMSK       0xFFFFFFF8
-#define HWIO_RTDMA_JPEG_RD_BUF_V_PNTR__PNTR__SHFT                3
-
-/* Register ADDR, RMSK, and SHFT*/
-#define RTDMA_JPEG_RD_BUF_PITCH                       RTDMA_JPEG_RD_BUF_PITCH
-#define HWIO_RTDMA_JPEG_RD_BUF_PITCH_ADDR  /* RW */    (JPEGD_BASE+0x00000118)
-#define HWIO_RTDMA_JPEG_RD_BUF_PITCH__POR              0x00000000
-#define HWIO_RTDMA_JPEG_RD_BUF_PITCH__RMSK             0x00003FF8
-#define HWIO_RTDMA_JPEG_RD_BUF_PITCH__SHFT                      3
-
-/* Register Element MIN and MAX*/
-#define HWIO_RTDMA_JPEG_RD_BUF_PITCH___S                        3
-#define HWIO_RTDMA_JPEG_RD_BUF_PITCH___S                        3
-#define HWIO_RTDMA_JPEG_RD_BUF_PITCH___S                        3
-#define HWIO_RTDMA_JPEG_RD_BUF_PITCH___S                        3
-
-/* Register Field FMSK and SHFT*/
-#define HWIO_RTDMA_JPEG_RD_BUF_PITCH__PITCH__BMSK            0x00003FF8
-#define HWIO_RTDMA_JPEG_RD_BUF_PITCH__PITCH__SHFT                     3
-
-/* Register ADDR, RMSK, and SHFT*/
-#define RTDMA_JPEG_RD_PLANE_SIZE                     RTDMA_JPEG_RD_PLANE_SIZE
-#define HWIO_RTDMA_JPEG_RD_PLANE_SIZE_ADDR  /* RW */  (JPEGD_BASE+0x0000011C)
-#define HWIO_RTDMA_JPEG_RD_PLANE_SIZE__POR            0x00000000
-#define HWIO_RTDMA_JPEG_RD_PLANE_SIZE__RMSK            0x1FFF1FFF
-#define HWIO_RTDMA_JPEG_RD_PLANE_SIZE__SHFT                     0
-
-/* Register Field FMSK and SHFT*/
-#define HWIO_RTDMA_JPEG_RD_PLANE_SIZE__PLANE_VSIZE__BMSK         0x1FFF0000
-#define HWIO_RTDMA_JPEG_RD_PLANE_SIZE__PLANE_VSIZE__SHFT                 16
-#define HWIO_RTDMA_JPEG_RD_PLANE_SIZE__PLANE_HSIZE__BMSK         0x00001FFF
-#define HWIO_RTDMA_JPEG_RD_PLANE_SIZE__PLANE_HSIZE__SHFT                  0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define RTDMA_JPEG_RD_BLOCK_SIZE                       RTDMA_JPEG_RD_BLOCK_SIZE
-#define HWIO_RTDMA_JPEG_RD_BLOCK_SIZE_ADDR  /* RW */    (JPEGD_BASE+0x00000120)
-#define HWIO_RTDMA_JPEG_RD_BLOCK_SIZE__POR              0x000003CF
-#define HWIO_RTDMA_JPEG_RD_BLOCK_SIZE__RMSK             0x00000FFF
-#define HWIO_RTDMA_JPEG_RD_BLOCK_SIZE__SHFT                      0
-
-/* Register Field FMSK and SHFT*/
-#define HWIO_RTDMA_JPEG_RD_BLOCK_SIZE__BLOCK_VSIZE__BMSK       0x00000FC0
-#define HWIO_RTDMA_JPEG_RD_BLOCK_SIZE__BLOCK_VSIZE__SHFT                6
-#define HWIO_RTDMA_JPEG_RD_BLOCK_SIZE__BLOCK_HSIZE__BMSK       0x0000003F
-#define HWIO_RTDMA_JPEG_RD_BLOCK_SIZE__BLOCK_HSIZE__SHFT                0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define RTDMA_JPEG_RD_BUFFER_SIZE               RTDMA_JPEG_RD_BUFFER_SIZE
-#define HWIO_RTDMA_JPEG_RD_BUFFER_SIZE_ADDR  (JPEGD_BASE+0x00000124)
-#define HWIO_RTDMA_JPEG_RD_BUFFER_SIZE__POR               0x00000000
-#define HWIO_RTDMA_JPEG_RD_BUFFER_SIZE__RMSK              0x00001FFF
-#define HWIO_RTDMA_JPEG_RD_BUFFER_SIZE__SHFT                       0
-
-/* Register Field FMSK and SHFT*/
-#define HWIO_RTDMA_JPEG_RD_BUFFER_SIZE__BUFFER_VSIZE__BMSK      0x00001FFF
-#define HWIO_RTDMA_JPEG_RD_BUFFER_SIZE__BUFFER_VSIZE__SHFT                0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define RTDMA_JPEG_RD_STA_ACK                     RTDMA_JPEG_RD_STA_ACK
-#define HWIO_RTDMA_JPEG_RD_STA_ACK_ADDR         (JPEGD_BASE+0x00000128)
-#define HWIO_RTDMA_JPEG_RD_STA_ACK__POR                     0x00000000
-#define HWIO_RTDMA_JPEG_RD_STA_ACK__RMSK                    0x00000003
-#define HWIO_RTDMA_JPEG_RD_STA_ACK__SHFT                             0
-
-/* Register Field FMSK and SHFT*/
-#define HWIO_RTDMA_JPEG_RD_STA_ACK__EOF_STA__BMSK           0x00000002
-#define HWIO_RTDMA_JPEG_RD_STA_ACK__EOF_STA__SHFT                    1
-#define HWIO_RTDMA_JPEG_RD_STA_ACK__SOF_STA__BMSK           0x00000001
-#define HWIO_RTDMA_JPEG_RD_STA_ACK__SOF_STA__SHFT                    0
-#define HWIO_RTDMA_JPEG_RD_STA_ACK__EOF_ACK__BMSK           0x00000002
-#define HWIO_RTDMA_JPEG_RD_STA_ACK__EOF_ACK__SHFT                    1
-#define HWIO_RTDMA_JPEG_RD_STA_ACK__SOF_ACK__BMSK           0x00000001
-#define HWIO_RTDMA_JPEG_RD_STA_ACK__SOF_ACK__SHFT                    0
-
-/* Register ADDR, RMSK, and SHFT*/
-#define RTDMA_JPEG_RD_INT_EN                      RTDMA_JPEG_RD_INT_EN
-#define HWIO_RTDMA_JPEG_RD_INT_EN_ADDR  /* W */        (JPEGD_BASE+0x0000012C)
-#define HWIO_RTDMA_JPEG_RD_INT_EN__POR                      0x00000000
-#define HWIO_RTDMA_JPEG_RD_INT_EN__RMSK                     0x00000003
-#define HWIO_RTDMA_JPEG_RD_INT_EN__SHFT                              0
-
-/* Register Field FMSK and SHFT*/
-#define HWIO_RTDMA_JPEG_RD_INT_EN__EOF_EN__BMSK             0x00000002
-#define HWIO_RTDMA_JPEG_RD_INT_EN__EOF_EN__SHFT                      1
-#define HWIO_RTDMA_JPEG_RD_INT_EN__SOF_EN__BMSK             0x00000001
-#define HWIO_RTDMA_JPEG_RD_INT_EN__SOF_EN__SHFT                      0
-
-#endif /* MSM_MERCURY_HW_REG_H */
diff --git a/drivers/media/video/msm/mercury/msm_mercury_macros.h b/drivers/media/video/msm/mercury/msm_mercury_macros.h
deleted file mode 100644
index 33c4f9a..0000000
--- a/drivers/media/video/msm/mercury/msm_mercury_macros.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 MSM_MERCURY_MACROS_H
-#define MSM_MERCURY_MACROS_H
-
-#include <media/msm_mercury.h>
-
-#define mercury_kread(reg) \
-	hw_cmd.type = MSM_MERCURY_HW_CMD_TYPE_READ; \
-	hw_cmd.n = 1; \
-	hw_cmd.offset = HWIO_##reg##_ADDR; \
-	hw_cmd.mask = HWIO_##reg##__RMSK; \
-	hw_cmd.data = 0x0; \
-	msm_mercury_hw_exec_cmds(&hw_cmd, 1);
-
-#define mercury_kwrite(reg, val) \
-	hw_cmd.offset = HWIO_##reg##_ADDR; \
-	hw_cmd.mask = HWIO_##reg##__RMSK; \
-	hw_cmd.type = MSM_MERCURY_HW_CMD_TYPE_WRITE; \
-	hw_cmd.n = 1; \
-	hw_cmd.data = val; \
-	msm_mercury_hw_exec_cmds(&hw_cmd, 1);
-
-#define GET_FVAL(val, reg, field) ((val & HWIO_FMSK(reg, field)) >> \
-	HWIO_SHFT(reg, field))
-
-#define byte unsigned char
-#define word unsigned short
-#define dword unsigned long
-
-#define inp(port)    (*((dword *) (port)))
-#define inpb(port)     (*((byte *) (port)))
-#define inpw(port)   (*((word *) (port)))
-#define inpdw(port)   (*((dword *)(port)))
-
-#define outp(port, val)   (*((dword *) (port)) = ((dword) (val)))
-#define outpb(port, val)   (*((byte *) (port)) = ((byte) (val)))
-#define outpw(port, val)  (*((word *) (port)) = ((word) (val)))
-#define outpdw(port, val) (*((dword *) (port)) = ((dword) (val)))
-
-
-#define in_byte(addr)				(inp(addr))
-#define in_byte_masked(addr, mask)	(inp(addr) & (byte)mask)
-#define out_byte(addr, val)			 outp(addr, val)
-#define in_word(addr)				(inpw(addr))
-#define in_word_masked(addr, mask)	(inpw(addr) & (word)mask)
-#define out_word(addr, val)			 outpw(addr, val)
-#define in_dword(addr)				(inpdw(addr))
-#define in_dword_masked(addr, mask)	(inpdw(addr) & mask)
-#define out_dword(addr, val)			 outpdw(addr, val)
-
-/* shadowed, masked output for write-only registers */
-#define out_byte_masked(io, mask, val, shadow)  \
-	do { \
-		shadow = (shadow & (word)(~(mask))) | \
-		((word)((val) & (mask))); \
-		(void) out_byte(io, shadow);\
-	} while (0);
-
-#define out_word_masked(io, mask, val, shadow)  \
-	do { \
-		shadow = (shadow & (word)(~(mask))) | \
-		((word)((val) & (mask))); \
-		(void) out_word(io, shadow); \
-	} while (0);
-
-#define out_dword_masked(io, mask, val, shadow)  \
-	do { \
-		shadow = (shadow & (dword)(~(mask))) | \
-		((dword)((val) & (mask))); \
-		(void) out_dword(io, shadow);\
-	} while (0);
-
-#define out_byte_masked_ns(io, mask, val, current_reg_content)  \
-	(void) out_byte(io, ((current_reg_content & \
-	(word)(~(mask))) | ((word)((val) & (mask)))))
-
-#define out_word_masked_ns(io, mask, val, current_reg_content)  \
-	(void) out_word(io, ((current_reg_content & \
-	(word)(~(mask))) | ((word)((val) & (mask)))))
-
-#define out_dword_masked_ns(io, mask, val, current_reg_content) \
-	(void) out_dword(io, ((current_reg_content & \
-	(dword)(~(mask))) | ((dword)((val) & (mask)))))
-
-#define MEM_INF(val, reg, field)	((val & HWIO_FMSK(reg, field)) >> \
-	HWIO_SHFT(reg, field))
-
-#define MEM_OUTF(mem, reg, field, val)\
-	out_dword_masked_ns(mem, HWIO_FMSK(reg, field), \
-	(unsigned  int)val<<HWIO_SHFT(reg, field), in_dword(mem))
-
-#define MEM_OUTF2(mem, reg, field2, field1, val2, val1)  \
-	out_dword_masked_ns(mem, (HWIO_FMSK(reg, field2)| \
-	HWIO_FMSK(reg, field1)), \
-	(((unsigned int)val2<<HWIO_SHFT(reg, field2))| \
-	((unsigned int)val1<<HWIO_SHFT(reg, field1))), in_dword(mem))
-
-#define MEM_OUTF3(mem, reg, fld3, fld2, fld1, val3, val2, val1)  \
-	out_dword_masked_ns(mem, (HWIO_FMSK(reg, fld3)| \
-	HWIO_FMSK(reg, fld2)|HWIO_FMSK(reg, fld1)), \
-	(((unsigned int)val3<<HWIO_SHFT(reg, fld3))| \
-	((unsigned int)val2<<HWIO_SHFT(reg, fld2))| \
-	((unsigned int)val1<<HWIO_SHFT(reg, fld1))), in_dword(mem))
-
-#define HWIO_FMSK(reg, field)   HWIO_##reg##__##field##__BMSK
-#define HWIO_SHFT(reg, field)   HWIO_##reg##__##field##__SHFT
-#endif
diff --git a/drivers/media/video/msm/mercury/msm_mercury_platform.c b/drivers/media/video/msm/mercury/msm_mercury_platform.c
deleted file mode 100644
index 3dc7f4b..0000000
--- a/drivers/media/video/msm/mercury/msm_mercury_platform.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/clk.h>
-#include <linux/io.h>
-#include <linux/android_pmem.h>
-#include <mach/clk.h>
-#include <mach/camera.h>
-#include <mach/msm_subsystem_map.h>
-
-#include "msm_mercury_platform.h"
-#include "msm_mercury_sync.h"
-#include "msm_mercury_common.h"
-#include "msm_mercury_hw.h"
-
-
-struct ion_client *mercury_client;
-
-static struct msm_cam_clk_info mercury_jpegd_clk_info[] = {
-	{"core_clk", 200000000},
-	{"iface_clk", -1}
-};
-
-void msm_mercury_platform_p2v(struct file  *file,
-	struct ion_handle **ionhandle)
-{
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	ion_unmap_iommu(mercury_client, *ionhandle, CAMERA_DOMAIN,
-		GEN_POOL);
-	ion_free(mercury_client, *ionhandle);
-	*ionhandle = NULL;
-#elif CONFIG_ANDROID_PMEM
-	put_pmem_file(file);
-#endif
-}
-
-uint32_t msm_mercury_platform_v2p(int fd, uint32_t len,
-	struct file **file_p,
-	struct ion_handle **ionhandle)
-{
-	unsigned long paddr;
-	unsigned long size;
-	int rc;
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	*ionhandle = ion_import_dma_buf(mercury_client, fd);
-	if (IS_ERR_OR_NULL(*ionhandle))
-		return 0;
-
-	rc = ion_map_iommu(mercury_client, *ionhandle, CAMERA_DOMAIN,
-		GEN_POOL, SZ_4K, 0, &paddr,
-		(unsigned long *)&size, 0, 0);
-#elif CONFIG_ANDROID_PMEM
-	unsigned long kvstart;
-	rc = get_pmem_file(fd, &paddr, &kvstart, &size, file_p);
-#else
-	rc = 0;
-	paddr = 0;
-	size = 0;
-#endif
-	if (rc < 0) {
-		MCR_PR_ERR("%s: get_pmem_file fd %d error %d\n", __func__, fd,
-			rc);
-		goto error1;
-	}
-
-	/* validate user input */
-	if (len > size) {
-		MCR_PR_ERR("%s: invalid offset + len\n", __func__);
-		goto error1;
-	}
-
-	return paddr;
-error1:
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	ion_free(mercury_client, *ionhandle);
-#endif
-	return 0;
-}
-
-int msm_mercury_platform_init(struct platform_device *pdev,
-	struct resource **mem,
-	void **base,
-	int *irq,
-	irqreturn_t (*handler) (int, void *),
-	void *context)
-{
-	int rc = 0;
-	int mercury_irq;
-	struct resource *mercury_mem, *mercury_io, *mercury_irq_res;
-	void *mercury_base;
-	struct msm_mercury_device *pmercury_dev =
-		(struct msm_mercury_device *) context;
-
-	MCR_DBG("%s:%d]\n", __func__, __LINE__);
-
-	mercury_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!mercury_mem) {
-		MCR_PR_ERR("%s: no mem resource?\n", __func__);
-		return -ENODEV;
-	}
-
-	mercury_irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!mercury_irq_res) {
-		MCR_PR_ERR("no irq resource?\n");
-		return -ENODEV;
-	}
-	mercury_irq = mercury_irq_res->start;
-
-	mercury_io = request_mem_region(mercury_mem->start,
-		resource_size(mercury_mem), pdev->name);
-	if (!mercury_io) {
-		MCR_PR_ERR("%s: region already claimed\n", __func__);
-		return -EBUSY;
-	}
-	MCR_DBG("%s:%d]\n", __func__, __LINE__);
-	mercury_base = ioremap(mercury_mem->start,
-		resource_size(mercury_mem));
-	if (!mercury_base) {
-		rc = -ENOMEM;
-		MCR_PR_ERR("%s: ioremap failed\n", __func__);
-		goto fail1;
-	}
-	MCR_DBG("%s:%d]\n", __func__, __LINE__);
-
-	rc = msm_cam_clk_enable(&pmercury_dev->pdev->dev,
-		mercury_jpegd_clk_info, pmercury_dev->mercury_clk,
-		ARRAY_SIZE(mercury_jpegd_clk_info), 1);
-	if (rc < 0)
-		MCR_PR_ERR("%s:%d] rc = %d\n", __func__, __LINE__, rc);
-
-	MCR_DBG("%s:%d]\n", __func__, __LINE__);
-	msm_mercury_hw_init(mercury_base, resource_size(mercury_mem));
-	rc = request_irq(mercury_irq, handler, IRQF_TRIGGER_RISING,
-		"mercury", context);
-	if (rc) {
-		MCR_PR_ERR("%s: request_irq failed, %d\n", __func__,
-			mercury_irq);
-		goto fail3;
-	}
-	MCR_DBG("%s:%d]\n", __func__, __LINE__);
-	*mem  = mercury_mem;
-	*base = mercury_base;
-	*irq  = mercury_irq;
-	MCR_DBG("%s:%d]\n", __func__, __LINE__);
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	mercury_client = msm_ion_client_create(-1, "camera/mercury");
-#endif
-	MCR_PR_ERR("%s:%d] success\n", __func__, __LINE__);
-	return rc;
-fail3:
-	MCR_DBG("%s:%d]\n", __func__, __LINE__);
-	msm_cam_clk_enable(&pmercury_dev->pdev->dev, mercury_jpegd_clk_info,
-		pmercury_dev->mercury_clk,
-		ARRAY_SIZE(mercury_jpegd_clk_info), 0);
-	MCR_DBG("%s:%d]\n", __func__, __LINE__);
-	iounmap(mercury_base);
-fail1:
-	MCR_DBG("%s:%d]\n", __func__, __LINE__);
-	release_mem_region(mercury_mem->start, resource_size(mercury_mem));
-	MCR_DBG("%s:%d]\n", __func__, __LINE__);
-	return rc;
-}
-
-int msm_mercury_platform_release(struct resource *mem, void *base,
-	int irq, void *context)
-{
-	int result = 0;
-	struct msm_mercury_device *pmercury_dev =
-		(struct msm_mercury_device *) context;
-
-	free_irq(irq, context);
-	msm_cam_clk_enable(&pmercury_dev->pdev->dev, mercury_jpegd_clk_info,
-		pmercury_dev->mercury_clk, ARRAY_SIZE(mercury_jpegd_clk_info),
-		0);
-	iounmap(base);
-	release_mem_region(mem->start, resource_size(mem));
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	ion_client_destroy(mercury_client);
-#endif
-	MCR_DBG("%s:%d] success\n", __func__, __LINE__);
-	return result;
-}
-
diff --git a/drivers/media/video/msm/mercury/msm_mercury_platform.h b/drivers/media/video/msm/mercury/msm_mercury_platform.h
deleted file mode 100644
index 9edbb30..0000000
--- a/drivers/media/video/msm/mercury/msm_mercury_platform.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 MSM_MERCURY_PLATFORM_H
-#define MSM_MERCURY_PLATFORM_H
-
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/msm_ion.h>
-
-int msm_mercury_platform_clk_enable(void);
-int msm_mercury_platform_clk_disable(void);
-
-void msm_mercury_platform_p2v(struct file  *file,
-	struct ion_handle **ionhandle);
-
-uint32_t msm_mercury_platform_v2p(int fd, uint32_t len, struct file **file,
-	struct ion_handle **ionhandle);
-
-int msm_mercury_platform_init(struct platform_device *pdev,
-	struct resource **mem,
-	void **base,
-	int *irq,
-	irqreturn_t (*handler) (int, void *),
-	void *context);
-
-int msm_mercury_platform_release(struct resource *mem, void *base, int irq,
-	void *context);
-
-#endif /* MSM_MERCURY_PLATFORM_H */
diff --git a/drivers/media/video/msm/mercury/msm_mercury_sync.c b/drivers/media/video/msm/mercury/msm_mercury_sync.c
deleted file mode 100644
index 31fb8b4..0000000
--- a/drivers/media/video/msm/mercury/msm_mercury_sync.c
+++ /dev/null
@@ -1,614 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/sched.h>
-#include <linux/list.h>
-#include <linux/uaccess.h>
-#include <linux/slab.h>
-#include <media/msm_mercury.h>
-
-#include "msm_mercury_sync.h"
-#include "msm_mercury_core.h"
-#include "msm_mercury_platform.h"
-#include "msm_mercury_common.h"
-#include "msm_mercury_macros.h"
-#include "msm_mercury_hw_reg.h"
-
-static struct msm_mercury_core_buf out_buf_local;
-static struct msm_mercury_core_buf in_buf_local;
-
-/*************** queue helper ****************/
-inline void msm_mercury_q_init(char const *name, struct msm_mercury_q *q_p)
-{
-	MCR_DBG("%s:%d] %s\n", __func__, __LINE__, name);
-	q_p->name = name;
-	spin_lock_init(&q_p->lck);
-	INIT_LIST_HEAD(&q_p->q);
-	init_waitqueue_head(&q_p->wait);
-	q_p->unblck = 0;
-}
-
-inline void *msm_mercury_q_out(struct msm_mercury_q *q_p)
-{
-	unsigned long flags;
-	struct msm_mercury_q_entry *q_entry_p = NULL;
-	void *data = NULL;
-
-	MCR_DBG("(%d)%s()  %s\n", __LINE__, __func__, q_p->name);
-	spin_lock_irqsave(&q_p->lck, flags);
-	if (!list_empty(&q_p->q)) {
-		q_entry_p = list_first_entry(&q_p->q,
-			struct msm_mercury_q_entry,
-			list);
-		list_del_init(&q_entry_p->list);
-	}
-	spin_unlock_irqrestore(&q_p->lck, flags);
-
-	if (q_entry_p) {
-		data = q_entry_p->data;
-		kfree(q_entry_p);
-	} else {
-		MCR_DBG("%s:%d] %s no entry\n", __func__, __LINE__, q_p->name);
-	}
-
-	return data;
-}
-
-inline int msm_mercury_q_in(struct msm_mercury_q *q_p, void *data)
-{
-	unsigned long flags;
-
-	struct msm_mercury_q_entry *q_entry_p;
-
-	MCR_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
-
-	q_entry_p = kmalloc(sizeof(struct msm_mercury_q_entry), GFP_ATOMIC);
-	if (!q_entry_p) {
-		MCR_PR_ERR("%s: no mem\n", __func__);
-		return -EFAULT;
-	}
-	q_entry_p->data = data;
-
-	spin_lock_irqsave(&q_p->lck, flags);
-	list_add_tail(&q_entry_p->list, &q_p->q);
-	spin_unlock_irqrestore(&q_p->lck, flags);
-
-	return 0;
-}
-
-inline int msm_mercury_q_in_buf(struct msm_mercury_q *q_p,
-	struct msm_mercury_core_buf *buf)
-{
-	struct msm_mercury_core_buf *buf_p;
-
-	MCR_DBG("%s:%d]\n", __func__, __LINE__);
-	buf_p = kmalloc(sizeof(struct msm_mercury_core_buf), GFP_ATOMIC);
-	if (!buf_p) {
-		MCR_PR_ERR("%s: no mem\n", __func__);
-		return -EFAULT;
-	}
-
-	memcpy(buf_p, buf, sizeof(struct msm_mercury_core_buf));
-
-	msm_mercury_q_in(q_p, buf_p);
-	return 0;
-}
-
-inline int msm_mercury_q_wait(struct msm_mercury_q *q_p)
-{
-	int tm = MAX_SCHEDULE_TIMEOUT; /* 500ms */
-	int rc;
-
-	MCR_DBG("%s:%d %s wait\n", __func__, __LINE__, q_p->name);
-	rc = wait_event_interruptible_timeout(q_p->wait,
-		(!list_empty_careful(&q_p->q) || q_p->unblck),
-		msecs_to_jiffies(tm));
-
-	MCR_DBG("%s:%d %s wait done (rc=%d)\n", __func__,
-		__LINE__, q_p->name, rc);
-	if (list_empty_careful(&q_p->q)) {
-		if (rc == 0) {
-			rc = -ETIMEDOUT;
-			MCR_PR_ERR("%s:%d] %s timeout\n", __func__,
-				__LINE__, q_p->name);
-		} else if (q_p->unblck) {
-			MCR_DBG("%s:%d %s unblock is true", __func__,
-				__LINE__, q_p->name);
-			rc = q_p->unblck;
-			q_p->unblck = 0;
-		} else if (rc < 0) {
-			MCR_PR_ERR("%s:%d %s rc %d\n", __func__, __LINE__,
-				q_p->name, rc);
-		}
-	}
-	return rc;
-}
-
-inline int msm_mercury_q_wakeup(struct msm_mercury_q *q_p)
-{
-	MCR_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
-	wake_up(&q_p->wait);
-	return 0;
-}
-
-inline int msm_mercury_q_wr_eoi(struct msm_mercury_q *q_p)
-{
-	MCR_DBG("%s:%d] Wake up %s\n", __func__, __LINE__, q_p->name);
-	q_p->unblck = MSM_MERCURY_EVT_FRAMEDONE;
-	wake_up(&q_p->wait);
-	return 0;
-}
-
-inline int msm_mercury_q_wr_err(struct msm_mercury_q *q_p)
-{
-	MCR_DBG("%s:%d] Wake up %s\n", __func__, __LINE__, q_p->name);
-	q_p->unblck = MSM_MERCURY_EVT_ERR;
-	wake_up(&q_p->wait);
-	return 0;
-}
-
-inline int msm_mercury_q_unblock(struct msm_mercury_q *q_p)
-{
-	MCR_DBG("%s:%d] Wake up %s\n", __func__, __LINE__, q_p->name);
-	q_p->unblck = MSM_MERCURY_EVT_UNBLOCK;
-	wake_up(&q_p->wait);
-	return 0;
-}
-
-inline void msm_mercury_q_cleanup(struct msm_mercury_q *q_p)
-{
-	void *data;
-	MCR_DBG("\n%s:%d] %s\n", __func__, __LINE__, q_p->name);
-	do {
-		data = msm_mercury_q_out(q_p);
-		if (data) {
-			MCR_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
-			kfree(data);
-		}
-	} while (data);
-	q_p->unblck = 0;
-}
-
-/*************** event queue ****************/
-int msm_mercury_framedone_irq(struct msm_mercury_device *pmercury_dev)
-{
-	MCR_DBG("%s:%d] Enter\n", __func__, __LINE__);
-	msm_mercury_q_unblock(&pmercury_dev->evt_q);
-
-	MCR_DBG("%s:%d] Exit\n", __func__, __LINE__);
-	return 0;
-}
-
-int msm_mercury_evt_get(struct msm_mercury_device *pmercury_dev,
-	void __user *arg)
-{
-	struct msm_mercury_ctrl_cmd ctrl_cmd;
-	int rc = 0;
-
-	MCR_DBG("(%d)%s() Enter\n", __LINE__, __func__);
-	ctrl_cmd.type = (uint32_t)msm_mercury_q_wait(&pmercury_dev->evt_q);
-
-	rc = copy_to_user(arg, &ctrl_cmd, sizeof(ctrl_cmd));
-
-	if (rc) {
-		MCR_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
-int msm_mercury_evt_get_unblock(struct msm_mercury_device *pmercury_dev)
-{
-	MCR_DBG("--(%d)%s() Enter\n", __LINE__, __func__);
-	msm_mercury_q_unblock(&pmercury_dev->evt_q);
-	return 0;
-}
-
-int msm_mercury_output_buf_cfg(struct msm_mercury_device *pmercury_dev,
-	void __user *arg)
-{
-	struct msm_mercury_buf buf_cmd;
-
-
-	MCR_DBG("%s:%d] Enter\n", __func__, __LINE__);
-	if (copy_from_user(&buf_cmd, arg, sizeof(struct msm_mercury_buf))) {
-		MCR_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
-		return -EFAULT;
-	}
-
-	out_buf_local.y_buffer_addr = msm_mercury_platform_v2p(buf_cmd.fd,
-		buf_cmd.y_len, &out_buf_local.file, &out_buf_local.handle);
-	out_buf_local.cbcr_buffer_addr = out_buf_local.y_buffer_addr +
-		buf_cmd.y_len;
-
-	if (!out_buf_local.y_buffer_addr) {
-		MCR_PR_ERR("%s:%d] v2p wrong\n", __func__, __LINE__);
-		return -EFAULT;
-	}
-
-	msm_mercury_hw_output_y_buf_cfg(out_buf_local.y_buffer_addr);
-	msm_mercury_hw_output_u_buf_cfg(out_buf_local.cbcr_buffer_addr);
-
-	MCR_DBG("(%d)%s()\n  y_buf=0x%08X, y_len=0x%08X, vaddr=0x%08X\n"
-		"  u_buf=0x%08X, u_len=0x%08X\n\n", __LINE__, __func__,
-		out_buf_local.y_buffer_addr, buf_cmd.y_len, (int) buf_cmd.vaddr,
-		out_buf_local.cbcr_buffer_addr, buf_cmd.cbcr_len);
-
-	return 0;
-}
-
-int msm_mercury_input_buf_cfg(struct msm_mercury_device *pmercury_dev,
-	void __user *arg)
-{
-	struct msm_mercury_buf buf_cmd;
-
-
-	MCR_DBG("%s:%d] Enter\n", __func__, __LINE__);
-	if (copy_from_user(&buf_cmd, arg, sizeof(struct msm_mercury_buf))) {
-		MCR_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
-		return -EFAULT;
-	}
-
-	in_buf_local.y_buffer_addr = msm_mercury_platform_v2p(buf_cmd.fd,
-		buf_cmd.y_len, &in_buf_local.file, &in_buf_local.handle);
-
-	if (!in_buf_local.y_buffer_addr) {
-		MCR_PR_ERR("%s:%d] v2p wrong\n", __func__, __LINE__);
-		return -EFAULT;
-	}
-
-	msm_mercury_hw_bitstream_buf_cfg(in_buf_local.y_buffer_addr);
-
-	MCR_DBG("(%d)%s()\n  bitstream_buf=0x%08X, len=0x%08X, vaddr=0x%08X\n",
-		__LINE__, __func__, in_buf_local.y_buffer_addr, buf_cmd.y_len,
-		(int) buf_cmd.vaddr);
-
-	return 0;
-}
-
-int msm_mercury_output_get(struct msm_mercury_device *pmercury_dev,
-	void __user *to)
-{
-	MCR_DBG("%s:%d] Enter\n", __func__, __LINE__);
-	msm_mercury_platform_p2v(out_buf_local.file, &out_buf_local.handle);
-	return 0;
-}
-
-int msm_mercury_input_get(struct msm_mercury_device *pmercury_dev,
-	void __user *to)
-{
-
-
-	MCR_DBG("%s:%d] Enter\n", __func__, __LINE__);
-	msm_mercury_platform_p2v(in_buf_local.file, &in_buf_local.handle);
-	return 0;
-}
-
-int msm_mercury_ioctl_dump_regs(void)
-{
-	uint32_t mercury_regs[] = {
-		0x0000, 0x0008, 0x0010, 0x0014, 0x0018, 0x001C, 0x0020, 0x0024,
-		0x0030, 0x0034, 0x0040, 0x0050, 0x0054, 0x0058, 0x005C, 0x0060,
-		0x0064, 0x0070, 0x0080, 0x0084, 0x0088, 0x0258, 0x025C, 0x0260,
-		0x0264, 0x0200, 0x0204, 0x0208, 0x020C, 0x0210, 0x0214, 0x0218,
-		0x021C, 0x0220, 0x0224, 0x0228, 0x0100, 0x0104, 0x010C, 0x0110,
-		0x0114, 0x0118, 0x011C, 0x0120, 0x0124, 0x0128, 0x012C};
-
-	struct msm_mercury_hw_cmd hw_cmd;
-	int len = sizeof(mercury_regs)/4;
-	int i;
-
-	MCR_DBG("\n%s\n  (%d)%s()\n", __FILE__, __LINE__, __func__);
-
-	hw_cmd.mask = 0xFFFFFFFF;
-	hw_cmd.type = MSM_MERCURY_HW_CMD_TYPE_READ;
-	hw_cmd.n = 1;
-
-	for (i = 0; i < len; i++) {
-		hw_cmd.offset = mercury_regs[i];
-		msm_mercury_hw_exec_cmds(&hw_cmd, 1);
-	}
-
-	return 0;
-}
-
-int msm_mercury_ioctl_magic_code(struct msm_mercury_device *pmercury_dev,
-	void * __user arg)
-{
-	struct msm_mercury_hw_cmd hw_cmd;
-	int rc = 0;
-
-	rc = copy_from_user(&hw_cmd, arg, sizeof(struct msm_mercury_hw_cmd));
-	if (rc) {
-		printk(KERN_ERR "%s:%d] failed\n", __func__, __LINE__);
-		return -EFAULT;
-	}
-
-	hw_cmd.data = 0x600D600D;
-	rc = copy_to_user(arg, &hw_cmd, sizeof(hw_cmd));
-
-	if (rc) {
-		printk(KERN_ERR "%s:%d] failed\n", __func__, __LINE__);
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
-int msm_mercury_irq(int event, void *context, void *data)
-{
-	struct msm_mercury_device *pmercury_dev =
-		(struct msm_mercury_device *) context;
-
-	switch (event) {
-	case MSM_MERCURY_HW_IRQ_SW_RESET_ACK:
-		/* wake up evt_q*/
-		MCR_DBG("(%d)%s Wake up event q from Reset IRQ\n", __LINE__,
-			__func__);
-		msm_mercury_q_wakeup(&pmercury_dev->evt_q);
-		break;
-	case MSM_MERCURY_HW_IRQ_WR_EOI_ACK:
-		/*wake up evt_q*/
-		MCR_DBG("%d%s Wake up eventq from WR_EOI IRQ\n", __LINE__,
-			__func__);
-		msm_mercury_q_wr_eoi(&pmercury_dev->evt_q);
-		break;
-	case MSM_MERCURY_HW_IRQ_WR_ERR_ACK:
-		MCR_DBG("(%d)%s Wake up eventq from WR_ERR IRQ\n",
-			__LINE__, __func__);
-		msm_mercury_q_wr_err(&pmercury_dev->evt_q);
-		break;
-	default:
-		MCR_DBG("(%d)%s (default) Wake up event q from WR_ERR IRQ\n",
-			__LINE__, __func__);
-		msm_mercury_q_wr_err(&pmercury_dev->evt_q);
-	}
-	return 0;
-}
-
-int __msm_mercury_open(struct msm_mercury_device *pmercury_dev)
-{
-	int rc = 0;
-
-	mutex_lock(&pmercury_dev->lock);
-	if (pmercury_dev->open_count) {
-		/* only open once */
-		MCR_PR_ERR("%s:%d] busy\n", __func__, __LINE__);
-		mutex_unlock(&pmercury_dev->lock);
-		return -EBUSY;
-	}
-	pmercury_dev->open_count++;
-	mutex_unlock(&pmercury_dev->lock);
-
-	msm_mercury_core_irq_install(msm_mercury_irq);
-
-	rc = msm_mercury_platform_init(pmercury_dev->pdev,
-		&pmercury_dev->mem, &pmercury_dev->base,
-		&pmercury_dev->irq, msm_mercury_core_irq, pmercury_dev);
-	if (rc) {
-		MCR_PR_ERR("%s:%d] platform_init fail %d\n", __func__,
-			__LINE__, rc);
-		return rc;
-	}
-
-	MCR_DBG("\n%s:%d] platform resources - mem 0x%p, base 0x%p, irq %d\n",
-		__func__, __LINE__, pmercury_dev->mem, pmercury_dev->base,
-		pmercury_dev->irq);
-
-	msm_mercury_q_cleanup(&pmercury_dev->evt_q);
-	msm_mercury_core_init();
-
-	MCR_DBG("\n%s:%d] success\n", __func__, __LINE__);
-	return rc;
-}
-
-int __msm_mercury_release(struct msm_mercury_device *pmercury_dev)
-{
-	MCR_DBG("%s:%d] Enter\n", __func__, __LINE__);
-	mutex_lock(&pmercury_dev->lock);
-	if (!pmercury_dev->open_count) {
-		MCR_PR_ERR(KERN_ERR "%s: not opened\n", __func__);
-		mutex_unlock(&pmercury_dev->lock);
-		return -EINVAL;
-	}
-	pmercury_dev->open_count--;
-	mutex_unlock(&pmercury_dev->lock);
-
-	msm_mercury_q_cleanup(&pmercury_dev->evt_q);
-
-	if (pmercury_dev->open_count)
-		MCR_PR_ERR(KERN_ERR "%s: multiple opens\n", __func__);
-
-	if (pmercury_dev->open_count)
-		MCR_PR_ERR(KERN_ERR "%s: multiple opens\n", __func__);
-
-
-	msm_mercury_platform_release(pmercury_dev->mem, pmercury_dev->base,
-		pmercury_dev->irq, pmercury_dev);
-
-	return 0;
-}
-
-int msm_mercury_ioctl_hw_cmd(struct msm_mercury_device *pmercury_dev,
-	void * __user arg)
-{
-	struct msm_mercury_hw_cmd hw_cmd;
-	int is_copy_to_user;
-	int rc = 0;
-
-	rc = copy_from_user(&hw_cmd, arg, sizeof(struct msm_mercury_hw_cmd));
-	if (rc) {
-		MCR_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
-		return -EFAULT;
-	}
-
-	is_copy_to_user = msm_mercury_hw_exec_cmds(&hw_cmd, 1);
-	if (is_copy_to_user >= 0) {
-		rc = copy_to_user(arg, &hw_cmd, sizeof(hw_cmd));
-
-		if (rc) {
-			MCR_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
-			return -EFAULT;
-		}
-	}
-
-	return 0;
-}
-
-int msm_mercury_ioctl_hw_cmds(struct msm_mercury_device *pmercury_dev,
-	void * __user arg)
-{
-	int is_copy_to_user;
-	int len;
-	uint32_t m;
-	struct msm_mercury_hw_cmds *hw_cmds_p;
-	struct msm_mercury_hw_cmd *hw_cmd_p;
-
-	if (copy_from_user(&m, arg, sizeof(m))) {
-		MCR_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
-		return -EFAULT;
-	}
-
-	len = sizeof(struct msm_mercury_hw_cmds) +
-		sizeof(struct msm_mercury_hw_cmd) * (m - 1);
-	hw_cmds_p = kmalloc(len, GFP_KERNEL);
-	if (!hw_cmds_p) {
-		MCR_PR_ERR("[%d]%s() no mem %d\n", __LINE__, __func__, len);
-		return -EFAULT;
-	}
-
-	if (copy_from_user(hw_cmds_p, arg, len)) {
-		MCR_PR_ERR("[%d]%s Fail to copy hw_cmds of len %d from user\n",
-			__LINE__, __func__, len);
-		kfree(hw_cmds_p);
-		return -EFAULT;
-	}
-
-	hw_cmd_p = (struct msm_mercury_hw_cmd *) &(hw_cmds_p->hw_cmd);
-
-	is_copy_to_user = msm_mercury_hw_exec_cmds(hw_cmd_p, m);
-
-	if (is_copy_to_user >= 0) {
-		if (copy_to_user(arg, hw_cmds_p, len)) {
-			MCR_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
-			kfree(hw_cmds_p);
-			return -EFAULT;
-		}
-	}
-	kfree(hw_cmds_p);
-	return 0;
-}
-
-int msm_mercury_ioctl_reset(struct msm_mercury_device *pmercury_dev,
-	void * __user arg)
-{
-	int rc = 0;
-
-	MCR_DBG("(%d)%s() Enter\n", __LINE__, __func__);
-	rc = msm_mercury_core_reset();
-
-	return rc;
-}
-
-long __msm_mercury_ioctl(struct msm_mercury_device *pmercury_dev,
-	unsigned int cmd, unsigned long arg)
-{
-	int rc = 0;
-
-	switch (cmd) {
-	case MSM_MCR_IOCTL_GET_HW_VERSION:
-		rc = msm_mercury_ioctl_magic_code(pmercury_dev,
-			(void __user *) arg);
-		break;
-
-	case MSM_MCR_IOCTL_RESET:
-		rc = msm_mercury_ioctl_reset(pmercury_dev, (void __user *) arg);
-		break;
-
-	case MSM_MCR_IOCTL_EVT_GET:
-		rc = msm_mercury_evt_get(pmercury_dev, (void __user *) arg);
-		break;
-
-	case MSM_MCR_IOCTL_EVT_GET_UNBLOCK:
-		rc = msm_mercury_evt_get_unblock(pmercury_dev);
-		break;
-
-	case MSM_MCR_IOCTL_HW_CMD:
-		rc = msm_mercury_ioctl_hw_cmd(pmercury_dev,
-			(void __user *) arg);
-		break;
-
-	case MSM_MCR_IOCTL_HW_CMDS:
-		rc = msm_mercury_ioctl_hw_cmds(pmercury_dev,
-			(void __user *) arg);
-		break;
-
-	case MSM_MCR_IOCTL_INPUT_BUF_CFG:
-		rc = msm_mercury_input_buf_cfg(pmercury_dev,
-			(void __user *) arg);
-		break;
-
-	case MSM_MCR_IOCTL_OUTPUT_BUF_CFG:
-		rc = msm_mercury_output_buf_cfg(pmercury_dev,
-			(void __user *) arg);
-		break;
-
-	case MSM_MCR_IOCTL_OUTPUT_GET:
-		rc = msm_mercury_output_get(pmercury_dev,
-			(void __user *) arg);
-		break;
-
-	case MSM_MCR_IOCTL_INPUT_GET:
-		rc = msm_mercury_input_get(pmercury_dev,
-			(void __user *) arg);
-		break;
-
-	case MSM_MCR_IOCTL_TEST_DUMP_REGION:
-		rc = msm_mercury_ioctl_dump_regs();
-		break;
-
-	default:
-		printk(KERN_ERR "(%d)%s()  cmd = %d not supported\n",
-			__LINE__, __func__, _IOC_NR(cmd));
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
-
-struct msm_mercury_device *__msm_mercury_init(struct platform_device *pdev)
-{
-	struct msm_mercury_device *pmercury_dev;
-	pmercury_dev = kzalloc(sizeof(struct msm_mercury_device), GFP_ATOMIC);
-	if (!pmercury_dev) {
-		printk(KERN_ERR "%s:%d]no mem\n", __func__, __LINE__);
-		return NULL;
-	}
-
-	mutex_init(&pmercury_dev->lock);
-
-	pmercury_dev->pdev = pdev;
-
-	msm_mercury_q_init("evt_q", &pmercury_dev->evt_q);
-
-	return pmercury_dev;
-}
-
-int __msm_mercury_exit(struct msm_mercury_device *pmercury_dev)
-{
-	mutex_destroy(&pmercury_dev->lock);
-	kfree(pmercury_dev);
-	return 0;
-}
-
diff --git a/drivers/media/video/msm/mercury/msm_mercury_sync.h b/drivers/media/video/msm/mercury/msm_mercury_sync.h
deleted file mode 100644
index f392907..0000000
--- a/drivers/media/video/msm/mercury/msm_mercury_sync.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 MSM_MERCURY_SYNC_H
-#define MSM_MERCURY_SYNC_H
-
-#include <linux/fs.h>
-#include <linux/list.h>
-#include <linux/cdev.h>
-#include <linux/platform_device.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-#include "msm_mercury_core.h"
-
-struct msm_mercury_q {
-		char const  *name;
-		struct list_head  q;
-		spinlock_t  lck;
-		wait_queue_head_t wait;
-		int        unblck;
-};
-
-struct msm_mercury_q_entry {
-		struct list_head list;
-		void   *data;
-};
-
-struct msm_mercury_device {
-		struct platform_device *pdev;
-		struct resource        *mem;
-		int                     irq;
-		void                   *base;
-		struct clk *mercury_clk[2];
-		struct device *device;
-		struct cdev   cdev;
-		struct mutex  lock;
-		char      open_count;
-		uint8_t       op_mode;
-
-		/* event queue including frame done & err indications*/
-		struct msm_mercury_q evt_q;
-		struct v4l2_subdev subdev;
-
-};
-
-int __msm_mercury_open(struct msm_mercury_device *pmcry_dev);
-int __msm_mercury_release(struct msm_mercury_device *pmcry_dev);
-
-long __msm_mercury_ioctl(struct msm_mercury_device *pmcry_dev,
-	unsigned int cmd, unsigned long arg);
-
-struct msm_mercury_device *__msm_mercury_init(struct platform_device *pdev);
-int __msm_mercury_exit(struct msm_mercury_device *pmcry_dev);
-int msm_mercury_ioctl_hw_cmds(struct msm_mercury_device *pmcry_dev,
-	void * __user arg);
-int msm_mercury_ioctl_hw_cmds_wo(struct msm_mercury_device *pmcry_dev,
-	void * __user arg);
-#endif /* MSM_MERCURY_SYNC_H */
diff --git a/drivers/media/video/msm/msm_axi_qos.c b/drivers/media/video/msm/msm_axi_qos.c
deleted file mode 100644
index eaceceb..0000000
--- a/drivers/media/video/msm/msm_axi_qos.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Copyright (c) 2009, Code Aurora Forum. 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/clk.h>
-#include <mach/camera.h>
-#define MSM_AXI_QOS_NAME "msm_camera"
-
-static struct clk *ebi1_clk;
-
-int add_axi_qos(void)
-{
-	ebi1_clk = clk_get(NULL, "ebi1_vfe_clk");
-	if (IS_ERR(ebi1_clk))
-		ebi1_clk = NULL;
-	else {
-		clk_prepare(ebi1_clk);
-		clk_enable(ebi1_clk);
-	}
-
-	return 0;
-}
-
-int update_axi_qos(uint32_t rate)
-{
-	if (!ebi1_clk)
-		return 0;
-
-	return clk_set_rate(ebi1_clk, rate * 1000);
-}
-
-void release_axi_qos(void)
-{
-	if (!ebi1_clk)
-		return;
-
-	clk_disable(ebi1_clk);
-	clk_unprepare(ebi1_clk);
-	clk_put(ebi1_clk);
-	ebi1_clk = NULL;
-}
diff --git a/drivers/media/video/msm/msm_camera.c b/drivers/media/video/msm/msm_camera.c
deleted file mode 100644
index c40711d..0000000
--- a/drivers/media/video/msm/msm_camera.c
+++ /dev/null
@@ -1,4073 +0,0 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. 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.
- *
- */
-//FIXME: most allocations need not be GFP_ATOMIC
-/* FIXME: management of mutexes */
-/* FIXME: msm_pmem_region_lookup return values */
-/* FIXME: way too many copy to/from user */
-/* FIXME: does region->active mean free */
-/* FIXME: check limits on command lenghts passed from userspace */
-/* FIXME: __msm_release: which queues should we flush when opencnt != 0 */
-
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <mach/board.h>
-
-#include <linux/uaccess.h>
-#include <linux/fs.h>
-#include <linux/list.h>
-#include <linux/uaccess.h>
-#include <linux/android_pmem.h>
-#include <linux/poll.h>
-#include <media/msm_camera.h>
-#include <mach/camera.h>
-#include <linux/syscalls.h>
-#include <linux/hrtimer.h>
-#include <linux/msm_ion.h>
-
-#include <mach/cpuidle.h>
-DEFINE_MUTEX(ctrl_cmd_lock);
-
-#define CAMERA_STOP_VIDEO 58
-spinlock_t pp_prev_spinlock;
-spinlock_t pp_stereocam_spinlock;
-spinlock_t st_frame_spinlock;
-
-#define ERR_USER_COPY(to) pr_err("%s(%d): copy %s user\n", \
-				__func__, __LINE__, ((to) ? "to" : "from"))
-#define ERR_COPY_FROM_USER() ERR_USER_COPY(0)
-#define ERR_COPY_TO_USER() ERR_USER_COPY(1)
-#define MAX_PMEM_CFG_BUFFERS 10
-
-static struct class *msm_class;
-static dev_t msm_devno;
-static LIST_HEAD(msm_sensors);
-struct  msm_control_device *g_v4l2_control_device;
-int g_v4l2_opencnt;
-static int camera_node;
-static enum msm_camera_type camera_type[MSM_MAX_CAMERA_SENSORS];
-static uint32_t sensor_mount_angle[MSM_MAX_CAMERA_SENSORS];
-
-struct ion_client *client_for_ion;
-
-static const char *vfe_config_cmd[] = {
-	"CMD_GENERAL",  /* 0 */
-	"CMD_AXI_CFG_OUT1",
-	"CMD_AXI_CFG_SNAP_O1_AND_O2",
-	"CMD_AXI_CFG_OUT2",
-	"CMD_PICT_T_AXI_CFG",
-	"CMD_PICT_M_AXI_CFG",  /* 5 */
-	"CMD_RAW_PICT_AXI_CFG",
-	"CMD_FRAME_BUF_RELEASE",
-	"CMD_PREV_BUF_CFG",
-	"CMD_SNAP_BUF_RELEASE",
-	"CMD_SNAP_BUF_CFG",  /* 10 */
-	"CMD_STATS_DISABLE",
-	"CMD_STATS_AEC_AWB_ENABLE",
-	"CMD_STATS_AF_ENABLE",
-	"CMD_STATS_AEC_ENABLE",
-	"CMD_STATS_AWB_ENABLE",  /* 15 */
-	"CMD_STATS_ENABLE",
-	"CMD_STATS_AXI_CFG",
-	"CMD_STATS_AEC_AXI_CFG",
-	"CMD_STATS_AF_AXI_CFG",
-	"CMD_STATS_AWB_AXI_CFG",  /* 20 */
-	"CMD_STATS_RS_AXI_CFG",
-	"CMD_STATS_CS_AXI_CFG",
-	"CMD_STATS_IHIST_AXI_CFG",
-	"CMD_STATS_SKIN_AXI_CFG",
-	"CMD_STATS_BUF_RELEASE",  /* 25 */
-	"CMD_STATS_AEC_BUF_RELEASE",
-	"CMD_STATS_AF_BUF_RELEASE",
-	"CMD_STATS_AWB_BUF_RELEASE",
-	"CMD_STATS_RS_BUF_RELEASE",
-	"CMD_STATS_CS_BUF_RELEASE",  /* 30 */
-	"CMD_STATS_IHIST_BUF_RELEASE",
-	"CMD_STATS_SKIN_BUF_RELEASE",
-	"UPDATE_STATS_INVALID",
-	"CMD_AXI_CFG_SNAP_GEMINI",
-	"CMD_AXI_CFG_SNAP",  /* 35 */
-	"CMD_AXI_CFG_PREVIEW",
-	"CMD_AXI_CFG_VIDEO",
-	"CMD_STATS_IHIST_ENABLE",
-	"CMD_STATS_RS_ENABLE",
-	"CMD_STATS_CS_ENABLE",  /* 40 */
-	"CMD_VPE",
-	"CMD_AXI_CFG_VPE",
-	"CMD_AXI_CFG_SNAP_VPE",
-	"CMD_AXI_CFG_SNAP_THUMB_VPE",
-};
-#define __CONTAINS(r, v, l, field) ({				\
-	typeof(r) __r = r;					\
-	typeof(v) __v = v;					\
-	typeof(v) __e = __v + l;				\
-	int res = __v >= __r->field &&				\
-		__e <= __r->field + __r->len;			\
-	res;							\
-})
-
-#define CONTAINS(r1, r2, field) ({				\
-	typeof(r2) __r2 = r2;					\
-	__CONTAINS(r1, __r2->field, __r2->len, field);		\
-})
-
-#define IN_RANGE(r, v, field) ({				\
-	typeof(r) __r = r;					\
-	typeof(v) __vv = v;					\
-	int res = ((__vv >= __r->field) &&			\
-		(__vv < (__r->field + __r->len)));		\
-	res;							\
-})
-
-#define OVERLAPS(r1, r2, field) ({				\
-	typeof(r1) __r1 = r1;					\
-	typeof(r2) __r2 = r2;					\
-	typeof(__r2->field) __v = __r2->field;			\
-	typeof(__v) __e = __v + __r2->len - 1;			\
-	int res = (IN_RANGE(__r1, __v, field) ||		\
-		   IN_RANGE(__r1, __e, field));                 \
-	res;							\
-})
-
-static inline void free_qcmd(struct msm_queue_cmd *qcmd)
-{
-	if (!qcmd || !atomic_read(&qcmd->on_heap))
-		return;
-	if (!atomic_sub_return(1, &qcmd->on_heap))
-		kfree(qcmd);
-}
-
-static void msm_region_init(struct msm_sync *sync)
-{
-	INIT_HLIST_HEAD(&sync->pmem_frames);
-	INIT_HLIST_HEAD(&sync->pmem_stats);
-	spin_lock_init(&sync->pmem_frame_spinlock);
-	spin_lock_init(&sync->pmem_stats_spinlock);
-}
-
-static void msm_queue_init(struct msm_device_queue *queue, const char *name)
-{
-	spin_lock_init(&queue->lock);
-	queue->len = 0;
-	queue->max = 0;
-	queue->name = name;
-	INIT_LIST_HEAD(&queue->list);
-	init_waitqueue_head(&queue->wait);
-}
-
-static void msm_enqueue(struct msm_device_queue *queue,
-		struct list_head *entry)
-{
-	unsigned long flags;
-	spin_lock_irqsave(&queue->lock, flags);
-	queue->len++;
-	if (queue->len > queue->max) {
-		queue->max = queue->len;
-		CDBG("%s: queue %s new max is %d\n", __func__,
-			queue->name, queue->max);
-	}
-	list_add_tail(entry, &queue->list);
-	wake_up(&queue->wait);
-	CDBG("%s: woke up %s\n", __func__, queue->name);
-	spin_unlock_irqrestore(&queue->lock, flags);
-}
-
-static void msm_enqueue_vpe(struct msm_device_queue *queue,
-		struct list_head *entry)
-{
-	unsigned long flags;
-	spin_lock_irqsave(&queue->lock, flags);
-	queue->len++;
-	if (queue->len > queue->max) {
-		queue->max = queue->len;
-		CDBG("%s: queue %s new max is %d\n", __func__,
-			queue->name, queue->max);
-	}
-	list_add_tail(entry, &queue->list);
-    CDBG("%s: woke up %s\n", __func__, queue->name);
-	spin_unlock_irqrestore(&queue->lock, flags);
-}
-
-#define msm_dequeue(queue, member) ({				\
-	unsigned long flags;					\
-	struct msm_device_queue *__q = (queue);			\
-	struct msm_queue_cmd *qcmd = 0;				\
-	spin_lock_irqsave(&__q->lock, flags);			\
-	if (!list_empty(&__q->list)) {				\
-		__q->len--;					\
-		qcmd = list_first_entry(&__q->list,		\
-				struct msm_queue_cmd, member);	\
-		if ((qcmd) && (&qcmd->member) && (&qcmd->member.next))	\
-			list_del_init(&qcmd->member);			\
-	}							\
-	spin_unlock_irqrestore(&__q->lock, flags);	\
-	qcmd;							\
-})
-
-#define msm_delete_entry(queue, member, q_cmd) ({		\
-	unsigned long flags;					\
-	struct msm_device_queue *__q = (queue);			\
-	struct msm_queue_cmd *qcmd = 0;				\
-	spin_lock_irqsave(&__q->lock, flags);			\
-	if (!list_empty(&__q->list)) {				\
-		list_for_each_entry(qcmd, &__q->list, member)	\
-		if (qcmd == q_cmd) {				\
-			__q->len--;				\
-			list_del_init(&qcmd->member);		\
-			CDBG("msm_delete_entry, match found\n");\
-			kfree(q_cmd);				\
-			q_cmd = NULL;				\
-			break;					\
-		}						\
-	}							\
-	spin_unlock_irqrestore(&__q->lock, flags);		\
-	q_cmd;		\
-})
-
-#define msm_queue_drain(queue, member) do {			\
-	unsigned long flags;					\
-	struct msm_device_queue *__q = (queue);			\
-	struct msm_queue_cmd *qcmd;				\
-	spin_lock_irqsave(&__q->lock, flags);			\
-	while (!list_empty(&__q->list)) {			\
-		__q->len--;					\
-		qcmd = list_first_entry(&__q->list,		\
-			struct msm_queue_cmd, member);		\
-		if (qcmd) {					\
-			if (&qcmd->member)	\
-				list_del_init(&qcmd->member);		\
-			free_qcmd(qcmd);				\
-		}							\
-	}							\
-	spin_unlock_irqrestore(&__q->lock, flags);		\
-} while (0)
-
-static int check_overlap(struct hlist_head *ptype,
-			unsigned long paddr,
-			unsigned long len)
-{
-	struct msm_pmem_region *region;
-	struct msm_pmem_region t = { .paddr = paddr, .len = len };
-	struct hlist_node *node;
-
-	hlist_for_each_entry(region, node, ptype, list) {
-		if (CONTAINS(region, &t, paddr) ||
-				CONTAINS(&t, region, paddr) ||
-				OVERLAPS(region, &t, paddr)) {
-			CDBG(" region (PHYS %p len %ld)"
-				" clashes with registered region"
-				" (paddr %p len %ld)\n",
-				(void *)t.paddr, t.len,
-				(void *)region->paddr, region->len);
-			return -1;
-		}
-	}
-
-	return 0;
-}
-
-static int check_pmem_info(struct msm_pmem_info *info, int len)
-{
-	if (info->offset < len &&
-	    info->offset + info->len <= len &&
-	    info->planar0_off < len &&
-	    info->planar1_off < len &&
-	    info->planar2_off < len)
-		return 0;
-
-	pr_err("%s: check failed: off %d len %d y 0x%x cbcr_p1 0x%x p2_add 0x%x(total len %d)\n",
-		__func__,
-		info->offset,
-		info->len,
-		info->planar0_off,
-		info->planar1_off,
-		info->planar2_off,
-		len);
-	return -EINVAL;
-}
-static int msm_pmem_table_add(struct hlist_head *ptype,
-	struct msm_pmem_info *info, spinlock_t* pmem_spinlock,
-	struct msm_sync *sync)
-{
-	unsigned long paddr;
-#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
-	struct file *file;
-	unsigned long kvstart;
-#endif
-	unsigned long len;
-	int rc = -ENOMEM;
-	struct msm_pmem_region *region;
-	unsigned long flags;
-
-	region = kmalloc(sizeof(struct msm_pmem_region), GFP_KERNEL);
-	if (!region)
-		goto out;
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-		region->handle = ion_import_dma_buf(client_for_ion, info->fd);
-		if (IS_ERR_OR_NULL(region->handle))
-			goto out1;
-		ion_phys(client_for_ion, region->handle,
-			&paddr, (size_t *)&len);
-#else
-	rc = get_pmem_file(info->fd, &paddr, &kvstart, &len, &file);
-	if (rc < 0) {
-		pr_err("%s: get_pmem_file fd %d error %d\n",
-			__func__,
-			info->fd, rc);
-		goto out1;
-	}
-	region->file = file;
-#endif
-	if (!info->len)
-		info->len = len;
-
-	rc = check_pmem_info(info, len);
-	if (rc < 0)
-		goto out2;
-
-	paddr += info->offset;
-	len = info->len;
-
-	spin_lock_irqsave(pmem_spinlock, flags);
-	if (check_overlap(ptype, paddr, len) < 0) {
-		spin_unlock_irqrestore(pmem_spinlock, flags);
-		rc = -EINVAL;
-		goto out2;
-	}
-	spin_unlock_irqrestore(pmem_spinlock, flags);
-
-	spin_lock_irqsave(pmem_spinlock, flags);
-	INIT_HLIST_NODE(&region->list);
-
-	region->paddr = paddr;
-	region->len = len;
-	memcpy(&region->info, info, sizeof(region->info));
-
-	hlist_add_head(&(region->list), ptype);
-	spin_unlock_irqrestore(pmem_spinlock, flags);
-	CDBG("%s: type %d, paddr 0x%lx, vaddr 0x%lx p0_add = 0x%x"
-		"p1_addr = 0x%x p2_addr = 0x%x\n",
-		__func__, info->type, paddr, (unsigned long)info->vaddr,
-		info->planar0_off, info->planar1_off, info->planar2_off);
-	return 0;
-out2:
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	ion_free(client_for_ion, region->handle);
-#else
-	put_pmem_file(region->file);
-#endif
-out1:
-	kfree(region);
-out:
-	return rc;
-}
-
-/* return of 0 means failure */
-static uint8_t msm_pmem_region_lookup(struct hlist_head *ptype,
-	int pmem_type, struct msm_pmem_region *reg, uint8_t maxcount,
-	spinlock_t *pmem_spinlock)
-{
-	struct msm_pmem_region *region;
-	struct msm_pmem_region *regptr;
-	struct hlist_node *node, *n;
-	unsigned long flags = 0;
-
-	uint8_t rc = 0;
-
-	regptr = reg;
-	spin_lock_irqsave(pmem_spinlock, flags);
-	hlist_for_each_entry_safe(region, node, n, ptype, list) {
-		if (region->info.type == pmem_type && region->info.active) {
-			*regptr = *region;
-			rc += 1;
-			if (rc >= maxcount)
-				break;
-			regptr++;
-		}
-	}
-	spin_unlock_irqrestore(pmem_spinlock, flags);
-	/* After lookup failure, dump all the list entries...*/
-	if (rc == 0) {
-		pr_err("%s: pmem_type = %d\n", __func__, pmem_type);
-		hlist_for_each_entry_safe(region, node, n, ptype, list) {
-			pr_err("listed region->info.type = %d, active = %d",
-				region->info.type, region->info.active);
-		}
-
-	}
-	return rc;
-}
-
-static uint8_t msm_pmem_region_lookup_2(struct hlist_head *ptype,
-					int pmem_type,
-					struct msm_pmem_region *reg,
-					uint8_t maxcount,
-					spinlock_t *pmem_spinlock)
-{
-	struct msm_pmem_region *region;
-	struct msm_pmem_region *regptr;
-	struct hlist_node *node, *n;
-	uint8_t rc = 0;
-	unsigned long flags = 0;
-	regptr = reg;
-	spin_lock_irqsave(pmem_spinlock, flags);
-	hlist_for_each_entry_safe(region, node, n, ptype, list) {
-		CDBG("%s:info.type=%d, pmem_type = %d,"
-						"info.active = %d\n",
-		__func__, region->info.type, pmem_type, region->info.active);
-
-		if (region->info.type == pmem_type && region->info.active) {
-			CDBG("%s:info.type=%d, pmem_type = %d,"
-							"info.active = %d,\n",
-				__func__, region->info.type, pmem_type,
-				region->info.active);
-			*regptr = *region;
-			region->info.type = MSM_PMEM_VIDEO;
-			rc += 1;
-			if (rc >= maxcount)
-				break;
-			regptr++;
-		}
-	}
-	spin_unlock_irqrestore(pmem_spinlock, flags);
-	return rc;
-}
-
-static int msm_pmem_frame_ptov_lookup(struct msm_sync *sync,
-		unsigned long p0addr,
-		unsigned long p1addr,
-		unsigned long p2addr,
-		struct msm_pmem_info *pmem_info,
-		int clear_active)
-{
-	struct msm_pmem_region *region;
-	struct hlist_node *node, *n;
-	unsigned long flags = 0;
-
-	spin_lock_irqsave(&sync->pmem_frame_spinlock, flags);
-	hlist_for_each_entry_safe(region, node, n, &sync->pmem_frames, list) {
-		if (p0addr == (region->paddr + region->info.planar0_off) &&
-			p1addr == (region->paddr + region->info.planar1_off) &&
-			p2addr == (region->paddr + region->info.planar2_off) &&
-			region->info.active) {
-			/* offset since we could pass vaddr inside
-			 * a registerd pmem buffer
-			 */
-			memcpy(pmem_info, &region->info, sizeof(*pmem_info));
-			if (clear_active)
-				region->info.active = 0;
-			spin_unlock_irqrestore(&sync->pmem_frame_spinlock,
-				flags);
-			return 0;
-		}
-	}
-	/* After lookup failure, dump all the list entries... */
-	pr_err("%s, for plane0 addr = 0x%lx, plane1 addr = 0x%lx  plane2 addr = 0x%lx\n",
-			__func__, p0addr, p1addr, p2addr);
-	hlist_for_each_entry_safe(region, node, n, &sync->pmem_frames, list) {
-		pr_err("listed p0addr 0x%lx, p1addr 0x%lx, p2addr 0x%lx, active = %d",
-				(region->paddr + region->info.planar0_off),
-				(region->paddr + region->info.planar1_off),
-				(region->paddr + region->info.planar2_off),
-				region->info.active);
-	}
-
-	spin_unlock_irqrestore(&sync->pmem_frame_spinlock, flags);
-	return -EINVAL;
-}
-
-static int msm_pmem_frame_ptov_lookup2(struct msm_sync *sync,
-		unsigned long p0_phy,
-		struct msm_pmem_info *pmem_info,
-		int clear_active)
-{
-	struct msm_pmem_region *region;
-	struct hlist_node *node, *n;
-	unsigned long flags = 0;
-
-	spin_lock_irqsave(&sync->pmem_frame_spinlock, flags);
-	hlist_for_each_entry_safe(region, node, n, &sync->pmem_frames, list) {
-		if (p0_phy == (region->paddr + region->info.planar0_off) &&
-				region->info.active) {
-			/* offset since we could pass vaddr inside
-			 * a registerd pmem buffer
-			 */
-			memcpy(pmem_info, &region->info, sizeof(*pmem_info));
-			if (clear_active)
-				region->info.active = 0;
-			spin_unlock_irqrestore(&sync->pmem_frame_spinlock,
-				flags);
-			return 0;
-		}
-	}
-
-	spin_unlock_irqrestore(&sync->pmem_frame_spinlock, flags);
-	return -EINVAL;
-}
-
-static unsigned long msm_pmem_stats_ptov_lookup(struct msm_sync *sync,
-		unsigned long addr, int *fd)
-{
-	struct msm_pmem_region *region;
-	struct hlist_node *node, *n;
-	unsigned long flags = 0;
-
-	spin_lock_irqsave(&sync->pmem_stats_spinlock, flags);
-	hlist_for_each_entry_safe(region, node, n, &sync->pmem_stats, list) {
-		if (addr == region->paddr && region->info.active) {
-			/* offset since we could pass vaddr inside a
-			 * registered pmem buffer */
-			*fd = region->info.fd;
-			region->info.active = 0;
-			spin_unlock_irqrestore(&sync->pmem_stats_spinlock,
-				flags);
-			return (unsigned long)(region->info.vaddr);
-		}
-	}
-	/* After lookup failure, dump all the list entries... */
-	pr_err("%s, lookup failure, for paddr 0x%lx\n",
-			__func__, addr);
-	hlist_for_each_entry_safe(region, node, n, &sync->pmem_stats, list) {
-		pr_err("listed paddr 0x%lx, active = %d",
-				region->paddr,
-				region->info.active);
-	}
-	spin_unlock_irqrestore(&sync->pmem_stats_spinlock, flags);
-
-	return 0;
-}
-
-static unsigned long msm_pmem_frame_vtop_lookup(struct msm_sync *sync,
-		unsigned long buffer, uint32_t p0_off, uint32_t p1_off,
-		uint32_t p2_off, int fd, int change_flag)
-{
-	struct msm_pmem_region *region;
-	struct hlist_node *node, *n;
-	unsigned long flags = 0;
-
-	spin_lock_irqsave(&sync->pmem_frame_spinlock, flags);
-	hlist_for_each_entry_safe(region,
-		node, n, &sync->pmem_frames, list) {
-		if (((unsigned long)(region->info.vaddr) == buffer) &&
-				(region->info.planar0_off == p0_off) &&
-				(region->info.planar1_off == p1_off) &&
-				(region->info.planar2_off == p2_off) &&
-				(region->info.fd == fd) &&
-				(region->info.active == 0)) {
-			if (change_flag)
-				region->info.active = 1;
-			spin_unlock_irqrestore(&sync->pmem_frame_spinlock,
-				flags);
-			return region->paddr;
-		}
-	}
-	/* After lookup failure, dump all the list entries... */
-	pr_err("%s, failed for vaddr 0x%lx, p0_off %d p1_off %d\n",
-			__func__, buffer, p0_off, p1_off);
-	hlist_for_each_entry_safe(region, node, n, &sync->pmem_frames, list) {
-		pr_err("%s, listed vaddr 0x%lx, r_p0 = 0x%x p0_off 0x%x"
-			"r_p1 = 0x%x, p1_off 0x%x, r_p2 = 0x%x, p2_off = 0x%x"
-			" active = %d\n", __func__, buffer,
-			region->info.planar0_off,
-			p0_off, region->info.planar1_off,
-			p1_off, region->info.planar2_off, p2_off,
-			region->info.active);
-	}
-
-	spin_unlock_irqrestore(&sync->pmem_frame_spinlock, flags);
-
-	return 0;
-}
-
-static unsigned long msm_pmem_stats_vtop_lookup(
-		struct msm_sync *sync,
-		unsigned long buffer,
-		int fd)
-{
-	struct msm_pmem_region *region;
-	struct hlist_node *node, *n;
-	unsigned long flags = 0;
-
-	spin_lock_irqsave(&sync->pmem_stats_spinlock, flags);
-	hlist_for_each_entry_safe(region, node, n, &sync->pmem_stats, list) {
-		if (((unsigned long)(region->info.vaddr) == buffer) &&
-				(region->info.fd == fd) &&
-				region->info.active == 0) {
-			region->info.active = 1;
-			spin_unlock_irqrestore(&sync->pmem_stats_spinlock,
-				flags);
-			return region->paddr;
-		}
-	}
-	/* After lookup failure, dump all the list entries... */
-	pr_err("%s,look up error for vaddr %ld\n",
-			__func__, buffer);
-	hlist_for_each_entry_safe(region, node, n, &sync->pmem_stats, list) {
-		pr_err("listed vaddr 0x%p, active = %d",
-				region->info.vaddr,
-				region->info.active);
-	}
-	spin_unlock_irqrestore(&sync->pmem_stats_spinlock, flags);
-
-	return 0;
-}
-
-static int __msm_pmem_table_del(struct msm_sync *sync,
-		struct msm_pmem_info *pinfo)
-{
-	int rc = 0;
-	struct msm_pmem_region *region;
-	struct hlist_node *node, *n;
-	unsigned long flags = 0;
-
-	switch (pinfo->type) {
-	case MSM_PMEM_PREVIEW:
-	case MSM_PMEM_THUMBNAIL:
-	case MSM_PMEM_MAINIMG:
-	case MSM_PMEM_RAW_MAINIMG:
-	case MSM_PMEM_C2D:
-	case MSM_PMEM_MAINIMG_VPE:
-	case MSM_PMEM_THUMBNAIL_VPE:
-		spin_lock_irqsave(&sync->pmem_frame_spinlock, flags);
-		hlist_for_each_entry_safe(region, node, n,
-			&sync->pmem_frames, list) {
-
-			if (pinfo->type == region->info.type &&
-					pinfo->vaddr == region->info.vaddr &&
-					pinfo->fd == region->info.fd) {
-				hlist_del(node);
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-				ion_free(client_for_ion, region->handle);
-#else
-				put_pmem_file(region->file);
-#endif
-				kfree(region);
-				CDBG("%s: type %d, vaddr  0x%p\n",
-					__func__, pinfo->type, pinfo->vaddr);
-			}
-		}
-		spin_unlock_irqrestore(&sync->pmem_frame_spinlock, flags);
-		break;
-
-	case MSM_PMEM_VIDEO:
-	case MSM_PMEM_VIDEO_VPE:
-		spin_lock_irqsave(&sync->pmem_frame_spinlock, flags);
-		hlist_for_each_entry_safe(region, node, n,
-			&sync->pmem_frames, list) {
-
-			if (((region->info.type == MSM_PMEM_VIDEO) ||
-				(region->info.type == MSM_PMEM_VIDEO_VPE)) &&
-				pinfo->vaddr == region->info.vaddr &&
-				pinfo->fd == region->info.fd) {
-				hlist_del(node);
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-				ion_free(client_for_ion, region->handle);
-#else
-				put_pmem_file(region->file);
-#endif
-				kfree(region);
-				CDBG("%s: type %d, vaddr  0x%p\n",
-					__func__, pinfo->type, pinfo->vaddr);
-			}
-		}
-		spin_unlock_irqrestore(&sync->pmem_frame_spinlock, flags);
-		break;
-
-	case MSM_PMEM_AEC_AWB:
-	case MSM_PMEM_AF:
-		spin_lock_irqsave(&sync->pmem_stats_spinlock, flags);
-		hlist_for_each_entry_safe(region, node, n,
-			&sync->pmem_stats, list) {
-
-			if (pinfo->type == region->info.type &&
-					pinfo->vaddr == region->info.vaddr &&
-					pinfo->fd == region->info.fd) {
-				hlist_del(node);
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-				ion_free(client_for_ion, region->handle);
-#else
-				put_pmem_file(region->file);
-#endif
-				kfree(region);
-				CDBG("%s: type %d, vaddr  0x%p\n",
-					__func__, pinfo->type, pinfo->vaddr);
-			}
-		}
-		spin_unlock_irqrestore(&sync->pmem_stats_spinlock, flags);
-		break;
-
-	default:
-		rc = -EINVAL;
-		break;
-	}
-
-	return rc;
-}
-
-static int msm_pmem_table_del(struct msm_sync *sync, void __user *arg)
-{
-	struct msm_pmem_info info;
-
-	if (copy_from_user(&info, arg, sizeof(info))) {
-		ERR_COPY_FROM_USER();
-		return -EFAULT;
-	}
-
-	return __msm_pmem_table_del(sync, &info);
-}
-
-static int __msm_get_frame(struct msm_sync *sync,
-		struct msm_frame *frame)
-{
-	int rc = 0;
-
-	struct msm_pmem_info pmem_info;
-	struct msm_queue_cmd *qcmd = NULL;
-	struct msm_vfe_resp *vdata;
-	struct msm_vfe_phy_info *pphy;
-
-	qcmd = msm_dequeue(&sync->frame_q, list_frame);
-
-	if (!qcmd) {
-		pr_err("%s: no preview frame.\n", __func__);
-		return -EAGAIN;
-	}
-
-	if ((!qcmd->command) && (qcmd->error_code & MSM_CAMERA_ERR_MASK)) {
-		frame->error_code = qcmd->error_code;
-		pr_err("%s: fake frame with camera error code = %d\n",
-			__func__, frame->error_code);
-		goto err;
-	}
-
-	vdata = (struct msm_vfe_resp *)(qcmd->command);
-	pphy = &vdata->phy;
-	CDBG("%s, pphy->p2_phy = 0x%x\n", __func__, pphy->p2_phy);
-
-	rc = msm_pmem_frame_ptov_lookup(sync,
-			pphy->p0_phy,
-			pphy->p1_phy,
-			pphy->p2_phy,
-			&pmem_info,
-			1); /* Clear the active flag */
-
-	if (rc < 0) {
-		pr_err("%s: cannot get frame, invalid lookup address"
-		"plane0 add %x plane1 add %x plane2 add%x\n",
-		__func__,
-		pphy->p0_phy,
-		pphy->p1_phy,
-		pphy->p2_phy);
-		goto err;
-	}
-
-	frame->ts = qcmd->ts;
-	frame->buffer = (unsigned long)pmem_info.vaddr;
-	frame->planar0_off = pmem_info.planar0_off;
-	frame->planar1_off = pmem_info.planar1_off;
-	frame->planar2_off = pmem_info.planar2_off;
-	frame->fd = pmem_info.fd;
-	frame->path = vdata->phy.output_id;
-	frame->frame_id = vdata->phy.frame_id;
-	CDBG("%s: plane0 %x, plane1 %x, plane2 %x,qcmd %x, virt_addr %x\n",
-		__func__, pphy->p0_phy, pphy->p1_phy, pphy->p2_phy,
-		(int) qcmd, (int) frame->buffer);
-
-err:
-	free_qcmd(qcmd);
-	return rc;
-}
-
-static int msm_get_frame(struct msm_sync *sync, void __user *arg)
-{
-	int rc = 0;
-	struct msm_frame frame;
-
-	if (copy_from_user(&frame,
-				arg,
-				sizeof(struct msm_frame))) {
-		ERR_COPY_FROM_USER();
-		return -EFAULT;
-	}
-
-	rc = __msm_get_frame(sync, &frame);
-	if (rc < 0)
-		return rc;
-
-	mutex_lock(&sync->lock);
-	if (sync->croplen && (!sync->stereocam_enabled)) {
-		if (frame.croplen != sync->croplen) {
-			pr_err("%s: invalid frame croplen %d,"
-				"expecting %d\n",
-				__func__,
-				frame.croplen,
-				sync->croplen);
-			mutex_unlock(&sync->lock);
-			return -EINVAL;
-		}
-
-		if (copy_to_user((void *)frame.cropinfo,
-				sync->cropinfo,
-				sync->croplen)) {
-			ERR_COPY_TO_USER();
-			mutex_unlock(&sync->lock);
-			return -EFAULT;
-		}
-	}
-
-	if (sync->fdroiinfo.info) {
-		if (copy_to_user((void *)frame.roi_info.info,
-			sync->fdroiinfo.info,
-			sync->fdroiinfo.info_len)) {
-			ERR_COPY_TO_USER();
-			mutex_unlock(&sync->lock);
-			return -EFAULT;
-		}
-	}
-
-	if (sync->stereocam_enabled) {
-		frame.stcam_conv_value = sync->stcam_conv_value;
-		frame.stcam_quality_ind = sync->stcam_quality_ind;
-	}
-
-	if (copy_to_user((void *)arg,
-				&frame, sizeof(struct msm_frame))) {
-		ERR_COPY_TO_USER();
-		rc = -EFAULT;
-	}
-
-	mutex_unlock(&sync->lock);
-	CDBG("%s: got frame\n", __func__);
-
-	return rc;
-}
-
-static int msm_enable_vfe(struct msm_sync *sync, void __user *arg)
-{
-	int rc = -EIO;
-	struct camera_enable_cmd cfg;
-
-	if (copy_from_user(&cfg,
-			arg,
-			sizeof(struct camera_enable_cmd))) {
-		ERR_COPY_FROM_USER();
-		return -EFAULT;
-	}
-
-	if (sync->vfefn.vfe_enable)
-		rc = sync->vfefn.vfe_enable(&cfg);
-
-	return rc;
-}
-
-static int msm_disable_vfe(struct msm_sync *sync, void __user *arg)
-{
-	int rc = -EIO;
-	struct camera_enable_cmd cfg;
-
-	if (copy_from_user(&cfg,
-			arg,
-			sizeof(struct camera_enable_cmd))) {
-		ERR_COPY_FROM_USER();
-		return -EFAULT;
-	}
-
-	if (sync->vfefn.vfe_disable)
-		rc = sync->vfefn.vfe_disable(&cfg, NULL);
-
-	return rc;
-}
-
-static struct msm_queue_cmd *__msm_control(struct msm_sync *sync,
-		struct msm_device_queue *queue,
-		struct msm_queue_cmd *qcmd,
-		int timeout)
-{
-	int rc;
-
-	CDBG("Inside __msm_control\n");
-	if (sync->event_q.len <= 100 && sync->frame_q.len <= 100) {
-		/* wake up config thread */
-		msm_enqueue(&sync->event_q, &qcmd->list_config);
-	} else {
-		pr_err("%s, Error Queue limit exceeded e_q = %d, f_q = %d\n",
-			__func__, sync->event_q.len, sync->frame_q.len);
-		free_qcmd(qcmd);
-		return NULL;
-	}
-	if (!queue)
-		return NULL;
-
-	/* wait for config status */
-	CDBG("Waiting for config status \n");
-	rc = wait_event_interruptible_timeout(
-			queue->wait,
-			!list_empty_careful(&queue->list),
-			timeout);
-	CDBG("Waiting over for config status\n");
-	if (list_empty_careful(&queue->list)) {
-		if (!rc) {
-			rc = -ETIMEDOUT;
-			pr_err("%s: wait_event error %d\n", __func__, rc);
-			return ERR_PTR(rc);
-		} else if (rc < 0) {
-			pr_err("%s: wait_event error %d\n", __func__, rc);
-			if (msm_delete_entry(&sync->event_q,
-				list_config, qcmd)) {
-				sync->ignore_qcmd = true;
-				sync->ignore_qcmd_type =
-					(int16_t)((struct msm_ctrl_cmd *)
-					(qcmd->command))->type;
-			}
-			return ERR_PTR(rc);
-		}
-	}
-	qcmd = msm_dequeue(queue, list_control);
-	BUG_ON(!qcmd);
-	CDBG("__msm_control done \n");
-	return qcmd;
-}
-
-static struct msm_queue_cmd *__msm_control_nb(struct msm_sync *sync,
-					struct msm_queue_cmd *qcmd_to_copy)
-{
-	/* Since this is a non-blocking command, we cannot use qcmd_to_copy and
-	 * its data, since they are on the stack.  We replicate them on the heap
-	 * and mark them on_heap so that they get freed when the config thread
-	 * dequeues them.
-	 */
-
-	struct msm_ctrl_cmd *udata;
-	struct msm_ctrl_cmd *udata_to_copy = qcmd_to_copy->command;
-
-	struct msm_queue_cmd *qcmd =
-			kmalloc(sizeof(*qcmd_to_copy) +
-				sizeof(*udata_to_copy) +
-				udata_to_copy->length,
-				GFP_KERNEL);
-	if (!qcmd) {
-		pr_err("%s: out of memory\n", __func__);
-		return ERR_PTR(-ENOMEM);
-	}
-	*qcmd = *qcmd_to_copy;
-	udata = qcmd->command = qcmd + 1;
-	memcpy(udata, udata_to_copy, sizeof(*udata));
-	udata->value = udata + 1;
-	memcpy(udata->value, udata_to_copy->value, udata_to_copy->length);
-
-	atomic_set(&qcmd->on_heap, 1);
-
-	/* qcmd_resp will be set to NULL */
-	return __msm_control(sync, NULL, qcmd, 0);
-}
-
-static int msm_control(struct msm_control_device *ctrl_pmsm,
-			int block,
-			void __user *arg)
-{
-	int rc = 0;
-
-	struct msm_sync *sync = ctrl_pmsm->pmsm->sync;
-	void __user *uptr;
-	struct msm_ctrl_cmd udata_resp;
-	struct msm_queue_cmd *qcmd_resp = NULL;
-	uint8_t data[max_control_command_size];
-	struct msm_ctrl_cmd *udata;
-	struct msm_queue_cmd *qcmd =
-		kmalloc(sizeof(struct msm_queue_cmd) +
-			sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
-	if (!qcmd) {
-		pr_err("%s: out of memory\n", __func__);
-		return -ENOMEM;
-	}
-	udata = (struct msm_ctrl_cmd *)(qcmd + 1);
-	atomic_set(&(qcmd->on_heap), 1);
-	CDBG("Inside msm_control\n");
-	if (copy_from_user(udata, arg, sizeof(struct msm_ctrl_cmd))) {
-		ERR_COPY_FROM_USER();
-		rc = -EFAULT;
-		goto end;
-	}
-
-	uptr = udata->value;
-	udata->value = data;
-	qcmd->type = MSM_CAM_Q_CTRL;
-	qcmd->command = udata;
-
-	if (udata->length) {
-		if (udata->length > sizeof(data)) {
-			pr_err("%s: user data too large (%d, max is %d)\n",
-					__func__,
-					udata->length,
-					sizeof(data));
-			rc = -EIO;
-			goto end;
-		}
-		if (copy_from_user(udata->value, uptr, udata->length)) {
-			ERR_COPY_FROM_USER();
-			rc = -EFAULT;
-			goto end;
-		}
-	}
-
-	if (unlikely(!block)) {
-		qcmd_resp = __msm_control_nb(sync, qcmd);
-		goto end;
-	}
-	msm_queue_drain(&ctrl_pmsm->ctrl_q, list_control);
-	qcmd_resp = __msm_control(sync,
-				  &ctrl_pmsm->ctrl_q,
-				  qcmd, msecs_to_jiffies(10000));
-
-	/* ownership of qcmd will be transfered to event queue */
-	qcmd = NULL;
-
-	if (!qcmd_resp || IS_ERR(qcmd_resp)) {
-		/* Do not free qcmd_resp here.  If the config thread read it,
-		 * then it has already been freed, and we timed out because
-		 * we did not receive a MSM_CAM_IOCTL_CTRL_CMD_DONE.  If the
-		 * config thread itself is blocked and not dequeueing commands,
-		 * then it will either eventually unblock and process them,
-		 * or when it is killed, qcmd will be freed in
-		 * msm_release_config.
-		 */
-		rc = PTR_ERR(qcmd_resp);
-		qcmd_resp = NULL;
-		goto end;
-	}
-
-	if (qcmd_resp->command) {
-		udata_resp = *(struct msm_ctrl_cmd *)qcmd_resp->command;
-		if (udata_resp.length > 0) {
-			if (copy_to_user(uptr,
-					 udata_resp.value,
-					 udata_resp.length)) {
-				ERR_COPY_TO_USER();
-				rc = -EFAULT;
-				goto end;
-			}
-		}
-		udata_resp.value = uptr;
-
-		if (copy_to_user((void *)arg, &udata_resp,
-				sizeof(struct msm_ctrl_cmd))) {
-			ERR_COPY_TO_USER();
-			rc = -EFAULT;
-			goto end;
-		}
-	}
-
-end:
-	free_qcmd(qcmd);
-	CDBG("%s: done rc = %d\n", __func__, rc);
-	return rc;
-}
-
-/* Divert frames for post-processing by delivering them to the config thread;
- * when post-processing is done, it will return the frame to the frame thread.
- */
-static int msm_divert_frame(struct msm_sync *sync,
-		struct msm_vfe_resp *data,
-		struct msm_stats_event_ctrl *se)
-{
-	struct msm_pmem_info pinfo;
-	struct msm_postproc buf;
-	int rc;
-
-	CDBG("%s: Frame PP sync->pp_mask %d\n", __func__, sync->pp_mask);
-
-	if (!(sync->pp_mask & PP_PREV)  && !(sync->pp_mask & PP_SNAP)) {
-		pr_err("%s: diverting frame, not in PP_PREV or PP_SNAP!\n",
-			__func__);
-		return -EINVAL;
-	}
-
-	rc = msm_pmem_frame_ptov_lookup(sync, data->phy.p0_phy,
-			data->phy.p1_phy, data->phy.p2_phy, &pinfo,
-			0); /* do not clear the active flag */
-
-	if (rc < 0) {
-		pr_err("%s: msm_pmem_frame_ptov_lookup failed\n", __func__);
-		return rc;
-	}
-
-	buf.fmain.buffer = (unsigned long)pinfo.vaddr;
-	buf.fmain.planar0_off = pinfo.planar0_off;
-	buf.fmain.planar1_off = pinfo.planar1_off;
-	buf.fmain.fd = pinfo.fd;
-
-	CDBG("%s: buf 0x%x fd %d\n", __func__, (unsigned int)buf.fmain.buffer,
-		 buf.fmain.fd);
-	if (copy_to_user((void *)(se->stats_event.data),
-			&(buf.fmain), sizeof(struct msm_frame))) {
-		ERR_COPY_TO_USER();
-		return -EFAULT;
-	}
-	return 0;
-}
-
-/* Divert stereo frames for post-processing by delivering
- * them to the config thread.
- */
-static int msm_divert_st_frame(struct msm_sync *sync,
-	struct msm_vfe_resp *data, struct msm_stats_event_ctrl *se, int path)
-{
-	struct msm_pmem_info pinfo;
-	struct msm_st_frame buf;
-	struct video_crop_t *crop = NULL;
-	int rc = 0;
-
-	if (se->stats_event.msg_id == OUTPUT_TYPE_ST_L) {
-		buf.type = OUTPUT_TYPE_ST_L;
-	} else if (se->stats_event.msg_id == OUTPUT_TYPE_ST_R) {
-		buf.type = OUTPUT_TYPE_ST_R;
-	} else {
-		if (se->resptype == MSM_CAM_RESP_STEREO_OP_1) {
-			rc = msm_pmem_frame_ptov_lookup(sync, data->phy.p0_phy,
-				data->phy.p1_phy, data->phy.p2_phy, &pinfo,
-				1);  /* do clear the active flag */
-			buf.buf_info.path = path;
-		} else if (se->resptype == MSM_CAM_RESP_STEREO_OP_2) {
-			rc = msm_pmem_frame_ptov_lookup(sync, data->phy.p0_phy,
-				data->phy.p1_phy, data->phy.p2_phy, &pinfo,
-				0); /* do not clear the active flag */
-			buf.buf_info.path = path;
-		} else
-			CDBG("%s: Invalid resptype = %d\n", __func__,
-				se->resptype);
-
-		if (rc < 0) {
-			CDBG("%s: msm_pmem_frame_ptov_lookup failed\n",
-				__func__);
-			return rc;
-		}
-
-		buf.type = OUTPUT_TYPE_ST_D;
-
-		if (sync->cropinfo != NULL) {
-			crop = sync->cropinfo;
-			switch (path) {
-			case OUTPUT_TYPE_P:
-			case OUTPUT_TYPE_T: {
-				buf.L.stCropInfo.in_w = crop->in1_w;
-				buf.L.stCropInfo.in_h = crop->in1_h;
-				buf.L.stCropInfo.out_w = crop->out1_w;
-				buf.L.stCropInfo.out_h = crop->out1_h;
-				buf.R.stCropInfo = buf.L.stCropInfo;
-				break;
-			}
-
-			case OUTPUT_TYPE_V:
-			case OUTPUT_TYPE_S: {
-				buf.L.stCropInfo.in_w = crop->in2_w;
-				buf.L.stCropInfo.in_h = crop->in2_h;
-				buf.L.stCropInfo.out_w = crop->out2_w;
-				buf.L.stCropInfo.out_h = crop->out2_h;
-				buf.R.stCropInfo = buf.L.stCropInfo;
-				break;
-			}
-			default: {
-				pr_warning("%s: invalid frame path %d\n",
-					__func__, path);
-				break;
-			}
-			}
-		} else {
-			buf.L.stCropInfo.in_w = 0;
-			buf.L.stCropInfo.in_h = 0;
-			buf.L.stCropInfo.out_w = 0;
-			buf.L.stCropInfo.out_h = 0;
-			buf.R.stCropInfo = buf.L.stCropInfo;
-		}
-
-		/* hardcode for now. */
-		if ((path == OUTPUT_TYPE_S) || (path == OUTPUT_TYPE_T))
-			buf.packing = sync->sctrl.s_snap_packing;
-		else
-			buf.packing = sync->sctrl.s_video_packing;
-
-		buf.buf_info.buffer = (unsigned long)pinfo.vaddr;
-		buf.buf_info.phy_offset = pinfo.offset;
-		buf.buf_info.planar0_off = pinfo.planar0_off;
-		buf.buf_info.planar1_off = pinfo.planar1_off;
-		buf.buf_info.planar2_off = pinfo.planar2_off;
-		buf.buf_info.fd = pinfo.fd;
-
-		CDBG("%s: buf 0x%x fd %d\n", __func__,
-			(unsigned int)buf.buf_info.buffer, buf.buf_info.fd);
-	}
-
-	if (copy_to_user((void *)(se->stats_event.data),
-			&buf, sizeof(struct msm_st_frame))) {
-		ERR_COPY_TO_USER();
-		return -EFAULT;
-	}
-	return 0;
-}
-
-static int msm_get_stats(struct msm_sync *sync, void __user *arg)
-{
-	int rc = 0;
-
-	struct msm_stats_event_ctrl se;
-
-	struct msm_queue_cmd *qcmd = NULL;
-	struct msm_ctrl_cmd  *ctrl = NULL;
-	struct msm_vfe_resp  *data = NULL;
-	struct msm_vpe_resp  *vpe_data = NULL;
-	struct msm_stats_buf stats;
-
-	if (copy_from_user(&se, arg,
-			sizeof(struct msm_stats_event_ctrl))) {
-		ERR_COPY_FROM_USER();
-		pr_err("%s, ERR_COPY_FROM_USER\n", __func__);
-		return -EFAULT;
-	}
-
-	rc = 0;
-
-	qcmd = msm_dequeue(&sync->event_q, list_config);
-	if (!qcmd) {
-		/* Should be associated with wait_event
-			error -512 from __msm_control*/
-		pr_err("%s, qcmd is Null\n", __func__);
-		rc = -ETIMEDOUT;
-		return rc;
-	}
-
-	CDBG("%s: received from DSP %d\n", __func__, qcmd->type);
-
-	switch (qcmd->type) {
-	case MSM_CAM_Q_VPE_MSG:
-		/* Complete VPE response. */
-		vpe_data = (struct msm_vpe_resp *)(qcmd->command);
-		se.resptype = MSM_CAM_RESP_STEREO_OP_2;
-		se.stats_event.type   = vpe_data->evt_msg.type;
-		se.stats_event.msg_id = vpe_data->evt_msg.msg_id;
-		se.stats_event.len    = vpe_data->evt_msg.len;
-
-		if (vpe_data->type == VPE_MSG_OUTPUT_ST_L) {
-			CDBG("%s: Change msg_id to OUTPUT_TYPE_ST_L\n",
-				__func__);
-			se.stats_event.msg_id = OUTPUT_TYPE_ST_L;
-			rc = msm_divert_st_frame(sync, data, &se,
-				OUTPUT_TYPE_V);
-		} else if (vpe_data->type == VPE_MSG_OUTPUT_ST_R) {
-			CDBG("%s: Change msg_id to OUTPUT_TYPE_ST_R\n",
-				__func__);
-			se.stats_event.msg_id = OUTPUT_TYPE_ST_R;
-			rc = msm_divert_st_frame(sync, data, &se,
-				OUTPUT_TYPE_V);
-		} else {
-			pr_warning("%s: invalid vpe_data->type = %d\n",
-				__func__, vpe_data->type);
-		}
-		break;
-
-	case MSM_CAM_Q_VFE_EVT:
-	case MSM_CAM_Q_VFE_MSG:
-		data = (struct msm_vfe_resp *)(qcmd->command);
-
-		/* adsp event and message */
-		se.resptype = MSM_CAM_RESP_STAT_EVT_MSG;
-
-		/* 0 - msg from aDSP, 1 - event from mARM */
-		se.stats_event.type   = data->evt_msg.type;
-		se.stats_event.msg_id = data->evt_msg.msg_id;
-		se.stats_event.len    = data->evt_msg.len;
-		se.stats_event.frame_id = data->evt_msg.frame_id;
-
-		CDBG("%s: qcmd->type %d length %d msd_id %d\n", __func__,
-			qcmd->type,
-			se.stats_event.len,
-			se.stats_event.msg_id);
-
-		if (data->type == VFE_MSG_COMMON) {
-			stats.status_bits = data->stats_msg.status_bits;
-			stats.awb_ymin = data->stats_msg.awb_ymin;
-
-			if (data->stats_msg.aec_buff) {
-				stats.aec.buff =
-				msm_pmem_stats_ptov_lookup(sync,
-						data->stats_msg.aec_buff,
-						&(stats.aec.fd));
-				if (!stats.aec.buff) {
-					pr_err("%s: msm_pmem_stats_ptov_lookup error\n",
-						__func__);
-					rc = -EINVAL;
-					goto failure;
-				}
-
-			} else {
-				stats.aec.buff = 0;
-			}
-			if (data->stats_msg.awb_buff) {
-				stats.awb.buff =
-				msm_pmem_stats_ptov_lookup(sync,
-						data->stats_msg.awb_buff,
-						&(stats.awb.fd));
-				if (!stats.awb.buff) {
-					pr_err("%s: msm_pmem_stats_ptov_lookup error\n",
-						__func__);
-					rc = -EINVAL;
-					goto failure;
-				}
-
-			} else {
-				stats.awb.buff = 0;
-			}
-			if (data->stats_msg.af_buff) {
-				stats.af.buff =
-				msm_pmem_stats_ptov_lookup(sync,
-						data->stats_msg.af_buff,
-						&(stats.af.fd));
-				if (!stats.af.buff) {
-					pr_err("%s: msm_pmem_stats_ptov_lookup error\n",
-						__func__);
-					rc = -EINVAL;
-					goto failure;
-				}
-
-			} else {
-				stats.af.buff = 0;
-			}
-			if (data->stats_msg.ihist_buff) {
-				stats.ihist.buff =
-				msm_pmem_stats_ptov_lookup(sync,
-						data->stats_msg.ihist_buff,
-						&(stats.ihist.fd));
-				if (!stats.ihist.buff) {
-					pr_err("%s: msm_pmem_stats_ptov_lookup error\n",
-						__func__);
-					rc = -EINVAL;
-					goto failure;
-				}
-
-			} else {
-				stats.ihist.buff = 0;
-			}
-
-			if (data->stats_msg.rs_buff) {
-				stats.rs.buff =
-				msm_pmem_stats_ptov_lookup(sync,
-						data->stats_msg.rs_buff,
-						&(stats.rs.fd));
-				if (!stats.rs.buff) {
-					pr_err("%s: msm_pmem_stats_ptov_lookup error\n",
-						__func__);
-					rc = -EINVAL;
-					goto failure;
-				}
-
-			} else {
-				stats.rs.buff = 0;
-			}
-
-			if (data->stats_msg.cs_buff) {
-				stats.cs.buff =
-				msm_pmem_stats_ptov_lookup(sync,
-						data->stats_msg.cs_buff,
-						&(stats.cs.fd));
-				if (!stats.cs.buff) {
-					pr_err("%s: msm_pmem_stats_ptov_lookup error\n",
-						__func__);
-					rc = -EINVAL;
-					goto failure;
-				}
-			} else {
-				stats.cs.buff = 0;
-			}
-
-			se.stats_event.frame_id = data->phy.frame_id;
-			if (copy_to_user((void *)(se.stats_event.data),
-					&stats,
-					sizeof(struct msm_stats_buf))) {
-				ERR_COPY_TO_USER();
-				rc = -EFAULT;
-				goto failure;
-			}
-		} else if ((data->type >= VFE_MSG_STATS_AEC) &&
-			(data->type <=  VFE_MSG_STATS_WE)) {
-			/* the check above includes all stats type. */
-			stats.awb_ymin = data->stats_msg.awb_ymin;
-			stats.buffer =
-				msm_pmem_stats_ptov_lookup(sync,
-						data->phy.sbuf_phy,
-						&(stats.fd));
-			if (!stats.buffer) {
-					pr_err("%s: msm_pmem_stats_ptov_lookup error\n",
-						__func__);
-					rc = -EINVAL;
-					goto failure;
-			}
-			se.stats_event.frame_id = data->phy.frame_id;
-			if (copy_to_user((void *)(se.stats_event.data),
-					&stats,
-					sizeof(struct msm_stats_buf))) {
-				ERR_COPY_TO_USER();
-				rc = -EFAULT;
-				goto failure;
-			}
-		} else if ((data->evt_msg.len > 0) &&
-				(data->type == VFE_MSG_GENERAL)) {
-			if (copy_to_user((void *)(se.stats_event.data),
-					data->evt_msg.data,
-					data->evt_msg.len)) {
-				ERR_COPY_TO_USER();
-				rc = -EFAULT;
-				goto failure;
-			}
-		} else {
-			if (sync->stereocam_enabled) {
-				if (data->type == VFE_MSG_OUTPUT_P) {
-					CDBG("%s: Preview mark as st op 1\n",
-						__func__);
-					se.resptype = MSM_CAM_RESP_STEREO_OP_1;
-					rc = msm_divert_st_frame(sync, data,
-						&se, OUTPUT_TYPE_P);
-					break;
-				} else if (data->type == VFE_MSG_OUTPUT_V) {
-					CDBG("%s: Video mark as st op 2\n",
-						__func__);
-					se.resptype = MSM_CAM_RESP_STEREO_OP_2;
-					rc = msm_divert_st_frame(sync, data,
-						&se, OUTPUT_TYPE_V);
-					break;
-				} else if (data->type == VFE_MSG_OUTPUT_S) {
-					CDBG("%s: Main img mark as st op 2\n",
-						__func__);
-					se.resptype = MSM_CAM_RESP_STEREO_OP_2;
-					rc = msm_divert_st_frame(sync, data,
-						&se, OUTPUT_TYPE_S);
-					break;
-				} else if (data->type == VFE_MSG_OUTPUT_T) {
-					CDBG("%s: Thumb img mark as st op 2\n",
-						__func__);
-					se.resptype = MSM_CAM_RESP_STEREO_OP_2;
-					rc = msm_divert_st_frame(sync, data,
-						&se, OUTPUT_TYPE_T);
-					break;
-				} else
-					CDBG("%s: VFE_MSG Fall Through\n",
-						__func__);
-			}
-			if ((sync->pp_frame_avail == 1) &&
-				(sync->pp_mask & PP_PREV) &&
-				(data->type == VFE_MSG_OUTPUT_P)) {
-					CDBG("%s:%d:preiew PP\n",
-					__func__, __LINE__);
-					se.stats_event.frame_id =
-							data->phy.frame_id;
-					rc = msm_divert_frame(sync, data, &se);
-					sync->pp_frame_avail = 0;
-			} else {
-				if ((sync->pp_mask & PP_PREV) &&
-					(data->type == VFE_MSG_OUTPUT_P)) {
-					se.stats_event.frame_id =
-							data->phy.frame_id;
-					free_qcmd(qcmd);
-					return 0;
-				} else
-					CDBG("%s:indication type is %d\n",
-						__func__, data->type);
-			}
-			if (sync->pp_mask & PP_SNAP)
-				if (data->type == VFE_MSG_OUTPUT_S ||
-					data->type == VFE_MSG_OUTPUT_T)
-					rc = msm_divert_frame(sync, data, &se);
-		}
-		break;
-
-	case MSM_CAM_Q_CTRL:
-		/* control command from control thread */
-		ctrl = (struct msm_ctrl_cmd *)(qcmd->command);
-
-		CDBG("%s: qcmd->type %d length %d\n", __func__,
-			qcmd->type, ctrl->length);
-
-		if (ctrl->length > 0) {
-			if (copy_to_user((void *)(se.ctrl_cmd.value),
-						ctrl->value,
-						ctrl->length)) {
-				ERR_COPY_TO_USER();
-				rc = -EFAULT;
-				goto failure;
-			}
-		}
-
-		se.resptype = MSM_CAM_RESP_CTRL;
-
-		/* what to control */
-		se.ctrl_cmd.type = ctrl->type;
-		se.ctrl_cmd.length = ctrl->length;
-		se.ctrl_cmd.resp_fd = ctrl->resp_fd;
-		break;
-
-	case MSM_CAM_Q_V4L2_REQ:
-		/* control command from v4l2 client */
-		ctrl = (struct msm_ctrl_cmd *)(qcmd->command);
-		if (ctrl->length > 0) {
-			if (copy_to_user((void *)(se.ctrl_cmd.value),
-					ctrl->value, ctrl->length)) {
-				ERR_COPY_TO_USER();
-				rc = -EFAULT;
-				goto failure;
-			}
-		}
-
-		/* 2 tells config thread this is v4l2 request */
-		se.resptype = MSM_CAM_RESP_V4L2;
-
-		/* what to control */
-		se.ctrl_cmd.type   = ctrl->type;
-		se.ctrl_cmd.length = ctrl->length;
-		break;
-
-	default:
-		rc = -EFAULT;
-		goto failure;
-	} /* switch qcmd->type */
-	if (copy_to_user((void *)arg, &se, sizeof(se))) {
-		ERR_COPY_TO_USER();
-		rc = -EFAULT;
-		goto failure;
-	}
-
-failure:
-	free_qcmd(qcmd);
-
-	CDBG("%s: %d\n", __func__, rc);
-	return rc;
-}
-
-static int msm_ctrl_cmd_done(struct msm_control_device *ctrl_pmsm,
-		void __user *arg)
-{
-	void __user *uptr;
-	struct msm_queue_cmd *qcmd = &ctrl_pmsm->qcmd;
-	struct msm_ctrl_cmd *command = &ctrl_pmsm->ctrl;
-
-	if (copy_from_user(command, arg, sizeof(*command))) {
-		ERR_COPY_FROM_USER();
-		return -EFAULT;
-	}
-
-	atomic_set(&qcmd->on_heap, 0);
-	qcmd->command = command;
-	uptr = command->value;
-
-	if (command->length > 0) {
-		command->value = ctrl_pmsm->ctrl_data;
-		if (command->length > sizeof(ctrl_pmsm->ctrl_data)) {
-			pr_err("%s: user data %d is too big (max %d)\n",
-				__func__, command->length,
-				sizeof(ctrl_pmsm->ctrl_data));
-			return -EINVAL;
-		}
-
-		if (copy_from_user(command->value,
-					uptr,
-					command->length)) {
-			ERR_COPY_FROM_USER();
-			return -EFAULT;
-		}
-	} else
-		command->value = NULL;
-
-	/* Ignore the command if the ctrl cmd has
-	   return back due to signaling */
-	/* Should be associated with wait_event
-	   error -512 from __msm_control*/
-	if (ctrl_pmsm->pmsm->sync->ignore_qcmd == true &&
-	   ctrl_pmsm->pmsm->sync->ignore_qcmd_type == (int16_t)command->type) {
-		ctrl_pmsm->pmsm->sync->ignore_qcmd = false;
-		ctrl_pmsm->pmsm->sync->ignore_qcmd_type = -1;
-	} else /* wake up control thread */
-		msm_enqueue(&ctrl_pmsm->ctrl_q, &qcmd->list_control);
-
-	return 0;
-}
-
-static int msm_config_vpe(struct msm_sync *sync, void __user *arg)
-{
-	struct msm_vpe_cfg_cmd cfgcmd;
-	if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
-		ERR_COPY_FROM_USER();
-		return -EFAULT;
-	}
-	CDBG("%s: cmd_type %s\n", __func__, vfe_config_cmd[cfgcmd.cmd_type]);
-	switch (cfgcmd.cmd_type) {
-	case CMD_VPE:
-		return sync->vpefn.vpe_config(&cfgcmd, NULL);
-	default:
-		pr_err("%s: unknown command type %d\n",
-			__func__, cfgcmd.cmd_type);
-	}
-	return -EINVAL;
-}
-
-static int msm_config_vfe(struct msm_sync *sync, void __user *arg)
-{
-	struct msm_vfe_cfg_cmd cfgcmd;
-	struct msm_pmem_region region[8];
-	struct axidata axi_data;
-
-	if (!sync->vfefn.vfe_config) {
-		pr_err("%s: no vfe_config!\n", __func__);
-		return -EIO;
-	}
-
-	if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
-		ERR_COPY_FROM_USER();
-		return -EFAULT;
-	}
-
-	memset(&axi_data, 0, sizeof(axi_data));
-	CDBG("%s: cmd_type %s\n", __func__, vfe_config_cmd[cfgcmd.cmd_type]);
-	switch (cfgcmd.cmd_type) {
-	case CMD_STATS_ENABLE:
-		axi_data.bufnum1 =
-			msm_pmem_region_lookup(&sync->pmem_stats,
-				MSM_PMEM_AEC_AWB, &region[0],
-				NUM_STAT_OUTPUT_BUFFERS,
-				&sync->pmem_stats_spinlock);
-		axi_data.bufnum2 =
-			msm_pmem_region_lookup(&sync->pmem_stats,
-				MSM_PMEM_AF, &region[axi_data.bufnum1],
-				NUM_STAT_OUTPUT_BUFFERS,
-				&sync->pmem_stats_spinlock);
-		if (!axi_data.bufnum1 || !axi_data.bufnum2) {
-			pr_err("%s: pmem region lookup error\n", __func__);
-			return -EINVAL;
-		}
-		axi_data.region = &region[0];
-		return sync->vfefn.vfe_config(&cfgcmd, &axi_data);
-	case CMD_STATS_AF_ENABLE:
-		axi_data.bufnum1 =
-			msm_pmem_region_lookup(&sync->pmem_stats,
-				MSM_PMEM_AF, &region[0],
-				NUM_STAT_OUTPUT_BUFFERS,
-				&sync->pmem_stats_spinlock);
-		if (!axi_data.bufnum1) {
-			pr_err("%s %d: pmem region lookup error\n",
-				__func__, __LINE__);
-			return -EINVAL;
-		}
-		axi_data.region = &region[0];
-		return sync->vfefn.vfe_config(&cfgcmd, &axi_data);
-	case CMD_STATS_AEC_AWB_ENABLE:
-		axi_data.bufnum1 =
-			msm_pmem_region_lookup(&sync->pmem_stats,
-				MSM_PMEM_AEC_AWB, &region[0],
-				NUM_STAT_OUTPUT_BUFFERS,
-				&sync->pmem_stats_spinlock);
-		if (!axi_data.bufnum1) {
-			pr_err("%s %d: pmem region lookup error\n",
-				__func__, __LINE__);
-			return -EINVAL;
-		}
-		axi_data.region = &region[0];
-		return sync->vfefn.vfe_config(&cfgcmd, &axi_data);
-	case CMD_STATS_AEC_ENABLE:
-		axi_data.bufnum1 =
-			msm_pmem_region_lookup(&sync->pmem_stats,
-			MSM_PMEM_AEC, &region[0],
-			NUM_STAT_OUTPUT_BUFFERS,
-			&sync->pmem_stats_spinlock);
-		if (!axi_data.bufnum1) {
-			pr_err("%s %d: pmem region lookup error\n",
-				__func__, __LINE__);
-			return -EINVAL;
-		}
-		axi_data.region = &region[0];
-		return sync->vfefn.vfe_config(&cfgcmd, &axi_data);
-	case CMD_STATS_AWB_ENABLE:
-		axi_data.bufnum1 =
-			msm_pmem_region_lookup(&sync->pmem_stats,
-			MSM_PMEM_AWB, &region[0],
-			NUM_STAT_OUTPUT_BUFFERS,
-			&sync->pmem_stats_spinlock);
-		if (!axi_data.bufnum1) {
-			pr_err("%s %d: pmem region lookup error\n",
-				__func__, __LINE__);
-			return -EINVAL;
-		}
-		axi_data.region = &region[0];
-		return sync->vfefn.vfe_config(&cfgcmd, &axi_data);
-
-
-	case CMD_STATS_IHIST_ENABLE:
-		axi_data.bufnum1 =
-			msm_pmem_region_lookup(&sync->pmem_stats,
-			MSM_PMEM_IHIST, &region[0],
-			NUM_STAT_OUTPUT_BUFFERS,
-			&sync->pmem_stats_spinlock);
-		if (!axi_data.bufnum1) {
-			pr_err("%s %d: pmem region lookup error\n",
-				__func__, __LINE__);
-			return -EINVAL;
-		}
-		axi_data.region = &region[0];
-		return sync->vfefn.vfe_config(&cfgcmd, &axi_data);
-
-	case CMD_STATS_RS_ENABLE:
-		axi_data.bufnum1 =
-			msm_pmem_region_lookup(&sync->pmem_stats,
-			MSM_PMEM_RS, &region[0],
-			NUM_STAT_OUTPUT_BUFFERS,
-			&sync->pmem_stats_spinlock);
-		if (!axi_data.bufnum1) {
-			pr_err("%s %d: pmem region lookup error\n",
-				__func__, __LINE__);
-			return -EINVAL;
-		}
-		axi_data.region = &region[0];
-		return sync->vfefn.vfe_config(&cfgcmd, &axi_data);
-
-	case CMD_STATS_CS_ENABLE:
-		axi_data.bufnum1 =
-			msm_pmem_region_lookup(&sync->pmem_stats,
-			MSM_PMEM_CS, &region[0],
-			NUM_STAT_OUTPUT_BUFFERS,
-			&sync->pmem_stats_spinlock);
-		if (!axi_data.bufnum1) {
-			pr_err("%s %d: pmem region lookup error\n",
-				__func__, __LINE__);
-			return -EINVAL;
-		}
-		axi_data.region = &region[0];
-		return sync->vfefn.vfe_config(&cfgcmd, &axi_data);
-
-	case CMD_GENERAL:
-	case CMD_STATS_DISABLE:
-		return sync->vfefn.vfe_config(&cfgcmd, NULL);
-	default:
-		pr_err("%s: unknown command type %d\n",
-			__func__, cfgcmd.cmd_type);
-	}
-
-	return -EINVAL;
-}
-static int msm_vpe_frame_cfg(struct msm_sync *sync,
-				void *cfgcmdin)
-{
-	int rc = -EIO;
-	struct axidata axi_data;
-	void *data = &axi_data;
-	struct msm_pmem_region region[8];
-	int pmem_type;
-
-	struct msm_vpe_cfg_cmd *cfgcmd;
-	cfgcmd = (struct msm_vpe_cfg_cmd *)cfgcmdin;
-
-	memset(&axi_data, 0, sizeof(axi_data));
-	CDBG("In vpe_frame_cfg cfgcmd->cmd_type = %s\n",
-		vfe_config_cmd[cfgcmd->cmd_type]);
-	switch (cfgcmd->cmd_type) {
-	case CMD_AXI_CFG_VPE:
-		pmem_type = MSM_PMEM_VIDEO_VPE;
-		axi_data.bufnum1 =
-			msm_pmem_region_lookup_2(&sync->pmem_frames, pmem_type,
-				&region[0], 8, &sync->pmem_frame_spinlock);
-		CDBG("axi_data.bufnum1 = %d\n", axi_data.bufnum1);
-		if (!axi_data.bufnum1) {
-			pr_err("%s %d: pmem region lookup error\n",
-				__func__, __LINE__);
-			return -EINVAL;
-		}
-		pmem_type = MSM_PMEM_VIDEO;
-		break;
-	case CMD_AXI_CFG_SNAP_THUMB_VPE:
-		CDBG("%s: CMD_AXI_CFG_SNAP_THUMB_VPE", __func__);
-		pmem_type = MSM_PMEM_THUMBNAIL_VPE;
-		axi_data.bufnum1 =
-			msm_pmem_region_lookup(&sync->pmem_frames, pmem_type,
-			&region[0], 8, &sync->pmem_frame_spinlock);
-		if (!axi_data.bufnum1) {
-			pr_err("%s: THUMBNAIL_VPE pmem region lookup error\n",
-				__func__);
-			return -EINVAL;
-		}
-		break;
-	case CMD_AXI_CFG_SNAP_VPE:
-		CDBG("%s: CMD_AXI_CFG_SNAP_VPE", __func__);
-		pmem_type = MSM_PMEM_MAINIMG_VPE;
-		axi_data.bufnum1 =
-			msm_pmem_region_lookup(&sync->pmem_frames, pmem_type,
-				&region[0], 8, &sync->pmem_frame_spinlock);
-		if (!axi_data.bufnum1) {
-			pr_err("%s: MAINIMG_VPE pmem region lookup error\n",
-				__func__);
-			return -EINVAL;
-		}
-		break;
-	default:
-		pr_err("%s: unknown command type %d\n",
-			__func__, cfgcmd->cmd_type);
-		break;
-	}
-	axi_data.region = &region[0];
-	CDBG("out vpe_frame_cfg cfgcmd->cmd_type = %s\n",
-		vfe_config_cmd[cfgcmd->cmd_type]);
-	/* send the AXI configuration command to driver */
-	if (sync->vpefn.vpe_config)
-		rc = sync->vpefn.vpe_config(cfgcmd, data);
-	return rc;
-}
-
-static int msm_frame_axi_cfg(struct msm_sync *sync,
-		struct msm_vfe_cfg_cmd *cfgcmd)
-{
-	int rc = -EIO;
-	struct axidata axi_data;
-	void *data = &axi_data;
-	struct msm_pmem_region region[MAX_PMEM_CFG_BUFFERS];
-	int pmem_type;
-
-	memset(&axi_data, 0, sizeof(axi_data));
-
-	switch (cfgcmd->cmd_type) {
-
-	case CMD_AXI_CFG_PREVIEW:
-		pmem_type = MSM_PMEM_PREVIEW;
-		axi_data.bufnum2 =
-			msm_pmem_region_lookup(&sync->pmem_frames, pmem_type,
-				&region[0], MAX_PMEM_CFG_BUFFERS,
-				&sync->pmem_frame_spinlock);
-		if (!axi_data.bufnum2) {
-			pr_err("%s %d: pmem region lookup error (empty %d)\n",
-				__func__, __LINE__,
-				hlist_empty(&sync->pmem_frames));
-			return -EINVAL;
-		}
-		break;
-
-	case CMD_AXI_CFG_VIDEO_ALL_CHNLS:
-	case CMD_AXI_CFG_VIDEO:
-		pmem_type = MSM_PMEM_PREVIEW;
-		axi_data.bufnum1 =
-			msm_pmem_region_lookup(&sync->pmem_frames, pmem_type,
-				&region[0], MAX_PMEM_CFG_BUFFERS,
-				&sync->pmem_frame_spinlock);
-		if (!axi_data.bufnum1) {
-			pr_err("%s %d: pmem region lookup error\n",
-				__func__, __LINE__);
-			return -EINVAL;
-		}
-
-		pmem_type = MSM_PMEM_VIDEO;
-		axi_data.bufnum2 =
-			msm_pmem_region_lookup(&sync->pmem_frames, pmem_type,
-				&region[axi_data.bufnum1],
-				(MAX_PMEM_CFG_BUFFERS-(axi_data.bufnum1)),
-				&sync->pmem_frame_spinlock);
-		if (!axi_data.bufnum2) {
-			pr_err("%s %d: pmem region lookup error\n",
-				__func__, __LINE__);
-			return -EINVAL;
-		}
-		break;
-
-	case CMD_AXI_CFG_SNAP:
-		CDBG("%s, CMD_AXI_CFG_SNAP, type=%d\n", __func__,
-			cfgcmd->cmd_type);
-		pmem_type = MSM_PMEM_THUMBNAIL;
-		axi_data.bufnum1 =
-			msm_pmem_region_lookup(&sync->pmem_frames, pmem_type,
-				&region[0], MAX_PMEM_CFG_BUFFERS,
-				&sync->pmem_frame_spinlock);
-		if (!axi_data.bufnum1) {
-			pr_err("%s %d: pmem region lookup error\n",
-				__func__, __LINE__);
-			return -EINVAL;
-		}
-
-		pmem_type = MSM_PMEM_MAINIMG;
-		axi_data.bufnum2 =
-			msm_pmem_region_lookup(&sync->pmem_frames, pmem_type,
-				&region[axi_data.bufnum1],
-				(MAX_PMEM_CFG_BUFFERS-(axi_data.bufnum1)),
-				 &sync->pmem_frame_spinlock);
-		if (!axi_data.bufnum2) {
-			pr_err("%s %d: pmem region lookup error\n",
-				__func__, __LINE__);
-			return -EINVAL;
-		}
-		break;
-
-	case CMD_AXI_CFG_ZSL_ALL_CHNLS:
-	case CMD_AXI_CFG_ZSL:
-		CDBG("%s, CMD_AXI_CFG_ZSL, type = %d\n", __func__,
-			cfgcmd->cmd_type);
-		pmem_type = MSM_PMEM_PREVIEW;
-		axi_data.bufnum1 =
-			msm_pmem_region_lookup(&sync->pmem_frames, pmem_type,
-				&region[0], MAX_PMEM_CFG_BUFFERS,
-				&sync->pmem_frame_spinlock);
-		if (!axi_data.bufnum1) {
-			pr_err("%s %d: pmem region lookup error\n",
-				__func__, __LINE__);
-			return -EINVAL;
-		}
-
-		pmem_type = MSM_PMEM_THUMBNAIL;
-		axi_data.bufnum2 =
-			msm_pmem_region_lookup(&sync->pmem_frames, pmem_type,
-				&region[axi_data.bufnum1],
-				(MAX_PMEM_CFG_BUFFERS-(axi_data.bufnum1)),
-				 &sync->pmem_frame_spinlock);
-		if (!axi_data.bufnum2) {
-			pr_err("%s %d: pmem region lookup error\n",
-				__func__, __LINE__);
-			return -EINVAL;
-		}
-
-		pmem_type = MSM_PMEM_MAINIMG;
-		axi_data.bufnum3 =
-			msm_pmem_region_lookup(&sync->pmem_frames, pmem_type,
-				&region[axi_data.bufnum1 + axi_data.bufnum2],
-				(MAX_PMEM_CFG_BUFFERS - axi_data.bufnum1 -
-				axi_data.bufnum2), &sync->pmem_frame_spinlock);
-		if (!axi_data.bufnum3) {
-			pr_err("%s %d: pmem region lookup error\n",
-				__func__, __LINE__);
-			return -EINVAL;
-		}
-		break;
-
-	case CMD_RAW_PICT_AXI_CFG:
-		pmem_type = MSM_PMEM_RAW_MAINIMG;
-		axi_data.bufnum2 =
-			msm_pmem_region_lookup(&sync->pmem_frames, pmem_type,
-				&region[0], MAX_PMEM_CFG_BUFFERS,
-				&sync->pmem_frame_spinlock);
-		if (!axi_data.bufnum2) {
-			pr_err("%s %d: pmem region lookup error\n",
-				__func__, __LINE__);
-			return -EINVAL;
-		}
-		break;
-
-	case CMD_GENERAL:
-		data = NULL;
-		break;
-
-	default:
-		pr_err("%s: unknown command type %d\n",
-			__func__, cfgcmd->cmd_type);
-		return -EINVAL;
-	}
-
-	axi_data.region = &region[0];
-
-	/* send the AXI configuration command to driver */
-	if (sync->vfefn.vfe_config)
-		rc = sync->vfefn.vfe_config(cfgcmd, data);
-
-	return rc;
-}
-
-static int msm_get_sensor_info(struct msm_sync *sync, void __user *arg)
-{
-	int rc = 0;
-	struct msm_camsensor_info info;
-	struct msm_camera_sensor_info *sdata;
-
-	if (copy_from_user(&info,
-			arg,
-			sizeof(struct msm_camsensor_info))) {
-		ERR_COPY_FROM_USER();
-		return -EFAULT;
-	}
-
-	sdata = sync->pdev->dev.platform_data;
-	if (sync->sctrl.s_camera_type == BACK_CAMERA_3D)
-		info.support_3d = true;
-	else
-		info.support_3d = false;
-	memcpy(&info.name[0],
-		sdata->sensor_name,
-		MAX_SENSOR_NAME);
-	info.flash_enabled = sdata->flash_data->flash_type !=
-		MSM_CAMERA_FLASH_NONE;
-
-	/* copy back to user space */
-	if (copy_to_user((void *)arg,
-			&info,
-			sizeof(struct msm_camsensor_info))) {
-		ERR_COPY_TO_USER();
-		rc = -EFAULT;
-	}
-
-	return rc;
-}
-
-static int msm_get_camera_info(void __user *arg)
-{
-	int rc = 0;
-	int i = 0;
-	struct msm_camera_info info;
-
-	if (copy_from_user(&info, arg, sizeof(struct msm_camera_info))) {
-		ERR_COPY_FROM_USER();
-		return -EFAULT;
-	}
-
-	CDBG("%s: camera_node %d\n", __func__, camera_node);
-	info.num_cameras = camera_node;
-
-	for (i = 0; i < camera_node; i++) {
-		info.has_3d_support[i] = 0;
-		info.is_internal_cam[i] = 0;
-		info.s_mount_angle[i] = sensor_mount_angle[i];
-		switch (camera_type[i]) {
-		case FRONT_CAMERA_2D:
-			info.is_internal_cam[i] = 1;
-			break;
-		case BACK_CAMERA_3D:
-			info.has_3d_support[i] = 1;
-			break;
-		case BACK_CAMERA_2D:
-		default:
-			break;
-		}
-	}
-	/* copy back to user space */
-	if (copy_to_user((void *)arg, &info, sizeof(struct msm_camera_info))) {
-		ERR_COPY_TO_USER();
-		rc = -EFAULT;
-	}
-	return rc;
-}
-
-static int __msm_put_frame_buf(struct msm_sync *sync,
-		struct msm_frame *pb)
-{
-	unsigned long pphy;
-	struct msm_vfe_cfg_cmd cfgcmd;
-
-	int rc = -EIO;
-
-	/* Change the active flag. */
-	pphy = msm_pmem_frame_vtop_lookup(sync,
-		pb->buffer,
-		pb->planar0_off, pb->planar1_off, pb->planar2_off, pb->fd, 1);
-
-	if (pphy != 0) {
-		CDBG("%s: rel: vaddr %lx, paddr %lx\n",
-			__func__,
-			pb->buffer, pphy);
-		cfgcmd.cmd_type = CMD_FRAME_BUF_RELEASE;
-		cfgcmd.value    = (void *)pb;
-		if (sync->vfefn.vfe_config)
-			rc = sync->vfefn.vfe_config(&cfgcmd, &pphy);
-	} else {
-		pr_err("%s: msm_pmem_frame_vtop_lookup failed\n",
-			__func__);
-		rc = -EINVAL;
-	}
-
-	return rc;
-}
-static int __msm_put_pic_buf(struct msm_sync *sync,
-		struct msm_frame *pb)
-{
-	unsigned long pphy;
-	struct msm_vfe_cfg_cmd cfgcmd;
-
-	int rc = -EIO;
-
-	pphy = msm_pmem_frame_vtop_lookup(sync,
-		pb->buffer,
-		pb->planar0_off, pb->planar1_off, pb->planar2_off, pb->fd, 1);
-
-	if (pphy != 0) {
-		CDBG("%s: rel: vaddr %lx, paddr %lx\n",
-			__func__,
-			pb->buffer, pphy);
-		cfgcmd.cmd_type = CMD_SNAP_BUF_RELEASE;
-		cfgcmd.value    = (void *)pb;
-		if (sync->vfefn.vfe_config)
-			rc = sync->vfefn.vfe_config(&cfgcmd, &pphy);
-	} else {
-		pr_err("%s: msm_pmem_frame_vtop_lookup failed\n",
-			__func__);
-		rc = -EINVAL;
-	}
-
-	return rc;
-}
-
-
-static int msm_put_frame_buffer(struct msm_sync *sync, void __user *arg)
-{
-	struct msm_frame buf_t;
-
-	if (copy_from_user(&buf_t,
-				arg,
-				sizeof(struct msm_frame))) {
-		ERR_COPY_FROM_USER();
-		return -EFAULT;
-	}
-
-	return __msm_put_frame_buf(sync, &buf_t);
-}
-
-
-static int msm_put_pic_buffer(struct msm_sync *sync, void __user *arg)
-{
-	struct msm_frame buf_t;
-
-	if (copy_from_user(&buf_t,
-				arg,
-				sizeof(struct msm_frame))) {
-		ERR_COPY_FROM_USER();
-		return -EFAULT;
-	}
-
-	return __msm_put_pic_buf(sync, &buf_t);
-}
-
-static int __msm_register_pmem(struct msm_sync *sync,
-		struct msm_pmem_info *pinfo)
-{
-	int rc = 0;
-
-	switch (pinfo->type) {
-	case MSM_PMEM_VIDEO:
-	case MSM_PMEM_PREVIEW:
-	case MSM_PMEM_THUMBNAIL:
-	case MSM_PMEM_MAINIMG:
-	case MSM_PMEM_RAW_MAINIMG:
-	case MSM_PMEM_VIDEO_VPE:
-	case MSM_PMEM_C2D:
-	case MSM_PMEM_MAINIMG_VPE:
-	case MSM_PMEM_THUMBNAIL_VPE:
-		rc = msm_pmem_table_add(&sync->pmem_frames, pinfo,
-			&sync->pmem_frame_spinlock, sync);
-		break;
-
-	case MSM_PMEM_AEC_AWB:
-	case MSM_PMEM_AF:
-	case MSM_PMEM_AEC:
-	case MSM_PMEM_AWB:
-	case MSM_PMEM_RS:
-	case MSM_PMEM_CS:
-	case MSM_PMEM_IHIST:
-	case MSM_PMEM_SKIN:
-
-		rc = msm_pmem_table_add(&sync->pmem_stats, pinfo,
-			 &sync->pmem_stats_spinlock, sync);
-		break;
-
-	default:
-		rc = -EINVAL;
-		break;
-	}
-
-	return rc;
-}
-
-static int msm_register_pmem(struct msm_sync *sync, void __user *arg)
-{
-	struct msm_pmem_info info;
-
-	if (copy_from_user(&info, arg, sizeof(info))) {
-		ERR_COPY_FROM_USER();
-		return -EFAULT;
-	}
-
-	return __msm_register_pmem(sync, &info);
-}
-
-static int msm_stats_axi_cfg(struct msm_sync *sync,
-		struct msm_vfe_cfg_cmd *cfgcmd)
-{
-	int rc = -EIO;
-	struct axidata axi_data;
-	void *data = &axi_data;
-
-	struct msm_pmem_region region[3];
-	int pmem_type = MSM_PMEM_MAX;
-
-	memset(&axi_data, 0, sizeof(axi_data));
-
-	switch (cfgcmd->cmd_type) {
-	case CMD_STATS_AXI_CFG:
-		pmem_type = MSM_PMEM_AEC_AWB;
-		break;
-	case CMD_STATS_AF_AXI_CFG:
-		pmem_type = MSM_PMEM_AF;
-		break;
-	case CMD_GENERAL:
-		data = NULL;
-		break;
-	default:
-		pr_err("%s: unknown command type %d\n",
-			__func__, cfgcmd->cmd_type);
-		return -EINVAL;
-	}
-
-	if (cfgcmd->cmd_type != CMD_GENERAL) {
-		axi_data.bufnum1 =
-			msm_pmem_region_lookup(&sync->pmem_stats, pmem_type,
-				&region[0], NUM_STAT_OUTPUT_BUFFERS,
-				&sync->pmem_stats_spinlock);
-		if (!axi_data.bufnum1) {
-			pr_err("%s %d: pmem region lookup error\n",
-				__func__, __LINE__);
-			return -EINVAL;
-		}
-	axi_data.region = &region[0];
-	}
-
-	/* send the AEC/AWB STATS configuration command to driver */
-	if (sync->vfefn.vfe_config)
-		rc = sync->vfefn.vfe_config(cfgcmd, &axi_data);
-
-	return rc;
-}
-
-static int msm_put_stats_buffer(struct msm_sync *sync, void __user *arg)
-{
-	int rc = -EIO;
-
-	struct msm_stats_buf buf;
-	unsigned long pphy;
-	struct msm_vfe_cfg_cmd cfgcmd;
-
-	if (copy_from_user(&buf, arg,
-				sizeof(struct msm_stats_buf))) {
-		ERR_COPY_FROM_USER();
-		return -EFAULT;
-	}
-
-	CDBG("%s\n", __func__);
-	pphy = msm_pmem_stats_vtop_lookup(sync, buf.buffer, buf.fd);
-
-	if (pphy != 0) {
-		if (buf.type == STAT_AEAW)
-			cfgcmd.cmd_type = CMD_STATS_BUF_RELEASE;
-		else if (buf.type == STAT_AF)
-			cfgcmd.cmd_type = CMD_STATS_AF_BUF_RELEASE;
-		else if (buf.type == STAT_AEC)
-			cfgcmd.cmd_type = CMD_STATS_AEC_BUF_RELEASE;
-		else if (buf.type == STAT_AWB)
-			cfgcmd.cmd_type = CMD_STATS_AWB_BUF_RELEASE;
-		else if (buf.type == STAT_IHIST)
-			cfgcmd.cmd_type = CMD_STATS_IHIST_BUF_RELEASE;
-		else if (buf.type == STAT_RS)
-			cfgcmd.cmd_type = CMD_STATS_RS_BUF_RELEASE;
-		else if (buf.type == STAT_CS)
-			cfgcmd.cmd_type = CMD_STATS_CS_BUF_RELEASE;
-
-		else {
-			pr_err("%s: invalid buf type %d\n",
-				__func__,
-				buf.type);
-			rc = -EINVAL;
-			goto put_done;
-		}
-
-		cfgcmd.value = (void *)&buf;
-
-		if (sync->vfefn.vfe_config) {
-			rc = sync->vfefn.vfe_config(&cfgcmd, &pphy);
-			if (rc < 0)
-				pr_err("%s: vfe_config error %d\n",
-					__func__, rc);
-		} else
-			pr_err("%s: vfe_config is NULL\n", __func__);
-	} else {
-		pr_err("%s: NULL physical address\n", __func__);
-		rc = -EINVAL;
-	}
-
-put_done:
-	return rc;
-}
-
-static int msm_axi_config(struct msm_sync *sync, void __user *arg)
-{
-	struct msm_vfe_cfg_cmd cfgcmd;
-
-	if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
-		ERR_COPY_FROM_USER();
-		return -EFAULT;
-	}
-
-	switch (cfgcmd.cmd_type) {
-	case CMD_AXI_CFG_VIDEO:
-	case CMD_AXI_CFG_PREVIEW:
-	case CMD_AXI_CFG_SNAP:
-	case CMD_RAW_PICT_AXI_CFG:
-	case CMD_AXI_CFG_ZSL:
-	case CMD_AXI_CFG_VIDEO_ALL_CHNLS:
-	case CMD_AXI_CFG_ZSL_ALL_CHNLS:
-		CDBG("%s, cfgcmd.cmd_type = %d\n", __func__, cfgcmd.cmd_type);
-		return msm_frame_axi_cfg(sync, &cfgcmd);
-
-	case CMD_AXI_CFG_VPE:
-	case CMD_AXI_CFG_SNAP_VPE:
-	case CMD_AXI_CFG_SNAP_THUMB_VPE:
-		return msm_vpe_frame_cfg(sync, (void *)&cfgcmd);
-
-	case CMD_STATS_AXI_CFG:
-	case CMD_STATS_AF_AXI_CFG:
-		return msm_stats_axi_cfg(sync, &cfgcmd);
-
-	default:
-		pr_err("%s: unknown command type %d\n",
-			__func__,
-			cfgcmd.cmd_type);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int __msm_get_pic(struct msm_sync *sync,
-		struct msm_frame *frame)
-{
-
-	int rc = 0;
-	struct msm_queue_cmd *qcmd = NULL;
-	struct msm_vfe_resp *vdata;
-	struct msm_vfe_phy_info *pphy;
-	struct msm_pmem_info pmem_info;
-	struct msm_frame *pframe;
-
-	qcmd = msm_dequeue(&sync->pict_q, list_pict);
-
-	if (!qcmd) {
-		pr_err("%s: no pic frame.\n", __func__);
-		return -EAGAIN;
-	}
-
-	if (MSM_CAM_Q_PP_MSG != qcmd->type) {
-		vdata = (struct msm_vfe_resp *)(qcmd->command);
-		pphy = &vdata->phy;
-
-		rc = msm_pmem_frame_ptov_lookup2(sync,
-				pphy->p0_phy,
-				&pmem_info,
-				1); /* mark pic frame in use */
-
-		if (rc < 0) {
-			pr_err("%s: cannot get pic frame, invalid lookup"
-				" address p0_phy add  %x p1_phy add%x\n",
-				__func__, pphy->p0_phy, pphy->p1_phy);
-			goto err;
-		}
-
-		frame->ts = qcmd->ts;
-		frame->buffer = (unsigned long)pmem_info.vaddr;
-		frame->planar0_off = pmem_info.planar0_off;
-		frame->planar1_off = pmem_info.planar1_off;
-		frame->fd = pmem_info.fd;
-		if (sync->stereocam_enabled &&
-			sync->stereo_state != STEREO_RAW_SNAP_STARTED) {
-			if (pmem_info.type == MSM_PMEM_THUMBNAIL_VPE)
-				frame->path = OUTPUT_TYPE_T;
-			else
-				frame->path = OUTPUT_TYPE_S;
-		} else
-			frame->path = vdata->phy.output_id;
-
-		CDBG("%s:p0_phy add %x, p0_phy add %x, qcmd %x, virt_addr %x\n",
-			__func__, pphy->p0_phy,
-			pphy->p1_phy, (int) qcmd, (int) frame->buffer);
-	} else { /* PP */
-		pframe = (struct msm_frame *)(qcmd->command);
-		frame->ts = qcmd->ts;
-		frame->buffer = pframe->buffer;
-		frame->planar0_off = pframe->planar0_off;
-		frame->planar1_off = pframe->planar1_off;
-		frame->fd = pframe->fd;
-		frame->path = pframe->path;
-		CDBG("%s: PP y_off %x, cbcr_off %x, path %d vaddr 0x%x\n",
-		__func__, frame->planar0_off, frame->planar1_off, frame->path,
-		(int) frame->buffer);
-	}
-
-err:
-	free_qcmd(qcmd);
-
-	return rc;
-}
-
-static int msm_get_pic(struct msm_sync *sync, void __user *arg)
-{
-	int rc = 0;
-	struct msm_frame frame;
-
-	if (copy_from_user(&frame,
-				arg,
-				sizeof(struct msm_frame))) {
-		ERR_COPY_FROM_USER();
-		return -EFAULT;
-	}
-
-	rc = __msm_get_pic(sync, &frame);
-	if (rc < 0)
-		return rc;
-
-	if (sync->croplen && (!sync->stereocam_enabled)) {
-		if (frame.croplen != sync->croplen) {
-			pr_err("%s: invalid frame croplen %d,"
-				"expecting %d\n",
-				__func__,
-				frame.croplen,
-				sync->croplen);
-			return -EINVAL;
-		}
-
-		if (copy_to_user((void *)frame.cropinfo,
-				sync->cropinfo,
-				sync->croplen)) {
-			ERR_COPY_TO_USER();
-			return -EFAULT;
-		}
-	}
-	CDBG("%s: copy snapshot frame to user\n", __func__);
-	if (copy_to_user((void *)arg,
-				&frame, sizeof(struct msm_frame))) {
-		ERR_COPY_TO_USER();
-		rc = -EFAULT;
-	}
-
-	CDBG("%s: got pic frame\n", __func__);
-
-	return rc;
-}
-
-static int msm_set_crop(struct msm_sync *sync, void __user *arg)
-{
-	struct crop_info crop;
-
-	mutex_lock(&sync->lock);
-	if (copy_from_user(&crop,
-				arg,
-				sizeof(struct crop_info))) {
-		ERR_COPY_FROM_USER();
-		mutex_unlock(&sync->lock);
-		return -EFAULT;
-	}
-
-	if (crop.len != CROP_LEN) {
-		mutex_unlock(&sync->lock);
-		return -EINVAL;
-	}
-
-	if (!sync->croplen) {
-		sync->cropinfo = kmalloc(crop.len, GFP_KERNEL);
-		if (!sync->cropinfo) {
-			mutex_unlock(&sync->lock);
-			return -ENOMEM;
-		}
-	}
-
-	if (copy_from_user(sync->cropinfo,
-				crop.info,
-				crop.len)) {
-		ERR_COPY_FROM_USER();
-		sync->croplen = 0;
-		kfree(sync->cropinfo);
-		mutex_unlock(&sync->lock);
-		return -EFAULT;
-	}
-
-	sync->croplen = crop.len;
-
-	mutex_unlock(&sync->lock);
-	return 0;
-}
-
-static int msm_error_config(struct msm_sync *sync, void __user *arg)
-{
-	struct msm_queue_cmd *qcmd =
-		kmalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
-
-	qcmd->command = NULL;
-
-	if (qcmd)
-		atomic_set(&(qcmd->on_heap), 1);
-
-	if (copy_from_user(&(qcmd->error_code), arg, sizeof(uint32_t))) {
-		ERR_COPY_FROM_USER();
-		free_qcmd(qcmd);
-		return -EFAULT;
-	}
-
-	pr_err("%s: Enqueue Fake Frame with error code = %d\n", __func__,
-		qcmd->error_code);
-	msm_enqueue(&sync->frame_q, &qcmd->list_frame);
-	return 0;
-}
-
-static int msm_set_fd_roi(struct msm_sync *sync, void __user *arg)
-{
-	struct fd_roi_info fd_roi;
-
-	mutex_lock(&sync->lock);
-	if (copy_from_user(&fd_roi,
-			arg,
-			sizeof(struct fd_roi_info))) {
-		ERR_COPY_FROM_USER();
-		mutex_unlock(&sync->lock);
-		return -EFAULT;
-	}
-	if (fd_roi.info_len <= 0) {
-		mutex_unlock(&sync->lock);
-		return -EFAULT;
-	}
-
-	if (!sync->fdroiinfo.info) {
-		sync->fdroiinfo.info = kmalloc(fd_roi.info_len, GFP_KERNEL);
-		if (!sync->fdroiinfo.info) {
-			mutex_unlock(&sync->lock);
-			return -ENOMEM;
-		}
-		sync->fdroiinfo.info_len = fd_roi.info_len;
-	} else if (sync->fdroiinfo.info_len < fd_roi.info_len) {
-		mutex_unlock(&sync->lock);
-		return -EINVAL;
-    }
-
-	if (copy_from_user(sync->fdroiinfo.info,
-			fd_roi.info,
-			fd_roi.info_len)) {
-		ERR_COPY_FROM_USER();
-		kfree(sync->fdroiinfo.info);
-		sync->fdroiinfo.info = NULL;
-		mutex_unlock(&sync->lock);
-		return -EFAULT;
-	}
-	mutex_unlock(&sync->lock);
-	return 0;
-}
-
-static int msm_pp_grab(struct msm_sync *sync, void __user *arg)
-{
-	uint32_t enable;
-	if (copy_from_user(&enable, arg, sizeof(enable))) {
-		ERR_COPY_FROM_USER();
-		return -EFAULT;
-	} else {
-		enable &= PP_MASK;
-		if (enable & (enable - 1)) {
-			CDBG("%s: more than one PP request!\n",
-				__func__);
-		}
-		if (sync->pp_mask) {
-			if (enable) {
-				CDBG("%s: postproc %x is already enabled\n",
-					__func__, sync->pp_mask & enable);
-			} else {
-				sync->pp_mask &= enable;
-				CDBG("%s: sync->pp_mask %d enable %d\n",
-					__func__, sync->pp_mask, enable);
-			}
-		}
-
-		CDBG("%s: sync->pp_mask %d enable %d\n", __func__,
-			sync->pp_mask, enable);
-		sync->pp_mask |= enable;
-	}
-
-	return 0;
-}
-
-static int msm_put_st_frame(struct msm_sync *sync, void __user *arg)
-{
-	unsigned long flags;
-	unsigned long st_pphy;
-	if (sync->stereocam_enabled) {
-		/* Make stereo frame ready for VPE. */
-		struct msm_st_frame stereo_frame_half;
-
-		if (copy_from_user(&stereo_frame_half, arg,
-			sizeof(stereo_frame_half))) {
-			ERR_COPY_FROM_USER();
-			return -EFAULT;
-		}
-
-		if (stereo_frame_half.type == OUTPUT_TYPE_ST_L) {
-			struct msm_vfe_resp *vfe_rp;
-			struct msm_queue_cmd *qcmd;
-
-			spin_lock_irqsave(&pp_stereocam_spinlock, flags);
-			if (!sync->pp_stereocam) {
-				pr_warning("%s: no stereo frame to deliver!\n",
-					__func__);
-				spin_unlock_irqrestore(&pp_stereocam_spinlock,
-					flags);
-				return -EINVAL;
-			}
-			CDBG("%s: delivering left frame to VPE\n", __func__);
-
-			qcmd = sync->pp_stereocam;
-			sync->pp_stereocam = NULL;
-			spin_unlock_irqrestore(&pp_stereocam_spinlock, flags);
-
-			vfe_rp = (struct msm_vfe_resp *)qcmd->command;
-
-			CDBG("%s: Left Py = 0x%x y_off = %d cbcr_off = %d\n",
-				__func__, vfe_rp->phy.p0_phy,
-				stereo_frame_half.L.buf_p0_off,
-				stereo_frame_half.L.buf_p1_off);
-
-			sync->vpefn.vpe_cfg_offset(stereo_frame_half.packing,
-			vfe_rp->phy.p0_phy + stereo_frame_half.L.buf_p0_off,
-			vfe_rp->phy.p1_phy + stereo_frame_half.L.buf_p1_off,
-			&(qcmd->ts), OUTPUT_TYPE_ST_L, stereo_frame_half.L,
-			stereo_frame_half.frame_id);
-
-			free_qcmd(qcmd);
-		} else if (stereo_frame_half.type == OUTPUT_TYPE_ST_R) {
-			CDBG("%s: delivering right frame to VPE\n", __func__);
-			spin_lock_irqsave(&st_frame_spinlock, flags);
-
-			sync->stcam_conv_value =
-				stereo_frame_half.buf_info.stcam_conv_value;
-			sync->stcam_quality_ind =
-				stereo_frame_half.buf_info.stcam_quality_ind;
-
-			st_pphy = msm_pmem_frame_vtop_lookup(sync,
-				stereo_frame_half.buf_info.buffer,
-				stereo_frame_half.buf_info.planar0_off,
-				stereo_frame_half.buf_info.planar1_off,
-				stereo_frame_half.buf_info.planar2_off,
-				stereo_frame_half.buf_info.fd,
-				0); /* Do not change the active flag. */
-
-			sync->vpefn.vpe_cfg_offset(stereo_frame_half.packing,
-				st_pphy + stereo_frame_half.R.buf_p0_off,
-				st_pphy + stereo_frame_half.R.buf_p1_off,
-				NULL, OUTPUT_TYPE_ST_R, stereo_frame_half.R,
-				stereo_frame_half.frame_id);
-
-			spin_unlock_irqrestore(&st_frame_spinlock, flags);
-		} else {
-			CDBG("%s: Invalid Msg\n", __func__);
-		}
-	}
-
-	return 0;
-}
-
-static struct msm_queue_cmd *msm_get_pp_qcmd(struct msm_frame* frame)
-{
-	struct msm_queue_cmd *qcmd =
-		kmalloc(sizeof(struct msm_queue_cmd) +
-			sizeof(struct msm_frame), GFP_ATOMIC);
-	qcmd->command = (struct msm_frame *)(qcmd + 1);
-
-	qcmd->type = MSM_CAM_Q_PP_MSG;
-
-	ktime_get_ts(&(qcmd->ts));
-	memcpy(qcmd->command, frame, sizeof(struct msm_frame));
-	atomic_set(&(qcmd->on_heap), 1);
-	return qcmd;
-}
-
-static int msm_pp_release(struct msm_sync *sync, void __user *arg)
-{
-	unsigned long flags;
-
-	if (!sync->pp_mask) {
-		pr_warning("%s: pp not in progress for\n", __func__);
-		return -EINVAL;
-	}
-	if (sync->pp_mask & PP_PREV) {
-
-
-		spin_lock_irqsave(&pp_prev_spinlock, flags);
-		if (!sync->pp_prev) {
-			pr_err("%s: no preview frame to deliver!\n",
-				__func__);
-			spin_unlock_irqrestore(&pp_prev_spinlock,
-				flags);
-			return -EINVAL;
-		}
-		CDBG("%s: delivering pp_prev\n", __func__);
-
-			if (sync->frame_q.len <= 100 &&
-				sync->event_q.len <= 100) {
-					msm_enqueue(&sync->frame_q,
-						&sync->pp_prev->list_frame);
-			} else {
-				pr_err("%s, Error Queue limit exceeded f_q=%d,\
-					e_q = %d\n",
-					__func__, sync->frame_q.len,
-					sync->event_q.len);
-				free_qcmd(sync->pp_prev);
-				goto done;
-			}
-
-			sync->pp_prev = NULL;
-			spin_unlock_irqrestore(&pp_prev_spinlock, flags);
-		goto done;
-	}
-
-	if ((sync->pp_mask & PP_SNAP) ||
-		(sync->pp_mask & PP_RAW_SNAP)) {
-		struct msm_frame frame;
-		struct msm_queue_cmd *qcmd;
-
-		if (copy_from_user(&frame,
-			arg,
-			sizeof(struct msm_frame))) {
-			ERR_COPY_FROM_USER();
-			return -EFAULT;
-		}
-		qcmd = msm_get_pp_qcmd(&frame);
-		if (!qcmd) {
-			pr_err("%s: no snapshot to deliver!\n", __func__);
-			return -EINVAL;
-		}
-		CDBG("%s: delivering pp snap\n", __func__);
-		msm_enqueue(&sync->pict_q, &qcmd->list_pict);
-	}
-
-done:
-	return 0;
-}
-
-static long msm_ioctl_common(struct msm_cam_device *pmsm,
-		unsigned int cmd,
-		void __user *argp)
-{
-	switch (cmd) {
-	case MSM_CAM_IOCTL_REGISTER_PMEM:
-		CDBG("%s cmd = MSM_CAM_IOCTL_REGISTER_PMEM\n", __func__);
-		return msm_register_pmem(pmsm->sync, argp);
-	case MSM_CAM_IOCTL_UNREGISTER_PMEM:
-		CDBG("%s cmd = MSM_CAM_IOCTL_UNREGISTER_PMEM\n", __func__);
-		return msm_pmem_table_del(pmsm->sync, argp);
-	case MSM_CAM_IOCTL_RELEASE_FRAME_BUFFER:
-		CDBG("%s cmd = MSM_CAM_IOCTL_RELEASE_FRAME_BUFFER\n", __func__);
-		return msm_put_frame_buffer(pmsm->sync, argp);
-		break;
-	default:
-		CDBG("%s cmd invalid\n", __func__);
-		return -EINVAL;
-	}
-}
-
-static long msm_ioctl_config(struct file *filep, unsigned int cmd,
-	unsigned long arg)
-{
-	int rc = -EINVAL;
-	void __user *argp = (void __user *)arg;
-	struct msm_cam_device *pmsm = filep->private_data;
-
-	CDBG("%s: cmd %d\n", __func__, _IOC_NR(cmd));
-
-	switch (cmd) {
-	case MSM_CAM_IOCTL_GET_SENSOR_INFO:
-		rc = msm_get_sensor_info(pmsm->sync, argp);
-		break;
-
-	case MSM_CAM_IOCTL_CONFIG_VFE:
-		/* Coming from config thread for update */
-		rc = msm_config_vfe(pmsm->sync, argp);
-		break;
-
-	case MSM_CAM_IOCTL_CONFIG_VPE:
-		/* Coming from config thread for update */
-		rc = msm_config_vpe(pmsm->sync, argp);
-		break;
-
-	case MSM_CAM_IOCTL_GET_STATS:
-		/* Coming from config thread wait
-		 * for vfe statistics and control requests */
-		rc = msm_get_stats(pmsm->sync, argp);
-		break;
-
-	case MSM_CAM_IOCTL_ENABLE_VFE:
-		/* This request comes from control thread:
-		 * enable either QCAMTASK or VFETASK */
-		rc = msm_enable_vfe(pmsm->sync, argp);
-		break;
-
-	case MSM_CAM_IOCTL_DISABLE_VFE:
-		/* This request comes from control thread:
-		 * disable either QCAMTASK or VFETASK */
-		rc = msm_disable_vfe(pmsm->sync, argp);
-		break;
-
-	case MSM_CAM_IOCTL_VFE_APPS_RESET:
-		msm_camio_vfe_blk_reset();
-		rc = 0;
-		break;
-
-	case MSM_CAM_IOCTL_RELEASE_STATS_BUFFER:
-		rc = msm_put_stats_buffer(pmsm->sync, argp);
-		break;
-
-	case MSM_CAM_IOCTL_AXI_CONFIG:
-	case MSM_CAM_IOCTL_AXI_VPE_CONFIG:
-		rc = msm_axi_config(pmsm->sync, argp);
-		break;
-
-	case MSM_CAM_IOCTL_SET_CROP:
-		rc = msm_set_crop(pmsm->sync, argp);
-		break;
-
-	case MSM_CAM_IOCTL_SET_FD_ROI:
-		rc = msm_set_fd_roi(pmsm->sync, argp);
-		break;
-
-	case MSM_CAM_IOCTL_PICT_PP:
-		/* Grab one preview frame or one snapshot
-		 * frame.
-		 */
-		rc = msm_pp_grab(pmsm->sync, argp);
-		break;
-
-	case MSM_CAM_IOCTL_PICT_PP_DONE:
-		/* Release the preview of snapshot frame
-		 * that was grabbed.
-		 */
-		rc = msm_pp_release(pmsm->sync, argp);
-		break;
-
-	case MSM_CAM_IOCTL_PUT_ST_FRAME:
-		/* Release the left or right frame
-		 * that was sent for stereo processing.
-		 */
-		rc = msm_put_st_frame(pmsm->sync, argp);
-		break;
-
-	case MSM_CAM_IOCTL_SENSOR_IO_CFG:
-		rc = pmsm->sync->sctrl.s_config(argp);
-		break;
-
-	case MSM_CAM_IOCTL_ERROR_CONFIG:
-		rc = msm_error_config(pmsm->sync, argp);
-		break;
-
-	case MSM_CAM_IOCTL_ABORT_CAPTURE: {
-		unsigned long flags = 0;
-		CDBG("get_pic:MSM_CAM_IOCTL_ABORT_CAPTURE\n");
-		spin_lock_irqsave(&pmsm->sync->abort_pict_lock, flags);
-		pmsm->sync->get_pic_abort = 1;
-		spin_unlock_irqrestore(&pmsm->sync->abort_pict_lock, flags);
-		wake_up(&(pmsm->sync->pict_q.wait));
-		rc = 0;
-		break;
-	}
-
-	default:
-		rc = msm_ioctl_common(pmsm, cmd, argp);
-		break;
-	}
-
-	CDBG("%s: cmd %d DONE\n", __func__, _IOC_NR(cmd));
-	return rc;
-}
-
-static int msm_unblock_poll_frame(struct msm_sync *);
-
-static long msm_ioctl_frame(struct file *filep, unsigned int cmd,
-	unsigned long arg)
-{
-	int rc = -EINVAL;
-	void __user *argp = (void __user *)arg;
-	struct msm_cam_device *pmsm = filep->private_data;
-
-
-	switch (cmd) {
-	case MSM_CAM_IOCTL_GETFRAME:
-		/* Coming from frame thread to get frame
-		 * after SELECT is done */
-		rc = msm_get_frame(pmsm->sync, argp);
-		break;
-	case MSM_CAM_IOCTL_RELEASE_FRAME_BUFFER:
-		rc = msm_put_frame_buffer(pmsm->sync, argp);
-		break;
-	case MSM_CAM_IOCTL_UNBLOCK_POLL_FRAME:
-		rc = msm_unblock_poll_frame(pmsm->sync);
-		break;
-	default:
-		break;
-	}
-
-	return rc;
-}
-
-static int msm_unblock_poll_pic(struct msm_sync *sync);
-static long msm_ioctl_pic(struct file *filep, unsigned int cmd,
-	unsigned long arg)
-{
-	int rc = -EINVAL;
-	void __user *argp = (void __user *)arg;
-	struct msm_cam_device *pmsm = filep->private_data;
-
-
-	switch (cmd) {
-	case MSM_CAM_IOCTL_GET_PICTURE:
-		rc = msm_get_pic(pmsm->sync, argp);
-		break;
-	case MSM_CAM_IOCTL_RELEASE_PIC_BUFFER:
-		rc = msm_put_pic_buffer(pmsm->sync, argp);
-		break;
-	case MSM_CAM_IOCTL_UNBLOCK_POLL_PIC_FRAME:
-		rc = msm_unblock_poll_pic(pmsm->sync);
-		break;
-	default:
-		break;
-	}
-
-	return rc;
-}
-
-
-static long msm_ioctl_control(struct file *filep, unsigned int cmd,
-	unsigned long arg)
-{
-	int rc = -EINVAL;
-	void __user *argp = (void __user *)arg;
-	struct msm_control_device *ctrl_pmsm = filep->private_data;
-	struct msm_cam_device *pmsm = ctrl_pmsm->pmsm;
-
-	switch (cmd) {
-	case MSM_CAM_IOCTL_CTRL_COMMAND:
-		/* Coming from control thread, may need to wait for
-		 * command status */
-		CDBG("calling msm_control kernel msm_ioctl_control\n");
-		mutex_lock(&ctrl_cmd_lock);
-		rc = msm_control(ctrl_pmsm, 1, argp);
-		mutex_unlock(&ctrl_cmd_lock);
-		break;
-	case MSM_CAM_IOCTL_CTRL_COMMAND_2:
-		/* Sends a message, returns immediately */
-		rc = msm_control(ctrl_pmsm, 0, argp);
-		break;
-	case MSM_CAM_IOCTL_CTRL_CMD_DONE:
-		/* Config thread calls the control thread to notify it
-		 * of the result of a MSM_CAM_IOCTL_CTRL_COMMAND.
-		 */
-		rc = msm_ctrl_cmd_done(ctrl_pmsm, argp);
-		break;
-	case MSM_CAM_IOCTL_GET_SENSOR_INFO:
-		rc = msm_get_sensor_info(pmsm->sync, argp);
-		break;
-	case MSM_CAM_IOCTL_GET_CAMERA_INFO:
-		rc = msm_get_camera_info(argp);
-		break;
-	default:
-		rc = msm_ioctl_common(pmsm, cmd, argp);
-		break;
-	}
-
-	return rc;
-}
-
-static int __msm_release(struct msm_sync *sync)
-{
-	struct msm_pmem_region *region;
-	struct hlist_node *hnode;
-	struct hlist_node *n;
-
-	mutex_lock(&sync->lock);
-	if (sync->opencnt)
-		sync->opencnt--;
-	pr_info("%s, open count =%d\n", __func__, sync->opencnt);
-	if (!sync->opencnt) {
-		/* need to clean up system resource */
-		pr_info("%s, release VFE\n", __func__);
-		if (sync->core_powered_on) {
-			if (sync->vfefn.vfe_release)
-				sync->vfefn.vfe_release(sync->pdev);
-			/*sensor release */
-			pr_info("%s, release Sensor\n", __func__);
-			sync->sctrl.s_release();
-			CDBG("%s, msm_camio_sensor_clk_off\n", __func__);
-			msm_camio_sensor_clk_off(sync->pdev);
-			if (sync->sfctrl.strobe_flash_release) {
-				CDBG("%s, strobe_flash_release\n", __func__);
-				sync->sfctrl.strobe_flash_release(
-				sync->sdata->strobe_flash_data, 1);
-			}
-		}
-		kfree(sync->cropinfo);
-		sync->cropinfo = NULL;
-		sync->croplen = 0;
-		CDBG("%s, free frame pmem region\n", __func__);
-		hlist_for_each_entry_safe(region, hnode, n,
-				&sync->pmem_frames, list) {
-			hlist_del(hnode);
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-				ion_free(client_for_ion, region->handle);
-#else
-			put_pmem_file(region->file);
-#endif
-			kfree(region);
-		}
-		CDBG("%s, free stats pmem region\n", __func__);
-		hlist_for_each_entry_safe(region, hnode, n,
-				&sync->pmem_stats, list) {
-			hlist_del(hnode);
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-				ion_free(client_for_ion, region->handle);
-#else
-			put_pmem_file(region->file);
-#endif
-			kfree(region);
-		}
-		msm_queue_drain(&sync->pict_q, list_pict);
-		msm_queue_drain(&sync->event_q, list_config);
-
-		pm_qos_update_request(&sync->idle_pm_qos, PM_QOS_DEFAULT_VALUE);
-		sync->apps_id = NULL;
-		sync->core_powered_on = 0;
-	}
-	mutex_unlock(&sync->lock);
-	ion_client_destroy(client_for_ion);
-
-	return 0;
-}
-
-static int msm_release_config(struct inode *node, struct file *filep)
-{
-	int rc;
-	struct msm_cam_device *pmsm = filep->private_data;
-	pr_info("%s: %s\n", __func__, filep->f_path.dentry->d_name.name);
-	rc = __msm_release(pmsm->sync);
-	if (!rc) {
-		msm_queue_drain(&pmsm->sync->event_q, list_config);
-		atomic_set(&pmsm->opened, 0);
-	}
-	return rc;
-}
-
-static int msm_release_control(struct inode *node, struct file *filep)
-{
-	int rc;
-	struct msm_control_device *ctrl_pmsm = filep->private_data;
-	struct msm_cam_device *pmsm = ctrl_pmsm->pmsm;
-	pr_info("%s: %s\n", __func__, filep->f_path.dentry->d_name.name);
-	g_v4l2_opencnt--;
-	mutex_lock(&pmsm->sync->lock);
-	if (pmsm->sync->core_powered_on && pmsm->sync->vfefn.vfe_stop) {
-		pr_info("%s, stop vfe if active\n", __func__);
-		pmsm->sync->vfefn.vfe_stop();
-	}
-	mutex_unlock(&pmsm->sync->lock);
-	rc = __msm_release(pmsm->sync);
-	if (!rc) {
-		msm_queue_drain(&ctrl_pmsm->ctrl_q, list_control);
-		kfree(ctrl_pmsm);
-	}
-	return rc;
-}
-
-static int msm_release_frame(struct inode *node, struct file *filep)
-{
-	int rc;
-	struct msm_cam_device *pmsm = filep->private_data;
-	pr_info("%s: %s\n", __func__, filep->f_path.dentry->d_name.name);
-	rc = __msm_release(pmsm->sync);
-	if (!rc) {
-		msm_queue_drain(&pmsm->sync->frame_q, list_frame);
-		atomic_set(&pmsm->opened, 0);
-	}
-	return rc;
-}
-
-
-static int msm_release_pic(struct inode *node, struct file *filep)
-{
-	int rc;
-	struct msm_cam_device *pmsm = filep->private_data;
-	CDBG("%s: %s\n", __func__, filep->f_path.dentry->d_name.name);
-	rc = __msm_release(pmsm->sync);
-	if (!rc) {
-		msm_queue_drain(&pmsm->sync->pict_q, list_pict);
-		atomic_set(&pmsm->opened, 0);
-	}
-	return rc;
-}
-
-static int msm_unblock_poll_pic(struct msm_sync *sync)
-{
-	unsigned long flags;
-	CDBG("%s\n", __func__);
-	spin_lock_irqsave(&sync->pict_q.lock, flags);
-	sync->unblock_poll_pic_frame = 1;
-	wake_up(&sync->pict_q.wait);
-	spin_unlock_irqrestore(&sync->pict_q.lock, flags);
-	return 0;
-}
-
-static int msm_unblock_poll_frame(struct msm_sync *sync)
-{
-	unsigned long flags;
-	CDBG("%s\n", __func__);
-	spin_lock_irqsave(&sync->frame_q.lock, flags);
-	sync->unblock_poll_frame = 1;
-	wake_up(&sync->frame_q.wait);
-	spin_unlock_irqrestore(&sync->frame_q.lock, flags);
-	return 0;
-}
-
-static unsigned int __msm_poll_frame(struct msm_sync *sync,
-		struct file *filep,
-		struct poll_table_struct *pll_table)
-{
-	int rc = 0;
-	unsigned long flags;
-
-	poll_wait(filep, &sync->frame_q.wait, pll_table);
-
-	spin_lock_irqsave(&sync->frame_q.lock, flags);
-	if (!list_empty_careful(&sync->frame_q.list))
-		/* frame ready */
-		rc = POLLIN | POLLRDNORM;
-	if (sync->unblock_poll_frame) {
-		CDBG("%s: sync->unblock_poll_frame is true\n", __func__);
-		rc |= POLLPRI;
-		sync->unblock_poll_frame = 0;
-	}
-	spin_unlock_irqrestore(&sync->frame_q.lock, flags);
-
-	return rc;
-}
-
-static unsigned int __msm_poll_pic(struct msm_sync *sync,
-		struct file *filep,
-		struct poll_table_struct *pll_table)
-{
-	int rc = 0;
-	unsigned long flags;
-
-	poll_wait(filep, &sync->pict_q.wait , pll_table);
-	spin_lock_irqsave(&sync->abort_pict_lock, flags);
-	if (sync->get_pic_abort == 1) {
-		/* TODO: need to pass an error case */
-		sync->get_pic_abort = 0;
-	}
-	spin_unlock_irqrestore(&sync->abort_pict_lock, flags);
-
-	spin_lock_irqsave(&sync->pict_q.lock, flags);
-	if (!list_empty_careful(&sync->pict_q.list))
-		/* frame ready */
-		rc = POLLIN | POLLRDNORM;
-	if (sync->unblock_poll_pic_frame) {
-		CDBG("%s: sync->unblock_poll_pic_frame is true\n", __func__);
-		rc |= POLLPRI;
-		sync->unblock_poll_pic_frame = 0;
-	}
-	spin_unlock_irqrestore(&sync->pict_q.lock, flags);
-
-	return rc;
-}
-
-static unsigned int msm_poll_frame(struct file *filep,
-	struct poll_table_struct *pll_table)
-{
-	struct msm_cam_device *pmsm = filep->private_data;
-	return __msm_poll_frame(pmsm->sync, filep, pll_table);
-}
-
-static unsigned int msm_poll_pic(struct file *filep,
-	struct poll_table_struct *pll_table)
-{
-	struct msm_cam_device *pmsm = filep->private_data;
-	return __msm_poll_pic(pmsm->sync, filep, pll_table);
-}
-
-static unsigned int __msm_poll_config(struct msm_sync *sync,
-		struct file *filep,
-		struct poll_table_struct *pll_table)
-{
-	int rc = 0;
-	unsigned long flags;
-
-	poll_wait(filep, &sync->event_q.wait, pll_table);
-
-	spin_lock_irqsave(&sync->event_q.lock, flags);
-	if (!list_empty_careful(&sync->event_q.list))
-		/* event ready */
-		rc = POLLIN | POLLRDNORM;
-	spin_unlock_irqrestore(&sync->event_q.lock, flags);
-
-	return rc;
-}
-
-static unsigned int msm_poll_config(struct file *filep,
-	struct poll_table_struct *pll_table)
-{
-	struct msm_cam_device *pmsm = filep->private_data;
-	return __msm_poll_config(pmsm->sync, filep, pll_table);
-}
-
-/*
- * This function executes in interrupt context.
- */
-
-static void *msm_vfe_sync_alloc(int size,
-			void *syncdata __attribute__((unused)),
-			gfp_t gfp)
-{
-	struct msm_queue_cmd *qcmd =
-		kzalloc(sizeof(struct msm_queue_cmd) + size, gfp);
-	if (qcmd) {
-		atomic_set(&qcmd->on_heap, 1);
-		return qcmd + 1;
-	}
-	return NULL;
-}
-
-static void *msm_vpe_sync_alloc(int size,
-			void *syncdata __attribute__((unused)),
-			gfp_t gfp)
-{
-	struct msm_queue_cmd *qcmd =
-		kzalloc(sizeof(struct msm_queue_cmd) + size, gfp);
-	if (qcmd) {
-		atomic_set(&qcmd->on_heap, 1);
-		return qcmd + 1;
-	}
-	return NULL;
-}
-
-static void msm_vfe_sync_free(void *ptr)
-{
-	if (ptr) {
-		struct msm_queue_cmd *qcmd =
-			(struct msm_queue_cmd *)ptr;
-		qcmd--;
-		if (atomic_read(&qcmd->on_heap))
-			kfree(qcmd);
-	}
-}
-
-static void msm_vpe_sync_free(void *ptr)
-{
-	if (ptr) {
-		struct msm_queue_cmd *qcmd =
-			(struct msm_queue_cmd *)ptr;
-		qcmd--;
-		if (atomic_read(&qcmd->on_heap))
-			kfree(qcmd);
-	}
-}
-
-/*
- * This function executes in interrupt context.
- */
-
-static void msm_vfe_sync(struct msm_vfe_resp *vdata,
-		enum msm_queue qtype, void *syncdata,
-		gfp_t gfp)
-{
-	struct msm_queue_cmd *qcmd = NULL;
-	struct msm_sync *sync = (struct msm_sync *)syncdata;
-	unsigned long flags;
-
-	if (!sync) {
-		pr_err("%s: no context in dsp callback.\n", __func__);
-		return;
-	}
-
-	qcmd = ((struct msm_queue_cmd *)vdata) - 1;
-	qcmd->type = qtype;
-	qcmd->command = vdata;
-
-	ktime_get_ts(&(qcmd->ts));
-
-	if (qtype != MSM_CAM_Q_VFE_MSG)
-		goto vfe_for_config;
-
-	CDBG("%s: vdata->type %d\n", __func__, vdata->type);
-
-	switch (vdata->type) {
-	case VFE_MSG_OUTPUT_P:
-		if (sync->pp_mask & PP_PREV) {
-			CDBG("%s: PP_PREV in progress: p0_add %x p1_add %x\n",
-				__func__,
-				vdata->phy.p0_phy,
-				vdata->phy.p1_phy);
-			spin_lock_irqsave(&pp_prev_spinlock, flags);
-			if (sync->pp_prev)
-				CDBG("%s: overwriting pp_prev!\n",
-					__func__);
-			CDBG("%s: sending preview to config\n", __func__);
-			sync->pp_prev = qcmd;
-			spin_unlock_irqrestore(&pp_prev_spinlock, flags);
-			sync->pp_frame_avail = 1;
-			if (atomic_read(&qcmd->on_heap))
-				atomic_add(1, &qcmd->on_heap);
-			break;
-		}
-		CDBG("%s: msm_enqueue frame_q\n", __func__);
-		if (sync->stereocam_enabled)
-			CDBG("%s: Enqueue VFE_MSG_OUTPUT_P to event_q for "
-				"stereo processing\n", __func__);
-		else {
-			if (sync->frame_q.len <= 100 &&
-				sync->event_q.len <= 100) {
-				if (atomic_read(&qcmd->on_heap))
-					atomic_add(1, &qcmd->on_heap);
-				msm_enqueue(&sync->frame_q, &qcmd->list_frame);
-			} else {
-				pr_err("%s, Error Queue limit exceeded "
-					"f_q = %d, e_q = %d\n",	__func__,
-					sync->frame_q.len, sync->event_q.len);
-				free_qcmd(qcmd);
-				return;
-			}
-		}
-		break;
-
-	case VFE_MSG_OUTPUT_T:
-		if (sync->stereocam_enabled) {
-			spin_lock_irqsave(&pp_stereocam_spinlock, flags);
-
-			/* if out1/2 is currently in progress, save the qcmd
-			and issue only ionce the 1st one completes the 3D
-			pipeline */
-			if (STEREO_SNAP_BUFFER1_PROCESSING ==
-				sync->stereo_state) {
-				sync->pp_stereocam2 = qcmd;
-				spin_unlock_irqrestore(&pp_stereocam_spinlock,
-					flags);
-				if (atomic_read(&qcmd->on_heap))
-					atomic_add(1, &qcmd->on_heap);
-				CDBG("%s: snapshot stereo in progress\n",
-					__func__);
-				return;
-			}
-
-			if (sync->pp_stereocam)
-				CDBG("%s: overwriting pp_stereocam!\n",
-					__func__);
-
-			CDBG("%s: sending stereo frame to config\n", __func__);
-			sync->pp_stereocam = qcmd;
-			sync->stereo_state =
-				STEREO_SNAP_BUFFER1_PROCESSING;
-
-			spin_unlock_irqrestore(&pp_stereocam_spinlock, flags);
-
-			/* Increament on_heap by one because the same qcmd will
-			be used for VPE in msm_pp_release. */
-			if (atomic_read(&qcmd->on_heap))
-				atomic_add(1, &qcmd->on_heap);
-			CDBG("%s: Enqueue VFE_MSG_OUTPUT_T to event_q for "
-				"stereo processing.\n", __func__);
-			break;
-		}
-		if (sync->pp_mask & PP_SNAP) {
-			CDBG("%s: pp sending thumbnail to config\n",
-				__func__);
-		} else {
-			msm_enqueue(&sync->pict_q, &qcmd->list_pict);
-			return;
-		}
-
-	case VFE_MSG_OUTPUT_S:
-		if (sync->stereocam_enabled &&
-			sync->stereo_state != STEREO_RAW_SNAP_STARTED) {
-			spin_lock_irqsave(&pp_stereocam_spinlock, flags);
-
-			/* if out1/2 is currently in progress, save the qcmd
-			and issue only once the 1st one completes the 3D
-			pipeline */
-			if (STEREO_SNAP_BUFFER1_PROCESSING ==
-				sync->stereo_state) {
-				sync->pp_stereocam2 = qcmd;
-				spin_unlock_irqrestore(&pp_stereocam_spinlock,
-					flags);
-				if (atomic_read(&qcmd->on_heap))
-					atomic_add(1, &qcmd->on_heap);
-				CDBG("%s: snapshot stereo in progress\n",
-					__func__);
-				return;
-			}
-			if (sync->pp_stereocam)
-				CDBG("%s: overwriting pp_stereocam!\n",
-					__func__);
-
-			CDBG("%s: sending stereo frame to config\n", __func__);
-			sync->pp_stereocam = qcmd;
-			sync->stereo_state =
-				STEREO_SNAP_BUFFER1_PROCESSING;
-
-			spin_unlock_irqrestore(&pp_stereocam_spinlock, flags);
-
-			/* Increament on_heap by one because the same qcmd will
-			be used for VPE in msm_pp_release. */
-			if (atomic_read(&qcmd->on_heap))
-				atomic_add(1, &qcmd->on_heap);
-			CDBG("%s: Enqueue VFE_MSG_OUTPUT_S to event_q for "
-				"stereo processing.\n", __func__);
-			break;
-		}
-		if (sync->pp_mask & PP_SNAP) {
-			CDBG("%s: pp sending main image to config\n",
-				__func__);
-		} else {
-			CDBG("%s: enqueue to picture queue\n", __func__);
-			msm_enqueue(&sync->pict_q, &qcmd->list_pict);
-			return;
-		}
-		break;
-
-	case VFE_MSG_OUTPUT_V:
-		if (sync->stereocam_enabled) {
-			spin_lock_irqsave(&pp_stereocam_spinlock, flags);
-
-			if (sync->pp_stereocam)
-				CDBG("%s: overwriting pp_stereocam!\n",
-					__func__);
-
-			CDBG("%s: sending stereo frame to config\n", __func__);
-			sync->pp_stereocam = qcmd;
-
-			spin_unlock_irqrestore(&pp_stereocam_spinlock, flags);
-
-			/* Increament on_heap by one because the same qcmd will
-			be used for VPE in msm_pp_release. */
-			if (atomic_read(&qcmd->on_heap))
-				atomic_add(1, &qcmd->on_heap);
-			CDBG("%s: Enqueue VFE_MSG_OUTPUT_V to event_q for "
-				"stereo processing.\n", __func__);
-			break;
-		}
-		if (sync->vpefn.vpe_cfg_update) {
-			CDBG("dis_en = %d\n", *sync->vpefn.dis);
-			if (*(sync->vpefn.dis)) {
-				memset(&(vdata->vpe_bf), 0,
-					sizeof(vdata->vpe_bf));
-
-				if (sync->cropinfo != NULL)
-					vdata->vpe_bf.vpe_crop =
-				*(struct video_crop_t *)(sync->cropinfo);
-
-				vdata->vpe_bf.p0_phy = vdata->phy.p0_phy;
-				vdata->vpe_bf.p1_phy = vdata->phy.p1_phy;
-				vdata->vpe_bf.ts = (qcmd->ts);
-				vdata->vpe_bf.frame_id = vdata->phy.frame_id;
-				qcmd->command = vdata;
-				msm_enqueue_vpe(&sync->vpe_q,
-					&qcmd->list_vpe_frame);
-				return;
-			} else if (sync->vpefn.vpe_cfg_update(sync->cropinfo)) {
-				CDBG("%s: msm_enqueue video frame to vpe time "
-					"= %ld\n", __func__, qcmd->ts.tv_nsec);
-
-				sync->vpefn.send_frame_to_vpe(
-					vdata->phy.p0_phy,
-					vdata->phy.p1_phy,
-					&(qcmd->ts), OUTPUT_TYPE_V);
-
-				free_qcmd(qcmd);
-				return;
-			} else {
-				CDBG("%s: msm_enqueue video frame_q\n",
-					__func__);
-				if (sync->liveshot_enabled) {
-					CDBG("%s: msm_enqueue liveshot\n",
-						__func__);
-					vdata->phy.output_id |= OUTPUT_TYPE_L;
-					sync->liveshot_enabled = false;
-				}
-				if (sync->frame_q.len <= 100 &&
-					sync->event_q.len <= 100) {
-						msm_enqueue(&sync->frame_q,
-							&qcmd->list_frame);
-				} else {
-					pr_err("%s, Error Queue limit exceeded\
-						f_q = %d, e_q = %d\n",
-						__func__, sync->frame_q.len,
-						sync->event_q.len);
-					free_qcmd(qcmd);
-				}
-
-				return;
-			}
-		} else {
-			CDBG("%s: msm_enqueue video frame_q\n",	__func__);
-			if (sync->frame_q.len <= 100 &&
-				sync->event_q.len <= 100) {
-				msm_enqueue(&sync->frame_q, &qcmd->list_frame);
-			} else {
-				pr_err("%s, Error Queue limit exceeded\
-					f_q = %d, e_q = %d\n",
-					__func__, sync->frame_q.len,
-					sync->event_q.len);
-				free_qcmd(qcmd);
-			}
-
-			return;
-		}
-
-	case VFE_MSG_SNAPSHOT:
-		if (sync->pp_mask & (PP_SNAP | PP_RAW_SNAP)) {
-			CDBG("%s: PP_SNAP in progress: pp_mask %x\n",
-				__func__, sync->pp_mask);
-		} else {
-			if (atomic_read(&qcmd->on_heap))
-				atomic_add(1, &qcmd->on_heap);
-			CDBG("%s: VFE_MSG_SNAPSHOT store\n",
-				__func__);
-			if (sync->stereocam_enabled &&
-				sync->stereo_state != STEREO_RAW_SNAP_STARTED) {
-				sync->pp_stereosnap = qcmd;
-				return;
-			}
-		}
-		break;
-
-	case VFE_MSG_COMMON:
-		CDBG("%s: qtype %d, comp stats, enqueue event_q.\n",
-			__func__, vdata->type);
-		break;
-
-	case VFE_MSG_GENERAL:
-		CDBG("%s: qtype %d, general msg, enqueue event_q.\n",
-			__func__, vdata->type);
-		break;
-
-	default:
-		CDBG("%s: qtype %d not handled\n", __func__, vdata->type);
-		/* fall through, send to config. */
-	}
-
-vfe_for_config:
-	CDBG("%s: msm_enqueue event_q\n", __func__);
-	if (sync->frame_q.len <= 100 && sync->event_q.len <= 100) {
-		msm_enqueue(&sync->event_q, &qcmd->list_config);
-	} else if (sync->event_q.len > 100) {
-		pr_err("%s, Error Event Queue limit exceeded f_q = %d, e_q = %d\n",
-			__func__, sync->frame_q.len, sync->event_q.len);
-		qcmd->error_code = 0xffffffff;
-		qcmd->command = NULL;
-		msm_enqueue(&sync->frame_q, &qcmd->list_frame);
-	} else {
-		pr_err("%s, Error Queue limit exceeded f_q = %d, e_q = %d\n",
-			__func__, sync->frame_q.len, sync->event_q.len);
-		free_qcmd(qcmd);
-	}
-
-}
-
-static void msm_vpe_sync(struct msm_vpe_resp *vdata,
-	enum msm_queue qtype, void *syncdata, void *ts, gfp_t gfp)
-{
-	struct msm_queue_cmd *qcmd = NULL;
-	unsigned long flags;
-
-	struct msm_sync *sync = (struct msm_sync *)syncdata;
-	if (!sync) {
-		pr_err("%s: no context in dsp callback.\n", __func__);
-		return;
-	}
-
-	qcmd = ((struct msm_queue_cmd *)vdata) - 1;
-	qcmd->type = qtype;
-	qcmd->command = vdata;
-	qcmd->ts = *((struct timespec *)ts);
-
-	if (qtype != MSM_CAM_Q_VPE_MSG) {
-		pr_err("%s: Invalid qcmd type = %d.\n", __func__, qcmd->type);
-		free_qcmd(qcmd);
-		return;
-	}
-
-	CDBG("%s: vdata->type %d\n", __func__, vdata->type);
-	switch (vdata->type) {
-	case VPE_MSG_OUTPUT_V:
-		if (sync->liveshot_enabled) {
-			CDBG("%s: msm_enqueue liveshot %d\n", __func__,
-				sync->liveshot_enabled);
-			vdata->phy.output_id |= OUTPUT_TYPE_L;
-			sync->liveshot_enabled = false;
-		}
-		vdata->phy.p2_phy = vdata->phy.p0_phy;
-		if (sync->frame_q.len <= 100 && sync->event_q.len <= 100) {
-			CDBG("%s: enqueue to frame_q from VPE\n", __func__);
-			msm_enqueue(&sync->frame_q, &qcmd->list_frame);
-		} else {
-			pr_err("%s, Error Queue limit exceeded f_q = %d, "
-				"e_q = %d\n", __func__, sync->frame_q.len,
-				sync->event_q.len);
-			free_qcmd(qcmd);
-		}
-		return;
-
-	case VPE_MSG_OUTPUT_ST_L:
-		CDBG("%s: enqueue left frame done msg to event_q from VPE\n",
-			__func__);
-		msm_enqueue(&sync->event_q, &qcmd->list_config);
-		return;
-
-	case VPE_MSG_OUTPUT_ST_R:
-		spin_lock_irqsave(&pp_stereocam_spinlock, flags);
-		CDBG("%s: received VPE_MSG_OUTPUT_ST_R state %d\n", __func__,
-			sync->stereo_state);
-
-		if (STEREO_SNAP_BUFFER1_PROCESSING == sync->stereo_state) {
-			msm_enqueue(&sync->pict_q, &qcmd->list_pict);
-			qcmd = sync->pp_stereocam2;
-			sync->pp_stereocam = sync->pp_stereocam2;
-			sync->pp_stereocam2 = NULL;
-			msm_enqueue(&sync->event_q, &qcmd->list_config);
-			sync->stereo_state =
-				STEREO_SNAP_BUFFER2_PROCESSING;
-		} else if (STEREO_SNAP_BUFFER2_PROCESSING ==
-				sync->stereo_state) {
-			sync->stereo_state = STEREO_SNAP_IDLE;
-			/* Send snapshot DONE */
-			msm_enqueue(&sync->pict_q, &qcmd->list_pict);
-			qcmd = sync->pp_stereosnap;
-			sync->pp_stereosnap = NULL;
-			CDBG("%s: send SNAPSHOT_DONE message\n", __func__);
-			msm_enqueue(&sync->event_q, &qcmd->list_config);
-		} else {
-			if (atomic_read(&qcmd->on_heap))
-				atomic_add(1, &qcmd->on_heap);
-			msm_enqueue(&sync->event_q, &qcmd->list_config);
-			if (sync->stereo_state == STEREO_VIDEO_ACTIVE) {
-				CDBG("%s: st frame to frame_q from VPE\n",
-					__func__);
-				msm_enqueue(&sync->frame_q, &qcmd->list_frame);
-			}
-		}
-		spin_unlock_irqrestore(&pp_stereocam_spinlock, flags);
-		return;
-
-	default:
-		pr_err("%s: qtype %d not handled\n", __func__, vdata->type);
-	}
-	pr_err("%s: Should not come here. Error.\n", __func__);
-}
-
-static struct msm_vpe_callback msm_vpe_s = {
-	.vpe_resp = msm_vpe_sync,
-	.vpe_alloc = msm_vpe_sync_alloc,
-	.vpe_free = msm_vpe_sync_free,
-};
-
-static struct msm_vfe_callback msm_vfe_s = {
-	.vfe_resp = msm_vfe_sync,
-	.vfe_alloc = msm_vfe_sync_alloc,
-	.vfe_free = msm_vfe_sync_free,
-};
-
-static int __msm_open(struct msm_cam_device *pmsm, const char *const apps_id,
-			int is_controlnode)
-{
-	int rc = 0;
-	struct msm_sync *sync = pmsm->sync;
-
-	mutex_lock(&sync->lock);
-	if (sync->apps_id && strcmp(sync->apps_id, apps_id)
-				&& (!strcmp(MSM_APPS_ID_V4L2, apps_id))) {
-		pr_err("%s(%s): sensor %s is already opened for %s\n",
-			__func__,
-			apps_id,
-			sync->sdata->sensor_name,
-			sync->apps_id);
-		rc = -EBUSY;
-		goto msm_open_done;
-	}
-
-	sync->apps_id = apps_id;
-
-	if (!sync->core_powered_on && !is_controlnode) {
-		pm_qos_update_request(&sync->idle_pm_qos,
-			msm_cpuidle_get_deep_idle_latency());
-
-		msm_camvfe_fn_init(&sync->vfefn, sync);
-		if (sync->vfefn.vfe_init) {
-			sync->pp_frame_avail = 0;
-			sync->get_pic_abort = 0;
-			rc = msm_camio_sensor_clk_on(sync->pdev);
-			if (rc < 0) {
-				pr_err("%s: setting sensor clocks failed: %d\n",
-					__func__, rc);
-				goto msm_open_err;
-			}
-			rc = sync->sctrl.s_init(sync->sdata);
-			if (rc < 0) {
-				pr_err("%s: sensor init failed: %d\n",
-					__func__, rc);
-				msm_camio_sensor_clk_off(sync->pdev);
-				goto msm_open_err;
-			}
-			rc = sync->vfefn.vfe_init(&msm_vfe_s,
-				sync->pdev);
-			if (rc < 0) {
-				pr_err("%s: vfe_init failed at %d\n",
-					__func__, rc);
-				sync->sctrl.s_release();
-				msm_camio_sensor_clk_off(sync->pdev);
-				goto msm_open_err;
-			}
-		} else {
-			pr_err("%s: no sensor init func\n", __func__);
-			rc = -ENODEV;
-			goto msm_open_err;
-		}
-		msm_camvpe_fn_init(&sync->vpefn, sync);
-
-		spin_lock_init(&sync->abort_pict_lock);
-		spin_lock_init(&pp_prev_spinlock);
-		spin_lock_init(&pp_stereocam_spinlock);
-		spin_lock_init(&st_frame_spinlock);
-		if (rc >= 0) {
-			msm_region_init(sync);
-			if (sync->vpefn.vpe_reg)
-				sync->vpefn.vpe_reg(&msm_vpe_s);
-			sync->unblock_poll_frame = 0;
-			sync->unblock_poll_pic_frame = 0;
-		}
-		sync->core_powered_on = 1;
-	}
-	sync->opencnt++;
-	client_for_ion = msm_ion_client_create(-1, "camera");
-
-msm_open_done:
-	mutex_unlock(&sync->lock);
-	return rc;
-
-msm_open_err:
-	atomic_set(&pmsm->opened, 0);
-	mutex_unlock(&sync->lock);
-	return rc;
-}
-
-static int msm_open_common(struct inode *inode, struct file *filep,
-			int once, int is_controlnode)
-{
-	int rc;
-	struct msm_cam_device *pmsm =
-		container_of(inode->i_cdev, struct msm_cam_device, cdev);
-
-	CDBG("%s: open %s\n", __func__, filep->f_path.dentry->d_name.name);
-
-	if (atomic_cmpxchg(&pmsm->opened, 0, 1) && once) {
-		pr_err("%s: %s is already opened.\n",
-			__func__,
-			filep->f_path.dentry->d_name.name);
-		return -EBUSY;
-	}
-
-	rc = nonseekable_open(inode, filep);
-	if (rc < 0) {
-		pr_err("%s: nonseekable_open error %d\n", __func__, rc);
-		return rc;
-	}
-
-	rc = __msm_open(pmsm, MSM_APPS_ID_PROP, is_controlnode);
-	if (rc < 0)
-		return rc;
-	filep->private_data = pmsm;
-	CDBG("%s: rc %d\n", __func__, rc);
-	return rc;
-}
-
-static int msm_open_frame(struct inode *inode, struct file *filep)
-{
-	struct msm_cam_device *pmsm =
-		container_of(inode->i_cdev, struct msm_cam_device, cdev);
-	msm_queue_drain(&pmsm->sync->frame_q, list_frame);
-	return msm_open_common(inode, filep, 1, 0);
-}
-
-static int msm_open(struct inode *inode, struct file *filep)
-{
-	return msm_open_common(inode, filep, 1, 0);
-}
-
-static int msm_open_control(struct inode *inode, struct file *filep)
-{
-	int rc;
-
-	struct msm_control_device *ctrl_pmsm =
-		kmalloc(sizeof(struct msm_control_device), GFP_KERNEL);
-	if (!ctrl_pmsm)
-		return -ENOMEM;
-
-	rc = msm_open_common(inode, filep, 0, 1);
-	if (rc < 0) {
-		kfree(ctrl_pmsm);
-		return rc;
-	}
-	ctrl_pmsm->pmsm = filep->private_data;
-	filep->private_data = ctrl_pmsm;
-
-	msm_queue_init(&ctrl_pmsm->ctrl_q, "control");
-
-	if (!g_v4l2_opencnt)
-		g_v4l2_control_device = ctrl_pmsm;
-	g_v4l2_opencnt++;
-	CDBG("%s: rc %d\n", __func__, rc);
-	return rc;
-}
-
-static const struct file_operations msm_fops_config = {
-	.owner = THIS_MODULE,
-	.open = msm_open,
-	.unlocked_ioctl = msm_ioctl_config,
-	.release = msm_release_config,
-	.poll = msm_poll_config,
-};
-
-static const struct file_operations msm_fops_control = {
-	.owner = THIS_MODULE,
-	.open = msm_open_control,
-	.unlocked_ioctl = msm_ioctl_control,
-	.release = msm_release_control,
-};
-
-static const struct file_operations msm_fops_frame = {
-	.owner = THIS_MODULE,
-	.open = msm_open_frame,
-	.unlocked_ioctl = msm_ioctl_frame,
-	.release = msm_release_frame,
-	.poll = msm_poll_frame,
-};
-
-static const struct file_operations msm_fops_pic = {
-	.owner = THIS_MODULE,
-	.open = msm_open,
-	.unlocked_ioctl = msm_ioctl_pic,
-	.release = msm_release_pic,
-	.poll = msm_poll_pic,
-};
-
-static int msm_setup_cdev(struct msm_cam_device *msm,
-			int node,
-			dev_t devno,
-			const char *suffix,
-			const struct file_operations *fops)
-{
-	int rc = -ENODEV;
-
-	struct device *device =
-		device_create(msm_class, NULL,
-			devno, NULL,
-			"%s%d", suffix, node);
-
-	if (IS_ERR(device)) {
-		rc = PTR_ERR(device);
-		pr_err("%s: error creating device: %d\n", __func__, rc);
-		return rc;
-	}
-
-	cdev_init(&msm->cdev, fops);
-	msm->cdev.owner = THIS_MODULE;
-
-	rc = cdev_add(&msm->cdev, devno, 1);
-	if (rc < 0) {
-		pr_err("%s: error adding cdev: %d\n", __func__, rc);
-		device_destroy(msm_class, devno);
-		return rc;
-	}
-
-	return rc;
-}
-
-static int msm_tear_down_cdev(struct msm_cam_device *msm, dev_t devno)
-{
-	cdev_del(&msm->cdev);
-	device_destroy(msm_class, devno);
-	return 0;
-}
-
-static int msm_sync_init(struct msm_sync *sync,
-		struct platform_device *pdev,
-		int (*sensor_probe)(const struct msm_camera_sensor_info *,
-				struct msm_sensor_ctrl *))
-{
-	int rc = 0;
-	struct msm_sensor_ctrl sctrl;
-	sync->sdata = pdev->dev.platform_data;
-
-	msm_queue_init(&sync->event_q, "event");
-	msm_queue_init(&sync->frame_q, "frame");
-	msm_queue_init(&sync->pict_q, "pict");
-	msm_queue_init(&sync->vpe_q, "vpe");
-
-	pm_qos_add_request(&sync->idle_pm_qos, PM_QOS_CPU_DMA_LATENCY,
-					   PM_QOS_DEFAULT_VALUE);
-
-	rc = msm_camio_probe_on(pdev);
-	if (rc < 0) {
-		pm_qos_remove_request(&sync->idle_pm_qos);
-		return rc;
-	}
-	rc = sensor_probe(sync->sdata, &sctrl);
-	if (rc >= 0) {
-		sync->pdev = pdev;
-		sync->sctrl = sctrl;
-	}
-	msm_camio_probe_off(pdev);
-	if (rc < 0) {
-		pr_err("%s: failed to initialize %s\n",
-			__func__,
-			sync->sdata->sensor_name);
-		pm_qos_remove_request(&sync->idle_pm_qos);
-		return rc;
-	}
-
-	sync->opencnt = 0;
-	sync->core_powered_on = 0;
-	sync->ignore_qcmd = false;
-	sync->ignore_qcmd_type = -1;
-	mutex_init(&sync->lock);
-	if (sync->sdata->strobe_flash_data) {
-		sync->sdata->strobe_flash_data->state = 0;
-		spin_lock_init(&sync->sdata->strobe_flash_data->spin_lock);
-	}
-	CDBG("%s: initialized %s\n", __func__, sync->sdata->sensor_name);
-	return rc;
-}
-
-static int msm_sync_destroy(struct msm_sync *sync)
-{
-	pm_qos_remove_request(&sync->idle_pm_qos);
-	return 0;
-}
-
-static int msm_device_init(struct msm_cam_device *pmsm,
-		struct msm_sync *sync,
-		int node)
-{
-	int dev_num = 4 * node;
-	int rc = msm_setup_cdev(pmsm, node,
-		MKDEV(MAJOR(msm_devno), dev_num),
-		"control", &msm_fops_control);
-	if (rc < 0) {
-		pr_err("%s: error creating control node: %d\n", __func__, rc);
-		return rc;
-	}
-
-	rc = msm_setup_cdev(pmsm + 1, node,
-		MKDEV(MAJOR(msm_devno), dev_num + 1),
-		"config", &msm_fops_config);
-	if (rc < 0) {
-		pr_err("%s: error creating config node: %d\n", __func__, rc);
-		msm_tear_down_cdev(pmsm, MKDEV(MAJOR(msm_devno),
-				dev_num));
-		return rc;
-	}
-
-	rc = msm_setup_cdev(pmsm + 2, node,
-		MKDEV(MAJOR(msm_devno), dev_num + 2),
-		"frame", &msm_fops_frame);
-	if (rc < 0) {
-		pr_err("%s: error creating frame node: %d\n", __func__, rc);
-		msm_tear_down_cdev(pmsm,
-			MKDEV(MAJOR(msm_devno), dev_num));
-		msm_tear_down_cdev(pmsm + 1,
-			MKDEV(MAJOR(msm_devno), dev_num + 1));
-		return rc;
-	}
-
-	rc = msm_setup_cdev(pmsm + 3, node,
-		MKDEV(MAJOR(msm_devno), dev_num + 3),
-		"pic", &msm_fops_pic);
-	if (rc < 0) {
-		pr_err("%s: error creating pic node: %d\n", __func__, rc);
-		msm_tear_down_cdev(pmsm,
-			MKDEV(MAJOR(msm_devno), dev_num));
-		msm_tear_down_cdev(pmsm + 1,
-			MKDEV(MAJOR(msm_devno), dev_num + 1));
-		msm_tear_down_cdev(pmsm + 2,
-			MKDEV(MAJOR(msm_devno), dev_num + 2));
-		return rc;
-	}
-
-
-	atomic_set(&pmsm[0].opened, 0);
-	atomic_set(&pmsm[1].opened, 0);
-	atomic_set(&pmsm[2].opened, 0);
-	atomic_set(&pmsm[3].opened, 0);
-
-	pmsm[0].sync = sync;
-	pmsm[1].sync = sync;
-	pmsm[2].sync = sync;
-	pmsm[3].sync = sync;
-
-	return rc;
-}
-
-int msm_camera_drv_start(struct platform_device *dev,
-		int (*sensor_probe)(const struct msm_camera_sensor_info *,
-			struct msm_sensor_ctrl *))
-{
-	struct msm_cam_device *pmsm = NULL;
-	struct msm_sync *sync;
-	int rc = -ENODEV;
-
-	if (camera_node >= MSM_MAX_CAMERA_SENSORS) {
-		pr_err("%s: too many camera sensors\n", __func__);
-		return rc;
-	}
-
-	if (!msm_class) {
-		/* There are three device nodes per sensor */
-		rc = alloc_chrdev_region(&msm_devno, 0,
-				4 * MSM_MAX_CAMERA_SENSORS,
-				"msm_camera");
-		if (rc < 0) {
-			pr_err("%s: failed to allocate chrdev: %d\n", __func__,
-				rc);
-			return rc;
-		}
-
-		msm_class = class_create(THIS_MODULE, "msm_camera");
-		if (IS_ERR(msm_class)) {
-			rc = PTR_ERR(msm_class);
-			pr_err("%s: create device class failed: %d\n",
-				__func__, rc);
-			return rc;
-		}
-	}
-
-	pmsm = kzalloc(sizeof(struct msm_cam_device) * 4 +
-			sizeof(struct msm_sync), GFP_ATOMIC);
-	if (!pmsm)
-		return -ENOMEM;
-	sync = (struct msm_sync *)(pmsm + 4);
-
-	rc = msm_sync_init(sync, dev, sensor_probe);
-	if (rc < 0) {
-		kfree(pmsm);
-		return rc;
-	}
-
-	CDBG("%s: setting camera node %d\n", __func__, camera_node);
-	rc = msm_device_init(pmsm, sync, camera_node);
-	if (rc < 0) {
-		msm_sync_destroy(sync);
-		kfree(pmsm);
-		return rc;
-	}
-
-	camera_type[camera_node] = sync->sctrl.s_camera_type;
-	sensor_mount_angle[camera_node] = sync->sctrl.s_mount_angle;
-	camera_node++;
-
-	list_add(&sync->list, &msm_sensors);
-	return rc;
-}
-EXPORT_SYMBOL(msm_camera_drv_start);
diff --git a/drivers/media/video/msm/msm_camirq_router.c b/drivers/media/video/msm/msm_camirq_router.c
deleted file mode 100644
index 25a561f..0000000
--- a/drivers/media/video/msm/msm_camirq_router.c
+++ /dev/null
@@ -1,282 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/interrupt.h>
-#include <linux/of.h>
-#include <mach/irqs.h>
-#include <media/msm_isp.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-#include "msm.h"
-#include "server/msm_cam_server.h"
-#include "msm_camirq_router.h"
-
-#ifdef CONFIG_MSM_CAMERA_DEBUG
-#define D(fmt, args...) pr_debug("msm: " fmt, ##args)
-#else
-#define D(fmt, args...) do {} while (0)
-#endif
-
-static void msm_irqrouter_update_irqmap_entry(
-	struct msm_cam_server_irqmap_entry *entry,
-	int is_composite, int irq_idx, int cam_hw_idx)
-{
-	int rc = 0;
-	entry->irq_idx = irq_idx;
-	entry->is_composite = is_composite;
-	entry->cam_hw_idx = cam_hw_idx;
-	rc = msm_cam_server_update_irqmap(entry);
-	if (rc < 0)
-		pr_err("%s Error updating irq %d information ",
-			__func__, irq_idx);
-}
-
-static void msm_irqrouter_send_default_irqmap(
-	struct irqrouter_ctrl_type *irqrouter_ctrl)
-{
-	struct msm_cam_server_irqmap_entry *irqmap =
-		&irqrouter_ctrl->def_hw_irqmap[0];
-
-	msm_irqrouter_update_irqmap_entry(&irqmap[CAMERA_SS_IRQ_0],
-		0, CAMERA_SS_IRQ_0, MSM_CAM_HW_MICRO);
-
-	msm_irqrouter_update_irqmap_entry(&irqmap[CAMERA_SS_IRQ_1],
-		0, CAMERA_SS_IRQ_1, MSM_CAM_HW_CCI);
-
-	msm_irqrouter_update_irqmap_entry(&irqmap[CAMERA_SS_IRQ_2],
-		0, CAMERA_SS_IRQ_2, MSM_CAM_HW_CSI0);
-
-	msm_irqrouter_update_irqmap_entry(&irqmap[CAMERA_SS_IRQ_3],
-		0, CAMERA_SS_IRQ_3, MSM_CAM_HW_CSI1);
-
-	msm_irqrouter_update_irqmap_entry(&irqmap[CAMERA_SS_IRQ_4],
-		0, CAMERA_SS_IRQ_4, MSM_CAM_HW_CSI2);
-
-	msm_irqrouter_update_irqmap_entry(&irqmap[CAMERA_SS_IRQ_5],
-		0, CAMERA_SS_IRQ_5, MSM_CAM_HW_CSI3);
-
-	msm_irqrouter_update_irqmap_entry(&irqmap[CAMERA_SS_IRQ_6],
-		0, CAMERA_SS_IRQ_6, MSM_CAM_HW_ISPIF);
-
-	msm_irqrouter_update_irqmap_entry(&irqmap[CAMERA_SS_IRQ_7],
-		0, CAMERA_SS_IRQ_7, MSM_CAM_HW_CPP);
-
-	msm_irqrouter_update_irqmap_entry(&irqmap[CAMERA_SS_IRQ_8],
-		0, CAMERA_SS_IRQ_8, MSM_CAM_HW_VFE0);
-
-	msm_irqrouter_update_irqmap_entry(&irqmap[CAMERA_SS_IRQ_9],
-		0, CAMERA_SS_IRQ_9, MSM_CAM_HW_VFE1);
-
-	msm_irqrouter_update_irqmap_entry(&irqmap[CAMERA_SS_IRQ_10],
-		0, CAMERA_SS_IRQ_10, MSM_CAM_HW_JPEG0);
-
-	msm_irqrouter_update_irqmap_entry(&irqmap[CAMERA_SS_IRQ_11],
-		0, CAMERA_SS_IRQ_11, MSM_CAM_HW_JPEG1);
-
-	msm_irqrouter_update_irqmap_entry(&irqmap[CAMERA_SS_IRQ_12],
-		0, CAMERA_SS_IRQ_12, MSM_CAM_HW_JPEG2);
-}
-
-static int msm_irqrouter_open(struct v4l2_subdev *sd,
-	struct v4l2_subdev_fh *fh)
-{
-	struct irqrouter_ctrl_type *irqrouter_ctrl = v4l2_get_subdevdata(sd);
-	/* Only one object of IRQ Router allowed. */
-	if (atomic_read(&irqrouter_ctrl->active) != 0) {
-		pr_err("%s IRQ router is already opened\n", __func__);
-		return -EINVAL;
-	}
-
-	D("%s E ", __func__);
-	atomic_inc(&irqrouter_ctrl->active);
-
-	return 0;
-}
-
-static int msm_irqrouter_close(struct v4l2_subdev *sd,
-	struct v4l2_subdev_fh *fh)
-{
-	struct irqrouter_ctrl_type *irqrouter_ctrl = v4l2_get_subdevdata(sd);
-	if (atomic_read(&irqrouter_ctrl->active) == 0) {
-		pr_err("%s IRQ router is already closed\n", __func__);
-		return -EINVAL;
-	}
-	D("%s E ", __func__);
-	atomic_dec(&irqrouter_ctrl->active);
-	return 0;
-}
-
-static const struct v4l2_subdev_internal_ops msm_irqrouter_internal_ops = {
-	.open = msm_irqrouter_open,
-	.close = msm_irqrouter_close,
-};
-
-long msm_irqrouter_subdev_ioctl(struct v4l2_subdev *sd,
-	unsigned int cmd, void *arg)
-{
-	struct irqrouter_ctrl_type *irqrouter_ctrl = v4l2_get_subdevdata(sd);
-	struct msm_camera_irq_cfg *irq_cfg;
-	struct intr_table_entry irq_req;
-	int rc = 0;
-
-	/* Handle all IRQ Router Subdev IOCTLs here.
-	 * Userspace sends the composite irq configuration.
-	 * IRQ Router subdev then configures the registers to group
-	 * together individual core hw irqs into a composite IRQ
-	 * to the MSM IRQ controller. It also registers them with
-	 * the irq manager in the camera server. */
-	switch (cmd) {
-	case MSM_IRQROUTER_CFG_COMPIRQ:
-		COPY_FROM_USER(rc, &irq_cfg, (void __user *)arg,
-			sizeof(struct msm_camera_irq_cfg));
-		if (rc) {
-			ERR_COPY_FROM_USER();
-			break;
-		}
-
-		if (!irq_cfg ||
-			(irq_cfg->irq_idx < CAMERA_SS_IRQ_0) ||
-			(irq_cfg->irq_idx >= CAMERA_SS_IRQ_MAX)) {
-			pr_err("%s Invalid input", __func__);
-			return -EINVAL;
-		} else {
-			irq_req.cam_hw_mask      = irq_cfg->cam_hw_mask;
-			irq_req.irq_idx          = irq_cfg->irq_idx;
-			irq_req.irq_num          =
-			irqrouter_ctrl->def_hw_irqmap[irq_cfg->irq_idx].irq_num;
-			irq_req.is_composite     = 1;
-			irq_req.irq_trigger_type = IRQF_TRIGGER_RISING;
-			irq_req.num_hwcore       = irq_cfg->num_hwcore;
-			irq_req.data             = NULL;
-			rc = msm_cam_server_request_irq(&irq_req);
-			if (rc < 0) {
-				pr_err("%s Error requesting comp irq %d ",
-					__func__, irq_req.irq_idx);
-				return rc;
-			}
-			irqrouter_ctrl->def_hw_irqmap
-				[irq_cfg->irq_idx].is_composite = 1;
-		}
-		break;
-	default:
-		pr_err("%s Invalid cmd %d ", __func__, cmd);
-		break;
-	}
-
-	return rc;
-}
-
-static const struct v4l2_subdev_core_ops msm_irqrouter_subdev_core_ops = {
-	.ioctl = msm_irqrouter_subdev_ioctl,
-};
-
-static const struct v4l2_subdev_ops msm_irqrouter_subdev_ops = {
-	.core = &msm_irqrouter_subdev_core_ops,
-};
-
-static int __devinit irqrouter_probe(struct platform_device *pdev)
-{
-	int rc = 0;
-	struct irqrouter_ctrl_type *irqrouter_ctrl;
-	struct msm_cam_subdev_info sd_info;
-
-	D("%s: device id = %d\n", __func__, pdev->id);
-
-	irqrouter_ctrl = kzalloc(sizeof(struct irqrouter_ctrl_type),
-				GFP_KERNEL);
-	if (!irqrouter_ctrl) {
-		pr_err("%s: not enough memory\n", __func__);
-		return -ENOMEM;
-	}
-
-	v4l2_subdev_init(&irqrouter_ctrl->subdev, &msm_irqrouter_subdev_ops);
-	irqrouter_ctrl->subdev.internal_ops = &msm_irqrouter_internal_ops;
-	irqrouter_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-	snprintf(irqrouter_ctrl->subdev.name,
-			 sizeof(irqrouter_ctrl->subdev.name), "msm_irqrouter");
-	v4l2_set_subdevdata(&irqrouter_ctrl->subdev, irqrouter_ctrl);
-	irqrouter_ctrl->pdev = pdev;
-
-	if (pdev->dev.of_node)
-		of_property_read_u32((&pdev->dev)->of_node,
-			"cell-index", &pdev->id);
-
-	msm_irqrouter_send_default_irqmap(irqrouter_ctrl);
-
-	media_entity_init(&irqrouter_ctrl->subdev.entity, 0, NULL, 0);
-	irqrouter_ctrl->subdev.entity.type = MEDIA_ENT_T_DEVNODE_V4L;
-	irqrouter_ctrl->subdev.entity.group_id = IRQ_ROUTER_DEV;
-	irqrouter_ctrl->subdev.entity.name = pdev->name;
-
-	sd_info.sdev_type = IRQ_ROUTER_DEV;
-	sd_info.sd_index = 0;
-	sd_info.irq_num = 0;
-	/* Now register this subdev with the camera server. */
-	rc = msm_cam_register_subdev_node(&irqrouter_ctrl->subdev, &sd_info);
-	if (rc < 0) {
-		pr_err("%s Error registering irqr subdev %d", __func__, rc);
-		goto error;
-	}
-	irqrouter_ctrl->subdev.entity.revision =
-		irqrouter_ctrl->subdev.devnode->num;
-	atomic_set(&irqrouter_ctrl->active, 0);
-
-	platform_set_drvdata(pdev, &irqrouter_ctrl->subdev);
-
-	return rc;
-error:
-	kfree(irqrouter_ctrl);
-	return rc;
-}
-
-static int __exit irqrouter_exit(struct platform_device *pdev)
-{
-	struct v4l2_subdev *subdev = dev_get_drvdata(&pdev->dev);
-	struct irqrouter_ctrl_type *irqrouter_ctrl =
-		v4l2_get_subdevdata(subdev);
-	kfree(irqrouter_ctrl);
-	return 0;
-}
-
-static const struct of_device_id msm_irqrouter_dt_match[] = {
-	{.compatible = "qcom,irqrouter"},
-	{}
-};
-
-MODULE_DEVICE_TABLE(of, msm_irqrouter_dt_match);
-
-static struct platform_driver msm_irqrouter_driver = {
-	.probe = irqrouter_probe,
-	.remove = irqrouter_exit,
-	.driver = {
-		.name = MSM_IRQ_ROUTER_DRV_NAME,
-		.owner = THIS_MODULE,
-		.of_match_table = msm_irqrouter_dt_match,
-	},
-};
-
-static int __init msm_irqrouter_init_module(void)
-{
-	return platform_driver_register(&msm_irqrouter_driver);
-}
-
-static void __exit msm_irqrouter_exit_module(void)
-{
-	platform_driver_unregister(&msm_irqrouter_driver);
-}
-
-module_init(msm_irqrouter_init_module);
-module_exit(msm_irqrouter_exit_module);
-MODULE_DESCRIPTION("msm camera irq router");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/msm_camirq_router.h b/drivers/media/video/msm/msm_camirq_router.h
deleted file mode 100644
index 2c9cb73..0000000
--- a/drivers/media/video/msm/msm_camirq_router.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 __MSM_CAM_IRQROUTER_H__
-#define __MSM_CAM_IRQROUTER_H__
-
-#include <linux/bitops.h>
-
-/* Camera SS common registers defines - Start */
-/* These registers are not directly related to
- * IRQ Router, but are common to the Camera SS.
- * IRQ Router registers dont have a unique base address
- * in the memory mapped address space. It is offset from
- * the Camera SS base address. So keep the common Camera
- * SS registers also in the IRQ Router subdev for now. */
-
-/* READ ONLY: Camera Subsystem HW version */
-#define CAMSS_HW_VERSION			0x00000000
-
-/* Bits 4:0 of this register can be used to select a desired
- * camera core test bus to drive the Camera_SS test bus output */
-#define CAMSS_TESTBUS_SEL			0x00000004
-
-/* Bits 4:0 of this register is used to allow either Microcontroller
- * or the CCI drive the corresponding GPIO output.
- * For eg: Setting bit 0 of this register allows Microcontroller to
- * drive GPIO #0. Clearing the bit allows CCI to drive GPIO #0. */
-#define CAMSS_GPIO_MUX_SEL			0x00000008
-
-/* Bit 0 of this register is used to set the default AHB master
- * for the AHB Arbiter. 0 - AHB Master 0, 1 - AHB Master 1*/
-#define CAMSS_AHB_ARB_CTL			0x0000000C
-
-/* READ ONLY */
-#define CAMSS_XPU2_STATUS			0x00000010
-
-/* Select the appropriate CSI clock for CSID Pixel pipes */
-#define CAMSS_CSI_PIX_CLK_MUX_SEL		0x00000020
-#define CAMSS_CSI_PIX_CLK_CGC_EN		0x00000024
-
-/* Select the appropriate CSI clock for CSID RDI pipes */
-#define CAMSS_CSI_RDI_CLK_MUX_SEL		0x00000028
-#define CAMSS_CSI_RDI_CLK_CGC_EN		0x0000002C
-
-/* Select the appropriate CSI clock for CSI Phy0 */
-#define CAMSS_CSI_PHY_0_CLK_MUX_SEL		0x00000030
-#define CAMSS_CSI_PHY_0_CLK_CGC_EN		0x00000034
-
-/* Select the appropriate CSI clock for CSI Phy1 */
-#define CAMSS_CSI_PHY_1_CLK_MUX_SEL		0x00000038
-#define CAMSS_CSI_PHY_1_CLK_CGC_EN		0x0000003C
-
-/* Select the appropriate CSI clock for CSI Phy2 */
-#define CAMSS_CSI_PHY_2_CLK_MUX_SEL		0x00000040
-#define CAMSS_CSI_PHY_2_CLK_CGC_EN		0x00000044
-/* Camera SS common registers defines - End */
-
-/* IRQ Router registers defines - Start */
-/* This register is used to reset the composite
- * IRQ outputs of the Camera_SS IRQ Router */
-#define CAMSS_IRQ_COMPOSITE_RESET_CTRL		0x00000060
-
-/* By default, this 'allows' the interrupts from
- * Micro to pass through, unless configured in
- * composite mode. */
-#define CAMSS_IRQ_COMPOSITE_MASK_0		0x00000064
-
-/* By default, this 'allows' the interrupts from
- * CCI to pass through, unless configured in
- * composite mode. */
-#define CAMSS_IRQ_COMPOSITE_MASK_1		0x00000068
-
-/* By default, this 'allows' the interrupts from
- * CSI_0 to pass through, unless configured in
- * composite mode. */
-#define CAMSS_IRQ_COMPOSITE_MASK_2		0x0000006C
-
-/* By default, this 'allows' the interrupts from
- * CSI_1 to pass through, unless configured in
- * composite mode. */
-#define CAMSS_IRQ_COMPOSITE_MASK_3		0x00000070
-
-/* By default, this 'allows' the interrupts from
- * CSI_2 to pass through, unless configured in
- * composite mode. */
-#define CAMSS_IRQ_COMPOSITE_MASK_4		0x00000074
-
-/* By default, this 'allows' the interrupts from
- * CSI_3 to pass through, unless configured in
- * composite mode. */
-#define CAMSS_IRQ_COMPOSITE_MASK_5		0x00000078
-
-/* By default, this 'allows' the interrupts from
- * ISPIF to pass through, unless configured in
- * composite mode. */
-#define CAMSS_IRQ_COMPOSITE_MASK_6		0x0000007C
-
-/* By default, this 'allows' the interrupts from
- * CPP to pass through, unless configured in
- * composite mode. */
-#define CAMSS_IRQ_COMPOSITE_MASK_7		0x00000080
-
-/* By default, this 'allows' the interrupts from
- * VFE_0 to pass through, unless configured in
- * composite mode. */
-#define CAMSS_IRQ_COMPOSITE_MASK_8		0x00000084
-
-/* By default, this 'allows' the interrupts from
- * VFE_1 to pass through, unless configured in
- * composite mode. */
-#define CAMSS_IRQ_COMPOSITE_MASK_9		0x00000088
-
-/* By default, this 'allows' the interrupts from
- * JPEG_0 to pass through, unless configured in
- * composite mode. */
-#define CAMSS_IRQ_COMPOSITE_MASK_10		0x0000008C
-
-/* By default, this 'allows' the interrupts from
- * JPEG_1 to pass through, unless configured in
- * composite mode. */
-#define CAMSS_IRQ_COMPOSITE_MASK_11		0x00000090
-
-/* By default, this 'allows' the interrupts from
- * JPEG_2 to pass through, unless configured in
- * composite mode. */
-#define CAMSS_IRQ_COMPOSITE_MASK_12		0x00000094
-
-/* The following IRQ_COMPOSITE_MICRO_MASK registers
- * allow the interrupts from the individual hw
- * cores to be composited into an IRQ for Micro. */
-#define CAMSS_IRQ_COMPOSITE_MICRO_MASK_0	0x000000A4
-#define CAMSS_IRQ_COMPOSITE_MICRO_MASK_1	0x000000A8
-#define CAMSS_IRQ_COMPOSITE_MICRO_MASK_2	0x000000AC
-#define CAMSS_IRQ_COMPOSITE_MICRO_MASK_3	0x000000B0
-#define CAMSS_IRQ_COMPOSITE_MICRO_MASK_4	0x000000B4
-#define CAMSS_IRQ_COMPOSITE_MICRO_MASK_5	0x000000B8
-/* IRQ Router register defines - End */
-
-/* Writing this mask will reset all the composite
- * IRQs of the Camera_SS IRQ Router */
-#define CAMSS_IRQ_COMPOSITE_RESET_MASK		0x003F1FFF
-
-/* Use this to enable Micro IRQ from IRQ Router
- * composite interrupt */
-#define ENABLE_MICRO_IRQ_IN_COMPOSITE		BIT(0)
-/* Use this to enable CCI IRQ from IRQ Router
- * composite interrupt */
-#define ENABLE_CCI_IRQ_IN_COMPOSITE		BIT(1)
-/* Use this to enable CSI0 IRQ from IRQ Router
- * composite interrupt */
-#define ENABLE_CSI0_IRQ_IN_COMPOSITE		BIT(2)
-/* Use this to enable CSI1 IRQ from IRQ Router
- * composite interrupt */
-#define ENABLE_CSI1_IRQ_IN_COMPOSITE		BIT(3)
-/* Use this to enable CSI2 IRQ from IRQ Router
- * composite interrupt */
-#define ENABLE_CSI2_IRQ_IN_COMPOSITE		BIT(4)
-/* Use this to enable CSI3 IRQ from IRQ Router
- * composite interrupt */
-#define ENABLE_CSI3_IRQ_IN_COMPOSITE		BIT(5)
-/* Use this to enable ISPIF IRQ from IRQ Router
- * composite interrupt */
-#define ENABLE_ISPIF_IRQ_IN_COMPOSITE		BIT(6)
-/* Use this to enable CPP IRQ from IRQ Router
- * composite interrupt */
-#define ENABLE_CPP_IRQ_IN_COMPOSITE		BIT(7)
-/* Use this to enable VFE0 IRQ from IRQ Router
- * composite interrupt */
-#define ENABLE_VFE0_IRQ_IN_COMPOSITE		BIT(8)
-/* Use this to enable VFE1 IRQ from IRQ Router
- * composite interrupt */
-#define ENABLE_VFE1_IRQ_IN_COMPOSITE		BIT(9)
-/* Use this to enable JPEG0 IRQ from IRQ Router
- * composite interrupt */
-#define ENABLE_JPEG0_IRQ_IN_COMPOSITE		BIT(10)
-/* Use this to enable JPEG1 IRQ from IRQ Router
- * composite interrupt */
-#define ENABLE_JPEG1_IRQ_IN_COMPOSITE		BIT(11)
-/* Use this to enable JPEG2 IRQ from IRQ Router
- * composite interrupt */
-#define ENABLE_JPEG2_IRQ_IN_COMPOSITE		BIT(12)
-
-struct irqrouter_ctrl_type {
-	/* v4l2 subdev */
-	struct v4l2_subdev subdev;
-	struct platform_device *pdev;
-
-	void __iomem *irqr_dev_base;
-
-	struct resource	*irqr_dev_mem;
-	struct resource *irqr_dev_io;
-	atomic_t active;
-	struct msm_cam_server_irqmap_entry def_hw_irqmap[CAMERA_SS_IRQ_MAX];
-};
-
-#endif /* __MSM_CAM_IRQROUTER_H__ */
diff --git a/drivers/media/video/msm/msm_gesture.c b/drivers/media/video/msm/msm_gesture.c
deleted file mode 100644
index 5777cb5..0000000
--- a/drivers/media/video/msm/msm_gesture.c
+++ /dev/null
@@ -1,501 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 <media/v4l2-subdev.h>
-#include <media/msm_camera.h>
-#include <media/msm_gestures.h>
-#include <media/v4l2-ctrls.h>
-#include <mach/camera.h>
-#include "msm.h"
-
-#ifdef CONFIG_MSM_CAMERA_DEBUG
-#define D(fmt, args...) pr_debug("msm_gesture: " fmt, ##args)
-#else
-#define D(fmt, args...) do {} while (0)
-#endif
-
-struct msm_gesture_ctrl {
-	int queue_id;
-	atomic_t active;
-	struct v4l2_ctrl_handler ctrl_handler;
-	int num_ctrls;
-	struct v4l2_fh *p_eventHandle;
-	struct v4l2_subdev *sd;
-	struct msm_ges_evt event;
-	int camera_opened;
-};
-
-static struct msm_gesture_ctrl g_gesture_ctrl;
-
-int msm_gesture_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
-	struct v4l2_event_subscription *sub)
-{
-	D("%s\n", __func__);
-	if (sub->type == V4L2_EVENT_ALL)
-		sub->type = MSM_GES_APP_NOTIFY_EVENT;
-	return v4l2_event_subscribe(fh, sub, 30);
-}
-
-static int msm_gesture_send_ctrl(struct msm_gesture_ctrl *p_gesture_ctrl,
-	int type, void *value, int length, uint32_t timeout)
-{
-	int rc = 0;
-	struct msm_ctrl_cmd ctrlcmd;
-	D("%s qid %d\n", __func__, p_gesture_ctrl->queue_id);
-	ctrlcmd.type = type;
-	ctrlcmd.timeout_ms = timeout;
-	ctrlcmd.length = length;
-	ctrlcmd.value = value;
-	ctrlcmd.vnode_id = 0;
-	ctrlcmd.queue_idx = p_gesture_ctrl->queue_id;
-	ctrlcmd.config_ident = 0;
-
-	rc = msm_server_send_ctrl(&ctrlcmd, MSM_GES_RESP_V4L2);
-	return rc;
-}
-
-static int msm_gesture_proc_ctrl_cmd(struct msm_gesture_ctrl *p_gesture_ctrl,
-	struct v4l2_control *ctrl)
-{
-	int rc = 0;
-	struct msm_ctrl_cmd *tmp_cmd = NULL;
-	uint8_t *ctrl_data = NULL;
-	void __user *uptr_cmd;
-	void __user *uptr_value;
-	uint32_t cmd_len = sizeof(struct msm_ctrl_cmd);
-	uint32_t value_len;
-
-	tmp_cmd = (struct msm_ctrl_cmd *)ctrl->value;
-	uptr_cmd = (void __user *)ctrl->value;
-	uptr_value = (void __user *)tmp_cmd->value;
-	value_len = tmp_cmd->length;
-
-	D("%s: cmd type = %d, up1=0x%x, ulen1=%d, up2=0x%x, ulen2=%d\n",
-		__func__, tmp_cmd->type, (uint32_t)uptr_cmd, cmd_len,
-		(uint32_t)uptr_value, tmp_cmd->length);
-
-	ctrl_data = kzalloc(value_len + cmd_len, GFP_KERNEL);
-	if (ctrl_data == 0) {
-		pr_err("%s could not allocate memory\n", __func__);
-		rc = -ENOMEM;
-		goto end;
-	}
-	tmp_cmd = (struct msm_ctrl_cmd *)ctrl_data;
-	if (copy_from_user((void *)ctrl_data, uptr_cmd,
-			cmd_len)) {
-		pr_err("%s: copy_from_user failed.\n", __func__);
-		rc = -EINVAL;
-		goto end;
-	}
-	tmp_cmd->value = (void *)(ctrl_data + cmd_len);
-	if (uptr_value && tmp_cmd->length > 0) {
-		if (copy_from_user((void *)tmp_cmd->value, uptr_value,
-			value_len)) {
-			pr_err("%s: copy_from_user failed, size=%d\n",
-				__func__, value_len);
-			rc = -EINVAL;
-			goto end;
-		}
-	} else
-		tmp_cmd->value = NULL;
-
-	/* send command to config thread in usersspace, and get return value */
-	rc = msm_server_send_ctrl((struct msm_ctrl_cmd *)ctrl_data,
-			MSM_GES_RESP_V4L2);
-	D("%s: msm_server_control rc=%d\n", __func__, rc);
-	if (rc == 0) {
-		if (uptr_value && tmp_cmd->length > 0 &&
-			copy_to_user((void __user *)uptr_value,
-				(void *)(ctrl_data + cmd_len),
-				tmp_cmd->length)) {
-			pr_err("%s: copy_to_user failed, size=%d\n",
-				__func__, tmp_cmd->length);
-			rc = -EINVAL;
-			goto end;
-		}
-		tmp_cmd->value = uptr_value;
-		if (copy_to_user((void __user *)uptr_cmd,
-			(void *)tmp_cmd, cmd_len)) {
-			pr_err("%s: copy_to_user failed in cpy, size=%d\n",
-				__func__, cmd_len);
-			rc = -EINVAL;
-			goto end;
-		}
-	}
-end:
-	D("%s: END, type = %d, vaddr = 0x%x, vlen = %d, status = %d, rc = %d\n",
-		__func__, tmp_cmd->type, (uint32_t)tmp_cmd->value,
-		tmp_cmd->length, tmp_cmd->status, rc);
-	kfree(ctrl_data);
-	return rc;
-}
-
-static int msm_gesture_s_ctrl(struct v4l2_subdev *sd,
-	struct v4l2_control *ctrl)
-{
-	int rc = 0;
-	struct msm_gesture_ctrl *p_gesture_ctrl = &g_gesture_ctrl;
-	D("%s ctrl->id %d\n", __func__, ctrl->id);
-	rc = msm_gesture_proc_ctrl_cmd(p_gesture_ctrl, ctrl);
-	if (rc != 0) {
-		pr_err("%s set ctrl failed %d\n", __func__, rc);
-		return -EINVAL;
-	}
-	return rc;
-}
-
-static int msm_gesture_s_ctrl_ops(struct v4l2_ctrl *ctrl)
-{
-	int rc = 0;
-	struct v4l2_control control;
-	struct msm_gesture_ctrl *p_gesture_ctrl = &g_gesture_ctrl;
-	control.id = ctrl->id;
-	control.value = ctrl->val;
-	D("%s ctrl->id 0x%x\n", __func__, ctrl->id);
-	rc = msm_gesture_proc_ctrl_cmd(p_gesture_ctrl, &control);
-	if (rc != 0) {
-		pr_err("%s proc ctrl failed %d\n", __func__, rc);
-		return -EINVAL;
-	}
-	return rc;
-}
-
-static int msm_gesture_s_ctrl_ext(struct v4l2_subdev *sd,
-	struct v4l2_ext_controls *ctrls)
-{
-	int rc = 0;
-	struct v4l2_control control;
-	struct msm_gesture_ctrl *p_gesture_ctrl = &g_gesture_ctrl;
-	if ((ctrls->count < 1) || (NULL == ctrls->controls)) {
-		pr_err("%s invalid ctrl failed\n", __func__);
-		return -EINVAL;
-	}
-	control.id = ctrls->controls->id;
-	control.value = ctrls->controls->value;
-	D("%s ctrl->id %d\n", __func__, control.id);
-	rc = msm_gesture_proc_ctrl_cmd(p_gesture_ctrl, &control);
-	if (rc != 0) {
-		pr_err("%s proc ctrl failed %d\n", __func__, rc);
-		return -EINVAL;
-	}
-	return rc;
-}
-
-static int msm_gesture_handle_event(struct v4l2_subdev *sd,
-	struct msm_gesture_ctrl *p_gesture_ctrl, void* arg)
-{
-	int rc = 0;
-	struct v4l2_event *evt = (struct v4l2_event *)arg;
-	struct msm_ges_evt *p_ges_evt = NULL;
-	D("%s: Received gesture evt 0x%x ", __func__, evt->type);
-	p_gesture_ctrl->event.evt_len = 0;
-	p_gesture_ctrl->event.evt_data = NULL;
-
-	p_ges_evt = (struct msm_ges_evt *)evt->u.data;
-	D("%s: event data %p len %d", __func__,
-		p_ges_evt->evt_data,
-		p_ges_evt->evt_len);
-
-	if (p_ges_evt->evt_len > 0) {
-		p_gesture_ctrl->event.evt_data =
-			kzalloc(p_ges_evt->evt_len, GFP_KERNEL);
-
-		if (NULL == p_gesture_ctrl->event.evt_data) {
-			pr_err("%s: cannot allocate event", __func__);
-			rc = -ENOMEM;
-		} else {
-			if (copy_from_user(
-				(void *)p_gesture_ctrl->event.evt_data,
-				(void __user *)p_ges_evt->evt_data,
-				p_ges_evt->evt_len)) {
-				pr_err("%s: copy_from_user failed",
-					__func__);
-				rc = -EFAULT;
-			} else {
-				D("%s: copied the event", __func__);
-				p_gesture_ctrl->event.evt_len =
-					p_ges_evt->evt_len;
-			}
-		}
-	}
-
-	if (rc == 0) {
-		ktime_get_ts(&evt->timestamp);
-		v4l2_event_queue(sd->devnode, evt);
-	}
-	D("%s: exit rc %d ", __func__, rc);
-	return rc;
-}
-
-static int msm_gesture_get_evt_payload(struct v4l2_subdev *sd,
-	struct msm_gesture_ctrl *p_gesture_ctrl, void* arg)
-{
-	int rc = 0;
-	struct msm_ges_evt *p_ges_evt = (struct msm_ges_evt *)arg;
-	D("%s: enter ", __func__);
-	if (NULL != p_gesture_ctrl->event.evt_data) {
-		D("%s: event data %p len %d", __func__,
-			p_gesture_ctrl->event.evt_data,
-			p_gesture_ctrl->event.evt_len);
-
-		if (copy_to_user((void __user *)p_ges_evt->evt_data,
-			p_gesture_ctrl->event.evt_data,
-			p_gesture_ctrl->event.evt_len)) {
-			pr_err("%s: copy_to_user failed.\n", __func__);
-			rc = -EFAULT;
-		} else {
-			D("%s: copied the event", __func__);
-			p_ges_evt->evt_len = p_gesture_ctrl->event.evt_len;
-		}
-	}
-	D("%s: exit rc %d ", __func__, rc);
-	return rc;
-}
-
-static int msm_gesture_handle_cam_event(struct v4l2_subdev *sd,
-	struct msm_gesture_ctrl *p_gesture_ctrl, int cam_evt)
-{
-	int rc = 0;
-	D("%s: cam_evt %d ", __func__, cam_evt);
-
-	if ((cam_evt != MSM_V4L2_GES_CAM_OPEN)
-		&& (cam_evt != MSM_V4L2_GES_CAM_CLOSE)) {
-		pr_err("%s: error invalid event %d ", __func__, cam_evt);
-		return -EINVAL;
-	}
-
-	p_gesture_ctrl->camera_opened =
-		(cam_evt == MSM_V4L2_GES_CAM_OPEN);
-
-	if (atomic_read(&p_gesture_ctrl->active) == 0) {
-		D("%s gesture not active\n", __func__);
-		return 0;
-	}
-
-	rc = msm_gesture_send_ctrl(p_gesture_ctrl, cam_evt, NULL,
-		0, 2000);
-	if (rc != 0) {
-		pr_err("%s gesture ctrl failed %d\n", __func__, rc);
-		rc = -EINVAL;
-	}
-	D("%s exit rc %d\n", __func__, rc);
-	return rc;
-}
-
-long msm_gesture_ioctl(struct v4l2_subdev *sd,
-	 unsigned int cmd, void *arg)
-{
-	int rc = 0;
-	struct msm_gesture_ctrl *p_gesture_ctrl = &g_gesture_ctrl;
-	D("%s\n", __func__);
-	switch (cmd) {
-	case MSM_GES_IOCTL_CTRL_COMMAND: {
-		struct v4l2_control *ctrl = (struct v4l2_control *)arg;
-		D("%s MSM_GES_IOCTL_CTRL_COMMAND arg %p size %d\n", __func__,
-			arg, sizeof(ctrl));
-		rc = msm_gesture_s_ctrl(sd, ctrl);
-		break;
-	}
-	case VIDIOC_MSM_GESTURE_EVT: {
-		rc = msm_gesture_handle_event(sd, p_gesture_ctrl, arg);
-		break;
-	}
-	case VIDIOC_MSM_GESTURE_CAM_EVT: {
-		int cam_evt = *((int *)arg);
-		rc = msm_gesture_handle_cam_event(sd, p_gesture_ctrl, cam_evt);
-		break;
-	}
-	case MSM_GES_GET_EVT_PAYLOAD: {
-		rc = msm_gesture_get_evt_payload(sd, p_gesture_ctrl, arg);
-		break;
-	}
-	default:
-		pr_err("%s: Invalid ioctl %d", __func__, cmd);
-		break;
-	}
-	D("%s exit rc %d\n", __func__, rc);
-	return rc;
-}
-
-static const struct v4l2_ctrl_ops msm_gesture_ctrl_ops = {
-	.s_ctrl = msm_gesture_s_ctrl_ops,
-};
-
-static const struct v4l2_ctrl_config msm_gesture_ctrl_filter = {
-	.ops = &msm_gesture_ctrl_ops,
-	.id = MSM_GESTURE_CID_CTRL_CMD,
-	.name = "Gesture ctrl",
-	.type = V4L2_CTRL_TYPE_INTEGER,
-	.flags = V4L2_CTRL_FLAG_SLIDER,
-	.max = 0x7fffffff,
-	.step = 1,
-	.min = 0x80000000,
-};
-
-static int msm_gesture_init_ctrl(struct v4l2_subdev *sd,
-	struct msm_gesture_ctrl *p_gesture_ctrl)
-{
-	int rc = 0;
-	p_gesture_ctrl->num_ctrls = 1;
-	p_gesture_ctrl->ctrl_handler.error = 0;
-	v4l2_ctrl_handler_init(&p_gesture_ctrl->ctrl_handler,
-		p_gesture_ctrl->num_ctrls);
-	v4l2_ctrl_new_custom(&p_gesture_ctrl->ctrl_handler,
-		&msm_gesture_ctrl_filter, p_gesture_ctrl);
-	if (p_gesture_ctrl->ctrl_handler.error) {
-		int err = p_gesture_ctrl->ctrl_handler.error;
-		D("%s: error adding control %d", __func__, err);
-		p_gesture_ctrl->ctrl_handler.error = 0;
-	}
-	sd->ctrl_handler = &p_gesture_ctrl->ctrl_handler;
-	return rc;
-}
-
-static int msm_gesture_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
-	int rc = 0, rc_err = 0;
-	struct msm_gesture_ctrl *p_gesture_ctrl = &g_gesture_ctrl;
-	D("%s\n", __func__);
-	if (atomic_read(&p_gesture_ctrl->active) != 0) {
-		pr_err("%s already opened\n", __func__);
-		return -EINVAL;
-	}
-	memset(&p_gesture_ctrl->event, 0x0, sizeof(struct msm_ges_evt));
-	rc = msm_server_open_client(&p_gesture_ctrl->queue_id);
-	if (rc != 0) {
-		pr_err("%s open failed %d\n", __func__, rc);
-		rc = -EINVAL;
-		goto err;
-	}
-
-	rc = msm_gesture_init_ctrl(sd, p_gesture_ctrl);
-	if (rc != 0) {
-		pr_err("%s init ctrl failed %d\n", __func__, rc);
-		rc = -EINVAL;
-		goto err;
-	}
-
-	rc = msm_gesture_send_ctrl(p_gesture_ctrl, MSM_V4L2_GES_OPEN, NULL,
-		0, 10000);
-	if (rc != 0) {
-		pr_err("%s gesture ctrl failed %d\n", __func__, rc);
-		rc = -EINVAL;
-		goto err;
-	}
-
-	atomic_inc(&p_gesture_ctrl->active);
-
-	return rc;
-
-err:
-	rc_err = msm_server_close_client(p_gesture_ctrl->queue_id);
-	if (rc_err != 0)
-		pr_err("%s failed %d\n", __func__, rc);
-	return rc;
-}
-
-static int msm_gesture_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
-	int rc = 0;
-	struct msm_gesture_ctrl *p_gesture_ctrl = &g_gesture_ctrl;
-	D("%s\n", __func__);
-	if (atomic_read(&p_gesture_ctrl->active) == 0) {
-		pr_err("%s already closed\n", __func__);
-		return -EINVAL;
-	}
-
-	rc = msm_gesture_send_ctrl(p_gesture_ctrl, MSM_V4L2_GES_CLOSE, NULL,
-		0, 10000);
-	if (rc != 0)
-		pr_err("%s gesture ctrl failed %d\n", __func__, rc);
-
-	rc = msm_server_close_client(p_gesture_ctrl->queue_id);
-	if (rc != 0)
-		pr_err("%s failed %d\n", __func__, rc);
-
-	v4l2_ctrl_handler_free(&p_gesture_ctrl->ctrl_handler);
-	kfree(p_gesture_ctrl->event.evt_data);
-
-	atomic_dec(&p_gesture_ctrl->active);
-	g_gesture_ctrl.queue_id = -1;
-	return 0;
-}
-
-static struct v4l2_subdev_core_ops msm_gesture_core_ops = {
-	.s_ctrl = msm_gesture_s_ctrl,
-	.s_ext_ctrls = msm_gesture_s_ctrl_ext,
-	.ioctl = msm_gesture_ioctl,
-	.subscribe_event = msm_gesture_subscribe_event,
-};
-
-static struct v4l2_subdev_video_ops msm_gesture_video_ops;
-
-static struct v4l2_subdev_ops msm_gesture_subdev_ops = {
-	.core = &msm_gesture_core_ops,
-	.video  = &msm_gesture_video_ops,
-};
-
-static const struct v4l2_subdev_internal_ops msm_gesture_internal_ops = {
-	.open = msm_gesture_open,
-	.close = msm_gesture_close,
-};
-
-static int msm_gesture_node_register(void)
-{
-	struct msm_gesture_ctrl *p_gesture_ctrl = &g_gesture_ctrl;
-	struct v4l2_subdev *gesture_subdev =
-		kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
-	struct msm_cam_subdev_info sd_info;
-
-	D("%s\n", __func__);
-	if (!gesture_subdev) {
-		pr_err("%s: no enough memory\n", __func__);
-		return -ENOMEM;
-	};
-
-	v4l2_subdev_init(gesture_subdev, &msm_gesture_subdev_ops);
-	gesture_subdev->internal_ops = &msm_gesture_internal_ops;
-	gesture_subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-	snprintf(gesture_subdev->name,
-			 sizeof(gesture_subdev->name), "gesture");
-
-	media_entity_init(&gesture_subdev->entity, 0, NULL, 0);
-	gesture_subdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
-	gesture_subdev->entity.group_id = GESTURE_DEV;
-	gesture_subdev->entity.name = gesture_subdev->name;
-
-	/* events */
-	gesture_subdev->flags |= V4L2_SUBDEV_FL_HAS_EVENTS;
-
-	sd_info.sdev_type = GESTURE_DEV;
-	sd_info.sd_index = 0;
-	sd_info.irq_num = 0;
-	msm_cam_register_subdev_node(gesture_subdev, &sd_info);
-
-	gesture_subdev->entity.revision = gesture_subdev->devnode->num;
-
-	atomic_set(&p_gesture_ctrl->active, 0);
-	p_gesture_ctrl->queue_id = -1;
-	p_gesture_ctrl->event.evt_data = NULL;
-	p_gesture_ctrl->event.evt_len = 0;
-	return 0;
-}
-
-static int __init msm_gesture_init_module(void)
-{
-	return msm_gesture_node_register();
-}
-
-module_init(msm_gesture_init_module);
-MODULE_DESCRIPTION("MSM Gesture driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/msm_isp.c b/drivers/media/video/msm/msm_isp.c
deleted file mode 100644
index 48ce577..0000000
--- a/drivers/media/video/msm/msm_isp.c
+++ /dev/null
@@ -1,767 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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/export.h>
-#include <linux/workqueue.h>
-#include <linux/delay.h>
-#include <linux/types.h>
-#include <linux/list.h>
-#include <linux/ioctl.h>
-#include <linux/spinlock.h>
-#include <linux/videodev2.h>
-#include <linux/proc_fs.h>
-#include <linux/vmalloc.h>
-#include <linux/android_pmem.h>
-
-#include <media/v4l2-dev.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-device.h>
-#include <media/msm_isp.h>
-#include <media/msm_gemini.h>
-
-#include "msm.h"
-
-#ifdef CONFIG_MSM_CAMERA_DEBUG
-#define D(fmt, args...) pr_debug("msm_isp: " fmt, ##args)
-#else
-#define D(fmt, args...) do {} while (0)
-#endif
-
-#define MSM_FRAME_AXI_MAX_BUF 32
-
-/*
- * This function executes in interrupt context.
- */
-
-void *msm_isp_sync_alloc(int size,
-	  gfp_t gfp)
-{
-	struct msm_queue_cmd *qcmd =
-		kmalloc(sizeof(struct msm_queue_cmd) + size, gfp);
-
-	if (qcmd) {
-		atomic_set(&qcmd->on_heap, 1);
-		return qcmd + 1;
-	}
-	return NULL;
-}
-
-void msm_isp_sync_free(void *ptr)
-{
-	if (ptr) {
-		struct msm_queue_cmd *qcmd =
-			(struct msm_queue_cmd *)ptr;
-		qcmd--;
-		if (atomic_read(&qcmd->on_heap))
-			kfree(qcmd);
-	}
-}
-
-static int msm_isp_notify_VFE_SOF_COUNT_EVT(struct v4l2_subdev *sd, void *arg)
-{
-	struct msm_vfe_cfg_cmd cfgcmd;
-	struct msm_camvfe_params vfe_params;
-	int rc;
-
-	cfgcmd.cmd_type = CMD_VFE_PIX_SOF_COUNT_UPDATE;
-	cfgcmd.value = NULL;
-	vfe_params.vfe_cfg = &cfgcmd;
-	vfe_params.data = arg;
-	rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
-	return 0;
-}
-
-int msm_isp_vfe_msg_to_img_mode(struct msm_cam_media_controller *pmctl,
-				int vfe_msg)
-{
-	int image_mode;
-	uint32_t vfe_output_mode = pmctl->vfe_output_mode;
-	vfe_output_mode &= ~(VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1);
-	if (vfe_msg == VFE_MSG_OUTPUT_PRIMARY) {
-		switch (vfe_output_mode) {
-		case VFE_OUTPUTS_MAIN_AND_PREVIEW:
-		case VFE_OUTPUTS_MAIN_AND_VIDEO:
-		case VFE_OUTPUTS_MAIN_AND_THUMB:
-		case VFE_OUTPUTS_RAW:
-		case VFE_OUTPUTS_JPEG_AND_THUMB:
-			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_MAIN;
-			break;
-		case VFE_OUTPUTS_THUMB_AND_MAIN:
-			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL;
-			break;
-		case VFE_OUTPUTS_VIDEO:
-		case VFE_OUTPUTS_VIDEO_AND_PREVIEW:
-			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_VIDEO;
-			break;
-		case VFE_OUTPUTS_PREVIEW:
-		case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
-			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW;
-			break;
-		default:
-			image_mode = -1;
-			break;
-		}
-	} else if (vfe_msg == VFE_MSG_OUTPUT_SECONDARY) {
-		switch (vfe_output_mode) {
-		case VFE_OUTPUTS_MAIN_AND_PREVIEW:
-		case VFE_OUTPUTS_VIDEO_AND_PREVIEW:
-			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW;
-			break;
-		case VFE_OUTPUTS_MAIN_AND_VIDEO:
-		case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
-			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_VIDEO;
-			break;
-		case VFE_OUTPUTS_MAIN_AND_THUMB:
-			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL;
-			break;
-		case VFE_OUTPUTS_THUMB_AND_MAIN:
-			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_MAIN;
-			break;
-		case VFE_OUTPUTS_JPEG_AND_THUMB:
-			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL;
-			break;
-		case VFE_OUTPUTS_PREVIEW:
-		case VFE_OUTPUTS_VIDEO:
-			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW;
-			break;
-		default:
-			image_mode = -1;
-			break;
-		}
-	} else if (vfe_msg == VFE_MSG_OUTPUT_TERTIARY1) {
-		if (pmctl->vfe_output_mode & VFE_OUTPUTS_RDI0)
-			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_RDI;
-		else
-			image_mode = -1;
-	} else if (vfe_msg == VFE_MSG_OUTPUT_TERTIARY2) {
-		if (pmctl->vfe_output_mode & VFE_OUTPUTS_RDI1)
-			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_RDI1;
-		else
-			image_mode = -1;
-	} else if (VFE_MSG_V2X_LIVESHOT_PRIMARY == vfe_msg) {
-			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_V2X_LIVESHOT;
-	} else
-		image_mode = -1;
-
-	D("%s Selected image mode %d vfe output mode %d, vfe msg %d\n",
-	  __func__, image_mode, pmctl->vfe_output_mode, vfe_msg);
-	return image_mode;
-}
-
-static int msm_isp_notify_VFE_BUF_EVT(struct msm_cam_media_controller *pmctl,
-					struct v4l2_subdev *sd, void *arg)
-{
-	int rc = -EINVAL;
-	struct msm_vfe_resp *vdata = (struct msm_vfe_resp *)arg;
-	struct msm_free_buf free_buf, temp_free_buf;
-	struct msm_camvfe_params vfe_params;
-	struct msm_vfe_cfg_cmd cfgcmd;
-	struct msm_cam_v4l2_device *pcam = pmctl->pcam_ptr;
-	struct msm_frame_info *frame_info =
-		(struct msm_frame_info *)vdata->evt_msg.data;
-	uint32_t vfe_id;
-	struct msm_cam_buf_handle buf_handle;
-
-	if (!pcam) {
-		pr_err("%s pcam is null. return\n", __func__);
-		msm_isp_sync_free(vdata);
-		return rc;
-	}
-	if (frame_info) {
-		vfe_id = frame_info->path;
-		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_INST_HANDLE;
-		buf_handle.inst_handle = frame_info->inst_handle;
-	} else {
-		vfe_id = vdata->evt_msg.msg_id;
-		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_IMG_MODE;
-		buf_handle.image_mode =
-			msm_isp_vfe_msg_to_img_mode(pmctl, vfe_id);
-	}
-
-	switch (vdata->type) {
-	case VFE_MSG_START:
-	case VFE_MSG_START_RECORDING:
-	case VFE_MSG_PREVIEW:
-		D("%s Got V32_START_*: Getting ping addr id = %d",
-						__func__, vfe_id);
-		msm_mctl_reserve_free_buf(pmctl, NULL,
-					&buf_handle, &free_buf);
-		cfgcmd.cmd_type = CMD_CONFIG_PING_ADDR;
-		cfgcmd.value = &vfe_id;
-		vfe_params.vfe_cfg = &cfgcmd;
-		vfe_params.data = (void *)&free_buf;
-		rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
-		msm_mctl_reserve_free_buf(pmctl, NULL,
-					&buf_handle, &free_buf);
-		cfgcmd.cmd_type = CMD_CONFIG_PONG_ADDR;
-		cfgcmd.value = &vfe_id;
-		vfe_params.vfe_cfg = &cfgcmd;
-		vfe_params.data = (void *)&free_buf;
-		rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
-		break;
-	case VFE_MSG_CAPTURE:
-		pr_debug("%s Got V32_CAPTURE: getting buffer for id = %d",
-						__func__, vfe_id);
-		msm_mctl_reserve_free_buf(pmctl, NULL,
-					&buf_handle, &free_buf);
-		cfgcmd.cmd_type = CMD_CONFIG_PING_ADDR;
-		cfgcmd.value = &vfe_id;
-		vfe_params.vfe_cfg = &cfgcmd;
-		vfe_params.data = (void *)&free_buf;
-		rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
-		temp_free_buf = free_buf;
-		if (msm_mctl_reserve_free_buf(pmctl, NULL,
-					&buf_handle, &free_buf)) {
-			/* Write the same buffer into PONG */
-			free_buf = temp_free_buf;
-		}
-		cfgcmd.cmd_type = CMD_CONFIG_PONG_ADDR;
-		cfgcmd.value = &vfe_id;
-		vfe_params.vfe_cfg = &cfgcmd;
-		vfe_params.data = (void *)&free_buf;
-		rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
-		break;
-	case VFE_MSG_JPEG_CAPTURE:
-		D("%s:VFE_MSG_JPEG_CAPTURE vdata->type %d\n", __func__,
-			vdata->type);
-		free_buf.num_planes = 2;
-		free_buf.ch_paddr[0] = pmctl->ping_imem_y;
-		free_buf.ch_paddr[1] = pmctl->ping_imem_cbcr;
-		cfgcmd.cmd_type = CMD_CONFIG_PING_ADDR;
-		cfgcmd.value = &vfe_id;
-		vfe_params.vfe_cfg = &cfgcmd;
-		vfe_params.data = (void *)&free_buf;
-		D("%s:VFE_MSG_JPEG_CAPTURE y_ping=%x cbcr_ping=%x\n",
-			__func__, free_buf.ch_paddr[0], free_buf.ch_paddr[1]);
-		rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
-		/* Write the same buffer into PONG */
-		free_buf.ch_paddr[0] = pmctl->pong_imem_y;
-		free_buf.ch_paddr[1] = pmctl->pong_imem_cbcr;
-		cfgcmd.cmd_type = CMD_CONFIG_PONG_ADDR;
-		cfgcmd.value = &vfe_id;
-		vfe_params.vfe_cfg = &cfgcmd;
-		vfe_params.data = (void *)&free_buf;
-		D("%s:VFE_MSG_JPEG_CAPTURE y_pong=%x cbcr_pong=%x\n",
-			__func__, free_buf.ch_paddr[0], free_buf.ch_paddr[1]);
-		rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
-		break;
-	case VFE_MSG_OUTPUT_IRQ:
-		D("%s Got OUTPUT_IRQ: Getting free buf id = %d",
-						__func__, vfe_id);
-		msm_mctl_reserve_free_buf(pmctl, NULL,
-					&buf_handle, &free_buf);
-		cfgcmd.cmd_type = CMD_CONFIG_FREE_BUF_ADDR;
-		cfgcmd.value = &vfe_id;
-		vfe_params.vfe_cfg = &cfgcmd;
-		vfe_params.data = (void *)&free_buf;
-		rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
-		break;
-	default:
-		pr_err("%s: Invalid vdata type: %d\n", __func__, vdata->type);
-		break;
-	}
-	return rc;
-}
-
-/*
- * This function executes in interrupt context.
- */
-static int msm_isp_notify_vfe(struct msm_cam_media_controller *pmctl,
-	struct v4l2_subdev *sd,	unsigned int notification,  void *arg)
-{
-	int rc = 0;
-	struct v4l2_event v4l2_evt;
-	struct msm_isp_event_ctrl *isp_event;
-	struct msm_free_buf buf;
-
-	if (!pmctl) {
-		pr_err("%s: no context in dsp callback.\n", __func__);
-		rc = -EINVAL;
-		return rc;
-	}
-
-	if (notification == NOTIFY_VFE_BUF_EVT)
-		return msm_isp_notify_VFE_BUF_EVT(pmctl, sd, arg);
-
-	if (notification == NOTIFY_VFE_PIX_SOF_COUNT)
-		return msm_isp_notify_VFE_SOF_COUNT_EVT(sd, arg);
-
-	isp_event = kzalloc(sizeof(struct msm_isp_event_ctrl), GFP_ATOMIC);
-	if (!isp_event) {
-		pr_err("%s Insufficient memory. return", __func__);
-		return -ENOMEM;
-	}
-
-	v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
-					MSM_CAM_RESP_STAT_EVT_MSG;
-	v4l2_evt.id = 0;
-
-	*((uint32_t *)v4l2_evt.u.data) = (uint32_t)isp_event;
-
-	isp_event->resptype = MSM_CAM_RESP_STAT_EVT_MSG;
-	isp_event->isp_data.isp_msg.type = MSM_CAMERA_MSG;
-	isp_event->isp_data.isp_msg.len = 0;
-
-	switch (notification) {
-	case NOTIFY_ISP_MSG_EVT: {
-		struct isp_msg_event *isp_msg = (struct isp_msg_event *)arg;
-
-		isp_event->isp_data.isp_msg.msg_id = isp_msg->msg_id;
-		isp_event->isp_data.isp_msg.frame_id = isp_msg->sof_count;
-		getnstimeofday(&(isp_event->isp_data.isp_msg.timestamp));
-		break;
-	}
-	case NOTIFY_VFE_MSG_OUT: {
-		uint8_t msgid;
-		struct msm_cam_buf_handle buf_handle;
-		struct isp_msg_output *isp_output =
-				(struct isp_msg_output *)arg;
-		if (!isp_output->buf.inst_handle) {
-			switch (isp_output->output_id) {
-			case MSG_ID_OUTPUT_P:
-				msgid = VFE_MSG_OUTPUT_P;
-				break;
-			case MSG_ID_OUTPUT_V:
-				msgid = VFE_MSG_OUTPUT_V;
-				break;
-			case MSG_ID_OUTPUT_T:
-				msgid = VFE_MSG_OUTPUT_T;
-				break;
-			case MSG_ID_OUTPUT_S:
-				msgid = VFE_MSG_OUTPUT_S;
-				break;
-			case MSG_ID_OUTPUT_PRIMARY:
-				msgid = VFE_MSG_OUTPUT_PRIMARY;
-				break;
-			case MSG_ID_OUTPUT_SECONDARY:
-				msgid = VFE_MSG_OUTPUT_SECONDARY;
-				break;
-			case MSG_ID_OUTPUT_TERTIARY1:
-				msgid = VFE_MSG_OUTPUT_TERTIARY1;
-				break;
-			case MSG_ID_OUTPUT_TERTIARY2:
-				msgid = VFE_MSG_OUTPUT_TERTIARY2;
-				break;
-
-			default:
-				pr_err("%s: Invalid VFE output id: %d\n",
-					   __func__, isp_output->output_id);
-				rc = -EINVAL;
-				break;
-			}
-			if (!rc) {
-				buf_handle.buf_lookup_type =
-					BUF_LOOKUP_BY_IMG_MODE;
-				buf_handle.image_mode =
-				msm_isp_vfe_msg_to_img_mode(pmctl, msgid);
-			}
-		} else {
-			buf_handle.buf_lookup_type = BUF_LOOKUP_BY_INST_HANDLE;
-			buf_handle.inst_handle = isp_output->buf.inst_handle;
-		}
-		isp_event->isp_data.isp_msg.msg_id =
-			isp_output->output_id;
-		isp_event->isp_data.isp_msg.frame_id =
-			isp_output->frameCounter;
-		buf = isp_output->buf;
-		msm_mctl_buf_done(pmctl, &buf_handle,
-			&buf, isp_output->frameCounter);
-		}
-		break;
-	case NOTIFY_VFE_MSG_COMP_STATS: {
-		struct msm_stats_buf *stats = (struct msm_stats_buf *)arg;
-		struct msm_stats_buf *stats_buf = NULL;
-
-		isp_event->isp_data.isp_msg.msg_id = MSG_ID_STATS_COMPOSITE;
-		stats->aec.buff = msm_pmem_stats_ptov_lookup(pmctl,
-					stats->aec.buff, &(stats->aec.fd));
-		stats->awb.buff = msm_pmem_stats_ptov_lookup(pmctl,
-					stats->awb.buff, &(stats->awb.fd));
-		stats->af.buff = msm_pmem_stats_ptov_lookup(pmctl,
-					stats->af.buff, &(stats->af.fd));
-		stats->ihist.buff = msm_pmem_stats_ptov_lookup(pmctl,
-					stats->ihist.buff, &(stats->ihist.fd));
-		stats->rs.buff = msm_pmem_stats_ptov_lookup(pmctl,
-					stats->rs.buff, &(stats->rs.fd));
-		stats->cs.buff = msm_pmem_stats_ptov_lookup(pmctl,
-					stats->cs.buff, &(stats->cs.fd));
-
-		stats_buf = kmalloc(sizeof(struct msm_stats_buf), GFP_ATOMIC);
-		if (!stats_buf) {
-			pr_err("%s: out of memory.\n", __func__);
-			rc = -ENOMEM;
-		} else {
-			*stats_buf = *stats;
-			isp_event->isp_data.isp_msg.len	=
-				sizeof(struct msm_stats_buf);
-			isp_event->isp_data.isp_msg.data = stats_buf;
-		}
-		}
-		break;
-	case NOTIFY_VFE_MSG_STATS: {
-		struct msm_stats_buf stats;
-		struct isp_msg_stats *isp_stats = (struct isp_msg_stats *)arg;
-
-		memset(&stats, 0, sizeof(stats));
-		isp_event->isp_data.isp_msg.msg_id = isp_stats->id;
-		isp_event->isp_data.isp_msg.frame_id =
-			isp_stats->frameCounter;
-		stats.buffer = isp_stats->buffer;
-		stats.fd = isp_stats->fd;
-		/* buf_idx used for O(0) lookup */
-		stats.buf_idx = isp_stats->buf_idx;
-		switch (isp_stats->id) {
-		case MSG_ID_STATS_AEC:
-		case MSG_ID_STATS_BG:
-			stats.aec.buff = stats.buffer;
-			stats.aec.fd = stats.fd;
-			break;
-		case MSG_ID_STATS_BE:
-			stats.be.buff = stats.buffer;
-			stats.be.fd = stats.fd;
-			break;
-		case MSG_ID_STATS_AF:
-		case MSG_ID_STATS_BF:
-			stats.af.buff = stats.buffer;
-			stats.af.fd = stats.fd;
-			break;
-		case MSG_ID_STATS_AWB:
-			stats.awb.buff = stats.buffer;
-			stats.awb.fd = stats.fd;
-			break;
-		case MSG_ID_STATS_IHIST:
-			stats.ihist.buff = stats.buffer;
-			stats.ihist.fd = stats.fd;
-			break;
-		case MSG_ID_STATS_RS:
-			stats.rs.buff = stats.buffer;
-			stats.rs.fd = stats.fd;
-			break;
-		case MSG_ID_STATS_CS:
-			stats.cs.buff = stats.buffer;
-			stats.cs.fd = stats.fd;
-			break;
-		case MSG_ID_STATS_BHIST:
-			stats.skin.buff = stats.buffer;
-			stats.skin.fd = stats.fd;
-			break;
-		case MSG_ID_STATS_AWB_AEC:
-			break;
-		default:
-			pr_err("%s: Invalid msg type", __func__);
-			break;
-		}
-		if (!stats.buffer) {
-			pr_err("%s: msm_pmem_stats_ptov_lookup error\n",
-							__func__);
-			isp_event->isp_data.isp_msg.len = 0;
-			rc = -EFAULT;
-		} else {
-			struct msm_stats_buf *stats_buf =
-				kmalloc(sizeof(struct msm_stats_buf),
-							GFP_ATOMIC);
-			if (!stats_buf) {
-				pr_err("%s: out of memory. stats_id = %d\n",
-					__func__, isp_stats->id);
-				rc = -ENOMEM;
-			} else {
-				*stats_buf = stats;
-				isp_event->isp_data.isp_msg.len	=
-					sizeof(struct msm_stats_buf);
-				isp_event->isp_data.isp_msg.data = stats_buf;
-			}
-		}
-		}
-		break;
-	default:
-		pr_err("%s: Unsupport isp notification %d\n",
-			__func__, notification);
-		rc = -EINVAL;
-		break;
-	}
-
-	v4l2_event_queue(pmctl->config_device->config_stat_event_queue.pvdev,
-			 &v4l2_evt);
-
-	return rc;
-}
-
-int msm_isp_notify(struct msm_cam_media_controller *pmctl,
-	struct v4l2_subdev *sd,	unsigned int notification, void *arg)
-{
-	return msm_isp_notify_vfe(pmctl, sd, notification, arg);
-}
-EXPORT_SYMBOL(msm_isp_notify);
-
-static int msm_config_vfe(struct v4l2_subdev *sd,
-	struct msm_cam_media_controller *mctl, void __user *arg)
-{
-	struct msm_vfe_cfg_cmd cfgcmd;
-	struct axidata axi_data;
-
-	if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
-		ERR_COPY_FROM_USER();
-		return -EFAULT;
-	}
-
-	memset(&axi_data, 0, sizeof(axi_data));
-	CDBG("%s: cmd_type %d\n", __func__, cfgcmd.cmd_type);
-	switch (cfgcmd.cmd_type) {
-	case CMD_STATS_BG_ENABLE:
-	case CMD_STATS_BE_ENABLE:
-	case CMD_STATS_BF_ENABLE:
-	case CMD_STATS_BHIST_ENABLE:
-	case CMD_STATS_AF_ENABLE:
-	case CMD_STATS_AEC_ENABLE:
-	case CMD_STATS_AWB_ENABLE:
-	case CMD_STATS_AEC_AWB_ENABLE:
-	case CMD_STATS_IHIST_ENABLE:
-	case CMD_STATS_RS_ENABLE:
-	case CMD_STATS_CS_ENABLE:
-		return msm_isp_subdev_ioctl(sd, &cfgcmd, NULL);
-	case CMD_GENERAL:
-	case CMD_STATS_DISABLE:
-		return msm_isp_subdev_ioctl(sd, &cfgcmd,
-							&axi_data);
-	default:
-		pr_err("%s: unknown command type %d\n",
-			__func__, cfgcmd.cmd_type);
-	}
-
-	return -EINVAL;
-}
-
-static int msm_axi_config(struct v4l2_subdev *sd,
-		struct msm_cam_media_controller *mctl, void __user *arg)
-{
-	struct msm_vfe_cfg_cmd cfgcmd;
-
-	if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
-		ERR_COPY_FROM_USER();
-		return -EFAULT;
-	}
-
-	switch (cfgcmd.cmd_type) {
-	case CMD_AXI_CFG_PRIM:
-	case CMD_AXI_CFG_SEC:
-	case CMD_AXI_CFG_ZSL:
-	case CMD_RAW_PICT_AXI_CFG:
-	case CMD_AXI_CFG_PRIM_ALL_CHNLS:
-	case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC:
-	case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC_ALL_CHNLS:
-	case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC:
-	case CMD_AXI_START:
-	case CMD_AXI_STOP:
-	case CMD_AXI_RESET:
-	case CMD_AXI_CFG_TERT1:
-	case CMD_AXI_CFG_TERT2:
-		/* Dont need to pass buffer information.
-		 * subdev will get the buffer from media
-		 * controller free queue.
-		 */
-		return msm_isp_subdev_ioctl(sd, &cfgcmd, NULL);
-
-	default:
-		pr_err("%s: unknown command type %d\n",
-			__func__,
-			cfgcmd.cmd_type);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int msm_put_stats_buffer(struct v4l2_subdev *sd,
-			struct msm_cam_media_controller *mctl, void __user *arg)
-{
-	int rc = -EIO;
-
-	struct msm_stats_buf buf;
-	unsigned long pphy;
-	struct msm_vfe_cfg_cmd cfgcmd;
-
-	if (copy_from_user(&buf, arg,
-				sizeof(struct msm_stats_buf))) {
-		ERR_COPY_FROM_USER();
-		return -EFAULT;
-	}
-
-	CDBG("%s\n", __func__);
-	pphy = msm_pmem_stats_vtop_lookup(mctl, buf.buffer, buf.fd);
-
-	if (pphy != 0) {
-		if (buf.type == STAT_AF)
-			cfgcmd.cmd_type = CMD_STATS_AF_BUF_RELEASE;
-		else if (buf.type == STAT_AEC)
-			cfgcmd.cmd_type = CMD_STATS_AEC_BUF_RELEASE;
-		else if (buf.type == STAT_AWB)
-			cfgcmd.cmd_type = CMD_STATS_AWB_BUF_RELEASE;
-		else if (buf.type == STAT_IHIST)
-			cfgcmd.cmd_type = CMD_STATS_IHIST_BUF_RELEASE;
-		else if (buf.type == STAT_RS)
-			cfgcmd.cmd_type = CMD_STATS_RS_BUF_RELEASE;
-		else if (buf.type == STAT_CS)
-			cfgcmd.cmd_type = CMD_STATS_CS_BUF_RELEASE;
-		else if (buf.type == STAT_AEAW)
-			cfgcmd.cmd_type = CMD_STATS_BUF_RELEASE;
-		else if (buf.type == STAT_BG)
-			cfgcmd.cmd_type = CMD_STATS_BG_BUF_RELEASE;
-		else if (buf.type == STAT_BE)
-			cfgcmd.cmd_type = CMD_STATS_BE_BUF_RELEASE;
-		else if (buf.type == STAT_BF)
-			cfgcmd.cmd_type = CMD_STATS_BF_BUF_RELEASE;
-		else if (buf.type == STAT_BHIST)
-			cfgcmd.cmd_type = CMD_STATS_BHIST_BUF_RELEASE;
-
-		else {
-			pr_err("%s: invalid buf type %d\n",
-				__func__,
-				buf.type);
-			rc = -EINVAL;
-			goto put_done;
-		}
-
-		cfgcmd.value = (void *)&buf;
-
-		rc = msm_isp_subdev_ioctl(sd, &cfgcmd, &pphy);
-	} else {
-		pr_err("%s: NULL physical address\n", __func__);
-		rc = -EINVAL;
-	}
-
-put_done:
-	return rc;
-}
-
-static int msm_vfe_stats_buf_ioctl(struct v4l2_subdev *sd,
-	unsigned int cmd,
-	struct msm_cam_media_controller *mctl,
-	void __user *arg)
-{
-	struct msm_vfe_cfg_cmd cfgcmd;
-	int rc = 0;
-	v4l2_set_subdev_hostdata(sd, mctl);
-	switch (cmd) {
-	case MSM_CAM_IOCTL_STATS_REQBUF: {
-		struct msm_stats_reqbuf reqbuf;
-		if (copy_from_user(&reqbuf, arg,
-			sizeof(struct msm_stats_reqbuf))) {
-			ERR_COPY_FROM_USER();
-			return -EFAULT;
-		}
-	cfgcmd.cmd_type = VFE_CMD_STATS_REQBUF;
-	cfgcmd.value = (void *)&reqbuf;
-	cfgcmd.length = sizeof(struct msm_stats_reqbuf);
-	rc = msm_isp_subdev_ioctl(sd, &cfgcmd, (void *)mctl->client);
-	break;
-	}
-	case MSM_CAM_IOCTL_STATS_ENQUEUEBUF: {
-		struct msm_stats_buf_info buf_info;
-		if (copy_from_user(&buf_info, arg,
-			sizeof(struct msm_stats_buf_info))) {
-			ERR_COPY_FROM_USER();
-			return -EFAULT;
-		}
-	cfgcmd.cmd_type = VFE_CMD_STATS_ENQUEUEBUF;
-	cfgcmd.value = (void *)&buf_info;
-	cfgcmd.length = sizeof(struct msm_stats_buf_info);
-	rc = msm_isp_subdev_ioctl(sd, &cfgcmd, NULL);
-	break;
-	}
-	case MSM_CAM_IOCTL_STATS_FLUSH_BUFQ: {
-		struct msm_stats_flush_bufq bufq_info;
-		if (copy_from_user(&bufq_info, arg,
-			sizeof(struct msm_stats_flush_bufq))) {
-			ERR_COPY_FROM_USER();
-			return -EFAULT;
-		}
-	cfgcmd.cmd_type = VFE_CMD_STATS_FLUSH_BUFQ;
-	cfgcmd.value = (void *)&bufq_info;
-	cfgcmd.length = sizeof(struct msm_stats_flush_bufq);
-	rc = msm_isp_subdev_ioctl(sd, &cfgcmd, NULL);
-	break;
-	}
-	case MSM_CAM_IOCTL_STATS_UNREG_BUF: {
-		struct msm_stats_reqbuf reqbuf;
-		if (copy_from_user(&reqbuf, arg,
-			sizeof(struct msm_stats_reqbuf))) {
-			ERR_COPY_FROM_USER();
-			return -EFAULT;
-		}
-	cfgcmd.cmd_type = VFE_CMD_STATS_UNREGBUF;
-	cfgcmd.value = (void *)&reqbuf;
-	cfgcmd.length = sizeof(struct msm_stats_reqbuf);
-	rc = msm_isp_subdev_ioctl(sd, &cfgcmd, (void *)mctl->client);
-	break;
-	}
-	default:
-		rc = -1;
-	break;
-	}
-	CDBG("%s\n", __func__);
-	return rc;
-}
-/* config function simliar to origanl msm_ioctl_config*/
-int msm_isp_config(struct msm_cam_media_controller *pmctl,
-			 unsigned int cmd, unsigned long arg)
-{
-
-	int rc = -EINVAL;
-	void __user *argp = (void __user *)arg;
-	struct v4l2_subdev *sd;
-	if (!pmctl->vfe_sdev) {
-		pr_err("%s vfe subdev is NULL\n", __func__);
-		return -ENXIO;
-	}
-	sd = pmctl->vfe_sdev;
-	D("%s: cmd %d\n", __func__, _IOC_NR(cmd));
-	switch (cmd) {
-	case MSM_CAM_IOCTL_CONFIG_VFE:
-		/* Coming from config thread for update */
-		rc = msm_config_vfe(sd, pmctl, argp);
-		break;
-
-	case MSM_CAM_IOCTL_AXI_CONFIG:
-		D("Received MSM_CAM_IOCTL_AXI_CONFIG\n");
-		rc = msm_axi_config(sd, pmctl, argp);
-		break;
-
-	case MSM_CAM_IOCTL_RELEASE_STATS_BUFFER:
-		rc = msm_put_stats_buffer(sd, pmctl, argp);
-		break;
-
-	case MSM_CAM_IOCTL_STATS_REQBUF:
-	case MSM_CAM_IOCTL_STATS_ENQUEUEBUF:
-	case MSM_CAM_IOCTL_STATS_FLUSH_BUFQ:
-	case MSM_CAM_IOCTL_STATS_UNREG_BUF:
-		rc = msm_vfe_stats_buf_ioctl(sd, cmd, pmctl, argp);
-		break;
-
-	default:
-		break;
-	}
-
-	D("%s: cmd %d DONE\n", __func__, _IOC_NR(cmd));
-
-	return rc;
-}
-EXPORT_SYMBOL(msm_isp_config);
-
-int msm_isp_subdev_ioctl(struct v4l2_subdev *isp_subdev,
-	struct msm_vfe_cfg_cmd *cfgcmd, void *data)
-{
-	struct msm_camvfe_params vfe_params;
-	vfe_params.vfe_cfg = cfgcmd;
-	vfe_params.data = data;
-	return v4l2_subdev_call(isp_subdev, core, ioctl, 0, &vfe_params);
-}
diff --git a/drivers/media/video/msm/msm_mctl_buf.c b/drivers/media/video/msm/msm_mctl_buf.c
deleted file mode 100644
index 2919d23..0000000
--- a/drivers/media/video/msm/msm_mctl_buf.c
+++ /dev/null
@@ -1,1073 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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/workqueue.h>
-#include <linux/delay.h>
-#include <linux/types.h>
-#include <linux/list.h>
-#include <linux/ioctl.h>
-#include <linux/spinlock.h>
-#include <linux/videodev2.h>
-#include <linux/vmalloc.h>
-
-#include <media/v4l2-dev.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-device.h>
-
-#include <linux/android_pmem.h>
-
-#include "msm.h"
-#include "msm_cam_server.h"
-#include "msm_ispif.h"
-
-#ifdef CONFIG_MSM_CAMERA_DEBUG
-#define D(fmt, args...) pr_debug("msm_mctl_buf: " fmt, ##args)
-#else
-#define D(fmt, args...) do {} while (0)
-#endif
-
-static int msm_vb2_ops_queue_setup(struct vb2_queue *vq,
-				const struct v4l2_format *fmt,
-				unsigned int *num_buffers,
-				unsigned int *num_planes,
-				unsigned int sizes[],
-				void *alloc_ctxs[])
-{
-	/* get the video device */
-	struct msm_cam_v4l2_dev_inst *pcam_inst = vb2_get_drv_priv(vq);
-	struct msm_cam_v4l2_device *pcam = pcam_inst->pcam;
-	int i;
-
-	D("%s\n", __func__);
-	if (!pcam || !(*num_buffers)) {
-		pr_err("%s error : invalid input\n", __func__);
-		return -EINVAL;
-	}
-
-	*num_planes = pcam_inst->plane_info.num_planes;
-	for (i = 0; i < pcam_inst->vid_fmt.fmt.pix_mp.num_planes; i++) {
-		sizes[i] = pcam_inst->plane_info.plane[i].size;
-		D("%s Inst %p : Plane %d Offset = %d Size = %ld"
-			"Aligned Size = %d", __func__, pcam_inst, i,
-			pcam_inst->plane_info.plane[i].offset,
-			pcam_inst->plane_info.plane[i].size, sizes[i]);
-	}
-	return 0;
-}
-
-static void msm_vb2_ops_wait_prepare(struct vb2_queue *q)
-{
-	/* we use polling so do not use this fn now */
-}
-static void msm_vb2_ops_wait_finish(struct vb2_queue *q)
-{
-	/* we use polling so do not use this fn now */
-}
-
-static int msm_vb2_ops_buf_init(struct vb2_buffer *vb)
-{
-	struct msm_cam_v4l2_dev_inst *pcam_inst;
-	struct msm_cam_v4l2_device *pcam;
-	struct msm_cam_media_controller *pmctl;
-	struct videobuf2_contig_pmem *mem;
-	struct vb2_queue	*vq;
-	uint32_t buf_idx;
-	struct msm_frame_buffer *buf;
-	int rc = 0, i;
-	enum videobuf2_buffer_type buf_type;
-	struct videobuf2_msm_offset offset;
-	vq = vb->vb2_queue;
-	pcam_inst = vb2_get_drv_priv(vq);
-	pcam = pcam_inst->pcam;
-	D("%s\n", __func__);
-	D("%s, inst=0x%x,idx=%d, width = %d\n", __func__,
-		(u32)pcam_inst, pcam_inst->my_index,
-		pcam_inst->vid_fmt.fmt.pix.width);
-	D("%s, inst=0x%x,idx=%d, height = %d\n", __func__,
-		(u32)pcam_inst, pcam_inst->my_index,
-		pcam_inst->vid_fmt.fmt.pix.height);
-
-	buf = container_of(vb, struct msm_frame_buffer, vidbuf);
-	if (buf->state == MSM_BUFFER_STATE_INITIALIZED)
-		return rc;
-
-	if (pcam_inst->plane_info.buffer_type ==
-		V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
-		buf_type = VIDEOBUF2_MULTIPLE_PLANES;
-	else if (pcam_inst->plane_info.buffer_type ==
-		V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		buf_type = VIDEOBUF2_SINGLE_PLANE;
-	else
-		return -EINVAL;
-
-	if (buf_type == VIDEOBUF2_SINGLE_PLANE) {
-		offset.sp_off.y_off = pcam_inst->plane_info.sp_y_offset;
-		offset.sp_off.cbcr_off =
-			pcam_inst->plane_info.plane[0].offset;
-	}
-	buf_idx = vb->v4l2_buf.index;
-	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
-	if (pmctl == NULL) {
-		pr_err("%s No mctl found\n", __func__);
-		return -EINVAL;
-	}
-	for (i = 0; i < vb->num_planes; i++) {
-		mem = vb2_plane_cookie(vb, i);
-		if (buf_type == VIDEOBUF2_MULTIPLE_PLANES)
-			offset.data_offset =
-				pcam_inst->plane_info.plane[i].offset;
-
-		if (vb->v4l2_buf.memory == V4L2_MEMORY_USERPTR)
-			rc = videobuf2_pmem_contig_user_get(mem, &offset,
-				buf_type,
-				pcam_inst->buf_offset[buf_idx][i].addr_offset,
-				pcam_inst->path, pmctl->client,
-				pmctl->domain_num);
-		else
-			rc = videobuf2_pmem_contig_mmap_get(mem, &offset,
-				buf_type, pcam_inst->path);
-		if (rc < 0) {
-			pr_err("%s error initializing buffer ",
-				__func__);
-			return rc;
-		}
-	}
-	buf->state = MSM_BUFFER_STATE_INITIALIZED;
-	return rc;
-}
-
-static int msm_vb2_ops_buf_prepare(struct vb2_buffer *vb)
-{
-	int i, rc = 0;
-	uint32_t len;
-	struct msm_cam_v4l2_dev_inst *pcam_inst;
-	struct msm_cam_v4l2_device *pcam;
-	struct msm_frame_buffer *buf;
-	struct vb2_queue *vq;
-
-	D("%s\n", __func__);
-	if (!vb || !vb->vb2_queue) {
-		pr_err("%s error : input is NULL\n", __func__);
-		return -EINVAL;
-	}
-	vq = vb->vb2_queue;
-	pcam_inst = vb2_get_drv_priv(vq);
-	pcam = pcam_inst->pcam;
-	buf = container_of(vb, struct msm_frame_buffer, vidbuf);
-
-	if (!pcam || !buf) {
-		pr_err("%s error : pointer is NULL\n", __func__);
-		return -EINVAL;
-	}
-	/* by this time vid_fmt should be already set.
-	 * return error if it is not. */
-	if ((pcam_inst->vid_fmt.fmt.pix.width == 0) ||
-		(pcam_inst->vid_fmt.fmt.pix.height == 0)) {
-		pr_err("%s error : pcam vid_fmt is not set\n", __func__);
-		return -EINVAL;
-	}
-	/* prefill in the byteused field */
-	for (i = 0; i < vb->num_planes; i++) {
-		len = vb2_plane_size(vb, i);
-		vb2_set_plane_payload(vb, i, len);
-	}
-	buf->state = MSM_BUFFER_STATE_PREPARED;
-	return rc;
-}
-
-static int msm_vb2_ops_buf_finish(struct vb2_buffer *vb)
-{
-	struct msm_cam_v4l2_dev_inst *pcam_inst;
-	struct msm_cam_v4l2_device *pcam;
-	struct msm_frame_buffer *buf;
-
-	pcam_inst = vb2_get_drv_priv(vb->vb2_queue);
-	pcam = pcam_inst->pcam;
-	buf = container_of(vb, struct msm_frame_buffer, vidbuf);
-	buf->state = MSM_BUFFER_STATE_DEQUEUED;
-	D("%s: inst=0x%x, buf=0x%x, idx=%d\n", __func__,
-	(uint32_t)pcam_inst, (uint32_t)buf, vb->v4l2_buf.index);
-	return 0;
-}
-
-static void msm_vb2_ops_buf_cleanup(struct vb2_buffer *vb)
-{
-	struct msm_cam_v4l2_dev_inst *pcam_inst;
-	struct msm_cam_media_controller *pmctl;
-	struct msm_cam_v4l2_device *pcam;
-	struct videobuf2_contig_pmem *mem;
-	struct msm_frame_buffer *buf, *tmp;
-	uint32_t i, vb_phyaddr = 0, buf_phyaddr = 0;
-	unsigned long flags = 0;
-
-	pcam_inst = vb2_get_drv_priv(vb->vb2_queue);
-	pcam = pcam_inst->pcam;
-	buf = container_of(vb, struct msm_frame_buffer, vidbuf);
-
-
-	if (pcam_inst->vid_fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-		for (i = 0; i < vb->num_planes; i++) {
-			mem = vb2_plane_cookie(vb, i);
-			if (!mem) {
-				D("%s Inst %p memory already freed up. return",
-					__func__, pcam_inst);
-				return;
-			}
-			D("%s: inst=%p, buf=0x%x, idx=%d plane id = %d\n",
-				__func__, pcam_inst,
-				(uint32_t)buf, vb->v4l2_buf.index, i);
-
-			spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
-			list_for_each_entry_safe(buf, tmp,
-					&pcam_inst->free_vq, list) {
-				if (&buf->vidbuf == vb) {
-					list_del_init(&buf->list);
-					break;
-				}
-			}
-			spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
-		}
-	} else {
-		mem = vb2_plane_cookie(vb, 0);
-		if (!mem)
-			return;
-		D("%s: inst=0x%x, buf=0x%x, idx=%d\n", __func__,
-		(uint32_t)pcam_inst, (uint32_t)buf, vb->v4l2_buf.index);
-		vb_phyaddr = (unsigned long) videobuf2_to_pmem_contig(vb, 0);
-		spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
-		list_for_each_entry_safe(buf, tmp,
-				&pcam_inst->free_vq, list) {
-			buf_phyaddr = (unsigned long)
-				videobuf2_to_pmem_contig(&buf->vidbuf, 0);
-			D("%s vb_idx=%d,vb_paddr=0x%x,phyaddr=0x%x\n",
-				__func__, buf->vidbuf.v4l2_buf.index,
-				buf_phyaddr, vb_phyaddr);
-			if (vb_phyaddr == buf_phyaddr) {
-				list_del_init(&buf->list);
-				break;
-			}
-		}
-		spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
-	}
-	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
-	if (pmctl == NULL) {
-		pr_err("%s No mctl found\n", __func__);
-		buf->state = MSM_BUFFER_STATE_UNUSED;
-		return;
-	}
-	for (i = 0; i < vb->num_planes; i++) {
-		mem = vb2_plane_cookie(vb, i);
-		videobuf2_pmem_contig_user_put(mem, pmctl->client,
-			pmctl->domain_num);
-	}
-	buf->state = MSM_BUFFER_STATE_UNUSED;
-}
-
-static int msm_vb2_ops_start_streaming(struct vb2_queue *q, unsigned int count)
-{
-	return 0;
-}
-
-static int msm_vb2_ops_stop_streaming(struct vb2_queue *q)
-{
-	return 0;
-}
-
-static void msm_vb2_ops_buf_queue(struct vb2_buffer *vb)
-{
-	struct msm_cam_v4l2_dev_inst *pcam_inst = NULL;
-	struct msm_cam_v4l2_device *pcam = NULL;
-	unsigned long flags = 0;
-	struct vb2_queue *vq;
-	struct msm_frame_buffer *buf;
-	D("%s\n", __func__);
-	if (!vb || !vb->vb2_queue) {
-		pr_err("%s error : input is NULL\n", __func__);
-		return ;
-	}
-	vq = vb->vb2_queue;
-	pcam_inst = vb2_get_drv_priv(vq);
-	pcam = pcam_inst->pcam;
-	D("%s pcam_inst=%p,(vb=0x%p),idx=%d,len=%d\n",
-		__func__, pcam_inst,
-	vb, vb->v4l2_buf.index, vb->v4l2_buf.length);
-	D("%s pcam_inst=%p, idx=%d\n", __func__, pcam_inst,
-		vb->v4l2_buf.index);
-	buf = container_of(vb, struct msm_frame_buffer, vidbuf);
-	spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
-	/* we are returning a buffer to the queue */
-	list_add_tail(&buf->list, &pcam_inst->free_vq);
-	spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
-	buf->state = MSM_BUFFER_STATE_QUEUED;
-}
-
-static struct vb2_ops msm_vb2_ops = {
-	.queue_setup = msm_vb2_ops_queue_setup,
-	.wait_prepare = msm_vb2_ops_wait_prepare,
-	.wait_finish = msm_vb2_ops_wait_finish,
-	.buf_init = msm_vb2_ops_buf_init,
-	.buf_prepare = msm_vb2_ops_buf_prepare,
-	.buf_finish = msm_vb2_ops_buf_finish,
-	.buf_cleanup = msm_vb2_ops_buf_cleanup,
-	.start_streaming = msm_vb2_ops_start_streaming,
-	.stop_streaming = msm_vb2_ops_stop_streaming,
-	.buf_queue = msm_vb2_ops_buf_queue,
-};
-
-
-/* prepare a video buffer queue for a vl42 device*/
-static int msm_vbqueue_init(struct msm_cam_v4l2_dev_inst *pcam_inst,
-			struct vb2_queue *q, enum v4l2_buf_type type)
-{
-	if (!q) {
-		pr_err("%s error : input is NULL\n", __func__);
-		return -EINVAL;
-	}
-
-	spin_lock_init(&pcam_inst->vq_irqlock);
-	INIT_LIST_HEAD(&pcam_inst->free_vq);
-	videobuf2_queue_pmem_contig_init(q, type,
-					&msm_vb2_ops,
-					sizeof(struct msm_frame_buffer),
-					(void *)pcam_inst);
-	return 0;
-}
-
-int msm_mctl_img_mode_to_inst_index(struct msm_cam_media_controller *pmctl,
-					int image_mode, int node_type)
-{
-	if ((image_mode >= 0) && node_type &&
-		pmctl->pcam_ptr->mctl_node.dev_inst_map[image_mode])
-		return pmctl->pcam_ptr->
-				mctl_node.dev_inst_map[image_mode]->my_index;
-	else if ((image_mode >= 0) &&
-		pmctl->pcam_ptr->dev_inst_map[image_mode])
-		return	pmctl->pcam_ptr->
-				dev_inst_map[image_mode]->my_index;
-	else
-		return -EINVAL;
-}
-
-void msm_mctl_gettimeofday(struct timeval *tv)
-{
-	struct timespec ts;
-
-	BUG_ON(!tv);
-
-	ktime_get_ts(&ts);
-	tv->tv_sec = ts.tv_sec;
-	tv->tv_usec = ts.tv_nsec/1000;
-}
-
-struct msm_frame_buffer *msm_mctl_buf_find(
-	struct msm_cam_media_controller *pmctl,
-	struct msm_cam_v4l2_dev_inst *pcam_inst, int del_buf,
-	struct msm_free_buf *fbuf)
-{
-	struct msm_frame_buffer *buf = NULL, *tmp;
-	uint32_t buf_phyaddr = 0;
-	unsigned long flags = 0;
-	uint32_t buf_idx, offset = 0;
-	struct videobuf2_contig_pmem *mem;
-
-	/* we actually need a list, not a queue */
-	spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
-	list_for_each_entry_safe(buf, tmp,
-			&pcam_inst->free_vq, list) {
-		buf_idx = buf->vidbuf.v4l2_buf.index;
-		mem = vb2_plane_cookie(&buf->vidbuf, 0);
-		if (mem->buffer_type ==	VIDEOBUF2_MULTIPLE_PLANES)
-			offset = mem->offset.data_offset +
-				pcam_inst->buf_offset[buf_idx][0].data_offset;
-		else
-			offset = mem->offset.sp_off.y_off;
-		buf_phyaddr = (unsigned long)
-				videobuf2_to_pmem_contig(&buf->vidbuf, 0) +
-				offset;
-		D("%s vb_idx=%d,vb_paddr=0x%x ch0=0x%x\n",
-			__func__, buf->vidbuf.v4l2_buf.index,
-			buf_phyaddr, fbuf->ch_paddr[0]);
-		if (fbuf->ch_paddr[0] == buf_phyaddr) {
-			if (del_buf)
-				list_del_init(&buf->list);
-			spin_unlock_irqrestore(&pcam_inst->vq_irqlock,
-								flags);
-			buf->state = MSM_BUFFER_STATE_RESERVED;
-			return buf;
-		}
-	}
-	spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
-	return NULL;
-}
-
-int msm_mctl_buf_done_proc(
-		struct msm_cam_media_controller *pmctl,
-		struct msm_cam_v4l2_dev_inst *pcam_inst,
-		struct msm_free_buf *fbuf,
-		uint32_t *frame_id,
-		struct msm_cam_timestamp *cam_ts)
-{
-	struct msm_frame_buffer *buf = NULL;
-	int del_buf = 1;
-
-	buf = msm_mctl_buf_find(pmctl, pcam_inst, del_buf, fbuf);
-	if (!buf) {
-		pr_err("%s: buf=0x%x not found\n",
-			__func__, fbuf->ch_paddr[0]);
-		return -EINVAL;
-	}
-	if (!cam_ts->present) {
-		if (frame_id)
-			buf->vidbuf.v4l2_buf.sequence = *frame_id;
-		msm_mctl_gettimeofday(
-			&buf->vidbuf.v4l2_buf.timestamp);
-	} else {
-		D("%s Copying timestamp as %ld.%ld", __func__,
-			cam_ts->timestamp.tv_sec, cam_ts->timestamp.tv_usec);
-		buf->vidbuf.v4l2_buf.timestamp = cam_ts->timestamp;
-		buf->vidbuf.v4l2_buf.sequence  = cam_ts->frame_id;
-	}
-	D("%s Notify user about buffer %d image_mode %d frame_id %d", __func__,
-		buf->vidbuf.v4l2_buf.index, pcam_inst->image_mode,
-		buf->vidbuf.v4l2_buf.sequence);
-	vb2_buffer_done(&buf->vidbuf, VB2_BUF_STATE_DONE);
-	return 0;
-}
-
-
-int msm_mctl_buf_done(struct msm_cam_media_controller *p_mctl,
-	struct msm_cam_buf_handle *buf_handle,
-	struct msm_free_buf *fbuf,
-	uint32_t frame_id)
-{
-	struct msm_cam_v4l2_dev_inst *pcam_inst;
-	int idx, rc;
-	int pp_divert_type = 0, pp_type = 0;
-	uint32_t image_mode;
-	struct msm_cam_timestamp cam_ts;
-
-	if (!p_mctl || !buf_handle || !fbuf) {
-		pr_err("%s Invalid argument. ", __func__);
-		return -EINVAL;
-	}
-	if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_IMG_MODE)
-		image_mode = buf_handle->image_mode;
-	else
-		image_mode = GET_IMG_MODE(buf_handle->inst_handle);
-
-	if (image_mode > MSM_V4L2_EXT_CAPTURE_MODE_MAX) {
-		pr_err("%s Invalid image mode %d ", __func__, image_mode);
-		return -EINVAL;
-	}
-
-	msm_mctl_check_pp(p_mctl, image_mode, &pp_divert_type, &pp_type);
-	D("%s: pp_type=%d, pp_divert_type = %d, frame_id = 0x%x image_mode %d",
-		__func__, pp_type, pp_divert_type, frame_id, image_mode);
-	if (pp_type || pp_divert_type) {
-		rc = msm_mctl_do_pp_divert(p_mctl, buf_handle,
-			fbuf, frame_id, pp_type);
-	} else {
-		/* Find the instance on which vb2_buffer_done() needs to be
-		 * called, so that the user can get the buffer.
-		 * If the lookup type is
-		 * - By instance handle:
-		 *    Either mctl_pp inst idx or video inst idx should be set.
-		 *    Try to get the MCTL_PP inst idx first, if its not set,
-		 *    fall back to video inst idx. Once we get the inst idx,
-		 *    get the pcam_inst from the corresponding dev_inst[] map.
-		 *    If neither are set, its a serious error, trigger a BUG_ON.
-		 * - By image mode:
-		 *    Legacy usecase. Use the image mode and get the pcam_inst
-		 *    from the video node.
-		 */
-		if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_INST_HANDLE) {
-			idx = GET_MCTLPP_INST_IDX(buf_handle->inst_handle);
-			if (idx > MSM_DEV_INST_MAX) {
-				idx = GET_VIDEO_INST_IDX(
-					buf_handle->inst_handle);
-				BUG_ON(idx > MSM_DEV_INST_MAX);
-				pcam_inst = p_mctl->pcam_ptr->dev_inst[idx];
-			} else {
-				pcam_inst = p_mctl->pcam_ptr->mctl_node.
-					dev_inst[idx];
-			}
-		} else if (buf_handle->buf_lookup_type ==
-				BUF_LOOKUP_BY_IMG_MODE) {
-			idx = msm_mctl_img_mode_to_inst_index(p_mctl,
-				buf_handle->image_mode, 0);
-			if (idx < 0) {
-				pr_err("%s Invalid idx %d ", __func__, idx);
-				return -EINVAL;
-			}
-			pcam_inst = p_mctl->pcam_ptr->dev_inst[idx];
-		} else {
-			pr_err("%s Invalid buffer lookup type %d", __func__,
-				buf_handle->buf_lookup_type);
-			return -EINVAL;
-		}
-		if (!pcam_inst) {
-			pr_err("%s Invalid instance, Dropping buffer. ",
-				__func__);
-			return -EINVAL;
-		}
-		memset(&cam_ts, 0, sizeof(cam_ts));
-		rc = msm_mctl_buf_done_proc(p_mctl, pcam_inst,
-			fbuf, &frame_id, &cam_ts);
-	}
-	return rc;
-}
-
-int msm_mctl_buf_init(struct msm_cam_v4l2_device *pcam)
-{
-	struct msm_cam_media_controller *pmctl;
-	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
-	if (pmctl == NULL) {
-		pr_err("%s No mctl found\n", __func__);
-		return -EINVAL;
-	}
-	pmctl->mctl_vbqueue_init = msm_vbqueue_init;
-	return 0;
-}
-
-static int is_buffer_queued(struct msm_cam_v4l2_device *pcam, int image_mode)
-{
-	int idx;
-	int ret = 0;
-	struct msm_frame_buffer *buf = NULL;
-	struct msm_cam_v4l2_dev_inst *pcam_inst = NULL;
-	idx = pcam->mctl_node.dev_inst_map[image_mode]->my_index;
-	pcam_inst = pcam->mctl_node.dev_inst[idx];
-	list_for_each_entry(buf, &pcam_inst->free_vq, list) {
-		if (buf->state != MSM_BUFFER_STATE_QUEUED)
-			continue;
-		ret = 1;
-	}
-	return ret;
-}
-
-struct msm_cam_v4l2_dev_inst *msm_mctl_get_inst_by_img_mode(
-	struct msm_cam_media_controller *pmctl, uint32_t img_mode)
-{
-	struct msm_cam_v4l2_dev_inst *pcam_inst = NULL;
-	struct msm_cam_v4l2_device *pcam = pmctl->pcam_ptr;
-	int idx;
-
-		/* Valid image mode. Search the mctl node first.
-		 * If mctl node doesnt have the instance, then
-		 * search in the user's video node */
-		if (pmctl->vfe_output_mode == VFE_OUTPUTS_MAIN_AND_THUMB
-		|| pmctl->vfe_output_mode == VFE_OUTPUTS_THUMB_AND_MAIN) {
-			if (pcam->mctl_node.dev_inst_map[img_mode]
-			&& is_buffer_queued(pcam, img_mode)) {
-				idx = pcam->mctl_node.dev_inst_map[img_mode]
-							->my_index;
-				pcam_inst = pcam->mctl_node.dev_inst[idx];
-				D("%s Found instance %p in mctl node device\n",
-				  __func__, pcam_inst);
-			} else if (pcam->dev_inst_map[img_mode]) {
-				idx = pcam->dev_inst_map[img_mode]->my_index;
-				pcam_inst = pcam->dev_inst[idx];
-				D("%s Found instance %p in video device\n",
-				__func__, pcam_inst);
-			}
-		} else if (img_mode == MSM_V4L2_EXT_CAPTURE_MODE_V2X_LIVESHOT) {
-				img_mode = MSM_V4L2_EXT_CAPTURE_MODE_MAIN;
-			if (pcam->mctl_node.dev_inst_map[img_mode] &&
-					is_buffer_queued(pcam, img_mode)) {
-				idx = pcam->mctl_node.dev_inst_map[img_mode]
-							->my_index;
-				pcam_inst = pcam->mctl_node.dev_inst[idx];
-				D("%s Found instance %p in mctl node device\n",
-				  __func__, pcam_inst);
-			} else if (pcam->dev_inst_map[img_mode]) {
-				idx = pcam->dev_inst_map[img_mode]->my_index;
-				pcam_inst = pcam->dev_inst[idx];
-				D("%s Found instance %p in video device\n",
-				__func__, pcam_inst);
-			}
-		} else {
-			if (pcam->mctl_node.dev_inst_map[img_mode]) {
-				idx = pcam->mctl_node.dev_inst_map[img_mode]
-				->my_index;
-				pcam_inst = pcam->mctl_node.dev_inst[idx];
-				D("%s Found instance %p in mctl node device\n",
-				__func__, pcam_inst);
-			} else if (pcam->dev_inst_map[img_mode]) {
-				idx = pcam->dev_inst_map[img_mode]->my_index;
-				pcam_inst = pcam->dev_inst[idx];
-				D("%s Found instance %p in video device\n",
-					__func__, pcam_inst);
-			}
-		}
-	return pcam_inst;
-}
-
-struct msm_cam_v4l2_dev_inst *msm_mctl_get_pcam_inst(
-				struct msm_cam_media_controller *pmctl,
-				struct msm_cam_buf_handle *buf_handle)
-{
-	struct msm_cam_v4l2_dev_inst *pcam_inst = NULL;
-	struct msm_cam_v4l2_device *pcam = pmctl->pcam_ptr;
-	int idx;
-
-	/* Get the pcam instance on based on the following rules:
-	 * If the lookup type is
-	 * - By instance handle:
-	 *    Either mctl_pp inst idx or video inst idx should be set.
-	 *    Try to get the MCTL_PP inst idx first, if its not set,
-	 *    fall back to video inst idx. Once we get the inst idx,
-	 *    get the pcam_inst from the corresponding dev_inst[] map.
-	 *    If neither are set, its a serious error, trigger a BUG_ON.
-	 * - By image mode:(Legacy usecase)
-	 *    If vfe is in configured in snapshot mode, first check if
-	 *    mctl pp node has a instance created for this image mode
-	 *    and if there is a buffer queued for that instance.
-	 *    If so, return that instance, otherwise get the pcam instance
-	 *    for this image_mode from the video instance.
-	 *    If the vfe is configured in any other mode, then first check
-	 *    if mctl pp node has a instance created for this image mode,
-	 *    otherwise get the pcam instance for this image mode from the
-	 *    video instance.
-	 */
-	if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_INST_HANDLE) {
-		idx = GET_MCTLPP_INST_IDX(buf_handle->inst_handle);
-		if (idx > MSM_DEV_INST_MAX) {
-			idx = GET_VIDEO_INST_IDX(buf_handle->inst_handle);
-			BUG_ON(idx > MSM_DEV_INST_MAX);
-			pcam_inst = pcam->dev_inst[idx];
-		} else {
-			pcam_inst = pcam->mctl_node.dev_inst[idx];
-		}
-	} else if ((buf_handle->buf_lookup_type == BUF_LOOKUP_BY_IMG_MODE)
-		&& (buf_handle->image_mode >= 0 &&
-		buf_handle->image_mode < MSM_V4L2_EXT_CAPTURE_MODE_MAX)) {
-		pcam_inst = msm_mctl_get_inst_by_img_mode(pmctl,
-				buf_handle->image_mode);
-	} else {
-		pr_err("%s Invalid buffer lookup type %d", __func__,
-			buf_handle->buf_lookup_type);
-	}
-	return pcam_inst;
-}
-
-int msm_mctl_reserve_free_buf(
-	struct msm_cam_media_controller *pmctl,
-	struct msm_cam_v4l2_dev_inst *pref_pcam_inst,
-	struct msm_cam_buf_handle *buf_handle,
-	struct msm_free_buf *free_buf)
-{
-	struct msm_cam_v4l2_dev_inst *pcam_inst = pref_pcam_inst;
-	unsigned long flags = 0;
-	struct videobuf2_contig_pmem *mem;
-	struct msm_frame_buffer *buf = NULL;
-	int rc = -EINVAL, i;
-	uint32_t buf_idx, plane_offset = 0;
-
-	if (!free_buf || !pmctl || !buf_handle) {
-		pr_err("%s: Invalid argument passed\n", __func__);
-		return rc;
-	}
-	memset(free_buf, 0, sizeof(struct msm_free_buf));
-
-	/* If the caller wants to reserve a buffer from a particular
-	 * camera instance, he would send the preferred camera instance.
-	 * If the preferred camera instance is NULL, get the
-	 * camera instance using the image mode passed */
-	if (!pcam_inst)
-		pcam_inst = msm_mctl_get_pcam_inst(pmctl, buf_handle);
-
-	if (!pcam_inst || !pcam_inst->streamon) {
-		pr_err("%s: stream is turned off\n", __func__);
-		return rc;
-	}
-	spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
-	list_for_each_entry(buf, &pcam_inst->free_vq, list) {
-		if (buf->state != MSM_BUFFER_STATE_QUEUED)
-			continue;
-
-		buf_idx = buf->vidbuf.v4l2_buf.index;
-		if (pcam_inst->vid_fmt.type ==
-				V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-			free_buf->num_planes =
-				pcam_inst->plane_info.num_planes;
-			for (i = 0; i < free_buf->num_planes; i++) {
-				mem = vb2_plane_cookie(&buf->vidbuf, i);
-				if (mem->buffer_type ==
-						VIDEOBUF2_MULTIPLE_PLANES)
-					plane_offset =
-					mem->offset.data_offset;
-				else
-					plane_offset =
-					mem->offset.sp_off.cbcr_off;
-
-				D("%s: data off %d plane off %d",
-					__func__,
-					pcam_inst->buf_offset[buf_idx][i].
-					data_offset, plane_offset);
-				free_buf->ch_paddr[i] =	(uint32_t)
-				videobuf2_to_pmem_contig(&buf->vidbuf, i) +
-				pcam_inst->buf_offset[buf_idx][i].data_offset +
-				plane_offset;
-
-			}
-		} else {
-			mem = vb2_plane_cookie(&buf->vidbuf, 0);
-			free_buf->ch_paddr[0] = (uint32_t)
-				videobuf2_to_pmem_contig(&buf->vidbuf, 0) +
-				mem->offset.sp_off.y_off;
-			free_buf->ch_paddr[1] =	free_buf->ch_paddr[0] +
-				mem->offset.sp_off.cbcr_off;
-		}
-		free_buf->vb = (uint32_t)buf;
-		buf->state = MSM_BUFFER_STATE_RESERVED;
-		D("%s inst=0x%p, idx=%d, paddr=0x%x, "
-			"ch1 addr=0x%x\n", __func__,
-			pcam_inst, buf->vidbuf.v4l2_buf.index,
-			free_buf->ch_paddr[0], free_buf->ch_paddr[1]);
-		rc = 0;
-		break;
-	}
-	if (rc != 0)
-		D("%s:No free buffer available: inst = 0x%p ",
-				__func__, pcam_inst);
-	spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
-	return rc;
-}
-
-int msm_mctl_release_free_buf(struct msm_cam_media_controller *pmctl,
-				struct msm_cam_v4l2_dev_inst *pcam_inst,
-				struct msm_free_buf *free_buf)
-{
-	unsigned long flags = 0;
-	struct msm_frame_buffer *buf = NULL;
-	uint32_t buf_phyaddr = 0;
-	int rc = -EINVAL;
-
-	if (!pcam_inst || !free_buf) {
-		pr_err("%s Invalid argument, buffer will not be returned\n",
-			__func__);
-		return rc;
-	}
-
-	spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
-	list_for_each_entry(buf, &pcam_inst->free_vq, list) {
-		buf_phyaddr =
-			(uint32_t) videobuf2_to_pmem_contig(&buf->vidbuf, 0);
-		if (free_buf->ch_paddr[0] == buf_phyaddr) {
-			D("%s Return buffer %d and mark it as QUEUED\n",
-				__func__, buf->vidbuf.v4l2_buf.index);
-			buf->state = MSM_BUFFER_STATE_QUEUED;
-			rc = 0;
-			break;
-		}
-	}
-	spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
-
-	if (rc)
-		pr_err("%s Cannot find buffer %x", __func__,
-			free_buf->ch_paddr[0]);
-
-	return rc;
-}
-
-int msm_mctl_buf_done_pp(struct msm_cam_media_controller *pmctl,
-	struct msm_cam_buf_handle *buf_handle,
-	struct msm_free_buf *frame,
-	struct msm_cam_return_frame_info *ret_frame)
-{
-	struct msm_cam_v4l2_dev_inst *pcam_inst = NULL;
-	int rc = 0, idx;
-	struct msm_cam_timestamp cam_ts;
-
-	if (!pmctl || !buf_handle || !ret_frame) {
-		pr_err("%s Invalid argument ", __func__);
-		return -EINVAL;
-	}
-
-	if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_INST_HANDLE) {
-		idx = GET_MCTLPP_INST_IDX(buf_handle->inst_handle);
-		if (idx > MSM_DEV_INST_MAX) {
-			idx = GET_VIDEO_INST_IDX(buf_handle->inst_handle);
-			BUG_ON(idx > MSM_DEV_INST_MAX);
-			pcam_inst = pmctl->pcam_ptr->dev_inst[idx];
-		} else {
-			pcam_inst = pmctl->pcam_ptr->mctl_node.dev_inst[idx];
-		}
-	} else if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_IMG_MODE) {
-		idx = msm_mctl_img_mode_to_inst_index(pmctl,
-			buf_handle->image_mode, ret_frame->node_type);
-		if (idx < 0) {
-			pr_err("%s Invalid instance, buffer not released\n",
-				__func__);
-			return idx;
-		}
-		if (ret_frame->node_type)
-			pcam_inst = pmctl->pcam_ptr->mctl_node.dev_inst[idx];
-		else
-			pcam_inst = pmctl->pcam_ptr->dev_inst[idx];
-	}
-	if (!pcam_inst) {
-		pr_err("%s Invalid instance, cannot send buf to user",
-			__func__);
-		return -EINVAL;
-	}
-
-	D("%s:inst=0x%p, paddr=0x%x, dirty=%d",
-		__func__, pcam_inst, frame->ch_paddr[0], ret_frame->dirty);
-	cam_ts.present = 1;
-	cam_ts.timestamp = ret_frame->timestamp;
-	cam_ts.frame_id   = ret_frame->frame_id;
-	if (ret_frame->dirty)
-		/* the frame is dirty, not going to disptach to app */
-		rc = msm_mctl_release_free_buf(pmctl, pcam_inst, frame);
-	else
-		rc = msm_mctl_buf_done_proc(pmctl, pcam_inst, frame,
-			NULL, &cam_ts);
-	return rc;
-}
-
-int msm_mctl_buf_return_buf(struct msm_cam_media_controller *pmctl,
-			int image_mode, struct msm_frame_buffer *rbuf)
-{
-	int idx = 0;
-	struct msm_frame_buffer *buf = NULL;
-	struct msm_cam_v4l2_dev_inst *pcam_inst;
-	struct msm_cam_v4l2_device *pcam = pmctl->pcam_ptr;
-	unsigned long flags = 0;
-
-	if (pcam->mctl_node.dev_inst_map[image_mode]) {
-		idx = pcam->mctl_node.dev_inst_map[image_mode]->my_index;
-		pcam_inst = pcam->mctl_node.dev_inst[idx];
-		D("%s Found instance %p in mctl node device\n",
-			__func__, pcam_inst);
-	} else {
-		pr_err("%s Invalid image mode %d ", __func__, image_mode);
-		return -EINVAL;
-	}
-
-	if (!pcam_inst) {
-		pr_err("%s Invalid instance\n", __func__);
-		return -EINVAL;
-	}
-
-	spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
-	if (!list_empty(&pcam_inst->free_vq)) {
-		list_for_each_entry(buf, &pcam_inst->free_vq, list) {
-			if (rbuf == buf) {
-				D("%s Return buffer %x in pcam_inst %p ",
-				__func__, (int)rbuf, pcam_inst);
-				buf->state = MSM_BUFFER_STATE_QUEUED;
-				spin_unlock_irqrestore(&pcam_inst->vq_irqlock,
-					flags);
-				return 0;
-			}
-		}
-	}
-	spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
-	return -EINVAL;
-}
-
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-/* Unmap using ION APIs */
-static void __msm_mctl_unmap_user_frame(struct msm_cam_meta_frame *meta_frame,
-	struct ion_client *client, int domain_num)
-{
-	int i = 0;
-	for (i = 0; i < meta_frame->frame.num_planes; i++) {
-		D("%s Plane %d handle %p", __func__, i,
-			meta_frame->map[i].handle);
-		ion_unmap_iommu(client, meta_frame->map[i].handle,
-					domain_num, 0);
-		ion_free(client, meta_frame->map[i].handle);
-	}
-}
-
-/* Map using ION APIs */
-static int __msm_mctl_map_user_frame(struct msm_cam_meta_frame *meta_frame,
-	struct ion_client *client, int domain_num)
-{
-	unsigned long paddr = 0;
-	unsigned long len = 0;
-	int i = 0, j = 0;
-
-	for (i = 0; i < meta_frame->frame.num_planes; i++) {
-		meta_frame->map[i].handle = ion_import_dma_buf(client,
-			meta_frame->frame.mp[i].fd);
-		if (IS_ERR_OR_NULL(meta_frame->map[i].handle)) {
-			pr_err("%s: ion_import failed for plane = %d fd = %d",
-				__func__, i, meta_frame->frame.mp[i].fd);
-			/* Roll back previous plane mappings, if any */
-			for (j = i-1; j >= 0; j--) {
-				ion_unmap_iommu(client,
-					meta_frame->map[j].handle,
-					domain_num, 0);
-				ion_free(client, meta_frame->map[j].handle);
-			}
-			return -EACCES;
-		}
-		D("%s Mapping fd %d plane %d handle %p", __func__,
-			meta_frame->frame.mp[i].fd, i,
-			meta_frame->map[i].handle);
-		if (ion_map_iommu(client, meta_frame->map[i].handle,
-				domain_num, 0, SZ_4K,
-				0, &paddr, &len, 0, 0) < 0) {
-			pr_err("%s: cannot map address plane %d", __func__, i);
-			ion_free(client, meta_frame->map[i].handle);
-			/* Roll back previous plane mappings, if any */
-			for (j = i-1; j >= 0; j--) {
-				if (meta_frame->map[j].handle) {
-					ion_unmap_iommu(client,
-						meta_frame->map[j].handle,
-						domain_num, 0);
-					ion_free(client,
-						meta_frame->map[j].handle);
-				}
-			}
-			return -EFAULT;
-		}
-
-		/* Validate the offsets with the mapped length. */
-		if ((meta_frame->frame.mp[i].addr_offset > len) ||
-			(meta_frame->frame.mp[i].data_offset +
-			meta_frame->frame.mp[i].length > len)) {
-			pr_err("%s: Invalid offsets A %d D %d L %d len %ld",
-				__func__, meta_frame->frame.mp[i].addr_offset,
-				meta_frame->frame.mp[i].data_offset,
-				meta_frame->frame.mp[i].length, len);
-			/* Roll back previous plane mappings, if any */
-			for (j = i; j >= 0; j--) {
-				if (meta_frame->map[j].handle) {
-					ion_unmap_iommu(client,
-						meta_frame->map[j].handle,
-						domain_num, 0);
-					ion_free(client,
-						meta_frame->map[j].handle);
-				}
-			}
-			return -EINVAL;
-		}
-		meta_frame->map[i].data_offset =
-			meta_frame->frame.mp[i].data_offset;
-		/* Add the addr_offset to the paddr here itself. The addr_offset
-		 * will be non-zero only if the user has allocated a buffer with
-		 * a single fd, but logically partitioned it into
-		 * multiple planes or buffers.*/
-		paddr += meta_frame->frame.mp[i].addr_offset;
-		meta_frame->map[i].paddr = paddr;
-		meta_frame->map[i].len = len;
-		D("%s Plane %d fd %d handle %p paddr %x", __func__,
-			i, meta_frame->frame.mp[i].fd,
-			meta_frame->map[i].handle,
-			(uint32_t)meta_frame->map[i].paddr);
-	}
-	D("%s Frame mapped successfully ", __func__);
-	return 0;
-}
-#else
-/* Unmap using PMEM APIs */
-static int __msm_mctl_unmap_user_frame(struct msm_cam_meta_frame *meta_frame,
-	struct ion_client *client, int domain_num)
-{
-	int i = 0, rc = 0;
-
-	for (i = 0; i < meta_frame->frame.num_planes; i++) {
-		D("%s Plane %d handle %p", __func__, i,
-			meta_frame->map[i].handle);
-		put_pmem_file(meta_frame->map[i].file);
-	}
-}
-
-/* Map using PMEM APIs */
-static int __msm_mctl_map_user_frame(struct msm_cam_meta_frame *meta_frame,
-	struct ion_client *client, int domain_num)
-{
-	unsigned long kvstart = 0;
-	unsigned long paddr = 0;
-	struct file *file = NULL;
-	unsigned long len;
-	int i = 0, j = 0;
-
-	for (i = 0; i < meta_frame->frame.num_planes; i++) {
-		rc = get_pmem_file(meta_frame->frame.mp[i].fd,
-			&paddr, &kvstart, &len, &file);
-		if (rc < 0) {
-			pr_err("%s: get_pmem_file fd %d error %d\n",
-				__func__, meta_frame->frame.mp[i].fd, rc);
-			/* Roll back previous plane mappings, if any */
-			for (j = i-1; j >= 0; j--)
-				if (meta_frame->map[j].file)
-					put_pmem_file(meta_frame->map[j].file);
-
-			return -EACCES;
-		}
-		D("%s Got pmem file for fd %d plane %d as %p", __func__,
-			meta_frame->frame.mp[i].fd, i, file);
-		meta_frame->map[i].file = file;
-		/* Validate the offsets with the mapped length. */
-		if ((meta_frame->frame.mp[i].addr_offset > len) ||
-			(meta_frame->frame.mp[i].data_offset +
-			meta_frame->frame.mp[i].length > len)) {
-			pr_err("%s: Invalid offsets A %d D %d L %d len %ld",
-				__func__, meta_frame->frame.mp[i].addr_offset,
-				meta_frame->frame.mp[i].data_offset,
-				meta_frame->frame.mp[i].length, len);
-			/* Roll back previous plane mappings, if any */
-			for (j = i; j >= 0; j--)
-				if (meta_frame->map[j].file)
-					put_pmem_file(meta_frame->map[j].file);
-
-			return -EINVAL;
-		}
-		meta_frame->map[i].data_offset =
-			meta_frame->frame.mp[i].data_offset;
-		/* Add the addr_offset to the paddr here itself. The addr_offset
-		 * will be non-zero only if the user has allocated a buffer with
-		 * a single fd, but logically partitioned it into
-		 * multiple planes or buffers.*/
-		paddr += meta_frame->frame.mp[i].addr_offset;
-		meta_frame->map[i].paddr = paddr;
-		meta_frame->map[i].len = len;
-		D("%s Plane %d fd %d handle %p paddr %x", __func__,
-			i, meta_frame->frame.mp[i].fd,
-			meta_frame->map[i].handle,
-			(uint32_t)meta_frame->map[i].paddr);
-	}
-	D("%s Frame mapped successfully ", __func__);
-	return 0;
-}
-#endif
-
-int msm_mctl_map_user_frame(struct msm_cam_meta_frame *meta_frame,
-	struct ion_client *client, int domain_num)
-{
-
-	if ((NULL == meta_frame) || (NULL == client)) {
-		pr_err("%s Invalid input ", __func__);
-		return -EINVAL;
-	}
-
-	memset(&meta_frame->map[0], 0,
-		sizeof(struct msm_cam_buf_map_info) * VIDEO_MAX_PLANES);
-
-	return __msm_mctl_map_user_frame(meta_frame, client, domain_num);
-}
-
-int msm_mctl_unmap_user_frame(struct msm_cam_meta_frame *meta_frame,
-	struct ion_client *client, int domain_num)
-{
-	if ((NULL == meta_frame) || (NULL == client)) {
-		pr_err("%s Invalid input ", __func__);
-		return -EINVAL;
-	}
-	__msm_mctl_unmap_user_frame(meta_frame, client, domain_num);
-	return 0;
-}
diff --git a/drivers/media/video/msm/msm_mctl_pp.c b/drivers/media/video/msm/msm_mctl_pp.c
deleted file mode 100644
index 7155d4c..0000000
--- a/drivers/media/video/msm/msm_mctl_pp.c
+++ /dev/null
@@ -1,717 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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/workqueue.h>
-#include <linux/delay.h>
-#include <linux/types.h>
-#include <linux/list.h>
-#include <linux/ioctl.h>
-#include <linux/spinlock.h>
-#include <linux/videodev2.h>
-#include <linux/proc_fs.h>
-#include <linux/vmalloc.h>
-
-#include <media/v4l2-dev.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-device.h>
-
-#include <linux/android_pmem.h>
-
-#include "msm.h"
-#include "msm_vpe.h"
-
-#ifdef CONFIG_MSM_CAMERA_DEBUG
-#define D(fmt, args...) pr_debug("msm_mctl: " fmt, ##args)
-#else
-#define D(fmt, args...) do {} while (0)
-#endif
-
-static int msm_mctl_pp_buf_divert(
-			struct msm_cam_media_controller *pmctl,
-			struct msm_cam_v4l2_dev_inst *pcam_inst,
-			struct msm_cam_evt_divert_frame *div)
-{
-	struct v4l2_event v4l2_evt;
-	struct msm_isp_event_ctrl *isp_event;
-	isp_event = kzalloc(sizeof(struct msm_isp_event_ctrl),
-						GFP_ATOMIC);
-	if (!isp_event) {
-		pr_err("%s Insufficient memory. return", __func__);
-		return -ENOMEM;
-	}
-	D("%s: msm_cam_evt_divert_frame=%d",
-		__func__, sizeof(struct msm_cam_evt_divert_frame));
-	memset(&v4l2_evt, 0, sizeof(v4l2_evt));
-	v4l2_evt.id = 0;
-	v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
-			MSM_CAM_RESP_DIV_FRAME_EVT_MSG;
-	*((uint32_t *)v4l2_evt.u.data) = (uint32_t)isp_event;
-	/* Copy the divert frame struct into event ctrl struct. */
-	isp_event->isp_data.div_frame = *div;
-
-	D("%s inst=%p, img_mode=%d, frame_id=%d\n", __func__,
-		pcam_inst, pcam_inst->image_mode, div->frame.frame_id);
-	v4l2_event_queue(
-		pmctl->config_device->config_stat_event_queue.pvdev,
-		&v4l2_evt);
-	return 0;
-}
-
-int msm_mctl_check_pp(struct msm_cam_media_controller *p_mctl,
-	int image_mode, int *pp_divert_type, int *pp_type)
-{
-	int rc = 0;
-	unsigned long flags;
-	uint32_t pp_key = 0;
-
-	*pp_type = 0;
-	*pp_divert_type = 0;
-	spin_lock_irqsave(&p_mctl->pp_info.lock, flags);
-	switch (image_mode) {
-	case MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW:
-		pp_key = PP_PREV;
-		if (p_mctl->pp_info.pp_key & pp_key)
-			*pp_divert_type = OUTPUT_TYPE_P;
-		if (p_mctl->pp_info.pp_ctrl.pp_msg_type & OUTPUT_TYPE_P)
-			*pp_type = OUTPUT_TYPE_P;
-		break;
-	case MSM_V4L2_EXT_CAPTURE_MODE_MAIN:
-		pp_key = PP_SNAP;
-		if (p_mctl->pp_info.pp_key & pp_key)
-			*pp_divert_type = OUTPUT_TYPE_S;
-		if (p_mctl->pp_info.pp_ctrl.pp_msg_type & OUTPUT_TYPE_S)
-			*pp_type = OUTPUT_TYPE_P;
-		break;
-	case MSM_V4L2_EXT_CAPTURE_MODE_VIDEO:
-		if (p_mctl->pp_info.pp_ctrl.pp_msg_type == OUTPUT_TYPE_V)
-			*pp_type = OUTPUT_TYPE_V;
-		break;
-	case MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL:
-		pp_key = PP_THUMB;
-		if (p_mctl->pp_info.pp_key & pp_key)
-			*pp_divert_type = OUTPUT_TYPE_T;
-		if (p_mctl->pp_info.pp_ctrl.pp_msg_type == OUTPUT_TYPE_T)
-			*pp_type = OUTPUT_TYPE_T;
-		break;
-	case MSM_V4L2_EXT_CAPTURE_MODE_RDI:
-		if (p_mctl->pp_info.pp_ctrl.pp_msg_type & OUTPUT_TYPE_R)
-			*pp_type = OUTPUT_TYPE_R;
-		break;
-	default:
-		break;
-	}
-	if (p_mctl->vfe_output_mode != VFE_OUTPUTS_MAIN_AND_THUMB &&
-		p_mctl->vfe_output_mode != VFE_OUTPUTS_THUMB_AND_MAIN) {
-		if (p_mctl->pp_info.div_frame[image_mode].ch_paddr[0])
-			*pp_divert_type = 0;
-	}
-	spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
-	D("%s: pp_type=%d, pp_divert_type = %d",
-	__func__, *pp_type, *pp_divert_type);
-	return rc;
-}
-
-static int is_buf_in_queue(struct msm_cam_v4l2_device *pcam,
-	struct msm_free_buf *fbuf, int image_mode)
-{
-	struct msm_frame_buffer *buf = NULL, *tmp;
-	struct msm_cam_v4l2_dev_inst *pcam_inst = NULL;
-	unsigned long flags = 0;
-	struct videobuf2_contig_pmem *mem;
-	uint32_t buf_idx, offset = 0;
-	uint32_t buf_phyaddr = 0;
-	int idx;
-	idx = pcam->mctl_node.dev_inst_map[image_mode]->my_index;
-	pcam_inst = pcam->mctl_node.dev_inst[idx];
-	spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
-	list_for_each_entry_safe(buf, tmp,
-	&pcam_inst->free_vq, list) {
-		buf_idx = buf->vidbuf.v4l2_buf.index;
-		mem = vb2_plane_cookie(&buf->vidbuf, 0);
-		if (mem->buffer_type ==	VIDEOBUF2_MULTIPLE_PLANES)
-			offset = mem->offset.data_offset +
-				pcam_inst->buf_offset[buf_idx][0].data_offset;
-		else
-			offset = mem->offset.sp_off.y_off;
-		buf_phyaddr = (unsigned long)
-			videobuf2_to_pmem_contig(&buf->vidbuf, 0) +
-			offset;
-		D("%s vb_idx=%d,vb_paddr=0x%x ch0=0x%x\n",
-		  __func__, buf->vidbuf.v4l2_buf.index,
-		  buf_phyaddr, fbuf->ch_paddr[0]);
-		if (fbuf->ch_paddr[0] == buf_phyaddr) {
-			spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
-			return 1;
-		}
-	}
-	spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
-	return 0;
-}
-
-static struct msm_cam_v4l2_dev_inst *msm_mctl_get_pcam_inst_for_divert(
-	struct msm_cam_media_controller *pmctl,
-	struct msm_cam_buf_handle *buf_handle,
-	struct msm_free_buf *fbuf, int *node_type)
-{
-	struct msm_cam_v4l2_dev_inst *pcam_inst = NULL;
-	struct msm_cam_v4l2_device *pcam = pmctl->pcam_ptr;
-	int idx;
-	uint32_t img_mode;
-
-	if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_INST_HANDLE) {
-		idx = GET_MCTLPP_INST_IDX(buf_handle->inst_handle);
-		if (idx > MSM_DEV_INST_MAX) {
-			idx = GET_VIDEO_INST_IDX(buf_handle->inst_handle);
-			BUG_ON(idx > MSM_DEV_INST_MAX);
-			pcam_inst = pcam->dev_inst[idx];
-			*node_type = VIDEO_NODE;
-		} else {
-			pcam_inst = pcam->mctl_node.dev_inst[idx];
-			*node_type = MCTL_NODE;
-		}
-	} else if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_IMG_MODE) {
-		img_mode = buf_handle->image_mode;
-		if (img_mode >= 0 && img_mode < MSM_V4L2_EXT_CAPTURE_MODE_MAX) {
-			/* Valid image mode. Search the mctl node first.
-			 * If mctl node doesnt have the instance, then
-			 * search in the user's video node */
-			if (pcam->mctl_node.dev_inst_map[img_mode]
-				&& is_buf_in_queue(pcam, fbuf, img_mode)) {
-				idx = pcam->mctl_node.
-					dev_inst_map[img_mode]->my_index;
-				pcam_inst = pcam->mctl_node.dev_inst[idx];
-				*node_type = MCTL_NODE;
-				D("%s Found instance %p in mctl node device\n",
-					__func__, pcam_inst);
-			} else if (pcam->dev_inst_map[img_mode]) {
-				idx = pcam->dev_inst_map[img_mode]->my_index;
-				pcam_inst = pcam->dev_inst[idx];
-				*node_type = VIDEO_NODE;
-				D("%s Found instance %p in video device",
-					__func__, pcam_inst);
-			} else {
-				pr_err("%s Cannot find instance for %d.\n",
-					__func__, img_mode);
-			}
-		} else {
-			pr_err("%s Invalid image mode %d. Return NULL\n",
-				__func__, buf_handle->image_mode);
-		}
-	} else {
-		pr_err("%s Invalid buffer lookup type ", __func__);
-	}
-	return pcam_inst;
-}
-
-int msm_mctl_do_pp_divert(
-	struct msm_cam_media_controller *p_mctl,
-	struct msm_cam_buf_handle *buf_handle,
-	struct msm_free_buf *fbuf,
-	uint32_t frame_id, int pp_type)
-{
-	struct msm_cam_v4l2_dev_inst *pcam_inst;
-	int rc = 0, i, buf_idx, node;
-	int del_buf = 0; /* delete from free queue */
-	struct msm_cam_evt_divert_frame div;
-	struct msm_frame_buffer *vb = NULL;
-	struct videobuf2_contig_pmem *mem;
-	uint32_t image_mode;
-
-	if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_IMG_MODE) {
-		image_mode = buf_handle->image_mode;
-		div.frame.inst_handle = 0;
-	} else if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_INST_HANDLE) {
-		image_mode = GET_IMG_MODE(buf_handle->inst_handle);
-		div.frame.inst_handle = buf_handle->inst_handle;
-	} else {
-		pr_err("%s Invalid buffer lookup type %d ", __func__,
-			buf_handle->buf_lookup_type);
-		return -EINVAL;
-	}
-
-	pcam_inst = msm_mctl_get_pcam_inst_for_divert(p_mctl,
-			buf_handle, fbuf, &node);
-	if (!pcam_inst) {
-		pr_err("%s Invalid instance. Cannot divert frame.\n",
-			__func__);
-		return -EINVAL;
-	}
-	vb = msm_mctl_buf_find(p_mctl, pcam_inst, del_buf, fbuf);
-	if (!vb)
-		return -EINVAL;
-
-	vb->vidbuf.v4l2_buf.sequence = frame_id;
-	buf_idx = vb->vidbuf.v4l2_buf.index;
-	D("%s Diverting frame %d %x Image mode %d\n", __func__, buf_idx,
-		(uint32_t)vb, pcam_inst->image_mode);
-	div.image_mode = pcam_inst->image_mode;
-	div.op_mode    = pcam_inst->pcam->op_mode;
-	div.inst_idx   = pcam_inst->my_index;
-	div.node_idx   = pcam_inst->pcam->vnode_id;
-	p_mctl->pp_info.cur_frame_id[pcam_inst->image_mode] = frame_id;
-	div.frame.frame_id =
-		p_mctl->pp_info.cur_frame_id[pcam_inst->image_mode];
-	div.frame.buf_idx  = buf_idx;
-	div.frame.handle = (uint32_t)vb;
-	msm_mctl_gettimeofday(&div.frame.timestamp);
-	vb->vidbuf.v4l2_buf.timestamp = div.frame.timestamp;
-	div.do_pp = pp_type;
-	D("%s Diverting frame %x id %d to userspace ", __func__,
-		(int)div.frame.handle, div.frame.frame_id);
-	/* Get the cookie for 1st plane and store the path.
-	 * Also use this to check the number of planes in
-	 * this buffer.*/
-	mem = vb2_plane_cookie(&vb->vidbuf, 0);
-	div.frame.path = mem->path;
-	div.frame.node_type = node;
-	if (mem->buffer_type == VIDEOBUF2_SINGLE_PLANE) {
-		/* This buffer contains only 1 plane. Use the
-		 * single planar structure to store the info.*/
-		div.frame.num_planes	= 1;
-		div.frame.sp.phy_addr	=
-			videobuf2_to_pmem_contig(&vb->vidbuf, 0);
-		div.frame.sp.addr_offset = mem->addr_offset;
-		div.frame.sp.y_off      = 0;
-		div.frame.sp.cbcr_off   = mem->offset.sp_off.cbcr_off;
-		div.frame.sp.fd         = (int)mem->vaddr;
-		div.frame.sp.length     = mem->size;
-		if (!pp_type)
-			p_mctl->pp_info.div_frame[pcam_inst->image_mode].
-			ch_paddr[0] = div.frame.sp.phy_addr;
-	} else {
-		/* This buffer contains multiple planes. Use the mutliplanar
-		 * structure to store the info. */
-		div.frame.num_planes	= pcam_inst->plane_info.num_planes;
-		/* Now traverse through all the planes of the buffer to
-		 * fill out the plane info. */
-		for (i = 0; i < div.frame.num_planes; i++) {
-			mem = vb2_plane_cookie(&vb->vidbuf, i);
-			div.frame.mp[i].phy_addr =
-				videobuf2_to_pmem_contig(&vb->vidbuf, i);
-			if (!pcam_inst->buf_offset)
-				div.frame.mp[i].data_offset = 0;
-			else
-				div.frame.mp[i].data_offset =
-				pcam_inst->buf_offset[buf_idx][i].data_offset;
-			div.frame.mp[i].addr_offset =
-				mem->addr_offset;
-			div.frame.mp[i].fd = (int)mem->vaddr;
-			div.frame.mp[i].length = mem->size;
-		}
-		if (!pp_type)
-			p_mctl->pp_info.div_frame[pcam_inst->image_mode].
-			ch_paddr[0] = div.frame.mp[0].phy_addr +
-					div.frame.mp[0].data_offset;
-	}
-	rc = msm_mctl_pp_buf_divert(p_mctl, pcam_inst, &div);
-	return rc;
-}
-
-static int msm_mctl_pp_get_phy_addr(
-	struct msm_cam_v4l2_dev_inst *pcam_inst,
-	uint32_t frame_handle,
-	struct msm_pp_frame *pp_frame)
-{
-	struct msm_frame_buffer *vb = NULL;
-	struct videobuf2_contig_pmem *mem;
-	int i, buf_idx = 0;
-
-	vb = (struct msm_frame_buffer *)frame_handle;
-	buf_idx = vb->vidbuf.v4l2_buf.index;
-	memset(pp_frame, 0, sizeof(struct msm_pp_frame));
-	pp_frame->handle = (uint32_t)vb;
-	pp_frame->frame_id = vb->vidbuf.v4l2_buf.sequence;
-	pp_frame->timestamp = vb->vidbuf.v4l2_buf.timestamp;
-	pp_frame->buf_idx = buf_idx;
-	pp_frame->inst_handle = pcam_inst->inst_handle;
-	/* Get the cookie for 1st plane and store the path.
-	 * Also use this to check the number of planes in
-	 * this buffer.*/
-	mem = vb2_plane_cookie(&vb->vidbuf, 0);
-	pp_frame->image_type = (unsigned short)mem->path;
-	if (mem->buffer_type == VIDEOBUF2_SINGLE_PLANE) {
-		pp_frame->num_planes = 1;
-		pp_frame->sp.addr_offset = mem->addr_offset;
-		pp_frame->sp.phy_addr =
-			videobuf2_to_pmem_contig(&vb->vidbuf, 0);
-		pp_frame->sp.y_off = 0;
-		pp_frame->sp.cbcr_off = mem->offset.sp_off.cbcr_off;
-		pp_frame->sp.length = mem->size;
-		pp_frame->sp.fd = (int)mem->vaddr;
-	} else {
-		pp_frame->num_planes = pcam_inst->plane_info.num_planes;
-		for (i = 0; i < pp_frame->num_planes; i++) {
-			mem = vb2_plane_cookie(&vb->vidbuf, i);
-			pp_frame->mp[i].addr_offset = mem->addr_offset;
-			pp_frame->mp[i].phy_addr =
-				videobuf2_to_pmem_contig(&vb->vidbuf, i);
-			pp_frame->mp[i].data_offset =
-			pcam_inst->buf_offset[buf_idx][i].data_offset;
-			pp_frame->mp[i].fd = (int)mem->vaddr;
-			pp_frame->mp[i].length = mem->size;
-			D("%s frame id %d buffer %d plane %d phy addr 0x%x"
-				" fd %d length %d\n", __func__,
-				pp_frame->frame_id, buf_idx, i,
-				(uint32_t)pp_frame->mp[i].phy_addr,
-				pp_frame->mp[i].fd, pp_frame->mp[i].length);
-		}
-	}
-	return 0;
-}
-
-static int msm_mctl_pp_path_to_img_mode(int path)
-{
-	switch (path) {
-	case OUTPUT_TYPE_P:
-		return MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW;
-	case OUTPUT_TYPE_V:
-		return MSM_V4L2_EXT_CAPTURE_MODE_VIDEO;
-	case OUTPUT_TYPE_S:
-		return MSM_V4L2_EXT_CAPTURE_MODE_MAIN;
-	case OUTPUT_TYPE_T:
-		return MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL;
-	case OUTPUT_TYPE_SAEC:
-		return MSM_V4L2_EXT_CAPTURE_MODE_AEC;
-	case OUTPUT_TYPE_SAWB:
-		return MSM_V4L2_EXT_CAPTURE_MODE_AWB;
-	case OUTPUT_TYPE_SAFC:
-		return MSM_V4L2_EXT_CAPTURE_MODE_AF;
-	case OUTPUT_TYPE_IHST:
-		return MSM_V4L2_EXT_CAPTURE_MODE_IHIST;
-	case OUTPUT_TYPE_CSTA:
-		return MSM_V4L2_EXT_CAPTURE_MODE_CSTA;
-	default:
-		return -EINVAL;
-	}
-}
-
-int msm_mctl_pp_proc_cmd(struct msm_cam_media_controller *p_mctl,
-			struct msm_mctl_pp_cmd *pp_cmd)
-{
-	int rc = 0;
-	unsigned long flags;
-
-	switch (pp_cmd->id) {
-	case MCTL_CMD_DIVERT_FRAME_PP_PATH: {
-		struct msm_mctl_pp_divert_pp divert_pp;
-		if (copy_from_user(&divert_pp, pp_cmd->value,
-				sizeof(divert_pp))) {
-			ERR_COPY_FROM_USER();
-			return -EFAULT;
-		}
-		D("%s: Divert Image mode =%d Enable %d",
-			__func__, divert_pp.path, divert_pp.enable);
-		spin_lock_irqsave(&p_mctl->pp_info.lock, flags);
-		if (divert_pp.enable)
-			p_mctl->pp_info.pp_ctrl.pp_msg_type |= divert_pp.path;
-		else
-			p_mctl->pp_info.pp_ctrl.pp_msg_type &= ~divert_pp.path;
-		spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
-		D("%s: pp path = 0x%x", __func__,
-			p_mctl->pp_info.pp_ctrl.pp_msg_type);
-		break;
-	}
-	default:
-		rc = -EPERM;
-	break;
-	}
-	return rc;
-}
-
-
-int msm_mctl_pp_ioctl(struct msm_cam_media_controller *p_mctl,
-			unsigned int cmd, unsigned long arg)
-{
-	int rc = -EINVAL;
-	struct msm_mctl_post_proc_cmd pp_cmd;
-	void __user *argp = (void __user *)arg;
-
-	if (copy_from_user(&pp_cmd, argp, sizeof(pp_cmd)))
-		return -EFAULT;
-
-	switch (pp_cmd.type) {
-	case MSM_PP_CMD_TYPE_MCTL:
-		rc = msm_mctl_pp_proc_cmd(p_mctl, &pp_cmd.cmd);
-		break;
-	default:
-		rc = -EPERM;
-		break;
-	}
-	if (!rc) {
-		/* deep copy back the return value */
-		if (copy_to_user((void *)arg,
-			&pp_cmd,
-			sizeof(struct msm_mctl_post_proc_cmd))) {
-			ERR_COPY_TO_USER();
-			rc = -EFAULT;
-		}
-	}
-	return rc;
-}
-
-int msm_mctl_pp_reserve_free_frame(
-	struct msm_cam_media_controller *p_mctl,
-	void __user *arg)
-{
-	struct msm_cam_evt_divert_frame div_frame;
-	int image_mode, rc = 0;
-	struct msm_free_buf free_buf;
-	struct msm_cam_v4l2_dev_inst *pcam_inst;
-	struct msm_cam_buf_handle buf_handle;
-
-	memset(&free_buf, 0, sizeof(struct msm_free_buf));
-	if (copy_from_user(&div_frame, arg,
-		sizeof(struct msm_cam_evt_divert_frame))) {
-		ERR_COPY_FROM_USER();
-		return -EFAULT;
-	}
-
-	image_mode = div_frame.image_mode;
-	if (image_mode <= 0) {
-		pr_err("%s Invalid image mode %d", __func__, image_mode);
-		return -EINVAL;
-	}
-	/* Always reserve the buffer from user's video node */
-	pcam_inst = p_mctl->pcam_ptr->dev_inst_map[image_mode];
-	if (!pcam_inst) {
-		pr_err("%s Instance already closed ", __func__);
-		return -EINVAL;
-	}
-	D("%s Reserving free frame using %p inst handle %x ", __func__,
-		pcam_inst, div_frame.frame.inst_handle);
-	if (div_frame.frame.inst_handle) {
-		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_INST_HANDLE;
-		buf_handle.inst_handle = div_frame.frame.inst_handle;
-	} else {
-		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_IMG_MODE;
-		buf_handle.image_mode = image_mode;
-	}
-	rc = msm_mctl_reserve_free_buf(p_mctl, pcam_inst,
-					&buf_handle, &free_buf);
-	if (rc == 0) {
-		msm_mctl_pp_get_phy_addr(pcam_inst,
-			free_buf.vb, &div_frame.frame);
-		if (copy_to_user((void *)arg, &div_frame, sizeof(div_frame))) {
-			ERR_COPY_TO_USER();
-			rc = -EFAULT;
-		}
-	}
-	D("%s: Got buffer %d from Inst %p rc = %d, phy = 0x%x",
-		__func__, div_frame.frame.buf_idx,
-		pcam_inst, rc, free_buf.ch_paddr[0]);
-	return rc;
-}
-
-int msm_mctl_pp_release_free_frame(
-	struct msm_cam_media_controller *p_mctl,
-	void __user *arg)
-{
-	struct msm_cam_evt_divert_frame div_frame;
-	struct msm_cam_v4l2_dev_inst *pcam_inst;
-	struct msm_pp_frame *frame;
-	int image_mode, rc = 0;
-	struct msm_free_buf free_buf;
-	struct msm_cam_buf_handle buf_handle;
-
-	if (copy_from_user(&div_frame, arg,
-		sizeof(struct msm_cam_evt_divert_frame))) {
-		ERR_COPY_FROM_USER();
-		return -EFAULT;
-	}
-
-	image_mode = div_frame.image_mode;
-	if (image_mode < 0) {
-		pr_err("%s Invalid image mode %d\n", __func__, image_mode);
-		return -EINVAL;
-	}
-	frame = &div_frame.frame;
-	if (frame->num_planes > 1)
-		free_buf.ch_paddr[0] = frame->mp[0].phy_addr;
-	else
-		free_buf.ch_paddr[0] = frame->sp.phy_addr;
-
-	if (div_frame.frame.inst_handle) {
-		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_INST_HANDLE;
-		buf_handle.inst_handle = div_frame.frame.inst_handle;
-	} else {
-		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_IMG_MODE;
-		buf_handle.image_mode = image_mode;
-	}
-	pcam_inst = msm_mctl_get_pcam_inst(p_mctl, &buf_handle);
-	if (!pcam_inst) {
-		pr_err("%s Invalid instance. Cannot release frame.\n",
-			__func__);
-		return -EINVAL;
-	}
-
-	rc = msm_mctl_release_free_buf(p_mctl, pcam_inst, &free_buf);
-	D("%s: release free buf, rc = %d, phy = 0x%x",
-		__func__, rc, free_buf.ch_paddr[0]);
-
-	return rc;
-}
-
-int msm_mctl_set_pp_key(struct msm_cam_media_controller *p_mctl,
-				void __user *arg)
-{
-	int rc = 0;
-	unsigned long flags;
-	spin_lock_irqsave(&p_mctl->pp_info.lock, flags);
-	if (copy_from_user(&p_mctl->pp_info.pp_key,
-			arg, sizeof(p_mctl->pp_info.pp_key))) {
-		ERR_COPY_FROM_USER();
-		rc = -EFAULT;
-	} else {
-		D("%s: mctl=0x%p, pp_key_setting=0x%x",
-			__func__, p_mctl, p_mctl->pp_info.pp_key);
-	}
-	spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
-	return rc;
-}
-
-int msm_mctl_pp_done(
-	struct msm_cam_media_controller *p_mctl,
-	void __user *arg)
-{
-	struct msm_pp_frame frame;
-	int image_mode, rc = 0;
-	int dirty = 0;
-	struct msm_free_buf buf;
-	unsigned long flags;
-	struct msm_cam_buf_handle buf_handle;
-	struct msm_cam_return_frame_info ret_frame;
-
-	if (copy_from_user(&frame, arg, sizeof(frame))) {
-		ERR_COPY_FROM_USER();
-		return -EFAULT;
-	}
-
-	spin_lock_irqsave(&p_mctl->pp_info.lock, flags);
-	if (frame.inst_handle) {
-		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_INST_HANDLE;
-		buf_handle.inst_handle = frame.inst_handle;
-		image_mode = GET_IMG_MODE(frame.inst_handle);
-	} else {
-		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_IMG_MODE;
-		buf_handle.image_mode =
-			msm_mctl_pp_path_to_img_mode(frame.path);
-		image_mode = buf_handle.image_mode;
-	}
-	if (image_mode < 0) {
-		pr_err("%s Invalid image mode\n", __func__);
-		return image_mode;
-	}
-	D("%s Returning frame %x id %d to kernel ", __func__,
-		(int)frame.handle, frame.frame_id);
-	if (p_mctl->pp_info.div_frame[image_mode].ch_paddr[0]) {
-		memcpy(&buf,
-			&p_mctl->pp_info.div_frame[image_mode],
-			sizeof(buf));
-		memset(&p_mctl->pp_info.div_frame[image_mode],
-			0, sizeof(buf));
-		if (p_mctl->pp_info.cur_frame_id[image_mode] !=
-					frame.frame_id) {
-			/* dirty frame. should not pass to app */
-			dirty = 1;
-		}
-	} else {
-		if (frame.num_planes > 1)
-			buf.ch_paddr[0] = frame.mp[0].phy_addr +
-						frame.mp[0].data_offset;
-		else
-			buf.ch_paddr[0] = frame.sp.phy_addr + frame.sp.y_off;
-	}
-	spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
-
-	ret_frame.dirty = dirty;
-	ret_frame.node_type = 0;
-	ret_frame.timestamp = frame.timestamp;
-	ret_frame.frame_id   = frame.frame_id;
-	D("%s frame_id: %d buffer idx %d\n", __func__,
-		frame.frame_id, frame.buf_idx);
-	rc = msm_mctl_buf_done_pp(p_mctl, &buf_handle, &buf, &ret_frame);
-	return rc;
-}
-
-int msm_mctl_pp_divert_done(
-	struct msm_cam_media_controller *p_mctl,
-	void __user *arg)
-{
-	struct msm_pp_frame frame;
-	int rc = 0;
-	struct msm_free_buf buf;
-	unsigned long flags;
-	struct msm_cam_buf_handle buf_handle;
-	struct msm_cam_return_frame_info ret_frame;
-
-	D("%s enter\n", __func__);
-
-	if (copy_from_user(&frame, arg, sizeof(frame))) {
-		ERR_COPY_FROM_USER();
-		return -EFAULT;
-	}
-
-	spin_lock_irqsave(&p_mctl->pp_info.lock, flags);
-	if (frame.inst_handle) {
-		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_INST_HANDLE;
-		buf_handle.inst_handle = frame.inst_handle;
-	} else {
-		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_IMG_MODE;
-		buf_handle.image_mode = frame.image_type;
-	}
-
-	if (frame.num_planes > 1)
-		buf.ch_paddr[0] = frame.mp[0].phy_addr +
-					frame.mp[0].data_offset;
-	else
-		buf.ch_paddr[0] = frame.sp.phy_addr + frame.sp.y_off;
-
-	spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
-
-	ret_frame.dirty = 0;
-	ret_frame.node_type = frame.node_type;
-	ret_frame.timestamp = frame.timestamp;
-	ret_frame.frame_id  = frame.frame_id;
-	D("%s Frame done id: %d\n", __func__, frame.frame_id);
-	rc = msm_mctl_buf_done_pp(p_mctl, &buf_handle, &buf, &ret_frame);
-	return rc;
-}
-
-int msm_mctl_pp_mctl_divert_done(
-	struct msm_cam_media_controller *p_mctl,
-	void __user *arg)
-{
-	struct msm_cam_evt_divert_frame div_frame;
-	struct msm_frame_buffer *buf;
-	int image_mode, rc = 0;
-
-	if (copy_from_user(&div_frame, arg,
-			sizeof(struct msm_cam_evt_divert_frame))) {
-		pr_err("%s copy from user failed ", __func__);
-		return -EFAULT;
-	}
-
-	if (!div_frame.frame.handle) {
-		pr_err("%s Invalid buffer handle ", __func__);
-		return -EINVAL;
-	}
-	image_mode = div_frame.image_mode;
-	buf = (struct msm_frame_buffer *)div_frame.frame.handle;
-	D("%s Returning buffer %x Image mode %d ", __func__,
-		(int)buf, image_mode);
-	rc = msm_mctl_buf_return_buf(p_mctl, image_mode, buf);
-	if (rc < 0)
-		pr_err("%s Error returning mctl buffer ", __func__);
-
-	return rc;
-}
diff --git a/drivers/media/video/msm/msm_mem.c b/drivers/media/video/msm/msm_mem.c
deleted file mode 100644
index e131193..0000000
--- a/drivers/media/video/msm/msm_mem.c
+++ /dev/null
@@ -1,427 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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/workqueue.h>
-#include <linux/delay.h>
-#include <linux/types.h>
-#include <linux/list.h>
-#include <linux/ioctl.h>
-#include <linux/spinlock.h>
-#include <linux/videodev2.h>
-#include <linux/proc_fs.h>
-#include <linux/vmalloc.h>
-
-#include <media/v4l2-dev.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-device.h>
-
-#include <linux/android_pmem.h>
-
-#include "msm.h"
-
-#ifdef CONFIG_MSM_CAMERA_DEBUG
-#define D(fmt, args...) pr_debug("msm_isp: " fmt, ##args)
-#else
-#define D(fmt, args...) do {} while (0)
-#endif
-
-#define PAD_TO_WORD(a)	  (((a) + 3) & ~3)
-
-#define __CONTAINS(r, v, l, field) ({			   \
-	typeof(r) __r = r;				  \
-	typeof(v) __v = v;				  \
-	typeof(v) __e = __v + l;				\
-	int res = __v >= __r->field &&			  \
-		__e <= __r->field + __r->len;		   \
-	res;							\
-})
-
-#define CONTAINS(r1, r2, field) ({			  \
-	typeof(r2) __r2 = r2;				   \
-	__CONTAINS(r1, __r2->field, __r2->len, field);	  \
-})
-
-#define IN_RANGE(r, v, field) ({				\
-	typeof(r) __r = r;				  \
-	typeof(v) __vv = v;				 \
-	int res = ((__vv >= __r->field) &&		  \
-		(__vv < (__r->field + __r->len)));	  \
-	res;							\
-})
-
-#define OVERLAPS(r1, r2, field) ({			  \
-	typeof(r1) __r1 = r1;				   \
-	typeof(r2) __r2 = r2;				   \
-	typeof(__r2->field) __v = __r2->field;		  \
-	typeof(__v) __e = __v + __r2->len - 1;		  \
-	int res = (IN_RANGE(__r1, __v, field) ||		\
-		IN_RANGE(__r1, __e, field));				 \
-	res;							\
-})
-
-static DEFINE_MUTEX(hlist_mut);
-
-#ifdef CONFIG_ANDROID_PMEM
-static int check_pmem_info(struct msm_pmem_info *info, int len)
-{
-	if (info->offset < len &&
-		info->offset + info->len <= len &&
-		info->planar0_off < len &&
-		info->planar1_off < len)
-		return 0;
-
-	pr_err("%s: check failed: off %d len %d y %d cbcr %d (total len %d)\n",
-						__func__,
-						info->offset,
-						info->len,
-						info->planar0_off,
-						info->planar1_off,
-						len);
-	return -EINVAL;
-}
-#endif
-
-static int check_overlap(struct hlist_head *ptype,
-				unsigned long paddr,
-				unsigned long len)
-{
-	struct msm_pmem_region *region;
-	struct msm_pmem_region t = { .paddr = paddr, .len = len };
-	struct hlist_node *node;
-
-	hlist_for_each_entry(region, node, ptype, list) {
-		if (CONTAINS(region, &t, paddr) ||
-			CONTAINS(&t, region, paddr) ||
-			OVERLAPS(region, &t, paddr)) {
-			CDBG(" region (PHYS %p len %ld)"
-				" clashes with registered region"
-				" (paddr %p len %ld)\n",
-				(void *)t.paddr, t.len,
-				(void *)region->paddr, region->len);
-			return -EINVAL;
-		}
-	}
-
-	return 0;
-}
-
-static int msm_pmem_table_add(struct hlist_head *ptype,
-	struct msm_pmem_info *info, struct ion_client *client, int domain_num)
-{
-	unsigned long paddr;
-#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
-	unsigned long kvstart;
-	struct file *file;
-#endif
-	int rc = -ENOMEM;
-
-	unsigned long len;
-	struct msm_pmem_region *region;
-
-	region = kmalloc(sizeof(struct msm_pmem_region), GFP_KERNEL);
-	if (!region)
-		goto out;
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	region->handle = ion_import_dma_buf(client, info->fd);
-	if (IS_ERR_OR_NULL(region->handle))
-		goto out1;
-	if (ion_map_iommu(client, region->handle, domain_num, 0,
-				  SZ_4K, 0, &paddr, &len, 0, 0) < 0)
-		goto out2;
-#elif CONFIG_ANDROID_PMEM
-	rc = get_pmem_file(info->fd, &paddr, &kvstart, &len, &file);
-	if (rc < 0) {
-		pr_err("%s: get_pmem_file fd %d error %d\n",
-				__func__, info->fd, rc);
-		goto out1;
-	}
-	region->file = file;
-#else
-	paddr = 0;
-	file = NULL;
-	kvstart = 0;
-#endif
-	if (!info->len)
-		info->len = len;
-	rc = check_pmem_info(info, len);
-	if (rc < 0)
-		goto out3;
-	paddr += info->offset;
-	len = info->len;
-
-	if (check_overlap(ptype, paddr, len) < 0) {
-		rc = -EINVAL;
-		goto out3;
-	}
-
-	CDBG("%s: type %d, active flag %d, paddr 0x%lx, vaddr 0x%lx\n",
-		__func__, info->type, info->active, paddr,
-		(unsigned long)info->vaddr);
-
-	INIT_HLIST_NODE(&region->list);
-	region->paddr = paddr;
-	region->len = len;
-	memcpy(&region->info, info, sizeof(region->info));
-	D("%s Adding region to list with type %d\n", __func__,
-						region->info.type);
-	D("%s pmem_stats address is 0x%p\n", __func__, ptype);
-	hlist_add_head(&(region->list), ptype);
-
-	return 0;
-out3:
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	ion_unmap_iommu(client, region->handle, domain_num, 0);
-#endif
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-out2:
-	ion_free(client, region->handle);
-#elif CONFIG_ANDROID_PMEM
-	put_pmem_file(region->file);
-#endif
-out1:
-	kfree(region);
-out:
-	return rc;
-}
-
-static int __msm_register_pmem(struct hlist_head *ptype,
-			struct msm_pmem_info *pinfo, struct ion_client *client,
-			int domain_num)
-{
-	int rc = 0;
-
-	switch (pinfo->type) {
-	case MSM_PMEM_AF:
-	case MSM_PMEM_AEC:
-	case MSM_PMEM_AWB:
-	case MSM_PMEM_RS:
-	case MSM_PMEM_CS:
-	case MSM_PMEM_IHIST:
-	case MSM_PMEM_SKIN:
-	case MSM_PMEM_AEC_AWB:
-	case MSM_PMEM_BAYER_GRID:
-	case MSM_PMEM_BAYER_EXPOSURE:
-	case MSM_PMEM_BAYER_FOCUS:
-	case MSM_PMEM_BAYER_HIST:
-		rc = msm_pmem_table_add(ptype, pinfo, client, domain_num);
-		break;
-
-	default:
-		rc = -EINVAL;
-		break;
-	}
-
-	return rc;
-}
-
-static int __msm_pmem_table_del(struct hlist_head *ptype,
-			struct msm_pmem_info *pinfo, struct ion_client *client,
-			int domain_num)
-{
-	int rc = 0;
-	struct msm_pmem_region *region;
-	struct hlist_node *node, *n;
-
-	switch (pinfo->type) {
-	case MSM_PMEM_AF:
-	case MSM_PMEM_AEC:
-	case MSM_PMEM_AWB:
-	case MSM_PMEM_RS:
-	case MSM_PMEM_CS:
-	case MSM_PMEM_IHIST:
-	case MSM_PMEM_SKIN:
-	case MSM_PMEM_AEC_AWB:
-	case MSM_PMEM_BAYER_GRID:
-	case MSM_PMEM_BAYER_EXPOSURE:
-	case MSM_PMEM_BAYER_FOCUS:
-	case MSM_PMEM_BAYER_HIST:
-		hlist_for_each_entry_safe(region, node, n,
-				ptype, list) {
-
-			if (pinfo->type == region->info.type &&
-				pinfo->vaddr == region->info.vaddr &&
-				pinfo->fd == region->info.fd) {
-				hlist_del(node);
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-				ion_unmap_iommu(client, region->handle,
-					domain_num, 0);
-				ion_free(client, region->handle);
-#else
-				put_pmem_file(region->file);
-#endif
-				kfree(region);
-			}
-		}
-		break;
-
-	default:
-		rc = -EINVAL;
-		break;
-	}
-
-	return rc;
-}
-
-/* return of 0 means failure */
-uint8_t msm_pmem_region_lookup(struct hlist_head *ptype,
-	int pmem_type, struct msm_pmem_region *reg, uint8_t maxcount)
-{
-	struct msm_pmem_region *region;
-	struct msm_pmem_region *regptr;
-	struct hlist_node *node, *n;
-
-	uint8_t rc = 0;
-	D("%s\n", __func__);
-	regptr = reg;
-	mutex_lock(&hlist_mut);
-	hlist_for_each_entry_safe(region, node, n, ptype, list) {
-		if (region->info.type == pmem_type && region->info.active) {
-			*regptr = *region;
-			rc += 1;
-			if (rc >= maxcount)
-				break;
-			regptr++;
-		}
-	}
-	D("%s finished, rc=%d\n", __func__, rc);
-	mutex_unlock(&hlist_mut);
-	return rc;
-}
-
-int msm_pmem_region_get_phy_addr(struct hlist_head *ptype,
-	struct msm_mem_map_info *mem_map, int32_t *phyaddr)
-{
-	struct msm_pmem_region *region;
-	struct hlist_node *node, *n;
-	int pmem_type = mem_map->mem_type;
-	int rc = -EFAULT;
-
-	D("%s\n", __func__);
-	*phyaddr = 0;
-	mutex_lock(&hlist_mut);
-	hlist_for_each_entry_safe(region, node, n, ptype, list) {
-		if (region->info.type == pmem_type &&
-			(uint32_t)region->info.vaddr == mem_map->cookie) {
-			*phyaddr = (int32_t)region->paddr;
-			rc = 0;
-			break;
-		}
-	}
-	D("%s finished, phy_addr = 0x%x, rc=%d\n", __func__, *phyaddr, rc);
-	mutex_unlock(&hlist_mut);
-	return rc;
-}
-
-uint8_t msm_pmem_region_lookup_2(struct hlist_head *ptype,
-					int pmem_type,
-					struct msm_pmem_region *reg,
-					uint8_t maxcount)
-{
-	struct msm_pmem_region *region;
-	struct msm_pmem_region *regptr;
-	struct hlist_node *node, *n;
-	uint8_t rc = 0;
-	regptr = reg;
-	mutex_lock(&hlist_mut);
-	hlist_for_each_entry_safe(region, node, n, ptype, list) {
-		D("Mio: info.type=%d, pmem_type = %d,"
-						"info.active = %d\n",
-		region->info.type, pmem_type, region->info.active);
-
-		if (region->info.type == pmem_type && region->info.active) {
-			D("info.type=%d, pmem_type = %d,"
-							"info.active = %d,\n",
-				region->info.type, pmem_type,
-				region->info.active);
-			*regptr = *region;
-			region->info.type = MSM_PMEM_VIDEO;
-			rc += 1;
-			if (rc >= maxcount)
-				break;
-			regptr++;
-		}
-	}
-	mutex_unlock(&hlist_mut);
-	return rc;
-}
-
-unsigned long msm_pmem_stats_vtop_lookup(
-				struct msm_cam_media_controller *mctl,
-				unsigned long buffer,
-				int fd)
-{
-	struct msm_pmem_region *region;
-	struct hlist_node *node, *n;
-
-	hlist_for_each_entry_safe(region, node, n,
-	&mctl->stats_info.pmem_stats_list, list) {
-		if (((unsigned long)(region->info.vaddr) == buffer) &&
-						(region->info.fd == fd) &&
-						region->info.active == 0) {
-			region->info.active = 1;
-			return region->paddr;
-		}
-	}
-
-	return 0;
-}
-
-unsigned long msm_pmem_stats_ptov_lookup(
-		struct msm_cam_media_controller *mctl,
-		unsigned long addr, int *fd)
-{
-	struct msm_pmem_region *region;
-	struct hlist_node *node, *n;
-
-	hlist_for_each_entry_safe(region, node, n,
-	&mctl->stats_info.pmem_stats_list, list) {
-		if (addr == region->paddr && region->info.active) {
-			/* offset since we could pass vaddr inside a
-			 * registered pmem buffer */
-			*fd = region->info.fd;
-			region->info.active = 0;
-			return (unsigned long)(region->info.vaddr);
-		}
-	}
-
-	return 0;
-}
-
-int msm_register_pmem(struct hlist_head *ptype, void __user *arg,
-					struct ion_client *client,
-					int domain_num)
-{
-	struct msm_pmem_info info;
-
-	if (copy_from_user(&info, arg, sizeof(info))) {
-		ERR_COPY_FROM_USER();
-			return -EFAULT;
-	}
-
-	return __msm_register_pmem(ptype, &info, client, domain_num);
-}
-//EXPORT_SYMBOL(msm_register_pmem);
-
-int msm_pmem_table_del(struct hlist_head *ptype, void __user *arg,
-			struct ion_client *client, int domain_num)
-{
-	struct msm_pmem_info info;
-
-	if (copy_from_user(&info, arg, sizeof(info))) {
-		ERR_COPY_FROM_USER();
-		return -EFAULT;
-	}
-
-	return __msm_pmem_table_del(ptype, &info, client, domain_num);
-}
-//EXPORT_SYMBOL(msm_pmem_table_del);
diff --git a/drivers/media/video/msm/msm_v4l2_video.c b/drivers/media/video/msm/msm_v4l2_video.c
deleted file mode 100644
index c4e6c62..0000000
--- a/drivers/media/video/msm/msm_v4l2_video.c
+++ /dev/null
@@ -1,947 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/fb.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/time.h>
-#include <linux/videodev2.h>
-#include <linux/platform_device.h>
-#include <linux/file.h>
-#include <linux/fs.h>
-#include <linux/msm_mdp.h>
-#include <linux/sched.h>
-#include <linux/capability.h>
-
-#include <media/v4l2-ioctl.h>
-#include <media/videobuf-dma-sg.h>
-#include <media/v4l2-dev.h>
-#include <media/msm_v4l2_overlay.h>
-
-#include <mach/board.h>
-#include <mach/msm_fb.h>
-
-#include "msm_v4l2_video.h"
-
-#define MSM_VIDEO -1
-
-static struct msm_v4l2_overlay_device	*saved_vout0;
-
-static struct mutex msmfb_lock;
-static char *v4l2_ram_phys;
-static unsigned int v4l2_ram_size;
-
-static int msm_v4l2_overlay_mapformat(uint32_t pixelformat);
-
-static int msm_v4l2_overlay_startstreaming(struct msm_v4l2_overlay_device *vout)
-{
-	vout->req.src.width = vout->pix.width;
-	vout->req.src.height = vout->pix.height;
-
-	vout->req.src_rect.x = vout->crop_rect.left;
-	vout->req.src_rect.y = vout->crop_rect.top;
-	vout->req.src_rect.w = vout->crop_rect.width;
-	vout->req.src_rect.h = vout->crop_rect.height;
-
-	vout->req.src.format =
-		msm_v4l2_overlay_mapformat(vout->pix.pixelformat);
-
-	vout->req.dst_rect.x = vout->win.w.left;
-	vout->req.dst_rect.y = vout->win.w.top;
-	vout->req.dst_rect.w = vout->win.w.width;
-	vout->req.dst_rect.h = vout->win.w.height;
-
-	vout->req.alpha = MDP_ALPHA_NOP;
-	vout->req.transp_mask = MDP_TRANSP_NOP;
-
-	pr_debug("msm_v4l2_overlay:startstreaming:enabling fb\n");
-	mutex_lock(&msmfb_lock);
-	msm_fb_v4l2_enable(&vout->req, true, &vout->par);
-	mutex_unlock(&msmfb_lock);
-
-	vout->streaming = 1;
-
-	return 0;
-}
-
-static int msm_v4l2_overlay_stopstreaming(struct msm_v4l2_overlay_device *vout)
-{
-	if (!vout->streaming)
-		return 0;
-
-	pr_debug("msm_v4l2_overlay:startstreaming:disabling fb\n");
-	mutex_lock(&msmfb_lock);
-	msm_fb_v4l2_enable(&vout->req, false, &vout->par);
-	mutex_unlock(&msmfb_lock);
-
-	vout->streaming = 0;
-
-	return 0;
-}
-
-static int msm_v4l2_overlay_mapformat(uint32_t pixelformat)
-{
-	int mdp_format;
-
-	switch (pixelformat) {
-	case V4L2_PIX_FMT_RGB565:
-		mdp_format = MDP_RGB_565;
-		break;
-	case V4L2_PIX_FMT_RGB32:
-		mdp_format = MDP_ARGB_8888;
-		break;
-	case V4L2_PIX_FMT_RGB24:
-		mdp_format = MDP_RGB_888;
-		break;
-	case V4L2_PIX_FMT_NV12:
-		mdp_format = MDP_Y_CRCB_H2V2;
-		break;
-	case V4L2_PIX_FMT_NV21:
-		mdp_format = MDP_Y_CBCR_H2V2;
-		break;
-	case V4L2_PIX_FMT_YUV420:
-		mdp_format = MDP_Y_CR_CB_H2V2;
-		break;
-	default:
-		pr_err("%s:Unrecognized format %u\n", __func__, pixelformat);
-		mdp_format = MDP_Y_CBCR_H2V2;
-		break;
-	}
-
-	return mdp_format;
-}
-
-static int
-msm_v4l2_overlay_fb_update(struct msm_v4l2_overlay_device *vout,
-	struct v4l2_buffer *buffer)
-{
-	int ret;
-	unsigned long src_addr, src_size;
-	struct msm_v4l2_overlay_userptr_buffer up_buffer;
-
-	if (!buffer ||
-		(buffer->memory == V4L2_MEMORY_MMAP &&
-		 buffer->index >= vout->numbufs))
-		return -EINVAL;
-
-	mutex_lock(&msmfb_lock);
-	switch (buffer->memory) {
-	case V4L2_MEMORY_MMAP:
-		src_addr = (unsigned long)v4l2_ram_phys
-		+ vout->bufs[buffer->index].offset;
-		src_size = buffer->bytesused;
-		ret = msm_fb_v4l2_update(vout->par, src_addr, src_size,
-		0, 0, 0, 0);
-		break;
-	case V4L2_MEMORY_USERPTR:
-		if (copy_from_user(&up_buffer,
-		(void __user *)buffer->m.userptr,
-		sizeof(struct msm_v4l2_overlay_userptr_buffer))) {
-			mutex_unlock(&msmfb_lock);
-			return -EINVAL;
-		}
-		ret = msm_fb_v4l2_update(vout->par,
-		(unsigned long)up_buffer.base[0], up_buffer.length[0],
-		(unsigned long)up_buffer.base[1], up_buffer.length[1],
-		(unsigned long)up_buffer.base[2], up_buffer.length[2]);
-		break;
-	default:
-		mutex_unlock(&msmfb_lock);
-		return -EINVAL;
-	}
-	mutex_unlock(&msmfb_lock);
-
-	if (buffer->memory == V4L2_MEMORY_MMAP) {
-		vout->bufs[buffer->index].queued = 1;
-		buffer->flags |= V4L2_BUF_FLAG_MAPPED;
-	}
-	buffer->flags |= V4L2_BUF_FLAG_QUEUED;
-
-	return ret;
-}
-
-static int
-msm_v4l2_overlay_vidioc_dqbuf(struct file *file,
-	struct msm_v4l2_overlay_fh *fh, void *arg)
-{
-	struct msm_v4l2_overlay_device *vout = fh->vout;
-	struct v4l2_buffer *buffer = arg;
-	int i;
-
-	if (!vout->streaming) {
-		pr_err("%s: Video Stream not enabled\n", __func__);
-		return -EINVAL;
-	}
-
-	if (!buffer || buffer->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
-		return -EINVAL;
-
-	if (buffer->memory == V4L2_MEMORY_MMAP) {
-		for (i = 0; i < vout->numbufs; i++) {
-			if (vout->bufs[i].queued == 1)  {
-				vout->bufs[i].queued = 0;
-				/* Call into fb to remove this buffer? */
-				break;
-			}
-		}
-
-		/*
-		 * This should actually block, unless O_NONBLOCK was
-		 *  specified in open, but fine for now, especially
-		 *  since this is not a capturing device
-		 */
-		if (i == vout->numbufs)
-			return -EAGAIN;
-	}
-
-	buffer->flags &= ~V4L2_BUF_FLAG_QUEUED;
-
-	return 0;
-}
-
-
-static int
-msm_v4l2_overlay_vidioc_qbuf(struct file *file, struct msm_v4l2_overlay_fh* fh,
-	void *arg, bool bUserPtr)
-{
-	struct msm_v4l2_overlay_device *vout = fh->vout;
-	struct v4l2_buffer *buffer = arg;
-	int ret;
-
-	if (!bUserPtr && buffer->memory != V4L2_MEMORY_MMAP)
-		return -EINVAL;
-
-	if (!vout->streaming) {
-		pr_err("%s: Video Stream not enabled\n", __func__);
-		return -EINVAL;
-	}
-
-	if (!buffer || buffer->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
-		return -EINVAL;
-
-	/* maybe allow only one qbuf at a time? */
-	ret =  msm_v4l2_overlay_fb_update(vout, buffer);
-
-	return 0;
-}
-
-static int
-msm_v4l2_overlay_vidioc_querycap(struct file *file, void *arg)
-{
-	struct v4l2_capability *buffer = arg;
-
-	memset(buffer, 0, sizeof(struct v4l2_capability));
-	strlcpy(buffer->driver, "msm_v4l2_video_overlay",
-		ARRAY_SIZE(buffer->driver));
-	strlcpy(buffer->card, "MSM MDP",
-		ARRAY_SIZE(buffer->card));
-	buffer->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT
-		| V4L2_CAP_VIDEO_OVERLAY;
-	return 0;
-}
-
-static int
-msm_v4l2_overlay_vidioc_fbuf(struct file *file,
-	struct msm_v4l2_overlay_device *vout, void *arg, bool get)
-{
-	struct v4l2_framebuffer *fb = arg;
-
-	if (fb == NULL)
-		return -EINVAL;
-
-	if (get) {
-		mutex_lock(&vout->update_lock);
-		memcpy(&fb->fmt, &vout->pix, sizeof(struct v4l2_pix_format));
-		mutex_unlock(&vout->update_lock);
-	}
-	/* The S_FBUF request does not store anything right now */
-	return 0;
-}
-
-static long msm_v4l2_overlay_calculate_bufsize(struct v4l2_pix_format *pix)
-{
-	int bpp;
-	long bufsize;
-	switch (pix->pixelformat) {
-	case V4L2_PIX_FMT_YUV420:
-	case V4L2_PIX_FMT_NV12:
-		bpp = 12;
-		break;
-
-	case V4L2_PIX_FMT_RGB565:
-		bpp = 16;
-		break;
-
-	case V4L2_PIX_FMT_RGB24:
-	case V4L2_PIX_FMT_BGR24:
-	case V4L2_PIX_FMT_YUV444:
-		bpp = 24;
-		break;
-
-	case V4L2_PIX_FMT_RGB32:
-	case V4L2_PIX_FMT_BGR32:
-		bpp = 32;
-		break;
-	default:
-		pr_err("%s: Unrecognized format %u\n", __func__,
-		pix->pixelformat);
-		bpp = 0;
-	}
-
-	bufsize = (pix->width * pix->height * bpp)/8;
-
-	return bufsize;
-}
-
-static long
-msm_v4l2_overlay_vidioc_reqbufs(struct file *file,
-	struct msm_v4l2_overlay_device *vout, void *arg)
-
-{
-	struct v4l2_requestbuffers *rqb = arg;
-	long bufsize;
-	int i;
-
-	if (rqb == NULL || rqb->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
-		return -EINVAL;
-
-	if (rqb->memory == V4L2_MEMORY_MMAP) {
-		if (rqb->count == 0) {
-			/* Deallocate allocated buffers */
-			mutex_lock(&vout->update_lock);
-			vout->numbufs = 0;
-			kfree(vout->bufs);
-			/*
-			 * There should be a way to look at bufs[i]->mapped,
-			 * and prevent userspace from mmaping and directly
-			 * calling this ioctl without unmapping. Maybe kernel
-			 * handles for us, but needs to be checked out
-			 */
-			mutex_unlock(&vout->update_lock);
-		} else {
-			/*
-			 * Keep it simple for now - need to deallocate
-			 * before reallocate
-			 */
-			if (vout->bufs)
-				return -EINVAL;
-
-			mutex_lock(&vout->update_lock);
-			bufsize =
-				msm_v4l2_overlay_calculate_bufsize(&vout->pix);
-			mutex_unlock(&vout->update_lock);
-
-			if (bufsize == 0
-				|| (bufsize * rqb->count) > v4l2_ram_size) {
-				pr_err("%s: Unsupported format or buffer size too large\n",
-				__func__);
-				pr_err("%s: bufsize %lu ram_size %u count %u\n",
-				__func__, bufsize, v4l2_ram_size, rqb->count);
-				return -EINVAL;
-			}
-
-			/*
-			 * We don't support multiple open of one vout,
-			 * but there are probably still some MT problems here,
-			 * (what if same fh is shared between two userspace
-			 * threads and they both call REQBUFS etc)
-			 */
-
-			mutex_lock(&vout->update_lock);
-			vout->numbufs = rqb->count;
-			vout->bufs =
-				kmalloc(rqb->count *
-					sizeof(struct msm_v4l2_overlay_buffer),
-					GFP_KERNEL);
-
-			for (i = 0; i < rqb->count; i++) {
-				struct msm_v4l2_overlay_buffer *b =
-				(struct msm_v4l2_overlay_buffer *)vout->bufs
-				+ i;
-				b->mapped = 0;
-				b->queued = 0;
-				b->offset = PAGE_ALIGN(bufsize*i);
-				b->bufsize = bufsize;
-			}
-
-			mutex_unlock(&vout->update_lock);
-
-		}
-	}
-
-	return 0;
-}
-
-static long
-msm_v4l2_overlay_vidioc_querybuf(struct file *file,
-				 struct msm_v4l2_overlay_device *vout,
-				 void *arg)
-{
-	struct v4l2_buffer *buf = arg;
-	struct msm_v4l2_overlay_buffer *mbuf;
-
-	if (buf == NULL || buf->type != V4L2_BUF_TYPE_VIDEO_OUTPUT
-			|| buf->memory == V4L2_MEMORY_USERPTR
-			|| buf->index >= vout->numbufs)
-		return -EINVAL;
-
-	mutex_lock(&vout->update_lock);
-
-	mbuf = (struct msm_v4l2_overlay_buffer *)vout->bufs + buf->index;
-	buf->flags = 0;
-	if (mbuf->mapped)
-		buf->flags |= V4L2_BUF_FLAG_MAPPED;
-	if (mbuf->queued)
-		buf->flags |= V4L2_BUF_FLAG_QUEUED;
-
-	buf->memory = V4L2_MEMORY_MMAP;
-	buf->length = mbuf->bufsize;
-	buf->m.offset = mbuf->offset;
-
-	mutex_unlock(&vout->update_lock);
-
-	return 0;
-}
-
-static long
-msm_v4l2_overlay_do_ioctl(struct file *file,
-		       unsigned int cmd, void *arg)
-{
-	struct msm_v4l2_overlay_fh *fh = file->private_data;
-	struct msm_v4l2_overlay_device *vout = fh->vout;
-	int ret;
-
-	switch (cmd) {
-	case VIDIOC_QUERYCAP:
-		return msm_v4l2_overlay_vidioc_querycap(file, arg);
-
-	case VIDIOC_G_FBUF:
-		return msm_v4l2_overlay_vidioc_fbuf(file, vout, arg, true);
-
-	case VIDIOC_S_FBUF:
-		return msm_v4l2_overlay_vidioc_fbuf(file, vout, arg, false);
-
-	case VIDIOC_REQBUFS:
-		return msm_v4l2_overlay_vidioc_reqbufs(file, vout, arg);
-
-	case VIDIOC_QUERYBUF:
-		return msm_v4l2_overlay_vidioc_querybuf(file, vout, arg);
-
-	case VIDIOC_QBUF:
-		mutex_lock(&vout->update_lock);
-		ret = msm_v4l2_overlay_vidioc_qbuf(file, fh, arg, false);
-		mutex_unlock(&vout->update_lock);
-
-		return ret;
-
-	case VIDIOC_MSM_USERPTR_QBUF:
-		if (!capable(CAP_SYS_RAWIO))
-			return -EPERM;
-
-		mutex_lock(&vout->update_lock);
-		ret = msm_v4l2_overlay_vidioc_qbuf(file, fh, arg, true);
-		mutex_unlock(&vout->update_lock);
-
-		return ret;
-
-	case VIDIOC_DQBUF:
-		mutex_lock(&vout->update_lock);
-		ret = msm_v4l2_overlay_vidioc_dqbuf(file, fh, arg);
-		mutex_unlock(&vout->update_lock);
-		break;
-
-	case VIDIOC_S_FMT: {
-		struct v4l2_format *f = arg;
-
-		switch (f->type) {
-		case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-			mutex_lock(&vout->update_lock);
-			memcpy(&vout->win, &f->fmt.win,
-				sizeof(struct v4l2_window));
-			mutex_unlock(&vout->update_lock);
-			break;
-
-		case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-			mutex_lock(&vout->update_lock);
-			memcpy(&vout->pix, &f->fmt.pix,
-				sizeof(struct v4l2_pix_format));
-			mutex_unlock(&vout->update_lock);
-			break;
-
-		default:
-			return -EINVAL;
-		}
-		break;
-	}
-	case VIDIOC_G_FMT: {
-		struct v4l2_format *f = arg;
-
-		switch (f->type) {
-		case V4L2_BUF_TYPE_VIDEO_OUTPUT: {
-			struct v4l2_pix_format *pix = &f->fmt.pix;
-			memset(pix, 0, sizeof(*pix));
-			*pix = vout->pix;
-			break;
-		}
-
-		case V4L2_BUF_TYPE_VIDEO_OVERLAY: {
-			struct v4l2_window *win = &f->fmt.win;
-			memset(win, 0, sizeof(*win));
-			win->w = vout->win.w;
-			break;
-		}
-		default:
-			return -EINVAL;
-		}
-		break;
-	}
-
-	case VIDIOC_CROPCAP: {
-		struct v4l2_cropcap *cr = arg;
-		if (cr->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
-			return -EINVAL;
-
-		cr->bounds.left =  0;
-		cr->bounds.top = 0;
-		cr->bounds.width = vout->crop_rect.width;
-		cr->bounds.height = vout->crop_rect.height;
-
-		cr->defrect.left =  0;
-		cr->defrect.top = 0;
-		cr->defrect.width = vout->crop_rect.width;
-		cr->defrect.height = vout->crop_rect.height;
-
-		cr->pixelaspect.numerator = 1;
-		cr->pixelaspect.denominator = 1;
-		break;
-	}
-
-	case VIDIOC_S_CROP: {
-		struct v4l2_crop *crop = arg;
-
-		switch (crop->type) {
-
-		case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-
-			mutex_lock(&vout->update_lock);
-			memcpy(&vout->crop_rect, &crop->c,
-				sizeof(struct v4l2_rect));
-			mutex_unlock(&vout->update_lock);
-
-			break;
-
-		default:
-
-			return -EINVAL;
-		}
-		break;
-	}
-	case VIDIOC_G_CROP: {
-		struct v4l2_crop *crop = arg;
-
-		switch (crop->type) {
-
-		case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-			memcpy(&crop->c, &vout->crop_rect,
-				sizeof(struct v4l2_rect));
-			break;
-
-		default:
-			return -EINVAL;
-		}
-		break;
-	}
-
-	case VIDIOC_S_CTRL: {
-		struct v4l2_control *ctrl = arg;
-		int32_t rotflag;
-
-		switch (ctrl->id) {
-
-		case V4L2_CID_ROTATE:
-			switch (ctrl->value) {
-			case 0:
-				rotflag = MDP_ROT_NOP;
-				break;
-			case 90:
-				rotflag = MDP_ROT_90;
-				break;
-			case 180:
-				rotflag = MDP_ROT_180;
-				break;
-			case 270:
-				rotflag = MDP_ROT_270;
-				break;
-			default:
-				pr_err("%s: V4L2_CID_ROTATE invalid rotation value %d.\n",
-						__func__, ctrl->value);
-				return -ERANGE;
-			}
-
-			mutex_lock(&vout->update_lock);
-			/* Clear the rotation flags */
-			vout->req.flags &= ~MDP_ROT_NOP;
-			vout->req.flags &= ~MDP_ROT_90;
-			vout->req.flags &= ~MDP_ROT_180;
-			vout->req.flags &= ~MDP_ROT_270;
-			/* Set the new rotation flag */
-			vout->req.flags |= rotflag;
-			mutex_unlock(&vout->update_lock);
-
-			break;
-
-		case V4L2_CID_HFLIP:
-			mutex_lock(&vout->update_lock);
-			/* Clear the flip flag */
-			vout->req.flags &= ~MDP_FLIP_LR;
-			if (true == ctrl->value)
-				vout->req.flags |= MDP_FLIP_LR;
-			mutex_unlock(&vout->update_lock);
-
-			break;
-
-		case V4L2_CID_VFLIP:
-			mutex_lock(&vout->update_lock);
-			/* Clear the flip flag */
-			vout->req.flags &= ~MDP_FLIP_UD;
-			if (true == ctrl->value)
-				vout->req.flags |= MDP_FLIP_UD;
-			mutex_unlock(&vout->update_lock);
-
-			break;
-
-		default:
-			pr_err("%s: VIDIOC_S_CTRL invalid control ID %d.\n",
-			__func__, ctrl->id);
-			return -EINVAL;
-		}
-		break;
-	}
-	case VIDIOC_G_CTRL: {
-		struct v4l2_control *ctrl = arg;
-		__s32 rotation;
-
-		switch (ctrl->id) {
-
-		case V4L2_CID_ROTATE:
-			if (MDP_ROT_NOP == (vout->req.flags & MDP_ROT_NOP))
-				rotation = 0;
-			if (MDP_ROT_90 == (vout->req.flags & MDP_ROT_90))
-				rotation = 90;
-			if (MDP_ROT_180 == (vout->req.flags & MDP_ROT_180))
-				rotation = 180;
-			if (MDP_ROT_270 == (vout->req.flags & MDP_ROT_270))
-				rotation = 270;
-
-			ctrl->value = rotation;
-			break;
-
-		case V4L2_CID_HFLIP:
-			if (MDP_FLIP_LR == (vout->req.flags & MDP_FLIP_LR))
-				ctrl->value = true;
-			break;
-
-		case V4L2_CID_VFLIP:
-			if (MDP_FLIP_UD == (vout->req.flags & MDP_FLIP_UD))
-				ctrl->value = true;
-			break;
-
-		default:
-			pr_err("%s: VIDIOC_G_CTRL invalid control ID %d.\n",
-			__func__, ctrl->id);
-			return -EINVAL;
-		}
-		break;
-	}
-
-	case VIDIOC_STREAMON: {
-
-		if (vout->streaming) {
-			pr_err("%s: VIDIOC_STREAMON: already streaming.\n",
-			__func__);
-			return -EBUSY;
-		}
-
-		mutex_lock(&vout->update_lock);
-		msm_v4l2_overlay_startstreaming(vout);
-		mutex_unlock(&vout->update_lock);
-
-		break;
-	}
-
-	case VIDIOC_STREAMOFF: {
-
-		if (!vout->streaming) {
-			pr_err("%s: VIDIOC_STREAMOFF: not currently streaming.\n",
-			__func__);
-			return -EINVAL;
-		}
-
-		mutex_lock(&vout->update_lock);
-		msm_v4l2_overlay_stopstreaming(vout);
-		mutex_unlock(&vout->update_lock);
-
-		break;
-	}
-
-	default:
-		return -ENOIOCTLCMD;
-
-	} /* switch */
-
-	return 0;
-}
-
-static long
-msm_v4l2_overlay_ioctl(struct file *file, unsigned int cmd,
-		    unsigned long arg)
-{
-	return video_usercopy(file, cmd, arg, msm_v4l2_overlay_do_ioctl);
-}
-
-static int
-msm_v4l2_overlay_mmap(struct file *filp, struct vm_area_struct * vma)
-{
-	unsigned long start = (unsigned long)v4l2_ram_phys;
-
-	/*
-	 * vm_pgoff is the offset (>>PAGE_SHIFT) that we provided
-	 * during REQBUFS. off therefore should equal the offset we
-	 * provided in REQBUFS, since last (PAGE_SHIFT) bits of off
-	 * should be 0
-	 */
-	unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
-	u32 len = PAGE_ALIGN((start & ~PAGE_MASK) + v4l2_ram_size);
-
-	/*
-	 * This is probably unnecessary now - the last PAGE_SHIFT
-	 * bits of start should be 0 now, since we are page aligning
-	 * v4l2_ram_phys
-	 */
-	start &= PAGE_MASK;
-
-	pr_debug("v4l2 map req for phys(%p,%p) offset %u to virt (%p,%p)\n",
-	(void *)(start+off), (void *)(start+off+(vma->vm_end - vma->vm_start)),
-	(unsigned int)off, (void *)vma->vm_start, (void *)vma->vm_end);
-
-	if ((vma->vm_end - vma->vm_start + off) > len) {
-		pr_err("v4l2 map request, memory requested too big\n");
-		return -EINVAL;
-	}
-
-	start += off;
-	vma->vm_pgoff = start >> PAGE_SHIFT;
-	/* This is an IO map - tell maydump to skip this VMA */
-	vma->vm_flags |= VM_IO | VM_RESERVED;
-
-	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
-	/* Remap the frame buffer I/O range */
-	if (io_remap_pfn_range(vma, vma->vm_start, start >> PAGE_SHIFT,
-				vma->vm_end - vma->vm_start,
-				vma->vm_page_prot))
-		return -EAGAIN;
-
-	return 0;
-}
-
-static int
-msm_v4l2_overlay_release(struct file *file)
-{
-	struct msm_v4l2_overlay_fh *fh = file->private_data;
-	struct msm_v4l2_overlay_device *vout = fh->vout;
-
-	if (vout->streaming)
-		msm_v4l2_overlay_stopstreaming(vout);
-
-	vout->ref_count--;
-
-	kfree(vout->bufs);
-	vout->numbufs = 0;
-	kfree(fh);
-
-	return 0;
-}
-
-static int
-msm_v4l2_overlay_open(struct file *file)
-{
-	struct msm_v4l2_overlay_device	*vout = NULL;
-	struct v4l2_pix_format	*pix = NULL;
-	struct msm_v4l2_overlay_fh *fh;
-
-	vout = saved_vout0;
-	vout->id = 0;
-
-	if (vout->ref_count) {
-		pr_err("%s: multiple open currently is not"
-		"supported!\n", __func__);
-		return -EBUSY;
-	}
-
-	vout->ref_count++;
-
-	/* allocate per-filehandle data */
-	fh = kmalloc(sizeof(struct msm_v4l2_overlay_fh), GFP_KERNEL);
-	if (NULL == fh)
-		return -ENOMEM;
-
-	fh->vout = vout;
-	fh->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-
-	file->private_data = fh;
-
-	vout->streaming		= 0;
-	vout->crop_rect.left	= vout->crop_rect.top = 0;
-	vout->crop_rect.width	= vout->screen_width;
-	vout->crop_rect.height	= vout->screen_height;
-
-	pix				= &vout->pix;
-	pix->width			= vout->screen_width;
-	pix->height		= vout->screen_height;
-	pix->pixelformat	= V4L2_PIX_FMT_RGB32;
-	pix->field			= V4L2_FIELD_NONE;
-	pix->bytesperline	= pix->width * 4;
-	pix->sizeimage		= pix->bytesperline * pix->height;
-	pix->priv			= 0;
-	pix->colorspace		= V4L2_COLORSPACE_SRGB;
-
-	vout->win.w.left	= 0;
-	vout->win.w.top		= 0;
-	vout->win.w.width	= vout->screen_width;
-	vout->win.w.height	= vout->screen_height;
-
-	vout->fb.capability = V4L2_FBUF_CAP_EXTERNOVERLAY
-		| V4L2_FBUF_CAP_LOCAL_ALPHA;
-	vout->fb.flags = V4L2_FBUF_FLAG_LOCAL_ALPHA;
-	vout->fb.base = 0;
-	memcpy(&vout->fb.fmt, pix, sizeof(struct v4l2_format));
-
-	vout->bufs = 0;
-	vout->numbufs = 0;
-
-	mutex_init(&vout->update_lock);
-
-	return 0;
-}
-
-
-static int __devinit
-msm_v4l2_overlay_probe(struct platform_device *pdev)
-{
-	char *v4l2_ram_phys_unaligned;
-	if ((pdev->id == 0) && (pdev->num_resources > 0)) {
-		v4l2_ram_size =
-			pdev->resource[0].end - pdev->resource[0].start + 1;
-		v4l2_ram_phys_unaligned = (char *)pdev->resource[0].start;
-		v4l2_ram_phys =
-		(char *)PAGE_ALIGN((unsigned int)v4l2_ram_phys_unaligned);
-		/*
-		 * We are (fwd) page aligning the start of v4l2 memory.
-		 * Therefore we have that much less physical memory available
-		 */
-		v4l2_ram_size -= (unsigned int)v4l2_ram_phys
-			- (unsigned int)v4l2_ram_phys_unaligned;
-
-
-	}
-	return 0;
-}
-
-static int __devexit
-msm_v4l2_overlay_remove(struct platform_device *pdev)
-{
-	return 0;
-}
-
-static void msm_v4l2_overlay_videodev_release(struct video_device *vfd)
-{
-	return;
-}
-
-static const struct v4l2_file_operations msm_v4l2_overlay_fops = {
-	.owner		= THIS_MODULE,
-	.open		= msm_v4l2_overlay_open,
-	.release	= msm_v4l2_overlay_release,
-	.mmap		= msm_v4l2_overlay_mmap,
-	.ioctl		= msm_v4l2_overlay_ioctl,
-};
-
-static struct video_device msm_v4l2_overlay_vid_device0 = {
-	.name		= "msm_v4l2_overlay",
-	.fops       = &msm_v4l2_overlay_fops,
-	.minor		= -1,
-	.release	= msm_v4l2_overlay_videodev_release,
-};
-
-static struct platform_driver msm_v4l2_overlay_platform_driver = {
-	.probe   = msm_v4l2_overlay_probe,
-	.remove  = msm_v4l2_overlay_remove,
-	.driver  = {
-			 .name = "msm_v4l2_overlay_pd",
-		   },
-};
-
-static int __init msm_v4l2_overlay_init(void)
-{
-	int ret;
-
-
-	saved_vout0 = kzalloc(sizeof(struct msm_v4l2_overlay_device),
-		GFP_KERNEL);
-
-	if (!saved_vout0)
-		return -ENOMEM;
-
-	ret = platform_driver_register(&msm_v4l2_overlay_platform_driver);
-	if (ret < 0)
-		goto end;
-
-	/*
-	 * Register the device with videodev.
-	 * Videodev will make IOCTL calls on application requests
-	 */
-	ret = video_register_device(&msm_v4l2_overlay_vid_device0,
-		VFL_TYPE_GRABBER, MSM_VIDEO);
-
-	if (ret < 0) {
-		pr_err("%s: V4L2 video overlay device registration failure(%d)\n",
-				  __func__, ret);
-		goto end_unregister;
-	}
-
-	mutex_init(&msmfb_lock);
-
-	return 0;
-
-end_unregister:
-	platform_driver_unregister(&msm_v4l2_overlay_platform_driver);
-
-end:
-	kfree(saved_vout0);
-	return ret;
-}
-
-static void __exit msm_v4l2_overlay_exit(void)
-{
-	video_unregister_device(&msm_v4l2_overlay_vid_device0);
-	platform_driver_unregister(&msm_v4l2_overlay_platform_driver);
-	mutex_destroy(&msmfb_lock);
-	kfree(saved_vout0);
-}
-
-module_init(msm_v4l2_overlay_init);
-module_exit(msm_v4l2_overlay_exit);
-
-MODULE_DESCRIPTION("MSM V4L2 Video Overlay Driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/msm_v4l2_video.h b/drivers/media/video/msm/msm_v4l2_video.h
deleted file mode 100644
index a7baa75..0000000
--- a/drivers/media/video/msm/msm_v4l2_video.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 MSM_V4L2_VIDEO_H
-#define MSM_V4L2_VIDEO_H
-
-#include <linux/mm.h>
-#include <linux/msm_mdp.h>
-#include <linux/videodev2.h>
-
-
-struct msm_v4l2_overlay_buffer {
-	int mapped;
-	int queued;
-	int offset;
-	int bufsize;
-};
-
-struct msm_v4l2_overlay_device {
-	struct device dev;
-
-	int ref_count;
-	int id;
-
-	int screen_width;
-	int screen_height;
-	int streaming;
-
-	struct v4l2_pix_format pix;
-	struct v4l2_window win;
-	struct v4l2_rect crop_rect;
-	struct v4l2_framebuffer fb;
-	struct msm_v4l2_overlay_buffer *bufs;
-	int numbufs;
-	struct mdp_overlay req;
-	void *par;
-
-	struct mutex update_lock;
-};
-
-struct msm_v4l2_overlay_fh {
-	struct msm_v4l2_overlay_device *vout;
-	enum v4l2_buf_type type;
-};
-
-struct msm_v4l2_overlay_userptr_buffer {
-	uint base[3];
-	size_t length[3];
-};
-
-#endif
diff --git a/drivers/media/video/msm/msm_vpe.c b/drivers/media/video/msm/msm_vpe.c
deleted file mode 100644
index ede0f7a..0000000
--- a/drivers/media/video/msm/msm_vpe.c
+++ /dev/null
@@ -1,1146 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/uaccess.h>
-#include <linux/interrupt.h>
-#include <mach/irqs.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/regulator/consumer.h>
-#include <linux/clk.h>
-#include <mach/clk.h>
-#include <asm/div64.h>
-#include <linux/workqueue.h>
-#include <linux/delay.h>
-#include <linux/types.h>
-#include <linux/list.h>
-#include <linux/ioctl.h>
-#include <linux/spinlock.h>
-#include "msm.h"
-#include "msm_vpe.h"
-
-#ifdef CONFIG_MSM_CAMERA_DEBUG
-#define D(fmt, args...) pr_debug("msm_vpe: " fmt, ##args)
-#else
-#define D(fmt, args...) do {} while (0)
-#endif
-
-static int vpe_enable(uint32_t, struct msm_cam_media_controller *);
-static int vpe_disable(struct msm_cam_media_controller *);
-static int vpe_update_scaler(struct msm_pp_crop *pcrop);
-struct vpe_ctrl_type *vpe_ctrl;
-static atomic_t vpe_init_done = ATOMIC_INIT(0);
-
-static int msm_vpe_do_pp(struct msm_mctl_pp_frame_info *pp_frame_info);
-
-static long long vpe_do_div(long long num, long long den)
-{
-	do_div(num, den);
-	return num;
-}
-
-static int vpe_start(void)
-{
-	/*  enable the frame irq, bit 0 = Display list 0 ROI done */
-	msm_camera_io_w_mb(1, vpe_ctrl->vpebase + VPE_INTR_ENABLE_OFFSET);
-	msm_camera_io_dump(vpe_ctrl->vpebase, 0x120);
-	msm_camera_io_dump(vpe_ctrl->vpebase + 0x00400, 0x18);
-	msm_camera_io_dump(vpe_ctrl->vpebase + 0x10000, 0x250);
-	msm_camera_io_dump(vpe_ctrl->vpebase + 0x30000, 0x20);
-	msm_camera_io_dump(vpe_ctrl->vpebase + 0x50000, 0x30);
-	msm_camera_io_dump(vpe_ctrl->vpebase + 0x50400, 0x10);
-
-	/* this triggers the operation. */
-	msm_camera_io_w_mb(1, vpe_ctrl->vpebase + VPE_DL0_START_OFFSET);
-	return 0;
-}
-
-void vpe_reset_state_variables(void)
-{
-	/* initialize local variables for state control, etc.*/
-	vpe_ctrl->op_mode = 0;
-	vpe_ctrl->state = VPE_STATE_INIT;
-}
-
-static void vpe_config_axi_default(void)
-{
-	msm_camera_io_w(0x25, vpe_ctrl->vpebase + VPE_AXI_ARB_2_OFFSET);
-	D("%s: yaddr %ld cbcraddr %ld", __func__,
-		 vpe_ctrl->out_y_addr, vpe_ctrl->out_cbcr_addr);
-	if (!vpe_ctrl->out_y_addr || !vpe_ctrl->out_cbcr_addr)
-		return;
-	msm_camera_io_w(vpe_ctrl->out_y_addr,
-		vpe_ctrl->vpebase + VPE_OUTP0_ADDR_OFFSET);
-	/* for video  CbCr address */
-	msm_camera_io_w(vpe_ctrl->out_cbcr_addr,
-		vpe_ctrl->vpebase + VPE_OUTP1_ADDR_OFFSET);
-}
-
-static int vpe_reset(void)
-{
-	uint32_t vpe_version;
-	uint32_t rc = 0;
-	unsigned long flags = 0;
-
-	spin_lock_irqsave(&vpe_ctrl->lock, flags);
-	if (vpe_ctrl->state == VPE_STATE_IDLE) {
-		D("%s: VPE already disabled.", __func__);
-		spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
-		return rc;
-	}
-	spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
-
-	vpe_reset_state_variables();
-	vpe_version = msm_camera_io_r(
-			vpe_ctrl->vpebase + VPE_HW_VERSION_OFFSET);
-	D("vpe_version = 0x%x\n", vpe_version);
-	/* disable all interrupts.*/
-	msm_camera_io_w(0, vpe_ctrl->vpebase + VPE_INTR_ENABLE_OFFSET);
-	/* clear all pending interrupts*/
-	msm_camera_io_w(0x1fffff, vpe_ctrl->vpebase + VPE_INTR_CLEAR_OFFSET);
-	/* write sw_reset to reset the core. */
-	msm_camera_io_w(0x10, vpe_ctrl->vpebase + VPE_SW_RESET_OFFSET);
-	/* then poll the reset bit, it should be self-cleared. */
-	while (1) {
-		rc =
-		msm_camera_io_r(vpe_ctrl->vpebase + VPE_SW_RESET_OFFSET) & 0x10;
-		if (rc == 0)
-			break;
-	}
-	/*  at this point, hardware is reset. Then pogram to default
-		values. */
-	msm_camera_io_w(VPE_AXI_RD_ARB_CONFIG_VALUE,
-			vpe_ctrl->vpebase + VPE_AXI_RD_ARB_CONFIG_OFFSET);
-
-	msm_camera_io_w(VPE_CGC_ENABLE_VALUE,
-			vpe_ctrl->vpebase + VPE_CGC_EN_OFFSET);
-	msm_camera_io_w(1, vpe_ctrl->vpebase + VPE_CMD_MODE_OFFSET);
-	msm_camera_io_w(VPE_DEFAULT_OP_MODE_VALUE,
-			vpe_ctrl->vpebase + VPE_OP_MODE_OFFSET);
-	msm_camera_io_w(VPE_DEFAULT_SCALE_CONFIG,
-			vpe_ctrl->vpebase + VPE_SCALE_CONFIG_OFFSET);
-	vpe_config_axi_default();
-	return rc;
-}
-
-static int msm_vpe_cfg_update(void *pinfo)
-{
-	uint32_t  rot_flag, rc = 0;
-	struct msm_pp_crop *pcrop = (struct msm_pp_crop *)pinfo;
-
-	rot_flag = msm_camera_io_r(vpe_ctrl->vpebase +
-						VPE_OP_MODE_OFFSET) & 0xE00;
-	if (pinfo != NULL) {
-		D("%s: Crop info in2_w = %d, in2_h = %d "
-			"out2_w = %d out2_h = %d\n",
-			__func__, pcrop->src_w, pcrop->src_h,
-			pcrop->dst_w, pcrop->dst_h);
-		rc = vpe_update_scaler(pcrop);
-	}
-	D("return rc = %d rot_flag = %d\n", rc, rot_flag);
-	rc |= rot_flag;
-
-	return rc;
-}
-
-void vpe_update_scale_coef(uint32_t *p)
-{
-	uint32_t i, offset;
-	offset = *p;
-	for (i = offset; i < (VPE_SCALE_COEFF_NUM + offset); i++) {
-		msm_camera_io_w(*(++p),
-			vpe_ctrl->vpebase + VPE_SCALE_COEFF_LSBn(i));
-		msm_camera_io_w(*(++p),
-			vpe_ctrl->vpebase + VPE_SCALE_COEFF_MSBn(i));
-	}
-}
-
-void vpe_input_plane_config(uint32_t *p)
-{
-	msm_camera_io_w(*p, vpe_ctrl->vpebase + VPE_SRC_FORMAT_OFFSET);
-	msm_camera_io_w(*(++p),
-		vpe_ctrl->vpebase + VPE_SRC_UNPACK_PATTERN1_OFFSET);
-	msm_camera_io_w(*(++p), vpe_ctrl->vpebase + VPE_SRC_IMAGE_SIZE_OFFSET);
-	msm_camera_io_w(*(++p), vpe_ctrl->vpebase + VPE_SRC_YSTRIDE1_OFFSET);
-	msm_camera_io_w(*(++p), vpe_ctrl->vpebase + VPE_SRC_SIZE_OFFSET);
-	msm_camera_io_w(*(++p), vpe_ctrl->vpebase + VPE_SRC_XY_OFFSET);
-}
-
-void vpe_output_plane_config(uint32_t *p)
-{
-	msm_camera_io_w(*p, vpe_ctrl->vpebase + VPE_OUT_FORMAT_OFFSET);
-	msm_camera_io_w(*(++p),
-		vpe_ctrl->vpebase + VPE_OUT_PACK_PATTERN1_OFFSET);
-	msm_camera_io_w(*(++p), vpe_ctrl->vpebase + VPE_OUT_YSTRIDE1_OFFSET);
-	msm_camera_io_w(*(++p), vpe_ctrl->vpebase + VPE_OUT_SIZE_OFFSET);
-	msm_camera_io_w(*(++p), vpe_ctrl->vpebase + VPE_OUT_XY_OFFSET);
-}
-
-static int vpe_operation_config(uint32_t *p)
-{
-	uint32_t w, h, temp;
-	msm_camera_io_w(*p, vpe_ctrl->vpebase + VPE_OP_MODE_OFFSET);
-
-	temp = msm_camera_io_r(vpe_ctrl->vpebase + VPE_OUT_SIZE_OFFSET);
-	w = temp & 0xFFF;
-	h = (temp & 0xFFF0000) >> 16;
-	if (*p++ & 0xE00) {
-		/* rotation enabled. */
-		vpe_ctrl->out_w = h;
-		vpe_ctrl->out_h = w;
-	} else {
-		vpe_ctrl->out_w = w;
-		vpe_ctrl->out_h = h;
-	}
-	D("%s: out_w=%d, out_h=%d", __func__, vpe_ctrl->out_w,
-		vpe_ctrl->out_h);
-	return 0;
-}
-
-/* Later we can separate the rotation and scaler calc. If
-*  rotation is enabled, simply swap the destination dimension.
-*  And then pass the already swapped output size to this
-*  function. */
-static int vpe_update_scaler(struct msm_pp_crop *pcrop)
-{
-	uint32_t out_ROI_width, out_ROI_height;
-	uint32_t src_ROI_width, src_ROI_height;
-
-	/*
-	* phase_step_x, phase_step_y, phase_init_x and phase_init_y
-	* are represented in fixed-point, unsigned 3.29 format
-	*/
-	uint32_t phase_step_x = 0;
-	uint32_t phase_step_y = 0;
-	uint32_t phase_init_x = 0;
-	uint32_t phase_init_y = 0;
-
-	uint32_t src_roi, src_x, src_y, src_xy, temp;
-	uint32_t yscale_filter_sel, xscale_filter_sel;
-	uint32_t scale_unit_sel_x, scale_unit_sel_y;
-	uint64_t numerator, denominator;
-
-	/* assumption is both direction need zoom. this can be
-	improved. */
-	temp =
-		msm_camera_io_r(vpe_ctrl->vpebase + VPE_OP_MODE_OFFSET) | 0x3;
-	msm_camera_io_w(temp, vpe_ctrl->vpebase + VPE_OP_MODE_OFFSET);
-
-	src_ROI_width = pcrop->src_w;
-	src_ROI_height = pcrop->src_h;
-	out_ROI_width = pcrop->dst_w;
-	out_ROI_height = pcrop->dst_h;
-
-	D("src w = 0x%x, h=0x%x, dst w = 0x%x, h =0x%x.\n",
-		src_ROI_width, src_ROI_height, out_ROI_width,
-		out_ROI_height);
-	src_roi = (src_ROI_height << 16) + src_ROI_width;
-
-	msm_camera_io_w(src_roi, vpe_ctrl->vpebase + VPE_SRC_SIZE_OFFSET);
-
-	src_x = pcrop->src_x;
-	src_y = pcrop->src_y;
-
-	D("src_x = %d, src_y=%d.\n", src_x, src_y);
-
-	src_xy = src_y*(1<<16) + src_x;
-	msm_camera_io_w(src_xy, vpe_ctrl->vpebase +
-			VPE_SRC_XY_OFFSET);
-	D("src_xy = %d, src_roi=%d.\n", src_xy, src_roi);
-
-	/* decide whether to use FIR or M/N for scaling */
-	if ((out_ROI_width == 1 && src_ROI_width < 4) ||
-		(src_ROI_width < 4 * out_ROI_width - 3))
-		scale_unit_sel_x = 0;/* use FIR scalar */
-	else
-		scale_unit_sel_x = 1;/* use M/N scalar */
-
-	if ((out_ROI_height == 1 && src_ROI_height < 4) ||
-		(src_ROI_height < 4 * out_ROI_height - 3))
-		scale_unit_sel_y = 0;/* use FIR scalar */
-	else
-		scale_unit_sel_y = 1;/* use M/N scalar */
-
-	/* calculate phase step for the x direction */
-
-	/* if destination is only 1 pixel wide,
-	the value of phase_step_x
-	is unimportant. Assigning phase_step_x to
-	src ROI width as an arbitrary value. */
-	if (out_ROI_width == 1)
-		phase_step_x = (uint32_t) ((src_ROI_width) <<
-						SCALER_PHASE_BITS);
-
-		/* if using FIR scalar */
-	else if (scale_unit_sel_x == 0) {
-
-		/* Calculate the quotient ( src_ROI_width - 1 )
-			( out_ROI_width - 1)
-			with u3.29 precision. Quotient is rounded up to
-			the larger 29th decimal point*/
-		numerator = (uint64_t)(src_ROI_width - 1) <<
-			SCALER_PHASE_BITS;
-		/* never equals to 0 because of the
-			"(out_ROI_width == 1 )"*/
-		denominator = (uint64_t)(out_ROI_width - 1);
-		/* divide and round up to the larger 29th
-			decimal point.*/
-		phase_step_x = (uint32_t) vpe_do_div((numerator +
-					denominator - 1), denominator);
-	} else if (scale_unit_sel_x == 1) { /* if M/N scalar */
-		/* Calculate the quotient ( src_ROI_width ) /
-			( out_ROI_width)
-			with u3.29 precision. Quotient is rounded down to the
-			smaller 29th decimal point.*/
-		numerator = (uint64_t)(src_ROI_width) <<
-			SCALER_PHASE_BITS;
-		denominator = (uint64_t)(out_ROI_width);
-		phase_step_x =
-			(uint32_t) vpe_do_div(numerator, denominator);
-	}
-	/* calculate phase step for the y direction */
-
-	/* if destination is only 1 pixel wide, the value of
-		phase_step_x is unimportant. Assigning phase_step_x
-		to src ROI width as an arbitrary value. */
-	if (out_ROI_height == 1)
-		phase_step_y =
-		(uint32_t) ((src_ROI_height) << SCALER_PHASE_BITS);
-
-	/* if FIR scalar */
-	else if (scale_unit_sel_y == 0) {
-		/* Calculate the quotient ( src_ROI_height - 1 ) /
-		( out_ROI_height - 1)
-		with u3.29 precision. Quotient is rounded up to the
-		larger 29th decimal point. */
-		numerator = (uint64_t)(src_ROI_height - 1) <<
-			SCALER_PHASE_BITS;
-		/* never equals to 0 because of the "
-		( out_ROI_height == 1 )" case */
-		denominator = (uint64_t)(out_ROI_height - 1);
-		/* Quotient is rounded up to the larger
-		29th decimal point. */
-		phase_step_y =
-		(uint32_t) vpe_do_div(
-			(numerator + denominator - 1), denominator);
-	} else if (scale_unit_sel_y == 1) { /* if M/N scalar */
-		/* Calculate the quotient ( src_ROI_height )
-			( out_ROI_height)
-			with u3.29 precision. Quotient is rounded down
-			to the smaller 29th decimal point. */
-		numerator = (uint64_t)(src_ROI_height) <<
-			SCALER_PHASE_BITS;
-		denominator = (uint64_t)(out_ROI_height);
-		phase_step_y = (uint32_t) vpe_do_div(
-			numerator, denominator);
-	}
-
-	/* decide which set of FIR coefficients to use */
-	if (phase_step_x > HAL_MDP_PHASE_STEP_2P50)
-		xscale_filter_sel = 0;
-	else if (phase_step_x > HAL_MDP_PHASE_STEP_1P66)
-		xscale_filter_sel = 1;
-	else if (phase_step_x > HAL_MDP_PHASE_STEP_1P25)
-		xscale_filter_sel = 2;
-	else
-		xscale_filter_sel = 3;
-
-	if (phase_step_y > HAL_MDP_PHASE_STEP_2P50)
-		yscale_filter_sel = 0;
-	else if (phase_step_y > HAL_MDP_PHASE_STEP_1P66)
-		yscale_filter_sel = 1;
-	else if (phase_step_y > HAL_MDP_PHASE_STEP_1P25)
-		yscale_filter_sel = 2;
-	else
-		yscale_filter_sel = 3;
-
-	/* calculate phase init for the x direction */
-
-	/* if using FIR scalar */
-	if (scale_unit_sel_x == 0) {
-		if (out_ROI_width == 1)
-			phase_init_x =
-				(uint32_t) ((src_ROI_width - 1) <<
-							SCALER_PHASE_BITS);
-		else
-			phase_init_x = 0;
-	} else if (scale_unit_sel_x == 1) /* M over N scalar  */
-		phase_init_x = 0;
-
-	/* calculate phase init for the y direction
-	if using FIR scalar */
-	if (scale_unit_sel_y == 0) {
-		if (out_ROI_height == 1)
-			phase_init_y =
-			(uint32_t) ((src_ROI_height -
-						1) << SCALER_PHASE_BITS);
-		else
-			phase_init_y = 0;
-	} else if (scale_unit_sel_y == 1) /* M over N scalar   */
-		phase_init_y = 0;
-
-	D("phase step x = %d, step y = %d.\n",
-		 phase_step_x, phase_step_y);
-	D("phase init x = %d, init y = %d.\n",
-		 phase_init_x, phase_init_y);
-
-	msm_camera_io_w(phase_step_x, vpe_ctrl->vpebase +
-			VPE_SCALE_PHASEX_STEP_OFFSET);
-	msm_camera_io_w(phase_step_y, vpe_ctrl->vpebase +
-			VPE_SCALE_PHASEY_STEP_OFFSET);
-
-	msm_camera_io_w(phase_init_x, vpe_ctrl->vpebase +
-			VPE_SCALE_PHASEX_INIT_OFFSET);
-
-	msm_camera_io_w(phase_init_y, vpe_ctrl->vpebase +
-			VPE_SCALE_PHASEY_INIT_OFFSET);
-
-	return 1;
-}
-
-int msm_vpe_is_busy(void)
-{
-	int busy = 0;
-	unsigned long flags;
-	spin_lock_irqsave(&vpe_ctrl->lock, flags);
-	if (vpe_ctrl->state == VPE_STATE_ACTIVE)
-		busy = 1;
-	spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
-	return busy;
-}
-
-static int msm_send_frame_to_vpe(void)
-{
-	int rc = 0;
-	unsigned long flags;
-	unsigned long srcP0, srcP1, outP0, outP1;
-	struct msm_mctl_pp_frame_info *frame_info = vpe_ctrl->pp_frame_info;
-
-	if (!frame_info) {
-		pr_err("%s Invalid frame", __func__);
-		return -EINVAL;
-	}
-
-	spin_lock_irqsave(&vpe_ctrl->lock, flags);
-
-	if (frame_info->src_frame.frame.num_planes > 1) {
-		srcP0 = frame_info->src_frame.map[0].paddr +
-			frame_info->src_frame.map[0].data_offset;
-		srcP1 = frame_info->src_frame.map[1].paddr +
-			frame_info->src_frame.map[1].data_offset;
-		outP0 = frame_info->dest_frame.map[0].paddr +
-			frame_info->dest_frame.map[0].data_offset;
-		outP1 = frame_info->dest_frame.map[1].paddr +
-			frame_info->dest_frame.map[1].data_offset;
-	} else {
-		srcP0 = frame_info->src_frame.map[0].paddr;
-		srcP1 = frame_info->src_frame.map[0].paddr +
-			frame_info->src_frame.map[0].data_offset;
-		outP0 = frame_info->dest_frame.map[0].paddr;
-		outP1 = frame_info->dest_frame.map[0].paddr +
-			frame_info->dest_frame.map[0].data_offset;
-	}
-
-	D("%s VPE Configured with Src %x, %x Dest %x, %x",
-		__func__, (uint32_t)srcP0, (uint32_t)srcP1,
-		(uint32_t)outP0, (uint32_t)outP1);
-
-	msm_camera_io_w(srcP0, vpe_ctrl->vpebase + VPE_SRCP0_ADDR_OFFSET);
-	msm_camera_io_w(srcP1, vpe_ctrl->vpebase + VPE_SRCP1_ADDR_OFFSET);
-	msm_camera_io_w(outP0, vpe_ctrl->vpebase + VPE_OUTP0_ADDR_OFFSET);
-	msm_camera_io_w(outP1, vpe_ctrl->vpebase + VPE_OUTP1_ADDR_OFFSET);
-
-	vpe_ctrl->state = VPE_STATE_ACTIVE;
-	spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
-	vpe_start();
-	return rc;
-}
-
-static void vpe_send_outmsg(void)
-{
-	unsigned long flags;
-	struct v4l2_event v4l2_evt;
-	struct msm_queue_cmd *event_qcmd;
-	spin_lock_irqsave(&vpe_ctrl->lock, flags);
-	if (vpe_ctrl->state == VPE_STATE_IDLE) {
-		pr_err("%s VPE is in IDLE state. Ignore the ack msg", __func__);
-		spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
-		return;
-	}
-	event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_ATOMIC);
-	atomic_set(&event_qcmd->on_heap, 1);
-	event_qcmd->command = (void *)vpe_ctrl->pp_frame_info;
-	vpe_ctrl->pp_frame_info = NULL;
-	vpe_ctrl->state = VPE_STATE_INIT;   /* put it back to idle. */
-
-	/* Enqueue the event payload. */
-	msm_enqueue(&vpe_ctrl->eventData_q, &event_qcmd->list_eventdata);
-	/* Now queue the event. */
-	v4l2_evt.type = V4L2_EVENT_PRIVATE_START + MSM_CAM_RESP_MCTL_PP_EVENT;
-	v4l2_evt.id = 0;
-	v4l2_event_queue(vpe_ctrl->subdev.devnode, &v4l2_evt);
-	spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
-}
-
-static void vpe_do_tasklet(unsigned long data)
-{
-	D("%s: irq_status = 0x%x",
-		   __func__, vpe_ctrl->irq_status);
-	if (vpe_ctrl->irq_status & 0x1)
-		vpe_send_outmsg();
-
-}
-DECLARE_TASKLET(vpe_tasklet, vpe_do_tasklet, 0);
-
-static irqreturn_t vpe_parse_irq(int irq_num, void *data)
-{
-	vpe_ctrl->irq_status = msm_camera_io_r_mb(vpe_ctrl->vpebase +
-							VPE_INTR_STATUS_OFFSET);
-	msm_camera_io_w_mb(vpe_ctrl->irq_status, vpe_ctrl->vpebase +
-				VPE_INTR_CLEAR_OFFSET);
-	msm_camera_io_w(0, vpe_ctrl->vpebase + VPE_INTR_ENABLE_OFFSET);
-	D("%s: vpe_parse_irq =0x%x.\n", __func__, vpe_ctrl->irq_status);
-	tasklet_schedule(&vpe_tasklet);
-	return IRQ_HANDLED;
-}
-
-static struct msm_cam_clk_info vpe_clk_info[] = {
-	{"vpe_clk", 160000000},
-	{"vpe_pclk", -1},
-};
-
-int vpe_enable(uint32_t clk_rate, struct msm_cam_media_controller *mctl)
-{
-	int rc = 0;
-	unsigned long flags = 0;
-	D("%s", __func__);
-	/* don't change the order of clock and irq.*/
-	spin_lock_irqsave(&vpe_ctrl->lock, flags);
-	if (vpe_ctrl->state != VPE_STATE_IDLE) {
-		pr_err("%s: VPE already enabled", __func__);
-		spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
-		return 0;
-	}
-	vpe_ctrl->state = VPE_STATE_INIT;
-	spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
-	enable_irq(vpe_ctrl->vpeirq->start);
-
-	if (vpe_ctrl->fs_vpe) {
-		rc = regulator_enable(vpe_ctrl->fs_vpe);
-		if (rc) {
-			pr_err("%s: Regulator enable failed\n", __func__);
-			goto vpe_fs_failed;
-		}
-	}
-
-	rc = msm_cam_clk_enable(&vpe_ctrl->pdev->dev, vpe_clk_info,
-			vpe_ctrl->vpe_clk, ARRAY_SIZE(vpe_clk_info), 1);
-	if (rc < 0)
-		goto vpe_clk_failed;
-
-#ifdef CONFIG_MSM_IOMMU
-	rc = iommu_attach_device(mctl->domain, vpe_ctrl->iommu_ctx_src);
-	if (rc < 0) {
-		pr_err("%s: Device attach failed\n", __func__);
-		goto src_attach_failed;
-	}
-	rc = iommu_attach_device(mctl->domain, vpe_ctrl->iommu_ctx_dst);
-	if (rc < 0) {
-		pr_err("%s: Device attach failed\n", __func__);
-		goto dst_attach_failed;
-	}
-#endif
-	return rc;
-
-#ifdef CONFIG_MSM_IOMMU
-dst_attach_failed:
-	iommu_detach_device(mctl->domain, vpe_ctrl->iommu_ctx_src);
-src_attach_failed:
-#endif
-	msm_cam_clk_enable(&vpe_ctrl->pdev->dev, vpe_clk_info,
-		vpe_ctrl->vpe_clk, ARRAY_SIZE(vpe_clk_info), 0);
-vpe_clk_failed:
-	if (vpe_ctrl->fs_vpe)
-		regulator_disable(vpe_ctrl->fs_vpe);
-vpe_fs_failed:
-	disable_irq(vpe_ctrl->vpeirq->start);
-	vpe_ctrl->state = VPE_STATE_IDLE;
-	return rc;
-}
-
-int vpe_disable(struct msm_cam_media_controller *mctl)
-{
-	int rc = 0;
-	unsigned long flags = 0;
-	D("%s", __func__);
-	spin_lock_irqsave(&vpe_ctrl->lock, flags);
-	if (vpe_ctrl->state == VPE_STATE_IDLE) {
-		D("%s: VPE already disabled", __func__);
-		spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
-		return rc;
-	}
-	spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
-#ifdef CONFIG_MSM_IOMMU
-	iommu_detach_device(mctl->domain, vpe_ctrl->iommu_ctx_dst);
-	iommu_detach_device(mctl->domain, vpe_ctrl->iommu_ctx_src);
-#endif
-	disable_irq(vpe_ctrl->vpeirq->start);
-	tasklet_kill(&vpe_tasklet);
-	msm_cam_clk_enable(&vpe_ctrl->pdev->dev, vpe_clk_info,
-			vpe_ctrl->vpe_clk, ARRAY_SIZE(vpe_clk_info), 0);
-
-	regulator_disable(vpe_ctrl->fs_vpe);
-	spin_lock_irqsave(&vpe_ctrl->lock, flags);
-	vpe_ctrl->state = VPE_STATE_IDLE;
-	spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
-	return rc;
-}
-
-static int msm_vpe_do_pp(struct msm_mctl_pp_frame_info *pp_frame_info)
-{
-	int rc = 0;
-	unsigned long flags;
-
-	spin_lock_irqsave(&vpe_ctrl->lock, flags);
-	if (vpe_ctrl->state == VPE_STATE_ACTIVE ||
-		 vpe_ctrl->state == VPE_STATE_IDLE) {
-		spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
-		pr_err(" =====VPE in wrong state:%d!!!  Wrong!========\n",
-		vpe_ctrl->state);
-		return -EBUSY;
-	}
-	spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
-	vpe_ctrl->pp_frame_info = pp_frame_info;
-	msm_vpe_cfg_update(
-		&vpe_ctrl->pp_frame_info->pp_frame_cmd.crop);
-	D("%s Sending frame idx %d id %d to VPE ", __func__,
-		pp_frame_info->src_frame.frame.buf_idx,
-		pp_frame_info->src_frame.frame.frame_id);
-	rc = msm_send_frame_to_vpe();
-	return rc;
-}
-
-static int msm_vpe_resource_init(void);
-
-int msm_vpe_subdev_init(struct v4l2_subdev *sd)
-{
-	int rc = 0;
-	struct msm_cam_media_controller *mctl;
-	mctl = v4l2_get_subdev_hostdata(sd);
-	D("%s:begin", __func__);
-	if (atomic_read(&vpe_init_done)) {
-		pr_err("%s: VPE has been initialized", __func__);
-		return -EBUSY;
-	}
-	atomic_set(&vpe_init_done, 1);
-
-	rc = msm_vpe_resource_init();
-	if (rc < 0) {
-		atomic_set(&vpe_init_done, 0);
-		return rc;
-	}
-	spin_lock_init(&vpe_ctrl->lock);
-	D("%s:end", __func__);
-	return rc;
-}
-EXPORT_SYMBOL(msm_vpe_subdev_init);
-
-static int msm_vpe_resource_init(void)
-{
-	int rc = 0;
-
-	vpe_ctrl->vpebase = ioremap(vpe_ctrl->vpemem->start,
-		resource_size(vpe_ctrl->vpemem));
-
-	if (!vpe_ctrl->vpebase) {
-		rc = -ENOMEM;
-		pr_err("%s: vpe ioremap failed\n", __func__);
-		goto vpe_unmap_mem_region;
-	}
-
-	return rc;
-/* from this part it is error handling. */
-vpe_unmap_mem_region:
-	iounmap(vpe_ctrl->vpebase);
-	vpe_ctrl->vpebase = NULL;
-	return rc;  /* this rc should have error code. */
-}
-
-void msm_vpe_subdev_release(struct v4l2_subdev *sd)
-{
-	struct msm_cam_media_controller *mctl;
-	mctl = v4l2_get_subdev_hostdata(sd);
-	if (!atomic_read(&vpe_init_done)) {
-		/* no VPE object created */
-		pr_err("%s: no VPE object to release", __func__);
-		return;
-	}
-	vpe_reset();
-	vpe_disable(mctl);
-	iounmap(vpe_ctrl->vpebase);
-	vpe_ctrl->vpebase = NULL;
-	atomic_set(&vpe_init_done, 0);
-}
-EXPORT_SYMBOL(msm_vpe_subdev_release);
-
-static int msm_vpe_process_vpe_cmd(struct msm_vpe_cfg_cmd *vpe_cmd,
-				struct msm_cam_media_controller *mctl)
-{
-	int rc = 0;
-
-	switch (vpe_cmd->cmd_type) {
-	case VPE_CMD_RESET:
-		rc = vpe_reset();
-		break;
-
-	case VPE_CMD_OPERATION_MODE_CFG: {
-		struct msm_vpe_op_mode_cfg op_mode_cfg;
-		if (sizeof(struct msm_vpe_op_mode_cfg) != vpe_cmd->length) {
-			pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d",
-				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
-				sizeof(struct msm_vpe_op_mode_cfg));
-			rc = -EINVAL;
-			break;
-		}
-		COPY_FROM_USER(rc, &op_mode_cfg, (void __user *)vpe_cmd->value,
-			sizeof(op_mode_cfg));
-		if (rc) {
-			ERR_COPY_FROM_USER();
-			break;
-		}
-
-		vpe_cmd->value = (void *)&op_mode_cfg;
-		rc = vpe_operation_config(vpe_cmd->value);
-		break;
-		}
-
-	case VPE_CMD_INPUT_PLANE_CFG: {
-		struct msm_vpe_input_plane_cfg input_cfg;
-		if (sizeof(struct msm_vpe_input_plane_cfg) != vpe_cmd->length) {
-			pr_err("%s: mismatch cmd = %d, len = %d, expected = %d",
-				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
-				sizeof(struct msm_vpe_input_plane_cfg));
-			rc = -EINVAL;
-			break;
-		}
-		COPY_FROM_USER(rc, &input_cfg, (void __user *)vpe_cmd->value,
-			sizeof(input_cfg));
-		if (rc) {
-			ERR_COPY_FROM_USER();
-			break;
-		}
-
-		vpe_cmd->value = (void *)&input_cfg;
-		vpe_input_plane_config(vpe_cmd->value);
-		break;
-		}
-
-	case VPE_CMD_OUTPUT_PLANE_CFG: {
-		struct msm_vpe_output_plane_cfg output_cfg;
-		if (sizeof(struct msm_vpe_output_plane_cfg) !=
-			vpe_cmd->length) {
-			pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d",
-				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
-				sizeof(struct msm_vpe_output_plane_cfg));
-				rc = -EINVAL;
-				break;
-		}
-		COPY_FROM_USER(rc, &output_cfg, (void __user *)vpe_cmd->value,
-			sizeof(output_cfg));
-		if (rc) {
-			ERR_COPY_FROM_USER();
-			break;
-		}
-
-		vpe_cmd->value = (void *)&output_cfg;
-		vpe_output_plane_config(vpe_cmd->value);
-		break;
-		}
-
-	case VPE_CMD_SCALE_CFG_TYPE:{
-		struct msm_vpe_scaler_cfg scaler_cfg;
-		if (sizeof(struct msm_vpe_scaler_cfg) != vpe_cmd->length) {
-			pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d",
-				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
-				sizeof(struct msm_vpe_scaler_cfg));
-			rc = -EINVAL;
-			break;
-		}
-		COPY_FROM_USER(rc, &scaler_cfg, (void __user *)vpe_cmd->value,
-			sizeof(scaler_cfg));
-		if (rc) {
-			ERR_COPY_FROM_USER();
-			break;
-		}
-
-		vpe_cmd->value = (void *)&scaler_cfg;
-		vpe_update_scale_coef(vpe_cmd->value);
-		break;
-		}
-
-	case VPE_CMD_ZOOM: {
-		struct msm_mctl_pp_frame_info *zoom;
-		zoom = kmalloc(sizeof(struct msm_mctl_pp_frame_info),
-				GFP_ATOMIC);
-		if (!zoom) {
-			pr_err("%s Not enough memory ", __func__);
-			rc = -ENOMEM;
-			break;
-		}
-
-		if (sizeof(zoom->pp_frame_cmd) != vpe_cmd->length) {
-			pr_err("%s: size mismatch id=%d, len=%d, expected=%d",
-				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
-				sizeof(zoom->pp_frame_cmd));
-			rc = -EINVAL;
-			kfree(zoom);
-			break;
-		}
-		COPY_FROM_USER(rc, &zoom->pp_frame_cmd,
-			(void __user *)vpe_cmd->value,
-			sizeof(zoom->pp_frame_cmd));
-		if (rc) {
-			ERR_COPY_FROM_USER();
-			kfree(zoom);
-			break;
-		}
-
-		zoom->user_cmd = vpe_cmd->cmd_type;
-		zoom->p_mctl = v4l2_get_subdev_hostdata(&vpe_ctrl->subdev);
-		D("%s: cookie=0x%x,action=0x%x,path=0x%x",
-			__func__, zoom->pp_frame_cmd.cookie,
-			zoom->pp_frame_cmd.vpe_output_action,
-			zoom->pp_frame_cmd.path);
-
-		D("%s Mapping Source frame ", __func__);
-		zoom->src_frame.frame = zoom->pp_frame_cmd.src_frame;
-		rc = msm_mctl_map_user_frame(&zoom->src_frame,
-			zoom->p_mctl->client, mctl->domain_num);
-		if (rc < 0) {
-			pr_err("%s Error mapping source buffer rc = %d",
-				__func__, rc);
-			kfree(zoom);
-			break;
-		}
-
-		D("%s Mapping Destination frame ", __func__);
-		zoom->dest_frame.frame = zoom->pp_frame_cmd.dest_frame;
-		rc = msm_mctl_map_user_frame(&zoom->dest_frame,
-			zoom->p_mctl->client, mctl->domain_num);
-		if (rc < 0) {
-			pr_err("%s Error mapping dest buffer rc = %d",
-				__func__, rc);
-			msm_mctl_unmap_user_frame(&zoom->src_frame,
-				zoom->p_mctl->client, mctl->domain_num);
-			kfree(zoom);
-			break;
-		}
-
-		rc = msm_vpe_do_pp(zoom);
-		break;
-		}
-
-	case VPE_CMD_ENABLE: {
-		struct msm_vpe_clock_rate clk_rate;
-		int turbo_mode;
-		if (sizeof(struct msm_vpe_clock_rate) != vpe_cmd->length) {
-			pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d",
-				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
-				sizeof(struct msm_vpe_clock_rate));
-			rc = -EINVAL;
-			break;
-		}
-		if (copy_from_user(&clk_rate, (void __user *)vpe_cmd->value,
-			sizeof(struct msm_vpe_clock_rate))) {
-			pr_err("%s:clk_rate copy failed", __func__);
-			return -EFAULT;
-		}
-		turbo_mode = (int)clk_rate.rate;
-		rc = turbo_mode ? vpe_enable(VPE_TURBO_MODE_CLOCK_RATE, mctl) :
-				vpe_enable(VPE_NORMAL_MODE_CLOCK_RATE, mctl);
-		break;
-		}
-
-	case VPE_CMD_DISABLE:
-		rc = vpe_disable(mctl);
-		break;
-
-	default:
-		break;
-	}
-
-	return rc;
-}
-
-static long msm_vpe_subdev_ioctl(struct v4l2_subdev *sd,
-			unsigned int cmd, void *arg)
-{
-	struct msm_vpe_cfg_cmd *vpe_cmd;
-	int rc = 0;
-	struct msm_cam_media_controller *mctl;
-	mctl = v4l2_get_subdev_hostdata(sd);
-	switch (cmd) {
-	case VIDIOC_MSM_VPE_INIT: {
-		msm_vpe_subdev_init(sd);
-		break;
-		}
-
-	case VIDIOC_MSM_VPE_RELEASE:
-		msm_vpe_subdev_release(sd);
-		break;
-
-	case MSM_CAM_V4L2_IOCTL_CFG_VPE: {
-		vpe_cmd = (struct msm_vpe_cfg_cmd *)arg;
-		rc = msm_vpe_process_vpe_cmd(vpe_cmd, mctl);
-		if (rc < 0) {
-			pr_err("%s Error processing VPE cmd %d ",
-				__func__, vpe_cmd->cmd_type);
-			break;
-		}
-		break;
-		}
-
-	case MSM_CAM_V4L2_IOCTL_GET_EVENT_PAYLOAD: {
-		struct msm_device_queue *queue = &vpe_ctrl->eventData_q;
-		struct msm_queue_cmd *event_qcmd;
-		struct msm_mctl_pp_event_info pp_event_info;
-		struct msm_mctl_pp_frame_info *pp_frame_info;
-		struct msm_camera_v4l2_ioctl_t *v4l2_ioctl = arg;
-
-		event_qcmd = msm_dequeue(queue, list_eventdata);
-		if (!event_qcmd) {
-			pr_err("%s No events in the queue", __func__);
-			return -EFAULT;
-		}
-		pp_frame_info = event_qcmd->command;
-
-		D("%s Unmapping source and destination buffers ",
-			__func__);
-		msm_mctl_unmap_user_frame(&pp_frame_info->src_frame,
-			pp_frame_info->p_mctl->client, mctl->domain_num);
-		msm_mctl_unmap_user_frame(&pp_frame_info->dest_frame,
-			pp_frame_info->p_mctl->client, mctl->domain_num);
-
-		pp_event_info.event = MCTL_PP_EVENT_CMD_ACK;
-		pp_event_info.ack.cmd = pp_frame_info->user_cmd;
-		pp_event_info.ack.status = 0;
-		pp_event_info.ack.cookie = pp_frame_info->pp_frame_cmd.cookie;
-		D("%s Sending payload %d %d %d", __func__,
-			pp_event_info.ack.cmd, pp_event_info.ack.status,
-			pp_event_info.ack.cookie);
-		if (copy_to_user((void __user *)v4l2_ioctl->ioctl_ptr,
-			&pp_event_info,	sizeof(struct msm_mctl_pp_event_info)))
-			pr_err("%s PAYLOAD Copy to user failed ", __func__);
-
-		kfree(pp_frame_info);
-		kfree(event_qcmd);
-		break;
-		}
-
-	default:
-		break;
-	}
-	return rc;
-}
-
-int msm_vpe_subdev_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
-	struct v4l2_event_subscription *sub)
-{
-	D("%s E\n", __func__);
-	return v4l2_event_subscribe(fh, sub, VPE_SUBDEV_MAX_EVENTS);
-}
-
-int msm_vpe_subdev_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
-	struct v4l2_event_subscription *sub)
-{
-	D("%s E\n", __func__);
-	return v4l2_event_unsubscribe(fh, sub);
-}
-
-static const struct v4l2_subdev_core_ops msm_vpe_subdev_core_ops = {
-	.ioctl = msm_vpe_subdev_ioctl,
-	.subscribe_event = msm_vpe_subdev_subscribe_event,
-	.unsubscribe_event = msm_vpe_subdev_unsubscribe_event,
-};
-
-static const struct v4l2_subdev_ops msm_vpe_subdev_ops = {
-	.core = &msm_vpe_subdev_core_ops,
-};
-
-static int msm_vpe_subdev_open(struct v4l2_subdev *sd,
-	struct v4l2_subdev_fh *fh)
-{
-	struct vpe_ctrl_type *vpe_ctrl = v4l2_get_subdevdata(sd);
-	/* Only one client of VPE allowed. */
-	if (atomic_read(&vpe_ctrl->active) != 0) {
-		pr_err("%s already opened\n", __func__);
-		return -EINVAL;
-	}
-
-	D("%s E ", __func__);
-	atomic_inc(&vpe_ctrl->active);
-	return 0;
-}
-
-static int msm_vpe_subdev_close(struct v4l2_subdev *sd,
-	struct v4l2_subdev_fh *fh)
-{
-	struct vpe_ctrl_type *vpe_ctrl = v4l2_get_subdevdata(sd);
-	struct msm_mctl_pp_frame_info *frame_info = vpe_ctrl->pp_frame_info;
-	struct msm_cam_media_controller *mctl;
-	mctl = v4l2_get_subdev_hostdata(sd);
-	if (atomic_read(&vpe_ctrl->active) == 0) {
-		pr_err("%s already closed\n", __func__);
-		return -EINVAL;
-	}
-
-	D("%s E ", __func__);
-	if (frame_info) {
-		D("%s Unmap the pending item from the queue ", __func__);
-		msm_mctl_unmap_user_frame(&frame_info->src_frame,
-			frame_info->p_mctl->client, mctl->domain_num);
-		msm_mctl_unmap_user_frame(&frame_info->dest_frame,
-			frame_info->p_mctl->client, mctl->domain_num);
-	}
-	/* Drain the payload queue. */
-	msm_queue_drain(&vpe_ctrl->eventData_q, list_eventdata);
-	atomic_dec(&vpe_ctrl->active);
-	return 0;
-}
-
-static const struct v4l2_subdev_internal_ops msm_vpe_internal_ops = {
-	.open = msm_vpe_subdev_open,
-	.close = msm_vpe_subdev_close,
-};
-
-static int __devinit msm_vpe_probe(struct platform_device *pdev)
-{
-	int rc = 0;
-	struct msm_cam_subdev_info sd_info;
-
-	D("%s: device id = %d\n", __func__, pdev->id);
-	vpe_ctrl = kzalloc(sizeof(struct vpe_ctrl_type), GFP_KERNEL);
-	if (!vpe_ctrl) {
-		pr_err("%s: not enough memory\n", __func__);
-		return -ENOMEM;
-	}
-
-	v4l2_subdev_init(&vpe_ctrl->subdev, &msm_vpe_subdev_ops);
-	v4l2_set_subdevdata(&vpe_ctrl->subdev, vpe_ctrl);
-	vpe_ctrl->subdev.internal_ops = &msm_vpe_internal_ops;
-	vpe_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-	snprintf(vpe_ctrl->subdev.name, sizeof(vpe_ctrl->subdev.name), "vpe");
-	platform_set_drvdata(pdev, &vpe_ctrl->subdev);
-
-	media_entity_init(&vpe_ctrl->subdev.entity, 0, NULL, 0);
-	vpe_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
-	vpe_ctrl->subdev.entity.group_id = VPE_DEV;
-	vpe_ctrl->subdev.entity.name = vpe_ctrl->subdev.name;
-
-	vpe_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_EVENTS;
-
-	vpe_ctrl->vpemem = platform_get_resource_byname(pdev,
-					IORESOURCE_MEM, "vpe");
-	if (!vpe_ctrl->vpemem) {
-		pr_err("%s: no mem resource?\n", __func__);
-		rc = -ENODEV;
-		goto vpe_no_resource;
-	}
-	vpe_ctrl->vpeirq = platform_get_resource_byname(pdev,
-					IORESOURCE_IRQ, "vpe");
-	if (!vpe_ctrl->vpeirq) {
-		pr_err("%s: no irq resource?\n", __func__);
-		rc = -ENODEV;
-		goto vpe_no_resource;
-	}
-
-	vpe_ctrl->vpeio = request_mem_region(vpe_ctrl->vpemem->start,
-		resource_size(vpe_ctrl->vpemem), pdev->name);
-	if (!vpe_ctrl->vpeio) {
-		pr_err("%s: no valid mem region\n", __func__);
-		rc = -EBUSY;
-		goto vpe_no_resource;
-	}
-
-	rc = request_irq(vpe_ctrl->vpeirq->start, vpe_parse_irq,
-		IRQF_TRIGGER_RISING, "vpe", 0);
-	if (rc < 0) {
-		release_mem_region(vpe_ctrl->vpemem->start,
-			resource_size(vpe_ctrl->vpemem));
-		pr_err("%s: irq request fail\n", __func__);
-		rc = -EBUSY;
-		goto vpe_no_resource;
-	}
-
-	vpe_ctrl->fs_vpe = regulator_get(&pdev->dev, "vdd");
-	if (IS_ERR(vpe_ctrl->fs_vpe)) {
-		pr_err("%s: Regulator FS_VPE get failed %ld\n", __func__,
-			PTR_ERR(vpe_ctrl->fs_vpe));
-		vpe_ctrl->fs_vpe = NULL;
-	}
-
-	disable_irq(vpe_ctrl->vpeirq->start);
-
-#ifdef CONFIG_MSM_IOMMU
-	/*get device context for IOMMU*/
-	vpe_ctrl->iommu_ctx_src = msm_iommu_get_ctx("vpe_src"); /*re-confirm*/
-	vpe_ctrl->iommu_ctx_dst = msm_iommu_get_ctx("vpe_dst"); /*re-confirm*/
-	if (!vpe_ctrl->iommu_ctx_src || !vpe_ctrl->iommu_ctx_dst) {
-		release_mem_region(vpe_ctrl->vpemem->start,
-			resource_size(vpe_ctrl->vpemem));
-		pr_err("%s: No iommu fw context found\n", __func__);
-		rc = -ENODEV;
-		goto vpe_no_resource;
-	}
-#endif
-
-	atomic_set(&vpe_ctrl->active, 0);
-	vpe_ctrl->pdev = pdev;
-	sd_info.sdev_type = VPE_DEV;
-	sd_info.sd_index = pdev->id;
-	sd_info.irq_num = vpe_ctrl->vpeirq->start;
-	msm_cam_register_subdev_node(&vpe_ctrl->subdev, &sd_info);
-	vpe_ctrl->subdev.entity.revision = vpe_ctrl->subdev.devnode->num;
-	msm_queue_init(&vpe_ctrl->eventData_q, "ackevents");
-
-	return 0;
-
-vpe_no_resource:
-	pr_err("%s: VPE Probe failed.\n", __func__);
-	kfree(vpe_ctrl);
-	return rc;
-}
-
-struct platform_driver msm_vpe_driver = {
-	.probe = msm_vpe_probe,
-	.driver = {
-		.name = MSM_VPE_DRV_NAME,
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init msm_vpe_init_module(void)
-{
-	return platform_driver_register(&msm_vpe_driver);
-}
-
-static void __exit msm_vpe_exit_module(void)
-{
-	platform_driver_unregister(&msm_vpe_driver);
-}
-
-module_init(msm_vpe_init_module);
-module_exit(msm_vpe_exit_module);
-MODULE_DESCRIPTION("VPE driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/msm_vpe.h b/drivers/media/video/msm/msm_vpe.h
deleted file mode 100644
index aad2380..0000000
--- a/drivers/media/video/msm/msm_vpe.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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 _MSM_VPE_H_
-#define _MSM_VPE_H_
-
-#include <mach/camera.h>
-
-/***********  start of register offset *********************/
-#define VPE_INTR_ENABLE_OFFSET                0x0020
-#define VPE_INTR_STATUS_OFFSET                0x0024
-#define VPE_INTR_CLEAR_OFFSET                 0x0028
-#define VPE_DL0_START_OFFSET                  0x0030
-#define VPE_HW_VERSION_OFFSET                 0x0070
-#define VPE_SW_RESET_OFFSET                   0x0074
-#define VPE_AXI_RD_ARB_CONFIG_OFFSET          0x0078
-#define VPE_SEL_CLK_OR_HCLK_TEST_BUS_OFFSET   0x007C
-#define VPE_CGC_EN_OFFSET                     0x0100
-#define VPE_CMD_STATUS_OFFSET                 0x10008
-#define VPE_PROFILE_EN_OFFSET                 0x10010
-#define VPE_PROFILE_COUNT_OFFSET              0x10014
-#define VPE_CMD_MODE_OFFSET                   0x10060
-#define VPE_SRC_SIZE_OFFSET                   0x10108
-#define VPE_SRCP0_ADDR_OFFSET                 0x1010C
-#define VPE_SRCP1_ADDR_OFFSET                 0x10110
-#define VPE_SRC_YSTRIDE1_OFFSET               0x1011C
-#define VPE_SRC_FORMAT_OFFSET                 0x10124
-#define VPE_SRC_UNPACK_PATTERN1_OFFSET        0x10128
-#define VPE_OP_MODE_OFFSET                    0x10138
-#define VPE_SCALE_PHASEX_INIT_OFFSET          0x1013C
-#define VPE_SCALE_PHASEY_INIT_OFFSET          0x10140
-#define VPE_SCALE_PHASEX_STEP_OFFSET          0x10144
-#define VPE_SCALE_PHASEY_STEP_OFFSET          0x10148
-#define VPE_OUT_FORMAT_OFFSET                 0x10150
-#define VPE_OUT_PACK_PATTERN1_OFFSET          0x10154
-#define VPE_OUT_SIZE_OFFSET                   0x10164
-#define VPE_OUTP0_ADDR_OFFSET                 0x10168
-#define VPE_OUTP1_ADDR_OFFSET                 0x1016C
-#define VPE_OUT_YSTRIDE1_OFFSET               0x10178
-#define VPE_OUT_XY_OFFSET                     0x1019C
-#define VPE_SRC_XY_OFFSET                     0x10200
-#define VPE_SRC_IMAGE_SIZE_OFFSET             0x10208
-#define VPE_SCALE_CONFIG_OFFSET               0x10230
-#define VPE_DEINT_STATUS_OFFSET               0x30000
-#define VPE_DEINT_DECISION_OFFSET             0x30004
-#define VPE_DEINT_COEFF0_OFFSET               0x30010
-#define VPE_SCALE_STATUS_OFFSET               0x50000
-#define VPE_SCALE_SVI_PARAM_OFFSET            0x50010
-#define VPE_SCALE_SHARPEN_CFG_OFFSET          0x50020
-#define VPE_SCALE_COEFF_LSP_0_OFFSET          0x50400
-#define VPE_SCALE_COEFF_MSP_0_OFFSET          0x50404
-
-#define VPE_AXI_ARB_1_OFFSET                  0x00408
-#define VPE_AXI_ARB_2_OFFSET                  0x0040C
-
-#define VPE_SCALE_COEFF_LSBn(n)	(0x50400 + 8 * (n))
-#define VPE_SCALE_COEFF_MSBn(n)	(0x50404 + 8 * (n))
-#define VPE_SCALE_COEFF_NUM			32
-
-/*********** end of register offset ********************/
-
-
-#define VPE_HARDWARE_VERSION          0x00080308
-#define VPE_SW_RESET_VALUE            0x00000010  /* bit 4 for PPP*/
-#define VPE_AXI_RD_ARB_CONFIG_VALUE   0x124924
-#define VPE_CMD_MODE_VALUE            0x1
-#define VPE_DEFAULT_OP_MODE_VALUE     0x40FC0004
-#define VPE_CGC_ENABLE_VALUE          0xffff
-#define VPE_DEFAULT_SCALE_CONFIG      0x3c
-
-#define VPE_NORMAL_MODE_CLOCK_RATE   150000000
-#define VPE_TURBO_MODE_CLOCK_RATE    200000000
-#define VPE_SUBDEV_MAX_EVENTS        30
-
-/**************************************************/
-/*********** End of command id ********************/
-/**************************************************/
-
-enum vpe_state {
-	VPE_STATE_IDLE,
-	VPE_STATE_INIT,
-	VPE_STATE_ACTIVE,
-};
-
-struct vpe_ctrl_type {
-	spinlock_t        lock;
-	uint32_t          irq_status;
-	void              *syncdata;
-	uint16_t          op_mode;
-	void              *extdata;
-	uint32_t          extlen;
-	struct msm_vpe_callback *resp;
-	uint32_t          out_h;  /* this is BEFORE rotation. */
-	uint32_t          out_w;  /* this is BEFORE rotation. */
-	struct timespec   ts;
-	int               output_type;
-	int               frame_pack;
-	uint8_t           pad_2k_bool;
-	enum vpe_state    state;
-	unsigned long     out_y_addr;
-	unsigned long     out_cbcr_addr;
-	struct v4l2_subdev subdev;
-	struct platform_device *pdev;
-	struct resource   *vpeirq;
-	void __iomem      *vpebase;
-	struct resource	  *vpemem;
-	struct resource   *vpeio;
-	void        *device_extdata;
-	struct regulator *fs_vpe;
-	struct clk	*vpe_clk[2];
-	struct msm_mctl_pp_frame_info *pp_frame_info;
-	atomic_t active;
-	struct msm_device_queue eventData_q; /*V4L2 Event Payload Queue*/
-	struct device *iommu_ctx_src;
-	struct device *iommu_ctx_dst;
-};
-
-/*
-* vpe_input_update
-*
-* Define the parameters for output plane
-*/
-/* this is the dimension of ROI.  width / height. */
-struct vpe_src_size_packed {
-	uint32_t        src_w;
-	uint32_t        src_h;
-};
-
-struct vpe_src_xy_packed {
-	uint32_t        src_x;
-	uint32_t        src_y;
-};
-
-struct vpe_input_plane_update_type {
-	struct vpe_src_size_packed             src_roi_size;
-	/* crop updates this set. */
-	struct vpe_src_xy_packed               src_roi_offset;
-	/* input address*/
-	uint8_t                         *src_p0_addr;
-	uint8_t                         *src_p1_addr;
-};
-
-struct vpe_msg_stats {
-	uint32_t    buffer;
-	uint32_t    frameCounter;
-};
-
-struct vpe_msg_output {
-	uint8_t   output_id;
-	uint32_t  yBuffer;
-	uint32_t  cbcrBuffer;
-	uint32_t  frameCounter;
-};
-
-struct vpe_message {
-	uint8_t  _d;
-	union {
-		struct vpe_msg_output              msgOut;
-		struct vpe_msg_stats               msgStats;
-	} _u;
-};
-
-#define SCALER_PHASE_BITS 29
-#define HAL_MDP_PHASE_STEP_2P50    0x50000000
-#define HAL_MDP_PHASE_STEP_1P66    0x35555555
-#define HAL_MDP_PHASE_STEP_1P25    0x28000000
-
-struct phase_val_t {
-	int32_t phase_init_x;
-	int32_t phase_init_y;
-	int32_t phase_step_x;
-	int32_t phase_step_y;
-};
-
-#endif /*_MSM_VPE_H_*/
-
diff --git a/drivers/media/video/msm/msm_vpe1.c b/drivers/media/video/msm/msm_vpe1.c
deleted file mode 100644
index df3630a..0000000
--- a/drivers/media/video/msm/msm_vpe1.c
+++ /dev/null
@@ -1,1469 +0,0 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. 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/uaccess.h>
-#include <linux/interrupt.h>
-#include <mach/irqs.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include "msm_vpe1.h"
-#include <linux/pm_qos.h>
-#include <linux/clk.h>
-#include <mach/clk.h>
-#include <asm/div64.h>
-
-static int vpe_enable(uint32_t);
-static int vpe_disable(void);
-static int vpe_update_scaler(struct video_crop_t *pcrop);
-static struct vpe_device_type  vpe_device_data;
-static struct vpe_device_type  *vpe_device;
-struct vpe_ctrl_type    *vpe_ctrl;
-char *vpe_general_cmd[] = {
-	"VPE_DUMMY_0",  /* 0 */
-	"VPE_SET_CLK",
-	"VPE_RESET",
-	"VPE_START",
-	"VPE_ABORT",
-	"VPE_OPERATION_MODE_CFG",  /* 5 */
-	"VPE_INPUT_PLANE_CFG",
-	"VPE_OUTPUT_PLANE_CFG",
-	"VPE_INPUT_PLANE_UPDATE",
-	"VPE_SCALE_CFG_TYPE",
-	"VPE_ROTATION_CFG_TYPE",  /* 10 */
-	"VPE_AXI_OUT_CFG",
-	"VPE_CMD_DIS_OFFSET_CFG",
-	"VPE_ENABLE",
-	"VPE_DISABLE",
-};
-static uint32_t orig_src_y, orig_src_cbcr;
-
-#define CHECKED_COPY_FROM_USER(in) {					\
-	if (copy_from_user((in), (void __user *)cmd->value,		\
-			cmd->length)) {					\
-		rc = -EFAULT;						\
-		break;							\
-	}								\
-}
-
-#define msm_dequeue_vpe(queue, member) ({			\
-	unsigned long flags;					\
-	struct msm_device_queue *__q = (queue);			\
-	struct msm_queue_cmd *qcmd = 0;				\
-	spin_lock_irqsave(&__q->lock, flags);			\
-	if (!list_empty(&__q->list)) {				\
-		__q->len--;					\
-		qcmd = list_first_entry(&__q->list,		\
-				struct msm_queue_cmd, member);	\
-		list_del_init(&qcmd->member);			\
-	}							\
-	spin_unlock_irqrestore(&__q->lock, flags);		\
-	qcmd;							\
-})
-
-/*
-static   struct vpe_cmd_type vpe_cmd[] = {
-		{VPE_DUMMY_0, 0},
-		{VPE_SET_CLK, 0},
-		{VPE_RESET, 0},
-		{VPE_START, 0},
-		{VPE_ABORT, 0},
-		{VPE_OPERATION_MODE_CFG, VPE_OPERATION_MODE_CFG_LEN},
-		{VPE_INPUT_PLANE_CFG, VPE_INPUT_PLANE_CFG_LEN},
-		{VPE_OUTPUT_PLANE_CFG, VPE_OUTPUT_PLANE_CFG_LEN},
-		{VPE_INPUT_PLANE_UPDATE, VPE_INPUT_PLANE_UPDATE_LEN},
-		{VPE_SCALE_CFG_TYPE, VPE_SCALER_CONFIG_LEN},
-		{VPE_ROTATION_CFG_TYPE, 0},
-		{VPE_AXI_OUT_CFG, 0},
-		{VPE_CMD_DIS_OFFSET_CFG, VPE_DIS_OFFSET_CFG_LEN},
-};
-*/
-
-static long long vpe_do_div(long long num, long long den)
-{
-	do_div(num, den);
-	return num;
-}
-
-static int vpe_start(void)
-{
-	/*  enable the frame irq, bit 0 = Display list 0 ROI done */
-	msm_camera_io_w(1, vpe_device->vpebase + VPE_INTR_ENABLE_OFFSET);
-	msm_camera_io_dump(vpe_device->vpebase + 0x10000, 0x250);
-	/* this triggers the operation. */
-	msm_camera_io_w(1, vpe_device->vpebase + VPE_DL0_START_OFFSET);
-
-	return 0;
-}
-
-void vpe_reset_state_variables(void)
-{
-	/* initialize local variables for state control, etc.*/
-	vpe_ctrl->op_mode = 0;
-	vpe_ctrl->state = VPE_STATE_INIT;
-	spin_lock_init(&vpe_ctrl->tasklet_lock);
-	spin_lock_init(&vpe_ctrl->state_lock);
-	INIT_LIST_HEAD(&vpe_ctrl->tasklet_q);
-}
-
-static void vpe_config_axi_default(void)
-{
-	msm_camera_io_w(0x25, vpe_device->vpebase + VPE_AXI_ARB_2_OFFSET);
-
-	CDBG("%s: yaddr %ld cbcraddr %ld", __func__,
-		 vpe_ctrl->out_y_addr, vpe_ctrl->out_cbcr_addr);
-
-	if (!vpe_ctrl->out_y_addr || !vpe_ctrl->out_cbcr_addr)
-		return;
-
-	msm_camera_io_w(vpe_ctrl->out_y_addr,
-		vpe_device->vpebase + VPE_OUTP0_ADDR_OFFSET);
-	/* for video  CbCr address */
-	msm_camera_io_w(vpe_ctrl->out_cbcr_addr,
-		vpe_device->vpebase + VPE_OUTP1_ADDR_OFFSET);
-
-}
-
-static int vpe_reset(void)
-{
-	uint32_t vpe_version;
-	uint32_t rc;
-
-	vpe_reset_state_variables();
-	vpe_version = msm_camera_io_r(
-			vpe_device->vpebase + VPE_HW_VERSION_OFFSET);
-	CDBG("vpe_version = 0x%x\n", vpe_version);
-
-	/* disable all interrupts.*/
-	msm_camera_io_w(0, vpe_device->vpebase + VPE_INTR_ENABLE_OFFSET);
-	/* clear all pending interrupts*/
-	msm_camera_io_w(0x1fffff, vpe_device->vpebase + VPE_INTR_CLEAR_OFFSET);
-
-	/* write sw_reset to reset the core. */
-	msm_camera_io_w(0x10, vpe_device->vpebase + VPE_SW_RESET_OFFSET);
-
-	/* then poll the reset bit, it should be self-cleared. */
-	while (1) {
-		rc = msm_camera_io_r(vpe_device->vpebase + VPE_SW_RESET_OFFSET)
-				& 0x10;
-		if (rc == 0)
-			break;
-	}
-
-	/*  at this point, hardware is reset. Then pogram to default
-		values. */
-	msm_camera_io_w(VPE_AXI_RD_ARB_CONFIG_VALUE,
-			vpe_device->vpebase + VPE_AXI_RD_ARB_CONFIG_OFFSET);
-
-	msm_camera_io_w(VPE_CGC_ENABLE_VALUE,
-			vpe_device->vpebase + VPE_CGC_EN_OFFSET);
-
-	msm_camera_io_w(1, vpe_device->vpebase + VPE_CMD_MODE_OFFSET);
-
-	msm_camera_io_w(VPE_DEFAULT_OP_MODE_VALUE,
-			vpe_device->vpebase + VPE_OP_MODE_OFFSET);
-
-	msm_camera_io_w(VPE_DEFAULT_SCALE_CONFIG,
-			vpe_device->vpebase + VPE_SCALE_CONFIG_OFFSET);
-
-	vpe_config_axi_default();
-	return 0;
-}
-
-int msm_vpe_cfg_update(void *pinfo)
-{
-	uint32_t  rot_flag, rc = 0;
-	struct video_crop_t *pcrop = (struct video_crop_t *)pinfo;
-
-	rot_flag = msm_camera_io_r(vpe_device->vpebase +
-						VPE_OP_MODE_OFFSET) & 0xE00;
-	if (pinfo != NULL) {
-		CDBG("Crop info in2_w = %d, in2_h = %d "
-			"out2_h = %d out2_w = %d \n", pcrop->in2_w,
-			pcrop->in2_h,
-			pcrop->out2_h, pcrop->out2_w);
-		rc = vpe_update_scaler(pcrop);
-	}
-	CDBG("return rc = %d rot_flag = %d\n", rc, rot_flag);
-	rc |= rot_flag;
-
-	return rc;
-}
-
-void vpe_update_scale_coef(uint32_t *p)
-{
-	uint32_t i, offset;
-	offset = *p;
-	for (i = offset; i < (VPE_SCALE_COEFF_NUM + offset); i++) {
-		msm_camera_io_w(*(++p),
-			vpe_device->vpebase + VPE_SCALE_COEFF_LSBn(i));
-		msm_camera_io_w(*(++p),
-			vpe_device->vpebase + VPE_SCALE_COEFF_MSBn(i));
-	}
-}
-
-void vpe_input_plane_config(uint32_t *p)
-{
-	msm_camera_io_w(*p,
-		vpe_device->vpebase + VPE_SRC_FORMAT_OFFSET);
-	msm_camera_io_w(*(++p),
-		vpe_device->vpebase + VPE_SRC_UNPACK_PATTERN1_OFFSET);
-	msm_camera_io_w(*(++p),
-		vpe_device->vpebase + VPE_SRC_IMAGE_SIZE_OFFSET);
-	msm_camera_io_w(*(++p),
-		vpe_device->vpebase + VPE_SRC_YSTRIDE1_OFFSET);
-	msm_camera_io_w(*(++p),
-		vpe_device->vpebase + VPE_SRC_SIZE_OFFSET);
-	vpe_ctrl->in_h_w = *p;
-	msm_camera_io_w(*(++p),
-		vpe_device->vpebase + VPE_SRC_XY_OFFSET);
-}
-
-void vpe_output_plane_config(uint32_t *p)
-{
-	msm_camera_io_w(*p,
-		vpe_device->vpebase + VPE_OUT_FORMAT_OFFSET);
-	msm_camera_io_w(*(++p),
-		vpe_device->vpebase + VPE_OUT_PACK_PATTERN1_OFFSET);
-	msm_camera_io_w(*(++p),
-		vpe_device->vpebase + VPE_OUT_YSTRIDE1_OFFSET);
-	msm_camera_io_w(*(++p),
-		vpe_device->vpebase + VPE_OUT_SIZE_OFFSET);
-	msm_camera_io_w(*(++p),
-		vpe_device->vpebase + VPE_OUT_XY_OFFSET);
-	vpe_ctrl->pcbcr_dis_offset = *(++p);
-}
-
-static int vpe_operation_config(uint32_t *p)
-{
-	uint32_t  outw, outh, temp;
-	msm_camera_io_w(*p, vpe_device->vpebase + VPE_OP_MODE_OFFSET);
-
-	temp = msm_camera_io_r(vpe_device->vpebase + VPE_OUT_SIZE_OFFSET);
-	outw = temp & 0xFFF;
-	outh = (temp & 0xFFF0000) >> 16;
-
-	if (*p++ & 0xE00) {
-		/* rotation enabled. */
-		vpe_ctrl->out_w = outh;
-		vpe_ctrl->out_h = outw;
-	} else {
-		vpe_ctrl->out_w = outw;
-		vpe_ctrl->out_h = outh;
-	}
-	vpe_ctrl->dis_en = *p;
-	return 0;
-}
-
-/* Later we can separate the rotation and scaler calc. If
-*  rotation is enabled, simply swap the destination dimension.
-*  And then pass the already swapped output size to this
-*  function. */
-static int vpe_update_scaler(struct video_crop_t *pcrop)
-{
-	uint32_t out_ROI_width, out_ROI_height;
-	uint32_t src_ROI_width, src_ROI_height;
-
-	uint32_t rc = 0;  /* default to no zoom. */
-	/*
-	* phase_step_x, phase_step_y, phase_init_x and phase_init_y
-	* are represented in fixed-point, unsigned 3.29 format
-	*/
-	uint32_t phase_step_x = 0;
-	uint32_t phase_step_y = 0;
-	uint32_t phase_init_x = 0;
-	uint32_t phase_init_y = 0;
-
-	uint32_t src_roi, src_x, src_y, src_xy, temp;
-	uint32_t yscale_filter_sel, xscale_filter_sel;
-	uint32_t scale_unit_sel_x, scale_unit_sel_y;
-	uint64_t numerator, denominator;
-
-	if ((pcrop->in2_w >= pcrop->out2_w) &&
-		(pcrop->in2_h >= pcrop->out2_h)) {
-		CDBG(" =======VPE no zoom needed.\n");
-
-		temp = msm_camera_io_r(vpe_device->vpebase + VPE_OP_MODE_OFFSET)
-		& 0xfffffffc;
-		msm_camera_io_w(temp, vpe_device->vpebase + VPE_OP_MODE_OFFSET);
-
-
-		msm_camera_io_w(0, vpe_device->vpebase + VPE_SRC_XY_OFFSET);
-
-		CDBG("vpe_ctrl->in_h_w = %d\n", vpe_ctrl->in_h_w);
-		msm_camera_io_w(vpe_ctrl->in_h_w , vpe_device->vpebase +
-				VPE_SRC_SIZE_OFFSET);
-
-		return rc;
-	}
-	/* If fall through then scaler is needed.*/
-
-	CDBG("========VPE zoom needed.\n");
-	/* assumption is both direction need zoom. this can be
-	improved. */
-	temp =
-		msm_camera_io_r(vpe_device->vpebase + VPE_OP_MODE_OFFSET) | 0x3;
-	msm_camera_io_w(temp, vpe_device->vpebase + VPE_OP_MODE_OFFSET);
-
-	src_ROI_width = pcrop->in2_w;
-	src_ROI_height = pcrop->in2_h;
-	out_ROI_width = pcrop->out2_w;
-	out_ROI_height = pcrop->out2_h;
-
-	CDBG("src w = 0x%x, h=0x%x, dst w = 0x%x, h =0x%x.\n",
-		src_ROI_width, src_ROI_height, out_ROI_width,
-		out_ROI_height);
-	src_roi = (src_ROI_height << 16) + src_ROI_width;
-
-	msm_camera_io_w(src_roi, vpe_device->vpebase + VPE_SRC_SIZE_OFFSET);
-
-	src_x = (out_ROI_width - src_ROI_width)/2;
-	src_y = (out_ROI_height - src_ROI_height)/2;
-
-	CDBG("src_x = %d, src_y=%d.\n", src_x, src_y);
-
-	src_xy = src_y*(1<<16) + src_x;
-	msm_camera_io_w(src_xy, vpe_device->vpebase +
-			VPE_SRC_XY_OFFSET);
-	CDBG("src_xy = %d, src_roi=%d.\n", src_xy, src_roi);
-
-	/* decide whether to use FIR or M/N for scaling */
-	if ((out_ROI_width == 1 && src_ROI_width < 4) ||
-		(src_ROI_width < 4 * out_ROI_width - 3))
-		scale_unit_sel_x = 0;/* use FIR scalar */
-	else
-		scale_unit_sel_x = 1;/* use M/N scalar */
-
-	if ((out_ROI_height == 1 && src_ROI_height < 4) ||
-		(src_ROI_height < 4 * out_ROI_height - 3))
-		scale_unit_sel_y = 0;/* use FIR scalar */
-	else
-		scale_unit_sel_y = 1;/* use M/N scalar */
-
-	/* calculate phase step for the x direction */
-
-	/* if destination is only 1 pixel wide,
-	the value of phase_step_x
-	is unimportant. Assigning phase_step_x to
-	src ROI width as an arbitrary value. */
-	if (out_ROI_width == 1)
-		phase_step_x = (uint32_t) ((src_ROI_width) <<
-						SCALER_PHASE_BITS);
-
-		/* if using FIR scalar */
-	else if (scale_unit_sel_x == 0) {
-
-		/* Calculate the quotient ( src_ROI_width - 1 )
-		/ ( out_ROI_width - 1)
-		with u3.29 precision. Quotient is rounded up to
-		the larger 29th decimal point. */
-		numerator = (uint64_t)(src_ROI_width - 1) <<
-			SCALER_PHASE_BITS;
-		/* never equals to 0 because of the
-		"(out_ROI_width == 1 )"*/
-		denominator = (uint64_t)(out_ROI_width - 1);
-		/* divide and round up to the larger 29th
-		decimal point. */
-		phase_step_x = (uint32_t) vpe_do_div((numerator +
-					denominator - 1), denominator);
-	} else if (scale_unit_sel_x == 1) { /* if M/N scalar */
-		/* Calculate the quotient ( src_ROI_width ) /
-		( out_ROI_width)
-		with u3.29 precision. Quotient is rounded down to the
-		smaller 29th decimal point. */
-		numerator = (uint64_t)(src_ROI_width) <<
-			SCALER_PHASE_BITS;
-		denominator = (uint64_t)(out_ROI_width);
-		phase_step_x =
-			(uint32_t) vpe_do_div(numerator, denominator);
-	}
-	/* calculate phase step for the y direction */
-
-	/* if destination is only 1 pixel wide, the value of
-		phase_step_x is unimportant. Assigning phase_step_x
-		to src ROI width as an arbitrary value. */
-	if (out_ROI_height == 1)
-		phase_step_y =
-		(uint32_t) ((src_ROI_height) << SCALER_PHASE_BITS);
-
-	/* if FIR scalar */
-	else if (scale_unit_sel_y == 0) {
-		/* Calculate the quotient ( src_ROI_height - 1 ) /
-		( out_ROI_height - 1)
-		with u3.29 precision. Quotient is rounded up to the
-		larger 29th decimal point. */
-		numerator = (uint64_t)(src_ROI_height - 1) <<
-			SCALER_PHASE_BITS;
-		/* never equals to 0 because of the "
-		( out_ROI_height == 1 )" case */
-		denominator = (uint64_t)(out_ROI_height - 1);
-		/* Quotient is rounded up to the larger
-		29th decimal point. */
-		phase_step_y =
-		(uint32_t) vpe_do_div(
-			(numerator + denominator - 1), denominator);
-	} else if (scale_unit_sel_y == 1) { /* if M/N scalar */
-		/* Calculate the quotient ( src_ROI_height )
-		/ ( out_ROI_height)
-		with u3.29 precision. Quotient is rounded down
-		to the smaller 29th decimal point. */
-		numerator = (uint64_t)(src_ROI_height) <<
-			SCALER_PHASE_BITS;
-		denominator = (uint64_t)(out_ROI_height);
-		phase_step_y = (uint32_t) vpe_do_div(
-			numerator, denominator);
-	}
-
-	/* decide which set of FIR coefficients to use */
-	if (phase_step_x > HAL_MDP_PHASE_STEP_2P50)
-		xscale_filter_sel = 0;
-	else if (phase_step_x > HAL_MDP_PHASE_STEP_1P66)
-		xscale_filter_sel = 1;
-	else if (phase_step_x > HAL_MDP_PHASE_STEP_1P25)
-		xscale_filter_sel = 2;
-	else
-		xscale_filter_sel = 3;
-
-	if (phase_step_y > HAL_MDP_PHASE_STEP_2P50)
-		yscale_filter_sel = 0;
-	else if (phase_step_y > HAL_MDP_PHASE_STEP_1P66)
-		yscale_filter_sel = 1;
-	else if (phase_step_y > HAL_MDP_PHASE_STEP_1P25)
-		yscale_filter_sel = 2;
-	else
-		yscale_filter_sel = 3;
-
-	/* calculate phase init for the x direction */
-
-	/* if using FIR scalar */
-	if (scale_unit_sel_x == 0) {
-		if (out_ROI_width == 1)
-			phase_init_x =
-				(uint32_t) ((src_ROI_width - 1) <<
-							SCALER_PHASE_BITS);
-		else
-			phase_init_x = 0;
-	} else if (scale_unit_sel_x == 1) /* M over N scalar  */
-		phase_init_x = 0;
-
-	/* calculate phase init for the y direction
-	if using FIR scalar */
-	if (scale_unit_sel_y == 0) {
-		if (out_ROI_height == 1)
-			phase_init_y =
-			(uint32_t) ((src_ROI_height -
-						1) << SCALER_PHASE_BITS);
-		else
-			phase_init_y = 0;
-	} else if (scale_unit_sel_y == 1) /* M over N scalar   */
-		phase_init_y = 0;
-
-	CDBG("phase step x = %d, step y = %d.\n",
-		 phase_step_x, phase_step_y);
-	CDBG("phase init x = %d, init y = %d.\n",
-		 phase_init_x, phase_init_y);
-
-	msm_camera_io_w(phase_step_x, vpe_device->vpebase +
-			VPE_SCALE_PHASEX_STEP_OFFSET);
-	msm_camera_io_w(phase_step_y, vpe_device->vpebase +
-			VPE_SCALE_PHASEY_STEP_OFFSET);
-
-	msm_camera_io_w(phase_init_x, vpe_device->vpebase +
-			VPE_SCALE_PHASEX_INIT_OFFSET);
-
-	msm_camera_io_w(phase_init_y, vpe_device->vpebase +
-			VPE_SCALE_PHASEY_INIT_OFFSET);
-
-	return 1;
-}
-
-static int vpe_update_scaler_with_dis(struct video_crop_t *pcrop,
-				struct dis_offset_type *dis_offset)
-{
-	uint32_t out_ROI_width, out_ROI_height;
-	uint32_t src_ROI_width, src_ROI_height;
-
-	uint32_t rc = 0;  /* default to no zoom. */
-	/*
-	* phase_step_x, phase_step_y, phase_init_x and phase_init_y
-	* are represented in fixed-point, unsigned 3.29 format
-	*/
-	uint32_t phase_step_x = 0;
-	uint32_t phase_step_y = 0;
-	uint32_t phase_init_x = 0;
-	uint32_t phase_init_y = 0;
-
-	uint32_t src_roi, temp;
-	int32_t  src_x, src_y, src_xy;
-	uint32_t yscale_filter_sel, xscale_filter_sel;
-	uint32_t scale_unit_sel_x, scale_unit_sel_y;
-	uint64_t numerator, denominator;
-	int32_t  zoom_dis_x, zoom_dis_y;
-
-	CDBG("%s: pcrop->in2_w = %d, pcrop->in2_h = %d\n", __func__,
-		 pcrop->in2_w, pcrop->in2_h);
-	CDBG("%s: pcrop->out2_w = %d, pcrop->out2_h = %d\n", __func__,
-		 pcrop->out2_w, pcrop->out2_h);
-
-	if ((pcrop->in2_w >= pcrop->out2_w) &&
-		(pcrop->in2_h >= pcrop->out2_h)) {
-		CDBG(" =======VPE no zoom needed, DIS is still enabled.\n");
-
-		temp = msm_camera_io_r(vpe_device->vpebase + VPE_OP_MODE_OFFSET)
-		& 0xfffffffc;
-		msm_camera_io_w(temp, vpe_device->vpebase + VPE_OP_MODE_OFFSET);
-
-		/* no zoom, use dis offset directly. */
-		src_xy = dis_offset->dis_offset_y * (1<<16) +
-			dis_offset->dis_offset_x;
-
-		msm_camera_io_w(src_xy,
-			vpe_device->vpebase + VPE_SRC_XY_OFFSET);
-
-		CDBG("vpe_ctrl->in_h_w = 0x%x\n", vpe_ctrl->in_h_w);
-		msm_camera_io_w(vpe_ctrl->in_h_w,
-			vpe_device->vpebase + VPE_SRC_SIZE_OFFSET);
-		return rc;
-	}
-	/* If fall through then scaler is needed.*/
-
-	CDBG("========VPE zoom needed + DIS enabled.\n");
-	/* assumption is both direction need zoom. this can be
-	 improved. */
-	temp = msm_camera_io_r(vpe_device->vpebase +
-					VPE_OP_MODE_OFFSET) | 0x3;
-	msm_camera_io_w(temp, vpe_device->vpebase +
-			VPE_OP_MODE_OFFSET);
-	zoom_dis_x = dis_offset->dis_offset_x *
-		pcrop->in2_w / pcrop->out2_w;
-	zoom_dis_y = dis_offset->dis_offset_y *
-		pcrop->in2_h / pcrop->out2_h;
-
-	src_x = zoom_dis_x + (pcrop->out2_w-pcrop->in2_w)/2;
-	src_y = zoom_dis_y + (pcrop->out2_h-pcrop->in2_h)/2;
-
-	out_ROI_width = vpe_ctrl->out_w;
-	out_ROI_height = vpe_ctrl->out_h;
-
-	src_ROI_width = out_ROI_width * pcrop->in2_w / pcrop->out2_w;
-	src_ROI_height = out_ROI_height * pcrop->in2_h / pcrop->out2_h;
-
-	/* clamp to output size.  This is because along
-	processing, we mostly do truncation, therefore
-	dis_offset tends to be
-	smaller values.  The intention was to make sure that the
-	offset does not exceed margin.   But in the case it could
-	result src_roi bigger, due to subtract a smaller value. */
-	CDBG("src w = 0x%x, h=0x%x, dst w = 0x%x, h =0x%x.\n",
-		src_ROI_width, src_ROI_height, out_ROI_width,
-		out_ROI_height);
-
-	src_roi = (src_ROI_height << 16) + src_ROI_width;
-
-	msm_camera_io_w(src_roi, vpe_device->vpebase + VPE_SRC_SIZE_OFFSET);
-
-	CDBG("src_x = %d, src_y=%d.\n", src_x, src_y);
-
-	src_xy = src_y*(1<<16) + src_x;
-	msm_camera_io_w(src_xy, vpe_device->vpebase +
-			VPE_SRC_XY_OFFSET);
-	CDBG("src_xy = 0x%x, src_roi=0x%x.\n", src_xy, src_roi);
-
-	/* decide whether to use FIR or M/N for scaling */
-	if ((out_ROI_width == 1 && src_ROI_width < 4) ||
-		(src_ROI_width < 4 * out_ROI_width - 3))
-		scale_unit_sel_x = 0;/* use FIR scalar */
-	else
-		scale_unit_sel_x = 1;/* use M/N scalar */
-
-	if ((out_ROI_height == 1 && src_ROI_height < 4) ||
-		(src_ROI_height < 4 * out_ROI_height - 3))
-		scale_unit_sel_y = 0;/* use FIR scalar */
-	else
-		scale_unit_sel_y = 1;/* use M/N scalar */
-	/* calculate phase step for the x direction */
-
-	/* if destination is only 1 pixel wide, the value of
-	phase_step_x is unimportant. Assigning phase_step_x
-	to src ROI width as an arbitrary value. */
-	if (out_ROI_width == 1)
-		phase_step_x = (uint32_t) ((src_ROI_width) <<
-							SCALER_PHASE_BITS);
-	else if (scale_unit_sel_x == 0) { /* if using FIR scalar */
-		/* Calculate the quotient ( src_ROI_width - 1 )
-		/ ( out_ROI_width - 1)with u3.29 precision.
-		Quotient is rounded up to the larger
-		29th decimal point. */
-		numerator =
-			(uint64_t)(src_ROI_width - 1) <<
-			SCALER_PHASE_BITS;
-		/* never equals to 0 because of the "
-		(out_ROI_width == 1 )"*/
-		denominator = (uint64_t)(out_ROI_width - 1);
-		/* divide and round up to the larger 29th
-		decimal point. */
-		phase_step_x = (uint32_t) vpe_do_div(
-			(numerator + denominator - 1), denominator);
-	} else if (scale_unit_sel_x == 1) { /* if M/N scalar */
-		/* Calculate the quotient
-		( src_ROI_width ) / ( out_ROI_width)
-		with u3.29 precision. Quotient is rounded
-		down to the smaller 29th decimal point. */
-		numerator = (uint64_t)(src_ROI_width) <<
-			SCALER_PHASE_BITS;
-		denominator = (uint64_t)(out_ROI_width);
-		phase_step_x =
-			(uint32_t) vpe_do_div(numerator, denominator);
-	}
-	/* calculate phase step for the y direction */
-
-	/* if destination is only 1 pixel wide, the value of
-		phase_step_x is unimportant. Assigning phase_step_x
-		to src ROI width as an arbitrary value. */
-	if (out_ROI_height == 1)
-		phase_step_y =
-		(uint32_t) ((src_ROI_height) << SCALER_PHASE_BITS);
-	else if (scale_unit_sel_y == 0) { /* if FIR scalar */
-		/* Calculate the quotient
-		( src_ROI_height - 1 ) / ( out_ROI_height - 1)
-		with u3.29 precision. Quotient is rounded up to the
-		larger 29th decimal point. */
-		numerator = (uint64_t)(src_ROI_height - 1) <<
-			SCALER_PHASE_BITS;
-		/* never equals to 0 because of the
-		"( out_ROI_height == 1 )" case */
-		denominator = (uint64_t)(out_ROI_height - 1);
-		/* Quotient is rounded up to the larger 29th
-		decimal point. */
-		phase_step_y =
-		(uint32_t) vpe_do_div(
-		(numerator + denominator - 1), denominator);
-	} else if (scale_unit_sel_y == 1) { /* if M/N scalar */
-		/* Calculate the quotient ( src_ROI_height ) / ( out_ROI_height)
-		with u3.29 precision. Quotient is rounded down to the smaller
-		29th decimal point. */
-		numerator = (uint64_t)(src_ROI_height) <<
-			SCALER_PHASE_BITS;
-		denominator = (uint64_t)(out_ROI_height);
-		phase_step_y = (uint32_t) vpe_do_div(
-			numerator, denominator);
-	}
-
-	/* decide which set of FIR coefficients to use */
-	if (phase_step_x > HAL_MDP_PHASE_STEP_2P50)
-		xscale_filter_sel = 0;
-	else if (phase_step_x > HAL_MDP_PHASE_STEP_1P66)
-		xscale_filter_sel = 1;
-	else if (phase_step_x > HAL_MDP_PHASE_STEP_1P25)
-		xscale_filter_sel = 2;
-	else
-		xscale_filter_sel = 3;
-
-	if (phase_step_y > HAL_MDP_PHASE_STEP_2P50)
-		yscale_filter_sel = 0;
-	else if (phase_step_y > HAL_MDP_PHASE_STEP_1P66)
-		yscale_filter_sel = 1;
-	else if (phase_step_y > HAL_MDP_PHASE_STEP_1P25)
-		yscale_filter_sel = 2;
-	else
-		yscale_filter_sel = 3;
-
-	/* calculate phase init for the x direction */
-
-	/* if using FIR scalar */
-	if (scale_unit_sel_x == 0) {
-		if (out_ROI_width == 1)
-			phase_init_x =
-			(uint32_t) ((src_ROI_width - 1) <<
-						SCALER_PHASE_BITS);
-		else
-			phase_init_x = 0;
-
-	} else if (scale_unit_sel_x == 1) /* M over N scalar  */
-		phase_init_x = 0;
-
-	/* calculate phase init for the y direction
-	if using FIR scalar */
-	if (scale_unit_sel_y == 0) {
-		if (out_ROI_height == 1)
-			phase_init_y =
-			(uint32_t) ((src_ROI_height -
-						1) << SCALER_PHASE_BITS);
-		else
-			phase_init_y = 0;
-
-	} else if (scale_unit_sel_y == 1) /* M over N scalar   */
-		phase_init_y = 0;
-
-	CDBG("phase step x = %d, step y = %d.\n",
-		phase_step_x, phase_step_y);
-	CDBG("phase init x = %d, init y = %d.\n",
-		phase_init_x, phase_init_y);
-
-	msm_camera_io_w(phase_step_x, vpe_device->vpebase +
-			VPE_SCALE_PHASEX_STEP_OFFSET);
-
-	msm_camera_io_w(phase_step_y, vpe_device->vpebase +
-			VPE_SCALE_PHASEY_STEP_OFFSET);
-
-	msm_camera_io_w(phase_init_x, vpe_device->vpebase +
-			VPE_SCALE_PHASEX_INIT_OFFSET);
-
-	msm_camera_io_w(phase_init_y, vpe_device->vpebase +
-			VPE_SCALE_PHASEY_INIT_OFFSET);
-
-	return 1;
-}
-
-void msm_send_frame_to_vpe(uint32_t p0_phy_add, uint32_t p1_phy_add,
-		struct timespec *ts, int output_type)
-{
-	uint32_t temp_pyaddr = 0, temp_pcbcraddr = 0;
-
-	CDBG("vpe input, p0_phy_add = 0x%x, p1_phy_add = 0x%x\n",
-		p0_phy_add, p1_phy_add);
-	msm_camera_io_w(p0_phy_add,
-		vpe_device->vpebase + VPE_SRCP0_ADDR_OFFSET);
-	msm_camera_io_w(p1_phy_add,
-		vpe_device->vpebase + VPE_SRCP1_ADDR_OFFSET);
-
-	if (vpe_ctrl->state == VPE_STATE_ACTIVE)
-		CDBG(" =====VPE is busy!!!  Wrong!========\n");
-
-	if (output_type != OUTPUT_TYPE_ST_R)
-		vpe_ctrl->ts = *ts;
-
-	if (output_type == OUTPUT_TYPE_ST_L) {
-		vpe_ctrl->pcbcr_before_dis =
-			msm_camera_io_r(vpe_device->vpebase +
-			VPE_OUTP1_ADDR_OFFSET);
-		temp_pyaddr = msm_camera_io_r(vpe_device->vpebase +
-			VPE_OUTP0_ADDR_OFFSET);
-		temp_pcbcraddr = temp_pyaddr + PAD_TO_2K(vpe_ctrl->out_w *
-			vpe_ctrl->out_h * 2, vpe_ctrl->pad_2k_bool);
-		msm_camera_io_w(temp_pcbcraddr, vpe_device->vpebase +
-			VPE_OUTP1_ADDR_OFFSET);
-	}
-
-	if (vpe_ctrl->dis_en) {
-		/* Changing the VPE output CBCR address,
-		to make Y/CBCR continuous */
-		vpe_ctrl->pcbcr_before_dis =
-			msm_camera_io_r(vpe_device->vpebase +
-			VPE_OUTP1_ADDR_OFFSET);
-		temp_pyaddr = msm_camera_io_r(vpe_device->vpebase +
-			VPE_OUTP0_ADDR_OFFSET);
-		temp_pcbcraddr = temp_pyaddr + vpe_ctrl->pcbcr_dis_offset;
-		msm_camera_io_w(temp_pcbcraddr, vpe_device->vpebase +
-			VPE_OUTP1_ADDR_OFFSET);
-	}
-
-	vpe_ctrl->output_type = output_type;
-	vpe_ctrl->state = VPE_STATE_ACTIVE;
-	vpe_start();
-}
-
-static int vpe_proc_general(struct msm_vpe_cmd *cmd)
-{
-	int rc = 0;
-	uint32_t *cmdp = NULL;
-	struct msm_queue_cmd *qcmd = NULL;
-	struct msm_vpe_buf_info *vpe_buf;
-	int turbo_mode = 0;
-	struct msm_sync *sync = (struct msm_sync *)vpe_ctrl->syncdata;
-	CDBG("vpe_proc_general: cmdID = %s, length = %d\n",
-		vpe_general_cmd[cmd->id], cmd->length);
-	switch (cmd->id) {
-	case VPE_ENABLE:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto vpe_proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto vpe_proc_general_done;
-		}
-		turbo_mode = *((int *)(cmd->value));
-		rc = turbo_mode ? vpe_enable(VPE_TURBO_MODE_CLOCK_RATE)
-			: vpe_enable(VPE_NORMAL_MODE_CLOCK_RATE);
-		break;
-	case VPE_DISABLE:
-		rc = vpe_disable();
-		break;
-	case VPE_RESET:
-	case VPE_ABORT:
-		rc = vpe_reset();
-		break;
-	case VPE_START:
-		rc = vpe_start();
-		break;
-
-	case VPE_INPUT_PLANE_CFG:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto vpe_proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto vpe_proc_general_done;
-		}
-		vpe_input_plane_config(cmdp);
-		break;
-
-	case VPE_OPERATION_MODE_CFG:
-		CDBG("cmd->length = %d \n", cmd->length);
-		if (cmd->length != VPE_OPERATION_MODE_CFG_LEN) {
-			rc = -EINVAL;
-			goto vpe_proc_general_done;
-		}
-		cmdp = kmalloc(VPE_OPERATION_MODE_CFG_LEN,
-					GFP_ATOMIC);
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			VPE_OPERATION_MODE_CFG_LEN)) {
-			rc = -EFAULT;
-			goto vpe_proc_general_done;
-		}
-		rc = vpe_operation_config(cmdp);
-		CDBG("rc = %d \n", rc);
-		break;
-
-	case VPE_OUTPUT_PLANE_CFG:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto vpe_proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto vpe_proc_general_done;
-		}
-		vpe_output_plane_config(cmdp);
-		break;
-
-	case VPE_SCALE_CFG_TYPE:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto vpe_proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto vpe_proc_general_done;
-		}
-		vpe_update_scale_coef(cmdp);
-		break;
-
-	case VPE_CMD_DIS_OFFSET_CFG: {
-		struct msm_vfe_resp *vdata;
-		/* first get the dis offset and frame id. */
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto vpe_proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto vpe_proc_general_done;
-		}
-		/* get the offset. */
-		vpe_ctrl->dis_offset = *(struct dis_offset_type *)cmdp;
-		qcmd = msm_dequeue_vpe(&sync->vpe_q, list_vpe_frame);
-		if (!qcmd) {
-			pr_err("%s: no video frame.\n", __func__);
-			kfree(cmdp);
-			return -EAGAIN;
-		}
-		vdata = (struct msm_vfe_resp *)(qcmd->command);
-		vpe_buf = &vdata->vpe_bf;
-		vpe_update_scaler_with_dis(&(vpe_buf->vpe_crop),
-					&(vpe_ctrl->dis_offset));
-
-		msm_send_frame_to_vpe(vpe_buf->p0_phy, vpe_buf->p1_phy,
-						&(vpe_buf->ts), OUTPUT_TYPE_V);
-
-		if (!qcmd || !atomic_read(&qcmd->on_heap)) {
-			kfree(cmdp);
-			return -EAGAIN;
-		}
-		if (!atomic_sub_return(1, &qcmd->on_heap))
-			kfree(qcmd);
-		break;
-	}
-
-	default:
-		break;
-	}
-vpe_proc_general_done:
-	kfree(cmdp);
-	return rc;
-}
-
-static void vpe_addr_convert(struct msm_vpe_phy_info *pinfo,
-	enum vpe_resp_msg type, void *data, void **ext, int32_t *elen)
-{
-	CDBG("In vpe_addr_convert type = %d\n", type);
-	switch (type) {
-	case VPE_MSG_OUTPUT_V:
-		pinfo->output_id = OUTPUT_TYPE_V;
-		break;
-	case VPE_MSG_OUTPUT_ST_R:
-		/* output_id will be used by user space only. */
-		pinfo->output_id = OUTPUT_TYPE_V;
-		break;
-	default:
-		break;
-	} /* switch */
-
-	CDBG("In vpe_addr_convert output_id = %d\n", pinfo->output_id);
-
-	pinfo->p0_phy =
-		((struct vpe_message *)data)->_u.msgOut.p0_Buffer;
-	pinfo->p1_phy =
-		((struct vpe_message *)data)->_u.msgOut.p1_Buffer;
-	*ext  = vpe_ctrl->extdata;
-	*elen = vpe_ctrl->extlen;
-}
-
-void vpe_proc_ops(uint8_t id, void *msg, size_t len)
-{
-	struct msm_vpe_resp *rp;
-
-	rp = vpe_ctrl->resp->vpe_alloc(sizeof(struct msm_vpe_resp),
-		vpe_ctrl->syncdata, GFP_ATOMIC);
-	if (!rp) {
-		CDBG("rp: cannot allocate buffer\n");
-		return;
-	}
-
-	CDBG("vpe_proc_ops, msgId = %d rp->evt_msg.msg_id = %d\n",
-		id, rp->evt_msg.msg_id);
-	rp->evt_msg.type   = MSM_CAMERA_MSG;
-	rp->evt_msg.msg_id = id;
-	rp->evt_msg.len    = len;
-	rp->evt_msg.data   = msg;
-
-	switch (rp->evt_msg.msg_id) {
-	case MSG_ID_VPE_OUTPUT_V:
-		rp->type = VPE_MSG_OUTPUT_V;
-		vpe_addr_convert(&(rp->phy), VPE_MSG_OUTPUT_V,
-			rp->evt_msg.data, &(rp->extdata),
-			&(rp->extlen));
-		break;
-
-	case MSG_ID_VPE_OUTPUT_ST_R:
-		rp->type = VPE_MSG_OUTPUT_ST_R;
-		vpe_addr_convert(&(rp->phy), VPE_MSG_OUTPUT_ST_R,
-			rp->evt_msg.data, &(rp->extdata),
-			&(rp->extlen));
-		break;
-
-	case MSG_ID_VPE_OUTPUT_ST_L:
-		rp->type = VPE_MSG_OUTPUT_ST_L;
-		break;
-
-	default:
-		rp->type = VPE_MSG_GENERAL;
-		break;
-	}
-	CDBG("%s: time = %ld\n",
-			__func__, vpe_ctrl->ts.tv_nsec);
-
-	vpe_ctrl->resp->vpe_resp(rp, MSM_CAM_Q_VPE_MSG,
-					vpe_ctrl->syncdata,
-					&(vpe_ctrl->ts), GFP_ATOMIC);
-}
-
-int vpe_config_axi(struct axidata *ad)
-{
-	uint32_t p1;
-	struct msm_pmem_region *regp1 = NULL;
-	CDBG("vpe_config_axi:bufnum1 = %d.\n", ad->bufnum1);
-
-	if (ad->bufnum1 != 1)
-		return -EINVAL;
-
-	regp1 = &(ad->region[0]);
-	/* for video  Y address */
-	p1 = (regp1->paddr + regp1->info.planar0_off);
-	msm_camera_io_w(p1, vpe_device->vpebase + VPE_OUTP0_ADDR_OFFSET);
-	/* for video  CbCr address */
-	p1 = (regp1->paddr + regp1->info.planar1_off);
-	msm_camera_io_w(p1, vpe_device->vpebase + VPE_OUTP1_ADDR_OFFSET);
-
-	return 0;
-}
-
-int msm_vpe_config(struct msm_vpe_cfg_cmd *cmd, void *data)
-{
-	struct msm_vpe_cmd vpecmd;
-	int rc = 0;
-	if (copy_from_user(&vpecmd,
-			(void __user *)(cmd->value),
-			sizeof(vpecmd))) {
-		pr_err("%s %d: copy_from_user failed\n", __func__,
-				__LINE__);
-		return -EFAULT;
-	}
-	CDBG("%s: cmd_type %d\n", __func__, cmd->cmd_type);
-	switch (cmd->cmd_type) {
-	case CMD_VPE:
-		rc = vpe_proc_general(&vpecmd);
-		CDBG(" rc = %d\n", rc);
-		break;
-
-	case CMD_AXI_CFG_VPE:
-	case CMD_AXI_CFG_SNAP_VPE:
-	case CMD_AXI_CFG_SNAP_THUMB_VPE: {
-		struct axidata *axid;
-		axid = data;
-		if (!axid)
-			return -EFAULT;
-		vpe_config_axi(axid);
-		break;
-	}
-	default:
-		break;
-	}
-	CDBG("%s: rc = %d\n", __func__, rc);
-	return rc;
-}
-
-void msm_vpe_offset_update(int frame_pack, uint32_t pyaddr, uint32_t pcbcraddr,
-	struct timespec *ts, int output_id, struct msm_st_half st_half,
-	int frameid)
-{
-	struct msm_vpe_buf_info vpe_buf;
-	uint32_t input_stride;
-
-	vpe_buf.vpe_crop.in2_w = st_half.stCropInfo.in_w;
-	vpe_buf.vpe_crop.in2_h = st_half.stCropInfo.in_h;
-	vpe_buf.vpe_crop.out2_w = st_half.stCropInfo.out_w;
-	vpe_buf.vpe_crop.out2_h = st_half.stCropInfo.out_h;
-	vpe_ctrl->dis_offset.dis_offset_x = st_half.pix_x_off;
-	vpe_ctrl->dis_offset.dis_offset_y = st_half.pix_y_off;
-	vpe_ctrl->dis_offset.frame_id = frameid;
-	vpe_ctrl->frame_pack = frame_pack;
-	vpe_ctrl->output_type = output_id;
-
-	input_stride = (st_half.buf_p1_stride * (1<<16)) +
-		st_half.buf_p0_stride;
-
-	msm_camera_io_w(input_stride,
-		vpe_device->vpebase + VPE_SRC_YSTRIDE1_OFFSET);
-
-	vpe_update_scaler_with_dis(&(vpe_buf.vpe_crop),
-		&(vpe_ctrl->dis_offset));
-
-	msm_send_frame_to_vpe(pyaddr, pcbcraddr, ts, output_id);
-}
-
-static void vpe_send_outmsg(uint8_t msgid, uint32_t p0_addr,
-	uint32_t p1_addr, uint32_t p2_addr)
-{
-	struct vpe_message msg;
-	uint8_t outid;
-	msg._d = outid = msgid;
-	msg._u.msgOut.output_id   = msgid;
-	msg._u.msgOut.p0_Buffer = p0_addr;
-	msg._u.msgOut.p1_Buffer = p1_addr;
-	msg._u.msgOut.p2_Buffer = p2_addr;
-	vpe_proc_ops(outid, &msg, sizeof(struct vpe_message));
-	return;
-}
-
-int msm_vpe_reg(struct msm_vpe_callback *presp)
-{
-	if (presp && presp->vpe_resp)
-		vpe_ctrl->resp = presp;
-
-	return 0;
-}
-
-static void vpe_send_msg_no_payload(enum VPE_MESSAGE_ID id)
-{
-	struct vpe_message msg;
-
-	CDBG("vfe31_send_msg_no_payload\n");
-	msg._d = id;
-	vpe_proc_ops(id, &msg, 0);
-}
-
-static void vpe_do_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	uint32_t pyaddr = 0, pcbcraddr = 0;
-	uint32_t src_y, src_cbcr, temp;
-
-	struct vpe_isr_queue_cmd_type *qcmd = NULL;
-
-	CDBG("=== vpe_do_tasklet start === \n");
-
-	spin_lock_irqsave(&vpe_ctrl->tasklet_lock, flags);
-	qcmd = list_first_entry(&vpe_ctrl->tasklet_q,
-		struct vpe_isr_queue_cmd_type, list);
-
-	if (!qcmd) {
-		spin_unlock_irqrestore(&vpe_ctrl->tasklet_lock, flags);
-		return;
-	}
-
-	list_del(&qcmd->list);
-	spin_unlock_irqrestore(&vpe_ctrl->tasklet_lock, flags);
-
-	/* interrupt to be processed,  *qcmd has the payload.  */
-	if (qcmd->irq_status & 0x1) {
-		if (vpe_ctrl->output_type == OUTPUT_TYPE_ST_L) {
-			CDBG("vpe left frame done.\n");
-			vpe_ctrl->output_type = 0;
-			CDBG("vpe send out msg.\n");
-			orig_src_y = msm_camera_io_r(vpe_device->vpebase +
-				VPE_SRCP0_ADDR_OFFSET);
-			orig_src_cbcr = msm_camera_io_r(vpe_device->vpebase +
-				VPE_SRCP1_ADDR_OFFSET);
-
-			pyaddr = msm_camera_io_r(vpe_device->vpebase +
-				VPE_OUTP0_ADDR_OFFSET);
-			pcbcraddr = msm_camera_io_r(vpe_device->vpebase +
-				VPE_OUTP1_ADDR_OFFSET);
-			CDBG("%s: out_w = %d, out_h = %d\n", __func__,
-				vpe_ctrl->out_w, vpe_ctrl->out_h);
-
-			if ((vpe_ctrl->frame_pack == TOP_DOWN_FULL) ||
-				(vpe_ctrl->frame_pack == TOP_DOWN_HALF)) {
-				msm_camera_io_w(pyaddr + (vpe_ctrl->out_w *
-					vpe_ctrl->out_h), vpe_device->vpebase +
-					VPE_OUTP0_ADDR_OFFSET);
-				msm_camera_io_w(pcbcraddr + (vpe_ctrl->out_w *
-					vpe_ctrl->out_h/2),
-					vpe_device->vpebase +
-					VPE_OUTP1_ADDR_OFFSET);
-			} else if ((vpe_ctrl->frame_pack ==
-				SIDE_BY_SIDE_HALF) || (vpe_ctrl->frame_pack ==
-				SIDE_BY_SIDE_FULL)) {
-				msm_camera_io_w(pyaddr + vpe_ctrl->out_w,
-					vpe_device->vpebase +
-					VPE_OUTP0_ADDR_OFFSET);
-				msm_camera_io_w(pcbcraddr + vpe_ctrl->out_w,
-					vpe_device->vpebase +
-					VPE_OUTP1_ADDR_OFFSET);
-			} else
-				CDBG("%s: Invalid packing = %d\n", __func__,
-					vpe_ctrl->frame_pack);
-
-			vpe_send_msg_no_payload(MSG_ID_VPE_OUTPUT_ST_L);
-			vpe_ctrl->state = VPE_STATE_INIT;
-			kfree(qcmd);
-			return;
-		} else if (vpe_ctrl->output_type == OUTPUT_TYPE_ST_R) {
-			src_y = orig_src_y;
-			src_cbcr = orig_src_cbcr;
-			CDBG("%s: out_w = %d, out_h = %d\n", __func__,
-				vpe_ctrl->out_w, vpe_ctrl->out_h);
-
-			if ((vpe_ctrl->frame_pack == TOP_DOWN_FULL) ||
-				(vpe_ctrl->frame_pack == TOP_DOWN_HALF)) {
-				pyaddr = msm_camera_io_r(vpe_device->vpebase +
-					VPE_OUTP0_ADDR_OFFSET) -
-					(vpe_ctrl->out_w * vpe_ctrl->out_h);
-			} else if ((vpe_ctrl->frame_pack ==
-				SIDE_BY_SIDE_HALF) || (vpe_ctrl->frame_pack ==
-				SIDE_BY_SIDE_FULL)) {
-				pyaddr = msm_camera_io_r(vpe_device->vpebase +
-				VPE_OUTP0_ADDR_OFFSET) - vpe_ctrl->out_w;
-			} else
-				CDBG("%s: Invalid packing = %d\n", __func__,
-					vpe_ctrl->frame_pack);
-
-			pcbcraddr = vpe_ctrl->pcbcr_before_dis;
-		} else {
-			src_y =	msm_camera_io_r(vpe_device->vpebase +
-				VPE_SRCP0_ADDR_OFFSET);
-			src_cbcr = msm_camera_io_r(vpe_device->vpebase +
-				VPE_SRCP1_ADDR_OFFSET);
-			pyaddr = msm_camera_io_r(vpe_device->vpebase +
-				VPE_OUTP0_ADDR_OFFSET);
-			pcbcraddr = msm_camera_io_r(vpe_device->vpebase +
-				VPE_OUTP1_ADDR_OFFSET);
-		}
-
-		if (vpe_ctrl->dis_en)
-			pcbcraddr = vpe_ctrl->pcbcr_before_dis;
-
-		msm_camera_io_w(src_y,
-				vpe_device->vpebase + VPE_OUTP0_ADDR_OFFSET);
-		msm_camera_io_w(src_cbcr,
-				vpe_device->vpebase + VPE_OUTP1_ADDR_OFFSET);
-
-		temp = msm_camera_io_r(vpe_device->vpebase + VPE_OP_MODE_OFFSET)
-				& 0xFFFFFFFC;
-		msm_camera_io_w(temp, vpe_device->vpebase + VPE_OP_MODE_OFFSET);
-
-		/*  now pass this frame to msm_camera.c. */
-		if (vpe_ctrl->output_type == OUTPUT_TYPE_ST_R) {
-			CDBG("vpe send out R msg.\n");
-			vpe_send_outmsg(MSG_ID_VPE_OUTPUT_ST_R, pyaddr,
-				pcbcraddr, pyaddr);
-		} else if (vpe_ctrl->output_type == OUTPUT_TYPE_V) {
-			CDBG("vpe send out V msg.\n");
-			vpe_send_outmsg(MSG_ID_VPE_OUTPUT_V, pyaddr,
-				pcbcraddr, pyaddr);
-		}
-
-		vpe_ctrl->output_type = 0;
-		vpe_ctrl->state = VPE_STATE_INIT;   /* put it back to idle. */
-
-	}
-	kfree(qcmd);
-}
-DECLARE_TASKLET(vpe_tasklet, vpe_do_tasklet, 0);
-
-static irqreturn_t vpe_parse_irq(int irq_num, void *data)
-{
-	unsigned long flags;
-	uint32_t irq_status = 0;
-	struct vpe_isr_queue_cmd_type *qcmd;
-
-	CDBG("vpe_parse_irq.\n");
-	/* read and clear back-to-back. */
-	irq_status = msm_camera_io_r_mb(vpe_device->vpebase +
-							VPE_INTR_STATUS_OFFSET);
-	msm_camera_io_w_mb(irq_status, vpe_device->vpebase +
-				VPE_INTR_CLEAR_OFFSET);
-
-	msm_camera_io_w(0, vpe_device->vpebase + VPE_INTR_ENABLE_OFFSET);
-
-	if (irq_status == 0) {
-		pr_err("%s: irq_status = 0,Something is wrong!\n", __func__);
-		return IRQ_HANDLED;
-	}
-	irq_status &= 0x1;
-	/* apply mask. only interested in bit 0.  */
-	if (irq_status) {
-		qcmd = kzalloc(sizeof(struct vpe_isr_queue_cmd_type),
-			GFP_ATOMIC);
-		if (!qcmd) {
-			pr_err("%s: qcmd malloc failed!\n", __func__);
-			return IRQ_HANDLED;
-		}
-		/* must be 0x1 now. so in bottom half we don't really
-		need to check. */
-		qcmd->irq_status = irq_status & 0x1;
-		spin_lock_irqsave(&vpe_ctrl->tasklet_lock, flags);
-		list_add_tail(&qcmd->list, &vpe_ctrl->tasklet_q);
-		spin_unlock_irqrestore(&vpe_ctrl->tasklet_lock, flags);
-		tasklet_schedule(&vpe_tasklet);
-	}
-	return IRQ_HANDLED;
-}
-
-static int vpe_enable_irq(void)
-{
-	uint32_t   rc = 0;
-	rc = request_irq(vpe_device->vpeirq,
-				vpe_parse_irq,
-				IRQF_TRIGGER_HIGH, "vpe", 0);
-	return rc;
-}
-
-int msm_vpe_open(void)
-{
-	int rc = 0;
-
-	CDBG("%s: In \n", __func__);
-
-	vpe_ctrl = kzalloc(sizeof(struct vpe_ctrl_type), GFP_KERNEL);
-	if (!vpe_ctrl) {
-		pr_err("%s: no memory!\n", __func__);
-		return -ENOMEM;
-	}
-
-	spin_lock_init(&vpe_ctrl->ops_lock);
-	CDBG("%s: Out\n", __func__);
-
-	return rc;
-}
-
-int msm_vpe_release(void)
-{
-	/* clean up....*/
-	int rc = 0;
-	CDBG("%s: state %d\n", __func__, vpe_ctrl->state);
-	if (vpe_ctrl->state != VPE_STATE_IDLE)
-		rc = vpe_disable();
-
-	kfree(vpe_ctrl);
-	return rc;
-}
-
-
-int vpe_enable(uint32_t clk_rate)
-{
-	int rc = 0;
-	unsigned long flags = 0;
-	/* don't change the order of clock and irq.*/
-	CDBG("%s: enable_clock rate %u\n", __func__, clk_rate);
-	spin_lock_irqsave(&vpe_ctrl->ops_lock, flags);
-	if (vpe_ctrl->state != VPE_STATE_IDLE) {
-		CDBG("%s: VPE already enabled", __func__);
-		spin_unlock_irqrestore(&vpe_ctrl->ops_lock, flags);
-		return 0;
-	}
-	vpe_ctrl->state = VPE_STATE_INIT;
-	spin_unlock_irqrestore(&vpe_ctrl->ops_lock, flags);
-
-	rc = msm_camio_vpe_clk_enable(clk_rate);
-	if (rc < 0) {
-		pr_err("%s: msm_camio_vpe_clk_enable failed", __func__);
-		vpe_ctrl->state = VPE_STATE_IDLE;
-		return rc;
-	}
-
-	CDBG("%s: enable_irq\n", __func__);
-	vpe_enable_irq();
-
-	/* initialize the data structure - lock, queue etc. */
-	spin_lock_init(&vpe_ctrl->tasklet_lock);
-	INIT_LIST_HEAD(&vpe_ctrl->tasklet_q);
-
-	return rc;
-}
-
-int vpe_disable(void)
-{
-	int rc = 0;
-	unsigned long flags = 0;
-	CDBG("%s: called", __func__);
-	spin_lock_irqsave(&vpe_ctrl->ops_lock, flags);
-	if (vpe_ctrl->state == VPE_STATE_IDLE) {
-		CDBG("%s: VPE already disabled", __func__);
-		spin_unlock_irqrestore(&vpe_ctrl->ops_lock, flags);
-		return 0;
-	}
-	vpe_ctrl->state = VPE_STATE_IDLE;
-	spin_unlock_irqrestore(&vpe_ctrl->ops_lock, flags);
-	vpe_ctrl->out_y_addr = msm_camera_io_r(vpe_device->vpebase +
-		VPE_OUTP0_ADDR_OFFSET);
-	vpe_ctrl->out_cbcr_addr = msm_camera_io_r(vpe_device->vpebase +
-		VPE_OUTP1_ADDR_OFFSET);
-	free_irq(vpe_device->vpeirq, 0);
-	tasklet_kill(&vpe_tasklet);
-	rc = msm_camio_vpe_clk_disable();
-	return rc;
-}
-
-static int __msm_vpe_probe(struct platform_device *pdev)
-{
-	int rc = 0;
-	struct resource   *vpemem, *vpeirq, *vpeio;
-	void __iomem      *vpebase;
-
-	/* first allocate */
-
-	vpe_device = &vpe_device_data;
-	memset(vpe_device, 0, sizeof(struct vpe_device_type));
-
-	/* does the device exist? */
-	vpeirq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!vpeirq) {
-		pr_err("%s: no vpe irq resource.\n", __func__);
-		rc = -ENODEV;
-		goto vpe_free_device;
-	}
-	vpemem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!vpemem) {
-		pr_err("%s: no vpe mem resource!\n", __func__);
-		rc = -ENODEV;
-		goto vpe_free_device;
-	}
-	vpeio = request_mem_region(vpemem->start,
-			resource_size(vpemem), pdev->name);
-	if (!vpeio) {
-		pr_err("%s: VPE region already claimed.\n", __func__);
-		rc = -EBUSY;
-		goto vpe_free_device;
-	}
-
-	vpebase =
-		ioremap(vpemem->start,
-				(vpemem->end - vpemem->start) + 1);
-	if (!vpebase) {
-		pr_err("%s: vpe ioremap failed.\n", __func__);
-		rc = -ENOMEM;
-		goto vpe_release_mem_region;
-	}
-
-	/* Fall through, _probe is successful. */
-	vpe_device->vpeirq = vpeirq->start;
-	vpe_device->vpemem = vpemem;
-	vpe_device->vpeio = vpeio;
-	vpe_device->vpebase = vpebase;
-	return rc;  /* this rc should be zero.*/
-
-	iounmap(vpe_device->vpebase);  /* this path should never occur */
-	vpe_device->vpebase = NULL;
-/* from this part it is error handling. */
-vpe_release_mem_region:
-	release_mem_region(vpemem->start, (vpemem->end - vpemem->start) + 1);
-vpe_free_device:
-	return rc;  /* this rc should have error code. */
-}
-
-static int __msm_vpe_remove(struct platform_device *pdev)
-{
-	struct resource	*vpemem;
-	vpemem = vpe_device->vpemem;
-
-	iounmap(vpe_device->vpebase);
-	vpe_device->vpebase = NULL;
-	release_mem_region(vpemem->start,
-					(vpemem->end - vpemem->start) + 1);
-	return 0;
-}
-
-static struct platform_driver msm_vpe_driver = {
-	.probe = __msm_vpe_probe,
-	.remove = __msm_vpe_remove,
-	.driver = {
-		.name = "msm_vpe",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init msm_vpe_init(void)
-{
-	return platform_driver_register(&msm_vpe_driver);
-}
-module_init(msm_vpe_init);
-
-static void __exit msm_vpe_exit(void)
-{
-	platform_driver_unregister(&msm_vpe_driver);
-}
-module_exit(msm_vpe_exit);
-
-MODULE_DESCRIPTION("msm vpe 1.0 driver");
-MODULE_VERSION("msm vpe driver 1.0");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/msm_vpe1.h b/drivers/media/video/msm/msm_vpe1.h
deleted file mode 100644
index f4d328d..0000000
--- a/drivers/media/video/msm/msm_vpe1.h
+++ /dev/null
@@ -1,254 +0,0 @@
-/* Copyright (c) 2010, 2012, Code Aurora Forum. 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 _msm_vpe1_h_
-#define _msm_vpe1_h_
-
-#include <mach/camera.h>
-
-/***********  start of register offset *********************/
-#define VPE_INTR_ENABLE_OFFSET                0x0020
-#define VPE_INTR_STATUS_OFFSET                0x0024
-#define VPE_INTR_CLEAR_OFFSET                 0x0028
-#define VPE_DL0_START_OFFSET                  0x0030
-#define VPE_HW_VERSION_OFFSET                 0x0070
-#define VPE_SW_RESET_OFFSET                   0x0074
-#define VPE_AXI_RD_ARB_CONFIG_OFFSET          0x0078
-#define VPE_SEL_CLK_OR_HCLK_TEST_BUS_OFFSET   0x007C
-#define VPE_CGC_EN_OFFSET                     0x0100
-#define VPE_CMD_STATUS_OFFSET                 0x10008
-#define VPE_PROFILE_EN_OFFSET                 0x10010
-#define VPE_PROFILE_COUNT_OFFSET              0x10014
-#define VPE_CMD_MODE_OFFSET                   0x10060
-#define VPE_SRC_SIZE_OFFSET                   0x10108
-#define VPE_SRCP0_ADDR_OFFSET                 0x1010C
-#define VPE_SRCP1_ADDR_OFFSET                 0x10110
-#define VPE_SRC_YSTRIDE1_OFFSET               0x1011C
-#define VPE_SRC_FORMAT_OFFSET                 0x10124
-#define VPE_SRC_UNPACK_PATTERN1_OFFSET        0x10128
-#define VPE_OP_MODE_OFFSET                    0x10138
-#define VPE_SCALE_PHASEX_INIT_OFFSET          0x1013C
-#define VPE_SCALE_PHASEY_INIT_OFFSET          0x10140
-#define VPE_SCALE_PHASEX_STEP_OFFSET          0x10144
-#define VPE_SCALE_PHASEY_STEP_OFFSET          0x10148
-#define VPE_OUT_FORMAT_OFFSET                 0x10150
-#define VPE_OUT_PACK_PATTERN1_OFFSET          0x10154
-#define VPE_OUT_SIZE_OFFSET                   0x10164
-#define VPE_OUTP0_ADDR_OFFSET                 0x10168
-#define VPE_OUTP1_ADDR_OFFSET                 0x1016C
-#define VPE_OUT_YSTRIDE1_OFFSET               0x10178
-#define VPE_OUT_XY_OFFSET                     0x1019C
-#define VPE_SRC_XY_OFFSET                     0x10200
-#define VPE_SRC_IMAGE_SIZE_OFFSET             0x10208
-#define VPE_SCALE_CONFIG_OFFSET               0x10230
-#define VPE_DEINT_STATUS_OFFSET               0x30000
-#define VPE_DEINT_DECISION_OFFSET             0x30004
-#define VPE_DEINT_COEFF0_OFFSET               0x30010
-#define VPE_SCALE_STATUS_OFFSET               0x50000
-#define VPE_SCALE_SVI_PARAM_OFFSET            0x50010
-#define VPE_SCALE_SHARPEN_CFG_OFFSET          0x50020
-#define VPE_SCALE_COEFF_LSP_0_OFFSET          0x50400
-#define VPE_SCALE_COEFF_MSP_0_OFFSET          0x50404
-
-#define VPE_AXI_ARB_2_OFFSET                  0x004C
-
-#define VPE_SCALE_COEFF_LSBn(n)	(0x50400 + 8 * (n))
-#define VPE_SCALE_COEFF_MSBn(n)	(0x50404 + 8 * (n))
-#define VPE_SCALE_COEFF_NUM			32
-
-/*********** end of register offset ********************/
-
-
-#define VPE_HARDWARE_VERSION          0x00080308
-#define VPE_SW_RESET_VALUE            0x00000010  /* bit 4 for PPP*/
-#define VPE_AXI_RD_ARB_CONFIG_VALUE   0x124924
-#define VPE_CMD_MODE_VALUE        0x1
-#define VPE_DEFAULT_OP_MODE_VALUE     0x40FC0004
-#define VPE_CGC_ENABLE_VALUE          0xffff
-#define VPE_DEFAULT_SCALE_CONFIG      0x3c
-
-#define VPE_NORMAL_MODE_CLOCK_RATE   150000000
-#define VPE_TURBO_MODE_CLOCK_RATE   200000000
-/**************************************************/
-/*********** Start of command id ******************/
-/**************************************************/
-enum VPE_CMD_ID_ENUM {
-	VPE_DUMMY_0 = 0,
-	VPE_SET_CLK,
-	VPE_RESET,
-	VPE_START,
-	VPE_ABORT,
-	VPE_OPERATION_MODE_CFG, /* 5 */
-	VPE_INPUT_PLANE_CFG,
-	VPE_OUTPUT_PLANE_CFG,
-	VPE_INPUT_PLANE_UPDATE,
-	VPE_SCALE_CFG_TYPE,
-	VPE_ROTATION_CFG_TYPE, /* 10 */
-	VPE_AXI_OUT_CFG,
-	VPE_CMD_DIS_OFFSET_CFG,
-	VPE_ENABLE,
-	VPE_DISABLE,
-};
-
-/* Length of each command.  In bytes.  (payload only) */
-#define VPE_OPERATION_MODE_CFG_LEN 8
-#define VPE_INPUT_PLANE_CFG_LEN    24
-#define VPE_OUTPUT_PLANE_CFG_LEN   20
-#define VPE_INPUT_PLANE_UPDATE_LEN 12
-#define VPE_SCALER_CONFIG_LEN      260
-#define VPE_DIS_OFFSET_CFG_LEN     12
-/**************************************************/
-/*********** End of command id ********************/
-/**************************************************/
-
-struct msm_vpe_cmd {
-	int32_t  id;
-	uint16_t length;
-	void     *value;
-};
-
-struct vpe_cmd_type {
-	uint16_t id;
-	uint32_t length;
-};
-
-struct vpe_isr_queue_cmd_type {
-	struct list_head            list;
-	uint32_t                    irq_status;
-};
-
-enum VPE_MESSAGE_ID {
-	MSG_ID_VPE_OUTPUT_V = 7, /* To match with that of VFE */
-	MSG_ID_VPE_OUTPUT_ST_L,
-	MSG_ID_VPE_OUTPUT_ST_R,
-};
-
-enum vpe_state {
-	VPE_STATE_IDLE,
-	VPE_STATE_INIT,
-	VPE_STATE_ACTIVE,
-};
-
-struct vpe_device_type {
-	/* device related. */
-	int   vpeirq;
-	void __iomem      *vpebase;
-	struct resource	  *vpemem;
-	struct resource   *vpeio;
-	void        *device_extdata;
-};
-
-struct dis_offset_type {
-	int32_t dis_offset_x;
-	int32_t dis_offset_y;
-	uint32_t frame_id;
-};
-
-struct vpe_ctrl_type {
-	spinlock_t        tasklet_lock;
-	spinlock_t        state_lock;
-	spinlock_t        ops_lock;
-
-	struct list_head  tasklet_q;
-	void              *syncdata;
-	uint16_t          op_mode;
-	void              *extdata;
-	uint32_t          extlen;
-	struct msm_vpe_callback *resp;
-	uint32_t          in_h_w;
-	uint32_t          out_h;  /* this is BEFORE rotation. */
-	uint32_t          out_w;  /* this is BEFORE rotation. */
-	uint32_t          dis_en;
-	struct timespec   ts;
-	struct dis_offset_type   dis_offset;
-	uint32_t          pcbcr_before_dis;
-	uint32_t          pcbcr_dis_offset;
-	int               output_type;
-	int               frame_pack;
-	uint8_t           pad_2k_bool;
-	enum vpe_state    state;
-	unsigned long     out_y_addr;
-	unsigned long     out_cbcr_addr;
-};
-
-/*
-* vpe_input_update
-*
-* Define the parameters for output plane
-*/
-/* this is the dimension of ROI.  width / height. */
-struct vpe_src_size_packed {
-	uint32_t        src_w;
-	uint32_t        src_h;
-};
-
-struct vpe_src_xy_packed {
-	uint32_t        src_x;
-	uint32_t        src_y;
-};
-
-struct vpe_input_plane_update_type {
-	struct vpe_src_size_packed             src_roi_size;
-	/* DIS updates this set. */
-	struct vpe_src_xy_packed               src_roi_offset;
-	/* input address*/
-	uint8_t                         *src_p0_addr;
-	uint8_t                         *src_p1_addr;
-};
-
-struct vpe_msg_stats{
-	uint32_t    buffer;
-	uint32_t    frameCounter;
-};
-
-struct vpe_msg_output {
-	uint8_t   output_id;
-	uint32_t  p0_Buffer;
-	uint32_t  p1_Buffer;
-	uint32_t  p2_Buffer;
-	uint32_t  frameCounter;
-};
-
-struct vpe_message {
-	uint8_t  _d;
-	union {
-		struct vpe_msg_output              msgOut;
-		struct vpe_msg_stats               msgStats;
-	} _u;
-};
-
-#define SCALER_PHASE_BITS 29
-#define HAL_MDP_PHASE_STEP_2P50    0x50000000
-#define HAL_MDP_PHASE_STEP_1P66    0x35555555
-#define HAL_MDP_PHASE_STEP_1P25    0x28000000
-
-struct phase_val_t {
-	int32_t phase_init_x;
-	int32_t phase_init_y;
-	int32_t phase_step_x;
-	int32_t phase_step_y;
-};
-
-extern struct vpe_ctrl_type *vpe_ctrl;
-
-int msm_vpe_open(void);
-int msm_vpe_release(void);
-int msm_vpe_reg(struct msm_vpe_callback *presp);
-void msm_send_frame_to_vpe(uint32_t pyaddr, uint32_t pcbcraddr,
-	struct timespec *ts, int output_id);
-int msm_vpe_config(struct msm_vpe_cfg_cmd *cmd, void *data);
-int msm_vpe_cfg_update(void *pinfo);
-void msm_vpe_offset_update(int frame_pack, uint32_t pyaddr, uint32_t pcbcraddr,
-	struct timespec *ts, int output_id, struct msm_st_half st_half,
-	int frameid);
-#endif /*_msm_vpe1_h_*/
-
diff --git a/drivers/media/video/msm/mt9d112.c b/drivers/media/video/msm/mt9d112.c
deleted file mode 100644
index 4dd0285..0000000
--- a/drivers/media/video/msm/mt9d112.c
+++ /dev/null
@@ -1,846 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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/delay.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/module.h>
-#include <media/msm_camera.h>
-#include <mach/gpio.h>
-#include "mt9d112.h"
-
-/* Micron MT9D112 Registers and their values */
-/* Sensor Core Registers */
-#define  REG_MT9D112_MODEL_ID 0x3000
-#define  MT9D112_MODEL_ID     0x1580
-
-/*  SOC Registers Page 1  */
-#define  REG_MT9D112_SENSOR_RESET     0x301A
-#define  REG_MT9D112_STANDBY_CONTROL  0x3202
-#define  REG_MT9D112_MCU_BOOT         0x3386
-
-#define SENSOR_DEBUG 0
-
-struct mt9d112_work {
-	struct work_struct work;
-};
-
-static struct  mt9d112_work *mt9d112_sensorw;
-static struct  i2c_client *mt9d112_client;
-
-struct mt9d112_ctrl {
-	const struct msm_camera_sensor_info *sensordata;
-};
-
-
-static struct mt9d112_ctrl *mt9d112_ctrl;
-
-static DECLARE_WAIT_QUEUE_HEAD(mt9d112_wait_queue);
-DEFINE_SEMAPHORE(mt9d112_sem);
-static int16_t mt9d112_effect = CAMERA_EFFECT_OFF;
-
-/*=============================================================
-	EXTERNAL DECLARATIONS
-==============================================================*/
-extern struct mt9d112_reg mt9d112_regs;
-
-
-/*=============================================================*/
-
-static int mt9d112_reset(const struct msm_camera_sensor_info *dev)
-{
-	int rc = 0;
-
-	rc = gpio_request(dev->sensor_reset, "mt9d112");
-
-	if (!rc) {
-		rc = gpio_direction_output(dev->sensor_reset, 0);
-		msleep(20);
-		gpio_set_value_cansleep(dev->sensor_reset, 1);
-		msleep(20);
-	}
-
-	return rc;
-}
-
-static int32_t mt9d112_i2c_txdata(unsigned short saddr,
-	unsigned char *txdata, int length)
-{
-	struct i2c_msg msg[] = {
-		{
-			.addr = saddr,
-			.flags = 0,
-			.len = length,
-			.buf = txdata,
-		},
-	};
-
-#if SENSOR_DEBUG
-	if (length == 2)
-		CDBG("msm_io_i2c_w: 0x%04x 0x%04x\n",
-			*(u16 *) txdata, *(u16 *) (txdata + 2));
-	else if (length == 4)
-		CDBG("msm_io_i2c_w: 0x%04x\n", *(u16 *) txdata);
-	else
-		CDBG("msm_io_i2c_w: length = %d\n", length);
-#endif
-	if (i2c_transfer(mt9d112_client->adapter, msg, 1) < 0) {
-		CDBG("mt9d112_i2c_txdata failed\n");
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int32_t mt9d112_i2c_write(unsigned short saddr,
-	unsigned short waddr, unsigned short wdata, enum mt9d112_width width)
-{
-	int32_t rc = -EIO;
-	unsigned char buf[4];
-
-	memset(buf, 0, sizeof(buf));
-	switch (width) {
-	case WORD_LEN: {
-		buf[0] = (waddr & 0xFF00)>>8;
-		buf[1] = (waddr & 0x00FF);
-		buf[2] = (wdata & 0xFF00)>>8;
-		buf[3] = (wdata & 0x00FF);
-
-		rc = mt9d112_i2c_txdata(saddr, buf, 4);
-	}
-		break;
-
-	case BYTE_LEN: {
-		buf[0] = waddr;
-		buf[1] = wdata;
-		rc = mt9d112_i2c_txdata(saddr, buf, 2);
-	}
-		break;
-
-	default:
-		break;
-	}
-
-	if (rc < 0)
-		CDBG(
-		"i2c_write failed, addr = 0x%x, val = 0x%x!\n",
-		waddr, wdata);
-
-	return rc;
-}
-
-static int32_t mt9d112_i2c_write_table(
-	struct mt9d112_i2c_reg_conf const *reg_conf_tbl,
-	int num_of_items_in_table)
-{
-	int i;
-	int32_t rc = -EIO;
-
-	for (i = 0; i < num_of_items_in_table; i++) {
-		rc = mt9d112_i2c_write(mt9d112_client->addr,
-			reg_conf_tbl->waddr, reg_conf_tbl->wdata,
-			reg_conf_tbl->width);
-		if (rc < 0)
-			break;
-		if (reg_conf_tbl->mdelay_time != 0)
-			mdelay(reg_conf_tbl->mdelay_time);
-		reg_conf_tbl++;
-	}
-
-	return rc;
-}
-
-static int mt9d112_i2c_rxdata(unsigned short saddr,
-	unsigned char *rxdata, int length)
-{
-	struct i2c_msg msgs[] = {
-	{
-		.addr   = saddr,
-		.flags = 0,
-		.len   = 2,
-		.buf   = rxdata,
-	},
-	{
-		.addr   = saddr,
-		.flags = I2C_M_RD,
-		.len   = length,
-		.buf   = rxdata,
-	},
-	};
-
-#if SENSOR_DEBUG
-	if (length == 2)
-		CDBG("msm_io_i2c_r: 0x%04x 0x%04x\n",
-			*(u16 *) rxdata, *(u16 *) (rxdata + 2));
-	else if (length == 4)
-		CDBG("msm_io_i2c_r: 0x%04x\n", *(u16 *) rxdata);
-	else
-		CDBG("msm_io_i2c_r: length = %d\n", length);
-#endif
-
-	if (i2c_transfer(mt9d112_client->adapter, msgs, 2) < 0) {
-		CDBG("mt9d112_i2c_rxdata failed!\n");
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int32_t mt9d112_i2c_read(unsigned short   saddr,
-	unsigned short raddr, unsigned short *rdata, enum mt9d112_width width)
-{
-	int32_t rc = 0;
-	unsigned char buf[4];
-
-	if (!rdata)
-		return -EIO;
-
-	memset(buf, 0, sizeof(buf));
-
-	switch (width) {
-	case WORD_LEN: {
-		buf[0] = (raddr & 0xFF00)>>8;
-		buf[1] = (raddr & 0x00FF);
-
-		rc = mt9d112_i2c_rxdata(saddr, buf, 2);
-		if (rc < 0)
-			return rc;
-
-		*rdata = buf[0] << 8 | buf[1];
-	}
-		break;
-
-	default:
-		break;
-	}
-
-	if (rc < 0)
-		CDBG("mt9d112_i2c_read failed!\n");
-
-	return rc;
-}
-
-static int32_t mt9d112_set_lens_roll_off(void)
-{
-	int32_t rc = 0;
-	rc = mt9d112_i2c_write_table(&mt9d112_regs.rftbl[0],
-								 mt9d112_regs.rftbl_size);
-	return rc;
-}
-
-static long mt9d112_reg_init(void)
-{
-	int32_t array_length;
-	int32_t i;
-	long rc;
-
-	/* PLL Setup Start */
-	rc = mt9d112_i2c_write_table(&mt9d112_regs.plltbl[0],
-					mt9d112_regs.plltbl_size);
-
-	if (rc < 0)
-		return rc;
-	/* PLL Setup End   */
-
-	array_length = mt9d112_regs.prev_snap_reg_settings_size;
-
-	/* Configure sensor for Preview mode and Snapshot mode */
-	for (i = 0; i < array_length; i++) {
-		rc = mt9d112_i2c_write(mt9d112_client->addr,
-		  mt9d112_regs.prev_snap_reg_settings[i].register_address,
-		  mt9d112_regs.prev_snap_reg_settings[i].register_value,
-		  WORD_LEN);
-
-		if (rc < 0)
-			return rc;
-	}
-
-	/* Configure for Noise Reduction, Saturation and Aperture Correction */
-	array_length = mt9d112_regs.noise_reduction_reg_settings_size;
-
-	for (i = 0; i < array_length; i++) {
-		rc = mt9d112_i2c_write(mt9d112_client->addr,
-			mt9d112_regs.noise_reduction_reg_settings[i].register_address,
-			mt9d112_regs.noise_reduction_reg_settings[i].register_value,
-			WORD_LEN);
-
-		if (rc < 0)
-			return rc;
-	}
-
-	/* Set Color Kill Saturation point to optimum value */
-	rc =
-	mt9d112_i2c_write(mt9d112_client->addr,
-	0x35A4,
-	0x0593,
-	WORD_LEN);
-	if (rc < 0)
-		return rc;
-
-	rc = mt9d112_i2c_write_table(&mt9d112_regs.stbl[0],
-					mt9d112_regs.stbl_size);
-	if (rc < 0)
-		return rc;
-
-	rc = mt9d112_set_lens_roll_off();
-	if (rc < 0)
-		return rc;
-
-	return 0;
-}
-
-static long mt9d112_set_effect(int mode, int effect)
-{
-	uint16_t reg_addr;
-	uint16_t reg_val;
-	long rc = 0;
-
-	switch (mode) {
-	case SENSOR_PREVIEW_MODE:
-		/* Context A Special Effects */
-		reg_addr = 0x2799;
-		break;
-
-	case SENSOR_RAW_SNAPSHOT_MODE:
-	case SENSOR_SNAPSHOT_MODE:
-		/* Context B Special Effects */
-		reg_addr = 0x279B;
-		break;
-
-	default:
-		reg_addr = 0x2799;
-		break;
-	}
-
-	switch (effect) {
-	case CAMERA_EFFECT_OFF: {
-		reg_val = 0x6440;
-
-		rc = mt9d112_i2c_write(mt9d112_client->addr,
-			0x338C, reg_addr, WORD_LEN);
-		if (rc < 0)
-			return rc;
-
-		rc = mt9d112_i2c_write(mt9d112_client->addr,
-			0x3390, reg_val, WORD_LEN);
-		if (rc < 0)
-			return rc;
-	}
-			break;
-
-	case CAMERA_EFFECT_MONO: {
-		reg_val = 0x6441;
-		rc = mt9d112_i2c_write(mt9d112_client->addr,
-			0x338C, reg_addr, WORD_LEN);
-		if (rc < 0)
-			return rc;
-
-		rc = mt9d112_i2c_write(mt9d112_client->addr,
-			0x3390, reg_val, WORD_LEN);
-		if (rc < 0)
-			return rc;
-	}
-		break;
-
-	case CAMERA_EFFECT_NEGATIVE: {
-		reg_val = 0x6443;
-		rc = mt9d112_i2c_write(mt9d112_client->addr,
-			0x338C, reg_addr, WORD_LEN);
-		if (rc < 0)
-			return rc;
-
-		rc = mt9d112_i2c_write(mt9d112_client->addr,
-			0x3390, reg_val, WORD_LEN);
-		if (rc < 0)
-			return rc;
-	}
-		break;
-
-	case CAMERA_EFFECT_SOLARIZE: {
-		reg_val = 0x6445;
-		rc = mt9d112_i2c_write(mt9d112_client->addr,
-			0x338C, reg_addr, WORD_LEN);
-		if (rc < 0)
-			return rc;
-
-		rc = mt9d112_i2c_write(mt9d112_client->addr,
-			0x3390, reg_val, WORD_LEN);
-		if (rc < 0)
-			return rc;
-	}
-		break;
-
-	case CAMERA_EFFECT_SEPIA: {
-		reg_val = 0x6442;
-		rc = mt9d112_i2c_write(mt9d112_client->addr,
-			0x338C, reg_addr, WORD_LEN);
-		if (rc < 0)
-			return rc;
-
-		rc = mt9d112_i2c_write(mt9d112_client->addr,
-			0x3390, reg_val, WORD_LEN);
-		if (rc < 0)
-			return rc;
-	}
-		break;
-
-	default: {
-		reg_val = 0x6440;
-		rc = mt9d112_i2c_write(mt9d112_client->addr,
-			0x338C, reg_addr, WORD_LEN);
-		if (rc < 0)
-			return rc;
-
-		rc = mt9d112_i2c_write(mt9d112_client->addr,
-			0x3390, reg_val, WORD_LEN);
-		if (rc < 0)
-			return rc;
-
-		return -EINVAL;
-	}
-	}
-	mt9d112_effect = effect;
-	/* Refresh Sequencer */
-	rc = mt9d112_i2c_write(mt9d112_client->addr,
-		0x338C, 0xA103, WORD_LEN);
-	if (rc < 0)
-		return rc;
-
-	rc = mt9d112_i2c_write(mt9d112_client->addr,
-		0x3390, 0x0005, WORD_LEN);
-
-	return rc;
-}
-
-static long mt9d112_set_sensor_mode(int mode)
-{
-	uint16_t clock;
-	long rc = 0;
-
-	switch (mode) {
-	case SENSOR_PREVIEW_MODE:
-		rc =
-			mt9d112_i2c_write(mt9d112_client->addr,
-				0x338C, 0xA20C, WORD_LEN);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9d112_i2c_write(mt9d112_client->addr,
-				0x3390, 0x0004, WORD_LEN);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9d112_i2c_write(mt9d112_client->addr,
-				0x338C, 0xA215, WORD_LEN);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9d112_i2c_write(mt9d112_client->addr,
-				0x3390, 0x0004, WORD_LEN);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9d112_i2c_write(mt9d112_client->addr,
-				0x338C, 0xA20B, WORD_LEN);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9d112_i2c_write(mt9d112_client->addr,
-				0x3390, 0x0000, WORD_LEN);
-		if (rc < 0)
-			return rc;
-
-		clock = 0x23C;
-
-		rc =
-			mt9d112_i2c_write(mt9d112_client->addr,
-				0x341C, clock, WORD_LEN);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9d112_i2c_write(mt9d112_client->addr,
-				0x338C, 0xA103, WORD_LEN);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9d112_i2c_write(mt9d112_client->addr,
-				0x3390, 0x0001, WORD_LEN);
-		if (rc < 0)
-			return rc;
-		mdelay(5);
-
-		break;
-
-	case SENSOR_SNAPSHOT_MODE:
-		/* Switch to lower fps for Snapshot */
-		rc =
-			mt9d112_i2c_write(mt9d112_client->addr,
-				0x341C, 0x0120, WORD_LEN);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9d112_i2c_write(mt9d112_client->addr,
-				0x338C, 0xA120, WORD_LEN);
-		if (rc < 0)
-			return rc;
-
-		msleep(40);/*waiting for the delay of one frame*/
-		rc =
-			mt9d112_i2c_write(mt9d112_client->addr,
-				0x3390, 0x0002, WORD_LEN);
-		if (rc < 0)
-			return rc;
-
-		msleep(80);/*waiting for the delay of two frames*/
-
-		rc =
-			mt9d112_i2c_write(mt9d112_client->addr,
-				0x338C, 0xA103, WORD_LEN);
-		if (rc < 0)
-			return rc;
-
-		msleep(40);/*waiting for the delay of one frame*/
-		rc =
-			mt9d112_i2c_write(mt9d112_client->addr,
-				0x3390, 0x0002, WORD_LEN);
-		if (rc < 0)
-			return rc;
-		break;
-
-	case SENSOR_RAW_SNAPSHOT_MODE:
-		/* Setting the effect to CAMERA_EFFECT_OFF */
-		rc =
-			mt9d112_i2c_write(mt9d112_client->addr,
-				0x338C, 0x279B, WORD_LEN);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9d112_i2c_write(mt9d112_client->addr,
-			0x3390, 0x6440, WORD_LEN);
-		if (rc < 0)
-			return rc;
-		msleep(40);/*waiting for the delay of one frame*/
-		/* Switch to lower fps for Snapshot */
-		rc =
-			mt9d112_i2c_write(mt9d112_client->addr,
-				0x341C, 0x0120, WORD_LEN);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9d112_i2c_write(mt9d112_client->addr,
-				0x338C, 0xA120, WORD_LEN);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9d112_i2c_write(mt9d112_client->addr,
-				0x3390, 0x0002, WORD_LEN);
-		if (rc < 0)
-			return rc;
-		msleep(80);/*waiting for the delay of two frames frame*/
-		rc =
-			mt9d112_i2c_write(mt9d112_client->addr,
-				0x338C, 0xA103, WORD_LEN);
-		if (rc < 0)
-			return rc;
-		msleep(40);/*waiting for the delay of one frame*/
-		rc =
-			mt9d112_i2c_write(mt9d112_client->addr,
-				0x3390, 0x0002, WORD_LEN);
-		if (rc < 0)
-			return rc;
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int mt9d112_sensor_init_probe(const struct msm_camera_sensor_info *data)
-{
-	uint16_t model_id = 0;
-	int rc = 0;
-
-	CDBG("init entry \n");
-	rc = mt9d112_reset(data);
-	if (rc < 0) {
-		CDBG("reset failed!\n");
-		goto init_probe_fail;
-	}
-
-	msm_camio_clk_rate_set(24000000);
-	msleep(20);
-
-	/* Micron suggested Power up block Start:
-	* Put MCU into Reset - Stop MCU */
-	rc = mt9d112_i2c_write(mt9d112_client->addr,
-		REG_MT9D112_MCU_BOOT, 0x0501, WORD_LEN);
-	if (rc < 0)
-		goto init_probe_fail;
-
-	/* Pull MCU from Reset - Start MCU */
-	rc = mt9d112_i2c_write(mt9d112_client->addr,
-		REG_MT9D112_MCU_BOOT, 0x0500, WORD_LEN);
-	if (rc < 0)
-		goto init_probe_fail;
-
-	mdelay(5);
-
-	/* Micron Suggested - Power up block */
-	rc = mt9d112_i2c_write(mt9d112_client->addr,
-		REG_MT9D112_SENSOR_RESET, 0x0ACC, WORD_LEN);
-	if (rc < 0)
-		goto init_probe_fail;
-
-	rc = mt9d112_i2c_write(mt9d112_client->addr,
-		REG_MT9D112_STANDBY_CONTROL, 0x0008, WORD_LEN);
-	if (rc < 0)
-		goto init_probe_fail;
-
-	/* FUSED_DEFECT_CORRECTION */
-	rc = mt9d112_i2c_write(mt9d112_client->addr,
-		0x33F4, 0x031D, WORD_LEN);
-	if (rc < 0)
-		goto init_probe_fail;
-
-	mdelay(5);
-
-	/* Micron suggested Power up block End */
-	/* Read the Model ID of the sensor */
-	rc = mt9d112_i2c_read(mt9d112_client->addr,
-		REG_MT9D112_MODEL_ID, &model_id, WORD_LEN);
-	if (rc < 0)
-		goto init_probe_fail;
-
-	CDBG("mt9d112 model_id = 0x%x\n", model_id);
-
-	/* Check if it matches it with the value in Datasheet */
-	if (model_id != MT9D112_MODEL_ID) {
-		rc = -EINVAL;
-		goto init_probe_fail;
-	}
-
-	rc = mt9d112_reg_init();
-	if (rc < 0)
-		goto init_probe_fail;
-
-	return rc;
-
-init_probe_fail:
-	return rc;
-}
-
-int mt9d112_sensor_init(const struct msm_camera_sensor_info *data)
-{
-	int rc = 0;
-
-	mt9d112_ctrl = kzalloc(sizeof(struct mt9d112_ctrl), GFP_KERNEL);
-	if (!mt9d112_ctrl) {
-		CDBG("mt9d112_init failed!\n");
-		rc = -ENOMEM;
-		goto init_done;
-	}
-
-	if (data)
-		mt9d112_ctrl->sensordata = data;
-
-	/* Input MCLK = 24MHz */
-	msm_camio_clk_rate_set(24000000);
-	mdelay(5);
-
-	msm_camio_camif_pad_reg_reset();
-
-	rc = mt9d112_sensor_init_probe(data);
-	if (rc < 0) {
-		CDBG("mt9d112_sensor_init failed!\n");
-		goto init_fail;
-	}
-
-init_done:
-	return rc;
-
-init_fail:
-	kfree(mt9d112_ctrl);
-	return rc;
-}
-
-static int mt9d112_init_client(struct i2c_client *client)
-{
-	/* Initialize the MSM_CAMI2C Chip */
-	init_waitqueue_head(&mt9d112_wait_queue);
-	return 0;
-}
-
-int mt9d112_sensor_config(void __user *argp)
-{
-	struct sensor_cfg_data cfg_data;
-	long   rc = 0;
-
-	if (copy_from_user(&cfg_data,
-			(void *)argp,
-			sizeof(struct sensor_cfg_data)))
-		return -EFAULT;
-
-	/* down(&mt9d112_sem); */
-
-	CDBG("mt9d112_ioctl, cfgtype = %d, mode = %d\n",
-		cfg_data.cfgtype, cfg_data.mode);
-
-		switch (cfg_data.cfgtype) {
-		case CFG_SET_MODE:
-			rc = mt9d112_set_sensor_mode(
-						cfg_data.mode);
-			break;
-
-		case CFG_SET_EFFECT:
-			rc = mt9d112_set_effect(cfg_data.mode,
-						cfg_data.cfg.effect);
-			break;
-
-		case CFG_GET_AF_MAX_STEPS:
-		default:
-			rc = -EINVAL;
-			break;
-		}
-
-	/* up(&mt9d112_sem); */
-
-	return rc;
-}
-
-int mt9d112_sensor_release(void)
-{
-	int rc = 0;
-
-	/* down(&mt9d112_sem); */
-	gpio_set_value_cansleep(mt9d112_ctrl->sensordata->sensor_reset, 0);
-	msleep(20);
-	gpio_free(mt9d112_ctrl->sensordata->sensor_reset);
-	kfree(mt9d112_ctrl);
-	/* up(&mt9d112_sem); */
-
-	return rc;
-}
-
-static int mt9d112_i2c_probe(struct i2c_client *client,
-	const struct i2c_device_id *id)
-{
-	int rc = 0;
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		rc = -ENOTSUPP;
-		goto probe_failure;
-	}
-
-	mt9d112_sensorw =
-		kzalloc(sizeof(struct mt9d112_work), GFP_KERNEL);
-
-	if (!mt9d112_sensorw) {
-		rc = -ENOMEM;
-		goto probe_failure;
-	}
-
-	i2c_set_clientdata(client, mt9d112_sensorw);
-	mt9d112_init_client(client);
-	mt9d112_client = client;
-
-	CDBG("mt9d112_probe succeeded!\n");
-
-	return 0;
-
-probe_failure:
-	kfree(mt9d112_sensorw);
-	mt9d112_sensorw = NULL;
-	CDBG("mt9d112_probe failed!\n");
-	return rc;
-}
-
-static const struct i2c_device_id mt9d112_i2c_id[] = {
-	{ "mt9d112", 0},
-	{ },
-};
-
-static struct i2c_driver mt9d112_i2c_driver = {
-	.id_table = mt9d112_i2c_id,
-	.probe  = mt9d112_i2c_probe,
-	.remove = __exit_p(mt9d112_i2c_remove),
-	.driver = {
-		.name = "mt9d112",
-	},
-};
-
-static int mt9d112_sensor_probe(const struct msm_camera_sensor_info *info,
-				struct msm_sensor_ctrl *s)
-{
-	int rc = i2c_add_driver(&mt9d112_i2c_driver);
-	if (rc < 0 || mt9d112_client == NULL) {
-		rc = -ENOTSUPP;
-		goto probe_done;
-	}
-
-	/* Input MCLK = 24MHz */
-	msm_camio_clk_rate_set(24000000);
-	mdelay(5);
-
-	rc = mt9d112_sensor_init_probe(info);
-	if (rc < 0) {
-		gpio_free(info->sensor_reset);
-		goto probe_done;
-	}
-	s->s_init = mt9d112_sensor_init;
-	s->s_release = mt9d112_sensor_release;
-	s->s_config  = mt9d112_sensor_config;
-	s->s_camera_type = FRONT_CAMERA_2D;
-	s->s_mount_angle  = 0;
-	gpio_set_value_cansleep(info->sensor_reset, 0);
-	msleep(20);
-	gpio_free(info->sensor_reset);
-
-probe_done:
-	CDBG("%s %s:%d\n", __FILE__, __func__, __LINE__);
-	return rc;
-}
-
-static int __mt9d112_probe(struct platform_device *pdev)
-{
-	return msm_camera_drv_start(pdev, mt9d112_sensor_probe);
-}
-
-static struct platform_driver msm_camera_driver = {
-	.probe = __mt9d112_probe,
-	.driver = {
-		.name = "msm_camera_mt9d112",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init mt9d112_init(void)
-{
-	return platform_driver_register(&msm_camera_driver);
-}
-
-module_init(mt9d112_init);
diff --git a/drivers/media/video/msm/mt9d112.h b/drivers/media/video/msm/mt9d112.h
deleted file mode 100644
index 309fcec..0000000
--- a/drivers/media/video/msm/mt9d112.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Copyright (c) 2009, Code Aurora Forum. 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 MT9D112_H
-#define MT9D112_H
-
-#include <linux/types.h>
-#include <mach/camera.h>
-
-extern struct mt9d112_reg mt9d112_regs;
-
-enum mt9d112_width {
-	WORD_LEN,
-	BYTE_LEN
-};
-
-struct mt9d112_i2c_reg_conf {
-	unsigned short waddr;
-	unsigned short wdata;
-	enum mt9d112_width width;
-	unsigned short mdelay_time;
-};
-
-struct mt9d112_reg {
-	const struct register_address_value_pair *prev_snap_reg_settings;
-	uint16_t prev_snap_reg_settings_size;
-	const struct register_address_value_pair *noise_reduction_reg_settings;
-	uint16_t noise_reduction_reg_settings_size;
-	const struct mt9d112_i2c_reg_conf *plltbl;
-	uint16_t plltbl_size;
-	const struct mt9d112_i2c_reg_conf *stbl;
-	uint16_t stbl_size;
-	const struct mt9d112_i2c_reg_conf *rftbl;
-	uint16_t rftbl_size;
-};
-
-#endif /* MT9D112_H */
diff --git a/drivers/media/video/msm/mt9d112_reg.c b/drivers/media/video/msm/mt9d112_reg.c
deleted file mode 100644
index 24edaf2..0000000
--- a/drivers/media/video/msm/mt9d112_reg.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/* Copyright (c) 2009, Code Aurora Forum. 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 "mt9d112.h"
-
-
-struct register_address_value_pair const
-preview_snapshot_mode_reg_settings_array[] = {
-	{0x338C, 0x2703},
-	{0x3390, 800},    /* Output Width (P) = 640 */
-	{0x338C, 0x2705},
-	{0x3390, 600},    /* Output Height (P) = 480 */
-	{0x338C, 0x2707},
-	{0x3390, 0x0640}, /* Output Width (S) = 1600 */
-	{0x338C, 0x2709},
-	{0x3390, 0x04B0}, /* Output Height (S) = 1200 */
-	{0x338C, 0x270D},
-	{0x3390, 0x0000}, /* Row Start (P) = 0 */
-	{0x338C, 0x270F},
-	{0x3390, 0x0000}, /* Column Start (P) = 0 */
-	{0x338C, 0x2711},
-	{0x3390, 0x04BD}, /* Row End (P) = 1213 */
-	{0x338C, 0x2713},
-	{0x3390, 0x064D}, /* Column End (P) = 1613 */
-	{0x338C, 0x2715},
-	{0x3390, 0x0000}, /* Extra Delay (P) = 0 */
-	{0x338C, 0x2717},
-	{0x3390, 0x2111}, /* Row Speed (P) = 8465 */
-	{0x338C, 0x2719},
-	{0x3390, 0x046C}, /* Read Mode (P) = 1132 */
-	{0x338C, 0x271B},
-	{0x3390, 0x024F}, /* Sensor_Sample_Time_pck(P) = 591 */
-	{0x338C, 0x271D},
-	{0x3390, 0x0102}, /* Sensor_Fine_Correction(P) = 258 */
-	{0x338C, 0x271F},
-	{0x3390, 0x0279}, /* Sensor_Fine_IT_min(P) = 633 */
-	{0x338C, 0x2721},
-	{0x3390, 0x0155}, /* Sensor_Fine_IT_max_margin(P) = 341 */
-	{0x338C, 0x2723},
-	{0x3390, 659},    /* Frame Lines (P) = 679 */
-	{0x338C, 0x2725},
-	{0x3390, 0x061B}, /* Line Length (P) = 1563 */
-	{0x338C, 0x2727},
-	{0x3390, 0x2020},
-	{0x338C, 0x2729},
-	{0x3390, 0x2020},
-	{0x338C, 0x272B},
-	{0x3390, 0x1020},
-	{0x338C, 0x272D},
-	{0x3390, 0x2007},
-	{0x338C, 0x272F},
-	{0x3390, 0x0004}, /* Row Start(S) = 4 */
-	{0x338C, 0x2731},
-	{0x3390, 0x0004}, /* Column Start(S) = 4 */
-	{0x338C, 0x2733},
-	{0x3390, 0x04BB}, /* Row End(S) = 1211 */
-	{0x338C, 0x2735},
-	{0x3390, 0x064B}, /* Column End(S) = 1611 */
-	{0x338C, 0x2737},
-	{0x3390, 0x04CE}, /* Extra Delay(S) = 1230 */
-	{0x338C, 0x2739},
-	{0x3390, 0x2111}, /* Row Speed(S) = 8465 */
-	{0x338C, 0x273B},
-	{0x3390, 0x0024}, /* Read Mode(S) = 36 */
-	{0x338C, 0x273D},
-	{0x3390, 0x0120}, /* Sensor sample time pck(S) = 288 */
-	{0x338C, 0x2741},
-	{0x3390, 0x0169}, /* Sensor_Fine_IT_min(P) = 361 */
-	{0x338C, 0x2745},
-	{0x3390, 0x04FF}, /* Frame Lines(S) = 1279 */
-	{0x338C, 0x2747},
-	{0x3390, 0x0824}, /* Line Length(S) = 2084 */
-	{0x338C, 0x2751},
-	{0x3390, 0x0000}, /* Crop_X0(P) = 0 */
-	{0x338C, 0x2753},
-	{0x3390, 0x0320}, /* Crop_X1(P) = 800 */
-	{0x338C, 0x2755},
-	{0x3390, 0x0000}, /* Crop_Y0(P) = 0 */
-	{0x338C, 0x2757},
-	{0x3390, 0x0258}, /* Crop_Y1(P) = 600 */
-	{0x338C, 0x275F},
-	{0x3390, 0x0000}, /* Crop_X0(S) = 0 */
-	{0x338C, 0x2761},
-	{0x3390, 0x0640}, /* Crop_X1(S) = 1600 */
-	{0x338C, 0x2763},
-	{0x3390, 0x0000}, /* Crop_Y0(S) = 0 */
-	{0x338C, 0x2765},
-	{0x3390, 0x04B0}, /* Crop_Y1(S) = 1200 */
-	{0x338C, 0x222E},
-	{0x3390, 0x00A0}, /* R9 Step = 160 */
-	{0x338C, 0xA408},
-	{0x3390, 0x001F},
-	{0x338C, 0xA409},
-	{0x3390, 0x0021},
-	{0x338C, 0xA40A},
-	{0x3390, 0x0025},
-	{0x338C, 0xA40B},
-	{0x3390, 0x0027},
-	{0x338C, 0x2411},
-	{0x3390, 0x00A0},
-	{0x338C, 0x2413},
-	{0x3390, 0x00C0},
-	{0x338C, 0x2415},
-	{0x3390, 0x00A0},
-	{0x338C, 0x2417},
-	{0x3390, 0x00C0},
-	{0x338C, 0x2799},
-	{0x3390, 0x6408}, /* MODE_SPEC_EFFECTS(P) */
-	{0x338C, 0x279B},
-	{0x3390, 0x6408}, /* MODE_SPEC_EFFECTS(S) */
-};
-
-static struct register_address_value_pair const
-noise_reduction_reg_settings_array[] = {
-	{0x338C, 0xA76D},
-	{0x3390, 0x0003},
-	{0x338C, 0xA76E},
-	{0x3390, 0x0003},
-	{0x338C, 0xA76F},
-	{0x3390, 0},
-	{0x338C, 0xA770},
-	{0x3390, 21},
-	{0x338C, 0xA771},
-	{0x3390, 37},
-	{0x338C, 0xA772},
-	{0x3390, 63},
-	{0x338C, 0xA773},
-	{0x3390, 100},
-	{0x338C, 0xA774},
-	{0x3390, 128},
-	{0x338C, 0xA775},
-	{0x3390, 151},
-	{0x338C, 0xA776},
-	{0x3390, 169},
-	{0x338C, 0xA777},
-	{0x3390, 186},
-	{0x338C, 0xA778},
-	{0x3390, 199},
-	{0x338C, 0xA779},
-	{0x3390, 210},
-	{0x338C, 0xA77A},
-	{0x3390, 220},
-	{0x338C, 0xA77B},
-	{0x3390, 228},
-	{0x338C, 0xA77C},
-	{0x3390, 234},
-	{0x338C, 0xA77D},
-	{0x3390, 240},
-	{0x338C, 0xA77E},
-	{0x3390, 244},
-	{0x338C, 0xA77F},
-	{0x3390, 248},
-	{0x338C, 0xA780},
-	{0x3390, 252},
-	{0x338C, 0xA781},
-	{0x3390, 255},
-	{0x338C, 0xA782},
-	{0x3390, 0},
-	{0x338C, 0xA783},
-	{0x3390, 21},
-	{0x338C, 0xA784},
-	{0x3390, 37},
-	{0x338C, 0xA785},
-	{0x3390, 63},
-	{0x338C, 0xA786},
-	{0x3390, 100},
-	{0x338C, 0xA787},
-	{0x3390, 128},
-	{0x338C, 0xA788},
-	{0x3390, 151},
-	{0x338C, 0xA789},
-	{0x3390, 169},
-	{0x338C, 0xA78A},
-	{0x3390, 186},
-	{0x338C, 0xA78B},
-	{0x3390, 199},
-	{0x338C, 0xA78C},
-	{0x3390, 210},
-	{0x338C, 0xA78D},
-	{0x3390, 220},
-	{0x338C, 0xA78E},
-	{0x3390, 228},
-	{0x338C, 0xA78F},
-	{0x3390, 234},
-	{0x338C, 0xA790},
-	{0x3390, 240},
-	{0x338C, 0xA791},
-	{0x3390, 244},
-	{0x338C, 0xA793},
-	{0x3390, 252},
-	{0x338C, 0xA794},
-	{0x3390, 255},
-	{0x338C, 0xA103},
-	{0x3390, 6},
-};
-
-static const struct mt9d112_i2c_reg_conf const lens_roll_off_tbl[] = {
-	{ 0x34CE, 0x81A0, WORD_LEN, 0 },
-	{ 0x34D0, 0x6331, WORD_LEN, 0 },
-	{ 0x34D2, 0x3394, WORD_LEN, 0 },
-	{ 0x34D4, 0x9966, WORD_LEN, 0 },
-	{ 0x34D6, 0x4B25, WORD_LEN, 0 },
-	{ 0x34D8, 0x2670, WORD_LEN, 0 },
-	{ 0x34DA, 0x724C, WORD_LEN, 0 },
-	{ 0x34DC, 0xFFFD, WORD_LEN, 0 },
-	{ 0x34DE, 0x00CA, WORD_LEN, 0 },
-	{ 0x34E6, 0x00AC, WORD_LEN, 0 },
-	{ 0x34EE, 0x0EE1, WORD_LEN, 0 },
-	{ 0x34F6, 0x0D87, WORD_LEN, 0 },
-	{ 0x3500, 0xE1F7, WORD_LEN, 0 },
-	{ 0x3508, 0x1CF4, WORD_LEN, 0 },
-	{ 0x3510, 0x1D28, WORD_LEN, 0 },
-	{ 0x3518, 0x1F26, WORD_LEN, 0 },
-	{ 0x3520, 0x2220, WORD_LEN, 0 },
-	{ 0x3528, 0x333D, WORD_LEN, 0 },
-	{ 0x3530, 0x15D9, WORD_LEN, 0 },
-	{ 0x3538, 0xCFB8, WORD_LEN, 0 },
-	{ 0x354C, 0x05FE, WORD_LEN, 0 },
-	{ 0x3544, 0x05F8, WORD_LEN, 0 },
-	{ 0x355C, 0x0596, WORD_LEN, 0 },
-	{ 0x3554, 0x0611, WORD_LEN, 0 },
-	{ 0x34E0, 0x00F2, WORD_LEN, 0 },
-	{ 0x34E8, 0x00A8, WORD_LEN, 0 },
-	{ 0x34F0, 0x0F7B, WORD_LEN, 0 },
-	{ 0x34F8, 0x0CD7, WORD_LEN, 0 },
-	{ 0x3502, 0xFEDB, WORD_LEN, 0 },
-	{ 0x350A, 0x13E4, WORD_LEN, 0 },
-	{ 0x3512, 0x1F2C, WORD_LEN, 0 },
-	{ 0x351A, 0x1D20, WORD_LEN, 0 },
-	{ 0x3522, 0x2422, WORD_LEN, 0 },
-	{ 0x352A, 0x2925, WORD_LEN, 0 },
-	{ 0x3532, 0x1D04, WORD_LEN, 0 },
-	{ 0x353A, 0xFBF2, WORD_LEN, 0 },
-	{ 0x354E, 0x0616, WORD_LEN, 0 },
-	{ 0x3546, 0x0597, WORD_LEN, 0 },
-	{ 0x355E, 0x05CD, WORD_LEN, 0 },
-	{ 0x3556, 0x0529, WORD_LEN, 0 },
-	{ 0x34E4, 0x00B2, WORD_LEN, 0 },
-	{ 0x34EC, 0x005E, WORD_LEN, 0 },
-	{ 0x34F4, 0x0F43, WORD_LEN, 0 },
-	{ 0x34FC, 0x0E2F, WORD_LEN, 0 },
-	{ 0x3506, 0xF9FC, WORD_LEN, 0 },
-	{ 0x350E, 0x0CE4, WORD_LEN, 0 },
-	{ 0x3516, 0x1E1E, WORD_LEN, 0 },
-	{ 0x351E, 0x1B19, WORD_LEN, 0 },
-	{ 0x3526, 0x151B, WORD_LEN, 0 },
-	{ 0x352E, 0x1416, WORD_LEN, 0 },
-	{ 0x3536, 0x10FC, WORD_LEN, 0 },
-	{ 0x353E, 0xC018, WORD_LEN, 0 },
-	{ 0x3552, 0x06B4, WORD_LEN, 0 },
-	{ 0x354A, 0x0506, WORD_LEN, 0 },
-	{ 0x3562, 0x06AB, WORD_LEN, 0 },
-	{ 0x355A, 0x063A, WORD_LEN, 0 },
-	{ 0x34E2, 0x00E5, WORD_LEN, 0 },
-	{ 0x34EA, 0x008B, WORD_LEN, 0 },
-	{ 0x34F2, 0x0E4C, WORD_LEN, 0 },
-	{ 0x34FA, 0x0CA3, WORD_LEN, 0 },
-	{ 0x3504, 0x0907, WORD_LEN, 0 },
-	{ 0x350C, 0x1DFD, WORD_LEN, 0 },
-	{ 0x3514, 0x1E24, WORD_LEN, 0 },
-	{ 0x351C, 0x2529, WORD_LEN, 0 },
-	{ 0x3524, 0x1D20, WORD_LEN, 0 },
-	{ 0x352C, 0x2332, WORD_LEN, 0 },
-	{ 0x3534, 0x10E9, WORD_LEN, 0 },
-	{ 0x353C, 0x0BCB, WORD_LEN, 0 },
-	{ 0x3550, 0x04EF, WORD_LEN, 0 },
-	{ 0x3548, 0x0609, WORD_LEN, 0 },
-	{ 0x3560, 0x0580, WORD_LEN, 0 },
-	{ 0x3558, 0x05DD, WORD_LEN, 0 },
-	{ 0x3540, 0x0000, WORD_LEN, 0 },
-	{ 0x3542, 0x0000, WORD_LEN, 0 }
-};
-
-static const struct mt9d112_i2c_reg_conf const pll_setup_tbl[] = {
-	{ 0x341E, 0x8F09, WORD_LEN, 0 },
-	{ 0x341C, 0x0250, WORD_LEN, 0 },
-	{ 0x341E, 0x8F09, WORD_LEN, 5 },
-	{ 0x341E, 0x8F08, WORD_LEN, 0 }
-};
-
-/* Refresh Sequencer */
-static const struct mt9d112_i2c_reg_conf const sequencer_tbl[] = {
-	{ 0x338C, 0x2799, WORD_LEN, 0},
-	{ 0x3390, 0x6440, WORD_LEN, 5},
-	{ 0x338C, 0x279B, WORD_LEN, 0},
-	{ 0x3390, 0x6440, WORD_LEN, 5},
-	{ 0x338C, 0xA103, WORD_LEN, 0},
-	{ 0x3390, 0x0005, WORD_LEN, 5},
-	{ 0x338C, 0xA103, WORD_LEN, 0},
-	{ 0x3390, 0x0006, WORD_LEN, 5}
-};
-
-struct mt9d112_reg mt9d112_regs = {
-	.prev_snap_reg_settings = &preview_snapshot_mode_reg_settings_array[0],
-	.prev_snap_reg_settings_size = ARRAY_SIZE(
-		preview_snapshot_mode_reg_settings_array),
-	.noise_reduction_reg_settings = &noise_reduction_reg_settings_array[0],
-	.noise_reduction_reg_settings_size = ARRAY_SIZE(
-		noise_reduction_reg_settings_array),
-	.plltbl = pll_setup_tbl,
-	.plltbl_size = ARRAY_SIZE(pll_setup_tbl),
-	.stbl = sequencer_tbl,
-	.stbl_size = ARRAY_SIZE(sequencer_tbl),
-	.rftbl = lens_roll_off_tbl,
-	.rftbl_size = ARRAY_SIZE(lens_roll_off_tbl)
-};
-
-
-
diff --git a/drivers/media/video/msm/mt9d113.c b/drivers/media/video/msm/mt9d113.c
deleted file mode 100644
index 8e81bda..0000000
--- a/drivers/media/video/msm/mt9d113.c
+++ /dev/null
@@ -1,656 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. 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/delay.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <media/msm_camera.h>
-#include <mach/gpio.h>
-#include "mt9d113.h"
-
-/* Micron MT9D113 Registers and their values */
-#define  REG_MT9D113_MODEL_ID	0x0000
-#define  MT9D113_MODEL_ID		0x2580
-#define Q8						0x00000100
-
-struct mt9d113_work {
-	struct work_struct work;
-};
-
-static struct  mt9d113_work *mt9d113_sensorw;
-static struct  i2c_client *mt9d113_client;
-
-struct mt9d113_ctrl {
-	const struct msm_camera_sensor_info *sensordata;
-	uint32_t sensormode;
-	uint32_t fps_divider;/* init to 1 * 0x00000400 */
-	uint32_t pict_fps_divider;/* init to 1 * 0x00000400 */
-	uint16_t fps;
-	uint16_t curr_step_pos;
-	uint16_t my_reg_gain;
-	uint32_t my_reg_line_count;
-	uint16_t total_lines_per_frame;
-	uint16_t config_csi;
-	enum mt9d113_resolution_t prev_res;
-	enum mt9d113_resolution_t pict_res;
-	enum mt9d113_resolution_t curr_res;
-	enum mt9d113_test_mode_t  set_test;
-};
-
-static struct mt9d113_ctrl *mt9d113_ctrl;
-
-static DECLARE_WAIT_QUEUE_HEAD(mt9d113_wait_queue);
-DEFINE_MUTEX(mt9d113_mut);
-
-static int mt9d113_i2c_rxdata(unsigned short saddr,
-				unsigned char *rxdata, int length)
-{
-	struct i2c_msg msgs[] = {
-		{
-			.addr   = saddr,
-			.flags = 0,
-			.len   = 2,
-			.buf   = rxdata,
-		},
-		{
-			.addr   = saddr,
-			.flags = I2C_M_RD,
-			.len   = length,
-			.buf   = rxdata,
-		},
-	};
-	if (i2c_transfer(mt9d113_client->adapter, msgs, 2) < 0) {
-		CDBG("mt9d113_i2c_rxdata failed!\n");
-		return -EIO;
-	}
-	return 0;
-}
-
-static int32_t mt9d113_i2c_read(unsigned short   saddr,
-				unsigned short raddr,
-				unsigned short *rdata,
-				enum mt9d113_width width)
-{
-	int32_t rc = 0;
-	unsigned char buf[4];
-	if (!rdata)
-		return -EIO;
-	memset(buf, 0, sizeof(buf));
-	switch (width) {
-	case WORD_LEN: {
-			buf[0] = (raddr & 0xFF00)>>8;
-			buf[1] = (raddr & 0x00FF);
-			rc = mt9d113_i2c_rxdata(saddr, buf, 2);
-			if (rc < 0)
-				return rc;
-			*rdata = buf[0] << 8 | buf[1];
-		}
-		break;
-	default:
-		break;
-	}
-	if (rc < 0)
-		CDBG("mt9d113_i2c_read failed !\n");
-	return rc;
-}
-
-static int32_t mt9d113_i2c_txdata(unsigned short saddr,
-				unsigned char *txdata, int length)
-{
-	struct i2c_msg msg[] = {
-		{
-			.addr = saddr,
-			.flags = 0,
-			.len = length,
-			.buf = txdata,
-		},
-	};
-	if (i2c_transfer(mt9d113_client->adapter, msg, 1) < 0) {
-		CDBG("mt9d113_i2c_txdata failed\n");
-		return -EIO;
-	}
-	return 0;
-}
-
-static int32_t mt9d113_i2c_write(unsigned short saddr,
-				unsigned short waddr,
-				unsigned short wdata,
-				enum mt9d113_width width)
-{
-	int32_t rc = -EIO;
-	unsigned char buf[4];
-	memset(buf, 0, sizeof(buf));
-	switch (width) {
-	case WORD_LEN: {
-			buf[0] = (waddr & 0xFF00)>>8;
-			buf[1] = (waddr & 0x00FF);
-			buf[2] = (wdata & 0xFF00)>>8;
-			buf[3] = (wdata & 0x00FF);
-			rc = mt9d113_i2c_txdata(saddr, buf, 4);
-		}
-		break;
-	case BYTE_LEN: {
-			buf[0] = waddr;
-			buf[1] = wdata;
-			rc = mt9d113_i2c_txdata(saddr, buf, 2);
-		}
-		break;
-	default:
-		break;
-	}
-	if (rc < 0)
-		printk(KERN_ERR
-			"i2c_write failed, addr = 0x%x, val = 0x%x!\n",
-			waddr, wdata);
-	return rc;
-}
-
-static int32_t mt9d113_i2c_write_table(
-				struct mt9d113_i2c_reg_conf
-				const *reg_conf_tbl,
-				int num_of_items_in_table)
-{
-	int i;
-	int32_t rc = -EIO;
-	for (i = 0; i < num_of_items_in_table; i++) {
-		rc = mt9d113_i2c_write(mt9d113_client->addr,
-				reg_conf_tbl->waddr, reg_conf_tbl->wdata,
-				WORD_LEN);
-		if (rc < 0)
-			break;
-		reg_conf_tbl++;
-	}
-	return rc;
-}
-
-static long mt9d113_reg_init(void)
-{
-	uint16_t data = 0;
-	int32_t rc = 0;
-	int count = 0;
-	struct msm_camera_csi_params mt9d113_csi_params;
-	if (!mt9d113_ctrl->config_csi) {
-		mt9d113_csi_params.lane_cnt = 1;
-		mt9d113_csi_params.data_format = CSI_8BIT;
-		mt9d113_csi_params.lane_assign = 0xe4;
-		mt9d113_csi_params.dpcm_scheme = 0;
-		mt9d113_csi_params.settle_cnt = 0x14;
-		rc = msm_camio_csi_config(&mt9d113_csi_params);
-		mt9d113_ctrl->config_csi = 1;
-		msleep(50);
-	}
-	/* Disable parallel and enable mipi*/
-	rc = mt9d113_i2c_write(mt9d113_client->addr,
-				0x001A,
-				0x0051, WORD_LEN);
-	rc = mt9d113_i2c_write(mt9d113_client->addr,
-				0x001A,
-				0x0050,
-				WORD_LEN);
-	msleep(20);
-	rc = mt9d113_i2c_write(mt9d113_client->addr,
-				0x001A,
-				0x0058,
-				WORD_LEN);
-
-	/* Preset pll settings begin*/
-	rc = mt9d113_i2c_write_table(&mt9d113_regs.pll_tbl[0],
-				mt9d113_regs.pll_tbl_size);
-	if (rc < 0)
-		return rc;
-	rc = mt9d113_i2c_read(mt9d113_client->addr,
-				0x0014, &data, WORD_LEN);
-	data = data&0x8000;
-	/* Poll*/
-	while (data == 0x0000) {
-		data = 0;
-		rc = mt9d113_i2c_read(mt9d113_client->addr,
-				0x0014, &data, WORD_LEN);
-		data = data & 0x8000;
-		usleep_range(11000, 12000);
-		count++;
-		if (count == 100) {
-			CDBG(" Timeout:1\n");
-			break;
-		}
-	}
-	rc = mt9d113_i2c_write(mt9d113_client->addr,
-				0x0014,
-				0x20FA,
-				WORD_LEN);
-
-	/*Preset pll Ends*/
-	mt9d113_i2c_write(mt9d113_client->addr,
-				0x0018,
-				0x402D,
-				WORD_LEN);
-
-	mt9d113_i2c_write(mt9d113_client->addr,
-				0x0018,
-				0x402C,
-				WORD_LEN);
-	/*POLL_REG=0x0018,0x4000,!=0x0000,DELAY=10,TIMEOUT=100*/
-	data = 0;
-	rc = mt9d113_i2c_read(mt9d113_client->addr,
-		0x0018, &data, WORD_LEN);
-	data = data & 0x4000;
-	count = 0;
-	while (data != 0x0000) {
-		rc = mt9d113_i2c_read(mt9d113_client->addr,
-			0x0018, &data, WORD_LEN);
-		data = data & 0x4000;
-		CDBG(" data is %d\n" , data);
-		usleep_range(11000, 12000);
-		count++;
-		if (count == 100) {
-			CDBG(" Loop2 timeout: MT9D113\n");
-			break;
-		}
-		CDBG(" Not streaming\n");
-	}
-	CDBG("MT9D113: Start stream\n");
-	/*Preset Register Wizard Conf*/
-	rc = mt9d113_i2c_write_table(&mt9d113_regs.register_tbl[0],
-				mt9d113_regs.register_tbl_size);
-	if (rc < 0)
-		return rc;
-	rc = mt9d113_i2c_write_table(&mt9d113_regs.err_tbl[0],
-				mt9d113_regs.err_tbl_size);
-	if (rc < 0)
-		return rc;
-	rc = mt9d113_i2c_write_table(&mt9d113_regs.eeprom_tbl[0],
-				mt9d113_regs.eeprom_tbl_size);
-	if (rc < 0)
-		return rc;
-
-	rc = mt9d113_i2c_write_table(&mt9d113_regs.low_light_tbl[0],
-				mt9d113_regs.low_light_tbl_size);
-	if (rc < 0)
-		return rc;
-
-	rc = mt9d113_i2c_write_table(&mt9d113_regs.awb_tbl[0],
-				mt9d113_regs.awb_tbl_size);
-	if (rc < 0)
-		return rc;
-
-	rc = mt9d113_i2c_write_table(&mt9d113_regs.patch_tbl[0],
-				mt9d113_regs.patch_tbl_size);
-	if (rc < 0)
-		return rc;
-
-	/*check patch load*/
-	mt9d113_i2c_write(mt9d113_client->addr,
-				0x098C,
-				0xA024,
-				WORD_LEN);
-	count = 0;
-	/*To check if patch is loaded properly
-	poll the register 0x990 till the condition is
-	met or till the timeout*/
-	data = 0;
-	rc = mt9d113_i2c_read(mt9d113_client->addr,
-				0x0990, &data, WORD_LEN);
-	while (data == 0) {
-		data = 0;
-		rc = mt9d113_i2c_read(mt9d113_client->addr,
-				0x0990, &data, WORD_LEN);
-		usleep_range(11000, 12000);
-		count++;
-		if (count == 100) {
-			CDBG("Timeout in patch loading\n");
-			break;
-		}
-	}
-		/*BITFIELD=0x0018, 0x0004, 0*/
-	/*Preset continue begin */
-	rc = mt9d113_i2c_write(mt9d113_client->addr, 0x0018, 0x0028,
-				WORD_LEN);
-	CDBG(" mt9d113 wait for seq done\n");
-	/* syncronize the FW with the sensor
-	MCU_ADDRESS [SEQ_CMD]*/
-	rc = mt9d113_i2c_write(mt9d113_client->addr,
-				0x098C, 0xA103, WORD_LEN);
-	rc = mt9d113_i2c_write(mt9d113_client->addr,
-				0x0990, 0x0006, WORD_LEN);
-		/*mt9d113 wait for seq done
-	 syncronize the FW with the sensor */
-	msleep(20);
-	/*Preset continue end */
-	CDBG(" MT9D113: Preset continue end\n");
-	rc = mt9d113_i2c_write(mt9d113_client->addr,
-				0x0012,
-				0x00F5,
-				WORD_LEN);
-	/*continue begin */
-	CDBG(" MT9D113: Preset continue begin\n");
-	rc = mt9d113_i2c_write(mt9d113_client->addr, 0x0018, 0x0028 ,
-				WORD_LEN);
-	/*mt9d113 wait for seq done
-	 syncronize the FW with the sensor
-	MCU_ADDRESS [SEQ_CMD]*/
-	msleep(20);
-	rc = mt9d113_i2c_write(mt9d113_client->addr,
-				0x098C, 0xA103, WORD_LEN);
-	/* MCU DATA */
-	rc = mt9d113_i2c_write(mt9d113_client->addr, 0x0990,
-				0x0006, WORD_LEN);
-	/*mt9d113 wait for seq done
-	syncronize the FW with the sensor */
-	/* MCU_ADDRESS [SEQ_CMD]*/
-	msleep(20);
-	/*Preset continue end*/
-	return rc;
-
-}
-
-static long mt9d113_set_sensor_mode(int mode)
-{
-	long rc = 0;
-	switch (mode) {
-	case SENSOR_PREVIEW_MODE:
-		rc = mt9d113_reg_init();
-		CDBG("MT9D113: configure to preview begin\n");
-		rc =
-		mt9d113_i2c_write(mt9d113_client->addr,
-						0x098C, 0xA115, WORD_LEN);
-		if (rc < 0)
-			return rc;
-		rc =
-		mt9d113_i2c_write(mt9d113_client->addr,
-						0x0990, 0x0000, WORD_LEN);
-		if (rc < 0)
-			return rc;
-		rc =
-		mt9d113_i2c_write(mt9d113_client->addr,
-						0x098C, 0xA103, WORD_LEN);
-		if (rc < 0)
-			return rc;
-		rc =
-		mt9d113_i2c_write(mt9d113_client->addr,
-						0x0990, 0x0001, WORD_LEN);
-		if (rc < 0)
-			return rc;
-		break;
-	case SENSOR_SNAPSHOT_MODE:
-	case SENSOR_RAW_SNAPSHOT_MODE:
-		rc =
-		mt9d113_i2c_write(mt9d113_client->addr,
-						0x098C, 0xA115, WORD_LEN);
-		rc =
-		mt9d113_i2c_write(mt9d113_client->addr,
-						0x0990, 0x0002, WORD_LEN);
-		rc =
-		mt9d113_i2c_write(mt9d113_client->addr,
-						0x098C, 0xA103, WORD_LEN);
-		rc =
-		mt9d113_i2c_write(mt9d113_client->addr,
-						0x0990, 0x0002, WORD_LEN);
-		break;
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static int mt9d113_sensor_init_probe(const struct
-				msm_camera_sensor_info * data)
-{
-	uint16_t model_id = 0;
-	int rc = 0;
-	/* Read the Model ID of the sensor */
-	rc = mt9d113_i2c_read(mt9d113_client->addr,
-						REG_MT9D113_MODEL_ID,
-						&model_id, WORD_LEN);
-	if (rc < 0)
-		goto init_probe_fail;
-	/* Check if it matches it with the value in Datasheet */
-	if (model_id != MT9D113_MODEL_ID)
-		printk(KERN_INFO "mt9d113 model_id = 0x%x\n", model_id);
-	if (rc < 0)
-		goto init_probe_fail;
-	return rc;
-init_probe_fail:
-	printk(KERN_INFO "probe fail\n");
-	return rc;
-}
-
-static int mt9d113_init_client(struct i2c_client *client)
-{
-	/* Initialize the MSM_CAMI2C Chip */
-	init_waitqueue_head(&mt9d113_wait_queue);
-	return 0;
-}
-
-int mt9d113_sensor_config(void __user *argp)
-{
-	struct sensor_cfg_data cfg_data;
-	long rc = 0;
-
-	if (copy_from_user(&cfg_data,
-					(void *)argp,
-					(sizeof(struct sensor_cfg_data))))
-		return -EFAULT;
-	mutex_lock(&mt9d113_mut);
-	CDBG("mt9d113_ioctl, cfgtype = %d, mode = %d\n",
-		 cfg_data.cfgtype, cfg_data.mode);
-	switch (cfg_data.cfgtype) {
-	case CFG_SET_MODE:
-		rc = mt9d113_set_sensor_mode(
-						cfg_data.mode);
-		break;
-	case CFG_SET_EFFECT:
-		return rc;
-	case CFG_GET_AF_MAX_STEPS:
-	default:
-		rc = -EINVAL;
-		break;
-	}
-	mutex_unlock(&mt9d113_mut);
-	return rc;
-}
-
-int mt9d113_sensor_release(void)
-{
-	int rc = 0;
-
-	mutex_lock(&mt9d113_mut);
-	gpio_set_value_cansleep(mt9d113_ctrl->sensordata->sensor_reset, 0);
-	msleep(20);
-	gpio_free(mt9d113_ctrl->sensordata->sensor_reset);
-	kfree(mt9d113_ctrl);
-	mutex_unlock(&mt9d113_mut);
-
-	return rc;
-}
-
-static int mt9d113_probe_init_done(const struct msm_camera_sensor_info
-				*data)
-{
-	gpio_free(data->sensor_reset);
-	return 0;
-}
-
-static int mt9d113_probe_init_sensor(const struct msm_camera_sensor_info
-				*data)
-{
-	int32_t rc = 0;
-	uint16_t chipid = 0;
-
-	rc = gpio_request(data->sensor_reset, "mt9d113");
-	printk(KERN_INFO " mt9d113_probe_init_sensor\n");
-	if (!rc) {
-		printk(KERN_INFO "sensor_reset = %d\n", rc);
-		gpio_direction_output(data->sensor_reset, 0);
-		usleep_range(11000, 12000);
-		gpio_set_value_cansleep(data->sensor_reset, 1);
-		usleep_range(11000, 12000);
-	} else
-		goto init_probe_done;
-	printk(KERN_INFO " mt9d113_probe_init_sensor called\n");
-	rc = mt9d113_i2c_read(mt9d113_client->addr, REG_MT9D113_MODEL_ID,
-						&chipid, WORD_LEN);
-	if (rc < 0)
-		goto init_probe_fail;
-	/*Compare sensor ID to MT9D113 ID: */
-	if (chipid != MT9D113_MODEL_ID) {
-		printk(KERN_INFO "mt9d113_probe_init_sensor chip id is%d\n",
-			chipid);
-	}
-	CDBG("mt9d113_probe_init_sensor Success\n");
-	goto init_probe_done;
-init_probe_fail:
-	CDBG(" ov2720_probe_init_sensor fails\n");
-	gpio_set_value_cansleep(data->sensor_reset, 0);
-	mt9d113_probe_init_done(data);
-init_probe_done:
-	printk(KERN_INFO " mt9d113_probe_init_sensor finishes\n");
-	return rc;
-}
-
-static int mt9d113_i2c_probe(struct i2c_client *client,
-				const struct i2c_device_id *id)
-{
-	int rc = 0;
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		rc = -ENOTSUPP;
-		goto probe_failure;
-	}
-	mt9d113_sensorw =
-	kzalloc(sizeof(struct mt9d113_work), GFP_KERNEL);
-	if (!mt9d113_sensorw) {
-		rc = -ENOMEM;
-		goto probe_failure;
-	}
-	i2c_set_clientdata(client, mt9d113_sensorw);
-	mt9d113_init_client(client);
-	mt9d113_client = client;
-	CDBG("mt9d113_probe succeeded!\n");
-	return 0;
-probe_failure:
-	kfree(mt9d113_sensorw);
-	mt9d113_sensorw = NULL;
-	CDBG("mt9d113_probe failed!\n");
-	return rc;
-}
-
-static const struct i2c_device_id mt9d113_i2c_id[] = {
-	{ "mt9d113", 0},
-	{},
-};
-
-static struct i2c_driver mt9d113_i2c_driver = {
-	.id_table = mt9d113_i2c_id,
-	.probe  = mt9d113_i2c_probe,
-	.remove = __exit_p(mt9d113_i2c_remove),
-			  .driver = {
-		.name = "mt9d113",
-	},
-};
-
-int mt9d113_sensor_open_init(const struct msm_camera_sensor_info *data)
-{
-	int32_t rc = 0;
-	mt9d113_ctrl = kzalloc(sizeof(struct mt9d113_ctrl), GFP_KERNEL);
-	if (!mt9d113_ctrl) {
-		printk(KERN_INFO "mt9d113_init failed!\n");
-		rc = -ENOMEM;
-		goto init_done;
-	}
-	mt9d113_ctrl->fps_divider = 1 * 0x00000400;
-	mt9d113_ctrl->pict_fps_divider = 1 * 0x00000400;
-	mt9d113_ctrl->set_test = TEST_OFF;
-	mt9d113_ctrl->config_csi = 0;
-	mt9d113_ctrl->prev_res = QTR_SIZE;
-	mt9d113_ctrl->pict_res = FULL_SIZE;
-	mt9d113_ctrl->curr_res = INVALID_SIZE;
-	if (data)
-		mt9d113_ctrl->sensordata = data;
-	if (rc < 0) {
-		printk(KERN_INFO "mt9d113_sensor_open_init fail\n");
-		return rc;
-	}
-		/* enable mclk first */
-		msm_camio_clk_rate_set(24000000);
-		msleep(20);
-		rc = mt9d113_probe_init_sensor(data);
-		if (rc < 0)
-			goto init_fail;
-		mt9d113_ctrl->fps = 30*Q8;
-		rc = mt9d113_sensor_init_probe(data);
-		if (rc < 0) {
-			gpio_set_value_cansleep(data->sensor_reset, 0);
-			goto init_fail;
-		} else
-			printk(KERN_ERR "%s: %d\n", __func__, __LINE__);
-		goto init_done;
-init_fail:
-		printk(KERN_INFO "init_fail\n");
-		mt9d113_probe_init_done(data);
-init_done:
-		CDBG("init_done\n");
-		return rc;
-}
-
-static int mt9d113_sensor_probe(const struct msm_camera_sensor_info
-				*info,
-				struct msm_sensor_ctrl *s)
-{
-	int rc = 0;
-	rc = i2c_add_driver(&mt9d113_i2c_driver);
-	if (rc < 0 || mt9d113_client == NULL) {
-		rc = -ENOTSUPP;
-		goto probe_fail;
-	}
-	msm_camio_clk_rate_set(24000000);
-	usleep_range(5000, 6000);
-	rc = mt9d113_probe_init_sensor(info);
-	if (rc < 0)
-		goto probe_fail;
-	s->s_init = mt9d113_sensor_open_init;
-	s->s_release = mt9d113_sensor_release;
-	s->s_config  = mt9d113_sensor_config;
-	s->s_camera_type = FRONT_CAMERA_2D;
-	s->s_mount_angle  = 0;
-	gpio_set_value_cansleep(info->sensor_reset, 0);
-	mt9d113_probe_init_done(info);
-	return rc;
-probe_fail:
-	printk(KERN_INFO "mt9d113_sensor_probe: SENSOR PROBE FAILS!\n");
-	return rc;
-}
-
-static int __mt9d113_probe(struct platform_device *pdev)
-{
-	return msm_camera_drv_start(pdev, mt9d113_sensor_probe);
-}
-
-static struct platform_driver msm_camera_driver = {
-	.probe = __mt9d113_probe,
-	.driver = {
-		.name = "msm_cam_mt9d113",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init mt9d113_init(void)
-{
-	return platform_driver_register(&msm_camera_driver);
-}
-
-module_init(mt9d113_init);
-
-MODULE_DESCRIPTION("Micron 2MP YUV sensor driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/mt9d113.h b/drivers/media/video/msm/mt9d113.h
deleted file mode 100644
index f22f16c..0000000
--- a/drivers/media/video/msm/mt9d113.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. 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 MT9D113_H
-#define MT9D113_H
-
-#include <linux/types.h>
-#include <mach/camera.h>
-
-extern struct mt9d113_reg mt9d113_regs;
-
-enum mt9d113_width {
-	WORD_LEN,
-	BYTE_LEN
-};
-
-struct mt9d113_i2c_reg_conf {
-	unsigned short waddr;
-	unsigned short wdata;
-};
-
-struct mt9d113_reg {
-	const struct mt9d113_i2c_reg_conf *pll_tbl;
-	uint16_t pll_tbl_size;
-	const struct mt9d113_i2c_reg_conf *register_tbl;
-	uint16_t register_tbl_size;
-	const struct mt9d113_i2c_reg_conf *err_tbl;
-	uint16_t err_tbl_size;
-	const struct mt9d113_i2c_reg_conf *low_light_tbl;
-	uint16_t low_light_tbl_size;
-	const struct mt9d113_i2c_reg_conf *awb_tbl;
-	uint16_t awb_tbl_size;
-	const struct mt9d113_i2c_reg_conf *patch_tbl;
-	uint16_t patch_tbl_size;
-	const struct mt9d113_i2c_reg_conf *eeprom_tbl ;
-	uint16_t eeprom_tbl_size ;
-};
-
-enum mt9d113_test_mode_t {
-	TEST_OFF,
-	TEST_1,
-	TEST_2,
-	TEST_3
-};
-
-enum mt9d113_resolution_t {
-	QTR_SIZE,
-	FULL_SIZE,
-	INVALID_SIZE
-};
-
-enum mt9d113_setting {
-	RES_PREVIEW,
-	RES_CAPTURE
-};
-#endif /* MT9D113_H */
diff --git a/drivers/media/video/msm/mt9d113_reg.c b/drivers/media/video/msm/mt9d113_reg.c
deleted file mode 100644
index cd5be0f..0000000
--- a/drivers/media/video/msm/mt9d113_reg.c
+++ /dev/null
@@ -1,455 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. 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 "mt9d113.h"
-
-struct mt9d113_i2c_reg_conf const
-	pll_tbl_settings[] = {
-		{0x0014, 0x21F9 }, /*PLL control: BYPASS PLL = 8697*/
-		{0x0010, 0x0115 }, /*PLL Dividers = 277*/
-		{0x0012, 0x0F5  }, /*PLL P Dividers = 245*/
-		{0x0014, 0x21FB }, /*PLL control: PLL_ENABLE on = 8699*/
-		{0x0014, 0x20FB }, /*PLL control: SEL_LOCK_DET on = 8443*/
-};
-
-struct mt9d113_i2c_reg_conf const
-	register_wizard_settings[] = {
-		{0x098C, 0x2719},
-		{0x0990, 0x005A},
-		{0x098C, 0x271B},
-		{0x0990, 0x01BE},
-		{0x098C, 0x271D},
-		{0x0990, 0x0131},
-		{0x098C, 0x271F},
-		{0x0990, 0x02BB},
-		{0x098C, 0x2721},
-		{0x0990, 0x0888},
-		{0x098C, 0x272F},
-		{0x0990, 0x003A},
-		{0x098C, 0x2731},
-		{0x0990, 0x00F6},
-		{0x098C, 0x2733},
-		{0x0990, 0x008B},
-		{0x098C, 0x2735},
-		{0x0990, 0x0521},
-		{0x098C, 0x2737},
-		{0x0990, 0x0888},
-		{0x098C, 0x275F},
-		{0x0990, 0x0194},
-		{0x098C, 0x2761},
-		{0x0990, 0x0014},
-		{0x098C, 0xA765},
-		{0x0990, 0x0044},
-		{0x098C, 0xA24F},
-		{0x0990, 0x0028},
-		{0x098C, 0xA20E},
-		{0x0990, 0x00A0},
-		{0x098C, 0xA20C},
-		{0x0990, 0x000E},
-		{0x098C, 0x2222},
-		{0x0990, 0x00A0},
-		{0x098C, 0x2212},
-		{0x0990, 0x01EE},
-		{0x098C, 0xA408},
-		{0x0990, 0x0026},
-		{0x098C, 0xA409},
-		{0x0990, 0x0029},
-		{0x098C, 0xA40A},
-		{0x0990, 0x002E},
-		{0x098C, 0xA40B},
-		{0x0990, 0x0031},
-		{0x098C, 0x2411},
-		{0x0990, 0x00A0},
-		{0x098C, 0x2413},
-		{0x0990, 0x00C0},
-		{0x098C, 0x2415},
-		{0x0990, 0x00A0},
-		{0x098C, 0x2417},
-		{0x0990, 0x00C0},
-};
-
-struct mt9d113_i2c_reg_conf const
-	err_settings[] = {
-		{0x3084, 0x240C},
-		{0x3092, 0x0A4C},
-		{0x3094, 0x4C4C},
-		{0x3096, 0x4C54},
-};
-
-struct mt9d113_i2c_reg_conf const
-	patch_settings[] = {
-		{0x098C, 0x0415},    /* MCU_ADDRESS*/
-		{0x0990, 0xF601},
-		{0x0992, 0x42C1},
-		{0x0994, 0x0326},
-		{0x0996, 0x11F6},
-		{0x0998, 0x0143},
-		{0x099A, 0xC104},
-		{0x099C, 0x260A},
-		{0x099E, 0xCC04},
-		{0x098C, 0x0425},
-		{0x0990, 0x33BD},
-		{0x0992, 0xA362},
-		{0x0994, 0xBD04},
-		{0x0996, 0x3339},
-		{0x0998, 0xC6FF},
-		{0x099A, 0xF701},
-		{0x099C, 0x6439},
-		{0x099E, 0xFE01},
-		{0x098C, 0x0435},
-		{0x0990, 0x6918},
-		{0x0992, 0xCE03},
-		{0x0994, 0x25CC},
-		{0x0996, 0x0013},
-		{0x0998, 0xBDC2},
-		{0x099A, 0xB8CC},
-		{0x099C, 0x0489},
-		{0x099E, 0xFD03},
-		{0x098C, 0x0445},
-		{0x0990, 0x27CC},
-		{0x0992, 0x0325},
-		{0x0994, 0xFD01},
-		{0x0996, 0x69FE},
-		{0x0998, 0x02BD},
-		{0x099A, 0x18CE},
-		{0x099C, 0x0339},
-		{0x099E, 0xCC00},
-		{0x098C, 0x0455},
-		{0x0990, 0x11BD},
-		{0x0992, 0xC2B8},
-		{0x0994, 0xCC04},
-		{0x0996, 0xC8FD},
-		{0x0998, 0x0347},
-		{0x099A, 0xCC03},
-		{0x099C, 0x39FD},
-		{0x099E, 0x02BD},
-		{0x098C, 0x0465},
-		{0x0990, 0xDE00},
-		{0x0992, 0x18CE},
-		{0x0994, 0x00C2},
-		{0x0996, 0xCC00},
-		{0x0998, 0x37BD},
-		{0x099A, 0xC2B8},
-		{0x099C, 0xCC04},
-		{0x099E, 0xEFDD},
-		{0x098C, 0x0475},
-		{0x0990, 0xE6CC},
-		{0x0992, 0x00C2},
-		{0x0994, 0xDD00},
-		{0x0996, 0xC601},
-		{0x0998, 0xF701},
-		{0x099A, 0x64C6},
-		{0x099C, 0x03F7},
-		{0x099E, 0x0165},
-		{0x098C, 0x0485},
-		{0x0990, 0x7F01},
-		{0x0992, 0x6639},
-		{0x0994, 0x3C3C},
-		{0x0996, 0x3C34},
-		{0x0998, 0xCC32},
-		{0x099A, 0x3EBD},
-		{0x099C, 0xA558},
-		{0x099E, 0x30ED},
-		{0x098C, 0x0495},
-		{0x0990, 0x04BD},
-		{0x0992, 0xB2D7},
-		{0x0994, 0x30E7},
-		{0x0996, 0x06CC},
-		{0x0998, 0x323E},
-		{0x099A, 0xED00},
-		{0x099C, 0xEC04},
-		{0x099E, 0xBDA5},
-		{0x098C, 0x04A5},
-		{0x0990, 0x44CC},
-		{0x0992, 0x3244},
-		{0x0994, 0xBDA5},
-		{0x0996, 0x585F},
-		{0x0998, 0x30ED},
-		{0x099A, 0x02CC},
-		{0x099C, 0x3244},
-		{0x099E, 0xED00},
-		{0x098C, 0x04B5},
-		{0x0990, 0xF601},
-		{0x0992, 0xD54F},
-		{0x0994, 0xEA03},
-		{0x0996, 0xAA02},
-		{0x0998, 0xBDA5},
-		{0x099A, 0x4430},
-		{0x099C, 0xE606},
-		{0x099E, 0x3838},
-		{0x098C, 0x04C5},
-		{0x0990, 0x3831},
-		{0x0992, 0x39BD},
-		{0x0994, 0xD661},
-		{0x0996, 0xF602},
-		{0x0998, 0xF4C1},
-		{0x099A, 0x0126},
-		{0x099C, 0x0BFE},
-		{0x099E, 0x02BD},
-		{0x098C, 0x04D5},
-		{0x0990, 0xEE10},
-		{0x0992, 0xFC02},
-		{0x0994, 0xF5AD},
-		{0x0996, 0x0039},
-		{0x0998, 0xF602},
-		{0x099A, 0xF4C1},
-		{0x099C, 0x0226},
-		{0x099E, 0x0AFE},
-		{0x098C, 0x04E5},
-		{0x0990, 0x02BD},
-		{0x0992, 0xEE10},
-		{0x0994, 0xFC02},
-		{0x0996, 0xF7AD},
-		{0x0998, 0x0039},
-		{0x099A, 0x3CBD},
-		{0x099C, 0xB059},
-		{0x099E, 0xCC00},
-		{0x098C, 0x04F5},
-		{0x0990, 0x28BD},
-		{0x0992, 0xA558},
-		{0x0994, 0x8300},
-		{0x0996, 0x0027},
-		{0x0998, 0x0BCC},
-		{0x099A, 0x0026},
-		{0x099C, 0x30ED},
-		{0x099E, 0x00C6},
-		{0x098C, 0x0505},
-		{0x0990, 0x03BD},
-		{0x0992, 0xA544},
-		{0x0994, 0x3839},
-		{0x098C, 0x2006},
-		{0x0990, 0x0415},
-		{0x098C, 0xA005},
-		{0x0990, 0x0001},
-};
-
-struct mt9d113_i2c_reg_conf const
-	eeprom_settings[] = {
-		{0x3658, 0x0110},
-		{0x365A, 0x1B6D},
-		{0x365C, 0x01F2},
-		{0x365E, 0xFBCD},
-		{0x3660, 0x8C91},
-		{0x3680, 0xB9ED},
-		{0x3682, 0x0EE},
-		{0x3684, 0x256F},
-		{0x3686, 0x824F},
-		{0x3688, 0xD293},
-		{0x36A8, 0x5BF2},
-		{0x36AA, 0x1711},
-		{0x36AC, 0xA095},
-		{0x36AE, 0x642C},
-		{0x36B0, 0x0E38},
-		{0x36D0, 0x88B0},
-		{0x36D2, 0x2EB2},
-		{0x36D4, 0x4C74},
-		{0x36D6, 0x9F96},
-		{0x36D8, 0x9557},
-		{0x36F8, 0xCE51},
-		{0x36FA, 0xB354},
-		{0x36FC, 0x2817},
-		{0x36FE, 0x14B8},
-		{0x3700, 0xB019},
-		{0x364E, 0x0710},
-		{0x3650, 0x30ED},
-		{0x3652, 0x03F2},
-		{0x3654, 0xF12E},
-		{0x3656, 0x8492},
-		{0x3676, 0xD9AD},
-		{0x3678, 0x88D0},
-		{0x367A, 0x7DED},
-		{0x367C, 0x3E31},
-		{0x367E, 0x91B3},
-		{0x369E, 0x7032},
-		{0x36A0, 0x2791},
-		{0x36A2, 0xBB55},
-		{0x36A4, 0xAB32},
-		{0x36A6, 0x1A58},
-		{0x36C6, 0xB50F},
-		{0x36C8, 0x0011},
-		{0x36CA, 0x6DB4},
-		{0x36CC, 0x96F5},
-		{0x36CE, 0x9BB7},
-		{0x36EE, 0x9353},
-		{0x36F0, 0xDF74},
-		{0x36F2, 0x04F8},
-		{0x36F4, 0x0FD8},
-		{0x36F6, 0xA87A},
-		{0x3662, 0x0170},
-		{0x3664, 0x6F0C},
-		{0x3666, 0x0112},
-		{0x3668, 0xCBAB},
-		{0x366A, 0x9111},
-		{0x368A, 0xB38D},
-		{0x368C, 0xE96F},
-		{0x368E, 0xCC0F},
-		{0x3690, 0x5851},
-		{0x3692, 0xFDD2},
-		{0x36B2, 0x5F92},
-		{0x36B4, 0x33B2},
-		{0x36B6, 0x9815},
-		{0x36B8, 0x86F5},
-		{0x36BA, 0x0578},
-		{0x36DA, 0xCD90},
-		{0x36DC, 0x1131},
-		{0x36DE, 0x5275},
-		{0x36E0, 0xE855},
-		{0x36E2, 0xD037},
-		{0x3702, 0xAAD1},
-		{0x3704, 0xEB75},
-		{0x3706, 0x0CD7},
-		{0x3708, 0x2C79},
-		{0x370A, 0xE0B9},
-		{0x366C, 0x0190},
-		{0x366E, 0x1C8D},
-		{0x3670, 0x0052},
-		{0x3672, 0xD66E},
-		{0x3674, 0xF511},
-		{0x3694, 0xB54D},
-		{0x3696, 0x6E4E},
-		{0x3698, 0x142E},
-		{0x369A, 0xC190},
-		{0x369C, 0xA753},
-		{0x36BC, 0x70F2},
-		{0x36BE, 0x04F1},
-		{0x36C0, 0xBD95},
-		{0x36C2, 0x0CEE},
-		{0x36C4, 0x1BF8},
-		{0x36E4, 0x806F},
-		{0x36E6, 0x1672},
-		{0x36E8, 0x2DF4},
-		{0x36EA, 0x8F16},
-		{0x36EC, 0xF776},
-		{0x370C, 0xAD73},
-		{0x370E, 0xB534},
-		{0x3710, 0x0D18},
-		{0x3712, 0x6057},
-		{0x3714, 0xBD1A},
-		{0x3644, 0x0354},
-		{0x3642, 0x0234},
-		{0x3210, 0x01B8},
-};
-
-struct mt9d113_i2c_reg_conf const
-	awb_settings[] = {
-		{0x098C, 0x2306},
-		{0x0990, 0x0180},
-		{0x098C, 0x2308},
-		{0x0990, 0xFF00},
-		{0x098C, 0x230A},
-		{0x0990, 0x0080},
-		{0x098C, 0x230C},
-		{0x0990, 0xFF66},
-		{0x098C, 0x230E},
-		{0x0990, 0x0180},
-		{0x098C, 0x2310},
-		{0x0990, 0xFFEE},
-		{0x098C, 0x2312},
-		{0x0990, 0xFFCD},
-		{0x098C, 0x2314},
-		{0x0990, 0xFECD},
-		{0x098C, 0x2316},
-		{0x0990, 0x019A},
-		{0x098C, 0x2318},
-		{0x0990, 0x0020},
-		{0x098C, 0x231A},
-		{0x0990, 0x0033},
-		{0x098C, 0x231C},
-		{0x0990, 0x0100},
-		{0x098C, 0x231E},
-		{0x0990, 0xFF9A},
-		{0x098C, 0x2320},
-		{0x0990, 0x0000},
-		{0x098C, 0x2322},
-		{0x0990, 0x004D},
-		{0x098C, 0x2324},
-		{0x0990, 0xFFCD},
-		{0x098C, 0x2326},
-		{0x0990, 0xFFB8},
-		{0x098C, 0x2328},
-		{0x0990, 0x004D},
-		{0x098C, 0x232A},
-		{0x0990, 0x0080},
-		{0x098C, 0x232C},
-		{0x0990, 0xFF66},
-		{0x098C, 0x232E},
-		{0x0990, 0x0008},
-		{0x098C, 0x2330},
-		{0x0990, 0xFFF7},
-		{0x098C, 0xA363},
-		{0x0990, 0x00D2},
-		{0x098C, 0xA364},
-		{0x0990, 0x00EE},
-		{0x3244, 0x0328},
-		{0x323E, 0xC22C},
-};
-
-struct mt9d113_i2c_reg_conf const
-	low_light_setting[] = {
-		{0x098C, 0x2B28},
-		{0x0990, 0x35E8},
-		{0x098C, 0x2B2A},
-		{0x0990, 0xB3B0},
-		{0x098C, 0xAB20},
-		{0x0990, 0x004B},
-		{0x098C, 0xAB24},
-		{0x0990, 0x0000},
-		{0x098C, 0xAB25},
-		{0x0990, 0x00FF},
-		{0x098C, 0xAB30},
-		{0x0990, 0x00FF},
-		{0x098C, 0xAB31},
-		{0x0990, 0x00FF},
-		{0x098C, 0xAB32},
-		{0x0990, 0x00FF},
-		{0x098C, 0xAB33},
-		{0x0990, 0x0057},
-		{0x098C, 0xAB34},
-		{0x0990, 0x0080},
-		{0x098C, 0xAB35},
-		{0x0990, 0x00FF},
-		{0x098C, 0xAB36},
-		{0x0990, 0x0014},
-		{0x098C, 0xAB37},
-		{0x0990, 0x0003},
-		{0x098C, 0x2B38},
-		{0x0990, 0x32C8},
-		{0x098C, 0x2B3A},
-		{0x0990, 0x7918},
-		{0x098C, 0x2B62},
-		{0x0990, 0xFFFE},
-		{0x098C, 0x2B64},
-		{0x0990, 0xFFFF},
-};
-
-struct mt9d113_reg mt9d113_regs = {
-		.pll_tbl = pll_tbl_settings,
-		.pll_tbl_size = ARRAY_SIZE(
-			pll_tbl_settings),
-		.register_tbl = register_wizard_settings,
-		.register_tbl_size = ARRAY_SIZE(
-			register_wizard_settings),
-		.err_tbl = err_settings,
-		.err_tbl_size = ARRAY_SIZE(err_settings),
-		.low_light_tbl = low_light_setting,
-		.low_light_tbl_size = ARRAY_SIZE(low_light_setting),
-		.awb_tbl = awb_settings,
-		.awb_tbl_size = ARRAY_SIZE(awb_settings),
-		.patch_tbl = patch_settings,
-		.patch_tbl_size = ARRAY_SIZE(patch_settings),
-		.eeprom_tbl = eeprom_settings,
-		.eeprom_tbl_size = ARRAY_SIZE(eeprom_settings),
-};
-
-
-
diff --git a/drivers/media/video/msm/mt9e013.c b/drivers/media/video/msm/mt9e013.c
deleted file mode 100644
index 94546f4..0000000
--- a/drivers/media/video/msm/mt9e013.c
+++ /dev/null
@@ -1,1140 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. 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/delay.h>
-#include <linux/debugfs.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/slab.h>
-#include <media/msm_camera.h>
-#include <mach/gpio.h>
-#include <mach/camera.h>
-#include "mt9e013.h"
-/*=============================================================
-	SENSOR REGISTER DEFINES
-==============================================================*/
-#define REG_GROUPED_PARAMETER_HOLD		0x0104
-#define GROUPED_PARAMETER_HOLD_OFF		0x00
-#define GROUPED_PARAMETER_HOLD			0x01
-/* Integration Time */
-#define REG_COARSE_INTEGRATION_TIME		0x3012
-/* Gain */
-#define REG_GLOBAL_GAIN	0x305E
-/* PLL registers */
-#define REG_FRAME_LENGTH_LINES		0x0340
-/* Test Pattern */
-#define REG_TEST_PATTERN_MODE			0x0601
-#define REG_VCM_NEW_CODE			0x30F2
-
-/*============================================================================
-							 TYPE DECLARATIONS
-============================================================================*/
-
-/* 16bit address - 8 bit context register structure */
-#define Q8	0x00000100
-#define Q10	0x00000400
-#define MT9E013_MASTER_CLK_RATE 24000000
-
-/* AF Total steps parameters */
-#define MT9E013_TOTAL_STEPS_NEAR_TO_FAR    32
-
-uint16_t mt9e013_step_position_table[MT9E013_TOTAL_STEPS_NEAR_TO_FAR+1];
-uint16_t mt9e013_nl_region_boundary1;
-uint16_t mt9e013_nl_region_code_per_step1;
-uint16_t mt9e013_l_region_code_per_step = 4;
-uint16_t mt9e013_damping_threshold = 10;
-uint16_t mt9e013_sw_damping_time_wait = 1;
-
-struct mt9e013_work_t {
-	struct work_struct work;
-};
-
-static struct mt9e013_work_t *mt9e013_sensorw;
-static struct i2c_client *mt9e013_client;
-
-struct mt9e013_ctrl_t {
-	const struct  msm_camera_sensor_info *sensordata;
-
-	uint32_t sensormode;
-	uint32_t fps_divider;/* init to 1 * 0x00000400 */
-	uint32_t pict_fps_divider;/* init to 1 * 0x00000400 */
-	uint16_t fps;
-
-	uint16_t curr_lens_pos;
-	uint16_t curr_step_pos;
-	uint16_t my_reg_gain;
-	uint32_t my_reg_line_count;
-	uint16_t total_lines_per_frame;
-
-	enum mt9e013_resolution_t prev_res;
-	enum mt9e013_resolution_t pict_res;
-	enum mt9e013_resolution_t curr_res;
-	enum mt9e013_test_mode_t  set_test;
-};
-
-
-static bool CSI_CONFIG;
-static struct mt9e013_ctrl_t *mt9e013_ctrl;
-static DECLARE_WAIT_QUEUE_HEAD(mt9e013_wait_queue);
-DEFINE_MUTEX(mt9e013_mut);
-
-static int cam_debug_init(void);
-static struct dentry *debugfs_base;
-/*=============================================================*/
-
-static int mt9e013_i2c_rxdata(unsigned short saddr,
-	unsigned char *rxdata, int length)
-{
-	struct i2c_msg msgs[] = {
-		{
-			.addr  = saddr,
-			.flags = 0,
-			.len   = 2,
-			.buf   = rxdata,
-		},
-		{
-			.addr  = saddr,
-			.flags = I2C_M_RD,
-			.len   = 2,
-			.buf   = rxdata,
-		},
-	};
-	if (i2c_transfer(mt9e013_client->adapter, msgs, 2) < 0) {
-		CDBG("mt9e013_i2c_rxdata faild 0x%x\n", saddr);
-		return -EIO;
-	}
-	return 0;
-}
-
-static int32_t mt9e013_i2c_txdata(unsigned short saddr,
-				unsigned char *txdata, int length)
-{
-	struct i2c_msg msg[] = {
-		{
-			.addr = saddr,
-			.flags = 0,
-			.len = length,
-			.buf = txdata,
-		 },
-	};
-	if (i2c_transfer(mt9e013_client->adapter, msg, 1) < 0) {
-		CDBG("mt9e013_i2c_txdata faild 0x%x\n", saddr);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int32_t mt9e013_i2c_read(unsigned short raddr,
-	unsigned short *rdata, int rlen)
-{
-	int32_t rc = 0;
-	unsigned char buf[2];
-	if (!rdata)
-		return -EIO;
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (raddr & 0xFF00) >> 8;
-	buf[1] = (raddr & 0x00FF);
-	rc = mt9e013_i2c_rxdata(mt9e013_client->addr<<1, buf, rlen);
-	if (rc < 0) {
-		CDBG("mt9e013_i2c_read 0x%x failed!\n", raddr);
-		return rc;
-	}
-	*rdata = (rlen == 2 ? buf[0] << 8 | buf[1] : buf[0]);
-	CDBG("mt9e013_i2c_read 0x%x val = 0x%x!\n", raddr, *rdata);
-	return rc;
-}
-
-static int32_t mt9e013_i2c_write_w_sensor(unsigned short waddr, uint16_t wdata)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[4];
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (waddr & 0xFF00) >> 8;
-	buf[1] = (waddr & 0x00FF);
-	buf[2] = (wdata & 0xFF00) >> 8;
-	buf[3] = (wdata & 0x00FF);
-	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, wdata);
-	rc = mt9e013_i2c_txdata(mt9e013_client->addr<<1, buf, 4);
-	if (rc < 0) {
-		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
-			waddr, wdata);
-	}
-	return rc;
-}
-
-static int32_t mt9e013_i2c_write_b_sensor(unsigned short waddr, uint8_t bdata)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[3];
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (waddr & 0xFF00) >> 8;
-	buf[1] = (waddr & 0x00FF);
-	buf[2] = bdata;
-	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
-	rc = mt9e013_i2c_txdata(mt9e013_client->addr<<1, buf, 3);
-	if (rc < 0) {
-		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
-			waddr, bdata);
-	}
-	return rc;
-}
-
-static int32_t mt9e013_i2c_write_w_table(struct mt9e013_i2c_reg_conf const
-					 *reg_conf_tbl, int num)
-{
-	int i;
-	int32_t rc = -EIO;
-	for (i = 0; i < num; i++) {
-		rc = mt9e013_i2c_write_w_sensor(reg_conf_tbl->waddr,
-			reg_conf_tbl->wdata);
-		if (rc < 0)
-			break;
-		reg_conf_tbl++;
-	}
-	return rc;
-}
-
-static void mt9e013_group_hold_on(void)
-{
-	mt9e013_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
-						GROUPED_PARAMETER_HOLD);
-}
-
-static void mt9e013_group_hold_off(void)
-{
-	mt9e013_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
-						GROUPED_PARAMETER_HOLD_OFF);
-}
-
-static void mt9e013_start_stream(void)
-{
-	mt9e013_i2c_write_w_sensor(0x301A, 0x8250);
-	mt9e013_i2c_write_w_sensor(0x301A, 0x8650);
-	mt9e013_i2c_write_w_sensor(0x301A, 0x8658);
-	mt9e013_i2c_write_b_sensor(0x0104, 0x00);
-	mt9e013_i2c_write_w_sensor(0x301A, 0x065C);
-}
-
-static void mt9e013_stop_stream(void)
-{
-	mt9e013_i2c_write_w_sensor(0x301A, 0x0058);
-	mt9e013_i2c_write_w_sensor(0x301A, 0x0050);
-	mt9e013_i2c_write_b_sensor(0x0104, 0x01);
-}
-
-static void mt9e013_get_pict_fps(uint16_t fps, uint16_t *pfps)
-{
-	/* input fps is preview fps in Q8 format */
-	uint32_t divider, d1, d2;
-
-	d1 = mt9e013_regs.reg_prev[E013_FRAME_LENGTH_LINES].wdata
-		* 0x00000400/
-		mt9e013_regs.reg_snap[E013_FRAME_LENGTH_LINES].wdata;
-	d2 = mt9e013_regs.reg_prev[E013_LINE_LENGTH_PCK].wdata
-		* 0x00000400/
-		mt9e013_regs.reg_snap[E013_LINE_LENGTH_PCK].wdata;
-	divider = d1 * d2 / 0x400;
-
-	/*Verify PCLK settings and frame sizes.*/
-	*pfps = (uint16_t) (fps * divider / 0x400);
-	/* 2 is the ratio of no.of snapshot channels
-	to number of preview channels */
-}
-
-static uint16_t mt9e013_get_prev_lines_pf(void)
-{
-	if (mt9e013_ctrl->prev_res == QTR_SIZE)
-		return mt9e013_regs.reg_prev[E013_FRAME_LENGTH_LINES].wdata;
-	else if (mt9e013_ctrl->prev_res == FULL_SIZE)
-		return mt9e013_regs.reg_snap[E013_FRAME_LENGTH_LINES].wdata;
-	else if (mt9e013_ctrl->prev_res == HFR_60FPS)
-		return mt9e013_regs.reg_60fps[E013_FRAME_LENGTH_LINES].wdata;
-	else if (mt9e013_ctrl->prev_res == HFR_90FPS)
-		return mt9e013_regs.reg_120fps[E013_FRAME_LENGTH_LINES].wdata;
-	else
-		return mt9e013_regs.reg_120fps[E013_FRAME_LENGTH_LINES].wdata;
-}
-
-static uint16_t mt9e013_get_prev_pixels_pl(void)
-{
-	if (mt9e013_ctrl->prev_res == QTR_SIZE)
-		return mt9e013_regs.reg_prev[E013_LINE_LENGTH_PCK].wdata;
-	else if (mt9e013_ctrl->prev_res == FULL_SIZE)
-		return mt9e013_regs.reg_snap[E013_LINE_LENGTH_PCK].wdata;
-	else if (mt9e013_ctrl->prev_res == HFR_60FPS)
-		return mt9e013_regs.reg_60fps[E013_LINE_LENGTH_PCK].wdata;
-	else if (mt9e013_ctrl->prev_res == HFR_90FPS)
-		return mt9e013_regs.reg_120fps[E013_LINE_LENGTH_PCK].wdata;
-	else
-		return mt9e013_regs.reg_120fps[E013_LINE_LENGTH_PCK].wdata;
-}
-
-static uint16_t mt9e013_get_pict_lines_pf(void)
-{
-	if (mt9e013_ctrl->pict_res == QTR_SIZE)
-		return mt9e013_regs.reg_prev[E013_FRAME_LENGTH_LINES].wdata;
-	else if (mt9e013_ctrl->pict_res == FULL_SIZE)
-		return mt9e013_regs.reg_snap[E013_FRAME_LENGTH_LINES].wdata;
-	else if (mt9e013_ctrl->pict_res == HFR_60FPS)
-		return mt9e013_regs.reg_60fps[E013_FRAME_LENGTH_LINES].wdata;
-	else if (mt9e013_ctrl->pict_res == HFR_90FPS)
-		return mt9e013_regs.reg_120fps[E013_FRAME_LENGTH_LINES].wdata;
-	else
-		return mt9e013_regs.reg_120fps[E013_FRAME_LENGTH_LINES].wdata;
-}
-
-static uint16_t mt9e013_get_pict_pixels_pl(void)
-{
-	if (mt9e013_ctrl->pict_res == QTR_SIZE)
-		return mt9e013_regs.reg_prev[E013_LINE_LENGTH_PCK].wdata;
-	else if (mt9e013_ctrl->pict_res == FULL_SIZE)
-		return mt9e013_regs.reg_snap[E013_LINE_LENGTH_PCK].wdata;
-	else if (mt9e013_ctrl->pict_res == HFR_60FPS)
-		return mt9e013_regs.reg_60fps[E013_LINE_LENGTH_PCK].wdata;
-	else if (mt9e013_ctrl->pict_res == HFR_90FPS)
-		return mt9e013_regs.reg_120fps[E013_LINE_LENGTH_PCK].wdata;
-	else
-		return mt9e013_regs.reg_120fps[E013_LINE_LENGTH_PCK].wdata;
-}
-
-static uint32_t mt9e013_get_pict_max_exp_lc(void)
-{
-	if (mt9e013_ctrl->pict_res == QTR_SIZE)
-		return mt9e013_regs.reg_prev[E013_FRAME_LENGTH_LINES].wdata
-			* 24;
-	else if (mt9e013_ctrl->pict_res == FULL_SIZE)
-		return mt9e013_regs.reg_snap[E013_FRAME_LENGTH_LINES].wdata
-			* 24;
-	else if (mt9e013_ctrl->pict_res == HFR_60FPS)
-		return mt9e013_regs.reg_60fps[E013_FRAME_LENGTH_LINES].wdata
-			* 24;
-	else if (mt9e013_ctrl->pict_res == HFR_90FPS)
-		return mt9e013_regs.reg_120fps[E013_FRAME_LENGTH_LINES].wdata
-			* 24;
-	else
-		return mt9e013_regs.reg_120fps[E013_FRAME_LENGTH_LINES].wdata
-			* 24;
-}
-
-static int32_t mt9e013_set_fps(struct fps_cfg   *fps)
-{
-	uint16_t total_lines_per_frame;
-	int32_t rc = 0;
-	if (mt9e013_ctrl->curr_res == QTR_SIZE)
-		total_lines_per_frame =
-		mt9e013_regs.reg_prev[E013_FRAME_LENGTH_LINES].wdata;
-	else if (mt9e013_ctrl->curr_res == FULL_SIZE)
-		total_lines_per_frame =
-		mt9e013_regs.reg_snap[E013_FRAME_LENGTH_LINES].wdata;
-	else if (mt9e013_ctrl->curr_res == HFR_60FPS)
-		total_lines_per_frame =
-		mt9e013_regs.reg_60fps[E013_FRAME_LENGTH_LINES].wdata;
-	else if (mt9e013_ctrl->curr_res == HFR_90FPS)
-		total_lines_per_frame =
-		mt9e013_regs.reg_120fps[E013_FRAME_LENGTH_LINES].wdata;
-	else
-		total_lines_per_frame =
-		mt9e013_regs.reg_120fps[E013_FRAME_LENGTH_LINES].wdata;
-
-	mt9e013_ctrl->fps_divider = fps->fps_div;
-	mt9e013_ctrl->pict_fps_divider = fps->pict_fps_div;
-
-	if (mt9e013_ctrl->curr_res == FULL_SIZE) {
-		total_lines_per_frame = (uint16_t)
-		(total_lines_per_frame * mt9e013_ctrl->pict_fps_divider/0x400);
-	} else {
-		total_lines_per_frame = (uint16_t)
-		(total_lines_per_frame * mt9e013_ctrl->fps_divider/0x400);
-	}
-
-	mt9e013_group_hold_on();
-	rc = mt9e013_i2c_write_w_sensor(REG_FRAME_LENGTH_LINES,
-							total_lines_per_frame);
-	mt9e013_group_hold_off();
-	return rc;
-}
-
-static int32_t mt9e013_write_exp_gain(uint16_t gain, uint32_t line)
-{
-	uint16_t max_legal_gain = 0xE7F;
-	int32_t rc = 0;
-	if (gain > max_legal_gain) {
-		CDBG("Max legal gain Line:%d\n", __LINE__);
-		gain = max_legal_gain;
-	}
-
-	if (mt9e013_ctrl->curr_res != FULL_SIZE) {
-		mt9e013_ctrl->my_reg_gain = gain;
-		mt9e013_ctrl->my_reg_line_count = (uint16_t) line;
-		line = (uint32_t) (line * mt9e013_ctrl->fps_divider /
-						   0x00000400);
-	} else {
-		line = (uint32_t) (line * mt9e013_ctrl->pict_fps_divider /
-						   0x00000400);
-	}
-
-	gain |= 0x1000;
-
-	mt9e013_group_hold_on();
-	rc = mt9e013_i2c_write_w_sensor(REG_GLOBAL_GAIN, gain);
-	rc = mt9e013_i2c_write_w_sensor(REG_COARSE_INTEGRATION_TIME, line);
-	mt9e013_group_hold_off();
-	return rc;
-}
-
-static int32_t mt9e013_set_pict_exp_gain(uint16_t gain, uint32_t line)
-{
-	int32_t rc = 0;
-	rc = mt9e013_write_exp_gain(gain, line);
-	mt9e013_i2c_write_w_sensor(0x301A, 0x065C|0x2);
-	return rc;
-}
-
-#define DIV_CEIL(x, y) (x/y + (x%y) ? 1 : 0)
-
-static int32_t mt9e013_move_focus(int direction,
-	int32_t num_steps)
-{
-	int16_t step_direction, dest_lens_position, dest_step_position;
-	int16_t target_dist, small_step, next_lens_position;
-	if (direction == MOVE_NEAR)
-		step_direction = 1;
-	else
-		step_direction = -1;
-
-	dest_step_position = mt9e013_ctrl->curr_step_pos
-						+ (step_direction * num_steps);
-
-	if (dest_step_position < 0)
-		dest_step_position = 0;
-	else if (dest_step_position > MT9E013_TOTAL_STEPS_NEAR_TO_FAR)
-		dest_step_position = MT9E013_TOTAL_STEPS_NEAR_TO_FAR;
-
-	if (dest_step_position == mt9e013_ctrl->curr_step_pos)
-		return 0;
-
-	dest_lens_position = mt9e013_step_position_table[dest_step_position];
-	target_dist = step_direction *
-		(dest_lens_position - mt9e013_ctrl->curr_lens_pos);
-
-	if (step_direction < 0 && (target_dist >=
-		mt9e013_step_position_table[mt9e013_damping_threshold])) {
-		small_step = DIV_CEIL(target_dist, 10);
-		mt9e013_sw_damping_time_wait = 10;
-	} else {
-		small_step = DIV_CEIL(target_dist, 4);
-		mt9e013_sw_damping_time_wait = 4;
-	}
-
-	for (next_lens_position = mt9e013_ctrl->curr_lens_pos
-		+ (step_direction * small_step);
-		(step_direction * next_lens_position) <=
-		(step_direction * dest_lens_position);
-		next_lens_position += (step_direction * small_step)) {
-		mt9e013_i2c_write_w_sensor(REG_VCM_NEW_CODE,
-		next_lens_position);
-		mt9e013_ctrl->curr_lens_pos = next_lens_position;
-		usleep(mt9e013_sw_damping_time_wait*50);
-	}
-
-	if (mt9e013_ctrl->curr_lens_pos != dest_lens_position) {
-		mt9e013_i2c_write_w_sensor(REG_VCM_NEW_CODE,
-		dest_lens_position);
-		usleep(mt9e013_sw_damping_time_wait*50);
-	}
-	mt9e013_ctrl->curr_lens_pos = dest_lens_position;
-	mt9e013_ctrl->curr_step_pos = dest_step_position;
-	return 0;
-}
-
-static int32_t mt9e013_set_default_focus(uint8_t af_step)
-{
-	int32_t rc = 0;
-	if (mt9e013_ctrl->curr_step_pos != 0) {
-		rc = mt9e013_move_focus(MOVE_FAR,
-		mt9e013_ctrl->curr_step_pos);
-	} else {
-		mt9e013_i2c_write_w_sensor(REG_VCM_NEW_CODE, 0x00);
-	}
-
-	mt9e013_ctrl->curr_lens_pos = 0;
-	mt9e013_ctrl->curr_step_pos = 0;
-
-	return rc;
-}
-
-static void mt9e013_init_focus(void)
-{
-	uint8_t i;
-	mt9e013_step_position_table[0] = 0;
-	for (i = 1; i <= MT9E013_TOTAL_STEPS_NEAR_TO_FAR; i++) {
-		if (i <= mt9e013_nl_region_boundary1) {
-			mt9e013_step_position_table[i] =
-				mt9e013_step_position_table[i-1]
-				+ mt9e013_nl_region_code_per_step1;
-		} else {
-			mt9e013_step_position_table[i] =
-				mt9e013_step_position_table[i-1]
-				+ mt9e013_l_region_code_per_step;
-		}
-
-		if (mt9e013_step_position_table[i] > 255)
-			mt9e013_step_position_table[i] = 255;
-	}
-}
-
-static int32_t mt9e013_test(enum mt9e013_test_mode_t mo)
-{
-	int32_t rc = 0;
-	if (mo == TEST_OFF)
-		return rc;
-	else {
-		/* REG_0x30D8[4] is TESBYPEN: 0: Normal Operation,
-		1: Bypass Signal Processing
-		REG_0x30D8[5] is EBDMASK: 0:
-		Output Embedded data, 1: No output embedded data */
-		if (mt9e013_i2c_write_b_sensor(REG_TEST_PATTERN_MODE,
-			(uint8_t) mo) < 0) {
-			return rc;
-		}
-	}
-	return rc;
-}
-
-static int32_t mt9e013_sensor_setting(int update_type, int rt)
-{
-
-	int32_t rc = 0;
-	struct msm_camera_csi_params mt9e013_csi_params;
-	uint8_t stored_af_step = 0;
-	CDBG("sensor_settings\n");
-	stored_af_step = mt9e013_ctrl->curr_step_pos;
-	mt9e013_set_default_focus(0);
-	mt9e013_stop_stream();
-	msleep(15);
-	if (update_type == REG_INIT) {
-		mt9e013_i2c_write_w_table(mt9e013_regs.reg_mipi,
-			mt9e013_regs.reg_mipi_size);
-		mt9e013_i2c_write_w_table(mt9e013_regs.rec_settings,
-			mt9e013_regs.rec_size);
-		cam_debug_init();
-		CSI_CONFIG = 0;
-	} else if (update_type == UPDATE_PERIODIC) {
-		if (rt == QTR_SIZE) {
-			mt9e013_i2c_write_w_table(mt9e013_regs.reg_pll,
-				mt9e013_regs.reg_pll_size);
-			mt9e013_i2c_write_w_table(mt9e013_regs.reg_prev,
-				mt9e013_regs.reg_prev_size);
-		} else if (rt == FULL_SIZE) {
-			mt9e013_i2c_write_w_table(mt9e013_regs.reg_pll,
-				mt9e013_regs.reg_pll_size);
-			mt9e013_i2c_write_w_table(mt9e013_regs.reg_snap,
-				mt9e013_regs.reg_snap_size);
-		} else if (rt == HFR_60FPS) {
-			mt9e013_i2c_write_w_table(mt9e013_regs.reg_pll_120fps,
-				mt9e013_regs.reg_pll_120fps_size);
-			mt9e013_i2c_write_w_sensor(0x0306, 0x0029);
-			mt9e013_i2c_write_w_table(mt9e013_regs.reg_120fps,
-				mt9e013_regs.reg_120fps_size);
-		} else if (rt == HFR_90FPS) {
-			mt9e013_i2c_write_w_table(mt9e013_regs.reg_pll_120fps,
-				mt9e013_regs.reg_pll_120fps_size);
-			mt9e013_i2c_write_w_sensor(0x0306, 0x003D);
-			mt9e013_i2c_write_w_table(mt9e013_regs.reg_120fps,
-				mt9e013_regs.reg_120fps_size);
-		} else if (rt == HFR_120FPS) {
-			msm_camio_vfe_clk_rate_set(266667000);
-			mt9e013_i2c_write_w_table(mt9e013_regs.reg_pll_120fps,
-				mt9e013_regs.reg_pll_120fps_size);
-			mt9e013_i2c_write_w_table(mt9e013_regs.reg_120fps,
-				mt9e013_regs.reg_120fps_size);
-		}
-		if (!CSI_CONFIG) {
-			msm_camio_vfe_clk_rate_set(192000000);
-			mt9e013_csi_params.data_format = CSI_10BIT;
-			mt9e013_csi_params.lane_cnt = 2;
-			mt9e013_csi_params.lane_assign = 0xe4;
-			mt9e013_csi_params.dpcm_scheme = 0;
-			mt9e013_csi_params.settle_cnt = 0x18;
-			rc = msm_camio_csi_config(&mt9e013_csi_params);
-			msleep(10);
-			CSI_CONFIG = 1;
-		}
-		mt9e013_move_focus(MOVE_NEAR, stored_af_step);
-		mt9e013_start_stream();
-	}
-	return rc;
-}
-
-static int32_t mt9e013_video_config(int mode)
-{
-
-	int32_t rc = 0;
-
-	CDBG("video config\n");
-	/* change sensor resolution if needed */
-	if (mt9e013_sensor_setting(UPDATE_PERIODIC,
-			mt9e013_ctrl->prev_res) < 0)
-		return rc;
-	if (mt9e013_ctrl->set_test) {
-		if (mt9e013_test(mt9e013_ctrl->set_test) < 0)
-			return  rc;
-	}
-
-	mt9e013_ctrl->curr_res = mt9e013_ctrl->prev_res;
-	mt9e013_ctrl->sensormode = mode;
-	return rc;
-}
-
-static int32_t mt9e013_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-	/*change sensor resolution if needed */
-	if (mt9e013_ctrl->curr_res != mt9e013_ctrl->pict_res) {
-		if (mt9e013_sensor_setting(UPDATE_PERIODIC,
-				mt9e013_ctrl->pict_res) < 0)
-			return rc;
-	}
-
-	mt9e013_ctrl->curr_res = mt9e013_ctrl->pict_res;
-	mt9e013_ctrl->sensormode = mode;
-	return rc;
-} /*end of mt9e013_snapshot_config*/
-
-static int32_t mt9e013_raw_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-	/* change sensor resolution if needed */
-	if (mt9e013_ctrl->curr_res != mt9e013_ctrl->pict_res) {
-		if (mt9e013_sensor_setting(UPDATE_PERIODIC,
-				mt9e013_ctrl->pict_res) < 0)
-			return rc;
-	}
-
-	mt9e013_ctrl->curr_res = mt9e013_ctrl->pict_res;
-	mt9e013_ctrl->sensormode = mode;
-	return rc;
-} /*end of mt9e013_raw_snapshot_config*/
-
-static int32_t mt9e013_set_sensor_mode(int mode,
-	int res)
-{
-	int32_t rc = 0;
-	switch (mode) {
-	case SENSOR_PREVIEW_MODE:
-	case SENSOR_HFR_60FPS_MODE:
-	case SENSOR_HFR_90FPS_MODE:
-	case SENSOR_HFR_120FPS_MODE:
-		mt9e013_ctrl->prev_res = res;
-		rc = mt9e013_video_config(mode);
-		break;
-	case SENSOR_SNAPSHOT_MODE:
-		mt9e013_ctrl->pict_res = res;
-		rc = mt9e013_snapshot_config(mode);
-		break;
-	case SENSOR_RAW_SNAPSHOT_MODE:
-		mt9e013_ctrl->pict_res = res;
-		rc = mt9e013_raw_snapshot_config(mode);
-		break;
-	default:
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
-
-static int32_t mt9e013_power_down(void)
-{
-	return 0;
-}
-
-static int mt9e013_probe_init_done(const struct msm_camera_sensor_info *data)
-{
-	CDBG("probe done\n");
-	gpio_free(data->sensor_reset);
-	return 0;
-}
-
-static int mt9e013_probe_init_sensor(const struct msm_camera_sensor_info *data)
-{
-	int32_t rc = 0;
-	uint16_t chipid = 0;
-	CDBG("%s: %d\n", __func__, __LINE__);
-	rc = gpio_request(data->sensor_reset, "mt9e013");
-	CDBG(" mt9e013_probe_init_sensor\n");
-	if (!rc) {
-		CDBG("sensor_reset = %d\n", rc);
-		gpio_direction_output(data->sensor_reset, 0);
-		msleep(10);
-		gpio_set_value_cansleep(data->sensor_reset, 1);
-		msleep(10);
-	} else {
-		goto init_probe_done;
-	}
-
-	CDBG(" mt9e013_probe_init_sensor is called\n");
-	rc = mt9e013_i2c_read(0x0000, &chipid, 2);
-	CDBG("ID: %d\n", chipid);
-	/* 4. Compare sensor ID to MT9E013 ID: */
-	if (chipid != 0x4B00) {
-		rc = -ENODEV;
-		CDBG("mt9e013_probe_init_sensor fail chip id doesnot match\n");
-		goto init_probe_fail;
-	}
-
-	mt9e013_ctrl = kzalloc(sizeof(struct mt9e013_ctrl_t), GFP_KERNEL);
-	if (!mt9e013_ctrl) {
-		CDBG("mt9e013_init failed!\n");
-		rc = -ENOMEM;
-	}
-	mt9e013_ctrl->fps_divider = 1 * 0x00000400;
-	mt9e013_ctrl->pict_fps_divider = 1 * 0x00000400;
-	mt9e013_ctrl->set_test = TEST_OFF;
-	mt9e013_ctrl->prev_res = QTR_SIZE;
-	mt9e013_ctrl->pict_res = FULL_SIZE;
-
-	if (data)
-		mt9e013_ctrl->sensordata = data;
-
-	goto init_probe_done;
-init_probe_fail:
-	CDBG(" mt9e013_probe_init_sensor fails\n");
-	gpio_set_value_cansleep(data->sensor_reset, 0);
-	mt9e013_probe_init_done(data);
-init_probe_done:
-	CDBG(" mt9e013_probe_init_sensor finishes\n");
-	return rc;
-}
-/* camsensor_mt9e013_reset */
-
-int mt9e013_sensor_open_init(const struct msm_camera_sensor_info *data)
-{
-	int32_t rc = 0;
-
-	CDBG("%s: %d\n", __func__, __LINE__);
-	CDBG("Calling mt9e013_sensor_open_init\n");
-
-	mt9e013_ctrl = kzalloc(sizeof(struct mt9e013_ctrl_t), GFP_KERNEL);
-	if (!mt9e013_ctrl) {
-		CDBG("mt9e013_init failed!\n");
-		rc = -ENOMEM;
-		goto init_done;
-	}
-	mt9e013_ctrl->fps_divider = 1 * 0x00000400;
-	mt9e013_ctrl->pict_fps_divider = 1 * 0x00000400;
-	mt9e013_ctrl->set_test = TEST_OFF;
-	mt9e013_ctrl->prev_res = QTR_SIZE;
-	mt9e013_ctrl->pict_res = FULL_SIZE;
-
-	if (data)
-		mt9e013_ctrl->sensordata = data;
-	if (rc < 0) {
-		CDBG("Calling mt9e013_sensor_open_init fail1\n");
-		return rc;
-	}
-	CDBG("%s: %d\n", __func__, __LINE__);
-	/* enable mclk first */
-	msm_camio_clk_rate_set(MT9E013_MASTER_CLK_RATE);
-	rc = mt9e013_probe_init_sensor(data);
-	if (rc < 0)
-		goto init_fail;
-
-	CDBG("init settings\n");
-	rc = mt9e013_sensor_setting(REG_INIT, mt9e013_ctrl->prev_res);
-	mt9e013_ctrl->fps = 30*Q8;
-	mt9e013_init_focus();
-	if (rc < 0) {
-		gpio_set_value_cansleep(data->sensor_reset, 0);
-		goto init_fail;
-	} else
-		goto init_done;
-init_fail:
-	CDBG("init_fail\n");
-	mt9e013_probe_init_done(data);
-init_done:
-	CDBG("init_done\n");
-	return rc;
-} /*endof mt9e013_sensor_open_init*/
-
-static int mt9e013_init_client(struct i2c_client *client)
-{
-	/* Initialize the MSM_CAMI2C Chip */
-	init_waitqueue_head(&mt9e013_wait_queue);
-	return 0;
-}
-
-static const struct i2c_device_id mt9e013_i2c_id[] = {
-	{"mt9e013", 0},
-	{ }
-};
-
-static int mt9e013_i2c_probe(struct i2c_client *client,
-	const struct i2c_device_id *id)
-{
-	int rc = 0;
-	CDBG("mt9e013_probe called!\n");
-
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		CDBG("i2c_check_functionality failed\n");
-		goto probe_failure;
-	}
-
-	mt9e013_sensorw = kzalloc(sizeof(struct mt9e013_work_t), GFP_KERNEL);
-	if (!mt9e013_sensorw) {
-		CDBG("kzalloc failed.\n");
-		rc = -ENOMEM;
-		goto probe_failure;
-	}
-
-	i2c_set_clientdata(client, mt9e013_sensorw);
-	mt9e013_init_client(client);
-	mt9e013_client = client;
-
-
-	CDBG("mt9e013_probe successed! rc = %d\n", rc);
-	return 0;
-
-probe_failure:
-	CDBG("mt9e013_probe failed! rc = %d\n", rc);
-	return rc;
-}
-
-static int mt9e013_send_wb_info(struct wb_info_cfg *wb)
-{
-	return 0;
-
-} /*end of mt9e013_snapshot_config*/
-
-static int __exit mt9e013_remove(struct i2c_client *client)
-{
-	struct mt9e013_work_t_t *sensorw = i2c_get_clientdata(client);
-	free_irq(client->irq, sensorw);
-	mt9e013_client = NULL;
-	kfree(sensorw);
-	return 0;
-}
-
-static struct i2c_driver mt9e013_i2c_driver = {
-	.id_table = mt9e013_i2c_id,
-	.probe  = mt9e013_i2c_probe,
-	.remove = __exit_p(mt9e013_i2c_remove),
-	.driver = {
-		.name = "mt9e013",
-	},
-};
-
-int mt9e013_sensor_config(void __user *argp)
-{
-	struct sensor_cfg_data cdata;
-	long   rc = 0;
-	if (copy_from_user(&cdata,
-		(void *)argp,
-		sizeof(struct sensor_cfg_data)))
-		return -EFAULT;
-	mutex_lock(&mt9e013_mut);
-	CDBG("mt9e013_sensor_config: cfgtype = %d\n",
-	cdata.cfgtype);
-		switch (cdata.cfgtype) {
-		case CFG_GET_PICT_FPS:
-			mt9e013_get_pict_fps(
-				cdata.cfg.gfps.prevfps,
-				&(cdata.cfg.gfps.pictfps));
-
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_GET_PREV_L_PF:
-			cdata.cfg.prevl_pf =
-			mt9e013_get_prev_lines_pf();
-
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_GET_PREV_P_PL:
-			cdata.cfg.prevp_pl =
-				mt9e013_get_prev_pixels_pl();
-
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_GET_PICT_L_PF:
-			cdata.cfg.pictl_pf =
-				mt9e013_get_pict_lines_pf();
-
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_GET_PICT_P_PL:
-			cdata.cfg.pictp_pl =
-				mt9e013_get_pict_pixels_pl();
-
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_GET_PICT_MAX_EXP_LC:
-			cdata.cfg.pict_max_exp_lc =
-				mt9e013_get_pict_max_exp_lc();
-
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_SET_FPS:
-		case CFG_SET_PICT_FPS:
-			rc = mt9e013_set_fps(&(cdata.cfg.fps));
-			break;
-
-		case CFG_SET_EXP_GAIN:
-			rc =
-				mt9e013_write_exp_gain(
-					cdata.cfg.exp_gain.gain,
-					cdata.cfg.exp_gain.line);
-			break;
-
-		case CFG_SET_PICT_EXP_GAIN:
-			rc =
-				mt9e013_set_pict_exp_gain(
-				cdata.cfg.exp_gain.gain,
-				cdata.cfg.exp_gain.line);
-			break;
-
-		case CFG_SET_MODE:
-			rc = mt9e013_set_sensor_mode(cdata.mode,
-					cdata.rs);
-			break;
-
-		case CFG_PWR_DOWN:
-			rc = mt9e013_power_down();
-			break;
-
-		case CFG_MOVE_FOCUS:
-			rc =
-				mt9e013_move_focus(
-				cdata.cfg.focus.dir,
-				cdata.cfg.focus.steps);
-			break;
-
-		case CFG_SET_DEFAULT_FOCUS:
-			rc =
-				mt9e013_set_default_focus(
-				cdata.cfg.focus.steps);
-			break;
-
-		case CFG_GET_AF_MAX_STEPS:
-			cdata.max_steps = MT9E013_TOTAL_STEPS_NEAR_TO_FAR;
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_SET_EFFECT:
-			rc = mt9e013_set_default_focus(
-				cdata.cfg.effect);
-			break;
-
-
-		case CFG_SEND_WB_INFO:
-			rc = mt9e013_send_wb_info(
-				&(cdata.cfg.wb_info));
-			break;
-
-		default:
-			rc = -EFAULT;
-			break;
-		}
-
-	mutex_unlock(&mt9e013_mut);
-
-	return rc;
-}
-
-static int mt9e013_sensor_release(void)
-{
-	int rc = -EBADF;
-	mutex_lock(&mt9e013_mut);
-	mt9e013_power_down();
-	gpio_set_value_cansleep(mt9e013_ctrl->sensordata->sensor_reset, 0);
-	msleep(5);
-	gpio_free(mt9e013_ctrl->sensordata->sensor_reset);
-	kfree(mt9e013_ctrl);
-	mt9e013_ctrl = NULL;
-	CDBG("mt9e013_release completed\n");
-	mutex_unlock(&mt9e013_mut);
-
-	return rc;
-}
-
-static int mt9e013_sensor_probe(const struct msm_camera_sensor_info *info,
-		struct msm_sensor_ctrl *s)
-{
-	int rc = 0;
-	rc = i2c_add_driver(&mt9e013_i2c_driver);
-	if (rc < 0 || mt9e013_client == NULL) {
-		rc = -ENOTSUPP;
-		CDBG("I2C add driver failed");
-		goto probe_fail;
-	}
-	msm_camio_clk_rate_set(MT9E013_MASTER_CLK_RATE);
-	rc = mt9e013_probe_init_sensor(info);
-	if (rc < 0)
-		goto probe_fail;
-	s->s_init = mt9e013_sensor_open_init;
-	s->s_release = mt9e013_sensor_release;
-	s->s_config  = mt9e013_sensor_config;
-	s->s_mount_angle = info->sensor_platform_info->mount_angle;
-	gpio_set_value_cansleep(info->sensor_reset, 0);
-	mt9e013_probe_init_done(info);
-	return rc;
-
-probe_fail:
-	CDBG("mt9e013_sensor_probe: SENSOR PROBE FAILS!\n");
-	return rc;
-}
-
-static int __mt9e013_probe(struct platform_device *pdev)
-{
-	return msm_camera_drv_start(pdev, mt9e013_sensor_probe);
-}
-
-static struct platform_driver msm_camera_driver = {
-	.probe = __mt9e013_probe,
-	.driver = {
-		.name = "msm_camera_mt9e013",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init mt9e013_init(void)
-{
-	return platform_driver_register(&msm_camera_driver);
-}
-
-module_init(mt9e013_init);
-void mt9e013_exit(void)
-{
-	i2c_del_driver(&mt9e013_i2c_driver);
-}
-MODULE_DESCRIPTION("Aptina 8 MP Bayer sensor driver");
-MODULE_LICENSE("GPL v2");
-
-static bool streaming = 1;
-
-static int mt9e013_focus_test(void *data, u64 *val)
-{
-	int i = 0;
-	mt9e013_set_default_focus(0);
-
-	for (i = 90; i < 256; i++) {
-		mt9e013_i2c_write_w_sensor(REG_VCM_NEW_CODE, i);
-		msleep(5000);
-	}
-	msleep(5000);
-	for (i = 255; i > 90; i--) {
-		mt9e013_i2c_write_w_sensor(REG_VCM_NEW_CODE, i);
-		msleep(5000);
-	}
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(cam_focus, mt9e013_focus_test,
-			NULL, "%lld\n");
-
-static int mt9e013_step_test(void *data, u64 *val)
-{
-	int i = 0;
-	mt9e013_set_default_focus(0);
-
-	for (i = 0; i < MT9E013_TOTAL_STEPS_NEAR_TO_FAR; i++) {
-		mt9e013_move_focus(MOVE_NEAR, 1);
-		msleep(5000);
-	}
-
-	mt9e013_move_focus(MOVE_FAR, MT9E013_TOTAL_STEPS_NEAR_TO_FAR);
-	msleep(5000);
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(cam_step, mt9e013_step_test,
-			NULL, "%lld\n");
-
-static int cam_debug_stream_set(void *data, u64 val)
-{
-	int rc = 0;
-
-	if (val) {
-		mt9e013_start_stream();
-		streaming = 1;
-	} else {
-		mt9e013_stop_stream();
-		streaming = 0;
-	}
-
-	return rc;
-}
-
-static int cam_debug_stream_get(void *data, u64 *val)
-{
-	*val = streaming;
-	return 0;
-}
-DEFINE_SIMPLE_ATTRIBUTE(cam_stream, cam_debug_stream_get,
-			cam_debug_stream_set, "%llu\n");
-
-
-static int cam_debug_init(void)
-{
-	struct dentry *cam_dir;
-	debugfs_base = debugfs_create_dir("sensor", NULL);
-	if (!debugfs_base)
-		return -ENOMEM;
-
-	cam_dir = debugfs_create_dir("mt9e013", debugfs_base);
-	if (!cam_dir)
-		return -ENOMEM;
-
-	if (!debugfs_create_file("focus", S_IRUGO | S_IWUSR, cam_dir,
-							 NULL, &cam_focus))
-		return -ENOMEM;
-	if (!debugfs_create_file("step", S_IRUGO | S_IWUSR, cam_dir,
-							 NULL, &cam_step))
-		return -ENOMEM;
-	if (!debugfs_create_file("stream", S_IRUGO | S_IWUSR, cam_dir,
-							 NULL, &cam_stream))
-		return -ENOMEM;
-
-	return 0;
-}
-
-
-
diff --git a/drivers/media/video/msm/mt9e013.h b/drivers/media/video/msm/mt9e013.h
deleted file mode 100644
index 9052a35..0000000
--- a/drivers/media/video/msm/mt9e013.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. 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 MT9E013_H
-#define MT9E013_H
-#include <linux/types.h>
-#include <mach/board.h>
-extern struct mt9e013_reg mt9e013_regs;
-struct reg_struct_init {
-	uint8_t reg_0x0112;      /* 0x0112*/
-	uint8_t reg_0x0113;      /* 0x0113*/
-	uint8_t vt_pix_clk_div;  /* 0x0301*/
-	uint8_t pre_pll_clk_div; /* 0x0305*/
-	uint8_t pll_multiplier;  /* 0x0307*/
-	uint8_t op_pix_clk_div;  /* 0x0309*/
-	uint8_t reg_0x3030;      /*0x3030*/
-	uint8_t reg_0x0111;      /*0x0111*/
-	uint8_t reg_0x0b00;      /*0x0b00*/
-	uint8_t reg_0x3001;      /*0x3001*/
-	uint8_t reg_0x3004;      /*0x3004*/
-	uint8_t reg_0x3007;      /*0x3007*/
-	uint8_t reg_0x3016;      /*0x3016*/
-	uint8_t reg_0x301d;      /*0x301d*/
-	uint8_t reg_0x317e;      /*0x317E*/
-	uint8_t reg_0x317f;      /*0x317F*/
-	uint8_t reg_0x3400;      /*0x3400*/
-	uint8_t reg_0x0b06;      /*0x0b06*/
-	uint8_t reg_0x0b07;      /*0x0b07*/
-	uint8_t reg_0x0b08;      /*0x0b08*/
-	uint8_t reg_0x0b09;      /*0x0b09*/
-	uint8_t reg_0x0136;
-	uint8_t reg_0x0137;
-	/* Edof */
-	uint8_t reg_0x0b83;      /*0x0b83*/
-	uint8_t reg_0x0b84;      /*0x0b84*/
-	uint8_t reg_0x0b85;      /*0x0b85*/
-	uint8_t reg_0x0b88;      /*0x0b88*/
-	uint8_t reg_0x0b89;      /*0x0b89*/
-	uint8_t reg_0x0b8a;      /*0x0b8a*/
-	};
-struct reg_struct {
-	uint8_t coarse_integration_time_hi; /*REG_COARSE_INTEGRATION_TIME_HI*/
-	uint8_t coarse_integration_time_lo; /*REG_COARSE_INTEGRATION_TIME_LO*/
-	uint8_t analogue_gain_code_global;
-	uint8_t frame_length_lines_hi; /* 0x0340*/
-	uint8_t frame_length_lines_lo; /* 0x0341*/
-	uint8_t line_length_pck_hi;    /* 0x0342*/
-	uint8_t line_length_pck_lo;    /* 0x0343*/
-	uint8_t reg_0x3005;   /* 0x3005*/
-	uint8_t reg_0x3010;  /* 0x3010*/
-	uint8_t reg_0x3011;  /* 0x3011*/
-	uint8_t reg_0x301a;  /* 0x301a*/
-	uint8_t reg_0x3035;  /* 0x3035*/
-	uint8_t reg_0x3036;   /* 0x3036*/
-	uint8_t reg_0x3041;  /*0x3041*/
-	uint8_t reg_0x3042;  /*0x3042*/
-	uint8_t reg_0x3045;  /*0x3045*/
-	uint8_t reg_0x0b80;   /* 0x0b80*/
-	uint8_t reg_0x0900;   /*0x0900*/
-	uint8_t reg_0x0901;   /* 0x0901*/
-	uint8_t reg_0x0902;   /*0x0902*/
-	uint8_t reg_0x0383;   /*0x0383*/
-	uint8_t reg_0x0387;   /* 0x0387*/
-	uint8_t reg_0x034c;   /* 0x034c*/
-	uint8_t reg_0x034d;   /*0x034d*/
-	uint8_t reg_0x034e;   /* 0x034e*/
-	uint8_t reg_0x034f;   /* 0x034f*/
-	uint8_t reg_0x1716; /*0x1716*/
-	uint8_t reg_0x1717; /*0x1717*/
-	uint8_t reg_0x1718; /*0x1718*/
-	uint8_t reg_0x1719; /*0x1719*/
-	uint8_t reg_0x3210;/*0x3210*/
-	uint8_t reg_0x111; /*0x111*/
-	uint8_t reg_0x3410;  /*0x3410*/
-	uint8_t reg_0x3098;
-	uint8_t reg_0x309D;
-	uint8_t reg_0x0200;
-	uint8_t reg_0x0201;
-	};
-struct mt9e013_i2c_reg_conf {
-	unsigned short waddr;
-	unsigned short wdata;
-};
-
-enum mt9e013_test_mode_t {
-	TEST_OFF,
-	TEST_1,
-	TEST_2,
-	TEST_3
-};
-
-enum mt9e013_resolution_t {
-	QTR_SIZE,
-	FULL_SIZE,
-	HFR_60FPS,
-	HFR_90FPS,
-	HFR_120FPS,
-	INVALID_SIZE
-};
-enum mt9e013_setting {
-	RES_PREVIEW,
-	RES_CAPTURE
-};
-enum mt9e013_reg_update {
-	/* Sensor egisters that need to be updated during initialization */
-	REG_INIT,
-	/* Sensor egisters that needs periodic I2C writes */
-	UPDATE_PERIODIC,
-	/* All the sensor Registers will be updated */
-	UPDATE_ALL,
-	/* Not valid update */
-	UPDATE_INVALID
-};
-
-enum mt9e013_reg_pll {
-	E013_VT_PIX_CLK_DIV,
-	E013_VT_SYS_CLK_DIV,
-	E013_PRE_PLL_CLK_DIV,
-	E013_PLL_MULTIPLIER,
-	E013_OP_PIX_CLK_DIV,
-	E013_OP_SYS_CLK_DIV
-};
-
-enum mt9e013_reg_mode {
-	E013_X_ADDR_START,
-	E013_X_ADDR_END,
-	E013_Y_ADDR_START,
-	E013_Y_ADDR_END,
-	E013_X_OUTPUT_SIZE,
-	E013_Y_OUTPUT_SIZE,
-	E013_DATAPATH_SELECT,
-	E013_READ_MODE,
-	E013_ANALOG_CONTROL5,
-	E013_DAC_LD_4_5,
-	E013_SCALING_MODE,
-	E013_SCALE_M,
-	E013_LINE_LENGTH_PCK,
-	E013_FRAME_LENGTH_LINES,
-	E013_COARSE_INTEGRATION_TIME,
-	E013_FINE_INTEGRATION_TIME,
-	E013_FINE_CORRECTION
-};
-
-struct mt9e013_reg {
-	const struct mt9e013_i2c_reg_conf *reg_mipi;
-	const unsigned short reg_mipi_size;
-	const struct mt9e013_i2c_reg_conf *rec_settings;
-	const unsigned short rec_size;
-	const struct mt9e013_i2c_reg_conf *reg_pll;
-	const unsigned short reg_pll_size;
-	const struct mt9e013_i2c_reg_conf *reg_pll_60fps;
-	const unsigned short reg_pll_60fps_size;
-	const struct mt9e013_i2c_reg_conf *reg_pll_120fps;
-	const unsigned short reg_pll_120fps_size;
-	const struct mt9e013_i2c_reg_conf *reg_prev;
-	const unsigned short reg_prev_size;
-	const struct mt9e013_i2c_reg_conf *reg_snap;
-	const unsigned short reg_snap_size;
-	const struct mt9e013_i2c_reg_conf *reg_60fps;
-	const unsigned short reg_60fps_size;
-	const struct mt9e013_i2c_reg_conf *reg_120fps;
-	const unsigned short reg_120fps_size;
-};
-#endif /* MT9E013_H */
diff --git a/drivers/media/video/msm/mt9e013_reg.c b/drivers/media/video/msm/mt9e013_reg.c
deleted file mode 100644
index 9a4bd7e..0000000
--- a/drivers/media/video/msm/mt9e013_reg.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. 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 "mt9e013.h"
-
-static struct mt9e013_i2c_reg_conf mipi_settings[] = {
-	/*Disable embedded data*/
-	{0x3064, 0x7800},/*SMIA_TEST*/
-	/*configure 2-lane MIPI*/
-	{0x31AE, 0x0202},/*SERIAL_FORMAT*/
-	{0x31B8, 0x0E3F},/*MIPI_TIMING_2*/
-	/*set data to RAW10 format*/
-	{0x0112, 0x0A0A},/*CCP_DATA_FORMAT*/
-	{0x30F0, 0x8000},/*VCM CONTROL*/
-};
-
-/*PLL Configuration
-(Ext=24MHz, vt_pix_clk=174MHz, op_pix_clk=69.6MHz)*/
-static struct mt9e013_i2c_reg_conf pll_settings[] = {
-	{0x0300, 0x0004},/*VT_PIX_CLK_DIV*/
-	{0x0302, 0x0001},/*VT_SYS_CLK_DIV*/
-	{0x0304, 0x0002},/*PRE_PLL_CLK_DIV*/
-	{0x0306, 0x003A},/*PLL_MULTIPLIER*/
-	{0x0308, 0x000A},/*OP_PIX_CLK_DIV*/
-	{0x030A, 0x0001},/*OP_SYS_CLK_DIV*/
-};
-
-static struct mt9e013_i2c_reg_conf prev_settings[] = {
-	/*Output Size (1632x1224)*/
-	{0x0344, 0x0008},/*X_ADDR_START*/
-	{0x0348, 0x0CC9},/*X_ADDR_END*/
-	{0x0346, 0x0008},/*Y_ADDR_START*/
-	{0x034A, 0x0999},/*Y_ADDR_END*/
-	{0x034C, 0x0660},/*X_OUTPUT_SIZE*/
-	{0x034E, 0x04C8},/*Y_OUTPUT_SIZE*/
-	{0x306E, 0xFCB0},/*DATAPATH_SELECT*/
-	{0x3040, 0x04C3},/*READ_MODE*/
-	{0x3178, 0x0000},/*ANALOG_CONTROL5*/
-	{0x3ED0, 0x1E24},/*DAC_LD_4_5*/
-	{0x0400, 0x0002},/*SCALING_MODE*/
-	{0x0404, 0x0010},/*SCALE_M*/
-	/*Timing configuration*/
-	{0x0342, 0x1018},/*LINE_LENGTH_PCK*/
-	{0x0340, 0x055B},/*FRAME_LENGTH_LINES*/
-	{0x0202, 0x0557},/*COARSE_INTEGRATION_TIME*/
-	{0x3014, 0x0846},/*FINE_INTEGRATION_TIME_*/
-	{0x3010, 0x0130},/*FINE_CORRECTION*/
-};
-
-static struct mt9e013_i2c_reg_conf snap_settings[] = {
-	/*Output Size (3264x2448)*/
-	{0x0344, 0x0008},/*X_ADDR_START */
-	{0x0348, 0x0CD7},/*X_ADDR_END*/
-	{0x0346, 0x0008},/*Y_ADDR_START */
-	{0x034A, 0x09A7},/*Y_ADDR_END*/
-	{0x034C, 0x0CD0},/*X_OUTPUT_SIZE*/
-	{0x034E, 0x09A0},/*Y_OUTPUT_SIZE*/
-	{0x306E, 0xFC80},/*DATAPATH_SELECT*/
-	{0x3040, 0x0041},/*READ_MODE*/
-	{0x3178, 0x0000},/*ANALOG_CONTROL5*/
-	{0x3ED0, 0x1E24},/*DAC_LD_4_5*/
-	{0x0400, 0x0000},/*SCALING_MODE*/
-	{0x0404, 0x0010},/*SCALE_M*/
-	/*Timing configuration*/
-	{0x0342, 0x13F8},/*LINE_LENGTH_PCK*/
-	{0x0340, 0x0A2F},/*FRAME_LENGTH_LINES*/
-	{0x0202, 0x0A1F},/*COARSE_INTEGRATION_TIME*/
-	{0x3014, 0x03F6},/*FINE_INTEGRATION_TIME_ */
-	{0x3010, 0x0078},/*FINE_CORRECTION*/
-};
-
-static struct mt9e013_i2c_reg_conf pll_settings_60fps[] = {
-	{0x0300, 0x0004},/*VT_PIX_CLK_DIV*/
-	{0x0302, 0x0001},/*VT_SYS_CLK_DIV*/
-	{0x0304, 0x0002},/*PRE_PLL_CLK_DIV*/
-	{0x0306, 0x0042},/*PLL_MULTIPLIER*/
-	{0x0308, 0x000A},/*OP_PIX_CLK_DIV*/
-	{0x030A, 0x0001},/*OP_SYS_CLK_DIV*/
-};
-
-static struct mt9e013_i2c_reg_conf prev_settings_60fps[] = {
-	/*Output Size (1632x1224)*/
-	{0x0344, 0x0008},/*X_ADDR_START*/
-	{0x0348, 0x0CC5},/*X_ADDR_END*/
-	{0x0346, 0x013a},/*Y_ADDR_START*/
-	{0x034A, 0x0863},/*Y_ADDR_END*/
-	{0x034C, 0x0660},/*X_OUTPUT_SIZE*/
-	{0x034E, 0x0396},/*Y_OUTPUT_SIZE*/
-	{0x306E, 0xFC80},/*DATAPATH_SELECT*/
-	{0x3040, 0x00C3},/*READ_MODE*/
-	{0x3178, 0x0000},/*ANALOG_CONTROL5*/
-	{0x3ED0, 0x1E24},/*DAC_LD_4_5*/
-	{0x0400, 0x0000},/*SCALING_MODE*/
-	{0x0404, 0x0010},/*SCALE_M*/
-	/*Timing configuration*/
-	{0x0342, 0x0BE8},/*LINE_LENGTH_PCK*/
-	{0x0340, 0x0425},/*FRAME_LENGTH_LINES*/
-	{0x0202, 0x0425},/*COARSE_INTEGRATION_TIME*/
-	{0x3014, 0x03F6},/*FINE_INTEGRATION_TIME_*/
-	{0x3010, 0x0078},/*FINE_CORRECTION*/
-};
-
-static struct mt9e013_i2c_reg_conf pll_settings_120fps[] = {
-	{0x0300, 0x0005},/*VT_PIX_CLK_DIV*/
-	{0x0302, 0x0001},/*VT_SYS_CLK_DIV*/
-	{0x0304, 0x0002},/*PRE_PLL_CLK_DIV*/
-	{0x0306, 0x0052},/*PLL_MULTIPLIER*/
-	{0x0308, 0x000A},/*OP_PIX_CLK_DIV*/
-	{0x030A, 0x0001},/*OP_SYS_CLK_DIV*/
-};
-
-static struct mt9e013_i2c_reg_conf prev_settings_120fps[] = {
-	{0x0344, 0x0008},/*X_ADDR_START*/
-	{0x0348, 0x0685},/*X_ADDR_END*/
-	{0x0346, 0x013a},/*Y_ADDR_START*/
-	{0x034A, 0x055B},/*Y_ADDR_END*/
-	{0x034C, 0x0340},/*X_OUTPUT_SIZE*/
-	{0x034E, 0x0212},/*Y_OUTPUT_SIZE*/
-	{0x306E, 0xFC80},/*DATAPATH_SELECT*/
-	{0x3040, 0x00C3},/*READ_MODE*/
-	{0x3178, 0x0000},/*ANALOG_CONTROL5*/
-	{0x3ED0, 0x1E24},/*DAC_LD_4_5*/
-	{0x0400, 0x0000},/*SCALING_MODE*/
-	{0x0404, 0x0010},/*SCALE_M*/
-	/*Timing configuration*/
-	{0x0342, 0x0970},/*LINE_LENGTH_PCK*/
-	{0x0340, 0x02A1},/*FRAME_LENGTH_LINES*/
-	{0x0202, 0x02A1},/*COARSE_INTEGRATION_TIME*/
-	{0x3014, 0x03F6},/*FINE_INTEGRATION_TIME_*/
-	{0x3010, 0x0078},/*FINE_CORRECTION*/
-};
-
-static struct mt9e013_i2c_reg_conf recommend_settings[] = {
-	{0x3044, 0x0590},
-	{0x306E, 0xFC80},
-	{0x30B2, 0xC000},
-	{0x30D6, 0x0800},
-	{0x316C, 0xB42F},
-	{0x316E, 0x869C},
-	{0x3170, 0x210E},
-	{0x317A, 0x010E},
-	{0x31E0, 0x1FB9},
-	{0x31E6, 0x07FC},
-	{0x37C0, 0x0000},
-	{0x37C2, 0x0000},
-	{0x37C4, 0x0000},
-	{0x37C6, 0x0000},
-	{0x3E02, 0x8801},
-	{0x3E04, 0x2301},
-	{0x3E06, 0x8449},
-	{0x3E08, 0x6841},
-	{0x3E0A, 0x400C},
-	{0x3E0C, 0x1001},
-	{0x3E0E, 0x2103},
-	{0x3E10, 0x4B41},
-	{0x3E12, 0x4B26},
-	{0x3E16, 0x8802},
-	{0x3E18, 0x84FF},
-	{0x3E1A, 0x8601},
-	{0x3E1C, 0x8401},
-	{0x3E1E, 0x840A},
-	{0x3E20, 0xFF00},
-	{0x3E22, 0x8401},
-	{0x3E24, 0x00FF},
-	{0x3E26, 0x0088},
-	{0x3E28, 0x2E8A},
-	{0x3E32, 0x8801},
-	{0x3E34, 0x4024},
-	{0x3E38, 0x8469},
-	{0x3E3C, 0x2301},
-	{0x3E3E, 0x3E25},
-	{0x3E40, 0x1C01},
-	{0x3E42, 0x8486},
-	{0x3E44, 0x8401},
-	{0x3E46, 0x00FF},
-	{0x3E48, 0x8401},
-	{0x3E4A, 0x8601},
-	{0x3E4C, 0x8402},
-	{0x3E4E, 0x00FF},
-	{0x3E50, 0x6623},
-	{0x3E52, 0x8340},
-	{0x3E54, 0x00FF},
-	{0x3E56, 0x4A42},
-	{0x3E58, 0x2203},
-	{0x3E5A, 0x674D},
-	{0x3E5C, 0x3F25},
-	{0x3E5E, 0x846A},
-	{0x3E60, 0x4C01},
-	{0x3E62, 0x8401},
-	{0x3E66, 0x3901},
-	{0x3ECC, 0x00EB},
-	{0x3ED0, 0x1E24},
-	{0x3ED4, 0xAFC4},
-	{0x3ED6, 0x909B},
-	{0x3ED8, 0x0006},
-	{0x3EDA, 0xCFC6},
-	{0x3EDC, 0x4FE4},
-	{0x3EE0, 0x2424},
-	{0x3EE2, 0x9797},
-	{0x3EE4, 0xC100},
-	{0x3EE6, 0x0540}
-};
-
-struct mt9e013_reg mt9e013_regs = {
-	.reg_mipi = &mipi_settings[0],
-	.reg_mipi_size = ARRAY_SIZE(mipi_settings),
-	.rec_settings = &recommend_settings[0],
-	.rec_size = ARRAY_SIZE(recommend_settings),
-	.reg_pll = &pll_settings[0],
-	.reg_pll_size = ARRAY_SIZE(pll_settings),
-	.reg_prev = &prev_settings[0],
-	.reg_pll_60fps = &pll_settings_60fps[0],
-	.reg_pll_60fps_size = ARRAY_SIZE(pll_settings_60fps),
-	.reg_pll_120fps = &pll_settings_120fps[0],
-	.reg_pll_120fps_size = ARRAY_SIZE(pll_settings_120fps),
-	.reg_prev_size = ARRAY_SIZE(prev_settings),
-	.reg_snap = &snap_settings[0],
-	.reg_snap_size = ARRAY_SIZE(snap_settings),
-	.reg_60fps = &prev_settings_60fps[0],
-	.reg_60fps_size = ARRAY_SIZE(prev_settings_60fps),
-	.reg_120fps = &prev_settings_120fps[0],
-	.reg_120fps_size = ARRAY_SIZE(prev_settings_120fps),
-};
diff --git a/drivers/media/video/msm/mt9p012.h b/drivers/media/video/msm/mt9p012.h
deleted file mode 100644
index 3df98b7..0000000
--- a/drivers/media/video/msm/mt9p012.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. 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 MT9T012_H
-#define MT9T012_H
-
-#include <linux/types.h>
-#include <mach/board.h>
-
-extern struct mt9p012_reg mt9p012_regs;	/* from mt9p012_reg.c */
-
-struct reg_struct {
-	uint16_t vt_pix_clk_div;     /* 0x0300 */
-	uint16_t vt_sys_clk_div;     /* 0x0302 */
-	uint16_t pre_pll_clk_div;    /* 0x0304 */
-	uint16_t pll_multiplier;     /* 0x0306 */
-	uint16_t op_pix_clk_div;     /* 0x0308 */
-	uint16_t op_sys_clk_div;     /* 0x030A */
-	uint16_t scale_m;            /* 0x0404 */
-	uint16_t row_speed;          /* 0x3016 */
-	uint16_t x_addr_start;       /* 0x3004 */
-	uint16_t x_addr_end;         /* 0x3008 */
-	uint16_t y_addr_start;       /* 0x3002 */
-	uint16_t y_addr_end;         /* 0x3006 */
-	uint16_t read_mode;          /* 0x3040 */
-	uint16_t x_output_size ;     /* 0x034C */
-	uint16_t y_output_size;      /* 0x034E */
-	uint16_t line_length_pck;    /* 0x300C */
-	uint16_t frame_length_lines; /* 0x300A */
-	uint16_t coarse_int_time;    /* 0x3012 */
-	uint16_t fine_int_time;      /* 0x3014 */
-};
-
-
-struct mt9p012_i2c_reg_conf {
-	unsigned short waddr;
-	unsigned short wdata;
-};
-
-
-struct mt9p012_reg {
-	struct reg_struct const *reg_pat;
-	uint16_t reg_pat_size;
-	struct mt9p012_i2c_reg_conf const *ttbl;
-	uint16_t ttbl_size;
-	struct mt9p012_i2c_reg_conf const *rftbl;
-	uint16_t rftbl_size;
-};
-
-#endif /* MT9T012_H */
diff --git a/drivers/media/video/msm/mt9p012_bam.c b/drivers/media/video/msm/mt9p012_bam.c
deleted file mode 100644
index 9197380..0000000
--- a/drivers/media/video/msm/mt9p012_bam.c
+++ /dev/null
@@ -1,1426 +0,0 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. 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/delay.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/kernel.h>
-#include <media/msm_camera.h>
-#include <mach/gpio.h>
-#include <mach/camera.h>
-#include "mt9p012.h"
-
-/*=============================================================
-    SENSOR REGISTER DEFINES
-==============================================================*/
-#define MT9P012_REG_MODEL_ID         0x0000
-#define MT9P012_MODEL_ID             0x2801
-#define REG_GROUPED_PARAMETER_HOLD   0x0104
-#define GROUPED_PARAMETER_HOLD       0x0100
-#define GROUPED_PARAMETER_UPDATE     0x0000
-#define REG_COARSE_INT_TIME          0x3012
-#define REG_VT_PIX_CLK_DIV           0x0300
-#define REG_VT_SYS_CLK_DIV           0x0302
-#define REG_PRE_PLL_CLK_DIV          0x0304
-#define REG_PLL_MULTIPLIER           0x0306
-#define REG_OP_PIX_CLK_DIV           0x0308
-#define REG_OP_SYS_CLK_DIV           0x030A
-#define REG_SCALE_M                  0x0404
-#define REG_FRAME_LENGTH_LINES       0x300A
-#define REG_LINE_LENGTH_PCK          0x300C
-#define REG_X_ADDR_START             0x3004
-#define REG_Y_ADDR_START             0x3002
-#define REG_X_ADDR_END               0x3008
-#define REG_Y_ADDR_END               0x3006
-#define REG_X_OUTPUT_SIZE            0x034C
-#define REG_Y_OUTPUT_SIZE            0x034E
-#define REG_FINE_INTEGRATION_TIME    0x3014
-#define REG_ROW_SPEED                0x3016
-#define MT9P012_REG_RESET_REGISTER   0x301A
-#define MT9P012_RESET_REGISTER_PWON  0x10CC
-#define MT9P012_RESET_REGISTER_PWOFF 0x10C8
-#define REG_READ_MODE                0x3040
-#define REG_GLOBAL_GAIN              0x305E
-#define REG_TEST_PATTERN_MODE        0x3070
-
-#define MT9P012_REV_7
-
-enum mt9p012_test_mode {
-	TEST_OFF,
-	TEST_1,
-	TEST_2,
-	TEST_3
-};
-
-enum mt9p012_resolution {
-	QTR_SIZE,
-	FULL_SIZE,
-	INVALID_SIZE
-};
-
-enum mt9p012_reg_update {
-	/* Sensor egisters that need to be updated during initialization */
-	REG_INIT,
-	/* Sensor egisters that needs periodic I2C writes */
-	UPDATE_PERIODIC,
-	/* All the sensor Registers will be updated */
-	UPDATE_ALL,
-	/* Not valid update */
-	UPDATE_INVALID
-};
-
-enum mt9p012_setting {
-	RES_PREVIEW,
-	RES_CAPTURE
-};
-
-/* actuator's Slave Address */
-#define MT9P012_AF_I2C_ADDR   0x0A
-
-/* AF Total steps parameters */
-#define MT9P012_STEPS_NEAR_TO_CLOSEST_INF  20
-#define MT9P012_TOTAL_STEPS_NEAR_TO_FAR    20
-
-#define MT9P012_MU5M0_PREVIEW_DUMMY_PIXELS 0
-#define MT9P012_MU5M0_PREVIEW_DUMMY_LINES  0
-
-/* Time in milisecs for waiting for the sensor to reset.*/
-#define MT9P012_RESET_DELAY_MSECS   66
-
-/* for 20 fps preview */
-#define MT9P012_DEFAULT_CLOCK_RATE  24000000
-#define MT9P012_DEFAULT_MAX_FPS     26	/* ???? */
-
-struct mt9p012_work {
-	struct work_struct work;
-};
-static struct mt9p012_work *mt9p012_sensorw;
-static struct i2c_client *mt9p012_client;
-
-struct mt9p012_ctrl {
-	const struct msm_camera_sensor_info *sensordata;
-
-	int sensormode;
-	uint32_t fps_divider;	/* init to 1 * 0x00000400 */
-	uint32_t pict_fps_divider;	/* init to 1 * 0x00000400 */
-
-	uint16_t curr_lens_pos;
-	uint16_t init_curr_lens_pos;
-	uint16_t my_reg_gain;
-	uint32_t my_reg_line_count;
-
-	enum mt9p012_resolution prev_res;
-	enum mt9p012_resolution pict_res;
-	enum mt9p012_resolution curr_res;
-	enum mt9p012_test_mode set_test;
-};
-
-static uint16_t bam_macro, bam_infinite;
-static uint16_t bam_step_lookup_table[MT9P012_TOTAL_STEPS_NEAR_TO_FAR + 1];
-static uint16_t update_type = UPDATE_PERIODIC;
-static struct mt9p012_ctrl *mt9p012_ctrl;
-static DECLARE_WAIT_QUEUE_HEAD(mt9p012_wait_queue);
-DEFINE_MUTEX(mt9p012_mut);
-
-/*=============================================================*/
-
-static int mt9p012_i2c_rxdata(unsigned short saddr, int slength,
-			      unsigned char *rxdata, int rxlength)
-{
-	struct i2c_msg msgs[] = {
-		{
-			.addr = saddr,
-			.flags = 0,
-			.len = slength,
-			.buf = rxdata,
-		},
-		{
-			.addr = saddr,
-			.flags = I2C_M_RD,
-			.len = rxlength,
-			.buf = rxdata,
-		},
-	};
-
-	if (i2c_transfer(mt9p012_client->adapter, msgs, 2) < 0) {
-		CDBG("mt9p012_i2c_rxdata failed!\n");
-		return -EIO;
-	}
-
-	return 0;
-}
-static int32_t mt9p012_i2c_read_b(unsigned short saddr, unsigned char raddr,
-				  unsigned short *rdata)
-{
-	int32_t rc = 0;
-	if (!rdata)
-		return -EIO;
-	rc = mt9p012_i2c_rxdata(saddr, 1, &raddr, 1);
-	if (rc < 0)
-		return rc;
-	*rdata = raddr;
-	if (rc < 0)
-		CDBG("mt9p012_i2c_read_b failed!\n");
-	return rc;
-}
-
-static int32_t mt9p012_i2c_read_w(unsigned short saddr, unsigned short raddr,
-				  unsigned short *rdata)
-{
-	int32_t rc = 0;
-	unsigned char buf[4];
-
-	if (!rdata)
-		return -EIO;
-
-	memset(buf, 0, sizeof(buf));
-
-	buf[0] = (raddr & 0xFF00) >> 8;
-	buf[1] = (raddr & 0x00FF);
-
-	rc = mt9p012_i2c_rxdata(saddr, 2, buf, 2);
-	if (rc < 0)
-		return rc;
-
-	*rdata = buf[0] << 8 | buf[1];
-
-	if (rc < 0)
-		CDBG("mt9p012_i2c_read failed!\n");
-
-	return rc;
-}
-
-static int32_t mt9p012_i2c_txdata(unsigned short saddr, unsigned char *txdata,
-				  int length)
-{
-	struct i2c_msg msg[] = {
-		{
-		 .addr = saddr,
-		 .flags = 0,
-		 .len = length,
-		 .buf = txdata,
-		 },
-	};
-
-	if (i2c_transfer(mt9p012_client->adapter, msg, 1) < 0) {
-		CDBG("mt9p012_i2c_txdata failed\n");
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int32_t mt9p012_i2c_write_b(unsigned short saddr, unsigned short baddr,
-				   unsigned short bdata)
-{
-	int32_t rc = -EIO;
-	unsigned char buf[2];
-
-	memset(buf, 0, sizeof(buf));
-	buf[0] = baddr;
-	buf[1] = bdata;
-	rc = mt9p012_i2c_txdata(saddr, buf, 2);
-
-	if (rc < 0)
-		CDBG("i2c_write failed, saddr = 0x%x addr = 0x%x, val =0x%x!\n",
-		     saddr, baddr, bdata);
-
-	return rc;
-}
-
-static int32_t mt9p012_i2c_write_w(unsigned short saddr, unsigned short waddr,
-				   unsigned short wdata)
-{
-	int32_t rc = -EIO;
-	unsigned char buf[4];
-
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (waddr & 0xFF00) >> 8;
-	buf[1] = (waddr & 0x00FF);
-	buf[2] = (wdata & 0xFF00) >> 8;
-	buf[3] = (wdata & 0x00FF);
-
-	rc = mt9p012_i2c_txdata(saddr, buf, 4);
-
-	if (rc < 0)
-		CDBG("i2c_write_w failed, addr = 0x%x, val = 0x%x!\n",
-		     waddr, wdata);
-
-	return rc;
-}
-
-static int32_t mt9p012_i2c_write_w_table(struct mt9p012_i2c_reg_conf const
-					 *reg_conf_tbl, int num)
-{
-	int i;
-	int32_t rc = -EIO;
-
-	for (i = 0; i < num; i++) {
-		rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-					 reg_conf_tbl->waddr,
-					 reg_conf_tbl->wdata);
-		if (rc < 0)
-			break;
-		reg_conf_tbl++;
-	}
-
-	return rc;
-}
-
-static int32_t mt9p012_test(enum mt9p012_test_mode mo)
-{
-	int32_t rc = 0;
-
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-				 REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_HOLD);
-	if (rc < 0)
-		return rc;
-
-	if (mo == TEST_OFF)
-		return 0;
-	else {
-		rc = mt9p012_i2c_write_w_table(mt9p012_regs.ttbl,
-					       mt9p012_regs.ttbl_size);
-		if (rc < 0)
-			return rc;
-
-		rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-					 REG_TEST_PATTERN_MODE, (uint16_t) mo);
-		if (rc < 0)
-			return rc;
-	}
-
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-				 REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_UPDATE);
-	if (rc < 0)
-		return rc;
-
-	return rc;
-}
-
-static int32_t mt9p012_lens_shading_enable(uint8_t is_enable)
-{
-	int32_t rc = 0;
-
-	CDBG("%s: entered. enable = %d\n", __func__, is_enable);
-
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-				 REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_HOLD);
-	if (rc < 0)
-		return rc;
-
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x3780,
-				 ((uint16_t) is_enable) << 15);
-	if (rc < 0)
-		return rc;
-
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-				 REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_UPDATE);
-
-	CDBG("%s: exiting. rc = %d\n", __func__, rc);
-	return rc;
-}
-
-static int32_t mt9p012_set_lc(void)
-{
-	int32_t rc;
-
-	rc = mt9p012_i2c_write_w_table(mt9p012_regs.rftbl,
-				       mt9p012_regs.rftbl_size);
-
-	return rc;
-}
-
-static void mt9p012_get_pict_fps(uint16_t fps, uint16_t *pfps)
-{
-	/* input fps is preview fps in Q8 format */
-	uint32_t divider;	/*Q10 */
-	uint32_t pclk_mult;	/*Q10 */
-
-	if (mt9p012_ctrl->prev_res == QTR_SIZE) {
-		divider = (uint32_t)
-		    (((mt9p012_regs.reg_pat[RES_PREVIEW].frame_length_lines *
-		       mt9p012_regs.reg_pat[RES_PREVIEW].line_length_pck) *
-		      0x00000400) /
-		     (mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines *
-		      mt9p012_regs.reg_pat[RES_CAPTURE].line_length_pck));
-
-		pclk_mult =
-		    (uint32_t) ((mt9p012_regs.reg_pat[RES_CAPTURE].
-				 pll_multiplier * 0x00000400) /
-				(mt9p012_regs.reg_pat[RES_PREVIEW].
-				 pll_multiplier));
-	} else {
-		/* full size resolution used for preview. */
-		divider = 0x00000400;	/*1.0 */
-		pclk_mult = 0x00000400;	/*1.0 */
-	}
-
-	/* Verify PCLK settings and frame sizes. */
-	*pfps = (uint16_t) (fps * divider * pclk_mult / 0x00000400 /
-			    0x00000400);
-}
-
-static uint16_t mt9p012_get_prev_lines_pf(void)
-{
-	if (mt9p012_ctrl->prev_res == QTR_SIZE)
-		return mt9p012_regs.reg_pat[RES_PREVIEW].frame_length_lines;
-	else
-		return mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines;
-}
-
-static uint16_t mt9p012_get_prev_pixels_pl(void)
-{
-	if (mt9p012_ctrl->prev_res == QTR_SIZE)
-		return mt9p012_regs.reg_pat[RES_PREVIEW].line_length_pck;
-	else
-		return mt9p012_regs.reg_pat[RES_CAPTURE].line_length_pck;
-}
-
-static uint16_t mt9p012_get_pict_lines_pf(void)
-{
-	return mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines;
-}
-
-static uint16_t mt9p012_get_pict_pixels_pl(void)
-{
-	return mt9p012_regs.reg_pat[RES_CAPTURE].line_length_pck;
-}
-
-static uint32_t mt9p012_get_pict_max_exp_lc(void)
-{
-	uint16_t snapshot_lines_per_frame;
-
-	if (mt9p012_ctrl->pict_res == QTR_SIZE)
-		snapshot_lines_per_frame =
-		    mt9p012_regs.reg_pat[RES_PREVIEW].frame_length_lines - 1;
-	else
-		snapshot_lines_per_frame =
-		    mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines - 1;
-
-	return snapshot_lines_per_frame * 24;
-}
-
-static int32_t mt9p012_set_fps(struct fps_cfg *fps)
-{
-	/* input is new fps in Q10 format */
-	int32_t rc = 0;
-	enum mt9p012_setting setting;
-
-	mt9p012_ctrl->fps_divider = fps->fps_div;
-	mt9p012_ctrl->pict_fps_divider = fps->pict_fps_div;
-
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-				 REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_HOLD);
-	if (rc < 0)
-		return -EBUSY;
-
-	if (mt9p012_ctrl->sensormode == SENSOR_PREVIEW_MODE)
-		setting = RES_PREVIEW;
-	else
-		setting = RES_CAPTURE;
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-			REG_FRAME_LENGTH_LINES,
-			(mt9p012_regs.reg_pat[setting].frame_length_lines *
-			fps->fps_div / 0x00000400));
-	if (rc < 0)
-		return rc;
-
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-				 REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_UPDATE);
-
-	return rc;
-}
-
-static int32_t mt9p012_write_exp_gain(uint16_t gain, uint32_t line)
-{
-	uint16_t max_legal_gain = 0x01FF;
-	uint32_t line_length_ratio = 0x00000400;
-	enum mt9p012_setting setting;
-	int32_t rc = 0;
-
-	CDBG("Line:%d mt9p012_write_exp_gain \n", __LINE__);
-
-	if (mt9p012_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
-		mt9p012_ctrl->my_reg_gain = gain;
-		mt9p012_ctrl->my_reg_line_count = (uint16_t) line;
-	}
-
-	if (gain > max_legal_gain) {
-		CDBG("Max legal gain Line:%d \n", __LINE__);
-		gain = max_legal_gain;
-	}
-
-	/* Verify no overflow */
-	if (mt9p012_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
-		line = (uint32_t) (line * mt9p012_ctrl->fps_divider /
-				   0x00000400);
-		setting = RES_PREVIEW;
-	} else {
-		line = (uint32_t) (line * mt9p012_ctrl->pict_fps_divider /
-				   0x00000400);
-		setting = RES_CAPTURE;
-	}
-
-	/* Set digital gain to 1 */
-#ifdef MT9P012_REV_7
-	gain |= 0x1000;
-#else
-	gain |= 0x0200;
-#endif
-
-	if ((mt9p012_regs.reg_pat[setting].frame_length_lines - 1) < line) {
-		line_length_ratio = (uint32_t) (line * 0x00000400) /
-		    (mt9p012_regs.reg_pat[setting].frame_length_lines - 1);
-	} else
-		line_length_ratio = 0x00000400;
-
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr, REG_GLOBAL_GAIN, gain);
-	if (rc < 0) {
-		CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__);
-		return rc;
-	}
-
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-				 REG_COARSE_INT_TIME, line);
-	if (rc < 0) {
-		CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__);
-		return rc;
-	}
-
-	CDBG("mt9p012_write_exp_gain: gain = %d, line = %d\n", gain, line);
-
-	return rc;
-}
-
-static int32_t mt9p012_set_pict_exp_gain(uint16_t gain, uint32_t line)
-{
-	int32_t rc = 0;
-
-	CDBG("Line:%d mt9p012_set_pict_exp_gain \n", __LINE__);
-
-	rc = mt9p012_write_exp_gain(gain, line);
-	if (rc < 0) {
-		CDBG("Line:%d mt9p012_set_pict_exp_gain failed... \n",
-		     __LINE__);
-		return rc;
-	}
-
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-				 MT9P012_REG_RESET_REGISTER, 0x10CC | 0x0002);
-	if (rc < 0) {
-		CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__);
-		return rc;
-	}
-
-	mdelay(5);
-
-	/* camera_timed_wait(snapshot_wait*exposure_ratio); */
-	return rc;
-}
-
-static int32_t mt9p012_setting(enum mt9p012_reg_update rupdate,
-			       enum mt9p012_setting rt)
-{
-	int32_t rc = 0;
-
-	switch (rupdate) {
-	case UPDATE_PERIODIC:
-		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
-			struct mt9p012_i2c_reg_conf ppc_tbl[] = {
-				{REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_HOLD},
-				{REG_ROW_SPEED,
-				 mt9p012_regs.reg_pat[rt].row_speed},
-				{REG_X_ADDR_START,
-				 mt9p012_regs.reg_pat[rt].x_addr_start},
-				{REG_X_ADDR_END,
-				 mt9p012_regs.reg_pat[rt].x_addr_end},
-				{REG_Y_ADDR_START,
-				 mt9p012_regs.reg_pat[rt].y_addr_start},
-				{REG_Y_ADDR_END,
-				 mt9p012_regs.reg_pat[rt].y_addr_end},
-				{REG_READ_MODE,
-				 mt9p012_regs.reg_pat[rt].read_mode},
-				{REG_SCALE_M, mt9p012_regs.reg_pat[rt].scale_m},
-				{REG_X_OUTPUT_SIZE,
-				 mt9p012_regs.reg_pat[rt].x_output_size},
-				{REG_Y_OUTPUT_SIZE,
-				 mt9p012_regs.reg_pat[rt].y_output_size},
-
-				{REG_LINE_LENGTH_PCK,
-				 mt9p012_regs.reg_pat[rt].line_length_pck},
-				{REG_FRAME_LENGTH_LINES,
-				 (mt9p012_regs.reg_pat[rt].frame_length_lines *
-				  mt9p012_ctrl->fps_divider / 0x00000400)},
-				{REG_COARSE_INT_TIME,
-				 mt9p012_regs.reg_pat[rt].coarse_int_time},
-				{REG_FINE_INTEGRATION_TIME,
-				 mt9p012_regs.reg_pat[rt].fine_int_time},
-				{REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_UPDATE},
-			};
-			if (update_type == REG_INIT) {
-				update_type = rupdate;
-				return rc;
-			}
-			rc = mt9p012_i2c_write_w_table(&ppc_tbl[0],
-						ARRAY_SIZE(ppc_tbl));
-			if (rc < 0)
-				return rc;
-
-			rc = mt9p012_test(mt9p012_ctrl->set_test);
-			if (rc < 0)
-				return rc;
-
-			rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-						 MT9P012_REG_RESET_REGISTER,
-						 MT9P012_RESET_REGISTER_PWON |
-						 0x0002);
-			if (rc < 0)
-				return rc;
-
-			mdelay(5);	/* 15? wait for sensor to transition */
-
-			return rc;
-		}
-		break;		/* UPDATE_PERIODIC */
-
-	case REG_INIT:
-		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
-			struct mt9p012_i2c_reg_conf ipc_tbl1[] = {
-				{MT9P012_REG_RESET_REGISTER,
-				 MT9P012_RESET_REGISTER_PWOFF},
-				{REG_VT_PIX_CLK_DIV,
-				 mt9p012_regs.reg_pat[rt].vt_pix_clk_div},
-				{REG_VT_SYS_CLK_DIV,
-				 mt9p012_regs.reg_pat[rt].vt_sys_clk_div},
-				{REG_PRE_PLL_CLK_DIV,
-				 mt9p012_regs.reg_pat[rt].pre_pll_clk_div},
-				{REG_PLL_MULTIPLIER,
-				 mt9p012_regs.reg_pat[rt].pll_multiplier},
-				{REG_OP_PIX_CLK_DIV,
-				 mt9p012_regs.reg_pat[rt].op_pix_clk_div},
-				{REG_OP_SYS_CLK_DIV,
-				 mt9p012_regs.reg_pat[rt].op_sys_clk_div},
-#ifdef MT9P012_REV_7
-				{0x30B0, 0x0001},
-				{0x308E, 0xE060},
-				{0x3092, 0x0A52},
-				{0x3094, 0x4656},
-				{0x3096, 0x5652},
-				{0x30CA, 0x8006},
-				{0x312A, 0xDD02},
-				{0x312C, 0x00E4},
-				{0x3170, 0x299A},
-#endif
-				/* optimized settings for noise */
-				{0x3088, 0x6FF6},
-				{0x3154, 0x0282},
-				{0x3156, 0x0381},
-				{0x3162, 0x04CE},
-				{0x0204, 0x0010},
-				{0x0206, 0x0010},
-				{0x0208, 0x0010},
-				{0x020A, 0x0010},
-				{0x020C, 0x0010},
-				{MT9P012_REG_RESET_REGISTER,
-				 MT9P012_RESET_REGISTER_PWON},
-			};
-
-			struct mt9p012_i2c_reg_conf ipc_tbl2[] = {
-				{MT9P012_REG_RESET_REGISTER,
-				 MT9P012_RESET_REGISTER_PWOFF},
-				{REG_VT_PIX_CLK_DIV,
-				 mt9p012_regs.reg_pat[rt].vt_pix_clk_div},
-				{REG_VT_SYS_CLK_DIV,
-				 mt9p012_regs.reg_pat[rt].vt_sys_clk_div},
-				{REG_PRE_PLL_CLK_DIV,
-				 mt9p012_regs.reg_pat[rt].pre_pll_clk_div},
-				{REG_PLL_MULTIPLIER,
-				 mt9p012_regs.reg_pat[rt].pll_multiplier},
-				{REG_OP_PIX_CLK_DIV,
-				 mt9p012_regs.reg_pat[rt].op_pix_clk_div},
-				{REG_OP_SYS_CLK_DIV,
-				 mt9p012_regs.reg_pat[rt].op_sys_clk_div},
-#ifdef MT9P012_REV_7
-				{0x30B0, 0x0001},
-				{0x308E, 0xE060},
-				{0x3092, 0x0A52},
-				{0x3094, 0x4656},
-				{0x3096, 0x5652},
-				{0x30CA, 0x8006},
-				{0x312A, 0xDD02},
-				{0x312C, 0x00E4},
-				{0x3170, 0x299A},
-#endif
-				/* optimized settings for noise */
-				{0x3088, 0x6FF6},
-				{0x3154, 0x0282},
-				{0x3156, 0x0381},
-				{0x3162, 0x04CE},
-				{0x0204, 0x0010},
-				{0x0206, 0x0010},
-				{0x0208, 0x0010},
-				{0x020A, 0x0010},
-				{0x020C, 0x0010},
-				{MT9P012_REG_RESET_REGISTER,
-				 MT9P012_RESET_REGISTER_PWON},
-			};
-
-			struct mt9p012_i2c_reg_conf ipc_tbl3[] = {
-				{REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_HOLD},
-				/* Set preview or snapshot mode */
-				{REG_ROW_SPEED,
-				 mt9p012_regs.reg_pat[rt].row_speed},
-				{REG_X_ADDR_START,
-				 mt9p012_regs.reg_pat[rt].x_addr_start},
-				{REG_X_ADDR_END,
-				 mt9p012_regs.reg_pat[rt].x_addr_end},
-				{REG_Y_ADDR_START,
-				 mt9p012_regs.reg_pat[rt].y_addr_start},
-				{REG_Y_ADDR_END,
-				 mt9p012_regs.reg_pat[rt].y_addr_end},
-				{REG_READ_MODE,
-				 mt9p012_regs.reg_pat[rt].read_mode},
-				{REG_SCALE_M, mt9p012_regs.reg_pat[rt].scale_m},
-				{REG_X_OUTPUT_SIZE,
-				 mt9p012_regs.reg_pat[rt].x_output_size},
-				{REG_Y_OUTPUT_SIZE,
-				 mt9p012_regs.reg_pat[rt].y_output_size},
-				{REG_LINE_LENGTH_PCK,
-				 mt9p012_regs.reg_pat[rt].line_length_pck},
-				{REG_FRAME_LENGTH_LINES,
-				 mt9p012_regs.reg_pat[rt].frame_length_lines},
-				{REG_COARSE_INT_TIME,
-				 mt9p012_regs.reg_pat[rt].coarse_int_time},
-				{REG_FINE_INTEGRATION_TIME,
-				 mt9p012_regs.reg_pat[rt].fine_int_time},
-				{REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_UPDATE},
-			};
-
-			/* reset fps_divider */
-			mt9p012_ctrl->fps_divider = 1 * 0x0400;
-
-			rc = mt9p012_i2c_write_w_table(&ipc_tbl1[0],
-						       ARRAY_SIZE(ipc_tbl1));
-			if (rc < 0)
-				return rc;
-
-			rc = mt9p012_i2c_write_w_table(&ipc_tbl2[0],
-						       ARRAY_SIZE(ipc_tbl2));
-			if (rc < 0)
-				return rc;
-
-			mdelay(5);
-
-			rc = mt9p012_i2c_write_w_table(&ipc_tbl3[0],
-						       ARRAY_SIZE(ipc_tbl3));
-			if (rc < 0)
-				return rc;
-
-			/* load lens shading */
-			rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-						 REG_GROUPED_PARAMETER_HOLD,
-						 GROUPED_PARAMETER_HOLD);
-			if (rc < 0)
-				return rc;
-
-			rc = mt9p012_set_lc();
-			if (rc < 0)
-				return rc;
-
-			rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-						 REG_GROUPED_PARAMETER_HOLD,
-						 GROUPED_PARAMETER_UPDATE);
-
-			if (rc < 0)
-				return rc;
-		}
-		update_type = rupdate;
-		break;		/* case REG_INIT: */
-
-	default:
-		rc = -EINVAL;
-		break;
-	}			/* switch (rupdate) */
-
-	return rc;
-}
-
-static int32_t mt9p012_video_config(int mode, int res)
-{
-	int32_t rc;
-
-	switch (res) {
-	case QTR_SIZE:
-		rc = mt9p012_setting(UPDATE_PERIODIC, RES_PREVIEW);
-		if (rc < 0)
-			return rc;
-
-		CDBG("mt9p012 sensor configuration done!\n");
-		break;
-
-	case FULL_SIZE:
-		rc = mt9p012_setting(UPDATE_PERIODIC, RES_CAPTURE);
-		if (rc < 0)
-			return rc;
-
-		break;
-
-	default:
-		return 0;
-	}			/* switch */
-
-	mt9p012_ctrl->prev_res = res;
-	mt9p012_ctrl->curr_res = res;
-	mt9p012_ctrl->sensormode = mode;
-
-	rc = mt9p012_write_exp_gain(mt9p012_ctrl->my_reg_gain,
-				    mt9p012_ctrl->my_reg_line_count);
-
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-				 MT9P012_REG_RESET_REGISTER, 0x10cc | 0x0002);
-
-	return rc;
-}
-
-static int32_t mt9p012_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-
-	rc = mt9p012_setting(UPDATE_PERIODIC, RES_CAPTURE);
-	if (rc < 0)
-		return rc;
-
-	mt9p012_ctrl->curr_res = mt9p012_ctrl->pict_res;
-
-	mt9p012_ctrl->sensormode = mode;
-
-	return rc;
-}
-
-static int32_t mt9p012_raw_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-
-	rc = mt9p012_setting(UPDATE_PERIODIC, RES_CAPTURE);
-	if (rc < 0)
-		return rc;
-
-	mt9p012_ctrl->curr_res = mt9p012_ctrl->pict_res;
-
-	mt9p012_ctrl->sensormode = mode;
-
-	return rc;
-}
-
-static int32_t mt9p012_power_down(void)
-{
-	int32_t rc = 0;
-
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-				 MT9P012_REG_RESET_REGISTER,
-				 MT9P012_RESET_REGISTER_PWOFF);
-
-	mdelay(5);
-	return rc;
-}
-
-static int32_t mt9p012_move_focus(int direction, int32_t num_steps)
-{
-	int32_t rc;
-	int16_t step_direction;
-	int16_t actual_step;
-	int16_t next_position;
-	uint8_t code_val;
-	uint8_t time_out;
-	uint8_t temp_pos;
-
-	uint16_t actual_position_target;
-	if (num_steps > MT9P012_TOTAL_STEPS_NEAR_TO_FAR)
-		num_steps = MT9P012_TOTAL_STEPS_NEAR_TO_FAR;
-	else if (num_steps == 0) {
-		CDBG("mt9p012_move_focus failed at line %d ...\n", __LINE__);
-		return -EINVAL;
-	}
-
-	if (direction == MOVE_NEAR)
-		step_direction = -1;
-	else if (direction == MOVE_FAR)
-		step_direction = 1;
-	else {
-		CDBG("mt9p012_move_focus failed at line %d ...\n", __LINE__);
-		return -EINVAL;
-	}
-
-	if (mt9p012_ctrl->curr_lens_pos < mt9p012_ctrl->init_curr_lens_pos)
-		mt9p012_ctrl->curr_lens_pos = mt9p012_ctrl->init_curr_lens_pos;
-
-	actual_step = (int16_t) (step_direction * (int16_t) num_steps);
-	next_position = (int16_t) (mt9p012_ctrl->curr_lens_pos + actual_step);
-
-	if (next_position > MT9P012_TOTAL_STEPS_NEAR_TO_FAR)
-		next_position = MT9P012_TOTAL_STEPS_NEAR_TO_FAR;
-	else if (next_position < 0)
-		next_position = 0;
-
-	if (num_steps >= 10)
-		time_out = 100;
-	else
-		time_out = 30;
-	code_val = next_position;
-	actual_position_target = bam_step_lookup_table[code_val];
-	rc = mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x01, 0x29);
-	if (rc < 0)
-		return rc;
-	temp_pos = (uint8_t) (actual_position_target >> 8);
-	rc = mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x05, temp_pos);
-	if (rc < 0)
-		return rc;
-	temp_pos = (uint8_t) (actual_position_target & 0x00FF);
-	/* code_val_lsb |= mode_mask; */
-	rc = mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x06, temp_pos);
-	if (rc < 0)
-		return rc;
-
-	rc = mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x0B, time_out);
-	if (rc < 0)
-		return rc;
-	rc = mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x07, 0x27);
-	if (rc < 0)
-		return rc;
-
-	mdelay(time_out);
-
-	/* Storing the current lens Position */
-	mt9p012_ctrl->curr_lens_pos = next_position;
-
-	return rc;
-}
-
-static int32_t mt9p012_set_default_focus(void)
-{
-	int32_t rc = 0;
-
-	uint8_t temp_pos;
-
-	/* Write the digital code for current to the actuator */
-	rc = mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x01, 0x29);
-	if (rc < 0)
-		return rc;
-	temp_pos = (uint8_t) (bam_infinite >> 8);
-
-	rc = mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x05, temp_pos);
-	if (rc < 0)
-		return rc;
-	temp_pos = (uint8_t) (bam_infinite & 0x00FF);
-	rc = mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x06, temp_pos);
-	if (rc < 0)
-		return rc;
-
-	rc = mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x0B, 0x64);
-	if (rc < 0)
-		return rc;
-
-	rc = mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x07, 0x27);
-	if (rc < 0)
-		return rc;
-
-	mdelay(140);
-
-	mt9p012_ctrl->curr_lens_pos = MT9P012_TOTAL_STEPS_NEAR_TO_FAR;
-
-	return rc;
-}
-
-static int mt9p012_probe_init_done(const struct msm_camera_sensor_info *data)
-{
-	gpio_direction_output(data->sensor_reset, 0);
-	gpio_free(data->sensor_reset);
-	return 0;
-}
-
-static int mt9p012_probe_init_sensor(const struct msm_camera_sensor_info *data)
-{
-	int32_t rc;
-	uint16_t chipid;
-
-	rc = gpio_request(data->sensor_reset, "mt9p012");
-	if (!rc)
-		gpio_direction_output(data->sensor_reset, 1);
-	else
-		goto init_probe_done;
-
-	msleep(20);
-
-	/* RESET the sensor image part via I2C command */
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-				 MT9P012_REG_RESET_REGISTER, 0x10CC | 0x0001);
-	if (rc < 0) {
-		CDBG("sensor reset failed. rc = %d\n", rc);
-		goto init_probe_fail;
-	}
-
-	msleep(MT9P012_RESET_DELAY_MSECS);
-
-	/* 3. Read sensor Model ID: */
-	rc = mt9p012_i2c_read_w(mt9p012_client->addr,
-				MT9P012_REG_MODEL_ID, &chipid);
-	if (rc < 0)
-		goto init_probe_fail;
-
-	/* 4. Compare sensor ID to MT9T012VC ID: */
-	if (chipid != MT9P012_MODEL_ID) {
-		rc = -ENODEV;
-		goto init_probe_fail;
-	}
-
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x306E, 0x9000);
-	if (rc < 0) {
-		CDBG("REV_7 write failed. rc = %d\n", rc);
-		goto init_probe_fail;
-	}
-
-	/* RESET_REGISTER, enable parallel interface and disable serialiser */
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x301A, 0x10CC);
-	if (rc < 0) {
-		CDBG("enable parallel interface failed. rc = %d\n", rc);
-		goto init_probe_fail;
-	}
-
-	/* To disable the 2 extra lines */
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x3064, 0x0805);
-
-	if (rc < 0) {
-		CDBG("disable the 2 extra lines failed. rc = %d\n", rc);
-		goto init_probe_fail;
-	}
-
-	goto init_probe_done;
-
-init_probe_fail:
-	mt9p012_probe_init_done(data);
-init_probe_done:
-	return rc;
-}
-
-static int mt9p012_sensor_open_init(const struct msm_camera_sensor_info *data)
-{
-	int32_t rc;
-	unsigned short temp_pos;
-	uint8_t i;
-	uint16_t temp;
-
-	mt9p012_ctrl = kzalloc(sizeof(struct mt9p012_ctrl), GFP_KERNEL);
-	if (!mt9p012_ctrl) {
-		CDBG("mt9p012_init failed!\n");
-		rc = -ENOMEM;
-		goto init_done;
-	}
-
-	mt9p012_ctrl->fps_divider = 1 * 0x00000400;
-	mt9p012_ctrl->pict_fps_divider = 1 * 0x00000400;
-	mt9p012_ctrl->set_test = TEST_OFF;
-	mt9p012_ctrl->prev_res = QTR_SIZE;
-	mt9p012_ctrl->pict_res = FULL_SIZE;
-
-	if (data)
-		mt9p012_ctrl->sensordata = data;
-
-	msm_camio_camif_pad_reg_reset();
-	mdelay(20);
-
-	rc = mt9p012_probe_init_sensor(data);
-	if (rc < 0)
-		goto init_fail1;
-
-	if (mt9p012_ctrl->prev_res == QTR_SIZE)
-		rc = mt9p012_setting(REG_INIT, RES_PREVIEW);
-	else
-		rc = mt9p012_setting(REG_INIT, RES_CAPTURE);
-
-	if (rc < 0) {
-		CDBG("mt9p012_setting failed. rc = %d\n", rc);
-		goto init_fail1;
-	}
-
-	/* sensor : output enable */
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-				 MT9P012_REG_RESET_REGISTER,
-				 MT9P012_RESET_REGISTER_PWON);
-	if (rc < 0) {
-		CDBG("sensor output enable failed. rc = %d\n", rc);
-		goto init_fail1;
-	}
-
-	/* enable AF actuator */
-	rc = gpio_request(mt9p012_ctrl->sensordata->vcm_pwd, "mt9p012");
-	if (!rc)
-		gpio_direction_output(mt9p012_ctrl->sensordata->vcm_pwd, 1);
-	else {
-		CDBG("mt9p012_ctrl gpio request failed!\n");
-		goto init_fail1;
-	}
-
-	mdelay(20);
-
-	bam_infinite = 0;
-	bam_macro = 0;
-	/*initialize AF actuator */
-	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x01, 0x09);
-	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x07, 0x2E);
-	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x0A, 0x01);
-	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x17, 0x06);
-	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x16, 0x0A);
-
-	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x01, 0x29);
-	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x05, 0x00);
-	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x06, 0x00);
-	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x0B, 0x64);
-	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x07, 0x27);
-	mdelay(140);
-	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x01, 0x29);
-	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x05, 0x03);
-	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x06, 0xFF);
-	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x0B, 0x64);
-	mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, 0x07, 0x27);
-	mdelay(140);
-
-	if (mt9p012_i2c_read_b(MT9P012_AF_I2C_ADDR >> 1, 0x12, &temp_pos)
-	    >= 0) {
-		bam_infinite = (uint16_t) temp_pos;
-		if (mt9p012_i2c_read_b
-		    (MT9P012_AF_I2C_ADDR >> 1, 0x13, &temp_pos) >= 0)
-			bam_infinite =
-			    (bam_infinite << 8) | ((uint16_t) temp_pos);
-	} else {
-		bam_infinite = 100;
-	}
-
-	if (mt9p012_i2c_read_b(MT9P012_AF_I2C_ADDR >> 1, 0x14, &temp_pos)
-	    >= 0) {
-		bam_macro = (uint16_t) temp_pos;
-		if (mt9p012_i2c_read_b
-		    (MT9P012_AF_I2C_ADDR >> 1, 0x15, &temp_pos) >= 0)
-			bam_macro = (bam_macro << 8) | ((uint16_t) temp_pos);
-	}
-	temp = (bam_infinite - bam_macro) / MT9P012_TOTAL_STEPS_NEAR_TO_FAR;
-	for (i = 0; i < MT9P012_TOTAL_STEPS_NEAR_TO_FAR; i++)
-		bam_step_lookup_table[i] = bam_macro + temp * i;
-
-	bam_step_lookup_table[MT9P012_TOTAL_STEPS_NEAR_TO_FAR] = bam_infinite;
-
-	rc = mt9p012_set_default_focus();
-	if (rc >= 0)
-		goto init_done;
-
-init_fail1:
-	mt9p012_probe_init_done(data);
-	kfree(mt9p012_ctrl);
-init_done:
-	return rc;
-}
-
-static int mt9p012_init_client(struct i2c_client *client)
-{
-	/* Initialize the MSM_CAMI2C Chip */
-	init_waitqueue_head(&mt9p012_wait_queue);
-	return 0;
-}
-
-static int32_t mt9p012_set_sensor_mode(int mode, int res)
-{
-	int32_t rc = 0;
-
-	switch (mode) {
-	case SENSOR_PREVIEW_MODE:
-		rc = mt9p012_video_config(mode, res);
-		break;
-
-	case SENSOR_SNAPSHOT_MODE:
-		rc = mt9p012_snapshot_config(mode);
-		break;
-
-	case SENSOR_RAW_SNAPSHOT_MODE:
-		rc = mt9p012_raw_snapshot_config(mode);
-		break;
-
-	default:
-		rc = -EINVAL;
-		break;
-	}
-
-	return rc;
-}
-
-int mt9p012_sensor_config(void __user *argp)
-{
-	struct sensor_cfg_data cdata;
-	int rc = 0;
-
-	if (copy_from_user(&cdata,
-			   (void *)argp, sizeof(struct sensor_cfg_data)))
-		return -EFAULT;
-
-	mutex_lock(&mt9p012_mut);
-
-	CDBG("%s: cfgtype = %d\n", __func__, cdata.cfgtype);
-	switch (cdata.cfgtype) {
-	case CFG_GET_PICT_FPS:
-		mt9p012_get_pict_fps(cdata.cfg.gfps.prevfps,
-				     &(cdata.cfg.gfps.pictfps));
-
-		if (copy_to_user((void *)argp, &cdata,
-				 sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PREV_L_PF:
-		cdata.cfg.prevl_pf = mt9p012_get_prev_lines_pf();
-
-		if (copy_to_user((void *)argp,
-				 &cdata, sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PREV_P_PL:
-		cdata.cfg.prevp_pl = mt9p012_get_prev_pixels_pl();
-
-		if (copy_to_user((void *)argp,
-				 &cdata, sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PICT_L_PF:
-		cdata.cfg.pictl_pf = mt9p012_get_pict_lines_pf();
-
-		if (copy_to_user((void *)argp,
-				 &cdata, sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PICT_P_PL:
-		cdata.cfg.pictp_pl = mt9p012_get_pict_pixels_pl();
-
-		if (copy_to_user((void *)argp,
-				 &cdata, sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PICT_MAX_EXP_LC:
-		cdata.cfg.pict_max_exp_lc = mt9p012_get_pict_max_exp_lc();
-
-		if (copy_to_user((void *)argp,
-				 &cdata, sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_SET_FPS:
-	case CFG_SET_PICT_FPS:
-		rc = mt9p012_set_fps(&(cdata.cfg.fps));
-		break;
-
-	case CFG_SET_EXP_GAIN:
-		rc = mt9p012_write_exp_gain(cdata.cfg.exp_gain.gain,
-					    cdata.cfg.exp_gain.line);
-		break;
-
-	case CFG_SET_PICT_EXP_GAIN:
-		CDBG("Line:%d CFG_SET_PICT_EXP_GAIN \n", __LINE__);
-		rc = mt9p012_set_pict_exp_gain(cdata.cfg.exp_gain.gain,
-					       cdata.cfg.exp_gain.line);
-		break;
-
-	case CFG_SET_MODE:
-		rc = mt9p012_set_sensor_mode(cdata.mode, cdata.rs);
-		break;
-
-	case CFG_PWR_DOWN:
-		rc = mt9p012_power_down();
-		break;
-
-	case CFG_MOVE_FOCUS:
-		CDBG("mt9p012_ioctl: CFG_MOVE_FOCUS: dir=%d steps=%d\n",
-		     cdata.cfg.focus.dir, cdata.cfg.focus.steps);
-		rc = mt9p012_move_focus(cdata.cfg.focus.dir,
-					cdata.cfg.focus.steps);
-		break;
-
-	case CFG_SET_DEFAULT_FOCUS:
-		rc = mt9p012_set_default_focus();
-
-		break;
-
-	case CFG_SET_EFFECT:
-		rc = mt9p012_set_default_focus();
-		break;
-
-	case CFG_SET_LENS_SHADING:
-		CDBG("%s: CFG_SET_LENS_SHADING\n", __func__);
-		rc = mt9p012_lens_shading_enable(cdata.cfg.lens_shading);
-		break;
-
-	case CFG_GET_AF_MAX_STEPS:
-		cdata.max_steps = MT9P012_STEPS_NEAR_TO_CLOSEST_INF;
-		if (copy_to_user((void *)argp,
-				 &cdata, sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	default:
-		rc = -EINVAL;
-		break;
-	}
-
-	mutex_unlock(&mt9p012_mut);
-	return rc;
-}
-
-int mt9p012_sensor_release(void)
-{
-	int rc = -EBADF;
-
-	mutex_lock(&mt9p012_mut);
-
-	mt9p012_power_down();
-
-	gpio_direction_output(mt9p012_ctrl->sensordata->sensor_reset, 0);
-	gpio_free(mt9p012_ctrl->sensordata->sensor_reset);
-
-	gpio_direction_output(mt9p012_ctrl->sensordata->vcm_pwd, 0);
-	gpio_free(mt9p012_ctrl->sensordata->vcm_pwd);
-
-	kfree(mt9p012_ctrl);
-	mt9p012_ctrl = NULL;
-
-	CDBG("mt9p012_release completed\n");
-
-	mutex_unlock(&mt9p012_mut);
-	return rc;
-}
-
-static int mt9p012_i2c_probe(struct i2c_client *client,
-			     const struct i2c_device_id *id)
-{
-	int rc = 0;
-	CDBG("mt9p012_probe called!\n");
-
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		CDBG("i2c_check_functionality failed\n");
-		goto probe_failure;
-	}
-
-	mt9p012_sensorw = kzalloc(sizeof(struct mt9p012_work), GFP_KERNEL);
-	if (!mt9p012_sensorw) {
-		CDBG("kzalloc failed.\n");
-		rc = -ENOMEM;
-		goto probe_failure;
-	}
-
-	i2c_set_clientdata(client, mt9p012_sensorw);
-	mt9p012_init_client(client);
-	mt9p012_client = client;
-
-	mdelay(50);
-
-	CDBG("mt9p012_probe successed! rc = %d\n", rc);
-	return 0;
-
-probe_failure:
-	CDBG("mt9p012_probe failed! rc = %d\n", rc);
-	return rc;
-}
-
-static int __exit mt9p012_remove(struct i2c_client *client)
-{
-	struct mt9p012_work_t *sensorw = i2c_get_clientdata(client);
-	free_irq(client->irq, sensorw);
-	mt9p012_client = NULL;
-	kfree(sensorw);
-	return 0;
-}
-
-static const struct i2c_device_id mt9p012_i2c_id[] = {
-	{"mt9p012", 0}
-};
-
-static struct i2c_driver mt9p012_i2c_driver = {
-	.id_table = mt9p012_i2c_id,
-	.probe = mt9p012_i2c_probe,
-	.remove = __exit_p(mt9p012_i2c_remove),
-	.driver = {
-		.name = "mt9p012",
-	},
-};
-
-static int mt9p012_sensor_probe(const struct msm_camera_sensor_info *info,
-				struct msm_sensor_ctrl *s)
-{
-	int rc = i2c_add_driver(&mt9p012_i2c_driver);
-	if (rc < 0 || mt9p012_client == NULL) {
-		rc = -ENOTSUPP;
-		goto probe_done;
-	}
-
-	msm_camio_clk_rate_set(MT9P012_DEFAULT_CLOCK_RATE);
-	mdelay(20);
-
-	rc = mt9p012_probe_init_sensor(info);
-	if (rc < 0)
-		goto probe_done;
-
-	s->s_init = mt9p012_sensor_open_init;
-	s->s_release = mt9p012_sensor_release;
-	s->s_config = mt9p012_sensor_config;
-	s->s_mount_angle  = 0;
-	mt9p012_probe_init_done(info);
-
-probe_done:
-	CDBG("%s %s:%d\n", __FILE__, __func__, __LINE__);
-	return rc;
-}
-
-static int __mt9p012_probe(struct platform_device *pdev)
-{
-	return msm_camera_drv_start(pdev, mt9p012_sensor_probe);
-}
-
-static struct platform_driver msm_camera_driver = {
-	.probe = __mt9p012_probe,
-	.driver = {
-		.name = "msm_camera_mt9p012",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init mt9p012_init(void)
-{
-	return platform_driver_register(&msm_camera_driver);
-}
-
-module_init(mt9p012_init);
-void mt9p012_exit(void)
-{
-	i2c_del_driver(&mt9p012_i2c_driver);
-}
diff --git a/drivers/media/video/msm/mt9p012_fox.c b/drivers/media/video/msm/mt9p012_fox.c
deleted file mode 100644
index a652c9f..0000000
--- a/drivers/media/video/msm/mt9p012_fox.c
+++ /dev/null
@@ -1,1346 +0,0 @@
-/* Copyright (c) 2009, 2011 Code Aurora Forum. 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/slab.h>
-#include <linux/delay.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/kernel.h>
-#include <media/msm_camera.h>
-#include <mach/gpio.h>
-#include <mach/camera.h>
-#include "mt9p012.h"
-
-/*=============================================================
-    SENSOR REGISTER DEFINES
-==============================================================*/
-#define MT9P012_REG_MODEL_ID         0x0000
-#define MT9P012_MODEL_ID             0x2801
-#define REG_GROUPED_PARAMETER_HOLD   0x0104
-#define GROUPED_PARAMETER_HOLD       0x0100
-#define GROUPED_PARAMETER_UPDATE     0x0000
-#define REG_COARSE_INT_TIME          0x3012
-#define REG_VT_PIX_CLK_DIV           0x0300
-#define REG_VT_SYS_CLK_DIV           0x0302
-#define REG_PRE_PLL_CLK_DIV          0x0304
-#define REG_PLL_MULTIPLIER           0x0306
-#define REG_OP_PIX_CLK_DIV           0x0308
-#define REG_OP_SYS_CLK_DIV           0x030A
-#define REG_SCALE_M                  0x0404
-#define REG_FRAME_LENGTH_LINES       0x300A
-#define REG_LINE_LENGTH_PCK          0x300C
-#define REG_X_ADDR_START             0x3004
-#define REG_Y_ADDR_START             0x3002
-#define REG_X_ADDR_END               0x3008
-#define REG_Y_ADDR_END               0x3006
-#define REG_X_OUTPUT_SIZE            0x034C
-#define REG_Y_OUTPUT_SIZE            0x034E
-#define REG_FINE_INTEGRATION_TIME    0x3014
-#define REG_ROW_SPEED                0x3016
-#define MT9P012_REG_RESET_REGISTER   0x301A
-#define MT9P012_RESET_REGISTER_PWON  0x10CC
-#define MT9P012_RESET_REGISTER_PWOFF 0x10C8
-#define REG_READ_MODE                0x3040
-#define REG_GLOBAL_GAIN              0x305E
-#define REG_TEST_PATTERN_MODE        0x3070
-
-#define MT9P012_REV_7
-
-enum mt9p012_test_mode {
-	TEST_OFF,
-	TEST_1,
-	TEST_2,
-	TEST_3
-};
-
-enum mt9p012_resolution {
-	QTR_SIZE,
-	FULL_SIZE,
-	INVALID_SIZE
-};
-
-enum mt9p012_reg_update {
-	/* Sensor egisters that need to be updated during initialization */
-	REG_INIT,
-	/* Sensor egisters that needs periodic I2C writes */
-	UPDATE_PERIODIC,
-	/* All the sensor Registers will be updated */
-	UPDATE_ALL,
-	/* Not valid update */
-	UPDATE_INVALID
-};
-
-enum mt9p012_setting {
-	RES_PREVIEW,
-	RES_CAPTURE
-};
-
-/* actuator's Slave Address */
-#define MT9P012_AF_I2C_ADDR   0x18
-
-/* AF Total steps parameters */
-#define MT9P012_STEPS_NEAR_TO_CLOSEST_INF  32
-#define MT9P012_TOTAL_STEPS_NEAR_TO_FAR    32
-
-#define MT9P012_MU5M0_PREVIEW_DUMMY_PIXELS 0
-#define MT9P012_MU5M0_PREVIEW_DUMMY_LINES  0
-
-/* Time in milisecs for waiting for the sensor to reset.*/
-#define MT9P012_RESET_DELAY_MSECS   66
-
-/* for 20 fps preview */
-#define MT9P012_DEFAULT_CLOCK_RATE  24000000
-#define MT9P012_DEFAULT_MAX_FPS     26	/* ???? */
-
-struct mt9p012_work {
-	struct work_struct work;
-};
-static struct mt9p012_work *mt9p012_sensorw;
-static struct i2c_client *mt9p012_client;
-
-struct mt9p012_ctrl {
-	const struct msm_camera_sensor_info *sensordata;
-
-	int sensormode;
-	uint32_t fps_divider;	/* init to 1 * 0x00000400 */
-	uint32_t pict_fps_divider;	/* init to 1 * 0x00000400 */
-
-	uint16_t curr_lens_pos;
-	uint16_t init_curr_lens_pos;
-	uint16_t my_reg_gain;
-	uint32_t my_reg_line_count;
-
-	enum mt9p012_resolution prev_res;
-	enum mt9p012_resolution pict_res;
-	enum mt9p012_resolution curr_res;
-	enum mt9p012_test_mode set_test;
-};
-static uint16_t update_type = UPDATE_PERIODIC;
-static struct mt9p012_ctrl *mt9p012_ctrl;
-static DECLARE_WAIT_QUEUE_HEAD(mt9p012_wait_queue);
-DEFINE_MUTEX(mt9p012_mut);
-
-
-/*=============================================================*/
-
-static int mt9p012_i2c_rxdata(unsigned short saddr, unsigned char *rxdata,
-			      int length)
-{
-	int retry_cnt = 0;
-	int rc;
-
-	struct i2c_msg msgs[] = {
-		{
-		 .addr = saddr,
-		 .flags = 0,
-		 .len = 2,
-		 .buf = rxdata,
-		 },
-		{
-		 .addr = saddr,
-		 .flags = I2C_M_RD,
-		 .len = length,
-		 .buf = rxdata,
-		 },
-	};
-
-	do {
-		rc = i2c_transfer(mt9p012_client->adapter, msgs, 2);
-		if (rc > 0)
-			break;
-		retry_cnt++;
-	} while (retry_cnt < 3);
-
-	if (rc < 0) {
-		pr_err("mt9p012_i2c_rxdata failed!:%d %d\n", rc, retry_cnt);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int32_t mt9p012_i2c_read_w(unsigned short saddr, unsigned short raddr,
-				  unsigned short *rdata)
-{
-	int32_t rc = 0;
-	unsigned char buf[4];
-
-	if (!rdata)
-		return -EIO;
-
-	memset(buf, 0, sizeof(buf));
-
-	buf[0] = (raddr & 0xFF00) >> 8;
-	buf[1] = (raddr & 0x00FF);
-
-	rc = mt9p012_i2c_rxdata(saddr, buf, 2);
-	if (rc < 0)
-		return rc;
-
-	*rdata = buf[0] << 8 | buf[1];
-
-	if (rc < 0)
-		CDBG("mt9p012_i2c_read failed!\n");
-
-	return rc;
-}
-
-static int32_t mt9p012_i2c_txdata(unsigned short saddr, unsigned char *txdata,
-				  int length)
-{
-	int retry_cnt = 0;
-	int rc;
-
-	struct i2c_msg msg[] = {
-		{
-		 .addr = saddr,
-		 .flags = 0,
-		 .len = length,
-		 .buf = txdata,
-		 },
-	};
-
-	do {
-		rc = i2c_transfer(mt9p012_client->adapter, msg, 1);
-		if (rc > 0)
-			break;
-		retry_cnt++;
-	} while (retry_cnt < 3);
-
-	if (rc < 0) {
-		pr_err("mt9p012_i2c_txdata failed: %d %d\n", rc, retry_cnt);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int32_t mt9p012_i2c_write_b(unsigned short saddr, unsigned short baddr,
-				   unsigned short bdata)
-{
-	int32_t rc = -EIO;
-	unsigned char buf[2];
-
-	memset(buf, 0, sizeof(buf));
-	buf[0] = baddr;
-	buf[1] = bdata;
-	rc = mt9p012_i2c_txdata(saddr, buf, 2);
-
-	if (rc < 0)
-		CDBG("i2c_write failed, saddr = 0x%x addr = 0x%x, val =0x%x!\n",
-		     saddr, baddr, bdata);
-
-	return rc;
-}
-
-static int32_t mt9p012_i2c_write_w(unsigned short saddr, unsigned short waddr,
-				   unsigned short wdata)
-{
-	int32_t rc = -EIO;
-	unsigned char buf[4];
-
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (waddr & 0xFF00) >> 8;
-	buf[1] = (waddr & 0x00FF);
-	buf[2] = (wdata & 0xFF00) >> 8;
-	buf[3] = (wdata & 0x00FF);
-
-	rc = mt9p012_i2c_txdata(saddr, buf, 4);
-
-	if (rc < 0)
-		CDBG("i2c_write_w failed, addr = 0x%x, val = 0x%x!\n",
-		     waddr, wdata);
-
-	return rc;
-}
-
-static int32_t mt9p012_i2c_write_w_table(struct mt9p012_i2c_reg_conf const
-					 *reg_conf_tbl, int num)
-{
-	int i;
-	int32_t rc = -EIO;
-
-	for (i = 0; i < num; i++) {
-		rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-					 reg_conf_tbl->waddr,
-					 reg_conf_tbl->wdata);
-		if (rc < 0)
-			break;
-		reg_conf_tbl++;
-	}
-
-	return rc;
-}
-
-static int32_t mt9p012_test(enum mt9p012_test_mode mo)
-{
-	int32_t rc = 0;
-
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-				 REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_HOLD);
-	if (rc < 0)
-		return rc;
-
-	if (mo == TEST_OFF)
-		return 0;
-	else {
-		rc = mt9p012_i2c_write_w_table(mt9p012_regs.ttbl,
-					       mt9p012_regs.ttbl_size);
-		if (rc < 0)
-			return rc;
-
-		rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-					 REG_TEST_PATTERN_MODE, (uint16_t) mo);
-		if (rc < 0)
-			return rc;
-	}
-
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-				 REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_UPDATE);
-	if (rc < 0)
-		return rc;
-
-	return rc;
-}
-
-static int32_t mt9p012_lens_shading_enable(uint8_t is_enable)
-{
-	int32_t rc = 0;
-
-	CDBG("%s: entered. enable = %d\n", __func__, is_enable);
-
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-				 REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_HOLD);
-	if (rc < 0)
-		return rc;
-
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x3780,
-				 ((uint16_t) is_enable) << 15);
-	if (rc < 0)
-		return rc;
-
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-				 REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_UPDATE);
-
-	CDBG("%s: exiting. rc = %d\n", __func__, rc);
-	return rc;
-}
-
-static int32_t mt9p012_set_lc(void)
-{
-	int32_t rc;
-
-	rc = mt9p012_i2c_write_w_table(mt9p012_regs.rftbl,
-				       mt9p012_regs.rftbl_size);
-
-	return rc;
-}
-
-static void mt9p012_get_pict_fps(uint16_t fps, uint16_t *pfps)
-{
-	/* input fps is preview fps in Q8 format */
-	uint32_t divider;	/*Q10 */
-	uint32_t pclk_mult;	/*Q10 */
-	uint32_t d1;
-	uint32_t d2;
-
-	d1 =
-		(uint32_t)(
-		(mt9p012_regs.reg_pat[RES_PREVIEW].frame_length_lines *
-		0x00000400) /
-		mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines);
-
-	d2 =
-		(uint32_t)(
-		(mt9p012_regs.reg_pat[RES_PREVIEW].line_length_pck *
-		0x00000400) /
-		mt9p012_regs.reg_pat[RES_CAPTURE].line_length_pck);
-
-	divider = (uint32_t) (d1 * d2) / 0x00000400;
-
-	pclk_mult =
-		(uint32_t) ((mt9p012_regs.reg_pat[RES_CAPTURE].pll_multiplier *
-		0x00000400) /
-		(mt9p012_regs.reg_pat[RES_PREVIEW].pll_multiplier));
-
-	/* Verify PCLK settings and frame sizes. */
-	*pfps = (uint16_t) (fps * divider * pclk_mult / 0x00000400 /
-			    0x00000400);
-}
-
-static uint16_t mt9p012_get_prev_lines_pf(void)
-{
-	if (mt9p012_ctrl->prev_res == QTR_SIZE)
-		return mt9p012_regs.reg_pat[RES_PREVIEW].frame_length_lines;
-	else
-		return mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines;
-}
-
-static uint16_t mt9p012_get_prev_pixels_pl(void)
-{
-	if (mt9p012_ctrl->prev_res == QTR_SIZE)
-		return mt9p012_regs.reg_pat[RES_PREVIEW].line_length_pck;
-	else
-		return mt9p012_regs.reg_pat[RES_CAPTURE].line_length_pck;
-}
-
-static uint16_t mt9p012_get_pict_lines_pf(void)
-{
-	return mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines;
-}
-
-static uint16_t mt9p012_get_pict_pixels_pl(void)
-{
-	return mt9p012_regs.reg_pat[RES_CAPTURE].line_length_pck;
-}
-
-static uint32_t mt9p012_get_pict_max_exp_lc(void)
-{
-	uint16_t snapshot_lines_per_frame;
-
-	if (mt9p012_ctrl->pict_res == QTR_SIZE)
-		snapshot_lines_per_frame =
-		    mt9p012_regs.reg_pat[RES_PREVIEW].frame_length_lines - 1;
-	else
-		snapshot_lines_per_frame =
-		    mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines - 1;
-
-	return snapshot_lines_per_frame * 24;
-}
-
-static int32_t mt9p012_set_fps(struct fps_cfg *fps)
-{
-	/* input is new fps in Q10 format */
-	int32_t rc = 0;
-	enum mt9p012_setting setting;
-
-	mt9p012_ctrl->fps_divider = fps->fps_div;
-	mt9p012_ctrl->pict_fps_divider = fps->pict_fps_div;
-
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-				 REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_HOLD);
-	if (rc < 0)
-		return -EBUSY;
-
-	if (mt9p012_ctrl->sensormode == SENSOR_PREVIEW_MODE)
-		setting = RES_PREVIEW;
-	else
-		setting = RES_CAPTURE;
-
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-		REG_FRAME_LENGTH_LINES,
-		(mt9p012_regs.reg_pat[setting].frame_length_lines *
-		fps->fps_div / 0x00000400));
-	if (rc < 0)
-		return rc;
-
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-				 REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_UPDATE);
-
-	return rc;
-}
-
-static int32_t mt9p012_write_exp_gain(uint16_t gain, uint32_t line)
-{
-	uint16_t max_legal_gain = 0x01FF;
-	uint32_t line_length_ratio = 0x00000400;
-	enum mt9p012_setting setting;
-	int32_t rc = 0;
-
-	CDBG("Line:%d mt9p012_write_exp_gain \n", __LINE__);
-
-	if (mt9p012_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
-		mt9p012_ctrl->my_reg_gain = gain;
-		mt9p012_ctrl->my_reg_line_count = (uint16_t) line;
-	}
-
-	if (gain > max_legal_gain) {
-		CDBG("Max legal gain Line:%d \n", __LINE__);
-		gain = max_legal_gain;
-	}
-
-	/* Verify no overflow */
-	if (mt9p012_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
-		line = (uint32_t) (line * mt9p012_ctrl->fps_divider /
-				   0x00000400);
-		setting = RES_PREVIEW;
-	} else {
-		line = (uint32_t) (line * mt9p012_ctrl->pict_fps_divider /
-				   0x00000400);
-		setting = RES_CAPTURE;
-	}
-
-	/* Set digital gain to 1 */
-#ifdef MT9P012_REV_7
-	gain |= 0x1000;
-#else
-	gain |= 0x0200;
-#endif
-
-	if ((mt9p012_regs.reg_pat[setting].frame_length_lines - 1) < line) {
-		line_length_ratio = (uint32_t) (line * 0x00000400) /
-		    (mt9p012_regs.reg_pat[setting].frame_length_lines - 1);
-	} else
-		line_length_ratio = 0x00000400;
-
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr, REG_GLOBAL_GAIN, gain);
-	if (rc < 0) {
-		CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__);
-		return rc;
-	}
-
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-				 REG_COARSE_INT_TIME, line);
-	if (rc < 0) {
-		CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__);
-		return rc;
-	}
-
-	CDBG("mt9p012_write_exp_gain: gain = %d, line = %d\n", gain, line);
-
-	return rc;
-}
-
-static int32_t mt9p012_set_pict_exp_gain(uint16_t gain, uint32_t line)
-{
-	int32_t rc = 0;
-
-	CDBG("Line:%d mt9p012_set_pict_exp_gain \n", __LINE__);
-
-	rc = mt9p012_write_exp_gain(gain, line);
-	if (rc < 0) {
-		CDBG("Line:%d mt9p012_set_pict_exp_gain failed... \n",
-		     __LINE__);
-		return rc;
-	}
-
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-				 MT9P012_REG_RESET_REGISTER, 0x10CC | 0x0002);
-	if (rc < 0) {
-		CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__);
-		return rc;
-	}
-
-	mdelay(5);
-
-	/* camera_timed_wait(snapshot_wait*exposure_ratio); */
-	return rc;
-}
-
-static int32_t mt9p012_setting(enum mt9p012_reg_update rupdate,
-			       enum mt9p012_setting rt)
-{
-	int32_t rc = 0;
-	switch (rupdate) {
-	case UPDATE_PERIODIC:
-		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
-			struct mt9p012_i2c_reg_conf ppc_tbl[] = {
-				{REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_HOLD},
-				{REG_ROW_SPEED,
-				 mt9p012_regs.reg_pat[rt].row_speed},
-				{REG_X_ADDR_START,
-				 mt9p012_regs.reg_pat[rt].x_addr_start},
-				{REG_X_ADDR_END,
-				 mt9p012_regs.reg_pat[rt].x_addr_end},
-				{REG_Y_ADDR_START,
-				 mt9p012_regs.reg_pat[rt].y_addr_start},
-				{REG_Y_ADDR_END,
-				 mt9p012_regs.reg_pat[rt].y_addr_end},
-				{REG_READ_MODE,
-				 mt9p012_regs.reg_pat[rt].read_mode},
-				{REG_SCALE_M, mt9p012_regs.reg_pat[rt].scale_m},
-				{REG_X_OUTPUT_SIZE,
-				 mt9p012_regs.reg_pat[rt].x_output_size},
-				{REG_Y_OUTPUT_SIZE,
-				 mt9p012_regs.reg_pat[rt].y_output_size},
-
-				{REG_LINE_LENGTH_PCK,
-				 mt9p012_regs.reg_pat[rt].line_length_pck},
-				{REG_FRAME_LENGTH_LINES,
-				 (mt9p012_regs.reg_pat[rt].frame_length_lines *
-				  mt9p012_ctrl->fps_divider / 0x00000400)},
-				{REG_COARSE_INT_TIME,
-				 mt9p012_regs.reg_pat[rt].coarse_int_time},
-				{REG_FINE_INTEGRATION_TIME,
-				 mt9p012_regs.reg_pat[rt].fine_int_time},
-				{REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_UPDATE},
-			};
-			if (update_type == REG_INIT) {
-				update_type = rupdate;
-				return rc;
-			}
-			rc = mt9p012_i2c_write_w_table(&ppc_tbl[0],
-						ARRAY_SIZE(ppc_tbl));
-			if (rc < 0)
-				return rc;
-
-			rc = mt9p012_test(mt9p012_ctrl->set_test);
-			if (rc < 0)
-				return rc;
-
-			rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-						 MT9P012_REG_RESET_REGISTER,
-						 MT9P012_RESET_REGISTER_PWON |
-						 0x0002);
-			if (rc < 0)
-				return rc;
-
-			mdelay(5);	/* 15? wait for sensor to transition */
-
-			return rc;
-		}
-		break;		/* UPDATE_PERIODIC */
-
-	case REG_INIT:
-		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
-			struct mt9p012_i2c_reg_conf ipc_tbl1[] = {
-				{MT9P012_REG_RESET_REGISTER,
-				 MT9P012_RESET_REGISTER_PWOFF},
-				{REG_VT_PIX_CLK_DIV,
-				 mt9p012_regs.reg_pat[rt].vt_pix_clk_div},
-				{REG_VT_SYS_CLK_DIV,
-				 mt9p012_regs.reg_pat[rt].vt_sys_clk_div},
-				{REG_PRE_PLL_CLK_DIV,
-				 mt9p012_regs.reg_pat[rt].pre_pll_clk_div},
-				{REG_PLL_MULTIPLIER,
-				 mt9p012_regs.reg_pat[rt].pll_multiplier},
-				{REG_OP_PIX_CLK_DIV,
-				 mt9p012_regs.reg_pat[rt].op_pix_clk_div},
-				{REG_OP_SYS_CLK_DIV,
-				 mt9p012_regs.reg_pat[rt].op_sys_clk_div},
-#ifdef MT9P012_REV_7
-				{0x30B0, 0x0001},
-				{0x308E, 0xE060},
-				{0x3092, 0x0A52},
-				{0x3094, 0x4656},
-				{0x3096, 0x5652},
-				{0x30CA, 0x8006},
-				{0x312A, 0xDD02},
-				{0x312C, 0x00E4},
-				{0x3170, 0x299A},
-#endif
-				/* optimized settings for noise */
-				{0x3088, 0x6FF6},
-				{0x3154, 0x0282},
-				{0x3156, 0x0381},
-				{0x3162, 0x04CE},
-				{0x0204, 0x0010},
-				{0x0206, 0x0010},
-				{0x0208, 0x0010},
-				{0x020A, 0x0010},
-				{0x020C, 0x0010},
-				{MT9P012_REG_RESET_REGISTER,
-				 MT9P012_RESET_REGISTER_PWON},
-			};
-
-			struct mt9p012_i2c_reg_conf ipc_tbl2[] = {
-				{MT9P012_REG_RESET_REGISTER,
-				 MT9P012_RESET_REGISTER_PWOFF},
-				{REG_VT_PIX_CLK_DIV,
-				 mt9p012_regs.reg_pat[rt].vt_pix_clk_div},
-				{REG_VT_SYS_CLK_DIV,
-				 mt9p012_regs.reg_pat[rt].vt_sys_clk_div},
-				{REG_PRE_PLL_CLK_DIV,
-				 mt9p012_regs.reg_pat[rt].pre_pll_clk_div},
-				{REG_PLL_MULTIPLIER,
-				 mt9p012_regs.reg_pat[rt].pll_multiplier},
-				{REG_OP_PIX_CLK_DIV,
-				 mt9p012_regs.reg_pat[rt].op_pix_clk_div},
-				{REG_OP_SYS_CLK_DIV,
-				 mt9p012_regs.reg_pat[rt].op_sys_clk_div},
-#ifdef MT9P012_REV_7
-				{0x30B0, 0x0001},
-				{0x308E, 0xE060},
-				{0x3092, 0x0A52},
-				{0x3094, 0x4656},
-				{0x3096, 0x5652},
-				{0x30CA, 0x8006},
-				{0x312A, 0xDD02},
-				{0x312C, 0x00E4},
-				{0x3170, 0x299A},
-#endif
-				/* optimized settings for noise */
-				{0x3088, 0x6FF6},
-				{0x3154, 0x0282},
-				{0x3156, 0x0381},
-				{0x3162, 0x04CE},
-				{0x0204, 0x0010},
-				{0x0206, 0x0010},
-				{0x0208, 0x0010},
-				{0x020A, 0x0010},
-				{0x020C, 0x0010},
-				{MT9P012_REG_RESET_REGISTER,
-				 MT9P012_RESET_REGISTER_PWON},
-			};
-
-			struct mt9p012_i2c_reg_conf ipc_tbl3[] = {
-				{REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_HOLD},
-				/* Set preview or snapshot mode */
-				{REG_ROW_SPEED,
-				 mt9p012_regs.reg_pat[rt].row_speed},
-				{REG_X_ADDR_START,
-				 mt9p012_regs.reg_pat[rt].x_addr_start},
-				{REG_X_ADDR_END,
-				 mt9p012_regs.reg_pat[rt].x_addr_end},
-				{REG_Y_ADDR_START,
-				 mt9p012_regs.reg_pat[rt].y_addr_start},
-				{REG_Y_ADDR_END,
-				 mt9p012_regs.reg_pat[rt].y_addr_end},
-				{REG_READ_MODE,
-				 mt9p012_regs.reg_pat[rt].read_mode},
-				{REG_SCALE_M, mt9p012_regs.reg_pat[rt].scale_m},
-				{REG_X_OUTPUT_SIZE,
-				 mt9p012_regs.reg_pat[rt].x_output_size},
-				{REG_Y_OUTPUT_SIZE,
-				 mt9p012_regs.reg_pat[rt].y_output_size},
-				{REG_LINE_LENGTH_PCK,
-				 mt9p012_regs.reg_pat[rt].line_length_pck},
-				{REG_FRAME_LENGTH_LINES,
-				 mt9p012_regs.reg_pat[rt].frame_length_lines},
-				{REG_COARSE_INT_TIME,
-				 mt9p012_regs.reg_pat[rt].coarse_int_time},
-				{REG_FINE_INTEGRATION_TIME,
-				 mt9p012_regs.reg_pat[rt].fine_int_time},
-				{REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_UPDATE},
-			};
-
-			/* reset fps_divider */
-			mt9p012_ctrl->fps_divider = 1 * 0x0400;
-
-			rc = mt9p012_i2c_write_w_table(&ipc_tbl1[0],
-						       ARRAY_SIZE(ipc_tbl1));
-			if (rc < 0)
-				return rc;
-
-			rc = mt9p012_i2c_write_w_table(&ipc_tbl2[0],
-						       ARRAY_SIZE(ipc_tbl2));
-			if (rc < 0)
-				return rc;
-
-			mdelay(5);
-
-			rc = mt9p012_i2c_write_w_table(&ipc_tbl3[0],
-						       ARRAY_SIZE(ipc_tbl3));
-			if (rc < 0)
-				return rc;
-
-			/* load lens shading */
-			rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-						 REG_GROUPED_PARAMETER_HOLD,
-						 GROUPED_PARAMETER_HOLD);
-			if (rc < 0)
-				return rc;
-
-			rc = mt9p012_set_lc();
-			if (rc < 0)
-				return rc;
-
-			rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-						 REG_GROUPED_PARAMETER_HOLD,
-						 GROUPED_PARAMETER_UPDATE);
-
-			if (rc < 0)
-				return rc;
-		}
-		update_type = rupdate;
-		break;		/* case REG_INIT: */
-
-	default:
-		rc = -EINVAL;
-		break;
-	}			/* switch (rupdate) */
-
-	return rc;
-}
-
-static int32_t mt9p012_video_config(int mode, int res)
-{
-	int32_t rc;
-
-	switch (res) {
-	case QTR_SIZE:
-		rc = mt9p012_setting(UPDATE_PERIODIC, RES_PREVIEW);
-		if (rc < 0)
-			return rc;
-
-		CDBG("mt9p012 sensor configuration done!\n");
-		break;
-
-	case FULL_SIZE:
-		rc = mt9p012_setting(UPDATE_PERIODIC, RES_CAPTURE);
-		if (rc < 0)
-			return rc;
-
-		break;
-
-	default:
-		return 0;
-	}			/* switch */
-
-	mt9p012_ctrl->prev_res = res;
-	mt9p012_ctrl->curr_res = res;
-	mt9p012_ctrl->sensormode = mode;
-
-	rc = mt9p012_write_exp_gain(mt9p012_ctrl->my_reg_gain,
-				    mt9p012_ctrl->my_reg_line_count);
-
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-				 MT9P012_REG_RESET_REGISTER, 0x10cc | 0x0002);
-
-	return rc;
-}
-
-static int32_t mt9p012_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-
-	rc = mt9p012_setting(UPDATE_PERIODIC, RES_CAPTURE);
-	if (rc < 0)
-		return rc;
-
-	mt9p012_ctrl->curr_res = mt9p012_ctrl->pict_res;
-
-	mt9p012_ctrl->sensormode = mode;
-
-	return rc;
-}
-
-static int32_t mt9p012_raw_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-
-	rc = mt9p012_setting(UPDATE_PERIODIC, RES_CAPTURE);
-	if (rc < 0)
-		return rc;
-
-	mt9p012_ctrl->curr_res = mt9p012_ctrl->pict_res;
-
-	mt9p012_ctrl->sensormode = mode;
-
-	return rc;
-}
-
-static int32_t mt9p012_power_down(void)
-{
-	int32_t rc = 0;
-
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-				 MT9P012_REG_RESET_REGISTER,
-				 MT9P012_RESET_REGISTER_PWOFF);
-
-	mdelay(5);
-	return rc;
-}
-
-static int32_t mt9p012_move_focus(int direction, int32_t num_steps)
-{
-	int16_t step_direction;
-	int16_t actual_step;
-	int16_t next_position;
-	uint8_t code_val_msb, code_val_lsb;
-
-	if (num_steps > MT9P012_TOTAL_STEPS_NEAR_TO_FAR)
-		num_steps = MT9P012_TOTAL_STEPS_NEAR_TO_FAR;
-	else if (num_steps == 0) {
-		CDBG("mt9p012_move_focus failed at line %d ...\n", __LINE__);
-		return -EINVAL;
-	}
-
-	if (direction == MOVE_NEAR)
-		step_direction = 16;	/* 10bit */
-	else if (direction == MOVE_FAR)
-		step_direction = -16;	/* 10 bit */
-	else {
-		CDBG("mt9p012_move_focus failed at line %d ...\n", __LINE__);
-		return -EINVAL;
-	}
-
-	if (mt9p012_ctrl->curr_lens_pos < mt9p012_ctrl->init_curr_lens_pos)
-		mt9p012_ctrl->curr_lens_pos = mt9p012_ctrl->init_curr_lens_pos;
-
-	actual_step = (int16_t) (step_direction * (int16_t) num_steps);
-	next_position = (int16_t) (mt9p012_ctrl->curr_lens_pos + actual_step);
-
-	if (next_position > 1023)
-		next_position = 1023;
-	else if (next_position < 0)
-		next_position = 0;
-
-	code_val_msb = next_position >> 4;
-	code_val_lsb = (next_position & 0x000F) << 4;
-	/* code_val_lsb |= mode_mask; */
-
-	/* Writing the digital code for current to the actuator */
-	if (mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1,
-				code_val_msb, code_val_lsb) < 0) {
-		CDBG("mt9p012_move_focus failed at line %d ...\n", __LINE__);
-		return -EBUSY;
-	}
-
-	/* Storing the current lens Position */
-	mt9p012_ctrl->curr_lens_pos = next_position;
-
-	return 0;
-}
-
-static int32_t mt9p012_set_default_focus(void)
-{
-	int32_t rc = 0;
-	uint8_t code_val_msb, code_val_lsb;
-
-	code_val_msb = 0x00;
-	code_val_lsb = 0x00;
-
-	/* Write the digital code for current to the actuator */
-	rc = mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1,
-				 code_val_msb, code_val_lsb);
-
-	mt9p012_ctrl->curr_lens_pos = 0;
-	mt9p012_ctrl->init_curr_lens_pos = 0;
-
-	return rc;
-}
-
-static int mt9p012_probe_init_done(const struct msm_camera_sensor_info *data)
-{
-	gpio_direction_output(data->sensor_reset, 0);
-	gpio_free(data->sensor_reset);
-	return 0;
-}
-
-static int mt9p012_probe_init_sensor(const struct msm_camera_sensor_info *data)
-{
-	int32_t rc;
-	uint16_t chipid;
-
-	rc = gpio_request(data->sensor_reset, "mt9p012");
-	if (!rc)
-		gpio_direction_output(data->sensor_reset, 1);
-	else
-		goto init_probe_done;
-
-	msleep(20);
-
-	/* RESET the sensor image part via I2C command */
-	CDBG("mt9p012_sensor_init(): reseting sensor.\n");
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-				 MT9P012_REG_RESET_REGISTER, 0x10CC | 0x0001);
-	if (rc < 0) {
-		CDBG("sensor reset failed. rc = %d\n", rc);
-		goto init_probe_fail;
-	}
-
-	msleep(MT9P012_RESET_DELAY_MSECS);
-
-	/* 3. Read sensor Model ID: */
-	rc = mt9p012_i2c_read_w(mt9p012_client->addr,
-				MT9P012_REG_MODEL_ID, &chipid);
-	if (rc < 0)
-		goto init_probe_fail;
-
-	/* 4. Compare sensor ID to MT9T012VC ID: */
-	if (chipid != MT9P012_MODEL_ID) {
-		CDBG("mt9p012 wrong model_id = 0x%x\n", chipid);
-		rc = -ENODEV;
-		goto init_probe_fail;
-	}
-
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x306E, 0x9000);
-	if (rc < 0) {
-		CDBG("REV_7 write failed. rc = %d\n", rc);
-		goto init_probe_fail;
-	}
-
-	/* RESET_REGISTER, enable parallel interface and disable serialiser */
-	CDBG("mt9p012_sensor_init(): enabling parallel interface.\n");
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x301A, 0x10CC);
-	if (rc < 0) {
-		CDBG("enable parallel interface failed. rc = %d\n", rc);
-		goto init_probe_fail;
-	}
-
-	/* To disable the 2 extra lines */
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x3064, 0x0805);
-
-	if (rc < 0) {
-		CDBG("disable the 2 extra lines failed. rc = %d\n", rc);
-		goto init_probe_fail;
-	}
-	goto init_probe_done;
-
-init_probe_fail:
-	mt9p012_probe_init_done(data);
-init_probe_done:
-	return rc;
-}
-
-static int mt9p012_sensor_open_init(const struct msm_camera_sensor_info *data)
-{
-	int32_t rc;
-
-	mt9p012_ctrl = kzalloc(sizeof(struct mt9p012_ctrl), GFP_KERNEL);
-	if (!mt9p012_ctrl) {
-		CDBG("mt9p012_init failed!\n");
-		rc = -ENOMEM;
-		goto init_done;
-	}
-
-	mt9p012_ctrl->fps_divider = 1 * 0x00000400;
-	mt9p012_ctrl->pict_fps_divider = 1 * 0x00000400;
-	mt9p012_ctrl->set_test = TEST_OFF;
-	mt9p012_ctrl->prev_res = QTR_SIZE;
-	mt9p012_ctrl->pict_res = FULL_SIZE;
-
-	if (data)
-		mt9p012_ctrl->sensordata = data;
-
-	msm_camio_camif_pad_reg_reset();
-	mdelay(20);
-
-	rc = mt9p012_probe_init_sensor(data);
-	if (rc < 0)
-		goto init_fail1;
-
-	if (mt9p012_ctrl->prev_res == QTR_SIZE)
-		rc = mt9p012_setting(REG_INIT, RES_PREVIEW);
-	else
-		rc = mt9p012_setting(REG_INIT, RES_CAPTURE);
-
-	if (rc < 0) {
-		CDBG("mt9p012_setting failed. rc = %d\n", rc);
-		goto init_fail1;
-	}
-
-	/* sensor : output enable */
-	CDBG("mt9p012_sensor_open_init(): enabling output.\n");
-	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-				 MT9P012_REG_RESET_REGISTER,
-				 MT9P012_RESET_REGISTER_PWON);
-	if (rc < 0) {
-		CDBG("sensor output enable failed. rc = %d\n", rc);
-		goto init_fail1;
-	}
-
-	/* enable AF actuator */
-	if (mt9p012_ctrl->sensordata->vcm_enable) {
-		CDBG("enable AF actuator, gpio = %d\n",
-			 mt9p012_ctrl->sensordata->vcm_pwd);
-		rc = gpio_request(mt9p012_ctrl->sensordata->vcm_pwd,
-						"mt9p012");
-		if (!rc)
-			gpio_direction_output(
-				mt9p012_ctrl->sensordata->vcm_pwd,
-				 1);
-		else {
-			CDBG("mt9p012_ctrl gpio request failed!\n");
-			goto init_fail1;
-		}
-		msleep(20);
-		rc = mt9p012_set_default_focus();
-		if (rc < 0) {
-			gpio_direction_output(mt9p012_ctrl->sensordata->vcm_pwd,
-								0);
-			gpio_free(mt9p012_ctrl->sensordata->vcm_pwd);
-		}
-	}
-	if (rc >= 0)
-		goto init_done;
-init_fail1:
-	mt9p012_probe_init_done(data);
-	kfree(mt9p012_ctrl);
-init_done:
-	return rc;
-}
-
-static int mt9p012_init_client(struct i2c_client *client)
-{
-	/* Initialize the MSM_CAMI2C Chip */
-	init_waitqueue_head(&mt9p012_wait_queue);
-	return 0;
-}
-
-static int32_t mt9p012_set_sensor_mode(int mode, int res)
-{
-	int32_t rc = 0;
-
-	switch (mode) {
-	case SENSOR_PREVIEW_MODE:
-		rc = mt9p012_video_config(mode, res);
-		break;
-
-	case SENSOR_SNAPSHOT_MODE:
-		rc = mt9p012_snapshot_config(mode);
-		break;
-
-	case SENSOR_RAW_SNAPSHOT_MODE:
-		rc = mt9p012_raw_snapshot_config(mode);
-		break;
-
-	default:
-		rc = -EINVAL;
-		break;
-	}
-
-	return rc;
-}
-
-int mt9p012_sensor_config(void __user *argp)
-{
-	struct sensor_cfg_data cdata;
-	int rc = 0;
-
-	if (copy_from_user(&cdata,
-			   (void *)argp, sizeof(struct sensor_cfg_data)))
-		return -EFAULT;
-
-	mutex_lock(&mt9p012_mut);
-
-	CDBG("%s: cfgtype = %d\n", __func__, cdata.cfgtype);
-	switch (cdata.cfgtype) {
-	case CFG_GET_PICT_FPS:
-		mt9p012_get_pict_fps(cdata.cfg.gfps.prevfps,
-				     &(cdata.cfg.gfps.pictfps));
-
-		if (copy_to_user((void *)argp, &cdata,
-				 sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PREV_L_PF:
-		cdata.cfg.prevl_pf = mt9p012_get_prev_lines_pf();
-
-		if (copy_to_user((void *)argp,
-				 &cdata, sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PREV_P_PL:
-		cdata.cfg.prevp_pl = mt9p012_get_prev_pixels_pl();
-
-		if (copy_to_user((void *)argp,
-				 &cdata, sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PICT_L_PF:
-		cdata.cfg.pictl_pf = mt9p012_get_pict_lines_pf();
-
-		if (copy_to_user((void *)argp,
-				 &cdata, sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PICT_P_PL:
-		cdata.cfg.pictp_pl = mt9p012_get_pict_pixels_pl();
-
-		if (copy_to_user((void *)argp,
-				 &cdata, sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PICT_MAX_EXP_LC:
-		cdata.cfg.pict_max_exp_lc = mt9p012_get_pict_max_exp_lc();
-
-		if (copy_to_user((void *)argp,
-				 &cdata, sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_SET_FPS:
-	case CFG_SET_PICT_FPS:
-		rc = mt9p012_set_fps(&(cdata.cfg.fps));
-		break;
-
-	case CFG_SET_EXP_GAIN:
-		rc = mt9p012_write_exp_gain(cdata.cfg.exp_gain.gain,
-					    cdata.cfg.exp_gain.line);
-		break;
-
-	case CFG_SET_PICT_EXP_GAIN:
-		CDBG("Line:%d CFG_SET_PICT_EXP_GAIN \n", __LINE__);
-		rc = mt9p012_set_pict_exp_gain(cdata.cfg.exp_gain.gain,
-					       cdata.cfg.exp_gain.line);
-		break;
-
-	case CFG_SET_MODE:
-		rc = mt9p012_set_sensor_mode(cdata.mode, cdata.rs);
-		break;
-
-	case CFG_PWR_DOWN:
-		rc = mt9p012_power_down();
-		break;
-
-	case CFG_MOVE_FOCUS:
-		CDBG("mt9p012_ioctl: CFG_MOVE_FOCUS: cdata.cfg.focus.dir=%d \
-				cdata.cfg.focus.steps=%d\n",
-				cdata.cfg.focus.dir, cdata.cfg.focus.steps);
-		rc = mt9p012_move_focus(cdata.cfg.focus.dir,
-					cdata.cfg.focus.steps);
-		break;
-
-	case CFG_SET_DEFAULT_FOCUS:
-		rc = mt9p012_set_default_focus();
-		break;
-
-	case CFG_SET_LENS_SHADING:
-		CDBG("%s: CFG_SET_LENS_SHADING\n", __func__);
-		rc = mt9p012_lens_shading_enable(cdata.cfg.lens_shading);
-		break;
-
-	case CFG_GET_AF_MAX_STEPS:
-		cdata.max_steps = MT9P012_STEPS_NEAR_TO_CLOSEST_INF;
-		if (copy_to_user((void *)argp,
-				 &cdata, sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_SET_EFFECT:
-	default:
-		rc = -EINVAL;
-		break;
-	}
-
-	mutex_unlock(&mt9p012_mut);
-	return rc;
-}
-
-int mt9p012_sensor_release(void)
-{
-	int rc = -EBADF;
-
-	mutex_lock(&mt9p012_mut);
-
-	mt9p012_power_down();
-
-	gpio_direction_output(mt9p012_ctrl->sensordata->sensor_reset, 0);
-	gpio_free(mt9p012_ctrl->sensordata->sensor_reset);
-
-	if (mt9p012_ctrl->sensordata->vcm_enable) {
-		gpio_direction_output(mt9p012_ctrl->sensordata->vcm_pwd, 0);
-		gpio_free(mt9p012_ctrl->sensordata->vcm_pwd);
-	}
-
-	kfree(mt9p012_ctrl);
-	mt9p012_ctrl = NULL;
-
-	CDBG("mt9p012_release completed\n");
-
-	mutex_unlock(&mt9p012_mut);
-	return rc;
-}
-
-static int mt9p012_i2c_probe(struct i2c_client *client,
-			     const struct i2c_device_id *id)
-{
-	int rc = 0;
-	CDBG("mt9p012_probe called!\n");
-
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		CDBG("i2c_check_functionality failed\n");
-		goto probe_failure;
-	}
-
-	mt9p012_sensorw = kzalloc(sizeof(struct mt9p012_work), GFP_KERNEL);
-	if (!mt9p012_sensorw) {
-		CDBG("kzalloc failed.\n");
-		rc = -ENOMEM;
-		goto probe_failure;
-	}
-
-	i2c_set_clientdata(client, mt9p012_sensorw);
-	mt9p012_init_client(client);
-	mt9p012_client = client;
-
-	mdelay(50);
-
-	CDBG("mt9p012_probe successed! rc = %d\n", rc);
-	return 0;
-
-probe_failure:
-	CDBG("mt9p012_probe failed! rc = %d\n", rc);
-	return rc;
-}
-
-static const struct i2c_device_id mt9p012_i2c_id[] = {
-	{"mt9p012", 0},
-	{}
-};
-
-static struct i2c_driver mt9p012_i2c_driver = {
-	.id_table = mt9p012_i2c_id,
-	.probe = mt9p012_i2c_probe,
-	.remove = __exit_p(mt9p012_i2c_remove),
-	.driver = {
-		   .name = "mt9p012",
-		   },
-};
-
-static int mt9p012_sensor_probe(const struct msm_camera_sensor_info *info,
-				struct msm_sensor_ctrl *s)
-{
-	int rc = i2c_add_driver(&mt9p012_i2c_driver);
-	if (rc < 0 || mt9p012_client == NULL) {
-		rc = -ENOTSUPP;
-		goto probe_done;
-	}
-
-	msm_camio_clk_rate_set(MT9P012_DEFAULT_CLOCK_RATE);
-	mdelay(20);
-
-	rc = mt9p012_probe_init_sensor(info);
-	if (rc < 0)
-		goto probe_done;
-
-	s->s_init = mt9p012_sensor_open_init;
-	s->s_release = mt9p012_sensor_release;
-	s->s_config = mt9p012_sensor_config;
-	s->s_mount_angle  = 0;
-	mt9p012_probe_init_done(info);
-
-probe_done:
-	CDBG("%s %s:%d\n", __FILE__, __func__, __LINE__);
-	return rc;
-}
-
-static int __mt9p012_probe(struct platform_device *pdev)
-{
-	return msm_camera_drv_start(pdev, mt9p012_sensor_probe);
-}
-
-static struct platform_driver msm_camera_driver = {
-	.probe = __mt9p012_probe,
-	.driver = {
-		   .name = "msm_camera_mt9p012",
-		   .owner = THIS_MODULE,
-		   },
-};
-
-static int __init mt9p012_init(void)
-{
-	return platform_driver_register(&msm_camera_driver);
-}
-
-module_init(mt9p012_init);
diff --git a/drivers/media/video/msm/mt9p012_km.c b/drivers/media/video/msm/mt9p012_km.c
deleted file mode 100644
index 5ba0e62..0000000
--- a/drivers/media/video/msm/mt9p012_km.c
+++ /dev/null
@@ -1,1296 +0,0 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. 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/slab.h>
-#include <linux/delay.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/kernel.h>
-#include <media/msm_camera.h>
-#include <mach/gpio.h>
-#include <mach/camera.h>
-#include "mt9p012_km.h"
-
-/*=============================================================
-    SENSOR REGISTER DEFINES
-==============================================================*/
-
-#define MT9P012_KM_REG_MODEL_ID      0x0000
-#define MT9P012_KM_MODEL_ID          0x2800
-#define REG_GROUPED_PARAMETER_HOLD   0x0104
-#define GROUPED_PARAMETER_HOLD       0x0100
-#define GROUPED_PARAMETER_UPDATE     0x0000
-#define REG_COARSE_INT_TIME          0x3012
-#define REG_VT_PIX_CLK_DIV           0x0300
-#define REG_VT_SYS_CLK_DIV           0x0302
-#define REG_PRE_PLL_CLK_DIV          0x0304
-#define REG_PLL_MULTIPLIER           0x0306
-#define REG_OP_PIX_CLK_DIV           0x0308
-#define REG_OP_SYS_CLK_DIV           0x030A
-#define REG_SCALE_M                  0x0404
-#define REG_FRAME_LENGTH_LINES       0x300A
-#define REG_LINE_LENGTH_PCK          0x300C
-#define REG_X_ADDR_START             0x3004
-#define REG_Y_ADDR_START             0x3002
-#define REG_X_ADDR_END               0x3008
-#define REG_Y_ADDR_END               0x3006
-#define REG_X_OUTPUT_SIZE            0x034C
-#define REG_Y_OUTPUT_SIZE            0x034E
-#define REG_FINE_INTEGRATION_TIME    0x3014
-#define REG_ROW_SPEED                0x3016
-#define MT9P012_KM_REG_RESET_REGISTER   0x301A
-#define MT9P012_KM_RESET_REGISTER_PWON  0x10CC
-#define MT9P012_KM_RESET_REGISTER_PWOFF 0x10C8
-#define REG_READ_MODE                0x3040
-#define REG_GLOBAL_GAIN              0x305E
-#define REG_TEST_PATTERN_MODE        0x3070
-
-enum mt9p012_km_test_mode {
-	TEST_OFF,
-	TEST_1,
-	TEST_2,
-	TEST_3
-};
-
-enum mt9p012_km_resolution {
-	QTR_SIZE,
-	FULL_SIZE,
-	INVALID_SIZE
-};
-
-enum mt9p012_km_reg_update {
-	/* Sensor egisters that need to be updated during initialization */
-	REG_INIT,
-	/* Sensor egisters that needs periodic I2C writes */
-	UPDATE_PERIODIC,
-	/* All the sensor Registers will be updated */
-	UPDATE_ALL,
-	/* Not valid update */
-	UPDATE_INVALID
-};
-
-enum mt9p012_km_setting {
-	RES_PREVIEW,
-	RES_CAPTURE
-};
-
-uint8_t mode_mask = 0x04;
-
-/* actuator's Slave Address */
-#define MT9P012_KM_AF_I2C_ADDR   (0x18 >> 1)
-
-/* AF Total steps parameters */
-#define MT9P012_KM_STEPS_NEAR_TO_CLOSEST_INF  30
-#define MT9P012_KM_TOTAL_STEPS_NEAR_TO_FAR    30
-
-/* Time in milisecs for waiting for the sensor to reset.*/
-#define MT9P012_KM_RESET_DELAY_MSECS   66
-
-/* for 20 fps preview */
-#define MT9P012_KM_DEFAULT_CLOCK_RATE  24000000
-
-struct mt9p012_km_work {
-	struct work_struct work;
-};
-static struct mt9p012_km_work *mt9p012_km_sensorw;
-static struct i2c_client *mt9p012_km_client;
-
-struct mt9p012_km_ctrl {
-	const struct msm_camera_sensor_info *sensordata;
-
-	int sensormode;
-	uint32_t fps_divider;	/* init to 1 * 0x00000400 */
-	uint32_t pict_fps_divider;	/* init to 1 * 0x00000400 */
-
-	uint16_t curr_lens_pos;
-	uint16_t init_curr_lens_pos;
-	uint16_t my_reg_gain;
-	uint32_t my_reg_line_count;
-
-	enum mt9p012_km_resolution prev_res;
-	enum mt9p012_km_resolution pict_res;
-	enum mt9p012_km_resolution curr_res;
-	enum mt9p012_km_test_mode set_test;
-};
-static uint16_t update_type = UPDATE_PERIODIC;
-static struct mt9p012_km_ctrl *mt9p012_km_ctrl;
-static DECLARE_WAIT_QUEUE_HEAD(mt9p012_km_wait_queue);
-DEFINE_MUTEX(mt9p012_km_mut);
-
-/*=============================================================*/
-
-static int mt9p012_km_i2c_rxdata(unsigned short saddr, unsigned char *rxdata,
-			int length)
-{
-	struct i2c_msg msgs[] = {
-		{
-			.addr = saddr << 1,
-			.flags = 0,
-			.len = 2,
-			.buf = rxdata,
-		},
-		{
-			.addr = saddr << 1,
-			.flags = I2C_M_RD,
-			.len = length,
-			.buf = rxdata,
-		},
-	};
-
-	if (i2c_transfer(mt9p012_km_client->adapter, msgs, 2) < 0) {
-		CDBG("mt9p012_km_i2c_rxdata failed!\n");
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int32_t mt9p012_km_i2c_read_w(unsigned short saddr, unsigned short raddr,
-				  unsigned short *rdata)
-{
-	int32_t rc = 0;
-	unsigned char buf[4];
-
-	if (!rdata)
-		return -EIO;
-
-	memset(buf, 0, sizeof(buf));
-
-	buf[0] = (raddr & 0xFF00) >> 8;
-	buf[1] = (raddr & 0x00FF);
-
-	rc = mt9p012_km_i2c_rxdata(saddr, buf, 2);
-	if (rc < 0)
-		return rc;
-
-	*rdata = buf[0] << 8 | buf[1];
-
-	if (rc < 0)
-		CDBG("mt9p012_km_i2c_read failed!\n");
-
-	return rc;
-}
-
-static int32_t mt9p012_km_i2c_txdata(unsigned short saddr,
-				  unsigned char *txdata,
-				  int length)
-{
-	struct i2c_msg msg[] = {
-		{
-		 .addr = saddr << 1,
-		 .flags = 0,
-		 .len = length,
-		 .buf = txdata,
-		 },
-	};
-
-	if (i2c_transfer(mt9p012_km_client->adapter, msg, 1) < 0) {
-		CDBG("mt9p012_km_i2c_txdata failed\n");
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int32_t mt9p012_km_i2c_write_b(unsigned short saddr,
-				   unsigned short baddr,
-				   unsigned short bdata)
-{
-	int32_t rc = -EIO;
-	unsigned char buf[2];
-
-	memset(buf, 0, sizeof(buf));
-	buf[0] = baddr;
-	buf[1] = bdata;
-	rc = mt9p012_km_i2c_txdata(saddr, buf, 2);
-
-	if (rc < 0)
-		CDBG("i2c_write failed, saddr = 0x%x addr = 0x%x, val =0x%x!\n",
-		     saddr, baddr, bdata);
-
-	return rc;
-}
-
-static int32_t mt9p012_km_i2c_write_w(unsigned short saddr,
-				   unsigned short waddr,
-				   unsigned short wdata)
-{
-	int32_t rc = -EIO;
-	unsigned char buf[4];
-
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (waddr & 0xFF00) >> 8;
-	buf[1] = (waddr & 0x00FF);
-	buf[2] = (wdata & 0xFF00) >> 8;
-	buf[3] = (wdata & 0x00FF);
-
-	rc = mt9p012_km_i2c_txdata(saddr, buf, 4);
-
-	if (rc < 0)
-		CDBG("i2c_write_w failed, addr = 0x%x, val = 0x%x!\n",
-		     waddr, wdata);
-
-	return rc;
-}
-
-static int32_t mt9p012_km_i2c_write_w_table(struct mt9p012_km_i2c_reg_conf const
-					 *reg_conf_tbl, int num)
-{
-	int i;
-	int32_t rc = -EIO;
-
-	for (i = 0; i < num; i++) {
-		rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
-					 reg_conf_tbl->waddr,
-					 reg_conf_tbl->wdata);
-		if (rc < 0)
-			break;
-		reg_conf_tbl++;
-	}
-
-	return rc;
-}
-
-static int32_t mt9p012_km_test(enum mt9p012_km_test_mode mo)
-{
-	int32_t rc = 0;
-
-	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
-				 REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_HOLD);
-	if (rc < 0)
-		return rc;
-
-	if (mo == TEST_OFF)
-		return 0;
-	else {
-		rc = mt9p012_km_i2c_write_w_table(mt9p012_km_regs.ttbl,
-					 mt9p012_km_regs.ttbl_size);
-		if (rc < 0)
-			return rc;
-
-		rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
-					 REG_TEST_PATTERN_MODE, (uint16_t) mo);
-		if (rc < 0)
-			return rc;
-	}
-
-	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
-				 REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_UPDATE);
-	if (rc < 0)
-		return rc;
-
-	return rc;
-}
-
-static int32_t mt9p012_km_lens_shading_enable(uint8_t is_enable)
-{
-	int32_t rc = 0;
-
-	CDBG("%s: entered. enable = %d\n", __func__, is_enable);
-
-	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
-				 REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_HOLD);
-	if (rc < 0)
-		return rc;
-
-	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr, 0x3780,
-				 ((uint16_t) is_enable) << 15);
-	if (rc < 0)
-		return rc;
-
-	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
-				 REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_UPDATE);
-
-	CDBG("%s: exiting. rc = %d\n", __func__, rc);
-	return rc;
-}
-
-static int32_t mt9p012_km_set_lc(void)
-{
-	int32_t rc;
-
-	rc = mt9p012_km_i2c_write_w_table(mt9p012_km_regs.lctbl,
-				       mt9p012_km_regs.lctbl_size);
-
-	return rc;
-}
-
-static void mt9p012_km_get_pict_fps(uint16_t fps, uint16_t *pfps)
-{
-
-	/* input fps is preview fps in Q8 format */
-	uint32_t divider;   /*Q10 */
-	uint32_t pclk_mult; /*Q10 */
-	uint32_t d1;
-	uint32_t d2;
-
-	d1 =
-		(uint32_t)(
-		(mt9p012_km_regs.reg_pat[RES_PREVIEW].frame_length_lines *
-		0x00000400) /
-		mt9p012_km_regs.reg_pat[RES_CAPTURE].frame_length_lines);
-
-	d2 =
-		(uint32_t)(
-		(mt9p012_km_regs.reg_pat[RES_PREVIEW].line_length_pck *
-		0x00000400) /
-		mt9p012_km_regs.reg_pat[RES_CAPTURE].line_length_pck);
-
-	divider = (uint32_t) (d1 * d2) / 0x00000400;
-
-	pclk_mult =
-		(uint32_t) ((mt9p012_km_regs.reg_pat[RES_CAPTURE].
-		pll_multiplier * 0x00000400) /
-		(mt9p012_km_regs.reg_pat[RES_PREVIEW].pll_multiplier));
-
-
-	/* Verify PCLK settings and frame sizes. */
-	*pfps = (uint16_t)((((fps * pclk_mult) / 0x00000400) * divider)/
-				0x00000400);
-}
-
-static uint16_t mt9p012_km_get_prev_lines_pf(void)
-{
-	if (mt9p012_km_ctrl->prev_res == QTR_SIZE)
-		return  mt9p012_km_regs.reg_pat[RES_PREVIEW].frame_length_lines;
-	else
-		return  mt9p012_km_regs.reg_pat[RES_CAPTURE].frame_length_lines;
-}
-
-static uint16_t mt9p012_km_get_prev_pixels_pl(void)
-{
-	if (mt9p012_km_ctrl->prev_res == QTR_SIZE)
-		return  mt9p012_km_regs.reg_pat[RES_PREVIEW].line_length_pck;
-	else
-		return  mt9p012_km_regs.reg_pat[RES_CAPTURE].line_length_pck;
-}
-
-static uint16_t mt9p012_km_get_pict_lines_pf(void)
-{
-	return  mt9p012_km_regs.reg_pat[RES_CAPTURE].frame_length_lines;
-}
-
-static uint16_t mt9p012_km_get_pict_pixels_pl(void)
-{
-	return  mt9p012_km_regs.reg_pat[RES_CAPTURE].line_length_pck;
-}
-
-static uint32_t mt9p012_km_get_pict_max_exp_lc(void)
-{
-	uint16_t snapshot_lines_per_frame;
-
-	if (mt9p012_km_ctrl->pict_res == QTR_SIZE)
-		snapshot_lines_per_frame =
-	    mt9p012_km_regs.reg_pat[RES_PREVIEW].frame_length_lines - 1;
-	else
-		snapshot_lines_per_frame =
-	    mt9p012_km_regs.reg_pat[RES_CAPTURE].frame_length_lines - 1;
-
-	return snapshot_lines_per_frame * 24;
-}
-
-static int32_t mt9p012_km_set_fps(struct fps_cfg *fps)
-{
-	int32_t rc = 0;
-
-	mt9p012_km_ctrl->fps_divider = fps->fps_div;
-	mt9p012_km_ctrl->pict_fps_divider = fps->pict_fps_div;
-
-	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
-				 REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_HOLD);
-	if (rc < 0)
-		return -EBUSY;
-
-	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
-			REG_FRAME_LENGTH_LINES,
-			mt9p012_km_regs.reg_pat[mt9p012_km_ctrl->sensormode].
-			frame_length_lines *
-			mt9p012_km_ctrl->fps_divider / 0x00000400);
-	if (rc < 0)
-		return rc;
-
-	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
-				 REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_UPDATE);
-
-	return rc;
-}
-
-
-static int32_t mt9p012_km_write_exp_gain(uint16_t gain, uint32_t line)
-{
-	uint16_t max_legal_gain = 0x01FF;
-	uint32_t line_length_ratio = 0x00000400;
-	enum mt9p012_km_setting setting;
-	int32_t rc = 0;
-
-	CDBG("Line:%d mt9p012_km_write_exp_gain \n", __LINE__);
-
-	if (mt9p012_km_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
-		mt9p012_km_ctrl->my_reg_gain = gain;
-		mt9p012_km_ctrl->my_reg_line_count = (uint16_t) line;
-	}
-
-	if (gain > max_legal_gain) {
-		CDBG("Max legal gain Line:%d \n", __LINE__);
-		gain = max_legal_gain;
-	}
-
-	/* Verify no overflow */
-	if (mt9p012_km_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
-		line = (uint32_t) (line * mt9p012_km_ctrl->fps_divider /
-				   0x00000400);
-		setting = RES_PREVIEW;
-	} else {
-		line = (uint32_t) (line * mt9p012_km_ctrl->pict_fps_divider /
-				   0x00000400);
-		setting = RES_CAPTURE;
-	}
-
-	gain |= 0x0200;
-
-	if ((mt9p012_km_regs.reg_pat[setting].frame_length_lines - 1) < line) {
-		line_length_ratio = (uint32_t) (line * 0x00000400) /
-		    (mt9p012_km_regs.reg_pat[setting].frame_length_lines - 1);
-	} else
-		line_length_ratio = 0x00000400;
-
-	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
-				REG_GROUPED_PARAMETER_HOLD,
-				GROUPED_PARAMETER_HOLD);
-	if (rc < 0) {
-		CDBG("mt9p012_km_i2c_write_w failed... Line:%d \n", __LINE__);
-		return rc;
-	}
-
-	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
-				 REG_GLOBAL_GAIN, gain);
-	if (rc < 0) {
-		CDBG("mt9p012_km_i2c_write_w failed... Line:%d \n", __LINE__);
-		return rc;
-	}
-
-	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
-				REG_LINE_LENGTH_PCK,
-			       (uint16_t) (mt9p012_km_regs.reg_pat[setting].
-			    line_length_pck * line_length_ratio / 0x00000400));
-	if (rc < 0)
-		return rc;
-
-	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
-				 REG_COARSE_INT_TIME,
-				 (uint16_t) ((line * 0x00000400)/
-				 line_length_ratio));
-	if (rc < 0) {
-		CDBG("mt9p012_km_i2c_write_w failed... Line:%d \n", __LINE__);
-		return rc;
-	}
-
-	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
-				 REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_UPDATE);
-	if (rc < 0) {
-		CDBG("mt9p012_km_i2c_write_w failed... Line:%d \n", __LINE__);
-		return rc;
-	}
-
-	CDBG("mt9p012_km_write_exp_gain: gain = %d, line = %d\n", gain, line);
-
-	return rc;
-}
-
-static int32_t mt9p012_km_set_pict_exp_gain(uint16_t gain, uint32_t line)
-{
-	int32_t rc = 0;
-
-	CDBG("Line:%d mt9p012_km_set_pict_exp_gain \n", __LINE__);
-
-	rc = mt9p012_km_write_exp_gain(gain, line);
-	if (rc < 0) {
-		CDBG("Line:%d mt9p012_km_set_pict_exp_gain failed... \n",
-		     __LINE__);
-		return rc;
-	}
-
-	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
-				 MT9P012_KM_REG_RESET_REGISTER,
-				 0x10CC | 0x0002);
-	if (rc < 0) {
-		CDBG("mt9p012_km_i2c_write_w failed... Line:%d \n", __LINE__);
-		return rc;
-	}
-
-	mdelay(5);
-
-	/* camera_timed_wait(snapshot_wait*exposure_ratio); */
-	return rc;
-}
-
-static int32_t mt9p012_km_setting(enum mt9p012_km_reg_update rupdate,
-				enum mt9p012_km_setting rt)
-{
-	int32_t rc = 0;
-
-	switch (rupdate) {
-	case UPDATE_PERIODIC:
-		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
-
-			struct mt9p012_km_i2c_reg_conf ppc_tbl[] = {
-				{REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_HOLD},
-				{REG_ROW_SPEED,
-				 mt9p012_km_regs.reg_pat[rt].row_speed},
-				{REG_X_ADDR_START,
-				 mt9p012_km_regs.reg_pat[rt].x_addr_start},
-				{REG_X_ADDR_END,
-				 mt9p012_km_regs.reg_pat[rt].x_addr_end},
-				{REG_Y_ADDR_START,
-				 mt9p012_km_regs.reg_pat[rt].y_addr_start},
-				{REG_Y_ADDR_END,
-				 mt9p012_km_regs.reg_pat[rt].y_addr_end},
-				{REG_READ_MODE,
-				 mt9p012_km_regs.reg_pat[rt].read_mode},
-				{REG_SCALE_M,
-				 mt9p012_km_regs.reg_pat[rt].scale_m},
-				{REG_X_OUTPUT_SIZE,
-				 mt9p012_km_regs.reg_pat[rt].x_output_size},
-				{REG_Y_OUTPUT_SIZE,
-				 mt9p012_km_regs.reg_pat[rt].y_output_size},
-				{REG_LINE_LENGTH_PCK,
-				 mt9p012_km_regs.reg_pat[rt].line_length_pck},
-				{REG_FRAME_LENGTH_LINES,
-			       (mt9p012_km_regs.reg_pat[rt].frame_length_lines *
-				mt9p012_km_ctrl->fps_divider / 0x00000400)},
-				{REG_COARSE_INT_TIME,
-				 mt9p012_km_regs.reg_pat[rt].coarse_int_time},
-				{REG_FINE_INTEGRATION_TIME,
-				 mt9p012_km_regs.reg_pat[rt].fine_int_time},
-				{REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_UPDATE},
-			};
-
-			if (update_type == REG_INIT) {
-				update_type = rupdate;
-				return rc;
-			}
-
-			rc = mt9p012_km_i2c_write_w_table(&ppc_tbl[0],
-						ARRAY_SIZE(ppc_tbl));
-			if (rc < 0)
-				return rc;
-
-			rc = mt9p012_km_test(mt9p012_km_ctrl->set_test);
-			if (rc < 0)
-				return rc;
-
-			rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
-						 MT9P012_KM_REG_RESET_REGISTER,
-						 0x10cc |
-						 0x0002);
-			if (rc < 0)
-				return rc;
-
-			mdelay(15);	/* 15? wait for sensor to transition */
-
-			return rc;
-		}
-		break;	/* UPDATE_PERIODIC */
-
-	case REG_INIT:
-		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
-			struct mt9p012_km_i2c_reg_conf ipc_tbl1[] = {
-				{MT9P012_KM_REG_RESET_REGISTER,
-				 MT9P012_KM_RESET_REGISTER_PWOFF},
-				{REG_VT_PIX_CLK_DIV,
-				 mt9p012_km_regs.reg_pat[rt].vt_pix_clk_div},
-				{REG_VT_SYS_CLK_DIV,
-				 mt9p012_km_regs.reg_pat[rt].vt_sys_clk_div},
-				{REG_PRE_PLL_CLK_DIV,
-				 mt9p012_km_regs.reg_pat[rt].pre_pll_clk_div},
-				{REG_PLL_MULTIPLIER,
-				 mt9p012_km_regs.reg_pat[rt].pll_multiplier},
-				{REG_OP_PIX_CLK_DIV,
-				 mt9p012_km_regs.reg_pat[rt].op_pix_clk_div},
-				{REG_OP_SYS_CLK_DIV,
-				 mt9p012_km_regs.reg_pat[rt].op_sys_clk_div},
-				{MT9P012_KM_REG_RESET_REGISTER,
-				 MT9P012_KM_RESET_REGISTER_PWON},
-			};
-
-			struct mt9p012_km_i2c_reg_conf ipc_tbl2[] = {
-				{REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_HOLD},
-				/* Optimized register settings for
-				   Rev3 Silicon */
-				{0x308A, 0x6424},
-				{0x3092, 0x0A52},
-				{0x3094, 0x4656},
-				{0x3096, 0x5652},
-				{0x0204, 0x0010},
-				{0x0206, 0x0010},
-				{0x0208, 0x0010},
-				{0x020A, 0x0010},
-				{0x020C, 0x0010},
-				{0x3088, 0x6FF6},
-				{0x3154, 0x0282},
-				{0x3156, 0x0381},
-				{0x3162, 0x04CE},
-			};
-
-			struct mt9p012_km_i2c_reg_conf ipc_tbl3[] = {
-				/* Set preview or snapshot mode */
-				{REG_ROW_SPEED,
-				 mt9p012_km_regs.reg_pat[rt].row_speed},
-				{REG_X_ADDR_START,
-				 mt9p012_km_regs.reg_pat[rt].x_addr_start},
-				{REG_X_ADDR_END,
-				 mt9p012_km_regs.reg_pat[rt].x_addr_end},
-				{REG_Y_ADDR_START,
-				 mt9p012_km_regs.reg_pat[rt].y_addr_start},
-				{REG_Y_ADDR_END,
-				 mt9p012_km_regs.reg_pat[rt].y_addr_end},
-				{REG_READ_MODE,
-				 mt9p012_km_regs.reg_pat[rt].read_mode},
-				{REG_SCALE_M,
-				 mt9p012_km_regs.reg_pat[rt].scale_m},
-				{REG_X_OUTPUT_SIZE,
-				 mt9p012_km_regs.reg_pat[rt].x_output_size},
-				{REG_Y_OUTPUT_SIZE,
-				 mt9p012_km_regs.reg_pat[rt].y_output_size},
-				{REG_LINE_LENGTH_PCK,
-				 mt9p012_km_regs.reg_pat[rt].line_length_pck},
-				{REG_FRAME_LENGTH_LINES,
-				 mt9p012_km_regs.reg_pat[rt].
-				 frame_length_lines},
-				{REG_COARSE_INT_TIME,
-				 mt9p012_km_regs.reg_pat[rt].coarse_int_time},
-				{REG_FINE_INTEGRATION_TIME,
-				 mt9p012_km_regs.reg_pat[rt].fine_int_time},
-				{REG_GROUPED_PARAMETER_HOLD,
-				 GROUPED_PARAMETER_UPDATE},
-			};
-
-			/* reset fps_divider */
-			mt9p012_km_ctrl->fps_divider = 1 * 0x0400;
-
-			rc = mt9p012_km_i2c_write_w_table(&ipc_tbl1[0],
-							ARRAY_SIZE(ipc_tbl1));
-			if (rc < 0)
-				return rc;
-
-			mdelay(15);
-
-			rc = mt9p012_km_i2c_write_w_table(&ipc_tbl2[0],
-							ARRAY_SIZE(ipc_tbl2));
-			if (rc < 0)
-				return rc;
-
-			mdelay(5);
-
-			rc = mt9p012_km_i2c_write_w_table(&ipc_tbl3[0],
-						       ARRAY_SIZE(ipc_tbl3));
-			if (rc < 0)
-				return rc;
-
-			/* load lens shading */
-			rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
-						 REG_GROUPED_PARAMETER_HOLD,
-						 GROUPED_PARAMETER_HOLD);
-			if (rc < 0)
-				return rc;
-
-			rc = mt9p012_km_set_lc();
-			if (rc < 0)
-				return rc;
-
-			rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
-						 REG_GROUPED_PARAMETER_HOLD,
-						 GROUPED_PARAMETER_UPDATE);
-
-			if (rc < 0)
-				return rc;
-		}
-		update_type = rupdate;
-		break;		/* case REG_INIT: */
-
-	default:
-		rc = -EINVAL;
-		break;
-	}			/* switch (rupdate) */
-
-	return rc;
-}
-
-static int32_t mt9p012_km_video_config(int mode, int res)
-{
-	int32_t rc;
-
-	switch (res) {
-	case QTR_SIZE:
-		rc = mt9p012_km_setting(UPDATE_PERIODIC, RES_PREVIEW);
-		if (rc < 0)
-			return rc;
-
-		CDBG("mt9p012_km sensor configuration done!\n");
-		break;
-
-	case FULL_SIZE:
-		rc = mt9p012_km_setting(UPDATE_PERIODIC, RES_CAPTURE);
-		if (rc < 0)
-			return rc;
-
-		break;
-
-	default:
-		return 0;
-	}			/* switch */
-
-	mt9p012_km_ctrl->prev_res = res;
-	mt9p012_km_ctrl->curr_res = res;
-	mt9p012_km_ctrl->sensormode = mode;
-
-	rc = mt9p012_km_write_exp_gain(mt9p012_km_ctrl->my_reg_gain,
-				    mt9p012_km_ctrl->my_reg_line_count);
-
-	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
-				 MT9P012_KM_REG_RESET_REGISTER,
-				 0x10cc | 0x0002);
-
-	mdelay(15);
-	return rc;
-}
-
-static int32_t mt9p012_km_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-
-	rc = mt9p012_km_setting(UPDATE_PERIODIC, RES_CAPTURE);
-	if (rc < 0)
-		return rc;
-
-	mt9p012_km_ctrl->curr_res = mt9p012_km_ctrl->pict_res;
-
-	mt9p012_km_ctrl->sensormode = mode;
-
-	return rc;
-}
-
-static int32_t mt9p012_km_raw_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-
-	rc = mt9p012_km_setting(UPDATE_PERIODIC, RES_CAPTURE);
-	if (rc < 0)
-		return rc;
-
-	mt9p012_km_ctrl->curr_res = mt9p012_km_ctrl->pict_res;
-
-	mt9p012_km_ctrl->sensormode = mode;
-
-	return rc;
-}
-
-static int32_t mt9p012_km_power_down(void)
-{
-	int32_t rc = 0;
-
-	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
-				 MT9P012_KM_REG_RESET_REGISTER,
-				 MT9P012_KM_RESET_REGISTER_PWOFF);
-
-	mdelay(5);
-	return rc;
-}
-
-static int32_t mt9p012_km_move_focus(int direction, int32_t num_steps)
-{
-	int16_t step_direction;
-	int16_t actual_step;
-	int16_t next_position;
-	uint8_t code_val_msb, code_val_lsb;
-
-	if (num_steps > MT9P012_KM_TOTAL_STEPS_NEAR_TO_FAR)
-		num_steps = MT9P012_KM_TOTAL_STEPS_NEAR_TO_FAR;
-	else if (num_steps == 0) {
-		CDBG("mt9p012_km_move_focus failed at line %d ...\n", __LINE__);
-		return -EINVAL;
-	}
-
-	if (direction == MOVE_NEAR)
-		step_direction = 16;	/* 10bit */
-	else if (direction == MOVE_FAR)
-		step_direction = -16;	/* 10 bit */
-	else {
-		CDBG("mt9p012_km_move_focus failed at line %d ...\n", __LINE__);
-		return -EINVAL;
-	}
-
-	if (mt9p012_km_ctrl->curr_lens_pos <
-				mt9p012_km_ctrl->init_curr_lens_pos)
-		mt9p012_km_ctrl->curr_lens_pos =
-				mt9p012_km_ctrl->init_curr_lens_pos;
-
-	actual_step = (int16_t) (step_direction * (int16_t) num_steps);
-	next_position = (int16_t) (mt9p012_km_ctrl->curr_lens_pos +
-							actual_step);
-
-	if (next_position > 1023)
-		next_position = 1023;
-	else if (next_position < 0)
-		next_position = 0;
-
-	code_val_msb = next_position >> 4;
-	code_val_lsb = (next_position & 0x000F) << 4;
-	code_val_lsb |= mode_mask;
-
-	/* Writing the digital code for current to the actuator */
-	if (mt9p012_km_i2c_write_b(MT9P012_KM_AF_I2C_ADDR >> 1,
-				code_val_msb, code_val_lsb) < 0) {
-		CDBG("mt9p012_km_move_focus failed at line %d ...\n", __LINE__);
-		return -EBUSY;
-	}
-
-	/* Storing the current lens Position */
-	mt9p012_km_ctrl->curr_lens_pos = next_position;
-
-	return 0;
-}
-
-static int32_t mt9p012_km_set_default_focus(void)
-{
-	int32_t rc = 0;
-	uint8_t code_val_msb, code_val_lsb;
-
-	code_val_msb = 0x00;
-	code_val_lsb = 0x04;
-
-	/* Write the digital code for current to the actuator */
-	rc = mt9p012_km_i2c_write_b(MT9P012_KM_AF_I2C_ADDR >> 1,
-				 code_val_msb, code_val_lsb);
-
-	mt9p012_km_ctrl->curr_lens_pos = 0;
-	mt9p012_km_ctrl->init_curr_lens_pos = 0;
-
-	return rc;
-}
-
-static int mt9p012_km_probe_init_done(const struct msm_camera_sensor_info *data)
-{
-	gpio_direction_output(data->sensor_reset, 0);
-	gpio_free(data->sensor_reset);
-	return 0;
-}
-
-static int
-	mt9p012_km_probe_init_sensor(const struct msm_camera_sensor_info *data)
-{
-	int32_t rc;
-	uint16_t chipid;
-
-	rc = gpio_request(data->sensor_reset, "mt9p012_km");
-	if (!rc)
-		gpio_direction_output(data->sensor_reset, 1);
-	else
-		goto init_probe_done;
-
-	msleep(20);
-
-	/* RESET the sensor image part via I2C command */
-	CDBG("mt9p012_km_sensor_init(): reseting sensor.\n");
-	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
-				 MT9P012_KM_REG_RESET_REGISTER,
-				 0x10CC | 0x0001);
-	if (rc < 0) {
-		CDBG("sensor reset failed. rc = %d\n", rc);
-		goto init_probe_fail;
-	}
-
-		msleep(MT9P012_KM_RESET_DELAY_MSECS);
-
-	/* 3. Read sensor Model ID: */
-	rc = mt9p012_km_i2c_read_w(mt9p012_km_client->addr,
-				MT9P012_KM_REG_MODEL_ID, &chipid);
-	if (rc < 0)
-		goto init_probe_fail;
-
-	/* 4. Compare sensor ID to MT9T012VC ID: */
-	if (chipid != MT9P012_KM_MODEL_ID) {
-		CDBG("mt9p012_km wrong model_id = 0x%x\n", chipid);
-		rc = -ENODEV;
-		goto init_probe_fail;
-	}
-
-	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr, 0x306E, 0x9080);
-	if (rc < 0) {
-		CDBG("REV_7 write failed. rc = %d\n", rc);
-		goto init_probe_fail;
-	}
-
-	/* RESET_REGISTER, enable parallel interface and disable serialiser */
-	CDBG("mt9p012_km_sensor_init(): enabling parallel interface.\n");
-	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr, 0x301A, 0x10CC);
-	if (rc < 0) {
-		CDBG("enable parallel interface failed. rc = %d\n", rc);
-		goto init_probe_fail;
-	}
-
-	/* To disable the 2 extra lines */
-	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr, 0x3064, 0x0805);
-
-	if (rc < 0) {
-		CDBG("disable the 2 extra lines failed. rc = %d\n", rc);
-		goto init_probe_fail;
-	}
-
-	goto init_probe_done;
-
-init_probe_fail:
-	mt9p012_km_probe_init_done(data);
-init_probe_done:
-	return rc;
-}
-
-static int
-	mt9p012_km_sensor_open_init(const struct msm_camera_sensor_info *data)
-{
-	int32_t rc;
-
-	mt9p012_km_ctrl = kzalloc(sizeof(struct mt9p012_km_ctrl), GFP_KERNEL);
-	if (!mt9p012_km_ctrl) {
-		CDBG("mt9p012_km_init failed!\n");
-		rc = -ENOMEM;
-		goto init_done;
-	}
-
-	mt9p012_km_ctrl->fps_divider = 1 * 0x00000400;
-	mt9p012_km_ctrl->pict_fps_divider = 1 * 0x00000400;
-	mt9p012_km_ctrl->set_test = TEST_OFF;
-	mt9p012_km_ctrl->prev_res = QTR_SIZE;
-	mt9p012_km_ctrl->pict_res = FULL_SIZE;
-
-	if (data)
-		mt9p012_km_ctrl->sensordata = data;
-
-	msm_camio_camif_pad_reg_reset();
-	mdelay(20);
-
-	rc = mt9p012_km_probe_init_sensor(data);
-	if (rc < 0)
-		goto init_fail1;
-
-	if (mt9p012_km_ctrl->prev_res == QTR_SIZE)
-		rc = mt9p012_km_setting(REG_INIT, RES_PREVIEW);
-	else
-		rc = mt9p012_km_setting(REG_INIT, RES_CAPTURE);
-
-	if (rc < 0) {
-		CDBG("mt9p012_km_setting failed. rc = %d\n", rc);
-		goto init_fail1;
-	}
-
-	/* sensor : output enable */
-	CDBG("mt9p012_km_sensor_open_init(): enabling output.\n");
-	rc = mt9p012_km_i2c_write_w(mt9p012_km_client->addr,
-				 MT9P012_KM_REG_RESET_REGISTER,
-				 MT9P012_KM_RESET_REGISTER_PWON);
-	if (rc < 0) {
-		CDBG("sensor output enable failed. rc = %d\n", rc);
-		goto init_fail1;
-	}
-
-	if (rc >= 0)
-		goto init_done;
-
-init_fail1:
-	mt9p012_km_probe_init_done(data);
-	kfree(mt9p012_km_ctrl);
-init_done:
-	return rc;
-}
-
-static int mt9p012_km_init_client(struct i2c_client *client)
-{
-	/* Initialize the MSM_CAMI2C Chip */
-	init_waitqueue_head(&mt9p012_km_wait_queue);
-	return 0;
-}
-
-static int32_t mt9p012_km_set_sensor_mode(int mode, int res)
-{
-	int32_t rc = 0;
-
-	switch (mode) {
-	case SENSOR_PREVIEW_MODE:
-		rc = mt9p012_km_video_config(mode, res);
-		break;
-
-	case SENSOR_SNAPSHOT_MODE:
-		rc = mt9p012_km_snapshot_config(mode);
-		break;
-
-	case SENSOR_RAW_SNAPSHOT_MODE:
-		rc = mt9p012_km_raw_snapshot_config(mode);
-		break;
-
-	default:
-		rc = -EINVAL;
-		break;
-	}
-
-	return rc;
-}
-
-int mt9p012_km_sensor_config(void __user *argp)
-{
-	struct sensor_cfg_data cdata;
-	int rc = 0;
-
-	if (copy_from_user(&cdata,
-			   (void *)argp, sizeof(struct sensor_cfg_data)))
-		return -EFAULT;
-
-	mutex_lock(&mt9p012_km_mut);
-
-	CDBG("%s: cfgtype = %d\n", __func__, cdata.cfgtype);
-	switch (cdata.cfgtype) {
-	case CFG_GET_PICT_FPS:
-		mt9p012_km_get_pict_fps(cdata.cfg.gfps.prevfps,
-				     &(cdata.cfg.gfps.pictfps));
-
-		if (copy_to_user((void *)argp, &cdata,
-				 sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PREV_L_PF:
-		cdata.cfg.prevl_pf = mt9p012_km_get_prev_lines_pf();
-
-		if (copy_to_user((void *)argp,
-				 &cdata, sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PREV_P_PL:
-		cdata.cfg.prevp_pl = mt9p012_km_get_prev_pixels_pl();
-
-		if (copy_to_user((void *)argp,
-				 &cdata, sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PICT_L_PF:
-		cdata.cfg.pictl_pf = mt9p012_km_get_pict_lines_pf();
-
-		if (copy_to_user((void *)argp,
-				 &cdata, sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PICT_P_PL:
-		cdata.cfg.pictp_pl = mt9p012_km_get_pict_pixels_pl();
-
-		if (copy_to_user((void *)argp,
-				 &cdata, sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PICT_MAX_EXP_LC:
-		cdata.cfg.pict_max_exp_lc = mt9p012_km_get_pict_max_exp_lc();
-
-		if (copy_to_user((void *)argp,
-				 &cdata, sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_SET_FPS:
-	case CFG_SET_PICT_FPS:
-		rc = mt9p012_km_set_fps(&(cdata.cfg.fps));
-		break;
-
-	case CFG_SET_EXP_GAIN:
-		rc = mt9p012_km_write_exp_gain(cdata.cfg.exp_gain.gain,
-					    cdata.cfg.exp_gain.line);
-		break;
-
-	case CFG_SET_PICT_EXP_GAIN:
-		CDBG("Line:%d CFG_SET_PICT_EXP_GAIN \n", __LINE__);
-		rc = mt9p012_km_set_pict_exp_gain(cdata.cfg.exp_gain.gain,
-					       cdata.cfg.exp_gain.line);
-		break;
-
-	case CFG_SET_MODE:
-		rc = mt9p012_km_set_sensor_mode(cdata.mode, cdata.rs);
-		break;
-
-	case CFG_PWR_DOWN:
-		rc = mt9p012_km_power_down();
-		break;
-
-	case CFG_MOVE_FOCUS:
-		CDBG("mt9p012_km_ioctl: CFG_MOVE_FOCUS: cdata.cfg.focus.dir=%d \
-				cdata.cfg.focus.steps=%d\n",
-				cdata.cfg.focus.dir, cdata.cfg.focus.steps);
-		rc = mt9p012_km_move_focus(cdata.cfg.focus.dir,
-					cdata.cfg.focus.steps);
-		break;
-
-	case CFG_SET_DEFAULT_FOCUS:
-		rc = mt9p012_km_set_default_focus();
-		break;
-
-	case CFG_SET_LENS_SHADING:
-		CDBG("%s: CFG_SET_LENS_SHADING\n", __func__);
-		rc = mt9p012_km_lens_shading_enable(cdata.cfg.lens_shading);
-		break;
-
-	case CFG_GET_AF_MAX_STEPS:
-		cdata.max_steps = MT9P012_KM_STEPS_NEAR_TO_CLOSEST_INF;
-		if (copy_to_user((void *)argp,
-				 &cdata, sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_SET_EFFECT:
-	default:
-		rc = -EINVAL;
-		break;
-	}
-
-	mutex_unlock(&mt9p012_km_mut);
-	return rc;
-}
-
-int mt9p012_km_sensor_release(void)
-{
-	int rc = -EBADF;
-
-	mutex_lock(&mt9p012_km_mut);
-
-	mt9p012_km_power_down();
-
-	gpio_direction_output(mt9p012_km_ctrl->sensordata->sensor_reset, 0);
-	gpio_free(mt9p012_km_ctrl->sensordata->sensor_reset);
-
-	gpio_direction_output(mt9p012_km_ctrl->sensordata->vcm_pwd, 0);
-	gpio_free(mt9p012_km_ctrl->sensordata->vcm_pwd);
-
-	kfree(mt9p012_km_ctrl);
-	mt9p012_km_ctrl = NULL;
-
-	CDBG("mt9p012_km_release completed\n");
-
-	mutex_unlock(&mt9p012_km_mut);
-	return rc;
-}
-
-static int mt9p012_km_i2c_probe(struct i2c_client *client,
-			     const struct i2c_device_id *id)
-{
-	int rc = 0;
-	CDBG("mt9p012_km_probe called!\n");
-
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		CDBG("i2c_check_functionality failed\n");
-		goto probe_failure;
-	}
-
-	mt9p012_km_sensorw = kzalloc(sizeof(struct mt9p012_km_work),
-							GFP_KERNEL);
-	if (!mt9p012_km_sensorw) {
-		CDBG("kzalloc failed.\n");
-		rc = -ENOMEM;
-		goto probe_failure;
-	}
-
-	i2c_set_clientdata(client, mt9p012_km_sensorw);
-	mt9p012_km_init_client(client);
-	mt9p012_km_client = client;
-
-	mdelay(50);
-
-	CDBG("mt9p012_km_probe successed! rc = %d\n", rc);
-	return 0;
-
-probe_failure:
-	CDBG("mt9p012_km_probe failed! rc = %d\n", rc);
-	return rc;
-}
-
-static const struct i2c_device_id mt9p012_km_i2c_id[] = {
-	{"mt9p012_km", 0},
-	{}
-};
-
-static struct i2c_driver mt9p012_km_i2c_driver = {
-	.id_table = mt9p012_km_i2c_id,
-	.probe = mt9p012_km_i2c_probe,
-	.remove = __exit_p(mt9p012_km_i2c_remove),
-	.driver = {
-		   .name = "mt9p012_km",
-		   },
-};
-
-static int mt9p012_km_sensor_probe(const struct msm_camera_sensor_info *info,
-				struct msm_sensor_ctrl *s)
-{
-	int rc = i2c_add_driver(&mt9p012_km_i2c_driver);
-	if (rc < 0 || mt9p012_km_client == NULL) {
-		rc = -ENOTSUPP;
-		goto probe_done;
-	}
-
-	msm_camio_clk_rate_set(MT9P012_KM_DEFAULT_CLOCK_RATE);
-	mdelay(20);
-
-	rc = mt9p012_km_probe_init_sensor(info);
-	if (rc < 0)
-		goto probe_done;
-
-	s->s_init = mt9p012_km_sensor_open_init;
-	s->s_release = mt9p012_km_sensor_release;
-	s->s_config = mt9p012_km_sensor_config;
-	s->s_mount_angle  = 0;
-	mt9p012_km_probe_init_done(info);
-
-probe_done:
-	CDBG("%s %s:%d\n", __FILE__, __func__, __LINE__);
-	return rc;
-}
-
-static int __mt9p012_km_probe(struct platform_device *pdev)
-{
-	return msm_camera_drv_start(pdev, mt9p012_km_sensor_probe);
-}
-
-static struct platform_driver msm_camera_driver = {
-	.probe = __mt9p012_km_probe,
-	.driver = {
-		   .name = "msm_camera_mt9p012_km",
-		   .owner = THIS_MODULE,
-		   },
-};
-
-static int __init mt9p012_km_init(void)
-{
-	return platform_driver_register(&msm_camera_driver);
-}
-
-module_init(mt9p012_km_init);
diff --git a/drivers/media/video/msm/mt9p012_km.h b/drivers/media/video/msm/mt9p012_km.h
deleted file mode 100644
index 0feb331..0000000
--- a/drivers/media/video/msm/mt9p012_km.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. 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 MT9P012_KM_H
-#define MT9P012_KM_H
-
-#include <linux/types.h>
-#include <mach/board.h>
-
-extern struct mt9p012_km_reg mt9p012_km_regs;	/* from mt9p012_km_reg.c */
-
-struct reg_struct {
-	uint16_t vt_pix_clk_div;     /* 0x0300 */
-	uint16_t vt_sys_clk_div;     /* 0x0302 */
-	uint16_t pre_pll_clk_div;    /* 0x0304 */
-	uint16_t pll_multiplier;     /* 0x0306 */
-	uint16_t op_pix_clk_div;     /* 0x0308 */
-	uint16_t op_sys_clk_div;     /* 0x030A */
-	uint16_t scale_m;            /* 0x0404 */
-	uint16_t row_speed;          /* 0x3016 */
-	uint16_t x_addr_start;       /* 0x3004 */
-	uint16_t x_addr_end;         /* 0x3008 */
-	uint16_t y_addr_start;       /* 0x3002 */
-	uint16_t y_addr_end;         /* 0x3006 */
-	uint16_t read_mode;          /* 0x3040 */
-	uint16_t x_output_size ;     /* 0x034C */
-	uint16_t y_output_size;      /* 0x034E */
-	uint16_t line_length_pck;    /* 0x300C */
-	uint16_t frame_length_lines; /* 0x300A */
-	uint16_t coarse_int_time;    /* 0x3012 */
-	uint16_t fine_int_time;      /* 0x3014 */
-};
-
-
-struct mt9p012_km_i2c_reg_conf {
-	unsigned short waddr;
-	unsigned short wdata;
-};
-
-
-struct mt9p012_km_reg {
-	struct reg_struct const *reg_pat;
-	uint16_t reg_pat_size;
-	struct mt9p012_km_i2c_reg_conf const *ttbl;
-	uint16_t ttbl_size;
-	struct mt9p012_km_i2c_reg_conf const *lctbl;
-	uint16_t lctbl_size;
-	struct mt9p012_km_i2c_reg_conf const *rftbl;
-	uint16_t rftbl_size;
-};
-
-#endif /* MT9P012_KM_H */
diff --git a/drivers/media/video/msm/mt9p012_km_reg.c b/drivers/media/video/msm/mt9p012_km_reg.c
deleted file mode 100644
index 109930b..0000000
--- a/drivers/media/video/msm/mt9p012_km_reg.c
+++ /dev/null
@@ -1,375 +0,0 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. 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 "mt9p012_km.h"
-#include <linux/kernel.h>
-
-/*Micron settings from Applications for lower power consumption.*/
-struct reg_struct const mt9p012_km_reg_pat[2] = {
-	{ /* Preview */
-		/* vt_pix_clk_div          REG=0x0300 */
-		6,  /* 5 */
-
-		/* vt_sys_clk_div          REG=0x0302 */
-		1,
-
-		/* pre_pll_clk_div         REG=0x0304 */
-		2,
-
-		/* pll_multiplier          REG=0x0306 */
-		60,
-
-		/* op_pix_clk_div          REG=0x0308 */
-		8,  /* 10 */
-
-		/* op_sys_clk_div          REG=0x030A */
-		1,
-
-		/* scale_m                 REG=0x0404 */
-		16,
-
-		/* row_speed               REG=0x3016 */
-		0x0111,
-
-		/* x_addr_start            REG=0x3004 */
-		8,
-
-		/* x_addr_end              REG=0x3008 */
-		2597,
-
-		/* y_addr_start            REG=0x3002 */
-		8,
-
-		/* y_addr_end              REG=0x3006 */
-		1949,
-
-		/* read_mode               REG=0x3040
-		 * Preview 2x2 skipping */
-		0x006C,
-
-		/* x_output_size           REG=0x034C */
-		1296,
-
-		/* y_output_size           REG=0x034E */
-		972,
-
-		/* line_length_pck         REG=0x300C */
-		3783,
-
-		/* frame_length_lines      REG=0x300A */
-		1074,
-
-		/* coarse_integration_time REG=0x3012 */
-		16,
-
-		/* fine_integration_time   REG=0x3014 */
-		1764
-	},
-	{ /* Snapshot */
-		/* vt_pix_clk_div          REG=0x0300 */
-		6,
-
-		/* vt_sys_clk_div          REG=0x0302 */
-		1,
-
-		/* pre_pll_clk_div         REG=0x0304 */
-		2,
-
-		/* pll_multiplier          REG=0x0306
-		 * 39 for 10fps snapshot */
-		39,
-
-		/* op_pix_clk_div          REG=0x0308 */
-		8,
-
-		/* op_sys_clk_div          REG=0x030A */
-		1,
-
-		/* scale_m                 REG=0x0404 */
-		16,
-
-		/* row_speed               REG=0x3016 */
-		0x0111,
-
-		/* x_addr_start            REG=0x3004 */
-		8,
-
-		/* x_addr_end              REG=0x3008 */
-		2615,
-
-		/* y_addr_start            REG=0x3002 */
-		8,
-
-		/* y_addr_end              REG=0x3006 */
-		1967,
-
-		/* read_mode               REG=0x3040 */
-		0x0024,
-
-		/* x_output_size           REG=0x034C */
-		2608,
-
-		/* y_output_size           REG=0x034E */
-		1960,
-
-		/* line_length_pck         REG=0x300C */
-		3788,
-
-		/* frame_length_lines      REG=0x300A 10 fps snapshot */
-		2045,
-
-		/* coarse_integration_time REG=0x3012 */
-		16,
-
-		/* fine_integration_time   REG=0x3014 */
-		882
-	}
-};
-
-struct mt9p012_km_i2c_reg_conf const mt9p012_km_test_tbl[] = {
-	{0x3044, 0x0544 & 0xFBFF},
-	{0x30CA, 0x0004 | 0x0001},
-	{0x30D4, 0x9020 & 0x7FFF},
-	{0x31E0, 0x0003 & 0xFFFE},
-	{0x3180, 0x91FF & 0x7FFF},
-	{0x301A, (0x10CC | 0x8000) & 0xFFF7},
-	{0x301E, 0x0000},
-	{0x3780, 0x0000},
-};
-
-
-struct mt9p012_km_i2c_reg_conf const mt9p012_km_lc_tbl[] = {
-	{0x360A, 0x00F0},
-	{0x360C, 0x0B29},
-	{0x360E, 0x5ED1},
-	{0x3610, 0x890D},
-	{0x3612, 0x9871},
-	{0x364A, 0xAD2C},
-	{0x364C, 0x0A8C},
-	{0x364E, 0x91EC},
-	{0x3650, 0x94EC},
-	{0x3652, 0xC76B},
-	{0x368A, 0x5931},
-	{0x368C, 0x4FED},
-	{0x368E, 0x8A50},
-	{0x3690, 0x5C0F},
-	{0x3692, 0x8393},
-	{0x36CA, 0xDB8E},
-	{0x36CC, 0xCA4D},
-	{0x36CE, 0x146F},
-	{0x36D0, 0x618F},
-	{0x36D2, 0x014F},
-	{0x370A, 0x1FEE},
-	{0x370C, 0xDD50},
-	{0x370E, 0xDB54},
-	{0x3710, 0xCA92},
-	{0x3712, 0x1896},
-	{0x3600, 0x00F0},
-	{0x3602, 0xA04C},
-	{0x3604, 0x5711},
-	{0x3606, 0x5E6D},
-	{0x3608, 0xA971},
-	{0x3640, 0xDCCC},
-	{0x3642, 0x0529},
-	{0x3644, 0x96ED},
-	{0x3646, 0xF447},
-	{0x3648, 0x4AEE},
-	{0x3680, 0x2171},
-	{0x3682, 0x634F},
-	{0x3684, 0xCC91},
-	{0x3686, 0xA9CE},
-	{0x3688, 0x8751},
-	{0x36C0, 0x8B6D},
-	{0x36C2, 0xE20E},
-	{0x36C4, 0x750F},
-	{0x36C6, 0x0090},
-	{0x36C8, 0x9E91},
-	{0x3700, 0xEAAF},
-	{0x3702, 0xB8AF},
-	{0x3704, 0xE293},
-	{0x3706, 0xAB33},
-	{0x3708, 0x4595},
-	{0x3614, 0x00D0},
-	{0x3616, 0x8AAB},
-	{0x3618, 0x18B1},
-	{0x361A, 0x54AD},
-	{0x361C, 0x9DB0},
-	{0x3654, 0x11EB},
-	{0x3656, 0x332C},
-	{0x3658, 0x316D},
-	{0x365A, 0xF0EB},
-	{0x365C, 0xB4ED},
-	{0x3694, 0x0F31},
-	{0x3696, 0x08D0},
-	{0x3698, 0xA52F},
-	{0x369A, 0xE64F},
-	{0x369C, 0xC9D2},
-	{0x36D4, 0x8C2D},
-	{0x36D6, 0xAD6E},
-	{0x36D8, 0xE1CE},
-	{0x36DA, 0x1750},
-	{0x36DC, 0x8CAD},
-	{0x3714, 0x8CAF},
-	{0x3716, 0x8C11},
-	{0x3718, 0xE453},
-	{0x371A, 0x9693},
-	{0x371C, 0x38B5},
-	{0x361E, 0x00D0},
-	{0x3620, 0xB6CB},
-	{0x3622, 0x4811},
-	{0x3624, 0xB70C},
-	{0x3626, 0xA771},
-	{0x365E, 0xB5A9},
-	{0x3660, 0x05AA},
-	{0x3662, 0x00CF},
-	{0x3664, 0xB86B},
-	{0x3666, 0xA4AF},
-	{0x369E, 0x3E31},
-	{0x36A0, 0x902B},
-	{0x36A2, 0xD251},
-	{0x36A4, 0x5C2F},
-	{0x36A6, 0x8471},
-	{0x36DE, 0x2C6D},
-	{0x36E0, 0xECEE},
-	{0x36E2, 0xB650},
-	{0x36E4, 0x0210},
-	{0x36E6, 0xACAE},
-	{0x371E, 0xAC30},
-	{0x3720, 0x394E},
-	{0x3722, 0xFDD3},
-	{0x3724, 0xBCB2},
-	{0x3726, 0x5AD5},
-	{0x3782, 0x0508},
-	{0x3784, 0x03B4},
-	{0x3780, 0x8000},
-};
-
-struct mt9p012_km_i2c_reg_conf const mt9p012_km_rolloff_tbl[] = {
-	{0x360A, 0x00F0},
-	{0x360C, 0x0B29},
-	{0x360E, 0x5ED1},
-	{0x3610, 0x890D},
-	{0x3612, 0x9871},
-	{0x364A, 0xAD2C},
-	{0x364C, 0x0A8C},
-	{0x364E, 0x91EC},
-	{0x3650, 0x94EC},
-	{0x3652, 0xC76B},
-	{0x368A, 0x5931},
-	{0x368C, 0x4FED},
-	{0x368E, 0x8A50},
-	{0x3690, 0x5C0F},
-	{0x3692, 0x8393},
-	{0x36CA, 0xDB8E},
-	{0x36CC, 0xCA4D},
-	{0x36CE, 0x146F},
-	{0x36D0, 0x618F},
-	{0x36D2, 0x014F},
-	{0x370A, 0x1FEE},
-	{0x370C, 0xDD50},
-	{0x370E, 0xDB54},
-	{0x3710, 0xCA92},
-	{0x3712, 0x1896},
-	{0x3600, 0x00F0},
-	{0x3602, 0xA04C},
-	{0x3604, 0x5711},
-	{0x3606, 0x5E6D},
-	{0x3608, 0xA971},
-	{0x3640, 0xDCCC},
-	{0x3642, 0x0529},
-	{0x3644, 0x96ED},
-	{0x3646, 0xF447},
-	{0x3648, 0x4AEE},
-	{0x3680, 0x2171},
-	{0x3682, 0x634F},
-	{0x3684, 0xCC91},
-	{0x3686, 0xA9CE},
-	{0x3688, 0x8751},
-	{0x36C0, 0x8B6D},
-	{0x36C2, 0xE20E},
-	{0x36C4, 0x750F},
-	{0x36C6, 0x0090},
-	{0x36C8, 0x9E91},
-	{0x3700, 0xEAAF},
-	{0x3702, 0xB8AF},
-	{0x3704, 0xE293},
-	{0x3706, 0xAB33},
-	{0x3708, 0x4595},
-	{0x3614, 0x00D0},
-	{0x3616, 0x8AAB},
-	{0x3618, 0x18B1},
-	{0x361A, 0x54AD},
-	{0x361C, 0x9DB0},
-	{0x3654, 0x11EB},
-	{0x3656, 0x332C},
-	{0x3658, 0x316D},
-	{0x365A, 0xF0EB},
-	{0x365C, 0xB4ED},
-	{0x3694, 0x0F31},
-	{0x3696, 0x08D0},
-	{0x3698, 0xA52F},
-	{0x369A, 0xE64F},
-	{0x369C, 0xC9D2},
-	{0x36D4, 0x8C2D},
-	{0x36D6, 0xAD6E},
-	{0x36D8, 0xE1CE},
-	{0x36DA, 0x1750},
-	{0x36DC, 0x8CAD},
-	{0x3714, 0x8CAF},
-	{0x3716, 0x8C11},
-	{0x3718, 0xE453},
-	{0x371A, 0x9693},
-	{0x371C, 0x38B5},
-	{0x361E, 0x00D0},
-	{0x3620, 0xB6CB},
-	{0x3622, 0x4811},
-	{0x3624, 0xB70C},
-	{0x3626, 0xA771},
-	{0x365E, 0xB5A9},
-	{0x3660, 0x05AA},
-	{0x3662, 0x00CF},
-	{0x3664, 0xB86B},
-	{0x3666, 0xA4AF},
-	{0x369E, 0x3E31},
-	{0x36A0, 0x902B},
-	{0x36A2, 0xD251},
-	{0x36A4, 0x5C2F},
-	{0x36A6, 0x8471},
-	{0x36DE, 0x2C6D},
-	{0x36E0, 0xECEE},
-	{0x36E2, 0xB650},
-	{0x36E4, 0x0210},
-	{0x36E6, 0xACAE},
-	{0x371E, 0xAC30},
-	{0x3720, 0x394E},
-	{0x3722, 0xFDD3},
-	{0x3724, 0xBCB2},
-	{0x3726, 0x5AD5},
-	{0x3782, 0x0508},
-	{0x3784, 0x03B4},
-	{0x3780, 0x8000},
-};
-
-
-struct mt9p012_km_reg mt9p012_km_regs = {
-	.reg_pat = &mt9p012_km_reg_pat[0],
-	.reg_pat_size = ARRAY_SIZE(mt9p012_km_reg_pat),
-	.ttbl = &mt9p012_km_test_tbl[0],
-	.ttbl_size = ARRAY_SIZE(mt9p012_km_test_tbl),
-	.lctbl = &mt9p012_km_lc_tbl[0],
-	.lctbl_size = ARRAY_SIZE(mt9p012_km_lc_tbl),
-	.rftbl = &mt9p012_km_rolloff_tbl[0],
-	.rftbl_size = ARRAY_SIZE(mt9p012_km_rolloff_tbl)
-};
-
-
diff --git a/drivers/media/video/msm/mt9p012_reg.c b/drivers/media/video/msm/mt9p012_reg.c
deleted file mode 100644
index 06fe419..0000000
--- a/drivers/media/video/msm/mt9p012_reg.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/* Copyright (c) 2009, Code Aurora Forum. 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 "mt9p012.h"
-#include <linux/kernel.h>
-
-/*Micron settings from Applications for lower power consumption.*/
-struct reg_struct const mt9p012_reg_pat[2] = {
-	{ /* Preview */
-		/* vt_pix_clk_div          REG=0x0300 */
-		6,  /* 5 */
-
-		/* vt_sys_clk_div          REG=0x0302 */
-		1,
-		/* pre_pll_clk_div         REG=0x0304 */
-		2,
-		/* pll_multiplier          REG=0x0306 */
-		60,
-
-		/* op_pix_clk_div          REG=0x0308 */
-		8,  /* 10 */
-
-		/* op_sys_clk_div          REG=0x030A */
-		1,
-
-		/* scale_m                 REG=0x0404 */
-		16,
-
-		/* row_speed               REG=0x3016 */
-		0x0111,
-
-		/* x_addr_start            REG=0x3004 */
-		8,
-
-		/* x_addr_end              REG=0x3008 */
-		2597,
-
-		/* y_addr_start            REG=0x3002 */
-		8,
-
-		/* y_addr_end              REG=0x3006 */
-		1949,
-
-		/* read_mode               REG=0x3040
-		 * Preview 2x2 skipping */
-		0x00C3,
-
-		/* x_output_size           REG=0x034C */
-		1296,
-
-		/* y_output_size           REG=0x034E */
-		972,
-
-		/* line_length_pck         REG=0x300C */
-		3659,
-
-		/* frame_length_lines      REG=0x300A */
-		1074,
-
-		/* coarse_integration_time REG=0x3012 */
-		16,
-
-		/* fine_integration_time   REG=0x3014 */
-		1764
-	},
-	{ /* Snapshot */
-		/* vt_pix_clk_div          REG=0x0300 */
-		6,
-
-		/* vt_sys_clk_div          REG=0x0302 */
-		1,
-
-		/* pre_pll_clk_div         REG=0x0304 */
-		2,
-
-		/* pll_multiplier          REG=0x0306
-		 * 60 for 10fps snapshot */
-		60,
-
-		/* op_pix_clk_div          REG=0x0308 */
-		8,
-
-		/* op_sys_clk_div          REG=0x030A */
-		1,
-
-		/* scale_m                 REG=0x0404 */
-		16,
-
-		/* row_speed               REG=0x3016 */
-		0x0111,
-
-		/* x_addr_start            REG=0x3004 */
-		8,
-
-		/* x_addr_end              REG=0x3008 */
-		2615,
-
-		/* y_addr_start            REG=0x3002 */
-		8,
-
-		/* y_addr_end              REG=0x3006 */
-		1967,
-
-		/* read_mode               REG=0x3040 */
-		0x0041,
-
-		/* x_output_size           REG=0x034C */
-		2608,
-
-		/* y_output_size           REG=0x034E */
-		1960,
-
-		/* line_length_pck         REG=0x300C */
-		3911,
-
-		/* frame_length_lines      REG=0x300A 10 fps snapshot */
-		2045,
-
-		/* coarse_integration_time REG=0x3012 */
-		16,
-
-		/* fine_integration_time   REG=0x3014 */
-		882
-	}
-};
-
-
-struct mt9p012_i2c_reg_conf const mt9p012_test_tbl[] = {
-	{0x3044, 0x0544 & 0xFBFF},
-	{0x30CA, 0x0004 | 0x0001},
-	{0x30D4, 0x9020 & 0x7FFF},
-	{0x31E0, 0x0003 & 0xFFFE},
-	{0x3180, 0x91FF & 0x7FFF},
-	{0x301A, (0x10CC | 0x8000) & 0xFFF7},
-	{0x301E, 0x0000},
-	{0x3780, 0x0000},
-};
-struct mt9p012_i2c_reg_conf const mt9p012_rolloff_tbl[] = {
-	{0x360A, 0x0110},
-	{0x360C, 0x270D},
-	{0x360E, 0x0071},
-	{0x3610, 0xA38D},
-	{0x3612, 0xA610},
-	{0x364A, 0x8F49},
-	{0x364C, 0x696A},
-	{0x364E, 0x0FCD},
-	{0x3650, 0x20ED},
-	{0x3652, 0x81ED},
-	{0x368A, 0x1031},
-	{0x368C, 0xBCAD},
-	{0x368E, 0x77AA},
-	{0x3690, 0xD10E},
-	{0x3692, 0xC133},
-	{0x36CA, 0x4F8D},
-	{0x36CC, 0xAC4D},
-	{0x36CE, 0xC8CE},
-	{0x36D0, 0x73AD},
-	{0x36D2, 0xC150},
-	{0x370A, 0xB590},
-	{0x370C, 0x9010},
-	{0x370E, 0xAC52},
-	{0x3710, 0x4D51},
-	{0x3712, 0x5670},
-	{0x3600, 0x00F0},
-	{0x3602, 0xCE4B},
-	{0x3604, 0x4270},
-	{0x3606, 0x8BC9},
-	{0x3608, 0xFA2F},
-	{0x3640, 0x9A09},
-	{0x3642, 0xB40C},
-	{0x3644, 0x4ECD},
-	{0x3646, 0x1BCC},
-	{0x3648, 0xD68E},
-	{0x3680, 0x1BF0},
-	{0x3682, 0xC94D},
-	{0x3684, 0x714F},
-	{0x3686, 0x1491},
-	{0x3688, 0xB8D3},
-	{0x36C0, 0x3E49},
-	{0x36C2, 0x7A6C},
-	{0x36C4, 0xEF2E},
-	{0x36C6, 0xE0EE},
-	{0x36C8, 0x570F},
-	{0x3700, 0xD6AF},
-	{0x3702, 0x2251},
-	{0x3704, 0x8A33},
-	{0x3706, 0xEFB3},
-	{0x3708, 0x1174},
-	{0x3614, 0x0150},
-	{0x3616, 0xA9AB},
-	{0x3618, 0x1770},
-	{0x361A, 0x8809},
-	{0x361C, 0xE3AE},
-	{0x3654, 0x5ACC},
-	{0x3656, 0x35EA},
-	{0x3658, 0x2DEC},
-	{0x365A, 0xB90B},
-	{0x365C, 0x250C},
-	{0x3694, 0x1630},
-	{0x3696, 0xD88C},
-	{0x3698, 0xBD0E},
-	{0x369A, 0x16D1},
-	{0x369C, 0xE492},
-	{0x36D4, 0x5D6D},
-	{0x36D6, 0x906E},
-	{0x36D8, 0x10AE},
-	{0x36DA, 0x7A8E},
-	{0x36DC, 0x9672},
-	{0x3714, 0x8D90},
-	{0x3716, 0x04F1},
-	{0x3718, 0x23F1},
-	{0x371A, 0xF313},
-	{0x371C, 0xE833},
-	{0x361E, 0x0490},
-	{0x3620, 0x14CD},
-	{0x3622, 0x38F0},
-	{0x3624, 0xBAED},
-	{0x3626, 0xFF6F},
-	{0x365E, 0x358C},
-	{0x3660, 0xA9E9},
-	{0x3662, 0x4A4E},
-	{0x3664, 0x398D},
-	{0x3666, 0x890F},
-	{0x369E, 0x2DF0},
-	{0x36A0, 0xF7CE},
-	{0x36A2, 0xB3CC},
-	{0x36A4, 0x118D},
-	{0x36A6, 0x9CB3},
-	{0x36DE, 0x462D},
-	{0x36E0, 0x74AA},
-	{0x36E2, 0xC8CF},
-	{0x36E4, 0x8DEF},
-	{0x36E6, 0xF130},
-	{0x371E, 0x9250},
-	{0x3720, 0x19CC},
-	{0x3722, 0xDFD1},
-	{0x3724, 0x5B70},
-	{0x3726, 0x34D2},
-	{0x3782, 0x0530},
-	{0x3784, 0x03C8},
-	{0x3780, 0x8000},
-};
-
-struct mt9p012_reg mt9p012_regs = {
-	.reg_pat = &mt9p012_reg_pat[0],
-	.reg_pat_size = ARRAY_SIZE(mt9p012_reg_pat),
-	.ttbl = &mt9p012_test_tbl[0],
-	.ttbl_size = ARRAY_SIZE(mt9p012_test_tbl),
-	.rftbl = &mt9p012_rolloff_tbl[0],
-	.rftbl_size = ARRAY_SIZE(mt9p012_rolloff_tbl)
-};
-
-
diff --git a/drivers/media/video/msm/mt9t013.c b/drivers/media/video/msm/mt9t013.c
deleted file mode 100644
index b4b5bdd..0000000
--- a/drivers/media/video/msm/mt9t013.c
+++ /dev/null
@@ -1,1504 +0,0 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. 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/delay.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <media/msm_camera.h>
-#include <mach/gpio.h>
-#include <mach/camera.h>
-#include <asm/mach-types.h>
-#include "mt9t013.h"
-
-/*=============================================================
-	SENSOR REGISTER DEFINES
-==============================================================*/
-#define MT9T013_REG_MODEL_ID 		 0x0000
-#define MT9T013_MODEL_ID     		 0x2600
-#define REG_GROUPED_PARAMETER_HOLD   0x0104
-#define GROUPED_PARAMETER_HOLD       0x0100
-#define GROUPED_PARAMETER_UPDATE     0x0000
-#define REG_COARSE_INT_TIME          0x3012
-#define REG_VT_PIX_CLK_DIV           0x0300
-#define REG_VT_SYS_CLK_DIV           0x0302
-#define REG_PRE_PLL_CLK_DIV          0x0304
-#define REG_PLL_MULTIPLIER           0x0306
-#define REG_OP_PIX_CLK_DIV           0x0308
-#define REG_OP_SYS_CLK_DIV           0x030A
-#define REG_SCALE_M                  0x0404
-#define REG_FRAME_LENGTH_LINES       0x300A
-#define REG_LINE_LENGTH_PCK          0x300C
-#define REG_X_ADDR_START             0x3004
-#define REG_Y_ADDR_START             0x3002
-#define REG_X_ADDR_END               0x3008
-#define REG_Y_ADDR_END               0x3006
-#define REG_X_OUTPUT_SIZE            0x034C
-#define REG_Y_OUTPUT_SIZE            0x034E
-#define REG_FINE_INT_TIME            0x3014
-#define REG_ROW_SPEED                0x3016
-#define MT9T013_REG_RESET_REGISTER   0x301A
-#define MT9T013_RESET_REGISTER_PWON  0x10CC
-#define MT9T013_RESET_REGISTER_PWOFF 0x1008 /* 0x10C8 stop streaming*/
-#define MT9T013_RESET_FAST_TRANSITION 0x0002
-#define REG_READ_MODE                0x3040
-#define REG_GLOBAL_GAIN              0x305E
-#define REG_TEST_PATTERN_MODE        0x3070
-
-
-enum mt9t013_test_mode {
-	TEST_OFF,
-	TEST_1,
-	TEST_2,
-	TEST_3
-};
-
-enum mt9t013_resolution {
-	QTR_SIZE,
-	FULL_SIZE,
-	INVALID_SIZE
-};
-
-enum mt9t013_reg_update {
-	REG_INIT, /* registers that need to be updated during initialization */
-	UPDATE_PERIODIC, /* registers that needs periodic I2C writes */
-	UPDATE_ALL, /* all registers will be updated */
-	UPDATE_INVALID
-};
-
-enum mt9t013_setting {
-	RES_PREVIEW,
-	RES_CAPTURE
-};
-
-/* actuator's Slave Address */
-#define MT9T013_AF_I2C_ADDR   0x18
-
-/*
-* AF Total steps parameters
-*/
-#define MT9T013_TOTAL_STEPS_NEAR_TO_FAR    30
-
-/*
- * Time in milisecs for waiting for the sensor to reset.
- */
-#define MT9T013_RESET_DELAY_MSECS   66
-
-/* for 30 fps preview */
-#define MT9T013_DEFAULT_CLOCK_RATE  24000000
-#define MT9T013_DEFAULT_MAX_FPS     26
-
-
-/* FIXME: Changes from here */
-struct mt9t013_work {
-	struct work_struct work;
-};
-
-static struct  mt9t013_work *mt9t013_sensorw;
-static struct  i2c_client *mt9t013_client;
-
-struct mt9t013_ctrl {
-	const struct msm_camera_sensor_info *sensordata;
-
-	int sensormode;
-	uint32_t fps_divider; 		/* init to 1 * 0x00000400 */
-	uint32_t pict_fps_divider; 	/* init to 1 * 0x00000400 */
-
-	uint16_t curr_lens_pos;
-	uint16_t init_curr_lens_pos;
-	uint16_t my_reg_gain;
-	uint32_t my_reg_line_count;
-
-	enum mt9t013_resolution prev_res;
-	enum mt9t013_resolution pict_res;
-	enum mt9t013_resolution curr_res;
-	enum mt9t013_test_mode  set_test;
-
-	unsigned short imgaddr;
-};
-
-
-static struct mt9t013_ctrl *mt9t013_ctrl;
-static DECLARE_WAIT_QUEUE_HEAD(mt9t013_wait_queue);
-DEFINE_SEMAPHORE(mt9t013_sem);
-
-static int mt9t013_i2c_rxdata(unsigned short saddr,
-	unsigned char *rxdata, int length)
-{
-	struct i2c_msg msgs[] = {
-	{
-		.addr   = saddr,
-		.flags = 0,
-		.len   = 2,
-		.buf   = rxdata,
-	},
-	{
-		.addr  = saddr,
-		.flags = I2C_M_RD,
-		.len   = length,
-		.buf   = rxdata,
-	},
-	};
-
-	if (i2c_transfer(mt9t013_client->adapter, msgs, 2) < 0) {
-		pr_err("mt9t013_i2c_rxdata failed!\n");
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int32_t mt9t013_i2c_read_w(unsigned short saddr,
-	unsigned short raddr, unsigned short *rdata)
-{
-	int32_t rc = 0;
-	unsigned char buf[4];
-
-	if (!rdata)
-		return -EIO;
-
-	memset(buf, 0, sizeof(buf));
-
-	buf[0] = (raddr & 0xFF00)>>8;
-	buf[1] = (raddr & 0x00FF);
-
-	rc = mt9t013_i2c_rxdata(saddr, buf, 2);
-	if (rc < 0)
-		return rc;
-
-	*rdata = buf[0] << 8 | buf[1];
-
-	if (rc < 0)
-		pr_err("mt9t013_i2c_read failed!\n");
-
-	return rc;
-}
-
-static int32_t mt9t013_i2c_txdata(unsigned short saddr,
-	unsigned char *txdata, int length)
-{
-	struct i2c_msg msg[] = {
-	{
-		.addr = saddr,
-		.flags = 0,
-		.len = length,
-		.buf = txdata,
-	},
-	};
-
-	if (i2c_transfer(mt9t013_client->adapter, msg, 1) < 0) {
-		pr_err("mt9t013_i2c_txdata failed\n");
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int32_t mt9t013_i2c_write_b(unsigned short saddr,
-	unsigned short waddr, unsigned short wdata)
-{
-	int32_t rc = -EIO;
-	unsigned char buf[2];
-
-	memset(buf, 0, sizeof(buf));
-	buf[0] = waddr;
-	buf[1] = wdata;
-	rc = mt9t013_i2c_txdata(saddr, buf, 2);
-
-	if (rc < 0)
-		pr_err("i2c_write failed, addr = 0x%x, val = 0x%x!\n",
-		waddr, wdata);
-
-	return rc;
-}
-
-static int32_t mt9t013_i2c_write_w(unsigned short saddr,
-	unsigned short waddr, unsigned short wdata)
-{
-	int32_t rc = -EIO;
-	unsigned char buf[4];
-
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (waddr & 0xFF00)>>8;
-	buf[1] = (waddr & 0x00FF);
-	buf[2] = (wdata & 0xFF00)>>8;
-	buf[3] = (wdata & 0x00FF);
-
-	rc = mt9t013_i2c_txdata(saddr, buf, 4);
-
-	if (rc < 0)
-		pr_err("i2c_write_w failed, addr = 0x%x, val = 0x%x!\n",
-		waddr, wdata);
-
-	return rc;
-}
-
-static int32_t mt9t013_i2c_write_w_table(
-	struct mt9t013_i2c_reg_conf const *reg_conf_tbl,
-	int num_of_items_in_table)
-{
-	int i;
-	int32_t rc = -EIO;
-
-	for (i = 0; i < num_of_items_in_table; i++) {
-		rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-			reg_conf_tbl->waddr, reg_conf_tbl->wdata);
-		if (rc < 0)
-			break;
-		reg_conf_tbl++;
-	}
-
-	return rc;
-}
-
-static int32_t mt9t013_test(enum mt9t013_test_mode mo)
-{
-	int32_t rc = 0;
-
-	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-			REG_GROUPED_PARAMETER_HOLD,
-			GROUPED_PARAMETER_HOLD);
-	if (rc < 0)
-		return rc;
-
-	if (mo == TEST_OFF)
-		return 0;
-	else {
-		rc = mt9t013_i2c_write_w_table(mt9t013_regs.ttbl,
-				mt9t013_regs.ttbl_size);
-		if (rc < 0)
-			return rc;
-		rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_TEST_PATTERN_MODE, (uint16_t)mo);
-		if (rc < 0)
-			return rc;
-	}
-
-	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-			REG_GROUPED_PARAMETER_HOLD,
-			GROUPED_PARAMETER_UPDATE);
-	if (rc < 0)
-		return rc;
-
-	return rc;
-}
-
-static int32_t mt9t013_set_lc(void)
-{
-	int32_t rc;
-
-	rc = mt9t013_i2c_write_w_table(mt9t013_regs.lctbl,
-		mt9t013_regs.lctbl_size);
-	if (rc < 0)
-		return rc;
-
-	return rc;
-}
-
-static int32_t mt9t013_set_default_focus(uint8_t af_step)
-{
-	int32_t rc = 0;
-	uint8_t code_val_msb, code_val_lsb;
-	code_val_msb = 0x01;
-	code_val_lsb = af_step;
-
-	/* Write the digital code for current to the actuator */
-	rc = mt9t013_i2c_write_b(MT9T013_AF_I2C_ADDR>>1,
-			code_val_msb, code_val_lsb);
-
-	mt9t013_ctrl->curr_lens_pos = 0;
-	mt9t013_ctrl->init_curr_lens_pos = 0;
-	return rc;
-}
-
-static void mt9t013_get_pict_fps(uint16_t fps, uint16_t *pfps)
-{
-	/* input fps is preview fps in Q8 format */
-	uint32_t divider;   /*Q10 */
-	uint32_t pclk_mult; /*Q10 */
-	uint32_t d1;
-	uint32_t d2;
-
-	d1 =
-		(uint32_t)(
-		(mt9t013_regs.reg_pat[RES_PREVIEW].frame_length_lines *
-		0x00000400) /
-		mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines);
-
-	d2 =
-		(uint32_t)(
-		(mt9t013_regs.reg_pat[RES_PREVIEW].line_length_pck *
-		0x00000400) /
-		mt9t013_regs.reg_pat[RES_CAPTURE].line_length_pck);
-
-	divider = (uint32_t) (d1 * d2) / 0x00000400;
-
-	pclk_mult =
-		(uint32_t) ((mt9t013_regs.reg_pat[RES_CAPTURE].pll_multiplier *
-		0x00000400) /
-		(mt9t013_regs.reg_pat[RES_PREVIEW].pll_multiplier));
-
-
-	/* Verify PCLK settings and frame sizes. */
-	*pfps =
-		(uint16_t) (fps * divider * pclk_mult /
-		0x00000400 / 0x00000400);
-}
-
-static uint16_t mt9t013_get_prev_lines_pf(void)
-{
-	if (mt9t013_ctrl->prev_res == QTR_SIZE)
-		return mt9t013_regs.reg_pat[RES_PREVIEW].frame_length_lines;
-	else
-		return mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines;
-}
-
-static uint16_t mt9t013_get_prev_pixels_pl(void)
-{
-	if (mt9t013_ctrl->prev_res == QTR_SIZE)
-		return mt9t013_regs.reg_pat[RES_PREVIEW].line_length_pck;
-	else
-		return mt9t013_regs.reg_pat[RES_CAPTURE].line_length_pck;
-}
-
-static uint16_t mt9t013_get_pict_lines_pf(void)
-{
-	return mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines;
-}
-
-static uint16_t mt9t013_get_pict_pixels_pl(void)
-{
-	return mt9t013_regs.reg_pat[RES_CAPTURE].line_length_pck;
-}
-
-static uint32_t mt9t013_get_pict_max_exp_lc(void)
-{
-	uint16_t snapshot_lines_per_frame;
-
-	if (mt9t013_ctrl->pict_res == QTR_SIZE) {
-		snapshot_lines_per_frame =
-		mt9t013_regs.reg_pat[RES_PREVIEW].frame_length_lines - 1;
-	} else  {
-		snapshot_lines_per_frame =
-		mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines - 1;
-	}
-
-	return snapshot_lines_per_frame * 24;
-}
-
-static int32_t mt9t013_set_fps(struct fps_cfg *fps)
-{
-	/* input is new fps in Q8 format */
-	int32_t rc = 0;
-	enum mt9t013_setting setting;
-
-	mt9t013_ctrl->fps_divider = fps->fps_div;
-	mt9t013_ctrl->pict_fps_divider = fps->pict_fps_div;
-
-	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-			REG_GROUPED_PARAMETER_HOLD,
-			GROUPED_PARAMETER_HOLD);
-	if (rc < 0)
-		return -EBUSY;
-
-	CDBG("mt9t013_set_fps: fps_div is %d, f_mult is %d\n",
-			fps->fps_div, fps->f_mult);
-
-	if (mt9t013_ctrl->sensormode == SENSOR_PREVIEW_MODE)
-		setting = RES_PREVIEW;
-	else
-		setting = RES_CAPTURE;
-	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-			REG_FRAME_LENGTH_LINES,
-			(uint16_t) (
-			mt9t013_regs.reg_pat[setting].frame_length_lines *
-			fps->fps_div / 0x00000400));
-
-	if (rc < 0)
-		return rc;
-
-	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-			REG_GROUPED_PARAMETER_HOLD,
-			GROUPED_PARAMETER_UPDATE);
-	if (rc < 0)
-		return rc;
-
-	return rc;
-}
-
-static int32_t mt9t013_write_exp_gain(uint16_t gain, uint32_t line)
-{
-	uint16_t max_legal_gain = 0x01FF;
-	int32_t rc = 0;
-
-	if (mt9t013_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
-		mt9t013_ctrl->my_reg_gain = gain;
-		mt9t013_ctrl->my_reg_line_count = (uint16_t) line;
-	}
-
-	if (gain > max_legal_gain)
-		gain = max_legal_gain;
-
-	if (mt9t013_ctrl->sensormode != SENSOR_SNAPSHOT_MODE)
-		line = (uint32_t) (line * mt9t013_ctrl->fps_divider /
-				   0x00000400);
-	else
-		line = (uint32_t) (line * mt9t013_ctrl->pict_fps_divider /
-				   0x00000400);
-
-	/*Set digital gain to 1 */
-	gain |= 0x0200;
-
-	/* There used to be PARAMETER_HOLD register write before and
-	 * after REG_GLOBAL_GAIN & REG_COARSE_INIT_TIME. This causes
-	 * aec oscillation. Hence removed. */
-
-	rc = mt9t013_i2c_write_w(mt9t013_client->addr, REG_GLOBAL_GAIN, gain);
-	if (rc < 0)
-		return rc;
-
-	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-			REG_COARSE_INT_TIME, line);
-	if (rc < 0)
-		return rc;
-
-	return rc;
-}
-
-static int32_t mt9t013_set_pict_exp_gain(uint16_t gain, uint32_t line)
-{
-	int32_t rc = 0;
-
-	rc = mt9t013_write_exp_gain(gain, line);
-	if (rc < 0)
-		return rc;
-
-	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-			MT9T013_REG_RESET_REGISTER,
-			0x10CC | 0x0002);
-
-	mdelay(5);
-
-	return rc;
-}
-
-static int32_t mt9t013_setting(enum mt9t013_reg_update rupdate,
-	enum mt9t013_setting rt)
-{
-	int32_t rc = 0;
-
-	switch (rupdate) {
-	case UPDATE_PERIODIC: {
-
-	if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
-#if 0
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				MT9T013_REG_RESET_REGISTER,
-				MT9T013_RESET_REGISTER_PWOFF);
-		if (rc < 0)
-			return rc;
-#endif
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_VT_PIX_CLK_DIV,
-				mt9t013_regs.reg_pat[rt].vt_pix_clk_div);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_VT_SYS_CLK_DIV,
-				mt9t013_regs.reg_pat[rt].vt_sys_clk_div);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_PRE_PLL_CLK_DIV,
-				mt9t013_regs.reg_pat[rt].pre_pll_clk_div);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_PLL_MULTIPLIER,
-				mt9t013_regs.reg_pat[rt].pll_multiplier);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_OP_PIX_CLK_DIV,
-				mt9t013_regs.reg_pat[rt].op_pix_clk_div);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_OP_SYS_CLK_DIV,
-				mt9t013_regs.reg_pat[rt].op_sys_clk_div);
-		if (rc < 0)
-			return rc;
-
-		mdelay(5);
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_GROUPED_PARAMETER_HOLD,
-				GROUPED_PARAMETER_HOLD);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_ROW_SPEED,
-				mt9t013_regs.reg_pat[rt].row_speed);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_X_ADDR_START,
-				mt9t013_regs.reg_pat[rt].x_addr_start);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_X_ADDR_END,
-				mt9t013_regs.reg_pat[rt].x_addr_end);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_Y_ADDR_START,
-				mt9t013_regs.reg_pat[rt].y_addr_start);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_Y_ADDR_END,
-				mt9t013_regs.reg_pat[rt].y_addr_end);
-		if (rc < 0)
-			return rc;
-
-		if (machine_is_sapphire()) {
-			if (rt == 0)
-				rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-					REG_READ_MODE,
-					0x046F);
-			else
-				rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-					REG_READ_MODE,
-					0x0027);
-		} else
-			rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-					REG_READ_MODE,
-					mt9t013_regs.reg_pat[rt].read_mode);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_SCALE_M,
-				mt9t013_regs.reg_pat[rt].scale_m);
-		if (rc < 0)
-			return rc;
-
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_X_OUTPUT_SIZE,
-				mt9t013_regs.reg_pat[rt].x_output_size);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_Y_OUTPUT_SIZE,
-				mt9t013_regs.reg_pat[rt].y_output_size);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_LINE_LENGTH_PCK,
-				mt9t013_regs.reg_pat[rt].line_length_pck);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-			REG_FRAME_LENGTH_LINES,
-			(mt9t013_regs.reg_pat[rt].frame_length_lines *
-			mt9t013_ctrl->fps_divider / 0x00000400));
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-			REG_COARSE_INT_TIME,
-			mt9t013_regs.reg_pat[rt].coarse_int_time);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-			REG_FINE_INT_TIME,
-			mt9t013_regs.reg_pat[rt].fine_int_time);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-			REG_GROUPED_PARAMETER_HOLD,
-			GROUPED_PARAMETER_UPDATE);
-		if (rc < 0)
-			return rc;
-
-		rc = mt9t013_test(mt9t013_ctrl->set_test);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-			MT9T013_REG_RESET_REGISTER,
-			MT9T013_RESET_REGISTER_PWON|
-			MT9T013_RESET_FAST_TRANSITION);
-		if (rc < 0)
-			return rc;
-
-		mdelay(5);
-
-		return rc;
-	}
-	}
-		break;
-
-	/*CAMSENSOR_REG_UPDATE_PERIODIC */
-	case REG_INIT: {
-	if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				MT9T013_REG_RESET_REGISTER,
-				MT9T013_RESET_REGISTER_PWOFF);
-		if (rc < 0)
-			/* MODE_SELECT, stop streaming */
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_VT_PIX_CLK_DIV,
-				mt9t013_regs.reg_pat[rt].vt_pix_clk_div);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_VT_SYS_CLK_DIV,
-				mt9t013_regs.reg_pat[rt].vt_sys_clk_div);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_PRE_PLL_CLK_DIV,
-				mt9t013_regs.reg_pat[rt].pre_pll_clk_div);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_PLL_MULTIPLIER,
-				mt9t013_regs.reg_pat[rt].pll_multiplier);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_OP_PIX_CLK_DIV,
-				mt9t013_regs.reg_pat[rt].op_pix_clk_div);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_OP_SYS_CLK_DIV,
-				mt9t013_regs.reg_pat[rt].op_sys_clk_div);
-		if (rc < 0)
-			return rc;
-
-		mdelay(5);
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_GROUPED_PARAMETER_HOLD,
-				GROUPED_PARAMETER_HOLD);
-		if (rc < 0)
-			return rc;
-
-		/* additional power saving mode ok around 38.2MHz */
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				0x3084, 0x2409);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				0x3092, 0x0A49);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				0x3094, 0x4949);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				0x3096, 0x4949);
-		if (rc < 0)
-			return rc;
-
-		/* Set preview or snapshot mode */
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_ROW_SPEED,
-				mt9t013_regs.reg_pat[rt].row_speed);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_X_ADDR_START,
-				mt9t013_regs.reg_pat[rt].x_addr_start);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_X_ADDR_END,
-				mt9t013_regs.reg_pat[rt].x_addr_end);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_Y_ADDR_START,
-				mt9t013_regs.reg_pat[rt].y_addr_start);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_Y_ADDR_END,
-				mt9t013_regs.reg_pat[rt].y_addr_end);
-		if (rc < 0)
-			return rc;
-
-		if (machine_is_sapphire()) {
-			if (rt == 0)
-				rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-					REG_READ_MODE,
-					0x046F);
-			else
-				rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-					REG_READ_MODE,
-					0x0027);
-		} else
-			rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-					REG_READ_MODE,
-					mt9t013_regs.reg_pat[rt].read_mode);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_SCALE_M,
-				mt9t013_regs.reg_pat[rt].scale_m);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_X_OUTPUT_SIZE,
-				mt9t013_regs.reg_pat[rt].x_output_size);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_Y_OUTPUT_SIZE,
-				mt9t013_regs.reg_pat[rt].y_output_size);
-		if (rc < 0)
-			return 0;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_LINE_LENGTH_PCK,
-				mt9t013_regs.reg_pat[rt].line_length_pck);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_FRAME_LENGTH_LINES,
-				mt9t013_regs.reg_pat[rt].frame_length_lines);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_COARSE_INT_TIME,
-				mt9t013_regs.reg_pat[rt].coarse_int_time);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_FINE_INT_TIME,
-				mt9t013_regs.reg_pat[rt].fine_int_time);
-		if (rc < 0)
-			return rc;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_GROUPED_PARAMETER_HOLD,
-				GROUPED_PARAMETER_UPDATE);
-			if (rc < 0)
-				return rc;
-
-		/* load lens shading */
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_GROUPED_PARAMETER_HOLD,
-				GROUPED_PARAMETER_HOLD);
-		if (rc < 0)
-			return rc;
-
-		/* most likely needs to be written only once. */
-		rc = mt9t013_set_lc();
-		if (rc < 0)
-			return -EBUSY;
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_GROUPED_PARAMETER_HOLD,
-				GROUPED_PARAMETER_UPDATE);
-		if (rc < 0)
-			return rc;
-
-		rc = mt9t013_test(mt9t013_ctrl->set_test);
-		if (rc < 0)
-			return rc;
-
-		mdelay(5);
-
-		rc =
-			mt9t013_i2c_write_w(mt9t013_client->addr,
-				MT9T013_REG_RESET_REGISTER,
-				MT9T013_RESET_REGISTER_PWON);
-		if (rc < 0)
-			/* MODE_SELECT, stop streaming */
-			return rc;
-
-		CDBG("!!! mt9t013 !!! PowerOn is done!\n");
-		mdelay(5);
-		return rc;
-		}
-	} /* case CAMSENSOR_REG_INIT: */
-	break;
-
-	/*CAMSENSOR_REG_INIT */
-	default:
-		rc = -EINVAL;
-		break;
-	} /* switch (rupdate) */
-
-	return rc;
-}
-
-static int32_t mt9t013_video_config(int mode, int res)
-{
-	int32_t rc;
-
-	switch (res) {
-	case QTR_SIZE:
-		rc = mt9t013_setting(UPDATE_PERIODIC, RES_PREVIEW);
-		if (rc < 0)
-			return rc;
-		CDBG("sensor configuration done!\n");
-		break;
-
-	case FULL_SIZE:
-		rc = mt9t013_setting(UPDATE_PERIODIC, RES_CAPTURE);
-		if (rc < 0)
-			return rc;
-		break;
-
-	default:
-		return -EINVAL;
-	} /* switch */
-
-	mt9t013_ctrl->prev_res = res;
-	mt9t013_ctrl->curr_res = res;
-	mt9t013_ctrl->sensormode = mode;
-
-	rc = mt9t013_write_exp_gain(mt9t013_ctrl->my_reg_gain,
-			mt9t013_ctrl->my_reg_line_count);
-	if (rc < 0)
-		return rc;
-
-	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-		MT9T013_REG_RESET_REGISTER,
-		MT9T013_RESET_REGISTER_PWON|MT9T013_RESET_FAST_TRANSITION);
-	if (rc < 0)
-		return rc;
-
-	msleep(5);
-	return rc;
-}
-
-static int32_t mt9t013_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-
-	rc = mt9t013_setting(UPDATE_PERIODIC, RES_CAPTURE);
-	if (rc < 0)
-		return rc;
-
-	mt9t013_ctrl->curr_res = mt9t013_ctrl->pict_res;
-	mt9t013_ctrl->sensormode = mode;
-	return rc;
-}
-
-static int32_t mt9t013_raw_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-
-	rc = mt9t013_setting(UPDATE_PERIODIC, RES_CAPTURE);
-	if (rc < 0)
-		return rc;
-
-	mt9t013_ctrl->curr_res = mt9t013_ctrl->pict_res;
-	mt9t013_ctrl->sensormode = mode;
-	return rc;
-}
-
-static int32_t mt9t013_power_down(void)
-{
-	int32_t rc = 0;
-
-	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-			MT9T013_REG_RESET_REGISTER,
-			MT9T013_RESET_REGISTER_PWOFF);
-	if (rc >= 0)
-		mdelay(5);
-	return rc;
-}
-
-static int32_t mt9t013_move_focus(int direction, int32_t num_steps)
-{
-	int16_t step_direction;
-	int16_t actual_step;
-	int16_t next_position;
-	int16_t break_steps[4];
-	uint8_t code_val_msb, code_val_lsb;
-	int16_t i;
-
-	if (num_steps > MT9T013_TOTAL_STEPS_NEAR_TO_FAR)
-		num_steps = MT9T013_TOTAL_STEPS_NEAR_TO_FAR;
-	else if (num_steps == 0)
-		return -EINVAL;
-
-	if (direction == MOVE_NEAR)
-		step_direction = 4;
-	else if (direction == MOVE_FAR)
-		step_direction = -4;
-	else
-		return -EINVAL;
-
-	if (mt9t013_ctrl->curr_lens_pos < mt9t013_ctrl->init_curr_lens_pos)
-		mt9t013_ctrl->curr_lens_pos = mt9t013_ctrl->init_curr_lens_pos;
-
-	actual_step =
-		(int16_t) (step_direction *
-		(int16_t) num_steps);
-
-	for (i = 0; i < 4; i++)
-		break_steps[i] =
-			actual_step / 4 * (i + 1) - actual_step / 4 * i;
-
-	for (i = 0; i < 4; i++) {
-		next_position =
-		(int16_t)
-		(mt9t013_ctrl->curr_lens_pos + break_steps[i]);
-
-		if (next_position > 255)
-			next_position = 255;
-		else if (next_position < 0)
-			next_position = 0;
-
-		code_val_msb =
-		((next_position >> 4) << 2) |
-		((next_position << 4) >> 6);
-
-		code_val_lsb =
-		((next_position & 0x03) << 6);
-
-		/* Writing the digital code for current to the actuator */
-		if (mt9t013_i2c_write_b(MT9T013_AF_I2C_ADDR>>1,
-				code_val_msb, code_val_lsb) < 0)
-			return -EBUSY;
-
-		/* Storing the current lens Position */
-		mt9t013_ctrl->curr_lens_pos = next_position;
-
-		if (i < 3)
-			mdelay(1);
-	} /* for */
-
-	return 0;
-}
-
-static int mt9t013_sensor_init_done(const struct msm_camera_sensor_info *data)
-{
-	gpio_direction_output(data->sensor_reset, 0);
-	gpio_free(data->sensor_reset);
-	return 0;
-}
-
-static int mt9t013_probe_init_sensor(const struct msm_camera_sensor_info *data)
-{
-	int rc;
-	uint16_t chipid;
-
-	rc = gpio_request(data->sensor_reset, "mt9t013");
-	if (!rc)
-		gpio_direction_output(data->sensor_reset, 1);
-	else
-		goto init_probe_done;
-
-	mdelay(20);
-
-	/* RESET the sensor image part via I2C command */
-	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-		MT9T013_REG_RESET_REGISTER, 0x1009);
-	if (rc < 0)
-		goto init_probe_fail;
-
-	msleep(10);
-
-	/* 3. Read sensor Model ID: */
-	rc = mt9t013_i2c_read_w(mt9t013_client->addr,
-		MT9T013_REG_MODEL_ID, &chipid);
-
-	if (rc < 0)
-		goto init_probe_fail;
-
-	CDBG("mt9t013 model_id = 0x%x\n", chipid);
-
-	/* 4. Compare sensor ID to MT9T012VC ID: */
-	if (chipid != MT9T013_MODEL_ID) {
-		rc = -ENODEV;
-		goto init_probe_fail;
-	}
-
-	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-		0x3064, 0x0805);
-	if (rc < 0)
-		goto init_probe_fail;
-
-	mdelay(MT9T013_RESET_DELAY_MSECS);
-
-	goto init_probe_done;
-
-	/* sensor: output enable */
-#if 0
-	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-		MT9T013_REG_RESET_REGISTER,
-		MT9T013_RESET_REGISTER_PWON);
-
-	/* if this fails, the sensor is not the MT9T013 */
-	rc = mt9t013_set_default_focus(0);
-#endif
-
-init_probe_fail:
-	gpio_direction_output(data->sensor_reset, 0);
-	gpio_free(data->sensor_reset);
-init_probe_done:
-	return rc;
-}
-
-static int32_t mt9t013_poweron_af(void)
-{
-	int32_t rc = 0;
-
-	/* enable AF actuator */
-	CDBG("enable AF actuator, gpio = %d\n",
-			mt9t013_ctrl->sensordata->vcm_pwd);
-	rc = gpio_request(mt9t013_ctrl->sensordata->vcm_pwd, "mt9t013");
-	if (!rc) {
-		gpio_direction_output(mt9t013_ctrl->sensordata->vcm_pwd, 0);
-		mdelay(20);
-		rc = mt9t013_set_default_focus(0);
-	} else
-		pr_err("%s, gpio_request failed (%d)!\n", __func__, rc);
-	return rc;
-}
-
-static void mt9t013_poweroff_af(void)
-{
-	gpio_direction_output(mt9t013_ctrl->sensordata->vcm_pwd, 1);
-	gpio_free(mt9t013_ctrl->sensordata->vcm_pwd);
-}
-
-int mt9t013_sensor_open_init(const struct msm_camera_sensor_info *data)
-{
-	int32_t  rc;
-
-	mt9t013_ctrl = kzalloc(sizeof(struct mt9t013_ctrl), GFP_KERNEL);
-	if (!mt9t013_ctrl) {
-		pr_err("mt9t013_init failed!\n");
-		rc = -ENOMEM;
-		goto init_done;
-	}
-
-	mt9t013_ctrl->fps_divider = 1 * 0x00000400;
-	mt9t013_ctrl->pict_fps_divider = 1 * 0x00000400;
-	mt9t013_ctrl->set_test = TEST_OFF;
-	mt9t013_ctrl->prev_res = QTR_SIZE;
-	mt9t013_ctrl->pict_res = FULL_SIZE;
-
-	if (data)
-		mt9t013_ctrl->sensordata = data;
-
-	/* enable mclk first */
-	msm_camio_clk_rate_set(MT9T013_DEFAULT_CLOCK_RATE);
-	mdelay(20);
-
-	msm_camio_camif_pad_reg_reset();
-	mdelay(20);
-
-	rc = mt9t013_probe_init_sensor(data);
-	if (rc < 0)
-		goto init_fail;
-
-	if (mt9t013_ctrl->prev_res == QTR_SIZE)
-		rc = mt9t013_setting(REG_INIT, RES_PREVIEW);
-	else
-		rc = mt9t013_setting(REG_INIT, RES_CAPTURE);
-
-	if (rc >= 0)
-		if (machine_is_sapphire())
-			rc = mt9t013_poweron_af();
-
-	if (rc < 0)
-		goto init_fail;
-	else
-		goto init_done;
-
-init_fail:
-	kfree(mt9t013_ctrl);
-init_done:
-	return rc;
-}
-
-static int mt9t013_init_client(struct i2c_client *client)
-{
-	/* Initialize the MSM_CAMI2C Chip */
-	init_waitqueue_head(&mt9t013_wait_queue);
-	return 0;
-}
-
-
-static int32_t mt9t013_set_sensor_mode(int mode, int res)
-{
-	int32_t rc = 0;
-	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-			REG_GROUPED_PARAMETER_HOLD,
-			GROUPED_PARAMETER_HOLD);
-	if (rc < 0)
-		return rc;
-
-	switch (mode) {
-	case SENSOR_PREVIEW_MODE:
-		rc = mt9t013_video_config(mode, res);
-		break;
-
-	case SENSOR_SNAPSHOT_MODE:
-		rc = mt9t013_snapshot_config(mode);
-		break;
-
-	case SENSOR_RAW_SNAPSHOT_MODE:
-		rc = mt9t013_raw_snapshot_config(mode);
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	/* FIXME: what should we do if rc < 0? */
-	if (rc >= 0)
-		return mt9t013_i2c_write_w(mt9t013_client->addr,
-				REG_GROUPED_PARAMETER_HOLD,
-				GROUPED_PARAMETER_UPDATE);
-	return rc;
-}
-
-int mt9t013_sensor_config(void __user *argp)
-{
-	struct sensor_cfg_data cdata;
-	long   rc = 0;
-
-	if (copy_from_user(&cdata, (void *)argp,
-			sizeof(struct sensor_cfg_data)))
-		return -EFAULT;
-
-	down(&mt9t013_sem);
-
-	CDBG("mt9t013_sensor_config: cfgtype = %d\n", cdata.cfgtype);
-	switch (cdata.cfgtype) {
-	case CFG_GET_PICT_FPS:
-		mt9t013_get_pict_fps(cdata.cfg.gfps.prevfps,
-				&(cdata.cfg.gfps.pictfps));
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PREV_L_PF:
-		cdata.cfg.prevl_pf = mt9t013_get_prev_lines_pf();
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PREV_P_PL:
-		cdata.cfg.prevp_pl = mt9t013_get_prev_pixels_pl();
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PICT_L_PF:
-		cdata.cfg.pictl_pf = mt9t013_get_pict_lines_pf();
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PICT_P_PL:
-		cdata.cfg.pictp_pl =
-			mt9t013_get_pict_pixels_pl();
-
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PICT_MAX_EXP_LC:
-		cdata.cfg.pict_max_exp_lc =
-			mt9t013_get_pict_max_exp_lc();
-
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_SET_FPS:
-	case CFG_SET_PICT_FPS:
-		rc = mt9t013_set_fps(&(cdata.cfg.fps));
-		break;
-
-	case CFG_SET_EXP_GAIN:
-		rc = mt9t013_write_exp_gain(cdata.cfg.exp_gain.gain,
-				cdata.cfg.exp_gain.line);
-		break;
-
-	case CFG_SET_PICT_EXP_GAIN:
-		rc = mt9t013_set_pict_exp_gain(cdata.cfg.exp_gain.gain,
-				cdata.cfg.exp_gain.line);
-		break;
-
-	case CFG_SET_MODE:
-		rc = mt9t013_set_sensor_mode(cdata.mode, cdata.rs);
-		break;
-
-	case CFG_PWR_DOWN:
-		rc = mt9t013_power_down();
-		break;
-
-	case CFG_MOVE_FOCUS:
-		rc = mt9t013_move_focus(cdata.cfg.focus.dir,
-				cdata.cfg.focus.steps);
-		break;
-
-	case CFG_SET_DEFAULT_FOCUS:
-		rc = mt9t013_set_default_focus(cdata.cfg.focus.steps);
-		break;
-
-	case CFG_GET_AF_MAX_STEPS:
-		cdata.max_steps = MT9T013_TOTAL_STEPS_NEAR_TO_FAR;
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_SET_EFFECT:
-	default:
-		rc = -EINVAL;
-		break;
-	}
-
-	up(&mt9t013_sem);
-	return rc;
-}
-
-int mt9t013_sensor_release(void)
-{
-	int rc = -EBADF;
-
-	down(&mt9t013_sem);
-
-	if (machine_is_sapphire())
-		mt9t013_poweroff_af();
-	mt9t013_power_down();
-
-	gpio_direction_output(mt9t013_ctrl->sensordata->sensor_reset,
-			0);
-	gpio_free(mt9t013_ctrl->sensordata->sensor_reset);
-
-	kfree(mt9t013_ctrl);
-
-	up(&mt9t013_sem);
-	CDBG("mt9t013_release completed!\n");
-	return rc;
-}
-
-static int mt9t013_i2c_probe(struct i2c_client *client,
-	const struct i2c_device_id *id)
-{
-	int rc = 0;
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		rc = -ENOTSUPP;
-		goto probe_failure;
-	}
-
-	mt9t013_sensorw =
-		kzalloc(sizeof(struct mt9t013_work), GFP_KERNEL);
-
-	if (!mt9t013_sensorw) {
-		rc = -ENOMEM;
-		goto probe_failure;
-	}
-
-	i2c_set_clientdata(client, mt9t013_sensorw);
-	mt9t013_init_client(client);
-	mt9t013_client = client;
-	mt9t013_client->addr = mt9t013_client->addr >> 1;
-	mdelay(50);
-
-	CDBG("i2c probe ok\n");
-	return 0;
-
-probe_failure:
-	kfree(mt9t013_sensorw);
-	mt9t013_sensorw = NULL;
-	pr_err("i2c probe failure %d\n", rc);
-	return rc;
-}
-
-static const struct i2c_device_id mt9t013_i2c_id[] = {
-	{ "mt9t013", 0},
-	{ }
-};
-
-static struct i2c_driver mt9t013_i2c_driver = {
-	.id_table = mt9t013_i2c_id,
-	.probe  = mt9t013_i2c_probe,
-	.remove = __exit_p(mt9t013_i2c_remove),
-	.driver = {
-		.name = "mt9t013",
-	},
-};
-
-static int mt9t013_sensor_probe(
-		const struct msm_camera_sensor_info *info,
-		struct msm_sensor_ctrl *s)
-{
-	/* We expect this driver to match with the i2c device registered
-	 * in the board file immediately. */
-	int rc = i2c_add_driver(&mt9t013_i2c_driver);
-	if (rc < 0 || mt9t013_client == NULL) {
-		rc = -ENOTSUPP;
-		goto probe_done;
-	}
-
-	/* enable mclk first */
-	msm_camio_clk_rate_set(MT9T013_DEFAULT_CLOCK_RATE);
-	mdelay(20);
-
-	rc = mt9t013_probe_init_sensor(info);
-	if (rc < 0) {
-		i2c_del_driver(&mt9t013_i2c_driver);
-		goto probe_done;
-	}
-
-	s->s_init = mt9t013_sensor_open_init;
-	s->s_release = mt9t013_sensor_release;
-	s->s_config  = mt9t013_sensor_config;
-	s->s_mount_angle = 0;
-	mt9t013_sensor_init_done(info);
-
-probe_done:
-	return rc;
-}
-
-static int __mt9t013_probe(struct platform_device *pdev)
-{
-	return msm_camera_drv_start(pdev, mt9t013_sensor_probe);
-}
-
-static struct platform_driver msm_camera_driver = {
-	.probe = __mt9t013_probe,
-	.driver = {
-		.name = "msm_camera_mt9t013",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init mt9t013_init(void)
-{
-	return platform_driver_register(&msm_camera_driver);
-}
-
-module_init(mt9t013_init);
diff --git a/drivers/media/video/msm/mt9t013.h b/drivers/media/video/msm/mt9t013.h
deleted file mode 100644
index 6afcb2d..0000000
--- a/drivers/media/video/msm/mt9t013.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. 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 MT9T013_H
-#define MT9T013_H
-
-#include <linux/types.h>
-#include <mach/board.h>
-
-extern struct mt9t013_reg mt9t013_regs; /* from mt9t013_reg.c */
-
-struct reg_struct {
-	uint16_t vt_pix_clk_div;        /*  0x0300 */
-	uint16_t vt_sys_clk_div;        /*  0x0302 */
-	uint16_t pre_pll_clk_div;       /*  0x0304 */
-	uint16_t pll_multiplier;        /*  0x0306 */
-	uint16_t op_pix_clk_div;        /*  0x0308 */
-	uint16_t op_sys_clk_div;        /*  0x030A */
-	uint16_t scale_m;               /*  0x0404 */
-	uint16_t row_speed;             /*  0x3016 */
-	uint16_t x_addr_start;          /*  0x3004 */
-	uint16_t x_addr_end;            /*  0x3008 */
-	uint16_t y_addr_start;        	/*  0x3002 */
-	uint16_t y_addr_end;            /*  0x3006 */
-	uint16_t read_mode;             /*  0x3040 */
-	uint16_t x_output_size;         /*  0x034C */
-	uint16_t y_output_size;         /*  0x034E */
-	uint16_t line_length_pck;       /*  0x300C */
-	uint16_t frame_length_lines;	/*  0x300A */
-	uint16_t coarse_int_time; 		/*  0x3012 */
-	uint16_t fine_int_time;   		/*  0x3014 */
-};
-
-struct mt9t013_i2c_reg_conf {
-	unsigned short waddr;
-	unsigned short wdata;
-};
-
-struct mt9t013_reg {
-	struct reg_struct const *reg_pat;
-	uint16_t reg_pat_size;
-	struct mt9t013_i2c_reg_conf const *ttbl;
-	uint16_t ttbl_size;
-	struct mt9t013_i2c_reg_conf const *lctbl;
-	uint16_t lctbl_size;
-	struct mt9t013_i2c_reg_conf const *rftbl;
-	uint16_t rftbl_size;
-};
-
-#endif /* #define MT9T013_H */
diff --git a/drivers/media/video/msm/mt9t013_reg.c b/drivers/media/video/msm/mt9t013_reg.c
deleted file mode 100644
index 9a9867e..0000000
--- a/drivers/media/video/msm/mt9t013_reg.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/* Copyright (c) 2009, Code Aurora Forum. 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 "mt9t013.h"
-#include <linux/kernel.h>
-
-struct reg_struct const mt9t013_reg_pat[2] = {
-	{ /* Preview 2x2 binning 20fps, pclk MHz, MCLK 24MHz */
-	/* vt_pix_clk_div:REG=0x0300 update get_snapshot_fps
-	* if this change */
-	8,
-
-	/* vt_sys_clk_div: REG=0x0302  update get_snapshot_fps
-	* if this change */
-	1,
-
-	/* pre_pll_clk_div REG=0x0304  update get_snapshot_fps
-	* if this change */
-	2,
-
-	/* pll_multiplier  REG=0x0306 60 for 30fps preview, 40
-	 * for 20fps preview
-	 * 46 for 30fps preview, try 47/48 to increase further */
-	46,
-
-	/* op_pix_clk_div        REG=0x0308 */
-	8,
-
-	/* op_sys_clk_div        REG=0x030A */
-	1,
-
-	/* scale_m       REG=0x0404 */
-	16,
-
-	/* row_speed     REG=0x3016 */
-	0x0111,
-
-	/* x_addr_start  REG=0x3004 */
-	8,
-
-	/* x_addr_end    REG=0x3008 */
-	2053,
-
-	/* y_addr_start  REG=0x3002 */
-	8,
-
-	/* y_addr_end    REG=0x3006 */
-	1541,
-
-	/* read_mode     REG=0x3040 */
-	0x046C,
-
-	/* x_output_size REG=0x034C */
-	1024,
-
-	/* y_output_size REG=0x034E */
-	768,
-
-	/* line_length_pck    REG=0x300C */
-	2616,
-
-	/* frame_length_lines REG=0x300A */
-	916,
-
-	/* coarse_int_time REG=0x3012 */
-	16,
-
-	/* fine_int_time   REG=0x3014 */
-	1461
-	},
-	{ /*Snapshot */
-	/* vt_pix_clk_div  REG=0x0300 update get_snapshot_fps
-	* if this change */
-	8,
-
-	/* vt_sys_clk_div  REG=0x0302 update get_snapshot_fps
-	* if this change */
-	1,
-
-	/* pre_pll_clk_div REG=0x0304 update get_snapshot_fps
-	 * if this change */
-	2,
-
-	/* pll_multiplier REG=0x0306 50 for 15fps snapshot,
-	 * 40 for 10fps snapshot
-	 * 46 for 30fps snapshot, try 47/48 to increase further */
-	46,
-
-	/* op_pix_clk_div        REG=0x0308 */
-	8,
-
-	/* op_sys_clk_div        REG=0x030A */
-	1,
-
-	/* scale_m       REG=0x0404 */
-	16,
-
-	/* row_speed     REG=0x3016 */
-	0x0111,
-
-	/* x_addr_start  REG=0x3004 */
-	8,
-
-	/* x_addr_end    REG=0x3008 */
-	2071,
-
-	/* y_addr_start  REG=0x3002 */
-	8,
-
-	/* y_addr_end    REG=0x3006 */
-	1551,
-
-	/* read_mode     REG=0x3040 */
-	0x0024,
-
-	/* x_output_size REG=0x034C */
-	2064,
-
-	/* y_output_size REG=0x034E */
-	1544,
-
-	/* line_length_pck REG=0x300C */
-	2952,
-
-	/* frame_length_lines    REG=0x300A */
-	1629,
-
-	/* coarse_int_time REG=0x3012 */
-	16,
-
-	/* fine_int_time REG=0x3014   */
-	733
-	}
-};
-
-struct mt9t013_i2c_reg_conf const mt9t013_test_tbl[] = {
-	{ 0x3044, 0x0544 & 0xFBFF },
-	{ 0x30CA, 0x0004 | 0x0001 },
-	{ 0x30D4, 0x9020 & 0x7FFF },
-	{ 0x31E0, 0x0003 & 0xFFFE },
-	{ 0x3180, 0x91FF & 0x7FFF },
-	{ 0x301A, (0x10CC | 0x8000) & 0xFFF7 },
-	{ 0x301E, 0x0000 },
-	{ 0x3780, 0x0000 },
-};
-
-/* [Lens shading 85 Percent TL84] */
-struct mt9t013_i2c_reg_conf const mt9t013_lc_tbl[] = {
-	{ 0x360A, 0x0290 }, /* P_RD_P0Q0 */
-	{ 0x360C, 0xC92D }, /* P_RD_P0Q1 */
-	{ 0x360E, 0x0771 }, /* P_RD_P0Q2 */
-	{ 0x3610, 0xE38C }, /* P_RD_P0Q3 */
-	{ 0x3612, 0xD74F }, /* P_RD_P0Q4 */
-	{ 0x364A, 0x168C }, /* P_RD_P1Q0 */
-	{ 0x364C, 0xCACB }, /* P_RD_P1Q1 */
-	{ 0x364E, 0x8C4C }, /* P_RD_P1Q2 */
-	{ 0x3650, 0x0BEA }, /* P_RD_P1Q3 */
-	{ 0x3652, 0xDC0F }, /* P_RD_P1Q4 */
-	{ 0x368A, 0x70B0 }, /* P_RD_P2Q0 */
-	{ 0x368C, 0x200B }, /* P_RD_P2Q1 */
-	{ 0x368E, 0x30B2 }, /* P_RD_P2Q2 */
-	{ 0x3690, 0xD04F }, /* P_RD_P2Q3 */
-	{ 0x3692, 0xACF5 }, /* P_RD_P2Q4 */
-	{ 0x36CA, 0xF7C9 }, /* P_RD_P3Q0 */
-	{ 0x36CC, 0x2AED }, /* P_RD_P3Q1 */
-	{ 0x36CE, 0xA652 }, /* P_RD_P3Q2 */
-	{ 0x36D0, 0x8192 }, /* P_RD_P3Q3 */
-	{ 0x36D2, 0x3A15 }, /* P_RD_P3Q4 */
-	{ 0x370A, 0xDA30 }, /* P_RD_P4Q0 */
-	{ 0x370C, 0x2E2F }, /* P_RD_P4Q1 */
-	{ 0x370E, 0xBB56 }, /* P_RD_P4Q2 */
-	{ 0x3710, 0x8195 }, /* P_RD_P4Q3 */
-	{ 0x3712, 0x02F9 }, /* P_RD_P4Q4 */
-	{ 0x3600, 0x0230 }, /* P_GR_P0Q0 */
-	{ 0x3602, 0x58AD }, /* P_GR_P0Q1 */
-	{ 0x3604, 0x18D1 }, /* P_GR_P0Q2 */
-	{ 0x3606, 0x260D }, /* P_GR_P0Q3 */
-	{ 0x3608, 0xF530 }, /* P_GR_P0Q4 */
-	{ 0x3640, 0x17EB }, /* P_GR_P1Q0 */
-	{ 0x3642, 0x3CAB }, /* P_GR_P1Q1 */
-	{ 0x3644, 0x87CE }, /* P_GR_P1Q2 */
-	{ 0x3646, 0xC02E }, /* P_GR_P1Q3 */
-	{ 0x3648, 0xF48F }, /* P_GR_P1Q4 */
-	{ 0x3680, 0x5350 }, /* P_GR_P2Q0 */
-	{ 0x3682, 0x7EAF }, /* P_GR_P2Q1 */
-	{ 0x3684, 0x4312 }, /* P_GR_P2Q2 */
-	{ 0x3686, 0xC652 }, /* P_GR_P2Q3 */
-	{ 0x3688, 0xBC15 }, /* P_GR_P2Q4 */
-	{ 0x36C0, 0xB8AD }, /* P_GR_P3Q0 */
-	{ 0x36C2, 0xBDCD }, /* P_GR_P3Q1 */
-	{ 0x36C4, 0xE4B2 }, /* P_GR_P3Q2 */
-	{ 0x36C6, 0xB50F }, /* P_GR_P3Q3 */
-	{ 0x36C8, 0x5B95 }, /* P_GR_P3Q4 */
-	{ 0x3700, 0xFC90 }, /* P_GR_P4Q0 */
-	{ 0x3702, 0x8C51 }, /* P_GR_P4Q1 */
-	{ 0x3704, 0xCED6 }, /* P_GR_P4Q2 */
-	{ 0x3706, 0xB594 }, /* P_GR_P4Q3 */
-	{ 0x3708, 0x0A39 }, /* P_GR_P4Q4 */
-	{ 0x3614, 0x0230 }, /* P_BL_P0Q0 */
-	{ 0x3616, 0x160D }, /* P_BL_P0Q1 */
-	{ 0x3618, 0x08D1 }, /* P_BL_P0Q2 */
-	{ 0x361A, 0x98AB }, /* P_BL_P0Q3 */
-	{ 0x361C, 0xEA50 }, /* P_BL_P0Q4 */
-	{ 0x3654, 0xB4EA }, /* P_BL_P1Q0 */
-	{ 0x3656, 0xEA6C }, /* P_BL_P1Q1 */
-	{ 0x3658, 0xFE08 }, /* P_BL_P1Q2 */
-	{ 0x365A, 0x2C6E }, /* P_BL_P1Q3 */
-	{ 0x365C, 0xEB0E }, /* P_BL_P1Q4 */
-	{ 0x3694, 0x6DF0 }, /* P_BL_P2Q0 */
-	{ 0x3696, 0x3ACF }, /* P_BL_P2Q1 */
-	{ 0x3698, 0x3E0F }, /* P_BL_P2Q2 */
-	{ 0x369A, 0xB2B1 }, /* P_BL_P2Q3 */
-	{ 0x369C, 0xC374 }, /* P_BL_P2Q4 */
-	{ 0x36D4, 0xF2AA }, /* P_BL_P3Q0 */
-	{ 0x36D6, 0x8CCC }, /* P_BL_P3Q1 */
-	{ 0x36D8, 0xDEF2 }, /* P_BL_P3Q2 */
-	{ 0x36DA, 0xFA11 }, /* P_BL_P3Q3 */
-	{ 0x36DC, 0x42F5 }, /* P_BL_P3Q4 */
-	{ 0x3714, 0xF4F1 }, /* P_BL_P4Q0 */
-	{ 0x3716, 0xF6F0 }, /* P_BL_P4Q1 */
-	{ 0x3718, 0x8FD6 }, /* P_BL_P4Q2 */
-	{ 0x371A, 0xEA14 }, /* P_BL_P4Q3 */
-	{ 0x371C, 0x6338 }, /* P_BL_P4Q4 */
-	{ 0x361E, 0x0350 }, /* P_GB_P0Q0 */
-	{ 0x3620, 0x91AE }, /* P_GB_P0Q1 */
-	{ 0x3622, 0x0571 }, /* P_GB_P0Q2 */
-	{ 0x3624, 0x100D }, /* P_GB_P0Q3 */
-	{ 0x3626, 0xCA70 }, /* P_GB_P0Q4 */
-	{ 0x365E, 0xE6CB }, /* P_GB_P1Q0 */
-	{ 0x3660, 0x50ED }, /* P_GB_P1Q1 */
-	{ 0x3662, 0x3DAE }, /* P_GB_P1Q2 */
-	{ 0x3664, 0xAA4F }, /* P_GB_P1Q3 */
-	{ 0x3666, 0xDC50 }, /* P_GB_P1Q4 */
-	{ 0x369E, 0x5470 }, /* P_GB_P2Q0 */
-	{ 0x36A0, 0x1F6E }, /* P_GB_P2Q1 */
-	{ 0x36A2, 0x6671 }, /* P_GB_P2Q2 */
-	{ 0x36A4, 0xC010 }, /* P_GB_P2Q3 */
-	{ 0x36A6, 0x8DF5 }, /* P_GB_P2Q4 */
-	{ 0x36DE, 0x0B0C }, /* P_GB_P3Q0 */
-	{ 0x36E0, 0x84CE }, /* P_GB_P3Q1 */
-	{ 0x36E2, 0x8493 }, /* P_GB_P3Q2 */
-	{ 0x36E4, 0xA610 }, /* P_GB_P3Q3 */
-	{ 0x36E6, 0x50B5 }, /* P_GB_P3Q4 */
-	{ 0x371E, 0x9651 }, /* P_GB_P4Q0 */
-	{ 0x3720, 0x1EAB }, /* P_GB_P4Q1 */
-	{ 0x3722, 0xAF76 }, /* P_GB_P4Q2 */
-	{ 0x3724, 0xE4F4 }, /* P_GB_P4Q3 */
-	{ 0x3726, 0x79F8 }, /* P_GB_P4Q4 */
-	{ 0x3782, 0x0410 }, /* POLY_ORIGIN_C */
-	{ 0x3784, 0x0320 }, /* POLY_ORIGIN_R  */
-	{ 0x3780, 0x8000 } /* POLY_SC_ENABLE */
-};
-
-struct mt9t013_reg mt9t013_regs = {
-	.reg_pat = &mt9t013_reg_pat[0],
-	.reg_pat_size = ARRAY_SIZE(mt9t013_reg_pat),
-	.ttbl = &mt9t013_test_tbl[0],
-	.ttbl_size = ARRAY_SIZE(mt9t013_test_tbl),
-	.lctbl = &mt9t013_lc_tbl[0],
-	.lctbl_size = ARRAY_SIZE(mt9t013_lc_tbl),
-	.rftbl = &mt9t013_lc_tbl[0],	/* &mt9t013_rolloff_tbl[0], */
-	.rftbl_size = ARRAY_SIZE(mt9t013_lc_tbl)
-};
-
-
diff --git a/drivers/media/video/msm/ov5640.c b/drivers/media/video/msm/ov5640.c
deleted file mode 100644
index 1380bcf..0000000
--- a/drivers/media/video/msm/ov5640.c
+++ /dev/null
@@ -1,1477 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. 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/delay.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/leds.h>
-#include <linux/slab.h>
-#include <media/msm_camera.h>
-#include <mach/gpio.h>
-#include <mach/camera.h>
-#include "ov5640.h"
-
-#define FALSE 0
-#define TRUE 1
-
-struct ov5640_work {
-	struct work_struct work;
-};
-
-struct __ov5640_ctrl {
-	const struct msm_camera_sensor_info *sensordata;
-	int sensormode;
-	uint fps_divider; /* init to 1 * 0x00000400 */
-	uint pict_fps_divider; /* init to 1 * 0x00000400 */
-	u16 curr_step_pos;
-	u16 curr_lens_pos;
-	u16 init_curr_lens_pos;
-	u16 my_reg_gain;
-	u16 my_reg_line_count;
-	enum msm_s_resolution prev_res;
-	enum msm_s_resolution pict_res;
-	enum msm_s_resolution curr_res;
-	enum msm_s_test_mode  set_test;
-};
-
-static DECLARE_WAIT_QUEUE_HEAD(ov5640_wait_queue);
-DEFINE_MUTEX(ov5640_mutex);
-
-static int ov5640_pwdn_gpio;
-static int ov5640_reset_gpio;
-static int ov5640_driver_pwdn_gpio;
-static int OV5640_CSI_CONFIG;
-static struct ov5640_work *ov5640_sensorw;
-static struct i2c_client    *ov5640_client;
-static u8 ov5640_i2c_buf[4];
-static u8 ov5640_counter;
-static int16_t ov5640_effect;
-static int is_autoflash;
-static int effect_value;
-unsigned int ov5640_SAT_U = 0x40;
-unsigned int ov5640_SAT_V = 0x40;
-
-static struct __ov5640_ctrl *ov5640_ctrl;
-static int ov5640_afinit = 1;
-
-struct rw_semaphore ov_leds_list_lock;
-struct list_head ov_leds_list;
-
-static int ov5640_i2c_remove(struct i2c_client *client);
-static int ov5640_i2c_probe(struct i2c_client *client,
-		const struct i2c_device_id *id);
-
-static int ov5640_i2c_txdata(u16 saddr, u8 *txdata, int length)
-{
-	struct i2c_msg msg[] = {
-		{
-			.addr	= saddr,
-			.flags	= 0,
-			.len	= length,
-			.buf	= txdata,
-		},
-	};
-
-	if (i2c_transfer(ov5640_client->adapter, msg, 1) < 0)
-		return -EIO;
-	else
-		return 0;
-}
-
-static int ov5640_i2c_write(unsigned short saddr, unsigned int waddr,
-		unsigned short bdata, u8 trytimes)
-{
-	int rc = -EIO;
-
-	ov5640_counter = 0;
-	ov5640_i2c_buf[0] = (waddr & 0xFF00) >> 8;
-	ov5640_i2c_buf[1] = (waddr & 0x00FF);
-	ov5640_i2c_buf[2] = (bdata & 0x00FF);
-
-	while ((ov5640_counter < trytimes) && (rc != 0)) {
-		rc = ov5640_i2c_txdata(saddr, ov5640_i2c_buf, 3);
-
-		if (rc < 0) {
-			ov5640_counter++;
-			CDBG("***--CAMERA i2c_write_w failed,i2c addr=0x%x,"
-				"command addr = 0x%x, val = 0x%x,s=%d,"
-					"rc=%d!\n", saddr, waddr, bdata,
-					ov5640_counter, rc);
-			msleep(20);
-		}
-	}
-	return rc;
-}
-
-static int ov5640_i2c_rxdata(unsigned short saddr, unsigned char *rxdata,
-		int length)
-{
-	struct i2c_msg msgs[] = {
-		{
-			.addr	= saddr,
-			.flags	= 0,
-			.len	= 2,
-			.buf	= rxdata,
-		},
-		{
-			.addr	= saddr,
-			.flags	= I2C_M_RD,
-			.len	= length,
-			.buf	= rxdata,
-		},
-	};
-
-	if (i2c_transfer(ov5640_client->adapter, msgs, 2) < 0) {
-		CDBG("ov5640_i2c_rxdata failed!\n");
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int32_t ov5640_i2c_read_byte(unsigned short  saddr,
-		unsigned int raddr, unsigned int *rdata)
-{
-	int rc = 0;
-	unsigned char buf[2];
-
-	memset(buf, 0, sizeof(buf));
-
-	buf[0] = (raddr & 0xFF00)>>8;
-	buf[1] = (raddr & 0x00FF);
-
-	rc = ov5640_i2c_rxdata(saddr, buf, 1);
-	if (rc < 0) {
-		CDBG("ov5640_i2c_read_byte failed!\n");
-		return rc;
-	}
-
-	*rdata = buf[0];
-
-	return rc;
-}
-
-static int32_t ov5640_writepregs(struct ov5640_sensor *ptb, int32_t len)
-{
-	int32_t i, ret = 0;
-	uint32_t regv;
-
-	for (i = 0; i < len; i++) {
-		if (0 == ptb[i].mask) {
-			ov5640_i2c_write(ov5640_client->addr, ptb[i].addr,
-					ptb[i].data, 10);
-		} else {
-			ov5640_i2c_read_byte(ov5640_client->addr, ptb[i].addr,
-					&regv);
-			regv &= ptb[i].mask;
-			regv |= (ptb[i].data & (~ptb[i].mask));
-			ov5640_i2c_write(ov5640_client->addr, ptb[i].addr,
-					regv, 10);
-		}
-	}
-	return ret;
-}
-
-static void camera_sw_power_onoff(int v)
-{
-	if (v == 0) {
-		CDBG("camera_sw_power_onoff: down\n");
-		ov5640_i2c_write(ov5640_client->addr, 0x3008, 0x42, 10);
-	} else {
-		CDBG("camera_sw_power_onoff: on\n");
-		ov5640_i2c_write(ov5640_client->addr, 0x3008, 0x02, 10);
-	}
-}
-
-static void ov5640_power_off(void)
-{
-	CDBG("--CAMERA-- %s ... (Start...)\n", __func__);
-	gpio_set_value(ov5640_pwdn_gpio, 1);
-	CDBG("--CAMERA-- %s ... (End...)\n", __func__);
-}
-
-static void ov5640_power_on(void)
-{
-	CDBG("--CAMERA-- %s ... (Start...)\n", __func__);
-	gpio_set_value(ov5640_pwdn_gpio, 0);
-	CDBG("--CAMERA-- %s ... (End...)\n", __func__);
-}
-
-static void ov5640_power_reset(void)
-{
-	CDBG("--CAMERA-- %s ... (Start...)\n", __func__);
-	gpio_set_value(ov5640_reset_gpio, 1);   /* reset camera reset pin */
-	msleep(20);
-	gpio_set_value(ov5640_reset_gpio, 0);
-	msleep(20);
-	gpio_set_value(ov5640_reset_gpio, 1);
-	msleep(20);
-
-	CDBG("--CAMERA-- %s ... (End...)\n", __func__);
-}
-
-static int ov5640_probe_readID(const struct msm_camera_sensor_info *data)
-{
-	int rc = 0;
-	u32 device_id_high = 0;
-	u32 device_id_low = 0;
-
-	CDBG("--CAMERA-- %s (Start...)\n", __func__);
-	CDBG("--CAMERA-- %s sensor poweron,begin to read ID!\n", __func__);
-
-	/* 0x300A ,sensor ID register */
-	rc = ov5640_i2c_read_byte(ov5640_client->addr, 0x300A,
-			&device_id_high);
-
-	if (rc < 0) {
-		CDBG("--CAMERA-- %s ok , readI2C failed, rc = 0x%x\r\n",
-				__func__, rc);
-		return rc;
-	}
-	CDBG("--CAMERA-- %s  readID high byte, data = 0x%x\r\n",
-			__func__, device_id_high);
-
-	/* 0x300B ,sensor ID register */
-	rc = ov5640_i2c_read_byte(ov5640_client->addr, 0x300B,
-			&device_id_low);
-	if (rc < 0) {
-		CDBG("--CAMERA-- %s ok , readI2C failed,rc = 0x%x\r\n",
-				__func__, rc);
-		return rc;
-	}
-
-	CDBG("--CAMERA-- %s  readID low byte, data = 0x%x\r\n",
-			__func__, device_id_low);
-	CDBG("--CAMERA-- %s return ID :0x%x\n", __func__,
-			(device_id_high << 8) + device_id_low);
-
-	/* 0x5640, ov5640 chip id */
-	if ((device_id_high << 8) + device_id_low != OV5640_SENSOR_ID) {
-		CDBG("--CAMERA-- %s ok , device id error, should be 0x%x\r\n",
-				__func__, OV5640_SENSOR_ID);
-		return -EINVAL;
-	} else {
-		CDBG("--CAMERA-- %s ok , device id=0x%x\n", __func__,
-				OV5640_SENSOR_ID);
-		return 0;
-	}
-}
-
-static int ov5640_af_setting(void)
-{
-	int rc = 0;
-	int lens = sizeof(ov5640_afinit_tbl) / sizeof(ov5640_afinit_tbl[0]);
-
-	CDBG("--CAMERA-- ov5640_af_setting\n");
-
-	ov5640_i2c_write(ov5640_client->addr, 0x3000, 0x20, 10);
-
-	rc = ov5640_i2c_txdata(ov5640_client->addr, ov5640_afinit_tbl, lens);
-	if (rc < 0) {
-		CDBG("--CAMERA-- AF_init failed\n");
-		return rc;
-	}
-
-	ov5640_i2c_write(ov5640_client->addr, OV5640_CMD_MAIN, 0x00, 10);
-	ov5640_i2c_write(ov5640_client->addr, OV5640_CMD_ACK, 0x00, 10);
-	ov5640_i2c_write(ov5640_client->addr, OV5640_CMD_PARA0, 0x00, 10);
-	ov5640_i2c_write(ov5640_client->addr, OV5640_CMD_PARA1, 0x00, 10);
-	ov5640_i2c_write(ov5640_client->addr, OV5640_CMD_PARA2, 0x00, 10);
-	ov5640_i2c_write(ov5640_client->addr, OV5640_CMD_PARA3, 0x00, 10);
-	ov5640_i2c_write(ov5640_client->addr, OV5640_CMD_PARA4, 0x00, 10);
-	ov5640_i2c_write(ov5640_client->addr, OV5640_CMD_FW_STATUS, 0x7f, 10);
-	ov5640_i2c_write(ov5640_client->addr, 0x3000, 0x00, 10);
-
-	return rc;
-}
-
-static int ov5640_set_flash_light(enum led_brightness brightness)
-{
-	struct led_classdev *led_cdev;
-
-	CDBG("ov5640_set_flash_light brightness = %d\n", brightness);
-
-	down_read(&ov_leds_list_lock);
-	list_for_each_entry(led_cdev, &ov_leds_list, node) {
-		if (!strncmp(led_cdev->name, "flashlight", 10))
-			break;
-	}
-	up_read(&ov_leds_list_lock);
-
-	if (led_cdev) {
-		led_brightness_set(led_cdev, brightness);
-	} else {
-		CDBG("get flashlight device failed\n");
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int ov5640_video_config(void)
-{
-	int rc = 0;
-
-	CDBG("--CAMERA-- ov5640_video_config\n");
-	CDBG("--CAMERA-- preview in, is_autoflash - 0x%x\n", is_autoflash);
-
-	/* autoflash setting */
-	if (is_autoflash == 1)
-		ov5640_set_flash_light(LED_OFF);
-
-	/* preview setting */
-	rc = OV5640CORE_WRITEPREG(ov5640_preview_tbl);
-	return rc;
-}
-
-static int ov5640_snapshot_config(void)
-{
-	int rc = 0;
-	unsigned int tmp;
-
-	CDBG("--CAMERA-- SENSOR_SNAPSHOT_MODE\n");
-	CDBG("--CAMERA-- %s, snapshot in, is_autoflash - 0x%x\n", __func__,
-			is_autoflash);
-
-	if (is_autoflash == 1) {
-		ov5640_i2c_read_byte(ov5640_client->addr, 0x350b, &tmp);
-		CDBG("--CAMERA-- GAIN VALUE : %x\n", tmp);
-		if ((tmp & 0x80) == 0)
-			ov5640_set_flash_light(LED_OFF);
-		else
-			ov5640_set_flash_light(LED_FULL);
-	}
-
-	rc = OV5640CORE_WRITEPREG(ov5640_capture_tbl);
-
-	return rc;
-}
-
-static int ov5640_setting(enum msm_s_reg_update rupdate,
-		enum msm_s_setting rt)
-{
-	int rc = -EINVAL, tmp;
-	struct msm_camera_csi_params ov5640_csi_params;
-
-	CDBG("--CAMERA-- %s (Start...), rupdate=%d\n", __func__, rupdate);
-
-	switch (rupdate) {
-	case S_UPDATE_PERIODIC:
-		if (!OV5640_CSI_CONFIG) {
-			camera_sw_power_onoff(0); /* standby */
-			msleep(20);
-
-			ov5640_csi_params.lane_cnt = 2;
-			ov5640_csi_params.data_format = CSI_8BIT;
-			ov5640_csi_params.lane_assign = 0xe4;
-			ov5640_csi_params.dpcm_scheme = 0;
-			ov5640_csi_params.settle_cnt = 0x6;
-
-			CDBG("%s: msm_camio_csi_config\n", __func__);
-
-			rc = msm_camio_csi_config(&ov5640_csi_params);
-			msleep(20);
-			camera_sw_power_onoff(1); /* on */
-			msleep(20);
-
-			OV5640_CSI_CONFIG = 1;
-
-		} else {
-			rc = 0;
-		}
-
-		if (S_RES_PREVIEW == rt)
-			rc = ov5640_video_config();
-		else if (S_RES_CAPTURE == rt)
-			rc = ov5640_snapshot_config();
-
-		break; /* UPDATE_PERIODIC */
-
-	case S_REG_INIT:
-		CDBG("--CAMERA-- S_REG_INIT (Start)\n");
-
-		rc = ov5640_i2c_write(ov5640_client->addr, 0x3103, 0x11, 10);
-		rc = ov5640_i2c_write(ov5640_client->addr, 0x3008, 0x82, 10);
-		msleep(20);
-
-		/* set sensor init setting */
-		CDBG("set sensor init setting\n");
-		rc = OV5640CORE_WRITEPREG(ov5640_init_tbl);
-		if (rc < 0) {
-			CDBG("sensor init setting failed\n");
-			break;
-		}
-
-		/* set image quality setting */
-		rc = OV5640CORE_WRITEPREG(ov5640_init_iq_tbl);
-		rc = ov5640_i2c_read_byte(ov5640_client->addr, 0x4740, &tmp);
-		CDBG("--CAMERA-- init 0x4740 value=0x%x\n", tmp);
-
-		if (tmp != 0x21) {
-			rc = ov5640_i2c_write(ov5640_client->addr, 0x4740,
-					0x21, 10);
-			msleep(20);
-			rc = ov5640_i2c_read_byte(ov5640_client->addr,
-					0x4740, &tmp);
-			CDBG("--CAMERA-- WG 0x4740 value=0x%x\n", tmp);
-		}
-
-		CDBG("--CAMERA-- AF_init: ov5640_afinit = %d\n",
-				ov5640_afinit);
-		if (ov5640_afinit == 1) {
-			rc = ov5640_af_setting();
-			if (rc < 0) {
-				CDBG("--CAMERA-- ov5640_af_setting failed\n");
-				break;
-			}
-			ov5640_afinit = 0;
-		}
-
-		/* reset fps_divider */
-		ov5640_ctrl->fps_divider = 1 * 0x0400;
-		CDBG("--CAMERA-- S_REG_INIT (End)\n");
-		break; /* case REG_INIT: */
-
-	default:
-		break;
-	} /* switch (rupdate) */
-
-	CDBG("--CAMERA-- %s (End), rupdate=%d\n", __func__, rupdate);
-
-	return rc;
-}
-
-static int ov5640_sensor_open_init(const struct msm_camera_sensor_info *data)
-{
-	int rc = -ENOMEM;
-
-	CDBG("--CAMERA-- %s\n", __func__);
-	ov5640_ctrl = kzalloc(sizeof(struct __ov5640_ctrl), GFP_KERNEL);
-	if (!ov5640_ctrl) {
-		CDBG("--CAMERA-- kzalloc ov5640_ctrl error !!\n");
-		kfree(ov5640_ctrl);
-		return rc;
-	}
-
-	ov5640_ctrl->fps_divider = 1 * 0x00000400;
-	ov5640_ctrl->pict_fps_divider = 1 * 0x00000400;
-	ov5640_ctrl->set_test = S_TEST_OFF;
-	ov5640_ctrl->prev_res = S_QTR_SIZE;
-	ov5640_ctrl->pict_res = S_FULL_SIZE;
-
-	if (data)
-		ov5640_ctrl->sensordata = data;
-
-	ov5640_power_off();
-
-	CDBG("%s: msm_camio_clk_rate_set\n", __func__);
-
-	msm_camio_clk_rate_set(24000000);
-	msleep(20);
-
-	ov5640_power_on();
-	ov5640_power_reset();
-
-	CDBG("%s: init sequence\n", __func__);
-
-	if (ov5640_ctrl->prev_res == S_QTR_SIZE)
-		rc = ov5640_setting(S_REG_INIT, S_RES_PREVIEW);
-	else
-		rc = ov5640_setting(S_REG_INIT, S_RES_CAPTURE);
-
-	if (rc < 0) {
-		CDBG("--CAMERA-- %s : ov5640_setting failed. rc = %d\n",
-				__func__, rc);
-		kfree(ov5640_ctrl);
-		return rc;
-	}
-
-	OV5640_CSI_CONFIG = 0;
-
-	CDBG("--CAMERA--re_init_sensor ok!!\n");
-	return rc;
-}
-
-static int ov5640_sensor_release(void)
-{
-	CDBG("--CAMERA--ov5640_sensor_release!!\n");
-
-	mutex_lock(&ov5640_mutex);
-
-	ov5640_power_off();
-
-	kfree(ov5640_ctrl);
-	ov5640_ctrl = NULL;
-
-	OV5640_CSI_CONFIG = 0;
-
-	mutex_unlock(&ov5640_mutex);
-	return 0;
-}
-
-static const struct i2c_device_id ov5640_i2c_id[] = {
-	{"ov5640",  0}, {}
-};
-
-static int ov5640_i2c_remove(struct i2c_client *client)
-{
-	return 0;
-}
-
-static int ov5640_init_client(struct i2c_client *client)
-{
-	/* Initialize the MSM_CAMI2C Chip */
-	init_waitqueue_head(&ov5640_wait_queue);
-	return 0;
-}
-
-static long ov5640_set_effect(int mode, int effect)
-{
-	int rc = 0;
-
-	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
-
-	switch (mode) {
-	case SENSOR_PREVIEW_MODE:
-		/* Context A Special Effects */
-		CDBG("--CAMERA-- %s ...SENSOR_PREVIEW_MODE\n", __func__);
-		break;
-
-	case SENSOR_SNAPSHOT_MODE:
-		/* Context B Special Effects */
-		CDBG("--CAMERA-- %s ...SENSOR_SNAPSHOT_MODE\n", __func__);
-		break;
-
-	default:
-		break;
-	}
-
-	effect_value = effect;
-
-	switch (effect)	{
-	case CAMERA_EFFECT_OFF:
-		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_OFF\n", __func__);
-		rc = OV5640CORE_WRITEPREG(ov5640_effect_normal_tbl);
-		/* for recover saturation level when change special effect */
-		ov5640_i2c_write(ov5640_client->addr, 0x5583, ov5640_SAT_U,
-				10);
-		/* for recover saturation level when change special effect */
-		ov5640_i2c_write(ov5640_client->addr, 0x5584, ov5640_SAT_V,
-				10);
-		break;
-
-	case CAMERA_EFFECT_MONO:
-		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_MONO\n", __func__);
-		rc = OV5640CORE_WRITEPREG(ov5640_effect_mono_tbl);
-		break;
-
-	case CAMERA_EFFECT_BW:
-		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_BW\n", __func__);
-		rc = OV5640CORE_WRITEPREG(ov5640_effect_bw_tbl);
-		break;
-
-	case CAMERA_EFFECT_BLUISH:
-		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_BLUISH\n", __func__);
-		rc = OV5640CORE_WRITEPREG(ov5640_effect_bluish_tbl);
-		break;
-
-	case CAMERA_EFFECT_SOLARIZE:
-		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_NEGATIVE\n", __func__);
-		rc = OV5640CORE_WRITEPREG(ov5640_effect_solarize_tbl);
-		break;
-
-	case CAMERA_EFFECT_SEPIA:
-		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_SEPIA\n", __func__);
-		rc = OV5640CORE_WRITEPREG(ov5640_effect_sepia_tbl);
-		break;
-
-	case CAMERA_EFFECT_REDDISH:
-		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_REDDISH\n", __func__);
-		rc = OV5640CORE_WRITEPREG(ov5640_effect_reddish_tbl);
-		break;
-
-	case CAMERA_EFFECT_GREENISH:
-		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_GREENISH\n", __func__);
-		rc = OV5640CORE_WRITEPREG(ov5640_effect_greenish_tbl);
-		break;
-
-	case CAMERA_EFFECT_NEGATIVE:
-		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_NEGATIVE\n", __func__);
-		rc = OV5640CORE_WRITEPREG(ov5640_effect_negative_tbl);
-		break;
-
-	default:
-		CDBG("--CAMERA-- %s ...Default(Not Support)\n", __func__);
-	}
-
-	ov5640_effect = effect;
-	/* Refresh Sequencer */
-	CDBG("--CAMERA-- %s ...(End)\n", __func__);
-	return rc;
-}
-
-static int ov5640_set_brightness(int8_t brightness)
-{
-	int rc = 0;
-
-	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
-	CDBG("--CAMERA-- %s ...brightness = %d\n", __func__ , brightness);
-
-	switch (brightness) {
-	case CAMERA_BRIGHTNESS_LV0:
-		CDBG("--CAMERA--CAMERA_BRIGHTNESS_LV0\n");
-		rc = OV5640CORE_WRITEPREG(ov5640_brightness_lv0_tbl);
-		break;
-
-	case CAMERA_BRIGHTNESS_LV1:
-		CDBG("--CAMERA--CAMERA_BRIGHTNESS_LV1\n");
-		rc = OV5640CORE_WRITEPREG(ov5640_brightness_lv1_tbl);
-		break;
-
-	case CAMERA_BRIGHTNESS_LV2:
-		CDBG("--CAMERA--CAMERA_BRIGHTNESS_LV2\n");
-		rc = OV5640CORE_WRITEPREG(ov5640_brightness_lv2_tbl);
-		break;
-
-	case CAMERA_BRIGHTNESS_LV3:
-		CDBG("--CAMERA--CAMERA_BRIGHTNESS_LV3\n");
-		rc = OV5640CORE_WRITEPREG(ov5640_brightness_lv3_tbl);
-		break;
-
-	case CAMERA_BRIGHTNESS_LV4:
-		CDBG("--CAMERA--CAMERA_BRIGHTNESS_LV4\n");
-		rc = OV5640CORE_WRITEPREG(ov5640_brightness_default_lv4_tbl);
-		break;
-
-	case CAMERA_BRIGHTNESS_LV5:
-		CDBG("--CAMERA--CAMERA_BRIGHTNESS_LV5\n");
-		rc = OV5640CORE_WRITEPREG(ov5640_brightness_lv5_tbl);
-		break;
-
-	case CAMERA_BRIGHTNESS_LV6:
-		CDBG("--CAMERA--CAMERA_BRIGHTNESS_LV6\n");
-		rc = OV5640CORE_WRITEPREG(ov5640_brightness_lv6_tbl);
-		break;
-
-	case CAMERA_BRIGHTNESS_LV7:
-		CDBG("--CAMERA--CAMERA_BRIGHTNESS_LV7\n");
-		rc = OV5640CORE_WRITEPREG(ov5640_brightness_lv7_tbl);
-		break;
-
-	case CAMERA_BRIGHTNESS_LV8:
-		CDBG("--CAMERA--CAMERA_BRIGHTNESS_LV8\n");
-		rc = OV5640CORE_WRITEPREG(ov5640_brightness_lv8_tbl);
-		break;
-
-	default:
-		CDBG("--CAMERA--CAMERA_BRIGHTNESS_ERROR COMMAND\n");
-		break;
-	}
-
-	CDBG("--CAMERA-- %s ...(End)\n", __func__);
-	return rc;
-}
-
-static int ov5640_set_contrast(int contrast)
-{
-	int rc = 0;
-
-	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
-	CDBG("--CAMERA-- %s ...contrast = %d\n", __func__ , contrast);
-
-	if (effect_value == CAMERA_EFFECT_OFF) {
-		switch (contrast) {
-		case CAMERA_CONTRAST_LV0:
-			CDBG("--CAMERA--CAMERA_CONTRAST_LV0\n");
-			rc = OV5640CORE_WRITEPREG(ov5640_contrast_lv0_tbl);
-			break;
-
-		case CAMERA_CONTRAST_LV1:
-			CDBG("--CAMERA--CAMERA_CONTRAST_LV1\n");
-			rc = OV5640CORE_WRITEPREG(ov5640_contrast_lv1_tbl);
-			break;
-
-		case CAMERA_CONTRAST_LV2:
-			CDBG("--CAMERA--CAMERA_CONTRAST_LV2\n");
-			rc = OV5640CORE_WRITEPREG(ov5640_contrast_lv2_tbl);
-			break;
-
-		case CAMERA_CONTRAST_LV3:
-			CDBG("--CAMERA--CAMERA_CONTRAST_LV3\n");
-			rc = OV5640CORE_WRITEPREG(ov5640_contrast_lv3_tbl);
-			break;
-
-		case CAMERA_CONTRAST_LV4:
-			CDBG("--CAMERA--CAMERA_CONTRAST_LV4\n");
-			rc = OV5640CORE_WRITEPREG(
-					ov5640_contrast_default_lv4_tbl);
-			break;
-
-		case CAMERA_CONTRAST_LV5:
-			CDBG("--CAMERA--CAMERA_CONTRAST_LV5\n");
-			rc = OV5640CORE_WRITEPREG(ov5640_contrast_lv5_tbl);
-			break;
-
-		case CAMERA_CONTRAST_LV6:
-			CDBG("--CAMERA--CAMERA_CONTRAST_LV6\n");
-			rc = OV5640CORE_WRITEPREG(ov5640_contrast_lv6_tbl);
-			break;
-
-		case CAMERA_CONTRAST_LV7:
-			CDBG("--CAMERA--CAMERA_CONTRAST_LV7\n");
-			rc = OV5640CORE_WRITEPREG(ov5640_contrast_lv7_tbl);
-			break;
-
-		case CAMERA_CONTRAST_LV8:
-			CDBG("--CAMERA--CAMERA_CONTRAST_LV8\n");
-			rc = OV5640CORE_WRITEPREG(ov5640_contrast_lv8_tbl);
-			break;
-
-		default:
-			CDBG("--CAMERA--CAMERA_CONTRAST_ERROR COMMAND\n");
-			break;
-		}
-	}
-
-	CDBG("--CAMERA-- %s ...(End)\n", __func__);
-	return rc;
-}
-
-static int ov5640_set_sharpness(int sharpness)
-{
-	int rc = 0;
-
-	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
-	CDBG("--CAMERA-- %s ...sharpness = %d\n", __func__ , sharpness);
-
-	if (effect_value == CAMERA_EFFECT_OFF) {
-		switch (sharpness) {
-		case CAMERA_SHARPNESS_LV0:
-			CDBG("--CAMERA--CAMERA_SHARPNESS_LV0\n");
-			rc = OV5640CORE_WRITEPREG(ov5640_sharpness_lv0_tbl);
-			break;
-
-		case CAMERA_SHARPNESS_LV1:
-			CDBG("--CAMERA--CAMERA_SHARPNESS_LV1\n");
-			rc = OV5640CORE_WRITEPREG(ov5640_sharpness_lv1_tbl);
-			break;
-
-		case CAMERA_SHARPNESS_LV2:
-			CDBG("--CAMERA--CAMERA_SHARPNESS_LV2\n");
-			rc = OV5640CORE_WRITEPREG(
-					ov5640_sharpness_default_lv2_tbl);
-			break;
-
-		case CAMERA_SHARPNESS_LV3:
-			CDBG("--CAMERA--CAMERA_SHARPNESS_LV3\n");
-			rc = OV5640CORE_WRITEPREG(ov5640_sharpness_lv3_tbl);
-			break;
-
-		case CAMERA_SHARPNESS_LV4:
-			CDBG("--CAMERA--CAMERA_SHARPNESS_LV4\n");
-			rc = OV5640CORE_WRITEPREG(ov5640_sharpness_lv4_tbl);
-			break;
-
-		case CAMERA_SHARPNESS_LV5:
-			CDBG("--CAMERA--CAMERA_SHARPNESS_LV5\n");
-			rc = OV5640CORE_WRITEPREG(ov5640_sharpness_lv5_tbl);
-			break;
-
-		case CAMERA_SHARPNESS_LV6:
-			CDBG("--CAMERA--CAMERA_SHARPNESS_LV6\n");
-			rc = OV5640CORE_WRITEPREG(ov5640_sharpness_lv6_tbl);
-			break;
-
-		case CAMERA_SHARPNESS_LV7:
-			CDBG("--CAMERA--CAMERA_SHARPNESS_LV7\n");
-			rc = OV5640CORE_WRITEPREG(ov5640_sharpness_lv7_tbl);
-			break;
-
-		case CAMERA_SHARPNESS_LV8:
-			CDBG("--CAMERA--CAMERA_SHARPNESS_LV8\n");
-			rc = OV5640CORE_WRITEPREG(ov5640_sharpness_lv8_tbl);
-			break;
-
-		default:
-			CDBG("--CAMERA--CAMERA_SHARPNESS_ERROR COMMAND\n");
-			break;
-		}
-	}
-
-	CDBG("--CAMERA-- %s ...(End)\n", __func__);
-	return rc;
-}
-
-static int ov5640_set_saturation(int saturation)
-{
-	long rc = 0;
-
-	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
-	CDBG("--CAMERA-- %s ...saturation = %d\n", __func__ , saturation);
-
-	if (effect_value == CAMERA_EFFECT_OFF) {
-		switch (saturation) {
-		case CAMERA_SATURATION_LV0:
-			CDBG("--CAMERA--CAMERA_SATURATION_LV0\n");
-			rc = OV5640CORE_WRITEPREG(ov5640_saturation_lv0_tbl);
-			break;
-
-		case CAMERA_SATURATION_LV1:
-			CDBG("--CAMERA--CAMERA_SATURATION_LV1\n");
-			rc = OV5640CORE_WRITEPREG(ov5640_saturation_lv1_tbl);
-			break;
-
-		case CAMERA_SATURATION_LV2:
-			CDBG("--CAMERA--CAMERA_SATURATION_LV2\n");
-			rc = OV5640CORE_WRITEPREG(ov5640_saturation_lv2_tbl);
-			break;
-
-		case CAMERA_SATURATION_LV3:
-			CDBG("--CAMERA--CAMERA_SATURATION_LV3\n");
-			rc = OV5640CORE_WRITEPREG(ov5640_saturation_lv3_tbl);
-			break;
-
-		case CAMERA_SATURATION_LV4:
-			CDBG("--CAMERA--CAMERA_SATURATION_LV4\n");
-			rc = OV5640CORE_WRITEPREG(
-					ov5640_saturation_default_lv4_tbl);
-			break;
-
-		case CAMERA_SATURATION_LV5:
-			CDBG("--CAMERA--CAMERA_SATURATION_LV5\n");
-			rc = OV5640CORE_WRITEPREG(ov5640_saturation_lv5_tbl);
-			break;
-
-		case CAMERA_SATURATION_LV6:
-			CDBG("--CAMERA--CAMERA_SATURATION_LV6\n");
-			rc = OV5640CORE_WRITEPREG(ov5640_saturation_lv6_tbl);
-			break;
-
-		case CAMERA_SATURATION_LV7:
-			CDBG("--CAMERA--CAMERA_SATURATION_LV7\n");
-			rc = OV5640CORE_WRITEPREG(ov5640_saturation_lv7_tbl);
-			break;
-
-		case CAMERA_SATURATION_LV8:
-			CDBG("--CAMERA--CAMERA_SATURATION_LV8\n");
-			rc = OV5640CORE_WRITEPREG(ov5640_saturation_lv8_tbl);
-			break;
-
-		default:
-			CDBG("--CAMERA--CAMERA_SATURATION_ERROR COMMAND\n");
-			break;
-		}
-	}
-
-	/* for recover saturation level when change special effect */
-	switch (saturation) {
-	case CAMERA_SATURATION_LV0:
-		CDBG("--CAMERA--CAMERA_SATURATION_LV0\n");
-		ov5640_SAT_U = 0x00;
-		ov5640_SAT_V = 0x00;
-		break;
-	case CAMERA_SATURATION_LV1:
-		CDBG("--CAMERA--CAMERA_SATURATION_LV1\n");
-		ov5640_SAT_U = 0x10;
-		ov5640_SAT_V = 0x10;
-		break;
-	case CAMERA_SATURATION_LV2:
-		CDBG("--CAMERA--CAMERA_SATURATION_LV2\n");
-		ov5640_SAT_U = 0x20;
-		ov5640_SAT_V = 0x20;
-		break;
-	case CAMERA_SATURATION_LV3:
-		CDBG("--CAMERA--CAMERA_SATURATION_LV3\n");
-		ov5640_SAT_U = 0x30;
-		ov5640_SAT_V = 0x30;
-		break;
-	case CAMERA_SATURATION_LV4:
-		CDBG("--CAMERA--CAMERA_SATURATION_LV4\n");
-		ov5640_SAT_U = 0x40;
-		ov5640_SAT_V = 0x40;            break;
-	case CAMERA_SATURATION_LV5:
-		CDBG("--CAMERA--CAMERA_SATURATION_LV5\n");
-		ov5640_SAT_U = 0x50;
-		ov5640_SAT_V = 0x50;            break;
-	case CAMERA_SATURATION_LV6:
-		CDBG("--CAMERA--CAMERA_SATURATION_LV6\n");
-		ov5640_SAT_U = 0x60;
-		ov5640_SAT_V = 0x60;
-		break;
-	case CAMERA_SATURATION_LV7:
-		CDBG("--CAMERA--CAMERA_SATURATION_LV7\n");
-		ov5640_SAT_U = 0x70;
-		ov5640_SAT_V = 0x70;            break;
-	case CAMERA_SATURATION_LV8:
-		CDBG("--CAMERA--CAMERA_SATURATION_LV8\n");
-		ov5640_SAT_U = 0x80;
-		ov5640_SAT_V = 0x80;
-		break;
-	default:
-		CDBG("--CAMERA--CAMERA_SATURATION_ERROR COMMAND\n");
-		break;
-	}
-
-	CDBG("--CAMERA-- %s ...(End)\n", __func__);
-	return rc;
-}
-
-static long ov5640_set_antibanding(int antibanding)
-{
-	long rc = 0;
-
-	CDBG("--CAMERA-- %s ...(Start)\n",  __func__);
-	CDBG("--CAMERA-- %s ...antibanding = %d\n",  __func__, antibanding);
-
-	switch (antibanding) {
-	case CAMERA_ANTIBANDING_OFF:
-		CDBG("--CAMERA--CAMERA_ANTIBANDING_OFF\n");
-		break;
-
-	case CAMERA_ANTIBANDING_60HZ:
-		CDBG("--CAMERA--CAMERA_ANTIBANDING_60HZ\n");
-		rc = OV5640CORE_WRITEPREG(ov5640_antibanding_60z_tbl);
-		break;
-
-	case CAMERA_ANTIBANDING_50HZ:
-		CDBG("--CAMERA--CAMERA_ANTIBANDING_50HZ\n");
-		rc = OV5640CORE_WRITEPREG(ov5640_antibanding_50z_tbl);
-		break;
-
-	case CAMERA_ANTIBANDING_AUTO:
-		CDBG("--CAMERA--CAMERA_ANTIBANDING_AUTO\n");
-		rc = OV5640CORE_WRITEPREG(ov5640_antibanding_auto_tbl);
-		break;
-
-	default:
-		CDBG("--CAMERA--CAMERA_ANTIBANDING_ERROR COMMAND\n");
-		break;
-	}
-
-	CDBG("--CAMERA-- %s ...(End)\n", __func__);
-	return rc;
-}
-
-static long ov5640_set_exposure_mode(int mode)
-{
-	long rc = 0;
-	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
-	CDBG("--CAMERA-- %s ...mode = %d\n", __func__ , mode);
-	CDBG("--CAMERA-- %s ...(End)\n", __func__);
-	return rc;
-}
-
-static int32_t ov5640_lens_shading_enable(uint8_t is_enable)
-{
-	int32_t rc = 0;
-	CDBG("--CAMERA--%s: ...(Start). enable = %d\n",  __func__, is_enable);
-
-	if (is_enable) {
-		CDBG("%s: enable~!!\n", __func__);
-		rc = OV5640CORE_WRITEPREG(ov5640_lens_shading_on_tbl);
-	} else {
-		CDBG("%s: disable~!!\n", __func__);
-		rc = OV5640CORE_WRITEPREG(ov5640_lens_shading_off_tbl);
-	}
-	CDBG("--CAMERA--%s: ...(End). rc = %d\n", __func__, rc);
-	return rc;
-}
-
-static int ov5640_set_sensor_mode(int mode, int res)
-{
-	int rc = 0;
-
-	CDBG("--CAMERA-- ov5640_set_sensor_mode mode = %d, res = %d\n",
-			mode, res);
-
-	switch (mode) {
-	case SENSOR_PREVIEW_MODE:
-		CDBG("--CAMERA-- SENSOR_PREVIEW_MODE\n");
-		rc = ov5640_setting(S_UPDATE_PERIODIC, S_RES_PREVIEW);
-		break;
-
-	case SENSOR_SNAPSHOT_MODE:
-		CDBG("--CAMERA-- SENSOR_SNAPSHOT_MODE\n");
-		rc = ov5640_setting(S_UPDATE_PERIODIC, S_RES_CAPTURE);
-		break;
-
-	case SENSOR_RAW_SNAPSHOT_MODE:
-		CDBG("--CAMERA-- SENSOR_RAW_SNAPSHOT_MODE\n");
-		rc = ov5640_setting(S_UPDATE_PERIODIC, S_RES_CAPTURE);
-		break;
-
-	default:
-		CDBG("--CAMERA--ov5640_set_sensor_mode no support\n");
-		rc = -EINVAL;
-		break;
-	}
-
-	return rc;
-}
-
-static int ov5640_set_wb_oem(uint8_t param)
-{
-	int rc = 0;
-	unsigned int tmp2;
-
-	CDBG("[kylin] %s \r\n", __func__);
-
-	ov5640_i2c_read_byte(ov5640_client->addr, 0x350b, &tmp2);
-	CDBG("--CAMERA-- GAIN VALUE : %x\n", tmp2);
-
-	switch (param) {
-	case CAMERA_WB_AUTO:
-
-		CDBG("--CAMERA--CAMERA_WB_AUTO\n");
-		rc = OV5640CORE_WRITEPREG(ov5640_wb_def);
-		break;
-
-	case CAMERA_WB_CUSTOM:
-		CDBG("--CAMERA--CAMERA_WB_CUSTOM\n");
-		rc = OV5640CORE_WRITEPREG(ov5640_wb_custom);
-		break;
-	case CAMERA_WB_INCANDESCENT:
-		CDBG("--CAMERA--CAMERA_WB_INCANDESCENT\n");
-		rc = OV5640CORE_WRITEPREG(ov5640_wb_inc);
-		break;
-	case CAMERA_WB_DAYLIGHT:
-		CDBG("--CAMERA--CAMERA_WB_DAYLIGHT\n");
-		rc = OV5640CORE_WRITEPREG(ov5640_wb_daylight);
-		break;
-	case CAMERA_WB_CLOUDY_DAYLIGHT:
-		CDBG("--CAMERA--CAMERA_WB_CLOUDY_DAYLIGHT\n");
-		rc = OV5640CORE_WRITEPREG(ov5640_wb_cloudy);
-		break;
-	default:
-		break;
-	}
-	return rc;
-}
-
-static int ov5640_set_touchaec(uint32_t x, uint32_t y)
-{
-	uint8_t aec_arr[8] = {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11};
-	int idx = 0;
-	int i;
-
-	CDBG("[kylin] %s x: %d ,y: %d\r\n", __func__ , x, y);
-	idx = x / 2 + y * 2;
-	CDBG("[kylin] idx: %d\r\n", idx);
-
-	if (x % 2 == 0)
-		aec_arr[idx] = 0x10 | 0x0a;
-	else
-		aec_arr[idx] = 0x01 | 0xa0;
-
-	for (i = 0; i < 8; i++) {
-		CDBG("write : %x val : %x ", 0x5688 + i, aec_arr[i]);
-		ov5640_i2c_write(ov5640_client->addr, 0x5688 + i,
-				aec_arr[i], 10);
-	}
-
-	return 1;
-}
-
-static int ov5640_set_exposure_compensation(int compensation)
-{
-	long rc = 0;
-
-	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
-
-	CDBG("--CAMERA-- %s ...exposure_compensation = %d\n", __func__ ,
-			    compensation);
-
-	switch (compensation) {
-	case CAMERA_EXPOSURE_COMPENSATION_LV0:
-		CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV0\n");
-		rc = OV5640CORE_WRITEPREG(
-				ov5640_exposure_compensation_lv0_tbl);
-		break;
-
-	case CAMERA_EXPOSURE_COMPENSATION_LV1:
-		CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV1\n");
-		rc = OV5640CORE_WRITEPREG(
-				ov5640_exposure_compensation_lv1_tbl);
-		break;
-
-	case CAMERA_EXPOSURE_COMPENSATION_LV2:
-		CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV2\n");
-		rc = OV5640CORE_WRITEPREG(
-			    ov5640_exposure_compensation_lv2_default_tbl);
-		break;
-
-	case CAMERA_EXPOSURE_COMPENSATION_LV3:
-		CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV3\n");
-		rc = OV5640CORE_WRITEPREG(
-				ov5640_exposure_compensation_lv3_tbl);
-		break;
-
-	case CAMERA_EXPOSURE_COMPENSATION_LV4:
-		CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV3\n");
-		rc = OV5640CORE_WRITEPREG(
-				ov5640_exposure_compensation_lv4_tbl);
-		break;
-
-	default:
-		CDBG("--CAMERA--ERROR CAMERA_EXPOSURE_COMPENSATION\n");
-		break;
-	}
-
-	CDBG("--CAMERA-- %s ...(End)\n", __func__);
-
-	return rc;
-}
-
-static int ov5640_sensor_start_af(void)
-{
-	int i;
-	unsigned int af_st = 0;
-	unsigned int af_ack = 0;
-	unsigned int tmp = 0;
-	int rc = 0;
-
-	CDBG("--CAMERA-- %s (Start...)\n", __func__);
-
-	ov5640_i2c_read_byte(ov5640_client->addr,
-			OV5640_CMD_FW_STATUS, &af_st);
-	CDBG("--CAMERA-- %s af_st = %d\n", __func__, af_st);
-
-	ov5640_i2c_write(ov5640_client->addr, OV5640_CMD_ACK, 0x01, 10);
-	ov5640_i2c_write(ov5640_client->addr, OV5640_CMD_MAIN, 0x03, 10);
-
-	for (i = 0; i < 50; i++) {
-		ov5640_i2c_read_byte(ov5640_client->addr,
-				OV5640_CMD_ACK, &af_ack);
-		if (af_ack == 0)
-			break;
-		msleep(50);
-	}
-	CDBG("--CAMERA-- %s af_ack = 0x%x\n", __func__, af_ack);
-
-	ov5640_i2c_read_byte(ov5640_client->addr, OV5640_CMD_FW_STATUS,
-			&af_st);
-	CDBG("--CAMERA-- %s af_st = %d\n", __func__, af_st);
-
-	if (af_st == 0x10) {
-		CDBG("--CAMERA-- %s AF ok and release AF setting~!!\n",
-				__func__);
-	} else {
-		CDBG("--CAMERA-- %s AF not ready!!\n", __func__);
-	}
-
-	ov5640_i2c_write(ov5640_client->addr, OV5640_CMD_ACK, 0x01, 10);
-	ov5640_i2c_write(ov5640_client->addr, OV5640_CMD_MAIN, 0x07, 10);
-
-	for (i = 0; i < 70; i++) {
-		ov5640_i2c_read_byte(ov5640_client->addr, OV5640_CMD_ACK,
-				&af_ack);
-		if (af_ack == 0)
-			break;
-		msleep(25);
-	}
-
-	ov5640_i2c_read_byte(ov5640_client->addr, OV5640_CMD_PARA0, &tmp);
-	CDBG("0x3024 = %x\n", tmp);
-	rc = ((tmp == 0) ? 1 : 0);
-
-	ov5640_i2c_read_byte(ov5640_client->addr, OV5640_CMD_PARA1, &tmp);
-	CDBG("0x3025 = %x\n", tmp);
-	rc = ((tmp == 0) ? 1 : 0);
-
-	ov5640_i2c_read_byte(ov5640_client->addr, OV5640_CMD_PARA2, &tmp);
-	CDBG("0x3026 = %x\n", tmp);
-	rc = ((tmp == 0) ? 1 : 0);
-
-	ov5640_i2c_read_byte(ov5640_client->addr, OV5640_CMD_PARA3, &tmp);
-	CDBG("0x3027 = %x\n", tmp);
-	rc = ((tmp == 0) ? 1 : 0) ;
-
-	ov5640_i2c_read_byte(ov5640_client->addr, OV5640_CMD_PARA4, &tmp);
-	CDBG("0x3028 = %x\n", tmp);
-	rc = ((tmp == 0) ? 1 : 0) ;
-
-	CDBG("--CAMERA-- %s rc = %d(End...)\n", __func__, rc);
-	return rc;
-}
-
-static int ov5640_sensor_config(void __user *argp)
-{
-	struct sensor_cfg_data cdata;
-	long rc = 0;
-
-	if (copy_from_user(&cdata, (void *)argp,
-				sizeof(struct sensor_cfg_data)))
-		return -EFAULT;
-
-	CDBG("--CAMERA-- %s %d\n", __func__, cdata.cfgtype);
-
-	mutex_lock(&ov5640_mutex);
-
-	switch (cdata.cfgtype) {
-	case CFG_SET_MODE:
-		rc = ov5640_set_sensor_mode(cdata.mode, cdata.rs);
-		break;
-
-	case CFG_SET_EFFECT:
-		CDBG("--CAMERA-- CFG_SET_EFFECT mode=%d,"
-				"effect = %d !!\n", cdata.mode,
-				cdata.cfg.effect);
-		rc = ov5640_set_effect(cdata.mode, cdata.cfg.effect);
-		break;
-
-	case CFG_START:
-		CDBG("--CAMERA-- CFG_START (Not Support) !!\n");
-		/* Not Support */
-		break;
-
-	case CFG_PWR_UP:
-		CDBG("--CAMERA-- CFG_PWR_UP (Not Support) !!\n");
-		/* Not Support */
-		break;
-
-	case CFG_PWR_DOWN:
-		CDBG("--CAMERA-- CFG_PWR_DOWN (Not Support)\n");
-		ov5640_power_off();
-		break;
-
-	case CFG_SET_DEFAULT_FOCUS:
-		CDBG("--CAMERA-- CFG_SET_DEFAULT_FOCUS (Not Implement) !!\n");
-		break;
-
-	case CFG_MOVE_FOCUS:
-		CDBG("--CAMERA-- CFG_MOVE_FOCUS (Not Implement) !!\n");
-		break;
-
-	case CFG_SET_BRIGHTNESS:
-		CDBG("--CAMERA-- CFG_SET_BRIGHTNESS  !!\n");
-		rc = ov5640_set_brightness(cdata.cfg.brightness);
-		break;
-
-	case CFG_SET_CONTRAST:
-		CDBG("--CAMERA-- CFG_SET_CONTRAST  !!\n");
-		rc = ov5640_set_contrast(cdata.cfg.contrast);
-		break;
-
-	case CFG_SET_EXPOSURE_MODE:
-		CDBG("--CAMERA-- CFG_SET_EXPOSURE_MODE !!\n");
-		rc = ov5640_set_exposure_mode(cdata.cfg.ae_mode);
-		break;
-
-	case CFG_SET_ANTIBANDING:
-		CDBG("--CAMERA-- CFG_SET_ANTIBANDING antibanding = %d!!\n",
-				cdata.cfg.antibanding);
-		rc = ov5640_set_antibanding(cdata.cfg.antibanding);
-		break;
-
-	case CFG_SET_LENS_SHADING:
-		CDBG("--CAMERA-- CFG_SET_LENS_SHADING !!\n");
-		rc = ov5640_lens_shading_enable(
-				cdata.cfg.lens_shading);
-		break;
-
-	case CFG_SET_SATURATION:
-		CDBG("--CAMERA-- CFG_SET_SATURATION !!\n");
-		rc = ov5640_set_saturation(cdata.cfg.saturation);
-		break;
-
-	case CFG_SET_SHARPNESS:
-		CDBG("--CAMERA-- CFG_SET_SHARPNESS !!\n");
-		rc = ov5640_set_sharpness(cdata.cfg.sharpness);
-		break;
-
-	case CFG_SET_WB:
-		CDBG("--CAMERA-- CFG_SET_WB!!\n");
-		ov5640_set_wb_oem(cdata.cfg.wb_val);
-		rc = 0 ;
-		break;
-
-	case CFG_SET_TOUCHAEC:
-		CDBG("--CAMERA-- CFG_SET_TOUCHAEC!!\n");
-		ov5640_set_touchaec(cdata.cfg.aec_cord.x,
-				cdata.cfg.aec_cord.y);
-		rc = 0 ;
-		break;
-
-	case CFG_SET_AUTO_FOCUS:
-		CDBG("--CAMERA-- CFG_SET_AUTO_FOCUS !\n");
-		rc = ov5640_sensor_start_af();
-		break;
-
-	case CFG_SET_AUTOFLASH:
-		CDBG("--CAMERA-- CFG_SET_AUTOFLASH !\n");
-		is_autoflash = cdata.cfg.is_autoflash;
-		CDBG("[kylin] is autoflash %d\r\n", is_autoflash);
-		rc = 0;
-		break;
-
-	case CFG_SET_EXPOSURE_COMPENSATION:
-		CDBG("--CAMERA-- CFG_SET_EXPOSURE_COMPENSATION !\n");
-		rc = ov5640_set_exposure_compensation(
-				cdata.cfg.exp_compensation);
-		break;
-
-	default:
-		CDBG("%s: Command=%d (Not Implement)!!\n", __func__,
-				cdata.cfgtype);
-		rc = -EINVAL;
-		break;
-	}
-
-	mutex_unlock(&ov5640_mutex);
-	return rc;
-}
-
-static struct i2c_driver ov5640_i2c_driver = {
-	.id_table = ov5640_i2c_id,
-	.probe  = ov5640_i2c_probe,
-	.remove = ov5640_i2c_remove,
-	.driver = {
-		.name = "ov5640",
-	},
-};
-
-static int ov5640_probe_init_gpio(const struct msm_camera_sensor_info *data)
-{
-	int rc = 0;
-
-	CDBG("--CAMERA-- %s\n", __func__);
-
-	ov5640_pwdn_gpio = data->sensor_pwd;
-	ov5640_reset_gpio = data->sensor_reset;
-	ov5640_driver_pwdn_gpio = data->vcm_pwd ;
-
-	if (data->vcm_enable)
-		gpio_direction_output(data->vcm_pwd, 1);
-
-	gpio_direction_output(data->sensor_reset, 1);
-	gpio_direction_output(data->sensor_pwd, 1);
-
-	return rc;
-
-}
-
-static void ov5640_probe_free_gpio(const struct msm_camera_sensor_info *data)
-{
-	gpio_free(ov5640_pwdn_gpio);
-	gpio_free(ov5640_reset_gpio);
-
-	if (data->vcm_enable) {
-		gpio_free(ov5640_driver_pwdn_gpio);
-		ov5640_driver_pwdn_gpio = 0xFF ;
-	}
-
-	ov5640_pwdn_gpio	= 0xFF;
-	ov5640_reset_gpio	= 0xFF;
-}
-
-static int ov5640_sensor_probe(const struct msm_camera_sensor_info *info,
-		struct msm_sensor_ctrl *s)
-{
-	int rc = -ENOTSUPP;
-
-	CDBG("--CAMERA-- %s (Start...)\n", __func__);
-	rc = i2c_add_driver(&ov5640_i2c_driver);
-	CDBG("--CAMERA-- i2c_add_driver ret:0x%x,ov5640_client=0x%x\n",
-			rc, (unsigned int)ov5640_client);
-	if ((rc < 0) || (ov5640_client == NULL)) {
-		CDBG("--CAMERA-- i2c_add_driver FAILS!!\n");
-		return rc;
-	}
-
-	rc = ov5640_probe_init_gpio(info);
-	if (rc < 0)
-		return rc;
-
-	ov5640_power_off();
-
-	/* SENSOR NEED MCLK TO DO I2C COMMUNICTION, OPEN CLK FIRST*/
-	msm_camio_clk_rate_set(24000000);
-
-	msleep(20);
-
-	ov5640_power_on();
-	ov5640_power_reset();
-
-	rc = ov5640_probe_readID(info);
-
-	if (rc < 0) {
-		CDBG("--CAMERA--ov5640_probe_readID Fail !!~~~~!!\n");
-		CDBG("--CAMERA-- %s, unregister\n", __func__);
-		i2c_del_driver(&ov5640_i2c_driver);
-		ov5640_power_off();
-		ov5640_probe_free_gpio(info);
-		return rc;
-	}
-
-	s->s_init		= ov5640_sensor_open_init;
-	s->s_release		= ov5640_sensor_release;
-	s->s_config		= ov5640_sensor_config;
-	s->s_camera_type	= BACK_CAMERA_2D;
-	s->s_mount_angle	= info->sensor_platform_info->mount_angle;
-
-	ov5640_power_off();
-
-	CDBG("--CAMERA-- %s (End...)\n", __func__);
-	return rc;
-}
-
-static int ov5640_i2c_probe(struct i2c_client *client,
-		const struct i2c_device_id *id)
-{
-	CDBG("--CAMERA-- %s ... (Start...)\n", __func__);
-
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		CDBG("--CAMERA--i2c_check_functionality failed\n");
-		return -ENOMEM;
-	}
-
-	ov5640_sensorw = kzalloc(sizeof(struct ov5640_work), GFP_KERNEL);
-	if (!ov5640_sensorw) {
-		CDBG("--CAMERA--kzalloc failed\n");
-		return -ENOMEM;
-	}
-
-	i2c_set_clientdata(client, ov5640_sensorw);
-	ov5640_init_client(client);
-	ov5640_client = client;
-
-	CDBG("--CAMERA-- %s ... (End...)\n", __func__);
-	return 0;
-}
-
-static int __ov5640_probe(struct platform_device *pdev)
-{
-	return msm_camera_drv_start(pdev, ov5640_sensor_probe);
-}
-
-static struct platform_driver msm_camera_driver = {
-	.probe	= __ov5640_probe,
-	.driver	= {
-		.name	= "msm_camera_ov5640",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static int __init ov5640_init(void)
-{
-	ov5640_i2c_buf[0] = 0x5A;
-	return platform_driver_register(&msm_camera_driver);
-}
-
-module_init(ov5640_init);
-
-MODULE_DESCRIPTION("OV5640 YUV MIPI sensor driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/ov5640.h b/drivers/media/video/msm/ov5640.h
deleted file mode 100644
index 0e65329..0000000
--- a/drivers/media/video/msm/ov5640.h
+++ /dev/null
@@ -1,2993 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. 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.
- */
-
-
-/*
-[SENSOR]
-Sensor Model:   OV5640
-Camera Module:
-Lens Model:
-Driver IC:
-PV Size         = 640 x 480
-Cap Size        = 2592 x 1944
-Output Format   = YUYV
-MCLK Speed      = 24M
-PV DVP_PCLK     = 28M
-Cap DVP_PCLK    = 56M
-PV Frame Rate   = 30fps
-Cap Frame Rate  = 7.5fps
-I2C Slave ID    = 0x78
-I2C Mode        = 16Addr, 8Data
-*/
-
-#ifndef CAMSENSOR_OV5640
-#define CAMSENSOR_OV5640
-
-#define INVMASK(v)  (0xff-v)
-#define OV5640CORE_WRITEPREG(PTBL)	ov5640_writepregs(PTBL,\
-					sizeof(PTBL)/sizeof(PTBL[0]))
-
-/* OV SENSOR SCCB */
-struct ov5640_sensor {
-	uint16_t addr;
-	uint8_t data;
-	uint8_t mask;
-};
-
-/* Auto Focus Command */
-#define OV5640_CMD_MAIN 0x3022
-#define OV5640_CMD_ACK 0x3023
-#define OV5640_CMD_PARA0 0x3024
-#define OV5640_CMD_PARA1 0x3025
-#define OV5640_CMD_PARA2 0x3026
-#define OV5640_CMD_PARA3 0x3027
-#define OV5640_CMD_PARA4 0x3028
-#define OV5640_CMD_FW_STATUS 0x3029
-
-/* Sensor ID */
-#define OV5640_SENSOR_ID 0x5640
-
-#define capture_framerate 750     /* 7.5fps capture frame rate */
-#define g_preview_frameRate 3000  /* 30fps preview frame rate */
-
-struct ov5640_sensor ov5640_init_tbl[] = {
-	{0x3008, 0x42},
-	{0x3103, 0x03},
-	{0x3017, 0x00},
-	{0x3018, 0x00},
-	{0x3034, 0x18},
-	{0x3035, 0x14},
-	{0x3036, 0x38},
-	{0x3037, 0x13},
-	{0x3108, 0x01},
-	{0x3630, 0x36},
-	{0x3631, 0x0e},
-	{0x3632, 0xe2},
-	{0x3633, 0x12},
-	{0x3621, 0xe0},
-	{0x3704, 0xa0},
-	{0x3703, 0x5a},
-	{0x3715, 0x78},
-	{0x3717, 0x01},
-	{0x370b, 0x60},
-	{0x3705, 0x1a},
-	{0x3905, 0x02},
-	{0x3906, 0x10},
-	{0x3901, 0x0a},
-	{0x3731, 0x12},
-	{0x3600, 0x08},
-	{0x3601, 0x33},
-	{0x302d, 0x60},
-	{0x3620, 0x52},
-	{0x371b, 0x20},
-	{0x471c, 0x50},
-	{0x3a13, 0x43},
-	{0x3a18, 0x00},
-	{0x3a19, 0xf8},
-	{0x3635, 0x13},
-	{0x3636, 0x03},
-	{0x3634, 0x40},
-	{0x3622, 0x01},
-	{0x3c01, 0x34},
-	{0x3c04, 0x28},
-	{0x3c05, 0x98},
-	{0x3c06, 0x00},
-	{0x3c07, 0x08},
-	{0x3c08, 0x00},
-	{0x3c09, 0x1c},
-	{0x3c0a, 0x9c},
-	{0x3c0b, 0x40},
-	{0x3820, 0x41},
-	{0x3821, 0x07},
-	{0x3814, 0x31},
-	{0x3815, 0x31},
-	{0x3800, 0x00},
-	{0x3801, 0x00},
-	{0x3802, 0x00},
-	{0x3803, 0x04},
-	{0x3804, 0x0a},
-	{0x3805, 0x3f},
-	{0x3806, 0x07},
-	{0x3807, 0x9b},
-	{0x3808, 0x02},
-	{0x3809, 0x80},
-	{0x380a, 0x01},
-	{0x380b, 0xe0},
-	{0x380c, 0x07},
-	{0x380d, 0x68},
-	{0x380e, 0x03},
-	{0x380f, 0xd8},
-	{0x3810, 0x00},
-	{0x3811, 0x10},
-	{0x3812, 0x00},
-	{0x3813, 0x06},
-	{0x3618, 0x00},
-	{0x3612, 0x29},
-	{0x3708, 0x64},
-	{0x3709, 0x52},
-	{0x370c, 0x03},
-	{0x3a02, 0x03},
-	{0x3a03, 0xd8},
-	{0x3a08, 0x01},
-	{0x3a09, 0x27},
-	{0x3a0a, 0x00},
-	{0x3a0b, 0xf6},
-	{0x3a0e, 0x03},
-	{0x3a0d, 0x04},
-	{0x3a14, 0x03},
-	{0x3a15, 0xd8},
-	{0x4001, 0x02},
-	{0x4004, 0x02},
-	{0x3000, 0x00},
-	{0x3002, 0x1c},
-	{0x3004, 0xff},
-	{0x3006, 0xc3},
-	{0x300e, 0x45},
-	{0x302e, 0x08},
-	{0x4300, 0x30},
-	{0x501f, 0x00},
-	{0x4713, 0x03},
-	{0x4407, 0x04},
-	{0x440e, 0x00},
-	{0x460b, 0x35},
-	{0x460c, 0x22},
-	{0x4837, 0x44},
-	{0x3824, 0x02},
-	{0x5000, 0xa7},
-	{0x5001, 0xa3},
-	{0x5180, 0xff},
-	{0x5181, 0xf2},
-	{0x5182, 0x00},
-	{0x5183, 0x14},
-	{0x5184, 0x25},
-	{0x5185, 0x24},
-	{0x5186, 0x09},
-	{0x5187, 0x09},
-	{0x5188, 0x09},
-	{0x5189, 0x75},
-	{0x518a, 0x54},
-	{0x518b, 0xe0},
-	{0x518c, 0xb2},
-	{0x518d, 0x42},
-	{0x518e, 0x3d},
-	{0x518f, 0x56},
-	{0x5190, 0x46},
-	{0x5191, 0xf8},
-	{0x5192, 0x04},
-	{0x5193, 0x70},
-	{0x5194, 0xf0},
-	{0x5195, 0xf0},
-	{0x5196, 0x03},
-	{0x5197, 0x01},
-	{0x5198, 0x04},
-	{0x5199, 0x12},
-	{0x519a, 0x04},
-	{0x519b, 0x00},
-	{0x519c, 0x06},
-	{0x519d, 0x82},
-	{0x519e, 0x38},
-	{0x5381, 0x1e},
-	{0x5382, 0x5b},
-	{0x5383, 0x08},
-	{0x5384, 0x0a},
-	{0x5385, 0x7e},
-	{0x5386, 0x88},
-	{0x5387, 0x7c},
-	{0x5388, 0x6c},
-	{0x5389, 0x10},
-	{0x538a, 0x01},
-	{0x538b, 0x98},
-	{0x5300, 0x08},
-	{0x5301, 0x30},
-	{0x5302, 0x10},
-	{0x5303, 0x00},
-	{0x5304, 0x08},
-	{0x5305, 0x30},
-	{0x5306, 0x08},
-	{0x5307, 0x16},
-	{0x5309, 0x08},
-	{0x530a, 0x30},
-	{0x530b, 0x04},
-	{0x530c, 0x06},
-	{0x5480, 0x01},
-	{0x5481, 0x08},
-	{0x5482, 0x14},
-	{0x5483, 0x28},
-	{0x5484, 0x51},
-	{0x5485, 0x65},
-	{0x5486, 0x71},
-	{0x5487, 0x7d},
-	{0x5488, 0x87},
-	{0x5489, 0x91},
-	{0x548a, 0x9a},
-	{0x548b, 0xaa},
-	{0x548c, 0xb8},
-	{0x548d, 0xcd},
-	{0x548e, 0xdd},
-	{0x548f, 0xea},
-	{0x5490, 0x1d},
-	{0x5580, 0x02},
-	{0x5583, 0x40},
-	{0x5584, 0x10},
-	{0x5589, 0x10},
-	{0x558a, 0x00},
-	{0x558b, 0xf8},
-	{0x5800, 0x23},
-	{0x5801, 0x14},
-	{0x5802, 0x0f},
-	{0x5803, 0x0f},
-	{0x5804, 0x12},
-	{0x5805, 0x26},
-	{0x5806, 0x0c},
-	{0x5807, 0x08},
-	{0x5808, 0x05},
-	{0x5809, 0x05},
-	{0x580a, 0x08},
-	{0x580b, 0x0d},
-	{0x580c, 0x08},
-	{0x580d, 0x03},
-	{0x580e, 0x00},
-	{0x580f, 0x00},
-	{0x5810, 0x03},
-	{0x5811, 0x09},
-	{0x5812, 0x07},
-	{0x5813, 0x03},
-	{0x5814, 0x00},
-	{0x5815, 0x01},
-	{0x5816, 0x03},
-	{0x5817, 0x08},
-	{0x5818, 0x0d},
-	{0x5819, 0x08},
-	{0x581a, 0x05},
-	{0x581b, 0x06},
-	{0x581c, 0x08},
-	{0x581d, 0x0e},
-	{0x581e, 0x29},
-	{0x581f, 0x17},
-	{0x5820, 0x11},
-	{0x5821, 0x11},
-	{0x5822, 0x15},
-	{0x5823, 0x28},
-	{0x5824, 0x46},
-	{0x5825, 0x26},
-	{0x5826, 0x08},
-	{0x5827, 0x26},
-	{0x5828, 0x64},
-	{0x5829, 0x26},
-	{0x582a, 0x24},
-	{0x582b, 0x22},
-	{0x582c, 0x24},
-	{0x582d, 0x24},
-	{0x582e, 0x06},
-	{0x582f, 0x22},
-	{0x5830, 0x40},
-	{0x5831, 0x42},
-	{0x5832, 0x24},
-	{0x5833, 0x26},
-	{0x5834, 0x24},
-	{0x5835, 0x22},
-	{0x5836, 0x22},
-	{0x5837, 0x26},
-	{0x5838, 0x44},
-	{0x5839, 0x24},
-	{0x583a, 0x26},
-	{0x583b, 0x28},
-	{0x583c, 0x42},
-	{0x583d, 0xce},
-	{0x5025, 0x00},
-	{0x3a0f, 0x30},
-	{0x3a10, 0x28},
-	{0x3a1b, 0x30},
-	{0x3a1e, 0x26},
-	{0x3a11, 0x60},
-	{0x3a1f, 0x14},
-	{0x3008, 0x02},
-};
-
-struct ov5640_sensor ov5640_init_iq_tbl[] = {
-/* Lens correction */
-/* OV5640 LENC setting */
-	{0x5800, 0x3f},
-	{0x5801, 0x20},
-	{0x5802, 0x1a},
-	{0x5803, 0x1a},
-	{0x5804, 0x23},
-	{0x5805, 0x3f},
-	{0x5806, 0x11},
-	{0x5807, 0x0c},
-	{0x5808, 0x09},
-	{0x5809, 0x08},
-	{0x580a, 0x0d},
-	{0x580b, 0x12},
-	{0x580c, 0x0d},
-	{0x580d, 0x04},
-	{0x580e, 0x00},
-	{0x580f, 0x00},
-	{0x5810, 0x05},
-	{0x5811, 0x0d},
-	{0x5812, 0x0d},
-	{0x5813, 0x04},
-	{0x5814, 0x00},
-	{0x5815, 0x00},
-	{0x5816, 0x04},
-	{0x5817, 0x0d},
-	{0x5818, 0x13},
-	{0x5819, 0x0d},
-	{0x581a, 0x08},
-	{0x581b, 0x08},
-	{0x581c, 0x0c},
-	{0x581d, 0x13},
-	{0x581e, 0x3f},
-	{0x581f, 0x1f},
-	{0x5820, 0x1b},
-	{0x5821, 0x1c},
-	{0x5822, 0x23},
-	{0x5823, 0x3f},
-	{0x5824, 0x6a},
-	{0x5825, 0x06},
-	{0x5826, 0x08},
-	{0x5827, 0x06},
-	{0x5828, 0x2a},
-	{0x5829, 0x08},
-	{0x582a, 0x24},
-	{0x582b, 0x24},
-	{0x582c, 0x24},
-	{0x582d, 0x08},
-	{0x582e, 0x08},
-	{0x582f, 0x22},
-	{0x5830, 0x40},
-	{0x5831, 0x22},
-	{0x5832, 0x06},
-	{0x5833, 0x08},
-	{0x5834, 0x24},
-	{0x5835, 0x24},
-	{0x5836, 0x04},
-	{0x5837, 0x0a},
-	{0x5838, 0x86},
-	{0x5839, 0x08},
-	{0x583a, 0x28},
-	{0x583b, 0x28},
-	{0x583c, 0x66},
-	{0x583d, 0xce},
-/* AEC */
-	{0x3a0f, 0x38},
-	{0x3a10, 0x30},
-	{0x3a11, 0x61},
-	{0x3a1b, 0x38},
-	{0x3a1e, 0x30},
-	{0x3a1f, 0x10},
-	/* AWB */
-	{0x5180, 0xff},
-	{0x5181, 0xf2},
-	{0x5182, 0x00},
-	{0x5183, 0x14},
-	{0x5184, 0x25},
-	{0x5185, 0x24},
-	{0x5186, 0x09},
-	{0x5187, 0x09},
-	{0x5188, 0x09},
-	{0x5189, 0x88},
-	{0x518a, 0x54},
-	{0x518b, 0xee},
-	{0x518c, 0xb2},
-	{0x518d, 0x50},
-	{0x518e, 0x34},
-	{0x518f, 0x6b},
-	{0x5190, 0x46},
-	{0x5191, 0xf8},
-	{0x5192, 0x04},
-	{0x5193, 0x70},
-	{0x5194, 0xf0},
-	{0x5195, 0xf0},
-	{0x5196, 0x03},
-	{0x5197, 0x01},
-	{0x5198, 0x04},
-	{0x5199, 0x6c},
-	{0x519a, 0x04},
-	{0x519b, 0x00},
-	{0x519c, 0x09},
-	{0x519d, 0x2b},
-	{0x519e, 0x38},
-
-/* UV Adjust Auto Mode */
-	{0x5580, 0x02},	/* 02 ;Sat enable */
-	{0x5588, 0x01},	/*40 ;enable UV adj */
-	{0x5583, 0x40},	/*	;offset high */
-	{0x5584, 0x18},	/*	;offset low */
-	{0x5589, 0x18},	/*	;gth1	*/
-	{0x558a, 0x00},
-	{0x358b, 0xf8},	/*	;gth2 */
-};
-
-struct ov5640_sensor ov5640_preview_tbl[] = {
-/* @@ MIPI_2lane_5M to vga(YUV) 30fps 99 640 480 98 0 0 */
-	{0x3503, 0x00}, /* enable AE back from capture to preview */
-	{0x3035, 0x14},
-	{0x3036, 0x38},
-	{0x3820, 0x41},
-	{0x3821, 0x07},
-	{0x3814, 0x31},
-	{0x3815, 0x31},
-	{0x3803, 0x04},
-	{0x3807, 0x9b},
-	{0x3808, 0x02},
-	{0x3809, 0x80},
-	{0x380a, 0x01},
-	{0x380b, 0xe0},
-	{0x380c, 0x07},
-	{0x380d, 0x68},
-	{0x380e, 0x03},
-	{0x380f, 0xd8},
-	{0x3813, 0x06},
-	{0x3618, 0x00},
-	{0x3612, 0x29},
-	{0x3708, 0x64},
-	{0x3709, 0x52},
-	{0x370c, 0x03},
-	{0x5001, 0xa3},
-	{0x4004, 0x02},
-	{0x4005, 0x18},
-	{0x4837, 0x44},
-	{0x4713, 0x03},
-	{0x4407, 0x04},
-	{0x460b, 0x35},
-	{0x460c, 0x22},
-	{0x3824, 0x02},
-};
-
-struct ov5640_sensor ov5640_capture_tbl[] = {
-/* @@ MIPI_2lane_5M(YUV) 7.5/15fps 99 2592 1944 98 0 0 */
-	{0x3035, 0x21}, /* 11 */
-	{0x3036, 0x54},
-	{0x3820, 0x40},
-	{0x3821, 0x06},
-	{0x3814, 0x11},
-	{0x3815, 0x11},
-	{0x3803, 0x00},
-	{0x3807, 0x9f},
-	{0x3808, 0x0a},
-	{0x3809, 0x20},
-	{0x380a, 0x07},
-	{0x380b, 0x98},
-	{0x380c, 0x0b},
-	{0x380d, 0x1c},
-	{0x380e, 0x07},
-	{0x380f, 0xb0},
-	{0x3813, 0x04},
-	{0x3618, 0x04},
-	{0x3612, 0x2b},
-	{0x3708, 0x21},
-	{0x3709, 0x12},
-	{0x370c, 0x00},
-	{0x5001, 0x83},
-	{0x4004, 0x06},
-	{0x4005, 0x1a},
-	{0x4837, 0x15}, /* 0a */
-	{0x4713, 0x02},
-	{0x4407, 0x0c},
-	{0x460b, 0x37},
-	{0x460c, 0x20},
-	{0x3824, 0x01},
-};
-
-/* Contrast */
-
-struct ov5640_sensor ov5640_contrast_lv0_tbl[] = {
-/* Contrast -4 */
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5580, 0x04, INVMASK(0x04)}, /* Enable BIT2 for contrast/brightness
-					  control*/
-	{0x5586, 0x10},                /* Gain */
-	{0x5585, 0x10},                /* Offset */
-	{0x5588, 0x00, INVMASK(0x04)}, /* Offset sign */
-};
-
-struct ov5640_sensor ov5640_contrast_lv1_tbl[] = {
-/* Contrast -3 */
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5580, 0x04, INVMASK(0x04)}, /* Enable BIT2 for contrast/brightness
-					  control */
-	{0x5586, 0x14},                /* Gain */
-	{0x5585, 0x14},                /* Offset */
-	{0x5588, 0x00, INVMASK(0x04)}, /* Offset sign */
-};
-
-struct ov5640_sensor ov5640_contrast_lv2_tbl[] = {
-/* Contrast -2 */
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5580, 0x04, INVMASK(0x04)}, /* Enable BIT2 for contrast/brightness
-					  control */
-	{0x5586, 0x18},                /* Gain */
-	{0x5585, 0x18},                /* Offset */
-	{0x5588, 0x00, INVMASK(0x04)}, /* Offset sign */
-};
-
-struct ov5640_sensor ov5640_contrast_lv3_tbl[] = {
-/* Contrast -1 */
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5580, 0x04, INVMASK(0x04)},
-	{0x5586, 0x1c},
-	{0x5585, 0x1c},
-	{0x5588, 0x00, INVMASK(0x04)},
-};
-
-struct ov5640_sensor ov5640_contrast_default_lv4_tbl[] = {
-/* Contrast (Default) */
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5580, 0x04, INVMASK(0x04)},
-	{0x5586, 0x20},
-	{0x5585, 0x00},
-	{0x5588, 0x00, INVMASK(0x04)},
-};
-
-struct ov5640_sensor ov5640_contrast_lv5_tbl[] = {
-/* Contrast +1 */
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5580, 0x04, INVMASK(0x04)},
-	{0x5586, 0x24},
-	{0x5585, 0x10},
-	{0x5588, 0x00, INVMASK(0x04)},
-};
-
-struct ov5640_sensor ov5640_contrast_lv6_tbl[] = {
-/* Contrast +2 */
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5580, 0x04, INVMASK(0x04)},
-	{0x5586, 0x28},
-	{0x5585, 0x18},
-	{0x5588, 0x00, INVMASK(0x04)},
-};
-
-struct ov5640_sensor ov5640_contrast_lv7_tbl[] = {
-/* Contrast +3 */
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5580, 0x04, INVMASK(0x04)},
-	{0x5586, 0x2c},
-	{0x5585, 0x1c},
-	{0x5588, 0x00, INVMASK(0x04)},
-};
-
-struct ov5640_sensor ov5640_contrast_lv8_tbl[] = {
-/* Contrast +4 */
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5580, 0x04, INVMASK(0x04)},
-	{0x5586, 0x30},
-	{0x5585, 0x20},
-	{0x5588, 0x00, INVMASK(0x04)},
-};
-
-/* Sharpness */
-
-struct ov5640_sensor ov5640_sharpness_lv0_tbl[] = {
-/* Sharpness 0 */
-	{0x5308, 0x40, INVMASK(0x40)},
-	{0x5302, 0x00},
-};
-
-struct ov5640_sensor ov5640_sharpness_lv1_tbl[] = {
-/* Sharpness 1 */
-	{0x5308, 0x40, INVMASK(0x40)},
-	{0x5302, 0x02},
-};
-
-struct ov5640_sensor ov5640_sharpness_default_lv2_tbl[] = {
-/* Sharpness_Auto (Default) */
-	{0x5308, 0x00, INVMASK(0x40)},
-	{0x5300, 0x08},
-	{0x5301, 0x30},
-	{0x5302, 0x10},
-	{0x5303, 0x00},
-	{0x5309, 0x08},
-	{0x530a, 0x30},
-	{0x530b, 0x04},
-	{0x530c, 0x06},
-};
-
-struct ov5640_sensor ov5640_sharpness_lv3_tbl[] = {
-/* Sharpness 3 */
-	{0x5308, 0x40, INVMASK(0x40)},
-	{0x5302, 0x08},
-};
-
-struct ov5640_sensor ov5640_sharpness_lv4_tbl[] = {
-/* Sharpness 4 */
-	{0x5308, 0x40, INVMASK(0x40)},
-	{0x5302, 0x0c},
-};
-
-struct ov5640_sensor ov5640_sharpness_lv5_tbl[] = {
-/* Sharpness 5 */
-	{0x5308, 0x40, INVMASK(0x40)},
-	{0x5302, 0x10},
-};
-
-struct ov5640_sensor ov5640_sharpness_lv6_tbl[] = {
-/* Sharpness 6 */
-	{0x5308, 0x40, INVMASK(0x40)},
-	{0x5302, 0x14},
-};
-
-struct ov5640_sensor ov5640_sharpness_lv7_tbl[] = {
-/* Sharpness 7 */
-	{0x5308, 0x40, INVMASK(0x40)},
-	{0x5302, 0x18},
-};
-
-struct ov5640_sensor ov5640_sharpness_lv8_tbl[] = {
-/* Sharpness 8 */
-	{0x5308, 0x40, INVMASK(0x40)},
-	{0x5302, 0x20},
-};
-
-/* Saturation */
-
-struct ov5640_sensor ov5640_saturation_lv0_tbl[] = {
-/* Saturation x0.25 */
-	{0x5001, 0x83, INVMASK(0x80)},  /* SDE_En */
-	{0x5583, 0x00},                 /* Saturaion gain in U */
-	{0x5584, 0x00},                 /* Saturation gain in V */
-	{0x5580, 0x02, INVMASK(0x02)},  /* Saturation enable */
-	{0x5588, 0x40, INVMASK(0x40)},
-};
-
-struct ov5640_sensor ov5640_saturation_lv1_tbl[] = {
-/* Saturation x0.5 */
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5583, 0x10},
-	{0x5584, 0x10},
-	{0x5580, 0x02, INVMASK(0x02)},
-	{0x5588, 0x40, INVMASK(0x40)},
-};
-
-struct ov5640_sensor ov5640_saturation_lv2_tbl[] = {
-/* Saturation x0.75 */
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5583, 0x20},
-	{0x5584, 0x20},
-	{0x5580, 0x02, INVMASK(0x02)},
-	{0x5588, 0x40, INVMASK(0x40)},
-};
-
-struct ov5640_sensor ov5640_saturation_lv3_tbl[] = {
-/* Saturation x0.75 */
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5583, 0x30},
-	{0x5584, 0x30},
-	{0x5580, 0x02, INVMASK(0x02)},
-	{0x5588, 0x40, INVMASK(0x40)},
-};
-
-struct ov5640_sensor ov5640_saturation_default_lv4_tbl[] = {
-/* Saturation x1 (Default) */
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5583, 0x40},
-	{0x5584, 0x40},
-	{0x5580, 0x02, INVMASK(0x02)},
-	{0x5588, 0x40, INVMASK(0x40)},
-};
-
-struct ov5640_sensor ov5640_saturation_lv5_tbl[] = {
-/* Saturation x1.25 */
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5583, 0x50},
-	{0x5584, 0x50},
-	{0x5580, 0x02, INVMASK(0x02)},
-	{0x5588, 0x40, INVMASK(0x40)},
-};
-
-struct ov5640_sensor ov5640_saturation_lv6_tbl[] = {
-/* Saturation x1.5 */
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5583, 0x60},
-	{0x5584, 0x60},
-	{0x5580, 0x02, INVMASK(0x02)},
-	{0x5588, 0x40, INVMASK(0x40)},
-};
-
-struct ov5640_sensor ov5640_saturation_lv7_tbl[] = {
-/* Saturation x1.25 */
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5583, 0x70},
-	{0x5584, 0x70},
-	{0x5580, 0x02, INVMASK(0x02)},
-	{0x5588, 0x40, INVMASK(0x40)},
-};
-
-struct ov5640_sensor ov5640_saturation_lv8_tbl[] = {
-/* Saturation x1.5 */
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5583, 0x80},
-	{0x5584, 0x80},
-	{0x5580, 0x02, INVMASK(0x02)},
-	{0x5588, 0x40, INVMASK(0x40)},
-};
-
-/* Brightness */
-
-struct ov5640_sensor ov5640_brightness_lv0_tbl[] = {
-/* Brightness -4 */
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5587, 0x40},
-	{0x5580, 0x04, INVMASK(0x04)},
-	{0x5588, 0x08, INVMASK(0x08)},
-};
-
-struct ov5640_sensor ov5640_brightness_lv1_tbl[] = {
-/* Brightness -3 */
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5587, 0x30},
-	{0x5580, 0x04, INVMASK(0x04)},
-	{0x5588, 0x08, INVMASK(0x08)},
-};
-
-struct ov5640_sensor ov5640_brightness_lv2_tbl[] = {
-/* Brightness -2 */
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5587, 0x20},
-	{0x5580, 0x04, INVMASK(0x04)},
-	{0x5588, 0x08, INVMASK(0x08)},
-};
-
-struct ov5640_sensor ov5640_brightness_lv3_tbl[] = {
-/* Brightness -1 */
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5587, 0x10},
-	{0x5580, 0x04, INVMASK(0x04)},
-	{0x5588, 0x08, INVMASK(0x08)},
-};
-
-struct ov5640_sensor ov5640_brightness_default_lv4_tbl[] = {
-/* Brightness 0 (Default) */
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5587, 0x00},
-	{0x5580, 0x04, INVMASK(0x04)},
-	{0x5588, 0x00, INVMASK(0x08)},
-};
-
-struct ov5640_sensor ov5640_brightness_lv5_tbl[] = {
-/* Brightness +1 */
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5587, 0x10},
-	{0x5580, 0x04, INVMASK(0x04)},
-	{0x5588, 0x00, INVMASK(0x08)},
-};
-
-struct ov5640_sensor ov5640_brightness_lv6_tbl[] = {
-/* Brightness +2 */
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5587, 0x20},
-	{0x5580, 0x04, INVMASK(0x04)},
-	{0x5588, 0x00, INVMASK(0x08)},
-};
-
-struct ov5640_sensor ov5640_brightness_lv7_tbl[] = {
-/* Brightness +3 */
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5587, 0x30},
-	{0x5580, 0x04, INVMASK(0x04)},
-	{0x5588, 0x00, INVMASK(0x08)},
-};
-
-struct ov5640_sensor ov5640_brightness_lv8_tbl[] = {
-/* Brightness +4 */
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5587, 0x40},
-	{0x5580, 0x04, INVMASK(0x04)},
-	{0x5588, 0x00, INVMASK(0x08)},
-};
-
-/* Exposure Compensation */
-struct ov5640_sensor ov5640_exposure_compensation_lv0_tbl[] = {
-	/* @@ +1.7EV */
-	{0x3a0f, 0x60},
-	{0x3a10, 0x58},
-	{0x3a11, 0xa0},
-	{0x3a1b, 0x60},
-	{0x3a1e, 0x58},
-	{0x3a1f, 0x20},
-};
-
-struct ov5640_sensor ov5640_exposure_compensation_lv1_tbl[] = {
-	/* @@ +1.0EV */
-	{0x3a0f, 0x50},
-	{0x3a10, 0x48},
-	{0x3a11, 0x90},
-	{0x3a1b, 0x50},
-	{0x3a1e, 0x48},
-	{0x3a1f, 0x20},
-};
-
-struct ov5640_sensor ov5640_exposure_compensation_lv2_default_tbl[] = {
-	/* @@ default */
-	{0x3a0f, 0x38},
-	{0x3a10, 0x30},
-	{0x3a11, 0x61},
-	{0x3a1b, 0x38},
-	{0x3a1e, 0x30},
-	{0x3a1f, 0x10},
-};
-
-struct ov5640_sensor ov5640_exposure_compensation_lv3_tbl[] = {
-	/* @@ -1.0EV */
-	{0x3a0f, 0x20},
-	{0x3a10, 0x18},
-	{0x3a11, 0x41},
-	{0x3a1b, 0x20},
-	{0x3a1e, 0x18},
-	{0x3a1f, 0x10},
-};
-
-struct ov5640_sensor ov5640_exposure_compensation_lv4_tbl[] = {
-	/* @@ -1.7EV */
-	{0x3a0f, 0x10},
-	{0x3a10, 0x08},
-	{0x3a11, 0x10},
-	{0x3a1b, 0x08},
-	{0x3a1e, 0x20},
-	{0x3a1f, 0x10},
-};
-
-/* Auto Expourse Weight */
-
-struct ov5640_sensor ov5640_ae_average_tbl[] = {
-  /* Whole Image Average */
-	{0x5688, 0x11}, /* Zone 1/Zone 0 weight */
-	{0x5689, 0x11}, /* Zone 3/Zone 2 weight */
-	{0x569a, 0x11}, /* Zone 5/Zone 4 weight */
-	{0x569b, 0x11}, /* Zone 7/Zone 6 weight */
-	{0x569c, 0x11}, /* Zone 9/Zone 8 weight */
-	{0x569d, 0x11}, /* Zone b/Zone a weight */
-	{0x569e, 0x11}, /* Zone d/Zone c weight */
-	{0x569f, 0x11}, /* Zone f/Zone e weight */
-};
-
-struct ov5640_sensor ov5640_ae_centerweight_tbl[] = {
-  /* Whole Image Center More weight */
-	{0x5688, 0x62},
-	{0x5689, 0x26},
-	{0x568a, 0xe6},
-	{0x568b, 0x6e},
-	{0x568c, 0xea},
-	{0x568d, 0xae},
-	{0x568e, 0xa6},
-	{0x568f, 0x6a},
-};
-
-/* Light Mode */
-struct ov5640_sensor ov5640_wb_def[] = {
-	{0x3406, 0x00, INVMASK(0x01)},
-};
-
-struct ov5640_sensor ov5640_wb_custom[] = {
-	{0x3406, 0x01, INVMASK(0x01)},
-	{0x3400, 0x04},
-	{0x3401, 0x58},
-	{0x3402, 0x04},
-	{0x3403, 0x00},
-	{0x3404, 0x08},
-	{0x3405, 0x40},
-};
-
-struct ov5640_sensor ov5640_wb_inc[] = {
-	{0x3406, 0x01, INVMASK(0x01)},
-	{0x3400, 0x04},
-	{0x3401, 0x88},
-	{0x3402, 0x04},
-	{0x3403, 0x00},
-	{0x3404, 0x08},
-	{0x3405, 0xb6},
-};
-
-struct ov5640_sensor ov5640_wb_daylight[] = {
-	{0x3406, 0x01, INVMASK(0x01)},
-	{0x3400, 0x07},
-	{0x3401, 0x02},
-	{0x3402, 0x04},
-	{0x3403, 0x00},
-	{0x3404, 0x05},
-	{0x3405, 0x15},
-};
-
-struct ov5640_sensor ov5640_wb_cloudy[] = {
-	{0x3406, 0x01, INVMASK(0x01)},
-	{0x3400, 0x07},
-	{0x3401, 0x88},
-	{0x3402, 0x04},
-	{0x3403, 0x00},
-	{0x3404, 0x05},
-	{0x3405, 0x00},
-};
-
-/* EFFECT */
-struct ov5640_sensor ov5640_effect_normal_tbl[] = {
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5580, 0x00, INVMASK(0x78)},
-	{0x5003, 0x08},
-	{0x5583, 0x40},
-	{0x5584, 0x40},
-};
-
-struct ov5640_sensor ov5640_effect_mono_tbl[] = {
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5580, 0x20, INVMASK(0x78)},
-	{0x5003, 0x08},
-	{0x5583, 0x40},
-	{0x5584, 0x40},
-};
-
-struct ov5640_sensor ov5640_effect_bw_tbl[] = {
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5580, 0x18, INVMASK(0x78)},
-	{0x5003, 0x08},
-	{0x5583, 0x80},
-	{0x5584, 0x80},
-};
-
-struct ov5640_sensor ov5640_effect_bluish_tbl[] = {
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5580, 0x18, INVMASK(0x78)},
-	{0x5003, 0x08},
-	{0x5583, 0xa0},
-	{0x5584, 0x40},
-};
-
-struct ov5640_sensor ov5640_effect_solarize_tbl[] = {
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5580, 0x00, INVMASK(0x78)},
-	{0x5003, 0x09},
-};
-
-
-struct ov5640_sensor ov5640_effect_sepia_tbl[] = {
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5580, 0x18, INVMASK(0x78)},
-	{0x5003, 0x08},
-	{0x5583, 0x40},
-	{0x5584, 0xa0},
-};
-
-struct ov5640_sensor ov5640_effect_reddish_tbl[] = {
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5580, 0x18, INVMASK(0x78)},
-	{0x5003, 0x08},
-	{0x5583, 0x80},
-	{0x5584, 0xc0},
-};
-
-struct ov5640_sensor ov5640_effect_greenish_tbl[] = {
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5580, 0x18, INVMASK(0x78)},
-	{0x5003, 0x08},
-	{0x5583, 0x60},
-	{0x5584, 0x60},
-};
-
-struct ov5640_sensor ov5640_effect_negative_tbl[] = {
-	{0x5001, 0x83, INVMASK(0x80)},
-	{0x5580, 0x40, INVMASK(0x78)},
-	{0x5003, 0x08},
-};
-
-/* AntiBanding */
-struct ov5640_sensor ov5640_antibanding_auto_tbl[] = {
-  /* Auto-XCLK24MHz */
-	{0x3622, 0x01}, /* PD-sel */
-	{0x3635, 0x1c}, /* VMREF 3635[2:0] */
-	{0x3634, 0x40}, /* I_5060 3643[2:0] */
-	{0x3c01, 0x34},
-	{0x3c00, 0x00},
-	{0x3c04, 0x28},
-	{0x3c05, 0x98},
-	{0x3c06, 0x00},
-	{0x3c07, 0x08},
-	{0x3c08, 0x00},
-	{0x3c09, 0x1c},
-	{0x300c, 0x22}, /* 50/60div 300c[2:0] */
-	{0x3c0a, 0x9c},
-	{0x3c0b, 0x40},
-};
-
-struct ov5640_sensor ov5640_antibanding_50z_tbl[] = {
-  /* Band 50Hz */
-	{0x3c01, 0x80, INVMASK(0x80)},
-	{0x3c00, 0x04},
-};
-
-struct ov5640_sensor ov5640_antibanding_60z_tbl[] = {
-  /* Band 60Hz */
-	{0x3c01, 0x80, INVMASK(0x80)},
-	{0x3c00, 0x00},
-};
-
-
-/* Lens_shading */
-
-struct ov5640_sensor ov5640_lens_shading_on_tbl[] = {
-	/* @@ Lenc On(C) */
-	{0x5000, 0x80, INVMASK(0x80)},
-};
-
-struct ov5640_sensor ov5640_lens_shading_off_tbl[] = {
-	/*  Lenc Off */
-	{0x5000, 0x00, INVMASK(0x80)},
-};
-
-/* Auto Focus Firmware-use 2011-08-24 firmware settings */
-u8 ov5640_afinit_tbl[] = {
-	0x80,	0x00,	0x02,	0x0b,	0x7b,	0x02,	0x07,	0xbd,	0xc2,
-	0x01,	0x22,	0x22,	0x00,	0x02,	0x0b,	0x57,	0xe5,	0x1f,
-	0x70,	0x72,	0xf5,	0x1e,	0xd2,	0x35,	0xff,	0xef,	0x25,
-	0xe0,	0x24,	0x4b,	0xf8,	0xe4,	0xf6,	0x08,	0xf6,	0x0f,
-	0xbf,	0x34,	0xf2,	0x90,	0x0e,	0x88,	0xe4,	0x93,	0xff,
-	0xe5,	0x49,	0xc3,	0x9f,	0x50,	0x04,	0x7f,	0x05,	0x80,
-	0x02,	0x7f,	0xfb,	0x78,	0xba,	0xa6,	0x07,	0x12,	0x0a,
-	0xb4,	0x40,	0x04,	0x7f,	0x03,	0x80,	0x02,	0x7f,	0x30,
-	0x78,	0xb9,	0xa6,	0x07,	0xe6,	0x18,	0xf6,	0x08,	0xe6,
-	0x78,	0xb6,	0xf6,	0x78,	0xb9,	0xe6,	0x78,	0xb7,	0xf6,
-	0x78,	0xbc,	0x76,	0x33,	0xe4,	0x08,	0xf6,	0x78,	0xb5,
-	0x76,	0x01,	0x75,	0x48,	0x02,	0x78,	0xb3,	0xf6,	0x08,
-	0xf6,	0x74,	0xff,	0x78,	0xbe,	0xf6,	0x08,	0xf6,	0x75,
-	0x1f,	0x01,	0x78,	0xb9,	0xe6,	0x75,	0xf0,	0x05,	0xa4,
-	0xf5,	0x49,	0x12,	0x08,	0x5b,	0xc2,	0x37,	0x22,	0x78,
-	0xb5,	0xe6,	0xd3,	0x94,	0x00,	0x40,	0x02,	0x16,	0x22,
-	0xe5,	0x1f,	0x64,	0x05,	0x70,	0x28,	0xf5,	0x1f,	0xc2,
-	0x01,	0x78,	0xb6,	0xe6,	0x25,	0xe0,	0x24,	0x4b,	0xf8,
-	0xe6,	0xfe,	0x08,	0xe6,	0xff,	0x78,	0x4b,	0xa6,	0x06,
-	0x08,	0xa6,	0x07,	0xa2,	0x37,	0xe4,	0x33,	0xf5,	0x3c,
-	0x90,	0x30,	0x28,	0xf0,	0x75,	0x1e,	0x10,	0xd2,	0x35,
-	0x22,	0xe5,	0x49,	0x75,	0xf0,	0x05,	0x84,	0x78,	0xb9,
-	0xf6,	0x90,	0x0e,	0x85,	0xe4,	0x93,	0xff,	0x25,	0xe0,
-	0x24,	0x0a,	0xf8,	0xe6,	0xfc,	0x08,	0xe6,	0xfd,	0x78,
-	0xb9,	0xe6,	0x25,	0xe0,	0x24,	0x4b,	0xf8,	0xa6,	0x04,
-	0x08,	0xa6,	0x05,	0xef,	0x12,	0x0a,	0xbb,	0xd3,	0x78,
-	0xb4,	0x96,	0xee,	0x18,	0x96,	0x40,	0x0d,	0x78,	0xb9,
-	0xe6,	0x78,	0xb6,	0xf6,	0x78,	0xb3,	0xa6,	0x06,	0x08,
-	0xa6,	0x07,	0x90,	0x0e,	0x85,	0xe4,	0x93,	0x12,	0x0a,
-	0xbb,	0xc3,	0x78,	0xbf,	0x96,	0xee,	0x18,	0x96,	0x50,
-	0x0d,	0x78,	0xb9,	0xe6,	0x78,	0xb7,	0xf6,	0x78,	0xbe,
-	0xa6,	0x06,	0x08,	0xa6,	0x07,	0x78,	0xb3,	0xe6,	0xfe,
-	0x08,	0xe6,	0xc3,	0x78,	0xbf,	0x96,	0xff,	0xee,	0x18,
-	0x96,	0x78,	0xc0,	0xf6,	0x08,	0xa6,	0x07,	0x90,	0x0e,
-	0x8a,	0xe4,	0x18,	0x12,	0x0a,	0x99,	0xc3,	0x33,	0xce,
-	0x33,	0xce,	0xd8,	0xf9,	0xff,	0xd3,	0xed,	0x9f,	0xec,
-	0x9e,	0x40,	0x02,	0xd2,	0x37,	0x78,	0xb9,	0xe6,	0x08,
-	0x26,	0x08,	0xf6,	0xe5,	0x1f,	0x64,	0x01,	0x70,	0x55,
-	0xe6,	0xc3,	0x78,	0xbd,	0x12,	0x0a,	0x8f,	0x40,	0x10,
-	0x12,	0x0a,	0x8a,	0x50,	0x0b,	0x30,	0x37,	0x41,	0x78,
-	0xb9,	0xe6,	0x78,	0xb6,	0x66,	0x60,	0x39,	0x12,	0x0a,
-	0xb2,	0x40,	0x04,	0x7f,	0xfe,	0x80,	0x02,	0x7f,	0x02,
-	0x78,	0xba,	0xa6,	0x07,	0x78,	0xb6,	0xe6,	0x24,	0x03,
-	0x78,	0xbc,	0xf6,	0x78,	0xb6,	0xe6,	0x24,	0xfd,	0x78,
-	0xbd,	0xf6,	0x12,	0x0a,	0xb2,	0x40,	0x06,	0x78,	0xbd,
-	0xe6,	0xff,	0x80,	0x04,	0x78,	0xbc,	0xe6,	0xff,	0x78,
-	0xbb,	0xa6,	0x07,	0x75,	0x1f,	0x02,	0x78,	0xb5,	0x76,
-	0x01,	0x02,	0x02,	0x68,	0xe5,	0x1f,	0x64,	0x02,	0x60,
-	0x03,	0x02,	0x02,	0x48,	0x78,	0xbb,	0xe6,	0xff,	0xc3,
-	0x78,	0xbd,	0x12,	0x0a,	0x90,	0x40,	0x08,	0x12,	0x0a,
-	0x8a,	0x50,	0x03,	0x02,	0x02,	0x46,	0x12,	0x0a,	0xb2,
-	0x40,	0x04,	0x7f,	0xff,	0x80,	0x02,	0x7f,	0x01,	0x78,
-	0xba,	0xa6,	0x07,	0x78,	0xb6,	0xe6,	0x04,	0x78,	0xbc,
-	0xf6,	0x78,	0xb6,	0xe6,	0x14,	0x78,	0xbd,	0xf6,	0x18,
-	0x12,	0x0a,	0xb4,	0x40,	0x04,	0xe6,	0xff,	0x80,	0x02,
-	0x7f,	0x00,	0x78,	0xbc,	0xa6,	0x07,	0xd3,	0x08,	0xe6,
-	0x64,	0x80,	0x94,	0x80,	0x40,	0x04,	0xe6,	0xff,	0x80,
-	0x02,	0x7f,	0x00,	0x78,	0xbd,	0xa6,	0x07,	0xc3,	0x18,
-	0xe6,	0x64,	0x80,	0x94,	0xb3,	0x50,	0x04,	0xe6,	0xff,
-	0x80,	0x02,	0x7f,	0x33,	0x78,	0xbc,	0xa6,	0x07,	0xc3,
-	0x08,	0xe6,	0x64,	0x80,	0x94,	0xb3,	0x50,	0x04,	0xe6,
-	0xff,	0x80,	0x02,	0x7f,	0x33,	0x78,	0xbd,	0xa6,	0x07,
-	0x12,	0x0a,	0xb2,	0x40,	0x06,	0x78,	0xbd,	0xe6,	0xff,
-	0x80,	0x04,	0x78,	0xbc,	0xe6,	0xff,	0x78,	0xbb,	0xa6,
-	0x07,	0x75,	0x1f,	0x03,	0x78,	0xb5,	0x76,	0x01,	0x80,
-	0x20,	0xe5,	0x1f,	0x64,	0x03,	0x70,	0x26,	0x78,	0xbb,
-	0xe6,	0xff,	0xc3,	0x78,	0xbd,	0x12,	0x0a,	0x90,	0x40,
-	0x05,	0x12,	0x0a,	0x8a,	0x40,	0x09,	0x78,	0xb6,	0xe6,
-	0x78,	0xbb,	0xf6,	0x75,	0x1f,	0x04,	0x78,	0xbb,	0xe6,
-	0x75,	0xf0,	0x05,	0xa4,	0xf5,	0x49,	0x02,	0x08,	0x5b,
-	0xe5,	0x1f,	0xb4,	0x04,	0x1d,	0x90,	0x0e,	0x89,	0xe4,
-	0x78,	0xc0,	0x12,	0x0a,	0x99,	0xc3,	0x33,	0xce,	0x33,
-	0xce,	0xd8,	0xf9,	0xff,	0xd3,	0xed,	0x9f,	0xec,	0x9e,
-	0x40,	0x02,	0xd2,	0x37,	0x75,	0x1f,	0x05,	0x22,	0xef,
-	0x8d,	0xf0,	0xa4,	0xa8,	0xf0,	0xcf,	0x8c,	0xf0,	0xa4,
-	0x28,	0xce,	0x8d,	0xf0,	0xa4,	0x2e,	0xfe,	0x22,	0xbc,
-	0x00,	0x0b,	0xbe,	0x00,	0x29,	0xef,	0x8d,	0xf0,	0x84,
-	0xff,	0xad,	0xf0,	0x22,	0xe4,	0xcc,	0xf8,	0x75,	0xf0,
-	0x08,	0xef,	0x2f,	0xff,	0xee,	0x33,	0xfe,	0xec,	0x33,
-	0xfc,	0xee,	0x9d,	0xec,	0x98,	0x40,	0x05,	0xfc,	0xee,
-	0x9d,	0xfe,	0x0f,	0xd5,	0xf0,	0xe9,	0xe4,	0xce,	0xfd,
-	0x22,	0xed,	0xf8,	0xf5,	0xf0,	0xee,	0x84,	0x20,	0xd2,
-	0x1c,	0xfe,	0xad,	0xf0,	0x75,	0xf0,	0x08,	0xef,	0x2f,
-	0xff,	0xed,	0x33,	0xfd,	0x40,	0x07,	0x98,	0x50,	0x06,
-	0xd5,	0xf0,	0xf2,	0x22,	0xc3,	0x98,	0xfd,	0x0f,	0xd5,
-	0xf0,	0xea,	0x22,	0xe8,	0x8f,	0xf0,	0xa4,	0xcc,	0x8b,
-	0xf0,	0xa4,	0x2c,	0xfc,	0xe9,	0x8e,	0xf0,	0xa4,	0x2c,
-	0xfc,	0x8a,	0xf0,	0xed,	0xa4,	0x2c,	0xfc,	0xea,	0x8e,
-	0xf0,	0xa4,	0xcd,	0xa8,	0xf0,	0x8b,	0xf0,	0xa4,	0x2d,
-	0xcc,	0x38,	0x25,	0xf0,	0xfd,	0xe9,	0x8f,	0xf0,	0xa4,
-	0x2c,	0xcd,	0x35,	0xf0,	0xfc,	0xeb,	0x8e,	0xf0,	0xa4,
-	0xfe,	0xa9,	0xf0,	0xeb,	0x8f,	0xf0,	0xa4,	0xcf,	0xc5,
-	0xf0,	0x2e,	0xcd,	0x39,	0xfe,	0xe4,	0x3c,	0xfc,	0xea,
-	0xa4,	0x2d,	0xce,	0x35,	0xf0,	0xfd,	0xe4,	0x3c,	0xfc,
-	0x22,	0x75,	0xf0,	0x08,	0x75,	0x82,	0x00,	0xef,	0x2f,
-	0xff,	0xee,	0x33,	0xfe,	0xcd,	0x33,	0xcd,	0xcc,	0x33,
-	0xcc,	0xc5,	0x82,	0x33,	0xc5,	0x82,	0x9b,	0xed,	0x9a,
-	0xec,	0x99,	0xe5,	0x82,	0x98,	0x40,	0x0c,	0xf5,	0x82,
-	0xee,	0x9b,	0xfe,	0xed,	0x9a,	0xfd,	0xec,	0x99,	0xfc,
-	0x0f,	0xd5,	0xf0,	0xd6,	0xe4,	0xce,	0xfb,	0xe4,	0xcd,
-	0xfa,	0xe4,	0xcc,	0xf9,	0xa8,	0x82,	0x22,	0xb8,	0x00,
-	0xc1,	0xb9,	0x00,	0x59,	0xba,	0x00,	0x2d,	0xec,	0x8b,
-	0xf0,	0x84,	0xcf,	0xce,	0xcd,	0xfc,	0xe5,	0xf0,	0xcb,
-	0xf9,	0x78,	0x18,	0xef,	0x2f,	0xff,	0xee,	0x33,	0xfe,
-	0xed,	0x33,	0xfd,	0xec,	0x33,	0xfc,	0xeb,	0x33,	0xfb,
-	0x10,	0xd7,	0x03,	0x99,	0x40,	0x04,	0xeb,	0x99,	0xfb,
-	0x0f,	0xd8,	0xe5,	0xe4,	0xf9,	0xfa,	0x22,	0x78,	0x18,
-	0xef,	0x2f,	0xff,	0xee,	0x33,	0xfe,	0xed,	0x33,	0xfd,
-	0xec,	0x33,	0xfc,	0xc9,	0x33,	0xc9,	0x10,	0xd7,	0x05,
-	0x9b,	0xe9,	0x9a,	0x40,	0x07,	0xec,	0x9b,	0xfc,	0xe9,
-	0x9a,	0xf9,	0x0f,	0xd8,	0xe0,	0xe4,	0xc9,	0xfa,	0xe4,
-	0xcc,	0xfb,	0x22,	0x75,	0xf0,	0x10,	0xef,	0x2f,	0xff,
-	0xee,	0x33,	0xfe,	0xed,	0x33,	0xfd,	0xcc,	0x33,	0xcc,
-	0xc8,	0x33,	0xc8,	0x10,	0xd7,	0x07,	0x9b,	0xec,	0x9a,
-	0xe8,	0x99,	0x40,	0x0a,	0xed,	0x9b,	0xfd,	0xec,	0x9a,
-	0xfc,	0xe8,	0x99,	0xf8,	0x0f,	0xd5,	0xf0,	0xda,	0xe4,
-	0xcd,	0xfb,	0xe4,	0xcc,	0xfa,	0xe4,	0xc8,	0xf9,	0x22,
-	0xeb,	0x9f,	0xf5,	0xf0,	0xea,	0x9e,	0x42,	0xf0,	0xe9,
-	0x9d,	0x42,	0xf0,	0xe8,	0x9c,	0x45,	0xf0,	0x22,	0xe8,
-	0x60,	0x0f,	0xef,	0xc3,	0x33,	0xff,	0xee,	0x33,	0xfe,
-	0xed,	0x33,	0xfd,	0xec,	0x33,	0xfc,	0xd8,	0xf1,	0x22,
-	0xe4,	0x93,	0xfc,	0x74,	0x01,	0x93,	0xfd,	0x74,	0x02,
-	0x93,	0xfe,	0x74,	0x03,	0x93,	0xff,	0x22,	0xe6,	0xfb,
-	0x08,	0xe6,	0xf9,	0x08,	0xe6,	0xfa,	0x08,	0xe6,	0xcb,
-	0xf8,	0x22,	0xec,	0xf6,	0x08,	0xed,	0xf6,	0x08,	0xee,
-	0xf6,	0x08,	0xef,	0xf6,	0x22,	0xa4,	0x25,	0x82,	0xf5,
-	0x82,	0xe5,	0xf0,	0x35,	0x83,	0xf5,	0x83,	0x22,	0xd0,
-	0x83,	0xd0,	0x82,	0xf8,	0xe4,	0x93,	0x70,	0x12,	0x74,
-	0x01,	0x93,	0x70,	0x0d,	0xa3,	0xa3,	0x93,	0xf8,	0x74,
-	0x01,	0x93,	0xf5,	0x82,	0x88,	0x83,	0xe4,	0x73,	0x74,
-	0x02,	0x93,	0x68,	0x60,	0xef,	0xa3,	0xa3,	0xa3,	0x80,
-	0xdf,	0x90,	0x38,	0x04,	0x78,	0x4f,	0x12,	0x09,	0x50,
-	0x90,	0x38,	0x00,	0xe0,	0xfe,	0xa3,	0xe0,	0xfd,	0xed,
-	0xff,	0xc3,	0x12,	0x09,	0x09,	0x90,	0x38,	0x10,	0x12,
-	0x08,	0xfd,	0x90,	0x38,	0x06,	0x78,	0x51,	0x12,	0x09,
-	0x50,	0x90,	0x38,	0x02,	0xe0,	0xfe,	0xa3,	0xe0,	0xfd,
-	0xed,	0xff,	0xc3,	0x12,	0x09,	0x09,	0x90,	0x38,	0x12,
-	0x12,	0x08,	0xfd,	0xa3,	0xe0,	0xb4,	0x31,	0x07,	0x78,
-	0x4f,	0x79,	0x4f,	0x12,	0x09,	0x66,	0x90,	0x38,	0x14,
-	0xe0,	0xb4,	0x71,	0x15,	0x78,	0x4f,	0xe6,	0xfe,	0x08,
-	0xe6,	0x78,	0x02,	0xce,	0xc3,	0x13,	0xce,	0x13,	0xd8,
-	0xf9,	0x79,	0x50,	0xf7,	0xee,	0x19,	0xf7,	0x90,	0x38,
-	0x15,	0xe0,	0xb4,	0x31,	0x07,	0x78,	0x51,	0x79,	0x51,
-	0x12,	0x09,	0x66,	0x90,	0x38,	0x15,	0xe0,	0xb4,	0x71,
-	0x15,	0x78,	0x51,	0xe6,	0xfe,	0x08,	0xe6,	0x78,	0x02,
-	0xce,	0xc3,	0x13,	0xce,	0x13,	0xd8,	0xf9,	0x79,	0x52,
-	0xf7,	0xee,	0x19,	0xf7,	0x79,	0x4f,	0x12,	0x09,	0x38,
-	0x09,	0x12,	0x09,	0x38,	0xaf,	0x45,	0x12,	0x08,	0xee,
-	0x7d,	0x50,	0x12,	0x02,	0xa9,	0x78,	0x57,	0xa6,	0x06,
-	0x08,	0xa6,	0x07,	0xaf,	0x43,	0x12,	0x08,	0xee,	0x7d,
-	0x50,	0x12,	0x02,	0xa9,	0x78,	0x53,	0xa6,	0x06,	0x08,
-	0xa6,	0x07,	0xaf,	0x46,	0x78,	0x51,	0x12,	0x08,	0xf0,
-	0x7d,	0x3c,	0x12,	0x02,	0xa9,	0x78,	0x59,	0xa6,	0x06,
-	0x08,	0xa6,	0x07,	0xaf,	0x44,	0x7e,	0x00,	0x78,	0x51,
-	0x12,	0x08,	0xf2,	0x7d,	0x3c,	0x12,	0x02,	0xa9,	0x78,
-	0x55,	0xa6,	0x06,	0x08,	0xa6,	0x07,	0xc3,	0x78,	0x58,
-	0xe6,	0x94,	0x08,	0x18,	0xe6,	0x94,	0x00,	0x50,	0x05,
-	0x76,	0x00,	0x08,	0x76,	0x08,	0xc3,	0x78,	0x5a,	0xe6,
-	0x94,	0x08,	0x18,	0xe6,	0x94,	0x00,	0x50,	0x05,	0x76,
-	0x00,	0x08,	0x76,	0x08,	0x78,	0x57,	0x12,	0x09,	0x25,
-	0xff,	0xd3,	0x78,	0x54,	0xe6,	0x9f,	0x18,	0xe6,	0x9e,
-	0x40,	0x0e,	0x78,	0x57,	0xe6,	0x13,	0xfe,	0x08,	0xe6,
-	0x78,	0x54,	0x12,	0x09,	0x5b,	0x80,	0x04,	0x7e,	0x00,
-	0x7f,	0x00,	0x78,	0x5b,	0x12,	0x09,	0x1d,	0xff,	0xd3,
-	0x78,	0x56,	0xe6,	0x9f,	0x18,	0xe6,	0x9e,	0x40,	0x0e,
-	0x78,	0x59,	0xe6,	0x13,	0xfe,	0x08,	0xe6,	0x78,	0x56,
-	0x12,	0x09,	0x5b,	0x80,	0x04,	0x7e,	0x00,	0x7f,	0x00,
-	0xe4,	0xfc,	0xfd,	0x78,	0x5f,	0x12,	0x04,	0x5c,	0x78,
-	0x57,	0x12,	0x09,	0x25,	0x78,	0x54,	0x26,	0xff,	0xee,
-	0x18,	0x36,	0xfe,	0x78,	0x63,	0x12,	0x09,	0x1d,	0x78,
-	0x56,	0x26,	0xff,	0xee,	0x18,	0x36,	0xfe,	0xe4,	0xfc,
-	0xfd,	0x78,	0x67,	0x12,	0x04,	0x5c,	0x12,	0x09,	0x2d,
-	0x78,	0x63,	0x12,	0x04,	0x4f,	0xd3,	0x12,	0x04,	0x1b,
-	0x40,	0x08,	0x12,	0x09,	0x2d,	0x78,	0x63,	0x12,	0x04,
-	0x5c,	0x78,	0x51,	0x12,	0x09,	0x2f,	0x78,	0x67,	0x12,
-	0x04,	0x4f,	0xd3,	0x12,	0x04,	0x1b,	0x40,	0x0a,	0x78,
-	0x51,	0x12,	0x09,	0x2f,	0x78,	0x67,	0x12,	0x04,	0x5c,
-	0xe4,	0xfd,	0x78,	0x5e,	0x12,	0x09,	0x48,	0x24,	0x01,
-	0x12,	0x09,	0x11,	0x78,	0x62,	0x12,	0x09,	0x48,	0x24,
-	0x02,	0x12,	0x09,	0x11,	0x78,	0x66,	0x12,	0x09,	0x48,
-	0x24,	0x03,	0x12,	0x09,	0x11,	0x78,	0x6a,	0x12,	0x09,
-	0x48,	0x24,	0x04,	0x12,	0x09,	0x11,	0x0d,	0xbd,	0x05,
-	0xd4,	0xc2,	0x0e,	0xc2,	0x06,	0x22,	0x85,	0x08,	0x41,
-	0x90,	0x30,	0x24,	0xe0,	0xf5,	0x3d,	0xa3,	0xe0,	0xf5,
-	0x3e,	0xa3,	0xe0,	0xf5,	0x3f,	0xa3,	0xe0,	0xf5,	0x40,
-	0xa3,	0xe0,	0xf5,	0x3c,	0xd2,	0x34,	0xe5,	0x41,	0x12,
-	0x04,	0x74,	0x06,	0xc7,	0x03,	0x06,	0xcb,	0x04,	0x06,
-	0xd1,	0x07,	0x06,	0xda,	0x08,	0x06,	0xeb,	0x12,	0x07,
-	0x03,	0x18,	0x07,	0x19,	0x19,	0x06,	0xee,	0x1a,	0x06,
-	0xfa,	0x1b,	0x07,	0x3e,	0x80,	0x07,	0x43,	0x81,	0x07,
-	0xa1,	0x8f,	0x07,	0x90,	0x90,	0x07,	0xa1,	0x91,	0x07,
-	0xa1,	0x92,	0x07,	0xa1,	0x93,	0x07,	0xa1,	0x94,	0x07,
-	0xa1,	0x98,	0x07,	0x9e,	0x9f,	0x00,	0x00,	0x07,	0xbc,
-	0x12,	0x0a,	0xf4,	0x22,	0x12,	0x0a,	0xf4,	0xd2,	0x03,
-	0x22,	0xa2,	0x37,	0xe4,	0x33,	0xf5,	0x3c,	0x02,	0x07,
-	0xa1,	0xc2,	0x01,	0xc2,	0x02,	0xc2,	0x03,	0x12,	0x09,
-	0x70,	0x75,	0x1e,	0x70,	0xd2,	0x35,	0x02,	0x07,	0xa1,
-	0x02,	0x07,	0x8b,	0x85,	0x40,	0x48,	0x85,	0x3c,	0x49,
-	0x12,	0x08,	0x5b,	0x02,	0x07,	0xa1,	0x85,	0x48,	0x40,
-	0x85,	0x49,	0x3c,	0x02,	0x07,	0xa1,	0xe4,	0xf5,	0x22,
-	0xf5,	0x23,	0x85,	0x40,	0x31,	0x85,	0x3f,	0x30,	0x85,
-	0x3e,	0x2f,	0x85,	0x3d,	0x2e,	0x12,	0x0a,	0xc6,	0x80,
-	0x1f,	0x75,	0x22,	0x00,	0x75,	0x23,	0x01,	0x74,	0xff,
-	0xf5,	0x2d,	0xf5,	0x2c,	0xf5,	0x2b,	0xf5,	0x2a,	0x12,
-	0x0a,	0xc6,	0x85,	0x2d,	0x40,	0x85,	0x2c,	0x3f,	0x85,
-	0x2b,	0x3e,	0x85,	0x2a,	0x3d,	0xe4,	0xf5,	0x3c,	0x02,
-	0x07,	0xa1,	0x12,	0x0b,	0x3d,	0x80,	0x5e,	0x85,	0x3d,
-	0x43,	0x85,	0x3e,	0x44,	0xe5,	0x45,	0xc3,	0x13,	0xff,
-	0xe5,	0x43,	0xc3,	0x9f,	0x50,	0x02,	0x8f,	0x43,	0xe5,
-	0x46,	0xc3,	0x13,	0xff,	0xe5,	0x44,	0xc3,	0x9f,	0x50,
-	0x02,	0x8f,	0x44,	0xe5,	0x45,	0xc3,	0x13,	0xff,	0xfd,
-	0xe5,	0x43,	0x90,	0x0e,	0x7f,	0x12,	0x0b,	0x10,	0x40,
-	0x04,	0xee,	0x9f,	0xf5,	0x43,	0xe5,	0x46,	0xc3,	0x13,
-	0xff,	0xfd,	0xe5,	0x44,	0x90,	0x0e,	0x80,	0x12,	0x0b,
-	0x10,	0x40,	0x04,	0xee,	0x9f,	0xf5,	0x44,	0x12,	0x04,
-	0x9a,	0x80,	0x11,	0x85,	0x40,	0x46,	0x85,	0x3f,	0x45,
-	0x85,	0x3e,	0x44,	0x85,	0x3d,	0x43,	0x80,	0x03,	0x02,
-	0x04,	0x9a,	0x90,	0x30,	0x24,	0xe5,	0x3d,	0xf0,	0xa3,
-	0xe5,	0x3e,	0xf0,	0xa3,	0xe5,	0x3f,	0xf0,	0xa3,	0xe5,
-	0x40,	0xf0,	0xa3,	0xe5,	0x3c,	0xf0,	0x90,	0x30,	0x23,
-	0xe4,	0xf0,	0x22,	0xc0,	0xe0,	0xc0,	0x83,	0xc0,	0x82,
-	0xc0,	0xd0,	0x90,	0x3f,	0x0c,	0xe0,	0xf5,	0x32,	0xe5,
-	0x32,	0x30,	0xe3,	0x4c,	0x30,	0x36,	0x3e,	0x90,	0x60,
-	0x19,
-	0xe0,
-	0xf5,
-	0x0a,
-	0xa3,
-	0xe0,
-	0xf5,
-	0x0b,
-	0x90,
-	0x60,
-	0x1d,
-	0xe0,
-	0xf5,
-	0x14,
-	0xa3,
-	0xe0,
-	0xf5,
-	0x15,
-	0x30,
-	0x01,
-	0x06,
-	0x30,
-	0x33,
-	0x03,
-	0xd3,
-	0x80,
-	0x01,
-	0xc3,
-	0x92,
-	0x09,
-	0x30,
-	0x02,
-	0x06,
-	0x30,
-	0x33,
-	0x03,
-	0xd3,
-	0x80,
-	0x01,
-	0xc3,
-	0x92,
-	0x0a,
-	0x30,
-	0x33,
-	0x0c,
-	0x30,
-	0x03,
-	0x09,
-	0x20,
-	0x02,
-	0x06,
-	0x20,
-	0x01,
-	0x03,
-	0xd3,
-	0x80,
-	0x01,
-	0xc3,
-	0x92,
-	0x0b,
-	0x90,
-	0x30,
-	0x01,
-	0xe0,
-	0x44,
-	0x40,
-	0xf0,
-	0xe0,
-	0x54,
-	0xbf,
-	0xf0,
-	0xe5,
-	0x32,
-	0x30,
-	0xe1,
-	0x14,
-	0x30,
-	0x34,
-	0x11,
-	0x90,
-	0x30,
-	0x22,
-	0xe0,
-	0xf5,
-	0x08,
-	0xe4,
-	0xf0,
-	0x30,
-	0x00,
-	0x03,
-	0xd3,
-	0x80,
-	0x01,
-	0xc3,
-	0x92,
-	0x08,
-	0xe5,
-	0x32,
-	0x30,
-	0xe5,
-	0x12,
-	0x90,
-	0x56,
-	0xa1,
-	0xe0,
-	0xf5,
-	0x09,
-	0x30,
-	0x31,
-	0x09,
-	0x30,
-	0x05,
-	0x03,
-	0xd3,
-	0x80,
-	0x01,
-	0xc3,
-	0x92,
-	0x0d,
-	0x90,
-	0x3f,
-	0x0c,
-	0xe5,
-	0x32,
-	0xf0,
-	0xd0,
-	0xd0,
-	0xd0,
-	0x82,
-	0xd0,
-	0x83,
-	0xd0,
-	0xe0,
-	0x32,
-	0x90,
-	0x0e,
-	0x7d,
-	0xe4,
-	0x93,
-	0xfe,
-	0x74,
-	0x01,
-	0x93,
-	0xff,
-	0xc3,
-	0x90,
-	0x0e,
-	0x7b,
-	0x74,
-	0x01,
-	0x93,
-	0x9f,
-	0xff,
-	0xe4,
-	0x93,
-	0x9e,
-	0xfe,
-	0xe4,
-	0x8f,
-	0x3b,
-	0x8e,
-	0x3a,
-	0xf5,
-	0x39,
-	0xf5,
-	0x38,
-	0xab,
-	0x3b,
-	0xaa,
-	0x3a,
-	0xa9,
-	0x39,
-	0xa8,
-	0x38,
-	0xaf,
-	0x49,
-	0xfc,
-	0xfd,
-	0xfe,
-	0x12,
-	0x02,
-	0xfe,
-	0x12,
-	0x0b,
-	0x22,
-	0xe4,
-	0x7b,
-	0xff,
-	0xfa,
-	0xf9,
-	0xf8,
-	0x12,
-	0x03,
-	0x89,
-	0x12,
-	0x0b,
-	0x22,
-	0x90,
-	0x0e,
-	0x69,
-	0xe4,
-	0x12,
-	0x0b,
-	0x37,
-	0x12,
-	0x0b,
-	0x22,
-	0xe4,
-	0x85,
-	0x48,
-	0x37,
-	0xf5,
-	0x36,
-	0xf5,
-	0x35,
-	0xf5,
-	0x34,
-	0xaf,
-	0x37,
-	0xae,
-	0x36,
-	0xad,
-	0x35,
-	0xac,
-	0x34,
-	0xa3,
-	0x12,
-	0x0b,
-	0x37,
-	0x8f,
-	0x37,
-	0x8e,
-	0x36,
-	0x8d,
-	0x35,
-	0x8c,
-	0x34,
-	0xe5,
-	0x3b,
-	0x45,
-	0x37,
-	0xf5,
-	0x3b,
-	0xe5,
-	0x3a,
-	0x45,
-	0x36,
-	0xf5,
-	0x3a,
-	0xe5,
-	0x39,
-	0x45,
-	0x35,
-	0xf5,
-	0x39,
-	0xe5,
-	0x38,
-	0x45,
-	0x34,
-	0xf5,
-	0x38,
-	0xe4,
-	0xf5,
-	0x22,
-	0xf5,
-	0x23,
-	0x85,
-	0x3b,
-	0x31,
-	0x85,
-	0x3a,
-	0x30,
-	0x85,
-	0x39,
-	0x2f,
-	0x85,
-	0x38,
-	0x2e,
-	0x02,
-	0x0a,
-	0xc6,
-	0x78,
-	0x4f,
-	0x7e,
-	0x00,
-	0xe6,
-	0xfc,
-	0x08,
-	0xe6,
-	0xfd,
-	0x12,
-	0x02,
-	0x97,
-	0x7c,
-	0x00,
-	0x22,
-	0xe0,
-	0xa3,
-	0xe0,
-	0x75,
-	0xf0,
-	0x02,
-	0xa4,
-	0xff,
-	0xae,
-	0xf0,
-	0xc3,
-	0x08,
-	0xe6,
-	0x9f,
-	0xf6,
-	0x18,
-	0xe6,
-	0x9e,
-	0xf6,
-	0x22,
-	0xff,
-	0xe5,
-	0xf0,
-	0x34,
-	0x60,
-	0x8f,
-	0x82,
-	0xf5,
-	0x83,
-	0xec,
-	0xf0,
-	0x22,
-	0xe4,
-	0xfc,
-	0xfd,
-	0x12,
-	0x04,
-	0x5c,
-	0x78,
-	0x59,
-	0xe6,
-	0xc3,
-	0x13,
-	0xfe,
-	0x08,
-	0xe6,
-	0x13,
-	0x22,
-	0x78,
-	0x4f,
-	0xe6,
-	0xfe,
-	0x08,
-	0xe6,
-	0xff,
-	0xe4,
-	0xfc,
-	0xfd,
-	0x22,
-	0xe7,
-	0xc4,
-	0xf8,
-	0x54,
-	0xf0,
-	0xc8,
-	0x68,
-	0xf7,
-	0x09,
-	0xe7,
-	0xc4,
-	0x54,
-	0x0f,
-	0x48,
-	0xf7,
-	0x22,
-	0xe6,
-	0xfc,
-	0xed,
-	0x75,
-	0xf0,
-	0x04,
-	0xa4,
-	0x22,
-	0xe0,
-	0xfe,
-	0xa3,
-	0xe0,
-	0xfd,
-	0xee,
-	0xf6,
-	0xed,
-	0x08,
-	0xf6,
-	0x22,
-	0x13,
-	0xff,
-	0xc3,
-	0xe6,
-	0x9f,
-	0xff,
-	0x18,
-	0xe6,
-	0x9e,
-	0xfe,
-	0x22,
-	0xe6,
-	0xc3,
-	0x13,
-	0xf7,
-	0x08,
-	0xe6,
-	0x13,
-	0x09,
-	0xf7,
-	0x22,
-	0xe4,
-	0xf5,
-	0x49,
-	0x90,
-	0x0e,
-	0x77,
-	0x93,
-	0xff,
-	0xe4,
-	0x8f,
-	0x37,
-	0xf5,
-	0x36,
-	0xf5,
-	0x35,
-	0xf5,
-	0x34,
-	0xaf,
-	0x37,
-	0xae,
-	0x36,
-	0xad,
-	0x35,
-	0xac,
-	0x34,
-	0x90,
-	0x0e,
-	0x6a,
-	0x12,
-	0x0b,
-	0x37,
-	0x8f,
-	0x37,
-	0x8e,
-	0x36,
-	0x8d,
-	0x35,
-	0x8c,
-	0x34,
-	0x90,
-	0x0e,
-	0x72,
-	0x12,
-	0x04,
-	0x3f,
-	0xef,
-	0x45,
-	0x37,
-	0xf5,
-	0x37,
-	0xee,
-	0x45,
-	0x36,
-	0xf5,
-	0x36,
-	0xed,
-	0x45,
-	0x35,
-	0xf5,
-	0x35,
-	0xec,
-	0x45,
-	0x34,
-	0xf5,
-	0x34,
-	0xe4,
-	0xf5,
-	0x22,
-	0xf5,
-	0x23,
-	0x85,
-	0x37,
-	0x31,
-	0x85,
-	0x36,
-	0x30,
-	0x85,
-	0x35,
-	0x2f,
-	0x85,
-	0x34,
-	0x2e,
-	0x12,
-	0x0a,
-	0xc6,
-	0xe4,
-	0xf5,
-	0x22,
-	0xf5,
-	0x23,
-	0x90,
-	0x0e,
-	0x72,
-	0x12,
-	0x0b,
-	0x2b,
-	0x12,
-	0x0a,
-	0xc6,
-	0xe4,
-	0xf5,
-	0x22,
-	0xf5,
-	0x23,
-	0x90,
-	0x0e,
-	0x6e,
-	0x12,
-	0x0b,
-	0x2b,
-	0x02,
-	0x0a,
-	0xc6,
-	0x75,
-	0x89,
-	0x03,
-	0x75,
-	0xa8,
-	0x01,
-	0x75,
-	0xb8,
-	0x04,
-	0x75,
-	0x34,
-	0xff,
-	0x75,
-	0x35,
-	0x0e,
-	0x75,
-	0x36,
-	0x15,
-	0x75,
-	0x37,
-	0x0d,
-	0x12,
-	0x0a,
-	0x4a,
-	0x12,
-	0x00,
-	0x09,
-	0x12,
-	0x0b,
-	0x3d,
-	0x12,
-	0x00,
-	0x06,
-	0xd2,
-	0x00,
-	0xd2,
-	0x34,
-	0xd2,
-	0xaf,
-	0x75,
-	0x34,
-	0xff,
-	0x75,
-	0x35,
-	0x0e,
-	0x75,
-	0x36,
-	0x49,
-	0x75,
-	0x37,
-	0x03,
-	0x12,
-	0x0a,
-	0x4a,
-	0x30,
-	0x08,
-	0x09,
-	0xc2,
-	0x34,
-	0x12,
-	0x06,
-	0x6a,
-	0xc2,
-	0x08,
-	0xd2,
-	0x34,
-	0x30,
-	0x09,
-	0x09,
-	0xc2,
-	0x36,
-	0x12,
-	0x00,
-	0x0e,
-	0xc2,
-	0x09,
-	0xd2,
-	0x36,
-	0x30,
-	0x0e,
-	0x03,
-	0x12,
-	0x04,
-	0x9a,
-	0x30,
-	0x35,
-	0xdf,
-	0x90,
-	0x30,
-	0x29,
-	0xe5,
-	0x1e,
-	0xf0,
-	0xb4,
-	0x10,
-	0x05,
-	0x90,
-	0x30,
-	0x23,
-	0xe4,
-	0xf0,
-	0xc2,
-	0x35,
-	0x80,
-	0xcd,
-	0xae,
-	0x35,
-	0xaf,
-	0x36,
-	0xe4,
-	0xfd,
-	0xed,
-	0xc3,
-	0x95,
-	0x37,
-	0x50,
-	0x33,
-	0x12,
-	0x0b,
-	0x87,
-	0xe4,
-	0x93,
-	0xf5,
-	0x38,
-	0x74,
-	0x01,
-	0x93,
-	0xf5,
-	0x39,
-	0x45,
-	0x38,
-	0x60,
-	0x23,
-	0x85,
-	0x39,
-	0x82,
-	0x85,
-	0x38,
-	0x83,
-	0xe0,
-	0xfc,
-	0x12,
-	0x0b,
-	0x87,
-	0x74,
-	0x03,
-	0x93,
-	0x52,
-	0x04,
-	0x12,
-	0x0b,
-	0x87,
-	0x74,
-	0x02,
-	0x93,
-	0x42,
-	0x04,
-	0x85,
-	0x39,
-	0x82,
-	0x85,
-	0x38,
-	0x83,
-	0xec,
-	0xf0,
-	0x0d,
-	0x80,
-	0xc7,
-	0x22,
-	0x78,
-	0xbb,
-	0xe6,
-	0xd3,
-	0x08,
-	0xff,
-	0xe6,
-	0x64,
-	0x80,
-	0xf8,
-	0xef,
-	0x64,
-	0x80,
-	0x98,
-	0x22,
-	0x93,
-	0xff,
-	0x7e,
-	0x00,
-	0xe6,
-	0xfc,
-	0x08,
-	0xe6,
-	0xfd,
-	0x12,
-	0x02,
-	0x97,
-	0xac,
-	0x06,
-	0xad,
-	0x07,
-	0x78,
-	0xb3,
-	0xe6,
-	0xfe,
-	0x08,
-	0xe6,
-	0x78,
-	0x03,
-	0x22,
-	0x78,
-	0xba,
-	0xd3,
-	0xe6,
-	0x64,
-	0x80,
-	0x94,
-	0x80,
-	0x22,
-	0x25,
-	0xe0,
-	0x24,
-	0x0a,
-	0xf8,
-	0xe6,
-	0xfe,
-	0x08,
-	0xe6,
-	0xff,
-	0x22,
-	0xa2,
-	0xaf,
-	0x92,
-	0x32,
-	0xc2,
-	0xaf,
-	0xe5,
-	0x23,
-	0x45,
-	0x22,
-	0x90,
-	0x0e,
-	0x5d,
-	0x60,
-	0x0e,
-	0x12,
-	0x0b,
-	0x70,
-	0xe0,
-	0xf5,
-	0x2c,
-	0x12,
-	0x0b,
-	0x6d,
-	0xe0,
-	0xf5,
-	0x2d,
-	0x80,
-	0x0c,
-	0x12,
-	0x0b,
-	0x70,
-	0xe5,
-	0x30,
-	0xf0,
-	0x12,
-	0x0b,
-	0x6d,
-	0xe5,
-	0x31,
-	0xf0,
-	0xa2,
-	0x32,
-	0x92,
-	0xaf,
-	0x22,
-	0xd2,
-	0x01,
-	0xc2,
-	0x02,
-	0xe4,
-	0xf5,
-	0x1f,
-	0xf5,
-	0x1e,
-	0xd2,
-	0x35,
-	0xd2,
-	0x33,
-	0xd2,
-	0x36,
-	0xd2,
-	0x01,
-	0xc2,
-	0x02,
-	0xf5,
-	0x1f,
-	0xf5,
-	0x1e,
-	0xd2,
-	0x35,
-	0xd2,
-	0x33,
-	0x22,
-	0x2d,
-	0xfd,
-	0xe4,
-	0x33,
-	0xfc,
-	0xe4,
-	0x93,
-	0xfe,
-	0xfb,
-	0xd3,
-	0xed,
-	0x9b,
-	0x74,
-	0x80,
-	0xf8,
-	0x6c,
-	0x98,
-	0x22,
-	0x8f,
-	0x3b,
-	0x8e,
-	0x3a,
-	0x8d,
-	0x39,
-	0x8c,
-	0x38,
-	0x22,
-	0x12,
-	0x04,
-	0x3f,
-	0x8f,
-	0x31,
-	0x8e,
-	0x30,
-	0x8d,
-	0x2f,
-	0x8c,
-	0x2e,
-	0x22,
-	0x93,
-	0xf9,
-	0xf8,
-	0x02,
-	0x04,
-	0x2c,
-	0x90,
-	0x0e,
-	0x81,
-	0x12,
-	0x04,
-	0x3f,
-	0x8f,
-	0x46,
-	0x8e,
-	0x45,
-	0x8d,
-	0x44,
-	0x8c,
-	0x43,
-	0xd2,
-	0x06,
-	0x30,
-	0x06,
-	0x03,
-	0xd3,
-	0x80,
-	0x01,
-	0xc3,
-	0x92,
-	0x0e,
-	0x22,
-	0xc0,
-	0xe0,
-	0xc0,
-	0x83,
-	0xc0,
-	0x82,
-	0x90,
-	0x3f,
-	0x0d,
-	0xe0,
-	0xf5,
-	0x33,
-	0xe5,
-	0x33,
-	0xf0,
-	0xd0,
-	0x82,
-	0xd0,
-	0x83,
-	0xd0,
-	0xe0,
-	0x32,
-	0x90,
-	0x0e,
-	0x5f,
-	0xe4,
-	0x93,
-	0xfe,
-	0x74,
-	0x01,
-	0x93,
-	0xf5,
-	0x82,
-	0x8e,
-	0x83,
-	0x22,
-	0x78,
-	0x7f,
-	0xe4,
-	0xf6,
-	0xd8,
-	0xfd,
-	0x75,
-	0x81,
-	0xca,
-	0x02,
-	0x09,
-	0xe1,
-	0x8f,
-	0x82,
-	0x8e,
-	0x83,
-	0x75,
-	0xf0,
-	0x04,
-	0xed,
-	0x02,
-	0x04,
-	0x68,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x11,
-	0x07,
-	0x21,
-	0x15,
-	0x29,
-	0x13,
-	0x4f,
-	0x56,
-	0x54,
-	0x20,
-	0x20,
-	0x20,
-	0x20,
-	0x20,
-	0x20,
-	0x01,
-	0x10,
-	0x00,
-	0x56,
-	0x40,
-	0x1a,
-	0x30,
-	0x29,
-	0x7e,
-	0x00,
-	0x30,
-	0x04,
-	0x20,
-	0xdf,
-	0x30,
-	0x05,
-	0x40,
-	0xbf,
-	0x50,
-	0x03,
-	0x00,
-	0xfd,
-	0x50,
-	0x27,
-	0x01,
-	0xfe,
-	0x60,
-	0x00,
-	0x11,
-	0x00,
-	0x3f,
-	0x05,
-	0x30,
-	0x00,
-	0x3f,
-	0x06,
-	0x22,
-	0x00,
-	0x3f,
-	0x01,
-	0x2a,
-	0x00,
-	0x3f,
-	0x02,
-	0x00,
-	0x00,
-	0x36,
-	0x06,
-	0x07,
-	0x00,
-	0x3f,
-	0x0b,
-	0x0f,
-	0xf0,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x30,
-	0x01,
-	0x40,
-	0xbf,
-	0x30,
-	0x01,
-	0x00,
-	0xbf,
-	0x30,
-	0x29,
-	0x70,
-	0x00,
-	0x3a,
-	0x00,
-	0x00,
-	0xff,
-	0x3a,
-	0x00,
-	0x00,
-	0xff,
-	0x36,
-	0x03,
-	0x36,
-	0x02,
-	0x41,
-	0x44,
-	0x58,
-	0x20,
-	0x18,
-	0x10,
-	0x0a,
-	0x04,
-	0x04,
-	0x00,
-	0x03,
-	0xff,
-	0x64,
-	0x00,
-	0x00,
-	0x80,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x02,
-	0x04,
-	0x06,
-	0x00,
-	0x03,
-	0x98,
-	0x00,
-	0xcc,
-	0x50,
-	0x3c,
-	0x28,
-	0x1e,
-	0x10,
-	0x10,
-	0x00,
-	0x00,
-	0x00,
-	0x6e,
-	0x30,
-	0x28,
-	0x00,
-	0xa5,
-	0x5a,
-	0x00,
-};
-
-#endif /* CAMSENSOR_OV5640 */
diff --git a/drivers/media/video/msm/ov5647.c b/drivers/media/video/msm/ov5647.c
deleted file mode 100644
index 2a6e7be..0000000
--- a/drivers/media/video/msm/ov5647.c
+++ /dev/null
@@ -1,1201 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/delay.h>
-#include <linux/debugfs.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/slab.h>
-#include <linux/gpio.h>
-#include <linux/bitops.h>
-#include <linux/leds.h>
-#include <mach/camera.h>
-#include <media/msm_camera.h>
-#include "ov5647.h"
-
-/* 16bit address - 8 bit context register structure */
-#define Q8	0x00000100
-#define Q10	0x00000400
-
-#define REG_OV5647_GAIN_MSB           0x350A
-#define REG_OV5647_GAIN_LSB           0x350B
-#define REG_OV5647_LINE_HSB           0x3500
-#define REG_OV5647_LINE_MSB           0x3501
-#define REG_OV5647_LINE_LSB           0x3502
-
-/* MCLK */
-#define OV5647_MASTER_CLK_RATE 24000000
-
-/* AF Total steps parameters */
-#define OV5647_TOTAL_STEPS_NEAR_TO_FAR	32
-
-#define OV5647_REG_PREV_FRAME_LEN_1	31
-#define OV5647_REG_PREV_FRAME_LEN_2	32
-#define OV5647_REG_PREV_LINE_LEN_1	33
-#define OV5647_REG_PREV_LINE_LEN_2	34
-
-#define OV5647_REG_SNAP_FRAME_LEN_1	15
-#define OV5647_REG_SNAP_FRAME_LEN_2	16
-#define OV5647_REG_SNAP_LINE_LEN_1	17
-#define OV5647_REG_SNAP_LINE_LEN_2	18
-#define MSB                             1
-#define LSB                             0
-
-/* Debug switch */
-#ifdef CDBG
-#undef CDBG
-#endif
-#ifdef CDBG_HIGH
-#undef CDBG_HIGH
-#endif
-
-/*#define OV5647_VERBOSE_DGB*/
-
-#ifdef OV5647_VERBOSE_DGB
-#define CDBG(fmt, args...) pr_debug(fmt, ##args)
-#define CDBG_HIGH(fmt, args...) pr_debug(fmt, ##args)
-#else
-#define CDBG(fmt, args...) do { } while (0)
-#define CDBG_HIGH(fmt, args...) pr_debug(fmt, ##args)
-#endif
-
-/*for debug*/
-#ifdef CDBG
-#undef CDBG
-#endif
-#define CDBG(fmt, args...) printk(fmt, ##args)
-
-static uint8_t  mode_mask = 0x09;
-struct ov5647_work_t {
-	struct work_struct work;
-};
-
-static struct ov5647_work_t *ov5647_sensorw;
-static struct ov5647_work_t *ov5647_af_sensorw;
-static struct i2c_client *ov5647_af_client;
-static struct i2c_client *ov5647_client;
-
-struct ov5647_ctrl_t {
-	const struct  msm_camera_sensor_info *sensordata;
-
-	uint32_t sensormode;
-	uint32_t fps_divider;/* init to 1 * 0x00000400 */
-	uint32_t pict_fps_divider;/* init to 1 * 0x00000400 */
-	uint16_t fps;
-
-	uint16_t curr_lens_pos;
-	uint16_t curr_step_pos;
-	uint16_t my_reg_gain;
-	uint32_t my_reg_line_count;
-	uint16_t total_lines_per_frame;
-
-	enum ov5647_resolution_t prev_res;
-	enum ov5647_resolution_t pict_res;
-	enum ov5647_resolution_t curr_res;
-	enum ov5647_test_mode_t  set_test;
-};
-
-static bool CSI_CONFIG;
-static struct ov5647_ctrl_t *ov5647_ctrl;
-
-static DECLARE_WAIT_QUEUE_HEAD(ov5647_wait_queue);
-static DECLARE_WAIT_QUEUE_HEAD(ov5647_af_wait_queue);
-DEFINE_MUTEX(ov5647_mut);
-
-static uint16_t prev_line_length_pck;
-static uint16_t prev_frame_length_lines;
-static uint16_t snap_line_length_pck;
-static uint16_t snap_frame_length_lines;
-
-static int ov5647_i2c_rxdata(unsigned short saddr,
-		unsigned char *rxdata, int length)
-{
-	struct i2c_msg msgs[] = {
-		{
-			.addr  = saddr,
-			.flags = 0,
-			.len   = 2,
-			.buf   = rxdata,
-		},
-		{
-			.addr  = saddr,
-			.flags = I2C_M_RD,
-			.len   = 1,
-			.buf   = rxdata,
-		},
-	};
-	if (i2c_transfer(ov5647_client->adapter, msgs, 2) < 0) {
-		CDBG("ov5647_i2c_rxdata faild 0x%x\n", saddr);
-		return -EIO;
-	}
-	return 0;
-}
-
-static int32_t ov5647_i2c_txdata(unsigned short saddr,
-		unsigned char *txdata, int length)
-{
-	struct i2c_msg msg[] = {
-		{
-			.addr = saddr,
-			.flags = 0,
-			.len = length,
-			.buf = txdata,
-		},
-	};
-	if (i2c_transfer(ov5647_client->adapter, msg, 1) < 0) {
-		CDBG("ov5647_i2c_txdata faild 0x%x\n", saddr);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int32_t ov5647_i2c_read(unsigned short raddr,
-		unsigned short *rdata)
-{
-	int32_t rc = 0;
-	unsigned char buf[2];
-
-	if (!rdata)
-		return -EIO;
-	CDBG("%s:saddr:0x%x raddr:0x%x data:0x%x",
-		__func__, ov5647_client->addr, raddr, *rdata);
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (raddr & 0xFF00) >> 8;
-	buf[1] = (raddr & 0x00FF);
-	rc = ov5647_i2c_rxdata(ov5647_client->addr >> 1, buf, 1);
-	if (rc < 0) {
-		CDBG("ov5647_i2c_read 0x%x failed!\n", raddr);
-		return rc;
-	}
-	*rdata = buf[0];
-	CDBG("ov5647_i2c_read 0x%x val = 0x%x!\n", raddr, *rdata);
-
-	return rc;
-}
-
-static int32_t ov5647_i2c_write_b_sensor(unsigned short waddr, uint8_t bdata)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[3];
-
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (waddr & 0xFF00) >> 8;
-	buf[1] = (waddr & 0x00FF);
-	buf[2] = bdata;
-	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
-	rc = ov5647_i2c_txdata(ov5647_client->addr >> 1, buf, 3);
-	if (rc < 0) {
-		pr_err("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
-				waddr, bdata);
-	}
-	return rc;
-}
-
-static int32_t ov5647_i2c_write_b_table(struct ov5647_i2c_reg_conf const
-		*reg_conf_tbl, int num)
-{
-	int i;
-	int32_t rc = -EIO;
-
-	for (i = 0; i < num; i++) {
-		rc = ov5647_i2c_write_b_sensor(reg_conf_tbl->waddr,
-				reg_conf_tbl->wdata);
-		if (rc < 0)
-			break;
-		reg_conf_tbl++;
-	}
-	return rc;
-}
-
-static int32_t ov5647_af_i2c_txdata(unsigned short saddr,
-		unsigned char *txdata, int length)
-{
-	struct i2c_msg msg[] = {
-		{
-			.addr = saddr,
-			.flags = 0,
-			.len = length,
-			.buf = txdata,
-		},
-	};
-	if (i2c_transfer(ov5647_af_client->adapter, msg, 1) < 0) {
-		pr_err("ov5647_af_i2c_txdata faild 0x%x\n", saddr);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int32_t ov5647_af_i2c_write_b_sensor(uint8_t waddr, uint8_t bdata)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[2];
-
-	memset(buf, 0, sizeof(buf));
-	buf[0] = waddr;
-	buf[1] = bdata;
-	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
-	rc = ov5647_af_i2c_txdata(ov5647_af_client->addr, buf, 2);
-	if (rc < 0) {
-		pr_err("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
-				waddr, bdata);
-	}
-	return rc;
-}
-
-static void ov5647_start_stream(void)
-{
-	CDBG("CAMERA_DBG: 0x4202 0x0, stream on...\r\n");
-	ov5647_i2c_write_b_sensor(0x4202, 0x00);/* streaming on */
-}
-
-static void ov5647_stop_stream(void)
-{
-	CDBG("CAMERA_DBG: 0x4202 0xf, stream off...\r\n");
-	ov5647_i2c_write_b_sensor(0x4202, 0x0f);/* streaming off */
-}
-
-static void ov5647_group_hold_on(void)
-{
-	ov5647_i2c_write_b_sensor(0x0104, 0x01);
-}
-
-static void ov5647_group_hold_off(void)
-{
-	ov5647_i2c_write_b_sensor(0x0104, 0x0);
-}
-
-static void ov5647_get_pict_fps(uint16_t fps, uint16_t *pfps)
-{
-	/* input fps is preview fps in Q8 format */
-	uint32_t divider, d1, d2;
-	uint32_t preview_pclk = 0x37, snapshot_pclk = 0x4f;
-
-	d1 = (prev_frame_length_lines * 0x00000400) / snap_frame_length_lines;
-	d2 = (prev_line_length_pck * 0x00000400) / snap_line_length_pck;
-	divider = (d1 * d2*preview_pclk/snapshot_pclk) / 0x400;
-	CDBG(KERN_ERR "ov5647_get_pict_fps divider = %d", divider);
-	/*Verify PCLK settings and frame sizes.*/
-	*pfps = (uint16_t) (fps * divider / 0x400);
-}
-
-static uint16_t ov5647_get_prev_lines_pf(void)
-{
-	if (ov5647_ctrl->prev_res == QTR_SIZE)
-		return prev_frame_length_lines;
-	else
-		return snap_frame_length_lines;
-}
-
-static uint16_t ov5647_get_prev_pixels_pl(void)
-{
-	if (ov5647_ctrl->prev_res == QTR_SIZE)
-		return prev_line_length_pck;
-	else
-		return snap_line_length_pck;
-}
-
-static uint16_t ov5647_get_pict_lines_pf(void)
-{
-	if (ov5647_ctrl->pict_res == QTR_SIZE)
-		return prev_frame_length_lines;
-	else
-		return snap_frame_length_lines;
-}
-
-static uint16_t ov5647_get_pict_pixels_pl(void)
-{
-	if (ov5647_ctrl->pict_res == QTR_SIZE)
-		return prev_line_length_pck;
-	else
-		return snap_line_length_pck;
-}
-
-static uint32_t ov5647_get_pict_max_exp_lc(void)
-{
-	return snap_frame_length_lines * 24;
-}
-
-static int32_t ov5647_set_fps(struct fps_cfg   *fps)
-{
-	uint16_t total_lines_per_frame;
-	int32_t rc = 0;
-
-	ov5647_ctrl->fps_divider = fps->fps_div;
-	ov5647_ctrl->pict_fps_divider = fps->pict_fps_div;
-
-	if (ov5647_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
-		total_lines_per_frame = (uint16_t)
-		((prev_frame_length_lines * ov5647_ctrl->fps_divider) / 0x400);
-	} else {
-		total_lines_per_frame = (uint16_t)
-		((snap_frame_length_lines * ov5647_ctrl->fps_divider) / 0x400);
-	}
-
-	ov5647_group_hold_on();
-	rc = ov5647_i2c_write_b_sensor(0x0340,
-			((total_lines_per_frame & 0xFF00) >> 8));
-	rc = ov5647_i2c_write_b_sensor(0x0341,
-			(total_lines_per_frame & 0x00FF));
-	ov5647_group_hold_off();
-
-	return rc;
-}
-
-static inline uint8_t ov5647_byte(uint16_t word, uint8_t offset)
-{
-	return word >> (offset * BITS_PER_BYTE);
-}
-
-static int32_t ov5647_write_exp_gain(uint16_t gain, uint32_t line)
-{
-	int rc = 0;
-	uint16_t max_line;
-	u8 intg_time_hsb, intg_time_msb, intg_time_lsb;
-	uint8_t gain_lsb, gain_hsb;
-	ov5647_ctrl->my_reg_gain = gain;
-	ov5647_ctrl->my_reg_line_count = (uint16_t)line;
-
-	CDBG(KERN_ERR "preview exposure setting 0x%x, 0x%x, %d",
-		 gain, line, line);
-
-	gain_lsb = (uint8_t) (ov5647_ctrl->my_reg_gain);
-	gain_hsb = (uint8_t)((ov5647_ctrl->my_reg_gain & 0x300)>>8);
-	/* adjust frame rate */
-	if (line > 980) {
-		rc = ov5647_i2c_write_b_sensor(0x380E,
-			 (uint8_t)((line+4) >> 8)) ;
-		rc = ov5647_i2c_write_b_sensor(0x380F,
-			 (uint8_t)((line+4) & 0x00FF)) ;
-		max_line = line + 4;
-	} else if (max_line > 984) {
-		rc = ov5647_i2c_write_b_sensor(0x380E,
-			 (uint8_t)(984 >> 8)) ;
-		rc = ov5647_i2c_write_b_sensor(0x380F,
-			 (uint8_t)(984 & 0x00FF)) ;
-		max_line = 984;
-	}
-
-	line = line<<4;
-	/* ov5647 need this operation */
-	intg_time_hsb = (u8)(line>>16);
-	intg_time_msb = (u8) ((line & 0xFF00) >> 8);
-	intg_time_lsb = (u8) (line & 0x00FF);
-
-	ov5647_group_hold_on();
-	rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_HSB, intg_time_hsb) ;
-	rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_MSB, intg_time_msb) ;
-	rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_LSB, intg_time_lsb) ;
-
-	rc = ov5647_i2c_write_b_sensor(REG_OV5647_GAIN_MSB, gain_hsb) ;
-	rc = ov5647_i2c_write_b_sensor(REG_OV5647_GAIN_LSB, gain_lsb) ;
-	ov5647_group_hold_off();
-
-	return rc;
-}
-
-
-static int32_t ov5647_set_pict_exp_gain(uint16_t gain, uint32_t line)
-{
-	uint16_t max_line;
-	int rc = 0;
-	uint8_t gain_lsb, gain_hsb;
-	u8 intg_time_hsb, intg_time_msb, intg_time_lsb;
-
-	ov5647_ctrl->my_reg_gain = gain;
-	ov5647_ctrl->my_reg_line_count = (uint16_t)line;
-
-	gain_lsb = (uint8_t) (ov5647_ctrl->my_reg_gain);
-	gain_hsb = (uint8_t)((ov5647_ctrl->my_reg_gain & 0x300)>>8);
-
-	CDBG(KERN_ERR "snapshot exposure seting 0x%x, 0x%x, %d"
-		, gain, line, line);
-
-	if (line > 1964) {
-		rc = ov5647_i2c_write_b_sensor(0x380E,
-			 (uint8_t)((line+4) >> 8)) ;
-		rc = ov5647_i2c_write_b_sensor(0x380F,
-			 (uint8_t)((line+4) & 0x00FF)) ;
-		max_line = line + 4;
-	} else if (max_line > 1968) {
-		rc = ov5647_i2c_write_b_sensor(0x380E,
-			 (uint8_t)(1968 >> 8)) ;
-		rc = ov5647_i2c_write_b_sensor(0x380F,
-			 (uint8_t)(1968 & 0x00FF)) ;
-		max_line = 1968;
-	}
-	line = line<<4;
-	/* ov5647 need this operation */
-	intg_time_hsb = (u8)(line>>16);
-	intg_time_msb = (u8) ((line & 0xFF00) >> 8);
-	intg_time_lsb = (u8) (line & 0x00FF);
-
-	/* FIXME for BLC trigger */
-	ov5647_group_hold_on();
-	rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_HSB, intg_time_hsb) ;
-	rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_MSB, intg_time_msb) ;
-	rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_LSB, intg_time_lsb) ;
-
-	rc = ov5647_i2c_write_b_sensor(REG_OV5647_GAIN_MSB, gain_hsb) ;
-	rc = ov5647_i2c_write_b_sensor(REG_OV5647_GAIN_LSB, gain_lsb - 1) ;
-
-	rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_HSB, intg_time_hsb) ;
-	rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_MSB, intg_time_msb) ;
-	rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_LSB, intg_time_lsb) ;
-
-	rc = ov5647_i2c_write_b_sensor(REG_OV5647_GAIN_MSB, gain_hsb) ;
-	rc = ov5647_i2c_write_b_sensor(REG_OV5647_GAIN_LSB, gain_lsb) ;
-	ov5647_group_hold_off();
-
-	msleep(500);
-	return rc;
-
-}
-
-static int32_t ov5647_move_focus(int direction, int32_t num_steps)
-{
-	uint8_t   code_val_msb = 0;
-	uint8_t   code_val_lsb = 0;
-	int16_t   step_direction, actual_step, next_position;
-	int rc;
-
-	if (num_steps == 0)
-		return 0;
-
-	if (direction == MOVE_NEAR)
-		step_direction = 20;
-	else if (direction == MOVE_FAR)
-		step_direction = -20;
-	else
-		return -EINVAL;
-
-	actual_step = (int16_t)(step_direction * num_steps);
-	next_position = (int16_t)ov5647_ctrl->curr_lens_pos + actual_step;
-	if (next_position < 0) {
-		CDBG(KERN_ERR "%s: OV5647 position(=%d) out of range",
-			__func__, next_position);
-		next_position = 0;
-	}
-	if (next_position > 0x3FF) {
-		CDBG(KERN_ERR "%s: OV5647 position(=%d) out of range",
-			__func__, next_position);
-		next_position = 0x3FF;
-	}
-	ov5647_ctrl->curr_lens_pos = next_position;
-
-	code_val_msb = (uint8_t)((ov5647_ctrl->curr_lens_pos & 0x03FF) >> 4);
-	code_val_lsb = (uint8_t)((ov5647_ctrl->curr_lens_pos & 0x000F) << 4);
-	code_val_lsb |= mode_mask;
-
-	rc = ov5647_af_i2c_write_b_sensor(code_val_msb, code_val_lsb);
-	/* DAC Setting */
-	if (rc != 0) {
-		CDBG(KERN_ERR "%s: WRITE ERROR lsb = 0x%x, msb = 0x%x",
-			__func__, code_val_lsb, code_val_msb);
-	} else {
-		CDBG(KERN_ERR "%s: Successful lsb = 0x%x, msb = 0x%x",
-			__func__, code_val_lsb, code_val_msb);
-		/* delay may set based on the steps moved
-		when I2C write successful */
-		msleep(100);
-	}
-	return 0;
-}
-
-static int32_t ov5647_set_default_focus(uint8_t af_step)
-{
-	uint8_t  code_val_msb = 0;
-	uint8_t  code_val_lsb = 0;
-	int rc = 0;
-
-	ov5647_ctrl->curr_lens_pos = 200;
-
-
-	code_val_msb = (ov5647_ctrl->curr_lens_pos & 0x03FF) >> 4;
-	code_val_lsb = (ov5647_ctrl->curr_lens_pos & 0x000F) << 4;
-	code_val_lsb |= mode_mask;
-
-	CDBG(KERN_ERR "ov5647_set_default_focus:lens pos = %d",
-		 ov5647_ctrl->curr_lens_pos);
-	rc = ov5647_af_i2c_write_b_sensor(code_val_msb, code_val_lsb);
-	/* DAC Setting */
-	if (rc != 0)
-		CDBG(KERN_ERR "%s: WRITE ERROR lsb = 0x%x, msb = 0x%x",
-			__func__, code_val_lsb, code_val_msb);
-	else
-		CDBG(KERN_ERR "%s: WRITE successful lsb = 0x%x, msb = 0x%x",
-			__func__, code_val_lsb, code_val_msb);
-
-	usleep_range(10000, 11000);
-	return 0;
-}
-
-static int32_t ov5647_test(enum ov5647_test_mode_t mo)
-{
-	int32_t rc = 0;
-
-	if (mo != TEST_OFF)
-		rc = ov5647_i2c_write_b_sensor(0x0601, (uint8_t) mo);
-
-	return rc;
-}
-
-static void ov5647_reset_sensor(void)
-{
-	ov5647_i2c_write_b_sensor(0x103, 0x1);
-}
-
-
-static int32_t ov5647_sensor_setting(int update_type, int rt)
-{
-
-	int32_t rc = 0;
-	struct msm_camera_csi_params ov5647_csi_params;
-
-	ov5647_stop_stream();
-
-	/* wait for clk/data really stop */
-	if ((rt == RES_CAPTURE) || (CSI_CONFIG == 0))
-		msleep(66);
-	else
-		msleep(266);
-
-	CDBG("CAMERA_DBG1: 0x4800 regVal:0x25\r\n");
-	ov5647_i2c_write_b_sensor(0x4800, 0x25);/* streaming off */
-
-	usleep_range(10000, 11000);
-
-	if (update_type == REG_INIT) {
-		ov5647_reset_sensor();
-		ov5647_i2c_write_b_table(ov5647_regs.rec_settings,
-			ov5647_regs.rec_size);
-		CSI_CONFIG = 0;
-	} else if (update_type == UPDATE_PERIODIC) {
-			/* turn off flash when preview */
-
-			if (rt == RES_PREVIEW) {
-				ov5647_i2c_write_b_table(ov5647_regs.reg_prev,
-					 ov5647_regs.reg_prev_size);
-				CDBG("CAMERA_DBG:preview settings...\r\n");
-			} else {
-				ov5647_i2c_write_b_table(ov5647_regs.reg_snap,
-					 ov5647_regs.reg_snap_size);
-				CDBG("CAMERA_DBG:snapshot settings...\r\n");
-			}
-
-			msleep(20);
-			if (!CSI_CONFIG) {
-				msm_camio_vfe_clk_rate_set(192000000);
-				ov5647_csi_params.data_format = CSI_8BIT;
-				ov5647_csi_params.lane_cnt = 2;
-				ov5647_csi_params.lane_assign = 0xe4;
-				ov5647_csi_params.dpcm_scheme = 0;
-				ov5647_csi_params.settle_cnt = 10;
-				rc = msm_camio_csi_config(&ov5647_csi_params);
-				msleep(20);
-				CSI_CONFIG = 1;
-			/* exit powerdown state */
-				ov5647_i2c_write_b_sensor(0x0100, 0x01);
-			}
-			CDBG("CAMERA_DBG: 0x4800 regVal:0x04\r\n");
-			/* streaming on */
-			ov5647_i2c_write_b_sensor(0x4800, 0x04);
-			msleep(266);
-			ov5647_start_stream();
-			msleep(30);
-	}
-	return rc;
-}
-
-static int32_t ov5647_video_config(int mode)
-{
-	int32_t rc = 0;
-	int rt;
-	CDBG("video config\n");
-	/* change sensor resolution if needed */
-	if (ov5647_ctrl->prev_res == QTR_SIZE)
-		rt = RES_PREVIEW;
-	else
-		rt = RES_CAPTURE;
-	if (ov5647_sensor_setting(UPDATE_PERIODIC, rt) < 0)
-		return rc;
-	if (ov5647_ctrl->set_test) {
-		if (ov5647_test(ov5647_ctrl->set_test) < 0)
-			return  rc;
-	}
-
-	ov5647_ctrl->curr_res = ov5647_ctrl->prev_res;
-	ov5647_ctrl->sensormode = mode;
-	return rc;
-}
-
-static int32_t ov5647_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-	int rt;
-
-	/*change sensor resolution if needed */
-	if (ov5647_ctrl->curr_res != ov5647_ctrl->pict_res) {
-		if (ov5647_ctrl->pict_res == QTR_SIZE)
-			rt = RES_PREVIEW;
-		else
-			rt = RES_CAPTURE;
-		if (ov5647_sensor_setting(UPDATE_PERIODIC, rt) < 0)
-			return rc;
-	}
-
-	ov5647_ctrl->curr_res = ov5647_ctrl->pict_res;
-	ov5647_ctrl->sensormode = mode;
-	return rc;
-}
-
-static int32_t ov5647_raw_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-	int rt;
-
-	/* change sensor resolution if needed */
-	if (ov5647_ctrl->curr_res != ov5647_ctrl->pict_res) {
-		if (ov5647_ctrl->pict_res == QTR_SIZE)
-			rt = RES_PREVIEW;
-		else
-			rt = RES_CAPTURE;
-		if (ov5647_sensor_setting(UPDATE_PERIODIC, rt) < 0)
-			return rc;
-	}
-
-	ov5647_ctrl->curr_res = ov5647_ctrl->pict_res;
-	ov5647_ctrl->sensormode = mode;
-	return rc;
-}
-
-static int32_t ov5647_set_sensor_mode(int mode,
-		int res)
-{
-	int32_t rc = 0;
-
-	switch (mode) {
-	case SENSOR_PREVIEW_MODE:
-		rc = ov5647_video_config(mode);
-		break;
-	case SENSOR_SNAPSHOT_MODE:
-		rc = ov5647_snapshot_config(mode);
-		break;
-	case SENSOR_RAW_SNAPSHOT_MODE:
-		rc = ov5647_raw_snapshot_config(mode);
-		break;
-	default:
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
-
-static int32_t ov5647_power_down(void)
-{
-	ov5647_stop_stream();
-	return 0;
-}
-
-static int ov5647_probe_init_done(const struct msm_camera_sensor_info *data)
-{
-	CDBG("probe done\n");
-	gpio_direction_output(data->sensor_pwd, 1);
-	return 0;
-}
-
-static int ov5647_probe_init_sensor(const struct msm_camera_sensor_info *data)
-{
-	int32_t rc = 0;
-	uint16_t regaddress1 = 0x300a;
-	uint16_t regaddress2 = 0x300b;
-	uint16_t chipid1 = 0;
-	uint16_t chipid2 = 0;
-
-	CDBG("%s: %d\n", __func__, __LINE__);
-
-	gpio_direction_output(data->sensor_pwd, 0);
-	usleep_range(4000, 4100);
-	gpio_direction_output(data->sensor_reset, 1);
-	usleep_range(2000, 2100);
-
-	ov5647_i2c_read(regaddress1, &chipid1);
-	if (chipid1 != 0x56) {
-		rc = -ENODEV;
-		pr_err("ov5647_probe_init_sensor fail chip id doesnot match\n");
-		goto init_probe_fail;
-	}
-
-	ov5647_i2c_read(regaddress2, &chipid2);
-	if (chipid2 != 0x47) {
-		rc = -ENODEV;
-		pr_err("ov5647_probe_init_sensor fail chip id doesnot match\n");
-		goto init_probe_fail;
-	}
-
-	pr_err("ID1: 0x%x\n", chipid1);
-	pr_err("ID2: 0x%x\n", chipid2);
-	goto init_probe_done;
-
-init_probe_fail:
-	pr_err(" ov5647_probe_init_sensor fails\n");
-	ov5647_probe_init_done(data);
-	return rc;
-init_probe_done:
-	pr_debug(" ov5647_probe_init_sensor finishes\n");
-	gpio_direction_output(data->sensor_pwd, 1);
-	return rc;
-}
-
-
-static int ov5647_sensor_open_init(const struct msm_camera_sensor_info *data)
-{
-	int32_t rc = 0;
-
-	CDBG("%s: %d\n", __func__, __LINE__);
-	CDBG("Calling ov5647_sensor_open_init\n");
-
-	ov5647_ctrl = kzalloc(sizeof(struct ov5647_ctrl_t), GFP_KERNEL);
-	if (!ov5647_ctrl) {
-		CDBG("ov5647_init failed!\n");
-		rc = -ENOMEM;
-		goto init_done;
-	}
-	ov5647_ctrl->fps_divider = 1 * 0x00000400;
-	ov5647_ctrl->pict_fps_divider = 1 * 0x00000400;
-	ov5647_ctrl->set_test = TEST_OFF;
-	ov5647_ctrl->prev_res = QTR_SIZE;
-	ov5647_ctrl->pict_res = FULL_SIZE;
-
-	if (data)
-		ov5647_ctrl->sensordata = data;
-
-	prev_frame_length_lines = 0x3d8;
-
-	prev_line_length_pck = 0x768*2;
-
-	snap_frame_length_lines = 0x7b0;
-
-	snap_line_length_pck = 0xa8c;
-
-	/* enable mclk first */
-	msm_camio_clk_rate_set(OV5647_MASTER_CLK_RATE);
-
-	gpio_direction_output(data->sensor_pwd, 1);
-	gpio_direction_output(data->sensor_reset, 0);
-	usleep_range(10000, 11000);
-	/* power on camera ldo and vreg */
-	if (ov5647_ctrl->sensordata->pmic_gpio_enable)
-		lcd_camera_power_onoff(1);
-	usleep_range(10000, 11000); /*waiting for ldo stable*/
-	gpio_direction_output(data->sensor_pwd, 0);
-	msleep(20);
-	gpio_direction_output(data->sensor_reset, 1);
-	msleep(25);
-
-	CDBG("init settings\n");
-	if (ov5647_ctrl->prev_res == QTR_SIZE)
-		rc = ov5647_sensor_setting(REG_INIT, RES_PREVIEW);
-	else
-		rc = ov5647_sensor_setting(REG_INIT, RES_CAPTURE);
-	ov5647_ctrl->fps = 30 * Q8;
-
-	/* enable AF actuator */
-	if (ov5647_ctrl->sensordata->vcm_enable) {
-		CDBG("enable AF actuator, gpio = %d\n",
-			 ov5647_ctrl->sensordata->vcm_pwd);
-		rc = gpio_request(ov5647_ctrl->sensordata->vcm_pwd,
-						"ov5647_af");
-		if (!rc)
-			gpio_direction_output(
-				ov5647_ctrl->sensordata->vcm_pwd,
-				 1);
-		else {
-			pr_err("ov5647_ctrl gpio request failed!\n");
-			goto init_fail;
-		}
-		msleep(20);
-		rc = ov5647_set_default_focus(0);
-		if (rc < 0) {
-			gpio_direction_output(ov5647_ctrl->sensordata->vcm_pwd,
-								0);
-			gpio_free(ov5647_ctrl->sensordata->vcm_pwd);
-		}
-	}
-	if (rc < 0)
-		goto init_fail;
-	else
-		goto init_done;
-init_fail:
-	CDBG("init_fail\n");
-	ov5647_probe_init_done(data);
-	/* No need to power OFF camera ldo and vreg
-	affects Display while resume */
-init_done:
-	CDBG("init_done\n");
-	return rc;
-}
-
-static int ov5647_i2c_remove(struct i2c_client *client)
-{
-	return 0;
-}
-
-static int ov5647_init_client(struct i2c_client *client)
-{
-	/* Initialize the MSM_CAMI2C Chip */
-	init_waitqueue_head(&ov5647_wait_queue);
-	return 0;
-}
-
-static int ov5647_af_init_client(struct i2c_client *client)
-{
-	/* Initialize the MSM_CAMI2C Chip */
-	init_waitqueue_head(&ov5647_af_wait_queue);
-	return 0;
-}
-
-static const struct i2c_device_id ov5647_af_i2c_id[] = {
-	{"ov5647_af", 0},
-	{ }
-};
-
-static int ov5647_af_i2c_probe(struct i2c_client *client,
-		const struct i2c_device_id *id)
-{
-	int rc = 0;
-	CDBG("ov5647_af_probe called!\n");
-
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		CDBG("i2c_check_functionality failed\n");
-		goto probe_failure;
-	}
-
-	ov5647_af_sensorw = kzalloc(sizeof(struct ov5647_work_t), GFP_KERNEL);
-	if (!ov5647_af_sensorw) {
-		CDBG("kzalloc failed.\n");
-		rc = -ENOMEM;
-		goto probe_failure;
-	}
-
-	i2c_set_clientdata(client, ov5647_af_sensorw);
-	ov5647_af_init_client(client);
-	ov5647_af_client = client;
-
-	msleep(50);
-
-	CDBG("ov5647_af_probe successed! rc = %d\n", rc);
-	return 0;
-
-probe_failure:
-	CDBG("ov5647_af_probe failed! rc = %d\n", rc);
-	return rc;
-}
-
-static const struct i2c_device_id ov5647_i2c_id[] = {
-	{"ov5647", 0}, {}
-};
-
-static int ov5647_i2c_probe(struct i2c_client *client,
-		const struct i2c_device_id *id)
-{
-	int rc = 0;
-	CDBG("ov5647_probe called!\n");
-
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		CDBG("i2c_check_functionality failed\n");
-		goto probe_failure;
-	}
-
-	ov5647_sensorw = kzalloc(sizeof(struct ov5647_work_t), GFP_KERNEL);
-	if (!ov5647_sensorw) {
-		CDBG("kzalloc failed.\n");
-		rc = -ENOMEM;
-		goto probe_failure;
-	}
-
-	i2c_set_clientdata(client, ov5647_sensorw);
-	ov5647_init_client(client);
-	ov5647_client = client;
-
-	msleep(50);
-
-	CDBG("ov5647_probe successed! rc = %d\n", rc);
-	return 0;
-
-probe_failure:
-	CDBG("ov5647_probe failed! rc = %d\n", rc);
-	return rc;
-}
-
-static int __devexit ov5647_remove(struct i2c_client *client)
-{
-	struct ov5647_work_t *sensorw = i2c_get_clientdata(client);
-	free_irq(client->irq, sensorw);
-	ov5647_client = NULL;
-	kfree(sensorw);
-	return 0;
-}
-
-static int __devexit ov5647_af_remove(struct i2c_client *client)
-{
-	struct ov5647_work_t *ov5647_af = i2c_get_clientdata(client);
-	free_irq(client->irq, ov5647_af);
-	ov5647_af_client = NULL;
-	kfree(ov5647_af);
-	return 0;
-}
-
-static struct i2c_driver ov5647_i2c_driver = {
-	.id_table = ov5647_i2c_id,
-	.probe  = ov5647_i2c_probe,
-	.remove = ov5647_i2c_remove,
-	.driver = {
-		.name = "ov5647",
-	},
-};
-
-static struct i2c_driver ov5647_af_i2c_driver = {
-	.id_table = ov5647_af_i2c_id,
-	.probe  = ov5647_af_i2c_probe,
-	.remove = __exit_p(ov5647_af_i2c_remove),
-	.driver = {
-		.name = "ov5647_af",
-	},
-};
-
-int ov5647_sensor_config(void __user *argp)
-{
-	struct sensor_cfg_data cdata;
-	long   rc = 0;
-	if (copy_from_user(&cdata,
-				(void *)argp,
-				sizeof(struct sensor_cfg_data)))
-		return -EFAULT;
-	mutex_lock(&ov5647_mut);
-	CDBG("ov5647_sensor_config: cfgtype = %d\n",
-			cdata.cfgtype);
-	switch (cdata.cfgtype) {
-	case CFG_GET_PICT_FPS:
-		ov5647_get_pict_fps(
-			cdata.cfg.gfps.prevfps,
-			&(cdata.cfg.gfps.pictfps));
-
-		if (copy_to_user((void *)argp,
-			&cdata,
-			sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-	case CFG_GET_PREV_L_PF:
-		cdata.cfg.prevl_pf =
-			ov5647_get_prev_lines_pf();
-
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-	case CFG_GET_PREV_P_PL:
-		cdata.cfg.prevp_pl =
-			ov5647_get_prev_pixels_pl();
-
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-	case CFG_GET_PICT_L_PF:
-		cdata.cfg.pictl_pf =
-			ov5647_get_pict_lines_pf();
-
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-	case CFG_GET_PICT_P_PL:
-		cdata.cfg.pictp_pl =
-			ov5647_get_pict_pixels_pl();
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-	case CFG_GET_PICT_MAX_EXP_LC:
-		cdata.cfg.pict_max_exp_lc =
-			ov5647_get_pict_max_exp_lc();
-
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-	case CFG_SET_FPS:
-	case CFG_SET_PICT_FPS:
-		rc = ov5647_set_fps(&(cdata.cfg.fps));
-		break;
-	case CFG_SET_EXP_GAIN:
-		rc = ov5647_write_exp_gain(cdata.cfg.exp_gain.gain,
-				cdata.cfg.exp_gain.line);
-		break;
-	case CFG_SET_PICT_EXP_GAIN:
-		rc = ov5647_set_pict_exp_gain(cdata.cfg.exp_gain.gain,
-				cdata.cfg.exp_gain.line);
-		break;
-	case CFG_SET_MODE:
-		rc = ov5647_set_sensor_mode(cdata.mode, cdata.rs);
-		break;
-	case CFG_PWR_DOWN:
-		rc = ov5647_power_down();
-		break;
-	case CFG_MOVE_FOCUS:
-		rc = ov5647_move_focus(cdata.cfg.focus.dir,
-				cdata.cfg.focus.steps);
-		break;
-	case CFG_SET_DEFAULT_FOCUS:
-		rc = ov5647_set_default_focus(cdata.cfg.focus.steps);
-		break;
-
-	case CFG_GET_AF_MAX_STEPS:
-		cdata.max_steps = OV5647_TOTAL_STEPS_NEAR_TO_FAR;
-		if (copy_to_user((void *)argp,
-					&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-	case CFG_SET_EFFECT:
-		rc = ov5647_set_default_focus(cdata.cfg.effect);
-		break;
-	default:
-		rc = -EFAULT;
-		break;
-	}
-	mutex_unlock(&ov5647_mut);
-
-	return rc;
-}
-
-static int ov5647_sensor_release(void)
-{
-	int rc = -EBADF;
-	unsigned short rdata;
-
-	mutex_lock(&ov5647_mut);
-	ov5647_power_down();
-	msleep(20);
-	ov5647_i2c_read(0x3018, &rdata);
-	rdata |= 0x18; /*set bit 3 bit 4 to 1*/
-	ov5647_i2c_write_b_sensor(0x3018, rdata);/*write back*/
-	msleep(20);
-
-	gpio_set_value(ov5647_ctrl->sensordata->sensor_pwd, 1);
-	usleep_range(5000, 5100);
-	if (ov5647_ctrl->sensordata->vcm_enable) {
-		gpio_direction_output(ov5647_ctrl->sensordata->vcm_pwd, 0);
-		gpio_free(ov5647_ctrl->sensordata->vcm_pwd);
-	}
-
-	/* No need to power OFF camera ldo and vreg
-	affects Display while resume */
-
-	kfree(ov5647_ctrl);
-	ov5647_ctrl = NULL;
-	CDBG("ov5647_release completed\n");
-	mutex_unlock(&ov5647_mut);
-
-	return rc;
-}
-
-static int ov5647_sensor_probe(const struct msm_camera_sensor_info *info,
-		struct msm_sensor_ctrl *s)
-{
-	int rc = 0;
-
-	CDBG("%s E\n", __func__);
-
-	gpio_direction_output(info->sensor_pwd, 1);
-	gpio_direction_output(info->sensor_reset, 0);
-	usleep_range(1000, 1100);
-	/* turn on ldo and vreg */
-	if (info->pmic_gpio_enable)
-		lcd_camera_power_onoff(1);
-
-	rc = i2c_add_driver(&ov5647_i2c_driver);
-	if (rc < 0 || ov5647_client == NULL) {
-		rc = -ENOTSUPP;
-		CDBG("I2C add driver ov5647 failed");
-		goto probe_fail_2;
-	}
-	if (info->vcm_enable) {
-		rc = i2c_add_driver(&ov5647_af_i2c_driver);
-		if (rc < 0 || ov5647_af_client == NULL) {
-			rc = -ENOTSUPP;
-			CDBG("I2C add driver ov5647 af failed");
-			goto probe_fail_3;
-		}
-	}
-	msm_camio_clk_rate_set(OV5647_MASTER_CLK_RATE);
-
-	rc = ov5647_probe_init_sensor(info);
-	if (rc < 0)
-		goto probe_fail_1;
-
-	s->s_init = ov5647_sensor_open_init;
-	s->s_release = ov5647_sensor_release;
-	s->s_config  = ov5647_sensor_config;
-	s->s_mount_angle = info->sensor_platform_info->mount_angle;
-	gpio_set_value(info->sensor_pwd, 1);
-	ov5647_probe_init_done(info);
-	/* turn off ldo and vreg */
-	if (info->pmic_gpio_enable)
-		lcd_camera_power_onoff(0);
-
-	CDBG("%s X", __func__);
-	return rc;
-
-probe_fail_3:
-	i2c_del_driver(&ov5647_af_i2c_driver);
-probe_fail_2:
-	i2c_del_driver(&ov5647_i2c_driver);
-probe_fail_1:
-	/* turn off ldo and vreg */
-	if (info->pmic_gpio_enable)
-		lcd_camera_power_onoff(0);
-	CDBG("ov5647_sensor_probe: SENSOR PROBE FAILS!\n");
-	CDBG("%s X", __func__);
-	return rc;
-}
-
-static int __devinit ov5647_probe(struct platform_device *pdev)
-{
-	return msm_camera_drv_start(pdev, ov5647_sensor_probe);
-}
-
-static struct platform_driver msm_camera_driver = {
-	.probe = ov5647_probe,
-	.driver = {
-		.name = "msm_camera_ov5647",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init ov5647_init(void)
-{
-	return platform_driver_register(&msm_camera_driver);
-}
-
-module_init(ov5647_init);
-MODULE_DESCRIPTION("Omnivision 5 MP Bayer sensor driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/ov5647.h b/drivers/media/video/msm/ov5647.h
deleted file mode 100644
index b43f15c..0000000
--- a/drivers/media/video/msm/ov5647.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 OV5647_H
-#define OV5647_H
-#include <linux/types.h>
-#include <mach/board.h>
-
-extern struct ov5647_reg ov5647_regs;
-extern int lcd_camera_power_onoff(int on);
-extern struct rw_semaphore leds_list_lock;
-extern struct list_head leds_list;
-
-struct ov5647_i2c_reg_conf {
-	unsigned short waddr;
-	unsigned short wdata;
-};
-
-enum ov5647_test_mode_t {
-	TEST_OFF,
-	TEST_1,
-	TEST_2,
-	TEST_3
-};
-
-enum ov5647_resolution_t {
-	QTR_SIZE,
-	FULL_SIZE,
-	INVALID_SIZE
-};
-enum ov5647_setting {
-	RES_PREVIEW,
-	RES_CAPTURE
-};
-enum ov5647_reg_update {
-	/* Sensor egisters that need to be updated during initialization */
-	REG_INIT,
-	/* Sensor egisters that needs periodic I2C writes */
-	UPDATE_PERIODIC,
-	/* All the sensor Registers will be updated */
-	UPDATE_ALL,
-	/* Not valid update */
-	UPDATE_INVALID
-};
-
-enum ov5647_reg_pll {
-	E013_VT_PIX_CLK_DIV,
-	E013_VT_SYS_CLK_DIV,
-	E013_PRE_PLL_CLK_DIV,
-	E013_PLL_MULTIPLIER,
-	E013_OP_PIX_CLK_DIV,
-	E013_OP_SYS_CLK_DIV
-};
-
-enum ov5647_reg_mode {
-	E013_X_ADDR_START,
-	E013_X_ADDR_END,
-	E013_Y_ADDR_START,
-	E013_Y_ADDR_END,
-	E013_X_OUTPUT_SIZE,
-	E013_Y_OUTPUT_SIZE,
-	E013_DATAPATH_SELECT,
-	E013_READ_MODE,
-	E013_ANALOG_CONTROL5,
-	E013_DAC_LD_4_5,
-	E013_SCALING_MODE,
-	E013_SCALE_M,
-	E013_LINE_LENGTH_PCK,
-	E013_FRAME_LENGTH_LINES,
-	E013_COARSE_INTEGRATION_TIME,
-	E013_FINE_INTEGRATION_TIME,
-	E013_FINE_CORRECTION
-};
-
-struct ov5647_reg {
-	const struct ov5647_i2c_reg_conf *rec_settings;
-	const unsigned short rec_size;
-	const struct ov5647_i2c_reg_conf *reg_prev;
-	const unsigned short reg_prev_size;
-	const struct ov5647_i2c_reg_conf *reg_snap;
-	const unsigned short reg_snap_size;
-};
-#endif /* OV5647_H */
diff --git a/drivers/media/video/msm/ov5647_reg.c b/drivers/media/video/msm/ov5647_reg.c
deleted file mode 100644
index 4a0fed4..0000000
--- a/drivers/media/video/msm/ov5647_reg.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 "ov5647.h"
-struct ov5647_i2c_reg_conf ov5647_prev_settings[] = {
-	/*1280*960 Reference Setting 24M MCLK 2lane 280Mbps/lane 30fps
-	for back to preview*/
-	{0x3035, 0x21},
-	{0x3036, 0x37},
-	{0x3821, 0x07},
-	{0x3820, 0x41},
-	{0x3612, 0x09},
-	{0x3618, 0x00},
-	{0x380c, 0x07},
-	{0x380d, 0x68},
-	{0x380e, 0x03},
-	{0x380f, 0xd8},
-	{0x3814, 0x31},
-	{0x3815, 0x31},
-	{0x3709, 0x52},
-	{0x3808, 0x05},
-	{0x3809, 0x00},
-	{0x380a, 0x03},
-	{0x380b, 0xc0},
-	{0x3800, 0x00},
-	{0x3801, 0x18},
-	{0x3802, 0x00},
-	{0x3803, 0x0e},
-	{0x3804, 0x0a},
-	{0x3805, 0x27},
-	{0x3806, 0x07},
-	{0x3807, 0x95},
-	{0x4004, 0x02},
-};
-
-struct ov5647_i2c_reg_conf ov5647_snap_settings[] = {
-	/*2608*1952 Reference Setting 24M MCLK 2lane 280Mbps/lane 30fps*/
-	{0x3035, 0x21},
-	{0x3036, 0x4f},
-	{0x3821, 0x06},
-	{0x3820, 0x00},
-	{0x3612, 0x0b},
-	{0x3618, 0x04},
-	{0x380c, 0x0a},
-	{0x380d, 0x8c},
-	{0x380e, 0x07},
-	{0x380f, 0xb0},
-	{0x3814, 0x11},
-	{0x3815, 0x11},
-	{0x3709, 0x12},
-	{0x3808, 0x0a},
-	{0x3809, 0x30},
-	{0x380a, 0x07},
-	{0x380b, 0xa0},
-	{0x3800, 0x00},
-	{0x3801, 0x04},
-	{0x3802, 0x00},
-	{0x3803, 0x00},
-	{0x3804, 0x0a},
-	{0x3805, 0x3b},
-	{0x3806, 0x07},
-	{0x3807, 0xa3},
-	{0x4004, 0x04},
-};
-
-struct ov5647_i2c_reg_conf ov5647_recommend_settings[] = {
-	{0x3035, 0x11},
-	{0x303c, 0x11},
-	{0x370c, 0x03},
-	{0x5000, 0x06},
-	{0x5003, 0x08},
-	{0x5a00, 0x08},
-	{0x3000, 0xff},
-	{0x3001, 0xff},
-	{0x3002, 0xff},
-	{0x301d, 0xf0},
-	{0x3a18, 0x00},
-	{0x3a19, 0xf8},
-	{0x3c01, 0x80},
-	{0x3b07, 0x0c},
-	{0x3708, 0x64},
-	{0x3630, 0x2e},
-	{0x3632, 0xe2},
-	{0x3633, 0x23},
-	{0x3634, 0x44},
-	{0x3620, 0x64},
-	{0x3621, 0xe0},
-	{0x3600, 0x37},
-	{0x3704, 0xa0},
-	{0x3703, 0x5a},
-	{0x3715, 0x78},
-	{0x3717, 0x01},
-	{0x3731, 0x02},
-	{0x370b, 0x60},
-	{0x3705, 0x1a},
-	{0x3f05, 0x02},
-	{0x3f06, 0x10},
-	{0x3f01, 0x0a},
-	{0x3a08, 0x01},
-	{0x3a0f, 0x58},
-	{0x3a10, 0x50},
-	{0x3a1b, 0x58},
-	{0x3a1e, 0x50},
-	{0x3a11, 0x60},
-	{0x3a1f, 0x28},
-	{0x4001, 0x02},
-	{0x4000, 0x09},
-	{0x3000, 0x00},
-	{0x3001, 0x00},
-	{0x3002, 0x00},
-	{0x3017, 0xe0},
-	{0x301c, 0xfc},
-	{0x3636, 0x06},
-	{0x3016, 0x08},
-	{0x3827, 0xec},
-	{0x3018, 0x44},
-	{0x3035, 0x21},
-	{0x3106, 0xf5},
-	{0x3034, 0x18},
-	{0x301c, 0xf8},
-	/*lens setting*/
-	{0x5000, 0x86},
-	{0x5800, 0x11},
-	{0x5801, 0x0c},
-	{0x5802, 0x0a},
-	{0x5803, 0x0b},
-	{0x5804, 0x0d},
-	{0x5805, 0x13},
-	{0x5806, 0x09},
-	{0x5807, 0x05},
-	{0x5808, 0x03},
-	{0x5809, 0x03},
-	{0x580a, 0x06},
-	{0x580b, 0x08},
-	{0x580c, 0x05},
-	{0x580d, 0x01},
-	{0x580e, 0x00},
-	{0x580f, 0x00},
-	{0x5810, 0x02},
-	{0x5811, 0x06},
-	{0x5812, 0x05},
-	{0x5813, 0x01},
-	{0x5814, 0x00},
-	{0x5815, 0x00},
-	{0x5816, 0x02},
-	{0x5817, 0x06},
-	{0x5818, 0x09},
-	{0x5819, 0x05},
-	{0x581a, 0x04},
-	{0x581b, 0x04},
-	{0x581c, 0x06},
-	{0x581d, 0x09},
-	{0x581e, 0x11},
-	{0x581f, 0x0c},
-	{0x5820, 0x0b},
-	{0x5821, 0x0b},
-	{0x5822, 0x0d},
-	{0x5823, 0x13},
-	{0x5824, 0x22},
-	{0x5825, 0x26},
-	{0x5826, 0x26},
-	{0x5827, 0x24},
-	{0x5828, 0x24},
-	{0x5829, 0x24},
-	{0x582a, 0x22},
-	{0x582b, 0x20},
-	{0x582c, 0x22},
-	{0x582d, 0x26},
-	{0x582e, 0x22},
-	{0x582f, 0x22},
-	{0x5830, 0x42},
-	{0x5831, 0x22},
-	{0x5832, 0x02},
-	{0x5833, 0x24},
-	{0x5834, 0x22},
-	{0x5835, 0x22},
-	{0x5836, 0x22},
-	{0x5837, 0x26},
-	{0x5838, 0x42},
-	{0x5839, 0x26},
-	{0x583a, 0x06},
-	{0x583b, 0x26},
-	{0x583c, 0x24},
-	{0x583d, 0xce},
-	/* manual AWB,manual AE,close Lenc,open WBC*/
-	{0x3503, 0x03}, /*manual AE*/
-	{0x3501, 0x10},
-	{0x3502, 0x80},
-	{0x350a, 0x00},
-	{0x350b, 0x7f},
-	{0x5001, 0x01}, /*manual AWB*/
-	{0x5180, 0x08},
-	{0x5186, 0x04},
-	{0x5187, 0x00},
-	{0x5188, 0x04},
-	{0x5189, 0x00},
-	{0x518a, 0x04},
-	{0x518b, 0x00},
-	{0x5000, 0x06}, /*No lenc,WBC on*/
-};
-
-struct ov5647_reg ov5647_regs = {
-	.rec_settings = &ov5647_recommend_settings[0],
-	.rec_size = ARRAY_SIZE(ov5647_recommend_settings),
-	.reg_prev = &ov5647_prev_settings[0],
-	.reg_prev_size = ARRAY_SIZE(ov5647_prev_settings),
-	.reg_snap = &ov5647_snap_settings[0],
-	.reg_snap_size = ARRAY_SIZE(ov5647_snap_settings),
-};
diff --git a/drivers/media/video/msm/ov7692.c b/drivers/media/video/msm/ov7692.c
deleted file mode 100644
index 7696b44..0000000
--- a/drivers/media/video/msm/ov7692.c
+++ /dev/null
@@ -1,597 +0,0 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. 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/delay.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/slab.h>
-#include <media/msm_camera.h>
-#include <mach/camera.h>
-#include "ov7692.h"
-
-/*=============================================================
-	SENSOR REGISTER DEFINES
-==============================================================*/
-#define Q8    0x00000100
-
-/* Omnivision8810 product ID register address */
-#define REG_OV7692_MODEL_ID_MSB                       0x0A
-#define REG_OV7692_MODEL_ID_LSB                       0x0B
-
-#define OV7692_MODEL_ID                       0x7692
-/* Omnivision8810 product ID */
-
-/* Time in milisecs for waiting for the sensor to reset */
-#define OV7692_RESET_DELAY_MSECS    66
-#define OV7692_DEFAULT_CLOCK_RATE   24000000
-/* Registers*/
-
-/* Color bar pattern selection */
-#define OV7692_COLOR_BAR_PATTERN_SEL_REG     0x82
-/* Color bar enabling control */
-#define OV7692_COLOR_BAR_ENABLE_REG           0x601
-/* Time in milisecs for waiting for the sensor to reset*/
-#define OV7692_RESET_DELAY_MSECS    66
-
-/*============================================================================
-							DATA DECLARATIONS
-============================================================================*/
-/*  96MHz PCLK @ 24MHz MCLK */
-struct reg_addr_val_pair_struct ov7692_init_settings_array[] = {
-    {0x12, 0x80},
-    {0x0e, 0x08},
-    {0x69, 0x52},
-    {0x1e, 0xb3},
-    {0x48, 0x42},
-    {0xff, 0x01},
-    {0xae, 0xa0},
-    {0xa8, 0x26},
-    {0xb4, 0xc0},
-    {0xb5, 0x40},
-    {0xff, 0x00},
-    {0x0c, 0x00},
-    {0x62, 0x10},
-    {0x12, 0x00},
-    {0x17, 0x65},
-    {0x18, 0xa4},
-    {0x19, 0x0a},
-    {0x1a, 0xf6},
-    {0x3e, 0x30},
-    {0x64, 0x0a},
-    {0xff, 0x01},
-    {0xb4, 0xc0},
-    {0xff, 0x00},
-    {0x67, 0x20},
-    {0x81, 0x3f},
-    {0xcc, 0x02},
-    {0xcd, 0x80},
-    {0xce, 0x01},
-    {0xcf, 0xe0},
-    {0xc8, 0x02},
-    {0xc9, 0x80},
-    {0xca, 0x01},
-    {0xcb, 0xe0},
-    {0xd0, 0x48},
-    {0x82, 0x03},
-    {0x0e, 0x00},
-    {0x70, 0x00},
-    {0x71, 0x34},
-    {0x74, 0x28},
-    {0x75, 0x98},
-    {0x76, 0x00},
-    {0x77, 0x64},
-    {0x78, 0x01},
-    {0x79, 0xc2},
-    {0x7a, 0x4e},
-    {0x7b, 0x1f},
-    {0x7c, 0x00},
-    {0x11, 0x00},
-    {0x20, 0x00},
-    {0x21, 0x23},
-    {0x50, 0x9a},
-    {0x51, 0x80},
-    {0x4c, 0x7d},
-    {0x0e, 0x00},
-    {0x80, 0x7f},
-    {0x85, 0x10},
-    {0x86, 0x00},
-    {0x87, 0x00},
-    {0x88, 0x00},
-    {0x89, 0x2a},
-    {0x8a, 0x26},
-    {0x8b, 0x22},
-    {0xbb, 0x7a},
-    {0xbc, 0x69},
-    {0xbd, 0x11},
-    {0xbe, 0x13},
-    {0xbf, 0x81},
-    {0xc0, 0x96},
-    {0xc1, 0x1e},
-    {0xb7, 0x05},
-    {0xb8, 0x09},
-    {0xb9, 0x00},
-    {0xba, 0x18},
-    {0x5a, 0x1f},
-    {0x5b, 0x9f},
-    {0x5c, 0x6a},
-    {0x5d, 0x42},
-    {0x24, 0x78},
-    {0x25, 0x68},
-    {0x26, 0xb3},
-    {0xa3, 0x0b},
-    {0xa4, 0x15},
-    {0xa5, 0x2a},
-    {0xa6, 0x51},
-    {0xa7, 0x63},
-    {0xa8, 0x74},
-    {0xa9, 0x83},
-    {0xaa, 0x91},
-    {0xab, 0x9e},
-    {0xac, 0xaa},
-    {0xad, 0xbe},
-    {0xae, 0xce},
-    {0xaf, 0xe5},
-    {0xb0, 0xf3},
-    {0xb1, 0xfb},
-    {0xb2, 0x06},
-    {0x8c, 0x5c},
-    {0x8d, 0x11},
-    {0x8e, 0x12},
-    {0x8f, 0x19},
-    {0x90, 0x50},
-    {0x91, 0x20},
-    {0x92, 0x96},
-    {0x93, 0x80},
-    {0x94, 0x13},
-    {0x95, 0x1b},
-    {0x96, 0xff},
-    {0x97, 0x00},
-    {0x98, 0x3d},
-    {0x99, 0x36},
-    {0x9a, 0x51},
-    {0x9b, 0x43},
-    {0x9c, 0xf0},
-    {0x9d, 0xf0},
-    {0x9e, 0xf0},
-    {0x9f, 0xff},
-    {0xa0, 0x68},
-    {0xa1, 0x62},
-    {0xa2, 0x0e},
-};
-
-static bool OV7692_CSI_CONFIG;
-/* 816x612, 24MHz MCLK 96MHz PCLK */
-uint32_t OV7692_FULL_SIZE_WIDTH        = 640;
-uint32_t OV7692_FULL_SIZE_HEIGHT       = 480;
-
-uint32_t OV7692_QTR_SIZE_WIDTH         = 640;
-uint32_t OV7692_QTR_SIZE_HEIGHT        = 480;
-
-uint32_t OV7692_HRZ_FULL_BLK_PIXELS    = 16;
-uint32_t OV7692_VER_FULL_BLK_LINES     = 12;
-uint32_t OV7692_HRZ_QTR_BLK_PIXELS     = 16;
-uint32_t OV7692_VER_QTR_BLK_LINES      = 12;
-
-struct ov7692_work_t {
-	struct work_struct work;
-};
-static struct  ov7692_work_t *ov7692_sensorw;
-static struct  i2c_client *ov7692_client;
-struct ov7692_ctrl_t {
-	const struct  msm_camera_sensor_info *sensordata;
-	uint32_t sensormode;
-	uint32_t fps_divider;		/* init to 1 * 0x00000400 */
-	uint32_t pict_fps_divider;	/* init to 1 * 0x00000400 */
-	uint32_t fps;
-	int32_t  curr_lens_pos;
-	uint32_t curr_step_pos;
-	uint32_t my_reg_gain;
-	uint32_t my_reg_line_count;
-	uint32_t total_lines_per_frame;
-	enum ov7692_resolution_t prev_res;
-	enum ov7692_resolution_t pict_res;
-	enum ov7692_resolution_t curr_res;
-	enum ov7692_test_mode_t  set_test;
-	unsigned short imgaddr;
-};
-static struct ov7692_ctrl_t *ov7692_ctrl;
-static DECLARE_WAIT_QUEUE_HEAD(ov7692_wait_queue);
-DEFINE_MUTEX(ov7692_mut);
-
-/*=============================================================*/
-
-static int ov7692_i2c_rxdata(unsigned short saddr,
-	unsigned char *rxdata, int length)
-{
-	struct i2c_msg msgs[] = {
-		{
-			.addr  = saddr,
-			.flags = 0,
-			.len   = 1,
-			.buf   = rxdata,
-		},
-		{
-			.addr  = saddr,
-			.flags = I2C_M_RD,
-			.len   = 1,
-			.buf   = rxdata,
-		},
-	};
-	if (i2c_transfer(ov7692_client->adapter, msgs, 2) < 0) {
-		CDBG("ov7692_i2c_rxdata failed!\n");
-		return -EIO;
-	}
-	return 0;
-}
-static int32_t ov7692_i2c_txdata(unsigned short saddr,
-				unsigned char *txdata, int length)
-{
-	struct i2c_msg msg[] = {
-		{
-			.addr = saddr,
-			.flags = 0,
-			.len = 2,
-			.buf = txdata,
-		 },
-	};
-	if (i2c_transfer(ov7692_client->adapter, msg, 1) < 0) {
-		CDBG("ov7692_i2c_txdata faild 0x%x\n", ov7692_client->addr);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int32_t ov7692_i2c_read(uint8_t raddr,
-	uint8_t *rdata, int rlen)
-{
-	int32_t rc = 0;
-	unsigned char buf[1];
-	if (!rdata)
-		return -EIO;
-	memset(buf, 0, sizeof(buf));
-	buf[0] = raddr;
-	rc = ov7692_i2c_rxdata(ov7692_client->addr >> 1, buf, rlen);
-	if (rc < 0) {
-		CDBG("ov7692_i2c_read 0x%x failed!\n", raddr);
-		return rc;
-	}
-	*rdata = buf[0];
-	return rc;
-}
-static int32_t ov7692_i2c_write_b_sensor(uint8_t waddr, uint8_t bdata)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[2];
-	memset(buf, 0, sizeof(buf));
-	buf[0] = waddr;
-	buf[1] = bdata;
-	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
-	rc = ov7692_i2c_txdata(ov7692_client->addr >> 1, buf, 2);
-	if (rc < 0)
-		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
-			waddr, bdata);
-	return rc;
-}
-
-static int32_t ov7692_sensor_setting(int update_type, int rt)
-{
-	int32_t i, array_length;
-	int32_t rc = 0;
-	struct msm_camera_csi_params ov7692_csi_params;
-	switch (update_type) {
-	case REG_INIT:
-		OV7692_CSI_CONFIG = 0;
-		ov7692_i2c_write_b_sensor(0x0e, 0x08);
-		return rc;
-		break;
-	case UPDATE_PERIODIC:
-		if (!OV7692_CSI_CONFIG) {
-			ov7692_csi_params.lane_cnt = 1;
-			ov7692_csi_params.data_format = CSI_8BIT;
-			ov7692_csi_params.lane_assign = 0xe4;
-			ov7692_csi_params.dpcm_scheme = 0;
-			ov7692_csi_params.settle_cnt = 0x14;
-
-			rc = msm_camio_csi_config(&ov7692_csi_params);
-			msleep(10);
-			array_length = sizeof(ov7692_init_settings_array) /
-				sizeof(ov7692_init_settings_array[0]);
-			for (i = 0; i < array_length; i++) {
-				rc = ov7692_i2c_write_b_sensor(
-					ov7692_init_settings_array[i].reg_addr,
-					ov7692_init_settings_array[i].reg_val);
-				if (rc < 0)
-					return rc;
-			}
-			OV7692_CSI_CONFIG = 1;
-			msleep(20);
-			return rc;
-		}
-		break;
-	default:
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
-
-static int32_t ov7692_video_config(int mode)
-{
-	int32_t rc = 0;
-	int rt;
-	/* change sensor resolution if needed */
-	rt = RES_PREVIEW;
-
-	if (ov7692_sensor_setting(UPDATE_PERIODIC, rt) < 0)
-		return rc;
-	ov7692_ctrl->curr_res = ov7692_ctrl->prev_res;
-	ov7692_ctrl->sensormode = mode;
-	return rc;
-}
-
-static int32_t ov7692_set_sensor_mode(int mode,
-	int res)
-{
-	int32_t rc = 0;
-	switch (mode) {
-	case SENSOR_PREVIEW_MODE:
-		rc = ov7692_video_config(mode);
-		break;
-	case SENSOR_SNAPSHOT_MODE:
-	case SENSOR_RAW_SNAPSHOT_MODE:
-		break;
-	default:
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
-static int32_t ov7692_power_down(void)
-{
-	return 0;
-}
-
-static int ov7692_probe_init_sensor(const struct msm_camera_sensor_info *data)
-{
-	uint8_t model_id_msb, model_id_lsb = 0;
-	uint16_t model_id;
-	int32_t rc = 0;
-	/*The reset pin is not physically connected to the sensor.
-	The standby pin will do the reset hence there is no need
-	to request the gpio reset*/
-
-	/* Read sensor Model ID: */
-	rc = ov7692_i2c_read(REG_OV7692_MODEL_ID_MSB, &model_id_msb, 1);
-	if (rc < 0)
-		goto init_probe_fail;
-	rc = ov7692_i2c_read(REG_OV7692_MODEL_ID_LSB, &model_id_lsb, 1);
-	if (rc < 0)
-		goto init_probe_fail;
-	model_id = (model_id_msb << 8) | ((model_id_lsb & 0x00FF)) ;
-	CDBG("ov7692 model_id = 0x%x, 0x%x, 0x%x\n",
-		 model_id, model_id_msb, model_id_lsb);
-	/* 4. Compare sensor ID to OV7692 ID: */
-	if (model_id != OV7692_MODEL_ID) {
-		rc = -ENODEV;
-		goto init_probe_fail;
-	}
-	goto init_probe_done;
-init_probe_fail:
-	pr_warning(" ov7692_probe_init_sensor fails\n");
-init_probe_done:
-	CDBG(" ov7692_probe_init_sensor finishes\n");
-	return rc;
-}
-
-int ov7692_sensor_open_init(const struct msm_camera_sensor_info *data)
-{
-	int32_t rc = 0;
-
-	CDBG("%s: %d\n", __func__, __LINE__);
-	CDBG("Calling ov7692_sensor_open_init\n");
-	ov7692_ctrl = kzalloc(sizeof(struct ov7692_ctrl_t), GFP_KERNEL);
-	if (!ov7692_ctrl) {
-		CDBG("ov7692_init failed!\n");
-		rc = -ENOMEM;
-		goto init_done;
-	}
-	ov7692_ctrl->fps_divider = 1 * 0x00000400;
-	ov7692_ctrl->pict_fps_divider = 1 * 0x00000400;
-	ov7692_ctrl->fps = 30 * Q8;
-	ov7692_ctrl->set_test = TEST_OFF;
-	ov7692_ctrl->prev_res = QTR_SIZE;
-	ov7692_ctrl->pict_res = FULL_SIZE;
-	ov7692_ctrl->curr_res = INVALID_SIZE;
-
-	if (data)
-		ov7692_ctrl->sensordata = data;
-
-	/* enable mclk first */
-
-	msm_camio_clk_rate_set(24000000);
-	msleep(20);
-
-	rc = ov7692_probe_init_sensor(data);
-	if (rc < 0) {
-		CDBG("Calling ov7692_sensor_open_init fail\n");
-		goto init_fail;
-	}
-
-	rc = ov7692_sensor_setting(REG_INIT, RES_PREVIEW);
-	if (rc < 0)
-		goto init_fail;
-	else
-		goto init_done;
-
-init_fail:
-	CDBG(" ov7692_sensor_open_init fail\n");
-	kfree(ov7692_ctrl);
-init_done:
-	CDBG("ov7692_sensor_open_init done\n");
-	return rc;
-}
-
-static int ov7692_init_client(struct i2c_client *client)
-{
-	/* Initialize the MSM_CAMI2C Chip */
-	init_waitqueue_head(&ov7692_wait_queue);
-	return 0;
-}
-
-static const struct i2c_device_id ov7692_i2c_id[] = {
-	{"ov7692", 0},
-	{ }
-};
-
-static int ov7692_i2c_probe(struct i2c_client *client,
-	const struct i2c_device_id *id)
-{
-	int rc = 0;
-	CDBG("ov7692_i2c_probe called!\n");
-
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		CDBG("i2c_check_functionality failed\n");
-		goto probe_failure;
-	}
-
-	ov7692_sensorw = kzalloc(sizeof(struct ov7692_work_t), GFP_KERNEL);
-	if (!ov7692_sensorw) {
-		CDBG("kzalloc failed.\n");
-		rc = -ENOMEM;
-		goto probe_failure;
-	}
-
-	i2c_set_clientdata(client, ov7692_sensorw);
-	ov7692_init_client(client);
-	ov7692_client = client;
-
-	CDBG("ov7692_i2c_probe success! rc = %d\n", rc);
-	return 0;
-
-probe_failure:
-	CDBG("ov7692_i2c_probe failed! rc = %d\n", rc);
-	return rc;
-}
-
-static int __exit ov7692_remove(struct i2c_client *client)
-{
-	struct ov7692_work_t_t *sensorw = i2c_get_clientdata(client);
-	free_irq(client->irq, sensorw);
-	ov7692_client = NULL;
-	kfree(sensorw);
-	return 0;
-}
-
-static struct i2c_driver ov7692_i2c_driver = {
-	.id_table = ov7692_i2c_id,
-	.probe  = ov7692_i2c_probe,
-	.remove = __exit_p(ov7692_i2c_remove),
-	.driver = {
-		.name = "ov7692",
-	},
-};
-
-int ov7692_sensor_config(void __user *argp)
-{
-	struct sensor_cfg_data cdata;
-	long   rc = 0;
-	if (copy_from_user(&cdata,
-		(void *)argp,
-		sizeof(struct sensor_cfg_data)))
-		return -EFAULT;
-	mutex_lock(&ov7692_mut);
-	CDBG("ov7692_sensor_config: cfgtype = %d\n",
-	cdata.cfgtype);
-	switch (cdata.cfgtype) {
-	case CFG_SET_MODE:
-		rc = ov7692_set_sensor_mode(cdata.mode,
-			cdata.rs);
-		break;
-	case CFG_PWR_DOWN:
-		rc = ov7692_power_down();
-		break;
-	case CFG_SET_EFFECT:
-		break;
-	default:
-		rc = -EFAULT;
-		break;
-	}
-
-	mutex_unlock(&ov7692_mut);
-
-	return rc;
-}
-static int ov7692_sensor_release(void)
-{
-	int rc = -EBADF;
-	mutex_lock(&ov7692_mut);
-	ov7692_power_down();
-	kfree(ov7692_ctrl);
-	ov7692_ctrl = NULL;
-	CDBG("ov7692_release completed\n");
-	mutex_unlock(&ov7692_mut);
-
-	return rc;
-}
-
-static int ov7692_sensor_probe(const struct msm_camera_sensor_info *info,
-		struct msm_sensor_ctrl *s)
-{
-	int rc = 0;
-	rc = i2c_add_driver(&ov7692_i2c_driver);
-	if (rc < 0 || ov7692_client == NULL) {
-		rc = -ENOTSUPP;
-		goto probe_fail;
-	}
-	msm_camio_clk_rate_set(24000000);
-	rc = ov7692_probe_init_sensor(info);
-	if (rc < 0)
-		goto probe_fail;
-	s->s_init = ov7692_sensor_open_init;
-	s->s_release = ov7692_sensor_release;
-	s->s_config  = ov7692_sensor_config;
-	s->s_camera_type = FRONT_CAMERA_2D;
-	s->s_mount_angle = 0;
-	return rc;
-
-probe_fail:
-	CDBG("ov7692_sensor_probe: SENSOR PROBE FAILS!\n");
-	i2c_del_driver(&ov7692_i2c_driver);
-	return rc;
-}
-
-static int __ov7692_probe(struct platform_device *pdev)
-{
-
-	return msm_camera_drv_start(pdev, ov7692_sensor_probe);
-}
-
-static struct platform_driver msm_camera_driver = {
-	.probe = __ov7692_probe,
-	.driver = {
-		.name = "msm_camera_ov7692",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init ov7692_init(void)
-{
-	return platform_driver_register(&msm_camera_driver);
-}
-
-module_init(ov7692_init);
-
-MODULE_DESCRIPTION("OMNI VGA YUV sensor driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/ov7692.h b/drivers/media/video/msm/ov7692.h
deleted file mode 100644
index fc9cf1c..0000000
--- a/drivers/media/video/msm/ov7692.h
+++ /dev/null
@@ -1,666 +0,0 @@
-/* Copyright (c) 2010, 2012, Code Aurora Forum. 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 OV7692_H
-#define OV7692_H
-#include <linux/types.h>
-#include <mach/board.h>
-
-#define INVMASK(v)  (0xff-v)
-#define OV7692Core_WritePREG(pTbl)  OV7692_WritePRegs \
-			(pTbl, sizeof(pTbl)/sizeof(pTbl[0]))
-
-extern int lcd_camera_power_onoff(int on);
-struct reg_addr_val_pair_struct {
-	uint8_t	reg_addr;
-	uint8_t	reg_val;
-};
-
-enum ov7692_test_mode_t {
-	TEST_OFF,
-	TEST_1,
-	TEST_2,
-	TEST_3
-};
-
-enum ov7692_resolution_t {
-	QTR_SIZE,
-	FULL_SIZE,
-	INVALID_SIZE
-};
-
-enum ov7692_setting {
-	RES_PREVIEW,
-	RES_CAPTURE
-};
-enum ov7692_reg_update {
-	/* Sensor egisters that need to be updated during initialization */
-	REG_INIT,
-	/* Sensor egisters that needs periodic I2C writes */
-	UPDATE_PERIODIC,
-	/* All the sensor Registers will be updated */
-	UPDATE_ALL,
-	/* Not valid update */
-	UPDATE_INVALID
-};
-
-/*OV SENSOR SCCB*/
-struct OV7692_WREG {
-	uint8_t addr;
-	uint8_t data;
-	uint8_t mask;
-} OV7692_WREG;
-
-#ifdef CONFIG_WEBCAM_OV7692_QRD
-/*  96MHz PCLK @ 24MHz MCLK */
-struct reg_addr_val_pair_struct ov7692_init_settings_array[] = {
-	{0x12, 0x80},
-	{0x0e, 0x08},
-	{0x69, 0x52},
-	{0x1e, 0xb3},
-	{0x48, 0x42},
-	{0xff, 0x01},
-	{0xae, 0xa0},
-	{0xa8, 0x26},
-	{0xb4, 0xc0},
-	{0xb5, 0x40},
-	{0xff, 0x00},
-	{0x0c, 0x00},
-	{0x62, 0x10},
-	{0x12, 0x00},
-	{0x17, 0x65},
-	{0x18, 0xa4},
-	{0x19, 0x0a},
-	{0x1a, 0xf6},
-	{0x3e, 0x30},
-	{0x64, 0x0a},
-	{0xff, 0x01},
-	{0xb4, 0xc0},
-	{0xff, 0x00},
-	{0x67, 0x20},
-	{0x81, 0x3f},
-	{0xcc, 0x02},
-	{0xcd, 0x80},
-	{0xce, 0x01},
-	{0xcf, 0xe0},
-	{0xc8, 0x02},
-	{0xc9, 0x80},
-	{0xca, 0x01},
-	{0xcb, 0xe0},
-	{0xd0, 0x48},
-	{0x82, 0x03},
-	/*{0x0e, 0x00},*/
-	{0x70, 0x00},
-	{0x71, 0x34},
-	{0x74, 0x28},
-	{0x75, 0x98},
-	{0x76, 0x00},
-	{0x77, 0x64},
-	{0x78, 0x01},
-	{0x79, 0xc2},
-	{0x7a, 0x4e},
-	{0x7b, 0x1f},
-	{0x7c, 0x00},
-	{0x11, 0x00},
-	{0x20, 0x00},
-	{0x21, 0x23},
-	{0x50, 0x9a},
-	{0x51, 0x80},
-	{0x4c, 0x7d},
-	/*{0x0e, 0x00},*/
-	{0x85, 0x10},
-	{0x86, 0x00},
-	{0x87, 0x00},
-	{0x88, 0x00},
-	{0x89, 0x2a},
-	{0x8a, 0x26},
-	{0x8b, 0x22},
-	{0xbb, 0x7a},
-	{0xbc, 0x69},
-	{0xbd, 0x11},
-	{0xbe, 0x13},
-	{0xbf, 0x81},
-	{0xc0, 0x96},
-	{0xc1, 0x1e},
-	{0xb7, 0x05},
-	{0xb8, 0x09},
-	{0xb9, 0x00},
-	{0xba, 0x18},
-	{0x5a, 0x1f},
-	{0x5b, 0x9f},
-	{0x5c, 0x6a},
-	{0x5d, 0x42},
-	{0x24, 0x78},
-	{0x25, 0x68},
-	{0x26, 0xb3},
-	{0xa3, 0x0b},
-	{0xa4, 0x15},
-	{0xa5, 0x2a},
-	{0xa6, 0x51},
-	{0xa7, 0x63},
-	{0xa8, 0x74},
-	{0xa9, 0x83},
-	{0xaa, 0x91},
-	{0xab, 0x9e},
-	{0xac, 0xaa},
-	{0xad, 0xbe},
-	{0xae, 0xce},
-	{0xaf, 0xe5},
-	{0xb0, 0xf3},
-	{0xb1, 0xfb},
-	{0xb2, 0x06},
-	{0x8c, 0x5c},
-	{0x8d, 0x11},
-	{0x8e, 0x12},
-	{0x8f, 0x19},
-	{0x90, 0x50},
-	{0x91, 0x20},
-	{0x92, 0x96},
-	{0x93, 0x80},
-	{0x94, 0x13},
-	{0x95, 0x1b},
-	{0x96, 0xff},
-	{0x97, 0x00},
-	{0x98, 0x3d},
-	{0x99, 0x36},
-	{0x9a, 0x51},
-	{0x9b, 0x43},
-	{0x9c, 0xf0},
-	{0x9d, 0xf0},
-	{0x9e, 0xf0},
-	{0x9f, 0xff},
-	{0xa0, 0x68},
-	{0xa1, 0x62},
-	{0xa2, 0x0e},
-};
-#endif
-/* Exposure Compensation */
-struct OV7692_WREG ov7692_exposure_compensation_lv0_tbl[] = {
-	/*@@ +1.7EV*/
-	{0x24, 0xc0},
-	{0x25, 0xb8},
-	{0x26, 0xe6},
-};
-
-struct OV7692_WREG ov7692_exposure_compensation_lv1_tbl[] = {
-	/*@@ +1.0EV*/
-	{0x24, 0xa8},
-	{0x25, 0xa0},
-	{0x26, 0xc4},
-};
-
-struct OV7692_WREG ov7692_exposure_compensation_lv2_default_tbl[] = {
-	/*@@ default*/
-	{0x24, 0x86},
-	{0x25, 0x76},
-	{0x26, 0xb3},
-};
-
-struct OV7692_WREG ov7692_exposure_compensation_lv3_tbl[] = {
-	/*@@ -1.0EV*/
-	{0x24, 0x70},
-	{0x25, 0x60},
-	{0x26, 0xa2},
-};
-
-struct OV7692_WREG ov7692_exposure_compensation_lv4_tbl[] = {
-	/*@@ -1.7EV*/
-	{0x24, 0x50},
-	{0x25, 0x40},
-	{0x26, 0xa2},
-};
-
-struct OV7692_WREG ov7692_antibanding_off_tbl[] = {
-	{0x13, 0xE5, INVMASK(0x20)},
-};
-
-struct OV7692_WREG ov7692_antibanding_auto_tbl[] = {
-	{0x13, 0x20, INVMASK(0x20)},
-	{0x14, 0x14, INVMASK(0x17)},
-};
-
-struct OV7692_WREG ov7692_antibanding_50z_tbl[] = {
-	/*Band 50Hz*/
-	{0x13, 0x20, INVMASK(0x20)},
-	{0x14, 0x17, INVMASK(0x17)},
-};
-
-struct OV7692_WREG ov7692_antibanding_60z_tbl[] = {
-	/*Band 60Hz*/
-	{0x13, 0x20, INVMASK(0x20)},
-	{0x14, 0x16, INVMASK(0x17)},
-};
-
-/*Saturation*/
-struct OV7692_WREG ov7692_saturation_lv0_tbl[] = {
-	/*Saturation level 0*/
-	{0x81, 0x33, INVMASK(0x33)},
-	{0xd8, 0x00, INVMASK(0xff)},
-	{0xd9, 0x00, INVMASK(0xff)},
-	{0xd2, 0x02, INVMASK(0xff)},
-};
-
-struct OV7692_WREG ov7692_saturation_lv1_tbl[] = {
-	/*Saturation level 1*/
-	{0x81, 0x33, INVMASK(0x33)},
-	{0xd8, 0x10, INVMASK(0xff)},
-	{0xd9, 0x10, INVMASK(0xff)},
-	{0xd2, 0x02, INVMASK(0xff)},
-};
-
-struct OV7692_WREG ov7692_saturation_lv2_tbl[] = {
-	/*Saturation level 2*/
-	{0x81, 0x33, INVMASK(0x33)},
-	{0xd8, 0x20, INVMASK(0xff)},
-	{0xd9, 0x20, INVMASK(0xff)},
-	{0xd2, 0x02, INVMASK(0xff)},
-
-};
-
-struct OV7692_WREG ov7692_saturation_lv3_tbl[] = {
-	/*Saturation level 3*/
-	{0x81, 0x33, INVMASK(0x33)},
-	{0xd8, 0x30, INVMASK(0xff)},
-	{0xd9, 0x30, INVMASK(0xff)},
-	{0xd2, 0x02, INVMASK(0xff)},
-
-};
-
-struct OV7692_WREG ov7692_saturation_default_lv4_tbl[] = {
-	/*Saturation level 4 (default)*/
-	{0x81, 0x33, INVMASK(0x33)},
-	{0xd8, 0x40, INVMASK(0xff)},
-	{0xd9, 0x40, INVMASK(0xff)},
-	{0xd2, 0x02, INVMASK(0xff)},
-};
-
-struct OV7692_WREG ov7692_saturation_lv5_tbl[] = {
-	/*Saturation level 5*/
-	{0x81, 0x33, INVMASK(0x33)},
-	{0xd8, 0x50, INVMASK(0xff)},
-	{0xd9, 0x50, INVMASK(0xff)},
-	{0xd2, 0x02, INVMASK(0xff)},
-};
-
-struct OV7692_WREG ov7692_saturation_lv6_tbl[] = {
-	/*Saturation level 6*/
-	{0x81, 0x33, INVMASK(0x33)},
-	{0xd8, 0x60, INVMASK(0xff)},
-	{0xd9, 0x60, INVMASK(0xff)},
-	{0xd2, 0x02, INVMASK(0xff)},
-};
-
-struct OV7692_WREG ov7692_saturation_lv7_tbl[] = {
-	/*Saturation level 7*/
-	{0x81, 0x33, INVMASK(0x33)},
-	{0xd8, 0x70, INVMASK(0xff)},
-	{0xd9, 0x70, INVMASK(0xff)},
-	{0xd2, 0x02, INVMASK(0xff)},
-};
-
-struct OV7692_WREG ov7692_saturation_lv8_tbl[] = {
-	/*Saturation level 8*/
-	{0x81, 0x33, INVMASK(0x33)},
-	{0xd8, 0x80, INVMASK(0xff)},
-	{0xd9, 0x80, INVMASK(0xff)},
-	{0xd2, 0x02, INVMASK(0xff)},
-};
-
-/*EFFECT*/
-struct OV7692_WREG ov7692_effect_normal_tbl[] = {
-	{0x81, 0x00, INVMASK(0x20)},
-	{0x28, 0x00, },
-	{0xd2, 0x00, },
-	{0xda, 0x80, },
-	{0xdb, 0x80, },
-};
-
-struct OV7692_WREG ov7692_effect_mono_tbl[] = {
-	{0x81, 0x20, INVMASK(0x20)},
-	{0x28, 0x00, },
-	{0xd2, 0x18, },
-	{0xda, 0x80, },
-	{0xdb, 0x80, },
-};
-
-struct OV7692_WREG ov7692_effect_bw_tbl[] = {
-	{0x81, 0x20, INVMASK(0x20)},
-	{0x28, 0x00, },
-	{0xd2, 0x18, },
-	{0xda, 0x80, },
-	{0xdb, 0x80, },
-};
-
-struct OV7692_WREG ov7692_effect_sepia_tbl[] = {
-	{0x81, 0x20, INVMASK(0x20)},
-	{0x28, 0x00, },
-	{0xd2, 0x18, },
-	{0xda, 0x40, },
-	{0xdb, 0xa0, },
-};
-
-struct OV7692_WREG ov7692_effect_bluish_tbl[] = {
-	{0x81, 0x20, INVMASK(0x20)},
-	{0x28, 0x00, },
-	{0xd2, 0x18, },
-	{0xda, 0xc0, },
-	{0xdb, 0x80, },
-};
-
-struct OV7692_WREG ov7692_effect_reddish_tbl[] = {
-	{0x81, 0x20, INVMASK(0x20)},
-	{0x28, 0x00, },
-	{0xd2, 0x18, },
-	{0xda, 0x80, },
-	{0xdb, 0xc0, },
-};
-
-struct OV7692_WREG ov7692_effect_greenish_tbl[] = {
-	{0x81, 0x20, INVMASK(0x20)},
-	{0x28, 0x00, },
-	{0xd2, 0x18, },
-	{0xda, 0x60, },
-	{0xdb, 0x60, },
-};
-
-struct OV7692_WREG ov7692_effect_negative_tbl[] = {
-	{0x81, 0x20, INVMASK(0x20)},
-	{0x28, 0x80, },
-	{0xd2, 0x40, },
-	{0xda, 0x80, },
-	{0xdb, 0x80, },
-};
-
-/*Contrast*/
-struct OV7692_WREG ov7692_contrast_lv0_tbl[] = {
-	/*Contrast -4*/
-	{0xb2, 0x29},
-	{0xa3, 0x55},
-	{0xa4, 0x5b},
-	{0xa5, 0x67},
-	{0xa6, 0x7e},
-	{0xa7, 0x89},
-	{0xa8, 0x93},
-	{0xa9, 0x9c},
-	{0xaa, 0xa4},
-	{0xab, 0xac},
-	{0xac, 0xb3},
-	{0xad, 0xbe},
-	{0xae, 0xc7},
-	{0xaf, 0xd5},
-	{0xb0, 0xdd},
-	{0xb1, 0xe1},
-};
-
-struct OV7692_WREG ov7692_contrast_lv1_tbl[] = {
-	/*Contrast -3*/
-	{0xb2, 0x20},
-	{0xa3, 0x43},
-	{0xa4, 0x4a},
-	{0xa5, 0x58},
-	{0xa6, 0x73},
-	{0xa7, 0x80},
-	{0xa8, 0x8b},
-	{0xa9, 0x96},
-	{0xaa, 0x9f},
-	{0xab, 0xa8},
-	{0xac, 0xb1},
-	{0xad, 0xbe},
-	{0xae, 0xc9},
-	{0xaf, 0xd8},
-	{0xb0, 0xe2},
-	{0xb1, 0xe8},
-};
-
-struct OV7692_WREG ov7692_contrast_lv2_tbl[] = {
-	/*Contrast -2*/
-	{0xb2, 0x18},
-	{0xa3, 0x31},
-	{0xa4, 0x39},
-	{0xa5, 0x4a},
-	{0xa6, 0x68},
-	{0xa7, 0x77},
-	{0xa8, 0x84},
-	{0xa9, 0x90},
-	{0xaa, 0x9b},
-	{0xab, 0xa5},
-	{0xac, 0xaf},
-	{0xad, 0xbe},
-	{0xae, 0xca},
-	{0xaf, 0xdc},
-	{0xb0, 0xe7},
-	{0xb1, 0xee},
-};
-
-struct OV7692_WREG ov7692_contrast_lv3_tbl[] = {
-	/*Contrast -1*/
-	{0xb2, 0x10},
-	{0xa3, 0x1f},
-	{0xa4, 0x28},
-	{0xa5, 0x3b},
-	{0xa6, 0x5d},
-	{0xa7, 0x6e},
-	{0xa8, 0x7d},
-	{0xa9, 0x8a},
-	{0xaa, 0x96},
-	{0xab, 0xa2},
-	{0xac, 0xad},
-	{0xad, 0xbe},
-	{0xae, 0xcc},
-	{0xaf, 0xe0},
-	{0xb0, 0xed},
-	{0xb1, 0xf4},
-};
-
-struct OV7692_WREG ov7692_contrast_default_lv4_tbl[] = {
-	/*Contrast 0*/
-	{0xb2, 0x6},
-	{0xa3, 0xb},
-	{0xa4, 0x15},
-	{0xa5, 0x2a},
-	{0xa6, 0x51},
-	{0xa7, 0x63},
-	{0xa8, 0x74},
-	{0xa9, 0x83},
-	{0xaa, 0x91},
-	{0xab, 0x9e},
-	{0xac, 0xaa},
-	{0xad, 0xbe},
-	{0xae, 0xce},
-	{0xaf, 0xe5},
-	{0xb0, 0xf3},
-	{0xb1, 0xfb},
-};
-
-struct OV7692_WREG ov7692_contrast_lv5_tbl[] = {
-	/*Contrast 1*/
-	{0xb2, 0xc},
-	{0xa3, 0x4},
-	{0xa4, 0xc},
-	{0xa5, 0x1f},
-	{0xa6, 0x45},
-	{0xa7, 0x58},
-	{0xa8, 0x6b},
-	{0xa9, 0x7c},
-	{0xaa, 0x8d},
-	{0xab, 0x9d},
-	{0xac, 0xac},
-	{0xad, 0xc3},
-	{0xae, 0xd2},
-	{0xaf, 0xe8},
-	{0xb0, 0xf2},
-	{0xb1, 0xf7},
-};
-
-struct OV7692_WREG ov7692_contrast_lv6_tbl[] = {
-	/*Contrast 2*/
-	{0xb2, 0x1},
-	{0xa3, 0x2},
-	{0xa4, 0x9},
-	{0xa5, 0x1a},
-	{0xa6, 0x3e},
-	{0xa7, 0x4a},
-	{0xa8, 0x59},
-	{0xa9, 0x6a},
-	{0xaa, 0x79},
-	{0xab, 0x8e},
-	{0xac, 0xa4},
-	{0xad, 0xc1},
-	{0xae, 0xdb},
-	{0xaf, 0xf4},
-	{0xb0, 0xff},
-	{0xb1, 0xff},
-};
-
-struct OV7692_WREG ov7692_contrast_lv7_tbl[] = {
-	/*Contrast 3*/
-	{0xb2, 0xc},
-	{0xa3, 0x4},
-	{0xa4, 0x8},
-	{0xa5, 0x17},
-	{0xa6, 0x27},
-	{0xa7, 0x3d},
-	{0xa8, 0x54},
-	{0xa9, 0x60},
-	{0xaa, 0x77},
-	{0xab, 0x85},
-	{0xac, 0xa4},
-	{0xad, 0xc6},
-	{0xae, 0xd2},
-	{0xaf, 0xe9},
-	{0xb0, 0xf0},
-	{0xb1, 0xf7},
-};
-
-struct OV7692_WREG ov7692_contrast_lv8_tbl[] = {
-	/*Contrast 4*/
-	{0xb2, 0x1},
-	{0xa3, 0x4},
-	{0xa4, 0x4},
-	{0xa5, 0x7},
-	{0xa6, 0xb},
-	{0xa7, 0x17},
-	{0xa8, 0x2a},
-	{0xa9, 0x41},
-	{0xaa, 0x59},
-	{0xab, 0x6b},
-	{0xac, 0x8b},
-	{0xad, 0xb1},
-	{0xae, 0xd2},
-	{0xaf, 0xea},
-	{0xb0, 0xf4},
-	{0xb1, 0xff},
-};
-
-	/*Sharpness*/
-struct OV7692_WREG ov7692_sharpness_lv0_tbl[] = {
-	/*Sharpness 0*/
-	{0xb4, 0x20, INVMASK(0x20)},
-	{0xb6, 0x00, INVMASK(0x1f)},
-};
-struct OV7692_WREG ov7692_sharpness_lv1_tbl[] = {
-	/*Sharpness 1*/
-	{0xb4, 0x20, INVMASK(0x20)},
-	{0xb6, 0x01, INVMASK(0x1f)},
-};
-struct OV7692_WREG ov7692_sharpness_default_lv2_tbl[] = {
-	/*Sharpness Auto (Default)*/
-	{0xb4, 0x00, INVMASK(0x20)},
-	{0xb6, 0x00, INVMASK(0x1f)},
-};
-struct OV7692_WREG ov7692_sharpness_lv3_tbl[] = {
-	/*Sharpness 3*/
-	{0xb4, 0x20, INVMASK(0x20)},
-	{0xb6, 0x66, INVMASK(0x04)},
-};
-struct OV7692_WREG ov7692_sharpness_lv4_tbl[] = {
-	/*Sharpness 4*/
-	{0xb4, 0x20, INVMASK(0x20)},
-	{0xb6, 0x99, INVMASK(0x1f)},
-};
-struct OV7692_WREG ov7692_sharpness_lv5_tbl[] = {
-	/*Sharpness 5*/
-	{0xb4, 0x20, INVMASK(0x20)},
-	{0xb6, 0xcc, INVMASK(0x1f)},
-};
-struct OV7692_WREG ov7692_sharpness_lv6_tbl[] = {
-	/*Sharpness 6*/
-	{0xb4, 0x20, INVMASK(0x20)},
-	{0xb6, 0xff, INVMASK(0x1f)},
-};
-
-	/* ISO TYPE*/
-struct OV7692_WREG ov7692_iso_type_auto[] = {
-	/*@@ISO Auto*/
-	{0x14, 0x20, INVMASK(0x70)},
-};
-
-struct OV7692_WREG ov7692_iso_type_100[] = {
-	/*@@ISO 100*/
-	{0x14, 0x00, INVMASK(0x70)},
-};
-
-struct OV7692_WREG ov7692_iso_type_200[] = {
-	/*@@ISO 200*/
-	{0x14, 0x10, INVMASK(0x70)},
-};
-
-struct OV7692_WREG ov7692_iso_type_400[] = {
-	/*@@ISO 400*/
-	{0x14, 0x20, INVMASK(0x70)},
-};
-
-struct OV7692_WREG ov7692_iso_type_800[] = {
-	/*@@ISO 800*/
-	{0x14, 0x30, INVMASK(0x70)},
-};
-
-struct OV7692_WREG ov7692_iso_type_1600[] = {
-	/*@@ISO 1600*/
-	{0x14, 0x40, INVMASK(0x70)},
-};
-
-	/*Light Mode*/
-struct OV7692_WREG ov7692_wb_def[] = {
-	{0x13, 0xf7},
-	{0x15, 0x00},
-};
-
-struct OV7692_WREG ov7692_wb_custom[] = {
-	{0x13, 0xf5},
-	{0x01, 0x56},
-	{0x02, 0x50},
-	{0x15, 0x00},
-};
-
-struct OV7692_WREG ov7692_wb_inc[] = {
-	{0x13, 0xf5},
-	{0x01, 0x66},
-	{0x02, 0x40},
-	{0x15, 0x00},
-};
-
-struct OV7692_WREG ov7692_wb_daylight[] = {
-	{0x13, 0xf5},
-	{0x01, 0x43},
-	{0x02, 0x5d},
-	{0x15, 0x00},
-};
-
-struct OV7692_WREG ov7692_wb_cloudy[] = {
-	{0x13, 0xf5},
-	{0x01, 0x48},
-	{0x02, 0x63},
-	{0x15, 0x00},
-};
-
-#endif
-
diff --git a/drivers/media/video/msm/ov7692_qrd.c b/drivers/media/video/msm/ov7692_qrd.c
deleted file mode 100644
index d83f28e..0000000
--- a/drivers/media/video/msm/ov7692_qrd.c
+++ /dev/null
@@ -1,1178 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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/delay.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/slab.h>
-#include <media/msm_camera.h>
-#include <mach/camera.h>
-#include <mach/gpio.h>
-#include "ov7692.h"
-
-/*=============================================================
-    SENSOR REGISTER DEFINES
-==============================================================*/
-#define Q8    0x00000100
-
-/* Omnivision8810 product ID register address */
-#define REG_OV7692_MODEL_ID_MSB                       0x0A
-#define REG_OV7692_MODEL_ID_LSB                       0x0B
-
-#define OV7692_MODEL_ID                       0x7692
-/* Omnivision8810 product ID */
-
-/* Time in milisecs for waiting for the sensor to reset */
-#define OV7692_RESET_DELAY_MSECS    66
-#define OV7692_DEFAULT_CLOCK_RATE   24000000
-/* Registers*/
-
-/* Color bar pattern selection */
-#define OV7692_COLOR_BAR_PATTERN_SEL_REG     0x82
-/* Color bar enabling control */
-#define OV7692_COLOR_BAR_ENABLE_REG           0x601
-/* Time in milisecs for waiting for the sensor to reset*/
-#define OV7692_RESET_DELAY_MSECS    66
-
-static int ov7692_pwdn_gpio;
-static int ov7692_reset_gpio;
-
-
-/*============================================================================
-			DATA DECLARATIONS
-============================================================================*/
-
-
-static bool OV7692_CSI_CONFIG;
-/* 816x612, 24MHz MCLK 96MHz PCLK */
-uint32_t OV7692_FULL_SIZE_WIDTH        = 640;
-uint32_t OV7692_FULL_SIZE_HEIGHT       = 480;
-
-uint32_t OV7692_QTR_SIZE_WIDTH         = 640;
-uint32_t OV7692_QTR_SIZE_HEIGHT        = 480;
-
-uint32_t OV7692_HRZ_FULL_BLK_PIXELS    = 16;
-uint32_t OV7692_VER_FULL_BLK_LINES     = 12;
-uint32_t OV7692_HRZ_QTR_BLK_PIXELS     = 16;
-uint32_t OV7692_VER_QTR_BLK_LINES      = 12;
-
-struct ov7692_work_t {
-	struct work_struct work;
-};
-static struct  ov7692_work_t *ov7692_sensorw;
-static struct  i2c_client *ov7692_client;
-struct ov7692_ctrl_t {
-	const struct  msm_camera_sensor_info *sensordata;
-	uint32_t sensormode;
-	uint32_t fps_divider;        /* init to 1 * 0x00000400 */
-	uint32_t pict_fps_divider;    /* init to 1 * 0x00000400 */
-	uint32_t fps;
-	int32_t  curr_lens_pos;
-	uint32_t curr_step_pos;
-	uint32_t my_reg_gain;
-	uint32_t my_reg_line_count;
-	uint32_t total_lines_per_frame;
-	enum ov7692_resolution_t prev_res;
-	enum ov7692_resolution_t pict_res;
-	enum ov7692_resolution_t curr_res;
-	enum ov7692_test_mode_t  set_test;
-	unsigned short imgaddr;
-};
-static struct ov7692_ctrl_t *ov7692_ctrl;
-static DECLARE_WAIT_QUEUE_HEAD(ov7692_wait_queue);
-DEFINE_MUTEX(ov7692_mut);
-static int effect_value;
-static int16_t ov7692_effect = CAMERA_EFFECT_OFF;
-static unsigned int SAT_U = 0x80;
-static unsigned int SAT_V = 0x80;
-
-/*=============================================================*/
-
-static int ov7692_i2c_rxdata(unsigned short saddr,
-		unsigned char *rxdata, int length)
-{
-	struct i2c_msg msgs[] = {
-		{
-			.addr  = saddr,
-			.flags = 0,
-			.len   = 1,
-			.buf   = rxdata,
-		},
-		{
-			.addr  = saddr,
-			.flags = I2C_M_RD,
-			.len   = 1,
-			.buf   = rxdata,
-		},
-	};
-	if (i2c_transfer(ov7692_client->adapter, msgs, 2) < 0) {
-		CDBG("ov7692_i2c_rxdata failed!\n");
-		return -EIO;
-	}
-	return 0;
-}
-static int32_t ov7692_i2c_txdata(unsigned short saddr,
-		unsigned char *txdata, int length)
-{
-	struct i2c_msg msg[] = {
-		{
-			.addr = saddr,
-			.flags = 0,
-			.len = 2,
-			.buf = txdata,
-		},
-	};
-	if (i2c_transfer(ov7692_client->adapter, msg, 1) < 0) {
-		CDBG("ov7692_i2c_txdata faild 0x%x\n", ov7692_client->addr);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int32_t ov7692_i2c_read(uint8_t raddr,
-		uint8_t *rdata, int rlen)
-{
-	int32_t rc = 0;
-	unsigned char buf[1];
-	if (!rdata)
-		return -EIO;
-	memset(buf, 0, sizeof(buf));
-	buf[0] = raddr;
-	rc = ov7692_i2c_rxdata(ov7692_client->addr >> 1, buf, rlen);
-	if (rc < 0) {
-		CDBG("ov7692_i2c_read 0x%x failed!\n", raddr);
-		return rc;
-	}
-	*rdata = buf[0];
-	return rc;
-}
-static int32_t ov7692_i2c_write_b_sensor(uint8_t waddr, uint8_t bdata)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[2];
-
-	memset(buf, 0, sizeof(buf));
-	buf[0] = waddr;
-	buf[1] = bdata;
-	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
-	rc = ov7692_i2c_txdata(ov7692_client->addr >> 1, buf, 2);
-	if (rc < 0)
-		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
-		waddr, bdata);
-
-	return rc;
-}
-
-static int32_t OV7692_WritePRegs(struct OV7692_WREG *pTb, int32_t len)
-{
-	int32_t i, ret = 0;
-	uint8_t regv;
-
-	for (i = 0; i < len; i++) {
-		if (pTb[i].mask == 0) {
-			ov7692_i2c_write_b_sensor(pTb[i].addr, pTb[i].data);
-		} else {
-			ov7692_i2c_read(pTb[i].addr, &regv, 1);
-			regv &= pTb[i].mask;
-			regv |= (pTb[i].data & (~pTb[i].mask));
-			ov7692_i2c_write_b_sensor(pTb[i].addr, regv);
-		}
-	}
-	return ret;
-}
-
-static int32_t ov7692_sensor_setting(int update_type, int rt)
-{
-	int32_t i, array_length;
-	int32_t rc = 0;
-	struct msm_camera_csi_params ov7692_csi_params;
-
-	CDBG("%s: rt = %d\n", __func__, rt);
-
-	switch (update_type) {
-	case REG_INIT:
-		OV7692_CSI_CONFIG = 0;
-		ov7692_i2c_write_b_sensor(0x0e, 0x08);
-		return rc;
-		break;
-	case UPDATE_PERIODIC:
-		if (!OV7692_CSI_CONFIG) {
-			ov7692_csi_params.lane_cnt = 1;
-			ov7692_csi_params.data_format = CSI_8BIT;
-			ov7692_csi_params.lane_assign = 0xe4;
-			ov7692_csi_params.dpcm_scheme = 0;
-			ov7692_csi_params.settle_cnt = 0x14;
-
-			array_length = sizeof(ov7692_init_settings_array) /
-				sizeof(ov7692_init_settings_array[0]);
-			for (i = 0; i < array_length; i++) {
-				rc = ov7692_i2c_write_b_sensor(
-				ov7692_init_settings_array[i].reg_addr,
-				ov7692_init_settings_array[i].reg_val);
-				if (rc < 0)
-					return rc;
-			}
-			usleep_range(10000, 11000);
-			rc = msm_camio_csi_config(&ov7692_csi_params);
-			usleep_range(10000, 11000);
-			ov7692_i2c_write_b_sensor(0x0e, 0x00);
-			OV7692_CSI_CONFIG = 1;
-			msleep(20);
-			return rc;
-		}
-		break;
-	default:
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
-
-static int32_t ov7692_video_config(int mode)
-{
-	int32_t rc = 0;
-	int rt;
-	/* change sensor resolution if needed */
-	rt = RES_PREVIEW;
-
-	CDBG("%s\n", __func__);
-
-	if (ov7692_sensor_setting(UPDATE_PERIODIC, rt) < 0)
-		return rc;
-	ov7692_ctrl->curr_res = ov7692_ctrl->prev_res;
-	ov7692_ctrl->sensormode = mode;
-	return rc;
-}
-
-static int32_t ov7692_set_sensor_mode(int mode,
-		int res)
-{
-	int32_t rc = 0;
-	switch (mode) {
-	case SENSOR_PREVIEW_MODE:
-		rc = ov7692_video_config(mode);
-		break;
-	case SENSOR_SNAPSHOT_MODE:
-	case SENSOR_RAW_SNAPSHOT_MODE:
-		break;
-	default:
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
-
-static int ov7692_set_exposure_compensation(int compensation)
-{
-	long rc = 0;
-
-	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
-	CDBG("--CAMERA-- %s ...exposure_compensation = %d\n",
-		 __func__ , compensation);
-	switch (compensation) {
-	case CAMERA_EXPOSURE_COMPENSATION_LV0:
-		CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV0\n");
-		rc = OV7692Core_WritePREG(
-			ov7692_exposure_compensation_lv0_tbl);
-		break;
-	case CAMERA_EXPOSURE_COMPENSATION_LV1:
-		CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV1\n");
-		rc = OV7692Core_WritePREG(
-			ov7692_exposure_compensation_lv1_tbl);
-		break;
-	case CAMERA_EXPOSURE_COMPENSATION_LV2:
-		CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV2\n");
-		rc = OV7692Core_WritePREG(
-			ov7692_exposure_compensation_lv2_default_tbl);
-		break;
-	case CAMERA_EXPOSURE_COMPENSATION_LV3:
-		CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV3\n");
-		rc = OV7692Core_WritePREG(
-			ov7692_exposure_compensation_lv3_tbl);
-		break;
-	case CAMERA_EXPOSURE_COMPENSATION_LV4:
-		CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV3\n");
-		rc = OV7692Core_WritePREG(
-			ov7692_exposure_compensation_lv4_tbl);
-		break;
-	default:
-		CDBG("--CAMERA--ERROR CAMERA_EXPOSURE_COMPENSATION\n");
-		break;
-	}
-	CDBG("--CAMERA-- %s ...(End)\n", __func__);
-	return rc;
-}
-
-static long ov7692_set_antibanding(int antibanding)
-{
-	long rc = 0;
-
-	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
-	CDBG("--CAMERA-- %s ...antibanding = %d\n", __func__, antibanding);
-	switch (antibanding) {
-	case CAMERA_ANTIBANDING_OFF:
-		CDBG("--CAMERA--CAMERA_ANTIBANDING_OFF\n");
-		break;
-	case CAMERA_ANTIBANDING_60HZ:
-		CDBG("--CAMERA--CAMERA_ANTIBANDING_60HZ\n");
-		rc = OV7692Core_WritePREG(ov7692_antibanding_60z_tbl);
-		break;
-	case CAMERA_ANTIBANDING_50HZ:
-		CDBG("--CAMERA--CAMERA_ANTIBANDING_50HZ\n");
-		rc = OV7692Core_WritePREG(ov7692_antibanding_50z_tbl);
-		break;
-	case CAMERA_ANTIBANDING_AUTO:
-		CDBG("--CAMERA--CAMERA_ANTIBANDING_AUTO\n");
-		rc = OV7692Core_WritePREG(ov7692_antibanding_auto_tbl);
-		break;
-	default:
-		CDBG("--CAMERA--CAMERA_ANTIBANDING_ERROR COMMAND\n");
-		break;
-	}
-	CDBG("--CAMERA-- %s ...(End)\n", __func__);
-	return rc;
-}
-
-static int ov7692_set_saturation(int saturation)
-{
-	long rc = 0;
-
-	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
-	CDBG("--CAMERA-- %s ...saturation = %d\n", __func__ , saturation);
-
-	if (effect_value == CAMERA_EFFECT_OFF) {
-		switch (saturation) {
-		case CAMERA_SATURATION_LV0:
-			CDBG("--CAMERA--CAMERA_SATURATION_LV0\n");
-			rc = OV7692Core_WritePREG(ov7692_saturation_lv0_tbl);
-			break;
-		case CAMERA_SATURATION_LV1:
-			CDBG("--CAMERA--CAMERA_SATURATION_LV1\n");
-			rc = OV7692Core_WritePREG(ov7692_saturation_lv1_tbl);
-			break;
-		case CAMERA_SATURATION_LV2:
-			CDBG("--CAMERA--CAMERA_SATURATION_LV2\n");
-			rc = OV7692Core_WritePREG(ov7692_saturation_lv2_tbl);
-			break;
-		case CAMERA_SATURATION_LV3:
-			CDBG("--CAMERA--CAMERA_SATURATION_LV3\n");
-			rc = OV7692Core_WritePREG(ov7692_saturation_lv3_tbl);
-			break;
-		case CAMERA_SATURATION_LV4:
-			CDBG("--CAMERA--CAMERA_SATURATION_LV4\n");
-			rc = OV7692Core_WritePREG(
-				ov7692_saturation_default_lv4_tbl);
-			break;
-		case CAMERA_SATURATION_LV5:
-			CDBG("--CAMERA--CAMERA_SATURATION_LV5\n");
-			rc = OV7692Core_WritePREG(ov7692_saturation_lv5_tbl);
-			break;
-		case CAMERA_SATURATION_LV6:
-			CDBG("--CAMERA--CAMERA_SATURATION_LV6\n");
-			rc = OV7692Core_WritePREG(ov7692_saturation_lv6_tbl);
-			break;
-		case CAMERA_SATURATION_LV7:
-			CDBG("--CAMERA--CAMERA_SATURATION_LV7\n");
-			rc = OV7692Core_WritePREG(ov7692_saturation_lv7_tbl);
-			break;
-		case CAMERA_SATURATION_LV8:
-			CDBG("--CAMERA--CAMERA_SATURATION_LV8\n");
-			rc = OV7692Core_WritePREG(ov7692_saturation_lv8_tbl);
-			break;
-		default:
-			CDBG("--CAMERA--CAMERA_SATURATION_ERROR COMMAND\n");
-			break;
-		}
-	}
-
-	/*for recover saturation level when change special effect*/
-	switch (saturation) {
-	case CAMERA_SATURATION_LV0:
-		CDBG("--CAMERA--CAMERA_SATURATION_LV0\n");
-		SAT_U = 0x00;
-		SAT_V = 0x00;
-		break;
-	case CAMERA_SATURATION_LV1:
-		CDBG("--CAMERA--CAMERA_SATURATION_LV1\n");
-		SAT_U = 0x10;
-		SAT_V = 0x10;
-		break;
-	case CAMERA_SATURATION_LV2:
-		CDBG("--CAMERA--CAMERA_SATURATION_LV2\n");
-		SAT_U = 0x20;
-		SAT_V = 0x20;
-		break;
-	case CAMERA_SATURATION_LV3:
-		CDBG("--CAMERA--CAMERA_SATURATION_LV3\n");
-		SAT_U = 0x30;
-		SAT_V = 0x30;
-		break;
-	case CAMERA_SATURATION_LV4:
-		CDBG("--CAMERA--CAMERA_SATURATION_LV4\n");
-		SAT_U = 0x40;
-		SAT_V = 0x40;
-		break;
-	case CAMERA_SATURATION_LV5:
-		CDBG("--CAMERA--CAMERA_SATURATION_LV5\n");
-		SAT_U = 0x50;
-		SAT_V = 0x50;
-		break;
-	case CAMERA_SATURATION_LV6:
-		CDBG("--CAMERA--CAMERA_SATURATION_LV6\n");
-		SAT_U = 0x60;
-		SAT_V = 0x60;
-		break;
-	case CAMERA_SATURATION_LV7:
-		CDBG("--CAMERA--CAMERA_SATURATION_LV7\n");
-		SAT_U = 0x70;
-		SAT_V = 0x70;
-		break;
-	case CAMERA_SATURATION_LV8:
-		CDBG("--CAMERA--CAMERA_SATURATION_LV8\n");
-		SAT_U = 0x80;
-		SAT_V = 0x80;
-		break;
-	default:
-		CDBG("--CAMERA--CAMERA_SATURATION_ERROR COMMAND\n");
-		break;
-	}
-	CDBG("--CAMERA-- %s ...(End)\n", __func__);
-	return rc;
-}
-
-static long ov7692_set_effect(int mode, int effect)
-{
-	int rc = 0;
-	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
-
-	switch (mode) {
-	case SENSOR_PREVIEW_MODE:
-		break;
-	case SENSOR_HFR_60FPS_MODE:
-		break;
-	case SENSOR_HFR_90FPS_MODE:
-		/* Context A Special Effects */
-		CDBG("-CAMERA- %s ...SENSOR_PREVIEW_MODE\n", __func__);
-		break;
-	case SENSOR_SNAPSHOT_MODE:
-		/* Context B Special Effects */
-		CDBG("-CAMERA- %s ...SENSOR_SNAPSHOT_MODE\n", __func__);
-		break;
-	default:
-		break;
-	}
-	effect_value = effect;
-	switch (effect) {
-	case CAMERA_EFFECT_OFF: {
-		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_OFF\n", __func__);
-		rc = OV7692Core_WritePREG(ov7692_effect_normal_tbl);
-		/* for recover saturation level
-		 when change special effect*/
-		ov7692_i2c_write_b_sensor(0xda, SAT_U);
-		/* for recover saturation level
-		when change special effect*/
-		ov7692_i2c_write_b_sensor(0xdb, SAT_V);
-		break;
-	}
-	case CAMERA_EFFECT_MONO: {
-		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_MONO\n", __func__);
-		rc = OV7692Core_WritePREG(ov7692_effect_mono_tbl);
-		break;
-	}
-	case CAMERA_EFFECT_BW: {
-		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_BW\n", __func__);
-		rc = OV7692Core_WritePREG(ov7692_effect_bw_tbl);
-		break;
-	}
-	case CAMERA_EFFECT_BLUISH: {
-		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_BLUISH\n", __func__);
-		rc = OV7692Core_WritePREG(ov7692_effect_bluish_tbl);
-		break;
-	}
-	case CAMERA_EFFECT_SOLARIZE: {
-		CDBG("%s ...CAMERA_EFFECT_NEGATIVE(No Support)!\n", __func__);
-		break;
-	}
-	case CAMERA_EFFECT_SEPIA: {
-		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_SEPIA\n", __func__);
-		rc = OV7692Core_WritePREG(ov7692_effect_sepia_tbl);
-		break;
-	}
-	case CAMERA_EFFECT_REDDISH: {
-		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_REDDISH\n", __func__);
-		rc = OV7692Core_WritePREG(ov7692_effect_reddish_tbl);
-		break;
-	}
-	case CAMERA_EFFECT_GREENISH: {
-		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_GREENISH\n", __func__);
-		rc = OV7692Core_WritePREG(ov7692_effect_greenish_tbl);
-		break;
-	}
-	case CAMERA_EFFECT_NEGATIVE: {
-		CDBG("--CAMERA-- %s ...CAMERA_EFFECT_NEGATIVE\n", __func__);
-		rc = OV7692Core_WritePREG(ov7692_effect_negative_tbl);
-		break;
-	}
-	default: {
-		CDBG("--CAMERA-- %s ...Default(Not Support)\n", __func__);
-	}
-	}
-	ov7692_effect = effect;
-	/*Refresh Sequencer */
-	CDBG("--CAMERA-- %s ...(End)\n", __func__);
-	return rc;
-}
-
-static int ov7692_set_contrast(int contrast)
-{
-	int rc = 0;
-	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
-	CDBG("--CAMERA-- %s ...contrast = %d\n", __func__ , contrast);
-
-	if (effect_value == CAMERA_EFFECT_OFF) {
-		switch (contrast) {
-		case CAMERA_CONTRAST_LV0:
-			CDBG("--CAMERA--CAMERA_CONTRAST_LV0\n");
-			rc = OV7692Core_WritePREG(ov7692_contrast_lv0_tbl);
-			break;
-		case CAMERA_CONTRAST_LV1:
-			CDBG("--CAMERA--CAMERA_CONTRAST_LV1\n");
-			rc = OV7692Core_WritePREG(ov7692_contrast_lv1_tbl);
-			break;
-		case CAMERA_CONTRAST_LV2:
-			CDBG("--CAMERA--CAMERA_CONTRAST_LV2\n");
-			rc = OV7692Core_WritePREG(ov7692_contrast_lv2_tbl);
-			break;
-		case CAMERA_CONTRAST_LV3:
-			CDBG("--CAMERA--CAMERA_CONTRAST_LV3\n");
-			rc = OV7692Core_WritePREG(ov7692_contrast_lv3_tbl);
-			break;
-		case CAMERA_CONTRAST_LV4:
-			CDBG("--CAMERA--CAMERA_CONTRAST_LV4\n");
-			rc = OV7692Core_WritePREG(
-				ov7692_contrast_default_lv4_tbl);
-			break;
-		case CAMERA_CONTRAST_LV5:
-			CDBG("--CAMERA--CAMERA_CONTRAST_LV5\n");
-			rc = OV7692Core_WritePREG(ov7692_contrast_lv5_tbl);
-			break;
-		case CAMERA_CONTRAST_LV6:
-			CDBG("--CAMERA--CAMERA_CONTRAST_LV6\n");
-			rc = OV7692Core_WritePREG(ov7692_contrast_lv6_tbl);
-			break;
-		case CAMERA_CONTRAST_LV7:
-			CDBG("--CAMERA--CAMERA_CONTRAST_LV7\n");
-			rc = OV7692Core_WritePREG(ov7692_contrast_lv7_tbl);
-			break;
-		case CAMERA_CONTRAST_LV8:
-			CDBG("--CAMERA--CAMERA_CONTRAST_LV8\n");
-			rc = OV7692Core_WritePREG(ov7692_contrast_lv8_tbl);
-			break;
-		default:
-			CDBG("--CAMERA--CAMERA_CONTRAST_ERROR COMMAND\n");
-			break;
-		}
-	}
-	CDBG("--CAMERA-- %s ...(End)\n", __func__);
-	return rc;
-}
-
-static int ov7692_set_sharpness(int sharpness)
-{
-	int rc = 0;
-	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
-	CDBG("--CAMERA-- %s ...sharpness = %d\n", __func__ , sharpness);
-
-	if (effect_value == CAMERA_EFFECT_OFF) {
-		switch (sharpness) {
-		case CAMERA_SHARPNESS_LV0:
-			CDBG("--CAMERA--CAMERA_SHARPNESS_LV0\n");
-			rc = OV7692Core_WritePREG(ov7692_sharpness_lv0_tbl);
-			break;
-		case CAMERA_SHARPNESS_LV1:
-			CDBG("--CAMERA--CAMERA_SHARPNESS_LV1\n");
-			rc = OV7692Core_WritePREG(ov7692_sharpness_lv1_tbl);
-			break;
-		case CAMERA_SHARPNESS_LV2:
-			CDBG("--CAMERA--CAMERA_SHARPNESS_LV2\n");
-			rc = OV7692Core_WritePREG(
-				ov7692_sharpness_default_lv2_tbl);
-			break;
-		case CAMERA_SHARPNESS_LV3:
-			CDBG("--CAMERA--CAMERA_SHARPNESS_LV3\n");
-			rc = OV7692Core_WritePREG(ov7692_sharpness_lv3_tbl);
-			break;
-		case CAMERA_SHARPNESS_LV4:
-			CDBG("--CAMERA--CAMERA_SHARPNESS_LV4\n");
-			rc = OV7692Core_WritePREG(ov7692_sharpness_lv4_tbl);
-			break;
-		case CAMERA_SHARPNESS_LV5:
-			CDBG("--CAMERA--CAMERA_SHARPNESS_LV5\n");
-			rc = OV7692Core_WritePREG(ov7692_sharpness_lv5_tbl);
-			break;
-		case CAMERA_SHARPNESS_LV6:
-			CDBG("--CAMERA--CAMERA_SHARPNESS_LV6\n");
-			rc = OV7692Core_WritePREG(ov7692_sharpness_lv6_tbl);
-			break;
-		default:
-			CDBG("--CAMERA--CAMERA_SHARPNESS_ERROR COMMAND\n");
-			break;
-		}
-	}
-	CDBG("--CAMERA-- %s ...(End)\n", __func__);
-	return rc;
-}
-
-static int ov7692_set_iso(int8_t iso_type)
-{
-	long rc = 0;
-
-	CDBG("--CAMERA-- %s ...(Start)\n", __func__);
-	CDBG("--CAMERA-- %s ...iso_type = %d\n", __func__ , iso_type);
-	switch (iso_type) {
-	case CAMERA_ISO_TYPE_AUTO:
-		CDBG("--CAMERA--CAMERA_ISO_TYPE_AUTO\n");
-		rc = OV7692Core_WritePREG(ov7692_iso_type_auto);
-		break;
-	case CAMEAR_ISO_TYPE_HJR:
-		CDBG("--CAMERA--CAMEAR_ISO_TYPE_HJR\n");
-		rc = OV7692Core_WritePREG(ov7692_iso_type_auto);
-		break;
-	case CAMEAR_ISO_TYPE_100:
-		CDBG("--CAMERA--CAMEAR_ISO_TYPE_100\n");
-		rc = OV7692Core_WritePREG(ov7692_iso_type_100);
-		break;
-	case CAMERA_ISO_TYPE_200:
-		CDBG("--CAMERA--CAMERA_ISO_TYPE_200\n");
-		rc = OV7692Core_WritePREG(ov7692_iso_type_200);
-		break;
-	case CAMERA_ISO_TYPE_400:
-		CDBG("--CAMERA--CAMERA_ISO_TYPE_400\n");
-		rc = OV7692Core_WritePREG(ov7692_iso_type_400);
-		break;
-	case CAMEAR_ISO_TYPE_800:
-		CDBG("--CAMERA--CAMEAR_ISO_TYPE_800\n");
-		rc = OV7692Core_WritePREG(ov7692_iso_type_800);
-		break;
-	case CAMERA_ISO_TYPE_1600:
-		CDBG("--CAMERA--CAMERA_ISO_TYPE_1600\n");
-		rc = OV7692Core_WritePREG(ov7692_iso_type_1600);
-		break;
-	default:
-		CDBG("--CAMERA--ERROR ISO TYPE\n");
-		break;
-	}
-	CDBG("--CAMERA-- %s ...(End)\n", __func__);
-	return rc;
-}
-
-static int ov7692_set_wb_oem(uint8_t param)
-{
-	int rc = 0;
-	CDBG("--CAMERA--%s runs\r\n", __func__);
-
-	switch (param) {
-	case CAMERA_WB_AUTO:
-		CDBG("--CAMERA--CAMERA_WB_AUTO\n");
-		rc = OV7692Core_WritePREG(ov7692_wb_def);
-		break;
-	case CAMERA_WB_CUSTOM:
-		CDBG("--CAMERA--CAMERA_WB_CUSTOM\n");
-		rc = OV7692Core_WritePREG(ov7692_wb_custom);
-		break;
-	case CAMERA_WB_INCANDESCENT:
-		CDBG("--CAMERA--CAMERA_WB_INCANDESCENT\n");
-		rc = OV7692Core_WritePREG(ov7692_wb_inc);
-		break;
-	case CAMERA_WB_DAYLIGHT:
-		CDBG("--CAMERA--CAMERA_WB_DAYLIGHT\n");
-		rc = OV7692Core_WritePREG(ov7692_wb_daylight);
-		break;
-	case CAMERA_WB_CLOUDY_DAYLIGHT:
-		CDBG("--CAMERA--CAMERA_WB_CLOUDY_DAYLIGHT\n");
-		rc = OV7692Core_WritePREG(ov7692_wb_cloudy);
-		break;
-	default:
-		break;
-	}
-	return rc;
-}
-
-static void ov7692_power_on(void)
-{
-	CDBG("%s\n", __func__);
-	gpio_set_value(ov7692_pwdn_gpio, 0);
-}
-
-static void ov7692_power_down(void)
-{
-	CDBG("%s\n", __func__);
-	gpio_set_value(ov7692_pwdn_gpio, 1);
-}
-
-static void ov7692_sw_reset(void)
-{
-	CDBG("%s\n", __func__);
-	ov7692_i2c_write_b_sensor(0x12, 0x80);
-}
-
-static void ov7692_hw_reset(void)
-{
-	CDBG("--CAMERA-- %s ... (Start...)\n", __func__);
-	gpio_set_value(ov7692_reset_gpio, 1);   /*reset camera reset pin*/
-	usleep_range(5000, 5100);
-	gpio_set_value(ov7692_reset_gpio, 0);
-	usleep_range(5000, 5100);
-	gpio_set_value(ov7692_reset_gpio, 1);
-	usleep_range(1000, 1100);
-	CDBG("--CAMERA-- %s ... (End...)\n", __func__);
-}
-
-
-
-static int ov7692_probe_init_sensor(const struct msm_camera_sensor_info *data)
-{
-	uint8_t model_id_msb, model_id_lsb = 0;
-	uint16_t model_id = 0;
-	int32_t rc = 0;
-	/*The reset pin is not physically connected to the sensor.
-	  The standby pin will do the reset hence there is no need
-	  to request the gpio reset*/
-
-	/* Read sensor Model ID: */
-	rc = ov7692_i2c_read(REG_OV7692_MODEL_ID_MSB, &model_id_msb, 1);
-	if (rc < 0)
-		goto init_probe_fail;
-	rc = ov7692_i2c_read(REG_OV7692_MODEL_ID_LSB, &model_id_lsb, 1);
-	if (rc < 0)
-		goto init_probe_fail;
-	model_id = (model_id_msb << 8) | ((model_id_lsb & 0x00FF)) ;
-	CDBG("ov7692 model_id = 0x%x, 0x%x, 0x%x\n",
-			model_id, model_id_msb, model_id_lsb);
-	/* 4. Compare sensor ID to OV7692 ID: */
-	if (model_id != OV7692_MODEL_ID) {
-		rc = -ENODEV;
-		goto init_probe_fail;
-	}
-	goto init_probe_done;
-init_probe_fail:
-	pr_warning(" ov7692_probe_init_sensor fails\n");
-init_probe_done:
-	CDBG(" ov7692_probe_init_sensor finishes\n");
-	return rc;
-}
-
-int ov7692_sensor_open_init(const struct msm_camera_sensor_info *data)
-{
-	int32_t rc = 0;
-
-	CDBG("%s: %d\n", __func__, __LINE__);
-	CDBG("Calling ov7692_sensor_open_init\n");
-	ov7692_ctrl = kzalloc(sizeof(struct ov7692_ctrl_t), GFP_KERNEL);
-	if (!ov7692_ctrl) {
-		CDBG("ov7692_init failed!\n");
-		rc = -ENOMEM;
-		goto init_done;
-	}
-	ov7692_ctrl->fps_divider = 1 * 0x00000400;
-	ov7692_ctrl->pict_fps_divider = 1 * 0x00000400;
-	ov7692_ctrl->fps = 30 * Q8;
-	ov7692_ctrl->set_test = TEST_OFF;
-	ov7692_ctrl->prev_res = QTR_SIZE;
-	ov7692_ctrl->pict_res = FULL_SIZE;
-	ov7692_ctrl->curr_res = INVALID_SIZE;
-
-	if (data)
-		ov7692_ctrl->sensordata = data;
-	/* turn on LDO for PVT */
-	if (data->pmic_gpio_enable)
-		lcd_camera_power_onoff(1);
-
-	/* enable mclk first */
-
-	msm_camio_clk_rate_set(24000000);
-	msleep(20);
-
-	ov7692_power_on();
-	usleep_range(5000, 5100);
-
-	rc = ov7692_probe_init_sensor(data);
-	if (rc < 0) {
-		CDBG("Calling ov7692_sensor_open_init fail\n");
-		goto init_fail;
-	}
-
-	rc = ov7692_sensor_setting(REG_INIT, RES_PREVIEW);
-	if (rc < 0)
-		goto init_fail;
-	else
-		goto init_done;
-
-init_fail:
-	CDBG(" ov7692_sensor_open_init fail\n");
-	if (data->pmic_gpio_enable)
-		lcd_camera_power_onoff(0);
-	kfree(ov7692_ctrl);
-init_done:
-	CDBG("ov7692_sensor_open_init done\n");
-	return rc;
-}
-
-static int ov7692_init_client(struct i2c_client *client)
-{
-	/* Initialize the MSM_CAMI2C Chip */
-	init_waitqueue_head(&ov7692_wait_queue);
-	return 0;
-}
-
-static const struct i2c_device_id ov7692_i2c_id[] = {
-	{"ov7692", 0},
-	{ }
-};
-
-static int ov7692_i2c_probe(struct i2c_client *client,
-		const struct i2c_device_id *id)
-{
-	int rc = 0;
-	CDBG("ov7692_i2c_probe called!\n");
-
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		CDBG("i2c_check_functionality failed\n");
-		goto probe_failure;
-	}
-
-	ov7692_sensorw = kzalloc(sizeof(struct ov7692_work_t), GFP_KERNEL);
-	if (!ov7692_sensorw) {
-		CDBG("kzalloc failed.\n");
-		rc = -ENOMEM;
-		goto probe_failure;
-	}
-
-	i2c_set_clientdata(client, ov7692_sensorw);
-	ov7692_init_client(client);
-	ov7692_client = client;
-
-	CDBG("ov7692_i2c_probe success! rc = %d\n", rc);
-	return 0;
-
-probe_failure:
-	CDBG("ov7692_i2c_probe failed! rc = %d\n", rc);
-	return rc;
-}
-
-static int __exit ov7692_remove(struct i2c_client *client)
-{
-	struct ov7692_work_t_t *sensorw = i2c_get_clientdata(client);
-	free_irq(client->irq, sensorw);
-	ov7692_client = NULL;
-	kfree(sensorw);
-	return 0;
-}
-
-static struct i2c_driver ov7692_i2c_driver = {
-	.id_table = ov7692_i2c_id,
-	.probe  = ov7692_i2c_probe,
-	.remove = __exit_p(ov7692_i2c_remove),
-	.driver = {
-		.name = "ov7692",
-	},
-};
-
-int ov7692_sensor_config(void __user *argp)
-{
-	struct sensor_cfg_data cdata;
-	long   rc = 0;
-	if (copy_from_user(&cdata,
-				(void *)argp,
-				sizeof(struct sensor_cfg_data)))
-		return -EFAULT;
-	mutex_lock(&ov7692_mut);
-	CDBG("ov7692_sensor_config: cfgtype = %d\n", cdata.cfgtype);
-	switch (cdata.cfgtype) {
-	case CFG_SET_MODE:
-		rc = ov7692_set_sensor_mode(cdata.mode, cdata.rs);
-		break;
-	case CFG_SET_EFFECT:
-		CDBG("--CAMERA-- CFG_SET_EFFECT mode=%d, effect = %d !!\n",
-			 cdata.mode, cdata.cfg.effect);
-		rc = ov7692_set_effect(cdata.mode, cdata.cfg.effect);
-		break;
-	case CFG_START:
-		CDBG("--CAMERA-- CFG_START (Not Support) !!\n");
-		/* Not Support */
-		break;
-	case CFG_PWR_UP:
-		CDBG("--CAMERA-- CFG_PWR_UP (Not Support) !!\n");
-		/* Not Support */
-		break;
-	case CFG_PWR_DOWN:
-		CDBG("--CAMERA-- CFG_PWR_DOWN !!\n");
-		ov7692_power_down();
-		break;
-	case CFG_WRITE_EXPOSURE_GAIN:
-		CDBG("--CAMERA-- CFG_WRITE_EXPOSURE_GAIN (Not Support) !!\n");
-		/* Not Support */
-		break;
-	case CFG_SET_DEFAULT_FOCUS:
-		CDBG("--CAMERA-- CFG_SET_DEFAULT_FOCUS (Not Implement) !!\n");
-		break;
-	case CFG_MOVE_FOCUS:
-		CDBG("--CAMERA-- CFG_MOVE_FOCUS (Not Implement) !!\n");
-		break;
-	case CFG_REGISTER_TO_REAL_GAIN:
-		CDBG("--CAMERA-- CFG_REGISTER_TO_REAL_GAIN (Not Support) !!\n");
-		/* Not Support */
-		break;
-	case CFG_REAL_TO_REGISTER_GAIN:
-		CDBG("--CAMERA-- CFG_REAL_TO_REGISTER_GAIN (Not Support) !!\n");
-		/* Not Support */
-		break;
-	case CFG_SET_FPS:
-		CDBG("--CAMERA-- CFG_SET_FPS (Not Support) !!\n");
-		/* Not Support */
-		break;
-	case CFG_SET_PICT_FPS:
-		CDBG("--CAMERA-- CFG_SET_PICT_FPS (Not Support) !!\n");
-		/* Not Support */
-		break;
-	case CFG_SET_BRIGHTNESS:
-		CDBG("--CAMERA-- CFG_SET_BRIGHTNESS  !!\n");
-		/* rc = ov7692_set_brightness(cdata.cfg.brightness); */
-		break;
-	case CFG_SET_CONTRAST:
-		CDBG("--CAMERA-- CFG_SET_CONTRAST  !!\n");
-		rc = ov7692_set_contrast(cdata.cfg.contrast);
-		break;
-	case CFG_SET_ZOOM:
-		CDBG("--CAMERA-- CFG_SET_ZOOM (Not Support) !!\n");
-		/* Not Support */
-		break;
-	case CFG_SET_EXPOSURE_MODE:
-		CDBG("--CAMERA-- CFG_SET_EXPOSURE_MODE !!\n");
-		/* rc = ov7692_set_exposure_mode(cdata.cfg.ae_mode); */
-		break;
-	case CFG_SET_WB:
-		CDBG("--CAMERA-- CFG_SET_WB!!\n");
-		ov7692_set_wb_oem(cdata.cfg.wb_val);
-		rc = 0 ;
-		break;
-	case CFG_SET_ANTIBANDING:
-		CDBG("--CAMERA-- CFG_SET_ANTIBANDING antibanding = %d !!\n",
-			 cdata.cfg.antibanding);
-		rc = ov7692_set_antibanding(cdata.cfg.antibanding);
-		break;
-	case CFG_SET_EXP_GAIN:
-		CDBG("--CAMERA-- CFG_SET_EXP_GAIN (Not Support) !!\n");
-		/* Not Support */
-		break;
-	case CFG_SET_PICT_EXP_GAIN:
-		CDBG("--CAMERA-- CFG_SET_PICT_EXP_GAIN (Not Support) !!\n");
-		/* Not Support */
-		break;
-	case CFG_SET_LENS_SHADING:
-		CDBG("--CAMERA-- CFG_SET_LENS_SHADING !!\n");
-		/* rc = ov7692_lens_shading_enable(cdata.cfg.lens_shading); */
-		break;
-	case CFG_GET_PICT_FPS:
-		CDBG("--CAMERA-- CFG_GET_PICT_FPS (Not Support) !!\n");
-		/* Not Support */
-		break;
-	case CFG_GET_PREV_L_PF:
-		CDBG("--CAMERA-- CFG_GET_PREV_L_PF (Not Support) !!\n");
-		/* Not Support */
-		break;
-	case CFG_GET_PREV_P_PL:
-		CDBG("--CAMERA-- CFG_GET_PREV_P_PL (Not Support) !!\n");
-		/* Not Support */
-		break;
-	case CFG_GET_PICT_L_PF:
-		CDBG("--CAMERA-- CFG_GET_PICT_L_PF (Not Support) !!\n");
-		/* Not Support */
-		break;
-	case CFG_GET_PICT_P_PL:
-		CDBG("--CAMERA-- CFG_GET_PICT_P_PL (Not Support) !!\n");
-		/* Not Support */
-		break;
-	case CFG_GET_AF_MAX_STEPS:
-		CDBG("--CAMERA-- CFG_GET_AF_MAX_STEPS (Not Support) !!\n");
-		/* Not Support */
-		break;
-	case CFG_GET_PICT_MAX_EXP_LC:
-		CDBG("--CAMERA-- CFG_GET_PICT_MAX_EXP_LC (Not Support) !!\n");
-		/* Not Support */
-		break;
-	case CFG_SEND_WB_INFO:
-		CDBG("--CAMERA-- CFG_SEND_WB_INFO (Not Support) !!\n");
-		/* Not Support */
-		break;
-	case CFG_SENSOR_INIT:
-		CDBG("--CAMERA-- CFG_SENSOR_INIT (Not Support) !!\n");
-		/* Not Support */
-		break;
-	case CFG_SET_SATURATION:
-		CDBG("--CAMERA-- CFG_SET_SATURATION !!\n");
-		rc = ov7692_set_saturation(cdata.cfg.saturation);
-		break;
-	case CFG_SET_SHARPNESS:
-		CDBG("--CAMERA-- CFG_SET_SHARPNESS !!\n");
-		rc = ov7692_set_sharpness(cdata.cfg.sharpness);
-		break;
-	case CFG_SET_TOUCHAEC:
-		CDBG("--CAMERA-- CFG_SET_TOUCHAEC!!\n");
-		/* ov7692_set_touchaec(cdata.cfg.aec_cord.x,
-			 cdata.cfg.aec_cord.y); */
-		rc = 0 ;
-		break;
-	case CFG_SET_AUTO_FOCUS:
-		CDBG("--CAMERA-- CFG_SET_AUTO_FOCUS (Not Support) !!\n");
-		/* Not Support */
-		break;
-	case CFG_SET_AUTOFLASH:
-		CDBG("--CAMERA-- CFG_SET_AUTOFLASH (Not Support) !!\n");
-		/* Not Support */
-		break;
-	case CFG_SET_EXPOSURE_COMPENSATION:
-		CDBG("--CAMERA-- CFG_SET_EXPOSURE_COMPENSATION !\n");
-		rc = ov7692_set_exposure_compensation(
-			cdata.cfg.exp_compensation);
-		break;
-	case CFG_SET_ISO:
-		CDBG("--CAMERA-- CFG_SET_ISO !\n");
-		rc = ov7692_set_iso(cdata.cfg.iso_type);
-		break;
-	default:
-		CDBG("--CAMERA-- %s: Command=%d (Not Implement) !!\n",
-			 __func__, cdata.cfgtype);
-		rc = -EINVAL;
-		break;
-	}
-
-	mutex_unlock(&ov7692_mut);
-
-	return rc;
-}
-static int ov7692_sensor_release(void)
-{
-	int rc = -EBADF;
-
-	mutex_lock(&ov7692_mut);
-	ov7692_sw_reset();
-	ov7692_power_down();
-	kfree(ov7692_ctrl);
-	ov7692_ctrl = NULL;
-	CDBG("ov7692_release completed\n");
-	mutex_unlock(&ov7692_mut);
-
-	return rc;
-}
-
-static int ov7692_probe_init_gpio(const struct msm_camera_sensor_info *data)
-{
-	int rc = 0;
-
-	ov7692_pwdn_gpio = data->sensor_pwd;
-	ov7692_reset_gpio = data->sensor_reset ;
-
-	if (data->sensor_reset_enable)
-		gpio_direction_output(data->sensor_reset, 1);
-
-	gpio_direction_output(data->sensor_pwd, 1);
-
-	return rc;
-
-}
-
-
-static int ov7692_sensor_probe(const struct msm_camera_sensor_info *info,
-		struct msm_sensor_ctrl *s)
-{
-	int rc = 0;
-	rc = i2c_add_driver(&ov7692_i2c_driver);
-	if (rc < 0 || ov7692_client == NULL) {
-		rc = -ENOTSUPP;
-		goto probe_fail;
-	}
-	pr_debug("%s: %d Entered\n", __func__, __LINE__);
-	rc = ov7692_probe_init_gpio(info);
-	if (rc < 0) {
-		CDBG("%s: gpio init failed\n", __func__);
-		goto probe_fail;
-	}
-	/* turn on LDO for PVT */
-	if (info->pmic_gpio_enable)
-		lcd_camera_power_onoff(1);
-
-	ov7692_power_down();
-
-	msm_camio_clk_rate_set(24000000);
-	usleep_range(5000, 5100);
-
-	ov7692_power_on();
-	usleep_range(5000, 5100);
-
-	if (info->sensor_reset_enable)
-		ov7692_hw_reset();
-	else
-		ov7692_sw_reset();
-
-	rc = ov7692_probe_init_sensor(info);
-	if (rc < 0)
-		goto probe_fail;
-
-
-	s->s_init = ov7692_sensor_open_init;
-	s->s_release = ov7692_sensor_release;
-	s->s_config  = ov7692_sensor_config;
-	s->s_camera_type = FRONT_CAMERA_2D;
-	s->s_mount_angle = info->sensor_platform_info->mount_angle;
-
-	/* ov7692_sw_reset(); */
-	ov7692_power_down();
-
-	if (info->pmic_gpio_enable)
-		lcd_camera_power_onoff(0);
-
-	return rc;
-
-probe_fail:
-	CDBG("ov7692_sensor_probe: SENSOR PROBE FAILS!\n");
-	if (info->pmic_gpio_enable)
-		lcd_camera_power_onoff(0);
-	i2c_del_driver(&ov7692_i2c_driver);
-	return rc;
-}
-
-static int __ov7692_probe(struct platform_device *pdev)
-{
-	return msm_camera_drv_start(pdev, ov7692_sensor_probe);
-}
-
-static struct platform_driver msm_camera_driver = {
-	.probe = __ov7692_probe,
-	.driver = {
-		.name = "msm_camera_ov7692",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init ov7692_init(void)
-{
-	return platform_driver_register(&msm_camera_driver);
-}
-
-module_init(ov7692_init);
-
-MODULE_DESCRIPTION("OMNI VGA YUV sensor driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/ov9726.c b/drivers/media/video/msm/ov9726.c
deleted file mode 100644
index 9619baa..0000000
--- a/drivers/media/video/msm/ov9726.c
+++ /dev/null
@@ -1,794 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. 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/delay.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/slab.h>
-#include <media/msm_camera.h>
-#include <mach/gpio.h>
-#include <mach/camera.h>
-#include "ov9726.h"
-
-/*=============================================================
-	SENSOR REGISTER DEFINES
-==============================================================*/
-#define OV9726_Q8				0x00000100
-#define OV9726_Q8Shift				8
-#define OV9726_Q10				0x00000400
-#define OV9726_Q10Shift				10
-
-/* Omnivision8810 product ID register address */
-#define	OV9726_PIDH_REG				0x0000
-#define	OV9726_PIDL_REG				0x0001
-/* Omnivision8810 product ID */
-#define	OV9726_PID				0x97
-/* Omnivision8810 version */
-#define	OV9726_VER				0x26
-/* Time in milisecs for waiting for the sensor to reset */
-#define	OV9726_RESET_DELAY_MSECS		66
-#define	OV9726_DEFAULT_CLOCK_RATE		24000000
-/* Registers*/
-#define	OV9726_GAIN				0x3000
-#define	OV9726_AEC_MSB				0x3002
-#define	OV9726_AEC_LSB				0x3003
-
-/* Color bar pattern selection */
-#define OV9726_COLOR_BAR_PATTERN_SEL_REG	0x600
-/* Color bar enabling control */
-#define OV9726_COLOR_BAR_ENABLE_REG		0x601
-/* Time in milisecs for waiting for the sensor to reset*/
-#define OV9726_RESET_DELAY_MSECS		66
-/* I2C Address of the Sensor */
-/*============================================================================
-		DATA DECLARATIONS
-============================================================================*/
-#define OV9726_FULL_SIZE_DUMMY_PIXELS		0
-#define OV9726_FULL_SIZE_DUMMY_LINES		0
-#define OV9726_QTR_SIZE_DUMMY_PIXELS		0
-#define OV9726_QTR_SIZE_DUMMY_LINES		0
-
-#define OV9726_FULL_SIZE_WIDTH			1296
-#define OV9726_FULL_SIZE_HEIGHT			808
-
-#define OV9726_QTR_SIZE_WIDTH			1296
-#define OV9726_QTR_SIZE_HEIGHT			808
-
-#define OV9726_HRZ_FULL_BLK_PIXELS		368
-#define OV9726_VER_FULL_BLK_LINES		32
-#define OV9726_HRZ_QTR_BLK_PIXELS		368
-#define OV9726_VER_QTR_BLK_LINES		32
-
-#define OV9726_MSB_MASK			0xFF00
-#define OV9726_LSB_MASK			0x00FF
-
-struct ov9726_work_t {
-	struct work_struct work;
-};
-static struct ov9726_work_t *ov9726_sensorw;
-static struct i2c_client *ov9726_client;
-struct ov9726_ctrl_t {
-	const struct  msm_camera_sensor_info *sensordata;
-	uint32_t sensormode;
-	uint32_t fps_divider;		/* init to 1 * 0x00000400 */
-	uint32_t pict_fps_divider;	/* init to 1 * 0x00000400 */
-	uint16_t fps;
-	int16_t curr_lens_pos;
-	uint16_t curr_step_pos;
-	uint16_t my_reg_gain;
-	uint32_t my_reg_line_count;
-	uint16_t total_lines_per_frame;
-	enum ov9726_resolution_t prev_res;
-	enum ov9726_resolution_t pict_res;
-	enum ov9726_resolution_t curr_res;
-	enum ov9726_test_mode_t  set_test;
-	unsigned short imgaddr;
-};
-static struct ov9726_ctrl_t *ov9726_ctrl;
-static int8_t config_not_set = 1;
-static DECLARE_WAIT_QUEUE_HEAD(ov9726_wait_queue);
-DEFINE_MUTEX(ov9726_mut);
-
-/*=============================================================*/
-static int ov9726_i2c_rxdata(unsigned short saddr,
-	unsigned char *rxdata, int length)
-{
-	struct i2c_msg msgs[] = {
-	{
-		.addr  = saddr,
-		.flags = 0,
-		.len   = 2,
-		.buf   = rxdata,
-	},
-	{
-		.addr  = saddr,
-		.flags = I2C_M_RD,
-		.len   = length,
-		.buf   = rxdata,
-	},
-	};
-
-	if (i2c_transfer(ov9726_client->adapter, msgs, 2) < 0) {
-		CDBG("ov9726_i2c_rxdata failed!\n");
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int32_t ov9726_i2c_txdata(unsigned short saddr,
-				unsigned char *txdata, int length)
-{
-	struct i2c_msg msg[] = {
-		{
-		 .addr = saddr ,
-		 .flags = 0,
-		 .len = length,
-		 .buf = txdata,
-		 },
-	};
-
-	if (i2c_transfer(ov9726_client->adapter, msg, 1) < 0) {
-		CDBG("ov9726_i2c_txdata faild 0x%x\n", ov9726_client->addr);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int32_t ov9726_i2c_read(unsigned short raddr,
-				unsigned short *rdata, int rlen)
-{
-	int32_t rc = 0;
-	unsigned char buf[2];
-
-	if (!rdata)
-		return -EIO;
-
-	buf[0] = (raddr & OV9726_MSB_MASK) >> 8;
-	buf[1] = (raddr & OV9726_LSB_MASK);
-
-	rc = ov9726_i2c_rxdata(ov9726_client->addr, buf, rlen);
-
-	if (rc < 0) {
-		CDBG("ov9726_i2c_read 0x%x failed!\n", raddr);
-		return rc;
-	}
-
-	*rdata = (rlen == 2 ? buf[0] << 8 | buf[1] : buf[0]);
-	return rc;
-}
-
-static int32_t ov9726_i2c_write_b(unsigned short saddr,
-	unsigned short waddr, uint8_t bdata)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[3];
-
-	buf[0] = (waddr & OV9726_MSB_MASK) >> 8;
-	buf[1] = (waddr & OV9726_LSB_MASK);
-	buf[2] = bdata;
-
-	CDBG("i2c_write_b addr = 0x%x, val = 0x%xd\n", waddr, bdata);
-	rc = ov9726_i2c_txdata(saddr, buf, 3);
-
-	if (rc < 0) {
-		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
-			 waddr, bdata);
-	}
-
-	return rc;
-}
-
-static void ov9726_get_pict_fps(uint16_t fps, uint16_t *pfps)
-{
-	uint32_t divider;	/*Q10 */
-	uint32_t d1;
-	uint32_t d2;
-	uint16_t snapshot_height, preview_height, preview_width, snapshot_width;
-	if (ov9726_ctrl->prev_res == QTR_SIZE) {
-		preview_width = OV9726_QTR_SIZE_WIDTH +
-			OV9726_HRZ_QTR_BLK_PIXELS ;
-		preview_height = OV9726_QTR_SIZE_HEIGHT +
-			OV9726_VER_QTR_BLK_LINES ;
-	} else {
-		/* full size resolution used for preview. */
-		preview_width = OV9726_FULL_SIZE_WIDTH +
-			OV9726_HRZ_FULL_BLK_PIXELS ;
-		preview_height = OV9726_FULL_SIZE_HEIGHT +
-			OV9726_VER_FULL_BLK_LINES ;
-	}
-	if (ov9726_ctrl->pict_res == QTR_SIZE) {
-		snapshot_width  = OV9726_QTR_SIZE_WIDTH +
-			OV9726_HRZ_QTR_BLK_PIXELS ;
-		snapshot_height = OV9726_QTR_SIZE_HEIGHT +
-			OV9726_VER_QTR_BLK_LINES ;
-	} else {
-		snapshot_width  = OV9726_FULL_SIZE_WIDTH +
-			OV9726_HRZ_FULL_BLK_PIXELS;
-		snapshot_height = OV9726_FULL_SIZE_HEIGHT +
-			OV9726_VER_FULL_BLK_LINES;
-	}
-
-	d1 = (uint32_t)(((uint32_t)preview_height <<
-		OV9726_Q10Shift) /
-		snapshot_height);
-
-	d2 = (uint32_t)(((uint32_t)preview_width <<
-		OV9726_Q10Shift) /
-		 snapshot_width);
-
-	divider = (uint32_t) (d1 * d2) >> OV9726_Q10Shift;
-	*pfps = (uint16_t)((uint32_t)(fps * divider) >> OV9726_Q10Shift);
-}
-
-static uint16_t ov9726_get_prev_lines_pf(void)
-{
-	if (ov9726_ctrl->prev_res == QTR_SIZE)
-		return OV9726_QTR_SIZE_HEIGHT + OV9726_VER_QTR_BLK_LINES;
-	else
-		return OV9726_FULL_SIZE_HEIGHT + OV9726_VER_FULL_BLK_LINES;
-}
-
-static uint16_t ov9726_get_prev_pixels_pl(void)
-{
-	if (ov9726_ctrl->prev_res == QTR_SIZE)
-		return OV9726_QTR_SIZE_WIDTH + OV9726_HRZ_QTR_BLK_PIXELS;
-	else
-		return OV9726_FULL_SIZE_WIDTH + OV9726_HRZ_FULL_BLK_PIXELS;
-}
-
-static uint16_t ov9726_get_pict_lines_pf(void)
-{
-	if (ov9726_ctrl->pict_res == QTR_SIZE)
-		return OV9726_QTR_SIZE_HEIGHT + OV9726_VER_QTR_BLK_LINES;
-	else
-		return OV9726_FULL_SIZE_HEIGHT + OV9726_VER_FULL_BLK_LINES;
-}
-
-static uint16_t ov9726_get_pict_pixels_pl(void)
-{
-	if (ov9726_ctrl->pict_res == QTR_SIZE)
-		return OV9726_QTR_SIZE_WIDTH + OV9726_HRZ_QTR_BLK_PIXELS;
-	else
-		return OV9726_FULL_SIZE_WIDTH + OV9726_HRZ_FULL_BLK_PIXELS;
-}
-
-static uint32_t ov9726_get_pict_max_exp_lc(void)
-{
-	if (ov9726_ctrl->pict_res == QTR_SIZE)
-		return (OV9726_QTR_SIZE_HEIGHT + OV9726_VER_QTR_BLK_LINES)*24;
-	else
-		return (OV9726_FULL_SIZE_HEIGHT + OV9726_VER_FULL_BLK_LINES)*24;
-}
-
-static int32_t ov9726_set_fps(struct fps_cfg	*fps)
-{
-	int32_t rc = 0;
-	CDBG("%s: fps->fps_div = %d\n", __func__, fps->fps_div);
-	/* TODO: Passing of fps_divider from user space has issues. */
-	/* ov9726_ctrl->fps_divider = fps->fps_div; */
-	ov9726_ctrl->fps_divider = 1 * 0x400;
-	CDBG("%s: ov9726_ctrl->fps_divider = %d\n", __func__,
-		ov9726_ctrl->fps_divider);
-	ov9726_ctrl->pict_fps_divider = fps->pict_fps_div;
-	ov9726_ctrl->fps = fps->f_mult;
-	return rc;
-}
-
-static int32_t ov9726_write_exp_gain(uint16_t gain, uint32_t line)
-{
-	static uint16_t max_legal_gain = 0x00FF;
-	uint8_t gain_msb, gain_lsb;
-	uint8_t intg_time_msb, intg_time_lsb;
-	uint8_t ov9726_offset = 6;
-	uint8_t line_length_pck_msb, line_length_pck_lsb;
-	uint16_t line_length_pck, frame_length_lines;
-	uint32_t line_length_ratio = 1 << OV9726_Q8Shift;
-	int32_t rc = -1;
-	CDBG("%s: gain = %d	line = %d", __func__, gain, line);
-
-	if (ov9726_ctrl->sensormode != SENSOR_SNAPSHOT_MODE) {
-		if (ov9726_ctrl->curr_res == QTR_SIZE) {
-			frame_length_lines = OV9726_QTR_SIZE_HEIGHT +
-			 OV9726_VER_QTR_BLK_LINES;
-			line_length_pck = OV9726_QTR_SIZE_WIDTH	+
-			 OV9726_HRZ_QTR_BLK_PIXELS;
-		} else {
-			frame_length_lines = OV9726_FULL_SIZE_HEIGHT +
-				OV9726_VER_FULL_BLK_LINES;
-			line_length_pck = OV9726_FULL_SIZE_WIDTH +
-				OV9726_HRZ_FULL_BLK_PIXELS;
-		}
-		if (line > (frame_length_lines - ov9726_offset))
-			ov9726_ctrl->fps = (uint16_t) (((uint32_t)30 <<
-				OV9726_Q8Shift) *
-				(frame_length_lines - ov9726_offset) / line);
-		else
-			ov9726_ctrl->fps = (uint16_t) ((uint32_t)30 <<
-				OV9726_Q8Shift);
-	} else {
-		frame_length_lines = OV9726_FULL_SIZE_HEIGHT +
-			OV9726_VER_FULL_BLK_LINES;
-		line_length_pck = OV9726_FULL_SIZE_WIDTH +
-			OV9726_HRZ_FULL_BLK_PIXELS;
-	}
-
-	if (ov9726_ctrl->sensormode != SENSOR_SNAPSHOT_MODE) {
-		line = (uint32_t) (line * ov9726_ctrl->fps_divider) >>
-			OV9726_Q10Shift;
-	} else {
-		line = (uint32_t) (line * ov9726_ctrl->pict_fps_divider) >>
-			OV9726_Q10Shift;
-	}
-
-	/* calculate line_length_ratio */
-	if (line > (frame_length_lines - ov9726_offset)) {
-		line_length_ratio = (line << OV9726_Q8Shift) /
-			(frame_length_lines - ov9726_offset);
-		line = frame_length_lines - ov9726_offset;
-	} else
-		line_length_ratio = (uint32_t)1 << OV9726_Q8Shift;
-
-	if (gain > max_legal_gain) {
-		/* range:	0	to 224 */
-		gain = max_legal_gain;
-	}
-	/* update	gain registers */
-	gain_msb = (uint8_t) ((gain & 0xFF00) >> 8);
-	gain_lsb = (uint8_t) (gain & 0x00FF);
-	/* linear	AFR	horizontal stretch */
-	line_length_pck = (uint16_t) ((line_length_pck *
-		line_length_ratio) >> OV9726_Q8Shift);
-	line_length_pck_msb = (uint8_t) ((line_length_pck & 0xFF00) >> 8);
-	line_length_pck_lsb = (uint8_t) (line_length_pck & 0x00FF);
-	/* update	line count registers */
-	intg_time_msb = (uint8_t) ((line & 0xFF00) >> 8);
-	intg_time_lsb = (uint8_t) (line	& 0x00FF);
-
-	rc = ov9726_i2c_write_b(ov9726_client->addr, 0x104, 0x1);
-	if (rc < 0)
-		return rc;
-
-	rc = ov9726_i2c_write_b(ov9726_client->addr, 0x204, gain_msb);
-	if (rc < 0)
-		return rc;
-
-	rc = ov9726_i2c_write_b(ov9726_client->addr, 0x205, gain_lsb);
-	if (rc < 0)
-		return rc;
-
-	rc = ov9726_i2c_write_b(ov9726_client->addr, 0x342,
-		line_length_pck_msb);
-	if (rc < 0)
-		return rc;
-
-	rc = ov9726_i2c_write_b(ov9726_client->addr, 0x343,
-		line_length_pck_lsb);
-	if (rc < 0)
-		return rc;
-
-	rc = ov9726_i2c_write_b(ov9726_client->addr, 0x0202, intg_time_msb);
-	if (rc < 0)
-		return rc;
-
-	rc = ov9726_i2c_write_b(ov9726_client->addr, 0x0203, intg_time_lsb);
-	if (rc < 0)
-		return rc;
-
-	rc = ov9726_i2c_write_b(ov9726_client->addr, 0x104, 0x0);
-	if (rc < 0)
-		return rc;
-
-	return rc;
-}
-
-static int32_t ov9726_set_pict_exp_gain(uint16_t gain, uint32_t line)
-{
-	int32_t rc = 0;
-	rc = ov9726_write_exp_gain(gain, line);
-	return rc;
-}
-
-static int32_t initialize_ov9726_registers(void)
-{
-	int32_t i;
-	int32_t rc = 0;
-	ov9726_ctrl->sensormode = SENSOR_PREVIEW_MODE ;
-	/* Configure sensor for Preview mode and Snapshot mode */
-	CDBG("Initialize_ov9726_registers\n");
-	for (i = 0; i < ov9726_array_length; i++) {
-		rc = ov9726_i2c_write_b(ov9726_client->addr,
-			ov9726_init_settings_array[i].reg_addr,
-			ov9726_init_settings_array[i].reg_val);
-	if (rc < 0)
-		return rc;
-	}
-	return rc;
-}
-
-static int32_t ov9726_video_config(int mode)
-{
-	int32_t rc = 0;
-
-	ov9726_ctrl->sensormode = mode;
-
-	if (config_not_set) {
-		struct msm_camera_csi_params ov9726_csi_params;
-
-		/* sensor in standby */
-		ov9726_i2c_write_b(ov9726_client->addr, 0x100, 0);
-		msleep(5);
-		/* Initialize Sensor registers */
-		ov9726_csi_params.data_format = CSI_10BIT;
-		ov9726_csi_params.lane_cnt = 1;
-		ov9726_csi_params.lane_assign = 0xe4;
-		ov9726_csi_params.dpcm_scheme = 0;
-		ov9726_csi_params.settle_cnt = 7;
-
-		rc = msm_camio_csi_config(&ov9726_csi_params);
-		rc = initialize_ov9726_registers();
-		config_not_set = 0;
-	}
-	return rc;
-}
-
-static int32_t ov9726_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-	ov9726_ctrl->sensormode = mode;
-	return rc;
-}
-
-static int32_t ov9726_raw_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-	ov9726_ctrl->sensormode = mode;
-	return rc;
-}
-
-static int32_t ov9726_set_sensor_mode(int  mode,
-			int  res)
-{
-	int32_t rc = 0;
-	switch (mode) {
-	case SENSOR_PREVIEW_MODE:
-		rc = ov9726_video_config(mode);
-		break;
-	case SENSOR_SNAPSHOT_MODE:
-		rc = ov9726_snapshot_config(mode);
-		break;
-	case SENSOR_RAW_SNAPSHOT_MODE:
-		rc = ov9726_raw_snapshot_config(mode);
-		break;
-	default:
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
-
-static int ov9726_probe_init_sensor(const struct msm_camera_sensor_info *data)
-{
-	int32_t rc = 0;
-	uint16_t  chipidl, chipidh;
-
-	if (data->sensor_reset_enable) {
-		rc = gpio_request(data->sensor_reset, "ov9726");
-		if (!rc) {
-			gpio_direction_output(data->sensor_reset, 0);
-			gpio_set_value_cansleep(data->sensor_reset, 1);
-			msleep(20);
-		} else
-			goto init_probe_done;
-	}
-	/* 3. Read sensor Model ID: */
-	rc = ov9726_i2c_read(OV9726_PIDH_REG, &chipidh, 1);
-	if (rc < 0)
-		goto init_probe_fail;
-	rc = ov9726_i2c_read(OV9726_PIDL_REG, &chipidl, 1);
-	if (rc < 0)
-		goto init_probe_fail;
-	CDBG("kov9726 model_id = 0x%x  0x%x\n", chipidh, chipidl);
-	/* 4. Compare sensor ID to OV9726 ID: */
-	if (chipidh != OV9726_PID) {
-		rc = -ENODEV;
-		printk(KERN_INFO "Probeinit fail\n");
-		goto init_probe_fail;
-	}
-	CDBG("chipidh == OV9726_PID\n");
-	msleep(OV9726_RESET_DELAY_MSECS);
-	CDBG("after delay\n");
-	goto init_probe_done;
-
-init_probe_fail:
-	if (data->sensor_reset_enable) {
-		gpio_direction_output(data->sensor_reset, 0);
-		gpio_free(data->sensor_reset);
-	}
-init_probe_done:
-	printk(KERN_INFO " ov9726_probe_init_sensor finishes\n");
-	return rc;
-}
-
-int ov9726_sensor_open_init(const struct msm_camera_sensor_info *data)
-{
-	int32_t  rc;
-
-	CDBG("Calling ov9726_sensor_open_init\n");
-	ov9726_ctrl = kzalloc(sizeof(struct ov9726_ctrl_t), GFP_KERNEL);
-	if (!ov9726_ctrl) {
-		CDBG("ov9726_init failed!\n");
-		rc = -ENOMEM;
-		goto init_done;
-	}
-	ov9726_ctrl->curr_lens_pos = -1;
-	ov9726_ctrl->fps_divider = 1 << OV9726_Q10Shift;
-	ov9726_ctrl->pict_fps_divider = 1 << OV9726_Q10Shift;
-	ov9726_ctrl->set_test = TEST_OFF;
-	ov9726_ctrl->prev_res = FULL_SIZE;
-	ov9726_ctrl->pict_res = FULL_SIZE;
-	ov9726_ctrl->curr_res = INVALID_SIZE;
-	config_not_set = 1;
-	if (data)
-		ov9726_ctrl->sensordata = data;
-	/* enable mclk first */
-	msm_camio_clk_rate_set(OV9726_DEFAULT_CLOCK_RATE);
-	msleep(20);
-	rc = ov9726_probe_init_sensor(data);
-	if (rc < 0)
-		goto init_fail;
-
-	ov9726_ctrl->fps = (uint16_t)(30 << OV9726_Q8Shift);
-	/* generate test pattern */
-	if (rc < 0)
-		goto init_fail;
-	else
-		goto init_done;
-	/* reset the driver state */
-init_fail:
-	CDBG(" init_fail\n");
-	kfree(ov9726_ctrl);
-init_done:
-	CDBG("init_done\n");
-	return rc;
-}
-
-static int ov9726_init_client(struct i2c_client *client)
-{
-	/* Initialize the MSM_CAMI2C Chip */
-	init_waitqueue_head(&ov9726_wait_queue);
-	return 0;
-}
-
-static const struct i2c_device_id ov9726_i2c_id[] = {
-	{ "ov9726", 0},
-	{ }
-};
-
-static int ov9726_i2c_probe(struct i2c_client *client,
-	const struct i2c_device_id *id)
-{
-	int rc = 0;
-	CDBG("ov9726_probe called!\n");
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		CDBG("i2c_check_functionality failed\n");
-		goto probe_failure;
-	}
-	ov9726_sensorw = kzalloc(sizeof(struct ov9726_work_t), GFP_KERNEL);
-	if (!ov9726_sensorw) {
-		CDBG("kzalloc failed.\n");
-		rc = -ENOMEM;
-		goto probe_failure;
-	}
-	i2c_set_clientdata(client, ov9726_sensorw);
-	ov9726_init_client(client);
-	ov9726_client = client;
-	msleep(50);
-	CDBG("ov9726_probe successed! rc = %d\n", rc);
-	return 0;
-probe_failure:
-	CDBG("ov9726_probe failed! rc = %d\n", rc);
-	return rc;
-}
-
-static int __exit ov9726_remove(struct i2c_client *client)
-{
-	struct ov9726_work_t_t *sensorw = i2c_get_clientdata(client);
-	free_irq(client->irq, sensorw);
-	ov9726_client = NULL;
-	kfree(sensorw);
-	return 0;
-}
-
-static struct i2c_driver ov9726_i2c_driver = {
-	.id_table = ov9726_i2c_id,
-	.probe	= ov9726_i2c_probe,
-	.remove = __exit_p(ov9726_i2c_remove),
-	.driver = {
-		.name = "ov9726",
-	},
-};
-
-int ov9726_sensor_config(void __user *argp)
-{
-	struct sensor_cfg_data cdata;
-	long   rc = 0;
-
-	if (copy_from_user(&cdata,
-				(void *)argp,
-				sizeof(struct sensor_cfg_data)))
-		return -EFAULT;
-	mutex_lock(&ov9726_mut);
-	CDBG("ov9726_sensor_config: cfgtype = %d\n",
-		cdata.cfgtype);
-	switch (cdata.cfgtype) {
-	case CFG_GET_PICT_FPS:
-		ov9726_get_pict_fps(cdata.cfg.gfps.prevfps,
-				&(cdata.cfg.gfps.pictfps));
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-			break;
-	case CFG_GET_PREV_L_PF:
-		cdata.cfg.prevl_pf = ov9726_get_prev_lines_pf();
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-	case CFG_GET_PREV_P_PL:
-		cdata.cfg.prevp_pl = ov9726_get_prev_pixels_pl();
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-	case CFG_GET_PICT_L_PF:
-		cdata.cfg.pictl_pf = ov9726_get_pict_lines_pf();
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-	case CFG_GET_PICT_P_PL:
-		cdata.cfg.pictp_pl =
-				ov9726_get_pict_pixels_pl();
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-	case CFG_GET_PICT_MAX_EXP_LC:
-		cdata.cfg.pict_max_exp_lc = ov9726_get_pict_max_exp_lc();
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-	case CFG_SET_FPS:
-	case CFG_SET_PICT_FPS:
-		rc = ov9726_set_fps(&(cdata.cfg.fps));
-		break;
-	case CFG_SET_EXP_GAIN:
-		rc = ov9726_write_exp_gain(
-					cdata.cfg.exp_gain.gain,
-					cdata.cfg.exp_gain.line);
-		break;
-	case CFG_SET_PICT_EXP_GAIN:
-		rc = ov9726_set_pict_exp_gain(
-					cdata.cfg.exp_gain.gain,
-					cdata.cfg.exp_gain.line);
-		break;
-	case CFG_SET_MODE:
-		rc = ov9726_set_sensor_mode(cdata.mode,
-						cdata.rs);
-		break;
-	case CFG_PWR_DOWN:
-	case CFG_MOVE_FOCUS:
-	case CFG_SET_DEFAULT_FOCUS:
-		rc = 0;
-		break;
-	case CFG_SET_EFFECT:
-	default:
-		rc = -EFAULT;
-		break;
-	}
-	mutex_unlock(&ov9726_mut);
-	return rc;
-}
-
-static int ov9726_probe_init_done(const struct msm_camera_sensor_info *data)
-{
-	if (data->sensor_reset_enable) {
-		gpio_direction_output(data->sensor_reset, 0);
-		gpio_free(data->sensor_reset);
-	}
-	return 0;
-}
-
-static int ov9726_sensor_release(void)
-{
-	int rc = -EBADF;
-	mutex_lock(&ov9726_mut);
-	if (ov9726_ctrl->sensordata->sensor_reset_enable) {
-		gpio_direction_output(
-			ov9726_ctrl->sensordata->sensor_reset, 0);
-		gpio_free(ov9726_ctrl->sensordata->sensor_reset);
-	}
-	kfree(ov9726_ctrl);
-	ov9726_ctrl = NULL;
-	CDBG("ov9726_release completed\n");
-	mutex_unlock(&ov9726_mut);
-	return rc;
-}
-
-static int ov9726_sensor_probe(const struct msm_camera_sensor_info *info,
-		struct msm_sensor_ctrl *s)
-{
-	int rc = 0;
-
-	rc = i2c_add_driver(&ov9726_i2c_driver);
-	if (rc < 0 || ov9726_client == NULL) {
-		rc = -ENOTSUPP;
-		goto probe_fail;
-	}
-	msm_camio_clk_rate_set(24000000);
-	msleep(20);
-	rc = ov9726_probe_init_sensor(info);
-	if (rc < 0)
-		goto probe_fail;
-
-	s->s_init = ov9726_sensor_open_init;
-	s->s_release = ov9726_sensor_release;
-	s->s_config  = ov9726_sensor_config;
-	s->s_camera_type = FRONT_CAMERA_2D;
-	s->s_mount_angle = info->sensor_platform_info->mount_angle;
-	ov9726_probe_init_done(info);
-
-	return rc;
-
-probe_fail:
-	CDBG("SENSOR PROBE FAILS!\n");
-	return rc;
-}
-
-static int __ov9726_probe(struct platform_device *pdev)
-{
-	return msm_camera_drv_start(pdev, ov9726_sensor_probe);
-}
-
-static struct platform_driver msm_camera_driver = {
-	.probe = __ov9726_probe,
-	.driver = {
-		.name = "msm_camera_ov9726",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init ov9726_init(void)
-{
-	return platform_driver_register(&msm_camera_driver);
-}
-
-module_init(ov9726_init);
-void ov9726_exit(void)
-{
-	i2c_del_driver(&ov9726_i2c_driver);
-}
-
-MODULE_DESCRIPTION("OMNI VGA Bayer sensor driver");
-MODULE_LICENSE("GPL v2");
-
diff --git a/drivers/media/video/msm/ov9726.h b/drivers/media/video/msm/ov9726.h
deleted file mode 100644
index 56d3da6..0000000
--- a/drivers/media/video/msm/ov9726.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. 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 OV9726_H
-#define OV9726_H
-#include <linux/types.h>
-#include <mach/board.h>
-
-/* 16bit address - 8 bit context register structure */
-struct reg_struct_type {
-	uint16_t	reg_addr;
-	unsigned char	reg_val;
-};
-
-enum ov9726_test_mode_t {
-	TEST_OFF,
-	TEST_1,
-	TEST_2,
-	TEST_3
-};
-
-enum ov9726_resolution_t {
-	QTR_SIZE,
-	FULL_SIZE,
-	INVALID_SIZE
-};
-extern struct reg_struct_type ov9726_init_settings_array[];
-extern int32_t ov9726_array_length;
-#endif
-
diff --git a/drivers/media/video/msm/ov9726_reg.c b/drivers/media/video/msm/ov9726_reg.c
deleted file mode 100644
index 54afbe8..0000000
--- a/drivers/media/video/msm/ov9726_reg.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. 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 "ov9726.h"
-struct reg_struct_type ov9726_init_settings_array[] = {
-	{0x0103, 0x01}, /* SOFTWARE_RESET */
-	{0x3026, 0x00}, /* OUTPUT_SELECT01 */
-	{0x3027, 0x00}, /* OUTPUT_SELECT02 */
-	{0x3002, 0xe8}, /* IO_CTRL00 */
-	{0x3004, 0x03}, /* IO_CTRL01 */
-	{0x3005, 0xff}, /* IO_CTRL02 */
-	{0x3703, 0x42},
-	{0x3704, 0x10},
-	{0x3705, 0x45},
-	{0x3603, 0xaa},
-	{0x3632, 0x2f},
-	{0x3620, 0x66},
-	{0x3621, 0xc0},
-	{0x0340, 0x03}, /* FRAME_LENGTH_LINES_HI */
-	{0x0341, 0xC1}, /* FRAME_LENGTH_LINES_LO */
-	{0x0342, 0x06}, /* LINE_LENGTH_PCK_HI */
-	{0x0343, 0x80}, /* LINE_LENGTH_PCK_LO */
-	{0x0202, 0x03}, /* COARSE_INTEGRATION_TIME_HI */
-	{0x0203, 0x43}, /* COARSE_INTEGRATION_TIME_LO */
-	{0x3833, 0x04},
-	{0x3835, 0x02},
-	{0x4702, 0x04},
-	{0x4704, 0x00}, /* DVP_CTRL01 */
-	{0x4706, 0x08},
-	{0x5052, 0x01},
-	{0x3819, 0x6e},
-	{0x3817, 0x94},
-	{0x3a18, 0x00}, /* AEC_GAIN_CEILING_HI */
-	{0x3a19, 0x7f}, /* AEC_GAIN_CEILING_LO */
-	{0x404e, 0x7e},
-	{0x3631, 0x52},
-	{0x3633, 0x50},
-	{0x3630, 0xd2},
-	{0x3604, 0x08},
-	{0x3601, 0x40},
-	{0x3602, 0x14},
-	{0x3610, 0xa0},
-	{0x3612, 0x20},
-	{0x034c, 0x05}, /* X_OUTPUT_SIZE_HI */
-	{0x034d, 0x10}, /* X_OUTPUT_SIZE_LO */
-	{0x034e, 0x03}, /* Y_OUTPUT_SIZE_HI */
-	{0x034f, 0x28}, /* Y_OUTPUT_SIZE_LO */
-	{0x0340, 0x03}, /* FRAME_LENGTH_LINES_HI */
-	{0x0341, 0xC1}, /* FRAME_LENGTH_LINES_LO */
-	{0x0342, 0x06}, /* LINE_LENGTH_PCK_HI */
-	{0x0343, 0x80}, /* LINE_LENGTH_PCK_LO */
-	{0x0202, 0x03}, /* COARSE_INTEGRATION_TIME_HI */
-	{0x0203, 0x43}, /* COARSE_INTEGRATION_TIME_LO */
-	{0x0303, 0x01}, /* VT_SYS_CLK_DIV_LO */
-	{0x3002, 0x00}, /* IO_CTRL00 */
-	{0x3004, 0x00}, /* IO_CTRL01 */
-	{0x3005, 0x00}, /* IO_CTRL02 */
-	{0x4801, 0x0f}, /* MIPI_CTRL01 */
-	{0x4803, 0x05}, /* MIPI_CTRL03 */
-	{0x4601, 0x16}, /* VFIFO_READ_CONTROL */
-	{0x3014, 0x05}, /* SC_CMMN_MIPI / SC_CTRL00 */
-	{0x3104, 0x80},
-	{0x0305, 0x04}, /* PRE_PLL_CLK_DIV_LO */
-	{0x0307, 0x64}, /* PLL_MULTIPLIER_LO */
-	{0x300c, 0x02},
-	{0x300d, 0x20},
-	{0x300e, 0x01},
-	{0x3010, 0x01},
-	{0x460e, 0x81}, /* VFIFO_CONTROL00 */
-	{0x0101, 0x01}, /* IMAGE_ORIENTATION */
-	{0x3707, 0x14},
-	{0x3622, 0x9f},
-	{0x5047, 0x3D}, /* ISP_CTRL47 */
-	{0x4002, 0x45}, /* BLC_CTRL02 */
-	{0x5000, 0x06}, /* ISP_CTRL0 */
-	{0x5001, 0x00}, /* ISP_CTRL1 */
-	{0x3406, 0x00}, /* AWB_MANUAL_CTRL */
-	{0x3503, 0x13}, /* AEC_ENABLE */
-	{0x4005, 0x18}, /* BLC_CTRL05 */
-	{0x4837, 0x21},
-	{0x0100, 0x01}, /* MODE_SELECT */
-	{0x3a0f, 0x64}, /* AEC_CTRL0F */
-	{0x3a10, 0x54}, /* AEC_CTRL10 */
-	{0x3a11, 0xc2}, /* AEC_CTRL11 */
-	{0x3a1b, 0x64}, /* AEC_CTRL1B */
-	{0x3a1e, 0x54}, /* AEC_CTRL1E */
-	{0x3a1a, 0x05}, /* AEC_DIFF_MAX */
-};
-int32_t ov9726_array_length = sizeof(ov9726_init_settings_array) /
-	sizeof(ov9726_init_settings_array[0]);
-
diff --git a/drivers/media/video/msm/qs_s5k4e1.c b/drivers/media/video/msm/qs_s5k4e1.c
deleted file mode 100644
index 64db015..0000000
--- a/drivers/media/video/msm/qs_s5k4e1.c
+++ /dev/null
@@ -1,1822 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. 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/delay.h>
-#include <linux/debugfs.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/slab.h>
-#include <media/msm_camera.h>
-#include <mach/gpio.h>
-#include <mach/camera.h>
-#include "qs_s5k4e1.h"
-/*=============================================================
-	SENSOR REGISTER DEFINES
-==============================================================*/
-#define REG_GROUPED_PARAMETER_HOLD		0x0104
-#define GROUPED_PARAMETER_HOLD_OFF		0x00
-#define GROUPED_PARAMETER_HOLD			0x01
-/* Integration Time */
-#define REG_COARSE_INTEGRATION_TIME		0x0202
-/* Gain */
-#define REG_GLOBAL_GAIN					0x0204
-#define REG_GR_GAIN					0x020E
-#define REG_R_GAIN					0x0210
-#define REG_B_GAIN					0x0212
-#define REG_GB_GAIN					0x0214
-/* PLL registers */
-#define REG_FRAME_LENGTH_LINES			0x0340
-#define REG_LINE_LENGTH_PCK				0x0342
-/* Test Pattern */
-#define REG_TEST_PATTERN_MODE			0x0601
-#define REG_VCM_NEW_CODE				0x30F2
-#define AF_ADDR							0x18
-#define BRIDGE_ADDR						0x80
-/*============================================================================
-			 TYPE DECLARATIONS
-============================================================================*/
-
-/* 16bit address - 8 bit context register structure */
-#define Q8  0x00000100
-#define Q10 0x00000400
-#define QS_S5K4E1_MASTER_CLK_RATE 24000000
-#define QS_S5K4E1_OFFSET			8
-
-/* AF Total steps parameters */
-#define QS_S5K4E1_TOTAL_STEPS_NEAR_TO_FAR    32
-#define QS_S5K4E1_TOTAL_STEPS_3D    32
-
-uint16_t qs_s5k4e1_step_position_table[QS_S5K4E1_TOTAL_STEPS_NEAR_TO_FAR+1];
-uint16_t qs_s5k4e1_step_position_table_left[QS_S5K4E1_TOTAL_STEPS_3D+1];
-uint16_t qs_s5k4e1_step_position_table_right[QS_S5K4E1_TOTAL_STEPS_3D+1];
-uint16_t qs_s5k4e1_nl_region_boundary1;
-uint16_t qs_s5k4e1_nl_region_code_per_step1 = 190;
-uint16_t qs_s5k4e1_l_region_code_per_step = 8;
-uint16_t qs_s5k4e1_damping_threshold = 10;
-uint16_t qs_s5k4e1_sw_damping_time_wait = 8;
-uint16_t qs_s5k4e1_af_mode = 4;
-int16_t qs_s5k4e1_af_initial_code = 190;
-int16_t qs_s5k4e1_af_right_adjust;
-
-struct qs_s5k4e1_work_t {
-	struct work_struct work;
-};
-
-static struct qs_s5k4e1_work_t *qs_s5k4e1_sensorw;
-static struct i2c_client *qs_s5k4e1_client;
-static char lens_eeprom_data[864];
-static bool cali_data_status;
-struct qs_s5k4e1_ctrl_t {
-	const struct  msm_camera_sensor_info *sensordata;
-
-	uint32_t sensormode;
-	uint32_t fps_divider;/* init to 1 * 0x00000400 */
-	uint32_t pict_fps_divider;/* init to 1 * 0x00000400 */
-	uint16_t fps;
-
-	uint16_t curr_lens_pos;
-	uint16_t curr_step_pos;
-	uint16_t my_reg_gain;
-	uint32_t my_reg_line_count;
-	uint16_t total_lines_per_frame;
-
-	enum qs_s5k4e1_resolution_t prev_res;
-	enum qs_s5k4e1_resolution_t pict_res;
-	enum qs_s5k4e1_resolution_t curr_res;
-	enum qs_s5k4e1_test_mode_t  set_test;
-	enum qs_s5k4e1_cam_mode_t cam_mode;
-};
-
-static uint16_t prev_line_length_pck;
-static uint16_t prev_frame_length_lines;
-static uint16_t snap_line_length_pck;
-static uint16_t snap_frame_length_lines;
-
-static bool CSI_CONFIG, LENS_SHADE_CONFIG, default_lens_shade;
-static struct qs_s5k4e1_ctrl_t *qs_s5k4e1_ctrl;
-static DECLARE_WAIT_QUEUE_HEAD(qs_s5k4e1_wait_queue);
-DEFINE_MUTEX(qs_s5k4e1_mut);
-
-static int cam_debug_init(void);
-static struct dentry *debugfs_base;
-/*=============================================================*/
-
-static int qs_s5k4e1_i2c_rxdata(unsigned short saddr,
-	unsigned char *rxdata, int length)
-{
-	struct i2c_msg msgs[] = {
-		{
-			.addr  = saddr,
-			.flags = 0,
-			.len   = 2,
-			.buf   = rxdata,
-		},
-		{
-			.addr  = saddr,
-			.flags = I2C_M_RD,
-			.len   = length,
-			.buf   = rxdata,
-		},
-	};
-	if (i2c_transfer(qs_s5k4e1_client->adapter, msgs, 2) < 0) {
-		CDBG("qs_s5k4e1_i2c_rxdata faild 0x%x\n", saddr);
-		return -EIO;
-	}
-	return 0;
-}
-
-static int32_t qs_s5k4e1_i2c_txdata(unsigned short saddr,
-				unsigned char *txdata, int length)
-{
-	struct i2c_msg msg[] = {
-		{
-			.addr = saddr,
-			.flags = 0,
-			.len = length,
-			.buf = txdata,
-		 },
-	};
-	if (i2c_transfer(qs_s5k4e1_client->adapter, msg, 1) < 0) {
-		CDBG("qs_s5k4e1_i2c_txdata faild 0x%x\n", saddr);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int32_t qs_s5k4e1_i2c_read(unsigned short raddr,
-	unsigned short *rdata, int rlen)
-{
-	int32_t rc = 0;
-	unsigned char buf[2];
-	if (!rdata)
-		return -EIO;
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (raddr & 0xFF00) >> 8;
-	buf[1] = (raddr & 0x00FF);
-	rc = qs_s5k4e1_i2c_rxdata(qs_s5k4e1_client->addr>>1, buf, rlen);
-	if (rc < 0) {
-		CDBG("qs_s5k4e1_i2c_read 0x%x failed!\n", raddr);
-		return rc;
-	}
-	*rdata = (rlen == 2 ? buf[0] << 8 | buf[1] : buf[0]);
-	CDBG("qs_s5k4e1_i2c_read 0x%x val = 0x%x!\n", raddr, *rdata);
-	return rc;
-}
-
-static int32_t qs_s5k4e1_i2c_write_w_sensor(unsigned short waddr,
-	 uint16_t wdata)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[4];
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (waddr & 0xFF00) >> 8;
-	buf[1] = (waddr & 0x00FF);
-	buf[2] = (wdata & 0xFF00) >> 8;
-	buf[3] = (wdata & 0x00FF);
-	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, wdata);
-	rc = qs_s5k4e1_i2c_txdata(qs_s5k4e1_client->addr>>1, buf, 4);
-	if (rc < 0) {
-		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
-			waddr, wdata);
-	}
-	return rc;
-}
-
-static int32_t qs_s5k4e1_i2c_write_b_sensor(unsigned short waddr, uint8_t bdata)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[3];
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (waddr & 0xFF00) >> 8;
-	buf[1] = (waddr & 0x00FF);
-	buf[2] = bdata;
-	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
-	rc = qs_s5k4e1_i2c_txdata(qs_s5k4e1_client->addr>>1, buf, 3);
-	if (rc < 0) {
-		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
-			waddr, bdata);
-	}
-	return rc;
-}
-
-static int32_t qs_s5k4e1_i2c_write_b_table(struct qs_s5k4e1_i2c_reg_conf const
-					 *reg_conf_tbl, int num)
-{
-	int i;
-	int32_t rc = -EIO;
-	for (i = 0; i < num; i++) {
-		rc = qs_s5k4e1_i2c_write_b_sensor(reg_conf_tbl->waddr,
-			reg_conf_tbl->wdata);
-		if (rc < 0)
-			break;
-		reg_conf_tbl++;
-	}
-	return rc;
-}
-
-static int32_t qs_s5k4e1_i2c_write_seq_sensor(unsigned short waddr,
-		unsigned char *seq_data, int len)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[len+2];
-	int i = 0;
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (waddr & 0xFF00) >> 8;
-	buf[1] = (waddr & 0x00FF);
-	for (i = 0; i < len; i++)
-		buf[i+2] = seq_data[i];
-	rc = qs_s5k4e1_i2c_txdata(qs_s5k4e1_client->addr>>1, buf, len+2);
-	return rc;
-}
-
-static int32_t af_i2c_write_b_sensor(unsigned short baddr, uint8_t bdata)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[2];
-	memset(buf, 0, sizeof(buf));
-	buf[0] = baddr;
-	buf[1] = bdata;
-	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", baddr, bdata);
-	rc = qs_s5k4e1_i2c_txdata(AF_ADDR>>1, buf, 2);
-	if (rc < 0) {
-		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
-			baddr, bdata);
-	}
-	return rc;
-}
-
-static int32_t bridge_i2c_write_w(unsigned short waddr, uint16_t wdata)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[4];
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (waddr & 0xFF00) >> 8;
-	buf[1] = (waddr & 0x00FF);
-	buf[2] = (wdata & 0xFF00) >> 8;
-	buf[3] = (wdata & 0x00FF);
-	CDBG("bridge_i2c_write_w addr = 0x%x, val = 0x%x\n", waddr, wdata);
-	rc = qs_s5k4e1_i2c_txdata(BRIDGE_ADDR>>1, buf, 4);
-	if (rc < 0) {
-		CDBG("bridge_i2c_write_w failed, addr = 0x%x, val = 0x%x!\n",
-			waddr, wdata);
-	}
-	return rc;
-}
-
-static int32_t bridge_i2c_read(unsigned short raddr,
-	unsigned short *rdata, int rlen)
-{
-	int32_t rc = 0;
-	unsigned char buf[2];
-	if (!rdata)
-		return -EIO;
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (raddr & 0xFF00) >> 8;
-	buf[1] = (raddr & 0x00FF);
-	rc = qs_s5k4e1_i2c_rxdata(BRIDGE_ADDR>>1, buf, rlen);
-	if (rc < 0) {
-		CDBG("bridge_i2c_read 0x%x failed!\n", raddr);
-		return rc;
-	}
-	*rdata = (rlen == 2 ? buf[0] << 8 | buf[1] : buf[0]);
-	CDBG("bridge_i2c_read 0x%x val = 0x%x!\n", raddr, *rdata);
-	return rc;
-}
-
-static int32_t qs_s5k4e1_eeprom_i2c_read(unsigned short raddr,
-	unsigned char *rdata, int rlen)
-{
-	int32_t rc = 0;
-	unsigned short i2caddr = 0xA0 >> 1;
-	unsigned char buf[rlen];
-	int i = 0;
-	if (!rdata)
-		return -EIO;
-
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (raddr & 0xFF00) >> 8;
-	buf[1] = (raddr & 0x00FF);
-	rc = qs_s5k4e1_i2c_rxdata(i2caddr, buf, rlen);
-	if (rc < 0) {
-		CDBG("qs_s5k4e1_eeprom_i2c_read 0x%x failed!\n", raddr);
-		return rc;
-	}
-	for (i = 0; i < rlen; i++) {
-		rdata[i] = buf[i];
-		CDBG("qs_s5k4e1_eeprom_i2c_read 0x%x index: %d val = 0x%x!\n",
-			raddr, i, buf[i]);
-	}
-	return rc;
-}
-
-static int32_t qs_s5k4e1_eeprom_i2c_read_b(unsigned short raddr,
-	unsigned short *rdata, int rlen)
-{
-	int32_t rc = 0;
-	unsigned char buf[2];
-	rc = qs_s5k4e1_eeprom_i2c_read(raddr, &buf[0], rlen);
-	*rdata = (rlen == 2 ? buf[0] << 8 | buf[1] : buf[0]);
-	CDBG("qs_s5k4e1_eeprom_i2c_read 0x%x val = 0x%x!\n", raddr, *rdata);
-	return rc;
-}
-
-static int32_t qs_s5k4e1_get_calibration_data(
-	struct sensor_3d_cali_data_t *cdata)
-{
-	int32_t rc = 0;
-	cali_data_status = 1;
-	rc = qs_s5k4e1_eeprom_i2c_read(0x0,
-		&(cdata->left_p_matrix[0][0][0]), 96);
-	if (rc < 0)
-		goto fail;
-	rc = qs_s5k4e1_eeprom_i2c_read(0x60,
-		&(cdata->right_p_matrix[0][0][0]), 96);
-	if (rc < 0)
-		goto fail;
-	rc = qs_s5k4e1_eeprom_i2c_read(0xC0, &(cdata->square_len[0]), 8);
-	if (rc < 0)
-		goto fail;
-	rc = qs_s5k4e1_eeprom_i2c_read(0xC8, &(cdata->focal_len[0]), 8);
-	if (rc < 0)
-		goto fail;
-	rc = qs_s5k4e1_eeprom_i2c_read(0xD0, &(cdata->pixel_pitch[0]), 8);
-	if (rc < 0)
-		goto fail;
-	rc = qs_s5k4e1_eeprom_i2c_read_b(0x100, &(cdata->left_r), 1);
-	if (rc < 0)
-		goto fail;
-	rc = qs_s5k4e1_eeprom_i2c_read_b(0x101, &(cdata->right_r), 1);
-	if (rc < 0)
-		goto fail;
-	rc = qs_s5k4e1_eeprom_i2c_read_b(0x102, &(cdata->left_b), 1);
-	if (rc < 0)
-		goto fail;
-	rc = qs_s5k4e1_eeprom_i2c_read_b(0x103, &(cdata->right_b), 1);
-	if (rc < 0)
-		goto fail;
-	rc = qs_s5k4e1_eeprom_i2c_read_b(0x104, &(cdata->left_gb), 1);
-	if (rc < 0)
-		goto fail;
-	rc = qs_s5k4e1_eeprom_i2c_read_b(0x105, &(cdata->right_gb), 1);
-	if (rc < 0)
-		goto fail;
-	rc = qs_s5k4e1_eeprom_i2c_read_b(0x110, &(cdata->left_af_far), 2);
-	if (rc < 0)
-		goto fail;
-	rc = qs_s5k4e1_eeprom_i2c_read_b(0x112, &(cdata->right_af_far), 2);
-	if (rc < 0)
-		goto fail;
-	rc = qs_s5k4e1_eeprom_i2c_read_b(0x114, &(cdata->left_af_mid), 2);
-	if (rc < 0)
-		goto fail;
-	rc = qs_s5k4e1_eeprom_i2c_read_b(0x116, &(cdata->right_af_mid), 2);
-	if (rc < 0)
-		goto fail;
-	rc = qs_s5k4e1_eeprom_i2c_read_b(0x118, &(cdata->left_af_short), 2);
-	if (rc < 0)
-		goto fail;
-	rc = qs_s5k4e1_eeprom_i2c_read_b(0x11A, &(cdata->right_af_short), 2);
-	if (rc < 0)
-		goto fail;
-	rc = qs_s5k4e1_eeprom_i2c_read_b(0x11C, &(cdata->left_af_5um), 2);
-	if (rc < 0)
-		goto fail;
-	rc = qs_s5k4e1_eeprom_i2c_read_b(0x11E, &(cdata->right_af_5um), 2);
-	if (rc < 0)
-		goto fail;
-	rc = qs_s5k4e1_eeprom_i2c_read_b(0x120, &(cdata->left_af_50up), 2);
-	if (rc < 0)
-		goto fail;
-	rc = qs_s5k4e1_eeprom_i2c_read_b(0x122, &(cdata->right_af_50up), 2);
-	if (rc < 0)
-		goto fail;
-	rc = qs_s5k4e1_eeprom_i2c_read_b(0x124, &(cdata->left_af_50down), 2);
-	if (rc < 0)
-		goto fail;
-	rc = qs_s5k4e1_eeprom_i2c_read_b(0x126, &(cdata->right_af_50down), 2);
-	if (rc < 0)
-		goto fail;
-
-	return 0;
-
-fail:
-	cali_data_status = 0;
-	return -EIO;
-
-}
-static int32_t qs_s5k4e1_write_left_lsc(char *left_lsc, int rt)
-{
-	struct qs_s5k4e1_i2c_reg_conf *ptr = (struct qs_s5k4e1_i2c_reg_conf *)
-		(qs_s5k4e1_regs.reg_lens + rt);
-	bridge_i2c_write_w(0x06, 0x02);
-	if (!LENS_SHADE_CONFIG) {
-		qs_s5k4e1_i2c_write_b_sensor(0x3096, 0x40);
-		qs_s5k4e1_i2c_write_b_table(ptr, qs_s5k4e1_regs.reg_lens_size);
-		if (default_lens_shade)
-			qs_s5k4e1_i2c_write_b_table(qs_s5k4e1_regs.
-			reg_default_lens, qs_s5k4e1_regs.reg_default_lens_size);
-		else {
-			qs_s5k4e1_i2c_write_seq_sensor(0x3200,
-				&left_lsc[0], 216);
-			qs_s5k4e1_i2c_write_seq_sensor(0x32D8,
-				&left_lsc[216], 216);
-		}
-		qs_s5k4e1_i2c_write_b_sensor(0x3096, 0x60);
-		qs_s5k4e1_i2c_write_b_sensor(0x3096, 0x40);
-	} else
-		qs_s5k4e1_i2c_write_b_table(ptr, qs_s5k4e1_regs.reg_lens_size);
-	return 0;
-}
-
-static int32_t qs_s5k4e1_write_right_lsc(char *right_lsc, int rt)
-{
-	struct qs_s5k4e1_i2c_reg_conf *ptr = (struct qs_s5k4e1_i2c_reg_conf *)
-		(qs_s5k4e1_regs.reg_lens + rt);
-	bridge_i2c_write_w(0x06, 0x01);
-	if (!LENS_SHADE_CONFIG) {
-		qs_s5k4e1_i2c_write_b_sensor(0x3096, 0x40);
-		qs_s5k4e1_i2c_write_b_table(ptr, qs_s5k4e1_regs.reg_lens_size);
-		if (default_lens_shade)
-			qs_s5k4e1_i2c_write_b_table(qs_s5k4e1_regs.
-			reg_default_lens, qs_s5k4e1_regs.reg_default_lens_size);
-		else {
-			qs_s5k4e1_i2c_write_seq_sensor(0x3200,
-				&right_lsc[0], 216);
-			qs_s5k4e1_i2c_write_seq_sensor(0x32D8,
-				&right_lsc[216], 216);
-		}
-		qs_s5k4e1_i2c_write_b_sensor(0x3096, 0x60);
-		qs_s5k4e1_i2c_write_b_sensor(0x3096, 0x40);
-	} else
-		qs_s5k4e1_i2c_write_b_table(ptr, qs_s5k4e1_regs.reg_lens_size);
-	return 0;
-}
-
-static int32_t qs_s5k4e1_write_lsc(char *lsc, int rt)
-{
-	if (qs_s5k4e1_ctrl->cam_mode == MODE_3D) {
-		qs_s5k4e1_write_left_lsc(&lsc[0], rt);
-		qs_s5k4e1_write_right_lsc(&lsc[432], rt);
-		bridge_i2c_write_w(0x06, 0x03);
-	} else if (qs_s5k4e1_ctrl->cam_mode == MODE_2D_LEFT)
-		qs_s5k4e1_write_left_lsc(&lsc[0], rt);
-	else if (qs_s5k4e1_ctrl->cam_mode == MODE_2D_RIGHT)
-		qs_s5k4e1_write_right_lsc(&lsc[432], rt);
-	return 0;
-}
-
-static int32_t qs_s5k4e1_read_left_lsc(char *left_lsc)
-{
-	qs_s5k4e1_eeprom_i2c_read(0x200, &left_lsc[0], 216);
-	qs_s5k4e1_eeprom_i2c_read(0x2D8, &left_lsc[216], 216);
-	return 0;
-}
-
-static int32_t qs_s5k4e1_read_right_lsc(char *right_lsc)
-{
-	qs_s5k4e1_eeprom_i2c_read(0x3B0, &right_lsc[0], 216);
-	qs_s5k4e1_eeprom_i2c_read(0x488, &right_lsc[216], 216);
-	return 0;
-}
-
-static int32_t qs_s5k4e1_read_lsc(char *lsc)
-{
-	qs_s5k4e1_read_left_lsc(&lsc[0]);
-	qs_s5k4e1_read_right_lsc(&lsc[432]);
-	return 0;
-}
-
-static int32_t qs_s5k4e1_bridge_reset(void){
-	unsigned short RegData = 0, GPIOInState = 0;
-	int32_t rc = 0;
-	rc = bridge_i2c_write_w(0x50, 0x00);
-	if (rc < 0)
-		goto bridge_fail;
-	rc = bridge_i2c_write_w(0x53, 0x00);
-	if (rc < 0)
-		goto bridge_fail;
-	msleep(30);
-	rc = bridge_i2c_write_w(0x53, 0x01);
-	if (rc < 0)
-		goto bridge_fail;
-	msleep(30);
-	rc = bridge_i2c_write_w(0x0E, 0xFFFF);
-	if (rc < 0)
-		goto err;
-	rc = bridge_i2c_read(0x54, &RegData, 2);
-	if (rc < 0)
-		goto err;
-	rc = bridge_i2c_write_w(0x54, (RegData | 0x1));
-	if (rc < 0)
-		goto err;
-	msleep(30);
-	rc = bridge_i2c_read(0x54, &RegData, 2);
-	if (rc < 0)
-		goto err;
-	rc = bridge_i2c_write_w(0x54, (RegData | 0x4));
-	if (rc < 0)
-		goto err;
-	rc = bridge_i2c_read(0x55, &GPIOInState, 2);
-	if (rc < 0)
-		goto err;
-	rc = bridge_i2c_write_w(0x55, (GPIOInState | 0x1));
-	if (rc < 0)
-		goto err;
-	msleep(30);
-	rc = bridge_i2c_read(0x55, &GPIOInState, 2);
-	if (rc < 0)
-		goto err;
-	rc = bridge_i2c_write_w(0x55, (GPIOInState | 0x4));
-	if (rc < 0)
-		goto err;
-	msleep(30);
-	rc = bridge_i2c_read(0x55, &GPIOInState, 2);
-	if (rc < 0)
-		goto err;
-	GPIOInState = ((GPIOInState >> 4) & 0x1);
-
-	rc = bridge_i2c_read(0x08, &GPIOInState, 2);
-	if (rc < 0)
-		goto err;
-	rc = bridge_i2c_write_w(0x08, GPIOInState | 0x4000);
-	if (rc < 0)
-		goto err;
-	return rc;
-
-err:
-	bridge_i2c_write_w(0x53, 0x00);
-	msleep(30);
-
-bridge_fail:
-	return rc;
-
-}
-
-static void qs_s5k4e1_bridge_config(int mode, int rt)
-{
-	unsigned short RegData = 0;
-	if (mode == MODE_3D) {
-		bridge_i2c_read(0x54, &RegData, 2);
-		bridge_i2c_write_w(0x54, (RegData | 0x2));
-		bridge_i2c_write_w(0x54, (RegData | 0xa));
-		bridge_i2c_read(0x55, &RegData, 2);
-		bridge_i2c_write_w(0x55, (RegData | 0x2));
-		bridge_i2c_write_w(0x55, (RegData | 0xa));
-		bridge_i2c_write_w(0x14, 0x0C);
-		msleep(20);
-		bridge_i2c_write_w(0x16, 0x00);
-		bridge_i2c_write_w(0x51, 0x3);
-		bridge_i2c_write_w(0x52, 0x1);
-		bridge_i2c_write_w(0x06, 0x03);
-		bridge_i2c_write_w(0x04, 0x2018);
-		bridge_i2c_write_w(0x50, 0x00);
-	} else if (mode == MODE_2D_RIGHT) {
-		bridge_i2c_read(0x54, &RegData, 2);
-		RegData |= 0x2;
-		bridge_i2c_write_w(0x54, RegData);
-		bridge_i2c_write_w(0x54, (RegData & ~(0x8)));
-		bridge_i2c_read(0x55, &RegData, 2);
-		RegData |= 0x2;
-		bridge_i2c_write_w(0x55, RegData);
-		bridge_i2c_write_w(0x55, (RegData & ~(0x8)));
-		bridge_i2c_write_w(0x14, 0x04);
-		msleep(20);
-		bridge_i2c_write_w(0x51, 0x3);
-		bridge_i2c_write_w(0x06, 0x01);
-		bridge_i2c_write_w(0x04, 0x2018);
-		bridge_i2c_write_w(0x50, 0x01);
-	} else if (mode == MODE_2D_LEFT) {
-		bridge_i2c_read(0x54, &RegData, 2);
-		RegData |= 0x8;
-		bridge_i2c_write_w(0x54, RegData);
-		bridge_i2c_write_w(0x54, (RegData & ~(0x2)));
-		bridge_i2c_read(0x55, &RegData, 2);
-		RegData |= 0x8;
-		bridge_i2c_write_w(0x55, RegData);
-		bridge_i2c_write_w(0x55, (RegData & ~(0x2)));
-		bridge_i2c_write_w(0x14, 0x08);
-		msleep(20);
-		bridge_i2c_write_w(0x51, 0x3);
-		bridge_i2c_write_w(0x06, 0x02);
-		bridge_i2c_write_w(0x04, 0x2018);
-		bridge_i2c_write_w(0x50, 0x02);
-	}
-}
-
-static void qs_s5k4e1_group_hold_on(void)
-{
-	qs_s5k4e1_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
-						GROUPED_PARAMETER_HOLD);
-}
-
-static void qs_s5k4e1_group_hold_off(void)
-{
-	qs_s5k4e1_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
-						GROUPED_PARAMETER_HOLD_OFF);
-}
-
-static void qs_s5k4e1_start_stream(void)
-{
-	qs_s5k4e1_i2c_write_b_sensor(0x0100, 0x01);
-}
-
-static void qs_s5k4e1_stop_stream(void)
-{
-	qs_s5k4e1_i2c_write_b_sensor(0x0100, 0x00);
-}
-
-static void qs_s5k4e1_get_pict_fps(uint16_t fps, uint16_t *pfps)
-{
-	/* input fps is preview fps in Q8 format */
-	uint32_t divider, d1, d2;
-
-	d1 = prev_frame_length_lines * 0x00000400 / snap_frame_length_lines;
-	d2 = prev_line_length_pck * 0x00000400 / snap_line_length_pck;
-	divider = d1 * d2 / 0x400;
-
-	/*Verify PCLK settings and frame sizes.*/
-	*pfps = (uint16_t) (fps * divider / 0x400);
-	/* 2 is the ratio of no.of snapshot channels
-	to number of preview channels */
-}
-
-static uint16_t qs_s5k4e1_get_prev_lines_pf(void)
-{
-
-	return prev_frame_length_lines;
-
-}
-
-static uint16_t qs_s5k4e1_get_prev_pixels_pl(void)
-{
-	return prev_line_length_pck;
-
-}
-
-static uint16_t qs_s5k4e1_get_pict_lines_pf(void)
-{
-	return snap_frame_length_lines;
-}
-
-static uint16_t qs_s5k4e1_get_pict_pixels_pl(void)
-{
-	return snap_line_length_pck;
-}
-
-
-static uint32_t qs_s5k4e1_get_pict_max_exp_lc(void)
-{
-	return snap_frame_length_lines  * 24;
-}
-
-static int32_t qs_s5k4e1_set_fps(struct fps_cfg   *fps)
-{
-	uint16_t total_lines_per_frame;
-	int32_t rc = 0;
-	qs_s5k4e1_ctrl->fps_divider = fps->fps_div;
-	qs_s5k4e1_ctrl->pict_fps_divider = fps->pict_fps_div;
-	if (qs_s5k4e1_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
-		total_lines_per_frame = (uint16_t)
-		((prev_frame_length_lines) * qs_s5k4e1_ctrl->fps_divider/0x400);
-	} else {
-		total_lines_per_frame = (uint16_t)
-		((snap_frame_length_lines) *
-			qs_s5k4e1_ctrl->pict_fps_divider/0x400);
-	}
-	qs_s5k4e1_group_hold_on();
-	rc = qs_s5k4e1_i2c_write_w_sensor(REG_FRAME_LENGTH_LINES,
-							total_lines_per_frame);
-	qs_s5k4e1_group_hold_off();
-	return rc;
-}
-
-static int32_t qs_s5k4e1_write_exp_gain(struct sensor_3d_exp_cfg exp_cfg)
-{
-	uint16_t max_legal_gain = 0x0200;
-	uint32_t ll_pck, fl_lines;
-	uint16_t gain = exp_cfg.gain;
-	uint32_t line = exp_cfg.line;
-	int32_t rc = 0;
-	if (gain > max_legal_gain) {
-		CDBG("Max legal gain Line:%d\n", __LINE__);
-		gain = max_legal_gain;
-	}
-	CDBG("qs_s5k4e1_write_exp_gain : gain = %d line = %d\n", gain, line);
-
-	if (qs_s5k4e1_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
-		qs_s5k4e1_ctrl->my_reg_gain = gain;
-		qs_s5k4e1_ctrl->my_reg_line_count = (uint16_t) line;
-		fl_lines = prev_frame_length_lines *
-			qs_s5k4e1_ctrl->fps_divider / 0x400;
-		ll_pck = prev_line_length_pck;
-	} else {
-		fl_lines = snap_frame_length_lines *
-			qs_s5k4e1_ctrl->pict_fps_divider / 0x400;
-		ll_pck = snap_line_length_pck;
-	}
-	if (line > (fl_lines - QS_S5K4E1_OFFSET))
-		fl_lines = line + QS_S5K4E1_OFFSET;
-	qs_s5k4e1_group_hold_on();
-	rc = qs_s5k4e1_i2c_write_w_sensor(REG_GLOBAL_GAIN, gain);
-	rc = qs_s5k4e1_i2c_write_w_sensor(REG_FRAME_LENGTH_LINES, fl_lines);
-	rc = qs_s5k4e1_i2c_write_w_sensor(REG_COARSE_INTEGRATION_TIME, line);
-	if ((qs_s5k4e1_ctrl->cam_mode == MODE_3D) && (cali_data_status == 1)) {
-		bridge_i2c_write_w(0x06, 0x01);
-		rc = qs_s5k4e1_i2c_write_w_sensor(REG_GLOBAL_GAIN,
-			 exp_cfg.gain_adjust);
-		rc = qs_s5k4e1_i2c_write_w_sensor(REG_GR_GAIN, exp_cfg.gr_gain);
-		rc = qs_s5k4e1_i2c_write_w_sensor(REG_R_GAIN,
-				exp_cfg.r_gain);
-		rc = qs_s5k4e1_i2c_write_w_sensor(REG_B_GAIN,
-				exp_cfg.b_gain);
-		rc = qs_s5k4e1_i2c_write_w_sensor(REG_GB_GAIN,
-				exp_cfg.gb_gain);
-		bridge_i2c_write_w(0x06, 0x03);
-	}
-	qs_s5k4e1_group_hold_off();
-	return rc;
-}
-
-static int32_t qs_s5k4e1_set_pict_exp_gain(struct sensor_3d_exp_cfg exp_cfg)
-{
-	int32_t rc = 0;
-	rc = qs_s5k4e1_write_exp_gain(exp_cfg);
-	return rc;
-}
-
-static int32_t qs_s5k4e1_write_focus_value(uint16_t code_value)
-{
-	uint8_t code_val_msb, code_val_lsb;
-	if ((qs_s5k4e1_ctrl->cam_mode == MODE_2D_LEFT) ||
-		(qs_s5k4e1_ctrl->cam_mode == MODE_3D)) {
-		/* Left */
-		bridge_i2c_write_w(0x06, 0x02);
-		CDBG("%s: Left Lens Position: %d\n", __func__,
-			code_value);
-		code_val_msb = code_value >> 4;
-		code_val_lsb = (code_value & 0x000F) << 4;
-		code_val_lsb |= qs_s5k4e1_af_mode;
-		if (af_i2c_write_b_sensor(code_val_msb, code_val_lsb) < 0) {
-			CDBG("move_focus failed at line %d ...\n", __LINE__);
-			return -EBUSY;
-		}
-	}
-
-	if ((qs_s5k4e1_ctrl->cam_mode == MODE_2D_RIGHT) ||
-		(qs_s5k4e1_ctrl->cam_mode == MODE_3D)) {
-		/* Right */
-		bridge_i2c_write_w(0x06, 0x01);
-		code_value += qs_s5k4e1_af_right_adjust;
-		CDBG("%s: Right Lens Position: %d\n", __func__,
-			code_value);
-		code_val_msb = code_value >> 4;
-		code_val_lsb = (code_value & 0x000F) << 4;
-		code_val_lsb |= qs_s5k4e1_af_mode;
-		if (af_i2c_write_b_sensor(code_val_msb, code_val_lsb) < 0) {
-			CDBG("move_focus failed at line %d ...\n", __LINE__);
-			return -EBUSY;
-		}
-	}
-
-	if (qs_s5k4e1_ctrl->cam_mode == MODE_3D) {
-		/* 3D Mode */
-		bridge_i2c_write_w(0x06, 0x03);
-	}
-	usleep(qs_s5k4e1_sw_damping_time_wait*50);
-	return 0;
-}
-
-static int32_t qs_s5k4e1_write_1D_focus_value(uint16_t code_value)
-{
-	uint8_t code_val_msb, code_val_lsb;
-	CDBG("%s: Lens Position: %d\n", __func__, code_value);
-	code_val_msb = code_value >> 4;
-	code_val_lsb = (code_value & 0x000F) << 4;
-	code_val_lsb |= qs_s5k4e1_af_mode;
-	if (af_i2c_write_b_sensor(code_val_msb, code_val_lsb) < 0) {
-		CDBG("move_focus failed at line %d ...\n", __LINE__);
-		return -EBUSY;
-	}
-
-	usleep(qs_s5k4e1_sw_damping_time_wait*50);
-	return 0;
-}
-
-static int32_t qs_s5k4e1_move_focus(int direction,
-	int32_t num_steps)
-{
-	int16_t step_direction, actual_step, dest_lens_position,
-		dest_step_position;
-	int16_t max_step_postion = QS_S5K4E1_TOTAL_STEPS_NEAR_TO_FAR;
-	CDBG("Inside %s\n", __func__);
-	if (direction == MOVE_NEAR)
-		step_direction = 1;
-	else
-		step_direction = -1;
-
-	actual_step = (int16_t) (step_direction * (int16_t) num_steps);
-	dest_step_position = (int16_t) (qs_s5k4e1_ctrl->curr_step_pos +
-		actual_step);
-
-	if (qs_s5k4e1_ctrl->cam_mode == MODE_3D)
-		max_step_postion = QS_S5K4E1_TOTAL_STEPS_3D;
-
-	if (dest_step_position > max_step_postion)
-		dest_step_position = max_step_postion;
-	else if (dest_step_position < 0)
-		dest_step_position = 0;
-
-	if (dest_step_position == qs_s5k4e1_ctrl->curr_step_pos) {
-		CDBG("%s cur and dest pos are same\n", __func__);
-		CDBG("%s cur_step_pos:%d\n", __func__,
-			qs_s5k4e1_ctrl->curr_step_pos);
-		return 0;
-	}
-
-	if (step_direction < 0) {
-		if (num_steps >= 20) {
-			/* sweeping towards all the way in infinity direction */
-			qs_s5k4e1_af_mode = 2;
-			qs_s5k4e1_sw_damping_time_wait = 8;
-		} else if (num_steps <= 4) {
-			/* reverse search during macro mode */
-			qs_s5k4e1_af_mode = 4;
-			qs_s5k4e1_sw_damping_time_wait = 16;
-		} else {
-			qs_s5k4e1_af_mode = 3;
-			qs_s5k4e1_sw_damping_time_wait = 12;
-		}
-	} else {
-		/* coarse search towards macro direction */
-		qs_s5k4e1_af_mode = 4;
-		qs_s5k4e1_sw_damping_time_wait = 16;
-	}
-
-	if (qs_s5k4e1_ctrl->cam_mode == MODE_3D) {
-		/* Left */
-		bridge_i2c_write_w(0x06, 0x02);
-		dest_lens_position =
-			qs_s5k4e1_step_position_table_left[dest_step_position];
-		if (qs_s5k4e1_write_1D_focus_value(dest_lens_position) < 0) {
-			CDBG("move_focus failed at line %d ...\n", __LINE__);
-			bridge_i2c_write_w(0x06, 0x03);
-			return -EBUSY;
-		}
-		/* Keep left sensor as reference as AF stats is from left */
-		qs_s5k4e1_ctrl->curr_step_pos = dest_step_position;
-		qs_s5k4e1_ctrl->curr_lens_pos = dest_lens_position;
-
-		/* Right */
-		bridge_i2c_write_w(0x06, 0x01);
-		dest_lens_position =
-			qs_s5k4e1_step_position_table_right[dest_step_position];
-		if (qs_s5k4e1_write_1D_focus_value(dest_lens_position) < 0) {
-			CDBG("move_focus failed at line %d ...\n", __LINE__);
-			bridge_i2c_write_w(0x06, 0x03);
-			return -EBUSY;
-		}
-
-		/* 3D Mode */
-		bridge_i2c_write_w(0x06, 0x03);
-		return 0;
-	}
-
-	dest_lens_position = qs_s5k4e1_step_position_table[dest_step_position];
-	CDBG("%s: Step Position: %d\n", __func__, dest_step_position);
-	if (qs_s5k4e1_ctrl->curr_lens_pos != dest_lens_position) {
-		if (qs_s5k4e1_write_focus_value(dest_lens_position) < 0) {
-			CDBG("move_focus failed at line %d ...\n", __LINE__);
-			return -EBUSY;
-		}
-	}
-
-	qs_s5k4e1_ctrl->curr_step_pos = dest_step_position;
-	qs_s5k4e1_ctrl->curr_lens_pos = dest_lens_position;
-	return 0;
-}
-
-static int32_t qs_s5k4e1_set_default_focus(uint8_t af_step)
-{
-	int32_t rc = 0;
-	if (qs_s5k4e1_ctrl->curr_step_pos) {
-		rc = qs_s5k4e1_move_focus(MOVE_FAR,
-			qs_s5k4e1_ctrl->curr_step_pos);
-		if (rc < 0)
-			return rc;
-	} else {
-		if (qs_s5k4e1_ctrl->cam_mode == MODE_3D) {
-			/* Left */
-			bridge_i2c_write_w(0x06, 0x02);
-			rc = qs_s5k4e1_write_1D_focus_value(
-				qs_s5k4e1_step_position_table_left[0]);
-			if (rc < 0) {
-				bridge_i2c_write_w(0x06, 0x03);
-				return rc;
-			}
-
-			/* Right */
-			bridge_i2c_write_w(0x06, 0x01);
-			rc = qs_s5k4e1_write_1D_focus_value(
-				qs_s5k4e1_step_position_table_right[0]);
-			if (rc < 0) {
-				bridge_i2c_write_w(0x06, 0x03);
-				return rc;
-			}
-
-			/* Left sensor is the reference sensor for AF stats */
-			qs_s5k4e1_ctrl->curr_lens_pos =
-				qs_s5k4e1_step_position_table_left[0];
-
-			/* 3D Mode */
-			bridge_i2c_write_w(0x06, 0x03);
-		} else {
-			rc = qs_s5k4e1_write_focus_value(
-				qs_s5k4e1_step_position_table[0]);
-			if (rc < 0)
-				return rc;
-			qs_s5k4e1_ctrl->curr_lens_pos =
-				qs_s5k4e1_step_position_table[0];
-		}
-	}
-	CDBG("%s\n", __func__);
-	return 0;
-}
-
-static void qs_s5k4e1_3d_table_init(void)
-{
-	int16_t af_data = 0;
-	uint16_t step = 8, step_q2 = 8, anchor_point_q2;
-	int32_t rc = 0, i, j;
-	uint16_t eeprom_read_addr[2][3] = {{0x110, 0x114, 0x118},
-		{0x112, 0x116, 0x11A} };
-	uint16_t *step_position_table;
-
-	step_position_table = qs_s5k4e1_step_position_table_left;
-	for (j = 0; j < 2; j++) {
-		rc = qs_s5k4e1_eeprom_i2c_read_b(eeprom_read_addr[j][0],
-			&af_data, 2);
-		if (rc == 0) {
-			CDBG("%s: Far data - %d\n", __func__, af_data);
-			step_position_table[0] = af_data;
-		} else {
-			CDBG("%s: EEPROM data read error\n", __func__);
-			return;
-		}
-
-		rc = qs_s5k4e1_eeprom_i2c_read_b(eeprom_read_addr[j][1],
-			&af_data, 2);
-		if (rc == 0) {
-			CDBG("%s: Medium data - %d\n", __func__, af_data);
-			step_position_table[2] = af_data;
-		} else {
-			CDBG("%s: EEPROM data read error\n", __func__);
-			return;
-		}
-
-		/*
-		 * Using the 150cm and 100cm calibration values
-		 * as per the Lens characteristics derive intermediate step
-		 */
-		step_position_table[1] = step_position_table[0] +
-			(step_position_table[2] - step_position_table[0])/2;
-		CDBG("%s: Step between 150cm:100cm is %d\n", __func__,
-			step_position_table[1]);
-
-		rc = qs_s5k4e1_eeprom_i2c_read_b(eeprom_read_addr[j][2],
-			&af_data, 2);
-		if (rc == 0) {
-			CDBG("%s: Short data - %d\n", __func__, af_data);
-			step_position_table[6] = af_data;
-		} else {
-			CDBG("%s: EEPROM data read error\n", __func__);
-			return;
-		}
-
-		/*
-		 * Using the 100cm and 50cm calibration values
-		 * as per the Lens characteristics derive
-		 * intermediate steps
-		 */
-		step = (step_position_table[6] - step_position_table[2])/4;
-
-		/*
-		 * Interpolate the intermediate steps between 100cm
-		 * to 50cm based on COC1.5
-		 */
-		step_position_table[3] = step_position_table[2] + step;
-		step_position_table[4] = step_position_table[3] + step;
-		step_position_table[5] = step_position_table[4] + step;
-
-		/*
-		 * Extrapolate the steps within 50cm based on
-		 * OC2 to converge faster. This range is beyond the 3D
-		 * specification of 50cm
-		 */
-		anchor_point_q2 = step_position_table[6] << 1;
-		step_q2 = (step_position_table[6] - step_position_table[2]);
-
-		for (i = 7; i < QS_S5K4E1_TOTAL_STEPS_3D; i++) {
-			anchor_point_q2 += step_q2;
-			step_position_table[i] = anchor_point_q2 >> 1;
-		}
-		step_position_table = qs_s5k4e1_step_position_table_right;
-	}
-}
-
-static void qs_s5k4e1_init_focus(void)
-{
-	uint8_t i;
-	int32_t rc = 0;
-	int16_t af_far_data = 0;
-	qs_s5k4e1_af_initial_code = 190;
-	/* Read the calibration data from left and right sensors if available */
-	rc = qs_s5k4e1_eeprom_i2c_read_b(0x110, &af_far_data, 2);
-	if (rc == 0) {
-		CDBG("%s: Left Far data - %d\n", __func__, af_far_data);
-		qs_s5k4e1_af_initial_code = af_far_data;
-	}
-
-	rc = qs_s5k4e1_eeprom_i2c_read_b(0x112, &af_far_data, 2);
-	if (rc == 0) {
-		CDBG("%s: Right Far data - %d\n", __func__, af_far_data);
-		qs_s5k4e1_af_right_adjust = af_far_data -
-			qs_s5k4e1_af_initial_code;
-	}
-
-	qs_s5k4e1_3d_table_init();
-
-	qs_s5k4e1_step_position_table[0] = qs_s5k4e1_af_initial_code;
-	for (i = 1; i <= QS_S5K4E1_TOTAL_STEPS_NEAR_TO_FAR; i++) {
-		if (i <= qs_s5k4e1_nl_region_boundary1) {
-			qs_s5k4e1_step_position_table[i] =
-				qs_s5k4e1_step_position_table[i-1]
-				+ qs_s5k4e1_nl_region_code_per_step1;
-		} else {
-			qs_s5k4e1_step_position_table[i] =
-				qs_s5k4e1_step_position_table[i-1]
-				+ qs_s5k4e1_l_region_code_per_step;
-		}
-
-		if (qs_s5k4e1_step_position_table[i] > 1023)
-			qs_s5k4e1_step_position_table[i] = 1023;
-	}
-	qs_s5k4e1_ctrl->curr_step_pos = 0;
-}
-
-static int32_t qs_s5k4e1_test(enum qs_s5k4e1_test_mode_t mo)
-{
-	int32_t rc = 0;
-	if (mo == TEST_OFF)
-		return rc;
-	else {
-		/* REG_0x30D8[4] is TESBYPEN: 0: Normal Operation,
-		1: Bypass Signal Processing
-		REG_0x30D8[5] is EBDMASK: 0:
-		Output Embedded data, 1: No output embedded data */
-		if (qs_s5k4e1_i2c_write_b_sensor(REG_TEST_PATTERN_MODE,
-			(uint8_t) mo) < 0) {
-			return rc;
-		}
-	}
-	return rc;
-}
-
-static int32_t qs_s5k4e1_sensor_setting(int update_type, int rt)
-{
-
-	int32_t rc = 0;
-	struct msm_camera_csi_params qs_s5k4e1_csi_params;
-
-	qs_s5k4e1_stop_stream();
-	msleep(80);
-	bridge_i2c_write_w(0x53, 0x00);
-	msleep(80);
-	if (update_type == REG_INIT) {
-		CSI_CONFIG = 0;
-		LENS_SHADE_CONFIG = 0;
-		default_lens_shade = 0;
-		bridge_i2c_write_w(0x53, 0x01);
-		msleep(30);
-		qs_s5k4e1_bridge_config(qs_s5k4e1_ctrl->cam_mode, rt);
-		msleep(30);
-		qs_s5k4e1_i2c_write_b_table(qs_s5k4e1_regs.rec_settings,
-				qs_s5k4e1_regs.rec_size);
-		msleep(30);
-	} else if (update_type == UPDATE_PERIODIC) {
-		qs_s5k4e1_write_lsc(lens_eeprom_data, rt);
-		msleep(100);
-		if (!CSI_CONFIG) {
-			if (qs_s5k4e1_ctrl->cam_mode == MODE_3D) {
-				qs_s5k4e1_csi_params.lane_cnt = 4;
-				qs_s5k4e1_csi_params.data_format = CSI_8BIT;
-			} else {
-				qs_s5k4e1_csi_params.lane_cnt = 1;
-				qs_s5k4e1_csi_params.data_format = CSI_10BIT;
-			}
-			qs_s5k4e1_csi_params.lane_assign = 0xe4;
-			qs_s5k4e1_csi_params.dpcm_scheme = 0;
-			qs_s5k4e1_csi_params.settle_cnt = 28;
-			rc = msm_camio_csi_config(&qs_s5k4e1_csi_params);
-			msleep(10);
-			cam_debug_init();
-			CSI_CONFIG = 1;
-		}
-		bridge_i2c_write_w(0x53, 0x01);
-		msleep(50);
-		qs_s5k4e1_i2c_write_b_table(qs_s5k4e1_regs.conf_array[rt].conf,
-			qs_s5k4e1_regs.conf_array[rt].size);
-		msleep(50);
-		qs_s5k4e1_start_stream();
-		msleep(80);
-	}
-	return rc;
-}
-
-static int32_t qs_s5k4e1_video_config(int mode)
-{
-
-	int32_t rc = 0;
-	/* change sensor resolution if needed */
-	if (qs_s5k4e1_sensor_setting(UPDATE_PERIODIC,
-			qs_s5k4e1_ctrl->prev_res) < 0)
-		return rc;
-	if (qs_s5k4e1_ctrl->set_test) {
-		if (qs_s5k4e1_test(qs_s5k4e1_ctrl->set_test) < 0)
-			return  rc;
-	}
-
-	qs_s5k4e1_ctrl->curr_res = qs_s5k4e1_ctrl->prev_res;
-	qs_s5k4e1_ctrl->sensormode = mode;
-	return rc;
-}
-
-static int32_t qs_s5k4e1_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-	/*change sensor resolution if needed */
-	if (qs_s5k4e1_ctrl->curr_res != qs_s5k4e1_ctrl->pict_res) {
-		if (qs_s5k4e1_sensor_setting(UPDATE_PERIODIC,
-				qs_s5k4e1_ctrl->pict_res) < 0)
-			return rc;
-	}
-
-	qs_s5k4e1_ctrl->curr_res = qs_s5k4e1_ctrl->pict_res;
-	qs_s5k4e1_ctrl->sensormode = mode;
-	return rc;
-} /*end of qs_s5k4e1_snapshot_config*/
-
-static int32_t qs_s5k4e1_raw_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-	/* change sensor resolution if needed */
-	if (qs_s5k4e1_ctrl->curr_res != qs_s5k4e1_ctrl->pict_res) {
-		if (qs_s5k4e1_sensor_setting(UPDATE_PERIODIC,
-				qs_s5k4e1_ctrl->pict_res) < 0)
-			return rc;
-	}
-
-	qs_s5k4e1_ctrl->curr_res = qs_s5k4e1_ctrl->pict_res;
-	qs_s5k4e1_ctrl->sensormode = mode;
-	return rc;
-} /*end of qs_s5k4e1_raw_snapshot_config*/
-
-static int32_t qs_s5k4e1_mode_init(int mode, struct sensor_init_cfg init_info)
-{
-	int32_t rc = 0;
-	if (mode != qs_s5k4e1_ctrl->cam_mode) {
-		qs_s5k4e1_ctrl->prev_res = init_info.prev_res;
-		qs_s5k4e1_ctrl->pict_res = init_info.pict_res;
-		qs_s5k4e1_ctrl->cam_mode = mode;
-
-		prev_frame_length_lines =
-		((qs_s5k4e1_regs.conf_array[qs_s5k4e1_ctrl->prev_res]\
-			.conf[QS_S5K4E1_FRAME_LENGTH_LINES_H].wdata << 8)
-			| qs_s5k4e1_regs.conf_array[qs_s5k4e1_ctrl->prev_res]\
-			.conf[QS_S5K4E1_FRAME_LENGTH_LINES_L].wdata);
-		prev_line_length_pck =
-		(qs_s5k4e1_regs.conf_array[qs_s5k4e1_ctrl->prev_res]\
-			.conf[QS_S5K4E1_LINE_LENGTH_PCK_H].wdata << 8)
-			| qs_s5k4e1_regs.conf_array[qs_s5k4e1_ctrl->prev_res]\
-			.conf[QS_S5K4E1_LINE_LENGTH_PCK_L].wdata;
-		snap_frame_length_lines =
-		(qs_s5k4e1_regs.conf_array[qs_s5k4e1_ctrl->pict_res]\
-			.conf[QS_S5K4E1_FRAME_LENGTH_LINES_H].wdata << 8)
-			| qs_s5k4e1_regs.conf_array[qs_s5k4e1_ctrl->pict_res]\
-			.conf[QS_S5K4E1_FRAME_LENGTH_LINES_L].wdata;
-		snap_line_length_pck =
-		(qs_s5k4e1_regs.conf_array[qs_s5k4e1_ctrl->pict_res]\
-			.conf[QS_S5K4E1_LINE_LENGTH_PCK_H].wdata << 8)
-			| qs_s5k4e1_regs.conf_array[qs_s5k4e1_ctrl->pict_res]\
-			.conf[QS_S5K4E1_LINE_LENGTH_PCK_L].wdata;
-
-	rc = qs_s5k4e1_sensor_setting(REG_INIT,
-		qs_s5k4e1_ctrl->prev_res);
-	}
-	return rc;
-}
-static int32_t qs_s5k4e1_set_sensor_mode(int mode,
-	int res)
-{
-	int32_t rc = 0;
-	switch (mode) {
-	case SENSOR_PREVIEW_MODE:
-		qs_s5k4e1_ctrl->prev_res = res;
-		rc = qs_s5k4e1_video_config(mode);
-		break;
-	case SENSOR_SNAPSHOT_MODE:
-		qs_s5k4e1_ctrl->pict_res = res;
-		rc = qs_s5k4e1_snapshot_config(mode);
-		break;
-	case SENSOR_RAW_SNAPSHOT_MODE:
-		qs_s5k4e1_ctrl->pict_res = res;
-		rc = qs_s5k4e1_raw_snapshot_config(mode);
-		break;
-	default:
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
-
-static int32_t qs_s5k4e1_power_down(void)
-{
-	qs_s5k4e1_stop_stream();
-	msleep(30);
-	qs_s5k4e1_af_mode = 2;
-	qs_s5k4e1_af_right_adjust = 0;
-	qs_s5k4e1_write_focus_value(0);
-	msleep(100);
-	/* Set AF actutator to PowerDown */
-	af_i2c_write_b_sensor(0x80, 00);
-	return 0;
-}
-
-static int qs_s5k4e1_probe_init_done(const struct msm_camera_sensor_info *data)
-{
-	CDBG("probe done\n");
-	gpio_free(data->sensor_reset);
-	return 0;
-}
-
-static int
-	qs_s5k4e1_probe_init_sensor(const struct msm_camera_sensor_info *data)
-{
-	int32_t rc = 0;
-	uint16_t chipid = 0;
-	CDBG("%s: %d\n", __func__, __LINE__);
-	rc = gpio_request(data->sensor_reset, "qs_s5k4e1");
-	CDBG(" qs_s5k4e1_probe_init_sensor\n");
-	if (!rc) {
-		CDBG("sensor_reset = %d\n", rc);
-		gpio_direction_output(data->sensor_reset, 0);
-		msleep(50);
-		gpio_set_value_cansleep(data->sensor_reset, 1);
-		msleep(13);
-	} else {
-		goto init_probe_done;
-	}
-	msleep(70);
-	rc = qs_s5k4e1_bridge_reset();
-	if (rc < 0)
-		goto init_probe_fail;
-	qs_s5k4e1_bridge_config(MODE_3D, RES_PREVIEW);
-	msleep(30);
-
-	CDBG(" qs_s5k4e1_probe_init_sensor is called\n");
-	rc = qs_s5k4e1_i2c_read(0x0000, &chipid, 2);
-	CDBG("ID: %d\n", chipid);
-	/* 4. Compare sensor ID to QS_S5K4E1 ID: */
-	if (chipid != 0x4e10) {
-		rc = -ENODEV;
-		CDBG("qs_s5k4e1_probe_init_sensor fail chip id mismatch\n");
-		goto init_probe_fail;
-	}
-	goto init_probe_done;
-init_probe_fail:
-	CDBG(" qs_s5k4e1_probe_init_sensor fails\n");
-	gpio_set_value_cansleep(data->sensor_reset, 0);
-	qs_s5k4e1_probe_init_done(data);
-init_probe_done:
-	CDBG(" qs_s5k4e1_probe_init_sensor finishes\n");
-	return rc;
-}
-/* camsensor_qs_s5k4e1_reset */
-
-int qs_s5k4e1_sensor_open_init(const struct msm_camera_sensor_info *data)
-{
-	int32_t rc = 0;
-	CDBG("%s: %d\n", __func__, __LINE__);
-	CDBG("Calling qs_s5k4e1_sensor_open_init\n");
-
-	qs_s5k4e1_ctrl = kzalloc(sizeof(struct qs_s5k4e1_ctrl_t), GFP_KERNEL);
-	if (!qs_s5k4e1_ctrl) {
-		CDBG("qs_s5k4e1_init failed!\n");
-		rc = -ENOMEM;
-		goto init_done;
-	}
-	qs_s5k4e1_ctrl->fps_divider = 1 * 0x00000400;
-	qs_s5k4e1_ctrl->pict_fps_divider = 1 * 0x00000400;
-	qs_s5k4e1_ctrl->set_test = TEST_OFF;
-	qs_s5k4e1_ctrl->cam_mode = MODE_INVALID;
-
-	if (data)
-		qs_s5k4e1_ctrl->sensordata = data;
-	if (rc < 0) {
-		CDBG("Calling qs_s5k4e1_sensor_open_init fail1\n");
-		return rc;
-	}
-	CDBG("%s: %d\n", __func__, __LINE__);
-	/* enable mclk first */
-	msm_camio_clk_rate_set(QS_S5K4E1_MASTER_CLK_RATE);
-	rc = qs_s5k4e1_probe_init_sensor(data);
-	if (rc < 0)
-		goto init_fail;
-/*Default mode is 3D*/
-	memcpy(lens_eeprom_data, data->eeprom_data, 864);
-	qs_s5k4e1_ctrl->fps = 30*Q8;
-	qs_s5k4e1_init_focus();
-	if (rc < 0) {
-		gpio_set_value_cansleep(data->sensor_reset, 0);
-		goto init_fail;
-	} else
-		goto init_done;
-init_fail:
-	CDBG("init_fail\n");
-	qs_s5k4e1_probe_init_done(data);
-init_done:
-	CDBG("init_done\n");
-	return rc;
-} /*endof qs_s5k4e1_sensor_open_init*/
-
-static int qs_s5k4e1_init_client(struct i2c_client *client)
-{
-	/* Initialize the MSM_CAMI2C Chip */
-	init_waitqueue_head(&qs_s5k4e1_wait_queue);
-	return 0;
-}
-
-static const struct i2c_device_id qs_s5k4e1_i2c_id[] = {
-	{"qs_s5k4e1", 0},
-	{ }
-};
-
-static int qs_s5k4e1_i2c_probe(struct i2c_client *client,
-	const struct i2c_device_id *id)
-{
-	int rc = 0;
-	CDBG("qs_s5k4e1_probe called!\n");
-
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		CDBG("i2c_check_functionality failed\n");
-		goto probe_failure;
-	}
-
-	qs_s5k4e1_sensorw = kzalloc(sizeof(struct qs_s5k4e1_work_t),
-		 GFP_KERNEL);
-	if (!qs_s5k4e1_sensorw) {
-		CDBG("kzalloc failed.\n");
-		rc = -ENOMEM;
-		goto probe_failure;
-	}
-
-	i2c_set_clientdata(client, qs_s5k4e1_sensorw);
-	qs_s5k4e1_init_client(client);
-	qs_s5k4e1_client = client;
-
-	msleep(50);
-
-	CDBG("qs_s5k4e1_probe successed! rc = %d\n", rc);
-	return 0;
-
-probe_failure:
-	CDBG("qs_s5k4e1_probe failed! rc = %d\n", rc);
-	return rc;
-}
-
-static int qs_s5k4e1_send_wb_info(struct wb_info_cfg *wb)
-{
-	return 0;
-
-} /*end of qs_s5k4e1_snapshot_config*/
-
-static int __exit qs_s5k4e1_remove(struct i2c_client *client)
-{
-	struct qs_s5k4e1_work_t_t *sensorw = i2c_get_clientdata(client);
-	free_irq(client->irq, sensorw);
-	qs_s5k4e1_client = NULL;
-	kfree(sensorw);
-	return 0;
-}
-
-static struct i2c_driver qs_s5k4e1_i2c_driver = {
-	.id_table = qs_s5k4e1_i2c_id,
-	.probe  = qs_s5k4e1_i2c_probe,
-	.remove = __exit_p(qs_s5k4e1_i2c_remove),
-	.driver = {
-		.name = "qs_s5k4e1",
-	},
-};
-
-int qs_s5k4e1_3D_sensor_config(void __user *argp)
-{
-	struct sensor_large_data cdata;
-	long rc;
-	if (copy_from_user(&cdata,
-		(void *)argp,
-		sizeof(struct sensor_large_data)))
-		return -EFAULT;
-	mutex_lock(&qs_s5k4e1_mut);
-	rc = qs_s5k4e1_get_calibration_data
-		(&cdata.data.sensor_3d_cali_data);
-	if (rc < 0)
-		goto fail;
-	if (copy_to_user((void *)argp,
-		&cdata,
-		sizeof(struct sensor_large_data)))
-		rc = -EFAULT;
-fail:
-	mutex_unlock(&qs_s5k4e1_mut);
-	return rc;
-}
-
-int qs_s5k4e1_2D_sensor_config(void __user *argp)
-{
-	struct sensor_cfg_data cdata;
-	long   rc = 0;
-	if (copy_from_user(&cdata,
-		(void *)argp,
-		sizeof(struct sensor_cfg_data)))
-		return -EFAULT;
-	mutex_lock(&qs_s5k4e1_mut);
-	CDBG("qs_s5k4e1_sensor_config: cfgtype = %d\n",
-	cdata.cfgtype);
-		switch (cdata.cfgtype) {
-		case CFG_GET_PICT_FPS:
-			qs_s5k4e1_get_pict_fps(
-				cdata.cfg.gfps.prevfps,
-				&(cdata.cfg.gfps.pictfps));
-
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_GET_PREV_L_PF:
-			cdata.cfg.prevl_pf =
-			qs_s5k4e1_get_prev_lines_pf();
-
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_GET_PREV_P_PL:
-			cdata.cfg.prevp_pl =
-				qs_s5k4e1_get_prev_pixels_pl();
-
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_GET_PICT_L_PF:
-			cdata.cfg.pictl_pf =
-				qs_s5k4e1_get_pict_lines_pf();
-
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_GET_PICT_P_PL:
-			cdata.cfg.pictp_pl =
-				qs_s5k4e1_get_pict_pixels_pl();
-
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_GET_PICT_MAX_EXP_LC:
-			cdata.cfg.pict_max_exp_lc =
-				qs_s5k4e1_get_pict_max_exp_lc();
-
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_SET_FPS:
-		case CFG_SET_PICT_FPS:
-			rc = qs_s5k4e1_set_fps(&(cdata.cfg.fps));
-			break;
-
-		case CFG_SET_EXP_GAIN:
-			rc =
-				qs_s5k4e1_write_exp_gain(
-					cdata.cfg.sensor_3d_exp);
-			break;
-
-		case CFG_SET_PICT_EXP_GAIN:
-			rc =
-				qs_s5k4e1_set_pict_exp_gain(
-				cdata.cfg.sensor_3d_exp);
-			break;
-
-		case CFG_SET_MODE:
-			rc = qs_s5k4e1_set_sensor_mode(cdata.mode,
-					cdata.rs);
-			break;
-
-		case CFG_PWR_DOWN:
-			rc = qs_s5k4e1_power_down();
-			break;
-
-		case CFG_MOVE_FOCUS:
-			rc =
-				qs_s5k4e1_move_focus(
-				cdata.cfg.focus.dir,
-				cdata.cfg.focus.steps);
-			break;
-
-		case CFG_SET_DEFAULT_FOCUS:
-			rc =
-				qs_s5k4e1_set_default_focus(
-				cdata.cfg.focus.steps);
-			break;
-
-		case CFG_GET_AF_MAX_STEPS:
-			if (qs_s5k4e1_ctrl->cam_mode == MODE_3D)
-				cdata.max_steps = QS_S5K4E1_TOTAL_STEPS_3D;
-			else
-				cdata.max_steps =
-					QS_S5K4E1_TOTAL_STEPS_NEAR_TO_FAR;
-
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_SET_EFFECT:
-			rc = qs_s5k4e1_set_default_focus(
-				cdata.cfg.effect);
-			break;
-
-
-		case CFG_SEND_WB_INFO:
-			rc = qs_s5k4e1_send_wb_info(
-				&(cdata.cfg.wb_info));
-			break;
-
-		case CFG_SENSOR_INIT:
-			rc = qs_s5k4e1_mode_init(cdata.mode,
-					cdata.cfg.init_info);
-			break;
-
-		default:
-			rc = -EFAULT;
-			break;
-		}
-
-	mutex_unlock(&qs_s5k4e1_mut);
-
-	return rc;
-}
-
-int qs_s5k4e1_sensor_config(void __user *argp)
-{
-	int cfgtype;
-	long rc;
-	if (copy_from_user(&cfgtype,
-		(void *)argp,
-		sizeof(int)))
-		return -EFAULT;
-	if (cfgtype != CFG_GET_3D_CALI_DATA)
-		rc = qs_s5k4e1_2D_sensor_config(argp);
-	else
-		rc = qs_s5k4e1_3D_sensor_config(argp);
-	return rc;
-}
-
-static int qs_s5k4e1_sensor_release(void)
-{
-	int rc = -EBADF;
-	mutex_lock(&qs_s5k4e1_mut);
-	qs_s5k4e1_power_down();
-	bridge_i2c_write_w(0x53, 0x00);
-	msleep(20);
-	gpio_set_value_cansleep(qs_s5k4e1_ctrl->sensordata->sensor_reset, 0);
-	msleep(5);
-	gpio_free(qs_s5k4e1_ctrl->sensordata->sensor_reset);
-	kfree(qs_s5k4e1_ctrl);
-	qs_s5k4e1_ctrl = NULL;
-	CDBG("qs_s5k4e1_release completed\n");
-	mutex_unlock(&qs_s5k4e1_mut);
-
-	return rc;
-}
-
-static int qs_s5k4e1_sensor_probe(const struct msm_camera_sensor_info *info,
-		struct msm_sensor_ctrl *s)
-{
-	int rc = 0;
-	rc = i2c_add_driver(&qs_s5k4e1_i2c_driver);
-	if (rc < 0 || qs_s5k4e1_client == NULL) {
-		rc = -ENOTSUPP;
-		CDBG("I2C add driver failed");
-		goto probe_fail;
-	}
-	msm_camio_clk_rate_set(QS_S5K4E1_MASTER_CLK_RATE);
-	rc = qs_s5k4e1_probe_init_sensor(info);
-	if (rc < 0)
-		goto probe_fail;
-	qs_s5k4e1_read_lsc(info->eeprom_data); /*Default mode is 3D*/
-	s->s_init = qs_s5k4e1_sensor_open_init;
-	s->s_release = qs_s5k4e1_sensor_release;
-	s->s_config  = qs_s5k4e1_sensor_config;
-	s->s_mount_angle = info->sensor_platform_info->mount_angle;
-	s->s_camera_type = BACK_CAMERA_3D;
-	s->s_video_packing = SIDE_BY_SIDE_HALF;
-	s->s_snap_packing = SIDE_BY_SIDE_FULL;
-	bridge_i2c_write_w(0x53, 0x00);
-	msleep(20);
-	gpio_set_value_cansleep(info->sensor_reset, 0);
-	qs_s5k4e1_probe_init_done(info);
-	return rc;
-
-probe_fail:
-	CDBG("qs_s5k4e1_sensor_probe: SENSOR PROBE FAILS!\n");
-	return rc;
-}
-
-static bool streaming = 1;
-
-static int qs_s5k4e1_focus_test(void *data, u64 *val)
-{
-	int i = 0;
-	qs_s5k4e1_set_default_focus(0);
-
-	for (i = 0; i < QS_S5K4E1_TOTAL_STEPS_NEAR_TO_FAR; i++) {
-		qs_s5k4e1_move_focus(MOVE_NEAR, 1);
-		msleep(2000);
-	}
-	msleep(5000);
-	for ( ; i > 0; i--) {
-		qs_s5k4e1_move_focus(MOVE_FAR, 1);
-		msleep(2000);
-	}
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(cam_focus, qs_s5k4e1_focus_test,
-			NULL, "%lld\n");
-
-static int qs_s5k4e1_step_test(void *data, u64 *val)
-{
-	int rc = 0;
-	struct sensor_large_data cdata;
-	rc = qs_s5k4e1_get_calibration_data
-		(&cdata.data.sensor_3d_cali_data);
-	if (rc < 0)
-		CDBG("%s: Calibration data read fail.\n", __func__);
-
-	return 0;
-}
-
-static int qs_s5k4e1_set_step(void *data, u64 val)
-{
-	qs_s5k4e1_l_region_code_per_step = val & 0xFF;
-	qs_s5k4e1_af_mode = (val >> 8) & 0xFF;
-	qs_s5k4e1_nl_region_code_per_step1 = (val >> 16) & 0xFFFF;
-
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(cam_step, qs_s5k4e1_step_test,
-			qs_s5k4e1_set_step, "%lld\n");
-
-static int cam_debug_stream_set(void *data, u64 val)
-{
-	int rc = 0;
-
-	if (val) {
-		qs_s5k4e1_start_stream();
-		streaming = 1;
-	} else {
-		qs_s5k4e1_stop_stream();
-		streaming = 0;
-	}
-
-	return rc;
-}
-
-static int cam_debug_stream_get(void *data, u64 *val)
-{
-	*val = streaming;
-	return 0;
-}
-DEFINE_SIMPLE_ATTRIBUTE(cam_stream, cam_debug_stream_get,
-			cam_debug_stream_set, "%llu\n");
-
-static uint16_t qs_s5k4e1_step_val = QS_S5K4E1_TOTAL_STEPS_NEAR_TO_FAR;
-static uint8_t qs_s5k4e1_step_dir = MOVE_NEAR;
-static int qs_s5k4e1_af_step_config(void *data, u64 val)
-{
-	qs_s5k4e1_step_val = val & 0xFFFF;
-	qs_s5k4e1_step_dir = (val >> 16) & 0x1;
-	CDBG("%s\n", __func__);
-	return 0;
-}
-
-static int qs_s5k4e1_af_step(void *data, u64 *val)
-{
-	int i = 0;
-	int dir = MOVE_NEAR;
-	CDBG("%s\n", __func__);
-	qs_s5k4e1_set_default_focus(0);
-	msleep(5000);
-	if (qs_s5k4e1_step_dir == 1)
-		dir = MOVE_FAR;
-
-	for (i = 0; i < qs_s5k4e1_step_val; i += 4) {
-		qs_s5k4e1_move_focus(dir, 4);
-		msleep(1000);
-	}
-	qs_s5k4e1_set_default_focus(0);
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(af_step, qs_s5k4e1_af_step,
-			qs_s5k4e1_af_step_config, "%llu\n");
-
-static int cam_debug_init(void)
-{
-	struct dentry *cam_dir;
-	debugfs_base = debugfs_create_dir("sensor", NULL);
-	if (!debugfs_base)
-		return -ENOMEM;
-
-	cam_dir = debugfs_create_dir("qs_s5k4e1", debugfs_base);
-	if (!cam_dir)
-		return -ENOMEM;
-
-	if (!debugfs_create_file("focus", S_IRUGO | S_IWUSR, cam_dir,
-							 NULL, &cam_focus))
-		return -ENOMEM;
-	if (!debugfs_create_file("step", S_IRUGO | S_IWUSR, cam_dir,
-							 NULL, &cam_step))
-		return -ENOMEM;
-	if (!debugfs_create_file("stream", S_IRUGO | S_IWUSR, cam_dir,
-							 NULL, &cam_stream))
-		return -ENOMEM;
-	if (!debugfs_create_file("af_step", S_IRUGO | S_IWUSR, cam_dir,
-							 NULL, &af_step))
-		return -ENOMEM;
-	return 0;
-}
-
-static int __qs_s5k4e1_probe(struct platform_device *pdev)
-{
-	return msm_camera_drv_start(pdev, qs_s5k4e1_sensor_probe);
-}
-
-static struct platform_driver msm_camera_driver = {
-	.probe = __qs_s5k4e1_probe,
-	.driver = {
-		.name = "msm_camera_qs_s5k4e1",
-	.owner = THIS_MODULE,
-	},
-};
-
-static int __init qs_s5k4e1_init(void)
-{
-	return platform_driver_register(&msm_camera_driver);
-}
-
-module_init(qs_s5k4e1_init);
-void qs_s5k4e1_exit(void)
-{
-	i2c_del_driver(&qs_s5k4e1_i2c_driver);
-}
-MODULE_DESCRIPTION("Samsung 5MP Bayer sensor driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/qs_s5k4e1.h b/drivers/media/video/msm/qs_s5k4e1.h
deleted file mode 100644
index f9c4c3f..0000000
--- a/drivers/media/video/msm/qs_s5k4e1.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. 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 QS_S5K4E1_H
-#define QS_S5K4E1_H
-#include <linux/types.h>
-#include <mach/board.h>
-extern struct qs_s5k4e1_reg qs_s5k4e1_regs;
-
-#define LENS_SHADE_TABLE 16
-
-struct qs_s5k4e1_i2c_reg_conf {
-	unsigned short waddr;
-	unsigned short wdata;
-};
-
-struct qs_s5k4e1_i2c_conf_array {
-       struct qs_s5k4e1_i2c_reg_conf *conf;
-       unsigned short size;
-};
-
-enum qs_s5k4e1_test_mode_t {
-	TEST_OFF,
-	TEST_1,
-	TEST_2,
-	TEST_3
-};
-
-enum qs_s5k4e1_resolution_t {
-	QTR_2D_SIZE,
-	FULL_2D_SIZE,
-	QTR_3D_SIZE,
-	FULL_3D_SIZE,
-	INVALID_SIZE
-};
-enum qs_s5k4e1_setting {
-	RES_PREVIEW,
-	RES_CAPTURE,
-	RES_3D_PREVIEW,
-	RES_3D_CAPTURE
-};
-enum qs_s5k4e1_cam_mode_t {
-    MODE_2D_RIGHT,
-	MODE_2D_LEFT,
-	MODE_3D,
-	MODE_INVALID
-};
-enum qs_s5k4e1_reg_update {
-	/* Sensor egisters that need to be updated during initialization */
-	REG_INIT,
-	/* Sensor egisters that needs periodic I2C writes */
-	UPDATE_PERIODIC,
-	/* All the sensor Registers will be updated */
-	UPDATE_ALL,
-	/* Not valid update */
-	UPDATE_INVALID
-};
-
-enum qs_s5k4e1_reg_mode {
-	QS_S5K4E1_FRAME_LENGTH_LINES_H = 1,
-	QS_S5K4E1_FRAME_LENGTH_LINES_L,
-	QS_S5K4E1_LINE_LENGTH_PCK_H,
-	QS_S5K4E1_LINE_LENGTH_PCK_L,
-};
-
-struct qs_s5k4e1_reg {
-	const struct qs_s5k4e1_i2c_reg_conf *rec_settings;
-	const unsigned short rec_size;
-	const struct qs_s5k4e1_i2c_reg_conf *reg_prev;
-	const unsigned short reg_prev_size;
-	const struct qs_s5k4e1_i2c_reg_conf *reg_snap;
-	const unsigned short reg_snap_size;
-	const struct qs_s5k4e1_i2c_reg_conf (*reg_lens)[LENS_SHADE_TABLE];
-	const unsigned short reg_lens_size;
-	const struct qs_s5k4e1_i2c_reg_conf *reg_default_lens;
-	const unsigned short reg_default_lens_size;
-	const struct qs_s5k4e1_i2c_conf_array *conf_array;
-};
-#endif /* QS_S5K4E1_H */
diff --git a/drivers/media/video/msm/qs_s5k4e1_reg.c b/drivers/media/video/msm/qs_s5k4e1_reg.c
deleted file mode 100644
index 39c3f29..0000000
--- a/drivers/media/video/msm/qs_s5k4e1_reg.c
+++ /dev/null
@@ -1,804 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. 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 "qs_s5k4e1.h"
-
-struct qs_s5k4e1_i2c_reg_conf qs_s5k4e1_prev_settings_3d[] = {
-	{0x0100, 0x00},
-	/*Frame Length*/
-	{0x0340, 0x04},
-	{0x0341, 0x90},
-	/*Line Length*/
-	{0x0342, 0x0A},
-	{0x0343, 0xB2},
-	{0x3030, 0x06},
-	{0x3017, 0xA4},
-	{0x301B, 0x88},
-	{0x30BC, 0x90},
-	{0x301C, 0x04},
-	{0x0202, 0x04},
-	{0x0203, 0x12},
-	{0x0204, 0x00},
-	{0x0205, 0x80},
-	{0x0306, 0x00},
-	{0x0307, 0x60},
-	{0x30B5, 0x01},
-	{0x30E2, 0x02},/*num lanes[1:0] = 1*/
-	{0x30F1, 0x60},
-/*MIPI Size Setting*/
-	{0x30A9, 0x02},
-	{0x300E, 0xE8},
-	{0x0387, 0x01},
-	{0x0344, 0x01},
-	{0x0345, 0x18},
-	{0x0348, 0x09},
-	{0x0349, 0x17},
-	{0x0346, 0x01},
-	{0x0347, 0x94},
-	{0x034A, 0x06},
-	{0x034B, 0x13},
-	{0x0380, 0x00},
-	{0x0381, 0x01},
-	{0x0382, 0x00},
-	{0x0383, 0x01},
-	{0x0384, 0x00},
-	{0x0385, 0x01},
-	{0x0386, 0x00},
-	{0x0387, 0x01},
-	{0x034C, 0x04},
-	{0x034D, 0x00},
-	{0x034E, 0x04},
-	{0x034F, 0x80},
-	{0x30BF, 0xAA},
-	{0x30C0, 0x40},
-	{0x30C8, 0x04},
-	{0x30C9, 0x00},
-};
-
-struct qs_s5k4e1_i2c_reg_conf qs_s5k4e1_prev_settings_2d[] = {
-	{0x0100, 0x00},
-	{0x0340, 0x03},
-	{0x0341, 0xe0},
-	{0x0342, 0x0A},
-	{0x0343, 0xB2},
-	{0x3030, 0x06},
-	{0x301B, 0x83},
-	{0x30BC, 0x98},
-	{0x301C, 0x04},
-	{0x0202, 0x01},
-	{0x0203, 0xFD},
-	{0x0204, 0x00},
-	{0x0205, 0x80},
-	{0x0306, 0x00},
-	{0x0307, 0x64},
-	{0x30B5, 0x00},
-	{0x30E2, 0x01},/*num lanes[1:0] = 1*/
-	{0x30F1, 0xd0},
-	{0x30A9, 0x02},
-	{0x300E, 0xEB},
-	{0x0387, 0x03},
-	{0x0344, 0x00},
-	{0x0345, 0x00},
-	{0x0348, 0x0A},
-	{0x0349, 0x2F},
-	{0x0346, 0x00},
-	{0x0347, 0x00},
-	{0x034A, 0x07},
-	{0x034B, 0xA7},
-	{0x0380, 0x00},
-	{0x0381, 0x01},
-	{0x0382, 0x00},
-	{0x0383, 0x01},
-	{0x0384, 0x00},
-	{0x0385, 0x01},
-	{0x0386, 0x00},
-	{0x0387, 0x03},
-	{0x034C, 0x05},
-	{0x034D, 0x10},
-	{0x034E, 0x03},
-	{0x034F, 0xd4},
-	{0x30BF, 0xAB},
-	{0x30C0, 0xc0},
-	{0x30C8, 0x06},
-	{0x30C9, 0x54},
-};
-
-struct qs_s5k4e1_i2c_reg_conf qs_s5k4e1_snap_settings_2d[] = {
-	{0x0100, 0x00},
-	{0x0340, 0x07},
-	{0x0341, 0xb4},
-	{0x0342, 0x0A},
-	{0x0343, 0xB2},
-	{0x3030, 0x06}, /*shut streaming off*/
-	{0x300E, 0xE8},
-	{0x301B, 0x75},
-	{0x301C, 0x04},
-	{0x30BC, 0x98},
-	{0x0202, 0x04},
-	{0x0203, 0x12},
-	{0x0204, 0x00},
-	{0x0205, 0x80},
-	{0x0306, 0x00},
-	{0x0307, 0x64},
-	{0x30B5, 0x00},
-	{0x30E2, 0x01},/*num lanes[1:0] = 1*/
-	{0x30F1, 0xd0},
-	{0x30A9, 0x03},/*Horizontal Binning Off*/
-	{0x300E, 0xE8},/*Vertical Binning Off*/
-	{0x0387, 0x01},/*y_odd_inc*/
-	{0x034C, 0x0A},/*x_output size*/
-	{0x034D, 0x30},
-	{0x034E, 0x07},/*y_output size*/
-	{0x034F, 0xA8},
-	{0x30BF, 0xAB},/*outif_enable[7], data_type[5:0](2Bh = bayer 10bit)*/
-	{0x30C0, 0x86},/*video_offset[7:4] 3260%12*/
-	{0x30C8, 0x0C},/*video_data_length 3260 = 2608 * 1.25*/
-	{0x30C9, 0xBC},
-
-};
-
-struct qs_s5k4e1_i2c_reg_conf qs_s5k4e1_snap_settings_3d[] = {
-	{0x0100, 0x00},
-
-/* Frame Length*/
-	{0x0340, 0x09},
-	{0x0341, 0x20},
-/* Line Length*/
-	{0x0342, 0x0A},
-	{0x0343, 0xB2},
-	{0x3030, 0x06},/*shut streaming off*/
-/*Analog Setting*/
-	{0x3017, 0xA4},
-	{0x301B, 0x88},
-	{0x30BC, 0x90},
-	{0x301C, 0x04},
-/*Integration setting ... */
-	{0x0202, 0x04},
-	{0x0203, 0x12},
-	{0x0204, 0x00},
-	{0x0205, 0x80},
-/*PLL setting ...*/
-	{0x0306, 0x00},
-	{0x0307, 0x60},
-	{0x30B5, 0x01},
-	{0x30E2, 0x02},/*num lanes[1:0] = 1*/
-	{0x30F1, 0x60},
-/*MIPI Size Setting*/
-	{0x30A9, 0x01},
-	{0x300E, 0xE8},
-	{0x0387, 0x01},
-	{0x0344, 0x01},/*x_addr_start*/
-	{0x0345, 0x14},
-	{0x0348, 0x09},/*x_addr_end*/
-	{0x0349, 0x17},
-	{0x0346, 0x01},/*y_addr_start*/
-	{0x0347, 0x94},
-	{0x034A, 0x06},/*y_addr_end*/
-	{0x034B, 0x13},
-	{0x0380, 0x00},/*x_even_inc 1*/
-	{0x0381, 0x01},
-	{0x0382, 0x00},/*x_odd_inc 1*/
-	{0x0383, 0x01},
-	{0x0384, 0x00},/*y_even_inc 1*/
-	{0x0385, 0x01},
-	{0x0386, 0x00},/*y_odd_inc 1*/
-	{0x0387, 0x01},
-	{0x034C, 0x08},/*x_output size*/
-	{0x034D, 0x00},
-	{0x034E, 0x04},/*y_output size*/
-	{0x034F, 0x80},
-	{0x30BF, 0xAA},/*outif_enable[7], data_type[5:0](2Bh = bayer 8bit)*/
-	{0x30C0, 0x80},/*video_offset[7:4]*/
-	{0x30C8, 0x08},/*video_data_length*/
-	{0x30C9, 0x00},
-
-};
-
-struct qs_s5k4e1_i2c_reg_conf qs_s5k4e1_recommend_settings[] = {
-	{0x0100, 0x00},
-
-	{0x3030, 0x06},/*shut streaming*/
-/*Analog Setting*/
-	{0x3000, 0x05},
-	{0x3001, 0x03},
-	{0x3002, 0x08},
-	{0x3003, 0x09},
-	{0x3004, 0x2E},
-	{0x3005, 0x06},
-	{0x3006, 0x34},
-	{0x3007, 0x00},
-	{0x3008, 0x3C},
-	{0x3009, 0x3C},
-	{0x300A, 0x28},
-	{0x300B, 0x04},
-	{0x300C, 0x0A},
-	{0x300D, 0x02},
-	{0x300F, 0x82},
-	{0x3010, 0x00},
-	{0x3011, 0x4C},
-	{0x3012, 0x30},
-	{0x3013, 0xC0},
-	{0x3014, 0x00},
-	{0x3015, 0x00},
-	{0x3016, 0x2C},
-	{0x3017, 0x94},
-	{0x3018, 0x78},
-	{0x301D, 0xD4},
-	{0x3021, 0x02},
-	{0x3022, 0x24},
-	{0x3024, 0x40},
-	{0x3027, 0x08},
-	{0x3029, 0xC6},
-	{0x302B, 0x01},
-	{0x30D8, 0x3F},
-/* ADLC setting ...*/
-	{0x3070, 0x5F},
-	{0x3071, 0x00},
-	{0x3080, 0x04},
-	{0x3081, 0x38},
-
-/*MIPI setting*/
-	{0x30BD, 0x00},/*SEL_CCP[0]*/
-	{0x3084, 0x15},/*SYNC Mode*/
-	{0x30BE, 0x1A},/*M_PCLKDIV_AUTO[4], M_DIV_PCLK[3:0]*/
-	{0x30C1, 0x01},/*pack video enable [0]*/
-	{0x30EE, 0x02},/*DPHY enable [1]*/
-	{0x3111, 0x86},/*Embedded data off [5]*/
-/*For MIPI T8 T9*/
-	{0x30E3, 0x38},
-	{0x30E4, 0x40},
-	{0x3113, 0x70},
-	{0x3114, 0x80},
-	{0x3115, 0x7B},
-	{0x3116, 0xC0},
-	{0x30EE, 0x12},
-
-/*PLL setting ...*/
-	{0x0305, 0x06},
-};
-static struct qs_s5k4e1_i2c_reg_conf qs_s5k4e1_default_lenshading_settings[] = {
-
-	{0x3200, 0x00},
-	{0x3201, 0x9a},
-	{0x3202, 0x56},
-	{0x3203, 0xf },
-	{0x3204, 0xd8},
-	{0x3205, 0x94},
-	{0x3206, 0x0 },
-	{0x3207, 0x10},
-	{0x3208, 0x71},
-	{0x3209, 0x0 },
-	{0x320a, 0x9 },
-	{0x320b, 0xc1},
-	{0x320c, 0xf },
-	{0x320d, 0xf1},
-	{0x320e, 0x3d},
-	{0x320f, 0x0 },
-	{0x3210, 0xa },
-	{0x3211, 0x93},
-	{0x3212, 0xf },
-	{0x3213, 0xc9},
-	{0x3214, 0xa1},
-	{0x3215, 0x0 },
-	{0x3216, 0x10},
-	{0x3217, 0x89},
-	{0x3218, 0xf },
-	{0x3219, 0xfb},
-	{0x321a, 0xf3},
-	{0x321b, 0xf },
-	{0x321c, 0xf8},
-	{0x321d, 0xfc},
-	{0x321e, 0x0 },
-	{0x321f, 0x4 },
-	{0x3220, 0xe3},
-	{0x3221, 0xf },
-	{0x3222, 0xfe},
-	{0x3223, 0x94},
-	{0x3224, 0x0 },
-	{0x3225, 0x24},
-	{0x3226, 0x59},
-	{0x3227, 0xf },
-	{0x3228, 0xe9},
-	{0x3229, 0x68},
-	{0x322a, 0xf },
-	{0x322b, 0xfa},
-	{0x322c, 0x7f},
-	{0x322d, 0x0 },
-	{0x322e, 0x13},
-	{0x322f, 0xe1},
-	{0x3230, 0x0 },
-	{0x3231, 0x3 },
-	{0x3232, 0xbc},
-	{0x3233, 0xf },
-	{0x3234, 0xf0},
-	{0x3235, 0xa1},
-	{0x3236, 0xf },
-	{0x3237, 0xf4},
-	{0x3238, 0xc9},
-	{0x3239, 0x0 },
-	{0x323a, 0x11},
-	{0x323b, 0x4b},
-	{0x323c, 0x0 },
-	{0x323d, 0x12},
-	{0x323e, 0xc5},
-	{0x323f, 0xf },
-	{0x3240, 0xe3},
-	{0x3241, 0xb },
-	{0x3242, 0xf },
-	{0x3243, 0xf8},
-	{0x3244, 0x4f},
-	{0x3245, 0x0 },
-	{0x3246, 0x13},
-	{0x3247, 0xac},
-	{0x3248, 0x0 },
-	{0x3249, 0x0 },
-	{0x324a, 0x7c},
-	{0x324b, 0xf },
-	{0x324c, 0xfe},
-	{0x324d, 0xdd},
-	{0x324e, 0xf },
-	{0x324f, 0xf2},
-	{0x3250, 0x96},
-	{0x3251, 0x0 },
-	{0x3252, 0x8 },
-	{0x3253, 0xef},
-	{0x3254, 0x0 },
-	{0x3255, 0x6 },
-	{0x3256, 0xa4},
-	{0x3257, 0x0 },
-	{0x3258, 0x2 },
-	{0x3259, 0x4b},
-	{0x325a, 0x0 },
-	{0x325b, 0x6 },
-	{0x325c, 0x85},
-	{0x325d, 0xf },
-	{0x325e, 0xf8},
-	{0x325f, 0x6a},
-	{0x3260, 0xf },
-	{0x3261, 0xfd},
-	{0x3262, 0x70},
-	{0x3263, 0x0 },
-	{0x3264, 0xd },
-	{0x3265, 0xa9},
-	{0x3266, 0xf },
-	{0x3267, 0xfd},
-	{0x3268, 0xf8},
-	{0x3269, 0xf },
-	{0x326a, 0xec},
-	{0x326b, 0xfc},
-	{0x326c, 0x0 },
-	{0x326d, 0xa7},
-	{0x326e, 0x5 },
-	{0x326f, 0xf },
-	{0x3270, 0xd6},
-	{0x3271, 0x19},
-	{0x3272, 0x0 },
-	{0x3273, 0xa },
-	{0x3274, 0xe8},
-	{0x3275, 0x0 },
-	{0x3276, 0x17},
-	{0x3277, 0x1 },
-	{0x3278, 0xf },
-	{0x3279, 0xe7},
-	{0x327a, 0xa0},
-	{0x327b, 0x0 },
-	{0x327c, 0xb },
-	{0x327d, 0xc3},
-	{0x327e, 0xf },
-	{0x327f, 0xc0},
-	{0x3280, 0xe3},
-	{0x3281, 0x0 },
-	{0x3282, 0x15},
-	{0x3283, 0x5a},
-	{0x3284, 0xf },
-	{0x3285, 0xf9},
-	{0x3286, 0xa0},
-	{0x3287, 0xf },
-	{0x3288, 0xf4},
-	{0x3289, 0xce},
-	{0x328a, 0x0 },
-	{0x328b, 0xb },
-	{0x328c, 0x72},
-	{0x328d, 0xf },
-	{0x328e, 0xfb},
-	{0x328f, 0xb5},
-	{0x3290, 0x0 },
-	{0x3291, 0x2f},
-	{0x3292, 0xb },
-	{0x3293, 0xf },
-	{0x3294, 0xde},
-	{0x3295, 0xc0},
-	{0x3296, 0x0 },
-	{0x3297, 0x0 },
-	{0x3298, 0x58},
-	{0x3299, 0x0 },
-	{0x329a, 0x1b},
-	{0x329b, 0x5 },
-	{0x329c, 0xf },
-	{0x329d, 0xf9},
-	{0x329e, 0x23},
-	{0x329f, 0xf },
-	{0x32a0, 0xf3},
-	{0x32a1, 0x94},
-	{0x32a2, 0xf },
-	{0x32a3, 0xe7},
-	{0x32a4, 0xc2},
-	{0x32a5, 0x0 },
-	{0x32a6, 0x1d},
-	{0x32a7, 0xe5},
-	{0x32a8, 0x0 },
-	{0x32a9, 0x5 },
-	{0x32aa, 0xaf},
-	{0x32ab, 0xf },
-	{0x32ac, 0xe3},
-	{0x32ad, 0xb7},
-	{0x32ae, 0xf },
-	{0x32af, 0xf8},
-	{0x32b0, 0x34},
-	{0x32b1, 0x0 },
-	{0x32b2, 0x1c},
-	{0x32b3, 0x3d},
-	{0x32b4, 0x0 },
-	{0x32b5, 0x10},
-	{0x32b6, 0x4a},
-	{0x32b7, 0xf },
-	{0x32b8, 0xfa},
-	{0x32b9, 0x7 },
-	{0x32ba, 0xf },
-	{0x32bb, 0xff},
-	{0x32bc, 0x16},
-	{0x32bd, 0x0 },
-	{0x32be, 0x5 },
-	{0x32bf, 0x4e},
-	{0x32c0, 0x0 },
-	{0x32c1, 0xc },
-	{0x32c2, 0x1b},
-	{0x32c3, 0xf },
-	{0x32c4, 0xf1},
-	{0x32c5, 0xdb},
-	{0x32c6, 0xf },
-	{0x32c7, 0xfc},
-	{0x32c8, 0xf8},
-	{0x32c9, 0xf },
-	{0x32ca, 0xf4},
-	{0x32cb, 0xad},
-	{0x32cc, 0xf },
-	{0x32cd, 0xfb},
-	{0x32ce, 0x59},
-	{0x32cf, 0x0 },
-	{0x32d0, 0x9 },
-	{0x32d1, 0xf7},
-	{0x32d2, 0x0 },
-	{0x32d3, 0x0 },
-	{0x32d4, 0xc1},
-	{0x32d5, 0xf },
-	{0x32d6, 0xf5},
-	{0x32d7, 0x30},
-	{0x32d8, 0x0 },
-	{0x32d9, 0x83},
-	{0x32da, 0x1d},
-	{0x32db, 0xf },
-	{0x32dc, 0xe3},
-	{0x32dd, 0x3c},
-	{0x32de, 0x0 },
-	{0x32df, 0xa },
-	{0x32e0, 0x10},
-	{0x32e1, 0x0 },
-	{0x32e2, 0x7 },
-	{0x32e3, 0x65},
-	{0x32e4, 0xf },
-	{0x32e5, 0xfe},
-	{0x32e6, 0x79},
-	{0x32e7, 0xf },
-	{0x32e8, 0xfd},
-	{0x32e9, 0x57},
-	{0x32ea, 0xf },
-	{0x32eb, 0xd6},
-	{0x32ec, 0x8f},
-	{0x32ed, 0x0 },
-	{0x32ee, 0x3 },
-	{0x32ef, 0x93},
-	{0x32f0, 0x0 },
-	{0x32f1, 0x6 },
-	{0x32f2, 0xa },
-	{0x32f3, 0xf },
-	{0x32f4, 0xfa},
-	{0x32f5, 0x6c},
-	{0x32f6, 0xf },
-	{0x32f7, 0xf1},
-	{0x32f8, 0x1e},
-	{0x32f9, 0x0 },
-	{0x32fa, 0x14},
-	{0x32fb, 0xe7},
-	{0x32fc, 0x0 },
-	{0x32fd, 0x1f},
-	{0x32fe, 0x2d},
-	{0x32ff, 0x0 },
-	{0x3300, 0x7 },
-	{0x3301, 0x5e},
-	{0x3302, 0xf },
-	{0x3303, 0xe0},
-	{0x3304, 0x55},
-	{0x3305, 0x0 },
-	{0x3306, 0x20},
-	{0x3307, 0x93},
-	{0x3308, 0x0 },
-	{0x3309, 0xf },
-	{0x330a, 0x20},
-	{0x330b, 0xf },
-	{0x330c, 0xd7},
-	{0x330d, 0xf5},
-	{0x330e, 0xf },
-	{0x330f, 0xef},
-	{0x3310, 0xb8},
-	{0x3311, 0xf },
-	{0x3312, 0xf0},
-	{0x3313, 0x29},
-	{0x3314, 0x0 },
-	{0x3315, 0x27},
-	{0x3316, 0x5e},
-	{0x3317, 0xf },
-	{0x3318, 0xda},
-	{0x3319, 0x14},
-	{0x331a, 0xf },
-	{0x331b, 0xef},
-	{0x331c, 0x93},
-	{0x331d, 0x0 },
-	{0x331e, 0x2c},
-	{0x331f, 0xdc},
-	{0x3320, 0x0 },
-	{0x3321, 0xe },
-	{0x3322, 0x2d},
-	{0x3323, 0x0 },
-	{0x3324, 0x6 },
-	{0x3325, 0xcf},
-	{0x3326, 0xf },
-	{0x3327, 0xfb},
-	{0x3328, 0x26},
-	{0x3329, 0x0 },
-	{0x332a, 0x3 },
-	{0x332b, 0x5 },
-	{0x332c, 0x0 },
-	{0x332d, 0x6 },
-	{0x332e, 0xa6},
-	{0x332f, 0xf },
-	{0x3330, 0xf7},
-	{0x3331, 0x7b},
-	{0x3332, 0xf },
-	{0x3333, 0xf9},
-	{0x3334, 0xb },
-	{0x3335, 0x0 },
-	{0x3336, 0x7 },
-	{0x3337, 0x5a},
-	{0x3338, 0xf },
-	{0x3339, 0xe4},
-	{0x333a, 0x7a},
-	{0x333b, 0x0 },
-	{0x333c, 0x1b},
-	{0x333d, 0xb0},
-	{0x333e, 0x0 },
-	{0x333f, 0x2 },
-	{0x3340, 0xa7},
-	{0x3341, 0xf },
-	{0x3342, 0xe9},
-	{0x3343, 0x3a},
-	{0x3344, 0x0 },
-	{0x3345, 0x95},
-	{0x3346, 0x42},
-	{0x3347, 0xf },
-	{0x3348, 0xda},
-	{0x3349, 0x45},
-	{0x334a, 0x0 },
-	{0x334b, 0x16},
-	{0x334c, 0x7a},
-	{0x334d, 0xf },
-	{0x334e, 0xfb},
-	{0x334f, 0x32},
-	{0x3350, 0x0 },
-	{0x3351, 0x6 },
-	{0x3352, 0x35},
-	{0x3353, 0xf },
-	{0x3354, 0xfc},
-	{0x3355, 0x8f},
-	{0x3356, 0xf },
-	{0x3357, 0xca},
-	{0x3358, 0xd5},
-	{0x3359, 0x0 },
-	{0x335a, 0x11},
-	{0x335b, 0x59},
-	{0x335c, 0xf },
-	{0x335d, 0xfa},
-	{0x335e, 0xaa},
-	{0x335f, 0xf },
-	{0x3360, 0xfe},
-	{0x3361, 0x84},
-	{0x3362, 0xf },
-	{0x3363, 0xf6},
-	{0x3364, 0x8f},
-	{0x3365, 0x0 },
-	{0x3366, 0xb },
-	{0x3367, 0x70},
-	{0x3368, 0x0 },
-	{0x3369, 0x25},
-	{0x336a, 0x83},
-	{0x336b, 0xf },
-	{0x336c, 0xe7},
-	{0x336d, 0x27},
-	{0x336e, 0xf },
-	{0x336f, 0xf1},
-	{0x3370, 0x72},
-	{0x3371, 0x0 },
-	{0x3372, 0x21},
-	{0x3373, 0x6d},
-	{0x3374, 0x0 },
-	{0x3375, 0x2 },
-	{0x3376, 0xc3},
-	{0x3377, 0xf },
-	{0x3378, 0xe8},
-	{0x3379, 0x5a},
-	{0x337a, 0xf },
-	{0x337b, 0xf2},
-	{0x337c, 0x73},
-	{0x337d, 0x0 },
-	{0x337e, 0x19},
-	{0x337f, 0xa5},
-	{0x3380, 0x0 },
-	{0x3381, 0x1a},
-	{0x3382, 0x81},
-	{0x3383, 0xf },
-	{0x3384, 0xd0},
-	{0x3385, 0x31},
-	{0x3386, 0xf },
-	{0x3387, 0xfb},
-	{0x3388, 0xff},
-	{0x3389, 0x0 },
-	{0x338a, 0x1e},
-	{0x338b, 0xe1},
-	{0x338c, 0x0 },
-	{0x338d, 0x5 },
-	{0x338e, 0xe1},
-	{0x338f, 0xf },
-	{0x3390, 0xee},
-	{0x3391, 0xe2},
-	{0x3392, 0xf },
-	{0x3393, 0xf6},
-	{0x3394, 0xcf},
-	{0x3395, 0x0 },
-	{0x3396, 0x13},
-	{0x3397, 0x8f},
-	{0x3398, 0x0 },
-	{0x3399, 0x3 },
-	{0x339a, 0x61},
-	{0x339b, 0xf },
-	{0x339c, 0xf8},
-	{0x339d, 0xf7},
-	{0x339e, 0x0 },
-	{0x339f, 0x0 },
-	{0x33a0, 0xb5},
-	{0x33a1, 0x0 },
-	{0x33a2, 0x5 },
-	{0x33a3, 0x78},
-	{0x33a4, 0xf },
-	{0x33a5, 0xf4},
-	{0x33a6, 0x5 },
-	{0x33a7, 0x0 },
-	{0x33a8, 0xc },
-	{0x33a9, 0xe },
-	{0x33aa, 0x0 },
-	{0x33ab, 0x3 },
-	{0x33ac, 0x53},
-	{0x33ad, 0xf },
-	{0x33ae, 0xec},
-	{0x33af, 0xbd},
-};
-
-const struct
-qs_s5k4e1_i2c_reg_conf qs_s5k4e1_lenshading_settings[4][LENS_SHADE_TABLE] = {
-	{/*2D Preview*/
-		{0x3097, 0x52},/*sh4ch_blk_width = 82*/
-		{0x3098, 0x3e},/*sh4ch_blk_height = 62*/
-		{0x3099, 0x03},/*sh4ch_step_x msb (sh4ch_step_x = 799)*/
-		{0x309a, 0x1f},/*sh4ch_step_x lsb*/
-		{0x309b, 0x04},/*sh4ch_step_y msb (sh4ch_step_y = 1057)*/
-		{0x309c, 0x21},/*sh4ch_step_y lsb*/
-		{0x309d, 0x00},/*sh4ch_start_blk_cnt_x = 0*/
-		{0x309e, 0x00},/*sh4ch_start_int_cnt_x = 0*/
-		{0x309f, 0x00},/*sh4ch_start_frac_cnt_x msb (0)*/
-		{0x30a0, 0x00},/*sh4ch_start_frac_cnt_x lsb*/
-		{0x30a1, 0x00},/*sh4ch_start_blk_cnt_y = 0*/
-		{0x30a2, 0x00},/*sh4ch_start_int_cnt_y = 0*/
-		{0x30a3, 0x00},/*sh4ch_start_frac_cnt_y msb (0)*/
-		{0x30a4, 0x00},/*sh4ch_start_frac_cnt_y lsb*/
-		{0x30a5, 0x01},
-		{0x30a6, 0x00},/*gs_pedestal	= 64*/
-	},
-	{/*2D Snapshot*/
-		{0x3097, 0x52},/*sh4ch_blk_width = 82*/
-		{0x3098, 0x7b},/*sh4ch_blk_height = 123*/
-		{0x3099, 0x03},/*sh4ch_step_x msb (sh4ch_step_x = 799)*/
-		{0x309a, 0x1f},/*sh4ch_step_x lsb*/
-		{0x309b, 0x02},/*sh4ch_step_y msb (sh4ch_step_y = 533)*/
-		{0x309c, 0x15},/*sh4ch_step_y lsb*/
-		{0x309d, 0x00},/*sh4ch_start_blk_cnt_x = 0*/
-		{0x309e, 0x00},/*sh4ch_start_int_cnt_x = 0*/
-		{0x309f, 0x00},/*sh4ch_start_frac_cnt_x msb (0)*/
-		{0x30a0, 0x00},/*sh4ch_start_frac_cnt_x lsb*/
-		{0x30a1, 0x00},/*sh4ch_start_blk_cnt_y = 0*/
-		{0x30a2, 0x00},/*sh4ch_start_int_cnt_y = 0*/
-		{0x30a3, 0x00},/*sh4ch_start_frac_cnt_y msb (0)*/
-		{0x30a4, 0x00},/*sh4ch_start_frac_cnt_y lsb*/
-		{0x30a5, 0x01},
-		{0x30a6, 0x00},/*gs_pedestal	= 64*/
-	},
-
-	{/*3D Preview*/
-		{0x3097, 0x52},/*sh4ch_blk_width = 82*/
-		{0x3098, 0x7b},/*sh4ch_blk_height = 123*/
-		{0x3099, 0x03},/*sh4ch_step_x msb (sh4ch_step_x = 799)*/
-		{0x309a, 0x1f},/*sh4ch_step_x lsb*/
-		{0x309b, 0x02},/*sh4ch_step_y msb (sh4ch_step_y = 533)*/
-		{0x309c, 0x15},/*sh4ch_step_y lsb*/
-		{0x309d, 0x3a},/*sh4ch_start_blk_cnt_x = 58*/
-		{0x309e, 0x01},/*sh4ch_start_int_cnt_x = 1*/
-		{0x309f, 0xb5},/*sh4ch_start_frac_cnt_x msb (46342)*/
-		{0x30a0, 0x06},/*sh4ch_start_frac_cnt_x lsb*/
-		{0x30a1, 0x23},/*sh4ch_start_blk_cnt_y = 35*/
-		{0x30a2, 0x03},/*sh4ch_start_int_cnt_y = 3*/
-		{0x30a3, 0x48},/*sh4ch_start_frac_cnt_y msb (46342)*/
-		{0x30a4, 0xdf},/*sh4ch_start_frac_cnt_y lsb*/
-		{0x30a5, 0x01},
-		{0x30a6, 0x00},/*gs_pedestal	= 64*/
-	},
-
-	{/*3D Snapshot*/
-		{0x3097, 0x52},/*sh4ch_blk_width = 82*/
-		{0x3098, 0x7b},/*sh4ch_blk_height = 123*/
-		{0x3099, 0x03},/*sh4ch_step_x msb (sh4ch_step_x = 799)*/
-		{0x309a, 0x1f},/*sh4ch_step_x lsb*/
-		{0x309b, 0x02},/*sh4ch_step_y msb (sh4ch_step_y = 533)*/
-		{0x309c, 0x15},/*sh4ch_step_y lsb*/
-		{0x309d, 0x38},/*sh4ch_start_blk_cnt_x = 56*/
-		{0x309e, 0x01},/*sh4ch_start_int_cnt_x = 1*/
-		{0x309f, 0xae},/*sh4ch_start_frac_cnt_x msb (44744)*/
-		{0x30a0, 0xc8},/*sh4ch_start_frac_cnt_x lsb*/
-		{0x30a1, 0x23},/*sh4ch_start_blk_cnt_y = 35*/
-		{0x30a2, 0x03},/*sh4ch_start_int_cnt_y = 3*/
-		{0x30a3, 0x48},/*sh4ch_start_frac_cnt_y msb (44744)*/
-		{0x30a4, 0xdf},/*sh4ch_start_frac_cnt_y lsb*/
-		{0x30a5, 0x01},
-		{0x30a6, 0x00},/*gs_pedestal	= 64*/
-	},
-
-};
-
-struct qs_s5k4e1_i2c_conf_array qs_s5k4e1_confs[] = {
-	{&qs_s5k4e1_prev_settings_2d[0], \
-		ARRAY_SIZE(qs_s5k4e1_prev_settings_2d)},
-	{&qs_s5k4e1_snap_settings_2d[0], \
-		ARRAY_SIZE(qs_s5k4e1_snap_settings_2d)},
-	{&qs_s5k4e1_prev_settings_3d[0], \
-		ARRAY_SIZE(qs_s5k4e1_prev_settings_3d)},
-	{&qs_s5k4e1_snap_settings_3d[0], \
-		ARRAY_SIZE(qs_s5k4e1_snap_settings_3d)},
-};
-struct qs_s5k4e1_reg qs_s5k4e1_regs = {
-	.rec_settings = &qs_s5k4e1_recommend_settings[0],
-	.rec_size = ARRAY_SIZE(qs_s5k4e1_recommend_settings),
-	.reg_lens = &qs_s5k4e1_lenshading_settings[0],
-	.reg_lens_size = ARRAY_SIZE(qs_s5k4e1_lenshading_settings[0]),
-	.reg_default_lens = &qs_s5k4e1_default_lenshading_settings[0],
-	.reg_default_lens_size =
-		ARRAY_SIZE(qs_s5k4e1_default_lenshading_settings),
-	.conf_array = &qs_s5k4e1_confs[0],
-};
diff --git a/drivers/media/video/msm/s5k3e2fx.c b/drivers/media/video/msm/s5k3e2fx.c
deleted file mode 100644
index 07a058e..0000000
--- a/drivers/media/video/msm/s5k3e2fx.c
+++ /dev/null
@@ -1,1387 +0,0 @@
-/* Copyright (c) 2009, Code Aurora Forum. 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/slab.h>
-#include <linux/delay.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <media/msm_camera.h>
-#include <mach/gpio.h>
-#include <mach/camera.h>
-#include "s5k3e2fx.h"
-
-#define S5K3E2FX_REG_MODEL_ID   0x0000
-#define S5K3E2FX_MODEL_ID       0x3E2F
-
-/* PLL Registers */
-#define REG_PRE_PLL_CLK_DIV           0x0305
-#define REG_PLL_MULTIPLIER_MSB        0x0306
-#define REG_PLL_MULTIPLIER_LSB        0x0307
-#define REG_VT_PIX_CLK_DIV            0x0301
-#define REG_VT_SYS_CLK_DIV            0x0303
-#define REG_OP_PIX_CLK_DIV            0x0309
-#define REG_OP_SYS_CLK_DIV            0x030B
-
-/* Data Format Registers */
-#define REG_CCP_DATA_FORMAT_MSB       0x0112
-#define REG_CCP_DATA_FORMAT_LSB       0x0113
-
-/* Output Size */
-#define REG_X_OUTPUT_SIZE_MSB         0x034C
-#define REG_X_OUTPUT_SIZE_LSB         0x034D
-#define REG_Y_OUTPUT_SIZE_MSB         0x034E
-#define REG_Y_OUTPUT_SIZE_LSB         0x034F
-
-/* Binning */
-#define REG_X_EVEN_INC                0x0381
-#define REG_X_ODD_INC                 0x0383
-#define REG_Y_EVEN_INC                0x0385
-#define REG_Y_ODD_INC                 0x0387
-/*Reserved register */
-#define REG_BINNING_ENABLE            0x3014
-
-/* Frame Fotmat */
-#define REG_FRAME_LENGTH_LINES_MSB    0x0340
-#define REG_FRAME_LENGTH_LINES_LSB    0x0341
-#define REG_LINE_LENGTH_PCK_MSB       0x0342
-#define REG_LINE_LENGTH_PCK_LSB       0x0343
-
-/* MSR setting */
-/* Reserved registers */
-#define REG_SHADE_CLK_ENABLE          0x30AC
-#define REG_SEL_CCP                   0x30C4
-#define REG_VPIX                      0x3024
-#define REG_CLAMP_ON                  0x3015
-#define REG_OFFSET                    0x307E
-
-/* CDS timing settings */
-/* Reserved registers */
-#define REG_LD_START                  0x3000
-#define REG_LD_END                    0x3001
-#define REG_SL_START                  0x3002
-#define REG_SL_END                    0x3003
-#define REG_RX_START                  0x3004
-#define REG_S1_START                  0x3005
-#define REG_S1_END                    0x3006
-#define REG_S1S_START                 0x3007
-#define REG_S1S_END                   0x3008
-#define REG_S3_START                  0x3009
-#define REG_S3_END                    0x300A
-#define REG_CMP_EN_START              0x300B
-#define REG_CLP_SL_START              0x300C
-#define REG_CLP_SL_END                0x300D
-#define REG_OFF_START                 0x300E
-#define REG_RMP_EN_START              0x300F
-#define REG_TX_START                  0x3010
-#define REG_TX_END                    0x3011
-#define REG_STX_WIDTH                 0x3012
-#define REG_TYPE1_AF_ENABLE           0x3130
-#define DRIVER_ENABLED                0x0001
-#define AUTO_START_ENABLED            0x0010
-#define REG_NEW_POSITION              0x3131
-#define REG_3152_RESERVED             0x3152
-#define REG_315A_RESERVED             0x315A
-#define REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB 0x0204
-#define REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB 0x0205
-#define REG_FINE_INTEGRATION_TIME         0x0200
-#define REG_COARSE_INTEGRATION_TIME       0x0202
-#define REG_COARSE_INTEGRATION_TIME_LSB   0x0203
-
-/* Mode select register */
-#define S5K3E2FX_REG_MODE_SELECT      0x0100
-#define S5K3E2FX_MODE_SELECT_STREAM     0x01   /* start streaming */
-#define S5K3E2FX_MODE_SELECT_SW_STANDBY 0x00   /* software standby */
-#define S5K3E2FX_REG_SOFTWARE_RESET   0x0103
-#define S5K3E2FX_SOFTWARE_RESET         0x01
-#define REG_TEST_PATTERN_MODE         0x0601
-
-struct reg_struct {
-  uint8_t pre_pll_clk_div;               /* 0x0305 */
-  uint8_t pll_multiplier_msb;            /* 0x0306 */
-  uint8_t pll_multiplier_lsb;            /* 0x0307 */
-  uint8_t vt_pix_clk_div;                /* 0x0301 */
-  uint8_t vt_sys_clk_div;                /* 0x0303 */
-  uint8_t op_pix_clk_div;                /* 0x0309 */
-  uint8_t op_sys_clk_div;                /* 0x030B */
-  uint8_t ccp_data_format_msb;           /* 0x0112 */
-  uint8_t ccp_data_format_lsb;           /* 0x0113 */
-  uint8_t x_output_size_msb;             /* 0x034C */
-  uint8_t x_output_size_lsb;             /* 0x034D */
-  uint8_t y_output_size_msb;             /* 0x034E */
-  uint8_t y_output_size_lsb;             /* 0x034F */
-  uint8_t x_even_inc;                    /* 0x0381 */
-  uint8_t x_odd_inc;                     /* 0x0383 */
-  uint8_t y_even_inc;                    /* 0x0385 */
-  uint8_t y_odd_inc;                     /* 0x0387 */
-  uint8_t binning_enable;                /* 0x3014 */
-  uint8_t frame_length_lines_msb;        /* 0x0340 */
-  uint8_t frame_length_lines_lsb;        /* 0x0341 */
-  uint8_t line_length_pck_msb;           /* 0x0342 */
-  uint8_t line_length_pck_lsb;           /* 0x0343 */
-  uint8_t shade_clk_enable ;             /* 0x30AC */
-  uint8_t sel_ccp;                       /* 0x30C4 */
-  uint8_t vpix;                          /* 0x3024 */
-  uint8_t clamp_on;                      /* 0x3015 */
-  uint8_t offset;                        /* 0x307E */
-  uint8_t ld_start;                      /* 0x3000 */
-  uint8_t ld_end;                        /* 0x3001 */
-  uint8_t sl_start;                      /* 0x3002 */
-  uint8_t sl_end;                        /* 0x3003 */
-  uint8_t rx_start;                      /* 0x3004 */
-  uint8_t s1_start;                      /* 0x3005 */
-  uint8_t s1_end;                        /* 0x3006 */
-  uint8_t s1s_start;                     /* 0x3007 */
-  uint8_t s1s_end;                       /* 0x3008 */
-  uint8_t s3_start;                      /* 0x3009 */
-  uint8_t s3_end;                        /* 0x300A */
-  uint8_t cmp_en_start;                  /* 0x300B */
-  uint8_t clp_sl_start;                  /* 0x300C */
-  uint8_t clp_sl_end;                    /* 0x300D */
-  uint8_t off_start;                     /* 0x300E */
-  uint8_t rmp_en_start;                  /* 0x300F */
-  uint8_t tx_start;                      /* 0x3010 */
-  uint8_t tx_end;                        /* 0x3011 */
-  uint8_t stx_width;                     /* 0x3012 */
-  uint8_t reg_3152_reserved;             /* 0x3152 */
-  uint8_t reg_315A_reserved;             /* 0x315A */
-  uint8_t analogue_gain_code_global_msb; /* 0x0204 */
-  uint8_t analogue_gain_code_global_lsb; /* 0x0205 */
-  uint8_t fine_integration_time;         /* 0x0200 */
-  uint8_t coarse_integration_time;       /* 0x0202 */
-  uint32_t  size_h;
-  uint32_t  blk_l;
-  uint32_t  size_w;
-  uint32_t  blk_p;
-};
-
-struct reg_struct s5k3e2fx_reg_pat[2] =  {
-  {	/* Preview */
-    0x06,  /* pre_pll_clk_div       REG=0x0305 */
-    0x00,  /* pll_multiplier_msb    REG=0x0306 */
-    0x88,  /* pll_multiplier_lsb    REG=0x0307 */
-    0x0a,  /* vt_pix_clk_div        REG=0x0301 */
-    0x01,  /* vt_sys_clk_div        REG=0x0303 */
-    0x0a,  /* op_pix_clk_div        REG=0x0309 */
-    0x01,  /* op_sys_clk_div        REG=0x030B */
-    0x0a,  /* ccp_data_format_msb   REG=0x0112 */
-    0x0a,  /* ccp_data_format_lsb   REG=0x0113 */
-    0x05,  /* x_output_size_msb     REG=0x034C */
-    0x10,  /* x_output_size_lsb     REG=0x034D */
-    0x03,  /* y_output_size_msb     REG=0x034E */
-    0xcc,  /* y_output_size_lsb     REG=0x034F */
-
-    /* enable binning for preview */
-    0x01,  /* x_even_inc             REG=0x0381 */
-    0x01,  /* x_odd_inc              REG=0x0383 */
-    0x01,  /* y_even_inc             REG=0x0385 */
-    0x03,  /* y_odd_inc              REG=0x0387 */
-    0x06,  /* binning_enable         REG=0x3014 */
-
-    0x03,  /* frame_length_lines_msb        REG=0x0340 */
-    0xde,  /* frame_length_lines_lsb        REG=0x0341 */
-    0x0a,  /* line_length_pck_msb           REG=0x0342 */
-    0xac,  /* line_length_pck_lsb           REG=0x0343 */
-    0x81,  /* shade_clk_enable              REG=0x30AC */
-    0x01,  /* sel_ccp                       REG=0x30C4 */
-    0x04,  /* vpix                          REG=0x3024 */
-    0x00,  /* clamp_on                      REG=0x3015 */
-    0x02,  /* offset                        REG=0x307E */
-    0x03,  /* ld_start                      REG=0x3000 */
-    0x9c,  /* ld_end                        REG=0x3001 */
-    0x02,  /* sl_start                      REG=0x3002 */
-    0x9e,  /* sl_end                        REG=0x3003 */
-    0x05,  /* rx_start                      REG=0x3004 */
-    0x0f,  /* s1_start                      REG=0x3005 */
-    0x24,  /* s1_end                        REG=0x3006 */
-    0x7c,  /* s1s_start                     REG=0x3007 */
-    0x9a,  /* s1s_end                       REG=0x3008 */
-    0x10,  /* s3_start                      REG=0x3009 */
-    0x14,  /* s3_end                        REG=0x300A */
-    0x10,  /* cmp_en_start                  REG=0x300B */
-    0x04,  /* clp_sl_start                  REG=0x300C */
-    0x26,  /* clp_sl_end                    REG=0x300D */
-    0x02,  /* off_start                     REG=0x300E */
-    0x0e,  /* rmp_en_start                  REG=0x300F */
-    0x30,  /* tx_start                      REG=0x3010 */
-    0x4e,  /* tx_end                        REG=0x3011 */
-    0x1E,  /* stx_width                     REG=0x3012 */
-    0x08,  /* reg_3152_reserved             REG=0x3152 */
-    0x10,  /* reg_315A_reserved             REG=0x315A */
-    0x00,  /* analogue_gain_code_global_msb REG=0x0204 */
-    0x80,  /* analogue_gain_code_global_lsb REG=0x0205 */
-    0x02,  /* fine_integration_time         REG=0x0200 */
-    0x03,  /* coarse_integration_time       REG=0x0202 */
-		972,
-		18,
-		1296,
-		1436
-  },
-  { /* Snapshot */
-    0x06,  /* pre_pll_clk_div               REG=0x0305 */
-    0x00,  /* pll_multiplier_msb            REG=0x0306 */
-    0x88,  /* pll_multiplier_lsb            REG=0x0307 */
-    0x0a,  /* vt_pix_clk_div                REG=0x0301 */
-    0x01,  /* vt_sys_clk_div                REG=0x0303 */
-    0x0a,  /* op_pix_clk_div                REG=0x0309 */
-    0x01,  /* op_sys_clk_div                REG=0x030B */
-    0x0a,  /* ccp_data_format_msb           REG=0x0112 */
-    0x0a,  /* ccp_data_format_lsb           REG=0x0113 */
-    0x0a,  /* x_output_size_msb             REG=0x034C */
-    0x30,  /* x_output_size_lsb             REG=0x034D */
-    0x07,  /* y_output_size_msb             REG=0x034E */
-    0xa8,  /* y_output_size_lsb             REG=0x034F */
-
-    /* disable binning for snapshot */
-    0x01,  /* x_even_inc                    REG=0x0381 */
-    0x01,  /* x_odd_inc                     REG=0x0383 */
-    0x01,  /* y_even_inc                    REG=0x0385 */
-    0x01,  /* y_odd_inc                     REG=0x0387 */
-    0x00,  /* binning_enable                REG=0x3014 */
-
-    0x07,  /* frame_length_lines_msb        REG=0x0340 */
-    0xb6,  /* frame_length_lines_lsb        REG=0x0341 */
-    0x0a,  /* line_length_pck_msb           REG=0x0342 */
-    0xac,  /* line_length_pck_lsb           REG=0x0343 */
-    0x81,  /* shade_clk_enable              REG=0x30AC */
-    0x01,  /* sel_ccp                       REG=0x30C4 */
-    0x04,  /* vpix                          REG=0x3024 */
-    0x00,  /* clamp_on                      REG=0x3015 */
-    0x02,  /* offset                        REG=0x307E */
-    0x03,  /* ld_start                      REG=0x3000 */
-    0x9c,  /* ld_end                        REG=0x3001 */
-    0x02,  /* sl_start                      REG=0x3002 */
-    0x9e,  /* sl_end                        REG=0x3003 */
-    0x05,  /* rx_start                      REG=0x3004 */
-    0x0f,  /* s1_start                      REG=0x3005 */
-    0x24,  /* s1_end                        REG=0x3006 */
-    0x7c,  /* s1s_start                     REG=0x3007 */
-    0x9a,  /* s1s_end                       REG=0x3008 */
-    0x10,  /* s3_start                      REG=0x3009 */
-    0x14,  /* s3_end                        REG=0x300A */
-    0x10,  /* cmp_en_start                  REG=0x300B */
-    0x04,  /* clp_sl_start                  REG=0x300C */
-    0x26,  /* clp_sl_end                    REG=0x300D */
-    0x02,  /* off_start                     REG=0x300E */
-    0x0e,  /* rmp_en_start                  REG=0x300F */
-    0x30,  /* tx_start                      REG=0x3010 */
-    0x4e,  /* tx_end                        REG=0x3011 */
-    0x1E,  /* stx_width                     REG=0x3012 */
-    0x08,  /* reg_3152_reserved             REG=0x3152 */
-    0x10,  /* reg_315A_reserved             REG=0x315A */
-    0x00,  /* analogue_gain_code_global_msb REG=0x0204 */
-    0x80,  /* analogue_gain_code_global_lsb REG=0x0205 */
-    0x02,  /* fine_integration_time         REG=0x0200 */
-    0x03,  /* coarse_integration_time       REG=0x0202 */
-		1960,
-		14,
-		2608,
-		124
-	}
-};
-
-struct s5k3e2fx_work {
-	struct work_struct work;
-};
-static struct s5k3e2fx_work *s5k3e2fx_sensorw;
-static struct i2c_client *s5k3e2fx_client;
-
-struct s5k3e2fx_ctrl {
-	const struct msm_camera_sensor_info *sensordata;
-
-	int sensormode;
-	uint32_t fps_divider; /* init to 1 * 0x00000400 */
-	uint32_t pict_fps_divider; /* init to 1 * 0x00000400 */
-
-	uint16_t curr_lens_pos;
-	uint16_t init_curr_lens_pos;
-	uint16_t my_reg_gain;
-	uint32_t my_reg_line_count;
-
-	enum msm_s_resolution prev_res;
-	enum msm_s_resolution pict_res;
-	enum msm_s_resolution curr_res;
-	enum msm_s_test_mode  set_test;
-};
-
-struct s5k3e2fx_i2c_reg_conf {
-	unsigned short waddr;
-	unsigned char  bdata;
-};
-
-static struct s5k3e2fx_ctrl *s5k3e2fx_ctrl;
-static DECLARE_WAIT_QUEUE_HEAD(s5k3e2fx_wait_queue);
-DEFINE_MUTEX(s5k3e2fx_mutex);
-
-static int s5k3e2fx_i2c_rxdata(unsigned short saddr, unsigned char *rxdata,
-	int length)
-{
-	struct i2c_msg msgs[] = {
-		{
-			.addr   = saddr,
-			.flags = 0,
-			.len   = 2,
-			.buf   = rxdata,
-		},
-		{
-			.addr   = saddr,
-			.flags = I2C_M_RD,
-			.len   = length,
-			.buf   = rxdata,
-		},
-	};
-
-	if (i2c_transfer(s5k3e2fx_client->adapter, msgs, 2) < 0) {
-		CDBG("s5k3e2fx_i2c_rxdata failed!\n");
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int32_t s5k3e2fx_i2c_txdata(unsigned short saddr,
-	unsigned char *txdata, int length)
-{
-	struct i2c_msg msg[] = {
-		{
-		.addr  = saddr,
-		.flags = 0,
-		.len = length,
-		.buf = txdata,
-		},
-	};
-
-	if (i2c_transfer(s5k3e2fx_client->adapter, msg, 1) < 0) {
-		CDBG("s5k3e2fx_i2c_txdata failed\n");
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int32_t s5k3e2fx_i2c_write_b(unsigned short saddr, unsigned short waddr,
-	unsigned char bdata)
-{
-	int32_t rc = -EIO;
-	unsigned char buf[4];
-
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (waddr & 0xFF00)>>8;
-	buf[1] = (waddr & 0x00FF);
-	buf[2] = bdata;
-
-	rc = s5k3e2fx_i2c_txdata(saddr, buf, 3);
-
-	if (rc < 0)
-		CDBG("i2c_write_w failed, addr = 0x%x, val = 0x%x!\n",
-			waddr, bdata);
-
-	return rc;
-}
-
-static int32_t s5k3e2fx_i2c_write_table(
-	struct s5k3e2fx_i2c_reg_conf *reg_cfg_tbl, int num)
-{
-	int i;
-	int32_t rc = -EIO;
-	for (i = 0; i < num; i++) {
-		rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
-			reg_cfg_tbl->waddr, reg_cfg_tbl->bdata);
-		if (rc < 0)
-			break;
-		reg_cfg_tbl++;
-	}
-
-	return rc;
-}
-
-static int32_t s5k3e2fx_i2c_read_w(unsigned short saddr, unsigned short raddr,
-	unsigned short *rdata)
-{
-	int32_t rc = 0;
-	unsigned char buf[4];
-
-	if (!rdata)
-		return -EIO;
-
-	memset(buf, 0, sizeof(buf));
-
-	buf[0] = (raddr & 0xFF00)>>8;
-	buf[1] = (raddr & 0x00FF);
-
-	rc = s5k3e2fx_i2c_rxdata(saddr, buf, 2);
-	if (rc < 0)
-		return rc;
-
-	*rdata = buf[0] << 8 | buf[1];
-
-	if (rc < 0)
-		CDBG("s5k3e2fx_i2c_read failed!\n");
-
-	return rc;
-}
-
-static int s5k3e2fx_probe_init_done(const struct msm_camera_sensor_info *data)
-{
-	gpio_direction_output(data->sensor_reset, 0);
-	gpio_free(data->sensor_reset);
-	return 0;
-}
-
-static int s5k3e2fx_probe_init_sensor(const struct msm_camera_sensor_info *data)
-{
-	int32_t  rc;
-	uint16_t chipid = 0;
-
-	rc = gpio_request(data->sensor_reset, "s5k3e2fx");
-	if (!rc)
-		gpio_direction_output(data->sensor_reset, 1);
-	else
-		goto init_probe_done;
-
-	mdelay(20);
-
-	CDBG("s5k3e2fx_sensor_init(): reseting sensor.\n");
-
-	rc = s5k3e2fx_i2c_read_w(s5k3e2fx_client->addr,
-		S5K3E2FX_REG_MODEL_ID, &chipid);
-	if (rc < 0)
-		goto init_probe_fail;
-
-	if (chipid != S5K3E2FX_MODEL_ID) {
-		CDBG("S5K3E2FX wrong model_id = 0x%x\n", chipid);
-		rc = -ENODEV;
-		goto init_probe_fail;
-	}
-
-	goto init_probe_done;
-
-init_probe_fail:
-	s5k3e2fx_probe_init_done(data);
-init_probe_done:
-	return rc;
-}
-
-static int s5k3e2fx_init_client(struct i2c_client *client)
-{
-	/* Initialize the MSM_CAMI2C Chip */
-	init_waitqueue_head(&s5k3e2fx_wait_queue);
-	return 0;
-}
-
-static const struct i2c_device_id s5k3e2fx_i2c_id[] = {
-	{ "s5k3e2fx", 0},
-	{ }
-};
-
-static int s5k3e2fx_i2c_probe(struct i2c_client *client,
-	const struct i2c_device_id *id)
-{
-	int rc = 0;
-	CDBG("s5k3e2fx_probe called!\n");
-
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		CDBG("i2c_check_functionality failed\n");
-		goto probe_failure;
-	}
-
-	s5k3e2fx_sensorw = kzalloc(sizeof(struct s5k3e2fx_work), GFP_KERNEL);
-	if (!s5k3e2fx_sensorw) {
-		CDBG("kzalloc failed.\n");
-		rc = -ENOMEM;
-		goto probe_failure;
-	}
-
-	i2c_set_clientdata(client, s5k3e2fx_sensorw);
-	s5k3e2fx_init_client(client);
-	s5k3e2fx_client = client;
-
-	mdelay(50);
-
-	CDBG("s5k3e2fx_probe successed! rc = %d\n", rc);
-	return 0;
-
-probe_failure:
-	CDBG("s5k3e2fx_probe failed! rc = %d\n", rc);
-	return rc;
-}
-
-static struct i2c_driver s5k3e2fx_i2c_driver = {
-	.id_table = s5k3e2fx_i2c_id,
-	.probe  = s5k3e2fx_i2c_probe,
-	.remove = __exit_p(s5k3e2fx_i2c_remove),
-	.driver = {
-		.name = "s5k3e2fx",
-	},
-};
-
-static int32_t s5k3e2fx_test(enum msm_s_test_mode mo)
-{
-	int32_t rc = 0;
-
-	if (mo == S_TEST_OFF)
-		rc = 0;
-	else
-		rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
-			REG_TEST_PATTERN_MODE, (uint16_t)mo);
-
-	return rc;
-}
-
-static int32_t s5k3e2fx_setting(enum msm_s_reg_update rupdate,
-	enum msm_s_setting rt)
-{
-	int32_t rc = 0;
-  uint16_t num_lperf;
-
-	switch (rupdate) {
-	case S_UPDATE_PERIODIC:
-	if (rt == S_RES_PREVIEW || rt == S_RES_CAPTURE) {
-
-		struct s5k3e2fx_i2c_reg_conf tbl_1[] = {
-			{REG_CCP_DATA_FORMAT_MSB,
-				s5k3e2fx_reg_pat[rt].ccp_data_format_msb},
-			{REG_CCP_DATA_FORMAT_LSB,
-				s5k3e2fx_reg_pat[rt].ccp_data_format_lsb},
-			{REG_X_OUTPUT_SIZE_MSB,
-				s5k3e2fx_reg_pat[rt].x_output_size_msb},
-			{REG_X_OUTPUT_SIZE_LSB,
-				s5k3e2fx_reg_pat[rt].x_output_size_lsb},
-			{REG_Y_OUTPUT_SIZE_MSB,
-				s5k3e2fx_reg_pat[rt].y_output_size_msb},
-			{REG_Y_OUTPUT_SIZE_LSB,
-				s5k3e2fx_reg_pat[rt].y_output_size_lsb},
-			{REG_X_EVEN_INC,
-				s5k3e2fx_reg_pat[rt].x_even_inc},
-			{REG_X_ODD_INC,
-				s5k3e2fx_reg_pat[rt].x_odd_inc},
-			{REG_Y_EVEN_INC,
-				s5k3e2fx_reg_pat[rt].y_even_inc},
-			{REG_Y_ODD_INC,
-				s5k3e2fx_reg_pat[rt].y_odd_inc},
-			{REG_BINNING_ENABLE,
-				s5k3e2fx_reg_pat[rt].binning_enable},
-		};
-
-		struct s5k3e2fx_i2c_reg_conf tbl_2[] = {
-			{REG_FRAME_LENGTH_LINES_MSB, 0},
-			{REG_FRAME_LENGTH_LINES_LSB, 0},
-			{REG_LINE_LENGTH_PCK_MSB,
-				s5k3e2fx_reg_pat[rt].line_length_pck_msb},
-			{REG_LINE_LENGTH_PCK_LSB,
-				s5k3e2fx_reg_pat[rt].line_length_pck_lsb},
-			{REG_SHADE_CLK_ENABLE,
-				s5k3e2fx_reg_pat[rt].shade_clk_enable},
-			{REG_SEL_CCP, s5k3e2fx_reg_pat[rt].sel_ccp},
-			{REG_VPIX, s5k3e2fx_reg_pat[rt].vpix},
-			{REG_CLAMP_ON, s5k3e2fx_reg_pat[rt].clamp_on},
-			{REG_OFFSET, s5k3e2fx_reg_pat[rt].offset},
-			{REG_LD_START, s5k3e2fx_reg_pat[rt].ld_start},
-			{REG_LD_END, s5k3e2fx_reg_pat[rt].ld_end},
-			{REG_SL_START, s5k3e2fx_reg_pat[rt].sl_start},
-			{REG_SL_END, s5k3e2fx_reg_pat[rt].sl_end},
-			{REG_RX_START, s5k3e2fx_reg_pat[rt].rx_start},
-			{REG_S1_START, s5k3e2fx_reg_pat[rt].s1_start},
-			{REG_S1_END, s5k3e2fx_reg_pat[rt].s1_end},
-			{REG_S1S_START, s5k3e2fx_reg_pat[rt].s1s_start},
-			{REG_S1S_END, s5k3e2fx_reg_pat[rt].s1s_end},
-			{REG_S3_START, s5k3e2fx_reg_pat[rt].s3_start},
-			{REG_S3_END, s5k3e2fx_reg_pat[rt].s3_end},
-			{REG_CMP_EN_START, s5k3e2fx_reg_pat[rt].cmp_en_start},
-			{REG_CLP_SL_START, s5k3e2fx_reg_pat[rt].clp_sl_start},
-			{REG_CLP_SL_END, s5k3e2fx_reg_pat[rt].clp_sl_end},
-			{REG_OFF_START, s5k3e2fx_reg_pat[rt].off_start},
-			{REG_RMP_EN_START, s5k3e2fx_reg_pat[rt].rmp_en_start},
-			{REG_TX_START, s5k3e2fx_reg_pat[rt].tx_start},
-			{REG_TX_END, s5k3e2fx_reg_pat[rt].tx_end},
-			{REG_STX_WIDTH, s5k3e2fx_reg_pat[rt].stx_width},
-			{REG_3152_RESERVED,
-				s5k3e2fx_reg_pat[rt].reg_3152_reserved},
-			{REG_315A_RESERVED,
-				s5k3e2fx_reg_pat[rt].reg_315A_reserved},
-			{REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB,
-				s5k3e2fx_reg_pat[rt].
-				analogue_gain_code_global_msb},
-			{REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB,
-				s5k3e2fx_reg_pat[rt].
-				analogue_gain_code_global_lsb},
-			{REG_FINE_INTEGRATION_TIME,
-				s5k3e2fx_reg_pat[rt].fine_integration_time},
-			{REG_COARSE_INTEGRATION_TIME,
-				s5k3e2fx_reg_pat[rt].coarse_integration_time},
-			{S5K3E2FX_REG_MODE_SELECT, S5K3E2FX_MODE_SELECT_STREAM},
-		};
-
-		rc = s5k3e2fx_i2c_write_table(&tbl_1[0],
-			ARRAY_SIZE(tbl_1));
-		if (rc < 0)
-			return rc;
-
-		num_lperf = (uint16_t)
-			((s5k3e2fx_reg_pat[rt].frame_length_lines_msb << 8)
-			& 0xFF00)
-			+ s5k3e2fx_reg_pat[rt].frame_length_lines_lsb;
-
-		num_lperf = num_lperf * s5k3e2fx_ctrl->fps_divider / 0x0400;
-
-		tbl_2[0] = (struct s5k3e2fx_i2c_reg_conf)
-			{REG_FRAME_LENGTH_LINES_MSB, (num_lperf & 0xFF00) >> 8};
-		tbl_2[1] = (struct s5k3e2fx_i2c_reg_conf)
-			{REG_FRAME_LENGTH_LINES_LSB, (num_lperf & 0x00FF)};
-
-		rc = s5k3e2fx_i2c_write_table(&tbl_2[0],
-			ARRAY_SIZE(tbl_2));
-		if (rc < 0)
-			return rc;
-
-		mdelay(5);
-
-		rc = s5k3e2fx_test(s5k3e2fx_ctrl->set_test);
-		if (rc < 0)
-			return rc;
-	  }
-    break; /* UPDATE_PERIODIC */
-
-	case S_REG_INIT:
-	if (rt == S_RES_PREVIEW || rt == S_RES_CAPTURE) {
-
-		struct s5k3e2fx_i2c_reg_conf tbl_3[] = {
-			{S5K3E2FX_REG_SOFTWARE_RESET, S5K3E2FX_SOFTWARE_RESET},
-			{S5K3E2FX_REG_MODE_SELECT,
-				S5K3E2FX_MODE_SELECT_SW_STANDBY},
-			/* PLL setting */
-			{REG_PRE_PLL_CLK_DIV,
-				s5k3e2fx_reg_pat[rt].pre_pll_clk_div},
-			{REG_PLL_MULTIPLIER_MSB,
-				s5k3e2fx_reg_pat[rt].pll_multiplier_msb},
-			{REG_PLL_MULTIPLIER_LSB,
-				s5k3e2fx_reg_pat[rt].pll_multiplier_lsb},
-			{REG_VT_PIX_CLK_DIV,
-				s5k3e2fx_reg_pat[rt].vt_pix_clk_div},
-			{REG_VT_SYS_CLK_DIV,
-				s5k3e2fx_reg_pat[rt].vt_sys_clk_div},
-			{REG_OP_PIX_CLK_DIV,
-				s5k3e2fx_reg_pat[rt].op_pix_clk_div},
-			{REG_OP_SYS_CLK_DIV,
-				s5k3e2fx_reg_pat[rt].op_sys_clk_div},
-			/*Data Format */
-			{REG_CCP_DATA_FORMAT_MSB,
-				s5k3e2fx_reg_pat[rt].ccp_data_format_msb},
-			{REG_CCP_DATA_FORMAT_LSB,
-				s5k3e2fx_reg_pat[rt].ccp_data_format_lsb},
-			/*Output Size */
-			{REG_X_OUTPUT_SIZE_MSB,
-				s5k3e2fx_reg_pat[rt].x_output_size_msb},
-			{REG_X_OUTPUT_SIZE_LSB,
-				s5k3e2fx_reg_pat[rt].x_output_size_lsb},
-			{REG_Y_OUTPUT_SIZE_MSB,
-				s5k3e2fx_reg_pat[rt].y_output_size_msb},
-			{REG_Y_OUTPUT_SIZE_LSB,
-				s5k3e2fx_reg_pat[rt].y_output_size_lsb},
-			/* Binning */
-			{REG_X_EVEN_INC, s5k3e2fx_reg_pat[rt].x_even_inc},
-			{REG_X_ODD_INC, s5k3e2fx_reg_pat[rt].x_odd_inc },
-			{REG_Y_EVEN_INC, s5k3e2fx_reg_pat[rt].y_even_inc},
-			{REG_Y_ODD_INC, s5k3e2fx_reg_pat[rt].y_odd_inc},
-			{REG_BINNING_ENABLE,
-				s5k3e2fx_reg_pat[rt].binning_enable},
-			/* Frame format */
-			{REG_FRAME_LENGTH_LINES_MSB,
-				s5k3e2fx_reg_pat[rt].frame_length_lines_msb},
-			{REG_FRAME_LENGTH_LINES_LSB,
-				s5k3e2fx_reg_pat[rt].frame_length_lines_lsb},
-			{REG_LINE_LENGTH_PCK_MSB,
-				s5k3e2fx_reg_pat[rt].line_length_pck_msb},
-			{REG_LINE_LENGTH_PCK_LSB,
-				s5k3e2fx_reg_pat[rt].line_length_pck_lsb},
-			/* MSR setting */
-			{REG_SHADE_CLK_ENABLE,
-				s5k3e2fx_reg_pat[rt].shade_clk_enable},
-			{REG_SEL_CCP, s5k3e2fx_reg_pat[rt].sel_ccp},
-			{REG_VPIX, s5k3e2fx_reg_pat[rt].vpix},
-			{REG_CLAMP_ON, s5k3e2fx_reg_pat[rt].clamp_on},
-			{REG_OFFSET, s5k3e2fx_reg_pat[rt].offset},
-			/* CDS timing setting */
-			{REG_LD_START, s5k3e2fx_reg_pat[rt].ld_start},
-			{REG_LD_END, s5k3e2fx_reg_pat[rt].ld_end},
-			{REG_SL_START, s5k3e2fx_reg_pat[rt].sl_start},
-			{REG_SL_END, s5k3e2fx_reg_pat[rt].sl_end},
-			{REG_RX_START, s5k3e2fx_reg_pat[rt].rx_start},
-			{REG_S1_START, s5k3e2fx_reg_pat[rt].s1_start},
-			{REG_S1_END, s5k3e2fx_reg_pat[rt].s1_end},
-			{REG_S1S_START, s5k3e2fx_reg_pat[rt].s1s_start},
-			{REG_S1S_END, s5k3e2fx_reg_pat[rt].s1s_end},
-			{REG_S3_START, s5k3e2fx_reg_pat[rt].s3_start},
-			{REG_S3_END, s5k3e2fx_reg_pat[rt].s3_end},
-			{REG_CMP_EN_START, s5k3e2fx_reg_pat[rt].cmp_en_start},
-			{REG_CLP_SL_START, s5k3e2fx_reg_pat[rt].clp_sl_start},
-			{REG_CLP_SL_END, s5k3e2fx_reg_pat[rt].clp_sl_end},
-			{REG_OFF_START, s5k3e2fx_reg_pat[rt].off_start},
-			{REG_RMP_EN_START, s5k3e2fx_reg_pat[rt].rmp_en_start},
-			{REG_TX_START, s5k3e2fx_reg_pat[rt].tx_start},
-			{REG_TX_END, s5k3e2fx_reg_pat[rt].tx_end},
-			{REG_STX_WIDTH, s5k3e2fx_reg_pat[rt].stx_width},
-			{REG_3152_RESERVED,
-				s5k3e2fx_reg_pat[rt].reg_3152_reserved},
-			{REG_315A_RESERVED,
-				s5k3e2fx_reg_pat[rt].reg_315A_reserved},
-			{REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB,
-				s5k3e2fx_reg_pat[rt].
-				analogue_gain_code_global_msb},
-			{REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB,
-				s5k3e2fx_reg_pat[rt].
-				analogue_gain_code_global_lsb},
-			{REG_FINE_INTEGRATION_TIME,
-				s5k3e2fx_reg_pat[rt].fine_integration_time},
-			{REG_COARSE_INTEGRATION_TIME,
-				s5k3e2fx_reg_pat[rt].coarse_integration_time},
-			{S5K3E2FX_REG_MODE_SELECT, S5K3E2FX_MODE_SELECT_STREAM},
-		};
-
-		/* reset fps_divider */
-		s5k3e2fx_ctrl->fps_divider = 1 * 0x0400;
-		rc = s5k3e2fx_i2c_write_table(&tbl_3[0],
-			ARRAY_SIZE(tbl_3));
-		if (rc < 0)
-			return rc;
-		}
-		break; /* case REG_INIT: */
-
-	default:
-		rc = -EINVAL;
-		break;
-	} /* switch (rupdate) */
-
-	return rc;
-}
-
-static int s5k3e2fx_sensor_open_init(const struct msm_camera_sensor_info *data)
-{
-	int32_t  rc;
-
-	s5k3e2fx_ctrl = kzalloc(sizeof(struct s5k3e2fx_ctrl), GFP_KERNEL);
-	if (!s5k3e2fx_ctrl) {
-		CDBG("s5k3e2fx_init failed!\n");
-		rc = -ENOMEM;
-		goto init_done;
-	}
-
-	s5k3e2fx_ctrl->fps_divider = 1 * 0x00000400;
-	s5k3e2fx_ctrl->pict_fps_divider = 1 * 0x00000400;
-	s5k3e2fx_ctrl->set_test = S_TEST_OFF;
-	s5k3e2fx_ctrl->prev_res = S_QTR_SIZE;
-	s5k3e2fx_ctrl->pict_res = S_FULL_SIZE;
-
-	if (data)
-		s5k3e2fx_ctrl->sensordata = data;
-
-	/* enable mclk first */
-	msm_camio_clk_rate_set(24000000);
-	mdelay(20);
-
-	msm_camio_camif_pad_reg_reset();
-	mdelay(20);
-
-	rc = s5k3e2fx_probe_init_sensor(data);
-	if (rc < 0)
-		goto init_fail1;
-
-	if (s5k3e2fx_ctrl->prev_res == S_QTR_SIZE)
-		rc = s5k3e2fx_setting(S_REG_INIT, S_RES_PREVIEW);
-	else
-		rc = s5k3e2fx_setting(S_REG_INIT, S_RES_CAPTURE);
-
-	if (rc < 0) {
-		CDBG("s5k3e2fx_setting failed. rc = %d\n", rc);
-		goto init_fail1;
-	}
-
-	/* initialize AF */
-	rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
-			0x3146, 0x3A);
-	if (rc < 0)
-		goto init_fail1;
-
-	rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
-			0x3130, 0x03);
-	if (rc < 0)
-		goto init_fail1;
-
-	goto init_done;
-
-init_fail1:
-	s5k3e2fx_probe_init_done(data);
-	kfree(s5k3e2fx_ctrl);
-init_done:
-	return rc;
-}
-
-static int32_t s5k3e2fx_power_down(void)
-{
-	int32_t rc = 0;
-	return rc;
-}
-
-static int s5k3e2fx_sensor_release(void)
-{
-	int rc = -EBADF;
-
-	mutex_lock(&s5k3e2fx_mutex);
-
-	s5k3e2fx_power_down();
-
-	gpio_direction_output(s5k3e2fx_ctrl->sensordata->sensor_reset,
-		0);
-	gpio_free(s5k3e2fx_ctrl->sensordata->sensor_reset);
-
-	kfree(s5k3e2fx_ctrl);
-	s5k3e2fx_ctrl = NULL;
-
-	CDBG("s5k3e2fx_release completed\n");
-
-	mutex_unlock(&s5k3e2fx_mutex);
-	return rc;
-}
-
-static void s5k3e2fx_get_pict_fps(uint16_t fps, uint16_t *pfps)
-{
-	/* input fps is preview fps in Q8 format */
-	uint32_t divider;   /* Q10 */
-
-	divider = (uint32_t)
-		((s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h +
-			s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l) *
-		 (s5k3e2fx_reg_pat[S_RES_PREVIEW].size_w +
-			s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_p)) * 0x00000400 /
-		((s5k3e2fx_reg_pat[S_RES_CAPTURE].size_h +
-			s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l) *
-		 (s5k3e2fx_reg_pat[S_RES_CAPTURE].size_w +
-			s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p));
-
-	/* Verify PCLK settings and frame sizes. */
-	*pfps = (uint16_t)(fps * divider / 0x00000400);
-}
-
-static uint16_t s5k3e2fx_get_prev_lines_pf(void)
-{
-	return s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h +
-		s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l;
-}
-
-static uint16_t s5k3e2fx_get_prev_pixels_pl(void)
-{
-	return s5k3e2fx_reg_pat[S_RES_PREVIEW].size_w +
-		s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_p;
-}
-
-static uint16_t s5k3e2fx_get_pict_lines_pf(void)
-{
-	return s5k3e2fx_reg_pat[S_RES_CAPTURE].size_h +
-		s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l;
-}
-
-static uint16_t s5k3e2fx_get_pict_pixels_pl(void)
-{
-	return s5k3e2fx_reg_pat[S_RES_CAPTURE].size_w +
-		s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p;
-}
-
-static uint32_t s5k3e2fx_get_pict_max_exp_lc(void)
-{
-	uint32_t snapshot_lines_per_frame;
-
-	if (s5k3e2fx_ctrl->pict_res == S_QTR_SIZE)
-		snapshot_lines_per_frame =
-		s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h +
-		s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l;
-	else
-		snapshot_lines_per_frame = 3961 * 3;
-
-	return snapshot_lines_per_frame;
-}
-
-static int32_t s5k3e2fx_set_fps(struct fps_cfg *fps)
-{
-	/* input is new fps in Q10 format */
-	int32_t rc = 0;
-	enum msm_s_setting setting;
-
-	s5k3e2fx_ctrl->fps_divider = fps->fps_div;
-
-	if (s5k3e2fx_ctrl->sensormode == SENSOR_PREVIEW_MODE)
-		setting = S_RES_PREVIEW;
-	else
-		setting = S_RES_CAPTURE;
-
-  rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
-		REG_FRAME_LENGTH_LINES_MSB,
-		(((s5k3e2fx_reg_pat[setting].size_h +
-			s5k3e2fx_reg_pat[setting].blk_l) *
-			s5k3e2fx_ctrl->fps_divider / 0x400) & 0xFF00) >> 8);
-	if (rc < 0)
-		goto set_fps_done;
-
-  rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
-		REG_FRAME_LENGTH_LINES_LSB,
-		(((s5k3e2fx_reg_pat[setting].size_h +
-			s5k3e2fx_reg_pat[setting].blk_l) *
-			s5k3e2fx_ctrl->fps_divider / 0x400) & 0x00FF));
-
-set_fps_done:
-	return rc;
-}
-
-static int32_t s5k3e2fx_write_exp_gain(uint16_t gain, uint32_t line)
-{
-	int32_t rc = 0;
-
-	uint16_t max_legal_gain = 0x0200;
-	uint32_t ll_ratio; /* Q10 */
-	uint32_t ll_pck, fl_lines;
-	uint16_t offset = 4;
-	uint32_t  gain_msb, gain_lsb;
-	uint32_t  intg_t_msb, intg_t_lsb;
-	uint32_t  ll_pck_msb, ll_pck_lsb;
-
-	struct s5k3e2fx_i2c_reg_conf tbl[2];
-
-	CDBG("Line:%d s5k3e2fx_write_exp_gain \n", __LINE__);
-
-	if (s5k3e2fx_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
-
-		s5k3e2fx_ctrl->my_reg_gain = gain;
-		s5k3e2fx_ctrl->my_reg_line_count = (uint16_t)line;
-
-		fl_lines = s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h +
-			s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l;
-
-		ll_pck = s5k3e2fx_reg_pat[S_RES_PREVIEW].size_w +
-			s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_p;
-
-	} else {
-
-		fl_lines = s5k3e2fx_reg_pat[S_RES_CAPTURE].size_h +
-			s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l;
-
-		ll_pck = s5k3e2fx_reg_pat[S_RES_CAPTURE].size_w +
-			s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p;
-	}
-
-	if (gain > max_legal_gain)
-		gain = max_legal_gain;
-
-	/* in Q10 */
-	line = (line * s5k3e2fx_ctrl->fps_divider);
-
-	if (fl_lines < (line / 0x400))
-		ll_ratio = (line / (fl_lines - offset));
-	else
-		ll_ratio = 0x400;
-
-	/* update gain registers */
-	gain_msb = (gain & 0xFF00) >> 8;
-	gain_lsb = gain & 0x00FF;
-	tbl[0].waddr = REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB;
-	tbl[0].bdata = gain_msb;
-	tbl[1].waddr = REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB;
-	tbl[1].bdata = gain_lsb;
-	rc = s5k3e2fx_i2c_write_table(&tbl[0], ARRAY_SIZE(tbl));
-	if (rc < 0)
-		goto write_gain_done;
-
-	ll_pck = ll_pck * ll_ratio;
-	ll_pck_msb = ((ll_pck / 0x400) & 0xFF00) >> 8;
-	ll_pck_lsb = (ll_pck / 0x400) & 0x00FF;
-	tbl[0].waddr = REG_LINE_LENGTH_PCK_MSB;
-	tbl[0].bdata = ll_pck_msb;
-	tbl[1].waddr = REG_LINE_LENGTH_PCK_LSB;
-	tbl[1].bdata = ll_pck_lsb;
-	rc = s5k3e2fx_i2c_write_table(&tbl[0], ARRAY_SIZE(tbl));
-	if (rc < 0)
-		goto write_gain_done;
-
-	line = line / ll_ratio;
-	intg_t_msb = (line & 0xFF00) >> 8;
-	intg_t_lsb = (line & 0x00FF);
-	tbl[0].waddr = REG_COARSE_INTEGRATION_TIME;
-	tbl[0].bdata = intg_t_msb;
-	tbl[1].waddr = REG_COARSE_INTEGRATION_TIME_LSB;
-	tbl[1].bdata = intg_t_lsb;
-	rc = s5k3e2fx_i2c_write_table(&tbl[0], ARRAY_SIZE(tbl));
-
-write_gain_done:
-	return rc;
-}
-
-static int32_t s5k3e2fx_set_pict_exp_gain(uint16_t gain, uint32_t line)
-{
-	int32_t rc = 0;
-
-	CDBG("Line:%d s5k3e2fx_set_pict_exp_gain \n", __LINE__);
-
-	rc =
-		s5k3e2fx_write_exp_gain(gain, line);
-
-	return rc;
-}
-
-static int32_t s5k3e2fx_video_config(int mode, int res)
-{
-	int32_t rc;
-
-	switch (res) {
-	case S_QTR_SIZE:
-		rc = s5k3e2fx_setting(S_UPDATE_PERIODIC, S_RES_PREVIEW);
-		if (rc < 0)
-			return rc;
-
-		CDBG("s5k3e2fx sensor configuration done!\n");
-		break;
-
-	case S_FULL_SIZE:
-		rc = s5k3e2fx_setting(S_UPDATE_PERIODIC, S_RES_CAPTURE);
-		if (rc < 0)
-			return rc;
-
-		break;
-
-	default:
-		return 0;
-	} /* switch */
-
-	s5k3e2fx_ctrl->prev_res = res;
-	s5k3e2fx_ctrl->curr_res = res;
-	s5k3e2fx_ctrl->sensormode = mode;
-
-	rc =
-		s5k3e2fx_write_exp_gain(s5k3e2fx_ctrl->my_reg_gain,
-			s5k3e2fx_ctrl->my_reg_line_count);
-
-	return rc;
-}
-
-static int32_t s5k3e2fx_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-
-	rc = s5k3e2fx_setting(S_UPDATE_PERIODIC, S_RES_CAPTURE);
-	if (rc < 0)
-		return rc;
-
-	s5k3e2fx_ctrl->curr_res = s5k3e2fx_ctrl->pict_res;
-	s5k3e2fx_ctrl->sensormode = mode;
-
-	return rc;
-}
-
-static int32_t s5k3e2fx_raw_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-
-	rc = s5k3e2fx_setting(S_UPDATE_PERIODIC, S_RES_CAPTURE);
-	if (rc < 0)
-		return rc;
-
-	s5k3e2fx_ctrl->curr_res = s5k3e2fx_ctrl->pict_res;
-	s5k3e2fx_ctrl->sensormode = mode;
-
-	return rc;
-}
-
-static int32_t s5k3e2fx_set_sensor_mode(int mode, int res)
-{
-	int32_t rc = 0;
-
-	switch (mode) {
-	case SENSOR_PREVIEW_MODE:
-		rc = s5k3e2fx_video_config(mode, res);
-		break;
-
-	case SENSOR_SNAPSHOT_MODE:
-		rc = s5k3e2fx_snapshot_config(mode);
-		break;
-
-	case SENSOR_RAW_SNAPSHOT_MODE:
-		rc = s5k3e2fx_raw_snapshot_config(mode);
-		break;
-
-	default:
-		rc = -EINVAL;
-		break;
-	}
-
-	return rc;
-}
-
-static int32_t s5k3e2fx_set_default_focus(void)
-{
-	int32_t rc = 0;
-
-  rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
-		0x3131, 0);
-	if (rc < 0)
-		return rc;
-
-  rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
-		0x3132, 0);
-	if (rc < 0)
-		return rc;
-
-	s5k3e2fx_ctrl->curr_lens_pos = 0;
-
-	return rc;
-}
-
-static int32_t s5k3e2fx_move_focus(int direction, int32_t num_steps)
-{
-	int32_t rc = 0;
-	int32_t i;
-	int16_t step_direction;
-	int16_t actual_step;
-	int16_t next_pos, pos_offset;
-	int16_t init_code = 50;
-	uint8_t next_pos_msb, next_pos_lsb;
-	int16_t s_move[5];
-	uint32_t gain; /* Q10 format */
-
-	if (direction == MOVE_NEAR)
-		step_direction = 20;
-	else if (direction == MOVE_FAR)
-		step_direction = -20;
-	else {
-		CDBG("s5k3e2fx_move_focus failed at line %d ...\n", __LINE__);
-		return -EINVAL;
-	}
-
-	actual_step = step_direction * (int16_t)num_steps;
-	pos_offset = init_code + s5k3e2fx_ctrl->curr_lens_pos;
-	gain = actual_step * 0x400 / 5;
-
-	for (i = 0; i <= 4; i++) {
-		if (actual_step >= 0)
-			s_move[i] = (((i+1)*gain+0x200)-(i*gain+0x200))/0x400;
-		else
-			s_move[i] = (((i+1)*gain-0x200)-(i*gain-0x200))/0x400;
-	}
-
-	/* Ring Damping Code */
-	for (i = 0; i <= 4; i++) {
-		next_pos = (int16_t)(pos_offset + s_move[i]);
-
-		if (next_pos > (738 + init_code))
-			next_pos = 738 + init_code;
-		else if (next_pos < 0)
-			next_pos = 0;
-
-		CDBG("next_position in damping mode = %d\n", next_pos);
-		/* Writing the Values to the actuator */
-		if (next_pos == init_code)
-			next_pos = 0x00;
-
-		next_pos_msb = next_pos >> 8;
-		next_pos_lsb = next_pos & 0x00FF;
-
-		rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
-			0x3131, next_pos_msb);
-		if (rc < 0)
-			break;
-
-		rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
-			0x3132, next_pos_lsb);
-		if (rc < 0)
-			break;
-
-		pos_offset = next_pos;
-		s5k3e2fx_ctrl->curr_lens_pos = pos_offset - init_code;
-		if (i < 4)
-			mdelay(3);
-	}
-
-	return rc;
-}
-
-static int s5k3e2fx_sensor_config(void __user *argp)
-{
-	struct sensor_cfg_data cdata;
-	long   rc = 0;
-
-	if (copy_from_user(&cdata,
-			(void *)argp,
-			sizeof(struct sensor_cfg_data)))
-		return -EFAULT;
-
-	mutex_lock(&s5k3e2fx_mutex);
-
-	CDBG("%s: cfgtype = %d\n", __func__, cdata.cfgtype);
-	switch (cdata.cfgtype) {
-	case CFG_GET_PICT_FPS:
-		s5k3e2fx_get_pict_fps(cdata.cfg.gfps.prevfps,
-			&(cdata.cfg.gfps.pictfps));
-
-		if (copy_to_user((void *)argp, &cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PREV_L_PF:
-		cdata.cfg.prevl_pf = s5k3e2fx_get_prev_lines_pf();
-
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PREV_P_PL:
-		cdata.cfg.prevp_pl = s5k3e2fx_get_prev_pixels_pl();
-
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PICT_L_PF:
-		cdata.cfg.pictl_pf = s5k3e2fx_get_pict_lines_pf();
-
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PICT_P_PL:
-		cdata.cfg.pictp_pl = s5k3e2fx_get_pict_pixels_pl();
-
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PICT_MAX_EXP_LC:
-		cdata.cfg.pict_max_exp_lc =
-			s5k3e2fx_get_pict_max_exp_lc();
-
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_SET_FPS:
-	case CFG_SET_PICT_FPS:
-		rc = s5k3e2fx_set_fps(&(cdata.cfg.fps));
-		break;
-
-	case CFG_SET_EXP_GAIN:
-		rc =
-			s5k3e2fx_write_exp_gain(cdata.cfg.exp_gain.gain,
-				cdata.cfg.exp_gain.line);
-		break;
-
-	case CFG_SET_PICT_EXP_GAIN:
-		CDBG("Line:%d CFG_SET_PICT_EXP_GAIN \n", __LINE__);
-		rc =
-			s5k3e2fx_set_pict_exp_gain(
-				cdata.cfg.exp_gain.gain,
-				cdata.cfg.exp_gain.line);
-		break;
-
-	case CFG_SET_MODE:
-		rc =
-			s5k3e2fx_set_sensor_mode(
-			cdata.mode, cdata.rs);
-		break;
-
-	case CFG_PWR_DOWN:
-		rc = s5k3e2fx_power_down();
-		break;
-
-	case CFG_MOVE_FOCUS:
-		rc =
-			s5k3e2fx_move_focus(
-			cdata.cfg.focus.dir,
-			cdata.cfg.focus.steps);
-		break;
-
-	case CFG_SET_DEFAULT_FOCUS:
-		rc =
-			s5k3e2fx_set_default_focus();
-		break;
-
-	case CFG_GET_AF_MAX_STEPS:
-	case CFG_SET_EFFECT:
-	case CFG_SET_LENS_SHADING:
-	default:
-		rc = -EINVAL;
-		break;
-	}
-
-	mutex_unlock(&s5k3e2fx_mutex);
-	return rc;
-}
-
-static int s5k3e2fx_sensor_probe(const struct msm_camera_sensor_info *info,
-		struct msm_sensor_ctrl *s)
-{
-	int rc = 0;
-
-	rc = i2c_add_driver(&s5k3e2fx_i2c_driver);
-	if (rc < 0 || s5k3e2fx_client == NULL) {
-		rc = -ENOTSUPP;
-		goto probe_fail;
-	}
-
-	msm_camio_clk_rate_set(24000000);
-	mdelay(20);
-
-	rc = s5k3e2fx_probe_init_sensor(info);
-	if (rc < 0)
-		goto probe_fail;
-
-	s->s_init = s5k3e2fx_sensor_open_init;
-	s->s_release = s5k3e2fx_sensor_release;
-	s->s_config  = s5k3e2fx_sensor_config;
-	s->s_mount_angle  = 0;
-	s5k3e2fx_probe_init_done(info);
-
-	return rc;
-
-probe_fail:
-	CDBG("SENSOR PROBE FAILS!\n");
-	return rc;
-}
-
-static int __s5k3e2fx_probe(struct platform_device *pdev)
-{
-	return msm_camera_drv_start(pdev, s5k3e2fx_sensor_probe);
-}
-
-static struct platform_driver msm_camera_driver = {
-	.probe = __s5k3e2fx_probe,
-	.driver = {
-		.name = "msm_camera_s5k3e2fx",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init s5k3e2fx_init(void)
-{
-	return platform_driver_register(&msm_camera_driver);
-}
-
-module_init(s5k3e2fx_init);
-
diff --git a/drivers/media/video/msm/s5k3e2fx.h b/drivers/media/video/msm/s5k3e2fx.h
deleted file mode 100644
index cf3f881..0000000
--- a/drivers/media/video/msm/s5k3e2fx.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright (c) 2009, Code Aurora Forum. 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 CAMSENSOR_S5K3E2FX
-#define CAMSENSOR_S5K3E2FX
-
-#include <mach/board.h>
-#endif /* CAMSENSOR_S5K3E2FX */
diff --git a/drivers/media/video/msm/s5k4e1.c b/drivers/media/video/msm/s5k4e1.c
deleted file mode 100644
index 30572d8..0000000
--- a/drivers/media/video/msm/s5k4e1.c
+++ /dev/null
@@ -1,1103 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. 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/delay.h>
-#include <linux/debugfs.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/slab.h>
-#include <linux/gpio.h>
-#include <linux/bitops.h>
-#include <mach/camera.h>
-#include <media/msm_camera.h>
-#include "s5k4e1.h"
-
-/* 16bit address - 8 bit context register structure */
-#define Q8	0x00000100
-#define Q10	0x00000400
-
-/* MCLK */
-#define S5K4E1_MASTER_CLK_RATE 24000000
-
-/* AF Total steps parameters */
-#define S5K4E1_TOTAL_STEPS_NEAR_TO_FAR	32
-
-#define S5K4E1_REG_PREV_FRAME_LEN_1	31
-#define S5K4E1_REG_PREV_FRAME_LEN_2	32
-#define S5K4E1_REG_PREV_LINE_LEN_1	33
-#define S5K4E1_REG_PREV_LINE_LEN_2	34
-
-#define S5K4E1_REG_SNAP_FRAME_LEN_1	15
-#define S5K4E1_REG_SNAP_FRAME_LEN_2	16
-#define  S5K4E1_REG_SNAP_LINE_LEN_1	17
-#define S5K4E1_REG_SNAP_LINE_LEN_2	18
-#define MSB                             1
-#define LSB                             0
-
-struct s5k4e1_work_t {
-	struct work_struct work;
-};
-
-static struct s5k4e1_work_t *s5k4e1_sensorw;
-static struct s5k4e1_work_t *s5k4e1_af_sensorw;
-static struct i2c_client *s5k4e1_af_client;
-static struct i2c_client *s5k4e1_client;
-
-struct s5k4e1_ctrl_t {
-	const struct  msm_camera_sensor_info *sensordata;
-
-	uint32_t sensormode;
-	uint32_t fps_divider;/* init to 1 * 0x00000400 */
-	uint32_t pict_fps_divider;/* init to 1 * 0x00000400 */
-	uint16_t fps;
-
-	uint16_t curr_lens_pos;
-	uint16_t curr_step_pos;
-	uint16_t my_reg_gain;
-	uint32_t my_reg_line_count;
-	uint16_t total_lines_per_frame;
-
-	enum s5k4e1_resolution_t prev_res;
-	enum s5k4e1_resolution_t pict_res;
-	enum s5k4e1_resolution_t curr_res;
-	enum s5k4e1_test_mode_t  set_test;
-};
-
-static bool CSI_CONFIG;
-static struct s5k4e1_ctrl_t *s5k4e1_ctrl;
-
-static DECLARE_WAIT_QUEUE_HEAD(s5k4e1_wait_queue);
-static DECLARE_WAIT_QUEUE_HEAD(s5k4e1_af_wait_queue);
-DEFINE_MUTEX(s5k4e1_mut);
-
-static uint16_t prev_line_length_pck;
-static uint16_t prev_frame_length_lines;
-static uint16_t snap_line_length_pck;
-static uint16_t snap_frame_length_lines;
-
-static int s5k4e1_i2c_rxdata(unsigned short saddr,
-		unsigned char *rxdata, int length)
-{
-	struct i2c_msg msgs[] = {
-		{
-			.addr  = saddr,
-			.flags = 0,
-			.len   = 1,
-			.buf   = rxdata,
-		},
-		{
-			.addr  = saddr,
-			.flags = I2C_M_RD,
-			.len   = 1,
-			.buf   = rxdata,
-		},
-	};
-	if (i2c_transfer(s5k4e1_client->adapter, msgs, 2) < 0) {
-		CDBG("s5k4e1_i2c_rxdata faild 0x%x\n", saddr);
-		return -EIO;
-	}
-	return 0;
-}
-
-static int32_t s5k4e1_i2c_txdata(unsigned short saddr,
-		unsigned char *txdata, int length)
-{
-	struct i2c_msg msg[] = {
-		{
-			.addr = saddr,
-			.flags = 0,
-			.len = length,
-			.buf = txdata,
-		},
-	};
-	if (i2c_transfer(s5k4e1_client->adapter, msg, 1) < 0) {
-		CDBG("s5k4e1_i2c_txdata faild 0x%x\n", saddr);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int32_t s5k4e1_i2c_read(unsigned short raddr,
-		unsigned short *rdata, int rlen)
-{
-	int32_t rc = 0;
-	unsigned char buf[2];
-
-	if (!rdata)
-		return -EIO;
-
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (raddr & 0xFF00) >> 8;
-	buf[1] = (raddr & 0x00FF);
-	rc = s5k4e1_i2c_rxdata(s5k4e1_client->addr, buf, rlen);
-	if (rc < 0) {
-		CDBG("s5k4e1_i2c_read 0x%x failed!\n", raddr);
-		return rc;
-	}
-	*rdata = (rlen == 2 ? buf[0] << 8 | buf[1] : buf[0]);
-	CDBG("s5k4e1_i2c_read 0x%x val = 0x%x!\n", raddr, *rdata);
-
-	return rc;
-}
-
-static int32_t s5k4e1_i2c_write_b_sensor(unsigned short waddr, uint8_t bdata)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[3];
-
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (waddr & 0xFF00) >> 8;
-	buf[1] = (waddr & 0x00FF);
-	buf[2] = bdata;
-	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
-	rc = s5k4e1_i2c_txdata(s5k4e1_client->addr, buf, 3);
-	if (rc < 0) {
-		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
-				waddr, bdata);
-	}
-	return rc;
-}
-
-static int32_t s5k4e1_i2c_write_b_table(struct s5k4e1_i2c_reg_conf const
-		*reg_conf_tbl, int num)
-{
-	int i;
-	int32_t rc = -EIO;
-
-	for (i = 0; i < num; i++) {
-		rc = s5k4e1_i2c_write_b_sensor(reg_conf_tbl->waddr,
-				reg_conf_tbl->wdata);
-		if (rc < 0)
-			break;
-		reg_conf_tbl++;
-	}
-	return rc;
-}
-
-static int32_t s5k4e1_af_i2c_txdata(unsigned short saddr,
-		unsigned char *txdata, int length)
-{
-	struct i2c_msg msg[] = {
-		{
-			.addr = saddr,
-			.flags = 0,
-			.len = length,
-			.buf = txdata,
-		},
-	};
-	if (i2c_transfer(s5k4e1_af_client->adapter, msg, 1) < 0) {
-		pr_err("s5k4e1_af_i2c_txdata faild 0x%x\n", saddr);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int32_t s5k4e1_af_i2c_write_b_sensor(uint8_t waddr, uint8_t bdata)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[2];
-
-	memset(buf, 0, sizeof(buf));
-	buf[0] = waddr;
-	buf[1] = bdata;
-	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
-	rc = s5k4e1_af_i2c_txdata(s5k4e1_af_client->addr << 1, buf, 2);
-	if (rc < 0) {
-		pr_err("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
-				waddr, bdata);
-	}
-	return rc;
-}
-
-static void s5k4e1_start_stream(void)
-{
-	s5k4e1_i2c_write_b_sensor(0x0100, 0x01);/* streaming on */
-}
-
-static void s5k4e1_stop_stream(void)
-{
-	s5k4e1_i2c_write_b_sensor(0x0100, 0x00);/* streaming off */
-}
-
-static void s5k4e1_group_hold_on(void)
-{
-	s5k4e1_i2c_write_b_sensor(0x0104, 0x01);
-}
-
-static void s5k4e1_group_hold_off(void)
-{
-	s5k4e1_i2c_write_b_sensor(0x0104, 0x0);
-}
-
-static void s5k4e1_get_pict_fps(uint16_t fps, uint16_t *pfps)
-{
-	/* input fps is preview fps in Q8 format */
-	uint32_t divider, d1, d2;
-
-	d1 = (prev_frame_length_lines * 0x00000400) / snap_frame_length_lines;
-	d2 = (prev_line_length_pck * 0x00000400) / snap_line_length_pck;
-	divider = (d1 * d2) / 0x400;
-
-	/*Verify PCLK settings and frame sizes.*/
-	*pfps = (uint16_t) (fps * divider / 0x400);
-}
-
-static uint16_t s5k4e1_get_prev_lines_pf(void)
-{
-	if (s5k4e1_ctrl->prev_res == QTR_SIZE)
-		return prev_frame_length_lines;
-	else
-		return snap_frame_length_lines;
-}
-
-static uint16_t s5k4e1_get_prev_pixels_pl(void)
-{
-	if (s5k4e1_ctrl->prev_res == QTR_SIZE)
-		return prev_line_length_pck;
-	else
-		return snap_line_length_pck;
-}
-
-static uint16_t s5k4e1_get_pict_lines_pf(void)
-{
-	if (s5k4e1_ctrl->pict_res == QTR_SIZE)
-		return prev_frame_length_lines;
-	else
-		return snap_frame_length_lines;
-}
-
-static uint16_t s5k4e1_get_pict_pixels_pl(void)
-{
-	if (s5k4e1_ctrl->pict_res == QTR_SIZE)
-		return prev_line_length_pck;
-	else
-		return snap_line_length_pck;
-}
-
-static uint32_t s5k4e1_get_pict_max_exp_lc(void)
-{
-	return snap_frame_length_lines * 24;
-}
-
-static int32_t s5k4e1_set_fps(struct fps_cfg   *fps)
-{
-	uint16_t total_lines_per_frame;
-	int32_t rc = 0;
-
-	s5k4e1_ctrl->fps_divider = fps->fps_div;
-	s5k4e1_ctrl->pict_fps_divider = fps->pict_fps_div;
-
-	if (s5k4e1_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
-		total_lines_per_frame = (uint16_t)
-		((prev_frame_length_lines * s5k4e1_ctrl->fps_divider) / 0x400);
-	} else {
-		total_lines_per_frame = (uint16_t)
-		((snap_frame_length_lines * s5k4e1_ctrl->fps_divider) / 0x400);
-	}
-
-	s5k4e1_group_hold_on();
-	rc = s5k4e1_i2c_write_b_sensor(0x0340,
-			((total_lines_per_frame & 0xFF00) >> 8));
-	rc = s5k4e1_i2c_write_b_sensor(0x0341,
-			(total_lines_per_frame & 0x00FF));
-	s5k4e1_group_hold_off();
-
-	return rc;
-}
-
-static inline uint8_t s5k4e1_byte(uint16_t word, uint8_t offset)
-{
-	return word >> (offset * BITS_PER_BYTE);
-}
-
-static int32_t s5k4e1_write_exp_gain(uint16_t gain, uint32_t line)
-{
-	uint16_t max_legal_gain = 0x0200;
-	int32_t rc = 0;
-	static uint32_t fl_lines;
-
-	if (gain > max_legal_gain) {
-		pr_debug("Max legal gain Line:%d\n", __LINE__);
-		gain = max_legal_gain;
-	}
-	/* Analogue Gain */
-	s5k4e1_i2c_write_b_sensor(0x0204, s5k4e1_byte(gain, MSB));
-	s5k4e1_i2c_write_b_sensor(0x0205, s5k4e1_byte(gain, LSB));
-
-	if (line > (prev_frame_length_lines - 4)) {
-		fl_lines = line+4;
-		s5k4e1_group_hold_on();
-		s5k4e1_i2c_write_b_sensor(0x0340, s5k4e1_byte(fl_lines, MSB));
-		s5k4e1_i2c_write_b_sensor(0x0341, s5k4e1_byte(fl_lines, LSB));
-		/* Coarse Integration Time */
-		s5k4e1_i2c_write_b_sensor(0x0202, s5k4e1_byte(line, MSB));
-		s5k4e1_i2c_write_b_sensor(0x0203, s5k4e1_byte(line, LSB));
-		s5k4e1_group_hold_off();
-	} else if (line < (fl_lines - 4)) {
-		fl_lines = line+4;
-		if (fl_lines < prev_frame_length_lines)
-			fl_lines = prev_frame_length_lines;
-
-		s5k4e1_group_hold_on();
-		/* Coarse Integration Time */
-		s5k4e1_i2c_write_b_sensor(0x0202, s5k4e1_byte(line, MSB));
-		s5k4e1_i2c_write_b_sensor(0x0203, s5k4e1_byte(line, LSB));
-		s5k4e1_i2c_write_b_sensor(0x0340, s5k4e1_byte(fl_lines, MSB));
-		s5k4e1_i2c_write_b_sensor(0x0341, s5k4e1_byte(fl_lines, LSB));
-		s5k4e1_group_hold_off();
-	} else {
-		fl_lines = line+4;
-		s5k4e1_group_hold_on();
-		/* Coarse Integration Time */
-		s5k4e1_i2c_write_b_sensor(0x0202, s5k4e1_byte(line, MSB));
-		s5k4e1_i2c_write_b_sensor(0x0203, s5k4e1_byte(line, LSB));
-		s5k4e1_group_hold_off();
-	}
-	return rc;
-}
-
-static int32_t s5k4e1_set_pict_exp_gain(uint16_t gain, uint32_t line)
-{
-	uint16_t max_legal_gain = 0x0200;
-	uint16_t min_ll_pck = 0x0AB2;
-	uint32_t ll_pck, fl_lines;
-	uint32_t ll_ratio;
-	int32_t rc = 0;
-	uint8_t gain_msb, gain_lsb;
-	uint8_t intg_time_msb, intg_time_lsb;
-	uint8_t ll_pck_msb, ll_pck_lsb;
-
-	if (gain > max_legal_gain) {
-		pr_debug("Max legal gain Line:%d\n", __LINE__);
-		gain = max_legal_gain;
-	}
-
-	pr_debug("s5k4e1_write_exp_gain : gain = %d line = %d\n", gain, line);
-	line = (uint32_t) (line * s5k4e1_ctrl->pict_fps_divider);
-	fl_lines = snap_frame_length_lines;
-	ll_pck = snap_line_length_pck;
-
-	if (fl_lines < (line / 0x400))
-		ll_ratio = (line / (fl_lines - 4));
-	else
-		ll_ratio = 0x400;
-
-	ll_pck = ll_pck * ll_ratio / 0x400;
-	line = line / ll_ratio;
-	if (ll_pck < min_ll_pck)
-		ll_pck = min_ll_pck;
-
-	gain_msb = (uint8_t) ((gain & 0xFF00) >> 8);
-	gain_lsb = (uint8_t) (gain & 0x00FF);
-
-	intg_time_msb = (uint8_t) ((line & 0xFF00) >> 8);
-	intg_time_lsb = (uint8_t) (line & 0x00FF);
-
-	ll_pck_msb = (uint8_t) ((ll_pck & 0xFF00) >> 8);
-	ll_pck_lsb = (uint8_t) (ll_pck & 0x00FF);
-
-	s5k4e1_group_hold_on();
-	s5k4e1_i2c_write_b_sensor(0x0204, gain_msb); /* Analogue Gain */
-	s5k4e1_i2c_write_b_sensor(0x0205, gain_lsb);
-
-	s5k4e1_i2c_write_b_sensor(0x0342, ll_pck_msb);
-	s5k4e1_i2c_write_b_sensor(0x0343, ll_pck_lsb);
-
-	/* Coarse Integration Time */
-	s5k4e1_i2c_write_b_sensor(0x0202, intg_time_msb);
-	s5k4e1_i2c_write_b_sensor(0x0203, intg_time_lsb);
-	s5k4e1_group_hold_off();
-
-	return rc;
-}
-
-static int32_t s5k4e1_move_focus(int direction,
-		int32_t num_steps)
-{
-	int16_t step_direction, actual_step, next_position;
-	uint8_t code_val_msb, code_val_lsb;
-
-	if (direction == MOVE_NEAR)
-		step_direction = 16;
-	else
-		step_direction = -16;
-
-	actual_step = (int16_t) (step_direction * num_steps);
-	next_position = (int16_t) (s5k4e1_ctrl->curr_lens_pos + actual_step);
-
-	if (next_position > 1023)
-		next_position = 1023;
-	else if (next_position < 0)
-		next_position = 0;
-
-	code_val_msb = next_position >> 4;
-	code_val_lsb = (next_position & 0x000F) << 4;
-
-	if (s5k4e1_af_i2c_write_b_sensor(code_val_msb, code_val_lsb) < 0) {
-		pr_err("move_focus failed at line %d ...\n", __LINE__);
-		return -EBUSY;
-	}
-
-	s5k4e1_ctrl->curr_lens_pos = next_position;
-	return 0;
-}
-
-static int32_t s5k4e1_set_default_focus(uint8_t af_step)
-{
-	int32_t rc = 0;
-
-	if (s5k4e1_ctrl->curr_step_pos != 0) {
-		rc = s5k4e1_move_focus(MOVE_FAR,
-				s5k4e1_ctrl->curr_step_pos);
-	} else {
-		s5k4e1_af_i2c_write_b_sensor(0x00, 0x00);
-	}
-
-	s5k4e1_ctrl->curr_lens_pos = 0;
-	s5k4e1_ctrl->curr_step_pos = 0;
-
-	return rc;
-}
-
-static int32_t s5k4e1_test(enum s5k4e1_test_mode_t mo)
-{
-	int32_t rc = 0;
-
-	if (mo != TEST_OFF)
-		rc = s5k4e1_i2c_write_b_sensor(0x0601, (uint8_t) mo);
-
-	return rc;
-}
-
-static void s5k4e1_reset_sensor(void)
-{
-	s5k4e1_i2c_write_b_sensor(0x103, 0x1);
-}
-
-static int32_t s5k4e1_sensor_setting(int update_type, int rt)
-{
-
-	int32_t rc = 0;
-	struct msm_camera_csi_params s5k4e1_csi_params;
-
-	s5k4e1_stop_stream();
-	msleep(30);
-
-	if (update_type == REG_INIT) {
-		s5k4e1_reset_sensor();
-		s5k4e1_i2c_write_b_table(s5k4e1_regs.reg_mipi,
-				s5k4e1_regs.reg_mipi_size);
-		s5k4e1_i2c_write_b_table(s5k4e1_regs.rec_settings,
-				s5k4e1_regs.rec_size);
-		s5k4e1_i2c_write_b_table(s5k4e1_regs.reg_pll_p,
-				s5k4e1_regs.reg_pll_p_size);
-		CSI_CONFIG = 0;
-	} else if (update_type == UPDATE_PERIODIC) {
-		if (rt == RES_PREVIEW)
-			s5k4e1_i2c_write_b_table(s5k4e1_regs.reg_prev,
-					s5k4e1_regs.reg_prev_size);
-		else
-			s5k4e1_i2c_write_b_table(s5k4e1_regs.reg_snap,
-					s5k4e1_regs.reg_snap_size);
-		msleep(20);
-		if (!CSI_CONFIG) {
-			msm_camio_vfe_clk_rate_set(192000000);
-			s5k4e1_csi_params.data_format = CSI_10BIT;
-			s5k4e1_csi_params.lane_cnt = 1;
-			s5k4e1_csi_params.lane_assign = 0xe4;
-			s5k4e1_csi_params.dpcm_scheme = 0;
-			s5k4e1_csi_params.settle_cnt = 24;
-			rc = msm_camio_csi_config(&s5k4e1_csi_params);
-			msleep(20);
-			CSI_CONFIG = 1;
-		}
-		s5k4e1_start_stream();
-		msleep(30);
-	}
-	return rc;
-}
-
-static int32_t s5k4e1_video_config(int mode)
-{
-
-	int32_t rc = 0;
-	int rt;
-	CDBG("video config\n");
-	/* change sensor resolution if needed */
-	if (s5k4e1_ctrl->prev_res == QTR_SIZE)
-		rt = RES_PREVIEW;
-	else
-		rt = RES_CAPTURE;
-	if (s5k4e1_sensor_setting(UPDATE_PERIODIC, rt) < 0)
-		return rc;
-	if (s5k4e1_ctrl->set_test) {
-		if (s5k4e1_test(s5k4e1_ctrl->set_test) < 0)
-			return  rc;
-	}
-
-	s5k4e1_ctrl->curr_res = s5k4e1_ctrl->prev_res;
-	s5k4e1_ctrl->sensormode = mode;
-	return rc;
-}
-
-static int32_t s5k4e1_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-	int rt;
-
-	/*change sensor resolution if needed */
-	if (s5k4e1_ctrl->curr_res != s5k4e1_ctrl->pict_res) {
-		if (s5k4e1_ctrl->pict_res == QTR_SIZE)
-			rt = RES_PREVIEW;
-		else
-			rt = RES_CAPTURE;
-		if (s5k4e1_sensor_setting(UPDATE_PERIODIC, rt) < 0)
-			return rc;
-	}
-
-	s5k4e1_ctrl->curr_res = s5k4e1_ctrl->pict_res;
-	s5k4e1_ctrl->sensormode = mode;
-	return rc;
-}
-
-static int32_t s5k4e1_raw_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-	int rt;
-
-	/* change sensor resolution if needed */
-	if (s5k4e1_ctrl->curr_res != s5k4e1_ctrl->pict_res) {
-		if (s5k4e1_ctrl->pict_res == QTR_SIZE)
-			rt = RES_PREVIEW;
-		else
-			rt = RES_CAPTURE;
-		if (s5k4e1_sensor_setting(UPDATE_PERIODIC, rt) < 0)
-			return rc;
-	}
-
-	s5k4e1_ctrl->curr_res = s5k4e1_ctrl->pict_res;
-	s5k4e1_ctrl->sensormode = mode;
-	return rc;
-}
-
-static int32_t s5k4e1_set_sensor_mode(int mode,
-		int res)
-{
-	int32_t rc = 0;
-
-	switch (mode) {
-	case SENSOR_PREVIEW_MODE:
-		rc = s5k4e1_video_config(mode);
-		break;
-	case SENSOR_SNAPSHOT_MODE:
-		rc = s5k4e1_snapshot_config(mode);
-		break;
-	case SENSOR_RAW_SNAPSHOT_MODE:
-		rc = s5k4e1_raw_snapshot_config(mode);
-		break;
-	default:
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
-
-static int32_t s5k4e1_power_down(void)
-{
-	s5k4e1_stop_stream();
-	return 0;
-}
-
-static int s5k4e1_probe_init_done(const struct msm_camera_sensor_info *data)
-{
-	CDBG("probe done\n");
-	gpio_free(data->sensor_reset);
-	return 0;
-}
-
-static int s5k4e1_probe_init_sensor(const struct msm_camera_sensor_info *data)
-{
-	int32_t rc = 0;
-	uint16_t regaddress1 = 0x0000;
-	uint16_t regaddress2 = 0x0001;
-	uint16_t chipid1 = 0;
-	uint16_t chipid2 = 0;
-
-	CDBG("%s: %d\n", __func__, __LINE__);
-	CDBG(" s5k4e1_probe_init_sensor is called\n");
-
-	rc = gpio_request(data->sensor_reset, "s5k4e1");
-	CDBG(" s5k4e1_probe_init_sensor\n");
-	if (!rc) {
-		CDBG("sensor_reset = %d\n", rc);
-		gpio_direction_output(data->sensor_reset, 0);
-		msleep(50);
-		gpio_set_value_cansleep(data->sensor_reset, 1);
-		msleep(20);
-	} else
-		goto gpio_req_fail;
-
-	msleep(20);
-
-	s5k4e1_i2c_read(regaddress1, &chipid1, 1);
-	if (chipid1 != 0x4E) {
-		rc = -ENODEV;
-		CDBG("s5k4e1_probe_init_sensor fail chip id doesnot match\n");
-		goto init_probe_fail;
-	}
-
-	s5k4e1_i2c_read(regaddress2, &chipid2 , 1);
-	if (chipid2 != 0x10) {
-		rc = -ENODEV;
-		CDBG("s5k4e1_probe_init_sensor fail chip id doesnot match\n");
-		goto init_probe_fail;
-	}
-
-	CDBG("ID: %d\n", chipid1);
-	CDBG("ID: %d\n", chipid1);
-
-	return rc;
-
-init_probe_fail:
-	CDBG(" s5k4e1_probe_init_sensor fails\n");
-	gpio_set_value_cansleep(data->sensor_reset, 0);
-	s5k4e1_probe_init_done(data);
-	if (data->vcm_enable) {
-		int ret = gpio_request(data->vcm_pwd, "s5k4e1_af");
-		if (!ret) {
-			gpio_direction_output(data->vcm_pwd, 0);
-			msleep(20);
-			gpio_free(data->vcm_pwd);
-		}
-	}
-gpio_req_fail:
-	return rc;
-}
-
-int s5k4e1_sensor_open_init(const struct msm_camera_sensor_info *data)
-{
-	int32_t rc = 0;
-
-	CDBG("%s: %d\n", __func__, __LINE__);
-	CDBG("Calling s5k4e1_sensor_open_init\n");
-
-	s5k4e1_ctrl = kzalloc(sizeof(struct s5k4e1_ctrl_t), GFP_KERNEL);
-	if (!s5k4e1_ctrl) {
-		CDBG("s5k4e1_init failed!\n");
-		rc = -ENOMEM;
-		goto init_done;
-	}
-	s5k4e1_ctrl->fps_divider = 1 * 0x00000400;
-	s5k4e1_ctrl->pict_fps_divider = 1 * 0x00000400;
-	s5k4e1_ctrl->set_test = TEST_OFF;
-	s5k4e1_ctrl->prev_res = QTR_SIZE;
-	s5k4e1_ctrl->pict_res = FULL_SIZE;
-
-	if (data)
-		s5k4e1_ctrl->sensordata = data;
-
-	prev_frame_length_lines =
-	((s5k4e1_regs.reg_prev[S5K4E1_REG_PREV_FRAME_LEN_1].wdata << 8) |
-		s5k4e1_regs.reg_prev[S5K4E1_REG_PREV_FRAME_LEN_2].wdata);
-
-	prev_line_length_pck =
-	(s5k4e1_regs.reg_prev[S5K4E1_REG_PREV_LINE_LEN_1].wdata << 8) |
-		s5k4e1_regs.reg_prev[S5K4E1_REG_PREV_LINE_LEN_2].wdata;
-
-	snap_frame_length_lines =
-	(s5k4e1_regs.reg_snap[S5K4E1_REG_SNAP_FRAME_LEN_1].wdata << 8) |
-		s5k4e1_regs.reg_snap[S5K4E1_REG_SNAP_FRAME_LEN_2].wdata;
-
-	snap_line_length_pck =
-	(s5k4e1_regs.reg_snap[S5K4E1_REG_SNAP_LINE_LEN_1].wdata << 8) |
-		s5k4e1_regs.reg_snap[S5K4E1_REG_SNAP_LINE_LEN_1].wdata;
-
-	/* enable mclk first */
-	msm_camio_clk_rate_set(S5K4E1_MASTER_CLK_RATE);
-	rc = s5k4e1_probe_init_sensor(data);
-	if (rc < 0)
-		goto init_fail;
-
-	CDBG("init settings\n");
-	if (s5k4e1_ctrl->prev_res == QTR_SIZE)
-		rc = s5k4e1_sensor_setting(REG_INIT, RES_PREVIEW);
-	else
-		rc = s5k4e1_sensor_setting(REG_INIT, RES_CAPTURE);
-	s5k4e1_ctrl->fps = 30 * Q8;
-
-	/* enable AF actuator */
-	if (s5k4e1_ctrl->sensordata->vcm_enable) {
-		CDBG("enable AF actuator, gpio = %d\n",
-			 s5k4e1_ctrl->sensordata->vcm_pwd);
-		rc = gpio_request(s5k4e1_ctrl->sensordata->vcm_pwd,
-						"s5k4e1_af");
-		if (!rc)
-			gpio_direction_output(
-				s5k4e1_ctrl->sensordata->vcm_pwd,
-				 1);
-		else {
-			pr_err("s5k4e1_ctrl gpio request failed!\n");
-			goto init_fail;
-		}
-		msleep(20);
-		rc = s5k4e1_set_default_focus(0);
-		if (rc < 0) {
-			gpio_direction_output(s5k4e1_ctrl->sensordata->vcm_pwd,
-								0);
-			gpio_free(s5k4e1_ctrl->sensordata->vcm_pwd);
-		}
-	}
-	if (rc < 0)
-		goto init_fail;
-	else
-		goto init_done;
-init_fail:
-	CDBG("init_fail\n");
-	s5k4e1_probe_init_done(data);
-init_done:
-	CDBG("init_done\n");
-	return rc;
-}
-
-static int s5k4e1_init_client(struct i2c_client *client)
-{
-	/* Initialize the MSM_CAMI2C Chip */
-	init_waitqueue_head(&s5k4e1_wait_queue);
-	return 0;
-}
-
-static int s5k4e1_af_init_client(struct i2c_client *client)
-{
-	/* Initialize the MSM_CAMI2C Chip */
-	init_waitqueue_head(&s5k4e1_af_wait_queue);
-	return 0;
-}
-
-static const struct i2c_device_id s5k4e1_af_i2c_id[] = {
-	{"s5k4e1_af", 0},
-	{ }
-};
-
-static int s5k4e1_af_i2c_probe(struct i2c_client *client,
-		const struct i2c_device_id *id)
-{
-	int rc = 0;
-	CDBG("s5k4e1_af_probe called!\n");
-
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		CDBG("i2c_check_functionality failed\n");
-		goto probe_failure;
-	}
-
-	s5k4e1_af_sensorw = kzalloc(sizeof(struct s5k4e1_work_t), GFP_KERNEL);
-	if (!s5k4e1_af_sensorw) {
-		CDBG("kzalloc failed.\n");
-		rc = -ENOMEM;
-		goto probe_failure;
-	}
-
-	i2c_set_clientdata(client, s5k4e1_af_sensorw);
-	s5k4e1_af_init_client(client);
-	s5k4e1_af_client = client;
-
-	msleep(50);
-
-	CDBG("s5k4e1_af_probe successed! rc = %d\n", rc);
-	return 0;
-
-probe_failure:
-	CDBG("s5k4e1_af_probe failed! rc = %d\n", rc);
-	return rc;
-}
-
-static const struct i2c_device_id s5k4e1_i2c_id[] = {
-	{"s5k4e1", 0},
-	{ }
-};
-
-static int s5k4e1_i2c_probe(struct i2c_client *client,
-		const struct i2c_device_id *id)
-{
-	int rc = 0;
-	CDBG("s5k4e1_probe called!\n");
-
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		CDBG("i2c_check_functionality failed\n");
-		goto probe_failure;
-	}
-
-	s5k4e1_sensorw = kzalloc(sizeof(struct s5k4e1_work_t), GFP_KERNEL);
-	if (!s5k4e1_sensorw) {
-		CDBG("kzalloc failed.\n");
-		rc = -ENOMEM;
-		goto probe_failure;
-	}
-
-	i2c_set_clientdata(client, s5k4e1_sensorw);
-	s5k4e1_init_client(client);
-	s5k4e1_client = client;
-
-	msleep(50);
-
-	CDBG("s5k4e1_probe successed! rc = %d\n", rc);
-	return 0;
-
-probe_failure:
-	CDBG("s5k4e1_probe failed! rc = %d\n", rc);
-	return rc;
-}
-
-static int __devexit s5k4e1_remove(struct i2c_client *client)
-{
-	struct s5k4e1_work_t *sensorw = i2c_get_clientdata(client);
-	free_irq(client->irq, sensorw);
-	s5k4e1_client = NULL;
-	kfree(sensorw);
-	return 0;
-}
-
-static int __devexit s5k4e1_af_remove(struct i2c_client *client)
-{
-	struct s5k4e1_work_t *s5k4e1_af = i2c_get_clientdata(client);
-	free_irq(client->irq, s5k4e1_af);
-	s5k4e1_af_client = NULL;
-	kfree(s5k4e1_af);
-	return 0;
-}
-
-static struct i2c_driver s5k4e1_i2c_driver = {
-	.id_table = s5k4e1_i2c_id,
-	.probe  = s5k4e1_i2c_probe,
-	.remove = __exit_p(s5k4e1_i2c_remove),
-	.driver = {
-		.name = "s5k4e1",
-	},
-};
-
-static struct i2c_driver s5k4e1_af_i2c_driver = {
-	.id_table = s5k4e1_af_i2c_id,
-	.probe  = s5k4e1_af_i2c_probe,
-	.remove = __exit_p(s5k4e1_af_i2c_remove),
-	.driver = {
-		.name = "s5k4e1_af",
-	},
-};
-
-int s5k4e1_sensor_config(void __user *argp)
-{
-	struct sensor_cfg_data cdata;
-	long   rc = 0;
-	if (copy_from_user(&cdata,
-				(void *)argp,
-				sizeof(struct sensor_cfg_data)))
-		return -EFAULT;
-	mutex_lock(&s5k4e1_mut);
-	CDBG("s5k4e1_sensor_config: cfgtype = %d\n",
-			cdata.cfgtype);
-	switch (cdata.cfgtype) {
-	case CFG_GET_PICT_FPS:
-		s5k4e1_get_pict_fps(
-			cdata.cfg.gfps.prevfps,
-			&(cdata.cfg.gfps.pictfps));
-
-		if (copy_to_user((void *)argp,
-			&cdata,
-			sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-	case CFG_GET_PREV_L_PF:
-		cdata.cfg.prevl_pf =
-			s5k4e1_get_prev_lines_pf();
-
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-	case CFG_GET_PREV_P_PL:
-		cdata.cfg.prevp_pl =
-			s5k4e1_get_prev_pixels_pl();
-
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-	case CFG_GET_PICT_L_PF:
-		cdata.cfg.pictl_pf =
-			s5k4e1_get_pict_lines_pf();
-
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-	case CFG_GET_PICT_P_PL:
-		cdata.cfg.pictp_pl =
-			s5k4e1_get_pict_pixels_pl();
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-	case CFG_GET_PICT_MAX_EXP_LC:
-		cdata.cfg.pict_max_exp_lc =
-			s5k4e1_get_pict_max_exp_lc();
-
-		if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-	case CFG_SET_FPS:
-	case CFG_SET_PICT_FPS:
-		rc = s5k4e1_set_fps(&(cdata.cfg.fps));
-		break;
-	case CFG_SET_EXP_GAIN:
-		rc = s5k4e1_write_exp_gain(cdata.cfg.exp_gain.gain,
-				cdata.cfg.exp_gain.line);
-		break;
-	case CFG_SET_PICT_EXP_GAIN:
-		rc = s5k4e1_set_pict_exp_gain(cdata.cfg.exp_gain.gain,
-				cdata.cfg.exp_gain.line);
-		break;
-	case CFG_SET_MODE:
-		rc = s5k4e1_set_sensor_mode(cdata.mode, cdata.rs);
-		break;
-	case CFG_PWR_DOWN:
-		rc = s5k4e1_power_down();
-		break;
-	case CFG_MOVE_FOCUS:
-		rc = s5k4e1_move_focus(cdata.cfg.focus.dir,
-				cdata.cfg.focus.steps);
-		break;
-	case CFG_SET_DEFAULT_FOCUS:
-		rc = s5k4e1_set_default_focus(cdata.cfg.focus.steps);
-		break;
-	case CFG_GET_AF_MAX_STEPS:
-		cdata.max_steps = S5K4E1_TOTAL_STEPS_NEAR_TO_FAR;
-		if (copy_to_user((void *)argp,
-					&cdata,
-				sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-	case CFG_SET_EFFECT:
-		rc = s5k4e1_set_default_focus(cdata.cfg.effect);
-		break;
-	default:
-		rc = -EFAULT;
-		break;
-	}
-	mutex_unlock(&s5k4e1_mut);
-
-	return rc;
-}
-
-static int s5k4e1_sensor_release(void)
-{
-	int rc = -EBADF;
-
-	mutex_lock(&s5k4e1_mut);
-	s5k4e1_power_down();
-	msleep(20);
-	gpio_set_value_cansleep(s5k4e1_ctrl->sensordata->sensor_reset, 0);
-	usleep_range(5000, 5100);
-	gpio_free(s5k4e1_ctrl->sensordata->sensor_reset);
-	if (s5k4e1_ctrl->sensordata->vcm_enable) {
-		gpio_set_value_cansleep(s5k4e1_ctrl->sensordata->vcm_pwd, 0);
-		gpio_free(s5k4e1_ctrl->sensordata->vcm_pwd);
-	}
-	kfree(s5k4e1_ctrl);
-	s5k4e1_ctrl = NULL;
-	CDBG("s5k4e1_release completed\n");
-	mutex_unlock(&s5k4e1_mut);
-
-	return rc;
-}
-
-static int s5k4e1_sensor_probe(const struct msm_camera_sensor_info *info,
-		struct msm_sensor_ctrl *s)
-{
-	int rc = 0;
-
-	rc = i2c_add_driver(&s5k4e1_i2c_driver);
-	if (rc < 0 || s5k4e1_client == NULL) {
-		rc = -ENOTSUPP;
-		CDBG("I2C add driver failed");
-		goto probe_fail_1;
-	}
-
-	rc = i2c_add_driver(&s5k4e1_af_i2c_driver);
-	if (rc < 0 || s5k4e1_af_client == NULL) {
-		rc = -ENOTSUPP;
-		CDBG("I2C add driver failed");
-		goto probe_fail_2;
-	}
-
-	msm_camio_clk_rate_set(S5K4E1_MASTER_CLK_RATE);
-
-	rc = s5k4e1_probe_init_sensor(info);
-	if (rc < 0)
-		goto probe_fail_3;
-
-	s->s_init = s5k4e1_sensor_open_init;
-	s->s_release = s5k4e1_sensor_release;
-	s->s_config  = s5k4e1_sensor_config;
-	s->s_mount_angle = info->sensor_platform_info->mount_angle;
-	gpio_set_value_cansleep(info->sensor_reset, 0);
-	s5k4e1_probe_init_done(info);
-	/* Keep vcm_pwd to OUT Low */
-	if (info->vcm_enable) {
-		rc = gpio_request(info->vcm_pwd, "s5k4e1_af");
-		if (!rc) {
-			gpio_direction_output(info->vcm_pwd, 0);
-			msleep(20);
-			gpio_free(info->vcm_pwd);
-		} else
-			return rc;
-	}
-	return rc;
-
-probe_fail_3:
-	i2c_del_driver(&s5k4e1_af_i2c_driver);
-probe_fail_2:
-	i2c_del_driver(&s5k4e1_i2c_driver);
-probe_fail_1:
-	CDBG("s5k4e1_sensor_probe: SENSOR PROBE FAILS!\n");
-	return rc;
-}
-
-static int __devinit s5k4e1_probe(struct platform_device *pdev)
-{
-	return msm_camera_drv_start(pdev, s5k4e1_sensor_probe);
-}
-
-static struct platform_driver msm_camera_driver = {
-	.probe = s5k4e1_probe,
-	.driver = {
-		.name = "msm_camera_s5k4e1",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init s5k4e1_init(void)
-{
-	return platform_driver_register(&msm_camera_driver);
-}
-
-module_init(s5k4e1_init);
-MODULE_DESCRIPTION("Samsung 5 MP Bayer sensor driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/s5k4e1.h b/drivers/media/video/msm/s5k4e1.h
deleted file mode 100644
index 7f60332..0000000
--- a/drivers/media/video/msm/s5k4e1.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. 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 S5K4E1_H
-#define S5K4E1_H
-#include <linux/types.h>
-#include <mach/board.h>
-extern struct s5k4e1_reg s5k4e1_regs;
-
-struct s5k4e1_i2c_reg_conf {
-	unsigned short waddr;
-	unsigned short wdata;
-};
-
-enum s5k4e1_test_mode_t {
-	TEST_OFF,
-	TEST_1,
-	TEST_2,
-	TEST_3
-};
-
-enum s5k4e1_resolution_t {
-	QTR_SIZE,
-	FULL_SIZE,
-	INVALID_SIZE
-};
-enum s5k4e1_setting {
-	RES_PREVIEW,
-	RES_CAPTURE
-};
-enum s5k4e1_reg_update {
-	/* Sensor egisters that need to be updated during initialization */
-	REG_INIT,
-	/* Sensor egisters that needs periodic I2C writes */
-	UPDATE_PERIODIC,
-	/* All the sensor Registers will be updated */
-	UPDATE_ALL,
-	/* Not valid update */
-	UPDATE_INVALID
-};
-
-enum s5k4e1_reg_pll {
-	E013_VT_PIX_CLK_DIV,
-	E013_VT_SYS_CLK_DIV,
-	E013_PRE_PLL_CLK_DIV,
-	E013_PLL_MULTIPLIER,
-	E013_OP_PIX_CLK_DIV,
-	E013_OP_SYS_CLK_DIV
-};
-
-enum s5k4e1_reg_mode {
-	E013_X_ADDR_START,
-	E013_X_ADDR_END,
-	E013_Y_ADDR_START,
-	E013_Y_ADDR_END,
-	E013_X_OUTPUT_SIZE,
-	E013_Y_OUTPUT_SIZE,
-	E013_DATAPATH_SELECT,
-	E013_READ_MODE,
-	E013_ANALOG_CONTROL5,
-	E013_DAC_LD_4_5,
-	E013_SCALING_MODE,
-	E013_SCALE_M,
-	E013_LINE_LENGTH_PCK,
-	E013_FRAME_LENGTH_LINES,
-	E013_COARSE_INTEGRATION_TIME,
-	E013_FINE_INTEGRATION_TIME,
-	E013_FINE_CORRECTION
-};
-
-struct s5k4e1_reg {
-	const struct s5k4e1_i2c_reg_conf *reg_mipi;
-	const unsigned short reg_mipi_size;
-	const struct s5k4e1_i2c_reg_conf *rec_settings;
-	const unsigned short rec_size;
-	const struct s5k4e1_i2c_reg_conf *reg_pll_p;
-	const unsigned short reg_pll_p_size;
-	const struct s5k4e1_i2c_reg_conf *reg_pll_s;
-	const unsigned short reg_pll_s_size;
-	const struct s5k4e1_i2c_reg_conf *reg_prev;
-	const unsigned short reg_prev_size;
-	const struct s5k4e1_i2c_reg_conf *reg_snap;
-	const unsigned short reg_snap_size;
-};
-#endif /* S5K4E1_H */
diff --git a/drivers/media/video/msm/s5k4e1_reg.c b/drivers/media/video/msm/s5k4e1_reg.c
deleted file mode 100644
index 59bb1c8..0000000
--- a/drivers/media/video/msm/s5k4e1_reg.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. 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 "s5k4e1.h"
-
-struct s5k4e1_i2c_reg_conf s5k4e1_mipi_settings[] = {
-	{0x30BD, 0x00},/* SEL_CCP[0] */
-	{0x3084, 0x15},/* SYNC Mode */
-	{0x30BE, 0x1A},/* M_PCLKDIV_AUTO[4], M_DIV_PCLK[3:0] */
-	{0x30C1, 0x01},/* pack video enable [0] */
-	{0x30EE, 0x02},/* DPHY enable [ 1] */
-	{0x3111, 0x86},/* Embedded data off [5] */
-};
-
-/* PLL Configuration */
-struct s5k4e1_i2c_reg_conf s5k4e1_pll_preview_settings[] = {
-	{0x0305, 0x04},
-	{0x0306, 0x00},
-	{0x0307, 0x44},
-	{0x30B5, 0x00},
-	{0x30E2, 0x01},/* num lanes[1:0] = 2 */
-	{0x30F1, 0xB0},
-};
-
-struct s5k4e1_i2c_reg_conf s5k4e1_pll_snap_settings[] = {
-	{0x0305, 0x04},
-	{0x0306, 0x00},
-	{0x0307, 0x44},
-	{0x30B5, 0x00},
-	{0x30E2, 0x01},/* num lanes[1:0] = 2 */
-	{0x30F1, 0xB0},
-};
-
-struct s5k4e1_i2c_reg_conf s5k4e1_prev_settings[] = {
-	/* output size (1304 x 980) */
-	{0x30A9, 0x02},/* Horizontal Binning On */
-	{0x300E, 0xEB},/* Vertical Binning On */
-	{0x0387, 0x03},/* y_odd_inc 03(10b AVG) */
-	{0x0344, 0x00},/* x_addr_start 0 */
-	{0x0345, 0x00},
-	{0x0348, 0x0A},/* x_addr_end 2607 */
-	{0x0349, 0x2F},
-	{0x0346, 0x00},/* y_addr_start 0 */
-	{0x0347, 0x00},
-	{0x034A, 0x07},/* y_addr_end 1959 */
-	{0x034B, 0xA7},
-	{0x0380, 0x00},/* x_even_inc 1 */
-	{0x0381, 0x01},
-	{0x0382, 0x00},/* x_odd_inc 1 */
-	{0x0383, 0x01},
-	{0x0384, 0x00},/* y_even_inc 1 */
-	{0x0385, 0x01},
-	{0x0386, 0x00},/* y_odd_inc 3 */
-	{0x0387, 0x03},
-	{0x034C, 0x05},/* x_output_size 1304 */
-	{0x034D, 0x18},
-	{0x034E, 0x03},/* y_output_size 980 */
-	{0x034F, 0xd4},
-	{0x30BF, 0xAB},/* outif_enable[7], data_type[5:0](2Bh = bayer 10bit} */
-	{0x30C0, 0xA0},/* video_offset[7:4] 3260%12 */
-	{0x30C8, 0x06},/* video_data_length 1600 = 1304 * 1.25 */
-	{0x30C9, 0x5E},
-	/* Timing Configuration */
-	{0x0202, 0x03},
-	{0x0203, 0x14},
-	{0x0204, 0x00},
-	{0x0205, 0x80},
-	{0x0340, 0x03},/* Frame Length */
-	{0x0341, 0xE0},
-	{0x0342, 0x0A},/* 2738  Line Length */
-	{0x0343, 0xB2},
-};
-
-struct s5k4e1_i2c_reg_conf s5k4e1_snap_settings[] = {
-	/*Output Size (2608x1960)*/
-	{0x30A9, 0x03},/* Horizontal Binning Off */
-	{0x300E, 0xE8},/* Vertical Binning Off */
-	{0x0387, 0x01},/* y_odd_inc */
-	{0x034C, 0x0A},/* x_output size */
-	{0x034D, 0x30},
-	{0x034E, 0x07},/* y_output size */
-	{0x034F, 0xA8},
-	{0x30BF, 0xAB},/* outif_enable[7], data_type[5:0](2Bh = bayer 10bit} */
-	{0x30C0, 0x80},/* video_offset[7:4] 3260%12 */
-	{0x30C8, 0x0C},/* video_data_length 3260 = 2608 * 1.25 */
-	{0x30C9, 0xBC},
-	/*Timing configuration*/
-	{0x0202, 0x06},
-	{0x0203, 0x28},
-	{0x0204, 0x00},
-	{0x0205, 0x80},
-	{0x0340, 0x07},/* Frame Length */
-	{0x0341, 0xB4},
-	{0x0342, 0x0A},/* 2738 Line Length */
-	{0x0343, 0xB2},
-};
-
-struct s5k4e1_i2c_reg_conf s5k4e1_recommend_settings[] = {
-	/*CDS timing setting ... */
-	{0x3000, 0x05},
-	{0x3001, 0x03},
-	{0x3002, 0x08},
-	{0x3003, 0x0A},
-	{0x3004, 0x50},
-	{0x3005, 0x0E},
-	{0x3006, 0x5E},
-	{0x3007, 0x00},
-	{0x3008, 0x78},
-	{0x3009, 0x78},
-	{0x300A, 0x50},
-	{0x300B, 0x08},
-	{0x300C, 0x14},
-	{0x300D, 0x00},
-	{0x300E, 0xE8},
-	{0x300F, 0x82},
-	{0x301B, 0x77},
-
-	/* CDS option setting ... */
-	{0x3010, 0x00},
-	{0x3011, 0x3A},
-	{0x3029, 0x04},
-	{0x3012, 0x30},
-	{0x3013, 0xA0},
-	{0x3014, 0x00},
-	{0x3015, 0x00},
-	{0x3016, 0x30},
-	{0x3017, 0x94},
-	{0x3018, 0x70},
-	{0x301D, 0xD4},
-	{0x3021, 0x02},
-	{0x3022, 0x24},
-	{0x3024, 0x40},
-	{0x3027, 0x08},
-
-	/* Pixel option setting ...   */
-	{0x301C, 0x04},
-	{0x30D8, 0x3F},
-	{0x302B, 0x01},
-
-	{0x3070, 0x5F},
-	{0x3071, 0x00},
-	{0x3080, 0x04},
-	{0x3081, 0x38},
-};
-
-struct s5k4e1_reg s5k4e1_regs = {
-	.reg_mipi = &s5k4e1_mipi_settings[0],
-	.reg_mipi_size = ARRAY_SIZE(s5k4e1_mipi_settings),
-	.rec_settings = &s5k4e1_recommend_settings[0],
-	.rec_size = ARRAY_SIZE(s5k4e1_recommend_settings),
-	.reg_pll_p = &s5k4e1_pll_preview_settings[0],
-	.reg_pll_p_size = ARRAY_SIZE(s5k4e1_pll_preview_settings),
-	.reg_pll_s = &s5k4e1_pll_snap_settings[0],
-	.reg_pll_s_size = ARRAY_SIZE(s5k4e1_pll_snap_settings),
-	.reg_prev = &s5k4e1_prev_settings[0],
-	.reg_prev_size = ARRAY_SIZE(s5k4e1_prev_settings),
-	.reg_snap = &s5k4e1_snap_settings[0],
-	.reg_snap_size = ARRAY_SIZE(s5k4e1_snap_settings),
-};
diff --git a/drivers/media/video/msm/sensors/Makefile b/drivers/media/video/msm/sensors/Makefile
deleted file mode 100644
index a70a632..0000000
--- a/drivers/media/video/msm/sensors/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
-EXTRA_CFLAGS += -Idrivers/media/video/msm
-EXTRA_CFLAGS += -Idrivers/media/video/msm/io
-EXTRA_CFLAGS += -Idrivers/media/video/msm/eeprom
-EXTRA_CFLAGS += -Idrivers/media/video/msm/csi
-obj-$(CONFIG_MSM_CAMERA_SENSOR) += msm_sensor_common.o msm_sensor.o msm_sensor_bayer.o msm_sensor_init.o
-obj-$(CONFIG_OV5647) += ov5647_v4l2.o
-obj-$(CONFIG_OV8825) += ov8825_v4l2.o
-obj-$(CONFIG_IMX074) += imx074_v4l2.o
-obj-$(CONFIG_S5K3L1YX) += s5k3l1yx.o
-obj-$(CONFIG_IMX135) += imx135_v4l2.o
-obj-$(CONFIG_OV2720) += ov2720.o
-obj-$(CONFIG_MT9M114) += mt9m114_v4l2.o
-obj-$(CONFIG_S5K4E1) += s5k4e1_v4l2.o
-obj-$(CONFIG_MT9E013) += mt9e013_v4l2.o
-obj-$(CONFIG_WEBCAM_OV9726) += ov9726_v4l2.o
-obj-$(CONFIG_OV7692) += ov7692_v4l2.o
-obj-$(CONFIG_VX6953) += vx6953.o
diff --git a/drivers/media/video/msm/sensors/imx074_v4l2.c b/drivers/media/video/msm/sensors/imx074_v4l2.c
deleted file mode 100644
index 91d4797..0000000
--- a/drivers/media/video/msm/sensors/imx074_v4l2.c
+++ /dev/null
@@ -1,291 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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 "msm_sensor.h"
-#define SENSOR_NAME "imx074"
-#define PLATFORM_DRIVER_NAME "msm_camera_imx074"
-#define imx074_obj imx074_##obj
-
-DEFINE_MUTEX(imx074_mut);
-static struct msm_sensor_ctrl_t imx074_s_ctrl;
-
-static struct msm_camera_i2c_reg_conf imx074_start_settings[] = {
-	{0x0100, 0x01},
-};
-
-static struct msm_camera_i2c_reg_conf imx074_stop_settings[] = {
-	{0x0100, 0x00},
-};
-
-static struct msm_camera_i2c_reg_conf imx074_groupon_settings[] = {
-	{0x104, 0x01},
-};
-
-static struct msm_camera_i2c_reg_conf imx074_groupoff_settings[] = {
-	{0x104, 0x00},
-};
-
-static struct msm_camera_i2c_reg_conf imx074_prev_settings[] = {
-	{0x0307, 0x2D}, /*pll_multiplier*/
-	{0x0340, 0x06}, /*frame_length_lines_hi*/
-	{0x0341, 0x34}, /*frame_length_lines_lo*/
-	{0x0342, 0x11}, /*line_length_pclk_hi*/
-	{0x0343, 0x78}, /*line_length_pclk_lo*/
-	{0x0347, 0x00}, /*y_addr_start*/
-	{0x034b, 0x2F}, /*y_add_end*/
-	{0x034c, 0x08}, /*x_output_size_msb*/
-	{0x034d, 0x38}, /*x_output_size_lsb*/
-	{0x034e, 0x06}, /*y_output_size_msb*/
-	{0x034f, 0x18}, /*y_output_size_lsb*/
-	{0x0381, 0x01}, /*x_even_inc*/
-	{0x0383, 0x03}, /*x_odd_inc*/
-	{0x0385, 0x01}, /*y_even_inc*/
-	{0x0387, 0x03}, /*y_odd_inc*/
-	{0x3001, 0x80}, /*hmodeadd*/
-	{0x3016, 0x16}, /*vmodeadd*/
-	{0x3069, 0x24}, /*vapplinepos_start*/
-	{0x306b, 0x53}, /*vapplinepos_end*/
-	{0x3086, 0x00}, /*shutter*/
-	{0x30e8, 0x80}, /*haddave*/
-	{0x3301, 0x83}, /*lanesel*/
-};
-
-static struct msm_camera_i2c_reg_conf imx074_snap_settings[] = {
-	{0x0307, 0x26}, /*pll_multiplier*/
-	{0x0340, 0x0C}, /*frame_length_lines_hi*/
-	{0x0341, 0x90}, /*frame_length_lines_lo*/
-	{0x0342, 0x11}, /*line_length_pclk_hi*/
-	{0x0343, 0x78}, /*line_length_pclk_lo*/
-	{0x0347, 0x00}, /*y_addr_start*/
-	{0x034b, 0x2F}, /*y_add_end*/
-	{0x034c, 0x10}, /*x_output_size_msb*/
-	{0x034d, 0x70}, /*x_output_size_lsb*/
-	{0x034e, 0x0c}, /*y_output_size_msb*/
-	{0x034f, 0x30}, /*y_output_size_lsb*/
-	{0x0381, 0x01}, /*x_even_inc*/
-	{0x0383, 0x01}, /*x_odd_inc*/
-	{0x0385, 0x01}, /*y_even_inc*/
-	{0x0387, 0x01}, /*y_odd_inc*/
-	{0x3001, 0x00}, /*hmodeadd*/
-	{0x3016, 0x06}, /*vmodeadd*/
-	{0x3069, 0x24}, /*vapplinepos_start*/
-	{0x306b, 0x53}, /*vapplinepos_end*/
-	{0x3086, 0x00}, /*shutter*/
-	{0x30e8, 0x00}, /*haddave*/
-	{0x3301, 0x03}, /*lanesel*/
-};
-
-static struct msm_camera_i2c_reg_conf imx074_recommend_settings[] = {
-	{0x0305, 0x02},
-	{0x302b, 0x4B},
-	{0x3024, 0x03},
-	{0x0101, 0x00},
-	{0x300a, 0x80},
-	{0x3014, 0x08},
-	{0x3015, 0x37},
-	{0x301c, 0x01},
-	{0x302c, 0x05},
-	{0x3031, 0x26},
-	{0x3041, 0x60},
-	{0x3051, 0x24},
-	{0x3053, 0x34},
-	{0x3057, 0xc0},
-	{0x305c, 0x09},
-	{0x305d, 0x07},
-	{0x3060, 0x30},
-	{0x3065, 0x00},
-	{0x30aa, 0x08},
-	{0x30ab, 0x1c},
-	{0x30b0, 0x32},
-	{0x30b2, 0x83},
-	{0x30d3, 0x04},
-	{0x3106, 0x78},
-	{0x310c, 0x82},
-	{0x3304, 0x05},
-	{0x3305, 0x04},
-	{0x3306, 0x11},
-	{0x3307, 0x02},
-	{0x3308, 0x0c},
-	{0x3309, 0x06},
-	{0x330a, 0x08},
-	{0x330b, 0x04},
-	{0x330c, 0x08},
-	{0x330d, 0x06},
-	{0x330f, 0x01},
-	{0x3381, 0x00},
-};
-
-static struct v4l2_subdev_info imx074_subdev_info[] = {
-	{
-	.code   = V4L2_MBUS_FMT_SBGGR10_1X10,
-	.colorspace = V4L2_COLORSPACE_JPEG,
-	.fmt    = 1,
-	.order    = 0,
-	},
-	/* more can be supported, to be added later */
-};
-
-static struct msm_camera_i2c_conf_array imx074_init_conf[] = {
-	{&imx074_recommend_settings[0],
-	ARRAY_SIZE(imx074_recommend_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}
-};
-
-static struct msm_camera_i2c_conf_array imx074_confs[] = {
-	{&imx074_snap_settings[0],
-	ARRAY_SIZE(imx074_snap_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
-	{&imx074_prev_settings[0],
-	ARRAY_SIZE(imx074_prev_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
-};
-
-static struct msm_sensor_output_info_t imx074_dimensions[] = {
-	{
-		.x_output = 0x1070,
-		.y_output = 0xC30,
-		.line_length_pclk = 0x1178,
-		.frame_length_lines = 0xC90,
-		.vt_pixel_clk = 182400000,
-		.op_pixel_clk = 182400000,
-		.binning_factor = 1,
-	},
-	{
-		.x_output = 0x838,
-		.y_output = 0x618,
-		.line_length_pclk = 0x1178,
-		.frame_length_lines = 0x634,
-		.vt_pixel_clk = 216000000,
-		.op_pixel_clk = 108000000,
-		.binning_factor = 2,
-	},
-};
-
-static struct msm_sensor_output_reg_addr_t imx074_reg_addr = {
-	.x_output = 0x34C,
-	.y_output = 0x34E,
-	.line_length_pclk = 0x342,
-	.frame_length_lines = 0x340,
-};
-
-static struct msm_sensor_id_info_t imx074_id_info = {
-	.sensor_id_reg_addr = 0x0,
-	.sensor_id = 0x0074,
-};
-
-static struct msm_sensor_exp_gain_info_t imx074_exp_gain_info = {
-	.coarse_int_time_addr = 0x202,
-	.global_gain_addr = 0x204,
-	.vert_offset = 3,
-};
-
-static enum msm_camera_vreg_name_t imx074_veg_seq[] = {
-	CAM_VDIG,
-	CAM_VIO,
-	CAM_VANA,
-	CAM_VAF,
-};
-
-static const struct i2c_device_id imx074_i2c_id[] = {
-	{SENSOR_NAME, (kernel_ulong_t)&imx074_s_ctrl},
-	{ }
-};
-
-static struct i2c_driver imx074_i2c_driver = {
-	.id_table = imx074_i2c_id,
-	.probe  = msm_sensor_i2c_probe,
-	.driver = {
-		.name = SENSOR_NAME,
-	},
-};
-
-static struct msm_camera_i2c_client imx074_sensor_i2c_client = {
-	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
-};
-
-static int __init msm_sensor_init_module(void)
-{
-	return i2c_add_driver(&imx074_i2c_driver);
-}
-
-static struct v4l2_subdev_core_ops imx074_subdev_core_ops = {
-	.ioctl = msm_sensor_subdev_ioctl,
-	.s_power = msm_sensor_power,
-};
-
-static struct v4l2_subdev_video_ops imx074_subdev_video_ops = {
-	.enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
-};
-
-static struct v4l2_subdev_ops imx074_subdev_ops = {
-	.core = &imx074_subdev_core_ops,
-	.video  = &imx074_subdev_video_ops,
-};
-
-static struct msm_sensor_fn_t imx074_func_tbl = {
-	.sensor_start_stream = msm_sensor_start_stream,
-	.sensor_stop_stream = msm_sensor_stop_stream,
-	.sensor_group_hold_on = msm_sensor_group_hold_on,
-	.sensor_group_hold_off = msm_sensor_group_hold_off,
-	.sensor_set_fps = msm_sensor_set_fps,
-	.sensor_write_exp_gain = msm_sensor_write_exp_gain1,
-	.sensor_write_snapshot_exp_gain = msm_sensor_write_exp_gain1,
-	.sensor_setting = msm_sensor_setting,
-	.sensor_csi_setting = msm_sensor_setting1,
-	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
-	.sensor_mode_init = msm_sensor_mode_init,
-	.sensor_get_output_info = msm_sensor_get_output_info,
-	.sensor_config = msm_sensor_config,
-	.sensor_power_up = msm_sensor_power_up,
-	.sensor_power_down = msm_sensor_power_down,
-	.sensor_adjust_frame_lines = msm_sensor_adjust_frame_lines1,
-	.sensor_get_csi_params = msm_sensor_get_csi_params,
-};
-
-static struct msm_sensor_reg_t imx074_regs = {
-	.default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
-	.start_stream_conf = imx074_start_settings,
-	.start_stream_conf_size = ARRAY_SIZE(imx074_start_settings),
-	.stop_stream_conf = imx074_stop_settings,
-	.stop_stream_conf_size = ARRAY_SIZE(imx074_stop_settings),
-	.group_hold_on_conf = imx074_groupon_settings,
-	.group_hold_on_conf_size = ARRAY_SIZE(imx074_groupon_settings),
-	.group_hold_off_conf = imx074_groupoff_settings,
-	.group_hold_off_conf_size =
-		ARRAY_SIZE(imx074_groupoff_settings),
-	.init_settings = &imx074_init_conf[0],
-	.init_size = ARRAY_SIZE(imx074_init_conf),
-	.mode_settings = &imx074_confs[0],
-	.output_settings = &imx074_dimensions[0],
-	.num_conf = ARRAY_SIZE(imx074_confs),
-};
-
-static struct msm_sensor_ctrl_t imx074_s_ctrl = {
-	.msm_sensor_reg = &imx074_regs,
-	.sensor_i2c_client = &imx074_sensor_i2c_client,
-	.sensor_i2c_addr = 0x34,
-	.vreg_seq = imx074_veg_seq,
-	.num_vreg_seq = ARRAY_SIZE(imx074_veg_seq),
-	.sensor_output_reg_addr = &imx074_reg_addr,
-	.sensor_id_info = &imx074_id_info,
-	.sensor_exp_gain_info = &imx074_exp_gain_info,
-	.cam_mode = MSM_SENSOR_MODE_INVALID,
-	.msm_sensor_mutex = &imx074_mut,
-	.sensor_i2c_driver = &imx074_i2c_driver,
-	.sensor_v4l2_subdev_info = imx074_subdev_info,
-	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(imx074_subdev_info),
-	.sensor_v4l2_subdev_ops = &imx074_subdev_ops,
-	.func_tbl = &imx074_func_tbl,
-	.clk_rate = MSM_SENSOR_MCLK_24HZ,
-};
-
-module_init(msm_sensor_init_module);
-MODULE_DESCRIPTION("Sony 13MP Bayer sensor driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/sensors/imx091.h b/drivers/media/video/msm/sensors/imx091.h
deleted file mode 100644
index 411b90c..0000000
--- a/drivers/media/video/msm/sensors/imx091.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 IMX091_SENSOR_NAME "imx091"
-DEFINE_MSM_MUTEX(imx091_mut);
-
-static struct msm_sensor_ctrl_t imx091_s_ctrl;
-
-static struct v4l2_subdev_info imx091_subdev_info[] = {
-	{
-	.code   = V4L2_MBUS_FMT_SBGGR10_1X10,
-	.colorspace = V4L2_COLORSPACE_JPEG,
-	.fmt    = 1,
-	.order    = 0,
-	},
-	/* more can be supported, to be added later */
-};
-
-static struct msm_sensor_id_info_t imx091_id_info = {
-	.sensor_id_reg_addr = 0x0000,
-	.sensor_id = 0x0091,
-};
-
-static enum msm_camera_vreg_name_t imx091_veg_seq[] = {
-	CAM_VANA,
-	CAM_VAF,
-	CAM_VDIG,
-	CAM_VIO,
-};
-
-static struct msm_camera_power_seq_t imx091_power_seq[] = {
-	{REQUEST_GPIO, 0},
-	{REQUEST_VREG, 0},
-	{ENABLE_VREG, 0},
-	{ENABLE_GPIO, 0},
-	{CONFIG_CLK, 1},
-	{CONFIG_I2C_MUX, 0},
-};
-
-static const struct i2c_device_id imx091_i2c_id[] = {
-	{IMX091_SENSOR_NAME, (kernel_ulong_t)&imx091_s_ctrl},
-	{ }
-};
-
-static struct i2c_driver imx091_i2c_driver = {
-	.id_table = imx091_i2c_id,
-	.probe  = msm_sensor_bayer_i2c_probe,
-	.driver = {
-		.name = IMX091_SENSOR_NAME,
-	},
-};
-
-static struct msm_camera_i2c_client imx091_sensor_i2c_client = {
-	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
-};
-
-static struct v4l2_subdev_core_ops imx091_subdev_core_ops = {
-	.ioctl = msm_sensor_bayer_subdev_ioctl,
-	.s_power = msm_sensor_bayer_power,
-};
-
-static struct v4l2_subdev_video_ops imx091_subdev_video_ops = {
-	.enum_mbus_fmt = msm_sensor_bayer_v4l2_enum_fmt,
-};
-
-static struct v4l2_subdev_ops imx091_subdev_ops = {
-	.core = &imx091_subdev_core_ops,
-	.video  = &imx091_subdev_video_ops,
-};
-
-static struct msm_sensor_fn_t imx091_func_tbl = {
-	.sensor_config = msm_sensor_bayer_config,
-	.sensor_power_up = msm_sensor_bayer_power_up,
-	.sensor_power_down = msm_sensor_bayer_power_down,
-	.sensor_get_csi_params = msm_sensor_bayer_get_csi_params,
-	.sensor_read_eeprom = msm_sensor_bayer_eeprom_read,
-};
-
-static struct msm_sensor_ctrl_t imx091_s_ctrl = {
-	.sensor_i2c_client = &imx091_sensor_i2c_client,
-	.sensor_i2c_addr = 0x34,
-	.vreg_seq = imx091_veg_seq,
-	.num_vreg_seq = ARRAY_SIZE(imx091_veg_seq),
-	.power_seq = &imx091_power_seq[0],
-	.num_power_seq = ARRAY_SIZE(imx091_power_seq),
-	.sensor_id_info = &imx091_id_info,
-	.msm_sensor_mutex = &imx091_mut,
-	.sensor_v4l2_subdev_info = imx091_subdev_info,
-	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(imx091_subdev_info),
-	.sensor_v4l2_subdev_ops = &imx091_subdev_ops,
-	.func_tbl = &imx091_func_tbl,
-	.clk_rate = MSM_SENSOR_MCLK_24HZ,
-};
diff --git a/drivers/media/video/msm/sensors/imx135_v4l2.c b/drivers/media/video/msm/sensors/imx135_v4l2.c
deleted file mode 100644
index f480923..0000000
--- a/drivers/media/video/msm/sensors/imx135_v4l2.c
+++ /dev/null
@@ -1,553 +0,0 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#include "msm_sensor.h"
-#define SENSOR_NAME "imx135"
-#define PLATFORM_DRIVER_NAME "msm_camera_imx135"
-#define imx135_obj imx135_##obj
-
-DEFINE_MUTEX(imx135_mut);
-static struct msm_sensor_ctrl_t imx135_s_ctrl;
-
-static struct msm_camera_i2c_reg_conf imx135_start_settings[] = {
-	{0x0100, 0x01},
-};
-
-static struct msm_camera_i2c_reg_conf imx135_stop_settings[] = {
-	{0x0100, 0x00},
-};
-
-static struct msm_camera_i2c_reg_conf imx135_groupon_settings[] = {
-	{0x104, 0x01},
-};
-
-static struct msm_camera_i2c_reg_conf imx135_groupoff_settings[] = {
-	{0x104, 0x00},
-};
-
-static struct msm_camera_i2c_reg_conf imx135_recommend_settings[] = {
-/* Recommended global settings */
-	{0x0220, 0x01},
-	{0x3008, 0xB0},
-	{0x320A, 0x01},
-	{0x320D, 0x10},
-	{0x3216, 0x2E},
-	{0x3230, 0x0A},
-	{0x3228, 0x05},
-	{0x3229, 0x02},
-	{0x322C, 0x02},
-	{0x3302, 0x10},
-	{0x3390, 0x45},
-	{0x3409, 0x0C},
-	{0x340B, 0xF5},
-	{0x340C, 0x2D},
-	{0x3412, 0x41},
-	{0x3413, 0xAD},
-	{0x3414, 0x1E},
-	{0x3427, 0x04},
-	{0x3480, 0x1E},
-	{0x3484, 0x1E},
-	{0x3488, 0x1E},
-	{0x348C, 0x1E},
-	{0x3490, 0x1E},
-	{0x3494, 0x1E},
-	{0x349C, 0x38},
-	{0x34A3, 0x38},
-	{0x3511, 0x8F},
-	{0x3518, 0x00},
-	{0x3519, 0x94},
-	{0x3833, 0x20},
-	{0x3893, 0x01},
-	{0x38C2, 0x08},
-	{0x3C09, 0x01},
-	{0x4300, 0x00},
-	{0x4316, 0x12},
-	{0x4317, 0x22},
-	{0x431A, 0x00},
-	{0x4324, 0x03},
-	{0x4325, 0x20},
-	{0x4326, 0x03},
-	{0x4327, 0x84},
-	{0x4328, 0x03},
-	{0x4329, 0x20},
-	{0x432A, 0x03},
-	{0x432B, 0x84},
-	{0x4401, 0x3F},
-	{0x4412, 0x3F},
-	{0x4413, 0xFF},
-	{0x4446, 0x3F},
-	{0x4447, 0xFF},
-	{0x4452, 0x00},
-	{0x4453, 0xA0},
-	{0x4454, 0x08},
-	{0x4455, 0x00},
-	{0x4458, 0x18},
-	{0x4459, 0x18},
-	{0x445A, 0x3F},
-	{0x445B, 0x3A},
-	{0x4463, 0x00},
-	{0x4465, 0x00},
-	{0x446E, 0x01},
-/* Image Quality Settings */
-/* Bypass Settings */
-	{0x4203, 0x48},
-/* Defect Correction Recommended Setting */
-	{0x4100, 0xE0},
-	{0x4102, 0x0B},
-/* RGB Filter Recommended Setting */
-	{0x4281, 0x22},
-	{0x4282, 0x82},
-	{0x4284, 0x00},
-	{0x4287, 0x18},
-	{0x4288, 0x00},
-	{0x428B, 0x1E},
-	{0x428C, 0x00},
-	{0x428F, 0x08},
-/* DLC/ADP Recommended Setting */
-	{0x4207, 0x00},
-	{0x4218, 0x02},
-	{0x421B, 0x00},
-	{0x4222, 0x04},
-	{0x4223, 0x44},
-	{0x4224, 0x46},
-	{0x4225, 0xFF},
-	{0x4226, 0x14},
-	{0x4227, 0xF2},
-	{0x4228, 0xFC},
-	{0x4229, 0x60},
-	{0x422A, 0xFA},
-	{0x422B, 0xFE},
-	{0x422C, 0xFE},
-/* Color Artifact Recommended Setting */
-	{0x4243, 0xAA}
-};
-
-/* IMX135 mode 1/2 HV at 24MHz */
-static struct msm_camera_i2c_reg_conf imx135_prev_settings[] = {
-/* Clock Setting */
-	{0x011E, 0x18},
-	{0x011F, 0x00},
-	{0x0301, 0x05},
-	{0x0303, 0x01},
-	{0x0304, 0x0B},
-	{0x0305, 0x03},
-	{0x0306, 0x01},
-	{0x0307, 0x5E},
-	{0x0309, 0x05},
-	{0x030B, 0x02},
-	{0x030C, 0x00},
-	{0x030D, 0x71},
-	{0x030E, 0x01},
-	{0x3A06, 0x12},
-/* Mode setting */
-	{0x0101, 0x00},
-	{0x0105, 0x00},
-	{0x0108, 0x03},
-	{0x0109, 0x30},
-	{0x010B, 0x32},
-	{0x0112, 0x0A},
-	{0x0113, 0x0A},
-	{0x0381, 0x01},
-	{0x0383, 0x01},
-	{0x0385, 0x01},
-	{0x0387, 0x01},
-	{0x0390, 0x01}, /* binning_en = 1 */
-	{0x0391, 0x22}, /* binning_type */
-	{0x0392, 0x00}, /* binning_mode = 0 (average) */
-	{0x0401, 0x00},
-	{0x0404, 0x00},
-	{0x0405, 0x10},
-	{0x4083, 0x01},
-/* Size setting*/
-	{0x0340, 0x0A}, /* frame_length_lines = 2680*/
-	{0x0341, 0x78},
-	{0x034C, 0x08},
-	{0x034D, 0x38},
-	{0x034E, 0x06},
-	{0x034F, 0x18},
-	{0x0354, 0x08},
-	{0x0355, 0x38},
-	{0x0356, 0x06},
-	{0x0357, 0x18},
-	{0x3310, 0x08},
-	{0x3311, 0x38},
-	{0x3312, 0x06},
-	{0x3313, 0x18},
-	{0x331C, 0x02},
-	{0x331D, 0xC0},
-	{0x33B0, 0x04},
-	{0x33B1, 0x00},
-	{0x33B3, 0x00},
-	{0x7006, 0x04},
-/* Global Timing Setting */
-	{0x0830, 0x67},
-	{0x0831, 0x27},
-	{0x0832, 0x47},
-	{0x0833, 0x27},
-	{0x0834, 0x27},
-	{0x0835, 0x1F},
-	{0x0836, 0x87},
-	{0x0837, 0x2F},
-	{0x0839, 0x1F},
-	{0x083A, 0x17},
-	{0x083B, 0x02},
-/* Integration Time Setting */
-	{0x0254, 0x00},
-/* Gain Setting */
-	{0x0205, 0x33}
-};
-
-/* IMX135 Mode Fullsize at 24MHz */
-static struct msm_camera_i2c_reg_conf imx135_snap_settings[] = {
-/* Clock Setting */
-	{0x011E, 0x18},
-	{0x011F, 0x00},
-	{0x0301, 0x05},
-	{0x0303, 0x01},
-	{0x0304, 0x0B},
-	{0x0305, 0x03},
-	{0x0306, 0x01},
-	{0x0307, 0x5E},
-	{0x0309, 0x05},
-	{0x030B, 0x01},
-	{0x030C, 0x00},
-	{0x030D, 0x60}, /* pll_multiplier = 96 */
-	{0x030E, 0x01},
-	{0x3A06, 0x11},
-/* Mode setting */
-	{0x0101, 0x00},
-	{0x0105, 0x00},
-	{0x0108, 0x03},
-	{0x0109, 0x30},
-	{0x010B, 0x32},
-	{0x0112, 0x0A},
-	{0x0113, 0x0A},
-	{0x0381, 0x01},
-	{0x0383, 0x01},
-	{0x0385, 0x01},
-	{0x0387, 0x01},
-	{0x0390, 0x00},
-	{0x0391, 0x11},
-	{0x0392, 0x00},
-	{0x0401, 0x00},
-	{0x0404, 0x00},
-	{0x0405, 0x10},
-	{0x4083, 0x01},
-/* Size setting */
-	{0x0340, 0x0C},
-	{0x0341, 0x46},
-	{0x034C, 0x10},
-	{0x034D, 0x70},
-	{0x034E, 0x0C},
-	{0x034F, 0x30},
-	{0x0354, 0x10},
-	{0x0355, 0x70},
-	{0x0356, 0x0C},
-	{0x0357, 0x30},
-	{0x3310, 0x10},
-	{0x3311, 0x70},
-	{0x3312, 0x0C},
-	{0x3313, 0x30},
-	{0x331C, 0x06},
-	{0x331D, 0x00},
-	{0x33B0, 0x04},
-	{0x33B1, 0x00},
-	{0x33B3, 0x00},
-	{0x7006, 0x04},
-/* Global Timing Setting */
-	{0x0830, 0x7F},
-	{0x0831, 0x37},
-	{0x0832, 0x5F},
-	{0x0833, 0x37},
-	{0x0834, 0x37},
-	{0x0835, 0x3F},
-	{0x0836, 0xC7},
-	{0x0837, 0x3F},
-	{0x0839, 0x1F},
-	{0x083A, 0x17},
-	{0x083B, 0x02},
-/* Integration Time Setting */
-	{0x0250, 0x0B},
-/* Gain Setting */
-	{0x0205, 0x33}
-};
-
-
-static struct msm_camera_i2c_reg_conf imx135_hdr_settings[] = {
-/* Clock Setting */
-	{0x011E, 0x18},
-	{0x011F, 0x00},
-	{0x0301, 0x05},
-	{0x0303, 0x01},
-	{0x0304, 0x0B},
-	{0x0305, 0x03},
-	{0x0306, 0x01},
-	{0x0307, 0x5E},
-	{0x0309, 0x05},
-	{0x030B, 0x02},
-	{0x030C, 0x00},
-	{0x030D, 0x71},
-	{0x030E, 0x01},
-	{0x3A06, 0x12},
-/* Mode setting */
-	{0x0101, 0x00},
-	{0x0105, 0x00},
-	{0x0108, 0x03},
-	{0x0109, 0x30},
-	{0x010B, 0x32},
-	{0x0112, 0x0E},
-	{0x0113, 0x0A},
-	{0x0381, 0x01},
-	{0x0383, 0x01},
-	{0x0385, 0x01},
-	{0x0387, 0x01},
-	{0x0390, 0x00},
-	{0x0391, 0x11},
-	{0x0392, 0x00},
-	{0x0401, 0x00},
-	{0x0404, 0x00},
-	{0x0405, 0x10},
-	{0x4083, 0x01},
-/* Size setting */
-	{0x0340, 0x0C},
-	{0x0341, 0x48},
-	{0x034C, 0x08},
-	{0x034D, 0x38},
-	{0x034E, 0x06},
-	{0x034F, 0x18},
-	{0x0354, 0x08},
-	{0x0355, 0x38},
-	{0x0356, 0x06},
-	{0x0357, 0x18},
-	{0x3310, 0x08},
-	{0x3311, 0x38},
-	{0x3312, 0x06},
-	{0x3313, 0x18},
-	{0x331C, 0x02},
-	{0x331D, 0xA0},
-	{0x33B0, 0x08},
-	{0x33B1, 0x38},
-	{0x33B3, 0x01},
-	{0x7006, 0x04},
-/* Global Timing Setting */
-	{0x0830, 0x67},
-	{0x0831, 0x27},
-	{0x0832, 0x47},
-	{0x0833, 0x27},
-	{0x0834, 0x27},
-	{0x0835, 0x1F},
-	{0x0836, 0x87},
-	{0x0837, 0x2F},
-	{0x0839, 0x1F},
-	{0x083A, 0x17},
-	{0x083B, 0x02},
-/* Integration Time Setting */
-	{0x0250, 0x0B},
-/* Gain Setting */
-	{0x0205, 0x33}
-};
-
-static struct v4l2_subdev_info imx135_subdev_info[] = {
-	{
-	.code		= V4L2_MBUS_FMT_SBGGR10_1X10,
-	.colorspace	= V4L2_COLORSPACE_JPEG,
-	.fmt		= 1,
-	.order		= 0,
-	},
-	/* more can be supported, to be added later */
-};
-
-static struct msm_camera_i2c_conf_array imx135_init_conf[] = {
-	{&imx135_recommend_settings[0],
-	ARRAY_SIZE(imx135_recommend_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}
-};
-
-static struct msm_camera_i2c_conf_array imx135_confs[] = {
-	{&imx135_snap_settings[0],
-	ARRAY_SIZE(imx135_snap_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
-	{&imx135_prev_settings[0],
-	ARRAY_SIZE(imx135_prev_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
-	{&imx135_hdr_settings[0],
-	ARRAY_SIZE(imx135_hdr_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
-};
-
-static struct msm_sensor_output_info_t imx135_dimensions[] = {
-	/* RES0 snapshot(FULL SIZE) */
-	{
-		.x_output = 4208,
-		.y_output = 3120,
-		.line_length_pclk = 4572,
-		.frame_length_lines = 3142,
-		.vt_pixel_clk = 307200000,
-		.op_pixel_clk = 307200000,
-		.binning_factor = 1,
-	},
-	/* RES1 4:3 preview(1/2HV QTR SIZE) */
-	{
-		.x_output = 2104,
-		.y_output = 1560,
-		.line_length_pclk = 4572,
-		.frame_length_lines = 2680,
-		.vt_pixel_clk = 361600000,
-		.op_pixel_clk = 180800000,
-		.binning_factor = 1,
-	},
-	/* RES2 4:3 HDR movie mode */
-	{
-		.x_output = 2104,
-		.y_output = 1560,
-		.line_length_pclk = 4572,
-		.frame_length_lines = 3144,
-		.vt_pixel_clk = 361600000,
-		.op_pixel_clk = 180800000,
-		.binning_factor = 1,
-	},
-};
-
-static struct msm_sensor_output_reg_addr_t imx135_reg_addr = {
-	.x_output = 0x34C,
-	.y_output = 0x34E,
-	.line_length_pclk = 0x342,
-	.frame_length_lines = 0x340,
-};
-
-static struct msm_sensor_id_info_t imx135_id_info = {
-	.sensor_id_reg_addr = 0x0000,
-	.sensor_id = 0x0087,
-};
-
-static struct msm_sensor_exp_gain_info_t imx135_exp_gain_info = {
-	.coarse_int_time_addr = 0x202,
-	.global_gain_addr = 0x205,
-	.vert_offset = 4,
-};
-
-static const struct i2c_device_id imx135_i2c_id[] = {
-	{SENSOR_NAME, (kernel_ulong_t)&imx135_s_ctrl},
-	{ }
-};
-
-static struct i2c_driver imx135_i2c_driver = {
-	.id_table = imx135_i2c_id,
-	.probe  = msm_sensor_i2c_probe,
-	.driver = {
-		.name = SENSOR_NAME,
-	},
-};
-
-static struct msm_camera_i2c_client imx135_sensor_i2c_client = {
-	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
-};
-
-static int __init msm_sensor_init_module(void)
-{
-	return i2c_add_driver(&imx135_i2c_driver);
-}
-
-static struct v4l2_subdev_core_ops imx135_subdev_core_ops = {
-	.ioctl = msm_sensor_subdev_ioctl,
-	.s_power = msm_sensor_power,
-};
-
-static struct v4l2_subdev_video_ops imx135_subdev_video_ops = {
-	.enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
-};
-
-static struct v4l2_subdev_ops imx135_subdev_ops = {
-	.core = &imx135_subdev_core_ops,
-	.video  = &imx135_subdev_video_ops,
-};
-
-int32_t imx135_write_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
-		uint16_t gain, uint32_t line)
-{
-	uint32_t fl_lines;
-	uint8_t offset;
-	fl_lines = s_ctrl->curr_frame_length_lines;
-	fl_lines = (fl_lines * s_ctrl->fps_divider) / Q10;
-	offset = s_ctrl->sensor_exp_gain_info->vert_offset;
-	if (line > (fl_lines - offset))
-		fl_lines = line + offset;
-
-	s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_output_reg_addr->frame_length_lines, fl_lines,
-		MSM_CAMERA_I2C_WORD_DATA);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr, line,
-		MSM_CAMERA_I2C_WORD_DATA);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->global_gain_addr, gain,
-		MSM_CAMERA_I2C_BYTE_DATA);
-	s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
-	return 0;
-}
-
-static struct msm_sensor_fn_t imx135_func_tbl = {
-	.sensor_start_stream = msm_sensor_start_stream,
-	.sensor_stop_stream = msm_sensor_stop_stream,
-	.sensor_group_hold_on = msm_sensor_group_hold_on,
-	.sensor_group_hold_off = msm_sensor_group_hold_off,
-	.sensor_set_fps = msm_sensor_set_fps,
-	.sensor_write_exp_gain = imx135_write_exp_gain,
-	.sensor_write_snapshot_exp_gain = imx135_write_exp_gain,
-	.sensor_setting = msm_sensor_setting,
-	.sensor_csi_setting = msm_sensor_setting1,
-	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
-	.sensor_mode_init = msm_sensor_mode_init,
-	.sensor_get_output_info = msm_sensor_get_output_info,
-	.sensor_config = msm_sensor_config,
-	.sensor_power_up = msm_sensor_power_up,
-	.sensor_power_down = msm_sensor_power_down,
-	.sensor_adjust_frame_lines = msm_sensor_adjust_frame_lines1,
-	.sensor_get_csi_params = msm_sensor_get_csi_params,
-};
-
-static struct msm_sensor_reg_t imx135_regs = {
-	.default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
-	.start_stream_conf = imx135_start_settings,
-	.start_stream_conf_size = ARRAY_SIZE(imx135_start_settings),
-	.stop_stream_conf = imx135_stop_settings,
-	.stop_stream_conf_size = ARRAY_SIZE(imx135_stop_settings),
-	.group_hold_on_conf = imx135_groupon_settings,
-	.group_hold_on_conf_size = ARRAY_SIZE(imx135_groupon_settings),
-	.group_hold_off_conf = imx135_groupoff_settings,
-	.group_hold_off_conf_size =
-		ARRAY_SIZE(imx135_groupoff_settings),
-	.init_settings = &imx135_init_conf[0],
-	.init_size = ARRAY_SIZE(imx135_init_conf),
-	.mode_settings = &imx135_confs[0],
-	.output_settings = &imx135_dimensions[0],
-	.num_conf = ARRAY_SIZE(imx135_confs),
-};
-
-static struct msm_sensor_ctrl_t imx135_s_ctrl = {
-	.msm_sensor_reg = &imx135_regs,
-	.sensor_i2c_client = &imx135_sensor_i2c_client,
-	.sensor_i2c_addr = 0x20,
-	.sensor_output_reg_addr = &imx135_reg_addr,
-	.sensor_id_info = &imx135_id_info,
-	.sensor_exp_gain_info = &imx135_exp_gain_info,
-	.cam_mode = MSM_SENSOR_MODE_INVALID,
-	.msm_sensor_mutex = &imx135_mut,
-	.sensor_i2c_driver = &imx135_i2c_driver,
-	.sensor_v4l2_subdev_info = imx135_subdev_info,
-	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(imx135_subdev_info),
-	.sensor_v4l2_subdev_ops = &imx135_subdev_ops,
-	.func_tbl = &imx135_func_tbl,
-	.clk_rate = MSM_SENSOR_MCLK_24HZ,
-};
-
-module_init(msm_sensor_init_module);
-MODULE_DESCRIPTION("Sony 13MP Bayer sensor driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
deleted file mode 100644
index 907523c..0000000
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ /dev/null
@@ -1,1975 +0,0 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-#include <mach/msm_bus.h>
-#include <mach/msm_bus_board.h>
-#include "msm_sensor.h"
-#include "msm_sensor_common.h"
-#include "msm.h"
-#include "msm_ispif.h"
-#include "msm_camera_i2c_mux.h"
-
-/*=============================================================*/
-void msm_sensor_adjust_frame_lines1(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	uint16_t cur_line = 0;
-	uint16_t exp_fl_lines = 0;
-	if (s_ctrl->sensor_exp_gain_info) {
-		msm_camera_i2c_read(s_ctrl->sensor_i2c_client,
-			s_ctrl->sensor_exp_gain_info->coarse_int_time_addr,
-			&cur_line,
-			MSM_CAMERA_I2C_WORD_DATA);
-		exp_fl_lines = cur_line +
-			s_ctrl->sensor_exp_gain_info->vert_offset;
-		if (exp_fl_lines > s_ctrl->msm_sensor_reg->
-			output_settings[s_ctrl->curr_res].frame_length_lines)
-			msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-				s_ctrl->sensor_output_reg_addr->
-				frame_length_lines,
-				exp_fl_lines,
-				MSM_CAMERA_I2C_WORD_DATA);
-		CDBG("%s cur_fl_lines %d, exp_fl_lines %d\n", __func__,
-			s_ctrl->msm_sensor_reg->
-			output_settings[s_ctrl->curr_res].frame_length_lines,
-			exp_fl_lines);
-	}
-	return;
-}
-
-void msm_sensor_adjust_frame_lines2(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	uint16_t cur_line = 0;
-	uint16_t exp_fl_lines = 0;
-	uint8_t int_time[3];
-	if (s_ctrl->sensor_exp_gain_info) {
-		msm_camera_i2c_read_seq(s_ctrl->sensor_i2c_client,
-			s_ctrl->sensor_exp_gain_info->coarse_int_time_addr-1,
-			&int_time[0], 3);
-		cur_line |= int_time[0] << 12;
-		cur_line |= int_time[1] << 4;
-		cur_line |= int_time[2] >> 4;
-		exp_fl_lines = cur_line +
-			s_ctrl->sensor_exp_gain_info->vert_offset;
-		if (exp_fl_lines > s_ctrl->msm_sensor_reg->
-			output_settings[s_ctrl->curr_res].frame_length_lines)
-			msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-				s_ctrl->sensor_output_reg_addr->
-				frame_length_lines,
-				exp_fl_lines,
-				MSM_CAMERA_I2C_WORD_DATA);
-		CDBG("%s cur_line %x cur_fl_lines %x, exp_fl_lines %x\n",
-			__func__,
-			cur_line,
-			s_ctrl->msm_sensor_reg->
-			output_settings[s_ctrl->curr_res].frame_length_lines,
-			exp_fl_lines);
-	}
-	return;
-}
-
-static void msm_sensor_delay_frames(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	long fps = 0;
-	uint32_t delay = 0;
-
-	if (s_ctrl->curr_res < MSM_SENSOR_INVALID_RES &&
-		s_ctrl->wait_num_frames > 0) {
-		fps = s_ctrl->msm_sensor_reg->
-			output_settings[s_ctrl->curr_res].vt_pixel_clk /
-			s_ctrl->curr_frame_length_lines /
-			s_ctrl->curr_line_length_pclk;
-		if (fps == 0)
-			delay = s_ctrl->min_delay;
-		else
-			delay = (1000 * s_ctrl->wait_num_frames) / fps / Q10;
-	}
-	CDBG("%s fps = %ld, delay = %d, min_delay %d\n", __func__, fps,
-		delay, s_ctrl->min_delay);
-	if (delay > s_ctrl->min_delay)
-		msleep(delay);
-	else if (s_ctrl->min_delay)
-		msleep(s_ctrl->min_delay);
-	return;
-}
-
-int32_t msm_sensor_write_init_settings(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	int32_t rc;
-	rc = msm_sensor_write_all_conf_array(
-		s_ctrl->sensor_i2c_client,
-		s_ctrl->msm_sensor_reg->init_settings,
-		s_ctrl->msm_sensor_reg->init_size);
-	return rc;
-}
-
-int32_t msm_sensor_write_res_settings(struct msm_sensor_ctrl_t *s_ctrl,
-	uint16_t res)
-{
-	int32_t rc;
-	rc = msm_sensor_write_conf_array(
-		s_ctrl->sensor_i2c_client,
-		s_ctrl->msm_sensor_reg->mode_settings, res);
-	if (rc < 0)
-		return rc;
-
-	rc = msm_sensor_write_output_settings(s_ctrl, res);
-	if (rc < 0)
-		return rc;
-
-	return rc;
-}
-
-int32_t msm_sensor_write_output_settings(struct msm_sensor_ctrl_t *s_ctrl,
-	uint16_t res)
-{
-	int32_t rc = -EFAULT;
-	struct msm_camera_i2c_reg_conf dim_settings[] = {
-		{s_ctrl->sensor_output_reg_addr->x_output,
-			s_ctrl->msm_sensor_reg->
-			output_settings[res].x_output},
-		{s_ctrl->sensor_output_reg_addr->y_output,
-			s_ctrl->msm_sensor_reg->
-			output_settings[res].y_output},
-		{s_ctrl->sensor_output_reg_addr->line_length_pclk,
-			s_ctrl->msm_sensor_reg->
-			output_settings[res].line_length_pclk},
-		{s_ctrl->sensor_output_reg_addr->frame_length_lines,
-			s_ctrl->msm_sensor_reg->
-			output_settings[res].frame_length_lines},
-	};
-
-	rc = msm_camera_i2c_write_tbl(s_ctrl->sensor_i2c_client, dim_settings,
-		ARRAY_SIZE(dim_settings), MSM_CAMERA_I2C_WORD_DATA);
-	return rc;
-}
-
-void msm_sensor_start_stream(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	if (s_ctrl->curr_res >= s_ctrl->msm_sensor_reg->num_conf)
-		return;
-
-	if (s_ctrl->func_tbl->sensor_adjust_frame_lines)
-		s_ctrl->func_tbl->sensor_adjust_frame_lines(s_ctrl);
-
-	msm_camera_i2c_write_tbl(
-		s_ctrl->sensor_i2c_client,
-		s_ctrl->msm_sensor_reg->start_stream_conf,
-		s_ctrl->msm_sensor_reg->start_stream_conf_size,
-		s_ctrl->msm_sensor_reg->default_data_type);
-	msm_sensor_delay_frames(s_ctrl);
-}
-
-void msm_sensor_stop_stream(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	msm_camera_i2c_write_tbl(
-		s_ctrl->sensor_i2c_client,
-		s_ctrl->msm_sensor_reg->stop_stream_conf,
-		s_ctrl->msm_sensor_reg->stop_stream_conf_size,
-		s_ctrl->msm_sensor_reg->default_data_type);
-	msm_sensor_delay_frames(s_ctrl);
-}
-
-void msm_sensor_group_hold_on(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	msm_camera_i2c_write_tbl(
-		s_ctrl->sensor_i2c_client,
-		s_ctrl->msm_sensor_reg->group_hold_on_conf,
-		s_ctrl->msm_sensor_reg->group_hold_on_conf_size,
-		s_ctrl->msm_sensor_reg->default_data_type);
-}
-
-void msm_sensor_group_hold_off(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	msm_camera_i2c_write_tbl(
-		s_ctrl->sensor_i2c_client,
-		s_ctrl->msm_sensor_reg->group_hold_off_conf,
-		s_ctrl->msm_sensor_reg->group_hold_off_conf_size,
-		s_ctrl->msm_sensor_reg->default_data_type);
-}
-
-int32_t msm_sensor_set_fps(struct msm_sensor_ctrl_t *s_ctrl,
-						struct fps_cfg *fps)
-{
-	s_ctrl->fps_divider = fps->fps_div;
-
-	return 0;
-}
-
-int32_t msm_sensor_write_exp_gain1(struct msm_sensor_ctrl_t *s_ctrl,
-		uint16_t gain, uint32_t line)
-{
-	uint32_t fl_lines;
-	uint8_t offset;
-	fl_lines = s_ctrl->curr_frame_length_lines;
-	fl_lines = (fl_lines * s_ctrl->fps_divider) / Q10;
-	offset = s_ctrl->sensor_exp_gain_info->vert_offset;
-	if (line > (fl_lines - offset))
-		fl_lines = line + offset;
-
-	s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_output_reg_addr->frame_length_lines, fl_lines,
-		MSM_CAMERA_I2C_WORD_DATA);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr, line,
-		MSM_CAMERA_I2C_WORD_DATA);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->global_gain_addr, gain,
-		MSM_CAMERA_I2C_WORD_DATA);
-	s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
-	return 0;
-}
-
-int32_t msm_sensor_write_exp_gain2(struct msm_sensor_ctrl_t *s_ctrl,
-		uint16_t gain, uint32_t line)
-{
-	uint32_t fl_lines, ll_pclk, ll_ratio;
-	uint8_t offset;
-	fl_lines = s_ctrl->curr_frame_length_lines * s_ctrl->fps_divider / Q10;
-	ll_pclk = s_ctrl->curr_line_length_pclk;
-	offset = s_ctrl->sensor_exp_gain_info->vert_offset;
-	if (line > (fl_lines - offset)) {
-		ll_ratio = (line * Q10) / (fl_lines - offset);
-		ll_pclk = ll_pclk * ll_ratio / Q10;
-		line = fl_lines - offset;
-	}
-
-	s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_output_reg_addr->line_length_pclk, ll_pclk,
-		MSM_CAMERA_I2C_WORD_DATA);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr, line,
-		MSM_CAMERA_I2C_WORD_DATA);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->global_gain_addr, gain,
-		MSM_CAMERA_I2C_WORD_DATA);
-	s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
-	return 0;
-}
-
-int32_t msm_sensor_setting1(struct msm_sensor_ctrl_t *s_ctrl,
-			int update_type, int res)
-{
-	int32_t rc = 0;
-
-	if (update_type == MSM_SENSOR_REG_INIT) {
-		CDBG("Register INIT\n");
-		msm_sensor_enable_debugfs(s_ctrl);
-		s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
-		msm_sensor_write_init_settings(s_ctrl);
-	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
-		CDBG("PERIODIC : %d\n", res);
-		msm_sensor_write_conf_array(
-			s_ctrl->sensor_i2c_client,
-			s_ctrl->msm_sensor_reg->mode_settings, res);
-		msleep(30);
-		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
-			NOTIFY_PCLK_CHANGE,
-			&s_ctrl->sensordata->pdata->ioclk.vfe_clk_rate);
-	}
-	return rc;
-}
-
-int32_t msm_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
-			int update_type, int res)
-{
-	int32_t rc = 0;
-
-	if (update_type == MSM_SENSOR_REG_INIT) {
-		s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
-		msm_sensor_write_init_settings(s_ctrl);
-	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
-		msm_sensor_write_res_settings(s_ctrl, res);
-		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
-			NOTIFY_PCLK_CHANGE, &s_ctrl->msm_sensor_reg->
-			output_settings[res].op_pixel_clk);
-	}
-	return rc;
-}
-
-int32_t msm_sensor_set_sensor_mode(struct msm_sensor_ctrl_t *s_ctrl,
-	int mode, int res)
-{
-	int32_t rc = 0;
-	if (s_ctrl->curr_res != res) {
-		s_ctrl->curr_frame_length_lines =
-			s_ctrl->msm_sensor_reg->
-			output_settings[res].frame_length_lines;
-
-		s_ctrl->curr_line_length_pclk =
-			s_ctrl->msm_sensor_reg->
-			output_settings[res].line_length_pclk;
-
-		if (s_ctrl->is_csic ||
-			!s_ctrl->sensordata->csi_if)
-			rc = s_ctrl->func_tbl->sensor_csi_setting(s_ctrl,
-				MSM_SENSOR_UPDATE_PERIODIC, res);
-		else
-			rc = s_ctrl->func_tbl->sensor_setting(s_ctrl,
-				MSM_SENSOR_UPDATE_PERIODIC, res);
-		if (rc < 0)
-			return rc;
-		s_ctrl->curr_res = res;
-	}
-
-	return rc;
-}
-
-int32_t msm_sensor_mode_init(struct msm_sensor_ctrl_t *s_ctrl,
-			int mode, struct sensor_init_cfg *init_info)
-{
-	int32_t rc = 0;
-	s_ctrl->fps_divider = Q10;
-	s_ctrl->cam_mode = MSM_SENSOR_MODE_INVALID;
-
-	CDBG("%s: %d\n", __func__, __LINE__);
-	if (mode != s_ctrl->cam_mode) {
-		s_ctrl->curr_res = MSM_SENSOR_INVALID_RES;
-		s_ctrl->cam_mode = mode;
-
-		if (s_ctrl->is_csic ||
-			!s_ctrl->sensordata->csi_if)
-			rc = s_ctrl->func_tbl->sensor_csi_setting(s_ctrl,
-				MSM_SENSOR_REG_INIT, 0);
-		else
-			rc = s_ctrl->func_tbl->sensor_setting(s_ctrl,
-				MSM_SENSOR_REG_INIT, 0);
-	}
-	return rc;
-}
-
-int32_t msm_sensor_get_output_info(struct msm_sensor_ctrl_t *s_ctrl,
-		struct sensor_output_info_t *sensor_output_info)
-{
-	int rc = 0;
-	sensor_output_info->num_info = s_ctrl->msm_sensor_reg->num_conf;
-	if (copy_to_user((void *)sensor_output_info->output_info,
-		s_ctrl->msm_sensor_reg->output_settings,
-		sizeof(struct msm_sensor_output_info_t) *
-		s_ctrl->msm_sensor_reg->num_conf))
-		rc = -EFAULT;
-
-	return rc;
-}
-
-static int32_t msm_sensor_release(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	CDBG("%s called\n", __func__);
-	s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
-	return 0;
-}
-
-long msm_sensor_subdev_ioctl(struct v4l2_subdev *sd,
-			unsigned int cmd, void *arg)
-{
-	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
-	void __user *argp = (void __user *)arg;
-	if (s_ctrl->sensor_state == MSM_SENSOR_POWER_DOWN)
-		return -EINVAL;
-	switch (cmd) {
-	case VIDIOC_MSM_SENSOR_CFG:
-		return s_ctrl->func_tbl->sensor_config(s_ctrl, argp);
-	case VIDIOC_MSM_SENSOR_RELEASE:
-		return msm_sensor_release(s_ctrl);
-	case VIDIOC_MSM_SENSOR_CSID_INFO: {
-		struct msm_sensor_csi_info *csi_info =
-			(struct msm_sensor_csi_info *)arg;
-		s_ctrl->is_csic = csi_info->is_csic;
-		return 0;
-	}
-	default:
-		return -ENOIOCTLCMD;
-	}
-}
-
-int32_t msm_sensor_get_csi_params(struct msm_sensor_ctrl_t *s_ctrl,
-		struct csi_lane_params_t *sensor_output_info)
-{
-	uint8_t index;
-	struct msm_camera_csi_lane_params *csi_lane_params =
-		s_ctrl->sensordata->sensor_platform_info->csi_lane_params;
-	if (csi_lane_params) {
-		sensor_output_info->csi_lane_assign = csi_lane_params->
-			csi_lane_assign;
-		sensor_output_info->csi_lane_mask = csi_lane_params->
-			csi_lane_mask;
-		sensor_output_info->csi_phy_sel =
-			s_ctrl->sensordata->pdata->csiphy_core;
-	}
-	sensor_output_info->csi_if = s_ctrl->sensordata->csi_if;
-	for (index = 0; index < sensor_output_info->csi_if; index++)
-		sensor_output_info->csid_core[index] = s_ctrl->sensordata->
-			pdata[index].csid_core;
-
-	return 0;
-}
-
-int32_t msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl, void __user *argp)
-{
-	struct sensor_cfg_data cdata;
-	long   rc = 0;
-	if (copy_from_user(&cdata,
-		(void *)argp,
-		sizeof(struct sensor_cfg_data)))
-		return -EFAULT;
-	mutex_lock(s_ctrl->msm_sensor_mutex);
-	CDBG("%s:%d %s cfgtype = %d\n", __func__, __LINE__,
-		s_ctrl->sensordata->sensor_name, cdata.cfgtype);
-	switch (cdata.cfgtype) {
-		case CFG_SET_FPS:
-		case CFG_SET_PICT_FPS:
-			if (s_ctrl->func_tbl->
-			sensor_set_fps == NULL) {
-				rc = -EFAULT;
-				break;
-			}
-			rc = s_ctrl->func_tbl->
-				sensor_set_fps(
-				s_ctrl,
-				&(cdata.cfg.fps));
-			break;
-
-		case CFG_SET_EXP_GAIN:
-			if (s_ctrl->func_tbl->
-			sensor_write_exp_gain == NULL) {
-				rc = -EFAULT;
-				break;
-			}
-			rc =
-				s_ctrl->func_tbl->
-				sensor_write_exp_gain(
-					s_ctrl,
-					cdata.cfg.exp_gain.gain,
-					cdata.cfg.exp_gain.line);
-			break;
-
-		case CFG_SET_PICT_EXP_GAIN:
-			if (s_ctrl->func_tbl->
-			sensor_write_snapshot_exp_gain == NULL) {
-				rc = -EFAULT;
-				break;
-			}
-			rc =
-				s_ctrl->func_tbl->
-				sensor_write_snapshot_exp_gain(
-					s_ctrl,
-					cdata.cfg.exp_gain.gain,
-					cdata.cfg.exp_gain.line);
-			break;
-
-		case CFG_SET_MODE:
-			if (s_ctrl->func_tbl->
-			sensor_set_sensor_mode == NULL) {
-				rc = -EFAULT;
-				break;
-			}
-			rc = s_ctrl->func_tbl->
-				sensor_set_sensor_mode(
-					s_ctrl,
-					cdata.mode,
-					cdata.rs);
-			break;
-
-		case CFG_SET_EFFECT:
-			break;
-
-		case CFG_SENSOR_INIT:
-			if (s_ctrl->func_tbl->
-			sensor_mode_init == NULL) {
-				rc = -EFAULT;
-				break;
-			}
-			rc = s_ctrl->func_tbl->
-				sensor_mode_init(
-				s_ctrl,
-				cdata.mode,
-				&(cdata.cfg.init_info));
-			break;
-
-		case CFG_GET_OUTPUT_INFO:
-			if (s_ctrl->func_tbl->
-			sensor_get_output_info == NULL) {
-				rc = -EFAULT;
-				break;
-			}
-			rc = s_ctrl->func_tbl->
-				sensor_get_output_info(
-				s_ctrl,
-				&cdata.cfg.output_info);
-
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_START_STREAM:
-			if (s_ctrl->func_tbl->sensor_start_stream == NULL) {
-				rc = -EFAULT;
-				break;
-			}
-			s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
-			break;
-
-		case CFG_STOP_STREAM:
-			if (s_ctrl->func_tbl->sensor_stop_stream == NULL) {
-				rc = -EFAULT;
-				break;
-			}
-			s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
-			break;
-
-		case CFG_GET_CSI_PARAMS:
-			if (s_ctrl->func_tbl->sensor_get_csi_params == NULL) {
-				rc = -EFAULT;
-				break;
-			}
-			rc = s_ctrl->func_tbl->sensor_get_csi_params(
-				s_ctrl,
-				&cdata.cfg.csi_lane_params);
-
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_POWER_UP:
-			pr_err("%s calling power up\n", __func__);
-			if (s_ctrl->func_tbl->sensor_power_up)
-				rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
-			else
-				rc = -EFAULT;
-			break;
-
-		case CFG_POWER_DOWN:
-			if (s_ctrl->func_tbl->sensor_power_down)
-				rc = s_ctrl->func_tbl->sensor_power_down(
-					s_ctrl);
-			else
-				rc = -EFAULT;
-			break;
-
-		default:
-			rc = -EFAULT;
-			break;
-		}
-
-	mutex_unlock(s_ctrl->msm_sensor_mutex);
-
-	return rc;
-}
-
-static struct msm_cam_clk_info cam_8960_clk_info[] = {
-	{"cam_clk", MSM_SENSOR_MCLK_24HZ},
-};
-
-static struct msm_cam_clk_info cam_8974_clk_info[] = {
-	{"cam_src_clk", 19200000},
-	{"cam_clk", -1},
-};
-
-int32_t msm_sensor_enable_i2c_mux(struct msm_camera_i2c_conf *i2c_conf)
-{
-	struct v4l2_subdev *i2c_mux_sd =
-		dev_get_drvdata(&i2c_conf->mux_dev->dev);
-	v4l2_subdev_call(i2c_mux_sd, core, ioctl,
-		VIDIOC_MSM_I2C_MUX_INIT, NULL);
-	v4l2_subdev_call(i2c_mux_sd, core, ioctl,
-		VIDIOC_MSM_I2C_MUX_CFG, (void *)&i2c_conf->i2c_mux_mode);
-	return 0;
-}
-
-int32_t msm_sensor_disable_i2c_mux(struct msm_camera_i2c_conf *i2c_conf)
-{
-	struct v4l2_subdev *i2c_mux_sd =
-		dev_get_drvdata(&i2c_conf->mux_dev->dev);
-	v4l2_subdev_call(i2c_mux_sd, core, ioctl,
-				VIDIOC_MSM_I2C_MUX_RELEASE, NULL);
-	return 0;
-}
-
-static int32_t msm_sensor_init_flash_data(struct device_node *of_node,
-	struct  msm_camera_sensor_info *sensordata)
-{
-	int32_t rc = 0;
-	uint32_t val = 0;
-	struct msm_camera_sensor_flash_data *flash_data = NULL;
-	struct device_node *flash_src_node = NULL;
-
-	sensordata->flash_data = kzalloc(sizeof(
-		struct msm_camera_sensor_flash_data), GFP_KERNEL);
-	if (!sensordata->flash_data) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		return -ENOMEM;
-	}
-
-	if (!of_get_property(of_node, "qcom,flash-src-index", &val)) {
-		CDBG("%s flash not available\n", __func__);
-		return rc;
-	}
-	flash_data = sensordata->flash_data;
-
-	flash_src_node = of_parse_phandle(of_node, "qcom,flash-src-index", 0);
-	if (!flash_src_node) {
-		pr_err("%s:%d flash_src_node NULL\n", __func__,
-			__LINE__);
-		goto ERROR1;
-	}
-
-	rc = of_property_read_u32(flash_src_node, "qcom,flash-type", &val);
-	CDBG("%s qcom,flash-type %d, rc %d\n", __func__, val, rc);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR2;
-	}
-	flash_data->flash_type = val;
-
-	rc = of_property_read_u32(flash_src_node, "cell-index", &val);
-	CDBG("%s qcom,flash-src-index %d, rc %d\n", __func__, val, rc);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR2;
-	}
-	flash_data->flash_src_index = val;
-
-	of_node_put(flash_src_node);
-
-	return rc;
-ERROR2:
-	of_node_put(flash_src_node);
-ERROR1:
-	flash_data->flash_type = MSM_CAMERA_FLASH_NONE;
-	return rc;
-}
-
-static int32_t msm_sensor_init_vreg_data(struct device_node *of_node,
-	struct msm_camera_sensor_platform_info *pinfo)
-{
-	int32_t rc = 0, i = 0;
-	uint32_t count = 0;
-	uint32_t *val_array = NULL;
-
-	count = of_property_count_strings(of_node, "qcom,cam-vreg-name");
-	CDBG("%s qcom,cam-vreg-name count %d\n", __func__, count);
-
-	if (!count)
-		return 0;
-
-	pinfo->cam_vreg = kzalloc(sizeof(struct camera_vreg_t) * count,
-		GFP_KERNEL);
-	if (!pinfo->cam_vreg) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		return -ENOMEM;
-	}
-
-	pinfo->num_vreg = count;
-	for (i = 0; i < count; i++) {
-		rc = of_property_read_string_index(of_node,
-			"qcom,cam-vreg-name", i, &pinfo->cam_vreg[i].reg_name);
-		CDBG("%s reg_name[%d] = %s\n", __func__, i,
-			pinfo->cam_vreg[i].reg_name);
-		if (rc < 0) {
-			pr_err("%s failed %d\n", __func__, __LINE__);
-			goto ERROR1;
-		}
-	}
-
-	val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
-	if (!val_array) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		rc = -ENOMEM;
-		goto ERROR1;
-	}
-
-	rc = of_property_read_u32_array(of_node, "qcom,cam-vreg-type",
-		val_array, count);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR2;
-	}
-	for (i = 0; i < count; i++) {
-		pinfo->cam_vreg[i].type = val_array[i];
-		CDBG("%s cam_vreg[%d].type = %d\n", __func__, i,
-			pinfo->cam_vreg[i].type);
-	}
-
-	rc = of_property_read_u32_array(of_node, "qcom,cam-vreg-min-voltage",
-		val_array, count);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR2;
-	}
-	for (i = 0; i < count; i++) {
-		pinfo->cam_vreg[i].min_voltage = val_array[i];
-		CDBG("%s cam_vreg[%d].min_voltage = %d\n", __func__,
-			i, pinfo->cam_vreg[i].min_voltage);
-	}
-
-	rc = of_property_read_u32_array(of_node, "qcom,cam-vreg-max-voltage",
-		val_array, count);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR2;
-	}
-	for (i = 0; i < count; i++) {
-		pinfo->cam_vreg[i].max_voltage = val_array[i];
-		CDBG("%s cam_vreg[%d].max_voltage = %d\n", __func__,
-			i, pinfo->cam_vreg[i].max_voltage);
-	}
-
-	rc = of_property_read_u32_array(of_node, "qcom,cam-vreg-op-mode",
-		val_array, count);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR2;
-	}
-	for (i = 0; i < count; i++) {
-		pinfo->cam_vreg[i].op_mode = val_array[i];
-		CDBG("%s cam_vreg[%d].op_mode = %d\n", __func__, i,
-			pinfo->cam_vreg[i].op_mode);
-	}
-
-	kfree(val_array);
-	return rc;
-ERROR2:
-	kfree(val_array);
-ERROR1:
-	kfree(pinfo->cam_vreg);
-	pinfo->num_vreg = 0;
-	return rc;
-}
-
-static int32_t msm_sensor_init_gpio_common_tbl_data(struct device_node *of_node,
-	struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
-	uint16_t gpio_array_size)
-{
-	int32_t rc = 0, i = 0;
-	uint32_t count = 0;
-	uint32_t *val_array = NULL;
-
-	if (!of_get_property(of_node, "qcom,gpio-common-tbl-num", &count))
-		return 0;
-
-	count /= sizeof(uint32_t);
-	if (!count) {
-		pr_err("%s qcom,gpio-common-tbl-num 0\n", __func__);
-		return 0;
-	} else if (count > gpio_array_size) {
-		pr_err("%s gpio common tbl size exceeds gpio array\n",
-			__func__);
-		return -EFAULT;
-	}
-
-	val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
-	if (!val_array) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		return -ENOMEM;
-	}
-
-	gconf->cam_gpio_common_tbl = kzalloc(sizeof(struct gpio) * count,
-		GFP_KERNEL);
-	if (!gconf->cam_gpio_common_tbl) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		rc = -ENOMEM;
-		goto ERROR1;
-	}
-	gconf->cam_gpio_common_tbl_size = count;
-
-	rc = of_property_read_u32_array(of_node, "qcom,gpio-common-tbl-num",
-		val_array, count);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR2;
-	}
-	for (i = 0; i < count; i++) {
-		if (val_array[i] >= gpio_array_size) {
-			pr_err("%s gpio common tbl index %d invalid\n",
-				__func__, val_array[i]);
-			return -EINVAL;
-		}
-		gconf->cam_gpio_common_tbl[i].gpio = gpio_array[val_array[i]];
-		CDBG("%s cam_gpio_common_tbl[%d].gpio = %d\n", __func__, i,
-			gconf->cam_gpio_common_tbl[i].gpio);
-	}
-
-	rc = of_property_read_u32_array(of_node, "qcom,gpio-common-tbl-flags",
-		val_array, count);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR2;
-	}
-	for (i = 0; i < count; i++) {
-		gconf->cam_gpio_common_tbl[i].flags = val_array[i];
-		CDBG("%s cam_gpio_common_tbl[%d].flags = %ld\n", __func__, i,
-			gconf->cam_gpio_common_tbl[i].flags);
-	}
-
-	for (i = 0; i < count; i++) {
-		rc = of_property_read_string_index(of_node,
-			"qcom,gpio-common-tbl-label", i,
-			&gconf->cam_gpio_common_tbl[i].label);
-		CDBG("%s cam_gpio_common_tbl[%d].label = %s\n", __func__, i,
-			gconf->cam_gpio_common_tbl[i].label);
-		if (rc < 0) {
-			pr_err("%s failed %d\n", __func__, __LINE__);
-			goto ERROR2;
-		}
-	}
-
-	kfree(val_array);
-	return rc;
-
-ERROR2:
-	kfree(gconf->cam_gpio_common_tbl);
-ERROR1:
-	kfree(val_array);
-	gconf->cam_gpio_common_tbl_size = 0;
-	return rc;
-}
-
-static int32_t msm_sensor_init_gpio_req_tbl_data(struct device_node *of_node,
-	struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
-	uint16_t gpio_array_size)
-{
-	int32_t rc = 0, i = 0;
-	uint32_t count = 0;
-	uint32_t *val_array = NULL;
-
-	if (!of_get_property(of_node, "qcom,gpio-req-tbl-num", &count))
-		return 0;
-
-	count /= sizeof(uint32_t);
-	if (!count) {
-		pr_err("%s qcom,gpio-req-tbl-num 0\n", __func__);
-		return 0;
-	}
-
-	val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
-	if (!val_array) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		return -ENOMEM;
-	}
-
-	gconf->cam_gpio_req_tbl = kzalloc(sizeof(struct gpio) * count,
-		GFP_KERNEL);
-	if (!gconf->cam_gpio_req_tbl) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		rc = -ENOMEM;
-		goto ERROR1;
-	}
-	gconf->cam_gpio_req_tbl_size = count;
-
-	rc = of_property_read_u32_array(of_node, "qcom,gpio-req-tbl-num",
-		val_array, count);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR2;
-	}
-	for (i = 0; i < count; i++) {
-		if (val_array[i] >= gpio_array_size) {
-			pr_err("%s gpio req tbl index %d invalid\n",
-				__func__, val_array[i]);
-			return -EINVAL;
-		}
-		gconf->cam_gpio_req_tbl[i].gpio = gpio_array[val_array[i]];
-		CDBG("%s cam_gpio_req_tbl[%d].gpio = %d\n", __func__, i,
-			gconf->cam_gpio_req_tbl[i].gpio);
-	}
-
-	rc = of_property_read_u32_array(of_node, "qcom,gpio-req-tbl-flags",
-		val_array, count);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR2;
-	}
-	for (i = 0; i < count; i++) {
-		gconf->cam_gpio_req_tbl[i].flags = val_array[i];
-		CDBG("%s cam_gpio_req_tbl[%d].flags = %ld\n", __func__, i,
-			gconf->cam_gpio_req_tbl[i].flags);
-	}
-
-	for (i = 0; i < count; i++) {
-		rc = of_property_read_string_index(of_node,
-			"qcom,gpio-req-tbl-label", i,
-			&gconf->cam_gpio_req_tbl[i].label);
-		CDBG("%s cam_gpio_req_tbl[%d].label = %s\n", __func__, i,
-			gconf->cam_gpio_req_tbl[i].label);
-		if (rc < 0) {
-			pr_err("%s failed %d\n", __func__, __LINE__);
-			goto ERROR2;
-		}
-	}
-
-	kfree(val_array);
-	return rc;
-
-ERROR2:
-	kfree(gconf->cam_gpio_req_tbl);
-ERROR1:
-	kfree(val_array);
-	gconf->cam_gpio_req_tbl_size = 0;
-	return rc;
-}
-
-static int32_t msm_sensor_init_gpio_set_tbl_data(struct device_node *of_node,
-	struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
-	uint16_t gpio_array_size)
-{
-	int32_t rc = 0, i = 0;
-	uint32_t count = 0;
-	uint32_t *val_array = NULL;
-
-	if (!of_get_property(of_node, "qcom,gpio-set-tbl-num", &count))
-		return 0;
-
-	count /= sizeof(uint32_t);
-	if (!count) {
-		pr_err("%s qcom,gpio-set-tbl-num 0\n", __func__);
-		return 0;
-	}
-
-	val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
-	if (!val_array) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		return -ENOMEM;
-	}
-
-	gconf->cam_gpio_set_tbl = kzalloc(sizeof(struct msm_gpio_set_tbl) *
-		count, GFP_KERNEL);
-	if (!gconf->cam_gpio_set_tbl) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		rc = -ENOMEM;
-		goto ERROR1;
-	}
-	gconf->cam_gpio_set_tbl_size = count;
-
-	rc = of_property_read_u32_array(of_node, "qcom,gpio-set-tbl-num",
-		val_array, count);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR2;
-	}
-	for (i = 0; i < count; i++) {
-		if (val_array[i] >= gpio_array_size) {
-			pr_err("%s gpio set tbl index %d invalid\n",
-				__func__, val_array[i]);
-			return -EINVAL;
-		}
-		gconf->cam_gpio_set_tbl[i].gpio = gpio_array[val_array[i]];
-		CDBG("%s cam_gpio_set_tbl[%d].gpio = %d\n", __func__, i,
-			gconf->cam_gpio_set_tbl[i].gpio);
-	}
-
-	rc = of_property_read_u32_array(of_node, "qcom,gpio-set-tbl-flags",
-		val_array, count);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR2;
-	}
-	for (i = 0; i < count; i++) {
-		gconf->cam_gpio_set_tbl[i].flags = val_array[i];
-		CDBG("%s cam_gpio_set_tbl[%d].flags = %ld\n", __func__, i,
-			gconf->cam_gpio_set_tbl[i].flags);
-	}
-
-	rc = of_property_read_u32_array(of_node, "qcom,gpio-set-tbl-delay",
-		val_array, count);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR2;
-	}
-	for (i = 0; i < count; i++) {
-		gconf->cam_gpio_set_tbl[i].delay = val_array[i];
-		CDBG("%s cam_gpio_set_tbl[%d].delay = %d\n", __func__, i,
-			gconf->cam_gpio_set_tbl[i].delay);
-	}
-
-	kfree(val_array);
-	return rc;
-
-ERROR2:
-	kfree(gconf->cam_gpio_set_tbl);
-ERROR1:
-	kfree(val_array);
-	gconf->cam_gpio_set_tbl_size = 0;
-	return rc;
-}
-
-static int32_t msm_sensor_init_gpio_tlmm_tbl_data(struct device_node *of_node,
-	struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
-	uint16_t gpio_array_size)
-{
-	int32_t rc = 0, i = 0;
-	uint32_t count = 0;
-	uint32_t *val_array = NULL;
-	struct gpio_tlmm_cfg *tlmm_cfg = NULL;
-
-	if (!of_get_property(of_node, "gpio_tlmm_table_num", &count))
-		return 0;
-
-	count /= sizeof(uint32_t);
-
-	if (!count)
-		return 0;
-
-	val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
-	if (!val_array) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		return -ENOMEM;
-	}
-
-	tlmm_cfg = kzalloc(sizeof(struct gpio_tlmm_cfg) * count, GFP_KERNEL);
-	if (!tlmm_cfg) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		rc = -ENOMEM;
-		goto ERROR1;
-	}
-
-	gconf->camera_off_table = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
-	if (!gconf->camera_off_table) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		rc = -ENOMEM;
-		goto ERROR2;
-	}
-	gconf->camera_off_table_size = count;
-
-	gconf->camera_on_table = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
-	if (!gconf->camera_on_table) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		rc = -ENOMEM;
-		goto ERROR3;
-	}
-	gconf->camera_on_table_size = count;
-
-	rc = of_property_read_u32_array(of_node, "gpio_tlmm_table_num",
-		val_array, count);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR4;
-	}
-	for (i = 0; i < count; i++) {
-		if (val_array[i] >= gpio_array_size) {
-			pr_err("%s gpio set tbl index %d invalid\n",
-				__func__, val_array[i]);
-			return -EINVAL;
-		}
-		tlmm_cfg[i].gpio = gpio_array[val_array[i]];
-		CDBG("%s tlmm_cfg[%d].gpio = %d\n", __func__, i,
-			tlmm_cfg[i].gpio);
-	}
-
-	rc = of_property_read_u32_array(of_node, "gpio_tlmm_table_dir",
-		val_array, count);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR4;
-	}
-	for (i = 0; i < count; i++) {
-		tlmm_cfg[i].dir = val_array[i];
-		CDBG("%s tlmm_cfg[%d].dir = %d\n", __func__, i,
-			tlmm_cfg[i].dir);
-	}
-
-	rc = of_property_read_u32_array(of_node, "gpio_tlmm_table_pull",
-		val_array, count);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR4;
-	}
-	for (i = 0; i < count; i++) {
-		tlmm_cfg[i].pull = val_array[i];
-		CDBG("%s tlmm_cfg[%d].pull = %d\n", __func__, i,
-			tlmm_cfg[i].pull);
-	}
-
-	rc = of_property_read_u32_array(of_node, "gpio_tlmm_table_drvstr",
-		val_array, count);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR4;
-	}
-	for (i = 0; i < count; i++) {
-		tlmm_cfg[i].drvstr = val_array[i];
-		CDBG("%s tlmm_cfg[%d].drvstr = %d\n", __func__, i,
-			tlmm_cfg[i].drvstr);
-	}
-
-	for (i = 0; i < count; i++) {
-		gconf->camera_off_table[i] = GPIO_CFG(tlmm_cfg[i].gpio,
-			0, tlmm_cfg[i].dir, tlmm_cfg[i].pull,
-			tlmm_cfg[i].drvstr);
-		gconf->camera_on_table[i] = GPIO_CFG(tlmm_cfg[i].gpio,
-			1, tlmm_cfg[i].dir, tlmm_cfg[i].pull,
-			tlmm_cfg[i].drvstr);
-	}
-
-	kfree(tlmm_cfg);
-	kfree(val_array);
-	return rc;
-
-ERROR4:
-	kfree(gconf->camera_on_table);
-ERROR3:
-	kfree(gconf->camera_off_table);
-ERROR2:
-	kfree(tlmm_cfg);
-ERROR1:
-	kfree(val_array);
-	gconf->camera_off_table_size = 0;
-	gconf->camera_on_table_size = 0;
-	return rc;
-}
-
-static int32_t msm_sensor_init_csi_data(struct device_node *of_node,
-	struct  msm_camera_sensor_info *sensordata)
-{
-	int32_t rc = 0, i = 0;
-	uint32_t count = 0, val = 0;
-	uint32_t *val_array = NULL;
-	struct msm_camera_sensor_platform_info *pinfo =
-		sensordata->sensor_platform_info;
-
-	rc = of_property_read_u32(of_node, "qcom,csi-if", &count);
-	CDBG("%s qcom,csi-if %d, rc %d\n", __func__, count, rc);
-	if (rc < 0 || !count)
-		return rc;
-	sensordata->csi_if = count;
-
-	sensordata->pdata = kzalloc(sizeof(
-		struct msm_camera_device_platform_data) * count, GFP_KERNEL);
-	if (!sensordata->pdata) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		return -ENOMEM;
-	}
-
-	val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
-	if (!val_array) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		rc = -ENOMEM;
-		goto ERROR1;
-	}
-
-	rc = of_property_read_u32_array(of_node, "qcom,csid-core", val_array,
-		count);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR2;
-	}
-	for (i = 0; i < count; i++) {
-		sensordata->pdata[i].csid_core = val_array[i];
-		CDBG("%s csi_data[%d].csid_core = %d\n", __func__, i,
-			sensordata->pdata[i].csid_core);
-	}
-
-	pinfo->csi_lane_params = kzalloc(
-		sizeof(struct msm_camera_csi_lane_params), GFP_KERNEL);
-	if (!pinfo->csi_lane_params) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		rc = -ENOMEM;
-		goto ERROR2;
-	}
-
-	rc = of_property_read_u32(of_node, "qcom,csi-lane-assign", &val);
-	CDBG("%s qcom,csi-lane-assign %x, rc %d\n", __func__, val, rc);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR3;
-	}
-	pinfo->csi_lane_params->csi_lane_assign = val;
-
-	rc = of_property_read_u32(of_node, "qcom,csi-lane-mask", &val);
-	CDBG("%s qcom,csi-lane-mask %x, rc %d\n", __func__, val, rc);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR3;
-	}
-	pinfo->csi_lane_params->csi_lane_mask = val;
-
-	rc = of_property_read_u32(of_node, "qcom,csi-phy-sel", &val);
-	CDBG("%s qcom,csi-phy-sel %x, rc %d\n", __func__, val, rc);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR3;
-	}
-	sensordata->pdata->csiphy_core = val;
-	kfree(val_array);
-	return rc;
-ERROR3:
-	kfree(pinfo->csi_lane_params);
-ERROR2:
-	kfree(val_array);
-ERROR1:
-	kfree(sensordata->pdata);
-	sensordata->csi_if = 0;
-	return rc;
-}
-static int32_t msm_sensor_init_actuator_data(struct device_node *of_node,
-	struct  msm_camera_sensor_info *sensordata)
-{
-	int32_t rc = 0;
-	uint32_t val = 0;
-
-	rc = of_property_read_u32(of_node, "qcom,actuator-cam-name", &val);
-	CDBG("%s qcom,actuator-cam-name %d, rc %d\n", __func__, val, rc);
-	if (rc < 0)
-		return 0;
-
-	sensordata->actuator_info = kzalloc(sizeof(struct msm_actuator_info),
-		GFP_KERNEL);
-	if (!sensordata->actuator_info) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		rc = -ENOMEM;
-		goto ERROR;
-	}
-
-	sensordata->actuator_info->cam_name = val;
-
-	rc = of_property_read_u32(of_node, "qcom,actuator-vcm-pwd", &val);
-	CDBG("%s qcom,actuator-vcm-pwd %d, rc %d\n", __func__, val, rc);
-	if (!rc)
-		sensordata->actuator_info->vcm_pwd = val;
-
-	rc = of_property_read_u32(of_node, "qcom,actuator-vcm-enable", &val);
-	CDBG("%s qcom,actuator-vcm-enable %d, rc %d\n", __func__, val, rc);
-	if (!rc)
-		sensordata->actuator_info->vcm_enable = val;
-
-	return 0;
-ERROR:
-	return rc;
-}
-
-static int32_t msm_sensor_init_sensor_data(struct platform_device *pdev,
-	struct msm_sensor_ctrl_t *s_ctrl)
-{
-	int32_t rc = 0, i = 0;
-	uint32_t val = 0;
-	struct device_node *of_node = pdev->dev.of_node;
-	struct msm_camera_sensor_platform_info *pinfo = NULL;
-	struct msm_camera_gpio_conf *gconf = NULL;
-	struct msm_camera_sensor_info *sensordata = NULL;
-	uint16_t *gpio_array = NULL;
-	uint16_t gpio_array_size = 0;
-
-	s_ctrl->sensordata = kzalloc(sizeof(struct msm_camera_sensor_info),
-		GFP_KERNEL);
-	if (!s_ctrl->sensordata) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		return -ENOMEM;
-	}
-
-	sensordata = s_ctrl->sensordata;
-
-	rc = of_property_read_string(of_node, "qcom,sensor-name",
-		&sensordata->sensor_name);
-	CDBG("%s qcom,sensor-name %s, rc %d\n", __func__,
-		sensordata->sensor_name, rc);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR1;
-	}
-
-	rc = of_property_read_u32(of_node, "qcom,camera-type", &val);
-	CDBG("%s qcom,camera-type %d, rc %d\n", __func__, val, rc);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR1;
-	}
-	sensordata->camera_type = val;
-
-	rc = of_property_read_u32(of_node, "qcom,sensor-type", &val);
-	CDBG("%s qcom,sensor-type %d, rc %d\n", __func__, val, rc);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR1;
-	}
-	sensordata->sensor_type = val;
-
-	rc = msm_sensor_init_flash_data(of_node, sensordata);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR1;
-	}
-
-	sensordata->sensor_platform_info = kzalloc(sizeof(
-		struct msm_camera_sensor_platform_info), GFP_KERNEL);
-	if (!sensordata->sensor_platform_info) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		rc = -ENOMEM;
-		goto ERROR1;
-	}
-
-	pinfo = sensordata->sensor_platform_info;
-
-	rc = of_property_read_u32(of_node, "qcom,mount-angle",
-		&pinfo->mount_angle);
-	CDBG("%s qcom,mount-angle %d, rc %d\n", __func__, pinfo->mount_angle,
-		rc);
-	if (rc < 0) {
-		/* Set default mount angle */
-		pinfo->mount_angle = 0;
-		rc = 0;
-	}
-
-	rc = msm_sensor_init_csi_data(of_node, sensordata);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR2;
-	}
-
-	rc = msm_sensor_init_vreg_data(of_node, pinfo);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR3;
-	}
-
-	pinfo->gpio_conf = kzalloc(sizeof(struct msm_camera_gpio_conf),
-		GFP_KERNEL);
-	if (!pinfo->gpio_conf) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		rc = -ENOMEM;
-		goto ERROR4;
-	}
-	gconf = pinfo->gpio_conf;
-	rc = of_property_read_u32(of_node, "qcom,gpio-no-mux",
-		&gconf->gpio_no_mux);
-	CDBG("%s gconf->gpio_no_mux %d, rc %d\n", __func__,
-		gconf->gpio_no_mux, rc);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR5;
-	}
-
-	gpio_array_size = of_gpio_count(of_node);
-	CDBG("%s gpio count %d\n", __func__, gpio_array_size);
-
-	if (gpio_array_size) {
-		gpio_array = kzalloc(sizeof(uint16_t) * gpio_array_size,
-			GFP_KERNEL);
-		if (!gpio_array) {
-			pr_err("%s failed %d\n", __func__, __LINE__);
-			goto ERROR5;
-		}
-		for (i = 0; i < gpio_array_size; i++) {
-			gpio_array[i] = of_get_gpio(of_node, i);
-			CDBG("%s gpio_array[%d] = %d\n", __func__, i,
-				gpio_array[i]);
-		}
-
-		rc = msm_sensor_init_gpio_common_tbl_data(of_node, gconf,
-			gpio_array, gpio_array_size);
-		if (rc < 0) {
-			pr_err("%s failed %d\n", __func__, __LINE__);
-			goto ERROR5;
-		}
-
-		rc = msm_sensor_init_gpio_req_tbl_data(of_node, gconf,
-			gpio_array, gpio_array_size);
-		if (rc < 0) {
-			pr_err("%s failed %d\n", __func__, __LINE__);
-			goto ERROR6;
-		}
-
-		rc = msm_sensor_init_gpio_set_tbl_data(of_node, gconf,
-			gpio_array, gpio_array_size);
-		if (rc < 0) {
-			pr_err("%s failed %d\n", __func__, __LINE__);
-			goto ERROR7;
-		}
-
-		rc = msm_sensor_init_gpio_tlmm_tbl_data(of_node, gconf,
-			gpio_array, gpio_array_size);
-		if (rc < 0) {
-			pr_err("%s failed %d\n", __func__, __LINE__);
-			goto ERROR8;
-		}
-	}
-	rc = msm_sensor_init_actuator_data(of_node, sensordata);
-	if (rc < 0) {
-		pr_err("%s failed %d\n", __func__, __LINE__);
-		goto ERROR9;
-	}
-
-	kfree(gpio_array);
-	return rc;
-
-ERROR9:
-	kfree(s_ctrl->sensordata->sensor_platform_info->gpio_conf->
-		camera_on_table);
-	kfree(s_ctrl->sensordata->sensor_platform_info->gpio_conf->
-		camera_off_table);
-ERROR8:
-	kfree(s_ctrl->sensordata->sensor_platform_info->gpio_conf->
-		cam_gpio_set_tbl);
-ERROR7:
-	kfree(s_ctrl->sensordata->sensor_platform_info->gpio_conf->
-		cam_gpio_req_tbl);
-ERROR6:
-	kfree(s_ctrl->sensordata->sensor_platform_info->gpio_conf->
-		cam_gpio_common_tbl);
-ERROR5:
-	kfree(s_ctrl->sensordata->sensor_platform_info->gpio_conf);
-ERROR4:
-	kfree(s_ctrl->sensordata->sensor_platform_info->cam_vreg);
-ERROR3:
-	kfree(s_ctrl->sensordata->sensor_platform_info->csi_lane_params);
-	kfree(s_ctrl->sensordata->pdata);
-ERROR2:
-	kfree(s_ctrl->sensordata->sensor_platform_info);
-	kfree(s_ctrl->sensordata->flash_data);
-ERROR1:
-	kfree(s_ctrl->sensordata);
-	kfree(gpio_array);
-	return rc;
-}
-
-int32_t msm_sensor_free_sensor_data(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	if (!s_ctrl->pdev)
-		return 0;
-	kfree(s_ctrl->sensordata->sensor_platform_info->gpio_conf->
-		camera_on_table);
-	kfree(s_ctrl->sensordata->sensor_platform_info->gpio_conf->
-		camera_off_table);
-	kfree(s_ctrl->sensordata->sensor_platform_info->gpio_conf->
-		cam_gpio_set_tbl);
-	kfree(s_ctrl->sensordata->sensor_platform_info->gpio_conf->
-		cam_gpio_req_tbl);
-	kfree(s_ctrl->sensordata->sensor_platform_info->gpio_conf->
-		cam_gpio_common_tbl);
-	kfree(s_ctrl->sensordata->sensor_platform_info->gpio_conf);
-	kfree(s_ctrl->sensordata->sensor_platform_info->cam_vreg);
-	kfree(s_ctrl->sensordata->sensor_platform_info->csi_lane_params);
-	kfree(s_ctrl->sensordata->pdata);
-	kfree(s_ctrl->sensordata->sensor_platform_info);
-	kfree(s_ctrl->sensordata->flash_data);
-	kfree(s_ctrl->sensordata);
-	return 0;
-}
-
-int32_t msm_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	int32_t rc = 0;
-	struct msm_camera_sensor_info *data = s_ctrl->sensordata;
-	struct device *dev = NULL;
-	if (s_ctrl->sensor_device_type == MSM_SENSOR_PLATFORM_DEVICE)
-		dev = &s_ctrl->pdev->dev;
-	else
-		dev = &s_ctrl->sensor_i2c_client->client->dev;
-	s_ctrl->reg_ptr = kzalloc(sizeof(struct regulator *)
-			* data->sensor_platform_info->num_vreg, GFP_KERNEL);
-	if (!s_ctrl->reg_ptr) {
-		pr_err("%s: could not allocate mem for regulators\n",
-			__func__);
-		return -ENOMEM;
-	}
-
-	rc = msm_camera_request_gpio_table(data, 1);
-	if (rc < 0) {
-		pr_err("%s: request gpio failed\n", __func__);
-		goto request_gpio_failed;
-	}
-
-	rc = msm_camera_config_vreg(dev,
-		s_ctrl->sensordata->sensor_platform_info->cam_vreg,
-		s_ctrl->sensordata->sensor_platform_info->num_vreg,
-		s_ctrl->vreg_seq,
-		s_ctrl->num_vreg_seq,
-		s_ctrl->reg_ptr, 1);
-	if (rc < 0) {
-		pr_err("%s: regulator on failed\n", __func__);
-		goto config_vreg_failed;
-	}
-
-	rc = msm_camera_enable_vreg(dev,
-		s_ctrl->sensordata->sensor_platform_info->cam_vreg,
-		s_ctrl->sensordata->sensor_platform_info->num_vreg,
-		s_ctrl->vreg_seq,
-		s_ctrl->num_vreg_seq,
-		s_ctrl->reg_ptr, 1);
-	if (rc < 0) {
-		pr_err("%s: enable regulator failed\n", __func__);
-		goto enable_vreg_failed;
-	}
-
-	rc = msm_camera_config_gpio_table(data, 1);
-	if (rc < 0) {
-		pr_err("%s: config gpio failed\n", __func__);
-		goto config_gpio_failed;
-	}
-
-	if (s_ctrl->sensor_device_type == MSM_SENSOR_I2C_DEVICE) {
-		if (s_ctrl->clk_rate != 0)
-			cam_8960_clk_info->clk_rate = s_ctrl->clk_rate;
-
-		rc = msm_cam_clk_enable(dev, cam_8960_clk_info,
-			s_ctrl->cam_clk, ARRAY_SIZE(cam_8960_clk_info), 1);
-		if (rc < 0) {
-			pr_err("%s: clk enable failed\n", __func__);
-			goto enable_clk_failed;
-		}
-	} else {
-		rc = msm_cam_clk_enable(dev, cam_8974_clk_info,
-			s_ctrl->cam_clk, ARRAY_SIZE(cam_8974_clk_info), 1);
-		if (rc < 0) {
-			pr_err("%s: clk enable failed\n", __func__);
-			goto enable_clk_failed;
-		}
-	}
-
-	if (!s_ctrl->power_seq_delay)
-		usleep_range(1000, 2000);
-	else if (s_ctrl->power_seq_delay < 20)
-		usleep_range((s_ctrl->power_seq_delay * 1000),
-			((s_ctrl->power_seq_delay * 1000) + 1000));
-	else
-		msleep(s_ctrl->power_seq_delay);
-
-	if (data->sensor_platform_info->ext_power_ctrl != NULL)
-		data->sensor_platform_info->ext_power_ctrl(1);
-
-	if (data->sensor_platform_info->i2c_conf &&
-		data->sensor_platform_info->i2c_conf->use_i2c_mux)
-		msm_sensor_enable_i2c_mux(data->sensor_platform_info->i2c_conf);
-
-	if (s_ctrl->sensor_device_type == MSM_SENSOR_PLATFORM_DEVICE) {
-		rc = msm_sensor_cci_util(s_ctrl->sensor_i2c_client,
-			MSM_CCI_INIT);
-		if (rc < 0) {
-			pr_err("%s cci_init failed\n", __func__);
-			goto cci_init_failed;
-		}
-	}
-	s_ctrl->curr_res = MSM_SENSOR_INVALID_RES;
-	return rc;
-
-cci_init_failed:
-	if (data->sensor_platform_info->i2c_conf &&
-		data->sensor_platform_info->i2c_conf->use_i2c_mux)
-		msm_sensor_disable_i2c_mux(
-			data->sensor_platform_info->i2c_conf);
-enable_clk_failed:
-		msm_camera_config_gpio_table(data, 0);
-config_gpio_failed:
-	msm_camera_enable_vreg(dev,
-			s_ctrl->sensordata->sensor_platform_info->cam_vreg,
-			s_ctrl->sensordata->sensor_platform_info->num_vreg,
-			s_ctrl->vreg_seq,
-			s_ctrl->num_vreg_seq,
-			s_ctrl->reg_ptr, 0);
-
-enable_vreg_failed:
-	msm_camera_config_vreg(dev,
-		s_ctrl->sensordata->sensor_platform_info->cam_vreg,
-		s_ctrl->sensordata->sensor_platform_info->num_vreg,
-		s_ctrl->vreg_seq,
-		s_ctrl->num_vreg_seq,
-		s_ctrl->reg_ptr, 0);
-config_vreg_failed:
-	msm_camera_request_gpio_table(data, 0);
-request_gpio_failed:
-	kfree(s_ctrl->reg_ptr);
-	return rc;
-}
-
-int32_t msm_sensor_power_down(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	struct msm_camera_sensor_info *data = s_ctrl->sensordata;
-	struct device *dev = NULL;
-	if (s_ctrl->sensor_device_type == MSM_SENSOR_PLATFORM_DEVICE)
-		dev = &s_ctrl->pdev->dev;
-	else
-		dev = &s_ctrl->sensor_i2c_client->client->dev;
-	if (s_ctrl->sensor_device_type == MSM_SENSOR_PLATFORM_DEVICE) {
-		msm_sensor_cci_util(s_ctrl->sensor_i2c_client,
-			MSM_CCI_RELEASE);
-	}
-
-	if (data->sensor_platform_info->i2c_conf &&
-		data->sensor_platform_info->i2c_conf->use_i2c_mux)
-		msm_sensor_disable_i2c_mux(
-			data->sensor_platform_info->i2c_conf);
-
-	if (data->sensor_platform_info->ext_power_ctrl != NULL)
-		data->sensor_platform_info->ext_power_ctrl(0);
-	if (s_ctrl->sensor_device_type == MSM_SENSOR_I2C_DEVICE)
-		msm_cam_clk_enable(dev, cam_8960_clk_info, s_ctrl->cam_clk,
-			ARRAY_SIZE(cam_8960_clk_info), 0);
-	else
-		msm_cam_clk_enable(dev, cam_8974_clk_info, s_ctrl->cam_clk,
-			ARRAY_SIZE(cam_8974_clk_info), 0);
-	msm_camera_config_gpio_table(data, 0);
-	msm_camera_enable_vreg(dev,
-		s_ctrl->sensordata->sensor_platform_info->cam_vreg,
-		s_ctrl->sensordata->sensor_platform_info->num_vreg,
-		s_ctrl->vreg_seq,
-		s_ctrl->num_vreg_seq,
-		s_ctrl->reg_ptr, 0);
-	msm_camera_config_vreg(dev,
-		s_ctrl->sensordata->sensor_platform_info->cam_vreg,
-		s_ctrl->sensordata->sensor_platform_info->num_vreg,
-		s_ctrl->vreg_seq,
-		s_ctrl->num_vreg_seq,
-		s_ctrl->reg_ptr, 0);
-	msm_camera_request_gpio_table(data, 0);
-	kfree(s_ctrl->reg_ptr);
-	s_ctrl->curr_res = MSM_SENSOR_INVALID_RES;
-	return 0;
-}
-
-int32_t msm_sensor_match_id(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	int32_t rc = 0;
-	uint16_t chipid = 0;
-	rc = msm_camera_i2c_read(
-			s_ctrl->sensor_i2c_client,
-			s_ctrl->sensor_id_info->sensor_id_reg_addr, &chipid,
-			MSM_CAMERA_I2C_WORD_DATA);
-	if (rc < 0) {
-		pr_err("%s: %s: read id failed\n", __func__,
-			s_ctrl->sensordata->sensor_name);
-		return rc;
-	}
-
-	CDBG("%s: read id: %x expected id %x:\n", __func__, chipid,
-		s_ctrl->sensor_id_info->sensor_id);
-	if (chipid != s_ctrl->sensor_id_info->sensor_id) {
-		pr_err("msm_sensor_match_id chip id doesnot match\n");
-		return -ENODEV;
-	}
-	return rc;
-}
-
-int32_t msm_sensor_i2c_probe(struct i2c_client *client,
-	const struct i2c_device_id *id)
-{
-	int rc = 0;
-	struct msm_sensor_ctrl_t *s_ctrl;
-	CDBG("%s %s_i2c_probe called\n", __func__, client->name);
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		pr_err("%s %s i2c_check_functionality failed\n",
-			__func__, client->name);
-		rc = -EFAULT;
-		return rc;
-	}
-
-	s_ctrl = (struct msm_sensor_ctrl_t *)(id->driver_data);
-	s_ctrl->sensor_device_type = MSM_SENSOR_I2C_DEVICE;
-	if (s_ctrl->sensor_i2c_client != NULL) {
-		s_ctrl->sensor_i2c_client->client = client;
-		if (s_ctrl->sensor_i2c_addr != 0)
-			s_ctrl->sensor_i2c_client->client->addr =
-				s_ctrl->sensor_i2c_addr;
-	} else {
-		pr_err("%s %s sensor_i2c_client NULL\n",
-			__func__, client->name);
-		rc = -EFAULT;
-		return rc;
-	}
-
-	s_ctrl->sensordata = client->dev.platform_data;
-	if (s_ctrl->sensordata == NULL) {
-		pr_err("%s %s NULL sensor data\n", __func__, client->name);
-		return -EFAULT;
-	}
-
-	rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
-	if (rc < 0) {
-		pr_err("%s %s power up failed\n", __func__, client->name);
-		return rc;
-	}
-
-	if (s_ctrl->func_tbl->sensor_match_id)
-		rc = s_ctrl->func_tbl->sensor_match_id(s_ctrl);
-	else
-		rc = msm_sensor_match_id(s_ctrl);
-	if (rc < 0)
-		goto probe_fail;
-
-	if (!s_ctrl->wait_num_frames)
-		s_ctrl->wait_num_frames = 1 * Q10;
-
-	pr_err("%s %s probe succeeded\n", __func__, client->name);
-	snprintf(s_ctrl->sensor_v4l2_subdev.name,
-		sizeof(s_ctrl->sensor_v4l2_subdev.name), "%s", id->name);
-	v4l2_i2c_subdev_init(&s_ctrl->sensor_v4l2_subdev, client,
-		s_ctrl->sensor_v4l2_subdev_ops);
-	s_ctrl->sensor_v4l2_subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-	media_entity_init(&s_ctrl->sensor_v4l2_subdev.entity, 0, NULL, 0);
-	s_ctrl->sensor_v4l2_subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
-	s_ctrl->sensor_v4l2_subdev.entity.group_id = SENSOR_DEV;
-	s_ctrl->sensor_v4l2_subdev.entity.name =
-		s_ctrl->sensor_v4l2_subdev.name;
-	msm_sensor_register(&s_ctrl->sensor_v4l2_subdev);
-	s_ctrl->sensor_v4l2_subdev.entity.revision =
-		s_ctrl->sensor_v4l2_subdev.devnode->num;
-	goto power_down;
-probe_fail:
-	pr_err("%s %s_i2c_probe failed\n", __func__, client->name);
-power_down:
-	if (rc > 0)
-		rc = 0;
-	s_ctrl->func_tbl->sensor_power_down(s_ctrl);
-	s_ctrl->sensor_state = MSM_SENSOR_POWER_DOWN;
-	return rc;
-}
-
-static int msm_sensor_subdev_match_core(struct device *dev, void *data)
-{
-	int core_index = (int)data;
-	struct platform_device *pdev = to_platform_device(dev);
-	CDBG("%s cci pdev %p\n", __func__, pdev);
-	if (pdev->id == core_index)
-		return 1;
-	else
-		return 0;
-}
-
-int32_t msm_sensor_platform_probe(struct platform_device *pdev, void *data)
-{
-	int32_t rc = 0;
-	struct msm_sensor_ctrl_t *s_ctrl = (struct msm_sensor_ctrl_t *)data;
-	struct device_driver *driver;
-	struct device *dev;
-	s_ctrl->pdev = pdev;
-	CDBG("%s called data %p\n", __func__, data);
-	if (pdev->dev.of_node) {
-		rc = msm_sensor_init_sensor_data(pdev, s_ctrl);
-		if (rc < 0) {
-			pr_err("%s failed line %d\n", __func__, __LINE__);
-			return rc;
-		}
-	}
-	s_ctrl->sensor_device_type = MSM_SENSOR_PLATFORM_DEVICE;
-	s_ctrl->sensor_i2c_client->cci_client = kzalloc(sizeof(
-		struct msm_camera_cci_client), GFP_KERNEL);
-	if (!s_ctrl->sensor_i2c_client->cci_client) {
-		pr_err("%s failed line %d\n", __func__, __LINE__);
-		return rc;
-	}
-	driver = driver_find(MSM_CCI_DRV_NAME, &platform_bus_type);
-	if (!driver) {
-		pr_err("%s failed line %d\n", __func__, __LINE__);
-		return rc;
-	}
-
-	dev = driver_find_device(driver, NULL, 0,
-				msm_sensor_subdev_match_core);
-	if (!dev) {
-		pr_err("%s failed line %d\n", __func__, __LINE__);
-		return rc;
-	}
-	s_ctrl->sensor_i2c_client->cci_client->cci_subdev =
-		dev_get_drvdata(dev);
-	CDBG("%s sd %p\n", __func__,
-		s_ctrl->sensor_i2c_client->cci_client->cci_subdev);
-	s_ctrl->sensor_i2c_client->cci_client->cci_i2c_master = MASTER_0;
-	s_ctrl->sensor_i2c_client->cci_client->sid =
-		s_ctrl->sensor_i2c_addr >> 1;
-	s_ctrl->sensor_i2c_client->cci_client->retries = 3;
-	s_ctrl->sensor_i2c_client->cci_client->id_map = 0;
-	if (!s_ctrl->wait_num_frames)
-		s_ctrl->wait_num_frames = 1 * Q10;
-
-	rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
-	if (rc < 0) {
-		pr_err("%s %s power up failed\n", __func__,
-			pdev->id_entry->name);
-		return rc;
-	}
-
-	if (s_ctrl->func_tbl->sensor_match_id)
-		rc = s_ctrl->func_tbl->sensor_match_id(s_ctrl);
-	else
-		rc = msm_sensor_match_id(s_ctrl);
-	if (rc < 0)
-		goto probe_fail;
-
-	pr_err("%s %s probe succeeded\n", __func__,
-		s_ctrl->sensordata->sensor_name);
-	v4l2_subdev_init(&s_ctrl->sensor_v4l2_subdev,
-		s_ctrl->sensor_v4l2_subdev_ops);
-	snprintf(s_ctrl->sensor_v4l2_subdev.name,
-		sizeof(s_ctrl->sensor_v4l2_subdev.name), "%s",
-		s_ctrl->sensordata->sensor_name);
-	v4l2_set_subdevdata(&s_ctrl->sensor_v4l2_subdev, pdev);
-	msm_sensor_register(&s_ctrl->sensor_v4l2_subdev);
-
-	goto power_down;
-probe_fail:
-	pr_err("%s %s probe failed\n", __func__, pdev->id_entry->name);
-power_down:
-	s_ctrl->func_tbl->sensor_power_down(s_ctrl);
-	return rc;
-}
-
-int32_t msm_sensor_power(struct v4l2_subdev *sd, int on)
-{
-	int rc = 0;
-	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
-	mutex_lock(s_ctrl->msm_sensor_mutex);
-	if (on) {
-		rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
-		if (rc < 0) {
-			pr_err("%s: %s power_up failed rc = %d\n", __func__,
-				s_ctrl->sensordata->sensor_name, rc);
-			s_ctrl->sensor_state = MSM_SENSOR_POWER_DOWN;
-		} else {
-			if (s_ctrl->func_tbl->sensor_match_id)
-				rc = s_ctrl->func_tbl->sensor_match_id(s_ctrl);
-			else
-				rc = msm_sensor_match_id(s_ctrl);
-			if (rc < 0) {
-				pr_err("%s: %s match_id failed  rc=%d\n",
-					__func__,
-					s_ctrl->sensordata->sensor_name, rc);
-				if (s_ctrl->func_tbl->sensor_power_down(s_ctrl)
-					< 0)
-					pr_err("%s: %s power_down failed\n",
-					__func__,
-					s_ctrl->sensordata->sensor_name);
-				s_ctrl->sensor_state = MSM_SENSOR_POWER_DOWN;
-			}
-			s_ctrl->sensor_state = MSM_SENSOR_POWER_UP;
-		}
-	} else {
-		rc = s_ctrl->func_tbl->sensor_power_down(s_ctrl);
-		s_ctrl->sensor_state = MSM_SENSOR_POWER_DOWN;
-	}
-	mutex_unlock(s_ctrl->msm_sensor_mutex);
-	return rc;
-}
-
-int32_t msm_sensor_v4l2_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
-			   enum v4l2_mbus_pixelcode *code)
-{
-	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
-
-	if ((unsigned int)index >= s_ctrl->sensor_v4l2_subdev_info_size)
-		return -EINVAL;
-
-	*code = s_ctrl->sensor_v4l2_subdev_info[index].code;
-	return 0;
-}
-
-int32_t msm_sensor_v4l2_s_ctrl(struct v4l2_subdev *sd,
-	struct v4l2_control *ctrl)
-{
-	int rc = -1, i = 0;
-	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
-	struct msm_sensor_v4l2_ctrl_info_t *v4l2_ctrl =
-		s_ctrl->msm_sensor_v4l2_ctrl_info;
-
-	CDBG("%s\n", __func__);
-	CDBG("%d\n", ctrl->id);
-	if (v4l2_ctrl == NULL)
-		return rc;
-	for (i = 0; i < s_ctrl->num_v4l2_ctrl; i++) {
-		if (v4l2_ctrl[i].ctrl_id == ctrl->id) {
-			if (v4l2_ctrl[i].s_v4l2_ctrl != NULL) {
-				CDBG("\n calling msm_sensor_s_ctrl_by_enum\n");
-				rc = v4l2_ctrl[i].s_v4l2_ctrl(
-					s_ctrl,
-					&s_ctrl->msm_sensor_v4l2_ctrl_info[i],
-					ctrl->value);
-			}
-			break;
-		}
-	}
-
-	return rc;
-}
-
-int32_t msm_sensor_v4l2_query_ctrl(
-	struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl)
-{
-	int rc = -1, i = 0;
-	struct msm_sensor_ctrl_t *s_ctrl =
-		(struct msm_sensor_ctrl_t *) sd->dev_priv;
-
-	CDBG("%s\n", __func__);
-	CDBG("%s id: %d\n", __func__, qctrl->id);
-
-	if (s_ctrl->msm_sensor_v4l2_ctrl_info == NULL)
-		return rc;
-
-	for (i = 0; i < s_ctrl->num_v4l2_ctrl; i++) {
-		if (s_ctrl->msm_sensor_v4l2_ctrl_info[i].ctrl_id == qctrl->id) {
-			qctrl->minimum =
-				s_ctrl->msm_sensor_v4l2_ctrl_info[i].min;
-			qctrl->maximum =
-				s_ctrl->msm_sensor_v4l2_ctrl_info[i].max;
-			qctrl->flags = 1;
-			rc = 0;
-			break;
-		}
-	}
-
-	return rc;
-}
-
-int msm_sensor_s_ctrl_by_enum(struct msm_sensor_ctrl_t *s_ctrl,
-		struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value)
-{
-	int rc = 0;
-	CDBG("%s enter\n", __func__);
-	rc = msm_sensor_write_enum_conf_array(
-		s_ctrl->sensor_i2c_client,
-		ctrl_info->enum_cfg_settings, value);
-	return rc;
-}
-
-static int msm_sensor_debugfs_stream_s(void *data, u64 val)
-{
-	struct msm_sensor_ctrl_t *s_ctrl = (struct msm_sensor_ctrl_t *) data;
-	if (val)
-		s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
-	else
-		s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(sensor_debugfs_stream, NULL,
-			msm_sensor_debugfs_stream_s, "%llu\n");
-
-static int msm_sensor_debugfs_test_s(void *data, u64 val)
-{
-	CDBG("val: %llu\n", val);
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(sensor_debugfs_test, NULL,
-			msm_sensor_debugfs_test_s, "%llu\n");
-
-int msm_sensor_enable_debugfs(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	struct dentry *debugfs_base, *sensor_dir;
-	debugfs_base = debugfs_create_dir("msm_sensor", NULL);
-	if (!debugfs_base)
-		return -ENOMEM;
-
-	sensor_dir = debugfs_create_dir
-		(s_ctrl->sensordata->sensor_name, debugfs_base);
-	if (!sensor_dir)
-		return -ENOMEM;
-
-	if (!debugfs_create_file("stream", S_IRUGO | S_IWUSR, sensor_dir,
-			(void *) s_ctrl, &sensor_debugfs_stream))
-		return -ENOMEM;
-
-	if (!debugfs_create_file("test", S_IRUGO | S_IWUSR, sensor_dir,
-			(void *) s_ctrl, &sensor_debugfs_test))
-		return -ENOMEM;
-
-	return 0;
-}
diff --git a/drivers/media/video/msm/sensors/msm_sensor.h b/drivers/media/video/msm/sensors/msm_sensor.h
deleted file mode 100644
index 7dd0602..0000000
--- a/drivers/media/video/msm/sensors/msm_sensor.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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 MSM_SENSOR_H
-#define MSM_SENSOR_H
-
-#include <linux/debugfs.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/miscdevice.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/uaccess.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/of_gpio.h>
-#include <linux/gpio.h>
-#include <mach/camera.h>
-#include <media/msm_camera.h>
-#include <media/v4l2-subdev.h>
-#include "msm_camera_i2c.h"
-#include "msm_camera_eeprom.h"
-#include "msm_sensor_common.h"
-
-void msm_sensor_start_stream(struct msm_sensor_ctrl_t *s_ctrl);
-void msm_sensor_stop_stream(struct msm_sensor_ctrl_t *s_ctrl);
-void msm_sensor_group_hold_on(struct msm_sensor_ctrl_t *s_ctrl);
-void msm_sensor_group_hold_off(struct msm_sensor_ctrl_t *s_ctrl);
-
-int32_t msm_sensor_set_fps(struct msm_sensor_ctrl_t *s_ctrl,
-			struct fps_cfg   *fps);
-int32_t msm_sensor_write_exp_gain1(struct msm_sensor_ctrl_t *s_ctrl,
-		uint16_t gain, uint32_t line);
-int32_t msm_sensor_write_exp_gain2(struct msm_sensor_ctrl_t *s_ctrl,
-		uint16_t gain, uint32_t line);
-int32_t msm_sensor_set_sensor_mode(struct msm_sensor_ctrl_t *s_ctrl,
-	int mode, int res);
-int32_t msm_sensor_mode_init(struct msm_sensor_ctrl_t *s_ctrl,
-			int mode, struct sensor_init_cfg *init_info);
-int32_t msm_sensor_get_output_info(struct msm_sensor_ctrl_t *,
-		struct sensor_output_info_t *);
-int32_t msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl,
-			void __user *argp);
-int32_t msm_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl);
-int32_t msm_sensor_power_down(struct msm_sensor_ctrl_t *s_ctrl);
-
-int32_t msm_sensor_match_id(struct msm_sensor_ctrl_t *s_ctrl);
-int msm_sensor_i2c_probe(struct i2c_client *client,
-	const struct i2c_device_id *id);
-
-int32_t msm_sensor_platform_probe(struct platform_device *pdev, void *data);
-
-int32_t msm_sensor_power(struct v4l2_subdev *sd, int on);
-
-int32_t msm_sensor_v4l2_s_ctrl(struct v4l2_subdev *sd,
-	struct v4l2_control *ctrl);
-
-int32_t msm_sensor_v4l2_query_ctrl(
-	struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl);
-
-int msm_sensor_s_ctrl_by_index(struct msm_sensor_ctrl_t *s_ctrl,
-	struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value);
-
-int msm_sensor_s_ctrl_by_enum(struct msm_sensor_ctrl_t *s_ctrl,
-		struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value);
-
-int msm_sensor_v4l2_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
-			enum v4l2_mbus_pixelcode *code);
-
-int msm_sensor_write_init_settings(struct msm_sensor_ctrl_t *s_ctrl);
-int msm_sensor_write_res_settings
-	(struct msm_sensor_ctrl_t *s_ctrl, uint16_t res);
-
-int32_t msm_sensor_write_output_settings(struct msm_sensor_ctrl_t *s_ctrl,
-	uint16_t res);
-
-void msm_sensor_adjust_frame_lines1(struct msm_sensor_ctrl_t *s_ctrl);
-
-void msm_sensor_adjust_frame_lines2(struct msm_sensor_ctrl_t *s_ctrl);
-
-int32_t msm_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
-			int update_type, int res);
-
-int32_t msm_sensor_setting1(struct msm_sensor_ctrl_t *s_ctrl,
-			int update_type, int res);
-
-int msm_sensor_enable_debugfs(struct msm_sensor_ctrl_t *s_ctrl);
-
-long msm_sensor_subdev_ioctl(struct v4l2_subdev *sd,
-			unsigned int cmd, void *arg);
-
-int32_t msm_sensor_get_csi_params(struct msm_sensor_ctrl_t *s_ctrl,
-		struct csi_lane_params_t *sensor_output_info);
-
-struct msm_sensor_ctrl_t *get_sctrl(struct v4l2_subdev *sd);
-int32_t msm_sensor_free_sensor_data(struct msm_sensor_ctrl_t *s_ctrl);
-
-#define VIDIOC_MSM_SENSOR_CFG \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 4, void __user *)
-
-#define VIDIOC_MSM_SENSOR_RELEASE \
-	_IO('V', BASE_VIDIOC_PRIVATE + 11)
-
-#define VIDIOC_MSM_SENSOR_CSID_INFO\
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 12, struct msm_sensor_csi_info *)
-
-#endif
diff --git a/drivers/media/video/msm/sensors/msm_sensor_bayer.c b/drivers/media/video/msm/sensors/msm_sensor_bayer.c
deleted file mode 100644
index 31313d2..0000000
--- a/drivers/media/video/msm/sensors/msm_sensor_bayer.c
+++ /dev/null
@@ -1,909 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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 "msm_sensor_bayer.h"
-#include "msm.h"
-#include "msm_ispif.h"
-#include "msm_camera_i2c_mux.h"
-/*=============================================================*/
-
-long msm_sensor_bayer_subdev_ioctl(struct v4l2_subdev *sd,
-			unsigned int cmd, void *arg)
-{
-	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
-	void __user *argp = (void __user *)arg;
-	switch (cmd) {
-	case VIDIOC_MSM_SENSOR_CFG:
-		return s_ctrl->func_tbl->sensor_config(s_ctrl, argp);
-	case VIDIOC_MSM_SENSOR_RELEASE:
-		return 0;
-	case VIDIOC_MSM_SENSOR_CSID_INFO: {
-		struct msm_sensor_csi_info *csi_info =
-			(struct msm_sensor_csi_info *)arg;
-		s_ctrl->is_csic = csi_info->is_csic;
-		return 0;
-	}
-	default:
-		return -ENOIOCTLCMD;
-	}
-}
-
-int32_t msm_sensor_bayer_get_csi_params(struct msm_sensor_ctrl_t *s_ctrl,
-		struct csi_lane_params_t *sensor_output_info)
-{
-	uint8_t index;
-	struct msm_camera_csi_lane_params *csi_lane_params =
-		s_ctrl->sensordata->sensor_platform_info->csi_lane_params;
-	if (csi_lane_params) {
-		sensor_output_info->csi_lane_assign = csi_lane_params->
-			csi_lane_assign;
-		sensor_output_info->csi_lane_mask = csi_lane_params->
-			csi_lane_mask;
-	}
-	sensor_output_info->csi_if = s_ctrl->sensordata->csi_if;
-	for (index = 0; index < sensor_output_info->csi_if; index++)
-		sensor_output_info->csid_core[index] = s_ctrl->sensordata->
-			pdata[index].csid_core;
-
-	return 0;
-}
-
-int32_t msm_sensor_bayer_config(struct msm_sensor_ctrl_t *s_ctrl,
-	void __user *argp)
-{
-	struct sensor_cfg_data cdata;
-	long rc = 0;
-	if (copy_from_user(&cdata,
-		(void *)argp,
-		sizeof(struct sensor_cfg_data)))
-		return -EFAULT;
-	mutex_lock(s_ctrl->msm_sensor_mutex);
-	CDBG("%s:%d %s cfgtype = %d\n", __func__, __LINE__,
-		s_ctrl->sensordata->sensor_name, cdata.cfgtype);
-	switch (cdata.cfgtype) {
-	case CFG_WRITE_I2C_ARRAY: {
-		struct msm_camera_i2c_reg_setting conf_array;
-		struct msm_camera_i2c_reg_array *regs = NULL;
-
-		if (copy_from_user(&conf_array,
-			(void *)cdata.cfg.setting,
-			sizeof(struct msm_camera_i2c_reg_setting))) {
-			pr_err("%s:%d failed\n", __func__, __LINE__);
-			rc = -EFAULT;
-			break;
-		}
-
-		regs = kzalloc(conf_array.size * sizeof(
-			struct msm_camera_i2c_reg_array),
-			GFP_KERNEL);
-		if (!regs) {
-			pr_err("%s:%d failed\n", __func__, __LINE__);
-			rc = -EFAULT;
-			break;
-		}
-
-		if (copy_from_user(regs, (void *)conf_array.reg_setting,
-			conf_array.size * sizeof(
-			struct msm_camera_i2c_reg_array))) {
-			pr_err("%s:%d failed\n", __func__, __LINE__);
-			kfree(regs);
-			rc = -EFAULT;
-			break;
-		}
-
-		conf_array.reg_setting = regs;
-		rc = msm_camera_i2c_write_bayer_table(s_ctrl->sensor_i2c_client,
-			&conf_array);
-		kfree(regs);
-		break;
-	}
-	case CFG_READ_I2C_ARRAY: {
-		struct msm_camera_i2c_reg_setting conf_array;
-		struct msm_camera_i2c_reg_array *regs;
-		int index;
-
-		if (copy_from_user(&conf_array,
-				(void *)cdata.cfg.setting,
-				sizeof(struct msm_camera_i2c_reg_setting))) {
-				pr_err("%s:%d failed\n", __func__, __LINE__);
-				rc = -EFAULT;
-				break;
-		}
-
-		regs = kzalloc(conf_array.size * sizeof(
-				struct msm_camera_i2c_reg_array),
-				GFP_KERNEL);
-		if (!regs) {
-			pr_err("%s:%d failed\n", __func__, __LINE__);
-			rc = -EFAULT;
-			kfree(regs);
-			break;
-		}
-
-		if (copy_from_user(regs, (void *)conf_array.reg_setting,
-				conf_array.size * sizeof(
-				struct msm_camera_i2c_reg_array))) {
-				pr_err("%s:%d failed\n", __func__, __LINE__);
-				kfree(regs);
-				rc = -EFAULT;
-				break;
-			}
-
-		s_ctrl->sensor_i2c_client->addr_type = conf_array.addr_type;
-		for (index = 0; index < conf_array.size; index++) {
-			msm_camera_i2c_read(s_ctrl->sensor_i2c_client,
-					regs[index].reg_addr,
-					&regs[index].reg_data,
-				conf_array.data_type
-				);
-		}
-
-		if (copy_to_user(conf_array.reg_setting,
-			regs,
-			conf_array.size * sizeof(
-			struct msm_camera_i2c_reg_array))) {
-			pr_err("%s:%d failed\n", __func__, __LINE__);
-			kfree(regs);
-			rc = -EFAULT;
-			break;
-		}
-		s_ctrl->sensor_i2c_client->addr_type = conf_array.addr_type;
-		kfree(regs);
-		break;
-	}
-	case CFG_PCLK_CHANGE: {
-		uint32_t pclk = cdata.cfg.pclk;
-		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
-			NOTIFY_PCLK_CHANGE, &pclk);
-		break;
-	}
-	case CFG_GPIO_OP: {
-		struct msm_cam_gpio_operation gop;
-		if (copy_from_user(&gop,
-			(void *)cdata.cfg.setting,
-			sizeof(struct msm_cam_gpio_operation))) {
-			pr_err("%s:%d failed\n", __func__, __LINE__);
-		}
-		switch (gop.op_type) {
-		case GPIO_GET_VALUE:
-			gop.value = gpio_get_value(gop.address);
-			if (copy_from_user((void *)cdata.cfg.setting,
-				&gop,
-				sizeof(struct msm_cam_gpio_operation))) {
-				pr_err("%s:%d failed\n", __func__, __LINE__);
-				rc = -EFAULT;
-				break;
-			}
-			break;
-		case GPIO_SET_VALUE:
-			gpio_set_value(gop.address, gop.value);
-			break;
-		case GPIO_SET_DIRECTION_INPUT:
-			gpio_direction_input(gop.address);
-			break;
-		case GPIO_SET_DIRECTION_OUTPUT:
-			gpio_direction_output(gop.address, gop.value);
-			break;
-		case GPIO_REQUEST:
-			gpio_request(gop.address, gop.tag);
-			break;
-		case GPIO_FREE:
-			gpio_free(gop.address);
-			break;
-		default:
-			break;
-		}
-
-		break;
-	}
-	case CFG_GET_CSI_PARAMS:
-		if (s_ctrl->func_tbl->sensor_get_csi_params == NULL) {
-			rc = -EFAULT;
-			break;
-		}
-		rc = s_ctrl->func_tbl->sensor_get_csi_params(
-			s_ctrl,
-			&cdata.cfg.csi_lane_params);
-
-		if (copy_to_user((void *)argp,
-			&cdata,
-			sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_POWER_UP:
-		if (s_ctrl->func_tbl->sensor_power_up)
-			rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
-		else
-			rc = -EFAULT;
-		break;
-
-	case CFG_POWER_DOWN:
-		if (s_ctrl->func_tbl->sensor_power_down)
-			rc = s_ctrl->func_tbl->sensor_power_down(
-				s_ctrl);
-		else
-			rc = -EFAULT;
-		break;
-
-	case CFG_CONFIG_VREG_ARRAY: {
-		struct msm_camera_vreg_setting vreg_setting;
-		struct camera_vreg_t *cam_vreg = NULL;
-
-		if (copy_from_user(&vreg_setting,
-			(void *)cdata.cfg.setting,
-			sizeof(struct msm_camera_vreg_setting))) {
-			pr_err("%s:%d failed\n", __func__, __LINE__);
-			rc = -EFAULT;
-			break;
-		}
-
-		cam_vreg = kzalloc(vreg_setting.num_vreg * sizeof(
-			struct camera_vreg_t),
-			GFP_KERNEL);
-		if (!cam_vreg) {
-			pr_err("%s:%d failed\n", __func__, __LINE__);
-			rc = -EFAULT;
-			break;
-		}
-
-		if (copy_from_user(cam_vreg, (void *)vreg_setting.cam_vreg,
-			vreg_setting.num_vreg * sizeof(
-			struct camera_vreg_t))) {
-			pr_err("%s:%d failed\n", __func__, __LINE__);
-			kfree(cam_vreg);
-			rc = -EFAULT;
-			break;
-		}
-		rc = msm_camera_config_vreg(
-			&s_ctrl->sensor_i2c_client->client->dev,
-			cam_vreg,
-			vreg_setting.num_vreg,
-			NULL,
-			0,
-			s_ctrl->reg_ptr,
-			vreg_setting.enable);
-		if (rc < 0) {
-			kfree(cam_vreg);
-			pr_err("%s: regulator on failed\n", __func__);
-			break;
-		}
-
-		rc = msm_camera_enable_vreg(
-			&s_ctrl->sensor_i2c_client->client->dev,
-			cam_vreg,
-			vreg_setting.num_vreg,
-			NULL,
-			0,
-			s_ctrl->reg_ptr,
-			vreg_setting.enable);
-		if (rc < 0) {
-			kfree(cam_vreg);
-			pr_err("%s: enable regulator failed\n", __func__);
-			break;
-		}
-		kfree(cam_vreg);
-		break;
-	}
-	case CFG_CONFIG_CLK_ARRAY: {
-		struct msm_cam_clk_setting clk_setting;
-		struct msm_cam_clk_info *clk_info = NULL;
-
-		if (copy_from_user(&clk_setting,
-			(void *)cdata.cfg.setting,
-			sizeof(struct msm_camera_vreg_setting))) {
-			pr_err("%s:%d failed\n", __func__, __LINE__);
-			rc = -EFAULT;
-			break;
-		}
-
-		clk_info = kzalloc(clk_setting.num_clk_info * sizeof(
-			struct msm_cam_clk_info),
-			GFP_KERNEL);
-		if (!clk_info) {
-			pr_err("%s:%d failed\n", __func__, __LINE__);
-			rc = -EFAULT;
-			break;
-		}
-
-		if (copy_from_user(clk_info, (void *)clk_setting.clk_info,
-			clk_setting.num_clk_info * sizeof(
-			struct msm_cam_clk_info))) {
-			pr_err("%s:%d failed\n", __func__, __LINE__);
-			kfree(clk_info);
-			rc = -EFAULT;
-			break;
-		}
-		rc = msm_cam_clk_enable(&s_ctrl->sensor_i2c_client->client->dev,
-			clk_info, s_ctrl->cam_clk,
-			clk_setting.num_clk_info,
-			clk_setting.enable);
-		kfree(clk_info);
-		break;
-	}
-	case CFG_GET_EEPROM_DATA: {
-		if (copy_to_user((void *)cdata.cfg.eeprom_data.eeprom_data,
-			&s_ctrl->eeprom_data.data, s_ctrl->eeprom_data.length)){
-			pr_err("%s:%d failed\n", __func__, __LINE__);
-			rc = -EFAULT;
-		}
-		cdata.cfg.eeprom_data.index = s_ctrl->eeprom_data.length;
-		break;
-	}
-	default:
-		rc = -EFAULT;
-		break;
-	}
-
-	mutex_unlock(s_ctrl->msm_sensor_mutex);
-
-	return rc;
-}
-
-static struct msm_cam_clk_info cam_clk_info[] = {
-	{"cam_clk", MSM_SENSOR_MCLK_24HZ},
-};
-
-int32_t msm_sensor_bayer_enable_i2c_mux(struct msm_camera_i2c_conf *i2c_conf)
-{
-	struct v4l2_subdev *i2c_mux_sd =
-		dev_get_drvdata(&i2c_conf->mux_dev->dev);
-	v4l2_subdev_call(i2c_mux_sd, core, ioctl,
-		VIDIOC_MSM_I2C_MUX_INIT, NULL);
-	v4l2_subdev_call(i2c_mux_sd, core, ioctl,
-		VIDIOC_MSM_I2C_MUX_CFG, (void *)&i2c_conf->i2c_mux_mode);
-	return 0;
-}
-
-int32_t msm_sensor_bayer_disable_i2c_mux(struct msm_camera_i2c_conf *i2c_conf)
-{
-	struct v4l2_subdev *i2c_mux_sd =
-		dev_get_drvdata(&i2c_conf->mux_dev->dev);
-	v4l2_subdev_call(i2c_mux_sd, core, ioctl,
-				VIDIOC_MSM_I2C_MUX_RELEASE, NULL);
-	return 0;
-}
-
-static struct msm_camera_power_seq_t sensor_power_seq[] = {
-	{REQUEST_GPIO, 0},
-	{REQUEST_VREG, 0},
-	{ENABLE_VREG, 0},
-	{ENABLE_GPIO, 0},
-	{CONFIG_CLK, 0},
-	{CONFIG_EXT_POWER_CTRL, 0},
-	{CONFIG_I2C_MUX, 0},
-};
-
-int32_t msm_sensor_bayer_power_up(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	int32_t rc = 0, size = 0, index = 0;
-	struct msm_camera_sensor_info *data = s_ctrl->sensordata;
-	struct msm_camera_power_seq_t *power_seq = NULL;
-	CDBG("%s: %d\n", __func__, __LINE__);
-	if (s_ctrl->power_seq) {
-		power_seq = s_ctrl->power_seq;
-		size = s_ctrl->num_power_seq;
-	} else {
-		power_seq = &sensor_power_seq[0];
-		size = ARRAY_SIZE(sensor_power_seq);
-	}
-
-	s_ctrl->reg_ptr = kzalloc(sizeof(struct regulator *)
-			* data->sensor_platform_info->num_vreg, GFP_KERNEL);
-	if (!s_ctrl->reg_ptr) {
-		pr_err("%s: could not allocate mem for regulators\n",
-			__func__);
-		return -ENOMEM;
-	}
-
-	for (index = 0; index < size; index++) {
-		switch (power_seq[index].power_config) {
-		case REQUEST_GPIO:
-			rc = msm_camera_request_gpio_table(data, 1);
-			if (rc < 0) {
-				pr_err("%s: request gpio failed\n", __func__);
-				goto ERROR;
-			}
-			if (power_seq[index].delay)
-				usleep_range(power_seq[index].delay * 1000,
-					(power_seq[index].delay * 1000) + 1000);
-			break;
-		case REQUEST_VREG:
-			rc = msm_camera_config_vreg(
-				&s_ctrl->sensor_i2c_client->client->dev,
-				s_ctrl->sensordata->sensor_platform_info->
-				cam_vreg,
-				s_ctrl->sensordata->sensor_platform_info->
-				num_vreg,
-				s_ctrl->vreg_seq,
-				s_ctrl->num_vreg_seq,
-				s_ctrl->reg_ptr, 1);
-			if (rc < 0) {
-				pr_err("%s: regulator on failed\n", __func__);
-				goto ERROR;
-			}
-			if (power_seq[index].delay)
-				usleep_range(power_seq[index].delay * 1000,
-					(power_seq[index].delay * 1000) + 1000);
-			break;
-		case ENABLE_VREG:
-			rc = msm_camera_enable_vreg(
-				&s_ctrl->sensor_i2c_client->client->dev,
-				s_ctrl->sensordata->sensor_platform_info->
-				cam_vreg,
-				s_ctrl->sensordata->sensor_platform_info->
-				num_vreg,
-				s_ctrl->vreg_seq,
-				s_ctrl->num_vreg_seq,
-				s_ctrl->reg_ptr, 1);
-			if (rc < 0) {
-				pr_err("%s: enable regulator failed\n",
-					__func__);
-				goto ERROR;
-			}
-			if (power_seq[index].delay)
-				usleep_range(power_seq[index].delay * 1000,
-					(power_seq[index].delay * 1000) + 1000);
-			break;
-		case ENABLE_GPIO:
-			rc = msm_camera_config_gpio_table(data, 1);
-			if (rc < 0) {
-				pr_err("%s: config gpio failed\n", __func__);
-				goto ERROR;
-			}
-			if (power_seq[index].delay)
-				usleep_range(power_seq[index].delay * 1000,
-					(power_seq[index].delay * 1000) + 1000);
-			break;
-		case CONFIG_CLK:
-			if (s_ctrl->clk_rate != 0)
-				cam_clk_info->clk_rate = s_ctrl->clk_rate;
-
-			rc = msm_cam_clk_enable(
-				&s_ctrl->sensor_i2c_client->client->dev,
-				cam_clk_info, s_ctrl->cam_clk,
-				ARRAY_SIZE(cam_clk_info), 1);
-			if (rc < 0) {
-				pr_err("%s: clk enable failed\n", __func__);
-				goto ERROR;
-			}
-			if (power_seq[index].delay)
-				usleep_range(power_seq[index].delay * 1000,
-					(power_seq[index].delay * 1000) + 1000);
-			break;
-		case CONFIG_EXT_POWER_CTRL:
-			if (data->sensor_platform_info->ext_power_ctrl != NULL)
-				data->sensor_platform_info->ext_power_ctrl(1);
-			if (power_seq[index].delay)
-				usleep_range(power_seq[index].delay * 1000,
-					(power_seq[index].delay * 1000) + 1000);
-			break;
-		case CONFIG_I2C_MUX:
-			if (data->sensor_platform_info->i2c_conf &&
-				data->sensor_platform_info->i2c_conf->
-				use_i2c_mux)
-				msm_sensor_bayer_enable_i2c_mux(
-					data->sensor_platform_info->i2c_conf);
-			if (power_seq[index].delay)
-				usleep_range(power_seq[index].delay * 1000,
-					(power_seq[index].delay * 1000) + 1000);
-			break;
-		default:
-			pr_err("%s error power config %d\n", __func__,
-				power_seq[index].power_config);
-			rc = -EINVAL;
-			break;
-		}
-	}
-
-	return rc;
-
-ERROR:
-	for (index--; index >= 0; index--) {
-		switch (power_seq[index].power_config) {
-		case CONFIG_I2C_MUX:
-			if (data->sensor_platform_info->i2c_conf &&
-				data->sensor_platform_info->i2c_conf->
-				use_i2c_mux)
-				msm_sensor_bayer_disable_i2c_mux(
-					data->sensor_platform_info->i2c_conf);
-			break;
-		case CONFIG_EXT_POWER_CTRL:
-			if (data->sensor_platform_info->ext_power_ctrl != NULL)
-				data->sensor_platform_info->ext_power_ctrl(0);
-			break;
-		case CONFIG_CLK:
-			msm_cam_clk_enable(&s_ctrl->sensor_i2c_client->client->
-				dev, cam_clk_info, s_ctrl->cam_clk,
-				ARRAY_SIZE(cam_clk_info), 0);
-			break;
-		case ENABLE_GPIO:
-			msm_camera_config_gpio_table(data, 0);
-			break;
-		case ENABLE_VREG:
-			msm_camera_enable_vreg(&s_ctrl->sensor_i2c_client->
-				client->dev,
-				s_ctrl->sensordata->sensor_platform_info->
-				cam_vreg,
-				s_ctrl->sensordata->sensor_platform_info->
-				num_vreg,
-				s_ctrl->vreg_seq,
-				s_ctrl->num_vreg_seq,
-				s_ctrl->reg_ptr, 0);
-			break;
-		case REQUEST_VREG:
-			msm_camera_config_vreg(&s_ctrl->sensor_i2c_client->
-				client->dev,
-				s_ctrl->sensordata->sensor_platform_info->
-				cam_vreg,
-				s_ctrl->sensordata->sensor_platform_info->
-				num_vreg,
-				s_ctrl->vreg_seq,
-				s_ctrl->num_vreg_seq,
-				s_ctrl->reg_ptr, 0);
-			break;
-		case REQUEST_GPIO:
-			msm_camera_request_gpio_table(data, 0);
-			break;
-		default:
-			pr_err("%s error power config %d\n", __func__,
-				power_seq[index].power_config);
-			break;
-		}
-	}
-	kfree(s_ctrl->reg_ptr);
-	return rc;
-}
-
-int32_t msm_sensor_bayer_power_down(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	int32_t size = 0, index = 0;
-	struct msm_camera_sensor_info *data = s_ctrl->sensordata;
-	struct msm_camera_power_seq_t *power_seq = NULL;
-	CDBG("%s\n", __func__);
-
-	if (s_ctrl->power_seq) {
-		power_seq = s_ctrl->power_seq;
-		size = s_ctrl->num_power_seq;
-	} else {
-		power_seq = &sensor_power_seq[0];
-		size = ARRAY_SIZE(sensor_power_seq);
-	}
-
-	for (index = (size - 1); index >= 0; index--) {
-		switch (power_seq[index].power_config) {
-		case CONFIG_I2C_MUX:
-			if (data->sensor_platform_info->i2c_conf &&
-				data->sensor_platform_info->i2c_conf->
-				use_i2c_mux)
-				msm_sensor_bayer_disable_i2c_mux(
-					data->sensor_platform_info->i2c_conf);
-			break;
-		case CONFIG_EXT_POWER_CTRL:
-			if (data->sensor_platform_info->ext_power_ctrl != NULL)
-				data->sensor_platform_info->ext_power_ctrl(0);
-			break;
-		case CONFIG_CLK:
-			msm_cam_clk_enable(&s_ctrl->sensor_i2c_client->client->
-				dev, cam_clk_info, s_ctrl->cam_clk,
-				ARRAY_SIZE(cam_clk_info), 0);
-			break;
-		case ENABLE_GPIO:
-			msm_camera_config_gpio_table(data, 0);
-			break;
-		case ENABLE_VREG:
-			msm_camera_enable_vreg(&s_ctrl->sensor_i2c_client->
-				client->dev,
-				s_ctrl->sensordata->sensor_platform_info->
-				cam_vreg,
-				s_ctrl->sensordata->sensor_platform_info->
-				num_vreg,
-				s_ctrl->vreg_seq,
-				s_ctrl->num_vreg_seq,
-				s_ctrl->reg_ptr, 0);
-			break;
-		case REQUEST_VREG:
-			msm_camera_config_vreg(&s_ctrl->sensor_i2c_client->
-				client->dev,
-				s_ctrl->sensordata->sensor_platform_info->
-				cam_vreg,
-				s_ctrl->sensordata->sensor_platform_info->
-				num_vreg,
-				s_ctrl->vreg_seq,
-				s_ctrl->num_vreg_seq,
-				s_ctrl->reg_ptr, 0);
-			break;
-		case REQUEST_GPIO:
-			msm_camera_request_gpio_table(data, 0);
-			break;
-		default:
-			pr_err("%s error power config %d\n", __func__,
-				power_seq[index].power_config);
-			break;
-		}
-	}
-	kfree(s_ctrl->reg_ptr);
-	return 0;
-}
-
-int32_t msm_sensor_bayer_match_id(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	int32_t rc = 0;
-	uint16_t chipid = 0;
-	rc = msm_camera_i2c_read(
-			s_ctrl->sensor_i2c_client,
-			s_ctrl->sensor_id_info->sensor_id_reg_addr, &chipid,
-			MSM_CAMERA_I2C_WORD_DATA);
-	if (rc < 0) {
-		pr_err("%s: %s: read id failed\n", __func__,
-			s_ctrl->sensordata->sensor_name);
-		return rc;
-	}
-
-	CDBG("%s: read id: %x expected id %x:\n", __func__, chipid,
-		s_ctrl->sensor_id_info->sensor_id);
-	if (chipid != s_ctrl->sensor_id_info->sensor_id) {
-		pr_err("msm_sensor_match_id chip id doesnot match\n");
-		return -ENODEV;
-	}
-	return rc;
-}
-
-int32_t msm_sensor_bayer_eeprom_read(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	uint32_t reg_addr = 0;
-	uint8_t *data = s_ctrl->eeprom_data.data;
-	uint32_t num_byte = 0;
-	int rc = 0;
-	uint32_t i2c_addr;
-	struct msm_camera_sensor_info *sensor_info = s_ctrl->sensordata;
-	i2c_addr = sensor_info->eeprom_info->eeprom_i2c_slave_addr;
-	num_byte = s_ctrl->eeprom_data.length = sensor_info->eeprom_info->
-		eeprom_read_length;
-	reg_addr = sensor_info->eeprom_info->eeprom_reg_addr;
-
-	data = kzalloc(num_byte * sizeof(uint8_t), GFP_KERNEL);
-	if (!data) {
-		pr_err("%s:%d failed\n", __func__, __LINE__);
-		rc = -EFAULT;
-		return rc;
-	}
-
-	s_ctrl->sensor_i2c_client->client->addr = i2c_addr;
-	CDBG("eeprom read: i2c addr is %x num byte %d  reg addr %x\n",
-		i2c_addr, num_byte, reg_addr);
-	rc = msm_camera_i2c_read_seq(s_ctrl->sensor_i2c_client, reg_addr, data,
-		num_byte);
-	s_ctrl->sensor_i2c_client->client->addr = s_ctrl->sensor_i2c_addr;
-	return rc;
-}
-
-int32_t msm_sensor_bayer_i2c_probe(struct i2c_client *client,
-	const struct i2c_device_id *id)
-{
-	int rc = 0;
-	struct msm_sensor_ctrl_t *s_ctrl;
-	CDBG("%s %s_i2c_probe called\n", __func__, client->name);
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		pr_err("%s %s i2c_check_functionality failed\n",
-			__func__, client->name);
-		rc = -EFAULT;
-		return rc;
-	}
-
-	s_ctrl = (struct msm_sensor_ctrl_t *)(id->driver_data);
-	if (s_ctrl->sensor_i2c_client != NULL) {
-		s_ctrl->sensor_i2c_client->client = client;
-		if (s_ctrl->sensor_i2c_addr != 0)
-			s_ctrl->sensor_i2c_client->client->addr =
-				s_ctrl->sensor_i2c_addr;
-	} else {
-		pr_err("%s %s sensor_i2c_client NULL\n",
-			__func__, client->name);
-		rc = -EFAULT;
-		return rc;
-	}
-
-	s_ctrl->sensordata = client->dev.platform_data;
-	if (s_ctrl->sensordata == NULL) {
-		pr_err("%s %s NULL sensor data\n", __func__, client->name);
-		return -EFAULT;
-	}
-
-	rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
-	if (rc < 0) {
-		pr_err("%s %s power up failed\n", __func__, client->name);
-		return rc;
-	}
-
-	if (s_ctrl->func_tbl->sensor_match_id)
-		rc = s_ctrl->func_tbl->sensor_match_id(s_ctrl);
-	else
-		rc = msm_sensor_bayer_match_id(s_ctrl);
-	if (rc < 0)
-		goto probe_fail;
-
-	if (!s_ctrl->wait_num_frames)
-		s_ctrl->wait_num_frames = 1;
-
-	pr_err("%s %s probe succeeded\n", __func__, client->name);
-	snprintf(s_ctrl->sensor_v4l2_subdev.name,
-		sizeof(s_ctrl->sensor_v4l2_subdev.name), "%s", id->name);
-	v4l2_i2c_subdev_init(&s_ctrl->sensor_v4l2_subdev, client,
-		s_ctrl->sensor_v4l2_subdev_ops);
-	s_ctrl->sensor_v4l2_subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-	media_entity_init(&s_ctrl->sensor_v4l2_subdev.entity, 0, NULL, 0);
-	s_ctrl->sensor_v4l2_subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
-	s_ctrl->sensor_v4l2_subdev.entity.group_id = SENSOR_DEV;
-	s_ctrl->sensor_v4l2_subdev.entity.name =
-		s_ctrl->sensor_v4l2_subdev.name;
-	msm_sensor_register(&s_ctrl->sensor_v4l2_subdev);
-	s_ctrl->sensor_v4l2_subdev.entity.revision =
-		s_ctrl->sensor_v4l2_subdev.devnode->num;
-	if (s_ctrl->func_tbl->sensor_read_eeprom != NULL)
-		s_ctrl->func_tbl->sensor_read_eeprom(s_ctrl);
-	else
-		msm_sensor_bayer_eeprom_read(s_ctrl);
-	goto power_down;
-probe_fail:
-	pr_err("%s %s_i2c_probe failed\n", __func__, client->name);
-power_down:
-	if (rc > 0)
-		rc = 0;
-	s_ctrl->func_tbl->sensor_power_down(s_ctrl);
-	return rc;
-}
-
-int32_t msm_sensor_delay_i2c_probe(struct i2c_client *client,
-	const struct i2c_device_id *id)
-{
-	int rc = 0;
-	struct msm_sensor_ctrl_t *s_ctrl;
-	CDBG("%s %s_delay_i2c_probe called\n", __func__, client->name);
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		pr_err("%s %s i2c_check_functionality failed\n",
-			__func__, client->name);
-		rc = -EFAULT;
-		return rc;
-	}
-
-	s_ctrl = (struct msm_sensor_ctrl_t *)(id->driver_data);
-	if (s_ctrl->sensor_i2c_client != NULL) {
-		s_ctrl->sensor_i2c_client->client = client;
-		if (s_ctrl->sensor_i2c_addr != 0)
-			s_ctrl->sensor_i2c_client->client->addr =
-				s_ctrl->sensor_i2c_addr;
-	} else {
-		pr_err("%s %s sensor_i2c_client NULL\n",
-			__func__, client->name);
-		rc = -EFAULT;
-		return rc;
-	}
-
-	s_ctrl->sensordata = client->dev.platform_data;
-	if (s_ctrl->sensordata == NULL) {
-		pr_err("%s %s NULL sensor data\n", __func__, client->name);
-		return -EFAULT;
-	}
-
-	if (!s_ctrl->wait_num_frames)
-		s_ctrl->wait_num_frames = 1;
-
-	pr_err("%s %s probe succeeded\n", __func__, client->name);
-	snprintf(s_ctrl->sensor_v4l2_subdev.name,
-		sizeof(s_ctrl->sensor_v4l2_subdev.name), "%s", id->name);
-	v4l2_i2c_subdev_init(&s_ctrl->sensor_v4l2_subdev, client,
-		s_ctrl->sensor_v4l2_subdev_ops);
-	s_ctrl->sensor_v4l2_subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-	media_entity_init(&s_ctrl->sensor_v4l2_subdev.entity, 0, NULL, 0);
-	s_ctrl->sensor_v4l2_subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
-	s_ctrl->sensor_v4l2_subdev.entity.group_id = SENSOR_DEV;
-	s_ctrl->sensor_v4l2_subdev.entity.name =
-		s_ctrl->sensor_v4l2_subdev.name;
-	msm_sensor_register(&s_ctrl->sensor_v4l2_subdev);
-	s_ctrl->sensor_v4l2_subdev.entity.revision =
-		s_ctrl->sensor_v4l2_subdev.devnode->num;
-	if (rc > 0)
-		rc = 0;
-	return rc;
-}
-
-int32_t msm_sensor_bayer_power(struct v4l2_subdev *sd, int on)
-{
-	int rc = 0;
-	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
-	mutex_lock(s_ctrl->msm_sensor_mutex);
-	if (!on)
-		rc = s_ctrl->func_tbl->sensor_power_down(s_ctrl);
-	mutex_unlock(s_ctrl->msm_sensor_mutex);
-	return rc;
-}
-
-int32_t msm_sensor_bayer_v4l2_enum_fmt(struct v4l2_subdev *sd,
-	unsigned int index, enum v4l2_mbus_pixelcode *code)
-{
-	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
-
-	if ((unsigned int)index >= s_ctrl->sensor_v4l2_subdev_info_size)
-		return -EINVAL;
-
-	*code = s_ctrl->sensor_v4l2_subdev_info[index].code;
-	return 0;
-}
-
-int32_t msm_sensor_bayer_v4l2_s_ctrl(struct v4l2_subdev *sd,
-	struct v4l2_control *ctrl)
-{
-	int rc = -1, i = 0;
-	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
-	struct msm_sensor_v4l2_ctrl_info_t *v4l2_ctrl =
-		s_ctrl->msm_sensor_v4l2_ctrl_info;
-
-	CDBG("%s\n", __func__);
-	CDBG("%d\n", ctrl->id);
-	if (v4l2_ctrl == NULL)
-		return rc;
-	for (i = 0; i < s_ctrl->num_v4l2_ctrl; i++) {
-		if (v4l2_ctrl[i].ctrl_id == ctrl->id) {
-			if (v4l2_ctrl[i].s_v4l2_ctrl != NULL) {
-				CDBG("\n calling msm_sensor_s_ctrl_by_enum\n");
-				rc = v4l2_ctrl[i].s_v4l2_ctrl(
-					s_ctrl,
-					&s_ctrl->msm_sensor_v4l2_ctrl_info[i],
-					ctrl->value);
-			}
-			break;
-		}
-	}
-
-	return rc;
-}
-
-int32_t msm_sensor_bayer_v4l2_query_ctrl(
-	struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl)
-{
-	int rc = -1, i = 0;
-	struct msm_sensor_ctrl_t *s_ctrl =
-		(struct msm_sensor_ctrl_t *) sd->dev_priv;
-
-	CDBG("%s\n", __func__);
-	CDBG("%s id: %d\n", __func__, qctrl->id);
-
-	if (s_ctrl->msm_sensor_v4l2_ctrl_info == NULL)
-		return rc;
-
-	for (i = 0; i < s_ctrl->num_v4l2_ctrl; i++) {
-		if (s_ctrl->msm_sensor_v4l2_ctrl_info[i].ctrl_id == qctrl->id) {
-			qctrl->minimum =
-				s_ctrl->msm_sensor_v4l2_ctrl_info[i].min;
-			qctrl->maximum =
-				s_ctrl->msm_sensor_v4l2_ctrl_info[i].max;
-			qctrl->flags = 1;
-			rc = 0;
-			break;
-		}
-	}
-
-	return rc;
-}
-
-int msm_sensor_bayer_s_ctrl_by_enum(struct msm_sensor_ctrl_t *s_ctrl,
-		struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value)
-{
-	int rc = 0;
-	CDBG("%s enter\n", __func__);
-	rc = msm_sensor_write_enum_conf_array(
-		s_ctrl->sensor_i2c_client,
-		ctrl_info->enum_cfg_settings, value);
-	return rc;
-}
-
diff --git a/drivers/media/video/msm/sensors/msm_sensor_bayer.h b/drivers/media/video/msm/sensors/msm_sensor_bayer.h
deleted file mode 100644
index 34e654b..0000000
--- a/drivers/media/video/msm/sensors/msm_sensor_bayer.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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 MSM_SENSOR_BAYER_H
-#define MSM_SENSOR_BAYER_H
-
-#include <linux/debugfs.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/miscdevice.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/uaccess.h>
-#include <mach/camera.h>
-#include <mach/gpio.h>
-#include <media/msm_camera.h>
-#include <media/v4l2-subdev.h>
-#include "msm_camera_i2c.h"
-#include "msm_camera_eeprom.h"
-#include "msm_sensor_common.h"
-
-struct sensor_driver_t {
-	struct platform_driver *platform_pdriver;
-	int32_t (*platform_probe)(struct platform_device *pdev);
-};
-
-int32_t msm_sensor_bayer_config(struct msm_sensor_ctrl_t *s_ctrl,
-			void __user *argp);
-int32_t msm_sensor_bayer_power_up(struct msm_sensor_ctrl_t *s_ctrl);
-int32_t msm_sensor_bayer_power_down(struct msm_sensor_ctrl_t *s_ctrl);
-
-int32_t msm_sensor_bayer_match_id(struct msm_sensor_ctrl_t *s_ctrl);
-int msm_sensor_bayer_i2c_probe(struct i2c_client *client,
-	const struct i2c_device_id *id);
-int32_t msm_sensor_delay_i2c_probe(struct i2c_client *client,
-	const struct i2c_device_id *id);
-int32_t msm_sensor_bayer_power(struct v4l2_subdev *sd, int on);
-
-int32_t msm_sensor_bayer_v4l2_s_ctrl(struct v4l2_subdev *sd,
-	struct v4l2_control *ctrl);
-
-int32_t msm_sensor_bayer_v4l2_query_ctrl(
-	struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl);
-
-int msm_sensor_bayer_s_ctrl_by_enum(struct msm_sensor_ctrl_t *s_ctrl,
-		struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value);
-
-int msm_sensor_bayer_v4l2_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
-			enum v4l2_mbus_pixelcode *code);
-
-long msm_sensor_bayer_subdev_ioctl(struct v4l2_subdev *sd,
-			unsigned int cmd, void *arg);
-
-int32_t msm_sensor_bayer_get_csi_params(struct msm_sensor_ctrl_t *s_ctrl,
-		struct csi_lane_params_t *sensor_output_info);
-
-int32_t msm_sensor_bayer_eeprom_read(struct msm_sensor_ctrl_t *s_ctrl);
-
-#define VIDIOC_MSM_SENSOR_CFG \
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 4, void __user *)
-
-#define VIDIOC_MSM_SENSOR_RELEASE \
-	_IO('V', BASE_VIDIOC_PRIVATE + 11)
-
-#define VIDIOC_MSM_SENSOR_CSID_INFO\
-	_IOWR('V', BASE_VIDIOC_PRIVATE + 12, struct msm_sensor_csi_info *)
-#endif
diff --git a/drivers/media/video/msm/sensors/msm_sensor_common.c b/drivers/media/video/msm/sensors/msm_sensor_common.c
deleted file mode 100644
index 9dac632..0000000
--- a/drivers/media/video/msm/sensors/msm_sensor_common.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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 "msm_sensor_common.h"
-
-struct msm_sensor_ctrl_t *get_sctrl(struct v4l2_subdev *sd)
-{
-	return container_of(sd, struct msm_sensor_ctrl_t, sensor_v4l2_subdev);
-}
diff --git a/drivers/media/video/msm/sensors/msm_sensor_common.h b/drivers/media/video/msm/sensors/msm_sensor_common.h
deleted file mode 100644
index 1f34a0f..0000000
--- a/drivers/media/video/msm/sensors/msm_sensor_common.h
+++ /dev/null
@@ -1,227 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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 MSM_SENSOR_COMMON_H
-#define MSM_SENSOR_COMMON_H
-
-#include <linux/debugfs.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/miscdevice.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/uaccess.h>
-#include <linux/gpio.h>
-#include <linux/of_gpio.h>
-#include <mach/camera.h>
-#include <media/msm_camera.h>
-#include <media/v4l2-subdev.h>
-#include "msm_camera_i2c.h"
-#include "msm_camera_eeprom.h"
-#define Q8  0x00000100
-#define Q10 0x00000400
-
-#define MSM_SENSOR_MCLK_8HZ 8000000
-#define MSM_SENSOR_MCLK_16HZ 16000000
-#define MSM_SENSOR_MCLK_24HZ 24000000
-
-#define DEFINE_MSM_MUTEX(mutexname) \
-	static struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
-
-struct gpio_tlmm_cfg {
-	uint32_t gpio;
-	uint32_t dir;
-	uint32_t pull;
-	uint32_t drvstr;
-};
-
-enum msm_sensor_reg_update {
-	/* Sensor egisters that need to be updated during initialization */
-	MSM_SENSOR_REG_INIT,
-	/* Sensor egisters that needs periodic I2C writes */
-	MSM_SENSOR_UPDATE_PERIODIC,
-	/* All the sensor Registers will be updated */
-	MSM_SENSOR_UPDATE_ALL,
-	/* Not valid update */
-	MSM_SENSOR_UPDATE_INVALID
-};
-
-enum msm_sensor_cam_mode_t {
-	MSM_SENSOR_MODE_2D_RIGHT,
-	MSM_SENSOR_MODE_2D_LEFT,
-	MSM_SENSOR_MODE_3D,
-	MSM_SENSOR_MODE_INVALID
-};
-
-enum msm_camera_power_config_t {
-	REQUEST_GPIO,
-	ENABLE_GPIO,
-	REQUEST_VREG,
-	ENABLE_VREG,
-	CONFIG_CLK,
-	CONFIG_EXT_POWER_CTRL,
-	CONFIG_I2C_MUX,
-};
-
-struct msm_camera_power_seq_t {
-	enum msm_camera_power_config_t power_config;
-	uint32_t delay;
-};
-
-struct msm_sensor_id_info_t {
-	uint16_t sensor_id_reg_addr;
-	uint16_t sensor_id;
-};
-
-struct msm_sensor_reg_t {
-	enum msm_camera_i2c_data_type default_data_type;
-	struct msm_camera_i2c_reg_conf *start_stream_conf;
-	uint8_t start_stream_conf_size;
-	struct msm_camera_i2c_reg_conf *stop_stream_conf;
-	uint8_t stop_stream_conf_size;
-	struct msm_camera_i2c_reg_conf *group_hold_on_conf;
-	uint8_t group_hold_on_conf_size;
-	struct msm_camera_i2c_reg_conf *group_hold_off_conf;
-	uint8_t group_hold_off_conf_size;
-	struct msm_camera_i2c_conf_array *init_settings;
-	uint8_t init_size;
-	struct msm_camera_i2c_conf_array *mode_settings;
-	struct msm_camera_i2c_conf_array *no_effect_settings;
-	struct msm_sensor_output_info_t *output_settings;
-	uint8_t num_conf;
-};
-
-enum msm_sensor_device_type_t {
-	MSM_SENSOR_I2C_DEVICE,
-	MSM_SENSOR_PLATFORM_DEVICE,
-};
-
-struct v4l2_subdev_info {
-	enum v4l2_mbus_pixelcode code;
-	enum v4l2_colorspace colorspace;
-	uint16_t fmt;
-	uint16_t order;
-};
-
-struct msm_sensor_ctrl_t;
-
-struct msm_sensor_v4l2_ctrl_info_t {
-	uint32_t ctrl_id;
-	int16_t min;
-	int16_t max;
-	int16_t step;
-	struct msm_camera_i2c_enum_conf_array *enum_cfg_settings;
-	int (*s_v4l2_ctrl) (struct msm_sensor_ctrl_t *,
-		struct msm_sensor_v4l2_ctrl_info_t *, int);
-};
-
-struct msm_sensor_fn_t {
-	void (*sensor_start_stream) (struct msm_sensor_ctrl_t *);
-	void (*sensor_stop_stream) (struct msm_sensor_ctrl_t *);
-	void (*sensor_group_hold_on) (struct msm_sensor_ctrl_t *);
-	void (*sensor_group_hold_off) (struct msm_sensor_ctrl_t *);
-
-	int32_t (*sensor_set_fps) (struct msm_sensor_ctrl_t *,
-			struct fps_cfg *);
-	int32_t (*sensor_write_exp_gain) (struct msm_sensor_ctrl_t *,
-			uint16_t, uint32_t);
-	int32_t (*sensor_write_snapshot_exp_gain) (struct msm_sensor_ctrl_t *,
-			uint16_t, uint32_t);
-	int32_t (*sensor_setting) (struct msm_sensor_ctrl_t *,
-			int update_type, int rt);
-	int32_t (*sensor_csi_setting) (struct msm_sensor_ctrl_t *,
-			int update_type, int rt);
-	int32_t (*sensor_set_sensor_mode)
-			(struct msm_sensor_ctrl_t *, int, int);
-	int32_t (*sensor_mode_init) (struct msm_sensor_ctrl_t *,
-		int, struct sensor_init_cfg *);
-	int32_t (*sensor_get_output_info) (struct msm_sensor_ctrl_t *,
-		struct sensor_output_info_t *);
-	int (*sensor_config) (struct msm_sensor_ctrl_t *, void __user *);
-	int (*sensor_power_down)
-		(struct msm_sensor_ctrl_t *);
-	int (*sensor_power_up) (struct msm_sensor_ctrl_t *);
-	int32_t (*sensor_match_id)(struct msm_sensor_ctrl_t *s_ctrl);
-	void (*sensor_adjust_frame_lines) (struct msm_sensor_ctrl_t *s_ctrl);
-	int32_t (*sensor_get_csi_params)(struct msm_sensor_ctrl_t *,
-		struct csi_lane_params_t *);
-	int32_t (*sensor_read_eeprom)(struct msm_sensor_ctrl_t *);
-};
-
-struct msm_sensor_csi_info {
-	uint8_t is_csic;
-};
-
-enum msm_sensor_state {
-	MSM_SENSOR_POWER_UP,
-	MSM_SENSOR_POWER_DOWN,
-};
-
-struct msm_sensor_eeprom_data {
-	uint8_t *data;
-	uint32_t length;
-};
-
-struct msm_sensor_ctrl_t {
-	struct  msm_camera_sensor_info *sensordata;
-	struct i2c_client *msm_sensor_client;
-	struct i2c_driver *sensor_i2c_driver;
-	struct platform_device *pdev;
-	struct msm_camera_i2c_client *sensor_i2c_client;
-	uint16_t sensor_i2c_addr;
-	enum msm_camera_vreg_name_t *vreg_seq;
-	int num_vreg_seq;
-	struct msm_camera_power_seq_t *power_seq;
-	int num_power_seq;
-	enum msm_sensor_device_type_t sensor_device_type;
-
-	struct msm_sensor_output_reg_addr_t *sensor_output_reg_addr;
-	struct msm_sensor_id_info_t *sensor_id_info;
-	struct msm_sensor_exp_gain_info_t *sensor_exp_gain_info;
-	struct msm_sensor_reg_t *msm_sensor_reg;
-	struct msm_sensor_v4l2_ctrl_info_t *msm_sensor_v4l2_ctrl_info;
-	uint16_t num_v4l2_ctrl;
-	uint8_t is_csic;
-
-	uint16_t curr_line_length_pclk;
-	uint16_t curr_frame_length_lines;
-
-	uint32_t fps_divider;
-	enum msm_sensor_resolution_t curr_res;
-	enum msm_sensor_cam_mode_t cam_mode;
-
-	struct mutex *msm_sensor_mutex;
-
-	struct v4l2_subdev sensor_v4l2_subdev;
-	struct v4l2_subdev_info *sensor_v4l2_subdev_info;
-	uint8_t sensor_v4l2_subdev_info_size;
-	struct v4l2_subdev_ops *sensor_v4l2_subdev_ops;
-	struct msm_sensor_fn_t *func_tbl;
-	struct regulator **reg_ptr;
-	struct clk *cam_clk[2];
-	long clk_rate;
-	enum msm_sensor_state sensor_state;
-	/* Number of frames to delay after start / stop stream in Q10 format.
-	   Initialize to -1 for this value to be ignored */
-	int16_t wait_num_frames;
-	/* minimum delay after stop / stop stream in ms */
-	uint16_t min_delay;
-	/* delay (in ms) after power up sequence */
-	uint16_t power_seq_delay;
-	struct msm_sensor_eeprom_data eeprom_data;
-};
-
-struct msm_sensor_ctrl_t *get_sctrl(struct v4l2_subdev *sd);
-
-#endif
diff --git a/drivers/media/video/msm/sensors/msm_sensor_init.c b/drivers/media/video/msm/sensors/msm_sensor_init.c
deleted file mode 100644
index 41c00eb..0000000
--- a/drivers/media/video/msm/sensors/msm_sensor_init.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 "msm_sensor.h"
-#include "msm.h"
-#include "msm_sensor_bayer.h"
-#include "imx091.h"
-
-static struct i2c_driver *sensor_i2c_driver[] = {
-	/* back camera */
-	&imx091_i2c_driver,
-	/* front camera */
-};
-
-static int __init msm_sensor_init_module(void)
-{
-	int index = 0;
-	for (index = 0; index < ARRAY_SIZE(sensor_i2c_driver); index++)
-		i2c_add_driver(sensor_i2c_driver[index]);
-	return 0;
-}
-
-module_init(msm_sensor_init_module);
-MODULE_DESCRIPTION("Sensor driver probe");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/sensors/mt9e013_v4l2.c b/drivers/media/video/msm/sensors/mt9e013_v4l2.c
deleted file mode 100644
index a38cb57..0000000
--- a/drivers/media/video/msm/sensors/mt9e013_v4l2.c
+++ /dev/null
@@ -1,496 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 "msm_sensor.h"
-#define SENSOR_NAME "mt9e013"
-#define PLATFORM_DRIVER_NAME "msm_camera_mt9e013"
-#define mt9e013_obj mt9e013_##obj
-
-DEFINE_MUTEX(mt9e013_mut);
-static struct msm_sensor_ctrl_t mt9e013_s_ctrl;
-
-static struct msm_camera_i2c_reg_conf mt9e013_groupon_settings[] = {
-	{0x0104, 0x01},
-};
-
-static struct msm_camera_i2c_reg_conf mt9e013_groupoff_settings[] = {
-	{0x0104, 0x00},
-};
-
-static struct msm_camera_i2c_reg_conf mt9e013_prev_settings[] = {
-	/*Output Size (1632x1224)*/
-	{0x0344, 0x0008},/*X_ADDR_START*/
-	{0x0348, 0x0CC9},/*X_ADDR_END*/
-	{0x0346, 0x0008},/*Y_ADDR_START*/
-	{0x034A, 0x0999},/*Y_ADDR_END*/
-	{0x034C, 0x0660},/*X_OUTPUT_SIZE*/
-	{0x034E, 0x04C8},/*Y_OUTPUT_SIZE*/
-	{0x306E, 0xFCB0},/*DATAPATH_SELECT*/
-	{0x3040, 0x04C3},/*READ_MODE*/
-	{0x3178, 0x0000},/*ANALOG_CONTROL5*/
-	{0x3ED0, 0x1E24},/*DAC_LD_4_5*/
-	{0x0400, 0x0002},/*SCALING_MODE*/
-	{0x0404, 0x0010},/*SCALE_M*/
-	/*Timing configuration*/
-	{0x0342, 0x1018},/*LINE_LENGTH_PCK*/
-	{0x0340, 0x055B},/*FRAME_LENGTH_LINES*/
-	{0x0202, 0x0557},/*COARSE_INTEGRATION_TIME*/
-	{0x3014, 0x0846},/*FINE_INTEGRATION_TIME_*/
-	{0x3010, 0x0130},/*FINE_CORRECTION*/
-};
-
-static struct msm_camera_i2c_reg_conf mt9e013_snap_settings[] = {
-	/*Output Size (3264x2448)*/
-	{0x0344, 0x0000},/*X_ADDR_START */
-	{0x0348, 0x0CCF},/*X_ADDR_END*/
-	{0x0346, 0x0000},/*Y_ADDR_START */
-	{0x034A, 0x099F},/*Y_ADDR_END*/
-	{0x034C, 0x0CD0},/*X_OUTPUT_SIZE*/
-	{0x034E, 0x09A0},/*Y_OUTPUT_SIZE*/
-	{0x306E, 0xFC80},/*DATAPATH_SELECT*/
-	{0x3040, 0x0041},/*READ_MODE*/
-	{0x3178, 0x0000},/*ANALOG_CONTROL5*/
-	{0x3ED0, 0x1E24},/*DAC_LD_4_5*/
-	{0x0400, 0x0000},/*SCALING_MODE*/
-	{0x0404, 0x0010},/*SCALE_M*/
-	/*Timing configuration*/
-	{0x0342, 0x13F8},/*LINE_LENGTH_PCK*/
-	{0x0340, 0x0A2F},/*FRAME_LENGTH_LINES*/
-	{0x0202, 0x0A1F},/*COARSE_INTEGRATION_TIME*/
-	{0x3014, 0x03F6},/*FINE_INTEGRATION_TIME_ */
-	{0x3010, 0x0078},/*FINE_CORRECTION*/
-};
-
-static struct msm_camera_i2c_reg_conf mt9e013_hfr60_settings[] = {
-	{0x0300, 0x0005},/*VT_PIX_CLK_DIV*/
-	{0x0302, 0x0001},/*VT_SYS_CLK_DIV*/
-	{0x0304, 0x0002},/*PRE_PLL_CLK_DIV*/
-	{0x0306, 0x0029},/*PLL_MULTIPLIER*/
-	{0x0308, 0x000A},/*OP_PIX_CLK_DIV*/
-	{0x030A, 0x0001},/*OP_SYS_CLK_DIV*/
-	{0x0344, 0x0008},/*X_ADDR_START*/
-	{0x0348, 0x0685},/*X_ADDR_END*/
-	{0x0346, 0x013a},/*Y_ADDR_START*/
-	{0x034A, 0x055B},/*Y_ADDR_END*/
-	{0x034C, 0x0340},/*X_OUTPUT_SIZE*/
-	{0x034E, 0x0212},/*Y_OUTPUT_SIZE*/
-	{0x306E, 0xFC80},/*DATAPATH_SELECT*/
-	{0x3040, 0x00C3},/*READ_MODE*/
-	{0x3178, 0x0000},/*ANALOG_CONTROL5*/
-	{0x3ED0, 0x1E24},/*DAC_LD_4_5*/
-	{0x0400, 0x0000},/*SCALING_MODE*/
-	{0x0404, 0x0010},/*SCALE_M*/
-	/*Timing configuration*/
-	{0x0342, 0x0970},/*LINE_LENGTH_PCK*/
-	{0x0340, 0x02A1},/*FRAME_LENGTH_LINES*/
-	{0x0202, 0x02A1},/*COARSE_INTEGRATION_TIME*/
-	{0x3014, 0x03F6},/*FINE_INTEGRATION_TIME_*/
-	{0x3010, 0x0078},/*FINE_CORRECTION*/
-};
-
-static struct msm_camera_i2c_reg_conf mt9e013_hfr90_settings[] = {
-	{0x0300, 0x0005},/*VT_PIX_CLK_DIV*/
-	{0x0302, 0x0001},/*VT_SYS_CLK_DIV*/
-	{0x0304, 0x0002},/*PRE_PLL_CLK_DIV*/
-	{0x0306, 0x003D},/*PLL_MULTIPLIER*/
-	{0x0308, 0x000A},/*OP_PIX_CLK_DIV*/
-	{0x030A, 0x0001},/*OP_SYS_CLK_DIV*/
-	{0x0344, 0x0008},/*X_ADDR_START*/
-	{0x0348, 0x0685},/*X_ADDR_END*/
-	{0x0346, 0x013a},/*Y_ADDR_START*/
-	{0x034A, 0x055B},/*Y_ADDR_END*/
-	{0x034C, 0x0340},/*X_OUTPUT_SIZE*/
-	{0x034E, 0x0212},/*Y_OUTPUT_SIZE*/
-	{0x306E, 0xFC80},/*DATAPATH_SELECT*/
-	{0x3040, 0x00C3},/*READ_MODE*/
-	{0x3178, 0x0000},/*ANALOG_CONTROL5*/
-	{0x3ED0, 0x1E24},/*DAC_LD_4_5*/
-	{0x0400, 0x0000},/*SCALING_MODE*/
-	{0x0404, 0x0010},/*SCALE_M*/
-	/*Timing configuration*/
-	{0x0342, 0x0970},/*LINE_LENGTH_PCK*/
-	{0x0340, 0x02A1},/*FRAME_LENGTH_LINES*/
-	{0x0202, 0x02A1},/*COARSE_INTEGRATION_TIME*/
-	{0x3014, 0x03F6},/*FINE_INTEGRATION_TIME_*/
-	{0x3010, 0x0078},/*FINE_CORRECTION*/
-};
-
-static struct msm_camera_i2c_reg_conf mt9e013_hfr120_settings[] = {
-	{0x0300, 0x0005},/*VT_PIX_CLK_DIV*/
-	{0x0302, 0x0001},/*VT_SYS_CLK_DIV*/
-	{0x0304, 0x0002},/*PRE_PLL_CLK_DIV*/
-	{0x0306, 0x0052},/*PLL_MULTIPLIER*/
-	{0x0308, 0x000A},/*OP_PIX_CLK_DIV*/
-	{0x030A, 0x0001},/*OP_SYS_CLK_DIV*/
-	{0x0344, 0x0008},/*X_ADDR_START*/
-	{0x0348, 0x0685},/*X_ADDR_END*/
-	{0x0346, 0x013a},/*Y_ADDR_START*/
-	{0x034A, 0x055B},/*Y_ADDR_END*/
-	{0x034C, 0x0340},/*X_OUTPUT_SIZE*/
-	{0x034E, 0x0212},/*Y_OUTPUT_SIZE*/
-	{0x306E, 0xFC80},/*DATAPATH_SELECT*/
-	{0x3040, 0x00C3},/*READ_MODE*/
-	{0x3178, 0x0000},/*ANALOG_CONTROL5*/
-	{0x3ED0, 0x1E24},/*DAC_LD_4_5*/
-	{0x0400, 0x0000},/*SCALING_MODE*/
-	{0x0404, 0x0010},/*SCALE_M*/
-	/*Timing configuration*/
-	{0x0342, 0x0970},/*LINE_LENGTH_PCK*/
-	{0x0340, 0x02A1},/*FRAME_LENGTH_LINES*/
-	{0x0202, 0x02A1},/*COARSE_INTEGRATION_TIME*/
-	{0x3014, 0x03F6},/*FINE_INTEGRATION_TIME_*/
-	{0x3010, 0x0078},/*FINE_CORRECTION*/
-};
-
-static struct msm_camera_i2c_reg_conf mt9e013_recommend_settings[] = {
-	/*Disable embedded data*/
-	{0x3064, 0x7800},/*SMIA_TEST*/
-	/*configure 2-lane MIPI*/
-	{0x31AE, 0x0202},/*SERIAL_FORMAT*/
-	{0x31B8, 0x0E3F},/*MIPI_TIMING_2*/
-	/*set data to RAW10 format*/
-	{0x0112, 0x0A0A},/*CCP_DATA_FORMAT*/
-	{0x30F0, 0x800D},/*VCM CONTROL*/
-
-	{0x3044, 0x0590},
-	{0x306E, 0xFC80},
-	{0x30B2, 0xC000},
-	{0x30D6, 0x0800},
-	{0x316C, 0xB42F},
-	{0x316E, 0x869A},
-	{0x3170, 0x210E},
-	{0x317A, 0x010E},
-	{0x31E0, 0x1FB9},
-	{0x31E6, 0x07FC},
-	{0x37C0, 0x0000},
-	{0x37C2, 0x0000},
-	{0x37C4, 0x0000},
-	{0x37C6, 0x0000},
-	{0x3E00, 0x0011},
-	{0x3E02, 0x8801},
-	{0x3E04, 0x2801},
-	{0x3E06, 0x8449},
-	{0x3E08, 0x6841},
-	{0x3E0A, 0x400C},
-	{0x3E0C, 0x1001},
-	{0x3E0E, 0x2603},
-	{0x3E10, 0x4B41},
-	{0x3E12, 0x4B24},
-	{0x3E14, 0xA3CF},
-	{0x3E16, 0x8802},
-	{0x3E18, 0x8401},
-	{0x3E1A, 0x8601},
-	{0x3E1C, 0x8401},
-	{0x3E1E, 0x840A},
-	{0x3E20, 0xFF00},
-	{0x3E22, 0x8401},
-	{0x3E24, 0x00FF},
-	{0x3E26, 0x0088},
-	{0x3E28, 0x2E8A},
-	{0x3E30, 0x0000},
-	{0x3E32, 0x8801},
-	{0x3E34, 0x4029},
-	{0x3E36, 0x00FF},
-	{0x3E38, 0x8469},
-	{0x3E3A, 0x00FF},
-	{0x3E3C, 0x2801},
-	{0x3E3E, 0x3E2A},
-	{0x3E40, 0x1C01},
-	{0x3E42, 0xFF84},
-	{0x3E44, 0x8401},
-	{0x3E46, 0x0C01},
-	{0x3E48, 0x8401},
-	{0x3E4A, 0x00FF},
-	{0x3E4C, 0x8402},
-	{0x3E4E, 0x8984},
-	{0x3E50, 0x6628},
-	{0x3E52, 0x8340},
-	{0x3E54, 0x00FF},
-	{0x3E56, 0x4A42},
-	{0x3E58, 0x2703},
-	{0x3E5A, 0x6752},
-	{0x3E5C, 0x3F2A},
-	{0x3E5E, 0x846A},
-	{0x3E60, 0x4C01},
-	{0x3E62, 0x8401},
-	{0x3E66, 0x3901},
-	{0x3E90, 0x2C01},
-	{0x3E98, 0x2B02},
-	{0x3E92, 0x2A04},
-	{0x3E94, 0x2509},
-	{0x3E96, 0x0000},
-	{0x3E9A, 0x2905},
-	{0x3E9C, 0x00FF},
-	{0x3ECC, 0x00EB},
-	{0x3ED0, 0x1E24},
-	{0x3ED4, 0xAFC4},
-	{0x3ED6, 0x909B},
-	{0x3EE0, 0x2424},
-	{0x3EE2, 0x9797},
-	{0x3EE4, 0xC100},
-	{0x3EE6, 0x0540},
-	{0x3174, 0x8000},
-	/* PLL settings */
-	{0x0300, 0x0004},/*VT_PIX_CLK_DIV*/
-	{0x0302, 0x0001},/*VT_SYS_CLK_DIV*/
-	{0x0304, 0x0002},/*PRE_PLL_CLK_DIV*/
-	{0x0306, 0x003A},/*PLL_MULTIPLIER*/
-	{0x0308, 0x000A},/*OP_PIX_CLK_DIV*/
-	{0x030A, 0x0001},/*OP_SYS_CLK_DIV*/
-};
-
-static struct v4l2_subdev_info mt9e013_subdev_info[] = {
-	{
-	.code   = V4L2_MBUS_FMT_SBGGR10_1X10,
-	.colorspace = V4L2_COLORSPACE_JPEG,
-	.fmt    = 1,
-	.order    = 0,
-	},
-	/* more can be supported, to be added later */
-};
-
-static struct msm_camera_i2c_conf_array mt9e013_init_conf[] = {
-	{&mt9e013_recommend_settings[0],
-	ARRAY_SIZE(mt9e013_recommend_settings), 0, MSM_CAMERA_I2C_WORD_DATA}
-};
-
-static struct msm_camera_i2c_conf_array mt9e013_confs[] = {
-	{&mt9e013_snap_settings[0],
-	ARRAY_SIZE(mt9e013_snap_settings), 0, MSM_CAMERA_I2C_WORD_DATA},
-	{&mt9e013_prev_settings[0],
-	ARRAY_SIZE(mt9e013_prev_settings), 0, MSM_CAMERA_I2C_WORD_DATA},
-	{&mt9e013_hfr60_settings[0],
-	ARRAY_SIZE(mt9e013_hfr60_settings), 0, MSM_CAMERA_I2C_WORD_DATA},
-	{&mt9e013_hfr90_settings[0],
-	ARRAY_SIZE(mt9e013_hfr90_settings), 0, MSM_CAMERA_I2C_WORD_DATA},
-	{&mt9e013_hfr120_settings[0],
-	ARRAY_SIZE(mt9e013_hfr120_settings), 0, MSM_CAMERA_I2C_WORD_DATA},
-};
-
-static struct msm_sensor_output_info_t mt9e013_dimensions[] = {
-	{
-		.x_output = 0xCD0,
-		.y_output = 0x9A0,
-		.line_length_pclk = 0x13F8,
-		.frame_length_lines = 0xA2F,
-		.vt_pixel_clk = 174000000,
-		.op_pixel_clk = 174000000,
-		.binning_factor = 1,
-	},
-	{
-		.x_output = 0x660,
-		.y_output = 0x4C8,
-		.line_length_pclk = 0x1018,
-		.frame_length_lines = 0x55B,
-		.vt_pixel_clk = 174000000,
-		.op_pixel_clk = 174000000,
-		.binning_factor = 1,
-	},
-	{
-		.x_output = 0x340,
-		.y_output = 0x212,
-		.line_length_pclk = 0x970,
-		.frame_length_lines = 0x2A1,
-		.vt_pixel_clk = 98400000,
-		.op_pixel_clk = 98400000,
-		.binning_factor = 1,
-	},
-	{
-		.x_output = 0x340,
-		.y_output = 0x212,
-		.line_length_pclk = 0x970,
-		.frame_length_lines = 0x2A1,
-		.vt_pixel_clk = 146400000,
-		.op_pixel_clk = 146400000,
-		.binning_factor = 1,
-	},
-	{
-		.x_output = 0x340,
-		.y_output = 0x212,
-		.line_length_pclk = 0x970,
-		.frame_length_lines = 0x2A1,
-		.vt_pixel_clk = 196800000,
-		.op_pixel_clk = 196800000,
-		.binning_factor = 1,
-	},
-};
-
-static struct msm_sensor_output_reg_addr_t mt9e013_reg_addr = {
-	.x_output = 0x34C,
-	.y_output = 0x34E,
-	.line_length_pclk = 0x342,
-	.frame_length_lines = 0x340,
-};
-
-static struct msm_sensor_id_info_t mt9e013_id_info = {
-	.sensor_id_reg_addr = 0x0,
-	.sensor_id = 0x4B00,
-};
-
-static struct msm_sensor_exp_gain_info_t mt9e013_exp_gain_info = {
-	.coarse_int_time_addr = 0x202,
-	.global_gain_addr = 0x305E,
-	.vert_offset = 0,
-};
-
-static int32_t mt9e013_write_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
-		uint16_t gain, uint32_t line)
-{
-	uint32_t fl_lines;
-	fl_lines =
-		(s_ctrl->curr_frame_length_lines * s_ctrl->fps_divider) / Q10;
-
-	s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->global_gain_addr, gain | 0x1000,
-		MSM_CAMERA_I2C_WORD_DATA);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr, line,
-		MSM_CAMERA_I2C_WORD_DATA);
-	s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
-	return 0;
-}
-
-static int32_t mt9e013_write_exp_snapshot_gain(struct msm_sensor_ctrl_t *s_ctrl,
-		uint16_t gain, uint32_t line)
-{
-	uint32_t fl_lines;
-	fl_lines =
-		(s_ctrl->curr_frame_length_lines * s_ctrl->fps_divider) / Q10;
-
-	s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->global_gain_addr, gain | 0x1000,
-		MSM_CAMERA_I2C_WORD_DATA);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr, line,
-		MSM_CAMERA_I2C_WORD_DATA);
-	s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		0x301A, (0x065C|0x2), MSM_CAMERA_I2C_WORD_DATA);
-
-	return 0;
-}
-static void mt9e013_start_stream(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		0x301A, 0x8250, MSM_CAMERA_I2C_WORD_DATA);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		0x301A, 0x8650, MSM_CAMERA_I2C_WORD_DATA);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		0x301A, 0x8658, MSM_CAMERA_I2C_WORD_DATA);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		0x0104, 0x00, MSM_CAMERA_I2C_BYTE_DATA);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		0x301A, 0x065C, MSM_CAMERA_I2C_WORD_DATA);
-}
-
-static void mt9e013_stop_stream(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		0x301A, 0x0058, MSM_CAMERA_I2C_WORD_DATA);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		0x301A, 0x0050, MSM_CAMERA_I2C_WORD_DATA);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		0x0104, 0x01, MSM_CAMERA_I2C_BYTE_DATA);
-}
-
-static const struct i2c_device_id mt9e013_i2c_id[] = {
-	{SENSOR_NAME, (kernel_ulong_t)&mt9e013_s_ctrl},
-	{ }
-};
-
-static struct i2c_driver mt9e013_i2c_driver = {
-	.id_table = mt9e013_i2c_id,
-	.probe  = msm_sensor_i2c_probe,
-	.driver = {
-		.name = SENSOR_NAME,
-	},
-};
-
-static struct msm_camera_i2c_client mt9e013_sensor_i2c_client = {
-	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
-};
-
-static int __init msm_sensor_init_module(void)
-{
-	return i2c_add_driver(&mt9e013_i2c_driver);
-}
-
-static struct v4l2_subdev_core_ops mt9e013_subdev_core_ops = {
-	.ioctl = msm_sensor_subdev_ioctl,
-	.s_power = msm_sensor_power,
-};
-
-static struct v4l2_subdev_video_ops mt9e013_subdev_video_ops = {
-	.enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
-};
-
-static struct v4l2_subdev_ops mt9e013_subdev_ops = {
-	.core = &mt9e013_subdev_core_ops,
-	.video  = &mt9e013_subdev_video_ops,
-};
-
-static struct msm_sensor_fn_t mt9e013_func_tbl = {
-	.sensor_start_stream = mt9e013_start_stream,
-	.sensor_stop_stream = mt9e013_stop_stream,
-	.sensor_group_hold_on = msm_sensor_group_hold_on,
-	.sensor_group_hold_off = msm_sensor_group_hold_off,
-	.sensor_set_fps = msm_sensor_set_fps,
-	.sensor_write_exp_gain = mt9e013_write_exp_gain,
-	.sensor_write_snapshot_exp_gain = mt9e013_write_exp_snapshot_gain,
-	.sensor_csi_setting = msm_sensor_setting1,
-	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
-	.sensor_mode_init = msm_sensor_mode_init,
-	.sensor_get_output_info = msm_sensor_get_output_info,
-	.sensor_config = msm_sensor_config,
-	.sensor_power_up = msm_sensor_power_up,
-	.sensor_power_down = msm_sensor_power_down,
-};
-
-static struct msm_sensor_reg_t mt9e013_regs = {
-	.default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
-	.group_hold_on_conf = mt9e013_groupon_settings,
-	.group_hold_on_conf_size = ARRAY_SIZE(mt9e013_groupon_settings),
-	.group_hold_off_conf = mt9e013_groupoff_settings,
-	.group_hold_off_conf_size =
-		ARRAY_SIZE(mt9e013_groupoff_settings),
-	.init_settings = &mt9e013_init_conf[0],
-	.init_size = ARRAY_SIZE(mt9e013_init_conf),
-	.mode_settings = &mt9e013_confs[0],
-	.output_settings = &mt9e013_dimensions[0],
-	.num_conf = ARRAY_SIZE(mt9e013_confs),
-};
-
-static struct msm_sensor_ctrl_t mt9e013_s_ctrl = {
-	.msm_sensor_reg = &mt9e013_regs,
-	.sensor_i2c_client = &mt9e013_sensor_i2c_client,
-	.sensor_i2c_addr = 0x6C,
-	.sensor_output_reg_addr = &mt9e013_reg_addr,
-	.sensor_id_info = &mt9e013_id_info,
-	.sensor_exp_gain_info = &mt9e013_exp_gain_info,
-	.cam_mode = MSM_SENSOR_MODE_INVALID,
-	.msm_sensor_mutex = &mt9e013_mut,
-	.sensor_i2c_driver = &mt9e013_i2c_driver,
-	.sensor_v4l2_subdev_info = mt9e013_subdev_info,
-	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(mt9e013_subdev_info),
-	.sensor_v4l2_subdev_ops = &mt9e013_subdev_ops,
-	.func_tbl = &mt9e013_func_tbl,
-	.clk_rate = MSM_SENSOR_MCLK_24HZ,
-};
-
-module_init(msm_sensor_init_module);
-MODULE_DESCRIPTION("Aptina 8MP Bayer sensor driver");
-MODULE_LICENSE("GPL v2");
-
-
diff --git a/drivers/media/video/msm/sensors/ov2720.c b/drivers/media/video/msm/sensors/ov2720.c
deleted file mode 100644
index bc38f62..0000000
--- a/drivers/media/video/msm/sensors/ov2720.c
+++ /dev/null
@@ -1,856 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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 "msm_sensor.h"
-#include "ov2720.h"
-#define SENSOR_NAME "ov2720"
-#define PLATFORM_DRIVER_NAME "msm_camera_ov2720"
-#define ov2720_obj ov2720_##obj
-
-DEFINE_MUTEX(ov2720_mut);
-static struct msm_sensor_ctrl_t ov2720_s_ctrl;
-
-static struct msm_camera_i2c_reg_conf ov2720_start_settings[] = {
-	{0x0100, 0x01},
-};
-
-static struct msm_camera_i2c_reg_conf ov2720_stop_settings[] = {
-	{0x0100, 0x00},
-};
-
-static struct msm_camera_i2c_reg_conf ov2720_groupon_settings[] = {
-	{0x3208, 0x00},
-};
-
-static struct msm_camera_i2c_reg_conf ov2720_groupoff_settings[] = {
-	{0x3208, 0x10},
-	{0x3208, 0xA0},
-};
-
-static struct msm_camera_i2c_reg_conf ov2720_prev_settings[] = {
-	{0x3800, 0x00},
-	{0x3801, 0x02},
-	{0x3802, 0x00},
-	{0x3803, 0x00},
-	{0x3804, 0x07},
-	{0x3805, 0xA1},
-	{0x3806, 0x04},
-	{0x3807, 0x47},
-	{0x3810, 0x00},
-	{0x3811, 0x09},
-	{0x3812, 0x00},
-	{0x3813, 0x02},
-	{0x3820, 0x80},
-	{0x3821, 0x06},
-	{0x3814, 0x11},
-	{0x3815, 0x11},
-	{0x3612, 0x0b},
-	{0x3618, 0x04},
-	{0x3a08, 0x01},
-	{0x3a09, 0x50},
-	{0x3a0a, 0x01},
-	{0x3a0b, 0x18},
-	{0x3a0d, 0x03},
-	{0x3a0e, 0x03},
-	{0x4520, 0x00},
-	{0x4837, 0x1b},
-	{0x3000, 0xff},
-	{0x3001, 0xff},
-	{0x3002, 0xf0},
-	{0x3600, 0x08},
-	{0x3621, 0xc0},
-	{0x3632, 0xd2},
-	{0x3633, 0x23},
-	{0x3634, 0x54},
-	{0x3f01, 0x0c},
-	{0x5001, 0xc1},
-	{0x3614, 0xf0},
-	{0x3630, 0x2d},
-	{0x370b, 0x62},
-	{0x3706, 0x61},
-	{0x4000, 0x02},
-	{0x4002, 0xc5},
-	{0x4005, 0x08},
-	{0x404f, 0x84},
-	{0x4051, 0x00},
-	{0x5000, 0xcf},
-	{0x3a18, 0x00},
-	{0x3a19, 0x80},
-	{0x3503, 0x03},
-	{0x4521, 0x00},
-	{0x5183, 0xb0},
-	{0x5184, 0xb0},
-	{0x5185, 0xb0},
-	{0x370c, 0x0c},
-	{0x3035, 0x10},
-	{0x3036, 0x1e},
-	{0x3037, 0x21},
-	{0x303e, 0x19},
-	{0x3038, 0x06},
-	{0x3018, 0x04},
-	{0x3000, 0x00},
-	{0x3001, 0x00},
-	{0x3002, 0x00},
-	{0x3a0f, 0x40},
-	{0x3a10, 0x38},
-	{0x3a1b, 0x48},
-	{0x3a1e, 0x30},
-	{0x3a11, 0x90},
-	{0x3a1f, 0x10},
-	{0x4800, 0x24},
-};
-
-static struct msm_camera_i2c_reg_conf ov2720_720_settings[] = {
-	{0x3800, 0x01},
-	{0x3801, 0x4a},
-	{0x3802, 0x00},
-	{0x3803, 0xba},
-	{0x3804, 0x06},
-	{0x3805, 0x51+32},
-	{0x3806, 0x03},
-	{0x3807, 0x8d+24},
-	{0x3810, 0x00},
-	{0x3811, 0x05},
-	{0x3812, 0x00},
-	{0x3813, 0x02},
-	{0x3820, 0x80},
-	{0x3821, 0x06},
-	{0x3814, 0x11},
-	{0x3815, 0x11},
-	{0x3612, 0x0b},
-	{0x3618, 0x04},
-	{0x3a08, 0x01},
-	{0x3a09, 0x50},
-	{0x3a0a, 0x01},
-	{0x3a0b, 0x18},
-	{0x3a0d, 0x03},
-	{0x3a0e, 0x03},
-	{0x4520, 0x00},
-	{0x4837, 0x1b},
-	{0x3000, 0xff},
-	{0x3001, 0xff},
-	{0x3002, 0xf0},
-	{0x3600, 0x08},
-	{0x3621, 0xc0},
-	{0x3632, 0xd2},
-	{0x3633, 0x23},
-	{0x3634, 0x54},
-	{0x3f01, 0x0c},
-	{0x5001, 0xc1},
-	{0x3614, 0xf0},
-	{0x3630, 0x2d},
-	{0x370b, 0x62},
-	{0x3706, 0x61},
-	{0x4000, 0x02},
-	{0x4002, 0xc5},
-	{0x4005, 0x08},
-	{0x404f, 0x84},
-	{0x4051, 0x00},
-	{0x5000, 0xff},
-	{0x3a18, 0x00},
-	{0x3a19, 0x80},
-	{0x3503, 0x13},
-	{0x4521, 0x00},
-	{0x5183, 0xb0},
-	{0x5184, 0xb0},
-	{0x5185, 0xb0},
-	{0x370c, 0x0c},
-	{0x3035, 0x10},
-	{0x3036, 0x04},
-	{0x3037, 0x61},
-	{0x303e, 0x19},
-	{0x3038, 0x06},
-	{0x3018, 0x04},
-	{0x3000, 0x00},
-	{0x3001, 0x00},
-	{0x3002, 0x00},
-	{0x3a0f, 0x40},
-	{0x3a10, 0x38},
-	{0x3a1b, 0x48},
-	{0x3a1e, 0x30},
-	{0x3a11, 0x90},
-	{0x3a1f, 0x10},
-	{0x4800, 0x24},
-};
-
-static struct msm_camera_i2c_reg_conf ov2720_vga_settings[] = {
-	{0x3800, 0x00},
-	{0x3801, 0x0c},
-	{0x3802, 0x00},
-	{0x3803, 0x02},
-	{0x3804, 0x07},
-	{0x3805, 0x97+32},
-	{0x3806, 0x04},
-	{0x3807, 0x45+24},
-	{0x3810, 0x00},
-	{0x3811, 0x03},
-	{0x3812, 0x00},
-	{0x3813, 0x03},
-	{0x3820, 0x80},
-	{0x3821, 0x06},
-	{0x3814, 0x11},
-	{0x3815, 0x11},
-	{0x3612, 0x0b},
-	{0x3618, 0x04},
-	{0x3a08, 0x01},
-	{0x3a09, 0x50},
-	{0x3a0a, 0x01},
-	{0x3a0b, 0x18},
-	{0x3a0d, 0x03},
-	{0x3a0e, 0x03},
-	{0x4520, 0x00},
-	{0x4837, 0x1b},
-	{0x3000, 0xff},
-	{0x3001, 0xff},
-	{0x3002, 0xf0},
-	{0x3600, 0x08},
-	{0x3621, 0xc0},
-	{0x3632, 0xd2},
-	{0x3633, 0x23},
-	{0x3634, 0x54},
-	{0x3f01, 0x0c},
-	{0x5001, 0xc1},
-	{0x3614, 0xf0},
-	{0x3630, 0x2d},
-	{0x370b, 0x62},
-	{0x3706, 0x61},
-	{0x4000, 0x02},
-	{0x4002, 0xc5},
-	{0x4005, 0x08},
-	{0x404f, 0x84},
-	{0x4051, 0x00},
-	{0x5000, 0xff},
-	{0x3a18, 0x00},
-	{0x3a19, 0x80},
-	{0x3503, 0x13},
-	{0x4521, 0x00},
-	{0x5183, 0xb0},
-	{0x5184, 0xb0},
-	{0x5185, 0xb0},
-	{0x370c, 0x0c},
-	{0x3035, 0x10},
-	{0x3036, 0x04},
-	{0x3037, 0x61},
-	{0x303e, 0x19},
-	{0x3038, 0x06},
-	{0x3018, 0x04},
-	{0x3000, 0x00},
-	{0x3001, 0x00},
-	{0x3002, 0x00},
-	{0x3a0f, 0x40},
-	{0x3a10, 0x38},
-	{0x3a1b, 0x48},
-	{0x3a1e, 0x30},
-	{0x3a11, 0x90},
-	{0x3a1f, 0x10},
-	{0x4800, 0x24},
-	{0x3500, 0x00},
-	{0x3501, 0x17},
-	{0x3502, 0xf0},
-	{0x3508, 0x00},
-	{0x3509, 0x20},
-};
-
-static struct msm_camera_i2c_reg_conf ov2720_60fps_settings[] = {
-	{0x3718, 0x10},
-	{0x3702, 0x18},
-	{0x373a, 0x3c},
-	{0x3715, 0x01},
-	{0x3703, 0x1d},
-	{0x3705, 0x0b},
-	{0x3730, 0x1f},
-	{0x3704, 0x3f},
-	{0x3f06, 0x1d},
-	{0x371c, 0x00},
-	{0x371d, 0x83},
-	{0x371e, 0x00},
-	{0x371f, 0xb6},
-	{0x3708, 0x63},
-	{0x3709, 0x52},
-	{0x3800, 0x01},
-	{0x3801, 0x42},
-	{0x3802, 0x00},
-	{0x3803, 0x40},
-	{0x3804, 0x06},
-	{0x3805, 0x61},
-	{0x3806, 0x04},
-	{0x3807, 0x08},
-	{0x3808, 0x02},
-	{0x3809, 0x80},
-	{0x380a, 0x01},
-	{0x380b, 0xe0},
-	{0x380c, 0x03},
-	{0x380d, 0x0c},
-	{0x380e, 0x02},
-	{0x380f, 0x00},
-	{0x3810, 0x00},
-	{0x3811, 0x0f},
-	{0x3812, 0x00},
-	{0x3813, 0x02},
-	{0x3820, 0x80},
-	{0x3821, 0x06},
-	{0x3814, 0x31},
-	{0x3815, 0x31},
-	{0x3612, 0x0b},
-	{0x3618, 0x04},
-	{0x3a08, 0x02},
-	{0x3a09, 0x67},
-	{0x3a0a, 0x02},
-	{0x3a0b, 0x00},
-	{0x3a0d, 0x00},
-	{0x3a0e, 0x00},
-	{0x4520, 0x0a},
-	{0x4837, 0x29},
-	{0x3000, 0xff},
-	{0x3001, 0xff},
-	{0x3002, 0xf0},
-	{0x3600, 0x08},
-	{0x3621, 0xc0},
-	{0x3632, 0xd2},
-	{0x3633, 0x23},
-	{0x3634, 0x54},
-	{0x3f01, 0x0c},
-	{0x5001, 0xc1},
-	{0x3614, 0xf0},
-	{0x3630, 0x2d},
-	{0x370b, 0x62},
-	{0x3706, 0x61},
-	{0x4000, 0x02},
-	{0x4002, 0xc5},
-	{0x4005, 0x08},
-	{0x404f, 0x84},
-	{0x4051, 0x00},
-	{0x5000, 0xcf},
-	{0x3a18, 0x00},
-	{0x3a19, 0x80},
-	{0x3503, 0x07},
-	{0x4521, 0x00},
-	{0x5183, 0xb0},
-	{0x5184, 0xb0},
-	{0x5185, 0xb0},
-	{0x370c, 0x0c},
-	{0x3035, 0x30},
-	{0x3036, 0x14},
-	{0x3037, 0x21},
-	{0x303e, 0x19},
-	{0x3038, 0x06},
-	{0x3018, 0x04},
-	{0x3000, 0x00},
-	{0x3001, 0x00},
-	{0x3002, 0x00},
-	{0x3a0f, 0x40},
-	{0x3a10, 0x38},
-	{0x3a1b, 0x48},
-	{0x3a1e, 0x30},
-	{0x3a11, 0x90},
-	{0x3a1f, 0x10},
-	{0x3011, 0x22},
-	{0x3a00, 0x58},
-};
-
-static struct msm_camera_i2c_reg_conf ov2720_90fps_settings[] = {
-	{0x3718, 0x10},
-	{0x3702, 0x18},
-	{0x373a, 0x3c},
-	{0x3715, 0x01},
-	{0x3703, 0x1d},
-	{0x3705, 0x0b},
-	{0x3730, 0x1f},
-	{0x3704, 0x3f},
-	{0x3f06, 0x1d},
-	{0x371c, 0x00},
-	{0x371d, 0x83},
-	{0x371e, 0x00},
-	{0x371f, 0xb6},
-	{0x3708, 0x63},
-	{0x3709, 0x52},
-	{0x3800, 0x01},
-	{0x3801, 0x42},
-	{0x3802, 0x00},
-	{0x3803, 0x40},
-	{0x3804, 0x06},
-	{0x3805, 0x61},
-	{0x3806, 0x04},
-	{0x3807, 0x08},
-	{0x3808, 0x02},
-	{0x3809, 0x80},
-	{0x380a, 0x01},
-	{0x380b, 0xe0},
-	{0x380c, 0x03},
-	{0x380d, 0x0c},
-	{0x380e, 0x02},
-	{0x380f, 0x00},
-	{0x3810, 0x00},
-	{0x3811, 0x0f},
-	{0x3812, 0x00},
-	{0x3813, 0x02},
-	{0x3820, 0x80},
-	{0x3821, 0x06},
-	{0x3814, 0x31},
-	{0x3815, 0x31},
-	{0x3612, 0x0b},
-	{0x3618, 0x04},
-	{0x3a08, 0x02},
-	{0x3a09, 0x67},
-	{0x3a0a, 0x02},
-	{0x3a0b, 0x00},
-	{0x3a0d, 0x00},
-	{0x3a0e, 0x00},
-	{0x4520, 0x0a},
-	{0x4837, 0x29},
-	{0x3000, 0xff},
-	{0x3001, 0xff},
-	{0x3002, 0xf0},
-	{0x3600, 0x08},
-	{0x3621, 0xc0},
-	{0x3632, 0xd2},
-	{0x3633, 0x23},
-	{0x3634, 0x54},
-	{0x3f01, 0x0c},
-	{0x5001, 0xc1},
-	{0x3614, 0xf0},
-	{0x3630, 0x2d},
-	{0x370b, 0x62},
-	{0x3706, 0x61},
-	{0x4000, 0x02},
-	{0x4002, 0xc5},
-	{0x4005, 0x08},
-	{0x404f, 0x84},
-	{0x4051, 0x00},
-	{0x5000, 0xcf},
-	{0x3a18, 0x00},
-	{0x3a19, 0x80},
-	{0x3503, 0x07},
-	{0x4521, 0x00},
-	{0x5183, 0xb0},
-	{0x5184, 0xb0},
-	{0x5185, 0xb0},
-	{0x370c, 0x0c},
-	{0x3035, 0x30},
-	{0x3036, 0x1e},
-	{0x3037, 0x21},
-	{0x303e, 0x19},
-	{0x3038, 0x06},
-	{0x3018, 0x04},
-	{0x3000, 0x00},
-	{0x3001, 0x00},
-	{0x3002, 0x00},
-	{0x3a0f, 0x40},
-	{0x3a10, 0x38},
-	{0x3a1b, 0x48},
-	{0x3a1e, 0x30},
-	{0x3a11, 0x90},
-	{0x3a1f, 0x10},
-	{0x3011, 0x22},
-	{0x3a00, 0x58},
-};
-
-static struct msm_camera_i2c_reg_conf ov2720_120fps_settings[] = {
-	{0x3718, 0x10},
-	{0x3702, 0x18},
-	{0x373a, 0x3c},
-	{0x3715, 0x01},
-	{0x3703, 0x1d},
-	{0x3705, 0x0b},
-	{0x3730, 0x1f},
-	{0x3704, 0x3f},
-	{0x3f06, 0x1d},
-	{0x371c, 0x00},
-	{0x371d, 0x83},
-	{0x371e, 0x00},
-	{0x371f, 0xb6},
-	{0x3708, 0x63},
-	{0x3709, 0x52},
-	{0x3800, 0x01},
-	{0x3801, 0x42},
-	{0x3802, 0x00},
-	{0x3803, 0x40},
-	{0x3804, 0x06},
-	{0x3805, 0x61},
-	{0x3806, 0x04},
-	{0x3807, 0x08},
-	{0x3808, 0x02},
-	{0x3809, 0x80},
-	{0x380a, 0x01},
-	{0x380b, 0xe0},
-	{0x380c, 0x03},
-	{0x380d, 0x0c},
-	{0x380e, 0x02},
-	{0x380f, 0x00},
-	{0x3810, 0x00},
-	{0x3811, 0x0f},
-	{0x3812, 0x00},
-	{0x3813, 0x02},
-	{0x3820, 0x80},
-	{0x3821, 0x06},
-	{0x3814, 0x31},
-	{0x3815, 0x31},
-	{0x3612, 0x0b},
-	{0x3618, 0x04},
-	{0x3a08, 0x02},
-	{0x3a09, 0x67},
-	{0x3a0a, 0x02},
-	{0x3a0b, 0x00},
-	{0x3a0d, 0x00},
-	{0x3a0e, 0x00},
-	{0x4520, 0x0a},
-	{0x4837, 0x29},
-	{0x3000, 0xff},
-	{0x3001, 0xff},
-	{0x3002, 0xf0},
-	{0x3600, 0x08},
-	{0x3621, 0xc0},
-	{0x3632, 0xd2},
-	{0x3633, 0x23},
-	{0x3634, 0x54},
-	{0x3f01, 0x0c},
-	{0x5001, 0xc1},
-	{0x3614, 0xf0},
-	{0x3630, 0x2d},
-	{0x370b, 0x62},
-	{0x3706, 0x61},
-	{0x4000, 0x02},
-	{0x4002, 0xc5},
-	{0x4005, 0x08},
-	{0x404f, 0x84},
-	{0x4051, 0x00},
-	{0x5000, 0xcf},
-	{0x3a18, 0x00},
-	{0x3a19, 0x80},
-	{0x3503, 0x07},
-	{0x4521, 0x00},
-	{0x5183, 0xb0},
-	{0x5184, 0xb0},
-	{0x5185, 0xb0},
-	{0x370c, 0x0c},
-	{0x3035, 0x10},
-	{0x3036, 0x14},
-	{0x3037, 0x21},
-	{0x303e, 0x19},
-	{0x3038, 0x06},
-	{0x3018, 0x04},
-	{0x3000, 0x00},
-	{0x3001, 0x00},
-	{0x3002, 0x00},
-	{0x3a0f, 0x40},
-	{0x3a10, 0x38},
-	{0x3a1b, 0x48},
-	{0x3a1e, 0x30},
-	{0x3a11, 0x90},
-	{0x3a1f, 0x10},
-	{0x3011, 0x22},
-	{0x3a00, 0x58},
-};
-
-static struct msm_camera_i2c_reg_conf ov2720_recommend_settings[] = {
-	{0x0103, 0x01},
-	{0x3718, 0x10},
-	{0x3702, 0x24},
-	{0x373a, 0x60},
-	{0x3715, 0x01},
-	{0x3703, 0x2e},
-	{0x3705, 0x10},
-	{0x3730, 0x30},
-	{0x3704, 0x62},
-	{0x3f06, 0x3a},
-	{0x371c, 0x00},
-	{0x371d, 0xc4},
-	{0x371e, 0x01},
-	{0x371f, 0x0d},
-	{0x3708, 0x61},
-	{0x3709, 0x12},
-};
-
-static struct v4l2_subdev_info ov2720_subdev_info[] = {
-	{
-	.code   = V4L2_MBUS_FMT_SBGGR10_1X10,
-	.colorspace = V4L2_COLORSPACE_JPEG,
-	.fmt    = 1,
-	.order    = 0,
-	},
-	/* more can be supported, to be added later */
-};
-
-static struct msm_camera_i2c_conf_array ov2720_init_conf[] = {
-	{&ov2720_recommend_settings[0],
-	ARRAY_SIZE(ov2720_recommend_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}
-};
-
-static struct msm_camera_i2c_conf_array ov2720_confs[] = {
-	{&ov2720_prev_settings[0],
-	ARRAY_SIZE(ov2720_prev_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
-	{&ov2720_vga_settings[0],
-	ARRAY_SIZE(ov2720_vga_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
-	{&ov2720_720_settings[0],
-	ARRAY_SIZE(ov2720_720_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
-	{&ov2720_60fps_settings[0],
-	ARRAY_SIZE(ov2720_60fps_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
-	{&ov2720_90fps_settings[0],
-	ARRAY_SIZE(ov2720_90fps_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
-	{&ov2720_120fps_settings[0],
-	ARRAY_SIZE(ov2720_120fps_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
-};
-
-static struct msm_sensor_output_info_t ov2720_dimensions[] = {
-	{
-		.x_output = 0x78C,
-		.y_output = 0x444,
-		.line_length_pclk = 0x85c,
-		.frame_length_lines = 0x460,
-		.vt_pixel_clk = 72000000,
-		.op_pixel_clk = 72000000,
-		.binning_factor = 1,
-	},
-	{
-		.x_output = 0x510,
-		.y_output = 0x278,
-		.line_length_pclk = 0x85c,
-		.frame_length_lines = 0x460,
-		.vt_pixel_clk = 72000000,
-		.op_pixel_clk = 72000000,
-		.binning_factor = 1,
-	},
-	{
-		.x_output = 0x298,
-		.y_output = 0x1F2,
-		.line_length_pclk = 0x85c,
-		.frame_length_lines = 0x460,
-		.vt_pixel_clk = 72000000,
-		.op_pixel_clk = 72000000,
-		.binning_factor = 1,
-	},
-	{
-		.x_output = 0x280, /* 640 */
-		.y_output = 0x1E0, /* 480 */
-		.line_length_pclk = 0x30C, /* 780 */
-		.frame_length_lines = 0x200, /* 512 */
-		.vt_pixel_clk = 24000000,
-		.op_pixel_clk = 24000000,
-		.binning_factor = 1,
-	},
-	{
-		.x_output = 0x280, /* 640 */
-		.y_output = 0x1E0, /* 480 */
-		.line_length_pclk = 0x30C, /* 780 */
-		.frame_length_lines = 0x200, /* 512 */
-		.vt_pixel_clk = 36000000,
-		.op_pixel_clk = 36000000,
-		.binning_factor = 1,
-	},
-	{
-		.x_output = 0x280, /* 640 */
-		.y_output = 0x1E0, /* 480 */
-		.line_length_pclk = 0x30C, /* 780 */
-		.frame_length_lines = 0x200, /* 512 */
-		.vt_pixel_clk = 48000000,
-		.op_pixel_clk = 48000000,
-		.binning_factor = 1,
-	},
-};
-
-static struct msm_sensor_output_reg_addr_t ov2720_reg_addr = {
-	.x_output = 0x3808,
-	.y_output = 0x380a,
-	.line_length_pclk = 0x380c,
-	.frame_length_lines = 0x380e,
-};
-
-static struct msm_sensor_id_info_t ov2720_id_info = {
-	.sensor_id_reg_addr = 0x300A,
-	.sensor_id = 0x2720,
-};
-
-static struct msm_sensor_exp_gain_info_t ov2720_exp_gain_info = {
-	.coarse_int_time_addr = 0x3501,
-	.global_gain_addr = 0x3508,
-	.vert_offset = 6,
-};
-
-static enum msm_camera_vreg_name_t ov2720_veg_seq[] = {
-	CAM_VIO,
-	CAM_VANA,
-	CAM_VDIG,
-};
-
-static int32_t ov2720_write_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
-		uint16_t gain, uint32_t line)
-{
-	uint32_t fl_lines, offset;
-	uint8_t int_time[3];
-	fl_lines =
-		(s_ctrl->curr_frame_length_lines * s_ctrl->fps_divider) / Q10;
-	offset = s_ctrl->sensor_exp_gain_info->vert_offset;
-	if (line > (fl_lines - offset))
-		fl_lines = line + offset;
-
-	s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_output_reg_addr->frame_length_lines, fl_lines,
-		MSM_CAMERA_I2C_WORD_DATA);
-	int_time[0] = line >> 12;
-	int_time[1] = line >> 4;
-	int_time[2] = line << 4;
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr-1,
-		int_time[0], MSM_CAMERA_I2C_BYTE_DATA);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr,
-		int_time[1], MSM_CAMERA_I2C_BYTE_DATA);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr+1,
-		int_time[2], MSM_CAMERA_I2C_BYTE_DATA);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->global_gain_addr, gain,
-		MSM_CAMERA_I2C_WORD_DATA);
-	s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
-	return 0;
-}
-
-static const struct i2c_device_id ov2720_i2c_id[] = {
-	{SENSOR_NAME, (kernel_ulong_t)&ov2720_s_ctrl},
-	{ }
-};
-
-static struct i2c_driver ov2720_i2c_driver = {
-	.id_table = ov2720_i2c_id,
-	.probe  = msm_sensor_i2c_probe,
-	.driver = {
-		.name = SENSOR_NAME,
-	},
-};
-
-static struct msm_camera_i2c_client ov2720_sensor_i2c_client = {
-	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
-};
-
-
-static const struct of_device_id ov2720_dt_match[] = {
-	{.compatible = "qcom,ov2720", .data = &ov2720_s_ctrl},
-	{}
-};
-
-MODULE_DEVICE_TABLE(of, ov2720_dt_match);
-
-static struct platform_driver ov2720_platform_driver = {
-	.driver = {
-		.name = "qcom,ov2720",
-		.owner = THIS_MODULE,
-		.of_match_table = ov2720_dt_match,
-	},
-};
-
-static int32_t ov2720_platform_probe(struct platform_device *pdev)
-{
-	int32_t rc = 0;
-	const struct of_device_id *match;
-	match = of_match_device(ov2720_dt_match, &pdev->dev);
-	rc = msm_sensor_platform_probe(pdev, match->data);
-	return rc;
-}
-
-static int __init msm_sensor_init_module(void)
-{
-	int32_t rc = 0;
-	rc = platform_driver_probe(&ov2720_platform_driver,
-		ov2720_platform_probe);
-	if (!rc)
-		return rc;
-	return i2c_add_driver(&ov2720_i2c_driver);
-}
-
-static void __exit msm_sensor_exit_module(void)
-{
-	if (ov2720_s_ctrl.pdev) {
-		msm_sensor_free_sensor_data(&ov2720_s_ctrl);
-		platform_driver_unregister(&ov2720_platform_driver);
-	} else
-		i2c_del_driver(&ov2720_i2c_driver);
-	return;
-}
-
-static struct v4l2_subdev_core_ops ov2720_subdev_core_ops = {
-	.ioctl = msm_sensor_subdev_ioctl,
-	.s_power = msm_sensor_power,
-};
-
-static struct v4l2_subdev_video_ops ov2720_subdev_video_ops = {
-	.enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
-};
-
-static struct v4l2_subdev_ops ov2720_subdev_ops = {
-	.core = &ov2720_subdev_core_ops,
-	.video  = &ov2720_subdev_video_ops,
-};
-
-static struct msm_sensor_fn_t ov2720_func_tbl = {
-	.sensor_start_stream = msm_sensor_start_stream,
-	.sensor_stop_stream = msm_sensor_stop_stream,
-	.sensor_group_hold_on = msm_sensor_group_hold_on,
-	.sensor_group_hold_off = msm_sensor_group_hold_off,
-	.sensor_set_fps = msm_sensor_set_fps,
-	.sensor_write_exp_gain = ov2720_write_exp_gain,
-	.sensor_write_snapshot_exp_gain = ov2720_write_exp_gain,
-	.sensor_setting = msm_sensor_setting,
-	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
-	.sensor_mode_init = msm_sensor_mode_init,
-	.sensor_get_output_info = msm_sensor_get_output_info,
-	.sensor_config = msm_sensor_config,
-	.sensor_power_up = msm_sensor_power_up,
-	.sensor_power_down = msm_sensor_power_down,
-	.sensor_adjust_frame_lines = msm_sensor_adjust_frame_lines2,
-	.sensor_get_csi_params = msm_sensor_get_csi_params,
-};
-
-static struct msm_sensor_reg_t ov2720_regs = {
-	.default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
-	.start_stream_conf = ov2720_start_settings,
-	.start_stream_conf_size = ARRAY_SIZE(ov2720_start_settings),
-	.stop_stream_conf = ov2720_stop_settings,
-	.stop_stream_conf_size = ARRAY_SIZE(ov2720_stop_settings),
-	.group_hold_on_conf = ov2720_groupon_settings,
-	.group_hold_on_conf_size = ARRAY_SIZE(ov2720_groupon_settings),
-	.group_hold_off_conf = ov2720_groupoff_settings,
-	.group_hold_off_conf_size =
-		ARRAY_SIZE(ov2720_groupoff_settings),
-	.init_settings = &ov2720_init_conf[0],
-	.init_size = ARRAY_SIZE(ov2720_init_conf),
-	.mode_settings = &ov2720_confs[0],
-	.output_settings = &ov2720_dimensions[0],
-	.num_conf = ARRAY_SIZE(ov2720_confs),
-};
-
-static struct msm_sensor_ctrl_t ov2720_s_ctrl = {
-	.msm_sensor_reg = &ov2720_regs,
-	.sensor_i2c_client = &ov2720_sensor_i2c_client,
-	.sensor_i2c_addr = 0x6C,
-	.vreg_seq = ov2720_veg_seq,
-	.num_vreg_seq = ARRAY_SIZE(ov2720_veg_seq),
-	.sensor_output_reg_addr = &ov2720_reg_addr,
-	.sensor_id_info = &ov2720_id_info,
-	.sensor_exp_gain_info = &ov2720_exp_gain_info,
-	.cam_mode = MSM_SENSOR_MODE_INVALID,
-	.msm_sensor_mutex = &ov2720_mut,
-	.sensor_i2c_driver = &ov2720_i2c_driver,
-	.sensor_v4l2_subdev_info = ov2720_subdev_info,
-	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(ov2720_subdev_info),
-	.sensor_v4l2_subdev_ops = &ov2720_subdev_ops,
-	.func_tbl = &ov2720_func_tbl,
-	.clk_rate = MSM_SENSOR_MCLK_24HZ,
-};
-
-module_init(msm_sensor_init_module);
-module_exit(msm_sensor_exit_module);
-MODULE_DESCRIPTION("Omnivision 2MP Bayer sensor driver");
-MODULE_LICENSE("GPL v2");
-
-
diff --git a/drivers/media/video/msm/sensors/ov2720.h b/drivers/media/video/msm/sensors/ov2720.h
deleted file mode 100644
index 7077a7d..0000000
--- a/drivers/media/video/msm/sensors/ov2720.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. 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 <mach/board.h>
-extern struct platform_driver ov2720_driver;
-
diff --git a/drivers/media/video/msm/sensors/ov5647_v4l2.c b/drivers/media/video/msm/sensors/ov5647_v4l2.c
deleted file mode 100644
index f6cf427..0000000
--- a/drivers/media/video/msm/sensors/ov5647_v4l2.c
+++ /dev/null
@@ -1,831 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 "msm_sensor.h"
-#include "msm.h"
-#define SENSOR_NAME "ov5647"
-#define PLATFORM_DRIVER_NAME "msm_camera_ov5647"
-#define ov5647_obj ov5647_##obj
-
-static struct msm_sensor_ctrl_t ov5647_s_ctrl;
-
-DEFINE_MUTEX(ov5647_mut);
-
-static struct msm_camera_i2c_reg_conf ov5647_start_settings[] = {
-	{0x4202, 0x00},  /* streaming on */
-	{0x0100, 0x01},
-	{0x4800, 0x04},
-};
-
-static struct msm_camera_i2c_reg_conf ov5647_stop_settings[] = {
-	{0x4202, 0x0f},  /* streaming off*/
-};
-
-static struct msm_camera_i2c_reg_conf ov5647_groupon_settings[] = {
-	{0x3208, 0x0},
-};
-
-static struct msm_camera_i2c_reg_conf ov5647_groupoff_settings[] = {
-	{0x3208, 0x10},
-	{0x3208, 0xa0},
-};
-
-static struct msm_camera_i2c_reg_conf ov5647_prev_settings[] = {
-	/*1280*960 Reference Setting 24M MCLK 2lane 280Mbps/lane 30fps
-	for back to preview*/
-	{0x3035, 0x21},
-	{0x3036, 0x37},
-	{0x3821, 0x07},
-	{0x3820, 0x41},
-	{0x3612, 0x09},
-	{0x3618, 0x00},
-	{0x380c, 0x07},
-	{0x380d, 0x68},
-	{0x380e, 0x03},
-	{0x380f, 0xd8},
-	{0x3814, 0x31},
-	{0x3815, 0x31},
-	{0x3709, 0x52},
-	{0x3808, 0x05},
-	{0x3809, 0x00},
-	{0x380a, 0x03},
-	{0x380b, 0xc0},
-	{0x3800, 0x00},
-	{0x3801, 0x18},
-	{0x3802, 0x00},
-	{0x3803, 0x0e},
-	{0x3804, 0x0a},
-	{0x3805, 0x27},
-	{0x3806, 0x07},
-	{0x3807, 0x95},
-	{0x4004, 0x02},
-};
-
-static struct msm_camera_i2c_reg_conf ov5647_snap_settings[] = {
-	/*2608*1952 Reference Setting 24M MCLK 2lane 280Mbps/lane 30fps*/
-	{0x3035, 0x21},
-	{0x3036, 0x4f},
-	{0x3821, 0x06},
-	{0x3820, 0x00},
-	{0x3612, 0x0b},
-	{0x3618, 0x04},
-	{0x380c, 0x0a},
-	{0x380d, 0x8c},
-	{0x380e, 0x07},
-	{0x380f, 0xb0},
-	{0x3814, 0x11},
-	{0x3815, 0x11},
-	{0x3709, 0x12},
-	{0x3808, 0x0a},
-	{0x3809, 0x30},
-	{0x380a, 0x07},
-	{0x380b, 0xa0},
-	{0x3800, 0x00},
-	{0x3801, 0x04},
-	{0x3802, 0x00},
-	{0x3803, 0x00},
-	{0x3804, 0x0a},
-	{0x3805, 0x3b},
-	{0x3806, 0x07},
-	{0x3807, 0xa3},
-	{0x4004, 0x04},
-};
-
-static struct msm_camera_i2c_reg_conf ov5647_video_60fps_settings[] = {
-	{0x3035, 0x21},
-	{0x3036, 0x38},
-	{0x3821, 0x07},
-	{0x3820, 0x41},
-	{0x3612, 0x49},
-	{0x3618, 0x00},
-	{0x380c, 0x07},
-	{0x380d, 0x30},
-	{0x380e, 0x01},
-	{0x380f, 0xf8},
-	{0x3814, 0x71},
-	{0x3815, 0x71},
-	{0x3709, 0x52},
-	{0x3808, 0x02},
-	{0x3809, 0x80},
-	{0x380a, 0x01},
-	{0x380b, 0xe0},
-	{0x3800, 0x00},
-	{0x3801, 0x10},
-	{0x3802, 0x00},
-	{0x3803, 0x00},
-	{0x3804, 0x0a},
-	{0x3805, 0x2f},
-	{0x3806, 0x07},
-	{0x3807, 0x9f},
-	{0x4004, 0x02},
-};
-
-static struct msm_camera_i2c_reg_conf ov5647_video_90fps_settings[] = {
-	{0x3035, 0x11},
-	{0x3036, 0x2a},
-	{0x3821, 0x07},
-	{0x3820, 0x41},
-	{0x3612, 0x49},
-	{0x3618, 0x00},
-	{0x380c, 0x07},
-	{0x380d, 0x30},
-	{0x380e, 0x01},
-	{0x380f, 0xf8},
-	{0x3814, 0x71},
-	{0x3815, 0x71},
-	{0x3709, 0x52},
-	{0x3808, 0x02},
-	{0x3809, 0x80},
-	{0x380a, 0x01},
-	{0x380b, 0xe0},
-	{0x3800, 0x00},
-	{0x3801, 0x10},
-	{0x3802, 0x00},
-	{0x3803, 0x00},
-	{0x3804, 0x0a},
-	{0x3805, 0x2f},
-	{0x3806, 0x07},
-	{0x3807, 0x9f},
-	{0x4004, 0x02},
-};
-
-static struct msm_camera_i2c_reg_conf ov5647_zsl_settings[] = {
-	{0x3035, 0x21},
-	{0x3036, 0x4f},
-	{0x3821, 0x06},
-	{0x3820, 0x00},
-	{0x3612, 0x0b},
-	{0x3618, 0x04},
-	{0x380c, 0x0a},
-	{0x380d, 0x8c},
-	{0x380e, 0x07},
-	{0x380f, 0xb0},
-	{0x3814, 0x11},
-	{0x3815, 0x11},
-	{0x3709, 0x12},
-	{0x3808, 0x0a},
-	{0x3809, 0x30},
-	{0x380a, 0x07},
-	{0x380b, 0xa0},
-	{0x3800, 0x00},
-	{0x3801, 0x04},
-	{0x3802, 0x00},
-	{0x3803, 0x00},
-	{0x3804, 0x0a},
-	{0x3805, 0x3b},
-	{0x3806, 0x07},
-	{0x3807, 0xa3},
-	{0x4004, 0x04},
-};
-
-static struct msm_camera_i2c_reg_conf ov5647_recommend_settings[] = {
-	{0x3035, 0x11},
-	{0x303c, 0x11},
-	{0x370c, 0x03},
-	{0x5000, 0x06},
-	{0x5003, 0x08},
-	{0x5a00, 0x08},
-	{0x3000, 0xff},
-	{0x3001, 0xff},
-	{0x3002, 0xff},
-	{0x301d, 0xf0},
-	{0x3a18, 0x00},
-	{0x3a19, 0xf8},
-	{0x3c01, 0x80},
-	{0x3b07, 0x0c},
-	{0x3708, 0x64},
-	{0x3630, 0x2e},
-	{0x3632, 0xe2},
-	{0x3633, 0x23},
-	{0x3634, 0x44},
-	{0x3620, 0x64},
-	{0x3621, 0xe0},
-	{0x3600, 0x37},
-	{0x3704, 0xa0},
-	{0x3703, 0x5a},
-	{0x3715, 0x78},
-	{0x3717, 0x01},
-	{0x3731, 0x02},
-	{0x370b, 0x60},
-	{0x3705, 0x1a},
-	{0x3f05, 0x02},
-	{0x3f06, 0x10},
-	{0x3f01, 0x0a},
-	{0x3a08, 0x01},
-	{0x3a0f, 0x58},
-	{0x3a10, 0x50},
-	{0x3a1b, 0x58},
-	{0x3a1e, 0x50},
-	{0x3a11, 0x60},
-	{0x3a1f, 0x28},
-	{0x4001, 0x02},
-	{0x4000, 0x09},
-	{0x3000, 0x00},
-	{0x3001, 0x00},
-	{0x3002, 0x00},
-	{0x3017, 0xe0},
-	{0x301c, 0xfc},
-	{0x3636, 0x06},
-	{0x3016, 0x08},
-	{0x3827, 0xec},
-	{0x3018, 0x44},
-	{0x3035, 0x21},
-	{0x3106, 0xf5},
-	{0x3034, 0x18},
-	{0x301c, 0xf8},
-	/*lens setting*/
-	{0x5000, 0x86},
-	{0x5800, 0x11},
-	{0x5801, 0x0c},
-	{0x5802, 0x0a},
-	{0x5803, 0x0b},
-	{0x5804, 0x0d},
-	{0x5805, 0x13},
-	{0x5806, 0x09},
-	{0x5807, 0x05},
-	{0x5808, 0x03},
-	{0x5809, 0x03},
-	{0x580a, 0x06},
-	{0x580b, 0x08},
-	{0x580c, 0x05},
-	{0x580d, 0x01},
-	{0x580e, 0x00},
-	{0x580f, 0x00},
-	{0x5810, 0x02},
-	{0x5811, 0x06},
-	{0x5812, 0x05},
-	{0x5813, 0x01},
-	{0x5814, 0x00},
-	{0x5815, 0x00},
-	{0x5816, 0x02},
-	{0x5817, 0x06},
-	{0x5818, 0x09},
-	{0x5819, 0x05},
-	{0x581a, 0x04},
-	{0x581b, 0x04},
-	{0x581c, 0x06},
-	{0x581d, 0x09},
-	{0x581e, 0x11},
-	{0x581f, 0x0c},
-	{0x5820, 0x0b},
-	{0x5821, 0x0b},
-	{0x5822, 0x0d},
-	{0x5823, 0x13},
-	{0x5824, 0x22},
-	{0x5825, 0x26},
-	{0x5826, 0x26},
-	{0x5827, 0x24},
-	{0x5828, 0x24},
-	{0x5829, 0x24},
-	{0x582a, 0x22},
-	{0x582b, 0x20},
-	{0x582c, 0x22},
-	{0x582d, 0x26},
-	{0x582e, 0x22},
-	{0x582f, 0x22},
-	{0x5830, 0x42},
-	{0x5831, 0x22},
-	{0x5832, 0x02},
-	{0x5833, 0x24},
-	{0x5834, 0x22},
-	{0x5835, 0x22},
-	{0x5836, 0x22},
-	{0x5837, 0x26},
-	{0x5838, 0x42},
-	{0x5839, 0x26},
-	{0x583a, 0x06},
-	{0x583b, 0x26},
-	{0x583c, 0x24},
-	{0x583d, 0xce},
-	/* manual AWB,manual AE,close Lenc,open WBC*/
-	{0x3503, 0x03}, /*manual AE*/
-	{0x3501, 0x10},
-	{0x3502, 0x80},
-	{0x350a, 0x00},
-	{0x350b, 0x7f},
-	{0x5001, 0x01}, /*manual AWB*/
-	{0x5180, 0x08},
-	{0x5186, 0x04},
-	{0x5187, 0x00},
-	{0x5188, 0x04},
-	{0x5189, 0x00},
-	{0x518a, 0x04},
-	{0x518b, 0x00},
-	{0x5000, 0x06}, /*No lenc,WBC on*/
-	{0x4005, 0x18},
-	{0x4051, 0x8f},
-};
-
-
-static struct msm_camera_i2c_conf_array ov5647_init_conf[] = {
-	{&ov5647_recommend_settings[0],
-	ARRAY_SIZE(ov5647_recommend_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}
-};
-
-static struct msm_camera_i2c_conf_array ov5647_confs[] = {
-	{&ov5647_snap_settings[0],
-	ARRAY_SIZE(ov5647_snap_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
-	{&ov5647_prev_settings[0],
-	ARRAY_SIZE(ov5647_prev_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
-	{&ov5647_video_60fps_settings[0],
-	ARRAY_SIZE(ov5647_video_60fps_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
-	{&ov5647_video_90fps_settings[0],
-	ARRAY_SIZE(ov5647_video_90fps_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
-	{&ov5647_zsl_settings[0],
-	ARRAY_SIZE(ov5647_zsl_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
-};
-
-static struct v4l2_subdev_info ov5647_subdev_info[] = {
-	{
-		.code   = V4L2_MBUS_FMT_SBGGR10_1X10,
-		.colorspace = V4L2_COLORSPACE_JPEG,
-		.fmt    = 1,
-		.order    = 0,
-	},
-	/* more can be supported, to be added later */
-};
-
-static struct msm_sensor_output_info_t ov5647_dimensions[] = {
-	{ /* For SNAPSHOT */
-		.x_output = 0xA30,  /*2608*/  /*for 5Mp*/
-		.y_output = 0x7A0,   /*1952*/
-		.line_length_pclk = 0xA8C,
-		.frame_length_lines = 0x7B0,
-		.vt_pixel_clk = 79704000,
-		.op_pixel_clk = 159408000,
-		.binning_factor = 0x0,
-	},
-	{ /* For PREVIEW */
-		.x_output = 0x500, /*1280*/
-		.y_output = 0x3C0, /*960*/
-		.line_length_pclk = 0x768,
-		.frame_length_lines = 0x3D8,
-		.vt_pixel_clk = 55969920,
-		.op_pixel_clk = 159408000,
-		.binning_factor = 0x0,
-	},
-	{ /* For 60fps */
-		.x_output = 0x280,  /*640*/
-		.y_output = 0x1E0,   /*480*/
-		.line_length_pclk = 0x73C,
-		.frame_length_lines = 0x1F8,
-		.vt_pixel_clk = 56004480,
-		.op_pixel_clk = 159408000,
-		.binning_factor = 0x0,
-	},
-	{ /* For 90fps */
-		.x_output = 0x280,  /*640*/
-		.y_output = 0x1E0,   /*480*/
-		.line_length_pclk = 0x73C,
-		.frame_length_lines = 0x1F8,
-		.vt_pixel_clk = 56004480,
-		.op_pixel_clk = 159408000,
-		.binning_factor = 0x0,
-	},
-	{ /* For ZSL */
-		.x_output = 0xA30,  /*2608*/  /*for 5Mp*/
-		.y_output = 0x7A0,   /*1952*/
-		.line_length_pclk = 0xA8C,
-		.frame_length_lines = 0x7B0,
-		.vt_pixel_clk = 79704000,
-		.op_pixel_clk = 159408000,
-		.binning_factor = 0x0,
-	},
-
-};
-
-static struct msm_sensor_output_reg_addr_t ov5647_reg_addr = {
-	.x_output = 0x3808,
-	.y_output = 0x380A,
-	.line_length_pclk = 0x380C,
-	.frame_length_lines = 0x380E,
-};
-
-static struct msm_sensor_id_info_t ov5647_id_info = {
-	.sensor_id_reg_addr = 0x300a,
-	.sensor_id = 0x5647,
-};
-
-static struct msm_sensor_exp_gain_info_t ov5647_exp_gain_info = {
-	.coarse_int_time_addr = 0x3500,
-	.global_gain_addr = 0x350A,
-	.vert_offset = 4,
-};
-
-void ov5647_sensor_reset_stream(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	msm_camera_i2c_write(
-		s_ctrl->sensor_i2c_client,
-		0x103, 0x1,
-		MSM_CAMERA_I2C_BYTE_DATA);
-}
-
-static int32_t ov5647_write_pict_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
-		uint16_t gain, uint32_t line)
-{
-
-	static uint16_t max_line = 1964;
-	uint8_t gain_lsb, gain_hsb;
-	u8 intg_time_hsb, intg_time_msb, intg_time_lsb;
-
-	gain_lsb = (uint8_t) (gain);
-	gain_hsb = (uint8_t)((gain & 0x300)>>8);
-
-	CDBG(KERN_ERR "snapshot exposure seting 0x%x, 0x%x, %d"
-		, gain, line, line);
-	s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
-	if (line > 1964) {
-		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-			s_ctrl->sensor_output_reg_addr->frame_length_lines,
-			(uint8_t)((line+4) >> 8),
-			MSM_CAMERA_I2C_BYTE_DATA);
-
-		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-			s_ctrl->sensor_output_reg_addr->frame_length_lines + 1,
-			(uint8_t)((line+4) & 0x00FF),
-			MSM_CAMERA_I2C_BYTE_DATA);
-		max_line = line + 4;
-	} else if (max_line > 1968) {
-		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-			s_ctrl->sensor_output_reg_addr->frame_length_lines,
-			(uint8_t)(1968 >> 8),
-			MSM_CAMERA_I2C_BYTE_DATA);
-
-		 msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-			s_ctrl->sensor_output_reg_addr->frame_length_lines + 1,
-			(uint8_t)(1968 & 0x00FF),
-			MSM_CAMERA_I2C_BYTE_DATA);
-			max_line = 1968;
-	}
-
-
-	line = line<<4;
-	/* ov5647 need this operation */
-	intg_time_hsb = (u8)(line>>16);
-	intg_time_msb = (u8) ((line & 0xFF00) >> 8);
-	intg_time_lsb = (u8) (line & 0x00FF);
-
-	/* FIXME for BLC trigger */
-	/* Coarse Integration Time */
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr,
-		intg_time_hsb,
-		MSM_CAMERA_I2C_BYTE_DATA);
-
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr + 1,
-		intg_time_msb,
-		MSM_CAMERA_I2C_BYTE_DATA);
-
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr + 2,
-		intg_time_lsb,
-		MSM_CAMERA_I2C_BYTE_DATA);
-
-	/* gain */
-
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->global_gain_addr,
-		gain_hsb,
-		MSM_CAMERA_I2C_BYTE_DATA);
-
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->global_gain_addr + 1,
-		gain_lsb^0x1,
-		MSM_CAMERA_I2C_BYTE_DATA);
-
-	/* Coarse Integration Time */
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr,
-		intg_time_hsb,
-		MSM_CAMERA_I2C_BYTE_DATA);
-
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr + 1,
-		intg_time_msb,
-		MSM_CAMERA_I2C_BYTE_DATA);
-
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr + 2,
-		intg_time_lsb,
-		MSM_CAMERA_I2C_BYTE_DATA);
-
-	/* gain */
-
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->global_gain_addr,
-		gain_hsb,
-		MSM_CAMERA_I2C_BYTE_DATA);
-
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->global_gain_addr + 1,
-		gain_lsb,
-		MSM_CAMERA_I2C_BYTE_DATA);
-
-
-	s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
-	return 0;
-
-}
-
-
-static int32_t ov5647_write_prev_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
-						uint16_t gain, uint32_t line)
-{
-	u8 intg_time_hsb, intg_time_msb, intg_time_lsb;
-	uint8_t gain_lsb, gain_hsb;
-	uint32_t fl_lines = s_ctrl->curr_frame_length_lines;
-	uint8_t offset = s_ctrl->sensor_exp_gain_info->vert_offset;
-
-	CDBG(KERN_ERR "preview exposure setting 0x%x, 0x%x, %d",
-		 gain, line, line);
-
-	gain_lsb = (uint8_t) (gain);
-	gain_hsb = (uint8_t)((gain & 0x300)>>8);
-
-	fl_lines = (fl_lines * s_ctrl->fps_divider) / Q10;
-
-	s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
-
-	/* adjust frame rate */
-	if ((s_ctrl->curr_res < MSM_SENSOR_RES_2) &&
-		(line > (fl_lines - offset)))
-		fl_lines = line + offset;
-
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_output_reg_addr->frame_length_lines,
-		(uint8_t)(fl_lines >> 8),
-		MSM_CAMERA_I2C_BYTE_DATA);
-
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_output_reg_addr->frame_length_lines + 1,
-		(uint8_t)(fl_lines & 0x00FF),
-		MSM_CAMERA_I2C_BYTE_DATA);
-
-	line = line<<4;
-	/* ov5647 need this operation */
-	intg_time_hsb = (u8)(line>>16);
-	intg_time_msb = (u8) ((line & 0xFF00) >> 8);
-	intg_time_lsb = (u8) (line & 0x00FF);
-
-
-	/* Coarse Integration Time */
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr,
-		intg_time_hsb,
-		MSM_CAMERA_I2C_BYTE_DATA);
-
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr + 1,
-		intg_time_msb,
-		MSM_CAMERA_I2C_BYTE_DATA);
-
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr + 2,
-		intg_time_lsb,
-		MSM_CAMERA_I2C_BYTE_DATA);
-
-	/* gain */
-
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->global_gain_addr,
-		gain_hsb,
-		MSM_CAMERA_I2C_BYTE_DATA);
-
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->global_gain_addr + 1,
-		gain_lsb,
-		MSM_CAMERA_I2C_BYTE_DATA);
-
-	s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
-
-	return 0;
-}
-
-static const struct i2c_device_id ov5647_i2c_id[] = {
-	{SENSOR_NAME, (kernel_ulong_t)&ov5647_s_ctrl},
-	{ }
-};
-int32_t ov5647_sensor_i2c_probe(struct i2c_client *client,
-		const struct i2c_device_id *id)
-{
-	int32_t rc = 0;
-	struct msm_sensor_ctrl_t *s_ctrl;
-
-	rc = msm_sensor_i2c_probe(client, id);
-
-	if (client->dev.platform_data == NULL) {
-		pr_err("%s: NULL sensor data\n", __func__);
-		return -EFAULT;
-	}
-
-	s_ctrl = client->dev.platform_data;
-
-	return rc;
-}
-
-static struct i2c_driver ov5647_i2c_driver = {
-	.id_table = ov5647_i2c_id,
-	.probe  = ov5647_sensor_i2c_probe,
-	.driver = {
-		.name = SENSOR_NAME,
-	},
-};
-
-
-
-static struct msm_camera_i2c_client ov5647_sensor_i2c_client = {
-	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
-};
-
-static int __init msm_sensor_init_module(void)
-{
-	return i2c_add_driver(&ov5647_i2c_driver);
-}
-
-static struct v4l2_subdev_core_ops ov5647_subdev_core_ops = {
-	.ioctl = msm_sensor_subdev_ioctl,
-	.s_power = msm_sensor_power,
-};
-
-static struct v4l2_subdev_video_ops ov5647_subdev_video_ops = {
-	.enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
-};
-
-static struct v4l2_subdev_ops ov5647_subdev_ops = {
-	.core = &ov5647_subdev_core_ops,
-	.video  = &ov5647_subdev_video_ops,
-};
-
-int32_t ov5647_sensor_power_down(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	struct msm_camera_sensor_info *info = NULL;
-	unsigned short rdata;
-	int rc;
-
-	info = s_ctrl->sensordata;
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		0x4202, 0xf,
-		MSM_CAMERA_I2C_BYTE_DATA);
-	msleep(20);
-	rc = msm_camera_i2c_read(s_ctrl->sensor_i2c_client, 0x3018,
-			&rdata, MSM_CAMERA_I2C_WORD_DATA);
-	CDBG("ov5647_sensor_power_down: %d\n", rc);
-	rdata |= 0x18;
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		0x3018, rdata,
-		MSM_CAMERA_I2C_WORD_DATA);
-	msleep(20);
-	gpio_direction_output(info->sensor_pwd, 1);
-	usleep_range(5000, 5100);
-	msm_sensor_power_down(s_ctrl);
-	return 0;
-}
-
-int32_t ov5647_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	int32_t rc = 0;
-	struct msm_camera_sensor_info *info = NULL;
-
-	info = s_ctrl->sensordata;
-	gpio_direction_output(info->sensor_pwd, 1);
-	gpio_direction_output(info->sensor_reset, 0);
-	usleep_range(10000, 11000);
-	rc = msm_sensor_power_up(s_ctrl);
-	if (rc < 0) {
-		CDBG("%s: msm_sensor_power_up failed\n", __func__);
-		return rc;
-	}
-
-	/* turn on ldo and vreg */
-
-	gpio_direction_output(info->sensor_pwd, 0);
-	msleep(20);
-	gpio_direction_output(info->sensor_reset, 1);
-	msleep(25);
-
-	return rc;
-
-}
-
-static int32_t vfe_clk = 266667000;
-
-static void ov5647_stop_stream(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	msm_camera_i2c_write_tbl(
-		s_ctrl->sensor_i2c_client,
-		s_ctrl->msm_sensor_reg->stop_stream_conf,
-		s_ctrl->msm_sensor_reg->stop_stream_conf_size,
-		s_ctrl->msm_sensor_reg->default_data_type);
-
-	if (s_ctrl->curr_res == MSM_SENSOR_RES_FULL)
-		msleep(66);
-	else
-		msleep(266);
-
-	msm_camera_i2c_write(
-			s_ctrl->sensor_i2c_client,
-			0x4800, 0x25,
-			MSM_CAMERA_I2C_BYTE_DATA);
-}
-
-int32_t ov5647_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
-			int update_type, int res)
-{
-	int32_t rc = 0;
-	if (update_type == MSM_SENSOR_REG_INIT) {
-		CDBG("Register INIT\n");
-		s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
-		msm_camera_i2c_write(
-				s_ctrl->sensor_i2c_client,
-				0x103, 0x1,
-				MSM_CAMERA_I2C_BYTE_DATA);
-		msm_sensor_enable_debugfs(s_ctrl);
-		msm_sensor_write_init_settings(s_ctrl);
-	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
-		CDBG("PERIODIC : %d\n", res);
-		msm_sensor_write_conf_array(
-			s_ctrl->sensor_i2c_client,
-			s_ctrl->msm_sensor_reg->mode_settings, res);
-		msleep(30);
-		msm_camera_i2c_write(
-			s_ctrl->sensor_i2c_client,
-			0x100, 0x1,
-			MSM_CAMERA_I2C_BYTE_DATA);
-		msm_camera_i2c_write(
-			s_ctrl->sensor_i2c_client,
-			0x4800, 0x4,
-			MSM_CAMERA_I2C_BYTE_DATA);
-		msleep(266);
-		if (res == MSM_SENSOR_RES_4)
-			v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
-					NOTIFY_PCLK_CHANGE,
-					&vfe_clk);
-	}
-	return rc;
-}
-static struct msm_sensor_fn_t ov5647_func_tbl = {
-	.sensor_start_stream = msm_sensor_start_stream,
-	.sensor_stop_stream = ov5647_stop_stream,
-	.sensor_group_hold_on = msm_sensor_group_hold_on,
-	.sensor_group_hold_off = msm_sensor_group_hold_off,
-	.sensor_set_fps = msm_sensor_set_fps,
-	.sensor_write_exp_gain = ov5647_write_prev_exp_gain,
-	.sensor_write_snapshot_exp_gain = ov5647_write_pict_exp_gain,
-	.sensor_csi_setting = ov5647_sensor_setting,
-	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
-	.sensor_mode_init = msm_sensor_mode_init,
-	.sensor_get_output_info = msm_sensor_get_output_info,
-	.sensor_config = msm_sensor_config,
-	.sensor_power_up = ov5647_sensor_power_up,
-	.sensor_power_down = ov5647_sensor_power_down,
-};
-
-static struct msm_sensor_reg_t ov5647_regs = {
-	.default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
-	.start_stream_conf = ov5647_start_settings,
-	.start_stream_conf_size = ARRAY_SIZE(ov5647_start_settings),
-	.stop_stream_conf = ov5647_stop_settings,
-	.stop_stream_conf_size = ARRAY_SIZE(ov5647_stop_settings),
-	.group_hold_on_conf = ov5647_groupon_settings,
-	.group_hold_on_conf_size = ARRAY_SIZE(ov5647_groupon_settings),
-	.group_hold_off_conf = ov5647_groupoff_settings,
-	.group_hold_off_conf_size =
-		ARRAY_SIZE(ov5647_groupoff_settings),
-	.init_settings = &ov5647_init_conf[0],
-	.init_size = ARRAY_SIZE(ov5647_init_conf),
-	.mode_settings = &ov5647_confs[0],
-	.output_settings = &ov5647_dimensions[0],
-	.num_conf = ARRAY_SIZE(ov5647_confs),
-};
-
-static struct msm_sensor_ctrl_t ov5647_s_ctrl = {
-	.msm_sensor_reg = &ov5647_regs,
-	.sensor_i2c_client = &ov5647_sensor_i2c_client,
-	.sensor_i2c_addr =  0x36 << 1 ,
-	.sensor_output_reg_addr = &ov5647_reg_addr,
-	.sensor_id_info = &ov5647_id_info,
-	.sensor_exp_gain_info = &ov5647_exp_gain_info,
-	.cam_mode = MSM_SENSOR_MODE_INVALID,
-	.msm_sensor_mutex = &ov5647_mut,
-	.sensor_i2c_driver = &ov5647_i2c_driver,
-	.sensor_v4l2_subdev_info = ov5647_subdev_info,
-	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(ov5647_subdev_info),
-	.sensor_v4l2_subdev_ops = &ov5647_subdev_ops,
-	.func_tbl = &ov5647_func_tbl,
-	.clk_rate = MSM_SENSOR_MCLK_24HZ,
-};
-
-module_init(msm_sensor_init_module);
-MODULE_DESCRIPTION("Omnivision WXGA Bayer sensor driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/sensors/ov7692_v4l2.c b/drivers/media/video/msm/sensors/ov7692_v4l2.c
deleted file mode 100644
index e0d4b53f..0000000
--- a/drivers/media/video/msm/sensors/ov7692_v4l2.c
+++ /dev/null
@@ -1,926 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 "msm_sensor.h"
-#define SENSOR_NAME "ov7692"
-
-DEFINE_MUTEX(ov7692_mut);
-static struct msm_sensor_ctrl_t ov7692_s_ctrl;
-
-static int effect_value = CAMERA_EFFECT_OFF;
-static unsigned int SAT_U = 0x80; /* DEFAULT SATURATION VALUES*/
-static unsigned int SAT_V = 0x80; /* DEFAULT SATURATION VALUES*/
-
-static struct msm_camera_i2c_reg_conf ov7692_start_settings[] = {
-	{0x0e, 0x00},
-};
-
-static struct msm_camera_i2c_reg_conf ov7692_stop_settings[] = {
-	{0x0e, 0x08},
-};
-
-static struct msm_camera_i2c_reg_conf ov7692_recommend_settings[] = {
-	{0x12, 0x80},
-	{0x0e, 0x08},
-	{0x69, 0x52},
-	{0x1e, 0xb3},
-	{0x48, 0x42},
-	{0xff, 0x01},
-	{0xae, 0xa0},
-	{0xa8, 0x26},
-	{0xb4, 0xc0},
-	{0xb5, 0x40},
-	{0xff, 0x00},
-	{0x0c, 0x00},
-	{0x62, 0x10},
-	{0x12, 0x00},
-	{0x17, 0x65},
-	{0x18, 0xa4},
-	{0x19, 0x0a},
-	{0x1a, 0xf6},
-	{0x3e, 0x30},
-	{0x64, 0x0a},
-	{0xff, 0x01},
-	{0xb4, 0xc0},
-	{0xff, 0x00},
-	{0x67, 0x20},
-	{0x81, 0x3f},
-	{0xd0, 0x48},
-	{0x82, 0x03},
-	{0x70, 0x00},
-	{0x71, 0x34},
-	{0x74, 0x28},
-	{0x75, 0x98},
-	{0x76, 0x00},
-	{0x77, 0x64},
-	{0x78, 0x01},
-	{0x79, 0xc2},
-	{0x7a, 0x4e},
-	{0x7b, 0x1f},
-	{0x7c, 0x00},
-	{0x11, 0x00},
-	{0x20, 0x00},
-	{0x21, 0x23},
-	{0x50, 0x9a},
-	{0x51, 0x80},
-	{0x4c, 0x7d},
-	{0x85, 0x10},
-	{0x86, 0x00},
-	{0x87, 0x00},
-	{0x88, 0x00},
-	{0x89, 0x2a},
-	{0x8a, 0x26},
-	{0x8b, 0x22},
-	{0xbb, 0x7a},
-	{0xbc, 0x69},
-	{0xbd, 0x11},
-	{0xbe, 0x13},
-	{0xbf, 0x81},
-	{0xc0, 0x96},
-	{0xc1, 0x1e},
-	{0xb7, 0x05},
-	{0xb8, 0x09},
-	{0xb9, 0x00},
-	{0xba, 0x18},
-	{0x5a, 0x1f},
-	{0x5b, 0x9f},
-	{0x5c, 0x6a},
-	{0x5d, 0x42},
-	{0x24, 0x78},
-	{0x25, 0x68},
-	{0x26, 0xb3},
-	{0xa3, 0x0b},
-	{0xa4, 0x15},
-	{0xa5, 0x2a},
-	{0xa6, 0x51},
-	{0xa7, 0x63},
-	{0xa8, 0x74},
-	{0xa9, 0x83},
-	{0xaa, 0x91},
-	{0xab, 0x9e},
-	{0xac, 0xaa},
-	{0xad, 0xbe},
-	{0xae, 0xce},
-	{0xaf, 0xe5},
-	{0xb0, 0xf3},
-	{0xb1, 0xfb},
-	{0xb2, 0x06},
-	{0x8c, 0x5c},
-	{0x8d, 0x11},
-	{0x8e, 0x12},
-	{0x8f, 0x19},
-	{0x90, 0x50},
-	{0x91, 0x20},
-	{0x92, 0x96},
-	{0x93, 0x80},
-	{0x94, 0x13},
-	{0x95, 0x1b},
-	{0x96, 0xff},
-	{0x97, 0x00},
-	{0x98, 0x3d},
-	{0x99, 0x36},
-	{0x9a, 0x51},
-	{0x9b, 0x43},
-	{0x9c, 0xf0},
-	{0x9d, 0xf0},
-	{0x9e, 0xf0},
-	{0x9f, 0xff},
-	{0xa0, 0x68},
-	{0xa1, 0x62},
-	{0xa2, 0x0e},
-};
-
-static struct msm_camera_i2c_reg_conf ov7692_full_settings[] = {
-	{0xcc, 0x02},
-	{0xcd, 0x80},
-	{0xce, 0x01},
-	{0xcf, 0xe0},
-	{0xc8, 0x02},
-	{0xc9, 0x80},
-	{0xca, 0x01},
-	{0xcb, 0xe0},
-};
-
-static struct v4l2_subdev_info ov7692_subdev_info[] = {
-	{
-		.code   = V4L2_MBUS_FMT_YUYV8_2X8,
-		.colorspace = V4L2_COLORSPACE_JPEG,
-		.fmt    = 1,
-		.order    = 0,
-	},
-	/* more can be supported, to be added later */
-};
-
-
-static struct msm_camera_i2c_conf_array ov7692_init_conf[] = {
-	{&ov7692_recommend_settings[0],
-	ARRAY_SIZE(ov7692_recommend_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}
-};
-
-static struct msm_camera_i2c_conf_array ov7692_confs[] = {
-	{&ov7692_full_settings[0],
-	ARRAY_SIZE(ov7692_full_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
-};
-
-static struct msm_camera_i2c_reg_conf ov7692_saturation[][4] = {
-	{{0x81, 0x33, 0x00, 0x00, 0xCC}, {0xd8, 0x00, 0x00, 0x00, 0x00},
-		{0xd9, 0x00, 0x00, 0x00, 0x00},
-		{0xd2, 0x02, 0x00, 0x00, 0x00},},/* SATURATION LEVEL0*/
-	{{0x81, 0x33, 0x00, 0x00, 0xCC}, {0xd8, 0x10, 0x00, 0x00, 0x00},
-		{0xd9, 0x10, 0x00, 0x00, 0x00},
-		{0xd2, 0x02, 0x00, 0x00, 0x00},},	/* SATURATION LEVEL1*/
-	{{0x81, 0x33, 0x00, 0x00, 0xCC}, {0xd8, 0x20, 0x00, 0x00, 0x00},
-		{0xd9, 0x20, 0x00, 0x00, 0x00},
-		{0xd2, 0x02, 0x00, 0x00, 0x00},},	/* SATURATION LEVEL2*/
-	{{0x81, 0x33, 0x00, 0x00, 0xCC}, {0xd8, 0x30, 0x00, 0x00, 0x00},
-		{0xd9, 0x30, 0x00, 0x00, 0x00},
-		{0xd2, 0x02, 0x00, 0x00, 0x00},},	/* SATURATION LEVEL3*/
-	{{0x81, 0x33, 0x00, 0x00, 0xCC}, {0xd8, 0x40, 0x00, 0x00, 0x00},
-		{0xd9, 0x40, 0x00, 0x00, 0x00},
-		{0xd2, 0x02, 0x00, 0x00, 0x00},},	/* SATURATION LEVEL4*/
-	{{0x81, 0x33, 0x00, 0x00, 0xCC}, {0xd8, 0x50, 0x00, 0x00, 0x00},
-		{0xd9, 0x50, 0x00, 0x00, 0x00},
-		{0xd2, 0x02, 0x00, 0x00, 0x00},},	/* SATURATION LEVEL5*/
-	{{0x81, 0x33, 0x00, 0x00, 0xCC}, {0xd8, 0x60, 0x00, 0x00, 0x00},
-		{0xd9, 0x60, 0x00, 0x00, 0x00},
-		{0xd2, 0x02, 0x00, 0x00, 0x00},},	/* SATURATION LEVEL6*/
-	{{0x81, 0x33, 0x00, 0x00, 0xCC}, {0xd8, 0x70, 0x00, 0x00, 0x00},
-		{0xd9, 0x70, 0x00, 0x00, 0x00},
-		{0xd2, 0x02, 0x00, 0x00, 0x00},},	/* SATURATION LEVEL7*/
-	{{0x81, 0x33, 0x00, 0x00, 0xCC}, {0xd8, 0x80, 0x00, 0x00, 0x00},
-		{0xd9, 0x80, 0x00, 0x00, 0x00},
-		{0xd2, 0x02, 0x00, 0x00, 0x00},},	/* SATURATION LEVEL8*/
-};
-static struct msm_camera_i2c_conf_array ov7692_saturation_confs[][1] = {
-	{{ov7692_saturation[0], ARRAY_SIZE(ov7692_saturation[0]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_saturation[1], ARRAY_SIZE(ov7692_saturation[1]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_saturation[2], ARRAY_SIZE(ov7692_saturation[2]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_saturation[3], ARRAY_SIZE(ov7692_saturation[3]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_saturation[4], ARRAY_SIZE(ov7692_saturation[4]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_saturation[5], ARRAY_SIZE(ov7692_saturation[5]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_saturation[6], ARRAY_SIZE(ov7692_saturation[6]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_saturation[7], ARRAY_SIZE(ov7692_saturation[7]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_saturation[8], ARRAY_SIZE(ov7692_saturation[8]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-};
-
-static int ov7692_saturation_enum_map[] = {
-	MSM_V4L2_SATURATION_L0,
-	MSM_V4L2_SATURATION_L1,
-	MSM_V4L2_SATURATION_L2,
-	MSM_V4L2_SATURATION_L3,
-	MSM_V4L2_SATURATION_L4,
-	MSM_V4L2_SATURATION_L5,
-	MSM_V4L2_SATURATION_L6,
-	MSM_V4L2_SATURATION_L7,
-	MSM_V4L2_SATURATION_L8,
-};
-static struct msm_sensor_output_info_t ov7692_dimensions[] = {
-	{
-		.x_output = 0x280,
-		.y_output = 0x1E0,
-		.line_length_pclk = 0x290,
-		.frame_length_lines = 0x1EC,
-		.vt_pixel_clk = 9216000,
-		.op_pixel_clk = 9216000,
-		.binning_factor = 1,
-	},
-};
-
-static struct msm_camera_i2c_enum_conf_array ov7692_saturation_enum_confs = {
-	.conf = &ov7692_saturation_confs[0][0],
-	.conf_enum = ov7692_saturation_enum_map,
-	.num_enum = ARRAY_SIZE(ov7692_saturation_enum_map),
-	.num_index = ARRAY_SIZE(ov7692_saturation_confs),
-	.num_conf = ARRAY_SIZE(ov7692_saturation_confs[0]),
-	.data_type = MSM_CAMERA_I2C_BYTE_DATA,
-};
-
-static struct msm_camera_i2c_reg_conf ov7692_contrast[][16] = {
-	{{0xb2, 0x29}, {0xa3, 0x55}, {0xa4, 0x5b}, {0xa5, 0x67}, {0xa6, 0x7e},
-		{0xa7, 0x89}, {0xa8, 0x93}, {0xa9, 0x9c}, {0xaa, 0xa4},
-		{0xab, 0xac}, {0xac, 0xb3}, {0xad, 0xbe}, {0xae, 0xc7},
-		{0xaf, 0xd5}, {0xb0, 0xdd}, {0xb1, 0xe1},},	/* CONTRAST L0*/
-	{{0xb2, 0x20}, {0xa3, 0x43}, {0xa4, 0x4a}, {0xa5, 0x58}, {0xa6, 0x73},
-		{0xa7, 0x80}, {0xa8, 0x8b}, {0xa9, 0x96}, {0xaa, 0x9f},
-		{0xab, 0xa8}, {0xac, 0xb1}, {0xad, 0xbe}, {0xae, 0xc9},
-		{0xaf, 0xd8}, {0xb0, 0xe2}, {0xb1, 0xe8},},	/* CONTRAST L1*/
-	{{0xb2, 0x18}, {0xa3, 0x31}, {0xa4, 0x39}, {0xa5, 0x4a}, {0xa6, 0x68},
-		{0xa7, 0x77}, {0xa8, 0x84}, {0xa9, 0x90}, {0xaa, 0x9b},
-		{0xab, 0xa5}, {0xac, 0xaf}, {0xad, 0xbe}, {0xae, 0xca},
-		{0xaf, 0xdc}, {0xb0, 0xe7}, {0xb1, 0xee},},	/* CONTRAST L2*/
-	{{0xb2, 0x10}, {0xa3, 0x1f}, {0xa4, 0x28}, {0xa5, 0x3b}, {0xa6, 0x5d},
-		{0xa7, 0x6e}, {0xa8, 0x7d}, {0xa9, 0x8a}, {0xaa, 0x96},
-		{0xab, 0xa2}, {0xac, 0xad}, {0xad, 0xbe}, {0xae, 0xcc},
-		{0xaf, 0xe0}, {0xb0, 0xed}, {0xb1, 0xf4},},	/* CONTRAST L3*/
-	 {{0xb2, 0x6}, {0xa3, 0xb}, {0xa4, 0x15}, {0xa5, 0x2a}, {0xa6, 0x51},
-		{0xa7, 0x63}, {0xa8, 0x74}, {0xa9, 0x83}, {0xaa, 0x91},
-		{0xab, 0x9e}, {0xac, 0xaa}, {0xad, 0xbe}, {0xae, 0xce},
-		{0xaf, 0xe5}, {0xb0, 0xf3}, {0xb1, 0xfb},},	/* CONTRAST L4*/
-	{{0xb2, 0xc}, {0xa3, 0x4}, {0xa4, 0xc}, {0xa5, 0x1f}, {0xa6, 0x45},
-		{0xa7, 0x58}, {0xa8, 0x6b}, {0xa9, 0x7c}, {0xaa, 0x8d},
-		{0xab, 0x9d}, {0xac, 0xac}, {0xad, 0xc3}, {0xae, 0xd2},
-		{0xaf, 0xe8}, {0xb0, 0xf2}, {0xb1, 0xf7},},	/* CONTRAST L5*/
-	{{0xb2, 0x1}, {0xa3, 0x2}, {0xa4, 0x9}, {0xa5, 0x1a}, {0xa6, 0x3e},
-		{0xa7, 0x4a}, {0xa8, 0x59}, {0xa9, 0x6a}, {0xaa, 0x79},
-		{0xab, 0x8e}, {0xac, 0xa4}, {0xad, 0xc1}, {0xae, 0xdb},
-		{0xaf, 0xf4}, {0xb0, 0xff}, {0xb1, 0xff},},	/* CONTRAST L6*/
-	{{0xb2, 0xc}, {0xa3, 0x4}, {0xa4, 0x8}, {0xa5, 0x17}, {0xa6, 0x27},
-		{0xa7, 0x3d}, {0xa8, 0x54}, {0xa9, 0x60}, {0xaa, 0x77},
-		{0xab, 0x85}, {0xac, 0xa4}, {0xad, 0xc6}, {0xae, 0xd2},
-		{0xaf, 0xe9}, {0xb0, 0xf0}, {0xb1, 0xf7},},	/* CONTRAST L7*/
-	{{0xb2, 0x1}, {0xa3, 0x4}, {0xa4, 0x4}, {0xa5, 0x7}, {0xa6, 0xb},
-		{0xa7, 0x17}, {0xa8, 0x2a}, {0xa9, 0x41}, {0xaa, 0x59},
-		{0xab, 0x6b}, {0xac, 0x8b}, {0xad, 0xb1}, {0xae, 0xd2},
-		{0xaf, 0xea}, {0xb0, 0xf4}, {0xb1, 0xff},},	/* CONTRAST L8*/
-};
-
-static struct msm_camera_i2c_conf_array ov7692_contrast_confs[][1] = {
-	{{ov7692_contrast[0], ARRAY_SIZE(ov7692_contrast[0]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_contrast[1], ARRAY_SIZE(ov7692_contrast[1]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_contrast[2], ARRAY_SIZE(ov7692_contrast[2]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_contrast[3], ARRAY_SIZE(ov7692_contrast[3]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_contrast[4], ARRAY_SIZE(ov7692_contrast[4]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_contrast[5], ARRAY_SIZE(ov7692_contrast[5]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_contrast[6], ARRAY_SIZE(ov7692_contrast[6]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_contrast[7], ARRAY_SIZE(ov7692_contrast[7]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_contrast[8], ARRAY_SIZE(ov7692_contrast[8]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-};
-
-
-static int ov7692_contrast_enum_map[] = {
-	MSM_V4L2_CONTRAST_L0,
-	MSM_V4L2_CONTRAST_L1,
-	MSM_V4L2_CONTRAST_L2,
-	MSM_V4L2_CONTRAST_L3,
-	MSM_V4L2_CONTRAST_L4,
-	MSM_V4L2_CONTRAST_L5,
-	MSM_V4L2_CONTRAST_L6,
-	MSM_V4L2_CONTRAST_L7,
-	MSM_V4L2_CONTRAST_L8,
-};
-
-static struct msm_camera_i2c_enum_conf_array ov7692_contrast_enum_confs = {
-	.conf = &ov7692_contrast_confs[0][0],
-	.conf_enum = ov7692_contrast_enum_map,
-	.num_enum = ARRAY_SIZE(ov7692_contrast_enum_map),
-	.num_index = ARRAY_SIZE(ov7692_contrast_confs),
-	.num_conf = ARRAY_SIZE(ov7692_contrast_confs[0]),
-	.data_type = MSM_CAMERA_I2C_BYTE_DATA,
-};
-static struct msm_camera_i2c_reg_conf ov7692_sharpness[][2] = {
-	{{0xb4, 0x20, 0x00, 0x00, 0xDF},
-		{0xb6, 0x00, 0x00, 0x00, 0xE0},},    /* SHARPNESS LEVEL 0*/
-	{{0xb4, 0x20, 0x00, 0x00, 0xDF},
-		{0xb6, 0x01, 0x00, 0x00, 0xE0},},    /* SHARPNESS LEVEL 1*/
-	{{0xb4, 0x00, 0x00, 0x00, 0xDF},
-		{0xb6, 0x00, 0x00, 0x00, 0xE0},},    /* SHARPNESS LEVEL 2*/
-	{{0xb4, 0x20, 0x00, 0x00, 0xDF},
-		{0xb6, 0x66, 0x00, 0x00, 0xE0},},    /* SHARPNESS LEVEL 3*/
-	{{0xb4, 0x20, 0x00, 0x00, 0xDF},
-		{0xb6, 0x99, 0x00, 0x00, 0xE0},},    /* SHARPNESS LEVEL 4*/
-	{{0xb4, 0x20, 0x00, 0x00, 0xDF},
-		{0xb6, 0xcc, 0x00, 0x00, 0xE0},},    /* SHARPNESS LEVEL 5*/
-};
-
-static struct msm_camera_i2c_conf_array ov7692_sharpness_confs[][1] = {
-	{{ov7692_sharpness[0], ARRAY_SIZE(ov7692_sharpness[0]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_sharpness[1], ARRAY_SIZE(ov7692_sharpness[1]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_sharpness[2], ARRAY_SIZE(ov7692_sharpness[2]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_sharpness[3], ARRAY_SIZE(ov7692_sharpness[3]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_sharpness[4], ARRAY_SIZE(ov7692_sharpness[4]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_sharpness[5], ARRAY_SIZE(ov7692_sharpness[5]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-};
-
-static int ov7692_sharpness_enum_map[] = {
-	MSM_V4L2_SHARPNESS_L0,
-	MSM_V4L2_SHARPNESS_L1,
-	MSM_V4L2_SHARPNESS_L2,
-	MSM_V4L2_SHARPNESS_L3,
-	MSM_V4L2_SHARPNESS_L4,
-	MSM_V4L2_SHARPNESS_L5,
-};
-
-static struct msm_camera_i2c_enum_conf_array ov7692_sharpness_enum_confs = {
-	.conf = &ov7692_sharpness_confs[0][0],
-	.conf_enum = ov7692_sharpness_enum_map,
-	.num_enum = ARRAY_SIZE(ov7692_sharpness_enum_map),
-	.num_index = ARRAY_SIZE(ov7692_sharpness_confs),
-	.num_conf = ARRAY_SIZE(ov7692_sharpness_confs[0]),
-	.data_type = MSM_CAMERA_I2C_BYTE_DATA,
-};
-
-static struct msm_camera_i2c_reg_conf ov7692_exposure[][3] = {
-	{{0x24, 0x50}, {0x25, 0x40}, {0x26, 0xa2},}, /*EXPOSURECOMPENSATIONN2*/
-	{{0x24, 0x70}, {0x25, 0x60}, {0x26, 0xa2},}, /*EXPOSURECOMPENSATIONN1*/
-	{{0x24, 0x86}, {0x25, 0x76}, {0x26, 0xb3},}, /*EXPOSURECOMPENSATIOND*/
-	{{0x24, 0xa8}, {0x25, 0xa0}, {0x26, 0xc4},}, /*EXPOSURECOMPENSATIONp1*/
-	{{0x24, 0xc0}, {0x25, 0xb8}, {0x26, 0xe6},}, /*EXPOSURECOMPENSATIONP2*/
-};
-
-static struct msm_camera_i2c_conf_array ov7692_exposure_confs[][1] = {
-	{{ov7692_exposure[0], ARRAY_SIZE(ov7692_exposure[0]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_exposure[1], ARRAY_SIZE(ov7692_exposure[1]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_exposure[2], ARRAY_SIZE(ov7692_exposure[2]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_exposure[3], ARRAY_SIZE(ov7692_exposure[3]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_exposure[4], ARRAY_SIZE(ov7692_exposure[4]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-};
-
-static int ov7692_exposure_enum_map[] = {
-	MSM_V4L2_EXPOSURE_N2,
-	MSM_V4L2_EXPOSURE_N1,
-	MSM_V4L2_EXPOSURE_D,
-	MSM_V4L2_EXPOSURE_P1,
-	MSM_V4L2_EXPOSURE_P2,
-};
-
-static struct msm_camera_i2c_enum_conf_array ov7692_exposure_enum_confs = {
-	.conf = &ov7692_exposure_confs[0][0],
-	.conf_enum = ov7692_exposure_enum_map,
-	.num_enum = ARRAY_SIZE(ov7692_exposure_enum_map),
-	.num_index = ARRAY_SIZE(ov7692_exposure_confs),
-	.num_conf = ARRAY_SIZE(ov7692_exposure_confs[0]),
-	.data_type = MSM_CAMERA_I2C_BYTE_DATA,
-};
-
-static struct msm_camera_i2c_reg_conf ov7692_iso[][1] = {
-	{{0x14, 0x20, 0x00, 0x00, 0x8F},},   /*ISO_AUTO*/
-	{{0x14, 0x20, 0x00, 0x00, 0x8F},},   /*ISO_DEBLUR*/
-	{{0x14, 0x00, 0x00, 0x00, 0x8F},},   /*ISO_100*/
-	{{0x14, 0x10, 0x00, 0x00, 0x8F},},   /*ISO_200*/
-	{{0x14, 0x20, 0x00, 0x00, 0x8F},},   /*ISO_400*/
-	{{0x14, 0x30, 0x00, 0x00, 0x8F},},   /*ISO_800*/
-	{{0x14, 0x40, 0x00, 0x00, 0x8F},},   /*ISO_1600*/
-};
-
-
-static struct msm_camera_i2c_conf_array ov7692_iso_confs[][1] = {
-	{{ov7692_iso[0], ARRAY_SIZE(ov7692_iso[0]),  0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_iso[1], ARRAY_SIZE(ov7692_iso[1]),  0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_iso[2], ARRAY_SIZE(ov7692_iso[2]),  0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_iso[3], ARRAY_SIZE(ov7692_iso[3]),  0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_iso[4], ARRAY_SIZE(ov7692_iso[4]),  0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_iso[5], ARRAY_SIZE(ov7692_iso[5]),  0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-};
-
-static int ov7692_iso_enum_map[] = {
-	MSM_V4L2_ISO_AUTO ,
-	MSM_V4L2_ISO_DEBLUR,
-	MSM_V4L2_ISO_100,
-	MSM_V4L2_ISO_200,
-	MSM_V4L2_ISO_400,
-	MSM_V4L2_ISO_800,
-	MSM_V4L2_ISO_1600,
-};
-
-
-static struct msm_camera_i2c_enum_conf_array ov7692_iso_enum_confs = {
-	.conf = &ov7692_iso_confs[0][0],
-	.conf_enum = ov7692_iso_enum_map,
-	.num_enum = ARRAY_SIZE(ov7692_iso_enum_map),
-	.num_index = ARRAY_SIZE(ov7692_iso_confs),
-	.num_conf = ARRAY_SIZE(ov7692_iso_confs[0]),
-	.data_type = MSM_CAMERA_I2C_BYTE_DATA,
-};
-
-static struct msm_camera_i2c_reg_conf ov7692_no_effect[] = {
-	{0x81, 0x00, 0x00, 0x00, 0xDF},
-	{0x28, 0x00,},
-	{0xd2, 0x00,},
-	{0xda, 0x80,},
-	{0xdb, 0x80,},
-};
-
-static struct msm_camera_i2c_conf_array ov7692_no_effect_confs[] = {
-	{&ov7692_no_effect[0],
-	ARRAY_SIZE(ov7692_no_effect), 0,
-	MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},
-};
-
-static struct msm_camera_i2c_reg_conf ov7692_special_effect[][5] = {
-	{{0x81, 0x20, 0x00, 0x00, 0xDF}, {0x28, 0x00,}, {0xd2, 0x18,},
-		{0xda, 0x80,}, {0xdb, 0x80,},},	/*for special effect OFF*/
-	{{0x81, 0x20, 0x00, 0x00, 0xDF}, {0x28, 0x00,}, {0xd2, 0x18,},
-		{0xda, 0x80,}, {0xdb, 0x80,},},	/*for special effect MONO*/
-	{{0x81, 0x20, 0x00, 0x00, 0xDF}, {0x28, 0x80,}, {0xd2, 0x40,},
-		{0xda, 0x80,}, {0xdb, 0x80,},},	/*for special efefct Negative*/
-	{{-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1},
-		{-1, -1, -1, -1, -1},
-		{-1, -1, -1, -1, -1},},/*Solarize is not supported by sensor*/
-	{{0x81, 0x20, 0x00, 0x00, 0xDF}, {0x28, 0x00,}, {0xd2, 0x18,},
-		{0xda, 0x40,}, {0xdb, 0xa0,},},	/*for sepia*/
-	{{-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1},
-		{-1, -1, -1, -1, -1},
-		{-1, -1, -1, -1, -1},},		/* Posteraize not supported */
-	{{-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1},
-		{-1, -1, -1, -1, -1},
-		{-1, -1, -1, -1, -1},},		/* White board not supported*/
-	{{-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1},
-		{-1, -1, -1, -1, -1},
-		{-1, -1, -1, -1, -1},},		/*Blackboard not supported*/
-	{{-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1},
-		{-1, -1, -1, -1, -1},
-		{-1, -1, -1, -1, -1},},		/*Aqua not supported*/
-	{{-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1},
-		{-1, -1, -1, -1, -1},
-		{-1, -1, -1, -1, -1},},		/*Emboss not supported */
-	{{-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1},
-		{-1, -1, -1, -1, -1},
-		{-1, -1, -1, -1, -1},},		/*sketch not supported*/
-	{{-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1},
-		{-1, -1, -1, -1, -1},
-		{-1, -1, -1, -1, -1},},		/*Neon not supported*/
-	{{-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1},
-		{-1, -1, -1, -1, -1},
-		{-1, -1, -1, -1, -1},},		/*MAX value*/
-};
-
-static struct msm_camera_i2c_conf_array ov7692_special_effect_confs[][1] = {
-	{{ov7692_special_effect[0],  ARRAY_SIZE(ov7692_special_effect[0]),  0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_special_effect[1],  ARRAY_SIZE(ov7692_special_effect[1]),  0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_special_effect[2],  ARRAY_SIZE(ov7692_special_effect[2]),  0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_special_effect[3],  ARRAY_SIZE(ov7692_special_effect[3]),  0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_special_effect[4],  ARRAY_SIZE(ov7692_special_effect[4]),  0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_special_effect[5],  ARRAY_SIZE(ov7692_special_effect[5]),  0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_special_effect[6],  ARRAY_SIZE(ov7692_special_effect[6]),  0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_special_effect[7],  ARRAY_SIZE(ov7692_special_effect[7]),  0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_special_effect[8],  ARRAY_SIZE(ov7692_special_effect[8]),  0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_special_effect[9],  ARRAY_SIZE(ov7692_special_effect[9]),  0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_special_effect[10], ARRAY_SIZE(ov7692_special_effect[10]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_special_effect[11], ARRAY_SIZE(ov7692_special_effect[11]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_special_effect[12], ARRAY_SIZE(ov7692_special_effect[12]), 0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-};
-
-static int ov7692_special_effect_enum_map[] = {
-	MSM_V4L2_EFFECT_OFF,
-	MSM_V4L2_EFFECT_MONO,
-	MSM_V4L2_EFFECT_NEGATIVE,
-	MSM_V4L2_EFFECT_SOLARIZE,
-	MSM_V4L2_EFFECT_SEPIA,
-	MSM_V4L2_EFFECT_POSTERAIZE,
-	MSM_V4L2_EFFECT_WHITEBOARD,
-	MSM_V4L2_EFFECT_BLACKBOARD,
-	MSM_V4L2_EFFECT_AQUA,
-	MSM_V4L2_EFFECT_EMBOSS,
-	MSM_V4L2_EFFECT_SKETCH,
-	MSM_V4L2_EFFECT_NEON,
-	MSM_V4L2_EFFECT_MAX,
-};
-
-static struct msm_camera_i2c_enum_conf_array
-		 ov7692_special_effect_enum_confs = {
-	.conf = &ov7692_special_effect_confs[0][0],
-	.conf_enum = ov7692_special_effect_enum_map,
-	.num_enum = ARRAY_SIZE(ov7692_special_effect_enum_map),
-	.num_index = ARRAY_SIZE(ov7692_special_effect_confs),
-	.num_conf = ARRAY_SIZE(ov7692_special_effect_confs[0]),
-	.data_type = MSM_CAMERA_I2C_BYTE_DATA,
-};
-
-static struct msm_camera_i2c_reg_conf ov7692_antibanding[][2] = {
-	{{0x13, 0x20, 0x00, 0x00, 0xDF},
-		{0x14, 0x16, 0x00, 0x00, 0xE8},},   /*ANTIBANDING 60HZ*/
-	{{0x13, 0x20, 0x00, 0x00, 0xDF},
-		{0x14, 0x17, 0x00, 0x00, 0xE8},},   /*ANTIBANDING 50HZ*/
-	{{0x13, 0x20, 0x00, 0x00, 0xDF},
-		{0x14, 0x14, 0x00, 0x00, 0xE8},},   /* ANTIBANDING AUTO*/
-};
-
-
-static struct msm_camera_i2c_conf_array ov7692_antibanding_confs[][1] = {
-	{{ov7692_antibanding[0], ARRAY_SIZE(ov7692_antibanding[0]),  0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_antibanding[1], ARRAY_SIZE(ov7692_antibanding[1]),  0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_antibanding[2], ARRAY_SIZE(ov7692_antibanding[2]),  0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-};
-
-static int ov7692_antibanding_enum_map[] = {
-	MSM_V4L2_POWER_LINE_60HZ,
-	MSM_V4L2_POWER_LINE_50HZ,
-	MSM_V4L2_POWER_LINE_AUTO,
-};
-
-
-static struct msm_camera_i2c_enum_conf_array ov7692_antibanding_enum_confs = {
-	.conf = &ov7692_antibanding_confs[0][0],
-	.conf_enum = ov7692_antibanding_enum_map,
-	.num_enum = ARRAY_SIZE(ov7692_antibanding_enum_map),
-	.num_index = ARRAY_SIZE(ov7692_antibanding_confs),
-	.num_conf = ARRAY_SIZE(ov7692_antibanding_confs[0]),
-	.data_type = MSM_CAMERA_I2C_BYTE_DATA,
-};
-
-static struct msm_camera_i2c_reg_conf ov7692_wb_oem[][4] = {
-	{{-1, -1, -1, -1 , -1}, {-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1},
-		{-1, -1, -1, -1, -1},},/*WHITEBALNACE OFF*/
-	{{0x13, 0xf7}, {0x15, 0x00}, {-1, -1, -1, -1, -1},
-		{-1, -1, -1, -1, -1},}, /*WHITEBALNACE AUTO*/
-	{{0x13, 0xf5}, {0x01, 0x56}, {0x02, 0x50},
-		{0x15, 0x00},},	/*WHITEBALNACE CUSTOM*/
-	{{0x13, 0xf5}, {0x01, 0x66}, {0x02, 0x40},
-		{0x15, 0x00},},	/*INCANDISCENT*/
-	{{-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1},
-		{-1, -1, -1, -1, -1},},	/*FLOURESECT NOT SUPPORTED */
-	{{0x13, 0xf5}, {0x01, 0x43}, {0x02, 0x5d},
-		{0x15, 0x00},},	/*DAYLIGHT*/
-	{{0x13, 0xf5}, {0x01, 0x48}, {0x02, 0x63},
-		{0x15, 0x00},},	/*CLOUDY*/
-};
-
-static struct msm_camera_i2c_conf_array ov7692_wb_oem_confs[][1] = {
-	{{ov7692_wb_oem[0], ARRAY_SIZE(ov7692_wb_oem[0]),  0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_wb_oem[1], ARRAY_SIZE(ov7692_wb_oem[1]),  0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_wb_oem[2], ARRAY_SIZE(ov7692_wb_oem[2]),  0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_wb_oem[3], ARRAY_SIZE(ov7692_wb_oem[3]),  0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_wb_oem[4], ARRAY_SIZE(ov7692_wb_oem[4]),  0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_wb_oem[5], ARRAY_SIZE(ov7692_wb_oem[5]),  0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-	{{ov7692_wb_oem[6], ARRAY_SIZE(ov7692_wb_oem[6]),  0,
-		MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA},},
-};
-
-static int ov7692_wb_oem_enum_map[] = {
-	MSM_V4L2_WB_OFF,
-	MSM_V4L2_WB_AUTO ,
-	MSM_V4L2_WB_CUSTOM,
-	MSM_V4L2_WB_INCANDESCENT,
-	MSM_V4L2_WB_FLUORESCENT,
-	MSM_V4L2_WB_DAYLIGHT,
-	MSM_V4L2_WB_CLOUDY_DAYLIGHT,
-};
-
-static struct msm_camera_i2c_enum_conf_array ov7692_wb_oem_enum_confs = {
-	.conf = &ov7692_wb_oem_confs[0][0],
-	.conf_enum = ov7692_wb_oem_enum_map,
-	.num_enum = ARRAY_SIZE(ov7692_wb_oem_enum_map),
-	.num_index = ARRAY_SIZE(ov7692_wb_oem_confs),
-	.num_conf = ARRAY_SIZE(ov7692_wb_oem_confs[0]),
-	.data_type = MSM_CAMERA_I2C_BYTE_DATA,
-};
-
-
-int ov7692_saturation_msm_sensor_s_ctrl_by_enum(
-		struct msm_sensor_ctrl_t *s_ctrl,
-		struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value)
-{
-	int rc = 0;
-	if (effect_value == CAMERA_EFFECT_OFF) {
-		rc = msm_sensor_write_enum_conf_array(
-			s_ctrl->sensor_i2c_client,
-			ctrl_info->enum_cfg_settings, value);
-	}
-	if (value <= MSM_V4L2_SATURATION_L8)
-		SAT_U = SAT_V = value * 0x10;
-	CDBG("--CAMERA-- %s ...(End)\n", __func__);
-	return rc;
-}
-
-
-int ov7692_contrast_msm_sensor_s_ctrl_by_enum(
-		struct msm_sensor_ctrl_t *s_ctrl,
-		struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value)
-{
-	int rc = 0;
-	if (effect_value == CAMERA_EFFECT_OFF) {
-		rc = msm_sensor_write_enum_conf_array(
-			s_ctrl->sensor_i2c_client,
-			ctrl_info->enum_cfg_settings, value);
-	}
-	return rc;
-}
-
-int ov7692_sharpness_msm_sensor_s_ctrl_by_enum(
-		struct msm_sensor_ctrl_t *s_ctrl,
-		struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value)
-{
-	int rc = 0;
-	if (effect_value == CAMERA_EFFECT_OFF) {
-		rc = msm_sensor_write_enum_conf_array(
-			s_ctrl->sensor_i2c_client,
-			ctrl_info->enum_cfg_settings, value);
-	}
-	return rc;
-}
-
-int ov7692_effect_msm_sensor_s_ctrl_by_enum(struct msm_sensor_ctrl_t *s_ctrl,
-		struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value)
-{
-	int rc = 0;
-	effect_value = value;
-	if (effect_value == CAMERA_EFFECT_OFF) {
-		rc = msm_sensor_write_conf_array(
-			s_ctrl->sensor_i2c_client,
-			s_ctrl->msm_sensor_reg->no_effect_settings, 0);
-		if (rc < 0) {
-			CDBG("write faield\n");
-			return rc;
-		}
-		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0xda, SAT_U,
-			MSM_CAMERA_I2C_BYTE_DATA);
-		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0xdb, SAT_V,
-			MSM_CAMERA_I2C_BYTE_DATA);
-	} else {
-		rc = msm_sensor_write_enum_conf_array(
-			s_ctrl->sensor_i2c_client,
-			ctrl_info->enum_cfg_settings, value);
-	}
-	return rc;
-}
-
-int ov7692_antibanding_msm_sensor_s_ctrl_by_enum(
-		struct msm_sensor_ctrl_t *s_ctrl,
-		struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value)
-{
-	int rc = 0;
-		return rc;
-}
-
-int ov7692_msm_sensor_s_ctrl_by_enum(struct msm_sensor_ctrl_t *s_ctrl,
-		struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value)
-{
-	int rc = 0;
-	rc = msm_sensor_write_enum_conf_array(
-		s_ctrl->sensor_i2c_client,
-		ctrl_info->enum_cfg_settings, value);
-	if (rc < 0) {
-		CDBG("write faield\n");
-		return rc;
-	}
-	return rc;
-}
-
-struct msm_sensor_v4l2_ctrl_info_t ov7692_v4l2_ctrl_info[] = {
-	{
-		.ctrl_id = V4L2_CID_SATURATION,
-		.min = MSM_V4L2_SATURATION_L0,
-		.max = MSM_V4L2_SATURATION_L8,
-		.step = 1,
-		.enum_cfg_settings = &ov7692_saturation_enum_confs,
-		.s_v4l2_ctrl = ov7692_saturation_msm_sensor_s_ctrl_by_enum,
-	},
-	{
-		.ctrl_id = V4L2_CID_CONTRAST,
-		.min = MSM_V4L2_CONTRAST_L0,
-		.max = MSM_V4L2_CONTRAST_L8,
-		.step = 1,
-		.enum_cfg_settings = &ov7692_contrast_enum_confs,
-		.s_v4l2_ctrl = ov7692_contrast_msm_sensor_s_ctrl_by_enum,
-	},
-	{
-		.ctrl_id = V4L2_CID_SHARPNESS,
-		.min = MSM_V4L2_SHARPNESS_L0,
-		.max = MSM_V4L2_SHARPNESS_L5,
-		.step = 1,
-		.enum_cfg_settings = &ov7692_sharpness_enum_confs,
-		.s_v4l2_ctrl = ov7692_sharpness_msm_sensor_s_ctrl_by_enum,
-	},
-	{
-		.ctrl_id = V4L2_CID_EXPOSURE,
-		.min = MSM_V4L2_EXPOSURE_N2,
-		.max = MSM_V4L2_EXPOSURE_P2,
-		.step = 1,
-		.enum_cfg_settings = &ov7692_exposure_enum_confs,
-		.s_v4l2_ctrl = ov7692_msm_sensor_s_ctrl_by_enum,
-	},
-	{
-		.ctrl_id = MSM_V4L2_PID_ISO,
-		.min = MSM_V4L2_ISO_AUTO,
-		.max = MSM_V4L2_ISO_1600,
-		.step = 1,
-		.enum_cfg_settings = &ov7692_iso_enum_confs,
-		.s_v4l2_ctrl = ov7692_msm_sensor_s_ctrl_by_enum,
-	},
-	{
-		.ctrl_id = V4L2_CID_SPECIAL_EFFECT,
-		.min = MSM_V4L2_EFFECT_OFF,
-		.max = MSM_V4L2_EFFECT_NEGATIVE,
-		.step = 1,
-		.enum_cfg_settings = &ov7692_special_effect_enum_confs,
-		.s_v4l2_ctrl = ov7692_effect_msm_sensor_s_ctrl_by_enum,
-	},
-	{
-		.ctrl_id = V4L2_CID_POWER_LINE_FREQUENCY,
-		.min = MSM_V4L2_POWER_LINE_60HZ,
-		.max = MSM_V4L2_POWER_LINE_AUTO,
-		.step = 1,
-		.enum_cfg_settings = &ov7692_antibanding_enum_confs,
-		.s_v4l2_ctrl = ov7692_antibanding_msm_sensor_s_ctrl_by_enum,
-	},
-	{
-		.ctrl_id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
-		.min = MSM_V4L2_WB_OFF,
-		.max = MSM_V4L2_WB_CLOUDY_DAYLIGHT,
-		.step = 1,
-		.enum_cfg_settings = &ov7692_wb_oem_enum_confs,
-		.s_v4l2_ctrl = ov7692_msm_sensor_s_ctrl_by_enum,
-	},
-
-};
-
-static struct msm_sensor_output_reg_addr_t ov7692_reg_addr = {
-	.x_output = 0xCC,
-	.y_output = 0xCE,
-	.line_length_pclk = 0xC8,
-	.frame_length_lines = 0xCA,
-};
-
-static struct msm_sensor_id_info_t ov7692_id_info = {
-	.sensor_id_reg_addr = 0x0A,
-	.sensor_id = 0x7692,
-};
-
-static const struct i2c_device_id ov7692_i2c_id[] = {
-	{SENSOR_NAME, (kernel_ulong_t)&ov7692_s_ctrl},
-	{ }
-};
-
-
-static struct i2c_driver ov7692_i2c_driver = {
-	.id_table = ov7692_i2c_id,
-	.probe  = msm_sensor_i2c_probe,
-	.driver = {
-		.name = SENSOR_NAME,
-	},
-};
-
-static struct msm_camera_i2c_client ov7692_sensor_i2c_client = {
-	.addr_type = MSM_CAMERA_I2C_BYTE_ADDR,
-};
-
-static int __init msm_sensor_init_module(void)
-{
-	int rc = 0;
-	CDBG("OV7692\n");
-
-	rc = i2c_add_driver(&ov7692_i2c_driver);
-
-	return rc;
-}
-
-static struct v4l2_subdev_core_ops ov7692_subdev_core_ops = {
-	.s_ctrl = msm_sensor_v4l2_s_ctrl,
-	.queryctrl = msm_sensor_v4l2_query_ctrl,
-	.ioctl = msm_sensor_subdev_ioctl,
-	.s_power = msm_sensor_power,
-};
-
-static struct v4l2_subdev_video_ops ov7692_subdev_video_ops = {
-	.enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
-};
-
-static struct v4l2_subdev_ops ov7692_subdev_ops = {
-	.core = &ov7692_subdev_core_ops,
-	.video  = &ov7692_subdev_video_ops,
-};
-
-static struct msm_sensor_fn_t ov7692_func_tbl = {
-	.sensor_start_stream = msm_sensor_start_stream,
-	.sensor_stop_stream = msm_sensor_stop_stream,
-	.sensor_csi_setting = msm_sensor_setting1,
-	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
-	.sensor_mode_init = msm_sensor_mode_init,
-	.sensor_get_output_info = msm_sensor_get_output_info,
-	.sensor_config = msm_sensor_config,
-	.sensor_power_up = msm_sensor_power_up,
-	.sensor_power_down = msm_sensor_power_down,
-};
-
-static struct msm_sensor_reg_t ov7692_regs = {
-	.default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
-	.start_stream_conf = ov7692_start_settings,
-	.start_stream_conf_size = ARRAY_SIZE(ov7692_start_settings),
-	.stop_stream_conf = ov7692_stop_settings,
-	.stop_stream_conf_size = ARRAY_SIZE(ov7692_stop_settings),
-	.init_settings = &ov7692_init_conf[0],
-	.init_size = ARRAY_SIZE(ov7692_init_conf),
-	.mode_settings = &ov7692_confs[0],
-	.no_effect_settings = &ov7692_no_effect_confs[0],
-	.output_settings = &ov7692_dimensions[0],
-	.num_conf = ARRAY_SIZE(ov7692_confs),
-};
-
-static struct msm_sensor_ctrl_t ov7692_s_ctrl = {
-	.msm_sensor_reg = &ov7692_regs,
-	.msm_sensor_v4l2_ctrl_info = ov7692_v4l2_ctrl_info,
-	.num_v4l2_ctrl = ARRAY_SIZE(ov7692_v4l2_ctrl_info),
-	.sensor_i2c_client = &ov7692_sensor_i2c_client,
-	.sensor_i2c_addr = 0x78,
-	.sensor_output_reg_addr = &ov7692_reg_addr,
-	.sensor_id_info = &ov7692_id_info,
-	.cam_mode = MSM_SENSOR_MODE_INVALID,
-	.msm_sensor_mutex = &ov7692_mut,
-	.sensor_i2c_driver = &ov7692_i2c_driver,
-	.sensor_v4l2_subdev_info = ov7692_subdev_info,
-	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(ov7692_subdev_info),
-	.sensor_v4l2_subdev_ops = &ov7692_subdev_ops,
-	.func_tbl = &ov7692_func_tbl,
-	.clk_rate = MSM_SENSOR_MCLK_24HZ,
-};
-
-module_init(msm_sensor_init_module);
-MODULE_DESCRIPTION("Omnivision VGA YUV sensor driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/sensors/ov8825_v4l2.c b/drivers/media/video/msm/sensors/ov8825_v4l2.c
deleted file mode 100644
index 092ee72..0000000
--- a/drivers/media/video/msm/sensors/ov8825_v4l2.c
+++ /dev/null
@@ -1,937 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 "msm_sensor.h"
-#include "msm.h"
-#define SENSOR_NAME "ov8825"
-#define PLATFORM_DRIVER_NAME "msm_camera_ov8825"
-#define ov8825_obj ov8825_##obj
-
-/* TO DO - Currently ov5647 typical values are used
- * Need to get the exact values */
-#define OV8825_RG_RATIO_TYPICAL_VALUE 64 /* R/G of typical camera module */
-#define OV8825_BG_RATIO_TYPICAL_VALUE 105 /* B/G of typical camera module */
-
-DEFINE_MUTEX(ov8825_mut);
-static struct msm_sensor_ctrl_t ov8825_s_ctrl;
-
-struct otp_struct {
-	uint8_t customer_id;
-	uint8_t module_integrator_id;
-	uint8_t lens_id;
-	uint8_t rg_ratio;
-	uint8_t bg_ratio;
-	uint8_t user_data[5];
-} st_ov8825_otp;
-
-static struct msm_camera_i2c_reg_conf ov8825_start_settings[] = {
-	{0x0100, 0x01},
-};
-
-static struct msm_camera_i2c_reg_conf ov8825_stop_settings[] = {
-	{0x0100, 0x00},
-};
-
-static struct msm_camera_i2c_reg_conf ov8825_groupon_settings[] = {
-	{0x3208, 0x00},
-};
-
-static struct msm_camera_i2c_reg_conf ov8825_groupoff_settings[] = {
-	{0x3208, 0x10},
-	{0x3208, 0xA0},
-};
-
-static struct msm_camera_i2c_reg_conf ov8825_prev_settings[] = {
-	{0x3003, 0xce}, /*PLL_CTRL0*/
-	{0x3004, 0xd4}, /*PLL_CTRL1*/
-	{0x3005, 0x00}, /*PLL_CTRL2*/
-	{0x3006, 0x10}, /*PLL_CTRL3*/
-	{0x3007, 0x3b}, /*PLL_CTRL4*/
-	{0x3011, 0x01}, /*MIPI_Lane_4_Lane*/
-	{0x3012, 0x80}, /*SC_PLL CTRL_S0*/
-	{0x3013, 0x39}, /*SC_PLL CTRL_S1*/
-	{0x3104, 0x20}, /*SCCB_PLL*/
-	{0x3106, 0x15}, /*SRB_CTRL*/
-	{0x3501, 0x4e}, /*AEC_HIGH*/
-	{0x3502, 0xa0}, /*AEC_LOW*/
-	{0x350b, 0x1f}, /*AGC*/
-	{0x3600, 0x06}, /*ANACTRL0*/
-	{0x3601, 0x34}, /*ANACTRL1*/
-	{0x3700, 0x20}, /*SENCTROL0 Sensor control*/
-	{0x3702, 0x50}, /*SENCTROL2 Sensor control*/
-	{0x3703, 0xcc}, /*SENCTROL3 Sensor control*/
-	{0x3704, 0x19}, /*SENCTROL4 Sensor control*/
-	{0x3705, 0x14}, /*SENCTROL5 Sensor control*/
-	{0x3706, 0x4b}, /*SENCTROL6 Sensor control*/
-	{0x3707, 0x63}, /*SENCTROL7 Sensor control*/
-	{0x3708, 0x84}, /*SENCTROL8 Sensor control*/
-	{0x3709, 0x40}, /*SENCTROL9 Sensor control*/
-	{0x370a, 0x12}, /*SENCTROLA Sensor control*/
-	{0x370e, 0x00}, /*SENCTROLE Sensor control*/
-	{0x3711, 0x0f}, /*SENCTROL11 Sensor control*/
-	{0x3712, 0x9c}, /*SENCTROL12 Sensor control*/
-	{0x3724, 0x01}, /*Reserved*/
-	{0x3725, 0x92}, /*Reserved*/
-	{0x3726, 0x01}, /*Reserved*/
-	{0x3727, 0xa9}, /*Reserved*/
-	{0x3800, 0x00}, /*HS(HREF start High)*/
-	{0x3801, 0x00}, /*HS(HREF start Low)*/
-	{0x3802, 0x00}, /*VS(Vertical start High)*/
-	{0x3803, 0x00}, /*VS(Vertical start Low)*/
-	{0x3804, 0x0c}, /*HW = 3295*/
-	{0x3805, 0xdf}, /*HW*/
-	{0x3806, 0x09}, /*VH = 2459*/
-	{0x3807, 0x9b}, /*VH*/
-	{0x3808, 0x06}, /*ISPHO = 1632*/
-	{0x3809, 0x60}, /*ISPHO*/
-	{0x380a, 0x04}, /*ISPVO = 1224*/
-	{0x380b, 0xc8}, /*ISPVO*/
-	{0x380c, 0x0d}, /*HTS = 3516*/
-	{0x380d, 0xbc}, /*HTS*/
-	{0x380e, 0x04}, /*VTS = 1264*/
-	{0x380f, 0xf0}, /*VTS*/
-	{0x3810, 0x00}, /*HOFF = 8*/
-	{0x3811, 0x08}, /*HOFF*/
-	{0x3812, 0x00}, /*VOFF = 4*/
-	{0x3813, 0x04}, /*VOFF*/
-	{0x3814, 0x31}, /*X INC*/
-	{0x3815, 0x31}, /*Y INC*/
-	{0x3820, 0x81}, /*Timing Reg20:Vflip*/
-	{0x3821, 0x17}, /*Timing Reg21:Hmirror*/
-	{0x3f00, 0x00}, /*PSRAM Ctrl0*/
-	{0x3f01, 0xfc}, /*PSRAM Ctrl1*/
-	{0x3f05, 0x10}, /*PSRAM Ctrl5*/
-	{0x4600, 0x04}, /*VFIFO Ctrl0*/
-	{0x4601, 0x00}, /*VFIFO Read ST High*/
-	{0x4602, 0x30}, /*VFIFO Read ST Low*/
-	{0x4837, 0x28}, /*MIPI PCLK PERIOD*/
-	{0x5068, 0x00}, /*HSCALE_CTRL*/
-	{0x506a, 0x00}, /*VSCALE_CTRL*/
-	{0x5c00, 0x80}, /*PBLC CTRL00*/
-	{0x5c01, 0x00}, /*PBLC CTRL01*/
-	{0x5c02, 0x00}, /*PBLC CTRL02*/
-	{0x5c03, 0x00}, /*PBLC CTRL03*/
-	{0x5c04, 0x00}, /*PBLC CTRL04*/
-	{0x5c08, 0x10}, /*PBLC CTRL08*/
-	{0x6900, 0x61}, /*CADC CTRL00*/
-};
-
-static struct msm_camera_i2c_reg_conf ov8825_snap_settings[] = {
-	{0x3003, 0xce}, /*PLL_CTRL0*/
-	{0x3004, 0xd8}, /*PLL_CTRL1*/
-	{0x3005, 0x00}, /*PLL_CTRL2*/
-	{0x3006, 0x10}, /*PLL_CTRL3*/
-	{0x3007, 0x3b}, /*PLL_CTRL4*/
-	{0x3011, 0x01}, /*MIPI_Lane_4_Lane*/
-	{0x3012, 0x81}, /*SC_PLL CTRL_S0*/
-	{0x3013, 0x39}, /*SC_PLL CTRL_S1*/
-	{0x3104, 0x20}, /*SCCB_PLL*/
-	{0x3106, 0x11}, /*SRB_CTRL*/
-	{0x3501, 0x9a}, /*AEC_HIGH*/
-	{0x3502, 0xa0}, /*AEC_LOW*/
-	{0x350b, 0x1f}, /*AGC*/
-	{0x3600, 0x07}, /*ANACTRL0*/
-	{0x3601, 0x33}, /*ANACTRL1*/
-	{0x3700, 0x10}, /*SENCTROL0 Sensor control*/
-	{0x3702, 0x28}, /*SENCTROL2 Sensor control*/
-	{0x3703, 0x6c}, /*SENCTROL3 Sensor control*/
-	{0x3704, 0x8d}, /*SENCTROL4 Sensor control*/
-	{0x3705, 0x0a}, /*SENCTROL5 Sensor control*/
-	{0x3706, 0x27}, /*SENCTROL6 Sensor control*/
-	{0x3707, 0x63}, /*SENCTROL7 Sensor control*/
-	{0x3708, 0x40}, /*SENCTROL8 Sensor control*/
-	{0x3709, 0x20}, /*SENCTROL9 Sensor control*/
-	{0x370a, 0x12}, /*SENCTROLA Sensor control*/
-	{0x370e, 0x00}, /*SENCTROLE Sensor control*/
-	{0x3711, 0x07}, /*SENCTROL11 Sensor control*/
-	{0x3712, 0x4e}, /*SENCTROL12 Sensor control*/
-	{0x3724, 0x00}, /*Reserved*/
-	{0x3725, 0xd4}, /*Reserved*/
-	{0x3726, 0x00}, /*Reserved*/
-	{0x3727, 0xe1}, /*Reserved*/
-	{0x3800, 0x00}, /*HS(HREF start High)*/
-	{0x3801, 0x00}, /*HS(HREF start Low)*/
-	{0x3802, 0x00}, /*VS(Vertical start Hgh)*/
-	{0x3803, 0x00}, /*VS(Vertical start Low)*/
-	{0x3804, 0x0c}, /*HW = 3295*/
-	{0x3805, 0xdf}, /*HW*/
-	{0x3806, 0x09}, /*VH = 2459*/
-	{0x3807, 0x9b}, /*VH*/
-	{0x3808, 0x0c}, /*ISPHO = 1632*/
-	{0x3809, 0xc0}, /*ISPHO*/
-	{0x380a, 0x09}, /*ISPVO = 1224*/
-	{0x380b, 0x90}, /*ISPVO*/
-	{0x380c, 0x0e}, /*HTS = 3516*/
-	{0x380d, 0x00}, /*HTS*/
-	{0x380e, 0x09}, /*VTS = 1264*/
-	{0x380f, 0xb0}, /*VTS*/
-	{0x3810, 0x00}, /*HOFF = 8*/
-	{0x3811, 0x10}, /*HOFF*/
-	{0x3812, 0x00}, /*VOFF = 4*/
-	{0x3813, 0x06}, /*VOFF*/
-	{0x3814, 0x11}, /*X INC*/
-	{0x3815, 0x11}, /*Y INC*/
-	{0x3820, 0x80}, /*Timing Reg20:Vflip*/
-	{0x3821, 0x16}, /*Timing Reg21:Hmirror*/
-	{0x3f00, 0x02}, /*PSRAM Ctrl0*/
-	{0x3f01, 0xfc}, /*PSRAM Ctrl1*/
-	{0x3f05, 0x10}, /*PSRAM Ctrl5*/
-	{0x4600, 0x04}, /*VFIFO Ctrl0*/
-	{0x4601, 0x00}, /*VFIFO Read ST High*/
-	{0x4602, 0x78}, /*VFIFO Read ST Low*/
-	{0x4837, 0x28}, /*MIPI PCLK PERIOD*/
-	{0x5068, 0x00}, /*HSCALE_CTRL*/
-	{0x506a, 0x00}, /*VSCALE_CTRL*/
-	{0x5c00, 0x80}, /*PBLC CTRL00*/
-	{0x5c01, 0x00}, /*PBLC CTRL01*/
-	{0x5c02, 0x00}, /*PBLC CTRL02*/
-	{0x5c03, 0x00}, /*PBLC CTRL03*/
-	{0x5c04, 0x00}, /*PBLC CTRL04*/
-	{0x5c08, 0x10}, /*PBLC CTRL08*/
-	{0x6900, 0x61}, /*CADC CTRL00*/
-};
-
-
-static struct msm_camera_i2c_reg_conf ov8825_reset_settings[] = {
-	{0x0103, 0x01},
-};
-
-static struct msm_camera_i2c_reg_conf ov8825_recommend_settings[] = {
-	{0x3000, 0x16},
-	{0x3001, 0x00},
-	{0x3002, 0x6c},
-	{0x300d, 0x00},
-	{0x301f, 0x09},
-	{0x3010, 0x00},
-	{0x3018, 0x00},
-	{0x3300, 0x00},
-	{0x3500, 0x00},
-	{0x3503, 0x07},
-	{0x3509, 0x00},
-	{0x3602, 0x42},
-	{0x3603, 0x5c},
-	{0x3604, 0x98},
-	{0x3605, 0xf5},
-	{0x3609, 0xb4},
-	{0x360a, 0x7c},
-	{0x360b, 0xc9},
-	{0x360c, 0x0b},
-	{0x3612, 0x00},
-	{0x3613, 0x02},
-	{0x3614, 0x0f},
-	{0x3615, 0x00},
-	{0x3616, 0x03},
-	{0x3617, 0xa1},
-	{0x3618, 0x00},
-	{0x3619, 0x00},
-	{0x361a, 0xB0},
-	{0x361b, 0x04},
-	{0x361c, 0x07},
-	{0x3701, 0x44},
-	{0x370b, 0x01},
-	{0x370c, 0x50},
-	{0x370d, 0x00},
-	{0x3816, 0x02},
-	{0x3817, 0x40},
-	{0x3818, 0x00},
-	{0x3819, 0x40},
-	{0x3b1f, 0x00},
-	{0x3d00, 0x00},
-	{0x3d01, 0x00},
-	{0x3d02, 0x00},
-	{0x3d03, 0x00},
-	{0x3d04, 0x00},
-	{0x3d05, 0x00},
-	{0x3d06, 0x00},
-	{0x3d07, 0x00},
-	{0x3d08, 0x00},
-	{0x3d09, 0x00},
-	{0x3d0a, 0x00},
-	{0x3d0b, 0x00},
-	{0x3d0c, 0x00},
-	{0x3d0d, 0x00},
-	{0x3d0e, 0x00},
-	{0x3d0f, 0x00},
-	{0x3d10, 0x00},
-	{0x3d11, 0x00},
-	{0x3d12, 0x00},
-	{0x3d13, 0x00},
-	{0x3d14, 0x00},
-	{0x3d15, 0x00},
-	{0x3d16, 0x00},
-	{0x3d17, 0x00},
-	{0x3d18, 0x00},
-	{0x3d19, 0x00},
-	{0x3d1a, 0x00},
-	{0x3d1b, 0x00},
-	{0x3d1c, 0x00},
-	{0x3d1d, 0x00},
-	{0x3d1e, 0x00},
-	{0x3d1f, 0x00},
-	{0x3d80, 0x00},
-	{0x3d81, 0x00},
-	{0x3d84, 0x00},
-	{0x3f06, 0x00},
-	{0x3f07, 0x00},
-	{0x4000, 0x29},
-	{0x4001, 0x02},
-	{0x4002, 0x45},
-	{0x4003, 0x08},
-	{0x4004, 0x04},
-	{0x4005, 0x18},
-	{0x4300, 0xff},
-	{0x4303, 0x00},
-	{0x4304, 0x08},
-	{0x4307, 0x00},
-	{0x4800, 0x04},
-	{0x4801, 0x0f},
-	{0x4843, 0x02},
-	{0x5000, 0x06},
-	{0x5001, 0x00},
-	{0x5002, 0x00},
-	{0x501f, 0x00},
-	{0x5780, 0xfc},
-	{0x5c05, 0x00},
-	{0x5c06, 0x00},
-	{0x5c07, 0x80},
-	{0x6700, 0x05},
-	{0x6701, 0x19},
-	{0x6702, 0xfd},
-	{0x6703, 0xd7},
-	{0x6704, 0xff},
-	{0x6705, 0xff},
-	{0x6800, 0x10},
-	{0x6801, 0x02},
-	{0x6802, 0x90},
-	{0x6803, 0x10},
-	{0x6804, 0x59},
-	{0x6901, 0x04},
-	{0x5800, 0x0f},
-	{0x5801, 0x0d},
-	{0x5802, 0x09},
-	{0x5803, 0x0a},
-	{0x5804, 0x0d},
-	{0x5805, 0x14},
-	{0x5806, 0x0a},
-	{0x5807, 0x04},
-	{0x5808, 0x03},
-	{0x5809, 0x03},
-	{0x580a, 0x05},
-	{0x580b, 0x0a},
-	{0x580c, 0x05},
-	{0x580d, 0x02},
-	{0x580e, 0x00},
-	{0x580f, 0x00},
-	{0x5810, 0x03},
-	{0x5811, 0x05},
-	{0x5812, 0x09},
-	{0x5813, 0x03},
-	{0x5814, 0x01},
-	{0x5815, 0x01},
-	{0x5816, 0x04},
-	{0x5817, 0x09},
-	{0x5818, 0x09},
-	{0x5819, 0x08},
-	{0x581a, 0x06},
-	{0x581b, 0x06},
-	{0x581c, 0x08},
-	{0x581d, 0x06},
-	{0x581e, 0x33},
-	{0x581f, 0x11},
-	{0x5820, 0x0e},
-	{0x5821, 0x0f},
-	{0x5822, 0x11},
-	{0x5823, 0x3f},
-	{0x5824, 0x08},
-	{0x5825, 0x46},
-	{0x5826, 0x46},
-	{0x5827, 0x46},
-	{0x5828, 0x46},
-	{0x5829, 0x46},
-	{0x582a, 0x42},
-	{0x582b, 0x42},
-	{0x582c, 0x44},
-	{0x582d, 0x46},
-	{0x582e, 0x46},
-	{0x582f, 0x60},
-	{0x5830, 0x62},
-	{0x5831, 0x42},
-	{0x5832, 0x46},
-	{0x5833, 0x46},
-	{0x5834, 0x44},
-	{0x5835, 0x44},
-	{0x5836, 0x44},
-	{0x5837, 0x48},
-	{0x5838, 0x28},
-	{0x5839, 0x46},
-	{0x583a, 0x48},
-	{0x583b, 0x68},
-	{0x583c, 0x28},
-	{0x583d, 0xae},
-	{0x5842, 0x00},
-	{0x5843, 0xef},
-	{0x5844, 0x01},
-	{0x5845, 0x3f},
-	{0x5846, 0x01},
-	{0x5847, 0x3f},
-	{0x5848, 0x00},
-	{0x5849, 0xd5},
-	{0x3503, 0x07},
-	{0x3500, 0x00},
-	{0x3501, 0x27},
-	{0x3502, 0x00},
-	{0x350b, 0xff},
-	{0x3400, 0x04},
-	{0x3401, 0x00},
-	{0x3402, 0x04},
-	{0x3403, 0x00},
-	{0x3404, 0x04},
-	{0x3405, 0x00},
-	{0x3406, 0x01},
-	{0x5001, 0x01},
-	{0x5000, 0x86},/* enable lens compensation and dpc */
-	/* LENC setting 70% */
-	{0x5800, 0x21},
-	{0x5801, 0x10},
-	{0x5802, 0x09},
-	{0x5803, 0x0a},
-	{0x5804, 0x0f},
-	{0x5805, 0x23},
-	{0x5806, 0x08},
-	{0x5807, 0x04},
-	{0x5808, 0x04},
-	{0x5809, 0x04},
-	{0x580a, 0x04},
-	{0x580b, 0x0a},
-	{0x580c, 0x04},
-	{0x580d, 0x02},
-	{0x580e, 0x00},
-	{0x580f, 0x00},
-	{0x5810, 0x03},
-	{0x5811, 0x06},
-	{0x5812, 0x05},
-	{0x5813, 0x02},
-	{0x5814, 0x00},
-	{0x5815, 0x00},
-	{0x5816, 0x03},
-	{0x5817, 0x06},
-	{0x5818, 0x09},
-	{0x5819, 0x05},
-	{0x581a, 0x04},
-	{0x581b, 0x04},
-	{0x581c, 0x05},
-	{0x581d, 0x0a},
-	{0x581e, 0x24},
-	{0x581f, 0x11},
-	{0x5820, 0x0a},
-	{0x5821, 0x0a},
-	{0x5822, 0x10},
-	{0x5823, 0x27},
-	{0x5824, 0x2a},
-	{0x5825, 0x58},
-	{0x5826, 0x28},
-	{0x5827, 0x28},
-	{0x5828, 0x28},
-	{0x5829, 0x28},
-	{0x582a, 0x46},
-	{0x582b, 0x44},
-	{0x582c, 0x46},
-	{0x582d, 0x46},
-	{0x582e, 0x28},
-	{0x582f, 0x62},
-	{0x5830, 0x60},
-	{0x5831, 0x42},
-	{0x5832, 0x28},
-	{0x5833, 0x48},
-	{0x5834, 0x46},
-	{0x5835, 0x46},
-	{0x5836, 0x26},
-	{0x5837, 0x46},
-	{0x5838, 0x28},
-	{0x5839, 0x48},
-	{0x583a, 0x28},
-	{0x583b, 0x28},
-	{0x583c, 0x26},
-	{0x583d, 0x9d},
-};
-
-static struct v4l2_subdev_info ov8825_subdev_info[] = {
-	{
-		.code   = V4L2_MBUS_FMT_SBGGR10_1X10,
-		.colorspace = V4L2_COLORSPACE_JPEG,
-		.fmt    = 1,
-		.order    = 0,
-	},
-	/* more can be supported, to be added later */
-};
-
-static struct msm_camera_i2c_conf_array ov8825_init_conf[] = {
-	{&ov8825_reset_settings[0],
-	ARRAY_SIZE(ov8825_reset_settings), 50, MSM_CAMERA_I2C_BYTE_DATA},
-	{&ov8825_recommend_settings[0],
-	ARRAY_SIZE(ov8825_recommend_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}
-};
-
-static struct msm_camera_i2c_conf_array ov8825_confs[] = {
-	{&ov8825_snap_settings[0],
-	ARRAY_SIZE(ov8825_snap_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
-	{&ov8825_prev_settings[0],
-	ARRAY_SIZE(ov8825_prev_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
-};
-
-static struct msm_sensor_output_info_t ov8825_dimensions[] = {
-	{
-		.x_output = 0xCC0,
-		.y_output = 0x990,
-		.line_length_pclk = 0xE00,
-		.frame_length_lines = 0x9B0,
-		.vt_pixel_clk = 133400000,
-		.op_pixel_clk = 176000000,
-		.binning_factor = 1,
-	},
-	{
-		.x_output = 0x660,
-		.y_output = 0x4C8,
-		.line_length_pclk = 0x6DE,
-		.frame_length_lines = 0x505,
-		.vt_pixel_clk = 66700000,
-		.op_pixel_clk = 88000000,
-		.binning_factor = 2,
-	},
-};
-
-static struct msm_sensor_output_reg_addr_t ov8825_reg_addr = {
-	.x_output = 0x3808,
-	.y_output = 0x380a,
-	.line_length_pclk = 0x380c,
-	.frame_length_lines = 0x380e,
-};
-
-static struct msm_sensor_id_info_t ov8825_id_info = {
-	.sensor_id_reg_addr = 0x300A,
-	.sensor_id = 0x8825,
-};
-
-static struct msm_sensor_exp_gain_info_t ov8825_exp_gain_info = {
-	.coarse_int_time_addr = 0x3501,
-	.global_gain_addr = 0x350A,
-	.vert_offset = 6,
-};
-
-/********************************************
- * index: index of otp group. (0, 1, 2)
- * return value:
- *     0, group index is empty
- *     1, group index has invalid data
- *     2, group index has valid data
- **********************************************/
-uint16_t ov8825_check_otp_wb(struct msm_sensor_ctrl_t *s_ctrl, uint16_t index)
-{
-	uint16_t temp, i;
-	uint16_t address;
-
-	/* clear otp buffer */
-
-	/* select otp bank 0 */
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x3d84, 0x08,
-			MSM_CAMERA_I2C_BYTE_DATA);
-
-	/* load otp into buffer */
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x3d81, 0x01,
-			MSM_CAMERA_I2C_BYTE_DATA);
-
-	/* read from group [index] */
-	address = 0x3d05 + index * 9;
-	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, address, &temp,
-			MSM_CAMERA_I2C_BYTE_DATA);
-
-	/* disable otp read */
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x3d81, 0x00,
-			MSM_CAMERA_I2C_BYTE_DATA);
-
-	/* clear otp buffer */
-	for (i = 0; i < 32; i++) {
-		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, (0x3d00+i),
-				0x00, MSM_CAMERA_I2C_BYTE_DATA);
-	}
-
-	if (!temp)
-		return 0;
-	else if ((!(temp & 0x80)) && (temp & 0x7f))
-		return 2;
-	else
-		return 1;
-}
-
-void ov8825_read_otp_wb(struct msm_sensor_ctrl_t *s_ctrl,
-		uint16_t index, struct otp_struct *potp)
-{
-	uint16_t temp, i;
-	uint16_t address;
-
-	/* select otp bank 0 */
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x3d84, 0x08,
-			MSM_CAMERA_I2C_BYTE_DATA);
-
-	/* load otp data into buffer */
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x3d81, 0x01,
-			MSM_CAMERA_I2C_BYTE_DATA);
-
-	/* read otp data from 0x3d00 - 0x3d1f*/
-	address = 0x3d05 + index * 9;
-
-	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, address, &temp,
-			MSM_CAMERA_I2C_BYTE_DATA);
-
-	potp->module_integrator_id = temp;
-	potp->customer_id = temp & 0x7f;
-
-	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, (address+1), &temp,
-			MSM_CAMERA_I2C_BYTE_DATA);
-	potp->lens_id = temp;
-
-	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, (address+2), &temp,
-			MSM_CAMERA_I2C_BYTE_DATA);
-	potp->rg_ratio = temp;
-
-	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, (address+3), &temp,
-			MSM_CAMERA_I2C_BYTE_DATA);
-	potp->bg_ratio = temp;
-
-	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, (address+4), &temp,
-			MSM_CAMERA_I2C_BYTE_DATA);
-	potp->user_data[0] = temp;
-
-	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, (address+5), &temp,
-			MSM_CAMERA_I2C_BYTE_DATA);
-	potp->user_data[1] = temp;
-
-	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, (address+6), &temp,
-			MSM_CAMERA_I2C_BYTE_DATA);
-	potp->user_data[2] = temp;
-
-	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, (address+7), &temp,
-			MSM_CAMERA_I2C_BYTE_DATA);
-	potp->user_data[3] = temp;
-
-	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, (address+8), &temp,
-			MSM_CAMERA_I2C_BYTE_DATA);
-	potp->user_data[4] = temp;
-
-	CDBG("%s customer_id  = 0x%02x\r\n", __func__, potp->customer_id);
-	CDBG("%s lens_id      = 0x%02x\r\n", __func__, potp->lens_id);
-	CDBG("%s rg_ratio     = 0x%02x\r\n", __func__, potp->rg_ratio);
-	CDBG("%s bg_ratio     = 0x%02x\r\n", __func__, potp->bg_ratio);
-	CDBG("%s user_data[0] = 0x%02x\r\n", __func__, potp->user_data[0]);
-	CDBG("%s user_data[1] = 0x%02x\r\n", __func__, potp->user_data[1]);
-	CDBG("%s user_data[2] = 0x%02x\r\n", __func__, potp->user_data[2]);
-	CDBG("%s user_data[3] = 0x%02x\r\n", __func__, potp->user_data[3]);
-	CDBG("%s user_data[4] = 0x%02x\r\n", __func__, potp->user_data[4]);
-
-	/* disable otp read */
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x3d81, 0x00,
-			MSM_CAMERA_I2C_BYTE_DATA);
-
-	/* clear otp buffer */
-	for (i = 0; i < 32; i++)
-		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, (0x3d00+i),
-				0x00, MSM_CAMERA_I2C_BYTE_DATA);
-}
-
-/**********************************************
- * r_gain, sensor red gain of AWB, 0x400 =1
- * g_gain, sensor green gain of AWB, 0x400 =1
- * b_gain, sensor blue gain of AWB, 0x400 =1
- ***********************************************/
-void ov8825_update_awb_gain(struct msm_sensor_ctrl_t *s_ctrl,
-		uint16_t r_gain, uint16_t g_gain, uint16_t b_gain)
-{
-	CDBG("%s r_gain = 0x%04x\r\n", __func__, r_gain);
-	CDBG("%s g_gain = 0x%04x\r\n", __func__, g_gain);
-	CDBG("%s b_gain = 0x%04x\r\n", __func__, b_gain);
-	if (r_gain > 0x400) {
-		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x5186,
-				(r_gain>>8), MSM_CAMERA_I2C_BYTE_DATA);
-		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x5187,
-				(r_gain&0xff), MSM_CAMERA_I2C_BYTE_DATA);
-	}
-	if (g_gain > 0x400) {
-		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x5188,
-				(g_gain>>8), MSM_CAMERA_I2C_BYTE_DATA);
-		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x5189,
-				(g_gain&0xff), MSM_CAMERA_I2C_BYTE_DATA);
-	}
-	if (b_gain > 0x400) {
-		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x518a,
-				(b_gain>>8), MSM_CAMERA_I2C_BYTE_DATA);
-		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x518b,
-				(b_gain&0xff), MSM_CAMERA_I2C_BYTE_DATA);
-	}
-}
-
-/**************************************************
- * call this function after OV8825 initialization
- * return value:
- *     0, update success
- *     1, no OTP
- ***************************************************/
-uint16_t ov8825_update_otp(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	uint16_t i;
-	uint16_t otp_index;
-	uint16_t temp;
-	uint16_t r_gain, g_gain, b_gain, g_gain_r, g_gain_b;
-
-	/* R/G and B/G of current camera module is read out from sensor OTP */
-	/* check first OTP with valid data */
-	for (i = 0; i < 3; i++) {
-		temp = ov8825_check_otp_wb(s_ctrl, i);
-		if (temp == 2) {
-			otp_index = i;
-			break;
-		}
-	}
-	if (i == 3) {
-		/* no valid wb OTP data */
-		CDBG("no valid wb OTP data\r\n");
-		return 1;
-	}
-	ov8825_read_otp_wb(s_ctrl, otp_index, &st_ov8825_otp);
-	/* calculate g_gain */
-	/* 0x400 = 1x gain */
-	if (st_ov8825_otp.bg_ratio < OV8825_BG_RATIO_TYPICAL_VALUE) {
-		if (st_ov8825_otp.rg_ratio < OV8825_RG_RATIO_TYPICAL_VALUE) {
-			g_gain = 0x400;
-			b_gain = 0x400 *
-				OV8825_BG_RATIO_TYPICAL_VALUE /
-				st_ov8825_otp.bg_ratio;
-			r_gain = 0x400 *
-				OV8825_RG_RATIO_TYPICAL_VALUE /
-				st_ov8825_otp.rg_ratio;
-		} else {
-			r_gain = 0x400;
-			g_gain = 0x400 *
-				st_ov8825_otp.rg_ratio /
-				OV8825_RG_RATIO_TYPICAL_VALUE;
-			b_gain = g_gain *
-				OV8825_BG_RATIO_TYPICAL_VALUE /
-				st_ov8825_otp.bg_ratio;
-		}
-	} else {
-		if (st_ov8825_otp.rg_ratio < OV8825_RG_RATIO_TYPICAL_VALUE) {
-			b_gain = 0x400;
-			g_gain = 0x400 *
-				st_ov8825_otp.bg_ratio /
-				OV8825_BG_RATIO_TYPICAL_VALUE;
-			r_gain = g_gain *
-				OV8825_RG_RATIO_TYPICAL_VALUE /
-				st_ov8825_otp.rg_ratio;
-		} else {
-			g_gain_b = 0x400 *
-				st_ov8825_otp.bg_ratio /
-				OV8825_BG_RATIO_TYPICAL_VALUE;
-			g_gain_r = 0x400 *
-				st_ov8825_otp.rg_ratio /
-				OV8825_RG_RATIO_TYPICAL_VALUE;
-			if (g_gain_b > g_gain_r) {
-				b_gain = 0x400;
-				g_gain = g_gain_b;
-				r_gain = g_gain *
-					OV8825_RG_RATIO_TYPICAL_VALUE /
-					st_ov8825_otp.rg_ratio;
-			} else {
-				r_gain = 0x400;
-				g_gain = g_gain_r;
-				b_gain = g_gain *
-					OV8825_BG_RATIO_TYPICAL_VALUE /
-					st_ov8825_otp.bg_ratio;
-			}
-		}
-	}
-	ov8825_update_awb_gain(s_ctrl, r_gain, g_gain, b_gain);
-	return 0;
-}
-
-static int32_t ov8825_write_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
-		uint16_t gain, uint32_t line)
-{
-	uint32_t fl_lines, offset;
-	uint8_t int_time[3];
-
-	fl_lines =
-		(s_ctrl->curr_frame_length_lines * s_ctrl->fps_divider) / Q10;
-	offset = s_ctrl->sensor_exp_gain_info->vert_offset;
-	if (line > (fl_lines - offset))
-		fl_lines = line + offset;
-	CDBG("ov8825_write_exp_gain: %d %d %d\n", fl_lines, gain, line);
-	s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_output_reg_addr->frame_length_lines, fl_lines,
-		MSM_CAMERA_I2C_WORD_DATA);
-	int_time[0] = line >> 12;
-	int_time[1] = line >> 4;
-	int_time[2] = line << 4;
-	msm_camera_i2c_write_seq(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr-1,
-		&int_time[0], 3);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->global_gain_addr, gain,
-		MSM_CAMERA_I2C_WORD_DATA);
-	s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
-	return 0;
-}
-
-static const struct i2c_device_id ov8825_i2c_id[] = {
-	{SENSOR_NAME, (kernel_ulong_t)&ov8825_s_ctrl},
-	{ }
-};
-
-int32_t ov8825_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	int32_t rc = 0;
-	struct msm_camera_sensor_info *info = NULL;
-
-	info = s_ctrl->sensordata;
-	gpio_direction_output(info->sensor_pwd, 0);
-	gpio_direction_output(info->sensor_reset, 0);
-	usleep_range(10000, 11000);
-	rc = msm_sensor_power_up(s_ctrl);
-	if (rc < 0) {
-		CDBG("%s: msm_sensor_power_up failed\n", __func__);
-		return rc;
-	}
-	/* turn on ldo and vreg */
-	gpio_direction_output(info->sensor_pwd, 1);
-	msleep(20);
-	gpio_direction_output(info->sensor_reset, 1);
-	msleep(40);
-	return rc;
-}
-
-static struct i2c_driver ov8825_i2c_driver = {
-	.id_table = ov8825_i2c_id,
-	.probe  = msm_sensor_i2c_probe,
-	.driver = {
-		.name = SENSOR_NAME,
-	},
-};
-
-static struct msm_camera_i2c_client ov8825_sensor_i2c_client = {
-	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
-};
-
-
-
-static int __init msm_sensor_init_module(void)
-{
-	return i2c_add_driver(&ov8825_i2c_driver);
-}
-
-static struct v4l2_subdev_core_ops ov8825_subdev_core_ops = {
-	.ioctl = msm_sensor_subdev_ioctl,
-	.s_power = msm_sensor_power,
-};
-
-static struct v4l2_subdev_video_ops ov8825_subdev_video_ops = {
-	.enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
-};
-
-static struct v4l2_subdev_ops ov8825_subdev_ops = {
-	.core = &ov8825_subdev_core_ops,
-	.video  = &ov8825_subdev_video_ops,
-};
-
-int32_t ov8825_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
-			int update_type, int res)
-{
-	int32_t rc = 0;
-
-	if (update_type == MSM_SENSOR_REG_INIT) {
-		CDBG("Register INIT\n");
-		s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
-		msm_sensor_enable_debugfs(s_ctrl);
-		msm_sensor_write_init_settings(s_ctrl);
-		CDBG("Update OTP\n");
-		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x100, 0x1,
-				MSM_CAMERA_I2C_BYTE_DATA);
-		msleep(66);
-		ov8825_update_otp(s_ctrl);
-		usleep_range(10000, 11000);
-		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x100, 0x0,
-		  MSM_CAMERA_I2C_BYTE_DATA);
-	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
-		CDBG("PERIODIC : %d\n", res);
-		msm_sensor_write_conf_array(
-			s_ctrl->sensor_i2c_client,
-			s_ctrl->msm_sensor_reg->mode_settings, res);
-		msleep(30);
-		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
-			NOTIFY_PCLK_CHANGE,
-			&s_ctrl->sensordata->pdata->ioclk.vfe_clk_rate);
-	}
-	return rc;
-}
-
-static struct msm_sensor_fn_t ov8825_func_tbl = {
-	.sensor_start_stream = msm_sensor_start_stream,
-	.sensor_stop_stream = msm_sensor_stop_stream,
-	.sensor_group_hold_on = msm_sensor_group_hold_on,
-	.sensor_group_hold_off = msm_sensor_group_hold_off,
-	.sensor_set_fps = msm_sensor_set_fps,
-	.sensor_write_exp_gain = ov8825_write_exp_gain,
-	.sensor_write_snapshot_exp_gain = ov8825_write_exp_gain,
-	.sensor_csi_setting = ov8825_sensor_setting,
-	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
-	.sensor_mode_init = msm_sensor_mode_init,
-	.sensor_get_output_info = msm_sensor_get_output_info,
-	.sensor_config = msm_sensor_config,
-	.sensor_power_up = ov8825_sensor_power_up,
-	.sensor_power_down = msm_sensor_power_down,
-};
-
-static struct msm_sensor_reg_t ov8825_regs = {
-	.default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
-	.start_stream_conf = ov8825_start_settings,
-	.start_stream_conf_size = ARRAY_SIZE(ov8825_start_settings),
-	.stop_stream_conf = ov8825_stop_settings,
-	.stop_stream_conf_size = ARRAY_SIZE(ov8825_stop_settings),
-	.group_hold_on_conf = ov8825_groupon_settings,
-	.group_hold_on_conf_size = ARRAY_SIZE(ov8825_groupon_settings),
-	.group_hold_off_conf = ov8825_groupoff_settings,
-	.group_hold_off_conf_size =	ARRAY_SIZE(ov8825_groupoff_settings),
-	.init_settings = &ov8825_init_conf[0],
-	.init_size = ARRAY_SIZE(ov8825_init_conf),
-	.mode_settings = &ov8825_confs[0],
-	.output_settings = &ov8825_dimensions[0],
-	.num_conf = ARRAY_SIZE(ov8825_confs),
-};
-
-static struct msm_sensor_ctrl_t ov8825_s_ctrl = {
-	.msm_sensor_reg = &ov8825_regs,
-	.sensor_i2c_client = &ov8825_sensor_i2c_client,
-	.sensor_i2c_addr = 0x6C,
-	.sensor_output_reg_addr = &ov8825_reg_addr,
-	.sensor_id_info = &ov8825_id_info,
-	.sensor_exp_gain_info = &ov8825_exp_gain_info,
-	.cam_mode = MSM_SENSOR_MODE_INVALID,
-	.msm_sensor_mutex = &ov8825_mut,
-	.sensor_i2c_driver = &ov8825_i2c_driver,
-	.sensor_v4l2_subdev_info = ov8825_subdev_info,
-	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(ov8825_subdev_info),
-	.sensor_v4l2_subdev_ops = &ov8825_subdev_ops,
-	.func_tbl = &ov8825_func_tbl,
-};
-
-module_init(msm_sensor_init_module);
-MODULE_DESCRIPTION("Omnivison 8MP Bayer sensor driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/sensors/ov9726_v4l2.c b/drivers/media/video/msm/sensors/ov9726_v4l2.c
deleted file mode 100644
index 50c13c6..0000000
--- a/drivers/media/video/msm/sensors/ov9726_v4l2.c
+++ /dev/null
@@ -1,268 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 "msm_sensor.h"
-#define SENSOR_NAME "ov9726"
-#define PLATFORM_DRIVER_NAME "msm_camera_ov9726"
-#define ov9726_obj ov9726_##obj
-
-DEFINE_MUTEX(ov9726_mut);
-static struct msm_sensor_ctrl_t ov9726_s_ctrl;
-
-static struct msm_camera_i2c_reg_conf ov9726_start_settings[] = {
-	{0x0100, 0x01},
-};
-
-static struct msm_camera_i2c_reg_conf ov9726_stop_settings[] = {
-	{0x0100, 0x00},
-};
-
-static struct msm_camera_i2c_reg_conf ov9726_groupon_settings[] = {
-	{0x0104, 0x01},
-};
-
-static struct msm_camera_i2c_reg_conf ov9726_groupoff_settings[] = {
-	{0x0104, 0x00},
-};
-
-static struct msm_camera_i2c_reg_conf ov9726_prev_settings[] = {
-};
-
-static struct msm_camera_i2c_reg_conf ov9726_recommend_settings[] = {
-	{0x0103, 0x01}, /* SOFTWARE_RESET */
-	{0x3026, 0x00}, /* OUTPUT_SELECT01 */
-	{0x3027, 0x00}, /* OUTPUT_SELECT02 */
-	{0x3002, 0xe8}, /* IO_CTRL00 */
-	{0x3004, 0x03}, /* IO_CTRL01 */
-	{0x3005, 0xff}, /* IO_CTRL02 */
-	{0x3703, 0x42},
-	{0x3704, 0x10},
-	{0x3705, 0x45},
-	{0x3603, 0xaa},
-	{0x3632, 0x2f},
-	{0x3620, 0x66},
-	{0x3621, 0xc0},
-	{0x0340, 0x03}, /* FRAME_LENGTH_LINES_HI */
-	{0x0341, 0xC1}, /* FRAME_LENGTH_LINES_LO */
-	{0x0342, 0x06}, /* LINE_LENGTH_PCK_HI */
-	{0x0343, 0x80}, /* LINE_LENGTH_PCK_LO */
-	{0x0202, 0x03}, /* COARSE_INTEGRATION_TIME_HI */
-	{0x0203, 0x43}, /* COARSE_INTEGRATION_TIME_LO */
-	{0x3833, 0x04},
-	{0x3835, 0x02},
-	{0x4702, 0x04},
-	{0x4704, 0x00}, /* DVP_CTRL01 */
-	{0x4706, 0x08},
-	{0x5052, 0x01},
-	{0x3819, 0x6e},
-	{0x3817, 0x94},
-	{0x3a18, 0x00}, /* AEC_GAIN_CEILING_HI */
-	{0x3a19, 0x7f}, /* AEC_GAIN_CEILING_LO */
-	{0x404e, 0x7e},
-	{0x3631, 0x52},
-	{0x3633, 0x50},
-	{0x3630, 0xd2},
-	{0x3604, 0x08},
-	{0x3601, 0x40},
-	{0x3602, 0x14},
-	{0x3610, 0xa0},
-	{0x3612, 0x20},
-	{0x034c, 0x05}, /* X_OUTPUT_SIZE_HI */
-	{0x034d, 0x10}, /* X_OUTPUT_SIZE_LO */
-	{0x034e, 0x03}, /* Y_OUTPUT_SIZE_HI */
-	{0x034f, 0x28}, /* Y_OUTPUT_SIZE_LO */
-	{0x0340, 0x03}, /* FRAME_LENGTH_LINES_HI */
-	{0x0341, 0xC1}, /* FRAME_LENGTH_LINES_LO */
-	{0x0342, 0x06}, /* LINE_LENGTH_PCK_HI */
-	{0x0343, 0x80}, /* LINE_LENGTH_PCK_LO */
-	{0x0202, 0x03}, /* COARSE_INTEGRATION_TIME_HI */
-	{0x0203, 0x43}, /* COARSE_INTEGRATION_TIME_LO */
-	{0x0303, 0x01}, /* VT_SYS_CLK_DIV_LO */
-	{0x3002, 0x00}, /* IO_CTRL00 */
-	{0x3004, 0x00}, /* IO_CTRL01 */
-	{0x3005, 0x00}, /* IO_CTRL02 */
-	{0x4801, 0x0f}, /* MIPI_CTRL01 */
-	{0x4803, 0x05}, /* MIPI_CTRL03 */
-	{0x4601, 0x16}, /* VFIFO_READ_CONTROL */
-	{0x3014, 0x05}, /* SC_CMMN_MIPI / SC_CTRL00 */
-	{0x3104, 0x80},
-	{0x0305, 0x04}, /* PRE_PLL_CLK_DIV_LO */
-	{0x0307, 0x64}, /* PLL_MULTIPLIER_LO */
-	{0x300c, 0x02},
-	{0x300d, 0x20},
-	{0x300e, 0x01},
-	{0x3010, 0x01},
-	{0x460e, 0x81}, /* VFIFO_CONTROL00 */
-	{0x0101, 0x01}, /* IMAGE_ORIENTATION */
-	{0x3707, 0x14},
-	{0x3622, 0x9f},
-	{0x5047, 0x3D}, /* ISP_CTRL47 */
-	{0x4002, 0x45}, /* BLC_CTRL02 */
-	{0x5000, 0x06}, /* ISP_CTRL0 */
-	{0x5001, 0x00}, /* ISP_CTRL1 */
-	{0x3406, 0x00}, /* AWB_MANUAL_CTRL */
-	{0x3503, 0x13}, /* AEC_ENABLE */
-	{0x4005, 0x18}, /* BLC_CTRL05 */
-	{0x4837, 0x21},
-	{0x0100, 0x01}, /* MODE_SELECT */
-	{0x3a0f, 0x64}, /* AEC_CTRL0F */
-	{0x3a10, 0x54}, /* AEC_CTRL10 */
-	{0x3a11, 0xc2}, /* AEC_CTRL11 */
-	{0x3a1b, 0x64}, /* AEC_CTRL1B */
-	{0x3a1e, 0x54}, /* AEC_CTRL1E */
-	{0x3a1a, 0x05}, /* AEC_DIFF_MAX */
-};
-
-static struct v4l2_subdev_info ov9726_subdev_info[] = {
-	{
-	.code   = V4L2_MBUS_FMT_SBGGR10_1X10,
-	.colorspace = V4L2_COLORSPACE_JPEG,
-	.fmt    = 1,
-	.order    = 0,
-	},
-	/* more can be supported, to be added later */
-};
-
-static struct msm_camera_i2c_conf_array ov9726_init_conf[] = {
-	{&ov9726_recommend_settings[0],
-	ARRAY_SIZE(ov9726_recommend_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}
-};
-
-static struct msm_camera_i2c_conf_array ov9726_confs[] = {
-	{&ov9726_prev_settings[0],
-	ARRAY_SIZE(ov9726_prev_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
-};
-
-static struct msm_sensor_output_info_t ov9726_dimensions[] = {
-	{
-		.x_output = 0x510, /* 1296 */
-		.y_output = 0x328, /* 808 */
-		.line_length_pclk = 0x680, /* 1664 */
-		.frame_length_lines = 0x3C1, /* 961 */
-		.vt_pixel_clk = 320000000,
-		.op_pixel_clk = 320000000,
-		.binning_factor = 1,
-	},
-};
-
-static struct msm_sensor_output_reg_addr_t ov9726_reg_addr = {
-	.x_output = 0x034c,
-	.y_output = 0x034e,
-	.line_length_pclk = 0x0342,
-	.frame_length_lines = 0x0340,
-};
-
-static struct msm_sensor_id_info_t ov9726_id_info = {
-	.sensor_id_reg_addr = 0x0000,
-	.sensor_id = 0x9726,
-};
-
-static struct msm_sensor_exp_gain_info_t ov9726_exp_gain_info = {
-	.coarse_int_time_addr = 0x0202,
-	.global_gain_addr = 0x0204,
-	.vert_offset = 6,
-};
-
-static const struct i2c_device_id ov9726_i2c_id[] = {
-	{SENSOR_NAME, (kernel_ulong_t)&ov9726_s_ctrl},
-	{ }
-};
-
-static struct i2c_driver ov9726_i2c_driver = {
-	.id_table = ov9726_i2c_id,
-	.probe  = msm_sensor_i2c_probe,
-	.driver = {
-		.name = SENSOR_NAME,
-	},
-};
-
-static struct msm_camera_i2c_client ov9726_sensor_i2c_client = {
-	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
-};
-
-static int __init msm_sensor_init_module(void)
-{
-	return i2c_add_driver(&ov9726_i2c_driver);
-}
-
-static struct v4l2_subdev_core_ops ov9726_subdev_core_ops = {
-	.ioctl = msm_sensor_subdev_ioctl,
-	.s_power = msm_sensor_power,
-};
-
-static struct v4l2_subdev_video_ops ov9726_subdev_video_ops = {
-	.enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
-};
-
-static struct v4l2_subdev_ops ov9726_subdev_ops = {
-	.core = &ov9726_subdev_core_ops,
-	.video  = &ov9726_subdev_video_ops,
-};
-
-static struct msm_sensor_fn_t ov9726_func_tbl = {
-	.sensor_start_stream = msm_sensor_start_stream,
-	.sensor_stop_stream = msm_sensor_stop_stream,
-	.sensor_group_hold_on = msm_sensor_group_hold_on,
-	.sensor_group_hold_off = msm_sensor_group_hold_off,
-	.sensor_set_fps = msm_sensor_set_fps,
-	.sensor_write_exp_gain = msm_sensor_write_exp_gain1,
-	.sensor_write_snapshot_exp_gain = msm_sensor_write_exp_gain1,
-	.sensor_csi_setting = msm_sensor_setting1,
-	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
-	.sensor_mode_init = msm_sensor_mode_init,
-	.sensor_get_output_info = msm_sensor_get_output_info,
-	.sensor_config = msm_sensor_config,
-	.sensor_power_up = msm_sensor_power_up,
-	.sensor_power_down = msm_sensor_power_down,
-};
-
-static struct msm_sensor_reg_t ov9726_regs = {
-	.default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
-	.start_stream_conf = ov9726_start_settings,
-	.start_stream_conf_size = ARRAY_SIZE(ov9726_start_settings),
-	.stop_stream_conf = ov9726_stop_settings,
-	.stop_stream_conf_size = ARRAY_SIZE(ov9726_stop_settings),
-	.group_hold_on_conf = ov9726_groupon_settings,
-	.group_hold_on_conf_size = ARRAY_SIZE(ov9726_groupon_settings),
-	.group_hold_off_conf = ov9726_groupoff_settings,
-	.group_hold_off_conf_size =
-		ARRAY_SIZE(ov9726_groupoff_settings),
-	.init_settings = &ov9726_init_conf[0],
-	.init_size = ARRAY_SIZE(ov9726_init_conf),
-	.mode_settings = &ov9726_confs[0],
-	.output_settings = &ov9726_dimensions[0],
-	.num_conf = ARRAY_SIZE(ov9726_confs),
-};
-
-static struct msm_sensor_ctrl_t ov9726_s_ctrl = {
-	.msm_sensor_reg = &ov9726_regs,
-	.sensor_i2c_client = &ov9726_sensor_i2c_client,
-	.sensor_i2c_addr = 0x20,
-	.sensor_output_reg_addr = &ov9726_reg_addr,
-	.sensor_id_info = &ov9726_id_info,
-	.sensor_exp_gain_info = &ov9726_exp_gain_info,
-	.cam_mode = MSM_SENSOR_MODE_INVALID,
-	.msm_sensor_mutex = &ov9726_mut,
-	.sensor_i2c_driver = &ov9726_i2c_driver,
-	.sensor_v4l2_subdev_info = ov9726_subdev_info,
-	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(ov9726_subdev_info),
-	.sensor_v4l2_subdev_ops = &ov9726_subdev_ops,
-	.func_tbl = &ov9726_func_tbl,
-	.clk_rate = MSM_SENSOR_MCLK_24HZ,
-};
-
-module_init(msm_sensor_init_module);
-MODULE_DESCRIPTION("Omnivision WXGA Bayer sensor driver");
-MODULE_LICENSE("GPL v2");
-
-
diff --git a/drivers/media/video/msm/sensors/s5k4e1_v4l2.c b/drivers/media/video/msm/sensors/s5k4e1_v4l2.c
deleted file mode 100644
index 8cdadd8..0000000
--- a/drivers/media/video/msm/sensors/s5k4e1_v4l2.c
+++ /dev/null
@@ -1,518 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 "msm_sensor.h"
-#define SENSOR_NAME "s5k4e1"
-#define PLATFORM_DRIVER_NAME "msm_camera_s5k4e1"
-#define s5k4e1_obj s5k4e1_##obj
-#define MSB                             1
-#define LSB                             0
-
-DEFINE_MUTEX(s5k4e1_mut);
-static struct msm_sensor_ctrl_t s5k4e1_s_ctrl;
-
-static struct msm_camera_i2c_reg_conf s5k4e1_start_settings[] = {
-	{0x0100, 0x01},
-};
-
-static struct msm_camera_i2c_reg_conf s5k4e1_stop_settings[] = {
-	{0x0100, 0x00},
-};
-
-static struct msm_camera_i2c_reg_conf s5k4e1_groupon_settings[] = {
-	{0x0104, 0x01},
-};
-
-static struct msm_camera_i2c_reg_conf s5k4e1_groupoff_settings[] = {
-	{0x0104, 0x00},
-};
-
-static struct msm_camera_i2c_reg_conf s5k4e1_prev_settings[] = {
-	/* output size (1304 x 980) */
-	{0x30A9, 0x02},/* Horizontal Binning On */
-	{0x300E, 0xEB},/* Vertical Binning On */
-	{0x0387, 0x03},/* y_odd_inc 03(10b AVG) */
-	{0x0344, 0x00},/* x_addr_start 0 */
-	{0x0345, 0x00},
-	{0x0348, 0x0A},/* x_addr_end 2607 */
-	{0x0349, 0x2F},
-	{0x0346, 0x00},/* y_addr_start 0 */
-	{0x0347, 0x00},
-	{0x034A, 0x07},/* y_addr_end 1959 */
-	{0x034B, 0xA7},
-	{0x0380, 0x00},/* x_even_inc 1 */
-	{0x0381, 0x01},
-	{0x0382, 0x00},/* x_odd_inc 1 */
-	{0x0383, 0x01},
-	{0x0384, 0x00},/* y_even_inc 1 */
-	{0x0385, 0x01},
-	{0x0386, 0x00},/* y_odd_inc 3 */
-	{0x0387, 0x03},
-	{0x034C, 0x05},/* x_output_size 1304 */
-	{0x034D, 0x18},
-	{0x034E, 0x03},/* y_output_size 980 */
-	{0x034F, 0xd4},
-	{0x30BF, 0xAB},/* outif_enable[7], data_type[5:0](2Bh = bayer 10bit} */
-	{0x30C0, 0xA0},/* video_offset[7:4] 3260%12 */
-	{0x30C8, 0x06},/* video_data_length 1600 = 1304 * 1.25 */
-	{0x30C9, 0x5E},
-	/* Timing Configuration */
-	{0x0202, 0x03},
-	{0x0203, 0x14},
-	{0x0204, 0x00},
-	{0x0205, 0x80},
-	{0x0340, 0x03},/* Frame Length */
-	{0x0341, 0xE0},
-	{0x0342, 0x0A},/* 2738  Line Length */
-	{0x0343, 0xB2},
-};
-
-static struct msm_camera_i2c_reg_conf s5k4e1_snap_settings[] = {
-	/*Output Size (2608x1960)*/
-	{0x30A9, 0x03},/* Horizontal Binning Off */
-	{0x300E, 0xE8},/* Vertical Binning Off */
-	{0x0387, 0x01},/* y_odd_inc */
-	{0x034C, 0x0A},/* x_output size */
-	{0x034D, 0x30},
-	{0x034E, 0x07},/* y_output size */
-	{0x034F, 0xA8},
-	{0x30BF, 0xAB},/* outif_enable[7], data_type[5:0](2Bh = bayer 10bit} */
-	{0x30C0, 0x80},/* video_offset[7:4] 3260%12 */
-	{0x30C8, 0x0C},/* video_data_length 3260 = 2608 * 1.25 */
-	{0x30C9, 0xBC},
-	/*Timing configuration*/
-	{0x0202, 0x06},
-	{0x0203, 0x28},
-	{0x0204, 0x00},
-	{0x0205, 0x80},
-	{0x0340, 0x07},/* Frame Length */
-	{0x0341, 0xB4},
-	{0x0342, 0x0A},/* 2738 Line Length */
-	{0x0343, 0xB2},
-};
-
-static struct msm_camera_i2c_reg_conf s5k4e1_recommend_settings[] = {
-	/* Reset setting */
-	{0x0103, 0x01},
-	/* MIPI settings */
-	{0x30BD, 0x00},/* SEL_CCP[0] */
-	{0x3084, 0x15},/* SYNC Mode */
-	{0x30BE, 0x1A},/* M_PCLKDIV_AUTO[4], M_DIV_PCLK[3:0] */
-	{0x30C1, 0x01},/* pack video enable [0] */
-	{0x30EE, 0x02},/* DPHY enable [ 1] */
-	{0x3111, 0x86},/* Embedded data off [5] */
-
-	/* REC Settings */
-	/*CDS timing setting ... */
-	{0x3000, 0x05},
-	{0x3001, 0x03},
-	{0x3002, 0x08},
-	{0x3003, 0x0A},
-	{0x3004, 0x50},
-	{0x3005, 0x0E},
-	{0x3006, 0x5E},
-	{0x3007, 0x00},
-	{0x3008, 0x78},
-	{0x3009, 0x78},
-	{0x300A, 0x50},
-	{0x300B, 0x08},
-	{0x300C, 0x14},
-	{0x300D, 0x00},
-	{0x300E, 0xE8},
-	{0x300F, 0x82},
-	{0x301B, 0x77},
-
-	/* CDS option setting ... */
-	{0x3010, 0x00},
-	{0x3011, 0x3A},
-	{0x3029, 0x04},
-	{0x3012, 0x30},
-	{0x3013, 0xA0},
-	{0x3014, 0x00},
-	{0x3015, 0x00},
-	{0x3016, 0x30},
-	{0x3017, 0x94},
-	{0x3018, 0x70},
-	{0x301D, 0xD4},
-	{0x3021, 0x02},
-	{0x3022, 0x24},
-	{0x3024, 0x40},
-	{0x3027, 0x08},
-
-	/* Pixel option setting ...   */
-	{0x301C, 0x04},
-	{0x30D8, 0x3F},
-	{0x302B, 0x01},
-
-	{0x3070, 0x5F},
-	{0x3071, 0x00},
-	{0x3080, 0x04},
-	{0x3081, 0x38},
-
-	/* PLL settings */
-	{0x0305, 0x04},
-	{0x0306, 0x00},
-	{0x0307, 0x44},
-	{0x30B5, 0x00},
-	{0x30E2, 0x01},/* num lanes[1:0] = 2 */
-	{0x30F1, 0xB0},
-};
-
-static struct v4l2_subdev_info s5k4e1_subdev_info[] = {
-	{
-	.code   = V4L2_MBUS_FMT_SGRBG10_1X10,
-	.colorspace = V4L2_COLORSPACE_JPEG,
-	.fmt    = 1,
-	.order    = 0,
-	},
-	/* more can be supported, to be added later */
-};
-
-static struct msm_camera_i2c_conf_array s5k4e1_init_conf[] = {
-	{&s5k4e1_recommend_settings[0],
-	ARRAY_SIZE(s5k4e1_recommend_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}
-};
-
-static struct msm_camera_i2c_conf_array s5k4e1_confs[] = {
-	{&s5k4e1_snap_settings[0],
-	ARRAY_SIZE(s5k4e1_snap_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
-	{&s5k4e1_prev_settings[0],
-	ARRAY_SIZE(s5k4e1_prev_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
-};
-
-static struct msm_sensor_output_info_t s5k4e1_dimensions[] = {
-	{
-		.x_output = 0xA30,
-		.y_output = 0x7A8,
-		.line_length_pclk = 0xAB2,
-		.frame_length_lines = 0x7B4,
-		.vt_pixel_clk = 81600000,
-		.op_pixel_clk = 81600000,
-		.binning_factor = 0,
-	},
-	{
-		.x_output = 0x518,
-		.y_output = 0x3D4,
-		.line_length_pclk = 0xAB2,
-		.frame_length_lines = 0x3E0,
-		.vt_pixel_clk = 81600000,
-		.op_pixel_clk = 81600000,
-		.binning_factor = 1,
-	},
-};
-
-static struct msm_sensor_output_reg_addr_t s5k4e1_reg_addr = {
-	.x_output = 0x034C,
-	.y_output = 0x034E,
-	.line_length_pclk = 0x0342,
-	.frame_length_lines = 0x0340,
-};
-
-static struct msm_sensor_id_info_t s5k4e1_id_info = {
-	.sensor_id_reg_addr = 0x0000,
-	.sensor_id = 0x4E10,
-};
-
-static struct msm_sensor_exp_gain_info_t s5k4e1_exp_gain_info = {
-	.coarse_int_time_addr = 0x0202,
-	.global_gain_addr = 0x0204,
-	.vert_offset = 4,
-};
-
-static inline uint8_t s5k4e1_byte(uint16_t word, uint8_t offset)
-{
-	return word >> (offset * BITS_PER_BYTE);
-}
-
-static int32_t s5k4e1_write_prev_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
-						uint16_t gain, uint32_t line)
-{
-	uint16_t max_legal_gain = 0x0200;
-	int32_t rc = 0;
-	static uint32_t fl_lines, offset;
-
-	pr_info("s5k4e1_write_prev_exp_gain :%d %d\n", gain, line);
-	offset = s_ctrl->sensor_exp_gain_info->vert_offset;
-	if (gain > max_legal_gain) {
-		CDBG("Max legal gain Line:%d\n", __LINE__);
-		gain = max_legal_gain;
-	}
-
-	/* Analogue Gain */
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->global_gain_addr,
-		s5k4e1_byte(gain, MSB),
-		MSM_CAMERA_I2C_BYTE_DATA);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->global_gain_addr + 1,
-		s5k4e1_byte(gain, LSB),
-		MSM_CAMERA_I2C_BYTE_DATA);
-
-	if (line > (s_ctrl->curr_frame_length_lines - offset)) {
-		fl_lines = line + offset;
-		s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
-		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-			s_ctrl->sensor_output_reg_addr->frame_length_lines,
-			s5k4e1_byte(fl_lines, MSB),
-			MSM_CAMERA_I2C_BYTE_DATA);
-		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-			s_ctrl->sensor_output_reg_addr->frame_length_lines + 1,
-			s5k4e1_byte(fl_lines, LSB),
-			MSM_CAMERA_I2C_BYTE_DATA);
-		/* Coarse Integration Time */
-		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-			s_ctrl->sensor_exp_gain_info->coarse_int_time_addr,
-			s5k4e1_byte(line, MSB),
-			MSM_CAMERA_I2C_BYTE_DATA);
-		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-			s_ctrl->sensor_exp_gain_info->coarse_int_time_addr + 1,
-			s5k4e1_byte(line, LSB),
-			MSM_CAMERA_I2C_BYTE_DATA);
-		s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
-	} else if (line < (fl_lines - offset)) {
-		fl_lines = line + offset;
-		if (fl_lines < s_ctrl->curr_frame_length_lines)
-			fl_lines = s_ctrl->curr_frame_length_lines;
-
-		s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
-		/* Coarse Integration Time */
-		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-			s_ctrl->sensor_exp_gain_info->coarse_int_time_addr,
-			s5k4e1_byte(line, MSB),
-			MSM_CAMERA_I2C_BYTE_DATA);
-		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-			s_ctrl->sensor_exp_gain_info->coarse_int_time_addr + 1,
-			s5k4e1_byte(line, LSB),
-			MSM_CAMERA_I2C_BYTE_DATA);
-		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-			s_ctrl->sensor_output_reg_addr->frame_length_lines,
-			s5k4e1_byte(fl_lines, MSB),
-			MSM_CAMERA_I2C_BYTE_DATA);
-		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-			s_ctrl->sensor_output_reg_addr->frame_length_lines + 1,
-			s5k4e1_byte(fl_lines, LSB),
-			MSM_CAMERA_I2C_BYTE_DATA);
-		s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
-	} else {
-		fl_lines = line+4;
-		s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
-		/* Coarse Integration Time */
-		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-			s_ctrl->sensor_exp_gain_info->coarse_int_time_addr,
-			s5k4e1_byte(line, MSB),
-			MSM_CAMERA_I2C_BYTE_DATA);
-		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-			s_ctrl->sensor_exp_gain_info->coarse_int_time_addr + 1,
-			s5k4e1_byte(line, LSB),
-			MSM_CAMERA_I2C_BYTE_DATA);
-		s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
-	}
-	return rc;
-}
-
-static int32_t s5k4e1_write_pict_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
-		uint16_t gain, uint32_t line)
-{
-	uint16_t max_legal_gain = 0x0200;
-	uint16_t min_ll_pck = 0x0AB2;
-	uint32_t ll_pck, fl_lines;
-	uint32_t ll_ratio;
-	uint8_t gain_msb, gain_lsb;
-	uint8_t intg_time_msb, intg_time_lsb;
-	uint8_t ll_pck_msb, ll_pck_lsb;
-
-	if (gain > max_legal_gain) {
-		CDBG("Max legal gain Line:%d\n", __LINE__);
-		gain = max_legal_gain;
-	}
-
-	pr_info("s5k4e1_write_exp_gain : gain = %d line = %d\n", gain, line);
-	line = (uint32_t) (line * s_ctrl->fps_divider);
-	fl_lines = s_ctrl->curr_frame_length_lines * s_ctrl->fps_divider / Q10;
-	ll_pck = s_ctrl->curr_line_length_pclk;
-
-	if (fl_lines < (line / Q10))
-		ll_ratio = (line / (fl_lines - 4));
-	else
-		ll_ratio = Q10;
-
-	ll_pck = ll_pck * ll_ratio / Q10;
-	line = line / ll_ratio;
-	if (ll_pck < min_ll_pck)
-		ll_pck = min_ll_pck;
-
-	gain_msb = (uint8_t) ((gain & 0xFF00) >> 8);
-	gain_lsb = (uint8_t) (gain & 0x00FF);
-
-	intg_time_msb = (uint8_t) ((line & 0xFF00) >> 8);
-	intg_time_lsb = (uint8_t) (line & 0x00FF);
-
-	ll_pck_msb = (uint8_t) ((ll_pck & 0xFF00) >> 8);
-	ll_pck_lsb = (uint8_t) (ll_pck & 0x00FF);
-
-	s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->global_gain_addr,
-		gain_msb,
-		MSM_CAMERA_I2C_BYTE_DATA);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->global_gain_addr + 1,
-		gain_lsb,
-		MSM_CAMERA_I2C_BYTE_DATA);
-
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_output_reg_addr->line_length_pclk,
-		ll_pck_msb,
-		MSM_CAMERA_I2C_BYTE_DATA);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_output_reg_addr->line_length_pclk + 1,
-		ll_pck_lsb,
-		MSM_CAMERA_I2C_BYTE_DATA);
-
-	/* Coarse Integration Time */
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr,
-		intg_time_msb,
-		MSM_CAMERA_I2C_BYTE_DATA);
-	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr + 1,
-		intg_time_lsb,
-		MSM_CAMERA_I2C_BYTE_DATA);
-	s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
-
-	return 0;
-}
-
-int32_t s5k4e1_sensor_i2c_probe(struct i2c_client *client,
-	const struct i2c_device_id *id)
-{
-	int rc = 0;
-	struct msm_camera_sensor_info *s_info;
-
-	rc = msm_sensor_i2c_probe(client, id);
-
-	s_info = client->dev.platform_data;
-	if (s_info == NULL) {
-		pr_err("%s %s NULL sensor data\n", __func__, client->name);
-		return -EFAULT;
-	}
-
-	if (s_info->actuator_info->vcm_enable) {
-		rc = gpio_request(s_info->actuator_info->vcm_pwd,
-				"msm_actuator");
-		if (rc < 0)
-			pr_err("%s: gpio_request:msm_actuator %d failed\n",
-				__func__, s_info->actuator_info->vcm_pwd);
-		rc = gpio_direction_output(s_info->actuator_info->vcm_pwd, 0);
-		if (rc < 0)
-			pr_err("%s: gpio:msm_actuator %d direction can't be set\n",
-				__func__, s_info->actuator_info->vcm_pwd);
-		gpio_free(s_info->actuator_info->vcm_pwd);
-	}
-
-	return rc;
-}
-
-static const struct i2c_device_id s5k4e1_i2c_id[] = {
-	{SENSOR_NAME, (kernel_ulong_t)&s5k4e1_s_ctrl},
-	{ }
-};
-
-static struct i2c_driver s5k4e1_i2c_driver = {
-	.id_table = s5k4e1_i2c_id,
-	.probe  = s5k4e1_sensor_i2c_probe,
-	.driver = {
-		.name = SENSOR_NAME,
-	},
-};
-
-static struct msm_camera_i2c_client s5k4e1_sensor_i2c_client = {
-	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
-};
-
-static int __init msm_sensor_init_module(void)
-{
-	return i2c_add_driver(&s5k4e1_i2c_driver);
-}
-
-static struct v4l2_subdev_core_ops s5k4e1_subdev_core_ops = {
-	.ioctl = msm_sensor_subdev_ioctl,
-	.s_power = msm_sensor_power,
-};
-
-static struct v4l2_subdev_video_ops s5k4e1_subdev_video_ops = {
-	.enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
-};
-
-static struct v4l2_subdev_ops s5k4e1_subdev_ops = {
-	.core = &s5k4e1_subdev_core_ops,
-	.video  = &s5k4e1_subdev_video_ops,
-};
-
-static struct msm_sensor_fn_t s5k4e1_func_tbl = {
-	.sensor_start_stream = msm_sensor_start_stream,
-	.sensor_stop_stream = msm_sensor_stop_stream,
-	.sensor_group_hold_on = msm_sensor_group_hold_on,
-	.sensor_group_hold_off = msm_sensor_group_hold_off,
-	.sensor_set_fps = msm_sensor_set_fps,
-	.sensor_write_exp_gain = s5k4e1_write_prev_exp_gain,
-	.sensor_write_snapshot_exp_gain = s5k4e1_write_pict_exp_gain,
-	.sensor_csi_setting = msm_sensor_setting1,
-	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
-	.sensor_mode_init = msm_sensor_mode_init,
-	.sensor_get_output_info = msm_sensor_get_output_info,
-	.sensor_config = msm_sensor_config,
-	.sensor_power_up = msm_sensor_power_up,
-	.sensor_power_down = msm_sensor_power_down,
-};
-
-static struct msm_sensor_reg_t s5k4e1_regs = {
-	.default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
-	.start_stream_conf = s5k4e1_start_settings,
-	.start_stream_conf_size = ARRAY_SIZE(s5k4e1_start_settings),
-	.stop_stream_conf = s5k4e1_stop_settings,
-	.stop_stream_conf_size = ARRAY_SIZE(s5k4e1_stop_settings),
-	.group_hold_on_conf = s5k4e1_groupon_settings,
-	.group_hold_on_conf_size = ARRAY_SIZE(s5k4e1_groupon_settings),
-	.group_hold_off_conf = s5k4e1_groupoff_settings,
-	.group_hold_off_conf_size =
-		ARRAY_SIZE(s5k4e1_groupoff_settings),
-	.init_settings = &s5k4e1_init_conf[0],
-	.init_size = ARRAY_SIZE(s5k4e1_init_conf),
-	.mode_settings = &s5k4e1_confs[0],
-	.output_settings = &s5k4e1_dimensions[0],
-	.num_conf = ARRAY_SIZE(s5k4e1_confs),
-};
-
-static struct msm_sensor_ctrl_t s5k4e1_s_ctrl = {
-	.msm_sensor_reg = &s5k4e1_regs,
-	.sensor_i2c_client = &s5k4e1_sensor_i2c_client,
-	.sensor_i2c_addr = 0x6C,
-	.sensor_output_reg_addr = &s5k4e1_reg_addr,
-	.sensor_id_info = &s5k4e1_id_info,
-	.sensor_exp_gain_info = &s5k4e1_exp_gain_info,
-	.cam_mode = MSM_SENSOR_MODE_INVALID,
-	.msm_sensor_mutex = &s5k4e1_mut,
-	.sensor_i2c_driver = &s5k4e1_i2c_driver,
-	.sensor_v4l2_subdev_info = s5k4e1_subdev_info,
-	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(s5k4e1_subdev_info),
-	.sensor_v4l2_subdev_ops = &s5k4e1_subdev_ops,
-	.func_tbl = &s5k4e1_func_tbl,
-	.clk_rate = MSM_SENSOR_MCLK_24HZ,
-};
-
-module_init(msm_sensor_init_module);
-MODULE_DESCRIPTION("Samsung 5MP Bayer sensor driver");
-MODULE_LICENSE("GPL v2");
-
-
diff --git a/drivers/media/video/msm/sensors/vx6953.c b/drivers/media/video/msm/sensors/vx6953.c
deleted file mode 100644
index ddc6cee..0000000
--- a/drivers/media/video/msm/sensors/vx6953.c
+++ /dev/null
@@ -1,2037 +0,0 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. 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 "msm_sensor.h"
-#include "msm.h"
-#include "vx6953.h"
-#include "vx6953_reg.h"
-#define SENSOR_NAME "vx6953"
-#define PLATFORM_DRIVER_NAME "msm_camera_vx6953"
-#define vx6953_obj vx6953_##obj
-
-DEFINE_MUTEX(vx6953_mut);
-
-#undef CDBG
-#define CDBG printk
-#define REG_GROUPED_PARAMETER_HOLD			0x0104
-#define GROUPED_PARAMETER_HOLD_OFF			0x00
-#define GROUPED_PARAMETER_HOLD				0x01
-#define REG_MODE_SELECT					0x0100
-#define MODE_SELECT_STANDBY_MODE			0x00
-#define MODE_SELECT_STREAM				0x01
-/* Integration Time */
-#define REG_COARSE_INTEGRATION_TIME_HI			0x0202
-#define REG_COARSE_INTEGRATION_TIME_LO			0x0203
-/* Gain */
-#define REG_ANALOGUE_GAIN_CODE_GLOBAL_HI		0x0204
-#define REG_ANALOGUE_GAIN_CODE_GLOBAL_LO		0x0205
-/* Digital Gain */
-#define REG_DIGITAL_GAIN_GREEN_R_HI			0x020E
-#define REG_DIGITAL_GAIN_GREEN_R_LO			0x020F
-#define REG_DIGITAL_GAIN_RED_HI				0x0210
-#define REG_DIGITAL_GAIN_RED_LO				0x0211
-#define REG_DIGITAL_GAIN_BLUE_HI			0x0212
-#define REG_DIGITAL_GAIN_BLUE_LO			0x0213
-#define REG_DIGITAL_GAIN_GREEN_B_HI			0x0214
-#define REG_DIGITAL_GAIN_GREEN_B_LO			0x0215
-/* output bits setting */
-#define REG_0x0112					0x0112
-#define REG_0x0113					0x0113
-/* PLL registers */
-#define REG_VT_PIX_CLK_DIV				0x0301
-#define REG_PRE_PLL_CLK_DIV				0x0305
-#define REG_PLL_MULTIPLIER				0x0307
-#define REG_OP_PIX_CLK_DIV				0x0309
-#define REG_0x034c					0x034c
-#define REG_0x034d					0x034d
-#define REG_0x034e					0x034e
-#define REG_0x034f					0x034f
-#define REG_0x0387					0x0387
-#define REG_0x0383					0x0383
-#define REG_FRAME_LENGTH_LINES_HI			0x0340
-#define REG_FRAME_LENGTH_LINES_LO			0x0341
-#define REG_LINE_LENGTH_PCK_HI				0x0342
-#define REG_LINE_LENGTH_PCK_LO				0x0343
-#define REG_0x3030					0x3030
-#define REG_0x0111					0x0111
-#define REG_0x0136					0x0136
-#define REG_0x0137					0x0137
-#define REG_0x0b00					0x0b00
-#define REG_0x3001					0x3001
-#define REG_0x3004					0x3004
-#define REG_0x3007					0x3007
-#define REG_0x301a					0x301a
-#define REG_0x3101					0x3101
-#define REG_0x3364					0x3364
-#define REG_0x3365					0x3365
-#define REG_0x0b83					0x0b83
-#define REG_0x0b84					0x0b84
-#define REG_0x0b85					0x0b85
-#define REG_0x0b88					0x0b88
-#define REG_0x0b89					0x0b89
-#define REG_0x0b8a					0x0b8a
-#define REG_0x3005					0x3005
-#define REG_0x3010					0x3010
-#define REG_0x3036					0x3036
-#define REG_0x3041					0x3041
-#define REG_0x0b80					0x0b80
-#define REG_0x0900					0x0900
-#define REG_0x0901					0x0901
-#define REG_0x0902					0x0902
-#define REG_0x3016					0x3016
-#define REG_0x301d					0x301d
-#define REG_0x317e					0x317e
-#define REG_0x317f					0x317f
-#define REG_0x3400					0x3400
-#define REG_0x303a					0x303a
-#define REG_0x1716					0x1716
-#define REG_0x1717					0x1717
-#define REG_0x1718					0x1718
-#define REG_0x1719					0x1719
-#define REG_0x3006					0x3006
-#define REG_0x301b					0x301b
-#define REG_0x3098					0x3098
-#define REG_0x309d					0x309d
-#define REG_0x3011					0x3011
-#define REG_0x3035					0x3035
-#define REG_0x3045					0x3045
-#define REG_0x3210					0x3210
-#define	REG_0x0111					0x0111
-#define REG_0x3410					0x3410
-#define REG_0x0b06					0x0b06
-#define REG_0x0b07					0x0b07
-#define REG_0x0b08					0x0b08
-#define REG_0x0b09					0x0b09
-#define REG_0x3640					0x3640
-/* Test Pattern */
-#define REG_TEST_PATTERN_MODE				0x0601
-/* 16bit address - 8 bit context register structure */
-#define	VX6953_STM5M0EDOF_OFFSET	9
-#define	Q8		0x00000100
-#define	Q10		0x00000400
-#define	VX6953_STM5M0EDOF_MAX_SNAPSHOT_EXPOSURE_LINE_COUNT	2922
-#define	VX6953_STM5M0EDOF_DEFAULT_MASTER_CLK_RATE	24000000
-#define	VX6953_STM5M0EDOF_OP_PIXEL_CLOCK_RATE	79800000
-#define	VX6953_STM5M0EDOF_VT_PIXEL_CLOCK_RATE	88670000
-/* Full	Size */
-#define	VX6953_FULL_SIZE_WIDTH	2608
-#define	VX6953_FULL_SIZE_HEIGHT		1960
-#define	VX6953_FULL_SIZE_DUMMY_PIXELS	1
-#define	VX6953_FULL_SIZE_DUMMY_LINES	0
-/* Quarter Size	*/
-#define	VX6953_QTR_SIZE_WIDTH	1304
-#define	VX6953_QTR_SIZE_HEIGHT		980
-#define	VX6953_QTR_SIZE_DUMMY_PIXELS	1
-#define	VX6953_QTR_SIZE_DUMMY_LINES		0
-/* Blanking	as measured	on the scope */
-/* Full	Size */
-#define	VX6953_HRZ_FULL_BLK_PIXELS	348
-#define	VX6953_VER_FULL_BLK_LINES	40
-/* Quarter Size	*/
-#define	VX6953_HRZ_QTR_BLK_PIXELS	1628
-#define	VX6953_VER_QTR_BLK_LINES	28
-#define	MAX_LINE_LENGTH_PCK		8190
-#define	MAX_FRAME_LENGTH_LINES	16383
-#define	VX6953_REVISION_NUMBER_CUT2	0x10/*revision number	for	Cut2.0*/
-#define	VX6953_REVISION_NUMBER_CUT3	0x20/*revision number	for	Cut3.0*/
-static struct msm_sensor_ctrl_t vx6953_s_ctrl;
-static uint32_t fps_divider;/* init to 1 * 0x00000400 */
-static uint16_t fps;
-static uint8_t vx6953_stm5m0edof_delay_msecs_stdby;
-static struct msm_camera_i2c_reg_conf vx6953_start_settings[] = {
-	{0x0100, 0x01},
-};
-
-static struct msm_camera_i2c_reg_conf vx6953_stop_settings[] = {
-	{0x0100, 0x00},
-};
-
-static struct msm_camera_i2c_reg_conf vx6953_groupon_settings[] = {
-	{0x0104, 0x01},
-};
-
-static struct msm_camera_i2c_reg_conf vx6953_groupoff_settings[] = {
-	{0x0104, 0x00},
-};
-
-static struct msm_camera_i2c_reg_conf vx6953_prev_settings[] = {
-	{0x0202, 0x03},/*REG = 0x0202 coarse integration_time_hi*/
-	{0x0203, 0xD0},/*REG = 0x0203 coarse_integration_time_lo*/
-	{0x0205, 0xC0},/*REG = 0x0205 analogue_gain_code_global*/
-	{0x0340, 0x03},/*REG = 0x0340 frame_length_lines_hi*/
-	{0x0341, 0xf0},/*REG = 0x0341 frame_length_lines_lo*/
-	{0x0342, 0x0b},/*REG = 0x0342  line_length_pck_hi*/
-	{0x0343, 0x74},/*REG = 0x0343  line_length_pck_lo*/
-	{0x3005, 0x03},/*REG = 0x3005*/
-	{0x3010, 0x00},/*REG = 0x3010*/
-	{0x3011, 0x01},/*REG = 0x3011*/
-	{0x301a, 0x6a},/*REG = 0x301a*/
-	{0x3035, 0x03},/*REG = 0x3035*/
-	{0x3036, 0x2c},/*REG = 0x3036*/
-	{0x3041, 0x00},/*REG = 0x3041*/
-	{0x3042, 0x24},/*REG = 0x3042*/
-	{0x3045, 0x81},/*REG = 0x3045*/
-	{0x0b80, 0x02},/*REG = 0x0b80 edof estimate*/
-	{0x0900, 0x01},/*REG = 0x0900*/
-	{0x0901, 0x22},/*REG = 0x0901*/
-	{0x0902, 0x04},/*REG = 0x0902*/
-	{0x0383, 0x03},/*REG = 0x0383*/
-	{0x0387, 0x03},/*REG = 0x0387*/
-	{0x034c, 0x05},/*REG = 0x034c*/
-	{0x034d, 0x18},/*REG = 0x034d*/
-	{0x034e, 0x03},/*REG = 0x034e*/
-	{0x034f, 0xd4},/*REG = 0x034f*/
-	{0x1716, 0x02},/*0x1716*/
-	{0x1717, 0x04},/*0x1717*/
-	{0x1718, 0x08},/*0x1718*/
-	{0x1719, 0x2c},/*0x1719*/
-};
-
-static struct msm_camera_i2c_reg_conf vx6953_snap_settings[] = {
-	{0x0202, 0x07},/*REG = 0x0202 coarse_integration_time_hi*/
-	{0x0203, 0x00},/*REG = 0x0203 coarse_integration_time_lo*/
-	{0x0205, 0xc0},/*REG = 0x0205 analogue_gain_code_global*/
-	{0x0340, 0x07},/*REG = 0x0340 frame_length_lines_hi*/
-	{0x0341, 0xd0},/*REG = 0x0341 frame_length_lines_lo*/
-	{0x0342, 0x0b},/*REG = 0x0342 line_length_pck_hi*/
-	{0x0343, 0x8c},/*REG = 0x0343 line_length_pck_lo*/
-	{0x3005, 0x01},/*REG = 0x3005*/
-	{0x3010, 0x00},/*REG = 0x3010*/
-	{0x3011, 0x00},/*REG = 0x3011*/
-	{0x301a, 0x55},/*REG = 0x301a*/
-	{0x3035, 0x01},/*REG = 0x3035*/
-	{0x3036, 0x23},/*REG = 0x3036*/
-	{0x3041, 0x00},/*REG = 0x3041*/
-	{0x3042, 0x24},/*REG = 0x3042*/
-	{0x3045, 0xb7},/*REG = 0x3045*/
-	{0x0b80, 0x01},/*REG = 0x0b80 edof application*/
-	{0x0900, 0x00},/*REG = 0x0900*/
-	{0x0901, 0x00},/*REG = 0x0901*/
-	{0x0902, 0x00},/*REG = 0x0902*/
-	{0x0383, 0x01},/*REG = 0x0383*/
-	{0x0387, 0x01},/*REG = 0x0387*/
-	{0x034c, 0x0A},/*REG = 0x034c*/
-	{0x034d, 0x30},/*REG = 0x034d*/
-	{0x034e, 0x07},/*REG = 0x034e*/
-	{0x034f, 0xA8},/*REG = 0x034f*/
-	{0x1716, 0x02},/*0x1716*/
-	{0x1717, 0x0d},/*0x1717*/
-	{0x1718, 0x07},/*0x1718*/
-	{0x1719, 0x7d},/*0x1719*/
-};
-
-static struct msm_camera_i2c_reg_conf vx6953_recommend_settings[] = {
-	{0x0103, 0x01}, /* standby */
-	{0x0100, 0x00}, /* stop streaming */
-	/* patch cut 2*/
-	{0xFB94, 0},	/*intialise Data Xfer Status reg*/
-	{0xFB95, 0},	/*gain 1	  (0x00)*/
-	{0xFB96, 0},	/*gain 1.07   (0x10)*/
-	{0xFB97, 0},	/*gain 1.14   (0x20)*/
-	{0xFB98, 0},	/*gain 1.23   (0x30)*/
-	{0xFB99, 0},	/*gain 1.33   (0x40)*/
-	{0xFB9A, 0},	/*gain 1.45   (0x50)*/
-	{0xFB9B, 0},	/*gain 1.6    (0x60)*/
-	{0xFB9C, 0},	/*gain 1.78   (0x70)*/
-	{0xFB9D, 2},	/*gain 2	  (0x80)*/
-	{0xFB9E, 2},	/*gain 2.29   (0x90)*/
-	{0xFB9F, 3},	/*gain 2.67   (0xA0)*/
-	{0xFBA0, 3},	/*gain 3.2    (0xB0)*/
-	{0xFBA1, 4},	/*gain 4	  (0xC0)*/
-	{0xFBA2, 7},	/*gain 5.33   (0xD0)*/
-	{0xFBA3, 10},	/*gain 8	  (0xE0)*/
-	{0xFBA4, 11},	/*gain 9.14   (0xE4)*/
-	{0xFBA5, 13},	/*gain 10.67  (0xE8)*/
-	{0xFBA6, 15},	/*gain 12.8   (0xEC)*/
-	{0xFBA7, 19},	/*gain 16     (0xF0)*/
-	{0xF800, 0x12},
-	{0xF801, 0x06},
-	{0xF802, 0xf7},
-	{0xF803, 0x90},
-	{0xF804, 0x02},
-	{0xF805, 0x05},
-	{0xF806, 0xe0},
-	{0xF807, 0xff},
-	{0xF808, 0x65},
-	{0xF809, 0x7d},
-	{0xF80A, 0x70},
-	{0xF80B, 0x03},
-	{0xF80C, 0x02},
-	{0xF80D, 0xf9},
-	{0xF80E, 0x1c},
-	{0xF80F, 0x8f},
-	{0xF810, 0x7d},
-	{0xF811, 0xe4},
-	{0xF812, 0xf5},
-	{0xF813, 0x7a},
-	{0xF814, 0x75},
-	{0xF815, 0x78},
-	{0xF816, 0x30},
-	{0xF817, 0x75},
-	{0xF818, 0x79},
-	{0xF819, 0x53},
-	{0xF81A, 0x85},
-	{0xF81B, 0x79},
-	{0xF81C, 0x82},
-	{0xF81D, 0x85},
-	{0xF81E, 0x78},
-	{0xF81F, 0x83},
-	{0xF820, 0xe0},
-	{0xF821, 0xc3},
-	{0xF822, 0x95},
-	{0xF823, 0x7b},
-	{0xF824, 0xf0},
-	{0xF825, 0x74},
-	{0xF826, 0x02},
-	{0xF827, 0x25},
-	{0xF828, 0x79},
-	{0xF829, 0xf5},
-	{0xF82A, 0x79},
-	{0xF82B, 0xe4},
-	{0xF82C, 0x35},
-	{0xF82D, 0x78},
-	{0xF82E, 0xf5},
-	{0xF82F, 0x78},
-	{0xF830, 0x05},
-	{0xF831, 0x7a},
-	{0xF832, 0xe5},
-	{0xF833, 0x7a},
-	{0xF834, 0xb4},
-	{0xF835, 0x08},
-	{0xF836, 0xe3},
-	{0xF837, 0xe5},
-	{0xF838, 0x7d},
-	{0xF839, 0x70},
-	{0xF83A, 0x04},
-	{0xF83B, 0xff},
-	{0xF83C, 0x02},
-	{0xF83D, 0xf8},
-	{0xF83E, 0xe4},
-	{0xF83F, 0xe5},
-	{0xF840, 0x7d},
-	{0xF841, 0xb4},
-	{0xF842, 0x10},
-	{0xF843, 0x05},
-	{0xF844, 0x7f},
-	{0xF845, 0x01},
-	{0xF846, 0x02},
-	{0xF847, 0xf8},
-	{0xF848, 0xe4},
-	{0xF849, 0xe5},
-	{0xF84A, 0x7d},
-	{0xF84B, 0xb4},
-	{0xF84C, 0x20},
-	{0xF84D, 0x05},
-	{0xF84E, 0x7f},
-	{0xF84F, 0x02},
-	{0xF850, 0x02},
-	{0xF851, 0xf8},
-	{0xF852, 0xe4},
-	{0xF853, 0xe5},
-	{0xF854, 0x7d},
-	{0xF855, 0xb4},
-	{0xF856, 0x30},
-	{0xF857, 0x05},
-	{0xF858, 0x7f},
-	{0xF859, 0x03},
-	{0xF85A, 0x02},
-	{0xF85B, 0xf8},
-	{0xF85C, 0xe4},
-	{0xF85D, 0xe5},
-	{0xF85E, 0x7d},
-	{0xF85F, 0xb4},
-	{0xF860, 0x40},
-	{0xF861, 0x04},
-	{0xF862, 0x7f},
-	{0xF863, 0x04},
-	{0xF864, 0x80},
-	{0xF865, 0x7e},
-	{0xF866, 0xe5},
-	{0xF867, 0x7d},
-	{0xF868, 0xb4},
-	{0xF869, 0x50},
-	{0xF86A, 0x04},
-	{0xF86B, 0x7f},
-	{0xF86C, 0x05},
-	{0xF86D, 0x80},
-	{0xF86E, 0x75},
-	{0xF86F, 0xe5},
-	{0xF870, 0x7d},
-	{0xF871, 0xb4},
-	{0xF872, 0x60},
-	{0xF873, 0x04},
-	{0xF874, 0x7f},
-	{0xF875, 0x06},
-	{0xF876, 0x80},
-	{0xF877, 0x6c},
-	{0xF878, 0xe5},
-	{0xF879, 0x7d},
-	{0xF87A, 0xb4},
-	{0xF87B, 0x70},
-	{0xF87C, 0x04},
-	{0xF87D, 0x7f},
-	{0xF87E, 0x07},
-	{0xF87F, 0x80},
-	{0xF880, 0x63},
-	{0xF881, 0xe5},
-	{0xF882, 0x7d},
-	{0xF883, 0xb4},
-	{0xF884, 0x80},
-	{0xF885, 0x04},
-	{0xF886, 0x7f},
-	{0xF887, 0x08},
-	{0xF888, 0x80},
-	{0xF889, 0x5a},
-	{0xF88A, 0xe5},
-	{0xF88B, 0x7d},
-	{0xF88C, 0xb4},
-	{0xF88D, 0x90},
-	{0xF88E, 0x04},
-	{0xF88F, 0x7f},
-	{0xF890, 0x09},
-	{0xF891, 0x80},
-	{0xF892, 0x51},
-	{0xF893, 0xe5},
-	{0xF894, 0x7d},
-	{0xF895, 0xb4},
-	{0xF896, 0xa0},
-	{0xF897, 0x04},
-	{0xF898, 0x7f},
-	{0xF899, 0x0a},
-	{0xF89A, 0x80},
-	{0xF89B, 0x48},
-	{0xF89C, 0xe5},
-	{0xF89D, 0x7d},
-	{0xF89E, 0xb4},
-	{0xF89F, 0xb0},
-	{0xF8A0, 0x04},
-	{0xF8A1, 0x7f},
-	{0xF8A2, 0x0b},
-	{0xF8A3, 0x80},
-	{0xF8A4, 0x3f},
-	{0xF8A5, 0xe5},
-	{0xF8A6, 0x7d},
-	{0xF8A7, 0xb4},
-	{0xF8A8, 0xc0},
-	{0xF8A9, 0x04},
-	{0xF8AA, 0x7f},
-	{0xF8AB, 0x0c},
-	{0xF8AC, 0x80},
-	{0xF8AD, 0x36},
-	{0xF8AE, 0xe5},
-	{0xF8AF, 0x7d},
-	{0xF8B0, 0xb4},
-	{0xF8B1, 0xd0},
-	{0xF8B2, 0x04},
-	{0xF8B3, 0x7f},
-	{0xF8B4, 0x0d},
-	{0xF8B5, 0x80},
-	{0xF8B6, 0x2d},
-	{0xF8B7, 0xe5},
-	{0xF8B8, 0x7d},
-	{0xF8B9, 0xb4},
-	{0xF8BA, 0xe0},
-	{0xF8BB, 0x04},
-	{0xF8BC, 0x7f},
-	{0xF8BD, 0x0e},
-	{0xF8BE, 0x80},
-	{0xF8BF, 0x24},
-	{0xF8C0, 0xe5},
-	{0xF8C1, 0x7d},
-	{0xF8C2, 0xb4},
-	{0xF8C3, 0xe4},
-	{0xF8C4, 0x04},
-	{0xF8C5, 0x7f},
-	{0xF8C6, 0x0f},
-	{0xF8C7, 0x80},
-	{0xF8C8, 0x1b},
-	{0xF8C9, 0xe5},
-	{0xF8CA, 0x7d},
-	{0xF8CB, 0xb4},
-	{0xF8CC, 0xe8},
-	{0xF8CD, 0x04},
-	{0xF8CE, 0x7f},
-	{0xF8CF, 0x10},
-	{0xF8D0, 0x80},
-	{0xF8D1, 0x12},
-	{0xF8D2, 0xe5},
-	{0xF8D3, 0x7d},
-	{0xF8D4, 0xb4},
-	{0xF8D5, 0xec},
-	{0xF8D6, 0x04},
-	{0xF8D7, 0x7f},
-	{0xF8D8, 0x11},
-	{0xF8D9, 0x80},
-	{0xF8DA, 0x09},
-	{0xF8DB, 0xe5},
-	{0xF8DC, 0x7d},
-	{0xF8DD, 0x7f},
-	{0xF8DE, 0x00},
-	{0xF8DF, 0xb4},
-	{0xF8E0, 0xf0},
-	{0xF8E1, 0x02},
-	{0xF8E2, 0x7f},
-	{0xF8E3, 0x12},
-	{0xF8E4, 0x8f},
-	{0xF8E5, 0x7c},
-	{0xF8E6, 0xef},
-	{0xF8E7, 0x24},
-	{0xF8E8, 0x95},
-	{0xF8E9, 0xff},
-	{0xF8EA, 0xe4},
-	{0xF8EB, 0x34},
-	{0xF8EC, 0xfb},
-	{0xF8ED, 0x8f},
-	{0xF8EE, 0x82},
-	{0xF8EF, 0xf5},
-	{0xF8F0, 0x83},
-	{0xF8F1, 0xe4},
-	{0xF8F2, 0x93},
-	{0xF8F3, 0xf5},
-	{0xF8F4, 0x7c},
-	{0xF8F5, 0xf5},
-	{0xF8F6, 0x7b},
-	{0xF8F7, 0xe4},
-	{0xF8F8, 0xf5},
-	{0xF8F9, 0x7a},
-	{0xF8FA, 0x75},
-	{0xF8FB, 0x78},
-	{0xF8FC, 0x30},
-	{0xF8FD, 0x75},
-	{0xF8FE, 0x79},
-	{0xF8FF, 0x53},
-	{0xF900, 0x85},
-	{0xF901, 0x79},
-	{0xF902, 0x82},
-	{0xF903, 0x85},
-	{0xF904, 0x78},
-	{0xF905, 0x83},
-	{0xF906, 0xe0},
-	{0xF907, 0x25},
-	{0xF908, 0x7c},
-	{0xF909, 0xf0},
-	{0xF90A, 0x74},
-	{0xF90B, 0x02},
-	{0xF90C, 0x25},
-	{0xF90D, 0x79},
-	{0xF90E, 0xf5},
-	{0xF90F, 0x79},
-	{0xF910, 0xe4},
-	{0xF911, 0x35},
-	{0xF912, 0x78},
-	{0xF913, 0xf5},
-	{0xF914, 0x78},
-	{0xF915, 0x05},
-	{0xF916, 0x7a},
-	{0xF917, 0xe5},
-	{0xF918, 0x7a},
-	{0xF919, 0xb4},
-	{0xF91A, 0x08},
-	{0xF91B, 0xe4},
-	{0xF91C, 0x02},
-	{0xF91D, 0x18},
-	{0xF91E, 0x32},
-	{0xF91F, 0x22},
-	{0xF920, 0xf0},
-	{0xF921, 0x90},
-	{0xF922, 0xa0},
-	{0xF923, 0xf8},
-	{0xF924, 0xe0},
-	{0xF925, 0x70},
-	{0xF926, 0x02},
-	{0xF927, 0xa3},
-	{0xF928, 0xe0},
-	{0xF929, 0x70},
-	{0xF92A, 0x0a},
-	{0xF92B, 0x90},
-	{0xF92C, 0xa1},
-	{0xF92D, 0x10},
-	{0xF92E, 0xe0},
-	{0xF92F, 0xfe},
-	{0xF930, 0xa3},
-	{0xF931, 0xe0},
-	{0xF932, 0xff},
-	{0xF933, 0x80},
-	{0xF934, 0x04},
-	{0xF935, 0x7e},
-	{0xF936, 0x00},
-	{0xF937, 0x7f},
-	{0xF938, 0x00},
-	{0xF939, 0x8e},
-	{0xF93A, 0x7e},
-	{0xF93B, 0x8f},
-	{0xF93C, 0x7f},
-	{0xF93D, 0x90},
-	{0xF93E, 0x36},
-	{0xF93F, 0x0d},
-	{0xF940, 0xe0},
-	{0xF941, 0x44},
-	{0xF942, 0x02},
-	{0xF943, 0xf0},
-	{0xF944, 0x90},
-	{0xF945, 0x36},
-	{0xF946, 0x0e},
-	{0xF947, 0xe5},
-	{0xF948, 0x7e},
-	{0xF949, 0xf0},
-	{0xF94A, 0xa3},
-	{0xF94B, 0xe5},
-	{0xF94C, 0x7f},
-	{0xF94D, 0xf0},
-	{0xF94E, 0xe5},
-	{0xF94F, 0x3a},
-	{0xF950, 0x60},
-	{0xF951, 0x0c},
-	{0xF952, 0x90},
-	{0xF953, 0x36},
-	{0xF954, 0x09},
-	{0xF955, 0xe0},
-	{0xF956, 0x70},
-	{0xF957, 0x06},
-	{0xF958, 0x90},
-	{0xF959, 0x36},
-	{0xF95A, 0x08},
-	{0xF95B, 0xf0},
-	{0xF95C, 0xf5},
-	{0xF95D, 0x3a},
-	{0xF95E, 0x02},
-	{0xF95F, 0x03},
-	{0xF960, 0x94},
-	{0xF961, 0x22},
-	{0xF962, 0x78},
-	{0xF963, 0x07},
-	{0xF964, 0xe6},
-	{0xF965, 0xd3},
-	{0xF966, 0x94},
-	{0xF967, 0x00},
-	{0xF968, 0x40},
-	{0xF969, 0x16},
-	{0xF96A, 0x16},
-	{0xF96B, 0xe6},
-	{0xF96C, 0x90},
-	{0xF96D, 0x30},
-	{0xF96E, 0xa1},
-	{0xF96F, 0xf0},
-	{0xF970, 0x90},
-	{0xF971, 0x43},
-	{0xF972, 0x83},
-	{0xF973, 0xe0},
-	{0xF974, 0xb4},
-	{0xF975, 0x01},
-	{0xF976, 0x0f},
-	{0xF977, 0x90},
-	{0xF978, 0x43},
-	{0xF979, 0x87},
-	{0xF97A, 0xe0},
-	{0xF97B, 0xb4},
-	{0xF97C, 0x01},
-	{0xF97D, 0x08},
-	{0xF97E, 0x80},
-	{0xF97F, 0x00},
-	{0xF980, 0x90},
-	{0xF981, 0x30},
-	{0xF982, 0xa0},
-	{0xF983, 0x74},
-	{0xF984, 0x01},
-	{0xF985, 0xf0},
-	{0xF986, 0x22},
-	{0xF987, 0xf0},
-	{0xF988, 0x90},
-	{0xF989, 0x35},
-	{0xF98A, 0xba},
-	{0xF98B, 0xe0},
-	{0xF98C, 0xb4},
-	{0xF98D, 0x0a},
-	{0xF98E, 0x0d},
-	{0xF98F, 0xa3},
-	{0xF990, 0xe0},
-	{0xF991, 0xb4},
-	{0xF992, 0x01},
-	{0xF993, 0x08},
-	{0xF994, 0x90},
-	{0xF995, 0xfb},
-	{0xF996, 0x94},
-	{0xF997, 0xe0},
-	{0xF998, 0x90},
-	{0xF999, 0x35},
-	{0xF99A, 0xb8},
-	{0xF99B, 0xf0},
-	{0xF99C, 0xd0},
-	{0xF99D, 0xd0},
-	{0xF99E, 0xd0},
-	{0xF99F, 0x82},
-	{0xF9A0, 0xd0},
-	{0xF9A1, 0x83},
-	{0xF9A2, 0xd0},
-	{0xF9A3, 0xe0},
-	{0xF9A4, 0x32},
-	{0xF9A5, 0x22},
-	{0xF9A6, 0xe5},
-	{0xF9A7, 0x7f},
-	{0xF9A8, 0x45},
-	{0xF9A9, 0x7e},
-	{0xF9AA, 0x60},
-	{0xF9AB, 0x15},
-	{0xF9AC, 0x90},
-	{0xF9AD, 0x01},
-	{0xF9AE, 0x00},
-	{0xF9AF, 0xe0},
-	{0xF9B0, 0x70},
-	{0xF9B1, 0x0f},
-	{0xF9B2, 0x90},
-	{0xF9B3, 0xa0},
-	{0xF9B4, 0xf8},
-	{0xF9B5, 0xe5},
-	{0xF9B6, 0x7e},
-	{0xF9B7, 0xf0},
-	{0xF9B8, 0xa3},
-	{0xF9B9, 0xe5},
-	{0xF9BA, 0x7f},
-	{0xF9BB, 0xf0},
-	{0xF9BC, 0xe4},
-	{0xF9BD, 0xf5},
-	{0xF9BE, 0x7e},
-	{0xF9BF, 0xf5},
-	{0xF9C0, 0x7f},
-	{0xF9C1, 0x22},
-	{0xF9C2, 0x02},
-	{0xF9C3, 0x0e},
-	{0xF9C4, 0x79},
-	{0xF9C5, 0x22},
-	/* Offsets:*/
-	{0x35C6, 0x00},/* FIDDLEDARKCAL*/
-	{0x35C7, 0x00},
-	{0x35C8, 0x01},/*STOREDISTANCEATSTOPSTREAMING*/
-	{0x35C9, 0x20},
-	{0x35CA, 0x01},/*BRUCEFIX*/
-	{0x35CB, 0x62},
-	{0x35CC, 0x01},/*FIXDATAXFERSTATUSREG*/
-	{0x35CD, 0x87},
-	{0x35CE, 0x01},/*FOCUSDISTANCEUPDATE*/
-	{0x35CF, 0xA6},
-	{0x35D0, 0x01},/*SKIPEDOFRESET*/
-	{0x35D1, 0xC2},
-	{0x35D2, 0x00},
-	{0x35D3, 0xFB},
-	{0x35D4, 0x00},
-	{0x35D5, 0x94},
-	{0x35D6, 0x00},
-	{0x35D7, 0xFB},
-	{0x35D8, 0x00},
-	{0x35D9, 0x94},
-	{0x35DA, 0x00},
-	{0x35DB, 0xFB},
-	{0x35DC, 0x00},
-	{0x35DD, 0x94},
-	{0x35DE, 0x00},
-	{0x35DF, 0xFB},
-	{0x35E0, 0x00},
-	{0x35E1, 0x94},
-	{0x35E6, 0x18},/* FIDDLEDARKCAL*/
-	{0x35E7, 0x2F},
-	{0x35E8, 0x03},/* STOREDISTANCEATSTOPSTREAMING*/
-	{0x35E9, 0x93},
-	{0x35EA, 0x18},/* BRUCEFIX*/
-	{0x35EB, 0x99},
-	{0x35EC, 0x00},/* FIXDATAXFERSTATUSREG*/
-	{0x35ED, 0xA3},
-	{0x35EE, 0x21},/* FOCUSDISTANCEUPDATE*/
-	{0x35EF, 0x5B},
-	{0x35F0, 0x0E},/* SKIPEDOFRESET*/
-	{0x35F1, 0x74},
-	{0x35F2, 0x04},
-	{0x35F3, 0x64},
-	{0x35F4, 0x04},
-	{0x35F5, 0x65},
-	{0x35F6, 0x04},
-	{0x35F7, 0x7B},
-	{0x35F8, 0x04},
-	{0x35F9, 0x7C},
-	{0x35FA, 0x04},
-	{0x35FB, 0xDD},
-	{0x35FC, 0x04},
-	{0x35FD, 0xDE},
-	{0x35FE, 0x04},
-	{0x35FF, 0xEF},
-	{0x3600, 0x04},
-	{0x3601, 0xF0},
-	/*Jump/Data:*/
-	{0x35C2, 0x3F},/* Jump Reg*/
-	{0x35C3, 0xFF},/* Jump Reg*/
-	{0x35C4, 0x3F},/* Data Reg*/
-	{0x35C5, 0xC0},/* Data Reg*/
-	{0x35C0, 0x01},/* Enable*/
-	/* end of patch cut 2 */
-	/* common settings */
-	{0x0112, 10},/*REG = 0x0112 , 10 bit */
-	{0x0113, 10},/*REG = 0x0113*/
-	{0x0301, 9},/*REG = 0x0301 vt_pix_clk_div*/
-	{0x0305, 4},/*REG = 0x0305 pre_pll_clk_div*/
-	{0x0307, 133},/*REG = 0x0307 pll_multiplier*/
-	{0x0309, 10},/*REG = 0x0309 op_pix_clk_div*/
-	{0x3030, 0x08},/*REG = 0x3030*/
-	{0x0111, 0x02},/*REG = 0x0111*/
-	{0x0b00, 0x01},/*REG = 0x0b00 ,lens shading off */
-	{0x3001, 0x30},/*REG = 0x3001*/
-	{0x3004, 0x33},/*REG = 0x3004*/
-	{0x3007, 0x09},/*REG = 0x3007*/
-	{0x3016, 0x1F},/*REG = 0x3016*/
-	{0x301d, 0x03},/*REG = 0x301d*/
-	{0x317E, 0x11},/*REG = 0x317E*/
-	{0x317F, 0x09},/*REG = 0x317F*/
-	{0x3400, 0x38},/*REG = 0x3400*/
-	{0x0b06, 0x00},/*REG_0x0b06*/
-	{0x0b07, 0x80},/*REG_0x0b07*/
-	{0x0b08, 0x01},/*REG_0x0b08*/
-	{0x0b09, 0x4F},/*REG_0x0b09*/
-	{0x0136, 0x18},/*REG_0x0136*/
-	{0x0137, 0x00},/*/REG_0x0137*/
-	{0x0b83, 0x20},/*REG = 0x0b83*/
-	{0x0b84, 0x90},/*REG = 0x0b84*/
-	{0x0b85, 0x20},/*REG = 0x0b85*/
-	{0x0b88, 0x80},/*REG = 0x0b88*/
-	{0x0b89, 0x00},/*REG = 0x0b89*/
-	{0x0b8a, 0x00},/*REG = 0x0b8a*/
-	/* end of common settings */
-};
-
-static struct v4l2_subdev_info vx6953_subdev_info[] = {
-	{
-	.code   = V4L2_MBUS_FMT_SGRBG10_1X10,
-	.colorspace = V4L2_COLORSPACE_JPEG,
-	.fmt    = 1,
-	.order    = 0,
-	},
-	/* more can be supported, to be added later */
-};
-
-static struct msm_camera_i2c_conf_array vx6953_init_conf[] = {
-	{&vx6953_recommend_settings[0],
-	ARRAY_SIZE(vx6953_recommend_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}
-};
-
-static struct msm_camera_i2c_conf_array vx6953_confs[] = {
-	{&vx6953_snap_settings[0],
-	ARRAY_SIZE(vx6953_snap_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
-	{&vx6953_prev_settings[0],
-	ARRAY_SIZE(vx6953_prev_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
-};
-
-static struct msm_sensor_output_info_t vx6953_dimensions[] = {
-	{
-		.x_output = 0xA30,
-		.y_output = 0x7A8,
-		.line_length_pclk = 0xB8C,
-		.frame_length_lines = 0x7D0,
-		.vt_pixel_clk = 88666666,
-		.op_pixel_clk = 192000000,
-		.binning_factor = 1,
-	},
-	{
-		.x_output = 0x518,
-		.y_output = 0x3D4,
-		.line_length_pclk = 0xB74,
-		.frame_length_lines = 0x3F0,
-		.vt_pixel_clk = 88666666,
-		.op_pixel_clk = 192000000,
-		.binning_factor = 1,
-	},
-};
-
-static struct msm_sensor_output_reg_addr_t vx6953_reg_addr = {
-	.x_output = 0x034C,
-	.y_output = 0x034E,
-	.line_length_pclk = 0x0342,
-	.frame_length_lines = 0x0340,
-};
-
-static struct msm_sensor_id_info_t vx6953_id_info = {
-	.sensor_id_reg_addr = 0x0000,
-	.sensor_id = 0x03B9,
-};
-
-static struct msm_sensor_exp_gain_info_t vx6953_exp_gain_info = {
-	.coarse_int_time_addr = 0x0202,
-	.global_gain_addr = 0x0204,
-	.vert_offset = 9,
-};
-
-static const struct i2c_device_id vx6953_i2c_id[] = {
-	{SENSOR_NAME, (kernel_ulong_t)&vx6953_s_ctrl},
-	{ }
-};
-
-static struct i2c_driver vx6953_i2c_driver = {
-	.id_table = vx6953_i2c_id,
-	.probe  = msm_sensor_i2c_probe,
-	.driver = {
-		.name = SENSOR_NAME,
-	},
-};
-
-static struct msm_camera_i2c_client vx6953_sensor_i2c_client = {
-	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
-};
-
-static int __init msm_sensor_init_module(void)
-{
-	return i2c_add_driver(&vx6953_i2c_driver);
-}
-
-static int32_t vx6953_set_fps(struct msm_sensor_ctrl_t *s_ctrl,
-	struct fps_cfg *fps) {
-	return 0;
-}
-
-int32_t vx6953_write_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
-	uint16_t gain, uint32_t line) {
-	return 0;
-}
-
-static struct v4l2_subdev_core_ops vx6953_subdev_core_ops = {
-	.ioctl = msm_sensor_subdev_ioctl,
-	.s_power = msm_sensor_power,
-};
-
-static struct v4l2_subdev_video_ops vx6953_subdev_video_ops = {
-	.enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
-};
-
-static struct v4l2_subdev_ops vx6953_subdev_ops = {
-	.core = &vx6953_subdev_core_ops,
-	.video  = &vx6953_subdev_video_ops,
-};
-
-static struct msm_camera_i2c_reg_conf vx6953_edof_estimation[] = {
-	{REG_0x0b80, 0x02},
-};
-
-static struct msm_camera_i2c_reg_conf vx6953_edof_application[] = {
-	{REG_0x0b80, 0x01},
-};
-
-static struct msm_camera_i2c_reg_conf vx6953_edof_default[] = {
-	{REG_0x0b80, 0x00},
-};
-
-static int vx6953_enable_edof(enum edof_mode_t edof_mode)
-{
-	int rc = 0;
-	if (edof_mode == VX6953_EDOF_ESTIMATION) {
-		/* EDof Estimation mode for preview */
-		msm_camera_i2c_write_tbl(
-			vx6953_s_ctrl.sensor_i2c_client,
-			vx6953_edof_estimation,
-			ARRAY_SIZE(vx6953_edof_estimation),
-			vx6953_s_ctrl.msm_sensor_reg->default_data_type);
-		CDBG("VX6953_EDOF_ESTIMATION");
-	} else if (edof_mode == VX6953_EDOF_APPLICATION) {
-		/* EDof Application mode for Capture */
-		msm_camera_i2c_write_tbl(
-			vx6953_s_ctrl.sensor_i2c_client,
-			vx6953_edof_application,
-			ARRAY_SIZE(vx6953_edof_application),
-			vx6953_s_ctrl.msm_sensor_reg->default_data_type);
-		CDBG("VX6953_EDOF_APPLICATION");
-	} else {
-		/* EDOF disabled */
-		msm_camera_i2c_write_tbl(
-			vx6953_s_ctrl.sensor_i2c_client,
-			vx6953_edof_default,
-			ARRAY_SIZE(vx6953_edof_default),
-			vx6953_s_ctrl.msm_sensor_reg->default_data_type);
-		CDBG("VX6953_EDOF_DISABLE");
-	}
-	return rc;
-}
-
-static struct msm_camera_i2c_reg_conf vx6953_standby[] = {
-	{0x103, 0x01},
-};
-
-static struct msm_camera_i2c_reg_conf patch_tbl_cut2[] = {
-	{0xFB94, 0},	/*intialise Data Xfer Status reg*/
-	{0xFB95, 0},	/*gain 1	  (0x00)*/
-	{0xFB96, 0},	/*gain 1.07   (0x10)*/
-	{0xFB97, 0},	/*gain 1.14   (0x20)*/
-	{0xFB98, 0},	/*gain 1.23   (0x30)*/
-	{0xFB99, 0},	/*gain 1.33   (0x40)*/
-	{0xFB9A, 0},	/*gain 1.45   (0x50)*/
-	{0xFB9B, 0},	/*gain 1.6    (0x60)*/
-	{0xFB9C, 0},	/*gain 1.78   (0x70)*/
-	{0xFB9D, 2},	/*gain 2	  (0x80)*/
-	{0xFB9E, 2},	/*gain 2.29   (0x90)*/
-	{0xFB9F, 3},	/*gain 2.67   (0xA0)*/
-	{0xFBA0, 3},	/*gain 3.2    (0xB0)*/
-	{0xFBA1, 4},	/*gain 4	  (0xC0)*/
-	{0xFBA2, 7},	/*gain 5.33   (0xD0)*/
-	{0xFBA3, 10},	/*gain 8	  (0xE0)*/
-	{0xFBA4, 11},	/*gain 9.14   (0xE4)*/
-	{0xFBA5, 13},	/*gain 10.67  (0xE8)*/
-	{0xFBA6, 15},	/*gain 12.8   (0xEC)*/
-	{0xFBA7, 19},	/*gain 16     (0xF0)*/
-	{0xF800, 0x12},
-	{0xF801, 0x06},
-	{0xF802, 0xf7},
-	{0xF803, 0x90},
-	{0xF804, 0x02},
-	{0xF805, 0x05},
-	{0xF806, 0xe0},
-	{0xF807, 0xff},
-	{0xF808, 0x65},
-	{0xF809, 0x7d},
-	{0xF80A, 0x70},
-	{0xF80B, 0x03},
-	{0xF80C, 0x02},
-	{0xF80D, 0xf9},
-	{0xF80E, 0x1c},
-	{0xF80F, 0x8f},
-	{0xF810, 0x7d},
-	{0xF811, 0xe4},
-	{0xF812, 0xf5},
-	{0xF813, 0x7a},
-	{0xF814, 0x75},
-	{0xF815, 0x78},
-	{0xF816, 0x30},
-	{0xF817, 0x75},
-	{0xF818, 0x79},
-	{0xF819, 0x53},
-	{0xF81A, 0x85},
-	{0xF81B, 0x79},
-	{0xF81C, 0x82},
-	{0xF81D, 0x85},
-	{0xF81E, 0x78},
-	{0xF81F, 0x83},
-	{0xF820, 0xe0},
-	{0xF821, 0xc3},
-	{0xF822, 0x95},
-	{0xF823, 0x7b},
-	{0xF824, 0xf0},
-	{0xF825, 0x74},
-	{0xF826, 0x02},
-	{0xF827, 0x25},
-	{0xF828, 0x79},
-	{0xF829, 0xf5},
-	{0xF82A, 0x79},
-	{0xF82B, 0xe4},
-	{0xF82C, 0x35},
-	{0xF82D, 0x78},
-	{0xF82E, 0xf5},
-	{0xF82F, 0x78},
-	{0xF830, 0x05},
-	{0xF831, 0x7a},
-	{0xF832, 0xe5},
-	{0xF833, 0x7a},
-	{0xF834, 0xb4},
-	{0xF835, 0x08},
-	{0xF836, 0xe3},
-	{0xF837, 0xe5},
-	{0xF838, 0x7d},
-	{0xF839, 0x70},
-	{0xF83A, 0x04},
-	{0xF83B, 0xff},
-	{0xF83C, 0x02},
-	{0xF83D, 0xf8},
-	{0xF83E, 0xe4},
-	{0xF83F, 0xe5},
-	{0xF840, 0x7d},
-	{0xF841, 0xb4},
-	{0xF842, 0x10},
-	{0xF843, 0x05},
-	{0xF844, 0x7f},
-	{0xF845, 0x01},
-	{0xF846, 0x02},
-	{0xF847, 0xf8},
-	{0xF848, 0xe4},
-	{0xF849, 0xe5},
-	{0xF84A, 0x7d},
-	{0xF84B, 0xb4},
-	{0xF84C, 0x20},
-	{0xF84D, 0x05},
-	{0xF84E, 0x7f},
-	{0xF84F, 0x02},
-	{0xF850, 0x02},
-	{0xF851, 0xf8},
-	{0xF852, 0xe4},
-	{0xF853, 0xe5},
-	{0xF854, 0x7d},
-	{0xF855, 0xb4},
-	{0xF856, 0x30},
-	{0xF857, 0x05},
-	{0xF858, 0x7f},
-	{0xF859, 0x03},
-	{0xF85A, 0x02},
-	{0xF85B, 0xf8},
-	{0xF85C, 0xe4},
-	{0xF85D, 0xe5},
-	{0xF85E, 0x7d},
-	{0xF85F, 0xb4},
-	{0xF860, 0x40},
-	{0xF861, 0x04},
-	{0xF862, 0x7f},
-	{0xF863, 0x04},
-	{0xF864, 0x80},
-	{0xF865, 0x7e},
-	{0xF866, 0xe5},
-	{0xF867, 0x7d},
-	{0xF868, 0xb4},
-	{0xF869, 0x50},
-	{0xF86A, 0x04},
-	{0xF86B, 0x7f},
-	{0xF86C, 0x05},
-	{0xF86D, 0x80},
-	{0xF86E, 0x75},
-	{0xF86F, 0xe5},
-	{0xF870, 0x7d},
-	{0xF871, 0xb4},
-	{0xF872, 0x60},
-	{0xF873, 0x04},
-	{0xF874, 0x7f},
-	{0xF875, 0x06},
-	{0xF876, 0x80},
-	{0xF877, 0x6c},
-	{0xF878, 0xe5},
-	{0xF879, 0x7d},
-	{0xF87A, 0xb4},
-	{0xF87B, 0x70},
-	{0xF87C, 0x04},
-	{0xF87D, 0x7f},
-	{0xF87E, 0x07},
-	{0xF87F, 0x80},
-	{0xF880, 0x63},
-	{0xF881, 0xe5},
-	{0xF882, 0x7d},
-	{0xF883, 0xb4},
-	{0xF884, 0x80},
-	{0xF885, 0x04},
-	{0xF886, 0x7f},
-	{0xF887, 0x08},
-	{0xF888, 0x80},
-	{0xF889, 0x5a},
-	{0xF88A, 0xe5},
-	{0xF88B, 0x7d},
-	{0xF88C, 0xb4},
-	{0xF88D, 0x90},
-	{0xF88E, 0x04},
-	{0xF88F, 0x7f},
-	{0xF890, 0x09},
-	{0xF891, 0x80},
-	{0xF892, 0x51},
-	{0xF893, 0xe5},
-	{0xF894, 0x7d},
-	{0xF895, 0xb4},
-	{0xF896, 0xa0},
-	{0xF897, 0x04},
-	{0xF898, 0x7f},
-	{0xF899, 0x0a},
-	{0xF89A, 0x80},
-	{0xF89B, 0x48},
-	{0xF89C, 0xe5},
-	{0xF89D, 0x7d},
-	{0xF89E, 0xb4},
-	{0xF89F, 0xb0},
-	{0xF8A0, 0x04},
-	{0xF8A1, 0x7f},
-	{0xF8A2, 0x0b},
-	{0xF8A3, 0x80},
-	{0xF8A4, 0x3f},
-	{0xF8A5, 0xe5},
-	{0xF8A6, 0x7d},
-	{0xF8A7, 0xb4},
-	{0xF8A8, 0xc0},
-	{0xF8A9, 0x04},
-	{0xF8AA, 0x7f},
-	{0xF8AB, 0x0c},
-	{0xF8AC, 0x80},
-	{0xF8AD, 0x36},
-	{0xF8AE, 0xe5},
-	{0xF8AF, 0x7d},
-	{0xF8B0, 0xb4},
-	{0xF8B1, 0xd0},
-	{0xF8B2, 0x04},
-	{0xF8B3, 0x7f},
-	{0xF8B4, 0x0d},
-	{0xF8B5, 0x80},
-	{0xF8B6, 0x2d},
-	{0xF8B7, 0xe5},
-	{0xF8B8, 0x7d},
-	{0xF8B9, 0xb4},
-	{0xF8BA, 0xe0},
-	{0xF8BB, 0x04},
-	{0xF8BC, 0x7f},
-	{0xF8BD, 0x0e},
-	{0xF8BE, 0x80},
-	{0xF8BF, 0x24},
-	{0xF8C0, 0xe5},
-	{0xF8C1, 0x7d},
-	{0xF8C2, 0xb4},
-	{0xF8C3, 0xe4},
-	{0xF8C4, 0x04},
-	{0xF8C5, 0x7f},
-	{0xF8C6, 0x0f},
-	{0xF8C7, 0x80},
-	{0xF8C8, 0x1b},
-	{0xF8C9, 0xe5},
-	{0xF8CA, 0x7d},
-	{0xF8CB, 0xb4},
-	{0xF8CC, 0xe8},
-	{0xF8CD, 0x04},
-	{0xF8CE, 0x7f},
-	{0xF8CF, 0x10},
-	{0xF8D0, 0x80},
-	{0xF8D1, 0x12},
-	{0xF8D2, 0xe5},
-	{0xF8D3, 0x7d},
-	{0xF8D4, 0xb4},
-	{0xF8D5, 0xec},
-	{0xF8D6, 0x04},
-	{0xF8D7, 0x7f},
-	{0xF8D8, 0x11},
-	{0xF8D9, 0x80},
-	{0xF8DA, 0x09},
-	{0xF8DB, 0xe5},
-	{0xF8DC, 0x7d},
-	{0xF8DD, 0x7f},
-	{0xF8DE, 0x00},
-	{0xF8DF, 0xb4},
-	{0xF8E0, 0xf0},
-	{0xF8E1, 0x02},
-	{0xF8E2, 0x7f},
-	{0xF8E3, 0x12},
-	{0xF8E4, 0x8f},
-	{0xF8E5, 0x7c},
-	{0xF8E6, 0xef},
-	{0xF8E7, 0x24},
-	{0xF8E8, 0x95},
-	{0xF8E9, 0xff},
-	{0xF8EA, 0xe4},
-	{0xF8EB, 0x34},
-	{0xF8EC, 0xfb},
-	{0xF8ED, 0x8f},
-	{0xF8EE, 0x82},
-	{0xF8EF, 0xf5},
-	{0xF8F0, 0x83},
-	{0xF8F1, 0xe4},
-	{0xF8F2, 0x93},
-	{0xF8F3, 0xf5},
-	{0xF8F4, 0x7c},
-	{0xF8F5, 0xf5},
-	{0xF8F6, 0x7b},
-	{0xF8F7, 0xe4},
-	{0xF8F8, 0xf5},
-	{0xF8F9, 0x7a},
-	{0xF8FA, 0x75},
-	{0xF8FB, 0x78},
-	{0xF8FC, 0x30},
-	{0xF8FD, 0x75},
-	{0xF8FE, 0x79},
-	{0xF8FF, 0x53},
-	{0xF900, 0x85},
-	{0xF901, 0x79},
-	{0xF902, 0x82},
-	{0xF903, 0x85},
-	{0xF904, 0x78},
-	{0xF905, 0x83},
-	{0xF906, 0xe0},
-	{0xF907, 0x25},
-	{0xF908, 0x7c},
-	{0xF909, 0xf0},
-	{0xF90A, 0x74},
-	{0xF90B, 0x02},
-	{0xF90C, 0x25},
-	{0xF90D, 0x79},
-	{0xF90E, 0xf5},
-	{0xF90F, 0x79},
-	{0xF910, 0xe4},
-	{0xF911, 0x35},
-	{0xF912, 0x78},
-	{0xF913, 0xf5},
-	{0xF914, 0x78},
-	{0xF915, 0x05},
-	{0xF916, 0x7a},
-	{0xF917, 0xe5},
-	{0xF918, 0x7a},
-	{0xF919, 0xb4},
-	{0xF91A, 0x08},
-	{0xF91B, 0xe4},
-	{0xF91C, 0x02},
-	{0xF91D, 0x18},
-	{0xF91E, 0x32},
-	{0xF91F, 0x22},
-	{0xF920, 0xf0},
-	{0xF921, 0x90},
-	{0xF922, 0xa0},
-	{0xF923, 0xf8},
-	{0xF924, 0xe0},
-	{0xF925, 0x70},
-	{0xF926, 0x02},
-	{0xF927, 0xa3},
-	{0xF928, 0xe0},
-	{0xF929, 0x70},
-	{0xF92A, 0x0a},
-	{0xF92B, 0x90},
-	{0xF92C, 0xa1},
-	{0xF92D, 0x10},
-	{0xF92E, 0xe0},
-	{0xF92F, 0xfe},
-	{0xF930, 0xa3},
-	{0xF931, 0xe0},
-	{0xF932, 0xff},
-	{0xF933, 0x80},
-	{0xF934, 0x04},
-	{0xF935, 0x7e},
-	{0xF936, 0x00},
-	{0xF937, 0x7f},
-	{0xF938, 0x00},
-	{0xF939, 0x8e},
-	{0xF93A, 0x7e},
-	{0xF93B, 0x8f},
-	{0xF93C, 0x7f},
-	{0xF93D, 0x90},
-	{0xF93E, 0x36},
-	{0xF93F, 0x0d},
-	{0xF940, 0xe0},
-	{0xF941, 0x44},
-	{0xF942, 0x02},
-	{0xF943, 0xf0},
-	{0xF944, 0x90},
-	{0xF945, 0x36},
-	{0xF946, 0x0e},
-	{0xF947, 0xe5},
-	{0xF948, 0x7e},
-	{0xF949, 0xf0},
-	{0xF94A, 0xa3},
-	{0xF94B, 0xe5},
-	{0xF94C, 0x7f},
-	{0xF94D, 0xf0},
-	{0xF94E, 0xe5},
-	{0xF94F, 0x3a},
-	{0xF950, 0x60},
-	{0xF951, 0x0c},
-	{0xF952, 0x90},
-	{0xF953, 0x36},
-	{0xF954, 0x09},
-	{0xF955, 0xe0},
-	{0xF956, 0x70},
-	{0xF957, 0x06},
-	{0xF958, 0x90},
-	{0xF959, 0x36},
-	{0xF95A, 0x08},
-	{0xF95B, 0xf0},
-	{0xF95C, 0xf5},
-	{0xF95D, 0x3a},
-	{0xF95E, 0x02},
-	{0xF95F, 0x03},
-	{0xF960, 0x94},
-	{0xF961, 0x22},
-	{0xF962, 0x78},
-	{0xF963, 0x07},
-	{0xF964, 0xe6},
-	{0xF965, 0xd3},
-	{0xF966, 0x94},
-	{0xF967, 0x00},
-	{0xF968, 0x40},
-	{0xF969, 0x16},
-	{0xF96A, 0x16},
-	{0xF96B, 0xe6},
-	{0xF96C, 0x90},
-	{0xF96D, 0x30},
-	{0xF96E, 0xa1},
-	{0xF96F, 0xf0},
-	{0xF970, 0x90},
-	{0xF971, 0x43},
-	{0xF972, 0x83},
-	{0xF973, 0xe0},
-	{0xF974, 0xb4},
-	{0xF975, 0x01},
-	{0xF976, 0x0f},
-	{0xF977, 0x90},
-	{0xF978, 0x43},
-	{0xF979, 0x87},
-	{0xF97A, 0xe0},
-	{0xF97B, 0xb4},
-	{0xF97C, 0x01},
-	{0xF97D, 0x08},
-	{0xF97E, 0x80},
-	{0xF97F, 0x00},
-	{0xF980, 0x90},
-	{0xF981, 0x30},
-	{0xF982, 0xa0},
-	{0xF983, 0x74},
-	{0xF984, 0x01},
-	{0xF985, 0xf0},
-	{0xF986, 0x22},
-	{0xF987, 0xf0},
-	{0xF988, 0x90},
-	{0xF989, 0x35},
-	{0xF98A, 0xba},
-	{0xF98B, 0xe0},
-	{0xF98C, 0xb4},
-	{0xF98D, 0x0a},
-	{0xF98E, 0x0d},
-	{0xF98F, 0xa3},
-	{0xF990, 0xe0},
-	{0xF991, 0xb4},
-	{0xF992, 0x01},
-	{0xF993, 0x08},
-	{0xF994, 0x90},
-	{0xF995, 0xfb},
-	{0xF996, 0x94},
-	{0xF997, 0xe0},
-	{0xF998, 0x90},
-	{0xF999, 0x35},
-	{0xF99A, 0xb8},
-	{0xF99B, 0xf0},
-	{0xF99C, 0xd0},
-	{0xF99D, 0xd0},
-	{0xF99E, 0xd0},
-	{0xF99F, 0x82},
-	{0xF9A0, 0xd0},
-	{0xF9A1, 0x83},
-	{0xF9A2, 0xd0},
-	{0xF9A3, 0xe0},
-	{0xF9A4, 0x32},
-	{0xF9A5, 0x22},
-	{0xF9A6, 0xe5},
-	{0xF9A7, 0x7f},
-	{0xF9A8, 0x45},
-	{0xF9A9, 0x7e},
-	{0xF9AA, 0x60},
-	{0xF9AB, 0x15},
-	{0xF9AC, 0x90},
-	{0xF9AD, 0x01},
-	{0xF9AE, 0x00},
-	{0xF9AF, 0xe0},
-	{0xF9B0, 0x70},
-	{0xF9B1, 0x0f},
-	{0xF9B2, 0x90},
-	{0xF9B3, 0xa0},
-	{0xF9B4, 0xf8},
-	{0xF9B5, 0xe5},
-	{0xF9B6, 0x7e},
-	{0xF9B7, 0xf0},
-	{0xF9B8, 0xa3},
-	{0xF9B9, 0xe5},
-	{0xF9BA, 0x7f},
-	{0xF9BB, 0xf0},
-	{0xF9BC, 0xe4},
-	{0xF9BD, 0xf5},
-	{0xF9BE, 0x7e},
-	{0xF9BF, 0xf5},
-	{0xF9C0, 0x7f},
-	{0xF9C1, 0x22},
-	{0xF9C2, 0x02},
-	{0xF9C3, 0x0e},
-	{0xF9C4, 0x79},
-	{0xF9C5, 0x22},
-	/* Offsets:*/
-	{0x35C6, 0x00},/* FIDDLEDARKCAL*/
-	{0x35C7, 0x00},
-	{0x35C8, 0x01},/*STOREDISTANCEATSTOPSTREAMING*/
-	{0x35C9, 0x20},
-	{0x35CA, 0x01},/*BRUCEFIX*/
-	{0x35CB, 0x62},
-	{0x35CC, 0x01},/*FIXDATAXFERSTATUSREG*/
-	{0x35CD, 0x87},
-	{0x35CE, 0x01},/*FOCUSDISTANCEUPDATE*/
-	{0x35CF, 0xA6},
-	{0x35D0, 0x01},/*SKIPEDOFRESET*/
-	{0x35D1, 0xC2},
-	{0x35D2, 0x00},
-	{0x35D3, 0xFB},
-	{0x35D4, 0x00},
-	{0x35D5, 0x94},
-	{0x35D6, 0x00},
-	{0x35D7, 0xFB},
-	{0x35D8, 0x00},
-	{0x35D9, 0x94},
-	{0x35DA, 0x00},
-	{0x35DB, 0xFB},
-	{0x35DC, 0x00},
-	{0x35DD, 0x94},
-	{0x35DE, 0x00},
-	{0x35DF, 0xFB},
-	{0x35E0, 0x00},
-	{0x35E1, 0x94},
-	{0x35E6, 0x18},/* FIDDLEDARKCAL*/
-	{0x35E7, 0x2F},
-	{0x35E8, 0x03},/* STOREDISTANCEATSTOPSTREAMING*/
-	{0x35E9, 0x93},
-	{0x35EA, 0x18},/* BRUCEFIX*/
-	{0x35EB, 0x99},
-	{0x35EC, 0x00},/* FIXDATAXFERSTATUSREG*/
-	{0x35ED, 0xA3},
-	{0x35EE, 0x21},/* FOCUSDISTANCEUPDATE*/
-	{0x35EF, 0x5B},
-	{0x35F0, 0x0E},/* SKIPEDOFRESET*/
-	{0x35F1, 0x74},
-	{0x35F2, 0x04},
-	{0x35F3, 0x64},
-	{0x35F4, 0x04},
-	{0x35F5, 0x65},
-	{0x35F6, 0x04},
-	{0x35F7, 0x7B},
-	{0x35F8, 0x04},
-	{0x35F9, 0x7C},
-	{0x35FA, 0x04},
-	{0x35FB, 0xDD},
-	{0x35FC, 0x04},
-	{0x35FD, 0xDE},
-	{0x35FE, 0x04},
-	{0x35FF, 0xEF},
-	{0x3600, 0x04},
-	{0x3601, 0xF0},
-	/*Jump/Data:*/
-	{0x35C2, 0x3F},/* Jump Reg*/
-	{0x35C3, 0xFF},/* Jump Reg*/
-	{0x35C4, 0x3F},/* Data Reg*/
-	{0x35C5, 0xC0},/* Data Reg*/
-	{0x35C0, 0x01},/* Enable*/
-};
-struct msm_camera_i2c_reg_conf init_tbl[] = {
-	{0x0112, 10},
-	{0x0113, 10},
-	{0x0301, 9},
-	{0x0305, 4},
-	{0x0307, 133},
-	{0x0309, 10},
-	{0x0202, 0x03},
-	{0x0203, 0xd0},
-	{0x0205, 0xc0},
-	{0x3030, 0x08},
-	{0x0111, 0x02},
-	{0x0b00, 0x01},
-	{0x3001, 0x30},
-	{0x3004, 0x33},
-	{0x3007, 0x09},
-	{0x3016, 0x1F},
-	{0x301d, 0x03},
-	{0x317e, 0x11},
-	{0x317f, 0x09},
-	{0x3400, 0x38},
-	{0x0b06, 0x00},
-	{0x0b07, 0x80},
-	{0x0b08, 0x01},
-	{0x0b09, 0x4F},
-	{0x0136, 0x18},
-	{0x0137, 0x00},
-	{0x0b83, 0x20},
-	{0x0b84, 0x90},
-	{0x0b85, 0x20},
-	{0x0b88, 0x80},
-	{0x0b89, 0x00},
-	{0x0b8a, 0x00},
-	{0x0340, 0x03},   /*REG = 0x0340 frame_length_lines_hi*/
-	{0x0341, 0xf0},   /*REG = 0x0341 frame_length_lines_lo*/
-	{0x0342, 0x0b},   /*REG = 0x0342  line_length_pck_hi*/
-	{0x0343, 0x74},   /*REG = 0x0343  line_length_pck_lo*/
-	{0x3005, 0x03},   /*REG = 0x3005*/
-	{0x3010, 0x00},   /*REG = 0x3010*/
-	{0x3011, 0x01},   /*REG = 0x3011*/
-	{0x301a, 0x6a},   /*REG = 0x301a*/
-	{0x3035, 0x03},   /*REG = 0x3035*/
-	{0x3036, 0x2c},   /*REG = 0x3036*/
-	{0x3041, 0x00},   /*REG = 0x3041*/
-	{0x3042, 0x24},   /*REG = 0x3042*/
-	{0x3045, 0x81},   /*REG = 0x3045*/
-	{0x0b80, 0x02},   /*REG = 0x0b80 edof estimate*/
-	{0x0900, 0x01},   /*REG = 0x0900*/
-	{0x0901, 0x22},   /*REG = 0x0901*/
-	{0x0902, 0x04},   /*REG = 0x0902*/
-	{0x0383, 0x03},   /*REG = 0x0383*/
-	{0x0387, 0x03},   /*REG = 0x0387*/
-	{0x034c, 0x05},   /*REG = 0x034c*/
-	{0x034d, 0x18},   /*REG = 0x034d*/
-	{0x034e, 0x03},   /*REG = 0x034e*/
-	{0x034f, 0xd4},   /*REG = 0x034f*/
-	{0x1716, 0x02},   /*0x1716*/
-	{0x1717, 0x04},   /*0x1717*/
-	{0x1718, 0x08},   /*0x1718*/
-	{0x1719, 0x2c},   /*0x1719*/
-};
-
-struct msm_camera_i2c_reg_conf mode_tbl1[] = {
-	{REG_0x0112, 10},/*REG = 0x0112 , 10 bit */
-	{REG_0x0113, 10},/*REG = 0x0113*/
-	{REG_VT_PIX_CLK_DIV, 9},/*REG = 0x0301 vt_pix_clk_div*/
-	{REG_PRE_PLL_CLK_DIV, 4},/*REG = 0x0305 pre_pll_clk_div*/
-	{REG_PLL_MULTIPLIER, 133},/*REG = 0x0307 pll_multiplier*/
-	{REG_OP_PIX_CLK_DIV, 10},/*REG = 0x0309 op_pix_clk_div*/
-	{REG_FRAME_LENGTH_LINES_HI, 0x03},/*REG = 0x0340 frame_length_lines_hi*/
-	{REG_FRAME_LENGTH_LINES_LO, 0xf0},/*REG = 0x0341 frame_length_lines_lo*/
-	{REG_LINE_LENGTH_PCK_HI, 0x0b},   /*REG = 0x0342  line_length_pck_hi*/
-	{REG_LINE_LENGTH_PCK_LO, 0x74},   /*REG = 0x0343  line_length_pck_lo*/
-	{REG_0x3005, 0x03},   /*REG = 0x3005*/
-	{0x3010, 0x00},   /*REG = 0x3010*/
-	{REG_0x3011, 0x01},   /*REG = 0x3011*/
-	{REG_0x301a, 0x6a},   /*REG = 0x301a*/
-	{REG_0x3035, 0x03},   /*REG = 0x3035*/
-	{REG_0x3036, 0x2c},   /*REG = 0x3036*/
-	{REG_0x3041, 0x00},   /*REG = 0x3041*/
-	{0x3042, 0x24},   /*REG = 0x3042*/
-	{REG_0x3045, 0x81},   /*REG = 0x3045*/
-	{REG_0x0b80, 0x02},   /*REG = 0x0b80 edof estimate*/
-	{REG_0x0900, 0x01},   /*REG = 0x0900*/
-	{REG_0x0901, 0x22},   /*REG = 0x0901*/
-	{REG_0x0902, 0x04},   /*REG = 0x0902*/
-	{REG_0x0383, 0x03},   /*REG = 0x0383*/
-	{REG_0x0387, 0x03},   /*REG = 0x0387*/
-	{REG_0x034c, 0x05},   /*REG = 0x034c*/
-	{REG_0x034d, 0x18},   /*REG = 0x034d*/
-	{REG_0x034e, 0x03},   /*REG = 0x034e*/
-	{REG_0x034f, 0xd4},   /*REG = 0x034f*/
-	{REG_0x1716, 0x02},   /*0x1716*/
-	{REG_0x1717, 0x04},   /*0x1717*/
-	{REG_0x1718, 0x08},   /*0x1718*/
-	{REG_0x1719, 0x2c},   /*0x1719*/
-};
-
-struct msm_camera_i2c_reg_conf mode_tbl2[] = {
-	{REG_0x0112, 10},/*REG = 0x0112 , 10 bit */
-	{REG_0x0113, 10},/*REG = 0x0113*/
-	{REG_VT_PIX_CLK_DIV, 9},/*REG = 0x0301 vt_pix_clk_div*/
-	{REG_PRE_PLL_CLK_DIV, 4},/*REG = 0x0305 pre_pll_clk_div*/
-	{REG_PLL_MULTIPLIER, 133},/*REG = 0x0307 pll_multiplier*/
-	{REG_OP_PIX_CLK_DIV, 10},/*REG = 0x0309 op_pix_clk_div*/
-	{REG_FRAME_LENGTH_LINES_HI, 0x07},/*REG = 0x0340 frame_length_lines_hi*/
-	{REG_FRAME_LENGTH_LINES_LO, 0xd0},/*REG = 0x0341 frame_length_lines_lo*/
-	{REG_LINE_LENGTH_PCK_HI, 0x0b},/*REG = 0x0342 line_length_pck_hi*/
-	{REG_LINE_LENGTH_PCK_LO, 0x8c},/*REG = 0x0343 line_length_pck_lo*/
-	{REG_0x3005, 0x01},/*REG = 0x3005*/
-	{0x3010, 0x00},/*REG = 0x3010*/
-	{REG_0x3011, 0x00},/*REG = 0x3011*/
-	{REG_0x301a, 0x55},/*REG = 0x301a*/
-	{REG_0x3035, 0x01},/*REG = 0x3035*/
-	{REG_0x3036, 0x23},/*REG = 0x3036*/
-	{REG_0x3041, 0x00},/*REG = 0x3041*/
-	{0x3042, 0x24},/*REG = 0x3042*/
-	{REG_0x3045, 0xb7},/*REG = 0x3045*/
-	{REG_0x0b80, 0x01},/*REG = 0x0b80 edof application*/
-	{REG_0x0900, 0x00},/*REG = 0x0900*/
-	{REG_0x0901, 0x00},/*REG = 0x0901*/
-	{REG_0x0902, 0x00},/*REG = 0x0902*/
-	{REG_0x0383, 0x01},/*REG = 0x0383*/
-	{REG_0x0387, 0x01},/*REG = 0x0387*/
-	{REG_0x034c, 0x0A},/*REG = 0x034c*/
-	{REG_0x034d, 0x30},/*REG = 0x034d*/
-	{REG_0x034e, 0x07},/*REG = 0x034e*/
-	{REG_0x034f, 0xA8},/*REG = 0x034f*/
-	{REG_0x1716, 0x02},/*0x1716*/
-	{REG_0x1717, 0x0d},/*0x1717*/
-	{REG_0x1718, 0x07},/*0x1718*/
-	{REG_0x1719, 0x7d},/*0x1719*/
-};
-
-static int32_t vx6953_sensor_setting(int update_type, int rt)
-{
-
-	int32_t rc = 0;
-	uint16_t frame_cnt = 0;
-		CDBG("%s update type = %d, rt = %d\n",
-			__func__, update_type, rt);
-
-		switch (update_type) {
-		case REG_INIT:
-		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
-						/* reset fps_divider */
-			fps = 30 * Q8;
-			/* stop streaming */
-
-			/* Reset everything first */
-			msm_camera_i2c_write_tbl(
-				vx6953_s_ctrl.sensor_i2c_client,
-				vx6953_standby,
-				ARRAY_SIZE(vx6953_standby),
-				vx6953_s_ctrl.msm_sensor_reg->
-				default_data_type);
-
-			msleep(20);
-
-			CDBG("Init vx6953_sensor_setting standby\n");
-			msm_camera_i2c_write_tbl(
-				vx6953_s_ctrl.sensor_i2c_client,
-				vx6953_stop_settings,
-				ARRAY_SIZE(vx6953_stop_settings),
-				vx6953_s_ctrl.msm_sensor_reg->
-				default_data_type);
-				/*vx6953_stm5m0edof_delay_msecs_stdby*/
-			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-			msm_camera_i2c_write_tbl(
-				vx6953_s_ctrl.sensor_i2c_client,
-				patch_tbl_cut2,
-				ARRAY_SIZE(patch_tbl_cut2),
-				vx6953_s_ctrl.msm_sensor_reg->
-				default_data_type);
-			msm_camera_i2c_write_tbl(
-				vx6953_s_ctrl.sensor_i2c_client,
-				init_tbl,
-				ARRAY_SIZE(init_tbl),
-				vx6953_s_ctrl.msm_sensor_reg->
-				default_data_type);
-			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-		}
-		return rc;
-		case UPDATE_PERIODIC:
-		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
-			struct msm_camera_i2c_reg_conf init_mode_tbl[] =  {
-			{REG_0x0112,
-				vx6953_regs.reg_pat_init[0].reg_0x0112},
-			{REG_0x0113,
-				vx6953_regs.reg_pat_init[0].reg_0x0113},
-			{REG_VT_PIX_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				vt_pix_clk_div},
-			{REG_PRE_PLL_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				pre_pll_clk_div},
-			{REG_PLL_MULTIPLIER,
-				vx6953_regs.reg_pat_init[0].
-				pll_multiplier},
-			{REG_OP_PIX_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				op_pix_clk_div},
-			{REG_COARSE_INTEGRATION_TIME_HI,
-				vx6953_regs.reg_pat[rt].
-				coarse_integration_time_hi},
-			{REG_COARSE_INTEGRATION_TIME_LO,
-				vx6953_regs.reg_pat[rt].
-				coarse_integration_time_lo},
-			{REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
-				vx6953_regs.reg_pat[rt].
-				analogue_gain_code_global},
-			{REG_0x3030,
-				vx6953_regs.reg_pat_init[0].reg_0x3030},
-			/* 953 specific registers */
-			{REG_0x0111,
-				vx6953_regs.reg_pat_init[0].reg_0x0111},
-			{REG_0x0b00,
-				vx6953_regs.reg_pat_init[0].reg_0x0b00},
-			{REG_0x3001,
-				vx6953_regs.reg_pat_init[0].reg_0x3001},
-			{REG_0x3004,
-				vx6953_regs.reg_pat_init[0].reg_0x3004},
-			{REG_0x3007,
-				vx6953_regs.reg_pat_init[0].reg_0x3007},
-			{REG_0x3016,
-				vx6953_regs.reg_pat_init[0].reg_0x3016},
-			{REG_0x301d,
-				vx6953_regs.reg_pat_init[0].reg_0x301d},
-			{REG_0x317e,
-				vx6953_regs.reg_pat_init[0].reg_0x317e},
-			{REG_0x317f,
-				vx6953_regs.reg_pat_init[0].reg_0x317f},
-			{REG_0x3400,
-				vx6953_regs.reg_pat_init[0].reg_0x3400},
-			{0x0b06,
-				vx6953_regs.reg_pat_init[0].reg_0x0b06},
-			/*Single_defect_correct_weight = auto*/
-			{0x0b07,
-				vx6953_regs.reg_pat_init[0].reg_0x0b07},
-			/*Dynamic couplet correction ENABLED*/
-			{0x0b08,
-				vx6953_regs.reg_pat_init[0].reg_0x0b08},
-			/*Dynamic couplet correction weight*/
-			{0x0b09,
-				vx6953_regs.reg_pat_init[0].reg_0x0b09},
-			/* Clock Setup */
-			/* Tell sensor ext clk is 24MHz*/
-			{0x0136,
-				vx6953_regs.reg_pat_init[0].reg_0x0136},
-			{0x0137,
-				vx6953_regs.reg_pat_init[0].reg_0x0137},
-			/* The white balance gains must be written
-			to the sensor every frame. */
-			/* Edof */
-			{REG_0x0b83,
-				vx6953_regs.reg_pat_init[0].reg_0x0b83},
-			{REG_0x0b84,
-				vx6953_regs.reg_pat_init[0].reg_0x0b84},
-			{0x0b85,
-				vx6953_regs.reg_pat_init[0].reg_0x0b85},
-			{0x0b88,
-				vx6953_regs.reg_pat_init[0].reg_0x0b88},
-			{0x0b89,
-				vx6953_regs.reg_pat_init[0].reg_0x0b89},
-			{REG_0x0b8a,
-				vx6953_regs.reg_pat_init[0].reg_0x0b8a},
-			/* Mode specific regieters */
-			{REG_FRAME_LENGTH_LINES_HI,
-				vx6953_regs.reg_pat[rt].
-				frame_length_lines_hi},
-			{REG_FRAME_LENGTH_LINES_LO,
-				vx6953_regs.reg_pat[rt].
-				frame_length_lines_lo},
-			{REG_LINE_LENGTH_PCK_HI,
-				vx6953_regs.reg_pat[rt].
-				line_length_pck_hi},
-			{REG_LINE_LENGTH_PCK_LO,
-				vx6953_regs.reg_pat[rt].
-				line_length_pck_lo},
-			{REG_0x3005,
-				vx6953_regs.reg_pat[rt].reg_0x3005},
-			{0x3010,
-				vx6953_regs.reg_pat[rt].reg_0x3010},
-			{REG_0x3011,
-				vx6953_regs.reg_pat[rt].reg_0x3011},
-			{REG_0x301a,
-				vx6953_regs.reg_pat[rt].reg_0x301a},
-			{REG_0x3035,
-				vx6953_regs.reg_pat[rt].reg_0x3035},
-			{REG_0x3036,
-				vx6953_regs.reg_pat[rt].reg_0x3036},
-			{REG_0x3041,
-				vx6953_regs.reg_pat[rt].reg_0x3041},
-			{0x3042,
-				vx6953_regs.reg_pat[rt].reg_0x3042},
-			{REG_0x3045,
-				vx6953_regs.reg_pat[rt].reg_0x3045},
-			/*EDOF: Estimation settings for Preview mode
-			Application settings for capture mode
-			(standard settings - Not tuned) */
-			{REG_0x0b80,
-				vx6953_regs.reg_pat[rt].reg_0x0b80},
-			{REG_0x0900,
-				vx6953_regs.reg_pat[rt].reg_0x0900},
-			{REG_0x0901,
-				vx6953_regs.reg_pat[rt].reg_0x0901},
-			{REG_0x0902,
-				vx6953_regs.reg_pat[rt].reg_0x0902},
-			{REG_0x0383,
-				vx6953_regs.reg_pat[rt].reg_0x0383},
-			{REG_0x0387,
-				vx6953_regs.reg_pat[rt].reg_0x0387},
-			/* Change output size / frame rate */
-			{REG_0x034c,
-				vx6953_regs.reg_pat[rt].reg_0x034c},
-			{REG_0x034d,
-				vx6953_regs.reg_pat[rt].reg_0x034d},
-			{REG_0x034e,
-				vx6953_regs.reg_pat[rt].reg_0x034e},
-			{REG_0x034f,
-				vx6953_regs.reg_pat[rt].reg_0x034f},
-			{REG_0x1716,
-				vx6953_regs.reg_pat[rt].reg_0x1716},
-			{REG_0x1717,
-				vx6953_regs.reg_pat[rt].reg_0x1717},
-			{REG_0x1718,
-				vx6953_regs.reg_pat[rt].reg_0x1718},
-			{REG_0x1719,
-				vx6953_regs.reg_pat[rt].reg_0x1719},
-			};
-			/* stop streaming */
-			msleep(20);
-
-			/* Reset everything first */
-			msm_camera_i2c_write_tbl(
-				vx6953_s_ctrl.sensor_i2c_client,
-				vx6953_standby,
-				ARRAY_SIZE(vx6953_standby),
-				vx6953_s_ctrl.msm_sensor_reg->
-				default_data_type);
-
-
-			msleep(20);
-
-			msm_camera_i2c_write_tbl(
-				vx6953_s_ctrl.sensor_i2c_client,
-				vx6953_stop_settings,
-				ARRAY_SIZE(vx6953_stop_settings),
-				vx6953_s_ctrl.msm_sensor_reg->
-				default_data_type);
-			/*vx6953_stm5m0edof_delay_msecs_stdby*/
-			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-
-			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-
-			msm_camera_i2c_write_tbl(
-				vx6953_s_ctrl.sensor_i2c_client,
-				patch_tbl_cut2,
-				ARRAY_SIZE(patch_tbl_cut2),
-				vx6953_s_ctrl.msm_sensor_reg->
-				default_data_type);
-
-			msm_camera_i2c_write_tbl(
-				vx6953_s_ctrl.sensor_i2c_client,
-				init_mode_tbl,
-				ARRAY_SIZE(init_mode_tbl),
-				vx6953_s_ctrl.msm_sensor_reg->
-				default_data_type);
-
-			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-			if (rt == RES_PREVIEW) {
-				CDBG("%s write mode_tbl for preview\n",
-					__func__);
-				msm_camera_i2c_write_tbl(
-					vx6953_s_ctrl.sensor_i2c_client,
-					mode_tbl1,
-					ARRAY_SIZE(mode_tbl1),
-					vx6953_s_ctrl.msm_sensor_reg->
-					default_data_type);
-			} else if (rt == RES_CAPTURE) {
-				CDBG("%s write mode_tbl for capture\n",
-					__func__);
-				msm_camera_i2c_write_tbl(
-					vx6953_s_ctrl.sensor_i2c_client,
-					mode_tbl2,
-					ARRAY_SIZE(mode_tbl2),
-					vx6953_s_ctrl.msm_sensor_reg->
-					default_data_type);
-			}
-			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-
-			/* Start sensor streaming */
-			msm_camera_i2c_write_tbl(
-				vx6953_s_ctrl.sensor_i2c_client,
-				vx6953_start_settings,
-				ARRAY_SIZE(vx6953_start_settings),
-				vx6953_s_ctrl.msm_sensor_reg->
-				default_data_type);
-			msleep(20);
-
-			msm_camera_i2c_read(
-				vx6953_s_ctrl.sensor_i2c_client,
-				0x0005,
-				&frame_cnt,
-				MSM_CAMERA_I2C_BYTE_ADDR);
-			while (frame_cnt == 0xFF) {
-				msm_camera_i2c_read(
-					vx6953_s_ctrl.sensor_i2c_client,
-					0x0005,
-					&frame_cnt,
-					MSM_CAMERA_I2C_BYTE_ADDR);
-				CDBG("%s frame_cnt = %d\n",
-					__func__, frame_cnt);
-				usleep_range(5000, 10000);
-			}
-		}
-		return rc;
-		default:
-		return rc;
-	}
-	return rc;
-}
-
-static int32_t vx6953_init_config(void)
-{
-	int32_t rc = 0;
-	int rt;
-	/* change sensor resolution	if needed */
-	CDBG("%s called\n", __func__);
-	rt = RES_PREVIEW;
-	vx6953_stm5m0edof_delay_msecs_stdby =
-		((((2 * 1000 * fps_divider) /
-		   fps) * Q8) / Q10) + 1;
-
-	vx6953_sensor_setting(REG_INIT, rt);
-
-	vx6953_enable_edof(VX6953_EDOF_ESTIMATION);
-	return rc;
-}
-
-static int32_t vx6953_update_config(int rt)
-{
-	int32_t rc = 0;
-	CDBG("%s rt = %d\n", __func__, rt);
-	if (rt == MSM_SENSOR_RES_FULL)
-		rt = RES_CAPTURE;
-	else if (rt == MSM_SENSOR_RES_QTR)
-		rt = RES_PREVIEW;
-
-	vx6953_stm5m0edof_delay_msecs_stdby = 67;
-	vx6953_sensor_setting(UPDATE_PERIODIC, rt);
-
-	if (rt == RES_PREVIEW)
-		vx6953_enable_edof(VX6953_EDOF_ESTIMATION);
-	else if (rt == RES_CAPTURE)
-		vx6953_enable_edof(VX6953_EDOF_APPLICATION);
-
-	return rc;
-} /*end of vx6953_snapshot_config*/
-
-static int32_t vx6953_set_sensor_mode(struct msm_sensor_ctrl_t *s_ctrl,
-	int update_type, int rt)
-{
-	int32_t rc = 0;
-
-	fps_divider = 1 * 0x00000400;
-	fps = 30*Q8;
-
-	switch (update_type) {
-	case MSM_SENSOR_REG_INIT:
-		rc = vx6953_init_config();
-		break;
-	case MSM_SENSOR_UPDATE_PERIODIC:
-		rc = vx6953_update_config(rt);
-		break;
-	default:
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
-static struct msm_sensor_fn_t vx6953_func_tbl = {
-	.sensor_start_stream = msm_sensor_start_stream,
-	.sensor_stop_stream = msm_sensor_stop_stream,
-	.sensor_group_hold_on = msm_sensor_group_hold_on,
-	.sensor_group_hold_off = msm_sensor_group_hold_off,
-	.sensor_set_fps = vx6953_set_fps,
-	.sensor_write_exp_gain = vx6953_write_exp_gain,
-	.sensor_write_snapshot_exp_gain = vx6953_write_exp_gain,
-	.sensor_csi_setting = vx6953_set_sensor_mode,
-	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
-	.sensor_mode_init = msm_sensor_mode_init,
-	.sensor_get_output_info = msm_sensor_get_output_info,
-	.sensor_config = msm_sensor_config,
-	.sensor_power_up = msm_sensor_power_up,
-	.sensor_power_down = msm_sensor_power_down,
-};
-
-static struct msm_sensor_reg_t vx6953_data_regs = {
-	.default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
-	.start_stream_conf = vx6953_start_settings,
-	.start_stream_conf_size = ARRAY_SIZE(vx6953_start_settings),
-	.stop_stream_conf = vx6953_stop_settings,
-	.stop_stream_conf_size = ARRAY_SIZE(vx6953_stop_settings),
-	.group_hold_on_conf = vx6953_groupon_settings,
-	.group_hold_on_conf_size = ARRAY_SIZE(vx6953_groupon_settings),
-	.group_hold_off_conf = vx6953_groupoff_settings,
-	.group_hold_off_conf_size =
-		ARRAY_SIZE(vx6953_groupoff_settings),
-	.init_settings = &vx6953_init_conf[0],
-	.init_size = ARRAY_SIZE(vx6953_init_conf),
-	.mode_settings = &vx6953_confs[0],
-	.output_settings = &vx6953_dimensions[0],
-	.num_conf = ARRAY_SIZE(vx6953_confs),
-};
-
-static struct msm_sensor_ctrl_t vx6953_s_ctrl = {
-	.msm_sensor_reg = &vx6953_data_regs,
-	.sensor_i2c_client = &vx6953_sensor_i2c_client,
-	.sensor_i2c_addr = 0x20,
-	.sensor_output_reg_addr = &vx6953_reg_addr,
-	.sensor_id_info = &vx6953_id_info,
-	.sensor_exp_gain_info = &vx6953_exp_gain_info,
-	.cam_mode = MSM_SENSOR_MODE_INVALID,
-	.msm_sensor_mutex = &vx6953_mut,
-	.sensor_i2c_driver = &vx6953_i2c_driver,
-	.sensor_v4l2_subdev_info = vx6953_subdev_info,
-	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(vx6953_subdev_info),
-	.sensor_v4l2_subdev_ops = &vx6953_subdev_ops,
-	.func_tbl = &vx6953_func_tbl,
-	.clk_rate = MSM_SENSOR_MCLK_24HZ,
-};
-
-module_init(msm_sensor_init_module);
-MODULE_DESCRIPTION("Sensor VX6953 (BAYER 5M)");
-MODULE_LICENSE("GPL v2");
-
diff --git a/drivers/media/video/msm/sensors/vx6953.h b/drivers/media/video/msm/sensors/vx6953.h
deleted file mode 100644
index 0fcdb53..0000000
--- a/drivers/media/video/msm/sensors/vx6953.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. 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 VX6953_H
-#define VX6953_H
-#include <linux/types.h>
-#include <mach/board.h>
-struct reg_struct_init {
-	uint8_t reg_0x0112;      /* 0x0112*/
-	uint8_t reg_0x0113;      /* 0x0113*/
-	uint8_t vt_pix_clk_div;  /* 0x0301*/
-	uint8_t pre_pll_clk_div; /* 0x0305*/
-	uint8_t pll_multiplier;  /* 0x0307*/
-	uint8_t op_pix_clk_div;  /* 0x0309*/
-	uint8_t reg_0x3030;      /*0x3030*/
-	uint8_t reg_0x0111;      /*0x0111*/
-	uint8_t reg_0x0b00;      /*0x0b00*/
-	uint8_t reg_0x3001;      /*0x3001*/
-	uint8_t reg_0x3004;      /*0x3004*/
-	uint8_t reg_0x3007;      /*0x3007*/
-	uint8_t reg_0x3016;      /*0x3016*/
-	uint8_t reg_0x301d;      /*0x301d*/
-	uint8_t reg_0x317e;      /*0x317E*/
-	uint8_t reg_0x317f;      /*0x317F*/
-	uint8_t reg_0x3400;      /*0x3400*/
-	uint8_t reg_0x0b06;      /*0x0b06*/
-	uint8_t reg_0x0b07;      /*0x0b07*/
-	uint8_t reg_0x0b08;      /*0x0b08*/
-	uint8_t reg_0x0b09;      /*0x0b09*/
-	uint8_t reg_0x0136;
-	uint8_t reg_0x0137;
-	/* Edof */
-	uint8_t reg_0x0b83;      /*0x0b83*/
-	uint8_t reg_0x0b84;      /*0x0b84*/
-	uint8_t reg_0x0b85;      /*0x0b85*/
-	uint8_t reg_0x0b88;      /*0x0b88*/
-	uint8_t reg_0x0b89;      /*0x0b89*/
-	uint8_t reg_0x0b8a;      /*0x0b8a*/
-	};
-struct reg_struct {
-	uint8_t coarse_integration_time_hi; /*REG_COARSE_INTEGRATION_TIME_HI*/
-	uint8_t coarse_integration_time_lo; /*REG_COARSE_INTEGRATION_TIME_LO*/
-	uint8_t analogue_gain_code_global;
-	uint8_t frame_length_lines_hi; /* 0x0340*/
-	uint8_t frame_length_lines_lo; /* 0x0341*/
-	uint8_t line_length_pck_hi;    /* 0x0342*/
-	uint8_t line_length_pck_lo;    /* 0x0343*/
-	uint8_t reg_0x3005;   /* 0x3005*/
-	uint8_t reg_0x3010;  /* 0x3010*/
-	uint8_t reg_0x3011;  /* 0x3011*/
-	uint8_t reg_0x301a;  /* 0x301a*/
-	uint8_t reg_0x3035;  /* 0x3035*/
-	uint8_t reg_0x3036;   /* 0x3036*/
-	uint8_t reg_0x3041;  /*0x3041*/
-	uint8_t reg_0x3042;  /*0x3042*/
-	uint8_t reg_0x3045;  /*0x3045*/
-	uint8_t reg_0x0b80;   /* 0x0b80*/
-	uint8_t reg_0x0900;   /*0x0900*/
-	uint8_t reg_0x0901;   /* 0x0901*/
-	uint8_t reg_0x0902;   /*0x0902*/
-	uint8_t reg_0x0383;   /*0x0383*/
-	uint8_t reg_0x0387;   /* 0x0387*/
-	uint8_t reg_0x034c;   /* 0x034c*/
-	uint8_t reg_0x034d;   /*0x034d*/
-	uint8_t reg_0x034e;   /* 0x034e*/
-	uint8_t reg_0x034f;   /* 0x034f*/
-	uint8_t reg_0x1716; /*0x1716*/
-	uint8_t reg_0x1717; /*0x1717*/
-	uint8_t reg_0x1718; /*0x1718*/
-	uint8_t reg_0x1719; /*0x1719*/
-	uint8_t reg_0x3210;/*0x3210*/
-	uint8_t reg_0x111; /*0x111*/
-	uint8_t reg_0x3410;  /*0x3410*/
-	uint8_t reg_0x3098;
-	uint8_t reg_0x309D;
-	uint8_t reg_0x0200;
-	uint8_t reg_0x0201;
-	};
-struct vx6953_i2c_reg_conf {
-	unsigned short waddr;
-	unsigned short wdata;
-};
-
-enum vx6953_test_mode_t {
-	TEST_OFF,
-	TEST_1,
-	TEST_2,
-	TEST_3
-};
-
-enum vx6953_resolution_t {
-	QTR_SIZE,
-	FULL_SIZE,
-	INVALID_SIZE
-};
-enum vx6953_setting {
-	RES_PREVIEW,
-	RES_CAPTURE
-};
-enum mt9p012_reg_update {
-	/* Sensor egisters that need to be updated during initialization */
-	REG_INIT,
-	/* Sensor egisters that needs periodic I2C writes */
-	UPDATE_PERIODIC,
-	/* All the sensor Registers will be updated */
-	UPDATE_ALL,
-	/* Not valid update */
-	UPDATE_INVALID
-};
-
-enum sensor_revision_t {
-	VX6953_STM5M0EDOF_CUT_1,
-	VX6953_STM5M0EDOF_CUT_2,
-	VX6953_STM5M0EDOF_CUT_3
-};
-enum edof_mode_t {
-	VX6953_EDOF_DISABLE,       /* 0x00 */
-	VX6953_EDOF_APPLICATION,   /* 0x01 */
-	VX6953_EDOF_ESTIMATION     /* 0x02 */
-};
-struct vx6953_reg {
-	const struct reg_struct_init  *reg_pat_init;
-	const struct reg_struct  *reg_pat;
-};
-#endif /* VX6953_H */
diff --git a/drivers/media/video/msm/sensors/vx6953_reg.h b/drivers/media/video/msm/sensors/vx6953_reg.h
deleted file mode 100644
index b76aa93..0000000
--- a/drivers/media/video/msm/sensors/vx6953_reg.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. 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.
- *
- */
-
-
-struct reg_struct_init vx6953_reg_init[1] = {
-	{
-		10,			/*REG = 0x0112 , 10 bit */
-		10,			/*REG = 0x0113*/
-		9,			/*REG = 0x0301 vt_pix_clk_div*/
-		4,		/*REG = 0x0305 pre_pll_clk_div*/
-		133,		/*REG = 0x0307 pll_multiplier*/
-		10,		/*REG = 0x0309 op_pix_clk_div*/
-		0x08,		/*REG = 0x3030*/
-		0x02,		/*REG = 0x0111*/
-		0x01,		/*REG = 0x0b00 ,lens shading off */
-		0x30,		/*REG = 0x3001*/
-		0x33,		/*REG = 0x3004*/
-		0x09,		/*REG = 0x3007*/
-		0x1F,		/*REG = 0x3016*/
-		0x03,		/*REG = 0x301d*/
-		0x11,		/*REG = 0x317E*/
-		0x09,		/*REG = 0x317F*/
-		0x38,		/*REG = 0x3400*/
-		0x00,		/*REG_0x0b06*/
-		0x80,		/*REG_0x0b07*/
-		0x01,		/*REG_0x0b08*/
-		0x4F,		/*REG_0x0b09*/
-		0x18,		/*REG_0x0136*/
-		0x00,		/*/REG_0x0137*/
-		0x20,		/*REG = 0x0b83*/
-		0x90,		/*REG = 0x0b84*/
-		0x20,		/*REG = 0x0b85*/
-		0x80,		/*REG = 0x0b88*/
-		0x00,		/*REG = 0x0b89*/
-		0x00,		/*REG = 0x0b8a*/
-	}
-};
-struct reg_struct vx6953_reg_pat[2] = {
-	{/* Preview */
-		0x03,	/*REG = 0x0202 coarse integration_time_hi*/
-		0xd0,	/*REG = 0x0203 coarse_integration_time_lo*/
-		0xc0,	/*REG = 0x0205 analogue_gain_code_global*/
-		0x03,	/*REG = 0x0340 frame_length_lines_hi*/
-		0xf0,	/*REG = 0x0341 frame_length_lines_lo*/
-		0x0b,	/*REG = 0x0342  line_length_pck_hi*/
-		0x74,	/*REG = 0x0343  line_length_pck_lo*/
-		0x03,	/*REG = 0x3005*/
-		0x00,	/*REG = 0x3010*/
-		0x01,	/*REG = 0x3011*/
-		0x6a,	/*REG = 0x301a*/
-		0x03,	/*REG = 0x3035*/
-		0x2c,	/*REG = 0x3036*/
-		0x00,	/*REG = 0x3041*/
-		0x24,	/*REG = 0x3042*/
-		0x81,	/*REG = 0x3045*/
-		0x02,	/*REG = 0x0b80 edof estimate*/
-		0x01,	/*REG = 0x0900*/
-		0x22,	/*REG = 0x0901*/
-		0x04,	/*REG = 0x0902*/
-		0x03,	/*REG = 0x0383*/
-		0x03,	/*REG = 0x0387*/
-		0x05,	/*REG = 0x034c*/
-		0x18,	/*REG = 0x034d*/
-		0x03,	/*REG = 0x034e*/
-		0xd4,	/*REG = 0x034f*/
-		0x02,	/*0x1716*/
-		0x04,	/*0x1717*/
-		0x08,	/*0x1718*/
-		0x2c,	/*0x1719*/
-		0x01,   /*0x3210*/
-		0x02,   /*0x111*/
-		0x01,   /*0x3410*/
-		0x01,   /*0x3098*/
-		0x05,   /*0x309D*/
-		0x02,
-		0x04,
-	},
-	{ /* Snapshot */
-		0x07,/*REG = 0x0202 coarse_integration_time_hi*/
-		0x00,/*REG = 0x0203 coarse_integration_time_lo*/
-		0xc0,/*REG = 0x0205 analogue_gain_code_global*/
-		0x07,/*REG = 0x0340 frame_length_lines_hi*/
-		0xd0,/*REG = 0x0341 frame_length_lines_lo*/
-		0x0b,/*REG = 0x0342 line_length_pck_hi*/
-		0x8c,/*REG = 0x0343 line_length_pck_lo*/
-		0x01,/*REG = 0x3005*/
-		0x00,/*REG = 0x3010*/
-		0x00,/*REG = 0x3011*/
-		0x55,/*REG = 0x301a*/
-		0x01,/*REG = 0x3035*/
-		0x23,/*REG = 0x3036*/
-		0x00,/*REG = 0x3041*/
-		0x24,/*REG = 0x3042*/
-		0xb7,/*REG = 0x3045*/
-		0x01,/*REG = 0x0b80 edof application*/
-		0x00,/*REG = 0x0900*/
-		0x00,/*REG = 0x0901*/
-		0x00,/*REG = 0x0902*/
-		0x01,/*REG = 0x0383*/
-		0x01,/*REG = 0x0387*/
-		0x0A,/*REG = 0x034c*/
-		0x30,/*REG = 0x034d*/
-		0x07,/*REG = 0x034e*/
-		0xA8,/*REG = 0x034f*/
-		0x02,/*0x1716*/
-		0x0d,/*0x1717*/
-		0x07,/*0x1718*/
-		0x7d,/*0x1719*/
-		0x01,/*0x3210*/
-		0x02,/*0x111*/
-		0x01,/*0x3410*/
-		0x01,/*0x3098*/
-		0x05, /*0x309D*/
-		0x02,
-		0x00,
-	}
-};
-
-
-
-struct vx6953_reg vx6953_regs = {
-	.reg_pat_init = &vx6953_reg_init[0],
-	.reg_pat = &vx6953_reg_pat[0],
-};
diff --git a/drivers/media/video/msm/server/Makefile b/drivers/media/video/msm/server/Makefile
deleted file mode 100644
index 55abeed..0000000
--- a/drivers/media/video/msm/server/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
-
-ifeq ($(CONFIG_MSM_CAMERA_V4L2),y)
-  EXTRA_CFLAGS += -Idrivers/media/video/msm
-  EXTRA_CFLAGS += -Idrivers/media/video/msm/io
-  EXTRA_CFLAGS += -Idrivers/media/video/msm/csi
-  EXTRA_CFLAGS += -Idrivers/media/video/msm/eeprom
-  EXTRA_CFLAGS += -Idrivers/media/video/msm/sensors
-  EXTRA_CFLAGS += -Idrivers/media/video/msm/actuators
-  obj-$(CONFIG_MSM_CAMERA)   += msm_cam_server.o
-endif
diff --git a/drivers/media/video/msm/server/msm_cam_server.c b/drivers/media/video/msm/server/msm_cam_server.c
deleted file mode 100644
index af31748..0000000
--- a/drivers/media/video/msm/server/msm_cam_server.c
+++ /dev/null
@@ -1,3289 +0,0 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/of.h>
-#include "msm_cam_server.h"
-#include "msm_csid.h"
-#include "msm_csic.h"
-#include "msm_csiphy.h"
-#include "msm_ispif.h"
-#include "msm_sensor.h"
-#include "msm_actuator.h"
-#include "msm_csi_register.h"
-
-#ifdef CONFIG_MSM_CAMERA_DEBUG
-#define D(fmt, args...) pr_debug("msm: " fmt, ##args)
-#else
-#define D(fmt, args...) do {} while (0)
-#endif
-
-static struct msm_cam_server_dev g_server_dev;
-static struct class *msm_class;
-static dev_t msm_devno;
-
-static long msm_server_send_v4l2_evt(void *evt);
-static void msm_cam_server_subdev_notify(struct v4l2_subdev *sd,
-	unsigned int notification, void *arg);
-
-void msm_queue_init(struct msm_device_queue *queue, const char *name)
-{
-	D("%s\n", __func__);
-	spin_lock_init(&queue->lock);
-	queue->len = 0;
-	queue->max = 0;
-	queue->name = name;
-	INIT_LIST_HEAD(&queue->list);
-	init_waitqueue_head(&queue->wait);
-}
-
-void msm_enqueue(struct msm_device_queue *queue,
-			struct list_head *entry)
-{
-	unsigned long flags;
-	spin_lock_irqsave(&queue->lock, flags);
-	queue->len++;
-	if (queue->len > queue->max) {
-		queue->max = queue->len;
-		pr_info("%s: queue %s new max is %d\n", __func__,
-			queue->name, queue->max);
-	}
-	list_add_tail(entry, &queue->list);
-	wake_up(&queue->wait);
-	D("%s: woke up %s\n", __func__, queue->name);
-	spin_unlock_irqrestore(&queue->lock, flags);
-}
-
-void msm_drain_eventq(struct msm_device_queue *queue)
-{
-	unsigned long flags;
-	struct msm_queue_cmd *qcmd;
-	struct msm_isp_event_ctrl *isp_event;
-	spin_lock_irqsave(&queue->lock, flags);
-	while (!list_empty(&queue->list)) {
-		qcmd = list_first_entry(&queue->list,
-			struct msm_queue_cmd, list_eventdata);
-		list_del_init(&qcmd->list_eventdata);
-		isp_event =
-			(struct msm_isp_event_ctrl *)
-			qcmd->command;
-		if (isp_event->isp_data.ctrl.value != NULL)
-			kfree(isp_event->isp_data.ctrl.value);
-		kfree(qcmd->command);
-		free_qcmd(qcmd);
-	}
-	spin_unlock_irqrestore(&queue->lock, flags);
-}
-
-int32_t msm_find_free_queue(void)
-{
-	int i;
-	for (i = 0; i < MAX_NUM_ACTIVE_CAMERA; i++) {
-		struct msm_cam_server_queue *queue;
-		queue = &g_server_dev.server_queue[i];
-		if (!queue->queue_active)
-			return i;
-	}
-	return -EINVAL;
-}
-
-void msm_setup_v4l2_event_queue(struct v4l2_fh *eventHandle,
-	struct video_device *pvdev)
-{
-	v4l2_fh_init(eventHandle, pvdev);
-	v4l2_fh_add(eventHandle);
-}
-
-void msm_destroy_v4l2_event_queue(struct v4l2_fh *eventHandle)
-{
-	v4l2_fh_del(eventHandle);
-	v4l2_fh_exit(eventHandle);
-}
-
-int msm_cam_server_config_interface_map(u32 extendedmode,
-	uint32_t mctl_handle, int vnode_id, int is_bayer_sensor)
-{
-	int i = 0;
-	int rc = 0;
-	int old_handle;
-	int interface;
-
-	if (vnode_id >= MAX_NUM_ACTIVE_CAMERA) {
-		pr_err("%s: invalid msm_dev node id = %d", __func__, vnode_id);
-		return -EINVAL;
-	}
-	D("%s: extendedmode = %d, vnode_id = %d, is_bayer_sensor = %d",
-		__func__, extendedmode, vnode_id, is_bayer_sensor);
-	switch (extendedmode) {
-	case MSM_V4L2_EXT_CAPTURE_MODE_RDI:
-		interface = RDI_0;
-		break;
-	case MSM_V4L2_EXT_CAPTURE_MODE_RDI1:
-		interface = RDI_1;
-		break;
-	case MSM_V4L2_EXT_CAPTURE_MODE_RDI2:
-		interface = RDI_2;
-		break;
-	default:
-		interface = PIX_0;
-		break;
-	}
-
-	for (i = 0; i < INTF_MAX; i++) {
-		if (g_server_dev.interface_map_table[i].interface ==
-							interface) {
-			if (is_bayer_sensor && interface == PIX_0) {
-				if (g_server_dev.
-					interface_map_table[i].mctl_handle &&
-					!g_server_dev.interface_map_table[i].
-						is_bayer_sensor) {
-					/* in simultaneous camera usecase
-					 * SoC does not use PIX interface */
-					g_server_dev.interface_map_table[i].
-						mctl_handle = 0;
-				}
-			}
-
-			if (!is_bayer_sensor && interface == PIX_0) {
-				if (g_server_dev.
-					interface_map_table[i].mctl_handle &&
-					g_server_dev.interface_map_table[i].
-						is_bayer_sensor) {
-					/* In case of simultaneous camera,
-					 * the YUV sensor could use PIX
-					 * interface to only queue the preview
-					 * or video buffers, but does not
-					 * expect any notifications directly.
-					 * (preview/video data is updated from
-					 * postprocessing in such scenario).
-					 * In such case, there is no need to
-					 * update the mctl_handle in the intf
-					 * map table, since the notification
-					 * will not be sent directly. */
-					break;
-				}
-			}
-
-			old_handle =
-				g_server_dev.interface_map_table[i].mctl_handle;
-			if (old_handle == 0) {
-				g_server_dev.interface_map_table[i].mctl_handle
-					= mctl_handle;
-				g_server_dev.interface_map_table[i].
-					is_bayer_sensor = is_bayer_sensor;
-				g_server_dev.interface_map_table[i].vnode_id
-					= vnode_id;
-			} else {
-				if (!g_server_dev.interface_map_table[i].
-					is_bayer_sensor &&
-					(extendedmode ==
-					MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW ||
-					extendedmode ==
-					MSM_V4L2_EXT_CAPTURE_MODE_VIDEO ||
-					extendedmode ==
-					MSM_V4L2_EXT_CAPTURE_MODE_MAIN ||
-					extendedmode ==
-					MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL)) {
-					D("%s: SoC sensor, image_mode = %d",
-					__func__, extendedmode);
-					break;
-				}
-				if (old_handle != mctl_handle) {
-					pr_err("%s: iface_map[%d] is set: %d\n",
-						__func__, i, old_handle);
-					rc = -EINVAL;
-				}
-			}
-			break;
-		}
-	}
-
-	if (i == INTF_MAX)
-		rc = -EINVAL;
-	return rc;
-}
-
-void msm_cam_server_clear_interface_map(uint32_t mctl_handle)
-{
-	int i;
-	for (i = 0; i < INTF_MAX; i++)
-		if (g_server_dev.interface_map_table[i].
-			mctl_handle == mctl_handle)
-			g_server_dev.interface_map_table[i].
-				mctl_handle = 0;
-}
-
-struct iommu_domain *msm_cam_server_get_domain()
-{
-	return g_server_dev.domain;
-}
-
-int msm_cam_server_get_domain_num()
-{
-	return g_server_dev.domain_num;
-}
-
-uint32_t msm_cam_server_get_mctl_handle(void)
-{
-	uint32_t i;
-	if ((g_server_dev.mctl_handle_cnt << 8) == 0)
-		g_server_dev.mctl_handle_cnt++;
-	for (i = 0; i < MAX_NUM_ACTIVE_CAMERA; i++) {
-		if (g_server_dev.mctl[i].handle == 0) {
-			g_server_dev.mctl[i].handle =
-				(++g_server_dev.mctl_handle_cnt) << 8 | i;
-			memset(&g_server_dev.mctl[i].mctl,
-				0, sizeof(g_server_dev.mctl[i].mctl));
-			return g_server_dev.mctl[i].handle;
-		}
-	}
-	return 0;
-}
-
-void msm_cam_server_free_mctl(uint32_t handle)
-{
-	uint32_t mctl_index;
-	mctl_index = handle & 0xff;
-	if ((mctl_index < MAX_NUM_ACTIVE_CAMERA) &&
-		(g_server_dev.mctl[mctl_index].handle == handle))
-		g_server_dev.mctl[mctl_index].handle = 0;
-	else
-		pr_err("%s: invalid free handle\n", __func__);
-}
-
-struct msm_cam_media_controller *msm_cam_server_get_mctl(uint32_t handle)
-{
-	uint32_t mctl_index;
-	mctl_index = handle & 0xff;
-	if ((mctl_index < MAX_NUM_ACTIVE_CAMERA) &&
-		(g_server_dev.mctl[mctl_index].handle == handle))
-		return &g_server_dev.mctl[mctl_index].mctl;
-	return NULL;
-}
-
-
-static void msm_cam_server_send_error_evt(
-		struct msm_cam_media_controller *pmctl, int evt_type)
-{
-	struct v4l2_event v4l2_ev;
-	v4l2_ev.id = 0;
-	v4l2_ev.type = evt_type;
-	ktime_get_ts(&v4l2_ev.timestamp);
-	v4l2_event_queue(pmctl->pcam_ptr->pvdev, &v4l2_ev);
-}
-
-static int msm_ctrl_cmd_done(void *arg)
-{
-	void __user *uptr;
-	struct msm_queue_cmd *qcmd;
-	struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
-	struct msm_ctrl_cmd *command;
-	D("%s\n", __func__);
-
-	command = kzalloc(sizeof(struct msm_ctrl_cmd), GFP_KERNEL);
-	if (!command) {
-		pr_err("%s Insufficient memory. return", __func__);
-		goto command_alloc_fail;
-	}
-
-	qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
-	if (!qcmd) {
-		pr_err("%s Insufficient memory. return", __func__);
-		goto qcmd_alloc_fail;
-	}
-
-	mutex_lock(&g_server_dev.server_queue_lock);
-
-	if (copy_from_user(command, (void __user *)ioctl_ptr->ioctl_ptr,
-					   sizeof(struct msm_ctrl_cmd))) {
-		pr_err("%s: copy_from_user failed, size=%d\n",
-			__func__, sizeof(struct msm_ctrl_cmd));
-		goto ctrl_cmd_done_error;
-	}
-
-	if (!g_server_dev.server_queue[command->queue_idx].queue_active) {
-		pr_err("%s: Invalid queue\n", __func__);
-		goto ctrl_cmd_done_error;
-	}
-
-	D("%s qid %d evtid %d %d\n", __func__, command->queue_idx,
-		command->evt_id,
-		g_server_dev.server_queue[command->queue_idx].evt_id);
-
-	if (command->evt_id !=
-		g_server_dev.server_queue[command->queue_idx].evt_id) {
-		pr_err("Invalid event id from userspace\n");
-		goto ctrl_cmd_done_error;
-	}
-
-	atomic_set(&qcmd->on_heap, 1);
-	uptr = command->value;
-	qcmd->command = command;
-
-	if (command->length > 0) {
-		command->value =
-			g_server_dev.server_queue[command->queue_idx].ctrl_data;
-		if (command->length > MAX_SERVER_PAYLOAD_LENGTH) {
-			pr_err("%s: user data %d is too big (max %d)\n",
-				__func__, command->length,
-				max_control_command_size);
-			goto ctrl_cmd_done_error;
-		}
-		if (copy_from_user(command->value, uptr, command->length)) {
-			pr_err("%s: copy_from_user failed, size=%d\n",
-				__func__, sizeof(struct msm_ctrl_cmd));
-			goto ctrl_cmd_done_error;
-		}
-	}
-	msm_enqueue(&g_server_dev.server_queue
-		[command->queue_idx].ctrl_q, &qcmd->list_control);
-	mutex_unlock(&g_server_dev.server_queue_lock);
-	return 0;
-
-ctrl_cmd_done_error:
-	mutex_unlock(&g_server_dev.server_queue_lock);
-	free_qcmd(qcmd);
-qcmd_alloc_fail:
-	kfree(command);
-command_alloc_fail:
-	return -EINVAL;
-}
-
-/* send control command to config and wait for results*/
-static int msm_server_control(struct msm_cam_server_dev *server_dev,
-				uint32_t id, struct msm_ctrl_cmd *out)
-{
-	int rc = 0;
-	uint8_t wait_count;
-	void *value;
-	struct msm_queue_cmd *rcmd;
-	struct msm_queue_cmd *event_qcmd;
-	struct msm_ctrl_cmd *ctrlcmd;
-	struct msm_device_queue *queue =
-		&server_dev->server_queue[out->queue_idx].ctrl_q;
-
-	struct v4l2_event v4l2_evt;
-	struct msm_isp_event_ctrl *isp_event;
-	void *ctrlcmd_data;
-
-	event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
-	if (!event_qcmd) {
-		pr_err("%s Insufficient memory. return", __func__);
-		rc = -ENOMEM;
-		goto event_qcmd_alloc_fail;
-	}
-
-	isp_event = kzalloc(sizeof(struct msm_isp_event_ctrl), GFP_KERNEL);
-	if (!isp_event) {
-		pr_err("%s Insufficient memory. return", __func__);
-		rc = -ENOMEM;
-		goto isp_event_alloc_fail;
-	}
-
-	D("%s\n", __func__);
-	mutex_lock(&server_dev->server_queue_lock);
-	if (++server_dev->server_evt_id == 0)
-		server_dev->server_evt_id++;
-
-	D("%s qid %d evtid %d\n", __func__, out->queue_idx,
-		server_dev->server_evt_id);
-	server_dev->server_queue[out->queue_idx].evt_id =
-		server_dev->server_evt_id;
-	v4l2_evt.type = V4L2_EVENT_PRIVATE_START + MSM_CAM_RESP_V4L2;
-	v4l2_evt.id = id;
-	v4l2_evt.u.data[0] = out->queue_idx;
-	/* setup event object to transfer the command; */
-	isp_event->resptype = MSM_CAM_RESP_V4L2;
-	isp_event->isp_data.ctrl = *out;
-	isp_event->isp_data.ctrl.evt_id = server_dev->server_evt_id;
-
-	if (out->value != NULL && out->length != 0) {
-		ctrlcmd_data = kzalloc(out->length, GFP_KERNEL);
-		if (!ctrlcmd_data) {
-			rc = -ENOMEM;
-			goto ctrlcmd_alloc_fail;
-		}
-		memcpy(ctrlcmd_data, out->value, out->length);
-		isp_event->isp_data.ctrl.value = ctrlcmd_data;
-	}
-
-	atomic_set(&event_qcmd->on_heap, 1);
-	event_qcmd->command = isp_event;
-
-	msm_enqueue(&server_dev->server_queue[out->queue_idx].eventData_q,
-				&event_qcmd->list_eventdata);
-
-	/* now send command to config thread in userspace,
-	 * and wait for results */
-	v4l2_event_queue(server_dev->server_command_queue.pvdev,
-					  &v4l2_evt);
-	D("%s v4l2_event_queue: type = 0x%x\n", __func__, v4l2_evt.type);
-	mutex_unlock(&server_dev->server_queue_lock);
-
-	/* wait for config return status */
-	D("Waiting for config status\n");
-	/* wait event may be interrupted by sugnal,
-	 * in this case -ERESTARTSYS is returned and retry is needed.
-	 * Now we only retry once. */
-	wait_count = 2;
-	do {
-		rc = wait_event_interruptible_timeout(queue->wait,
-			!list_empty_careful(&queue->list),
-			msecs_to_jiffies(out->timeout_ms));
-		wait_count--;
-		if (rc != -ERESTARTSYS)
-			break;
-		D("%s: wait_event interrupted by signal, remain_count = %d",
-			__func__, wait_count);
-	} while (wait_count > 0);
-	D("Waiting is over for config status\n");
-	if (list_empty_careful(&queue->list)) {
-		if (!rc)
-			rc = -ETIMEDOUT;
-		if (rc < 0) {
-			if (++server_dev->server_evt_id == 0)
-				server_dev->server_evt_id++;
-			pr_err("%s: wait_event error %d\n", __func__, rc);
-			return rc;
-		}
-	}
-
-	rcmd = msm_dequeue(queue, list_control);
-	BUG_ON(!rcmd);
-	D("%s Finished servicing ioctl\n", __func__);
-
-	ctrlcmd = (struct msm_ctrl_cmd *)(rcmd->command);
-	value = out->value;
-	if (ctrlcmd->length > 0 && value != NULL &&
-		ctrlcmd->length <= out->length)
-		memcpy(value, ctrlcmd->value, ctrlcmd->length);
-
-	memcpy(out, ctrlcmd, sizeof(struct msm_ctrl_cmd));
-	out->value = value;
-
-	kfree(ctrlcmd);
-	free_qcmd(rcmd);
-	D("%s: rc %d\n", __func__, rc);
-	/* rc is the time elapsed.
-	 * This means that the communication with the daemon itself was
-	 * successful(irrespective of the handling of the ctrlcmd).
-	 * So, just reset the rc to 0 to indicate success.
-	 * Its upto the caller to parse the ctrlcmd to check the status. We
-	 * dont need to parse it here. */
-	if (rc >= 0)
-		rc = 0;
-
-	return rc;
-
-ctrlcmd_alloc_fail:
-	kfree(isp_event);
-isp_event_alloc_fail:
-	kfree(event_qcmd);
-event_qcmd_alloc_fail:
-	return rc;
-}
-
-int msm_server_private_general(struct msm_cam_v4l2_device *pcam,
-		struct msm_camera_v4l2_ioctl_t *ioctl_ptr)
-{
-	struct msm_ctrl_cmd ctrlcmd;
-	void *temp_data = NULL;
-	int rc;
-	if (ioctl_ptr->len > 0) {
-		temp_data = kzalloc(ioctl_ptr->len, GFP_KERNEL);
-		if (!temp_data) {
-			pr_err("%s could not allocate memory\n", __func__);
-			rc = -ENOMEM;
-			goto end;
-		}
-		if (copy_from_user((void *)temp_data,
-			(void __user *)ioctl_ptr->ioctl_ptr,
-			ioctl_ptr->len)) {
-			ERR_COPY_FROM_USER();
-			rc = -EFAULT;
-			goto copy_from_user_failed;
-		}
-	}
-
-	mutex_lock(&pcam->vid_lock);
-	ctrlcmd.type = MSM_V4L2_PRIVATE_CMD;
-	ctrlcmd.length = ioctl_ptr->len;
-	ctrlcmd.value = temp_data;
-	ctrlcmd.timeout_ms = 1000;
-	ctrlcmd.status = ioctl_ptr->id;
-	ctrlcmd.vnode_id = pcam->vnode_id;
-	ctrlcmd.queue_idx = pcam->server_queue_idx;
-	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
-	/* send command to config thread in usersspace, and get return value */
-	rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
-	if (rc < 0)
-		pr_err("%s: send event failed\n", __func__);
-	else {
-		if (ioctl_ptr->len > 0) {
-			if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
-				(void *)temp_data,
-				ioctl_ptr->len)) {
-				ERR_COPY_TO_USER();
-				rc = -EFAULT;
-			}
-		}
-	}
-	mutex_unlock(&pcam->vid_lock);
-
-	kfree(temp_data);
-	return rc;
-copy_from_user_failed:
-	kfree(temp_data);
-end:
-return rc;
-}
-
-int msm_server_get_crop(struct msm_cam_v4l2_device *pcam,
-				int idx, struct v4l2_crop *crop)
-{
-	int rc = 0;
-	struct msm_ctrl_cmd ctrlcmd;
-
-	BUG_ON(crop == NULL);
-
-	ctrlcmd.type = MSM_V4L2_GET_CROP;
-	ctrlcmd.length = sizeof(struct v4l2_crop);
-	ctrlcmd.value = (void *)crop;
-	ctrlcmd.timeout_ms = 1000;
-	ctrlcmd.vnode_id = pcam->vnode_id;
-	ctrlcmd.queue_idx = pcam->server_queue_idx;
-	ctrlcmd.stream_type = pcam->dev_inst[idx]->image_mode;
-	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[
-						pcam->server_queue_idx];
-
-	/* send command to config thread in userspace, and get return value */
-	rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
-	D("%s: rc = %d\n", __func__, rc);
-
-	return rc;
-}
-
-/*send open command to server*/
-int msm_send_open_server(struct msm_cam_v4l2_device *pcam)
-{
-	int rc = 0;
-	struct msm_ctrl_cmd ctrlcmd;
-	int idx = pcam->server_queue_idx;
-	D("%s qid %d\n", __func__, pcam->server_queue_idx);
-	ctrlcmd.type	   = MSM_V4L2_OPEN;
-	ctrlcmd.timeout_ms = 10000;
-	ctrlcmd.length = strnlen(
-		g_server_dev.config_info.config_dev_name[idx],
-		MAX_DEV_NAME_LEN)+1;
-	ctrlcmd.value = (char *)g_server_dev.config_info.config_dev_name[idx];
-	ctrlcmd.vnode_id = pcam->vnode_id;
-	ctrlcmd.queue_idx = pcam->server_queue_idx;
-	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[idx];
-
-	/* send command to config thread in usersspace, and get return value */
-	rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
-
-	return rc;
-}
-
-int msm_send_close_server(struct msm_cam_v4l2_device *pcam)
-{
-	int rc = 0;
-	struct msm_ctrl_cmd ctrlcmd;
-	D("%s qid %d\n", __func__, pcam->server_queue_idx);
-	ctrlcmd.type	   = MSM_V4L2_CLOSE;
-	ctrlcmd.timeout_ms = 10000;
-	ctrlcmd.length	 = strnlen(g_server_dev.config_info.config_dev_name[
-				pcam->server_queue_idx], MAX_DEV_NAME_LEN)+1;
-	ctrlcmd.value    = (char *)g_server_dev.config_info.config_dev_name[
-				pcam->server_queue_idx];
-	ctrlcmd.vnode_id = pcam->vnode_id;
-	ctrlcmd.queue_idx = pcam->server_queue_idx;
-	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[
-						pcam->server_queue_idx];
-
-	/* send command to config thread in usersspace, and get return value */
-	rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
-
-	return rc;
-}
-
-int msm_server_set_fmt(struct msm_cam_v4l2_device *pcam, int idx,
-				 struct v4l2_format *pfmt)
-{
-	int rc = 0;
-	int i = 0;
-	struct v4l2_pix_format *pix = &pfmt->fmt.pix;
-	struct msm_ctrl_cmd ctrlcmd;
-	struct img_plane_info plane_info;
-
-	plane_info.width = pix->width;
-	plane_info.height = pix->height;
-	plane_info.pixelformat = pix->pixelformat;
-	plane_info.buffer_type = pfmt->type;
-	plane_info.ext_mode = pcam->dev_inst[idx]->image_mode;
-	plane_info.num_planes = 1;
-	plane_info.inst_handle = pcam->dev_inst[idx]->inst_handle;
-	D("%s: %d, %d, 0x%x\n", __func__,
-		pfmt->fmt.pix.width, pfmt->fmt.pix.height,
-		pfmt->fmt.pix.pixelformat);
-
-	if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		D("%s, Attention! Wrong buf-type %d\n", __func__, pfmt->type);
-
-	for (i = 0; i < pcam->num_fmts; i++)
-		if (pcam->usr_fmts[i].fourcc == pix->pixelformat)
-			break;
-	if (i == pcam->num_fmts) {
-		pr_err("%s: User requested pixelformat %x not supported\n",
-						__func__, pix->pixelformat);
-		return -EINVAL;
-	}
-
-	ctrlcmd.type       = MSM_V4L2_VID_CAP_TYPE;
-	ctrlcmd.length     = sizeof(struct img_plane_info);
-	ctrlcmd.value      = (void *)&plane_info;
-	ctrlcmd.timeout_ms = 10000;
-	ctrlcmd.vnode_id   = pcam->vnode_id;
-	ctrlcmd.queue_idx = pcam->server_queue_idx;
-	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
-
-	/* send command to config thread in usersspace, and get return value */
-	rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
-
-	if (rc >= 0) {
-		pcam->dev_inst[idx]->vid_fmt = *pfmt;
-		pcam->dev_inst[idx]->sensor_pxlcode
-					= pcam->usr_fmts[i].pxlcode;
-		D("%s:inst=0x%x,idx=%d,width=%d,heigth=%d\n",
-			 __func__, (u32)pcam->dev_inst[idx], idx,
-			 pcam->dev_inst[idx]->vid_fmt.fmt.pix.width,
-			 pcam->dev_inst[idx]->vid_fmt.fmt.pix.height);
-		pcam->dev_inst[idx]->plane_info = plane_info;
-	}
-
-	return rc;
-}
-
-int msm_server_set_fmt_mplane(struct msm_cam_v4l2_device *pcam, int idx,
-				 struct v4l2_format *pfmt)
-{
-	int rc = 0;
-	int i = 0;
-	struct v4l2_pix_format_mplane *pix_mp = &pfmt->fmt.pix_mp;
-	struct msm_ctrl_cmd ctrlcmd;
-	struct img_plane_info plane_info;
-
-	plane_info.width = pix_mp->width;
-	plane_info.height = pix_mp->height;
-	plane_info.pixelformat = pix_mp->pixelformat;
-	plane_info.buffer_type = pfmt->type;
-	plane_info.ext_mode = pcam->dev_inst[idx]->image_mode;
-	plane_info.num_planes = pix_mp->num_planes;
-	plane_info.inst_handle = pcam->dev_inst[idx]->inst_handle;
-
-	if (plane_info.num_planes <= 0 ||
-		plane_info.num_planes > VIDEO_MAX_PLANES) {
-		pr_err("%s Invalid number of planes set %d", __func__,
-				plane_info.num_planes);
-		return -EINVAL;
-	}
-	D("%s: %d, %d, 0x%x\n", __func__,
-		pfmt->fmt.pix_mp.width, pfmt->fmt.pix_mp.height,
-		pfmt->fmt.pix_mp.pixelformat);
-
-	if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-		pr_err("%s, Attention! Wrong buf-type %d\n",
-			__func__, pfmt->type);
-		return -EINVAL;
-	}
-
-	for (i = 0; i < pcam->num_fmts; i++)
-		if (pcam->usr_fmts[i].fourcc == pix_mp->pixelformat)
-			break;
-	if (i == pcam->num_fmts) {
-		pr_err("%s: User requested pixelformat %x not supported\n",
-						__func__, pix_mp->pixelformat);
-		return -EINVAL;
-	}
-
-	ctrlcmd.type       = MSM_V4L2_VID_CAP_TYPE;
-	ctrlcmd.length     = sizeof(struct img_plane_info);
-	ctrlcmd.value      = (void *)&plane_info;
-	ctrlcmd.timeout_ms = 10000;
-	ctrlcmd.vnode_id   = pcam->vnode_id;
-	ctrlcmd.queue_idx = pcam->server_queue_idx;
-
-	/* send command to config thread in usersspace, and get return value */
-	rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
-	if (rc >= 0) {
-		pcam->dev_inst[idx]->vid_fmt = *pfmt;
-		pcam->dev_inst[idx]->sensor_pxlcode
-					= pcam->usr_fmts[i].pxlcode;
-		D("%s:inst=0x%x,idx=%d,width=%d,heigth=%d\n",
-			 __func__, (u32)pcam->dev_inst[idx], idx,
-			 pcam->dev_inst[idx]->vid_fmt.fmt.pix_mp.width,
-			 pcam->dev_inst[idx]->vid_fmt.fmt.pix_mp.height);
-		pcam->dev_inst[idx]->plane_info = plane_info;
-	}
-
-	return rc;
-}
-
-int msm_server_streamon(struct msm_cam_v4l2_device *pcam, int idx)
-{
-	int rc = 0;
-	struct msm_ctrl_cmd ctrlcmd;
-	D("%s\n", __func__);
-	ctrlcmd.type	   = MSM_V4L2_STREAM_ON;
-	ctrlcmd.timeout_ms = 10000;
-	ctrlcmd.length	 = 0;
-	ctrlcmd.value    = NULL;
-	ctrlcmd.stream_type = pcam->dev_inst[idx]->image_mode;
-	ctrlcmd.vnode_id = pcam->vnode_id;
-	ctrlcmd.queue_idx = pcam->server_queue_idx;
-	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
-
-
-	/* send command to config thread in usersspace, and get return value */
-	rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
-
-	return rc;
-}
-
-int msm_server_streamoff(struct msm_cam_v4l2_device *pcam, int idx)
-{
-	int rc = 0;
-	struct msm_ctrl_cmd ctrlcmd;
-
-	D("%s, pcam = 0x%x\n", __func__, (u32)pcam);
-	ctrlcmd.type        = MSM_V4L2_STREAM_OFF;
-	ctrlcmd.timeout_ms  = 10000;
-	ctrlcmd.length      = 0;
-	ctrlcmd.value       = NULL;
-	ctrlcmd.stream_type = pcam->dev_inst[idx]->image_mode;
-	ctrlcmd.vnode_id = pcam->vnode_id;
-	ctrlcmd.queue_idx = pcam->server_queue_idx;
-	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
-
-	/* send command to config thread in usersspace, and get return value */
-	rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
-
-	return rc;
-}
-
-int msm_server_proc_ctrl_cmd(struct msm_cam_v4l2_device *pcam,
-		struct msm_camera_v4l2_ioctl_t *ioctl_ptr, int is_set_cmd)
-{
-	int rc = 0;
-	struct msm_ctrl_cmd ctrlcmd, tmp_cmd, *cmd_ptr;
-	uint8_t *ctrl_data = NULL;
-	uint32_t cmd_len = sizeof(struct msm_ctrl_cmd);
-	uint32_t value_len;
-
-	if (copy_from_user(&tmp_cmd,
-		(void __user *)ioctl_ptr->ioctl_ptr, cmd_len)) {
-		pr_err("%s: copy_from_user failed.\n", __func__);
-		rc = -EINVAL;
-		goto end;
-	}
-	value_len = tmp_cmd.length;
-	ctrl_data = kzalloc(value_len+cmd_len, GFP_KERNEL);
-	if (!ctrl_data) {
-		pr_err("%s could not allocate memory\n", __func__);
-		rc = -ENOMEM;
-		goto end;
-	}
-
-	cmd_ptr = (struct msm_ctrl_cmd *) ctrl_data;
-	*cmd_ptr = tmp_cmd;
-	if (tmp_cmd.value && tmp_cmd.length > 0) {
-		cmd_ptr->value = (void *)(ctrl_data+cmd_len);
-		if (copy_from_user((void *)cmd_ptr->value,
-				   (void __user *)tmp_cmd.value,
-				   value_len)) {
-			pr_err("%s: copy_from_user failed.\n", __func__);
-			rc = -EINVAL;
-			goto end;
-		}
-	} else {
-		cmd_ptr->value = NULL;
-	}
-
-	D("%s: cmd type = %d, up1=0x%x, ulen1=%d, up2=0x%x, ulen2=%d\n",
-		__func__, tmp_cmd.type, (uint32_t)ioctl_ptr->ioctl_ptr, cmd_len,
-		(uint32_t)tmp_cmd.value, tmp_cmd.length);
-
-	ctrlcmd.type = MSM_V4L2_SET_CTRL_CMD;
-	ctrlcmd.length = cmd_len + value_len;
-	ctrlcmd.value = (void *)ctrl_data;
-	if (tmp_cmd.timeout_ms > 0)
-		ctrlcmd.timeout_ms = tmp_cmd.timeout_ms;
-	else
-		ctrlcmd.timeout_ms = 1000;
-	ctrlcmd.vnode_id = pcam->vnode_id;
-	ctrlcmd.queue_idx = pcam->server_queue_idx;
-	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
-	/* send command to config thread in usersspace, and get return value */
-	rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
-	D("%s: msm_server_control rc=%d\n", __func__, rc);
-	if (rc == 0) {
-		if (tmp_cmd.value && tmp_cmd.length > 0 &&
-			copy_to_user((void __user *)tmp_cmd.value,
-				(void *)(ctrl_data+cmd_len), tmp_cmd.length)) {
-			pr_err("%s: copy_to_user failed, size=%d\n",
-				__func__, tmp_cmd.length);
-			rc = -EINVAL;
-			goto end;
-		}
-		tmp_cmd.status = cmd_ptr->status = ctrlcmd.status;
-		if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
-			(void *)cmd_ptr, cmd_len)) {
-			pr_err("%s: copy_to_user failed in cpy, size=%d\n",
-				__func__, cmd_len);
-			rc = -EINVAL;
-			goto end;
-		}
-	}
-end:
-	D("%s: END, type = %d, vaddr = 0x%x, vlen = %d, status = %d, rc = %d\n",
-		__func__, tmp_cmd.type, (uint32_t)tmp_cmd.value,
-		tmp_cmd.length, tmp_cmd.status, rc);
-	kfree(ctrl_data);
-	ctrl_data = NULL;
-	return rc;
-}
-
-int msm_server_s_ctrl(struct msm_cam_v4l2_device *pcam,
-				 struct v4l2_control *ctrl)
-{
-	int rc = 0;
-	struct msm_ctrl_cmd ctrlcmd;
-	uint8_t ctrl_data[max_control_command_size];
-
-	WARN_ON(ctrl == NULL);
-	if (ctrl == NULL) {
-		pr_err("%s Invalid control\n", __func__);
-		return -EINVAL;
-	}
-
-	memset(ctrl_data, 0, sizeof(ctrl_data));
-
-	ctrlcmd.type = MSM_V4L2_SET_CTRL;
-	ctrlcmd.length = sizeof(struct v4l2_control);
-	ctrlcmd.value = (void *)ctrl_data;
-	memcpy(ctrlcmd.value, ctrl, ctrlcmd.length);
-	ctrlcmd.timeout_ms = 1000;
-	ctrlcmd.vnode_id = pcam->vnode_id;
-	ctrlcmd.queue_idx = pcam->server_queue_idx;
-	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
-
-	/* send command to config thread in usersspace, and get return value */
-	rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
-
-	return rc;
-}
-
-int msm_server_g_ctrl(struct msm_cam_v4l2_device *pcam,
-				 struct v4l2_control *ctrl)
-{
-	int rc = 0;
-	struct msm_ctrl_cmd ctrlcmd;
-	uint8_t ctrl_data[max_control_command_size];
-
-	WARN_ON(ctrl == NULL);
-	if (ctrl == NULL) {
-		pr_err("%s Invalid control\n", __func__);
-		return -EINVAL;
-	}
-
-	memset(ctrl_data, 0, sizeof(ctrl_data));
-
-	ctrlcmd.type = MSM_V4L2_GET_CTRL;
-	ctrlcmd.length = sizeof(struct v4l2_control);
-	ctrlcmd.value = (void *)ctrl_data;
-	memcpy(ctrlcmd.value, ctrl, ctrlcmd.length);
-	ctrlcmd.timeout_ms = 1000;
-	ctrlcmd.vnode_id = pcam->vnode_id;
-	ctrlcmd.queue_idx = pcam->server_queue_idx;
-	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
-
-	/* send command to config thread in usersspace, and get return value */
-	rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
-
-	ctrl->value = ((struct v4l2_control *)ctrlcmd.value)->value;
-
-	return rc;
-}
-
-int msm_server_q_ctrl(struct msm_cam_v4l2_device *pcam,
-			struct v4l2_queryctrl *queryctrl)
-{
-	int rc = 0;
-	struct msm_ctrl_cmd ctrlcmd;
-	uint8_t ctrl_data[max_control_command_size];
-
-	WARN_ON(queryctrl == NULL);
-	memset(ctrl_data, 0, sizeof(ctrl_data));
-
-	ctrlcmd.type = MSM_V4L2_QUERY_CTRL;
-	ctrlcmd.length = sizeof(struct v4l2_queryctrl);
-	ctrlcmd.value = (void *)ctrl_data;
-	memcpy(ctrlcmd.value, queryctrl, ctrlcmd.length);
-	ctrlcmd.timeout_ms = 1000;
-	ctrlcmd.vnode_id = pcam->vnode_id;
-	ctrlcmd.queue_idx = pcam->server_queue_idx;
-	ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
-
-	/* send command to config thread in userspace, and get return value */
-	rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
-	D("%s: rc = %d\n", __func__, rc);
-
-	if (rc >= 0)
-		memcpy(queryctrl, ctrlcmd.value, sizeof(struct v4l2_queryctrl));
-
-	return rc;
-}
-
-int msm_server_get_fmt(struct msm_cam_v4l2_device *pcam,
-		 int idx, struct v4l2_format *pfmt)
-{
-	struct v4l2_pix_format *pix = &pfmt->fmt.pix;
-
-	pix->width        = pcam->dev_inst[idx]->vid_fmt.fmt.pix.width;
-	pix->height       = pcam->dev_inst[idx]->vid_fmt.fmt.pix.height;
-	pix->field        = pcam->dev_inst[idx]->vid_fmt.fmt.pix.field;
-	pix->pixelformat  = pcam->dev_inst[idx]->vid_fmt.fmt.pix.pixelformat;
-	pix->bytesperline = pcam->dev_inst[idx]->vid_fmt.fmt.pix.bytesperline;
-	pix->colorspace   = pcam->dev_inst[idx]->vid_fmt.fmt.pix.colorspace;
-	if (pix->bytesperline < 0)
-		return pix->bytesperline;
-
-	pix->sizeimage    = pix->height * pix->bytesperline;
-
-	return 0;
-}
-
-int msm_server_get_fmt_mplane(struct msm_cam_v4l2_device *pcam,
-		 int idx, struct v4l2_format *pfmt)
-{
-	*pfmt = pcam->dev_inst[idx]->vid_fmt;
-	return 0;
-}
-
-int msm_server_try_fmt(struct msm_cam_v4l2_device *pcam,
-				 struct v4l2_format *pfmt)
-{
-	int rc = 0;
-	int i = 0;
-	struct v4l2_pix_format *pix = &pfmt->fmt.pix;
-
-	D("%s: 0x%x\n", __func__, pix->pixelformat);
-	if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-		pr_err("%s: pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE!\n",
-							__func__);
-		return -EINVAL;
-	}
-
-	/* check if the format is supported by this host-sensor combo */
-	for (i = 0; i < pcam->num_fmts; i++) {
-		D("%s: usr_fmts.fourcc: 0x%x\n", __func__,
-			pcam->usr_fmts[i].fourcc);
-		if (pcam->usr_fmts[i].fourcc == pix->pixelformat)
-			break;
-	}
-
-	if (i == pcam->num_fmts) {
-		pr_err("%s: Format %x not found\n", __func__, pix->pixelformat);
-		return -EINVAL;
-	}
-	return rc;
-}
-
-int msm_server_try_fmt_mplane(struct msm_cam_v4l2_device *pcam,
-				 struct v4l2_format *pfmt)
-{
-	int rc = 0;
-	int i = 0;
-	struct v4l2_pix_format_mplane *pix_mp = &pfmt->fmt.pix_mp;
-
-	D("%s: 0x%x\n", __func__, pix_mp->pixelformat);
-	if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-		pr_err("%s: Incorrect format type %d ",
-			__func__, pfmt->type);
-		return -EINVAL;
-	}
-
-	/* check if the format is supported by this host-sensor combo */
-	for (i = 0; i < pcam->num_fmts; i++) {
-		D("%s: usr_fmts.fourcc: 0x%x\n", __func__,
-			pcam->usr_fmts[i].fourcc);
-		if (pcam->usr_fmts[i].fourcc == pix_mp->pixelformat)
-			break;
-	}
-
-	if (i == pcam->num_fmts) {
-		pr_err("%s: Format %x not found\n",
-			__func__, pix_mp->pixelformat);
-		return -EINVAL;
-	}
-	return rc;
-}
-
-int msm_server_v4l2_subscribe_event(struct v4l2_fh *fh,
-			struct v4l2_event_subscription *sub)
-{
-	int rc = 0;
-
-	D("%s: fh = 0x%x, type = 0x%x", __func__, (u32)fh, sub->type);
-	if (sub->type == V4L2_EVENT_ALL) {
-		/*sub->type = MSM_ISP_EVENT_START;*/
-		sub->type = V4L2_EVENT_PRIVATE_START + MSM_CAM_RESP_CTRL;
-		D("sub->type start = 0x%x\n", sub->type);
-		do {
-			rc = v4l2_event_subscribe(fh, sub, 30);

-			if (rc < 0) {
-				D("%s: failed for evtType = 0x%x, rc = %d\n",
-						__func__, sub->type, rc);
-			/* unsubscribe all events here and return */
-			sub->type = V4L2_EVENT_ALL;
-			v4l2_event_unsubscribe(fh, sub);
-			return rc;
-			} else
-				D("%s: subscribed evtType = 0x%x, rc = %d\n",
-						__func__, sub->type, rc);
-			sub->type++;
-			D("sub->type while = 0x%x\n", sub->type);
-		} while (sub->type !=
-			V4L2_EVENT_PRIVATE_START + MSM_SVR_RESP_MAX);
-	} else {
-		D("sub->type not V4L2_EVENT_ALL = 0x%x\n", sub->type);
-		rc = v4l2_event_subscribe(fh, sub, 30);

-		if (rc < 0)
-			D("%s: failed for evtType = 0x%x, rc = %d\n",
-						__func__, sub->type, rc);
-	}
-
-	D("%s: rc = %d\n", __func__, rc);
-	return rc;
-}
-
-int msm_server_v4l2_unsubscribe_event(struct v4l2_fh *fh,
-			struct v4l2_event_subscription *sub)
-{
-	int rc = 0;
-
-	D("%s: fh = 0x%x\n", __func__, (u32)fh);
-	rc = v4l2_event_unsubscribe(fh, sub);
-	D("%s: rc = %d\n", __func__, rc);
-	return rc;
-}
-
-/* open an active camera session to manage the streaming logic */
-static int msm_cam_server_open_session(struct msm_cam_server_dev *ps,
-	struct msm_cam_v4l2_device *pcam)
-{
-	int rc = 0;
-
-	D("%s\n", __func__);
-
-	if (!ps || !pcam) {
-		pr_err("%s NULL pointer passed in!\n", __func__);
-		return rc;
-	}
-
-	/*
-	 * The number of camera instance should be controlled by the
-	 * resource manager. Currently supporting two active instances
-	 */
-	if (atomic_read(&ps->number_pcam_active) > 1) {
-		pr_err("%s Cannot have more than two active camera %d\n",
-			__func__, atomic_read(&ps->number_pcam_active));
-		return -EINVAL;
-	}
-	/* book keeping this camera session*/
-	ps->pcam_active[pcam->server_queue_idx] = pcam;
-	ps->opened_pcam[pcam->vnode_id] = pcam;
-	atomic_inc(&ps->number_pcam_active);
-
-	D("config pcam = 0x%p\n", pcam);
-
-	/* initialization the media controller module*/
-	msm_mctl_init(pcam);
-
-	return rc;
-}
-
-/* close an active camera session to server */
-static int msm_cam_server_close_session(struct msm_cam_server_dev *ps,
-	struct msm_cam_v4l2_device *pcam)
-{
-	int i;
-	int rc = 0;
-	D("%s\n", __func__);
-
-	if (!ps || !pcam) {
-		D("%s NULL pointer passed in!\n", __func__);
-		return rc;
-	}
-
-	atomic_dec(&ps->number_pcam_active);
-	ps->pcam_active[pcam->server_queue_idx] = NULL;
-	ps->opened_pcam[pcam->vnode_id] = NULL;
-	for (i = 0; i < INTF_MAX; i++) {
-		if (ps->interface_map_table[i].mctl_handle ==
-			pcam->mctl_handle)
-			ps->interface_map_table[i].mctl_handle = 0;
-	}
-	msm_mctl_free(pcam);
-	return rc;
-}
-
-static int map_imem_addresses(struct msm_cam_media_controller *mctl)
-{
-	int rc = 0;
-	rc = msm_iommu_map_contig_buffer(
-		(unsigned long)IMEM_Y_PING_OFFSET, mctl->domain_num, 0,
-		((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)),
-		SZ_4K, IOMMU_WRITE | IOMMU_READ,
-		(unsigned long *)&mctl->ping_imem_y);
-	mctl->ping_imem_cbcr = mctl->ping_imem_y + IMEM_Y_SIZE;
-	if (rc < 0) {
-		pr_err("%s: ping iommu mapping returned error %d\n",
-			__func__, rc);
-		mctl->ping_imem_y = 0;
-		mctl->ping_imem_cbcr = 0;
-	}
-	msm_iommu_map_contig_buffer(
-		(unsigned long)IMEM_Y_PONG_OFFSET, mctl->domain_num, 0,
-		((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)),
-		SZ_4K, IOMMU_WRITE | IOMMU_READ,
-		(unsigned long *)&mctl->pong_imem_y);
-	mctl->pong_imem_cbcr = mctl->pong_imem_y + IMEM_Y_SIZE;
-	if (rc < 0) {
-		pr_err("%s: pong iommu mapping returned error %d\n",
-			 __func__, rc);
-		mctl->pong_imem_y = 0;
-		mctl->pong_imem_cbcr = 0;
-	}
-	return rc;
-}
-
-static void unmap_imem_addresses(struct msm_cam_media_controller *mctl)
-{
-	msm_iommu_unmap_contig_buffer(mctl->ping_imem_y,
-		mctl->domain_num, 0,
-		((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)));
-	msm_iommu_unmap_contig_buffer(mctl->pong_imem_y,
-		mctl->domain_num, 0,
-		((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)));
-	mctl->ping_imem_y = 0;
-	mctl->ping_imem_cbcr = 0;
-	mctl->pong_imem_y = 0;
-	mctl->pong_imem_cbcr = 0;
-}
-
-static long msm_ioctl_server(struct file *file, void *fh,
-		bool valid_prio, int cmd, void *arg)
-{
-	int rc = -EINVAL;
-	struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
-	struct msm_camera_info temp_cam_info;
-	struct msm_cam_config_dev_info temp_config_info;
-	struct msm_mctl_node_info temp_mctl_info;
-	int i;
-
-	D("%s: cmd %d\n", __func__, _IOC_NR(cmd));
-
-	switch (cmd) {
-	case MSM_CAM_V4L2_IOCTL_GET_CAMERA_INFO:
-		if (copy_from_user(&temp_cam_info,
-				(void __user *)ioctl_ptr->ioctl_ptr,
-				sizeof(struct msm_camera_info))) {
-			pr_err("%s Copy from user failed for cmd %d",
-				__func__, cmd);
-			rc = -EINVAL;
-			return rc;
-		}
-		for (i = 0; i < g_server_dev.camera_info.num_cameras; i++) {
-			if (copy_to_user((void __user *)
-			temp_cam_info.video_dev_name[i],
-			g_server_dev.camera_info.video_dev_name[i],
-			strnlen(g_server_dev.camera_info.video_dev_name[i],
-				MAX_DEV_NAME_LEN))) {
-				pr_err("%s Copy to user failed for cmd %d",
-					__func__, cmd);
-				rc = -EINVAL;
-				return rc;
-			}
-			temp_cam_info.has_3d_support[i] =
-				g_server_dev.camera_info.has_3d_support[i];
-			temp_cam_info.is_internal_cam[i] =
-				g_server_dev.camera_info.is_internal_cam[i];
-			temp_cam_info.s_mount_angle[i] =
-				g_server_dev.camera_info.s_mount_angle[i];
-			temp_cam_info.sensor_type[i] =
-				g_server_dev.camera_info.sensor_type[i];
-
-		}
-		temp_cam_info.num_cameras =
-			g_server_dev.camera_info.num_cameras;
-		if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
-			&temp_cam_info,	sizeof(struct msm_camera_info))) {
-			pr_err("%s Copy to user failed for cmd %d",
-				__func__, cmd);
-			rc = -EINVAL;
-			return rc;
-		}
-		rc = 0;
-		break;
-
-	case MSM_CAM_V4L2_IOCTL_GET_CONFIG_INFO:
-		if (copy_from_user(&temp_config_info,
-			(void __user *)ioctl_ptr->ioctl_ptr,
-			sizeof(struct msm_cam_config_dev_info))) {
-			pr_err("%s Copy from user failed for cmd %d",
-				__func__, cmd);
-			rc = -EINVAL;
-			return rc;
-		}
-		for (i = 0;
-		 i < g_server_dev.config_info.num_config_nodes; i++) {
-			if (copy_to_user(
-			(void __user *)temp_config_info.config_dev_name[i],
-			g_server_dev.config_info.config_dev_name[i],
-			strnlen(g_server_dev.config_info.config_dev_name[i],
-				MAX_DEV_NAME_LEN))) {
-				pr_err("%s Copy to user failed for cmd %d",
-					__func__, cmd);
-				rc = -EINVAL;
-				return rc;
-			}
-		}
-		temp_config_info.num_config_nodes =
-			g_server_dev.config_info.num_config_nodes;
-		if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
-			&temp_config_info,
-			sizeof(struct msm_cam_config_dev_info))) {
-			pr_err("%s Copy to user failed for cmd %d",
-				__func__, cmd);
-			rc = -EINVAL;
-			return rc;
-		}
-		rc = 0;
-		break;
-	case MSM_CAM_V4L2_IOCTL_GET_MCTL_INFO:
-		if (copy_from_user(&temp_mctl_info,
-				(void __user *)ioctl_ptr->ioctl_ptr,
-				sizeof(struct msm_mctl_node_info))) {
-			pr_err("%s Copy from user failed for cmd %d",
-				__func__, cmd);
-			rc = -EINVAL;
-			return rc;
-		}
-		for (i = 0; i < g_server_dev.mctl_node_info.num_mctl_nodes;
-				i++) {
-			if (copy_to_user((void __user *)
-			temp_mctl_info.mctl_node_name[i],
-			g_server_dev.mctl_node_info.mctl_node_name[i], strnlen(
-			g_server_dev.mctl_node_info.mctl_node_name[i],
-			MAX_DEV_NAME_LEN))) {
-				pr_err("%s Copy to user failed for cmd %d",
-					__func__, cmd);
-				rc = -EINVAL;
-				return rc;
-			}
-		}
-		temp_mctl_info.num_mctl_nodes =
-			g_server_dev.mctl_node_info.num_mctl_nodes;
-		if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
-			&temp_mctl_info, sizeof(struct msm_mctl_node_info))) {
-			pr_err("%s Copy to user failed for cmd %d",
-				__func__, cmd);
-			rc = -EINVAL;
-			return rc;
-		}
-		rc = 0;
-	break;
-
-	case MSM_CAM_V4L2_IOCTL_CTRL_CMD_DONE:
-		D("%s: MSM_CAM_IOCTL_CTRL_CMD_DONE\n", __func__);
-		rc = msm_ctrl_cmd_done(arg);
-		break;
-
-	case MSM_CAM_V4L2_IOCTL_GET_EVENT_PAYLOAD: {
-		struct msm_queue_cmd *event_cmd;
-		struct msm_isp_event_ctrl u_isp_event;
-		struct msm_isp_event_ctrl *k_isp_event;
-		struct msm_device_queue *queue;
-		void __user *u_ctrl_value = NULL;
-		if (copy_from_user(&u_isp_event,
-			(void __user *)ioctl_ptr->ioctl_ptr,
-			sizeof(struct msm_isp_event_ctrl))) {
-			pr_err("%s Copy from user failed for cmd %d",
-				__func__, cmd);
-			rc = -EINVAL;
-			return rc;
-		}
-
-		mutex_lock(&g_server_dev.server_queue_lock);
-		if (!g_server_dev.server_queue
-			[u_isp_event.isp_data.ctrl.queue_idx].queue_active) {
-			pr_err("%s: Invalid queue\n", __func__);
-			mutex_unlock(&g_server_dev.server_queue_lock);
-			rc = -EINVAL;
-			return rc;
-		}
-		queue = &g_server_dev.server_queue
-			[u_isp_event.isp_data.ctrl.queue_idx].eventData_q;
-		event_cmd = msm_dequeue(queue, list_eventdata);
-		if (!event_cmd) {
-			pr_err("%s: No event payload\n", __func__);
-			rc = -EINVAL;
-			mutex_unlock(&g_server_dev.server_queue_lock);
-			return rc;
-		}
-		k_isp_event = (struct msm_isp_event_ctrl *)
-				event_cmd->command;
-		free_qcmd(event_cmd);
-
-		/* Save the pointer of the user allocated command buffer*/
-		u_ctrl_value = u_isp_event.isp_data.ctrl.value;
-
-		/* Copy the event structure into user struct*/
-		u_isp_event = *k_isp_event;
-
-		/* Restore the saved pointer of the user
-		 * allocated command buffer. */
-		u_isp_event.isp_data.ctrl.value = u_ctrl_value;
-
-		/* Copy the ctrl cmd, if present*/
-		if (k_isp_event->isp_data.ctrl.length > 0 &&
-			k_isp_event->isp_data.ctrl.value != NULL) {
-			void *k_ctrl_value =
-				k_isp_event->isp_data.ctrl.value;
-			if (copy_to_user(u_ctrl_value, k_ctrl_value,
-				 k_isp_event->isp_data.ctrl.length)) {
-				pr_err("%s Copy to user failed for cmd %d",
-					__func__, cmd);
-				kfree(k_isp_event->isp_data.ctrl.value);
-				kfree(k_isp_event);
-				rc = -EINVAL;
-				mutex_unlock(&g_server_dev.server_queue_lock);
-				break;
-			}
-			kfree(k_isp_event->isp_data.ctrl.value);
-		}
-		if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
-			&u_isp_event, sizeof(struct msm_isp_event_ctrl))) {
-			pr_err("%s Copy to user failed for cmd %d",
-				__func__, cmd);
-			kfree(k_isp_event);
-			mutex_unlock(&g_server_dev.server_queue_lock);
-			rc = -EINVAL;
-			return rc;
-		}
-		kfree(k_isp_event);
-		mutex_unlock(&g_server_dev.server_queue_lock);
-		rc = 0;
-		break;
-	}
-
-	case MSM_CAM_IOCTL_SEND_EVENT:
-		rc = msm_server_send_v4l2_evt(arg);
-		break;
-
-	default:
-		pr_err("%s: Invalid IOCTL = %d", __func__, cmd);
-		break;
-	}
-	return rc;
-}
-
-static int msm_open_server(struct file *fp)
-{
-	int rc = 0;
-	D("%s: open %s\n", __func__, fp->f_path.dentry->d_name.name);
-	mutex_lock(&g_server_dev.server_lock);
-	g_server_dev.use_count++;
-	if (g_server_dev.use_count == 1)
-		fp->private_data =
-			&g_server_dev.server_command_queue.eventHandle;
-	mutex_unlock(&g_server_dev.server_lock);
-	return rc;
-}
-
-static int msm_close_server(struct file *fp)
-{
-	struct v4l2_event_subscription sub;
-	D("%s\n", __func__);
-	mutex_lock(&g_server_dev.server_lock);
-	if (g_server_dev.use_count > 0)
-		g_server_dev.use_count--;
-	mutex_unlock(&g_server_dev.server_lock);
-
-	if (g_server_dev.use_count == 0) {
-		int i;
-		mutex_lock(&g_server_dev.server_lock);
-		for (i = 0; i < MAX_NUM_ACTIVE_CAMERA; i++) {
-			if (g_server_dev.pcam_active[i]) {
-				struct msm_cam_media_controller *pmctl = NULL;
-
-				pmctl = msm_cam_server_get_mctl(
-				g_server_dev.pcam_active[i]->mctl_handle);
-				if (pmctl && pmctl->mctl_release) {
-					pmctl->mctl_release(pmctl);
-					/*so that it isn't closed again*/
-					pmctl->mctl_release = NULL;
-				}
-				if (pmctl)
-					msm_cam_server_send_error_evt(pmctl,
-						V4L2_EVENT_PRIVATE_START +
-						MSM_CAM_APP_NOTIFY_ERROR_EVENT);
-			}
-		}
-		sub.type = V4L2_EVENT_ALL;
-		msm_server_v4l2_unsubscribe_event(
-			&g_server_dev.server_command_queue.eventHandle, &sub);
-		mutex_unlock(&g_server_dev.server_lock);
-	}
-	return 0;
-}
-
-static unsigned int msm_poll_server(struct file *fp,
-					struct poll_table_struct *wait)
-{
-	int rc = 0;
-
-	D("%s\n", __func__);
-	poll_wait(fp,
-		 &g_server_dev.server_command_queue.eventHandle.wait,

-		 wait);
-	if (v4l2_event_pending(&g_server_dev.server_command_queue.eventHandle))
-		rc |= POLLPRI;
-
-	return rc;
-}
-
-int msm_server_get_usecount(void)
-{
-	return g_server_dev.use_count;
-}
-
-int msm_server_update_sensor_info(struct msm_cam_v4l2_device *pcam,
-	struct msm_camera_sensor_info *sdata)
-{
-	int rc = 0;
-
-	if (!pcam || !sdata) {
-		pr_err("%s Input data is null ", __func__);
-		return -EINVAL;
-	}
-
-	g_server_dev.camera_info.video_dev_name
-	[g_server_dev.camera_info.num_cameras]
-	= video_device_node_name(pcam->pvdev);
-	D("%s Connected video device %s\n", __func__,
-		g_server_dev.camera_info.video_dev_name
-		[g_server_dev.camera_info.num_cameras]);
-
-	g_server_dev.camera_info.s_mount_angle
-	[g_server_dev.camera_info.num_cameras]
-	= sdata->sensor_platform_info->mount_angle;
-
-	g_server_dev.camera_info.is_internal_cam
-	[g_server_dev.camera_info.num_cameras]
-	= sdata->camera_type;
-
-	g_server_dev.mctl_node_info.mctl_node_name
-	[g_server_dev.mctl_node_info.num_mctl_nodes]
-	= video_device_node_name(pcam->mctl_node.pvdev);
-
-	pr_info("%s mctl_node_name[%d] = %s\n", __func__,
-		g_server_dev.mctl_node_info.num_mctl_nodes,
-		g_server_dev.mctl_node_info.mctl_node_name
-		[g_server_dev.mctl_node_info.num_mctl_nodes]);
-
-	/*Temporary solution to store info in media device structure
-	  until we can expand media device structure to support more
-	  device info*/
-	snprintf(pcam->media_dev.serial,
-			sizeof(pcam->media_dev.serial),
-			"%s-%d-%d", QCAMERA_NAME,
-			sdata->sensor_platform_info->mount_angle,
-			sdata->camera_type);
-
-	g_server_dev.camera_info.num_cameras++;
-	g_server_dev.mctl_node_info.num_mctl_nodes++;
-
-	D("%s done, rc = %d\n", __func__, rc);
-	D("%s number of sensors connected is %d\n", __func__,
-		g_server_dev.camera_info.num_cameras);
-
-	return rc;
-}
-
-int msm_server_begin_session(struct msm_cam_v4l2_device *pcam,
-	int server_q_idx)
-{
-	int rc = -EINVAL, ges_evt;
-	struct msm_cam_server_queue *queue;
-	struct msm_cam_media_controller *pmctl;
-
-	if (!pcam) {
-		pr_err("%s pcam passed is null ", __func__);
-		return rc;
-	}
-
-	ges_evt = MSM_V4L2_GES_CAM_OPEN;
-	D("%s send gesture evt\n", __func__);
-	msm_cam_server_subdev_notify(g_server_dev.gesture_device,
-		NOTIFY_GESTURE_CAM_EVT, &ges_evt);
-
-	pcam->server_queue_idx = server_q_idx;
-	queue = &g_server_dev.server_queue[server_q_idx];
-	queue->ctrl_data = kzalloc(sizeof(uint8_t) *
-			MAX_SERVER_PAYLOAD_LENGTH, GFP_KERNEL);
-	if (queue->ctrl_data == NULL) {
-		pr_err("%s: Could not allocate memory\n", __func__);
-		rc = -ENOMEM;
-		goto error;
-	}
-	msm_queue_init(&queue->ctrl_q, "control");
-	msm_queue_init(&queue->eventData_q, "eventdata");
-	queue->queue_active = 1;
-	rc = msm_cam_server_open_session(&g_server_dev, pcam);
-	if (rc < 0) {
-		pr_err("%s: cam_server_open_session failed %d\n",
-			__func__, rc);
-		goto error;
-	}
-
-	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
-	if (!pmctl) {
-		pr_err("%s: invalid mctl controller", __func__);
-		goto error;
-	}
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-		pmctl->domain = msm_cam_server_get_domain();
-		pmctl->domain_num = msm_cam_server_get_domain_num();
-#endif
-	rc = map_imem_addresses(pmctl);
-	if (rc < 0) {
-		pr_err("%sFailed to map imem addresses %d\n", __func__, rc);
-		goto error;
-	}
-
-	return rc;
-error:
-	ges_evt = MSM_V4L2_GES_CAM_CLOSE;
-	msm_cam_server_subdev_notify(g_server_dev.gesture_device,
-		NOTIFY_GESTURE_CAM_EVT, &ges_evt);
-
-	queue->queue_active = 0;
-	msm_drain_eventq(&queue->eventData_q);
-	msm_queue_drain(&queue->ctrl_q, list_control);
-	kfree(queue->ctrl_data);
-	queue->ctrl_data = NULL;
-	queue = NULL;
-	return rc;
-}
-
-int msm_server_end_session(struct msm_cam_v4l2_device *pcam)
-{
-	int rc = -EINVAL, ges_evt;
-	struct msm_cam_server_queue *queue;
-	struct msm_cam_media_controller *pmctl;
-
-	mutex_lock(&g_server_dev.server_queue_lock);
-	queue = &g_server_dev.server_queue[pcam->server_queue_idx];
-	queue->queue_active = 0;
-	kfree(queue->ctrl_data);
-	queue->ctrl_data = NULL;
-	msm_queue_drain(&queue->ctrl_q, list_control);
-	msm_drain_eventq(&queue->eventData_q);
-	mutex_unlock(&g_server_dev.server_queue_lock);
-
-	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
-	if (!pmctl) {
-		pr_err("%s: invalid mctl controller", __func__);
-		return -EINVAL;
-	}
-	unmap_imem_addresses(pmctl);
-
-	rc = msm_cam_server_close_session(&g_server_dev, pcam);
-	if (rc < 0)
-		pr_err("msm_cam_server_close_session fails %d\n", rc);
-
-	ges_evt = MSM_V4L2_GES_CAM_CLOSE;
-	msm_cam_server_subdev_notify(g_server_dev.gesture_device,
-			NOTIFY_GESTURE_CAM_EVT, &ges_evt);
-
-	return rc;
-}
-
-/* Init a config node for ISP control,
- * which will create a config device (/dev/config0/ and plug in
- * ISP's operation "v4l2_ioctl_ops*"
- */
-static const struct v4l2_file_operations msm_fops_server = {
-	.owner = THIS_MODULE,
-	.open  = msm_open_server,
-	.poll  = msm_poll_server,
-	.unlocked_ioctl = video_ioctl2,
-	.release = msm_close_server,
-};
-
-static const struct v4l2_ioctl_ops msm_ioctl_ops_server = {
-	.vidioc_subscribe_event = msm_server_v4l2_subscribe_event,
-	.vidioc_unsubscribe_event = msm_server_v4l2_unsubscribe_event,
-	.vidioc_default = msm_ioctl_server,
-};
-
-static uint32_t msm_camera_server_find_mctl(
-		unsigned int notification, void *arg)
-{
-	int i;
-	uint32_t interface;
-	switch (notification) {
-	case NOTIFY_ISP_MSG_EVT:
-		if (((struct isp_msg_event *)arg)->msg_id ==
-			MSG_ID_RDI0_UPDATE_ACK)
-			interface = RDI_0;
-		else if (((struct isp_msg_event *)arg)->msg_id ==
-			MSG_ID_RDI1_UPDATE_ACK)
-			interface = RDI_1;
-		else
-			interface = PIX_0;
-		break;
-	case NOTIFY_VFE_MSG_OUT:
-		if (((struct isp_msg_output *)arg)->output_id ==
-					MSG_ID_OUTPUT_TERTIARY1)
-			interface = RDI_0;
-		else if (((struct isp_msg_output *)arg)->output_id ==
-						MSG_ID_OUTPUT_TERTIARY2)
-			interface = RDI_1;
-		else
-			interface = PIX_0;
-		break;
-	case NOTIFY_VFE_BUF_EVT: {
-		struct msm_vfe_resp *rp;
-		struct msm_frame_info *frame_info;
-		uint8_t vnode_id;
-
-		rp = (struct msm_vfe_resp *)arg;
-		frame_info = rp->evt_msg.data;
-		if (!frame_info) {
-			interface = PIX_0;
-			break;
-		}
-		if (frame_info->inst_handle) {
-			vnode_id = GET_DEVID_MODE(frame_info->inst_handle);
-			if (vnode_id < MAX_NUM_ACTIVE_CAMERA &&
-				g_server_dev.opened_pcam[vnode_id]) {
-				return g_server_dev.
-					opened_pcam[vnode_id]->mctl_handle;
-			} else {
-				pr_err("%s: cannot find mctl handle", __func__);
-				return 0;
-			}
-		} else {
-			if (frame_info->path == VFE_MSG_OUTPUT_TERTIARY1)
-				interface = RDI_0;
-			else if (frame_info->path == VFE_MSG_OUTPUT_TERTIARY2)
-				interface = RDI_1;
-			else
-				interface = PIX_0;
-		}
-		}
-		break;
-	case NOTIFY_AXI_RDI_SOF_COUNT: {
-		struct rdi_count_msg *msg = (struct rdi_count_msg *)arg;
-		interface = msg->rdi_interface;
-		}
-		break;
-	case NOTIFY_VFE_MSG_STATS:
-	case NOTIFY_VFE_MSG_COMP_STATS:
-	case NOTIFY_VFE_CAMIF_ERROR:
-	default:
-		interface = PIX_0;
-		break;
-	}
-	for (i = 0; i < INTF_MAX; i++) {
-		if (interface == g_server_dev.interface_map_table[i].interface)
-			break;
-	}
-	if (i == INTF_MAX) {
-		pr_err("%s: Cannot find valid interface map\n", __func__);
-		return -EINVAL;
-	} else
-		return g_server_dev.interface_map_table[i].mctl_handle;
-}
-
-static void msm_cam_server_subdev_notify(struct v4l2_subdev *sd,
-				unsigned int notification, void *arg)
-{
-	int rc = -EINVAL;
-	uint32_t mctl_handle = 0;
-	struct msm_cam_media_controller *p_mctl = NULL;
-	int is_gesture_evt =
-		(notification == NOTIFY_GESTURE_EVT)
-		|| (notification == NOTIFY_GESTURE_CAM_EVT);
-
-	if (!is_gesture_evt) {
-		mctl_handle = msm_camera_server_find_mctl(notification, arg);
-		if (mctl_handle < 0) {
-			pr_err("%s: Couldn't find mctl instance!\n", __func__);
-			return;
-		}
-	}
-	switch (notification) {
-	case NOTIFY_ISP_MSG_EVT:
-	case NOTIFY_VFE_MSG_OUT:
-	case NOTIFY_VFE_PIX_SOF_COUNT:
-	case NOTIFY_VFE_MSG_STATS:
-	case NOTIFY_VFE_MSG_COMP_STATS:
-	case NOTIFY_VFE_BUF_EVT:
-		p_mctl = msm_cam_server_get_mctl(mctl_handle);
-		if (p_mctl && p_mctl->isp_notify && p_mctl->vfe_sdev)
-			rc = p_mctl->isp_notify(p_mctl,
-				p_mctl->vfe_sdev, notification, arg);
-		break;
-	case NOTIFY_VFE_IRQ:{
-		struct msm_vfe_cfg_cmd cfg_cmd;
-		struct msm_camvfe_params vfe_params;
-		cfg_cmd.cmd_type = CMD_VFE_PROCESS_IRQ;
-		vfe_params.vfe_cfg = &cfg_cmd;
-		vfe_params.data = arg;
-		rc = v4l2_subdev_call(sd,
-			core, ioctl, 0, &vfe_params);
-	}
-		break;
-	case NOTIFY_AXI_IRQ:
-		rc = v4l2_subdev_call(sd, core, ioctl, VIDIOC_MSM_AXI_IRQ, arg);
-		break;
-	case NOTIFY_AXI_RDI_SOF_COUNT:
-		p_mctl = msm_cam_server_get_mctl(mctl_handle);
-		if (p_mctl && p_mctl->axi_sdev)
-			rc = v4l2_subdev_call(p_mctl->axi_sdev, core, ioctl,
-				VIDIOC_MSM_AXI_RDI_COUNT_UPDATE, arg);
-		break;
-	case NOTIFY_PCLK_CHANGE:
-		p_mctl = v4l2_get_subdev_hostdata(sd);
-		if (p_mctl) {
-			if (p_mctl->axi_sdev)
-				rc = v4l2_subdev_call(p_mctl->axi_sdev, video,
-				s_crystal_freq, *(uint32_t *)arg, 0);
-			else
-				rc = v4l2_subdev_call(p_mctl->vfe_sdev, video,
-				s_crystal_freq, *(uint32_t *)arg, 0);
-		}
-		break;
-	case NOTIFY_GESTURE_EVT:
-		rc = v4l2_subdev_call(g_server_dev.gesture_device,
-			core, ioctl, VIDIOC_MSM_GESTURE_EVT, arg);
-		break;
-	case NOTIFY_GESTURE_CAM_EVT:
-		rc = v4l2_subdev_call(g_server_dev.gesture_device,
-			core, ioctl, VIDIOC_MSM_GESTURE_CAM_EVT, arg);
-		break;
-	case NOTIFY_VFE_CAMIF_ERROR: {
-		p_mctl = msm_cam_server_get_mctl(mctl_handle);
-		if (p_mctl)
-			msm_cam_server_send_error_evt(p_mctl,
-				V4L2_EVENT_PRIVATE_START +
-				MSM_CAM_APP_NOTIFY_ERROR_EVENT);
-		break;
-	}
-	default:
-		break;
-	}
-
-	return;
-}
-
-void msm_cam_release_subdev_node(struct video_device *vdev)
-{
-	struct v4l2_subdev *sd = video_get_drvdata(vdev);
-	sd->devnode = NULL;
-	kfree(vdev);
-}
-
-/* Helper function to get the irq_idx corresponding
- * to the irq_num. */
-int get_irq_idx_from_irq_num(int irq_num)
-{
-	int i;
-	for (i = 0; i < CAMERA_SS_IRQ_MAX; i++)
-		if (irq_num == g_server_dev.hw_irqmap[i].irq_num)
-			return g_server_dev.hw_irqmap[i].irq_idx;
-
-	return -EINVAL;
-}
-
-static struct v4l2_subdev  *msm_cam_find_subdev_node(
-	struct v4l2_subdev **sd_list, u32 revision_num)
-{
-	int i = 0;
-	for (i = 0; sd_list[i] != NULL; i++) {
-		if (sd_list[i]->entity.revision == revision_num) {
-			return sd_list[i];
-			break;
-		}
-	}
-	return NULL;
-}
-
-int msm_mctl_find_sensor_subdevs(struct msm_cam_media_controller *p_mctl,
-	uint8_t csiphy_core_index, uint8_t csid_core_index)
-{
-	int rc = -ENODEV;
-
-	v4l2_set_subdev_hostdata(p_mctl->sensor_sdev, p_mctl);
-
-	rc = msm_csi_register_subdevs(p_mctl, csiphy_core_index,
-		csid_core_index, &g_server_dev);
-	if (rc < 0)
-		pr_err("%s: Could not find sensor subdevs\n", __func__);
-
-	return rc;
-}
-
-int msm_mctl_find_flash_subdev(struct msm_cam_media_controller *p_mctl,
-	uint8_t index)
-{
-	if (index < MAX_NUM_FLASH_DEV)
-		p_mctl->flash_sdev = g_server_dev.flash_device[index];
-	return 0;
-}
-
-static irqreturn_t msm_camera_server_parse_irq(int irq_num, void *data)
-{
-	unsigned long flags;
-	int irq_idx, i, rc;
-	u32 status = 0;
-	struct intr_table_entry *ind_irq_tbl;
-	struct intr_table_entry *comp_irq_tbl;
-	bool subdev_handled = 0;
-
-	irq_idx = get_irq_idx_from_irq_num(irq_num);
-	if (irq_idx < 0) {
-		pr_err("server_parse_irq: no clients for irq #%d. returning ",
-			irq_num);
-		return IRQ_HANDLED;
-	}
-
-	spin_lock_irqsave(&g_server_dev.intr_table_lock, flags);
-	ind_irq_tbl = &g_server_dev.irq_lkup_table.ind_intr_tbl[0];
-	comp_irq_tbl = &g_server_dev.irq_lkup_table.comp_intr_tbl[0];
-	if (ind_irq_tbl[irq_idx].is_composite) {
-		for (i = 0; i < comp_irq_tbl[irq_idx].num_hwcore; i++) {
-			if (comp_irq_tbl[irq_idx].subdev_list[i]) {
-				rc = v4l2_subdev_call(
-					comp_irq_tbl[irq_idx].subdev_list[i],
-					core, interrupt_service_routine,
-					status, &subdev_handled);
-				if ((rc < 0) || !subdev_handled) {
-					pr_err("server_parse_irq:Error\n"
-						"handling irq %d rc = %d",
-						irq_num, rc);
-					/* Dispatch the irq to the remaining
-					 * subdevs in the list. */
-					continue;
-				}
-			}
-		}
-	} else {
-		rc = v4l2_subdev_call(ind_irq_tbl[irq_idx].subdev_list[0],
-			core, interrupt_service_routine,
-			status, &subdev_handled);
-		if ((rc < 0) || !subdev_handled) {
-			pr_err("server_parse_irq: Error handling irq %d rc = %d",
-				irq_num, rc);
-			spin_unlock_irqrestore(&g_server_dev.intr_table_lock,
-				flags);
-			return IRQ_HANDLED;
-		}
-	}
-	spin_unlock_irqrestore(&g_server_dev.intr_table_lock, flags);
-	return IRQ_HANDLED;
-}
-
-/* Helper function to get the irq_idx corresponding
- * to the camera hwcore. This function should _only_
- * be invoked when the IRQ Router is configured
- * non-composite mode. */
-int get_irq_idx_from_camhw_idx(int cam_hw_idx)
-{
-	int i;
-	for (i = 0; i < MSM_CAM_HW_MAX; i++)
-		if (cam_hw_idx == g_server_dev.hw_irqmap[i].cam_hw_idx)
-			return g_server_dev.hw_irqmap[i].irq_idx;
-
-	return -EINVAL;
-}
-
-static inline void update_compirq_subdev_info(
-	struct intr_table_entry *irq_entry,
-	uint32_t cam_hw_mask, uint8_t cam_hw_id,
-	int *num_hwcore)
-{
-	if (cam_hw_mask & (0x1 << cam_hw_id)) {
-		/* If the mask has been set for this cam hwcore
-		 * update the subdev ptr......*/
-		irq_entry->subdev_list[cam_hw_id] =
-			g_server_dev.subdev_table[cam_hw_id];
-		(*num_hwcore)++;
-	} else {
-		/*....else, just clear it, so that the irq will
-		 * not be dispatched to this hw. */
-		irq_entry->subdev_list[cam_hw_id] = NULL;
-	}
-}
-
-static int msm_server_update_composite_irq_info(
-	struct intr_table_entry *irq_req)
-{
-	int num_hwcore = 0, rc = 0;
-	struct intr_table_entry *comp_irq_tbl =
-		&g_server_dev.irq_lkup_table.comp_intr_tbl[0];
-
-	comp_irq_tbl[irq_req->irq_idx].is_composite = 1;
-	comp_irq_tbl[irq_req->irq_idx].irq_trigger_type =
-		irq_req->irq_trigger_type;
-	comp_irq_tbl[irq_req->irq_idx].num_hwcore = irq_req->num_hwcore;
-
-	update_compirq_subdev_info(&comp_irq_tbl[irq_req->irq_idx],
-		irq_req->cam_hw_mask, MSM_CAM_HW_MICRO, &num_hwcore);
-
-	update_compirq_subdev_info(&comp_irq_tbl[irq_req->irq_idx],
-		irq_req->cam_hw_mask, MSM_CAM_HW_CCI, &num_hwcore);
-
-	update_compirq_subdev_info(&comp_irq_tbl[irq_req->irq_idx],
-		irq_req->cam_hw_mask, MSM_CAM_HW_CSI0, &num_hwcore);
-
-	update_compirq_subdev_info(&comp_irq_tbl[irq_req->irq_idx],
-		irq_req->cam_hw_mask, MSM_CAM_HW_CSI1, &num_hwcore);
-
-	update_compirq_subdev_info(&comp_irq_tbl[irq_req->irq_idx],
-		irq_req->cam_hw_mask, MSM_CAM_HW_CSI2, &num_hwcore);
-
-	update_compirq_subdev_info(&comp_irq_tbl[irq_req->irq_idx],
-		irq_req->cam_hw_mask, MSM_CAM_HW_CSI3, &num_hwcore);
-
-	update_compirq_subdev_info(&comp_irq_tbl[irq_req->irq_idx],
-		irq_req->cam_hw_mask, MSM_CAM_HW_ISPIF, &num_hwcore);
-
-	update_compirq_subdev_info(&comp_irq_tbl[irq_req->irq_idx],
-		irq_req->cam_hw_mask, MSM_CAM_HW_CPP, &num_hwcore);
-
-	update_compirq_subdev_info(&comp_irq_tbl[irq_req->irq_idx],
-		irq_req->cam_hw_mask, MSM_CAM_HW_VFE0, &num_hwcore);
-
-	update_compirq_subdev_info(&comp_irq_tbl[irq_req->irq_idx],
-		irq_req->cam_hw_mask, MSM_CAM_HW_VFE1, &num_hwcore);
-
-	update_compirq_subdev_info(&comp_irq_tbl[irq_req->irq_idx],
-		irq_req->cam_hw_mask, MSM_CAM_HW_JPEG0, &num_hwcore);
-
-	update_compirq_subdev_info(&comp_irq_tbl[irq_req->irq_idx],
-		irq_req->cam_hw_mask, MSM_CAM_HW_JPEG1, &num_hwcore);
-
-	update_compirq_subdev_info(&comp_irq_tbl[irq_req->irq_idx],
-		irq_req->cam_hw_mask, MSM_CAM_HW_JPEG2, &num_hwcore);
-
-	if (num_hwcore != irq_req->num_hwcore) {
-		pr_warn("%s Mismatch!! requested cam hwcores: %d, Mask set %d",
-			__func__, irq_req->num_hwcore, num_hwcore);
-		rc = -EINVAL;
-	}
-	return rc;
-}
-
-int msm_cam_server_request_irq(void *arg)
-{
-	unsigned long flags;
-	int rc = 0;
-	struct intr_table_entry *irq_req =  (struct intr_table_entry *)arg;
-	struct intr_table_entry *ind_irq_tbl =
-		&g_server_dev.irq_lkup_table.ind_intr_tbl[0];
-	struct intr_table_entry *comp_irq_tbl =
-		&g_server_dev.irq_lkup_table.comp_intr_tbl[0];
-
-	if (!irq_req || !irq_req->irq_num || !irq_req->num_hwcore) {
-		pr_err("%s Invalid input ", __func__);
-		return -EINVAL;
-	}
-
-	if (!g_server_dev.irqr_device) {
-		/* This either means, the current target does not
-		 * have a IRQ Router hw or the IRQ Router device is
-		 * not probed yet. The latter should not happen.
-		 * In any case, just return back without updating
-		 * the interrupt lookup table. */
-		pr_info("%s IRQ Router hw is not present. ", __func__);
-		return -ENXIO;
-	}
-
-	if (irq_req->is_composite) {
-		if (irq_req->irq_idx >= CAMERA_SS_IRQ_0 &&
-				irq_req->irq_idx < CAMERA_SS_IRQ_MAX) {
-			spin_lock_irqsave(&g_server_dev.intr_table_lock, flags);
-			/* Update the composite irq information into
-			 * the composite irq lookup table.... */
-			if (msm_server_update_composite_irq_info(irq_req)) {
-				pr_err("%s Invalid configuration", __func__);
-				spin_unlock_irqrestore(
-					&g_server_dev.intr_table_lock, flags);
-				return -EINVAL;
-			}
-			spin_unlock_irqrestore(&g_server_dev.intr_table_lock,
-				flags);
-			/*...and then update the corresponding entry
-			 * in the individual irq lookup table to indicate
-			 * that this IRQ is a composite irq and needs to be
-			 * sent to multiple subdevs. */
-			ind_irq_tbl[irq_req->irq_idx].is_composite = 1;
-			rc = request_irq(comp_irq_tbl[irq_req->irq_idx].irq_num,
-				msm_camera_server_parse_irq,
-				irq_req->irq_trigger_type,
-				ind_irq_tbl[irq_req->irq_idx].dev_name,
-				ind_irq_tbl[irq_req->irq_idx].data);
-			if (rc < 0) {
-				pr_err("%s: request_irq failed for %s\n",
-					__func__, irq_req->dev_name);
-				return -EBUSY;
-			}
-		} else {
-			pr_err("%s Invalid irq_idx %d ",
-				__func__, irq_req->irq_idx);
-			return -EINVAL;
-		}
-	} else {
-		if (irq_req->cam_hw_idx >= MSM_CAM_HW_MICRO &&
-				irq_req->cam_hw_idx < MSM_CAM_HW_MAX) {
-			/* Update the irq information into
-			 * the individual irq lookup table.... */
-			irq_req->irq_idx =
-				get_irq_idx_from_camhw_idx(irq_req->cam_hw_idx);
-			if (irq_req->irq_idx < 0) {
-				pr_err("%s Invalid hw index %d ", __func__,
-					irq_req->cam_hw_idx);
-				return -EINVAL;
-			}
-			spin_lock_irqsave(&g_server_dev.intr_table_lock, flags);
-			/* Make sure the composite irq is not configured for
-			 * this IRQ already. */
-			BUG_ON(ind_irq_tbl[irq_req->irq_idx].is_composite);
-
-			ind_irq_tbl[irq_req->irq_idx] = *irq_req;
-			/* irq_num is stored inside the server's hw_irqmap
-			 * during the device subdevice registration. */
-			ind_irq_tbl[irq_req->irq_idx].irq_num =
-			g_server_dev.hw_irqmap[irq_req->irq_idx].irq_num;
-
-			/*...and clear the corresponding entry in the
-			 * compsoite irq lookup table to indicate that this
-			 * IRQ will only be dispatched to single subdev. */
-			memset(&comp_irq_tbl[irq_req->irq_idx], 0,
-					sizeof(struct intr_table_entry));
-			D("%s Saving Entry %d %d %d %p",
-			__func__,
-			ind_irq_tbl[irq_req->irq_idx].irq_num,
-			ind_irq_tbl[irq_req->irq_idx].cam_hw_idx,
-			ind_irq_tbl[irq_req->irq_idx].is_composite,
-			ind_irq_tbl[irq_req->irq_idx].subdev_list[0]);
-
-			spin_unlock_irqrestore(&g_server_dev.intr_table_lock,
-				flags);
-
-			rc = request_irq(ind_irq_tbl[irq_req->irq_idx].irq_num,
-				msm_camera_server_parse_irq,
-				irq_req->irq_trigger_type,
-				ind_irq_tbl[irq_req->irq_idx].dev_name,
-				ind_irq_tbl[irq_req->irq_idx].data);
-			if (rc < 0) {
-				pr_err("%s: request_irq failed for %s\n",
-					__func__, irq_req->dev_name);
-				return -EBUSY;
-			}
-		} else {
-			pr_err("%s Invalid hw index %d ", __func__,
-				irq_req->cam_hw_idx);
-			return -EINVAL;
-		}
-	}
-	D("%s Successfully requested for IRQ for device %s ", __func__,
-		irq_req->dev_name);
-	return rc;
-}
-
-int msm_cam_server_update_irqmap(
-	struct msm_cam_server_irqmap_entry *irqmap_entry)
-{
-	if (!irqmap_entry || (irqmap_entry->irq_idx < CAMERA_SS_IRQ_0 ||
-		irqmap_entry->irq_idx >= CAMERA_SS_IRQ_MAX)) {
-		pr_err("%s Invalid irqmap entry ", __func__);
-		return -EINVAL;
-	}
-	g_server_dev.hw_irqmap[irqmap_entry->irq_idx] = *irqmap_entry;
-	return 0;
-}
-
-static int msm_cam_server_register_subdev(struct v4l2_device *v4l2_dev,
-	struct v4l2_subdev *sd)
-{
-	int rc = 0;
-	struct video_device *vdev;
-
-	if (v4l2_dev == NULL || sd == NULL || !sd->name[0]) {
-		pr_err("%s Invalid input ", __func__);
-		return -EINVAL;
-	}
-
-	rc = v4l2_device_register_subdev(v4l2_dev, sd);
-	if (rc < 0) {
-		pr_err("%s v4l2 subdev register failed for %s ret = %d",
-			__func__, sd->name, rc);
-		return rc;
-	}
-
-	/* Register a device node for every subdev marked with the
-	 * V4L2_SUBDEV_FL_HAS_DEVNODE flag.
-	 */
-	if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE))
-		return rc;
-
-	vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
-	if (!vdev) {
-		pr_err("%s Not enough memory ", __func__);
-		rc = -ENOMEM;
-		goto clean_up;
-	}
-
-	video_set_drvdata(vdev, sd);
-	strlcpy(vdev->name, sd->name, sizeof(vdev->name));
-	vdev->v4l2_dev = v4l2_dev;
-	vdev->fops = &v4l2_subdev_fops;
-	vdev->release = msm_cam_release_subdev_node;
-	rc = __video_register_device(vdev, VFL_TYPE_SUBDEV, -1, 1,
-						  sd->owner);
-	if (rc < 0) {
-		pr_err("%s Error registering video device %s", __func__,
-			sd->name);
-		kfree(vdev);
-		goto clean_up;
-	}
-#if defined(CONFIG_MEDIA_CONTROLLER)
-	sd->entity.info.v4l.major = VIDEO_MAJOR;
-	sd->entity.info.v4l.minor = vdev->minor;
-#endif
-	sd->devnode = vdev;
-	return 0;
-
-clean_up:
-	if (sd->devnode)
-		video_unregister_device(sd->devnode);
-	return rc;
-}
-
-static int msm_cam_server_fill_sdev_irqnum(int cam_hw_idx,
-	int irq_num)
-{
-	int rc = 0, irq_idx;
-	irq_idx = get_irq_idx_from_camhw_idx(cam_hw_idx);
-	if (irq_idx < 0) {
-		pr_err("%s Invalid cam_hw_idx %d ", __func__, cam_hw_idx);
-		rc = -EINVAL;
-	} else {
-		g_server_dev.hw_irqmap[irq_idx].irq_num = irq_num;
-	}
-	return rc;
-}
-
-int msm_cam_register_subdev_node(struct v4l2_subdev *sd,
-	struct msm_cam_subdev_info *sd_info)
-{
-	int err = 0, cam_hw_idx;
-	uint8_t sdev_type, index;
-
-	sdev_type = sd_info->sdev_type;
-	index     = sd_info->sd_index;
-
-	switch (sdev_type) {
-	case SENSOR_DEV:
-		if (index >= MAX_NUM_SENSOR_DEV) {
-			pr_err("%s Invalid sensor idx %d", __func__, index);
-			err = -EINVAL;
-			break;
-		}
-		g_server_dev.sensor_device[index] = sd;
-		break;
-
-	case CSIPHY_DEV:
-		if (index >= MAX_NUM_CSIPHY_DEV) {
-			pr_err("%s Invalid CSIPHY idx %d", __func__, index);
-			err = -EINVAL;
-			break;
-		}
-		g_server_dev.csiphy_device[index] = sd;
-		break;
-
-	case CSID_DEV:
-		if (index >= MAX_NUM_CSID_DEV) {
-			pr_err("%s Invalid CSID idx %d", __func__, index);
-			err = -EINVAL;
-			break;
-		}
-		cam_hw_idx = MSM_CAM_HW_CSI0 + index;
-		g_server_dev.csid_device[index] = sd;
-		if (g_server_dev.irqr_device) {
-			g_server_dev.subdev_table[cam_hw_idx] = sd;
-			err = msm_cam_server_fill_sdev_irqnum(cam_hw_idx,
-				sd_info->irq_num);
-		}
-		break;
-
-	case CSIC_DEV:
-		if (index >= MAX_NUM_CSIC_DEV) {
-			pr_err("%s Invalid CSIC idx %d", __func__, index);
-			err = -EINVAL;
-			break;
-		}
-		g_server_dev.csic_device[index] = sd;
-		break;
-
-	case ISPIF_DEV:
-		if (index >= MAX_NUM_ISPIF_DEV) {
-			pr_err("%s Invalid ISPIF idx %d", __func__, index);
-			err = -EINVAL;
-			break;
-		}
-		cam_hw_idx = MSM_CAM_HW_ISPIF + index;
-		g_server_dev.ispif_device[index] = sd;
-		if (g_server_dev.irqr_device) {
-			g_server_dev.subdev_table[cam_hw_idx] = sd;
-			err = msm_cam_server_fill_sdev_irqnum(cam_hw_idx,
-				sd_info->irq_num);
-		}
-		break;
-
-	case VFE_DEV:
-		if (index >= MAX_NUM_VFE_DEV) {
-			pr_err("%s Invalid VFE idx %d", __func__, index);
-			err = -EINVAL;
-			break;
-		}
-		cam_hw_idx = MSM_CAM_HW_VFE0 + index;
-		g_server_dev.vfe_device[index] = sd;
-		if (g_server_dev.irqr_device) {
-			g_server_dev.subdev_table[cam_hw_idx] = sd;
-			err = msm_cam_server_fill_sdev_irqnum(cam_hw_idx,
-				sd_info->irq_num);
-		}
-		break;
-
-	case VPE_DEV:
-		if (index >= MAX_NUM_VPE_DEV) {
-			pr_err("%s Invalid VPE idx %d", __func__, index);
-			err = -EINVAL;
-			break;
-		}
-		g_server_dev.vpe_device[index] = sd;
-		break;
-
-	case AXI_DEV:
-		if (index >= MAX_NUM_AXI_DEV) {
-			pr_err("%s Invalid AXI idx %d", __func__, index);
-			err = -EINVAL;
-			break;
-		}
-		g_server_dev.axi_device[index] = sd;
-		break;
-
-	case GESTURE_DEV:
-		g_server_dev.gesture_device = sd;
-		break;
-
-	case IRQ_ROUTER_DEV:
-		g_server_dev.irqr_device = sd;
-
-	case CPP_DEV:
-		if (index >= MAX_NUM_CPP_DEV) {
-			pr_err("%s Invalid CPP idx %d", __func__, index);
-			err = -EINVAL;
-			break;
-		}
-		g_server_dev.cpp_device[index] = sd;
-		break;
-	case CCI_DEV:
-		g_server_dev.cci_device = sd;
-		if (g_server_dev.irqr_device) {
-			if (index >= MAX_NUM_CCI_DEV) {
-				pr_err("%s Invalid CCI idx %d", __func__,
-					index);
-				err = -EINVAL;
-				break;
-			}
-			cam_hw_idx = MSM_CAM_HW_CCI + index;
-			g_server_dev.subdev_table[cam_hw_idx] = sd;
-			err = msm_cam_server_fill_sdev_irqnum(MSM_CAM_HW_CCI,
-				sd_info->irq_num);
-		}
-		break;
-
-	case FLASH_DEV:
-		if (index >= MAX_NUM_FLASH_DEV) {
-			pr_err("%s Invalid flash idx %d", __func__, index);
-			err = -EINVAL;
-			break;
-		}
-		g_server_dev.flash_device[index] = sd;
-		break;
-
-	default:
-		break;
-	}
-
-	if (err < 0)
-		return err;
-
-	err = msm_cam_server_register_subdev(&g_server_dev.v4l2_dev, sd);
-	return err;
-}
-
-#ifdef CONFIG_MSM_IOMMU
-static int camera_register_domain(void)
-{
-	struct msm_iova_partition camera_fw_partition = {
-		.start = SZ_128K,
-		.size = SZ_2G - SZ_128K,
-	};
-	struct msm_iova_layout camera_fw_layout = {
-		.partitions = &camera_fw_partition,
-		.npartitions = 1,
-		.client_name = "camera_isp",
-		.domain_flags = 0,
-	};
-
-	return msm_register_domain(&camera_fw_layout);
-}
-#endif
-
-static int msm_setup_server_dev(struct platform_device *pdev)
-{
-	int rc = -ENODEV, i;
-
-	D("%s\n", __func__);
-	g_server_dev.server_pdev = pdev;
-	g_server_dev.v4l2_dev.dev = &pdev->dev;
-	g_server_dev.v4l2_dev.notify = msm_cam_server_subdev_notify;
-	rc = v4l2_device_register(g_server_dev.v4l2_dev.dev,
-			&g_server_dev.v4l2_dev);
-	if (rc < 0)
-		return -EINVAL;
-
-	g_server_dev.video_dev = video_device_alloc();
-	if (g_server_dev.video_dev == NULL) {
-		pr_err("%s: video_device_alloc failed\n", __func__);
-		return rc;
-	}
-
-	strlcpy(g_server_dev.video_dev->name, pdev->name,
-			sizeof(g_server_dev.video_dev->name));
-
-	g_server_dev.video_dev->v4l2_dev = &g_server_dev.v4l2_dev;
-	g_server_dev.video_dev->fops = &msm_fops_server;
-	g_server_dev.video_dev->ioctl_ops = &msm_ioctl_ops_server;
-	g_server_dev.video_dev->release   = video_device_release;
-	g_server_dev.video_dev->minor = 100;
-	g_server_dev.video_dev->vfl_type = VFL_TYPE_GRABBER;
-
-	video_set_drvdata(g_server_dev.video_dev, &g_server_dev);
-
-	strlcpy(g_server_dev.media_dev.model, QCAMERA_SERVER_NAME,
-		sizeof(g_server_dev.media_dev.model));
-	g_server_dev.media_dev.dev = &pdev->dev;
-	rc = media_device_register(&g_server_dev.media_dev);
-	g_server_dev.v4l2_dev.mdev = &g_server_dev.media_dev;
-	media_entity_init(&g_server_dev.video_dev->entity, 0, NULL, 0);
-	g_server_dev.video_dev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
-	g_server_dev.video_dev->entity.group_id = QCAMERA_VNODE_GROUP_ID;
-
-	rc = video_register_device(g_server_dev.video_dev,
-		VFL_TYPE_GRABBER, 100);
-
-	g_server_dev.video_dev->entity.name =
-		video_device_node_name(g_server_dev.video_dev);
-
-	mutex_init(&g_server_dev.server_lock);
-	mutex_init(&g_server_dev.server_queue_lock);
-	spin_lock_init(&g_server_dev.intr_table_lock);
-	memset(&g_server_dev.irq_lkup_table, 0,
-			sizeof(struct irqmgr_intr_lkup_table));
-	g_server_dev.camera_info.num_cameras = 0;
-	atomic_set(&g_server_dev.number_pcam_active, 0);
-	g_server_dev.server_evt_id = 0;
-
-	/*initialize fake video device and event queue*/
-
-	g_server_dev.server_command_queue.pvdev = g_server_dev.video_dev;
-	msm_setup_v4l2_event_queue(
-		&g_server_dev.server_command_queue.eventHandle,
-		g_server_dev.server_command_queue.pvdev);
-
-	for (i = 0; i < MAX_NUM_ACTIVE_CAMERA; i++) {
-		struct msm_cam_server_queue *queue;
-		queue = &g_server_dev.server_queue[i];
-		queue->queue_active = 0;
-		msm_queue_init(&queue->ctrl_q, "control");
-		msm_queue_init(&queue->eventData_q, "eventdata");
-		g_server_dev.pcam_active[i] = NULL;
-	}
-
-	for (i = 0; i < INTF_MAX; i++) {
-		g_server_dev.interface_map_table[i].interface = 0x01 << i;
-		g_server_dev.interface_map_table[i].mctl_handle = 0;
-	}
-#ifdef CONFIG_MSM_IOMMU
-	g_server_dev.domain_num = camera_register_domain();
-	if (g_server_dev.domain_num < 0) {
-		pr_err("%s: could not register domain\n", __func__);
-		rc = -ENODEV;
-		return rc;
-	}
-	g_server_dev.domain =
-		msm_get_iommu_domain(g_server_dev.domain_num);
-	if (!g_server_dev.domain) {
-		pr_err("%s: cannot find domain\n", __func__);
-		rc = -ENODEV;
-		return rc;
-	}
-#endif
-	return rc;
-}
-
-static long msm_server_send_v4l2_evt(void *evt)
-{
-	struct v4l2_event *v4l2_ev = (struct v4l2_event *)evt;
-	int rc = 0;
-
-	if (NULL == evt) {
-		pr_err("%s: evt is NULL\n", __func__);
-		return -EINVAL;
-	}
-
-	D("%s: evt type 0x%x\n", __func__, v4l2_ev->type);
-	if ((v4l2_ev->type >= MSM_GES_APP_EVT_MIN) &&
-		(v4l2_ev->type < MSM_GES_APP_EVT_MAX)) {
-		msm_cam_server_subdev_notify(g_server_dev.gesture_device,
-			NOTIFY_GESTURE_EVT, v4l2_ev);
-	} else {
-		pr_err("%s: Invalid evt %d\n", __func__, v4l2_ev->type);
-		rc = -EINVAL;
-	}
-	D("%s: end\n", __func__);
-
-	return rc;
-}
-
-int msm_cam_server_open_mctl_session(struct msm_cam_v4l2_device *pcam,
-	int *p_active)
-{
-	int rc = 0;
-	int i = 0;
-	struct msm_cam_media_controller *pmctl = NULL;
-	*p_active = 0;
-
-	for (i = 0; i < MAX_NUM_ACTIVE_CAMERA; i++) {
-		if (NULL != g_server_dev.pcam_active[i]) {
-			pr_info("%s: Active camera present return", __func__);
-			return 0;
-		}
-	}
-
-	rc = msm_cam_server_open_session(&g_server_dev, pcam);
-	if (rc < 0) {
-		pr_err("%s: cam_server_open_session failed %d\n",
-		__func__, rc);
-		return rc;
-	}
-
-	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
-	if (!pmctl || !pmctl->mctl_open) {
-		D("%s: media contoller is not inited\n",
-			 __func__);
-		rc = -ENODEV;
-		return rc;
-	}
-
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-		pmctl->domain = msm_cam_server_get_domain();
-		pmctl->domain_num = msm_cam_server_get_domain_num();
-#endif
-
-	D("%s: call mctl_open\n", __func__);
-	rc = pmctl->mctl_open(pmctl, MSM_APPS_ID_V4L2);
-
-	if (rc < 0) {
-		pr_err("%s: HW open failed rc = 0x%x\n",  __func__, rc);
-		return rc;
-	}
-	pmctl->pcam_ptr = pcam;
-	*p_active = 1;
-	return rc;
-}
-
-int msm_cam_server_close_mctl_session(struct msm_cam_v4l2_device *pcam)
-{
-	int rc = 0;
-	struct msm_cam_media_controller *pmctl = NULL;
-
-	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
-	if (!pmctl) {
-		D("%s: invalid handle\n", __func__);
-		return -ENODEV;
-	}
-
-	if (pmctl->mctl_release)
-		pmctl->mctl_release(pmctl);
-
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	kref_put(&pmctl->refcount, msm_release_ion_client);
-#endif
-
-	rc = msm_cam_server_close_session(&g_server_dev, pcam);
-	if (rc < 0)
-		pr_err("msm_cam_server_close_session fails %d\n", rc);
-
-	return rc;
-}
-
-int msm_server_open_client(int *p_qidx)
-{
-	int rc = 0;
-	int server_q_idx = 0;
-	struct msm_cam_server_queue *queue = NULL;
-
-	mutex_lock(&g_server_dev.server_lock);
-	server_q_idx = msm_find_free_queue();
-	if (server_q_idx < 0) {
-		mutex_unlock(&g_server_dev.server_lock);
-		return server_q_idx;
-	}
-
-	*p_qidx = server_q_idx;
-	queue = &g_server_dev.server_queue[server_q_idx];
-	queue->ctrl_data = kzalloc(sizeof(uint8_t) *
-		MAX_SERVER_PAYLOAD_LENGTH, GFP_KERNEL);
-	if (!queue->ctrl_data) {
-		pr_err("%s: Could not find memory\n", __func__);
-		return -ENOMEM;
-	}
-	msm_queue_init(&queue->ctrl_q, "control");
-	msm_queue_init(&queue->eventData_q, "eventdata");
-	queue->queue_active = 1;
-	mutex_unlock(&g_server_dev.server_lock);
-	return rc;
-}
-
-int msm_server_send_ctrl(struct msm_ctrl_cmd *out,
-	int ctrl_id)
-{
-	int rc = 0;
-	void *value;
-	struct msm_queue_cmd *rcmd;
-	struct msm_queue_cmd *event_qcmd;
-	struct msm_ctrl_cmd *ctrlcmd;
-	struct msm_cam_server_dev *server_dev = &g_server_dev;
-	struct msm_device_queue *queue =
-		&server_dev->server_queue[out->queue_idx].ctrl_q;
-
-	struct v4l2_event v4l2_evt;
-	struct msm_isp_event_ctrl *isp_event;
-	void *ctrlcmd_data;
-
-	event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
-	if (!event_qcmd) {
-		pr_err("%s Insufficient memory. return", __func__);
-		rc = -ENOMEM;
-		goto event_qcmd_alloc_fail;
-	}
-
-	isp_event = kzalloc(sizeof(struct msm_isp_event_ctrl), GFP_KERNEL);
-	if (!isp_event) {
-		pr_err("%s Insufficient memory. return", __func__);
-		rc = -ENOMEM;
-		goto isp_event_alloc_fail;
-	}
-
-	D("%s\n", __func__);
-	mutex_lock(&server_dev->server_queue_lock);
-	if (++server_dev->server_evt_id == 0)
-		server_dev->server_evt_id++;
-
-	D("%s qid %d evtid %d\n", __func__, out->queue_idx,
-		server_dev->server_evt_id);
-	server_dev->server_queue[out->queue_idx].evt_id =
-		server_dev->server_evt_id;
-	v4l2_evt.type = V4L2_EVENT_PRIVATE_START + ctrl_id;
-	v4l2_evt.id = 0;
-	v4l2_evt.u.data[0] = out->queue_idx;
-	/* setup event object to transfer the command; */
-	isp_event->resptype = MSM_CAM_RESP_V4L2;
-	isp_event->isp_data.ctrl = *out;
-	isp_event->isp_data.ctrl.evt_id = server_dev->server_evt_id;
-
-	if (out->value != NULL && out->length != 0) {
-		ctrlcmd_data = kzalloc(out->length, GFP_KERNEL);
-		if (!ctrlcmd_data) {
-			rc = -ENOMEM;
-			goto ctrlcmd_alloc_fail;
-		}
-		memcpy(ctrlcmd_data, out->value, out->length);
-		isp_event->isp_data.ctrl.value = ctrlcmd_data;
-	}
-
-	atomic_set(&event_qcmd->on_heap, 1);
-	event_qcmd->command = isp_event;
-
-	msm_enqueue(&server_dev->server_queue[out->queue_idx].eventData_q,
-				&event_qcmd->list_eventdata);
-
-	/* now send command to config thread in userspace,
-	 * and wait for results */
-	v4l2_event_queue(server_dev->server_command_queue.pvdev,
-					  &v4l2_evt);
-	D("%s v4l2_event_queue: type = 0x%x\n", __func__, v4l2_evt.type);
-	mutex_unlock(&server_dev->server_queue_lock);
-
-	/* wait for config return status */
-	D("Waiting for config status\n");
-	rc = wait_event_interruptible_timeout(queue->wait,
-		!list_empty_careful(&queue->list),
-		msecs_to_jiffies(out->timeout_ms));
-	D("Waiting is over for config status\n");
-	if (list_empty_careful(&queue->list)) {
-		if (!rc)
-			rc = -ETIMEDOUT;
-		if (rc < 0) {
-			if (++server_dev->server_evt_id == 0)
-				server_dev->server_evt_id++;
-			pr_err("%s: wait_event error %d\n", __func__, rc);
-			return rc;
-		}
-	}
-
-	rcmd = msm_dequeue(queue, list_control);
-	BUG_ON(!rcmd);
-	D("%s Finished servicing ioctl\n", __func__);
-
-	ctrlcmd = (struct msm_ctrl_cmd *)(rcmd->command);
-	value = out->value;
-	if (ctrlcmd->length > 0 && value != NULL &&
-		ctrlcmd->length <= out->length)
-		memcpy(value, ctrlcmd->value, ctrlcmd->length);
-
-	memcpy(out, ctrlcmd, sizeof(struct msm_ctrl_cmd));
-	out->value = value;
-
-	kfree(ctrlcmd);
-	free_qcmd(rcmd);
-	D("%s: rc %d\n", __func__, rc);
-	/* rc is the time elapsed. */
-	if (rc >= 0) {
-		/* TODO: Refactor msm_ctrl_cmd::status field */
-		if (out->status == 0)
-			rc = -1;
-		else if (out->status == 1 || out->status == 4)
-			rc = 0;
-		else
-			rc = -EINVAL;
-	}
-	return rc;
-
-ctrlcmd_alloc_fail:
-	kfree(isp_event);
-isp_event_alloc_fail:
-	kfree(event_qcmd);
-event_qcmd_alloc_fail:
-	return rc;
-}
-
-int msm_server_close_client(int idx)
-{
-	int rc = 0;
-	struct msm_cam_server_queue *queue = NULL;
-	mutex_lock(&g_server_dev.server_lock);
-	queue = &g_server_dev.server_queue[idx];
-	queue->queue_active = 0;
-	kfree(queue->ctrl_data);
-	queue->ctrl_data = NULL;
-	msm_queue_drain(&queue->ctrl_q, list_control);
-	msm_drain_eventq(&queue->eventData_q);
-	mutex_unlock(&g_server_dev.server_lock);
-	return rc;
-}
-
-static unsigned int msm_poll_config(struct file *fp,
-					struct poll_table_struct *wait)
-{
-	int rc = 0;
-	struct msm_cam_config_dev *config = fp->private_data;
-	if (config == NULL)
-		return -EINVAL;
-
-	D("%s\n", __func__);
-
-	poll_wait(fp,
-	&config->config_stat_event_queue.eventHandle.wait, wait);

-	if (v4l2_event_pending(&config->config_stat_event_queue.eventHandle))
-		rc |= POLLPRI;
-	return rc;
-}
-
-static int msm_mmap_config(struct file *fp, struct vm_area_struct *vma)
-{
-	struct msm_cam_config_dev *config_cam = fp->private_data;
-	int rc = 0;
-	int phyaddr;
-	int retval;
-	unsigned long size;
-
-	D("%s: phy_addr=0x%x", __func__, config_cam->mem_map.cookie);
-	phyaddr = (int)config_cam->mem_map.cookie;
-	if (!phyaddr) {
-		pr_err("%s: no physical memory to map", __func__);
-		return -EFAULT;
-	}
-	memset(&config_cam->mem_map, 0,
-		sizeof(struct msm_mem_map_info));
-	size = vma->vm_end - vma->vm_start;
-	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-	retval = remap_pfn_range(vma, vma->vm_start,
-					phyaddr >> PAGE_SHIFT,
-					size, vma->vm_page_prot);
-	if (retval) {
-		pr_err("%s: remap failed, rc = %d",
-					__func__, retval);
-		rc = -ENOMEM;
-		goto end;
-	}
-	D("%s: phy_addr=0x%x: %08lx-%08lx, pgoff %08lx\n",
-			__func__, (uint32_t)phyaddr,
-			vma->vm_start, vma->vm_end, vma->vm_pgoff);
-end:
-	return rc;
-}
-
-static int msm_open_config(struct inode *inode, struct file *fp)
-{
-	int rc;
-	struct msm_cam_config_dev *config_cam = container_of(inode->i_cdev,
-		struct msm_cam_config_dev, config_cdev);
-
-	D("%s: open %s\n", __func__, fp->f_path.dentry->d_name.name);
-
-	rc = nonseekable_open(inode, fp);
-	if (rc < 0) {
-		pr_err("%s: nonseekable_open error %d\n", __func__, rc);
-		return rc;
-	}
-	config_cam->use_count++;
-
-	/* assume there is only one active camera possible*/
-	config_cam->p_mctl = msm_cam_server_get_mctl(
-		g_server_dev.pcam_active[config_cam->dev_num]->mctl_handle);
-	if (!config_cam->p_mctl) {
-		pr_err("%s: cannot find mctl\n", __func__);
-		return -ENODEV;
-	}
-
-	INIT_HLIST_HEAD(&config_cam->p_mctl->stats_info.pmem_stats_list);
-	spin_lock_init(&config_cam->p_mctl->stats_info.pmem_stats_spinlock);
-
-	config_cam->p_mctl->config_device = config_cam;
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	kref_get(&config_cam->p_mctl->refcount);
-#endif
-	fp->private_data = config_cam;
-	return rc;
-}
-
-static int msm_set_mctl_subdev(struct msm_cam_media_controller *pmctl,
-	struct msm_mctl_set_sdev_data *set_data)
-{
-	int rc = 0;
-	struct v4l2_subdev *temp_sdev = NULL;
-	switch (set_data->sdev_type) {
-	case CSIPHY_DEV:
-		pmctl->csiphy_sdev = msm_cam_find_subdev_node
-			(&g_server_dev.csiphy_device[0], set_data->revision);
-		temp_sdev = pmctl->csiphy_sdev;
-		break;
-	case CSID_DEV:
-		pmctl->csid_sdev = msm_cam_find_subdev_node
-			(&g_server_dev.csid_device[0], set_data->revision);
-		temp_sdev = pmctl->csid_sdev;
-		break;
-	case CSIC_DEV:
-		pmctl->csic_sdev = msm_cam_find_subdev_node
-			(&g_server_dev.csic_device[0], set_data->revision);
-		temp_sdev = pmctl->csic_sdev;
-		break;
-	case ISPIF_DEV:
-		pmctl->ispif_sdev = msm_cam_find_subdev_node
-			(&g_server_dev.ispif_device[0], set_data->revision);
-		temp_sdev = pmctl->ispif_sdev;
-		break;
-	case VFE_DEV:
-		pmctl->vfe_sdev = msm_cam_find_subdev_node
-			(&g_server_dev.vfe_device[0], set_data->revision);
-		temp_sdev = pmctl->vfe_sdev;
-		break;
-	case AXI_DEV:
-		pmctl->axi_sdev = msm_cam_find_subdev_node
-			(&g_server_dev.axi_device[0], set_data->revision);
-		temp_sdev = pmctl->axi_sdev;
-		break;
-	case VPE_DEV:
-		pmctl->vpe_sdev = msm_cam_find_subdev_node
-			(&g_server_dev.vpe_device[0], set_data->revision);
-		temp_sdev = pmctl->vpe_sdev;
-		break;
-	default:
-		rc = -EINVAL;
-		break;
-	}
-	if (temp_sdev != NULL)
-		v4l2_set_subdev_hostdata(temp_sdev, pmctl);
-	else
-		pr_err("%s: Could not find subdev\n", __func__);
-	return rc;
-}
-
-static int msm_unset_mctl_subdev(struct msm_cam_media_controller *pmctl,
-	struct msm_mctl_set_sdev_data *set_data)
-{
-	int rc = 0;
-	switch (set_data->sdev_type) {
-	case CSIPHY_DEV:
-		pmctl->csiphy_sdev = NULL;
-		break;
-	case CSID_DEV:
-		pmctl->csid_sdev = NULL;
-		break;
-	case CSIC_DEV:
-		pmctl->csic_sdev = NULL;
-		break;
-	case ISPIF_DEV:
-		pmctl->ispif_sdev = NULL;
-		break;
-	case VFE_DEV:
-		pmctl->vfe_sdev = NULL;
-		break;
-	case AXI_DEV:
-		pmctl->axi_sdev = NULL;
-		break;
-	case VPE_DEV:
-		pmctl->vpe_sdev = NULL;
-		break;
-	default:
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
-
-static long msm_ioctl_config(struct file *fp, unsigned int cmd,
-	unsigned long arg)
-{
-
-	int rc = 0;
-	struct v4l2_event ev;
-	struct msm_cam_config_dev *config_cam = fp->private_data;
-	struct v4l2_event_subscription temp_sub;
-
-	D("%s: cmd %d\n", __func__, _IOC_NR(cmd));
-	ev.id = 0;

-
-	switch (cmd) {
-	/* memory management shall be handeld here*/
-	case MSM_CAM_IOCTL_REGISTER_PMEM:
-		return msm_register_pmem(
-			&config_cam->p_mctl->stats_info.pmem_stats_list,
-			(void __user *)arg, config_cam->p_mctl->client,
-			config_cam->p_mctl->domain_num);
-		break;
-
-	case MSM_CAM_IOCTL_UNREGISTER_PMEM:
-		return msm_pmem_table_del(
-			&config_cam->p_mctl->stats_info.pmem_stats_list,
-			(void __user *)arg, config_cam->p_mctl->client,
-			config_cam->p_mctl->domain_num);
-		break;
-
-	case VIDIOC_SUBSCRIBE_EVENT:
-		if (copy_from_user(&temp_sub,
-			(void __user *)arg,
-			sizeof(struct v4l2_event_subscription))) {
-				pr_err("%s copy_from_user failed for cmd %d ",
-					__func__, cmd);
-				rc = -EINVAL;
-				return rc;
-		}
-		rc = msm_server_v4l2_subscribe_event
-			(&config_cam->config_stat_event_queue.eventHandle,
-				 &temp_sub);
-		if (rc < 0) {
-			pr_err("%s: cam_v4l2_subscribe_event failed rc=%d\n",
-				__func__, rc);
-			return rc;
-		}
-		break;
-
-	case VIDIOC_UNSUBSCRIBE_EVENT:
-		if (copy_from_user(&temp_sub, (void __user *)arg,
-			  sizeof(struct v4l2_event_subscription))) {
-			rc = -EINVAL;
-			return rc;
-		}
-		rc = msm_server_v4l2_unsubscribe_event
-			(&config_cam->config_stat_event_queue.eventHandle,
-			 &temp_sub);
-		if (rc < 0) {
-			pr_err("%s: cam_v4l2_unsubscribe_event failed rc=%d\n",
-				__func__, rc);
-			return rc;
-		}
-		break;
-
-	case VIDIOC_DQEVENT: {
-		void __user *u_msg_value = NULL, *user_ptr = NULL;
-		struct msm_isp_event_ctrl u_isp_event;
-		struct msm_isp_event_ctrl *k_isp_event;
-
-		/* First, copy the v4l2 event structure from userspace */
-		D("%s: VIDIOC_DQEVENT\n", __func__);
-		if (copy_from_user(&ev, (void __user *)arg,
-				sizeof(struct v4l2_event)))
-			break;
-		/* Next, get the pointer to event_ctrl structure
-		 * embedded inside the v4l2_event.u.data array. */
-		user_ptr = (void __user *)(*((uint32_t *)ev.u.data));
-
-		/* Next, copy the userspace event ctrl structure */
-		if (copy_from_user((void *)&u_isp_event, user_ptr,
-				   sizeof(struct msm_isp_event_ctrl))) {
-			rc = -EFAULT;
-			break;
-		}
-		/* Save the pointer of the user allocated command buffer*/
-		u_msg_value = u_isp_event.isp_data.isp_msg.data;
-
-		/* Dequeue the event queued into the v4l2 queue*/
-		rc = v4l2_event_dequeue(
-			&config_cam->config_stat_event_queue.eventHandle,
-			&ev, fp->f_flags & O_NONBLOCK);
-		if (rc < 0) {
-			pr_err("no pending events?");
-			rc = -EFAULT;
-			break;
-		}
-		/* Use k_isp_event to point to the event_ctrl structure
-		 * embedded inside v4l2_event.u.data */
-		k_isp_event = (struct msm_isp_event_ctrl *)
-				(*((uint32_t *)ev.u.data));
-		/* Copy the event structure into user struct. */
-		u_isp_event = *k_isp_event;
-		if (ev.type != (V4L2_EVENT_PRIVATE_START +
-				MSM_CAM_RESP_DIV_FRAME_EVT_MSG) &&
-				ev.type != (V4L2_EVENT_PRIVATE_START +
-				MSM_CAM_RESP_MCTL_PP_EVENT)) {
-
-			/* Restore the saved pointer of the
-			 * user allocated command buffer. */
-			u_isp_event.isp_data.isp_msg.data = u_msg_value;
-
-			if (ev.type == (V4L2_EVENT_PRIVATE_START +
-					MSM_CAM_RESP_STAT_EVT_MSG)) {
-				if (k_isp_event->isp_data.isp_msg.len > 0) {
-					void *k_msg_value =
-					k_isp_event->isp_data.isp_msg.data;
-					if (copy_to_user(u_msg_value,
-							k_msg_value,
-					 k_isp_event->isp_data.isp_msg.len)) {
-						rc = -EINVAL;
-						break;
-					}
-					kfree(k_msg_value);
-					k_msg_value = NULL;
-				}
-			}
-		}
-		/* Copy the event ctrl structure back
-		 * into user's structure. */
-		if (copy_to_user(user_ptr,
-				(void *)&u_isp_event, sizeof(
-				struct msm_isp_event_ctrl))) {
-			rc = -EINVAL;
-			break;
-		}
-		kfree(k_isp_event);
-		k_isp_event = NULL;
-
-		/* Copy the v4l2_event structure back to the user*/
-		if (copy_to_user((void __user *)arg, &ev,
-				sizeof(struct v4l2_event))) {
-			rc = -EINVAL;
-			break;
-		}
-		}
-
-		break;
-
-	case MSM_CAM_IOCTL_V4L2_EVT_NOTIFY:
-		rc = msm_v4l2_evt_notify(config_cam->p_mctl, cmd, arg);
-		break;
-
-	case MSM_CAM_IOCTL_SET_MEM_MAP_INFO:
-		if (copy_from_user(&config_cam->mem_map, (void __user *)arg,
-				sizeof(struct msm_mem_map_info)))
-			rc = -EINVAL;
-		break;
-
-	case MSM_CAM_IOCTL_SET_MCTL_SDEV:{
-		struct msm_mctl_set_sdev_data set_data;
-		if (copy_from_user(&set_data, (void __user *)arg,
-			sizeof(struct msm_mctl_set_sdev_data))) {
-			ERR_COPY_FROM_USER();
-			rc = -EINVAL;
-			break;
-		}
-		rc = msm_set_mctl_subdev(config_cam->p_mctl, &set_data);
-		break;
-	}
-
-	case MSM_CAM_IOCTL_UNSET_MCTL_SDEV:{
-		struct msm_mctl_set_sdev_data set_data;
-		if (copy_from_user(&set_data, (void __user *)arg,
-			sizeof(struct msm_mctl_set_sdev_data))) {
-			ERR_COPY_FROM_USER();
-			rc = -EINVAL;
-			break;
-		}
-		rc = msm_unset_mctl_subdev(config_cam->p_mctl, &set_data);
-		break;
-	}
-
-	default:{
-		/* For the rest of config command, forward to media controller*/
-		struct msm_cam_media_controller *p_mctl = config_cam->p_mctl;
-		if (p_mctl && p_mctl->mctl_cmd) {
-			rc = config_cam->p_mctl->mctl_cmd(p_mctl, cmd, arg);
-		} else {
-			rc = -EINVAL;
-			pr_err("%s: media controller is null\n", __func__);
-		}
-
-		break;
-	} /* end of default*/
-	} /* end of switch*/
-	return rc;
-}
-
-static int msm_close_config(struct inode *node, struct file *f)
-{
-	struct v4l2_event ev;
-	struct v4l2_event_subscription sub;
-	struct msm_isp_event_ctrl *isp_event;
-	struct msm_cam_config_dev *config_cam = f->private_data;
-
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	D("%s Decrementing ref count of config node ", __func__);
-	kref_put(&config_cam->p_mctl->refcount, msm_release_ion_client);
-#endif
-	sub.type = V4L2_EVENT_ALL;
-	msm_server_v4l2_unsubscribe_event(
-		&config_cam->config_stat_event_queue.eventHandle,
-		&sub);
-	while (v4l2_event_pending(
-		&config_cam->config_stat_event_queue.eventHandle)) {
-		v4l2_event_dequeue(
-			&config_cam->config_stat_event_queue.eventHandle,
-			&ev, O_NONBLOCK);
-		isp_event = (struct msm_isp_event_ctrl *)
-			(*((uint32_t *)ev.u.data));
-		if (isp_event) {
-			if (isp_event->isp_data.isp_msg.len != 0 &&
-				isp_event->isp_data.isp_msg.data != NULL)
-				kfree(isp_event->isp_data.isp_msg.data);
-			kfree(isp_event);
-		}
-	}
-	return 0;
-}
-
-static const struct file_operations msm_fops_config = {
-	.owner = THIS_MODULE,
-	.open  = msm_open_config,
-	.poll  = msm_poll_config,
-	.unlocked_ioctl = msm_ioctl_config,
-	.mmap	= msm_mmap_config,
-	.release = msm_close_config,
-};
-
-static int msm_setup_config_dev(int node, char *device_name)
-{
-	int rc = -ENODEV;
-	struct device *device_config;
-	int dev_num = node;
-	dev_t devno;
-	struct msm_cam_config_dev *config_cam;
-
-	config_cam = kzalloc(sizeof(*config_cam), GFP_KERNEL);
-	if (!config_cam) {
-		pr_err("%s: could not allocate memory for config_device\n",
-			__func__);
-		return -ENOMEM;
-	}
-
-	D("%s\n", __func__);
-
-	devno = MKDEV(MAJOR(msm_devno), dev_num+1);
-	device_config = device_create(msm_class, NULL, devno, NULL, "%s%d",
-		device_name, dev_num);
-
-	if (IS_ERR(device_config)) {
-		rc = PTR_ERR(device_config);
-		pr_err("%s: error creating device: %d\n", __func__, rc);
-		goto config_setup_fail;
-	}
-
-	cdev_init(&config_cam->config_cdev, &msm_fops_config);
-	config_cam->config_cdev.owner = THIS_MODULE;
-
-	rc = cdev_add(&config_cam->config_cdev, devno, 1);
-	if (rc < 0) {
-		pr_err("%s: error adding cdev: %d\n", __func__, rc);
-		device_destroy(msm_class, devno);
-		goto config_setup_fail;
-	}
-	g_server_dev.config_info.config_dev_name[dev_num] =
-		dev_name(device_config);
-	D("%s Connected config device %s\n", __func__,
-		g_server_dev.config_info.config_dev_name[dev_num]);
-	g_server_dev.config_info.config_dev_id[dev_num] =
-		dev_num;
-
-	config_cam->config_stat_event_queue.pvdev = video_device_alloc();
-	if (config_cam->config_stat_event_queue.pvdev == NULL) {
-		pr_err("%s: video_device_alloc failed\n", __func__);
-		goto config_setup_fail;
-	}
-
-	/* v4l2_fh support */
-	spin_lock_init(&config_cam->config_stat_event_queue.pvdev->fh_lock);
-	INIT_LIST_HEAD(&config_cam->config_stat_event_queue.pvdev->fh_list);
-	msm_setup_v4l2_event_queue(
-		&config_cam->config_stat_event_queue.eventHandle,
-		config_cam->config_stat_event_queue.pvdev);
-	config_cam->dev_num = dev_num;
-
-	return rc;
-
-config_setup_fail:
-	kfree(config_cam);
-	return rc;
-}
-
-static int __devinit msm_camera_probe(struct platform_device *pdev)
-{
-	int rc = 0, i;
-	memset(&g_server_dev, 0, sizeof(struct msm_cam_server_dev));
-	/*for now just create two config nodes
-	  put logic here later to know how many configs to create*/
-	g_server_dev.config_info.num_config_nodes = 2;
-
-	if (!msm_class) {
-		rc = alloc_chrdev_region(&msm_devno, 0,
-		g_server_dev.config_info.num_config_nodes+1, "msm_camera");
-		if (rc < 0) {
-			pr_err("%s: failed to allocate chrdev: %d\n", __func__,
-			rc);
-			return rc;
-		}
-
-		msm_class = class_create(THIS_MODULE, "msm_camera");
-		if (IS_ERR(msm_class)) {
-			rc = PTR_ERR(msm_class);
-			pr_err("%s: create device class failed: %d\n",
-			__func__, rc);
-			return rc;
-		}
-	}
-
-	D("creating server and config nodes\n");
-	rc = msm_setup_server_dev(pdev);
-	if (rc < 0) {
-		pr_err("%s: failed to create server dev: %d\n", __func__,
-		rc);
-		return rc;
-	}
-
-	for (i = 0; i < g_server_dev.config_info.num_config_nodes; i++) {
-		rc = msm_setup_config_dev(i, "config");
-		if (rc < 0) {
-			pr_err("%s:failed to create config dev: %d\n",
-			 __func__, rc);
-			return rc;
-		}
-	}
-
-	return rc;
-}
-
-static int __exit msm_camera_exit(struct platform_device *pdev)
-{
-	return 0;
-}
-
-static const struct of_device_id msm_cam_server_dt_match[] = {
-	{.compatible = "qcom,cam_server"},
-}
-
-MODULE_DEVICE_TABLE(of, msm_cam_server_dt_match);
-
-static struct platform_driver msm_cam_server_driver = {
-	.probe = msm_camera_probe,
-	.remove = msm_camera_exit,
-	.driver = {
-		.name = "msm_cam_server",
-		.owner = THIS_MODULE,
-		.of_match_table = msm_cam_server_dt_match,
-	},
-};
-
-static int __init msm_cam_server_init(void)
-{
-	return platform_driver_register(&msm_cam_server_driver);
-}
-
-static void __exit msm_cam_server_exit(void)
-{
-	platform_driver_unregister(&msm_cam_server_driver);
-}
-
-module_init(msm_cam_server_init);
-module_exit(msm_cam_server_exit);
-MODULE_DESCRIPTION("msm camera server");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/server/msm_cam_server.h b/drivers/media/video/msm/server/msm_cam_server.h
deleted file mode 100644
index 387c254..0000000
--- a/drivers/media/video/msm/server/msm_cam_server.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 _MSM_CAM_SERVER_H
-#define _MSM_CAM_SERVER_H
-
-#include <linux/proc_fs.h>
-#include <linux/ioctl.h>
-#include <mach/camera.h>
-#include "../msm.h"
-
-uint32_t msm_cam_server_get_mctl_handle(void);
-struct iommu_domain *msm_cam_server_get_domain(void);
-int msm_cam_server_get_domain_num(void);
-struct msm_cam_media_controller *msm_cam_server_get_mctl(uint32_t handle);
-void msm_cam_server_free_mctl(uint32_t handle);
-/* Server session control APIs */
-int msm_server_begin_session(struct msm_cam_v4l2_device *pcam,
-	int server_q_idx);
-int msm_server_end_session(struct msm_cam_v4l2_device *pcam);
-int msm_send_open_server(struct msm_cam_v4l2_device *pcam);
-int msm_send_close_server(struct msm_cam_v4l2_device *pcam);
-int msm_server_update_sensor_info(struct msm_cam_v4l2_device *pcam,
-	struct msm_camera_sensor_info *sdata);
-/* Server camera control APIs */
-int msm_server_streamon(struct msm_cam_v4l2_device *pcam, int idx);
-int msm_server_streamoff(struct msm_cam_v4l2_device *pcam, int idx);
-int msm_server_get_usecount(void);
-int32_t msm_find_free_queue(void);
-int msm_server_proc_ctrl_cmd(struct msm_cam_v4l2_device *pcam,
-	struct msm_camera_v4l2_ioctl_t *ioctl_ptr, int is_set_cmd);
-int msm_server_private_general(struct msm_cam_v4l2_device *pcam,
-	struct msm_camera_v4l2_ioctl_t *ioctl_ptr);
-int msm_server_s_ctrl(struct msm_cam_v4l2_device *pcam,
-	struct v4l2_control *ctrl);
-int msm_server_g_ctrl(struct msm_cam_v4l2_device *pcam,
-	struct v4l2_control *ctrl);
-int msm_server_q_ctrl(struct msm_cam_v4l2_device *pcam,
-	struct v4l2_queryctrl *queryctrl);
-int msm_server_set_fmt(struct msm_cam_v4l2_device *pcam, int idx,
-	struct v4l2_format *pfmt);
-int msm_server_set_fmt_mplane(struct msm_cam_v4l2_device *pcam, int idx,
-	struct v4l2_format *pfmt);
-int msm_server_get_fmt(struct msm_cam_v4l2_device *pcam,
-	int idx, struct v4l2_format *pfmt);
-int msm_server_get_fmt_mplane(struct msm_cam_v4l2_device *pcam,
-	int idx, struct v4l2_format *pfmt);
-int msm_server_try_fmt(struct msm_cam_v4l2_device *pcam,
-	struct v4l2_format *pfmt);
-int msm_server_try_fmt_mplane(struct msm_cam_v4l2_device *pcam,
-	struct v4l2_format *pfmt);
-int msm_server_v4l2_subscribe_event(struct v4l2_fh *fh,
-	struct v4l2_event_subscription *sub);
-int msm_server_v4l2_unsubscribe_event(struct v4l2_fh *fh,
-	struct v4l2_event_subscription *sub);
-int msm_server_get_crop(struct msm_cam_v4l2_device *pcam,
-	int idx, struct v4l2_crop *crop);
-int msm_cam_server_request_irq(void *arg);
-int msm_cam_server_update_irqmap(
-	struct msm_cam_server_irqmap_entry *entry);
-int msm_cam_server_config_interface_map(u32 extendedmode,
-	uint32_t mctl_handle, int vnode_id, int is_bayer_sensor);
-#endif /* _MSM_CAM_SERVER_H */
diff --git a/drivers/media/video/msm/sn12m0pz.c b/drivers/media/video/msm/sn12m0pz.c
deleted file mode 100644
index c39e97f..0000000
--- a/drivers/media/video/msm/sn12m0pz.c
+++ /dev/null
@@ -1,1851 +0,0 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. 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/delay.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <media/msm_camera.h>
-#include <mach/gpio.h>
-#include <mach/camera.h>
-#include <linux/slab.h>
-#include "sn12m0pz.h"
-
-
-#define	Q8					0x00000100
-#define	REG_GROUPED_PARAMETER_HOLD		0x0104
-#define	GROUPED_PARAMETER_HOLD_OFF		0x00
-#define	GROUPED_PARAMETER_HOLD			0x01
-#define	REG_MODE_SELECT				0x0100
-#define	MODE_SELECT_STANDBY_MODE		0x00
-#define	MODE_SELECT_STREAM			0x01
-
-/* Integration Time */
-#define	REG_COARSE_INTEGRATION_TIME_MSB		0x0202
-#define	REG_COARSE_INTEGRATION_TIME_LSB		0x0203
-
-/* Gain */
-#define	REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB	0x0204
-#define	REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB	0x0205
-
-/* PLL Register Defines */
-#define	REG_PLL_MULTIPLIER			0x0307
-#define	REG_0x302B				0x302B
-
-/* MIPI Enable Settings */
-#define	REG_0x30E5				0x30E5
-#define	REG_0x3300				0x3300
-
-/* Global Setting */
-#define	REG_IMAGE_ORIENTATION			0x0101
-
-#define	REG_0x300A				0x300A
-#define	REG_0x3014				0x3014
-#define	REG_0x3015				0x3015
-#define	REG_0x3017				0x3017
-#define	REG_0x301C				0x301C
-#define	REG_0x3031				0x3031
-#define	REG_0x3040				0x3040
-#define	REG_0x3041				0x3041
-#define	REG_0x3051				0x3051
-#define	REG_0x3053				0x3053
-#define	REG_0x3055				0x3055
-#define	REG_0x3057				0x3057
-#define	REG_0x3060				0x3060
-#define	REG_0x3065				0x3065
-#define	REG_0x30AA				0x30AA
-#define	REG_0x30AB				0x30AB
-#define	REG_0x30B0				0x30B0
-#define	REG_0x30B2				0x30B2
-#define	REG_0x30D3				0x30D3
-
-#define	REG_0x3106				0x3106
-#define	REG_0x3108				0x3108
-#define	REG_0x310A				0x310A
-#define	REG_0x310C				0x310C
-#define	REG_0x310E				0x310E
-#define	REG_0x3126				0x3126
-#define	REG_0x312E				0x312E
-#define	REG_0x313C				0x313C
-#define	REG_0x313E				0x313E
-#define	REG_0x3140				0x3140
-#define	REG_0x3142				0x3142
-#define	REG_0x3144				0x3144
-#define	REG_0x3148				0x3148
-#define	REG_0x314A				0x314A
-#define	REG_0x3166				0x3166
-#define	REG_0x3168				0x3168
-#define	REG_0x316F				0x316F
-#define	REG_0x3171				0x3171
-#define	REG_0x3173				0x3173
-#define	REG_0x3175				0x3175
-#define	REG_0x3177				0x3177
-#define	REG_0x3179				0x3179
-#define	REG_0x317B				0x317B
-#define	REG_0x317D				0x317D
-#define	REG_0x317F			0x317F
-#define	REG_0x3181			0x3181
-#define	REG_0x3184			0x3184
-#define	REG_0x3185			0x3185
-#define	REG_0x3187			0x3187
-
-#define	REG_0x31A4			0x31A4
-#define	REG_0x31A6			0x31A6
-#define	REG_0x31AC			0x31AC
-#define	REG_0x31AE			0x31AE
-#define	REG_0x31B4			0x31B4
-#define	REG_0x31B6			0x31B6
-
-#define	REG_0x3254			0x3254
-#define	REG_0x3256			0x3256
-#define	REG_0x3258			0x3258
-#define	REG_0x325A			0x325A
-#define	REG_0x3260			0x3260
-#define	REG_0x3262			0x3262
-
-
-#define	REG_0x3304			0x3304
-#define	REG_0x3305			0x3305
-#define	REG_0x3306			0x3306
-#define	REG_0x3307			0x3307
-#define	REG_0x3308			0x3308
-#define	REG_0x3309			0x3309
-#define	REG_0x330A			0x330A
-#define	REG_0x330B			0x330B
-#define	REG_0x330C			0x330C
-#define	REG_0x330D			0x330D
-
-/* Mode Setting */
-#define	REG_FRAME_LENGTH_LINES_MSB	0x0340
-#define	REG_FRAME_LENGTH_LINES_LSB	0x0341
-#define	REG_LINE_LENGTH_PCK_MSB		0x0342
-#define	REG_LINE_LENGTH_PCK_LSB		0x0343
-#define	REG_X_OUTPUT_SIZE_MSB		0x034C
-#define	REG_X_OUTPUT_SIZE_LSB		0x034D
-#define	REG_Y_OUTPUT_SIZE_MSB		0x034E
-#define	REG_Y_OUTPUT_SIZE_LSB		0x034F
-#define	REG_X_EVEN_INC_LSB		0x0381
-#define	REG_X_ODD_INC_LSB		0x0383
-#define	REG_Y_EVEN_INC_LSB		0x0385
-#define	REG_Y_ODD_INC_LSB		0x0387
-#define	REG_0x3016			0x3016
-#define	REG_0x30E8			0x30E8
-#define	REG_0x3301			0x3301
-/* for 120fps support */
-#define	REG_0x0344			0x0344
-#define	REG_0x0345			0x0345
-#define	REG_0x0346			0x0346
-#define	REG_0x0347			0x0347
-#define	REG_0x0348			0x0348
-#define	REG_0x0349			0x0349
-#define	REG_0x034A			0x034A
-#define	REG_0x034B			0x034B
-
-/* Test Pattern */
-#define	REG_0x30D8			0x30D8
-#define	REG_TEST_PATTERN_MODE		0x0601
-
-/* Solid Color Test Pattern */
-#define	REG_TEST_DATA_RED_MSB		0x0603
-#define	REG_TEST_DATA_RED_LSB		0x0603
-#define	REG_TEST_DATA_GREENR_MSB	0x0604
-#define	REG_TEST_DATA_GREENR_LSB	0x0605
-#define	REG_TEST_DATA_BLUE_MSB		0x0606
-#define	REG_TEST_DATA_BLUE_LSB		0x0607
-#define	REG_TEST_DATA_GREENB_MSB	0x0608
-#define	REG_TEST_DATA_GREENB_LSB	0x0609
-#define	SN12M0PZ_AF_I2C_SLAVE_ID	0xE4
-#define	SN12M0PZ_STEPS_NEAR_TO_CLOSEST_INF	42
-#define	SN12M0PZ_TOTAL_STEPS_NEAR_TO_FAR	42
-
-
-/* TYPE DECLARATIONS */
-
-
-enum mipi_config_type {
-	IU060F_SN12M0PZ_STMIPID01,
-	IU060F_SN12M0PZ_STMIPID02
-};
-
-enum sn12m0pz_test_mode_t {
-	TEST_OFF,
-	TEST_1,
-	TEST_2,
-	TEST_3
-};
-
-enum sn12m0pz_resolution_t {
-	QTR_SIZE,
-	FULL_SIZE,
-	INVALID_SIZE,
-	QVGA_SIZE,
-};
-
-enum sn12m0pz_setting {
-	RES_PREVIEW,
-	RES_CAPTURE,
-	RES_VIDEO_120FPS,
-};
-
-enum mt9p012_reg_update {
-	/* Sensor egisters that need to be updated during initialization */
-	REG_INIT,
-	/* Sensor egisters that needs periodic I2C writes */
-	UPDATE_PERIODIC,
-	/* All the sensor Registers will be updated */
-	UPDATE_ALL,
-	/* Not valid update */
-	UPDATE_INVALID
-};
-
-/* 816x612, 24MHz MCLK 96MHz PCLK */
-#define	IU060F_SN12M0PZ_OFFSET			3
-/* Time in milisecs for waiting for the sensor to reset.*/
-#define	SN12M0PZ_RESET_DELAY_MSECS		66
-#define	SN12M0PZ_WIDTH				4032
-#define	SN12M0PZ_HEIGHT				3024
-#define	SN12M0PZ_FULL_SIZE_WIDTH		4032
-#define	SN12M0PZ_FULL_SIZE_HEIGHT		3024
-#define	SN12M0PZ_HRZ_FULL_BLK_PIXELS		176
-#define	SN12M0PZ_VER_FULL_BLK_LINES		50
-#define	SN12M0PZ_QTR_SIZE_WIDTH			2016
-#define	SN12M0PZ_QTR_SIZE_HEIGHT		1512
-#define	SN12M0PZ_HRZ_QTR_BLK_PIXELS		2192
-#define	SN12M0PZ_VER_QTR_BLK_LINES		26
-
-/* 120fps mode */
-#define	SN12M0PZ_QVGA_SIZE_WIDTH		4032
-#define	SN12M0PZ_QVGA_SIZE_HEIGHT		249
-#define	SN12M0PZ_HRZ_QVGA_BLK_PIXELS		176
-#define	SN12M0PZ_VER_QVGA_BLK_LINES		9
-#define	SN12M0PZ_DEFAULT_CLOCK_RATE		24000000
-
-static uint32_t IU060F_SN12M0PZ_DELAY_MSECS = 30;
-static enum mipi_config_type mipi_config = IU060F_SN12M0PZ_STMIPID02;
-/* AF Tuning Parameters */
-static int16_t enable_single_D02_lane;
-static int16_t fullsize_cropped_at_8mp;
-
-struct sn12m0pz_work_t {
-	struct work_struct work;
-};
-
-static struct sn12m0pz_work_t *sn12m0pz_sensorw;
-static struct i2c_client *sn12m0pz_client;
-
-struct sn12m0pz_ctrl_t {
-	const struct msm_camera_sensor_info *sensordata;
-	uint32_t sensormode;
-	uint32_t fps_divider;/* init to 1 * 0x00000400 */
-	uint32_t pict_fps_divider;/* init to 1 * 0x00000400 */
-	uint16_t fps;
-	int16_t curr_lens_pos;
-	uint16_t curr_step_pos;
-	uint16_t my_reg_gain;
-	uint32_t my_reg_line_count;
-	uint16_t total_lines_per_frame;
-	enum sn12m0pz_resolution_t prev_res;
-	enum sn12m0pz_resolution_t pict_res;
-	enum sn12m0pz_resolution_t curr_res;
-	enum sn12m0pz_test_mode_t  set_test;
-	unsigned short imgaddr;
-};
-
-static struct sn12m0pz_ctrl_t *sn12m0pz_ctrl;
-static DECLARE_WAIT_QUEUE_HEAD(sn12m0pz_wait_queue);
-DEFINE_MUTEX(sn12m0pz_mut);
-
-
-static int sn12m0pz_i2c_rxdata(unsigned short saddr,
-	unsigned char *rxdata, int length)
-{
-	struct i2c_msg msgs[] = {
-		{
-			.addr  = saddr,
-			.flags = 0,
-			.len   = 2,
-			.buf   = rxdata,
-		},
-		{
-			.addr  = saddr,
-			.flags = I2C_M_RD,
-			.len   = 2,
-			.buf   = rxdata,
-		},
-	};
-
-	if (i2c_transfer(sn12m0pz_client->adapter, msgs, 2) < 0) {
-		CDBG("sn12m0pz_i2c_rxdata failed!");
-		return -EIO;
-	}
-
-	return 0;
-}
-static int32_t sn12m0pz_i2c_txdata(unsigned short saddr,
-				unsigned char *txdata, int length)
-{
-
-	struct i2c_msg msg[] = {
-		{
-			.addr  = saddr,
-			.flags = 0,
-			.len	 = length,
-			.buf	 = txdata,
-		},
-	};
-
-	if (i2c_transfer(sn12m0pz_client->adapter, msg, 1) < 0) {
-		CDBG("sn12m0pz_i2c_txdata faild 0x%x", sn12m0pz_client->addr);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int32_t sn12m0pz_i2c_read(unsigned short raddr,
-				unsigned short *rdata, int rlen)
-{
-	int32_t rc;
-	unsigned char buf[2];
-	if (!rdata)
-		return -EIO;
-
-	memset(buf, 0, sizeof(buf));
-
-	buf[0] = (raddr & 0xFF00) >> 8;
-	buf[1] = (raddr & 0x00FF);
-
-	rc = sn12m0pz_i2c_rxdata(sn12m0pz_client->addr, buf, rlen);
-
-	if (rc < 0) {
-		CDBG("sn12m0pz_i2c_read 0x%x failed!", raddr);
-		return rc;
-	}
-
-	*rdata = (rlen == 2 ? buf[0] << 8 | buf[1] : buf[0]);
-
-	return rc;
-}
-
-static int32_t sn12m0pz_i2c_write_b_sensor(unsigned short waddr, uint8_t bdata)
-{
-	int32_t rc;
-	unsigned char buf[3];
-
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (waddr & 0xFF00) >> 8;
-	buf[1] = (waddr & 0x00FF);
-	buf[2] = bdata;
-	udelay(90);
-	CDBG("i2c_write_b addr = %x, val = %x\n", waddr, bdata);
-	rc = sn12m0pz_i2c_txdata(sn12m0pz_client->addr, buf, 3);
-
-	if (rc < 0) {
-		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!",
-			waddr, bdata);
-	}
-
-	return rc;
-}
-
-static int16_t sn12m0pz_i2c_write_b_af(unsigned short saddr,
-				unsigned short baddr, unsigned short bdata)
-{
-	int16_t rc;
-	unsigned char buf[2];
-
-	memset(buf, 0, sizeof(buf));
-	buf[0] = baddr;
-	buf[1] = bdata;
-	rc = sn12m0pz_i2c_txdata(saddr, buf, 2);
-
-	if (rc < 0)
-		CDBG("i2c_write failed, saddr = 0x%x addr = 0x%x, val =0x%x!",
-			saddr, baddr, bdata);
-
-	return rc;
-}
-
-static int32_t sn12m0pz_i2c_write_byte_bridge(unsigned short saddr,
-				unsigned short waddr, uint8_t bdata)
-{
-	int32_t rc;
-	unsigned char buf[3];
-
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (waddr & 0xFF00) >> 8;
-	buf[1] = (waddr & 0x00FF);
-	buf[2] = bdata;
-
-	CDBG("i2c_write_b addr = %x, val = %x", waddr, bdata);
-	rc = sn12m0pz_i2c_txdata(saddr, buf, 3);
-
-	if (rc < 0)
-		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!",
-			waddr, bdata);
-
-	return rc;
-}
-
-static int32_t sn12m0pz_stmipid01_config(void)
-{
-	int32_t rc = 0;
-	/* Initiate I2C for D01: */
-	/* MIPI Bridge configuration */
-	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0002, 0x19) < 0)
-		return rc; /* enable clock lane*/
-	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0003, 0x00) < 0)
-		return rc;
-	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0004, 0x3E) < 0)
-		return rc; /* mipi mode clock*/
-	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0005, 0x01) < 0)
-		return rc; /* enable data line*/
-	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0006, 0x0F) < 0)
-		return rc; /* mipi mode data 0x01*/
-	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0009, 0x00) < 0)
-		return rc; /* Data_Lane1_Reg1*/
-	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x000D, 0x92) < 0)
-		return rc; /* CCPRxRegisters*/
-	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x000E, 0x28) < 0)
-		return rc; /* 10 bits for pixel width input for CCP rx.*/
-	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0014, 0xC0) < 0)
-		return rc; /* no bypass, no decomp, 1Lane System,CSIstreaming*/
-	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0015, 0x48) < 0)
-		return rc; /* ModeControlRegisters-- Don't reset error flag*/
-	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0017, 0x2B) < 0)
-		return rc; /* Data_ID_Rreg*/
-	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0018, 0x2B) < 0)
-		return rc; /* Data_ID_Rreg_emb*/
-	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0019, 0x0C) < 0)
-		return rc;
-	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x001E, 0x0A) < 0)
-		return rc;
-	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x001F, 0x0A) < 0)
-		return rc;
-
-	return rc;
-}
-static int32_t sn12m0pz_stmipid02_config(void)
-{
-	int32_t rc = 0;
-
-	/* Main Camera Clock Lane 1 (CLHP1, CLKN1)*/
-	/* Enable Clock Lane 1 (CLHP1, CLKN1), 0x15 for 400MHz */
-	if (enable_single_D02_lane) {
-		if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0002, 0x19) < 0)
-			return rc;
-		/* Main Camera Data Lane 1.1 (DATA2P1, DATA2N1) */
-		if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0009, 0x00) < 0)
-			return rc;/* Enable Data Lane 1.2 (DATA2P1, DATA2N1) */
-		if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x000A, 0x00) < 0)
-			return rc; /*CSIMode on Data Lane1.2(DATA2P1,DATA2N1)*/
-		/* Mode Control */
-		/* Enable single lane for qtr preview */
-		if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0014, 0xC0) < 0)
-			return rc; /*set 0xC0 - left justified on upper bits)*/
-		/* bit 1 set to 0 i.e. 1 lane system for qtr size preview */
-	} else {
-		if (sn12m0pz_ctrl->prev_res == QVGA_SIZE) {
-			if (sn12m0pz_i2c_write_byte_bridge(0x28>>1,
-				0x0002, 0x19) < 0)
-				return rc;
-		} else {
-			if (sn12m0pz_i2c_write_byte_bridge(0x28>>1,
-				0x0002, 0x21) < 0)
-				return rc;
-		}
-		/* Main Camera Data Lane 1.1 (DATA2P1, DATA2N1) */
-		if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0009, 0x01) < 0)
-			return rc; /* Enable Data Lane 1.2 (DATA2P1, DATA2N1) */
-		if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x000A, 0x01) < 0)
-			return rc; /* CSI Mode Data Lane1.2(DATA2P1, DATA2N1)*/
-
-		/* Mode Control */
-		/* Enable two lanes for full size preview/ snapshot */
-		if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0014, 0xC2) < 0)
-			return rc; /* No decompression, CSI dual lane */
-	}
-
-	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0004, 0x1E) < 0)
-		return rc;
-
-	/* Main Camera Data Lane 1.1 (DATA1P1, DATA1N1) */
-	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0005, 0x03) < 0)
-		return rc; /* Enable Data Lane 1.1 (DATA1P1, DATA1N1) */
-	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0006, 0x0f) < 0)
-		return rc; /* CSI Mode on Data Lane 1.1 (DATA1P1, DATA1N1) */
-
-	/* Tristated Output, continuous clock, */
-	/*polarity of clock is inverted and sync signals not inverted*/
-	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0015, 0x08) < 0)
-		return rc;
-	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0036, 0x20) < 0)
-		return rc; /* Enable compensation macro, main camera */
-
-	/* Data type: 0x2B Raw 10 */
-	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0017, 0x2B) < 0)
-		return rc;
-	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0018, 0x2B) < 0)
-		return rc; /* Data type of embedded data: 0x2B Raw 10 */
-	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x0019, 0x0C) < 0)
-		return rc; /* Data type and pixel width programmed 0x0C*/
-
-	/* Decompression Mode */
-
-	/* Pixel Width and Decompression ON/OFF */
-	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x001E, 0x0A) < 0)
-		return rc; /* Image data not compressed: 0x0A for 10 bits */
-	if (sn12m0pz_i2c_write_byte_bridge(0x28>>1, 0x001F, 0x0A) < 0)
-		return rc; /* Embedded data not compressed: 0x0A for 10 bits */
-	return rc;
-}
-
-static int16_t sn12m0pz_af_init(void)
-{
-	int16_t rc;
-	/* Initialize waveform */
-	rc = sn12m0pz_i2c_write_b_af(SN12M0PZ_AF_I2C_SLAVE_ID >> 1, 0x01, 0xA9);
-
-	rc = sn12m0pz_i2c_write_b_af(SN12M0PZ_AF_I2C_SLAVE_ID >> 1, 0x02, 0xD2);
-
-	rc = sn12m0pz_i2c_write_b_af(SN12M0PZ_AF_I2C_SLAVE_ID >> 1, 0x03, 0x0C);
-
-	rc = sn12m0pz_i2c_write_b_af(SN12M0PZ_AF_I2C_SLAVE_ID >> 1, 0x04, 0x14);
-
-	rc = sn12m0pz_i2c_write_b_af(SN12M0PZ_AF_I2C_SLAVE_ID >> 1, 0x05, 0xB6);
-
-	rc = sn12m0pz_i2c_write_b_af(SN12M0PZ_AF_I2C_SLAVE_ID >> 1, 0x06, 0x4F);
-
-	rc = sn12m0pz_i2c_write_b_af(SN12M0PZ_AF_I2C_SLAVE_ID >> 1, 0x07, 0x00);
-
-	return rc;
-}
-
-static int32_t sn12m0pz_move_focus(int direction,
-	int32_t num_steps)
-{
-	int8_t step_direction, dest_step_position, bit_mask;
-	int32_t rc = 0;
-	uint16_t sn12m0pz_l_region_code_per_step = 3;
-
-	if (num_steps == 0)
-		return rc;
-
-	if (direction == MOVE_NEAR) {
-		step_direction = 1;
-		bit_mask = 0x80;
-	} else if (direction == MOVE_FAR) {
-		step_direction = -1;
-		bit_mask = 0x00;
-	} else {
-		CDBG("sn12m0pz_move_focus: Illegal focus direction");
-		return -EINVAL;
-	}
-
-	dest_step_position = sn12m0pz_ctrl->curr_step_pos +
-		(step_direction * num_steps);
-
-	if (dest_step_position < 0)
-		dest_step_position = 0;
-	else if (dest_step_position > SN12M0PZ_TOTAL_STEPS_NEAR_TO_FAR)
-		dest_step_position = SN12M0PZ_TOTAL_STEPS_NEAR_TO_FAR;
-
-	rc = sn12m0pz_i2c_write_b_af(SN12M0PZ_AF_I2C_SLAVE_ID >> 1, 0x00,
-		((num_steps * sn12m0pz_l_region_code_per_step) | bit_mask));
-
-	sn12m0pz_ctrl->curr_step_pos = dest_step_position;
-
-	return rc;
-}
-static int32_t sn12m0pz_set_default_focus(uint8_t af_step)
-{
-	int32_t rc;
-
-	/* Initialize to infinity */
-
-	rc = sn12m0pz_i2c_write_b_af(SN12M0PZ_AF_I2C_SLAVE_ID >> 1, 0x00, 0x7F);
-
-	rc = sn12m0pz_i2c_write_b_af(SN12M0PZ_AF_I2C_SLAVE_ID >> 1, 0x00, 0x7F);
-
-	sn12m0pz_ctrl->curr_step_pos = 0;
-
-	return rc;
-}
-static void sn12m0pz_get_pict_fps(uint16_t fps, uint16_t *pfps)
-{
-	/* input fps is preview fps in Q8 format */
-	uint16_t preview_frame_length_lines, snapshot_frame_length_lines;
-	uint16_t preview_line_length_pck, snapshot_line_length_pck;
-	uint32_t divider, pclk_mult, d1, d2;
-
-	/* Total frame_length_lines and line_length_pck for preview */
-	CDBG("sn12m0pz_get_pict_fps prev_res %d", sn12m0pz_ctrl->prev_res);
-	if (sn12m0pz_ctrl->prev_res == QVGA_SIZE) {
-		preview_frame_length_lines = SN12M0PZ_QVGA_SIZE_HEIGHT +
-			SN12M0PZ_VER_QVGA_BLK_LINES;
-		preview_line_length_pck = SN12M0PZ_QVGA_SIZE_WIDTH +
-			SN12M0PZ_HRZ_QVGA_BLK_PIXELS;
-	} else {
-		preview_frame_length_lines = SN12M0PZ_QTR_SIZE_HEIGHT +
-			SN12M0PZ_VER_QTR_BLK_LINES;
-		preview_line_length_pck = SN12M0PZ_QTR_SIZE_WIDTH +
-			SN12M0PZ_HRZ_QTR_BLK_PIXELS;
-	}
-	/* Total frame_length_lines and line_length_pck for snapshot */
-	snapshot_frame_length_lines = SN12M0PZ_FULL_SIZE_HEIGHT
-				+ SN12M0PZ_HRZ_FULL_BLK_PIXELS;
-	snapshot_line_length_pck = SN12M0PZ_FULL_SIZE_WIDTH
-				+ SN12M0PZ_HRZ_FULL_BLK_PIXELS;
-	d1 = preview_frame_length_lines *
-				0x00000400 / snapshot_frame_length_lines;
-	d2 = preview_line_length_pck *
-				0x00000400/snapshot_line_length_pck;
-	divider = d1 * d2 / 0x400;
-	pclk_mult =
-		(uint32_t)
-		(sn12m0pz_regs.reg_pat[RES_CAPTURE].pll_multiplier_lsb *
-		0x400) / (uint32_t)
-		sn12m0pz_regs.reg_pat[RES_PREVIEW].pll_multiplier_lsb;
-	*pfps = (uint16_t) (((fps * divider) / 0x400 * pclk_mult) / 0x400);
-}
-
-static uint16_t sn12m0pz_get_prev_lines_pf(void)
-{
-	if (sn12m0pz_ctrl->prev_res == QTR_SIZE)
-		return SN12M0PZ_QTR_SIZE_HEIGHT +
-			SN12M0PZ_VER_QTR_BLK_LINES;
-	else if (sn12m0pz_ctrl->prev_res == QVGA_SIZE)
-		return SN12M0PZ_QVGA_SIZE_HEIGHT +
-			SN12M0PZ_VER_QVGA_BLK_LINES;
-
-	else
-		return SN12M0PZ_FULL_SIZE_HEIGHT +
-			SN12M0PZ_VER_FULL_BLK_LINES;
-}
-
-static uint16_t sn12m0pz_get_prev_pixels_pl(void)
-{
-	if (sn12m0pz_ctrl->prev_res == QTR_SIZE)
-		return SN12M0PZ_QTR_SIZE_WIDTH +
-			SN12M0PZ_HRZ_QTR_BLK_PIXELS;
-	else
-		return SN12M0PZ_FULL_SIZE_WIDTH +
-			SN12M0PZ_HRZ_FULL_BLK_PIXELS;
-}
-
-static uint16_t sn12m0pz_get_pict_lines_pf(void)
-{
-	if (sn12m0pz_ctrl->pict_res == QTR_SIZE)
-		return SN12M0PZ_QTR_SIZE_HEIGHT +
-			SN12M0PZ_VER_QTR_BLK_LINES;
-	else
-		return SN12M0PZ_FULL_SIZE_HEIGHT +
-			SN12M0PZ_VER_FULL_BLK_LINES;
-}
-
-static uint16_t sn12m0pz_get_pict_pixels_pl(void)
-{
-	if (sn12m0pz_ctrl->pict_res == QTR_SIZE)
-		return SN12M0PZ_QTR_SIZE_WIDTH +
-			SN12M0PZ_HRZ_QTR_BLK_PIXELS;
-	else
-		return SN12M0PZ_FULL_SIZE_WIDTH +
-			SN12M0PZ_HRZ_FULL_BLK_PIXELS;
-}
-
-static uint32_t sn12m0pz_get_pict_max_exp_lc(void)
-{
-	if (sn12m0pz_ctrl->pict_res == QTR_SIZE)
-		return (SN12M0PZ_QTR_SIZE_HEIGHT +
-			SN12M0PZ_VER_QTR_BLK_LINES) * 24;
-	else
-		return (SN12M0PZ_FULL_SIZE_HEIGHT +
-			SN12M0PZ_VER_FULL_BLK_LINES) * 24;
-}
-
-static int32_t sn12m0pz_set_fps(struct fps_cfg	*fps)
-{
-	uint16_t total_lines_per_frame;
-	int32_t rc = 0;
-
-	total_lines_per_frame = (uint16_t)((SN12M0PZ_QTR_SIZE_HEIGHT +
-				SN12M0PZ_VER_QTR_BLK_LINES) *
-				sn12m0pz_ctrl->fps_divider / 0x400);
-
-	if (sn12m0pz_i2c_write_b_sensor(REG_FRAME_LENGTH_LINES_MSB,
-				((total_lines_per_frame & 0xFF00) >> 8)) < 0)
-		return rc;
-
-	if (sn12m0pz_i2c_write_b_sensor(REG_FRAME_LENGTH_LINES_LSB,
-				(total_lines_per_frame & 0x00FF)) < 0)
-		return rc;
-
-	return rc;
-}
-
-static int32_t sn12m0pz_write_exp_gain(uint16_t gain, uint32_t line)
-{
-	static uint16_t max_legal_gain = 0x00E0;
-	uint8_t gain_msb, gain_lsb;
-	uint8_t intg_time_msb, intg_time_lsb;
-	uint8_t line_length_pck_msb, line_length_pck_lsb;
-	uint16_t line_length_pck, frame_length_lines, temp_lines;
-	uint32_t line_length_ratio = 1 * Q8;
-	int32_t rc = 0;
-	CDBG("sn12m0pz_write_exp_gain : gain = %d line = %d", gain, line);
-
-	if (sn12m0pz_ctrl->sensormode != SENSOR_SNAPSHOT_MODE) {
-		if (sn12m0pz_ctrl->prev_res == QVGA_SIZE) {
-			frame_length_lines = SN12M0PZ_QVGA_SIZE_HEIGHT +
-						SN12M0PZ_VER_QVGA_BLK_LINES;
-			line_length_pck = SN12M0PZ_QVGA_SIZE_WIDTH +
-						SN12M0PZ_HRZ_QVGA_BLK_PIXELS;
-			if (line > (frame_length_lines -
-					IU060F_SN12M0PZ_OFFSET))
-				line = frame_length_lines -
-						IU060F_SN12M0PZ_OFFSET;
-			sn12m0pz_ctrl->fps = (uint16_t) (120 * Q8);
-		} else {
-			if (sn12m0pz_ctrl->curr_res  == QTR_SIZE) {
-				frame_length_lines = SN12M0PZ_QTR_SIZE_HEIGHT +
-						SN12M0PZ_VER_QTR_BLK_LINES;
-				line_length_pck = SN12M0PZ_QTR_SIZE_WIDTH +
-						SN12M0PZ_HRZ_QTR_BLK_PIXELS;
-			} else {
-				frame_length_lines = SN12M0PZ_HEIGHT +
-						SN12M0PZ_VER_FULL_BLK_LINES;
-				line_length_pck = SN12M0PZ_WIDTH +
-						SN12M0PZ_HRZ_FULL_BLK_PIXELS;
-			}
-			if (line > (frame_length_lines -
-						IU060F_SN12M0PZ_OFFSET))
-				sn12m0pz_ctrl->fps = (uint16_t) (30 * Q8 *
-			(frame_length_lines - IU060F_SN12M0PZ_OFFSET) / line);
-			else
-				sn12m0pz_ctrl->fps = (uint16_t) (30 * Q8);
-		}
-	} else {
-		if (sn12m0pz_ctrl->curr_res  == QTR_SIZE) {
-			frame_length_lines = SN12M0PZ_QTR_SIZE_HEIGHT +
-						SN12M0PZ_VER_QTR_BLK_LINES;
-			line_length_pck = SN12M0PZ_QTR_SIZE_WIDTH +
-						SN12M0PZ_HRZ_QTR_BLK_PIXELS;
-		} else {
-			frame_length_lines = SN12M0PZ_HEIGHT +
-						SN12M0PZ_VER_FULL_BLK_LINES;
-			line_length_pck = SN12M0PZ_WIDTH +
-						SN12M0PZ_HRZ_FULL_BLK_PIXELS;
-		}
-	}
-	if (gain > max_legal_gain)
-		/* range: 0 to 224 */
-		gain = max_legal_gain;
-	temp_lines = line;
-	/* calculate line_length_ratio */
-	if (line > (frame_length_lines - IU060F_SN12M0PZ_OFFSET)) {
-		line_length_ratio = (line * Q8) / (frame_length_lines -
-					IU060F_SN12M0PZ_OFFSET);
-		temp_lines = frame_length_lines - IU060F_SN12M0PZ_OFFSET;
-		if (line_length_ratio == 0)
-			line_length_ratio = 1 * Q8;
-	} else
-		line_length_ratio = 1 * Q8;
-
-	line = (uint32_t) (line * sn12m0pz_ctrl->fps_divider/0x400);
-
-	/* update gain registers */
-	gain_msb = (uint8_t) ((gain & 0xFF00) >> 8);
-	gain_lsb = (uint8_t) (gain & 0x00FF);
-
-	/* linear AFR horizontal stretch */
-	line_length_pck = (uint16_t) (line_length_pck * line_length_ratio / Q8);
-	line_length_pck_msb = (uint8_t) ((line_length_pck & 0xFF00) >> 8);
-	line_length_pck_lsb = (uint8_t) (line_length_pck & 0x00FF);
-
-	/* update line count registers */
-	intg_time_msb = (uint8_t) ((temp_lines & 0xFF00) >> 8);
-	intg_time_lsb = (uint8_t) (temp_lines & 0x00FF);
-
-
-	if (sn12m0pz_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
-			GROUPED_PARAMETER_HOLD) < 0)
-		return rc;
-
-	if (sn12m0pz_i2c_write_b_sensor(REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB,
-			gain_msb) < 0)
-		return rc;
-
-	if (sn12m0pz_i2c_write_b_sensor(REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB,
-			gain_lsb) < 0)
-		return rc;
-
-	if (sn12m0pz_i2c_write_b_sensor(REG_LINE_LENGTH_PCK_MSB,
-			line_length_pck_msb) < 0)
-		return rc;
-
-	if (sn12m0pz_i2c_write_b_sensor(REG_LINE_LENGTH_PCK_LSB,
-			line_length_pck_lsb) < 0)
-		return rc;
-
-	if (sn12m0pz_i2c_write_b_sensor(REG_COARSE_INTEGRATION_TIME_MSB,
-			intg_time_msb) < 0)
-		return rc;
-
-	if (sn12m0pz_i2c_write_b_sensor(REG_COARSE_INTEGRATION_TIME_LSB,
-			intg_time_lsb) < 0)
-		return rc;
-
-	if (sn12m0pz_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
-			GROUPED_PARAMETER_HOLD_OFF) < 0)
-		return rc;
-
-	return rc;
-}
-
-
-static int32_t sn12m0pz_set_pict_exp_gain(uint16_t gain, uint32_t line)
-{
-	int32_t rc;
-	rc = sn12m0pz_write_exp_gain(gain, line);
-	return rc;
-}
-
-static int32_t sn12m0pz_test(enum sn12m0pz_test_mode_t mo)
-{
-	uint8_t test_data_val_msb = 0x07;
-	uint8_t test_data_val_lsb = 0xFF;
-	int32_t rc = 0;
-	if (mo == TEST_OFF)
-		return rc;
-	else {
-		/* REG_0x30D8[4] is TESBYPEN: 0: Normal Operation,
-		 1: Bypass Signal Processing. REG_0x30D8[5] is EBDMASK:
-		 0: Output Embedded data, 1: No output embedded data */
-
-		if (sn12m0pz_i2c_write_b_sensor(REG_0x30D8, 0x10) < 0)
-			return rc;
-
-		if (sn12m0pz_i2c_write_b_sensor(REG_TEST_PATTERN_MODE,
-			(uint8_t) mo) < 0)
-			return rc;
-
-		/* Solid Color Test Pattern */
-
-		if (mo == TEST_1) {
-			if (sn12m0pz_i2c_write_b_sensor(REG_TEST_DATA_RED_MSB,
-				test_data_val_msb) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_TEST_DATA_RED_LSB,
-				test_data_val_lsb) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(
-						REG_TEST_DATA_GREENR_MSB,
-						test_data_val_msb) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(
-						REG_TEST_DATA_GREENR_LSB,
-						test_data_val_lsb) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_TEST_DATA_BLUE_MSB,
-				test_data_val_msb) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_TEST_DATA_BLUE_LSB,
-				test_data_val_lsb) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(
-						REG_TEST_DATA_GREENB_MSB,
-						test_data_val_msb) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(
-						REG_TEST_DATA_GREENB_LSB,
-						test_data_val_lsb) < 0)
-				return rc;
-		}
-
-	}
-
-	return rc;
-}
-
-static int32_t sn12m0pz_reset(void)
-{
-	int32_t rc = 0;
-	/* register 0x0002 is Port 2, CAM_XCLRO */
-	gpio_direction_output(sn12m0pz_ctrl->
-		sensordata->sensor_reset,
-		0);
-	msleep(50);
-	gpio_direction_output(sn12m0pz_ctrl->
-		sensordata->sensor_reset,
-		1);
-	msleep(13);
-	return rc;
-}
-
-static int32_t sn12m0pz_sensor_setting(int update_type, int rt)
-{
-	uint16_t total_lines_per_frame;
-	int32_t rc = 0;
-
-	switch (update_type) {
-	case UPDATE_PERIODIC:
-		/* Put Sensor into sofware standby mode	*/
-		if (sn12m0pz_i2c_write_b_sensor(REG_MODE_SELECT,
-				MODE_SELECT_STANDBY_MODE) <  0)
-			return rc;
-		msleep(5);
-		/* Hardware reset D02, lane config between full size/qtr size*/
-		rc = sn12m0pz_reset();
-		if (rc < 0)
-			return rc;
-
-		if (sn12m0pz_stmipid02_config() < 0)
-			return rc;
-	case REG_INIT:
-		if (rt == RES_PREVIEW || rt == RES_CAPTURE
-				|| rt == RES_VIDEO_120FPS) {
-			/* reset fps_divider */
-			sn12m0pz_ctrl->fps_divider = 1 * 0x400;
-
-			/* PLL settings */
-			if (sn12m0pz_i2c_write_b_sensor(REG_PLL_MULTIPLIER,
-			sn12m0pz_regs.reg_pat[rt].pll_multiplier_lsb) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x302B,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x302B) < 0)
-				return rc;
-
-			/* MIPI Enable Settings */
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x30E5,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x30E5) < 0)
-				return rc;
-
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3300,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3300) < 0)
-				return rc;
-
-			/* Global Setting */
-			if (
-				sn12m0pz_i2c_write_b_sensor(
-				REG_IMAGE_ORIENTATION,
-				sn12m0pz_regs.reg_pat_init[0].image_orient) < 0)
-				return rc;
-			if (
-				sn12m0pz_i2c_write_b_sensor(
-				REG_COARSE_INTEGRATION_TIME_MSB,
-				sn12m0pz_regs.reg_pat[rt].coarse_integ_time_msb)
-				< 0)
-				return rc;
-			if (
-				sn12m0pz_i2c_write_b_sensor(
-				REG_COARSE_INTEGRATION_TIME_LSB,
-				sn12m0pz_regs.reg_pat[rt].coarse_integ_time_lsb)
-				 < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x300A,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x300A) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3014,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3014) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3015,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3015) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3017,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3017) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x301C,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x301C) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3031,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3031) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3040,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3040) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3041,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3041) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3051,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3051) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3053,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3053) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3055,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3055) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3057,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3057) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3060,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3060) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3065,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3065) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x30AA,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x30AA) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x30AB,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x30AB) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x30B0,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x30B0) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x30B2,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x30B2) < 0)
-				return rc;
-
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x30D3,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x30D3) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x30D8,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x30D8) < 0)
-				return rc;
-
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3106,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3106) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3108,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3108) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x310A,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x310A) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x310C,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x310C) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x310E,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x310E) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3126,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3126) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x312E,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x312E) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x313C,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x313C) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x313E,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x313E) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3140,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3140) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3142,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3142) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3144,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3144) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3148,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3148) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x314A,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x314A) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3166,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3166) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3168,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3168) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x316F,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x316F) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3171,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3171) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3173,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3173) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3175,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3175) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3177,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3177) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3179,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3179) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x317B,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x317B) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x317D,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x317D) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x317F,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x317F) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3181,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3181) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3184,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3184) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3185,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3185) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3187,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3187) < 0)
-				return rc;
-
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x31A4,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x31A4) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x31A6,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x31A6) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x31AC,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x31AC) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x31AE,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x31AE) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x31B4,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x31B4) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x31B6,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x31B6) < 0)
-				return rc;
-
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3254,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3254) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3256,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3256) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3258,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3258) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x325A,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x325A) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3260,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3260) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3262,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3262) < 0)
-				return rc;
-
-
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3304,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3304) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3305,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3305) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3306,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3306) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3307,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3307) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3308,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3308) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3309,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x3309) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x330A,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x330A) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x330B,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x330B) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x330C,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x330C) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x330D,
-				sn12m0pz_regs.reg_pat_init[0].reg_0x330D) < 0)
-				return rc;
-
-			/* Mode setting */
-			/* Update registers with correct
-				 frame_length_line value for AFR */
-			total_lines_per_frame = (uint16_t)(
-			(sn12m0pz_regs.reg_pat[rt].frame_length_lines_msb << 8)
-			& 0xFF00) +
-			sn12m0pz_regs.reg_pat[rt].frame_length_lines_lsb;
-			total_lines_per_frame = total_lines_per_frame *
-					sn12m0pz_ctrl->fps_divider / 0x400;
-
-			if (sn12m0pz_i2c_write_b_sensor(
-					REG_FRAME_LENGTH_LINES_MSB,
-					(total_lines_per_frame & 0xFF00) >> 8)
-					< 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(
-					REG_FRAME_LENGTH_LINES_LSB,
-					(total_lines_per_frame & 0x00FF)) < 0)
-				return rc;
-
-			if (sn12m0pz_i2c_write_b_sensor(REG_LINE_LENGTH_PCK_MSB,
-				sn12m0pz_regs.reg_pat[rt].line_length_pck_msb) <
-				0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_LINE_LENGTH_PCK_LSB,
-				sn12m0pz_regs.reg_pat[rt].line_length_pck_lsb) <
-				0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_X_OUTPUT_SIZE_MSB,
-				sn12m0pz_regs.reg_pat[rt].x_output_size_msb) <
-				0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_X_OUTPUT_SIZE_LSB,
-				sn12m0pz_regs.reg_pat[rt].x_output_size_lsb) <
-				0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_Y_OUTPUT_SIZE_MSB,
-				sn12m0pz_regs.reg_pat[rt].y_output_size_msb) <
-				0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_Y_OUTPUT_SIZE_LSB,
-				sn12m0pz_regs.reg_pat[rt].y_output_size_lsb) <
-				0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_X_EVEN_INC_LSB,
-				sn12m0pz_regs.reg_pat[rt].x_even_inc_lsb) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_X_ODD_INC_LSB,
-				sn12m0pz_regs.reg_pat[rt].x_odd_inc_lsb) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_Y_EVEN_INC_LSB,
-				sn12m0pz_regs.reg_pat[rt].y_even_inc_lsb) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_Y_ODD_INC_LSB,
-				sn12m0pz_regs.reg_pat[rt].y_odd_inc_lsb) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3016,
-				sn12m0pz_regs.reg_pat[rt].reg_0x3016) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x30E8,
-				sn12m0pz_regs.reg_pat[rt].reg_0x30E8) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x3301,
-				sn12m0pz_regs.reg_pat[rt].reg_0x3301) < 0)
-				return rc;
-
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x0344,
-				sn12m0pz_regs.reg_pat[rt].reg_0x0344) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x0345,
-				sn12m0pz_regs.reg_pat[rt].reg_0x0345) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x0346,
-				sn12m0pz_regs.reg_pat[rt].reg_0x0346) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x0347,
-				sn12m0pz_regs.reg_pat[rt].reg_0x0347) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x0348,
-				sn12m0pz_regs.reg_pat[rt].reg_0x0348) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x0349,
-				sn12m0pz_regs.reg_pat[rt].reg_0x0349) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x034A,
-				sn12m0pz_regs.reg_pat[rt].reg_0x034A) < 0)
-				return rc;
-			if (sn12m0pz_i2c_write_b_sensor(REG_0x034B,
-				sn12m0pz_regs.reg_pat[rt].reg_0x034B) < 0)
-				return rc;
-
-			if ((rt == RES_CAPTURE) && fullsize_cropped_at_8mp) {
-				/* x address end */
-				if (sn12m0pz_i2c_write_b_sensor(0x0348,
-								0x0C) < 0)
-					return rc;
-				if (sn12m0pz_i2c_write_b_sensor(0x0349,
-								0x0CF) < 0)
-					return rc;
-				/* y address end */
-				if (sn12m0pz_i2c_write_b_sensor(0x034A,
-								0x09) < 0)
-					return rc;
-				if (sn12m0pz_i2c_write_b_sensor(0x034B,
-								0x9F) < 0)
-					return rc;
-			}
-
-			if (mipi_config == IU060F_SN12M0PZ_STMIPID01) {
-				if (sn12m0pz_i2c_write_b_sensor(
-						REG_PLL_MULTIPLIER, 0x43) < 0)
-					return rc;
-				if (rt == RES_CAPTURE) {
-					if (sn12m0pz_i2c_write_b_sensor(
-						REG_0x3301, 0x01) < 0)
-						return rc;
-				if (sn12m0pz_i2c_write_b_sensor(
-						REG_0x3017, 0xE0) < 0)
-					return rc;
-				}
-			}
-
-			if (sn12m0pz_i2c_write_b_sensor(REG_MODE_SELECT,
-						MODE_SELECT_STREAM) < 0)
-				return rc;
-
-			msleep(IU060F_SN12M0PZ_DELAY_MSECS);
-
-			if (sn12m0pz_test(sn12m0pz_ctrl->set_test) < 0)
-				return rc;
-
-			if (mipi_config == IU060F_SN12M0PZ_STMIPID02)
-				CDBG("%s,%d", __func__, __LINE__);
-			return rc;
-		}
-	default:
-		return rc;
-		}
-}
-
-
-static int32_t sn12m0pz_video_config(int mode)
-{
-
-	int32_t rc = 0;
-	int rt;
-
-
-	if (mode == SENSOR_HFR_120FPS_MODE)
-		sn12m0pz_ctrl->prev_res = QVGA_SIZE;
-
-	/* change sensor resolution if needed */
-	if (sn12m0pz_ctrl->curr_res != sn12m0pz_ctrl->prev_res) {
-		if (sn12m0pz_ctrl->prev_res == QTR_SIZE) {
-			rt = RES_PREVIEW;
-			IU060F_SN12M0PZ_DELAY_MSECS = 35; /*measured on scope*/
-			enable_single_D02_lane = 1;
-		} else if (sn12m0pz_ctrl->prev_res == QVGA_SIZE) {
-			rt = RES_VIDEO_120FPS;
-			IU060F_SN12M0PZ_DELAY_MSECS = 35; /*measured on scope*/
-			enable_single_D02_lane = 0;
-		} else {
-			rt = RES_CAPTURE;
-			enable_single_D02_lane = 0;
-		}
-
-		if (sn12m0pz_sensor_setting(UPDATE_PERIODIC, rt) < 0)
-			return rc;
-	}
-
-	sn12m0pz_ctrl->curr_res = sn12m0pz_ctrl->prev_res;
-	sn12m0pz_ctrl->sensormode = mode;
-
-	return rc;
-}
-static int32_t sn12m0pz_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-	int rt;
-	/* change sensor resolution if needed */
-	if (sn12m0pz_ctrl->curr_res != sn12m0pz_ctrl->pict_res) {
-		if (sn12m0pz_ctrl->pict_res == QTR_SIZE) {
-			rt = RES_PREVIEW;
-			enable_single_D02_lane = 1;
-		} else {
-			rt = RES_CAPTURE;
-			IU060F_SN12M0PZ_DELAY_MSECS = 100;/*measured on scope*/
-			enable_single_D02_lane = 0;
-		}
-
-		if (sn12m0pz_sensor_setting(UPDATE_PERIODIC, rt) < 0)
-			return rc;
-	}
-
-	sn12m0pz_ctrl->curr_res = sn12m0pz_ctrl->pict_res;
-	sn12m0pz_ctrl->sensormode = mode;
-	return rc;
-}
-
-static int32_t sn12m0pz_raw_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-	int rt;
-	/* change sensor resolution if needed */
-	if (sn12m0pz_ctrl->curr_res != sn12m0pz_ctrl->pict_res) {
-		if (sn12m0pz_ctrl->pict_res == QTR_SIZE) {
-			rt = RES_PREVIEW;
-			enable_single_D02_lane = 1;
-		} else {
-			rt = RES_CAPTURE;
-			IU060F_SN12M0PZ_DELAY_MSECS = 100;/*measured on scope*/
-			enable_single_D02_lane = 0;
-		}
-		if (sn12m0pz_sensor_setting(UPDATE_PERIODIC, rt) < 0)
-			return rc;
-		}
-	sn12m0pz_ctrl->curr_res = sn12m0pz_ctrl->pict_res;
-	sn12m0pz_ctrl->sensormode = mode;
-	return rc;
-}
-static int32_t sn12m0pz_set_sensor_mode(int  mode,
-	int  res)
-{
-	int32_t rc;
-
-	switch (mode) {
-	case SENSOR_PREVIEW_MODE:
-	case SENSOR_HFR_120FPS_MODE:
-		rc = sn12m0pz_video_config(mode);
-		break;
-
-	case SENSOR_SNAPSHOT_MODE:
-		rc = sn12m0pz_snapshot_config(mode);
-		break;
-
-	case SENSOR_RAW_SNAPSHOT_MODE:
-		rc = sn12m0pz_raw_snapshot_config(mode);
-		break;
-
-	default:
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
-
-static int32_t sn12m0pz_power_down(void)
-{
-	return 0;
-}
-
-
-static int sn12m0pz_probe_init_done(const struct msm_camera_sensor_info *data)
-{
-
-	gpio_direction_output(data->sensor_reset, 0);
-	gpio_free(data->sensor_reset);
-	gpio_direction_output(data->vcm_pwd, 0);
-	gpio_free(data->vcm_pwd);
-	return 0;
-}
-
-static int sn12m0pz_probe_init_sensor(const struct msm_camera_sensor_info *data)
-{
-	int32_t rc;
-	unsigned short chipidl, chipidh;
-	CDBG("Requesting gpio");
-	rc = gpio_request(data->sensor_reset, "sn12m0pz");
-	CDBG(" sn12m0pz_probe_init_sensor");
-	if (!rc) {
-		gpio_direction_output(data->sensor_reset, 0);
-		msleep(20);
-		gpio_direction_output(data->sensor_reset, 1);
-		msleep(13);
-	} else {
-		goto init_probe_done;
-	}
-	CDBG("Requestion gpio");
-	rc = gpio_request(data->vcm_pwd, "sn12m0pz");
-	CDBG(" sn12m0pz_probe_init_sensor");
-
-	if (!rc) {
-		gpio_direction_output(data->vcm_pwd, 0);
-		msleep(20);
-		gpio_direction_output(data->vcm_pwd, 1);
-		msleep(13);
-	} else {
-		gpio_direction_output(data->sensor_reset, 0);
-		gpio_free(data->sensor_reset);
-		goto init_probe_done;
-	}
-
-	msleep(20);
-
-	/* 3. Read sensor Model ID: */
-	rc = sn12m0pz_i2c_read(0x0000, &chipidh, 1);
-	if (rc < 0) {
-		CDBG(" sn12m0pz_probe_init_sensor3");
-		goto init_probe_fail;
-	}
-	rc = sn12m0pz_i2c_read(0x0001, &chipidl, 1);
-	if (rc < 0) {
-		CDBG(" sn12m0pz_probe_init_sensor4");
-		goto init_probe_fail;
-	}
-
-	/* 4. Compare sensor ID to SN12M0PZ ID: */
-	if (chipidh != 0x00 || chipidl != 0x60) {
-		rc = -ENODEV;
-		CDBG("sn12m0pz_probe_init_sensor fail chip id doesnot match");
-		goto init_probe_fail;
-	}
-
-	msleep(SN12M0PZ_RESET_DELAY_MSECS);
-
-	goto init_probe_done;
-
-init_probe_fail:
-	CDBG(" sn12m0pz_probe_init_sensor fails");
-	sn12m0pz_probe_init_done(data);
-
-init_probe_done:
-	CDBG(" sn12m0pz_probe_init_sensor finishes");
-	return rc;
-}
-
-int sn12m0pz_sensor_open_init(const struct msm_camera_sensor_info *data)
-{
-	int32_t rc = 0;
-	CDBG("Calling sn12m0pz_sensor_open_init");
-
-	sn12m0pz_ctrl = kzalloc(sizeof(struct sn12m0pz_ctrl_t), GFP_KERNEL);
-	if (!sn12m0pz_ctrl) {
-		CDBG("sn12m0pz_init failed!");
-		rc = -ENOMEM;
-		goto init_done;
-	}
-
-	sn12m0pz_ctrl->fps_divider      = 1 * 0x00000400;
-	sn12m0pz_ctrl->pict_fps_divider = 1 * 0x00000400;
-	sn12m0pz_ctrl->set_test = TEST_OFF;
-	sn12m0pz_ctrl->prev_res = QTR_SIZE;
-	sn12m0pz_ctrl->pict_res = FULL_SIZE;
-	sn12m0pz_ctrl->curr_res = INVALID_SIZE;
-	if (data)
-		sn12m0pz_ctrl->sensordata = data;
-
-	if (rc < 0)
-		return rc;
-
-	/* enable mclk first */
-	msm_camio_clk_rate_set(SN12M0PZ_DEFAULT_CLOCK_RATE);
-	msleep(20);
-	msm_camio_camif_pad_reg_reset();
-	msleep(20);
-	CDBG("Calling sn12m0pz_sensor_open_init");
-	rc = sn12m0pz_probe_init_sensor(data);
-
-	if (rc < 0)
-		goto init_fail;
-	/* send reset signal */
-	if (mipi_config == IU060F_SN12M0PZ_STMIPID01) {
-		if (sn12m0pz_stmipid01_config() < 0) {
-			CDBG("Calling sn12m0pz_sensor_open_init fail");
-			return rc;
-		}
-	} else {
-		if (sn12m0pz_ctrl->prev_res  == QTR_SIZE)
-			enable_single_D02_lane = 1;
-		else /* FULL_SIZE */
-			enable_single_D02_lane = 0;
-
-		if (sn12m0pz_stmipid02_config() < 0) {
-			CDBG("Calling sn12m0pz_sensor_open_init fail");
-			return rc;
-		}
-	}
-
-
-	if (sn12m0pz_ctrl->prev_res == QTR_SIZE) {
-		if (sn12m0pz_sensor_setting(REG_INIT, RES_PREVIEW) < 0)
-			return rc;
-	} else if (sn12m0pz_ctrl->prev_res == QVGA_SIZE) {
-		if (sn12m0pz_sensor_setting(REG_INIT, RES_VIDEO_120FPS) < 0)
-			return rc;
-	} else {
-		if (sn12m0pz_sensor_setting(REG_INIT, RES_CAPTURE) < 0)
-			return rc;
-	}
-
-	if (sn12m0pz_af_init() < 0)
-		return rc;
-	sn12m0pz_ctrl->fps = 30*Q8;
-	if (rc < 0)
-		goto init_fail;
-	else
-		goto init_done;
-init_fail:
-	CDBG(" init_fail");
-	sn12m0pz_probe_init_done(data);
-	kfree(sn12m0pz_ctrl);
-init_done:
-	CDBG("init_done");
-	return rc;
-}
-static int __devinit sn12m0pz_init_client(struct i2c_client *client)
-{
-	/* Initialize the MSM_CAMI2C Chip */
-	init_waitqueue_head(&sn12m0pz_wait_queue);
-	return 0;
-}
-
-static const struct i2c_device_id sn12m0pz_i2c_id[] = {
-	{ "sn12m0pz", 0},
-	{ }
-};
-
-static int __devinit sn12m0pz_i2c_probe(struct i2c_client *client,
-	const struct i2c_device_id *id)
-{
-	int rc = 0;
-	CDBG("sn12m0pz_probe called!");
-
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		CDBG("i2c_check_functionality failed");
-		goto probe_failure;
-	}
-
-	sn12m0pz_sensorw = kzalloc(sizeof(struct sn12m0pz_work_t), GFP_KERNEL);
-	if (!sn12m0pz_sensorw) {
-		CDBG("kzalloc failed");
-		rc = -ENOMEM;
-		goto probe_failure;
-	}
-
-	i2c_set_clientdata(client, sn12m0pz_sensorw);
-	sn12m0pz_init_client(client);
-	sn12m0pz_client = client;
-
-	msleep(50);
-
-	CDBG("sn12m0pz_probe successed! rc = %d", rc);
-	return 0;
-
-probe_failure:
-	CDBG("sn12m0pz_probe failed! rc = %d", rc);
-	return rc;
-}
-
-static int __exit sn12m0pz_remove(struct i2c_client *client)
-{
-	struct sn12m0pz_work_t_t *sensorw = i2c_get_clientdata(client);
-	free_irq(client->irq, sensorw);
-	sn12m0pz_client = NULL;
-	kfree(sensorw);
-	return 0;
-}
-
-static struct i2c_driver sn12m0pz_i2c_driver = {
-	.id_table = sn12m0pz_i2c_id,
-	.probe	= sn12m0pz_i2c_probe,
-	.remove = __exit_p(sn12m0pz_i2c_remove),
-	.driver = {
-		.name = "sn12m0pz",
-	},
-};
-
-int sn12m0pz_sensor_config(void __user *argp)
-{
-	struct sensor_cfg_data cdata;
-	int32_t rc = 0;
-	if (copy_from_user(&cdata,
-				(void *)argp,
-				sizeof(struct sensor_cfg_data)))
-		return -EFAULT;
-
-	mutex_lock(&sn12m0pz_mut);
-
-	CDBG("sn12m0pz_sensor_config: cfgtype = %d",
-		cdata.cfgtype);
-	switch (cdata.cfgtype) {
-	case CFG_GET_PICT_FPS:
-		sn12m0pz_get_pict_fps(cdata.cfg.gfps.prevfps,
-					&(cdata.cfg.gfps.pictfps));
-
-		if (copy_to_user((void *)argp,
-			&cdata,
-			sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PREV_L_PF:
-		cdata.cfg.prevl_pf =
-			sn12m0pz_get_prev_lines_pf();
-
-		if (copy_to_user((void *)argp,
-			&cdata,
-			sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PREV_P_PL:
-		cdata.cfg.prevp_pl =
-			sn12m0pz_get_prev_pixels_pl();
-
-		if (copy_to_user((void *)argp,
-			&cdata,
-			sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PICT_L_PF:
-		cdata.cfg.pictl_pf =
-			sn12m0pz_get_pict_lines_pf();
-
-		if (copy_to_user((void *)argp,
-			&cdata,
-			sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PICT_P_PL:
-		cdata.cfg.pictp_pl =
-			sn12m0pz_get_pict_pixels_pl();
-
-		if (copy_to_user((void *)argp,
-			&cdata,
-			sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PICT_MAX_EXP_LC:
-		cdata.cfg.pict_max_exp_lc =
-			sn12m0pz_get_pict_max_exp_lc();
-
-		if (copy_to_user((void *)argp,
-			&cdata,
-			sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_SET_FPS:
-	case CFG_SET_PICT_FPS:
-		rc = sn12m0pz_set_fps(&(cdata.cfg.fps));
-		break;
-
-	case CFG_SET_EXP_GAIN:
-		rc =
-			sn12m0pz_write_exp_gain(
-				cdata.cfg.exp_gain.gain,
-				cdata.cfg.exp_gain.line);
-		break;
-	case CFG_SET_PICT_EXP_GAIN:
-		rc =
-			sn12m0pz_set_pict_exp_gain(
-				cdata.cfg.exp_gain.gain,
-				cdata.cfg.exp_gain.line);
-		break;
-
-	case CFG_SET_MODE:
-		rc = sn12m0pz_set_sensor_mode(cdata.mode,
-					cdata.rs);
-		break;
-
-	case CFG_PWR_DOWN:
-		rc = sn12m0pz_power_down();
-		break;
-
-	case CFG_MOVE_FOCUS:
-		rc = sn12m0pz_move_focus(cdata.cfg.focus.dir,
-					cdata.cfg.focus.steps);
-		break;
-
-	case CFG_SET_DEFAULT_FOCUS:
-		rc = sn12m0pz_set_default_focus(cdata.cfg.focus.steps);
-		break;
-
-	case CFG_SET_EFFECT:
-		rc = 0;
-		break;
-	case CFG_SET_LENS_SHADING:
-		rc = 0;
-		break;
-	default:
-		rc = -EFAULT;
-		break;
-	}
-
-	mutex_unlock(&sn12m0pz_mut);
-
-	return rc;
-}
-
-static int sn12m0pz_sensor_release(void)
-{
-	int rc = -EBADF;
-
-	mutex_lock(&sn12m0pz_mut);
-
-	sn12m0pz_power_down();
-
-	gpio_direction_output(sn12m0pz_ctrl->sensordata->sensor_reset,
-		0);
-	gpio_free(sn12m0pz_ctrl->sensordata->sensor_reset);
-
-	gpio_direction_output(sn12m0pz_ctrl->sensordata->vcm_pwd,
-		0);
-	gpio_free(sn12m0pz_ctrl->sensordata->vcm_pwd);
-
-	kfree(sn12m0pz_ctrl);
-	sn12m0pz_ctrl = NULL;
-
-	CDBG("sn12m0pz_release completed");
-
-
-	mutex_unlock(&sn12m0pz_mut);
-
-	return rc;
-}
-
-static int sn12m0pz_sensor_probe(const struct msm_camera_sensor_info *info,
-		struct msm_sensor_ctrl *s)
-{
-	int rc;
-
-	rc = i2c_add_driver(&sn12m0pz_i2c_driver);
-	if (rc < 0 || sn12m0pz_client == NULL) {
-		rc = -ENOTSUPP;
-		goto probe_fail;
-	}
-
-	msm_camio_clk_rate_set(SN12M0PZ_DEFAULT_CLOCK_RATE);
-	msleep(20);
-
-	rc = sn12m0pz_probe_init_sensor(info);
-	if (rc < 0)
-		goto probe_fail;
-
-	s->s_init = sn12m0pz_sensor_open_init;
-	s->s_release = sn12m0pz_sensor_release;
-	s->s_config  = sn12m0pz_sensor_config;
-	s->s_mount_angle  = 0;
-	sn12m0pz_probe_init_done(info);
-
-	return rc;
-
-probe_fail:
-	CDBG("SENSOR PROBE FAILS!");
-	i2c_del_driver(&sn12m0pz_i2c_driver);
-	return rc;
-}
-
-static int __sn12m0pz_probe(struct platform_device *pdev)
-{
-	return msm_camera_drv_start(pdev, sn12m0pz_sensor_probe);
-}
-
-static struct platform_driver msm_camera_driver = {
-	.probe = __sn12m0pz_probe,
-	.driver = {
-		.name = "msm_camera_sn12m0pz",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init sn12m0pz_init(void)
-{
-	return platform_driver_register(&msm_camera_driver);
-}
-
-module_init(sn12m0pz_init);
-
-MODULE_DESCRIPTION("Sony 12M MP Bayer sensor driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/sn12m0pz.h b/drivers/media/video/msm/sn12m0pz.h
deleted file mode 100644
index f2abc47..0000000
--- a/drivers/media/video/msm/sn12m0pz.h
+++ /dev/null
@@ -1,138 +0,0 @@
-
-/* Copyright (c) 2010, Code Aurora Forum. 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 SN12M0PZ_H
-#define SN12M0PZ_H
-
-#include <linux/types.h>
-extern struct sn12m0pz_reg sn12m0pz_regs; /* from mt9t013_reg.c */
-struct reg_struct{
-	uint8_t pll_multiplier_lsb;            /* 0x0307*/
-	uint8_t coarse_integ_time_msb;   /* 0x0202*/
-	uint8_t coarse_integ_time_lsb;   /* 0x0203*/
-	uint8_t frame_length_lines_msb;        /* 0x0340*/
-	uint8_t frame_length_lines_lsb;        /* 0x0341*/
-	uint8_t line_length_pck_msb;           /* 0x0342*/
-	uint8_t line_length_pck_lsb;           /* 0x0343*/
-	uint8_t x_output_size_msb;             /* 0x034C*/
-	uint8_t x_output_size_lsb;             /* 0x034D*/
-	uint8_t y_output_size_msb;             /* 0x034E*/
-	uint8_t y_output_size_lsb;             /* 0x034F*/
-	uint8_t x_even_inc_lsb;                /* 0x0381*/
-	uint8_t x_odd_inc_lsb;                 /* 0x0383*/
-	uint8_t y_even_inc_lsb;                /* 0x0385*/
-	uint8_t y_odd_inc_lsb;                 /* 0x0387*/
-	uint8_t reg_0x3016;                    /* 0x3016 VMODEADD*/
-	uint8_t reg_0x30E8;                    /* 0x30E8 HADDAVE*/
-	uint8_t reg_0x3301;                    /* 0x3301 RGLANESEL*/
-	/*added for 120fps support */
-	uint8_t reg_0x0344;
-	uint8_t reg_0x0345;
-	uint8_t reg_0x0346;
-	uint8_t reg_0x0347;
-	uint8_t reg_0x0348;
-	uint8_t reg_0x0349;
-	uint8_t reg_0x034A;
-	uint8_t reg_0x034B;
-};
-struct reg_struct_init{
-	uint8_t reg_0x302B;/* 0x302B*/
-
-	uint8_t reg_0x30E5;/* 0x30E5*/
-	uint8_t reg_0x3300;   /* 0x3300*/
-
-	uint8_t image_orient;   /* 0x0101*/
-
-	uint8_t reg_0x300A;   /* 0x300A*/
-	uint8_t reg_0x3014;   /* 0x3014*/
-	uint8_t reg_0x3015;   /* 0x3015*/
-	uint8_t reg_0x3017;   /* 0x3017*/
-	uint8_t reg_0x301C;   /* 0x301C*/
-	uint8_t reg_0x3031;   /* 0x3031*/
-	uint8_t reg_0x3040;   /* 0x3040*/
-	uint8_t reg_0x3041;   /* 0x3041*/
-	uint8_t reg_0x3051;   /* 0x3051*/
-	uint8_t reg_0x3053;   /* 0x3053*/
-	uint8_t reg_0x3055;   /* 0x3055*/
-	uint8_t reg_0x3057;   /* 0x3057*/
-	uint8_t reg_0x3060;   /* 0x3060*/
-	uint8_t reg_0x3065;   /* 0x3065*/
-	uint8_t reg_0x30AA;   /* 0x30AA*/
-	uint8_t reg_0x30AB;   /* 0x30AB*/
-	uint8_t reg_0x30B0;   /* 0x30B0*/
-	uint8_t reg_0x30B2;   /* 0x30B2*/
-
-	uint8_t reg_0x30D3;   /* 0X30D3*/
-	uint8_t reg_0x30D8;   /* 0X30D8*/
-
-	uint8_t reg_0x3106;   /* 0x3106*/
-	uint8_t reg_0x3108;   /* 0x3108*/
-	uint8_t reg_0x310A;   /* 0x310A*/
-	uint8_t reg_0x310C;   /* 0x310C*/
-	uint8_t reg_0x310E;   /* 0x310E*/
-	uint8_t reg_0x3126;   /* 0x3126*/
-	uint8_t reg_0x312E;   /* 0x312E*/
-	uint8_t reg_0x313C;   /* 0x313C*/
-	uint8_t reg_0x313E;   /* 0x313E*/
-	uint8_t reg_0x3140;   /* 0x3140*/
-	uint8_t reg_0x3142;   /* 0x3142*/
-	uint8_t reg_0x3144;   /* 0x3144*/
-	uint8_t reg_0x3148;   /* 0x3148*/
-	uint8_t reg_0x314A;   /* 0x314A*/
-	uint8_t reg_0x3166;   /* 0x3166*/
-	uint8_t reg_0x3168;   /* 0x3168*/
-	uint8_t reg_0x316F;   /* 0x316F*/
-	uint8_t reg_0x3171;   /* 0x3171*/
-	uint8_t reg_0x3173;   /* 0x3173*/
-	uint8_t reg_0x3175;   /* 0x3175*/
-	uint8_t reg_0x3177;   /* 0x3177*/
-	uint8_t reg_0x3179;   /* 0x3179*/
-	uint8_t reg_0x317B;   /* 0x317B*/
-	uint8_t reg_0x317D;   /* 0x317D*/
-	uint8_t reg_0x317F;   /* 0x317F*/
-	uint8_t reg_0x3181;   /* 0x3181*/
-	uint8_t reg_0x3184;   /* 0x3184*/
-	uint8_t reg_0x3185;   /* 0x3185*/
-	uint8_t reg_0x3187;   /* 0x3187*/
-
-	uint8_t reg_0x31A4;   /* 0x31A4*/
-	uint8_t reg_0x31A6;   /* 0x31A6*/
-	uint8_t reg_0x31AC;   /* 0x31AC*/
-	uint8_t reg_0x31AE;   /* 0x31AE*/
-	uint8_t reg_0x31B4;   /* 0x31B4*/
-	uint8_t reg_0x31B6;   /* 0x31B6*/
-
-	uint8_t reg_0x3254;   /* 0x3254*/
-	uint8_t reg_0x3256;   /* 0x3256*/
-	uint8_t reg_0x3258;   /* 0x3258*/
-	uint8_t reg_0x325A;   /* 0x325A*/
-	uint8_t reg_0x3260;   /* 0x3260*/
-	uint8_t reg_0x3262;   /* 0x3262*/
-
-	uint8_t reg_0x3304;   /* 0x3304*/
-	uint8_t reg_0x3305;   /* 0x3305*/
-	uint8_t reg_0x3306;   /* 0x3306*/
-	uint8_t reg_0x3307;   /* 0x3307*/
-	uint8_t reg_0x3308;   /* 0x3308*/
-	uint8_t reg_0x3309;   /* 0x3309*/
-	uint8_t reg_0x330A;   /* 0x330A*/
-	uint8_t reg_0x330B;   /* 0x330B*/
-	uint8_t reg_0x330C;   /* 0x330C*/
-	uint8_t reg_0x330D;   /* 0x330D*/
-
-};
-struct sn12m0pz_reg{
-	const struct reg_struct  *reg_pat;
-	const struct reg_struct_init  *reg_pat_init;
-};
-#endif
diff --git a/drivers/media/video/msm/sn12m0pz_reg.c b/drivers/media/video/msm/sn12m0pz_reg.c
deleted file mode 100644
index d21eac1..0000000
--- a/drivers/media/video/msm/sn12m0pz_reg.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. 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 "sn12m0pz.h"
-/* Initialisation settings */
-
-const struct reg_struct_init iu060f_reg_pat_init[1] = {{
-	/* PLL setting */
-	0x4B, /* reg 0x302B*/
-	/* MIPI Enable Setting */
-	0x04, /* reg 0x30E5*/
-	0x00, /* reg 0x3300*/
-	/* Global Setting */
-	0x00, /* image_orientation*/
-	0x80, /* reg 0x300A*/
-	0x08, /* reg 0x3014*/
-	0x37, /* reg 0x3015*/
-	0x60, /* reg 0x3017*/
-	0x01, /* reg 0x301C*/
-	0x28, /* reg 0x3031*/
-	0x00, /* reg 0x3040*/
-	0x60, /* reg 0x3041*/
-	0x24, /* reg 0x3051*/
-	0x34, /* reg 0x3053*/
-	0x3B, /* reg 0x3055*/
-	0xC0, /* reg 0x3057*/
-	0x30, /* reg 0x3060*/
-	0x00, /* reg 0x3065*/
-	0x88, /* reg 0x30AA*/
-	0x1C, /* reg 0x30AB*/
-	0x32, /* reg 0x30B0*/
-	0x83, /* reg 0x30B2*/
-	0x04, /* reg 0x30D3*/
-	0xC0, /* reg 0x30D8*/
-	0x50, /* reg 0x3106*/
-	0xA5, /* reg 0x3108*/
-	0xA9, /* reg 0x310A*/
-	0x0C, /* reg 0x310C*/
-	0x55, /* reg 0x310E*/
-	0xCC, /* reg 0x3126*/
-	0x83, /* reg 0x312E*/
-	0xC7, /* reg 0x313C*/
-	0x07, /* reg 0x313E*/
-	0x32, /* reg 0x3140*/
-	0x35, /* reg 0x3142*/
-	0x35, /* reg 0x3144*/
-	0x73, /* reg 0x3148*/
-	0x80, /* reg 0x314A*/
-	0xBE, /* reg 0x3166*/
-	0xBD, /* reg 0x3168*/
-	0x82, /* reg 0x316F*/
-	0xBC, /* reg 0x3171*/
-	0x82, /* reg 0x3173*/
-	0xBC, /* reg 0x3175*/
-	0x0C, /* reg 0x3177*/
-	0x2C, /* reg 0x3179*/
-	0x83, /* reg 0x317B*/
-	0xAF, /* reg 0x317D*/
-	0x83, /* reg 0x317F*/
-	0xAF, /* reg 0x3181*/
-	0x06, /* reg 0x3184*/
-	0xBA, /* reg 0x3185*/
-	0xBE, /* reg 0x3187*/
-	0xD8, /* reg 0x31A4*/
-	0x17, /* reg 0x31A6*/
-	0xCF, /* reg 0x31AC*/
-	0xF1, /* reg 0x31AE*/
-	0xD8, /* reg 0x31B4*/
-	0x17, /* reg 0x31B6*/
-	0x09, /* reg 0x3254 */
-	0xC5, /* reg 0x3256 */
-	0x84, /* reg 0x3258 */
-	0x6C, /* reg 0x325A */
-	0x0B, /* reg 0x3260 */
-	0x09, /* reg 0x3262 */
-	0x05, /* reg 0x3304*/
-	0x04, /* reg 0x3305*/
-	0x15, /* reg 0x3306*/
-	0x03, /* reg 0x3307*/
-	0x13, /* reg 0x3308*/
-	0x05, /* reg 0x3309*/
-	0x0B, /* reg 0x330A*/
-	0x04, /* reg 0x330B*/
-	0x0B, /* reg 0x330C*/
-	0x06  /* reg 0x330D*/
-}
-};
-
-/* Preview / Snapshot register settings */
-const struct reg_struct iu060f_reg_pat[3] = {
-	{ /* Preview */
-		0x22, /*0x1b*/ /* fps*/
-
-		/* Global Setting */
-		0x01, /* coarse_integration_time_msb*/
-		0xFF, /* coarse_integration_time_lsb*/
-
-		/* Mode Setting */
-		/* V: 1/2 V-addition (1,3),
-		H: 1/2 H-averaging (1,3) */
-
-		0x06, /* frame_length_lines_msb     0x0340*/
-		0x02, /* frame_length_lines_lsb     0x0341*/
-		0x10, /* line_length_pck_msb        0x0342*/
-		0x70, /* line_length_pck_lsb        0x0343*/
-		0x07, /* x_output_size_msb          0x034C*/
-		0xe0, /* x_output_size_lsb          0x034D*/
-		0x05, /* y_output_size_msb          0x034E*/
-		0xe8, /* y_output_size_lsb          0x034F*/
-		0x01, /* x_even_inc_lsb             0x0381*/
-		0x03, /* x_odd_inc_lsb              0x0383*/
-		0x01, /* y_even_inc_lsb             0x0385*/
-		0x03, /* y_odd_inc_lsb              0x0387*/
-		0x46, /* reg 0x3016 VMODEADD        0x3016*/
-		0x86, /* reg 0x30E8 HADDAVE         0x30E8*/
-		0x01, /* reg 0x3301 RGLANESEL       0x3301*/
-
-		0x00,  /* 0x0344 */
-		0x00,  /* 0x0345 */
-		0x00,  /* 0x0346 */
-		0x00,  /* 0x0347 */
-		0x0F,  /* 0x0348 */
-		0xBF,  /* 0x0349 */
-		0x0B,  /* 0x034A */
-		0xCF,  /* 0x034B */
-	},
-	{ /* Snapshot */
-		0x14, /* pll_multiplier_lsb    // 20/10 fps*/
-		/* 0x14 for pclk 96MHz at 7.5 fps */
-
-		/* Global Setting */
-		0x0B, /* coarse_integration_time_msb*/
-		0xFF, /* coarse_integration_time_lsb*/
-
-		/* Mode Setting */
-		/* Full */
-		0x0C,/*frame_length_lines_msb 0x0340*/
-		0x02,/*frame_length_lines_lsb 0x0341*/
-		0x10,/*line_length_pck_msb 0x0342*/
-		0x70,/* line_length_pck_lsb 0x0343*/
-		0x0F,/* x_output_size_msb   0x034C*/
-		0xC0, /* x_output_size_lsb  0x034D*/
-		0x0B, /* y_output_size_msb  0x034E*/
-		0xD0, /* y_output_size_lsb  0x034F*/
-		0x01, /* x_even_inc_lsb     0x0381*/
-		0x01, /* x_odd_inc_lsb      0x0383*/
-		0x01, /* y_even_inc_lsb                     0x0385*/
-		0x01, /* y_odd_inc_lsb                      0x0387*/
-		0x06, /* reg 0x3016 VMODEADD                0x3016*/
-		0x06, /* reg 0x30E8 HADDAVE                 0x30E8*/
-		0x00, /* reg 0x3301 RGLANESEL               0x3301*/
-
-		0x00,  /* 0x0344 */
-		0x00,  /* 0x0345 */
-		0x00,  /* 0x0346 */
-		0x00,  /* 0x0347 */
-		0x0F,  /* 0x0348 */
-		0xBF,  /* 0x0349 */
-		0x0B,  /* 0x034A */
-		0xCF,  /* 0x034B */
-	},
-	/* 120 fps settings */
-	{
-		0x1B, /*0x1B fps*/
-		/* Global Setting */
-		0x00, /* coarse_integration_time_msb*/
-		0xFE, /* coarse_integration_time_lsb*/
-
-		/* Mode Setting */
-		/* V: 1/8 V-addition (9,7),
-		H: Full */
-
-		0x01, /* frame_length_lines_msb     0x0340*/
-		0x01, /* frame_length_lines_lsb     0x0341*/
-		0x10, /* line_length_pck_msb        0x0342*/
-		0x70, /* line_length_pck_lsb        0x0343*/
-		0x0f, /* x_output_size_msb          0x034C*/
-		0xc0, /* x_output_size_lsb          0x034D*/
-		0x00, /* y_output_size_msb          0x034E*/
-		0xF8, /* y_output_size_lsb          0x034F*/
-		0x01, /* x_even_inc_lsb             0x0381*/
-		0x01, /* x_odd_inc_lsb              0x0383*/
-		0x09, /* y_even_inc_lsb             0x0385*/
-		0x07, /* y_odd_inc_lsb              0x0387*/
-		0x46, /* reg 0x3016 VMODEADD        0x3016*/
-		0x86, /* reg 0x30E8 HADDAVE         0x30E8*/
-		0x00, /* reg 0x3301 RGLANESEL       0x3301*/
-		/* add for 120fps support */
-		0x00, /* 0x0344*/
-		0x00, /* 0x0345*/
-		0x02, /* 0x0346*/
-		0x10, /* 0x0347*/
-		0x0F, /* 0x0348*/
-		0xBF, /* 0x0349*/
-		0x09, /* 0x034A*/
-		0xCF, /* 0x034B*/
-	}
-};
-struct sn12m0pz_reg sn12m0pz_regs = {
-	.reg_pat = &iu060f_reg_pat[0],
-	.reg_pat_init = &iu060f_reg_pat_init[0],
-};
-
diff --git a/drivers/media/video/msm/vb6801.c b/drivers/media/video/msm/vb6801.c
deleted file mode 100644
index fa82570..0000000
--- a/drivers/media/video/msm/vb6801.c
+++ /dev/null
@@ -1,1616 +0,0 @@
-/* Copyright (c) 2009, Code Aurora Forum. 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/delay.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <media/msm_camera.h>
-#include <mach/gpio.h>
-#include <mach/camera.h>
-#include "vb6801.h"
-
-/*=============================================================
-	SENSOR REGISTER DEFINES
-==============================================================*/
-enum {
-	REG_HOLD = 0x0104,
-	RELEASE_HOLD = 0x0000,
-	HOLD = 0x0001,
-	STANDBY_MODE = 0x0000,
-	REG_COARSE_INTEGRATION_TIME = 0x0202,
-	REG_ANALOGUE_GAIN_CODE_GLOBAL = 0x0204,
-	REG_RAMP_SCALE = 0x3116,
-	REG_POWER_MAN_ENABLE_3 = 0x3142,
-	REG_POWER_MAN_ENABLE_4 = 0x3143,
-	REG_POWER_MAN_ENABLE_5 = 0x3144,
-	REG_CCP2_DATA_FORMAT = 0x0112,
-	REG_PRE_PLL_CLK_DIV = 0x0304,
-	REG_PLL_MULTIPLIER = 0x0306,
-	REG_VT_SYS_CLK_DIV = 0x0302,
-	REG_VT_PIX_CLK_DIV = 0x0300,
-	REG_OP_SYS_CLK_DIV = 0x030A,
-	REG_OP_PIX_CLK_DIV = 0x0308,
-	REG_VT_LINE_LENGTH_PCK = 0x0342,
-	REG_X_OUTPUT_SIZE = 0x034C,
-	REG_Y_OUTPUT_SIZE = 0x034E,
-	REG_X_ODD_INC = 0x0382,
-	REG_Y_ODD_INC = 0x0386,
-	REG_VT_FRAME_LENGTH_LINES = 0x0340,
-	REG_ANALOG_TIMING_MODES_2 = 0x3113,
-	REG_BRUCE_ENABLE = 0x37B0,
-	REG_OP_CODER_SYNC_CLK_SETUP = 0x3400,
-	REG_OP_CODER_ENABLE = 0x3401,
-	REG_OP_CODER_SLOW_PAD_EN = 0x3402,
-	REG_OP_CODER_AUTO_STARTUP = 0x3414,
-	REG_SCYTHE_ENABLE = 0x3204,
-	REG_SCYTHE_WEIGHT = 0x3206,
-	REG_FRAME_COUNT = 0x0005,
-	REG_MODE_SELECT = 0x0100,
-	REG_CCP2_CHANNEL_IDENTIFIER = 0x0110,
-	REG_CCP2_SIGNALLING_MODE = 0x0111,
-	REG_BTL_LEVEL_SETUP = 0x311B,
-	REG_OP_CODER_AUTOMATIC_MODE_ENABLE = 0x3403,
-	REG_PLL_CTRL = 0x3801,
-	REG_VCM_DAC_CODE = 0x3860,
-	REG_VCM_DAC_STROBE = 0x3868,
-	REG_VCM_DAC_ENABLE = 0x386C,
-	REG_NVM_T1_ADDR_00 = 0x3600,
-	REG_NVM_T1_ADDR_01 = 0x3601,
-	REG_NVM_T1_ADDR_02 = 0x3602,
-	REG_NVM_T1_ADDR_03 = 0x3603,
-	REG_NVM_T1_ADDR_04 = 0x3604,
-	REG_NVM_T1_ADDR_05 = 0x3605,
-	REG_NVM_T1_ADDR_06 = 0x3606,
-	REG_NVM_T1_ADDR_07 = 0x3607,
-	REG_NVM_T1_ADDR_08 = 0x3608,
-	REG_NVM_T1_ADDR_09 = 0x3609,
-	REG_NVM_T1_ADDR_0A = 0x360A,
-	REG_NVM_T1_ADDR_0B = 0x360B,
-	REG_NVM_T1_ADDR_0C = 0x360C,
-	REG_NVM_T1_ADDR_0D = 0x360D,
-	REG_NVM_T1_ADDR_0E = 0x360E,
-	REG_NVM_T1_ADDR_0F = 0x360F,
-	REG_NVM_T1_ADDR_10 = 0x3610,
-	REG_NVM_T1_ADDR_11 = 0x3611,
-	REG_NVM_T1_ADDR_12 = 0x3612,
-	REG_NVM_T1_ADDR_13 = 0x3613,
-	REG_NVM_CTRL = 0x3680,
-	REG_NVM_PDN = 0x3681,
-	REG_NVM_PULSE_WIDTH = 0x368B,
-};
-
-#define VB6801_LINES_PER_FRAME_PREVIEW   800
-#define VB6801_LINES_PER_FRAME_SNAPSHOT 1600
-#define VB6801_PIXELS_PER_LINE_PREVIEW  2500
-#define VB6801_PIXELS_PER_LINE_SNAPSHOT 2500
-
-/* AF constant */
-#define VB6801_TOTAL_STEPS_NEAR_TO_FAR    25
-#define VB6801_STEPS_NEAR_TO_CLOSEST_INF  25
-
-/* for 30 fps preview */
-#define VB6801_DEFAULT_CLOCK_RATE    12000000
-
-enum vb6801_test_mode_t {
-	TEST_OFF,
-	TEST_1,
-	TEST_2,
-	TEST_3
-};
-
-enum vb6801_resolution_t {
-	QTR_SIZE,
-	FULL_SIZE,
-	INVALID_SIZE
-};
-
-enum vb6801_setting_t {
-	RES_PREVIEW,
-	RES_CAPTURE
-};
-
-struct vb6801_work_t {
-	struct work_struct work;
-};
-
-struct sensor_dynamic_params_t {
-	uint16_t preview_pixelsPerLine;
-	uint16_t preview_linesPerFrame;
-	uint16_t snapshot_pixelsPerLine;
-	uint16_t snapshot_linesPerFrame;
-	uint8_t snapshot_changed_fps;
-	uint32_t pclk;
-};
-
-struct vb6801_sensor_info {
-	/* Sensor Configuration Input Parameters */
-	uint32_t ext_clk_freq_mhz;
-	uint32_t target_frame_rate_fps;
-	uint32_t target_vt_pix_clk_freq_mhz;
-	uint32_t sub_sampling_factor;
-	uint32_t analog_binning_allowed;
-	uint32_t raw_mode;
-	uint32_t capture_mode;
-
-	/* Image Readout Registers */
-	uint32_t x_odd_inc;	/* x pixel array addressing odd increment */
-	uint32_t y_odd_inc;	/* y pixel array addressing odd increment */
-	uint32_t x_output_size;	/* width of output image  */
-	uint32_t y_output_size;	/* height of output image */
-
-	/* Declare data format */
-	uint32_t ccp2_data_format;
-
-	/* Clock Tree Registers */
-	uint32_t pre_pll_clk_div;
-	uint32_t pll_multiplier;
-	uint32_t vt_sys_clk_div;
-	uint32_t vt_pix_clk_div;
-	uint32_t op_sys_clk_div;
-	uint32_t op_pix_clk_div;
-
-	/* Video Timing Registers */
-	uint32_t vt_line_length_pck;
-	uint32_t vt_frame_length_lines;
-
-	/* Analogue Binning Registers */
-	uint8_t vtiming_major;
-	uint8_t analog_timing_modes_4;
-
-	/* Fine (pixel) Integration Time Registers */
-	uint32_t fine_integration_time;
-
-	/* Coarse (lines) Integration Time Limit Registers */
-	uint32_t coarse_integration_time_max;
-
-	/* Coarse (lines) Integration Timit Register (16-bit) */
-	uint32_t coarse_integration_time;
-
-	/* Analogue Gain Code Global Registers */
-	uint32_t analogue_gain_code_global;
-
-	/* Digital Gain Code Registers */
-	uint32_t digital_gain_code;
-
-	/* Overall gain (analogue & digital) code
-	 * Note that this is not a real register but just
-	 * an abstraction for the combination of analogue
-	 * and digital gain */
-	uint32_t gain_code;
-
-	/* FMT Test Information */
-	uint32_t pass_fail;
-	uint32_t day;
-	uint32_t month;
-	uint32_t year;
-	uint32_t tester;
-	uint32_t part_number;
-
-	/* Autofocus controls */
-	uint32_t vcm_dac_code;
-	int vcm_max_dac_code_step;
-	int vcm_proportional_factor;
-	int vcm_dac_code_spacing_ms;
-
-	/* VCM NVM Characterisation Information */
-	uint32_t vcm_dac_code_infinity_dn;
-	uint32_t vcm_dac_code_macro_up;
-	uint32_t vcm_dac_code_up_dn_delta;
-
-	/* Internal Variables */
-	uint32_t min_vt_frame_length_lines;
-};
-
-struct vb6801_work_t *vb6801_sensorw;
-struct i2c_client *vb6801_client;
-
-struct vb6801_ctrl_t {
-	const struct msm_camera_sensor_info *sensordata;
-
-	int sensormode;
-	uint32_t factor_fps;	/* init to 1 * 0x00000400 */
-	uint16_t curr_fps;
-	uint16_t max_fps;
-	int8_t pict_exp_update;
-	int8_t reducel;
-	uint16_t curr_lens_pos;
-	uint16_t init_curr_lens_pos;
-	enum vb6801_resolution_t prev_res;
-	enum vb6801_resolution_t pict_res;
-	enum vb6801_resolution_t curr_res;
-	enum vb6801_test_mode_t set_test;
-
-	struct vb6801_sensor_info s_info;
-	struct sensor_dynamic_params_t s_dynamic_params;
-};
-
-static struct vb6801_ctrl_t *vb6801_ctrl;
-static DECLARE_WAIT_QUEUE_HEAD(vb6801_wait_queue);
-DEFINE_MUTEX(vb6801_mut);
-
-static int vb6801_i2c_rxdata(unsigned short saddr,
-			     unsigned char *rxdata, int length)
-{
-	struct i2c_msg msgs[] = {
-		{
-			.addr = saddr,
-			.flags = 0,
-			.len = 2,
-			.buf = rxdata,
-		},
-		{
-			.addr = saddr,
-			.flags = I2C_M_RD,
-			.len = 2,
-			.buf = rxdata,
-		},
-	};
-
-	if (i2c_transfer(vb6801_client->adapter, msgs, 2) < 0) {
-		CDBG("vb6801_i2c_rxdata failed!\n");
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int32_t vb6801_i2c_read(unsigned short raddr,
-			       unsigned short *rdata, int rlen)
-{
-	int32_t rc = 0;
-	unsigned char buf[2];
-
-	if (!rdata)
-		return -EIO;
-
-	memset(buf, 0, sizeof(buf));
-
-	buf[0] = (raddr & 0xFF00) >> 8;
-	buf[1] = (raddr & 0x00FF);
-
-	rc = vb6801_i2c_rxdata(vb6801_client->addr, buf, rlen);
-
-	if (rc < 0) {
-		CDBG("vb6801_i2c_read 0x%x failed!\n", raddr);
-		return rc;
-	}
-
-	*rdata = (rlen == 2 ? buf[0] << 8 | buf[1] : buf[0]);
-
-	return rc;
-}
-
-static int32_t vb6801_i2c_read_table(struct vb6801_i2c_reg_conf_t *regs,
-				     int items)
-{
-	int i;
-	int32_t rc = -EFAULT;
-
-	for (i = 0; i < items; i++) {
-		unsigned short *buf =
-		    regs->dlen == D_LEN_BYTE ?
-		    (unsigned short *)&regs->bdata :
-		    (unsigned short *)&regs->wdata;
-		rc = vb6801_i2c_read(regs->waddr, buf, regs->dlen + 1);
-
-		if (rc < 0) {
-			CDBG("vb6801_i2c_read_table Failed!!!\n");
-			break;
-		}
-
-		regs++;
-	}
-
-	return rc;
-}
-
-static int32_t vb6801_i2c_txdata(unsigned short saddr,
-				 unsigned char *txdata, int length)
-{
-	struct i2c_msg msg[] = {
-		{
-			.addr = saddr,
-			.flags = 0,
-			.len = length,
-			.buf = txdata,
-		},
-	};
-
-	if (i2c_transfer(vb6801_client->adapter, msg, 1) < 0) {
-		CDBG("vb6801_i2c_txdata faild 0x%x\n", vb6801_client->addr);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int32_t vb6801_i2c_write_b(unsigned short waddr, uint8_t bdata)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[3];
-
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (waddr & 0xFF00) >> 8;
-	buf[1] = (waddr & 0x00FF);
-	buf[2] = bdata;
-
-	CDBG("i2c_write_b addr = %d, val = %d\n", waddr, bdata);
-	rc = vb6801_i2c_txdata(vb6801_client->addr, buf, 3);
-
-	if (rc < 0) {
-		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
-		     waddr, bdata);
-	}
-
-	return rc;
-}
-
-static int32_t vb6801_i2c_write_w(unsigned short waddr, unsigned short wdata)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[4];
-
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (waddr & 0xFF00) >> 8;
-	buf[1] = (waddr & 0x00FF);
-	buf[2] = (wdata & 0xFF00) >> 8;
-	buf[3] = (wdata & 0x00FF);
-
-	CDBG("i2c_write_w addr = %d, val = %d, buf[2] = 0x%x, buf[3] = 0x%x\n",
-	     waddr, wdata, buf[2], buf[3]);
-
-	rc = vb6801_i2c_txdata(vb6801_client->addr, buf, 4);
-	if (rc < 0) {
-		CDBG("i2c_write_w failed, addr = 0x%x, val = 0x%x!\n",
-		     waddr, wdata);
-	}
-
-	return rc;
-}
-
-static int32_t vb6801_i2c_write_table(struct vb6801_i2c_reg_conf_t *regs,
-				      int items)
-{
-	int i;
-	int32_t rc = -EFAULT;
-
-	for (i = 0; i < items; i++) {
-		rc = ((regs->dlen == D_LEN_BYTE) ?
-		      vb6801_i2c_write_b(regs->waddr, regs->bdata) :
-		      vb6801_i2c_write_w(regs->waddr, regs->wdata));
-
-		if (rc < 0) {
-			CDBG("vb6801_i2c_write_table Failed!!!\n");
-			break;
-		}
-
-		regs++;
-	}
-
-	return rc;
-}
-
-static int32_t vb6801_reset(const struct msm_camera_sensor_info *data)
-{
-	int rc;
-
-	rc = gpio_request(data->sensor_reset, "vb6801");
-	if (!rc) {
-		CDBG("sensor_reset SUcceeded\n");
-		gpio_direction_output(data->sensor_reset, 0);
-		mdelay(50);
-		gpio_direction_output(data->sensor_reset, 1);
-		mdelay(13);
-	} else
-		CDBG("sensor_reset FAiled\n");
-
-	return rc;
-}
-
-static int32_t vb6801_set_default_focus(void)
-{
-	int32_t rc = 0;
-
-	/* FIXME: Default focus not supported */
-
-	return rc;
-}
-
-static void vb6801_get_pict_fps(uint16_t fps, uint16_t *pfps)
-{
-	/* input fps is preview fps in Q8 format */
-	uint32_t divider; /*Q10 */
-	uint32_t pclk_mult; /*Q10 */
-	uint32_t d1;
-	uint32_t d2;
-
-	d1 =
-		(uint32_t)(
-		(vb6801_ctrl->s_dynamic_params.preview_linesPerFrame *
-		0x00000400) /
-		vb6801_ctrl->s_dynamic_params.snapshot_linesPerFrame);
-
-	d2 =
-		(uint32_t)(
-		(vb6801_ctrl->s_dynamic_params.preview_pixelsPerLine *
-		0x00000400) /
-		vb6801_ctrl->s_dynamic_params.snapshot_pixelsPerLine);
-
-
-	divider = (uint32_t) (d1 * d2) / 0x00000400;
-
-	pclk_mult = (48 * 0x400) / 60;
-
-	/* Verify PCLK settings and frame sizes. */
-	*pfps = (uint16_t)((((fps * pclk_mult) / 0x00000400) * divider)/
-				0x00000400);
-}
-
-static uint16_t vb6801_get_prev_lines_pf(void)
-{
-	if (vb6801_ctrl->prev_res == QTR_SIZE)
-		return vb6801_ctrl->s_dynamic_params.preview_linesPerFrame;
-	else
-		return vb6801_ctrl->s_dynamic_params.snapshot_linesPerFrame;
-}
-
-static uint16_t vb6801_get_prev_pixels_pl(void)
-{
-	if (vb6801_ctrl->prev_res == QTR_SIZE)
-		return vb6801_ctrl->s_dynamic_params.preview_pixelsPerLine;
-	else
-		return vb6801_ctrl->s_dynamic_params.snapshot_pixelsPerLine;
-}
-
-static uint16_t vb6801_get_pict_lines_pf(void)
-{
-	return vb6801_ctrl->s_dynamic_params.snapshot_linesPerFrame;
-}
-
-static uint16_t vb6801_get_pict_pixels_pl(void)
-{
-	return vb6801_ctrl->s_dynamic_params.snapshot_pixelsPerLine;
-}
-
-static uint32_t vb6801_get_pict_max_exp_lc(void)
-{
-	uint16_t snapshot_lines_per_frame;
-
-	if (vb6801_ctrl->pict_res == QTR_SIZE) {
-		snapshot_lines_per_frame =
-		    vb6801_ctrl->s_dynamic_params.preview_linesPerFrame - 3;
-	} else {
-		snapshot_lines_per_frame =
-		    vb6801_ctrl->s_dynamic_params.snapshot_linesPerFrame - 3;
-	}
-
-	return snapshot_lines_per_frame;
-}
-
-static int32_t vb6801_set_fps(struct fps_cfg *fps)
-{
-	int32_t rc = 0;
-
-	/* input is new fps in Q8 format */
-	switch (fps->fps_div) {
-	case 7680:		/* 30 * Q8 */
-		vb6801_ctrl->factor_fps = 1;
-		break;
-
-	case 3840:		/* 15 * Q8 */
-		vb6801_ctrl->factor_fps = 2;
-		break;
-
-	case 2560:		/* 10 * Q8 */
-		vb6801_ctrl->factor_fps = 3;
-		break;
-
-	case 1920:		/* 7.5 * Q8 */
-		vb6801_ctrl->factor_fps = 4;
-		break;
-
-	default:
-		rc = -ENODEV;
-		break;
-	}
-
-	return rc;
-}
-
-static int32_t vb6801_write_exp_gain(uint16_t gain, uint32_t line)
-{
-	int32_t rc = 0;
-	uint16_t lpf;
-
-	if (vb6801_ctrl->curr_res == SENSOR_FULL_SIZE)
-		lpf = VB6801_LINES_PER_FRAME_SNAPSHOT;
-	else
-		lpf = VB6801_LINES_PER_FRAME_PREVIEW;
-
-	/* hold */
-	rc = vb6801_i2c_write_w(REG_HOLD, HOLD);
-	if (rc < 0)
-		goto exp_gain_done;
-
-	if ((vb6801_ctrl->curr_fps <
-	     vb6801_ctrl->max_fps / vb6801_ctrl->factor_fps) &&
-	    (!vb6801_ctrl->pict_exp_update)) {
-
-		if (vb6801_ctrl->reducel) {
-
-			rc = vb6801_i2c_write_w(REG_VT_FRAME_LENGTH_LINES,
-						lpf * vb6801_ctrl->factor_fps);
-
-			vb6801_ctrl->curr_fps =
-			    vb6801_ctrl->max_fps / vb6801_ctrl->factor_fps;
-
-		} else if (!vb6801_ctrl->reducel) {
-
-			rc = vb6801_i2c_write_w(REG_COARSE_INTEGRATION_TIME,
-						line * vb6801_ctrl->factor_fps);
-
-			vb6801_ctrl->reducel = 1;
-		}
-	} else if ((vb6801_ctrl->curr_fps >
-		    vb6801_ctrl->max_fps / vb6801_ctrl->factor_fps) &&
-		   (!vb6801_ctrl->pict_exp_update)) {
-
-		rc = vb6801_i2c_write_w(REG_VT_FRAME_LENGTH_LINES,
-					lpf * vb6801_ctrl->factor_fps);
-
-		vb6801_ctrl->curr_fps =
-		    vb6801_ctrl->max_fps / vb6801_ctrl->factor_fps;
-
-	} else {
-		/* analogue_gain_code_global */
-		rc = vb6801_i2c_write_w(REG_ANALOGUE_GAIN_CODE_GLOBAL, gain);
-		if (rc < 0)
-			goto exp_gain_done;
-
-		/* coarse_integration_time */
-		rc = vb6801_i2c_write_w(REG_COARSE_INTEGRATION_TIME,
-					line * vb6801_ctrl->factor_fps);
-		if (rc < 0)
-			goto exp_gain_done;
-
-		vb6801_ctrl->pict_exp_update = 1;
-	}
-
-	rc = vb6801_i2c_write_w(REG_HOLD, RELEASE_HOLD);
-
-exp_gain_done:
-	return rc;
-}
-
-static int32_t vb6801_set_pict_exp_gain(uint16_t gain, uint32_t line)
-{
-	vb6801_ctrl->pict_exp_update = 1;
-	return vb6801_write_exp_gain(gain, line);
-}
-
-static int32_t vb6801_power_down(void)
-{
-	int32_t rc = 0;
-	rc = vb6801_i2c_write_b(REG_NVM_PDN, 0);
-
-	mdelay(5);
-	return rc;
-}
-
-static int32_t vb6801_go_to_position(uint32_t target_vcm_dac_code,
-				     struct vb6801_sensor_info *ps)
-{
-	/* Prior to running this function the following values must
-	 * be initialised in the sensor data structure, PS
-	 * ps->vcm_dac_code
-	 * ps->vcm_max_dac_code_step
-	 * ps->vcm_dac_code_spacing_ms */
-
-	int32_t rc = 0;
-
-	ps->vcm_dac_code = target_vcm_dac_code;
-
-	/* Restore Strobe to zero state */
-	rc = vb6801_i2c_write_b(REG_VCM_DAC_STROBE, 0x00);
-	if (rc < 0)
-		return rc;
-
-	/* Write 9-bit VCM DAC Code */
-	rc = vb6801_i2c_write_w(REG_VCM_DAC_CODE, ps->vcm_dac_code);
-	if (rc < 0)
-		return rc;
-
-	/* Generate a rising edge on the dac_strobe to latch
-	 * new DAC value */
-
-	rc = vb6801_i2c_write_w(REG_VCM_DAC_STROBE, 0x01);
-
-	return rc;
-}
-
-static int32_t vb6801_move_focus(int direction, int32_t num_steps)
-{
-	int16_t step_direction;
-	int16_t actual_step;
-	int16_t next_position;
-	uint32_t step_size;
-	int16_t small_move[4];
-	uint16_t i;
-	int32_t rc = 0;
-
-	step_size = (vb6801_ctrl->s_info.vcm_dac_code_macro_up -
-		     vb6801_ctrl->s_info.vcm_dac_code_infinity_dn) /
-	    VB6801_TOTAL_STEPS_NEAR_TO_FAR;
-
-	if (num_steps > VB6801_TOTAL_STEPS_NEAR_TO_FAR)
-		num_steps = VB6801_TOTAL_STEPS_NEAR_TO_FAR;
-	else if (num_steps == 0)
-		return -EINVAL;
-
-	if (direction == MOVE_NEAR)
-		step_direction = 4;
-	else if (direction == MOVE_FAR)
-		step_direction = -4;
-	else
-		return -EINVAL;
-
-	/* need to decide about default position and power supplied
-	 * at start up and reset */
-	if (vb6801_ctrl->curr_lens_pos < vb6801_ctrl->init_curr_lens_pos)
-		vb6801_ctrl->curr_lens_pos = vb6801_ctrl->init_curr_lens_pos;
-
-	actual_step = (step_direction * num_steps);
-
-	next_position = vb6801_ctrl->curr_lens_pos;
-
-	for (i = 0; i < 4; i++) {
-		if (actual_step >= 0)
-			small_move[i] =
-			    (i + 1) * actual_step / 4 - i * actual_step / 4;
-
-		if (actual_step < 0)
-			small_move[i] =
-			    (i + 1) * actual_step / 4 - i * actual_step / 4;
-	}
-
-	if (next_position > 511)
-		next_position = 511;
-	else if (next_position < 0)
-		next_position = 0;
-
-	/* for damping */
-	for (i = 0; i < 4; i++) {
-		next_position =
-		    (int16_t) (vb6801_ctrl->curr_lens_pos + small_move[i]);
-
-		/* Writing the digital code for current to the actuator */
-		CDBG("next_position in damping mode = %d\n", next_position);
-
-		rc = vb6801_go_to_position(next_position, &vb6801_ctrl->s_info);
-		if (rc < 0) {
-			CDBG("go_to_position Failed!!!\n");
-			return rc;
-		}
-
-		vb6801_ctrl->curr_lens_pos = next_position;
-		if (i < 3)
-			mdelay(5);
-	}
-
-	return rc;
-}
-
-static int vb6801_read_nvm_data(struct vb6801_sensor_info *ps)
-{
-	/* +--------+------+------+----------------+---------------+
-	 * | Index | NVM | NVM | Name | Description |
-	 * | | Addr | Byte | | |
-	 * +--------+------+------+----------------+---------------+
-	 * | 0x3600 | 0 | 3 | nvm_t1_addr_00 | {PF[2:0]:Day[4:0]} |
-	 * | 0x3601 | 0 | 2 | nvm_t1_addr_01 | {Month[3:0]:Year[3:0]} |
-	 * | 0x3602 | 0 | 1 | nvm_t1_addr_02 | Tester[7:0] |
-	 * | 0x3603 | 0 | 0 | nvm_t1_addr_03 | Part[15:8] |
-	 * +--------+------+------+----------------+---------------+
-	 * | 0x3604 | 1 | 3 | nvm_t1_addr_04 | Part[7:0] |
-	 * | 0x3605 | 1 | 2 | nvm_t1_addr_05 | StartWPM[7:0] |
-	 * | 0x3606 | 1 | 1 | nvm_t1_addr_06 | Infinity[7:0] |
-	 * | 0x3607 | 1 | 0 | nvm_t1_addr_07 | Macro[7:0] |
-	 * +--------+------+------+----------------+---------------+
-	 * | 0x3608 | 2 | 3 | nvm_t1_addr_08 | Reserved |
-	 * | 0x3609 | 2 | 2 | nvm_t1_addr_09 | Reserved |
-	 * | 0x360A | 2 | 1 | nvm_t1_addr_0A | UpDown[7:0] |
-	 * | 0x360B | 2 | 0 | nvm_t1_addr_0B | Reserved |
-	 * +--------+------+------+----------------+---------------+
-	 * | 0x360C | 3 | 3 | nvm_t1_addr_0C | Reserved |
-	 * | 0x360D | 3 | 2 | nvm_t1_addr_0D | Reserved |
-	 * | 0x360E | 3 | 1 | nvm_t1_addr_0E | Reserved |
-	 * | 0x360F | 3 | 0 | nvm_t1_addr_0F | Reserved |
-	 * +--------+------+------+----------------+---------------+
-	 * | 0x3610 | 4 | 3 | nvm_t1_addr_10 | Reserved |
-	 * | 0x3611 | 4 | 2 | nvm_t1_addr_11 | Reserved |
-	 * | 0x3612 | 4 | 1 | nvm_t1_addr_12 | Reserved |
-	 * | 0x3613 | 4 | 0 | nvm_t1_addr_13 | Reserved |
-	 * +--------+------+------+----------------+---------------+*/
-
-	int32_t rc;
-	struct vb6801_i2c_reg_conf_t rreg[] = {
-		{REG_NVM_T1_ADDR_00, 0, 0, D_LEN_BYTE},
-		{REG_NVM_T1_ADDR_01, 0, 0, D_LEN_BYTE},
-		{REG_NVM_T1_ADDR_02, 0, 0, D_LEN_BYTE},
-		{REG_NVM_T1_ADDR_03, 0, 0, D_LEN_BYTE},
-		{REG_NVM_T1_ADDR_04, 0, 0, D_LEN_BYTE},
-		{REG_NVM_T1_ADDR_05, 0, 0, D_LEN_BYTE},
-		{REG_NVM_T1_ADDR_06, 0, 0, D_LEN_BYTE},
-		{REG_NVM_T1_ADDR_07, 0, 0, D_LEN_BYTE},
-		{REG_NVM_T1_ADDR_08, 0, 0, D_LEN_BYTE},
-		{REG_NVM_T1_ADDR_09, 0, 0, D_LEN_BYTE},
-		{REG_NVM_T1_ADDR_0A, 0, 0, D_LEN_BYTE},
-		{REG_NVM_T1_ADDR_0B, 0, 0, D_LEN_BYTE},
-		{REG_NVM_T1_ADDR_0C, 0, 0, D_LEN_BYTE},
-		{REG_NVM_T1_ADDR_0D, 0, 0, D_LEN_BYTE},
-		{REG_NVM_T1_ADDR_0E, 0, 0, D_LEN_BYTE},
-		{REG_NVM_T1_ADDR_0F, 0, 0, D_LEN_BYTE},
-		{REG_NVM_T1_ADDR_10, 0, 0, D_LEN_BYTE},
-		{REG_NVM_T1_ADDR_11, 0, 0, D_LEN_BYTE},
-		{REG_NVM_T1_ADDR_12, 0, 0, D_LEN_BYTE},
-		{REG_NVM_T1_ADDR_13, 0, 0, D_LEN_BYTE},
-	};
-
-	struct vb6801_i2c_reg_conf_t wreg[] = {
-		/* Enable NVM for Direct Reading */
-		{REG_NVM_CTRL, 0, 2, D_LEN_BYTE},
-
-		/* Power up NVM */
-		{REG_NVM_PDN, 0, 1, D_LEN_BYTE},
-	};
-
-	rc = vb6801_i2c_write_table(wreg, ARRAY_SIZE(wreg));
-	if (rc < 0) {
-		CDBG("I2C Write Table FAILED!!!\n");
-		return rc;
-	}
-
-	/* NVM Read Pulse Width
-	 * ====================
-	 * nvm_pulse_width_us = nvm_pulse_width_ext_clk / ext_clk_freq_mhz
-	 * Valid Range for Read Pulse Width = 400ns -> 3.0us
-	 * Min ext_clk_freq_mhz = 6MHz  => 3.0 *  6  = 18
-	 * Max ext_clk_freq_mhz = 27MHz => 0.4 * 27 = 10.8
-	 * Choose 15 as a common value
-	 *  - 15 /  6.0 = 2.5000us
-	 *  - 15 / 12.0 = 1.2500us
-	 *  - 15 / 27.0 = 0.5555us */
-	rc = vb6801_i2c_write_w(REG_NVM_PULSE_WIDTH, 15);
-	if (rc < 0) {
-		rc = -EBUSY;
-		goto nv_shutdown;
-	}
-
-	rc = vb6801_i2c_read_table(rreg, ARRAY_SIZE(rreg));
-	if (rc < 0) {
-		CDBG("I2C Read Table FAILED!!!\n");
-		rc = -EBUSY;
-		goto nv_shutdown;
-	}
-
-	/* Decode and Save FMT Info */
-	ps->pass_fail = (rreg[0].bdata & 0x00E0) >> 5;
-	ps->day = (rreg[0].bdata & 0x001F);
-	ps->month = (rreg[1].bdata & 0x00F0) >> 4;
-	ps->year = (rreg[1].bdata & 0x000F) + 2000;
-	ps->tester = rreg[2].bdata;
-	ps->part_number = (rreg[3].bdata << 8) + rreg[4].bdata;
-
-	/* Decode and Save VCM Dac Values in data structure */
-	ps->vcm_dac_code_infinity_dn = rreg[6].bdata;
-	ps->vcm_dac_code_macro_up = rreg[7].bdata << 1;
-	ps->vcm_dac_code_up_dn_delta = rreg[10].bdata;
-
-nv_shutdown:
-	/* Power Down NVM to extend life time */
-	rc = vb6801_i2c_write_b(REG_NVM_PDN, 0);
-
-	return rc;
-}
-
-static int vb6801_config_sensor(int32_t ext_clk_freq_mhz,
-				int32_t target_frame_rate_fps,
-				int32_t target_vt_pix_clk_freq_mhz,
-				uint32_t sub_sampling_factor,
-				uint32_t analog_binning_allowed,
-				uint32_t raw_mode, int capture_mode,
-				enum vb6801_resolution_t res)
-{
-	uint32_t rc;
-	/* ext_clk_freq_mhz      = 6.0 -> 27.0 MHz
-	 * target_frame_rate_fps  = 15 fps
-	 * target_vt_pix_clk_freq_mhz = 24.0 -> 64.0MHz
-	 * sub_sampling factor   = 1, 2, 3, or 4
-	 * raw_mode factor       = 10
-	 *
-	 * capture_mode, 0 = CCP1
-	 * capture_mode, 1 = CCP2
-	 * capture_mode, 2 = 10-bit parallel + hsync + vsync */
-
-	/* Declare data format */
-	uint32_t ccp2_data_format = 0x0A0A;
-
-	/*  Declare clock tree variables */
-	int32_t min_pll_ip_freq_mhz = 6;
-	int32_t max_pll_op_freq_mhz = 640;
-	uint32_t pre_pll_clk_div = 1;
-	int32_t pll_ip_freq_mhz = 6;
-	uint32_t pll_multiplier = 100;
-	int32_t pll_op_freq_mhz = 600;
-	uint32_t vt_sys_clk_div = 1;
-	int32_t vt_sys_clk_freq_mhz = 600;
-	uint32_t vt_pix_clk_div = 10;
-	int32_t vt_pix_clk_freq_mhz = 60;
-	uint32_t op_sys_clk_div = 1;
-	int32_t op_sys_clk_freq_mhz = 60;
-	uint32_t op_pix_clk_div = 10;
-	int32_t op_pix_clk_freq_mhz = 60;
-
-	/* Declare pixel array and frame timing variables */
-	uint32_t x_pixel_array = 2064;
-	uint32_t y_pixel_array = 1544;
-	uint32_t x_even_inc = 1;
-	uint32_t x_odd_inc = 1;
-	uint32_t y_even_inc = 1;
-	uint32_t y_odd_inc = 1;
-	uint32_t x_output_size = 2064;
-	uint32_t y_output_size = 1544;
-	uint32_t additional_rows = 2;
-	uint32_t min_vt_frame_blanking_lines = 16;
-	uint32_t vt_line_length_pck = 2500;
-	uint32_t vt_line_length_us = 0;
-	uint32_t min_vt_frame_length_lines = 1562;
-	uint32_t vt_frame_length_lines = 1600;
-	uint32_t target_vt_frame_length_ms;	/* 200 * 0x0001000 / 3; */
-	uint32_t vt_frame_length_ms;	/* 200 * 0x0001000 / 3; */
-	uint32_t frame_rate_fps = 15;
-
-	/* Coarse intergration time */
-	uint32_t coarse_integration_time = 1597;
-	uint32_t coarse_integration_time_max_margin = 3;
-	uint16_t frame_count;
-	int timeout;
-
-	struct vb6801_sensor_info *pinfo = &vb6801_ctrl->s_info;
-
-	struct vb6801_i2c_reg_conf_t rreg[] = {
-		{REG_PRE_PLL_CLK_DIV, 0, 0, D_LEN_WORD},
-		{REG_PLL_MULTIPLIER, 0, 0, D_LEN_WORD},
-		{REG_VT_SYS_CLK_DIV, 0, 0, D_LEN_WORD},
-		{REG_VT_PIX_CLK_DIV, 0, 0, D_LEN_WORD},
-		{REG_OP_SYS_CLK_DIV, 0, 0, D_LEN_WORD},
-		{REG_OP_PIX_CLK_DIV, 0, 0, D_LEN_WORD},
-		{REG_FRAME_COUNT, 0, 0, D_LEN_BYTE},
-	};
-
-	struct vb6801_i2c_reg_conf_t wreg2[] = {
-		{REG_POWER_MAN_ENABLE_3, 0, 95, D_LEN_BYTE},
-		{REG_POWER_MAN_ENABLE_4, 0, 142, D_LEN_BYTE},
-		{REG_POWER_MAN_ENABLE_5, 0, 7, D_LEN_BYTE},
-	};
-
-	/* VIDEO TIMING CALCULATIONS
-	 * ========================= */
-
-	/* Pixel Array Size */
-	x_pixel_array = 2064;
-	y_pixel_array = 1544;
-
-	/* set current resolution */
-	vb6801_ctrl->curr_res = res;
-
-	/* Analogue binning setup */
-	if (pinfo->analog_binning_allowed > 0 &&
-	    pinfo->sub_sampling_factor == 4) {
-
-		pinfo->vtiming_major = 1;
-		pinfo->analog_timing_modes_4 = 32;
-	} else if (pinfo->analog_binning_allowed > 0 &&
-		   pinfo->sub_sampling_factor == 2) {
-
-		pinfo->vtiming_major = 1;
-		pinfo->analog_timing_modes_4 = 0;
-	} else {
-
-		pinfo->vtiming_major = 0;
-		pinfo->analog_timing_modes_4 = 0;
-	}
-
-	/* Sub-Sampling X & Y Odd Increments: valid values 1, 3, 5, 7 */
-	x_even_inc = 1;
-	y_even_inc = 1;
-	x_odd_inc = (sub_sampling_factor << 1) - x_even_inc;
-	y_odd_inc = (sub_sampling_factor << 1) - y_even_inc;
-
-	/* Output image size
-	 * Must always be a multiple of 2 - round down */
-	x_output_size = ((x_pixel_array / sub_sampling_factor) >> 1) << 1;
-	y_output_size = ((y_pixel_array / sub_sampling_factor) >> 1) << 1;
-
-	/* Output data format */
-	ccp2_data_format = (raw_mode << 8) + raw_mode;
-
-	/* Pre PLL clock divider : valid values 1, 2 or 4
-	 * The 1st step is to ensure that PLL input frequency is as close
-	 * as possible to the min allowed PLL input frequency.
-	 * This yields the smallest step size in the PLL output frequency. */
-	pre_pll_clk_div =
-	    ((int)(ext_clk_freq_mhz / min_pll_ip_freq_mhz) >> 1) << 1;
-	if (pre_pll_clk_div < 2)
-		pre_pll_clk_div = 1;
-
-	pll_ip_freq_mhz = ext_clk_freq_mhz / pre_pll_clk_div;
-
-	/* Video Timing System Clock divider: valid values 1, 2, 4
-	 * Now need to work backwards through the clock tree to determine the
-	 * 1st pass estimates for vt_sys_clk_freq_mhz and then the PLL output
-	 * frequency.*/
-	vt_sys_clk_freq_mhz = vt_pix_clk_div * target_vt_pix_clk_freq_mhz;
-	vt_sys_clk_div = max_pll_op_freq_mhz / vt_sys_clk_freq_mhz;
-	if (vt_sys_clk_div < 2)
-		vt_sys_clk_div = 1;
-
-	/* PLL Mulitplier: min , max 106 */
-	pll_op_freq_mhz = vt_sys_clk_div * vt_sys_clk_freq_mhz;
-	pll_multiplier = (pll_op_freq_mhz * 0x0001000) / pll_ip_freq_mhz;
-
-	/* Calculate the acutal pll output frequency
-	 * - the pll_multiplier calculation introduces a quantisation error
-	 *   due the integer nature of the pll multiplier */
-	pll_op_freq_mhz = (pll_ip_freq_mhz * pll_multiplier) / 0x0001000;
-
-	/* Re-calculate video timing clock frequencies based
-	 * on actual PLL freq */
-	vt_sys_clk_freq_mhz = pll_op_freq_mhz / vt_sys_clk_div;
-	vt_pix_clk_freq_mhz = ((vt_sys_clk_freq_mhz * 0x0001000) /
-				vt_pix_clk_div)/0x0001000;
-
-	/* Output System Clock Divider: valid value 1, 2, 4, 6, 8
-	 * op_sys_clk_div = vt_sys_clk_div;*/
-	op_sys_clk_div = (vt_sys_clk_div * sub_sampling_factor);
-	if (op_sys_clk_div < 2)
-		op_sys_clk_div = 1;
-
-	/* Calculate output timing clock frequencies */
-	op_sys_clk_freq_mhz = pll_op_freq_mhz / op_sys_clk_div;
-	op_pix_clk_freq_mhz =
-	    (op_sys_clk_freq_mhz * 0x0001000) / (op_pix_clk_div * 0x0001000);
-
-	/* Line length in pixels and us */
-	vt_line_length_pck = 2500;
-	vt_line_length_us =
-	    vt_line_length_pck * 0x0001000 / vt_pix_clk_freq_mhz;
-
-	/* Target vt_frame_length_ms */
-	target_vt_frame_length_ms = (1000 * 0x0001000 / target_frame_rate_fps);
-
-	/* Frame length in lines */
-	min_vt_frame_length_lines =
-	    additional_rows + y_output_size + min_vt_frame_blanking_lines;
-
-	vt_frame_length_lines =
-	    ((1000 * target_vt_frame_length_ms) / vt_line_length_us);
-
-	if (vt_frame_length_lines <= min_vt_frame_length_lines)
-		vt_frame_length_lines = min_vt_frame_length_lines;
-
-	/* Calcuate the actual frame length in ms */
-	vt_frame_length_ms = (vt_frame_length_lines * vt_line_length_us / 1000);
-
-	/* Frame Rate in fps */
-	frame_rate_fps = (1000 * 0x0001000 / vt_frame_length_ms);
-
-	/* Set coarse integration to max */
-	coarse_integration_time =
-	    vt_frame_length_lines - coarse_integration_time_max_margin;
-
-	CDBG("SENSOR VIDEO TIMING SUMMARY:\n");
-	CDBG(" ============================\n");
-	CDBG("ext_clk_freq_mhz      = %d\n", ext_clk_freq_mhz);
-	CDBG("pre_pll_clk_div       = %d\n", pre_pll_clk_div);
-	CDBG("pll_ip_freq_mhz       = %d\n", pll_ip_freq_mhz);
-	CDBG("pll_multiplier        = %d\n", pll_multiplier);
-	CDBG("pll_op_freq_mhz       = %d\n", pll_op_freq_mhz);
-	CDBG("vt_sys_clk_div        = %d\n", vt_sys_clk_div);
-	CDBG("vt_sys_clk_freq_mhz   = %d\n", vt_sys_clk_freq_mhz);
-	CDBG("vt_pix_clk_div        = %d\n", vt_pix_clk_div);
-	CDBG("vt_pix_clk_freq_mhz   = %d\n", vt_pix_clk_freq_mhz);
-	CDBG("op_sys_clk_div        = %d\n", op_sys_clk_div);
-	CDBG("op_sys_clk_freq_mhz   = %d\n", op_sys_clk_freq_mhz);
-	CDBG("op_pix_clk_div        = %d\n", op_pix_clk_div);
-	CDBG("op_pix_clk_freq_mhz   = %d\n", op_pix_clk_freq_mhz);
-	CDBG("vt_line_length_pck    = %d\n", vt_line_length_pck);
-	CDBG("vt_line_length_us     = %d\n", vt_line_length_us/0x0001000);
-	CDBG("vt_frame_length_lines = %d\n", vt_frame_length_lines);
-	CDBG("vt_frame_length_ms    = %d\n", vt_frame_length_ms/0x0001000);
-	CDBG("frame_rate_fps        = %d\n", frame_rate_fps);
-	CDBG("ccp2_data_format = %d\n", ccp2_data_format);
-	CDBG("x_output_size = %d\n", x_output_size);
-	CDBG("y_output_size = %d\n", y_output_size);
-	CDBG("x_odd_inc = %d\n", x_odd_inc);
-	CDBG("y_odd_inc = %d\n", y_odd_inc);
-	CDBG("(vt_frame_length_lines * frame_rate_factor ) = %d\n",
-	    (vt_frame_length_lines * vb6801_ctrl->factor_fps));
-	CDBG("coarse_integration_time = %d\n", coarse_integration_time);
-	CDBG("pinfo->vcm_dac_code = %d\n", pinfo->vcm_dac_code);
-	CDBG("capture_mode = %d\n", capture_mode);
-
-	/* RE-CONFIGURE SENSOR WITH NEW TIMINGS
-	 * ====================================
-	 * Enter Software Standby Mode */
-	rc = vb6801_i2c_write_b(REG_MODE_SELECT, 0);
-	if (rc < 0) {
-		CDBG("I2C vb6801_i2c_write_b FAILED!!!\n");
-		return rc;
-	}
-
-	/* Wait 100ms */
-	mdelay(100);
-
-	if (capture_mode == 0) {
-
-		rc = vb6801_i2c_write_b(REG_CCP2_CHANNEL_IDENTIFIER, 0);
-		rc = vb6801_i2c_write_b(REG_CCP2_SIGNALLING_MODE, 0);
-	} else if (capture_mode == 1) {
-
-		rc = vb6801_i2c_write_b(REG_CCP2_CHANNEL_IDENTIFIER, 0);
-		rc = vb6801_i2c_write_b(REG_CCP2_SIGNALLING_MODE, 1);
-	}
-
-	{
-		struct vb6801_i2c_reg_conf_t wreg[] = {
-			/* Re-configure Sensor */
-			{REG_CCP2_DATA_FORMAT, ccp2_data_format, 0,
-			 D_LEN_WORD},
-			{REG_ANALOGUE_GAIN_CODE_GLOBAL, 128, 0, D_LEN_WORD},
-			{REG_PRE_PLL_CLK_DIV, pre_pll_clk_div, 0, D_LEN_WORD},
-			{REG_VT_SYS_CLK_DIV, vt_sys_clk_div, 0, D_LEN_WORD},
-			{REG_VT_PIX_CLK_DIV, vt_pix_clk_div, 0, D_LEN_WORD},
-			{REG_OP_SYS_CLK_DIV, vt_sys_clk_div, 0, D_LEN_WORD},
-			{REG_OP_PIX_CLK_DIV, vt_pix_clk_div, 0, D_LEN_WORD},
-			{REG_VT_LINE_LENGTH_PCK, vt_line_length_pck, 0,
-			 D_LEN_WORD},
-			{REG_X_OUTPUT_SIZE, x_output_size, 0, D_LEN_WORD},
-			{REG_Y_OUTPUT_SIZE, y_output_size, 0, D_LEN_WORD},
-			{REG_X_ODD_INC, x_odd_inc, 0, D_LEN_WORD},
-			{REG_Y_ODD_INC, y_odd_inc, 0, D_LEN_WORD},
-			{REG_VT_FRAME_LENGTH_LINES,
-			 vt_frame_length_lines * vb6801_ctrl->factor_fps, 0,
-			 D_LEN_WORD},
-			{REG_COARSE_INTEGRATION_TIME,
-			 coarse_integration_time, 0, D_LEN_WORD},
-			/* Analogue Settings */
-			{REG_ANALOG_TIMING_MODES_2, 0, 132, D_LEN_BYTE},
-			{REG_RAMP_SCALE, 0, 5, D_LEN_BYTE},
-			{REG_BTL_LEVEL_SETUP, 0, 11, D_LEN_BYTE},
-			/* Enable Defect Correction */
-			{REG_SCYTHE_ENABLE, 0, 1, D_LEN_BYTE},
-			{REG_SCYTHE_WEIGHT, 0, 16, D_LEN_BYTE},
-			{REG_BRUCE_ENABLE, 0, 1, D_LEN_BYTE},
-			/* Auto Focus Configuration
-			 * Please note that the DAC Code is a written as a
-			 * 16-bit value 0 = infinity (no DAC current) */
-			{REG_VCM_DAC_CODE, pinfo->vcm_dac_code, 0, D_LEN_WORD},
-			{REG_VCM_DAC_STROBE, 0, 0, D_LEN_BYTE},
-			{REG_VCM_DAC_ENABLE, 0, 1, D_LEN_BYTE},
-		};
-
-		rc = vb6801_i2c_write_table(wreg, ARRAY_SIZE(wreg));
-		if (rc < 0) {
-			CDBG("I2C Write Table FAILED!!!\n");
-			return rc;
-		}
-	}
-	/* Parallel Interface Configuration */
-	if (capture_mode >= 2) {
-		struct vb6801_i2c_reg_conf_t wreg1[] = {
-			{REG_OP_CODER_SYNC_CLK_SETUP, 0, 15, D_LEN_BYTE},
-			{REG_OP_CODER_ENABLE, 0, 3, D_LEN_BYTE},
-			{REG_OP_CODER_SLOW_PAD_EN, 0, 1, D_LEN_BYTE},
-			{REG_OP_CODER_AUTOMATIC_MODE_ENABLE, 0, 3, D_LEN_BYTE},
-			{REG_OP_CODER_AUTO_STARTUP, 0, 2, D_LEN_BYTE},
-		};
-
-		rc = vb6801_i2c_write_table(wreg1, ARRAY_SIZE(wreg1));
-		if (rc < 0) {
-			CDBG("I2C Write Table FAILED!!!\n");
-			return rc;
-		}
-	}
-
-	/* Enter Streaming Mode */
-	rc = vb6801_i2c_write_b(REG_MODE_SELECT, 1);
-	if (rc < 0) {
-		CDBG("I2C Write Table FAILED!!!\n");
-		return rc;
-	}
-
-	/* Wait until the sensor starts streaming
-	 * Poll until the reported frame_count value is != 0xFF */
-	frame_count = 0xFF;
-	timeout = 2000;
-	while (frame_count == 0xFF && timeout > 0) {
-		rc = vb6801_i2c_read(REG_FRAME_COUNT, &frame_count, 1);
-		if (rc < 0)
-			return rc;
-
-		CDBG("REG_FRAME_COUNT  = 0x%x\n", frame_count);
-		timeout--;
-	}
-
-	/* Post Streaming Configuration */
-
-	rc = vb6801_i2c_write_table(wreg2, ARRAY_SIZE(wreg2));
-	if (rc < 0) {
-		CDBG("I2C Write Table FAILED!!!\n");
-		return rc;
-	}
-
-	rc = vb6801_i2c_read_table(rreg, ARRAY_SIZE(rreg));
-	if (rc < 0) {
-		CDBG("I2C Read Table FAILED!!!\n");
-		return rc;
-	}
-
-	CDBG("REG_PRE_PLL_CLK_DIV = 0x%x\n", rreg[0].wdata);
-	CDBG("REG_PLL_MULTIPLIER  = 0x%x\n", rreg[1].wdata);
-	CDBG("REG_VT_SYS_CLK_DIV  = 0x%x\n", rreg[2].wdata);
-	CDBG("REG_VT_PIX_CLK_DIV  = 0x%x\n", rreg[3].wdata);
-	CDBG("REG_OP_SYS_CLK_DIV  = 0x%x\n", rreg[4].wdata);
-	CDBG("REG_OP_PIX_CLK_DIV  = 0x%x\n", rreg[5].wdata);
-	CDBG("REG_FRAME_COUNT  = 0x%x\n", rreg[6].bdata);
-
-	mdelay(50);
-	frame_count = 0;
-	rc = vb6801_i2c_read(REG_FRAME_COUNT, &frame_count, 1);
-	CDBG("REG_FRAME_COUNT1  = 0x%x\n", frame_count);
-
-	mdelay(150);
-	frame_count = 0;
-	rc = vb6801_i2c_read(REG_FRAME_COUNT, &frame_count, 1);
-	CDBG("REG_FRAME_COUNT2  = 0x%x\n", frame_count);
-
-	mdelay(100);
-	frame_count = 0;
-	rc = vb6801_i2c_read(REG_FRAME_COUNT, &frame_count, 1);
-	CDBG("REG_FRAME_COUNT3  = 0x%x\n", frame_count);
-
-	mdelay(250);
-	frame_count = 0;
-	rc = vb6801_i2c_read(REG_FRAME_COUNT, &frame_count, 1);
-	CDBG("REG_FRAME_COUNT4  = 0x%x\n", frame_count);
-
-	return rc;
-}
-
-static int vb6801_sensor_init_done(const struct msm_camera_sensor_info *data)
-{
-	gpio_direction_output(data->sensor_reset, 0);
-	gpio_free(data->sensor_reset);
-	return 0;
-}
-
-static int vb6801_init_client(struct i2c_client *client)
-{
-	/* Initialize the MSM_CAMI2C Chip */
-	init_waitqueue_head(&vb6801_wait_queue);
-	return 0;
-}
-
-static int32_t vb6801_video_config(int mode, int res)
-{
-	int32_t rc = 0;
-
-	vb6801_ctrl->prev_res = res;
-	vb6801_ctrl->curr_res = res;
-	vb6801_ctrl->sensormode = mode;
-
-	rc = vb6801_config_sensor(12, 30, 60, 2, 1, 10, 2, RES_PREVIEW);
-	if (rc < 0)
-		return rc;
-
-	rc = vb6801_i2c_read(REG_VT_LINE_LENGTH_PCK,
-			     &vb6801_ctrl->s_dynamic_params.
-			     preview_pixelsPerLine, 2);
-	if (rc < 0)
-		return rc;
-
-	rc = vb6801_i2c_read(REG_VT_LINE_LENGTH_PCK,
-			     &vb6801_ctrl->s_dynamic_params.
-			     preview_linesPerFrame, 2);
-
-	return rc;
-}
-
-static int32_t vb6801_snapshot_config(int mode, int res)
-{
-	int32_t rc = 0;
-
-	vb6801_ctrl->curr_res = vb6801_ctrl->pict_res;
-	vb6801_ctrl->sensormode = mode;
-
-	rc = vb6801_config_sensor(12, 12, 48, 1, 1, 10, 2, RES_CAPTURE);
-	if (rc < 0)
-		return rc;
-
-	rc = vb6801_i2c_read(REG_VT_LINE_LENGTH_PCK,
-			     &vb6801_ctrl->s_dynamic_params.
-			     snapshot_pixelsPerLine, 2);
-	if (rc < 0)
-		return rc;
-
-	rc = vb6801_i2c_read(REG_VT_LINE_LENGTH_PCK,
-			     &vb6801_ctrl->s_dynamic_params.
-			     snapshot_linesPerFrame, 2);
-
-	return rc;
-}
-
-static int32_t vb6801_set_sensor_mode(int mode, int res)
-{
-	int32_t rc = 0;
-
-	switch (mode) {
-	case SENSOR_PREVIEW_MODE:
-		rc = vb6801_video_config(mode, res);
-		break;
-
-	case SENSOR_SNAPSHOT_MODE:
-	case SENSOR_RAW_SNAPSHOT_MODE:
-		rc = vb6801_snapshot_config(mode, res);
-		break;
-
-	default:
-		rc = -EINVAL;
-		break;
-	}
-
-	return rc;
-}
-
-int vb6801_sensor_config(void __user *argp)
-{
-	struct sensor_cfg_data cdata;
-	long rc = 0;
-
-	if (copy_from_user(&cdata,
-			   (void *)argp, sizeof(struct sensor_cfg_data)))
-		return -EFAULT;
-
-	mutex_lock(&vb6801_mut);
-
-	CDBG("vb6801_sensor_config, cfgtype = %d\n", cdata.cfgtype);
-
-	switch (cdata.cfgtype) {
-	case CFG_GET_PICT_FPS:
-		vb6801_get_pict_fps(cdata.cfg.gfps.prevfps,
-				    &(cdata.cfg.gfps.pictfps));
-
-		if (copy_to_user((void *)argp,
-				 &cdata, sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PREV_L_PF:
-		cdata.cfg.prevl_pf = vb6801_get_prev_lines_pf();
-
-		if (copy_to_user((void *)argp,
-				 &cdata, sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PREV_P_PL:
-		cdata.cfg.prevp_pl = vb6801_get_prev_pixels_pl();
-
-		if (copy_to_user((void *)argp,
-				 &cdata, sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PICT_L_PF:
-		cdata.cfg.pictl_pf = vb6801_get_pict_lines_pf();
-
-		if (copy_to_user((void *)argp,
-				 &cdata, sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PICT_P_PL:
-		cdata.cfg.pictp_pl = vb6801_get_pict_pixels_pl();
-
-		if (copy_to_user((void *)argp,
-				 &cdata, sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_GET_PICT_MAX_EXP_LC:
-		cdata.cfg.pict_max_exp_lc = vb6801_get_pict_max_exp_lc();
-
-		if (copy_to_user((void *)argp,
-				 &cdata, sizeof(struct sensor_cfg_data)))
-			rc = -EFAULT;
-		break;
-
-	case CFG_SET_FPS:
-	case CFG_SET_PICT_FPS:
-		rc = vb6801_set_fps(&(cdata.cfg.fps));
-		break;
-
-	case CFG_SET_EXP_GAIN:
-		rc = vb6801_write_exp_gain(cdata.cfg.exp_gain.gain,
-					   cdata.cfg.exp_gain.line);
-		break;
-
-	case CFG_SET_PICT_EXP_GAIN:
-		rc = vb6801_set_pict_exp_gain(cdata.cfg.exp_gain.gain,
-					      cdata.cfg.exp_gain.line);
-		break;
-
-	case CFG_SET_MODE:
-		rc = vb6801_set_sensor_mode(cdata.mode, cdata.rs);
-		break;
-
-	case CFG_PWR_DOWN:
-		rc = vb6801_power_down();
-		break;
-
-	case CFG_MOVE_FOCUS:
-		rc = vb6801_move_focus(cdata.cfg.focus.dir,
-				       cdata.cfg.focus.steps);
-		break;
-
-	case CFG_SET_DEFAULT_FOCUS:
-		rc = vb6801_set_default_focus();
-		break;
-
-	default:
-		rc = -EFAULT;
-		break;
-	}
-
-	mutex_unlock(&vb6801_mut);
-
-	return rc;
-}
-
-static int vb6801_sensor_release(void)
-{
-	int rc = -EBADF;
-
-	mutex_lock(&vb6801_mut);
-
-	vb6801_power_down();
-	vb6801_sensor_init_done(vb6801_ctrl->sensordata);
-	kfree(vb6801_ctrl);
-	mutex_unlock(&vb6801_mut);
-
-	return rc;
-}
-
-static int vb6801_i2c_probe(struct i2c_client *client,
-			    const struct i2c_device_id *id)
-{
-	int rc = 0;
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		rc = -ENOTSUPP;
-		goto probe_failure;
-	}
-
-	vb6801_sensorw = kzalloc(sizeof(struct vb6801_work_t), GFP_KERNEL);
-
-	if (!vb6801_sensorw) {
-		rc = -ENOMEM;
-		goto probe_failure;
-	}
-
-	i2c_set_clientdata(client, vb6801_sensorw);
-	vb6801_init_client(client);
-	vb6801_client = client;
-	vb6801_client->addr = vb6801_client->addr >> 1;
-
-	return 0;
-
-probe_failure:
-	if (vb6801_sensorw != NULL) {
-		kfree(vb6801_sensorw);
-		vb6801_sensorw = NULL;
-	}
-	return rc;
-}
-
-static int __exit vb6801_i2c_remove(struct i2c_client *client)
-{
-	struct vb6801_work_t *sensorw = i2c_get_clientdata(client);
-	free_irq(client->irq, sensorw);
-	vb6801_client = NULL;
-	kfree(sensorw);
-	return 0;
-}
-
-static const struct i2c_device_id vb6801_i2c_id[] = {
-	{"vb6801", 0},
-	{}
-};
-
-static struct i2c_driver vb6801_i2c_driver = {
-	.id_table = vb6801_i2c_id,
-	.probe = vb6801_i2c_probe,
-	.remove = __exit_p(vb6801_i2c_remove),
-	.driver = {
-		   .name = "vb6801",
-		   },
-};
-
-static int vb6801_probe_init_sensor(const struct msm_camera_sensor_info *data)
-{
-	int rc;
-
-	struct vb6801_i2c_reg_conf_t rreg[] = {
-		{0x0000, 0, 0, D_LEN_BYTE},
-		{0x0001, 0, 0, D_LEN_BYTE},
-	};
-
-	rc = vb6801_reset(data);
-	if (rc < 0)
-		goto init_probe_done;
-
-	mdelay(20);
-
-	rc = vb6801_i2c_read_table(rreg, ARRAY_SIZE(rreg));
-	if (rc < 0) {
-		CDBG("I2C Read Table FAILED!!!\n");
-		goto init_probe_fail;
-	}
-
-	/* 4. Compare sensor ID to VB6801 ID: */
-	if (rreg[0].bdata != 0x03 || rreg[1].bdata != 0x53) {
-		CDBG("vb6801_sensor_init: sensor ID don't match!\n");
-		goto init_probe_fail;
-	}
-
-	goto init_probe_done;
-
-init_probe_fail:
-	vb6801_sensor_init_done(data);
-init_probe_done:
-	return rc;
-}
-
-int vb6801_sensor_open_init(const struct msm_camera_sensor_info *data)
-{
-	int32_t rc;
-	struct vb6801_i2c_reg_conf_t wreg[] = {
-		{REG_MODE_SELECT, 0, STANDBY_MODE, D_LEN_BYTE},
-		{0x0113, 0, 0x0A, D_LEN_BYTE},
-	};
-
-	vb6801_ctrl = kzalloc(sizeof(struct vb6801_ctrl_t), GFP_KERNEL);
-	if (!vb6801_ctrl) {
-		rc = -ENOMEM;
-		goto open_init_fail1;
-	}
-
-	vb6801_ctrl->factor_fps = 1 /** 0x00000400*/ ;
-	vb6801_ctrl->curr_fps = 7680; /* 30 * Q8 */ ;
-	vb6801_ctrl->max_fps = 7680; /* 30 * Q8 */ ;
-	vb6801_ctrl->pict_exp_update = 0; /* 30 * Q8 */ ;
-	vb6801_ctrl->reducel = 0; /* 30 * Q8 */ ;
-
-	vb6801_ctrl->set_test = TEST_OFF;
-	vb6801_ctrl->prev_res = QTR_SIZE;
-	vb6801_ctrl->pict_res = FULL_SIZE;
-
-	vb6801_ctrl->s_dynamic_params.preview_linesPerFrame =
-	    VB6801_LINES_PER_FRAME_PREVIEW;
-	vb6801_ctrl->s_dynamic_params.preview_pixelsPerLine =
-	    VB6801_PIXELS_PER_LINE_PREVIEW;
-	vb6801_ctrl->s_dynamic_params.snapshot_linesPerFrame =
-	    VB6801_LINES_PER_FRAME_SNAPSHOT;
-	vb6801_ctrl->s_dynamic_params.snapshot_pixelsPerLine =
-	    VB6801_PIXELS_PER_LINE_SNAPSHOT;
-
-	if (data)
-		vb6801_ctrl->sensordata = data;
-
-	/* enable mclk first */
-	msm_camio_clk_rate_set(VB6801_DEFAULT_CLOCK_RATE);
-	mdelay(20);
-
-	rc = vb6801_reset(data);
-	if (rc < 0)
-		goto open_init_fail1;
-
-	rc = vb6801_i2c_write_table(wreg, ARRAY_SIZE(wreg));
-	if (rc < 0) {
-		CDBG("I2C Write Table FAILED!!!\n");
-		goto open_init_fail2;
-	}
-
-	rc = vb6801_read_nvm_data(&vb6801_ctrl->s_info);
-	if (rc < 0) {
-		CDBG("vb6801_read_nvm_data FAILED!!!\n");
-		goto open_init_fail2;
-	}
-	mdelay(66);
-
-	rc = vb6801_config_sensor(12, 30, 60, 2, 1, 10, 2, RES_PREVIEW);
-	if (rc < 0)
-		goto open_init_fail2;
-
-	goto open_init_done;
-
-open_init_fail2:
-	vb6801_sensor_init_done(data);
-open_init_fail1:
-	kfree(vb6801_ctrl);
-open_init_done:
-	return rc;
-}
-
-static int vb6801_sensor_probe(const struct msm_camera_sensor_info *info,
-			       struct msm_sensor_ctrl *s)
-{
-	int rc = i2c_add_driver(&vb6801_i2c_driver);
-	if (rc < 0 || vb6801_client == NULL) {
-		rc = -ENOTSUPP;
-		goto probe_done;
-	}
-
-	/* enable mclk first */
-	msm_camio_clk_rate_set(VB6801_DEFAULT_CLOCK_RATE);
-	mdelay(20);
-
-	rc = vb6801_probe_init_sensor(info);
-	if (rc < 0)
-		goto probe_done;
-
-	s->s_init = vb6801_sensor_open_init;
-	s->s_release = vb6801_sensor_release;
-	s->s_config = vb6801_sensor_config;
-	s->s_mount_angle  = 0;
-	vb6801_sensor_init_done(info);
-
-probe_done:
-	return rc;
-}
-
-static int __vb6801_probe(struct platform_device *pdev)
-{
-	return msm_camera_drv_start(pdev, vb6801_sensor_probe);
-}
-
-static struct platform_driver msm_camera_driver = {
-	.probe = __vb6801_probe,
-	.driver = {
-		   .name = "msm_camera_vb6801",
-		   .owner = THIS_MODULE,
-		   },
-};
-
-static int __init vb6801_init(void)
-{
-	return platform_driver_register(&msm_camera_driver);
-}
-
-module_init(vb6801_init);
-void vb6801_exit(void)
-{
-	i2c_del_driver(&vb6801_i2c_driver);
-}
diff --git a/drivers/media/video/msm/vb6801.h b/drivers/media/video/msm/vb6801.h
deleted file mode 100644
index 8248f8d..0000000
--- a/drivers/media/video/msm/vb6801.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. 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 VB6801_H
-#define VB6801_H
-
-#include <mach/board.h>
-
-extern struct vb6801_reg_t vb6801_regs;	/* from vb6801_reg.c */
-
-struct reg_struct {
-	uint16_t vt_pix_clk_div;	/*  0x0300 */
-	uint16_t vt_sys_clk_div;	/*  0x0302 */
-	uint16_t pre_pll_clk_div;	/*  0x0304 */
-	uint16_t pll_multiplier;	/*  0x0306 */
-	uint16_t op_pix_clk_div;	/*  0x0308 */
-	uint16_t op_sys_clk_div;	/*  0x030A */
-	uint16_t scale_m;	/*  0x0404 */
-	uint16_t row_speed;	/*  0x3016 */
-	uint16_t x_addr_start;	/*  0x3004 */
-	uint16_t x_addr_end;	/*  0x3008 */
-	uint16_t y_addr_start;	/*  0x3002 */
-	uint16_t y_addr_end;	/*  0x3006 */
-	uint16_t read_mode;	/*  0x3040 */
-	uint16_t x_output_size;	/*  0x034C */
-	uint16_t y_output_size;	/*  0x034E */
-	uint16_t line_length_pck;	/*  0x300C */
-	uint16_t frame_length_lines;	/*  0x300A */
-	uint16_t coarse_int_time;	/*  0x3012 */
-	uint16_t fine_int_time;	/*  0x3014 */
-};
-
-enum i2c_data_len {
-	D_LEN_BYTE,
-	D_LEN_WORD
-};
-
-struct vb6801_i2c_reg_conf_t {
-	unsigned short waddr;
-	unsigned short wdata;
-	uint8_t bdata;
-	enum i2c_data_len dlen;
-};
-
-struct vb6801_reg_t {
-	struct reg_struct const *reg_pat;
-	uint16_t reg_pat_size;
-	struct vb6801_i2c_reg_conf_t const *ttbl;
-	uint16_t ttbl_size;
-	struct vb6801_i2c_reg_conf_t const *lctbl;
-	uint16_t lctbl_size;
-	struct vb6801_i2c_reg_conf_t const *rftbl;
-	uint16_t rftbl_size;
-};
-
-#endif /* VB6801_H */
diff --git a/drivers/media/video/msm/vfe/Makefile b/drivers/media/video/msm/vfe/Makefile
deleted file mode 100644
index 250b55f..0000000
--- a/drivers/media/video/msm/vfe/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
-ccflags-y += -Idrivers/media/video/msm
-ccflags-y += -Idrivers/media/video/msm/server
-ifeq ($(GCC_VERSION),0404)
-CFLAGS_REMOVE_msm_vfe8x.o = -Wframe-larger-than=1024
-endif
-ifeq ($(CONFIG_MSM_CAMERA_V4L2),y)
-  obj-$(CONFIG_ARCH_MSM7X27A) += msm_vfe7x27a_v4l2.o
-  obj-$(CONFIG_ARCH_MSM8X60) += msm_vfe31_v4l2.o
-  obj-$(CONFIG_ARCH_MSM7X30) += msm_vfe31_v4l2.o
-else
-  obj-$(CONFIG_ARCH_MSM7X27A) += msm_vfe7x27a.o
-  obj-$(CONFIG_ARCH_MSM8X60) += msm_vfe31.o
-  obj-$(CONFIG_ARCH_MSM7X30) += msm_vfe31.o
-endif
-obj-$(CONFIG_ARCH_MSM_ARM11) += msm_vfe7x.o
-obj-$(CONFIG_ARCH_QSD8X50) += msm_vfe8x.o msm_vfe8x_proc.o
-obj-$(CONFIG_ARCH_MSM8960) += msm_vfe32.o
-obj-$(CONFIG_ARCH_MSM8974) += msm_vfe40.o
-obj-$(CONFIG_MSM_CAMERA_V4L2) += msm_vfe_stats_buf.o
diff --git a/drivers/media/video/msm/vfe/msm_vfe31.c b/drivers/media/video/msm/vfe/msm_vfe31.c
deleted file mode 100644
index 2929538..0000000
--- a/drivers/media/video/msm/vfe/msm_vfe31.c
+++ /dev/null
@@ -1,4012 +0,0 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. 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/uaccess.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <mach/irqs.h>
-#include <mach/camera.h>
-#include <asm/atomic.h>
-
-#include "msm_vfe31.h"
-#include "msm_vpe1.h"
-atomic_t irq_cnt;
-
-static struct vfe31_ctrl_type *vfe31_ctrl;
-static struct msm_camera_io_clk camio_clk;
-static void *vfe_syncdata;
-static void vfe31_send_msg_no_payload(enum VFE31_MESSAGE_ID id);
-static void vfe31_reset_hist_cfg(void);
-
-struct vfe31_isr_queue_cmd {
-	struct list_head list;
-	uint32_t                           vfeInterruptStatus0;
-	uint32_t                           vfeInterruptStatus1;
-	uint32_t                           vfePingPongStatus;
-	struct vfe_frame_asf_info          vfeAsfFrameInfo;
-	struct vfe_frame_bpc_info          vfeBpcFrameInfo;
-	struct vfe_msg_camif_status        vfeCamifStatusLocal;
-};
-
-static struct vfe31_cmd_type vfe31_cmd[] = {
-/* 0*/	{V31_DUMMY_0},
-		{V31_SET_CLK},
-		{V31_RESET},
-		{V31_START},
-		{V31_TEST_GEN_START},
-/* 5*/	{V31_OPERATION_CFG, V31_OPERATION_CFG_LEN},
-		{V31_AXI_OUT_CFG, V31_AXI_OUT_LEN, V31_AXI_OUT_OFF, 0xFF},
-		{V31_CAMIF_CFG, V31_CAMIF_LEN, V31_CAMIF_OFF, 0xFF},
-		{V31_AXI_INPUT_CFG},
-		{V31_BLACK_LEVEL_CFG, V31_BLACK_LEVEL_LEN, V31_BLACK_LEVEL_OFF,
-		0xFF},
-/*10*/  {V31_ROLL_OFF_CFG, V31_ROLL_OFF_CFG_LEN, V31_ROLL_OFF_CFG_OFF,
-		0xFF},
-		{V31_DEMUX_CFG, V31_DEMUX_LEN, V31_DEMUX_OFF, 0xFF},
-		{V31_DEMOSAIC_0_CFG, V31_DEMOSAIC_0_LEN, V31_DEMOSAIC_0_OFF,
-		0xFF},
-		{V31_DEMOSAIC_1_CFG, V31_DEMOSAIC_1_LEN, V31_DEMOSAIC_1_OFF,
-		0xFF},
-		{V31_DEMOSAIC_2_CFG, V31_DEMOSAIC_2_LEN, V31_DEMOSAIC_2_OFF,
-		0xFF},
-/*15*/	{V31_FOV_CFG, V31_FOV_LEN, V31_FOV_OFF, 0xFF},
-		{V31_MAIN_SCALER_CFG, V31_MAIN_SCALER_LEN, V31_MAIN_SCALER_OFF,
-		0xFF},
-		{V31_WB_CFG, V31_WB_LEN, V31_WB_OFF, 0xFF},
-		{V31_COLOR_COR_CFG, V31_COLOR_COR_LEN, V31_COLOR_COR_OFF, 0xFF},
-		{V31_RGB_G_CFG, V31_RGB_G_LEN, V31_RGB_G_OFF, 0xFF},
-/*20*/	{V31_LA_CFG, V31_LA_LEN, V31_LA_OFF, 0xFF },
-		{V31_CHROMA_EN_CFG, V31_CHROMA_EN_LEN, V31_CHROMA_EN_OFF, 0xFF},
-		{V31_CHROMA_SUP_CFG, V31_CHROMA_SUP_LEN, V31_CHROMA_SUP_OFF,
-		0xFF},
-		{V31_MCE_CFG, V31_MCE_LEN, V31_MCE_OFF, 0xFF},
-		{V31_SK_ENHAN_CFG, V31_SCE_LEN, V31_SCE_OFF, 0xFF},
-/*25*/	{V31_ASF_CFG, V31_ASF_LEN, V31_ASF_OFF, 0xFF},
-		{V31_S2Y_CFG, V31_S2Y_LEN, V31_S2Y_OFF, 0xFF},
-		{V31_S2CbCr_CFG, V31_S2CbCr_LEN, V31_S2CbCr_OFF, 0xFF},
-		{V31_CHROMA_SUBS_CFG, V31_CHROMA_SUBS_LEN, V31_CHROMA_SUBS_OFF,
-		0xFF},
-		{V31_OUT_CLAMP_CFG, V31_OUT_CLAMP_LEN, V31_OUT_CLAMP_OFF,
-		0xFF},
-/*30*/	{V31_FRAME_SKIP_CFG, V31_FRAME_SKIP_LEN, V31_FRAME_SKIP_OFF,
-		0xFF},
-		{V31_DUMMY_1},
-		{V31_DUMMY_2},
-		{V31_DUMMY_3},
-		{V31_UPDATE},
-/*35*/	{V31_BL_LVL_UPDATE, V31_BLACK_LEVEL_LEN, V31_BLACK_LEVEL_OFF,
-		0xFF},
-		{V31_DEMUX_UPDATE, V31_DEMUX_LEN, V31_DEMUX_OFF, 0xFF},
-		{V31_DEMOSAIC_1_UPDATE, V31_DEMOSAIC_1_LEN, V31_DEMOSAIC_1_OFF,
-		0xFF},
-		{V31_DEMOSAIC_2_UPDATE, V31_DEMOSAIC_2_LEN, V31_DEMOSAIC_2_OFF,
-		0xFF},
-		{V31_FOV_UPDATE, V31_FOV_LEN, V31_FOV_OFF, 0xFF},
-/*40*/	{V31_MAIN_SCALER_UPDATE, V31_MAIN_SCALER_LEN, V31_MAIN_SCALER_OFF,
-		0xFF},
-		{V31_WB_UPDATE, V31_WB_LEN, V31_WB_OFF, 0xFF},
-		{V31_COLOR_COR_UPDATE, V31_COLOR_COR_LEN, V31_COLOR_COR_OFF,
-		0xFF},
-		{V31_RGB_G_UPDATE, V31_RGB_G_LEN, V31_CHROMA_EN_OFF, 0xFF},
-		{V31_LA_UPDATE, V31_LA_LEN, V31_LA_OFF, 0xFF },
-/*45*/	{V31_CHROMA_EN_UPDATE, V31_CHROMA_EN_LEN, V31_CHROMA_EN_OFF,
-		0xFF},
-		{V31_CHROMA_SUP_UPDATE, V31_CHROMA_SUP_LEN, V31_CHROMA_SUP_OFF,
-		0xFF},
-		{V31_MCE_UPDATE, V31_MCE_LEN, V31_MCE_OFF, 0xFF},
-		{V31_SK_ENHAN_UPDATE, V31_SCE_LEN, V31_SCE_OFF, 0xFF},
-		{V31_S2CbCr_UPDATE, V31_S2CbCr_LEN, V31_S2CbCr_OFF, 0xFF},
-/*50*/	{V31_S2Y_UPDATE, V31_S2Y_LEN, V31_S2Y_OFF, 0xFF},
-		{V31_ASF_UPDATE, V31_ASF_UPDATE_LEN, V31_ASF_OFF, 0xFF},
-		{V31_FRAME_SKIP_UPDATE},
-		{V31_CAMIF_FRAME_UPDATE},
-		{V31_STATS_AF_UPDATE, V31_STATS_AF_LEN, V31_STATS_AF_OFF},
-/*55*/	{V31_STATS_AE_UPDATE, V31_STATS_AE_LEN, V31_STATS_AE_OFF},
-		{V31_STATS_AWB_UPDATE, V31_STATS_AWB_LEN, V31_STATS_AWB_OFF},
-		{V31_STATS_RS_UPDATE, V31_STATS_RS_LEN, V31_STATS_RS_OFF},
-		{V31_STATS_CS_UPDATE, V31_STATS_CS_LEN, V31_STATS_CS_OFF},
-		{V31_STATS_SKIN_UPDATE},
-/*60*/	{V31_STATS_IHIST_UPDATE, V31_STATS_IHIST_LEN, V31_STATS_IHIST_OFF},
-		{V31_DUMMY_4},
-		{V31_EPOCH1_ACK},
-		{V31_EPOCH2_ACK},
-		{V31_START_RECORDING},
-/*65*/	{V31_STOP_RECORDING},
-		{V31_DUMMY_5},
-		{V31_DUMMY_6},
-		{V31_CAPTURE, V31_CAPTURE_LEN, 0xFF},
-		{V31_DUMMY_7},
-/*70*/	{V31_STOP},
-		{V31_GET_HW_VERSION},
-		{V31_GET_FRAME_SKIP_COUNTS},
-		{V31_OUTPUT1_BUFFER_ENQ},
-		{V31_OUTPUT2_BUFFER_ENQ},
-/*75*/	{V31_OUTPUT3_BUFFER_ENQ},
-		{V31_JPEG_OUT_BUF_ENQ},
-		{V31_RAW_OUT_BUF_ENQ},
-		{V31_RAW_IN_BUF_ENQ},
-		{V31_STATS_AF_ENQ},
-/*80*/	{V31_STATS_AE_ENQ},
-		{V31_STATS_AWB_ENQ},
-		{V31_STATS_RS_ENQ},
-		{V31_STATS_CS_ENQ},
-		{V31_STATS_SKIN_ENQ},
-/*85*/	{V31_STATS_IHIST_ENQ},
-		{V31_DUMMY_8},
-		{V31_JPEG_ENC_CFG},
-		{V31_DUMMY_9},
-		{V31_STATS_AF_START, V31_STATS_AF_LEN, V31_STATS_AF_OFF},
-/*90*/	{V31_STATS_AF_STOP},
-		{V31_STATS_AE_START, V31_STATS_AE_LEN, V31_STATS_AE_OFF},
-		{V31_STATS_AE_STOP},
-		{V31_STATS_AWB_START, V31_STATS_AWB_LEN, V31_STATS_AWB_OFF},
-		{V31_STATS_AWB_STOP},
-/*95*/	{V31_STATS_RS_START, V31_STATS_RS_LEN, V31_STATS_RS_OFF},
-		{V31_STATS_RS_STOP},
-		{V31_STATS_CS_START, V31_STATS_CS_LEN, V31_STATS_CS_OFF},
-		{V31_STATS_CS_STOP},
-		{V31_STATS_SKIN_START},
-/*100*/	{V31_STATS_SKIN_STOP},
-		{V31_STATS_IHIST_START,
-		V31_STATS_IHIST_LEN, V31_STATS_IHIST_OFF},
-		{V31_STATS_IHIST_STOP},
-		{V31_DUMMY_10},
-		{V31_SYNC_TIMER_SETTING, V31_SYNC_TIMER_LEN,
-			V31_SYNC_TIMER_OFF},
-/*105*/	{V31_ASYNC_TIMER_SETTING, V31_ASYNC_TIMER_LEN, V31_ASYNC_TIMER_OFF},
-		{V31_LIVESHOT},
-		{V31_ZSL, V31_CAPTURE_LEN, 0xFF},
-		{V31_STEREOCAM},
-		{V31_LA_SETUP},
-/*110*/	{V31_XBAR_CFG, V31_XBAR_CFG_LEN, V31_XBAR_CFG_OFF},
-/*111*/	{V31_EZTUNE_CFG, V31_EZTUNE_CFG_LEN, V31_EZTUNE_CFG_OFF},
-};
-
-uint32_t vfe31_AXI_WM_CFG[] = {
-	0x0000004C,
-	0x00000064,
-	0x0000007C,
-	0x00000094,
-	0x000000AC,
-	0x000000C4,
-	0x000000DC,
-};
-
-static const char *vfe31_general_cmd[] = {
-	"DUMMY_0",  /* 0 */
-	"SET_CLK",
-	"RESET",
-	"START",
-	"TEST_GEN_START",
-	"OPERATION_CFG",  /* 5 */
-	"AXI_OUT_CFG",
-	"CAMIF_CFG",
-	"AXI_INPUT_CFG",
-	"BLACK_LEVEL_CFG",
-	"ROLL_OFF_CFG",  /* 10 */
-	"DEMUX_CFG",
-	"DEMOSAIC_0_CFG",  /* general */
-	"DEMOSAIC_1_CFG",  /* ABF     */
-	"DEMOSAIC_2_CFG",  /* BPC     */
-	"FOV_CFG",  /* 15  */
-	"MAIN_SCALER_CFG",
-	"WB_CFG",
-	"COLOR_COR_CFG",
-	"RGB_G_CFG",
-	"LA_CFG",  /* 20 */
-	"CHROMA_EN_CFG",
-	"CHROMA_SUP_CFG",
-	"MCE_CFG",
-	"SK_ENHAN_CFG",
-	"ASF_CFG",  /* 25 */
-	"S2Y_CFG",
-	"S2CbCr_CFG",
-	"CHROMA_SUBS_CFG",
-	"OUT_CLAMP_CFG",
-	"FRAME_SKIP_CFG",  /* 30 */
-	"DUMMY_1",
-	"DUMMY_2",
-	"DUMMY_3",
-	"UPDATE",
-	"BL_LVL_UPDATE",  /* 35 */
-	"DEMUX_UPDATE",
-	"DEMOSAIC_1_UPDATE",  /* BPC */
-	"DEMOSAIC_2_UPDATE",  /* ABF */
-	"FOV_UPDATE",
-	"MAIN_SCALER_UPDATE",  /* 40 */
-	"WB_UPDATE",
-	"COLOR_COR_UPDATE",
-	"RGB_G_UPDATE",
-	"LA_UPDATE",
-	"CHROMA_EN_UPDATE",  /* 45 */
-	"CHROMA_SUP_UPDATE",
-	"MCE_UPDATE",
-	"SK_ENHAN_UPDATE",
-	"S2CbCr_UPDATE",
-	"S2Y_UPDATE",  /* 50 */
-	"ASF_UPDATE",
-	"FRAME_SKIP_UPDATE",
-	"CAMIF_FRAME_UPDATE",
-	"STATS_AF_UPDATE",
-	"STATS_AE_UPDATE",  /* 55 */
-	"STATS_AWB_UPDATE",
-	"STATS_RS_UPDATE",
-	"STATS_CS_UPDATE",
-	"STATS_SKIN_UPDATE",
-	"STATS_IHIST_UPDATE",  /* 60 */
-	"DUMMY_4",
-	"EPOCH1_ACK",
-	"EPOCH2_ACK",
-	"START_RECORDING",
-	"STOP_RECORDING",  /* 65 */
-	"DUMMY_5",
-	"DUMMY_6",
-	"CAPTURE",
-	"DUMMY_7",
-	"STOP",  /* 70 */
-	"GET_HW_VERSION",
-	"GET_FRAME_SKIP_COUNTS",
-	"OUTPUT1_BUFFER_ENQ",
-	"OUTPUT2_BUFFER_ENQ",
-	"OUTPUT3_BUFFER_ENQ",  /* 75 */
-	"JPEG_OUT_BUF_ENQ",
-	"RAW_OUT_BUF_ENQ",
-	"RAW_IN_BUF_ENQ",
-	"STATS_AF_ENQ",
-	"STATS_AE_ENQ",  /* 80 */
-	"STATS_AWB_ENQ",
-	"STATS_RS_ENQ",
-	"STATS_CS_ENQ",
-	"STATS_SKIN_ENQ",
-	"STATS_IHIST_ENQ",  /* 85 */
-	"DUMMY_8",
-	"JPEG_ENC_CFG",
-	"DUMMY_9",
-	"STATS_AF_START",
-	"STATS_AF_STOP",  /* 90 */
-	"STATS_AE_START",
-	"STATS_AE_STOP",
-	"STATS_AWB_START",
-	"STATS_AWB_STOP",
-	"STATS_RS_START",  /* 95 */
-	"STATS_RS_STOP",
-	"STATS_CS_START",
-	"STATS_CS_STOP",
-	"STATS_SKIN_START",
-	"STATS_SKIN_STOP",  /* 100 */
-	"STATS_IHIST_START",
-	"STATS_IHIST_STOP",
-	"DUMMY_10",
-	"SYNC_TIMER_SETTING",
-	"ASYNC_TIMER_SETTING",  /* 105 */
-	"V31_LIVESHOT",
-	"V31_ZSL",
-	"V31_STEREOCAM",
-	"V31_LA_SETUP",
-	"V31_XBAR_CFG",
-};
-
-static void vfe_addr_convert(struct msm_vfe_phy_info *pinfo,
-	enum vfe_resp_msg type, void *data, void **ext, int32_t *elen)
-{
-	uint8_t outid;
-	switch (type) {
-	case VFE_MSG_OUTPUT_T:
-	case VFE_MSG_OUTPUT_P:
-	case VFE_MSG_OUTPUT_S:
-	case VFE_MSG_OUTPUT_V:
-	{
-		pinfo->output_id =
-			((struct vfe_message *)data)->_u.msgOut.output_id;
-
-		switch (type) {
-		case VFE_MSG_OUTPUT_P:
-			outid = OUTPUT_TYPE_P;
-			break;
-		case VFE_MSG_OUTPUT_V:
-			outid = OUTPUT_TYPE_V;
-			break;
-		case VFE_MSG_OUTPUT_T:
-			outid = OUTPUT_TYPE_T;
-			break;
-		case VFE_MSG_OUTPUT_S:
-			outid = OUTPUT_TYPE_S;
-			break;
-		default:
-			outid = 0xff;
-			break;
-		}
-		pinfo->output_id = outid;
-		pinfo->p0_phy =
-			((struct vfe_message *)data)->_u.msgOut.p0_addr;
-		pinfo->p1_phy =
-			((struct vfe_message *)data)->_u.msgOut.p1_addr;
-		pinfo->p2_phy =
-			((struct vfe_message *)data)->_u.msgOut.p2_addr;
-
-		pinfo->frame_id =
-		((struct vfe_message *)data)->_u.msgOut.frameCounter;
-
-		((struct vfe_msg_output *)(vfe31_ctrl->extdata))->bpcInfo =
-		((struct vfe_message *)data)->_u.msgOut.bpcInfo;
-		((struct vfe_msg_output *)(vfe31_ctrl->extdata))->asfInfo =
-		((struct vfe_message *)data)->_u.msgOut.asfInfo;
-		((struct vfe_msg_output *)(vfe31_ctrl->extdata))->frameCounter =
-		((struct vfe_message *)data)->_u.msgOut.frameCounter;
-		*ext  = vfe31_ctrl->extdata;
-		*elen = vfe31_ctrl->extlen;
-	}
-		break;
-
-	default:
-		break;
-	} /* switch */
-}
-
-
-static void vfe31_proc_ops(enum VFE31_MESSAGE_ID id, void *msg, size_t len)
-{
-	struct msm_vfe_resp *rp;
-
-	rp = vfe31_ctrl->resp->vfe_alloc(sizeof(struct msm_vfe_resp),
-		vfe31_ctrl->syncdata, GFP_ATOMIC);
-	if (!rp) {
-		CDBG("rp: cannot allocate buffer\n");
-		return;
-	}
-	CDBG("vfe31_proc_ops, msgId = %d\n", id);
-	rp->evt_msg.type   = MSM_CAMERA_MSG;
-	rp->evt_msg.msg_id = id;
-	rp->evt_msg.len    = len;
-	rp->evt_msg.data   = msg;
-
-	switch (rp->evt_msg.msg_id) {
-	case MSG_ID_SNAPSHOT_DONE:
-		rp->type = VFE_MSG_SNAPSHOT;
-		break;
-
-	case MSG_ID_OUTPUT_P:
-		rp->type = VFE_MSG_OUTPUT_P;
-		vfe_addr_convert(&(rp->phy), VFE_MSG_OUTPUT_P,
-			rp->evt_msg.data, &(rp->extdata),
-			&(rp->extlen));
-		break;
-
-	case MSG_ID_OUTPUT_T:
-		rp->type = VFE_MSG_OUTPUT_T;
-		vfe_addr_convert(&(rp->phy), VFE_MSG_OUTPUT_T,
-			rp->evt_msg.data, &(rp->extdata),
-			&(rp->extlen));
-		break;
-
-	case MSG_ID_OUTPUT_S:
-		rp->type = VFE_MSG_OUTPUT_S;
-		vfe_addr_convert(&(rp->phy), VFE_MSG_OUTPUT_S,
-			rp->evt_msg.data, &(rp->extdata),
-			&(rp->extlen));
-		break;
-
-	case MSG_ID_OUTPUT_V:
-		rp->type = VFE_MSG_OUTPUT_V;
-		vfe_addr_convert(&(rp->phy), VFE_MSG_OUTPUT_V,
-			rp->evt_msg.data, &(rp->extdata),
-			&(rp->extlen));
-		break;
-
-	case MSG_ID_COMMON:
-		rp->type = VFE_MSG_COMMON;
-		rp->stats_msg.status_bits = ((struct vfe_message *)
-			rp->evt_msg.data)->_u.msgStats.status_bits;
-		rp->stats_msg.frame_id = ((struct vfe_message *)
-			rp->evt_msg.data)->_u.msgStats.frameCounter;
-
-		rp->stats_msg.aec_buff = ((struct vfe_message *)
-			rp->evt_msg.data)->_u.msgStats.buff.aec;
-		rp->stats_msg.awb_buff = ((struct vfe_message *)
-			rp->evt_msg.data)->_u.msgStats.buff.awb;
-		rp->stats_msg.af_buff = ((struct vfe_message *)
-			rp->evt_msg.data)->_u.msgStats.buff.af;
-		rp->stats_msg.ihist_buff = ((struct vfe_message *)
-			rp->evt_msg.data)->_u.msgStats.buff.ihist;
-		rp->stats_msg.rs_buff = ((struct vfe_message *)
-			rp->evt_msg.data)->_u.msgStats.buff.rs;
-		rp->stats_msg.cs_buff = ((struct vfe_message *)
-			rp->evt_msg.data)->_u.msgStats.buff.cs;
-		rp->stats_msg.awb_ymin = ((struct vfe_message *)
-			rp->evt_msg.data)->_u.msgStats.buff.awb_ymin;
-		break;
-
-	case MSG_ID_SYNC_TIMER0_DONE:
-		rp->type = VFE_MSG_SYNC_TIMER0;
-		break;
-
-	case MSG_ID_SYNC_TIMER1_DONE:
-		rp->type = VFE_MSG_SYNC_TIMER1;
-		break;
-
-	case MSG_ID_SYNC_TIMER2_DONE:
-		rp->type = VFE_MSG_SYNC_TIMER2;
-		break;
-
-	default:
-		rp->type = VFE_MSG_GENERAL;
-		break;
-	}
-
-	/* save the frame id.*/
-	rp->evt_msg.frame_id = rp->phy.frame_id;
-
-	vfe31_ctrl->resp->vfe_resp(rp, MSM_CAM_Q_VFE_MSG, vfe31_ctrl->syncdata,
-		GFP_ATOMIC);
-}
-
-static void vfe_send_outmsg(uint8_t msgid, uint32_t p0_addr,
-	uint32_t p1_addr, uint32_t p2_addr)
-{
-	struct vfe_message msg;
-	uint8_t outid;
-
-	msg._d = msgid;   /* now the output mode is redundnat. */
-	msg._u.msgOut.frameCounter = vfe31_ctrl->vfeFrameId;
-
-	switch (msgid) {
-	case MSG_ID_OUTPUT_P:
-		outid = OUTPUT_TYPE_P;
-		break;
-	case MSG_ID_OUTPUT_V:
-		outid = OUTPUT_TYPE_V;
-		break;
-	case MSG_ID_OUTPUT_T:
-		outid = OUTPUT_TYPE_T;
-		break;
-	case MSG_ID_OUTPUT_S:
-		outid = OUTPUT_TYPE_S;
-		break;
-	default:
-		outid = 0xff;  /* -1 for error condition.*/
-		break;
-	}
-	msg._u.msgOut.output_id   = msgid;
-	msg._u.msgOut.p0_addr     = p0_addr;
-	msg._u.msgOut.p1_addr     = p1_addr;
-	msg._u.msgOut.p2_addr     = p2_addr;
-	CDBG("%s p2_addr = 0x%x\n", __func__, p2_addr);
-	vfe31_proc_ops(msgid, &msg, sizeof(struct vfe_message));
-	return;
-}
-static int vfe31_enable(struct camera_enable_cmd *enable)
-{
-	return 0;
-}
-
-static void vfe31_stop(void)
-{
-	atomic_set(&vfe31_ctrl->vstate, 0);
-	atomic_set(&vfe31_ctrl->stop_ack_pending, 1);
-
-	/* in either continuous or snapshot mode, stop command can be issued
-	 * at any time. stop camif immediately. */
-	msm_camera_io_w_mb(CAMIF_COMMAND_STOP_IMMEDIATELY,
-		vfe31_ctrl->vfebase + VFE_CAMIF_COMMAND);
-
-	/* disable all interrupts.  */
-	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
-		vfe31_ctrl->vfebase + VFE_IRQ_MASK_0);
-	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
-		vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
-
-	/* clear all pending interrupts*/
-	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
-		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_0);
-	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
-		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_1);
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	msm_camera_io_w_mb(1,
-		vfe31_ctrl->vfebase + VFE_IRQ_CMD);
-
-	/* now enable only halt_irq & reset_irq */
-	msm_camera_io_w(0xf0000000,          /* this is for async timer. */
-		vfe31_ctrl->vfebase + VFE_IRQ_MASK_0);
-	msm_camera_io_w(VFE_IMASK_AXI_HALT,
-		vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
-
-	/* then apply axi halt command. */
-	msm_camera_io_w_mb(AXI_HALT,
-		vfe31_ctrl->vfebase + VFE_AXI_CMD);
-}
-
-static int vfe31_disable(struct camera_enable_cmd *enable,
-	struct platform_device *dev)
-{
-	msm_camio_set_perf_lvl(S_EXIT);
-	msm_camio_disable(dev);
-	return 0;
-}
-
-static int vfe31_add_free_buf2(struct vfe31_output_ch *outch,
-	uint32_t paddr, uint32_t p0_off, uint32_t p1_off, uint32_t p2_off)
-{
-	struct vfe31_free_buf *free_buf = NULL;
-	unsigned long flags = 0;
-	free_buf = kmalloc(sizeof(struct vfe31_free_buf), GFP_KERNEL);
-	if (!free_buf)
-		return -ENOMEM;
-
-	spin_lock_irqsave(&outch->free_buf_lock, flags);
-	free_buf->paddr = paddr;
-	free_buf->planar0_off = p0_off;
-	free_buf->planar1_off = p1_off;
-	free_buf->planar2_off = p2_off;
-	list_add_tail(&free_buf->node, &outch->free_buf_head);
-
-	CDBG("%s: free_buf paddr = 0x%x, y_off = %d, cbcr_off = %d\n",
-		__func__, free_buf->paddr, free_buf->planar0_off,
-		free_buf->planar1_off);
-	spin_unlock_irqrestore(&outch->free_buf_lock, flags);
-	return 0;
-}
-
-#define vfe31_add_free_buf(outch, regptr) \
-	vfe31_add_free_buf2(outch, regptr->paddr, \
-	regptr->info.planar0_off,	\
-	regptr->info.planar1_off,	\
-	regptr->info.planar2_off)
-
-#define vfe31_free_buf_available(outch) \
-	(!list_empty(&outch.free_buf_head))
-
-static inline struct vfe31_free_buf *vfe31_get_free_buf(
-	struct vfe31_output_ch *outch)
-{
-	unsigned long flags = 0;
-	struct vfe31_free_buf *free_buf = NULL;
-	spin_lock_irqsave(&outch->free_buf_lock, flags);
-	if (!list_empty(&outch->free_buf_head)) {
-		free_buf = list_first_entry(&outch->free_buf_head,
-			struct vfe31_free_buf, node);
-		if (free_buf)
-			list_del_init(&free_buf->node);
-	}
-	spin_unlock_irqrestore(&outch->free_buf_lock, flags);
-	return free_buf;
-}
-
-static inline void vfe31_reset_free_buf_queue(
-	struct vfe31_output_ch *outch)
-{
-	unsigned long flags = 0;
-	struct vfe31_free_buf *free_buf = NULL;
-	spin_lock_irqsave(&outch->free_buf_lock, flags);
-	while (!list_empty(&outch->free_buf_head)) {
-		free_buf = list_first_entry(&outch->free_buf_head,
-			struct vfe31_free_buf, node);
-		if (free_buf) {
-			list_del_init(&free_buf->node);
-			kfree(free_buf);
-		}
-	}
-	spin_unlock_irqrestore(&outch->free_buf_lock, flags);
-}
-
-#define vfe31_init_free_buf_queue() do {	\
-	INIT_LIST_HEAD(&vfe31_ctrl->outpath.out0.free_buf_head);	\
-	INIT_LIST_HEAD(&vfe31_ctrl->outpath.out1.free_buf_head);	\
-	INIT_LIST_HEAD(&vfe31_ctrl->outpath.out2.free_buf_head);	\
-	spin_lock_init(&vfe31_ctrl->outpath.out0.free_buf_lock);	\
-	spin_lock_init(&vfe31_ctrl->outpath.out1.free_buf_lock);	\
-	spin_lock_init(&vfe31_ctrl->outpath.out2.free_buf_lock);	\
-} while (0)
-
-#define vfe31_reset_free_buf_queue_all() do {	\
-	vfe31_reset_free_buf_queue(&vfe31_ctrl->outpath.out0);	\
-	vfe31_reset_free_buf_queue(&vfe31_ctrl->outpath.out1);	\
-	vfe31_reset_free_buf_queue(&vfe31_ctrl->outpath.out2);	\
-} while (0)
-
-static int vfe31_config_axi(int mode, struct axidata *ad, uint32_t *ao)
-{
-	int i;
-	uint32_t *p, *p1, *p2, *p3;
-	int32_t *ch_info;
-	struct vfe31_output_ch *outp1, *outp2, *outp3;
-	struct msm_pmem_region *regp1 = NULL;
-	struct msm_pmem_region *regp2 = NULL;
-	struct msm_pmem_region *regp3 = NULL;
-	int ret;
-	struct msm_sync* p_sync = (struct msm_sync *)vfe_syncdata;
-
-	outp1 = NULL;
-	outp2 = NULL;
-	outp3 = NULL;
-
-	p = ao + 2;
-
-	/* Update the corresponding write masters for each output*/
-	ch_info = ao + V31_AXI_CFG_LEN;
-	vfe31_ctrl->outpath.out0.ch0 = 0x0000FFFF & *ch_info;
-	vfe31_ctrl->outpath.out0.ch1 = 0x0000FFFF & (*ch_info++ >> 16);
-	vfe31_ctrl->outpath.out0.ch2 = 0x0000FFFF & *ch_info++;
-	vfe31_ctrl->outpath.out1.ch0 = 0x0000FFFF & *ch_info;
-	vfe31_ctrl->outpath.out1.ch1 = 0x0000FFFF & (*ch_info++ >> 16);
-	vfe31_ctrl->outpath.out1.ch2 = 0x0000FFFF & *ch_info++;
-	vfe31_ctrl->outpath.out2.ch0 = 0x0000FFFF & *ch_info;
-	vfe31_ctrl->outpath.out2.ch1 = 0x0000FFFF & (*ch_info++ >> 16);
-	vfe31_ctrl->outpath.out2.ch2 = 0x0000FFFF & *ch_info++;
-
-	CDBG("vfe31_config_axi: mode = %d, bufnum1 = %d, bufnum2 = %d"
-		"bufnum3 = %d", mode, ad->bufnum1, ad->bufnum2, ad->bufnum3);
-
-	switch (mode) {
-
-	case OUTPUT_2: {
-		if (ad->bufnum2 != 3)
-			return -EINVAL;
-		regp1 = &(ad->region[ad->bufnum1]);
-		outp1 = &(vfe31_ctrl->outpath.out0);
-		vfe31_ctrl->outpath.output_mode |= VFE31_OUTPUT_MODE_PT;
-
-		for (i = 0; i < 2; i++) {
-			p1 = ao + 6 + i;    /* wm0 for y  */
-			*p1 = (regp1->paddr + regp1->info.planar0_off);
-
-			p1 = ao + 12 + i;  /* wm1 for cbcr */
-			*p1 = (regp1->paddr + regp1->info.planar1_off);
-			regp1++;
-		}
-		ret = vfe31_add_free_buf(outp1, regp1);
-		if (ret < 0)
-			return ret;
-	}
-		break;
-
-	case OUTPUT_1_AND_2:
-		/* use wm0& 4 for thumbnail, wm1&5 for main image.*/
-		if ((ad->bufnum1 < 1) || (ad->bufnum2 < 1))
-			return -EINVAL;
-		vfe31_ctrl->outpath.output_mode |=
-			VFE31_OUTPUT_MODE_S;  /* main image.*/
-		vfe31_ctrl->outpath.output_mode |=
-			VFE31_OUTPUT_MODE_PT;  /* thumbnail. */
-
-		/* this is thumbnail buffer. */
-		regp1 = &(ad->region[ad->bufnum1-1]);
-		/* this is main image buffer. */
-		regp2 = &(ad->region[ad->bufnum1+ad->bufnum2-1]);
-
-		outp1 = &(vfe31_ctrl->outpath.out0);
-		outp2 = &(vfe31_ctrl->outpath.out1); /* snapshot */
-
-		/*  Parse the buffers!!! */
-		if (ad->bufnum2 == 1) {	/* assuming bufnum1 = bufnum2 */
-			p1 = ao + 6;   /* wm0 ping */
-			*p1++ = (regp1->paddr + regp1->info.planar0_off);
-
-			/* this is to duplicate ping address to pong.*/
-			*p1 = (regp1->paddr + regp1->info.planar0_off);
-
-			p1 = ao + 30;  /* wm4 ping */
-			*p1++ = (regp1->paddr + regp1->info.planar1_off);
-			CDBG("%s: regp1->info.cbcr_off = 0x%x\n", __func__,
-						 regp1->info.planar1_off);
-
-			/* this is to duplicate ping address to pong.*/
-			*p1 = (regp1->paddr + regp1->info.planar1_off);
-
-			p1 = ao + 12;   /* wm1 ping */
-			*p1++ = (regp2->paddr + regp2->info.planar0_off);
-
-			/* pong = ping,*/
-			*p1 = (regp2->paddr + regp2->info.planar0_off);
-
-			p1 = ao + 36;  /* wm5 */
-			*p1++ = (regp2->paddr + regp2->info.planar1_off);
-			CDBG("%s: regp2->info.cbcr_off = 0x%x\n", __func__,
-						 regp2->info.planar1_off);
-
-			/* pong = ping,*/
-			*p1 = (regp2->paddr + regp2->info.planar1_off);
-		} else { /* more than one snapshot */
-			/* first fill ping & pong */
-			for (i = 0; i < 2; i++) {
-				p1 = ao + 6 + i;    /* wm0 for y  */
-				*p1 = (regp1->paddr + regp1->info.planar0_off);
-				p1 = ao + 30 + i;  /* wm4 for cbcr */
-				*p1 = (regp1->paddr + regp1->info.planar1_off);
-				regp1--;
-			}
-
-			for (i = 0; i < 2; i++) {
-				p2 = ao + 12 + i;    /* wm1 for y  */
-				*p2 = (regp2->paddr + regp2->info.planar0_off);
-				p2 = ao + 36 + i;  /* wm5 for cbcr */
-				*p2 = (regp2->paddr + regp2->info.planar1_off);
-				regp2--;
-			}
-
-			for (i = 2; i < ad->bufnum1; i++) {
-				ret = vfe31_add_free_buf(outp1, regp1);
-				if (ret < 0)
-					return ret;
-				regp1--;
-			}
-
-			for (i = 2; i < ad->bufnum2; i++) {
-				ret = vfe31_add_free_buf(outp2, regp2);
-				if (ret < 0)
-					return ret;
-				regp2--;
-			}
-		}
-		break;
-
-	case OUTPUT_1_2_AND_3:
-		CDBG("%s: OUTPUT_1_2_AND_3", __func__);
-		CDBG("%s: %d %d %d", __func__, ad->bufnum1, ad->bufnum2,
-			ad->bufnum3);
-		/* use wm0& 4 for postview, wm1&5 for preview.*/
-		/* use wm2& 6 for main img */
-		if ((ad->bufnum1 < 1) || (ad->bufnum2 < 1) || (ad->bufnum3 < 1))
-			return -EINVAL;
-		vfe31_ctrl->outpath.output_mode |=
-			VFE31_OUTPUT_MODE_S;  /* main image.*/
-		vfe31_ctrl->outpath.output_mode |=
-			VFE31_OUTPUT_MODE_P;  /* preview. */
-		vfe31_ctrl->outpath.output_mode |=
-			VFE31_OUTPUT_MODE_T;  /* thumbnail. */
-
-		/* this is preview buffer. */
-		regp1 = &(ad->region[0]);
-		/* this is thumbnail buffer. */
-		regp2 = &(ad->region[ad->bufnum1]);
-		/* this is main image buffer. */
-		regp3 = &(ad->region[ad->bufnum1+ad->bufnum2]);
-		outp1 = &(vfe31_ctrl->outpath.out0);
-		outp2 = &(vfe31_ctrl->outpath.out1);
-		outp3 = &(vfe31_ctrl->outpath.out2);
-
-		/*  Parse the buffers!!! */
-		/* first fill ping & pong */
-		for (i = 0; i < 2; i++) {
-			p1 = ao + 6 + i;    /* wm0 for y  */
-			*p1 = (regp1->paddr + regp1->info.planar0_off);
-			p1 = ao + 30 + i;  /* wm4 for cbcr */
-			*p1 = (regp1->paddr + regp1->info.planar1_off);
-			regp1++;
-		}
-
-		for (i = 0; i < 2; i++) {
-			p2 = ao + 12 + i;    /* wm1 for y  */
-			*p2 = (regp2->paddr + regp2->info.planar0_off);
-			p2 = ao + 36 + i;  /* wm5 for cbcr */
-			*p2 = (regp2->paddr + regp2->info.planar1_off);
-			regp2++;
-		}
-
-		for (i = 0; i < 2; i++) {
-			p3 = ao + 18 + i;    /* wm2 for y  */
-			*p3 = (regp3->paddr + regp3->info.planar0_off);
-			p3 = ao + 42 + i;  /* wm6 for cbcr */
-			*p3 = (regp3->paddr + regp3->info.planar1_off);
-			regp3++;
-		}
-
-		for (i = 2; i < ad->bufnum1; i++) {
-			ret = vfe31_add_free_buf(outp1, regp1);
-			if (ret < 0)
-				return ret;
-			regp1++;
-		}
-
-		for (i = 2; i < ad->bufnum2; i++) {
-			ret = vfe31_add_free_buf(outp2, regp2);
-			if (ret < 0)
-				return ret;
-			regp2++;
-		}
-
-		for (i = 2; i < ad->bufnum3; i++) {
-			ret = vfe31_add_free_buf(outp3, regp3);
-			if (ret < 0)
-				return ret;
-			regp3++;
-		}
-		break;
-
-	case OUTPUT_ZSL_ALL_CHNLS:
-		CDBG("%s: OUTPUT_ZSL_ALL_CHNLS", __func__);
-		CDBG("%s: %d %d %d", __func__, ad->bufnum1, ad->bufnum2,
-			ad->bufnum3);
-		/* use wm0& 4 for postview, wm1&5 for preview.*/
-		/* use wm2& 6 for main img */
-		if ((ad->bufnum1 < 1) || (ad->bufnum2 < 1) || (ad->bufnum3 < 1))
-			return -EINVAL;
-		vfe31_ctrl->outpath.output_mode |=
-			VFE31_OUTPUT_MODE_S;  /* main image.*/
-		vfe31_ctrl->outpath.output_mode |=
-			VFE31_OUTPUT_MODE_P_ALL_CHNLS;  /* preview. */
-		vfe31_ctrl->outpath.output_mode |=
-			VFE31_OUTPUT_MODE_T;  /* thumbnail. */
-
-		/* this is preview buffer. */
-		regp1 = &(ad->region[0]);
-		/* this is thumbnail buffer. */
-		regp2 = &(ad->region[ad->bufnum1]);
-		/* this is main image buffer. */
-		regp3 = &(ad->region[ad->bufnum1+ad->bufnum2]);
-		outp1 = &(vfe31_ctrl->outpath.out0);
-		outp2 = &(vfe31_ctrl->outpath.out1);
-		outp3 = &(vfe31_ctrl->outpath.out2);
-
-		/*  Parse the buffers!!! */
-		/* first fill ping & pong */
-		for (i = 0; i < 2; i++) {
-			p1 = ao + 6 + i;    /* wm0 for y  */
-			*p1 = (regp2->paddr + regp2->info.planar0_off);
-			p1 = ao + 12 + i;  /* wm1 for cbcr */
-			*p1 = (regp2->paddr + regp2->info.planar1_off);
-			regp2++;
-		}
-
-		for (i = 0; i < 2; i++) {
-			p2 = ao + 30 + i;    /* wm4 for y  */
-			*p2 = (regp1->paddr + regp1->info.planar0_off);
-			p2 = ao + 36 + i;  /* wm5 for cbcr */
-			*p2 = (regp1->paddr + regp1->info.planar1_off);
-			p2 = ao + 42 + i;  /* wm5 for cbcr */
-			*p2 = (regp1->paddr + regp1->info.planar2_off);
-			regp1++;
-		}
-
-		for (i = 0; i < 2; i++) {
-			p3 = ao + 18 + i;    /* wm2 for y  */
-			*p3 = (regp3->paddr + regp3->info.planar0_off);
-			p3 = ao + 24 + i;  /* wm3 for cbcr */
-			*p3 = (regp3->paddr + regp3->info.planar1_off);
-			regp3++;
-		}
-		for (i = 2; i < ad->bufnum1; i++) {
-			ret = vfe31_add_free_buf(outp1, regp1);
-			if (ret < 0)
-				return ret;
-			regp1++;
-		}
-
-		for (i = 2; i < ad->bufnum2; i++) {
-			ret = vfe31_add_free_buf(outp2, regp2);
-			if (ret < 0)
-				return ret;
-			regp2++;
-		}
-
-		for (i = 2; i < ad->bufnum3; i++) {
-			ret = vfe31_add_free_buf(outp3, regp3);
-			if (ret < 0)
-				return ret;
-			regp3++;
-		}
-		break;
-
-	case OUTPUT_1_AND_3: {
-		/* use wm0&4 for preview, wm1&5 for video.*/
-		if ((ad->bufnum1 < 2) || (ad->bufnum2 < 2))
-			return -EINVAL;
-
-#ifdef CONFIG_MSM_CAMERA_V4L2
-		*p++ = 0x1;    /* xbar cfg0 */
-		*p = 0x1a03;    /* xbar cfg1 */
-#endif
-		vfe31_ctrl->outpath.output_mode |=
-			VFE31_OUTPUT_MODE_V;  /* video*/
-		vfe31_ctrl->outpath.output_mode |=
-			VFE31_OUTPUT_MODE_PT;  /* preview */
-
-		regp1 = &(ad->region[0]); /* this is preview buffer. */
-		regp2 = &(ad->region[ad->bufnum1]);/* this is video buffer. */
-		outp1 = &(vfe31_ctrl->outpath.out0); /* preview */
-		outp2 = &(vfe31_ctrl->outpath.out2); /* video */
-
-
-		for (i = 0; i < 2; i++) {
-			p1 = ao + 6 + i;    /* wm0 for y  */
-			*p1 = (regp1->paddr + regp1->info.planar0_off);
-
-			p1 = ao + 30 + i;  /* wm4 for cbcr */
-			*p1 = (regp1->paddr + regp1->info.planar1_off);
-			regp1++;
-		}
-
-		for (i = 0; i < 2; i++) {
-			p2 = ao + 12 + i;    /* wm1 for y  */
-			*p2 = (regp2->paddr + regp2->info.planar0_off);
-
-			p2 = ao + 36 + i;  /* wm5 for cbcr */
-			*p2 = (regp2->paddr + regp2->info.planar1_off);
-			regp2++;
-		}
-		for (i = 2; i < ad->bufnum1; i++) {
-			ret = vfe31_add_free_buf(outp1, regp1);
-			if (ret < 0)
-				return ret;
-			regp1++;
-		}
-
-		for (i = 2; i < ad->bufnum2; i++) {
-			ret = vfe31_add_free_buf(outp2, regp2);
-			if (ret < 0)
-				return ret;
-			regp2++;
-		}
-	}
-		break;
-
-	case OUTPUT_VIDEO_ALL_CHNLS: {
-		/* use wm0&4 for preview, wm1&5 for video.*/
-		vfe31_ctrl->outpath.output_mode |=
-			VFE31_OUTPUT_MODE_V;  /* video*/
-		vfe31_ctrl->outpath.output_mode |=
-			VFE31_OUTPUT_MODE_P_ALL_CHNLS;
-		regp1 = &(ad->region[0]);
-		regp2 = &(ad->region[ad->bufnum1]);
-		outp1 = &(vfe31_ctrl->outpath.out0);
-		outp2 = &(vfe31_ctrl->outpath.out2);
-
-		for (i = 0; i < 2; i++) {
-			p1 = ao + 6 + i;    /* wm0 for y  */
-			*p1 = (regp1->paddr + regp1->info.planar0_off);
-
-			p1 = ao + 12 + i;  /* wm1 for cbcr */
-			*p1 = (regp1->paddr + regp1->info.planar1_off);
-
-			p1 = ao + 18 + i;  /* wm2 for cbcr */
-			*p1 = (regp1->paddr + regp1->info.planar2_off);
-			regp1++;
-		}
-		for (i = 0; i < 2; i++) {
-			p2 = ao + 30 + i;    /* wm4 for y  */
-			*p2 = (regp2->paddr + regp2->info.planar0_off);
-
-			p2 = ao + 36 + i;  /* wm5 for cbcr */
-			*p2 = (regp2->paddr + regp2->info.planar1_off);
-			regp2++;
-		}
-		for (i = 2; i < ad->bufnum1; i++) {
-			ret = vfe31_add_free_buf(outp1, regp1);
-			if (ret < 0)
-				return ret;
-			regp1++;
-		}
-		for (i = 2; i < ad->bufnum2; i++) {
-			ret = vfe31_add_free_buf(outp2, regp2);
-			if (ret < 0)
-				return ret;
-			regp2++;
-		}
-	}
-		break;
-
-	case CAMIF_TO_AXI_VIA_OUTPUT_2: {  /* use wm0 only */
-		if (ad->bufnum2 < 1)
-			return -EINVAL;
-		CDBG("config axi for raw snapshot.\n");
-		vfe31_ctrl->outpath.out1.ch0 = 0; /* raw */
-		regp1 = &(ad->region[ad->bufnum1]);
-		vfe31_ctrl->outpath.output_mode |= VFE31_OUTPUT_MODE_S;
-		p1 = ao + 6;    /* wm0 for y  */
-		*p1 = (regp1->paddr + regp1->info.planar0_off);
-		if (p_sync->stereocam_enabled)
-			p_sync->stereo_state = STEREO_RAW_SNAP_IDLE;
-	}
-		break;
-	default:
-		break;
-	}
-	msm_camera_io_memcpy(
-		vfe31_ctrl->vfebase + vfe31_cmd[V31_AXI_OUT_CFG].offset,
-		ao, vfe31_cmd[V31_AXI_OUT_CFG].length - V31_AXI_CH_INF_LEN);
-
-	return 0;
-}
-
-static void vfe31_reset_internal_variables(void)
-{
-	unsigned long flags;
-	vfe31_ctrl->vfeImaskCompositePacked = 0;
-	/* state control variables */
-	vfe31_ctrl->start_ack_pending = FALSE;
-	atomic_set(&irq_cnt, 0);
-
-	spin_lock_irqsave(&vfe31_ctrl->xbar_lock, flags);
-	vfe31_ctrl->xbar_update_pending = 0;
-	spin_unlock_irqrestore(&vfe31_ctrl->xbar_lock, flags);
-
-	atomic_set(&vfe31_ctrl->stop_ack_pending, 0);
-	atomic_set(&vfe31_ctrl->vstate, 0);
-
-	vfe31_ctrl->aec_ack_pending = FALSE;
-	vfe31_ctrl->af_ack_pending = FALSE;
-	vfe31_ctrl->awb_ack_pending = FALSE;
-	vfe31_ctrl->ihist_ack_pending = FALSE;
-	vfe31_ctrl->rs_ack_pending = FALSE;
-	vfe31_ctrl->cs_ack_pending = FALSE;
-
-	vfe31_ctrl->reset_ack_pending  = FALSE;
-
-	spin_lock_irqsave(&vfe31_ctrl->update_ack_lock, flags);
-	vfe31_ctrl->update_ack_pending = FALSE;
-	spin_unlock_irqrestore(&vfe31_ctrl->update_ack_lock, flags);
-
-	vfe31_ctrl->recording_state = VFE_REC_STATE_IDLE;
-
-	/* 0 for continuous mode, 1 for snapshot mode */
-	vfe31_ctrl->operation_mode = VFE_MODE_OF_OPERATION_CONTINUOUS;
-	vfe31_ctrl->outpath.output_mode = 0;
-	vfe31_ctrl->vfe_capture_count = 0;
-
-	/* this is unsigned 32 bit integer. */
-	vfe31_ctrl->vfeFrameId = 0;
-
-	vfe31_ctrl->output1Pattern = 0xffffffff;
-	vfe31_ctrl->output1Period  = 31;
-	vfe31_ctrl->output2Pattern = 0xffffffff;
-	vfe31_ctrl->output2Period  = 31;
-	vfe31_ctrl->vfeFrameSkipCount   = 0;
-	vfe31_ctrl->vfeFrameSkipPeriod  = 31;
-
-	/* Stats control variables. */
-	memset(&(vfe31_ctrl->afStatsControl), 0,
-		sizeof(struct vfe_stats_control));
-
-	memset(&(vfe31_ctrl->awbStatsControl), 0,
-		sizeof(struct vfe_stats_control));
-
-	memset(&(vfe31_ctrl->aecStatsControl), 0,
-		sizeof(struct vfe_stats_control));
-
-	memset(&(vfe31_ctrl->ihistStatsControl), 0,
-		sizeof(struct vfe_stats_control));
-
-	memset(&(vfe31_ctrl->rsStatsControl), 0,
-		sizeof(struct vfe_stats_control));
-
-	memset(&(vfe31_ctrl->csStatsControl), 0,
-		sizeof(struct vfe_stats_control));
-}
-
-static void vfe31_reset(void)
-{
-	uint32_t vfe_version;
-	vfe31_reset_free_buf_queue_all();
-	vfe31_reset_internal_variables();
-
-	vfe31_reset_hist_cfg();
-	vfe_version = msm_camera_io_r(vfe31_ctrl->vfebase);
-	CDBG("vfe_version = 0x%x\n", vfe_version);
-	/* disable all interrupts.  vfeImaskLocal is also reset to 0
-	* to begin with. */
-	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
-		vfe31_ctrl->vfebase + VFE_IRQ_MASK_0);
-
-	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
-		vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
-
-	/* clear all pending interrupts*/
-	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
-		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_0);
-	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
-		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_1);
-
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_IRQ_CMD);
-
-	/* enable reset_ack interrupt.  */
-	msm_camera_io_w(VFE_IMASK_RESET,
-		vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
-
-	/* Write to VFE_GLOBAL_RESET_CMD to reset the vfe hardware. Once reset
-	 * is done, hardware interrupt will be generated.  VFE ist processes
-	 * the interrupt to complete the function call.  Note that the reset
-	 * function is synchronous. */
-
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	msm_camera_io_w_mb(VFE_RESET_UPON_RESET_CMD,
-		vfe31_ctrl->vfebase + VFE_GLOBAL_RESET);
-}
-
-static int vfe31_operation_config(uint32_t *cmd)
-{
-	uint32_t *p = cmd;
-
-	vfe31_ctrl->operation_mode = *p;
-	vpe_ctrl->pad_2k_bool = (vfe31_ctrl->operation_mode & 1) ?
-		FALSE : TRUE;
-
-	vfe31_ctrl->stats_comp = *(++p);
-	vfe31_ctrl->hfr_mode = *(++p);
-
-	msm_camera_io_w(*(++p), vfe31_ctrl->vfebase + VFE_CFG_OFF);
-	msm_camera_io_w(*(++p), vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-	msm_camera_io_w(*(++p), vfe31_ctrl->vfebase + VFE_REALIGN_BUF);
-	msm_camera_io_w(*(++p), vfe31_ctrl->vfebase + VFE_CHROMA_UP);
-	msm_camera_io_w(*(++p), vfe31_ctrl->vfebase + VFE_STATS_CFG);
-	wmb();
-	return 0;
-}
-static uint32_t vfe_stats_awb_buf_init(struct vfe_cmd_stats_buf *in)
-{
-	uint32_t *ptr = in->statsBuf;
-	uint32_t addr;
-
-	addr = ptr[0];
-	msm_camera_io_w(addr,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR);
-	addr = ptr[1];
-	msm_camera_io_w(addr,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR);
-	vfe31_ctrl->awbStatsControl.nextFrameAddrBuf = in->statsBuf[2];
-	return 0;
-}
-
-
-static uint32_t vfe_stats_aec_buf_init(struct vfe_cmd_stats_buf *in)
-{
-	uint32_t *ptr = in->statsBuf;
-	uint32_t addr;
-
-	addr = ptr[0];
-	msm_camera_io_w(addr,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_AEC_WR_PING_ADDR);
-	addr = ptr[1];
-	msm_camera_io_w(addr,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_AEC_WR_PONG_ADDR);
-
-	vfe31_ctrl->aecStatsControl.nextFrameAddrBuf = in->statsBuf[2];
-	return 0;
-}
-
-static uint32_t vfe_stats_af_buf_init(struct vfe_cmd_stats_buf *in)
-{
-	uint32_t *ptr = in->statsBuf;
-	uint32_t addr;
-
-	addr = ptr[0];
-	msm_camera_io_w(addr,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR);
-	addr = ptr[1];
-	msm_camera_io_w(addr,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR);
-
-	vfe31_ctrl->afStatsControl.nextFrameAddrBuf = in->statsBuf[2];
-	return 0;
-}
-
-static uint32_t vfe_stats_ihist_buf_init(struct vfe_cmd_stats_buf *in)
-{
-	uint32_t *ptr = in->statsBuf;
-	uint32_t addr;
-
-	addr = ptr[0];
-	msm_camera_io_w(addr,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_HIST_WR_PING_ADDR);
-	addr = ptr[1];
-	msm_camera_io_w(addr,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_HIST_WR_PONG_ADDR);
-
-	vfe31_ctrl->ihistStatsControl.nextFrameAddrBuf = in->statsBuf[2];
-	return 0;
-}
-
-static uint32_t vfe_stats_rs_buf_init(struct vfe_cmd_stats_buf *in)
-{
-	uint32_t *ptr = in->statsBuf;
-	uint32_t addr;
-
-	addr = ptr[0];
-	msm_camera_io_w(addr,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_RS_WR_PING_ADDR);
-	addr = ptr[1];
-	msm_camera_io_w(addr,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_RS_WR_PONG_ADDR);
-
-	vfe31_ctrl->rsStatsControl.nextFrameAddrBuf = in->statsBuf[2];
-	return 0;
-}
-static uint32_t vfe_stats_cs_buf_init(struct vfe_cmd_stats_buf *in)
-{
-	uint32_t *ptr = in->statsBuf;
-	uint32_t addr;
-
-	addr = ptr[0];
-	msm_camera_io_w(addr,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_CS_WR_PING_ADDR);
-	addr = ptr[1];
-	msm_camera_io_w(addr,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_CS_WR_PONG_ADDR);
-
-	vfe31_ctrl->csStatsControl.nextFrameAddrBuf = in->statsBuf[2];
-	return 0;
-}
-
-static void vfe31_start_common(void)
-{
-	uint32_t irq_mask = 0x00E00021;
-	vfe31_ctrl->start_ack_pending = TRUE;
-	CDBG("VFE opertaion mode = 0x%x, output mode = 0x%x\n",
-		vfe31_ctrl->operation_mode, vfe31_ctrl->outpath.output_mode);
-	/* Enable IRQ for comp stats, Image master, SOF & Reg Update*/
-	if (vfe31_ctrl->stats_comp)
-		irq_mask |= 0x01000000;
-	else /* Enable IRQ for Image masters, AF stats, SOF & Reg Update */
-		irq_mask |= 0x00004000;
-
-	/* Enable EOF for video mode */
-	if (VFE_MODE_OF_OPERATION_VIDEO == vfe31_ctrl->operation_mode)
-		irq_mask |= 0x4;
-
-	msm_camera_io_w(irq_mask, vfe31_ctrl->vfebase + VFE_IRQ_MASK_0);
-
-	msm_camera_io_w(VFE_IMASK_RESET,
-		vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
-	/* enable out of order option */
-	msm_camera_io_w(0x80000000, vfe31_ctrl->vfebase + VFE_AXI_CFG);
-	/* enable performance monitor */
-	msm_camera_io_w(1, vfe31_ctrl->vfebase + VFE_BUS_PM_CFG);
-	msm_camera_io_w(1, vfe31_ctrl->vfebase + VFE_BUS_PM_CMD);
-
-
-	msm_camera_io_dump(vfe31_ctrl->vfebase, 0x600);
-
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-	msm_camera_io_w(1, vfe31_ctrl->vfebase + VFE_CAMIF_COMMAND);
-	wmb();
-
-	atomic_set(&vfe31_ctrl->vstate, 1);
-}
-
-static int vfe31_start_recording(void)
-{
-	msm_camio_set_perf_lvl(S_VIDEO);
-	usleep(1000);
-	vfe31_ctrl->recording_state = VFE_REC_STATE_START_REQUESTED;
-	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-	return 0;
-}
-
-static int vfe31_stop_recording(void)
-{
-	vfe31_ctrl->recording_state = VFE_REC_STATE_STOP_REQUESTED;
-	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-	msm_camio_set_perf_lvl(S_PREVIEW);
-	return 0;
-}
-
-static void vfe31_liveshot(void)
-{
-	struct msm_sync* p_sync = (struct msm_sync *)vfe_syncdata;
-	if (p_sync)
-		p_sync->liveshot_enabled = true;
-}
-
-static void vfe31_stereocam(uint32_t enable)
-{
-	struct msm_sync* p_sync = (struct msm_sync *)vfe_syncdata;
-	if (p_sync) {
-		CDBG("%s: Enable StereoCam %d!!!\n", __func__, enable);
-		p_sync->stereocam_enabled = enable;
-	}
-}
-
-static int vfe31_zsl(void)
-{
-	uint32_t irq_comp_mask = 0;
-	/* capture command is valid for both idle and active state. */
-	irq_comp_mask	=
-		msm_camera_io_r(vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
-
-	CDBG("%s:op mode %d O/P Mode %d\n", __func__,
-		vfe31_ctrl->operation_mode, vfe31_ctrl->outpath.output_mode);
-	if ((vfe31_ctrl->operation_mode == VFE_MODE_OF_OPERATION_ZSL)) {
-		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_P) {
-			irq_comp_mask |=
-				((0x1 << (vfe31_ctrl->outpath.out0.ch0)) |
-				(0x1 << (vfe31_ctrl->outpath.out0.ch1)));
-		} else if (vfe31_ctrl->outpath.output_mode &
-				VFE31_OUTPUT_MODE_P_ALL_CHNLS) {
-			irq_comp_mask |= (0x1 << vfe31_ctrl->outpath.out0.ch0 |
-				0x1 << vfe31_ctrl->outpath.out0.ch1 |
-				0x1 << vfe31_ctrl->outpath.out0.ch2);
-		}
-		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_T) {
-			irq_comp_mask |=
-				((0x1 << (vfe31_ctrl->outpath.out1.ch0 + 8)) |
-				(0x1 << (vfe31_ctrl->outpath.out1.ch1 + 8)));
-		}
-		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_S) {
-			irq_comp_mask |=
-			((0x1 << (vfe31_ctrl->outpath.out2.ch0 + 8)) |
-			(0x1 << (vfe31_ctrl->outpath.out2.ch1 + 8)));
-		}
-		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_P) {
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
-		} else if (vfe31_ctrl->outpath.output_mode &
-				VFE31_OUTPUT_MODE_P_ALL_CHNLS) {
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch2]);
-		}
-		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_T) {
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
-		}
-		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_S) {
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out2.ch0]);
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out2.ch1]);
-		}
-	}
-	msm_camera_io_w(irq_comp_mask, vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
-	vfe31_start_common();
-	msm_camio_set_perf_lvl(S_ZSL);
-	usleep(1000);
-	/* for debug */
-	msm_camera_io_w(1, vfe31_ctrl->vfebase + 0x18C);
-	msm_camera_io_w(1, vfe31_ctrl->vfebase + 0x188);
-	return 0;
-}
-
-static int vfe31_capture(uint32_t num_frames_capture)
-{
-	uint32_t irq_comp_mask = 0;
-	struct msm_sync* p_sync = (struct msm_sync *)vfe_syncdata;
-
-	/* capture command is valid for both idle and active state. */
-	vfe31_ctrl->vfe_capture_count = num_frames_capture;
-	if (p_sync) {
-		p_sync->snap_count = num_frames_capture;
-		p_sync->thumb_count = num_frames_capture;
-	}
-
-	irq_comp_mask	=
-		msm_camera_io_r(vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
-
-	if ((vfe31_ctrl->operation_mode ==
-		 VFE_MODE_OF_OPERATION_SNAPSHOT) ||
-		(vfe31_ctrl->operation_mode ==
-		 VFE_MODE_OF_OPERATION_ZSL)){
-		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_PT) {
-			irq_comp_mask |=
-				((0x1 << (vfe31_ctrl->outpath.out0.ch0 + 8)) |
-				(0x1 << (vfe31_ctrl->outpath.out0.ch1 + 8)));
-		}
-		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_S) {
-			irq_comp_mask |=
-			((0x1 << (vfe31_ctrl->outpath.out1.ch0 + 8)) |
-			(0x1 << (vfe31_ctrl->outpath.out1.ch1 + 8)));
-		}
-		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_PT) {
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
-		}
-		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_S) {
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
-		}
-	} else {  /* this is raw snapshot mode. */
-		CDBG("config the comp imask for raw snapshot mode.\n");
-		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_S) {
-			irq_comp_mask |=
-			(0x1 << (vfe31_ctrl->outpath.out1.ch0 + 8));
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
-		}
-	}
-	msm_camera_io_w(irq_comp_mask, vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
-	if (p_sync->stereocam_enabled)
-		msm_camio_set_perf_lvl(S_STEREO_CAPTURE);
-	else
-		msm_camio_set_perf_lvl(S_CAPTURE);
-
-	usleep(1000);
-	vfe31_start_common();
-	return 0;
-}
-
-static int vfe31_start(void)
-{
-	uint32_t irq_comp_mask = 0;
-	struct msm_sync* p_sync = (struct msm_sync *)vfe_syncdata;
-	/* start command now is only good for continuous mode. */
-	if ((vfe31_ctrl->operation_mode != VFE_MODE_OF_OPERATION_CONTINUOUS) &&
-		(vfe31_ctrl->operation_mode != VFE_MODE_OF_OPERATION_VIDEO))
-		return 0;
-	irq_comp_mask =
-		msm_camera_io_r(vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
-
-	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_PT) {
-		irq_comp_mask |= (0x1 << vfe31_ctrl->outpath.out0.ch0 |
-			0x1 << vfe31_ctrl->outpath.out0.ch1);
-			if (vfe31_ctrl->outpath.out0.ch2 >= 0)
-				irq_comp_mask |=
-					(0x1 << vfe31_ctrl->outpath.out0.ch0 |
-					0x1 << vfe31_ctrl->outpath.out0.ch1 |
-					0x1 << vfe31_ctrl->outpath.out0.ch2);
-	} else if (vfe31_ctrl->outpath.output_mode &
-		VFE31_OUTPUT_MODE_P_ALL_CHNLS) {
-			irq_comp_mask |= (0x1 << vfe31_ctrl->outpath.out0.ch0 |
-				0x1 << vfe31_ctrl->outpath.out0.ch1 |
-				0x1 << vfe31_ctrl->outpath.out0.ch2);
-	}
-
-	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_V) {
-		irq_comp_mask |= (0x1 << (vfe31_ctrl->outpath.out2.ch0 + 16)|
-			0x1 << (vfe31_ctrl->outpath.out2.ch1 + 16));
-	}
-
-	msm_camera_io_w(irq_comp_mask, vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
-
-
-	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_PT) {
-		msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
-		msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
-		if (vfe31_ctrl->outpath.out0.ch2 >= 0)
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch2]);
-	} else if (vfe31_ctrl->outpath.output_mode &
-		VFE31_OUTPUT_MODE_P_ALL_CHNLS) {
-		msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
-		msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
-		msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch2]);
-	}
-
-	if (p_sync->stereocam_enabled)
-		msm_camio_set_perf_lvl(S_STEREO_VIDEO);
-	else
-		msm_camio_set_perf_lvl(S_PREVIEW);
-
-	usleep(1000);
-	vfe31_start_common();
-	return 0;
-}
-
-static void vfe31_update(void)
-{
-	unsigned long flags;
-	CDBG("vfe31_update\n");
-
-	if (vfe31_ctrl->update_gamma) {
-		if (!msm_camera_io_r(vfe31_ctrl->vfebase + V31_GAMMA_CFG_OFF))
-			msm_camera_io_w(7,
-				vfe31_ctrl->vfebase+V31_GAMMA_CFG_OFF);
-		else
-			msm_camera_io_w(0,
-				vfe31_ctrl->vfebase+V31_GAMMA_CFG_OFF);
-		vfe31_ctrl->update_gamma = false;
-	}
-	if (vfe31_ctrl->update_luma) {
-		if (!msm_camera_io_r(vfe31_ctrl->vfebase + V31_LUMA_CFG_OFF))
-			msm_camera_io_w(1,
-				vfe31_ctrl->vfebase + V31_LUMA_CFG_OFF);
-		else
-			msm_camera_io_w(0,
-				vfe31_ctrl->vfebase + V31_LUMA_CFG_OFF);
-		vfe31_ctrl->update_luma = false;
-	}
-	spin_lock_irqsave(&vfe31_ctrl->update_ack_lock, flags);
-	vfe31_ctrl->update_ack_pending = TRUE;
-	spin_unlock_irqrestore(&vfe31_ctrl->update_ack_lock, flags);
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-	return;
-}
-
-static void vfe31_sync_timer_stop(void)
-{
-	uint32_t value = 0;
-	vfe31_ctrl->sync_timer_state = 0;
-	if (vfe31_ctrl->sync_timer_number == 0)
-		value = 0x10000;
-	else if (vfe31_ctrl->sync_timer_number == 1)
-		value = 0x20000;
-	else if (vfe31_ctrl->sync_timer_number == 2)
-		value = 0x40000;
-
-	/* Timer Stop */
-	msm_camera_io_w_mb(value, vfe31_ctrl->vfebase + V31_SYNC_TIMER_OFF);
-}
-
-static void vfe31_sync_timer_start(const uint32_t *tbl)
-{
-	/* set bit 8 for auto increment. */
-	uint32_t value = 1;
-	uint32_t val;
-
-	vfe31_ctrl->sync_timer_state = *tbl++;
-	vfe31_ctrl->sync_timer_repeat_count = *tbl++;
-	vfe31_ctrl->sync_timer_number = *tbl++;
-	CDBG("%s timer_state %d, repeat_cnt %d timer number %d\n",
-		 __func__, vfe31_ctrl->sync_timer_state,
-		 vfe31_ctrl->sync_timer_repeat_count,
-		 vfe31_ctrl->sync_timer_number);
-
-	if (vfe31_ctrl->sync_timer_state) { /* Start Timer */
-		value = value << vfe31_ctrl->sync_timer_number;
-	} else { /* Stop Timer */
-		CDBG("Failed to Start timer\n");
-		 return;
-	}
-
-	/* Timer Start */
-	msm_camera_io_w(value, vfe31_ctrl->vfebase + V31_SYNC_TIMER_OFF);
-	/* Sync Timer Line Start */
-	value = *tbl++;
-	msm_camera_io_w(value, vfe31_ctrl->vfebase + V31_SYNC_TIMER_OFF +
-		4 + ((vfe31_ctrl->sync_timer_number) * 12));
-	/* Sync Timer Pixel Start */
-	value = *tbl++;
-	msm_camera_io_w(value, vfe31_ctrl->vfebase + V31_SYNC_TIMER_OFF +
-			 8 + ((vfe31_ctrl->sync_timer_number) * 12));
-	/* Sync Timer Pixel Duration */
-	value = *tbl++;
-	val = camio_clk.vfe_clk_rate / 10000;
-	val = 10000000 / val;
-	val = value * 10000 / val;
-	CDBG("%s: Pixel Clk Cycles!!! %d\n", __func__, val);
-	msm_camera_io_w(val, vfe31_ctrl->vfebase + V31_SYNC_TIMER_OFF +
-		12 + ((vfe31_ctrl->sync_timer_number) * 12));
-	/* Timer0 Active High/LOW */
-	value = *tbl++;
-	msm_camera_io_w(value,
-		vfe31_ctrl->vfebase + V31_SYNC_TIMER_POLARITY_OFF);
-	/* Selects sync timer 0 output to drive onto timer1 port */
-	value = 0;
-	msm_camera_io_w(value, vfe31_ctrl->vfebase + V31_TIMER_SELECT_OFF);
-	wmb();
-}
-
-static void vfe31_program_dmi_cfg(enum VFE31_DMI_RAM_SEL bankSel)
-{
-	/* set bit 8 for auto increment. */
-	uint32_t value = VFE_DMI_CFG_DEFAULT;
-	value += (uint32_t)bankSel;
-
-	msm_camera_io_w_mb(value, vfe31_ctrl->vfebase + VFE_DMI_CFG);
-	/* by default, always starts with offset 0.*/
-	msm_camera_io_w(0, vfe31_ctrl->vfebase + VFE_DMI_ADDR);
-	wmb();
-}
-static void vfe31_write_gamma_cfg(enum VFE31_DMI_RAM_SEL channel_sel,
-						const uint32_t *tbl)
-{
-	int i;
-	uint32_t value, value1, value2;
-	vfe31_program_dmi_cfg(channel_sel);
-	/* for loop for extracting init table. */
-	for (i = 0 ; i < (VFE31_GAMMA_NUM_ENTRIES/2) ; i++) {
-		value = *tbl++;
-		value1 = value & 0x0000FFFF;
-		value2 = (value & 0xFFFF0000)>>16;
-		msm_camera_io_w((value1),
-			vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
-		msm_camera_io_w((value2),
-			vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
-	}
-	vfe31_program_dmi_cfg(NO_MEM_SELECTED);
-}
-
-static void vfe31_reset_hist_cfg()
-{
-	uint32_t i;
-	uint32_t value = 0;
-
-	vfe31_program_dmi_cfg(STATS_HIST_RAM);
-	for (i = 0 ; i < VFE31_HIST_TABLE_LENGTH ; i++)
-		msm_camera_io_w(value, vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
-	vfe31_program_dmi_cfg(NO_MEM_SELECTED);
-}
-
-static void vfe31_write_la_cfg(enum VFE31_DMI_RAM_SEL channel_sel,
-						const uint32_t *tbl)
-{
-	uint32_t i;
-	uint32_t value, value1, value2;
-
-	vfe31_program_dmi_cfg(channel_sel);
-	/* for loop for extracting init table. */
-	for (i = 0 ; i < (VFE31_LA_TABLE_LENGTH/2) ; i++) {
-		value = *tbl++;
-		value1 = value & 0x0000FFFF;
-		value2 = (value & 0xFFFF0000)>>16;
-		msm_camera_io_w((value1),
-			vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
-		msm_camera_io_w((value2),
-			vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
-	}
-	vfe31_program_dmi_cfg(NO_MEM_SELECTED);
-}
-
-static int vfe31_proc_general(struct msm_vfe31_cmd *cmd)
-{
-	int i , rc = 0;
-	uint32_t old_val = 0 , new_val = 0;
-	uint32_t *cmdp = NULL;
-	uint32_t *cmdp_local = NULL;
-	uint32_t snapshot_cnt = 0;
-	uint32_t stereo_cam_enable = 0;
-	struct msm_sync* p_sync = (struct msm_sync *)vfe_syncdata;
-
-	CDBG("vfe31_proc_general: cmdID = %s, length = %d\n",
-		vfe31_general_cmd[cmd->id], cmd->length);
-	switch (cmd->id) {
-	case V31_RESET:
-		pr_info("vfe31_proc_general: cmdID = %s\n",
-			vfe31_general_cmd[cmd->id]);
-		vfe31_reset();
-		break;
-	case V31_START:
-		pr_info("vfe31_proc_general: cmdID = %s\n",
-			vfe31_general_cmd[cmd->id]);
-		rc = vfe31_start();
-		break;
-	case V31_UPDATE:
-		vfe31_update();
-		break;
-	case V31_ZSL:
-		pr_info("vfe31_proc_general: cmdID = %s\n",
-			vfe31_general_cmd[cmd->id]);
-		vfe31_zsl();
-		break;
-	case V31_CAPTURE:
-		pr_info("vfe31_proc_general: cmdID = %s\n",
-			vfe31_general_cmd[cmd->id]);
-		if (copy_from_user(&snapshot_cnt, (void __user *)(cmd->value),
-				sizeof(uint32_t))) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		rc = vfe31_capture(snapshot_cnt);
-		break;
-	case V31_START_RECORDING:
-		pr_info("vfe31_proc_general: cmdID = %s\n",
-			vfe31_general_cmd[cmd->id]);
-		rc = vfe31_start_recording();
-		if (p_sync->stereocam_enabled)
-			p_sync->stereo_state = STEREO_VIDEO_ACTIVE;
-		break;
-	case V31_STOP_RECORDING:
-		pr_info("vfe31_proc_general: cmdID = %s\n",
-			vfe31_general_cmd[cmd->id]);
-		rc = vfe31_stop_recording();
-		if (p_sync->stereocam_enabled)
-			p_sync->stereo_state = STEREO_VIDEO_IDLE;
-		break;
-	case V31_OPERATION_CFG: {
-		if (cmd->length != V31_OPERATION_CFG_LEN) {
-			rc = -EINVAL;
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(V31_OPERATION_CFG_LEN, GFP_ATOMIC);
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			V31_OPERATION_CFG_LEN)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		rc = vfe31_operation_config(cmdp);
-		}
-		break;
-
-	case V31_STATS_AE_START: {
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val |= AE_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
-		cmdp, (vfe31_cmd[cmd->id].length));
-		}
-		break;
-	case V31_STATS_AF_START: {
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val |= AF_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
-		cmdp, (vfe31_cmd[cmd->id].length));
-		}
-		break;
-	case V31_STATS_AWB_START: {
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val |= AWB_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
-			cmdp, (vfe31_cmd[cmd->id].length));
-		}
-		break;
-
-	case V31_STATS_IHIST_START: {
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val |= IHIST_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
-			cmdp, (vfe31_cmd[cmd->id].length));
-		}
-		break;
-
-	case V31_XBAR_CFG: {
-		unsigned long flags = 0;
-		spin_lock_irqsave(&vfe31_ctrl->xbar_lock, flags);
-		if ((cmd->length != V31_XBAR_CFG_LEN)
-			|| vfe31_ctrl->xbar_update_pending) {
-			rc = -EINVAL;
-			spin_unlock_irqrestore(&vfe31_ctrl->xbar_lock, flags);
-			goto proc_general_done;
-		}
-		spin_unlock_irqrestore(&vfe31_ctrl->xbar_lock, flags);
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		spin_lock_irqsave(&vfe31_ctrl->xbar_lock, flags);
-		vfe31_ctrl->xbar_cfg[0] = *cmdp;
-		vfe31_ctrl->xbar_cfg[1] = *(cmdp+1);
-		vfe31_ctrl->xbar_update_pending = 1;
-		spin_unlock_irqrestore(&vfe31_ctrl->xbar_lock, flags);
-		CDBG("%s: xbar0 0x%x xbar1 0x%x", __func__,
-			vfe31_ctrl->xbar_cfg[0],
-			vfe31_ctrl->xbar_cfg[1]);
-		}
-		break;
-
-	case V31_STATS_RS_START: {
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
-			cmdp, (vfe31_cmd[cmd->id].length));
-		}
-		break;
-
-	case V31_STATS_CS_START: {
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
-			cmdp, (vfe31_cmd[cmd->id].length));
-		}
-		break;
-
-	case V31_MCE_UPDATE:
-	case V31_MCE_CFG:{
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		/* Incrementing with 4 so as to point to the 2nd Register as
-		the 2nd register has the mce_enable bit */
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase +
-						V31_CHROMA_SUP_OFF + 4);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		new_val = *cmdp_local;
-		old_val &= MCE_EN_MASK;
-		new_val = new_val | old_val;
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + V31_CHROMA_SUP_OFF + 4,
-			&new_val, 4);
-		cmdp_local += 1;
-
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase +
-						V31_CHROMA_SUP_OFF + 8);
-		new_val = *cmdp_local;
-		old_val &= MCE_Q_K_MASK;
-		new_val = new_val | old_val;
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + V31_CHROMA_SUP_OFF + 8,
-			&new_val, 4);
-		cmdp_local += 1;
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
-			cmdp_local, (vfe31_cmd[cmd->id].length));
-		}
-		break;
-	case V31_DEMOSAIC_2_UPDATE: /* 38 BPC update   */
-	case V31_DEMOSAIC_2_CFG: {  /* 14 BPC config   */
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		new_val = *cmdp_local;
-
-		old_val = msm_camera_io_r(
-				vfe31_ctrl->vfebase + V31_DEMOSAIC_0_OFF);
-		old_val &= BPC_MASK;
-
-		new_val = new_val | old_val;
-		*cmdp_local = new_val;
-		msm_camera_io_memcpy(vfe31_ctrl->vfebase + V31_DEMOSAIC_0_OFF,
-					cmdp_local, 4);
-		cmdp_local += 1;
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
-			cmdp_local, (vfe31_cmd[cmd->id].length));
-		}
-		break;
-	case V31_DEMOSAIC_1_UPDATE:/* 37 ABF update  */
-	case V31_DEMOSAIC_1_CFG: { /* 13 ABF config  */
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		new_val = *cmdp_local;
-
-		old_val = msm_camera_io_r(
-				vfe31_ctrl->vfebase + V31_DEMOSAIC_0_OFF);
-		old_val &= ABF_MASK;
-		new_val = new_val | old_val;
-		*cmdp_local = new_val;
-
-		msm_camera_io_memcpy(vfe31_ctrl->vfebase + V31_DEMOSAIC_0_OFF,
-		    cmdp_local, 4);
-
-		cmdp_local += 1;
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
-			cmdp_local, (vfe31_cmd[cmd->id].length));
-		}
-		break;
-	case V31_ROLL_OFF_CFG: {
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value) , cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
-		cmdp_local, 16);
-		cmdp_local += 4;
-		vfe31_program_dmi_cfg(ROLLOFF_RAM);
-		/* for loop for extrcting init table. */
-		for (i = 0 ; i < (VFE31_ROLL_OFF_INIT_TABLE_SIZE * 2) ; i++) {
-			msm_camera_io_w(*cmdp_local ,
-			vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
-			cmdp_local++;
-		}
-		CDBG("done writing init table\n");
-		/* by default, always starts with offset 0. */
-		msm_camera_io_w(LENS_ROLL_OFF_DELTA_TABLE_OFFSET,
-		vfe31_ctrl->vfebase + VFE_DMI_ADDR);
-		/* for loop for extracting delta table. */
-		for (i = 0 ; i < (VFE31_ROLL_OFF_DELTA_TABLE_SIZE * 2) ; i++) {
-			msm_camera_io_w(*cmdp_local,
-			vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
-			cmdp_local++;
-		}
-		vfe31_program_dmi_cfg(NO_MEM_SELECTED);
-		}
-		break;
-
-	case V31_LA_CFG:{
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		/* Select Bank 0*/
-		*cmdp = 0;
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
-			cmdp, (vfe31_cmd[cmd->id].length));
-		cmdp += 1;
-		vfe31_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK0 , cmdp);
-		cmdp -= 1;
-		}
-		break;
-
-	case V31_LA_UPDATE: {
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		old_val = msm_camera_io_r(
-				vfe31_ctrl->vfebase + V31_LUMA_CFG_OFF);
-		cmdp += 1;
-		if (old_val != 0x0)
-			vfe31_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK0 , cmdp);
-		else
-			vfe31_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK1 , cmdp);
-		vfe31_ctrl->update_luma = true;
-		cmdp -= 1;
-		}
-		break;
-
-	case V31_SK_ENHAN_CFG:
-	case V31_SK_ENHAN_UPDATE:{
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		msm_camera_io_memcpy(vfe31_ctrl->vfebase + V31_SCE_OFF,
-				cmdp, V31_SCE_LEN);
-		}
-		break;
-
-	case V31_LIVESHOT:
-		vfe31_liveshot();
-		break;
-
-	case V31_STEREOCAM:
-		if (copy_from_user(&stereo_cam_enable,
-			(void __user *)(cmd->value), sizeof(uint32_t))) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		vfe31_stereocam(stereo_cam_enable);
-		break;
-
-	case V31_RGB_G_CFG: {
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		/* Select Bank 0*/
-		*cmdp = 0;
-		msm_camera_io_memcpy(vfe31_ctrl->vfebase + V31_RGB_G_OFF,
-				cmdp, 4);
-		cmdp += 1;
-		vfe31_write_gamma_cfg(RGBLUT_CHX_BANK0, cmdp);
-		cmdp -= 1;
-		}
-		break;
-
-	case V31_RGB_G_UPDATE: {
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp, (void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		old_val = msm_camera_io_r(
-				vfe31_ctrl->vfebase + V31_GAMMA_CFG_OFF);
-		cmdp += 1;
-
-		if (!old_val) {
-			vfe31_write_gamma_cfg(RGBLUT_CHX_BANK1, cmdp);
-		} else {
-			vfe31_write_gamma_cfg(RGBLUT_CHX_BANK0, cmdp);
-			}
-		vfe31_ctrl->update_gamma = true;
-		cmdp -= 1;
-		}
-		break;
-
-	case V31_STATS_AWB_STOP: {
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= ~AWB_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		}
-		break;
-	case V31_STATS_AE_STOP: {
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= ~AE_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		}
-		break;
-	case V31_STATS_AF_STOP: {
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= ~AF_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		}
-		break;
-
-	case V31_STATS_IHIST_STOP: {
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= ~IHIST_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		}
-		break;
-
-	case V31_STATS_RS_STOP: {
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= ~RS_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		}
-		break;
-
-	case V31_STATS_CS_STOP: {
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= ~CS_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		}
-		break;
-	case V31_STOP:
-		pr_info("vfe31_proc_general: cmdID = %s\n",
-			vfe31_general_cmd[cmd->id]);
-		vfe31_stop();
-		break;
-
-	case V31_SYNC_TIMER_SETTING:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp, (void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		vfe31_sync_timer_start(cmdp);
-		break;
-
-	case V31_EZTUNE_CFG: {
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		*cmdp &= ~STATS_ENABLE_MASK;
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= STATS_ENABLE_MASK;
-		*cmdp |= old_val;
-
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
-			cmdp, (vfe31_cmd[cmd->id].length));
-		}
-		break;
-
-	default: {
-		if (cmd->length != vfe31_cmd[cmd->id].length)
-			return -EINVAL;
-
-		cmdp = kmalloc(vfe31_cmd[cmd->id].length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-
-		if (copy_from_user(cmdp, (void __user *)cmd->value,
-				cmd->length)) {
-			rc = -EFAULT;
-			pr_err("%s copy from user failed for cmd %d",
-				__func__, cmd->id);
-			goto proc_general_done;
-		}
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
-			cmdp, (vfe31_cmd[cmd->id].length));
-	}
-	break;
-
-	}
-
-proc_general_done:
-	kfree(cmdp);
-
-	return rc;
-}
-
-static void vfe31_stats_af_ack(struct vfe_cmd_stats_ack *pAck)
-{
-	vfe31_ctrl->afStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
-	vfe31_ctrl->af_ack_pending = FALSE;
-}
-
-static void vfe31_stats_awb_ack(struct vfe_cmd_stats_ack *pAck)
-{
-	vfe31_ctrl->awbStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
-	vfe31_ctrl->awb_ack_pending = FALSE;
-}
-
-static void vfe31_stats_aec_ack(struct vfe_cmd_stats_ack *pAck)
-{
-	vfe31_ctrl->aecStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
-	vfe31_ctrl->aec_ack_pending = FALSE;
-}
-
-static void vfe31_stats_ihist_ack(struct vfe_cmd_stats_ack *pAck)
-{
-	vfe31_ctrl->ihistStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
-	vfe31_ctrl->ihist_ack_pending = FALSE;
-}
-
-static void vfe31_stats_rs_ack(struct vfe_cmd_stats_ack *pAck)
-{
-	vfe31_ctrl->rsStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
-	vfe31_ctrl->rs_ack_pending = FALSE;
-}
-
-static void vfe31_stats_cs_ack(struct vfe_cmd_stats_ack *pAck)
-{
-	vfe31_ctrl->csStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
-	vfe31_ctrl->cs_ack_pending = FALSE;
-}
-
-static int vfe31_config(struct msm_vfe_cfg_cmd *cmd, void *data)
-{
-	struct msm_vfe31_cmd vfecmd;
-
-	long rc = 0;
-	uint32_t i = 0;
-	struct vfe_cmd_stats_buf *scfg = NULL;
-	struct msm_pmem_region   *regptr = NULL;
-	struct vfe_cmd_stats_ack *sack = NULL;
-
-	if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
-		cmd->cmd_type != CMD_SNAP_BUF_RELEASE &&
-		cmd->cmd_type != CMD_STATS_AEC_BUF_RELEASE &&
-		cmd->cmd_type != CMD_STATS_AWB_BUF_RELEASE &&
-		cmd->cmd_type != CMD_STATS_IHIST_BUF_RELEASE &&
-		cmd->cmd_type != CMD_STATS_RS_BUF_RELEASE &&
-		cmd->cmd_type != CMD_STATS_CS_BUF_RELEASE &&
-		cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE) {
-		if (copy_from_user(&vfecmd,
-				(void __user *)(cmd->value),
-				sizeof(vfecmd))) {
-			pr_err("%s %d: copy_from_user failed\n", __func__,
-				__LINE__);
-			return -EFAULT;
-		}
-	} else {
-	/* here eith stats release or frame release. */
-		if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
-			cmd->cmd_type != CMD_SNAP_BUF_RELEASE) {
-			/* then must be stats release. */
-			if (!data)
-				return -EFAULT;
-				sack = kmalloc(sizeof(struct vfe_cmd_stats_ack),
-				GFP_ATOMIC);
-				if (!sack)
-					return -ENOMEM;
-
-				sack->nextStatsBuf = *(uint32_t *)data;
-			}
-	}
-
-	CDBG("%s: cmdType = %d\n", __func__, cmd->cmd_type);
-
-	if ((cmd->cmd_type == CMD_STATS_AF_ENABLE) ||
-		(cmd->cmd_type == CMD_STATS_AWB_ENABLE) ||
-		(cmd->cmd_type == CMD_STATS_IHIST_ENABLE) ||
-		(cmd->cmd_type == CMD_STATS_RS_ENABLE) ||
-		(cmd->cmd_type == CMD_STATS_CS_ENABLE) ||
-		(cmd->cmd_type == CMD_STATS_AEC_ENABLE)) {
-		struct axidata *axid;
-		axid = data;
-		if (!axid) {
-			rc = -EFAULT;
-			goto vfe31_config_done;
-		}
-
-		scfg =
-			kmalloc(sizeof(struct vfe_cmd_stats_buf),
-				GFP_ATOMIC);
-		if (!scfg) {
-			rc = -ENOMEM;
-			goto vfe31_config_done;
-		}
-		regptr = axid->region;
-		if (axid->bufnum1 > 0) {
-			for (i = 0; i < axid->bufnum1; i++) {
-				scfg->statsBuf[i] =
-					(uint32_t)(regptr->paddr);
-				regptr++;
-			}
-		}
-		/* individual */
-		switch (cmd->cmd_type) {
-		case CMD_STATS_AEC_ENABLE:
-			rc = vfe_stats_aec_buf_init(scfg);
-			break;
-		case CMD_STATS_AF_ENABLE:
-			rc = vfe_stats_af_buf_init(scfg);
-			break;
-		case CMD_STATS_AWB_ENABLE:
-			rc = vfe_stats_awb_buf_init(scfg);
-			break;
-		case CMD_STATS_IHIST_ENABLE:
-			rc = vfe_stats_ihist_buf_init(scfg);
-			break;
-		case CMD_STATS_RS_ENABLE:
-			rc = vfe_stats_rs_buf_init(scfg);
-			break;
-		case CMD_STATS_CS_ENABLE:
-			rc = vfe_stats_cs_buf_init(scfg);
-			break;
-		}
-	}
-
-	switch (cmd->cmd_type) {
-	case CMD_GENERAL:
-		rc = vfe31_proc_general(&vfecmd);
-		break;
-
-	case CMD_FRAME_BUF_RELEASE: {
-		struct msm_frame *b;
-		unsigned long p;
-		int ret;
-		struct vfe31_output_ch *outch = NULL;
-		if (!data) {
-			rc = -EFAULT;
-			break;
-		}
-
-		b = (struct msm_frame *)(cmd->value);
-		p = *(unsigned long *)data;
-
-		CDBG("CMD_FRAME_BUF_RELEASE b->path = %d\n", b->path);
-
-		if (b->path & OUTPUT_TYPE_P) {
-			CDBG("CMD_FRAME_BUF_RELEASE got free buffer\n");
-			outch = &vfe31_ctrl->outpath.out0;
-		} else if (b->path & OUTPUT_TYPE_S) {
-			outch = &vfe31_ctrl->outpath.out1;
-		} else if (b->path & OUTPUT_TYPE_V) {
-			outch = &vfe31_ctrl->outpath.out2;
-		} else {
-			rc = -EFAULT;
-			break;
-		}
-
-		ret = vfe31_add_free_buf2(outch, p, b->planar0_off,
-			b->planar1_off, b->planar2_off);
-		if (ret < 0)
-			return ret;
-		break;
-	}
-
-	case CMD_SNAP_BUF_RELEASE: {
-		struct msm_frame *b;
-		unsigned long p;
-		int ret;
-		struct vfe31_output_ch *outch = NULL;
-		if (!data)
-			return -EFAULT;
-
-		b = (struct msm_frame *)(cmd->value);
-		p = *(unsigned long *)data;
-
-		CDBG("CMD_PIC_BUF_RELEASE b->path = %d\n", b->path);
-
-		if (b->path & OUTPUT_TYPE_T) {
-			CDBG("CMD_FRAME_BUF_RELEASE got free buffer\n");
-			outch = &vfe31_ctrl->outpath.out1;
-		} else if (b->path & OUTPUT_TYPE_S) {
-			outch = &vfe31_ctrl->outpath.out2;
-		} else
-			return -EFAULT;
-
-		ret = vfe31_add_free_buf2(outch, p, b->planar0_off,
-			b->planar1_off,	b->planar2_off);
-		if (ret < 0)
-			return ret;
-		break;
-	}
-
-	case CMD_STATS_AEC_BUF_RELEASE:
-		vfe31_stats_aec_ack(sack);
-		break;
-
-	case CMD_STATS_AF_BUF_RELEASE:
-		vfe31_stats_af_ack(sack);
-		break;
-
-	case CMD_STATS_AWB_BUF_RELEASE:
-		vfe31_stats_awb_ack(sack);
-		break;
-
-	case CMD_STATS_IHIST_BUF_RELEASE:
-		vfe31_stats_ihist_ack(sack);
-		break;
-
-	case CMD_STATS_RS_BUF_RELEASE:
-		vfe31_stats_rs_ack(sack);
-		break;
-
-	case CMD_STATS_CS_BUF_RELEASE:
-		vfe31_stats_cs_ack(sack);
-		break;
-
-	case CMD_AXI_CFG_PREVIEW: {
-		struct axidata *axid;
-		uint32_t *axio = NULL;
-		axid = data;
-		if (!axid) {
-			rc = -EFAULT;
-			break;
-		}
-		axio =
-			kmalloc(vfe31_cmd[V31_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			break;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe31_cmd[V31_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			rc = -EFAULT;
-			break;
-		}
-		vfe31_config_axi(OUTPUT_2, axid, axio);
-		kfree(axio);
-		break;
-	}
-
-	case CMD_RAW_PICT_AXI_CFG: {
-		struct axidata *axid;
-		uint32_t *axio = NULL;
-		axid = data;
-		if (!axid) {
-			rc = -EFAULT;
-			break;
-		}
-		axio =
-			kmalloc(vfe31_cmd[V31_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			break;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe31_cmd[V31_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			rc = -EFAULT;
-			break;
-		}
-		vfe31_config_axi(CAMIF_TO_AXI_VIA_OUTPUT_2, axid, axio);
-		kfree(axio);
-		break;
-	}
-
-	case CMD_AXI_CFG_SNAP: {
-		struct axidata *axid;
-		uint32_t *axio = NULL;
-		CDBG("%s, CMD_AXI_CFG_SNAP\n", __func__);
-		axid = data;
-		if (!axid)
-			return -EFAULT;
-		axio =
-			kmalloc(vfe31_cmd[V31_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			break;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe31_cmd[V31_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			rc = -EFAULT;
-			break;
-		}
-		vfe31_config_axi(OUTPUT_1_AND_2, axid, axio);
-		kfree(axio);
-		break;
-	}
-
-	case CMD_AXI_CFG_ZSL: {
-		struct axidata *axid;
-		uint32_t *axio = NULL;
-		CDBG("%s, CMD_AXI_CFG_ZSL\n", __func__);
-		axid = data;
-		if (!axid)
-			return -EFAULT;
-		axio =
-			kmalloc(vfe31_cmd[V31_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			break;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe31_cmd[V31_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			rc = -EFAULT;
-			break;
-		}
-		vfe31_config_axi(OUTPUT_1_2_AND_3, axid, axio);
-		kfree(axio);
-	}
-		break;
-
-	case CMD_AXI_CFG_ZSL_ALL_CHNLS: {
-		struct axidata *axid;
-		uint32_t *axio;
-		CDBG("%s, CMD_AXI_CFG_ZSL\n", __func__);
-		axid = data;
-		if (!axid)
-			return -EFAULT;
-		axio =
-			kmalloc(vfe31_cmd[V31_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			break;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe31_cmd[V31_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			rc = -EFAULT;
-			break;
-		}
-		vfe31_config_axi(OUTPUT_ZSL_ALL_CHNLS, axid, axio);
-		kfree(axio);
-	}
-		break;
-
-	case CMD_AXI_CFG_VIDEO: {
-		struct axidata *axid;
-		uint32_t *axio = NULL;
-		axid = data;
-		if (!axid) {
-			rc = -EFAULT;
-			break;
-		}
-
-		axio =
-			kmalloc(vfe31_cmd[V31_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			break;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe31_cmd[V31_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			rc = -EFAULT;
-			break;
-		}
-		vfe31_config_axi(OUTPUT_1_AND_3, axid, axio);
-		kfree(axio);
-		break;
-	}
-
-	case CMD_AXI_CFG_VIDEO_ALL_CHNLS: {
-		struct axidata *axid;
-		uint32_t *axio = NULL;
-		axid = data;
-		if (!axid) {
-			rc = -EFAULT;
-			break;
-		}
-
-		axio =
-			kmalloc(vfe31_cmd[V31_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			break;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe31_cmd[V31_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			rc = -EFAULT;
-			break;
-		}
-		vfe31_config_axi(OUTPUT_VIDEO_ALL_CHNLS, axid, axio);
-		kfree(axio);
-		break;
-	}
-
-	default:
-		break;
-	}
-vfe31_config_done:
-	kfree(scfg);
-	kfree(sack);
-	CDBG("%s done: rc = %d\n", __func__, (int) rc);
-	return rc;
-}
-
-static void vfe31_send_msg_no_payload(enum VFE31_MESSAGE_ID id)
-{
-	struct vfe_message msg;
-
-	CDBG("vfe31_send_msg_no_payload\n");
-	msg._d = id;
-	vfe31_proc_ops(id, &msg, 0);
-}
-
-static void vfe31_process_reg_update_irq(void)
-{
-	uint32_t  temp, old_val;
-	unsigned long flags;
-	if (vfe31_ctrl->recording_state == VFE_REC_STATE_START_REQUESTED) {
-		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_V) {
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out2.ch0]);
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out2.ch1]);
-		}
-		vfe31_ctrl->recording_state = VFE_REC_STATE_STARTED;
-		if (vpe_ctrl->dis_en) {
-			old_val = msm_camera_io_r(
-				vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-			old_val |= RS_CS_ENABLE_MASK;
-			msm_camera_io_w(old_val,
-				vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		}
-		msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-		CDBG("start video triggered .\n");
-	} else if (vfe31_ctrl->recording_state
-			== VFE_REC_STATE_STOP_REQUESTED) {
-		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_V) {
-			msm_camera_io_w(0, vfe31_ctrl->vfebase +
-				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out2.ch0]);
-			msm_camera_io_w(0, vfe31_ctrl->vfebase +
-				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out2.ch1]);
-		}
-
-		/*disable rs& cs when stop recording. */
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= (~RS_CS_ENABLE_MASK);
-		msm_camera_io_w(old_val,
-				vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		CDBG("stop video triggered\n");
-	}
-	if (vfe31_ctrl->start_ack_pending == TRUE) {
-		vfe31_send_msg_no_payload(MSG_ID_START_ACK);
-		vfe31_ctrl->start_ack_pending = FALSE;
-	} else {
-		if (vfe31_ctrl->recording_state ==
-			VFE_REC_STATE_STOP_REQUESTED) {
-			vfe31_ctrl->recording_state = VFE_REC_STATE_STOPPED;
-			msm_camera_io_w_mb(1, vfe31_ctrl->vfebase +
-						VFE_REG_UPDATE_CMD);
-		} else if (vfe31_ctrl->recording_state ==
-			VFE_REC_STATE_STOPPED) {
-			CDBG("sent stop video rec ACK");
-			vfe31_send_msg_no_payload(MSG_ID_STOP_REC_ACK);
-			vfe31_ctrl->recording_state = VFE_REC_STATE_IDLE;
-		}
-		spin_lock_irqsave(&vfe31_ctrl->update_ack_lock, flags);
-		if (vfe31_ctrl->update_ack_pending == TRUE) {
-			vfe31_ctrl->update_ack_pending = FALSE;
-			spin_unlock_irqrestore(
-				&vfe31_ctrl->update_ack_lock, flags);
-			vfe31_send_msg_no_payload(MSG_ID_UPDATE_ACK);
-		} else {
-			spin_unlock_irqrestore(
-				&vfe31_ctrl->update_ack_lock, flags);
-		}
-	}
-	/* in snapshot mode */
-	if (vfe31_ctrl->operation_mode ==
-		VFE_MODE_OF_OPERATION_SNAPSHOT) {
-		/* later we need to add check for live snapshot mode. */
-
-		if (vfe31_ctrl->vfe_capture_count)
-			vfe31_ctrl->vfe_capture_count--;
-		/* if last frame to be captured: */
-		if (vfe31_ctrl->vfe_capture_count == 0) {
-			/* stop the bus output:  write master enable = 0*/
-			if (vfe31_ctrl->outpath.output_mode &
-					VFE31_OUTPUT_MODE_PT) {
-				msm_camera_io_w(0, vfe31_ctrl->vfebase +
-					vfe31_AXI_WM_CFG[
-						vfe31_ctrl->outpath.out0.ch0]);
-				msm_camera_io_w(0, vfe31_ctrl->vfebase +
-					vfe31_AXI_WM_CFG[vfe31_ctrl->
-						outpath.out0.ch1]);
-			}
-			if (vfe31_ctrl->outpath.output_mode &
-					VFE31_OUTPUT_MODE_S) {
-				msm_camera_io_w(0, vfe31_ctrl->vfebase +
-					vfe31_AXI_WM_CFG[vfe31_ctrl->
-						outpath.out1.ch0]);
-				msm_camera_io_w(0, vfe31_ctrl->vfebase +
-					vfe31_AXI_WM_CFG[vfe31_ctrl->
-						outpath.out1.ch1]);
-			}
-
-			/* Ensure the write order while writing
-			to the command register using the barrier */
-			msm_camera_io_w_mb(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
-				vfe31_ctrl->vfebase + VFE_CAMIF_COMMAND);
-
-			/* Ensure the read order while reading
-			to the command register using the barrier */
-			temp = msm_camera_io_r_mb(vfe31_ctrl->vfebase +
-				VFE_CAMIF_COMMAND);
-		}
-		/* then do reg_update. */
-		msm_camera_io_w_mb(1, vfe31_ctrl->vfebase +
-			VFE_REG_UPDATE_CMD);
-	} /* if snapshot mode. */
-}
-
-static void vfe31_set_default_reg_values(void)
-{
-	msm_camera_io_w(0x800080, vfe31_ctrl->vfebase + VFE_DEMUX_GAIN_0);
-	msm_camera_io_w(0x800080, vfe31_ctrl->vfebase + VFE_DEMUX_GAIN_1);
-	msm_camera_io_w(0xFFFFF, vfe31_ctrl->vfebase + VFE_CGC_OVERRIDE);
-
-	/* default frame drop period and pattern */
-	msm_camera_io_w(0x1f, vfe31_ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_CFG);
-	msm_camera_io_w(0x1f, vfe31_ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_CFG);
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe31_ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_PATTERN);
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe31_ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_PATTERN);
-	msm_camera_io_w(0x1f, vfe31_ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y);
-	msm_camera_io_w(0x1f, vfe31_ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR);
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe31_ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_PATTERN);
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe31_ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR_PATTERN);
-	msm_camera_io_w(0, vfe31_ctrl->vfebase + VFE_CLAMP_MIN);
-	msm_camera_io_w(0xFFFFFF, vfe31_ctrl->vfebase + VFE_CLAMP_MAX);
-
-	/* stats UB config */
-	msm_camera_io_w(0x3980007,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_AEC_UB_CFG);
-	msm_camera_io_w(0x3A00007,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_AF_UB_CFG);
-	msm_camera_io_w(0x3A8000F,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_AWB_UB_CFG);
-	msm_camera_io_w(0x3B80007,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_RS_UB_CFG);
-	msm_camera_io_w(0x3C0001F,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_CS_UB_CFG);
-	msm_camera_io_w(0x3E0001F,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_HIST_UB_CFG);
-}
-
-static void vfe31_process_reset_irq(void)
-{
-	atomic_set(&vfe31_ctrl->vstate, 0);
-	vfe31_ctrl->while_stopping_mask = VFE_IMASK_WHILE_STOPPING_1;
-	if (atomic_read(&vfe31_ctrl->stop_ack_pending)) {
-		/* this is from the stop command. */
-		atomic_set(&vfe31_ctrl->stop_ack_pending, 0);
-		vfe31_send_msg_no_payload(MSG_ID_STOP_ACK);
-	} else {
-		/* this is from reset command. */
-		vfe31_set_default_reg_values();
-
-		/* reload all write masters. (frame & line)*/
-		msm_camera_io_w_mb(0x7FFF, vfe31_ctrl->vfebase + VFE_BUS_CMD);
-		vfe31_send_msg_no_payload(MSG_ID_RESET_ACK);
-	}
-}
-
-
-static void vfe31_process_axi_halt_irq(void)
-{
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	msm_camera_io_w_mb(AXI_HALT_CLEAR,
-		vfe31_ctrl->vfebase + VFE_AXI_CMD);
-	vfe31_ctrl->while_stopping_mask = VFE_IMASK_RESET;
-
-	/* disable all interrupts.  */
-	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
-		vfe31_ctrl->vfebase + VFE_IRQ_MASK_0);
-	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
-		vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
-
-	/* clear all pending interrupts*/
-	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
-		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_0);
-	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
-		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_1);
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	msm_camera_io_w_mb(1,
-		vfe31_ctrl->vfebase + VFE_IRQ_CMD);
-
-	/* now enable only halt_irq & reset_irq */
-	msm_camera_io_w(0xf0000000,          /* this is for async timer. */
-		vfe31_ctrl->vfebase + VFE_IRQ_MASK_0);
-	msm_camera_io_w(VFE_IMASK_RESET,
-		vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
-
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	CDBG("%s: about to reset vfe...\n", __func__);
-	msm_camera_io_w_mb(VFE_RESET_UPON_STOP_CMD,
-		vfe31_ctrl->vfebase + VFE_GLOBAL_RESET);
-
-}
-
-static void vfe31_process_camif_sof_irq(void)
-{
-	uint32_t  temp;
-
-	/* in raw snapshot mode */
-	if (vfe31_ctrl->operation_mode ==
-		VFE_MODE_OF_OPERATION_RAW_SNAPSHOT) {
-		if (vfe31_ctrl->start_ack_pending) {
-			vfe31_send_msg_no_payload(MSG_ID_START_ACK);
-			vfe31_ctrl->start_ack_pending = FALSE;
-		}
-		if (vfe31_ctrl->vfe_capture_count)
-			vfe31_ctrl->vfe_capture_count--;
-		/* if last frame to be captured: */
-		if (vfe31_ctrl->vfe_capture_count == 0) {
-			/* Ensure the write order while writing
-			to the command register using the barrier */
-			msm_camera_io_w_mb(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
-				vfe31_ctrl->vfebase + VFE_CAMIF_COMMAND);
-			temp = msm_camera_io_r_mb(vfe31_ctrl->vfebase +
-				VFE_CAMIF_COMMAND);
-		}
-	} /* if raw snapshot mode. */
-
-	if ((vfe31_ctrl->hfr_mode != HFR_MODE_OFF) &&
-		(vfe31_ctrl->operation_mode == VFE_MODE_OF_OPERATION_VIDEO) &&
-		(vfe31_ctrl->vfeFrameId % vfe31_ctrl->hfr_mode != 0)) {
-		vfe31_ctrl->vfeFrameId++;
-		CDBG("Skip the SOF notification when HFR enabled\n");
-		return;
-	}
-	vfe31_send_msg_no_payload(MSG_ID_SOF_ACK);
-	vfe31_ctrl->vfeFrameId++;
-	CDBG("camif_sof_irq, frameId = %d\n", vfe31_ctrl->vfeFrameId);
-
-	if (vfe31_ctrl->sync_timer_state) {
-		if (vfe31_ctrl->sync_timer_repeat_count == 0)
-			vfe31_sync_timer_stop();
-		else
-		vfe31_ctrl->sync_timer_repeat_count--;
-	}
-}
-
-static void vfe31_process_error_irq(uint32_t errStatus)
-{
-	uint32_t camifStatus, read_val;
-	uint32_t *temp;
-
-	if (errStatus & VFE31_IMASK_CAMIF_ERROR) {
-		pr_err("vfe31_irq: camif errors\n");
-		temp = (uint32_t *)(vfe31_ctrl->vfebase + VFE_CAMIF_STATUS);
-		camifStatus = msm_camera_io_r(temp);
-		pr_err("camifStatus  = 0x%x\n", camifStatus);
-		vfe31_send_msg_no_payload(MSG_ID_CAMIF_ERROR);
-	}
-
-	if (errStatus & VFE31_IMASK_STATS_CS_OVWR)
-		pr_err("vfe31_irq: stats cs overwrite\n");
-
-	if (errStatus & VFE31_IMASK_STATS_IHIST_OVWR)
-		pr_err("vfe31_irq: stats ihist overwrite\n");
-
-	if (errStatus & VFE31_IMASK_REALIGN_BUF_Y_OVFL)
-		pr_err("vfe31_irq: realign bug Y overflow\n");
-
-	if (errStatus & VFE31_IMASK_REALIGN_BUF_CB_OVFL)
-		pr_err("vfe31_irq: realign bug CB overflow\n");
-
-	if (errStatus & VFE31_IMASK_REALIGN_BUF_CR_OVFL)
-		pr_err("vfe31_irq: realign bug CR overflow\n");
-
-	if (errStatus & VFE31_IMASK_VIOLATION)
-		pr_err("vfe31_irq: violation interrupt\n");
-
-	if (errStatus & VFE31_IMASK_IMG_MAST_0_BUS_OVFL)
-		pr_err("vfe31_irq: image master 0 bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_IMG_MAST_1_BUS_OVFL)
-		pr_err("vfe31_irq: image master 1 bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_IMG_MAST_2_BUS_OVFL)
-		pr_err("vfe31_irq: image master 2 bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_IMG_MAST_3_BUS_OVFL)
-		pr_err("vfe31_irq: image master 3 bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_IMG_MAST_4_BUS_OVFL)
-		pr_err("vfe31_irq: image master 4 bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_IMG_MAST_5_BUS_OVFL)
-		pr_err("vfe31_irq: image master 5 bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_IMG_MAST_6_BUS_OVFL)
-		pr_err("vfe31_irq: image master 6 bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_STATS_AE_BUS_OVFL)
-		pr_err("vfe31_irq: ae stats bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_STATS_AF_BUS_OVFL)
-		pr_err("vfe31_irq: af stats bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_STATS_AWB_BUS_OVFL)
-		pr_err("vfe31_irq: awb stats bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_STATS_RS_BUS_OVFL)
-		pr_err("vfe31_irq: rs stats bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_STATS_CS_BUS_OVFL)
-		pr_err("vfe31_irq: cs stats bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_STATS_IHIST_BUS_OVFL)
-		pr_err("vfe31_irq: ihist stats bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_STATS_SKIN_BUS_OVFL)
-		pr_err("vfe31_irq: skin stats bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_AXI_ERROR) {
-		pr_err("vfe31_irq: axi error\n");
-		/* read status too when overflow happens.*/
-		read_val = msm_camera_io_r(vfe31_ctrl->vfebase +
-			VFE_BUS_PING_PONG_STATUS);
-		pr_debug("VFE_BUS_PING_PONG_STATUS = 0x%x\n", read_val);
-		read_val = msm_camera_io_r(vfe31_ctrl->vfebase +
-			VFE_BUS_OPERATION_STATUS);
-		pr_debug("VFE_BUS_OPERATION_STATUS = 0x%x\n", read_val);
-		read_val = msm_camera_io_r(vfe31_ctrl->vfebase +
-			VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_0);
-		pr_debug("VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_0 = 0x%x\n",
-			read_val);
-		read_val = msm_camera_io_r(vfe31_ctrl->vfebase +
-			VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_1);
-		pr_debug("VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_1 = 0x%x\n",
-			read_val);
-		read_val = msm_camera_io_r(vfe31_ctrl->vfebase +
-			VFE_AXI_STATUS);
-		pr_debug("VFE_AXI_STATUS = 0x%x\n", read_val);
-	}
-}
-
-#define VFE31_AXI_OFFSET 0x0050
-#define vfe31_get_ch_ping_addr(chn) \
-	(msm_camera_io_r(vfe31_ctrl->vfebase + 0x0050 + 0x18 * (chn)))
-#define vfe31_get_ch_pong_addr(chn) \
-	(msm_camera_io_r(vfe31_ctrl->vfebase + 0x0050 + 0x18 * (chn) + 4))
-#define vfe31_get_ch_addr(ping_pong, chn) \
-	(((ping_pong) & (1 << (chn))) == 0 ? \
-	vfe31_get_ch_pong_addr(chn) : vfe31_get_ch_ping_addr(chn))
-
-#define vfe31_put_ch_ping_addr(chn, addr) \
-	(msm_camera_io_w((addr), vfe31_ctrl->vfebase + 0x0050 + 0x18 * (chn)))
-#define vfe31_put_ch_pong_addr(chn, addr) \
-	(msm_camera_io_w((addr), \
-	vfe31_ctrl->vfebase + 0x0050 + 0x18 * (chn) + 4))
-#define vfe31_put_ch_addr(ping_pong, chn, addr) \
-	(((ping_pong) & (1 << (chn))) == 0 ?   \
-	vfe31_put_ch_pong_addr((chn), (addr)) : \
-	vfe31_put_ch_ping_addr((chn), (addr)))
-
-static void vfe31_process_output_path_irq_0(uint32_t ping_pong)
-{
-	uint32_t p0_addr, p1_addr, p2_addr;
-#ifdef CONFIG_MSM_CAMERA_V4L2
-	uint32_t pyaddr_ping, pcbcraddr_ping, pyaddr_pong, pcbcraddr_pong;
-#endif
-	struct vfe31_free_buf *free_buf = NULL;
-	/* we render frames in the following conditions:
-	1. Continuous mode and the free buffer is avaialable.
-	*/
-	if (vfe31_ctrl->outpath.output_mode &
-		VFE31_OUTPUT_MODE_P_ALL_CHNLS) {
-		if (!(((ping_pong & PINGPONG_LOWER) == PINGPONG_LOWER) ||
-			((ping_pong & PINGPONG_LOWER) == 0x0))) {
-			pr_err(" Irq_2 - skip the frame pp_status is not proper"
-				"PP_status = 0x%x\n", ping_pong);
-			return;
-		}
-	}
-	free_buf = vfe31_get_free_buf(&vfe31_ctrl->outpath.out0);
-
-	if (free_buf) {
-		/* Y channel */
-		p0_addr = vfe31_get_ch_addr(ping_pong,
-			vfe31_ctrl->outpath.out0.ch0);
-		/* Chroma channel */
-		p1_addr = vfe31_get_ch_addr(ping_pong,
-			vfe31_ctrl->outpath.out0.ch1);
-		if (vfe31_ctrl->outpath.output_mode &
-			VFE31_OUTPUT_MODE_P_ALL_CHNLS) {
-			p2_addr = vfe31_get_ch_addr(ping_pong,
-				vfe31_ctrl->outpath.out0.ch2);
-		} else {
-			p2_addr = p0_addr;
-		}
-		CDBG("Output path 0, p0_addr = 0x%x, p1_addr = 0x%x,"
-			 "p2_addr = 0x%x\n", p0_addr, p1_addr, p2_addr);
-		/* Y channel */
-		vfe31_put_ch_addr(ping_pong,
-			vfe31_ctrl->outpath.out0.ch0,
-			free_buf->paddr + free_buf->planar0_off);
-		/* Chroma channel */
-		vfe31_put_ch_addr(ping_pong,
-			vfe31_ctrl->outpath.out0.ch1,
-			free_buf->paddr + free_buf->planar1_off);
-		if (vfe31_ctrl->outpath.output_mode &
-			VFE31_OUTPUT_MODE_P_ALL_CHNLS)
-			vfe31_put_ch_addr(ping_pong,
-				vfe31_ctrl->outpath.out0.ch2,
-			free_buf->paddr + free_buf->planar2_off);
-			kfree(free_buf);
-			/* if continuous mode, for display. (preview) */
-			vfe_send_outmsg(MSG_ID_OUTPUT_P,  p0_addr, p1_addr,
-				p2_addr);
-	} else {
-		vfe31_ctrl->outpath.out0.frame_drop_cnt++;
-		pr_warning("path_irq_0 - no free buffer!\n");
-#ifdef CONFIG_MSM_CAMERA_V4L2
-		pr_info("Swapping ping and pong\n");
-
-		/*get addresses*/
-		/* Y channel */
-		pyaddr_ping = vfe31_get_ch_ping_addr(
-			vfe31_ctrl->outpath.out0.ch0);
-		/* Chroma channel */
-		pcbcraddr_ping = vfe31_get_ch_ping_addr(
-			vfe31_ctrl->outpath.out0.ch1);
-		/* Y channel */
-		pyaddr_pong = vfe31_get_ch_pong_addr(
-			vfe31_ctrl->outpath.out0.ch0);
-		/* Chroma channel */
-		pcbcraddr_pong = vfe31_get_ch_pong_addr(
-			vfe31_ctrl->outpath.out0.ch1);
-
-		CDBG("ping = 0x%p, pong = 0x%p\n", (void *)pyaddr_ping,
-			(void *)pyaddr_pong);
-		CDBG("ping_cbcr = 0x%p, pong_cbcr = 0x%p\n",
-			(void *)pcbcraddr_ping, (void *)pcbcraddr_pong);
-
-		/*put addresses*/
-		/* SWAP y channel*/
-		vfe31_put_ch_ping_addr(vfe31_ctrl->outpath.out0.ch0,
-			pyaddr_pong);
-		vfe31_put_ch_pong_addr(vfe31_ctrl->outpath.out0.ch0,
-			pyaddr_ping);
-		/* SWAP chroma channel*/
-		vfe31_put_ch_ping_addr(vfe31_ctrl->outpath.out0.ch1,
-			pcbcraddr_pong);
-		vfe31_put_ch_pong_addr(vfe31_ctrl->outpath.out0.ch1,
-			pcbcraddr_ping);
-		CDBG("after swap: ping = 0x%p, pong = 0x%p\n",
-			(void *)pyaddr_pong, (void *)pyaddr_ping);
-#endif
-	}
-}
-
-static void vfe31_process_snapshot_frame(uint32_t ping_pong)
-{
-	uint32_t p0_addr, p1_addr;
-	struct vfe31_free_buf *free_buf = NULL;
-	/* Y channel- Main Image */
-	p0_addr = vfe31_get_ch_addr(ping_pong,
-		vfe31_ctrl->outpath.out1.ch0);
-	/* Chroma channel - TN Image */
-	p1_addr = vfe31_get_ch_addr(ping_pong,
-		vfe31_ctrl->outpath.out1.ch1);
-
-	free_buf = vfe31_get_free_buf(&vfe31_ctrl->outpath.out1);
-	CDBG("%s: snapshot main, p0_addr = 0x%x, p1_addr = 0x%x\n",
-		__func__, p0_addr, p1_addr);
-	if (free_buf) {
-		/* Y channel */
-		vfe31_put_ch_addr(ping_pong,
-			vfe31_ctrl->outpath.out1.ch0,
-			free_buf->paddr + free_buf->planar0_off);
-		/* Chroma channel */
-		vfe31_put_ch_addr(ping_pong,
-			vfe31_ctrl->outpath.out1.ch1,
-			free_buf->paddr + free_buf->planar1_off);
-		kfree(free_buf);
-	}
-	vfe_send_outmsg(MSG_ID_OUTPUT_S, p0_addr, p1_addr, p0_addr);
-
-	/* Y channel- TN Image */
-	p0_addr = vfe31_get_ch_addr(ping_pong,
-		vfe31_ctrl->outpath.out0.ch0);
-	/* Chroma channel - TN Image */
-	p1_addr = vfe31_get_ch_addr(ping_pong,
-		vfe31_ctrl->outpath.out0.ch1);
-
-	free_buf = vfe31_get_free_buf(&vfe31_ctrl->outpath.out0);
-	CDBG("%s: snapshot TN, p0_addr = 0x%x, p1_addr = 0x%x\n",
-		__func__, p0_addr, p1_addr);
-	if (free_buf) {
-		/* Y channel */
-		vfe31_put_ch_addr(ping_pong,
-			vfe31_ctrl->outpath.out0.ch0,
-			free_buf->paddr + free_buf->planar0_off);
-		/* Chroma channel */
-		vfe31_put_ch_addr(ping_pong,
-			vfe31_ctrl->outpath.out0.ch1,
-			free_buf->paddr + free_buf->planar1_off);
-		kfree(free_buf);
-	}
-
-	vfe_send_outmsg(MSG_ID_OUTPUT_T, p0_addr, p1_addr, p0_addr);
-
-	/* in snapshot mode if done then send
-		snapshot done message */
-	if (vfe31_ctrl->vfe_capture_count == 0) {
-		vfe31_send_msg_no_payload(MSG_ID_SNAPSHOT_DONE);
-		/* Ensure the write order while writing
-			to the cmd register using barrier */
-		msm_camera_io_w_mb(CAMIF_COMMAND_STOP_IMMEDIATELY,
-			vfe31_ctrl->vfebase +
-			VFE_CAMIF_COMMAND);
-	}
-}
-
-static void vfe31_process_raw_snapshot_frame(uint32_t ping_pong)
-{
-	uint32_t pyaddr, pcbcraddr;
-	struct vfe31_free_buf *free_buf = NULL;
-	struct msm_sync* p_sync = (struct msm_sync *)vfe_syncdata;
-
-	if (p_sync->stereocam_enabled)
-		p_sync->stereo_state = STEREO_RAW_SNAP_STARTED;
-
-	/* Y channel- Main Image */
-	pyaddr = vfe31_get_ch_addr(ping_pong,
-		vfe31_ctrl->outpath.out1.ch0);
-	/* Chroma channel - Main Image */
-	pcbcraddr = vfe31_get_ch_addr(ping_pong,
-		vfe31_ctrl->outpath.out1.ch1);
-
-	free_buf = vfe31_get_free_buf(&vfe31_ctrl->outpath.out1);
-	CDBG("%s: snapshot raw, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
-		__func__, pyaddr, pcbcraddr);
-	if (free_buf) {
-		/* Y channel */
-		vfe31_put_ch_addr(ping_pong,
-			vfe31_ctrl->outpath.out1.ch0,
-			free_buf->paddr + free_buf->planar0_off);
-		/* Chroma channel */
-		vfe31_put_ch_addr(ping_pong,
-			vfe31_ctrl->outpath.out1.ch1,
-			free_buf->paddr + free_buf->planar1_off);
-		kfree(free_buf);
-	}
-	 vfe_send_outmsg(MSG_ID_OUTPUT_S, pyaddr, pcbcraddr, 0);
-
-	/* in snapshot mode if done then send
-		snapshot done message */
-	if (vfe31_ctrl->vfe_capture_count == 0) {
-		vfe31_send_msg_no_payload(MSG_ID_SNAPSHOT_DONE);
-		/* Ensure the write order while writing
-		to the cmd register using barrier */
-		msm_camera_io_w_mb(CAMIF_COMMAND_STOP_IMMEDIATELY,
-			vfe31_ctrl->vfebase +
-			VFE_CAMIF_COMMAND);
-	}
-}
-static void vfe31_process_zsl_frame(uint32_t ping_pong)
-{
-	uint32_t p0_addr, p1_addr;
-	struct vfe31_free_buf *free_buf = NULL;
-	/* Y channel- Main Image */
-	p0_addr = vfe31_get_ch_addr(ping_pong,
-		vfe31_ctrl->outpath.out2.ch0);
-	/* Chroma channel - Main Image */
-	p1_addr = vfe31_get_ch_addr(ping_pong,
-		vfe31_ctrl->outpath.out2.ch1);
-
-	free_buf = vfe31_get_free_buf(&vfe31_ctrl->outpath.out2);
-	CDBG("%s: snapshot main, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
-		__func__, p0_addr, p1_addr);
-	if (free_buf) {
-		/* Y channel */
-		vfe31_put_ch_addr(ping_pong,
-			vfe31_ctrl->outpath.out2.ch0,
-			free_buf->paddr + free_buf->planar0_off);
-		/* Chroma channel */
-		vfe31_put_ch_addr(ping_pong,
-			vfe31_ctrl->outpath.out2.ch1,
-			free_buf->paddr + free_buf->planar1_off);
-		kfree(free_buf);
-	}
-	 vfe_send_outmsg(MSG_ID_OUTPUT_S, p0_addr, p1_addr, p0_addr);
-
-	/* Y channel- TN Image */
-	p0_addr = vfe31_get_ch_addr(ping_pong,
-		vfe31_ctrl->outpath.out1.ch0);
-	/* Chroma channel - TN Image */
-	p1_addr = vfe31_get_ch_addr(ping_pong,
-		vfe31_ctrl->outpath.out1.ch1);
-
-	free_buf = vfe31_get_free_buf(&vfe31_ctrl->outpath.out1);
-	CDBG("%s: snapshot TN, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
-		__func__, p0_addr, p1_addr);
-	if (free_buf) {
-		/* Y channel */
-		vfe31_put_ch_addr(ping_pong,
-			vfe31_ctrl->outpath.out1.ch0,
-			free_buf->paddr + free_buf->planar0_off);
-		/* Chroma channel */
-		vfe31_put_ch_addr(ping_pong,
-			vfe31_ctrl->outpath.out1.ch1,
-			free_buf->paddr + free_buf->planar1_off);
-		kfree(free_buf);
-	}
-
-	vfe_send_outmsg(MSG_ID_OUTPUT_T, p0_addr, p1_addr, p0_addr);
-}
-
-static void vfe31_process_output_path_irq_1(uint32_t ping_pong)
-{
-
-#ifdef CONFIG_MSM_CAMERA_V4L2
-	uint32_t pyaddr_ping, pcbcraddr_ping, pyaddr_pong, pcbcraddr_pong;
-#endif
-	CDBG("%s, operation_mode = %d, cap_cnt = %d\n", __func__,
-		vfe31_ctrl->operation_mode, vfe31_ctrl->vfe_capture_count);
-
-	/* In Snapshot mode */
-	if ((VFE_MODE_OF_OPERATION_SNAPSHOT == vfe31_ctrl->operation_mode)
-		&& ((vfe31_ctrl->vfe_capture_count <= 1)
-		|| (vfe31_free_buf_available(vfe31_ctrl->outpath.out0) &&
-		vfe31_free_buf_available(vfe31_ctrl->outpath.out1)))) {
-		vfe31_process_snapshot_frame(ping_pong);
-	} else if ((VFE_MODE_OF_OPERATION_RAW_SNAPSHOT ==
-		vfe31_ctrl->operation_mode) &&
-		((vfe31_ctrl->vfe_capture_count <= 1) ||
-		vfe31_free_buf_available(vfe31_ctrl->outpath.out1))) {
-		vfe31_process_raw_snapshot_frame(ping_pong);
-	} else if ((VFE_MODE_OF_OPERATION_ZSL == vfe31_ctrl->operation_mode)
-		&& (vfe31_free_buf_available(vfe31_ctrl->outpath.out1)
-		&& vfe31_free_buf_available(vfe31_ctrl->outpath.out2))) {
-		vfe31_process_zsl_frame(ping_pong);
-	} else {
-		vfe31_ctrl->outpath.out1.frame_drop_cnt++;
-		pr_info("path_irq_1 - no free buffer!\n");
-#ifdef CONFIG_MSM_CAMERA_V4L2
-		pr_info("Swapping ping and pong\n");
-
-		/*get addresses*/
-		/* Y channel */
-		pyaddr_ping = vfe31_get_ch_ping_addr(
-			vfe31_ctrl->outpath.out1.ch0);
-		/* Chroma channel */
-		pcbcraddr_ping = vfe31_get_ch_ping_addr(
-			vfe31_ctrl->outpath.out1.ch1);
-		/* Y channel */
-		pyaddr_pong = vfe31_get_ch_pong_addr(
-			vfe31_ctrl->outpath.out1.ch0);
-		/* Chroma channel */
-		pcbcraddr_pong = vfe31_get_ch_pong_addr(
-			vfe31_ctrl->outpath.out1.ch1);
-
-		CDBG("ping = 0x%p, pong = 0x%p\n", (void *)pyaddr_ping,
-			(void *)pyaddr_pong);
-		CDBG("ping_cbcr = 0x%p, pong_cbcr = 0x%p\n",
-			(void *)pcbcraddr_ping, (void *)pcbcraddr_pong);
-
-		/*put addresses*/
-		/* SWAP y channel*/
-		vfe31_put_ch_ping_addr(vfe31_ctrl->outpath.out1.ch0,
-			pyaddr_pong);
-		vfe31_put_ch_pong_addr(vfe31_ctrl->outpath.out1.ch0,
-			pyaddr_ping);
-		/* SWAP chroma channel*/
-		vfe31_put_ch_ping_addr(vfe31_ctrl->outpath.out1.ch1,
-			pcbcraddr_pong);
-		vfe31_put_ch_pong_addr(vfe31_ctrl->outpath.out1.ch1,
-			pcbcraddr_ping);
-		CDBG("after swap: ping = 0x%p, pong = 0x%p\n",
-			(void *)pyaddr_pong, (void *)pyaddr_ping);
-#endif
-	}
-
-}
-
-static void vfe31_process_output_path_irq_2(uint32_t ping_pong)
-{
-	uint32_t p0_addr, p1_addr, p2_addr;
-	struct vfe31_free_buf *free_buf = NULL;
-
-#ifdef CONFIG_MSM_CAMERA_V4L2
-	uint32_t pyaddr_ping, pcbcraddr_ping, pyaddr_pong, pcbcraddr_pong;
-#endif
-	/* we render frames in the following conditions:
-	1. Continuous mode and the free buffer is avaialable.
-	*/
-	CDBG("%s, operation_mode = %d, state %d\n", __func__,
-		vfe31_ctrl->operation_mode,
-		vfe31_ctrl->recording_state);
-	/* Ensure that both wm1 and wm5 ping and pong buffers are active*/
-	if (!(((ping_pong & 0x22) == 0x22) ||
-		((ping_pong & 0x22) == 0x0))) {
-		pr_err(" Irq_2 - skip the frame pp_status is not proper"
-			"PP_status = 0x%x\n", ping_pong);
-		return;
-	}
-	if ((vfe31_ctrl->recording_state == VFE_REC_STATE_STOP_REQUESTED)
-		|| (vfe31_ctrl->recording_state == VFE_REC_STATE_STOPPED)) {
-		vfe31_ctrl->outpath.out2.frame_drop_cnt++;
-		pr_warning("path_irq_2 - recording stopped\n");
-		return;
-	}
-
-	free_buf = vfe31_get_free_buf(&vfe31_ctrl->outpath.out2);
-
-	if (free_buf) {
-		/* Y channel */
-		p0_addr = vfe31_get_ch_addr(ping_pong,
-			vfe31_ctrl->outpath.out2.ch0);
-		/* Chroma channel */
-		p1_addr = vfe31_get_ch_addr(ping_pong,
-			vfe31_ctrl->outpath.out2.ch1);
-		p2_addr = p0_addr;
-		CDBG("video output, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
-			p0_addr, p1_addr);
-
-		/* Y channel */
-		vfe31_put_ch_addr(ping_pong,
-		vfe31_ctrl->outpath.out2.ch0,
-		free_buf->paddr + free_buf->planar0_off);
-		/* Chroma channel */
-		vfe31_put_ch_addr(ping_pong,
-		vfe31_ctrl->outpath.out2.ch1,
-		free_buf->paddr + free_buf->planar1_off);
-		kfree(free_buf);
-		vfe_send_outmsg(MSG_ID_OUTPUT_V, p0_addr, p1_addr, p2_addr);
-	} else {
-		vfe31_ctrl->outpath.out2.frame_drop_cnt++;
-		pr_warning("path_irq_2 - no free buffer!\n");
-
-#ifdef CONFIG_MSM_CAMERA_V4L2
-		pr_info("Swapping ping and pong\n");
-
-		/*get addresses*/
-		/* Y channel */
-		pyaddr_ping = vfe31_get_ch_ping_addr(
-			vfe31_ctrl->outpath.out2.ch0);
-		/* Chroma channel */
-		pcbcraddr_ping = vfe31_get_ch_ping_addr(
-			vfe31_ctrl->outpath.out2.ch1);
-		/* Y channel */
-		pyaddr_pong = vfe31_get_ch_pong_addr(
-			vfe31_ctrl->outpath.out2.ch0);
-		/* Chroma channel */
-		pcbcraddr_pong = vfe31_get_ch_pong_addr(
-			vfe31_ctrl->outpath.out2.ch1);
-
-		CDBG("ping = 0x%p, pong = 0x%p\n", (void *)pyaddr_ping,
-			(void *)pyaddr_pong);
-		CDBG("ping_cbcr = 0x%p, pong_cbcr = 0x%p\n",
-			(void *)pcbcraddr_ping, (void *)pcbcraddr_pong);
-
-		/*put addresses*/
-		/* SWAP y channel*/
-		vfe31_put_ch_ping_addr(vfe31_ctrl->outpath.out2.ch0,
-			pyaddr_pong);
-		vfe31_put_ch_pong_addr(vfe31_ctrl->outpath.out2.ch0,
-			pyaddr_ping);
-		/* SWAP chroma channel*/
-		vfe31_put_ch_ping_addr(vfe31_ctrl->outpath.out2.ch1,
-			pcbcraddr_pong);
-		vfe31_put_ch_pong_addr(vfe31_ctrl->outpath.out2.ch1,
-			pcbcraddr_ping);
-		CDBG("after swap: ping = 0x%p, pong = 0x%p\n",
-			(void *)pyaddr_pong, (void *)pyaddr_ping);
-#endif
-	}
-}
-
-
-static uint32_t  vfe31_process_stats_irq_common(uint32_t statsNum,
-						uint32_t newAddr) {
-
-	uint32_t pingpongStatus;
-	uint32_t returnAddr;
-	uint32_t pingpongAddr;
-
-	/* must be 0=ping, 1=pong */
-	pingpongStatus =
-		((msm_camera_io_r(vfe31_ctrl->vfebase +
-		VFE_BUS_PING_PONG_STATUS))
-	& ((uint32_t)(1<<(statsNum + 7)))) >> (statsNum + 7);
-	/* stats bits starts at 7 */
-	CDBG("statsNum %d, pingpongStatus %d\n", statsNum, pingpongStatus);
-	pingpongAddr =
-		((uint32_t)(vfe31_ctrl->vfebase +
-				VFE_BUS_STATS_PING_PONG_BASE)) +
-				(3*statsNum)*4 + (1-pingpongStatus)*4;
-	returnAddr = msm_camera_io_r((uint32_t *)pingpongAddr);
-	msm_camera_io_w(newAddr, (uint32_t *)pingpongAddr);
-	return returnAddr;
-}
-
-static void vfe_send_stats_msg(void)
-{
-	struct  vfe_message msg;
-	uint32_t temp;
-
-	/* fill message with right content. */
-	msg._u.msgStats.frameCounter = vfe31_ctrl->vfeFrameId;
-	msg._u.msgStats.status_bits = vfe31_ctrl->status_bits;
-	msg._d = MSG_ID_COMMON;
-
-	msg._u.msgStats.buff.aec = vfe31_ctrl->aecStatsControl.bufToRender;
-	msg._u.msgStats.buff.awb = vfe31_ctrl->awbStatsControl.bufToRender;
-	msg._u.msgStats.buff.af = vfe31_ctrl->afStatsControl.bufToRender;
-
-	msg._u.msgStats.buff.ihist = vfe31_ctrl->ihistStatsControl.bufToRender;
-	msg._u.msgStats.buff.rs = vfe31_ctrl->rsStatsControl.bufToRender;
-	msg._u.msgStats.buff.cs = vfe31_ctrl->csStatsControl.bufToRender;
-
-	temp = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_STATS_AWB_SGW_CFG);
-	msg._u.msgStats.buff.awb_ymin = (0xFF00 & temp) >> 8;
-
-	vfe31_proc_ops(msg._d,
-		&msg, sizeof(struct vfe_message));
-	return;
-}
-
-static void vfe31_process_stats(void)
-{
-	int32_t process_stats = false;
-
-	CDBG("%s, stats = 0x%x\n", __func__, vfe31_ctrl->status_bits);
-
-	if (vfe31_ctrl->status_bits & VFE_IRQ_STATUS0_STATS_AEC) {
-		if (!vfe31_ctrl->aec_ack_pending) {
-			vfe31_ctrl->aec_ack_pending = TRUE;
-			vfe31_ctrl->aecStatsControl.bufToRender =
-				vfe31_process_stats_irq_common(statsAeNum,
-				vfe31_ctrl->aecStatsControl.nextFrameAddrBuf);
-			process_stats = true;
-		} else{
-			vfe31_ctrl->aecStatsControl.bufToRender = 0;
-			vfe31_ctrl->aecStatsControl.droppedStatsFrameCount++;
-		}
-	} else {
-		vfe31_ctrl->aecStatsControl.bufToRender = 0;
-	}
-
-	if (vfe31_ctrl->status_bits & VFE_IRQ_STATUS0_STATS_AWB) {
-		if (!vfe31_ctrl->awb_ack_pending) {
-			vfe31_ctrl->awb_ack_pending = TRUE;
-			vfe31_ctrl->awbStatsControl.bufToRender =
-				vfe31_process_stats_irq_common(statsAwbNum,
-				vfe31_ctrl->awbStatsControl.nextFrameAddrBuf);
-			process_stats = true;
-		} else{
-			vfe31_ctrl->awbStatsControl.droppedStatsFrameCount++;
-			vfe31_ctrl->awbStatsControl.bufToRender = 0;
-		}
-	} else {
-		vfe31_ctrl->awbStatsControl.bufToRender = 0;
-	}
-
-
-	if (vfe31_ctrl->status_bits & VFE_IRQ_STATUS0_STATS_AF) {
-		if (!vfe31_ctrl->af_ack_pending) {
-			vfe31_ctrl->af_ack_pending = TRUE;
-			vfe31_ctrl->afStatsControl.bufToRender =
-				vfe31_process_stats_irq_common(statsAfNum,
-				vfe31_ctrl->afStatsControl.nextFrameAddrBuf);
-			process_stats = true;
-		} else {
-			vfe31_ctrl->afStatsControl.bufToRender = 0;
-			vfe31_ctrl->afStatsControl.droppedStatsFrameCount++;
-		}
-	} else {
-		vfe31_ctrl->afStatsControl.bufToRender = 0;
-	}
-
-	if (vfe31_ctrl->status_bits & VFE_IRQ_STATUS0_STATS_IHIST) {
-		if (!vfe31_ctrl->ihist_ack_pending) {
-			vfe31_ctrl->ihist_ack_pending = TRUE;
-			vfe31_ctrl->ihistStatsControl.bufToRender =
-				vfe31_process_stats_irq_common(statsIhistNum,
-				vfe31_ctrl->ihistStatsControl.nextFrameAddrBuf);
-			process_stats = true;
-		} else {
-			vfe31_ctrl->ihistStatsControl.droppedStatsFrameCount++;
-			vfe31_ctrl->ihistStatsControl.bufToRender = 0;
-		}
-	} else {
-		vfe31_ctrl->ihistStatsControl.bufToRender = 0;
-	}
-
-	if (vfe31_ctrl->status_bits & VFE_IRQ_STATUS0_STATS_RS) {
-		if (!vfe31_ctrl->rs_ack_pending) {
-			vfe31_ctrl->rs_ack_pending = TRUE;
-			vfe31_ctrl->rsStatsControl.bufToRender =
-				vfe31_process_stats_irq_common(statsRsNum,
-				vfe31_ctrl->rsStatsControl.nextFrameAddrBuf);
-			process_stats = true;
-		} else {
-			vfe31_ctrl->rsStatsControl.droppedStatsFrameCount++;
-			vfe31_ctrl->rsStatsControl.bufToRender = 0;
-		}
-	} else {
-		vfe31_ctrl->rsStatsControl.bufToRender = 0;
-	}
-
-
-	if (vfe31_ctrl->status_bits & VFE_IRQ_STATUS0_STATS_CS) {
-		if (!vfe31_ctrl->cs_ack_pending) {
-			vfe31_ctrl->cs_ack_pending = TRUE;
-			vfe31_ctrl->csStatsControl.bufToRender =
-				vfe31_process_stats_irq_common(statsCsNum,
-				vfe31_ctrl->csStatsControl.nextFrameAddrBuf);
-			process_stats = true;
-		} else {
-			vfe31_ctrl->csStatsControl.droppedStatsFrameCount++;
-			vfe31_ctrl->csStatsControl.bufToRender = 0;
-		}
-	} else {
-		vfe31_ctrl->csStatsControl.bufToRender = 0;
-	}
-
-	if (process_stats)
-		vfe_send_stats_msg();
-
-	return;
-}
-
-static void vfe31_process_stats_irq(uint32_t *irqstatus)
-{
-	/* Subsample the stats according to the hfr speed*/
-	if ((vfe31_ctrl->hfr_mode != HFR_MODE_OFF) &&
-		(vfe31_ctrl->vfeFrameId % vfe31_ctrl->hfr_mode != 0)) {
-		CDBG("Skip the stats when HFR enabled\n");
-		return;
-	}
-
-	vfe31_ctrl->status_bits = VFE_COM_STATUS & *irqstatus;
-	vfe31_process_stats();
-	return;
-}
-
-static void vfe31_do_tasklet(unsigned long data)
-{
-	unsigned long flags;
-
-	struct vfe31_isr_queue_cmd *qcmd = NULL;
-
-	CDBG("=== vfe31_do_tasklet start === \n");
-
-	while (atomic_read(&irq_cnt)) {
-		spin_lock_irqsave(&vfe31_ctrl->tasklet_lock, flags);
-		qcmd = list_first_entry(&vfe31_ctrl->tasklet_q,
-			struct vfe31_isr_queue_cmd, list);
-		atomic_sub(1, &irq_cnt);
-
-		if (!qcmd) {
-			spin_unlock_irqrestore(&vfe31_ctrl->tasklet_lock,
-				flags);
-			return;
-		}
-
-		list_del(&qcmd->list);
-		spin_unlock_irqrestore(&vfe31_ctrl->tasklet_lock,
-			flags);
-
-		/* interrupt to be processed,  *qcmd has the payload.  */
-		if (qcmd->vfeInterruptStatus0 &
-			VFE_IRQ_STATUS0_REG_UPDATE_MASK) {
-			CDBG("irq regUpdateIrq\n");
-			vfe31_process_reg_update_irq();
-		}
-
-		if (qcmd->vfeInterruptStatus1 &
-			VFE_IMASK_RESET) {
-			CDBG("irq resetAckIrq\n");
-			vfe31_process_reset_irq();
-		}
-
-
-		if (qcmd->vfeInterruptStatus1 &
-			VFE_IMASK_AXI_HALT) {
-			CDBG("irq axi halt irq\n");
-			vfe31_process_axi_halt_irq();
-		}
-
-		if (atomic_read(&vfe31_ctrl->vstate)) {
-			if (qcmd->vfeInterruptStatus1 &
-					VFE31_IMASK_ERROR_ONLY_1) {
-				pr_err("irq	errorIrq\n");
-				vfe31_process_error_irq(
-					qcmd->vfeInterruptStatus1 &
-					VFE31_IMASK_ERROR_ONLY_1);
-			}
-
-			/* irqs below are only valid when in active state. */
-			/* next, check output path related interrupts. */
-			if (qcmd->vfeInterruptStatus0 &
-				VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK) {
-				CDBG("Image composite done 0 irq occured.\n");
-				vfe31_process_output_path_irq_0(
-					qcmd->vfePingPongStatus);
-			}
-
-			if (qcmd->vfeInterruptStatus0 &
-				VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK) {
-				CDBG("Image composite done 1 irq occured.\n");
-				vfe31_process_output_path_irq_1(
-					qcmd->vfePingPongStatus);
-			}
-
-			if (qcmd->vfeInterruptStatus0 &
-				VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE2_MASK) {
-				CDBG("Image composite done 2 irq occured.\n");
-				vfe31_process_output_path_irq_2(
-					qcmd->vfePingPongStatus);
-			}
-
-			/* then process stats irq. */
-			if (vfe31_ctrl->stats_comp) {
-				/* process stats comb interrupt. */
-				if (qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK) {
-					CDBG("Stats composite irq occured.\n");
-					vfe31_process_stats_irq(
-						&qcmd->vfeInterruptStatus0);
-				}
-			} else {
-				/* process individual stats interrupt. */
-				if (qcmd->vfeInterruptStatus0 &
-						VFE_COM_STATUS) {
-					CDBG("VFE stats occured.\n");
-					vfe31_process_stats_irq(
-						&qcmd->vfeInterruptStatus0);
-				}
-				if (qcmd->vfeInterruptStatus0 &
-						VFE_IRQ_STATUS0_SYNC_TIMER0) {
-					CDBG("SYNC_TIMER 0 irq occured.\n");
-					vfe31_send_msg_no_payload(
-						MSG_ID_SYNC_TIMER0_DONE);
-				}
-				if (qcmd->vfeInterruptStatus0 &
-						VFE_IRQ_STATUS0_SYNC_TIMER1) {
-					CDBG("SYNC_TIMER 1 irq occured.\n");
-					vfe31_send_msg_no_payload(
-						MSG_ID_SYNC_TIMER1_DONE);
-				}
-				if (qcmd->vfeInterruptStatus0 &
-						VFE_IRQ_STATUS0_SYNC_TIMER2) {
-					CDBG("SYNC_TIMER 2 irq occured.\n");
-					vfe31_send_msg_no_payload(
-						MSG_ID_SYNC_TIMER2_DONE);
-				}
-			}
-		}
-		if (qcmd->vfeInterruptStatus0 &
-				VFE_IRQ_STATUS0_CAMIF_SOF_MASK) {
-			CDBG("irq	camifSofIrq\n");
-			vfe31_process_camif_sof_irq();
-		}
-		kfree(qcmd);
-	}
-	CDBG("=== vfe31_do_tasklet end === \n");
-}
-
-DECLARE_TASKLET(vfe31_tasklet, vfe31_do_tasklet, 0);
-
-static irqreturn_t vfe31_parse_irq(int irq_num, void *data)
-{
-	unsigned long flags;
-	struct vfe31_irq_status irq;
-	struct vfe31_isr_queue_cmd *qcmd;
-	uint32_t *val;
-	CDBG("vfe_parse_irq\n");
-	memset(&irq, 0, sizeof(struct vfe31_irq_status));
-
-	val = (uint32_t *)(vfe31_ctrl->vfebase + VFE_IRQ_STATUS_0);
-	irq.vfeIrqStatus0 = msm_camera_io_r(val);
-
-	val = (uint32_t *)(vfe31_ctrl->vfebase + VFE_IRQ_STATUS_1);
-	irq.vfeIrqStatus1 = msm_camera_io_r(val);
-
-	if (irq.vfeIrqStatus1 & VFE_IMASK_AXI_HALT) {
-		msm_camera_io_w(VFE_IMASK_RESET,
-			vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
-		msm_camera_io_w_mb(AXI_HALT_CLEAR,
-			vfe31_ctrl->vfebase + VFE_AXI_CMD);
-	}
-
-	val = (uint32_t *)(vfe31_ctrl->vfebase + VFE_CAMIF_STATUS);
-	irq.camifStatus = msm_camera_io_r(val);
-	CDBG("camifStatus  = 0x%x\n", irq.camifStatus);
-
-	val = (uint32_t *)(vfe31_ctrl->vfebase + VFE_BUS_PING_PONG_STATUS);
-	irq.vfePingPongStatus = msm_camera_io_r(val);
-
-	/* clear the pending interrupt of the same kind.*/
-	msm_camera_io_w(irq.vfeIrqStatus0,
-		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_0);
-	msm_camera_io_w(irq.vfeIrqStatus1,
-		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_1);
-
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_IRQ_CMD);
-
-	if ((irq.vfeIrqStatus0 == 0) && (irq.vfeIrqStatus1 == 0)) {
-		CDBG("vfe_parse_irq: vfeIrqStatus0 & 1 are both 0!\n");
-		return IRQ_HANDLED;
-	}
-
-	qcmd = kzalloc(sizeof(struct vfe31_isr_queue_cmd),
-		GFP_ATOMIC);
-	if (!qcmd) {
-		pr_err("vfe_parse_irq: qcmd malloc failed!\n");
-		return IRQ_HANDLED;
-	}
-
-	if (atomic_read(&vfe31_ctrl->stop_ack_pending)) {
-		irq.vfeIrqStatus0 &= VFE_IMASK_WHILE_STOPPING_0;
-		irq.vfeIrqStatus1 &= vfe31_ctrl->while_stopping_mask;
-	}
-
-	spin_lock_irqsave(&vfe31_ctrl->xbar_lock, flags);
-	if ((irq.vfeIrqStatus0 &
-		VFE_IRQ_STATUS0_CAMIF_EOF_MASK) &&
-		vfe31_ctrl->xbar_update_pending) {
-		CDBG("irq camifEofIrq\n");
-		msm_camera_io_memcpy(vfe31_ctrl->vfebase + V31_XBAR_CFG_OFF,
-			(void *)vfe31_ctrl->xbar_cfg, V31_XBAR_CFG_LEN);
-		vfe31_ctrl->xbar_update_pending = 0;
-	}
-	spin_unlock_irqrestore(&vfe31_ctrl->xbar_lock, flags);
-	CDBG("vfe_parse_irq: Irq_status0 = 0x%x, Irq_status1 = 0x%x.\n",
-		irq.vfeIrqStatus0, irq.vfeIrqStatus1);
-
-	qcmd->vfeInterruptStatus0 = irq.vfeIrqStatus0;
-	qcmd->vfeInterruptStatus1 = irq.vfeIrqStatus1;
-	qcmd->vfePingPongStatus = irq.vfePingPongStatus;
-
-	spin_lock_irqsave(&vfe31_ctrl->tasklet_lock, flags);
-	list_add_tail(&qcmd->list, &vfe31_ctrl->tasklet_q);
-
-	atomic_add(1, &irq_cnt);
-	spin_unlock_irqrestore(&vfe31_ctrl->tasklet_lock, flags);
-	tasklet_schedule(&vfe31_tasklet);
-	return IRQ_HANDLED;
-}
-
-static void vfe31_release(struct platform_device *pdev)
-{
-	struct resource	*vfemem, *vfeio;
-
-	vfe31_reset_free_buf_queue_all();
-	CDBG("%s, free_irq\n", __func__);
-	free_irq(vfe31_ctrl->vfeirq, 0);
-	tasklet_kill(&vfe31_tasklet);
-
-	if (atomic_read(&irq_cnt))
-		pr_warning("%s, Warning IRQ Count not ZERO\n", __func__);
-
-	vfemem = vfe31_ctrl->vfemem;
-	vfeio  = vfe31_ctrl->vfeio;
-
-	msm_vpe_release();
-
-	kfree(vfe31_ctrl->extdata);
-	iounmap(vfe31_ctrl->vfebase);
-	kfree(vfe31_ctrl);
-	vfe31_ctrl = NULL;
-	release_mem_region(vfemem->start, (vfemem->end - vfemem->start) + 1);
-	CDBG("%s, msm_camio_disable\n", __func__);
-	msm_camio_disable(pdev);
-	msm_camio_set_perf_lvl(S_EXIT);
-
-	vfe_syncdata = NULL;
-}
-
-static int vfe31_resource_init(struct msm_vfe_callback *presp,
-	struct platform_device *pdev, void *sdata)
-{
-	struct resource	*vfemem, *vfeirq, *vfeio;
-	int rc;
-	struct msm_camera_sensor_info *s_info;
-	s_info = pdev->dev.platform_data;
-
-	pdev->resource = s_info->resource;
-	pdev->num_resources = s_info->num_resources;
-
-	vfemem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!vfemem) {
-		pr_err("%s: no mem resource?\n", __func__);
-		return -ENODEV;
-	}
-
-	vfeirq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!vfeirq) {
-		pr_err("%s: no irq resource?\n", __func__);
-		return -ENODEV;
-	}
-
-	vfeio = request_mem_region(vfemem->start,
-		resource_size(vfemem), pdev->name);
-	if (!vfeio) {
-		pr_err("%s: VFE region already claimed\n", __func__);
-		return -EBUSY;
-	}
-
-	vfe31_ctrl = kzalloc(sizeof(struct vfe31_ctrl_type), GFP_KERNEL);
-	if (!vfe31_ctrl) {
-		rc = -ENOMEM;
-		goto cmd_init_failed1;
-	}
-
-	vfe31_ctrl->vfeirq = vfeirq->start;
-
-	vfe31_ctrl->vfebase =
-		ioremap(vfemem->start, (vfemem->end - vfemem->start) + 1);
-	if (!vfe31_ctrl->vfebase) {
-		rc = -ENOMEM;
-		pr_err("%s: vfe ioremap failed\n", __func__);
-		goto cmd_init_failed2;
-	}
-
-	if (presp && presp->vfe_resp)
-		vfe31_ctrl->resp = presp;
-	else {
-		rc = -EINVAL;
-		goto cmd_init_failed3;
-	}
-
-	vfe31_ctrl->extdata =
-		kmalloc(sizeof(struct vfe31_frame_extra), GFP_KERNEL);
-	if (!vfe31_ctrl->extdata) {
-		rc = -ENOMEM;
-		goto cmd_init_failed3;
-	}
-
-	vfe31_ctrl->extlen = sizeof(struct vfe31_frame_extra);
-
-	spin_lock_init(&vfe31_ctrl->io_lock);
-	spin_lock_init(&vfe31_ctrl->update_ack_lock);
-	spin_lock_init(&vfe31_ctrl->tasklet_lock);
-	spin_lock_init(&vfe31_ctrl->xbar_lock);
-
-	INIT_LIST_HEAD(&vfe31_ctrl->tasklet_q);
-	vfe31_init_free_buf_queue();
-
-	vfe31_ctrl->syncdata = sdata;
-	vfe31_ctrl->vfemem = vfemem;
-	vfe31_ctrl->vfeio  = vfeio;
-	vfe31_ctrl->update_gamma = false;
-	vfe31_ctrl->update_luma = false;
-	vfe31_ctrl->s_info = s_info;
-	vfe31_ctrl->stats_comp = 0;
-	vfe31_ctrl->hfr_mode = HFR_MODE_OFF;
-	return 0;
-
-cmd_init_failed3:
-	free_irq(vfe31_ctrl->vfeirq, 0);
-	iounmap(vfe31_ctrl->vfebase);
-cmd_init_failed2:
-	kfree(vfe31_ctrl);
-cmd_init_failed1:
-	release_mem_region(vfemem->start, (vfemem->end - vfemem->start) + 1);
-	return rc;
-}
-
-static int vfe31_init(struct msm_vfe_callback *presp,
-	struct platform_device *pdev)
-{
-	int rc = 0;
-	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-
-	camio_clk = camdev->ioclk;
-
-	rc = vfe31_resource_init(presp, pdev, vfe_syncdata);
-	if (rc < 0)
-		return rc;
-	/* Bring up all the required GPIOs and Clocks */
-	rc = msm_camio_enable(pdev);
-	msm_camio_set_perf_lvl(S_INIT);
-	if (msm_vpe_open() < 0)
-		CDBG("%s: vpe_open failed\n", __func__);
-
-	/* TO DO: Need to release the VFE resources */
-	rc = request_irq(vfe31_ctrl->vfeirq, vfe31_parse_irq,
-			IRQF_TRIGGER_RISING, "vfe", 0);
-
-	return rc;
-}
-
-void msm_camvfe_fn_init(struct msm_camvfe_fn *fptr, void *data)
-{
-	fptr->vfe_init    = vfe31_init;
-	fptr->vfe_enable  = vfe31_enable;
-	fptr->vfe_config  = vfe31_config;
-	fptr->vfe_disable = vfe31_disable;
-	fptr->vfe_release = vfe31_release;
-	fptr->vfe_stop = vfe31_stop;
-	vfe_syncdata = data;
-}
-
-void msm_camvpe_fn_init(struct msm_camvpe_fn *fptr, void *data)
-{
-	fptr->vpe_reg		= msm_vpe_reg;
-	fptr->send_frame_to_vpe	= msm_send_frame_to_vpe;
-	fptr->vpe_config	= msm_vpe_config;
-	fptr->vpe_cfg_update	= msm_vpe_cfg_update;
-	fptr->dis		= &(vpe_ctrl->dis_en);
-	fptr->vpe_cfg_offset = msm_vpe_offset_update;
-	vpe_ctrl->syncdata = data;
-}
diff --git a/drivers/media/video/msm/vfe/msm_vfe31.h b/drivers/media/video/msm/vfe/msm_vfe31.h
deleted file mode 100644
index bec5f58..0000000
--- a/drivers/media/video/msm/vfe/msm_vfe31.h
+++ /dev/null
@@ -1,1119 +0,0 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. 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 __MSM_VFE31_H__
-#define __MSM_VFE31_H__
-
-#define TRUE  1
-#define FALSE 0
-
-/* at start of camif,  bit 1:0 = 0x01:enable
- * image data capture at frame boundary. */
-#define CAMIF_COMMAND_START  0x00000005
-
-/* bit 2= 0x1:clear the CAMIF_STATUS register
- * value. */
-#define CAMIF_COMMAND_CLEAR  0x00000004
-
-/* at stop of vfe pipeline, for now it is assumed
- * that camif will stop at any time. Bit 1:0 = 0x10:
- * disable image data capture immediately. */
-#define CAMIF_COMMAND_STOP_IMMEDIATELY  0x00000002
-
-/* at stop of vfe pipeline, for now it is assumed
- * that camif will stop at any time. Bit 1:0 = 0x00:
- * disable image data capture at frame boundary */
-#define CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY  0x00000000
-
-/* to halt axi bridge */
-#define AXI_HALT  0x00000001
-
-/* clear the halt bit. */
-#define AXI_HALT_CLEAR  0x00000000
-
-/* clear axi_halt_irq */
-#define MASK_AXI_HALT_IRQ	0xFF7FFFFF
-
-/* reset the pipeline when stop command is issued.
- * (without reset the register.) bit 26-31 = 0,
- * domain reset, bit 0-9 = 1 for module reset, except
- * register module. */
-#define VFE_RESET_UPON_STOP_CMD  0x000003ef
-
-/* reset the pipeline when reset command.
- * bit 26-31 = 0, domain reset, bit 0-9 = 1 for module reset. */
-#define VFE_RESET_UPON_RESET_CMD  0x000003ff
-
-/* bit 5 is for axi status idle or busy.
- * 1 =  halted,  0 = busy */
-#define AXI_STATUS_BUSY_MASK 0x00000020
-
-/* bit 0 & bit 1 = 1, both y and cbcr irqs need to be present
- * for frame done interrupt */
-#define VFE_COMP_IRQ_BOTH_Y_CBCR 3
-
-/* bit 1 = 1, only cbcr irq triggers frame done interrupt */
-#define VFE_COMP_IRQ_CBCR_ONLY 2
-
-/* bit 0 = 1, only y irq triggers frame done interrupt */
-#define VFE_COMP_IRQ_Y_ONLY 1
-
-/* bit 0 = 1, PM go;   bit1 = 1, PM stop */
-#define VFE_PERFORMANCE_MONITOR_GO   0x00000001
-#define VFE_PERFORMANCE_MONITOR_STOP 0x00000002
-
-/* bit 0 = 1, test gen go;   bit1 = 1, test gen stop */
-#define VFE_TEST_GEN_GO   0x00000001
-#define VFE_TEST_GEN_STOP 0x00000002
-
-/* the chroma is assumed to be interpolated between
- * the luma samples.  JPEG 4:2:2 */
-#define VFE_CHROMA_UPSAMPLE_INTERPOLATED 0
-
-/* constants for irq registers */
-#define VFE_DISABLE_ALL_IRQS 0
-/* bit =1 is to clear the corresponding bit in VFE_IRQ_STATUS.  */
-#define VFE_CLEAR_ALL_IRQS   0xffffffff
-
-#define VFE_IRQ_STATUS0_CAMIF_SOF_MASK            0x00000001
-#define VFE_IRQ_STATUS0_CAMIF_EOF_MASK            0x00000004
-#define VFE_IRQ_STATUS0_REG_UPDATE_MASK           0x00000020
-#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK 0x00200000
-#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK 0x00400000
-#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE2_MASK 0x00800000
-#define VFE_IRQ_STATUS1_RESET_AXI_HALT_ACK_MASK   0x00800000
-#define VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK       0x01000000
-
-#define VFE_IRQ_STATUS0_STATS_AEC     0x2000  /* bit 13 */
-#define VFE_IRQ_STATUS0_STATS_AF      0x4000  /* bit 14 */
-#define VFE_IRQ_STATUS0_STATS_AWB     0x8000  /* bit 15 */
-#define VFE_IRQ_STATUS0_STATS_RS      0x10000  /* bit 16 */
-#define VFE_IRQ_STATUS0_STATS_CS      0x20000  /* bit 17 */
-#define VFE_IRQ_STATUS0_STATS_IHIST   0x40000  /* bit 18 */
-
-#define VFE_IRQ_STATUS0_SYNC_TIMER0   0x2000000  /* bit 25 */
-#define VFE_IRQ_STATUS0_SYNC_TIMER1   0x4000000  /* bit 26 */
-#define VFE_IRQ_STATUS0_SYNC_TIMER2   0x8000000  /* bit 27 */
-#define VFE_IRQ_STATUS0_ASYNC_TIMER0  0x10000000  /* bit 28 */
-#define VFE_IRQ_STATUS0_ASYNC_TIMER1  0x20000000  /* bit 29 */
-#define VFE_IRQ_STATUS0_ASYNC_TIMER2  0x40000000  /* bit 30 */
-#define VFE_IRQ_STATUS0_ASYNC_TIMER3  0x80000000  /* bit 31 */
-
-/* imask for while waiting for stop ack,  driver has already
- * requested stop, waiting for reset irq, and async timer irq.
- * For irq_status_0, bit 28-31 are for async timer. For
- * irq_status_1, bit 22 for reset irq, bit 23 for axi_halt_ack
-   irq */
-#define VFE_IMASK_WHILE_STOPPING_0  0xF0000000
-#define VFE_IMASK_WHILE_STOPPING_1  0x00C00000
-#define VFE_IMASK_RESET             0x00400000
-#define VFE_IMASK_AXI_HALT          0x00800000
-
-
-/* no error irq in mask 0 */
-#define VFE_IMASK_ERROR_ONLY_0  0x0
-/* when normal case, don't want to block error status. */
-/* bit 0-21 are error irq bits */
-#define VFE_IMASK_ERROR_ONLY_1  0x003fffff
-
-/* For BPC bit 0,bit 12-17 and bit 26 -20 are set to zero and other's 1 */
-#define BPC_MASK 0xF80C0FFE
-
-/* For BPC bit 1 and 2 are set to zero and other's 1 */
-#define ABF_MASK 0xFFFFFFF9
-
-/* For MCE enable bit 28 set to zero and other's 1 */
-#define MCE_EN_MASK 0xEFFFFFFF
-
-/* For MCE Q_K bit 28 to 31 set to zero and other's 1 */
-#define MCE_Q_K_MASK 0x0FFFFFFF
-
-#define AWB_ENABLE_MASK 0x00000080     /* bit 7 */
-#define AF_ENABLE_MASK 0x00000040      /* bit 6 */
-#define AE_ENABLE_MASK 0x00000020      /* bit 5 */
-#define IHIST_ENABLE_MASK 0x00008000   /* bit 15 */
-#define RS_ENABLE_MASK 0x00000100      /* bit 8  */
-#define CS_ENABLE_MASK 0x00000200      /* bit 9  */
-#define RS_CS_ENABLE_MASK 0x00000300   /* bit 8,9  */
-#define STATS_ENABLE_MASK 0x000483E0   /* bit 18,15,9,8,7,6,5*/
-
-#define VFE_REG_UPDATE_TRIGGER           1
-#define VFE_PM_BUF_MAX_CNT_MASK          0xFF
-#define VFE_DMI_CFG_DEFAULT              0x00000100
-#define LENS_ROLL_OFF_DELTA_TABLE_OFFSET 32
-#define VFE_AE_PINGPONG_STATUS_BIT       0x80
-#define VFE_AF_PINGPONG_STATUS_BIT       0x100
-#define VFE_AWB_PINGPONG_STATUS_BIT      0x200
-#define PINGPONG_LOWER                   0x7
-
-#define HFR_MODE_OFF 1
-
-enum VFE31_DMI_RAM_SEL {
-	 NO_MEM_SELECTED          = 0,
-	 ROLLOFF_RAM              = 0x1,
-	 RGBLUT_RAM_CH0_BANK0     = 0x2,
-	 RGBLUT_RAM_CH0_BANK1     = 0x3,
-	 RGBLUT_RAM_CH1_BANK0     = 0x4,
-	 RGBLUT_RAM_CH1_BANK1     = 0x5,
-	 RGBLUT_RAM_CH2_BANK0     = 0x6,
-	 RGBLUT_RAM_CH2_BANK1     = 0x7,
-	 STATS_HIST_RAM           = 0x8,
-	 RGBLUT_CHX_BANK0         = 0x9,
-	 RGBLUT_CHX_BANK1         = 0xa,
-	 LUMA_ADAPT_LUT_RAM_BANK0 = 0xb,
-	 LUMA_ADAPT_LUT_RAM_BANK1 = 0xc
-};
-
-enum  VFE_STATE {
-	VFE_STATE_IDLE,
-	VFE_STATE_ACTIVE
-};
-
-enum  vfe_recording_state {
-	VFE_REC_STATE_IDLE,
-	VFE_REC_STATE_START_REQUESTED,
-	VFE_REC_STATE_STARTED,
-	VFE_REC_STATE_STOP_REQUESTED,
-	VFE_REC_STATE_STOPPED,
-};
-
-#define V31_DUMMY_0               0
-#define V31_SET_CLK               1
-#define V31_RESET                 2
-#define V31_START                 3
-#define V31_TEST_GEN_START        4
-#define V31_OPERATION_CFG         5
-#define V31_AXI_OUT_CFG           6
-#define V31_CAMIF_CFG             7
-#define V31_AXI_INPUT_CFG         8
-#define V31_BLACK_LEVEL_CFG       9
-#define V31_ROLL_OFF_CFG          10
-#define V31_DEMUX_CFG             11
-#define V31_DEMOSAIC_0_CFG        12 /* general */
-#define V31_DEMOSAIC_1_CFG        13 /* ABF     */
-#define V31_DEMOSAIC_2_CFG        14 /* BPC     */
-#define V31_FOV_CFG               15
-#define V31_MAIN_SCALER_CFG       16
-#define V31_WB_CFG                17
-#define V31_COLOR_COR_CFG         18
-#define V31_RGB_G_CFG             19
-#define V31_LA_CFG                20
-#define V31_CHROMA_EN_CFG         21
-#define V31_CHROMA_SUP_CFG        22
-#define V31_MCE_CFG               23
-#define V31_SK_ENHAN_CFG          24
-#define V31_ASF_CFG               25
-#define V31_S2Y_CFG               26
-#define V31_S2CbCr_CFG            27
-#define V31_CHROMA_SUBS_CFG       28
-#define V31_OUT_CLAMP_CFG         29
-#define V31_FRAME_SKIP_CFG        30
-#define V31_DUMMY_1               31
-#define V31_DUMMY_2               32
-#define V31_DUMMY_3               33
-#define V31_UPDATE                34
-#define V31_BL_LVL_UPDATE         35
-#define V31_DEMUX_UPDATE          36
-#define V31_DEMOSAIC_1_UPDATE     37 /* BPC */
-#define V31_DEMOSAIC_2_UPDATE     38 /* ABF */
-#define V31_FOV_UPDATE            39
-#define V31_MAIN_SCALER_UPDATE    40
-#define V31_WB_UPDATE             41
-#define V31_COLOR_COR_UPDATE      42
-#define V31_RGB_G_UPDATE          43
-#define V31_LA_UPDATE             44
-#define V31_CHROMA_EN_UPDATE      45
-#define V31_CHROMA_SUP_UPDATE     46
-#define V31_MCE_UPDATE            47
-#define V31_SK_ENHAN_UPDATE       48
-#define V31_S2CbCr_UPDATE         49
-#define V31_S2Y_UPDATE            50
-#define V31_ASF_UPDATE            51
-#define V31_FRAME_SKIP_UPDATE     52
-#define V31_CAMIF_FRAME_UPDATE    53
-#define V31_STATS_AF_UPDATE       54
-#define V31_STATS_AE_UPDATE       55
-#define V31_STATS_AWB_UPDATE      56
-#define V31_STATS_RS_UPDATE       57
-#define V31_STATS_CS_UPDATE       58
-#define V31_STATS_SKIN_UPDATE     59
-#define V31_STATS_IHIST_UPDATE    60
-#define V31_DUMMY_4               61
-#define V31_EPOCH1_ACK            62
-#define V31_EPOCH2_ACK            63
-#define V31_START_RECORDING       64
-#define V31_STOP_RECORDING        65
-#define V31_DUMMY_5               66
-#define V31_DUMMY_6               67
-#define V31_CAPTURE               68
-#define V31_DUMMY_7               69
-#define V31_STOP                  70
-#define V31_GET_HW_VERSION        71
-#define V31_GET_FRAME_SKIP_COUNTS 72
-#define V31_OUTPUT1_BUFFER_ENQ    73
-#define V31_OUTPUT2_BUFFER_ENQ    74
-#define V31_OUTPUT3_BUFFER_ENQ    75
-#define V31_JPEG_OUT_BUF_ENQ      76
-#define V31_RAW_OUT_BUF_ENQ       77
-#define V31_RAW_IN_BUF_ENQ        78
-#define V31_STATS_AF_ENQ          79
-#define V31_STATS_AE_ENQ          80
-#define V31_STATS_AWB_ENQ         81
-#define V31_STATS_RS_ENQ          82
-#define V31_STATS_CS_ENQ          83
-#define V31_STATS_SKIN_ENQ        84
-#define V31_STATS_IHIST_ENQ       85
-#define V31_DUMMY_8               86
-#define V31_JPEG_ENC_CFG          87
-#define V31_DUMMY_9               88
-#define V31_STATS_AF_START        89
-#define V31_STATS_AF_STOP         90
-#define V31_STATS_AE_START        91
-#define V31_STATS_AE_STOP         92
-#define V31_STATS_AWB_START       93
-#define V31_STATS_AWB_STOP        94
-#define V31_STATS_RS_START        95
-#define V31_STATS_RS_STOP         96
-#define V31_STATS_CS_START        97
-#define V31_STATS_CS_STOP         98
-#define V31_STATS_SKIN_START      99
-#define V31_STATS_SKIN_STOP       100
-#define V31_STATS_IHIST_START     101
-#define V31_STATS_IHIST_STOP      102
-#define V31_DUMMY_10              103
-#define V31_SYNC_TIMER_SETTING    104
-#define V31_ASYNC_TIMER_SETTING   105
-#define V31_LIVESHOT              106
-#define V31_ZSL                   107
-#define V31_STEREOCAM             108
-#define V31_LA_SETUP              109
-#define V31_XBAR_CFG              110
-#define V31_EZTUNE_CFG            111
-
-#define V31_CAMIF_OFF             0x000001E4
-#define V31_CAMIF_LEN             32
-
-#define V31_DEMUX_OFF             0x00000284
-#define V31_DEMUX_LEN             20
-
-#define V31_DEMOSAIC_0_OFF        0x00000298
-#define V31_DEMOSAIC_0_LEN        4
-/* ABF     */
-#define V31_DEMOSAIC_1_OFF        0x000002A4
-#define V31_DEMOSAIC_1_LEN        180
-/* BPC     */
-#define V31_DEMOSAIC_2_OFF        0x0000029C
-#define V31_DEMOSAIC_2_LEN        8
-
-/* gamma VFE_LUT_BANK_SEL*/
-#define V31_GAMMA_CFG_OFF         0x000003BC
-#define V31_LUMA_CFG_OFF          0x000003C0
-
-#define V31_OUT_CLAMP_OFF         0x00000524
-#define V31_OUT_CLAMP_LEN         8
-
-#define V31_OPERATION_CFG_LEN     32
-
-#define V31_AXI_OUT_OFF           0x00000038
-#define V31_AXI_OUT_LEN           220
-#define V31_AXI_CH_INF_LEN        32
-#define V31_AXI_CFG_LEN           47
-
-#define V31_FRAME_SKIP_OFF        0x00000504
-#define V31_FRAME_SKIP_LEN        32
-
-#define V31_CHROMA_SUBS_OFF       0x000004F8
-#define V31_CHROMA_SUBS_LEN       12
-
-#define V31_FOV_OFF           0x00000360
-#define V31_FOV_LEN           8
-
-#define V31_MAIN_SCALER_OFF 0x00000368
-#define V31_MAIN_SCALER_LEN 28
-
-#define V31_S2Y_OFF 0x000004D0
-#define V31_S2Y_LEN 20
-
-#define V31_S2CbCr_OFF 0x000004E4
-#define V31_S2CbCr_LEN 20
-
-#define V31_CHROMA_EN_OFF 0x000003C4
-#define V31_CHROMA_EN_LEN 36
-
-#define V31_SYNC_TIMER_OFF      0x0000020C
-#define V31_SYNC_TIMER_POLARITY_OFF 0x00000234
-#define V31_TIMER_SELECT_OFF        0x0000025C
-#define V31_SYNC_TIMER_LEN 28
-
-#define V31_ASYNC_TIMER_OFF 0x00000238
-#define V31_ASYNC_TIMER_LEN 28
-
-#define V31_BLACK_LEVEL_OFF 0x00000264
-#define V31_BLACK_LEVEL_LEN 16
-
-#define V31_ROLL_OFF_CFG_OFF 0x00000274
-#define V31_ROLL_OFF_CFG_LEN 16
-
-#define V31_COLOR_COR_OFF 0x00000388
-#define V31_COLOR_COR_LEN 52
-
-#define V31_WB_OFF 0x00000384
-#define V31_WB_LEN 4
-
-#define V31_RGB_G_OFF 0x000003BC
-#define V31_RGB_G_LEN 4
-
-#define V31_LA_OFF 0x000003C0
-#define V31_LA_LEN 4
-
-#define V31_SCE_OFF 0x00000418
-#define V31_SCE_LEN 136
-
-#define V31_CHROMA_SUP_OFF 0x000003E8
-#define V31_CHROMA_SUP_LEN 12
-
-#define V31_MCE_OFF 0x000003F4
-#define V31_MCE_LEN 36
-#define V31_STATS_AF_OFF 0x0000053c
-#define V31_STATS_AF_LEN 16
-
-#define V31_STATS_AE_OFF 0x00000534
-#define V31_STATS_AE_LEN 8
-
-#define V31_STATS_AWB_OFF 0x0000054c
-#define V31_STATS_AWB_LEN 32
-
-#define V31_STATS_IHIST_OFF 0x0000057c
-#define V31_STATS_IHIST_LEN 8
-
-#define V31_STATS_RS_OFF 0x0000056c
-#define V31_STATS_RS_LEN 8
-
-#define V31_STATS_CS_OFF 0x00000574
-#define V31_STATS_CS_LEN 8
-
-#define V31_XBAR_CFG_OFF 0x00000040
-#define V31_XBAR_CFG_LEN 8
-
-#define V31_EZTUNE_CFG_OFF 0x00000010
-#define V31_EZTUNE_CFG_LEN 4
-
-#define V31_ASF_OFF 0x000004A0
-#define V31_ASF_LEN 48
-#define V31_ASF_UPDATE_LEN 36
-
-#define V31_CAPTURE_LEN 4
-
-struct vfe_cmd_hw_version {
-	uint32_t minorVersion;
-	uint32_t majorVersion;
-	uint32_t coreVersion;
-};
-
-enum VFE_AXI_OUTPUT_MODE {
-	VFE_AXI_OUTPUT_MODE_Output1,
-	VFE_AXI_OUTPUT_MODE_Output2,
-	VFE_AXI_OUTPUT_MODE_Output1AndOutput2,
-	VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2,
-	VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1,
-	VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2,
-	VFE_AXI_LAST_OUTPUT_MODE_ENUM
-};
-
-enum VFE_RAW_WR_PATH_SEL {
-	VFE_RAW_OUTPUT_DISABLED,
-	VFE_RAW_OUTPUT_ENC_CBCR_PATH,
-	VFE_RAW_OUTPUT_VIEW_CBCR_PATH,
-	VFE_RAW_OUTPUT_PATH_INVALID
-};
-
-
-#define VFE_AXI_OUTPUT_BURST_LENGTH     4
-#define VFE_MAX_NUM_FRAGMENTS_PER_FRAME 4
-#define VFE_AXI_OUTPUT_CFG_FRAME_COUNT  3
-
-struct vfe_cmds_per_write_master {
-	uint16_t imageWidth;
-	uint16_t imageHeight;
-	uint16_t outRowCount;
-	uint16_t outRowIncrement;
-	uint32_t outFragments[VFE_AXI_OUTPUT_CFG_FRAME_COUNT]
-		[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
-};
-
-struct vfe_cmds_axi_per_output_path {
-	uint8_t fragmentCount;
-	struct vfe_cmds_per_write_master firstWM;
-	struct vfe_cmds_per_write_master secondWM;
-};
-
-enum VFE_AXI_BURST_LENGTH {
-	VFE_AXI_BURST_LENGTH_IS_2  = 2,
-	VFE_AXI_BURST_LENGTH_IS_4  = 4,
-	VFE_AXI_BURST_LENGTH_IS_8  = 8,
-	VFE_AXI_BURST_LENGTH_IS_16 = 16
-};
-
-
-struct vfe_cmd_fov_crop_config {
-	uint8_t enable;
-	uint16_t firstPixel;
-	uint16_t lastPixel;
-	uint16_t firstLine;
-	uint16_t lastLine;
-};
-
-struct vfe_cmds_main_scaler_stripe_init {
-	uint16_t MNCounterInit;
-	uint16_t phaseInit;
-};
-
-struct vfe_cmds_scaler_one_dimension {
-	uint8_t  enable;
-	uint16_t inputSize;
-	uint16_t outputSize;
-	uint32_t phaseMultiplicationFactor;
-	uint8_t  interpolationResolution;
-};
-
-struct vfe_cmd_main_scaler_config {
-	uint8_t enable;
-	struct vfe_cmds_scaler_one_dimension    hconfig;
-	struct vfe_cmds_scaler_one_dimension    vconfig;
-	struct vfe_cmds_main_scaler_stripe_init MNInitH;
-	struct vfe_cmds_main_scaler_stripe_init MNInitV;
-};
-
-struct vfe_cmd_scaler2_config {
-	uint8_t enable;
-	struct vfe_cmds_scaler_one_dimension hconfig;
-	struct vfe_cmds_scaler_one_dimension vconfig;
-};
-
-
-struct vfe_cmd_frame_skip_update {
-	uint32_t output1Pattern;
-	uint32_t output2Pattern;
-};
-
-struct vfe_cmd_output_clamp_config {
-	uint8_t minCh0;
-	uint8_t minCh1;
-	uint8_t minCh2;
-	uint8_t maxCh0;
-	uint8_t maxCh1;
-	uint8_t maxCh2;
-};
-
-struct vfe_cmd_chroma_subsample_config {
-	uint8_t enable;
-	uint8_t cropEnable;
-	uint8_t vsubSampleEnable;
-	uint8_t hsubSampleEnable;
-	uint8_t vCosited;
-	uint8_t hCosited;
-	uint8_t vCositedPhase;
-	uint8_t hCositedPhase;
-	uint16_t cropWidthFirstPixel;
-	uint16_t cropWidthLastPixel;
-	uint16_t cropHeightFirstLine;
-	uint16_t cropHeightLastLine;
-};
-
-enum VFE_START_INPUT_SOURCE {
-	VFE_START_INPUT_SOURCE_CAMIF,
-	VFE_START_INPUT_SOURCE_TESTGEN,
-	VFE_START_INPUT_SOURCE_AXI,
-	VFE_START_INPUT_SOURCE_INVALID
-};
-
-enum VFE_START_PIXEL_PATTERN {
-	VFE_BAYER_RGRGRG,
-	VFE_BAYER_GRGRGR,
-	VFE_BAYER_BGBGBG,
-	VFE_BAYER_GBGBGB,
-	VFE_YUV_YCbYCr,
-	VFE_YUV_YCrYCb,
-	VFE_YUV_CbYCrY,
-	VFE_YUV_CrYCbY
-};
-
-enum VFE_BUS_RD_INPUT_PIXEL_PATTERN {
-	VFE_BAYER_RAW,
-	VFE_YUV_INTERLEAVED,
-	VFE_YUV_PSEUDO_PLANAR_Y,
-	VFE_YUV_PSEUDO_PLANAR_CBCR
-};
-
-enum VFE_YUV_INPUT_COSITING_MODE {
-	VFE_YUV_COSITED,
-	VFE_YUV_INTERPOLATED
-};
-
-
-/* 13*1  */
-#define VFE31_ROLL_OFF_INIT_TABLE_SIZE  13
-/* 13*16 */
-#define VFE31_ROLL_OFF_DELTA_TABLE_SIZE 208
-
-#define VFE31_GAMMA_NUM_ENTRIES  64
-
-#define VFE31_LA_TABLE_LENGTH    64
-
-#define VFE31_HIST_TABLE_LENGTH  256
-
-struct vfe_cmds_demosaic_abf {
-	uint8_t   enable;
-	uint8_t   forceOn;
-	uint8_t   shift;
-	uint16_t  lpThreshold;
-	uint16_t  max;
-	uint16_t  min;
-	uint8_t   ratio;
-};
-
-struct vfe_cmds_demosaic_bpc {
-	uint8_t   enable;
-	uint16_t  fmaxThreshold;
-	uint16_t  fminThreshold;
-	uint16_t  redDiffThreshold;
-	uint16_t  blueDiffThreshold;
-	uint16_t  greenDiffThreshold;
-};
-
-struct vfe_cmd_demosaic_config {
-	uint8_t   enable;
-	uint8_t   slopeShift;
-	struct vfe_cmds_demosaic_abf abfConfig;
-	struct vfe_cmds_demosaic_bpc bpcConfig;
-};
-
-struct vfe_cmd_demosaic_bpc_update {
-	struct vfe_cmds_demosaic_bpc bpcUpdate;
-};
-
-struct vfe_cmd_demosaic_abf_update {
-	struct vfe_cmds_demosaic_abf abfUpdate;
-};
-
-struct vfe_cmd_white_balance_config {
-	uint8_t  enable;
-	uint16_t ch2Gain;
-	uint16_t ch1Gain;
-	uint16_t ch0Gain;
-};
-
-enum VFE_COLOR_CORRECTION_COEF_QFACTOR {
-	COEF_IS_Q7_SIGNED,
-	COEF_IS_Q8_SIGNED,
-	COEF_IS_Q9_SIGNED,
-	COEF_IS_Q10_SIGNED
-};
-
-struct vfe_cmd_color_correction_config {
-	uint8_t     enable;
-	enum VFE_COLOR_CORRECTION_COEF_QFACTOR coefQFactor;
-	int16_t  C0;
-	int16_t  C1;
-	int16_t  C2;
-	int16_t  C3;
-	int16_t  C4;
-	int16_t  C5;
-	int16_t  C6;
-	int16_t  C7;
-	int16_t  C8;
-	int16_t  K0;
-	int16_t  K1;
-	int16_t  K2;
-};
-
-#define VFE_LA_TABLE_LENGTH 64
-
-struct vfe_cmd_la_config {
-	uint8_t enable;
-	int16_t table[VFE_LA_TABLE_LENGTH];
-};
-
-#define VFE_GAMMA_TABLE_LENGTH 256
-enum VFE_RGB_GAMMA_TABLE_SELECT {
-	RGB_GAMMA_CH0_SELECTED,
-	RGB_GAMMA_CH1_SELECTED,
-	RGB_GAMMA_CH2_SELECTED,
-	RGB_GAMMA_CH0_CH1_SELECTED,
-	RGB_GAMMA_CH0_CH2_SELECTED,
-	RGB_GAMMA_CH1_CH2_SELECTED,
-	RGB_GAMMA_CH0_CH1_CH2_SELECTED
-};
-
-struct vfe_cmd_rgb_gamma_config {
-	uint8_t enable;
-	enum VFE_RGB_GAMMA_TABLE_SELECT channelSelect;
-	int16_t table[VFE_GAMMA_TABLE_LENGTH];
-};
-
-struct vfe_cmd_chroma_enhan_config {
-	uint8_t  enable;
-	int16_t am;
-	int16_t ap;
-	int16_t bm;
-	int16_t bp;
-	int16_t cm;
-	int16_t cp;
-	int16_t dm;
-	int16_t dp;
-	int16_t kcr;
-	int16_t kcb;
-	int16_t RGBtoYConversionV0;
-	int16_t RGBtoYConversionV1;
-	int16_t RGBtoYConversionV2;
-	uint8_t RGBtoYConversionOffset;
-};
-
-struct vfe_cmd_chroma_suppression_config {
-	uint8_t enable;
-	uint8_t m1;
-	uint8_t m3;
-	uint8_t n1;
-	uint8_t n3;
-	uint8_t nn1;
-	uint8_t mm1;
-};
-
-struct vfe_cmd_asf_config {
-	uint8_t enable;
-	uint8_t smoothFilterEnabled;
-	uint8_t sharpMode;
-	uint8_t smoothCoefCenter;
-	uint8_t smoothCoefSurr;
-	uint8_t normalizeFactor;
-	uint8_t sharpK1;
-	uint8_t sharpK2;
-	uint8_t sharpThreshE1;
-	int8_t sharpThreshE2;
-	int8_t sharpThreshE3;
-	int8_t sharpThreshE4;
-	int8_t sharpThreshE5;
-	int8_t filter1Coefficients[9];
-	int8_t filter2Coefficients[9];
-	uint8_t  cropEnable;
-	uint16_t cropFirstPixel;
-	uint16_t cropLastPixel;
-	uint16_t cropFirstLine;
-	uint16_t cropLastLine;
-};
-
-struct vfe_cmd_asf_update {
-	uint8_t enable;
-	uint8_t smoothFilterEnabled;
-	uint8_t sharpMode;
-	uint8_t smoothCoefCenter;
-	uint8_t smoothCoefSurr;
-	uint8_t normalizeFactor;
-	uint8_t sharpK1;
-	uint8_t sharpK2;
-	uint8_t sharpThreshE1;
-	int8_t  sharpThreshE2;
-	int8_t  sharpThreshE3;
-	int8_t  sharpThreshE4;
-	int8_t  sharpThreshE5;
-	int8_t  filter1Coefficients[9];
-	int8_t  filter2Coefficients[9];
-	uint8_t cropEnable;
-};
-
-enum VFE_TEST_GEN_SYNC_EDGE {
-	VFE_TEST_GEN_SYNC_EDGE_ActiveHigh,
-	VFE_TEST_GEN_SYNC_EDGE_ActiveLow
-};
-
-
-struct vfe_cmd_bus_pm_start {
-	uint8_t output2YWrPmEnable;
-	uint8_t output2CbcrWrPmEnable;
-	uint8_t output1YWrPmEnable;
-	uint8_t output1CbcrWrPmEnable;
-};
-
-struct  vfe_frame_skip_counts {
-	uint32_t  totalFrameCount;
-	uint32_t  output1Count;
-	uint32_t  output2Count;
-};
-
-enum VFE_AXI_RD_UNPACK_HBI_SEL {
-	VFE_AXI_RD_HBI_32_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_64_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_128_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_256_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_512_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_1024_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_2048_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_4096_CLOCK_CYCLES
-};
-
-enum VFE31_MESSAGE_ID {
-	MSG_ID_RESET_ACK, /* 0 */
-	MSG_ID_START_ACK,
-	MSG_ID_STOP_ACK,
-	MSG_ID_UPDATE_ACK,
-	MSG_ID_OUTPUT_P,
-	MSG_ID_OUTPUT_T,
-	MSG_ID_OUTPUT_S,
-	MSG_ID_OUTPUT_V,
-	MSG_ID_SNAPSHOT_DONE,
-	MSG_ID_COMMON,
-	MSG_ID_EPOCH1, /* 10 */
-	MSG_ID_EPOCH2,
-	MSG_ID_SYNC_TIMER0_DONE,
-	MSG_ID_SYNC_TIMER1_DONE,
-	MSG_ID_SYNC_TIMER2_DONE,
-	MSG_ID_ASYNC_TIMER0_DONE,
-	MSG_ID_ASYNC_TIMER1_DONE,
-	MSG_ID_ASYNC_TIMER2_DONE,
-	MSG_ID_ASYNC_TIMER3_DONE,
-	MSG_ID_AE_OVERFLOW,
-	MSG_ID_AF_OVERFLOW, /* 20 */
-	MSG_ID_AWB_OVERFLOW,
-	MSG_ID_RS_OVERFLOW,
-	MSG_ID_CS_OVERFLOW,
-	MSG_ID_IHIST_OVERFLOW,
-	MSG_ID_SKIN_OVERFLOW,
-	MSG_ID_AXI_ERROR,
-	MSG_ID_CAMIF_OVERFLOW,
-	MSG_ID_VIOLATION,
-	MSG_ID_CAMIF_ERROR,
-	MSG_ID_BUS_OVERFLOW, /* 30 */
-	MSG_ID_SOF_ACK,
-	MSG_ID_STOP_REC_ACK,
-};
-
-struct stats_buffer {
-	uint8_t awb_ymin;
-	uint32_t aec;
-	uint32_t awb;
-	uint32_t af;
-	uint32_t ihist;
-	uint32_t rs;
-	uint32_t cs;
-	uint32_t skin;
-};
-
-struct vfe_msg_stats {
-	struct stats_buffer buff;
-	uint32_t    frameCounter;
-	uint32_t    status_bits;
-};
-
-
-struct vfe_frame_bpc_info {
-	uint32_t greenDefectPixelCount;
-	uint32_t redBlueDefectPixelCount;
-};
-
-struct vfe_frame_asf_info {
-	uint32_t  asfMaxEdge;
-	uint32_t  asfHbiCount;
-};
-
-struct vfe_msg_camif_status {
-	uint8_t  camifState;
-	uint32_t pixelCount;
-	uint32_t lineCount;
-};
-
-
-struct vfe31_irq_status {
-	uint32_t vfeIrqStatus0;
-	uint32_t vfeIrqStatus1;
-	uint32_t camifStatus;
-	uint32_t demosaicStatus;
-	uint32_t asfMaxEdge;
-	uint32_t vfePingPongStatus;
-};
-
-struct vfe_msg_output {
-	uint8_t   output_id;
-	uint32_t  p0_addr;
-	uint32_t  p1_addr;
-	uint32_t  p2_addr;
-	struct vfe_frame_bpc_info bpcInfo;
-	struct vfe_frame_asf_info asfInfo;
-	uint32_t  frameCounter;
-};
-
-struct vfe_message {
-	enum VFE31_MESSAGE_ID _d;
-	union {
-		struct vfe_msg_output              msgOut;
-		struct vfe_msg_stats               msgStats;
-		struct vfe_msg_camif_status        msgCamifError;
-   } _u;
-};
-
-/* New one for 7x30 */
-struct msm_vfe31_cmd {
-	int32_t  id;
-	uint16_t length;
-	void     *value;
-};
-
-#define V31_PREVIEW_AXI_FLAG  0x00000001
-#define V31_SNAPSHOT_AXI_FLAG (0x00000001<<1)
-
-struct vfe31_cmd_type {
-	uint16_t id;
-	uint32_t length;
-	uint32_t offset;
-	uint32_t flag;
-};
-
-struct vfe31_free_buf {
-	struct list_head node;
-	uint32_t paddr;
-	uint32_t planar0_off;
-	uint32_t planar1_off;
-	uint32_t planar2_off;
-	uint32_t cbcr_off;
-};
-
-struct vfe31_output_ch {
-	struct list_head free_buf_head;
-	spinlock_t free_buf_lock;
-	uint16_t output_fmt;
-	int8_t ch0;
-	int8_t ch1;
-	int8_t ch2;
-	uint32_t  frame_drop_cnt;
-};
-
-/* no error irq in mask 0 */
-#define VFE31_IMASK_ERROR_ONLY_0  0x0
-/* when normal case, don't want to block error status. */
-/* bit 0-21 are error irq bits */
-#define VFE31_IMASK_ERROR_ONLY_1               0x003FFFFF
-#define VFE31_IMASK_CAMIF_ERROR               (0x00000001<<0)
-#define VFE31_IMASK_STATS_CS_OVWR             (0x00000001<<1)
-#define VFE31_IMASK_STATS_IHIST_OVWR          (0x00000001<<2)
-#define VFE31_IMASK_REALIGN_BUF_Y_OVFL        (0x00000001<<3)
-#define VFE31_IMASK_REALIGN_BUF_CB_OVFL       (0x00000001<<4)
-#define VFE31_IMASK_REALIGN_BUF_CR_OVFL       (0x00000001<<5)
-#define VFE31_IMASK_VIOLATION                 (0x00000001<<6)
-#define VFE31_IMASK_IMG_MAST_0_BUS_OVFL       (0x00000001<<7)
-#define VFE31_IMASK_IMG_MAST_1_BUS_OVFL       (0x00000001<<8)
-#define VFE31_IMASK_IMG_MAST_2_BUS_OVFL       (0x00000001<<9)
-#define VFE31_IMASK_IMG_MAST_3_BUS_OVFL       (0x00000001<<10)
-#define VFE31_IMASK_IMG_MAST_4_BUS_OVFL       (0x00000001<<11)
-#define VFE31_IMASK_IMG_MAST_5_BUS_OVFL       (0x00000001<<12)
-#define VFE31_IMASK_IMG_MAST_6_BUS_OVFL       (0x00000001<<13)
-#define VFE31_IMASK_STATS_AE_BUS_OVFL         (0x00000001<<14)
-#define VFE31_IMASK_STATS_AF_BUS_OVFL         (0x00000001<<15)
-#define VFE31_IMASK_STATS_AWB_BUS_OVFL        (0x00000001<<16)
-#define VFE31_IMASK_STATS_RS_BUS_OVFL         (0x00000001<<17)
-#define VFE31_IMASK_STATS_CS_BUS_OVFL         (0x00000001<<18)
-#define VFE31_IMASK_STATS_IHIST_BUS_OVFL      (0x00000001<<19)
-#define VFE31_IMASK_STATS_SKIN_BUS_OVFL       (0x00000001<<20)
-#define VFE31_IMASK_AXI_ERROR                 (0x00000001<<21)
-
-#define VFE_COM_STATUS 0x000FE000
-
-struct vfe31_output_path {
-	uint16_t output_mode;     /* bitmask  */
-
-	struct vfe31_output_ch out0; /* preview and thumbnail */
-	struct vfe31_output_ch out1; /* snapshot */
-	struct vfe31_output_ch out2; /* video    */
-};
-
-struct vfe31_frame_extra {
-	uint32_t greenDefectPixelCount;
-	uint32_t redBlueDefectPixelCount;
-
-	uint32_t  asfMaxEdge;
-	uint32_t  asfHbiCount;
-
-	uint32_t yWrPmStats0;
-	uint32_t yWrPmStats1;
-	uint32_t cbcrWrPmStats0;
-	uint32_t cbcrWrPmStats1;
-
-	uint32_t  frameCounter;
-};
-
-#define VFE_DISABLE_ALL_IRQS             0
-#define VFE_CLEAR_ALL_IRQS               0xffffffff
-
-#define VFE_GLOBAL_RESET                 0x00000004
-#define VFE_CGC_OVERRIDE                 0x0000000C
-#define VFE_MODULE_CFG                   0x00000010
-#define VFE_CFG_OFF                      0x00000014
-#define VFE_IRQ_CMD                      0x00000018
-#define VFE_IRQ_MASK_0                   0x0000001C
-#define VFE_IRQ_MASK_1                   0x00000020
-#define VFE_IRQ_CLEAR_0                  0x00000024
-#define VFE_IRQ_CLEAR_1                  0x00000028
-#define VFE_IRQ_STATUS_0                 0x0000002C
-#define VFE_IRQ_STATUS_1                 0x00000030
-#define VFE_IRQ_COMP_MASK                0x00000034
-#define VFE_BUS_CMD                      0x00000038
-#define VFE_BUS_PING_PONG_STATUS         0x00000180
-#define VFE_BUS_OPERATION_STATUS         0x00000184
-
-#define VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_0        0x00000190
-#define VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_1        0x00000194
-
-#define VFE_AXI_CMD                      0x000001D8
-#define VFE_AXI_STATUS                   0x000001DC
-#define VFE_BUS_STATS_PING_PONG_BASE     0x000000F4
-
-#define VFE_BUS_STATS_AEC_WR_PING_ADDR   0x000000F4
-#define VFE_BUS_STATS_AEC_WR_PONG_ADDR   0x000000F8
-#define VFE_BUS_STATS_AEC_UB_CFG         0x000000FC
-#define VFE_BUS_STATS_AF_WR_PING_ADDR    0x00000100
-#define VFE_BUS_STATS_AF_WR_PONG_ADDR    0x00000104
-#define VFE_BUS_STATS_AF_UB_CFG          0x00000108
-#define VFE_BUS_STATS_AWB_WR_PING_ADDR   0x0000010C
-#define VFE_BUS_STATS_AWB_WR_PONG_ADDR   0x00000110
-#define VFE_BUS_STATS_AWB_UB_CFG         0x00000114
-#define VFE_BUS_STATS_RS_WR_PING_ADDR    0x00000118
-#define VFE_BUS_STATS_RS_WR_PONG_ADDR    0x0000011C
-#define VFE_BUS_STATS_RS_UB_CFG          0x00000120
-
-#define VFE_BUS_STATS_CS_WR_PING_ADDR    0x00000124
-#define VFE_BUS_STATS_CS_WR_PONG_ADDR    0x00000128
-#define VFE_BUS_STATS_CS_UB_CFG          0x0000012C
-#define VFE_BUS_STATS_HIST_WR_PING_ADDR  0x00000130
-#define VFE_BUS_STATS_HIST_WR_PONG_ADDR  0x00000134
-#define VFE_BUS_STATS_HIST_UB_CFG        0x00000138
-#define VFE_BUS_STATS_SKIN_WR_PING_ADDR  0x0000013C
-#define VFE_BUS_STATS_SKIN_WR_PONG_ADDR  0x00000140
-#define VFE_BUS_STATS_SKIN_UB_CFG        0x00000144
-#define VFE_BUS_PM_CMD                   0x00000188
-#define VFE_BUS_PM_CFG                   0x0000018C
-#define VFE_CAMIF_COMMAND                0x000001E0
-#define VFE_CAMIF_STATUS                 0x00000204
-#define VFE_REG_UPDATE_CMD               0x00000260
-#define VFE_DEMUX_GAIN_0                 0x00000288
-#define VFE_DEMUX_GAIN_1                 0x0000028C
-#define VFE_CHROMA_UP                    0x0000035C
-#define VFE_FRAMEDROP_ENC_Y_CFG          0x00000504
-#define VFE_FRAMEDROP_ENC_CBCR_CFG       0x00000508
-#define VFE_FRAMEDROP_ENC_Y_PATTERN      0x0000050C
-#define VFE_FRAMEDROP_ENC_CBCR_PATTERN   0x00000510
-#define VFE_FRAMEDROP_VIEW_Y             0x00000514
-#define VFE_FRAMEDROP_VIEW_CBCR          0x00000518
-#define VFE_FRAMEDROP_VIEW_Y_PATTERN     0x0000051C
-#define VFE_FRAMEDROP_VIEW_CBCR_PATTERN  0x00000520
-#define VFE_CLAMP_MAX                    0x00000524
-#define VFE_CLAMP_MIN                    0x00000528
-#define VFE_REALIGN_BUF                  0x0000052C
-#define VFE_STATS_CFG                    0x00000530
-#define VFE_STATS_AWB_SGW_CFG            0x00000554
-#define VFE_DMI_CFG                      0x00000598
-#define VFE_DMI_ADDR                     0x0000059C
-#define VFE_DMI_DATA_LO                  0x000005A4
-#define VFE_AXI_CFG                      0x00000600
-
-struct vfe_stats_control {
-	uint8_t  ackPending;
-	uint32_t nextFrameAddrBuf;
-	uint32_t droppedStatsFrameCount;
-	uint32_t bufToRender;
-};
-
-struct vfe31_ctrl_type {
-	uint16_t operation_mode;     /* streaming or snapshot */
-	struct vfe31_output_path outpath;
-
-	uint32_t vfeImaskCompositePacked;
-
-	spinlock_t  update_ack_lock;
-	spinlock_t  io_lock;
-
-	int8_t aec_ack_pending;
-	int8_t awb_ack_pending;
-	int8_t af_ack_pending;
-	int8_t ihist_ack_pending;
-	int8_t rs_ack_pending;
-	int8_t cs_ack_pending;
-
-	struct msm_vfe_callback *resp;
-	uint32_t extlen;
-	void *extdata;
-
-	int8_t start_ack_pending;
-	atomic_t stop_ack_pending;
-	int8_t reset_ack_pending;
-	int8_t update_ack_pending;
-	enum vfe_recording_state recording_state;
-	int8_t output0_available;
-	int8_t output1_available;
-	int8_t update_gamma;
-	int8_t update_luma;
-	spinlock_t  tasklet_lock;
-	struct list_head tasklet_q;
-	int vfeirq;
-	void __iomem *vfebase;
-	void *syncdata;
-
-	struct resource	*vfemem;
-	struct resource *vfeio;
-
-	uint32_t stats_comp;
-	uint32_t hfr_mode;
-	atomic_t vstate;
-	uint32_t vfe_capture_count;
-	uint32_t sync_timer_repeat_count;
-	uint32_t sync_timer_state;
-	uint32_t sync_timer_number;
-
-	uint32_t vfeFrameId;
-	uint32_t output1Pattern;
-	uint32_t output1Period;
-	uint32_t output2Pattern;
-	uint32_t output2Period;
-	uint32_t vfeFrameSkipCount;
-	uint32_t vfeFrameSkipPeriod;
-	uint32_t status_bits;
-	struct vfe_stats_control afStatsControl;
-	struct vfe_stats_control awbStatsControl;
-	struct vfe_stats_control aecStatsControl;
-	struct vfe_stats_control ihistStatsControl;
-	struct vfe_stats_control rsStatsControl;
-	struct vfe_stats_control csStatsControl;
-	struct msm_camera_sensor_info *s_info;
-	struct vfe_message vMsgHold_Snap;
-	struct vfe_message vMsgHold_Thumb;
-	int8_t xbar_update_pending;
-	uint32_t xbar_cfg[2];
-	spinlock_t xbar_lock;
-	uint32_t while_stopping_mask;
-};
-
-#define statsAeNum      0
-#define statsAfNum      1
-#define statsAwbNum     2
-#define statsRsNum      3
-#define statsCsNum      4
-#define statsIhistNum   5
-#define statsSkinNum    6
-
-struct vfe_cmd_stats_ack{
-  uint32_t  nextStatsBuf;
-};
-
-#define VFE_STATS_BUFFER_COUNT            3
-
-struct vfe_cmd_stats_buf{
-   uint32_t statsBuf[VFE_STATS_BUFFER_COUNT];
-};
-#endif /* __MSM_VFE31_H__ */
diff --git a/drivers/media/video/msm/vfe/msm_vfe31_v4l2.c b/drivers/media/video/msm/vfe/msm_vfe31_v4l2.c
deleted file mode 100644
index de32f1b..0000000
--- a/drivers/media/video/msm/vfe/msm_vfe31_v4l2.c
+++ /dev/null
@@ -1,4241 +0,0 @@
-/* Copyright (c) 2012 Code Aurora Forum. 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/uaccess.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/atomic.h>
-#include <linux/regulator/consumer.h>
-#include <linux/clk.h>
-#include <linux/module.h>
-#include <mach/clk.h>
-#include <mach/irqs.h>
-#include <mach/camera.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-#include <media/msm_isp.h>
-
-#include "msm.h"
-#include "msm_vfe31_v4l2.h"
-
-atomic_t irq_cnt;
-
-#define BUFF_SIZE_128 128
-
-#define VFE31_AXI_OFFSET 0x0050
-#define vfe31_get_ch_ping_addr(chn) \
-	(msm_camera_io_r(vfe31_ctrl->vfebase + 0x0050 + 0x18 * (chn)))
-#define vfe31_get_ch_pong_addr(chn) \
-	(msm_camera_io_r(vfe31_ctrl->vfebase + 0x0050 + 0x18 * (chn) + 4))
-#define vfe31_get_ch_addr(ping_pong, chn) \
-	(((ping_pong) & (1 << (chn))) == 0 ? \
-	vfe31_get_ch_pong_addr(chn) : vfe31_get_ch_ping_addr(chn))
-
-#define vfe31_put_ch_ping_addr(chn, addr) \
-	(msm_camera_io_w((addr), vfe31_ctrl->vfebase + 0x0050 + 0x18 * (chn)))
-#define vfe31_put_ch_pong_addr(chn, addr) \
-	(msm_camera_io_w((addr), \
-	vfe31_ctrl->vfebase + 0x0050 + 0x18 * (chn) + 4))
-#define vfe31_put_ch_addr(ping_pong, chn, addr) \
-	(((ping_pong) & (1 << (chn))) == 0 ?   \
-	vfe31_put_ch_pong_addr((chn), (addr)) : \
-	vfe31_put_ch_ping_addr((chn), (addr)))
-
-#define VFE_CLK_RATE	153600000
-#define CAMIF_CFG_RMSK             0x1fffff
-
-static struct vfe31_ctrl_type *vfe31_ctrl;
-static uint32_t vfe_clk_rate;
-
-struct vfe31_isr_queue_cmd {
-	struct list_head	list;
-	uint32_t		vfeInterruptStatus0;
-	uint32_t		vfeInterruptStatus1;
-};
-
-static struct vfe31_cmd_type vfe31_cmd[] = {
-/* 0*/	{VFE_CMD_DUMMY_0},
-		{VFE_CMD_SET_CLK},
-		{VFE_CMD_RESET},
-		{VFE_CMD_START},
-		{VFE_CMD_TEST_GEN_START},
-/* 5*/	{VFE_CMD_OPERATION_CFG, V31_OPERATION_CFG_LEN},
-		{VFE_CMD_AXI_OUT_CFG, V31_AXI_OUT_LEN, V31_AXI_OUT_OFF, 0xFF},
-		{VFE_CMD_CAMIF_CFG, V31_CAMIF_LEN, V31_CAMIF_OFF, 0xFF},
-		{VFE_CMD_AXI_INPUT_CFG},
-		{VFE_CMD_BLACK_LEVEL_CFG, V31_BLACK_LEVEL_LEN,
-		V31_BLACK_LEVEL_OFF,
-		0xFF},
-/*10*/  {VFE_CMD_MESH_ROLL_OFF_CFG, V31_MESH_ROLL_OFF_CFG_LEN,
-		V31_MESH_ROLL_OFF_CFG_OFF, 0xFF},
-		{VFE_CMD_DEMUX_CFG, V31_DEMUX_LEN, V31_DEMUX_OFF, 0xFF},
-		{VFE_CMD_FOV_CFG, V31_FOV_LEN, V31_FOV_OFF, 0xFF},
-		{VFE_CMD_MAIN_SCALER_CFG, V31_MAIN_SCALER_LEN,
-		V31_MAIN_SCALER_OFF, 0xFF},
-		{VFE_CMD_WB_CFG, V31_WB_LEN, V31_WB_OFF, 0xFF},
-/*15*/	{VFE_CMD_COLOR_COR_CFG, V31_COLOR_COR_LEN, V31_COLOR_COR_OFF, 0xFF},
-		{VFE_CMD_RGB_G_CFG, V31_RGB_G_LEN, V31_RGB_G_OFF, 0xFF},
-		{VFE_CMD_LA_CFG, V31_LA_LEN, V31_LA_OFF, 0xFF },
-		{VFE_CMD_CHROMA_EN_CFG, V31_CHROMA_EN_LEN, V31_CHROMA_EN_OFF,
-		0xFF},
-		{VFE_CMD_CHROMA_SUP_CFG, V31_CHROMA_SUP_LEN, V31_CHROMA_SUP_OFF,
-		0xFF},
-/*20*/	{VFE_CMD_MCE_CFG, V31_MCE_LEN, V31_MCE_OFF, 0xFF},
-		{VFE_CMD_SK_ENHAN_CFG, V31_SCE_LEN, V31_SCE_OFF, 0xFF},
-		{VFE_CMD_ASF_CFG, V31_ASF_LEN, V31_ASF_OFF, 0xFF},
-		{VFE_CMD_S2Y_CFG, V31_S2Y_LEN, V31_S2Y_OFF, 0xFF},
-		{VFE_CMD_S2CbCr_CFG, V31_S2CbCr_LEN, V31_S2CbCr_OFF, 0xFF},
-/*25*/	{VFE_CMD_CHROMA_SUBS_CFG, V31_CHROMA_SUBS_LEN, V31_CHROMA_SUBS_OFF,
-		0xFF},
-		{VFE_CMD_OUT_CLAMP_CFG, V31_OUT_CLAMP_LEN, V31_OUT_CLAMP_OFF,
-		0xFF},
-		{VFE_CMD_FRAME_SKIP_CFG, V31_FRAME_SKIP_LEN, V31_FRAME_SKIP_OFF,
-		0xFF},
-		{VFE_CMD_DUMMY_1},
-		{VFE_CMD_DUMMY_2},
-/*30*/	{VFE_CMD_DUMMY_3},
-		{VFE_CMD_UPDATE},
-		{VFE_CMD_BL_LVL_UPDATE, V31_BLACK_LEVEL_LEN,
-		V31_BLACK_LEVEL_OFF, 0xFF},
-		{VFE_CMD_DEMUX_UPDATE, V31_DEMUX_LEN, V31_DEMUX_OFF, 0xFF},
-		{VFE_CMD_FOV_UPDATE, V31_FOV_LEN, V31_FOV_OFF, 0xFF},
-/*35*/	{VFE_CMD_MAIN_SCALER_UPDATE, V31_MAIN_SCALER_LEN, V31_MAIN_SCALER_OFF,
-		0xFF},
-		{VFE_CMD_WB_UPDATE, V31_WB_LEN, V31_WB_OFF, 0xFF},
-		{VFE_CMD_COLOR_COR_UPDATE, V31_COLOR_COR_LEN, V31_COLOR_COR_OFF,
-		0xFF},
-		{VFE_CMD_RGB_G_UPDATE, V31_RGB_G_LEN, V31_CHROMA_EN_OFF, 0xFF},
-		{VFE_CMD_LA_UPDATE, V31_LA_LEN, V31_LA_OFF, 0xFF },
-/*40*/	{VFE_CMD_CHROMA_EN_UPDATE, V31_CHROMA_EN_LEN, V31_CHROMA_EN_OFF,
-		0xFF},
-		{VFE_CMD_CHROMA_SUP_UPDATE, V31_CHROMA_SUP_LEN,
-		V31_CHROMA_SUP_OFF, 0xFF},
-		{VFE_CMD_MCE_UPDATE, V31_MCE_LEN, V31_MCE_OFF, 0xFF},
-		{VFE_CMD_SK_ENHAN_UPDATE, V31_SCE_LEN, V31_SCE_OFF, 0xFF},
-		{VFE_CMD_S2CbCr_UPDATE, V31_S2CbCr_LEN, V31_S2CbCr_OFF, 0xFF},
-/*45*/	{VFE_CMD_S2Y_UPDATE, V31_S2Y_LEN, V31_S2Y_OFF, 0xFF},
-		{VFE_CMD_ASF_UPDATE, V31_ASF_UPDATE_LEN, V31_ASF_OFF, 0xFF},
-		{VFE_CMD_FRAME_SKIP_UPDATE},
-		{VFE_CMD_CAMIF_FRAME_UPDATE},
-		{VFE_CMD_STATS_AF_UPDATE, V31_STATS_AF_LEN, V31_STATS_AF_OFF},
-/*50*/	{VFE_CMD_STATS_AE_UPDATE, V31_STATS_AE_LEN, V31_STATS_AE_OFF},
-		{VFE_CMD_STATS_AWB_UPDATE, V31_STATS_AWB_LEN,
-		V31_STATS_AWB_OFF},
-		{VFE_CMD_STATS_RS_UPDATE, V31_STATS_RS_LEN, V31_STATS_RS_OFF},
-		{VFE_CMD_STATS_CS_UPDATE, V31_STATS_CS_LEN, V31_STATS_CS_OFF},
-		{VFE_CMD_STATS_SKIN_UPDATE},
-/*55*/	{VFE_CMD_STATS_IHIST_UPDATE, V31_STATS_IHIST_LEN, V31_STATS_IHIST_OFF},
-		{VFE_CMD_DUMMY_4},
-		{VFE_CMD_EPOCH1_ACK},
-		{VFE_CMD_EPOCH2_ACK},
-		{VFE_CMD_START_RECORDING},
-/*60*/	{VFE_CMD_STOP_RECORDING},
-		{VFE_CMD_DUMMY_5},
-		{VFE_CMD_DUMMY_6},
-		{VFE_CMD_CAPTURE, V31_CAPTURE_LEN, 0xFF},
-		{VFE_CMD_DUMMY_7},
-/*65*/	{VFE_CMD_STOP},
-		{VFE_CMD_GET_HW_VERSION, V31_GET_HW_VERSION_LEN,
-		V31_GET_HW_VERSION_OFF},
-		{VFE_CMD_GET_FRAME_SKIP_COUNTS},
-		{VFE_CMD_OUTPUT1_BUFFER_ENQ},
-		{VFE_CMD_OUTPUT2_BUFFER_ENQ},
-/*70*/	{VFE_CMD_OUTPUT3_BUFFER_ENQ},
-		{VFE_CMD_JPEG_OUT_BUF_ENQ},
-		{VFE_CMD_RAW_OUT_BUF_ENQ},
-		{VFE_CMD_RAW_IN_BUF_ENQ},
-		{VFE_CMD_STATS_AF_ENQ},
-/*75*/	{VFE_CMD_STATS_AE_ENQ},
-		{VFE_CMD_STATS_AWB_ENQ},
-		{VFE_CMD_STATS_RS_ENQ},
-		{VFE_CMD_STATS_CS_ENQ},
-		{VFE_CMD_STATS_SKIN_ENQ},
-/*80*/	{VFE_CMD_STATS_IHIST_ENQ},
-		{VFE_CMD_DUMMY_8},
-		{VFE_CMD_JPEG_ENC_CFG},
-		{VFE_CMD_DUMMY_9},
-		{VFE_CMD_STATS_AF_START, V31_STATS_AF_LEN, V31_STATS_AF_OFF},
-/*85*/	{VFE_CMD_STATS_AF_STOP},
-		{VFE_CMD_STATS_AE_START, V31_STATS_AE_LEN, V31_STATS_AE_OFF},
-		{VFE_CMD_STATS_AE_STOP},
-		{VFE_CMD_STATS_AWB_START, V31_STATS_AWB_LEN, V31_STATS_AWB_OFF},
-		{VFE_CMD_STATS_AWB_STOP},
-/*90*/	{VFE_CMD_STATS_RS_START, V31_STATS_RS_LEN, V31_STATS_RS_OFF},
-		{VFE_CMD_STATS_RS_STOP},
-		{VFE_CMD_STATS_CS_START, V31_STATS_CS_LEN, V31_STATS_CS_OFF},
-		{VFE_CMD_STATS_CS_STOP},
-		{VFE_CMD_STATS_SKIN_START},
-/*95*/	{VFE_CMD_STATS_SKIN_STOP},
-		{VFE_CMD_STATS_IHIST_START,
-		V31_STATS_IHIST_LEN, V31_STATS_IHIST_OFF},
-		{VFE_CMD_STATS_IHIST_STOP},
-		{VFE_CMD_DUMMY_10},
-		{VFE_CMD_SYNC_TIMER_SETTING, V31_SYNC_TIMER_LEN,
-			V31_SYNC_TIMER_OFF},
-/*100*/	{VFE_CMD_ASYNC_TIMER_SETTING, V31_ASYNC_TIMER_LEN, V31_ASYNC_TIMER_OFF},
-		{VFE_CMD_LIVESHOT},
-		{VFE_CMD_LA_SETUP},
-		{VFE_CMD_LINEARIZATION_CFG},
-		{VFE_CMD_DEMOSAICV3},
-/*105*/	{VFE_CMD_DEMOSAICV3_ABCC_CFG},
-	{VFE_CMD_DEMOSAICV3_DBCC_CFG},
-		{VFE_CMD_DEMOSAICV3_DBPC_CFG, V31_DEMOSAICV3_DBPC_LEN,
-			V31_DEMOSAICV3_DBPC_CFG_OFF},
-		{VFE_CMD_DEMOSAICV3_ABF_CFG, V31_DEMOSAICV3_ABF_LEN,
-			V31_DEMOSAICV3_ABF_OFF},
-		{VFE_CMD_DEMOSAICV3_ABCC_UPDATE},
-/*110*/	{VFE_CMD_DEMOSAICV3_DBCC_UPDATE},
-		{VFE_CMD_DEMOSAICV3_DBPC_UPDATE, V31_DEMOSAICV3_DBPC_LEN,
-			V31_DEMOSAICV3_DBPC_CFG_OFF},
-		{VFE_CMD_XBAR_CFG},
-		{VFE_CMD_MODULE_CFG, V31_MODULE_CFG_LEN, V31_MODULE_CFG_OFF},
-		{VFE_CMD_ZSL},
-/*115*/	{VFE_CMD_LINEARIZATION_UPDATE},
-		{VFE_CMD_DEMOSAICV3_ABF_UPDATE, V31_DEMOSAICV3_ABF_LEN,
-			V31_DEMOSAICV3_ABF_OFF},
-		{VFE_CMD_CLF_CFG},
-		{VFE_CMD_CLF_LUMA_UPDATE},
-		{VFE_CMD_CLF_CHROMA_UPDATE},
-/*120*/ {VFE_CMD_PCA_ROLL_OFF_CFG},
-		{VFE_CMD_PCA_ROLL_OFF_UPDATE},
-		{VFE_CMD_GET_REG_DUMP},
-		{VFE_CMD_GET_LINEARIZATON_TABLE},
-		{VFE_CMD_GET_MESH_ROLLOFF_TABLE},
-/*125*/ {VFE_CMD_GET_PCA_ROLLOFF_TABLE},
-		{VFE_CMD_GET_RGB_G_TABLE},
-		{VFE_CMD_GET_LA_TABLE},
-		{VFE_CMD_DEMOSAICV3_UPDATE},
-};
-
-uint32_t vfe31_AXI_WM_CFG[] = {
-	0x0000004C,
-	0x00000064,
-	0x0000007C,
-	0x00000094,
-	0x000000AC,
-	0x000000C4,
-	0x000000DC,
-};
-
-static const char * const vfe31_general_cmd[] = {
-	"DUMMY_0",  /* 0 */
-	"SET_CLK",
-	"RESET",
-	"START",
-	"TEST_GEN_START",
-	"OPERATION_CFG",  /* 5 */
-	"AXI_OUT_CFG",
-	"CAMIF_CFG",
-	"AXI_INPUT_CFG",
-	"BLACK_LEVEL_CFG",
-	"ROLL_OFF_CFG",  /* 10 */
-	"DEMUX_CFG",
-	"FOV_CFG",
-	"MAIN_SCALER_CFG",
-	"WB_CFG",
-	"COLOR_COR_CFG", /* 15 */
-	"RGB_G_CFG",
-	"LA_CFG",
-	"CHROMA_EN_CFG",
-	"CHROMA_SUP_CFG",
-	"MCE_CFG", /* 20 */
-	"SK_ENHAN_CFG",
-	"ASF_CFG",
-	"S2Y_CFG",
-	"S2CbCr_CFG",
-	"CHROMA_SUBS_CFG",  /* 25 */
-	"OUT_CLAMP_CFG",
-	"FRAME_SKIP_CFG",
-	"DUMMY_1",
-	"DUMMY_2",
-	"DUMMY_3",  /* 30 */
-	"UPDATE",
-	"BL_LVL_UPDATE",
-	"DEMUX_UPDATE",
-	"FOV_UPDATE",
-	"MAIN_SCALER_UPDATE",  /* 35 */
-	"WB_UPDATE",
-	"COLOR_COR_UPDATE",
-	"RGB_G_UPDATE",
-	"LA_UPDATE",
-	"CHROMA_EN_UPDATE",  /* 40 */
-	"CHROMA_SUP_UPDATE",
-	"MCE_UPDATE",
-	"SK_ENHAN_UPDATE",
-	"S2CbCr_UPDATE",
-	"S2Y_UPDATE",  /* 45 */
-	"ASF_UPDATE",
-	"FRAME_SKIP_UPDATE",
-	"CAMIF_FRAME_UPDATE",
-	"STATS_AF_UPDATE",
-	"STATS_AE_UPDATE",  /* 50 */
-	"STATS_AWB_UPDATE",
-	"STATS_RS_UPDATE",
-	"STATS_CS_UPDATE",
-	"STATS_SKIN_UPDATE",
-	"STATS_IHIST_UPDATE",  /* 55 */
-	"DUMMY_4",
-	"EPOCH1_ACK",
-	"EPOCH2_ACK",
-	"START_RECORDING",
-	"STOP_RECORDING",  /* 60 */
-	"DUMMY_5",
-	"DUMMY_6",
-	"CAPTURE",
-	"DUMMY_7",
-	"STOP",  /* 65 */
-	"GET_HW_VERSION",
-	"GET_FRAME_SKIP_COUNTS",
-	"OUTPUT1_BUFFER_ENQ",
-	"OUTPUT2_BUFFER_ENQ",
-	"OUTPUT3_BUFFER_ENQ",  /* 70 */
-	"JPEG_OUT_BUF_ENQ",
-	"RAW_OUT_BUF_ENQ",
-	"RAW_IN_BUF_ENQ",
-	"STATS_AF_ENQ",
-	"STATS_AE_ENQ",  /* 75 */
-	"STATS_AWB_ENQ",
-	"STATS_RS_ENQ",
-	"STATS_CS_ENQ",
-	"STATS_SKIN_ENQ",
-	"STATS_IHIST_ENQ",  /* 80 */
-	"DUMMY_8",
-	"JPEG_ENC_CFG",
-	"DUMMY_9",
-	"STATS_AF_START",
-	"STATS_AF_STOP",  /* 85 */
-	"STATS_AE_START",
-	"STATS_AE_STOP",
-	"STATS_AWB_START",
-	"STATS_AWB_STOP",
-	"STATS_RS_START",  /* 90 */
-	"STATS_RS_STOP",
-	"STATS_CS_START",
-	"STATS_CS_STOP",
-	"STATS_SKIN_START",
-	"STATS_SKIN_STOP",  /* 95 */
-	"STATS_IHIST_START",
-	"STATS_IHIST_STOP",
-	"DUMMY_10",
-	"SYNC_TIMER_SETTING",
-	"ASYNC_TIMER_SETTING",  /* 100 */
-	"LIVESHOT",
-	"LA_SETUP",
-	"LINEARIZATION_CFG",
-	"DEMOSAICV3",
-	"DEMOSAICV3_ABCC_CFG", /* 105 */
-	"DEMOSAICV3_DBCC_CFG",
-	"DEMOSAICV3_DBPC_CFG",
-	"DEMOSAICV3_ABF_CFG",
-	"DEMOSAICV3_ABCC_UPDATE",
-	"DEMOSAICV3_DBCC_UPDATE", /* 110 */
-	"DEMOSAICV3_DBPC_UPDATE",
-	"XBAR_CFG",
-	"EZTUNE_CFG",
-	"V31_ZSL",
-	"LINEARIZATION_UPDATE", /*115*/
-	"DEMOSAICV3_ABF_UPDATE",
-	"CLF_CFG",
-	"CLF_LUMA_UPDATE",
-	"CLF_CHROMA_UPDATE",
-	"PCA_ROLL_OFF_CFG", /*120*/
-	"PCA_ROLL_OFF_UPDATE",
-	"GET_REG_DUMP",
-	"GET_LINEARIZATON_TABLE",
-	"GET_MESH_ROLLOFF_TABLE",
-	"GET_PCA_ROLLOFF_TABLE", /*125*/
-	"GET_RGB_G_TABLE",
-	"GET_LA_TABLE",
-	"DEMOSAICV3_UPDATE",
-};
-
-
-static unsigned long vfe31_stats_dqbuf(enum msm_stats_enum_type stats_type)
-{
-	struct msm_stats_meta_buf *buf = NULL;
-	int rc = 0;
-	rc = vfe31_ctrl->stats_ops.dqbuf(vfe31_ctrl->stats_ops.stats_ctrl,
-			stats_type, &buf);
-	if (rc < 0) {
-		CDBG("%s: dq stats buf (type = %d) err = %d",
-			__func__, stats_type, rc);
-		return 0L;
-	}
-	return buf->paddr;
-}
-
-static unsigned long vfe31_stats_flush_enqueue(
-	enum msm_stats_enum_type stats_type)
-{
-	struct msm_stats_bufq *bufq = NULL;
-	struct msm_stats_meta_buf *stats_buf = NULL;
-	int rc = 0;
-	int i;
-	/*
-	 * Passing NULL for ion client as the buffers are already
-	 * mapped at this stage, client is not required, flush all
-	 * the buffers, and buffers move to PREPARE state
-	 */
-
-	rc = vfe31_ctrl->stats_ops.bufq_flush(
-			vfe31_ctrl->stats_ops.stats_ctrl, stats_type, NULL);
-	if (rc < 0) {
-		pr_err("%s: dq stats buf (type = %d) err = %d",
-			__func__, stats_type, rc);
-		return 0L;
-	}
-
-	/* Queue all the buffers back to QUEUED state */
-	bufq = vfe31_ctrl->stats_ctrl.bufq[stats_type];
-	for (i = 0; i < bufq->num_bufs; i++) {
-		stats_buf = &bufq->bufs[i];
-		rc = vfe31_ctrl->stats_ops.enqueue_buf(
-				vfe31_ctrl->stats_ops.stats_ctrl,
-				&(stats_buf->info), NULL, -1);
-		if (rc < 0) {
-			pr_err("%s: dq stats buf (type = %d) err = %d",
-				__func__, stats_type, rc);
-			return rc;
-		}
-	}
-	return 0L;
-}
-
-static unsigned long vfe31_stats_unregbuf(
-	struct msm_stats_reqbuf *req_buf, int domain_num)
-{
-	int i = 0, rc = 0;
-
-	for (i = 0; i < req_buf->num_buf; i++) {
-		rc = vfe31_ctrl->stats_ops.buf_unprepare(
-			vfe31_ctrl->stats_ops.stats_ctrl,
-			req_buf->stats_type, i,
-			vfe31_ctrl->stats_ops.client, domain_num);
-		if (rc < 0) {
-			pr_err("%s: unreg stats buf (type = %d) err = %d",
-				__func__, req_buf->stats_type, rc);
-		return rc;
-		}
-	}
-	return 0L;
-}
-
-static int vfe_stats_awb_buf_init(
-	struct vfe_cmd_stats_buf *in)
-{
-	uint32_t addr;
-	unsigned long flags;
-
-	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_AWB);
-	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq awb ping buf from free buf queue", __func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR);
-	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_AWB);
-	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq awb ping buf from free buf queue", __func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR);
-	return 0;
-}
-
-static int vfe_stats_aec_buf_init(
-	struct vfe_cmd_stats_buf *in)
-{
-	uint32_t addr;
-	unsigned long flags;
-
-	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_AEC);
-	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq aec ping buf from free buf queue",
-			__func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe31_ctrl->vfebase +
-		VFE_BUS_STATS_AEC_WR_PING_ADDR);
-	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_AEC);
-	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq aec pong buf from free buf queue",
-			__func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe31_ctrl->vfebase +
-		VFE_BUS_STATS_AEC_WR_PONG_ADDR);
-	return 0;
-}
-
-static int vfe_stats_af_buf_init(
-	struct vfe_cmd_stats_buf *in)
-{
-	uint32_t addr;
-	unsigned long flags;
-	int rc = 0;
-
-	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
-	rc = vfe31_stats_flush_enqueue(MSM_STATS_TYPE_AF);
-	if (rc < 0) {
-		pr_err("%s: dq stats buf err = %d",
-			__func__, rc);
-		spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
-		return -EINVAL;
-	}
-	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_AF);
-	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq af ping buf from free buf queue", __func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR);
-	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_AF);
-	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq af pong buf from free buf queue", __func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR);
-	return 0;
-}
-
-static int vfe_stats_ihist_buf_init(
-	struct vfe_cmd_stats_buf *in)
-{
-	uint32_t addr;
-	unsigned long flags;
-	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_IHIST);
-	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq ihist ping buf from free buf queue",
-			__func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_HIST_WR_PING_ADDR);
-	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_IHIST);
-	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq ihist pong buf from free buf queue", __func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_HIST_WR_PONG_ADDR);
-	return 0;
-}
-
-static int vfe_stats_rs_buf_init(struct vfe_cmd_stats_buf *in)
-{
-	uint32_t addr;
-	unsigned long flags;
-	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_RS);
-	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq rs ping buf from free buf queue", __func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_RS_WR_PING_ADDR);
-	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_RS);
-	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq rs pong buf from free buf queue", __func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_RS_WR_PONG_ADDR);
-	return 0;
-}
-
-static int vfe_stats_cs_buf_init(struct vfe_cmd_stats_buf *in)
-{
-	uint32_t addr;
-	unsigned long flags;
-
-	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_CS);
-	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq cs ping buf from free buf queue", __func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_CS_WR_PING_ADDR);
-	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_CS);
-	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq cs pong buf from free buf queue", __func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_CS_WR_PONG_ADDR);
-	return 0;
-}
-
-static void vfe31_stop(void)
-{
-	uint8_t  axiBusyFlag = true;
-	unsigned long flags;
-
-	atomic_set(&vfe31_ctrl->vstate, 0);
-
-	/* for reset hw modules, and send msg when reset_irq comes.*/
-	spin_lock_irqsave(&vfe31_ctrl->stop_flag_lock, flags);
-	vfe31_ctrl->stop_ack_pending = TRUE;
-	spin_unlock_irqrestore(&vfe31_ctrl->stop_flag_lock, flags);
-
-	/* disable all interrupts.  */
-	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
-		vfe31_ctrl->vfebase + VFE_IRQ_MASK_0);
-	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
-		vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
-
-	/* clear all pending interrupts*/
-	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
-		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_0);
-	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
-		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_1);
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	msm_camera_io_w_mb(1,
-		vfe31_ctrl->vfebase + VFE_IRQ_CMD);
-
-	/* in either continuous or snapshot mode, stop command can be issued
-	 * at any time. stop camif immediately. */
-	msm_camera_io_w_mb(CAMIF_COMMAND_STOP_IMMEDIATELY,
-		vfe31_ctrl->vfebase + VFE_CAMIF_COMMAND);
-	/* axi halt command. */
-	msm_camera_io_w(AXI_HALT,
-		vfe31_ctrl->vfebase + VFE_AXI_CMD);
-	wmb();
-	while (axiBusyFlag) {
-		if (msm_camera_io_r(vfe31_ctrl->vfebase + VFE_AXI_STATUS) & 0x1)
-			axiBusyFlag = false;
-	}
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	msm_camera_io_w_mb(AXI_HALT_CLEAR,
-		vfe31_ctrl->vfebase + VFE_AXI_CMD);
-
-	/* now enable only halt_irq & reset_irq */
-	msm_camera_io_w(0xf0000000,          /* this is for async timer. */
-		vfe31_ctrl->vfebase + VFE_IRQ_MASK_0);
-	msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_1,
-		vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
-
-	msm_camera_io_w_mb(VFE_RESET_UPON_STOP_CMD,
-		vfe31_ctrl->vfebase + VFE_GLOBAL_RESET);
-}
-
-static void vfe31_subdev_notify(int id, int path, uint32_t inst_handle)
-{
-	struct msm_vfe_resp rp;
-	struct msm_frame_info frame_info;
-	unsigned long flags;
-	spin_lock_irqsave(&vfe31_ctrl->sd_notify_lock, flags);
-	memset(&rp, 0, sizeof(struct msm_vfe_resp));
-	CDBG("vfe31_subdev_notify : msgId = %d\n", id);
-	rp.evt_msg.type   = MSM_CAMERA_MSG;
-	frame_info.inst_handle = inst_handle;
-	frame_info.path = path;
-	rp.evt_msg.data = &frame_info;
-	rp.type	   = id;
-	v4l2_subdev_notify(&vfe31_ctrl->subdev, NOTIFY_VFE_BUF_EVT, &rp);
-	spin_unlock_irqrestore(&vfe31_ctrl->sd_notify_lock, flags);
-}
-
-static int vfe31_config_axi(int mode, uint32_t *ao)
-{
-	uint32_t *ch_info;
-	uint32_t *axi_cfg = ao + V31_AXI_RESERVED;
-	uint32_t bus_cmd = *axi_cfg;
-	int i;
-
-	/* Update the corresponding write masters for each output*/
-	ch_info = axi_cfg + V31_AXI_CFG_LEN;
-	vfe31_ctrl->outpath.out0.ch0 = 0x0000FFFF & *ch_info;
-	vfe31_ctrl->outpath.out0.ch1 = 0x0000FFFF & (*ch_info++ >> 16);
-	vfe31_ctrl->outpath.out0.ch2 = 0x0000FFFF & *ch_info++;
-	vfe31_ctrl->outpath.out0.inst_handle = *ch_info++;
-	vfe31_ctrl->outpath.out1.ch0 = 0x0000FFFF & *ch_info;
-	vfe31_ctrl->outpath.out1.ch1 = 0x0000FFFF & (*ch_info++ >> 16);
-	vfe31_ctrl->outpath.out1.ch2 = 0x0000FFFF & *ch_info++;
-	vfe31_ctrl->outpath.out1.inst_handle = *ch_info++;
-	vfe31_ctrl->outpath.out2.ch0 = 0x0000FFFF & *ch_info;
-	vfe31_ctrl->outpath.out2.ch1 = 0x0000FFFF & (*ch_info++ >> 16);
-	vfe31_ctrl->outpath.out2.ch2 = 0x0000FFFF & *ch_info++;
-	vfe31_ctrl->outpath.out2.inst_handle = *ch_info++;
-
-	switch (mode) {
-	case OUTPUT_PRIM:
-		vfe31_ctrl->outpath.output_mode =
-			VFE31_OUTPUT_MODE_PRIMARY;
-		break;
-	case OUTPUT_PRIM_ALL_CHNLS:
-		vfe31_ctrl->outpath.output_mode =
-			VFE31_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
-		break;
-	case OUTPUT_PRIM|OUTPUT_SEC:
-		vfe31_ctrl->outpath.output_mode =
-			VFE31_OUTPUT_MODE_PRIMARY;
-		vfe31_ctrl->outpath.output_mode |=
-			VFE31_OUTPUT_MODE_SECONDARY;
-		break;
-	case OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS:
-		vfe31_ctrl->outpath.output_mode =
-			VFE31_OUTPUT_MODE_PRIMARY;
-		vfe31_ctrl->outpath.output_mode |=
-			VFE31_OUTPUT_MODE_SECONDARY_ALL_CHNLS;
-		break;
-	case OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC:
-		vfe31_ctrl->outpath.output_mode =
-			VFE31_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
-		vfe31_ctrl->outpath.output_mode |=
-			VFE31_OUTPUT_MODE_SECONDARY;
-		break;
-	default:
-		pr_err("%s Invalid AXI mode %d ", __func__, mode);
-		return -EINVAL;
-	}
-
-	axi_cfg++;
-	msm_camera_io_memcpy(vfe31_ctrl->vfebase +
-		vfe31_cmd[VFE_CMD_AXI_OUT_CFG].offset, axi_cfg,
-		V31_AXI_BUS_CFG_LEN);
-	axi_cfg += V31_AXI_BUS_CFG_LEN/4;
-	for (i = 0; i < ARRAY_SIZE(vfe31_AXI_WM_CFG); i++) {
-		msm_camera_io_w(*axi_cfg,
-		vfe31_ctrl->vfebase+vfe31_AXI_WM_CFG[i]);
-		axi_cfg += 3;
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase+vfe31_AXI_WM_CFG[i]+12,
-							axi_cfg, 12);
-		axi_cfg += 3;
-	}
-	msm_camera_io_w(bus_cmd, vfe31_ctrl->vfebase +
-					V31_AXI_BUS_CMD_OFF);
-
-	return 0;
-}
-
-static void vfe31_reset_internal_variables(void)
-{
-	unsigned long flags;
-	vfe31_ctrl->vfeImaskCompositePacked = 0;
-	/* state control variables */
-	vfe31_ctrl->start_ack_pending = FALSE;
-	atomic_set(&irq_cnt, 0);
-
-	spin_lock_irqsave(&vfe31_ctrl->stop_flag_lock, flags);
-	vfe31_ctrl->stop_ack_pending  = FALSE;
-	spin_unlock_irqrestore(&vfe31_ctrl->stop_flag_lock, flags);
-
-	vfe31_ctrl->reset_ack_pending  = FALSE;
-
-	spin_lock_irqsave(&vfe31_ctrl->update_ack_lock, flags);
-	vfe31_ctrl->update_ack_pending = FALSE;
-	spin_unlock_irqrestore(&vfe31_ctrl->update_ack_lock, flags);
-
-	vfe31_ctrl->recording_state = VFE_STATE_IDLE;
-	vfe31_ctrl->liveshot_state = VFE_STATE_IDLE;
-
-	atomic_set(&vfe31_ctrl->vstate, 0);
-
-	/* 0 for continuous mode, 1 for snapshot mode */
-	vfe31_ctrl->operation_mode = 0;
-	vfe31_ctrl->outpath.output_mode = 0;
-	vfe31_ctrl->vfe_capture_count = 0;
-
-	/* this is unsigned 32 bit integer. */
-	vfe31_ctrl->vfeFrameId = 0;
-	/* Stats control variables. */
-	memset(&(vfe31_ctrl->afStatsControl), 0,
-		sizeof(struct vfe_stats_control));
-
-	memset(&(vfe31_ctrl->awbStatsControl), 0,
-		sizeof(struct vfe_stats_control));
-
-	memset(&(vfe31_ctrl->aecStatsControl), 0,
-		sizeof(struct vfe_stats_control));
-
-	memset(&(vfe31_ctrl->ihistStatsControl), 0,
-		sizeof(struct vfe_stats_control));
-
-	memset(&(vfe31_ctrl->rsStatsControl), 0,
-		sizeof(struct vfe_stats_control));
-
-	memset(&(vfe31_ctrl->csStatsControl), 0,
-		sizeof(struct vfe_stats_control));
-
-	vfe31_ctrl->frame_skip_cnt = 31;
-	vfe31_ctrl->frame_skip_pattern = 0xffffffff;
-	vfe31_ctrl->snapshot_frame_cnt = 0;
-}
-
-static void vfe31_reset(void)
-{
-	vfe31_reset_internal_variables();
-	/* disable all interrupts.  vfeImaskLocal is also reset to 0
-	* to begin with. */
-	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
-		vfe31_ctrl->vfebase + VFE_IRQ_MASK_0);
-
-	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
-		vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
-
-	/* clear all pending interrupts*/
-	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
-		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_0);
-	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
-		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_1);
-
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_IRQ_CMD);
-
-	/* enable reset_ack interrupt.  */
-	msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_1,
-	vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
-
-	/* Write to VFE_GLOBAL_RESET_CMD to reset the vfe hardware. Once reset
-	 * is done, hardware interrupt will be generated.  VFE ist processes
-	 * the interrupt to complete the function call.  Note that the reset
-	 * function is synchronous. */
-
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	msm_camera_io_w_mb(VFE_RESET_UPON_RESET_CMD,
-		vfe31_ctrl->vfebase + VFE_GLOBAL_RESET);
-}
-
-static int vfe31_operation_config(uint32_t *cmd)
-{
-	uint32_t *p = cmd;
-
-	vfe31_ctrl->operation_mode = *p;
-	vfe31_ctrl->stats_comp = *(++p);
-	vfe31_ctrl->hfr_mode = *(++p);
-
-	msm_camera_io_w(*(++p), vfe31_ctrl->vfebase + VFE_CFG);
-	msm_camera_io_w(*(++p), vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-	msm_camera_io_w(*(++p), vfe31_ctrl->vfebase + VFE_REALIGN_BUF);
-	msm_camera_io_w(*(++p), vfe31_ctrl->vfebase + VFE_CHROMA_UP);
-	msm_camera_io_w(*(++p), vfe31_ctrl->vfebase + VFE_STATS_CFG);
-	return 0;
-}
-
-static void msm_camera_io_dump2(void __iomem *addr, int size)
-{
-	char line_str[BUFF_SIZE_128], *p_str;
-	int i;
-	u32 *p = (u32 *) addr;
-	u32 data;
-	CDBG("%s: %p %d\n", __func__, addr, size);
-	line_str[0] = '\0';
-	p_str = line_str;
-	for (i = 0; i < size/4; i++) {
-		if (i % 4 == 0) {
-			snprintf(p_str, 12, "%08x: ", (u32) p);
-			p_str += 10;
-		}
-		data = readl_relaxed(p++);
-		snprintf(p_str, 12, "%08x ", data);
-		p_str += 9;
-		if ((i + 1) % 4 == 0) {
-			CDBG("%s\n", line_str);
-			line_str[0] = '\0';
-			p_str = line_str;
-		}
-	}
-	if (line_str[0] != '\0')
-		CDBG("%s\n", line_str);
-}
-
-static void vfe31_start_common(void)
-{
-	uint32_t irq_mask = 0x00E00021;
-	vfe31_ctrl->start_ack_pending = TRUE;
-	CDBG("VFE opertaion mode = 0x%x, output mode = 0x%x\n",
-		vfe31_ctrl->operation_mode, vfe31_ctrl->outpath.output_mode);
-	if (vfe31_ctrl->stats_comp)
-		irq_mask |= VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK;
-	else
-		irq_mask |= 0x000FE000;
-
-	msm_camera_io_w(irq_mask, vfe31_ctrl->vfebase + VFE_IRQ_MASK_0);
-	msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_1,
-		vfe31_ctrl->vfebase + VFE_IRQ_MASK_1);
-
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_CAMIF_COMMAND);
-
-	msm_camera_io_dump2(vfe31_ctrl->vfebase, vfe31_ctrl->register_total*4);
-	atomic_set(&vfe31_ctrl->vstate, 1);
-}
-
-static int vfe31_start_recording(struct msm_cam_media_controller *pmctl)
-{
-	msm_camio_bus_scale_cfg(
-		pmctl->sdata->pdata->cam_bus_scale_table, S_VIDEO);
-	vfe31_ctrl->recording_state = VFE_STATE_START_REQUESTED;
-	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-	return 0;
-}
-
-static int vfe31_stop_recording(struct msm_cam_media_controller *pmctl)
-{
-	vfe31_ctrl->recording_state = VFE_STATE_STOP_REQUESTED;
-	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-	msm_camio_bus_scale_cfg(
-		pmctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
-	return 0;
-}
-
-static void vfe31_start_liveshot(struct msm_cam_media_controller *pmctl)
-{
-	/* Hardcode 1 live snapshot for now. */
-	vfe31_ctrl->outpath.out0.capture_cnt = 1;
-	vfe31_ctrl->vfe_capture_count = vfe31_ctrl->outpath.out0.capture_cnt;
-
-	vfe31_ctrl->liveshot_state = VFE_STATE_START_REQUESTED;
-	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-}
-
-static int vfe31_zsl(struct msm_cam_media_controller *pmctl)
-{
-	uint32_t irq_comp_mask = 0;
-	/* capture command is valid for both idle and active state. */
-	irq_comp_mask	=
-		msm_camera_io_r(vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
-
-	CDBG("%s:op mode %d O/P Mode %d\n", __func__,
-		vfe31_ctrl->operation_mode, vfe31_ctrl->outpath.output_mode);
-
-	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_PRIMARY) {
-		irq_comp_mask |= ((0x1 << (vfe31_ctrl->outpath.out0.ch0)) |
-			(0x1 << (vfe31_ctrl->outpath.out0.ch1)));
-	} else if (vfe31_ctrl->outpath.output_mode &
-		VFE31_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
-		irq_comp_mask |= ((0x1 << (vfe31_ctrl->outpath.out0.ch0)) |
-			(0x1 << (vfe31_ctrl->outpath.out0.ch1)) |
-			(0x1 << (vfe31_ctrl->outpath.out0.ch2)));
-	}
-
-	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_SECONDARY) {
-		irq_comp_mask |= ((0x1 << (vfe31_ctrl->outpath.out1.ch0 + 8)) |
-			(0x1 << (vfe31_ctrl->outpath.out1.ch1 + 8)));
-	} else if (vfe31_ctrl->outpath.output_mode &
-		VFE31_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
-		irq_comp_mask |= ((0x1 << (vfe31_ctrl->outpath.out1.ch0 + 8)) |
-			(0x1 << (vfe31_ctrl->outpath.out1.ch1 + 8)) |
-			(0x1 << (vfe31_ctrl->outpath.out1.ch2 + 8)));
-	}
-
-	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_PRIMARY) {
-		msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
-		msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
-	} else if (vfe31_ctrl->outpath.output_mode &
-		VFE31_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
-		msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
-		msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
-		msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch2]);
-	}
-
-	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_SECONDARY) {
-		msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
-		msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
-	} else if (vfe31_ctrl->outpath.output_mode &
-		VFE31_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
-		msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
-		msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
-		msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch2]);
-	}
-
-	msm_camera_io_w(irq_comp_mask, vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
-	vfe31_start_common();
-	msm_camio_bus_scale_cfg(
-		pmctl->sdata->pdata->cam_bus_scale_table, S_ZSL);
-
-	msm_camera_io_w(1, vfe31_ctrl->vfebase + 0x18C);
-	msm_camera_io_w(1, vfe31_ctrl->vfebase + 0x188);
-	return 0;
-}
-static int vfe31_capture_raw(
-	struct msm_cam_media_controller *pmctl,
-	uint32_t num_frames_capture)
-{
-	uint32_t irq_comp_mask = 0;
-
-	vfe31_ctrl->outpath.out0.capture_cnt = num_frames_capture;
-	vfe31_ctrl->vfe_capture_count = num_frames_capture;
-
-	irq_comp_mask =
-		msm_camera_io_r(vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
-
-	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_PRIMARY) {
-		irq_comp_mask |= (0x1 << (vfe31_ctrl->outpath.out0.ch0));
-		msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
-	}
-
-	msm_camera_io_w(irq_comp_mask, vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
-	msm_camio_bus_scale_cfg(
-		pmctl->sdata->pdata->cam_bus_scale_table, S_CAPTURE);
-	vfe31_start_common();
-	return 0;
-}
-
-static int vfe31_capture(
-	struct msm_cam_media_controller *pmctl,
-	uint32_t num_frames_capture)
-{
-	uint32_t irq_comp_mask = 0;
-	/* capture command is valid for both idle and active state. */
-	vfe31_ctrl->outpath.out1.capture_cnt = num_frames_capture;
-	if (vfe31_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB ||
-		vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN ||
-		vfe31_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB ||
-		vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG) {
-		vfe31_ctrl->outpath.out0.capture_cnt =
-			num_frames_capture;
-	}
-
-	vfe31_ctrl->vfe_capture_count = num_frames_capture;
-	irq_comp_mask = msm_camera_io_r(
-				vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
-
-	if (vfe31_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB ||
-		vfe31_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB ||
-		vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN) {
-		if (vfe31_ctrl->outpath.output_mode &
-			VFE31_OUTPUT_MODE_PRIMARY) {
-			irq_comp_mask |= (0x1 << vfe31_ctrl->outpath.out0.ch0 |
-				0x1 << vfe31_ctrl->outpath.out0.ch1);
-		}
-		if (vfe31_ctrl->outpath.output_mode &
-			VFE31_OUTPUT_MODE_SECONDARY) {
-			irq_comp_mask |=
-				(0x1 << (vfe31_ctrl->outpath.out1.ch0 + 8) |
-				0x1 << (vfe31_ctrl->outpath.out1.ch1 + 8));
-		}
-		if (vfe31_ctrl->outpath.output_mode &
-			VFE31_OUTPUT_MODE_PRIMARY) {
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
-		}
-		if (vfe31_ctrl->outpath.output_mode &
-			VFE31_OUTPUT_MODE_SECONDARY) {
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
-		}
-	}
-
-	vfe31_ctrl->vfe_capture_count = num_frames_capture;
-
-	msm_camera_io_w(irq_comp_mask, vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
-	msm_camera_io_r(vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
-	msm_camio_bus_scale_cfg(
-		pmctl->sdata->pdata->cam_bus_scale_table, S_CAPTURE);
-
-	vfe31_start_common();
-	/* for debug */
-	msm_camera_io_w(1, vfe31_ctrl->vfebase + 0x18C);
-	msm_camera_io_w(1, vfe31_ctrl->vfebase + 0x188);
-	return 0;
-}
-
-static int vfe31_start(struct msm_cam_media_controller *pmctl)
-{
-	uint32_t irq_comp_mask = 0;
-
-	irq_comp_mask	=
-		msm_camera_io_r(vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
-
-	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_PRIMARY) {
-		irq_comp_mask |= (0x1 << vfe31_ctrl->outpath.out0.ch0 |
-			0x1 << vfe31_ctrl->outpath.out0.ch1);
-	} else if (vfe31_ctrl->outpath.output_mode &
-		VFE31_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
-		irq_comp_mask |= (0x1 << vfe31_ctrl->outpath.out0.ch0 |
-			0x1 << vfe31_ctrl->outpath.out0.ch1 |
-			0x1 << vfe31_ctrl->outpath.out0.ch2);
-	}
-	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_SECONDARY) {
-		irq_comp_mask |= (0x1 << (vfe31_ctrl->outpath.out1.ch0 + 8) |
-			0x1 << (vfe31_ctrl->outpath.out1.ch1 + 8));
-	} else if (vfe31_ctrl->outpath.output_mode &
-		VFE31_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
-		irq_comp_mask |= (0x1 << (vfe31_ctrl->outpath.out1.ch0 + 8) |
-			0x1 << (vfe31_ctrl->outpath.out1.ch1 + 8) |
-			0x1 << (vfe31_ctrl->outpath.out1.ch2 + 8));
-	}
-	msm_camera_io_w(irq_comp_mask, vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
-
-	switch (vfe31_ctrl->operation_mode) {
-	case VFE_OUTPUTS_PREVIEW:
-	case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
-		if (vfe31_ctrl->outpath.output_mode &
-			VFE31_OUTPUT_MODE_PRIMARY) {
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
-		} else if (vfe31_ctrl->outpath.output_mode &
-			VFE31_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch2]);
-		}
-		break;
-	default:
-		if (vfe31_ctrl->outpath.output_mode &
-			VFE31_OUTPUT_MODE_SECONDARY) {
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
-		} else if (vfe31_ctrl->outpath.output_mode &
-			VFE31_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch2]);
-		}
-		break;
-	}
-	msm_camio_bus_scale_cfg(
-		pmctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
-	vfe31_start_common();
-	return 0;
-}
-
-static void vfe31_update(void)
-{
-	unsigned long flags;
-
-	if (vfe31_ctrl->update_la) {
-		if (!msm_camera_io_r(vfe31_ctrl->vfebase + V31_LA_OFF))
-			msm_camera_io_w(1, vfe31_ctrl->vfebase + V31_LA_OFF);
-		else
-			msm_camera_io_w(0, vfe31_ctrl->vfebase + V31_LA_OFF);
-		vfe31_ctrl->update_la = false;
-	}
-
-	if (vfe31_ctrl->update_gamma) {
-		if (!msm_camera_io_r(vfe31_ctrl->vfebase + V31_RGB_G_OFF))
-			msm_camera_io_w(7, vfe31_ctrl->vfebase+V31_RGB_G_OFF);
-		else
-			msm_camera_io_w(0, vfe31_ctrl->vfebase+V31_RGB_G_OFF);
-		vfe31_ctrl->update_gamma = false;
-	}
-
-	spin_lock_irqsave(&vfe31_ctrl->update_ack_lock, flags);
-	vfe31_ctrl->update_ack_pending = TRUE;
-	spin_unlock_irqrestore(&vfe31_ctrl->update_ack_lock, flags);
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-	return;
-}
-
-static void vfe31_sync_timer_stop(void)
-{
-	uint32_t value = 0;
-	vfe31_ctrl->sync_timer_state = 0;
-	if (vfe31_ctrl->sync_timer_number == 0)
-		value = 0x10000;
-	else if (vfe31_ctrl->sync_timer_number == 1)
-		value = 0x20000;
-	else if (vfe31_ctrl->sync_timer_number == 2)
-		value = 0x40000;
-
-	/* Timer Stop */
-	msm_camera_io_w(value, vfe31_ctrl->vfebase + V31_SYNC_TIMER_OFF);
-}
-
-static void vfe31_sync_timer_start(const uint32_t *tbl)
-{
-	/* set bit 8 for auto increment. */
-	uint32_t value = 1;
-	uint32_t val;
-
-	vfe31_ctrl->sync_timer_state = *tbl++;
-	vfe31_ctrl->sync_timer_repeat_count = *tbl++;
-	vfe31_ctrl->sync_timer_number = *tbl++;
-	CDBG("%s timer_state %d, repeat_cnt %d timer number %d\n",
-		 __func__, vfe31_ctrl->sync_timer_state,
-		 vfe31_ctrl->sync_timer_repeat_count,
-		 vfe31_ctrl->sync_timer_number);
-
-	if (vfe31_ctrl->sync_timer_state) { /* Start Timer */
-		value = value << vfe31_ctrl->sync_timer_number;
-	} else { /* Stop Timer */
-		CDBG("Failed to Start timer\n");
-		return;
-	}
-
-	/* Timer Start */
-	msm_camera_io_w(value, vfe31_ctrl->vfebase + V31_SYNC_TIMER_OFF);
-	/* Sync Timer Line Start */
-	value = *tbl++;
-	msm_camera_io_w(value, vfe31_ctrl->vfebase + V31_SYNC_TIMER_OFF +
-		4 + ((vfe31_ctrl->sync_timer_number) * 12));
-	/* Sync Timer Pixel Start */
-	value = *tbl++;
-	msm_camera_io_w(value, vfe31_ctrl->vfebase + V31_SYNC_TIMER_OFF +
-		 8 + ((vfe31_ctrl->sync_timer_number) * 12));
-	/* Sync Timer Pixel Duration */
-	value = *tbl++;
-	val = vfe_clk_rate / 10000;
-	val = 10000000 / val;
-	val = value * 10000 / val;
-	CDBG("%s: Pixel Clk Cycles!!! %d\n", __func__, val);
-	msm_camera_io_w(val, vfe31_ctrl->vfebase + V31_SYNC_TIMER_OFF +
-		12 + ((vfe31_ctrl->sync_timer_number) * 12));
-	/* Timer0 Active High/LOW */
-	value = *tbl++;
-	msm_camera_io_w(value,
-		vfe31_ctrl->vfebase + V31_SYNC_TIMER_POLARITY_OFF);
-	/* Selects sync timer 0 output to drive onto timer1 port */
-	value = 0;
-	msm_camera_io_w(value, vfe31_ctrl->vfebase + V31_TIMER_SELECT_OFF);
-}
-
-static void vfe31_program_dmi_cfg(enum VFE31_DMI_RAM_SEL bankSel)
-{
-	/* set bit 8 for auto increment. */
-	uint32_t value = VFE_DMI_CFG_DEFAULT;
-	value += (uint32_t)bankSel;
-	CDBG("%s: banksel = %d\n", __func__, bankSel);
-
-	msm_camera_io_w(value, vfe31_ctrl->vfebase + VFE_DMI_CFG);
-	/* by default, always starts with offset 0.*/
-	msm_camera_io_w(0, vfe31_ctrl->vfebase + VFE_DMI_ADDR);
-}
-static void vfe31_write_gamma_cfg(enum VFE31_DMI_RAM_SEL channel_sel,
-						const uint32_t *tbl)
-{
-	int i;
-	uint32_t value, value1, value2;
-	vfe31_program_dmi_cfg(channel_sel);
-	for (i = 0 ; i < (VFE31_GAMMA_NUM_ENTRIES/2) ; i++) {
-		value = *tbl++;
-		value1 = value & 0x0000FFFF;
-		value2 = (value & 0xFFFF0000)>>16;
-		msm_camera_io_w((value1),
-			vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
-		msm_camera_io_w((value2),
-			vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
-	}
-	vfe31_program_dmi_cfg(NO_MEM_SELECTED);
-}
-
-static void vfe31_read_gamma_cfg(enum VFE31_DMI_RAM_SEL channel_sel,
-	uint32_t *tbl)
-{
-	int i;
-	vfe31_program_dmi_cfg(channel_sel);
-	CDBG("%s: Gamma table channel: %d\n", __func__, channel_sel);
-	for (i = 0 ; i < VFE31_GAMMA_NUM_ENTRIES ; i++) {
-		*tbl = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
-		CDBG("%s: %08x\n", __func__, *tbl);
-		tbl++;
-	}
-	vfe31_program_dmi_cfg(NO_MEM_SELECTED);
-}
-
-static void vfe31_write_la_cfg(enum VFE31_DMI_RAM_SEL channel_sel,
-						const uint32_t *tbl)
-{
-	uint32_t i;
-	uint32_t value, value1, value2;
-
-	vfe31_program_dmi_cfg(channel_sel);
-	for (i = 0 ; i < (VFE31_LA_TABLE_LENGTH/2) ; i++) {
-		value = *tbl++;
-		value1 = value & 0x0000FFFF;
-		value2 = (value & 0xFFFF0000)>>16;
-		msm_camera_io_w((value1),
-			vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
-		msm_camera_io_w((value2),
-			vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
-	}
-	vfe31_program_dmi_cfg(NO_MEM_SELECTED);
-}
-
-static struct vfe31_output_ch *vfe31_get_ch(int path)
-{
-	struct vfe31_output_ch *ch = NULL;
-
-	if (path == VFE_MSG_OUTPUT_PRIMARY)
-		ch = &vfe31_ctrl->outpath.out0;
-	else if (path == VFE_MSG_OUTPUT_SECONDARY)
-		ch = &vfe31_ctrl->outpath.out1;
-	else
-		pr_err("%s: Invalid path %d\n", __func__, path);
-
-	BUG_ON(ch == NULL);
-	return ch;
-}
-static struct msm_free_buf *vfe31_check_free_buffer(int id, int path)
-{
-	struct vfe31_output_ch *outch = NULL;
-	struct msm_free_buf *b = NULL;
-	uint32_t inst_handle = 0;
-
-	if (path == VFE_MSG_OUTPUT_PRIMARY)
-		inst_handle = vfe31_ctrl->outpath.out0.inst_handle;
-	else
-		inst_handle = vfe31_ctrl->outpath.out1.inst_handle;
-
-	vfe31_subdev_notify(id, path, inst_handle);
-	outch = vfe31_get_ch(path);
-	if (outch->free_buf.ch_paddr[0])
-		b = &outch->free_buf;
-	return b;
-}
-static int vfe31_configure_pingpong_buffers(int id, int path)
-{
-	struct vfe31_output_ch *outch = NULL;
-	int rc = 0;
-	uint32_t inst_handle = 0;
-
-	if (path == VFE_MSG_OUTPUT_PRIMARY)
-		inst_handle = vfe31_ctrl->outpath.out0.inst_handle;
-	else
-		inst_handle = vfe31_ctrl->outpath.out1.inst_handle;
-
-	vfe31_subdev_notify(id, path, inst_handle);
-	outch = vfe31_get_ch(path);
-	if (outch->ping.ch_paddr[0] && outch->pong.ch_paddr[0]) {
-		/* Configure Preview Ping Pong */
-		CDBG("%s Configure ping/pong address for %d",
-			__func__, path);
-		vfe31_put_ch_ping_addr(outch->ch0,
-			outch->ping.ch_paddr[0]);
-		vfe31_put_ch_pong_addr(outch->ch0,
-			outch->pong.ch_paddr[0]);
-
-		if (vfe31_ctrl->operation_mode !=
-			VFE_OUTPUTS_RAW) {
-			vfe31_put_ch_ping_addr(outch->ch1,
-				outch->ping.ch_paddr[1]);
-			vfe31_put_ch_pong_addr(outch->ch1,
-				outch->pong.ch_paddr[1]);
-		}
-
-		if (outch->ping.num_planes > 2)
-			vfe31_put_ch_ping_addr(outch->ch2,
-				outch->ping.ch_paddr[2]);
-		if (outch->pong.num_planes > 2)
-			vfe31_put_ch_pong_addr(outch->ch2,
-				outch->pong.ch_paddr[2]);
-
-		/* avoid stale info */
-		memset(&outch->ping, 0, sizeof(struct msm_free_buf));
-		memset(&outch->pong, 0, sizeof(struct msm_free_buf));
-	} else {
-		pr_err("%s ping/pong addr is null!!", __func__);
-		rc = -EINVAL;
-	}
-	return rc;
-}
-
-static void vfe31_send_isp_msg(struct vfe31_ctrl_type *vctrl,
-	uint32_t isp_msg_id)
-{
-	struct isp_msg_event isp_msg_evt;
-
-	isp_msg_evt.msg_id = isp_msg_id;
-	isp_msg_evt.sof_count = vfe31_ctrl->vfeFrameId;
-	v4l2_subdev_notify(&vctrl->subdev,
-		NOTIFY_ISP_MSG_EVT, (void *)&isp_msg_evt);
-}
-
-static int vfe31_proc_general(
-	struct msm_cam_media_controller *pmctl,
-	struct msm_isp_cmd *cmd)
-{
-	int i , rc = 0;
-	uint32_t old_val = 0 , new_val = 0;
-	uint32_t *cmdp = NULL;
-	uint32_t *cmdp_local = NULL;
-	uint32_t snapshot_cnt = 0;
-	uint32_t temp1 = 0, temp2 = 0;
-
-	CDBG("vfe31_proc_general: cmdID = %s, length = %d\n",
-		vfe31_general_cmd[cmd->id], cmd->length);
-	switch (cmd->id) {
-	case VFE_CMD_RESET:
-		pr_info("vfe31_proc_general: cmdID = %s\n",
-			vfe31_general_cmd[cmd->id]);
-		vfe31_reset();
-		break;
-	case VFE_CMD_START:
-		pr_info("vfe31_proc_general: cmdID = %s\n",
-			vfe31_general_cmd[cmd->id]);
-		if ((vfe31_ctrl->operation_mode ==
-				VFE_OUTPUTS_PREVIEW_AND_VIDEO) ||
-			(vfe31_ctrl->operation_mode ==
-				VFE_OUTPUTS_PREVIEW))
-			/* Configure primary channel */
-			rc = vfe31_configure_pingpong_buffers(
-				VFE_MSG_START, VFE_MSG_OUTPUT_PRIMARY);
-		else
-			/* Configure secondary channel */
-			rc = vfe31_configure_pingpong_buffers(
-				VFE_MSG_START, VFE_MSG_OUTPUT_SECONDARY);
-		if (rc < 0) {
-			pr_err("%s error configuring pingpong buffers"
-				" for preview", __func__);
-			rc = -EINVAL;
-			goto proc_general_done;
-		}
-		rc = vfe31_start(pmctl);
-		break;
-	case VFE_CMD_UPDATE:
-		vfe31_update();
-		break;
-	case VFE_CMD_CAPTURE_RAW:
-		pr_info("%s: cmdID = VFE_CMD_CAPTURE_RAW\n", __func__);
-		if (copy_from_user(&snapshot_cnt, (void __user *)(cmd->value),
-			sizeof(uint32_t))) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		rc = vfe31_configure_pingpong_buffers(VFE_MSG_CAPTURE,
-			VFE_MSG_OUTPUT_PRIMARY);
-		if (rc < 0) {
-			pr_err("%s error configuring pingpong buffers"
-				" for snapshot", __func__);
-			rc = -EINVAL;
-			goto proc_general_done;
-		}
-		rc = vfe31_capture_raw(pmctl, snapshot_cnt);
-		break;
-	case VFE_CMD_CAPTURE:
-		if (copy_from_user(&snapshot_cnt, (void __user *)(cmd->value),
-			sizeof(uint32_t))) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-
-		if (vfe31_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB ||
-		vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG) {
-			if (snapshot_cnt != 1) {
-				pr_err("only support 1 inline snapshot\n");
-				rc = -EINVAL;
-				goto proc_general_done;
-			}
-			/* Configure primary channel for JPEG */
-			rc = vfe31_configure_pingpong_buffers(
-				VFE_MSG_JPEG_CAPTURE,
-				VFE_MSG_OUTPUT_PRIMARY);
-		} else {
-			/* Configure primary channel */
-			rc = vfe31_configure_pingpong_buffers(
-				VFE_MSG_CAPTURE,
-				VFE_MSG_OUTPUT_PRIMARY);
-		}
-		if (rc < 0) {
-			pr_err("%s error configuring pingpong buffers"
-				" for primary output", __func__);
-			rc = -EINVAL;
-			goto proc_general_done;
-		}
-		/* Configure secondary channel */
-		rc = vfe31_configure_pingpong_buffers(VFE_MSG_CAPTURE,
-			VFE_MSG_OUTPUT_SECONDARY);
-		if (rc < 0) {
-			pr_err("%s error configuring pingpong buffers"
-				" for secondary output", __func__);
-			rc = -EINVAL;
-			goto proc_general_done;
-		}
-		rc = vfe31_capture(pmctl, snapshot_cnt);
-		break;
-	case VFE_CMD_START_RECORDING:
-		pr_info("vfe31_proc_general: cmdID = %s\n",
-			vfe31_general_cmd[cmd->id]);
-		if (copy_from_user(&temp1, (void __user *)(cmd->value),
-				sizeof(uint32_t))) {
-			pr_err("%s Error copying inst_handle for recording\n",
-				__func__);
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		if (vfe31_ctrl->operation_mode ==
-			VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
-			vfe31_ctrl->outpath.out1.inst_handle = temp1;
-			rc = vfe31_configure_pingpong_buffers(
-				VFE_MSG_START_RECORDING,
-				VFE_MSG_OUTPUT_SECONDARY);
-		} else if (vfe31_ctrl->operation_mode ==
-			VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
-			vfe31_ctrl->outpath.out0.inst_handle = temp1;
-			rc = vfe31_configure_pingpong_buffers(
-				VFE_MSG_START_RECORDING,
-				VFE_MSG_OUTPUT_PRIMARY);
-		}
-		if (rc < 0) {
-			pr_err("%s error configuring pingpong buffers"
-				" for video", __func__);
-			rc = -EINVAL;
-			goto proc_general_done;
-		}
-		rc = vfe31_start_recording(pmctl);
-		break;
-	case VFE_CMD_STOP_RECORDING:
-		pr_info("vfe31_proc_general: cmdID = %s\n",
-			vfe31_general_cmd[cmd->id]);
-		rc = vfe31_stop_recording(pmctl);
-		break;
-	case VFE_CMD_OPERATION_CFG:
-		if (cmd->length != V31_OPERATION_CFG_LEN) {
-			rc = -EINVAL;
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(V31_OPERATION_CFG_LEN, GFP_ATOMIC);
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			V31_OPERATION_CFG_LEN)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		rc = vfe31_operation_config(cmdp);
-		break;
-
-	case VFE_CMD_STATS_AE_START:
-		rc = vfe_stats_aec_buf_init(NULL);
-		if (rc < 0) {
-			pr_err("%s: cannot config ping/pong address of AEC",
-				__func__);
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val |= AE_BG_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
-		cmdp, (vfe31_cmd[cmd->id].length));
-		break;
-	case VFE_CMD_STATS_AF_START:
-		rc = vfe_stats_af_buf_init(NULL);
-		if (rc < 0) {
-			pr_err("%s: cannot config ping/pong address of AF",
-				__func__);
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val |= AF_BF_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
-		cmdp, (vfe31_cmd[cmd->id].length));
-		break;
-	case VFE_CMD_STATS_AWB_START:
-		rc = vfe_stats_awb_buf_init(NULL);
-		if (rc < 0) {
-			pr_err("%s: cannot config ping/pong address of AWB",
-				__func__);
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val |= AWB_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
-			cmdp, (vfe31_cmd[cmd->id].length));
-		break;
-
-	case VFE_CMD_STATS_IHIST_START:
-		rc = vfe_stats_ihist_buf_init(NULL);
-		if (rc < 0) {
-			pr_err("%s: cannot config ping/pong address of IHIST",
-			__func__);
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val |= IHIST_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
-			cmdp, (vfe31_cmd[cmd->id].length));
-		break;
-
-	case VFE_CMD_STATS_RS_START:
-		rc = vfe_stats_rs_buf_init(NULL);
-		if (rc < 0) {
-			pr_err("%s: cannot config ping/pong address of RS",
-				__func__);
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
-			cmdp, (vfe31_cmd[cmd->id].length));
-		break;
-
-	case VFE_CMD_STATS_CS_START:
-		rc = vfe_stats_cs_buf_init(NULL);
-		if (rc < 0) {
-			pr_err("%s: cannot config ping/pong address of CS",
-				__func__);
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
-			cmdp, (vfe31_cmd[cmd->id].length));
-		break;
-
-	case VFE_CMD_MCE_UPDATE:
-	case VFE_CMD_MCE_CFG:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		/* Incrementing with 4 so as to point to the 2nd Register as
-		the 2nd register has the mce_enable bit */
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase +
-			V31_CHROMA_SUP_OFF + 4);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		new_val = *cmdp_local;
-		old_val &= MCE_EN_MASK;
-		new_val = new_val | old_val;
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + V31_CHROMA_SUP_OFF + 4,
-			&new_val, 4);
-		cmdp_local += 1;
-
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase +
-			V31_CHROMA_SUP_OFF + 8);
-		new_val = *cmdp_local;
-		old_val &= MCE_Q_K_MASK;
-		new_val = new_val | old_val;
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + V31_CHROMA_SUP_OFF + 8,
-			&new_val, 4);
-		cmdp_local += 1;
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
-			cmdp_local, (vfe31_cmd[cmd->id].length));
-		break;
-	case VFE_CMD_CHROMA_SUP_UPDATE:
-	case VFE_CMD_CHROMA_SUP_CFG:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		msm_camera_io_memcpy(vfe31_ctrl->vfebase + V31_CHROMA_SUP_OFF,
-			cmdp_local, 4);
-
-		cmdp_local += 1;
-		new_val = *cmdp_local;
-		/* Incrementing with 4 so as to point to the 2nd Register as
-		 * the 2nd register has the mce_enable bit
-		 */
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase +
-			V31_CHROMA_SUP_OFF + 4);
-		old_val &= ~MCE_EN_MASK;
-		new_val = new_val | old_val;
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + V31_CHROMA_SUP_OFF + 4,
-			&new_val, 4);
-		cmdp_local += 1;
-
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase +
-			V31_CHROMA_SUP_OFF + 8);
-		new_val = *cmdp_local;
-		old_val &= ~MCE_Q_K_MASK;
-		new_val = new_val | old_val;
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + V31_CHROMA_SUP_OFF + 8,
-			&new_val, 4);
-		break;
-
-	case VFE_CMD_MESH_ROLL_OFF_CFG:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value) , cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
-			cmdp_local, 16);
-		cmdp_local += 4;
-		vfe31_program_dmi_cfg(ROLLOFF_RAM);
-		/* for loop for extrcting init table. */
-		for (i = 0; i < (V31_MESH_ROLL_OFF_INIT_TABLE_SIZE * 2); i++) {
-			msm_camera_io_w(*cmdp_local ,
-			vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
-			cmdp_local++;
-		}
-		CDBG("done writing init table\n");
-		/* by default, always starts with offset 0. */
-		msm_camera_io_w(V31_MESH_ROLL_OFF_DELTA_TABLE_OFFSET,
-		vfe31_ctrl->vfebase + VFE_DMI_ADDR);
-		/* for loop for extracting delta table. */
-		for (i = 0; i < (V31_MESH_ROLL_OFF_DELTA_TABLE_SIZE * 2); i++) {
-			msm_camera_io_w(*cmdp_local,
-			vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
-			cmdp_local++;
-		}
-		vfe31_program_dmi_cfg(NO_MEM_SELECTED);
-		break;
-
-	case VFE_CMD_GET_MESH_ROLLOFF_TABLE:
-		temp1 = sizeof(uint32_t) * ((V31_MESH_ROLL_OFF_INIT_TABLE_SIZE *
-			2) + (V31_MESH_ROLL_OFF_DELTA_TABLE_SIZE * 2));
-		if (cmd->length != temp1) {
-			rc = -EINVAL;
-			goto proc_general_done;
-		}
-		cmdp = kzalloc(temp1, GFP_KERNEL);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		vfe31_program_dmi_cfg(ROLLOFF_RAM);
-		CDBG("%s: Mesh Rolloff init Table\n", __func__);
-		for (i = 0; i < (V31_MESH_ROLL_OFF_INIT_TABLE_SIZE * 2); i++) {
-			*cmdp_local = msm_camera_io_r(
-					vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
-			CDBG("%s: %08x\n", __func__, *cmdp_local);
-			cmdp_local++;
-		}
-		msm_camera_io_w(V31_MESH_ROLL_OFF_DELTA_TABLE_OFFSET,
-			vfe31_ctrl->vfebase + VFE_DMI_ADDR);
-		CDBG("%s: Mesh Rolloff Delta Table\n", __func__);
-		for (i = 0; i < (V31_MESH_ROLL_OFF_DELTA_TABLE_SIZE * 2); i++) {
-			*cmdp_local = msm_camera_io_r(
-					vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
-			CDBG("%s: %08x\n", __func__, *cmdp_local);
-			cmdp_local++;
-		}
-		CDBG("done reading delta table\n");
-		vfe31_program_dmi_cfg(NO_MEM_SELECTED);
-		if (copy_to_user((void __user *)(cmd->value), cmdp,
-			temp1)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		break;
-	case VFE_CMD_LA_CFG:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
-			cmdp_local, (vfe31_cmd[cmd->id].length));
-
-		cmdp_local += 1;
-		vfe31_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK0, cmdp_local);
-		break;
-
-	case VFE_CMD_LA_UPDATE:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-
-		cmdp_local = cmdp + 1;
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + V31_LA_OFF);
-		if (old_val != 0x0)
-			vfe31_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK0,
-				cmdp_local);
-		else
-			vfe31_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK1,
-				cmdp_local);
-		vfe31_ctrl->update_la = true;
-		break;
-
-	case VFE_CMD_GET_LA_TABLE:
-		temp1 = sizeof(uint32_t) * VFE31_LA_TABLE_LENGTH / 2;
-		if (cmd->length != temp1) {
-			rc = -EINVAL;
-			goto proc_general_done;
-		}
-		cmdp = kzalloc(temp1, GFP_KERNEL);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		if (msm_camera_io_r(vfe31_ctrl->vfebase + V31_LA_OFF))
-			vfe31_program_dmi_cfg(LUMA_ADAPT_LUT_RAM_BANK1);
-		else
-			vfe31_program_dmi_cfg(LUMA_ADAPT_LUT_RAM_BANK0);
-		for (i = 0 ; i < (VFE31_LA_TABLE_LENGTH / 2) ; i++) {
-			*cmdp_local = msm_camera_io_r(
-					vfe31_ctrl->vfebase + VFE_DMI_DATA_LO);
-			*cmdp_local |= (msm_camera_io_r(vfe31_ctrl->vfebase +
-				VFE_DMI_DATA_LO)) << 16;
-			cmdp_local++;
-		}
-		vfe31_program_dmi_cfg(NO_MEM_SELECTED);
-		if (copy_to_user((void __user *)(cmd->value), cmdp,
-			temp1)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		break;
-	case VFE_CMD_SK_ENHAN_CFG:
-	case VFE_CMD_SK_ENHAN_UPDATE:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		msm_camera_io_memcpy(vfe31_ctrl->vfebase + V31_SCE_OFF,
-			cmdp, V31_SCE_LEN);
-		break;
-
-	case VFE_CMD_LIVESHOT:
-		if (copy_from_user(&temp1, (void __user *)(cmd->value),
-				sizeof(uint32_t))) {
-			pr_err("%s Error copying inst_handle for liveshot ",
-				__func__);
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		vfe31_ctrl->outpath.out0.inst_handle = temp1;
-		/* Configure primary channel */
-		rc = vfe31_configure_pingpong_buffers(VFE_MSG_CAPTURE,
-			VFE_MSG_OUTPUT_PRIMARY);
-		if (rc < 0) {
-			pr_err("%s error configuring pingpong buffers"
-				" for primary output", __func__);
-			rc = -EINVAL;
-			goto proc_general_done;
-		}
-		vfe31_start_liveshot(pmctl);
-		break;
-
-	case VFE_CMD_DEMOSAICV3:
-		if (cmd->length != V31_DEMOSAICV3_LEN) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		new_val = *cmdp_local;
-
-		old_val = msm_camera_io_r(
-				vfe31_ctrl->vfebase + V31_DEMOSAICV3_OFF);
-		old_val &= DEMOSAIC_MASK;
-		new_val = new_val | old_val;
-		*cmdp_local = new_val;
-
-		msm_camera_io_memcpy(vfe31_ctrl->vfebase + V31_DEMOSAICV3_OFF,
-			cmdp_local, V31_DEMOSAICV3_LEN);
-		break;
-
-	case VFE_CMD_DEMOSAICV3_UPDATE:
-		if (cmd->length !=
-			V31_DEMOSAICV3_LEN * V31_DEMOSAICV3_UP_REG_CNT) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		new_val = *cmdp_local;
-
-		old_val = msm_camera_io_r(
-				vfe31_ctrl->vfebase + V31_DEMOSAICV3_OFF);
-		old_val &= DEMOSAIC_MASK;
-		new_val = new_val | old_val;
-		*cmdp_local = new_val;
-
-		msm_camera_io_memcpy(vfe31_ctrl->vfebase + V31_DEMOSAICV3_OFF,
-			cmdp_local, V31_DEMOSAICV3_LEN);
-
-		break;
-
-	case VFE_CMD_DEMOSAICV3_ABCC_CFG:
-		rc = -EFAULT;
-		break;
-
-	case VFE_CMD_DEMOSAICV3_ABF_UPDATE:/* 116 ABF update  */
-	case VFE_CMD_DEMOSAICV3_ABF_CFG: /* 108 ABF config  */
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		new_val = *cmdp_local;
-
-		old_val = msm_camera_io_r(
-				vfe31_ctrl->vfebase + V31_DEMOSAICV3_OFF);
-		old_val &= ABF_MASK;
-		new_val = new_val | old_val;
-		*cmdp_local = new_val;
-
-		msm_camera_io_memcpy(vfe31_ctrl->vfebase + V31_DEMOSAICV3_OFF,
-		    cmdp_local, 4);
-
-		cmdp_local += 1;
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
-			cmdp_local, (vfe31_cmd[cmd->id].length));
-		break;
-
-	case VFE_CMD_DEMOSAICV3_DBCC_CFG:
-	case VFE_CMD_DEMOSAICV3_DBCC_UPDATE:
-		return -EINVAL;
-
-	case VFE_CMD_DEMOSAICV3_DBPC_CFG:
-	case VFE_CMD_DEMOSAICV3_DBPC_UPDATE:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		new_val = *cmdp_local;
-
-		old_val = msm_camera_io_r(
-				vfe31_ctrl->vfebase + V31_DEMOSAICV3_OFF);
-		old_val &= BPC_MASK;
-
-		new_val = new_val | old_val;
-		*cmdp_local = new_val;
-		msm_camera_io_memcpy(vfe31_ctrl->vfebase + V31_DEMOSAICV3_OFF,
-					cmdp_local, V31_DEMOSAICV3_LEN);
-		cmdp_local += 1;
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + V31_DEMOSAICV3_DBPC_CFG_OFF,
-			cmdp_local, V31_DEMOSAICV3_DBPC_LEN);
-		break;
-
-	case VFE_CMD_RGB_G_CFG:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		msm_camera_io_memcpy(vfe31_ctrl->vfebase + V31_RGB_G_OFF,
-			cmdp, 4);
-		cmdp += 1;
-
-		vfe31_write_gamma_cfg(RGBLUT_RAM_CH0_BANK0, cmdp);
-		vfe31_write_gamma_cfg(RGBLUT_RAM_CH1_BANK0, cmdp);
-		vfe31_write_gamma_cfg(RGBLUT_RAM_CH2_BANK0, cmdp);
-		cmdp -= 1;
-		break;
-
-	case VFE_CMD_RGB_G_UPDATE:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp, (void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + V31_RGB_G_OFF);
-		cmdp += 1;
-		if (old_val != 0x0) {
-			vfe31_write_gamma_cfg(RGBLUT_RAM_CH0_BANK0, cmdp);
-			vfe31_write_gamma_cfg(RGBLUT_RAM_CH1_BANK0, cmdp);
-			vfe31_write_gamma_cfg(RGBLUT_RAM_CH2_BANK0, cmdp);
-		} else {
-			vfe31_write_gamma_cfg(RGBLUT_RAM_CH0_BANK1, cmdp);
-			vfe31_write_gamma_cfg(RGBLUT_RAM_CH1_BANK1, cmdp);
-			vfe31_write_gamma_cfg(RGBLUT_RAM_CH2_BANK1, cmdp);
-		}
-		vfe31_ctrl->update_gamma = TRUE;
-		cmdp -= 1;
-		break;
-
-	case VFE_CMD_GET_RGB_G_TABLE:
-		temp1 = sizeof(uint32_t) * VFE31_GAMMA_NUM_ENTRIES * 3;
-		if (cmd->length != temp1) {
-			rc = -EINVAL;
-			goto proc_general_done;
-		}
-		cmdp = kzalloc(temp1, GFP_KERNEL);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + V31_RGB_G_OFF);
-		temp2 = old_val ? RGBLUT_RAM_CH0_BANK1 :
-			RGBLUT_RAM_CH0_BANK0;
-		for (i = 0; i < 3; i++) {
-			vfe31_read_gamma_cfg(temp2,
-				cmdp_local + (VFE31_GAMMA_NUM_ENTRIES * i));
-			temp2 += 2;
-		}
-		if (copy_to_user((void __user *)(cmd->value), cmdp,
-			temp1)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		break;
-
-	case VFE_CMD_STATS_AWB_STOP:
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= ~AWB_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		break;
-	case VFE_CMD_STATS_AE_STOP:
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= ~AE_BG_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		break;
-	case VFE_CMD_STATS_AF_STOP:
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= ~AF_BF_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		rc = vfe31_stats_flush_enqueue(MSM_STATS_TYPE_AF);
-		if (rc < 0) {
-			pr_err("%s: dq stats buf err = %d",
-				   __func__, rc);
-			return -EINVAL;
-		}
-		break;
-
-	case VFE_CMD_STATS_IHIST_STOP:
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= ~IHIST_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		break;
-
-	case VFE_CMD_STATS_RS_STOP:
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= ~RS_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		break;
-
-	case VFE_CMD_STATS_CS_STOP:
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= ~CS_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		break;
-
-	case VFE_CMD_STOP:
-		pr_info("vfe31_proc_general: cmdID = %s\n",
-			vfe31_general_cmd[cmd->id]);
-		vfe31_stop();
-		break;
-
-	case VFE_CMD_SYNC_TIMER_SETTING:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp, (void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		vfe31_sync_timer_start(cmdp);
-		break;
-
-	case VFE_CMD_MODULE_CFG:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		*cmdp &= ~STATS_ENABLE_MASK;
-		old_val = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= STATS_ENABLE_MASK;
-		*cmdp |= old_val;
-
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
-			cmdp, (vfe31_cmd[cmd->id].length));
-		break;
-
-	case VFE_CMD_ZSL:
-		rc = vfe31_configure_pingpong_buffers(VFE_MSG_START,
-			VFE_MSG_OUTPUT_PRIMARY);
-		if (rc < 0)
-			goto proc_general_done;
-		rc = vfe31_configure_pingpong_buffers(VFE_MSG_START,
-			VFE_MSG_OUTPUT_SECONDARY);
-		if (rc < 0)
-			goto proc_general_done;
-
-		rc = vfe31_zsl(pmctl);
-		break;
-
-	case VFE_CMD_ASF_CFG:
-	case VFE_CMD_ASF_UPDATE:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp, (void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
-			cmdp, (vfe31_cmd[cmd->id].length));
-		cmdp_local = cmdp + V31_ASF_LEN/4;
-		break;
-
-	case VFE_CMD_GET_HW_VERSION:
-		if (cmd->length != V31_GET_HW_VERSION_LEN) {
-			rc = -EINVAL;
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(V31_GET_HW_VERSION_LEN, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		*cmdp = msm_camera_io_r(
-				vfe31_ctrl->vfebase+V31_GET_HW_VERSION_OFF);
-		if (copy_to_user((void __user *)(cmd->value), cmdp,
-			V31_GET_HW_VERSION_LEN)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		break;
-	case VFE_CMD_GET_REG_DUMP:
-		temp1 = sizeof(uint32_t) * vfe31_ctrl->register_total;
-		if (cmd->length != temp1) {
-			rc = -EINVAL;
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(temp1, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		msm_camera_io_dump(
-			vfe31_ctrl->vfebase, vfe31_ctrl->register_total*4);
-		CDBG("%s: %p %p %d\n", __func__, (void *)cmdp,
-			vfe31_ctrl->vfebase, temp1);
-		memcpy_fromio((void *)cmdp, vfe31_ctrl->vfebase, temp1);
-		if (copy_to_user((void __user *)(cmd->value), cmdp, temp1)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		break;
-	case VFE_CMD_FRAME_SKIP_CFG:
-		if (cmd->length != vfe31_cmd[cmd->id].length)
-			return -EINVAL;
-
-		cmdp = kmalloc(vfe31_cmd[cmd->id].length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-
-		if (copy_from_user(cmdp, (void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
-			cmdp, (vfe31_cmd[cmd->id].length));
-		vfe31_ctrl->frame_skip_cnt = ((uint32_t)
-			*cmdp & VFE_FRAME_SKIP_PERIOD_MASK) + 1;
-		vfe31_ctrl->frame_skip_pattern = (uint32_t)(*(cmdp + 2));
-		break;
-	default:
-		if (cmd->length != vfe31_cmd[cmd->id].length)
-			return -EINVAL;
-
-		cmdp = kmalloc(vfe31_cmd[cmd->id].length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-
-		if (copy_from_user(cmdp, (void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		msm_camera_io_memcpy(
-			vfe31_ctrl->vfebase + vfe31_cmd[cmd->id].offset,
-			cmdp, (vfe31_cmd[cmd->id].length));
-		break;
-
-	}
-
-proc_general_done:
-	kfree(cmdp);
-
-	return rc;
-}
-
-static inline void vfe31_read_irq_status(struct vfe31_irq_status *out)
-{
-	uint32_t *temp;
-	memset(out, 0, sizeof(struct vfe31_irq_status));
-	temp = (uint32_t *)(vfe31_ctrl->vfebase + VFE_IRQ_STATUS_0);
-	out->vfeIrqStatus0 = msm_camera_io_r(temp);
-
-	temp = (uint32_t *)(vfe31_ctrl->vfebase + VFE_IRQ_STATUS_1);
-	out->vfeIrqStatus1 = msm_camera_io_r(temp);
-
-	temp = (uint32_t *)(vfe31_ctrl->vfebase + VFE_CAMIF_STATUS);
-	out->camifStatus = msm_camera_io_r(temp);
-	CDBG("camifStatus  = 0x%x\n", out->camifStatus);
-
-	/* clear the pending interrupt of the same kind.*/
-	msm_camera_io_w(out->vfeIrqStatus0,
-		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_0);
-	msm_camera_io_w(out->vfeIrqStatus1,
-		vfe31_ctrl->vfebase + VFE_IRQ_CLEAR_1);
-
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_IRQ_CMD);
-
-}
-
-static void vfe31_process_reg_update_irq(void)
-{
-	unsigned long flags;
-
-	if (vfe31_ctrl->recording_state == VFE_STATE_START_REQUESTED) {
-		if (vfe31_ctrl->operation_mode ==
-			VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
-		} else if (vfe31_ctrl->operation_mode ==
-			VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
-		}
-		vfe31_ctrl->recording_state = VFE_STATE_STARTED;
-		msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-		CDBG("start video triggered .\n");
-	} else if (vfe31_ctrl->recording_state ==
-		VFE_STATE_STOP_REQUESTED) {
-		if (vfe31_ctrl->operation_mode ==
-			VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
-			msm_camera_io_w(0, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(0, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
-		} else if (vfe31_ctrl->operation_mode ==
-			VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
-			msm_camera_io_w(0, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
-			msm_camera_io_w(0, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
-		}
-		CDBG("stop video triggered .\n");
-	}
-
-	if (vfe31_ctrl->start_ack_pending == TRUE) {
-		vfe31_send_isp_msg(vfe31_ctrl, MSG_ID_START_ACK);
-		vfe31_ctrl->start_ack_pending = FALSE;
-	} else {
-		if (vfe31_ctrl->recording_state ==
-			VFE_STATE_STOP_REQUESTED) {
-			vfe31_ctrl->recording_state = VFE_STATE_STOPPED;
-			/* request a reg update and send STOP_REC_ACK
-			 * when we process the next reg update irq.
-			 */
-			msm_camera_io_w_mb(1,
-			vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-		} else if (vfe31_ctrl->recording_state ==
-			VFE_STATE_STOPPED) {
-			vfe31_send_isp_msg(vfe31_ctrl, MSG_ID_STOP_REC_ACK);
-			vfe31_ctrl->recording_state = VFE_STATE_IDLE;
-		}
-		spin_lock_irqsave(&vfe31_ctrl->update_ack_lock, flags);
-		if (vfe31_ctrl->update_ack_pending == TRUE) {
-			vfe31_ctrl->update_ack_pending = FALSE;
-			spin_unlock_irqrestore(
-				&vfe31_ctrl->update_ack_lock, flags);
-			vfe31_send_isp_msg(vfe31_ctrl, MSG_ID_UPDATE_ACK);
-		} else {
-			spin_unlock_irqrestore(
-				&vfe31_ctrl->update_ack_lock, flags);
-		}
-	}
-
-	if (vfe31_ctrl->liveshot_state == VFE_STATE_START_REQUESTED) {
-		pr_info("%s enabling liveshot output\n", __func__);
-		if (vfe31_ctrl->outpath.output_mode &
-			VFE31_OUTPUT_MODE_PRIMARY) {
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(1, vfe31_ctrl->vfebase +
-			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
-			vfe31_ctrl->liveshot_state = VFE_STATE_STARTED;
-		}
-	}
-
-	if (vfe31_ctrl->liveshot_state == VFE_STATE_STARTED) {
-		vfe31_ctrl->vfe_capture_count--;
-		if (!vfe31_ctrl->vfe_capture_count)
-			vfe31_ctrl->liveshot_state = VFE_STATE_STOP_REQUESTED;
-		msm_camera_io_w_mb(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-	} else if (vfe31_ctrl->liveshot_state == VFE_STATE_STOP_REQUESTED) {
-		CDBG("%s: disabling liveshot output\n", __func__);
-		if (vfe31_ctrl->outpath.output_mode &
-			VFE31_OUTPUT_MODE_PRIMARY) {
-			msm_camera_io_w(0, vfe31_ctrl->vfebase +
-				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(0, vfe31_ctrl->vfebase +
-				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
-			vfe31_ctrl->liveshot_state = VFE_STATE_STOPPED;
-			msm_camera_io_w_mb(1, vfe31_ctrl->vfebase +
-				VFE_REG_UPDATE_CMD);
-		}
-	} else if (vfe31_ctrl->liveshot_state == VFE_STATE_STOPPED) {
-		vfe31_ctrl->liveshot_state = VFE_STATE_IDLE;
-	}
-
-	if ((vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN) ||
-		(vfe31_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB) ||
-		(vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG) ||
-		(vfe31_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB)) {
-		/* in snapshot mode */
-		/* later we need to add check for live snapshot mode. */
-		if (vfe31_ctrl->frame_skip_pattern & (0x1 <<
-			(vfe31_ctrl->snapshot_frame_cnt %
-				vfe31_ctrl->frame_skip_cnt))) {
-			/* if last frame to be captured: */
-			if (vfe31_ctrl->vfe_capture_count == 0) {
-				/* stop the bus output:write master enable = 0*/
-				if (vfe31_ctrl->outpath.output_mode &
-					VFE31_OUTPUT_MODE_PRIMARY) {
-					msm_camera_io_w(0, vfe31_ctrl->vfebase +
-						vfe31_AXI_WM_CFG[vfe31_ctrl->
-						outpath.out0.ch0]);
-					msm_camera_io_w(0, vfe31_ctrl->vfebase +
-						vfe31_AXI_WM_CFG[vfe31_ctrl->
-						outpath.out0.ch1]);
-				}
-				if (vfe31_ctrl->outpath.output_mode &
-					VFE31_OUTPUT_MODE_SECONDARY) {
-					msm_camera_io_w(0, vfe31_ctrl->vfebase +
-						vfe31_AXI_WM_CFG[vfe31_ctrl->
-						outpath.out1.ch0]);
-					msm_camera_io_w(0, vfe31_ctrl->vfebase +
-						vfe31_AXI_WM_CFG[vfe31_ctrl->
-						outpath.out1.ch1]);
-				}
-				msm_camera_io_w_mb
-				(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
-				vfe31_ctrl->vfebase + VFE_CAMIF_COMMAND);
-				vfe31_ctrl->snapshot_frame_cnt = -1;
-				vfe31_ctrl->frame_skip_cnt = 31;
-				vfe31_ctrl->frame_skip_pattern = 0xffffffff;
-			} /*if snapshot count is 0*/
-		} /*if frame is not being dropped*/
-		/* then do reg_update. */
-		msm_camera_io_w(1, vfe31_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-	} /* if snapshot mode. */
-}
-
-static void vfe31_set_default_reg_values(void)
-{
-	msm_camera_io_w(0x800080, vfe31_ctrl->vfebase + VFE_DEMUX_GAIN_0);
-	msm_camera_io_w(0x800080, vfe31_ctrl->vfebase + VFE_DEMUX_GAIN_1);
-	/* What value should we program CGC_OVERRIDE to? */
-	msm_camera_io_w(0xFFFFF, vfe31_ctrl->vfebase + VFE_CGC_OVERRIDE);
-
-	/* default frame drop period and pattern */
-	msm_camera_io_w(0x1f, vfe31_ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_CFG);
-	msm_camera_io_w(0x1f, vfe31_ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_CFG);
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe31_ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_PATTERN);
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe31_ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_PATTERN);
-	msm_camera_io_w(0x1f, vfe31_ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y);
-	msm_camera_io_w(0x1f, vfe31_ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR);
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe31_ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_PATTERN);
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe31_ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR_PATTERN);
-	msm_camera_io_w(0, vfe31_ctrl->vfebase + VFE_CLAMP_MIN);
-	msm_camera_io_w(0xFFFFFF, vfe31_ctrl->vfebase + VFE_CLAMP_MAX);
-
-	/* stats UB config */
-	msm_camera_io_w(0x3980007,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_AEC_UB_CFG);
-	msm_camera_io_w(0x3A00007,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_AF_UB_CFG);
-	msm_camera_io_w(0x3A8000F,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_AWB_UB_CFG);
-	msm_camera_io_w(0x3B80007,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_RS_UB_CFG);
-	msm_camera_io_w(0x3C0001F,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_CS_UB_CFG);
-	msm_camera_io_w(0x3E0001F,
-		vfe31_ctrl->vfebase + VFE_BUS_STATS_HIST_UB_CFG);
-}
-
-static void vfe31_process_reset_irq(void)
-{
-	unsigned long flags;
-
-	atomic_set(&vfe31_ctrl->vstate, 0);
-
-	spin_lock_irqsave(&vfe31_ctrl->stop_flag_lock, flags);
-	if (vfe31_ctrl->stop_ack_pending) {
-		vfe31_ctrl->stop_ack_pending = FALSE;
-		spin_unlock_irqrestore(&vfe31_ctrl->stop_flag_lock, flags);
-		vfe31_send_isp_msg(vfe31_ctrl, MSG_ID_STOP_ACK);
-	} else {
-		spin_unlock_irqrestore(&vfe31_ctrl->stop_flag_lock, flags);
-		/* this is from reset command. */
-		vfe31_set_default_reg_values();
-
-		/* reload all write masters. (frame & line)*/
-		msm_camera_io_w(0x7FFF, vfe31_ctrl->vfebase + VFE_BUS_CMD);
-		vfe31_send_isp_msg(vfe31_ctrl, MSG_ID_RESET_ACK);
-	}
-}
-
-static void vfe31_process_camif_sof_irq(void)
-{
-	if (vfe31_ctrl->operation_mode ==
-		VFE_OUTPUTS_RAW) {
-		if (vfe31_ctrl->start_ack_pending) {
-			vfe31_send_isp_msg(vfe31_ctrl, MSG_ID_START_ACK);
-			vfe31_ctrl->start_ack_pending = FALSE;
-		}
-		vfe31_ctrl->vfe_capture_count--;
-		/* if last frame to be captured: */
-		if (vfe31_ctrl->vfe_capture_count == 0) {
-			/* Ensure the write order while writing
-			 to the command register using the barrier */
-			msm_camera_io_w_mb(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
-				vfe31_ctrl->vfebase + VFE_CAMIF_COMMAND);
-		}
-	} /* if raw snapshot mode. */
-	if ((vfe31_ctrl->hfr_mode != HFR_MODE_OFF) &&
-		(vfe31_ctrl->operation_mode == VFE_MODE_OF_OPERATION_VIDEO) &&
-		(vfe31_ctrl->vfeFrameId % vfe31_ctrl->hfr_mode != 0)) {
-		vfe31_ctrl->vfeFrameId++;
-		CDBG("Skip the SOF notification when HFR enabled\n");
-		return;
-	}
-	vfe31_ctrl->vfeFrameId++;
-	vfe31_send_isp_msg(vfe31_ctrl, MSG_ID_SOF_ACK);
-	CDBG("camif_sof_irq, frameId = %d\n", vfe31_ctrl->vfeFrameId);
-
-	if (vfe31_ctrl->sync_timer_state) {
-		if (vfe31_ctrl->sync_timer_repeat_count == 0)
-			vfe31_sync_timer_stop();
-		else
-			vfe31_ctrl->sync_timer_repeat_count--;
-	}
-	if ((vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN) ||
-		(vfe31_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB) ||
-		(vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG) ||
-		(vfe31_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB)) {
-		if (vfe31_ctrl->frame_skip_pattern & (0x1 <<
-			(vfe31_ctrl->snapshot_frame_cnt %
-				vfe31_ctrl->frame_skip_cnt))) {
-			vfe31_ctrl->vfe_capture_count--;
-		}
-		vfe31_ctrl->snapshot_frame_cnt++;
-	}
-}
-
-static void vfe31_process_error_irq(uint32_t errStatus)
-{
-	uint32_t reg_value, read_val;
-
-	if (errStatus & VFE31_IMASK_CAMIF_ERROR) {
-		pr_err("vfe31_irq: camif errors\n");
-		reg_value = msm_camera_io_r(
-				vfe31_ctrl->vfebase + VFE_CAMIF_STATUS);
-		pr_err("camifStatus  = 0x%x\n", reg_value);
-		vfe31_send_isp_msg(vfe31_ctrl, MSG_ID_CAMIF_ERROR);
-	}
-
-	if (errStatus & VFE31_IMASK_STATS_CS_OVWR)
-		pr_err("vfe31_irq: stats cs overwrite\n");
-
-	if (errStatus & VFE31_IMASK_STATS_IHIST_OVWR)
-		pr_err("vfe31_irq: stats ihist overwrite\n");
-
-	if (errStatus & VFE31_IMASK_REALIGN_BUF_Y_OVFL)
-		pr_err("vfe31_irq: realign bug Y overflow\n");
-
-	if (errStatus & VFE31_IMASK_REALIGN_BUF_CB_OVFL)
-		pr_err("vfe31_irq: realign bug CB overflow\n");
-
-	if (errStatus & VFE31_IMASK_REALIGN_BUF_CR_OVFL)
-		pr_err("vfe31_irq: realign bug CR overflow\n");
-
-	if (errStatus & VFE31_IMASK_VIOLATION)
-		pr_err("vfe31_irq: violation interrupt\n");
-
-	if (errStatus & VFE31_IMASK_IMG_MAST_0_BUS_OVFL)
-		pr_err("vfe31_irq: image master 0 bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_IMG_MAST_1_BUS_OVFL)
-		pr_err("vfe31_irq: image master 1 bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_IMG_MAST_2_BUS_OVFL)
-		pr_err("vfe31_irq: image master 2 bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_IMG_MAST_3_BUS_OVFL)
-		pr_err("vfe31_irq: image master 3 bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_IMG_MAST_4_BUS_OVFL)
-		pr_err("vfe31_irq: image master 4 bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_IMG_MAST_5_BUS_OVFL)
-		pr_err("vfe31_irq: image master 5 bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_IMG_MAST_6_BUS_OVFL)
-		pr_err("vfe31_irq: image master 6 bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_STATS_AE_BG_BUS_OVFL)
-		pr_err("vfe31_irq: ae/bg stats bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_STATS_AF_BF_BUS_OVFL)
-		pr_err("vfe31_irq: af/bf stats bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_STATS_AWB_BUS_OVFL)
-		pr_err("vfe31_irq: awb stats bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_STATS_RS_BUS_OVFL)
-		pr_err("vfe31_irq: rs stats bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_STATS_CS_BUS_OVFL)
-		pr_err("vfe31_irq: cs stats bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_STATS_IHIST_BUS_OVFL)
-		pr_err("vfe31_irq: ihist stats bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_STATS_SKIN_BHIST_BUS_OVFL)
-		pr_err("vfe31_irq: skin/bhist stats bus overflow\n");
-
-	if (errStatus & VFE31_IMASK_AXI_ERROR) {
-		pr_err("vfe31_irq: axi error\n");
-		/* read status too when overflow happens.*/
-		read_val = msm_camera_io_r(vfe31_ctrl->vfebase +
-			VFE_BUS_PING_PONG_STATUS);
-		pr_debug("VFE_BUS_PING_PONG_STATUS = 0x%x\n", read_val);
-		read_val = msm_camera_io_r(vfe31_ctrl->vfebase +
-			VFE_BUS_OPERATION_STATUS);
-		pr_debug("VFE_BUS_OPERATION_STATUS = 0x%x\n", read_val);
-		read_val = msm_camera_io_r(vfe31_ctrl->vfebase +
-			VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_0);
-		pr_debug("VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_0 = 0x%x\n",
-			read_val);
-		read_val = msm_camera_io_r(vfe31_ctrl->vfebase +
-			VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_1);
-		pr_debug("VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_1 = 0x%x\n",
-			read_val);
-		read_val = msm_camera_io_r(vfe31_ctrl->vfebase +
-			VFE_AXI_STATUS);
-		pr_debug("VFE_AXI_STATUS = 0x%x\n", read_val);
-	}
-}
-static void vfe_send_outmsg(struct v4l2_subdev *sd, uint8_t msgid,
-	uint32_t ch0_paddr, uint32_t ch1_paddr,
-	uint32_t ch2_paddr, uint32_t inst_handle)
-{
-	struct isp_msg_output msg;
-
-	msg.output_id		= msgid;
-	msg.buf.inst_handle	= inst_handle;
-	msg.buf.ch_paddr[0]	= ch0_paddr;
-	msg.buf.ch_paddr[1]	= ch1_paddr;
-	msg.buf.ch_paddr[2]	= ch2_paddr;
-	msg.frameCounter	= vfe31_ctrl->vfeFrameId;
-
-	v4l2_subdev_notify(&vfe31_ctrl->subdev,
-		NOTIFY_VFE_MSG_OUT, &msg);
-	return;
-}
-
-static void vfe31_process_output_path_irq_0(void)
-{
-	uint32_t ping_pong;
-	uint32_t ch0_paddr, ch1_paddr, ch2_paddr;
-	uint8_t out_bool = 0;
-	struct msm_free_buf *free_buf = NULL;
-
-	free_buf = vfe31_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
-		VFE_MSG_OUTPUT_PRIMARY);
-
-	/* we render frames in the following conditions:
-	 * 1. Continuous mode and the free buffer is avaialable.
-	 * 2. In snapshot shot mode, free buffer is not always available.
-	 * when pending snapshot count is <=1,  then no need to use
-	 * free buffer.
-	 */
-	out_bool = ((vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN ||
-		vfe31_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB ||
-		vfe31_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG ||
-		vfe31_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB ||
-		vfe31_ctrl->operation_mode == VFE_OUTPUTS_RAW ||
-		vfe31_ctrl->liveshot_state == VFE_STATE_STARTED ||
-		vfe31_ctrl->liveshot_state == VFE_STATE_STOP_REQUESTED ||
-		vfe31_ctrl->liveshot_state == VFE_STATE_STOPPED) &&
-		(vfe31_ctrl->vfe_capture_count <= 1)) || free_buf;
-
-	if (out_bool) {
-		ping_pong = msm_camera_io_r(vfe31_ctrl->vfebase +
-			VFE_BUS_PING_PONG_STATUS);
-
-		/* Channel 0*/
-		ch0_paddr = vfe31_get_ch_addr(ping_pong,
-			vfe31_ctrl->outpath.out0.ch0);
-		/* Channel 1*/
-		ch1_paddr = vfe31_get_ch_addr(ping_pong,
-			vfe31_ctrl->outpath.out0.ch1);
-		/* Channel 2*/
-		ch2_paddr = vfe31_get_ch_addr(ping_pong,
-			vfe31_ctrl->outpath.out0.ch2);
-
-		CDBG("output path 0, ch0 = 0x%x, ch1 = 0x%x, ch2 = 0x%x\n",
-			ch0_paddr, ch1_paddr, ch2_paddr);
-		if (free_buf) {
-			/* Y channel */
-			vfe31_put_ch_addr(ping_pong,
-			vfe31_ctrl->outpath.out0.ch0,
-			free_buf->ch_paddr[0]);
-			/* Chroma channel */
-			vfe31_put_ch_addr(ping_pong,
-			vfe31_ctrl->outpath.out0.ch1,
-			free_buf->ch_paddr[1]);
-			if (free_buf->num_planes > 2)
-				vfe31_put_ch_addr(ping_pong,
-					vfe31_ctrl->outpath.out0.ch2,
-					free_buf->ch_paddr[2]);
-		}
-		if (vfe31_ctrl->operation_mode ==
-				VFE_OUTPUTS_THUMB_AND_MAIN ||
-			vfe31_ctrl->operation_mode ==
-				VFE_OUTPUTS_MAIN_AND_THUMB ||
-			vfe31_ctrl->operation_mode ==
-				VFE_OUTPUTS_THUMB_AND_JPEG ||
-			vfe31_ctrl->operation_mode ==
-				VFE_OUTPUTS_JPEG_AND_THUMB ||
-			vfe31_ctrl->operation_mode ==
-				VFE_OUTPUTS_RAW ||
-			vfe31_ctrl->liveshot_state == VFE_STATE_STOPPED)
-			vfe31_ctrl->outpath.out0.capture_cnt--;
-
-		vfe_send_outmsg(&vfe31_ctrl->subdev,
-			MSG_ID_OUTPUT_PRIMARY, ch0_paddr,
-			ch1_paddr, ch2_paddr,
-			vfe31_ctrl->outpath.out0.inst_handle);
-
-		if (vfe31_ctrl->liveshot_state == VFE_STATE_STOPPED)
-			vfe31_ctrl->liveshot_state = VFE_STATE_IDLE;
-
-	} else {
-		vfe31_ctrl->outpath.out0.frame_drop_cnt++;
-		CDBG("path_irq_0 - no free buffer!\n");
-	}
-}
-
-static void vfe31_process_output_path_irq_1(void)
-{
-	uint32_t ping_pong;
-	uint32_t ch0_paddr, ch1_paddr, ch2_paddr;
-	/* this must be snapshot main image output. */
-	uint8_t out_bool = 0;
-	struct msm_free_buf *free_buf = NULL;
-
-	free_buf = vfe31_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
-		VFE_MSG_OUTPUT_SECONDARY);
-	out_bool = ((vfe31_ctrl->operation_mode ==
-				VFE_OUTPUTS_THUMB_AND_MAIN ||
-			vfe31_ctrl->operation_mode ==
-				VFE_OUTPUTS_MAIN_AND_THUMB ||
-			vfe31_ctrl->operation_mode ==
-				VFE_OUTPUTS_RAW ||
-			vfe31_ctrl->operation_mode ==
-				VFE_OUTPUTS_JPEG_AND_THUMB) &&
-			(vfe31_ctrl->vfe_capture_count <= 1)) || free_buf;
-
-	if (out_bool) {
-		ping_pong = msm_camera_io_r(vfe31_ctrl->vfebase +
-			VFE_BUS_PING_PONG_STATUS);
-
-		/* Y channel */
-		ch0_paddr = vfe31_get_ch_addr(ping_pong,
-			vfe31_ctrl->outpath.out1.ch0);
-		/* Chroma channel */
-		ch1_paddr = vfe31_get_ch_addr(ping_pong,
-			vfe31_ctrl->outpath.out1.ch1);
-		ch2_paddr = vfe31_get_ch_addr(ping_pong,
-			vfe31_ctrl->outpath.out1.ch2);
-
-		pr_debug("%s ch0 = 0x%x, ch1 = 0x%x, ch2 = 0x%x\n",
-			__func__, ch0_paddr, ch1_paddr, ch2_paddr);
-		if (free_buf) {
-			/* Y channel */
-			vfe31_put_ch_addr(ping_pong,
-			vfe31_ctrl->outpath.out1.ch0,
-			free_buf->ch_paddr[0]);
-			/* Chroma channel */
-			vfe31_put_ch_addr(ping_pong,
-			vfe31_ctrl->outpath.out1.ch1,
-			free_buf->ch_paddr[1]);
-			if (free_buf->num_planes > 2)
-				vfe31_put_ch_addr(ping_pong,
-					vfe31_ctrl->outpath.out1.ch2,
-					free_buf->ch_paddr[2]);
-		}
-		if (vfe31_ctrl->operation_mode ==
-				VFE_OUTPUTS_THUMB_AND_MAIN ||
-			vfe31_ctrl->operation_mode ==
-				VFE_OUTPUTS_MAIN_AND_THUMB ||
-			vfe31_ctrl->operation_mode ==
-				VFE_OUTPUTS_RAW ||
-			vfe31_ctrl->operation_mode ==
-				VFE_OUTPUTS_JPEG_AND_THUMB)
-			vfe31_ctrl->outpath.out1.capture_cnt--;
-
-		vfe_send_outmsg(&vfe31_ctrl->subdev,
-			MSG_ID_OUTPUT_SECONDARY, ch0_paddr,
-			ch1_paddr, ch2_paddr,
-			vfe31_ctrl->outpath.out1.inst_handle);
-	} else {
-		vfe31_ctrl->outpath.out1.frame_drop_cnt++;
-		CDBG("path_irq_1 - no free buffer!\n");
-	}
-}
-
-static uint32_t  vfe31_process_stats_irq_common(uint32_t statsNum,
-	uint32_t newAddr)
-{
-
-	uint32_t pingpongStatus;
-	uint32_t returnAddr;
-	uint32_t pingpongAddr;
-
-	/* must be 0=ping, 1=pong */
-	pingpongStatus =
-		((msm_camera_io_r(vfe31_ctrl->vfebase +
-		VFE_BUS_PING_PONG_STATUS))
-		& ((uint32_t)(1<<(statsNum + 7)))) >> (statsNum + 7);
-	/* stats bits starts at 7 */
-	CDBG("statsNum %d, pingpongStatus %d\n", statsNum, pingpongStatus);
-	pingpongAddr =
-		((uint32_t)(vfe31_ctrl->vfebase +
-		VFE_BUS_STATS_PING_PONG_BASE)) +
-		(3*statsNum)*4 + (1-pingpongStatus)*4;
-	returnAddr = msm_camera_io_r((uint32_t *)pingpongAddr);
-	msm_camera_io_w(newAddr, (uint32_t *)pingpongAddr);
-	return returnAddr;
-}
-
-static void
-vfe_send_stats_msg(uint32_t bufAddress, uint32_t statsNum)
-{
-	int rc = 0;
-	void *vaddr = NULL;
-	/* fill message with right content. */
-	/* @todo This is causing issues, need further investigate */
-	/* spin_lock_irqsave(&ctrl->state_lock, flags); */
-	struct isp_msg_stats msgStats;
-	msgStats.frameCounter = vfe31_ctrl->vfeFrameId;
-	msgStats.buffer = bufAddress;
-
-	switch (statsNum) {
-	case STATS_AE_NUM:{
-		msgStats.id = MSG_ID_STATS_AEC;
-		rc = vfe31_ctrl->stats_ops.dispatch(
-				vfe31_ctrl->stats_ops.stats_ctrl,
-				MSM_STATS_TYPE_AEC,	bufAddress,
-				&msgStats.buf_idx, &vaddr, &msgStats.fd,
-				vfe31_ctrl->stats_ops.client);
-		}
-		break;
-	case STATS_AF_NUM:{
-		msgStats.id = MSG_ID_STATS_AF;
-		rc = vfe31_ctrl->stats_ops.dispatch(
-				vfe31_ctrl->stats_ops.stats_ctrl,
-				MSM_STATS_TYPE_AF, bufAddress,
-				&msgStats.buf_idx, &vaddr, &msgStats.fd,
-				vfe31_ctrl->stats_ops.client);
-		}
-		break;
-	case STATS_AWB_NUM: {
-		msgStats.id = MSG_ID_STATS_AWB;
-		rc = vfe31_ctrl->stats_ops.dispatch(
-				vfe31_ctrl->stats_ops.stats_ctrl,
-				MSM_STATS_TYPE_AWB, bufAddress,
-				&msgStats.buf_idx, &vaddr, &msgStats.fd,
-				vfe31_ctrl->stats_ops.client);
-		}
-		break;
-
-	case STATS_IHIST_NUM: {
-		msgStats.id = MSG_ID_STATS_IHIST;
-		rc = vfe31_ctrl->stats_ops.dispatch(
-				vfe31_ctrl->stats_ops.stats_ctrl,
-				MSM_STATS_TYPE_IHIST, bufAddress,
-				&msgStats.buf_idx, &vaddr, &msgStats.fd,
-				vfe31_ctrl->stats_ops.client);
-		}
-		break;
-	case STATS_RS_NUM: {
-		msgStats.id = MSG_ID_STATS_RS;
-		rc = vfe31_ctrl->stats_ops.dispatch(
-				vfe31_ctrl->stats_ops.stats_ctrl,
-				MSM_STATS_TYPE_RS, bufAddress,
-				&msgStats.buf_idx, &vaddr, &msgStats.fd,
-				vfe31_ctrl->stats_ops.client);
-		}
-		break;
-	case STATS_CS_NUM: {
-		msgStats.id = MSG_ID_STATS_CS;
-		rc = vfe31_ctrl->stats_ops.dispatch(
-				vfe31_ctrl->stats_ops.stats_ctrl,
-				MSM_STATS_TYPE_CS, bufAddress,
-				&msgStats.buf_idx, &vaddr, &msgStats.fd,
-				vfe31_ctrl->stats_ops.client);
-		}
-		break;
-
-	default:
-		goto stats_done;
-	}
-	if (rc == 0) {
-		msgStats.buffer = (uint32_t)vaddr;
-		v4l2_subdev_notify(&vfe31_ctrl->subdev,
-			NOTIFY_VFE_MSG_STATS, &msgStats);
-	} else {
-		pr_err("%s: paddr to idx mapping error, stats_id = %d,\n"
-			"paddr = 0x%d\n", __func__,
-			 msgStats.id, msgStats.buffer);
-	}
-stats_done:
-	/* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
-	return;
-}
-
-static void vfe_send_comp_stats_msg(uint32_t status_bits)
-{
-	struct msm_stats_buf msgStats;
-	uint32_t temp;
-
-	msgStats.frame_id = vfe31_ctrl->vfeFrameId;
-	msgStats.status_bits = status_bits;
-
-	msgStats.aec.buff = vfe31_ctrl->aecStatsControl.bufToRender;
-	msgStats.awb.buff = vfe31_ctrl->awbStatsControl.bufToRender;
-	msgStats.af.buff = vfe31_ctrl->afStatsControl.bufToRender;
-
-	msgStats.ihist.buff = vfe31_ctrl->ihistStatsControl.bufToRender;
-	msgStats.rs.buff = vfe31_ctrl->rsStatsControl.bufToRender;
-	msgStats.cs.buff = vfe31_ctrl->csStatsControl.bufToRender;
-
-	temp = msm_camera_io_r(vfe31_ctrl->vfebase + VFE_STATS_AWB_SGW_CFG);
-	msgStats.awb_ymin = (0xFF00 & temp) >> 8;
-
-	v4l2_subdev_notify(&vfe31_ctrl->subdev,
-		NOTIFY_VFE_MSG_COMP_STATS, &msgStats);
-}
-
-static void vfe31_process_stats_ae_irq(void)
-{
-	unsigned long flags;
-	uint32_t addr;
-	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_AEC);
-	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
-	if (addr) {
-		vfe31_ctrl->aecStatsControl.bufToRender =
-			vfe31_process_stats_irq_common(STATS_AE_NUM,
-			addr);
-
-		vfe_send_stats_msg(vfe31_ctrl->aecStatsControl.bufToRender,
-			STATS_AE_NUM);
-	} else{
-		vfe31_ctrl->aecStatsControl.droppedStatsFrameCount++;
-		CDBG("%s: droppedStatsFrameCount = %d", __func__,
-			vfe31_ctrl->aecStatsControl.droppedStatsFrameCount);
-	}
-}
-
-static void vfe31_process_stats_awb_irq(void)
-{
-	unsigned long flags;
-	uint32_t addr;
-	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_AWB);
-	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
-	if (addr) {
-		vfe31_ctrl->awbStatsControl.bufToRender =
-			vfe31_process_stats_irq_common(STATS_AWB_NUM,
-			addr);
-
-		vfe_send_stats_msg(vfe31_ctrl->awbStatsControl.bufToRender,
-			STATS_AWB_NUM);
-	} else{
-		vfe31_ctrl->awbStatsControl.droppedStatsFrameCount++;
-		CDBG("%s: droppedStatsFrameCount = %d", __func__,
-			vfe31_ctrl->awbStatsControl.droppedStatsFrameCount);
-	}
-}
-
-static void vfe31_process_stats_af_irq(void)
-{
-	unsigned long flags;
-	uint32_t addr;
-	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_AF);
-	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
-	if (addr) {
-		vfe31_ctrl->afStatsControl.bufToRender =
-			vfe31_process_stats_irq_common(STATS_AF_NUM,
-			addr);
-
-		vfe_send_stats_msg(vfe31_ctrl->afStatsControl.bufToRender,
-			STATS_AF_NUM);
-	} else{
-		vfe31_ctrl->afStatsControl.droppedStatsFrameCount++;
-		CDBG("%s: droppedStatsFrameCount = %d", __func__,
-			vfe31_ctrl->afStatsControl.droppedStatsFrameCount);
-	}
-}
-
-static void vfe31_process_stats_ihist_irq(void)
-{
-	unsigned long flags;
-	uint32_t addr;
-	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_IHIST);
-	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
-	if (addr) {
-		vfe31_ctrl->ihistStatsControl.bufToRender =
-			  vfe31_process_stats_irq_common(STATS_IHIST_NUM,
-				addr);
-		vfe_send_stats_msg(vfe31_ctrl->ihistStatsControl.bufToRender,
-			  STATS_IHIST_NUM);
-	} else {
-		vfe31_ctrl->ihistStatsControl.droppedStatsFrameCount++;
-		CDBG("%s: droppedStatsFrameCount = %d", __func__,
-			 vfe31_ctrl->ihistStatsControl.droppedStatsFrameCount);
-	}
-}
-
-static void vfe31_process_stats_rs_irq(void)
-{
-	unsigned long flags;
-	uint32_t addr;
-	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_RS);
-	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
-	if (addr) {
-		vfe31_ctrl->rsStatsControl.bufToRender =
-			vfe31_process_stats_irq_common(STATS_RS_NUM,
-			addr);
-		vfe_send_stats_msg(vfe31_ctrl->rsStatsControl.bufToRender,
-			STATS_RS_NUM);
-	} else {
-		vfe31_ctrl->rsStatsControl.droppedStatsFrameCount++;
-		CDBG("%s: droppedStatsFrameCount = %d", __func__,
-			vfe31_ctrl->rsStatsControl.droppedStatsFrameCount);
-	}
-}
-
-static void vfe31_process_stats_cs_irq(void)
-{
-	unsigned long flags;
-	uint32_t addr;
-	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_CS);
-	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
-	if (addr) {
-		vfe31_ctrl->csStatsControl.bufToRender =
-			vfe31_process_stats_irq_common(STATS_CS_NUM,
-				addr);
-			vfe_send_stats_msg(
-				vfe31_ctrl->csStatsControl.bufToRender,
-				STATS_CS_NUM);
-	} else {
-		vfe31_ctrl->csStatsControl.droppedStatsFrameCount++;
-		CDBG("%s: droppedStatsFrameCount = %d", __func__,
-			vfe31_ctrl->csStatsControl.droppedStatsFrameCount);
-	}
-}
-
-static void vfe31_process_stats(uint32_t status_bits)
-{
-	unsigned long flags;
-	int32_t process_stats = false;
-	uint32_t addr;
-	CDBG("%s, stats = 0x%x\n", __func__, status_bits);
-
-	spin_lock_irqsave(&vfe31_ctrl->stats_bufq_lock, flags);
-	if (status_bits & VFE_IRQ_STATUS0_STATS_AEC) {
-		addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_AEC);
-		if (addr) {
-			vfe31_ctrl->aecStatsControl.bufToRender =
-				vfe31_process_stats_irq_common(STATS_AE_NUM,
-				addr);
-			process_stats = true;
-		} else{
-			vfe31_ctrl->aecStatsControl.bufToRender = 0;
-			vfe31_ctrl->aecStatsControl.droppedStatsFrameCount++;
-		}
-	} else {
-		vfe31_ctrl->aecStatsControl.bufToRender = 0;
-	}
-
-	if (status_bits & VFE_IRQ_STATUS0_STATS_AWB) {
-		addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_AWB);
-		if (addr) {
-			vfe31_ctrl->awbStatsControl.bufToRender =
-				vfe31_process_stats_irq_common(STATS_AWB_NUM,
-				addr);
-			process_stats = true;
-		} else{
-			vfe31_ctrl->awbStatsControl.droppedStatsFrameCount++;
-			vfe31_ctrl->awbStatsControl.bufToRender = 0;
-		}
-	} else {
-		vfe31_ctrl->awbStatsControl.bufToRender = 0;
-	}
-
-
-	if (status_bits & VFE_IRQ_STATUS0_STATS_AF) {
-		addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_AF);
-		if (addr) {
-			vfe31_ctrl->afStatsControl.bufToRender =
-				vfe31_process_stats_irq_common(STATS_AF_NUM,
-				addr);
-			process_stats = true;
-		} else {
-			vfe31_ctrl->afStatsControl.bufToRender = 0;
-			vfe31_ctrl->afStatsControl.droppedStatsFrameCount++;
-		}
-	} else {
-		vfe31_ctrl->afStatsControl.bufToRender = 0;
-	}
-
-	if (status_bits & VFE_IRQ_STATUS0_STATS_IHIST) {
-		addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_IHIST);
-		if (addr) {
-			vfe31_ctrl->ihistStatsControl.bufToRender =
-				vfe31_process_stats_irq_common(STATS_IHIST_NUM,
-				addr);
-			process_stats = true;
-		} else {
-			vfe31_ctrl->ihistStatsControl.droppedStatsFrameCount++;
-			vfe31_ctrl->ihistStatsControl.bufToRender = 0;
-		}
-	} else {
-		vfe31_ctrl->ihistStatsControl.bufToRender = 0;
-	}
-
-	if (status_bits & VFE_IRQ_STATUS0_STATS_RS) {
-		addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_RS);
-		if (!addr) {
-			vfe31_ctrl->rsStatsControl.bufToRender =
-				vfe31_process_stats_irq_common(STATS_RS_NUM,
-				addr);
-			process_stats = true;
-		} else {
-			vfe31_ctrl->rsStatsControl.droppedStatsFrameCount++;
-			vfe31_ctrl->rsStatsControl.bufToRender = 0;
-		}
-	} else {
-		vfe31_ctrl->rsStatsControl.bufToRender = 0;
-	}
-
-
-	if (status_bits & VFE_IRQ_STATUS0_STATS_CS) {
-		addr = (uint32_t)vfe31_stats_dqbuf(MSM_STATS_TYPE_CS);
-		if (addr) {
-			vfe31_ctrl->csStatsControl.bufToRender =
-				vfe31_process_stats_irq_common(STATS_CS_NUM,
-				addr);
-			process_stats = true;
-		} else {
-			vfe31_ctrl->csStatsControl.droppedStatsFrameCount++;
-			vfe31_ctrl->csStatsControl.bufToRender = 0;
-		}
-	} else {
-		vfe31_ctrl->csStatsControl.bufToRender = 0;
-	}
-
-	spin_unlock_irqrestore(&vfe31_ctrl->stats_bufq_lock, flags);
-	if (process_stats)
-		vfe_send_comp_stats_msg(status_bits);
-
-	return;
-}
-
-static long vfe_stats_bufq_sub_ioctl(struct msm_vfe_cfg_cmd *cmd,
-	void *ion_client, int domain_num)
-{
-	long rc = 0;
-	switch (cmd->cmd_type) {
-	case VFE_CMD_STATS_REQBUF:
-		if (!vfe31_ctrl->stats_ops.stats_ctrl) {
-			/* stats_ctrl has not been init yet */
-			rc = msm_stats_buf_ops_init(&vfe31_ctrl->stats_ctrl,
-					(struct ion_client *)ion_client,
-					&vfe31_ctrl->stats_ops);
-		if (rc < 0) {
-			pr_err("%s: cannot init stats ops", __func__);
-			goto end;
-		}
-		rc = vfe31_ctrl->stats_ops.stats_ctrl_init(
-				&vfe31_ctrl->stats_ctrl);
-		if (rc < 0) {
-			pr_err("%s: cannot init stats_ctrl ops", __func__);
-			memset(&vfe31_ctrl->stats_ops, 0,
-				sizeof(vfe31_ctrl->stats_ops));
-			goto end;
-		}
-		if (sizeof(struct msm_stats_reqbuf) != cmd->length) {
-			/* error. the length not match */
-			pr_err("%s: stats reqbuf input size = %d,\n"
-				"struct size = %d, mis match\n",
-				 __func__, cmd->length,
-				 sizeof(struct msm_stats_reqbuf));
-			rc = -EINVAL;
-			goto end;
-		}
-	}
-	rc = vfe31_ctrl->stats_ops.reqbuf(&vfe31_ctrl->stats_ctrl,
-			(struct msm_stats_reqbuf *)cmd->value,
-			vfe31_ctrl->stats_ops.client);
-	break;
-	case VFE_CMD_STATS_ENQUEUEBUF:
-		if (sizeof(struct msm_stats_buf_info) != cmd->length) {
-			/* error. the length not match */
-			pr_err("%s: stats enqueuebuf input size = %d,\n"
-				"struct size = %d, mis match\n",
-				__func__, cmd->length,
-				sizeof(struct msm_stats_buf_info));
-			rc = -EINVAL ;
-			goto end;
-		}
-		rc = vfe31_ctrl->stats_ops.enqueue_buf(&vfe31_ctrl->stats_ctrl,
-				(struct msm_stats_buf_info *)cmd->value,
-				vfe31_ctrl->stats_ops.client, domain_num);
-	break;
-	case VFE_CMD_STATS_FLUSH_BUFQ: {
-		struct msm_stats_flush_bufq *flush_req = NULL;
-		flush_req = (struct msm_stats_flush_bufq *)cmd->value;
-		if (sizeof(struct msm_stats_flush_bufq) != cmd->length) {
-			/* error. the length not match */
-			pr_err("%s: stats flush queue input size = %d,\n"
-				"struct size = %d, mitch match\n",
-				__func__, cmd->length,
-				sizeof(struct msm_stats_flush_bufq));
-			rc = -EINVAL ;
-			goto end;
-		}
-		rc = vfe31_ctrl->stats_ops.bufq_flush(&vfe31_ctrl->stats_ctrl,
-				(enum msm_stats_enum_type)flush_req->stats_type,
-				vfe31_ctrl->stats_ops.client);
-	}
-	break;
-	case VFE_CMD_STATS_UNREGBUF:
-	{
-		struct msm_stats_reqbuf *req_buf = NULL;
-		req_buf = (struct msm_stats_reqbuf *)cmd->value;
-		if (sizeof(struct msm_stats_reqbuf) != cmd->length) {
-			/* error. the length not match */
-			pr_err("%s: stats reqbuf input size = %d,\n"
-				"struct size = %d, mitch match\n",
-				 __func__, cmd->length,
-				sizeof(struct msm_stats_reqbuf));
-			rc = -EINVAL ;
-			goto end;
-		}
-		rc = vfe31_stats_unregbuf(req_buf, domain_num);
-	}
-	break;
-	default:
-		rc = -1;
-		pr_err("%s: cmd_type %d not supported", __func__,
-			cmd->cmd_type);
-	break;
-	}
-end:
-	return rc;
-}
-
-static void vfe31_process_stats_irq(uint32_t *irqstatus)
-{
-	uint32_t status_bits = VFE_COM_STATUS & *irqstatus;
-
-	if ((vfe31_ctrl->hfr_mode != HFR_MODE_OFF) &&
-		(vfe31_ctrl->vfeFrameId % vfe31_ctrl->hfr_mode != 0)) {
-		CDBG("Skip the stats when HFR enabled\n");
-		return;
-	}
-
-	vfe31_process_stats(status_bits);
-	return;
-}
-
-static void vfe31_do_tasklet(unsigned long data)
-{
-	unsigned long flags;
-
-	struct vfe31_isr_queue_cmd *qcmd = NULL;
-
-	CDBG("=== vfe31_do_tasklet start ===\n");
-
-	while (atomic_read(&irq_cnt)) {
-		spin_lock_irqsave(&vfe31_ctrl->tasklet_lock, flags);
-		qcmd = list_first_entry(&vfe31_ctrl->tasklet_q,
-			struct vfe31_isr_queue_cmd, list);
-		atomic_sub(1, &irq_cnt);
-
-		if (!qcmd) {
-			spin_unlock_irqrestore(&vfe31_ctrl->tasklet_lock,
-				flags);
-			return;
-		}
-
-		list_del(&qcmd->list);
-		spin_unlock_irqrestore(&vfe31_ctrl->tasklet_lock,
-			flags);
-
-		if (qcmd->vfeInterruptStatus0 &
-			VFE_IRQ_STATUS0_CAMIF_SOF_MASK) {
-			CDBG("irq	camifSofIrq\n");
-			vfe31_process_camif_sof_irq();
-		}
-		/* interrupt to be processed,  *qcmd has the payload.  */
-		if (qcmd->vfeInterruptStatus0 &
-			VFE_IRQ_STATUS0_REG_UPDATE_MASK) {
-			CDBG("irq	regUpdateIrq\n");
-			vfe31_process_reg_update_irq();
-		}
-
-		if (qcmd->vfeInterruptStatus1 &
-			VFE_IMASK_WHILE_STOPPING_1) {
-			CDBG("irq	resetAckIrq\n");
-			vfe31_process_reset_irq();
-		}
-
-		if (atomic_read(&vfe31_ctrl->vstate)) {
-			if (qcmd->vfeInterruptStatus1 &
-				VFE31_IMASK_ERROR_ONLY_1) {
-				pr_err("irq	errorIrq\n");
-				vfe31_process_error_irq(
-					qcmd->vfeInterruptStatus1 &
-					VFE31_IMASK_ERROR_ONLY_1);
-			}
-			/* next, check output path related interrupts. */
-			if (qcmd->vfeInterruptStatus0 &
-				VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK) {
-				CDBG("Image composite done 0 irq occured.\n");
-				vfe31_process_output_path_irq_0();
-			}
-			if (qcmd->vfeInterruptStatus0 &
-				VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK) {
-				CDBG("Image composite done 1 irq occured.\n");
-				vfe31_process_output_path_irq_1();
-			}
-			/* in snapshot mode if done then send
-			snapshot done message */
-			if (vfe31_ctrl->operation_mode ==
-					VFE_OUTPUTS_THUMB_AND_MAIN ||
-				vfe31_ctrl->operation_mode ==
-					VFE_OUTPUTS_MAIN_AND_THUMB ||
-				vfe31_ctrl->operation_mode ==
-					VFE_OUTPUTS_THUMB_AND_JPEG ||
-				vfe31_ctrl->operation_mode ==
-					VFE_OUTPUTS_JPEG_AND_THUMB ||
-				vfe31_ctrl->operation_mode ==
-					VFE_OUTPUTS_RAW) {
-				if ((vfe31_ctrl->outpath.out0.capture_cnt == 0)
-					&& (vfe31_ctrl->outpath.out1.
-					capture_cnt == 0)) {
-					msm_camera_io_w_mb(
-						CAMIF_COMMAND_STOP_IMMEDIATELY,
-						vfe31_ctrl->vfebase +
-						VFE_CAMIF_COMMAND);
-					vfe31_send_isp_msg(vfe31_ctrl,
-						MSG_ID_SNAPSHOT_DONE);
-				}
-			}
-			/* then process stats irq. */
-			if (vfe31_ctrl->stats_comp) {
-				/* process stats comb interrupt. */
-				if (qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK) {
-					CDBG("Stats composite irq occured.\n");
-					vfe31_process_stats_irq(
-						&qcmd->vfeInterruptStatus0);
-				}
-			} else {
-				/* process individual stats interrupt. */
-				if (qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_STATS_AEC) {
-					CDBG("Stats AEC irq occured.\n");
-					vfe31_process_stats_ae_irq();
-				}
-				if (qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_STATS_AWB) {
-					CDBG("Stats AWB irq occured.\n");
-					vfe31_process_stats_awb_irq();
-				}
-				if (qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_STATS_AF) {
-					CDBG("Stats AF irq occured.\n");
-					vfe31_process_stats_af_irq();
-				}
-				if (qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_STATS_IHIST) {
-					CDBG("Stats IHIST irq occured.\n");
-					vfe31_process_stats_ihist_irq();
-				}
-				if (qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_STATS_RS) {
-					CDBG("Stats RS irq occured.\n");
-					vfe31_process_stats_rs_irq();
-				}
-				if (qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_STATS_CS) {
-					CDBG("Stats CS irq occured.\n");
-					vfe31_process_stats_cs_irq();
-				}
-				if (qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_SYNC_TIMER0) {
-					CDBG("SYNC_TIMER 0 irq occured.\n");
-					vfe31_send_isp_msg(vfe31_ctrl,
-						MSG_ID_SYNC_TIMER0_DONE);
-				}
-				if (qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_SYNC_TIMER1) {
-					CDBG("SYNC_TIMER 1 irq occured.\n");
-					vfe31_send_isp_msg(vfe31_ctrl,
-						MSG_ID_SYNC_TIMER1_DONE);
-				}
-				if (qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_SYNC_TIMER2) {
-					CDBG("SYNC_TIMER 2 irq occured.\n");
-					vfe31_send_isp_msg(vfe31_ctrl,
-						MSG_ID_SYNC_TIMER2_DONE);
-				}
-			}
-		}
-		kfree(qcmd);
-	}
-	CDBG("=== vfe31_do_tasklet end ===\n");
-}
-
-DECLARE_TASKLET(vfe31_tasklet, vfe31_do_tasklet, 0);
-
-static irqreturn_t vfe31_parse_irq(int irq_num, void *data)
-{
-	unsigned long flags;
-	struct vfe31_irq_status irq;
-	struct vfe31_isr_queue_cmd *qcmd;
-
-	CDBG("vfe_parse_irq\n");
-
-	vfe31_read_irq_status(&irq);
-
-	if ((irq.vfeIrqStatus0 == 0) && (irq.vfeIrqStatus1 == 0)) {
-		CDBG("vfe_parse_irq: vfeIrqStatus0 & 1 are both 0!\n");
-		return IRQ_HANDLED;
-	}
-
-	qcmd = kzalloc(sizeof(struct vfe31_isr_queue_cmd),
-		GFP_ATOMIC);
-	if (!qcmd) {
-		pr_err("vfe_parse_irq: qcmd malloc failed!\n");
-		return IRQ_HANDLED;
-	}
-
-	spin_lock_irqsave(&vfe31_ctrl->stop_flag_lock, flags);
-	if (vfe31_ctrl->stop_ack_pending) {
-		irq.vfeIrqStatus0 &= VFE_IMASK_WHILE_STOPPING_0;
-		irq.vfeIrqStatus1 &= VFE_IMASK_WHILE_STOPPING_1;
-	}
-	spin_unlock_irqrestore(&vfe31_ctrl->stop_flag_lock, flags);
-
-	CDBG("vfe_parse_irq: Irq_status0 = 0x%x, Irq_status1 = 0x%x.\n",
-		irq.vfeIrqStatus0, irq.vfeIrqStatus1);
-
-	qcmd->vfeInterruptStatus0 = irq.vfeIrqStatus0;
-	qcmd->vfeInterruptStatus1 = irq.vfeIrqStatus1;
-
-	spin_lock_irqsave(&vfe31_ctrl->tasklet_lock, flags);
-	list_add_tail(&qcmd->list, &vfe31_ctrl->tasklet_q);
-
-	atomic_add(1, &irq_cnt);
-	spin_unlock_irqrestore(&vfe31_ctrl->tasklet_lock, flags);
-	tasklet_schedule(&vfe31_tasklet);
-	return IRQ_HANDLED;
-}
-
-static long msm_vfe_subdev_ioctl(struct v4l2_subdev *sd,
-			unsigned int subdev_cmd, void *arg)
-{
-	struct msm_cam_media_controller *pmctl =
-		(struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
-	struct msm_isp_cmd vfecmd;
-	struct msm_camvfe_params *vfe_params;
-	struct msm_vfe_cfg_cmd *cmd;
-	void *data;
-
-	long rc = 0;
-	struct vfe_cmd_stats_buf *scfg = NULL;
-	struct vfe_cmd_stats_ack *sack = NULL;
-
-	if (subdev_cmd == VIDIOC_MSM_VFE_INIT) {
-		CDBG("%s init\n", __func__);
-		return msm_vfe_subdev_init(sd);
-	} else if (subdev_cmd == VIDIOC_MSM_VFE_RELEASE) {
-		msm_vfe_subdev_release(sd);
-		return 0;
-	}
-	vfe_params = (struct msm_camvfe_params *)arg;
-	cmd = vfe_params->vfe_cfg;
-	data = vfe_params->data;
-
-	switch (cmd->cmd_type) {
-	case VFE_CMD_STATS_REQBUF:
-	case VFE_CMD_STATS_ENQUEUEBUF:
-	case VFE_CMD_STATS_FLUSH_BUFQ:
-	case VFE_CMD_STATS_UNREGBUF:
-		/* for easy porting put in one envelope */
-		rc = vfe_stats_bufq_sub_ioctl(cmd, vfe_params->data,
-			pmctl->domain_num);
-		return rc;
-	default:
-		if (cmd->cmd_type != CMD_CONFIG_PING_ADDR &&
-			cmd->cmd_type != CMD_CONFIG_PONG_ADDR &&
-			cmd->cmd_type != CMD_CONFIG_FREE_BUF_ADDR &&
-			cmd->cmd_type != CMD_STATS_AEC_BUF_RELEASE &&
-			cmd->cmd_type != CMD_STATS_AWB_BUF_RELEASE &&
-			cmd->cmd_type != CMD_STATS_IHIST_BUF_RELEASE &&
-			cmd->cmd_type != CMD_STATS_RS_BUF_RELEASE &&
-			cmd->cmd_type != CMD_STATS_CS_BUF_RELEASE &&
-			cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE) {
-				if (copy_from_user(&vfecmd,
-					(void __user *)(cmd->value),
-					sizeof(vfecmd))) {
-						pr_err("%s %d: copy_from_user failed\n",
-						__func__, __LINE__);
-					return -EFAULT;
-				}
-		} else {
-			/* here eith stats release or frame release. */
-			if (cmd->cmd_type != CMD_CONFIG_PING_ADDR &&
-				cmd->cmd_type != CMD_CONFIG_PONG_ADDR &&
-				cmd->cmd_type != CMD_CONFIG_FREE_BUF_ADDR) {
-				/* then must be stats release. */
-				if (!data) {
-					pr_err("%s: data = NULL," \
-						"cmd->cmd_type = %d\n",
-						__func__, cmd->cmd_type);
-					return -EFAULT;
-				}
-				sack = kmalloc(sizeof(struct vfe_cmd_stats_ack),
-							GFP_ATOMIC);
-				if (!sack) {
-					pr_err("%s: no mem for" \
-						"cmd->cmd_type = %d\n",
-						__func__, cmd->cmd_type);
-					return -ENOMEM;
-				}
-
-				sack->nextStatsBuf = *(uint32_t *)data;
-			}
-		}
-
-		CDBG("%s: cmdType = %d\n", __func__, cmd->cmd_type);
-
-		if ((cmd->cmd_type == CMD_STATS_AF_ENABLE)    ||
-			(cmd->cmd_type == CMD_STATS_AWB_ENABLE)   ||
-			(cmd->cmd_type == CMD_STATS_IHIST_ENABLE) ||
-			(cmd->cmd_type == CMD_STATS_RS_ENABLE)    ||
-			(cmd->cmd_type == CMD_STATS_CS_ENABLE)    ||
-			(cmd->cmd_type == CMD_STATS_AEC_ENABLE)) {
-			scfg = NULL;
-			goto vfe31_config_done;
-		}
-		switch (cmd->cmd_type) {
-		case CMD_GENERAL: {
-			rc = vfe31_proc_general(pmctl, &vfecmd);
-			}
-			break;
-		case CMD_CONFIG_PING_ADDR: {
-			int path = *((int *)cmd->value);
-			struct vfe31_output_ch *outch = vfe31_get_ch(path);
-			outch->ping = *((struct msm_free_buf *)data);
-			}
-			break;
-
-		case CMD_CONFIG_PONG_ADDR: {
-			int path = *((int *)cmd->value);
-			struct vfe31_output_ch *outch = vfe31_get_ch(path);
-			outch->pong = *((struct msm_free_buf *)data);
-			}
-			break;
-
-		case CMD_CONFIG_FREE_BUF_ADDR: {
-			int path = *((int *)cmd->value);
-			struct vfe31_output_ch *outch = vfe31_get_ch(path);
-			outch->free_buf = *((struct msm_free_buf *)data);
-			}
-			break;
-
-		case CMD_SNAP_BUF_RELEASE:
-			break;
-
-		case CMD_AXI_CFG_PRIM: {
-			uint32_t *axio = NULL;
-			axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-			if (!axio) {
-				rc = -ENOMEM;
-				break;
-			}
-
-			if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
-				kfree(axio);
-				rc = -EFAULT;
-				break;
-			}
-			vfe31_config_axi(OUTPUT_PRIM, axio);
-			kfree(axio);
-			}
-			break;
-
-		case CMD_AXI_CFG_PRIM_ALL_CHNLS: {
-			uint32_t *axio = NULL;
-			axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
-					GFP_ATOMIC);
-			if (!axio) {
-				rc = -ENOMEM;
-				break;
-			}
-
-			if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
-				kfree(axio);
-				rc = -EFAULT;
-				break;
-			}
-			vfe31_config_axi(OUTPUT_PRIM_ALL_CHNLS, axio);
-			kfree(axio);
-		}
-			break;
-
-		case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC: {
-			uint32_t *axio = NULL;
-			axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
-					GFP_ATOMIC);
-			if (!axio) {
-				rc = -ENOMEM;
-				break;
-			}
-
-			if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
-				kfree(axio);
-				rc = -EFAULT;
-				break;
-			}
-			vfe31_config_axi(OUTPUT_PRIM|OUTPUT_SEC, axio);
-			kfree(axio);
-			}
-			break;
-
-		case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC_ALL_CHNLS: {
-			uint32_t *axio = NULL;
-			axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
-					GFP_ATOMIC);
-			if (!axio) {
-				rc = -ENOMEM;
-				break;
-			}
-
-			if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
-				kfree(axio);
-				rc = -EFAULT;
-				break;
-			}
-			vfe31_config_axi
-				(OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS, axio);
-			kfree(axio);
-			}
-			break;
-
-		case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC: {
-			uint32_t *axio = NULL;
-			axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-			if (!axio) {
-				rc = -ENOMEM;
-				break;
-			}
-
-			if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
-				kfree(axio);
-				rc = -EFAULT;
-				break;
-			}
-			vfe31_config_axi
-				(OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC, axio);
-			kfree(axio);
-			}
-			break;
-
-		case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC_ALL_CHNLS: {
-			pr_err("%s Invalid/Unsupported AXI configuration %x",
-				__func__, cmd->cmd_type);
-			}
-			break;
-
-		case CMD_AXI_START:
-			/* No need to decouple AXI/VFE for VFE3.1*/
-			break;
-
-		case CMD_AXI_STOP:
-			/* No need to decouple AXI/VFE for VFE3.1*/
-			break;
-
-		case CMD_AXI_RESET:
-			/* No need to decouple AXI/VFE for VFE3.1*/
-			break;
-
-		default:
-			pr_err("%s Unsupported AXI configuration %x ", __func__,
-				cmd->cmd_type);
-			break;
-		}
-	}
-vfe31_config_done:
-	kfree(scfg);
-	kfree(sack);
-	CDBG("%s done: rc = %d\n", __func__, (int) rc);
-	return rc;
-}
-
-static int msm_vfe_subdev_s_crystal_freq(struct v4l2_subdev *sd,
-	u32 freq, u32 flags)
-{
-	int rc = 0;
-	int round_rate;
-
-	round_rate = clk_round_rate(vfe31_ctrl->vfe_clk[0], freq);
-	if (rc < 0) {
-		pr_err("%s: clk_round_rate failed %d\n",
-			__func__, rc);
-		return rc;
-	}
-
-	vfe_clk_rate = round_rate;
-	rc = clk_set_rate(vfe31_ctrl->vfe_clk[0], round_rate);
-	if (rc < 0)
-		pr_err("%s: clk_set_rate failed %d\n",
-			__func__, rc);
-
-	return rc;
-}
-
-static const struct v4l2_subdev_video_ops msm_vfe_subdev_video_ops = {
-	.s_crystal_freq = msm_vfe_subdev_s_crystal_freq,
-};
-
-static const struct v4l2_subdev_core_ops msm_vfe_subdev_core_ops = {
-	.ioctl = msm_vfe_subdev_ioctl,
-};
-
-static const struct v4l2_subdev_ops msm_vfe_subdev_ops = {
-	.core = &msm_vfe_subdev_core_ops,
-	.video = &msm_vfe_subdev_video_ops,
-};
-
-static struct msm_cam_clk_info vfe_clk_info[] = {
-	{"vfe_clk", VFE_CLK_RATE},
-	{"vfe_pclk", -1},
-};
-
-static struct msm_cam_clk_info vfe_camif_clk_info[] = {
-	{"camif_pad_pclk", -1},
-	{"vfe_camif_clk", -1},
-};
-
-static void msm_vfe_camio_clk_sel(enum msm_camio_clk_src_type srctype)
-{
-	struct clk *clk = NULL;
-
-	clk = vfe31_ctrl->vfe_clk[0];
-
-	if (clk != NULL) {
-		switch (srctype) {
-		case MSM_CAMIO_CLK_SRC_INTERNAL:
-			clk_set_flags(clk, 0x00000100 << 1);
-			break;
-
-		case MSM_CAMIO_CLK_SRC_EXTERNAL:
-			clk_set_flags(clk, 0x00000100);
-			break;
-
-		default:
-			break;
-		}
-	}
-}
-
-static void msm_vfe_camif_pad_reg_reset(void)
-{
-	uint32_t reg;
-
-	msm_vfe_camio_clk_sel(MSM_CAMIO_CLK_SRC_INTERNAL);
-	usleep_range(10000, 15000);
-
-	reg = (msm_camera_io_r(vfe31_ctrl->camifbase)) & CAMIF_CFG_RMSK;
-	reg |= 0x3;
-	msm_camera_io_w(reg, vfe31_ctrl->camifbase);
-	usleep_range(10000, 15000);
-
-	reg = (msm_camera_io_r(vfe31_ctrl->camifbase)) & CAMIF_CFG_RMSK;
-	reg |= 0x10;
-	msm_camera_io_w(reg, vfe31_ctrl->camifbase);
-	usleep_range(10000, 15000);
-
-	reg = (msm_camera_io_r(vfe31_ctrl->camifbase)) & CAMIF_CFG_RMSK;
-	/* Need to be uninverted*/
-	reg &= 0x03;
-	msm_camera_io_w(reg, vfe31_ctrl->camifbase);
-	usleep_range(10000, 15000);
-}
-
-int msm_vfe_subdev_init(struct v4l2_subdev *sd)
-{
-	int rc = 0;
-	struct msm_cam_media_controller *mctl;
-	mctl = v4l2_get_subdev_hostdata(sd);
-	if (mctl == NULL) {
-		rc = -EINVAL;
-		goto mctl_failed;
-	}
-
-	spin_lock_init(&vfe31_ctrl->stop_flag_lock);
-	spin_lock_init(&vfe31_ctrl->state_lock);
-	spin_lock_init(&vfe31_ctrl->stats_bufq_lock);
-	spin_lock_init(&vfe31_ctrl->io_lock);
-	spin_lock_init(&vfe31_ctrl->update_ack_lock);
-	spin_lock_init(&vfe31_ctrl->tasklet_lock);
-	spin_lock_init(&vfe31_ctrl->sd_notify_lock);
-	INIT_LIST_HEAD(&vfe31_ctrl->tasklet_q);
-
-	memset(&vfe31_ctrl->stats_ctrl, 0, sizeof(struct msm_stats_bufq_ctrl));
-	memset(&vfe31_ctrl->stats_ops, 0, sizeof(struct msm_stats_ops));
-
-	vfe31_ctrl->update_linear = false;
-	vfe31_ctrl->update_rolloff = false;
-	vfe31_ctrl->update_la = false;
-	vfe31_ctrl->update_gamma = false;
-	vfe31_ctrl->hfr_mode = HFR_MODE_OFF;
-
-	vfe31_ctrl->vfebase = ioremap(vfe31_ctrl->vfemem->start,
-		resource_size(vfe31_ctrl->vfemem));
-	if (!vfe31_ctrl->vfebase) {
-		rc = -ENOMEM;
-		pr_err("%s: vfe ioremap failed\n", __func__);
-		goto vfe_remap_failed;
-	}
-	if (!mctl->sdata->csi_if) {
-		vfe31_ctrl->camifbase = ioremap(vfe31_ctrl->camifmem->start,
-			resource_size(vfe31_ctrl->camifmem));
-		if (!vfe31_ctrl->camifbase) {
-			rc = -ENOMEM;
-			pr_err("%s: camif ioremap failed\n", __func__);
-			goto camif_remap_failed;
-		}
-	}
-
-	if (vfe31_ctrl->fs_vfe) {
-		rc = regulator_enable(vfe31_ctrl->fs_vfe);
-		if (rc) {
-			pr_err("%s: Regulator FS_VFE enable failed\n",
-							__func__);
-			goto vfe_fs_failed;
-		}
-	}
-
-	rc = msm_cam_clk_enable(&vfe31_ctrl->pdev->dev, vfe_clk_info,
-		vfe31_ctrl->vfe_clk, ARRAY_SIZE(vfe_clk_info), 1);
-	if (rc < 0)
-		goto vfe_clk_enable_failed;
-
-	if (!mctl->sdata->csi_if) {
-		rc = msm_cam_clk_enable(&vfe31_ctrl->pdev->dev,
-			vfe_camif_clk_info,
-			vfe31_ctrl->vfe_camif_clk,
-			ARRAY_SIZE(vfe_camif_clk_info), 1);
-		if (rc < 0)
-			goto vfe_camif_clk_enable_failed;
-		msm_vfe_camif_pad_reg_reset();
-	}
-
-#ifdef CONFIG_MSM_IOMMU
-	rc = iommu_attach_device(mctl->domain, vfe31_ctrl->iommu_ctx_imgwr);
-	if (rc < 0) {
-		rc = -ENODEV;
-		pr_err("%s: Device attach failed\n", __func__);
-		goto device_imgwr_attach_failed;
-	}
-	rc = iommu_attach_device(mctl->domain, vfe31_ctrl->iommu_ctx_misc);
-	if (rc < 0) {
-		rc = -ENODEV;
-		pr_err("%s: Device attach failed\n", __func__);
-		goto device_misc_attach_failed;
-	}
-#endif
-
-	msm_camio_bus_scale_cfg(
-		mctl->sdata->pdata->cam_bus_scale_table, S_INIT);
-	msm_camio_bus_scale_cfg(
-		mctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
-	vfe31_ctrl->register_total = VFE31_REGISTER_TOTAL;
-
-	enable_irq(vfe31_ctrl->vfeirq->start);
-
-	return rc;
-
-#ifdef CONFIG_MSM_IOMMU
-device_misc_attach_failed:
-	iommu_detach_device(mctl->domain, vfe31_ctrl->iommu_ctx_imgwr);
-device_imgwr_attach_failed:
-#endif
-	if (!mctl->sdata->csi_if)
-		msm_cam_clk_enable(&vfe31_ctrl->pdev->dev,
-			vfe_camif_clk_info,
-			vfe31_ctrl->vfe_camif_clk,
-			ARRAY_SIZE(vfe_camif_clk_info), 0);
-vfe_camif_clk_enable_failed:
-	msm_cam_clk_enable(&vfe31_ctrl->pdev->dev, vfe_clk_info,
-		vfe31_ctrl->vfe_clk, ARRAY_SIZE(vfe_clk_info), 0);
-vfe_clk_enable_failed:
-	regulator_disable(vfe31_ctrl->fs_vfe);
-vfe_fs_failed:
-	if (!mctl->sdata->csi_if)
-		iounmap(vfe31_ctrl->camifbase);
-camif_remap_failed:
-	iounmap(vfe31_ctrl->vfebase);
-vfe_remap_failed:
-mctl_failed:
-	return rc;
-}
-
-void msm_vfe_subdev_release(struct v4l2_subdev *sd)
-{
-	struct msm_cam_media_controller *pmctl =
-		(struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
-	disable_irq(vfe31_ctrl->vfeirq->start);
-	tasklet_kill(&vfe31_tasklet);
-
-#ifdef CONFIG_MSM_IOMMU
-	iommu_detach_device(pmctl->domain, vfe31_ctrl->iommu_ctx_misc);
-	iommu_detach_device(pmctl->domain, vfe31_ctrl->iommu_ctx_imgwr);
-#endif
-
-	if (!pmctl->sdata->csi_if)
-		msm_cam_clk_enable(&vfe31_ctrl->pdev->dev,
-			vfe_camif_clk_info,
-			vfe31_ctrl->vfe_camif_clk,
-			ARRAY_SIZE(vfe_camif_clk_info), 0);
-
-	msm_cam_clk_enable(&vfe31_ctrl->pdev->dev, vfe_clk_info,
-		vfe31_ctrl->vfe_clk, ARRAY_SIZE(vfe_clk_info), 0);
-
-	if (vfe31_ctrl->fs_vfe)
-		regulator_disable(vfe31_ctrl->fs_vfe);
-
-	CDBG("%s Releasing resources\n", __func__);
-	if (!pmctl->sdata->csi_if)
-		iounmap(vfe31_ctrl->camifbase);
-	iounmap(vfe31_ctrl->vfebase);
-
-	if (atomic_read(&irq_cnt))
-		pr_warning("%s, Warning IRQ Count not ZERO\n", __func__);
-
-	msm_camio_bus_scale_cfg(
-		pmctl->sdata->pdata->cam_bus_scale_table, S_EXIT);
-}
-
-static const struct v4l2_subdev_internal_ops msm_vfe_internal_ops;
-
-static int __devinit vfe31_probe(struct platform_device *pdev)
-{
-	int rc = 0;
-	struct msm_cam_subdev_info sd_info;
-
-	CDBG("%s: device id = %d\n", __func__, pdev->id);
-
-	vfe31_ctrl = kzalloc(sizeof(struct vfe31_ctrl_type), GFP_KERNEL);
-	if (!vfe31_ctrl) {
-		pr_err("%s: no enough memory\n", __func__);
-		return -ENOMEM;
-	}
-
-	v4l2_subdev_init(&vfe31_ctrl->subdev, &msm_vfe_subdev_ops);
-	vfe31_ctrl->subdev.internal_ops = &msm_vfe_internal_ops;
-	vfe31_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-	snprintf(vfe31_ctrl->subdev.name,
-			 sizeof(vfe31_ctrl->subdev.name), "vfe3.1");
-	v4l2_set_subdevdata(&vfe31_ctrl->subdev, vfe31_ctrl);
-	platform_set_drvdata(pdev, &vfe31_ctrl->subdev);
-
-	vfe31_ctrl->vfemem = platform_get_resource_byname(pdev,
-		IORESOURCE_MEM, "msm_vfe");
-	if (!vfe31_ctrl->vfemem) {
-		pr_err("%s: no mem resource?\n", __func__);
-		rc = -ENODEV;
-		goto vfe31_no_resource;
-	}
-	vfe31_ctrl->vfeirq = platform_get_resource_byname(pdev,
-		IORESOURCE_IRQ, "msm_vfe");
-	if (!vfe31_ctrl->vfeirq) {
-		pr_err("%s: no irq resource?\n", __func__);
-		rc = -ENODEV;
-		goto vfe31_no_resource;
-	}
-	vfe31_ctrl->camifmem = platform_get_resource_byname(pdev,
-		IORESOURCE_MEM, "msm_camif");
-	if (!vfe31_ctrl->camifmem)
-		pr_err("%s: camif not supported\n", __func__);
-
-	vfe31_ctrl->vfeio = request_mem_region(vfe31_ctrl->vfemem->start,
-		resource_size(vfe31_ctrl->vfemem), pdev->name);
-	if (!vfe31_ctrl->vfeio) {
-		pr_err("%s: no valid mem region\n", __func__);
-		rc = -EBUSY;
-		goto vfe31_no_resource;
-	}
-
-	if (vfe31_ctrl->camifmem) {
-		vfe31_ctrl->camifio = request_mem_region(
-			vfe31_ctrl->camifmem->start,
-			resource_size(vfe31_ctrl->camifmem), pdev->name);
-		if (!vfe31_ctrl->camifio) {
-			release_mem_region(vfe31_ctrl->vfemem->start,
-				resource_size(vfe31_ctrl->vfemem));
-			pr_err("%s: no valid mem region\n", __func__);
-			rc = -EBUSY;
-			goto vfe31_no_resource;
-		}
-	}
-
-	rc = request_irq(vfe31_ctrl->vfeirq->start, vfe31_parse_irq,
-		IRQF_TRIGGER_RISING, "vfe", 0);
-	if (rc < 0) {
-		if (vfe31_ctrl->camifmem) {
-			release_mem_region(vfe31_ctrl->camifmem->start,
-				resource_size(vfe31_ctrl->camifmem));
-		}
-		release_mem_region(vfe31_ctrl->vfemem->start,
-			resource_size(vfe31_ctrl->vfemem));
-		pr_err("%s: irq request fail\n", __func__);
-		rc = -EBUSY;
-		goto vfe31_no_resource;
-	}
-
-	disable_irq(vfe31_ctrl->vfeirq->start);
-
-#ifdef CONFIG_MSM_IOMMU
-	/*get device context for IOMMU*/
-	vfe31_ctrl->iommu_ctx_imgwr =
-		msm_iommu_get_ctx("vfe_imgwr"); /*re-confirm*/
-	vfe31_ctrl->iommu_ctx_misc =
-		msm_iommu_get_ctx("vfe_misc"); /*re-confirm*/
-	if (!vfe31_ctrl->iommu_ctx_imgwr || !vfe31_ctrl->iommu_ctx_misc) {
-		if (vfe31_ctrl->camifmem) {
-			release_mem_region(vfe31_ctrl->camifmem->start,
-				resource_size(vfe31_ctrl->camifmem));
-		}
-		release_mem_region(vfe31_ctrl->vfemem->start,
-			resource_size(vfe31_ctrl->vfemem));
-		pr_err("%s: No iommu fw context found\n", __func__);
-		rc = -ENODEV;
-		goto vfe31_no_resource;
-	}
-#endif
-
-	vfe31_ctrl->pdev = pdev;
-	vfe31_ctrl->fs_vfe = regulator_get(&vfe31_ctrl->pdev->dev, "vdd");
-	if (IS_ERR(vfe31_ctrl->fs_vfe)) {
-		pr_err("%s: Regulator get failed %ld\n", __func__,
-			PTR_ERR(vfe31_ctrl->fs_vfe));
-		vfe31_ctrl->fs_vfe = NULL;
-	}
-
-	sd_info.sdev_type = VFE_DEV;
-	sd_info.sd_index = 0;
-	sd_info.irq_num = vfe31_ctrl->vfeirq->start;
-	msm_cam_register_subdev_node(&vfe31_ctrl->subdev, &sd_info);
-
-	media_entity_init(&vfe31_ctrl->subdev.entity, 0, NULL, 0);
-	vfe31_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
-	vfe31_ctrl->subdev.entity.group_id = VFE_DEV;
-	vfe31_ctrl->subdev.entity.name = pdev->name;
-	vfe31_ctrl->subdev.entity.revision = vfe31_ctrl->subdev.devnode->num;
-	return 0;
-
-vfe31_no_resource:
-	kfree(vfe31_ctrl);
-	return 0;
-}
-
-static struct platform_driver vfe31_driver = {
-	.probe = vfe31_probe,
-	.driver = {
-	.name = MSM_VFE_DRV_NAME,
-	.owner = THIS_MODULE,
-	},
-};
-
-static int __init msm_vfe31_init_module(void)
-{
-	return platform_driver_register(&vfe31_driver);
-}
-
-static void __exit msm_vfe31_exit_module(void)
-{
-	platform_driver_unregister(&vfe31_driver);
-}
-
-module_init(msm_vfe31_init_module);
-module_exit(msm_vfe31_exit_module);
-MODULE_DESCRIPTION("VFE 3.1 driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/vfe/msm_vfe31_v4l2.h b/drivers/media/video/msm/vfe/msm_vfe31_v4l2.h
deleted file mode 100644
index 97ecd6e..0000000
--- a/drivers/media/video/msm/vfe/msm_vfe31_v4l2.h
+++ /dev/null
@@ -1,955 +0,0 @@
-/* Copyright (c) 2012 Code Aurora Forum. 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 __MSM_VFE31_V4L2_H__
-#define __MSM_VFE31_V4L2_H__
-
-#include <linux/bitops.h>
-#include "msm_vfe_stats_buf.h"
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-/* This defines total number registers in VFE.
- * Each register is 4 bytes so to get the range,
- * multiply this number with 4. */
-#define VFE31_REGISTER_TOTAL 0x0000017F
-
-/* at start of camif,  bit 1:0 = 0x01:enable
- * image data capture at frame boundary. */
-#define CAMIF_COMMAND_START  0x00000005
-
-/* bit 2= 0x1:clear the CAMIF_STATUS register
- * value. */
-#define CAMIF_COMMAND_CLEAR  0x00000004
-
-/* at stop of vfe pipeline, for now it is assumed
- * that camif will stop at any time. Bit 1:0 = 0x10:
- * disable image data capture immediately. */
-#define CAMIF_COMMAND_STOP_IMMEDIATELY  0x00000002
-
-/* at stop of vfe pipeline, for now it is assumed
- * that camif will stop at any time. Bit 1:0 = 0x00:
- * disable image data capture at frame boundary */
-#define CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY  0x00000000
-
-/* to halt axi bridge */
-#define AXI_HALT  0x00000001
-
-/* clear the halt bit. */
-#define AXI_HALT_CLEAR  0x00000000
-
-/* clear axi_halt_irq */
-#define MASK_AXI_HALT_IRQ	0xFF7FFFFF
-
-/* reset the pipeline when stop command is issued.
- * (without reset the register.) bit 26-31 = 0,
- * domain reset, bit 0-9 = 1 for module reset, except
- * register module. */
-#define VFE_RESET_UPON_STOP_CMD  0x000003ef
-
-/* reset the pipeline when reset command.
- * bit 26-31 = 0, domain reset, bit 0-9 = 1 for module reset. */
-#define VFE_RESET_UPON_RESET_CMD  0x000003ff
-
-/* bit 5 is for axi status idle or busy.
- * 1 =  halted,  0 = busy */
-#define AXI_STATUS_BUSY_MASK 0x00000020
-
-/* bit 0 & bit 1 = 1, both y and cbcr irqs need to be present
- * for frame done interrupt */
-#define VFE_COMP_IRQ_BOTH_Y_CBCR 3
-
-/* bit 1 = 1, only cbcr irq triggers frame done interrupt */
-#define VFE_COMP_IRQ_CBCR_ONLY 2
-
-/* bit 0 = 1, only y irq triggers frame done interrupt */
-#define VFE_COMP_IRQ_Y_ONLY 1
-
-/* bit 0 = 1, PM go;   bit1 = 1, PM stop */
-#define VFE_PERFORMANCE_MONITOR_GO   0x00000001
-#define VFE_PERFORMANCE_MONITOR_STOP 0x00000002
-
-/* bit 0 = 1, test gen go;   bit1 = 1, test gen stop */
-#define VFE_TEST_GEN_GO   0x00000001
-#define VFE_TEST_GEN_STOP 0x00000002
-
-/* the chroma is assumed to be interpolated between
- * the luma samples.  JPEG 4:2:2 */
-#define VFE_CHROMA_UPSAMPLE_INTERPOLATED 0
-
-/* constants for irq registers */
-#define VFE_DISABLE_ALL_IRQS 0
-/* bit =1 is to clear the corresponding bit in VFE_IRQ_STATUS.  */
-#define VFE_CLEAR_ALL_IRQS   0xffffffff
-
-#define VFE_IRQ_STATUS0_CAMIF_SOF_MASK            0x00000001
-#define VFE_IRQ_STATUS0_CAMIF_EOF_MASK            0x00000004
-#define VFE_IRQ_STATUS0_REG_UPDATE_MASK           0x00000020
-#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK 0x00200000
-#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK 0x00400000
-#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE2_MASK 0x00800000
-#define VFE_IRQ_STATUS1_RESET_AXI_HALT_ACK_MASK   0x00800000
-#define VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK       0x01000000
-
-#define VFE_IRQ_STATUS0_STATS_AEC     0x2000  /* bit 13 */
-#define VFE_IRQ_STATUS0_STATS_AF      0x4000  /* bit 14 */
-#define VFE_IRQ_STATUS0_STATS_AWB     0x8000  /* bit 15 */
-#define VFE_IRQ_STATUS0_STATS_RS      0x10000  /* bit 16 */
-#define VFE_IRQ_STATUS0_STATS_CS      0x20000  /* bit 17 */
-#define VFE_IRQ_STATUS0_STATS_IHIST   0x40000  /* bit 18 */
-
-#define VFE_IRQ_STATUS0_SYNC_TIMER0   0x2000000  /* bit 25 */
-#define VFE_IRQ_STATUS0_SYNC_TIMER1   0x4000000  /* bit 26 */
-#define VFE_IRQ_STATUS0_SYNC_TIMER2   0x8000000  /* bit 27 */
-#define VFE_IRQ_STATUS0_ASYNC_TIMER0  0x10000000  /* bit 28 */
-#define VFE_IRQ_STATUS0_ASYNC_TIMER1  0x20000000  /* bit 29 */
-#define VFE_IRQ_STATUS0_ASYNC_TIMER2  0x40000000  /* bit 30 */
-#define VFE_IRQ_STATUS0_ASYNC_TIMER3  0x80000000  /* bit 31 */
-
-/* imask for while waiting for stop ack,  driver has already
- * requested stop, waiting for reset irq, and async timer irq.
- * For irq_status_0, bit 28-31 are for async timer. For
- * irq_status_1, bit 22 for reset irq, bit 23 for axi_halt_ack
-   irq */
-#define VFE_IMASK_WHILE_STOPPING_0  0xF0000000
-#define VFE_IMASK_WHILE_STOPPING_1  0x00C00000
-#define VFE_IMASK_RESET             0x00400000
-#define VFE_IMASK_AXI_HALT          0x00800000
-
-
-/* no error irq in mask 0 */
-#define VFE_IMASK_ERROR_ONLY_0  0x0
-/* when normal case, don't want to block error status. */
-/* bit 0-21 are error irq bits */
-#define VFE_IMASK_ERROR_ONLY_1  0x003fffff
-
-/* For BPC bit 0,bit 12-17 and bit 26 -20 are set to zero and other's 1 */
-#define BPC_MASK 0xF80C0FFE
-
-/* For BPC bit 1 and 2 are set to zero and other's 1 */
-#define ABF_MASK 0xFFFFFFF9
-
-/* For DBPC bit 0 is set to zero and other's 1 */
-#define DBPC_MASK 0xFFFFFFFE
-
-/* For DBCC bit 1 is set to zero and other's 1 */
-#define DBCC_MASK 0xFFFFFFFD
-
-/* For DBPC/ABF/DBCC/ABCC bits are set to 1 all others 0 */
-#define DEMOSAIC_MASK 0x8FFFFFFF
-/* For MCE enable bit 28 set to zero and other's 1 */
-#define MCE_EN_MASK 0xEFFFFFFF
-
-/* For MCE Q_K bit 28 to 31 set to zero and other's 1 */
-#define MCE_Q_K_MASK 0x0FFFFFFF
-
-#define AE_BG_ENABLE_MASK 0x00000020      /* bit 5 */
-#define AF_BF_ENABLE_MASK 0x00000040      /* bit 6 */
-#define AWB_ENABLE_MASK 0x00000080     /* bit 7 */
-
-#define RS_ENABLE_MASK 0x00000100      /* bit 8  */
-#define CS_ENABLE_MASK 0x00000200      /* bit 9  */
-#define RS_CS_ENABLE_MASK 0x00000300   /* bit 8,9  */
-#define IHIST_ENABLE_MASK 0x00008000   /* bit 15 */
-#define STATS_ENABLE_MASK 0x000483E0   /* bit 18,15,9,8,7,6,5*/
-
-#define VFE_REG_UPDATE_TRIGGER           1
-#define VFE_PM_BUF_MAX_CNT_MASK          0xFF
-#define VFE_DMI_CFG_DEFAULT              0x00000100
-#define VFE_AE_PINGPONG_STATUS_BIT       0x80
-#define VFE_AF_PINGPONG_STATUS_BIT       0x100
-#define VFE_AWB_PINGPONG_STATUS_BIT      0x200
-
-#define HFR_MODE_OFF 1
-#define VFE_FRAME_SKIP_PERIOD_MASK 0x0000001F /*bits 0 -4*/
-
-enum VFE31_DMI_RAM_SEL {
-	 NO_MEM_SELECTED          = 0,
-	 ROLLOFF_RAM              = 0x1,
-	 RGBLUT_RAM_CH0_BANK0     = 0x2,
-	 RGBLUT_RAM_CH0_BANK1     = 0x3,
-	 RGBLUT_RAM_CH1_BANK0     = 0x4,
-	 RGBLUT_RAM_CH1_BANK1     = 0x5,
-	 RGBLUT_RAM_CH2_BANK0     = 0x6,
-	 RGBLUT_RAM_CH2_BANK1     = 0x7,
-	 STATS_HIST_RAM           = 0x8,
-	 RGBLUT_CHX_BANK0         = 0x9,
-	 RGBLUT_CHX_BANK1         = 0xa,
-	 LUMA_ADAPT_LUT_RAM_BANK0 = 0xb,
-	 LUMA_ADAPT_LUT_RAM_BANK1 = 0xc
-};
-
-enum vfe_output_state {
-	VFE_STATE_IDLE,
-	VFE_STATE_START_REQUESTED,
-	VFE_STATE_STARTED,
-	VFE_STATE_STOP_REQUESTED,
-	VFE_STATE_STOPPED,
-};
-
-#define V31_CAMIF_OFF             0x000001E4
-#define V31_CAMIF_LEN             32
-
-#define V31_DEMUX_OFF             0x00000284
-#define V31_DEMUX_LEN             20
-
-#define V31_DEMOSAICV3_UP_REG_CNT 5
-
-#define V31_OUT_CLAMP_OFF         0x00000524
-#define V31_OUT_CLAMP_LEN         8
-
-#define V31_OPERATION_CFG_LEN     32
-
-#define V31_AXI_BUS_CMD_OFF       0x00000038
-#define V31_AXI_OUT_OFF           0x0000003C
-#define V31_AXI_OUT_LEN           240
-#define V31_AXI_CFG_LEN           47
-#define V31_AXI_RESERVED            1
-#define V31_AXI_RESERVED_LEN        4
-#define V31_AXI_BUS_CFG_LEN       16
-
-#define V31_FRAME_SKIP_OFF        0x00000504
-#define V31_FRAME_SKIP_LEN        32
-
-#define V31_CHROMA_SUBS_OFF       0x000004F8
-#define V31_CHROMA_SUBS_LEN       12
-
-#define V31_FOV_OFF           0x00000360
-#define V31_FOV_LEN           8
-
-#define V31_MAIN_SCALER_OFF 0x00000368
-#define V31_MAIN_SCALER_LEN 28
-
-#define V31_S2Y_OFF 0x000004D0
-#define V31_S2Y_LEN 20
-
-#define V31_S2CbCr_OFF 0x000004E4
-#define V31_S2CbCr_LEN 20
-
-#define V31_CHROMA_EN_OFF 0x000003C4
-#define V31_CHROMA_EN_LEN 36
-
-#define V31_SYNC_TIMER_OFF      0x0000020C
-#define V31_SYNC_TIMER_POLARITY_OFF 0x00000234
-#define V31_TIMER_SELECT_OFF        0x0000025C
-#define V31_SYNC_TIMER_LEN 28
-
-#define V31_ASYNC_TIMER_OFF 0x00000238
-#define V31_ASYNC_TIMER_LEN 28
-
-#define V31_BLACK_LEVEL_OFF 0x00000264
-#define V31_BLACK_LEVEL_LEN 16
-
-#define V31_MESH_ROLL_OFF_CFG_OFF             0x00000274
-#define V31_MESH_ROLL_OFF_CFG_LEN             16
-#define V31_MESH_ROLL_OFF_INIT_TABLE_SIZE     13
-#define V31_MESH_ROLL_OFF_DELTA_TABLE_SIZE    208
-#define V31_MESH_ROLL_OFF_DELTA_TABLE_OFFSET  32
-
-#define V31_COLOR_COR_OFF 0x00000388
-#define V31_COLOR_COR_LEN 52
-
-#define V31_WB_OFF 0x00000384
-#define V31_WB_LEN 4
-
-#define V31_RGB_G_OFF 0x000003BC
-#define V31_RGB_G_LEN 4
-
-#define V31_LA_OFF 0x000003C0
-#define V31_LA_LEN 4
-
-#define V31_SCE_OFF 0x00000418
-#define V31_SCE_LEN 136
-
-#define V31_CHROMA_SUP_OFF 0x000003E8
-#define V31_CHROMA_SUP_LEN 12
-
-#define V31_MCE_OFF 0x000003F4
-#define V31_MCE_LEN 36
-#define V31_STATS_AF_OFF 0x0000053c
-#define V31_STATS_AF_LEN 16
-
-#define V31_STATS_AE_OFF 0x00000534
-#define V31_STATS_AE_LEN 8
-
-#define V31_STATS_AWB_OFF 0x0000054c
-#define V31_STATS_AWB_LEN 32
-
-#define V31_STATS_IHIST_OFF 0x0000057c
-#define V31_STATS_IHIST_LEN 8
-
-#define V31_STATS_RS_OFF 0x0000056c
-#define V31_STATS_RS_LEN 8
-
-#define V31_STATS_CS_OFF 0x00000574
-#define V31_STATS_CS_LEN 8
-
-#define V31_ASF_OFF 0x000004A0
-#define V31_ASF_LEN 48
-#define V31_ASF_UPDATE_LEN 36
-#define V31_CAPTURE_LEN 4
-#define V31_GET_HW_VERSION_OFF 0
-#define V31_GET_HW_VERSION_LEN 4
-#define V31_DEMOSAICV3_OFF 0x00000298
-#define V31_DEMOSAICV3_LEN 4
-/* BPC     */
-#define V31_DEMOSAICV3_DBPC_CFG_OFF  0x0000029C
-#define V31_DEMOSAICV3_DBPC_LEN 8
-#define V31_XBAR_CFG_OFF 0x00000040
-/* ABF     */
-#define V31_DEMOSAICV3_ABF_OFF 0x000002A4
-#define V31_DEMOSAICV3_ABF_LEN 180
-#define V31_XBAR_CFG_LEN 8
-
-#define V31_MODULE_CFG_OFF 0x00000010
-#define V31_MODULE_CFG_LEN 4
-#define V31_EZTUNE_CFG_OFF 0x00000010
-#define V31_EZTUNE_CFG_LEN 4
-
-struct vfe_cmd_hw_version {
-	uint32_t minorVersion;
-	uint32_t majorVersion;
-	uint32_t coreVersion;
-};
-
-enum VFE_AXI_OUTPUT_MODE {
-	VFE_AXI_OUTPUT_MODE_Output1,
-	VFE_AXI_OUTPUT_MODE_Output2,
-	VFE_AXI_OUTPUT_MODE_Output1AndOutput2,
-	VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2,
-	VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1,
-	VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2,
-	VFE_AXI_LAST_OUTPUT_MODE_ENUM
-};
-
-enum VFE_RAW_WR_PATH_SEL {
-	VFE_RAW_OUTPUT_DISABLED,
-	VFE_RAW_OUTPUT_ENC_CBCR_PATH,
-	VFE_RAW_OUTPUT_VIEW_CBCR_PATH,
-	VFE_RAW_OUTPUT_PATH_INVALID
-};
-
-#define VFE_AXI_OUTPUT_BURST_LENGTH     4
-#define VFE_MAX_NUM_FRAGMENTS_PER_FRAME 4
-#define VFE_AXI_OUTPUT_CFG_FRAME_COUNT  3
-
-struct vfe_cmds_per_write_master {
-	uint16_t imageWidth;
-	uint16_t imageHeight;
-	uint16_t outRowCount;
-	uint16_t outRowIncrement;
-	uint32_t outFragments[VFE_AXI_OUTPUT_CFG_FRAME_COUNT]
-		[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
-};
-
-struct vfe_cmds_axi_per_output_path {
-	uint8_t fragmentCount;
-	struct vfe_cmds_per_write_master firstWM;
-	struct vfe_cmds_per_write_master secondWM;
-};
-
-enum VFE_AXI_BURST_LENGTH {
-	VFE_AXI_BURST_LENGTH_IS_2  = 2,
-	VFE_AXI_BURST_LENGTH_IS_4  = 4,
-	VFE_AXI_BURST_LENGTH_IS_8  = 8,
-	VFE_AXI_BURST_LENGTH_IS_16 = 16
-};
-
-struct vfe_cmd_fov_crop_config {
-	uint8_t enable;
-	uint16_t firstPixel;
-	uint16_t lastPixel;
-	uint16_t firstLine;
-	uint16_t lastLine;
-};
-
-struct vfe_cmds_main_scaler_stripe_init {
-	uint16_t MNCounterInit;
-	uint16_t phaseInit;
-};
-
-struct vfe_cmds_scaler_one_dimension {
-	uint8_t  enable;
-	uint16_t inputSize;
-	uint16_t outputSize;
-	uint32_t phaseMultiplicationFactor;
-	uint8_t  interpolationResolution;
-};
-
-struct vfe_cmd_main_scaler_config {
-	uint8_t enable;
-	struct vfe_cmds_scaler_one_dimension    hconfig;
-	struct vfe_cmds_scaler_one_dimension    vconfig;
-	struct vfe_cmds_main_scaler_stripe_init MNInitH;
-	struct vfe_cmds_main_scaler_stripe_init MNInitV;
-};
-
-struct vfe_cmd_scaler2_config {
-	uint8_t enable;
-	struct vfe_cmds_scaler_one_dimension hconfig;
-	struct vfe_cmds_scaler_one_dimension vconfig;
-};
-
-
-struct vfe_cmd_frame_skip_update {
-	uint32_t output1Pattern;
-	uint32_t output2Pattern;
-};
-
-struct vfe_cmd_output_clamp_config {
-	uint8_t minCh0;
-	uint8_t minCh1;
-	uint8_t minCh2;
-	uint8_t maxCh0;
-	uint8_t maxCh1;
-	uint8_t maxCh2;
-};
-
-struct vfe_cmd_chroma_subsample_config {
-	uint8_t enable;
-	uint8_t cropEnable;
-	uint8_t vsubSampleEnable;
-	uint8_t hsubSampleEnable;
-	uint8_t vCosited;
-	uint8_t hCosited;
-	uint8_t vCositedPhase;
-	uint8_t hCositedPhase;
-	uint16_t cropWidthFirstPixel;
-	uint16_t cropWidthLastPixel;
-	uint16_t cropHeightFirstLine;
-	uint16_t cropHeightLastLine;
-};
-
-enum VFE_START_PIXEL_PATTERN {
-	VFE_BAYER_RGRGRG,
-	VFE_BAYER_GRGRGR,
-	VFE_BAYER_BGBGBG,
-	VFE_BAYER_GBGBGB,
-	VFE_YUV_YCbYCr,
-	VFE_YUV_YCrYCb,
-	VFE_YUV_CbYCrY,
-	VFE_YUV_CrYCbY
-};
-
-enum VFE_BUS_RD_INPUT_PIXEL_PATTERN {
-	VFE_BAYER_RAW,
-	VFE_YUV_INTERLEAVED,
-	VFE_YUV_PSEUDO_PLANAR_Y,
-	VFE_YUV_PSEUDO_PLANAR_CBCR
-};
-
-enum VFE_YUV_INPUT_COSITING_MODE {
-	VFE_YUV_COSITED,
-	VFE_YUV_INTERPOLATED
-};
-
-#define VFE31_GAMMA_NUM_ENTRIES  64
-
-#define VFE31_LA_TABLE_LENGTH    64
-
-#define VFE31_HIST_TABLE_LENGTH  256
-
-struct vfe_cmds_demosaic_abf {
-	uint8_t   enable;
-	uint8_t   forceOn;
-	uint8_t   shift;
-	uint16_t  lpThreshold;
-	uint16_t  max;
-	uint16_t  min;
-	uint8_t   ratio;
-};
-
-struct vfe_cmds_demosaic_bpc {
-	uint8_t   enable;
-	uint16_t  fmaxThreshold;
-	uint16_t  fminThreshold;
-	uint16_t  redDiffThreshold;
-	uint16_t  blueDiffThreshold;
-	uint16_t  greenDiffThreshold;
-};
-
-struct vfe_cmd_demosaic_config {
-	uint8_t   enable;
-	uint8_t   slopeShift;
-	struct vfe_cmds_demosaic_abf abfConfig;
-	struct vfe_cmds_demosaic_bpc bpcConfig;
-};
-
-struct vfe_cmd_demosaic_bpc_update {
-	struct vfe_cmds_demosaic_bpc bpcUpdate;
-};
-
-struct vfe_cmd_demosaic_abf_update {
-	struct vfe_cmds_demosaic_abf abfUpdate;
-};
-
-struct vfe_cmd_white_balance_config {
-	uint8_t  enable;
-	uint16_t ch2Gain;
-	uint16_t ch1Gain;
-	uint16_t ch0Gain;
-};
-
-enum VFE_COLOR_CORRECTION_COEF_QFACTOR {
-	COEF_IS_Q7_SIGNED,
-	COEF_IS_Q8_SIGNED,
-	COEF_IS_Q9_SIGNED,
-	COEF_IS_Q10_SIGNED
-};
-
-struct vfe_cmd_color_correction_config {
-	uint8_t     enable;
-	enum VFE_COLOR_CORRECTION_COEF_QFACTOR coefQFactor;
-	int16_t  C0;
-	int16_t  C1;
-	int16_t  C2;
-	int16_t  C3;
-	int16_t  C4;
-	int16_t  C5;
-	int16_t  C6;
-	int16_t  C7;
-	int16_t  C8;
-	int16_t  K0;
-	int16_t  K1;
-	int16_t  K2;
-};
-
-#define VFE_LA_TABLE_LENGTH 64
-
-struct vfe_cmd_la_config {
-	uint8_t enable;
-	int16_t table[VFE_LA_TABLE_LENGTH];
-};
-
-#define VFE_GAMMA_TABLE_LENGTH 256
-enum VFE_RGB_GAMMA_TABLE_SELECT {
-	RGB_GAMMA_CH0_SELECTED,
-	RGB_GAMMA_CH1_SELECTED,
-	RGB_GAMMA_CH2_SELECTED,
-	RGB_GAMMA_CH0_CH1_SELECTED,
-	RGB_GAMMA_CH0_CH2_SELECTED,
-	RGB_GAMMA_CH1_CH2_SELECTED,
-	RGB_GAMMA_CH0_CH1_CH2_SELECTED
-};
-
-struct vfe_cmd_rgb_gamma_config {
-	uint8_t enable;
-	enum VFE_RGB_GAMMA_TABLE_SELECT channelSelect;
-	int16_t table[VFE_GAMMA_TABLE_LENGTH];
-};
-
-struct vfe_cmd_chroma_enhan_config {
-	uint8_t  enable;
-	int16_t am;
-	int16_t ap;
-	int16_t bm;
-	int16_t bp;
-	int16_t cm;
-	int16_t cp;
-	int16_t dm;
-	int16_t dp;
-	int16_t kcr;
-	int16_t kcb;
-	int16_t RGBtoYConversionV0;
-	int16_t RGBtoYConversionV1;
-	int16_t RGBtoYConversionV2;
-	uint8_t RGBtoYConversionOffset;
-};
-
-struct vfe_cmd_chroma_suppression_config {
-	uint8_t enable;
-	uint8_t m1;
-	uint8_t m3;
-	uint8_t n1;
-	uint8_t n3;
-	uint8_t nn1;
-	uint8_t mm1;
-};
-
-struct vfe_cmd_asf_config {
-	uint8_t enable;
-	uint8_t smoothFilterEnabled;
-	uint8_t sharpMode;
-	uint8_t smoothCoefCenter;
-	uint8_t smoothCoefSurr;
-	uint8_t normalizeFactor;
-	uint8_t sharpK1;
-	uint8_t sharpK2;
-	uint8_t sharpThreshE1;
-	int8_t sharpThreshE2;
-	int8_t sharpThreshE3;
-	int8_t sharpThreshE4;
-	int8_t sharpThreshE5;
-	int8_t filter1Coefficients[9];
-	int8_t filter2Coefficients[9];
-	uint8_t  cropEnable;
-	uint16_t cropFirstPixel;
-	uint16_t cropLastPixel;
-	uint16_t cropFirstLine;
-	uint16_t cropLastLine;
-};
-
-struct vfe_cmd_asf_update {
-	uint8_t enable;
-	uint8_t smoothFilterEnabled;
-	uint8_t sharpMode;
-	uint8_t smoothCoefCenter;
-	uint8_t smoothCoefSurr;
-	uint8_t normalizeFactor;
-	uint8_t sharpK1;
-	uint8_t sharpK2;
-	uint8_t sharpThreshE1;
-	int8_t  sharpThreshE2;
-	int8_t  sharpThreshE3;
-	int8_t  sharpThreshE4;
-	int8_t  sharpThreshE5;
-	int8_t  filter1Coefficients[9];
-	int8_t  filter2Coefficients[9];
-	uint8_t cropEnable;
-};
-
-enum VFE_TEST_GEN_SYNC_EDGE {
-	VFE_TEST_GEN_SYNC_EDGE_ActiveHigh,
-	VFE_TEST_GEN_SYNC_EDGE_ActiveLow
-};
-
-
-struct vfe_cmd_bus_pm_start {
-	uint8_t output2YWrPmEnable;
-	uint8_t output2CbcrWrPmEnable;
-	uint8_t output1YWrPmEnable;
-	uint8_t output1CbcrWrPmEnable;
-};
-
-struct  vfe_frame_skip_counts {
-	uint32_t  totalFrameCount;
-	uint32_t  output1Count;
-	uint32_t  output2Count;
-};
-
-enum VFE_AXI_RD_UNPACK_HBI_SEL {
-	VFE_AXI_RD_HBI_32_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_64_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_128_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_256_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_512_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_1024_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_2048_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_4096_CLOCK_CYCLES
-};
-
-struct vfe_frame_bpc_info {
-	uint32_t greenDefectPixelCount;
-	uint32_t redBlueDefectPixelCount;
-};
-
-struct vfe_frame_asf_info {
-	uint32_t  asfMaxEdge;
-	uint32_t  asfHbiCount;
-};
-
-struct vfe_msg_camif_status {
-	uint8_t  camifState;
-	uint32_t pixelCount;
-	uint32_t lineCount;
-};
-
-struct vfe31_irq_status {
-	uint32_t vfeIrqStatus0;
-	uint32_t vfeIrqStatus1;
-	uint32_t camifStatus;
-	uint32_t demosaicStatus;
-	uint32_t asfMaxEdge;
-};
-
-#define V31_PREVIEW_AXI_FLAG  0x00000001
-#define V31_SNAPSHOT_AXI_FLAG (0x00000001<<1)
-
-struct vfe31_cmd_type {
-	uint16_t id;
-	uint32_t length;
-	uint32_t offset;
-	uint32_t flag;
-};
-
-struct vfe31_free_buf {
-	struct list_head node;
-	uint32_t paddr;
-	uint32_t y_off;
-	uint32_t cbcr_off;
-};
-
-struct vfe31_output_ch {
-	struct list_head free_buf_queue;
-	spinlock_t free_buf_lock;
-	uint32_t inst_handle;
-	int8_t ch0;
-	int8_t ch1;
-	int8_t ch2;
-	uint32_t  capture_cnt;
-	uint32_t  frame_drop_cnt;
-	struct msm_free_buf ping;
-	struct msm_free_buf pong;
-	struct msm_free_buf free_buf;
-};
-
-/* no error irq in mask 0 */
-#define VFE31_IMASK_ERROR_ONLY_0  0x0
-/* when normal case, don't want to block error status. */
-/* bit 0-21 are error irq bits */
-#define VFE31_IMASK_ERROR_ONLY_1               0x003FFFFF
-#define VFE31_IMASK_CAMIF_ERROR               (0x00000001<<0)
-#define VFE31_IMASK_STATS_CS_OVWR             (0x00000001<<1)
-#define VFE31_IMASK_STATS_IHIST_OVWR          (0x00000001<<2)
-#define VFE31_IMASK_REALIGN_BUF_Y_OVFL        (0x00000001<<3)
-#define VFE31_IMASK_REALIGN_BUF_CB_OVFL       (0x00000001<<4)
-#define VFE31_IMASK_REALIGN_BUF_CR_OVFL       (0x00000001<<5)
-#define VFE31_IMASK_VIOLATION                 (0x00000001<<6)
-#define VFE31_IMASK_IMG_MAST_0_BUS_OVFL       (0x00000001<<7)
-#define VFE31_IMASK_IMG_MAST_1_BUS_OVFL       (0x00000001<<8)
-#define VFE31_IMASK_IMG_MAST_2_BUS_OVFL       (0x00000001<<9)
-#define VFE31_IMASK_IMG_MAST_3_BUS_OVFL       (0x00000001<<10)
-#define VFE31_IMASK_IMG_MAST_4_BUS_OVFL       (0x00000001<<11)
-#define VFE31_IMASK_IMG_MAST_5_BUS_OVFL       (0x00000001<<12)
-#define VFE31_IMASK_IMG_MAST_6_BUS_OVFL       (0x00000001<<13)
-#define VFE31_IMASK_STATS_AE_BG_BUS_OVFL         (0x00000001<<14)
-#define VFE31_IMASK_STATS_AF_BF_BUS_OVFL         (0x00000001<<15)
-#define VFE31_IMASK_STATS_AWB_BUS_OVFL        (0x00000001<<16)
-#define VFE31_IMASK_STATS_RS_BUS_OVFL         (0x00000001<<17)
-#define VFE31_IMASK_STATS_CS_BUS_OVFL         (0x00000001<<18)
-#define VFE31_IMASK_STATS_IHIST_BUS_OVFL      (0x00000001<<19)
-#define VFE31_IMASK_STATS_SKIN_BHIST_BUS_OVFL       (0x00000001<<20)
-#define VFE31_IMASK_AXI_ERROR                 (0x00000001<<21)
-
-#define VFE_COM_STATUS 0x000FE000
-
-struct vfe31_output_path {
-	uint16_t output_mode;     /* bitmask  */
-
-	struct vfe31_output_ch out0; /* preview and thumbnail */
-	struct vfe31_output_ch out1; /* snapshot */
-	struct vfe31_output_ch out2; /* video    */
-};
-
-struct vfe31_frame_extra {
-	uint32_t greenDefectPixelCount;
-	uint32_t redBlueDefectPixelCount;
-
-	uint32_t  asfMaxEdge;
-	uint32_t  asfHbiCount;
-
-	uint32_t yWrPmStats0;
-	uint32_t yWrPmStats1;
-	uint32_t cbcrWrPmStats0;
-	uint32_t cbcrWrPmStats1;
-
-	uint32_t  frameCounter;
-};
-
-#define VFE_DISABLE_ALL_IRQS             0
-#define VFE_CLEAR_ALL_IRQS               0xffffffff
-
-#define VFE_HW_VERSION					 0x00000000
-#define VFE_GLOBAL_RESET                 0x00000004
-#define VFE_MODULE_RESET				 0x00000008
-#define VFE_CGC_OVERRIDE                 0x0000000C
-#define VFE_MODULE_CFG                   0x00000010
-#define VFE_CFG				 0x00000014
-#define VFE_IRQ_CMD                      0x00000018
-#define VFE_IRQ_MASK_0                   0x0000001C
-#define VFE_IRQ_MASK_1                   0x00000020
-#define VFE_IRQ_CLEAR_0                  0x00000024
-#define VFE_IRQ_CLEAR_1                  0x00000028
-#define VFE_IRQ_STATUS_0                 0x0000002C
-#define VFE_IRQ_STATUS_1                 0x00000030
-#define VFE_IRQ_COMP_MASK                0x00000034
-#define VFE_BUS_CMD                      0x00000038
-#define VFE_BUS_PING_PONG_STATUS         0x00000180
-#define VFE_BUS_OPERATION_STATUS         0x00000184
-
-#define VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_0        0x00000190
-#define VFE_BUS_IMAGE_MASTER_0_WR_PM_STATS_1        0x00000194
-
-#define VFE_AXI_CMD                      0x000001D8
-#define VFE_AXI_STATUS                   0x000001DC
-#define VFE_BUS_STATS_PING_PONG_BASE     0x000000F4
-
-#define VFE_BUS_STATS_AEC_WR_PING_ADDR   0x000000F4
-#define VFE_BUS_STATS_AEC_WR_PONG_ADDR   0x000000F8
-#define VFE_BUS_STATS_AEC_UB_CFG         0x000000FC
-#define VFE_BUS_STATS_AF_WR_PING_ADDR    0x00000100
-#define VFE_BUS_STATS_AF_WR_PONG_ADDR    0x00000104
-#define VFE_BUS_STATS_AF_UB_CFG          0x00000108
-#define VFE_BUS_STATS_AWB_WR_PING_ADDR   0x0000010C
-#define VFE_BUS_STATS_AWB_WR_PONG_ADDR   0x00000110
-#define VFE_BUS_STATS_AWB_UB_CFG         0x00000114
-#define VFE_BUS_STATS_RS_WR_PING_ADDR    0x00000118
-#define VFE_BUS_STATS_RS_WR_PONG_ADDR    0x0000011C
-#define VFE_BUS_STATS_RS_UB_CFG          0x00000120
-
-#define VFE_BUS_STATS_CS_WR_PING_ADDR    0x00000124
-#define VFE_BUS_STATS_CS_WR_PONG_ADDR    0x00000128
-#define VFE_BUS_STATS_CS_UB_CFG          0x0000012C
-#define VFE_BUS_STATS_HIST_WR_PING_ADDR  0x00000130
-#define VFE_BUS_STATS_HIST_WR_PONG_ADDR  0x00000134
-#define VFE_BUS_STATS_HIST_UB_CFG        0x00000138
-#define VFE_BUS_STATS_SKIN_WR_PING_ADDR  0x0000013C
-#define VFE_BUS_STATS_SKIN_WR_PONG_ADDR  0x00000140
-#define VFE_BUS_STATS_SKIN_UB_CFG        0x00000144
-#define VFE_BUS_PM_CMD                   0x00000188
-#define VFE_BUS_PM_CFG                   0x0000018C
-#define VFE_CAMIF_COMMAND                0x000001E0
-#define VFE_CAMIF_STATUS                 0x00000204
-#define VFE_REG_UPDATE_CMD               0x00000260
-#define VFE_DEMUX_GAIN_0                 0x00000288
-#define VFE_DEMUX_GAIN_1                 0x0000028C
-#define VFE_CHROMA_UP                    0x0000035C
-#define VFE_FRAMEDROP_ENC_Y_CFG          0x00000504
-#define VFE_FRAMEDROP_ENC_CBCR_CFG       0x00000508
-#define VFE_FRAMEDROP_ENC_Y_PATTERN      0x0000050C
-#define VFE_FRAMEDROP_ENC_CBCR_PATTERN   0x00000510
-#define VFE_FRAMEDROP_VIEW_Y             0x00000514
-#define VFE_FRAMEDROP_VIEW_CBCR          0x00000518
-#define VFE_FRAMEDROP_VIEW_Y_PATTERN     0x0000051C
-#define VFE_FRAMEDROP_VIEW_CBCR_PATTERN  0x00000520
-#define VFE_CLAMP_MAX                    0x00000524
-#define VFE_CLAMP_MIN                    0x00000528
-#define VFE_REALIGN_BUF                  0x0000052C
-#define VFE_STATS_CFG                    0x00000530
-#define VFE_STATS_AWB_SGW_CFG            0x00000554
-#define VFE_DMI_CFG                      0x00000598
-#define VFE_DMI_ADDR                     0x0000059C
-#define VFE_DMI_DATA_LO                  0x000005A4
-#define VFE_AXI_CFG                      0x00000600
-
-#define VFE31_OUTPUT_MODE_PT		BIT(0)
-#define VFE31_OUTPUT_MODE_S			BIT(1)
-#define VFE31_OUTPUT_MODE_V			BIT(2)
-#define VFE31_OUTPUT_MODE_P			BIT(3)
-#define VFE31_OUTPUT_MODE_T			BIT(4)
-#define VFE31_OUTPUT_MODE_P_ALL_CHNLS		BIT(5)
-#define VFE31_OUTPUT_MODE_PRIMARY		BIT(6)
-#define VFE31_OUTPUT_MODE_PRIMARY_ALL_CHNLS	BIT(7)
-#define VFE31_OUTPUT_MODE_SECONDARY		BIT(8)
-#define VFE31_OUTPUT_MODE_SECONDARY_ALL_CHNLS	BIT(9)
-struct vfe_stats_control {
-	uint8_t  ackPending;
-	uint32_t nextFrameAddrBuf;
-	uint32_t droppedStatsFrameCount;
-	uint32_t bufToRender;
-};
-
-struct vfe31_ctrl_type {
-	uint16_t operation_mode;     /* streaming or snapshot */
-	struct vfe31_output_path outpath;
-
-	uint32_t vfeImaskCompositePacked;
-
-	spinlock_t  stop_flag_lock;
-	spinlock_t  update_ack_lock;
-	spinlock_t  state_lock;
-	spinlock_t  io_lock;
-	spinlock_t  stats_bufq_lock;
-
-	uint32_t extlen;
-	void *extdata;
-
-	int8_t start_ack_pending;
-	int8_t stop_ack_pending;
-	int8_t reset_ack_pending;
-	int8_t update_ack_pending;
-	enum vfe_output_state recording_state;
-	int8_t update_linear;
-	int8_t update_rolloff;
-	int8_t update_la;
-	int8_t update_gamma;
-	enum vfe_output_state liveshot_state;
-
-	spinlock_t  tasklet_lock;
-	struct list_head tasklet_q;
-	void __iomem *vfebase;
-	void __iomem *camifbase;
-	void *syncdata;
-	uint32_t register_total;
-
-	struct resource	*vfemem;
-	struct resource	*camifmem;
-	struct resource *vfeio;
-	struct resource *camifio;
-	struct resource *vfeirq;
-	struct regulator *fs_vfe;
-
-	uint32_t stats_comp;
-	atomic_t vstate;
-	uint32_t vfe_capture_count;
-	uint32_t sync_timer_repeat_count;
-	uint32_t sync_timer_state;
-	uint32_t sync_timer_number;
-
-	uint32_t vfeFrameId;
-	uint32_t output1Pattern;
-	uint32_t output1Period;
-	uint32_t output2Pattern;
-	uint32_t output2Period;
-	uint32_t vfeFrameSkipCount;
-	uint32_t vfeFrameSkipPeriod;
-	struct vfe_stats_control afStatsControl;
-	struct vfe_stats_control awbStatsControl;
-	struct vfe_stats_control aecStatsControl;
-	struct vfe_stats_control ihistStatsControl;
-	struct vfe_stats_control rsStatsControl;
-	struct vfe_stats_control csStatsControl;
-
-	/* v4l2 subdev */
-	struct v4l2_subdev subdev;
-	struct platform_device *pdev;
-	struct clk *vfe_clk[5];
-	struct clk *vfe_camif_clk[2];
-	spinlock_t  sd_notify_lock;
-	uint32_t hfr_mode;
-	uint32_t frame_skip_cnt;
-	uint32_t frame_skip_pattern;
-	uint32_t snapshot_frame_cnt;
-	struct msm_stats_bufq_ctrl stats_ctrl;
-	struct msm_stats_ops stats_ops;
-	struct device *iommu_ctx_imgwr;
-	struct device *iommu_ctx_misc;
-};
-
-enum VFE31_STATS_NUM {
-	STATS_AE_NUM,
-	STATS_AF_NUM,
-	STATS_AWB_NUM,
-	STATS_RS_NUM,
-	STATS_CS_NUM,
-	STATS_IHIST_NUM,
-	STATS_SKIN_NUM,
-	STATS_MAX_NUM,
-};
-
-struct vfe_cmd_stats_ack {
-	uint32_t  nextStatsBuf;
-};
-
-#define VFE_STATS_BUFFER_COUNT            3
-
-struct vfe_cmd_stats_buf {
-	uint32_t statsBuf[VFE_STATS_BUFFER_COUNT];
-};
-#endif /* __MSM_VFE31_H__ */
diff --git a/drivers/media/video/msm/vfe/msm_vfe32.c b/drivers/media/video/msm/vfe/msm_vfe32.c
deleted file mode 100644
index a382d53..0000000
--- a/drivers/media/video/msm/vfe/msm_vfe32.c
+++ /dev/null
@@ -1,6782 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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/uaccess.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/atomic.h>
-#include <linux/regulator/consumer.h>
-#include <linux/clk.h>
-#include <mach/irqs.h>
-#include <mach/camera.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-#include <media/msm_isp.h>
-
-#include "msm.h"
-#include "msm_cam_server.h"
-#include "msm_vfe32.h"
-
-atomic_t irq_cnt;
-
-#define VFE32_AXI_OFFSET 0x0050
-#define vfe32_get_ch_ping_addr(base, chn) \
-	(msm_camera_io_r((base) + 0x0050 + 0x18 * (chn)))
-#define vfe32_get_ch_pong_addr(base, chn) \
-	(msm_camera_io_r((base) + 0x0050 + 0x18 * (chn) + 4))
-#define vfe32_get_ch_addr(ping_pong, base, chn) \
-	((((ping_pong) & (1 << (chn))) == 0) ? \
-	(vfe32_get_ch_pong_addr((base), chn)) : \
-	(vfe32_get_ch_ping_addr((base), chn)))
-
-#define vfe32_put_ch_ping_addr(base, chn, addr) \
-	(msm_camera_io_w((addr), (base) + 0x0050 + 0x18 * (chn)))
-#define vfe32_put_ch_pong_addr(base, chn, addr) \
-	(msm_camera_io_w((addr), (base) + 0x0050 + 0x18 * (chn) + 4))
-#define vfe32_put_ch_addr(ping_pong, base, chn, addr) \
-	(((ping_pong) & (1 << (chn))) == 0 ?   \
-	vfe32_put_ch_pong_addr((base), (chn), (addr)) : \
-	vfe32_put_ch_ping_addr((base), (chn), (addr)))
-
-static uint32_t vfe_clk_rate;
-static void vfe32_send_isp_msg(struct v4l2_subdev *sd,
-	uint32_t vfeFrameId, uint32_t isp_msg_id);
-
-
-struct vfe32_isr_queue_cmd {
-	struct list_head list;
-	uint32_t                           vfeInterruptStatus0;
-	uint32_t                           vfeInterruptStatus1;
-};
-
-static struct vfe32_cmd_type vfe32_cmd[] = {
-/* 0*/	{VFE_CMD_DUMMY_0},
-		{VFE_CMD_SET_CLK},
-		{VFE_CMD_RESET},
-		{VFE_CMD_START},
-		{VFE_CMD_TEST_GEN_START},
-/* 5*/	{VFE_CMD_OPERATION_CFG, V32_OPERATION_CFG_LEN},
-		{VFE_CMD_AXI_OUT_CFG, V32_AXI_OUT_LEN, V32_AXI_OUT_OFF, 0xFF},
-		{VFE_CMD_CAMIF_CFG, V32_CAMIF_LEN, V32_CAMIF_OFF, 0xFF},
-		{VFE_CMD_AXI_INPUT_CFG},
-		{VFE_CMD_BLACK_LEVEL_CFG, V32_BLACK_LEVEL_LEN,
-		V32_BLACK_LEVEL_OFF,
-		0xFF},
-/*10*/  {VFE_CMD_MESH_ROLL_OFF_CFG, V32_MESH_ROLL_OFF_CFG_LEN,
-		V32_MESH_ROLL_OFF_CFG_OFF, 0xFF},
-		{VFE_CMD_DEMUX_CFG, V32_DEMUX_LEN, V32_DEMUX_OFF, 0xFF},
-		{VFE_CMD_FOV_CFG, V32_FOV_LEN, V32_FOV_OFF, 0xFF},
-		{VFE_CMD_MAIN_SCALER_CFG, V32_MAIN_SCALER_LEN,
-		V32_MAIN_SCALER_OFF, 0xFF},
-		{VFE_CMD_WB_CFG, V32_WB_LEN, V32_WB_OFF, 0xFF},
-/*15*/	{VFE_CMD_COLOR_COR_CFG, V32_COLOR_COR_LEN, V32_COLOR_COR_OFF, 0xFF},
-		{VFE_CMD_RGB_G_CFG, V32_RGB_G_LEN, V32_RGB_G_OFF, 0xFF},
-		{VFE_CMD_LA_CFG, V32_LA_LEN, V32_LA_OFF, 0xFF },
-		{VFE_CMD_CHROMA_EN_CFG, V32_CHROMA_EN_LEN, V32_CHROMA_EN_OFF,
-		0xFF},
-		{VFE_CMD_CHROMA_SUP_CFG, V32_CHROMA_SUP_LEN, V32_CHROMA_SUP_OFF,
-		0xFF},
-/*20*/	{VFE_CMD_MCE_CFG, V32_MCE_LEN, V32_MCE_OFF, 0xFF},
-		{VFE_CMD_SK_ENHAN_CFG, V32_SCE_LEN, V32_SCE_OFF, 0xFF},
-		{VFE_CMD_ASF_CFG, V32_ASF_LEN, V32_ASF_OFF, 0xFF},
-		{VFE_CMD_S2Y_CFG, V32_S2Y_LEN, V32_S2Y_OFF, 0xFF},
-		{VFE_CMD_S2CbCr_CFG, V32_S2CbCr_LEN, V32_S2CbCr_OFF, 0xFF},
-/*25*/	{VFE_CMD_CHROMA_SUBS_CFG, V32_CHROMA_SUBS_LEN, V32_CHROMA_SUBS_OFF,
-		0xFF},
-		{VFE_CMD_OUT_CLAMP_CFG, V32_OUT_CLAMP_LEN, V32_OUT_CLAMP_OFF,
-		0xFF},
-		{VFE_CMD_FRAME_SKIP_CFG, V32_FRAME_SKIP_LEN, V32_FRAME_SKIP_OFF,
-		0xFF},
-		{VFE_CMD_DUMMY_1},
-		{VFE_CMD_DUMMY_2},
-/*30*/	{VFE_CMD_DUMMY_3},
-		{VFE_CMD_UPDATE},
-		{VFE_CMD_BL_LVL_UPDATE, V32_BLACK_LEVEL_LEN,
-		V32_BLACK_LEVEL_OFF, 0xFF},
-		{VFE_CMD_DEMUX_UPDATE, V32_DEMUX_LEN, V32_DEMUX_OFF, 0xFF},
-		{VFE_CMD_FOV_UPDATE, V32_FOV_LEN, V32_FOV_OFF, 0xFF},
-/*35*/	{VFE_CMD_MAIN_SCALER_UPDATE, V32_MAIN_SCALER_LEN, V32_MAIN_SCALER_OFF,
-		0xFF},
-		{VFE_CMD_WB_UPDATE, V32_WB_LEN, V32_WB_OFF, 0xFF},
-		{VFE_CMD_COLOR_COR_UPDATE, V32_COLOR_COR_LEN, V32_COLOR_COR_OFF,
-		0xFF},
-		{VFE_CMD_RGB_G_UPDATE, V32_RGB_G_LEN, V32_CHROMA_EN_OFF, 0xFF},
-		{VFE_CMD_LA_UPDATE, V32_LA_LEN, V32_LA_OFF, 0xFF },
-/*40*/	{VFE_CMD_CHROMA_EN_UPDATE, V32_CHROMA_EN_LEN, V32_CHROMA_EN_OFF,
-		0xFF},
-		{VFE_CMD_CHROMA_SUP_UPDATE, V32_CHROMA_SUP_LEN,
-		V32_CHROMA_SUP_OFF, 0xFF},
-		{VFE_CMD_MCE_UPDATE, V32_MCE_LEN, V32_MCE_OFF, 0xFF},
-		{VFE_CMD_SK_ENHAN_UPDATE, V32_SCE_LEN, V32_SCE_OFF, 0xFF},
-		{VFE_CMD_S2CbCr_UPDATE, V32_S2CbCr_LEN, V32_S2CbCr_OFF, 0xFF},
-/*45*/	{VFE_CMD_S2Y_UPDATE, V32_S2Y_LEN, V32_S2Y_OFF, 0xFF},
-		{VFE_CMD_ASF_UPDATE, V32_ASF_UPDATE_LEN, V32_ASF_OFF, 0xFF},
-		{VFE_CMD_FRAME_SKIP_UPDATE},
-		{VFE_CMD_CAMIF_FRAME_UPDATE},
-		{VFE_CMD_STATS_AF_UPDATE, V32_STATS_AF_LEN, V32_STATS_AF_OFF},
-/*50*/	{VFE_CMD_STATS_AE_UPDATE, V32_STATS_AE_LEN, V32_STATS_AE_OFF},
-		{VFE_CMD_STATS_AWB_UPDATE, V32_STATS_AWB_LEN,
-		V32_STATS_AWB_OFF},
-		{VFE_CMD_STATS_RS_UPDATE, V32_STATS_RS_LEN, V32_STATS_RS_OFF},
-		{VFE_CMD_STATS_CS_UPDATE, V32_STATS_CS_LEN, V32_STATS_CS_OFF},
-		{VFE_CMD_STATS_SKIN_UPDATE},
-/*55*/	{VFE_CMD_STATS_IHIST_UPDATE, V32_STATS_IHIST_LEN, V32_STATS_IHIST_OFF},
-		{VFE_CMD_DUMMY_4},
-		{VFE_CMD_EPOCH1_ACK},
-		{VFE_CMD_EPOCH2_ACK},
-		{VFE_CMD_START_RECORDING},
-/*60*/	{VFE_CMD_STOP_RECORDING},
-		{VFE_CMD_DUMMY_5},
-		{VFE_CMD_DUMMY_6},
-		{VFE_CMD_CAPTURE, V32_CAPTURE_LEN, 0xFF},
-		{VFE_CMD_DUMMY_7},
-/*65*/	{VFE_CMD_STOP},
-		{VFE_CMD_GET_HW_VERSION, V32_GET_HW_VERSION_LEN,
-		V32_GET_HW_VERSION_OFF},
-		{VFE_CMD_GET_FRAME_SKIP_COUNTS},
-		{VFE_CMD_OUTPUT1_BUFFER_ENQ},
-		{VFE_CMD_OUTPUT2_BUFFER_ENQ},
-/*70*/	{VFE_CMD_OUTPUT3_BUFFER_ENQ},
-		{VFE_CMD_JPEG_OUT_BUF_ENQ},
-		{VFE_CMD_RAW_OUT_BUF_ENQ},
-		{VFE_CMD_RAW_IN_BUF_ENQ},
-		{VFE_CMD_STATS_AF_ENQ},
-/*75*/	{VFE_CMD_STATS_AE_ENQ},
-		{VFE_CMD_STATS_AWB_ENQ},
-		{VFE_CMD_STATS_RS_ENQ},
-		{VFE_CMD_STATS_CS_ENQ},
-		{VFE_CMD_STATS_SKIN_ENQ},
-/*80*/	{VFE_CMD_STATS_IHIST_ENQ},
-		{VFE_CMD_DUMMY_8},
-		{VFE_CMD_JPEG_ENC_CFG},
-		{VFE_CMD_DUMMY_9},
-		{VFE_CMD_STATS_AF_START, V32_STATS_AF_LEN, V32_STATS_AF_OFF},
-/*85*/	{VFE_CMD_STATS_AF_STOP},
-		{VFE_CMD_STATS_AE_START, V32_STATS_AE_LEN, V32_STATS_AE_OFF},
-		{VFE_CMD_STATS_AE_STOP},
-		{VFE_CMD_STATS_AWB_START, V32_STATS_AWB_LEN, V32_STATS_AWB_OFF},
-		{VFE_CMD_STATS_AWB_STOP},
-/*90*/	{VFE_CMD_STATS_RS_START, V32_STATS_RS_LEN, V32_STATS_RS_OFF},
-		{VFE_CMD_STATS_RS_STOP},
-		{VFE_CMD_STATS_CS_START, V32_STATS_CS_LEN, V32_STATS_CS_OFF},
-		{VFE_CMD_STATS_CS_STOP},
-		{VFE_CMD_STATS_SKIN_START},
-/*95*/	{VFE_CMD_STATS_SKIN_STOP},
-		{VFE_CMD_STATS_IHIST_START,
-		V32_STATS_IHIST_LEN, V32_STATS_IHIST_OFF},
-		{VFE_CMD_STATS_IHIST_STOP},
-		{VFE_CMD_DUMMY_10},
-		{VFE_CMD_SYNC_TIMER_SETTING, V32_SYNC_TIMER_LEN,
-			V32_SYNC_TIMER_OFF},
-/*100*/	{VFE_CMD_ASYNC_TIMER_SETTING, V32_ASYNC_TIMER_LEN, V32_ASYNC_TIMER_OFF},
-		{VFE_CMD_LIVESHOT},
-		{VFE_CMD_LA_SETUP},
-		{VFE_CMD_LINEARIZATION_CFG, V32_LINEARIZATION_LEN1,
-			V32_LINEARIZATION_OFF1},
-		{VFE_CMD_DEMOSAICV3},
-/*105*/	{VFE_CMD_DEMOSAICV3_ABCC_CFG},
-		{VFE_CMD_DEMOSAICV3_DBCC_CFG, V32_DEMOSAICV3_DBCC_LEN,
-			V32_DEMOSAICV3_DBCC_OFF},
-		{VFE_CMD_DEMOSAICV3_DBPC_CFG},
-		{VFE_CMD_DEMOSAICV3_ABF_CFG, V32_DEMOSAICV3_ABF_LEN,
-			V32_DEMOSAICV3_ABF_OFF},
-		{VFE_CMD_DEMOSAICV3_ABCC_UPDATE},
-/*110*/	{VFE_CMD_DEMOSAICV3_DBCC_UPDATE, V32_DEMOSAICV3_DBCC_LEN,
-			V32_DEMOSAICV3_DBCC_OFF},
-		{VFE_CMD_DEMOSAICV3_DBPC_UPDATE},
-		{VFE_CMD_XBAR_CFG},
-		{VFE_CMD_MODULE_CFG, V32_MODULE_CFG_LEN, V32_MODULE_CFG_OFF},
-		{VFE_CMD_ZSL},
-/*115*/	{VFE_CMD_LINEARIZATION_UPDATE, V32_LINEARIZATION_LEN1,
-			V32_LINEARIZATION_OFF1},
-		{VFE_CMD_DEMOSAICV3_ABF_UPDATE, V32_DEMOSAICV3_ABF_LEN,
-			V32_DEMOSAICV3_ABF_OFF},
-		{VFE_CMD_CLF_CFG, V32_CLF_CFG_LEN, V32_CLF_CFG_OFF},
-		{VFE_CMD_CLF_LUMA_UPDATE, V32_CLF_LUMA_UPDATE_LEN,
-			V32_CLF_LUMA_UPDATE_OFF},
-		{VFE_CMD_CLF_CHROMA_UPDATE, V32_CLF_CHROMA_UPDATE_LEN,
-			V32_CLF_CHROMA_UPDATE_OFF},
-/*120*/ {VFE_CMD_PCA_ROLL_OFF_CFG},
-		{VFE_CMD_PCA_ROLL_OFF_UPDATE},
-		{VFE_CMD_GET_REG_DUMP},
-		{VFE_CMD_GET_LINEARIZATON_TABLE},
-		{VFE_CMD_GET_MESH_ROLLOFF_TABLE},
-/*125*/ {VFE_CMD_GET_PCA_ROLLOFF_TABLE},
-		{VFE_CMD_GET_RGB_G_TABLE},
-		{VFE_CMD_GET_LA_TABLE},
-		{VFE_CMD_DEMOSAICV3_UPDATE},
-		{VFE_CMD_ACTIVE_REGION_CFG},
-/*130*/ {VFE_CMD_COLOR_PROCESSING_CONFIG},
-		{VFE_CMD_STATS_WB_AEC_CONFIG},
-		{VFE_CMD_STATS_WB_AEC_UPDATE},
-		{VFE_CMD_Y_GAMMA_CONFIG},
-		{VFE_CMD_SCALE_OUTPUT1_CONFIG},
-/*135*/ {VFE_CMD_SCALE_OUTPUT2_CONFIG},
-		{VFE_CMD_CAPTURE_RAW},
-		{VFE_CMD_STOP_LIVESHOT},
-		{VFE_CMD_RECONFIG_VFE},
-		{VFE_CMD_STATS_REQBUF},
-/*140*/	{VFE_CMD_STATS_ENQUEUEBUF},
-		{VFE_CMD_STATS_FLUSH_BUFQ},
-		{VFE_CMD_STATS_UNREGBUF},
-		{VFE_CMD_STATS_BG_START, V32_STATS_BG_LEN, V32_STATS_BG_OFF},
-		{VFE_CMD_STATS_BG_STOP},
-		{VFE_CMD_STATS_BF_START, V32_STATS_BF_LEN, V32_STATS_BF_OFF},
-/*145*/ {VFE_CMD_STATS_BF_STOP},
-		{VFE_CMD_STATS_BHIST_START, V32_STATS_BHIST_LEN,
-			V32_STATS_BHIST_OFF},
-/*147*/	{VFE_CMD_STATS_BHIST_STOP},
-};
-
-uint32_t vfe32_AXI_WM_CFG[] = {
-	0x0000004C,
-	0x00000064,
-	0x0000007C,
-	0x00000094,
-	0x000000AC,
-	0x000000C4,
-	0x000000DC,
-};
-
-static const char * const vfe32_general_cmd[] = {
-	"DUMMY_0",  /* 0 */
-	"SET_CLK",
-	"RESET",
-	"START",
-	"TEST_GEN_START",
-	"OPERATION_CFG",  /* 5 */
-	"AXI_OUT_CFG",
-	"CAMIF_CFG",
-	"AXI_INPUT_CFG",
-	"BLACK_LEVEL_CFG",
-	"ROLL_OFF_CFG",  /* 10 */
-	"DEMUX_CFG",
-	"FOV_CFG",
-	"MAIN_SCALER_CFG",
-	"WB_CFG",
-	"COLOR_COR_CFG", /* 15 */
-	"RGB_G_CFG",
-	"LA_CFG",
-	"CHROMA_EN_CFG",
-	"CHROMA_SUP_CFG",
-	"MCE_CFG", /* 20 */
-	"SK_ENHAN_CFG",
-	"ASF_CFG",
-	"S2Y_CFG",
-	"S2CbCr_CFG",
-	"CHROMA_SUBS_CFG",  /* 25 */
-	"OUT_CLAMP_CFG",
-	"FRAME_SKIP_CFG",
-	"DUMMY_1",
-	"DUMMY_2",
-	"DUMMY_3",  /* 30 */
-	"UPDATE",
-	"BL_LVL_UPDATE",
-	"DEMUX_UPDATE",
-	"FOV_UPDATE",
-	"MAIN_SCALER_UPDATE",  /* 35 */
-	"WB_UPDATE",
-	"COLOR_COR_UPDATE",
-	"RGB_G_UPDATE",
-	"LA_UPDATE",
-	"CHROMA_EN_UPDATE",  /* 40 */
-	"CHROMA_SUP_UPDATE",
-	"MCE_UPDATE",
-	"SK_ENHAN_UPDATE",
-	"S2CbCr_UPDATE",
-	"S2Y_UPDATE",  /* 45 */
-	"ASF_UPDATE",
-	"FRAME_SKIP_UPDATE",
-	"CAMIF_FRAME_UPDATE",
-	"STATS_AF_UPDATE",
-	"STATS_AE_UPDATE",  /* 50 */
-	"STATS_AWB_UPDATE",
-	"STATS_RS_UPDATE",
-	"STATS_CS_UPDATE",
-	"STATS_SKIN_UPDATE",
-	"STATS_IHIST_UPDATE",  /* 55 */
-	"DUMMY_4",
-	"EPOCH1_ACK",
-	"EPOCH2_ACK",
-	"START_RECORDING",
-	"STOP_RECORDING",  /* 60 */
-	"DUMMY_5",
-	"DUMMY_6",
-	"CAPTURE",
-	"DUMMY_7",
-	"STOP",  /* 65 */
-	"GET_HW_VERSION",
-	"GET_FRAME_SKIP_COUNTS",
-	"OUTPUT1_BUFFER_ENQ",
-	"OUTPUT2_BUFFER_ENQ",
-	"OUTPUT3_BUFFER_ENQ",  /* 70 */
-	"JPEG_OUT_BUF_ENQ",
-	"RAW_OUT_BUF_ENQ",
-	"RAW_IN_BUF_ENQ",
-	"STATS_AF_ENQ",
-	"STATS_AE_ENQ",  /* 75 */
-	"STATS_AWB_ENQ",
-	"STATS_RS_ENQ",
-	"STATS_CS_ENQ",
-	"STATS_SKIN_ENQ",
-	"STATS_IHIST_ENQ",  /* 80 */
-	"DUMMY_8",
-	"JPEG_ENC_CFG",
-	"DUMMY_9",
-	"STATS_AF_START",
-	"STATS_AF_STOP",  /* 85 */
-	"STATS_AE_START",
-	"STATS_AE_STOP",
-	"STATS_AWB_START",
-	"STATS_AWB_STOP",
-	"STATS_RS_START",  /* 90 */
-	"STATS_RS_STOP",
-	"STATS_CS_START",
-	"STATS_CS_STOP",
-	"STATS_SKIN_START",
-	"STATS_SKIN_STOP",  /* 95 */
-	"STATS_IHIST_START",
-	"STATS_IHIST_STOP",
-	"DUMMY_10",
-	"SYNC_TIMER_SETTING",
-	"ASYNC_TIMER_SETTING",  /* 100 */
-	"LIVESHOT",
-	"LA_SETUP",
-	"LINEARIZATION_CFG",
-	"DEMOSAICV3",
-	"DEMOSAICV3_ABCC_CFG", /* 105 */
-	"DEMOSAICV3_DBCC_CFG",
-	"DEMOSAICV3_DBPC_CFG",
-	"DEMOSAICV3_ABF_CFG",
-	"DEMOSAICV3_ABCC_UPDATE",
-	"DEMOSAICV3_DBCC_UPDATE", /* 110 */
-	"DEMOSAICV3_DBPC_UPDATE",
-	"XBAR_CFG",
-	"EZTUNE_CFG",
-	"V32_ZSL",
-	"LINEARIZATION_UPDATE", /*115*/
-	"DEMOSAICV3_ABF_UPDATE",
-	"CLF_CFG",
-	"CLF_LUMA_UPDATE",
-	"CLF_CHROMA_UPDATE",
-	"PCA_ROLL_OFF_CFG", /*120*/
-	"PCA_ROLL_OFF_UPDATE",
-	"GET_REG_DUMP",
-	"GET_LINEARIZATON_TABLE",
-	"GET_MESH_ROLLOFF_TABLE",
-	"GET_PCA_ROLLOFF_TABLE", /*125*/
-	"GET_RGB_G_TABLE",
-	"GET_LA_TABLE",
-	"DEMOSAICV3_UPDATE",
-	"DUMMY_11",
-	"DUMMY_12", /*130*/
-	"DUMMY_13",
-	"DUMMY_14",
-	"DUMMY_15",
-	"DUMMY_16",
-	"DUMMY_17", /*135*/
-	"DUMMY_18",
-	"DUMMY_19",
-	"DUMMY_20",
-	"STATS_REQBUF",
-	"STATS_ENQUEUEBUF", /*140*/
-	"STATS_FLUSH_BUFQ",
-	"STATS_UNREGBUF",
-	"STATS_BG_START",
-	"STATS_BG_STOP",
-	"STATS_BF_START", /*145*/
-	"STATS_BF_STOP",
-	"STATS_BHIST_START",
-	"STATS_BHIST_STOP",
-	"RESET_2",
-};
-
-uint8_t vfe32_use_bayer_stats(struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	if (vfe32_ctrl->ver_num.main >= 4) {
-		/* VFE 4 or above uses bayer stats */
-		return TRUE;
-	} else {
-		return FALSE;
-	}
-}
-
-static void axi_enable_wm_irq(struct vfe_share_ctrl_t *share_ctrl)
-{
-	uint32_t irq_mask, irq_comp_mask = 0;
-	uint16_t vfe_output_mode =
-		share_ctrl->outpath.output_mode &
-			~(VFE32_OUTPUT_MODE_TERTIARY1|
-			VFE32_OUTPUT_MODE_TERTIARY2);
-
-	if (vfe_output_mode)
-		irq_comp_mask =
-		msm_camera_io_r(share_ctrl->vfebase +
-			VFE_IRQ_COMP_MASK);
-	irq_mask = msm_camera_io_r(share_ctrl->vfebase +
-				VFE_IRQ_MASK_0);
-
-	if (share_ctrl->outpath.output_mode &
-			VFE32_OUTPUT_MODE_PRIMARY) {
-		if (share_ctrl->current_mode == VFE_OUTPUTS_RAW)
-			irq_comp_mask |= (
-				0x1 << share_ctrl->outpath.out0.ch0);
-		else
-			irq_comp_mask |= (
-				0x1 << share_ctrl->outpath.out0.ch0 |
-				0x1 << share_ctrl->outpath.out0.ch1);
-		irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
-	} else if (share_ctrl->outpath.output_mode &
-			   VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
-		irq_comp_mask |= (
-			0x1 << share_ctrl->outpath.out0.ch0 |
-			0x1 << share_ctrl->outpath.out0.ch1 |
-			0x1 << share_ctrl->outpath.out0.ch2);
-		irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
-	}
-	if (share_ctrl->outpath.output_mode &
-			VFE32_OUTPUT_MODE_SECONDARY) {
-		irq_comp_mask |= (
-			0x1 << (share_ctrl->outpath.out1.ch0 + 8) |
-			0x1 << (share_ctrl->outpath.out1.ch1 + 8));
-		irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
-	} else if (share_ctrl->outpath.output_mode &
-			VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
-		irq_comp_mask |= (
-			0x1 << (share_ctrl->outpath.out1.ch0 + 8) |
-			0x1 << (share_ctrl->outpath.out1.ch1 + 8) |
-			0x1 << (share_ctrl->outpath.out1.ch2 + 8));
-		irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
-	}
-
-	if (share_ctrl->outpath.output_mode &
-		VFE32_OUTPUT_MODE_TERTIARY1) {
-		irq_mask |= (0x1 << (share_ctrl->outpath.out2.ch0 +
-			VFE_WM_OFFSET));
-	}
-
-	if (share_ctrl->outpath.output_mode &
-		VFE32_OUTPUT_MODE_TERTIARY2) {
-		irq_mask |= (0x1 << (share_ctrl->outpath.out3.ch0 +
-			VFE_WM_OFFSET));
-	}
-
-	msm_camera_io_w(irq_mask, share_ctrl->vfebase +
-			VFE_IRQ_MASK_0);
-	if (vfe_output_mode)
-		msm_camera_io_w(irq_comp_mask,
-			share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
-}
-
-static void axi_disable_wm_irq(struct vfe_share_ctrl_t *share_ctrl,
-	uint16_t output_mode)
-{
-	uint32_t irq_mask, irq_comp_mask = 0;
-	uint16_t vfe_output_mode =
-		output_mode &
-			~(VFE32_OUTPUT_MODE_TERTIARY1|
-			VFE32_OUTPUT_MODE_TERTIARY2);
-	if (vfe_output_mode)
-		irq_comp_mask =
-		msm_camera_io_r(share_ctrl->vfebase +
-			VFE_IRQ_COMP_MASK);
-	irq_mask = msm_camera_io_r(share_ctrl->vfebase +
-				VFE_IRQ_MASK_0);
-
-	if (output_mode &
-			VFE32_OUTPUT_MODE_PRIMARY) {
-		irq_comp_mask &= ~(
-			0x1 << share_ctrl->outpath.out0.ch0 |
-			0x1 << share_ctrl->outpath.out0.ch1);
-		irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
-	} else if (output_mode &
-			   VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
-		irq_comp_mask &= ~(
-			0x1 << share_ctrl->outpath.out0.ch0 |
-			0x1 << share_ctrl->outpath.out0.ch1 |
-			0x1 << share_ctrl->outpath.out0.ch2);
-		irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
-	}
-	if (output_mode &
-			VFE32_OUTPUT_MODE_SECONDARY) {
-		irq_comp_mask &= ~(
-			0x1 << (share_ctrl->outpath.out1.ch0 + 8) |
-			0x1 << (share_ctrl->outpath.out1.ch1 + 8));
-		irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
-	} else if (output_mode &
-			VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
-		irq_comp_mask &= ~(
-			0x1 << (share_ctrl->outpath.out1.ch0 + 8) |
-			0x1 << (share_ctrl->outpath.out1.ch1 + 8) |
-			0x1 << (share_ctrl->outpath.out1.ch2 + 8));
-		irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
-	}
-	if (output_mode &
-			VFE32_OUTPUT_MODE_TERTIARY1) {
-			irq_mask &= ~(0x1 << (share_ctrl->outpath.out2.ch0 +
-				VFE_WM_OFFSET));
-	}
-	if (output_mode &
-		VFE32_OUTPUT_MODE_TERTIARY2) {
-		irq_mask &= ~(0x1 << (share_ctrl->outpath.out3.ch0 +
-			VFE_WM_OFFSET));
-	}
-	msm_camera_io_w(irq_mask, share_ctrl->vfebase +
-				VFE_IRQ_MASK_0);
-	if (vfe_output_mode)
-		msm_camera_io_w(irq_comp_mask,
-			share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
-}
-
-static void axi_enable_irq(struct vfe_share_ctrl_t *share_ctrl)
-{
-	uint32_t irq_mask, irq_mask1;
-	uint32_t vfe_mode =
-		share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
-			VFE_OUTPUTS_RDI1);
-
-	if (share_ctrl->axi_ref_cnt == 1) {
-		irq_mask1 =
-			msm_camera_io_r(share_ctrl->vfebase +
-				VFE_IRQ_MASK_1);
-
-		irq_mask1 |= VFE_IMASK_WHILE_STOPPING_1;
-			msm_camera_io_w(irq_mask1, share_ctrl->vfebase +
-				VFE_IRQ_MASK_1);
-	}
-
-	if (share_ctrl->current_mode & (VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1)) {
-		irq_mask1 =
-			msm_camera_io_r(share_ctrl->vfebase +
-				VFE_IRQ_MASK_1);
-
-		if (share_ctrl->current_mode & VFE_OUTPUTS_RDI0)
-			irq_mask1 |= VFE_IRQ_STATUS1_RDI0_REG_UPDATE_MASK;
-
-		if (share_ctrl->current_mode & VFE_OUTPUTS_RDI1)
-			irq_mask1 |= VFE_IRQ_STATUS1_RDI1_REG_UPDATE_MASK;
-
-		msm_camera_io_w(irq_mask1, share_ctrl->vfebase +
-			VFE_IRQ_MASK_1);
-	}
-
-	if (vfe_mode) {
-		irq_mask =
-		msm_camera_io_r(share_ctrl->vfebase +
-			VFE_IRQ_MASK_0);
-		irq_mask |= 0x00000021;
-		if (share_ctrl->stats_comp)
-			irq_mask |= VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK;
-		else
-			irq_mask |= 0x000FE000;
-		msm_camera_io_w(irq_mask, share_ctrl->vfebase +
-			VFE_IRQ_MASK_0);
-		atomic_set(&share_ctrl->vstate, 1);
-	}
-	atomic_set(&share_ctrl->handle_common_irq, 1);
-}
-
-static void axi_clear_all_interrupts(struct vfe_share_ctrl_t *share_ctrl)
-{
-	atomic_set(&share_ctrl->handle_common_irq, 0);
-	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
-		share_ctrl->vfebase + VFE_IRQ_MASK_0);
-	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
-		share_ctrl->vfebase + VFE_IRQ_MASK_1);
-
-	/* clear all pending interrupts*/
-	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
-		share_ctrl->vfebase + VFE_IRQ_CLEAR_0);
-	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
-		share_ctrl->vfebase + VFE_IRQ_CLEAR_1);
-	/* Ensure the write order while writing
-	*to the command register using the barrier */
-	msm_camera_io_w_mb(1,
-		share_ctrl->vfebase + VFE_IRQ_CMD);
-}
-
-static void axi_disable_irq(struct vfe_share_ctrl_t *share_ctrl,
-	uint32_t mode)
-{
-
-	/* disable all interrupts.  */
-
-	uint32_t irq_mask = 0, irq_mask1 = 0, clear_mask1 = 0;
-	uint32_t vfe_mode =
-		(mode & ~(VFE_OUTPUTS_RDI0|
-			VFE_OUTPUTS_RDI1));
-
-	if (mode & (VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1)) {
-		irq_mask1 =
-			msm_camera_io_r(share_ctrl->vfebase +
-				VFE_IRQ_MASK_1);
-
-		if (mode & VFE_OUTPUTS_RDI0) {
-			irq_mask1 &= ~(VFE_IRQ_STATUS1_RDI0_REG_UPDATE_MASK);
-			clear_mask1 |= VFE_IRQ_STATUS1_RDI0_REG_UPDATE_MASK;
-		}
-
-		if (mode & VFE_OUTPUTS_RDI1) {
-			irq_mask1 &= ~(VFE_IRQ_STATUS1_RDI1_REG_UPDATE_MASK);
-			clear_mask1 |= VFE_IRQ_STATUS1_RDI1_REG_UPDATE_MASK;
-		}
-
-		msm_camera_io_w(irq_mask1, share_ctrl->vfebase +
-			VFE_IRQ_MASK_1);
-		msm_camera_io_w(clear_mask1,
-			share_ctrl->vfebase + VFE_IRQ_CLEAR_1);
-	}
-
-	if (vfe_mode) {
-		atomic_set(&share_ctrl->vstate, 0);
-		irq_mask =
-		msm_camera_io_r(share_ctrl->vfebase +
-			VFE_IRQ_MASK_0);
-		irq_mask &= ~(0x00000021);
-		if (share_ctrl->stats_comp)
-			irq_mask &= ~(VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK);
-		else
-			irq_mask &= ~0x000FE000;
-		msm_camera_io_w(irq_mask, share_ctrl->vfebase +
-			VFE_IRQ_MASK_0);
-	}
-}
-
-static void vfe32_stop(struct vfe32_ctrl_type *vfe32_ctrl)
-{
-
-	/* in either continuous or snapshot mode, stop command can be issued
-	 * at any time. stop camif immediately. */
-	if (!vfe32_ctrl->share_ctrl->dual_enabled)
-		msm_camera_io_w_mb(CAMIF_COMMAND_STOP_IMMEDIATELY,
-			vfe32_ctrl->share_ctrl->vfebase + VFE_CAMIF_COMMAND);
-	else
-		msm_camera_io_w(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
-			vfe32_ctrl->share_ctrl->vfebase + VFE_CAMIF_COMMAND);
-	vfe32_ctrl->share_ctrl->operation_mode &=
-		(VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1);
-}
-
-static void vfe32_subdev_notify(int id, int path, uint32_t inst_handle,
-	struct v4l2_subdev *sd, struct vfe_share_ctrl_t *share_ctrl)
-{
-	struct msm_vfe_resp rp;
-	struct msm_frame_info frame_info;
-	unsigned long flags = 0;
-	spin_lock_irqsave(&share_ctrl->sd_notify_lock, flags);
-	CDBG("vfe32_subdev_notify : msgId = %d\n", id);
-	memset(&rp, 0, sizeof(struct msm_vfe_resp));
-	rp.evt_msg.type   = MSM_CAMERA_MSG;
-	frame_info.inst_handle = inst_handle;
-	frame_info.path = path;
-	rp.evt_msg.data = &frame_info;
-	rp.type	   = id;
-	v4l2_subdev_notify(sd, NOTIFY_VFE_BUF_EVT, &rp);
-	spin_unlock_irqrestore(&share_ctrl->sd_notify_lock, flags);
-}
-
-static int vfe32_config_axi(
-	struct axi_ctrl_t *axi_ctrl, int mode, uint32_t *ao)
-{
-	uint32_t *ch_info;
-	uint32_t *axi_cfg = ao+V32_AXI_BUS_FMT_OFF;
-	int vfe_mode = (mode & ~(OUTPUT_TERT1|OUTPUT_TERT2));
-	uint32_t bus_cmd = *axi_cfg;
-	int i;
-
-	/* Update the corresponding write masters for each output*/
-	ch_info = axi_cfg + V32_AXI_CFG_LEN;
-	axi_ctrl->share_ctrl->outpath.out0.ch0 = 0x0000FFFF & *ch_info;
-	axi_ctrl->share_ctrl->outpath.out0.ch1 =
-		0x0000FFFF & (*ch_info++ >> 16);
-	axi_ctrl->share_ctrl->outpath.out0.ch2 = 0x0000FFFF & *ch_info++;
-	axi_ctrl->share_ctrl->outpath.out0.inst_handle = *ch_info++;
-
-	axi_ctrl->share_ctrl->outpath.out1.ch0 = 0x0000FFFF & *ch_info;
-	axi_ctrl->share_ctrl->outpath.out1.ch1 =
-		0x0000FFFF & (*ch_info++ >> 16);
-	axi_ctrl->share_ctrl->outpath.out1.ch2 = 0x0000FFFF & *ch_info++;
-	axi_ctrl->share_ctrl->outpath.out1.inst_handle = *ch_info++;
-
-	axi_ctrl->share_ctrl->outpath.out2.ch0 = 0x0000FFFF & *ch_info;
-	axi_ctrl->share_ctrl->outpath.out2.ch1 =
-		0x0000FFFF & (*ch_info++ >> 16);
-	axi_ctrl->share_ctrl->outpath.out2.ch2 = 0x0000FFFF & *ch_info++;
-	axi_ctrl->share_ctrl->outpath.out2.inst_handle = *ch_info++;
-
-	axi_ctrl->share_ctrl->outpath.out3.ch0 = 0x0000FFFF & *ch_info;
-	axi_ctrl->share_ctrl->outpath.out3.ch1 =
-		0x0000FFFF & (*ch_info++ >> 16);
-	axi_ctrl->share_ctrl->outpath.out3.ch2 = 0x0000FFFF & *ch_info++;
-	axi_ctrl->share_ctrl->outpath.out3.inst_handle = *ch_info++;
-
-	axi_ctrl->share_ctrl->outpath.output_mode = 0;
-
-	if (mode & OUTPUT_TERT1)
-		axi_ctrl->share_ctrl->outpath.output_mode |=
-			VFE32_OUTPUT_MODE_TERTIARY1;
-	if (mode & OUTPUT_TERT2)
-		axi_ctrl->share_ctrl->outpath.output_mode |=
-			VFE32_OUTPUT_MODE_TERTIARY2;
-	if (mode == OUTPUT_TERT1 || mode == OUTPUT_TERT1
-		|| mode == (OUTPUT_TERT1|OUTPUT_TERT2))
-			goto bus_cfg;
-
-	switch (vfe_mode) {
-	case OUTPUT_PRIM:
-		axi_ctrl->share_ctrl->outpath.output_mode |=
-			VFE32_OUTPUT_MODE_PRIMARY;
-		break;
-	case OUTPUT_PRIM_ALL_CHNLS:
-		axi_ctrl->share_ctrl->outpath.output_mode |=
-			VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
-		break;
-	case OUTPUT_PRIM|OUTPUT_SEC:
-		axi_ctrl->share_ctrl->outpath.output_mode |=
-			VFE32_OUTPUT_MODE_PRIMARY;
-		axi_ctrl->share_ctrl->outpath.output_mode |=
-			VFE32_OUTPUT_MODE_SECONDARY;
-		break;
-	case OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS:
-		axi_ctrl->share_ctrl->outpath.output_mode |=
-			VFE32_OUTPUT_MODE_PRIMARY;
-		axi_ctrl->share_ctrl->outpath.output_mode |=
-			VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS;
-		break;
-	case OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC:
-		axi_ctrl->share_ctrl->outpath.output_mode |=
-			VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
-		axi_ctrl->share_ctrl->outpath.output_mode |=
-			VFE32_OUTPUT_MODE_SECONDARY;
-		break;
-	default:
-		pr_err("%s Invalid AXI mode %d ", __func__, mode);
-		return -EINVAL;
-	}
-
-bus_cfg:
-	msm_camera_io_w(*ao, axi_ctrl->share_ctrl->vfebase +
-		VFE_BUS_IO_FORMAT_CFG);
-	axi_cfg++;
-	msm_camera_io_memcpy(axi_ctrl->share_ctrl->vfebase +
-		vfe32_cmd[VFE_CMD_AXI_OUT_CFG].offset, axi_cfg,
-		V32_AXI_BUS_CFG_LEN);
-	axi_cfg += V32_AXI_BUS_CFG_LEN/4;
-	for (i = 0; i < ARRAY_SIZE(vfe32_AXI_WM_CFG); i++) {
-		axi_cfg += 3;
-		msm_camera_io_memcpy(
-			axi_ctrl->share_ctrl->vfebase+vfe32_AXI_WM_CFG[i]+12,
-								axi_cfg, 12);
-		axi_cfg += 3;
-	}
-	msm_camera_io_w(bus_cmd, axi_ctrl->share_ctrl->vfebase +
-					V32_AXI_BUS_CMD_OFF);
-	msm_camera_io_w(*ch_info++,
-		axi_ctrl->share_ctrl->vfebase + VFE_PIXEL_IF_CFG);
-	if (msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
-		V32_GET_HW_VERSION_OFF) ==
-		VFE33_HW_NUMBER) {
-		msm_camera_io_w(*ch_info++,
-			axi_ctrl->share_ctrl->vfebase + VFE_RDI0_CFG);
-		msm_camera_io_w(*ch_info++,
-			axi_ctrl->share_ctrl->vfebase + VFE_RDI1_CFG);
-	}
-	return 0;
-}
-
-static void axi_reset_internal_variables(
-	struct axi_ctrl_t *axi_ctrl,
-	struct msm_camera_vfe_params_t vfe_params)
-{
-	if (vfe_params.operation_mode & VFE_OUTPUTS_RDI0) {
-		atomic_set(&axi_ctrl->share_ctrl->rdi0_update_ack_pending, 0);
-		axi_ctrl->share_ctrl->rdi0_capture_count = -1;
-		axi_ctrl->share_ctrl->outpath.out2.capture_cnt = -1;
-		axi_ctrl->share_ctrl->rdi0FrameId = 0;
-		axi_ctrl->share_ctrl->comp_output_mode &=
-			~VFE32_OUTPUT_MODE_TERTIARY1;
-		axi_ctrl->share_ctrl->operation_mode &=
-			~(VFE_OUTPUTS_RDI0);
-	}
-
-	if (vfe_params.operation_mode & VFE_OUTPUTS_RDI1) {
-		atomic_set(&axi_ctrl->share_ctrl->rdi1_update_ack_pending, 0);
-		axi_ctrl->share_ctrl->rdi1_capture_count = -1;
-		axi_ctrl->share_ctrl->outpath.out3.capture_cnt = -1;
-		axi_ctrl->share_ctrl->rdi1FrameId = 0;
-		axi_ctrl->share_ctrl->comp_output_mode &=
-			~VFE32_OUTPUT_MODE_TERTIARY2;
-		axi_ctrl->share_ctrl->operation_mode &=
-			~(VFE_OUTPUTS_RDI1);
-	}
-}
-
-static void axi_global_reset_internal_variables(
-	struct axi_ctrl_t *axi_ctrl)
-{
-	unsigned long flags;
-	/* state control variables */
-	axi_ctrl->share_ctrl->start_ack_pending = FALSE;
-	atomic_set(&irq_cnt, 0);
-
-	spin_lock_irqsave(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
-	axi_ctrl->share_ctrl->stop_ack_pending  = FALSE;
-	spin_unlock_irqrestore(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
-
-	init_completion(&axi_ctrl->share_ctrl->reset_complete);
-
-	spin_lock_irqsave(&axi_ctrl->share_ctrl->update_ack_lock, flags);
-	axi_ctrl->share_ctrl->update_ack_pending = FALSE;
-	spin_unlock_irqrestore(&axi_ctrl->share_ctrl->update_ack_lock, flags);
-
-	axi_ctrl->share_ctrl->recording_state = VFE_STATE_IDLE;
-	axi_ctrl->share_ctrl->liveshot_state = VFE_STATE_IDLE;
-
-	atomic_set(&axi_ctrl->share_ctrl->vstate, 0);
-	atomic_set(&axi_ctrl->share_ctrl->handle_common_irq, 0);
-	atomic_set(&axi_ctrl->share_ctrl->pix0_update_ack_pending, 0);
-	atomic_set(&axi_ctrl->share_ctrl->rdi0_update_ack_pending, 0);
-	atomic_set(&axi_ctrl->share_ctrl->rdi1_update_ack_pending, 0);
-	atomic_set(&axi_ctrl->share_ctrl->rdi2_update_ack_pending, 0);
-
-	/* 0 for continuous mode, 1 for snapshot mode */
-	axi_ctrl->share_ctrl->operation_mode = 0;
-	axi_ctrl->share_ctrl->current_mode = 0;
-	axi_ctrl->share_ctrl->outpath.output_mode = 0;
-	axi_ctrl->share_ctrl->comp_output_mode = 0;
-	axi_ctrl->share_ctrl->vfe_capture_count = 0;
-	axi_ctrl->share_ctrl->rdi0_capture_count = -1;
-	axi_ctrl->share_ctrl->rdi1_capture_count = -1;
-	axi_ctrl->share_ctrl->outpath.out0.capture_cnt = -1;
-	axi_ctrl->share_ctrl->outpath.out1.capture_cnt = -1;
-	axi_ctrl->share_ctrl->outpath.out2.capture_cnt = -1;
-	axi_ctrl->share_ctrl->outpath.out3.capture_cnt = -1;
-
-	/* this is unsigned 32 bit integer. */
-	axi_ctrl->share_ctrl->vfeFrameId = 0;
-	axi_ctrl->share_ctrl->rdi0FrameId = 0;
-	axi_ctrl->share_ctrl->rdi1FrameId = 0;
-	axi_ctrl->share_ctrl->rdi2FrameId = 0;
-}
-
-
-static void vfe32_program_dmi_cfg(
-	enum VFE32_DMI_RAM_SEL bankSel,
-	struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	/* set bit 8 for auto increment. */
-	uint32_t value = VFE_DMI_CFG_DEFAULT;
-	value += (uint32_t)bankSel;
-	CDBG("%s: banksel = %d\n", __func__, bankSel);
-
-	msm_camera_io_w(value, vfe32_ctrl->share_ctrl->vfebase +
-		VFE_DMI_CFG);
-	/* by default, always starts with offset 0.*/
-	msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
-		VFE_DMI_ADDR);
-}
-
-static void vfe32_reset_dmi_tables(
-	struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	int i = 0;
-
-	/* Reset Histogram LUTs */
-	CDBG("Reset Bayer histogram LUT : 0\n");
-	vfe32_program_dmi_cfg(STATS_BHIST_RAM0, vfe32_ctrl);
-	/* Loop for configuring LUT */
-	for (i = 0; i < 256; i++) {
-		msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
-			VFE_DMI_DATA_HI);
-		msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
-			VFE_DMI_DATA_LO);
-	}
-	vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
-
-	CDBG("Reset Bayer Histogram LUT: 1\n");
-	vfe32_program_dmi_cfg(STATS_BHIST_RAM1, vfe32_ctrl);
-	/* Loop for configuring LUT */
-	for (i = 0; i < 256; i++) {
-		msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
-			VFE_DMI_DATA_HI);
-		msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
-			VFE_DMI_DATA_LO);
-	}
-	vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
-
-	CDBG("Reset IHistogram LUT\n");
-	vfe32_program_dmi_cfg(STATS_IHIST_RAM, vfe32_ctrl);
-	/* Loop for configuring LUT */
-	for (i = 0; i < 256; i++) {
-		msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
-			VFE_DMI_DATA_HI);
-		msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
-			VFE_DMI_DATA_LO);
-	}
-	vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
-}
-
-static void vfe32_set_default_reg_values(
-	struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	msm_camera_io_w(0x800080,
-		vfe32_ctrl->share_ctrl->vfebase + VFE_DEMUX_GAIN_0);
-	msm_camera_io_w(0x800080,
-		vfe32_ctrl->share_ctrl->vfebase + VFE_DEMUX_GAIN_1);
-	/* What value should we program CGC_OVERRIDE to? */
-	msm_camera_io_w(0xFFFFF,
-		vfe32_ctrl->share_ctrl->vfebase + VFE_CGC_OVERRIDE);
-
-	/* default frame drop period and pattern */
-	msm_camera_io_w(0x1f,
-		vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_CFG);
-	msm_camera_io_w(0x1f,
-		vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_CFG);
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_PATTERN);
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe32_ctrl->share_ctrl->vfebase +
-		VFE_FRAMEDROP_ENC_CBCR_PATTERN);
-	msm_camera_io_w(0x1f,
-		vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y);
-	msm_camera_io_w(0x1f,
-		vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR);
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_PATTERN);
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe32_ctrl->share_ctrl->vfebase +
-		VFE_FRAMEDROP_VIEW_CBCR_PATTERN);
-	msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase + VFE_CLAMP_MIN);
-	msm_camera_io_w(0xFFFFFF,
-		vfe32_ctrl->share_ctrl->vfebase + VFE_CLAMP_MAX);
-
-	/* stats UB config */
-	CDBG("%s: Use bayer stats = %d\n", __func__,
-		 vfe32_use_bayer_stats(vfe32_ctrl));
-	if (!vfe32_use_bayer_stats(vfe32_ctrl)) {
-		msm_camera_io_w(0x3980007,
-			vfe32_ctrl->share_ctrl->vfebase +
-				VFE_BUS_STATS_AEC_BG_UB_CFG);
-		msm_camera_io_w(0x3A00007,
-			vfe32_ctrl->share_ctrl->vfebase +
-				VFE_BUS_STATS_AF_BF_UB_CFG);
-		msm_camera_io_w(0x3A8000F,
-			vfe32_ctrl->share_ctrl->vfebase +
-				VFE_BUS_STATS_AWB_UB_CFG);
-		msm_camera_io_w(0x3B80007,
-			vfe32_ctrl->share_ctrl->vfebase +
-				VFE_BUS_STATS_RS_UB_CFG);
-		msm_camera_io_w(0x3C0001F,
-			vfe32_ctrl->share_ctrl->vfebase +
-				VFE_BUS_STATS_CS_UB_CFG);
-		msm_camera_io_w(0x3E0001F,
-			vfe32_ctrl->share_ctrl->vfebase +
-				VFE_BUS_STATS_HIST_UB_CFG);
-	} else {
-		msm_camera_io_w(0x350001F,
-			vfe32_ctrl->share_ctrl->vfebase +
-				VFE_BUS_STATS_HIST_UB_CFG);
-		msm_camera_io_w(0x370002F,
-			vfe32_ctrl->share_ctrl->vfebase +
-				VFE_BUS_STATS_AEC_BG_UB_CFG);
-		msm_camera_io_w(0x3A0002F,
-			vfe32_ctrl->share_ctrl->vfebase +
-				VFE_BUS_STATS_AF_BF_UB_CFG);
-		msm_camera_io_w(0x3D00007,
-			vfe32_ctrl->share_ctrl->vfebase +
-				VFE_BUS_STATS_RS_UB_CFG);
-		msm_camera_io_w(0x3D8001F,
-			vfe32_ctrl->share_ctrl->vfebase +
-				VFE_BUS_STATS_CS_UB_CFG);
-		msm_camera_io_w(0x3F80007,
-			vfe32_ctrl->share_ctrl->vfebase +
-				VFE_BUS_STATS_SKIN_BHIST_UB_CFG);
-	}
-	vfe32_reset_dmi_tables(vfe32_ctrl);
-}
-
-static void vfe32_reset_internal_variables(
-	struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	unsigned long flags;
-	spin_lock_irqsave(&vfe32_ctrl->share_ctrl->update_ack_lock,
-		flags);
-	vfe32_ctrl->share_ctrl->update_ack_pending = FALSE;
-	spin_unlock_irqrestore(&vfe32_ctrl->share_ctrl->update_ack_lock,
-		flags);
-	vfe32_ctrl->share_ctrl->vfe_capture_count = 0;
-	/* this is unsigned 32 bit integer. */
-	vfe32_ctrl->share_ctrl->vfeFrameId = 0;
-	vfe32_ctrl->share_ctrl->update_counter = 0;
-
-	/* Stats control variables. */
-	memset(&(vfe32_ctrl->afbfStatsControl), 0,
-		sizeof(struct vfe_stats_control));
-
-	memset(&(vfe32_ctrl->awbStatsControl), 0,
-		sizeof(struct vfe_stats_control));
-
-	memset(&(vfe32_ctrl->aecbgStatsControl), 0,
-		sizeof(struct vfe_stats_control));
-
-	memset(&(vfe32_ctrl->bhistStatsControl), 0,
-		sizeof(struct vfe_stats_control));
-
-	memset(&(vfe32_ctrl->ihistStatsControl), 0,
-		sizeof(struct vfe_stats_control));
-
-	memset(&(vfe32_ctrl->rsStatsControl), 0,
-		sizeof(struct vfe_stats_control));
-
-	memset(&(vfe32_ctrl->csStatsControl), 0,
-		sizeof(struct vfe_stats_control));
-	vfe32_ctrl->share_ctrl->outpath.out0.capture_cnt = -1;
-	vfe32_ctrl->share_ctrl->outpath.out1.capture_cnt = -1;
-	vfe32_ctrl->share_ctrl->recording_state = VFE_STATE_IDLE;
-	vfe32_ctrl->share_ctrl->liveshot_state = VFE_STATE_IDLE;
-
-	atomic_set(&vfe32_ctrl->share_ctrl->vstate, 0);
-	atomic_set(&vfe32_ctrl->share_ctrl->pix0_update_ack_pending, 0);
-
-	vfe32_ctrl->frame_skip_cnt = 31;
-	vfe32_ctrl->frame_skip_pattern = 0xffffffff;
-	vfe32_ctrl->snapshot_frame_cnt = 0;
-	vfe32_set_default_reg_values(vfe32_ctrl);
-}
-
-
-static int vfe32_reset(struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	uint32_t irq_mask1, irq_mask;
-	atomic_set(&vfe32_ctrl->share_ctrl->vstate, 0);
-	msm_camera_io_w(VFE_MODULE_RESET_CMD,
-		vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_RESET);
-	msm_camera_io_w(0,
-		vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_RESET);
-
-	irq_mask =
-		msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
-			VFE_IRQ_MASK_0);
-	irq_mask &= ~(0x000FE021|VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK);
-
-	msm_camera_io_w(irq_mask, vfe32_ctrl->share_ctrl->vfebase +
-		VFE_IRQ_MASK_0);
-	vfe32_ctrl->share_ctrl->operation_mode &=
-		(VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1);
-	vfe32_ctrl->share_ctrl->comp_output_mode &=
-			(VFE32_OUTPUT_MODE_TERTIARY1|
-			VFE32_OUTPUT_MODE_TERTIARY2);
-
-	/* enable reset_ack interrupt.  */
-	irq_mask1 = msm_camera_io_r(
-		vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
-	irq_mask1 |= VFE_IMASK_WHILE_STOPPING_1;
-	msm_camera_io_w(irq_mask1,
-		vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
-	msm_camera_io_w_mb(VFE_ONLY_RESET_CMD,
-		vfe32_ctrl->share_ctrl->vfebase + VFE_GLOBAL_RESET);
-
-	return wait_for_completion_interruptible(
-			&vfe32_ctrl->share_ctrl->reset_complete);
-}
-
-static int axi_reset(struct axi_ctrl_t *axi_ctrl,
-	struct msm_camera_vfe_params_t vfe_params)
-{
-	int rc = 0;
-	if (vfe_params.skip_reset) {
-		axi_reset_internal_variables(axi_ctrl, vfe_params);
-		return rc;
-	}
-	axi_global_reset_internal_variables(axi_ctrl);
-	/* disable all interrupts.  vfeImaskLocal is also reset to 0
-	* to begin with. */
-	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
-		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_0);
-
-	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
-		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
-
-	/* clear all pending interrupts*/
-	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
-		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_0);
-	msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
-		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_1);
-
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	msm_camera_io_w_mb(1, axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CMD);
-
-	/* enable reset_ack interrupt.  */
-	msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_1,
-		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
-
-	/* Write to VFE_GLOBAL_RESET_CMD to reset the vfe hardware. Once reset
-	 * is done, hardware interrupt will be generated.  VFE ist processes
-	 * the interrupt to complete the function call.  Note that the reset
-	 * function is synchronous. */
-
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	msm_camera_io_w_mb(VFE_RESET_UPON_RESET_CMD,
-		axi_ctrl->share_ctrl->vfebase + VFE_GLOBAL_RESET);
-
-	return wait_for_completion_interruptible(
-			&axi_ctrl->share_ctrl->reset_complete);
-}
-
-static int vfe32_operation_config(uint32_t *cmd,
-			struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	uint32_t *p = cmd;
-
-	vfe32_ctrl->share_ctrl->stats_comp = *(++p);
-	vfe32_ctrl->hfr_mode = *(++p);
-
-	msm_camera_io_w(*(++p),
-		vfe32_ctrl->share_ctrl->vfebase + VFE_CFG);
-	msm_camera_io_w(*(++p),
-		vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-	msm_camera_io_w(*(++p),
-		vfe32_ctrl->share_ctrl->vfebase + VFE_REALIGN_BUF);
-	msm_camera_io_w(*(++p),
-		vfe32_ctrl->share_ctrl->vfebase + VFE_CHROMA_UP);
-	msm_camera_io_w(*(++p),
-		vfe32_ctrl->share_ctrl->vfebase + VFE_STATS_CFG);
-	return 0;
-}
-
-static unsigned long vfe32_stats_dqbuf(struct vfe32_ctrl_type *vfe32_ctrl,
-	enum msm_stats_enum_type stats_type)
-{
-	struct msm_stats_meta_buf *buf = NULL;
-	int rc = 0;
-	rc = vfe32_ctrl->stats_ops.dqbuf(
-			vfe32_ctrl->stats_ops.stats_ctrl, stats_type, &buf);
-	if (rc < 0) {
-		CDBG("%s: dq stats buf (type = %d) err = %d",
-			__func__, stats_type, rc);
-		return 0L;
-	}
-	return buf->paddr;
-}
-
-static unsigned long vfe32_stats_flush_enqueue(
-	struct vfe32_ctrl_type *vfe32_ctrl,
-	enum msm_stats_enum_type stats_type)
-{
-	struct msm_stats_bufq *bufq = NULL;
-	struct msm_stats_meta_buf *stats_buf = NULL;
-	int rc = 0;
-	int i;
-
-	/*
-	 * Passing NULL for ion client as the buffers are already
-	 * mapped at this stage, client is not required, flush all
-	 * the buffers, and buffers move to PREPARE state
-	 */
-
-	rc = vfe32_ctrl->stats_ops.bufq_flush(
-			vfe32_ctrl->stats_ops.stats_ctrl, stats_type, NULL);
-	if (rc < 0) {
-		pr_err("%s: dq stats buf (type = %d) err = %d",
-			__func__, stats_type, rc);
-		return 0L;
-	}
-	/* Queue all the buffers back to QUEUED state */
-	bufq = vfe32_ctrl->stats_ctrl.bufq[stats_type];
-	for (i = 0; i < bufq->num_bufs; i++) {
-		stats_buf = &bufq->bufs[i];
-		rc = vfe32_ctrl->stats_ops.enqueue_buf(
-				vfe32_ctrl->stats_ops.stats_ctrl,
-				&(stats_buf->info), NULL, -1);
-		if (rc < 0) {
-			pr_err("%s: dq stats buf (type = %d) err = %d",
-				 __func__, stats_type, rc);
-			return rc;
-		}
-	}
-	return 0L;
-}
-
-
-static unsigned long vfe32_stats_unregbuf(
-	struct vfe32_ctrl_type *vfe32_ctrl,
-	struct msm_stats_reqbuf *req_buf, int domain_num)
-{
-	int i = 0, rc = 0;
-
-	for (i = 0; i < req_buf->num_buf; i++) {
-		rc = vfe32_ctrl->stats_ops.buf_unprepare(
-			vfe32_ctrl->stats_ops.stats_ctrl,
-			req_buf->stats_type, i,
-			vfe32_ctrl->stats_ops.client, domain_num);
-		if (rc < 0) {
-			pr_err("%s: unreg stats buf (type = %d) err = %d",
-				__func__, req_buf->stats_type, rc);
-		return rc;
-		}
-	}
-	return 0L;
-}
-static int vfe_stats_awb_buf_init(
-	struct vfe32_ctrl_type *vfe32_ctrl,
-	struct vfe_cmd_stats_buf *in)
-{
-	uint32_t addr;
-	unsigned long flags;
-
-	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_AWB);
-	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq awb ping buf from free buf queue", __func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe32_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_AWB_WR_PING_ADDR);
-	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_AWB);
-	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq awb ping buf from free buf queue",
-			__func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe32_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_AWB_WR_PONG_ADDR);
-	return 0;
-}
-
-static uint32_t vfe_stats_aec_bg_buf_init(
-	struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	uint32_t addr;
-	unsigned long flags;
-	uint32_t stats_type;
-
-	stats_type =
-		(!vfe32_use_bayer_stats(vfe32_ctrl)) ? MSM_STATS_TYPE_AEC
-			: MSM_STATS_TYPE_BG;
-	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, stats_type);
-	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq aec ping buf from free buf queue",
-			__func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe32_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_AEC_BG_WR_PING_ADDR);
-	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, stats_type);
-	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq aec pong buf from free buf queue",
-			__func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe32_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_AEC_BG_WR_PONG_ADDR);
-	return 0;
-}
-
-static int vfe_stats_af_bf_buf_init(
-	struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	uint32_t addr;
-	unsigned long flags;
-	int rc = 0;
-
-	uint32_t stats_type;
-	stats_type =
-		(!vfe32_use_bayer_stats(vfe32_ctrl)) ? MSM_STATS_TYPE_AF
-			: MSM_STATS_TYPE_BF;
-
-	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
-	rc = vfe32_stats_flush_enqueue(vfe32_ctrl, stats_type);
-	if (rc < 0) {
-		pr_err("%s: dq stats buf err = %d",
-			   __func__, rc);
-		spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
-		return -EINVAL;
-	}
-	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, stats_type);
-	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq af ping buf from free buf queue", __func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe32_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_AF_BF_WR_PING_ADDR);
-	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, stats_type);
-	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq af pong buf from free buf queue", __func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe32_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_AF_BF_WR_PONG_ADDR);
-	return 0;
-}
-
-static uint32_t vfe_stats_bhist_buf_init(
-	struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	uint32_t addr;
-	unsigned long flags;
-
-	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_BHIST);
-	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq ihist ping buf from free buf queue",
-			__func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe32_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_SKIN_BHIST_WR_PING_ADDR);
-	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_BHIST);
-	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq ihist pong buf from free buf queue",
-			__func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe32_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_SKIN_BHIST_WR_PONG_ADDR);
-
-	return 0;
-}
-
-static int vfe_stats_ihist_buf_init(
-	struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	uint32_t addr;
-	unsigned long flags;
-
-	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_IHIST);
-	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq ihist ping buf from free buf queue",
-			__func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe32_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_HIST_WR_PING_ADDR);
-	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_IHIST);
-	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq ihist pong buf from free buf queue",
-			__func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe32_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_HIST_WR_PONG_ADDR);
-
-	return 0;
-}
-
-static int vfe_stats_rs_buf_init(
-	struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	uint32_t addr;
-	unsigned long flags;
-
-	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_RS);
-	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq rs ping buf from free buf queue", __func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe32_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_RS_WR_PING_ADDR);
-	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_RS);
-	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq rs pong buf from free buf queue", __func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe32_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_RS_WR_PONG_ADDR);
-	return 0;
-}
-
-static int vfe_stats_cs_buf_init(
-	struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	uint32_t addr;
-	unsigned long flags;
-	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_CS);
-	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq cs ping buf from free buf queue", __func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe32_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_CS_WR_PING_ADDR);
-	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_CS);
-	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq cs pong buf from free buf queue", __func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe32_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_CS_WR_PONG_ADDR);
-	return 0;
-}
-
-static void vfe32_start_common(struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	CDBG("VFE opertaion mode = 0x%x, output mode = 0x%x\n",
-		vfe32_ctrl->share_ctrl->operation_mode,
-		vfe32_ctrl->share_ctrl->outpath.output_mode);
-	msm_camera_io_w_mb(1, vfe32_ctrl->share_ctrl->vfebase +
-		VFE_CAMIF_COMMAND);
-	msm_camera_io_w_mb(VFE_AXI_CFG_MASK,
-		vfe32_ctrl->share_ctrl->vfebase + VFE_AXI_CFG);
-}
-
-static int vfe32_start_recording(
-	struct msm_cam_media_controller *pmctl,
-	struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	vfe32_ctrl->share_ctrl->recording_state = VFE_STATE_START_REQUESTED;
-	msm_camera_io_w_mb(1,
-		vfe32_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-	return 0;
-}
-
-static int vfe32_stop_recording(
-	struct msm_cam_media_controller *pmctl,
-	struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	vfe32_ctrl->share_ctrl->recording_state = VFE_STATE_STOP_REQUESTED;
-	msm_camera_io_w_mb(1,
-		vfe32_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-	return 0;
-}
-
-static void vfe32_start_liveshot(
-	struct msm_cam_media_controller *pmctl,
-	struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	/* Hardcode 1 live snapshot for now. */
-	vfe32_ctrl->share_ctrl->outpath.out0.capture_cnt = 1;
-	vfe32_ctrl->share_ctrl->vfe_capture_count =
-		vfe32_ctrl->share_ctrl->outpath.out0.capture_cnt;
-
-	vfe32_ctrl->share_ctrl->liveshot_state = VFE_STATE_START_REQUESTED;
-	msm_camera_io_w_mb(1, vfe32_ctrl->
-		share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-}
-
-static void vfe32_stop_liveshot(
-	struct msm_cam_media_controller *pmctl,
-	struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	vfe32_ctrl->share_ctrl->liveshot_state = VFE_STATE_STOP_REQUESTED;
-	msm_camera_io_w_mb(1,
-		vfe32_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-}
-
-static int vfe32_zsl(
-	struct msm_cam_media_controller *pmctl,
-	struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	vfe32_ctrl->share_ctrl->start_ack_pending = TRUE;
-	vfe32_start_common(vfe32_ctrl);
-
-	msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase + 0x18C);
-	msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase + 0x188);
-	return 0;
-}
-static int vfe32_capture_raw(
-	struct msm_cam_media_controller *pmctl,
-	struct vfe32_ctrl_type *vfe32_ctrl,
-	uint32_t num_frames_capture)
-{
-	vfe32_ctrl->share_ctrl->outpath.out0.capture_cnt = num_frames_capture;
-	vfe32_ctrl->share_ctrl->vfe_capture_count = num_frames_capture;
-	vfe32_start_common(vfe32_ctrl);
-	return 0;
-}
-
-static int vfe32_capture(
-	struct msm_cam_media_controller *pmctl,
-	uint32_t num_frames_capture,
-	struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	/* capture command is valid for both idle and active state. */
-	vfe32_ctrl->share_ctrl->outpath.out1.capture_cnt = num_frames_capture;
-	if (vfe32_ctrl->share_ctrl->current_mode ==
-			VFE_OUTPUTS_MAIN_AND_THUMB ||
-		vfe32_ctrl->share_ctrl->current_mode ==
-			VFE_OUTPUTS_THUMB_AND_MAIN ||
-		vfe32_ctrl->share_ctrl->current_mode ==
-			VFE_OUTPUTS_JPEG_AND_THUMB ||
-		vfe32_ctrl->share_ctrl->current_mode ==
-			VFE_OUTPUTS_THUMB_AND_JPEG) {
-		vfe32_ctrl->share_ctrl->outpath.out0.capture_cnt =
-			num_frames_capture;
-	}
-
-	vfe32_ctrl->share_ctrl->vfe_capture_count = num_frames_capture;
-
-	vfe32_ctrl->share_ctrl->vfe_capture_count = num_frames_capture;
-
-	vfe32_start_common(vfe32_ctrl);
-	/* for debug */
-	msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase + 0x18C);
-	msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase + 0x188);
-	return 0;
-}
-
-static int vfe32_start(
-	struct msm_cam_media_controller *pmctl,
-	struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	vfe32_start_common(vfe32_ctrl);
-	return 0;
-}
-
-static void vfe32_update(struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	unsigned long flags;
-	uint32_t value = 0;
-	if (vfe32_ctrl->update_linear) {
-		if (!msm_camera_io_r(
-			vfe32_ctrl->share_ctrl->vfebase +
-			V32_LINEARIZATION_OFF1))
-			msm_camera_io_w(1,
-				vfe32_ctrl->share_ctrl->vfebase +
-				V32_LINEARIZATION_OFF1);
-		else
-			msm_camera_io_w(0,
-				vfe32_ctrl->share_ctrl->vfebase +
-				V32_LINEARIZATION_OFF1);
-		vfe32_ctrl->update_linear = false;
-	}
-
-	if (vfe32_ctrl->update_rolloff) {
-		value = msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
-			V33_PCA_ROLL_OFF_CFG_OFF1);
-		value ^= V33_PCA_ROLL_OFF_LUT_BANK_SEL_MASK;
-		msm_camera_io_w(value, vfe32_ctrl->share_ctrl->vfebase +
-			V33_PCA_ROLL_OFF_CFG_OFF1);
-		vfe32_ctrl->update_rolloff = false;
-	}
-
-	if (vfe32_ctrl->update_la) {
-		if (!msm_camera_io_r(
-			vfe32_ctrl->share_ctrl->vfebase + V32_LA_OFF))
-			msm_camera_io_w(1,
-				vfe32_ctrl->share_ctrl->vfebase + V32_LA_OFF);
-		else
-			msm_camera_io_w(0,
-				vfe32_ctrl->share_ctrl->vfebase + V32_LA_OFF);
-		vfe32_ctrl->update_la = false;
-	}
-
-	if (vfe32_ctrl->update_gamma) {
-		value = msm_camera_io_r(
-			vfe32_ctrl->share_ctrl->vfebase + V32_RGB_G_OFF);
-		value ^= V32_GAMMA_LUT_BANK_SEL_MASK;
-		msm_camera_io_w(value,
-			vfe32_ctrl->share_ctrl->vfebase + V32_RGB_G_OFF);
-		vfe32_ctrl->update_gamma = false;
-	}
-
-	spin_lock_irqsave(&vfe32_ctrl->share_ctrl->update_ack_lock, flags);
-	vfe32_ctrl->share_ctrl->update_ack_pending = TRUE;
-	spin_unlock_irqrestore(&vfe32_ctrl->share_ctrl->update_ack_lock, flags);
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	msm_camera_io_w_mb(1,
-		vfe32_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-	return;
-}
-
-static void vfe32_sync_timer_stop(struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	uint32_t value = 0;
-	vfe32_ctrl->sync_timer_state = 0;
-	if (vfe32_ctrl->sync_timer_number == 0)
-		value = 0x10000;
-	else if (vfe32_ctrl->sync_timer_number == 1)
-		value = 0x20000;
-	else if (vfe32_ctrl->sync_timer_number == 2)
-		value = 0x40000;
-
-	/* Timer Stop */
-	msm_camera_io_w(value,
-		vfe32_ctrl->share_ctrl->vfebase + V32_SYNC_TIMER_OFF);
-}
-
-static void vfe32_sync_timer_start(
-	const uint32_t *tbl,
-	struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	/* set bit 8 for auto increment. */
-	uint32_t value = 1;
-	uint32_t val;
-
-	vfe32_ctrl->sync_timer_state = *tbl++;
-	vfe32_ctrl->sync_timer_repeat_count = *tbl++;
-	vfe32_ctrl->sync_timer_number = *tbl++;
-	CDBG("%s timer_state %d, repeat_cnt %d timer number %d\n",
-		 __func__, vfe32_ctrl->sync_timer_state,
-		 vfe32_ctrl->sync_timer_repeat_count,
-		 vfe32_ctrl->sync_timer_number);
-
-	if (vfe32_ctrl->sync_timer_state) { /* Start Timer */
-		value = value << vfe32_ctrl->sync_timer_number;
-	} else { /* Stop Timer */
-		CDBG("Failed to Start timer\n");
-		return;
-	}
-
-	/* Timer Start */
-	msm_camera_io_w(value,
-		vfe32_ctrl->share_ctrl->vfebase + V32_SYNC_TIMER_OFF);
-	/* Sync Timer Line Start */
-	value = *tbl++;
-	msm_camera_io_w(value,
-		vfe32_ctrl->share_ctrl->vfebase + V32_SYNC_TIMER_OFF +
-		4 + ((vfe32_ctrl->sync_timer_number) * 12));
-	/* Sync Timer Pixel Start */
-	value = *tbl++;
-	msm_camera_io_w(value,
-			vfe32_ctrl->share_ctrl->vfebase + V32_SYNC_TIMER_OFF +
-			 8 + ((vfe32_ctrl->sync_timer_number) * 12));
-	/* Sync Timer Pixel Duration */
-	value = *tbl++;
-	val = vfe_clk_rate / 10000;
-	val = 10000000 / val;
-	val = value * 10000 / val;
-	CDBG("%s: Pixel Clk Cycles!!! %d\n", __func__, val);
-	msm_camera_io_w(val,
-		vfe32_ctrl->share_ctrl->vfebase + V32_SYNC_TIMER_OFF +
-		12 + ((vfe32_ctrl->sync_timer_number) * 12));
-	/* Timer0 Active High/LOW */
-	value = *tbl++;
-	msm_camera_io_w(value,
-		vfe32_ctrl->share_ctrl->vfebase + V32_SYNC_TIMER_POLARITY_OFF);
-	/* Selects sync timer 0 output to drive onto timer1 port */
-	value = 0;
-	msm_camera_io_w(value,
-		vfe32_ctrl->share_ctrl->vfebase + V32_TIMER_SELECT_OFF);
-}
-
-
-static void vfe32_write_gamma_cfg(
-	enum VFE32_DMI_RAM_SEL channel_sel,
-	const uint32_t *tbl,
-	struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	int i;
-	uint32_t value, value1, value2;
-	vfe32_program_dmi_cfg(channel_sel, vfe32_ctrl);
-	for (i = 0 ; i < (VFE32_GAMMA_NUM_ENTRIES/2) ; i++) {
-		value = *tbl++;
-		value1 = value & 0x0000FFFF;
-		value2 = (value & 0xFFFF0000)>>16;
-		msm_camera_io_w((value1),
-			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
-		msm_camera_io_w((value2),
-			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
-	}
-	vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
-}
-
-static void vfe32_read_gamma_cfg(
-	enum VFE32_DMI_RAM_SEL channel_sel,
-	uint32_t *tbl,
-	struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	int i;
-	vfe32_program_dmi_cfg(channel_sel, vfe32_ctrl);
-	CDBG("%s: Gamma table channel: %d\n", __func__, channel_sel);
-	for (i = 0 ; i < VFE32_GAMMA_NUM_ENTRIES ; i++) {
-		*tbl = msm_camera_io_r(
-			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
-		CDBG("%s: %08x\n", __func__, *tbl);
-		tbl++;
-	}
-	vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
-}
-
-static void vfe32_write_la_cfg(
-	enum VFE32_DMI_RAM_SEL channel_sel,
-	const uint32_t *tbl,
-	struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	uint32_t i;
-	uint32_t value, value1, value2;
-
-	vfe32_program_dmi_cfg(channel_sel, vfe32_ctrl);
-	for (i = 0 ; i < (VFE32_LA_TABLE_LENGTH/2) ; i++) {
-		value = *tbl++;
-		value1 = value & 0x0000FFFF;
-		value2 = (value & 0xFFFF0000)>>16;
-		msm_camera_io_w((value1),
-			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
-		msm_camera_io_w((value2),
-			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
-	}
-	vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
-}
-
-static struct vfe32_output_ch *vfe32_get_ch(
-	int path, struct vfe_share_ctrl_t *share_ctrl)
-{
-	struct vfe32_output_ch *ch = NULL;
-
-	if (path == VFE_MSG_OUTPUT_PRIMARY)
-		ch = &share_ctrl->outpath.out0;
-	else if (path == VFE_MSG_OUTPUT_SECONDARY)
-		ch = &share_ctrl->outpath.out1;
-	else if (path == VFE_MSG_OUTPUT_TERTIARY1)
-		ch = &share_ctrl->outpath.out2;
-	else if (path == VFE_MSG_OUTPUT_TERTIARY2)
-		ch = &share_ctrl->outpath.out3;
-	else
-		pr_err("%s: Invalid path %d\n", __func__,
-			path);
-
-	BUG_ON(ch == NULL);
-	return ch;
-}
-static struct msm_free_buf *vfe32_check_free_buffer(
-	int id, int path, struct axi_ctrl_t *axi_ctrl)
-{
-	struct vfe32_output_ch *outch = NULL;
-	struct msm_free_buf *b = NULL;
-	uint32_t inst_handle = 0;
-
-	if (path == VFE_MSG_OUTPUT_PRIMARY)
-		inst_handle = axi_ctrl->share_ctrl->outpath.out0.inst_handle;
-	else if (path == VFE_MSG_OUTPUT_SECONDARY)
-		inst_handle = axi_ctrl->share_ctrl->outpath.out1.inst_handle;
-	else if (path == VFE_MSG_OUTPUT_TERTIARY1)
-		inst_handle = axi_ctrl->share_ctrl->outpath.out2.inst_handle;
-	else if (path == VFE_MSG_OUTPUT_TERTIARY2)
-		inst_handle = axi_ctrl->share_ctrl->outpath.out3.inst_handle;
-
-	vfe32_subdev_notify(id, path, inst_handle,
-		&axi_ctrl->subdev, axi_ctrl->share_ctrl);
-	outch = vfe32_get_ch(path, axi_ctrl->share_ctrl);
-	if (outch->free_buf.ch_paddr[0])
-		b = &outch->free_buf;
-	return b;
-}
-static int configure_pingpong_buffers(
-	int id, int path, struct axi_ctrl_t *axi_ctrl)
-{
-	struct vfe32_output_ch *outch = NULL;
-	int rc = 0;
-	uint32_t inst_handle = 0;
-	if (path == VFE_MSG_OUTPUT_PRIMARY)
-		inst_handle = axi_ctrl->share_ctrl->outpath.out0.inst_handle;
-	else if (path == VFE_MSG_OUTPUT_SECONDARY)
-		inst_handle = axi_ctrl->share_ctrl->outpath.out1.inst_handle;
-	else if (path == VFE_MSG_OUTPUT_TERTIARY1)
-		inst_handle = axi_ctrl->share_ctrl->outpath.out2.inst_handle;
-	else if (path == VFE_MSG_OUTPUT_TERTIARY2)
-		inst_handle = axi_ctrl->share_ctrl->outpath.out3.inst_handle;
-
-	vfe32_subdev_notify(id, path, inst_handle,
-		&axi_ctrl->subdev, axi_ctrl->share_ctrl);
-	outch = vfe32_get_ch(path, axi_ctrl->share_ctrl);
-	if (outch->ping.ch_paddr[0] && outch->pong.ch_paddr[0]) {
-		/* Configure Preview Ping Pong */
-		pr_info("%s Configure ping/pong address for %d",
-						__func__, path);
-		vfe32_put_ch_ping_addr(
-			axi_ctrl->share_ctrl->vfebase, outch->ch0,
-			outch->ping.ch_paddr[0]);
-		vfe32_put_ch_pong_addr(
-			axi_ctrl->share_ctrl->vfebase, outch->ch0,
-			outch->pong.ch_paddr[0]);
-
-		if ((axi_ctrl->share_ctrl->current_mode !=
-			VFE_OUTPUTS_RAW) && (path != VFE_MSG_OUTPUT_TERTIARY1)
-			&& (path != VFE_MSG_OUTPUT_TERTIARY2)) {
-			vfe32_put_ch_ping_addr(
-				axi_ctrl->share_ctrl->vfebase, outch->ch1,
-				outch->ping.ch_paddr[1]);
-			vfe32_put_ch_pong_addr(
-				axi_ctrl->share_ctrl->vfebase, outch->ch1,
-				outch->pong.ch_paddr[1]);
-		}
-
-		if (outch->ping.num_planes > 2)
-			vfe32_put_ch_ping_addr(
-				axi_ctrl->share_ctrl->vfebase, outch->ch2,
-				outch->ping.ch_paddr[2]);
-		if (outch->pong.num_planes > 2)
-			vfe32_put_ch_pong_addr(
-				axi_ctrl->share_ctrl->vfebase, outch->ch2,
-				outch->pong.ch_paddr[2]);
-
-		/* avoid stale info */
-		memset(&outch->ping, 0, sizeof(struct msm_free_buf));
-		memset(&outch->pong, 0, sizeof(struct msm_free_buf));
-	} else {
-		pr_err("%s ping/pong addr is null!!", __func__);
-		rc = -EINVAL;
-	}
-	return rc;
-}
-
-static void vfe32_write_linear_cfg(
-	enum VFE32_DMI_RAM_SEL channel_sel,
-	const uint32_t *tbl, struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	uint32_t i;
-
-	vfe32_program_dmi_cfg(channel_sel, vfe32_ctrl);
-	/* for loop for configuring LUT. */
-	for (i = 0 ; i < VFE32_LINEARIZATON_TABLE_LENGTH ; i++) {
-		msm_camera_io_w(*tbl,
-			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
-		tbl++;
-	}
-	CDBG("done writing to linearization table\n");
-	vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
-}
-
-static void vfe32_send_isp_msg(
-	struct v4l2_subdev *sd,
-	uint32_t vfeFrameId,
-	uint32_t isp_msg_id)
-{
-	struct isp_msg_event isp_msg_evt;
-
-	isp_msg_evt.msg_id = isp_msg_id;
-	isp_msg_evt.sof_count = vfeFrameId;
-	v4l2_subdev_notify(sd,
-			NOTIFY_ISP_MSG_EVT,
-			(void *)&isp_msg_evt);
-}
-
-static int vfe32_proc_general(
-	struct msm_cam_media_controller *pmctl,
-	struct msm_isp_cmd *cmd,
-	struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	int i , rc = 0;
-	uint32_t old_val = 0 , new_val = 0, module_val = 0;
-	uint32_t *cmdp = NULL;
-	uint32_t *cmdp_local = NULL;
-	uint32_t snapshot_cnt = 0;
-	uint32_t temp1 = 0, temp2 = 0;
-	struct msm_camera_vfe_params_t vfe_params;
-
-	CDBG("vfe32_proc_general: cmdID = %s, length = %d\n",
-		vfe32_general_cmd[cmd->id], cmd->length);
-	switch (cmd->id) {
-	case VFE_CMD_RESET:
-		pr_info("vfe32_proc_general: cmdID = %s\n",
-			vfe32_general_cmd[cmd->id]);
-		vfe32_ctrl->share_ctrl->vfe_reset_flag = true;
-		vfe32_reset(vfe32_ctrl);
-		break;
-	case VFE_CMD_START:
-		pr_info("vfe32_proc_general: cmdID = %s\n",
-			vfe32_general_cmd[cmd->id]);
-		if (copy_from_user(&vfe_params,
-				(void __user *)(cmd->value),
-				sizeof(struct msm_camera_vfe_params_t))) {
-				rc = -EFAULT;
-				goto proc_general_done;
-		}
-
-		vfe32_ctrl->share_ctrl->current_mode =
-			vfe_params.operation_mode;
-
-		rc = vfe32_start(pmctl, vfe32_ctrl);
-		break;
-	case VFE_CMD_UPDATE:
-		vfe32_update(vfe32_ctrl);
-		break;
-	case VFE_CMD_CAPTURE_RAW:
-		pr_info("%s: cmdID = VFE_CMD_CAPTURE_RAW\n", __func__);
-		if (copy_from_user(&vfe_params,
-				(void __user *)(cmd->value),
-				sizeof(struct msm_camera_vfe_params_t))) {
-				rc = -EFAULT;
-				goto proc_general_done;
-		}
-
-		snapshot_cnt = vfe_params.capture_count;
-		vfe32_ctrl->share_ctrl->current_mode =
-			vfe_params.operation_mode;
-		rc = vfe32_capture_raw(pmctl, vfe32_ctrl, snapshot_cnt);
-		break;
-	case VFE_CMD_CAPTURE:
-		if (copy_from_user(&vfe_params,
-				(void __user *)(cmd->value),
-				sizeof(struct msm_camera_vfe_params_t))) {
-				rc = -EFAULT;
-				goto proc_general_done;
-		}
-
-		snapshot_cnt = vfe_params.capture_count;
-		vfe32_ctrl->share_ctrl->current_mode =
-			vfe_params.operation_mode;
-
-		rc = vfe32_capture(pmctl, snapshot_cnt, vfe32_ctrl);
-		break;
-	case VFE_CMD_START_RECORDING:
-		pr_info("vfe32_proc_general: cmdID = %s\n",
-			vfe32_general_cmd[cmd->id]);
-		rc = vfe32_start_recording(pmctl, vfe32_ctrl);
-		break;
-	case VFE_CMD_STOP_RECORDING:
-		pr_info("vfe32_proc_general: cmdID = %s\n",
-			vfe32_general_cmd[cmd->id]);
-		rc = vfe32_stop_recording(pmctl, vfe32_ctrl);
-		break;
-	case VFE_CMD_OPERATION_CFG: {
-		if (cmd->length != V32_OPERATION_CFG_LEN) {
-			rc = -EINVAL;
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(V32_OPERATION_CFG_LEN, GFP_ATOMIC);
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			V32_OPERATION_CFG_LEN)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		rc = vfe32_operation_config(cmdp, vfe32_ctrl);
-		}
-		break;
-
-	case VFE_CMD_STATS_AE_START: {
-		if (vfe32_use_bayer_stats(vfe32_ctrl)) {
-			/* Error */
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		rc = vfe_stats_aec_bg_buf_init(vfe32_ctrl);
-		if (rc < 0) {
-			pr_err("%s: cannot config ping/pong address of AEC",
-				 __func__);
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		old_val = msm_camera_io_r(
-			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val |= AE_BG_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase +
-			vfe32_cmd[cmd->id].offset,
-			cmdp, (vfe32_cmd[cmd->id].length));
-		}
-		break;
-	case VFE_CMD_STATS_AF_START: {
-		if (vfe32_use_bayer_stats(vfe32_ctrl)) {
-			/* Error */
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		rc = vfe_stats_af_bf_buf_init(vfe32_ctrl);
-		if (rc < 0) {
-			pr_err("%s: cannot config ping/pong address of AF",
-				__func__);
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		old_val = msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
-			VFE_MODULE_CFG);
-		old_val |= AF_BF_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase +
-			vfe32_cmd[cmd->id].offset,
-			cmdp, (vfe32_cmd[cmd->id].length));
-		}
-		break;
-	case VFE_CMD_STATS_AWB_START: {
-		if (vfe32_use_bayer_stats(vfe32_ctrl)) {
-			/* Error */
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		rc = vfe_stats_awb_buf_init(vfe32_ctrl, NULL);
-		if (rc < 0) {
-			pr_err("%s: cannot config ping/pong address of AWB",
-				 __func__);
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		old_val = msm_camera_io_r(
-			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val |= AWB_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase +
-			vfe32_cmd[cmd->id].offset,
-			cmdp, (vfe32_cmd[cmd->id].length));
-		}
-		break;
-
-	case VFE_CMD_STATS_IHIST_START: {
-		rc = vfe_stats_ihist_buf_init(vfe32_ctrl);
-		if (rc < 0) {
-			pr_err("%s: cannot config ping/pong address of IHIST",
-				 __func__);
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		old_val = msm_camera_io_r(
-			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val |= IHIST_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase +
-			vfe32_cmd[cmd->id].offset,
-			cmdp, (vfe32_cmd[cmd->id].length));
-		}
-		break;
-
-
-	case VFE_CMD_STATS_RS_START: {
-		rc = vfe_stats_rs_buf_init(vfe32_ctrl);
-		if (rc < 0) {
-			pr_err("%s: cannot config ping/pong address of RS",
-				__func__);
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase +
-			vfe32_cmd[cmd->id].offset,
-			cmdp, (vfe32_cmd[cmd->id].length));
-		}
-		break;
-
-	case VFE_CMD_STATS_CS_START: {
-		rc = vfe_stats_cs_buf_init(vfe32_ctrl);
-		if (rc < 0) {
-			pr_err("%s: cannot config ping/pong address of CS",
-				__func__);
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase +
-			vfe32_cmd[cmd->id].offset,
-			cmdp, (vfe32_cmd[cmd->id].length));
-		}
-		break;
-
-	case VFE_CMD_STATS_BG_START:
-	case VFE_CMD_STATS_BF_START:
-	case VFE_CMD_STATS_BHIST_START: {
-		if (!vfe32_use_bayer_stats(vfe32_ctrl)) {
-			/* Error */
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		old_val = msm_camera_io_r(
-			vfe32_ctrl->share_ctrl->vfebase + VFE_STATS_CFG);
-		module_val = msm_camera_io_r(
-			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		if (VFE_CMD_STATS_BG_START == cmd->id) {
-			module_val |= AE_BG_ENABLE_MASK;
-			old_val |= STATS_BG_ENABLE_MASK;
-			rc = vfe_stats_aec_bg_buf_init(vfe32_ctrl);
-			if (rc < 0) {
-				pr_err("%s: cannot config ping/pong address of CS",
-					__func__);
-				goto proc_general_done;
-			}
-		} else if (VFE_CMD_STATS_BF_START == cmd->id) {
-			module_val |= AF_BF_ENABLE_MASK;
-			old_val |= STATS_BF_ENABLE_MASK;
-			rc = vfe_stats_af_bf_buf_init(vfe32_ctrl);
-			if (rc < 0) {
-				pr_err("%s: cannot config ping/pong address of CS",
-					__func__);
-				goto proc_general_done;
-			}
-		} else {
-			module_val |= SKIN_BHIST_ENABLE_MASK;
-			old_val |= STATS_BHIST_ENABLE_MASK;
-			rc = vfe_stats_bhist_buf_init(vfe32_ctrl);
-			if (rc < 0) {
-				pr_err("%s: cannot config ping/pong address of CS",
-					__func__);
-				goto proc_general_done;
-			}
-		}
-		msm_camera_io_w(old_val, vfe32_ctrl->share_ctrl->vfebase +
-			VFE_STATS_CFG);
-		msm_camera_io_w(module_val,
-			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-				(void __user *)(cmd->value),
-				cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase +
-			vfe32_cmd[cmd->id].offset,
-			cmdp, (vfe32_cmd[cmd->id].length));
-		}
-		break;
-	case VFE_CMD_MCE_UPDATE:
-	case VFE_CMD_MCE_CFG:{
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		/* Incrementing with 4 so as to point to the 2nd Register as
-		the 2nd register has the mce_enable bit */
-		old_val = msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
-			V32_CHROMA_SUP_OFF + 4);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		new_val = *cmdp_local;
-		old_val &= MCE_EN_MASK;
-		new_val = new_val | old_val;
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase +
-			V32_CHROMA_SUP_OFF + 4, &new_val, 4);
-		cmdp_local += 1;
-
-		old_val = msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
-			V32_CHROMA_SUP_OFF + 8);
-		new_val = *cmdp_local;
-		old_val &= MCE_Q_K_MASK;
-		new_val = new_val | old_val;
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase +
-			V32_CHROMA_SUP_OFF + 8, &new_val, 4);
-		cmdp_local += 1;
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase +
-			vfe32_cmd[cmd->id].offset,
-			cmdp_local, (vfe32_cmd[cmd->id].length));
-		}
-		break;
-	case VFE_CMD_CHROMA_SUP_UPDATE:
-	case VFE_CMD_CHROMA_SUP_CFG:{
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		msm_camera_io_memcpy(vfe32_ctrl->share_ctrl->vfebase +
-			V32_CHROMA_SUP_OFF, cmdp_local, 4);
-
-		cmdp_local += 1;
-		new_val = *cmdp_local;
-		/* Incrementing with 4 so as to point to the 2nd Register as
-		 * the 2nd register has the mce_enable bit
-		 */
-		old_val = msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
-			V32_CHROMA_SUP_OFF + 4);
-		old_val &= ~MCE_EN_MASK;
-		new_val = new_val | old_val;
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase +
-			V32_CHROMA_SUP_OFF + 4, &new_val, 4);
-		cmdp_local += 1;
-
-		old_val = msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
-			V32_CHROMA_SUP_OFF + 8);
-		new_val = *cmdp_local;
-		old_val &= ~MCE_Q_K_MASK;
-		new_val = new_val | old_val;
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase +
-			V32_CHROMA_SUP_OFF + 8, &new_val, 4);
-		}
-		break;
-	case VFE_CMD_BLACK_LEVEL_CFG:
-		rc = -EFAULT;
-		goto proc_general_done;
-
-	case VFE_CMD_MESH_ROLL_OFF_CFG: {
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value) , cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase +
-			vfe32_cmd[cmd->id].offset,
-			cmdp_local, 16);
-		cmdp_local += 4;
-		vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK0, vfe32_ctrl);
-		/* for loop for extrcting init table. */
-		for (i = 0; i < (V32_MESH_ROLL_OFF_INIT_TABLE_SIZE * 2); i++) {
-			msm_camera_io_w(*cmdp_local ,
-			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
-			cmdp_local++;
-		}
-		CDBG("done writing init table\n");
-		/* by default, always starts with offset 0. */
-		msm_camera_io_w(V32_MESH_ROLL_OFF_DELTA_TABLE_OFFSET,
-		vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_ADDR);
-		/* for loop for extracting delta table. */
-		for (i = 0; i < (V32_MESH_ROLL_OFF_DELTA_TABLE_SIZE * 2); i++) {
-			msm_camera_io_w(*cmdp_local,
-			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
-			cmdp_local++;
-		}
-		vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
-		}
-		break;
-
-	case VFE_CMD_GET_MESH_ROLLOFF_TABLE:
-		temp1 = sizeof(uint32_t) * ((V32_MESH_ROLL_OFF_INIT_TABLE_SIZE *
-			2) + (V32_MESH_ROLL_OFF_DELTA_TABLE_SIZE * 2));
-		if (cmd->length != temp1) {
-			rc = -EINVAL;
-			goto proc_general_done;
-		}
-		cmdp = kzalloc(temp1, GFP_KERNEL);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK0, vfe32_ctrl);
-		CDBG("%s: Mesh Rolloff init Table\n", __func__);
-		for (i = 0; i < (V32_MESH_ROLL_OFF_INIT_TABLE_SIZE * 2); i++) {
-			*cmdp_local =
-				msm_camera_io_r(
-					vfe32_ctrl->share_ctrl->vfebase +
-					VFE_DMI_DATA_LO);
-			CDBG("%s: %08x\n", __func__, *cmdp_local);
-			cmdp_local++;
-		}
-		msm_camera_io_w(V32_MESH_ROLL_OFF_DELTA_TABLE_OFFSET,
-			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_ADDR);
-		CDBG("%s: Mesh Rolloff Delta Table\n", __func__);
-		for (i = 0; i < (V32_MESH_ROLL_OFF_DELTA_TABLE_SIZE * 2); i++) {
-			*cmdp_local =
-				msm_camera_io_r(
-					vfe32_ctrl->share_ctrl->vfebase +
-					VFE_DMI_DATA_LO);
-			CDBG("%s: %08x\n", __func__, *cmdp_local);
-			cmdp_local++;
-		}
-		CDBG("done reading delta table\n");
-		vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
-		if (copy_to_user((void __user *)(cmd->value), cmdp,
-			temp1)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		break;
-	case VFE_CMD_LA_CFG:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase +
-			vfe32_cmd[cmd->id].offset,
-			cmdp_local, (vfe32_cmd[cmd->id].length));
-
-		cmdp_local += 1;
-		vfe32_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK0,
-						   cmdp_local, vfe32_ctrl);
-		break;
-
-	case VFE_CMD_LA_UPDATE: {
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-
-		cmdp_local = cmdp + 1;
-		old_val = msm_camera_io_r(
-			vfe32_ctrl->share_ctrl->vfebase + V32_LA_OFF);
-		if (old_val != 0x0)
-			vfe32_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK0,
-				cmdp_local, vfe32_ctrl);
-		else
-			vfe32_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK1,
-				cmdp_local, vfe32_ctrl);
-		}
-		vfe32_ctrl->update_la = true;
-		break;
-
-	case VFE_CMD_GET_LA_TABLE:
-		temp1 = sizeof(uint32_t) * VFE32_LA_TABLE_LENGTH / 2;
-		if (cmd->length != temp1) {
-			rc = -EINVAL;
-			goto proc_general_done;
-		}
-		cmdp = kzalloc(temp1, GFP_KERNEL);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		if (msm_camera_io_r(vfe32_ctrl->
-				share_ctrl->vfebase + V32_LA_OFF))
-			vfe32_program_dmi_cfg(LUMA_ADAPT_LUT_RAM_BANK1,
-						vfe32_ctrl);
-		else
-			vfe32_program_dmi_cfg(LUMA_ADAPT_LUT_RAM_BANK0,
-						vfe32_ctrl);
-		for (i = 0 ; i < (VFE32_LA_TABLE_LENGTH / 2) ; i++) {
-			*cmdp_local =
-				msm_camera_io_r(
-					vfe32_ctrl->share_ctrl->vfebase +
-					VFE_DMI_DATA_LO);
-			*cmdp_local |= (msm_camera_io_r(
-				vfe32_ctrl->share_ctrl->vfebase +
-				VFE_DMI_DATA_LO)) << 16;
-			cmdp_local++;
-		}
-		vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
-		if (copy_to_user((void __user *)(cmd->value), cmdp,
-			temp1)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		break;
-	case VFE_CMD_SK_ENHAN_CFG:
-	case VFE_CMD_SK_ENHAN_UPDATE:{
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase + V32_SCE_OFF,
-			cmdp, V32_SCE_LEN);
-		}
-		break;
-
-	case VFE_CMD_LIVESHOT:
-		/* Configure primary channel */
-		vfe32_start_liveshot(pmctl, vfe32_ctrl);
-		break;
-
-	case VFE_CMD_LINEARIZATION_CFG:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp, (void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase +
-			V32_LINEARIZATION_OFF1,
-			cmdp_local, V32_LINEARIZATION_LEN1);
-		cmdp_local += 4;
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase +
-			V32_LINEARIZATION_OFF2,
-			cmdp_local, V32_LINEARIZATION_LEN2);
-
-		cmdp_local = cmdp + 17;
-		vfe32_write_linear_cfg(BLACK_LUT_RAM_BANK0,
-					cmdp_local, vfe32_ctrl);
-		break;
-
-	case VFE_CMD_LINEARIZATION_UPDATE:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp, (void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		cmdp_local++;
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase +
-			V32_LINEARIZATION_OFF1 + 4,
-			cmdp_local, (V32_LINEARIZATION_LEN1 - 4));
-		cmdp_local += 3;
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase +
-			V32_LINEARIZATION_OFF2,
-			cmdp_local, V32_LINEARIZATION_LEN2);
-		cmdp_local = cmdp + 17;
-		/*extracting the bank select*/
-		old_val = msm_camera_io_r(
-				vfe32_ctrl->share_ctrl->vfebase +
-				V32_LINEARIZATION_OFF1);
-
-		if (old_val != 0x0)
-			vfe32_write_linear_cfg(BLACK_LUT_RAM_BANK0,
-						cmdp_local, vfe32_ctrl);
-		else
-			vfe32_write_linear_cfg(BLACK_LUT_RAM_BANK1,
-						cmdp_local, vfe32_ctrl);
-		vfe32_ctrl->update_linear = true;
-		break;
-
-	case VFE_CMD_GET_LINEARIZATON_TABLE:
-		temp1 = sizeof(uint32_t) * VFE32_LINEARIZATON_TABLE_LENGTH;
-		if (cmd->length != temp1) {
-			rc = -EINVAL;
-			goto proc_general_done;
-		}
-		cmdp = kzalloc(temp1, GFP_KERNEL);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		if (msm_camera_io_r(
-			vfe32_ctrl->share_ctrl->vfebase +
-			V32_LINEARIZATION_OFF1))
-			vfe32_program_dmi_cfg(BLACK_LUT_RAM_BANK1, vfe32_ctrl);
-		else
-			vfe32_program_dmi_cfg(BLACK_LUT_RAM_BANK0, vfe32_ctrl);
-		CDBG("%s: Linearization Table\n", __func__);
-		for (i = 0 ; i < VFE32_LINEARIZATON_TABLE_LENGTH ; i++) {
-			*cmdp_local = msm_camera_io_r(
-				vfe32_ctrl->share_ctrl->vfebase +
-				VFE_DMI_DATA_LO);
-			CDBG("%s: %08x\n", __func__, *cmdp_local);
-			cmdp_local++;
-		}
-		vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
-		if (copy_to_user((void __user *)(cmd->value), cmdp,
-			temp1)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		break;
-	case VFE_CMD_DEMOSAICV3:
-		if (cmd->length !=
-			V32_DEMOSAICV3_0_LEN+V32_DEMOSAICV3_1_LEN) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		new_val = *cmdp_local;
-
-		old_val = msm_camera_io_r(
-			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF);
-		old_val &= DEMOSAIC_MASK;
-		new_val = new_val | old_val;
-		*cmdp_local = new_val;
-
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF,
-			cmdp_local, V32_DEMOSAICV3_0_LEN);
-		cmdp_local += 1;
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_1_OFF,
-			cmdp_local, V32_DEMOSAICV3_1_LEN);
-		break;
-
-	case VFE_CMD_DEMOSAICV3_UPDATE:
-		if (cmd->length !=
-			V32_DEMOSAICV3_0_LEN * V32_DEMOSAICV3_UP_REG_CNT) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		new_val = *cmdp_local;
-
-		old_val = msm_camera_io_r(
-			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF);
-		old_val &= DEMOSAIC_MASK;
-		new_val = new_val | old_val;
-		*cmdp_local = new_val;
-
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF,
-			cmdp_local, V32_DEMOSAICV3_0_LEN);
-		/* As the address space is not contiguous increment by 2
-		 * before copying to next address space */
-		cmdp_local += 1;
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_1_OFF,
-			cmdp_local, 2 * V32_DEMOSAICV3_0_LEN);
-		/* As the address space is not contiguous increment by 2
-		 * before copying to next address space */
-		cmdp_local += 2;
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_2_OFF,
-			cmdp_local, 2 * V32_DEMOSAICV3_0_LEN);
-		break;
-
-	case VFE_CMD_DEMOSAICV3_ABCC_CFG:
-		rc = -EFAULT;
-		break;
-
-	case VFE_CMD_DEMOSAICV3_ABF_UPDATE:/* 116 ABF update  */
-	case VFE_CMD_DEMOSAICV3_ABF_CFG: { /* 108 ABF config  */
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		new_val = *cmdp_local;
-
-		old_val = msm_camera_io_r(
-			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF);
-		old_val &= ABF_MASK;
-		new_val = new_val | old_val;
-		*cmdp_local = new_val;
-
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF,
-			cmdp_local, 4);
-
-		cmdp_local += 1;
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase +
-			vfe32_cmd[cmd->id].offset,
-			cmdp_local, (vfe32_cmd[cmd->id].length));
-		}
-		break;
-
-	case VFE_CMD_DEMOSAICV3_DBCC_CFG:
-	case VFE_CMD_DEMOSAICV3_DBCC_UPDATE:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		new_val = *cmdp_local;
-
-		old_val = msm_camera_io_r(
-			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF);
-		old_val &= DBCC_MASK;
-
-		new_val = new_val | old_val;
-		*cmdp_local = new_val;
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF,
-			cmdp_local, 4);
-		cmdp_local += 1;
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase +
-			vfe32_cmd[cmd->id].offset,
-			cmdp_local, (vfe32_cmd[cmd->id].length));
-		break;
-
-	case VFE_CMD_DEMOSAICV3_DBPC_CFG:
-	case VFE_CMD_DEMOSAICV3_DBPC_UPDATE:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		new_val = *cmdp_local;
-
-		old_val = msm_camera_io_r(
-			vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF);
-		old_val &= DBPC_MASK;
-
-		new_val = new_val | old_val;
-		*cmdp_local = new_val;
-		msm_camera_io_memcpy(vfe32_ctrl->share_ctrl->vfebase +
-			V32_DEMOSAICV3_0_OFF,
-			cmdp_local, V32_DEMOSAICV3_LEN);
-		cmdp_local += 1;
-		msm_camera_io_memcpy(vfe32_ctrl->share_ctrl->vfebase +
-			V32_DEMOSAICV3_DBPC_CFG_OFF,
-			cmdp_local, V32_DEMOSAICV3_DBPC_LEN);
-		cmdp_local += 1;
-		msm_camera_io_memcpy(vfe32_ctrl->share_ctrl->vfebase +
-			V32_DEMOSAICV3_DBPC_CFG_OFF0,
-			cmdp_local, V32_DEMOSAICV3_DBPC_LEN);
-		cmdp_local += 1;
-		msm_camera_io_memcpy(vfe32_ctrl->share_ctrl->vfebase +
-			V32_DEMOSAICV3_DBPC_CFG_OFF1,
-			cmdp_local, V32_DEMOSAICV3_DBPC_LEN);
-		cmdp_local += 1;
-		msm_camera_io_memcpy(vfe32_ctrl->share_ctrl->vfebase +
-			V32_DEMOSAICV3_DBPC_CFG_OFF2,
-			cmdp_local, V32_DEMOSAICV3_DBPC_LEN);
-		break;
-
-	case VFE_CMD_RGB_G_CFG: {
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase + V32_RGB_G_OFF,
-			cmdp, 4);
-		cmdp += 1;
-
-		vfe32_write_gamma_cfg(RGBLUT_RAM_CH0_BANK0, cmdp, vfe32_ctrl);
-		vfe32_write_gamma_cfg(RGBLUT_RAM_CH1_BANK0, cmdp, vfe32_ctrl);
-		vfe32_write_gamma_cfg(RGBLUT_RAM_CH2_BANK0, cmdp, vfe32_ctrl);
-		}
-	    cmdp -= 1;
-		break;
-
-	case VFE_CMD_RGB_G_UPDATE: {
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp, (void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-
-		old_val = msm_camera_io_r(
-			vfe32_ctrl->share_ctrl->vfebase + V32_RGB_G_OFF);
-		cmdp += 1;
-		if (old_val != 0x0) {
-			vfe32_write_gamma_cfg(
-				RGBLUT_RAM_CH0_BANK0, cmdp, vfe32_ctrl);
-			vfe32_write_gamma_cfg(
-				RGBLUT_RAM_CH1_BANK0, cmdp, vfe32_ctrl);
-			vfe32_write_gamma_cfg(
-				RGBLUT_RAM_CH2_BANK0, cmdp, vfe32_ctrl);
-		} else {
-			vfe32_write_gamma_cfg(
-				RGBLUT_RAM_CH0_BANK1, cmdp, vfe32_ctrl);
-			vfe32_write_gamma_cfg(
-				RGBLUT_RAM_CH1_BANK1, cmdp, vfe32_ctrl);
-			vfe32_write_gamma_cfg(
-				RGBLUT_RAM_CH2_BANK1, cmdp, vfe32_ctrl);
-		}
-		}
-		vfe32_ctrl->update_gamma = TRUE;
-		cmdp -= 1;
-		break;
-
-	case VFE_CMD_GET_RGB_G_TABLE:
-		temp1 = sizeof(uint32_t) * VFE32_GAMMA_NUM_ENTRIES * 3;
-		if (cmd->length != temp1) {
-			rc = -EINVAL;
-			goto proc_general_done;
-		}
-		cmdp = kzalloc(temp1, GFP_KERNEL);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-
-		old_val = msm_camera_io_r(
-			vfe32_ctrl->share_ctrl->vfebase + V32_RGB_G_OFF);
-		temp2 = old_val ? RGBLUT_RAM_CH0_BANK1 :
-			RGBLUT_RAM_CH0_BANK0;
-		for (i = 0; i < 3; i++) {
-			vfe32_read_gamma_cfg(temp2,
-				cmdp_local + (VFE32_GAMMA_NUM_ENTRIES * i),
-				vfe32_ctrl);
-			temp2 += 2;
-		}
-		if (copy_to_user((void __user *)(cmd->value), cmdp,
-			temp1)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		break;
-
-	case VFE_CMD_STATS_AWB_STOP: {
-		if (vfe32_use_bayer_stats(vfe32_ctrl)) {
-			/* Error */
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		old_val = msm_camera_io_r(
-			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= ~AWB_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		}
-		break;
-	case VFE_CMD_STATS_AE_STOP: {
-		if (vfe32_use_bayer_stats(vfe32_ctrl)) {
-			/* Error */
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		old_val = msm_camera_io_r(
-			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= ~AE_BG_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		}
-		break;
-	case VFE_CMD_STATS_AF_STOP: {
-		if (vfe32_use_bayer_stats(vfe32_ctrl)) {
-			/* Error */
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		old_val = msm_camera_io_r(
-			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= ~AF_BF_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		}
-		break;
-
-	case VFE_CMD_STATS_IHIST_STOP: {
-		old_val = msm_camera_io_r(
-			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= ~IHIST_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		}
-		break;
-
-	case VFE_CMD_STATS_RS_STOP: {
-		old_val = msm_camera_io_r(
-			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= ~RS_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		}
-		break;
-
-	case VFE_CMD_STATS_CS_STOP: {
-		old_val = msm_camera_io_r(
-			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= ~CS_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		}
-		break;
-
-	case VFE_CMD_STATS_BG_STOP:
-	case VFE_CMD_STATS_BF_STOP:
-	case VFE_CMD_STATS_BHIST_STOP: {
-		if (!vfe32_use_bayer_stats(vfe32_ctrl)) {
-			/* Error */
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		old_val = msm_camera_io_r(
-			vfe32_ctrl->share_ctrl->vfebase + VFE_STATS_CFG);
-		if (VFE_CMD_STATS_BG_STOP == cmd->id)
-			old_val &= ~STATS_BG_ENABLE_MASK;
-		else if (VFE_CMD_STATS_BF_STOP == cmd->id)
-			old_val &= ~STATS_BF_ENABLE_MASK;
-		else
-			old_val &= ~STATS_BHIST_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe32_ctrl->share_ctrl->vfebase + VFE_STATS_CFG);
-		if (VFE_CMD_STATS_BF_STOP == cmd->id) {
-			rc = vfe32_stats_flush_enqueue(vfe32_ctrl,
-					MSM_STATS_TYPE_BF);
-			if (rc < 0) {
-				pr_err("%s: dq stats buf err = %d",
-					   __func__, rc);
-				return -EINVAL;
-			}
-		}
-		}
-		break;
-
-	case VFE_CMD_STOP:
-		pr_info("vfe32_proc_general: cmdID = %s\n",
-			vfe32_general_cmd[cmd->id]);
-		if (copy_from_user(&vfe_params,
-				(void __user *)(cmd->value),
-				sizeof(struct msm_camera_vfe_params_t))) {
-				rc = -EFAULT;
-				goto proc_general_done;
-		}
-
-		vfe32_stop(vfe32_ctrl);
-		break;
-
-	case VFE_CMD_SYNC_TIMER_SETTING:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp, (void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		vfe32_sync_timer_start(cmdp, vfe32_ctrl);
-		break;
-
-	case VFE_CMD_MODULE_CFG: {
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		*cmdp &= ~STATS_ENABLE_MASK;
-		old_val = msm_camera_io_r(
-			vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= STATS_ENABLE_MASK;
-		*cmdp |= old_val;
-
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase +
-			vfe32_cmd[cmd->id].offset,
-			cmdp, (vfe32_cmd[cmd->id].length));
-		}
-		break;
-
-	case VFE_CMD_ZSL:
-		if (copy_from_user(&vfe_params,
-				(void __user *)(cmd->value),
-				sizeof(struct msm_camera_vfe_params_t))) {
-				rc = -EFAULT;
-				goto proc_general_done;
-		}
-
-		vfe32_ctrl->share_ctrl->current_mode =
-			vfe_params.operation_mode;
-
-		rc = vfe32_zsl(pmctl, vfe32_ctrl);
-		break;
-
-	case VFE_CMD_ASF_CFG:
-	case VFE_CMD_ASF_UPDATE:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp, (void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase +
-			vfe32_cmd[cmd->id].offset,
-			cmdp, (vfe32_cmd[cmd->id].length));
-		cmdp_local = cmdp + V32_ASF_LEN/4;
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase +
-			V32_ASF_SPECIAL_EFX_CFG_OFF,
-			cmdp_local, V32_ASF_SPECIAL_EFX_CFG_LEN);
-		break;
-
-	case VFE_CMD_PCA_ROLL_OFF_CFG:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value) , cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-
-		cmdp_local = cmdp;
-
-		temp1 = *cmdp_local;
-		cmdp_local++;
-
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase +
-			V33_PCA_ROLL_OFF_CFG_OFF1,
-			cmdp_local, V33_PCA_ROLL_OFF_CFG_LEN1);
-		cmdp_local += 4;
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase +
-			V33_PCA_ROLL_OFF_CFG_OFF2,
-			cmdp_local, V33_PCA_ROLL_OFF_CFG_LEN2);
-
-		cmdp_local += 3;
-		CDBG("%s: start writing RollOff Ram0 table\n", __func__);
-		vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK0, vfe32_ctrl);
-		msm_camera_io_w(temp1,
-			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_ADDR);
-		for (i = 0 ; i < V33_PCA_ROLL_OFF_TABLE_SIZE ; i++) {
-			msm_camera_io_w(*(cmdp_local + 1),
-				vfe32_ctrl->share_ctrl->vfebase +
-				VFE33_DMI_DATA_HI);
-			msm_camera_io_w(*cmdp_local,
-				vfe32_ctrl->share_ctrl->vfebase +
-				VFE33_DMI_DATA_LO);
-			cmdp_local += 2;
-		}
-		CDBG("%s: end writing RollOff Ram0 table\n", __func__);
-
-		CDBG("%s: start writing RollOff Ram1 table\n", __func__);
-		vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK0, vfe32_ctrl);
-		msm_camera_io_w(temp1,
-			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_ADDR);
-		for (i = 0 ; i < V33_PCA_ROLL_OFF_TABLE_SIZE ; i++) {
-			msm_camera_io_w(*cmdp_local,
-				vfe32_ctrl->share_ctrl->vfebase +
-				VFE33_DMI_DATA_LO);
-			cmdp_local += 2;
-		}
-		CDBG("%s: end writing RollOff Ram1 table\n", __func__);
-
-		vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
-		break;
-
-	case VFE_CMD_PCA_ROLL_OFF_UPDATE:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value), cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-
-		cmdp_local = cmdp;
-
-		temp1 = *cmdp_local;
-		cmdp_local += 8;
-
-		temp2 = msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
-			V33_PCA_ROLL_OFF_CFG_OFF1)
-			& V33_PCA_ROLL_OFF_LUT_BANK_SEL_MASK;
-
-		CDBG("%s: start writing RollOff Ram0 table\n", __func__);
-		if (temp2)
-			vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK0, vfe32_ctrl);
-		else
-			vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK1, vfe32_ctrl);
-
-		msm_camera_io_w(temp1,
-			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_ADDR);
-		for (i = 0 ; i < V33_PCA_ROLL_OFF_TABLE_SIZE ; i++) {
-			msm_camera_io_w(*(cmdp_local + 1),
-				vfe32_ctrl->share_ctrl->vfebase +
-				VFE33_DMI_DATA_HI);
-			msm_camera_io_w(*cmdp_local,
-				vfe32_ctrl->share_ctrl->vfebase +
-				VFE33_DMI_DATA_LO);
-			cmdp_local += 2;
-		}
-		CDBG("%s: end writing RollOff Ram0 table\n", __func__);
-
-		CDBG("%s: start writing RollOff Ram1 table\n", __func__);
-		if (temp2)
-			vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK0, vfe32_ctrl);
-		else
-			vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK1, vfe32_ctrl);
-
-		msm_camera_io_w(temp1,
-			vfe32_ctrl->share_ctrl->vfebase + VFE_DMI_ADDR);
-		for (i = 0 ; i < V33_PCA_ROLL_OFF_TABLE_SIZE ; i++) {
-			msm_camera_io_w(*cmdp_local,
-				vfe32_ctrl->share_ctrl->vfebase +
-				VFE33_DMI_DATA_LO);
-			cmdp_local += 2;
-		}
-		CDBG("%s: end writing RollOff Ram1 table\n", __func__);
-
-		vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
-		vfe32_ctrl->update_rolloff = true;
-		break;
-	case VFE_CMD_GET_PCA_ROLLOFF_TABLE:
-		temp1 = sizeof(uint64_t) * V33_PCA_ROLL_OFF_TABLE_SIZE * 2;
-		if (cmd->length != temp1) {
-			rc = -EINVAL;
-			goto proc_general_done;
-		}
-		cmdp = kzalloc(temp1, GFP_KERNEL);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		old_val = msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
-			V33_PCA_ROLL_OFF_CFG_OFF1) &
-			V33_PCA_ROLL_OFF_LUT_BANK_SEL_MASK;
-
-		if (old_val)
-			vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK1, vfe32_ctrl);
-		else
-			vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK0, vfe32_ctrl);
-
-		CDBG("%s: PCA Rolloff Ram0\n", __func__);
-		for (i = 0 ; i < V33_PCA_ROLL_OFF_TABLE_SIZE * 2; i++) {
-			temp2 = (i == (V33_PCA_ROLL_OFF_TABLE_SIZE));
-			if (old_val && temp2)
-				vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK1,
-				vfe32_ctrl);
-			else if (!old_val && temp2)
-				vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK0,
-				vfe32_ctrl);
-
-			*cmdp_local = msm_camera_io_r(
-				vfe32_ctrl->share_ctrl->vfebase +
-				VFE33_DMI_DATA_LO);
-			*(cmdp_local + 1) =
-				msm_camera_io_r(
-				vfe32_ctrl->share_ctrl->vfebase +
-				VFE33_DMI_DATA_HI);
-			CDBG("%s: %08x%08x\n", __func__,
-				*(cmdp_local + 1), *cmdp_local);
-			cmdp_local += 2;
-		}
-		vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
-		if (copy_to_user((void __user *)(cmd->value), cmdp,
-			temp1)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		break;
-	case VFE_CMD_GET_HW_VERSION:
-		if (cmd->length != V32_GET_HW_VERSION_LEN) {
-			rc = -EINVAL;
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(V32_GET_HW_VERSION_LEN, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		*cmdp = msm_camera_io_r(
-			vfe32_ctrl->share_ctrl->vfebase+V32_GET_HW_VERSION_OFF);
-		if (copy_to_user((void __user *)(cmd->value), cmdp,
-			V32_GET_HW_VERSION_LEN)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		break;
-	case VFE_CMD_GET_REG_DUMP:
-		temp1 = sizeof(uint32_t) *
-			vfe32_ctrl->share_ctrl->register_total;
-		if (cmd->length != temp1) {
-			rc = -EINVAL;
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(temp1, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		msm_camera_io_dump(vfe32_ctrl->share_ctrl->vfebase,
-			vfe32_ctrl->share_ctrl->register_total*4);
-		CDBG("%s: %p %p %d\n", __func__, (void *)cmdp,
-			vfe32_ctrl->share_ctrl->vfebase, temp1);
-		memcpy_fromio((void *)cmdp,
-			vfe32_ctrl->share_ctrl->vfebase, temp1);
-		if (copy_to_user((void __user *)(cmd->value), cmdp, temp1)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		break;
-	case VFE_CMD_FRAME_SKIP_CFG:
-		if (cmd->length != vfe32_cmd[cmd->id].length)
-			return -EINVAL;
-
-		cmdp = kmalloc(vfe32_cmd[cmd->id].length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-
-		if (copy_from_user((cmdp), (void __user *)cmd->value,
-				cmd->length)) {
-			rc = -EFAULT;
-			pr_err("%s copy from user failed for cmd %d",
-				__func__, cmd->id);
-			break;
-		}
-
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase +
-			vfe32_cmd[cmd->id].offset,
-			cmdp, (vfe32_cmd[cmd->id].length));
-		vfe32_ctrl->frame_skip_cnt = ((uint32_t)
-			*cmdp & VFE_FRAME_SKIP_PERIOD_MASK) + 1;
-		vfe32_ctrl->frame_skip_pattern = (uint32_t)(*(cmdp + 2));
-		break;
-	case VFE_CMD_STOP_LIVESHOT:
-		CDBG("%s Stopping liveshot ", __func__);
-		vfe32_stop_liveshot(pmctl, vfe32_ctrl);
-		break;
-	default:
-		if (cmd->length != vfe32_cmd[cmd->id].length)
-			return -EINVAL;
-
-		cmdp = kmalloc(vfe32_cmd[cmd->id].length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-
-		if (copy_from_user((cmdp), (void __user *)cmd->value,
-				cmd->length)) {
-			rc = -EFAULT;
-			pr_err("%s copy from user failed for cmd %d",
-				__func__, cmd->id);
-			goto proc_general_done;
-		}
-		msm_camera_io_memcpy(
-			vfe32_ctrl->share_ctrl->vfebase +
-			vfe32_cmd[cmd->id].offset,
-			cmdp, (vfe32_cmd[cmd->id].length));
-		break;
-
-	}
-
-proc_general_done:
-	kfree(cmdp);
-
-	return rc;
-}
-
-static inline void vfe32_read_irq_status(
-	struct axi_ctrl_t *axi_ctrl, struct vfe32_irq_status *out)
-{
-	uint32_t *temp;
-	memset(out, 0, sizeof(struct vfe32_irq_status));
-	temp = (uint32_t *)(axi_ctrl->share_ctrl->vfebase + VFE_IRQ_STATUS_0);
-	out->vfeIrqStatus0 = msm_camera_io_r(temp);
-
-	temp = (uint32_t *)(axi_ctrl->share_ctrl->vfebase + VFE_IRQ_STATUS_1);
-	out->vfeIrqStatus1 = msm_camera_io_r(temp);
-
-	temp = (uint32_t *)(axi_ctrl->share_ctrl->vfebase + VFE_CAMIF_STATUS);
-	out->camifStatus = msm_camera_io_r(temp);
-	CDBG("camifStatus  = 0x%x\n", out->camifStatus);
-
-	/* clear the pending interrupt of the same kind.*/
-	msm_camera_io_w(out->vfeIrqStatus0,
-		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_0);
-	msm_camera_io_w(out->vfeIrqStatus1,
-		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_1);
-
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	msm_camera_io_w_mb(1, axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CMD);
-
-}
-
-void axi_stop_pix(struct vfe_share_ctrl_t *share_ctrl,
-	uint32_t vfe_mode, uint8_t cmd_type)
-{
-	uint32_t reg_update = 0x1;
-	switch (cmd_type) {
-	case AXI_CMD_RAW_CAPTURE:
-		msm_camera_io_w(0, share_ctrl->vfebase
-			+ vfe32_AXI_WM_CFG[share_ctrl->outpath.out0.ch0]);
-		break;
-	case AXI_CMD_PREVIEW: {
-		switch (vfe_mode) {
-		case VFE_OUTPUTS_PREVIEW:
-		case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
-			if (share_ctrl->comp_output_mode &
-				VFE32_OUTPUT_MODE_PRIMARY) {
-				msm_camera_io_w(0, share_ctrl->vfebase
-					+ vfe32_AXI_WM_CFG[share_ctrl->
-					outpath.out0.ch0]);
-				msm_camera_io_w(0, share_ctrl->vfebase
-					+ vfe32_AXI_WM_CFG[share_ctrl->
-					outpath.out0.ch1]);
-			} else if (share_ctrl->comp_output_mode &
-					VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
-				msm_camera_io_w(0, share_ctrl->vfebase
-					+ vfe32_AXI_WM_CFG[share_ctrl->
-					outpath.out0.ch0]);
-				msm_camera_io_w(0, share_ctrl->vfebase
-					+ vfe32_AXI_WM_CFG[share_ctrl->
-					outpath.out0.ch1]);
-				msm_camera_io_w(0, share_ctrl->vfebase
-					+ vfe32_AXI_WM_CFG[share_ctrl->
-					outpath.out0.ch2]);
-			}
-			break;
-		default:
-			if (share_ctrl->comp_output_mode &
-				VFE32_OUTPUT_MODE_SECONDARY) {
-				msm_camera_io_w(0, share_ctrl->vfebase
-					+ vfe32_AXI_WM_CFG[share_ctrl->
-					outpath.out1.ch0]);
-				msm_camera_io_w(0, share_ctrl->vfebase
-					+ vfe32_AXI_WM_CFG[share_ctrl->
-					outpath.out1.ch1]);
-			} else if (share_ctrl->comp_output_mode &
-				VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
-				msm_camera_io_w(0, share_ctrl->vfebase
-					+ vfe32_AXI_WM_CFG[share_ctrl->
-					outpath.out1.ch0]);
-				msm_camera_io_w(0, share_ctrl->vfebase
-					+ vfe32_AXI_WM_CFG[share_ctrl->
-					outpath.out1.ch1]);
-				msm_camera_io_w(0, share_ctrl->vfebase
-					+ vfe32_AXI_WM_CFG[share_ctrl->
-					outpath.out1.ch2]);
-			}
-			break;
-			}
-		}
-		break;
-	default:
-		if (share_ctrl->comp_output_mode &
-			VFE32_OUTPUT_MODE_PRIMARY) {
-			msm_camera_io_w(0, share_ctrl->vfebase +
-				vfe32_AXI_WM_CFG[share_ctrl->
-				outpath.out0.ch0]);
-			msm_camera_io_w(0, share_ctrl->vfebase +
-				vfe32_AXI_WM_CFG[share_ctrl->
-				outpath.out0.ch1]);
-		} else if (share_ctrl->comp_output_mode &
-				VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
-			msm_camera_io_w(0, share_ctrl->vfebase +
-				vfe32_AXI_WM_CFG[share_ctrl->
-				outpath.out0.ch0]);
-			msm_camera_io_w(0, share_ctrl->vfebase +
-				vfe32_AXI_WM_CFG[share_ctrl->
-				outpath.out0.ch1]);
-			msm_camera_io_w(0, share_ctrl->vfebase +
-				vfe32_AXI_WM_CFG[share_ctrl->
-				outpath.out0.ch2]);
-		}
-
-		if (share_ctrl->comp_output_mode &
-			VFE32_OUTPUT_MODE_SECONDARY) {
-			msm_camera_io_w(0, share_ctrl->vfebase +
-				vfe32_AXI_WM_CFG[share_ctrl->
-				outpath.out1.ch0]);
-			msm_camera_io_w(0, share_ctrl->vfebase +
-				vfe32_AXI_WM_CFG[share_ctrl->outpath.out1.ch1]);
-		} else if (share_ctrl->comp_output_mode &
-			VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
-			msm_camera_io_w(0, share_ctrl->vfebase +
-				vfe32_AXI_WM_CFG[share_ctrl->outpath.out1.ch0]);
-			msm_camera_io_w(0, share_ctrl->vfebase +
-				vfe32_AXI_WM_CFG[share_ctrl->outpath.out1.ch1]);
-			msm_camera_io_w(0, share_ctrl->vfebase +
-				vfe32_AXI_WM_CFG[share_ctrl->outpath.out1.ch2]);
-		}
-		break;
-	}
-
-	msm_camera_io_w_mb(reg_update,
-		share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-}
-
-void axi_stop_rdi0(struct vfe_share_ctrl_t *share_ctrl)
-{
-	uint32_t reg_update = 0x2;
-	msm_camera_io_w(0, share_ctrl->vfebase +
-		vfe32_AXI_WM_CFG[share_ctrl->outpath.out2.ch0]);
-	msm_camera_io_w_mb(reg_update,
-		share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-}
-
-void axi_stop_rdi1(struct vfe_share_ctrl_t *share_ctrl)
-{
-	uint32_t reg_update = 0x4;
-	msm_camera_io_w(0, share_ctrl->vfebase +
-		vfe32_AXI_WM_CFG[share_ctrl->outpath.out3.ch0]);
-	msm_camera_io_w_mb(reg_update,
-		share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-}
-
-void axi_stop_process(struct vfe_share_ctrl_t *share_ctrl)
-{
-	uint32_t vfe_mode =
-	share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
-		VFE_OUTPUTS_RDI1);
-
-	if (share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
-		axi_stop_rdi0(share_ctrl);
-		axi_disable_wm_irq(share_ctrl,
-			VFE32_OUTPUT_MODE_TERTIARY1);
-		share_ctrl->comp_output_mode &= ~VFE32_OUTPUT_MODE_TERTIARY1;
-		share_ctrl->operation_mode &=
-			~(VFE_OUTPUTS_RDI0);
-	}
-	if (share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
-		axi_stop_rdi1(share_ctrl);
-		axi_disable_wm_irq(share_ctrl,
-			VFE32_OUTPUT_MODE_TERTIARY2);
-		share_ctrl->comp_output_mode &= ~VFE32_OUTPUT_MODE_TERTIARY2;
-		share_ctrl->operation_mode &=
-			~(VFE_OUTPUTS_RDI1);
-	}
-	if (vfe_mode) {
-		uint16_t mode = share_ctrl->comp_output_mode &
-			~(VFE32_OUTPUT_MODE_TERTIARY1|
-			VFE32_OUTPUT_MODE_TERTIARY2);
-		axi_stop_pix(share_ctrl, vfe_mode, share_ctrl->cmd_type);
-		axi_disable_wm_irq(share_ctrl, mode);
-		share_ctrl->comp_output_mode &=
-				(VFE32_OUTPUT_MODE_TERTIARY1|
-				VFE32_OUTPUT_MODE_TERTIARY2);
-	}
-}
-
-static void vfe32_process_reg_update_irq(
-		struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	unsigned long flags;
-	struct vfe_share_ctrl_t *share_ctrl = vfe32_ctrl->share_ctrl;
-	if (atomic_read(
-		&share_ctrl->pix0_update_ack_pending) == 2) {
-		uint32_t vfe_mode =
-				share_ctrl->operation_mode & ~(VFE_OUTPUTS_RDI0|
-					VFE_OUTPUTS_RDI1);
-
-		if (share_ctrl->dual_enabled && !share_ctrl->update_counter) {
-			axi_stop_pix(share_ctrl, vfe_mode,
-				share_ctrl->cmd_type);
-			share_ctrl->update_counter++;
-		} else {
-			uint16_t output_mode =
-				share_ctrl->comp_output_mode &
-				~(VFE32_OUTPUT_MODE_TERTIARY1|
-				VFE32_OUTPUT_MODE_TERTIARY2);
-			share_ctrl->update_counter = 0;
-			if (!share_ctrl->dual_enabled)
-				axi_stop_pix(share_ctrl, vfe_mode,
-					share_ctrl->cmd_type);
-			axi_disable_wm_irq(share_ctrl, output_mode);
-			axi_disable_irq(share_ctrl, vfe_mode);
-			atomic_set(&share_ctrl->pix0_update_ack_pending, 0);
-			msm_camera_io_w_mb(
-					CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
-					share_ctrl->vfebase +
-					VFE_CAMIF_COMMAND);
-			vfe32_send_isp_msg(&vfe32_ctrl->subdev,
-				share_ctrl->vfeFrameId,
-				MSG_ID_PIX0_UPDATE_ACK);
-			share_ctrl->comp_output_mode &=
-				(VFE32_OUTPUT_MODE_TERTIARY1|
-				VFE32_OUTPUT_MODE_TERTIARY2);
-		}
-	}  else {
-		if (share_ctrl->recording_state == VFE_STATE_START_REQUESTED) {
-			if (share_ctrl->operation_mode &
-					VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
-				msm_camera_io_w((
-					0x1 << share_ctrl->outpath.out0.ch0 |
-					0x1 << share_ctrl->outpath.out0.ch1),
-					share_ctrl->vfebase + VFE_BUS_CMD);
-				msm_camera_io_w(1,
-					share_ctrl->vfebase + vfe32_AXI_WM_CFG[
-					share_ctrl->outpath.out0.ch0]);
-				msm_camera_io_w(1,
-					share_ctrl->vfebase + vfe32_AXI_WM_CFG[
-					share_ctrl->outpath.out0.ch1]);
-			} else if (share_ctrl->operation_mode &
-					VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
-				msm_camera_io_w((
-					0x1 << share_ctrl->outpath.out1.ch0 |
-					0x1 << share_ctrl->outpath.out1.ch1),
-					share_ctrl->vfebase + VFE_BUS_CMD);
-				msm_camera_io_w(1,
-					share_ctrl->vfebase + vfe32_AXI_WM_CFG[
-					share_ctrl->outpath.out1.ch0]);
-				msm_camera_io_w(1,
-					share_ctrl->vfebase + vfe32_AXI_WM_CFG[
-					share_ctrl->outpath.out1.ch1]);
-			}
-			share_ctrl->recording_state = VFE_STATE_STARTED;
-			msm_camera_io_w_mb(1,
-				share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-			CDBG("start video triggered .\n");
-		} else if (share_ctrl->recording_state ==
-					VFE_STATE_STOP_REQUESTED) {
-			if (share_ctrl->operation_mode &
-					VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
-				msm_camera_io_w(0,
-					share_ctrl->vfebase + vfe32_AXI_WM_CFG[
-					share_ctrl->outpath.out0.ch0]);
-				msm_camera_io_w(0,
-					share_ctrl->vfebase + vfe32_AXI_WM_CFG[
-					share_ctrl->outpath.out0.ch1]);
-			} else if (share_ctrl->operation_mode &
-					VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
-				msm_camera_io_w(0,
-					share_ctrl->vfebase + vfe32_AXI_WM_CFG[
-					share_ctrl->outpath.out1.ch0]);
-				msm_camera_io_w(0,
-					share_ctrl->vfebase + vfe32_AXI_WM_CFG[
-					share_ctrl->outpath.out1.ch1]);
-			}
-			CDBG("stop video triggered .\n");
-		}
-
-		if (atomic_cmpxchg(
-		&share_ctrl->pix0_update_ack_pending, 1, 0) == 1) {
-			share_ctrl->comp_output_mode |=
-				(share_ctrl->outpath.output_mode
-				& ~(VFE32_OUTPUT_MODE_TERTIARY1|
-					VFE32_OUTPUT_MODE_TERTIARY2));
-			vfe32_send_isp_msg(&vfe32_ctrl->subdev,
-				share_ctrl->vfeFrameId, MSG_ID_PIX0_UPDATE_ACK);
-		} else {
-			if (share_ctrl->recording_state ==
-						VFE_STATE_STOP_REQUESTED) {
-				share_ctrl->recording_state = VFE_STATE_STOPPED;
-				/* request a reg update and send STOP_REC_ACK
-				 * when we process the next reg update irq.
-				 */
-				msm_camera_io_w_mb(1, share_ctrl->vfebase +
-							VFE_REG_UPDATE_CMD);
-			} else if (share_ctrl->recording_state ==
-						VFE_STATE_STOPPED) {
-				vfe32_send_isp_msg(&vfe32_ctrl->subdev,
-					share_ctrl->vfeFrameId,
-					MSG_ID_STOP_REC_ACK);
-				share_ctrl->recording_state = VFE_STATE_IDLE;
-			}
-			spin_lock_irqsave(
-				&share_ctrl->update_ack_lock,
-				flags);
-			if (share_ctrl->update_ack_pending == TRUE) {
-				share_ctrl->update_ack_pending = FALSE;
-				spin_unlock_irqrestore(
-					&share_ctrl->update_ack_lock, flags);
-				vfe32_send_isp_msg(&vfe32_ctrl->subdev,
-					share_ctrl->vfeFrameId,
-					MSG_ID_UPDATE_ACK);
-			} else {
-				spin_unlock_irqrestore(
-					&share_ctrl->update_ack_lock, flags);
-			}
-		}
-
-		switch (share_ctrl->liveshot_state) {
-		case VFE_STATE_START_REQUESTED:
-			CDBG("%s enabling liveshot output\n", __func__);
-			if (share_ctrl->comp_output_mode &
-						VFE32_OUTPUT_MODE_PRIMARY) {
-				msm_camera_io_w((
-					0x1 << share_ctrl->outpath.out0.ch0 |
-					0x1 << share_ctrl->outpath.out0.ch1),
-					share_ctrl->vfebase + VFE_BUS_CMD);
-				msm_camera_io_w(1, share_ctrl->vfebase +
-					vfe32_AXI_WM_CFG[
-					share_ctrl->outpath.out0.ch0]);
-				msm_camera_io_w(1, share_ctrl->vfebase +
-					vfe32_AXI_WM_CFG[
-					share_ctrl->outpath.out0.ch1]);
-
-				share_ctrl->liveshot_state =
-					VFE_STATE_STARTED;
-			}
-			break;
-		case VFE_STATE_STARTED:
-			share_ctrl->vfe_capture_count--;
-			if (!share_ctrl->vfe_capture_count &&
-				(share_ctrl->comp_output_mode &
-					VFE32_OUTPUT_MODE_PRIMARY)) {
-				msm_camera_io_w(0, share_ctrl->vfebase +
-					vfe32_AXI_WM_CFG[
-					share_ctrl->outpath.out0.ch0]);
-				msm_camera_io_w(0, share_ctrl->vfebase +
-					vfe32_AXI_WM_CFG[
-					share_ctrl->outpath.out0.ch1]);
-			}
-			break;
-		case VFE_STATE_STOP_REQUESTED:
-			if (share_ctrl->comp_output_mode &
-					VFE32_OUTPUT_MODE_PRIMARY) {
-				/* Stop requested, stop write masters, and
-				 * trigger REG_UPDATE. Send STOP_LS_ACK in
-				 * next reg update. */
-				msm_camera_io_w(0, share_ctrl->vfebase +
-					vfe32_AXI_WM_CFG[
-					share_ctrl->outpath.out0.ch0]);
-				msm_camera_io_w(0, share_ctrl->vfebase +
-					vfe32_AXI_WM_CFG[
-					share_ctrl->outpath.out0.ch1]);
-
-				share_ctrl->liveshot_state = VFE_STATE_STOPPED;
-				msm_camera_io_w_mb(1, share_ctrl->vfebase +
-					VFE_REG_UPDATE_CMD);
-			}
-			break;
-		case VFE_STATE_STOPPED:
-			CDBG("%s Sending STOP_LS ACK\n", __func__);
-			vfe32_send_isp_msg(&vfe32_ctrl->subdev,
-				share_ctrl->vfeFrameId, MSG_ID_STOP_LS_ACK);
-			share_ctrl->liveshot_state = VFE_STATE_IDLE;
-			break;
-		default:
-			break;
-		}
-
-		if ((share_ctrl->operation_mode & VFE_OUTPUTS_THUMB_AND_MAIN) ||
-			(share_ctrl->operation_mode &
-				VFE_OUTPUTS_MAIN_AND_THUMB) ||
-			(share_ctrl->operation_mode &
-				VFE_OUTPUTS_THUMB_AND_JPEG) ||
-			(share_ctrl->operation_mode &
-				VFE_OUTPUTS_JPEG_AND_THUMB)) {
-			/* in snapshot mode */
-			/* later we need to add check for live snapshot mode. */
-			if (vfe32_ctrl->frame_skip_pattern & (0x1 <<
-				(vfe32_ctrl->snapshot_frame_cnt %
-					vfe32_ctrl->frame_skip_cnt))) {
-				share_ctrl->vfe_capture_count--;
-				/* if last frame to be captured: */
-				if (share_ctrl->vfe_capture_count == 0) {
-					/* stop the bus output: */
-					uint32_t vfe_mode =
-						share_ctrl->operation_mode &
-							~(VFE_OUTPUTS_RDI0|
-							VFE_OUTPUTS_RDI1);
-					axi_stop_pix(share_ctrl, vfe_mode,
-						AXI_CMD_CAPTURE);
-					msm_camera_io_w_mb
-					(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
-					share_ctrl->vfebase +
-					VFE_CAMIF_COMMAND);
-					vfe32_ctrl->snapshot_frame_cnt = -1;
-					vfe32_ctrl->frame_skip_cnt = 31;
-					vfe32_ctrl->frame_skip_pattern =
-								0xffffffff;
-				} /*if snapshot count is 0*/
-			} /*if frame is not being dropped*/
-			vfe32_ctrl->snapshot_frame_cnt++;
-			/* then do reg_update. */
-			msm_camera_io_w(1,
-				share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-		} /* if snapshot mode. */
-	}
-}
-
-static void vfe32_process_rdi0_reg_update_irq(
-	struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	if (atomic_cmpxchg(
-		&vfe32_ctrl->share_ctrl->rdi0_update_ack_pending, 1, 0) == 1) {
-		vfe32_ctrl->share_ctrl->comp_output_mode |=
-			VFE32_OUTPUT_MODE_TERTIARY1;
-		vfe32_send_isp_msg(&vfe32_ctrl->subdev,
-			vfe32_ctrl->share_ctrl->rdi0FrameId,
-			MSG_ID_RDI0_UPDATE_ACK);
-	}
-
-	if ((atomic_read(
-		&vfe32_ctrl->share_ctrl->rdi0_update_ack_pending) == 2)
-		|| (vfe32_ctrl->share_ctrl->rdi0_capture_count == 0)) {
-		axi_disable_wm_irq(vfe32_ctrl->share_ctrl,
-			VFE32_OUTPUT_MODE_TERTIARY1);
-		axi_disable_irq(vfe32_ctrl->share_ctrl, VFE_OUTPUTS_RDI0);
-		atomic_set(&vfe32_ctrl->share_ctrl->rdi0_update_ack_pending, 0);
-		vfe32_send_isp_msg(&vfe32_ctrl->subdev,
-			vfe32_ctrl->share_ctrl->rdi0FrameId,
-			MSG_ID_RDI0_UPDATE_ACK);
-
-		if (vfe32_ctrl->share_ctrl->rdi0_capture_count == 0)
-			vfe32_ctrl->share_ctrl->rdi0_capture_count = -1;
-		if (vfe32_ctrl->share_ctrl->outpath.out2.capture_cnt
-			== 0)
-			vfe32_ctrl->share_ctrl->outpath.out2.capture_cnt = -1;
-		vfe32_ctrl->share_ctrl->comp_output_mode &=
-			~VFE32_OUTPUT_MODE_TERTIARY1;
-		vfe32_ctrl->share_ctrl->operation_mode &=
-			~(VFE_OUTPUTS_RDI0);
-	}
-
-	if (vfe32_ctrl->share_ctrl->rdi0_capture_count > 0) {
-		vfe32_ctrl->share_ctrl->rdi0_capture_count--;
-		if (!vfe32_ctrl->share_ctrl->rdi0_capture_count)
-			axi_stop_rdi0(vfe32_ctrl->share_ctrl);
-	}
-}
-
-static void vfe32_process_rdi1_reg_update_irq(
-	struct vfe32_ctrl_type *vfe32_ctrl)
-{
-
-	if (atomic_cmpxchg(
-		&vfe32_ctrl->share_ctrl->rdi1_update_ack_pending, 1, 0)
-				== 1) {
-		vfe32_ctrl->share_ctrl->comp_output_mode |=
-			VFE32_OUTPUT_MODE_TERTIARY2;
-		vfe32_send_isp_msg(&vfe32_ctrl->subdev,
-			vfe32_ctrl->share_ctrl->rdi1FrameId,
-			MSG_ID_RDI1_UPDATE_ACK);
-	}
-
-	if ((atomic_read(
-		&vfe32_ctrl->share_ctrl->rdi1_update_ack_pending) == 2)
-		|| (vfe32_ctrl->share_ctrl->rdi1_capture_count == 0)) {
-		axi_disable_wm_irq(vfe32_ctrl->share_ctrl,
-			VFE32_OUTPUT_MODE_TERTIARY2);
-		axi_disable_irq(vfe32_ctrl->share_ctrl, VFE_OUTPUTS_RDI1);
-		atomic_set(&vfe32_ctrl->share_ctrl->rdi1_update_ack_pending, 0);
-		vfe32_send_isp_msg(&vfe32_ctrl->subdev,
-			vfe32_ctrl->share_ctrl->rdi1FrameId,
-			MSG_ID_RDI1_UPDATE_ACK);
-
-		if (vfe32_ctrl->share_ctrl->rdi1_capture_count == 0)
-			vfe32_ctrl->share_ctrl->rdi1_capture_count = -1;
-		if (vfe32_ctrl->share_ctrl->outpath.out3.capture_cnt
-			== 0)
-			vfe32_ctrl->share_ctrl->outpath.out3.capture_cnt = -1;
-		vfe32_ctrl->share_ctrl->comp_output_mode &=
-			~VFE32_OUTPUT_MODE_TERTIARY2;
-		vfe32_ctrl->share_ctrl->operation_mode &=
-			~(VFE_OUTPUTS_RDI1);
-	}
-
-	if (vfe32_ctrl->share_ctrl->rdi1_capture_count > 0) {
-		vfe32_ctrl->share_ctrl->rdi1_capture_count--;
-		if (!vfe32_ctrl->share_ctrl->rdi1_capture_count)
-			axi_stop_rdi1(vfe32_ctrl->share_ctrl);
-	}
-}
-
-static void vfe32_process_reset_irq(
-		struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	unsigned long flags;
-
-	atomic_set(&vfe32_ctrl->share_ctrl->vstate, 0);
-	atomic_set(&vfe32_ctrl->share_ctrl->handle_common_irq, 0);
-
-	spin_lock_irqsave(&vfe32_ctrl->share_ctrl->stop_flag_lock, flags);
-	if (vfe32_ctrl->share_ctrl->stop_ack_pending) {
-		vfe32_ctrl->share_ctrl->stop_ack_pending = FALSE;
-		spin_unlock_irqrestore(
-			&vfe32_ctrl->share_ctrl->stop_flag_lock, flags);
-		if (vfe32_ctrl->share_ctrl->sync_abort)
-			complete(&vfe32_ctrl->share_ctrl->reset_complete);
-		else
-			vfe32_send_isp_msg(&vfe32_ctrl->subdev,
-				vfe32_ctrl->share_ctrl->vfeFrameId,
-				MSG_ID_STOP_ACK);
-	} else {
-		spin_unlock_irqrestore(
-			&vfe32_ctrl->share_ctrl->stop_flag_lock, flags);
-		/* this is from reset command. */
-		vfe32_reset_internal_variables(vfe32_ctrl);
-		if (vfe32_ctrl->share_ctrl->vfe_reset_flag) {
-			vfe32_ctrl->share_ctrl->vfe_reset_flag = false;
-			msm_camera_io_w(0x7F80,
-				vfe32_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
-		} else {
-			/* reload all write masters. (frame & line)*/
-			msm_camera_io_w(0x7FFF,
-				vfe32_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
-		}
-		complete(&vfe32_ctrl->share_ctrl->reset_complete);
-	}
-}
-
-static void vfe32_process_camif_sof_irq(
-		struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	if (vfe32_ctrl->share_ctrl->operation_mode ==
-		VFE_OUTPUTS_RAW) {
-		if (atomic_cmpxchg(
-			&vfe32_ctrl->share_ctrl->pix0_update_ack_pending,
-					1, 0) == 1) {
-			vfe32_ctrl->share_ctrl->comp_output_mode |=
-				(vfe32_ctrl->share_ctrl->outpath.output_mode
-				& ~(VFE32_OUTPUT_MODE_TERTIARY1|
-				VFE32_OUTPUT_MODE_TERTIARY2));
-			vfe32_send_isp_msg(&vfe32_ctrl->subdev,
-				vfe32_ctrl->share_ctrl->vfeFrameId,
-				MSG_ID_PIX0_UPDATE_ACK);
-		}
-
-		vfe32_ctrl->share_ctrl->vfe_capture_count--;
-		/* if last frame to be captured: */
-		if (vfe32_ctrl->share_ctrl->vfe_capture_count == 0) {
-			/* Ensure the write order while writing
-			 to the command register using the barrier */
-			msm_camera_io_w_mb(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
-			vfe32_ctrl->share_ctrl->vfebase + VFE_CAMIF_COMMAND);
-		}
-	} /* if raw snapshot mode. */
-	if ((vfe32_ctrl->hfr_mode != HFR_MODE_OFF) &&
-		(vfe32_ctrl->share_ctrl->operation_mode ==
-			VFE_MODE_OF_OPERATION_VIDEO) &&
-		(vfe32_ctrl->share_ctrl->vfeFrameId %
-			vfe32_ctrl->hfr_mode != 0)) {
-		if (vfe32_ctrl->vfe_sof_count_enable)
-			vfe32_ctrl->share_ctrl->vfeFrameId++;
-		CDBG("Skip the SOF notification when HFR enabled\n");
-		return;
-	}
-	if (vfe32_ctrl->vfe_sof_count_enable)
-		vfe32_ctrl->share_ctrl->vfeFrameId++;
-
-	vfe32_send_isp_msg(&vfe32_ctrl->subdev,
-		vfe32_ctrl->share_ctrl->vfeFrameId, MSG_ID_SOF_ACK);
-	CDBG("camif_sof_irq, frameId = %d\n",
-		vfe32_ctrl->share_ctrl->vfeFrameId);
-
-	if (vfe32_ctrl->sync_timer_state) {
-		if (vfe32_ctrl->sync_timer_repeat_count == 0)
-			vfe32_sync_timer_stop(vfe32_ctrl);
-		else
-			vfe32_ctrl->sync_timer_repeat_count--;
-	}
-}
-
-static void vfe32_process_error_irq(
-	struct axi_ctrl_t *axi_ctrl, uint32_t errStatus)
-{
-	uint32_t reg_value;
-	if (errStatus & VFE32_IMASK_VIOLATION) {
-		pr_err("vfe32_irq: violation interrupt\n");
-		reg_value = msm_camera_io_r(
-			axi_ctrl->share_ctrl->vfebase + VFE_VIOLATION_STATUS);
-		pr_err("%s: violationStatus  = 0x%x\n", __func__, reg_value);
-	}
-
-	if (errStatus & VFE32_IMASK_CAMIF_ERROR) {
-		pr_err("vfe32_irq: camif errors\n");
-		reg_value = msm_camera_io_r(
-			axi_ctrl->share_ctrl->vfebase + VFE_CAMIF_STATUS);
-		v4l2_subdev_notify(&axi_ctrl->subdev,
-			NOTIFY_VFE_CAMIF_ERROR, (void *)NULL);
-		pr_err("camifStatus  = 0x%x\n", reg_value);
-		vfe32_send_isp_msg(&axi_ctrl->subdev,
-			axi_ctrl->share_ctrl->vfeFrameId, MSG_ID_CAMIF_ERROR);
-	}
-
-	if (errStatus & VFE32_IMASK_BHIST_OVWR)
-		pr_err("vfe32_irq: stats bhist overwrite\n");
-
-	if (errStatus & VFE32_IMASK_STATS_CS_OVWR)
-		pr_err("vfe32_irq: stats cs overwrite\n");
-
-	if (errStatus & VFE32_IMASK_STATS_IHIST_OVWR)
-		pr_err("vfe32_irq: stats ihist overwrite\n");
-
-	if (errStatus & VFE32_IMASK_REALIGN_BUF_Y_OVFL)
-		pr_err("vfe32_irq: realign bug Y overflow\n");
-
-	if (errStatus & VFE32_IMASK_REALIGN_BUF_CB_OVFL)
-		pr_err("vfe32_irq: realign bug CB overflow\n");
-
-	if (errStatus & VFE32_IMASK_REALIGN_BUF_CR_OVFL)
-		pr_err("vfe32_irq: realign bug CR overflow\n");
-
-	if (errStatus & VFE32_IMASK_STATS_AE_BG_BUS_OVFL)
-		pr_err("vfe32_irq: ae/bg stats bus overflow\n");
-
-	if (errStatus & VFE32_IMASK_STATS_AF_BF_BUS_OVFL)
-		pr_err("vfe32_irq: af/bf stats bus overflow\n");
-
-	if (errStatus & VFE32_IMASK_STATS_AWB_BUS_OVFL)
-		pr_err("vfe32_irq: awb stats bus overflow\n");
-
-	if (errStatus & VFE32_IMASK_STATS_RS_BUS_OVFL)
-		pr_err("vfe32_irq: rs stats bus overflow\n");
-
-	if (errStatus & VFE32_IMASK_STATS_CS_BUS_OVFL)
-		pr_err("vfe32_irq: cs stats bus overflow\n");
-
-	if (errStatus & VFE32_IMASK_STATS_IHIST_BUS_OVFL)
-		pr_err("vfe32_irq: ihist stats bus overflow\n");
-
-	if (errStatus & VFE32_IMASK_STATS_SKIN_BHIST_BUS_OVFL)
-		pr_err("vfe32_irq: skin/bhist stats bus overflow\n");
-}
-
-static void vfe32_process_common_error_irq(
-	struct axi_ctrl_t *axi_ctrl, uint32_t errStatus)
-{
-
-	if (errStatus & VFE32_IMASK_IMG_MAST_0_BUS_OVFL)
-		pr_err("vfe32_irq: image master 0 bus overflow\n");
-
-	if (errStatus & VFE32_IMASK_IMG_MAST_1_BUS_OVFL)
-		pr_err("vfe32_irq: image master 1 bus overflow\n");
-
-	if (errStatus & VFE32_IMASK_IMG_MAST_2_BUS_OVFL)
-		pr_err("vfe32_irq: image master 2 bus overflow\n");
-
-	if (errStatus & VFE32_IMASK_IMG_MAST_3_BUS_OVFL)
-		pr_err("vfe32_irq: image master 3 bus overflow\n");
-
-	if (errStatus & VFE32_IMASK_IMG_MAST_4_BUS_OVFL)
-		pr_err("vfe32_irq: image master 4 bus overflow\n");
-
-	if (errStatus & VFE32_IMASK_IMG_MAST_5_BUS_OVFL)
-		pr_err("vfe32_irq: image master 5 bus overflow\n");
-
-	if (errStatus & VFE32_IMASK_IMG_MAST_6_BUS_OVFL)
-		pr_err("vfe32_irq: image master 6 bus overflow\n");
-
-	if (errStatus & VFE32_IMASK_AXI_ERROR)
-		pr_err("vfe32_irq: axi error\n");
-}
-
-
-static void vfe_send_outmsg(
-	struct axi_ctrl_t *axi_ctrl, uint8_t msgid,
-	uint32_t ch0_paddr, uint32_t ch1_paddr,
-	uint32_t ch2_paddr, uint32_t inst_handle)
-{
-	struct isp_msg_output msg;
-
-	msg.output_id = msgid;
-	msg.buf.inst_handle = inst_handle;
-	msg.buf.ch_paddr[0]	= ch0_paddr;
-	msg.buf.ch_paddr[1]	= ch1_paddr;
-	msg.buf.ch_paddr[2]	= ch2_paddr;
-	switch (msgid) {
-	case MSG_ID_OUTPUT_TERTIARY1:
-		msg.frameCounter = axi_ctrl->share_ctrl->rdi0FrameId;
-		break;
-	case MSG_ID_OUTPUT_TERTIARY2:
-		msg.frameCounter = axi_ctrl->share_ctrl->rdi1FrameId;
-		break;
-	default:
-		msg.frameCounter = axi_ctrl->share_ctrl->vfeFrameId;
-		break;
-	}
-
-	v4l2_subdev_notify(&axi_ctrl->subdev,
-			NOTIFY_VFE_MSG_OUT,
-			&msg);
-	return;
-}
-
-static void vfe32_process_output_path_irq_0(
-	struct axi_ctrl_t *axi_ctrl)
-{
-	uint32_t ping_pong;
-	uint32_t ch0_paddr, ch1_paddr, ch2_paddr;
-	uint8_t out_bool = 0;
-	struct msm_free_buf *free_buf = NULL;
-	free_buf = vfe32_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
-		VFE_MSG_OUTPUT_PRIMARY, axi_ctrl);
-
-	/* we render frames in the following conditions:
-	1. Continuous mode and the free buffer is avaialable.
-	2. In snapshot shot mode, free buffer is not always available.
-	when pending snapshot count is <=1,  then no need to use
-	free buffer.
-	*/
-	out_bool = (
-		(axi_ctrl->share_ctrl->operation_mode &
-			VFE_OUTPUTS_THUMB_AND_MAIN ||
-		axi_ctrl->share_ctrl->operation_mode &
-			VFE_OUTPUTS_MAIN_AND_THUMB ||
-		axi_ctrl->share_ctrl->operation_mode &
-			VFE_OUTPUTS_THUMB_AND_JPEG ||
-		axi_ctrl->share_ctrl->operation_mode &
-			VFE_OUTPUTS_JPEG_AND_THUMB ||
-		axi_ctrl->share_ctrl->operation_mode &
-			VFE_OUTPUTS_RAW ||
-		axi_ctrl->share_ctrl->liveshot_state ==
-			VFE_STATE_STARTED ||
-		axi_ctrl->share_ctrl->liveshot_state ==
-			VFE_STATE_STOP_REQUESTED ||
-		axi_ctrl->share_ctrl->liveshot_state ==
-			VFE_STATE_STOPPED) &&
-		(axi_ctrl->share_ctrl->vfe_capture_count <= 1)) ||
-			free_buf;
-
-	if (out_bool) {
-		ping_pong = msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
-			VFE_BUS_PING_PONG_STATUS);
-
-		/* Channel 0*/
-		ch0_paddr = vfe32_get_ch_addr(
-			ping_pong, axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out0.ch0);
-		/* Channel 1*/
-		ch1_paddr = vfe32_get_ch_addr(
-			ping_pong, axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out0.ch1);
-		/* Channel 2*/
-		ch2_paddr = vfe32_get_ch_addr(
-			ping_pong, axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out0.ch2);
-
-		CDBG("output path 0, ch0 = 0x%x, ch1 = 0x%x, ch2 = 0x%x\n",
-			ch0_paddr, ch1_paddr, ch2_paddr);
-		if (free_buf) {
-			/* Y channel */
-			vfe32_put_ch_addr(ping_pong,
-			axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out0.ch0,
-			free_buf->ch_paddr[0]);
-			/* Chroma channel */
-			vfe32_put_ch_addr(ping_pong,
-			axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out0.ch1,
-			free_buf->ch_paddr[1]);
-			if (free_buf->num_planes > 2)
-				vfe32_put_ch_addr(ping_pong,
-					axi_ctrl->share_ctrl->vfebase,
-					axi_ctrl->share_ctrl->outpath.out0.ch2,
-					free_buf->ch_paddr[2]);
-		}
-		if (axi_ctrl->share_ctrl->operation_mode &
-				VFE_OUTPUTS_THUMB_AND_MAIN ||
-			axi_ctrl->share_ctrl->operation_mode &
-				VFE_OUTPUTS_MAIN_AND_THUMB ||
-			axi_ctrl->share_ctrl->operation_mode &
-				VFE_OUTPUTS_THUMB_AND_JPEG ||
-			axi_ctrl->share_ctrl->operation_mode &
-				VFE_OUTPUTS_JPEG_AND_THUMB ||
-			axi_ctrl->share_ctrl->operation_mode &
-				VFE_OUTPUTS_RAW ||
-			axi_ctrl->share_ctrl->liveshot_state ==
-				VFE_STATE_STOPPED)
-			axi_ctrl->share_ctrl->outpath.out0.capture_cnt--;
-
-		vfe_send_outmsg(axi_ctrl,
-			MSG_ID_OUTPUT_PRIMARY, ch0_paddr,
-			ch1_paddr, ch2_paddr,
-			axi_ctrl->share_ctrl->outpath.out0.inst_handle);
-
-	} else {
-		axi_ctrl->share_ctrl->outpath.out0.frame_drop_cnt++;
-		CDBG("path_irq_0 - no free buffer!\n");
-	}
-}
-
-static void vfe32_process_output_path_irq_1(
-	struct axi_ctrl_t *axi_ctrl)
-{
-	uint32_t ping_pong;
-	uint32_t ch0_paddr, ch1_paddr, ch2_paddr;
-	/* this must be snapshot main image output. */
-	uint8_t out_bool = 0;
-	struct msm_free_buf *free_buf = NULL;
-
-	free_buf = vfe32_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
-		VFE_MSG_OUTPUT_SECONDARY, axi_ctrl);
-	out_bool = ((axi_ctrl->share_ctrl->operation_mode &
-				VFE_OUTPUTS_THUMB_AND_MAIN ||
-			axi_ctrl->share_ctrl->operation_mode &
-				VFE_OUTPUTS_MAIN_AND_THUMB ||
-			axi_ctrl->share_ctrl->operation_mode &
-				VFE_OUTPUTS_RAW ||
-			axi_ctrl->share_ctrl->operation_mode &
-				VFE_OUTPUTS_JPEG_AND_THUMB) &&
-			(axi_ctrl->share_ctrl->vfe_capture_count <= 1)) ||
-				free_buf;
-
-	if (out_bool) {
-		ping_pong = msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
-			VFE_BUS_PING_PONG_STATUS);
-
-		/* Y channel */
-		ch0_paddr = vfe32_get_ch_addr(ping_pong,
-			axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out1.ch0);
-		/* Chroma channel */
-		ch1_paddr = vfe32_get_ch_addr(ping_pong,
-			axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out1.ch1);
-		ch2_paddr = vfe32_get_ch_addr(ping_pong,
-			axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out1.ch2);
-
-		CDBG("%s ch0 = 0x%x, ch1 = 0x%x, ch2 = 0x%x\n",
-			__func__, ch0_paddr, ch1_paddr, ch2_paddr);
-		if (free_buf) {
-			/* Y channel */
-			vfe32_put_ch_addr(ping_pong,
-			axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out1.ch0,
-			free_buf->ch_paddr[0]);
-			/* Chroma channel */
-			vfe32_put_ch_addr(ping_pong,
-			axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out1.ch1,
-			free_buf->ch_paddr[1]);
-			if (free_buf->num_planes > 2)
-				vfe32_put_ch_addr(ping_pong,
-					axi_ctrl->share_ctrl->vfebase,
-					axi_ctrl->share_ctrl->outpath.out1.ch2,
-					free_buf->ch_paddr[2]);
-		}
-		if (axi_ctrl->share_ctrl->operation_mode &
-				VFE_OUTPUTS_THUMB_AND_MAIN ||
-			axi_ctrl->share_ctrl->operation_mode &
-				VFE_OUTPUTS_MAIN_AND_THUMB ||
-			axi_ctrl->share_ctrl->operation_mode &
-				VFE_OUTPUTS_RAW ||
-			axi_ctrl->share_ctrl->operation_mode &
-				VFE_OUTPUTS_JPEG_AND_THUMB)
-			axi_ctrl->share_ctrl->outpath.out1.capture_cnt--;
-
-		vfe_send_outmsg(axi_ctrl,
-			MSG_ID_OUTPUT_SECONDARY, ch0_paddr,
-			ch1_paddr, ch2_paddr,
-			axi_ctrl->share_ctrl->outpath.out1.inst_handle);
-
-	} else {
-		axi_ctrl->share_ctrl->outpath.out1.frame_drop_cnt++;
-		CDBG("path_irq_1 - no free buffer!\n");
-	}
-}
-
-static void vfe32_process_output_path_irq_rdi0(
-			struct axi_ctrl_t *axi_ctrl)
-{
-	uint32_t ping_pong;
-	uint32_t ch0_paddr = 0;
-	/* this must be rdi image output. */
-	struct msm_free_buf *free_buf = NULL;
-	/*RDI0*/
-	CDBG("rdi0 out irq\n");
-	if (axi_ctrl->share_ctrl->operation_mode & VFE_OUTPUTS_RDI0) {
-		free_buf = vfe32_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
-			VFE_MSG_OUTPUT_TERTIARY1, axi_ctrl);
-		if (axi_ctrl->share_ctrl->outpath.out2.capture_cnt > 0 ||
-							free_buf) {
-			ping_pong = msm_camera_io_r(axi_ctrl->
-				share_ctrl->vfebase +
-				VFE_BUS_PING_PONG_STATUS);
-
-			/* Y only channel */
-			ch0_paddr = vfe32_get_ch_addr(ping_pong,
-				axi_ctrl->share_ctrl->vfebase,
-				axi_ctrl->share_ctrl->outpath.out2.ch0);
-
-			pr_debug("%s ch0 = 0x%x\n",
-				__func__, ch0_paddr);
-
-			if (free_buf)
-				vfe32_put_ch_addr(ping_pong,
-					axi_ctrl->share_ctrl->vfebase,
-					axi_ctrl->share_ctrl->outpath.out2.ch0,
-					free_buf->ch_paddr[0]);
-			if (axi_ctrl->share_ctrl->outpath.out2.capture_cnt == 1)
-				axi_ctrl->share_ctrl->
-					outpath.out2.capture_cnt = 0;
-
-			vfe_send_outmsg(axi_ctrl,
-				MSG_ID_OUTPUT_TERTIARY1, ch0_paddr,
-				0, 0,
-				axi_ctrl->share_ctrl->outpath.out2.inst_handle);
-
-		} else {
-			axi_ctrl->share_ctrl->outpath.out2.frame_drop_cnt++;
-			pr_err("path_irq_2 irq - no free buffer for rdi0!\n");
-		}
-	}
-}
-
-static void vfe32_process_output_path_irq_rdi1(
-	struct axi_ctrl_t *axi_ctrl)
-{
-	uint32_t ping_pong;
-	uint32_t ch0_paddr = 0;
-	/* this must be rdi image output. */
-	struct msm_free_buf *free_buf = NULL;
-	/*RDI1*/
-	if (axi_ctrl->share_ctrl->operation_mode & VFE_OUTPUTS_RDI1) {
-		free_buf = vfe32_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
-			VFE_MSG_OUTPUT_TERTIARY2, axi_ctrl);
-		if (axi_ctrl->share_ctrl->outpath.out3.capture_cnt > 0 ||
-							free_buf) {
-			ping_pong = msm_camera_io_r(axi_ctrl->
-				share_ctrl->vfebase +
-				VFE_BUS_PING_PONG_STATUS);
-
-			/* Y channel */
-			ch0_paddr = vfe32_get_ch_addr(ping_pong,
-				axi_ctrl->share_ctrl->vfebase,
-				axi_ctrl->share_ctrl->outpath.out3.ch0);
-			pr_debug("%s ch0 = 0x%x\n",
-				__func__, ch0_paddr);
-
-			if (free_buf)
-				vfe32_put_ch_addr(ping_pong,
-					axi_ctrl->share_ctrl->vfebase,
-					axi_ctrl->share_ctrl->outpath.out3.ch0,
-					free_buf->ch_paddr[0]);
-			if (axi_ctrl->share_ctrl->
-					outpath.out3.capture_cnt == 1)
-				axi_ctrl->share_ctrl->
-				outpath.out3.capture_cnt = 0;
-
-			vfe_send_outmsg(axi_ctrl,
-				MSG_ID_OUTPUT_TERTIARY2, ch0_paddr,
-				0, 0,
-				axi_ctrl->share_ctrl->outpath.out3.inst_handle);
-		} else {
-			axi_ctrl->share_ctrl->outpath.out3.frame_drop_cnt++;
-			pr_err("path_irq irq - no free buffer for rdi1!\n");
-		}
-	}
-}
-
-static uint32_t  vfe32_process_stats_irq_common(
-	struct vfe32_ctrl_type *vfe32_ctrl,
-	uint32_t statsNum, uint32_t newAddr)
-{
-	uint32_t pingpongStatus;
-	uint32_t returnAddr;
-	uint32_t pingpongAddr;
-
-	/* must be 0=ping, 1=pong */
-	pingpongStatus =
-		((msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
-		VFE_BUS_PING_PONG_STATUS))
-	& ((uint32_t)(1<<(statsNum + 7)))) >> (statsNum + 7);
-	/* stats bits starts at 7 */
-	CDBG("statsNum %d, pingpongStatus %d\n", statsNum, pingpongStatus);
-	pingpongAddr =
-		((uint32_t)(vfe32_ctrl->share_ctrl->vfebase +
-				VFE_BUS_STATS_PING_PONG_BASE)) +
-				(3*statsNum)*4 + (1-pingpongStatus)*4;
-	returnAddr = msm_camera_io_r((uint32_t *)pingpongAddr);
-	msm_camera_io_w(newAddr, (uint32_t *)pingpongAddr);
-	return returnAddr;
-}
-
-static void vfe_send_stats_msg(
-	struct vfe32_ctrl_type *vfe32_ctrl,
-	uint32_t bufAddress, uint32_t statsNum)
-{
-	int rc = 0;
-	void *vaddr = NULL;
-	/* fill message with right content. */
-	/* @todo This is causing issues, need further investigate */
-	/* spin_lock_irqsave(&ctrl->state_lock, flags); */
-	struct isp_msg_stats msgStats;
-	uint32_t stats_type;
-	msgStats.frameCounter = vfe32_ctrl->share_ctrl->vfeFrameId;
-	if (vfe32_ctrl->simultaneous_sof_stat)
-		msgStats.frameCounter--;
-	msgStats.buffer = bufAddress;
-	switch (statsNum) {
-	case statsAeNum:{
-		msgStats.id =
-			(!vfe32_use_bayer_stats(vfe32_ctrl)) ? MSG_ID_STATS_AEC
-				: MSG_ID_STATS_BG;
-		stats_type =
-			(!vfe32_use_bayer_stats(vfe32_ctrl)) ?
-				MSM_STATS_TYPE_AEC : MSM_STATS_TYPE_BG;
-		rc = vfe32_ctrl->stats_ops.dispatch(
-				vfe32_ctrl->stats_ops.stats_ctrl,
-				stats_type, bufAddress,
-				&msgStats.buf_idx, &vaddr, &msgStats.fd,
-				vfe32_ctrl->stats_ops.client);
-		}
-		break;
-	case statsAfNum:{
-		msgStats.id =
-			(!vfe32_use_bayer_stats(vfe32_ctrl)) ? MSG_ID_STATS_AF
-				: MSG_ID_STATS_BF;
-		stats_type =
-			(!vfe32_use_bayer_stats(vfe32_ctrl)) ? MSM_STATS_TYPE_AF
-				: MSM_STATS_TYPE_BF;
-		rc = vfe32_ctrl->stats_ops.dispatch(
-				vfe32_ctrl->stats_ops.stats_ctrl,
-				stats_type, bufAddress,
-				&msgStats.buf_idx, &vaddr, &msgStats.fd,
-				vfe32_ctrl->stats_ops.client);
-		}
-		break;
-	case statsAwbNum: {
-		msgStats.id = MSG_ID_STATS_AWB;
-		rc = vfe32_ctrl->stats_ops.dispatch(
-				vfe32_ctrl->stats_ops.stats_ctrl,
-				MSM_STATS_TYPE_AWB, bufAddress,
-				&msgStats.buf_idx, &vaddr, &msgStats.fd,
-				vfe32_ctrl->stats_ops.client);
-		}
-		break;
-
-	case statsIhistNum: {
-		msgStats.id = MSG_ID_STATS_IHIST;
-		rc = vfe32_ctrl->stats_ops.dispatch(
-				vfe32_ctrl->stats_ops.stats_ctrl,
-				MSM_STATS_TYPE_IHIST, bufAddress,
-				&msgStats.buf_idx, &vaddr, &msgStats.fd,
-				vfe32_ctrl->stats_ops.client);
-		}
-		break;
-	case statsRsNum: {
-		msgStats.id = MSG_ID_STATS_RS;
-		rc = vfe32_ctrl->stats_ops.dispatch(
-				vfe32_ctrl->stats_ops.stats_ctrl,
-				MSM_STATS_TYPE_RS, bufAddress,
-				&msgStats.buf_idx, &vaddr, &msgStats.fd,
-				vfe32_ctrl->stats_ops.client);
-		}
-		break;
-	case statsCsNum: {
-		msgStats.id = MSG_ID_STATS_CS;
-		rc = vfe32_ctrl->stats_ops.dispatch(
-				vfe32_ctrl->stats_ops.stats_ctrl,
-				MSM_STATS_TYPE_CS, bufAddress,
-				&msgStats.buf_idx, &vaddr, &msgStats.fd,
-				vfe32_ctrl->stats_ops.client);
-		}
-		break;
-	case statsSkinNum: {
-		msgStats.id = MSG_ID_STATS_BHIST;
-		rc = vfe32_ctrl->stats_ops.dispatch(
-				vfe32_ctrl->stats_ops.stats_ctrl,
-				MSM_STATS_TYPE_BHIST, bufAddress,
-				&msgStats.buf_idx, &vaddr, &msgStats.fd,
-				vfe32_ctrl->stats_ops.client);
-		}
-		break;
-
-	default:
-		goto stats_done;
-	}
-	if (rc == 0) {
-		msgStats.buffer = (uint32_t)vaddr;
-		v4l2_subdev_notify(&vfe32_ctrl->subdev,
-			NOTIFY_VFE_MSG_STATS,
-			&msgStats);
-	} else {
-		pr_err("%s: paddr to idx mapping error, stats_id = %d, paddr = 0x%d",
-			 __func__, msgStats.id, msgStats.buffer);
-	}
-stats_done:
-	/* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
-	return;
-}
-
-static void vfe_send_comp_stats_msg(
-	struct vfe32_ctrl_type *vfe32_ctrl, uint32_t status_bits)
-{
-	struct msm_stats_buf msgStats;
-	uint32_t temp;
-
-	msgStats.frame_id = vfe32_ctrl->share_ctrl->vfeFrameId;
-	if (vfe32_ctrl->simultaneous_sof_stat)
-		msgStats.frame_id--;
-
-	msgStats.status_bits = status_bits;
-
-	msgStats.aec.buff = vfe32_ctrl->aecbgStatsControl.bufToRender;
-	msgStats.awb.buff = vfe32_ctrl->awbStatsControl.bufToRender;
-	msgStats.af.buff = vfe32_ctrl->afbfStatsControl.bufToRender;
-
-	msgStats.ihist.buff = vfe32_ctrl->ihistStatsControl.bufToRender;
-	msgStats.rs.buff = vfe32_ctrl->rsStatsControl.bufToRender;
-	msgStats.cs.buff = vfe32_ctrl->csStatsControl.bufToRender;
-
-	temp = msm_camera_io_r(
-		vfe32_ctrl->share_ctrl->vfebase + VFE_STATS_AWB_SGW_CFG);
-	msgStats.awb_ymin = (0xFF00 & temp) >> 8;
-
-	v4l2_subdev_notify(&vfe32_ctrl->subdev,
-				NOTIFY_VFE_MSG_COMP_STATS,
-				&msgStats);
-}
-
-static void vfe32_process_stats_ae_bg_irq(struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	unsigned long flags;
-	uint32_t addr;
-	uint32_t stats_type;
-	stats_type =
-		(!vfe32_use_bayer_stats(vfe32_ctrl)) ? MSM_STATS_TYPE_AEC
-			: MSM_STATS_TYPE_BG;
-	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, stats_type);
-	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
-	if (addr) {
-		vfe32_ctrl->aecbgStatsControl.bufToRender =
-			vfe32_process_stats_irq_common(vfe32_ctrl, statsAeNum,
-			addr);
-
-		vfe_send_stats_msg(vfe32_ctrl,
-			vfe32_ctrl->aecbgStatsControl.bufToRender, statsAeNum);
-	} else{
-		vfe32_ctrl->aecbgStatsControl.droppedStatsFrameCount++;
-		CDBG("%s: droppedStatsFrameCount = %d", __func__,
-			vfe32_ctrl->aecbgStatsControl.droppedStatsFrameCount);
-	}
-}
-
-static void vfe32_process_stats_awb_irq(struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	unsigned long flags;
-	uint32_t addr;
-	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_AWB);
-	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
-	if (addr) {
-		vfe32_ctrl->awbStatsControl.bufToRender =
-			vfe32_process_stats_irq_common(vfe32_ctrl, statsAwbNum,
-			addr);
-
-		vfe_send_stats_msg(vfe32_ctrl,
-			vfe32_ctrl->awbStatsControl.bufToRender, statsAwbNum);
-	} else{
-		vfe32_ctrl->awbStatsControl.droppedStatsFrameCount++;
-		CDBG("%s: droppedStatsFrameCount = %d", __func__,
-			vfe32_ctrl->awbStatsControl.droppedStatsFrameCount);
-	}
-}
-
-static void vfe32_process_stats_af_bf_irq(struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	unsigned long flags;
-	uint32_t addr;
-	uint32_t stats_type;
-	stats_type =
-		(!vfe32_use_bayer_stats(vfe32_ctrl)) ? MSM_STATS_TYPE_AF
-			: MSM_STATS_TYPE_BF;
-	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, stats_type);
-	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
-	if (addr) {
-		vfe32_ctrl->afbfStatsControl.bufToRender =
-			vfe32_process_stats_irq_common(vfe32_ctrl, statsAfNum,
-			addr);
-
-		vfe_send_stats_msg(vfe32_ctrl,
-			vfe32_ctrl->afbfStatsControl.bufToRender, statsAfNum);
-	} else{
-		vfe32_ctrl->afbfStatsControl.droppedStatsFrameCount++;
-		CDBG("%s: droppedStatsFrameCount = %d", __func__,
-			vfe32_ctrl->afbfStatsControl.droppedStatsFrameCount);
-	}
-}
-
-static void vfe32_process_stats_bhist_irq(struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	unsigned long flags;
-	uint32_t addr;
-	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_BHIST);
-	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
-	if (addr) {
-		vfe32_ctrl->bhistStatsControl.bufToRender =
-			vfe32_process_stats_irq_common(vfe32_ctrl,
-				statsSkinNum, addr);
-
-		vfe_send_stats_msg(vfe32_ctrl,
-			vfe32_ctrl->bhistStatsControl.bufToRender,
-			statsSkinNum);
-	} else{
-		vfe32_ctrl->bhistStatsControl.droppedStatsFrameCount++;
-		CDBG("%s: droppedStatsFrameCount = %d", __func__,
-			vfe32_ctrl->bhistStatsControl.droppedStatsFrameCount);
-	}
-}
-
-static void vfe32_process_stats_ihist_irq(struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	unsigned long flags;
-	uint32_t addr;
-	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_IHIST);
-	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
-	if (addr) {
-		vfe32_ctrl->ihistStatsControl.bufToRender =
-			vfe32_process_stats_irq_common(
-			vfe32_ctrl, statsIhistNum, addr);
-
-		vfe_send_stats_msg(vfe32_ctrl,
-			vfe32_ctrl->ihistStatsControl.bufToRender,
-			statsIhistNum);
-	} else {
-		vfe32_ctrl->ihistStatsControl.droppedStatsFrameCount++;
-		CDBG("%s: droppedStatsFrameCount = %d", __func__,
-			vfe32_ctrl->ihistStatsControl.droppedStatsFrameCount);
-	}
-}
-
-static void vfe32_process_stats_rs_irq(struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	unsigned long flags;
-	uint32_t addr;
-	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_RS);
-	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
-	if (addr) {
-		vfe32_ctrl->rsStatsControl.bufToRender =
-			vfe32_process_stats_irq_common(vfe32_ctrl, statsRsNum,
-			addr);
-
-		vfe_send_stats_msg(vfe32_ctrl,
-			vfe32_ctrl->rsStatsControl.bufToRender, statsRsNum);
-	} else {
-		vfe32_ctrl->rsStatsControl.droppedStatsFrameCount++;
-		CDBG("%s: droppedStatsFrameCount = %d", __func__,
-			vfe32_ctrl->rsStatsControl.droppedStatsFrameCount);
-	}
-}
-
-static void vfe32_process_stats_cs_irq(struct vfe32_ctrl_type *vfe32_ctrl)
-{
-	unsigned long flags;
-	uint32_t addr;
-	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl, MSM_STATS_TYPE_CS);
-	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
-	if (addr) {
-		vfe32_ctrl->csStatsControl.bufToRender =
-			vfe32_process_stats_irq_common(vfe32_ctrl, statsCsNum,
-			addr);
-
-			vfe_send_stats_msg(vfe32_ctrl,
-				vfe32_ctrl->csStatsControl.bufToRender,
-				statsCsNum);
-	} else {
-		vfe32_ctrl->csStatsControl.droppedStatsFrameCount++;
-		CDBG("%s: droppedStatsFrameCount = %d", __func__,
-			vfe32_ctrl->csStatsControl.droppedStatsFrameCount);
-	}
-}
-
-static void vfe32_process_stats(struct vfe32_ctrl_type *vfe32_ctrl,
-	uint32_t status_bits)
-{
-	unsigned long flags;
-	int32_t process_stats = false;
-	uint32_t addr;
-	uint32_t stats_type;
-
-	CDBG("%s, stats = 0x%x\n", __func__, status_bits);
-	spin_lock_irqsave(&vfe32_ctrl->stats_bufq_lock, flags);
-	stats_type =
-		(!vfe32_use_bayer_stats(vfe32_ctrl)) ? MSM_STATS_TYPE_AEC
-			: MSM_STATS_TYPE_BG;
-
-	if (status_bits & VFE_IRQ_STATUS0_STATS_AEC_BG) {
-		addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl,
-				stats_type);
-		if (addr) {
-			vfe32_ctrl->aecbgStatsControl.bufToRender =
-				vfe32_process_stats_irq_common(
-				vfe32_ctrl, statsAeNum,	addr);
-			process_stats = true;
-		} else{
-			vfe32_ctrl->aecbgStatsControl.bufToRender = 0;
-			vfe32_ctrl->aecbgStatsControl.droppedStatsFrameCount++;
-		}
-	} else {
-		vfe32_ctrl->aecbgStatsControl.bufToRender = 0;
-	}
-
-	if (status_bits & VFE_IRQ_STATUS0_STATS_AWB) {
-		addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl,
-			MSM_STATS_TYPE_AWB);
-		if (addr) {
-			vfe32_ctrl->awbStatsControl.bufToRender =
-				vfe32_process_stats_irq_common(
-				vfe32_ctrl, statsAwbNum,
-				addr);
-			process_stats = true;
-		} else{
-			vfe32_ctrl->awbStatsControl.droppedStatsFrameCount++;
-			vfe32_ctrl->awbStatsControl.bufToRender = 0;
-		}
-	} else {
-		vfe32_ctrl->awbStatsControl.bufToRender = 0;
-	}
-
-	stats_type =
-		(!vfe32_use_bayer_stats(vfe32_ctrl)) ? MSM_STATS_TYPE_AF
-			: MSM_STATS_TYPE_BF;
-	if (status_bits & VFE_IRQ_STATUS0_STATS_AF_BF) {
-		addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl,
-					stats_type);
-		if (addr) {
-			vfe32_ctrl->afbfStatsControl.bufToRender =
-				vfe32_process_stats_irq_common(
-				vfe32_ctrl, statsAfNum,
-				addr);
-			process_stats = true;
-		} else {
-			vfe32_ctrl->afbfStatsControl.bufToRender = 0;
-			vfe32_ctrl->afbfStatsControl.droppedStatsFrameCount++;
-		}
-	} else {
-		vfe32_ctrl->afbfStatsControl.bufToRender = 0;
-	}
-
-	if (status_bits & VFE_IRQ_STATUS0_STATS_IHIST) {
-		addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl,
-					MSM_STATS_TYPE_IHIST);
-		if (addr) {
-			vfe32_ctrl->ihistStatsControl.bufToRender =
-				vfe32_process_stats_irq_common(
-				vfe32_ctrl, statsIhistNum,
-				addr);
-			process_stats = true;
-		} else {
-			vfe32_ctrl->ihistStatsControl.droppedStatsFrameCount++;
-			vfe32_ctrl->ihistStatsControl.bufToRender = 0;
-		}
-	} else {
-		vfe32_ctrl->ihistStatsControl.bufToRender = 0;
-	}
-
-	if (status_bits & VFE_IRQ_STATUS0_STATS_RS) {
-		addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl,
-					MSM_STATS_TYPE_RS);
-		if (addr) {
-			vfe32_ctrl->rsStatsControl.bufToRender =
-				vfe32_process_stats_irq_common(
-				vfe32_ctrl, statsRsNum,
-				addr);
-			process_stats = true;
-		} else {
-			vfe32_ctrl->rsStatsControl.droppedStatsFrameCount++;
-			vfe32_ctrl->rsStatsControl.bufToRender = 0;
-		}
-	} else {
-		vfe32_ctrl->rsStatsControl.bufToRender = 0;
-	}
-
-	if (status_bits & VFE_IRQ_STATUS0_STATS_CS) {
-		addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl,
-					MSM_STATS_TYPE_CS);
-		if (addr) {
-			vfe32_ctrl->csStatsControl.bufToRender =
-				vfe32_process_stats_irq_common(
-				vfe32_ctrl, statsCsNum,
-				addr);
-			process_stats = true;
-		} else {
-			vfe32_ctrl->csStatsControl.droppedStatsFrameCount++;
-			vfe32_ctrl->csStatsControl.bufToRender = 0;
-		}
-	} else {
-		vfe32_ctrl->csStatsControl.bufToRender = 0;
-	}
-	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
-	if (process_stats)
-		vfe_send_comp_stats_msg(vfe32_ctrl, status_bits);
-
-	return;
-}
-
-static void vfe32_process_stats_irq(
-	struct vfe32_ctrl_type *vfe32_ctrl, uint32_t irqstatus)
-{
-	uint32_t status_bits = VFE_COM_STATUS & irqstatus;
-	if ((vfe32_ctrl->hfr_mode != HFR_MODE_OFF) &&
-		(vfe32_ctrl->share_ctrl->vfeFrameId %
-		 vfe32_ctrl->hfr_mode != 0)) {
-		CDBG("Skip the stats when HFR enabled\n");
-		return;
-	}
-
-	vfe32_process_stats(vfe32_ctrl, status_bits);
-	return;
-}
-
-static void vfe32_process_irq(
-	struct vfe32_ctrl_type *vfe32_ctrl, uint32_t irqstatus)
-{
-	if (irqstatus &
-		VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK) {
-		vfe32_process_stats_irq(vfe32_ctrl, irqstatus);
-		return;
-	}
-
-	switch (irqstatus) {
-	case VFE_IRQ_STATUS0_CAMIF_SOF_MASK:
-		CDBG("irq	camifSofIrq\n");
-		vfe32_process_camif_sof_irq(vfe32_ctrl);
-		break;
-	case VFE_IRQ_STATUS0_REG_UPDATE_MASK:
-		CDBG("irq	regUpdateIrq\n");
-		vfe32_process_reg_update_irq(vfe32_ctrl);
-		break;
-	case VFE_IRQ_STATUS1_RDI0_REG_UPDATE:
-		CDBG("irq	rdi0 regUpdateIrq\n");
-		vfe32_process_rdi0_reg_update_irq(vfe32_ctrl);
-		break;
-	case VFE_IRQ_STATUS1_RDI1_REG_UPDATE:
-		CDBG("irq	rdi1 regUpdateIrq\n");
-		vfe32_process_rdi1_reg_update_irq(vfe32_ctrl);
-		break;
-	case VFE_IMASK_WHILE_STOPPING_1:
-		CDBG("irq	resetAckIrq\n");
-		vfe32_process_reset_irq(vfe32_ctrl);
-		break;
-	case VFE_IRQ_STATUS0_STATS_AEC_BG:
-		CDBG("Stats AEC irq occured.\n");
-		vfe32_process_stats_ae_bg_irq(vfe32_ctrl);
-		break;
-	case VFE_IRQ_STATUS0_STATS_AWB:
-		CDBG("Stats AWB irq occured.\n");
-		vfe32_process_stats_awb_irq(vfe32_ctrl);
-		break;
-	case VFE_IRQ_STATUS0_STATS_AF_BF:
-		CDBG("Stats AF irq occured.\n");
-		vfe32_process_stats_af_bf_irq(vfe32_ctrl);
-		break;
-	case VFE_IRQ_STATUS0_STATS_SK_BHIST:
-		CDBG("Stats BHIST irq occured.\n");
-		vfe32_process_stats_bhist_irq(vfe32_ctrl);
-		break;
-	case VFE_IRQ_STATUS0_STATS_IHIST:
-		CDBG("Stats IHIST irq occured.\n");
-		vfe32_process_stats_ihist_irq(vfe32_ctrl);
-		break;
-	case VFE_IRQ_STATUS0_STATS_RS:
-		CDBG("Stats RS irq occured.\n");
-		vfe32_process_stats_rs_irq(vfe32_ctrl);
-		break;
-	case VFE_IRQ_STATUS0_STATS_CS:
-		CDBG("Stats CS irq occured.\n");
-		vfe32_process_stats_cs_irq(vfe32_ctrl);
-		break;
-	case VFE_IRQ_STATUS0_SYNC_TIMER0:
-		CDBG("SYNC_TIMER 0 irq occured.\n");
-		vfe32_send_isp_msg(&vfe32_ctrl->subdev,
-			vfe32_ctrl->share_ctrl->vfeFrameId,
-			MSG_ID_SYNC_TIMER0_DONE);
-		break;
-	case VFE_IRQ_STATUS0_SYNC_TIMER1:
-		CDBG("SYNC_TIMER 1 irq occured.\n");
-		vfe32_send_isp_msg(&vfe32_ctrl->subdev,
-			vfe32_ctrl->share_ctrl->vfeFrameId,
-			MSG_ID_SYNC_TIMER1_DONE);
-		break;
-	case VFE_IRQ_STATUS0_SYNC_TIMER2:
-		CDBG("SYNC_TIMER 2 irq occured.\n");
-		vfe32_send_isp_msg(&vfe32_ctrl->subdev,
-			vfe32_ctrl->share_ctrl->vfeFrameId,
-			MSG_ID_SYNC_TIMER2_DONE);
-		break;
-	default:
-		pr_err("Invalid IRQ status\n");
-	}
-}
-
-static void axi32_do_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	struct axi_ctrl_t *axi_ctrl = (struct axi_ctrl_t *)data;
-	struct vfe32_ctrl_type *vfe32_ctrl = axi_ctrl->share_ctrl->vfe32_ctrl;
-	struct vfe32_isr_queue_cmd *qcmd = NULL;
-	int stat_interrupt;
-
-	CDBG("=== axi32_do_tasklet start ===\n");
-
-	while (atomic_read(&irq_cnt)) {
-		spin_lock_irqsave(&axi_ctrl->tasklet_lock, flags);
-		qcmd = list_first_entry(&axi_ctrl->tasklet_q,
-			struct vfe32_isr_queue_cmd, list);
-		atomic_sub(1, &irq_cnt);
-
-		if (!qcmd) {
-			spin_unlock_irqrestore(&axi_ctrl->tasklet_lock,
-				flags);
-			return;
-		}
-
-		list_del(&qcmd->list);
-		spin_unlock_irqrestore(&axi_ctrl->tasklet_lock,
-			flags);
-
-		if (axi_ctrl->share_ctrl->stats_comp) {
-			stat_interrupt = (qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK);
-		} else {
-			stat_interrupt =
-				(qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_STATS_AEC_BG) |
-				(qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_STATS_AWB) |
-				(qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_STATS_AF_BF) |
-				(qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_STATS_IHIST) |
-				(qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_STATS_RS) |
-				(qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_STATS_CS);
-		}
-		if (qcmd->vfeInterruptStatus0 &
-				VFE_IRQ_STATUS0_CAMIF_SOF_MASK) {
-			if (stat_interrupt)
-				vfe32_ctrl->simultaneous_sof_stat = 1;
-			v4l2_subdev_notify(&vfe32_ctrl->subdev,
-				NOTIFY_VFE_IRQ,
-				(void *)VFE_IRQ_STATUS0_CAMIF_SOF_MASK);
-		}
-
-		/* interrupt to be processed,  *qcmd has the payload.  */
-		if (qcmd->vfeInterruptStatus0 &
-				VFE_IRQ_STATUS0_REG_UPDATE_MASK)
-			v4l2_subdev_notify(&vfe32_ctrl->subdev,
-				NOTIFY_VFE_IRQ,
-				(void *)VFE_IRQ_STATUS0_REG_UPDATE_MASK);
-
-		if (qcmd->vfeInterruptStatus1 &
-				VFE_IRQ_STATUS1_RDI0_REG_UPDATE_MASK)
-			v4l2_subdev_notify(&vfe32_ctrl->subdev,
-				NOTIFY_VFE_IRQ,
-				(void *)VFE_IRQ_STATUS1_RDI0_REG_UPDATE);
-
-		if (qcmd->vfeInterruptStatus1 &
-				VFE_IRQ_STATUS1_RDI1_REG_UPDATE_MASK)
-			v4l2_subdev_notify(&vfe32_ctrl->subdev,
-				NOTIFY_VFE_IRQ,
-				(void *)VFE_IRQ_STATUS1_RDI1_REG_UPDATE);
-
-		if (qcmd->vfeInterruptStatus1 &
-				VFE_IMASK_WHILE_STOPPING_1)
-			v4l2_subdev_notify(&vfe32_ctrl->subdev,
-				NOTIFY_VFE_IRQ,
-				(void *)VFE_IMASK_WHILE_STOPPING_1);
-
-		if (atomic_read(&axi_ctrl->share_ctrl->handle_common_irq)) {
-			if (qcmd->vfeInterruptStatus1 &
-					VFE32_IMASK_COMMON_ERROR_ONLY_1) {
-				pr_err("irq	errorIrq\n");
-				vfe32_process_common_error_irq(
-					axi_ctrl,
-					qcmd->vfeInterruptStatus1 &
-					VFE32_IMASK_COMMON_ERROR_ONLY_1);
-			}
-
-			v4l2_subdev_notify(&axi_ctrl->subdev,
-				NOTIFY_AXI_IRQ,
-				(void *)qcmd->vfeInterruptStatus0);
-		}
-
-		if (atomic_read(&axi_ctrl->share_ctrl->vstate)) {
-			if (qcmd->vfeInterruptStatus1 &
-					VFE32_IMASK_VFE_ERROR_ONLY_1) {
-				pr_err("irq	errorIrq\n");
-				vfe32_process_error_irq(
-					axi_ctrl,
-					qcmd->vfeInterruptStatus1 &
-					VFE32_IMASK_VFE_ERROR_ONLY_1);
-			}
-
-			/* then process stats irq. */
-			if (axi_ctrl->share_ctrl->stats_comp) {
-				/* process stats comb interrupt. */
-				if (qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK) {
-					CDBG("Stats composite irq occured.\n");
-					v4l2_subdev_notify(&vfe32_ctrl->subdev,
-					NOTIFY_VFE_IRQ,
-					(void *)qcmd->vfeInterruptStatus0);
-				}
-			} else {
-				/* process individual stats interrupt. */
-				if (qcmd->vfeInterruptStatus0 &
-						VFE_IRQ_STATUS0_STATS_AEC_BG)
-					v4l2_subdev_notify(&vfe32_ctrl->subdev,
-					NOTIFY_VFE_IRQ,
-					(void *)VFE_IRQ_STATUS0_STATS_AEC_BG);
-
-				if (qcmd->vfeInterruptStatus0 &
-						VFE_IRQ_STATUS0_STATS_AWB)
-					v4l2_subdev_notify(&vfe32_ctrl->subdev,
-					NOTIFY_VFE_IRQ,
-					(void *)VFE_IRQ_STATUS0_STATS_AWB);
-
-				if (qcmd->vfeInterruptStatus0 &
-						VFE_IRQ_STATUS0_STATS_AF_BF)
-					v4l2_subdev_notify(&vfe32_ctrl->subdev,
-					NOTIFY_VFE_IRQ,
-					(void *)VFE_IRQ_STATUS0_STATS_AF_BF);
-				if (qcmd->vfeInterruptStatus0 &
-						VFE_IRQ_STATUS0_STATS_SK_BHIST)
-					v4l2_subdev_notify(&vfe32_ctrl->subdev,
-					NOTIFY_VFE_IRQ,
-					(void *)VFE_IRQ_STATUS0_STATS_SK_BHIST);
-
-				if (qcmd->vfeInterruptStatus0 &
-						VFE_IRQ_STATUS0_STATS_IHIST)
-					v4l2_subdev_notify(&vfe32_ctrl->subdev,
-					NOTIFY_VFE_IRQ,
-					(void *)VFE_IRQ_STATUS0_STATS_IHIST);
-
-				if (qcmd->vfeInterruptStatus0 &
-						VFE_IRQ_STATUS0_STATS_RS)
-					v4l2_subdev_notify(&vfe32_ctrl->subdev,
-					NOTIFY_VFE_IRQ,
-					(void *)VFE_IRQ_STATUS0_STATS_RS);
-
-				if (qcmd->vfeInterruptStatus0 &
-						VFE_IRQ_STATUS0_STATS_CS)
-					v4l2_subdev_notify(&vfe32_ctrl->subdev,
-					NOTIFY_VFE_IRQ,
-					(void *)VFE_IRQ_STATUS0_STATS_CS);
-
-				if (qcmd->vfeInterruptStatus0 &
-						VFE_IRQ_STATUS0_SYNC_TIMER0)
-					v4l2_subdev_notify(&vfe32_ctrl->subdev,
-					NOTIFY_VFE_IRQ,
-					(void *)VFE_IRQ_STATUS0_SYNC_TIMER0);
-
-				if (qcmd->vfeInterruptStatus0 &
-						VFE_IRQ_STATUS0_SYNC_TIMER1)
-					v4l2_subdev_notify(&vfe32_ctrl->subdev,
-					NOTIFY_VFE_IRQ,
-					(void *)VFE_IRQ_STATUS0_SYNC_TIMER1);
-
-				if (qcmd->vfeInterruptStatus0 &
-						VFE_IRQ_STATUS0_SYNC_TIMER2)
-					v4l2_subdev_notify(&vfe32_ctrl->subdev,
-					NOTIFY_VFE_IRQ,
-					(void *)VFE_IRQ_STATUS0_SYNC_TIMER2);
-			}
-		}
-		vfe32_ctrl->simultaneous_sof_stat = 0;
-		kfree(qcmd);
-	}
-	CDBG("=== axi32_do_tasklet end ===\n");
-}
-
-static irqreturn_t vfe32_parse_irq(int irq_num, void *data)
-{
-	unsigned long flags;
-	struct vfe32_irq_status irq;
-	struct vfe32_isr_queue_cmd *qcmd;
-	struct axi_ctrl_t *axi_ctrl = data;
-
-	CDBG("vfe_parse_irq\n");
-
-	vfe32_read_irq_status(axi_ctrl, &irq);
-
-	if ((irq.vfeIrqStatus0 == 0) && (irq.vfeIrqStatus1 == 0)) {
-		CDBG("vfe_parse_irq: vfeIrqStatus0 & 1 are both 0!\n");
-		return IRQ_HANDLED;
-	}
-
-	qcmd = kzalloc(sizeof(struct vfe32_isr_queue_cmd),
-		GFP_ATOMIC);
-	if (!qcmd) {
-		pr_err("vfe_parse_irq: qcmd malloc failed!\n");
-		return IRQ_HANDLED;
-	}
-
-	spin_lock_irqsave(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
-	if (axi_ctrl->share_ctrl->stop_ack_pending) {
-		irq.vfeIrqStatus0 &= VFE_IMASK_WHILE_STOPPING_0;
-		irq.vfeIrqStatus1 &= VFE_IMASK_WHILE_STOPPING_1;
-	}
-	spin_unlock_irqrestore(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
-
-	CDBG("vfe_parse_irq: Irq_status0 = 0x%x, Irq_status1 = 0x%x.\n",
-		irq.vfeIrqStatus0, irq.vfeIrqStatus1);
-
-	qcmd->vfeInterruptStatus0 = irq.vfeIrqStatus0;
-	qcmd->vfeInterruptStatus1 = irq.vfeIrqStatus1;
-
-	spin_lock_irqsave(&axi_ctrl->tasklet_lock, flags);
-	list_add_tail(&qcmd->list, &axi_ctrl->tasklet_q);
-
-	atomic_add(1, &irq_cnt);
-	spin_unlock_irqrestore(&axi_ctrl->tasklet_lock, flags);
-	tasklet_schedule(&axi_ctrl->vfe32_tasklet);
-	return IRQ_HANDLED;
-}
-
-int msm_axi_subdev_isr_routine(struct v4l2_subdev *sd,
-	u32 status, bool *handled)
-{
-	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
-	irqreturn_t ret;
-	pr_info("%s E ", __func__);
-	ret = vfe32_parse_irq(axi_ctrl->vfeirq->start, axi_ctrl);
-	*handled = TRUE;
-	return 0;
-}
-
-static long vfe_stats_bufq_sub_ioctl(
-	struct vfe32_ctrl_type *vfe_ctrl,
-	struct msm_vfe_cfg_cmd *cmd, void *ion_client, int domain_num)
-{
-	long rc = 0;
-	switch (cmd->cmd_type) {
-	case VFE_CMD_STATS_REQBUF:
-	if (!vfe_ctrl->stats_ops.stats_ctrl) {
-		/* stats_ctrl has not been init yet */
-		rc = msm_stats_buf_ops_init(&vfe_ctrl->stats_ctrl,
-				(struct ion_client *)ion_client,
-				&vfe_ctrl->stats_ops);
-		if (rc < 0) {
-			pr_err("%s: cannot init stats ops", __func__);
-			goto end;
-		}
-		rc = vfe_ctrl->stats_ops.stats_ctrl_init(&vfe_ctrl->stats_ctrl);
-		if (rc < 0) {
-			pr_err("%s: cannot init stats_ctrl ops", __func__);
-			memset(&vfe_ctrl->stats_ops, 0,
-				sizeof(vfe_ctrl->stats_ops));
-			goto end;
-		}
-		if (sizeof(struct msm_stats_reqbuf) != cmd->length) {
-			/* error. the length not match */
-			pr_err("%s: stats reqbuf input size = %d,\n"
-				"struct size = %d, mitch match\n",
-				 __func__, cmd->length,
-				sizeof(struct msm_stats_reqbuf));
-			rc = -EINVAL ;
-			goto end;
-		}
-	}
-	rc = vfe_ctrl->stats_ops.reqbuf(
-			&vfe_ctrl->stats_ctrl,
-			(struct msm_stats_reqbuf *)cmd->value,
-			vfe_ctrl->stats_ops.client);
-	break;
-	case VFE_CMD_STATS_ENQUEUEBUF:
-	if (sizeof(struct msm_stats_buf_info) != cmd->length) {
-		/* error. the length not match */
-		pr_err("%s: stats enqueuebuf input size = %d,\n"
-			"struct size = %d, mitch match\n",
-			 __func__, cmd->length,
-			sizeof(struct msm_stats_buf_info));
-			rc = -EINVAL;
-			goto end;
-	}
-	rc = vfe_ctrl->stats_ops.enqueue_buf(
-			&vfe_ctrl->stats_ctrl,
-			(struct msm_stats_buf_info *)cmd->value,
-			vfe_ctrl->stats_ops.client, domain_num);
-	break;
-	case VFE_CMD_STATS_FLUSH_BUFQ:
-	{
-		struct msm_stats_flush_bufq *flush_req = NULL;
-		flush_req = (struct msm_stats_flush_bufq *)cmd->value;
-		if (sizeof(struct msm_stats_flush_bufq) != cmd->length) {
-			/* error. the length not match */
-			pr_err("%s: stats flush queue input size = %d,\n"
-				"struct size = %d, mitch match\n",
-				__func__, cmd->length,
-				sizeof(struct msm_stats_flush_bufq));
-			rc = -EINVAL;
-			goto end;
-	}
-	rc = vfe_ctrl->stats_ops.bufq_flush(
-			&vfe_ctrl->stats_ctrl,
-			(enum msm_stats_enum_type)flush_req->stats_type,
-			vfe_ctrl->stats_ops.client);
-	}
-	break;
-	case VFE_CMD_STATS_UNREGBUF:
-	{
-		struct msm_stats_reqbuf *req_buf = NULL;
-		req_buf = (struct msm_stats_reqbuf *)cmd->value;
-		if (sizeof(struct msm_stats_reqbuf) != cmd->length) {
-			/* error. the length not match */
-			pr_err("%s: stats reqbuf input size = %d,\n"
-				"struct size = %d, mitch match\n",
-				 __func__, cmd->length,
-				sizeof(struct msm_stats_reqbuf));
-			rc = -EINVAL ;
-			goto end;
-		}
-		rc = vfe32_stats_unregbuf(vfe_ctrl, req_buf, domain_num);
-	}
-	break;
-	default:
-		rc = -1;
-		pr_err("%s: cmd_type %d not supported", __func__,
-			cmd->cmd_type);
-	break;
-	}
-end:
-	return rc;
-}
-
-static long msm_vfe_subdev_ioctl(struct v4l2_subdev *sd,
-			unsigned int subdev_cmd, void *arg)
-{
-	struct msm_cam_media_controller *pmctl =
-		(struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
-	struct vfe32_ctrl_type *vfe32_ctrl =
-		(struct vfe32_ctrl_type *)v4l2_get_subdevdata(sd);
-	struct msm_isp_cmd vfecmd;
-	struct msm_camvfe_params *vfe_params;
-	struct msm_vfe_cfg_cmd *cmd;
-	void *data;
-
-	long rc = 0;
-	struct vfe_cmd_stats_buf *scfg = NULL;
-	struct vfe_cmd_stats_ack *sack = NULL;
-
-	if (!vfe32_ctrl->share_ctrl->vfebase) {
-		pr_err("%s: base address unmapped\n", __func__);
-		return -EFAULT;
-	}
-
-	CDBG("%s\n", __func__);
-	if (subdev_cmd == VIDIOC_MSM_VFE_INIT) {
-		CDBG("%s init\n", __func__);
-		return msm_vfe_subdev_init(sd);
-	} else if (subdev_cmd == VIDIOC_MSM_VFE_RELEASE) {
-		msm_vfe_subdev_release(sd);
-		return 0;
-	}
-	vfe_params = (struct msm_camvfe_params *)arg;
-	cmd = vfe_params->vfe_cfg;
-	data = vfe_params->data;
-	switch (cmd->cmd_type) {
-	case CMD_VFE_PROCESS_IRQ:
-		vfe32_process_irq(vfe32_ctrl, (uint32_t) data);
-		return rc;
-	case VFE_CMD_STATS_REQBUF:
-	case VFE_CMD_STATS_ENQUEUEBUF:
-	case VFE_CMD_STATS_FLUSH_BUFQ:
-	case VFE_CMD_STATS_UNREGBUF:
-		/* for easy porting put in one envelope */
-		rc = vfe_stats_bufq_sub_ioctl(vfe32_ctrl,
-				cmd, vfe_params->data, pmctl->domain_num);
-		return rc;
-	default:
-		if (cmd->cmd_type != CMD_CONFIG_PING_ADDR &&
-		cmd->cmd_type != CMD_CONFIG_PONG_ADDR &&
-		cmd->cmd_type != CMD_CONFIG_FREE_BUF_ADDR &&
-		cmd->cmd_type != CMD_STATS_AEC_BUF_RELEASE &&
-		cmd->cmd_type != CMD_STATS_AWB_BUF_RELEASE &&
-		cmd->cmd_type != CMD_STATS_IHIST_BUF_RELEASE &&
-		cmd->cmd_type != CMD_STATS_RS_BUF_RELEASE &&
-		cmd->cmd_type != CMD_STATS_CS_BUF_RELEASE &&
-		cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE &&
-		cmd->cmd_type != CMD_STATS_BG_BUF_RELEASE &&
-		cmd->cmd_type != CMD_STATS_BF_BUF_RELEASE &&
-		cmd->cmd_type != CMD_STATS_BHIST_BUF_RELEASE &&
-		cmd->cmd_type != CMD_VFE_PIX_SOF_COUNT_UPDATE &&
-		cmd->cmd_type != CMD_VFE_COUNT_PIX_SOF_ENABLE) {
-			if (copy_from_user(&vfecmd,
-					(void __user *)(cmd->value),
-					sizeof(vfecmd))) {
-				pr_err("%s %d: copy_from_user failed\n",
-					__func__, __LINE__);
-				return -EFAULT;
-			}
-		} else {
-			/* here eith stats release or frame release. */
-			if (cmd->cmd_type != CMD_CONFIG_PING_ADDR &&
-				cmd->cmd_type != CMD_CONFIG_PONG_ADDR &&
-				cmd->cmd_type != CMD_CONFIG_FREE_BUF_ADDR) {
-				/* then must be stats release. */
-				if (!data) {
-					pr_err("%s: data = NULL, cmd->cmd_type = %d",
-						__func__, cmd->cmd_type);
-					return -EFAULT;
-				}
-				sack = kmalloc(sizeof(struct vfe_cmd_stats_ack),
-							GFP_ATOMIC);
-				if (!sack) {
-					pr_err("%s: no mem for cmd->cmd_type = %d",
-					 __func__, cmd->cmd_type);
-					return -ENOMEM;
-				}
-				sack->nextStatsBuf = *(uint32_t *)data;
-			}
-		}
-	}
-
-	CDBG("%s: cmdType = %d\n", __func__, cmd->cmd_type);
-
-	if ((cmd->cmd_type == CMD_STATS_AF_ENABLE)    ||
-		(cmd->cmd_type == CMD_STATS_AWB_ENABLE)   ||
-		(cmd->cmd_type == CMD_STATS_IHIST_ENABLE) ||
-		(cmd->cmd_type == CMD_STATS_RS_ENABLE)    ||
-		(cmd->cmd_type == CMD_STATS_CS_ENABLE)    ||
-		(cmd->cmd_type == CMD_STATS_AEC_ENABLE)   ||
-		(cmd->cmd_type == CMD_STATS_BG_ENABLE)    ||
-		(cmd->cmd_type == CMD_STATS_BF_ENABLE)    ||
-		(cmd->cmd_type == CMD_STATS_BHIST_ENABLE)) {
-		struct axidata *axid;
-		axid = data;
-		if (!axid) {
-			rc = -EFAULT;
-			goto vfe32_config_done;
-		}
-		CDBG("%s: cmdType = %d\n", __func__, cmd->cmd_type);
-
-		if ((cmd->cmd_type == CMD_STATS_AF_ENABLE)    ||
-			(cmd->cmd_type == CMD_STATS_AWB_ENABLE)   ||
-			(cmd->cmd_type == CMD_STATS_IHIST_ENABLE) ||
-			(cmd->cmd_type == CMD_STATS_RS_ENABLE)    ||
-			(cmd->cmd_type == CMD_STATS_CS_ENABLE)    ||
-			(cmd->cmd_type == CMD_STATS_AEC_ENABLE)) {
-				scfg = NULL;
-				/* individual */
-				goto vfe32_config_done;
-		}
-		switch (cmd->cmd_type) {
-		case CMD_STATS_AEC_ENABLE:
-		case CMD_STATS_BG_ENABLE:
-		case CMD_STATS_BF_ENABLE:
-		case CMD_STATS_BHIST_ENABLE:
-		case CMD_STATS_AWB_ENABLE:
-		case CMD_STATS_IHIST_ENABLE:
-		case CMD_STATS_RS_ENABLE:
-		case CMD_STATS_CS_ENABLE:
-		default:
-			pr_err("%s Unsupported cmd type %d",
-				__func__, cmd->cmd_type);
-			break;
-		}
-		goto vfe32_config_done;
-	}
-	switch (cmd->cmd_type) {
-	case CMD_GENERAL:
-		rc = vfe32_proc_general(pmctl, &vfecmd, vfe32_ctrl);
-	break;
-	case CMD_VFE_COUNT_PIX_SOF_ENABLE: {
-		int enable = *((int *)cmd->value);
-		if (enable)
-			vfe32_ctrl->vfe_sof_count_enable = TRUE;
-		else
-			vfe32_ctrl->vfe_sof_count_enable = false;
-	}
-	break;
-	case CMD_VFE_PIX_SOF_COUNT_UPDATE:
-		if (!vfe32_ctrl->vfe_sof_count_enable)
-			vfe32_ctrl->share_ctrl->vfeFrameId =
-			*((uint32_t *)vfe_params->data);
-	break;
-	case CMD_CONFIG_PING_ADDR: {
-		int path = *((int *)cmd->value);
-		struct vfe32_output_ch *outch =
-			vfe32_get_ch(path, vfe32_ctrl->share_ctrl);
-		outch->ping = *((struct msm_free_buf *)data);
-	}
-	break;
-
-	case CMD_CONFIG_PONG_ADDR: {
-		int path = *((int *)cmd->value);
-		struct vfe32_output_ch *outch =
-			vfe32_get_ch(path, vfe32_ctrl->share_ctrl);
-		outch->pong = *((struct msm_free_buf *)data);
-	}
-	break;
-
-	case CMD_CONFIG_FREE_BUF_ADDR: {
-		int path = *((int *)cmd->value);
-		struct vfe32_output_ch *outch =
-			vfe32_get_ch(path, vfe32_ctrl->share_ctrl);
-		outch->free_buf = *((struct msm_free_buf *)data);
-	}
-	break;
-
-	case CMD_SNAP_BUF_RELEASE:
-		break;
-
-	default:
-		pr_err("%s Unsupported AXI configuration %x ", __func__,
-			cmd->cmd_type);
-	break;
-	}
-vfe32_config_done:
-	kfree(scfg);
-	kfree(sack);
-	CDBG("%s done: rc = %d\n", __func__, (int) rc);
-	return rc;
-}
-
-static struct msm_cam_clk_info vfe32_clk_info[] = {
-	{"vfe_clk", 228570000},
-	{"vfe_pclk", -1},
-	{"csi_vfe_clk", -1},
-};
-
-static int msm_axi_subdev_s_crystal_freq(struct v4l2_subdev *sd,
-						u32 freq, u32 flags)
-{
-	int rc = 0;
-	int round_rate;
-	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
-
-	if (axi_ctrl->share_ctrl->dual_enabled)
-		return rc;
-
-	round_rate = clk_round_rate(axi_ctrl->vfe_clk[0], freq);
-	if (rc < 0) {
-		pr_err("%s: clk_round_rate failed %d\n",
-					__func__, rc);
-		return rc;
-	}
-
-	vfe_clk_rate = round_rate;
-	rc = clk_set_rate(axi_ctrl->vfe_clk[0], round_rate);
-	if (rc < 0)
-		pr_err("%s: clk_set_rate failed %d\n",
-					__func__, rc);
-
-	return rc;
-}
-
-static const struct v4l2_subdev_core_ops msm_vfe_subdev_core_ops = {
-	.ioctl = msm_vfe_subdev_ioctl,
-};
-
-static const struct v4l2_subdev_ops msm_vfe_subdev_ops = {
-	.core = &msm_vfe_subdev_core_ops,
-};
-
-int msm_axi_subdev_init(struct v4l2_subdev *sd,
-	uint8_t dual_enabled)
-{
-	int rc = 0;
-	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
-	struct msm_cam_media_controller *mctl =
-		v4l2_get_subdev_hostdata(sd);
-	if (mctl == NULL) {
-		rc = -EINVAL;
-		goto mctl_failed;
-	}
-
-	axi_ctrl->share_ctrl->axi_ref_cnt++;
-	if (axi_ctrl->share_ctrl->axi_ref_cnt > 1)
-		return rc;
-	axi_ctrl->share_ctrl->dual_enabled = dual_enabled;
-	spin_lock_init(&axi_ctrl->tasklet_lock);
-	INIT_LIST_HEAD(&axi_ctrl->tasklet_q);
-	spin_lock_init(&axi_ctrl->share_ctrl->sd_notify_lock);
-
-	axi_ctrl->share_ctrl->vfebase = ioremap(axi_ctrl->vfemem->start,
-		resource_size(axi_ctrl->vfemem));
-	if (!axi_ctrl->share_ctrl->vfebase) {
-		rc = -ENOMEM;
-		pr_err("%s: vfe ioremap failed\n", __func__);
-		goto remap_failed;
-	}
-
-	if (axi_ctrl->fs_vfe) {
-		rc = regulator_enable(axi_ctrl->fs_vfe);
-		if (rc) {
-			pr_err("%s: Regulator enable failed\n",	__func__);
-			goto fs_failed;
-		}
-	}
-
-	rc = msm_cam_clk_enable(&axi_ctrl->pdev->dev, vfe32_clk_info,
-			axi_ctrl->vfe_clk, ARRAY_SIZE(vfe32_clk_info), 1);
-	if (rc < 0)
-		goto clk_enable_failed;
-
-#ifdef CONFIG_MSM_IOMMU
-	rc = iommu_attach_device(mctl->domain, axi_ctrl->iommu_ctx_imgwr);
-	if (rc < 0) {
-		pr_err("%s: imgwr attach failed rc = %d\n", __func__, rc);
-		rc = -ENODEV;
-		goto device_imgwr_attach_failed;
-	}
-	rc = iommu_attach_device(mctl->domain, axi_ctrl->iommu_ctx_misc);
-	if (rc < 0) {
-		pr_err("%s: misc attach failed rc = %d\n", __func__, rc);
-		rc = -ENODEV;
-		goto device_misc_attach_failed;
-	}
-#endif
-
-	msm_camio_bus_scale_cfg(
-		mctl->sdata->pdata->cam_bus_scale_table, S_INIT);
-
-	if (axi_ctrl->share_ctrl->dual_enabled)
-		msm_camio_bus_scale_cfg(
-			mctl->sdata->pdata->cam_bus_scale_table, S_DUAL);
-	else
-		msm_camio_bus_scale_cfg(
-			mctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
-
-	if (msm_camera_io_r(
-		axi_ctrl->share_ctrl->vfebase + V32_GET_HW_VERSION_OFF) ==
-		VFE32_HW_NUMBER)
-		axi_ctrl->share_ctrl->register_total = VFE32_REGISTER_TOTAL;
-	else
-		axi_ctrl->share_ctrl->register_total = VFE33_REGISTER_TOTAL;
-
-	spin_lock_init(&axi_ctrl->share_ctrl->stop_flag_lock);
-	spin_lock_init(&axi_ctrl->share_ctrl->update_ack_lock);
-	spin_lock_init(&axi_ctrl->share_ctrl->start_ack_lock);
-
-	enable_irq(axi_ctrl->vfeirq->start);
-
-	return rc;
-
-#ifdef CONFIG_MSM_IOMMU
-device_misc_attach_failed:
-	iommu_detach_device(mctl->domain, axi_ctrl->iommu_ctx_imgwr);
-device_imgwr_attach_failed:
-#endif
-	msm_cam_clk_enable(&axi_ctrl->pdev->dev, vfe32_clk_info,
-			axi_ctrl->vfe_clk, ARRAY_SIZE(vfe32_clk_info), 0);
-clk_enable_failed:
-	if (axi_ctrl->fs_vfe)
-		regulator_disable(axi_ctrl->fs_vfe);
-fs_failed:
-	iounmap(axi_ctrl->share_ctrl->vfebase);
-	axi_ctrl->share_ctrl->vfebase = NULL;
-remap_failed:
-mctl_failed:
-	return rc;
-}
-
-int msm_vfe_subdev_init(struct v4l2_subdev *sd)
-{
-	int rc = 0;
-	struct vfe32_ctrl_type *vfe32_ctrl =
-		(struct vfe32_ctrl_type *)v4l2_get_subdevdata(sd);
-
-	spin_lock_init(&vfe32_ctrl->state_lock);
-	spin_lock_init(&vfe32_ctrl->stats_bufq_lock);
-
-	vfe32_ctrl->update_linear = false;
-	vfe32_ctrl->update_rolloff = false;
-	vfe32_ctrl->update_la = false;
-	vfe32_ctrl->update_gamma = false;
-	vfe32_ctrl->vfe_sof_count_enable = false;
-	vfe32_ctrl->hfr_mode = HFR_MODE_OFF;
-
-	memset(&vfe32_ctrl->stats_ctrl, 0,
-		sizeof(struct msm_stats_bufq_ctrl));
-	memset(&vfe32_ctrl->stats_ops, 0, sizeof(struct msm_stats_ops));
-
-	return rc;
-}
-
-void msm_axi_subdev_release(struct v4l2_subdev *sd)
-{
-	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
-	struct msm_cam_media_controller *pmctl =
-		v4l2_get_subdev_hostdata(sd);
-
-	if (!axi_ctrl->share_ctrl->vfebase) {
-		pr_err("%s: base address unmapped\n", __func__);
-		return;
-	}
-
-	axi_ctrl->share_ctrl->axi_ref_cnt--;
-	if (axi_ctrl->share_ctrl->axi_ref_cnt > 0)
-		return;
-
-	axi_clear_all_interrupts(axi_ctrl->share_ctrl);
-	axi_ctrl->share_ctrl->dual_enabled = 0;
-	disable_irq(axi_ctrl->vfeirq->start);
-	tasklet_kill(&axi_ctrl->vfe32_tasklet);
-#ifdef CONFIG_MSM_IOMMU
-	iommu_detach_device(pmctl->domain, axi_ctrl->iommu_ctx_misc);
-	iommu_detach_device(pmctl->domain, axi_ctrl->iommu_ctx_imgwr);
-#endif
-	msm_cam_clk_enable(&axi_ctrl->pdev->dev, vfe32_clk_info,
-			axi_ctrl->vfe_clk, ARRAY_SIZE(vfe32_clk_info), 0);
-	if (axi_ctrl->fs_vfe)
-		regulator_disable(axi_ctrl->fs_vfe);
-
-	iounmap(axi_ctrl->share_ctrl->vfebase);
-	axi_ctrl->share_ctrl->vfebase = NULL;
-
-	if (atomic_read(&irq_cnt))
-		pr_warning("%s, Warning IRQ Count not ZERO\n", __func__);
-
-	msm_camio_bus_scale_cfg(
-		pmctl->sdata->pdata->cam_bus_scale_table, S_EXIT);
-
-}
-
-void msm_vfe_subdev_release(struct v4l2_subdev *sd)
-{
-	struct vfe32_ctrl_type *vfe32_ctrl =
-		(struct vfe32_ctrl_type *)v4l2_get_subdevdata(sd);
-	CDBG("vfe subdev release %p\n",
-		vfe32_ctrl->share_ctrl->vfebase);
-}
-
-void axi_abort(struct axi_ctrl_t *axi_ctrl)
-{
-	uint8_t  axi_busy_flag = true;
-	unsigned long flags;
-	/* axi halt command. */
-
-	spin_lock_irqsave(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
-	axi_ctrl->share_ctrl->stop_ack_pending  = TRUE;
-	spin_unlock_irqrestore(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
-	msm_camera_io_w(AXI_HALT,
-		axi_ctrl->share_ctrl->vfebase + VFE_AXI_CMD);
-	wmb();
-	while (axi_busy_flag) {
-		if (msm_camera_io_r(
-			axi_ctrl->share_ctrl->vfebase + VFE_AXI_STATUS) & 0x1)
-			axi_busy_flag = false;
-	}
-	/* Ensure the write order while writing
-	* to the command register using the barrier */
-	msm_camera_io_w_mb(AXI_HALT_CLEAR,
-		axi_ctrl->share_ctrl->vfebase + VFE_AXI_CMD);
-
-	/* after axi halt, then ok to apply global reset.
-	* enable reset_ack and async timer interrupt only while
-	* stopping the pipeline.*/
-	msm_camera_io_w(0xf0000000,
-		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_0);
-	msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_1,
-		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
-
-	/* Ensure the write order while writing
-	* to the command register using the barrier */
-	msm_camera_io_w_mb(VFE_RESET_UPON_STOP_CMD,
-		axi_ctrl->share_ctrl->vfebase + VFE_GLOBAL_RESET);
-	if (axi_ctrl->share_ctrl->sync_abort)
-		wait_for_completion_interruptible(
-			&axi_ctrl->share_ctrl->reset_complete);
-}
-
-int axi_config_buffers(struct axi_ctrl_t *axi_ctrl,
-	struct msm_camera_vfe_params_t vfe_params)
-{
-	uint16_t vfe_mode = axi_ctrl->share_ctrl->current_mode
-			& ~(VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1);
-	int rc = 0;
-	switch (vfe_params.cmd_type) {
-	case AXI_CMD_PREVIEW:
-		if (vfe_mode) {
-			if ((axi_ctrl->share_ctrl->current_mode &
-				VFE_OUTPUTS_PREVIEW_AND_VIDEO) ||
-				(axi_ctrl->share_ctrl->current_mode &
-				VFE_OUTPUTS_PREVIEW))
-				/* Configure primary channel */
-				rc = configure_pingpong_buffers(
-					VFE_MSG_START,
-					VFE_MSG_OUTPUT_PRIMARY,
-					axi_ctrl);
-			else
-			/* Configure secondary channel */
-				rc = configure_pingpong_buffers(
-					VFE_MSG_START,
-					VFE_MSG_OUTPUT_SECONDARY,
-					axi_ctrl);
-		}
-		if (axi_ctrl->share_ctrl->current_mode &
-				VFE_OUTPUTS_RDI0)
-			rc = configure_pingpong_buffers(
-				VFE_MSG_START, VFE_MSG_OUTPUT_TERTIARY1,
-				axi_ctrl);
-		if (axi_ctrl->share_ctrl->current_mode &
-				VFE_OUTPUTS_RDI1)
-			rc = configure_pingpong_buffers(
-				VFE_MSG_START, VFE_MSG_OUTPUT_TERTIARY2,
-				axi_ctrl);
-
-		if (rc < 0) {
-			pr_err("%s error configuring pingpong buffers for preview",
-				__func__);
-			rc = -EINVAL;
-			goto config_done;
-		}
-		break;
-	case AXI_CMD_RAW_CAPTURE:
-		rc = configure_pingpong_buffers(
-			VFE_MSG_CAPTURE, VFE_MSG_OUTPUT_PRIMARY,
-			axi_ctrl);
-		if (rc < 0) {
-			pr_err("%s error configuring pingpong buffers for snapshot",
-				__func__);
-			rc = -EINVAL;
-			goto config_done;
-		}
-		break;
-	case AXI_CMD_ZSL:
-		rc = configure_pingpong_buffers(VFE_MSG_START,
-			VFE_MSG_OUTPUT_PRIMARY, axi_ctrl);
-		if (rc < 0)
-			goto config_done;
-		rc = configure_pingpong_buffers(VFE_MSG_START,
-			VFE_MSG_OUTPUT_SECONDARY, axi_ctrl);
-		if (rc < 0)
-			goto config_done;
-		break;
-	case AXI_CMD_RECORD:
-		if (axi_ctrl->share_ctrl->current_mode &
-			VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
-			axi_ctrl->share_ctrl->outpath.out1.inst_handle =
-				vfe_params.inst_handle;
-			rc = configure_pingpong_buffers(
-				VFE_MSG_START_RECORDING,
-				VFE_MSG_OUTPUT_SECONDARY,
-				axi_ctrl);
-		} else if (axi_ctrl->share_ctrl->current_mode &
-			VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
-			axi_ctrl->share_ctrl->outpath.out0.inst_handle =
-				vfe_params.inst_handle;
-			rc = configure_pingpong_buffers(
-				VFE_MSG_START_RECORDING,
-				VFE_MSG_OUTPUT_PRIMARY,
-				axi_ctrl);
-		}
-		if (rc < 0) {
-			pr_err("%s error configuring pingpong buffers for video",
-				__func__);
-			rc = -EINVAL;
-			goto config_done;
-		}
-		break;
-	case AXI_CMD_LIVESHOT:
-		axi_ctrl->share_ctrl->outpath.out0.inst_handle =
-			vfe_params.inst_handle;
-		rc = configure_pingpong_buffers(VFE_MSG_CAPTURE,
-					VFE_MSG_OUTPUT_PRIMARY, axi_ctrl);
-		if (rc < 0) {
-			pr_err("%s error configuring pingpong buffers for primary output",
-				__func__);
-			rc = -EINVAL;
-			goto config_done;
-		}
-		break;
-	case AXI_CMD_CAPTURE:
-		if (vfe_mode) {
-			if (axi_ctrl->share_ctrl->current_mode ==
-				VFE_OUTPUTS_JPEG_AND_THUMB ||
-			axi_ctrl->share_ctrl->current_mode ==
-				VFE_OUTPUTS_THUMB_AND_JPEG) {
-
-				/* Configure primary channel for JPEG */
-				rc = configure_pingpong_buffers(
-					VFE_MSG_JPEG_CAPTURE,
-					VFE_MSG_OUTPUT_PRIMARY,
-					axi_ctrl);
-			} else {
-				/* Configure primary channel */
-				rc = configure_pingpong_buffers(
-					VFE_MSG_CAPTURE,
-					VFE_MSG_OUTPUT_PRIMARY,
-					axi_ctrl);
-			}
-			if (rc < 0) {
-				pr_err("%s error configuring pingpong buffers for primary output",
-					__func__);
-				rc = -EINVAL;
-				goto config_done;
-			}
-			/* Configure secondary channel */
-			rc = configure_pingpong_buffers(
-					VFE_MSG_CAPTURE,
-					VFE_MSG_OUTPUT_SECONDARY,
-					axi_ctrl);
-			if (rc < 0) {
-				pr_err("%s error configuring pingpong buffers for secondary output",
-					__func__);
-				rc = -EINVAL;
-				goto config_done;
-			}
-		}
-
-		if (axi_ctrl->share_ctrl->current_mode &
-				VFE_OUTPUTS_RDI0)
-			rc = configure_pingpong_buffers(
-				VFE_MSG_CAPTURE, VFE_MSG_OUTPUT_TERTIARY1,
-				axi_ctrl);
-		if (axi_ctrl->share_ctrl->current_mode &
-				VFE_OUTPUTS_RDI1)
-			rc = configure_pingpong_buffers(
-				VFE_MSG_CAPTURE, VFE_MSG_OUTPUT_TERTIARY2,
-				axi_ctrl);
-		break;
-	default:
-		rc = -EINVAL;
-		break;
-
-	}
-config_done:
-	return rc;
-}
-
-void axi_start(struct msm_cam_media_controller *pmctl,
-	struct axi_ctrl_t *axi_ctrl, struct msm_camera_vfe_params_t vfe_params)
-{
-	int rc = 0, bus_vector_idx = 0;
-	uint32_t reg_update = 0;
-	uint32_t vfe_mode =
-		(axi_ctrl->share_ctrl->current_mode &
-		~(VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1));
-	rc = axi_config_buffers(axi_ctrl, vfe_params);
-	if (rc < 0)
-		return;
-
-	switch (vfe_params.cmd_type) {
-	case AXI_CMD_PREVIEW:
-		if (!axi_ctrl->share_ctrl->dual_enabled)
-			msm_camio_bus_scale_cfg(
-			pmctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
-		break;
-	case AXI_CMD_CAPTURE:
-	case AXI_CMD_RAW_CAPTURE:
-		if (!axi_ctrl->share_ctrl->dual_enabled)
-			msm_camio_bus_scale_cfg(
-			pmctl->sdata->pdata->cam_bus_scale_table, S_CAPTURE);
-		break;
-	case AXI_CMD_RECORD:
-		if (cpu_is_msm8930() || cpu_is_msm8930aa() ||
-			cpu_is_msm8930ab()) {
-			if (axi_ctrl->share_ctrl->current_mode &
-				VFE_OUTPUTS_PREVIEW_AND_VIDEO
-			|| axi_ctrl->share_ctrl->current_mode &
-				VFE_OUTPUTS_VIDEO_AND_PREVIEW)
-				bus_vector_idx = S_VIDEO;
-			else
-				bus_vector_idx = S_ADV_VIDEO;
-		} else {
-			bus_vector_idx = S_VIDEO;
-		}
-		if (!axi_ctrl->share_ctrl->dual_enabled)
-			msm_camio_bus_scale_cfg(
-			pmctl->sdata->pdata->cam_bus_scale_table,
-			bus_vector_idx);
-		return;
-	case AXI_CMD_ZSL:
-		if (!axi_ctrl->share_ctrl->dual_enabled)
-			msm_camio_bus_scale_cfg(
-			pmctl->sdata->pdata->cam_bus_scale_table, S_ZSL);
-		break;
-	case AXI_CMD_LIVESHOT:
-		if (!axi_ctrl->share_ctrl->dual_enabled)
-			msm_camio_bus_scale_cfg(
-			pmctl->sdata->pdata->cam_bus_scale_table, S_LIVESHOT);
-		return;
-	default:
-		return;
-	}
-	axi_enable_wm_irq(axi_ctrl->share_ctrl);
-
-	switch (vfe_params.cmd_type) {
-	case AXI_CMD_RAW_CAPTURE:
-		msm_camera_io_w((
-			0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0),
-			axi_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
-		msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
-			+ vfe32_AXI_WM_CFG[axi_ctrl->
-			share_ctrl->outpath.out0.ch0]);
-		break;
-	case AXI_CMD_PREVIEW: {
-		switch (vfe_mode) {
-		case VFE_OUTPUTS_PREVIEW:
-		case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
-			if (axi_ctrl->share_ctrl->outpath.output_mode &
-				VFE32_OUTPUT_MODE_PRIMARY) {
-				msm_camera_io_w((
-					0x1 << axi_ctrl->share_ctrl->
-							outpath.out0.ch0 |
-					0x1 << axi_ctrl->share_ctrl->
-							outpath.out0.ch1),
-					axi_ctrl->share_ctrl->vfebase +
-							VFE_BUS_CMD);
-				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
-					+ vfe32_AXI_WM_CFG[axi_ctrl->
-					share_ctrl->outpath.out0.ch0]);
-				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
-					+ vfe32_AXI_WM_CFG[axi_ctrl->
-					share_ctrl->outpath.out0.ch1]);
-
-
-			} else if (axi_ctrl->share_ctrl->outpath.output_mode &
-					VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
-				msm_camera_io_w((
-					0x1 << axi_ctrl->share_ctrl->
-							outpath.out0.ch0 |
-					0x1 << axi_ctrl->share_ctrl->
-							outpath.out0.ch1 |
-					0x1 << axi_ctrl->share_ctrl->
-							outpath.out0.ch2),
-					axi_ctrl->share_ctrl->vfebase +
-							VFE_BUS_CMD);
-				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
-					+ vfe32_AXI_WM_CFG[axi_ctrl->
-					share_ctrl->outpath.out0.ch0]);
-				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
-					+ vfe32_AXI_WM_CFG[axi_ctrl->
-					share_ctrl->outpath.out0.ch1]);
-				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
-					+ vfe32_AXI_WM_CFG[axi_ctrl->
-					share_ctrl->outpath.out0.ch2]);
-			}
-			break;
-		default:
-			if (axi_ctrl->share_ctrl->outpath.output_mode &
-				VFE32_OUTPUT_MODE_SECONDARY) {
-				msm_camera_io_w((
-					0x1 << axi_ctrl->share_ctrl->
-						outpath.out1.ch0 |
-					0x1 << axi_ctrl->share_ctrl->
-						outpath.out1.ch1),
-					axi_ctrl->share_ctrl->vfebase +
-						VFE_BUS_CMD);
-				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
-					+ vfe32_AXI_WM_CFG[axi_ctrl->
-					share_ctrl->outpath.out1.ch0]);
-				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
-					+ vfe32_AXI_WM_CFG[axi_ctrl->
-					share_ctrl->outpath.out1.ch1]);
-			} else if (axi_ctrl->share_ctrl->outpath.output_mode &
-				VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
-				msm_camera_io_w((
-					0x1 << axi_ctrl->share_ctrl->
-							outpath.out1.ch0 |
-					0x1 << axi_ctrl->share_ctrl->
-							outpath.out1.ch1 |
-					0x1 << axi_ctrl->share_ctrl->
-							outpath.out1.ch2),
-					axi_ctrl->share_ctrl->vfebase +
-							VFE_BUS_CMD);
-				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
-					+ vfe32_AXI_WM_CFG[axi_ctrl->
-					share_ctrl->outpath.out1.ch0]);
-				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
-					+ vfe32_AXI_WM_CFG[axi_ctrl->
-					share_ctrl->outpath.out1.ch1]);
-				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
-					+ vfe32_AXI_WM_CFG[axi_ctrl->
-					share_ctrl->outpath.out1.ch2]);
-			}
-			break;
-			}
-		}
-		break;
-	default:
-		if (axi_ctrl->share_ctrl->outpath.output_mode &
-			VFE32_OUTPUT_MODE_PRIMARY) {
-			msm_camera_io_w((
-				0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0 |
-				0x1 << axi_ctrl->share_ctrl->outpath.out0.ch1),
-				axi_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe32_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe32_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out0.ch1]);
-		} else if (axi_ctrl->share_ctrl->outpath.output_mode &
-				VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
-			msm_camera_io_w((
-				0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0 |
-				0x1 << axi_ctrl->share_ctrl->outpath.out0.ch1 |
-				0x1 << axi_ctrl->share_ctrl->outpath.out0.ch2),
-				axi_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe32_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe32_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out0.ch1]);
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe32_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out0.ch2]);
-		}
-
-		if (axi_ctrl->share_ctrl->outpath.output_mode &
-			VFE32_OUTPUT_MODE_SECONDARY) {
-			msm_camera_io_w((
-				0x1 << axi_ctrl->share_ctrl->outpath.out1.ch0 |
-				0x1 << axi_ctrl->share_ctrl->outpath.out1.ch1),
-				axi_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe32_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out1.ch0]);
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe32_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out1.ch1]);
-		} else if (axi_ctrl->share_ctrl->outpath.output_mode &
-			VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
-			msm_camera_io_w((
-				0x1 << axi_ctrl->share_ctrl->outpath.out1.ch0 |
-				0x1 << axi_ctrl->share_ctrl->outpath.out1.ch1 |
-				0x1 << axi_ctrl->share_ctrl->outpath.out1.ch2),
-				axi_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe32_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out1.ch0]);
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe32_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out1.ch1]);
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe32_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out1.ch2]);
-		}
-		break;
-	}
-	if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
-		axi_ctrl->share_ctrl->outpath.out2.capture_cnt =
-						vfe_params.capture_count;
-		axi_ctrl->share_ctrl->rdi0_capture_count =
-						vfe_params.capture_count;
-		msm_camera_io_w((
-				0x1 << axi_ctrl->share_ctrl->outpath.out2.ch0),
-				axi_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
-		msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[axi_ctrl->share_ctrl->
-			outpath.out2.ch0]);
-	}
-	if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
-		axi_ctrl->share_ctrl->outpath.out3.capture_cnt =
-						vfe_params.capture_count;
-		axi_ctrl->share_ctrl->rdi1_capture_count =
-						vfe_params.capture_count;
-		msm_camera_io_w((
-				0x1 << axi_ctrl->share_ctrl->outpath.out3.ch0),
-				axi_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
-		msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[axi_ctrl->share_ctrl->
-			outpath.out3.ch0]);
-	}
-
-	axi_enable_irq(axi_ctrl->share_ctrl);
-
-	if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
-		if (!atomic_cmpxchg(
-			&axi_ctrl->share_ctrl->rdi0_update_ack_pending,
-				0, 1))
-			reg_update |= 0x2;
-	}
-	if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
-		if (!atomic_cmpxchg(
-			&axi_ctrl->share_ctrl->rdi1_update_ack_pending,
-				0, 1))
-			reg_update |= 0x4;
-	}
-
-	if (vfe_mode) {
-		if (!atomic_cmpxchg(
-			&axi_ctrl->share_ctrl->pix0_update_ack_pending,
-				0, 1))
-			reg_update |= 0x1;
-	}
-
-	msm_camera_io_w_mb(reg_update,
-			axi_ctrl->share_ctrl->vfebase +
-			VFE_REG_UPDATE_CMD);
-	axi_ctrl->share_ctrl->operation_mode |=
-		axi_ctrl->share_ctrl->current_mode;
-}
-
-void axi_stop(struct msm_cam_media_controller *pmctl,
-	struct axi_ctrl_t *axi_ctrl, struct msm_camera_vfe_params_t vfe_params)
-{
-	uint32_t reg_update = 0;
-	uint32_t vfe_mode =
-	axi_ctrl->share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
-		VFE_OUTPUTS_RDI1);
-	int bus_vector_idx = 0;
-
-	switch (vfe_params.cmd_type) {
-	case AXI_CMD_PREVIEW:
-	case AXI_CMD_CAPTURE:
-	case AXI_CMD_RAW_CAPTURE:
-	case AXI_CMD_ZSL:
-		axi_ctrl->share_ctrl->cmd_type = vfe_params.cmd_type;
-		break;
-	case AXI_CMD_RECORD:
-		if (!axi_ctrl->share_ctrl->dual_enabled)
-			msm_camio_bus_scale_cfg(
-			pmctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
-		return;
-	case AXI_CMD_LIVESHOT:
-		if (!axi_ctrl->share_ctrl->dual_enabled) {
-			bus_vector_idx = S_VIDEO;
-
-			if (cpu_is_msm8930() || cpu_is_msm8930aa() ||
-				cpu_is_msm8930ab())
-				bus_vector_idx = S_ADV_VIDEO;
-
-			msm_camio_bus_scale_cfg(
-			pmctl->sdata->pdata->cam_bus_scale_table,
-			bus_vector_idx);
-		}
-		return;
-	default:
-		return;
-	}
-
-	if (axi_ctrl->share_ctrl->stop_immediately) {
-		axi_disable_irq(axi_ctrl->share_ctrl,
-			axi_ctrl->share_ctrl->current_mode);
-		axi_stop_process(axi_ctrl->share_ctrl);
-		return;
-	}
-
-	if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
-		msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[axi_ctrl->share_ctrl->
-				outpath.out2.ch0]);
-		if (!atomic_cmpxchg(
-			&axi_ctrl->share_ctrl->rdi0_update_ack_pending,
-				0, 2))
-			reg_update |= 0x2;
-	}
-	if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
-		msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase +
-			vfe32_AXI_WM_CFG[axi_ctrl->share_ctrl->
-				outpath.out3.ch0]);
-		if (!atomic_cmpxchg(
-			&axi_ctrl->share_ctrl->rdi1_update_ack_pending,
-				0, 2))
-			reg_update |= 0x4;
-	}
-	if (vfe_mode) {
-		if (!atomic_cmpxchg(
-			&axi_ctrl->share_ctrl->pix0_update_ack_pending,
-				0, 2))
-			reg_update |= 0x1;
-	}
-	msm_camera_io_w_mb(reg_update,
-		axi_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-}
-
-static int msm_axi_config(struct v4l2_subdev *sd, void __user *arg)
-{
-	struct msm_vfe_cfg_cmd cfgcmd;
-	struct msm_isp_cmd vfecmd;
-	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
-	struct msm_cam_media_controller *pmctl =
-		(struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
-	int rc = 0, vfe_cmd_type = 0, rdi_mode = 0;
-
-	if (!axi_ctrl->share_ctrl->vfebase) {
-		pr_err("%s: base address unmapped\n", __func__);
-		return -EFAULT;
-	}
-	memset(&cfgcmd, 0, sizeof(struct msm_vfe_cfg_cmd));
-	if (NULL != arg) {
-		if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
-			ERR_COPY_FROM_USER();
-			return -EFAULT;
-		}
-	}
-	memset(&vfecmd, 0, sizeof(struct msm_isp_cmd));
-	if (NULL != cfgcmd.value) {
-		if (copy_from_user(&vfecmd,
-				(void __user *)(cfgcmd.value),
-				sizeof(vfecmd))) {
-			pr_err("%s %d: copy_from_user failed\n", __func__,
-				__LINE__);
-			return -EFAULT;
-		}
-	}
-
-	vfe_cmd_type = (cfgcmd.cmd_type & ~(CMD_AXI_CFG_TERT1|
-		CMD_AXI_CFG_TERT2));
-	switch (cfgcmd.cmd_type) {
-	case CMD_AXI_CFG_TERT1:{
-		uint32_t *axio = NULL;
-		axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio) {
-			return -ENOMEM;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			return -EFAULT;
-		}
-		vfe32_config_axi(axi_ctrl, OUTPUT_TERT1, axio);
-		kfree(axio);
-		return rc;
-		}
-	case CMD_AXI_CFG_TERT2:{
-		uint32_t *axio = NULL;
-		axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio)
-			return -ENOMEM;
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			return -EFAULT;
-		}
-		vfe32_config_axi(axi_ctrl, OUTPUT_TERT2, axio);
-		kfree(axio);
-		return rc;
-		}
-	case CMD_AXI_CFG_TERT1|CMD_AXI_CFG_TERT2:{
-		uint32_t *axio = NULL;
-		axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio)
-			return -ENOMEM;
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			return -EFAULT;
-		}
-		vfe32_config_axi(axi_ctrl, OUTPUT_TERT1|OUTPUT_TERT2, axio);
-		kfree(axio);
-		return rc;
-		}
-	default:
-		if (cfgcmd.cmd_type & CMD_AXI_CFG_TERT1)
-			rdi_mode |= OUTPUT_TERT1;
-		if (cfgcmd.cmd_type & CMD_AXI_CFG_TERT2)
-			rdi_mode |= OUTPUT_TERT2;
-	}
-	switch (vfe_cmd_type) {
-	case CMD_AXI_CFG_PRIM: {
-		uint32_t *axio = NULL;
-		axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			break;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			rc = -EFAULT;
-			break;
-		}
-		vfe32_config_axi(axi_ctrl, rdi_mode|OUTPUT_PRIM, axio);
-		kfree(axio);
-		break;
-		}
-	case CMD_AXI_CFG_PRIM_ALL_CHNLS: {
-		uint32_t *axio = NULL;
-		axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			break;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			rc = -EFAULT;
-			break;
-		}
-		vfe32_config_axi(axi_ctrl, rdi_mode|OUTPUT_PRIM_ALL_CHNLS,
-			axio);
-		kfree(axio);
-		break;
-		}
-	case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC: {
-		uint32_t *axio = NULL;
-		axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			break;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			rc = -EFAULT;
-			break;
-		}
-		vfe32_config_axi(axi_ctrl,
-			rdi_mode|OUTPUT_PRIM|OUTPUT_SEC, axio);
-		kfree(axio);
-		break;
-		}
-	case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC_ALL_CHNLS: {
-		uint32_t *axio = NULL;
-		axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			break;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			rc = -EFAULT;
-			break;
-		}
-		vfe32_config_axi(axi_ctrl,
-			rdi_mode|OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS, axio);
-		kfree(axio);
-		break;
-		}
-	case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC: {
-		uint32_t *axio = NULL;
-		axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			break;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			rc = -EFAULT;
-			break;
-		}
-		vfe32_config_axi(axi_ctrl,
-			rdi_mode|OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC, axio);
-		kfree(axio);
-		break;
-		}
-
-	case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC_ALL_CHNLS:
-		pr_err("%s Invalid/Unsupported AXI configuration %x",
-			__func__, cfgcmd.cmd_type);
-		break;
-	case CMD_AXI_START: {
-		struct msm_camera_vfe_params_t vfe_params;
-		if (copy_from_user(&vfe_params,
-				(void __user *)(vfecmd.value),
-				sizeof(struct msm_camera_vfe_params_t))) {
-				return -EFAULT;
-		}
-		axi_ctrl->share_ctrl->current_mode =
-			vfe_params.operation_mode;
-		axi_start(pmctl, axi_ctrl, vfe_params);
-		}
-		break;
-	case CMD_AXI_STOP: {
-		struct msm_camera_vfe_params_t vfe_params;
-		if (copy_from_user(&vfe_params,
-				(void __user *)(vfecmd.value),
-				sizeof(struct msm_camera_vfe_params_t))) {
-				return -EFAULT;
-		}
-		axi_ctrl->share_ctrl->current_mode =
-			vfe_params.operation_mode;
-		axi_ctrl->share_ctrl->stop_immediately =
-			vfe_params.stop_immediately;
-		axi_stop(pmctl, axi_ctrl, vfe_params);
-		}
-		break;
-	case CMD_AXI_RESET: {
-		struct msm_camera_vfe_params_t vfe_params;
-		if (copy_from_user(&vfe_params,
-				(void __user *)(vfecmd.value),
-				sizeof(struct msm_camera_vfe_params_t))) {
-				return -EFAULT;
-		}
-		axi_reset(axi_ctrl, vfe_params);
-		}
-		break;
-	case CMD_AXI_ABORT:
-		if (copy_from_user(&axi_ctrl->share_ctrl->sync_abort,
-				(void __user *)(vfecmd.value),
-				sizeof(uint8_t))) {
-				return -EFAULT;
-		}
-		axi_abort(axi_ctrl);
-		break;
-	default:
-		pr_err("%s Unsupported AXI configuration %x ", __func__,
-			cfgcmd.cmd_type);
-		break;
-	}
-	return rc;
-}
-
-static void msm_axi_process_irq(struct v4l2_subdev *sd, void *arg)
-{
-	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
-	uint32_t irqstatus = (uint32_t) arg;
-
-	if (!axi_ctrl->share_ctrl->vfebase) {
-		pr_err("%s: base address unmapped\n", __func__);
-		return;
-	}
-
-	/* next, check output path related interrupts. */
-	if (irqstatus &
-		VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK) {
-		CDBG("Image composite done 0 irq occured.\n");
-		vfe32_process_output_path_irq_0(axi_ctrl);
-	}
-	if (irqstatus &
-		VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK) {
-		CDBG("Image composite done 1 irq occured.\n");
-		vfe32_process_output_path_irq_1(axi_ctrl);
-	}
-
-	if (axi_ctrl->share_ctrl->comp_output_mode &
-		VFE32_OUTPUT_MODE_TERTIARY1)
-		if (irqstatus & (0x1 << (axi_ctrl->share_ctrl->outpath.out2.ch0
-			+ VFE_WM_OFFSET)))
-			vfe32_process_output_path_irq_rdi0(axi_ctrl);
-	if (axi_ctrl->share_ctrl->comp_output_mode &
-		VFE32_OUTPUT_MODE_TERTIARY2)
-		if (irqstatus & (0x1 << (axi_ctrl->share_ctrl->outpath.out3.ch0
-			+ VFE_WM_OFFSET)))
-			vfe32_process_output_path_irq_rdi1(axi_ctrl);
-
-	/* in snapshot mode if done then send
-	snapshot done message */
-	if (
-		axi_ctrl->share_ctrl->operation_mode &
-			VFE_OUTPUTS_THUMB_AND_MAIN ||
-		axi_ctrl->share_ctrl->operation_mode &
-			VFE_OUTPUTS_MAIN_AND_THUMB ||
-		axi_ctrl->share_ctrl->operation_mode &
-			VFE_OUTPUTS_THUMB_AND_JPEG ||
-		axi_ctrl->share_ctrl->operation_mode &
-			VFE_OUTPUTS_JPEG_AND_THUMB ||
-		axi_ctrl->share_ctrl->operation_mode &
-			VFE_OUTPUTS_RAW) {
-		if ((axi_ctrl->share_ctrl->outpath.out0.capture_cnt == 0)
-				&& (axi_ctrl->share_ctrl->outpath.out1.
-				capture_cnt == 0)) {
-			uint32_t mode =
-				(axi_ctrl->share_ctrl->operation_mode &
-				~(VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1));
-			uint16_t output_mode =
-			axi_ctrl->share_ctrl->comp_output_mode &
-				~(VFE32_OUTPUT_MODE_TERTIARY1|
-				VFE32_OUTPUT_MODE_TERTIARY2);
-			if (!axi_ctrl->share_ctrl->dual_enabled)
-				msm_camera_io_w_mb(
-					CAMIF_COMMAND_STOP_IMMEDIATELY,
-					axi_ctrl->share_ctrl->vfebase +
-					VFE_CAMIF_COMMAND);
-			axi_disable_wm_irq(axi_ctrl->share_ctrl, output_mode);
-			axi_disable_irq(axi_ctrl->share_ctrl, mode);
-			vfe32_send_isp_msg(&axi_ctrl->subdev,
-				axi_ctrl->share_ctrl->vfeFrameId,
-				MSG_ID_PIX0_UPDATE_ACK);
-			axi_ctrl->share_ctrl->outpath.out0.
-				capture_cnt = -1;
-			axi_ctrl->share_ctrl->outpath.out1.
-				capture_cnt = -1;
-			axi_ctrl->share_ctrl->comp_output_mode &=
-				(VFE32_OUTPUT_MODE_TERTIARY1|
-				VFE32_OUTPUT_MODE_TERTIARY2);
-		}
-	}
-
-	if (axi_ctrl->share_ctrl->outpath.out2.capture_cnt == 0) {
-		axi_ctrl->share_ctrl->comp_output_mode &=
-				~VFE32_OUTPUT_MODE_TERTIARY1;
-		axi_ctrl->share_ctrl->outpath.out2.capture_cnt = -1;
-	}
-
-	if (axi_ctrl->share_ctrl->outpath.out3.capture_cnt == 0) {
-		axi_ctrl->share_ctrl->comp_output_mode &=
-				~VFE32_OUTPUT_MODE_TERTIARY2;
-		axi_ctrl->share_ctrl->outpath.out3.capture_cnt = -1;
-	}
-}
-
-static int msm_axi_buf_cfg(struct v4l2_subdev *sd, void __user *arg)
-{
-	struct msm_camvfe_params *vfe_params =
-		(struct msm_camvfe_params *)arg;
-	struct msm_vfe_cfg_cmd *cmd = vfe_params->vfe_cfg;
-	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
-	void *data = vfe_params->data;
-	int rc = 0;
-
-	if (!axi_ctrl->share_ctrl->vfebase) {
-		pr_err("%s: base address unmapped\n", __func__);
-		return -EFAULT;
-	}
-
-	switch (cmd->cmd_type) {
-	case CMD_CONFIG_PING_ADDR: {
-		int path = *((int *)cmd->value);
-		struct vfe32_output_ch *outch =
-			vfe32_get_ch(path, axi_ctrl->share_ctrl);
-		outch->ping = *((struct msm_free_buf *)data);
-	}
-		break;
-
-	case CMD_CONFIG_PONG_ADDR: {
-		int path = *((int *)cmd->value);
-		struct vfe32_output_ch *outch =
-			vfe32_get_ch(path, axi_ctrl->share_ctrl);
-		outch->pong = *((struct msm_free_buf *)data);
-	}
-		break;
-
-	case CMD_CONFIG_FREE_BUF_ADDR: {
-		int path = *((int *)cmd->value);
-		struct vfe32_output_ch *outch =
-			vfe32_get_ch(path, axi_ctrl->share_ctrl);
-		outch->free_buf = *((struct msm_free_buf *)data);
-	}
-		break;
-	default:
-		pr_err("%s Unsupported AXI Buf config %x ", __func__,
-			cmd->cmd_type);
-	}
-	return rc;
-};
-
-static const struct v4l2_subdev_internal_ops msm_vfe_internal_ops;
-
-static long msm_axi_subdev_ioctl(struct v4l2_subdev *sd,
-			unsigned int cmd, void *arg)
-{
-	int rc = -ENOIOCTLCMD;
-	switch (cmd) {
-	case VIDIOC_MSM_AXI_INIT: {
-		uint8_t dual_enabled;
-		if (copy_from_user(&dual_enabled,
-				(void __user *)(arg),
-				sizeof(uint8_t))) {
-				rc = -EFAULT;
-				break;
-		}
-		rc = msm_axi_subdev_init(sd, dual_enabled);
-		}
-		break;
-	case VIDIOC_MSM_AXI_CFG:
-		rc = msm_axi_config(sd, arg);
-		break;
-	case VIDIOC_MSM_AXI_IRQ:
-		msm_axi_process_irq(sd, arg);
-		rc = 0;
-		break;
-	case VIDIOC_MSM_AXI_BUF_CFG:
-		msm_axi_buf_cfg(sd, arg);
-		rc = 0;
-		break;
-	case VIDIOC_MSM_AXI_RELEASE:
-		msm_axi_subdev_release(sd);
-		rc = 0;
-		break;
-	case VIDIOC_MSM_AXI_RDI_COUNT_UPDATE: {
-		struct rdi_count_msg *msg = (struct rdi_count_msg *)arg;
-		struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
-		switch (msg->rdi_interface) {
-		case RDI_0:
-			axi_ctrl->share_ctrl->rdi0FrameId = msg->count;
-			rc = 0;
-			break;
-		case RDI_1:
-			axi_ctrl->share_ctrl->rdi1FrameId = msg->count;
-			rc = 0;
-			break;
-		case RDI_2:
-			axi_ctrl->share_ctrl->rdi2FrameId = msg->count;
-			rc = 0;
-			break;
-		default:
-			pr_err("%s: Incorrect interface sent\n", __func__);
-			rc = -EINVAL;
-			break;
-		}
-		break;
-	}
-	default:
-		pr_err("%s: command %d not found\n", __func__,
-						_IOC_NR(cmd));
-		break;
-	}
-	return rc;
-}
-
-static const struct v4l2_subdev_core_ops msm_axi_subdev_core_ops = {
-	.ioctl = msm_axi_subdev_ioctl,
-	.interrupt_service_routine = msm_axi_subdev_isr_routine,
-};
-
-static const struct v4l2_subdev_video_ops msm_axi_subdev_video_ops = {
-	.s_crystal_freq = msm_axi_subdev_s_crystal_freq,
-};
-
-static const struct v4l2_subdev_ops msm_axi_subdev_ops = {
-	.core = &msm_axi_subdev_core_ops,
-	.video = &msm_axi_subdev_video_ops,
-};
-
-static const struct v4l2_subdev_internal_ops msm_axi_internal_ops;
-
-static int __devinit vfe32_probe(struct platform_device *pdev)
-{
-	int rc = 0;
-	struct axi_ctrl_t *axi_ctrl;
-	struct vfe32_ctrl_type *vfe32_ctrl;
-	struct vfe_share_ctrl_t *share_ctrl;
-	struct intr_table_entry irq_req;
-	struct msm_cam_subdev_info sd_info;
-
-	CDBG("%s: device id = %d\n", __func__, pdev->id);
-
-	share_ctrl = kzalloc(sizeof(struct vfe_share_ctrl_t), GFP_KERNEL);
-	if (!share_ctrl) {
-		pr_err("%s: no enough memory\n", __func__);
-		return -ENOMEM;
-	}
-
-	axi_ctrl = kzalloc(sizeof(struct axi_ctrl_t), GFP_KERNEL);
-	if (!axi_ctrl) {
-		pr_err("%s: no enough memory\n", __func__);
-		kfree(share_ctrl);
-		return -ENOMEM;
-	}
-
-	vfe32_ctrl = kzalloc(sizeof(struct vfe32_ctrl_type), GFP_KERNEL);
-	if (!vfe32_ctrl) {
-		pr_err("%s: no enough memory\n", __func__);
-		kfree(share_ctrl);
-		kfree(axi_ctrl);
-		return -ENOMEM;
-	}
-
-	share_ctrl->axi_ctrl = axi_ctrl;
-	share_ctrl->vfe32_ctrl = vfe32_ctrl;
-	axi_ctrl->share_ctrl = share_ctrl;
-	vfe32_ctrl->share_ctrl = share_ctrl;
-	axi_ctrl->share_ctrl->axi_ref_cnt = 0;
-	v4l2_subdev_init(&axi_ctrl->subdev, &msm_axi_subdev_ops);
-	axi_ctrl->subdev.internal_ops = &msm_axi_internal_ops;
-	axi_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-	snprintf(axi_ctrl->subdev.name,
-			 sizeof(axi_ctrl->subdev.name), "axi");
-	v4l2_set_subdevdata(&axi_ctrl->subdev, axi_ctrl);
-	axi_ctrl->pdev = pdev;
-
-	sd_info.sdev_type = AXI_DEV;
-	sd_info.sd_index = 0;
-	sd_info.irq_num = 0;
-	msm_cam_register_subdev_node(&axi_ctrl->subdev, &sd_info);
-
-	media_entity_init(&axi_ctrl->subdev.entity, 0, NULL, 0);
-	axi_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
-	axi_ctrl->subdev.entity.group_id = AXI_DEV;
-	axi_ctrl->subdev.entity.name = pdev->name;
-	axi_ctrl->subdev.entity.revision = axi_ctrl->subdev.devnode->num;
-
-	v4l2_subdev_init(&vfe32_ctrl->subdev, &msm_vfe_subdev_ops);
-	vfe32_ctrl->subdev.internal_ops = &msm_vfe_internal_ops;
-	vfe32_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-	snprintf(vfe32_ctrl->subdev.name,
-			 sizeof(vfe32_ctrl->subdev.name), "vfe3.2");
-	v4l2_set_subdevdata(&vfe32_ctrl->subdev, vfe32_ctrl);
-	platform_set_drvdata(pdev, &vfe32_ctrl->subdev);
-
-	axi_ctrl->vfemem = platform_get_resource_byname(pdev,
-					IORESOURCE_MEM, "vfe32");
-	if (!axi_ctrl->vfemem) {
-		pr_err("%s: no mem resource?\n", __func__);
-		rc = -ENODEV;
-		goto vfe32_no_resource;
-	}
-	axi_ctrl->vfeirq = platform_get_resource_byname(pdev,
-					IORESOURCE_IRQ, "vfe32");
-	if (!axi_ctrl->vfeirq) {
-		pr_err("%s: no irq resource?\n", __func__);
-		rc = -ENODEV;
-		goto vfe32_no_resource;
-	}
-
-	axi_ctrl->vfeio = request_mem_region(axi_ctrl->vfemem->start,
-		resource_size(axi_ctrl->vfemem), pdev->name);
-	if (!axi_ctrl->vfeio) {
-		pr_err("%s: no valid mem region\n", __func__);
-		rc = -EBUSY;
-		goto vfe32_no_resource;
-	}
-
-	axi_ctrl->fs_vfe = regulator_get(&pdev->dev, "vdd");
-	if (IS_ERR(axi_ctrl->fs_vfe)) {
-		pr_err("%s: Regulator get failed %ld\n", __func__,
-			PTR_ERR(axi_ctrl->fs_vfe));
-		axi_ctrl->fs_vfe = NULL;
-	}
-
-	/* Register subdev node before requesting irq since
-	 * irq_num is needed by msm_cam_server */
-	sd_info.sdev_type = VFE_DEV;
-	sd_info.sd_index = 0;
-	sd_info.irq_num = axi_ctrl->vfeirq->start;
-	msm_cam_register_subdev_node(&vfe32_ctrl->subdev, &sd_info);
-
-	media_entity_init(&vfe32_ctrl->subdev.entity, 0, NULL, 0);
-	vfe32_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
-	vfe32_ctrl->subdev.entity.group_id = VFE_DEV;
-	vfe32_ctrl->subdev.entity.name = pdev->name;
-	vfe32_ctrl->subdev.entity.revision = vfe32_ctrl->subdev.devnode->num;
-
-	/* Request for this device irq from the camera server. If the
-	 * IRQ Router is present on this target, the interrupt will be
-	 * handled by the camera server and the interrupt service
-	 * routine called. If the request_irq call returns ENXIO, then
-	 * the IRQ Router hardware is not present on this target. We
-	 * have to request for the irq ourselves and register the
-	 * appropriate interrupt handler. */
-	irq_req.cam_hw_idx       = MSM_CAM_HW_VFE0;
-	irq_req.dev_name         = "vfe";
-	irq_req.irq_idx          = CAMERA_SS_IRQ_8;
-	irq_req.irq_num          = axi_ctrl->vfeirq->start;
-	irq_req.is_composite     = 0;
-	irq_req.irq_trigger_type = IRQF_TRIGGER_RISING;
-	irq_req.num_hwcore       = 1;
-	irq_req.subdev_list[0]   = &axi_ctrl->subdev;
-	irq_req.data             = (void *)axi_ctrl;
-	rc = msm_cam_server_request_irq(&irq_req);
-	if (rc == -ENXIO) {
-		/* IRQ Router hardware is not present on this hardware.
-		 * Request for the IRQ and register the interrupt handler. */
-		rc = request_irq(axi_ctrl->vfeirq->start, vfe32_parse_irq,
-			IRQF_TRIGGER_RISING, "vfe", axi_ctrl);
-		if (rc < 0) {
-			release_mem_region(axi_ctrl->vfemem->start,
-				resource_size(axi_ctrl->vfemem));
-			pr_err("%s: irq request fail\n", __func__);
-			rc = -EBUSY;
-			goto vfe32_no_resource;
-		}
-		disable_irq(axi_ctrl->vfeirq->start);
-	} else if (rc < 0) {
-		pr_err("%s Error registering irq ", __func__);
-		goto vfe32_no_resource;
-	}
-
-#ifdef CONFIG_MSM_IOMMU
-	/*get device context for IOMMU*/
-	axi_ctrl->iommu_ctx_imgwr =
-		msm_iommu_get_ctx("vfe_imgwr"); /*re-confirm*/
-	axi_ctrl->iommu_ctx_misc =
-		msm_iommu_get_ctx("vfe_misc"); /*re-confirm*/
-	if (!axi_ctrl->iommu_ctx_imgwr || !axi_ctrl->iommu_ctx_misc) {
-		release_mem_region(axi_ctrl->vfemem->start,
-			resource_size(axi_ctrl->vfemem));
-		pr_err("%s: No iommu fw context found\n", __func__);
-		rc = -ENODEV;
-		goto vfe32_no_resource;
-	}
-#endif
-
-	tasklet_init(&axi_ctrl->vfe32_tasklet,
-		axi32_do_tasklet, (unsigned long)axi_ctrl);
-
-	vfe32_ctrl->pdev = pdev;
-	/*disable bayer stats by default*/
-	vfe32_ctrl->ver_num.main = 0;
-	return 0;
-
-vfe32_no_resource:
-	kfree(vfe32_ctrl);
-	kfree(axi_ctrl);
-	return 0;
-}
-
-static struct platform_driver vfe32_driver = {
-	.probe = vfe32_probe,
-	.driver = {
-		.name = MSM_VFE_DRV_NAME,
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init msm_vfe32_init_module(void)
-{
-	return platform_driver_register(&vfe32_driver);
-}
-
-static void __exit msm_vfe32_exit_module(void)
-{
-	platform_driver_unregister(&vfe32_driver);
-}
-
-module_init(msm_vfe32_init_module);
-module_exit(msm_vfe32_exit_module);
-MODULE_DESCRIPTION("VFE 3.2 driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/vfe/msm_vfe32.h b/drivers/media/video/msm/vfe/msm_vfe32.h
deleted file mode 100644
index 169c34e..0000000
--- a/drivers/media/video/msm/vfe/msm_vfe32.h
+++ /dev/null
@@ -1,1078 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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 __MSM_VFE32_H__
-#define __MSM_VFE32_H__
-
-#include <linux/bitops.h>
-#include "msm_vfe_stats_buf.h"
-
-#define TRUE  1
-#define FALSE 0
-
-#define VFE32_HW_NUMBER 0x3030B
-#define VFE33_HW_NUMBER 0x30408
-
-/* This defines total number registers in VFE.
- * Each register is 4 bytes so to get the range,
- * multiply this number with 4. */
-#define VFE32_REGISTER_TOTAL 0x000001CD
-#define VFE33_REGISTER_TOTAL 0x000001EE
-
-/* at start of camif,  bit 1:0 = 0x01:enable
- * image data capture at frame boundary. */
-#define CAMIF_COMMAND_START  0x00000005
-
-/* bit 2= 0x1:clear the CAMIF_STATUS register
- * value. */
-#define CAMIF_COMMAND_CLEAR  0x00000004
-
-/* at stop of vfe pipeline, for now it is assumed
- * that camif will stop at any time. Bit 1:0 = 0x10:
- * disable image data capture immediately. */
-#define CAMIF_COMMAND_STOP_IMMEDIATELY  0x00000002
-
-/* at stop of vfe pipeline, for now it is assumed
- * that camif will stop at any time. Bit 1:0 = 0x00:
- * disable image data capture at frame boundary */
-#define CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY  0x00000000
-
-/* to halt axi bridge */
-#define AXI_HALT  0x00000001
-
-/* clear the halt bit. */
-#define AXI_HALT_CLEAR  0x00000000
-
-/* reset the pipeline when stop command is issued.
- * (without reset the register.) bit 26-32 = 0,
- * domain reset, bit 0-9 = 1 for module reset, except
- * register module. */
-#define VFE_RESET_UPON_STOP_CMD  0x000003ef
-
-/* reset the pipeline when reset command.
- * bit 26-32 = 0, domain reset, bit 0-9 = 1 for module reset. */
-#define VFE_RESET_UPON_RESET_CMD  0x000003ff
-
-/* reset the vfe only when reset command*/
-#define VFE_ONLY_RESET_CMD  0x00000002
-
-/*Vfe module reset command*/
-#define VFE_MODULE_RESET_CMD 0x07ffffff
-
-/* bit 5 is for axi status idle or busy.
- * 1 =  halted,  0 = busy */
-#define AXI_STATUS_BUSY_MASK 0x00000020
-
-/* bit 0 & bit 1 = 1, both y and cbcr irqs need to be present
- * for frame done interrupt */
-#define VFE_COMP_IRQ_BOTH_Y_CBCR 3
-
-/* bit 1 = 1, only cbcr irq triggers frame done interrupt */
-#define VFE_COMP_IRQ_CBCR_ONLY 2
-
-/* bit 0 = 1, only y irq triggers frame done interrupt */
-#define VFE_COMP_IRQ_Y_ONLY 1
-
-/* bit 0 = 1, PM go;   bit1 = 1, PM stop */
-#define VFE_PERFORMANCE_MONITOR_GO   0x00000001
-#define VFE_PERFORMANCE_MONITOR_STOP 0x00000002
-
-/* bit 0 = 1, test gen go;   bit1 = 1, test gen stop */
-#define VFE_TEST_GEN_GO   0x00000001
-#define VFE_TEST_GEN_STOP 0x00000002
-
-/* the chroma is assumed to be interpolated between
- * the luma samples.  JPEG 4:2:2 */
-#define VFE_CHROMA_UPSAMPLE_INTERPOLATED 0
-
-/* wm bit offset for IRQ MASK and IRQ STATUS register */
-#define VFE_WM_OFFSET 6
-
-/* constants for irq registers */
-#define VFE_DISABLE_ALL_IRQS 0
-/* bit =1 is to clear the corresponding bit in VFE_IRQ_STATUS.  */
-#define VFE_CLEAR_ALL_IRQS   0xffffffff
-
-#define VFE_IRQ_STATUS0_CAMIF_SOF_MASK            0x00000001
-#define VFE_IRQ_STATUS0_REG_UPDATE_MASK           0x00000020
-#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK 0x00200000
-#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK 0x00400000
-#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE2_MASK 0x00800000
-#define VFE_IRQ_STATUS1_RESET_AXI_HALT_ACK_MASK   0x00800000
-#define VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK       0x01000000
-
-#define VFE_IRQ_STATUS0_STATS_AEC_BG    0x2000  /* bit 13 */
-#define VFE_IRQ_STATUS0_STATS_AF_BF     0x4000  /* bit 14 */
-#define VFE_IRQ_STATUS0_STATS_AWB       0x8000  /* bit 15 */
-#define VFE_IRQ_STATUS0_STATS_RS        0x10000  /* bit 16 */
-#define VFE_IRQ_STATUS0_STATS_CS        0x20000  /* bit 17 */
-#define VFE_IRQ_STATUS0_STATS_IHIST     0x40000  /* bit 18 */
-#define VFE_IRQ_STATUS0_STATS_SK_BHIST  0x80000 /* bit 19 */
-
-#define VFE_IRQ_STATUS0_SYNC_TIMER0   0x2000000  /* bit 25 */
-#define VFE_IRQ_STATUS0_SYNC_TIMER1   0x4000000  /* bit 26 */
-#define VFE_IRQ_STATUS0_SYNC_TIMER2   0x8000000  /* bit 27 */
-#define VFE_IRQ_STATUS0_ASYNC_TIMER0  0x10000000  /* bit 28 */
-#define VFE_IRQ_STATUS0_ASYNC_TIMER1  0x20000000  /* bit 29 */
-#define VFE_IRQ_STATUS0_ASYNC_TIMER2  0x40000000  /* bit 30 */
-#define VFE_IRQ_STATUS0_ASYNC_TIMER3  0x80000000  /* bit 32 */
-
-#define VFE_IRQ_STATUS1_RDI0_REG_UPDATE_MASK  0x4000000 /*bit 26*/
-#define VFE_IRQ_STATUS1_RDI1_REG_UPDATE_MASK  0x8000000 /*bit 27*/
-
-/*TODOs the irq status passed from axi to vfe irq handler does not account
-* for 2 irq status registers. So below macro is added to differentiate between
-* same bit set on both irq status registers. This wil be fixed later by passing
-*entire payload to vfe irq handler and parsing there instead of passing just the
-*status bit*/
-#define VFE_IRQ_STATUS1_RDI0_REG_UPDATE  0x84000000 /*bit 26*/
-#define VFE_IRQ_STATUS1_RDI1_REG_UPDATE  0x88000000 /*bit 27*/
-
-/* imask for while waiting for stop ack,  driver has already
- * requested stop, waiting for reset irq, and async timer irq.
- * For irq_status_0, bit 28-32 are for async timer. For
- * irq_status_1, bit 22 for reset irq, bit 23 for axi_halt_ack
-   irq */
-#define VFE_IMASK_WHILE_STOPPING_0  0xF0000000
-#define VFE_IMASK_WHILE_STOPPING_1  0x00800000
-
-/* no error irq in mask 0 */
-#define VFE_IMASK_ERROR_ONLY_0  0x0
-/* when normal case, don't want to block error status. */
-/* bit 0-21 are error irq bits */
-#define VFE_IMASK_ERROR_ONLY_1  0x003fffff
-
-/* For BPC bit 0,bit 12-17 and bit 26 -20 are set to zero and other's 1 */
-#define BPC_MASK 0xF80C0FFE
-
-/* For ABF bit 4 is set to zero and other's 1 */
-#define ABF_MASK 0xFFFFFFF7
-
-
-/* For DBPC bit 0 is set to zero and other's 1 */
-#define DBPC_MASK 0xFFFFFFFE
-
-/* For DBPC bit 1 is set to zero and other's 1 */
-#define DBCC_MASK 0xFFFFFFFD
-
-/* For DBPC/ABF/DBCC/ABCC bits are set to 1 all others 0 */
-#define DEMOSAIC_MASK 0xF
-
-/* For MCE enable bit 28 set to zero and other's 1 */
-#define MCE_EN_MASK 0xEFFFFFFF
-
-/* For MCE Q_K bit 28 to 32 set to zero and other's 1 */
-#define MCE_Q_K_MASK 0x0FFFFFFF
-
-#define AE_BG_ENABLE_MASK 0x00000020      /* bit 5 */
-#define AF_BF_ENABLE_MASK 0x00000040      /* bit 6 */
-#define AWB_ENABLE_MASK 0x00000080     /* bit 7 */
-#define RS_ENABLE_MASK 0x00000100      /* bit 8  */
-#define CS_ENABLE_MASK 0x00000200      /* bit 9  */
-#define RS_CS_ENABLE_MASK 0x00000300   /* bit 8,9  */
-#define CLF_ENABLE_MASK 0x00002000     /* bit 13 */
-#define IHIST_ENABLE_MASK 0x00010000   /* bit 16 */
-#define SKIN_BHIST_ENABLE_MASK 0x00080000 /* bit 19 */
-#define STATS_ENABLE_MASK 0x000903E0   /* bit 19,16,9,8,7,6,5*/
-
-#define STATS_BG_ENABLE_MASK     0x00000002 /* bit 1 */
-#define STATS_BF_ENABLE_MASK     0x00000004 /* bit 2 */
-#define STATS_BHIST_ENABLE_MASK  0x00000008 /* bit 3 */
-
-#define VFE_REG_UPDATE_TRIGGER           1
-#define VFE_PM_BUF_MAX_CNT_MASK          0xFF
-#define VFE_DMI_CFG_DEFAULT              0x00000100
-#define VFE_AE_PINGPONG_STATUS_BIT       0x80
-#define VFE_AF_PINGPONG_STATUS_BIT       0x100
-#define VFE_AWB_PINGPONG_STATUS_BIT      0x200
-
-#define HFR_MODE_OFF 1
-#define VFE_FRAME_SKIP_PERIOD_MASK 0x0000001F /*bits 0 -4*/
-
-enum VFE32_DMI_RAM_SEL {
-	NO_MEM_SELECTED          = 0,
-	BLACK_LUT_RAM_BANK0      = 0x1,
-	BLACK_LUT_RAM_BANK1      = 0x2,
-	ROLLOFF_RAM0_BANK0       = 0x3,
-	DEMOSAIC_LUT_RAM_BANK0   = 0x4,
-	DEMOSAIC_LUT_RAM_BANK1   = 0x5,
-	STATS_BHIST_RAM0         = 0x6,
-	STATS_BHIST_RAM1         = 0x7,
-	RGBLUT_RAM_CH0_BANK0     = 0x8,
-	RGBLUT_RAM_CH0_BANK1     = 0x9,
-	RGBLUT_RAM_CH1_BANK0     = 0xa,
-	RGBLUT_RAM_CH1_BANK1     = 0xb,
-	RGBLUT_RAM_CH2_BANK0     = 0xc,
-	RGBLUT_RAM_CH2_BANK1     = 0xd,
-	RGBLUT_CHX_BANK0         = 0xe,
-	RGBLUT_CHX_BANK1         = 0xf,
-	STATS_IHIST_RAM          = 0x10,
-	LUMA_ADAPT_LUT_RAM_BANK0 = 0x11,
-	LUMA_ADAPT_LUT_RAM_BANK1 = 0x12,
-	ROLLOFF_RAM1_BANK0       = 0x13,
-	ROLLOFF_RAM0_BANK1       = 0x14,
-	ROLLOFF_RAM1_BANK1       = 0x15,
-};
-
-enum vfe_output_state {
-	VFE_STATE_IDLE,
-	VFE_STATE_START_REQUESTED,
-	VFE_STATE_STARTED,
-	VFE_STATE_STOP_REQUESTED,
-	VFE_STATE_STOPPED,
-};
-
-#define V32_CAMIF_OFF             0x000001E4
-#define V32_CAMIF_LEN             32
-
-#define V32_DEMUX_OFF             0x00000284
-#define V32_DEMUX_LEN             20
-
-#define V32_DEMOSAICV3_0_OFF      0x00000298
-#define V32_DEMOSAICV3_0_LEN      4
-#define V32_DEMOSAICV3_1_OFF      0x0000061C
-#define V32_DEMOSAICV3_1_LEN      88
-#define V32_DEMOSAICV3_2_OFF      0x0000066C
-#define V32_DEMOSAICV3_UP_REG_CNT 5
-/* BPC     */
-#define V32_DEMOSAIC_2_OFF        0x0000029C
-#define V32_DEMOSAIC_2_LEN        8
-
-#define V32_OUT_CLAMP_OFF         0x00000524
-#define V32_OUT_CLAMP_LEN         8
-
-#define V32_OPERATION_CFG_LEN     32
-
-#define V32_AXI_BUS_CMD_OFF       0x00000038
-#define V32_AXI_OUT_OFF           0x0000003C
-#define V32_AXI_OUT_LEN           252
-#define V32_AXI_CFG_LEN           47
-#define V32_AXI_BUS_FMT_OFF       1
-#define V32_AXI_BUS_FMT_LEN       4
-#define V32_AXI_BUS_CFG_LEN       16
-
-#define V32_FRAME_SKIP_OFF        0x00000504
-#define V32_FRAME_SKIP_LEN        32
-
-#define V32_CHROMA_SUBS_OFF       0x000004F8
-#define V32_CHROMA_SUBS_LEN       12
-
-#define V32_FOV_OFF           0x00000360
-#define V32_FOV_LEN           8
-
-#define V32_MAIN_SCALER_OFF 0x00000368
-#define V32_MAIN_SCALER_LEN 28
-
-#define V32_S2Y_OFF 0x000004D0
-#define V32_S2Y_LEN 20
-
-#define V32_S2CbCr_OFF 0x000004E4
-#define V32_S2CbCr_LEN 20
-
-#define V32_CHROMA_EN_OFF 0x000003C4
-#define V32_CHROMA_EN_LEN 36
-
-#define V32_SYNC_TIMER_OFF      0x0000020C
-#define V32_SYNC_TIMER_POLARITY_OFF 0x00000234
-#define V32_TIMER_SELECT_OFF        0x0000025C
-#define V32_SYNC_TIMER_LEN 28
-
-#define V32_ASYNC_TIMER_OFF 0x00000238
-#define V32_ASYNC_TIMER_LEN 28
-
-#define V32_BLACK_LEVEL_OFF 0x00000264
-#define V32_BLACK_LEVEL_LEN 16
-
-#define V32_MESH_ROLL_OFF_CFG_OFF             0x00000274
-#define V32_MESH_ROLL_OFF_CFG_LEN             16
-#define V32_MESH_ROLL_OFF_INIT_TABLE_SIZE     13
-#define V32_MESH_ROLL_OFF_DELTA_TABLE_SIZE    208
-#define V32_MESH_ROLL_OFF_DELTA_TABLE_OFFSET  32
-#define V32_GAMMA_LUT_BANK_SEL_MASK           0x00000007
-
-#define V33_PCA_ROLL_OFF_CFG_LEN1             16
-#define V33_PCA_ROLL_OFF_CFG_OFF1             0x00000274
-#define V33_PCA_ROLL_OFF_CFG_LEN2             12
-#define V33_PCA_ROLL_OFF_CFG_OFF2             0x000007A8
-#define V33_PCA_ROLL_OFF_TABLE_SIZE           (17 + (13*4))
-#define V33_PCA_ROLL_OFF_LUT_BANK_SEL_MASK    0x00010000
-
-#define V32_COLOR_COR_OFF 0x00000388
-#define V32_COLOR_COR_LEN 52
-
-#define V32_WB_OFF 0x00000384
-#define V32_WB_LEN 4
-
-#define V32_RGB_G_OFF 0x000003BC
-#define V32_RGB_G_LEN 4
-
-#define V32_LA_OFF 0x000003C0
-#define V32_LA_LEN 4
-
-#define V32_SCE_OFF 0x00000418
-#define V32_SCE_LEN 136
-
-#define V32_CHROMA_SUP_OFF 0x000003E8
-#define V32_CHROMA_SUP_LEN 12
-
-#define V32_MCE_OFF 0x000003F4
-#define V32_MCE_LEN 36
-#define V32_STATS_AF_OFF 0x0000053c
-#define V32_STATS_AF_LEN 16
-
-#define V32_STATS_AE_OFF 0x00000534
-#define V32_STATS_AE_LEN 8
-
-#define V32_STATS_AWB_OFF 0x0000054c
-#define V32_STATS_AWB_LEN 32
-
-#define V32_STATS_IHIST_OFF 0x0000057c
-#define V32_STATS_IHIST_LEN 8
-
-#define V32_STATS_RS_OFF 0x0000056c
-#define V32_STATS_RS_LEN 8
-
-#define V32_STATS_CS_OFF 0x00000574
-#define V32_STATS_CS_LEN 8
-
-
-#define V32_ASF_OFF 0x000004A0
-#define V32_ASF_LEN 48
-#define V32_ASF_UPDATE_LEN 36
-
-#define V32_CAPTURE_LEN 4
-
-#define V32_GET_HW_VERSION_OFF 0
-#define V32_GET_HW_VERSION_LEN 4
-
-#define V32_LINEARIZATION_OFF1 0x00000264
-#define V32_LINEARIZATION_LEN1 16
-
-#define V32_LINEARIZATION_OFF2 0x0000067C
-#define V32_LINEARIZATION_LEN2 52
-
-#define V32_DEMOSAICV3_OFF 0x00000298
-#define V32_DEMOSAICV3_LEN 4
-
-#define V32_DEMOSAICV3_DBPC_CFG_OFF  0x0000029C
-#define V32_DEMOSAICV3_DBPC_LEN 4
-
-#define V32_DEMOSAICV3_DBPC_CFG_OFF0 0x000002a0
-#define V32_DEMOSAICV3_DBPC_CFG_OFF1 0x00000604
-#define V32_DEMOSAICV3_DBPC_CFG_OFF2 0x00000608
-
-#define V32_DEMOSAICV3_DBCC_OFF 0x0000060C
-#define V32_DEMOSAICV3_DBCC_LEN 16
-
-#define V32_DEMOSAICV3_ABF_OFF 0x000002A4
-#define V32_DEMOSAICV3_ABF_LEN 180
-
-#define V32_MODULE_CFG_OFF 0x00000010
-#define V32_MODULE_CFG_LEN 4
-
-#define V32_ASF_SPECIAL_EFX_CFG_OFF 0x000005FC
-#define V32_ASF_SPECIAL_EFX_CFG_LEN 4
-
-#define V32_CLF_CFG_OFF 0x000006B0
-#define V32_CLF_CFG_LEN 72
-
-#define V32_CLF_LUMA_UPDATE_OFF 0x000006B4
-#define V32_CLF_LUMA_UPDATE_LEN 60
-
-#define V32_CLF_CHROMA_UPDATE_OFF 0x000006F0
-#define V32_CLF_CHROMA_UPDATE_LEN 8
-
-#define V32_STATS_BG_OFF 0x00000700
-#define V32_STATS_BG_LEN 12
-
-#define V32_STATS_BF_OFF 0x0000070c
-#define V32_STATS_BF_LEN 24
-
-#define V32_STATS_BHIST_OFF 0x00000724
-#define V32_STATS_BHIST_LEN 8
-
-struct vfe_cmd_hw_version {
-	uint32_t minorVersion;
-	uint32_t majorVersion;
-	uint32_t coreVersion;
-};
-
-enum VFE_AXI_OUTPUT_MODE {
-	VFE_AXI_OUTPUT_MODE_Output1,
-	VFE_AXI_OUTPUT_MODE_Output2,
-	VFE_AXI_OUTPUT_MODE_Output1AndOutput2,
-	VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2,
-	VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1,
-	VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2,
-	VFE_AXI_LAST_OUTPUT_MODE_ENUM
-};
-
-enum VFE_RAW_WR_PATH_SEL {
-	VFE_RAW_OUTPUT_DISABLED,
-	VFE_RAW_OUTPUT_ENC_CBCR_PATH,
-	VFE_RAW_OUTPUT_VIEW_CBCR_PATH,
-	VFE_RAW_OUTPUT_PATH_INVALID
-};
-
-
-#define VFE_AXI_OUTPUT_BURST_LENGTH     4
-#define VFE_MAX_NUM_FRAGMENTS_PER_FRAME 4
-#define VFE_AXI_OUTPUT_CFG_FRAME_COUNT  3
-
-struct vfe_cmds_per_write_master {
-	uint16_t imageWidth;
-	uint16_t imageHeight;
-	uint16_t outRowCount;
-	uint16_t outRowIncrement;
-	uint32_t outFragments[VFE_AXI_OUTPUT_CFG_FRAME_COUNT]
-		[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
-};
-
-struct vfe_cmds_axi_per_output_path {
-	uint8_t fragmentCount;
-	struct vfe_cmds_per_write_master firstWM;
-	struct vfe_cmds_per_write_master secondWM;
-};
-
-enum VFE_AXI_BURST_LENGTH {
-	VFE_AXI_BURST_LENGTH_IS_2  = 2,
-	VFE_AXI_BURST_LENGTH_IS_4  = 4,
-	VFE_AXI_BURST_LENGTH_IS_8  = 8,
-	VFE_AXI_BURST_LENGTH_IS_16 = 16
-};
-
-
-struct vfe_cmd_fov_crop_config {
-	uint8_t enable;
-	uint16_t firstPixel;
-	uint16_t lastPixel;
-	uint16_t firstLine;
-	uint16_t lastLine;
-};
-
-struct vfe_cmds_main_scaler_stripe_init {
-	uint16_t MNCounterInit;
-	uint16_t phaseInit;
-};
-
-struct vfe_cmds_scaler_one_dimension {
-	uint8_t  enable;
-	uint16_t inputSize;
-	uint16_t outputSize;
-	uint32_t phaseMultiplicationFactor;
-	uint8_t  interpolationResolution;
-};
-
-struct vfe_cmd_main_scaler_config {
-	uint8_t enable;
-	struct vfe_cmds_scaler_one_dimension    hconfig;
-	struct vfe_cmds_scaler_one_dimension    vconfig;
-	struct vfe_cmds_main_scaler_stripe_init MNInitH;
-	struct vfe_cmds_main_scaler_stripe_init MNInitV;
-};
-
-struct vfe_cmd_scaler2_config {
-	uint8_t enable;
-	struct vfe_cmds_scaler_one_dimension hconfig;
-	struct vfe_cmds_scaler_one_dimension vconfig;
-};
-
-
-struct vfe_cmd_frame_skip_update {
-	uint32_t output1Pattern;
-	uint32_t output2Pattern;
-};
-
-struct vfe_cmd_output_clamp_config {
-	uint8_t minCh0;
-	uint8_t minCh1;
-	uint8_t minCh2;
-	uint8_t maxCh0;
-	uint8_t maxCh1;
-	uint8_t maxCh2;
-};
-
-struct vfe_cmd_chroma_subsample_config {
-	uint8_t enable;
-	uint8_t cropEnable;
-	uint8_t vsubSampleEnable;
-	uint8_t hsubSampleEnable;
-	uint8_t vCosited;
-	uint8_t hCosited;
-	uint8_t vCositedPhase;
-	uint8_t hCositedPhase;
-	uint16_t cropWidthFirstPixel;
-	uint16_t cropWidthLastPixel;
-	uint16_t cropHeightFirstLine;
-	uint16_t cropHeightLastLine;
-};
-
-enum VFE_START_PIXEL_PATTERN {
-	VFE_BAYER_RGRGRG,
-	VFE_BAYER_GRGRGR,
-	VFE_BAYER_BGBGBG,
-	VFE_BAYER_GBGBGB,
-	VFE_YUV_YCbYCr,
-	VFE_YUV_YCrYCb,
-	VFE_YUV_CbYCrY,
-	VFE_YUV_CrYCbY
-};
-
-enum VFE_BUS_RD_INPUT_PIXEL_PATTERN {
-	VFE_BAYER_RAW,
-	VFE_YUV_INTERLEAVED,
-	VFE_YUV_PSEUDO_PLANAR_Y,
-	VFE_YUV_PSEUDO_PLANAR_CBCR
-};
-
-enum VFE_YUV_INPUT_COSITING_MODE {
-	VFE_YUV_COSITED,
-	VFE_YUV_INTERPOLATED
-};
-
-#define VFE32_GAMMA_NUM_ENTRIES  64
-
-#define VFE32_LA_TABLE_LENGTH    64
-
-#define VFE32_LINEARIZATON_TABLE_LENGTH    36
-
-struct vfe_cmds_demosaic_abf {
-	uint8_t   enable;
-	uint8_t   forceOn;
-	uint8_t   shift;
-	uint16_t  lpThreshold;
-	uint16_t  max;
-	uint16_t  min;
-	uint8_t   ratio;
-};
-
-struct vfe_cmds_demosaic_bpc {
-	uint8_t   enable;
-	uint16_t  fmaxThreshold;
-	uint16_t  fminThreshold;
-	uint16_t  redDiffThreshold;
-	uint16_t  blueDiffThreshold;
-	uint16_t  greenDiffThreshold;
-};
-
-struct vfe_cmd_demosaic_config {
-	uint8_t   enable;
-	uint8_t   slopeShift;
-	struct vfe_cmds_demosaic_abf abfConfig;
-	struct vfe_cmds_demosaic_bpc bpcConfig;
-};
-
-struct vfe_cmd_demosaic_bpc_update {
-	struct vfe_cmds_demosaic_bpc bpcUpdate;
-};
-
-struct vfe_cmd_demosaic_abf_update {
-	struct vfe_cmds_demosaic_abf abfUpdate;
-};
-
-struct vfe_cmd_white_balance_config {
-	uint8_t  enable;
-	uint16_t ch2Gain;
-	uint16_t ch1Gain;
-	uint16_t ch0Gain;
-};
-
-enum VFE_COLOR_CORRECTION_COEF_QFACTOR {
-	COEF_IS_Q7_SIGNED,
-	COEF_IS_Q8_SIGNED,
-	COEF_IS_Q9_SIGNED,
-	COEF_IS_Q10_SIGNED
-};
-
-struct vfe_cmd_color_correction_config {
-	uint8_t     enable;
-	enum VFE_COLOR_CORRECTION_COEF_QFACTOR coefQFactor;
-	int16_t  C0;
-	int16_t  C1;
-	int16_t  C2;
-	int16_t  C3;
-	int16_t  C4;
-	int16_t  C5;
-	int16_t  C6;
-	int16_t  C7;
-	int16_t  C8;
-	int16_t  K0;
-	int16_t  K1;
-	int16_t  K2;
-};
-
-#define VFE_LA_TABLE_LENGTH 64
-
-struct vfe_cmd_la_config {
-	uint8_t enable;
-	int16_t table[VFE_LA_TABLE_LENGTH];
-};
-
-#define VFE_GAMMA_TABLE_LENGTH 256
-enum VFE_RGB_GAMMA_TABLE_SELECT {
-	RGB_GAMMA_CH0_SELECTED,
-	RGB_GAMMA_CH1_SELECTED,
-	RGB_GAMMA_CH2_SELECTED,
-	RGB_GAMMA_CH0_CH1_SELECTED,
-	RGB_GAMMA_CH0_CH2_SELECTED,
-	RGB_GAMMA_CH1_CH2_SELECTED,
-	RGB_GAMMA_CH0_CH1_CH2_SELECTED
-};
-
-struct vfe_cmd_rgb_gamma_config {
-	uint8_t enable;
-	enum VFE_RGB_GAMMA_TABLE_SELECT channelSelect;
-	int16_t table[VFE_GAMMA_TABLE_LENGTH];
-};
-
-struct vfe_cmd_chroma_enhan_config {
-	uint8_t  enable;
-	int16_t am;
-	int16_t ap;
-	int16_t bm;
-	int16_t bp;
-	int16_t cm;
-	int16_t cp;
-	int16_t dm;
-	int16_t dp;
-	int16_t kcr;
-	int16_t kcb;
-	int16_t RGBtoYConversionV0;
-	int16_t RGBtoYConversionV1;
-	int16_t RGBtoYConversionV2;
-	uint8_t RGBtoYConversionOffset;
-};
-
-struct vfe_cmd_chroma_suppression_config {
-	uint8_t enable;
-	uint8_t m1;
-	uint8_t m3;
-	uint8_t n1;
-	uint8_t n3;
-	uint8_t nn1;
-	uint8_t mm1;
-};
-
-struct vfe_cmd_asf_config {
-	uint8_t enable;
-	uint8_t smoothFilterEnabled;
-	uint8_t sharpMode;
-	uint8_t smoothCoefCenter;
-	uint8_t smoothCoefSurr;
-	uint8_t normalizeFactor;
-	uint8_t sharpK1;
-	uint8_t sharpK2;
-	uint8_t sharpThreshE1;
-	int8_t sharpThreshE2;
-	int8_t sharpThreshE3;
-	int8_t sharpThreshE4;
-	int8_t sharpThreshE5;
-	int8_t filter1Coefficients[9];
-	int8_t filter2Coefficients[9];
-	uint8_t  cropEnable;
-	uint16_t cropFirstPixel;
-	uint16_t cropLastPixel;
-	uint16_t cropFirstLine;
-	uint16_t cropLastLine;
-};
-
-struct vfe_cmd_asf_update {
-	uint8_t enable;
-	uint8_t smoothFilterEnabled;
-	uint8_t sharpMode;
-	uint8_t smoothCoefCenter;
-	uint8_t smoothCoefSurr;
-	uint8_t normalizeFactor;
-	uint8_t sharpK1;
-	uint8_t sharpK2;
-	uint8_t sharpThreshE1;
-	int8_t  sharpThreshE2;
-	int8_t  sharpThreshE3;
-	int8_t  sharpThreshE4;
-	int8_t  sharpThreshE5;
-	int8_t  filter1Coefficients[9];
-	int8_t  filter2Coefficients[9];
-	uint8_t cropEnable;
-};
-
-enum VFE_TEST_GEN_SYNC_EDGE {
-	VFE_TEST_GEN_SYNC_EDGE_ActiveHigh,
-	VFE_TEST_GEN_SYNC_EDGE_ActiveLow
-};
-
-
-struct vfe_cmd_bus_pm_start {
-	uint8_t output2YWrPmEnable;
-	uint8_t output2CbcrWrPmEnable;
-	uint8_t output1YWrPmEnable;
-	uint8_t output1CbcrWrPmEnable;
-};
-
-struct  vfe_frame_skip_counts {
-	uint32_t  totalFrameCount;
-	uint32_t  output1Count;
-	uint32_t  output2Count;
-};
-
-enum VFE_AXI_RD_UNPACK_HBI_SEL {
-	VFE_AXI_RD_HBI_32_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_64_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_128_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_256_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_512_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_1024_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_2048_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_4096_CLOCK_CYCLES
-};
-
-struct vfe_frame_bpc_info {
-	uint32_t greenDefectPixelCount;
-	uint32_t redBlueDefectPixelCount;
-};
-
-struct vfe_frame_asf_info {
-	uint32_t  asfMaxEdge;
-	uint32_t  asfHbiCount;
-};
-
-struct vfe_msg_camif_status {
-	uint8_t  camifState;
-	uint32_t pixelCount;
-	uint32_t lineCount;
-};
-
-struct vfe32_irq_status {
-	uint32_t vfeIrqStatus0;
-	uint32_t vfeIrqStatus1;
-	uint32_t camifStatus;
-	uint32_t demosaicStatus;
-	uint32_t asfMaxEdge;
-};
-
-#define V32_PREVIEW_AXI_FLAG  0x00000001
-#define V32_SNAPSHOT_AXI_FLAG (0x00000001<<1)
-
-struct vfe32_cmd_type {
-	uint16_t id;
-	uint32_t length;
-	uint32_t offset;
-	uint32_t flag;
-};
-
-struct vfe32_free_buf {
-	struct list_head node;
-	uint32_t paddr;
-	uint32_t y_off;
-	uint32_t cbcr_off;
-};
-
-struct vfe32_output_ch {
-	struct list_head free_buf_queue;
-	spinlock_t free_buf_lock;
-	uint32_t inst_handle;
-	int8_t ch0;
-	int8_t ch1;
-	int8_t ch2;
-	int32_t  capture_cnt;
-	uint32_t  frame_drop_cnt;
-	struct msm_free_buf ping;
-	struct msm_free_buf pong;
-	struct msm_free_buf free_buf;
-};
-
-/* no error irq in mask 0 */
-#define VFE32_IMASK_ERROR_ONLY_0  0x0
-/* when normal case, don't want to block error status. */
-/* bit 0-21 are error irq bits */
-#define VFE32_IMASK_COMMON_ERROR_ONLY_1       0x00407F00
-#define VFE32_IMASK_VFE_ERROR_ONLY_1          0x001F80FF
-#define VFE32_IMASK_CAMIF_ERROR               (0x00000001<<0)
-#define VFE32_IMASK_BHIST_OVWR                (0x00000001<<1)
-#define VFE32_IMASK_STATS_CS_OVWR             (0x00000001<<2)
-#define VFE32_IMASK_STATS_IHIST_OVWR          (0x00000001<<3)
-#define VFE32_IMASK_REALIGN_BUF_Y_OVFL        (0x00000001<<4)
-#define VFE32_IMASK_REALIGN_BUF_CB_OVFL       (0x00000001<<5)
-#define VFE32_IMASK_REALIGN_BUF_CR_OVFL       (0x00000001<<6)
-#define VFE32_IMASK_VIOLATION                 (0x00000001<<7)
-#define VFE32_IMASK_IMG_MAST_0_BUS_OVFL       (0x00000001<<8)
-#define VFE32_IMASK_IMG_MAST_1_BUS_OVFL       (0x00000001<<9)
-#define VFE32_IMASK_IMG_MAST_2_BUS_OVFL       (0x00000001<<10)
-#define VFE32_IMASK_IMG_MAST_3_BUS_OVFL       (0x00000001<<11)
-#define VFE32_IMASK_IMG_MAST_4_BUS_OVFL       (0x00000001<<12)
-#define VFE32_IMASK_IMG_MAST_5_BUS_OVFL       (0x00000001<<13)
-#define VFE32_IMASK_IMG_MAST_6_BUS_OVFL       (0x00000001<<14)
-#define VFE32_IMASK_STATS_AE_BG_BUS_OVFL      (0x00000001<<15)
-#define VFE32_IMASK_STATS_AF_BF_BUS_OVFL      (0x00000001<<16)
-#define VFE32_IMASK_STATS_AWB_BUS_OVFL        (0x00000001<<17)
-#define VFE32_IMASK_STATS_RS_BUS_OVFL         (0x00000001<<18)
-#define VFE32_IMASK_STATS_CS_BUS_OVFL         (0x00000001<<19)
-#define VFE32_IMASK_STATS_IHIST_BUS_OVFL      (0x00000001<<20)
-#define VFE32_IMASK_STATS_SKIN_BHIST_BUS_OVFL (0x00000001<<21)
-#define VFE32_IMASK_AXI_ERROR                 (0x00000001<<22)
-
-#define VFE_COM_STATUS 0x000FE000
-
-struct vfe32_output_path {
-	uint16_t output_mode;     /* bitmask  */
-
-	struct vfe32_output_ch out0; /* preview and thumbnail */
-	struct vfe32_output_ch out1; /* snapshot */
-	struct vfe32_output_ch out2; /* rdi0    */
-	struct vfe32_output_ch out3; /* rdi01   */
-};
-
-struct vfe32_frame_extra {
-	uint32_t greenDefectPixelCount;
-	uint32_t redBlueDefectPixelCount;
-
-	uint32_t  asfMaxEdge;
-	uint32_t  asfHbiCount;
-
-	uint32_t yWrPmStats0;
-	uint32_t yWrPmStats1;
-	uint32_t cbcrWrPmStats0;
-	uint32_t cbcrWrPmStats1;
-
-	uint32_t  frameCounter;
-};
-
-#define VFE_DISABLE_ALL_IRQS            0
-#define VFE_CLEAR_ALL_IRQS              0xffffffff
-
-#define VFE_HW_VERSION			0x00000000
-#define VFE_GLOBAL_RESET                0x00000004
-#define VFE_MODULE_RESET		0x00000008
-#define VFE_CGC_OVERRIDE                0x0000000C
-#define VFE_MODULE_CFG                  0x00000010
-#define VFE_CFG				0x00000014
-#define VFE_IRQ_CMD                     0x00000018
-#define VFE_IRQ_MASK_0                  0x0000001C
-#define VFE_IRQ_MASK_1                  0x00000020
-#define VFE_IRQ_CLEAR_0                 0x00000024
-#define VFE_IRQ_CLEAR_1                 0x00000028
-#define VFE_IRQ_STATUS_0                0x0000002C
-#define VFE_IRQ_STATUS_1                0x00000030
-#define VFE_IRQ_COMP_MASK               0x00000034
-#define VFE_BUS_CMD                     0x00000038
-#define VFE_BUS_PING_PONG_STATUS        0x00000180
-#define VFE_AXI_CMD                     0x000001D8
-#define VFE_AXI_STATUS        0x000001DC
-#define VFE_BUS_STATS_PING_PONG_BASE    0x000000F4
-
-#define VFE_BUS_STATS_AEC_BG_WR_PING_ADDR    0x000000F4
-#define VFE_BUS_STATS_AEC_BG_WR_PONG_ADDR    0x000000F8
-#define VFE_BUS_STATS_AEC_BG_UB_CFG          0x000000FC
-#define VFE_BUS_STATS_AF_BF_WR_PING_ADDR     0x00000100
-#define VFE_BUS_STATS_AF_BF_WR_PONG_ADDR     0x00000104
-#define VFE_BUS_STATS_AF_BF_UB_CFG           0x00000108
-#define VFE_BUS_STATS_AWB_WR_PING_ADDR    0x0000010C
-#define VFE_BUS_STATS_AWB_WR_PONG_ADDR    0x00000110
-#define VFE_BUS_STATS_AWB_UB_CFG          0x00000114
-#define VFE_BUS_STATS_RS_WR_PING_ADDR    0x00000118
-#define VFE_BUS_STATS_RS_WR_PONG_ADDR    0x0000011C
-#define VFE_BUS_STATS_RS_UB_CFG          0x00000120
-
-#define VFE_BUS_STATS_CS_WR_PING_ADDR    0x00000124
-#define VFE_BUS_STATS_CS_WR_PONG_ADDR    0x00000128
-#define VFE_BUS_STATS_CS_UB_CFG          0x0000012C
-#define VFE_BUS_STATS_HIST_WR_PING_ADDR   0x00000130
-#define VFE_BUS_STATS_HIST_WR_PONG_ADDR   0x00000134
-#define VFE_BUS_STATS_HIST_UB_CFG          0x00000138
-#define VFE_BUS_STATS_SKIN_BHIST_WR_PING_ADDR    0x0000013C
-#define VFE_BUS_STATS_SKIN_BHIST_WR_PONG_ADDR    0x00000140
-#define VFE_BUS_STATS_SKIN_BHIST_UB_CFG          0x00000144
-#define VFE_CAMIF_COMMAND               0x000001E0
-#define VFE_CAMIF_STATUS                0x00000204
-#define VFE_REG_UPDATE_CMD              0x00000260
-#define VFE_DEMUX_GAIN_0                0x00000288
-#define VFE_DEMUX_GAIN_1                0x0000028C
-#define VFE_CHROMA_UP                   0x0000035C
-#define VFE_FRAMEDROP_ENC_Y_CFG         0x00000504
-#define VFE_FRAMEDROP_ENC_CBCR_CFG      0x00000508
-#define VFE_FRAMEDROP_ENC_Y_PATTERN     0x0000050C
-#define VFE_FRAMEDROP_ENC_CBCR_PATTERN  0x00000510
-#define VFE_FRAMEDROP_VIEW_Y            0x00000514
-#define VFE_FRAMEDROP_VIEW_CBCR         0x00000518
-#define VFE_FRAMEDROP_VIEW_Y_PATTERN    0x0000051C
-#define VFE_FRAMEDROP_VIEW_CBCR_PATTERN 0x00000520
-#define VFE_CLAMP_MAX                   0x00000524
-#define VFE_CLAMP_MIN                   0x00000528
-#define VFE_REALIGN_BUF                 0x0000052C
-#define VFE_STATS_CFG                   0x00000530
-#define VFE_STATS_AWB_SGW_CFG           0x00000554
-#define VFE_DMI_CFG                     0x00000598
-#define VFE_DMI_ADDR                    0x0000059C
-#define VFE_DMI_DATA_HI                 0x000005A0
-#define VFE_DMI_DATA_LO                 0x000005A4
-#define VFE_AXI_CFG                     0x00000600
-#define VFE_BUS_IO_FORMAT_CFG           0x000006F8
-#define VFE_PIXEL_IF_CFG                0x000006FC
-#define VFE_RDI0_CFG                    0x00000734
-#define VFE_RDI1_CFG                    0x000007A4
-
-#define VFE_VIOLATION_STATUS            0x000007B4
-
-#define VFE33_DMI_DATA_HI               0x000005A0
-#define VFE33_DMI_DATA_LO               0x000005A4
-
-#define VFE_AXI_CFG_MASK                0xFFFFFFFF
-
-#define VFE32_OUTPUT_MODE_PT			BIT(0)
-#define VFE32_OUTPUT_MODE_S			BIT(1)
-#define VFE32_OUTPUT_MODE_V			BIT(2)
-#define VFE32_OUTPUT_MODE_P			BIT(3)
-#define VFE32_OUTPUT_MODE_T			BIT(4)
-#define VFE32_OUTPUT_MODE_P_ALL_CHNLS		BIT(5)
-#define VFE32_OUTPUT_MODE_PRIMARY		BIT(6)
-#define VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS	BIT(7)
-#define VFE32_OUTPUT_MODE_SECONDARY		BIT(8)
-#define VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS	BIT(9)
-#define VFE32_OUTPUT_MODE_TERTIARY1		BIT(10)
-#define VFE32_OUTPUT_MODE_TERTIARY2		BIT(11)
-
-struct vfe_stats_control {
-	uint32_t droppedStatsFrameCount;
-	uint32_t bufToRender;
-};
-struct axi_ctrl_t;
-struct vfe32_ctrl_type;
-
-struct vfe_share_ctrl_t {
-	void __iomem *vfebase;
-	uint32_t register_total;
-
-	atomic_t vstate;
-	atomic_t handle_common_irq;
-	uint32_t vfeFrameId;
-	uint32_t rdi0FrameId;
-	uint32_t rdi1FrameId;
-	uint32_t rdi2FrameId;
-	uint32_t stats_comp;
-	spinlock_t  sd_notify_lock;
-	spinlock_t  stop_flag_lock;
-	int8_t stop_ack_pending;
-	enum vfe_output_state liveshot_state;
-	uint32_t vfe_capture_count;
-	int32_t rdi0_capture_count;
-	int32_t rdi1_capture_count;
-	uint8_t update_counter;
-
-	uint32_t operation_mode;     /* streaming or snapshot */
-	uint32_t current_mode;
-	struct vfe32_output_path outpath;
-
-	uint16_t port_info;
-	uint8_t stop_immediately;
-	uint8_t sync_abort;
-	uint16_t cmd_type;
-	uint8_t vfe_reset_flag;
-	uint8_t dual_enabled;
-
-	uint8_t axi_ref_cnt;
-	uint16_t comp_output_mode;
-
-	struct completion reset_complete;
-
-	spinlock_t  update_ack_lock;
-	spinlock_t  start_ack_lock;
-
-	struct axi_ctrl_t *axi_ctrl;
-	struct vfe32_ctrl_type *vfe32_ctrl;
-	int8_t start_ack_pending;
-	int8_t update_ack_pending;
-	enum vfe_output_state recording_state;
-
-	atomic_t pix0_update_ack_pending;
-	atomic_t rdi0_update_ack_pending;
-	atomic_t rdi1_update_ack_pending;
-	atomic_t rdi2_update_ack_pending;
-
-};
-
-struct axi_ctrl_t {
-	struct v4l2_subdev subdev;
-	struct platform_device *pdev;
-	struct resource *vfeirq;
-	spinlock_t  tasklet_lock;
-	struct list_head tasklet_q;
-
-	void *syncdata;
-
-	struct resource	*vfemem;
-	struct resource *vfeio;
-	struct regulator *fs_vfe;
-	struct clk *vfe_clk[3];
-	struct tasklet_struct vfe32_tasklet;
-	struct vfe_share_ctrl_t *share_ctrl;
-	struct device *iommu_ctx_imgwr;
-	struct device *iommu_ctx_misc;
-};
-
-struct vfe32_ctrl_type {
-	spinlock_t  state_lock;
-	spinlock_t  stats_bufq_lock;
-	uint32_t extlen;
-	void *extdata;
-
-	int8_t vfe_sof_count_enable;
-	int8_t update_linear;
-	int8_t update_rolloff;
-	int8_t update_la;
-	int8_t update_gamma;
-
-	struct vfe_share_ctrl_t *share_ctrl;
-
-	uint32_t sync_timer_repeat_count;
-	uint32_t sync_timer_state;
-	uint32_t sync_timer_number;
-
-	struct msm_ver_num_info ver_num;
-	struct vfe_stats_control afbfStatsControl;
-	struct vfe_stats_control awbStatsControl;
-	struct vfe_stats_control aecbgStatsControl;
-	struct vfe_stats_control ihistStatsControl;
-	struct vfe_stats_control rsStatsControl;
-	struct vfe_stats_control csStatsControl;
-	struct vfe_stats_control bhistStatsControl;
-
-	/* v4l2 subdev */
-	struct v4l2_subdev subdev;
-	struct platform_device *pdev;
-	uint32_t hfr_mode;
-	uint32_t frame_skip_cnt;
-	uint32_t frame_skip_pattern;
-	uint32_t snapshot_frame_cnt;
-	struct msm_stats_bufq_ctrl stats_ctrl;
-	struct msm_stats_ops stats_ops;
-
-	uint32_t simultaneous_sof_stat;
-};
-
-#define statsAeNum      0
-#define statsAfNum      1
-#define statsAwbNum     2
-#define statsRsNum      3
-#define statsCsNum      4
-#define statsIhistNum   5
-#define statsSkinNum    6
-
-struct vfe_cmd_stats_ack {
-	uint32_t  nextStatsBuf;
-};
-
-#define VFE_STATS_BUFFER_COUNT            3
-
-struct vfe_cmd_stats_buf {
-	uint32_t statsBuf[VFE_STATS_BUFFER_COUNT];
-};
-
-#endif /* __MSM_VFE32_H__ */
diff --git a/drivers/media/video/msm/vfe/msm_vfe40.c b/drivers/media/video/msm/vfe/msm_vfe40.c
deleted file mode 100644
index 81a6dd2..0000000
--- a/drivers/media/video/msm/vfe/msm_vfe40.c
+++ /dev/null
@@ -1,6478 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/uaccess.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/atomic.h>
-#include <linux/regulator/consumer.h>
-#include <linux/clk.h>
-#include <mach/irqs.h>
-#include <mach/camera.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-#include <media/msm_isp.h>
-#include <mach/msm_bus.h>
-#include <mach/msm_bus_board.h>
-
-#include "msm.h"
-#include "msm_cam_server.h"
-#include "msm_vfe40.h"
-
-atomic_t irq_cnt;
-
-#define VFE_WM_CFG_BASE 0x0070
-#define VFE_WM_CFG_LEN 0x0024
-
-#define vfe40_get_ch_ping_addr(base, chn) \
-	(msm_camera_io_r((base) + VFE_WM_CFG_BASE + VFE_WM_CFG_LEN * (chn)))
-#define vfe40_get_ch_pong_addr(base, chn) \
-	(msm_camera_io_r((base) + VFE_WM_CFG_BASE + VFE_WM_CFG_LEN * (chn) + 4))
-#define vfe40_get_ch_addr(ping_pong, base, chn) \
-	((((ping_pong) & (1 << (chn))) == 0) ? \
-	(vfe40_get_ch_pong_addr((base), chn)) : \
-	(vfe40_get_ch_ping_addr((base), chn)))
-
-#define vfe40_put_ch_ping_addr(base, chn, addr) \
-	(msm_camera_io_w((addr), \
-	(base) + VFE_WM_CFG_BASE + VFE_WM_CFG_LEN * (chn)))
-#define vfe40_put_ch_pong_addr(base, chn, addr) \
-	(msm_camera_io_w((addr), \
-	(base) + VFE_WM_CFG_BASE + VFE_WM_CFG_LEN * (chn) + 4))
-#define vfe40_put_ch_addr(ping_pong, base, chn, addr) \
-	(((ping_pong) & (1 << (chn))) == 0 ?   \
-	vfe40_put_ch_pong_addr((base), (chn), (addr)) : \
-	vfe40_put_ch_ping_addr((base), (chn), (addr)))
-
-static uint32_t vfe_clk_rate;
-static void vfe40_send_isp_msg(struct v4l2_subdev *sd,
-	uint32_t vfeFrameId, uint32_t isp_msg_id);
-
-
-struct vfe40_isr_queue_cmd {
-	struct list_head list;
-	uint32_t                           vfeInterruptStatus0;
-	uint32_t                           vfeInterruptStatus1;
-};
-
-static struct vfe40_cmd_type vfe40_cmd[] = {
-	[1] = {VFE_CMD_SET_CLK},
-	[2] = {VFE_CMD_RESET},
-	[3] = {VFE_CMD_START},
-	[4] = {VFE_CMD_TEST_GEN_START},
-	[5] = {VFE_CMD_OPERATION_CFG, V40_OPERATION_CFG_LEN},
-	[6] = {VFE_CMD_AXI_OUT_CFG, V40_AXI_OUT_LEN, V40_AXI_BUS_CMD_OFF, 0xFF},
-	[7] = {VFE_CMD_CAMIF_CFG, V40_CAMIF_LEN, V40_CAMIF_OFF, 0xFF},
-	[8] = {VFE_CMD_AXI_INPUT_CFG},
-	[9] = {VFE_CMD_BLACK_LEVEL_CFG},
-	[10] = {VFE_CMD_MESH_ROLL_OFF_CFG, V40_MESH_ROLL_OFF_CFG_LEN,
-		V40_MESH_ROLL_OFF_CFG_OFF, 0xFF},
-	[11] = {VFE_CMD_DEMUX_CFG, V40_DEMUX_LEN, V40_DEMUX_OFF, 0xFF},
-	[12] = {VFE_CMD_FOV_CFG},
-	[13] = {VFE_CMD_MAIN_SCALER_CFG},
-	[14] = {VFE_CMD_WB_CFG, V40_WB_LEN, V40_WB_OFF, 0xFF},
-	[15] = {VFE_CMD_COLOR_COR_CFG, V40_COLOR_COR_LEN,
-		V40_COLOR_COR_OFF, 0xFF},
-	[16] = {VFE_CMD_RGB_G_CFG, V40_RGB_G_LEN, V40_RGB_G_OFF, 0xFF},
-	[17] = {VFE_CMD_LA_CFG, V40_LA_LEN, V40_LA_OFF, 0xFF },
-	[18] = {VFE_CMD_CHROMA_EN_CFG, V40_CHROMA_EN_LEN, V40_CHROMA_EN_OFF,
-		0xFF},
-	[19] = {VFE_CMD_CHROMA_SUP_CFG, V40_CHROMA_SUP_LEN,
-		V40_CHROMA_SUP_OFF, 0xFF},
-	[20] = {VFE_CMD_MCE_CFG, V40_MCE_LEN, V40_MCE_OFF, 0xFF},
-	[21] = {VFE_CMD_SK_ENHAN_CFG, V40_SCE_LEN, V40_SCE_OFF, 0xFF},
-	[22] = {VFE_CMD_ASF_CFG, V40_ASF_LEN, V40_ASF_OFF, 0xFF},
-	[23] = {VFE_CMD_S2Y_CFG},
-	[24] = {VFE_CMD_S2CbCr_CFG},
-	[25] = {VFE_CMD_CHROMA_SUBS_CFG},
-	[26] = {VFE_CMD_OUT_CLAMP_CFG, V40_OUT_CLAMP_LEN, V40_OUT_CLAMP_OFF,
-		0xFF},
-	[27] = {VFE_CMD_FRAME_SKIP_CFG},
-	[31] = {VFE_CMD_UPDATE},
-	[32] = {VFE_CMD_BL_LVL_UPDATE},
-	[33] = {VFE_CMD_DEMUX_UPDATE, V40_DEMUX_LEN, V40_DEMUX_OFF, 0xFF},
-	[34] = {VFE_CMD_FOV_UPDATE},
-	[35] = {VFE_CMD_MAIN_SCALER_UPDATE},
-	[36] = {VFE_CMD_WB_UPDATE, V40_WB_LEN, V40_WB_OFF, 0xFF},
-	[37] = {VFE_CMD_COLOR_COR_UPDATE, V40_COLOR_COR_LEN,
-		V40_COLOR_COR_OFF, 0xFF},
-	[38] = {VFE_CMD_RGB_G_UPDATE, V40_RGB_G_LEN, V40_CHROMA_EN_OFF, 0xFF},
-	[39] = {VFE_CMD_LA_UPDATE, V40_LA_LEN, V40_LA_OFF, 0xFF },
-	[40] = {VFE_CMD_CHROMA_EN_UPDATE, V40_CHROMA_EN_LEN,
-		V40_CHROMA_EN_OFF, 0xFF},
-	[41] = {VFE_CMD_CHROMA_SUP_UPDATE, V40_CHROMA_SUP_LEN,
-		V40_CHROMA_SUP_OFF, 0xFF},
-	[42] = {VFE_CMD_MCE_UPDATE, V40_MCE_LEN, V40_MCE_OFF, 0xFF},
-	[43] = {VFE_CMD_SK_ENHAN_UPDATE, V40_SCE_LEN, V40_SCE_OFF, 0xFF},
-	[44] = {VFE_CMD_S2CbCr_UPDATE},
-	[45] = {VFE_CMD_S2Y_UPDATE},
-	[46] = {VFE_CMD_ASF_UPDATE, V40_ASF_UPDATE_LEN, V40_ASF_OFF, 0xFF},
-	[47] = {VFE_CMD_FRAME_SKIP_UPDATE},
-	[48] = {VFE_CMD_CAMIF_FRAME_UPDATE},
-	[49] = {VFE_CMD_STATS_AF_UPDATE},
-	[50] = {VFE_CMD_STATS_AE_UPDATE},
-	[51] = {VFE_CMD_STATS_AWB_UPDATE, V40_STATS_AWB_LEN,
-		V40_STATS_AWB_OFF},
-	[52] = {VFE_CMD_STATS_RS_UPDATE, V40_STATS_RS_LEN, V40_STATS_RS_OFF},
-	[53] = {VFE_CMD_STATS_CS_UPDATE, V40_STATS_CS_LEN, V40_STATS_CS_OFF},
-	[54] = {VFE_CMD_STATS_SKIN_UPDATE},
-	[55] = {VFE_CMD_STATS_IHIST_UPDATE, V40_STATS_IHIST_LEN,
-		V40_STATS_IHIST_OFF},
-	[57] = {VFE_CMD_EPOCH1_ACK},
-	[58] = {VFE_CMD_EPOCH2_ACK},
-	[59] = {VFE_CMD_START_RECORDING},
-	[60] = {VFE_CMD_STOP_RECORDING},
-	[63] = {VFE_CMD_CAPTURE, V40_CAPTURE_LEN, 0xFF},
-	[65] = {VFE_CMD_STOP},
-	[66] = {VFE_CMD_GET_HW_VERSION, V40_GET_HW_VERSION_LEN,
-		V40_GET_HW_VERSION_OFF},
-	[67] = {VFE_CMD_GET_FRAME_SKIP_COUNTS},
-	[68] = {VFE_CMD_OUTPUT1_BUFFER_ENQ},
-	[69] = {VFE_CMD_OUTPUT2_BUFFER_ENQ},
-	[70] = {VFE_CMD_OUTPUT3_BUFFER_ENQ},
-	[71] = {VFE_CMD_JPEG_OUT_BUF_ENQ},
-	[72] = {VFE_CMD_RAW_OUT_BUF_ENQ},
-	[73] = {VFE_CMD_RAW_IN_BUF_ENQ},
-	[74] = {VFE_CMD_STATS_AF_ENQ},
-	[75] = {VFE_CMD_STATS_AE_ENQ},
-	[76] = {VFE_CMD_STATS_AWB_ENQ},
-	[77] = {VFE_CMD_STATS_RS_ENQ},
-	[78] = {VFE_CMD_STATS_CS_ENQ},
-	[79] = {VFE_CMD_STATS_SKIN_ENQ},
-	[80] = {VFE_CMD_STATS_IHIST_ENQ},
-	[82] = {VFE_CMD_JPEG_ENC_CFG},
-	[84] = {VFE_CMD_STATS_AF_START},
-	[85] = {VFE_CMD_STATS_AF_STOP},
-	[86] = {VFE_CMD_STATS_AE_START},
-	[87] = {VFE_CMD_STATS_AE_STOP},
-	[88] = {VFE_CMD_STATS_AWB_START, V40_STATS_AWB_LEN, V40_STATS_AWB_OFF},
-	[89] = {VFE_CMD_STATS_AWB_STOP},
-	[90] = {VFE_CMD_STATS_RS_START, V40_STATS_RS_LEN, V40_STATS_RS_OFF},
-	[91] = {VFE_CMD_STATS_RS_STOP},
-	[92] = {VFE_CMD_STATS_CS_START, V40_STATS_CS_LEN, V40_STATS_CS_OFF},
-	[93] = {VFE_CMD_STATS_CS_STOP},
-	[94] = {VFE_CMD_STATS_SKIN_START},
-	[95] = {VFE_CMD_STATS_SKIN_STOP},
-	[96] = {VFE_CMD_STATS_IHIST_START,
-		V40_STATS_IHIST_LEN, V40_STATS_IHIST_OFF},
-	[97] = {VFE_CMD_STATS_IHIST_STOP},
-	[99] = {VFE_CMD_SYNC_TIMER_SETTING, V40_SYNC_TIMER_LEN,
-			V40_SYNC_TIMER_OFF},
-	[100] = {VFE_CMD_ASYNC_TIMER_SETTING, V40_ASYNC_TIMER_LEN,
-		V40_ASYNC_TIMER_OFF},
-	[101] = {VFE_CMD_LIVESHOT},
-	[102] = {VFE_CMD_LA_SETUP},
-	[103] = {VFE_CMD_LINEARIZATION_CFG, V40_LINEARIZATION_LEN1,
-			V40_LINEARIZATION_OFF1},
-	[104] = {VFE_CMD_DEMOSAICV3},
-	[105] = {VFE_CMD_DEMOSAICV3_ABCC_CFG},
-	[106] = {VFE_CMD_DEMOSAICV3_DBCC_CFG, V40_DEMOSAICV3_DBCC_LEN,
-			V40_DEMOSAICV3_DBCC_OFF},
-	[107] = {VFE_CMD_DEMOSAICV3_DBPC_CFG},
-	[108] = {VFE_CMD_DEMOSAICV3_ABF_CFG, V40_DEMOSAICV3_ABF_LEN,
-			V40_DEMOSAICV3_ABF_OFF},
-	[109] = {VFE_CMD_DEMOSAICV3_ABCC_UPDATE},
-	[110] = {VFE_CMD_DEMOSAICV3_DBCC_UPDATE, V40_DEMOSAICV3_DBCC_LEN,
-			V40_DEMOSAICV3_DBCC_OFF},
-	[111] = {VFE_CMD_DEMOSAICV3_DBPC_UPDATE},
-	[112] = {VFE_CMD_XBAR_CFG},
-	[113] = {VFE_CMD_MODULE_CFG, V40_MODULE_CFG_LEN, V40_MODULE_CFG_OFF},
-	[114] = {VFE_CMD_ZSL},
-	[115] = {VFE_CMD_LINEARIZATION_UPDATE, V40_LINEARIZATION_LEN1,
-			V40_LINEARIZATION_OFF1},
-	[116] = {VFE_CMD_DEMOSAICV3_ABF_UPDATE, V40_DEMOSAICV3_ABF_LEN,
-			V40_DEMOSAICV3_ABF_OFF},
-	[117] = {VFE_CMD_CLF_CFG, V40_CLF_CFG_LEN, V40_CLF_CFG_OFF},
-	[118] = {VFE_CMD_CLF_LUMA_UPDATE, V40_CLF_LUMA_UPDATE_LEN,
-			V40_CLF_LUMA_UPDATE_OFF},
-	[119] = {VFE_CMD_CLF_CHROMA_UPDATE, V40_CLF_CHROMA_UPDATE_LEN,
-			V40_CLF_CHROMA_UPDATE_OFF},
-	[120] = {VFE_CMD_PCA_ROLL_OFF_CFG},
-	[121] = {VFE_CMD_PCA_ROLL_OFF_UPDATE},
-	[122] = {VFE_CMD_GET_REG_DUMP},
-	[123] = {VFE_CMD_GET_LINEARIZATON_TABLE},
-	[124] = {VFE_CMD_GET_MESH_ROLLOFF_TABLE},
-	[125] = {VFE_CMD_GET_PCA_ROLLOFF_TABLE},
-	[126] = {VFE_CMD_GET_RGB_G_TABLE},
-	[127] = {VFE_CMD_GET_LA_TABLE},
-	[128] = {VFE_CMD_DEMOSAICV3_UPDATE},
-	[129] = {VFE_CMD_ACTIVE_REGION_CFG},
-	[130] = {VFE_CMD_COLOR_PROCESSING_CONFIG},
-	[131] = {VFE_CMD_STATS_WB_AEC_CONFIG},
-	[132] = {VFE_CMD_STATS_WB_AEC_UPDATE},
-	[133] = {VFE_CMD_Y_GAMMA_CONFIG},
-	[134] = {VFE_CMD_SCALE_OUTPUT1_CONFIG},
-	[135] = {VFE_CMD_SCALE_OUTPUT2_CONFIG},
-	[136] = {VFE_CMD_CAPTURE_RAW},
-	[137] = {VFE_CMD_STOP_LIVESHOT},
-	[138] = {VFE_CMD_RECONFIG_VFE},
-	[139] = {VFE_CMD_STATS_REQBUF},
-	[140] = {VFE_CMD_STATS_ENQUEUEBUF},
-	[141] = {VFE_CMD_STATS_FLUSH_BUFQ},
-	[142] = {VFE_CMD_STATS_UNREGBUF},
-	[143] = {VFE_CMD_STATS_BG_START, V40_STATS_BG_LEN, V40_STATS_BG_OFF},
-	[144] = {VFE_CMD_STATS_BG_STOP},
-	[145] = {VFE_CMD_STATS_BF_START, V40_STATS_BF_LEN, V40_STATS_BF_OFF},
-	[146] = {VFE_CMD_STATS_BF_STOP},
-	[147] = {VFE_CMD_STATS_BHIST_START, V40_STATS_BHIST_LEN,
-			V40_STATS_BHIST_OFF},
-	[148] = {VFE_CMD_STATS_BHIST_STOP},
-	[149] = {VFE_CMD_RESET_2},
-	[150] = {VFE_CMD_FOV_ENC_CFG, V40_FOV_ENC_LEN,
-		V40_FOV_ENC_OFF, 0xFF},
-	[151] = {VFE_CMD_FOV_VIEW_CFG, V40_FOV_VIEW_LEN,
-		V40_FOV_VIEW_OFF, 0xFF},
-	[152] = {VFE_CMD_FOV_ENC_UPDATE, V40_FOV_ENC_LEN,
-		V40_FOV_ENC_OFF, 0xFF},
-	[153] = {VFE_CMD_FOV_VIEW_UPDATE, V40_FOV_VIEW_LEN,
-		V40_FOV_VIEW_OFF, 0xFF},
-	[154] = {VFE_CMD_SCALER_ENC_CFG, V40_SCALER_ENC_LEN,
-		V40_SCALER_ENC_OFF, 0xFF},
-	[155] = {VFE_CMD_SCALER_VIEW_CFG, V40_SCALER_VIEW_LEN,
-		V40_SCALER_VIEW_OFF, 0xFF},
-	[156] = {VFE_CMD_SCALER_ENC_UPDATE, V40_SCALER_ENC_LEN,
-		V40_SCALER_ENC_OFF, 0xFF},
-	[157] = {VFE_CMD_SCALER_VIEW_UPDATE, V40_SCALER_VIEW_LEN,
-		V40_SCALER_VIEW_OFF, 0xFF},
-	[158] = {VFE_CMD_COLORXFORM_ENC_CFG, V40_COLORXFORM_ENC_CFG_LEN,
-		V40_COLORXFORM_ENC_CFG_OFF, 0xFF},
-	[159] = {VFE_CMD_COLORXFORM_VIEW_CFG, V40_COLORXFORM_VIEW_CFG_LEN,
-		V40_COLORXFORM_VIEW_CFG_OFF},
-	[160] = {VFE_CMD_COLORXFORM_ENC_UPDATE, V40_COLORXFORM_ENC_CFG_LEN,
-		V40_COLORXFORM_ENC_CFG_OFF, 0xFF},
-	[161] = {VFE_CMD_COLORXFORM_VIEW_UPDATE, V40_COLORXFORM_VIEW_CFG_LEN,
-		V40_COLORXFORM_VIEW_CFG_OFF, 0xFF},
-	[163] = {VFE_CMD_STATS_BE_START, V40_STATS_BE_LEN, V40_STATS_BE_OFF},
-	[164] = {VFE_CMD_STATS_BE_STOP},
-};
-
-static const uint32_t vfe40_AXI_WM_CFG[] = {
-	0x0000006C,
-	0x00000090,
-	0x000000B4,
-	0x000000D8,
-	0x000000FC,
-	0x00000120,
-	0x00000144,
-};
-
-static const char * const vfe40_general_cmd[] = {
-	[1] = "SET_CLK",
-	[2] = "RESET",
-	[3] = "START",
-	[4] = "TEST_GEN_START",
-	[5] = "OPERATION_CFG",  /* 5 */
-	[6] = "AXI_OUT_CFG",
-	[7] = "CAMIF_CFG",
-	[8] = "AXI_INPUT_CFG",
-	[9] = "BLACK_LEVEL_CFG",
-	[10] = "ROLL_OFF_CFG",  /* 10 */
-	[11] = "DEMUX_CFG",
-	[12] = "FOV_CFG",
-	[13] = "MAIN_SCALER_CFG",
-	[14] = "WB_CFG",
-	[15] = "COLOR_COR_CFG", /* 15 */
-	[16] = "RGB_G_CFG",
-	[17] = "LA_CFG",
-	[18] = "CHROMA_EN_CFG",
-	[19] = "CHROMA_SUP_CFG",
-	[20] = "MCE_CFG", /* 20 */
-	[21] = "SK_ENHAN_CFG",
-	[22] = "ASF_CFG",
-	[23] = "S2Y_CFG",
-	[24] = "S2CbCr_CFG",
-	[25] = "CHROMA_SUBS_CFG",  /* 25 */
-	[26] = "OUT_CLAMP_CFG",
-	[27] = "FRAME_SKIP_CFG",
-	[31] = "UPDATE",
-	[32] = "BL_LVL_UPDATE",
-	[33] = "DEMUX_UPDATE",
-	[34] = "FOV_UPDATE",
-	[35] = "MAIN_SCALER_UPDATE",  /* 35 */
-	[36] = "WB_UPDATE",
-	[37] = "COLOR_COR_UPDATE",
-	[38] = "RGB_G_UPDATE",
-	[39] = "LA_UPDATE",
-	[40] = "CHROMA_EN_UPDATE",  /* 40 */
-	[41] = "CHROMA_SUP_UPDATE",
-	[42] = "MCE_UPDATE",
-	[43] = "SK_ENHAN_UPDATE",
-	[44] = "S2CbCr_UPDATE",
-	[45] = "S2Y_UPDATE",  /* 45 */
-	[46] = "ASF_UPDATE",
-	[47] = "FRAME_SKIP_UPDATE",
-	[48] = "CAMIF_FRAME_UPDATE",
-	[49] = "STATS_AF_UPDATE",
-	[50] = "STATS_AE_UPDATE",  /* 50 */
-	[51] = "STATS_AWB_UPDATE",
-	[52] = "STATS_RS_UPDATE",
-	[53] = "STATS_CS_UPDATE",
-	[54] = "STATS_SKIN_UPDATE",
-	[55] = "STATS_IHIST_UPDATE",  /* 55 */
-	[57] = "EPOCH1_ACK",
-	[58] = "EPOCH2_ACK",
-	[59] = "START_RECORDING",
-	[60] = "STOP_RECORDING",  /* 60 */
-	[63] = "CAPTURE",
-	[65] = "STOP",  /* 65 */
-	[66] = "GET_HW_VERSION",
-	[67] = "GET_FRAME_SKIP_COUNTS",
-	[68] = "OUTPUT1_BUFFER_ENQ",
-	[69] = "OUTPUT2_BUFFER_ENQ",
-	[70] = "OUTPUT3_BUFFER_ENQ",  /* 70 */
-	[71] = "JPEG_OUT_BUF_ENQ",
-	[72] = "RAW_OUT_BUF_ENQ",
-	[73] = "RAW_IN_BUF_ENQ",
-	[74] = "STATS_AF_ENQ",
-	[75] = "STATS_AE_ENQ",  /* 75 */
-	[76] = "STATS_AWB_ENQ",
-	[77] = "STATS_RS_ENQ",
-	[78] = "STATS_CS_ENQ",
-	[79] = "STATS_SKIN_ENQ",
-	[80] = "STATS_IHIST_ENQ",  /* 80 */
-	[82] = "JPEG_ENC_CFG",
-	[84] = "STATS_AF_START",
-	[85] = "STATS_AF_STOP",  /* 85 */
-	[86] = "STATS_AE_START",
-	[87] = "STATS_AE_STOP",
-	[88] = "STATS_AWB_START",
-	[89] = "STATS_AWB_STOP",
-	[90] = "STATS_RS_START",  /* 90 */
-	[91] = "STATS_RS_STOP",
-	[92] = "STATS_CS_START",
-	[93] = "STATS_CS_STOP",
-	[94] = "STATS_SKIN_START",
-	[95] = "STATS_SKIN_STOP",  /* 95 */
-	[96] = "STATS_IHIST_START",
-	[97] = "STATS_IHIST_STOP",
-	[99] = "SYNC_TIMER_SETTING",
-	[100] = "ASYNC_TIMER_SETTING",  /* 100 */
-	[101] = "LIVESHOT",
-	[102] = "LA_SETUP",
-	[103] = "LINEARIZATION_CFG",
-	[104] = "DEMOSAICV3",
-	[105] = "DEMOSAICV3_ABCC_CFG", /* 105 */
-	[106] = "DEMOSAICV3_DBCC_CFG",
-	[107] = "DEMOSAICV3_DBPC_CFG",
-	[108] = "DEMOSAICV3_ABF_CFG",
-	[109] = "DEMOSAICV3_ABCC_UPDATE",
-	[110] = "DEMOSAICV3_DBCC_UPDATE", /* 110 */
-	[111] = "DEMOSAICV3_DBPC_UPDATE",
-	[112] = "XBAR_CFG",
-	[113] = "EZTUNE_CFG",
-	[114] = "V40_ZSL",
-	[115] = "LINEARIZATION_UPDATE", /*115*/
-	[116] = "DEMOSAICV3_ABF_UPDATE",
-	[117] = "CLF_CFG",
-	[118] = "CLF_LUMA_UPDATE",
-	[119] = "CLF_CHROMA_UPDATE",
-	[120] = "PCA_ROLL_OFF_CFG", /*120*/
-	[121] = "PCA_ROLL_OFF_UPDATE",
-	[122] = "GET_REG_DUMP",
-	[123] = "GET_LINEARIZATON_TABLE",
-	[124] = "GET_MESH_ROLLOFF_TABLE",
-	[125] = "GET_PCA_ROLLOFF_TABLE", /*125*/
-	[126] = "GET_RGB_G_TABLE",
-	[127] = "GET_LA_TABLE",
-	[128] = "DEMOSAICV3_UPDATE",
-	[139] = "STATS_REQBUF",
-	[140] = "STATS_ENQUEUEBUF", /*140*/
-	[141] = "STATS_FLUSH_BUFQ",
-	[142] = "STATS_UNREGBUF",
-	[143] = "STATS_BG_START",
-	[144] = "STATS_BG_STOP",
-	[145] = "STATS_BF_START", /*145*/
-	[146] = "STATS_BF_STOP",
-	[147] = "STATS_BHIST_START",
-	[148] = "STATS_BHIST_STOP",
-	[149] = "RESET_2",
-};
-
-/*Temporary use fixed bus vectors in VFE */
-static struct msm_bus_vectors vfe_init_vectors[] = {
-	{
-		.src = MSM_BUS_MASTER_VFE,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab  = 0,
-		.ib  = 0,
-	},
-};
-
-static struct msm_bus_vectors vfe_preview_vectors[] = {
-	{
-		.src = MSM_BUS_MASTER_VFE,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab  = 27648000,
-		.ib  = 110592000,
-	},
-};
-
-static struct msm_bus_vectors vfe_video_vectors[] = {
-	{
-		.src = MSM_BUS_MASTER_VFE,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab  = 274406400,
-		.ib  = 617103360,
-	},
-};
-
-static struct msm_bus_vectors vfe_liveshot_vectors[] = {
-	{
-		.src = MSM_BUS_MASTER_VFE,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab  = 348192000,
-		.ib  = 617103360,
-	},
-};
-
-static struct msm_bus_vectors vfe_snapshot_vectors[] = {
-	{
-		.src = MSM_BUS_MASTER_VFE,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab  = 274423680,
-		.ib  = 1097694720,
-	},
-};
-
-static struct msm_bus_vectors vfe_zsl_vectors[] = {
-	{
-		.src = MSM_BUS_MASTER_VFE,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab  = 302071680,
-		.ib  = 1208286720,
-	},
-};
-
-static struct msm_bus_paths vfe_bus_client_config[] = {
-	{
-		ARRAY_SIZE(vfe_init_vectors),
-		vfe_init_vectors,
-	},
-	{
-		ARRAY_SIZE(vfe_preview_vectors),
-		vfe_preview_vectors,
-	},
-	{
-		ARRAY_SIZE(vfe_video_vectors),
-		vfe_video_vectors,
-	},
-	{
-		ARRAY_SIZE(vfe_snapshot_vectors),
-		vfe_snapshot_vectors,
-	},
-	{
-		ARRAY_SIZE(vfe_zsl_vectors),
-		vfe_zsl_vectors,
-	},
-	{
-		ARRAY_SIZE(vfe_liveshot_vectors),
-		vfe_liveshot_vectors,
-	},
-};
-
-static struct msm_bus_scale_pdata vfe_bus_client_pdata = {
-		vfe_bus_client_config,
-		ARRAY_SIZE(vfe_bus_client_config),
-		.name = "msm_camera_vfe",
-};
-
-uint8_t vfe40_use_bayer_stats(struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	if (vfe40_ctrl->ver_num.main >= 4) {
-		/* VFE 4 or above uses bayer stats */
-		return TRUE;
-	} else {
-		return FALSE;
-	}
-}
-
-static void axi_enable_irq(struct vfe_share_ctrl_t *share_ctrl)
-{
-	uint32_t irq_mask;
-	uint16_t vfe_operation_mode =
-		share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
-			VFE_OUTPUTS_RDI1);
-	irq_mask =
-		msm_camera_io_r(share_ctrl->vfebase +
-			VFE_IRQ_MASK_0);
-
-	irq_mask |= VFE_IMASK_WHILE_STOPPING_0;
-
-	if (share_ctrl->current_mode & VFE_OUTPUTS_RDI0)
-		irq_mask |= VFE_IRQ_STATUS0_RDI0_REG_UPDATE_MASK;
-
-	if (share_ctrl->current_mode & VFE_OUTPUTS_RDI1)
-		irq_mask |= VFE_IRQ_STATUS0_RDI1_REG_UPDATE_MASK;
-
-	msm_camera_io_w(irq_mask, share_ctrl->vfebase +
-		VFE_IRQ_MASK_0);
-
-	if (vfe_operation_mode) {
-		irq_mask =
-		msm_camera_io_r(share_ctrl->vfebase +
-			VFE_IRQ_MASK_0);
-		irq_mask |= 0x00000021;
-		if (share_ctrl->stats_comp)
-			irq_mask |= VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK_0;
-		else
-			irq_mask |= 0x00FF0000;
-		msm_camera_io_w(irq_mask, share_ctrl->vfebase +
-			VFE_IRQ_MASK_0);
-		atomic_set(&share_ctrl->vstate, 1);
-	}
-	atomic_set(&share_ctrl->handle_common_irq, 1);
-}
-
-static void axi_disable_irq(struct vfe_share_ctrl_t *share_ctrl)
-{
-
-	/* disable all interrupts.  */
-
-	uint32_t irq_mask = 0;
-	uint16_t vfe_operation_mode =
-		share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
-			VFE_OUTPUTS_RDI1);
-
-	if (share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
-		irq_mask =
-		msm_camera_io_r(share_ctrl->vfebase +
-			VFE_IRQ_MASK_0);
-		irq_mask &= ~(VFE_IRQ_STATUS0_RDI0_REG_UPDATE_MASK);
-		msm_camera_io_w(irq_mask, share_ctrl->vfebase +
-			VFE_IRQ_MASK_0);
-		msm_camera_io_w(VFE_IRQ_STATUS0_RDI0_REG_UPDATE_MASK,
-			share_ctrl->vfebase + VFE_IRQ_CLEAR_0);
-	}
-	if (share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
-		irq_mask =
-		msm_camera_io_r(share_ctrl->vfebase +
-			VFE_IRQ_MASK_0);
-		irq_mask &= ~(VFE_IRQ_STATUS0_RDI1_REG_UPDATE_MASK);
-		msm_camera_io_w(irq_mask, share_ctrl->vfebase +
-			VFE_IRQ_MASK_0);
-		msm_camera_io_w(VFE_IRQ_STATUS0_RDI1_REG_UPDATE_MASK,
-			share_ctrl->vfebase + VFE_IRQ_CLEAR_0);
-	}
-	if (vfe_operation_mode) {
-		atomic_set(&share_ctrl->vstate, 0);
-		irq_mask =
-		msm_camera_io_r(share_ctrl->vfebase +
-			VFE_IRQ_MASK_0);
-		irq_mask &= ~(0x00000011);
-		if (share_ctrl->stats_comp)
-			irq_mask &= ~(VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK_0);
-		else
-			irq_mask &= ~0x00FF0000;
-		msm_camera_io_w(irq_mask, share_ctrl->vfebase +
-			VFE_IRQ_MASK_0);
-	}
-
-}
-
-static void vfe40_stop(struct vfe40_ctrl_type *vfe40_ctrl)
-{
-
-	/* in either continuous or snapshot mode, stop command can be issued
-	 * at any time. stop camif immediately. */
-	msm_camera_io_w(CAMIF_COMMAND_STOP_IMMEDIATELY,
-		vfe40_ctrl->share_ctrl->vfebase + VFE_CAMIF_COMMAND);
-	vfe40_ctrl->share_ctrl->operation_mode &=
-		~(vfe40_ctrl->share_ctrl->current_mode);
-	vfe40_ctrl->share_ctrl->current_mode = 0;
-}
-
-static void vfe40_subdev_notify(int id, int path, uint32_t inst_handle,
-	struct v4l2_subdev *sd, struct vfe_share_ctrl_t *share_ctrl)
-{
-	struct msm_vfe_resp rp;
-	struct msm_frame_info frame_info;
-	unsigned long flags = 0;
-	spin_lock_irqsave(&share_ctrl->sd_notify_lock, flags);
-	CDBG("vfe40_subdev_notify : msgId = %d\n", id);
-	memset(&rp, 0, sizeof(struct msm_vfe_resp));
-	rp.evt_msg.type   = MSM_CAMERA_MSG;
-	frame_info.inst_handle = inst_handle;
-	frame_info.path = path;
-	rp.evt_msg.data = &frame_info;
-	rp.type	   = id;
-	v4l2_subdev_notify(sd, NOTIFY_VFE_BUF_EVT, &rp);
-	spin_unlock_irqrestore(&share_ctrl->sd_notify_lock, flags);
-}
-
-static int vfe40_config_axi(
-	struct axi_ctrl_t *axi_ctrl, int mode, uint32_t *ao)
-{
-	uint32_t *ch_info;
-	uint32_t *axi_cfg = ao;
-	int vfe_mode = (mode & ~(OUTPUT_TERT1|OUTPUT_TERT2));
-
-	/* Update the corresponding write masters for each output*/
-	ch_info = axi_cfg + V40_AXI_CFG_LEN;
-	axi_ctrl->share_ctrl->outpath.out0.ch0 = 0x0000FFFF & *ch_info;
-	axi_ctrl->share_ctrl->outpath.out0.ch1 =
-		0x0000FFFF & (*ch_info++ >> 16);
-	axi_ctrl->share_ctrl->outpath.out0.ch2 = 0x0000FFFF & *ch_info++;
-	axi_ctrl->share_ctrl->outpath.out0.inst_handle = *ch_info++;
-
-	axi_ctrl->share_ctrl->outpath.out1.ch0 = 0x0000FFFF & *ch_info;
-	axi_ctrl->share_ctrl->outpath.out1.ch1 =
-		0x0000FFFF & (*ch_info++ >> 16);
-	axi_ctrl->share_ctrl->outpath.out1.ch2 = 0x0000FFFF & *ch_info++;
-	axi_ctrl->share_ctrl->outpath.out1.inst_handle = *ch_info++;
-
-	axi_ctrl->share_ctrl->outpath.out2.ch0 = 0x0000FFFF & *ch_info;
-	axi_ctrl->share_ctrl->outpath.out2.ch1 =
-		0x0000FFFF & (*ch_info++ >> 16);
-	axi_ctrl->share_ctrl->outpath.out2.ch2 = 0x0000FFFF & *ch_info++;
-	axi_ctrl->share_ctrl->outpath.out2.inst_handle = *ch_info++;
-
-	axi_ctrl->share_ctrl->outpath.out3.ch0 = 0x0000FFFF & *ch_info;
-	axi_ctrl->share_ctrl->outpath.out3.ch1 =
-		0x0000FFFF & (*ch_info++ >> 16);
-	axi_ctrl->share_ctrl->outpath.out3.ch2 = 0x0000FFFF & *ch_info++;
-	axi_ctrl->share_ctrl->outpath.out3.inst_handle = *ch_info++;
-
-	axi_ctrl->share_ctrl->outpath.output_mode = 0;
-
-	if (mode & OUTPUT_TERT1)
-		axi_ctrl->share_ctrl->outpath.output_mode |=
-			VFE40_OUTPUT_MODE_TERTIARY1;
-	if (mode & OUTPUT_TERT2)
-		axi_ctrl->share_ctrl->outpath.output_mode |=
-			VFE40_OUTPUT_MODE_TERTIARY2;
-	if (mode == OUTPUT_TERT1 || mode == OUTPUT_TERT1
-		|| mode == (OUTPUT_TERT1|OUTPUT_TERT2))
-			goto bus_cfg;
-
-	switch (vfe_mode) {
-	case OUTPUT_PRIM:
-		axi_ctrl->share_ctrl->outpath.output_mode |=
-			VFE40_OUTPUT_MODE_PRIMARY;
-		break;
-	case OUTPUT_PRIM_ALL_CHNLS:
-		axi_ctrl->share_ctrl->outpath.output_mode |=
-			VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
-		break;
-	case OUTPUT_PRIM|OUTPUT_SEC:
-		axi_ctrl->share_ctrl->outpath.output_mode |=
-			VFE40_OUTPUT_MODE_PRIMARY;
-		axi_ctrl->share_ctrl->outpath.output_mode |=
-			VFE40_OUTPUT_MODE_SECONDARY;
-		break;
-	case OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS:
-		axi_ctrl->share_ctrl->outpath.output_mode |=
-			VFE40_OUTPUT_MODE_PRIMARY;
-		axi_ctrl->share_ctrl->outpath.output_mode |=
-			VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS;
-		break;
-	case OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC:
-		axi_ctrl->share_ctrl->outpath.output_mode |=
-			VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
-		axi_ctrl->share_ctrl->outpath.output_mode |=
-			VFE40_OUTPUT_MODE_SECONDARY;
-		break;
-	default:
-		pr_err("%s Invalid AXI mode %d ", __func__, mode);
-		return -EINVAL;
-	}
-
-bus_cfg:
-	msm_camera_io_memcpy(axi_ctrl->share_ctrl->vfebase +
-		vfe40_cmd[VFE_CMD_AXI_OUT_CFG].offset, axi_cfg,
-		V40_AXI_BUS_CFG_LEN);
-	msm_camera_io_w(*ch_info++,
-		axi_ctrl->share_ctrl->vfebase + VFE_RDI0_CFG);
-	msm_camera_io_w(*ch_info++,
-		axi_ctrl->share_ctrl->vfebase + VFE_RDI1_CFG);
-	msm_camera_io_w(*ch_info++,
-		axi_ctrl->share_ctrl->vfebase + VFE_RDI2_CFG);
-	return 0;
-}
-
-static void axi_reset_internal_variables(
-	struct axi_ctrl_t *axi_ctrl)
-{
-	unsigned long flags;
-	/* state control variables */
-	axi_ctrl->share_ctrl->start_ack_pending = FALSE;
-	atomic_set(&irq_cnt, 0);
-
-	spin_lock_irqsave(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
-	axi_ctrl->share_ctrl->stop_ack_pending  = FALSE;
-	spin_unlock_irqrestore(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
-
-	spin_lock_irqsave(&axi_ctrl->share_ctrl->update_ack_lock, flags);
-	axi_ctrl->share_ctrl->update_ack_pending = FALSE;
-	spin_unlock_irqrestore(&axi_ctrl->share_ctrl->update_ack_lock, flags);
-
-	axi_ctrl->share_ctrl->recording_state = VFE_STATE_IDLE;
-	axi_ctrl->share_ctrl->liveshot_state = VFE_STATE_IDLE;
-
-	atomic_set(&axi_ctrl->share_ctrl->vstate, 0);
-	atomic_set(&axi_ctrl->share_ctrl->handle_common_irq, 0);
-	atomic_set(&axi_ctrl->share_ctrl->pix0_update_ack_pending, 0);
-	atomic_set(&axi_ctrl->share_ctrl->rdi0_update_ack_pending, 0);
-	atomic_set(&axi_ctrl->share_ctrl->rdi1_update_ack_pending, 0);
-	atomic_set(&axi_ctrl->share_ctrl->rdi2_update_ack_pending, 0);
-
-	/* 0 for continuous mode, 1 for snapshot mode */
-	axi_ctrl->share_ctrl->operation_mode = 0;
-	axi_ctrl->share_ctrl->current_mode = 0;
-	axi_ctrl->share_ctrl->outpath.output_mode = 0;
-	axi_ctrl->share_ctrl->comp_output_mode = 0;
-	axi_ctrl->share_ctrl->vfe_capture_count = 0;
-
-	/* this is unsigned 32 bit integer. */
-	axi_ctrl->share_ctrl->vfeFrameId = 0;
-	axi_ctrl->share_ctrl->rdi0FrameId = 0;
-	axi_ctrl->share_ctrl->rdi1FrameId = 0;
-	axi_ctrl->share_ctrl->rdi2FrameId = 0;
-}
-
-static void vfe40_program_dmi_cfg(
-	enum VFE40_DMI_RAM_SEL bankSel,
-	struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	/* set bit 8 for auto increment. */
-	uint32_t value = VFE_DMI_CFG_DEFAULT;
-	value += (uint32_t)bankSel;
-	CDBG("%s: banksel = %d\n", __func__, bankSel);
-
-	msm_camera_io_w(value, vfe40_ctrl->share_ctrl->vfebase +
-		VFE_DMI_CFG);
-	/* by default, always starts with offset 0.*/
-	msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase +
-		VFE_DMI_ADDR);
-}
-
-static void vfe40_reset_dmi_tables(
-	struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	int i = 0;
-
-	/* Reset Histogram LUTs */
-	CDBG("Reset Bayer histogram LUT : 0\n");
-	vfe40_program_dmi_cfg(STATS_BHIST_RAM0, vfe40_ctrl);
-	/* Loop for configuring LUT */
-	for (i = 0; i < 256; i++) {
-		msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase +
-			VFE_DMI_DATA_HI);
-		msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase +
-			VFE_DMI_DATA_LO);
-	}
-	vfe40_program_dmi_cfg(NO_MEM_SELECTED, vfe40_ctrl);
-
-	CDBG("Reset Bayer Histogram LUT: 1\n");
-	vfe40_program_dmi_cfg(STATS_BHIST_RAM1, vfe40_ctrl);
-	/* Loop for configuring LUT */
-	for (i = 0; i < 256; i++) {
-		msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase +
-			VFE_DMI_DATA_HI);
-		msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase +
-			VFE_DMI_DATA_LO);
-	}
-	vfe40_program_dmi_cfg(NO_MEM_SELECTED, vfe40_ctrl);
-
-	CDBG("Reset IHistogram LUT\n");
-	vfe40_program_dmi_cfg(STATS_IHIST_RAM, vfe40_ctrl);
-	/* Loop for configuring LUT */
-	for (i = 0; i < 256; i++) {
-		msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase +
-			VFE_DMI_DATA_HI);
-		msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase +
-			VFE_DMI_DATA_LO);
-	}
-	vfe40_program_dmi_cfg(NO_MEM_SELECTED, vfe40_ctrl);
-}
-
-static void vfe40_set_default_reg_values(
-	struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	msm_camera_io_w(0x800080,
-		vfe40_ctrl->share_ctrl->vfebase + VFE_DEMUX_GAIN_0);
-	msm_camera_io_w(0x800080,
-		vfe40_ctrl->share_ctrl->vfebase + VFE_DEMUX_GAIN_1);
-	msm_camera_io_w(0x198FFFFF,
-		vfe40_ctrl->share_ctrl->vfebase + VFE_CGC_OVERRIDE);
-
-	msm_camera_io_w(0,
-		vfe40_ctrl->share_ctrl->vfebase + VFE_CLAMP_ENC_MIN);
-	msm_camera_io_w(0xFFFFFF,
-		vfe40_ctrl->share_ctrl->vfebase + VFE_CLAMP_ENC_MAX);
-	msm_camera_io_w(0,
-		vfe40_ctrl->share_ctrl->vfebase + VFE_CLAMP_VIEW_MIN);
-	msm_camera_io_w(0xFFFFFF,
-		vfe40_ctrl->share_ctrl->vfebase + VFE_CLAMP_VIEW_MAX);
-
-	/* stats UB config */
-	CDBG("%s: Use bayer stats = %d\n", __func__,
-		 vfe40_use_bayer_stats(vfe40_ctrl));
-
-	msm_camera_io_w(0x82F80007,
-		vfe40_ctrl->share_ctrl->vfebase +
-			VFE_BUS_STATS_RS_WR_UB_CFG);
-	msm_camera_io_w(0x8300000F,
-		vfe40_ctrl->share_ctrl->vfebase +
-			VFE_BUS_STATS_CS_WR_UB_CFG);
-
-	msm_camera_io_w(0x8310003F,
-		vfe40_ctrl->share_ctrl->vfebase +
-			VFE_BUS_STATS_BG_WR_UB_CFG);
-	msm_camera_io_w(0x8350003F,
-		vfe40_ctrl->share_ctrl->vfebase +
-			VFE_BUS_STATS_BE_WR_UB_CFG);
-	msm_camera_io_w(0x8390003F,
-		vfe40_ctrl->share_ctrl->vfebase +
-			VFE_BUS_STATS_BF_WR_UB_CFG);
-
-	msm_camera_io_w(0x83D0000F,
-	vfe40_ctrl->share_ctrl->vfebase +
-			VFE_BUS_STATS_HIST_WR_UB_CFG);
-	msm_camera_io_w(0x83E0000F,
-		vfe40_ctrl->share_ctrl->vfebase +
-			VFE_BUS_STATS_SKIN_WR_UB_CFG);
-
-	msm_camera_io_w(0x83F0000F,
-		vfe40_ctrl->share_ctrl->vfebase +
-			VFE_BUS_STATS_AWB_WR_UB_CFG);
-
-	/* stats frame subsample config*/
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe40_ctrl->share_ctrl->vfebase +
-			VFE_BUS_STATS_HIST_WR_FRAMEDROP_PATTERN);
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe40_ctrl->share_ctrl->vfebase +
-			VFE_BUS_STATS_BG_WR_FRAMEDROP_PATTERN);
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe40_ctrl->share_ctrl->vfebase +
-			VFE_BUS_STATS_BE_WR_FRAMEDROP_PATTERN);
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe40_ctrl->share_ctrl->vfebase +
-			VFE_BUS_STATS_BF_WR_FRAMEDROP_PATTERN);
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe40_ctrl->share_ctrl->vfebase +
-			VFE_BUS_STATS_RS_WR_FRAMEDROP_PATTERN);
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe40_ctrl->share_ctrl->vfebase +
-			VFE_BUS_STATS_CS_WR_FRAMEDROP_PATTERN);
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe40_ctrl->share_ctrl->vfebase +
-			VFE_BUS_STATS_SKIN_WR_FRAMEDROP_PATTERN);
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe40_ctrl->share_ctrl->vfebase +
-			VFE_BUS_STATS_AWB_WR_FRAMEDROP_PATTERN);
-
-	/* stats irq subsample config*/
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe40_ctrl->share_ctrl->vfebase +
-			VFE_BUS_STATS_HIST_WR_IRQ_SUBSAMPLE_PATTERN);
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe40_ctrl->share_ctrl->vfebase +
-			VFE_BUS_STATS_BG_WR_IRQ_SUBSAMPLE_PATTERN);
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe40_ctrl->share_ctrl->vfebase +
-			VFE_BUS_STATS_BE_WR_IRQ_SUBSAMPLE_PATTERN);
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe40_ctrl->share_ctrl->vfebase +
-			VFE_BUS_STATS_BF_WR_IRQ_SUBSAMPLE_PATTERN);
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe40_ctrl->share_ctrl->vfebase +
-			VFE_BUS_STATS_RS_WR_IRQ_SUBSAMPLE_PATTERN);
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe40_ctrl->share_ctrl->vfebase +
-			VFE_BUS_STATS_CS_WR_IRQ_SUBSAMPLE_PATTERN);
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe40_ctrl->share_ctrl->vfebase +
-			VFE_BUS_STATS_SKIN_WR_IRQ_SUBSAMPLE_PATTERN);
-	msm_camera_io_w(0xFFFFFFFF,
-		vfe40_ctrl->share_ctrl->vfebase +
-			VFE_BUS_STATS_AWB_WR_IRQ_SUBSAMPLE_PATTERN);
-
-	vfe40_reset_dmi_tables(vfe40_ctrl);
-}
-
-static void vfe40_reset_internal_variables(
-	struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	/* Stats control variables. */
-	memset(&(vfe40_ctrl->bfStatsControl), 0,
-		sizeof(struct vfe_stats_control));
-
-	memset(&(vfe40_ctrl->awbStatsControl), 0,
-		sizeof(struct vfe_stats_control));
-
-	memset(&(vfe40_ctrl->bgStatsControl), 0,
-		sizeof(struct vfe_stats_control));
-
-	memset(&(vfe40_ctrl->beStatsControl), 0,
-		sizeof(struct vfe_stats_control));
-
-	memset(&(vfe40_ctrl->bhistStatsControl), 0,
-		sizeof(struct vfe_stats_control));
-
-	memset(&(vfe40_ctrl->ihistStatsControl), 0,
-		sizeof(struct vfe_stats_control));
-
-	memset(&(vfe40_ctrl->rsStatsControl), 0,
-		sizeof(struct vfe_stats_control));
-
-	memset(&(vfe40_ctrl->csStatsControl), 0,
-		sizeof(struct vfe_stats_control));
-
-	vfe40_ctrl->frame_skip_cnt = 31;
-	vfe40_ctrl->frame_skip_pattern = 0xffffffff;
-	vfe40_ctrl->snapshot_frame_cnt = 0;
-	vfe40_set_default_reg_values(vfe40_ctrl);
-}
-
-static int vfe40_reset(struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	uint32_t irq_mask;
-	atomic_set(&vfe40_ctrl->share_ctrl->vstate, 0);
-	msm_camera_io_w(VFE_MODULE_RESET_CMD,
-		vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_RESET);
-	msm_camera_io_w(0,
-		vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_RESET);
-
-	irq_mask =
-		msm_camera_io_r(vfe40_ctrl->share_ctrl->vfebase +
-			VFE_IRQ_MASK_0);
-	irq_mask &= ~(0x00FF0011|VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK_0);
-
-	/* enable reset_ack interrupt.  */
-	irq_mask |= VFE_IMASK_WHILE_STOPPING_0;
-	msm_camera_io_w(irq_mask, vfe40_ctrl->share_ctrl->vfebase +
-		VFE_IRQ_MASK_0);
-
-	msm_camera_io_w_mb(VFE_ONLY_RESET_CMD,
-		vfe40_ctrl->share_ctrl->vfebase + VFE_GLOBAL_RESET);
-
-	return wait_for_completion_interruptible(
-			&vfe40_ctrl->share_ctrl->reset_complete);
-}
-
-static int axi_reset(struct axi_ctrl_t *axi_ctrl)
-{
-	axi_reset_internal_variables(axi_ctrl);
-	/* disable all interrupts.  vfeImaskLocal is also reset to 0
-	* to begin with. */
-	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
-		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_0);
-
-	msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
-		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
-
-	/* clear all pending interrupts*/
-	msm_camera_io_w(VFE_CLEAR_ALL_IRQ0,
-		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_0);
-	msm_camera_io_w(VFE_CLEAR_ALL_IRQ1,
-		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_1);
-
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	msm_camera_io_w_mb(1, axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CMD);
-
-	/* enable reset_ack interrupt.  */
-	msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_0,
-		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_0);
-
-	/* Write to VFE_GLOBAL_RESET_CMD to reset the vfe hardware. Once reset
-	 * is done, hardware interrupt will be generated.  VFE ist processes
-	 * the interrupt to complete the function call.  Note that the reset
-	 * function is synchronous. */
-
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	msm_camera_io_w_mb(VFE_RESET_UPON_RESET_CMD,
-		axi_ctrl->share_ctrl->vfebase + VFE_GLOBAL_RESET);
-
-	return wait_for_completion_interruptible(
-			&axi_ctrl->share_ctrl->reset_complete);
-}
-
-static int vfe40_operation_config(uint32_t *cmd,
-			struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	uint32_t *p = cmd;
-
-	vfe40_ctrl->share_ctrl->stats_comp = *(++p);
-	vfe40_ctrl->hfr_mode = *(++p);
-
-	msm_camera_io_w(*(++p),
-		vfe40_ctrl->share_ctrl->vfebase + VFE_CFG);
-	msm_camera_io_w(*(++p),
-		vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-	msm_camera_io_w(*(++p),
-		vfe40_ctrl->share_ctrl->vfebase + VFE_REALIGN_BUF);
-	msm_camera_io_w(*(++p),
-		vfe40_ctrl->share_ctrl->vfebase + VFE_CHROMA_UP);
-	msm_camera_io_w(*(++p),
-		vfe40_ctrl->share_ctrl->vfebase + VFE_STATS_CFG);
-	return 0;
-}
-
-static unsigned long vfe40_stats_dqbuf(struct vfe40_ctrl_type *vfe40_ctrl,
-	enum msm_stats_enum_type stats_type)
-{
-	struct msm_stats_meta_buf *buf = NULL;
-	int rc = 0;
-	rc = vfe40_ctrl->stats_ops.dqbuf(
-			vfe40_ctrl->stats_ops.stats_ctrl, stats_type, &buf);
-	if (rc < 0) {
-		pr_err("%s: dq stats buf (type = %d) err = %d\n",
-			__func__, stats_type, rc);
-		return 0L;
-	}
-	return buf->paddr;
-}
-
-static unsigned long vfe40_stats_flush_enqueue(
-	struct vfe40_ctrl_type *vfe40_ctrl,
-	enum msm_stats_enum_type stats_type)
-{
-	struct msm_stats_bufq *bufq = NULL;
-	struct msm_stats_meta_buf *stats_buf = NULL;
-	int rc = 0;
-	int i;
-
-	/*
-	 * Passing NULL for ion client as the buffers are already
-	 * mapped at this stage, client is not required, flush all
-	 * the buffers, and buffers move to PREPARE state
-	 */
-
-	rc = vfe40_ctrl->stats_ops.bufq_flush(
-			vfe40_ctrl->stats_ops.stats_ctrl, stats_type, NULL);
-	if (rc < 0) {
-		pr_err("%s: dq stats buf (type = %d) err = %d",
-			__func__, stats_type, rc);
-		return 0L;
-	}
-	/* Queue all the buffers back to QUEUED state */
-	bufq = vfe40_ctrl->stats_ctrl.bufq[stats_type];
-	for (i = 0; i < bufq->num_bufs; i++) {
-		stats_buf = &bufq->bufs[i];
-		rc = vfe40_ctrl->stats_ops.enqueue_buf(
-				vfe40_ctrl->stats_ops.stats_ctrl,
-				&(stats_buf->info), NULL, -1);
-		if (rc < 0) {
-			pr_err("%s: dq stats buf (type = %d) err = %d",
-				 __func__, stats_type, rc);
-			return rc;
-		}
-	}
-	return 0L;
-}
-
-
-static unsigned long vfe40_stats_unregbuf(
-	struct vfe40_ctrl_type *vfe40_ctrl,
-	struct msm_stats_reqbuf *req_buf, int domain_num)
-{
-	int i = 0, rc = 0;
-
-	for (i = 0; i < req_buf->num_buf; i++) {
-		rc = vfe40_ctrl->stats_ops.buf_unprepare(
-			vfe40_ctrl->stats_ops.stats_ctrl,
-			req_buf->stats_type, i,
-			vfe40_ctrl->stats_ops.client, domain_num);
-		if (rc < 0) {
-			pr_err("%s: unreg stats buf (type = %d) err = %d",
-				__func__, req_buf->stats_type, rc);
-		return rc;
-		}
-	}
-	return 0L;
-}
-static int vfe_stats_awb_buf_init(
-	struct vfe40_ctrl_type *vfe40_ctrl,
-	struct vfe_cmd_stats_buf *in)
-{
-	uint32_t addr;
-	unsigned long flags;
-	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_AWB);
-	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq awb ping buf from free buf queue\n", __func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe40_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_AWB_WR_PING_ADDR);
-	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_AWB);
-	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq awb ping buf from free buf queue\n",
-			__func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe40_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_AWB_WR_PONG_ADDR);
-	return 0;
-}
-
-static uint32_t vfe_stats_be_buf_init(
-	struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	uint32_t addr;
-	unsigned long flags;
-	uint32_t stats_type;
-
-	stats_type = MSM_STATS_TYPE_BE;
-	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, stats_type);
-	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq BE ping buf from free buf queue\n",
-			__func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe40_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_BE_WR_PING_ADDR);
-	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, stats_type);
-	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq BE pong buf from free buf queue\n",
-			__func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe40_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_BE_WR_PONG_ADDR);
-	return 0;
-}
-
-static uint32_t vfe_stats_bg_buf_init(
-	struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	uint32_t addr;
-	unsigned long flags;
-	uint32_t stats_type;
-
-	stats_type = MSM_STATS_TYPE_BG;
-	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, stats_type);
-	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq aec/Bg ping buf from free buf queue\n",
-			__func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe40_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_BG_WR_PING_ADDR);
-	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, stats_type);
-	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq aec/Bg pong buf from free buf queue\n",
-			__func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe40_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_BG_WR_PONG_ADDR);
-	return 0;
-}
-
-static int vfe_stats_bf_buf_init(
-	struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	uint32_t addr;
-	unsigned long flags;
-	int rc = 0;
-
-	uint32_t stats_type;
-	stats_type = MSM_STATS_TYPE_BF;
-
-	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
-	rc = vfe40_stats_flush_enqueue(vfe40_ctrl, stats_type);
-	if (rc < 0) {
-		pr_err("%s: dq stats buf err = %d",
-			   __func__, rc);
-		spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
-		return -EINVAL;
-	}
-	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, stats_type);
-	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq af ping buf from free buf queue", __func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe40_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_BF_WR_PING_ADDR);
-	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, stats_type);
-	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq af pong buf from free buf queue", __func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe40_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_BF_WR_PONG_ADDR);
-	return 0;
-}
-
-static uint32_t vfe_stats_bhist_buf_init(
-	struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	uint32_t addr;
-	unsigned long flags;
-	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_BHIST);
-	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq ihist ping buf from free buf queue",
-			__func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe40_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_SKIN_WR_PING_ADDR);
-	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_BHIST);
-	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq ihist pong buf from free buf queue",
-			__func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe40_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_SKIN_WR_PONG_ADDR);
-
-	return 0;
-}
-
-static int vfe_stats_ihist_buf_init(
-	struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	uint32_t addr;
-	unsigned long flags;
-
-	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_IHIST);
-	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq ihist ping buf from free buf queue",
-			__func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe40_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_HIST_WR_PING_ADDR);
-	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_IHIST);
-	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq Ihist pong buf from free buf queue",
-			__func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe40_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_HIST_WR_PONG_ADDR);
-
-	return 0;
-}
-
-static int vfe_stats_rs_buf_init(
-	struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	uint32_t addr;
-	unsigned long flags;
-
-	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_RS);
-	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq rs ping buf from free buf queue", __func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe40_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_RS_WR_PING_ADDR);
-	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_RS);
-	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq rs pong buf from free buf queue", __func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe40_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_RS_WR_PONG_ADDR);
-	return 0;
-}
-
-static int vfe_stats_cs_buf_init(
-	struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	uint32_t addr;
-	unsigned long flags;
-	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_CS);
-	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq cs ping buf from free buf queue", __func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe40_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_CS_WR_PING_ADDR);
-	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_CS);
-	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
-	if (!addr) {
-		pr_err("%s: dq cs pong buf from free buf queue", __func__);
-		return -ENOMEM;
-	}
-	msm_camera_io_w(addr,
-		vfe40_ctrl->share_ctrl->vfebase +
-		VFE_BUS_STATS_CS_WR_PONG_ADDR);
-	return 0;
-}
-
-static void vfe40_cfg_qos_parms(struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	void __iomem *vfebase = vfe40_ctrl->share_ctrl->vfebase;
-	msm_camera_io_w(0xAAAAAAAA, vfebase + VFE_0_BUS_BDG_QOS_CFG_0);
-	msm_camera_io_w(0xAAAAAAAA, vfebase + VFE_0_BUS_BDG_QOS_CFG_1);
-	msm_camera_io_w(0xAAAAAAAA, vfebase + VFE_0_BUS_BDG_QOS_CFG_2);
-	msm_camera_io_w(0xAAAAAAAA, vfebase + VFE_0_BUS_BDG_QOS_CFG_3);
-	msm_camera_io_w(0xAAAAAAAA, vfebase + VFE_0_BUS_BDG_QOS_CFG_4);
-	msm_camera_io_w(0xAAAAAAAA, vfebase + VFE_0_BUS_BDG_QOS_CFG_5);
-	msm_camera_io_w(0xAAAAAAAA, vfebase + VFE_0_BUS_BDG_QOS_CFG_6);
-	msm_camera_io_w(0x0002AAAA, vfebase + VFE_0_BUS_BDG_QOS_CFG_7);
-}
-
-static void vfe40_start_common(struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	uint16_t vfe_operation_mode =
-		vfe40_ctrl->share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
-			VFE_OUTPUTS_RDI1);
-	CDBG("VFE opertaion mode = 0x%x, output mode = 0x%x\n",
-		vfe40_ctrl->share_ctrl->current_mode,
-		vfe40_ctrl->share_ctrl->outpath.output_mode);
-
-	vfe40_cfg_qos_parms(vfe40_ctrl);
-
-	msm_camera_io_w_mb(0x1,
-			vfe40_ctrl->share_ctrl->vfebase +
-			VFE_REG_UPDATE_CMD);
-
-	msm_camera_io_w_mb(0x00003fff,
-			vfe40_ctrl->share_ctrl->vfebase +
-			V40_AXI_BUS_CMD_OFF);
-	msm_camera_io_w_mb(1,
-			vfe40_ctrl->share_ctrl->vfebase +
-			V40_BUS_PM_CMD);
-	if (vfe_operation_mode) {
-		msm_camera_io_w_mb(1, vfe40_ctrl->share_ctrl->vfebase +
-			VFE_CAMIF_COMMAND);
-	}
-
-}
-
-static int vfe40_start_recording(
-	struct msm_cam_media_controller *pmctl,
-	struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	vfe40_ctrl->share_ctrl->recording_state = VFE_STATE_START_REQUESTED;
-	msm_camera_io_w_mb(1,
-		vfe40_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-	return 0;
-}
-
-static int vfe40_stop_recording(
-	struct msm_cam_media_controller *pmctl,
-	struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	vfe40_ctrl->share_ctrl->recording_state = VFE_STATE_STOP_REQUESTED;
-	msm_camera_io_w_mb(1,
-		vfe40_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-	return 0;
-}
-
-static void vfe40_start_liveshot(
-	struct msm_cam_media_controller *pmctl,
-	struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	/* Hardcode 1 live snapshot for now. */
-	vfe40_ctrl->share_ctrl->outpath.out0.capture_cnt = 1;
-	vfe40_ctrl->share_ctrl->vfe_capture_count =
-		vfe40_ctrl->share_ctrl->outpath.out0.capture_cnt;
-
-	vfe40_ctrl->share_ctrl->liveshot_state = VFE_STATE_START_REQUESTED;
-	msm_camera_io_w_mb(1, vfe40_ctrl->
-		share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-}
-
-static void vfe40_stop_liveshot(
-	struct msm_cam_media_controller *pmctl,
-	struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	vfe40_ctrl->share_ctrl->liveshot_state = VFE_STATE_STOP_REQUESTED;
-	msm_camera_io_w_mb(1,
-		vfe40_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-}
-
-static int vfe40_zsl(
-	struct msm_cam_media_controller *pmctl,
-	struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	vfe40_ctrl->share_ctrl->start_ack_pending = TRUE;
-	vfe40_start_common(vfe40_ctrl);
-
-	return 0;
-}
-static int vfe40_capture_raw(
-	struct msm_cam_media_controller *pmctl,
-	struct vfe40_ctrl_type *vfe40_ctrl,
-	uint32_t num_frames_capture)
-{
-	vfe40_ctrl->share_ctrl->outpath.out0.capture_cnt = num_frames_capture;
-	vfe40_ctrl->share_ctrl->vfe_capture_count = num_frames_capture;
-	vfe40_start_common(vfe40_ctrl);
-	return 0;
-}
-
-static int vfe40_capture(
-	struct msm_cam_media_controller *pmctl,
-	uint32_t num_frames_capture,
-	struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	/* capture command is valid for both idle and active state. */
-	vfe40_ctrl->share_ctrl->outpath.out1.capture_cnt = num_frames_capture;
-	if (vfe40_ctrl->share_ctrl->current_mode ==
-			VFE_OUTPUTS_MAIN_AND_THUMB ||
-		vfe40_ctrl->share_ctrl->current_mode ==
-			VFE_OUTPUTS_THUMB_AND_MAIN ||
-		vfe40_ctrl->share_ctrl->current_mode ==
-			VFE_OUTPUTS_JPEG_AND_THUMB ||
-		vfe40_ctrl->share_ctrl->current_mode ==
-			VFE_OUTPUTS_THUMB_AND_JPEG) {
-		vfe40_ctrl->share_ctrl->outpath.out0.capture_cnt =
-			num_frames_capture;
-	}
-
-	vfe40_ctrl->share_ctrl->vfe_capture_count = num_frames_capture;
-
-
-	vfe40_start_common(vfe40_ctrl);
-	/* for debug */
-	return 0;
-}
-
-static int vfe40_start(
-	struct msm_cam_media_controller *pmctl,
-	struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	vfe40_start_common(vfe40_ctrl);
-	return 0;
-}
-
-static void vfe40_update(struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	unsigned long flags;
-	uint32_t value = 0;
-	if (vfe40_ctrl->update_linear) {
-		if (!msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase +
-			V40_LINEARIZATION_OFF1))
-			msm_camera_io_w(1,
-				vfe40_ctrl->share_ctrl->vfebase +
-				V40_LINEARIZATION_OFF1);
-		else
-			msm_camera_io_w(0,
-				vfe40_ctrl->share_ctrl->vfebase +
-				V40_LINEARIZATION_OFF1);
-		vfe40_ctrl->update_linear = false;
-	}
-
-	if (vfe40_ctrl->update_la) {
-		if (!msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase + V40_LA_OFF))
-			msm_camera_io_w(1,
-				vfe40_ctrl->share_ctrl->vfebase + V40_LA_OFF);
-		else
-			msm_camera_io_w(0,
-				vfe40_ctrl->share_ctrl->vfebase + V40_LA_OFF);
-		vfe40_ctrl->update_la = false;
-	}
-
-	if (vfe40_ctrl->update_gamma) {
-		value = msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase + V40_RGB_G_OFF);
-		value ^= V40_GAMMA_LUT_BANK_SEL_MASK;
-		msm_camera_io_w(value,
-			vfe40_ctrl->share_ctrl->vfebase + V40_RGB_G_OFF);
-		vfe40_ctrl->update_gamma = false;
-	}
-
-	spin_lock_irqsave(&vfe40_ctrl->share_ctrl->update_ack_lock, flags);
-	vfe40_ctrl->share_ctrl->update_ack_pending = TRUE;
-	spin_unlock_irqrestore(&vfe40_ctrl->share_ctrl->update_ack_lock, flags);
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	msm_camera_io_w_mb(1,
-		vfe40_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-	return;
-}
-
-static void vfe40_sync_timer_stop(struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	uint32_t value = 0;
-	vfe40_ctrl->sync_timer_state = 0;
-	if (vfe40_ctrl->sync_timer_number == 0)
-		value = 0x10000;
-	else if (vfe40_ctrl->sync_timer_number == 1)
-		value = 0x20000;
-	else if (vfe40_ctrl->sync_timer_number == 2)
-		value = 0x40000;
-
-	/* Timer Stop */
-	msm_camera_io_w(value,
-		vfe40_ctrl->share_ctrl->vfebase + V40_SYNC_TIMER_OFF);
-}
-
-static void vfe40_sync_timer_start(
-	const uint32_t *tbl,
-	struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	/* set bit 8 for auto increment. */
-	uint32_t value = 1;
-	uint32_t val;
-
-	vfe40_ctrl->sync_timer_state = *tbl++;
-	vfe40_ctrl->sync_timer_repeat_count = *tbl++;
-	vfe40_ctrl->sync_timer_number = *tbl++;
-	CDBG("%s timer_state %d, repeat_cnt %d timer number %d\n",
-		 __func__, vfe40_ctrl->sync_timer_state,
-		 vfe40_ctrl->sync_timer_repeat_count,
-		 vfe40_ctrl->sync_timer_number);
-
-	if (vfe40_ctrl->sync_timer_state) { /* Start Timer */
-		value = value << vfe40_ctrl->sync_timer_number;
-	} else { /* Stop Timer */
-		CDBG("Failed to Start timer\n");
-		return;
-	}
-
-	/* Timer Start */
-	msm_camera_io_w(value,
-		vfe40_ctrl->share_ctrl->vfebase + V40_SYNC_TIMER_OFF);
-	/* Sync Timer Line Start */
-	value = *tbl++;
-	msm_camera_io_w(value,
-		vfe40_ctrl->share_ctrl->vfebase + V40_SYNC_TIMER_OFF +
-		4 + ((vfe40_ctrl->sync_timer_number) * 12));
-	/* Sync Timer Pixel Start */
-	value = *tbl++;
-	msm_camera_io_w(value,
-			vfe40_ctrl->share_ctrl->vfebase + V40_SYNC_TIMER_OFF +
-			 8 + ((vfe40_ctrl->sync_timer_number) * 12));
-	/* Sync Timer Pixel Duration */
-	value = *tbl++;
-	val = vfe_clk_rate / 10000;
-	val = 10000000 / val;
-	val = value * 10000 / val;
-	CDBG("%s: Pixel Clk Cycles!!! %d\n", __func__, val);
-	msm_camera_io_w(val,
-		vfe40_ctrl->share_ctrl->vfebase + V40_SYNC_TIMER_OFF +
-		12 + ((vfe40_ctrl->sync_timer_number) * 12));
-	/* Timer0 Active High/LOW */
-	value = *tbl++;
-	msm_camera_io_w(value,
-		vfe40_ctrl->share_ctrl->vfebase + V40_SYNC_TIMER_POLARITY_OFF);
-	/* Selects sync timer 0 output to drive onto timer1 port */
-	value = 0;
-	msm_camera_io_w(value,
-		vfe40_ctrl->share_ctrl->vfebase + V40_TIMER_SELECT_OFF);
-}
-
-
-static void vfe40_write_gamma_cfg(
-	enum VFE40_DMI_RAM_SEL channel_sel,
-	const uint32_t *tbl,
-	struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	int i;
-	uint32_t value, value1, value2;
-	vfe40_program_dmi_cfg(channel_sel, vfe40_ctrl);
-	for (i = 0 ; i < (VFE40_GAMMA_NUM_ENTRIES/2) ; i++) {
-		value = *tbl++;
-		value1 = value & 0x0000FFFF;
-		value2 = (value & 0xFFFF0000)>>16;
-		msm_camera_io_w((value1),
-			vfe40_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
-		msm_camera_io_w((value2),
-			vfe40_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
-	}
-	vfe40_program_dmi_cfg(NO_MEM_SELECTED, vfe40_ctrl);
-}
-
-static void vfe40_read_gamma_cfg(
-	enum VFE40_DMI_RAM_SEL channel_sel,
-	uint32_t *tbl,
-	struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	int i;
-	vfe40_program_dmi_cfg(channel_sel, vfe40_ctrl);
-	CDBG("%s: Gamma table channel: %d\n", __func__, channel_sel);
-	for (i = 0 ; i < VFE40_GAMMA_NUM_ENTRIES ; i++) {
-		*tbl = msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
-		CDBG("%s: %08x\n", __func__, *tbl);
-		tbl++;
-	}
-	vfe40_program_dmi_cfg(NO_MEM_SELECTED, vfe40_ctrl);
-}
-
-static void vfe40_write_la_cfg(
-	enum VFE40_DMI_RAM_SEL channel_sel,
-	const uint32_t *tbl,
-	struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	uint32_t i;
-	uint32_t value, value1, value2;
-
-	vfe40_program_dmi_cfg(channel_sel, vfe40_ctrl);
-	for (i = 0 ; i < (VFE40_LA_TABLE_LENGTH/2) ; i++) {
-		value = *tbl++;
-		value1 = value & 0x0000FFFF;
-		value2 = (value & 0xFFFF0000)>>16;
-		msm_camera_io_w((value1),
-			vfe40_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
-		msm_camera_io_w((value2),
-			vfe40_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
-	}
-	vfe40_program_dmi_cfg(NO_MEM_SELECTED, vfe40_ctrl);
-}
-
-static struct vfe40_output_ch *vfe40_get_ch(
-	int path, struct vfe_share_ctrl_t *share_ctrl)
-{
-	struct vfe40_output_ch *ch = NULL;
-
-	if (path == VFE_MSG_OUTPUT_PRIMARY)
-		ch = &share_ctrl->outpath.out0;
-	else if (path == VFE_MSG_OUTPUT_SECONDARY)
-		ch = &share_ctrl->outpath.out1;
-	else if (path == VFE_MSG_OUTPUT_TERTIARY1)
-		ch = &share_ctrl->outpath.out2;
-	else if (path == VFE_MSG_OUTPUT_TERTIARY2)
-		ch = &share_ctrl->outpath.out3;
-	else
-		pr_err("%s: Invalid path %d\n", __func__,
-			path);
-
-	BUG_ON(ch == NULL);
-	return ch;
-}
-static struct msm_free_buf *vfe40_check_free_buffer(
-	int id, int path, struct axi_ctrl_t *axi_ctrl)
-{
-	struct vfe40_output_ch *outch = NULL;
-	struct msm_free_buf *b = NULL;
-	uint32_t inst_handle = 0;
-
-	if (path == VFE_MSG_OUTPUT_PRIMARY)
-		inst_handle = axi_ctrl->share_ctrl->outpath.out0.inst_handle;
-	else if (path == VFE_MSG_OUTPUT_SECONDARY)
-		inst_handle = axi_ctrl->share_ctrl->outpath.out1.inst_handle;
-	else if (path == VFE_MSG_OUTPUT_TERTIARY1)
-		inst_handle = axi_ctrl->share_ctrl->outpath.out2.inst_handle;
-	else if (path == VFE_MSG_OUTPUT_TERTIARY2)
-		inst_handle = axi_ctrl->share_ctrl->outpath.out3.inst_handle;
-
-	vfe40_subdev_notify(id, path, inst_handle,
-		&axi_ctrl->subdev, axi_ctrl->share_ctrl);
-	outch = vfe40_get_ch(path, axi_ctrl->share_ctrl);
-	if (outch->free_buf.ch_paddr[0])
-		b = &outch->free_buf;
-	return b;
-}
-static int configure_pingpong_buffers(
-	int id, int path, struct axi_ctrl_t *axi_ctrl)
-{
-	struct vfe40_output_ch *outch = NULL;
-	int rc = 0;
-	uint32_t inst_handle = 0;
-	if (path == VFE_MSG_OUTPUT_PRIMARY)
-		inst_handle = axi_ctrl->share_ctrl->outpath.out0.inst_handle;
-	else if (path == VFE_MSG_OUTPUT_SECONDARY)
-		inst_handle = axi_ctrl->share_ctrl->outpath.out1.inst_handle;
-	else if (path == VFE_MSG_OUTPUT_TERTIARY1)
-		inst_handle = axi_ctrl->share_ctrl->outpath.out2.inst_handle;
-	else if (path == VFE_MSG_OUTPUT_TERTIARY2)
-		inst_handle = axi_ctrl->share_ctrl->outpath.out3.inst_handle;
-
-	vfe40_subdev_notify(id, path, inst_handle,
-		&axi_ctrl->subdev, axi_ctrl->share_ctrl);
-	outch = vfe40_get_ch(path, axi_ctrl->share_ctrl);
-	if (outch->ping.ch_paddr[0] && outch->pong.ch_paddr[0]) {
-		/* Configure Preview Ping Pong */
-		pr_info("%s Configure ping/pong address for %d\n",
-						__func__, path);
-		vfe40_put_ch_ping_addr(
-			axi_ctrl->share_ctrl->vfebase, outch->ch0,
-			outch->ping.ch_paddr[0]);
-		vfe40_put_ch_pong_addr(
-			axi_ctrl->share_ctrl->vfebase, outch->ch0,
-			outch->pong.ch_paddr[0]);
-
-		if ((axi_ctrl->share_ctrl->current_mode !=
-			VFE_OUTPUTS_RAW) && (path != VFE_MSG_OUTPUT_TERTIARY1)
-			&& (path != VFE_MSG_OUTPUT_TERTIARY2)) {
-			vfe40_put_ch_ping_addr(
-				axi_ctrl->share_ctrl->vfebase, outch->ch1,
-				outch->ping.ch_paddr[1]);
-			vfe40_put_ch_pong_addr(
-				axi_ctrl->share_ctrl->vfebase, outch->ch1,
-				outch->pong.ch_paddr[1]);
-		}
-
-		if (outch->ping.num_planes > 2)
-			vfe40_put_ch_ping_addr(
-				axi_ctrl->share_ctrl->vfebase, outch->ch2,
-				outch->ping.ch_paddr[2]);
-		if (outch->pong.num_planes > 2)
-			vfe40_put_ch_pong_addr(
-				axi_ctrl->share_ctrl->vfebase, outch->ch2,
-				outch->pong.ch_paddr[2]);
-
-		/* avoid stale info */
-		memset(&outch->ping, 0, sizeof(struct msm_free_buf));
-		memset(&outch->pong, 0, sizeof(struct msm_free_buf));
-	} else {
-		pr_err("%s ping/pong addr is null!!", __func__);
-		rc = -EINVAL;
-	}
-	return rc;
-}
-
-static void vfe40_write_linear_cfg(
-	enum VFE40_DMI_RAM_SEL channel_sel,
-	const uint32_t *tbl, struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	uint32_t i;
-
-	vfe40_program_dmi_cfg(channel_sel, vfe40_ctrl);
-	/* for loop for configuring LUT. */
-	for (i = 0 ; i < VFE40_LINEARIZATON_TABLE_LENGTH ; i++) {
-		msm_camera_io_w(*tbl,
-			vfe40_ctrl->share_ctrl->vfebase + VFE_DMI_DATA_LO);
-		tbl++;
-	}
-	CDBG("done writing to linearization table\n");
-	vfe40_program_dmi_cfg(NO_MEM_SELECTED, vfe40_ctrl);
-}
-
-static void vfe40_send_isp_msg(
-	struct v4l2_subdev *sd,
-	uint32_t vfeFrameId,
-	uint32_t isp_msg_id)
-{
-	struct isp_msg_event isp_msg_evt;
-
-	isp_msg_evt.msg_id = isp_msg_id;
-	isp_msg_evt.sof_count = vfeFrameId;
-	v4l2_subdev_notify(sd,
-			NOTIFY_ISP_MSG_EVT,
-			(void *)&isp_msg_evt);
-}
-
-static int vfe40_proc_general(
-	struct msm_cam_media_controller *pmctl,
-	struct msm_isp_cmd *cmd,
-	struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	int i , rc = 0;
-	uint32_t old_val = 0 , new_val = 0, module_val = 0;
-	uint32_t *cmdp = NULL;
-	uint32_t *cmdp_local = NULL;
-	uint32_t snapshot_cnt = 0;
-	uint32_t temp1 = 0, temp2 = 0;
-	struct msm_camera_vfe_params_t vfe_params;
-
-	CDBG("vfe40_proc_general: cmdID = %s, length = %d\n",
-		vfe40_general_cmd[cmd->id], cmd->length);
-	switch (cmd->id) {
-	case VFE_CMD_RESET:
-		pr_info("vfe40_proc_general: cmdID = %s\n",
-			vfe40_general_cmd[cmd->id]);
-		vfe40_ctrl->share_ctrl->vfe_reset_flag = true;
-		vfe40_reset(vfe40_ctrl);
-		break;
-	case VFE_CMD_START:
-		pr_info("vfe40_proc_general: cmdID = %s\n",
-			vfe40_general_cmd[cmd->id]);
-		if (copy_from_user(&vfe_params,
-				(void __user *)(cmd->value),
-				sizeof(struct msm_camera_vfe_params_t))) {
-				rc = -EFAULT;
-				goto proc_general_done;
-		}
-
-		vfe40_ctrl->share_ctrl->current_mode =
-			vfe_params.operation_mode;
-
-		rc = vfe40_start(pmctl, vfe40_ctrl);
-		break;
-	case VFE_CMD_UPDATE:
-		vfe40_update(vfe40_ctrl);
-		break;
-	case VFE_CMD_CAPTURE_RAW:
-		pr_info("%s: cmdID = VFE_CMD_CAPTURE_RAW\n", __func__);
-		if (copy_from_user(&vfe_params,
-				(void __user *)(cmd->value),
-				sizeof(struct msm_camera_vfe_params_t))) {
-				rc = -EFAULT;
-				goto proc_general_done;
-		}
-
-		snapshot_cnt = vfe_params.capture_count;
-		vfe40_ctrl->share_ctrl->current_mode =
-			vfe_params.operation_mode;
-		rc = vfe40_capture_raw(pmctl, vfe40_ctrl, snapshot_cnt);
-		break;
-	case VFE_CMD_CAPTURE:
-		pr_info("%s: cmdID = VFE_CMD_CAPTURE\n", __func__);
-		if (copy_from_user(&vfe_params,
-				(void __user *)(cmd->value),
-				sizeof(struct msm_camera_vfe_params_t))) {
-				rc = -EFAULT;
-				goto proc_general_done;
-		}
-
-		snapshot_cnt = vfe_params.capture_count;
-		vfe40_ctrl->share_ctrl->current_mode =
-			vfe_params.operation_mode;
-
-		rc = vfe40_capture(pmctl, snapshot_cnt, vfe40_ctrl);
-		break;
-	case VFE_CMD_START_RECORDING:
-		pr_info("vfe40_proc_general: cmdID = %s\n",
-			vfe40_general_cmd[cmd->id]);
-		rc = vfe40_start_recording(pmctl, vfe40_ctrl);
-		break;
-	case VFE_CMD_STOP_RECORDING:
-		pr_info("vfe40_proc_general: cmdID = %s\n",
-			vfe40_general_cmd[cmd->id]);
-		rc = vfe40_stop_recording(pmctl, vfe40_ctrl);
-		break;
-	case VFE_CMD_OPERATION_CFG: {
-		if (cmd->length != V40_OPERATION_CFG_LEN) {
-			rc = -EINVAL;
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(V40_OPERATION_CFG_LEN, GFP_ATOMIC);
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			V40_OPERATION_CFG_LEN)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		rc = vfe40_operation_config(cmdp, vfe40_ctrl);
-		}
-		break;
-
-	case VFE_CMD_STATS_AE_START: {
-		if (vfe40_use_bayer_stats(vfe40_ctrl)) {
-			/* Error */
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		rc = vfe_stats_bg_buf_init(vfe40_ctrl);
-		if (rc < 0) {
-			pr_err("%s: cannot config ping/pong address of AEC",
-				 __func__);
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		old_val = msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val |= BG_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase +
-			vfe40_cmd[cmd->id].offset,
-			cmdp, (vfe40_cmd[cmd->id].length));
-		}
-		break;
-	case VFE_CMD_STATS_AF_START: {
-		if (vfe40_use_bayer_stats(vfe40_ctrl)) {
-			/* Error */
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		rc = vfe_stats_bf_buf_init(vfe40_ctrl);
-		if (rc < 0) {
-			pr_err("%s: cannot config ping/pong address of AF",
-				__func__);
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		old_val = msm_camera_io_r(vfe40_ctrl->share_ctrl->vfebase +
-			VFE_MODULE_CFG);
-		old_val |= BF_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase +
-			vfe40_cmd[cmd->id].offset,
-			cmdp, (vfe40_cmd[cmd->id].length));
-		}
-		break;
-	case VFE_CMD_STATS_AWB_START: {
-		rc = vfe_stats_awb_buf_init(vfe40_ctrl, NULL);
-		if (rc < 0) {
-			pr_err("%s: cannot config ping/pong address of AWB",
-				 __func__);
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		old_val = msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val |= AWB_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase +
-			vfe40_cmd[cmd->id].offset,
-			cmdp, (vfe40_cmd[cmd->id].length));
-		}
-		break;
-
-	case VFE_CMD_STATS_IHIST_START: {
-		rc = vfe_stats_ihist_buf_init(vfe40_ctrl);
-		if (rc < 0) {
-			pr_err("%s: cannot config ping/pong address of IHIST",
-				 __func__);
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		old_val = msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val |= IHIST_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase +
-			vfe40_cmd[cmd->id].offset,
-			cmdp, (vfe40_cmd[cmd->id].length));
-		}
-		break;
-
-
-	case VFE_CMD_STATS_RS_START: {
-		rc = vfe_stats_rs_buf_init(vfe40_ctrl);
-		if (rc < 0) {
-			pr_err("%s: cannot config ping/pong address of RS",
-				__func__);
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase +
-			vfe40_cmd[cmd->id].offset,
-			cmdp, (vfe40_cmd[cmd->id].length));
-		}
-		break;
-
-	case VFE_CMD_STATS_CS_START: {
-		rc = vfe_stats_cs_buf_init(vfe40_ctrl);
-		if (rc < 0) {
-			pr_err("%s: cannot config ping/pong address of CS",
-				__func__);
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase +
-			vfe40_cmd[cmd->id].offset,
-			cmdp, (vfe40_cmd[cmd->id].length));
-		}
-		break;
-
-	case VFE_CMD_STATS_BG_START:
-	case VFE_CMD_STATS_BE_START:
-	case VFE_CMD_STATS_BF_START:
-	case VFE_CMD_STATS_BHIST_START: {
-		old_val = msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase + VFE_STATS_CFG);
-		module_val = msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-
-		if (VFE_CMD_STATS_BE_START == cmd->id) {
-			module_val |= BE_ENABLE_MASK;
-			rc = vfe_stats_be_buf_init(vfe40_ctrl);
-			if (rc < 0) {
-				pr_err("%s: cannot config ping/pong address of BG",
-					__func__);
-				goto proc_general_done;
-			}
-		} else if (VFE_CMD_STATS_BG_START == cmd->id) {
-			module_val |= BG_ENABLE_MASK;
-			rc = vfe_stats_bg_buf_init(vfe40_ctrl);
-			if (rc < 0) {
-				pr_err("%s: cannot config ping/pong address of BG",
-					__func__);
-				goto proc_general_done;
-			}
-		} else if (VFE_CMD_STATS_BF_START == cmd->id) {
-			module_val |= BF_ENABLE_MASK;
-			rc = vfe_stats_bf_buf_init(vfe40_ctrl);
-			if (rc < 0) {
-				pr_err("%s: cannot config ping/pong address of BF",
-					__func__);
-				goto proc_general_done;
-			}
-		} else {
-			module_val |= BHIST_ENABLE_MASK;
-			old_val |= STATS_BHIST_ENABLE_MASK;
-			rc = vfe_stats_bhist_buf_init(vfe40_ctrl);
-			if (rc < 0) {
-				pr_err("%s: cannot config ping/pong address of BHist",
-					__func__);
-				goto proc_general_done;
-			}
-		}
-		msm_camera_io_w(old_val, vfe40_ctrl->share_ctrl->vfebase +
-			VFE_STATS_CFG);
-		msm_camera_io_w(module_val,
-			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-				(void __user *)(cmd->value),
-				cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase +
-			vfe40_cmd[cmd->id].offset,
-			cmdp, (vfe40_cmd[cmd->id].length));
-		}
-		break;
-	case VFE_CMD_MCE_UPDATE:
-	case VFE_CMD_MCE_CFG:{
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		/* Incrementing with 4 so as to point to the 2nd Register as
-		the 2nd register has the mce_enable bit */
-		old_val = msm_camera_io_r(vfe40_ctrl->share_ctrl->vfebase +
-			V40_CHROMA_SUP_OFF + 4);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		new_val = *cmdp_local;
-		old_val &= MCE_EN_MASK;
-		new_val = new_val | old_val;
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase +
-			V40_CHROMA_SUP_OFF + 4, &new_val, 4);
-		cmdp_local += 1;
-
-		old_val = msm_camera_io_r(vfe40_ctrl->share_ctrl->vfebase +
-			V40_CHROMA_SUP_OFF + 8);
-		new_val = *cmdp_local;
-		old_val &= MCE_Q_K_MASK;
-		new_val = new_val | old_val;
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase +
-			V40_CHROMA_SUP_OFF + 8, &new_val, 4);
-		cmdp_local += 1;
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase +
-			vfe40_cmd[cmd->id].offset,
-			cmdp_local, (vfe40_cmd[cmd->id].length));
-		}
-		break;
-	case VFE_CMD_CHROMA_SUP_UPDATE:
-	case VFE_CMD_CHROMA_SUP_CFG:{
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		msm_camera_io_memcpy(vfe40_ctrl->share_ctrl->vfebase +
-			V40_CHROMA_SUP_OFF, cmdp_local, 4);
-
-		cmdp_local += 1;
-		new_val = *cmdp_local;
-		/* Incrementing with 4 so as to point to the 2nd Register as
-		 * the 2nd register has the mce_enable bit
-		 */
-		old_val = msm_camera_io_r(vfe40_ctrl->share_ctrl->vfebase +
-			V40_CHROMA_SUP_OFF + 4);
-		old_val &= ~MCE_EN_MASK;
-		new_val = new_val | old_val;
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase +
-			V40_CHROMA_SUP_OFF + 4, &new_val, 4);
-		cmdp_local += 1;
-
-		old_val = msm_camera_io_r(vfe40_ctrl->share_ctrl->vfebase +
-			V40_CHROMA_SUP_OFF + 8);
-		new_val = *cmdp_local;
-		old_val &= ~MCE_Q_K_MASK;
-		new_val = new_val | old_val;
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase +
-			V40_CHROMA_SUP_OFF + 8, &new_val, 4);
-		}
-		break;
-	case VFE_CMD_BLACK_LEVEL_CFG:
-		rc = -EFAULT;
-		goto proc_general_done;
-
-	case VFE_CMD_MESH_ROLL_OFF_CFG: {
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value) , cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase +
-			vfe40_cmd[cmd->id].offset,
-			cmdp_local, V40_MESH_ROLL_OFF_CFG_LEN);
-		cmdp_local += 9;
-		vfe40_program_dmi_cfg(ROLLOFF_RAM0_BANK0, vfe40_ctrl);
-		/* for loop for extrcting table. */
-		for (i = 0; i < (V40_MESH_ROLL_OFF_TABLE_SIZE * 2); i++) {
-			msm_camera_io_w(*cmdp_local,
-				vfe40_ctrl->share_ctrl->vfebase +
-				VFE_DMI_DATA_LO);
-			cmdp_local++;
-		}
-		CDBG("done writing mesh table\n");
-		vfe40_program_dmi_cfg(NO_MEM_SELECTED, vfe40_ctrl);
-	}
-	break;
-	case VFE_CMD_GET_MESH_ROLLOFF_TABLE:
-		break;
-
-	case VFE_CMD_LA_CFG:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase +
-			vfe40_cmd[cmd->id].offset,
-			cmdp_local, (vfe40_cmd[cmd->id].length));
-
-		cmdp_local += 1;
-		vfe40_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK0,
-						   cmdp_local, vfe40_ctrl);
-		break;
-
-	case VFE_CMD_LA_UPDATE: {
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-
-		cmdp_local = cmdp + 1;
-		old_val = msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase + V40_LA_OFF);
-		if (old_val != 0x0)
-			vfe40_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK0,
-				cmdp_local, vfe40_ctrl);
-		else
-			vfe40_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK1,
-				cmdp_local, vfe40_ctrl);
-		}
-		vfe40_ctrl->update_la = true;
-		break;
-
-	case VFE_CMD_GET_LA_TABLE:
-		temp1 = sizeof(uint32_t) * VFE40_LA_TABLE_LENGTH / 2;
-		if (cmd->length != temp1) {
-			rc = -EINVAL;
-			goto proc_general_done;
-		}
-		cmdp = kzalloc(temp1, GFP_KERNEL);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		if (msm_camera_io_r(vfe40_ctrl->
-				share_ctrl->vfebase + V40_LA_OFF))
-			vfe40_program_dmi_cfg(LUMA_ADAPT_LUT_RAM_BANK1,
-						vfe40_ctrl);
-		else
-			vfe40_program_dmi_cfg(LUMA_ADAPT_LUT_RAM_BANK0,
-						vfe40_ctrl);
-		for (i = 0 ; i < (VFE40_LA_TABLE_LENGTH / 2) ; i++) {
-			*cmdp_local =
-				msm_camera_io_r(
-					vfe40_ctrl->share_ctrl->vfebase +
-					VFE_DMI_DATA_LO);
-			*cmdp_local |= (msm_camera_io_r(
-				vfe40_ctrl->share_ctrl->vfebase +
-				VFE_DMI_DATA_LO)) << 16;
-			cmdp_local++;
-		}
-		vfe40_program_dmi_cfg(NO_MEM_SELECTED, vfe40_ctrl);
-		if (copy_to_user((void __user *)(cmd->value), cmdp,
-			temp1)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		break;
-	case VFE_CMD_SK_ENHAN_CFG:
-	case VFE_CMD_SK_ENHAN_UPDATE:{
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase + V40_SCE_OFF,
-			cmdp, V40_SCE_LEN);
-		}
-		break;
-
-	case VFE_CMD_LIVESHOT:
-		/* Configure primary channel */
-		vfe40_start_liveshot(pmctl, vfe40_ctrl);
-		break;
-
-	case VFE_CMD_LINEARIZATION_CFG:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp, (void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase +
-			V40_LINEARIZATION_OFF1,
-			cmdp_local, V40_LINEARIZATION_LEN1);
-		cmdp_local = cmdp + 17;
-		vfe40_write_linear_cfg(BLACK_LUT_RAM_BANK0,
-					cmdp_local, vfe40_ctrl);
-		break;
-
-	case VFE_CMD_LINEARIZATION_UPDATE:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp, (void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		cmdp_local++;
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase +
-			V40_LINEARIZATION_OFF1 + 4,
-			cmdp_local, (V40_LINEARIZATION_LEN1 - 4));
-		cmdp_local = cmdp + 17;
-		/*extracting the bank select*/
-		old_val = msm_camera_io_r(
-				vfe40_ctrl->share_ctrl->vfebase +
-				V40_LINEARIZATION_OFF1);
-
-		if (old_val != 0x0)
-			vfe40_write_linear_cfg(BLACK_LUT_RAM_BANK0,
-						cmdp_local, vfe40_ctrl);
-		else
-			vfe40_write_linear_cfg(BLACK_LUT_RAM_BANK1,
-						cmdp_local, vfe40_ctrl);
-		vfe40_ctrl->update_linear = true;
-		break;
-
-	case VFE_CMD_GET_LINEARIZATON_TABLE:
-		temp1 = sizeof(uint32_t) * VFE40_LINEARIZATON_TABLE_LENGTH;
-		if (cmd->length != temp1) {
-			rc = -EINVAL;
-			goto proc_general_done;
-		}
-		cmdp = kzalloc(temp1, GFP_KERNEL);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		if (msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase +
-			V40_LINEARIZATION_OFF1))
-			vfe40_program_dmi_cfg(BLACK_LUT_RAM_BANK1, vfe40_ctrl);
-		else
-			vfe40_program_dmi_cfg(BLACK_LUT_RAM_BANK0, vfe40_ctrl);
-		CDBG("%s: Linearization Table\n", __func__);
-		for (i = 0 ; i < VFE40_LINEARIZATON_TABLE_LENGTH ; i++) {
-			*cmdp_local = msm_camera_io_r(
-				vfe40_ctrl->share_ctrl->vfebase +
-				VFE_DMI_DATA_LO);
-			CDBG("%s: %08x\n", __func__, *cmdp_local);
-			cmdp_local++;
-		}
-		vfe40_program_dmi_cfg(NO_MEM_SELECTED, vfe40_ctrl);
-		if (copy_to_user((void __user *)(cmd->value), cmdp,
-			temp1)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		break;
-	case VFE_CMD_DEMOSAICV3:
-		if (cmd->length !=
-			V40_DEMOSAICV3_0_LEN+V40_DEMOSAICV3_1_LEN) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		new_val = *cmdp_local;
-
-		old_val = msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase + V40_DEMOSAICV3_0_OFF);
-		old_val &= DEMOSAIC_MASK;
-		new_val = new_val | old_val;
-		*cmdp_local = new_val;
-
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase + V40_DEMOSAICV3_0_OFF,
-			cmdp_local, V40_DEMOSAICV3_0_LEN);
-		cmdp_local += 1;
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase + V40_DEMOSAICV3_1_OFF,
-			cmdp_local, V40_DEMOSAICV3_1_LEN);
-		break;
-
-	case VFE_CMD_DEMOSAICV3_UPDATE:
-		if (cmd->length !=
-			V40_DEMOSAICV3_0_LEN * V40_DEMOSAICV3_UP_REG_CNT) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		new_val = *cmdp_local;
-
-		old_val = msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase + V40_DEMOSAICV3_0_OFF);
-		old_val &= DEMOSAIC_MASK;
-		new_val = new_val | old_val;
-		*cmdp_local = new_val;
-
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase + V40_DEMOSAICV3_0_OFF,
-			cmdp_local, V40_DEMOSAICV3_0_LEN);
-		/* As the address space is not contiguous increment by 2
-		 * before copying to next address space */
-		cmdp_local += 1;
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase + V40_DEMOSAICV3_1_OFF,
-			cmdp_local, 2 * V40_DEMOSAICV3_0_LEN);
-		/* As the address space is not contiguous increment by 2
-		 * before copying to next address space */
-		cmdp_local += 2;
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase + V40_DEMOSAICV3_2_OFF,
-			cmdp_local, 2 * V40_DEMOSAICV3_0_LEN);
-		break;
-
-	case VFE_CMD_DEMOSAICV3_ABCC_CFG:
-		rc = -EFAULT;
-		break;
-
-	case VFE_CMD_DEMOSAICV3_ABF_UPDATE:/* 116 ABF update  */
-	case VFE_CMD_DEMOSAICV3_ABF_CFG: { /* 108 ABF config  */
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		new_val = *cmdp_local;
-
-		old_val = msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase + V40_DEMOSAICV3_0_OFF);
-		old_val &= ABF_MASK;
-		new_val = new_val | old_val;
-		*cmdp_local = new_val;
-
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase + V40_DEMOSAICV3_0_OFF,
-			cmdp_local, 4);
-
-		cmdp_local += 1;
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase +
-			vfe40_cmd[cmd->id].offset,
-			cmdp_local, (vfe40_cmd[cmd->id].length));
-		}
-		break;
-
-	case VFE_CMD_DEMOSAICV3_DBCC_CFG:
-	case VFE_CMD_DEMOSAICV3_DBCC_UPDATE:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		new_val = *cmdp_local;
-
-		old_val = msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase + V40_DEMOSAICV3_0_OFF);
-		old_val &= DBCC_MASK;
-
-		new_val = new_val | old_val;
-		*cmdp_local = new_val;
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase + V40_DEMOSAICV3_0_OFF,
-			cmdp_local, 4);
-		cmdp_local += 1;
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase +
-			vfe40_cmd[cmd->id].offset,
-			cmdp_local, (vfe40_cmd[cmd->id].length));
-		break;
-
-	case VFE_CMD_DEMOSAICV3_DBPC_CFG:
-	case VFE_CMD_DEMOSAICV3_DBPC_UPDATE:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-		new_val = *cmdp_local;
-
-		old_val = msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase + V40_DEMOSAICV3_0_OFF);
-		old_val &= DBPC_MASK;
-
-		new_val = new_val | old_val;
-		*cmdp_local = new_val;
-		msm_camera_io_memcpy(vfe40_ctrl->share_ctrl->vfebase +
-			V40_DEMOSAICV3_0_OFF,
-			cmdp_local, V40_DEMOSAICV3_0_LEN);
-		cmdp_local += 1;
-		msm_camera_io_memcpy(vfe40_ctrl->share_ctrl->vfebase +
-			V40_DEMOSAICV3_DBPC_CFG_OFF,
-			cmdp_local, V40_DEMOSAICV3_DBPC_LEN);
-		cmdp_local += 1;
-		msm_camera_io_memcpy(vfe40_ctrl->share_ctrl->vfebase +
-			V40_DEMOSAICV3_DBPC_CFG_OFF0,
-			cmdp_local, V40_DEMOSAICV3_DBPC_LEN);
-		cmdp_local += 1;
-		msm_camera_io_memcpy(vfe40_ctrl->share_ctrl->vfebase +
-			V40_DEMOSAICV3_DBPC_CFG_OFF1,
-			cmdp_local, V40_DEMOSAICV3_DBPC_LEN);
-		cmdp_local += 1;
-		msm_camera_io_memcpy(vfe40_ctrl->share_ctrl->vfebase +
-			V40_DEMOSAICV3_DBPC_CFG_OFF2,
-			cmdp_local, V40_DEMOSAICV3_DBPC_LEN);
-		break;
-
-	case VFE_CMD_RGB_G_CFG: {
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase + V40_RGB_G_OFF,
-			cmdp, 4);
-		cmdp += 1;
-
-		vfe40_write_gamma_cfg(RGBLUT_RAM_CH0_BANK0, cmdp, vfe40_ctrl);
-		vfe40_write_gamma_cfg(RGBLUT_RAM_CH1_BANK0, cmdp, vfe40_ctrl);
-		vfe40_write_gamma_cfg(RGBLUT_RAM_CH2_BANK0, cmdp, vfe40_ctrl);
-		}
-	    cmdp -= 1;
-		break;
-
-	case VFE_CMD_RGB_G_UPDATE: {
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp, (void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-
-		old_val = msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase + V40_RGB_G_OFF);
-		cmdp += 1;
-		if (old_val != 0x0) {
-			vfe40_write_gamma_cfg(
-				RGBLUT_RAM_CH0_BANK0, cmdp, vfe40_ctrl);
-			vfe40_write_gamma_cfg(
-				RGBLUT_RAM_CH1_BANK0, cmdp, vfe40_ctrl);
-			vfe40_write_gamma_cfg(
-				RGBLUT_RAM_CH2_BANK0, cmdp, vfe40_ctrl);
-		} else {
-			vfe40_write_gamma_cfg(
-				RGBLUT_RAM_CH0_BANK1, cmdp, vfe40_ctrl);
-			vfe40_write_gamma_cfg(
-				RGBLUT_RAM_CH1_BANK1, cmdp, vfe40_ctrl);
-			vfe40_write_gamma_cfg(
-				RGBLUT_RAM_CH2_BANK1, cmdp, vfe40_ctrl);
-		}
-		}
-		vfe40_ctrl->update_gamma = TRUE;
-		cmdp -= 1;
-		break;
-
-	case VFE_CMD_GET_RGB_G_TABLE:
-		temp1 = sizeof(uint32_t) * VFE40_GAMMA_NUM_ENTRIES * 3;
-		if (cmd->length != temp1) {
-			rc = -EINVAL;
-			goto proc_general_done;
-		}
-		cmdp = kzalloc(temp1, GFP_KERNEL);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		cmdp_local = cmdp;
-
-		old_val = msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase + V40_RGB_G_OFF);
-		temp2 = old_val ? RGBLUT_RAM_CH0_BANK1 :
-			RGBLUT_RAM_CH0_BANK0;
-		for (i = 0; i < 3; i++) {
-			vfe40_read_gamma_cfg(temp2,
-				cmdp_local + (VFE40_GAMMA_NUM_ENTRIES * i),
-				vfe40_ctrl);
-			temp2 += 2;
-		}
-		if (copy_to_user((void __user *)(cmd->value), cmdp,
-			temp1)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		break;
-
-	case VFE_CMD_STATS_AWB_STOP: {
-		old_val = msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= ~AWB_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		}
-		break;
-	case VFE_CMD_STATS_BG_STOP: {
-		old_val = msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= ~BG_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		}
-		break;
-	case VFE_CMD_STATS_BF_STOP: {
-		old_val = msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= ~BF_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-		vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-
-		rc = vfe40_stats_flush_enqueue(vfe40_ctrl,
-				MSM_STATS_TYPE_BF);
-		if (rc < 0) {
-			pr_err("%s: dq stats buf err = %d",
-				   __func__, rc);
-			return -EINVAL;
-			}
-		}
-		break;
-
-	case VFE_CMD_STATS_BE_STOP: {
-		old_val = msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= ~BE_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		}
-		break;
-
-	case VFE_CMD_STATS_IHIST_STOP: {
-		old_val = msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= ~IHIST_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		}
-		break;
-
-	case VFE_CMD_STATS_RS_STOP: {
-		old_val = msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= ~RS_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		}
-		break;
-
-	case VFE_CMD_STATS_CS_STOP: {
-		old_val = msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= ~CS_ENABLE_MASK;
-		msm_camera_io_w(old_val,
-			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		}
-		break;
-
-	case VFE_CMD_STATS_BHIST_STOP: {
-		if (!vfe40_use_bayer_stats(vfe40_ctrl)) {
-			/* Error */
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		old_val = msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase + VFE_STATS_CFG);
-
-		if (VFE_CMD_STATS_BHIST_STOP == cmd->id)
-			old_val &= ~STATS_BHIST_ENABLE_MASK;
-
-		msm_camera_io_w(old_val,
-			vfe40_ctrl->share_ctrl->vfebase + VFE_STATS_CFG);
-		}
-		break;
-
-	case VFE_CMD_STOP:
-		pr_info("vfe40_proc_general: cmdID = %s\n",
-			vfe40_general_cmd[cmd->id]);
-		if (copy_from_user(&vfe_params,
-				(void __user *)(cmd->value),
-				sizeof(struct msm_camera_vfe_params_t))) {
-				rc = -EFAULT;
-				goto proc_general_done;
-		}
-
-		vfe40_ctrl->share_ctrl->current_mode =
-			vfe_params.operation_mode;
-		vfe40_stop(vfe40_ctrl);
-		break;
-
-	case VFE_CMD_SYNC_TIMER_SETTING:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp, (void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		vfe40_sync_timer_start(cmdp, vfe40_ctrl);
-		break;
-
-	case VFE_CMD_MODULE_CFG: {
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp,
-			(void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		*cmdp &= ~STATS_ENABLE_MASK;
-		old_val = msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
-		old_val &= STATS_ENABLE_MASK;
-		*cmdp |= old_val;
-
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase +
-			vfe40_cmd[cmd->id].offset,
-			cmdp, (vfe40_cmd[cmd->id].length));
-		}
-		break;
-
-	case VFE_CMD_ZSL:
-		if (copy_from_user(&vfe_params,
-				(void __user *)(cmd->value),
-				sizeof(struct msm_camera_vfe_params_t))) {
-				rc = -EFAULT;
-				goto proc_general_done;
-		}
-
-		vfe40_ctrl->share_ctrl->current_mode =
-			vfe_params.operation_mode;
-
-		rc = vfe40_zsl(pmctl, vfe40_ctrl);
-		break;
-
-	case VFE_CMD_ASF_CFG:
-	case VFE_CMD_ASF_UPDATE:
-		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		if (copy_from_user(cmdp, (void __user *)(cmd->value),
-			cmd->length)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase +
-			vfe40_cmd[cmd->id].offset,
-			cmdp, (vfe40_cmd[cmd->id].length));
-		cmdp_local = cmdp + V40_ASF_LEN/4;
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase +
-			V40_ASF_SPECIAL_EFX_CFG_OFF,
-			cmdp_local, V40_ASF_SPECIAL_EFX_CFG_LEN);
-		break;
-
-	case VFE_CMD_GET_HW_VERSION:
-		if (cmd->length != V40_GET_HW_VERSION_LEN) {
-			rc = -EINVAL;
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(V40_GET_HW_VERSION_LEN, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		*cmdp = msm_camera_io_r(
-			vfe40_ctrl->share_ctrl->vfebase+V40_GET_HW_VERSION_OFF);
-		if (copy_to_user((void __user *)(cmd->value), cmdp,
-			V40_GET_HW_VERSION_LEN)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		break;
-	case VFE_CMD_GET_REG_DUMP:
-		temp1 = sizeof(uint32_t) *
-			vfe40_ctrl->share_ctrl->register_total;
-		if (cmd->length != temp1) {
-			rc = -EINVAL;
-			goto proc_general_done;
-		}
-		cmdp = kmalloc(temp1, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-		msm_camera_io_dump(vfe40_ctrl->share_ctrl->vfebase,
-			vfe40_ctrl->share_ctrl->register_total*4);
-		CDBG("%s: %p %p %d\n", __func__, (void *)cmdp,
-			vfe40_ctrl->share_ctrl->vfebase, temp1);
-		memcpy_fromio((void *)cmdp,
-			vfe40_ctrl->share_ctrl->vfebase, temp1);
-		if (copy_to_user((void __user *)(cmd->value), cmdp, temp1)) {
-			rc = -EFAULT;
-			goto proc_general_done;
-		}
-		break;
-	case VFE_CMD_FRAME_SKIP_CFG:
-		if (cmd->length != vfe40_cmd[cmd->id].length)
-			return -EINVAL;
-
-		cmdp = kmalloc(vfe40_cmd[cmd->id].length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-
-		if (copy_from_user((cmdp), (void __user *)cmd->value,
-				cmd->length)) {
-			rc = -EFAULT;
-			pr_err("%s copy from user failed for cmd %d",
-				__func__, cmd->id);
-			break;
-		}
-
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase +
-			vfe40_cmd[cmd->id].offset,
-			cmdp, (vfe40_cmd[cmd->id].length));
-		vfe40_ctrl->frame_skip_cnt = ((uint32_t)
-			*cmdp & VFE_FRAME_SKIP_PERIOD_MASK) + 1;
-		vfe40_ctrl->frame_skip_pattern = (uint32_t)(*(cmdp + 2));
-		break;
-	case VFE_CMD_STOP_LIVESHOT:
-		CDBG("%s Stopping liveshot ", __func__);
-		vfe40_stop_liveshot(pmctl, vfe40_ctrl);
-		break;
-	default:
-		if (cmd->length != vfe40_cmd[cmd->id].length)
-			return -EINVAL;
-
-		cmdp = kmalloc(vfe40_cmd[cmd->id].length, GFP_ATOMIC);
-		if (!cmdp) {
-			rc = -ENOMEM;
-			goto proc_general_done;
-		}
-
-		if (copy_from_user((cmdp), (void __user *)cmd->value,
-				cmd->length)) {
-			rc = -EFAULT;
-			pr_err("%s copy from user failed for cmd %d",
-				__func__, cmd->id);
-			goto proc_general_done;
-		}
-		msm_camera_io_memcpy(
-			vfe40_ctrl->share_ctrl->vfebase +
-			vfe40_cmd[cmd->id].offset,
-			cmdp, (vfe40_cmd[cmd->id].length));
-		break;
-
-	}
-
-proc_general_done:
-	kfree(cmdp);
-
-	return rc;
-}
-
-static inline void vfe40_read_irq_status(
-	struct axi_ctrl_t *axi_ctrl, struct vfe40_irq_status *out)
-{
-	uint32_t *temp;
-	memset(out, 0, sizeof(struct vfe40_irq_status));
-	temp = (uint32_t *)(axi_ctrl->share_ctrl->vfebase + VFE_IRQ_STATUS_0);
-	out->vfeIrqStatus0 = msm_camera_io_r(temp);
-
-	temp = (uint32_t *)(axi_ctrl->share_ctrl->vfebase + VFE_IRQ_STATUS_1);
-	out->vfeIrqStatus1 = msm_camera_io_r(temp);
-
-	temp = (uint32_t *)(axi_ctrl->share_ctrl->vfebase + VFE_CAMIF_STATUS);
-	out->camifStatus = msm_camera_io_r(temp);
-	CDBG("camifStatus  = 0x%x\n", out->camifStatus);
-
-	/* clear the pending interrupt of the same kind.*/
-	msm_camera_io_w(out->vfeIrqStatus0,
-		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_0);
-	msm_camera_io_w(out->vfeIrqStatus1,
-		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_1);
-
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	msm_camera_io_w_mb(1, axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CMD);
-
-}
-
-void axi_stop_pix(struct vfe_share_ctrl_t *share_ctrl)
-{
-	uint32_t operation_mode =
-	share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
-		VFE_OUTPUTS_RDI1);
-	uint32_t irq_comp_mask, irq_mask;
-	uint32_t reg_update = 0x1;
-
-	irq_comp_mask =
-		msm_camera_io_r(share_ctrl->vfebase +
-			VFE_IRQ_COMP_MASK);
-	irq_mask = msm_camera_io_r(share_ctrl->vfebase +
-			VFE_IRQ_MASK_0);
-
-	switch (share_ctrl->cmd_type) {
-	case AXI_CMD_PREVIEW: {
-		switch (operation_mode) {
-		case VFE_OUTPUTS_PREVIEW:
-		case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
-			if (share_ctrl->comp_output_mode &
-				VFE40_OUTPUT_MODE_PRIMARY) {
-				msm_camera_io_w(0, share_ctrl->vfebase
-					+ vfe40_AXI_WM_CFG[share_ctrl->
-					outpath.out0.ch0]);
-				msm_camera_io_w(0, share_ctrl->vfebase
-					+ vfe40_AXI_WM_CFG[share_ctrl->
-					outpath.out0.ch1]);
-				irq_comp_mask &= ~(
-					0x1 << share_ctrl->outpath.out0.ch0 |
-					0x1 << share_ctrl->outpath.out0.ch1);
-				share_ctrl->outpath.output_mode |=
-					VFE40_OUTPUT_MODE_PRIMARY;
-			} else if (share_ctrl->comp_output_mode &
-					VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
-				msm_camera_io_w(0, share_ctrl->vfebase
-					+ vfe40_AXI_WM_CFG[share_ctrl->
-					outpath.out0.ch0]);
-				msm_camera_io_w(0, share_ctrl->vfebase
-					+ vfe40_AXI_WM_CFG[share_ctrl->
-					outpath.out0.ch1]);
-				msm_camera_io_w(0, share_ctrl->vfebase
-					+ vfe40_AXI_WM_CFG[share_ctrl->
-					outpath.out0.ch2]);
-				irq_comp_mask &= ~(
-					0x1 << share_ctrl->outpath.out0.ch0 |
-					0x1 << share_ctrl->outpath.out0.ch1 |
-					0x1 << share_ctrl->outpath.out0.ch2);
-				share_ctrl->outpath.output_mode |=
-					VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
-			}
-			irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
-			break;
-		default:
-			if (share_ctrl->comp_output_mode &
-				VFE40_OUTPUT_MODE_SECONDARY) {
-				msm_camera_io_w(0, share_ctrl->vfebase
-					+ vfe40_AXI_WM_CFG[share_ctrl->
-					outpath.out1.ch0]);
-				msm_camera_io_w(0, share_ctrl->vfebase
-					+ vfe40_AXI_WM_CFG[share_ctrl->
-					outpath.out1.ch1]);
-				irq_comp_mask &= ~(
-					0x1 << share_ctrl->outpath.out1.ch0 |
-					0x1 << share_ctrl->outpath.out1.ch1);
-				share_ctrl->outpath.output_mode |=
-					VFE40_OUTPUT_MODE_SECONDARY;
-			} else if (share_ctrl->comp_output_mode &
-				VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
-				msm_camera_io_w(0, share_ctrl->vfebase
-					+ vfe40_AXI_WM_CFG[share_ctrl->
-					outpath.out1.ch0]);
-				msm_camera_io_w(0, share_ctrl->vfebase
-					+ vfe40_AXI_WM_CFG[share_ctrl->
-					outpath.out1.ch1]);
-				msm_camera_io_w(0, share_ctrl->vfebase
-					+ vfe40_AXI_WM_CFG[share_ctrl->
-					outpath.out1.ch2]);
-				irq_comp_mask &= ~(
-					0x1 << share_ctrl->outpath.out1.ch0 |
-					0x1 << share_ctrl->outpath.out1.ch1 |
-					0x1 << share_ctrl->outpath.out1.ch2);
-				share_ctrl->outpath.output_mode |=
-					VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS;
-			}
-			irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
-			break;
-			}
-		}
-		break;
-	default:
-		if (share_ctrl->comp_output_mode &
-			VFE40_OUTPUT_MODE_PRIMARY) {
-			msm_camera_io_w(0, share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[share_ctrl->
-				outpath.out0.ch0]);
-			msm_camera_io_w(0, share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[share_ctrl->
-				outpath.out0.ch1]);
-			irq_comp_mask &= ~(
-				0x1 << share_ctrl->outpath.out0.ch0 |
-				0x1 << share_ctrl->outpath.out0.ch1);
-			irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
-			share_ctrl->outpath.output_mode |=
-					VFE40_OUTPUT_MODE_PRIMARY;
-		} else if (share_ctrl->comp_output_mode &
-				VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
-			msm_camera_io_w(0, share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[share_ctrl->
-				outpath.out0.ch0]);
-			msm_camera_io_w(0, share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[share_ctrl->
-				outpath.out0.ch1]);
-			msm_camera_io_w(0, share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[share_ctrl->
-				outpath.out0.ch2]);
-			irq_comp_mask &= ~(
-				0x1 << share_ctrl->outpath.out0.ch0 |
-				0x1 << share_ctrl->outpath.out0.ch1 |
-				0x1 << share_ctrl->outpath.out0.ch2);
-			irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
-			share_ctrl->outpath.output_mode |=
-					VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
-		}
-
-		if (share_ctrl->comp_output_mode &
-			VFE40_OUTPUT_MODE_SECONDARY) {
-			msm_camera_io_w(0, share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[share_ctrl->
-				outpath.out1.ch0]);
-			msm_camera_io_w(0, share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[share_ctrl->outpath.out1.ch1]);
-			irq_comp_mask &= ~(
-				0x1 << share_ctrl->outpath.out1.ch0 |
-				0x1 << share_ctrl->outpath.out1.ch1);
-			irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
-			share_ctrl->outpath.output_mode |=
-					VFE40_OUTPUT_MODE_SECONDARY;
-		} else if (share_ctrl->comp_output_mode &
-			VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
-			msm_camera_io_w(0, share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[share_ctrl->outpath.out1.ch0]);
-			msm_camera_io_w(0, share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[share_ctrl->outpath.out1.ch1]);
-			msm_camera_io_w(0, share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[share_ctrl->outpath.out1.ch2]);
-			irq_comp_mask &= ~(
-				0x1 << share_ctrl->outpath.out1.ch0 |
-				0x1 << share_ctrl->outpath.out1.ch1 |
-				0x1 << share_ctrl->outpath.out1.ch2);
-			irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
-			share_ctrl->outpath.output_mode |=
-					VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS;
-		}
-		break;
-	}
-
-	msm_camera_io_w_mb(reg_update,
-		share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-	msm_camera_io_w(irq_comp_mask,
-		share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
-	msm_camera_io_w(irq_mask, share_ctrl->vfebase +
-			VFE_IRQ_MASK_0);
-}
-
-void axi_stop_rdi0(struct vfe_share_ctrl_t *share_ctrl)
-{
-	uint32_t reg_update = 0x2;
-	uint32_t irq_mask;
-	irq_mask = msm_camera_io_r(share_ctrl->vfebase +
-			VFE_IRQ_MASK_0);
-
-	if (share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
-		msm_camera_io_w(0, share_ctrl->vfebase +
-			vfe40_AXI_WM_CFG[share_ctrl->outpath.out2.ch0]);
-		irq_mask &= ~(0x1 << (share_ctrl->outpath.out2.ch0 +
-				VFE_WM_OFFSET));
-	}
-	msm_camera_io_w_mb(reg_update,
-		share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-	msm_camera_io_w(irq_mask, share_ctrl->vfebase +
-			VFE_IRQ_MASK_0);
-}
-
-void axi_stop_rdi1(struct vfe_share_ctrl_t *share_ctrl)
-{
-	uint32_t reg_update = 0x4;
-	uint32_t irq_mask;
-	irq_mask = msm_camera_io_r(share_ctrl->vfebase +
-			VFE_IRQ_MASK_0);
-
-	if (share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
-		msm_camera_io_w(1, share_ctrl->vfebase +
-			vfe40_AXI_WM_CFG[share_ctrl->outpath.out3.ch0]);
-		irq_mask &= ~(0x1 << (share_ctrl->outpath.out3.ch0 +
-			VFE_WM_OFFSET));
-	}
-	msm_camera_io_w_mb(reg_update,
-		share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-	msm_camera_io_w(irq_mask, share_ctrl->vfebase +
-			VFE_IRQ_MASK_0);
-}
-
-void axi_stop_process(struct vfe_share_ctrl_t *share_ctrl)
-{
-	uint32_t operation_mode =
-	share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
-		VFE_OUTPUTS_RDI1);
-
-	if (share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
-		axi_stop_rdi0(share_ctrl);
-		share_ctrl->comp_output_mode &= ~VFE40_OUTPUT_MODE_TERTIARY1;
-	}
-	if (share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
-		axi_stop_rdi1(share_ctrl);
-		share_ctrl->comp_output_mode &= ~VFE40_OUTPUT_MODE_TERTIARY2;
-	}
-	if (operation_mode) {
-		axi_stop_pix(share_ctrl);
-		share_ctrl->comp_output_mode &=
-				~(share_ctrl->outpath.output_mode);
-	}
-}
-
-static void vfe40_process_reg_update_irq(
-		struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	unsigned long flags;
-	struct vfe_share_ctrl_t *share_ctrl = vfe40_ctrl->share_ctrl;
-
-	if (atomic_cmpxchg(
-		&share_ctrl->pix0_update_ack_pending, 2, 0) == 2) {
-		axi_stop_pix(share_ctrl);
-		msm_camera_io_w_mb(
-				CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
-				share_ctrl->vfebase + VFE_CAMIF_COMMAND);
-		axi_disable_irq(share_ctrl);
-		vfe40_send_isp_msg(&vfe40_ctrl->subdev,
-			share_ctrl->vfeFrameId,
-			MSG_ID_PIX0_UPDATE_ACK);
-		share_ctrl->comp_output_mode &=
-				~(share_ctrl->outpath.output_mode);
-		share_ctrl->current_mode &=
-			(VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI0);
-	}  else {
-		if (share_ctrl->recording_state == VFE_STATE_START_REQUESTED) {
-			if (share_ctrl->operation_mode &
-				VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
-				msm_camera_io_w(1,
-					share_ctrl->vfebase + vfe40_AXI_WM_CFG[
-				share_ctrl->outpath.out0.ch0]);
-				msm_camera_io_w(1,
-					share_ctrl->vfebase + vfe40_AXI_WM_CFG[
-				share_ctrl->outpath.out0.ch1]);
-			} else if (share_ctrl->operation_mode &
-				VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
-				msm_camera_io_w(1,
-					share_ctrl->vfebase + vfe40_AXI_WM_CFG[
-				share_ctrl->outpath.out1.ch0]);
-				msm_camera_io_w(1,
-					share_ctrl->vfebase + vfe40_AXI_WM_CFG[
-				share_ctrl->outpath.out1.ch1]);
-		}
-			share_ctrl->recording_state = VFE_STATE_STARTED;
-		msm_camera_io_w_mb(1,
-				share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-		CDBG("start video triggered .\n");
-		} else if (share_ctrl->recording_state ==
-			VFE_STATE_STOP_REQUESTED) {
-			if (share_ctrl->operation_mode &
-				VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
-				msm_camera_io_w(0,
-					share_ctrl->vfebase + vfe40_AXI_WM_CFG[
-				share_ctrl->outpath.out0.ch0]);
-				msm_camera_io_w(0,
-					share_ctrl->vfebase + vfe40_AXI_WM_CFG[
-				share_ctrl->outpath.out0.ch1]);
-			} else if (share_ctrl->operation_mode &
-				VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
-				msm_camera_io_w(0,
-					share_ctrl->vfebase + vfe40_AXI_WM_CFG[
-				share_ctrl->outpath.out1.ch0]);
-				msm_camera_io_w(0,
-					share_ctrl->vfebase + vfe40_AXI_WM_CFG[
-				share_ctrl->outpath.out1.ch1]);
-		}
-		CDBG("stop video triggered .\n");
-	}
-
-		if (atomic_cmpxchg(
-			&share_ctrl->pix0_update_ack_pending, 1, 0) == 1) {
-			share_ctrl->comp_output_mode |=
-				(share_ctrl->outpath.output_mode
-				& ~(VFE40_OUTPUT_MODE_TERTIARY1|
-					VFE40_OUTPUT_MODE_TERTIARY2));
-		vfe40_send_isp_msg(&vfe40_ctrl->subdev,
-				share_ctrl->vfeFrameId, MSG_ID_PIX0_UPDATE_ACK);
-			share_ctrl->current_mode &=
-				(VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI0);
-	} else {
-		if (share_ctrl->recording_state ==
-			VFE_STATE_STOP_REQUESTED) {
-				share_ctrl->recording_state = VFE_STATE_STOPPED;
-			/* request a reg update and send STOP_REC_ACK
-			 * when we process the next reg update irq.
-			 */
-			msm_camera_io_w_mb(1, share_ctrl->vfebase +
-						VFE_REG_UPDATE_CMD);
-		} else if (share_ctrl->recording_state ==
-					VFE_STATE_STOPPED) {
-			vfe40_send_isp_msg(&vfe40_ctrl->subdev,
-					share_ctrl->vfeFrameId,
-				MSG_ID_STOP_REC_ACK);
-				share_ctrl->recording_state = VFE_STATE_IDLE;
-		}
-		spin_lock_irqsave(&share_ctrl->update_ack_lock, flags);
-		if (share_ctrl->update_ack_pending == TRUE) {
-			share_ctrl->update_ack_pending = FALSE;
-			spin_unlock_irqrestore(
-				&share_ctrl->update_ack_lock, flags);
-			vfe40_send_isp_msg(&vfe40_ctrl->subdev,
-				share_ctrl->vfeFrameId, MSG_ID_UPDATE_ACK);
-		} else {
-			spin_unlock_irqrestore(
-					&share_ctrl->update_ack_lock, flags);
-		}
-	}
-
-	switch (share_ctrl->liveshot_state) {
-	case VFE_STATE_START_REQUESTED:
-		CDBG("%s enabling liveshot output\n", __func__);
-			if (share_ctrl->comp_output_mode &
-			VFE40_OUTPUT_MODE_PRIMARY) {
-				msm_camera_io_w(1, share_ctrl->vfebase +
-					vfe40_AXI_WM_CFG[
-				share_ctrl->outpath.out0.ch0]);
-				msm_camera_io_w(1, share_ctrl->vfebase +
-					vfe40_AXI_WM_CFG[
-				share_ctrl->outpath.out0.ch1]);
-
-				share_ctrl->liveshot_state =
-				VFE_STATE_STARTED;
-				msm_camera_io_w_mb(1, share_ctrl->vfebase +
-				VFE_REG_UPDATE_CMD);
-		}
-		break;
-	case VFE_STATE_STARTED:
-		CDBG("%s disabling liveshot output\n", __func__);
-		if (share_ctrl->vfe_capture_count >= 1) {
-			if (share_ctrl->vfe_capture_count == 1 &&
-				(share_ctrl->comp_output_mode &
-				VFE40_OUTPUT_MODE_PRIMARY)) {
-				msm_camera_io_w(0, share_ctrl->vfebase +
-					vfe40_AXI_WM_CFG[
-					share_ctrl->outpath.out0.ch0]);
-				msm_camera_io_w(0, share_ctrl->vfebase +
-					vfe40_AXI_WM_CFG[
-					share_ctrl->outpath.out0.ch1]);
-				msm_camera_io_w_mb(1, share_ctrl->vfebase +
-					VFE_REG_UPDATE_CMD);
-			}
-			share_ctrl->vfe_capture_count--;
-		}
-		break;
-	case VFE_STATE_STOP_REQUESTED:
-		CDBG("%s disabling liveshot output from stream off\n",
-			__func__);
-		if (share_ctrl->comp_output_mode &
-			VFE40_OUTPUT_MODE_PRIMARY) {
-			/* Stop requested, stop write masters, and
-			 * trigger REG_UPDATE. Send STOP_LS_ACK in
-			 * next reg update. */
-			msm_camera_io_w(0, share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[
-			share_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(0, share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[
-			share_ctrl->outpath.out0.ch1]);
-			share_ctrl->liveshot_state = VFE_STATE_STOPPED;
-			msm_camera_io_w_mb(1, share_ctrl->vfebase +
-				VFE_REG_UPDATE_CMD);
-		}
-		break;
-	case VFE_STATE_STOPPED:
-		CDBG("%s Sending STOP_LS ACK\n", __func__);
-		vfe40_send_isp_msg(&vfe40_ctrl->subdev,
-			share_ctrl->vfeFrameId, MSG_ID_STOP_LS_ACK);
-			share_ctrl->liveshot_state = VFE_STATE_IDLE;
-		break;
-	default:
-		break;
-	}
-
-	if ((share_ctrl->operation_mode & VFE_OUTPUTS_THUMB_AND_MAIN) ||
-		(share_ctrl->operation_mode &
-		VFE_OUTPUTS_MAIN_AND_THUMB) ||
-		(share_ctrl->operation_mode &
-		VFE_OUTPUTS_THUMB_AND_JPEG) ||
-		(share_ctrl->operation_mode &
-		VFE_OUTPUTS_JPEG_AND_THUMB)) {
-		/* in snapshot mode */
-		/* later we need to add check for live snapshot mode. */
-		if (vfe40_ctrl->frame_skip_pattern & (0x1 <<
-			(vfe40_ctrl->snapshot_frame_cnt %
-				vfe40_ctrl->frame_skip_cnt))) {
-				share_ctrl->vfe_capture_count--;
-			/* if last frame to be captured: */
-				if (share_ctrl->vfe_capture_count == 0) {
-					/* stop the bus output: */
-					if (share_ctrl->comp_output_mode
-					& VFE40_OUTPUT_MODE_PRIMARY) {
-						msm_camera_io_w(0,
-							share_ctrl->vfebase+
-							vfe40_AXI_WM_CFG[
-							share_ctrl->
-							outpath.out0.ch0]);
-						msm_camera_io_w(0,
-							share_ctrl->vfebase+
-							vfe40_AXI_WM_CFG[
-							share_ctrl->
-							outpath.out0.ch1]);
-					}
-					if (share_ctrl->comp_output_mode &
-						VFE40_OUTPUT_MODE_SECONDARY) {
-						msm_camera_io_w(0,
-							share_ctrl->vfebase+
-							vfe40_AXI_WM_CFG[
-							share_ctrl->
-							outpath.out1.ch0]);
-						msm_camera_io_w(0,
-							share_ctrl->vfebase+
-							vfe40_AXI_WM_CFG[
-							share_ctrl->
-							outpath.out1.ch1]);
-				}
-				msm_camera_io_w_mb
-				(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
-					share_ctrl->vfebase +
-					VFE_CAMIF_COMMAND);
-				vfe40_ctrl->snapshot_frame_cnt = -1;
-				vfe40_ctrl->frame_skip_cnt = 31;
-				vfe40_ctrl->frame_skip_pattern = 0xffffffff;
-			} /*if snapshot count is 0*/
-		} /*if frame is not being dropped*/
-		vfe40_ctrl->snapshot_frame_cnt++;
-		/* then do reg_update. */
-		msm_camera_io_w(1,
-				share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-	} /* if snapshot mode. */
-}
-}
-
-static void vfe40_process_rdi0_reg_update_irq(
-	struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	if (atomic_cmpxchg(
-		&vfe40_ctrl->share_ctrl->rdi0_update_ack_pending, 2, 0) == 2) {
-		axi_stop_rdi0(vfe40_ctrl->share_ctrl);
-		axi_disable_irq(vfe40_ctrl->share_ctrl);
-		vfe40_send_isp_msg(&vfe40_ctrl->subdev,
-			vfe40_ctrl->share_ctrl->vfeFrameId,
-			MSG_ID_RDI0_UPDATE_ACK);
-		vfe40_ctrl->share_ctrl->comp_output_mode &=
-			~VFE40_OUTPUT_MODE_TERTIARY1;
-		vfe40_ctrl->share_ctrl->current_mode &=
-			~(VFE_OUTPUTS_RDI0);
-	}
-
-	if (atomic_cmpxchg(
-		&vfe40_ctrl->share_ctrl->rdi0_update_ack_pending, 1, 0) == 1) {
-		vfe40_ctrl->share_ctrl->comp_output_mode |=
-			VFE40_OUTPUT_MODE_TERTIARY1;
-		vfe40_send_isp_msg(&vfe40_ctrl->subdev,
-			vfe40_ctrl->share_ctrl->vfeFrameId,
-			MSG_ID_RDI0_UPDATE_ACK);
-		vfe40_ctrl->share_ctrl->current_mode &=
-			~(VFE_OUTPUTS_RDI0);
-	}
-}
-
-static void vfe40_process_rdi1_reg_update_irq(
-	struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	if (atomic_cmpxchg(
-		&vfe40_ctrl->share_ctrl->rdi1_update_ack_pending, 2, 0) == 2) {
-		axi_stop_rdi1(vfe40_ctrl->share_ctrl);
-		axi_disable_irq(vfe40_ctrl->share_ctrl);
-		vfe40_send_isp_msg(&vfe40_ctrl->subdev,
-			vfe40_ctrl->share_ctrl->vfeFrameId,
-			MSG_ID_RDI1_UPDATE_ACK);
-			vfe40_ctrl->share_ctrl->comp_output_mode &=
-				~VFE40_OUTPUT_MODE_TERTIARY2;
-		vfe40_ctrl->share_ctrl->current_mode &=
-			~(VFE_OUTPUTS_RDI1);
-	}
-
-	if (atomic_cmpxchg(
-		&vfe40_ctrl->share_ctrl->rdi1_update_ack_pending, 1, 0) == 1) {
-		vfe40_ctrl->share_ctrl->comp_output_mode |=
-			VFE40_OUTPUT_MODE_TERTIARY2;
-		vfe40_send_isp_msg(&vfe40_ctrl->subdev,
-			vfe40_ctrl->share_ctrl->vfeFrameId,
-			MSG_ID_RDI1_UPDATE_ACK);
-		vfe40_ctrl->share_ctrl->current_mode &=
-			~(VFE_OUTPUTS_RDI1);
-	}
-}
-
-static void vfe40_process_reset_irq(
-		struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	unsigned long flags;
-
-	atomic_set(&vfe40_ctrl->share_ctrl->vstate, 0);
-	atomic_set(&vfe40_ctrl->share_ctrl->handle_common_irq, 0);
-
-	spin_lock_irqsave(&vfe40_ctrl->share_ctrl->stop_flag_lock, flags);
-	if (vfe40_ctrl->share_ctrl->stop_ack_pending) {
-		vfe40_ctrl->share_ctrl->stop_ack_pending = FALSE;
-		spin_unlock_irqrestore(
-			&vfe40_ctrl->share_ctrl->stop_flag_lock, flags);
-		if (vfe40_ctrl->share_ctrl->sync_abort)
-			complete(&vfe40_ctrl->share_ctrl->reset_complete);
-		else
-		vfe40_send_isp_msg(&vfe40_ctrl->subdev,
-				vfe40_ctrl->share_ctrl->vfeFrameId,
-				MSG_ID_STOP_ACK);
-	} else {
-		spin_unlock_irqrestore(
-			&vfe40_ctrl->share_ctrl->stop_flag_lock, flags);
-		/* this is from reset command. */
-		vfe40_reset_internal_variables(vfe40_ctrl);
-		if (vfe40_ctrl->share_ctrl->vfe_reset_flag) {
-			vfe40_ctrl->share_ctrl->vfe_reset_flag = false;
-			msm_camera_io_w(0xFF00,
-				vfe40_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
-		} else {
-		/* reload all write masters. (frame & line)*/
-		msm_camera_io_w(0xFF7F,
-			vfe40_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
-		}
-		complete(&vfe40_ctrl->share_ctrl->reset_complete);
-	}
-}
-
-static void vfe40_process_camif_sof_irq(
-		struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	if (vfe40_ctrl->share_ctrl->operation_mode &
-		VFE_OUTPUTS_RAW) {
-		if (vfe40_ctrl->share_ctrl->start_ack_pending)
-			vfe40_ctrl->share_ctrl->start_ack_pending = FALSE;
-
-		vfe40_ctrl->share_ctrl->vfe_capture_count--;
-		/* if last frame to be captured: */
-		if (vfe40_ctrl->share_ctrl->vfe_capture_count == 0) {
-			/* Ensure the write order while writing
-			 to the command register using the barrier */
-			msm_camera_io_w_mb(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
-			vfe40_ctrl->share_ctrl->vfebase + VFE_CAMIF_COMMAND);
-		}
-	} /* if raw snapshot mode. */
-	if ((vfe40_ctrl->hfr_mode != HFR_MODE_OFF) &&
-		(vfe40_ctrl->share_ctrl->operation_mode ==
-			VFE_MODE_OF_OPERATION_VIDEO) &&
-		(vfe40_ctrl->share_ctrl->vfeFrameId %
-			vfe40_ctrl->hfr_mode != 0)) {
-		if (vfe40_ctrl->vfe_sof_count_enable)
-			vfe40_ctrl->share_ctrl->vfeFrameId++;
-		CDBG("Skip the SOF notification when HFR enabled\n");
-		return;
-	}
-
-	if (vfe40_ctrl->vfe_sof_count_enable)
-		vfe40_ctrl->share_ctrl->vfeFrameId++;
-
-	vfe40_send_isp_msg(&vfe40_ctrl->subdev,
-		vfe40_ctrl->share_ctrl->vfeFrameId, MSG_ID_SOF_ACK);
-	CDBG("camif_sof_irq, frameId = %d\n",
-		vfe40_ctrl->share_ctrl->vfeFrameId);
-
-	if (vfe40_ctrl->sync_timer_state) {
-		if (vfe40_ctrl->sync_timer_repeat_count == 0)
-			vfe40_sync_timer_stop(vfe40_ctrl);
-		else
-			vfe40_ctrl->sync_timer_repeat_count--;
-	}
-}
-
-static void vfe40_process_error_irq(
-	struct axi_ctrl_t *axi_ctrl, uint32_t errStatus)
-{
-	uint32_t reg_value;
-	if (errStatus & VFE40_IMASK_VIOLATION) {
-		pr_err("vfe40_irq: violation interrupt\n");
-		reg_value = msm_camera_io_r(
-			axi_ctrl->share_ctrl->vfebase + VFE_VIOLATION_STATUS);
-		pr_err("%s: violationStatus  = 0x%x\n", __func__, reg_value);
-	}
-
-	if (errStatus & VFE40_IMASK_CAMIF_ERROR) {
-		pr_err("vfe40_irq: camif errors\n");
-		reg_value = msm_camera_io_r(
-			axi_ctrl->share_ctrl->vfebase + VFE_CAMIF_STATUS);
-		v4l2_subdev_notify(&axi_ctrl->subdev,
-			NOTIFY_VFE_CAMIF_ERROR, (void *)NULL);
-		pr_err("camifStatus  = 0x%x\n", reg_value);
-		vfe40_send_isp_msg(&axi_ctrl->subdev,
-			axi_ctrl->share_ctrl->vfeFrameId, MSG_ID_CAMIF_ERROR);
-	}
-
-	if (errStatus & VFE40_IMASK_BHIST_OVWR)
-		pr_err("vfe40_irq: stats bhist overwrite\n");
-
-	if (errStatus & VFE40_IMASK_STATS_CS_OVWR)
-		pr_err("vfe40_irq: stats cs overwrite\n");
-
-	if (errStatus & VFE40_IMASK_STATS_IHIST_OVWR)
-		pr_err("vfe40_irq: stats ihist overwrite\n");
-
-	if (errStatus & VFE40_IMASK_REALIGN_BUF_Y_OVFL)
-		pr_err("vfe40_irq: realign bug Y overflow\n");
-
-	if (errStatus & VFE40_IMASK_REALIGN_BUF_CB_OVFL)
-		pr_err("vfe40_irq: realign bug CB overflow\n");
-
-	if (errStatus & VFE40_IMASK_REALIGN_BUF_CR_OVFL)
-		pr_err("vfe40_irq: realign bug CR overflow\n");
-
-	if (errStatus & VFE40_IMASK_STATS_BE_BUS_OVFL)
-		pr_err("vfe40_irq: be stats bus overflow\n");
-
-	if (errStatus & VFE40_IMASK_STATS_BG_BUS_OVFL)
-		pr_err("vfe40_irq: bg stats bus overflow\n");
-
-	if (errStatus & VFE40_IMASK_STATS_BF_BUS_OVFL)
-		pr_err("vfe40_irq: bf stats bus overflow\n");
-
-	if (errStatus & VFE40_IMASK_STATS_AWB_BUS_OVFL)
-		pr_err("vfe40_irq: awb stats bus overflow\n");
-
-	if (errStatus & VFE40_IMASK_STATS_RS_BUS_OVFL)
-		pr_err("vfe40_irq: rs stats bus overflow\n");
-
-	if (errStatus & VFE40_IMASK_STATS_CS_BUS_OVFL)
-		pr_err("vfe40_irq: cs stats bus overflow\n");
-
-	if (errStatus & VFE40_IMASK_STATS_IHIST_BUS_OVFL)
-		pr_err("vfe40_irq: ihist stats bus overflow\n");
-
-	if (errStatus & VFE40_IMASK_STATS_SKIN_BHIST_BUS_OVFL)
-		pr_err("vfe40_irq: skin/bhist stats bus overflow\n");
-}
-
-static void vfe40_process_common_error_irq(
-	struct axi_ctrl_t *axi_ctrl, uint32_t errStatus)
-{
-	if (errStatus & VFE40_IMASK_BUS_BDG_HALT_ACK)
-		pr_err("vfe40_irq: BUS BDG HALT ACK\n");
-
-	if (errStatus & VFE40_IMASK_IMG_MAST_0_BUS_OVFL)
-		pr_err("vfe40_irq: image master 0 bus overflow\n");
-
-	if (errStatus & VFE40_IMASK_IMG_MAST_1_BUS_OVFL)
-		pr_err("vfe40_irq: image master 1 bus overflow\n");
-
-	if (errStatus & VFE40_IMASK_IMG_MAST_2_BUS_OVFL)
-		pr_err("vfe40_irq: image master 2 bus overflow\n");
-
-	if (errStatus & VFE40_IMASK_IMG_MAST_3_BUS_OVFL)
-		pr_err("vfe40_irq: image master 3 bus overflow\n");
-
-	if (errStatus & VFE40_IMASK_IMG_MAST_4_BUS_OVFL)
-		pr_err("vfe40_irq: image master 4 bus overflow\n");
-
-	if (errStatus & VFE40_IMASK_IMG_MAST_5_BUS_OVFL)
-		pr_err("vfe40_irq: image master 5 bus overflow\n");
-
-	if (errStatus & VFE40_IMASK_IMG_MAST_6_BUS_OVFL)
-		pr_err("vfe40_irq: image master 6 bus overflow\n");
-
-}
-
-static void vfe_send_outmsg(
-	struct axi_ctrl_t *axi_ctrl, uint8_t msgid,
-	uint32_t ch0_paddr, uint32_t ch1_paddr,
-	uint32_t ch2_paddr, uint32_t inst_handle)
-{
-	struct isp_msg_output msg;
-
-	msg.output_id = msgid;
-	msg.buf.inst_handle = inst_handle;
-	msg.buf.ch_paddr[0]	= ch0_paddr;
-	msg.buf.ch_paddr[1]	= ch1_paddr;
-	msg.buf.ch_paddr[2]	= ch2_paddr;
-	switch (msgid) {
-	case MSG_ID_OUTPUT_TERTIARY1:
-		msg.frameCounter = axi_ctrl->share_ctrl->rdi0FrameId;
-		break;
-	case MSG_ID_OUTPUT_TERTIARY2:
-		msg.frameCounter = axi_ctrl->share_ctrl->rdi1FrameId;
-		break;
-	default:
-		msg.frameCounter = axi_ctrl->share_ctrl->vfeFrameId;
-		break;
-	}
-
-	v4l2_subdev_notify(&axi_ctrl->subdev,
-			NOTIFY_VFE_MSG_OUT,
-			&msg);
-	return;
-}
-
-static void vfe40_process_output_path_irq_0(
-	struct axi_ctrl_t *axi_ctrl)
-{
-	uint32_t ping_pong;
-	uint32_t ch0_paddr, ch1_paddr, ch2_paddr;
-	uint8_t out_bool = 0;
-	struct msm_free_buf *free_buf = NULL;
-
-	free_buf = vfe40_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
-		VFE_MSG_OUTPUT_PRIMARY, axi_ctrl);
-
-	/* we render frames in the following conditions:
-	1. Continuous mode and the free buffer is avaialable.
-	2. In snapshot shot mode, free buffer is not always available.
-	when pending snapshot count is <=1,  then no need to use
-	free buffer.
-	*/
-	out_bool = (
-		(axi_ctrl->share_ctrl->operation_mode &
-			VFE_OUTPUTS_THUMB_AND_MAIN ||
-		axi_ctrl->share_ctrl->operation_mode &
-			VFE_OUTPUTS_MAIN_AND_THUMB ||
-		axi_ctrl->share_ctrl->operation_mode &
-			VFE_OUTPUTS_THUMB_AND_JPEG ||
-		axi_ctrl->share_ctrl->operation_mode &
-			VFE_OUTPUTS_JPEG_AND_THUMB ||
-		axi_ctrl->share_ctrl->operation_mode &
-			VFE_OUTPUTS_RAW ||
-		axi_ctrl->share_ctrl->liveshot_state ==
-			VFE_STATE_STARTED ||
-		axi_ctrl->share_ctrl->liveshot_state ==
-			VFE_STATE_STOP_REQUESTED ||
-		axi_ctrl->share_ctrl->liveshot_state ==
-			VFE_STATE_STOPPED) &&
-		(axi_ctrl->share_ctrl->vfe_capture_count <= 1)) ||
-			free_buf;
-
-	if (out_bool) {
-		ping_pong = msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
-			VFE_BUS_PING_PONG_STATUS);
-
-		/* Channel 0*/
-		ch0_paddr = vfe40_get_ch_addr(
-			ping_pong, axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out0.ch0);
-		/* Channel 1*/
-		ch1_paddr = vfe40_get_ch_addr(
-			ping_pong, axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out0.ch1);
-		/* Channel 2*/
-		ch2_paddr = vfe40_get_ch_addr(
-			ping_pong, axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out0.ch2);
-
-		CDBG("output path 0, ch0 = 0x%x, ch1 = 0x%x, ch2 = 0x%x\n",
-			ch0_paddr, ch1_paddr, ch2_paddr);
-		if (free_buf) {
-			/* Y channel */
-			vfe40_put_ch_addr(ping_pong,
-			axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out0.ch0,
-			free_buf->ch_paddr[0]);
-			/* Chroma channel */
-			vfe40_put_ch_addr(ping_pong,
-			axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out0.ch1,
-			free_buf->ch_paddr[1]);
-			if (free_buf->num_planes > 2)
-				vfe40_put_ch_addr(ping_pong,
-					axi_ctrl->share_ctrl->vfebase,
-					axi_ctrl->share_ctrl->outpath.out0.ch2,
-					free_buf->ch_paddr[2]);
-		}
-		if (axi_ctrl->share_ctrl->operation_mode &
-				VFE_OUTPUTS_THUMB_AND_MAIN ||
-			axi_ctrl->share_ctrl->operation_mode &
-				VFE_OUTPUTS_MAIN_AND_THUMB ||
-			axi_ctrl->share_ctrl->operation_mode &
-				VFE_OUTPUTS_THUMB_AND_JPEG ||
-			axi_ctrl->share_ctrl->operation_mode &
-				VFE_OUTPUTS_JPEG_AND_THUMB ||
-			axi_ctrl->share_ctrl->operation_mode &
-				VFE_OUTPUTS_RAW ||
-			axi_ctrl->share_ctrl->liveshot_state ==
-				VFE_STATE_STOPPED)
-			axi_ctrl->share_ctrl->outpath.out0.capture_cnt--;
-
-		vfe_send_outmsg(axi_ctrl,
-			MSG_ID_OUTPUT_PRIMARY, ch0_paddr,
-			ch1_paddr, ch2_paddr,
-			axi_ctrl->share_ctrl->outpath.out0.inst_handle);
-
-	} else {
-		axi_ctrl->share_ctrl->outpath.out0.frame_drop_cnt++;
-		CDBG("path_irq_0 - no free buffer!\n");
-	}
-}
-
-static void vfe40_process_output_path_irq_1(
-	struct axi_ctrl_t *axi_ctrl)
-{
-	uint32_t ping_pong;
-	uint32_t ch0_paddr, ch1_paddr, ch2_paddr;
-	/* this must be snapshot main image output. */
-	uint8_t out_bool = 0;
-	struct msm_free_buf *free_buf = NULL;
-
-	free_buf = vfe40_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
-		VFE_MSG_OUTPUT_SECONDARY, axi_ctrl);
-	out_bool = ((axi_ctrl->share_ctrl->operation_mode &
-				VFE_OUTPUTS_THUMB_AND_MAIN ||
-			axi_ctrl->share_ctrl->operation_mode &
-				VFE_OUTPUTS_MAIN_AND_THUMB ||
-			axi_ctrl->share_ctrl->operation_mode &
-				VFE_OUTPUTS_RAW ||
-			axi_ctrl->share_ctrl->operation_mode &
-				VFE_OUTPUTS_JPEG_AND_THUMB) &&
-			(axi_ctrl->share_ctrl->vfe_capture_count <= 1)) ||
-				free_buf;
-
-	if (out_bool) {
-		ping_pong = msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
-			VFE_BUS_PING_PONG_STATUS);
-
-		/* Y channel */
-		ch0_paddr = vfe40_get_ch_addr(ping_pong,
-			axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out1.ch0);
-		/* Chroma channel */
-		ch1_paddr = vfe40_get_ch_addr(ping_pong,
-			axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out1.ch1);
-		ch2_paddr = vfe40_get_ch_addr(ping_pong,
-			axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out1.ch2);
-
-		CDBG("%s ch0 = 0x%x, ch1 = 0x%x, ch2 = 0x%x\n",
-			__func__, ch0_paddr, ch1_paddr, ch2_paddr);
-		if (free_buf) {
-			/* Y channel */
-			vfe40_put_ch_addr(ping_pong,
-			axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out1.ch0,
-			free_buf->ch_paddr[0]);
-			/* Chroma channel */
-			vfe40_put_ch_addr(ping_pong,
-			axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out1.ch1,
-			free_buf->ch_paddr[1]);
-			if (free_buf->num_planes > 2)
-				vfe40_put_ch_addr(ping_pong,
-					axi_ctrl->share_ctrl->vfebase,
-					axi_ctrl->share_ctrl->outpath.out1.ch2,
-					free_buf->ch_paddr[2]);
-		}
-		if (axi_ctrl->share_ctrl->operation_mode &
-				VFE_OUTPUTS_THUMB_AND_MAIN ||
-			axi_ctrl->share_ctrl->operation_mode &
-				VFE_OUTPUTS_MAIN_AND_THUMB ||
-			axi_ctrl->share_ctrl->operation_mode &
-				VFE_OUTPUTS_RAW ||
-			axi_ctrl->share_ctrl->operation_mode &
-				VFE_OUTPUTS_JPEG_AND_THUMB)
-			axi_ctrl->share_ctrl->outpath.out1.capture_cnt--;
-
-		vfe_send_outmsg(axi_ctrl,
-			MSG_ID_OUTPUT_SECONDARY, ch0_paddr,
-			ch1_paddr, ch2_paddr,
-			axi_ctrl->share_ctrl->outpath.out1.inst_handle);
-
-	} else {
-		axi_ctrl->share_ctrl->outpath.out1.frame_drop_cnt++;
-		CDBG("path_irq_1 - no free buffer!\n");
-	}
-}
-
-static void vfe40_process_output_path_irq_rdi0(
-			struct axi_ctrl_t *axi_ctrl)
-{
-	uint32_t ping_pong;
-	uint32_t ch0_paddr = 0;
-	/* this must be rdi image output. */
-	struct msm_free_buf *free_buf = NULL;
-	/*RDI0*/
-	if (axi_ctrl->share_ctrl->operation_mode & VFE_OUTPUTS_RDI0) {
-		free_buf = vfe40_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
-			VFE_MSG_OUTPUT_TERTIARY1, axi_ctrl);
-		if (free_buf) {
-			ping_pong = msm_camera_io_r(axi_ctrl->
-				share_ctrl->vfebase +
-				VFE_BUS_PING_PONG_STATUS);
-
-			/* Y only channel */
-			ch0_paddr = vfe40_get_ch_addr(ping_pong,
-				axi_ctrl->share_ctrl->vfebase,
-				axi_ctrl->share_ctrl->outpath.out2.ch0);
-
-			pr_debug("%s ch0 = 0x%x\n",
-				__func__, ch0_paddr);
-
-			/* Y channel */
-			vfe40_put_ch_addr(ping_pong,
-				axi_ctrl->share_ctrl->vfebase,
-				axi_ctrl->share_ctrl->outpath.out2.ch0,
-				free_buf->ch_paddr[0]);
-
-			vfe_send_outmsg(axi_ctrl,
-				MSG_ID_OUTPUT_TERTIARY1, ch0_paddr,
-				0, 0,
-				axi_ctrl->share_ctrl->outpath.out2.inst_handle);
-
-		} else {
-			axi_ctrl->share_ctrl->outpath.out2.frame_drop_cnt++;
-			pr_err("path_irq_2 irq - no free buffer for rdi0!\n");
-		}
-	}
-}
-
-static void vfe40_process_output_path_irq_rdi1(
-	struct axi_ctrl_t *axi_ctrl)
-{
-	uint32_t ping_pong;
-	uint32_t ch0_paddr = 0;
-	/* this must be rdi image output. */
-	struct msm_free_buf *free_buf = NULL;
-	/*RDI1*/
-	if (axi_ctrl->share_ctrl->operation_mode & VFE_OUTPUTS_RDI1) {
-		free_buf = vfe40_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
-			VFE_MSG_OUTPUT_TERTIARY2, axi_ctrl);
-		if (free_buf) {
-			ping_pong = msm_camera_io_r(axi_ctrl->
-				share_ctrl->vfebase +
-				VFE_BUS_PING_PONG_STATUS);
-
-			/* Y channel */
-			ch0_paddr = vfe40_get_ch_addr(ping_pong,
-				axi_ctrl->share_ctrl->vfebase,
-				axi_ctrl->share_ctrl->outpath.out3.ch0);
-			pr_debug("%s ch0 = 0x%x\n",
-				__func__, ch0_paddr);
-
-			/* Y channel */
-			vfe40_put_ch_addr(ping_pong,
-				axi_ctrl->share_ctrl->vfebase,
-				axi_ctrl->share_ctrl->outpath.out3.ch0,
-				free_buf->ch_paddr[0]);
-
-			vfe_send_outmsg(axi_ctrl,
-				MSG_ID_OUTPUT_TERTIARY2, ch0_paddr,
-				0, 0,
-				axi_ctrl->share_ctrl->outpath.out3.inst_handle);
-		} else {
-			axi_ctrl->share_ctrl->outpath.out3.frame_drop_cnt++;
-			pr_err("path_irq irq - no free buffer for rdi1!\n");
-		}
-	}
-}
-
-static uint32_t  vfe40_process_stats_irq_common(
-	struct vfe40_ctrl_type *vfe40_ctrl,
-	uint32_t statsNum, uint32_t newAddr)
-{
-	uint32_t pingpongStatus;
-	uint32_t returnAddr;
-	uint32_t pingpongAddr;
-
-	/* must be 0=ping, 1=pong */
-	pingpongStatus =
-		((msm_camera_io_r(vfe40_ctrl->share_ctrl->vfebase +
-		VFE_BUS_PING_PONG_STATUS))
-	& ((uint32_t)(1<<(statsNum + 7)))) >> (statsNum + 7);
-	/* stats bits starts at 7 */
-	CDBG("%s:statsNum %d, pingpongStatus %d\n", __func__,
-		 statsNum, pingpongStatus);
-	pingpongAddr =
-		((uint32_t)(vfe40_ctrl->share_ctrl->vfebase +
-				VFE_BUS_STATS_PING_PONG_BASE)) +
-				(VFE_STATS_BUS_REG_NUM*statsNum)*4 +
-				(1-pingpongStatus)*4;
-	returnAddr = msm_camera_io_r((uint32_t *)pingpongAddr);
-	msm_camera_io_w(newAddr, (uint32_t *)pingpongAddr);
-	return returnAddr;
-}
-
-static void vfe_send_stats_msg(
-	struct vfe40_ctrl_type *vfe40_ctrl,
-	uint32_t bufAddress, uint32_t statsNum)
-{
-	int rc = 0;
-	void *vaddr = NULL;
-	/* fill message with right content. */
-	/* @todo This is causing issues, need further investigate */
-	/* spin_lock_irqsave(&ctrl->state_lock, flags); */
-	struct isp_msg_stats msgStats;
-	uint32_t stats_type;
-	msgStats.frameCounter = vfe40_ctrl->share_ctrl->vfeFrameId;
-	if (vfe40_ctrl->simultaneous_sof_stat)
-		msgStats.frameCounter--;
-	msgStats.buffer = bufAddress;
-	switch (statsNum) {
-	case statsBgNum:{
-		msgStats.id = MSG_ID_STATS_BG;
-		stats_type = MSM_STATS_TYPE_BG;
-		rc = vfe40_ctrl->stats_ops.dispatch(
-				vfe40_ctrl->stats_ops.stats_ctrl,
-				stats_type, bufAddress,
-				&msgStats.buf_idx, &vaddr, &msgStats.fd,
-				vfe40_ctrl->stats_ops.client);
-		}
-		break;
-	case statsBeNum:{
-		msgStats.id = MSG_ID_STATS_BE;
-		stats_type = MSM_STATS_TYPE_BE;
-		rc = vfe40_ctrl->stats_ops.dispatch(
-				vfe40_ctrl->stats_ops.stats_ctrl,
-				stats_type, bufAddress,
-				&msgStats.buf_idx, &vaddr, &msgStats.fd,
-				vfe40_ctrl->stats_ops.client);
-		}
-		break;
-	case statsBfNum:{
-		msgStats.id = MSG_ID_STATS_BF;
-		stats_type =  MSM_STATS_TYPE_BF;
-		rc = vfe40_ctrl->stats_ops.dispatch(
-				vfe40_ctrl->stats_ops.stats_ctrl,
-				stats_type, bufAddress,
-				&msgStats.buf_idx, &vaddr, &msgStats.fd,
-				vfe40_ctrl->stats_ops.client);
-		}
-		break;
-	case statsAwbNum: {
-		msgStats.id = MSG_ID_STATS_AWB;
-		rc = vfe40_ctrl->stats_ops.dispatch(
-				vfe40_ctrl->stats_ops.stats_ctrl,
-				MSM_STATS_TYPE_AWB, bufAddress,
-				&msgStats.buf_idx, &vaddr, &msgStats.fd,
-				vfe40_ctrl->stats_ops.client);
-		}
-		break;
-
-	case statsIhistNum: {
-		msgStats.id = MSG_ID_STATS_IHIST;
-		rc = vfe40_ctrl->stats_ops.dispatch(
-				vfe40_ctrl->stats_ops.stats_ctrl,
-				MSM_STATS_TYPE_IHIST, bufAddress,
-				&msgStats.buf_idx, &vaddr, &msgStats.fd,
-				vfe40_ctrl->stats_ops.client);
-		}
-		break;
-	case statsRsNum: {
-		msgStats.id = MSG_ID_STATS_RS;
-		rc = vfe40_ctrl->stats_ops.dispatch(
-				vfe40_ctrl->stats_ops.stats_ctrl,
-				MSM_STATS_TYPE_RS, bufAddress,
-				&msgStats.buf_idx, &vaddr, &msgStats.fd,
-				vfe40_ctrl->stats_ops.client);
-		}
-		break;
-	case statsCsNum: {
-		msgStats.id = MSG_ID_STATS_CS;
-		rc = vfe40_ctrl->stats_ops.dispatch(
-				vfe40_ctrl->stats_ops.stats_ctrl,
-				MSM_STATS_TYPE_CS, bufAddress,
-				&msgStats.buf_idx, &vaddr, &msgStats.fd,
-				vfe40_ctrl->stats_ops.client);
-		}
-		break;
-	case statsSkinNum: {
-		msgStats.id = MSG_ID_STATS_BHIST;
-		rc = vfe40_ctrl->stats_ops.dispatch(
-				vfe40_ctrl->stats_ops.stats_ctrl,
-				MSM_STATS_TYPE_BHIST, bufAddress,
-				&msgStats.buf_idx, &vaddr, &msgStats.fd,
-				vfe40_ctrl->stats_ops.client);
-		}
-		break;
-
-	default:
-		goto stats_done;
-	}
-	if (rc == 0) {
-		msgStats.buffer = (uint32_t)vaddr;
-		v4l2_subdev_notify(&vfe40_ctrl->subdev,
-			NOTIFY_VFE_MSG_STATS,
-			&msgStats);
-	} else {
-		pr_err("%s: paddr to idx mapping error, stats_id = %d, paddr = 0x%d",
-			 __func__, msgStats.id, msgStats.buffer);
-	}
-stats_done:
-	/* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
-	return;
-}
-
-static void vfe_send_comp_stats_msg(
-	struct vfe40_ctrl_type *vfe40_ctrl, uint32_t status_bits)
-{
-	struct msm_stats_buf msgStats;
-	uint32_t temp;
-
-	msgStats.frame_id = vfe40_ctrl->share_ctrl->vfeFrameId;
-	if (vfe40_ctrl->simultaneous_sof_stat)
-		msgStats.frame_id--;
-
-	msgStats.status_bits = status_bits;
-
-	msgStats.aec.buff = vfe40_ctrl->bgStatsControl.bufToRender;
-	msgStats.awb.buff = vfe40_ctrl->awbStatsControl.bufToRender;
-	msgStats.af.buff = vfe40_ctrl->bfStatsControl.bufToRender;
-
-	msgStats.ihist.buff = vfe40_ctrl->ihistStatsControl.bufToRender;
-	msgStats.rs.buff = vfe40_ctrl->rsStatsControl.bufToRender;
-	msgStats.cs.buff = vfe40_ctrl->csStatsControl.bufToRender;
-
-	temp = msm_camera_io_r(
-		vfe40_ctrl->share_ctrl->vfebase + VFE_STATS_AWB_SGW_CFG);
-	msgStats.awb_ymin = (0xFF00 & temp) >> 8;
-
-	v4l2_subdev_notify(&vfe40_ctrl->subdev,
-				NOTIFY_VFE_MSG_COMP_STATS,
-				&msgStats);
-}
-
-static void vfe40_process_stats_be_irq(struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	unsigned long flags;
-	uint32_t addr;
-	uint32_t stats_type;
-	stats_type = MSM_STATS_TYPE_BE;
-	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, stats_type);
-	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
-	if (addr) {
-		vfe40_ctrl->beStatsControl.bufToRender =
-			vfe40_process_stats_irq_common(vfe40_ctrl, statsBeNum,
-			addr);
-
-		vfe_send_stats_msg(vfe40_ctrl,
-			vfe40_ctrl->beStatsControl.bufToRender, statsBeNum);
-	} else{
-		vfe40_ctrl->beStatsControl.droppedStatsFrameCount++;
-		CDBG("%s: droppedStatsFrameCount = %d", __func__,
-			vfe40_ctrl->beStatsControl.droppedStatsFrameCount);
-	}
-}
-
-static void vfe40_process_stats_bg_irq(struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	unsigned long flags;
-	uint32_t addr;
-	uint32_t stats_type;
-	stats_type = MSM_STATS_TYPE_BG;
-	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, stats_type);
-	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
-	if (addr) {
-		vfe40_ctrl->bgStatsControl.bufToRender =
-			vfe40_process_stats_irq_common(vfe40_ctrl, statsBgNum,
-			addr);
-
-		vfe_send_stats_msg(vfe40_ctrl,
-			vfe40_ctrl->bgStatsControl.bufToRender, statsBgNum);
-	} else{
-		vfe40_ctrl->bgStatsControl.droppedStatsFrameCount++;
-		CDBG("%s: droppedStatsFrameCount = %d", __func__,
-			vfe40_ctrl->bgStatsControl.droppedStatsFrameCount);
-	}
-}
-
-static void vfe40_process_stats_awb_irq(struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	unsigned long flags;
-	uint32_t addr;
-	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_AWB);
-	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
-	if (addr) {
-		vfe40_ctrl->awbStatsControl.bufToRender =
-			vfe40_process_stats_irq_common(vfe40_ctrl, statsAwbNum,
-			addr);
-
-		vfe_send_stats_msg(vfe40_ctrl,
-			vfe40_ctrl->awbStatsControl.bufToRender, statsAwbNum);
-	} else{
-		vfe40_ctrl->awbStatsControl.droppedStatsFrameCount++;
-		CDBG("%s: droppedStatsFrameCount = %d", __func__,
-			vfe40_ctrl->awbStatsControl.droppedStatsFrameCount);
-	}
-}
-
-static void vfe40_process_stats_bf_irq(struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	unsigned long flags;
-	uint32_t addr;
-	uint32_t stats_type;
-	stats_type = MSM_STATS_TYPE_BF;
-	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, stats_type);
-	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
-	if (addr) {
-		vfe40_ctrl->bfStatsControl.bufToRender =
-			vfe40_process_stats_irq_common(vfe40_ctrl, statsBfNum,
-			addr);
-
-		vfe_send_stats_msg(vfe40_ctrl,
-			vfe40_ctrl->bfStatsControl.bufToRender, statsBfNum);
-	} else{
-		vfe40_ctrl->bfStatsControl.droppedStatsFrameCount++;
-		CDBG("%s: droppedStatsFrameCount = %d", __func__,
-			vfe40_ctrl->bfStatsControl.droppedStatsFrameCount);
-	}
-}
-
-static void vfe40_process_stats_bhist_irq(struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	unsigned long flags;
-	uint32_t addr;
-	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_BHIST);
-	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
-	if (addr) {
-		vfe40_ctrl->bhistStatsControl.bufToRender =
-			vfe40_process_stats_irq_common(vfe40_ctrl,
-				statsSkinNum, addr);
-
-		vfe_send_stats_msg(vfe40_ctrl,
-			vfe40_ctrl->bhistStatsControl.bufToRender,
-			statsSkinNum);
-	} else{
-		vfe40_ctrl->bhistStatsControl.droppedStatsFrameCount++;
-		CDBG("%s: droppedStatsFrameCount = %d", __func__,
-			vfe40_ctrl->bhistStatsControl.droppedStatsFrameCount);
-	}
-}
-
-static void vfe40_process_stats_ihist_irq(struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	unsigned long flags;
-	uint32_t addr;
-	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_IHIST);
-	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
-	if (addr) {
-		vfe40_ctrl->ihistStatsControl.bufToRender =
-			vfe40_process_stats_irq_common(
-			vfe40_ctrl, statsIhistNum, addr);
-
-		vfe_send_stats_msg(vfe40_ctrl,
-			vfe40_ctrl->ihistStatsControl.bufToRender,
-			statsIhistNum);
-	} else {
-		vfe40_ctrl->ihistStatsControl.droppedStatsFrameCount++;
-		CDBG("%s: droppedStatsFrameCount = %d", __func__,
-			vfe40_ctrl->ihistStatsControl.droppedStatsFrameCount);
-	}
-}
-
-static void vfe40_process_stats_rs_irq(struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	unsigned long flags;
-	uint32_t addr;
-	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_RS);
-	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
-	if (addr) {
-		vfe40_ctrl->rsStatsControl.bufToRender =
-			vfe40_process_stats_irq_common(vfe40_ctrl, statsRsNum,
-			addr);
-
-		vfe_send_stats_msg(vfe40_ctrl,
-			vfe40_ctrl->rsStatsControl.bufToRender, statsRsNum);
-	} else {
-		vfe40_ctrl->rsStatsControl.droppedStatsFrameCount++;
-		CDBG("%s: droppedStatsFrameCount = %d", __func__,
-			vfe40_ctrl->rsStatsControl.droppedStatsFrameCount);
-	}
-}
-
-static void vfe40_process_stats_cs_irq(struct vfe40_ctrl_type *vfe40_ctrl)
-{
-	unsigned long flags;
-	uint32_t addr;
-	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
-	addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_CS);
-	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
-	if (addr) {
-		vfe40_ctrl->csStatsControl.bufToRender =
-			vfe40_process_stats_irq_common(vfe40_ctrl, statsCsNum,
-			addr);
-
-			vfe_send_stats_msg(vfe40_ctrl,
-				vfe40_ctrl->csStatsControl.bufToRender,
-				statsCsNum);
-	} else {
-		vfe40_ctrl->csStatsControl.droppedStatsFrameCount++;
-		CDBG("%s: droppedStatsFrameCount = %d", __func__,
-			vfe40_ctrl->csStatsControl.droppedStatsFrameCount);
-	}
-}
-
-static void vfe40_process_stats(struct vfe40_ctrl_type *vfe40_ctrl,
-	uint32_t status_bits)
-{
-	unsigned long flags;
-	int32_t process_stats = false;
-	uint32_t addr;
-	uint32_t stats_type;
-
-	CDBG("%s, stats = 0x%x\n", __func__, status_bits);
-	spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
-
-	stats_type = MSM_STATS_TYPE_BE;
-	if (status_bits & VFE_IRQ_STATUS0_STATS_BE) {
-		addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl,
-				stats_type);
-		if (addr) {
-			vfe40_ctrl->beStatsControl.bufToRender =
-				vfe40_process_stats_irq_common(
-				vfe40_ctrl, statsBeNum, addr);
-			process_stats = true;
-		} else{
-			vfe40_ctrl->beStatsControl.bufToRender = 0;
-			vfe40_ctrl->beStatsControl.droppedStatsFrameCount++;
-		}
-	} else {
-		vfe40_ctrl->beStatsControl.bufToRender = 0;
-	}
-
-	stats_type = MSM_STATS_TYPE_BG;
-	if (status_bits & VFE_IRQ_STATUS0_STATS_BG) {
-		addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl,
-				stats_type);
-		if (addr) {
-			vfe40_ctrl->bgStatsControl.bufToRender =
-				vfe40_process_stats_irq_common(
-				vfe40_ctrl, statsBgNum, addr);
-			process_stats = true;
-		} else{
-			vfe40_ctrl->bgStatsControl.bufToRender = 0;
-			vfe40_ctrl->bgStatsControl.droppedStatsFrameCount++;
-		}
-	} else {
-		vfe40_ctrl->bgStatsControl.bufToRender = 0;
-	}
-
-	if (status_bits & VFE_IRQ_STATUS0_STATS_AWB) {
-		addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl,
-			MSM_STATS_TYPE_AWB);
-		if (addr) {
-			vfe40_ctrl->awbStatsControl.bufToRender =
-				vfe40_process_stats_irq_common(
-				vfe40_ctrl, statsAwbNum,
-				addr);
-			process_stats = true;
-		} else{
-			vfe40_ctrl->awbStatsControl.droppedStatsFrameCount++;
-			vfe40_ctrl->awbStatsControl.bufToRender = 0;
-		}
-	} else {
-		vfe40_ctrl->awbStatsControl.bufToRender = 0;
-	}
-
-	stats_type = MSM_STATS_TYPE_BF;
-	if (status_bits & VFE_IRQ_STATUS0_STATS_BF) {
-		addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl,
-					stats_type);
-		if (addr) {
-			vfe40_ctrl->bfStatsControl.bufToRender =
-				vfe40_process_stats_irq_common(
-				vfe40_ctrl, statsBfNum,
-				addr);
-			process_stats = true;
-		} else {
-			vfe40_ctrl->bfStatsControl.bufToRender = 0;
-			vfe40_ctrl->bfStatsControl.droppedStatsFrameCount++;
-		}
-	} else {
-		vfe40_ctrl->bfStatsControl.bufToRender = 0;
-	}
-
-	if (status_bits & VFE_IRQ_STATUS0_STATS_IHIST) {
-		addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl,
-					MSM_STATS_TYPE_IHIST);
-		if (addr) {
-			vfe40_ctrl->ihistStatsControl.bufToRender =
-				vfe40_process_stats_irq_common(
-				vfe40_ctrl, statsIhistNum,
-				addr);
-			process_stats = true;
-		} else {
-			vfe40_ctrl->ihistStatsControl.droppedStatsFrameCount++;
-			vfe40_ctrl->ihistStatsControl.bufToRender = 0;
-		}
-	} else {
-		vfe40_ctrl->ihistStatsControl.bufToRender = 0;
-	}
-
-	if (status_bits & VFE_IRQ_STATUS0_STATS_RS) {
-		addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl,
-					MSM_STATS_TYPE_RS);
-		if (addr) {
-			vfe40_ctrl->rsStatsControl.bufToRender =
-				vfe40_process_stats_irq_common(
-				vfe40_ctrl, statsRsNum,
-				addr);
-			process_stats = true;
-		} else {
-			vfe40_ctrl->rsStatsControl.droppedStatsFrameCount++;
-			vfe40_ctrl->rsStatsControl.bufToRender = 0;
-		}
-	} else {
-		vfe40_ctrl->rsStatsControl.bufToRender = 0;
-	}
-
-	if (status_bits & VFE_IRQ_STATUS0_STATS_CS) {
-		addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl,
-					MSM_STATS_TYPE_CS);
-		if (addr) {
-			vfe40_ctrl->csStatsControl.bufToRender =
-				vfe40_process_stats_irq_common(
-				vfe40_ctrl, statsCsNum,
-				addr);
-			process_stats = true;
-		} else {
-			vfe40_ctrl->csStatsControl.droppedStatsFrameCount++;
-			vfe40_ctrl->csStatsControl.bufToRender = 0;
-		}
-	} else {
-		vfe40_ctrl->csStatsControl.bufToRender = 0;
-	}
-	spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
-	if (process_stats)
-		vfe_send_comp_stats_msg(vfe40_ctrl, status_bits);
-
-	return;
-}
-
-static void vfe40_process_stats_irq(
-	struct vfe40_ctrl_type *vfe40_ctrl, uint32_t irqstatus)
-{
-	uint32_t status_bits = VFE_COM_STATUS & irqstatus;
-	if ((vfe40_ctrl->hfr_mode != HFR_MODE_OFF) &&
-		(vfe40_ctrl->share_ctrl->vfeFrameId %
-		 vfe40_ctrl->hfr_mode != 0)) {
-		CDBG("Skip the stats when HFR enabled\n");
-		return;
-	}
-
-	vfe40_process_stats(vfe40_ctrl, status_bits);
-	return;
-}
-
-static void vfe40_process_irq(
-	struct vfe40_ctrl_type *vfe40_ctrl, uint32_t irqstatus)
-{
-	if (irqstatus &
-		VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK_0) {
-		vfe40_process_stats_irq(vfe40_ctrl, irqstatus);
-		return;
-	}
-
-	switch (irqstatus) {
-	case VFE_IRQ_STATUS0_CAMIF_SOF_MASK:
-		CDBG("irq	camifSofIrq\n");
-		vfe40_process_camif_sof_irq(vfe40_ctrl);
-		break;
-	case VFE_IRQ_STATUS0_REG_UPDATE_MASK:
-		CDBG("irq	regUpdateIrq\n");
-		vfe40_process_reg_update_irq(vfe40_ctrl);
-		break;
-	case VFE_IRQ_STATUS0_RDI0_REG_UPDATE:
-		CDBG("irq	rdi0 regUpdateIrq\n");
-		vfe40_process_rdi0_reg_update_irq(vfe40_ctrl);
-		break;
-	case VFE_IRQ_STATUS0_RDI1_REG_UPDATE:
-		CDBG("irq	rdi1 regUpdateIrq\n");
-		vfe40_process_rdi1_reg_update_irq(vfe40_ctrl);
-		break;
-	case VFE_IMASK_WHILE_STOPPING_0:
-		CDBG("irq	resetAckIrq\n");
-		vfe40_process_reset_irq(vfe40_ctrl);
-		break;
-	case VFE_IRQ_STATUS0_STATS_BG:
-		CDBG("Stats BG irq occured.\n");
-		vfe40_process_stats_bg_irq(vfe40_ctrl);
-		break;
-	case VFE_IRQ_STATUS0_STATS_BE:
-		CDBG("Stats BE irq occured.\n");
-		vfe40_process_stats_be_irq(vfe40_ctrl);
-		break;
-	case VFE_IRQ_STATUS0_STATS_BF:
-		CDBG("Stats BF irq occured.\n");
-		vfe40_process_stats_bf_irq(vfe40_ctrl);
-		break;
-	case VFE_IRQ_STATUS0_STATS_AWB:
-		CDBG("Stats AWB irq occured.\n");
-		vfe40_process_stats_awb_irq(vfe40_ctrl);
-		break;
-	case VFE_IRQ_STATUS0_STATS_SKIN_BHIST:
-		CDBG("Stats BHIST irq occured.\n");
-		vfe40_process_stats_bhist_irq(vfe40_ctrl);
-		break;
-	case VFE_IRQ_STATUS0_STATS_IHIST:
-		CDBG("Stats IHIST irq occured.\n");
-		vfe40_process_stats_ihist_irq(vfe40_ctrl);
-		break;
-	case VFE_IRQ_STATUS0_STATS_RS:
-		CDBG("Stats RS irq occured.\n");
-		vfe40_process_stats_rs_irq(vfe40_ctrl);
-		break;
-	case VFE_IRQ_STATUS0_STATS_CS:
-		CDBG("Stats CS irq occured.\n");
-		vfe40_process_stats_cs_irq(vfe40_ctrl);
-		break;
-	case VFE_IRQ_STATUS1_SYNC_TIMER0:
-		CDBG("SYNC_TIMER 0 irq occured.\n");
-		vfe40_send_isp_msg(&vfe40_ctrl->subdev,
-			vfe40_ctrl->share_ctrl->vfeFrameId,
-			MSG_ID_SYNC_TIMER0_DONE);
-		break;
-	case VFE_IRQ_STATUS1_SYNC_TIMER1:
-		CDBG("SYNC_TIMER 1 irq occured.\n");
-		vfe40_send_isp_msg(&vfe40_ctrl->subdev,
-			vfe40_ctrl->share_ctrl->vfeFrameId,
-			MSG_ID_SYNC_TIMER1_DONE);
-		break;
-	case VFE_IRQ_STATUS1_SYNC_TIMER2:
-		CDBG("SYNC_TIMER 2 irq occured.\n");
-		vfe40_send_isp_msg(&vfe40_ctrl->subdev,
-			vfe40_ctrl->share_ctrl->vfeFrameId,
-			MSG_ID_SYNC_TIMER2_DONE);
-		break;
-	default:
-		pr_err("Invalid IRQ status\n");
-	}
-}
-
-static void axi40_do_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	struct axi_ctrl_t *axi_ctrl = (struct axi_ctrl_t *)data;
-	struct vfe40_ctrl_type *vfe40_ctrl = axi_ctrl->share_ctrl->vfe40_ctrl;
-	struct vfe40_isr_queue_cmd *qcmd = NULL;
-	int stat_interrupt;
-
-	CDBG("=== axi40_do_tasklet start ===\n");
-
-	while (atomic_read(&irq_cnt)) {
-		spin_lock_irqsave(&axi_ctrl->tasklet_lock, flags);
-		qcmd = list_first_entry(&axi_ctrl->tasklet_q,
-			struct vfe40_isr_queue_cmd, list);
-		atomic_sub(1, &irq_cnt);
-
-		if (!qcmd) {
-			spin_unlock_irqrestore(&axi_ctrl->tasklet_lock,
-				flags);
-			return;
-		}
-
-		list_del(&qcmd->list);
-		spin_unlock_irqrestore(&axi_ctrl->tasklet_lock,
-			flags);
-
-		if (axi_ctrl->share_ctrl->stats_comp) {
-			stat_interrupt = (qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK_0);
-		} else {
-			stat_interrupt =
-				(qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_STATS_BG) |
-				(qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_STATS_BE) |
-				(qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_STATS_AWB) |
-				(qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_STATS_BF) |
-				(qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_STATS_IHIST) |
-				(qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_STATS_RS) |
-				(qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_STATS_CS);
-		}
-		if (qcmd->vfeInterruptStatus0 &
-				VFE_IRQ_STATUS0_CAMIF_SOF_MASK) {
-			if (stat_interrupt)
-				vfe40_ctrl->simultaneous_sof_stat = 1;
-			v4l2_subdev_notify(&vfe40_ctrl->subdev,
-				NOTIFY_VFE_IRQ,
-				(void *)VFE_IRQ_STATUS0_CAMIF_SOF_MASK);
-		}
-
-		/* interrupt to be processed,  *qcmd has the payload.  */
-		if (qcmd->vfeInterruptStatus0 &
-				VFE_IRQ_STATUS0_REG_UPDATE_MASK)
-			v4l2_subdev_notify(&vfe40_ctrl->subdev,
-				NOTIFY_VFE_IRQ,
-				(void *)VFE_IRQ_STATUS0_REG_UPDATE_MASK);
-
-		if (qcmd->vfeInterruptStatus1 &
-				VFE_IRQ_STATUS0_RDI0_REG_UPDATE_MASK)
-			v4l2_subdev_notify(&vfe40_ctrl->subdev,
-				NOTIFY_VFE_IRQ,
-				(void *)VFE_IRQ_STATUS0_RDI0_REG_UPDATE);
-
-		if (qcmd->vfeInterruptStatus1 &
-				VFE_IRQ_STATUS0_RDI1_REG_UPDATE_MASK)
-			v4l2_subdev_notify(&vfe40_ctrl->subdev,
-				NOTIFY_VFE_IRQ,
-				(void *)VFE_IRQ_STATUS0_RDI1_REG_UPDATE);
-
-		if (qcmd->vfeInterruptStatus0 &
-				VFE_IMASK_WHILE_STOPPING_0)
-			v4l2_subdev_notify(&vfe40_ctrl->subdev,
-				NOTIFY_VFE_IRQ,
-				(void *)VFE_IMASK_WHILE_STOPPING_0);
-
-		if (atomic_read(&axi_ctrl->share_ctrl->handle_common_irq)) {
-			if (qcmd->vfeInterruptStatus1 &
-					VFE40_IMASK_COMMON_ERROR_ONLY_1) {
-				pr_err("irq	errorIrq\n");
-				vfe40_process_common_error_irq(
-					axi_ctrl,
-					qcmd->vfeInterruptStatus1 &
-					VFE40_IMASK_COMMON_ERROR_ONLY_1);
-			}
-
-			v4l2_subdev_notify(&axi_ctrl->subdev,
-				NOTIFY_AXI_IRQ,
-				(void *)qcmd->vfeInterruptStatus0);
-		}
-
-		if (atomic_read(&axi_ctrl->share_ctrl->vstate)) {
-			if (qcmd->vfeInterruptStatus1 &
-					VFE40_IMASK_VFE_ERROR_ONLY_1) {
-				pr_err("irq	errorIrq\n");
-				vfe40_process_error_irq(
-					axi_ctrl,
-					qcmd->vfeInterruptStatus1 &
-					VFE40_IMASK_VFE_ERROR_ONLY_1);
-			}
-
-			/* then process stats irq. */
-			if (axi_ctrl->share_ctrl->stats_comp) {
-				/* process stats comb interrupt. */
-				if (qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK_0) {
-					CDBG("Stats composite irq occured.\n");
-					v4l2_subdev_notify(&vfe40_ctrl->subdev,
-					NOTIFY_VFE_IRQ,
-					(void *)qcmd->vfeInterruptStatus0);
-				}
-			} else {
-				/* process individual stats interrupt. */
-				if (qcmd->vfeInterruptStatus0 &
-						VFE_IRQ_STATUS0_STATS_BG)
-					v4l2_subdev_notify(&vfe40_ctrl->subdev,
-					NOTIFY_VFE_IRQ,
-					(void *)VFE_IRQ_STATUS0_STATS_BG);
-
-				if (qcmd->vfeInterruptStatus0 &
-						VFE_IRQ_STATUS0_STATS_BE)
-					v4l2_subdev_notify(&vfe40_ctrl->subdev,
-					NOTIFY_VFE_IRQ,
-					(void *)VFE_IRQ_STATUS0_STATS_BE);
-
-				if (qcmd->vfeInterruptStatus0 &
-						VFE_IRQ_STATUS0_STATS_AWB)
-					v4l2_subdev_notify(&vfe40_ctrl->subdev,
-					NOTIFY_VFE_IRQ,
-					(void *)VFE_IRQ_STATUS0_STATS_AWB);
-
-				if (qcmd->vfeInterruptStatus0 &
-						VFE_IRQ_STATUS0_STATS_BF)
-					v4l2_subdev_notify(&vfe40_ctrl->subdev,
-					NOTIFY_VFE_IRQ,
-					(void *)VFE_IRQ_STATUS0_STATS_BF);
-				if (qcmd->vfeInterruptStatus0 &
-					VFE_IRQ_STATUS0_STATS_SKIN_BHIST)
-					v4l2_subdev_notify(&vfe40_ctrl->subdev,
-					NOTIFY_VFE_IRQ,
-					(void *)
-					VFE_IRQ_STATUS0_STATS_SKIN_BHIST);
-
-				if (qcmd->vfeInterruptStatus0 &
-						VFE_IRQ_STATUS0_STATS_IHIST)
-					v4l2_subdev_notify(&vfe40_ctrl->subdev,
-					NOTIFY_VFE_IRQ,
-					(void *)VFE_IRQ_STATUS0_STATS_IHIST);
-
-				if (qcmd->vfeInterruptStatus0 &
-						VFE_IRQ_STATUS0_STATS_RS)
-					v4l2_subdev_notify(&vfe40_ctrl->subdev,
-					NOTIFY_VFE_IRQ,
-					(void *)VFE_IRQ_STATUS0_STATS_RS);
-
-				if (qcmd->vfeInterruptStatus0 &
-						VFE_IRQ_STATUS0_STATS_CS)
-					v4l2_subdev_notify(&vfe40_ctrl->subdev,
-					NOTIFY_VFE_IRQ,
-					(void *)VFE_IRQ_STATUS0_STATS_CS);
-
-				if (qcmd->vfeInterruptStatus1 &
-						VFE_IRQ_STATUS1_SYNC_TIMER0)
-					v4l2_subdev_notify(&vfe40_ctrl->subdev,
-					NOTIFY_VFE_IRQ,
-					(void *)VFE_IRQ_STATUS1_SYNC_TIMER0);
-
-				if (qcmd->vfeInterruptStatus1 &
-						VFE_IRQ_STATUS1_SYNC_TIMER1)
-					v4l2_subdev_notify(&vfe40_ctrl->subdev,
-					NOTIFY_VFE_IRQ,
-					(void *)VFE_IRQ_STATUS1_SYNC_TIMER1);
-
-				if (qcmd->vfeInterruptStatus1 &
-						VFE_IRQ_STATUS1_SYNC_TIMER2)
-					v4l2_subdev_notify(&vfe40_ctrl->subdev,
-					NOTIFY_VFE_IRQ,
-					(void *)VFE_IRQ_STATUS1_SYNC_TIMER2);
-			}
-		}
-		vfe40_ctrl->simultaneous_sof_stat = 0;
-		kfree(qcmd);
-	}
-	CDBG("=== axi40_do_tasklet end ===\n");
-}
-
-static irqreturn_t vfe40_parse_irq(int irq_num, void *data)
-{
-	unsigned long flags;
-	struct vfe40_irq_status irq;
-	struct vfe40_isr_queue_cmd *qcmd;
-	struct axi_ctrl_t *axi_ctrl = data;
-
-	CDBG("vfe_parse_irq\n");
-
-	vfe40_read_irq_status(axi_ctrl, &irq);
-
-	if ((irq.vfeIrqStatus0 == 0) && (irq.vfeIrqStatus1 == 0)) {
-		CDBG("vfe_parse_irq: vfeIrqStatus0 & 1 are both 0!\n");
-		return IRQ_HANDLED;
-	}
-
-	qcmd = kzalloc(sizeof(struct vfe40_isr_queue_cmd),
-		GFP_ATOMIC);
-	if (!qcmd) {
-		pr_err("vfe_parse_irq: qcmd malloc failed!\n");
-		return IRQ_HANDLED;
-	}
-
-	spin_lock_irqsave(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
-	if (axi_ctrl->share_ctrl->stop_ack_pending) {
-		irq.vfeIrqStatus0 &= VFE_IMASK_WHILE_STOPPING_0;
-		irq.vfeIrqStatus1 &= VFE_IMASK_WHILE_STOPPING_1;
-	}
-	spin_unlock_irqrestore(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
-
-	CDBG("vfe_parse_irq: Irq_status0 = 0x%x, Irq_status1 = 0x%x.\n",
-		irq.vfeIrqStatus0, irq.vfeIrqStatus1);
-
-	qcmd->vfeInterruptStatus0 = irq.vfeIrqStatus0;
-	qcmd->vfeInterruptStatus1 = irq.vfeIrqStatus1;
-
-	spin_lock_irqsave(&axi_ctrl->tasklet_lock, flags);
-	list_add_tail(&qcmd->list, &axi_ctrl->tasklet_q);
-
-	atomic_add(1, &irq_cnt);
-	spin_unlock_irqrestore(&axi_ctrl->tasklet_lock, flags);
-	tasklet_schedule(&axi_ctrl->vfe40_tasklet);
-	return IRQ_HANDLED;
-}
-
-int msm_axi_subdev_isr_routine(struct v4l2_subdev *sd,
-	u32 status, bool *handled)
-{
-	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
-	irqreturn_t ret;
-	CDBG("%s E ", __func__);
-	ret = vfe40_parse_irq(axi_ctrl->vfeirq->start, axi_ctrl);
-	*handled = TRUE;
-	return 0;
-}
-
-static long vfe_stats_bufq_sub_ioctl(
-	struct vfe40_ctrl_type *vfe_ctrl,
-	struct msm_vfe_cfg_cmd *cmd, void *ion_client, int domain_num)
-{
-	long rc = 0;
-	switch (cmd->cmd_type) {
-	case VFE_CMD_STATS_REQBUF:
-	if (!vfe_ctrl->stats_ops.stats_ctrl) {
-		/* stats_ctrl has not been init yet */
-		rc = msm_stats_buf_ops_init(&vfe_ctrl->stats_ctrl,
-				(struct ion_client *)ion_client,
-				&vfe_ctrl->stats_ops);
-		if (rc < 0) {
-			pr_err("%s: cannot init stats ops", __func__);
-			goto end;
-		}
-		rc = vfe_ctrl->stats_ops.stats_ctrl_init(&vfe_ctrl->stats_ctrl);
-		if (rc < 0) {
-			pr_err("%s: cannot init stats_ctrl ops", __func__);
-			memset(&vfe_ctrl->stats_ops, 0,
-				sizeof(vfe_ctrl->stats_ops));
-			goto end;
-		}
-		if (sizeof(struct msm_stats_reqbuf) != cmd->length) {
-			/* error. the length not match */
-			pr_err("%s: stats reqbuf input size = %d,\n"
-				"struct size = %d, mitch match\n",
-				 __func__, cmd->length,
-				sizeof(struct msm_stats_reqbuf));
-			rc = -EINVAL ;
-			goto end;
-		}
-	}
-	rc = vfe_ctrl->stats_ops.reqbuf(
-			&vfe_ctrl->stats_ctrl,
-			(struct msm_stats_reqbuf *)cmd->value,
-			vfe_ctrl->stats_ops.client);
-	break;
-	case VFE_CMD_STATS_ENQUEUEBUF:
-	if (sizeof(struct msm_stats_buf_info) != cmd->length) {
-		/* error. the length not match */
-		pr_err("%s: stats enqueuebuf input size = %d,\n"
-			"struct size = %d, mitch match\n",
-			 __func__, cmd->length,
-			sizeof(struct msm_stats_buf_info));
-			rc = -EINVAL;
-			goto end;
-	}
-	rc = vfe_ctrl->stats_ops.enqueue_buf(
-			&vfe_ctrl->stats_ctrl,
-			(struct msm_stats_buf_info *)cmd->value,
-			vfe_ctrl->stats_ops.client, domain_num);
-	break;
-	case VFE_CMD_STATS_FLUSH_BUFQ:
-	{
-		struct msm_stats_flush_bufq *flush_req = NULL;
-		flush_req = (struct msm_stats_flush_bufq *)cmd->value;
-		if (sizeof(struct msm_stats_flush_bufq) != cmd->length) {
-			/* error. the length not match */
-			pr_err("%s: stats flush queue input size = %d,\n"
-				"struct size = %d, mitch match\n",
-				__func__, cmd->length,
-				sizeof(struct msm_stats_flush_bufq));
-			rc = -EINVAL;
-			goto end;
-	}
-	rc = vfe_ctrl->stats_ops.bufq_flush(
-			&vfe_ctrl->stats_ctrl,
-			(enum msm_stats_enum_type)flush_req->stats_type,
-			vfe_ctrl->stats_ops.client);
-	}
-	break;
-	case VFE_CMD_STATS_UNREGBUF:
-	{
-		struct msm_stats_reqbuf *req_buf = NULL;
-		req_buf = (struct msm_stats_reqbuf *)cmd->value;
-		if (sizeof(struct msm_stats_reqbuf) != cmd->length) {
-			/* error. the length not match */
-			pr_err("%s: stats reqbuf input size = %d,\n"
-				"struct size = %d, mitch match\n",
-				 __func__, cmd->length,
-				sizeof(struct msm_stats_reqbuf));
-			rc = -EINVAL ;
-			goto end;
-		}
-		rc = vfe40_stats_unregbuf(vfe_ctrl, req_buf, domain_num);
-	}
-	break;
-	default:
-		rc = -1;
-		pr_err("%s: cmd_type %d not supported", __func__,
-			cmd->cmd_type);
-	break;
-	}
-end:
-	return rc;
-}
-
-static long msm_vfe_subdev_ioctl(struct v4l2_subdev *sd,
-			unsigned int subdev_cmd, void *arg)
-{
-	struct msm_cam_media_controller *pmctl =
-		(struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
-	struct vfe40_ctrl_type *vfe40_ctrl =
-		(struct vfe40_ctrl_type *)v4l2_get_subdevdata(sd);
-	struct msm_isp_cmd vfecmd;
-	struct msm_camvfe_params *vfe_params;
-	struct msm_vfe_cfg_cmd *cmd;
-	void *data;
-
-	long rc = 0;
-	struct vfe_cmd_stats_buf *scfg = NULL;
-	struct vfe_cmd_stats_ack *sack = NULL;
-
-	if (!vfe40_ctrl->share_ctrl->vfebase) {
-		pr_err("%s: base address unmapped\n", __func__);
-		return -EFAULT;
-	}
-
-	CDBG("%s\n", __func__);
-	if (subdev_cmd == VIDIOC_MSM_VFE_INIT) {
-		CDBG("%s init\n", __func__);
-		return msm_vfe_subdev_init(sd);
-	} else if (subdev_cmd == VIDIOC_MSM_VFE_RELEASE) {
-		msm_vfe_subdev_release(sd);
-		return 0;
-	}
-	vfe_params = (struct msm_camvfe_params *)arg;
-	cmd = vfe_params->vfe_cfg;
-	data = vfe_params->data;
-	switch (cmd->cmd_type) {
-	case CMD_VFE_PROCESS_IRQ:
-		vfe40_process_irq(vfe40_ctrl, (uint32_t) data);
-		return rc;
-	case VFE_CMD_STATS_REQBUF:
-	case VFE_CMD_STATS_ENQUEUEBUF:
-	case VFE_CMD_STATS_FLUSH_BUFQ:
-	case VFE_CMD_STATS_UNREGBUF:
-		/* for easy porting put in one envelope */
-		rc = vfe_stats_bufq_sub_ioctl(vfe40_ctrl,
-				cmd, vfe_params->data, pmctl->domain_num);
-		return rc;
-	default:
-		if (cmd->cmd_type != CMD_CONFIG_PING_ADDR &&
-		cmd->cmd_type != CMD_CONFIG_PONG_ADDR &&
-		cmd->cmd_type != CMD_CONFIG_FREE_BUF_ADDR &&
-		cmd->cmd_type != CMD_STATS_AEC_BUF_RELEASE &&
-		cmd->cmd_type != CMD_STATS_AWB_BUF_RELEASE &&
-		cmd->cmd_type != CMD_STATS_IHIST_BUF_RELEASE &&
-		cmd->cmd_type != CMD_STATS_RS_BUF_RELEASE &&
-		cmd->cmd_type != CMD_STATS_CS_BUF_RELEASE &&
-		cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE &&
-		cmd->cmd_type != CMD_STATS_BG_BUF_RELEASE &&
-		cmd->cmd_type != CMD_STATS_BE_BUF_RELEASE &&
-		cmd->cmd_type != CMD_STATS_BF_BUF_RELEASE &&
-		cmd->cmd_type != CMD_STATS_BHIST_BUF_RELEASE &&
-		cmd->cmd_type != CMD_VFE_PIX_SOF_COUNT_UPDATE &&
-		cmd->cmd_type != CMD_VFE_COUNT_PIX_SOF_ENABLE) {
-			if (copy_from_user(&vfecmd,
-					(void __user *)(cmd->value),
-					sizeof(vfecmd))) {
-				pr_err("%s %d: copy_from_user failed\n",
-					__func__, __LINE__);
-				return -EFAULT;
-			}
-		} else {
-			/* here eith stats release or frame release. */
-			if (cmd->cmd_type != CMD_CONFIG_PING_ADDR &&
-				cmd->cmd_type != CMD_CONFIG_PONG_ADDR &&
-				cmd->cmd_type != CMD_CONFIG_FREE_BUF_ADDR) {
-				/* then must be stats release. */
-				if (!data) {
-					pr_err("%s: data = NULL, cmd->cmd_type = %d",
-						__func__, cmd->cmd_type);
-					return -EFAULT;
-				}
-				sack = kmalloc(sizeof(struct vfe_cmd_stats_ack),
-							GFP_ATOMIC);
-				if (!sack) {
-					pr_err("%s: no mem for cmd->cmd_type = %d",
-					 __func__, cmd->cmd_type);
-					return -ENOMEM;
-				}
-				sack->nextStatsBuf = *(uint32_t *)data;
-			}
-		}
-	}
-
-	CDBG("%s: cmdType = %d\n", __func__, cmd->cmd_type);
-
-	if ((cmd->cmd_type == CMD_STATS_AF_ENABLE)    ||
-		(cmd->cmd_type == CMD_STATS_AWB_ENABLE)   ||
-		(cmd->cmd_type == CMD_STATS_IHIST_ENABLE) ||
-		(cmd->cmd_type == CMD_STATS_RS_ENABLE)    ||
-		(cmd->cmd_type == CMD_STATS_CS_ENABLE)    ||
-		(cmd->cmd_type == CMD_STATS_AEC_ENABLE)   ||
-		(cmd->cmd_type == CMD_STATS_BG_ENABLE)    ||
-		(cmd->cmd_type == CMD_STATS_BE_ENABLE)    ||
-		(cmd->cmd_type == CMD_STATS_BF_ENABLE)    ||
-		(cmd->cmd_type == CMD_STATS_BHIST_ENABLE)) {
-		struct axidata *axid;
-		axid = data;
-		if (!axid) {
-			rc = -EFAULT;
-			goto vfe40_config_done;
-		}
-		CDBG("%s: cmdType = %d\n", __func__, cmd->cmd_type);
-
-		if ((cmd->cmd_type == CMD_STATS_AF_ENABLE)    ||
-			(cmd->cmd_type == CMD_STATS_AWB_ENABLE)   ||
-			(cmd->cmd_type == CMD_STATS_IHIST_ENABLE) ||
-			(cmd->cmd_type == CMD_STATS_RS_ENABLE)    ||
-			(cmd->cmd_type == CMD_STATS_CS_ENABLE)    ||
-			(cmd->cmd_type == CMD_STATS_AEC_ENABLE)) {
-				scfg = NULL;
-				/* individual */
-				goto vfe40_config_done;
-		}
-		switch (cmd->cmd_type) {
-		case CMD_STATS_AEC_ENABLE:
-		case CMD_STATS_BG_ENABLE:
-		case CMD_STATS_BE_ENABLE:
-		case CMD_STATS_BF_ENABLE:
-		case CMD_STATS_BHIST_ENABLE:
-		case CMD_STATS_AWB_ENABLE:
-		case CMD_STATS_IHIST_ENABLE:
-		case CMD_STATS_RS_ENABLE:
-		case CMD_STATS_CS_ENABLE:
-		default:
-			pr_err("%s Unsupported cmd type %d",
-				__func__, cmd->cmd_type);
-			break;
-		}
-		goto vfe40_config_done;
-	}
-	switch (cmd->cmd_type) {
-	case CMD_GENERAL:
-		rc = vfe40_proc_general(pmctl, &vfecmd, vfe40_ctrl);
-	break;
-	case CMD_VFE_COUNT_PIX_SOF_ENABLE: {
-		int enable = *((int *)cmd->value);
-		if (enable)
-			vfe40_ctrl->vfe_sof_count_enable = TRUE;
-		else
-			vfe40_ctrl->vfe_sof_count_enable = false;
-	}
-	break;
-	case CMD_VFE_PIX_SOF_COUNT_UPDATE:
-		if (!vfe40_ctrl->vfe_sof_count_enable)
-			vfe40_ctrl->share_ctrl->vfeFrameId =
-			*((uint32_t *)vfe_params->data);
-	break;
-	case CMD_CONFIG_PING_ADDR: {
-		int path = *((int *)cmd->value);
-		struct vfe40_output_ch *outch =
-			vfe40_get_ch(path, vfe40_ctrl->share_ctrl);
-		outch->ping = *((struct msm_free_buf *)data);
-	}
-	break;
-
-	case CMD_CONFIG_PONG_ADDR: {
-		int path = *((int *)cmd->value);
-		struct vfe40_output_ch *outch =
-			vfe40_get_ch(path, vfe40_ctrl->share_ctrl);
-		outch->pong = *((struct msm_free_buf *)data);
-	}
-	break;
-
-	case CMD_CONFIG_FREE_BUF_ADDR: {
-		int path = *((int *)cmd->value);
-		struct vfe40_output_ch *outch =
-			vfe40_get_ch(path, vfe40_ctrl->share_ctrl);
-		outch->free_buf = *((struct msm_free_buf *)data);
-	}
-	break;
-
-	case CMD_SNAP_BUF_RELEASE:
-		break;
-
-	default:
-		pr_err("%s Unsupported AXI configuration %x ", __func__,
-			cmd->cmd_type);
-	break;
-	}
-vfe40_config_done:
-	kfree(scfg);
-	kfree(sack);
-	CDBG("%s done: rc = %d\n", __func__, (int) rc);
-	return rc;
-}
-
-static struct msm_cam_clk_info vfe40_clk_info[] = {
-	{"camss_top_ahb_clk", -1},
-	{"vfe_clk_src", 266670000},
-	{"camss_vfe_vfe_clk", -1},
-	{"camss_csi_vfe_clk", -1},
-	{"iface_clk", -1},
-	{"bus_clk", -1},
-	{"alt_bus_clk", -1},
-};
-
-static int msm_axi_subdev_s_crystal_freq(struct v4l2_subdev *sd,
-						u32 freq, u32 flags)
-{
-	int rc = 0;
-	int round_rate;
-	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
-
-	round_rate = clk_round_rate(axi_ctrl->vfe_clk[1], freq);
-	if (rc < 0) {
-		pr_err("%s: clk_round_rate failed %d\n",
-					__func__, rc);
-		return rc;
-	}
-
-	vfe_clk_rate = round_rate;
-	rc = clk_set_rate(axi_ctrl->vfe_clk[1], round_rate);
-	if (rc < 0)
-		pr_err("%s: clk_set_rate failed %d\n",
-					__func__, rc);
-
-	return rc;
-}
-
-static const struct v4l2_subdev_core_ops msm_vfe_subdev_core_ops = {
-	.ioctl = msm_vfe_subdev_ioctl,
-};
-
-static const struct v4l2_subdev_ops msm_vfe_subdev_ops = {
-	.core = &msm_vfe_subdev_core_ops,
-};
-
-static void msm_vfe40_init_vbif_parms(void __iomem *vfe_vbif_base)
-{
-	msm_camera_io_w(0x1,
-		vfe_vbif_base + VFE40_VBIF_CLKON);
-	msm_camera_io_w(0x01010101,
-		vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF0);
-	msm_camera_io_w(0x01010101,
-		vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF1);
-	msm_camera_io_w(0x10010110,
-		vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF2);
-	msm_camera_io_w(0x10101010,
-		vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF0);
-	msm_camera_io_w(0x10101010,
-		vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF1);
-	msm_camera_io_w(0x10101010,
-		vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF2);
-	msm_camera_io_w(0x00001010,
-		vfe_vbif_base + VFE40_VBIF_OUT_RD_LIM_CONF0);
-	msm_camera_io_w(0x00001010,
-		vfe_vbif_base + VFE40_VBIF_OUT_WR_LIM_CONF0);
-	msm_camera_io_w(0x00000707,
-		vfe_vbif_base + VFE40_VBIF_DDR_OUT_MAX_BURST);
-	msm_camera_io_w(0x00000707,
-		vfe_vbif_base + VFE40_VBIF_OCMEM_OUT_MAX_BURST);
-	msm_camera_io_w(0x00000030,
-		vfe_vbif_base + VFE40_VBIF_ARB_CTL);
-	msm_camera_io_w(0x04210842,
-		vfe_vbif_base + VFE40_VBIF_DDR_ARB_CONF0);
-	msm_camera_io_w(0x04210842,
-		vfe_vbif_base + VFE40_VBIF_DDR_ARB_CONF1);
-	msm_camera_io_w(0x00000001,
-		vfe_vbif_base + VFE40_VBIF_ROUND_ROBIN_QOS_ARB);
-	msm_camera_io_w(0x22222222,
-		vfe_vbif_base + VFE40_VBIF_OUT_AXI_AMEMTYPE_CONF0);
-	msm_camera_io_w(0x00002222,
-		vfe_vbif_base + VFE40_VBIF_OUT_AXI_AMEMTYPE_CONF1);
-	msm_camera_io_w(0x00000FFF,
-		vfe_vbif_base + VFE40_VBIF_OUT_AXI_AOOO_EN);
-	msm_camera_io_w(0x0FFF0FFF,
-		vfe_vbif_base + VFE40_VBIF_OUT_AXI_AOOO);
-}
-
-int msm_axi_subdev_init(struct v4l2_subdev *sd)
-{
-	int rc = 0;
-	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
-	struct msm_cam_media_controller *mctl;
-	mctl = v4l2_get_subdev_hostdata(sd);
-	if (mctl == NULL) {
-		pr_err("%s: mctl is NULL\n", __func__);
-		rc = -EINVAL;
-		goto mctl_failed;
-	}
-	axi_ctrl->share_ctrl->axi_ref_cnt++;
-	if (axi_ctrl->share_ctrl->axi_ref_cnt > 1)
-		return rc;
-
-	spin_lock_init(&axi_ctrl->tasklet_lock);
-	INIT_LIST_HEAD(&axi_ctrl->tasklet_q);
-	spin_lock_init(&axi_ctrl->share_ctrl->sd_notify_lock);
-
-	axi_ctrl->share_ctrl->vfebase = ioremap(axi_ctrl->vfemem->start,
-		resource_size(axi_ctrl->vfemem));
-	if (!axi_ctrl->share_ctrl->vfebase) {
-		rc = -ENOMEM;
-		pr_err("%s: vfe ioremap failed\n", __func__);
-		goto remap_failed;
-	}
-
-	axi_ctrl->share_ctrl->vfe_vbif_base =
-		ioremap(axi_ctrl->vfe_vbif_mem->start,
-			resource_size(axi_ctrl->vfe_vbif_mem));
-	if (!axi_ctrl->share_ctrl->vfe_vbif_base) {
-		rc = -ENOMEM;
-		pr_err("%s: vfe ioremap failed\n", __func__);
-		goto remap_failed;
-	}
-
-	if (axi_ctrl->fs_vfe) {
-		rc = regulator_enable(axi_ctrl->fs_vfe);
-		if (rc) {
-			pr_err("%s: Regulator enable failed\n",	__func__);
-			goto fs_failed;
-		}
-	}
-
-	rc = msm_cam_clk_enable(&axi_ctrl->pdev->dev, vfe40_clk_info,
-			axi_ctrl->vfe_clk, ARRAY_SIZE(vfe40_clk_info), 1);
-	if (rc < 0)
-		goto clk_enable_failed;
-
-	axi_ctrl->bus_perf_client =
-		msm_bus_scale_register_client(&vfe_bus_client_pdata);
-	if (!axi_ctrl->bus_perf_client) {
-		pr_err("%s: Registration Failed!\n", __func__);
-		axi_ctrl->bus_perf_client = 0;
-		goto bus_scale_register_failed;
-	}
-
-	msm_camera_bus_scale_cfg(axi_ctrl->bus_perf_client, S_PREVIEW);
-
-	rc = iommu_attach_device(mctl->domain, axi_ctrl->iommu_ctx);
-	if (rc < 0) {
-		pr_err("%s: imgwr attach failed rc = %d\n", __func__, rc);
-		rc = -ENODEV;
-		goto device_imgwr_attach_failed;
-	}
-
-	msm_vfe40_init_vbif_parms(axi_ctrl->share_ctrl->vfe_vbif_base);
-
-	axi_ctrl->share_ctrl->register_total = VFE40_REGISTER_TOTAL;
-
-	spin_lock_init(&axi_ctrl->share_ctrl->stop_flag_lock);
-	spin_lock_init(&axi_ctrl->share_ctrl->update_ack_lock);
-	spin_lock_init(&axi_ctrl->share_ctrl->start_ack_lock);
-	init_completion(&axi_ctrl->share_ctrl->reset_complete);
-
-	if (!axi_ctrl->use_irq_router)
-		enable_irq(axi_ctrl->vfeirq->start);
-
-	return rc;
-
-bus_scale_register_failed:
-	msm_cam_clk_enable(&axi_ctrl->pdev->dev, vfe40_clk_info,
-		axi_ctrl->vfe_clk, ARRAY_SIZE(vfe40_clk_info), 0);
-clk_enable_failed:
-	if (axi_ctrl->fs_vfe)
-		regulator_disable(axi_ctrl->fs_vfe);
-fs_failed:
-	iounmap(axi_ctrl->share_ctrl->vfebase);
-	axi_ctrl->share_ctrl->vfebase = NULL;
-remap_failed:
-	iommu_detach_device(mctl->domain, axi_ctrl->iommu_ctx);
-device_imgwr_attach_failed:
-	if (!axi_ctrl->use_irq_router)
-		disable_irq(axi_ctrl->vfeirq->start);
-mctl_failed:
-	return rc;
-}
-
-int msm_vfe_subdev_init(struct v4l2_subdev *sd)
-{
-	int rc = 0;
-	struct vfe40_ctrl_type *vfe40_ctrl =
-		(struct vfe40_ctrl_type *)v4l2_get_subdevdata(sd);
-
-	spin_lock_init(&vfe40_ctrl->state_lock);
-	spin_lock_init(&vfe40_ctrl->stats_bufq_lock);
-
-	vfe40_ctrl->update_linear = false;
-	vfe40_ctrl->update_rolloff = false;
-	vfe40_ctrl->update_la = false;
-	vfe40_ctrl->update_gamma = false;
-	vfe40_ctrl->vfe_sof_count_enable = true;
-	vfe40_ctrl->hfr_mode = HFR_MODE_OFF;
-
-	memset(&vfe40_ctrl->stats_ctrl, 0,
-		   sizeof(struct msm_stats_bufq_ctrl));
-	memset(&vfe40_ctrl->stats_ops, 0, sizeof(struct msm_stats_ops));
-
-	return rc;
-}
-
-void msm_axi_subdev_release(struct v4l2_subdev *sd)
-{
-	struct msm_cam_media_controller *pmctl =
-		(struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
-	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
-	if (!axi_ctrl->share_ctrl->vfebase) {
-		pr_err("%s: base address unmapped\n", __func__);
-		return;
-	}
-
-	CDBG("%s, free_irq\n", __func__);
-	axi_ctrl->share_ctrl->axi_ref_cnt--;
-	if (axi_ctrl->share_ctrl->axi_ref_cnt > 0)
-		return;
-	if (!axi_ctrl->use_irq_router)
-		disable_irq(axi_ctrl->vfeirq->start);
-	tasklet_kill(&axi_ctrl->vfe40_tasklet);
-
-	iommu_detach_device(pmctl->domain, axi_ctrl->iommu_ctx);
-
-	msm_cam_clk_enable(&axi_ctrl->pdev->dev, vfe40_clk_info,
-			axi_ctrl->vfe_clk, ARRAY_SIZE(vfe40_clk_info), 0);
-	if (axi_ctrl->fs_vfe)
-		regulator_disable(axi_ctrl->fs_vfe);
-
-	iounmap(axi_ctrl->share_ctrl->vfebase);
-	iounmap(axi_ctrl->share_ctrl->vfe_vbif_base);
-	axi_ctrl->share_ctrl->vfebase = NULL;
-
-	if (atomic_read(&irq_cnt))
-		pr_warning("%s, Warning IRQ Count not ZERO\n", __func__);
-
-	msm_camera_bus_scale_cfg(axi_ctrl->bus_perf_client, S_EXIT);
-	axi_ctrl->bus_perf_client = 0;
-
-	msm_vfe_subdev_release(&axi_ctrl->share_ctrl->vfe40_ctrl->subdev);
-}
-
-void msm_vfe_subdev_release(struct v4l2_subdev *sd)
-{
-	struct vfe40_ctrl_type *vfe40_ctrl =
-		(struct vfe40_ctrl_type *)v4l2_get_subdevdata(sd);
-	CDBG("vfe subdev release %p\n",
-		vfe40_ctrl->share_ctrl->vfebase);
-}
-
-void axi_abort(struct axi_ctrl_t *axi_ctrl)
-{
-	uint8_t  axi_busy_flag = true;
-	unsigned long flags;
-	/* axi halt command. */
-
-	spin_lock_irqsave(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
-	axi_ctrl->share_ctrl->stop_ack_pending  = TRUE;
-	spin_unlock_irqrestore(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
-	msm_camera_io_w(AXI_HALT,
-		axi_ctrl->share_ctrl->vfebase + VFE_AXI_CMD);
-	wmb();
-	while (axi_busy_flag) {
-		if (msm_camera_io_r(
-			axi_ctrl->share_ctrl->vfebase + VFE_AXI_STATUS) & 0x1)
-			axi_busy_flag = false;
-	}
-	/* Ensure the write order while writing
-	* to the command register using the barrier */
-	msm_camera_io_w_mb(AXI_HALT_CLEAR,
-		axi_ctrl->share_ctrl->vfebase + VFE_AXI_CMD);
-
-	/* after axi halt, then ok to apply global reset.
-	* enable reset_ack and async timer interrupt only while
-	* stopping the pipeline.*/
-	msm_camera_io_w(0x80000000,
-		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_0);
-	msm_camera_io_w(0xF0000000,
-		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
-
-	/* Ensure the write order while writing
-	* to the command register using the barrier */
-	msm_camera_io_w_mb(VFE_RESET_UPON_STOP_CMD,
-		axi_ctrl->share_ctrl->vfebase + VFE_GLOBAL_RESET);
-	if (axi_ctrl->share_ctrl->sync_abort)
-		wait_for_completion_interruptible(
-			&axi_ctrl->share_ctrl->reset_complete);
-}
-
-int axi_config_buffers(struct axi_ctrl_t *axi_ctrl,
-	struct msm_camera_vfe_params_t vfe_params)
-{
-	uint16_t vfe_mode = axi_ctrl->share_ctrl->current_mode
-			& ~(VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1);
-	int rc = 0;
-	switch (vfe_params.cmd_type) {
-	case AXI_CMD_PREVIEW:
-		if (vfe_mode) {
-			if ((axi_ctrl->share_ctrl->current_mode &
-				VFE_OUTPUTS_PREVIEW_AND_VIDEO) ||
-				(axi_ctrl->share_ctrl->current_mode &
-				VFE_OUTPUTS_PREVIEW))
-				/* Configure primary channel */
-				rc = configure_pingpong_buffers(
-					VFE_MSG_START,
-					VFE_MSG_OUTPUT_PRIMARY,
-					axi_ctrl);
-			else
-			/* Configure secondary channel */
-				rc = configure_pingpong_buffers(
-					VFE_MSG_START,
-					VFE_MSG_OUTPUT_SECONDARY,
-					axi_ctrl);
-		}
-		if (axi_ctrl->share_ctrl->current_mode &
-				VFE_OUTPUTS_RDI0)
-			rc = configure_pingpong_buffers(
-				VFE_MSG_START, VFE_MSG_OUTPUT_TERTIARY1,
-				axi_ctrl);
-		if (axi_ctrl->share_ctrl->current_mode &
-				VFE_OUTPUTS_RDI1)
-			rc = configure_pingpong_buffers(
-				VFE_MSG_START, VFE_MSG_OUTPUT_TERTIARY2,
-				axi_ctrl);
-
-		if (rc < 0) {
-			pr_err("%s error configuring pingpong buffers for preview",
-				__func__);
-			rc = -EINVAL;
-			goto config_done;
-		}
-		break;
-	case AXI_CMD_RAW_CAPTURE:
-		rc = configure_pingpong_buffers(
-			VFE_MSG_CAPTURE, VFE_MSG_OUTPUT_PRIMARY,
-			axi_ctrl);
-		if (rc < 0) {
-			pr_err("%s error configuring pingpong buffers for snapshot",
-				__func__);
-			rc = -EINVAL;
-			goto config_done;
-		}
-		break;
-	case AXI_CMD_ZSL:
-		rc = configure_pingpong_buffers(VFE_MSG_START,
-			VFE_MSG_OUTPUT_PRIMARY, axi_ctrl);
-		if (rc < 0)
-			goto config_done;
-		rc = configure_pingpong_buffers(VFE_MSG_START,
-			VFE_MSG_OUTPUT_SECONDARY, axi_ctrl);
-		if (rc < 0)
-			goto config_done;
-		break;
-	case AXI_CMD_RECORD:
-		if (axi_ctrl->share_ctrl->current_mode &
-			VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
-			axi_ctrl->share_ctrl->outpath.out1.inst_handle =
-				vfe_params.inst_handle;
-			rc = configure_pingpong_buffers(
-				VFE_MSG_START_RECORDING,
-				VFE_MSG_OUTPUT_SECONDARY,
-				axi_ctrl);
-		} else if (axi_ctrl->share_ctrl->current_mode &
-			VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
-			axi_ctrl->share_ctrl->outpath.out0.inst_handle =
-				vfe_params.inst_handle;
-			rc = configure_pingpong_buffers(
-				VFE_MSG_START_RECORDING,
-				VFE_MSG_OUTPUT_PRIMARY,
-				axi_ctrl);
-		}
-		if (rc < 0) {
-			pr_err("%s error configuring pingpong buffers for video",
-				__func__);
-			rc = -EINVAL;
-			goto config_done;
-		}
-		break;
-	case AXI_CMD_LIVESHOT:
-		axi_ctrl->share_ctrl->outpath.out0.inst_handle =
-			vfe_params.inst_handle;
-		rc = configure_pingpong_buffers(VFE_MSG_CAPTURE,
-					VFE_MSG_OUTPUT_PRIMARY, axi_ctrl);
-		if (rc < 0) {
-			pr_err("%s error configuring pingpong buffers for primary output",
-				__func__);
-			rc = -EINVAL;
-			goto config_done;
-		}
-		break;
-	case AXI_CMD_CAPTURE:
-		if (axi_ctrl->share_ctrl->current_mode ==
-			VFE_OUTPUTS_JPEG_AND_THUMB ||
-		axi_ctrl->share_ctrl->current_mode ==
-			VFE_OUTPUTS_THUMB_AND_JPEG) {
-
-			/* Configure primary channel for JPEG */
-			rc = configure_pingpong_buffers(
-				VFE_MSG_JPEG_CAPTURE,
-				VFE_MSG_OUTPUT_PRIMARY,
-				axi_ctrl);
-		} else {
-			/* Configure primary channel */
-			rc = configure_pingpong_buffers(
-				VFE_MSG_CAPTURE,
-				VFE_MSG_OUTPUT_PRIMARY,
-				axi_ctrl);
-		}
-		if (rc < 0) {
-			pr_err("%s error configuring pingpong buffers for primary output",
-				__func__);
-			rc = -EINVAL;
-			goto config_done;
-		}
-		/* Configure secondary channel */
-		rc = configure_pingpong_buffers(
-				VFE_MSG_CAPTURE, VFE_MSG_OUTPUT_SECONDARY,
-				axi_ctrl);
-		if (rc < 0) {
-			pr_err("%s error configuring pingpong buffers for secondary output",
-				__func__);
-			rc = -EINVAL;
-			goto config_done;
-		}
-		break;
-	default:
-		rc = -EINVAL;
-		break;
-
-	}
-config_done:
-	return rc;
-}
-
-void axi_start(struct msm_cam_media_controller *pmctl,
-	struct axi_ctrl_t *axi_ctrl, struct msm_camera_vfe_params_t vfe_params)
-{
-	uint32_t irq_comp_mask = 0, irq_mask = 0;
-	int rc = 0;
-	uint32_t reg_update = 0;
-	uint16_t operation_mode =
-		(axi_ctrl->share_ctrl->current_mode &
-		~(VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1));
-	rc = axi_config_buffers(axi_ctrl, vfe_params);
-	if (rc < 0)
-		return;
-
-	switch (vfe_params.cmd_type) {
-	case AXI_CMD_PREVIEW:
-		msm_camera_bus_scale_cfg(axi_ctrl->bus_perf_client, S_PREVIEW);
-		break;
-	case AXI_CMD_CAPTURE:
-	case AXI_CMD_RAW_CAPTURE:
-		msm_camera_bus_scale_cfg(axi_ctrl->bus_perf_client, S_CAPTURE);
-		break;
-	case AXI_CMD_RECORD:
-		msm_camera_bus_scale_cfg(axi_ctrl->bus_perf_client, S_VIDEO);
-		return;
-	case AXI_CMD_ZSL:
-		msm_camera_bus_scale_cfg(axi_ctrl->bus_perf_client, S_ZSL);
-		break;
-	case AXI_CMD_LIVESHOT:
-		msm_camera_bus_scale_cfg(axi_ctrl->bus_perf_client, S_LIVESHOT);
-		return;
-	default:
-		return;
-	}
-
-	irq_comp_mask =
-		msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
-			VFE_IRQ_COMP_MASK);
-	irq_mask = msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
-			VFE_IRQ_MASK_0);
-
-	if (axi_ctrl->share_ctrl->outpath.output_mode &
-			VFE40_OUTPUT_MODE_PRIMARY) {
-		if (vfe_params.cmd_type == AXI_CMD_RAW_CAPTURE) {
-			irq_comp_mask |=
-				0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0;
-		} else {
-			irq_comp_mask |= (
-				0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0 |
-				0x1 << axi_ctrl->share_ctrl->outpath.out0.ch1);
-		}
-		irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
-	} else if (axi_ctrl->share_ctrl->outpath.output_mode &
-			   VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
-		irq_comp_mask |= (
-			0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0 |
-			0x1 << axi_ctrl->share_ctrl->outpath.out0.ch1 |
-			0x1 << axi_ctrl->share_ctrl->outpath.out0.ch2);
-		irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
-	}
-	if (axi_ctrl->share_ctrl->outpath.output_mode &
-			VFE40_OUTPUT_MODE_SECONDARY) {
-		irq_comp_mask |= (
-			0x1 << (axi_ctrl->share_ctrl->outpath.out1.ch0 + 8) |
-			0x1 << (axi_ctrl->share_ctrl->outpath.out1.ch1 + 8));
-		irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
-	} else if (axi_ctrl->share_ctrl->outpath.output_mode &
-			VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
-		irq_comp_mask |= (
-			0x1 << (axi_ctrl->share_ctrl->outpath.out1.ch0 + 8) |
-			0x1 << (axi_ctrl->share_ctrl->outpath.out1.ch1 + 8) |
-			0x1 << (axi_ctrl->share_ctrl->outpath.out1.ch2 + 8));
-		irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
-	}
-	if (axi_ctrl->share_ctrl->outpath.output_mode &
-		VFE40_OUTPUT_MODE_TERTIARY1) {
-		irq_mask |= (0x1 << (axi_ctrl->share_ctrl->outpath.out2.ch0 +
-			VFE_WM_OFFSET));
-	}
-	if (axi_ctrl->share_ctrl->outpath.output_mode &
-		VFE40_OUTPUT_MODE_TERTIARY2) {
-		irq_mask |= (0x1 << (axi_ctrl->share_ctrl->outpath.out3.ch0 +
-			VFE_WM_OFFSET));
-	}
-
-	msm_camera_io_w(irq_comp_mask,
-		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
-	msm_camera_io_w(irq_mask, axi_ctrl->share_ctrl->vfebase +
-			VFE_IRQ_MASK_0);
-
-	switch (vfe_params.cmd_type) {
-	case AXI_CMD_PREVIEW: {
-		switch (operation_mode) {
-		case VFE_OUTPUTS_PREVIEW:
-		case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
-			if (axi_ctrl->share_ctrl->outpath.output_mode &
-				VFE40_OUTPUT_MODE_PRIMARY) {
-				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
-					+ vfe40_AXI_WM_CFG[axi_ctrl->
-					share_ctrl->outpath.out0.ch0]);
-				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
-					+ vfe40_AXI_WM_CFG[axi_ctrl->
-					share_ctrl->outpath.out0.ch1]);
-			} else if (axi_ctrl->share_ctrl->outpath.output_mode &
-					VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
-				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
-					+ vfe40_AXI_WM_CFG[axi_ctrl->
-					share_ctrl->outpath.out0.ch0]);
-				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
-					+ vfe40_AXI_WM_CFG[axi_ctrl->
-					share_ctrl->outpath.out0.ch1]);
-				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
-					+ vfe40_AXI_WM_CFG[axi_ctrl->
-					share_ctrl->outpath.out0.ch2]);
-			}
-			break;
-		default:
-			if (axi_ctrl->share_ctrl->outpath.output_mode &
-				VFE40_OUTPUT_MODE_SECONDARY) {
-				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
-					+ vfe40_AXI_WM_CFG[axi_ctrl->
-					share_ctrl->outpath.out1.ch0]);
-				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
-					+ vfe40_AXI_WM_CFG[axi_ctrl->
-					share_ctrl->outpath.out1.ch1]);
-			} else if (axi_ctrl->share_ctrl->outpath.output_mode &
-				VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
-				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
-					+ vfe40_AXI_WM_CFG[axi_ctrl->
-					share_ctrl->outpath.out1.ch0]);
-				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
-					+ vfe40_AXI_WM_CFG[axi_ctrl->
-					share_ctrl->outpath.out1.ch1]);
-				msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
-					+ vfe40_AXI_WM_CFG[axi_ctrl->
-					share_ctrl->outpath.out1.ch2]);
-			}
-			break;
-			}
-		}
-		break;
-	default:
-		if (axi_ctrl->share_ctrl->outpath.output_mode &
-			VFE40_OUTPUT_MODE_PRIMARY) {
-			if (vfe_params.cmd_type == AXI_CMD_RAW_CAPTURE) {
-				msm_camera_io_w(1,
-					axi_ctrl->share_ctrl->vfebase +
-					vfe40_AXI_WM_CFG[axi_ctrl->
-					share_ctrl->outpath.out0.ch0]);
-			} else {
-				msm_camera_io_w(1,
-					axi_ctrl->share_ctrl->vfebase +
-					vfe40_AXI_WM_CFG[axi_ctrl
-					->share_ctrl->outpath.out0.ch0]);
-				msm_camera_io_w(1,
-					axi_ctrl->share_ctrl->vfebase +
-					vfe40_AXI_WM_CFG[axi_ctrl->
-					share_ctrl->outpath.out0.ch1]);
-			}
-		} else if (axi_ctrl->share_ctrl->outpath.output_mode &
-				VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out0.ch1]);
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out0.ch2]);
-		}
-
-		if (axi_ctrl->share_ctrl->outpath.output_mode &
-			VFE40_OUTPUT_MODE_SECONDARY) {
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out1.ch0]);
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out1.ch1]);
-		} else if (axi_ctrl->share_ctrl->outpath.output_mode &
-			VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out1.ch0]);
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out1.ch1]);
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out1.ch2]);
-		}
-		break;
-	}
-
-	if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI0)
-		msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-			vfe40_AXI_WM_CFG[axi_ctrl->share_ctrl->
-			outpath.out2.ch0]);
-	if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI1)
-		msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-			vfe40_AXI_WM_CFG[axi_ctrl->share_ctrl->
-			outpath.out3.ch0]);
-
-	if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
-		irq_mask |= VFE_IRQ_STATUS0_RDI0_REG_UPDATE_MASK;
-		if (!atomic_cmpxchg(
-			&axi_ctrl->share_ctrl->rdi0_update_ack_pending,
-				0, 1))
-			reg_update |= 0x2;
-	}
-	if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
-		irq_mask |= VFE_IRQ_STATUS0_RDI1_REG_UPDATE_MASK;
-		if (!atomic_cmpxchg(
-			&axi_ctrl->share_ctrl->rdi1_update_ack_pending,
-				0, 1))
-			reg_update |= 0x4;
-	}
-	msm_camera_io_w(irq_mask, axi_ctrl->share_ctrl->vfebase +
-		VFE_IRQ_MASK_0);
-	if (operation_mode) {
-		if (!atomic_cmpxchg(
-			&axi_ctrl->share_ctrl->pix0_update_ack_pending,
-				0, 1))
-			reg_update |= 0x1;
-	}
-
-	msm_camera_io_w_mb(reg_update,
-			axi_ctrl->share_ctrl->vfebase +
-			VFE_REG_UPDATE_CMD);
-	axi_ctrl->share_ctrl->operation_mode |=
-		axi_ctrl->share_ctrl->current_mode;
-	axi_enable_irq(axi_ctrl->share_ctrl);
-}
-
-void axi_stop(struct msm_cam_media_controller *pmctl,
-	struct axi_ctrl_t *axi_ctrl, struct msm_camera_vfe_params_t vfe_params)
-{
-	uint32_t reg_update = 0;
-	uint32_t operation_mode =
-	axi_ctrl->share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
-		VFE_OUTPUTS_RDI1);
-
-	switch (vfe_params.cmd_type) {
-	case AXI_CMD_PREVIEW:
-	case AXI_CMD_CAPTURE:
-	case AXI_CMD_RAW_CAPTURE:
-	case AXI_CMD_ZSL:
-		break;
-	case AXI_CMD_RECORD:
-		msm_camera_bus_scale_cfg(axi_ctrl->bus_perf_client, S_PREVIEW);
-		return;
-	case AXI_CMD_LIVESHOT:
-		msm_camera_bus_scale_cfg(axi_ctrl->bus_perf_client, S_VIDEO);
-		return;
-	default:
-		return;
-	}
-
-	if (axi_ctrl->share_ctrl->stop_immediately) {
-		axi_disable_irq(axi_ctrl->share_ctrl);
-		axi_stop_process(axi_ctrl->share_ctrl);
-		return;
-	}
-
-	if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
-		if (!atomic_cmpxchg(
-			&axi_ctrl->share_ctrl->rdi0_update_ack_pending, 0, 2))
-			reg_update |= 0x2;
-	}
-	if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
-		if (!atomic_cmpxchg(
-			&axi_ctrl->share_ctrl->rdi1_update_ack_pending, 0, 2))
-			reg_update |= 0x4;
-	}
-	if (operation_mode) {
-		if (!atomic_cmpxchg(
-			&axi_ctrl->share_ctrl->pix0_update_ack_pending, 0, 2))
-			reg_update |= 0x1;
-	}
-	msm_camera_io_w_mb(reg_update,
-		axi_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-}
-
-static int msm_axi_config(struct v4l2_subdev *sd, void __user *arg)
-{
-	struct msm_vfe_cfg_cmd cfgcmd;
-	struct msm_isp_cmd vfecmd;
-	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
-	struct msm_cam_media_controller *pmctl =
-		(struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
-	int rc = 0, vfe_cmd_type = 0, rdi_mode = 0;
-
-	if (!axi_ctrl->share_ctrl->vfebase) {
-		pr_err("%s: base address unmapped\n", __func__);
-		return -EFAULT;
-	}
-	memset(&cfgcmd, 0, sizeof(struct msm_vfe_cfg_cmd));
-	if (NULL != arg) {
-		if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
-			ERR_COPY_FROM_USER();
-			return -EFAULT;
-		}
-	}
-	memset(&vfecmd, 0, sizeof(struct msm_isp_cmd));
-	if (NULL != cfgcmd.value) {
-		if (copy_from_user(&vfecmd,
-				(void __user *)(cfgcmd.value),
-				sizeof(vfecmd))) {
-			pr_err("%s %d: copy_from_user failed\n", __func__,
-				__LINE__);
-			return -EFAULT;
-		}
-	}
-
-	vfe_cmd_type = (cfgcmd.cmd_type & ~(CMD_AXI_CFG_TERT1|
-		CMD_AXI_CFG_TERT2));
-	switch (cfgcmd.cmd_type) {
-	case CMD_AXI_CFG_TERT1:{
-		uint32_t *axio = NULL;
-		axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio)
-			return -ENOMEM;
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			return -EFAULT;
-		}
-		vfe40_config_axi(axi_ctrl, OUTPUT_TERT1, axio);
-		kfree(axio);
-		return rc;
-		}
-	case CMD_AXI_CFG_TERT2:{
-		uint32_t *axio = NULL;
-		axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio)
-			return -ENOMEM;
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			return -EFAULT;
-		}
-		vfe40_config_axi(axi_ctrl, OUTPUT_TERT2, axio);
-		kfree(axio);
-		return rc;
-		}
-	case CMD_AXI_CFG_TERT1|CMD_AXI_CFG_TERT2:{
-		uint32_t *axio = NULL;
-		axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio)
-			return -ENOMEM;
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			return -EFAULT;
-		}
-		vfe40_config_axi(axi_ctrl, OUTPUT_TERT1|OUTPUT_TERT2, axio);
-		kfree(axio);
-		return rc;
-		}
-	default:
-		if (cfgcmd.cmd_type & CMD_AXI_CFG_TERT1)
-			rdi_mode |= OUTPUT_TERT1;
-		if (cfgcmd.cmd_type & CMD_AXI_CFG_TERT2)
-			rdi_mode |= OUTPUT_TERT2;
-	}
-	switch (vfe_cmd_type) {
-	case CMD_AXI_CFG_PRIM: {
-		uint32_t *axio = NULL;
-		axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			break;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			rc = -EFAULT;
-			break;
-		}
-		vfe40_config_axi(axi_ctrl, rdi_mode|OUTPUT_PRIM, axio);
-		kfree(axio);
-		break;
-		}
-	case CMD_AXI_CFG_PRIM_ALL_CHNLS: {
-		uint32_t *axio = NULL;
-		axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			break;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			rc = -EFAULT;
-			break;
-		}
-		vfe40_config_axi(axi_ctrl, rdi_mode|OUTPUT_PRIM_ALL_CHNLS,
-			axio);
-		kfree(axio);
-		break;
-		}
-	case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC: {
-		uint32_t *axio = NULL;
-		axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			break;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			rc = -EFAULT;
-			break;
-		}
-		vfe40_config_axi(axi_ctrl,
-			rdi_mode|OUTPUT_PRIM|OUTPUT_SEC, axio);
-		kfree(axio);
-		break;
-		}
-	case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC_ALL_CHNLS: {
-		uint32_t *axio = NULL;
-		axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			break;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			rc = -EFAULT;
-			break;
-		}
-		vfe40_config_axi(axi_ctrl,
-			rdi_mode|OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS, axio);
-		kfree(axio);
-		break;
-		}
-	case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC: {
-		uint32_t *axio = NULL;
-		axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			break;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			rc = -EFAULT;
-			break;
-		}
-		vfe40_config_axi(axi_ctrl,
-			rdi_mode|OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC, axio);
-		kfree(axio);
-		break;
-		}
-
-	case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC_ALL_CHNLS:
-		pr_err("%s Invalid/Unsupported AXI configuration %x",
-			__func__, cfgcmd.cmd_type);
-		break;
-	case CMD_AXI_START: {
-		struct msm_camera_vfe_params_t vfe_params;
-		if (copy_from_user(&vfe_params,
-				(void __user *)(vfecmd.value),
-				sizeof(struct msm_camera_vfe_params_t))) {
-				return -EFAULT;
-		}
-		axi_ctrl->share_ctrl->current_mode =
-			vfe_params.operation_mode;
-		axi_start(pmctl, axi_ctrl, vfe_params);
-		}
-		break;
-	case CMD_AXI_STOP: {
-		struct msm_camera_vfe_params_t vfe_params;
-		if (copy_from_user(&vfe_params,
-				(void __user *)(vfecmd.value),
-				sizeof(struct msm_camera_vfe_params_t))) {
-				return -EFAULT;
-		}
-		axi_ctrl->share_ctrl->current_mode =
-			vfe_params.operation_mode;
-		axi_ctrl->share_ctrl->stop_immediately =
-			vfe_params.stop_immediately;
-		axi_stop(pmctl, axi_ctrl, vfe_params);
-		}
-		break;
-	case CMD_AXI_RESET:
-		axi_reset(axi_ctrl);
-		break;
-	case CMD_AXI_ABORT:
-		if (copy_from_user(&axi_ctrl->share_ctrl->sync_abort,
-				(void __user *)(vfecmd.value),
-				sizeof(uint8_t))) {
-				return -EFAULT;
-		}
-		axi_abort(axi_ctrl);
-		break;
-	default:
-		pr_err("%s Unsupported AXI configuration %x ", __func__,
-			cfgcmd.cmd_type);
-		break;
-	}
-	return rc;
-}
-
-static void msm_axi_process_irq(struct v4l2_subdev *sd, void *arg)
-{
-	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
-	uint32_t irqstatus = (uint32_t) arg;
-
-	if (!axi_ctrl->share_ctrl->vfebase) {
-		pr_err("%s: base address unmapped\n", __func__);
-		return;
-	}
-
-	/* next, check output path related interrupts. */
-	if (irqstatus &
-		VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK) {
-		CDBG("Image composite done 0 irq occured.\n");
-		vfe40_process_output_path_irq_0(axi_ctrl);
-	}
-	if (irqstatus &
-		VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK) {
-		CDBG("Image composite done 1 irq occured.\n");
-		vfe40_process_output_path_irq_1(axi_ctrl);
-	}
-
-	if (axi_ctrl->share_ctrl->comp_output_mode &
-		VFE40_OUTPUT_MODE_TERTIARY1)
-		if (irqstatus & (0x1 << (axi_ctrl->share_ctrl->outpath.out2.ch0
-			+ VFE_WM_OFFSET)))
-			vfe40_process_output_path_irq_rdi0(axi_ctrl);
-	if (axi_ctrl->share_ctrl->comp_output_mode &
-		VFE40_OUTPUT_MODE_TERTIARY2)
-		if (irqstatus & (0x1 << (axi_ctrl->share_ctrl->outpath.out3.ch0
-			+ VFE_WM_OFFSET)))
-			vfe40_process_output_path_irq_rdi1(axi_ctrl);
-
-	/* in snapshot mode if done then send
-	snapshot done message */
-	if (
-		axi_ctrl->share_ctrl->operation_mode &
-			VFE_OUTPUTS_THUMB_AND_MAIN ||
-		axi_ctrl->share_ctrl->operation_mode &
-			VFE_OUTPUTS_MAIN_AND_THUMB ||
-		axi_ctrl->share_ctrl->operation_mode &
-			VFE_OUTPUTS_THUMB_AND_JPEG ||
-		axi_ctrl->share_ctrl->operation_mode &
-			VFE_OUTPUTS_JPEG_AND_THUMB ||
-		axi_ctrl->share_ctrl->operation_mode &
-			VFE_OUTPUTS_RAW) {
-		if ((axi_ctrl->share_ctrl->outpath.out0.capture_cnt == 0)
-				&& (axi_ctrl->share_ctrl->outpath.out1.
-				capture_cnt == 0)) {
-			msm_camera_io_w_mb(
-				CAMIF_COMMAND_STOP_IMMEDIATELY,
-				axi_ctrl->share_ctrl->vfebase +
-				VFE_CAMIF_COMMAND);
-			axi_disable_irq(axi_ctrl->share_ctrl);
-			vfe40_send_isp_msg(&axi_ctrl->subdev,
-				axi_ctrl->share_ctrl->vfeFrameId,
-				MSG_ID_PIX0_UPDATE_ACK);
-			vfe40_send_isp_msg(&axi_ctrl->subdev,
-				axi_ctrl->share_ctrl->vfeFrameId,
-				MSG_ID_SNAPSHOT_DONE);
-		}
-	}
-}
-
-static int msm_axi_buf_cfg(struct v4l2_subdev *sd, void __user *arg)
-{
-	struct msm_camvfe_params *vfe_params =
-		(struct msm_camvfe_params *)arg;
-	struct msm_vfe_cfg_cmd *cmd = vfe_params->vfe_cfg;
-	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
-	void *data = vfe_params->data;
-	int rc = 0;
-
-	if (!axi_ctrl->share_ctrl->vfebase) {
-		pr_err("%s: base address unmapped\n", __func__);
-		return -EFAULT;
-	}
-
-	switch (cmd->cmd_type) {
-	case CMD_CONFIG_PING_ADDR: {
-		int path = *((int *)cmd->value);
-		struct vfe40_output_ch *outch =
-			vfe40_get_ch(path, axi_ctrl->share_ctrl);
-		outch->ping = *((struct msm_free_buf *)data);
-	}
-		break;
-
-	case CMD_CONFIG_PONG_ADDR: {
-		int path = *((int *)cmd->value);
-		struct vfe40_output_ch *outch =
-			vfe40_get_ch(path, axi_ctrl->share_ctrl);
-		outch->pong = *((struct msm_free_buf *)data);
-	}
-		break;
-
-	case CMD_CONFIG_FREE_BUF_ADDR: {
-		int path = *((int *)cmd->value);
-		struct vfe40_output_ch *outch =
-			vfe40_get_ch(path, axi_ctrl->share_ctrl);
-		outch->free_buf = *((struct msm_free_buf *)data);
-	}
-		break;
-	default:
-		pr_err("%s Unsupported AXI Buf config %x ", __func__,
-			cmd->cmd_type);
-	}
-	return rc;
-};
-
-static const struct v4l2_subdev_internal_ops msm_vfe_internal_ops;
-
-static long msm_axi_subdev_ioctl(struct v4l2_subdev *sd,
-			unsigned int cmd, void *arg)
-{
-	int rc = -ENOIOCTLCMD;
-	switch (cmd) {
-	case VIDIOC_MSM_AXI_INIT:
-		rc = msm_axi_subdev_init(sd);
-		break;
-	case VIDIOC_MSM_AXI_CFG:
-		rc = msm_axi_config(sd, arg);
-		break;
-	case VIDIOC_MSM_AXI_IRQ:
-		msm_axi_process_irq(sd, arg);
-		rc = 0;
-		break;
-	case VIDIOC_MSM_AXI_BUF_CFG:
-		msm_axi_buf_cfg(sd, arg);
-		rc = 0;
-		break;
-	case VIDIOC_MSM_AXI_RELEASE:
-		msm_axi_subdev_release(sd);
-		rc = 0;
-		break;
-	case VIDIOC_MSM_AXI_RDI_COUNT_UPDATE: {
-		struct rdi_count_msg *msg = (struct rdi_count_msg *)arg;
-		struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
-		switch (msg->rdi_interface) {
-		case RDI_0:
-			axi_ctrl->share_ctrl->rdi0FrameId = msg->count;
-			rc = 0;
-			break;
-		case RDI_1:
-			axi_ctrl->share_ctrl->rdi1FrameId = msg->count;
-			rc = 0;
-			break;
-		case RDI_2:
-			axi_ctrl->share_ctrl->rdi2FrameId = msg->count;
-			rc = 0;
-			break;
-		default:
-			pr_err("%s: Incorrect interface sent\n", __func__);
-			rc = -EINVAL;
-			break;
-		}
-		break;
-	}
-	default:
-		pr_err("%s: command %d not found\n", __func__,
-						_IOC_NR(cmd));
-		break;
-	}
-	return rc;
-}
-
-static const struct v4l2_subdev_core_ops msm_axi_subdev_core_ops = {
-	.ioctl = msm_axi_subdev_ioctl,
-	.interrupt_service_routine = msm_axi_subdev_isr_routine,
-};
-
-static const struct v4l2_subdev_video_ops msm_axi_subdev_video_ops = {
-	.s_crystal_freq = msm_axi_subdev_s_crystal_freq,
-};
-
-static const struct v4l2_subdev_ops msm_axi_subdev_ops = {
-	.core = &msm_axi_subdev_core_ops,
-	.video = &msm_axi_subdev_video_ops,
-};
-
-static const struct v4l2_subdev_internal_ops msm_axi_internal_ops;
-
-static int __devinit vfe40_probe(struct platform_device *pdev)
-{
-	int rc = 0;
-	struct axi_ctrl_t *axi_ctrl;
-	struct vfe40_ctrl_type *vfe40_ctrl;
-	struct vfe_share_ctrl_t *share_ctrl;
-	struct intr_table_entry irq_req;
-	struct msm_cam_subdev_info sd_info;
-	CDBG("%s: device id = %d\n", __func__, pdev->id);
-
-	share_ctrl = kzalloc(sizeof(struct vfe_share_ctrl_t), GFP_KERNEL);
-	if (!share_ctrl) {
-		pr_err("%s: no enough memory\n", __func__);
-		return -ENOMEM;
-	}
-
-	axi_ctrl = kzalloc(sizeof(struct axi_ctrl_t), GFP_KERNEL);
-	if (!axi_ctrl) {
-		pr_err("%s: no enough memory\n", __func__);
-		kfree(share_ctrl);
-		return -ENOMEM;
-	}
-
-	vfe40_ctrl = kzalloc(sizeof(struct vfe40_ctrl_type), GFP_KERNEL);
-	if (!vfe40_ctrl) {
-		pr_err("%s: no enough memory\n", __func__);
-		kfree(share_ctrl);
-		kfree(axi_ctrl);
-		return -ENOMEM;
-	}
-
-	if (pdev->dev.of_node)
-		of_property_read_u32((&pdev->dev)->of_node,
-			"cell-index", &pdev->id);
-
-	share_ctrl->axi_ctrl = axi_ctrl;
-	share_ctrl->vfe40_ctrl = vfe40_ctrl;
-	axi_ctrl->share_ctrl = share_ctrl;
-	vfe40_ctrl->share_ctrl = share_ctrl;
-	axi_ctrl->share_ctrl->axi_ref_cnt = 0;
-	v4l2_subdev_init(&axi_ctrl->subdev, &msm_axi_subdev_ops);
-	axi_ctrl->subdev.internal_ops = &msm_axi_internal_ops;
-	axi_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-	snprintf(axi_ctrl->subdev.name,
-			 sizeof(axi_ctrl->subdev.name), "axi");
-	v4l2_set_subdevdata(&axi_ctrl->subdev, axi_ctrl);
-	axi_ctrl->pdev = pdev;
-
-	sd_info.sdev_type = AXI_DEV;
-	sd_info.sd_index = pdev->id;
-	sd_info.irq_num = 0;
-	msm_cam_register_subdev_node(&axi_ctrl->subdev, &sd_info);
-
-	media_entity_init(&axi_ctrl->subdev.entity, 0, NULL, 0);
-	axi_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
-	axi_ctrl->subdev.entity.group_id = AXI_DEV;
-	axi_ctrl->subdev.entity.name = pdev->name;
-	axi_ctrl->subdev.entity.revision = axi_ctrl->subdev.devnode->num;
-
-	v4l2_subdev_init(&vfe40_ctrl->subdev, &msm_vfe_subdev_ops);
-	vfe40_ctrl->subdev.internal_ops = &msm_vfe_internal_ops;
-	vfe40_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-	snprintf(vfe40_ctrl->subdev.name,
-			 sizeof(vfe40_ctrl->subdev.name), "vfe4.0");
-	v4l2_set_subdevdata(&vfe40_ctrl->subdev, vfe40_ctrl);
-	platform_set_drvdata(pdev, &vfe40_ctrl->subdev);
-
-	axi_ctrl->vfemem = platform_get_resource_byname(pdev,
-					IORESOURCE_MEM, "vfe");
-	if (!axi_ctrl->vfemem) {
-		pr_err("%s: no mem resource?\n", __func__);
-		rc = -ENODEV;
-		goto vfe40_no_resource;
-	}
-
-	axi_ctrl->vfe_vbif_mem = platform_get_resource_byname(pdev,
-					IORESOURCE_MEM, "vfe_vbif");
-	if (!axi_ctrl->vfe_vbif_mem) {
-		pr_err("%s: no mem resource?\n", __func__);
-		rc = -ENODEV;
-		goto vfe40_no_resource;
-	}
-
-	axi_ctrl->vfeirq = platform_get_resource_byname(pdev,
-					IORESOURCE_IRQ, "vfe");
-	if (!axi_ctrl->vfeirq) {
-		pr_err("%s: no irq resource?\n", __func__);
-		rc = -ENODEV;
-		goto vfe40_no_resource;
-	}
-
-	axi_ctrl->vfeio = request_mem_region(axi_ctrl->vfemem->start,
-		resource_size(axi_ctrl->vfemem), pdev->name);
-	if (!axi_ctrl->vfeio) {
-		pr_err("%s: no valid mem region\n", __func__);
-		rc = -EBUSY;
-		goto vfe40_no_resource;
-	}
-
-	axi_ctrl->fs_vfe = regulator_get(&pdev->dev, "vdd");
-	if (IS_ERR(axi_ctrl->fs_vfe)) {
-		pr_err("%s: Regulator get failed %ld\n", __func__,
-			PTR_ERR(axi_ctrl->fs_vfe));
-		axi_ctrl->fs_vfe = NULL;
-	}
-
-	/* Register subdev node before requesting irq since
-	 * irq_num is needed by msm_cam_server */
-	sd_info.sdev_type = VFE_DEV;
-	sd_info.sd_index = pdev->id;
-	sd_info.irq_num = axi_ctrl->vfeirq->start;
-	msm_cam_register_subdev_node(&vfe40_ctrl->subdev, &sd_info);
-
-	media_entity_init(&vfe40_ctrl->subdev.entity, 0, NULL, 0);
-	vfe40_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
-	vfe40_ctrl->subdev.entity.group_id = VFE_DEV;
-	vfe40_ctrl->subdev.entity.name = pdev->name;
-	vfe40_ctrl->subdev.entity.revision = vfe40_ctrl->subdev.devnode->num;
-
-	/* Request for this device irq from the camera server. If the
-	 * IRQ Router is present on this target, the interrupt will be
-	 * handled by the camera server and the interrupt service
-	 * routine called. If the request_irq call returns ENXIO, then
-	 * the IRQ Router hardware is not present on this target. We
-	 * have to request for the irq ourselves and register the
-	 * appropriate interrupt handler. */
-	axi_ctrl->use_irq_router = true;
-	irq_req.cam_hw_idx       = MSM_CAM_HW_VFE0 + pdev->id;
-	irq_req.dev_name         = "vfe";
-	irq_req.irq_idx          = CAMERA_SS_IRQ_8;
-	irq_req.irq_num          = axi_ctrl->vfeirq->start;
-	irq_req.is_composite     = 0;
-	irq_req.irq_trigger_type = IRQF_TRIGGER_RISING;
-	irq_req.num_hwcore       = 1;
-	irq_req.subdev_list[0]   = &axi_ctrl->subdev;
-	irq_req.data             = (void *)axi_ctrl;
-	rc = msm_cam_server_request_irq(&irq_req);
-	if (rc == -ENXIO) {
-		/* IRQ Router hardware is not present on this hardware.
-		 * Request for the IRQ and register the interrupt handler. */
-		axi_ctrl->use_irq_router = false;
-		rc = request_irq(axi_ctrl->vfeirq->start, vfe40_parse_irq,
-			IRQF_TRIGGER_RISING, "vfe", axi_ctrl);
-		if (rc < 0) {
-			release_mem_region(axi_ctrl->vfemem->start,
-				resource_size(axi_ctrl->vfemem));
-			pr_err("%s: irq request fail\n", __func__);
-			rc = -EBUSY;
-			goto vfe40_no_resource;
-		}
-		disable_irq(axi_ctrl->vfeirq->start);
-	} else if (rc < 0) {
-		pr_err("%s Error registering irq ", __func__);
-		goto vfe40_no_resource;
-	}
-
-	/*get device context for IOMMU*/
-	if (pdev->id == 0)
-		axi_ctrl->iommu_ctx = msm_iommu_get_ctx("vfe0");
-	else if (pdev->id == 1)
-		axi_ctrl->iommu_ctx = msm_iommu_get_ctx("vfe1");
-	if (!axi_ctrl->iommu_ctx) {
-		release_mem_region(axi_ctrl->vfemem->start,
-			resource_size(axi_ctrl->vfemem));
-		pr_err("%s: No iommu fw context found\n", __func__);
-		rc = -ENODEV;
-		goto vfe40_no_resource;
-	}
-
-	tasklet_init(&axi_ctrl->vfe40_tasklet,
-		axi40_do_tasklet, (unsigned long)axi_ctrl);
-
-	vfe40_ctrl->pdev = pdev;
-	/*enable bayer stats by default*/
-	vfe40_ctrl->ver_num.main = 4;
-
-	return 0;
-
-vfe40_no_resource:
-	kfree(vfe40_ctrl);
-	kfree(axi_ctrl);
-	return 0;
-}
-
-static const struct of_device_id msm_vfe_dt_match[] = {
-	{.compatible = "qcom,vfe40"},
-};
-
-MODULE_DEVICE_TABLE(of, msm_vfe_dt_match);
-
-static struct platform_driver vfe40_driver = {
-	.probe = vfe40_probe,
-	.driver = {
-		.name = MSM_VFE_DRV_NAME,
-		.owner = THIS_MODULE,
-		.of_match_table = msm_vfe_dt_match,
-	},
-};
-
-static int __init msm_vfe40_init_module(void)
-{
-	return platform_driver_register(&vfe40_driver);
-}
-
-static void __exit msm_vfe40_exit_module(void)
-{
-	platform_driver_unregister(&vfe40_driver);
-}
-
-module_init(msm_vfe40_init_module);
-module_exit(msm_vfe40_exit_module);
-MODULE_DESCRIPTION("VFE 4.0 driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/vfe/msm_vfe40.h b/drivers/media/video/msm/vfe/msm_vfe40.h
deleted file mode 100644
index a94c428..0000000
--- a/drivers/media/video/msm/vfe/msm_vfe40.h
+++ /dev/null
@@ -1,1063 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 __MSM_VFE40_H__
-#define __MSM_VFE40_H__
-
-#include <linux/bitops.h>
-#include "msm_vfe_stats_buf.h"
-
-#define TRUE  1
-#define FALSE 0
-
-#define VFE40_HW_NUMBER 0x10000015
-
-/* This defines total number registers in VFE.
- * Each register is 4 bytes so to get the range,
- * multiply this number with 4. */
-#define VFE40_REGISTER_TOTAL 0x00000320
-
-/* at stop of vfe pipeline, for now it is assumed
- * that camif will stop at any time. Bit 1:0 = 0x10:
- * disable image data capture immediately. */
-#define CAMIF_COMMAND_STOP_IMMEDIATELY  0x00000002
-
-/* at stop of vfe pipeline, for now it is assumed
- * that camif will stop at any time. Bit 1:0 = 0x00:
- * disable image data capture at frame boundary */
-#define CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY  0x00000000
-
-/* to halt axi bridge */
-#define AXI_HALT  0x00000001
-
-/* clear the halt bit. */
-#define AXI_HALT_CLEAR  0x00000000
-
-/* reset the pipeline when stop command is issued.
- * (without reset the register.) bit 26-32 = 0,
- * domain reset, bit 0-9 = 1 for module reset, except
- * register module. */
-#define VFE_RESET_UPON_STOP_CMD  0x000003ef
-
-/* reset the pipeline when reset command.
- * bit 26-32 = 0, domain reset, bit 0-9 = 1 for module reset. */
-#define VFE_RESET_UPON_RESET_CMD  0x000003ff
-
-/* reset the vfe only when reset command*/
-#define VFE_ONLY_RESET_CMD  0x00000002
-
-/*Vfe module reset command*/
-#define VFE_MODULE_RESET_CMD 0x07ffffff
-
-/* wm bit offset for IRQ MASK and IRQ STATUS register */
-#define VFE_WM_OFFSET 6
-
-/* constants for irq registers */
-#define VFE_DISABLE_ALL_IRQS 0
-/* bit =1 is to clear the corresponding bit in VFE_IRQ_STATUS.  */
-#define VFE_CLEAR_ALL_IRQ0   0xffff7fff
-#define VFE_CLEAR_ALL_IRQ1   0xffffffff
-
-#define VFE_IRQ_STATUS0_CAMIF_SOF_MASK            (0x00000001<<0)
-#define VFE_IRQ_STATUS0_REG_UPDATE_MASK           (0x00000001<<4)
-#define VFE_IRQ_STATUS0_RDI0_REG_UPDATE_MASK      (0x00000001<<5)
-#define VFE_IRQ_STATUS0_RDI1_REG_UPDATE_MASK      (0x00000001<<6)
-#define VFE_IRQ_STATUS0_RDI2_REG_UPDATE_MASK      (0x00000001<<7)
-#define VFE_IRQ_STATUS0_STATS_BE                  (0x00000001<<16)
-#define VFE_IRQ_STATUS0_STATS_BG                  (0x00000001<<17)
-#define VFE_IRQ_STATUS0_STATS_BF                  (0x00000001<<18)
-#define VFE_IRQ_STATUS0_STATS_AWB                 (0x00000001<<19)
-#define VFE_IRQ_STATUS0_STATS_RS                  (0x00000001<<20)
-#define VFE_IRQ_STATUS0_STATS_CS                  (0x00000001<<21)
-#define VFE_IRQ_STATUS0_STATS_IHIST               (0x00000001<<22)
-#define VFE_IRQ_STATUS0_STATS_SKIN_BHIST          (0x00000001<<23)
-#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK (0x00000001<<25)
-#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK (0x00000001<<26)
-#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE2_MASK (0x00000001<<27)
-#define VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE3_MASK (0x00000001<<28)
-#define VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK_0     (0x00000001<<29)
-#define VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK_1     (0x00000001<<30)
-#define VFE_IRQ_STATUS0_RESET_AXI_HALT_ACK_MASK   (0x00000001<<31)
-
-#define VFE_IRQ_STATUS1_SYNC_TIMER0               (0x00000001<<25)
-#define VFE_IRQ_STATUS1_SYNC_TIMER1               (0x00000001<<26)
-#define VFE_IRQ_STATUS1_SYNC_TIMER2               (0x00000001<<27)
-#define VFE_IRQ_STATUS1_ASYNC_TIMER0              (0x00000001<<28)
-#define VFE_IRQ_STATUS1_ASYNC_TIMER1              (0x00000001<<29)
-#define VFE_IRQ_STATUS1_ASYNC_TIMER2              (0x00000001<<30)
-#define VFE_IRQ_STATUS1_ASYNC_TIMER3              (0x00000001<<31)
-
-/*TODOs the irq status passed from axi to vfe irq handler does not account
-* for 2 irq status registers. So below macro is added to differentiate between
-* same bit set on both irq status registers. This wil be fixed later by passing
-*entire payload to vfe irq handler and parsing there instead of passing just the
-*status bit*/
-
-#define VFE_IRQ_STATUS0_RDI0_REG_UPDATE  VFE_IRQ_STATUS0_RDI0_REG_UPDATE_MASK
-#define VFE_IRQ_STATUS0_RDI1_REG_UPDATE  VFE_IRQ_STATUS0_RDI1_REG_UPDATE_MASK
-
-/* imask for while waiting for stop ack,  driver has already
- * requested stop, waiting for reset irq, and async timer irq.
- * For irq_status_1, bit 28-32 are for async timer. For
- * irq_status_0, bit 31 for reset irq, bit 23 for axi_halt_ack
-   irq */
-#define VFE_IMASK_WHILE_STOPPING_0  0x80000000
-#define VFE_IMASK_WHILE_STOPPING_1  0xF0000000
-
-/* For ABF bit 4 is set to zero and other's 1 */
-#define ABF_MASK 0xFFFFFFF7
-
-/* For DBPC bit 0 is set to zero and other's 1 */
-#define DBPC_MASK 0xFFFFFFFE
-
-/* For DBPC bit 1 is set to zero and other's 1 */
-#define DBCC_MASK 0xFFFFFFFD
-
-/* For DBPC/ABF/DBCC/ABCC bits are set to 1 all others 0 */
-#define DEMOSAIC_MASK 0xF
-
-/* For MCE enable bit 28 set to zero and other's 1 */
-#define MCE_EN_MASK 0xEFFFFFFF
-
-/* For MCE Q_K bit 28 to 32 set to zero and other's 1 */
-#define MCE_Q_K_MASK 0x0FFFFFFF
-
-#define BE_ENABLE_MASK    (0x00000001<<5)
-#define BG_ENABLE_MASK    (0x00000001<<6)
-#define BF_ENABLE_MASK    (0x00000001<<7)
-#define AWB_ENABLE_MASK   (0x00000001<<8)
-#define RS_ENABLE_MASK    (0x00000001<<9)
-#define CS_ENABLE_MASK    (0x00000001<<10)
-#define CLF_ENABLE_MASK   (0x00000001<<12)
-#define IHIST_ENABLE_MASK (0x00000001<<15)
-#define BHIST_ENABLE_MASK (0x00000001<<18)
-#define RS_CS_ENABLE_MASK (RS_ENABLE_MASK|CS_ENABLE_MASK)
-#define STATS_ENABLE_MASK 0x000487E0   /* bit 18,15,10,9,8,7,6,5*/
-
-#define STATS_BHIST_ENABLE_MASK (0x00000001<<1)
-
-#define VFE_DMI_CFG_DEFAULT              0x00000100
-
-#define HFR_MODE_OFF 1
-#define VFE_FRAME_SKIP_PERIOD_MASK 0x0000001F /*bits 0 -4*/
-
-enum VFE40_DMI_RAM_SEL {
-	NO_MEM_SELECTED          = 0,
-	BLACK_LUT_RAM_BANK0      = 0x1,
-	BLACK_LUT_RAM_BANK1      = 0x2,
-	ROLLOFF_RAM0_BANK0       = 0x3,
-	ROLLOFF_RAM0_BANK1       = 0x4,
-	DEMOSAIC_LUT_RAM_BANK0   = 0x5,
-	DEMOSAIC_LUT_RAM_BANK1   = 0x6,
-	STATS_BHIST_RAM0         = 0x7,
-	STATS_BHIST_RAM1         = 0x8,
-	RGBLUT_RAM_CH0_BANK0     = 0x9,
-	RGBLUT_RAM_CH0_BANK1     = 0xa,
-	RGBLUT_RAM_CH1_BANK0     = 0xb,
-	RGBLUT_RAM_CH1_BANK1     = 0xc,
-	RGBLUT_RAM_CH2_BANK0     = 0xd,
-	RGBLUT_RAM_CH2_BANK1     = 0xe,
-	RGBLUT_CHX_BANK0         = 0xf,
-	RGBLUT_CHX_BANK1         = 0x10,
-	STATS_IHIST_RAM          = 0x11,
-	LUMA_ADAPT_LUT_RAM_BANK0 = 0x12,
-	LUMA_ADAPT_LUT_RAM_BANK1 = 0x13,
-};
-
-enum vfe_output_state {
-	VFE_STATE_IDLE,
-	VFE_STATE_START_REQUESTED,
-	VFE_STATE_STARTED,
-	VFE_STATE_STOP_REQUESTED,
-	VFE_STATE_STOPPED,
-};
-
-#define V40_CAMIF_OFF             0x000002F8
-#define V40_CAMIF_LEN             36
-
-#define V40_DEMUX_OFF             0x00000424
-#define V40_DEMUX_LEN             28
-
-#define V40_DEMOSAICV3_0_OFF      0x00000440
-#define V40_DEMOSAICV3_0_LEN      4
-#define V40_DEMOSAICV3_1_OFF      0x00000518
-#define V40_DEMOSAICV3_1_LEN      88
-#define V40_DEMOSAICV3_2_OFF      0x00000568
-#define V40_DEMOSAICV3_UP_REG_CNT 5
-
-#define V40_OUT_CLAMP_OFF         0x00000874
-#define V40_OUT_CLAMP_LEN         16
-
-#define V40_OPERATION_CFG_LEN     32
-
-#define V40_AXI_BUS_CMD_OFF       0x0000004C
-#define V40_AXI_BUS_CFG_LEN       284
-#define V40_AXI_OUT_LEN           344
-#define V40_AXI_CFG_LEN           71
-
-#define V40_BUS_PM_CMD            0x00000270
-#define V40_FOV_ENC_OFF           0x00000854
-#define V40_FOV_ENC_LEN           16
-#define V40_FOV_VIEW_OFF          0x00000864
-#define V40_FOV_VIEW_LEN          16
-
-#define V40_SCALER_ENC_OFF 0x0000075C
-#define V40_SCALER_ENC_LEN 72
-
-#define V40_SCALER_VIEW_OFF 0x000007A4
-#define V40_SCALER_VIEW_LEN 72
-
-#define V40_COLORXFORM_ENC_CFG_OFF 0x0000071C
-#define V40_COLORXFORM_ENC_CFG_LEN 32
-
-#define V40_COLORXFORM_VIEW_CFG_OFF 0x0000073C
-#define V40_COLORXFORM_VIEW_CFG_LEN 32
-
-#define V40_CHROMA_EN_OFF 0x00000640
-#define V40_CHROMA_EN_LEN 36
-
-#define V40_SYNC_TIMER_OFF      0x00000324
-#define V40_SYNC_TIMER_POLARITY_OFF 0x0000034C
-#define V40_TIMER_SELECT_OFF        0x00000374
-#define V40_SYNC_TIMER_LEN 28
-
-#define V40_ASYNC_TIMER_OFF 0x00000350
-#define V40_ASYNC_TIMER_LEN 28
-
-/* use 10x13 mesh table in vfe40*/
-#define V40_MESH_ROLL_OFF_CFG_OFF             0x00000400
-#define V40_MESH_ROLL_OFF_CFG_LEN             36
-#define V40_MESH_ROLL_OFF_TABLE_SIZE          130
-
-#define V40_COLOR_COR_OFF 0x000005D0
-#define V40_COLOR_COR_LEN 52
-
-#define V40_WB_OFF 0x00000580
-#define V40_WB_LEN 4
-
-#define V40_RGB_G_OFF 0x00000638
-#define V40_RGB_G_LEN 4
-#define V40_GAMMA_LUT_BANK_SEL_MASK           0x00000007
-
-#define V40_LA_OFF 0x0000063C
-#define V40_LA_LEN 4
-
-#define V40_SCE_OFF 0x00000694
-#define V40_SCE_LEN 136
-
-#define V40_CHROMA_SUP_OFF 0x00000664
-#define V40_CHROMA_SUP_LEN 12
-
-#define V40_MCE_OFF 0x00000670
-#define V40_MCE_LEN 36
-
-#define V40_STATS_BE_OFF 0x0000088C
-#define V40_STATS_BE_LEN 12
-
-#define V40_STATS_BG_OFF 0x00000898
-#define V40_STATS_BG_LEN 12
-
-#define V40_STATS_BF_OFF 0x000008A4
-#define V40_STATS_BF_LEN 24
-
-#define V40_STATS_BHIST_OFF 0x000008BC
-#define V40_STATS_BHIST_LEN 8
-
-#define V40_STATS_AWB_OFF 0x000008C4
-#define V40_STATS_AWB_LEN 32
-
-#define V40_STATS_RS_OFF 0x000008E4
-#define V40_STATS_RS_LEN 8
-
-#define V40_STATS_CS_OFF 0x000008EC
-#define V40_STATS_CS_LEN 8
-
-#define V40_STATS_IHIST_OFF 0x000008F4
-#define V40_STATS_IHIST_LEN 8
-
-#define V40_STATS_SKIN_OFF 0x000008FC
-#define V40_STATS_SKIN_LEN 20
-
-#define V40_ASF_OFF 0x000007EC
-#define V40_ASF_LEN 48
-#define V40_ASF_UPDATE_LEN 36
-
-#define V40_CAPTURE_LEN 4
-
-#define V40_GET_HW_VERSION_OFF 0
-#define V40_GET_HW_VERSION_LEN 4
-
-#define V40_LINEARIZATION_OFF1 0x0000037C
-#define V40_LINEARIZATION_LEN1 68
-
-#define V40_DEMOSAICV3_DBPC_CFG_OFF  0x00000444
-#define V40_DEMOSAICV3_DBPC_LEN 4
-
-#define V40_DEMOSAICV3_DBPC_CFG_OFF0 0x00000448
-#define V40_DEMOSAICV3_DBPC_CFG_OFF1 0x0000044C
-#define V40_DEMOSAICV3_DBPC_CFG_OFF2 0x00000450
-
-#define V40_DEMOSAICV3_DBCC_OFF 0x00000454
-#define V40_DEMOSAICV3_DBCC_LEN 16
-
-#define V40_DEMOSAICV3_ABF_OFF 0x00000464
-#define V40_DEMOSAICV3_ABF_LEN 180
-
-#define V40_MODULE_CFG_OFF 0x00000018
-#define V40_MODULE_CFG_LEN 4
-
-#define V40_ASF_SPECIAL_EFX_CFG_OFF 0x0000081C
-#define V40_ASF_SPECIAL_EFX_CFG_LEN 4
-
-#define V40_CLF_CFG_OFF 0x00000588
-#define V40_CLF_CFG_LEN 72
-
-#define V40_CLF_LUMA_UPDATE_OFF 0x0000058C
-#define V40_CLF_LUMA_UPDATE_LEN 60
-
-#define V40_CLF_CHROMA_UPDATE_OFF 0x000005C8
-#define V40_CLF_CHROMA_UPDATE_LEN 8
-
-#define VFE40_GAMMA_NUM_ENTRIES  64
-
-#define VFE40_LA_TABLE_LENGTH    64
-
-#define VFE40_LINEARIZATON_TABLE_LENGTH    36
-
-struct vfe_cmd_hw_version {
-	uint32_t minorVersion;
-	uint32_t majorVersion;
-	uint32_t coreVersion;
-};
-
-enum VFE_AXI_OUTPUT_MODE {
-	VFE_AXI_OUTPUT_MODE_Output1,
-	VFE_AXI_OUTPUT_MODE_Output2,
-	VFE_AXI_OUTPUT_MODE_Output1AndOutput2,
-	VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2,
-	VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1,
-	VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2,
-	VFE_AXI_LAST_OUTPUT_MODE_ENUM
-};
-
-enum VFE_RAW_WR_PATH_SEL {
-	VFE_RAW_OUTPUT_DISABLED,
-	VFE_RAW_OUTPUT_ENC_CBCR_PATH,
-	VFE_RAW_OUTPUT_VIEW_CBCR_PATH,
-	VFE_RAW_OUTPUT_PATH_INVALID
-};
-
-
-#define VFE_AXI_OUTPUT_BURST_LENGTH     4
-#define VFE_MAX_NUM_FRAGMENTS_PER_FRAME 4
-#define VFE_AXI_OUTPUT_CFG_FRAME_COUNT  3
-
-struct vfe_cmds_per_write_master {
-	uint16_t imageWidth;
-	uint16_t imageHeight;
-	uint16_t outRowCount;
-	uint16_t outRowIncrement;
-	uint32_t outFragments[VFE_AXI_OUTPUT_CFG_FRAME_COUNT]
-		[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
-};
-
-struct vfe_cmds_axi_per_output_path {
-	uint8_t fragmentCount;
-	struct vfe_cmds_per_write_master firstWM;
-	struct vfe_cmds_per_write_master secondWM;
-};
-
-enum VFE_AXI_BURST_LENGTH {
-	VFE_AXI_BURST_LENGTH_IS_2  = 2,
-	VFE_AXI_BURST_LENGTH_IS_4  = 4,
-	VFE_AXI_BURST_LENGTH_IS_8  = 8,
-	VFE_AXI_BURST_LENGTH_IS_16 = 16
-};
-
-
-struct vfe_cmd_fov_crop_config {
-	uint8_t enable;
-	uint16_t firstPixel;
-	uint16_t lastPixel;
-	uint16_t firstLine;
-	uint16_t lastLine;
-};
-
-struct vfe_cmds_main_scaler_stripe_init {
-	uint16_t MNCounterInit;
-	uint16_t phaseInit;
-};
-
-struct vfe_cmds_scaler_one_dimension {
-	uint8_t  enable;
-	uint16_t inputSize;
-	uint16_t outputSize;
-	uint32_t phaseMultiplicationFactor;
-	uint8_t  interpolationResolution;
-};
-
-struct vfe_cmd_main_scaler_config {
-	uint8_t enable;
-	struct vfe_cmds_scaler_one_dimension    hconfig;
-	struct vfe_cmds_scaler_one_dimension    vconfig;
-	struct vfe_cmds_main_scaler_stripe_init MNInitH;
-	struct vfe_cmds_main_scaler_stripe_init MNInitV;
-};
-
-struct vfe_cmd_scaler2_config {
-	uint8_t enable;
-	struct vfe_cmds_scaler_one_dimension hconfig;
-	struct vfe_cmds_scaler_one_dimension vconfig;
-};
-
-
-struct vfe_cmd_frame_skip_update {
-	uint32_t output1Pattern;
-	uint32_t output2Pattern;
-};
-
-struct vfe_cmd_output_clamp_config {
-	uint8_t minCh0;
-	uint8_t minCh1;
-	uint8_t minCh2;
-	uint8_t maxCh0;
-	uint8_t maxCh1;
-	uint8_t maxCh2;
-};
-
-struct vfe_cmd_chroma_subsample_config {
-	uint8_t enable;
-	uint8_t cropEnable;
-	uint8_t vsubSampleEnable;
-	uint8_t hsubSampleEnable;
-	uint8_t vCosited;
-	uint8_t hCosited;
-	uint8_t vCositedPhase;
-	uint8_t hCositedPhase;
-	uint16_t cropWidthFirstPixel;
-	uint16_t cropWidthLastPixel;
-	uint16_t cropHeightFirstLine;
-	uint16_t cropHeightLastLine;
-};
-
-enum VFE_START_PIXEL_PATTERN {
-	VFE_BAYER_RGRGRG,
-	VFE_BAYER_GRGRGR,
-	VFE_BAYER_BGBGBG,
-	VFE_BAYER_GBGBGB,
-	VFE_YUV_YCbYCr,
-	VFE_YUV_YCrYCb,
-	VFE_YUV_CbYCrY,
-	VFE_YUV_CrYCbY
-};
-
-enum VFE_BUS_RD_INPUT_PIXEL_PATTERN {
-	VFE_BAYER_RAW,
-	VFE_YUV_INTERLEAVED,
-	VFE_YUV_PSEUDO_PLANAR_Y,
-	VFE_YUV_PSEUDO_PLANAR_CBCR
-};
-
-enum VFE_YUV_INPUT_COSITING_MODE {
-	VFE_YUV_COSITED,
-	VFE_YUV_INTERPOLATED
-};
-
-struct vfe_cmds_demosaic_abf {
-	uint8_t   enable;
-	uint8_t   forceOn;
-	uint8_t   shift;
-	uint16_t  lpThreshold;
-	uint16_t  max;
-	uint16_t  min;
-	uint8_t   ratio;
-};
-
-struct vfe_cmds_demosaic_bpc {
-	uint8_t   enable;
-	uint16_t  fmaxThreshold;
-	uint16_t  fminThreshold;
-	uint16_t  redDiffThreshold;
-	uint16_t  blueDiffThreshold;
-	uint16_t  greenDiffThreshold;
-};
-
-struct vfe_cmd_demosaic_config {
-	uint8_t   enable;
-	uint8_t   slopeShift;
-	struct vfe_cmds_demosaic_abf abfConfig;
-	struct vfe_cmds_demosaic_bpc bpcConfig;
-};
-
-struct vfe_cmd_demosaic_bpc_update {
-	struct vfe_cmds_demosaic_bpc bpcUpdate;
-};
-
-struct vfe_cmd_demosaic_abf_update {
-	struct vfe_cmds_demosaic_abf abfUpdate;
-};
-
-struct vfe_cmd_white_balance_config {
-	uint8_t  enable;
-	uint16_t ch2Gain;
-	uint16_t ch1Gain;
-	uint16_t ch0Gain;
-};
-
-enum VFE_COLOR_CORRECTION_COEF_QFACTOR {
-	COEF_IS_Q7_SIGNED,
-	COEF_IS_Q8_SIGNED,
-	COEF_IS_Q9_SIGNED,
-	COEF_IS_Q10_SIGNED
-};
-
-struct vfe_cmd_color_correction_config {
-	uint8_t     enable;
-	enum VFE_COLOR_CORRECTION_COEF_QFACTOR coefQFactor;
-	int16_t  C0;
-	int16_t  C1;
-	int16_t  C2;
-	int16_t  C3;
-	int16_t  C4;
-	int16_t  C5;
-	int16_t  C6;
-	int16_t  C7;
-	int16_t  C8;
-	int16_t  K0;
-	int16_t  K1;
-	int16_t  K2;
-};
-
-#define VFE_LA_TABLE_LENGTH 64
-
-struct vfe_cmd_la_config {
-	uint8_t enable;
-	int16_t table[VFE_LA_TABLE_LENGTH];
-};
-
-#define VFE_GAMMA_TABLE_LENGTH 256
-enum VFE_RGB_GAMMA_TABLE_SELECT {
-	RGB_GAMMA_CH0_SELECTED,
-	RGB_GAMMA_CH1_SELECTED,
-	RGB_GAMMA_CH2_SELECTED,
-	RGB_GAMMA_CH0_CH1_SELECTED,
-	RGB_GAMMA_CH0_CH2_SELECTED,
-	RGB_GAMMA_CH1_CH2_SELECTED,
-	RGB_GAMMA_CH0_CH1_CH2_SELECTED
-};
-
-struct vfe_cmd_rgb_gamma_config {
-	uint8_t enable;
-	enum VFE_RGB_GAMMA_TABLE_SELECT channelSelect;
-	int16_t table[VFE_GAMMA_TABLE_LENGTH];
-};
-
-struct vfe_cmd_chroma_enhan_config {
-	uint8_t  enable;
-	int16_t am;
-	int16_t ap;
-	int16_t bm;
-	int16_t bp;
-	int16_t cm;
-	int16_t cp;
-	int16_t dm;
-	int16_t dp;
-	int16_t kcr;
-	int16_t kcb;
-	int16_t RGBtoYConversionV0;
-	int16_t RGBtoYConversionV1;
-	int16_t RGBtoYConversionV2;
-	uint8_t RGBtoYConversionOffset;
-};
-
-struct vfe_cmd_chroma_suppression_config {
-	uint8_t enable;
-	uint8_t m1;
-	uint8_t m3;
-	uint8_t n1;
-	uint8_t n3;
-	uint8_t nn1;
-	uint8_t mm1;
-};
-
-struct vfe_cmd_asf_config {
-	uint8_t enable;
-	uint8_t smoothFilterEnabled;
-	uint8_t sharpMode;
-	uint8_t smoothCoefCenter;
-	uint8_t smoothCoefSurr;
-	uint8_t normalizeFactor;
-	uint8_t sharpK1;
-	uint8_t sharpK2;
-	uint8_t sharpThreshE1;
-	int8_t sharpThreshE2;
-	int8_t sharpThreshE3;
-	int8_t sharpThreshE4;
-	int8_t sharpThreshE5;
-	int8_t filter1Coefficients[9];
-	int8_t filter2Coefficients[9];
-	uint8_t  cropEnable;
-	uint16_t cropFirstPixel;
-	uint16_t cropLastPixel;
-	uint16_t cropFirstLine;
-	uint16_t cropLastLine;
-};
-
-struct vfe_cmd_asf_update {
-	uint8_t enable;
-	uint8_t smoothFilterEnabled;
-	uint8_t sharpMode;
-	uint8_t smoothCoefCenter;
-	uint8_t smoothCoefSurr;
-	uint8_t normalizeFactor;
-	uint8_t sharpK1;
-	uint8_t sharpK2;
-	uint8_t sharpThreshE1;
-	int8_t  sharpThreshE2;
-	int8_t  sharpThreshE3;
-	int8_t  sharpThreshE4;
-	int8_t  sharpThreshE5;
-	int8_t  filter1Coefficients[9];
-	int8_t  filter2Coefficients[9];
-	uint8_t cropEnable;
-};
-
-enum VFE_TEST_GEN_SYNC_EDGE {
-	VFE_TEST_GEN_SYNC_EDGE_ActiveHigh,
-	VFE_TEST_GEN_SYNC_EDGE_ActiveLow
-};
-
-
-struct vfe_cmd_bus_pm_start {
-	uint8_t output2YWrPmEnable;
-	uint8_t output2CbcrWrPmEnable;
-	uint8_t output1YWrPmEnable;
-	uint8_t output1CbcrWrPmEnable;
-};
-
-struct  vfe_frame_skip_counts {
-	uint32_t  totalFrameCount;
-	uint32_t  output1Count;
-	uint32_t  output2Count;
-};
-
-enum VFE_AXI_RD_UNPACK_HBI_SEL {
-	VFE_AXI_RD_HBI_32_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_64_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_128_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_256_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_512_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_1024_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_2048_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_4096_CLOCK_CYCLES
-};
-
-struct vfe_frame_bpc_info {
-	uint32_t greenDefectPixelCount;
-	uint32_t redBlueDefectPixelCount;
-};
-
-struct vfe_frame_asf_info {
-	uint32_t  asfMaxEdge;
-	uint32_t  asfHbiCount;
-};
-
-struct vfe_msg_camif_status {
-	uint8_t  camifState;
-	uint32_t pixelCount;
-	uint32_t lineCount;
-};
-
-struct vfe40_irq_status {
-	uint32_t vfeIrqStatus0;
-	uint32_t vfeIrqStatus1;
-	uint32_t camifStatus;
-	uint32_t demosaicStatus;
-	uint32_t asfMaxEdge;
-};
-
-#define V40_PREVIEW_AXI_FLAG  0x00000001
-#define V40_SNAPSHOT_AXI_FLAG (0x00000001<<1)
-
-struct vfe40_cmd_type {
-	uint16_t id;
-	uint32_t length;
-	uint32_t offset;
-	uint32_t flag;
-};
-
-struct vfe40_free_buf {
-	struct list_head node;
-	uint32_t paddr;
-	uint32_t y_off;
-	uint32_t cbcr_off;
-};
-
-struct vfe40_output_ch {
-	struct list_head free_buf_queue;
-	spinlock_t free_buf_lock;
-	uint32_t inst_handle;
-	int8_t ch0;
-	int8_t ch1;
-	int8_t ch2;
-	uint32_t  capture_cnt;
-	uint32_t  frame_drop_cnt;
-	struct msm_free_buf ping;
-	struct msm_free_buf pong;
-	struct msm_free_buf free_buf;
-};
-
-/* no error irq in mask 0 */
-#define VFE40_IMASK_ERROR_ONLY_0  0x0
-/* when normal case, don't want to block error status. */
-/* bit 0-21 are error irq bits */
-#define VFE40_IMASK_COMMON_ERROR_ONLY_1       0x0000FF00
-#define VFE40_IMASK_VFE_ERROR_ONLY_1          0x00FF01FF
-#define VFE40_IMASK_CAMIF_ERROR               (0x00000001<<0)
-#define VFE40_IMASK_BHIST_OVWR                (0x00000001<<1)
-#define VFE40_IMASK_STATS_CS_OVWR             (0x00000001<<2)
-#define VFE40_IMASK_STATS_IHIST_OVWR          (0x00000001<<3)
-#define VFE40_IMASK_REALIGN_BUF_Y_OVFL        (0x00000001<<4)
-#define VFE40_IMASK_REALIGN_BUF_CB_OVFL       (0x00000001<<5)
-#define VFE40_IMASK_REALIGN_BUF_CR_OVFL       (0x00000001<<6)
-#define VFE40_IMASK_VIOLATION                 (0x00000001<<7)
-#define VFE40_IMASK_BUS_BDG_HALT_ACK          (0x00000001<<8)
-#define VFE40_IMASK_IMG_MAST_0_BUS_OVFL       (0x00000001<<9)
-#define VFE40_IMASK_IMG_MAST_1_BUS_OVFL       (0x00000001<<10)
-#define VFE40_IMASK_IMG_MAST_2_BUS_OVFL       (0x00000001<<11)
-#define VFE40_IMASK_IMG_MAST_3_BUS_OVFL       (0x00000001<<12)
-#define VFE40_IMASK_IMG_MAST_4_BUS_OVFL       (0x00000001<<13)
-#define VFE40_IMASK_IMG_MAST_5_BUS_OVFL       (0x00000001<<14)
-#define VFE40_IMASK_IMG_MAST_6_BUS_OVFL       (0x00000001<<15)
-#define VFE40_IMASK_STATS_BE_BUS_OVFL         (0x00000001<<16)
-#define VFE40_IMASK_STATS_BG_BUS_OVFL         (0x00000001<<17)
-#define VFE40_IMASK_STATS_BF_BUS_OVFL         (0x00000001<<18)
-#define VFE40_IMASK_STATS_AWB_BUS_OVFL        (0x00000001<<19)
-#define VFE40_IMASK_STATS_RS_BUS_OVFL         (0x00000001<<10)
-#define VFE40_IMASK_STATS_CS_BUS_OVFL         (0x00000001<<21)
-#define VFE40_IMASK_STATS_IHIST_BUS_OVFL      (0x00000001<<22)
-#define VFE40_IMASK_STATS_SKIN_BHIST_BUS_OVFL (0x00000001<<23)
-
-#define VFE_COM_STATUS 0x000FE000
-
-struct vfe40_output_path {
-	uint16_t output_mode;     /* bitmask  */
-
-	struct vfe40_output_ch out0; /* preview and thumbnail */
-	struct vfe40_output_ch out1; /* snapshot */
-	struct vfe40_output_ch out2; /* rdi0    */
-	struct vfe40_output_ch out3; /* rdi01   */
-};
-
-struct vfe40_frame_extra {
-	uint32_t greenDefectPixelCount;
-	uint32_t redBlueDefectPixelCount;
-
-	uint32_t  asfMaxEdge;
-	uint32_t  asfHbiCount;
-
-	uint32_t yWrPmStats0;
-	uint32_t yWrPmStats1;
-	uint32_t cbcrWrPmStats0;
-	uint32_t cbcrWrPmStats1;
-
-	uint32_t  frameCounter;
-};
-
-#define VFE_HW_VERSION			0x00000000
-#define VFE_GLOBAL_RESET                0x0000000C
-#define VFE_MODULE_RESET                0x00000010
-#define VFE_CGC_OVERRIDE                0x00000014
-#define VFE_MODULE_CFG                  0x00000018
-#define VFE_CFG				            0x0000001C
-#define VFE_IRQ_CMD                     0x00000024
-#define VFE_IRQ_MASK_0                  0x00000028
-#define VFE_IRQ_MASK_1                  0x0000002C
-#define VFE_IRQ_CLEAR_0                 0x00000030
-#define VFE_IRQ_CLEAR_1                 0x00000034
-#define VFE_IRQ_STATUS_0                0x00000038
-#define VFE_IRQ_STATUS_1                0x0000003C
-#define VFE_IRQ_COMP_MASK               0x00000040
-#define VFE_BUS_CMD                     0x0000004C
-#define VFE_BUS_PING_PONG_STATUS        0x00000268
-#define VFE_AXI_CMD                     0x000002C0
-#define VFE_AXI_STATUS                  0x000002E4
-#define VFE_BUS_STATS_PING_PONG_BASE    0x00000168
-
-#define VFE_BUS_STATS_BE_WR_PING_ADDR    0x00000168
-#define VFE_BUS_STATS_BE_WR_PONG_ADDR    0x0000016C
-#define VFE_BUS_STATS_BE_WR_ADDR_CFG    0x00000170
-#define VFE_BUS_STATS_BE_WR_UB_CFG          0x00000174
-#define VFE_BUS_STATS_BE_WR_FRAMEDROP_PATTERN  0x00000178
-#define VFE_BUS_STATS_BE_WR_IRQ_SUBSAMPLE_PATTERN 0x0000017C
-
-#define VFE_BUS_STATS_BG_WR_PING_ADDR     0x00000180
-#define VFE_BUS_STATS_BG_WR_PONG_ADDR     0x00000184
-#define VFE_BUS_STATS_BG_WR_ADDR_CFG      0x00000188
-#define VFE_BUS_STATS_BG_WR_UB_CFG        0x0000018C
-#define VFE_BUS_STATS_BG_WR_FRAMEDROP_PATTERN 0x00000190
-#define VFE_BUS_STATS_BG_WR_IRQ_SUBSAMPLE_PATTERN 0x00000194
-
-#define VFE_BUS_STATS_BF_WR_PING_ADDR     0x00000198
-#define VFE_BUS_STATS_BF_WR_PONG_ADDR     0x0000019C
-#define VFE_BUS_STATS_BF_WR_ADDR_CFG      0x000001A0
-#define VFE_BUS_STATS_BF_WR_UB_CFG        0x000001A4
-#define VFE_BUS_STATS_BF_WR_FRAMEDROP_PATTERN  0x000001A8
-#define VFE_BUS_STATS_BF_WR_IRQ_SUBSAMPLE_PATTERN  0x000001AC
-
-#define VFE_BUS_STATS_AWB_WR_PING_ADDR    0x000001B0
-#define VFE_BUS_STATS_AWB_WR_PONG_ADDR    0x000001B4
-#define VFE_BUS_STATS_AWB_WR_ADDR_CFG     0x000001B8
-#define VFE_BUS_STATS_AWB_WR_UB_CFG       0x000001BC
-#define VFE_BUS_STATS_AWB_WR_FRAMEDROP_PATTERN  0x000001C0
-#define VFE_BUS_STATS_AWB_WR_IRQ_SUBSAMPLE_PATTERN  0x000001C4
-
-#define VFE_BUS_STATS_RS_WR_PING_ADDR     0x000001C8
-#define VFE_BUS_STATS_RS_WR_PONG_ADDR     0x000001CC
-#define VFE_BUS_STATS_RS_WR_ADDR_CFG      0x000001D0
-#define VFE_BUS_STATS_RS_WR_UB_CFG    0x000001D4
-#define VFE_BUS_STATS_RS_WR_FRAMEDROP_PATTERN      0x000001D8
-#define VFE_BUS_STATS_RS_WR_IRQ_SUBSAMPLE_PATTERN  0x000001DC
-
-#define VFE_BUS_STATS_CS_WR_PING_ADDR     0x000001E0
-#define VFE_BUS_STATS_CS_WR_PONG_ADDR     0x000001E4
-#define VFE_BUS_STATS_CS_WR_ADDR_CFG      0x000001E8
-#define VFE_BUS_STATS_CS_WR_UB_CFG        0x000001EC
-#define VFE_BUS_STATS_CS_WR_FRAMEDROP_PATTERN     0x000001F0
-#define VFE_BUS_STATS_CS_WR_IRQ_SUBSAMPLE_PATTERN 0x000001F4
-
-#define VFE_BUS_STATS_HIST_WR_PING_ADDR   0x000001F8
-#define VFE_BUS_STATS_HIST_WR_PONG_ADDR   0x000001FC
-#define VFE_BUS_STATS_HIST_WR_ADDR_CFG    0x00000200
-#define VFE_BUS_STATS_HIST_WR_UB_CFG      0x00000204
-#define VFE_BUS_STATS_HIST_WR_FRAMEDROP_PATTERN      0x00000208
-#define VFE_BUS_STATS_HIST_WR_IRQ_SUBSAMPLE_PATTERN  0x0000020C
-
-
-#define VFE_BUS_STATS_SKIN_WR_PING_ADDR   0x00000210
-#define VFE_BUS_STATS_SKIN_WR_PONG_ADDR   0x00000214
-#define VFE_BUS_STATS_SKIN_WR_ADDR_CFG    0x00000218
-#define VFE_BUS_STATS_SKIN_WR_UB_CFG      0x0000021C
-#define VFE_BUS_STATS_SKIN_WR_FRAMEDROP_PATTERN       0x00000220
-#define VFE_BUS_STATS_SKIN_WR_IRQ_SUBSAMPLE_PATTERN   0x00000224
-
-#define VFE_0_BUS_BDG_QOS_CFG_0     0x000002C4
-#define VFE_0_BUS_BDG_QOS_CFG_1     0x000002C8
-#define VFE_0_BUS_BDG_QOS_CFG_2     0x000002CC
-#define VFE_0_BUS_BDG_QOS_CFG_3     0x000002D0
-#define VFE_0_BUS_BDG_QOS_CFG_4     0x000002D4
-#define VFE_0_BUS_BDG_QOS_CFG_5     0x000002D8
-#define VFE_0_BUS_BDG_QOS_CFG_6     0x000002DC
-#define VFE_0_BUS_BDG_QOS_CFG_7     0x000002E0
-
-#define VFE_CAMIF_COMMAND               0x000002F4
-#define VFE_CAMIF_STATUS                0x0000031C
-#define VFE_REG_UPDATE_CMD              0x00000378
-#define VFE_DEMUX_GAIN_0                0x00000428
-#define VFE_DEMUX_GAIN_1                0x0000042C
-#define VFE_CHROMA_UP                   0x0000057C
-
-#define VFE_CLAMP_ENC_MAX               0x00000874
-#define VFE_CLAMP_ENC_MIN               0x00000878
-#define VFE_CLAMP_VIEW_MAX              0x0000087C
-#define VFE_CLAMP_VIEW_MIN              0x00000880
-
-#define VFE_REALIGN_BUF                 0x00000884
-#define VFE_STATS_CFG                   0x00000888
-#define VFE_STATS_AWB_SGW_CFG           0x000008CC
-#define VFE_DMI_CFG                     0x00000910
-#define VFE_DMI_ADDR                    0x00000914
-#define VFE_DMI_DATA_HI                 0x00000918
-#define VFE_DMI_DATA_LO                 0x0000091C
-#define VFE_BUS_IO_FORMAT_CFG           0x00000054
-#define VFE_RDI0_CFG                    0x000002E8
-#define VFE_RDI1_CFG                    0x000002EC
-#define VFE_RDI2_CFG                    0x000002F0
-
-#define VFE_VIOLATION_STATUS            0x00000048
-
-#define VFE40_DMI_DATA_HI               0x00000918
-#define VFE40_DMI_DATA_LO               0x0000091C
-
-#define VFE40_OUTPUT_MODE_PT			BIT(0)
-#define VFE40_OUTPUT_MODE_S			BIT(1)
-#define VFE40_OUTPUT_MODE_V			BIT(2)
-#define VFE40_OUTPUT_MODE_P			BIT(3)
-#define VFE40_OUTPUT_MODE_T			BIT(4)
-#define VFE40_OUTPUT_MODE_P_ALL_CHNLS		BIT(5)
-#define VFE40_OUTPUT_MODE_PRIMARY		BIT(6)
-#define VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS	BIT(7)
-#define VFE40_OUTPUT_MODE_SECONDARY		BIT(8)
-#define VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS	BIT(9)
-#define VFE40_OUTPUT_MODE_TERTIARY1		BIT(10)
-#define VFE40_OUTPUT_MODE_TERTIARY2		BIT(11)
-
-#define VFE40_VBIF_CLKON					0x4
-#define VFE40_VBIF_IN_RD_LIM_CONF0			0xB0
-#define VFE40_VBIF_IN_RD_LIM_CONF1			0xB4
-#define VFE40_VBIF_IN_RD_LIM_CONF2			0xB8
-#define VFE40_VBIF_IN_WR_LIM_CONF0			0xC0
-#define VFE40_VBIF_IN_WR_LIM_CONF1			0xC4
-#define VFE40_VBIF_IN_WR_LIM_CONF2			0xC8
-#define VFE40_VBIF_OUT_RD_LIM_CONF0			0xD0
-#define VFE40_VBIF_OUT_WR_LIM_CONF0			0xD4
-#define VFE40_VBIF_DDR_OUT_MAX_BURST		0xD8
-#define VFE40_VBIF_OCMEM_OUT_MAX_BURST		0xDC
-#define VFE40_VBIF_ARB_CTL					0xF0
-#define VFE40_VBIF_DDR_ARB_CONF0			0xF4
-#define VFE40_VBIF_DDR_ARB_CONF1			0xF8
-#define VFE40_VBIF_ROUND_ROBIN_QOS_ARB		0x124
-#define VFE40_VBIF_OUT_AXI_AMEMTYPE_CONF0	0x160
-#define VFE40_VBIF_OUT_AXI_AMEMTYPE_CONF1	0x164
-#define VFE40_VBIF_OUT_AXI_AOOO_EN			0x178
-#define VFE40_VBIF_OUT_AXI_AOOO				0x17C
-
-struct vfe_stats_control {
-	uint32_t droppedStatsFrameCount;
-	uint32_t bufToRender;
-};
-struct axi_ctrl_t;
-struct vfe40_ctrl_type;
-
-struct vfe_share_ctrl_t {
-	void __iomem *vfebase;
-	void __iomem *vfe_vbif_base;
-	uint32_t register_total;
-
-	atomic_t vstate;
-	atomic_t handle_common_irq;
-	uint32_t vfeFrameId;
-	uint32_t rdi0FrameId;
-	uint32_t rdi1FrameId;
-	uint32_t rdi2FrameId;
-	uint32_t stats_comp;
-	spinlock_t  sd_notify_lock;
-	spinlock_t  stop_flag_lock;
-	int8_t stop_ack_pending;
-	enum vfe_output_state liveshot_state;
-	uint32_t vfe_capture_count;
-
-	uint32_t operation_mode;     /* streaming or snapshot */
-	uint32_t current_mode;
-	struct vfe40_output_path outpath;
-
-	uint16_t port_info;
-	uint8_t stop_immediately;
-	uint8_t sync_abort;
-	uint16_t cmd_type;
-	uint8_t vfe_reset_flag;
-
-	uint8_t axi_ref_cnt;
-	uint16_t comp_output_mode;
-
-	struct completion reset_complete;
-
-	spinlock_t  update_ack_lock;
-	spinlock_t  start_ack_lock;
-
-	struct axi_ctrl_t *axi_ctrl;
-	struct vfe40_ctrl_type *vfe40_ctrl;
-	int8_t start_ack_pending;
-	int8_t update_ack_pending;
-	enum vfe_output_state recording_state;
-
-	atomic_t pix0_update_ack_pending;
-	atomic_t rdi0_update_ack_pending;
-	atomic_t rdi1_update_ack_pending;
-	atomic_t rdi2_update_ack_pending;
-};
-
-struct axi_ctrl_t {
-	struct v4l2_subdev subdev;
-	struct platform_device *pdev;
-	struct resource *vfeirq;
-	spinlock_t  tasklet_lock;
-	struct list_head tasklet_q;
-
-	void *syncdata;
-
-	struct resource	*vfemem;
-	struct resource	*vfe_vbif_mem;
-	struct resource *vfeio;
-	struct resource *vfe_vbif_io;
-	struct regulator *fs_vfe;
-	struct clk *vfe_clk[7];
-	struct tasklet_struct vfe40_tasklet;
-	struct vfe_share_ctrl_t *share_ctrl;
-	struct device *iommu_ctx;
-	uint32_t bus_perf_client;
-	uint32_t use_irq_router;
-};
-
-struct vfe40_ctrl_type {
-	spinlock_t  state_lock;
-	spinlock_t  stats_bufq_lock;
-	uint32_t extlen;
-	void *extdata;
-
-	int8_t vfe_sof_count_enable;
-	int8_t update_linear;
-	int8_t update_rolloff;
-	int8_t update_la;
-	int8_t update_gamma;
-
-	struct vfe_share_ctrl_t *share_ctrl;
-
-	uint32_t sync_timer_repeat_count;
-	uint32_t sync_timer_state;
-	uint32_t sync_timer_number;
-
-	struct msm_ver_num_info ver_num;
-	struct vfe_stats_control beStatsControl;
-	struct vfe_stats_control bfStatsControl;
-	struct vfe_stats_control awbStatsControl;
-	struct vfe_stats_control bgStatsControl;
-	struct vfe_stats_control ihistStatsControl;
-	struct vfe_stats_control rsStatsControl;
-	struct vfe_stats_control csStatsControl;
-	struct vfe_stats_control bhistStatsControl;
-
-	/* v4l2 subdev */
-	struct v4l2_subdev subdev;
-	struct platform_device *pdev;
-	uint32_t hfr_mode;
-	uint32_t frame_skip_cnt;
-	uint32_t frame_skip_pattern;
-	uint32_t snapshot_frame_cnt;
-	struct msm_stats_bufq_ctrl stats_ctrl;
-	struct msm_stats_ops stats_ops;
-
-	uint32_t simultaneous_sof_stat;
-};
-
-#define statsBeNum      0
-#define statsBgNum      1
-#define statsBfNum      2
-#define statsAwbNum     3
-#define statsRsNum      4
-#define statsCsNum      5
-#define statsIhistNum   6
-#define statsSkinNum    7
-
-#define VFE_STATS_BUS_REG_NUM  6
-
-struct vfe_cmd_stats_ack {
-	uint32_t  nextStatsBuf;
-};
-
-#define VFE_STATS_BUFFER_COUNT            3
-
-struct vfe_cmd_stats_buf {
-	uint32_t statsBuf[VFE_STATS_BUFFER_COUNT];
-};
-
-#endif /* __MSM_VFE40_H__ */
diff --git a/drivers/media/video/msm/vfe/msm_vfe40_axi.c b/drivers/media/video/msm/vfe/msm_vfe40_axi.c
deleted file mode 100644
index 41d1cdd..0000000
--- a/drivers/media/video/msm/vfe/msm_vfe40_axi.c
+++ /dev/null
@@ -1,824 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/uaccess.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/atomic.h>
-#include <linux/regulator/consumer.h>
-#include <linux/clk.h>
-#include <mach/irqs.h>
-#include <mach/camera.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-#include <media/msm_isp.h>
-
-#include "msm.h"
-#include "msm_vfe40.h"
-
-static int msm_axi_subdev_s_crystal_freq(struct v4l2_subdev *sd,
-						u32 freq, u32 flags)
-{
-	int rc = 0;
-	int round_rate;
-	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
-
-	round_rate = clk_round_rate(axi_ctrl->vfe_clk[0], freq);
-	if (rc < 0) {
-		pr_err("%s: clk_round_rate failed %d\n",
-					__func__, rc);
-		return rc;
-	}
-
-	axi_ctrl->share_ctrl->vfe_clk_rate = round_rate;
-	rc = clk_set_rate(axi_ctrl->vfe_clk[0], round_rate);
-	if (rc < 0)
-		pr_err("%s: clk_set_rate failed %d\n",
-					__func__, rc);
-
-	return rc;
-}
-
-void axi_start(struct axi_ctrl_t *axi_ctrl)
-{
-	switch (axi_ctrl->share_ctrl->operation_mode) {
-	case VFE_OUTPUTS_PREVIEW:
-	case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
-		if (axi_ctrl->share_ctrl->outpath.output_mode &
-			VFE40_OUTPUT_MODE_PRIMARY) {
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out0.ch1]);
-		} else if (axi_ctrl->share_ctrl->outpath.output_mode &
-				VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out0.ch1]);
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out0.ch2]);
-		}
-		break;
-	default:
-		if (axi_ctrl->share_ctrl->outpath.output_mode &
-			VFE40_OUTPUT_MODE_SECONDARY) {
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out1.ch0]);
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out1.ch1]);
-		} else if (axi_ctrl->share_ctrl->outpath.output_mode &
-			VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out1.ch0]);
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out1.ch1]);
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out1.ch2]);
-		}
-		break;
-	}
-}
-
-void axi_stop(struct axi_ctrl_t *axi_ctrl)
-{
-	uint8_t  axiBusyFlag = true;
-	/* axi halt command. */
-	msm_camera_io_w(AXI_HALT,
-		axi_ctrl->share_ctrl->vfebase + VFE_AXI_CMD);
-	wmb();
-	while (axiBusyFlag) {
-		if (msm_camera_io_r(
-			axi_ctrl->share_ctrl->vfebase + VFE_AXI_STATUS) & 0x1)
-			axiBusyFlag = false;
-	}
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	msm_camera_io_w_mb(AXI_HALT_CLEAR,
-		axi_ctrl->share_ctrl->vfebase + VFE_AXI_CMD);
-
-	/* after axi halt, then ok to apply global reset. */
-	/* enable reset_ack and async timer interrupt only while
-	stopping the pipeline.*/
-	msm_camera_io_w(0xf0000000,
-		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_0);
-	msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_1,
-		axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
-
-	/* Ensure the write order while writing
-	to the command register using the barrier */
-	msm_camera_io_w_mb(VFE_RESET_UPON_STOP_CMD,
-		axi_ctrl->share_ctrl->vfebase + VFE_GLOBAL_RESET);
-}
-
-static int vfe40_config_axi(
-	struct axi_ctrl_t *axi_ctrl, int mode, uint32_t *ao)
-{
-	uint32_t *ch_info;
-	uint32_t *axi_cfg = ao;
-
-	/* Update the corresponding write masters for each output*/
-	ch_info = axi_cfg + V40_AXI_CFG_LEN;
-	axi_ctrl->share_ctrl->outpath.out0.ch0 = 0x0000FFFF & *ch_info;
-	axi_ctrl->share_ctrl->outpath.out0.ch1 =
-		0x0000FFFF & (*ch_info++ >> 16);
-	axi_ctrl->share_ctrl->outpath.out0.ch2 = 0x0000FFFF & *ch_info;
-	axi_ctrl->share_ctrl->outpath.out0.image_mode =
-		0x0000FFFF & (*ch_info++ >> 16);
-	axi_ctrl->share_ctrl->outpath.out1.ch0 = 0x0000FFFF & *ch_info;
-	axi_ctrl->share_ctrl->outpath.out1.ch1 =
-		0x0000FFFF & (*ch_info++ >> 16);
-	axi_ctrl->share_ctrl->outpath.out1.ch2 = 0x0000FFFF & *ch_info;
-	axi_ctrl->share_ctrl->outpath.out1.image_mode =
-		0x0000FFFF & (*ch_info++ >> 16);
-	axi_ctrl->share_ctrl->outpath.out2.ch0 = 0x0000FFFF & *ch_info;
-	axi_ctrl->share_ctrl->outpath.out2.ch1 =
-		0x0000FFFF & (*ch_info++ >> 16);
-	axi_ctrl->share_ctrl->outpath.out2.ch2 = 0x0000FFFF & *ch_info++;
-
-	switch (mode) {
-	case OUTPUT_PRIM:
-		axi_ctrl->share_ctrl->outpath.output_mode =
-			VFE40_OUTPUT_MODE_PRIMARY;
-		break;
-	case OUTPUT_PRIM_ALL_CHNLS:
-		axi_ctrl->share_ctrl->outpath.output_mode =
-			VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
-		break;
-	case OUTPUT_PRIM|OUTPUT_SEC:
-		axi_ctrl->share_ctrl->outpath.output_mode =
-			VFE40_OUTPUT_MODE_PRIMARY;
-		axi_ctrl->share_ctrl->outpath.output_mode |=
-			VFE40_OUTPUT_MODE_SECONDARY;
-		break;
-	case OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS:
-		axi_ctrl->share_ctrl->outpath.output_mode =
-			VFE40_OUTPUT_MODE_PRIMARY;
-		axi_ctrl->share_ctrl->outpath.output_mode |=
-			VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS;
-		break;
-	case OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC:
-		axi_ctrl->share_ctrl->outpath.output_mode =
-			VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
-		axi_ctrl->share_ctrl->outpath.output_mode |=
-			VFE40_OUTPUT_MODE_SECONDARY;
-		break;
-	default:
-		pr_err("%s Invalid AXI mode %d ", __func__, mode);
-		return -EINVAL;
-	}
-	msm_camera_io_w(*ao, axi_ctrl->share_ctrl->vfebase +
-		VFE_BUS_IO_FORMAT_CFG);
-	msm_camera_io_memcpy(axi_ctrl->share_ctrl->vfebase +
-		vfe40_cmd[VFE_CMD_AXI_OUT_CFG].offset, axi_cfg,
-		vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length - V40_AXI_CH_INF_LEN);
-	msm_camera_io_w(*ch_info++,
-		axi_ctrl->share_ctrl->vfebase + VFE_RDI0_CFG);
-	if (msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
-		V40_GET_HW_VERSION_OFF) ==
-		VFE40_HW_NUMBER) {
-		msm_camera_io_w(*ch_info++,
-			axi_ctrl->share_ctrl->vfebase + VFE_RDI1_CFG);
-		msm_camera_io_w(*ch_info++,
-			axi_ctrl->share_ctrl->vfebase + VFE_RDI2_CFG);
-	}
-	return 0;
-}
-
-static int msm_axi_config(struct v4l2_subdev *sd, void __user *arg)
-{
-	struct msm_vfe_cfg_cmd cfgcmd;
-	struct msm_isp_cmd vfecmd;
-	int rc = 0;
-	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
-
-	if (!axi_ctrl->share_ctrl->vfebase) {
-		pr_err("%s: base address unmapped\n", __func__);
-		return -EFAULT;
-	}
-	if (NULL != arg) {
-		if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
-			ERR_COPY_FROM_USER();
-			return -EFAULT;
-		}
-	}
-	if (NULL != cfgcmd.value) {
-		if (copy_from_user(&vfecmd,
-				(void __user *)(cfgcmd.value),
-				sizeof(vfecmd))) {
-			pr_err("%s %d: copy_from_user failed\n", __func__,
-				__LINE__);
-			return -EFAULT;
-		}
-	}
-
-	switch (cfgcmd.cmd_type) {
-	case CMD_AXI_CFG_PRIM: {
-		uint32_t *axio = NULL;
-		axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			break;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			rc = -EFAULT;
-			break;
-		}
-		vfe40_config_axi(axi_ctrl, OUTPUT_PRIM, axio);
-		kfree(axio);
-	}
-		break;
-	case CMD_AXI_CFG_PRIM_ALL_CHNLS: {
-		uint32_t *axio = NULL;
-		axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			break;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			rc = -EFAULT;
-			break;
-		}
-		vfe40_config_axi(axi_ctrl, OUTPUT_PRIM_ALL_CHNLS, axio);
-		kfree(axio);
-	}
-		break;
-	case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC: {
-		uint32_t *axio = NULL;
-		axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			break;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			rc = -EFAULT;
-			break;
-		}
-		vfe40_config_axi(axi_ctrl, OUTPUT_PRIM|OUTPUT_SEC, axio);
-		kfree(axio);
-	}
-		break;
-	case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC_ALL_CHNLS: {
-		uint32_t *axio = NULL;
-		axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			break;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			rc = -EFAULT;
-			break;
-		}
-		vfe40_config_axi(axi_ctrl,
-			OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS, axio);
-		kfree(axio);
-	}
-		break;
-	case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC: {
-		uint32_t *axio = NULL;
-		axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
-				GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			break;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd.value),
-				vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
-			kfree(axio);
-			rc = -EFAULT;
-			break;
-		}
-		vfe40_config_axi(axi_ctrl,
-			OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC, axio);
-		kfree(axio);
-	}
-		break;
-	case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC_ALL_CHNLS:
-		pr_err("%s Invalid/Unsupported AXI configuration %x",
-			__func__, cfgcmd.cmd_type);
-		break;
-	case CMD_AXI_START:
-		axi_start(axi_ctrl);
-		break;
-	case CMD_AXI_STOP:
-		axi_stop(axi_ctrl);
-		break;
-	case CMD_AXI_RESET:
-		break;
-	default:
-		pr_err("%s Unsupported AXI configuration %x ", __func__,
-			cfgcmd.cmd_type);
-		break;
-	}
-	return rc;
-}
-
-static struct msm_free_buf *vfe40_check_free_buffer(
-	int id, int path, struct axi_ctrl_t *axi_ctrl)
-{
-	struct vfe40_output_ch *outch = NULL;
-	struct msm_free_buf *b = NULL;
-	uint32_t image_mode = 0;
-
-	if (path == VFE_MSG_OUTPUT_PRIMARY)
-		image_mode = axi_ctrl->share_ctrl->outpath.out0.image_mode;
-	else
-		image_mode = axi_ctrl->share_ctrl->outpath.out1.image_mode;
-
-	vfe40_subdev_notify(id, path, image_mode,
-		&axi_ctrl->subdev, axi_ctrl->share_ctrl);
-	outch = vfe40_get_ch(path, axi_ctrl->share_ctrl);
-	if (outch->free_buf.ch_paddr[0])
-		b = &outch->free_buf;
-	return b;
-}
-
-static void vfe_send_outmsg(
-	struct axi_ctrl_t *axi_ctrl, uint8_t msgid,
-	uint32_t ch0_paddr, uint32_t ch1_paddr,
-	uint32_t ch2_paddr, uint32_t image_mode)
-{
-	struct isp_msg_output msg;
-
-	msg.output_id = msgid;
-	msg.buf.image_mode = image_mode;
-	msg.buf.ch_paddr[0]	= ch0_paddr;
-	msg.buf.ch_paddr[1]	= ch1_paddr;
-	msg.buf.ch_paddr[2]	= ch2_paddr;
-	msg.frameCounter = axi_ctrl->share_ctrl->vfeFrameId;
-
-	v4l2_subdev_notify(&axi_ctrl->subdev,
-			NOTIFY_VFE_MSG_OUT,
-			&msg);
-	return;
-}
-
-static void vfe40_process_output_path_irq_0(
-	struct axi_ctrl_t *axi_ctrl)
-{
-	uint32_t ping_pong;
-	uint32_t ch0_paddr, ch1_paddr, ch2_paddr;
-	uint8_t out_bool = 0;
-	struct msm_free_buf *free_buf = NULL;
-
-	free_buf = vfe40_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
-		VFE_MSG_OUTPUT_PRIMARY, axi_ctrl);
-
-	/* we render frames in the following conditions:
-	1. Continuous mode and the free buffer is avaialable.
-	2. In snapshot shot mode, free buffer is not always available.
-	when pending snapshot count is <=1,  then no need to use
-	free buffer.
-	*/
-	out_bool = (
-		(axi_ctrl->share_ctrl->operation_mode ==
-			VFE_OUTPUTS_THUMB_AND_MAIN ||
-		axi_ctrl->share_ctrl->operation_mode ==
-			VFE_OUTPUTS_MAIN_AND_THUMB ||
-		axi_ctrl->share_ctrl->operation_mode ==
-			VFE_OUTPUTS_THUMB_AND_JPEG ||
-		axi_ctrl->share_ctrl->operation_mode ==
-			VFE_OUTPUTS_JPEG_AND_THUMB ||
-		axi_ctrl->share_ctrl->operation_mode ==
-			VFE_OUTPUTS_RAW ||
-		axi_ctrl->share_ctrl->liveshot_state ==
-			VFE_STATE_STARTED ||
-		axi_ctrl->share_ctrl->liveshot_state ==
-			VFE_STATE_STOP_REQUESTED ||
-		axi_ctrl->share_ctrl->liveshot_state ==
-			VFE_STATE_STOPPED) &&
-		(axi_ctrl->share_ctrl->vfe_capture_count <= 1)) ||
-			free_buf;
-
-	if (out_bool) {
-		ping_pong = msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
-			VFE_BUS_PING_PONG_STATUS);
-
-		/* Channel 0*/
-		ch0_paddr = vfe40_get_ch_addr(
-			ping_pong, axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out0.ch0);
-		/* Channel 1*/
-		ch1_paddr = vfe40_get_ch_addr(
-			ping_pong, axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out0.ch1);
-		/* Channel 2*/
-		ch2_paddr = vfe40_get_ch_addr(
-			ping_pong, axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out0.ch2);
-
-		CDBG("output path 0, ch0 = 0x%x, ch1 = 0x%x, ch2 = 0x%x\n",
-			ch0_paddr, ch1_paddr, ch2_paddr);
-		if (free_buf) {
-			/* Y channel */
-			vfe40_put_ch_addr(ping_pong,
-			axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out0.ch0,
-			free_buf->ch_paddr[0]);
-			/* Chroma channel */
-			vfe40_put_ch_addr(ping_pong,
-			axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out0.ch1,
-			free_buf->ch_paddr[1]);
-			if (free_buf->num_planes > 2)
-				vfe40_put_ch_addr(ping_pong,
-					axi_ctrl->share_ctrl->vfebase,
-					axi_ctrl->share_ctrl->outpath.out0.ch2,
-					free_buf->ch_paddr[2]);
-		}
-		if (axi_ctrl->share_ctrl->operation_mode ==
-				VFE_OUTPUTS_THUMB_AND_MAIN ||
-			axi_ctrl->share_ctrl->operation_mode ==
-				VFE_OUTPUTS_MAIN_AND_THUMB ||
-			axi_ctrl->share_ctrl->operation_mode ==
-				VFE_OUTPUTS_THUMB_AND_JPEG ||
-			axi_ctrl->share_ctrl->operation_mode ==
-				VFE_OUTPUTS_JPEG_AND_THUMB ||
-			axi_ctrl->share_ctrl->operation_mode ==
-				VFE_OUTPUTS_RAW ||
-			axi_ctrl->share_ctrl->liveshot_state ==
-				VFE_STATE_STOPPED)
-			axi_ctrl->share_ctrl->outpath.out0.capture_cnt--;
-
-		vfe_send_outmsg(axi_ctrl,
-			MSG_ID_OUTPUT_PRIMARY, ch0_paddr,
-			ch1_paddr, ch2_paddr,
-			axi_ctrl->share_ctrl->outpath.out0.image_mode);
-
-		if (axi_ctrl->share_ctrl->liveshot_state == VFE_STATE_STOPPED)
-			axi_ctrl->share_ctrl->liveshot_state = VFE_STATE_IDLE;
-
-	} else {
-		axi_ctrl->share_ctrl->outpath.out0.frame_drop_cnt++;
-		CDBG("path_irq_0 - no free buffer!\n");
-	}
-}
-
-static void vfe40_process_output_path_irq_1(
-	struct axi_ctrl_t *axi_ctrl)
-{
-	uint32_t ping_pong;
-	uint32_t ch0_paddr, ch1_paddr, ch2_paddr;
-	/* this must be snapshot main image output. */
-	uint8_t out_bool = 0;
-	struct msm_free_buf *free_buf = NULL;
-
-	free_buf = vfe40_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
-		VFE_MSG_OUTPUT_SECONDARY, axi_ctrl);
-	out_bool = ((axi_ctrl->share_ctrl->operation_mode ==
-				VFE_OUTPUTS_THUMB_AND_MAIN ||
-			axi_ctrl->share_ctrl->operation_mode ==
-				VFE_OUTPUTS_MAIN_AND_THUMB ||
-			axi_ctrl->share_ctrl->operation_mode ==
-				VFE_OUTPUTS_RAW ||
-			axi_ctrl->share_ctrl->operation_mode ==
-				VFE_OUTPUTS_JPEG_AND_THUMB) &&
-			(axi_ctrl->share_ctrl->vfe_capture_count <= 1)) ||
-				free_buf;
-
-	if (out_bool) {
-		ping_pong = msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
-			VFE_BUS_PING_PONG_STATUS);
-
-		/* Y channel */
-		ch0_paddr = vfe40_get_ch_addr(ping_pong,
-			axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out1.ch0);
-		/* Chroma channel */
-		ch1_paddr = vfe40_get_ch_addr(ping_pong,
-			axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out1.ch1);
-		ch2_paddr = vfe40_get_ch_addr(ping_pong,
-			axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out1.ch2);
-
-		CDBG("%s ch0 = 0x%x, ch1 = 0x%x, ch2 = 0x%x\n",
-			__func__, ch0_paddr, ch1_paddr, ch2_paddr);
-		if (free_buf) {
-			/* Y channel */
-			vfe40_put_ch_addr(ping_pong,
-			axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out1.ch0,
-			free_buf->ch_paddr[0]);
-			/* Chroma channel */
-			vfe40_put_ch_addr(ping_pong,
-			axi_ctrl->share_ctrl->vfebase,
-			axi_ctrl->share_ctrl->outpath.out1.ch1,
-			free_buf->ch_paddr[1]);
-			if (free_buf->num_planes > 2)
-				vfe40_put_ch_addr(ping_pong,
-					axi_ctrl->share_ctrl->vfebase,
-					axi_ctrl->share_ctrl->outpath.out1.ch2,
-					free_buf->ch_paddr[2]);
-		}
-		if (axi_ctrl->share_ctrl->operation_mode ==
-				VFE_OUTPUTS_THUMB_AND_MAIN ||
-			axi_ctrl->share_ctrl->operation_mode ==
-				VFE_OUTPUTS_MAIN_AND_THUMB ||
-			axi_ctrl->share_ctrl->operation_mode ==
-				VFE_OUTPUTS_RAW ||
-			axi_ctrl->share_ctrl->operation_mode ==
-				VFE_OUTPUTS_JPEG_AND_THUMB)
-			axi_ctrl->share_ctrl->outpath.out1.capture_cnt--;
-
-		vfe_send_outmsg(axi_ctrl,
-			MSG_ID_OUTPUT_SECONDARY, ch0_paddr,
-			ch1_paddr, ch2_paddr,
-			axi_ctrl->share_ctrl->outpath.out1.image_mode);
-
-	} else {
-		axi_ctrl->share_ctrl->outpath.out1.frame_drop_cnt++;
-		CDBG("path_irq_1 - no free buffer!\n");
-	}
-}
-
-static void msm_axi_process_irq(struct v4l2_subdev *sd, void *arg)
-{
-	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
-	uint32_t irqstatus = (uint32_t) arg;
-
-	if (!axi_ctrl->share_ctrl->vfebase) {
-		pr_err("%s: base address unmapped\n", __func__);
-		return;
-	}
-	/* next, check output path related interrupts. */
-	if (irqstatus &
-		VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK) {
-		CDBG("Image composite done 0 irq occured.\n");
-		vfe40_process_output_path_irq_0(axi_ctrl);
-	}
-	if (irqstatus &
-		VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK) {
-		CDBG("Image composite done 1 irq occured.\n");
-		vfe40_process_output_path_irq_1(axi_ctrl);
-	}
-	/* in snapshot mode if done then send
-	snapshot done message */
-	if (axi_ctrl->share_ctrl->operation_mode ==
-			VFE_OUTPUTS_THUMB_AND_MAIN ||
-		axi_ctrl->share_ctrl->operation_mode ==
-			VFE_OUTPUTS_MAIN_AND_THUMB ||
-		axi_ctrl->share_ctrl->operation_mode ==
-			VFE_OUTPUTS_THUMB_AND_JPEG ||
-		axi_ctrl->share_ctrl->operation_mode ==
-			VFE_OUTPUTS_JPEG_AND_THUMB ||
-		axi_ctrl->share_ctrl->operation_mode ==
-			VFE_OUTPUTS_RAW) {
-		if ((axi_ctrl->share_ctrl->outpath.out0.capture_cnt == 0)
-				&& (axi_ctrl->share_ctrl->outpath.out1.
-				capture_cnt == 0)) {
-			msm_camera_io_w_mb(
-				CAMIF_COMMAND_STOP_IMMEDIATELY,
-				axi_ctrl->share_ctrl->vfebase +
-				VFE_CAMIF_COMMAND);
-			vfe40_send_isp_msg(&axi_ctrl->subdev,
-				axi_ctrl->share_ctrl->vfeFrameId,
-				MSG_ID_SNAPSHOT_DONE);
-		}
-	}
-}
-
-static int msm_axi_buf_cfg(struct v4l2_subdev *sd, void __user *arg)
-{
-	struct msm_camvfe_params *vfe_params =
-		(struct msm_camvfe_params *)arg;
-	struct msm_vfe_cfg_cmd *cmd = vfe_params->vfe_cfg;
-	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
-	void *data = vfe_params->data;
-	int rc = 0;
-
-	if (!axi_ctrl->share_ctrl->vfebase) {
-		pr_err("%s: base address unmapped\n", __func__);
-		return -EFAULT;
-	}
-
-	switch (cmd->cmd_type) {
-	case CMD_CONFIG_PING_ADDR: {
-		int path = *((int *)cmd->value);
-		struct vfe40_output_ch *outch =
-			vfe40_get_ch(path, axi_ctrl->share_ctrl);
-		outch->ping = *((struct msm_free_buf *)data);
-	}
-		break;
-
-	case CMD_CONFIG_PONG_ADDR: {
-		int path = *((int *)cmd->value);
-		struct vfe40_output_ch *outch =
-			vfe40_get_ch(path, axi_ctrl->share_ctrl);
-		outch->pong = *((struct msm_free_buf *)data);
-	}
-		break;
-
-	case CMD_CONFIG_FREE_BUF_ADDR: {
-		int path = *((int *)cmd->value);
-		struct vfe40_output_ch *outch =
-			vfe40_get_ch(path, axi_ctrl->share_ctrl);
-		outch->free_buf = *((struct msm_free_buf *)data);
-	}
-		break;
-	default:
-		pr_err("%s Unsupported AXI Buf config %x ", __func__,
-			cmd->cmd_type);
-	}
-	return rc;
-};
-
-static struct msm_cam_clk_info vfe40_clk_info[] = {
-	{"vfe_clk_src", 266670000},
-	{"camss_vfe_vfe_clk", -1},
-	{"camss_csi_vfe_clk", -1},
-	{"top_clk", -1},
-	{"iface_clk", -1},
-	{"bus_clk", -1},
-};
-
-int msm_axi_subdev_init(struct v4l2_subdev *sd,
-			struct msm_cam_media_controller *mctl)
-{
-	int rc = 0;
-	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
-	v4l2_set_subdev_hostdata(sd, mctl);
-	spin_lock_init(&axi_ctrl->tasklet_lock);
-	INIT_LIST_HEAD(&axi_ctrl->tasklet_q);
-	spin_lock_init(&axi_ctrl->share_ctrl->sd_notify_lock);
-
-	axi_ctrl->share_ctrl->vfebase = ioremap(axi_ctrl->vfemem->start,
-		resource_size(axi_ctrl->vfemem));
-	if (!axi_ctrl->share_ctrl->vfebase) {
-		rc = -ENOMEM;
-		pr_err("%s: vfe ioremap failed\n", __func__);
-		goto remap_failed;
-	}
-
-	if (axi_ctrl->fs_vfe == NULL) {
-		axi_ctrl->fs_vfe =
-			regulator_get(&axi_ctrl->pdev->dev, "vdd");
-		if (IS_ERR(axi_ctrl->fs_vfe)) {
-			pr_err("%s: Regulator FS_VFE get failed %ld\n",
-				__func__, PTR_ERR(axi_ctrl->fs_vfe));
-			axi_ctrl->fs_vfe = NULL;
-			goto fs_failed;
-		} else if (regulator_enable(axi_ctrl->fs_vfe)) {
-			pr_err("%s: Regulator FS_VFE enable failed\n",
-							__func__);
-			regulator_put(axi_ctrl->fs_vfe);
-			axi_ctrl->fs_vfe = NULL;
-			goto fs_failed;
-		}
-	}
-	rc = msm_cam_clk_enable(&axi_ctrl->pdev->dev, vfe40_clk_info,
-			axi_ctrl->vfe_clk, ARRAY_SIZE(vfe40_clk_info), 1);
-	if (rc < 0)
-			goto clk_enable_failed;
-
-	msm_camio_bus_scale_cfg(
-		mctl->sdata->pdata->cam_bus_scale_table, S_INIT);
-	msm_camio_bus_scale_cfg(
-		mctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
-
-	axi_ctrl->share_ctrl->register_total = VFE40_REGISTER_TOTAL;
-
-	enable_irq(axi_ctrl->vfeirq->start);
-
-	return rc;
-clk_enable_failed:
-	regulator_disable(axi_ctrl->fs_vfe);
-	regulator_put(axi_ctrl->fs_vfe);
-	axi_ctrl->fs_vfe = NULL;
-fs_failed:
-	iounmap(axi_ctrl->share_ctrl->vfebase);
-	axi_ctrl->share_ctrl->vfebase = NULL;
-remap_failed:
-	disable_irq(axi_ctrl->vfeirq->start);
-	return rc;
-}
-
-void msm_axi_subdev_release(struct v4l2_subdev *sd)
-{
-	struct msm_cam_media_controller *pmctl =
-		(struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
-	struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
-	if (!axi_ctrl->share_ctrl->vfebase) {
-		pr_err("%s: base address unmapped\n", __func__);
-		return;
-	}
-
-	CDBG("%s, free_irq\n", __func__);
-	disable_irq(axi_ctrl->vfeirq->start);
-	tasklet_kill(&axi_ctrl->vfe40_tasklet);
-	msm_cam_clk_enable(&axi_ctrl->pdev->dev, vfe40_clk_info,
-		axi_ctrl->vfe_clk, ARRAY_SIZE(vfe40_clk_info), 0);
-
-	if (axi_ctrl->fs_vfe) {
-		regulator_disable(axi_ctrl->fs_vfe);
-		regulator_put(axi_ctrl->fs_vfe);
-		axi_ctrl->fs_vfe = NULL;
-	}
-	iounmap(axi_ctrl->share_ctrl->vfebase);
-	axi_ctrl->share_ctrl->vfebase = NULL;
-
-	if (atomic_read(&axi_ctrl->share_ctrl->irq_cnt))
-		pr_warning("%s, Warning IRQ Count not ZERO\n", __func__);
-
-	msm_camio_bus_scale_cfg(
-		pmctl->sdata->pdata->cam_bus_scale_table, S_EXIT);
-}
-
-static long msm_axi_subdev_ioctl(struct v4l2_subdev *sd,
-			unsigned int cmd, void *arg)
-{
-	int rc = -ENOIOCTLCMD;
-	switch (cmd) {
-	case VIDIOC_MSM_AXI_INIT:
-		rc = msm_axi_subdev_init(sd,
-			(struct msm_cam_media_controller *)arg);
-		break;
-	case VIDIOC_MSM_AXI_CFG:
-		rc = msm_axi_config(sd, arg);
-		break;
-	case VIDIOC_MSM_AXI_IRQ:
-		msm_axi_process_irq(sd, arg);
-		rc = 0;
-		break;
-	case VIDIOC_MSM_AXI_BUF_CFG:
-		msm_axi_buf_cfg(sd, arg);
-		rc = 0;
-		break;
-	case VIDIOC_MSM_AXI_RELEASE:
-		msm_axi_subdev_release(sd);
-		rc = 0;
-		break;
-	default:
-		pr_err("%s: command not found\n", __func__);
-	}
-	return rc;
-}
-
-static const struct v4l2_subdev_core_ops msm_axi_subdev_core_ops = {
-	.ioctl = msm_axi_subdev_ioctl,
-};
-
-static const struct v4l2_subdev_video_ops msm_axi_subdev_video_ops = {
-	.s_crystal_freq = msm_axi_subdev_s_crystal_freq,
-};
-
-static const struct v4l2_subdev_ops msm_axi_subdev_ops = {
-	.core = &msm_axi_subdev_core_ops,
-	.video = &msm_axi_subdev_video_ops,
-};
-
-static const struct v4l2_subdev_internal_ops msm_axi_internal_ops;
-
-void vfe40_axi_probe(struct axi_ctrl_t *axi_ctrl)
-{
-	struct msm_cam_subdev_info sd_info;
-	v4l2_subdev_init(&axi_ctrl->subdev, &msm_axi_subdev_ops);
-	axi_ctrl->subdev.internal_ops = &msm_axi_internal_ops;
-	axi_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-	snprintf(axi_ctrl->subdev.name,
-			 sizeof(axi_ctrl->subdev.name), "axi");
-	v4l2_set_subdevdata(&axi_ctrl->subdev, axi_ctrl);
-
-	sd_info.sdev_type = AXI_DEV;
-	sd_info.sd_index = axi_ctrl->pdev->id;
-	sd_info.irq_num = 0;
-	msm_cam_register_subdev_node(&axi_ctrl->subdev, &sd_info);
-}
diff --git a/drivers/media/video/msm/vfe/msm_vfe7x.c b/drivers/media/video/msm/vfe/msm_vfe7x.c
deleted file mode 100644
index 6a6eeb7..0000000
--- a/drivers/media/video/msm/vfe/msm_vfe7x.c
+++ /dev/null
@@ -1,786 +0,0 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. 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/msm_adsp.h>
-#include <linux/uaccess.h>
-#include <linux/fs.h>
-#include <linux/android_pmem.h>
-#include <linux/slab.h>
-#include <mach/msm_adsp.h>
-#include <mach/clk.h>
-#include <linux/delay.h>
-#include <linux/wait.h>
-#include "msm_vfe7x.h"
-#include <linux/pm_qos.h>
-
-#define QDSP_CMDQUEUE 25
-
-#define VFE_RESET_CMD 0
-#define VFE_START_CMD 1
-#define VFE_STOP_CMD  2
-#define VFE_FRAME_ACK 20
-#define STATS_AF_ACK  21
-#define STATS_WE_ACK  22
-
-#define MSG_STOP_ACK  1
-#define MSG_SNAPSHOT  2
-#define MSG_OUTPUT1   6
-#define MSG_OUTPUT2   7
-#define MSG_STATS_AF  8
-#define MSG_STATS_WE  9
-#define MSG_OUTPUT_S  10
-#define MSG_OUTPUT_T  11
-
-#define VFE_ADSP_EVENT 0xFFFF
-#define SNAPSHOT_MASK_MODE 0x00000002
-#define MSM_AXI_QOS_PREVIEW	192000
-#define MSM_AXI_QOS_SNAPSHOT	192000
-
-
-static struct msm_adsp_module *qcam_mod;
-static struct msm_adsp_module *vfe_mod;
-static struct msm_vfe_callback *resp;
-static void *extdata;
-static uint32_t extlen;
-
-struct mutex vfe_lock;
-static void     *vfe_syncdata;
-static uint8_t vfestopped;
-static uint32_t vfetask_state;
-static int cnt;
-
-static struct stop_event stopevent;
-
-unsigned long paddr_s_y;
-unsigned long paddr_s_cbcr;
-unsigned long paddr_t_y;
-unsigned long paddr_t_cbcr;
-
-static void vfe_7x_convert(struct msm_vfe_phy_info *pinfo,
-		enum vfe_resp_msg type,
-		void *data, void **ext, int32_t *elen)
-{
-	switch (type) {
-	case VFE_MSG_OUTPUT_P: {
-		pinfo->p0_phy = ((struct vfe_endframe *)data)->y_address;
-		pinfo->p1_phy =
-			((struct vfe_endframe *)data)->cbcr_address;
-		pinfo->p2_phy = pinfo->p0_phy;
-		pinfo->output_id = OUTPUT_TYPE_P;
-
-		CDBG("vfe_7x_convert, y_phy = 0x%x, cbcr_phy = 0x%x\n",
-				 pinfo->p0_phy, pinfo->p1_phy);
-
-		((struct vfe_frame_extra *)extdata)->bl_evencol =
-		((struct vfe_endframe *)data)->blacklevelevencolumn;
-
-		((struct vfe_frame_extra *)extdata)->bl_oddcol =
-		((struct vfe_endframe *)data)->blackleveloddcolumn;
-
-		((struct vfe_frame_extra *)extdata)->g_def_p_cnt =
-		((struct vfe_endframe *)data)->greendefectpixelcount;
-
-		((struct vfe_frame_extra *)extdata)->r_b_def_p_cnt =
-		((struct vfe_endframe *)data)->redbluedefectpixelcount;
-
-		*ext  = extdata;
-		*elen = extlen;
-	}
-		break;
-
-	case VFE_MSG_OUTPUT_S: {
-		pinfo->p0_phy = paddr_s_y;
-		pinfo->p1_phy = paddr_s_cbcr;
-		pinfo->p2_phy = pinfo->p0_phy;
-		pinfo->output_id = OUTPUT_TYPE_S;
-		CDBG("vfe_7x_convert: y_phy = 0x%x cbcr_phy = 0x%x\n",
-					pinfo->p0_phy, pinfo->p1_phy);
-	}
-		break;
-
-	case VFE_MSG_OUTPUT_T: {
-		pinfo->p0_phy = paddr_t_y;
-		pinfo->p1_phy = paddr_t_cbcr;
-		pinfo->p2_phy = pinfo->p0_phy;
-		pinfo->output_id = OUTPUT_TYPE_T;
-		CDBG("vfe_7x_convert: y_phy = 0x%x cbcr_phy = 0x%x\n",
-					pinfo->p0_phy, pinfo->p1_phy);
-	}
-		break;
-
-	case VFE_MSG_STATS_AF:
-	case VFE_MSG_STATS_WE:
-		pinfo->sbuf_phy = *(uint32_t *)data;
-		break;
-
-	default:
-		break;
-	} /* switch */
-}
-
-static void vfe_7x_ops(void *driver_data, unsigned id, size_t len,
-		void (*getevent)(void *ptr, size_t len))
-{
-	uint32_t evt_buf[3];
-	struct msm_vfe_resp *rp;
-	void *data;
-	CDBG("%s:id=%d\n", __func__, id);
-
-	len = (id == VFE_ADSP_EVENT) ? 0 : len;
-	data = resp->vfe_alloc(sizeof(struct msm_vfe_resp) + len,
-		vfe_syncdata,  GFP_ATOMIC);
-
-	if (!data) {
-		pr_err("%s: rp: cannot allocate buffer\n", __func__);
-		return;
-	}
-	rp = (struct msm_vfe_resp *)data;
-	rp->evt_msg.len = len;
-
-	if (id == VFE_ADSP_EVENT) {
-		/* event */
-		rp->type           = VFE_EVENT;
-		rp->evt_msg.type   = MSM_CAMERA_EVT;
-		getevent(evt_buf, sizeof(evt_buf));
-		rp->evt_msg.msg_id = evt_buf[0];
-	CDBG("%s:event:msg_id=%d\n", __func__, rp->evt_msg.msg_id);
-		resp->vfe_resp(rp, MSM_CAM_Q_VFE_EVT, vfe_syncdata,
-		GFP_ATOMIC);
-	} else {
-		/* messages */
-		rp->evt_msg.type   = MSM_CAMERA_MSG;
-		rp->evt_msg.msg_id = id;
-		rp->evt_msg.data = rp + 1;
-		getevent(rp->evt_msg.data, len);
-	CDBG("%s:messages:msg_id=%d\n", __func__, rp->evt_msg.msg_id);
-
-		switch (rp->evt_msg.msg_id) {
-		case MSG_SNAPSHOT:
-			update_axi_qos(MSM_AXI_QOS_PREVIEW);
-			vfe_7x_ops(driver_data, MSG_OUTPUT_S, len, getevent);
-			vfe_7x_ops(driver_data, MSG_OUTPUT_T, len, getevent);
-			rp->type = VFE_MSG_SNAPSHOT;
-			break;
-
-		case MSG_OUTPUT_S:
-			rp->type = VFE_MSG_OUTPUT_S;
-			vfe_7x_convert(&(rp->phy), VFE_MSG_OUTPUT_S,
-				rp->evt_msg.data, &(rp->extdata),
-				&(rp->extlen));
-			break;
-
-		case MSG_OUTPUT_T:
-			rp->type = VFE_MSG_OUTPUT_T;
-			vfe_7x_convert(&(rp->phy), VFE_MSG_OUTPUT_T,
-				rp->evt_msg.data, &(rp->extdata),
-				&(rp->extlen));
-			break;
-
-		case MSG_OUTPUT1:
-		case MSG_OUTPUT2:
-			rp->type = VFE_MSG_OUTPUT_P;
-			vfe_7x_convert(&(rp->phy), VFE_MSG_OUTPUT_P,
-				rp->evt_msg.data, &(rp->extdata),
-				&(rp->extlen));
-			break;
-
-		case MSG_STATS_AF:
-			rp->type = VFE_MSG_STATS_AF;
-			vfe_7x_convert(&(rp->phy), VFE_MSG_STATS_AF,
-					rp->evt_msg.data, NULL, NULL);
-			break;
-
-		case MSG_STATS_WE:
-			rp->type = VFE_MSG_STATS_WE;
-			vfe_7x_convert(&(rp->phy), VFE_MSG_STATS_WE,
-					rp->evt_msg.data, NULL, NULL);
-
-			CDBG("MSG_STATS_WE: phy = 0x%x\n", rp->phy.sbuf_phy);
-			break;
-
-		case MSG_STOP_ACK:
-			rp->type = VFE_MSG_GENERAL;
-			stopevent.state = 1;
-			wake_up(&stopevent.wait);
-			break;
-
-
-		default:
-			rp->type = VFE_MSG_GENERAL;
-			break;
-		}
-		resp->vfe_resp(rp, MSM_CAM_Q_VFE_MSG, vfe_syncdata, GFP_ATOMIC);
-	}
-}
-
-static struct msm_adsp_ops vfe_7x_sync = {
-	.event = vfe_7x_ops,
-};
-
-static int vfe_7x_enable(struct camera_enable_cmd *enable)
-{
-	int rc = -EFAULT;
-
-	if (!strcmp(enable->name, "QCAMTASK"))
-		rc = msm_adsp_enable(qcam_mod);
-	else if (!strcmp(enable->name, "VFETASK")) {
-		rc = msm_adsp_enable(vfe_mod);
-		vfetask_state = 1;
-	}
-
-	if (!cnt) {
-		add_axi_qos();
-		cnt++;
-	}
-	return rc;
-}
-
-static int vfe_7x_disable(struct camera_enable_cmd *enable,
-		struct platform_device *dev __attribute__((unused)))
-{
-	int rc = -EFAULT;
-
-	if (!strcmp(enable->name, "QCAMTASK"))
-		rc = msm_adsp_disable(qcam_mod);
-	else if (!strcmp(enable->name, "VFETASK")) {
-		rc = msm_adsp_disable(vfe_mod);
-		vfetask_state = 0;
-	}
-
-	return rc;
-}
-
-static int vfe_7x_stop(void)
-{
-	int rc = 0;
-	uint32_t stopcmd = VFE_STOP_CMD;
-	rc = msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
-				&stopcmd, sizeof(uint32_t));
-	if (rc < 0) {
-		CDBG("%s:%d: failed rc = %d \n", __func__, __LINE__, rc);
-		return rc;
-	}
-
-	stopevent.state = 0;
-	rc = wait_event_timeout(stopevent.wait,
-		stopevent.state != 0,
-		msecs_to_jiffies(stopevent.timeout));
-
-	return rc;
-}
-
-static void vfe_7x_release(struct platform_device *pdev)
-{
-	mutex_lock(&vfe_lock);
-	vfe_syncdata = NULL;
-	mutex_unlock(&vfe_lock);
-
-	if (!vfestopped) {
-		CDBG("%s:%d:Calling vfe_7x_stop()\n", __func__, __LINE__);
-		vfe_7x_stop();
-	} else
-		vfestopped = 0;
-
-	msm_adsp_disable(qcam_mod);
-	msm_adsp_disable(vfe_mod);
-	vfetask_state = 0;
-
-	msm_adsp_put(qcam_mod);
-	msm_adsp_put(vfe_mod);
-
-	msm_camio_disable(pdev);
-
-	kfree(extdata);
-	extlen = 0;
-
-	/* Release AXI */
-	release_axi_qos();
-	cnt = 0;
-}
-
-static int vfe_7x_init(struct msm_vfe_callback *presp,
-	struct platform_device *dev)
-{
-	int rc = 0;
-
-	init_waitqueue_head(&stopevent.wait);
-	stopevent.timeout = 200;
-	stopevent.state = 0;
-
-	if (presp && presp->vfe_resp)
-		resp = presp;
-	else
-		return -EFAULT;
-
-	/* Bring up all the required GPIOs and Clocks */
-	rc = msm_camio_enable(dev);
-	if (rc < 0)
-		return rc;
-	msm_camio_camif_pad_reg_reset();
-
-	extlen = sizeof(struct vfe_frame_extra);
-
-	extdata =
-		kmalloc(extlen, GFP_ATOMIC);
-	if (!extdata) {
-		rc = -ENOMEM;
-		goto init_fail;
-	}
-
-	rc = msm_adsp_get("QCAMTASK", &qcam_mod, &vfe_7x_sync, NULL);
-	if (rc) {
-		rc = -EBUSY;
-		goto get_qcam_fail;
-	}
-
-	rc = msm_adsp_get("VFETASK", &vfe_mod, &vfe_7x_sync, NULL);
-	if (rc) {
-		rc = -EBUSY;
-		goto get_vfe_fail;
-	}
-
-	return 0;
-
-get_vfe_fail:
-	msm_adsp_put(qcam_mod);
-get_qcam_fail:
-	kfree(extdata);
-init_fail:
-	extlen = 0;
-	return rc;
-}
-
-static int vfe_7x_config_axi(int mode,
-	struct axidata *ad, struct axiout *ao)
-{
-	struct msm_pmem_region *regptr;
-	unsigned long *bptr;
-	int    cnt;
-
-	int rc = 0;
-
-	if (mode == OUTPUT_1 || mode == OUTPUT_1_AND_2) {
-		regptr = ad->region;
-
-		CDBG("bufnum1 = %d\n", ad->bufnum1);
-		if (mode == OUTPUT_1_AND_2) {
-			paddr_t_y = regptr->paddr + regptr->info.planar0_off;
-			paddr_t_cbcr = regptr->paddr + regptr->info.planar1_off;
-		}
-
-		CDBG("config_axi1: O1, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
-			regptr->paddr, regptr->info.planar0_off,
-			regptr->info.planar1_off);
-
-		bptr = &ao->output1buffer1_y_phy;
-		for (cnt = 0; cnt < ad->bufnum1; cnt++) {
-			*bptr = regptr->paddr + regptr->info.planar0_off;
-			bptr++;
-			*bptr = regptr->paddr + regptr->info.planar1_off;
-
-			bptr++;
-			regptr++;
-		}
-
-		regptr--;
-		for (cnt = 0; cnt < (8 - ad->bufnum1); cnt++) {
-			*bptr = regptr->paddr + regptr->info.planar0_off;
-			bptr++;
-			*bptr = regptr->paddr + regptr->info.planar1_off;
-			bptr++;
-		}
-	} /* if OUTPUT1 or Both */
-
-	if (mode == OUTPUT_2 || mode == OUTPUT_1_AND_2) {
-		regptr = &(ad->region[ad->bufnum1]);
-
-		CDBG("bufnum2 = %d\n", ad->bufnum2);
-		paddr_s_y = regptr->paddr +  regptr->info.planar0_off;
-		paddr_s_cbcr = regptr->paddr +  regptr->info.planar1_off;
-		CDBG("config_axi2: O2, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
-			regptr->paddr, regptr->info.planar0_off,
-			regptr->info.planar1_off);
-
-		bptr = &ao->output2buffer1_y_phy;
-		for (cnt = 0; cnt < ad->bufnum2; cnt++) {
-			*bptr = regptr->paddr + regptr->info.planar0_off;
-			bptr++;
-			*bptr = regptr->paddr + regptr->info.planar1_off;
-
-			bptr++;
-			regptr++;
-		}
-
-		regptr--;
-		for (cnt = 0; cnt < (8 - ad->bufnum2); cnt++) {
-			*bptr = regptr->paddr + regptr->info.planar0_off;
-			bptr++;
-			*bptr = regptr->paddr + regptr->info.planar1_off;
-			bptr++;
-		}
-	}
-
-	return rc;
-}
-
-static int vfe_7x_config(struct msm_vfe_cfg_cmd *cmd, void *data)
-{
-	struct msm_pmem_region *regptr;
-	unsigned char buf[256];
-
-	struct vfe_stats_ack sack;
-	struct axidata *axid;
-	uint32_t i, op_mode;
-	uint32_t *_mode;
-
-	struct vfe_stats_we_cfg *scfg = NULL;
-	struct vfe_stats_af_cfg *sfcfg = NULL;
-
-	struct axiout *axio = NULL;
-	void   *cmd_data = NULL;
-	void   *cmd_data_alloc = NULL;
-	long rc = 0;
-	struct msm_vfe_command_7k *vfecmd;
-
-	vfecmd =
-			kmalloc(sizeof(struct msm_vfe_command_7k),
-				GFP_ATOMIC);
-	if (!vfecmd) {
-		pr_err("vfecmd alloc failed!\n");
-		return -ENOMEM;
-	}
-
-	if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
-	    cmd->cmd_type != CMD_STATS_BUF_RELEASE &&
-	    cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE) {
-		if (copy_from_user(vfecmd,
-				(void __user *)(cmd->value),
-				sizeof(struct msm_vfe_command_7k))) {
-			rc = -EFAULT;
-			goto config_failure;
-		}
-	}
-
-	switch (cmd->cmd_type) {
-	case CMD_STATS_AEC_AWB_ENABLE:
-	case CMD_STATS_AXI_CFG: {
-		axid = data;
-		if (!axid) {
-			rc = -EFAULT;
-			goto config_failure;
-		}
-
-		scfg =
-			kmalloc(sizeof(struct vfe_stats_we_cfg),
-				GFP_ATOMIC);
-		if (!scfg) {
-			rc = -ENOMEM;
-			goto config_failure;
-		}
-
-		if (copy_from_user(scfg,
-					(void __user *)(vfecmd->value),
-					vfecmd->length)) {
-
-			rc = -EFAULT;
-			goto config_done;
-		}
-
-		CDBG("STATS_ENABLE: bufnum = %d, enabling = %d\n",
-			axid->bufnum1, scfg->wb_expstatsenable);
-
-		if (axid->bufnum1 > 0) {
-			regptr = axid->region;
-
-			for (i = 0; i < axid->bufnum1; i++) {
-
-				CDBG("STATS_ENABLE, phy = 0x%lx\n",
-					regptr->paddr);
-
-				scfg->wb_expstatoutputbuffer[i] =
-					(void *)regptr->paddr;
-				regptr++;
-			}
-
-			cmd_data = scfg;
-
-		} else {
-			rc = -EINVAL;
-			goto config_done;
-		}
-	}
-		break;
-
-	case CMD_STATS_AF_ENABLE:
-	case CMD_STATS_AF_AXI_CFG: {
-		axid = data;
-		if (!axid) {
-			rc = -EFAULT;
-			goto config_failure;
-		}
-
-		sfcfg =
-			kmalloc(sizeof(struct vfe_stats_af_cfg),
-				GFP_ATOMIC);
-
-		if (!sfcfg) {
-			rc = -ENOMEM;
-			goto config_failure;
-		}
-
-		if (copy_from_user(sfcfg,
-					(void __user *)(vfecmd->value),
-					vfecmd->length)) {
-
-			rc = -EFAULT;
-			goto config_done;
-		}
-
-		CDBG("AF_ENABLE: bufnum = %d, enabling = %d\n",
-			axid->bufnum1, sfcfg->af_enable);
-
-		if (axid->bufnum1 > 0) {
-			regptr = &axid->region[0];
-
-			for (i = 0; i < axid->bufnum1; i++) {
-
-				CDBG("STATS_ENABLE, phy = 0x%lx\n",
-					regptr->paddr);
-
-				sfcfg->af_outbuf[i] =
-					(void *)regptr->paddr;
-
-				regptr++;
-			}
-
-			cmd_data = sfcfg;
-
-		} else {
-			rc = -EINVAL;
-			goto config_done;
-		}
-	}
-		break;
-
-	case CMD_FRAME_BUF_RELEASE: {
-		struct msm_frame *b;
-		unsigned long p;
-		struct vfe_outputack fack;
-		if (!data)  {
-			rc = -EFAULT;
-			goto config_failure;
-		}
-
-		b = (struct msm_frame *)(cmd->value);
-		p = *(unsigned long *)data;
-
-		fack.header = VFE_FRAME_ACK;
-
-		fack.output2newybufferaddress =
-			(void *)(p + b->planar0_off);
-
-		fack.output2newcbcrbufferaddress =
-			(void *)(p + b->planar1_off);
-
-		vfecmd->queue = QDSP_CMDQUEUE;
-		vfecmd->length = sizeof(struct vfe_outputack);
-		cmd_data = &fack;
-	}
-		break;
-
-	case CMD_SNAP_BUF_RELEASE:
-		break;
-
-	case CMD_STATS_BUF_RELEASE: {
-		CDBG("vfe_7x_config: CMD_STATS_BUF_RELEASE\n");
-		if (!data) {
-			rc = -EFAULT;
-			goto config_failure;
-		}
-
-		sack.header = STATS_WE_ACK;
-		sack.bufaddr = (void *)*(uint32_t *)data;
-
-		vfecmd->queue  = QDSP_CMDQUEUE;
-		vfecmd->length = sizeof(struct vfe_stats_ack);
-		cmd_data = &sack;
-	}
-		break;
-
-	case CMD_STATS_AF_BUF_RELEASE: {
-		CDBG("vfe_7x_config: CMD_STATS_AF_BUF_RELEASE\n");
-		if (!data) {
-			rc = -EFAULT;
-			goto config_failure;
-		}
-
-		sack.header = STATS_AF_ACK;
-		sack.bufaddr = (void *)*(uint32_t *)data;
-
-		vfecmd->queue  = QDSP_CMDQUEUE;
-		vfecmd->length = sizeof(struct vfe_stats_ack);
-		cmd_data = &sack;
-	}
-		break;
-
-	case CMD_GENERAL:
-	case CMD_STATS_DISABLE: {
-		if (vfecmd->length > 256) {
-			cmd_data_alloc =
-			cmd_data = kmalloc(vfecmd->length, GFP_ATOMIC);
-			if (!cmd_data) {
-				rc = -ENOMEM;
-				goto config_failure;
-			}
-		} else
-			cmd_data = buf;
-
-		if (copy_from_user(cmd_data,
-					(void __user *)(vfecmd->value),
-					vfecmd->length)) {
-
-			rc = -EFAULT;
-			goto config_done;
-		}
-
-		if (vfecmd->queue == QDSP_CMDQUEUE) {
-			switch (*(uint32_t *)cmd_data) {
-			case VFE_RESET_CMD:
-				msm_camio_vfe_blk_reset();
-				vfestopped = 0;
-				break;
-
-			case VFE_START_CMD:
-				_mode = (uint32_t *)cmd_data;
-				op_mode = *(++_mode);
-				if (op_mode & SNAPSHOT_MASK_MODE) {
-					/* request AXI bus for snapshot */
-					if (update_axi_qos(MSM_AXI_QOS_SNAPSHOT)
-						< 0) {
-						rc = -EFAULT;
-						goto config_failure;
-					}
-				} else {
-					/* request AXI bus for snapshot */
-					if (update_axi_qos(MSM_AXI_QOS_PREVIEW)
-						< 0) {
-						rc = -EFAULT;
-						goto config_failure;
-					}
-				}
-				msm_camio_camif_pad_reg_reset_2();
-				vfestopped = 0;
-				break;
-
-			case VFE_STOP_CMD:
-				vfestopped = 1;
-				goto config_send;
-
-			default:
-				break;
-			}
-		} /* QDSP_CMDQUEUE */
-	}
-		break;
-	case CMD_AXI_CFG_PREVIEW:
-	case CMD_RAW_PICT_AXI_CFG: {
-		axid = data;
-		if (!axid) {
-			rc = -EFAULT;
-			goto config_failure;
-		}
-
-		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			goto config_failure;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd->value),
-					sizeof(struct axiout))) {
-			rc = -EFAULT;
-			goto config_done;
-		}
-
-		vfe_7x_config_axi(OUTPUT_2, axid, axio);
-		cmd_data = axio;
-	}
-		break;
-
-	case CMD_AXI_CFG_SNAP: {
-		axid = data;
-		if (!axid) {
-			rc = -EFAULT;
-			goto config_failure;
-		}
-
-		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			goto config_failure;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd->value),
-					sizeof(struct axiout))) {
-			rc = -EFAULT;
-			goto config_done;
-		}
-
-		vfe_7x_config_axi(OUTPUT_1_AND_2, axid, axio);
-
-		cmd_data = axio;
-	}
-		break;
-
-	default:
-		break;
-	} /* switch */
-
-	if (vfestopped)
-		goto config_done;
-
-config_send:
-	CDBG("send adsp command = %d\n", *(uint32_t *)cmd_data);
-	if (vfetask_state)
-		rc = msm_adsp_write(vfe_mod, vfecmd->queue,
-					cmd_data, vfecmd->length);
-config_done:
-	if (cmd_data_alloc != NULL)
-		kfree(cmd_data_alloc);
-
-config_failure:
-	kfree(scfg);
-	kfree(axio);
-	kfree(vfecmd);
-	return rc;
-}
-
-void msm_camvfe_fn_init(struct msm_camvfe_fn *fptr, void *data)
-{
-	mutex_init(&vfe_lock);
-	fptr->vfe_init    = vfe_7x_init;
-	fptr->vfe_enable  = vfe_7x_enable;
-	fptr->vfe_config  = vfe_7x_config;
-	fptr->vfe_disable = vfe_7x_disable;
-	fptr->vfe_release = vfe_7x_release;
-	vfe_syncdata = data;
-}
-
-void msm_camvpe_fn_init(struct msm_camvpe_fn *fptr, void *data)
-{
-	fptr->vpe_reg		= NULL;
-	fptr->send_frame_to_vpe	= NULL;
-	fptr->vpe_config	= NULL;
-	fptr->vpe_cfg_update	= NULL;
-	fptr->dis		= NULL;
-}
diff --git a/drivers/media/video/msm/vfe/msm_vfe7x.h b/drivers/media/video/msm/vfe/msm_vfe7x.h
deleted file mode 100644
index dd3571f..0000000
--- a/drivers/media/video/msm/vfe/msm_vfe7x.h
+++ /dev/null
@@ -1,265 +0,0 @@
-/* Copyright (c) 2009, Code Aurora Forum. 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 __MSM_VFE7X_H__
-#define __MSM_VFE7X_H__
-#include <media/msm_camera.h>
-#include <mach/camera.h>
-
-struct vfe_frame_extra {
-	uint32_t  bl_evencol;
-	uint32_t  bl_oddcol;
-	uint16_t  g_def_p_cnt;
-	uint16_t  r_b_def_p_cnt;
-};
-
-struct vfe_endframe {
-	uint32_t      y_address;
-	uint32_t      cbcr_address;
-
-	unsigned int  blacklevelevencolumn:23;
-	uint16_t      reserved1:9;
-	unsigned int  blackleveloddcolumn:23;
-	uint16_t      reserved2:9;
-
-	uint16_t      greendefectpixelcount:8;
-	uint16_t      reserved3:8;
-	uint16_t      redbluedefectpixelcount:8;
-	uint16_t      reserved4:8;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_outputack {
-	uint32_t  header;
-	void      *output2newybufferaddress;
-	void      *output2newcbcrbufferaddress;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_stats_ack {
-	uint32_t header;
-	/* MUST BE 64 bit ALIGNED */
-	void     *bufaddr;
-} __attribute__((packed, aligned(4)));
-
-/* AXI Output Config Command sent to DSP */
-struct axiout {
-	uint32_t            cmdheader:32;
-	int 		    outputmode:3;
-	uint8_t             format:2;
-	uint32_t            /* reserved */ : 27;
-
-	/* AXI Output 1 Y Configuration, Part 1 */
-	uint32_t            out1yimageheight:12;
-	uint32_t            /* reserved */ : 4;
-	uint32_t            out1yimagewidthin64bitwords:10;
-	uint32_t            /* reserved */ : 6;
-
-	/* AXI Output 1 Y Configuration, Part 2 */
-	uint8_t             out1yburstlen:2;
-	uint32_t            out1ynumrows:12;
-	uint32_t            out1yrowincin64bitincs:12;
-	uint32_t            /* reserved */ : 6;
-
-	/* AXI Output 1 CbCr Configuration, Part 1 */
-	uint32_t            out1cbcrimageheight:12;
-	uint32_t            /* reserved */ : 4;
-	uint32_t            out1cbcrimagewidthin64bitwords:10;
-	uint32_t            /* reserved */ : 6;
-
-	/* AXI Output 1 CbCr Configuration, Part 2 */
-	uint8_t             out1cbcrburstlen:2;
-	uint32_t            out1cbcrnumrows:12;
-	uint32_t            out1cbcrrowincin64bitincs:12;
-	uint32_t            /* reserved */ : 6;
-
-	/* AXI Output 2 Y Configuration, Part 1 */
-	uint32_t            out2yimageheight:12;
-	uint32_t            /* reserved */ : 4;
-	uint32_t            out2yimagewidthin64bitwords:10;
-	uint32_t            /* reserved */ : 6;
-
-	/* AXI Output 2 Y Configuration, Part 2 */
-	uint8_t             out2yburstlen:2;
-	uint32_t            out2ynumrows:12;
-	uint32_t            out2yrowincin64bitincs:12;
-	uint32_t            /* reserved */ : 6;
-
-	/* AXI Output 2 CbCr Configuration, Part 1 */
-	uint32_t            out2cbcrimageheight:12;
-	uint32_t            /* reserved */ : 4;
-	uint32_t            out2cbcrimagewidtein64bitwords:10;
-	uint32_t            /* reserved */ : 6;
-
-	/* AXI Output 2 CbCr Configuration, Part 2 */
-	uint8_t             out2cbcrburstlen:2;
-	uint32_t            out2cbcrnumrows:12;
-	uint32_t            out2cbcrrowincin64bitincs:12;
-	uint32_t            /* reserved */ : 6;
-
-	/* Address configuration:
-	 * output1 phisycal address */
-	unsigned long   output1buffer1_y_phy;
-	unsigned long   output1buffer1_cbcr_phy;
-	unsigned long   output1buffer2_y_phy;
-	unsigned long   output1buffer2_cbcr_phy;
-	unsigned long   output1buffer3_y_phy;
-	unsigned long   output1buffer3_cbcr_phy;
-	unsigned long   output1buffer4_y_phy;
-	unsigned long   output1buffer4_cbcr_phy;
-	unsigned long   output1buffer5_y_phy;
-	unsigned long   output1buffer5_cbcr_phy;
-	unsigned long   output1buffer6_y_phy;
-	unsigned long   output1buffer6_cbcr_phy;
-	unsigned long   output1buffer7_y_phy;
-	unsigned long   output1buffer7_cbcr_phy;
-	unsigned long   output1buffer8_y_phy;
-	unsigned long   output1buffer8_cbcr_phy;
-
-	/* output2 phisycal address */
-	unsigned long   output2buffer1_y_phy;
-	unsigned long   output2buffer1_cbcr_phy;
-	unsigned long   output2buffer2_y_phy;
-	unsigned long   output2buffer2_cbcr_phy;
-	unsigned long   output2buffer3_y_phy;
-	unsigned long   output2buffer3_cbcr_phy;
-	unsigned long   output2buffer4_y_phy;
-	unsigned long   output2buffer4_cbcr_phy;
-	unsigned long   output2buffer5_y_phy;
-	unsigned long   output2buffer5_cbcr_phy;
-	unsigned long   output2buffer6_y_phy;
-	unsigned long   output2buffer6_cbcr_phy;
-	unsigned long   output2buffer7_y_phy;
-	unsigned long   output2buffer7_cbcr_phy;
-	unsigned long   output2buffer8_y_phy;
-	unsigned long   output2buffer8_cbcr_phy;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_stats_we_cfg {
-	uint32_t       header;
-
-	/* White Balance/Exposure Statistic Selection */
-	uint8_t        wb_expstatsenable:1;
-	uint8_t        wb_expstatbuspriorityselection:1;
-	unsigned int   wb_expstatbuspriorityvalue:4;
-	unsigned int   /* reserved */ : 26;
-
-	/* White Balance/Exposure Statistic Configuration, Part 1 */
-	uint8_t        exposurestatregions:1;
-	uint8_t        exposurestatsubregions:1;
-	unsigned int   /* reserved */ : 14;
-
-	unsigned int   whitebalanceminimumy:8;
-	unsigned int   whitebalancemaximumy:8;
-
-	/* White Balance/Exposure Statistic Configuration, Part 2 */
-	uint8_t wb_expstatslopeofneutralregionline[
-		NUM_WB_EXP_NEUTRAL_REGION_LINES];
-
-	/* White Balance/Exposure Statistic Configuration, Part 3 */
-	unsigned int   wb_expstatcrinterceptofneutralregionline2:12;
-	unsigned int   /* reserved */ : 4;
-	unsigned int   wb_expstatcbinterceptofneutralreginnline1:12;
-	unsigned int    /* reserved */ : 4;
-
-	/* White Balance/Exposure Statistic Configuration, Part 4 */
-	unsigned int   wb_expstatcrinterceptofneutralregionline4:12;
-	unsigned int   /* reserved */ : 4;
-	unsigned int   wb_expstatcbinterceptofneutralregionline3:12;
-	unsigned int   /* reserved */ : 4;
-
-	/* White Balance/Exposure Statistic Output Buffer Header */
-	unsigned int   wb_expmetricheaderpattern:8;
-	unsigned int   /* reserved */ : 24;
-
-	/* White Balance/Exposure Statistic Output Buffers-MUST
-	* BE 64 bit ALIGNED */
-	void  *wb_expstatoutputbuffer[NUM_WB_EXP_STAT_OUTPUT_BUFFERS];
-} __attribute__((packed, aligned(4)));
-
-struct vfe_stats_af_cfg {
-	uint32_t header;
-
-	/* Autofocus Statistic Selection */
-	uint8_t       af_enable:1;
-	uint8_t       af_busprioritysel:1;
-	unsigned int  af_buspriorityval:4;
-	unsigned int  /* reserved */ : 26;
-
-	/* Autofocus Statistic Configuration, Part 1 */
-	unsigned int  af_singlewinvoffset:12;
-	unsigned int  /* reserved */ : 4;
-	unsigned int  af_singlewinhoffset:12;
-	unsigned int  /* reserved */ : 3;
-	uint8_t       af_winmode:1;
-
-	/* Autofocus Statistic Configuration, Part 2 */
-	unsigned int  af_singglewinvh:11;
-	unsigned int  /* reserved */ : 5;
-	unsigned int  af_singlewinhw:11;
-	unsigned int  /* reserved */ : 5;
-
-	/* Autofocus Statistic Configuration, Parts 3-6 */
-	uint8_t       af_multiwingrid[NUM_AUTOFOCUS_MULTI_WINDOW_GRIDS];
-
-	/* Autofocus Statistic Configuration, Part 7 */
-	signed int    af_metrichpfcoefa00:5;
-	signed int    af_metrichpfcoefa04:5;
-	unsigned int  af_metricmaxval:11;
-	uint8_t       af_metricsel:1;
-	unsigned int  /* reserved */ : 10;
-
-	/* Autofocus Statistic Configuration, Part 8 */
-	signed int    af_metrichpfcoefa20:5;
-	signed int    af_metrichpfcoefa21:5;
-	signed int    af_metrichpfcoefa22:5;
-	signed int    af_metrichpfcoefa23:5;
-	signed int    af_metrichpfcoefa24:5;
-	unsigned int  /* reserved */ : 7;
-
-	/* Autofocus Statistic Output Buffer Header */
-	unsigned int  af_metrichp:8;
-	unsigned int  /* reserved */ : 24;
-
-	/* Autofocus Statistic Output Buffers - MUST BE 64 bit ALIGNED!!! */
-	void *af_outbuf[NUM_AF_STAT_OUTPUT_BUFFERS];
-} __attribute__((packed, aligned(4))); /* VFE_StatsAutofocusConfigCmdType */
-
-struct msm_camera_frame_msg {
-	unsigned long   output_y_address;
-	unsigned long   output_cbcr_address;
-
-	unsigned int    blacklevelevenColumn:23;
-	uint16_t        reserved1:9;
-	unsigned int    blackleveloddColumn:23;
-	uint16_t        reserved2:9;
-
-	uint16_t        greendefectpixelcount:8;
-	uint16_t        reserved3:8;
-	uint16_t        redbluedefectpixelcount:8;
-	uint16_t        reserved4:8;
-} __attribute__((packed, aligned(4)));
-
-/* New one for 7k */
-struct msm_vfe_command_7k {
-	uint16_t queue;
-	uint16_t length;
-	void     *value;
-};
-
-struct stop_event {
-  wait_queue_head_t wait;
-	int state;
-  int timeout;
-};
-
-
-#endif /* __MSM_VFE7X_H__ */
diff --git a/drivers/media/video/msm/vfe/msm_vfe7x27a.c b/drivers/media/video/msm/vfe/msm_vfe7x27a.c
deleted file mode 100644
index 825b7cb..0000000
--- a/drivers/media/video/msm/vfe/msm_vfe7x27a.c
+++ /dev/null
@@ -1,745 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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/msm_adsp.h>
-#include <linux/uaccess.h>
-#include <linux/fs.h>
-#include <linux/android_pmem.h>
-#include <linux/slab.h>
-#include <linux/pm_qos.h>
-#include <linux/delay.h>
-#include <linux/wait.h>
-#include <mach/msm_adsp.h>
-#include <mach/clk.h>
-#include <mach/camera.h>
-#include "msm_vfe7x27a.h"
-
-#define QDSP_CMDQUEUE 25
-
-#define VFE_RESET_CMD 0
-#define VFE_START_CMD 1
-#define VFE_STOP_CMD  2
-#define VFE_FRAME_ACK 20
-#define STATS_AF_ACK  21
-#define STATS_WE_ACK  22
-
-#define MSG_STOP_ACK  1
-#define MSG_SNAPSHOT  2
-#define MSG_OUTPUT1   6
-#define MSG_OUTPUT2   7
-#define MSG_STATS_AF  8
-#define MSG_STATS_WE  9
-#define MSG_OUTPUT_S  23
-#define MSG_OUTPUT_T  22
-#define MSG_SOF       15
-
-#define VFE_ADSP_EVENT 0xFFFF
-#define SNAPSHOT_MASK_MODE 0x00000002
-#define MSM_AXI_QOS_PREVIEW	122000
-#define MSM_AXI_QOS_SNAPSHOT	192000
-
-
-static struct msm_adsp_module *qcam_mod;
-static struct msm_adsp_module *vfe_mod;
-static struct msm_vfe_callback *resp;
-static void *extdata;
-static uint32_t extlen;
-
-struct mutex vfe_lock;
-static void     *vfe_syncdata;
-static uint8_t vfestopped;
-
-static struct stop_event stopevent;
-
-unsigned long paddr_s_y;
-unsigned long paddr_s_cbcr;
-unsigned long paddr_t_y;
-unsigned long paddr_t_cbcr;
-static uint32_t op_mode;
-
-static void vfe_7x_convert(struct msm_vfe_phy_info *pinfo,
-		enum vfe_resp_msg type,
-		void *data, void **ext, int32_t *elen)
-{
-	switch (type) {
-	case VFE_MSG_OUTPUT_P: {
-		pinfo->p0_phy = ((struct vfe_endframe *)data)->y_address;
-		pinfo->p1_phy =
-			((struct vfe_endframe *)data)->cbcr_address;
-		pinfo->p2_phy = pinfo->p0_phy;
-		pinfo->output_id = OUTPUT_TYPE_P;
-
-		CDBG("vfe_7x_convert, y_phy = 0x%x, cbcr_phy = 0x%x\n",
-				 pinfo->p0_phy, pinfo->p1_phy);
-
-		memcpy(((struct vfe_frame_extra *)extdata),
-			&((struct vfe_endframe *)data)->extra,
-			sizeof(struct vfe_frame_extra));
-
-		*ext  = extdata;
-		*elen = extlen;
-		pinfo->frame_id =
-				((struct vfe_frame_extra *)extdata)->frame_id;
-	}
-		break;
-	case VFE_MSG_OUTPUT_S: {
-		pinfo->p0_phy = paddr_s_y;
-		pinfo->p1_phy = paddr_s_cbcr;
-		pinfo->p2_phy = pinfo->p0_phy;
-		pinfo->output_id = OUTPUT_TYPE_S;
-		CDBG("vfe_7x_convert: y_phy = 0x%x cbcr_phy = 0x%x\n",
-					pinfo->p0_phy, pinfo->p1_phy);
-	}
-		break;
-	case VFE_MSG_OUTPUT_T: {
-		pinfo->p0_phy = paddr_t_y;
-		pinfo->p1_phy = paddr_t_cbcr;
-		pinfo->p2_phy = pinfo->p0_phy;
-		pinfo->output_id = OUTPUT_TYPE_T;
-		CDBG("vfe_7x_convert: y_phy = 0x%x cbcr_phy = 0x%x\n",
-					pinfo->p0_phy, pinfo->p1_phy);
-	}
-		break;
-	case VFE_MSG_STATS_AF:
-	case VFE_MSG_STATS_WE:
-		pinfo->sbuf_phy = *(uint32_t *)data;
-		pinfo->frame_id = *(((uint32_t *)data) + 1);
-		CDBG("frame id = %d\n", pinfo->frame_id);
-		break;
-	default:
-		break;
-	}
-}
-
-static void vfe_7x_ops(void *driver_data, unsigned id, size_t len,
-		void (*getevent)(void *ptr, size_t len))
-{
-	uint32_t evt_buf[3];
-	struct msm_vfe_resp *rp;
-	void *data;
-	CDBG("%s:id=%d\n", __func__, id);
-
-	len = (id == VFE_ADSP_EVENT) ? 0 : len;
-	data = resp->vfe_alloc(sizeof(struct msm_vfe_resp) + len,
-		vfe_syncdata,  GFP_ATOMIC);
-
-	if (!data) {
-		pr_err("%s: rp: cannot allocate buffer\n", __func__);
-		return;
-	}
-	rp = data;
-	rp->evt_msg.len = len;
-
-	if (id == VFE_ADSP_EVENT) {
-		/* event */
-		rp->type           = VFE_EVENT;
-		rp->evt_msg.type   = MSM_CAMERA_EVT;
-		getevent(evt_buf, sizeof(evt_buf));
-		rp->evt_msg.msg_id = evt_buf[0];
-		CDBG("%s:event:msg_id=%d\n", __func__, rp->evt_msg.msg_id);
-		resp->vfe_resp(rp, MSM_CAM_Q_VFE_EVT, vfe_syncdata,
-		GFP_ATOMIC);
-	} else {
-		/* messages */
-		rp->evt_msg.type   = MSM_CAMERA_MSG;
-		rp->evt_msg.msg_id = id;
-		rp->evt_msg.data = rp + 1;
-		getevent(rp->evt_msg.data, len);
-		CDBG("%s:messages:msg_id=%d\n", __func__, rp->evt_msg.msg_id);
-
-		switch (rp->evt_msg.msg_id) {
-		case MSG_SNAPSHOT:
-			msm_camio_set_perf_lvl(S_PREVIEW);
-			vfe_7x_ops(driver_data, MSG_OUTPUT_S, len, getevent);
-			vfe_7x_ops(driver_data, MSG_OUTPUT_T, len, getevent);
-			rp->type = VFE_MSG_SNAPSHOT;
-			break;
-		case MSG_OUTPUT_S:
-			rp->type = VFE_MSG_OUTPUT_S;
-			vfe_7x_convert(&(rp->phy), VFE_MSG_OUTPUT_S,
-					rp->evt_msg.data, &(rp->extdata),
-					&(rp->extlen));
-			break;
-		case MSG_OUTPUT_T:
-			rp->type = VFE_MSG_OUTPUT_T;
-			vfe_7x_convert(&(rp->phy), VFE_MSG_OUTPUT_T,
-					rp->evt_msg.data, &(rp->extdata),
-					&(rp->extlen));
-			break;
-		case MSG_OUTPUT1:
-		case MSG_OUTPUT2:
-			if (op_mode & SNAPSHOT_MASK_MODE) {
-				resp->vfe_free(data);
-				return;
-			}
-			rp->type = VFE_MSG_OUTPUT_P;
-			vfe_7x_convert(&(rp->phy), VFE_MSG_OUTPUT_P,
-				rp->evt_msg.data, &(rp->extdata),
-				&(rp->extlen));
-			break;
-		case MSG_STATS_AF:
-			rp->type = VFE_MSG_STATS_AF;
-			vfe_7x_convert(&(rp->phy), VFE_MSG_STATS_AF,
-					rp->evt_msg.data, NULL, NULL);
-			break;
-		case MSG_STATS_WE:
-			rp->type = VFE_MSG_STATS_WE;
-			vfe_7x_convert(&(rp->phy), VFE_MSG_STATS_WE,
-					rp->evt_msg.data, NULL, NULL);
-
-			CDBG("MSG_STATS_WE: phy = 0x%x\n", rp->phy.sbuf_phy);
-			break;
-		case MSG_STOP_ACK:
-			rp->type = VFE_MSG_GENERAL;
-			stopevent.state = 1;
-			wake_up(&stopevent.wait);
-			break;
-		default:
-			rp->type = VFE_MSG_GENERAL;
-			break;
-		}
-		if (id != MSG_SOF)
-			resp->vfe_resp(rp, MSM_CAM_Q_VFE_MSG,
-					vfe_syncdata, GFP_ATOMIC);
-	}
-}
-
-static struct msm_adsp_ops vfe_7x_sync = {
-	.event = vfe_7x_ops,
-};
-
-static int vfe_7x_enable(struct camera_enable_cmd *enable)
-{
-	int rc = -EFAULT;
-	static int cnt;
-
-	if (!strcmp(enable->name, "QCAMTASK"))
-		rc = msm_adsp_enable(qcam_mod);
-	else if (!strcmp(enable->name, "VFETASK"))
-		rc = msm_adsp_enable(vfe_mod);
-
-	if (!cnt) {
-		msm_camio_set_perf_lvl(S_INIT);
-		cnt++;
-	}
-	return rc;
-}
-
-static int vfe_7x_disable(struct camera_enable_cmd *enable,
-		struct platform_device *dev __attribute__((unused)))
-{
-	int rc = -EFAULT;
-
-	if (!strcmp(enable->name, "QCAMTASK"))
-		rc = msm_adsp_disable(qcam_mod);
-	else if (!strcmp(enable->name, "VFETASK"))
-		rc = msm_adsp_disable(vfe_mod);
-
-	return rc;
-}
-
-static int vfe_7x_stop(void)
-{
-	int rc = 0;
-	uint32_t stopcmd = VFE_STOP_CMD;
-	rc = msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
-				&stopcmd, sizeof(uint32_t));
-	if (rc < 0) {
-		CDBG("%s:%d: failed rc = %d\n", __func__, __LINE__, rc);
-		return rc;
-	}
-
-	stopevent.state = 0;
-	rc = wait_event_timeout(stopevent.wait,
-		stopevent.state != 0,
-		msecs_to_jiffies(stopevent.timeout));
-
-	return rc;
-}
-
-static void vfe_7x_release(struct platform_device *pdev)
-{
-	mutex_lock(&vfe_lock);
-	vfe_syncdata = NULL;
-	mutex_unlock(&vfe_lock);
-
-	if (!vfestopped) {
-		CDBG("%s:%d:Calling vfe_7x_stop()\n", __func__, __LINE__);
-		vfe_7x_stop();
-	} else
-		vfestopped = 0;
-
-	msm_adsp_disable(qcam_mod);
-	msm_adsp_disable(vfe_mod);
-
-	msm_adsp_put(qcam_mod);
-	msm_adsp_put(vfe_mod);
-
-	msm_camio_disable(pdev);
-
-	kfree(extdata);
-	extlen = 0;
-
-	msm_camio_set_perf_lvl(S_EXIT);
-}
-
-static int vfe_7x_init(struct msm_vfe_callback *presp,
-	struct platform_device *dev)
-{
-	int rc = 0;
-
-	init_waitqueue_head(&stopevent.wait);
-	stopevent.timeout = 200;
-	stopevent.state = 0;
-
-	if (presp && presp->vfe_resp)
-		resp = presp;
-	else
-		return -EFAULT;
-
-	/* Bring up all the required GPIOs and Clocks */
-	rc = msm_camio_enable(dev);
-	if (rc < 0)
-		return rc;
-
-	extlen = sizeof(struct vfe_frame_extra);
-
-	extdata = kmalloc(extlen, GFP_ATOMIC);
-	if (!extdata) {
-		rc = -ENOMEM;
-		goto init_fail;
-	}
-
-	rc = msm_adsp_get("QCAMTASK", &qcam_mod, &vfe_7x_sync, NULL);
-	if (rc) {
-		rc = -EBUSY;
-		goto get_qcam_fail;
-	}
-
-	rc = msm_adsp_get("VFETASK", &vfe_mod, &vfe_7x_sync, NULL);
-	if (rc) {
-		rc = -EBUSY;
-		goto get_vfe_fail;
-	}
-
-	return 0;
-
-get_vfe_fail:
-	msm_adsp_put(qcam_mod);
-get_qcam_fail:
-	kfree(extdata);
-init_fail:
-	extlen = 0;
-	return rc;
-}
-
-static int vfe_7x_config_axi(int mode,
-	struct axidata *ad, struct axiout *ao)
-{
-	struct msm_pmem_region *regptr;
-	unsigned long *bptr;
-	int    cnt;
-
-	int rc = 0;
-
-	if (mode == OUTPUT_1 || mode == OUTPUT_1_AND_2) {
-		regptr = ad->region;
-
-		CDBG("bufnum1 = %d\n", ad->bufnum1);
-		if (mode == OUTPUT_1_AND_2) {
-			paddr_t_y = regptr->paddr + regptr->info.planar0_off;
-			paddr_t_cbcr = regptr->paddr +
-			regptr->info.planar1_off;
-		}
-
-		CDBG("config_axi1: O1, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
-			regptr->paddr, regptr->info.planar0_off,
-			regptr->info.planar1_off);
-
-		bptr = &ao->output1buffer1_y_phy;
-		for (cnt = 0; cnt < ad->bufnum1; cnt++) {
-			*bptr = regptr->paddr + regptr->info.planar0_off;
-			bptr++;
-			*bptr = regptr->paddr + regptr->info.planar1_off;
-
-			bptr++;
-			regptr++;
-		}
-
-		regptr--;
-		for (cnt = 0; cnt < (8 - ad->bufnum1); cnt++) {
-			*bptr = regptr->paddr + regptr->info.planar0_off;
-			bptr++;
-			*bptr = regptr->paddr + regptr->info.planar1_off;
-			bptr++;
-		}
-	}
-
-	if (mode == OUTPUT_2 || mode == OUTPUT_1_AND_2) {
-		regptr = &(ad->region[ad->bufnum1]);
-
-		CDBG("bufnum2 = %d\n", ad->bufnum2);
-		paddr_s_y = regptr->paddr +  regptr->info.planar0_off;
-		paddr_s_cbcr = regptr->paddr +  regptr->info.planar1_off;
-
-		CDBG("config_axi2: O2, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
-			regptr->paddr, regptr->info.planar0_off,
-			regptr->info.planar1_off);
-
-		bptr = &ao->output2buffer1_y_phy;
-		for (cnt = 0; cnt < ad->bufnum2; cnt++) {
-			*bptr = regptr->paddr + regptr->info.planar0_off;
-			bptr++;
-			*bptr = regptr->paddr + regptr->info.planar1_off;
-
-			bptr++;
-			regptr++;
-		}
-
-		regptr--;
-		for (cnt = 0; cnt < (8 - ad->bufnum2); cnt++) {
-			*bptr = regptr->paddr + regptr->info.planar0_off;
-			bptr++;
-			*bptr = regptr->paddr + regptr->info.planar1_off;
-			bptr++;
-		}
-	}
-
-	return rc;
-}
-
-static int vfe_7x_config(struct msm_vfe_cfg_cmd *cmd, void *data)
-{
-	struct msm_pmem_region *regptr;
-	unsigned char buf[256];
-
-	struct vfe_stats_ack sack;
-	struct axidata *axid;
-	uint32_t i;
-	uint32_t *_mode;
-
-	struct vfe_stats_we_cfg *scfg = NULL;
-	struct vfe_stats_af_cfg *sfcfg = NULL;
-
-	struct axiout *axio = NULL;
-	void   *cmd_data = NULL;
-	void   *cmd_data_alloc = NULL;
-	long rc = 0;
-	struct msm_vfe_command_7k *vfecmd;
-
-	vfecmd = kmalloc(sizeof(struct msm_vfe_command_7k), GFP_ATOMIC);
-	if (!vfecmd) {
-		pr_err("vfecmd alloc failed!\n");
-		return -ENOMEM;
-	}
-
-	if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
-	    cmd->cmd_type != CMD_STATS_BUF_RELEASE &&
-	    cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE) {
-		if (copy_from_user(vfecmd,
-				(void __user *)(cmd->value),
-				sizeof(struct msm_vfe_command_7k))) {
-			rc = -EFAULT;
-			goto config_failure;
-		}
-	}
-
-	switch (cmd->cmd_type) {
-	case CMD_STATS_AEC_AWB_ENABLE:
-	case CMD_STATS_AXI_CFG: {
-		axid = data;
-		if (!axid) {
-			rc = -EFAULT;
-			goto config_failure;
-		}
-
-		scfg =
-			kmalloc(sizeof(struct vfe_stats_we_cfg),
-				GFP_ATOMIC);
-		if (!scfg) {
-			rc = -ENOMEM;
-			goto config_failure;
-		}
-
-		if (copy_from_user(scfg,
-					(void __user *)(vfecmd->value),
-					vfecmd->length)) {
-
-			rc = -EFAULT;
-			goto config_done;
-		}
-
-		CDBG("STATS_ENABLE: bufnum = %d, enabling = %d\n",
-			axid->bufnum1, scfg->wb_expstatsenable);
-
-		if (axid->bufnum1 > 0) {
-			regptr = axid->region;
-
-			for (i = 0; i < axid->bufnum1; i++) {
-
-				CDBG("STATS_ENABLE, phy = 0x%lx\n",
-					regptr->paddr);
-
-				scfg->wb_expstatoutputbuffer[i] =
-					(void *)regptr->paddr;
-				regptr++;
-			}
-
-			cmd_data = scfg;
-
-		} else {
-			rc = -EINVAL;
-			goto config_done;
-		}
-	}
-		break;
-	case CMD_STATS_AF_ENABLE:
-	case CMD_STATS_AF_AXI_CFG: {
-		axid = data;
-		if (!axid) {
-			rc = -EFAULT;
-			goto config_failure;
-		}
-
-		sfcfg =
-			kmalloc(sizeof(struct vfe_stats_af_cfg),
-				GFP_ATOMIC);
-
-		if (!sfcfg) {
-			rc = -ENOMEM;
-			goto config_failure;
-		}
-
-		if (copy_from_user(sfcfg,
-					(void __user *)(vfecmd->value),
-					vfecmd->length)) {
-
-			rc = -EFAULT;
-			goto config_done;
-		}
-
-		CDBG("AF_ENABLE: bufnum = %d, enabling = %d\n",
-			axid->bufnum1, sfcfg->af_enable);
-
-		if (axid->bufnum1 > 0) {
-			regptr = &axid->region[0];
-
-			for (i = 0; i < axid->bufnum1; i++) {
-
-				CDBG("STATS_ENABLE, phy = 0x%lx\n",
-					regptr->paddr);
-
-				sfcfg->af_outbuf[i] =
-					(void *)regptr->paddr;
-
-				regptr++;
-			}
-
-			cmd_data = sfcfg;
-
-		} else {
-			rc = -EINVAL;
-			goto config_done;
-		}
-	}
-		break;
-	case CMD_FRAME_BUF_RELEASE: {
-		struct msm_frame *b;
-		unsigned long p;
-		struct vfe_outputack fack;
-		if (!data)  {
-			rc = -EFAULT;
-			goto config_failure;
-		}
-
-		b = (struct msm_frame *)(cmd->value);
-		p = *(unsigned long *)data;
-
-		fack.header = VFE_FRAME_ACK;
-
-		fack.output2newybufferaddress =
-			(void *)(p + b->planar0_off);
-
-		fack.output2newcbcrbufferaddress =
-			(void *)(p + b->planar1_off);
-
-		vfecmd->queue = QDSP_CMDQUEUE;
-		vfecmd->length = sizeof(struct vfe_outputack);
-		cmd_data = &fack;
-	}
-		break;
-	case CMD_SNAP_BUF_RELEASE:
-		break;
-	case CMD_STATS_BUF_RELEASE: {
-		CDBG("vfe_7x_config: CMD_STATS_BUF_RELEASE\n");
-		if (!data) {
-			rc = -EFAULT;
-			goto config_failure;
-		}
-
-		sack.header = STATS_WE_ACK;
-		sack.bufaddr = (void *)*(uint32_t *)data;
-
-		vfecmd->queue  = QDSP_CMDQUEUE;
-		vfecmd->length = sizeof(struct vfe_stats_ack);
-		cmd_data = &sack;
-	}
-		break;
-	case CMD_STATS_AF_BUF_RELEASE: {
-		CDBG("vfe_7x_config: CMD_STATS_AF_BUF_RELEASE\n");
-		if (!data) {
-			rc = -EFAULT;
-			goto config_failure;
-		}
-
-		sack.header = STATS_AF_ACK;
-		sack.bufaddr = (void *)*(uint32_t *)data;
-
-		vfecmd->queue  = QDSP_CMDQUEUE;
-		vfecmd->length = sizeof(struct vfe_stats_ack);
-		cmd_data = &sack;
-	}
-		break;
-	case CMD_GENERAL:
-	case CMD_STATS_DISABLE: {
-		if (vfecmd->length > 256) {
-			cmd_data_alloc =
-			cmd_data = kmalloc(vfecmd->length, GFP_ATOMIC);
-			if (!cmd_data) {
-				rc = -ENOMEM;
-				goto config_failure;
-			}
-		} else
-			cmd_data = buf;
-
-		if (copy_from_user(cmd_data,
-					(void __user *)(vfecmd->value),
-					vfecmd->length)) {
-
-			rc = -EFAULT;
-			goto config_done;
-		}
-
-		if (vfecmd->queue == QDSP_CMDQUEUE) {
-			switch (*(uint32_t *)cmd_data) {
-			case VFE_RESET_CMD:
-				msm_camio_vfe_blk_reset();
-				vfestopped = 0;
-				break;
-			case VFE_START_CMD:
-				_mode = (uint32_t *)cmd_data;
-				op_mode = *(++_mode);
-				if (op_mode & SNAPSHOT_MASK_MODE)
-					msm_camio_set_perf_lvl(S_CAPTURE);
-				else
-					msm_camio_set_perf_lvl(S_PREVIEW);
-				vfestopped = 0;
-				break;
-			case VFE_STOP_CMD:
-				vfestopped = 1;
-				goto config_send;
-
-			default:
-				break;
-			}
-		} /* QDSP_CMDQUEUE */
-	}
-		break;
-	case CMD_AXI_CFG_PREVIEW:
-	case CMD_RAW_PICT_AXI_CFG: {
-		axid = data;
-		if (!axid) {
-			rc = -EFAULT;
-			goto config_failure;
-		}
-
-		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			goto config_failure;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd->value),
-					sizeof(struct axiout))) {
-			rc = -EFAULT;
-			goto config_done;
-		}
-
-		vfe_7x_config_axi(OUTPUT_2, axid, axio);
-		cmd_data = axio;
-	}
-		break;
-	case CMD_AXI_CFG_SNAP: {
-		axid = data;
-		if (!axid) {
-			rc = -EFAULT;
-			goto config_failure;
-		}
-
-		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			goto config_failure;
-		}
-
-		if (copy_from_user(axio, (void __user *)(vfecmd->value),
-					sizeof(struct axiout))) {
-			rc = -EFAULT;
-			goto config_done;
-		}
-
-		vfe_7x_config_axi(OUTPUT_1_AND_2, axid, axio);
-
-		cmd_data = axio;
-	}
-		break;
-	default:
-		break;
-	}
-
-	if (vfestopped)
-		goto config_done;
-
-config_send:
-	CDBG("send adsp command = %d\n", *(uint32_t *)cmd_data);
-	rc = msm_adsp_write(vfe_mod, vfecmd->queue,
-				cmd_data, vfecmd->length);
-
-config_done:
-	kfree(cmd_data_alloc);
-
-config_failure:
-	kfree(scfg);
-	kfree(axio);
-	kfree(vfecmd);
-	return rc;
-}
-
-void msm_camvfe_fn_init(struct msm_camvfe_fn *fptr, void *data)
-{
-	mutex_init(&vfe_lock);
-	fptr->vfe_init    = vfe_7x_init;
-	fptr->vfe_enable  = vfe_7x_enable;
-	fptr->vfe_config  = vfe_7x_config;
-	fptr->vfe_disable = vfe_7x_disable;
-	fptr->vfe_release = vfe_7x_release;
-	vfe_syncdata = data;
-}
-
-void msm_camvpe_fn_init(struct msm_camvpe_fn *fptr, void *data)
-{
-	fptr->vpe_reg		= NULL;
-	fptr->send_frame_to_vpe	= NULL;
-	fptr->vpe_config	= NULL;
-	fptr->vpe_cfg_update	= NULL;
-	fptr->dis		= NULL;
-}
diff --git a/drivers/media/video/msm/vfe/msm_vfe7x27a.h b/drivers/media/video/msm/vfe/msm_vfe7x27a.h
deleted file mode 100644
index a488206..0000000
--- a/drivers/media/video/msm/vfe/msm_vfe7x27a.h
+++ /dev/null
@@ -1,300 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. 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 __MSM_VFE7X_H__
-#define __MSM_VFE7X_H__
-#include <media/msm_camera.h>
-#include <mach/camera.h>
-
-struct vfe_frame_extra {
-	uint32_t	bl_evencol:23;
-	uint32_t	rvd1:9;
-	uint32_t	bl_oddcol:23;
-	uint32_t	rvd2:9;
-
-	uint32_t	d_dbpc_stats_hot:16;
-	uint32_t	d_dbpc_stats_cold:16;
-
-	uint32_t	d_dbpc_stats_0_hot:10;
-	uint32_t	rvd3:6;
-	uint32_t	d_dbpc_stats_0_cold:10;
-	uint32_t	rvd4:6;
-	uint32_t	d_dbpc_stats_1_hot:10;
-	uint32_t	rvd5:6;
-	uint32_t	d_dbpc_stats_1_cold:10;
-	uint32_t	rvd6:6;
-
-	uint32_t	asf_max_edge;
-
-	uint32_t	e_y_wm_pm_stats_0:21;
-	uint32_t	rvd7:11;
-	uint32_t	e_y_wm_pm_stats_1_bl:8;
-	uint32_t	rvd8:8;
-	uint32_t	e_y_wm_pm_stats_1_nl:12;
-	uint32_t	rvd9:4;
-
-	uint32_t	e_cbcr_wm_pm_stats_0:21;
-	uint32_t	rvd10:11;
-	uint32_t	e_cbcr_wm_pm_stats_1_bl:8;
-	uint32_t	rvd11:8;
-	uint32_t	e_cbcr_wm_pm_stats_1_nl:12;
-	uint32_t	rvd12:4;
-
-	uint32_t	v_y_wm_pm_stats_0:21;
-	uint32_t	rvd13:11;
-	uint32_t	v_y_wm_pm_stats_1_bl:8;
-	uint32_t	rvd14:8;
-	uint32_t	v_y_wm_pm_stats_1_nl:12;
-	uint32_t	rvd15:4;
-
-	uint32_t	v_cbcr_wm_pm_stats_0:21;
-	uint32_t	rvd16:11;
-	uint32_t	v_cbcr_wm_pm_stats_1_bl:8;
-	uint32_t	rvd17:8;
-	uint32_t	v_cbcr_wm_pm_stats_1_nl:12;
-	uint32_t	rvd18:4;
-
-	uint32_t      frame_id;
-};
-
-struct vfe_endframe {
-	uint32_t      y_address;
-	uint32_t      cbcr_address;
-
-	struct vfe_frame_extra extra;
-} __packed;
-
-struct vfe_outputack {
-	uint32_t  header;
-	void      *output2newybufferaddress;
-	void      *output2newcbcrbufferaddress;
-} __packed;
-
-struct vfe_stats_ack {
-	uint32_t header;
-	/* MUST BE 64 bit ALIGNED */
-	void     *bufaddr;
-} __packed;
-
-/* AXI Output Config Command sent to DSP */
-struct axiout {
-	uint32_t            cmdheader:32;
-	int                 outputmode:3;
-	uint8_t             format:2;
-	uint32_t            /* reserved */ : 27;
-
-	/* AXI Output 1 Y Configuration, Part 1 */
-	uint32_t            out1yimageheight:12;
-	uint32_t            /* reserved */ : 4;
-	uint32_t            out1yimagewidthin64bitwords:10;
-	uint32_t            /* reserved */ : 6;
-
-	/* AXI Output 1 Y Configuration, Part 2 */
-	uint8_t             out1yburstlen:2;
-	uint32_t            out1ynumrows:12;
-	uint32_t            out1yrowincin64bitincs:12;
-	uint32_t            /* reserved */ : 6;
-
-	/* AXI Output 1 CbCr Configuration, Part 1 */
-	uint32_t            out1cbcrimageheight:12;
-	uint32_t            /* reserved */ : 4;
-	uint32_t            out1cbcrimagewidthin64bitwords:10;
-	uint32_t            /* reserved */ : 6;
-
-	/* AXI Output 1 CbCr Configuration, Part 2 */
-	uint8_t             out1cbcrburstlen:2;
-	uint32_t            out1cbcrnumrows:12;
-	uint32_t            out1cbcrrowincin64bitincs:12;
-	uint32_t            /* reserved */ : 6;
-
-	/* AXI Output 2 Y Configuration, Part 1 */
-	uint32_t            out2yimageheight:12;
-	uint32_t            /* reserved */ : 4;
-	uint32_t            out2yimagewidthin64bitwords:10;
-	uint32_t            /* reserved */ : 6;
-
-	/* AXI Output 2 Y Configuration, Part 2 */
-	uint8_t             out2yburstlen:2;
-	uint32_t            out2ynumrows:12;
-	uint32_t            out2yrowincin64bitincs:12;
-	uint32_t            /* reserved */ : 6;
-
-	/* AXI Output 2 CbCr Configuration, Part 1 */
-	uint32_t            out2cbcrimageheight:12;
-	uint32_t            /* reserved */ : 4;
-	uint32_t            out2cbcrimagewidtein64bitwords:10;
-	uint32_t            /* reserved */ : 6;
-
-	/* AXI Output 2 CbCr Configuration, Part 2 */
-	uint8_t             out2cbcrburstlen:2;
-	uint32_t            out2cbcrnumrows:12;
-	uint32_t            out2cbcrrowincin64bitincs:12;
-	uint32_t            /* reserved */ : 6;
-
-	/* Address configuration:
-	 * output1 phisycal address */
-	unsigned long   output1buffer1_y_phy;
-	unsigned long   output1buffer1_cbcr_phy;
-	unsigned long   output1buffer2_y_phy;
-	unsigned long   output1buffer2_cbcr_phy;
-	unsigned long   output1buffer3_y_phy;
-	unsigned long   output1buffer3_cbcr_phy;
-	unsigned long   output1buffer4_y_phy;
-	unsigned long   output1buffer4_cbcr_phy;
-	unsigned long   output1buffer5_y_phy;
-	unsigned long   output1buffer5_cbcr_phy;
-	unsigned long   output1buffer6_y_phy;
-	unsigned long   output1buffer6_cbcr_phy;
-	unsigned long   output1buffer7_y_phy;
-	unsigned long   output1buffer7_cbcr_phy;
-	unsigned long   output1buffer8_y_phy;
-	unsigned long   output1buffer8_cbcr_phy;
-
-	/* output2 phisycal address */
-	unsigned long   output2buffer1_y_phy;
-	unsigned long   output2buffer1_cbcr_phy;
-	unsigned long   output2buffer2_y_phy;
-	unsigned long   output2buffer2_cbcr_phy;
-	unsigned long   output2buffer3_y_phy;
-	unsigned long   output2buffer3_cbcr_phy;
-	unsigned long   output2buffer4_y_phy;
-	unsigned long   output2buffer4_cbcr_phy;
-	unsigned long   output2buffer5_y_phy;
-	unsigned long   output2buffer5_cbcr_phy;
-	unsigned long   output2buffer6_y_phy;
-	unsigned long   output2buffer6_cbcr_phy;
-	unsigned long   output2buffer7_y_phy;
-	unsigned long   output2buffer7_cbcr_phy;
-	unsigned long   output2buffer8_y_phy;
-	unsigned long   output2buffer8_cbcr_phy;
-} __packed;
-
-struct vfe_stats_we_cfg {
-	uint32_t       header;
-
-	/* White Balance/Exposure Statistic Selection */
-	uint8_t        wb_expstatsenable:1;
-	uint8_t        wb_expstatbuspriorityselection:1;
-	unsigned int   wb_expstatbuspriorityvalue:4;
-	unsigned int   /* reserved */ : 26;
-
-	/* White Balance/Exposure Statistic Configuration, Part 1 */
-	uint8_t        exposurestatregions:1;
-	uint8_t        exposurestatsubregions:1;
-	unsigned int   /* reserved */ : 14;
-
-	unsigned int   whitebalanceminimumy:8;
-	unsigned int   whitebalancemaximumy:8;
-
-	/* White Balance/Exposure Statistic Configuration, Part 2 */
-	uint8_t wb_expstatslopeofneutralregionline[
-		NUM_WB_EXP_NEUTRAL_REGION_LINES];
-
-	/* White Balance/Exposure Statistic Configuration, Part 3 */
-	unsigned int   wb_expstatcrinterceptofneutralregionline2:12;
-	unsigned int   /* reserved */ : 4;
-	unsigned int   wb_expstatcbinterceptofneutralreginnline1:12;
-	unsigned int    /* reserved */ : 4;
-
-	/* White Balance/Exposure Statistic Configuration, Part 4 */
-	unsigned int   wb_expstatcrinterceptofneutralregionline4:12;
-	unsigned int   /* reserved */ : 4;
-	unsigned int   wb_expstatcbinterceptofneutralregionline3:12;
-	unsigned int   /* reserved */ : 4;
-
-	/* White Balance/Exposure Statistic Output Buffer Header */
-	unsigned int   wb_expmetricheaderpattern:8;
-	unsigned int   /* reserved */ : 24;
-
-	/* White Balance/Exposure Statistic Output Buffers-MUST
-	* BE 64 bit ALIGNED */
-	void  *wb_expstatoutputbuffer[NUM_WB_EXP_STAT_OUTPUT_BUFFERS];
-} __packed;
-
-struct vfe_stats_af_cfg {
-	uint32_t header;
-
-	/* Autofocus Statistic Selection */
-	uint8_t       af_enable:1;
-	uint8_t       af_busprioritysel:1;
-	unsigned int  af_buspriorityval:4;
-	unsigned int  /* reserved */ : 26;
-
-	/* Autofocus Statistic Configuration, Part 1 */
-	unsigned int  af_singlewinvoffset:12;
-	unsigned int  /* reserved */ : 4;
-	unsigned int  af_singlewinhoffset:12;
-	unsigned int  /* reserved */ : 3;
-	uint8_t       af_winmode:1;
-
-	/* Autofocus Statistic Configuration, Part 2 */
-	unsigned int  af_singglewinvh:11;
-	unsigned int  /* reserved */ : 5;
-	unsigned int  af_singlewinhw:11;
-	unsigned int  /* reserved */ : 5;
-
-	/* Autofocus Statistic Configuration, Parts 3-6 */
-	uint8_t       af_multiwingrid[NUM_AUTOFOCUS_MULTI_WINDOW_GRIDS];
-
-	/* Autofocus Statistic Configuration, Part 7 */
-	signed int    af_metrichpfcoefa00:5;
-	signed int    af_metrichpfcoefa04:5;
-	unsigned int  af_metricmaxval:11;
-	uint8_t       af_metricsel:1;
-	unsigned int  /* reserved */ : 10;
-
-	/* Autofocus Statistic Configuration, Part 8 */
-	signed int    af_metrichpfcoefa20:5;
-	signed int    af_metrichpfcoefa21:5;
-	signed int    af_metrichpfcoefa22:5;
-	signed int    af_metrichpfcoefa23:5;
-	signed int    af_metrichpfcoefa24:5;
-	unsigned int  /* reserved */ : 7;
-
-	/* Autofocus Statistic Output Buffer Header */
-	unsigned int  af_metrichp:8;
-	unsigned int  /* reserved */ : 24;
-
-	/* Autofocus Statistic Output Buffers - MUST BE 64 bit ALIGNED!!! */
-	void *af_outbuf[NUM_AF_STAT_OUTPUT_BUFFERS];
-} __packed; /* VFE_StatsAutofocusConfigCmdType */
-
-struct msm_camera_frame_msg {
-	unsigned long   output_y_address;
-	unsigned long   output_cbcr_address;
-
-	unsigned int    blacklevelevenColumn:23;
-	uint16_t        reserved1:9;
-	unsigned int    blackleveloddColumn:23;
-	uint16_t        reserved2:9;
-
-	uint16_t        greendefectpixelcount:8;
-	uint16_t        reserved3:8;
-	uint16_t        redbluedefectpixelcount:8;
-	uint16_t        reserved4:8;
-} __packed;
-
-/* New one for 7k */
-struct msm_vfe_command_7k {
-	uint16_t queue;
-	uint16_t length;
-	void     *value;
-};
-
-struct stop_event {
-	wait_queue_head_t wait;
-	int state;
-	int timeout;
-};
-
-
-#endif /* __MSM_VFE7X_H__ */
diff --git a/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c b/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c
deleted file mode 100644
index 6440b8e..0000000
--- a/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c
+++ /dev/null
@@ -1,2479 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/msm_adsp.h>
-#include <linux/uaccess.h>
-#include <linux/fs.h>
-#include <linux/android_pmem.h>
-#include <linux/slab.h>
-#include <linux/pm_qos.h>
-#include <linux/delay.h>
-#include <linux/wait.h>
-#include <linux/module.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-#include <media/msm_isp.h>
-#include <mach/msm_adsp.h>
-#include <linux/clk.h>
-#include <mach/clk.h>
-#include <mach/camera.h>
-#include "msm_vfe7x27a_v4l2.h"
-#include "msm.h"
-
-/* ADSP Messages */
-#define MSG_RESET_ACK  0
-#define MSG_STOP_ACK  1
-#define MSG_SNAPSHOT  2
-#define MSG_ILLEGAL_COMMAND  3
-#define MSG_START_ACK  4
-#define MSG_UPDATE_ACK  5
-#define MSG_OUTPUT1  6
-#define MSG_OUTPUT2  7
-#define MSG_STATS_AF  8
-#define MSG_STATS_WE  9
-#define MSG_STATS_HISTOGRAM  10
-#define MSG_EPOCH1  11
-#define MSG_EPOCH2  12
-#define MSG_VFE_ERROR 13
-#define MSG_SYNC_TIMER1_DONE  14
-#define MSG_SYNC_TIMER2_DONE  15
-#define MSG_ASYNC_TIMER1_DONE  16
-#define MSG_ASYNC_TIMER2_DONE  17
-#define MSG_CAPTURE_COMPLETE  18
-#define MSG_TABLE_CMD_ACK  19
-#define MSG_EXP_TIMEOUT_ACK  20
-#define MSG_SOF  21
-#define MSG_OUTPUT_T  22
-#define MSG_OUTPUT_S  23
-
-#define VFE_ADSP_EVENT 0xFFFF
-#define SNAPSHOT_MASK_MODE 0x00000001
-#define MSM_AXI_QOS_PREVIEW	122000
-#define MSM_AXI_QOS_SNAPSHOT	192000
-
-
-#define QDSP_CMDQUEUE 25
-#define QDSP_SCALEQUEUE 26
-#define QDSP_TABLEQUEUE 27
-
-/* ADSP Scler queue Cmd IDs */
-#define VFE_SCALE_OUTPUT1_CONFIG  0
-#define VFE_SCALE_OUTPUT2_CONFIG  1
-#define VFE_SCALE_MAX  0xFFFFFFFF
-
-/* ADSP table queue Cmd IDs */
-#define VFE_AXI_INPUT_CONFIG  0
-#define VFE_AXI_OUTPUT_CONFIG  1
-#define VFE_RGB_GAMMA_CONFIG  2
-#define VFE_Y_GAMMA_CONFIG  3
-#define VFE_ROLL_OFF_CONFIG  4
-#define VFE_DEMOSAICv3_BPC_CFG  6
-#define VFE_DEMOSAICv3_ABF_CFG  7
-#define VFE_DEMOSAICv3_CFG  8
-#define VFE_MAX  0xFFFFFFFF
-
-/* ADSP cfg queue cmd IDs */
-#define VFE_RESET  0
-#define VFE_START  1
-#define VFE_STOP  2
-#define VFE_UPDATE  3
-#define VFE_CAMIF_CONFIG  4
-#define VFE_ACTIVE_REGION_CONFIG  5
-#define VFE_DEMOSAIC_CONFIG  6
-#define VFE_INPUT_FORMAT_CONFIG  7
-#define VFE_OUTPUT_CLAMP_CONFIG  8
-#define VFE_CHROMA_SUBSAMPLE_CONFIG  9
-#define VFE_BLACK_LEVEL_CONFIG  10
-#define VFE_WHITE_BALANCE_CONFIG  11
-#define VFE_COLOR_PROCESSING_CONFIG  12
-#define VFE_ADAPTIVE_FILTER_CONFIG  13
-#define VFE_FRAME_SKIP_CONFIG  14
-#define VFE_FOV_CROP  15
-#define VFE_STATS_AUTOFOCUS_CONFIG  16
-#define VFE_STATS_WB_EXP_CONFIG  17
-#define VFE_STATS_HISTOGRAM_CONFIG  18
-#define VFE_OUTPUT1_ACK  19
-#define VFE_OUTPUT2_ACK  20
-#define VFE_STATS_AUTOFOCUS_ACK  21
-#define VFE_STATS_WB_EXP_ACK  22
-#define VFE_EPOCH1_ACK  23
-#define VFE_EPOCH2_ACK  24
-#define VFE_UPDATE_CAMIF_FRAME_CONFIG  25
-#define VFE_SYNC_TIMER1_CONFIG  26
-#define VFE_SYNC_TIMER2_CONFIG  27
-#define VFE_ASYNC_TIMER1_START  28
-#define VFE_ASYNC_TIMER2_START  29
-#define VFE_STATS_AUTOFOCUS_UPDATE  30
-#define VFE_STATS_WB_EXP_UPDATE  31
-#define VFE_ROLL_OFF_UPDATE  33
-#define VFE_DEMOSAICv3_BPC_UPDATE  34
-#define VFE_TESTGEN_START  35
-#define VFE_STATS_MA  0xFFFFFFFF
-
-struct msg_id_map msgs_map[] = {
-	{MSG_RESET_ACK, MSG_ID_RESET_ACK},
-	{MSG_STOP_ACK, MSG_ID_STOP_ACK},
-	{MSG_SNAPSHOT, MSG_ID_SNAPSHOT_DONE},
-	{MSG_ILLEGAL_COMMAND, VFE_MAX},
-	{MSG_START_ACK, MSG_ID_START_ACK},
-	{MSG_UPDATE_ACK, MSG_ID_UPDATE_ACK},
-	{MSG_OUTPUT1, VFE_MAX},
-	{MSG_OUTPUT2, VFE_MAX},
-	{MSG_STATS_AF, MSG_ID_STATS_AF},
-	{MSG_STATS_WE, MSG_ID_STATS_AWB_AEC},
-	{MSG_STATS_HISTOGRAM, MSG_ID_STATS_IHIST},
-	{MSG_EPOCH1, MSG_ID_EPOCH1},
-	{MSG_EPOCH2, MSG_ID_EPOCH2},
-	{MSG_VFE_ERROR, MSG_ID_CAMIF_ERROR},
-	{MSG_SYNC_TIMER1_DONE, MSG_ID_SYNC_TIMER1_DONE},
-	{MSG_SYNC_TIMER2_DONE, MSG_ID_SYNC_TIMER2_DONE},
-	{MSG_ASYNC_TIMER1_DONE, MSG_ID_ASYNC_TIMER1_DONE},
-	{MSG_ASYNC_TIMER2_DONE, MSG_ID_ASYNC_TIMER2_DONE},
-	{MSG_CAPTURE_COMPLETE, MSG_CAPTURE_COMPLETE},
-	{MSG_TABLE_CMD_ACK, MSG_TABLE_CMD_ACK},
-	{MSG_EXP_TIMEOUT_ACK, MSG_EXP_TIMEOUT_ACK},
-	{MSG_SOF, MSG_ID_SOF_ACK},
-	{MSG_OUTPUT_T, MSG_ID_OUTPUT_T},
-	{MSG_OUTPUT_S, MSG_ID_OUTPUT_S},
-};
-
-struct cmd_id_map cmds_map[] = {
-	{VFE_CMD_DUMMY_0, VFE_MAX, VFE_MAX},
-	{VFE_CMD_SET_CLK, VFE_MAX, VFE_MAX},
-	{VFE_CMD_RESET, VFE_RESET, QDSP_CMDQUEUE,
-			"VFE_CMD_RESET", "VFE_RESET"},
-	{VFE_CMD_START, VFE_START, QDSP_CMDQUEUE,
-			"VFE_CMD_START", "VFE_START"},
-	{VFE_CMD_TEST_GEN_START, VFE_TESTGEN_START, QDSP_CMDQUEUE,
-		"VFE_CMD_TEST_GEN_START", "VFE_TESTGEN_START"},
-	{VFE_CMD_OPERATION_CFG, VFE_MAX , VFE_MAX},
-	{VFE_CMD_AXI_OUT_CFG, VFE_AXI_OUTPUT_CONFIG, QDSP_TABLEQUEUE,
-		"VFE_CMD_AXI_OUT_CFG", "VFE_AXI_OUTPUT_CONFIG"},
-	{VFE_CMD_CAMIF_CFG, VFE_CAMIF_CONFIG, QDSP_CMDQUEUE,
-			"VFE_CMD_CAMIF_CFG", "VFE_CAMIF_CONFIG"},
-	{VFE_CMD_AXI_INPUT_CFG, VFE_AXI_INPUT_CONFIG, QDSP_TABLEQUEUE,
-		"VFE_CMD_AXI_INPUT_CFG", "VFE_AXI_INPUT_CONFIG"},
-	{VFE_CMD_BLACK_LEVEL_CFG, VFE_BLACK_LEVEL_CONFIG, QDSP_CMDQUEUE,
-		"VFE_CMD_BLACK_LEVEL_CFG", "VFE_BLACK_LEVEL_CONFIG"},
-	{VFE_CMD_MESH_ROLL_OFF_CFG, VFE_ROLL_OFF_CONFIG, QDSP_TABLEQUEUE,
-		"VFE_CMD_MESH_ROLL_OFF_CFG", "VFE_ROLL_OFF_CONFIG"},
-	{VFE_CMD_DEMUX_CFG, VFE_INPUT_FORMAT_CONFIG, QDSP_CMDQUEUE,
-		"VFE_CMD_DEMUX_CFG", "VFE_INPUT_FORMAT_CONFIG"},
-	{VFE_CMD_FOV_CFG, VFE_FOV_CROP, QDSP_CMDQUEUE,
-		"VFE_CMD_FOV_CFG", "VFE_FOV_CROP"},
-	{VFE_CMD_MAIN_SCALER_CFG, VFE_MAX, VFE_MAX},
-	{VFE_CMD_WB_CFG, VFE_WHITE_BALANCE_CONFIG, QDSP_CMDQUEUE,
-		"VFE_CMD_WB_CFG", "VFE_WHITE_BALANCE_CONFIG"},
-	{VFE_CMD_COLOR_COR_CFG, VFE_MAX, VFE_MAX},
-	{VFE_CMD_RGB_G_CFG, VFE_RGB_GAMMA_CONFIG, QDSP_TABLEQUEUE,
-		"VFE_CMD_RGB_G_CFG", "VFE_RGB_GAMMA_CONFIG"},
-	{VFE_CMD_LA_CFG, VFE_MAX, VFE_MAX},
-	{VFE_CMD_CHROMA_EN_CFG, VFE_MAX, VFE_MAX},
-	{VFE_CMD_CHROMA_SUP_CFG, VFE_MAX, VFE_MAX},
-	{VFE_CMD_MCE_CFG, VFE_MAX, VFE_MAX},
-	{VFE_CMD_SK_ENHAN_CFG, VFE_MAX, VFE_MAX},
-	{VFE_CMD_ASF_CFG, VFE_ADAPTIVE_FILTER_CONFIG, QDSP_CMDQUEUE,
-		"VFE_CMD_ASF_CFG", "VFE_ADAPTIVE_FILTER_CONFIG"},
-	{VFE_CMD_S2Y_CFG, VFE_MAX, VFE_MAX},
-	{VFE_CMD_S2CbCr_CFG, VFE_MAX, VFE_MAX},
-	{VFE_CMD_CHROMA_SUBS_CFG, VFE_CHROMA_SUBSAMPLE_CONFIG, QDSP_CMDQUEUE,
-		"VFE_CMD_CHROMA_SUBS_CFG", "VFE_CHROMA_SUBSAMPLE_CONFIG"},
-	{VFE_CMD_OUT_CLAMP_CFG, VFE_OUTPUT_CLAMP_CONFIG, QDSP_CMDQUEUE,
-		"VFE_CMD_OUT_CLAMP_CFG", "VFE_OUTPUT_CLAMP_CONFIG"},
-	{VFE_CMD_FRAME_SKIP_CFG, VFE_FRAME_SKIP_CONFIG, QDSP_CMDQUEUE,
-		"VFE_CMD_FRAME_SKIP_CFG", "VFE_FRAME_SKIP_CONFIG"},
-	{VFE_CMD_DUMMY_1, VFE_MAX, VFE_MAX},
-	{VFE_CMD_DUMMY_2, VFE_MAX, VFE_MAX},
-	{VFE_CMD_DUMMY_3, VFE_MAX, VFE_MAX},
-	{VFE_CMD_UPDATE, VFE_UPDATE, QDSP_CMDQUEUE,
-		"VFE_CMD_UPDATE", "VFE_UPDATE"},
-	{VFE_CMD_BL_LVL_UPDATE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_DEMUX_UPDATE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_FOV_UPDATE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_MAIN_SCALER_UPDATE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_WB_UPDATE, VFE_WHITE_BALANCE_CONFIG, QDSP_CMDQUEUE,
-		"VFE_CMD_WB_UPDATE", "VFE_WHITE_BALANCE_CONFIG"},
-	{VFE_CMD_COLOR_COR_UPDATE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_RGB_G_UPDATE, VFE_RGB_GAMMA_CONFIG, QDSP_TABLEQUEUE,
-		"VFE_CMD_RGB_G_UPDATE", "VFE_RGB_GAMMA_CONFIG"},
-	{VFE_CMD_LA_UPDATE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_CHROMA_EN_UPDATE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_CHROMA_SUP_UPDATE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_MCE_UPDATE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_SK_ENHAN_UPDATE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_S2CbCr_UPDATE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_S2Y_UPDATE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_ASF_UPDATE, VFE_ADAPTIVE_FILTER_CONFIG, QDSP_CMDQUEUE,
-		"VFE_CMD_ASF_UPDATE", "VFE_ADAPTIVE_FILTER_CONFIG"},
-	{VFE_CMD_FRAME_SKIP_UPDATE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_CAMIF_FRAME_UPDATE, VFE_UPDATE_CAMIF_FRAME_CONFIG,
-		QDSP_CMDQUEUE, "VFE_CMD_CAMIF_FRAME_UPDATE",
-		"VFE_UPDATE_CAMIF_FRAME_CONFIG"},
-	{VFE_CMD_STATS_AF_UPDATE, VFE_STATS_AUTOFOCUS_UPDATE, QDSP_CMDQUEUE,
-		"VFE_CMD_STATS_AF_UPDATE", "VFE_STATS_AUTOFOCUS_UPDATE"},
-	{VFE_CMD_STATS_AE_UPDATE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_STATS_AWB_UPDATE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_STATS_RS_UPDATE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_STATS_CS_UPDATE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_STATS_SKIN_UPDATE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_STATS_IHIST_UPDATE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_DUMMY_4, VFE_MAX, VFE_MAX},
-	{VFE_CMD_EPOCH1_ACK, VFE_EPOCH1_ACK, QDSP_CMDQUEUE,
-			"VFE_CMD_EPOCH1_ACK", "VFE_EPOCH1_ACK"},
-	{VFE_CMD_EPOCH2_ACK, VFE_EPOCH2_ACK, QDSP_CMDQUEUE,
-			"VFE_CMD_EPOCH2_ACK", "VFE_EPOCH2_ACK"},
-	{VFE_CMD_START_RECORDING, VFE_MAX, VFE_MAX},
-	{VFE_CMD_STOP_RECORDING, VFE_MAX , VFE_MAX},
-	{VFE_CMD_DUMMY_5, VFE_MAX, VFE_MAX},
-	{VFE_CMD_DUMMY_6, VFE_MAX, VFE_MAX},
-	{VFE_CMD_CAPTURE, VFE_START, QDSP_CMDQUEUE,
-			"VFE_CMD_CAPTURE", "VFE_START"},
-	{VFE_CMD_DUMMY_7, VFE_MAX, VFE_MAX},
-	{VFE_CMD_STOP, VFE_STOP, QDSP_CMDQUEUE, "VFE_CMD_STOP", "VFE_STOP"},
-	{VFE_CMD_GET_HW_VERSION, VFE_MAX, VFE_MAX},
-	{VFE_CMD_GET_FRAME_SKIP_COUNTS, VFE_MAX, VFE_MAX},
-	{VFE_CMD_OUTPUT1_BUFFER_ENQ, VFE_MAX, VFE_MAX},
-	{VFE_CMD_OUTPUT2_BUFFER_ENQ, VFE_MAX, VFE_MAX},
-	{VFE_CMD_OUTPUT3_BUFFER_ENQ, VFE_MAX, VFE_MAX},
-	{VFE_CMD_JPEG_OUT_BUF_ENQ, VFE_MAX, VFE_MAX},
-	{VFE_CMD_RAW_OUT_BUF_ENQ, VFE_MAX, VFE_MAX},
-	{VFE_CMD_RAW_IN_BUF_ENQ, VFE_MAX, VFE_MAX},
-	{VFE_CMD_STATS_AF_ENQ, VFE_MAX, VFE_MAX},
-	{VFE_CMD_STATS_AE_ENQ, VFE_MAX, VFE_MAX},
-	{VFE_CMD_STATS_AWB_ENQ, VFE_MAX, VFE_MAX},
-	{VFE_CMD_STATS_RS_ENQ, VFE_MAX, VFE_MAX},
-	{VFE_CMD_STATS_CS_ENQ, VFE_MAX, VFE_MAX},
-	{VFE_CMD_STATS_SKIN_ENQ, VFE_MAX, VFE_MAX},
-	{VFE_CMD_STATS_IHIST_ENQ, VFE_MAX, VFE_MAX},
-	{VFE_CMD_DUMMY_8, VFE_MAX, VFE_MAX},
-	{VFE_CMD_JPEG_ENC_CFG, VFE_MAX, VFE_MAX},
-	{VFE_CMD_DUMMY_9, VFE_MAX, VFE_MAX},
-	{VFE_CMD_STATS_AF_START, VFE_STATS_AUTOFOCUS_CONFIG, QDSP_CMDQUEUE,
-		"VFE_CMD_STATS_AF_START", "VFE_STATS_AUTOFOCUS_CONFIG"},
-	{VFE_CMD_STATS_AF_STOP, VFE_STATS_AUTOFOCUS_CONFIG, QDSP_CMDQUEUE,
-		"VFE_CMD_STATS_AF_STOP", "VFE_STATS_AUTOFOCUS_CONFIG"},
-	{VFE_CMD_STATS_AE_START, VFE_MAX, VFE_MAX},
-	{VFE_CMD_STATS_AE_STOP, VFE_MAX, VFE_MAX},
-	{VFE_CMD_STATS_AWB_START, VFE_MAX, VFE_MAX},
-	{VFE_CMD_STATS_AWB_STOP, VFE_MAX, VFE_MAX},
-	{VFE_CMD_STATS_RS_START, VFE_MAX, VFE_MAX},
-	{VFE_CMD_STATS_RS_STOP, VFE_MAX, VFE_MAX},
-	{VFE_CMD_STATS_CS_START, VFE_MAX, VFE_MAX},
-	{VFE_CMD_STATS_CS_STOP, VFE_MAX, VFE_MAX},
-	{VFE_CMD_STATS_SKIN_START, VFE_MAX, VFE_MAX},
-	{VFE_CMD_STATS_SKIN_STOP, VFE_MAX, VFE_MAX},
-	{VFE_CMD_STATS_IHIST_START, VFE_STATS_HISTOGRAM_CONFIG, QDSP_CMDQUEUE,
-		"VFE_CMD_STATS_IHIST_START", "VFE_STATS_HISTOGRAM_CONFIG"},
-	{VFE_CMD_STATS_IHIST_STOP, VFE_MAX, VFE_MAX},
-	{VFE_CMD_DUMMY_10, VFE_MAX, VFE_MAX},
-	{VFE_CMD_SYNC_TIMER_SETTING, VFE_MAX, VFE_MAX},
-	{VFE_CMD_ASYNC_TIMER_SETTING, VFE_MAX, VFE_MAX},
-	{VFE_CMD_LIVESHOT, VFE_MAX, VFE_MAX},
-	{VFE_CMD_LA_SETUP, VFE_MAX, VFE_MAX},
-	{VFE_CMD_LINEARIZATION_CFG, VFE_MAX, VFE_MAX},
-	{VFE_CMD_DEMOSAICV3, VFE_DEMOSAICv3_CFG, QDSP_TABLEQUEUE,
-		"VFE_CMD_DEMOSAICV3", "VFE_DEMOSAICv3_CFG"},
-	{VFE_CMD_DEMOSAICV3_ABCC_CFG, VFE_MAX, VFE_MAX},
-	{VFE_CMD_DEMOSAICV3_DBCC_CFG, VFE_MAX, VFE_MAX},
-	{VFE_CMD_DEMOSAICV3_DBPC_CFG, VFE_DEMOSAICv3_BPC_CFG, QDSP_TABLEQUEUE,
-		"VFE_CMD_DEMOSAICV3_DBPC_CFG", "VFE_DEMOSAICv3_BPC_CFG"},
-	{VFE_CMD_DEMOSAICV3_ABF_CFG, VFE_DEMOSAICv3_ABF_CFG, QDSP_TABLEQUEUE,
-		"VFE_CMD_DEMOSAICV3_ABF_CFG", "VFE_DEMOSAICv3_ABF_CFG"},
-	{VFE_CMD_DEMOSAICV3_ABCC_UPDATE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_DEMOSAICV3_DBCC_UPDATE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_DEMOSAICV3_DBPC_UPDATE, VFE_DEMOSAICv3_BPC_UPDATE,
-		QDSP_CMDQUEUE, "VFE_CMD_DEMOSAICV3_DBPC_UPDATE",
-		"VFE_DEMOSAICv3_BPC_UPDATE"},
-	{VFE_CMD_XBAR_CFG, VFE_MAX, VFE_MAX},
-	{VFE_CMD_MODULE_CFG, VFE_MAX, VFE_MAX},
-	{VFE_CMD_ZSL, VFE_START, QDSP_CMDQUEUE,
-			"VFE_CMD_ZSL", "VFE_START"},
-	{VFE_CMD_LINEARIZATION_UPDATE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_DEMOSAICV3_ABF_UPDATE, VFE_DEMOSAICv3_ABF_CFG,
-		QDSP_TABLEQUEUE, "VFE_CMD_DEMOSAICV3_ABF_UPDATE",
-		"VFE_DEMOSAICv3_ABF_CFG"},
-	{VFE_CMD_CLF_CFG, VFE_MAX, VFE_MAX},
-	{VFE_CMD_CLF_LUMA_UPDATE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_CLF_CHROMA_UPDATE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_PCA_ROLL_OFF_CFG, VFE_MAX, VFE_MAX},
-	{VFE_CMD_PCA_ROLL_OFF_UPDATE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_GET_REG_DUMP, VFE_MAX, VFE_MAX},
-	{VFE_CMD_GET_LINEARIZATON_TABLE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_GET_MESH_ROLLOFF_TABLE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_GET_PCA_ROLLOFF_TABLE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_GET_RGB_G_TABLE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_GET_LA_TABLE, VFE_MAX, VFE_MAX},
-	{VFE_CMD_DEMOSAICV3_UPDATE, VFE_DEMOSAICv3_CFG, QDSP_TABLEQUEUE,
-		"VFE_CMD_DEMOSAICV3_UPDATE", "VFE_DEMOSAICv3_CFG"},
-	{VFE_CMD_ACTIVE_REGION_CFG, VFE_ACTIVE_REGION_CONFIG, QDSP_CMDQUEUE,
-		"VFE_CMD_ACTIVE_REGION_CFG", "VFE_ACTIVE_REGION_CONFIG"},
-	{VFE_CMD_COLOR_PROCESSING_CONFIG, VFE_COLOR_PROCESSING_CONFIG,
-		QDSP_CMDQUEUE, "VFE_CMD_COLOR_PROCESSING_CONFIG",
-		"VFE_COLOR_PROCESSING_CONFIG"},
-	{VFE_CMD_STATS_WB_AEC_CONFIG, VFE_STATS_WB_EXP_CONFIG, QDSP_CMDQUEUE,
-		"VFE_CMD_STATS_WB_AEC_CONFIG", "VFE_STATS_WB_EXP_CONFIG"},
-	{VFE_CMD_STATS_WB_AEC_UPDATE, VFE_STATS_WB_EXP_UPDATE, QDSP_CMDQUEUE,
-		"VFE_CMD_STATS_WB_AEC_UPDATE", "VFE_STATS_WB_EXP_UPDATE"},
-	{VFE_CMD_Y_GAMMA_CONFIG, VFE_Y_GAMMA_CONFIG, QDSP_TABLEQUEUE,
-		"VFE_CMD_Y_GAMMA_CONFIG", "VFE_Y_GAMMA_CONFIG"},
-	{VFE_CMD_SCALE_OUTPUT1_CONFIG, VFE_SCALE_OUTPUT1_CONFIG,
-		QDSP_SCALEQUEUE, "VFE_CMD_SCALE_OUTPUT1_CONFIG",
-		"VFE_SCALE_OUTPUT1_CONFIG"},
-	{VFE_CMD_SCALE_OUTPUT2_CONFIG, VFE_SCALE_OUTPUT2_CONFIG,
-		QDSP_SCALEQUEUE, "VFE_CMD_SCALE_OUTPUT2_CONFIG",
-		"VFE_SCALE_OUTPUT2_CONFIG"},
-	{VFE_CMD_CAPTURE_RAW, VFE_START, QDSP_CMDQUEUE,
-			"VFE_CMD_CAPTURE_RAW", "VFE_START"},
-	{VFE_CMD_STOP_LIVESHOT, VFE_MAX, VFE_MAX},
-	{VFE_CMD_RECONFIG_VFE, VFE_MAX, VFE_MAX},
-};
-
-
-static struct msm_adsp_module *qcam_mod;
-static struct msm_adsp_module *vfe_mod;
-static void *extdata;
-static uint32_t extlen;
-
-struct mutex vfe_lock;
-static uint8_t vfestopped;
-
-static struct stop_event stopevent;
-
-static uint32_t op_mode;
-static uint32_t raw_mode;
-static struct vfe2x_ctrl_type *vfe2x_ctrl;
-
-static unsigned long vfe2x_stats_dqbuf(enum msm_stats_enum_type stats_type)
-{
-	struct msm_stats_meta_buf *buf = NULL;
-	int rc = 0;
-
-	rc = vfe2x_ctrl->stats_ops.dqbuf(vfe2x_ctrl->stats_ops.stats_ctrl,
-							  stats_type, &buf);
-	if (rc < 0) {
-		CDBG("%s: dq stats buf (type = %d) err = %d",
-			   __func__, stats_type, rc);
-		return 0;
-	}
-	return buf->paddr;
-}
-
-static unsigned long vfe2x_stats_flush_enqueue(
-	enum msm_stats_enum_type stats_type)
-{
-	struct msm_stats_bufq *bufq = NULL;
-	struct msm_stats_meta_buf *stats_buf = NULL;
-	int rc = 0;
-	int i;
-
-	/*
-	 * Passing NULL for ion client as the buffers are already
-	 * mapped at this stage, client is not required, flush all
-	 * the buffers, and buffers move to PREPARE state
-	 */
-	rc = vfe2x_ctrl->stats_ops.bufq_flush(
-			vfe2x_ctrl->stats_ops.stats_ctrl,
-			stats_type, NULL);
-	if (rc < 0) {
-		pr_err("%s: dq stats buf (type = %d) err = %d",
-			 __func__, stats_type, rc);
-		return 0L;
-	}
-
-	/* Queue all the buffers back to QUEUED state */
-	bufq = vfe2x_ctrl->stats_ctrl.bufq[stats_type];
-	for (i = 0; i < bufq->num_bufs; i++) {
-		stats_buf = &bufq->bufs[i];
-		rc = vfe2x_ctrl->stats_ops.enqueue_buf(
-				vfe2x_ctrl->stats_ops.stats_ctrl,
-				&(stats_buf->info), NULL, -1);
-			if (rc < 0) {
-				pr_err("%s: dq stats buf (type = %d) err = %d",
-					 __func__, stats_type, rc);
-				return rc;
-			}
-	}
-	return 0L;
-}
-
-static unsigned long vfe2x_stats_unregbuf(
-	struct msm_stats_reqbuf *req_buf)
-{
-	int i = 0, rc = 0;
-
-	for (i = 0; i < req_buf->num_buf; i++) {
-		rc = vfe2x_ctrl->stats_ops.buf_unprepare(
-			vfe2x_ctrl->stats_ops.stats_ctrl,
-			req_buf->stats_type, i,
-			vfe2x_ctrl->stats_ops.client, -1);
-		if (rc < 0) {
-			pr_err("%s: unreg stats buf (type = %d) err = %d",
-				__func__, req_buf->stats_type, rc);
-		return rc;
-		}
-	}
-	return 0L;
-}
-
-static int vfe2x_stats_buf_init(enum msm_stats_enum_type type)
-{
-	unsigned long flags;
-	int i = 0, rc = 0;
-	if (type == MSM_STATS_TYPE_AF) {
-		spin_lock_irqsave(&vfe2x_ctrl->stats_bufq_lock, flags);
-		rc = vfe2x_stats_flush_enqueue(MSM_STATS_TYPE_AF);
-		if (rc < 0) {
-			pr_err("%s: dq stats buf err = %d",
-				 __func__, rc);
-			spin_unlock_irqrestore(&vfe2x_ctrl->stats_bufq_lock,
-				flags);
-			return -EINVAL;
-		}
-		spin_unlock_irqrestore(&vfe2x_ctrl->stats_bufq_lock, flags);
-	}
-	for (i = 0; i < 3; i++) {
-		spin_lock_irqsave(&vfe2x_ctrl->stats_bufq_lock, flags);
-		if (type == MSM_STATS_TYPE_AE_AW)
-			vfe2x_ctrl->stats_we_buf_ptr[i] =
-				vfe2x_stats_dqbuf(type);
-		else
-			vfe2x_ctrl->stats_af_buf_ptr[i] =
-				vfe2x_stats_dqbuf(type);
-		spin_unlock_irqrestore(&vfe2x_ctrl->stats_bufq_lock, flags);
-		if (!vfe2x_ctrl->stats_we_buf_ptr[i]) {
-			pr_err("%s: dq error type %d ", __func__, type);
-			return -ENOMEM;
-		}
-	}
-	return rc;
-}
-
-static unsigned long vfe2x_stats_enqueuebuf(
-	struct msm_stats_buf_info *info, struct vfe_stats_ack *sack)
-{
-	struct msm_stats_bufq *bufq = NULL;
-	struct msm_stats_meta_buf *stats_buf = NULL;
-	struct msm_stats_meta_buf *buf = NULL;
-	int rc = 0;
-
-	bufq = vfe2x_ctrl->stats_ctrl.bufq[info->type];
-	stats_buf = &bufq->bufs[info->buf_idx];
-
-	CDBG("vfe2x_stats_enqueuebuf: %d\n", stats_buf->state);
-	if (stats_buf->state == MSM_STATS_BUFFER_STATE_INITIALIZED ||
-		stats_buf->state == MSM_STATS_BUFFER_STATE_PREPARED) {
-		rc = vfe2x_ctrl->stats_ops.enqueue_buf(
-				&vfe2x_ctrl->stats_ctrl,
-				info, vfe2x_ctrl->stats_ops.client, -1);
-		if (rc < 0) {
-			pr_err("%s: enqueue_buf (type = %d), index : %d, err = %d",
-				 __func__, info->type, info->buf_idx, rc);
-			return rc;
-		}
-
-	} else {
-		rc = vfe2x_ctrl->stats_ops.querybuf(
-				vfe2x_ctrl->stats_ops.stats_ctrl, info, &buf);
-		if (rc < 0) {
-			pr_err("%s: querybuf (type = %d), index : %d, err = %d",
-				__func__, info->type, info->buf_idx, rc);
-			return rc;
-	}
-		stats_buf->state = MSM_STATS_BUFFER_STATE_DEQUEUED;
-	if (info->type == MSM_STATS_TYPE_AE_AW) {
-		sack->header = VFE_STATS_WB_EXP_ACK;
-		sack->bufaddr = (void *)(uint32_t *)buf->paddr;
-	} else if (info->type == MSM_STATS_TYPE_AF) {
-		sack->header = VFE_STATS_AUTOFOCUS_ACK;
-		sack->bufaddr = (void *)(uint32_t *)buf->paddr;
-	} else
-		pr_err("%s: Invalid stats: should never come here\n", __func__);
-	}
-	return 0L;
-}
-
-static long vfe2x_stats_bufq_sub_ioctl(struct msm_vfe_cfg_cmd *cmd,
-	void *ion_client)
-{
-	long rc = 0;
-
-	switch (cmd->cmd_type) {
-	case VFE_CMD_STATS_REQBUF:
-		if (!vfe2x_ctrl->stats_ops.stats_ctrl) {
-			/* stats_ctrl has not been init yet */
-			rc = msm_stats_buf_ops_init(
-					&vfe2x_ctrl->stats_ctrl,
-					(struct ion_client *)ion_client,
-					&vfe2x_ctrl->stats_ops);
-			if (rc < 0) {
-				pr_err("%s: cannot init stats ops", __func__);
-				goto end;
-			}
-			rc = vfe2x_ctrl->stats_ops.stats_ctrl_init(
-					&vfe2x_ctrl->stats_ctrl);
-			if (rc < 0) {
-				pr_err("%s: cannot init stats_ctrl ops",
-					 __func__);
-				memset(&vfe2x_ctrl->stats_ops, 0,
-				sizeof(vfe2x_ctrl->stats_ops));
-				goto end;
-			}
-			if (sizeof(struct msm_stats_reqbuf) != cmd->length) {
-				/* error. the length not match */
-				pr_err("%s: stats reqbuf input size = %d,\n"
-					"struct size = %d, mismatch\n",
-					__func__, cmd->length,
-					sizeof(struct msm_stats_reqbuf));
-				rc = -EINVAL;
-				goto end;
-			}
-		}
-		rc = vfe2x_ctrl->stats_ops.reqbuf(
-				&vfe2x_ctrl->stats_ctrl,
-				(struct msm_stats_reqbuf *)cmd->value,
-				vfe2x_ctrl->stats_ops.client);
-		break;
-		case VFE_CMD_STATS_ENQUEUEBUF: {
-			if (sizeof(struct msm_stats_buf_info) != cmd->length) {
-				/* error. the length not match */
-				pr_err("%s: stats enqueuebuf input size = %d,\n"
-					"struct size = %d, mismatch\n",
-					 __func__, cmd->length,
-					sizeof(struct msm_stats_buf_info));
-				rc = -EINVAL;
-				goto end;
-		}
-		rc = vfe2x_ctrl->stats_ops.enqueue_buf(
-				&vfe2x_ctrl->stats_ctrl,
-				(struct msm_stats_buf_info *)cmd->value,
-				vfe2x_ctrl->stats_ops.client, -1);
-	}
-	break;
-	case VFE_CMD_STATS_FLUSH_BUFQ: {
-		struct msm_stats_flush_bufq *flush_req = NULL;
-		flush_req = (struct msm_stats_flush_bufq *)cmd->value;
-		if (sizeof(struct msm_stats_flush_bufq) != cmd->length) {
-			/* error. the length not match */
-			pr_err("%s: stats flush queue input size = %d,\n"
-				"struct size = %d, mismatch\n",
-				__func__, cmd->length,
-				sizeof(struct msm_stats_flush_bufq));
-				rc = -EINVAL;
-				goto end;
-		}
-		rc = vfe2x_ctrl->stats_ops.bufq_flush(
-				&vfe2x_ctrl->stats_ctrl,
-				(enum msm_stats_enum_type)flush_req->stats_type,
-				vfe2x_ctrl->stats_ops.client);
-	}
-	break;
-	case VFE_CMD_STATS_UNREGBUF:
-	{
-		struct msm_stats_reqbuf *req_buf = NULL;
-		req_buf = (struct msm_stats_reqbuf *)cmd->value;
-		if (sizeof(struct msm_stats_reqbuf) != cmd->length) {
-			/* error. the length not match */
-			pr_err("%s: stats reqbuf input size = %d,\n"
-				"struct size = %d, mitch match\n",
-				 __func__, cmd->length,
-				sizeof(struct msm_stats_reqbuf));
-			rc = -EINVAL ;
-			goto end;
-		}
-		rc = vfe2x_stats_unregbuf(req_buf);
-	}
-	break;
-	default:
-		rc = -1;
-		pr_err("%s: cmd_type %d not supported",
-			 __func__, cmd->cmd_type);
-	break;
-	}
-end:
-	return rc;
-}
-
-static void vfe2x_send_isp_msg(
-	struct vfe2x_ctrl_type *vctrl,
-	uint32_t isp_msg_id)
-{
-	struct isp_msg_event isp_msg_evt;
-
-	isp_msg_evt.msg_id = isp_msg_id;
-	isp_msg_evt.sof_count = vfe2x_ctrl->vfeFrameId;
-	v4l2_subdev_notify(&vctrl->subdev,
-			NOTIFY_ISP_MSG_EVT,
-			(void *)&isp_msg_evt);
-}
-
-static void vfe_send_outmsg(struct v4l2_subdev *sd, uint8_t msgid,
-		uint32_t ch0_paddr, uint32_t ch1_paddr)
-{
-	struct isp_msg_output msg;
-
-	msg.output_id = msgid;
-	msg.buf.inst_handle = 0;
-	msg.buf.ch_paddr[0]     = ch0_paddr;
-	msg.buf.ch_paddr[1]     = ch1_paddr;
-	msg.frameCounter = vfe2x_ctrl->vfeFrameId;
-
-	v4l2_subdev_notify(&vfe2x_ctrl->subdev,
-			NOTIFY_VFE_MSG_OUT,
-			&msg);
-	return;
-}
-
-static void vfe_send_stats_msg(uint32_t buf_addr, uint32_t msg_id)
-{
-	struct isp_msg_stats msg_stats;
-	void *vaddr = NULL;
-	int rc;
-
-	msg_stats.frameCounter = vfe2x_ctrl->vfeFrameId;
-	msg_stats.buffer       = buf_addr;
-	msg_stats.id           = msg_id;
-
-	if (MSG_ID_STATS_AWB_AEC == msg_id)
-		rc = vfe2x_ctrl->stats_ops.dispatch(
-			vfe2x_ctrl->stats_ops.stats_ctrl,
-			MSM_STATS_TYPE_AE_AW, buf_addr,
-			&msg_stats.buf_idx, &vaddr, &msg_stats.fd,
-			vfe2x_ctrl->stats_ops.client);
-	else if (MSG_ID_STATS_AF == msg_id)
-		rc = vfe2x_ctrl->stats_ops.dispatch(
-			vfe2x_ctrl->stats_ops.stats_ctrl,
-			MSM_STATS_TYPE_AF, buf_addr,
-			&msg_stats.buf_idx, &vaddr, &msg_stats.fd,
-			vfe2x_ctrl->stats_ops.client);
-
-	v4l2_subdev_notify(&vfe2x_ctrl->subdev,
-				NOTIFY_VFE_MSG_STATS,
-				&msg_stats);
-}
-
-static void vfe_7x_ops(void *driver_data, unsigned id, size_t len,
-		void (*getevent)(void *ptr, size_t len))
-{
-	uint32_t evt_buf[3];
-	void *data = NULL;
-	struct buf_info *outch = NULL;
-	uint32_t y_phy, cbcr_phy;
-	static uint32_t liveshot_y_phy;
-	static struct vfe_endframe liveshot_swap;
-	struct table_cmd *table_pending = NULL;
-	unsigned long flags;
-	void   *cmd_data = NULL;
-	unsigned char buf[256];
-	struct msm_free_buf *free_buf = NULL;
-	struct vfe_outputack fack;
-	int i;
-
-	CDBG("%s:id=%d\n", __func__, id);
-	if (id != VFE_ADSP_EVENT) {
-		data = kzalloc(len, GFP_ATOMIC);
-		if (!data) {
-			pr_err("%s: rp: cannot allocate buffer\n", __func__);
-			return;
-		}
-	}
-	if (id == VFE_ADSP_EVENT) {
-		/* event */
-		getevent(evt_buf, sizeof(evt_buf));
-		CDBG("%s:event:msg_id=%d\n", __func__, id);
-	} else {
-		/* messages */
-		getevent(data, len);
-		CDBG("%s:messages:msg_id=%d\n", __func__, id);
-
-		switch (id) {
-		case MSG_SNAPSHOT:
-			while (vfe2x_ctrl->snap.frame_cnt <
-				vfe2x_ctrl->num_snap) {
-				vfe_7x_ops(driver_data, MSG_OUTPUT_S, len,
-					getevent);
-				if (!raw_mode)
-					vfe_7x_ops(driver_data, MSG_OUTPUT_T,
-						len, getevent);
-			}
-			vfe2x_send_isp_msg(vfe2x_ctrl, MSG_ID_SNAPSHOT_DONE);
-			kfree(data);
-			return;
-		case MSG_OUTPUT_S:
-			outch = &vfe2x_ctrl->snap;
-			if (outch->frame_cnt == 0) {
-				y_phy = outch->ping.ch_paddr[0];
-				cbcr_phy = outch->ping.ch_paddr[1];
-			} else if (outch->frame_cnt == 1) {
-				y_phy = outch->pong.ch_paddr[0];
-				cbcr_phy = outch->pong.ch_paddr[1];
-			} else if (outch->frame_cnt == 2) {
-				y_phy = outch->free_buf.ch_paddr[0];
-				cbcr_phy = outch->free_buf.ch_paddr[1];
-			} else {
-				y_phy = outch->free_buf_arr[outch->frame_cnt
-					- 3].ch_paddr[0];
-				cbcr_phy = outch->free_buf_arr[outch->frame_cnt
-					- 3].ch_paddr[1];
-			}
-			outch->frame_cnt++;
-			CDBG("MSG_OUTPUT_S: %x %x %d\n",
-				(unsigned int)y_phy, (unsigned int)cbcr_phy,
-					outch->frame_cnt);
-			vfe_send_outmsg(&vfe2x_ctrl->subdev,
-					MSG_ID_OUTPUT_PRIMARY,
-						y_phy, cbcr_phy);
-			break;
-		case MSG_OUTPUT_T:
-			outch = &vfe2x_ctrl->thumb;
-			if (outch->frame_cnt == 0) {
-				y_phy = outch->ping.ch_paddr[0];
-				cbcr_phy = outch->ping.ch_paddr[1];
-			} else if (outch->frame_cnt == 1) {
-				y_phy = outch->pong.ch_paddr[0];
-				cbcr_phy = outch->pong.ch_paddr[1];
-			} else if (outch->frame_cnt == 2) {
-				y_phy = outch->free_buf.ch_paddr[0];
-				cbcr_phy = outch->free_buf.ch_paddr[1];
-			} else {
-				y_phy = outch->free_buf_arr[outch->frame_cnt
-					- 3].ch_paddr[0];
-				cbcr_phy = outch->free_buf_arr[outch->frame_cnt
-					- 3].ch_paddr[1];
-			}
-			outch->frame_cnt++;
-			CDBG("MSG_OUTPUT_T: %x %x %d\n",
-				(unsigned int)y_phy, (unsigned int)cbcr_phy,
-				outch->frame_cnt);
-			vfe_send_outmsg(&vfe2x_ctrl->subdev,
-						MSG_ID_OUTPUT_SECONDARY,
-							y_phy, cbcr_phy);
-			break;
-		case MSG_OUTPUT1:
-			if (op_mode & SNAPSHOT_MASK_MODE) {
-				kfree(data);
-				return;
-			} else {
-				free_buf = vfe2x_check_free_buffer(
-							VFE_MSG_OUTPUT_IRQ,
-							VFE_MSG_OUTPUT_SECONDARY
-							);
-				CDBG("free_buf = %x\n",
-						(unsigned int) free_buf);
-				if (free_buf) {
-					fack.header = VFE_OUTPUT1_ACK;
-
-					fack.output2newybufferaddress =
-						(void *)(free_buf->ch_paddr[0]);
-
-					fack.output2newcbcrbufferaddress =
-						(void *)(free_buf->ch_paddr[1]);
-
-					cmd_data = &fack;
-					len = sizeof(fack);
-					msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
-							cmd_data, len);
-			      } else {
-					fack.header = VFE_OUTPUT1_ACK;
-					fack.output2newybufferaddress =
-					(void *)
-				((struct vfe_endframe *)data)->y_address;
-					fack.output2newcbcrbufferaddress =
-					(void *)
-				((struct vfe_endframe *)data)->cbcr_address;
-					cmd_data = &fack;
-					len = sizeof(fack);
-					msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
-						cmd_data, len);
-					if (!vfe2x_ctrl->zsl_mode) {
-						kfree(data);
-						return;
-					}
-				}
-			}
-			y_phy = ((struct vfe_endframe *)data)->y_address;
-			cbcr_phy = ((struct vfe_endframe *)data)->cbcr_address;
-
-
-			CDBG("vfe_7x_convert, y_phy = 0x%x, cbcr_phy = 0x%x\n",
-				 y_phy, cbcr_phy);
-			if (free_buf) {
-				for (i = 0; i < 3; i++) {
-					if (vfe2x_ctrl->free_buf.buf[i].
-							ch_paddr[0] == y_phy) {
-						vfe2x_ctrl->free_buf.
-							buf[i].ch_paddr[0] =
-							free_buf->ch_paddr[0];
-						vfe2x_ctrl->free_buf.
-							buf[i].ch_paddr[1] =
-							free_buf->ch_paddr[1];
-						break;
-					}
-				}
-				if (i == 3)
-					CDBG("Address doesnt match\n");
-			}
-			memcpy(((struct vfe_frame_extra *)extdata),
-				&((struct vfe_endframe *)data)->extra,
-				sizeof(struct vfe_frame_extra));
-
-			vfe2x_ctrl->vfeFrameId =
-				((struct vfe_frame_extra *)extdata)->frame_id;
-			vfe_send_outmsg(&vfe2x_ctrl->subdev,
-						MSG_ID_OUTPUT_SECONDARY,
-						y_phy, cbcr_phy);
-			break;
-		case MSG_OUTPUT2:
-			if (op_mode & SNAPSHOT_MASK_MODE) {
-				kfree(data);
-				return;
-			}
-			if (vfe2x_ctrl->liveshot_enabled)
-				free_buf = vfe2x_check_free_buffer(
-					VFE_MSG_OUTPUT_IRQ,
-					VFE_MSG_V2X_LIVESHOT_PRIMARY);
-			else
-				free_buf = vfe2x_check_free_buffer(
-					VFE_MSG_OUTPUT_IRQ,
-					VFE_MSG_OUTPUT_PRIMARY);
-			CDBG("free_buf = %x\n",
-					(unsigned int) free_buf);
-			spin_lock_irqsave(
-					&vfe2x_ctrl->liveshot_enabled_lock,
-					flags);
-			if (!vfe2x_ctrl->liveshot_enabled) {
-				spin_unlock_irqrestore(
-						&vfe2x_ctrl->
-						liveshot_enabled_lock,
-						flags);
-				if (free_buf) {
-					fack.header = VFE_OUTPUT2_ACK;
-
-					fack.output2newybufferaddress =
-						(void *)
-						(free_buf->ch_paddr[0]);
-
-					fack.output2newcbcrbufferaddress =
-						(void *)
-						(free_buf->ch_paddr[1]);
-
-					cmd_data = &fack;
-					len = sizeof(fack);
-					msm_adsp_write(vfe_mod,
-							QDSP_CMDQUEUE,
-							cmd_data, len);
-				} else {
-					fack.header = VFE_OUTPUT2_ACK;
-					fack.output2newybufferaddress =
-						(void *)
-						((struct vfe_endframe *)
-						 data)->y_address;
-					fack.output2newcbcrbufferaddress =
-						(void *)
-						((struct vfe_endframe *)
-						 data)->cbcr_address;
-					cmd_data = &fack;
-					len = sizeof(fack);
-					msm_adsp_write(vfe_mod,
-							QDSP_CMDQUEUE,
-							cmd_data, len);
-					if (!vfe2x_ctrl->zsl_mode) {
-						kfree(data);
-						return;
-					}
-				}
-			} else { /* Live snapshot */
-				spin_unlock_irqrestore(
-						&vfe2x_ctrl->
-						liveshot_enabled_lock,
-						flags);
-				if (free_buf) {
-					/* liveshot_swap to enqueue
-					   when liveshot snapshot buffer
-					   is obtainedi from adsp */
-					liveshot_swap.y_address =
-						((struct vfe_endframe *)
-						 data)->y_address;
-					liveshot_swap.cbcr_address =
-						((struct vfe_endframe *)
-						 data)->cbcr_address;
-
-					fack.header = VFE_OUTPUT2_ACK;
-
-					fack.output2newybufferaddress =
-						(void *)
-						(free_buf->ch_paddr[0]);
-
-					fack.output2newcbcrbufferaddress =
-						(void *)
-						(free_buf->ch_paddr[1]);
-
-					liveshot_y_phy =
-						(uint32_t)
-						fack.output2newybufferaddress;
-
-					cmd_data = &fack;
-					len = sizeof(fack);
-					msm_adsp_write(vfe_mod,
-							QDSP_CMDQUEUE,
-							cmd_data, len);
-				} else if (liveshot_y_phy !=
-						((struct vfe_endframe *)
-						 data)->y_address) {
-
-					fack.header = VFE_OUTPUT2_ACK;
-					fack.output2newybufferaddress =
-						(void *)
-						((struct vfe_endframe *)
-						 data)->y_address;
-
-					fack.output2newcbcrbufferaddress =
-						(void *)
-						((struct vfe_endframe *)
-						 data)->cbcr_address;
-
-					cmd_data = &fack;
-					len = sizeof(fack);
-					msm_adsp_write(vfe_mod,
-							QDSP_CMDQUEUE,
-							cmd_data, len);
-					kfree(data);
-					return;
-				} else {
-					/* Enque data got
-					 * during freebuf */
-					fack.header = VFE_OUTPUT2_ACK;
-					fack.output2newybufferaddress =
-						(void *)
-						(liveshot_swap.y_address);
-
-					fack.output2newcbcrbufferaddress =
-						(void *)
-						(liveshot_swap.cbcr_address);
-					cmd_data = &fack;
-					len = sizeof(fack);
-					msm_adsp_write(vfe_mod,
-							QDSP_CMDQUEUE,
-							cmd_data, len);
-				}
-			}
-			y_phy = ((struct vfe_endframe *)data)->
-				y_address;
-			cbcr_phy = ((struct vfe_endframe *)data)->
-				cbcr_address;
-
-
-			CDBG("MSG_OUT2:y_phy= 0x%x, cbcr_phy= 0x%x\n",
-					y_phy, cbcr_phy);
-			if (free_buf) {
-				for (i = 0; i < 3; i++) {
-					if (vfe2x_ctrl->free_buf.buf[i].
-							ch_paddr[0] == y_phy) {
-						vfe2x_ctrl->free_buf.
-							buf[i].ch_paddr[0] =
-							free_buf->ch_paddr[0];
-						vfe2x_ctrl->free_buf.
-							buf[i].ch_paddr[1] =
-							free_buf->ch_paddr[1];
-						break;
-					}
-				}
-				if (i == 3)
-					CDBG("Address doesnt match\n");
-			}
-			memcpy(((struct vfe_frame_extra *)extdata),
-					&((struct vfe_endframe *)data)->extra,
-					sizeof(struct vfe_frame_extra));
-
-			vfe2x_ctrl->vfeFrameId =
-				((struct vfe_frame_extra *)extdata)->
-				frame_id;
-
-			if (!vfe2x_ctrl->liveshot_enabled) {
-				/* Liveshot not enalbed */
-				vfe_send_outmsg(&vfe2x_ctrl->subdev,
-						MSG_ID_OUTPUT_PRIMARY,
-						y_phy, cbcr_phy);
-			} else if (liveshot_y_phy == y_phy) {
-				vfe_send_outmsg(&vfe2x_ctrl->subdev,
-						MSG_ID_OUTPUT_PRIMARY,
-						y_phy, cbcr_phy);
-			}
-			break;
-		case MSG_RESET_ACK:
-		case MSG_START_ACK:
-		case MSG_UPDATE_ACK:
-		case MSG_VFE_ERROR:
-		case MSG_SYNC_TIMER1_DONE:
-		case MSG_SYNC_TIMER2_DONE:
-			vfe2x_send_isp_msg(vfe2x_ctrl, msgs_map[id].isp_id);
-			if (id == MSG_START_ACK)
-				vfe2x_ctrl->vfe_started = 1;
-			if (id == MSG_VFE_ERROR) {
-				uint16_t *ptr;
-				struct vfe_error_msg *VFE_ErrorMessageBuffer
-					= data;
-				ptr = data;
-				CDBG("Error: %x %x\n", ptr[0], ptr[1]);
-				CDBG("CAMIF_Error              = %d\n",
-					VFE_ErrorMessageBuffer->camif_error);
-				CDBG("output1YBusOverflow      = %d\n",
-					VFE_ErrorMessageBuffer->
-					output1ybusoverflow);
-				CDBG("output1CbCrBusOverflow   = %d\n",
-					VFE_ErrorMessageBuffer->
-					output1cbcrbusoverflow);
-				CDBG("output2YBusOverflow      = %d\n",
-					VFE_ErrorMessageBuffer->
-					output2ybusoverflow);
-				CDBG("output2CbCrBusOverflow   = %d\n",
-						VFE_ErrorMessageBuffer->
-						output2cbcrbusoverflow);
-				CDBG("autofocusStatBusOverflow = %d\n",
-						VFE_ErrorMessageBuffer->
-						autofocusstatbusoverflow);
-				CDBG("WB_EXPStatBusOverflow    = %d\n",
-						VFE_ErrorMessageBuffer->
-						wb_expstatbusoverflow);
-				CDBG("AXIError                 = %d\n",
-						VFE_ErrorMessageBuffer->
-						axierror);
-				CDBG("CAMIF_Staus              = %d\n",
-						VFE_ErrorMessageBuffer->
-						camif_staus);
-				CDBG("pixel_count              = %d\n",
-						VFE_ErrorMessageBuffer->
-						pixel_count);
-				CDBG("line_count               = %d\n",
-						VFE_ErrorMessageBuffer->
-						line_count);
-			}
-			break;
-		case MSG_SOF:
-			vfe2x_ctrl->vfeFrameId++;
-			if (vfe2x_ctrl->vfeFrameId == 0)
-				vfe2x_ctrl->vfeFrameId = 1; /* wrapped back */
-			if ((op_mode & SNAPSHOT_MASK_MODE) && !raw_mode
-				&& (vfe2x_ctrl->num_snap <= 1)) {
-				CDBG("Ignore SOF for snapshot\n");
-				kfree(data);
-				return;
-			}
-			vfe2x_send_isp_msg(vfe2x_ctrl, MSG_ID_SOF_ACK);
-			if (raw_mode)
-				vfe2x_send_isp_msg(vfe2x_ctrl,
-						MSG_ID_START_ACK);
-			break;
-		case MSG_STOP_ACK:
-			stopevent.state = 1;
-			vfe2x_ctrl->vfe_started = 0;
-			wake_up(&stopevent.wait);
-			vfe2x_send_isp_msg(vfe2x_ctrl, MSG_ID_STOP_ACK);
-			break;
-		case MSG_STATS_AF:
-		case MSG_STATS_WE:
-			vfe_send_stats_msg(*(uint32_t *)data,
-						msgs_map[id].isp_id);
-			break;
-		default:
-			if (MSG_TABLE_CMD_ACK != id)
-				vfe2x_send_isp_msg(vfe2x_ctrl,
-						msgs_map[id].isp_id);
-			break;
-		}
-	}
-	if (MSG_TABLE_CMD_ACK == id) {
-		spin_lock_irqsave(&vfe2x_ctrl->table_lock, flags);
-		vfe2x_ctrl->tableack_pending = 0;
-		if (list_empty(&vfe2x_ctrl->table_q)) {
-			if (vfe2x_ctrl->start_pending) {
-				CDBG("Send START\n");
-				cmd_data = buf;
-				*(uint32_t *)cmd_data = VFE_START;
-				memcpy(((char *)cmd_data) + 4,
-					&vfe2x_ctrl->start_cmd,
-					sizeof(vfe2x_ctrl->start_cmd));
-				/* Send Start cmd here */
-				len  = sizeof(vfe2x_ctrl->start_cmd) + 4;
-				msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
-						cmd_data, len);
-				vfe2x_ctrl->start_pending = 0;
-			} else if (vfe2x_ctrl->stop_pending) {
-				CDBG("Send STOP\n");
-				cmd_data = buf;
-				*(uint32_t *)cmd_data = VFE_STOP;
-				/* Send Stop cmd here */
-				len  = 4;
-				msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
-						cmd_data, len);
-				vfe2x_ctrl->stop_pending = 0;
-			} else if (vfe2x_ctrl->update_pending) {
-				CDBG("Send Update\n");
-				cmd_data = buf;
-				*(uint32_t *)cmd_data = VFE_UPDATE;
-				/* Send Update cmd here */
-				len  = 4;
-				msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
-						cmd_data, len);
-				vfe2x_ctrl->update_pending = 0;
-			}
-			spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
-			kfree(data);
-			return;
-		}
-		table_pending = list_first_entry(&vfe2x_ctrl->table_q,
-					struct table_cmd, list);
-		if (!table_pending) {
-			spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
-			kfree(data);
-			return;
-		}
-		msm_adsp_write(vfe_mod, table_pending->queue,
-				table_pending->cmd, table_pending->size);
-		list_del(&table_pending->list);
-		kfree(table_pending->cmd);
-		kfree(table_pending);
-		vfe2x_ctrl->tableack_pending = 1;
-		spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
-	} else if (!vfe2x_ctrl->tableack_pending) {
-		if (!list_empty(&vfe2x_ctrl->table_q)) {
-			kfree(data);
-			return;
-		}
-	}
-	kfree(data);
-}
-
-static struct msm_adsp_ops vfe_7x_sync = {
-	.event = vfe_7x_ops,
-};
-
-static int vfe_7x_config_axi(int mode,
-	struct buf_info *ad, struct axiout *ao)
-{
-	unsigned long *bptr;
-	int    cnt;
-	int rc = 0;
-	int o_mode = 0;
-	unsigned long flags;
-
-	if (op_mode & SNAPSHOT_MASK_MODE)
-		o_mode = SNAPSHOT_MASK_MODE;
-
-	if ((o_mode == SNAPSHOT_MASK_MODE) && (vfe2x_ctrl->num_snap > 1)) {
-		CDBG("%s: BURST mode freebuf cnt %d", __func__,
-			ad->free_buf_cnt);
-		/* Burst */
-		if (mode == OUTPUT_SEC) {
-			ao->output1buffer1_y_phy = ad->ping.ch_paddr[0];
-			ao->output1buffer1_cbcr_phy = ad->ping.ch_paddr[1];
-			ao->output1buffer2_y_phy = ad->pong.ch_paddr[0];
-			ao->output1buffer2_cbcr_phy = ad->pong.ch_paddr[1];
-			ao->output1buffer3_y_phy = ad->free_buf.ch_paddr[0];
-			ao->output1buffer3_cbcr_phy = ad->free_buf.ch_paddr[1];
-			bptr = &ao->output1buffer4_y_phy;
-			for (cnt = 0; cnt < 5; cnt++) {
-				*bptr = (cnt < ad->free_buf_cnt-3) ?
-					ad->free_buf_arr[cnt].ch_paddr[0] :
-						ad->pong.ch_paddr[0];
-				bptr++;
-				*bptr = (cnt < ad->free_buf_cnt-3) ?
-					ad->free_buf_arr[cnt].ch_paddr[1] :
-						ad->pong.ch_paddr[1];
-				bptr++;
-			}
-			CDBG("%x %x\n", (unsigned int)ao->output1buffer1_y_phy,
-				(unsigned int)ao->output1buffer1_cbcr_phy);
-			CDBG("%x %x\n", (unsigned int)ao->output1buffer2_y_phy,
-				(unsigned int)ao->output1buffer2_cbcr_phy);
-			CDBG("%x %x\n", (unsigned int)ao->output1buffer3_y_phy,
-				(unsigned int)ao->output1buffer3_cbcr_phy);
-			CDBG("%x %x\n", (unsigned int)ao->output1buffer4_y_phy,
-				(unsigned int)ao->output1buffer4_cbcr_phy);
-			CDBG("%x %x\n", (unsigned int)ao->output1buffer5_y_phy,
-				(unsigned int)ao->output1buffer5_cbcr_phy);
-			CDBG("%x %x\n", (unsigned int)ao->output1buffer6_y_phy,
-				(unsigned int)ao->output1buffer6_cbcr_phy);
-			CDBG("%x %x\n", (unsigned int)ao->output1buffer7_y_phy,
-				(unsigned int)ao->output1buffer7_cbcr_phy);
-		} else { /*Primary*/
-			ao->output2buffer1_y_phy = ad->ping.ch_paddr[0];
-			ao->output2buffer1_cbcr_phy = ad->ping.ch_paddr[1];
-			ao->output2buffer2_y_phy = ad->pong.ch_paddr[0];
-			ao->output2buffer2_cbcr_phy = ad->pong.ch_paddr[1];
-			ao->output2buffer3_y_phy = ad->free_buf.ch_paddr[0];
-			ao->output2buffer3_cbcr_phy = ad->free_buf.ch_paddr[1];
-			bptr = &ao->output2buffer4_y_phy;
-			for (cnt = 0; cnt < 5; cnt++) {
-				*bptr = (cnt < ad->free_buf_cnt-3) ?
-					ad->free_buf_arr[cnt].ch_paddr[0] :
-						ad->pong.ch_paddr[0];
-				bptr++;
-				*bptr = (cnt < ad->free_buf_cnt-3) ?
-					ad->free_buf_arr[cnt].ch_paddr[1] :
-						ad->pong.ch_paddr[1];
-				bptr++;
-			}
-			CDBG("%x %x\n", (unsigned int)ao->output2buffer1_y_phy,
-				(unsigned int)ao->output2buffer1_cbcr_phy);
-			CDBG("%x %x\n", (unsigned int)ao->output2buffer2_y_phy,
-				(unsigned int)ao->output2buffer2_cbcr_phy);
-			CDBG("%x %x\n", (unsigned int)ao->output2buffer3_y_phy,
-				(unsigned int)ao->output2buffer3_cbcr_phy);
-			CDBG("%x %x\n", (unsigned int)ao->output2buffer4_y_phy,
-				(unsigned int)ao->output2buffer4_cbcr_phy);
-			CDBG("%x %x\n", (unsigned int)ao->output2buffer5_y_phy,
-				(unsigned int)ao->output2buffer5_cbcr_phy);
-			CDBG("%x %x\n", (unsigned int)ao->output2buffer6_y_phy,
-				(unsigned int)ao->output2buffer6_cbcr_phy);
-			CDBG("%x %x\n", (unsigned int)ao->output2buffer7_y_phy,
-				(unsigned int)ao->output2buffer7_cbcr_phy);
-		}
-	} else if (mode == OUTPUT_SEC) {
-		/* Thumbnail */
-		if (vfe2x_ctrl->zsl_mode) {
-			ao->output1buffer1_y_phy = ad->ping.ch_paddr[0];
-			ao->output1buffer1_cbcr_phy = ad->ping.ch_paddr[1];
-			ao->output1buffer2_y_phy = ad->pong.ch_paddr[0];
-			ao->output1buffer2_cbcr_phy = ad->pong.ch_paddr[1];
-			ao->output1buffer3_y_phy = ad->free_buf.ch_paddr[0];
-			ao->output1buffer3_cbcr_phy = ad->free_buf.ch_paddr[1];
-			bptr = &ao->output1buffer4_y_phy;
-			for (cnt = 0; cnt < 5; cnt++) {
-				*bptr = ad->pong.ch_paddr[0];
-				bptr++;
-				*bptr = ad->pong.ch_paddr[1];
-				bptr++;
-			}
-		} else {
-			ao->output1buffer1_y_phy = ad->ping.ch_paddr[0];
-			ao->output1buffer1_cbcr_phy = ad->ping.ch_paddr[1];
-			ao->output1buffer2_y_phy = ad->pong.ch_paddr[0];
-			ao->output1buffer2_cbcr_phy = ad->pong.ch_paddr[1];
-			bptr = &ao->output1buffer3_y_phy;
-			for (cnt = 0; cnt < 6; cnt++) {
-				*bptr = ad->pong.ch_paddr[0];
-				bptr++;
-				*bptr = ad->pong.ch_paddr[1];
-				bptr++;
-			}
-		}
-	} else if (mode == OUTPUT_PRIM && o_mode != SNAPSHOT_MASK_MODE) {
-		/* Preview */
-		ao->output2buffer1_y_phy = ad->ping.ch_paddr[0];
-		ao->output2buffer1_cbcr_phy = ad->ping.ch_paddr[1];
-		ao->output2buffer2_y_phy = ad->pong.ch_paddr[0];
-		ao->output2buffer2_cbcr_phy = ad->pong.ch_paddr[1];
-		spin_lock_irqsave(&vfe2x_ctrl->liveshot_enabled_lock,
-				flags);
-		if (vfe2x_ctrl->liveshot_enabled) { /* Live shot */
-			ao->output2buffer3_y_phy = ad->pong.ch_paddr[0];
-			ao->output2buffer3_cbcr_phy = ad->pong.ch_paddr[1];
-		} else {
-			ao->output2buffer3_y_phy = ad->free_buf.ch_paddr[0];
-			ao->output2buffer3_cbcr_phy = ad->free_buf.ch_paddr[1];
-		}
-		spin_unlock_irqrestore(&vfe2x_ctrl->liveshot_enabled_lock,
-				flags);
-		bptr = &ao->output2buffer4_y_phy;
-		for (cnt = 0; cnt < 5; cnt++) {
-			*bptr = ad->pong.ch_paddr[0];
-			bptr++;
-			*bptr = ad->pong.ch_paddr[1];
-			bptr++;
-		}
-		CDBG("%x %x\n", (unsigned int)ao->output2buffer1_y_phy,
-			(unsigned int)ao->output2buffer1_cbcr_phy);
-		CDBG("%x %x\n", (unsigned int)ao->output2buffer2_y_phy,
-			(unsigned int)ao->output2buffer2_cbcr_phy);
-		CDBG("%x %x\n", (unsigned int)ao->output2buffer3_y_phy,
-			(unsigned int)ao->output2buffer3_cbcr_phy);
-		CDBG("%x %x\n", (unsigned int)ao->output2buffer4_y_phy,
-			(unsigned int)ao->output2buffer4_cbcr_phy);
-		CDBG("%x %x\n", (unsigned int)ao->output2buffer5_y_phy,
-			(unsigned int)ao->output2buffer5_cbcr_phy);
-		CDBG("%x %x\n", (unsigned int)ao->output2buffer6_y_phy,
-			(unsigned int)ao->output2buffer6_cbcr_phy);
-		CDBG("%x %x\n", (unsigned int)ao->output2buffer7_y_phy,
-			(unsigned int)ao->output2buffer7_cbcr_phy);
-		vfe2x_ctrl->free_buf.buf[0].ch_paddr[0] = ad->ping.ch_paddr[0];
-		vfe2x_ctrl->free_buf.buf[0].ch_paddr[1] = ad->ping.ch_paddr[1];
-		vfe2x_ctrl->free_buf.buf[1].ch_paddr[0] = ad->pong.ch_paddr[0];
-		vfe2x_ctrl->free_buf.buf[1].ch_paddr[1] = ad->pong.ch_paddr[1];
-		vfe2x_ctrl->free_buf.buf[2].ch_paddr[0] =
-			ad->free_buf.ch_paddr[0];
-		vfe2x_ctrl->free_buf.buf[2].ch_paddr[1] =
-			ad->free_buf.ch_paddr[1];
-	} else if (mode == OUTPUT_PRIM && o_mode == SNAPSHOT_MASK_MODE) {
-		vfe2x_ctrl->reconfig_vfe = 0;
-		if (raw_mode) {
-			ao->output2buffer1_y_phy = ad->ping.ch_paddr[0];
-			ao->output2buffer1_cbcr_phy = ad->ping.ch_paddr[0];
-			ao->output2buffer2_y_phy = ad->pong.ch_paddr[0];
-			ao->output2buffer2_cbcr_phy = ad->pong.ch_paddr[0];
-		} else {
-			ao->output2buffer1_y_phy = ad->ping.ch_paddr[0];
-			ao->output2buffer1_cbcr_phy = ad->ping.ch_paddr[1];
-			ao->output2buffer2_y_phy = ad->pong.ch_paddr[0];
-			ao->output2buffer2_cbcr_phy = ad->pong.ch_paddr[1];
-	}
-		bptr = &ao->output2buffer3_y_phy;
-		for (cnt = 0; cnt < 6; cnt++) {
-			*bptr = ad->pong.ch_paddr[0];
-			bptr++;
-			*bptr = ad->pong.ch_paddr[1];
-			bptr++;
-		}
-	}
-
-	return rc;
-}
-
-static void vfe2x_subdev_notify(int id, int path)
-{
-	struct msm_vfe_resp rp;
-	unsigned long flags = 0;
-	spin_lock_irqsave(&vfe2x_ctrl->sd_notify_lock, flags);
-	memset(&rp, 0, sizeof(struct msm_vfe_resp));
-	CDBG("vfe2x_subdev_notify : msgId = %d\n", id);
-	rp.evt_msg.type   = MSM_CAMERA_MSG;
-	rp.evt_msg.msg_id = path;
-	rp.evt_msg.data = NULL;
-	rp.type	   = id;
-	v4l2_subdev_notify(&vfe2x_ctrl->subdev, NOTIFY_VFE_BUF_EVT, &rp);
-	spin_unlock_irqrestore(&vfe2x_ctrl->sd_notify_lock, flags);
-}
-
-static struct msm_free_buf *vfe2x_check_free_buffer(int id, int path)
-{
-	struct buf_info *outch = NULL;
-
-	vfe2x_subdev_notify(id, path);
-	if (op_mode & SNAPSHOT_MASK_MODE) {
-		if (path == VFE_MSG_OUTPUT_PRIMARY ||
-				path == VFE_MSG_V2X_LIVESHOT_PRIMARY)
-			outch = &vfe2x_ctrl->snap;
-		else if (path == VFE_MSG_OUTPUT_SECONDARY)
-			outch = &vfe2x_ctrl->thumb;
-	} else {
-		if (path == VFE_MSG_OUTPUT_PRIMARY ||
-				path == VFE_MSG_V2X_LIVESHOT_PRIMARY) {
-			if (vfe2x_ctrl->zsl_mode)
-				outch = &vfe2x_ctrl->zsl_prim;
-			else
-				outch = &vfe2x_ctrl->prev;
-		} else if (path == VFE_MSG_OUTPUT_SECONDARY)
-				outch = &vfe2x_ctrl->zsl_sec;
-	}
-	if (outch->free_buf.ch_paddr[0])
-		return &outch->free_buf;
-
-	return NULL;
-}
-
-static int vfe2x_configure_pingpong_buffers(int id, int path)
-{
-	struct buf_info *outch = NULL;
-	int rc = 0;
-
-	vfe2x_subdev_notify(id, path);
-	CDBG("Opmode = %d\n", op_mode);
-	if (op_mode & SNAPSHOT_MASK_MODE) {
-		if (path == VFE_MSG_OUTPUT_PRIMARY ||
-				path == VFE_MSG_V2X_LIVESHOT_PRIMARY)
-			outch = &vfe2x_ctrl->snap;
-		else if (path == VFE_MSG_OUTPUT_SECONDARY)
-			outch = &vfe2x_ctrl->thumb;
-	} else {
-		if (path == VFE_MSG_OUTPUT_PRIMARY ||
-				path == VFE_MSG_V2X_LIVESHOT_PRIMARY) {
-			if (vfe2x_ctrl->zsl_mode)
-				outch = &vfe2x_ctrl->zsl_prim;
-			else
-				outch = &vfe2x_ctrl->prev;
-		} else if (path == VFE_MSG_OUTPUT_SECONDARY)
-			outch = &vfe2x_ctrl->zsl_sec;
-	}
-	if (outch->ping.ch_paddr[0] && outch->pong.ch_paddr[0]) {
-		/* Configure Preview Ping Pong */
-		CDBG("%s Configure ping/pong address for %d",
-						__func__, path);
-	} else {
-		pr_err("%s ping/pong addr is null!!", __func__);
-		rc = -EINVAL;
-	}
-	return rc;
-}
-
-static struct buf_info *vfe2x_get_ch(int path)
-{
-	struct buf_info *ch = NULL;
-
-	CDBG("path = %d op_mode = %d\n", path, op_mode);
-	/* TODO: Remove Mode specific stuff */
-	if (op_mode & SNAPSHOT_MASK_MODE) {
-		if (path == VFE_MSG_OUTPUT_SECONDARY)
-			ch = &vfe2x_ctrl->thumb;
-		else if (path == VFE_MSG_OUTPUT_PRIMARY ||
-					path == VFE_MSG_V2X_LIVESHOT_PRIMARY)
-			ch = &vfe2x_ctrl->snap;
-	} else {
-		if (path == VFE_MSG_OUTPUT_PRIMARY ||
-					path == VFE_MSG_V2X_LIVESHOT_PRIMARY) {
-			if (vfe2x_ctrl->zsl_mode)
-				ch = &vfe2x_ctrl->zsl_prim;
-			else
-				ch = &vfe2x_ctrl->prev;
-		} else if (path == VFE_MSG_OUTPUT_SECONDARY)
-			ch = &vfe2x_ctrl->zsl_sec;
-	}
-
-	BUG_ON(ch == NULL);
-	return ch;
-}
-
-static long msm_vfe_subdev_ioctl(struct v4l2_subdev *sd,
-			unsigned int subdev_cmd, void *arg)
-{
-	struct msm_isp_cmd vfecmd;
-	struct msm_camvfe_params *vfe_params;
-	struct msm_vfe_cfg_cmd *cmd;
-	struct table_cmd *table_pending;
-	long rc = 0;
-	void *data;
-
-	struct msm_pmem_region *regptr;
-	unsigned char buf[256];
-
-	struct vfe_stats_ack sack;
-	struct axidata *axid;
-	uint32_t i;
-	uint32_t header = 0;
-	uint32_t queue = 0;
-	struct vfe_stats_we_cfg *scfg = NULL;
-	struct vfe_stats_af_cfg *sfcfg = NULL;
-
-	struct axiout *axio = NULL;
-	void   *cmd_data = NULL;
-	void   *cmd_data_alloc = NULL;
-	unsigned long flags;
-	struct msm_free_buf *free_buf = NULL;
-	struct vfe_outputack fack;
-
-	CDBG("msm_vfe_subdev_ioctl is called\n");
-	if (subdev_cmd == VIDIOC_MSM_VFE_INIT) {
-		CDBG("%s init\n", __func__);
-		return msm_vfe_subdev_init(sd);
-	} else if (subdev_cmd == VIDIOC_MSM_VFE_RELEASE) {
-		msm_vfe_subdev_release(sd);
-		return 0;
-	}
-
-	vfe_params = (struct msm_camvfe_params *)arg;
-	cmd = vfe_params->vfe_cfg;
-	data = vfe_params->data;
-
-	if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
-		cmd->cmd_type != CMD_STATS_BUF_RELEASE &&
-		cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE &&
-		cmd->cmd_type != CMD_CONFIG_PING_ADDR &&
-		cmd->cmd_type != CMD_CONFIG_PONG_ADDR &&
-		cmd->cmd_type != CMD_CONFIG_FREE_BUF_ADDR &&
-		cmd->cmd_type != CMD_VFE_BUFFER_RELEASE &&
-		cmd->cmd_type != VFE_CMD_STATS_REQBUF &&
-		cmd->cmd_type != VFE_CMD_STATS_FLUSH_BUFQ &&
-		cmd->cmd_type != VFE_CMD_STATS_UNREGBUF &&
-		cmd->cmd_type != VFE_CMD_STATS_ENQUEUEBUF) {
-		if (copy_from_user(&vfecmd,
-			   (void __user *)(cmd->value),
-			   sizeof(vfecmd))) {
-			pr_err("copy_from_user in msm_vfe_subdev_ioctl fail\n");
-			return -EFAULT;
-		}
-	}
-	switch (cmd->cmd_type) {
-	case VFE_CMD_STATS_REQBUF:
-	case VFE_CMD_STATS_FLUSH_BUFQ:
-	case VFE_CMD_STATS_UNREGBUF:
-		/* for easy porting put in one envelope */
-		rc = vfe2x_stats_bufq_sub_ioctl(cmd, vfe_params->data);
-		return rc;
-	case VFE_CMD_STATS_ENQUEUEBUF:
-		if (sizeof(struct msm_stats_buf_info) != cmd->length) {
-			/* error. the length not match */
-			pr_err("%s: stats enqueuebuf input size = %d,\n"
-				"struct size = %d, mitch match\n",\
-				__func__, cmd->length,
-				sizeof(struct msm_stats_buf_info));
-			rc = -EINVAL;
-			return rc;
-		}
-		sack.header = 0;
-		sack.bufaddr = NULL;
-		rc = vfe2x_stats_enqueuebuf(cmd->value, &sack);
-		if (rc < 0) {
-			pr_err("%s: error", __func__);
-			rc = -EINVAL;
-			return rc;
-		}
-		if (sack.header != 0 && sack.bufaddr != NULL) {
-			queue  = QDSP_CMDQUEUE;
-			vfecmd.length = sizeof(struct vfe_stats_ack) - 4;
-			cmd_data = &sack;
-		} else {
-			return 0;
-		}
-	break;
-	case CMD_VFE_BUFFER_RELEASE: {
-		if (!(vfe2x_ctrl->vfe_started) || op_mode == 1)
-			return 0;
-		if (op_mode & SNAPSHOT_MASK_MODE) {
-			free_buf = vfe2x_check_free_buffer(
-					VFE_MSG_OUTPUT_IRQ,
-					VFE_MSG_OUTPUT_SECONDARY);
-		} else {
-			free_buf = vfe2x_check_free_buffer(
-					VFE_MSG_OUTPUT_IRQ,
-					VFE_MSG_OUTPUT_PRIMARY);
-			if (free_buf) {
-				fack.header = VFE_OUTPUT2_ACK;
-
-				fack.output2newybufferaddress =
-						(void *)(free_buf->ch_paddr[0]);
-
-				fack.output2newcbcrbufferaddress =
-						(void *)(free_buf->ch_paddr[1]);
-
-				cmd_data = &fack;
-				vfecmd.length = sizeof(fack) - 4;
-				queue = QDSP_CMDQUEUE;
-			}
-		}
-	}
-	break;
-	case CMD_CONFIG_PING_ADDR: {
-		int path = *((int *)cmd->value);
-		struct buf_info *outch = vfe2x_get_ch(path);
-		outch->ping = *((struct msm_free_buf *)data);
-	}
-		return 0;
-	case CMD_CONFIG_PONG_ADDR: {
-		int path = *((int *)cmd->value);
-		struct buf_info *outch = vfe2x_get_ch(path);
-		outch->pong = *((struct msm_free_buf *)data);
-	}
-		return 0;
-
-	case CMD_AXI_START:
-	case CMD_AXI_STOP:
-	case CMD_AXI_RESET:
-		return 0;
-
-	case CMD_CONFIG_FREE_BUF_ADDR: {
-		int path = *((int *)cmd->value);
-		struct buf_info *outch = vfe2x_get_ch(path);
-		if ((op_mode & SNAPSHOT_MASK_MODE) &&
-			(vfe2x_ctrl->num_snap > 1)) {
-			CDBG("%s: CMD_CONFIG_FREE_BUF_ADDR Burst mode %d",
-					__func__, outch->free_buf_cnt);
-			if (outch->free_buf_cnt <= 0)
-				outch->free_buf =
-					*((struct msm_free_buf *)data);
-			else
-				outch->free_buf_arr[outch->free_buf_cnt-1] =
-					*((struct msm_free_buf *)data);
-			++outch->free_buf_cnt;
-		} else {
-			outch->free_buf = *((struct msm_free_buf *)data);
-		}
-	}
-		return 0;
-
-	case CMD_STATS_AXI_CFG: {
-		axid = data;
-		if (!axid) {
-			rc = -EFAULT;
-			goto config_failure;
-		}
-
-		scfg =
-			kmalloc(sizeof(struct vfe_stats_we_cfg),
-				GFP_ATOMIC);
-		if (!scfg) {
-			rc = -ENOMEM;
-			goto config_failure;
-		}
-
-		if (copy_from_user((char *)scfg + 4,
-					(void __user *)(vfecmd.value),
-					vfecmd.length)) {
-
-			rc = -EFAULT;
-			goto config_done;
-		}
-
-		CDBG("STATS_ENABLE: bufnum = %d, enabling = %d\n",
-			axid->bufnum1, scfg->wb_expstatsenable);
-
-		header = cmds_map[vfecmd.id].vfe_id;
-		queue = cmds_map[vfecmd.id].queue;
-		if (header == -1 && queue == -1) {
-			rc = -EFAULT;
-			goto config_failure;
-		}
-		*(uint32_t *)scfg = header;
-		if (axid->bufnum1 > 0) {
-			regptr = axid->region;
-
-			for (i = 0; i < axid->bufnum1; i++) {
-
-				CDBG("STATS_ENABLE, phy = 0x%lx\n",
-					regptr->paddr);
-
-				scfg->wb_expstatoutputbuffer[i] =
-					(void *)regptr->paddr;
-				regptr++;
-			}
-
-			cmd_data = scfg;
-
-		} else {
-			rc = -EINVAL;
-			goto config_done;
-		}
-	}
-		break;
-	case CMD_STATS_AEC_AWB_ENABLE: {
-		pr_err("CMD_STATS_AEC_AWB_ENABLE\n");
-		scfg =
-			kmalloc(sizeof(struct vfe_stats_we_cfg),
-				GFP_ATOMIC);
-		if (!scfg) {
-			rc = -ENOMEM;
-			goto config_failure;
-		}
-
-		if (copy_from_user((char *)scfg + 4,
-					(void __user *)(vfecmd.value),
-					vfecmd.length)) {
-
-			rc = -EFAULT;
-			goto config_done;
-		}
-
-		header = cmds_map[vfecmd.id].vfe_id;
-		queue = cmds_map[vfecmd.id].queue;
-		if (header == -1 && queue == -1) {
-			rc = -EFAULT;
-			goto config_failure;
-		}
-		*(uint32_t *)scfg = header;
-		rc = vfe2x_stats_buf_init(MSM_STATS_TYPE_AE_AW);
-		if (rc < 0) {
-			pr_err("%s: cannot config ping/pong address of AWB",
-				 __func__);
-			goto config_failure;
-		}
-		scfg->wb_expstatoutputbuffer[0] =
-			(void *)vfe2x_ctrl->stats_we_buf_ptr[0];
-		scfg->wb_expstatoutputbuffer[1] =
-			(void *)vfe2x_ctrl->stats_we_buf_ptr[1];
-		scfg->wb_expstatoutputbuffer[2] =
-			(void *)vfe2x_ctrl->stats_we_buf_ptr[2];
-		cmd_data = scfg;
-	}
-	break;
-	case CMD_STATS_AF_ENABLE:
-	case CMD_STATS_AF_AXI_CFG: {
-		CDBG("CMD_STATS_AF_ENABLE CMD_STATS_AF_AXI_CFG\n");
-		sfcfg =
-			kmalloc(sizeof(struct vfe_stats_af_cfg),
-				GFP_ATOMIC);
-
-		if (!sfcfg) {
-			rc = -ENOMEM;
-			goto config_failure;
-		}
-
-		if (copy_from_user((char *)sfcfg + 4,
-					(void __user *)(vfecmd.value),
-					vfecmd.length)) {
-
-			rc = -EFAULT;
-			goto config_done;
-		}
-
-		header = cmds_map[vfecmd.id].vfe_id;
-		queue = cmds_map[vfecmd.id].queue;
-		if (header == -1 && queue == -1) {
-			rc = -EFAULT;
-			goto config_failure;
-		}
-		*(uint32_t *)sfcfg = header;
-		rc = vfe2x_stats_buf_init(MSM_STATS_TYPE_AF);
-		sfcfg->af_outbuf[0] = (void *)vfe2x_ctrl->stats_af_buf_ptr[0];
-		sfcfg->af_outbuf[1] = (void *)vfe2x_ctrl->stats_af_buf_ptr[1];
-		sfcfg->af_outbuf[2] = (void *)vfe2x_ctrl->stats_af_buf_ptr[2];
-		if (rc < 0) {
-			pr_err("%s: cannot config ping/pong address of AWB",
-				__func__);
-			goto config_failure;
-		}
-		cmd_data = sfcfg;
-	}
-		break;
-	case CMD_SNAP_BUF_RELEASE:
-		break;
-	case CMD_STATS_BUF_RELEASE: {
-		CDBG("vfe_7x_config: CMD_STATS_BUF_RELEASE\n");
-		if (!data) {
-			rc = -EFAULT;
-			goto config_failure;
-		}
-
-		sack.header = VFE_STATS_WB_EXP_ACK;
-		sack.bufaddr = (void *)*(uint32_t *)data;
-
-		queue  = QDSP_CMDQUEUE;
-		vfecmd.length = sizeof(struct vfe_stats_ack) - 4;
-		cmd_data = &sack;
-	}
-		break;
-	case CMD_STATS_AF_BUF_RELEASE: {
-		CDBG("vfe_7x_config: CMD_STATS_AF_BUF_RELEASE\n");
-		if (!data) {
-			rc = -EFAULT;
-			goto config_failure;
-		}
-
-		sack.header = VFE_STATS_AUTOFOCUS_ACK;
-		sack.bufaddr = (void *)*(uint32_t *)data;
-
-		queue  = QDSP_CMDQUEUE;
-		vfecmd.length = sizeof(struct vfe_stats_ack) - 4;
-		cmd_data = &sack;
-	}
-		break;
-	case CMD_GENERAL:
-	case CMD_STATS_DISABLE: {
-		CDBG("CMD_GENERAL:%d %d\n", vfecmd.id, vfecmd.length);
-		if (vfecmd.id == VFE_CMD_OPERATION_CFG) {
-			if (copy_from_user(&vfe2x_ctrl->start_cmd,
-						(void __user *)(vfecmd.value),
-							vfecmd.length))
-				rc = -EFAULT;
-			op_mode = vfe2x_ctrl->start_cmd.mode_of_operation;
-			vfe2x_ctrl->snap.free_buf_cnt = 0;
-			vfe2x_ctrl->thumb.free_buf_cnt = 0;
-			vfe2x_ctrl->snap.frame_cnt = 0;
-			vfe2x_ctrl->thumb.frame_cnt = 0;
-			vfe2x_ctrl->num_snap =
-				vfe2x_ctrl->start_cmd.snap_number;
-			return rc;
-		}
-		if (vfecmd.id == VFE_CMD_RECONFIG_VFE) {
-			CDBG("VFE is RECONFIGURED\n");
-			vfe2x_ctrl->reconfig_vfe = 1;
-			return 0;
-		}
-		if (vfecmd.id == VFE_CMD_LIVESHOT) {
-			CDBG("live shot enabled\n");
-			spin_lock_irqsave(&vfe2x_ctrl->liveshot_enabled_lock,
-					flags);
-			vfe2x_ctrl->liveshot_enabled = 1;
-			spin_unlock_irqrestore(&vfe2x_ctrl->
-					liveshot_enabled_lock,
-					flags);
-			return 0;
-		}
-		if (vfecmd.id == VFE_CMD_STOP_LIVESHOT) {
-			CDBG("live shot disabled\n");
-			spin_lock_irqsave(&vfe2x_ctrl->liveshot_enabled_lock,
-					flags);
-			vfe2x_ctrl->liveshot_enabled = 0;
-			spin_unlock_irqrestore(
-					&vfe2x_ctrl->liveshot_enabled_lock,
-					flags);
-			return 0;
-		}
-		if (vfecmd.length > 256 - 4) {
-			cmd_data_alloc =
-			cmd_data = kmalloc(vfecmd.length + 4, GFP_ATOMIC);
-			if (!cmd_data) {
-				rc = -ENOMEM;
-				goto config_failure;
-			}
-		} else
-			cmd_data = buf;
-
-		if (copy_from_user(((char *)cmd_data) + 4,
-					(void __user *)(vfecmd.value),
-					vfecmd.length)) {
-
-			rc = -EFAULT;
-			goto config_done;
-		}
-		header = cmds_map[vfecmd.id].vfe_id;
-		queue = cmds_map[vfecmd.id].queue;
-		if (header == -1 && queue == -1) {
-			rc = -EFAULT;
-			goto config_done;
-		}
-		CDBG("%s %s\n", cmds_map[vfecmd.id].isp_id_name,
-			cmds_map[vfecmd.id].vfe_id_name);
-		*(uint32_t *)cmd_data = header;
-		if (queue == QDSP_CMDQUEUE) {
-			switch (vfecmd.id) {
-			case VFE_CMD_RESET:
-				msm_camio_vfe_blk_reset_2();
-				vfestopped = 0;
-				break;
-			case VFE_CMD_START:
-			case VFE_CMD_CAPTURE:
-			case VFE_CMD_CAPTURE_RAW:
-			case VFE_CMD_ZSL:
-				spin_lock_irqsave(&vfe2x_ctrl->table_lock,
-									flags);
-				if ((!list_empty(&vfe2x_ctrl->table_q)) ||
-						vfe2x_ctrl->tableack_pending) {
-					CDBG("start pending\n");
-					vfe2x_ctrl->start_pending = 1;
-					spin_unlock_irqrestore(
-						&vfe2x_ctrl->table_lock,
-								flags);
-					return 0;
-				}
-				spin_unlock_irqrestore(&vfe2x_ctrl->table_lock,
-									flags);
-				vfecmd.length = sizeof(vfe2x_ctrl->start_cmd);
-				memcpy(((char *)cmd_data) + 4,
-					&vfe2x_ctrl->start_cmd,
-					sizeof(vfe2x_ctrl->start_cmd));
-				if (op_mode & SNAPSHOT_MASK_MODE)
-					msm_camio_set_perf_lvl(S_CAPTURE);
-				else
-					msm_camio_set_perf_lvl(S_PREVIEW);
-				vfestopped = 0;
-				break;
-			case VFE_CMD_STOP:
-				vfestopped = 1;
-				spin_lock_irqsave(&vfe2x_ctrl->table_lock,
-						flags);
-				if (op_mode & SNAPSHOT_MASK_MODE) {
-					vfe2x_ctrl->stop_pending = 0;
-					spin_unlock_irqrestore(
-							&vfe2x_ctrl->table_lock,
-							flags);
-					return 0;
-				}
-				if ((!list_empty(&vfe2x_ctrl->table_q)) ||
-						vfe2x_ctrl->tableack_pending) {
-					CDBG("stop pending\n");
-					vfe2x_ctrl->stop_pending = 1;
-					spin_unlock_irqrestore(
-							&vfe2x_ctrl->table_lock,
-							flags);
-					return 0;
-				}
-				spin_unlock_irqrestore(&vfe2x_ctrl->table_lock,
-						flags);
-				vfe2x_ctrl->vfe_started = 0;
-				goto config_send;
-			case VFE_CMD_UPDATE:
-				spin_lock_irqsave(&vfe2x_ctrl->table_lock,
-						flags);
-				if ((!list_empty(&vfe2x_ctrl->table_q)) ||
-						vfe2x_ctrl->tableack_pending) {
-					CDBG("update pending\n");
-					vfe2x_ctrl->update_pending = 0;
-					vfe2x_send_isp_msg(vfe2x_ctrl,
-						msgs_map[MSG_UPDATE_ACK].
-						isp_id);
-					spin_unlock_irqrestore(
-							&vfe2x_ctrl->table_lock,
-							flags);
-					return 0;
-				}
-				spin_unlock_irqrestore(&vfe2x_ctrl->table_lock,
-						flags);
-				goto config_send;
-			default:
-				break;
-			}
-		} /* QDSP_CMDQUEUE */
-	}
-		break;
-	case CMD_AXI_CFG_SEC: {
-		CDBG("CMD_AXI_CFG_SEC\n");
-		raw_mode = 0;
-		vfe2x_ctrl->zsl_mode = 0;
-		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
-		if (!axio) {
-			pr_err("NULL axio\n");
-			rc = -ENOMEM;
-			goto config_failure;
-		}
-
-		if (copy_from_user((char *)axio + 4,
-					(void __user *)(vfecmd.value),
-					sizeof(struct axiout))) {
-			CDBG("copy_from_user failed\n");
-			rc = -EFAULT;
-			goto config_done;
-		}
-		if (op_mode & SNAPSHOT_MASK_MODE)
-			rc = vfe2x_configure_pingpong_buffers(
-						VFE_MSG_CAPTURE,
-						VFE_MSG_OUTPUT_SECONDARY);
-		else
-			rc = vfe2x_configure_pingpong_buffers(
-						VFE_MSG_PREVIEW,
-						VFE_MSG_OUTPUT_SECONDARY);
-		if (rc < 0) {
-			pr_err("%s error configuring pingpong buffers"
-				" for preview", __func__);
-			rc = -EINVAL;
-			goto config_done;
-		}
-
-		if (!(op_mode & SNAPSHOT_MASK_MODE))
-			free_buf = vfe2x_check_free_buffer(
-					VFE_MSG_OUTPUT_IRQ,
-					VFE_MSG_OUTPUT_SECONDARY);
-		header = cmds_map[vfecmd.id].vfe_id;
-		queue = cmds_map[vfecmd.id].queue;
-		if (header == -1 && queue == -1) {
-			rc = -EFAULT;
-			goto config_done;
-		}
-		*(uint32_t *)axio = header;
-		if (op_mode & SNAPSHOT_MASK_MODE)
-			vfe_7x_config_axi(OUTPUT_SEC,
-					&vfe2x_ctrl->thumb, axio);
-		else
-			vfe_7x_config_axi(OUTPUT_SEC,
-					&vfe2x_ctrl->video, axio);
-		cmd_data = axio;
-	}
-		break;
-	case CMD_AXI_CFG_PRIM: {
-		CDBG("CMD_AXI_CFG_PRIM : %d\n", op_mode);
-		raw_mode = 0;
-		vfe2x_ctrl->zsl_mode = 0;
-		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
-		if (!axio) {
-			pr_err("NULL axio\n");
-			rc = -ENOMEM;
-			goto config_failure;
-		}
-
-		if (copy_from_user((char *)axio + 4,
-					(void __user *)(vfecmd.value),
-					sizeof(struct axiout))) {
-			pr_err("copy_from_user failed\n");
-			rc = -EFAULT;
-			goto config_done;
-		}
-		if (!vfe2x_ctrl->reconfig_vfe) {
-			if (op_mode & SNAPSHOT_MASK_MODE)
-				rc = vfe2x_configure_pingpong_buffers(
-						VFE_MSG_CAPTURE,
-						VFE_MSG_OUTPUT_PRIMARY);
-			else
-				rc = vfe2x_configure_pingpong_buffers(
-						VFE_MSG_PREVIEW,
-						VFE_MSG_OUTPUT_PRIMARY);
-			if (rc < 0) {
-				pr_err("%s error configuring pingpong buffers"
-					" for preview", __func__);
-				rc = -EINVAL;
-				goto config_done;
-			}
-			if (!(op_mode & SNAPSHOT_MASK_MODE))
-				free_buf = vfe2x_check_free_buffer(
-					VFE_MSG_OUTPUT_IRQ,
-					VFE_MSG_OUTPUT_PRIMARY);
-		} else {
-			vfe2x_ctrl->prev.ping.ch_paddr[0] =
-				vfe2x_ctrl->free_buf.buf[0].ch_paddr[0];
-			vfe2x_ctrl->prev.ping.ch_paddr[1] =
-				vfe2x_ctrl->free_buf.buf[0].ch_paddr[1];
-			vfe2x_ctrl->prev.pong.ch_paddr[0] =
-				vfe2x_ctrl->free_buf.buf[1].ch_paddr[0];
-			vfe2x_ctrl->prev.pong.ch_paddr[1] =
-				vfe2x_ctrl->free_buf.buf[1].ch_paddr[1];
-			vfe2x_ctrl->prev.free_buf.ch_paddr[0] =
-				vfe2x_ctrl->free_buf.buf[2].ch_paddr[0];
-			vfe2x_ctrl->prev.free_buf.ch_paddr[1] =
-				vfe2x_ctrl->free_buf.buf[2].ch_paddr[1];
-			vfe2x_ctrl->reconfig_vfe = 0;
-		}
-		header = cmds_map[vfecmd.id].vfe_id;
-		queue = cmds_map[vfecmd.id].queue;
-		if (header == -1 && queue == -1) {
-			rc = -EFAULT;
-			goto config_done;
-		}
-		*(uint32_t *)axio = header;
-		if (op_mode & SNAPSHOT_MASK_MODE)
-			vfe_7x_config_axi(OUTPUT_PRIM, &vfe2x_ctrl->snap, axio);
-		else
-			vfe_7x_config_axi(OUTPUT_PRIM, &vfe2x_ctrl->prev, axio);
-		cmd_data = axio;
-	}
-		break;
-	case CMD_AXI_CFG_ZSL: {
-		CDBG("CMD_AXI_CFG_ZSL: %d\n", op_mode);
-		raw_mode = 0;
-		vfe2x_ctrl->zsl_mode = 1;
-		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
-		if (!axio) {
-			pr_err("NULL axio\n");
-			rc = -ENOMEM;
-			goto config_failure;
-		}
-
-		if (copy_from_user((char *)axio + 4,
-					(void __user *)(vfecmd.value),
-					sizeof(struct axiout))) {
-			pr_err("copy_from_user failed\n");
-			rc = -EFAULT;
-			goto config_done;
-		}
-		if (!vfe2x_ctrl->reconfig_vfe) {
-				rc = vfe2x_configure_pingpong_buffers(
-						VFE_MSG_PREVIEW,
-						VFE_MSG_OUTPUT_PRIMARY);
-				rc = vfe2x_configure_pingpong_buffers(
-						VFE_MSG_PREVIEW,
-						VFE_MSG_OUTPUT_SECONDARY);
-			if (rc < 0) {
-				pr_err("%s error configuring pingpong buffers"
-					" for preview", __func__);
-				rc = -EINVAL;
-				goto config_done;
-			}
-				free_buf = vfe2x_check_free_buffer(
-					VFE_MSG_OUTPUT_IRQ,
-					VFE_MSG_OUTPUT_PRIMARY);
-				free_buf = vfe2x_check_free_buffer(
-					VFE_MSG_OUTPUT_IRQ,
-					VFE_MSG_OUTPUT_SECONDARY);
-		} else {
-			vfe2x_ctrl->prev.ping.ch_paddr[0] =
-				vfe2x_ctrl->free_buf.buf[0].ch_paddr[0];
-			vfe2x_ctrl->prev.ping.ch_paddr[1] =
-				vfe2x_ctrl->free_buf.buf[0].ch_paddr[1];
-			vfe2x_ctrl->prev.pong.ch_paddr[0] =
-				vfe2x_ctrl->free_buf.buf[1].ch_paddr[0];
-			vfe2x_ctrl->prev.pong.ch_paddr[1] =
-				vfe2x_ctrl->free_buf.buf[1].ch_paddr[1];
-			vfe2x_ctrl->prev.free_buf.ch_paddr[0] =
-				vfe2x_ctrl->free_buf.buf[2].ch_paddr[0];
-			vfe2x_ctrl->prev.free_buf.ch_paddr[1] =
-				vfe2x_ctrl->free_buf.buf[2].ch_paddr[1];
-			vfe2x_ctrl->reconfig_vfe = 0;
-		}
-		header = cmds_map[vfecmd.id].vfe_id;
-		queue = cmds_map[vfecmd.id].queue;
-		if (header == -1 && queue == -1) {
-			rc = -EFAULT;
-			goto config_done;
-		}
-		*(uint32_t *)axio = header;
-		vfe_7x_config_axi(OUTPUT_PRIM, &vfe2x_ctrl->zsl_prim, axio);
-		vfe_7x_config_axi(OUTPUT_SEC, &vfe2x_ctrl->zsl_sec, axio);
-		cmd_data = axio;
-	}
-		break;
-	case CMD_AXI_CFG_SEC|CMD_AXI_CFG_PRIM: {
-		CDBG("CMD_AXI_CFG_SEC|PRIM\n");
-		raw_mode = 0;
-		vfe2x_ctrl->zsl_mode = 0;
-		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
-		if (!axio) {
-			pr_err("NULL axio\n");
-			rc = -ENOMEM;
-			goto config_failure;
-		}
-
-		if (copy_from_user((char *)axio + 4,
-					(void __user *)(vfecmd.value),
-					sizeof(struct axiout))) {
-			pr_err("copy_from_user failed\n");
-			rc = -EFAULT;
-			goto config_done;
-		}
-		if (op_mode & SNAPSHOT_MASK_MODE)
-			rc = vfe2x_configure_pingpong_buffers(
-						VFE_MSG_CAPTURE,
-						VFE_MSG_OUTPUT_SECONDARY);
-		else
-			rc = vfe2x_configure_pingpong_buffers(
-						VFE_MSG_PREVIEW,
-						VFE_MSG_OUTPUT_SECONDARY);
-		if (rc < 0) {
-			pr_err("%s error configuring pingpong buffers"
-				" for preview", __func__);
-			rc = -EINVAL;
-			goto config_done;
-		}
-
-		if (!(op_mode & SNAPSHOT_MASK_MODE)) {
-			free_buf = vfe2x_check_free_buffer(
-					VFE_MSG_OUTPUT_IRQ,
-					VFE_MSG_OUTPUT_SECONDARY);
-		} else if ((op_mode & SNAPSHOT_MASK_MODE) &&
-				(vfe2x_ctrl->num_snap > 1)) {
-			int i = 0;
-			CDBG("Burst mode AXI config SEC snap cnt %d\n",
-				vfe2x_ctrl->num_snap);
-			for (i = 0; i < vfe2x_ctrl->num_snap - 2; i++) {
-				free_buf = vfe2x_check_free_buffer(
-					VFE_MSG_OUTPUT_IRQ,
-					VFE_MSG_OUTPUT_SECONDARY);
-			}
-		}
-		header = cmds_map[vfecmd.id].vfe_id;
-		queue = cmds_map[vfecmd.id].queue;
-		if (header == -1 && queue == -1) {
-			rc = -EFAULT;
-			goto config_done;
-		}
-		*(uint32_t *)axio = header;
-		if (op_mode & SNAPSHOT_MASK_MODE)
-			vfe_7x_config_axi(OUTPUT_SEC, &vfe2x_ctrl->thumb, axio);
-		else
-			vfe_7x_config_axi(OUTPUT_SEC, &vfe2x_ctrl->prev, axio);
-
-		if (op_mode & SNAPSHOT_MASK_MODE)
-			rc = vfe2x_configure_pingpong_buffers(
-						VFE_MSG_CAPTURE,
-						VFE_MSG_OUTPUT_PRIMARY);
-		else
-			rc = vfe2x_configure_pingpong_buffers(
-						VFE_MSG_PREVIEW,
-						VFE_MSG_OUTPUT_PRIMARY);
-		if (rc < 0) {
-			pr_err("%s error configuring pingpong buffers"
-				" for preview", __func__);
-			rc = -EINVAL;
-			goto config_done;
-		}
-
-		if (!(op_mode & SNAPSHOT_MASK_MODE)) {
-			free_buf = vfe2x_check_free_buffer(
-					VFE_MSG_OUTPUT_IRQ,
-					VFE_MSG_OUTPUT_PRIMARY);
-		} else if ((op_mode & SNAPSHOT_MASK_MODE) &&
-				(vfe2x_ctrl->num_snap > 1)) {
-			int i = 0;
-			CDBG("Burst mode AXI config PRIM snap cnt %d\n",
-				vfe2x_ctrl->num_snap);
-			for (i = 0; i < vfe2x_ctrl->num_snap - 2; i++) {
-				free_buf = vfe2x_check_free_buffer(
-					VFE_MSG_OUTPUT_IRQ,
-					VFE_MSG_OUTPUT_PRIMARY);
-			}
-		}
-
-		if (op_mode & SNAPSHOT_MASK_MODE)
-			vfe_7x_config_axi(OUTPUT_PRIM,
-					&vfe2x_ctrl->snap, axio);
-		else
-			vfe_7x_config_axi(OUTPUT_PRIM,
-					&vfe2x_ctrl->prev, axio);
-		cmd_data = axio;
-	}
-		break;
-	case CMD_RAW_PICT_AXI_CFG: {
-		CDBG("CMD_RAW_PICT_AXI_CFG:%d\n", op_mode);
-		raw_mode = 1;
-		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			goto config_failure;
-		}
-
-		if (copy_from_user((char *)axio + 4,
-					(void __user *)(vfecmd.value),
-					sizeof(struct axiout))) {
-			rc = -EFAULT;
-			goto config_done;
-		}
-		header = cmds_map[vfecmd.id].vfe_id;
-		queue = cmds_map[vfecmd.id].queue;
-		rc = vfe2x_configure_pingpong_buffers(VFE_MSG_CAPTURE,
-						VFE_MSG_OUTPUT_PRIMARY);
-		if (rc < 0) {
-			pr_err("%s error configuring pingpong buffers"
-				" for preview", __func__);
-			rc = -EINVAL;
-			goto config_done;
-		}
-		if (header == -1 && queue == -1) {
-			rc = -EFAULT;
-			goto config_done;
-		}
-		*(uint32_t *)axio = header;
-		vfe_7x_config_axi(OUTPUT_PRIM, &vfe2x_ctrl->snap, axio);
-		cmd_data = axio;
-	}
-		break;
-	default:
-		break;
-	}
-
-	if (vfestopped)
-		goto config_done;
-
-config_send:
-	CDBG("send adsp command = %d\n", *(uint32_t *)cmd_data);
-	spin_lock_irqsave(&vfe2x_ctrl->table_lock, flags);
-	if (queue == QDSP_TABLEQUEUE &&
-			vfe2x_ctrl->tableack_pending) {
-		CDBG("store table cmd\n");
-		table_pending = kzalloc(sizeof(struct table_cmd), GFP_ATOMIC);
-		if (!table_pending) {
-			rc = -ENOMEM;
-			spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
-			goto config_done;
-		}
-		table_pending->cmd = kzalloc(vfecmd.length + 4, GFP_ATOMIC);
-		if (!table_pending->cmd) {
-			kfree(table_pending);
-			rc = -ENOMEM;
-			spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
-			goto config_done;
-		}
-		memcpy(table_pending->cmd, cmd_data, vfecmd.length + 4);
-		table_pending->queue = queue;
-		table_pending->size = vfecmd.length + 4;
-		list_add_tail(&table_pending->list, &vfe2x_ctrl->table_q);
-		spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
-	} else {
-		if (queue == QDSP_TABLEQUEUE) {
-			CDBG("sending table cmd\n");
-			vfe2x_ctrl->tableack_pending = 1;
-			rc = msm_adsp_write(vfe_mod, queue,
-				cmd_data, vfecmd.length + 4);
-			spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
-		} else {
-			if (*(uint32_t *)cmd_data == VFE_OUTPUT2_ACK) {
-				uint32_t *ptr = cmd_data;
-				CDBG("%x %x %x\n", ptr[0], ptr[1], ptr[2]);
-			}
-			CDBG("send n-table cmd\n");
-			rc = msm_adsp_write(vfe_mod, queue,
-				cmd_data, vfecmd.length + 4);
-			spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
-			CDBG("%x\n", vfecmd.length + 4);
-		}
-	}
-
-config_done:
-	kfree(cmd_data_alloc);
-
-config_failure:
-	kfree(scfg);
-	kfree(axio);
-	kfree(sfcfg);
-	return rc;
-}
-
-static struct msm_cam_clk_info vfe2x_clk_info[] = {
-	{"vfe_clk", 192000000},
-};
-
-int msm_vfe_subdev_init(struct v4l2_subdev *sd)
-{
-	int rc = 0;
-	struct msm_cam_media_controller *mctl;
-	mctl = v4l2_get_subdev_hostdata(sd);
-	if (mctl == NULL) {
-		pr_err("%s: mctl is NULL\n", __func__);
-		rc = -EINVAL;
-		goto mctl_failed;
-	}
-
-	spin_lock_init(&vfe2x_ctrl->sd_notify_lock);
-	spin_lock_init(&vfe2x_ctrl->table_lock);
-	spin_lock_init(&vfe2x_ctrl->vfe_msg_lock);
-	spin_lock_init(&vfe2x_ctrl->liveshot_enabled_lock);
-	init_waitqueue_head(&stopevent.wait);
-	INIT_LIST_HEAD(&vfe2x_ctrl->table_q);
-	INIT_LIST_HEAD(&vfe2x_ctrl->vfe_msg_q);
-	stopevent.timeout = 200;
-	stopevent.state = 0;
-	vfe2x_ctrl->vfe_started = 0;
-
-	memset(&vfe2x_ctrl->stats_ctrl, 0, sizeof(struct msm_stats_bufq_ctrl));
-	memset(&vfe2x_ctrl->stats_ops, 0, sizeof(struct msm_stats_ops));
-
-	CDBG("msm_cam_clk_enable: enable vfe_clk\n");
-	rc = msm_cam_clk_enable(&vfe2x_ctrl->pdev->dev, vfe2x_clk_info,
-			vfe2x_ctrl->vfe_clk, ARRAY_SIZE(vfe2x_clk_info), 1);
-	if (rc < 0)
-		return rc;
-
-	msm_camio_set_perf_lvl(S_INIT);
-
-	/* TODO : check is it required */
-	extlen = sizeof(struct vfe_frame_extra);
-
-	extdata = kmalloc(extlen, GFP_ATOMIC);
-	if (!extdata) {
-		rc = -ENOMEM;
-		goto init_fail;
-	}
-
-	rc = msm_adsp_get("QCAMTASK", &qcam_mod, &vfe_7x_sync, NULL);
-	if (rc) {
-		rc = -EBUSY;
-		goto get_qcam_fail;
-	}
-
-	rc = msm_adsp_get("VFETASK", &vfe_mod, &vfe_7x_sync, NULL);
-	if (rc) {
-		rc = -EBUSY;
-		goto get_vfe_fail;
-	}
-	msm_adsp_enable(qcam_mod);
-	msm_adsp_enable(vfe_mod);
-	return 0;
-
-get_vfe_fail:
-	msm_adsp_put(qcam_mod);
-get_qcam_fail:
-	kfree(extdata);
-init_fail:
-	extlen = 0;
-mctl_failed:
-	return rc;
-}
-
-int msm_vpe_subdev_init(struct v4l2_subdev *sd)
-{
-	return 0;
-}
-
-void msm_vpe_subdev_release(struct v4l2_subdev *sd)
-{
-	return;
-}
-
-void msm_vfe_subdev_release(struct v4l2_subdev *sd)
-{
-	CDBG("msm_cam_clk_enable: disable vfe_clk\n");
-	msm_cam_clk_enable(&vfe2x_ctrl->pdev->dev, vfe2x_clk_info,
-			vfe2x_ctrl->vfe_clk, ARRAY_SIZE(vfe2x_clk_info), 0);
-	msm_adsp_disable(qcam_mod);
-	msm_adsp_disable(vfe_mod);
-
-	msm_adsp_put(qcam_mod);
-	msm_adsp_put(vfe_mod);
-
-	kfree(extdata);
-	msm_camio_set_perf_lvl(S_EXIT);
-	return;
-}
-
-static int msm_vfe_subdev_s_crystal_freq(struct v4l2_subdev *sd,
-	u32 freq, u32 flags)
-{
-	int rc = 0;
-	int round_rate;
-
-	round_rate = clk_round_rate(vfe2x_ctrl->vfe_clk[0], freq);
-	if (rc < 0) {
-		pr_err("%s: clk_round_rate failed %d\n",
-			__func__, rc);
-		return rc;
-	}
-
-	rc = clk_set_rate(vfe2x_ctrl->vfe_clk[0], round_rate);
-	if (rc < 0)
-		pr_err("%s: clk_set_rate failed %d\n",
-			__func__, rc);
-
-	return rc;
-}
-
-static const struct v4l2_subdev_video_ops msm_vfe_subdev_video_ops = {
-	.s_crystal_freq = msm_vfe_subdev_s_crystal_freq,
-};
-
-static const struct v4l2_subdev_core_ops msm_vfe_subdev_core_ops = {
-	.ioctl = msm_vfe_subdev_ioctl,
-};
-
-static const struct v4l2_subdev_ops msm_vfe_subdev_ops = {
-	.core = &msm_vfe_subdev_core_ops,
-	.video = &msm_vfe_subdev_video_ops,
-};
-
-static const struct v4l2_subdev_internal_ops msm_vfe_internal_ops;
-
-static int __devinit vfe2x_probe(struct platform_device *pdev)
-{
-	struct msm_cam_subdev_info sd_info;
-
-	CDBG("%s: device id = %d\n", __func__, pdev->id);
-	vfe2x_ctrl = kzalloc(sizeof(struct vfe2x_ctrl_type), GFP_KERNEL);
-	if (!vfe2x_ctrl) {
-		pr_err("%s: no enough memory\n", __func__);
-		return -ENOMEM;
-	}
-
-	v4l2_subdev_init(&vfe2x_ctrl->subdev, &msm_vfe_subdev_ops);
-	vfe2x_ctrl->subdev.internal_ops = &msm_vfe_internal_ops;
-	vfe2x_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-	snprintf(vfe2x_ctrl->subdev.name,
-			 sizeof(vfe2x_ctrl->subdev.name), "vfe2.x");
-	v4l2_set_subdevdata(&vfe2x_ctrl->subdev, vfe2x_ctrl);
-	platform_set_drvdata(pdev, &vfe2x_ctrl->subdev);
-
-	vfe2x_ctrl->pdev = pdev;
-	sd_info.sdev_type = VFE_DEV;
-	sd_info.sd_index = 0;
-	sd_info.irq_num = 0;
-	msm_cam_register_subdev_node(&vfe2x_ctrl->subdev, &sd_info);
-
-	media_entity_init(&vfe2x_ctrl->subdev.entity, 0, NULL, 0);
-	vfe2x_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
-	vfe2x_ctrl->subdev.entity.group_id = VFE_DEV;
-	vfe2x_ctrl->subdev.entity.name = pdev->name;
-	vfe2x_ctrl->subdev.entity.revision = vfe2x_ctrl->subdev.devnode->num;
-	return 0;
-}
-
-static struct platform_driver vfe2x_driver = {
-	.probe = vfe2x_probe,
-	.driver = {
-		.name = MSM_VFE_DRV_NAME,
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init msm_vfe2x_init_module(void)
-{
-	return platform_driver_register(&vfe2x_driver);
-}
-
-static void __exit msm_vfe2x_exit_module(void)
-{
-	platform_driver_unregister(&vfe2x_driver);
-}
-
-module_init(msm_vfe2x_init_module);
-module_exit(msm_vfe2x_exit_module);
-MODULE_DESCRIPTION("VFE 2.x driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.h b/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.h
deleted file mode 100644
index 7693235..0000000
--- a/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.h
+++ /dev/null
@@ -1,431 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 __MSM_VFE7X_H__
-#define __MSM_VFE7X_H__
-#include <media/msm_camera.h>
-#include <mach/camera.h>
-#include <linux/list.h>
-#include "msm.h"
-#include "msm_vfe_stats_buf.h"
-
-/*8 DSP buffers, 3 - ping, pong, free*/
-#define FREE_BUF_ARR_SIZE 5
-
-struct cmd_id_map {
-	uint32_t isp_id;
-	uint32_t vfe_id;
-	uint32_t queue;
-	char isp_id_name[64];
-	char vfe_id_name[64];
-} __packed;
-
-struct msg_id_map {
-	uint32_t vfe_id;
-	uint32_t isp_id;
-} __packed;
-
-struct table_cmd {
-	struct list_head list;
-	void *cmd;
-	int size;
-	int queue;
-} __packed;
-
-struct vfe_msg {
-	struct list_head list;
-	void *cmd;
-	int len;
-	int id;
-} __packed;
-
-struct buf_info {
-	/* Buffer */
-	struct msm_free_buf ping;
-	struct msm_free_buf pong;
-	struct msm_free_buf free_buf;
-	/*Array for holding the free buffer if more than one*/
-	struct msm_free_buf free_buf_arr[FREE_BUF_ARR_SIZE];
-	int free_buf_cnt;
-	int frame_cnt;
-} __packed;
-
-struct prev_free_buf_info {
-	struct msm_free_buf buf[3];
-};
-
-struct vfe_cmd_start {
-	uint32_t input_source:1;
-	uint32_t mode_of_operation:1;
-	uint32_t snap_number:4;
-	uint32_t /* reserved */ : 26;
-
-	/* Image Pipeline Modules */
-	uint32_t blacklevel_correction_enable:1;
-	uint32_t lens_rolloff_correction_enable:1;
-	uint32_t white_balance_enable:1;
-	uint32_t rgb_gamma_enable:1;
-	uint32_t luma_noise_reductionpath_enable:1;
-	uint32_t adaptive_spatialfilter_enable:1;
-	uint32_t chroma_subsample_enable:1;
-	uint32_t /* reserved */ : 25;
-
-	/* The dimension fed to the statistics module */
-	uint32_t last_pixel:12;
-	uint32_t /* reserved */ : 4;
-	uint32_t last_line:12;
-	uint32_t /* reserved */ : 4;
-} __packed;
-
-struct vfe2x_ctrl_type {
-	struct buf_info prev;
-	struct buf_info video;
-	struct buf_info snap;
-	struct buf_info raw;
-	struct buf_info thumb;
-	struct prev_free_buf_info free_buf;
-	struct buf_info zsl_prim;
-	struct buf_info zsl_sec;
-	struct prev_free_buf_info zsl_free_buf[2];
-
-
-	spinlock_t  table_lock;
-	struct list_head table_q;
-	uint32_t tableack_pending;
-	uint32_t vfeFrameId;
-
-	spinlock_t vfe_msg_lock;
-	struct list_head vfe_msg_q;
-
-	struct vfe_cmd_start start_cmd;
-	uint32_t start_pending;
-	uint32_t vfe_started;
-	uint32_t stop_pending;
-	uint32_t update_pending;
-
-	spinlock_t liveshot_enabled_lock;
-	uint32_t liveshot_enabled;
-
-	/* v4l2 subdev */
-	struct v4l2_subdev subdev;
-	struct platform_device *pdev;
-	struct clk *vfe_clk[3];
-	spinlock_t  sd_notify_lock;
-	uint32_t    reconfig_vfe;
-	uint32_t    zsl_mode;
-	spinlock_t  stats_bufq_lock;
-	struct msm_stats_bufq_ctrl stats_ctrl;
-	struct msm_stats_ops stats_ops;
-	unsigned long stats_we_buf_ptr[3];
-	unsigned long stats_af_buf_ptr[3];
-	int num_snap;
-} __packed;
-
-struct vfe_frame_extra {
-	uint32_t	bl_evencol:23;
-	uint32_t	rvd1:9;
-	uint32_t	bl_oddcol:23;
-	uint32_t	rvd2:9;
-
-	uint32_t	d_dbpc_stats_hot:16;
-	uint32_t	d_dbpc_stats_cold:16;
-
-	uint32_t	d_dbpc_stats_0_hot:10;
-	uint32_t	rvd3:6;
-	uint32_t	d_dbpc_stats_0_cold:10;
-	uint32_t	rvd4:6;
-	uint32_t	d_dbpc_stats_1_hot:10;
-	uint32_t	rvd5:6;
-	uint32_t	d_dbpc_stats_1_cold:10;
-	uint32_t	rvd6:6;
-
-	uint32_t	asf_max_edge;
-
-	uint32_t	e_y_wm_pm_stats_0:21;
-	uint32_t	rvd7:11;
-	uint32_t	e_y_wm_pm_stats_1_bl:8;
-	uint32_t	rvd8:8;
-	uint32_t	e_y_wm_pm_stats_1_nl:12;
-	uint32_t	rvd9:4;
-
-	uint32_t	e_cbcr_wm_pm_stats_0:21;
-	uint32_t	rvd10:11;
-	uint32_t	e_cbcr_wm_pm_stats_1_bl:8;
-	uint32_t	rvd11:8;
-	uint32_t	e_cbcr_wm_pm_stats_1_nl:12;
-	uint32_t	rvd12:4;
-
-	uint32_t	v_y_wm_pm_stats_0:21;
-	uint32_t	rvd13:11;
-	uint32_t	v_y_wm_pm_stats_1_bl:8;
-	uint32_t	rvd14:8;
-	uint32_t	v_y_wm_pm_stats_1_nl:12;
-	uint32_t	rvd15:4;
-
-	uint32_t	v_cbcr_wm_pm_stats_0:21;
-	uint32_t	rvd16:11;
-	uint32_t	v_cbcr_wm_pm_stats_1_bl:8;
-	uint32_t	rvd17:8;
-	uint32_t	v_cbcr_wm_pm_stats_1_nl:12;
-	uint32_t	rvd18:4;
-
-	uint32_t      frame_id;
-} __packed;
-
-struct vfe_endframe {
-	uint32_t      y_address;
-	uint32_t      cbcr_address;
-
-	struct vfe_frame_extra extra;
-} __packed;
-
-struct vfe_outputack {
-	uint32_t  header;
-	void      *output2newybufferaddress;
-	void      *output2newcbcrbufferaddress;
-} __packed;
-
-struct vfe_stats_ack {
-	uint32_t header;
-	/* MUST BE 64 bit ALIGNED */
-	void     *bufaddr;
-} __packed;
-
-/* AXI Output Config Command sent to DSP */
-struct axiout {
-	uint32_t            cmdheader:32;
-	int                 outputmode:3;
-	uint8_t             format:2;
-	uint32_t            /* reserved */ : 27;
-
-	/* AXI Output 1 Y Configuration, Part 1 */
-	uint32_t            out1yimageheight:12;
-	uint32_t            /* reserved */ : 4;
-	uint32_t            out1yimagewidthin64bitwords:10;
-	uint32_t            /* reserved */ : 6;
-
-	/* AXI Output 1 Y Configuration, Part 2 */
-	uint8_t             out1yburstlen:2;
-	uint32_t            out1ynumrows:12;
-	uint32_t            out1yrowincin64bitincs:12;
-	uint32_t            /* reserved */ : 6;
-
-	/* AXI Output 1 CbCr Configuration, Part 1 */
-	uint32_t            out1cbcrimageheight:12;
-	uint32_t            /* reserved */ : 4;
-	uint32_t            out1cbcrimagewidthin64bitwords:10;
-	uint32_t            /* reserved */ : 6;
-
-	/* AXI Output 1 CbCr Configuration, Part 2 */
-	uint8_t             out1cbcrburstlen:2;
-	uint32_t            out1cbcrnumrows:12;
-	uint32_t            out1cbcrrowincin64bitincs:12;
-	uint32_t            /* reserved */ : 6;
-
-	/* AXI Output 2 Y Configuration, Part 1 */
-	uint32_t            out2yimageheight:12;
-	uint32_t            /* reserved */ : 4;
-	uint32_t            out2yimagewidthin64bitwords:10;
-	uint32_t            /* reserved */ : 6;
-
-	/* AXI Output 2 Y Configuration, Part 2 */
-	uint8_t             out2yburstlen:2;
-	uint32_t            out2ynumrows:12;
-	uint32_t            out2yrowincin64bitincs:12;
-	uint32_t            /* reserved */ : 6;
-
-	/* AXI Output 2 CbCr Configuration, Part 1 */
-	uint32_t            out2cbcrimageheight:12;
-	uint32_t            /* reserved */ : 4;
-	uint32_t            out2cbcrimagewidtein64bitwords:10;
-	uint32_t            /* reserved */ : 6;
-
-	/* AXI Output 2 CbCr Configuration, Part 2 */
-	uint8_t             out2cbcrburstlen:2;
-	uint32_t            out2cbcrnumrows:12;
-	uint32_t            out2cbcrrowincin64bitincs:12;
-	uint32_t            /* reserved */ : 6;
-
-	/* Address configuration:
-	 * output1 phisycal address */
-	unsigned long   output1buffer1_y_phy;
-	unsigned long   output1buffer1_cbcr_phy;
-	unsigned long   output1buffer2_y_phy;
-	unsigned long   output1buffer2_cbcr_phy;
-	unsigned long   output1buffer3_y_phy;
-	unsigned long   output1buffer3_cbcr_phy;
-	unsigned long   output1buffer4_y_phy;
-	unsigned long   output1buffer4_cbcr_phy;
-	unsigned long   output1buffer5_y_phy;
-	unsigned long   output1buffer5_cbcr_phy;
-	unsigned long   output1buffer6_y_phy;
-	unsigned long   output1buffer6_cbcr_phy;
-	unsigned long   output1buffer7_y_phy;
-	unsigned long   output1buffer7_cbcr_phy;
-	unsigned long   output1buffer8_y_phy;
-	unsigned long   output1buffer8_cbcr_phy;
-
-	/* output2 phisycal address */
-	unsigned long   output2buffer1_y_phy;
-	unsigned long   output2buffer1_cbcr_phy;
-	unsigned long   output2buffer2_y_phy;
-	unsigned long   output2buffer2_cbcr_phy;
-	unsigned long   output2buffer3_y_phy;
-	unsigned long   output2buffer3_cbcr_phy;
-	unsigned long   output2buffer4_y_phy;
-	unsigned long   output2buffer4_cbcr_phy;
-	unsigned long   output2buffer5_y_phy;
-	unsigned long   output2buffer5_cbcr_phy;
-	unsigned long   output2buffer6_y_phy;
-	unsigned long   output2buffer6_cbcr_phy;
-	unsigned long   output2buffer7_y_phy;
-	unsigned long   output2buffer7_cbcr_phy;
-	unsigned long   output2buffer8_y_phy;
-	unsigned long   output2buffer8_cbcr_phy;
-} __packed;
-
-struct vfe_stats_we_cfg {
-	uint32_t       header;
-
-	/* White Balance/Exposure Statistic Selection */
-	uint8_t        wb_expstatsenable:1;
-	uint8_t        wb_expstatbuspriorityselection:1;
-	unsigned int   wb_expstatbuspriorityvalue:4;
-	unsigned int   /* reserved */ : 26;
-
-	/* White Balance/Exposure Statistic Configuration, Part 1 */
-	uint8_t        exposurestatregions:1;
-	uint8_t        exposurestatsubregions:1;
-	unsigned int   /* reserved */ : 14;
-
-	unsigned int   whitebalanceminimumy:8;
-	unsigned int   whitebalancemaximumy:8;
-
-	/* White Balance/Exposure Statistic Configuration, Part 2 */
-	uint8_t wb_expstatslopeofneutralregionline[
-		NUM_WB_EXP_NEUTRAL_REGION_LINES];
-
-	/* White Balance/Exposure Statistic Configuration, Part 3 */
-	unsigned int   wb_expstatcrinterceptofneutralregionline2:12;
-	unsigned int   /* reserved */ : 4;
-	unsigned int   wb_expstatcbinterceptofneutralreginnline1:12;
-	unsigned int    /* reserved */ : 4;
-
-	/* White Balance/Exposure Statistic Configuration, Part 4 */
-	unsigned int   wb_expstatcrinterceptofneutralregionline4:12;
-	unsigned int   /* reserved */ : 4;
-	unsigned int   wb_expstatcbinterceptofneutralregionline3:12;
-	unsigned int   /* reserved */ : 4;
-
-	/* White Balance/Exposure Statistic Output Buffer Header */
-	unsigned int   wb_expmetricheaderpattern:8;
-	unsigned int   /* reserved */ : 24;
-
-	/* White Balance/Exposure Statistic Output Buffers-MUST
-	* BE 64 bit ALIGNED */
-	void  *wb_expstatoutputbuffer[NUM_WB_EXP_STAT_OUTPUT_BUFFERS];
-} __packed;
-
-struct vfe_stats_af_cfg {
-	uint32_t header;
-
-	/* Autofocus Statistic Selection */
-	uint8_t       af_enable:1;
-	uint8_t       af_busprioritysel:1;
-	unsigned int  af_buspriorityval:4;
-	unsigned int  /* reserved */ : 26;
-
-	/* Autofocus Statistic Configuration, Part 1 */
-	unsigned int  af_singlewinvoffset:12;
-	unsigned int  /* reserved */ : 4;
-	unsigned int  af_singlewinhoffset:12;
-	unsigned int  /* reserved */ : 3;
-	uint8_t       af_winmode:1;
-
-	/* Autofocus Statistic Configuration, Part 2 */
-	unsigned int  af_singglewinvh:11;
-	unsigned int  /* reserved */ : 5;
-	unsigned int  af_singlewinhw:11;
-	unsigned int  /* reserved */ : 5;
-
-	/* Autofocus Statistic Configuration, Parts 3-6 */
-	uint8_t       af_multiwingrid[NUM_AUTOFOCUS_MULTI_WINDOW_GRIDS];
-
-	/* Autofocus Statistic Configuration, Part 7 */
-	signed int    af_metrichpfcoefa00:5;
-	signed int    af_metrichpfcoefa04:5;
-	unsigned int  af_metricmaxval:11;
-	uint8_t       af_metricsel:1;
-	unsigned int  /* reserved */ : 10;
-
-	/* Autofocus Statistic Configuration, Part 8 */
-	signed int    af_metrichpfcoefa20:5;
-	signed int    af_metrichpfcoefa21:5;
-	signed int    af_metrichpfcoefa22:5;
-	signed int    af_metrichpfcoefa23:5;
-	signed int    af_metrichpfcoefa24:5;
-	unsigned int  /* reserved */ : 7;
-
-	/* Autofocus Statistic Output Buffer Header */
-	unsigned int  af_metrichp:8;
-	unsigned int  /* reserved */ : 24;
-
-	/* Autofocus Statistic Output Buffers - MUST BE 64 bit ALIGNED!!! */
-	void *af_outbuf[NUM_AF_STAT_OUTPUT_BUFFERS];
-} __packed; /* VFE_StatsAutofocusConfigCmdType */
-
-struct msm_camera_frame_msg {
-	unsigned long   output_y_address;
-	unsigned long   output_cbcr_address;
-
-	unsigned int    blacklevelevenColumn:23;
-	uint16_t        reserved1:9;
-	unsigned int    blackleveloddColumn:23;
-	uint16_t        reserved2:9;
-
-	uint16_t        greendefectpixelcount:8;
-	uint16_t        reserved3:8;
-	uint16_t        redbluedefectpixelcount:8;
-	uint16_t        reserved4:8;
-} __packed;
-
-/* New one for 7k */
-struct msm_vfe_command_7k {
-	uint16_t queue;
-	uint16_t length;
-	void     *value;
-};
-
-struct stop_event {
-	wait_queue_head_t wait;
-	int state;
-	int timeout;
-};
-struct vfe_error_msg {
-	unsigned int camif_error:1;
-	unsigned int output1ybusoverflow:1;
-	unsigned int output1cbcrbusoverflow:1;
-	unsigned int output2ybusoverflow:1;
-	unsigned int output2cbcrbusoverflow:1;
-	unsigned int autofocusstatbusoverflow:1;
-	unsigned int wb_expstatbusoverflow:1;
-	unsigned int axierror:1;
-	unsigned int /* reserved */ : 24;
-	unsigned int camif_staus:1;
-	unsigned int pixel_count:14;
-	unsigned int line_count:14;
-	unsigned int /*reserved */ : 3;
-} __packed;
-
-static struct msm_free_buf *vfe2x_check_free_buffer(int id, int path);
-
-#endif /* __MSM_VFE7X_H__ */
diff --git a/drivers/media/video/msm/vfe/msm_vfe8x.c b/drivers/media/video/msm/vfe/msm_vfe8x.c
deleted file mode 100644
index 38011ba..0000000
--- a/drivers/media/video/msm/vfe/msm_vfe8x.c
+++ /dev/null
@@ -1,843 +0,0 @@
-/* Copyright (c) 2009, 2012, Code Aurora Forum. 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/uaccess.h>
-#include <linux/interrupt.h>
-#include <mach/irqs.h>
-#include "msm_vfe8x_proc.h"
-#include <linux/pm_qos.h>
-
-#define ON  1
-#define OFF 0
-
-static const char *vfe_general_cmd[] = {
-	"START",  /* 0 */
-	"RESET",
-	"AXI_INPUT_CONFIG",
-	"CAMIF_CONFIG",
-	"AXI_OUTPUT_CONFIG",
-	"BLACK_LEVEL_CONFIG",  /* 5 */
-	"ROLL_OFF_CONFIG",
-	"DEMUX_CHANNEL_GAIN_CONFIG",
-	"DEMOSAIC_CONFIG",
-	"FOV_CROP_CONFIG",
-	"MAIN_SCALER_CONFIG",  /* 10 */
-	"WHITE_BALANCE_CONFIG",
-	"COLOR_CORRECTION_CONFIG",
-	"LA_CONFIG",
-	"RGB_GAMMA_CONFIG",
-	"CHROMA_ENHAN_CONFIG",  /* 15 */
-	"CHROMA_SUPPRESSION_CONFIG",
-	"ASF_CONFIG",
-	"SCALER2Y_CONFIG",
-	"SCALER2CbCr_CONFIG",
-	"CHROMA_SUBSAMPLE_CONFIG",  /* 20 */
-	"FRAME_SKIP_CONFIG",
-	"OUTPUT_CLAMP_CONFIG",
-	"TEST_GEN_START",
-	"UPDATE",
-	"OUTPUT1_ACK",  /* 25 */
-	"OUTPUT2_ACK",
-	"EPOCH1_ACK",
-	"EPOCH2_ACK",
-	"STATS_AUTOFOCUS_ACK",
-	"STATS_WB_EXP_ACK",  /* 30 */
-	"BLACK_LEVEL_UPDATE",
-	"DEMUX_CHANNEL_GAIN_UPDATE",
-	"DEMOSAIC_BPC_UPDATE",
-	"DEMOSAIC_ABF_UPDATE",
-	"FOV_CROP_UPDATE",  /* 35 */
-	"WHITE_BALANCE_UPDATE",
-	"COLOR_CORRECTION_UPDATE",
-	"LA_UPDATE",
-	"RGB_GAMMA_UPDATE",
-	"CHROMA_ENHAN_UPDATE",  /* 40 */
-	"CHROMA_SUPPRESSION_UPDATE",
-	"MAIN_SCALER_UPDATE",
-	"SCALER2CbCr_UPDATE",
-	"SCALER2Y_UPDATE",
-	"ASF_UPDATE",  /* 45 */
-	"FRAME_SKIP_UPDATE",
-	"CAMIF_FRAME_UPDATE",
-	"STATS_AUTOFOCUS_UPDATE",
-	"STATS_WB_EXP_UPDATE",
-	"STOP",  /* 50 */
-	"GET_HW_VERSION",
-	"STATS_SETTING",
-	"STATS_AUTOFOCUS_START",
-	"STATS_AUTOFOCUS_STOP",
-	"STATS_WB_EXP_START",  /* 55 */
-	"STATS_WB_EXP_STOP",
-	"ASYNC_TIMER_SETTING",
-};
-
-static void     *vfe_syncdata;
-
-static int vfe_enable(struct camera_enable_cmd *enable)
-{
-	return 0;
-}
-
-static int vfe_disable(struct camera_enable_cmd *enable,
-	struct platform_device *dev)
-{
-	vfe_stop();
-	msm_camio_disable(dev);
-	return 0;
-}
-
-static void vfe_release(struct platform_device *dev)
-{
-	msm_camio_disable(dev);
-	vfe_cmd_release(dev);
-	update_axi_qos(PM_QOS_DEFAULT_VALUE);
-	vfe_syncdata = NULL;
-}
-
-static void vfe_config_axi(int mode,
-			   struct axidata *ad,
-			   struct vfe_cmd_axi_output_config *ao)
-{
-	struct msm_pmem_region *regptr, *regptr1;
-	int i, j;
-	uint32_t *p1, *p2;
-
-	if (mode == OUTPUT_1 || mode == OUTPUT_1_AND_2) {
-		regptr = ad->region;
-		for (i = 0; i < ad->bufnum1; i++) {
-
-			p1 = &(ao->output1.outputY.outFragments[i][0]);
-			p2 = &(ao->output1.outputCbcr.outFragments[i][0]);
-
-			for (j = 0; j < ao->output1.fragmentCount; j++) {
-
-				*p1 = regptr->paddr + regptr->info.planar0_off;
-				p1++;
-
-				*p2 = regptr->paddr + regptr->info.planar1_off;
-				p2++;
-			}
-			regptr++;
-		}
-	} /* if OUTPUT1 or Both */
-
-	if (mode == OUTPUT_2 || mode == OUTPUT_1_AND_2) {
-
-		regptr = &(ad->region[ad->bufnum1]);
-		CDBG("bufnum2 = %d\n", ad->bufnum2);
-
-		for (i = 0; i < ad->bufnum2; i++) {
-
-			p1 = &(ao->output2.outputY.outFragments[i][0]);
-			p2 = &(ao->output2.outputCbcr.outFragments[i][0]);
-
-			CDBG("config_axi: O2, phy = 0x%lx, y_off = %d, "\
-			     "cbcr_off = %d\n", regptr->paddr,
-				regptr->info.planar0_off,
-				regptr->info.planar1_off);
-
-			for (j = 0; j < ao->output2.fragmentCount; j++) {
-
-				*p1 = regptr->paddr + regptr->info.planar0_off;
-				CDBG("vfe_config_axi: p1 = 0x%x\n", *p1);
-				p1++;
-
-				*p2 = regptr->paddr + regptr->info.planar1_off;
-				CDBG("vfe_config_axi: p2 = 0x%x\n", *p2);
-				p2++;
-			}
-			regptr++;
-		}
-	}
-	/* For video configuration */
-	if (mode == OUTPUT_1_AND_3) {
-		/* this is preview buffer. */
-		regptr =  &(ad->region[0]);
-		/* this is video buffer. */
-		regptr1 = &(ad->region[ad->bufnum1]);
-		CDBG("bufnum1 = %d\n", ad->bufnum1);
-		CDBG("bufnum2 = %d\n", ad->bufnum2);
-
-	for (i = 0; i < ad->bufnum1; i++) {
-		p1 = &(ao->output1.outputY.outFragments[i][0]);
-		p2 = &(ao->output1.outputCbcr.outFragments[i][0]);
-
-		CDBG("config_axi: O1, phy = 0x%lx, y_off = %d, "\
-			 "cbcr_off = %d\n", regptr->paddr,
-			 regptr->info.planar0_off, regptr->info.planar1_off);
-
-			for (j = 0; j < ao->output1.fragmentCount; j++) {
-
-				*p1 = regptr->paddr + regptr->info.planar0_off;
-				CDBG("vfe_config_axi: p1 = 0x%x\n", *p1);
-				p1++;
-
-				*p2 = regptr->paddr + regptr->info.planar1_off;
-				CDBG("vfe_config_axi: p2 = 0x%x\n", *p2);
-				p2++;
-			}
-			regptr++;
-		}
-	for (i = 0; i < ad->bufnum2; i++) {
-		p1 = &(ao->output2.outputY.outFragments[i][0]);
-		p2 = &(ao->output2.outputCbcr.outFragments[i][0]);
-
-		CDBG("config_axi: O2, phy = 0x%lx, y_off = %d, "\
-			 "cbcr_off = %d\n", regptr1->paddr,
-			 regptr1->info.planar0_off, regptr1->info.planar1_off);
-
-			for (j = 0; j < ao->output2.fragmentCount; j++) {
-				*p1 = regptr1->paddr +
-					regptr1->info.planar0_off;
-				CDBG("vfe_config_axi: p1 = 0x%x\n", *p1);
-				p1++;
-				*p2 = regptr1->paddr +
-					r1->info.planar1_off;
-				CDBG("vfe_config_axi: p2 = 0x%x\n", *p2);
-				p2++;
-			}
-			regptr1++;
-		}
-	}
-
-}
-
-#define CHECKED_COPY_FROM_USER(in) {					\
-	if (cmd->length != sizeof(*(in))) {				\
-		pr_err("msm_camera: %s:%d cmd %d: user data size %d "	\
-			"!= kernel data size %d\n",			\
-			__func__, __LINE__,				\
-			cmd->id, cmd->length, sizeof(*(in)));		\
-		rc = -EIO;						\
-		break;							\
-	}								\
-	if (copy_from_user((in), (void __user *)cmd->value,		\
-			sizeof(*(in)))) {				\
-		rc = -EFAULT;						\
-		break;							\
-	}								\
-}
-
-static int vfe_proc_general(struct msm_vfe_command_8k *cmd)
-{
-	int rc = 0;
-
-	CDBG("%s: cmdID = %s\n", __func__, vfe_general_cmd[cmd->id]);
-
-	switch (cmd->id) {
-	case VFE_CMD_ID_RESET:
-		msm_camio_vfe_blk_reset();
-		msm_camio_camif_pad_reg_reset_2();
-		vfe_reset();
-		break;
-
-	case VFE_CMD_ID_START: {
-		struct vfe_cmd_start start;
-			CHECKED_COPY_FROM_USER(&start);
-
-		/* msm_camio_camif_pad_reg_reset_2(); */
-		msm_camio_camif_pad_reg_reset();
-		vfe_start(&start);
-	}
-		break;
-
-	case VFE_CMD_ID_CAMIF_CONFIG: {
-		struct vfe_cmd_camif_config camif;
-			CHECKED_COPY_FROM_USER(&camif);
-
-		vfe_camif_config(&camif);
-	}
-		break;
-
-	case VFE_CMD_ID_BLACK_LEVEL_CONFIG: {
-		struct vfe_cmd_black_level_config bl;
-			CHECKED_COPY_FROM_USER(&bl);
-
-		vfe_black_level_config(&bl);
-	}
-		break;
-
-	case VFE_CMD_ID_ROLL_OFF_CONFIG:{
-			/* rolloff is too big to be on the stack */
-			struct vfe_cmd_roll_off_config *rolloff =
-			    kmalloc(sizeof(struct vfe_cmd_roll_off_config),
-				    GFP_KERNEL);
-			if (!rolloff) {
-				pr_err("%s: out of memory\n", __func__);
-				rc = -ENOMEM;
-				break;
-			}
-			/* Wrap CHECKED_COPY_FROM_USER() in a do-while(0) loop
-			 * to make sure we free rolloff when copy_from_user()
-			 * fails.
-			 */
-			do {
-				CHECKED_COPY_FROM_USER(rolloff);
-				vfe_roll_off_config(rolloff);
-			} while (0);
-			kfree(rolloff);
-	}
-		break;
-
-	case VFE_CMD_ID_DEMUX_CHANNEL_GAIN_CONFIG: {
-		struct vfe_cmd_demux_channel_gain_config demuxc;
-			CHECKED_COPY_FROM_USER(&demuxc);
-
-		/* demux is always enabled.  */
-		vfe_demux_channel_gain_config(&demuxc);
-	}
-		break;
-
-	case VFE_CMD_ID_DEMOSAIC_CONFIG: {
-		struct vfe_cmd_demosaic_config demosaic;
-			CHECKED_COPY_FROM_USER(&demosaic);
-
-		vfe_demosaic_config(&demosaic);
-	}
-		break;
-
-	case VFE_CMD_ID_FOV_CROP_CONFIG:
-	case VFE_CMD_ID_FOV_CROP_UPDATE: {
-		struct vfe_cmd_fov_crop_config fov;
-			CHECKED_COPY_FROM_USER(&fov);
-
-		vfe_fov_crop_config(&fov);
-	}
-		break;
-
-	case VFE_CMD_ID_MAIN_SCALER_CONFIG:
-	case VFE_CMD_ID_MAIN_SCALER_UPDATE: {
-		struct vfe_cmd_main_scaler_config mainds;
-			CHECKED_COPY_FROM_USER(&mainds);
-
-		vfe_main_scaler_config(&mainds);
-	}
-		break;
-
-	case VFE_CMD_ID_WHITE_BALANCE_CONFIG:
-	case VFE_CMD_ID_WHITE_BALANCE_UPDATE: {
-		struct vfe_cmd_white_balance_config wb;
-			CHECKED_COPY_FROM_USER(&wb);
-
-		vfe_white_balance_config(&wb);
-	}
-		break;
-
-	case VFE_CMD_ID_COLOR_CORRECTION_CONFIG:
-	case VFE_CMD_ID_COLOR_CORRECTION_UPDATE: {
-		struct vfe_cmd_color_correction_config cc;
-			CHECKED_COPY_FROM_USER(&cc);
-
-		vfe_color_correction_config(&cc);
-	}
-		break;
-
-	case VFE_CMD_ID_LA_CONFIG: {
-		struct vfe_cmd_la_config la;
-			CHECKED_COPY_FROM_USER(&la);
-
-		vfe_la_config(&la);
-	}
-		break;
-
-	case VFE_CMD_ID_RGB_GAMMA_CONFIG: {
-		struct vfe_cmd_rgb_gamma_config rgb;
-			CHECKED_COPY_FROM_USER(&rgb);
-
-		rc = vfe_rgb_gamma_config(&rgb);
-	}
-		break;
-
-	case VFE_CMD_ID_CHROMA_ENHAN_CONFIG:
-	case VFE_CMD_ID_CHROMA_ENHAN_UPDATE: {
-		struct vfe_cmd_chroma_enhan_config chrom;
-			CHECKED_COPY_FROM_USER(&chrom);
-
-		vfe_chroma_enhan_config(&chrom);
-	}
-		break;
-
-	case VFE_CMD_ID_CHROMA_SUPPRESSION_CONFIG:
-	case VFE_CMD_ID_CHROMA_SUPPRESSION_UPDATE: {
-		struct vfe_cmd_chroma_suppression_config chromsup;
-			CHECKED_COPY_FROM_USER(&chromsup);
-
-		vfe_chroma_sup_config(&chromsup);
-	}
-		break;
-
-	case VFE_CMD_ID_ASF_CONFIG: {
-		struct vfe_cmd_asf_config asf;
-			CHECKED_COPY_FROM_USER(&asf);
-
-		vfe_asf_config(&asf);
-	}
-		break;
-
-	case VFE_CMD_ID_SCALER2Y_CONFIG:
-	case VFE_CMD_ID_SCALER2Y_UPDATE: {
-		struct vfe_cmd_scaler2_config ds2y;
-			CHECKED_COPY_FROM_USER(&ds2y);
-
-		vfe_scaler2y_config(&ds2y);
-	}
-		break;
-
-	case VFE_CMD_ID_SCALER2CbCr_CONFIG:
-	case VFE_CMD_ID_SCALER2CbCr_UPDATE: {
-		struct vfe_cmd_scaler2_config ds2cbcr;
-			CHECKED_COPY_FROM_USER(&ds2cbcr);
-
-		vfe_scaler2cbcr_config(&ds2cbcr);
-	}
-		break;
-
-	case VFE_CMD_ID_CHROMA_SUBSAMPLE_CONFIG: {
-		struct vfe_cmd_chroma_subsample_config sub;
-			CHECKED_COPY_FROM_USER(&sub);
-
-		vfe_chroma_subsample_config(&sub);
-	}
-		break;
-
-	case VFE_CMD_ID_FRAME_SKIP_CONFIG: {
-		struct vfe_cmd_frame_skip_config fskip;
-			CHECKED_COPY_FROM_USER(&fskip);
-
-		vfe_frame_skip_config(&fskip);
-	}
-		break;
-
-	case VFE_CMD_ID_OUTPUT_CLAMP_CONFIG: {
-		struct vfe_cmd_output_clamp_config clamp;
-			CHECKED_COPY_FROM_USER(&clamp);
-
-		vfe_output_clamp_config(&clamp);
-	}
-		break;
-
-	/* module update commands */
-	case VFE_CMD_ID_BLACK_LEVEL_UPDATE: {
-		struct vfe_cmd_black_level_config blk;
-			CHECKED_COPY_FROM_USER(&blk);
-
-		vfe_black_level_update(&blk);
-	}
-		break;
-
-	case VFE_CMD_ID_DEMUX_CHANNEL_GAIN_UPDATE: {
-		struct vfe_cmd_demux_channel_gain_config dmu;
-			CHECKED_COPY_FROM_USER(&dmu);
-
-		vfe_demux_channel_gain_update(&dmu);
-	}
-		break;
-
-	case VFE_CMD_ID_DEMOSAIC_BPC_UPDATE: {
-		struct vfe_cmd_demosaic_bpc_update demo_bpc;
-			CHECKED_COPY_FROM_USER(&demo_bpc);
-
-		vfe_demosaic_bpc_update(&demo_bpc);
-	}
-		break;
-
-	case VFE_CMD_ID_DEMOSAIC_ABF_UPDATE: {
-		struct vfe_cmd_demosaic_abf_update demo_abf;
-			CHECKED_COPY_FROM_USER(&demo_abf);
-
-		vfe_demosaic_abf_update(&demo_abf);
-	}
-		break;
-
-	case VFE_CMD_ID_LA_UPDATE: {
-		struct vfe_cmd_la_config la;
-			CHECKED_COPY_FROM_USER(&la);
-
-		vfe_la_update(&la);
-	}
-		break;
-
-	case VFE_CMD_ID_RGB_GAMMA_UPDATE: {
-		struct vfe_cmd_rgb_gamma_config rgb;
-			CHECKED_COPY_FROM_USER(&rgb);
-
-		rc = vfe_rgb_gamma_update(&rgb);
-	}
-		break;
-
-	case VFE_CMD_ID_ASF_UPDATE: {
-		struct vfe_cmd_asf_update asf;
-			CHECKED_COPY_FROM_USER(&asf);
-
-		vfe_asf_update(&asf);
-	}
-		break;
-
-	case VFE_CMD_ID_FRAME_SKIP_UPDATE: {
-		struct vfe_cmd_frame_skip_update fskip;
-			CHECKED_COPY_FROM_USER(&fskip);
-			/* Start recording */
-			if (fskip.output2Pattern == 0xffffffff)
-				update_axi_qos(MSM_AXI_QOS_RECORDING);
-			 else if (fskip.output2Pattern == 0)
-				update_axi_qos(MSM_AXI_QOS_PREVIEW);
-
-		vfe_frame_skip_update(&fskip);
-	}
-		break;
-
-	case VFE_CMD_ID_CAMIF_FRAME_UPDATE: {
-		struct vfe_cmds_camif_frame fup;
-			CHECKED_COPY_FROM_USER(&fup);
-
-		vfe_camif_frame_update(&fup);
-	}
-		break;
-
-	/* stats update commands */
-	case VFE_CMD_ID_STATS_AUTOFOCUS_UPDATE: {
-		struct vfe_cmd_stats_af_update afup;
-			CHECKED_COPY_FROM_USER(&afup);
-
-		vfe_stats_update_af(&afup);
-	}
-		break;
-
-	case VFE_CMD_ID_STATS_WB_EXP_UPDATE: {
-		struct vfe_cmd_stats_wb_exp_update wbexp;
-			CHECKED_COPY_FROM_USER(&wbexp);
-
-		vfe_stats_update_wb_exp(&wbexp);
-	}
-		break;
-
-	/* control of start, stop, update, etc... */
-	case VFE_CMD_ID_STOP:
-		vfe_stop();
-		break;
-
-	case VFE_CMD_ID_GET_HW_VERSION:
-		break;
-
-	/* stats */
-	case VFE_CMD_ID_STATS_SETTING: {
-		struct vfe_cmd_stats_setting stats;
-			CHECKED_COPY_FROM_USER(&stats);
-
-		vfe_stats_setting(&stats);
-	}
-		break;
-
-	case VFE_CMD_ID_STATS_AUTOFOCUS_START: {
-		struct vfe_cmd_stats_af_start af;
-			CHECKED_COPY_FROM_USER(&af);
-
-		vfe_stats_start_af(&af);
-	}
-		break;
-
-	case VFE_CMD_ID_STATS_AUTOFOCUS_STOP:
-		vfe_stats_af_stop();
-		break;
-
-	case VFE_CMD_ID_STATS_WB_EXP_START: {
-		struct vfe_cmd_stats_wb_exp_start awexp;
-			CHECKED_COPY_FROM_USER(&awexp);
-
-		vfe_stats_start_wb_exp(&awexp);
-	}
-		break;
-
-	case VFE_CMD_ID_STATS_WB_EXP_STOP:
-		vfe_stats_wb_exp_stop();
-		break;
-
-	case VFE_CMD_ID_ASYNC_TIMER_SETTING:
-		break;
-
-	case VFE_CMD_ID_UPDATE:
-		vfe_update();
-		break;
-
-	/* test gen */
-	case VFE_CMD_ID_TEST_GEN_START:
-		break;
-
-/*
-  acknowledge from upper layer
-	these are not in general command.
-
-	case VFE_CMD_ID_OUTPUT1_ACK:
-		break;
-	case VFE_CMD_ID_OUTPUT2_ACK:
-		break;
-	case VFE_CMD_ID_EPOCH1_ACK:
-		break;
-	case VFE_CMD_ID_EPOCH2_ACK:
-		break;
-	case VFE_CMD_ID_STATS_AUTOFOCUS_ACK:
-		break;
-	case VFE_CMD_ID_STATS_WB_EXP_ACK:
-		break;
-*/
-
-	default:
-		pr_err("%s: invalid cmd id %d\n", __func__, cmd->id);
-		rc = -EINVAL;
-		break;
-	} /* switch */
-
-	return rc;
-}
-
-static int vfe_config(struct msm_vfe_cfg_cmd *cmd, void *data)
-{
-	struct msm_pmem_region *regptr;
-	struct msm_vfe_command_8k vfecmd;
-	struct vfe_cmd_axi_output_config axio;
-	struct axidata *axid = data;
-
-	int rc = 0;
-
-
-	if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
-		cmd->cmd_type != CMD_STATS_BUF_RELEASE &&
-		cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE) {
-
-		if (copy_from_user(&vfecmd,
-			(void __user *)(cmd->value), sizeof(vfecmd))) {
-			pr_err("%s %d: copy_from_user failed\n",
-				__func__, __LINE__);
-			return -EFAULT;
-		}
-	}
-
-	CDBG("%s: cmdType = %d\n", __func__, cmd->cmd_type);
-
-	switch (cmd->cmd_type) {
-	case CMD_GENERAL:
-		rc = vfe_proc_general(&vfecmd);
-		break;
-
-	case CMD_STATS_ENABLE:
-	case CMD_STATS_AXI_CFG: {
-			int i;
-			struct vfe_cmd_stats_setting scfg;
-
-			BUG_ON(!axid);
-
-			if (vfecmd.length != sizeof(scfg)) {
-				pr_err
-				("msm_camera: %s: cmd %d: user-space "\
-				"data size %d != kernel data size %d\n",
-				__func__,
-				cmd->cmd_type, vfecmd.length,
-				sizeof(scfg));
-				return -EIO;
-			}
-
-			if (copy_from_user(&scfg,
-				(void __user *)(vfecmd.value),
-				sizeof(scfg))) {
-				pr_err("%s %d: copy_from_user failed\n",
-				__func__, __LINE__);
-			return -EFAULT;
-		}
-
-		regptr = axid->region;
-		if (axid->bufnum1 > 0) {
-			for (i = 0; i < axid->bufnum1; i++) {
-					scfg.awbBuffer[i] =
-					(uint32_t)(regptr->paddr);
-				regptr++;
-			}
-		}
-
-		if (axid->bufnum2 > 0) {
-			for (i = 0; i < axid->bufnum2; i++) {
-					scfg.afBuffer[i] =
-					(uint32_t)(regptr->paddr);
-				regptr++;
-			}
-		}
-
-			vfe_stats_setting(&scfg);
-	}
-		break;
-
-	case CMD_STATS_AF_AXI_CFG:
-		break;
-
-	case CMD_FRAME_BUF_RELEASE: {
-		/* preview buffer release */
-		struct msm_frame *b;
-		unsigned long p;
-		struct vfe_cmd_output_ack fack;
-
-			BUG_ON(!data);
-
-		b = (struct msm_frame *)(cmd->value);
-		p = *(unsigned long *)data;
-
-			fack.ybufaddr[0] = (uint32_t) (p + b->planar0_off);
-
-			fack.chromabufaddr[0] = (uint32_t) (p + b->planar1_off);
-
-		if (b->path == OUTPUT_TYPE_P)
-			vfe_output_p_ack(&fack);
-
-		if ((b->path == OUTPUT_TYPE_V)
-			 || (b->path == OUTPUT_TYPE_S))
-			vfe_output_v_ack(&fack);
-	}
-		break;
-
-	case CMD_SNAP_BUF_RELEASE:
-		break;
-
-	case CMD_STATS_BUF_RELEASE: {
-		struct vfe_cmd_stats_wb_exp_ack sack;
-
-			BUG_ON(!data);
-
-		sack.nextWbExpOutputBufferAddr = *(uint32_t *)data;
-		vfe_stats_wb_exp_ack(&sack);
-	}
-		break;
-
-	case CMD_STATS_AF_BUF_RELEASE: {
-		struct vfe_cmd_stats_af_ack ack;
-
-			BUG_ON(!data);
-
-		ack.nextAFOutputBufferAddr = *(uint32_t *)data;
-		vfe_stats_af_ack(&ack);
-	}
-		break;
-
-	case CMD_AXI_CFG_PREVIEW:
-	case CMD_RAW_PICT_AXI_CFG: {
-
-			BUG_ON(!axid);
-
-			if (copy_from_user(&axio, (void __user *)(vfecmd.value),
-				sizeof(axio))) {
-				pr_err("%s %d: copy_from_user failed\n",
-					__func__, __LINE__);
-			return -EFAULT;
-		}
-			/* Validate the data from user space */
-			if (axio.output2.fragmentCount <
-				VFE_MIN_NUM_FRAGMENTS_PER_FRAME ||
-				axio.output2.fragmentCount >
-				VFE_MAX_NUM_FRAGMENTS_PER_FRAME)
-				return -EINVAL;
-
-			vfe_config_axi(OUTPUT_2, axid, &axio);
-			axio.outputDataSize = 0;
-			vfe_axi_output_config(&axio);
-	}
-		break;
-
-	case CMD_AXI_CFG_SNAP: {
-
-			BUG_ON(!axid);
-
-			if (copy_from_user(&axio, (void __user *)(vfecmd.value),
-				sizeof(axio))) {
-				pr_err("%s %d: copy_from_user failed\n",
-					__func__, __LINE__);
-			return -EFAULT;
-		}
-			/* Validate the data from user space */
-			if (axio.output1.fragmentCount <
-				VFE_MIN_NUM_FRAGMENTS_PER_FRAME ||
-				axio.output1.fragmentCount >
-				VFE_MAX_NUM_FRAGMENTS_PER_FRAME ||
-				axio.output2.fragmentCount <
-				VFE_MIN_NUM_FRAGMENTS_PER_FRAME ||
-				axio.output2.fragmentCount >
-				VFE_MAX_NUM_FRAGMENTS_PER_FRAME)
-				return -EINVAL;
-
-			vfe_config_axi(OUTPUT_1_AND_2, axid, &axio);
-			vfe_axi_output_config(&axio);
-	}
-		break;
-
-	case CMD_AXI_CFG_VIDEO: {
-			BUG_ON(!axid);
-
-			if (copy_from_user(&axio, (void __user *)(vfecmd.value),
-				sizeof(axio))) {
-				pr_err("%s %d: copy_from_user failed\n",
-					__func__, __LINE__);
-			return -EFAULT;
-		}
-			/* Validate the data from user space */
-			if (axio.output1.fragmentCount <
-				VFE_MIN_NUM_FRAGMENTS_PER_FRAME ||
-				axio.output1.fragmentCount >
-				VFE_MAX_NUM_FRAGMENTS_PER_FRAME ||
-				axio.output2.fragmentCount <
-				VFE_MIN_NUM_FRAGMENTS_PER_FRAME ||
-				axio.output2.fragmentCount >
-				VFE_MAX_NUM_FRAGMENTS_PER_FRAME)
-				return -EINVAL;
-
-			vfe_config_axi(OUTPUT_1_AND_3, axid, &axio);
-			axio.outputDataSize = 0;
-			vfe_axi_output_config(&axio);
-	}
-		break;
-
-	default:
-		break;
-	} /* switch */
-
-	return rc;
-}
-
-static int vfe_init(struct msm_vfe_callback *presp, struct platform_device *dev)
-{
-	int rc = 0;
-
-	rc = vfe_cmd_init(presp, dev, vfe_syncdata);
-	if (rc < 0)
-		return rc;
-
-	/* Bring up all the required GPIOs and Clocks */
-	rc = msm_camio_enable(dev);
-
-	return rc;
-}
-
-void msm_camvfe_fn_init(struct msm_camvfe_fn *fptr, void *data)
-{
-	fptr->vfe_init    = vfe_init;
-	fptr->vfe_enable  = vfe_enable;
-	fptr->vfe_config  = vfe_config;
-	fptr->vfe_disable = vfe_disable;
-	fptr->vfe_release = vfe_release;
-	vfe_syncdata = data;
-}
-
-void msm_camvpe_fn_init(struct msm_camvpe_fn *fptr, void *data)
-{
-	fptr->vpe_reg		= NULL;
-	fptr->send_frame_to_vpe	= NULL;
-	fptr->vpe_config	= NULL;
-	fptr->vpe_cfg_update	= NULL;
-	fptr->dis		= NULL;
-}
diff --git a/drivers/media/video/msm/vfe/msm_vfe8x.h b/drivers/media/video/msm/vfe/msm_vfe8x.h
deleted file mode 100644
index 1b3148f..0000000
--- a/drivers/media/video/msm/vfe/msm_vfe8x.h
+++ /dev/null
@@ -1,909 +0,0 @@
-/* Copyright (c) 2009, Code Aurora Forum. 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 __MSM_VFE8X_H__
-#define __MSM_VFE8X_H__
-
-#define TRUE  1
-#define FALSE 0
-#define boolean uint8_t
-
-enum  VFE_STATE {
-	VFE_STATE_IDLE,
-	VFE_STATE_ACTIVE
-};
-
-enum vfe_cmd_id {
-	/*
-	*Important! Command_ID are arranged in order.
-	*Don't change!*/
-	VFE_CMD_ID_START,
-	VFE_CMD_ID_RESET,
-
-	/* bus and camif config */
-	VFE_CMD_ID_AXI_INPUT_CONFIG,
-	VFE_CMD_ID_CAMIF_CONFIG,
-	VFE_CMD_ID_AXI_OUTPUT_CONFIG,
-
-	/* module config  */
-	VFE_CMD_ID_BLACK_LEVEL_CONFIG,
-	VFE_CMD_ID_ROLL_OFF_CONFIG,
-	VFE_CMD_ID_DEMUX_CHANNEL_GAIN_CONFIG,
-	VFE_CMD_ID_DEMOSAIC_CONFIG,
-	VFE_CMD_ID_FOV_CROP_CONFIG,
-	VFE_CMD_ID_MAIN_SCALER_CONFIG,
-	VFE_CMD_ID_WHITE_BALANCE_CONFIG,
-	VFE_CMD_ID_COLOR_CORRECTION_CONFIG,
-	VFE_CMD_ID_LA_CONFIG,
-	VFE_CMD_ID_RGB_GAMMA_CONFIG,
-	VFE_CMD_ID_CHROMA_ENHAN_CONFIG,
-	VFE_CMD_ID_CHROMA_SUPPRESSION_CONFIG,
-	VFE_CMD_ID_ASF_CONFIG,
-	VFE_CMD_ID_SCALER2Y_CONFIG,
-	VFE_CMD_ID_SCALER2CbCr_CONFIG,
-	VFE_CMD_ID_CHROMA_SUBSAMPLE_CONFIG,
-	VFE_CMD_ID_FRAME_SKIP_CONFIG,
-	VFE_CMD_ID_OUTPUT_CLAMP_CONFIG,
-
-	/* test gen */
-	VFE_CMD_ID_TEST_GEN_START,
-
-	VFE_CMD_ID_UPDATE,
-
-	/* ackownledge from upper layer */
-	VFE_CMD_ID_OUTPUT1_ACK,
-	VFE_CMD_ID_OUTPUT2_ACK,
-	VFE_CMD_ID_EPOCH1_ACK,
-	VFE_CMD_ID_EPOCH2_ACK,
-	VFE_CMD_ID_STATS_AUTOFOCUS_ACK,
-	VFE_CMD_ID_STATS_WB_EXP_ACK,
-
-	/* module update commands */
-	VFE_CMD_ID_BLACK_LEVEL_UPDATE,
-	VFE_CMD_ID_DEMUX_CHANNEL_GAIN_UPDATE,
-	VFE_CMD_ID_DEMOSAIC_BPC_UPDATE,
-	VFE_CMD_ID_DEMOSAIC_ABF_UPDATE,
-	VFE_CMD_ID_FOV_CROP_UPDATE,
-	VFE_CMD_ID_WHITE_BALANCE_UPDATE,
-	VFE_CMD_ID_COLOR_CORRECTION_UPDATE,
-	VFE_CMD_ID_LA_UPDATE,
-	VFE_CMD_ID_RGB_GAMMA_UPDATE,
-	VFE_CMD_ID_CHROMA_ENHAN_UPDATE,
-	VFE_CMD_ID_CHROMA_SUPPRESSION_UPDATE,
-	VFE_CMD_ID_MAIN_SCALER_UPDATE,
-	VFE_CMD_ID_SCALER2CbCr_UPDATE,
-	VFE_CMD_ID_SCALER2Y_UPDATE,
-	VFE_CMD_ID_ASF_UPDATE,
-	VFE_CMD_ID_FRAME_SKIP_UPDATE,
-	VFE_CMD_ID_CAMIF_FRAME_UPDATE,
-
-	/* stats update commands */
-	VFE_CMD_ID_STATS_AUTOFOCUS_UPDATE,
-	VFE_CMD_ID_STATS_WB_EXP_UPDATE,
-
-	/* control of start, stop, update, etc... */
-  VFE_CMD_ID_STOP,
-	VFE_CMD_ID_GET_HW_VERSION,
-
-	/* stats */
-	VFE_CMD_ID_STATS_SETTING,
-	VFE_CMD_ID_STATS_AUTOFOCUS_START,
-	VFE_CMD_ID_STATS_AUTOFOCUS_STOP,
-	VFE_CMD_ID_STATS_WB_EXP_START,
-	VFE_CMD_ID_STATS_WB_EXP_STOP,
-
-	VFE_CMD_ID_ASYNC_TIMER_SETTING,
-
-	/* max id  */
-	VFE_CMD_ID_MAX
-};
-
-struct vfe_cmd_hw_version {
-	uint32_t minorVersion;
-	uint32_t majorVersion;
-	uint32_t coreVersion;
-};
-
-enum VFE_CAMIF_SYNC_EDGE {
-	VFE_CAMIF_SYNC_EDGE_ActiveHigh,
-	VFE_CAMIF_SYNC_EDGE_ActiveLow
-};
-
-enum VFE_CAMIF_SYNC_MODE {
-	VFE_CAMIF_SYNC_MODE_APS,
-	VFE_CAMIF_SYNC_MODE_EFS,
-	VFE_CAMIF_SYNC_MODE_ELS,
-	VFE_CAMIF_SYNC_MODE_ILLEGAL
-};
-
-struct vfe_cmds_camif_efs {
-	uint8_t efsendofline;
-	uint8_t efsstartofline;
-	uint8_t efsendofframe;
-	uint8_t efsstartofframe;
-};
-
-struct vfe_cmds_camif_frame {
-	uint16_t pixelsPerLine;
-	uint16_t linesPerFrame;
-};
-
-struct vfe_cmds_camif_window {
-	uint16_t firstpixel;
-	uint16_t lastpixel;
-	uint16_t firstline;
-	uint16_t lastline;
-};
-
-enum CAMIF_SUBSAMPLE_FRAME_SKIP {
-	CAMIF_SUBSAMPLE_FRAME_SKIP_0,
-	CAMIF_SUBSAMPLE_FRAME_SKIP_AllFrames,
-	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_2Frame,
-	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_3Frame,
-	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_4Frame,
-	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_5Frame,
-	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_6Frame,
-	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_7Frame,
-	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_8Frame,
-	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_9Frame,
-	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_10Frame,
-	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_11Frame,
-	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_12Frame,
-	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_13Frame,
-	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_14Frame,
-	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_15Frame
-};
-
-struct vfe_cmds_camif_subsample {
-	uint16_t pixelskipmask;
-	uint16_t lineskipmask;
-	enum CAMIF_SUBSAMPLE_FRAME_SKIP frameskip;
-	uint8_t frameskipmode;
-	uint8_t pixelskipwrap;
-};
-
-struct vfe_cmds_camif_epoch {
-	uint8_t  enable;
-	uint16_t lineindex;
-};
-
-struct vfe_cmds_camif_cfg {
-	enum VFE_CAMIF_SYNC_EDGE  vSyncEdge;
-	enum VFE_CAMIF_SYNC_EDGE  hSyncEdge;
-	enum VFE_CAMIF_SYNC_MODE  syncMode;
-	uint8_t vfeSubSampleEnable;
-	uint8_t busSubSampleEnable;
-	uint8_t irqSubSampleEnable;
-	uint8_t binningEnable;
-	uint8_t misrEnable;
-};
-
-struct vfe_cmd_camif_config {
-	struct vfe_cmds_camif_cfg camifConfig;
-	struct vfe_cmds_camif_efs EFS;
-	struct vfe_cmds_camif_frame     frame;
-	struct vfe_cmds_camif_window    window;
-	struct vfe_cmds_camif_subsample subsample;
-	struct vfe_cmds_camif_epoch     epoch1;
-	struct vfe_cmds_camif_epoch     epoch2;
-};
-
-enum VFE_AXI_OUTPUT_MODE {
-	VFE_AXI_OUTPUT_MODE_Output1,
-	VFE_AXI_OUTPUT_MODE_Output2,
-	VFE_AXI_OUTPUT_MODE_Output1AndOutput2,
-	VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2,
-	VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1,
-	VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2,
-	VFE_AXI_LAST_OUTPUT_MODE_ENUM
-};
-
-enum VFE_RAW_WR_PATH_SEL {
-	VFE_RAW_OUTPUT_DISABLED,
-	VFE_RAW_OUTPUT_ENC_CBCR_PATH,
-	VFE_RAW_OUTPUT_VIEW_CBCR_PATH,
-	VFE_RAW_OUTPUT_PATH_INVALID
-};
-
-enum VFE_RAW_PIXEL_DATA_SIZE {
-	VFE_RAW_PIXEL_DATA_SIZE_8BIT,
-	VFE_RAW_PIXEL_DATA_SIZE_10BIT,
-	VFE_RAW_PIXEL_DATA_SIZE_12BIT,
-};
-
-#define VFE_AXI_OUTPUT_BURST_LENGTH     4
-#define VFE_MAX_NUM_FRAGMENTS_PER_FRAME 4
-#define VFE_MIN_NUM_FRAGMENTS_PER_FRAME 1
-#define VFE_AXI_OUTPUT_CFG_FRAME_COUNT  3
-
-struct vfe_cmds_axi_out_per_component {
-	uint16_t imageWidth;
-	uint16_t imageHeight;
-	uint16_t outRowCount;
-	uint16_t outRowIncrement;
-	uint32_t outFragments[VFE_AXI_OUTPUT_CFG_FRAME_COUNT]
-		[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
-};
-
-struct vfe_cmds_axi_per_output_path {
-	uint8_t fragmentCount;
-	struct vfe_cmds_axi_out_per_component outputY;
-	struct vfe_cmds_axi_out_per_component outputCbcr;
-};
-
-enum VFE_AXI_BURST_LENGTH {
-	VFE_AXI_BURST_LENGTH_IS_2  = 2,
-	VFE_AXI_BURST_LENGTH_IS_4  = 4,
-	VFE_AXI_BURST_LENGTH_IS_8  = 8,
-	VFE_AXI_BURST_LENGTH_IS_16 = 16
-};
-
-struct vfe_cmd_axi_output_config {
-	enum VFE_AXI_BURST_LENGTH burstLength;
-	enum VFE_AXI_OUTPUT_MODE outputMode;
-	enum VFE_RAW_PIXEL_DATA_SIZE outputDataSize;
-	struct vfe_cmds_axi_per_output_path output1;
-	struct vfe_cmds_axi_per_output_path output2;
-};
-
-struct vfe_cmd_fov_crop_config {
-	uint8_t enable;
-	uint16_t firstPixel;
-	uint16_t lastPixel;
-	uint16_t firstLine;
-	uint16_t lastLine;
-};
-
-struct vfe_cmds_main_scaler_stripe_init {
-	uint16_t MNCounterInit;
-	uint16_t phaseInit;
-};
-
-struct vfe_cmds_scaler_one_dimension {
-	uint8_t  enable;
-	uint16_t inputSize;
-	uint16_t outputSize;
-	uint32_t phaseMultiplicationFactor;
-	uint8_t  interpolationResolution;
-};
-
-struct vfe_cmd_main_scaler_config {
-	uint8_t enable;
-	struct vfe_cmds_scaler_one_dimension    hconfig;
-	struct vfe_cmds_scaler_one_dimension    vconfig;
-	struct vfe_cmds_main_scaler_stripe_init MNInitH;
-	struct vfe_cmds_main_scaler_stripe_init MNInitV;
-};
-
-struct vfe_cmd_scaler2_config {
-	uint8_t enable;
-	struct vfe_cmds_scaler_one_dimension hconfig;
-	struct vfe_cmds_scaler_one_dimension vconfig;
-};
-
-struct vfe_cmd_frame_skip_config {
-	uint8_t output1Period;
-	uint32_t output1Pattern;
-	uint8_t output2Period;
-	uint32_t output2Pattern;
-};
-
-struct vfe_cmd_frame_skip_update {
-	uint32_t output1Pattern;
-	uint32_t output2Pattern;
-};
-
-struct vfe_cmd_output_clamp_config {
-	uint8_t minCh0;
-	uint8_t minCh1;
-	uint8_t minCh2;
-	uint8_t maxCh0;
-	uint8_t maxCh1;
-	uint8_t maxCh2;
-};
-
-struct vfe_cmd_chroma_subsample_config {
-	uint8_t enable;
-	uint8_t cropEnable;
-	uint8_t vsubSampleEnable;
-	uint8_t hsubSampleEnable;
-	uint8_t vCosited;
-	uint8_t hCosited;
-	uint8_t vCositedPhase;
-	uint8_t hCositedPhase;
-	uint16_t cropWidthFirstPixel;
-	uint16_t cropWidthLastPixel;
-	uint16_t cropHeightFirstLine;
-	uint16_t cropHeightLastLine;
-};
-
-enum VFE_START_INPUT_SOURCE {
-	VFE_START_INPUT_SOURCE_CAMIF,
-	VFE_START_INPUT_SOURCE_TESTGEN,
-	VFE_START_INPUT_SOURCE_AXI,
-	VFE_START_INPUT_SOURCE_INVALID
-};
-
-enum VFE_START_OPERATION_MODE {
-	VFE_START_OPERATION_MODE_CONTINUOUS,
-	VFE_START_OPERATION_MODE_SNAPSHOT
-};
-
-enum VFE_START_PIXEL_PATTERN {
-	VFE_BAYER_RGRGRG,
-	VFE_BAYER_GRGRGR,
-	VFE_BAYER_BGBGBG,
-	VFE_BAYER_GBGBGB,
-	VFE_YUV_YCbYCr,
-	VFE_YUV_YCrYCb,
-	VFE_YUV_CbYCrY,
-	VFE_YUV_CrYCbY
-};
-
-enum VFE_BUS_RD_INPUT_PIXEL_PATTERN {
-	VFE_BAYER_RAW,
-	VFE_YUV_INTERLEAVED,
-	VFE_YUV_PSEUDO_PLANAR_Y,
-	VFE_YUV_PSEUDO_PLANAR_CBCR
-};
-
-enum VFE_YUV_INPUT_COSITING_MODE {
-	VFE_YUV_COSITED,
-	VFE_YUV_INTERPOLATED
-};
-
-struct vfe_cmd_start {
-	enum VFE_START_INPUT_SOURCE inputSource;
-	enum VFE_START_OPERATION_MODE operationMode;
-	uint8_t     snapshotCount;
-	enum VFE_START_PIXEL_PATTERN pixel;
-	enum VFE_YUV_INPUT_COSITING_MODE yuvInputCositingMode;
-};
-
-struct vfe_cmd_output_ack {
-	uint32_t ybufaddr[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
-	uint32_t chromabufaddr[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
-};
-
-#define VFE_STATS_BUFFER_COUNT 3
-
-struct vfe_cmd_stats_setting {
-	uint16_t frameHDimension;
-	uint16_t frameVDimension;
-	uint8_t  afBusPrioritySelection;
-	uint8_t  afBusPriority;
-	uint8_t  awbBusPrioritySelection;
-	uint8_t  awbBusPriority;
-	uint8_t  histBusPrioritySelection;
-	uint8_t  histBusPriority;
-	uint32_t afBuffer[VFE_STATS_BUFFER_COUNT];
-	uint32_t awbBuffer[VFE_STATS_BUFFER_COUNT];
-	uint32_t histBuffer[VFE_STATS_BUFFER_COUNT];
-};
-
-struct vfe_cmd_stats_af_start {
-	uint8_t  enable;
-	uint8_t  windowMode;
-	uint16_t windowHOffset;
-	uint16_t windowVOffset;
-	uint16_t windowWidth;
-	uint16_t windowHeight;
-	uint8_t  gridForMultiWindows[16];
-	uint8_t     metricSelection;
-	int16_t  metricMax;
-	int8_t   highPassCoef[7];
-	int8_t   bufferHeader;
-};
-
-struct vfe_cmd_stats_af_update {
-	uint8_t  windowMode;
-	uint16_t windowHOffset;
-	uint16_t windowVOffset;
-	uint16_t windowWidth;
-	uint16_t windowHeight;
-};
-
-struct vfe_cmd_stats_wb_exp_start {
-	uint8_t   enable;
-	uint8_t   wbExpRegions;
-	uint8_t   wbExpSubRegion;
-	uint8_t   awbYMin;
-	uint8_t   awbYMax;
-	int8_t    awbMCFG[4];
-	int16_t   awbCCFG[4];
-	int8_t    axwHeader;
-};
-
-struct vfe_cmd_stats_wb_exp_update {
-	uint8_t wbExpRegions;
-	uint8_t wbExpSubRegion;
-	int8_t  awbYMin;
-	int8_t  awbYMax;
-	int8_t  awbMCFG[4];
-	int16_t awbCCFG[4];
-};
-
-struct vfe_cmd_stats_af_ack {
-	uint32_t nextAFOutputBufferAddr;
-};
-
-struct vfe_cmd_stats_wb_exp_ack {
-	uint32_t  nextWbExpOutputBufferAddr;
-};
-
-struct vfe_cmd_black_level_config {
-	uint8_t  enable;
-	uint16_t evenEvenAdjustment;
-	uint16_t evenOddAdjustment;
-	uint16_t oddEvenAdjustment;
-	uint16_t oddOddAdjustment;
-};
-
-/* 13*1  */
-#define  VFE_ROLL_OFF_INIT_TABLE_SIZE  13
-/* 13*16 */
-#define  VFE_ROLL_OFF_DELTA_TABLE_SIZE 208
-
-struct vfe_cmd_roll_off_config {
-	uint8_t  enable;
-	uint16_t gridWidth;
-	uint16_t gridHeight;
-	uint16_t  yDelta;
-	uint8_t  gridXIndex;
-	uint8_t  gridYIndex;
-	uint16_t gridPixelXIndex;
-	uint16_t gridPixelYIndex;
-	uint16_t yDeltaAccum;
-	uint16_t initTableR[VFE_ROLL_OFF_INIT_TABLE_SIZE];
-	uint16_t initTableGr[VFE_ROLL_OFF_INIT_TABLE_SIZE];
-	uint16_t initTableB[VFE_ROLL_OFF_INIT_TABLE_SIZE];
-	uint16_t initTableGb[VFE_ROLL_OFF_INIT_TABLE_SIZE];
-	int16_t  deltaTableR[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
-	int16_t  deltaTableGr[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
-	int16_t  deltaTableB[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
-	int16_t  deltaTableGb[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
-};
-
-struct vfe_cmd_demux_channel_gain_config {
-	uint16_t ch0EvenGain;
-	uint16_t ch0OddGain;
-	uint16_t ch1Gain;
-	uint16_t ch2Gain;
-};
-
-struct vfe_cmds_demosaic_abf {
-	uint8_t   enable;
-	uint8_t   forceOn;
-	uint8_t   shift;
-	uint16_t  lpThreshold;
-	uint16_t  max;
-	uint16_t  min;
-	uint8_t   ratio;
-};
-
-struct vfe_cmds_demosaic_bpc {
-	uint8_t   enable;
-	uint16_t  fmaxThreshold;
-	uint16_t  fminThreshold;
-	uint16_t  redDiffThreshold;
-	uint16_t  blueDiffThreshold;
-	uint16_t  greenDiffThreshold;
-};
-
-struct vfe_cmd_demosaic_config {
-	uint8_t   enable;
-	uint8_t   slopeShift;
-	struct vfe_cmds_demosaic_abf abfConfig;
-	struct vfe_cmds_demosaic_bpc bpcConfig;
-};
-
-struct vfe_cmd_demosaic_bpc_update {
-	struct vfe_cmds_demosaic_bpc bpcUpdate;
-};
-
-struct vfe_cmd_demosaic_abf_update {
-	struct vfe_cmds_demosaic_abf abfUpdate;
-};
-
-struct vfe_cmd_white_balance_config {
-	uint8_t  enable;
-	uint16_t ch2Gain;
-	uint16_t ch1Gain;
-	uint16_t ch0Gain;
-};
-
-enum VFE_COLOR_CORRECTION_COEF_QFACTOR {
-	COEF_IS_Q7_SIGNED,
-	COEF_IS_Q8_SIGNED,
-	COEF_IS_Q9_SIGNED,
-	COEF_IS_Q10_SIGNED
-};
-
-struct vfe_cmd_color_correction_config {
-	uint8_t     enable;
-	enum VFE_COLOR_CORRECTION_COEF_QFACTOR coefQFactor;
-	int16_t  C0;
-	int16_t  C1;
-	int16_t  C2;
-	int16_t  C3;
-	int16_t  C4;
-	int16_t  C5;
-	int16_t  C6;
-	int16_t  C7;
-	int16_t  C8;
-	int16_t  K0;
-	int16_t  K1;
-	int16_t  K2;
-};
-
-#define VFE_LA_TABLE_LENGTH 256
-struct vfe_cmd_la_config {
-	uint8_t enable;
-	int16_t table[VFE_LA_TABLE_LENGTH];
-};
-
-#define VFE_GAMMA_TABLE_LENGTH 256
-enum VFE_RGB_GAMMA_TABLE_SELECT {
-	RGB_GAMMA_CH0_SELECTED,
-	RGB_GAMMA_CH1_SELECTED,
-	RGB_GAMMA_CH2_SELECTED,
-	RGB_GAMMA_CH0_CH1_SELECTED,
-	RGB_GAMMA_CH0_CH2_SELECTED,
-	RGB_GAMMA_CH1_CH2_SELECTED,
-	RGB_GAMMA_CH0_CH1_CH2_SELECTED
-};
-
-struct vfe_cmd_rgb_gamma_config {
-	uint8_t enable;
-	enum VFE_RGB_GAMMA_TABLE_SELECT channelSelect;
-	int16_t table[VFE_GAMMA_TABLE_LENGTH];
-};
-
-struct vfe_cmd_chroma_enhan_config {
-	uint8_t  enable;
-	int16_t am;
-	int16_t ap;
-	int16_t bm;
-	int16_t bp;
-	int16_t cm;
-	int16_t cp;
-	int16_t dm;
-	int16_t dp;
-	int16_t kcr;
-	int16_t kcb;
-	int16_t RGBtoYConversionV0;
-	int16_t RGBtoYConversionV1;
-	int16_t RGBtoYConversionV2;
-	uint8_t RGBtoYConversionOffset;
-};
-
-struct vfe_cmd_chroma_suppression_config {
-	uint8_t enable;
-	uint8_t m1;
-	uint8_t m3;
-	uint8_t n1;
-	uint8_t n3;
-	uint8_t nn1;
-	uint8_t mm1;
-};
-
-struct vfe_cmd_asf_config {
-	uint8_t enable;
-	uint8_t smoothFilterEnabled;
-	uint8_t sharpMode;
-	uint8_t smoothCoefCenter;
-	uint8_t smoothCoefSurr;
-	uint8_t normalizeFactor;
-	uint8_t sharpK1;
-	uint8_t sharpK2;
-	uint8_t sharpThreshE1;
-	int8_t sharpThreshE2;
-	int8_t sharpThreshE3;
-	int8_t sharpThreshE4;
-	int8_t sharpThreshE5;
-	int8_t filter1Coefficients[9];
-	int8_t filter2Coefficients[9];
-	uint8_t  cropEnable;
-	uint16_t cropFirstPixel;
-	uint16_t cropLastPixel;
-	uint16_t cropFirstLine;
-	uint16_t cropLastLine;
-};
-
-struct vfe_cmd_asf_update {
-	uint8_t enable;
-	uint8_t smoothFilterEnabled;
-	uint8_t sharpMode;
-	uint8_t smoothCoefCenter;
-	uint8_t smoothCoefSurr;
-	uint8_t normalizeFactor;
-	uint8_t sharpK1;
-	uint8_t sharpK2;
-	uint8_t sharpThreshE1;
-	int8_t  sharpThreshE2;
-	int8_t  sharpThreshE3;
-	int8_t  sharpThreshE4;
-	int8_t  sharpThreshE5;
-	int8_t  filter1Coefficients[9];
-	int8_t  filter2Coefficients[9];
-	uint8_t cropEnable;
-};
-
-enum VFE_TEST_GEN_SYNC_EDGE {
-	VFE_TEST_GEN_SYNC_EDGE_ActiveHigh,
-	VFE_TEST_GEN_SYNC_EDGE_ActiveLow
-};
-
-struct vfe_cmd_test_gen_start {
-	uint8_t pixelDataSelect;
-	uint8_t systematicDataSelect;
-	enum VFE_TEST_GEN_SYNC_EDGE  hsyncEdge;
-	enum VFE_TEST_GEN_SYNC_EDGE  vsyncEdge;
-	uint16_t numFrame;
-	enum VFE_RAW_PIXEL_DATA_SIZE pixelDataSize;
-	uint16_t imageWidth;
-	uint16_t imageHeight;
-	uint32_t startOfFrameOffset;
-	uint32_t endOfFrameNOffset;
-	uint16_t startOfLineOffset;
-	uint16_t endOfLineNOffset;
-	uint16_t hbi;
-	uint8_t  vblEnable;
-	uint16_t vbl;
-	uint8_t  startOfFrameDummyLine;
-	uint8_t  endOfFrameDummyLine;
-	uint8_t  unicolorBarEnable;
-	uint8_t  colorBarsSplitEnable;
-	uint8_t  unicolorBarSelect;
-	enum VFE_START_PIXEL_PATTERN  colorBarsPixelPattern;
-	uint8_t  colorBarsRotatePeriod;
-	uint16_t testGenRandomSeed;
-};
-
-struct vfe_cmd_bus_pm_start {
-	uint8_t output2YWrPmEnable;
-	uint8_t output2CbcrWrPmEnable;
-	uint8_t output1YWrPmEnable;
-	uint8_t output1CbcrWrPmEnable;
-};
-
-struct vfe_cmd_camif_frame_update {
-	struct vfe_cmds_camif_frame camifFrame;
-};
-
-struct vfe_cmd_sync_timer_setting {
-	uint8_t  whichSyncTimer;
-	uint8_t  operation;
-	uint8_t  polarity;
-	uint16_t repeatCount;
-	uint16_t hsyncCount;
-	uint32_t pclkCount;
-	uint32_t outputDuration;
-};
-
-struct vfe_cmd_async_timer_setting {
-	uint8_t  whichAsyncTimer;
-	uint8_t  operation;
-	uint8_t  polarity;
-	uint16_t repeatCount;
-	uint16_t inactiveCount;
-	uint32_t activeCount;
-};
-
-struct  vfe_frame_skip_counts {
-	uint32_t  totalFrameCount;
-	uint32_t  output1Count;
-	uint32_t  output2Count;
-};
-
-enum VFE_AXI_RD_UNPACK_HBI_SEL {
-	VFE_AXI_RD_HBI_32_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_64_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_128_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_256_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_512_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_1024_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_2048_CLOCK_CYCLES,
-	VFE_AXI_RD_HBI_4096_CLOCK_CYCLES
-};
-
-struct vfe_cmd_axi_input_config {
-	uint32_t  fragAddr[4];
-	uint8_t   totalFragmentCount;
-	uint16_t  ySize;
-	uint16_t  xOffset;
-	uint16_t  xSize;
-	uint16_t  rowIncrement;
-	uint16_t  numOfRows;
-	enum VFE_AXI_BURST_LENGTH burstLength;
-	uint8_t   unpackPhase;
-	enum VFE_AXI_RD_UNPACK_HBI_SEL unpackHbi;
-	enum VFE_RAW_PIXEL_DATA_SIZE   pixelSize;
-	uint8_t   padRepeatCountLeft;
-	uint8_t   padRepeatCountRight;
-	uint8_t   padRepeatCountTop;
-	uint8_t   padRepeatCountBottom;
-	uint8_t   padLeftComponentSelectCycle0;
-	uint8_t   padLeftComponentSelectCycle1;
-	uint8_t   padLeftComponentSelectCycle2;
-	uint8_t   padLeftComponentSelectCycle3;
-	uint8_t   padLeftStopCycle0;
-	uint8_t   padLeftStopCycle1;
-	uint8_t   padLeftStopCycle2;
-	uint8_t   padLeftStopCycle3;
-	uint8_t   padRightComponentSelectCycle0;
-	uint8_t   padRightComponentSelectCycle1;
-	uint8_t   padRightComponentSelectCycle2;
-	uint8_t   padRightComponentSelectCycle3;
-	uint8_t   padRightStopCycle0;
-	uint8_t   padRightStopCycle1;
-	uint8_t   padRightStopCycle2;
-	uint8_t   padRightStopCycle3;
-	uint8_t   padTopLineCount;
-	uint8_t   padBottomLineCount;
-};
-
-struct vfe_interrupt_status {
-	uint8_t camifErrorIrq;
-	uint8_t camifSofIrq;
-	uint8_t camifEolIrq;
-	uint8_t camifEofIrq;
-	uint8_t camifEpoch1Irq;
-	uint8_t camifEpoch2Irq;
-	uint8_t camifOverflowIrq;
-	uint8_t ceIrq;
-	uint8_t regUpdateIrq;
-	uint8_t resetAckIrq;
-	uint8_t encYPingpongIrq;
-	uint8_t encCbcrPingpongIrq;
-	uint8_t viewYPingpongIrq;
-	uint8_t viewCbcrPingpongIrq;
-	uint8_t rdPingpongIrq;
-	uint8_t afPingpongIrq;
-	uint8_t awbPingpongIrq;
-	uint8_t histPingpongIrq;
-	uint8_t encIrq;
-	uint8_t viewIrq;
-	uint8_t busOverflowIrq;
-	uint8_t afOverflowIrq;
-	uint8_t awbOverflowIrq;
-	uint8_t syncTimer0Irq;
-	uint8_t syncTimer1Irq;
-	uint8_t syncTimer2Irq;
-	uint8_t asyncTimer0Irq;
-	uint8_t asyncTimer1Irq;
-	uint8_t asyncTimer2Irq;
-	uint8_t asyncTimer3Irq;
-	uint8_t axiErrorIrq;
-	uint8_t violationIrq;
-	uint8_t anyErrorIrqs;
-	uint8_t anyOutput1PathIrqs;
-	uint8_t anyOutput2PathIrqs;
-	uint8_t anyOutputPathIrqs;
-	uint8_t anyAsyncTimerIrqs;
-	uint8_t anySyncTimerIrqs;
-	uint8_t anyIrqForActiveStatesOnly;
-};
-
-enum VFE_MESSAGE_ID {
-	VFE_MSG_ID_RESET_ACK,
-	VFE_MSG_ID_START_ACK,
-	VFE_MSG_ID_STOP_ACK,
-	VFE_MSG_ID_UPDATE_ACK,
-	VFE_MSG_ID_OUTPUT_P,
-	VFE_MSG_ID_OUTPUT_V,
-	VFE_MSG_ID_OUTPUT_S,
-	VFE_MSG_ID_OUTPUT_T,
-	VFE_MSG_ID_SNAPSHOT_DONE,
-	VFE_MSG_ID_STATS_AUTOFOCUS,
-	VFE_MSG_ID_STATS_WB_EXP,
-	VFE_MSG_ID_EPOCH1,
-	VFE_MSG_ID_EPOCH2,
-	VFE_MSG_ID_SYNC_TIMER0_DONE,
-	VFE_MSG_ID_SYNC_TIMER1_DONE,
-	VFE_MSG_ID_SYNC_TIMER2_DONE,
-	VFE_MSG_ID_ASYNC_TIMER0_DONE,
-	VFE_MSG_ID_ASYNC_TIMER1_DONE,
-	VFE_MSG_ID_ASYNC_TIMER2_DONE,
-	VFE_MSG_ID_ASYNC_TIMER3_DONE,
-	VFE_MSG_ID_AF_OVERFLOW,
-	VFE_MSG_ID_AWB_OVERFLOW,
-	VFE_MSG_ID_AXI_ERROR,
-	VFE_MSG_ID_CAMIF_OVERFLOW,
-	VFE_MSG_ID_VIOLATION,
-	VFE_MSG_ID_CAMIF_ERROR,
-	VFE_MSG_ID_BUS_OVERFLOW,
-	VFE_MSG_ID_SOF_ACK,
-};
-
-struct vfe_msg_stats_autofocus {
-	uint32_t    afBuffer;
-	uint32_t    frameCounter;
-};
-
-struct vfe_msg_stats_wb_exp {
-	uint32_t awbBuffer;
-	uint32_t frameCounter;
-};
-
-struct vfe_frame_bpc_info {
-	uint32_t greenDefectPixelCount;
-	uint32_t redBlueDefectPixelCount;
-};
-
-struct vfe_frame_asf_info {
-	uint32_t  asfMaxEdge;
-	uint32_t  asfHbiCount;
-};
-
-struct vfe_msg_camif_status {
-	uint8_t  camifState;
-	uint32_t pixelCount;
-	uint32_t lineCount;
-};
-
-struct vfe_bus_pm_per_path {
-	uint32_t yWrPmStats0;
-	uint32_t yWrPmStats1;
-	uint32_t cbcrWrPmStats0;
-	uint32_t cbcrWrPmStats1;
-};
-
-struct vfe_bus_performance_monitor {
-	struct vfe_bus_pm_per_path encPathPmInfo;
-	struct vfe_bus_pm_per_path viewPathPmInfo;
-};
-
-struct vfe_irq_thread_msg {
-	uint32_t  vfeIrqStatus;
-	uint32_t  camifStatus;
-	uint32_t  demosaicStatus;
-	uint32_t  asfMaxEdge;
-	struct vfe_bus_performance_monitor pmInfo;
-};
-
-struct vfe_msg_output {
-	uint32_t  yBuffer;
-	uint32_t  cbcrBuffer;
-	struct vfe_frame_bpc_info bpcInfo;
-	struct vfe_frame_asf_info asfInfo;
-	uint32_t  frameCounter;
-	struct vfe_bus_pm_per_path pmData;
-};
-
-struct vfe_message {
-	enum VFE_MESSAGE_ID _d;
-	union {
-		struct vfe_msg_output              msgOutput1;
-		struct vfe_msg_output              msgOutput2;
-		struct vfe_msg_stats_autofocus     msgStatsAf;
-		struct vfe_msg_stats_wb_exp        msgStatsWbExp;
-		struct vfe_msg_camif_status        msgCamifError;
-		struct vfe_bus_performance_monitor msgBusOverflow;
-   } _u;
-};
-
-/* New one for 8k */
-struct msm_vfe_command_8k {
-	int id;
-	uint16_t length;
-	void     *value;
-};
-
-struct vfe_frame_extra {
-	struct vfe_frame_bpc_info bpcInfo;
-	struct vfe_frame_asf_info asfInfo;
-	uint32_t  frameCounter;
-	struct vfe_bus_pm_per_path pmData;
-};
-#endif /* __MSM_VFE8X_H__ */
diff --git a/drivers/media/video/msm/vfe/msm_vfe8x_proc.c b/drivers/media/video/msm/vfe/msm_vfe8x_proc.c
deleted file mode 100644
index 055b244..0000000
--- a/drivers/media/video/msm/vfe/msm_vfe8x_proc.c
+++ /dev/null
@@ -1,3889 +0,0 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. 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/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/list.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include "msm_vfe8x_proc.h"
-#include <media/msm_camera.h>
-#include <mach/board.h>
-
-struct isr_queue_cmd {
-	struct list_head list;
-	struct vfe_interrupt_status vfeInterruptStatus;
-	struct vfe_frame_asf_info vfeAsfFrameInfo;
-	struct vfe_frame_bpc_info vfeBpcFrameInfo;
-	struct vfe_msg_camif_status vfeCamifStatusLocal;
-	struct vfe_bus_performance_monitor vfePmData;
-};
-
-struct msm_vfe8x_ctrl {
-	/* bit 1:0 ENC_IRQ_MASK = 0x11:
-	 * generate IRQ when both y and cbcr frame is ready. */
-
-	/* bit 1:0 VIEW_IRQ_MASK= 0x11:
-	 * generate IRQ when both y and cbcr frame is ready. */
-	struct vfe_irq_composite_mask_config vfeIrqCompositeMaskLocal;
-	struct vfe_module_enable vfeModuleEnableLocal;
-	struct vfe_camif_cfg_data   vfeCamifConfigLocal;
-	struct vfe_interrupt_mask   vfeImaskLocal;
-	struct vfe_stats_cmd_data   vfeStatsCmdLocal;
-	struct vfe_bus_cfg_data     vfeBusConfigLocal;
-	struct vfe_cmd_bus_pm_start vfeBusPmConfigLocal;
-	struct vfe_bus_cmd_data     vfeBusCmdLocal;
-	enum vfe_interrupt_name     vfeInterruptNameLocal;
-	uint32_t vfeLaBankSel;
-	struct vfe_gamma_lut_sel  vfeGammaLutSel;
-
-	boolean vfeStartAckPendingFlag;
-	boolean vfeStopAckPending;
-	boolean vfeResetAckPending;
-	boolean vfeUpdateAckPending;
-
-	enum VFE_AXI_OUTPUT_MODE        axiOutputMode;
-	enum VFE_START_OPERATION_MODE   vfeOperationMode;
-
-	atomic_t vfe_serv_interrupt;
-
-	uint32_t            vfeSnapShotCount;
-	uint32_t            vfeRequestedSnapShotCount;
-	boolean             vfeStatsPingPongReloadFlag;
-	uint32_t            vfeFrameId;
-
-	struct vfe_cmd_frame_skip_config vfeFrameSkip;
-	uint32_t vfeFrameSkipPattern;
-	uint8_t  vfeFrameSkipCount;
-	uint8_t  vfeFrameSkipPeriod;
-
-	boolean  vfeTestGenStartFlag;
-	uint32_t vfeImaskPacked;
-	uint32_t vfeImaskCompositePacked;
-	enum VFE_RAW_PIXEL_DATA_SIZE       axiInputDataSize;
-	struct vfe_irq_thread_msg          vfeIrqThreadMsgLocal;
-
-	struct vfe_output_path_combo  viewPath;
-	struct vfe_output_path_combo  encPath;
-	struct vfe_frame_skip_counts vfeDroppedFrameCounts;
-	struct vfe_stats_control afStatsControl;
-	struct vfe_stats_control awbStatsControl;
-
-	enum VFE_STATE  vstate;
-
-	struct msm_vfe_callback *resp;
-	struct vfe_frame_extra extdata;
-
-	struct isr_queue_cmd irqs[10];
-	spinlock_t irqs_lock;
-	int irq_get;
-	int irq_put;
-
-	int vfeirq;
-	void __iomem *vfebase;
-
-	void *syncdata;
-};
-
-static struct msm_vfe8x_ctrl *ctrl;
-static spinlock_t msm_vfe_ctrl_lock;
-
-static void vfe_prog_hw(uint8_t *hwreg, uint32_t *inptr, uint32_t regcnt)
-{
-	/* unsigned long flags; */
-	uint32_t i;
-	uint32_t *p;
-
-	/* @todo This is causing issues, need further investigate */
-	/* spin_lock_irqsave(&ctrl->io_lock, flags); */
-
-	p = (uint32_t *)(hwreg);
-	for (i = 0; i < (regcnt >> 2); i++)
-		writel(*inptr++, p++);
-		/* *p++ = *inptr++; */
-
-	/* spin_unlock_irqrestore(&ctrl->io_lock, flags); */
-}
-
-static void
-vfe_set_bus_pipo_addr(struct vfe_output_path_combo *vpath,
-	struct vfe_output_path_combo *epath)
-{
-	vpath->yPath.hwRegPingAddress = (uint8_t *)
-		(ctrl->vfebase + VFE_BUS_VIEW_Y_WR_PING_ADDR);
-	vpath->yPath.hwRegPongAddress = (uint8_t *)
-		(ctrl->vfebase + VFE_BUS_VIEW_Y_WR_PONG_ADDR);
-	vpath->cbcrPath.hwRegPingAddress = (uint8_t *)
-		(ctrl->vfebase + VFE_BUS_VIEW_CBCR_WR_PING_ADDR);
-	vpath->cbcrPath.hwRegPongAddress = (uint8_t *)
-		(ctrl->vfebase + VFE_BUS_VIEW_CBCR_WR_PONG_ADDR);
-
-	epath->yPath.hwRegPingAddress = (uint8_t *)
-		(ctrl->vfebase + VFE_BUS_ENC_Y_WR_PING_ADDR);
-	epath->yPath.hwRegPongAddress = (uint8_t *)
-		(ctrl->vfebase + VFE_BUS_ENC_Y_WR_PONG_ADDR);
-	epath->cbcrPath.hwRegPingAddress = (uint8_t *)
-		(ctrl->vfebase + VFE_BUS_ENC_CBCR_WR_PING_ADDR);
-	epath->cbcrPath.hwRegPongAddress = (uint8_t *)
-		(ctrl->vfebase + VFE_BUS_ENC_CBCR_WR_PONG_ADDR);
-}
-
-static void vfe_axi_output(struct vfe_cmd_axi_output_config *in,
-	struct vfe_output_path_combo *out1,
-	struct vfe_output_path_combo *out2, uint16_t out)
-{
-	struct vfe_axi_out_cfg cmd;
-
-	uint16_t temp;
-	uint32_t burstLength;
-
-	memset(&cmd, 0, sizeof(cmd));
-	/* force it to burst length 4, hardware does not support it. */
-	burstLength = 1;
-
-	/* AXI Output 2 Y Configuration*/
-	/* VFE_BUS_ENC_Y_WR_PING_ADDR  */
-	cmd.out2YPingAddr = out2->yPath.addressBuffer[0];
-
-	/* VFE_BUS_ENC_Y_WR_PONG_ADDR  */
-	cmd.out2YPongAddr = out2->yPath.addressBuffer[1];
-
-	/* VFE_BUS_ENC_Y_WR_IMAGE_SIZE */
-	cmd.out2YImageHeight = in->output2.outputY.imageHeight;
-	/* convert the image width and row increment to be in
-	 * unit of 64bit (8 bytes) */
-	temp = (in->output2.outputY.imageWidth + (out - 1)) / out;
-	cmd.out2YImageWidthin64bit = temp;
-
-	/* VFE_BUS_ENC_Y_WR_BUFFER_CFG */
-	cmd.out2YBurstLength = burstLength;
-	cmd.out2YNumRows = in->output2.outputY.outRowCount;
-	temp = (in->output2.outputY.outRowIncrement + (out - 1)) / out;
-	cmd.out2YRowIncrementIn64bit = temp;
-
-	/* AXI Output 2 Cbcr Configuration*/
-	/* VFE_BUS_ENC_Cbcr_WR_PING_ADDR  */
-	cmd.out2CbcrPingAddr = out2->cbcrPath.addressBuffer[0];
-
-	/* VFE_BUS_ENC_Cbcr_WR_PONG_ADDR  */
-	cmd.out2CbcrPongAddr = out2->cbcrPath.addressBuffer[1];
-
-	/* VFE_BUS_ENC_Cbcr_WR_IMAGE_SIZE */
-	cmd.out2CbcrImageHeight = in->output2.outputCbcr.imageHeight;
-	temp = (in->output2.outputCbcr.imageWidth + (out - 1)) / out;
-	cmd.out2CbcrImageWidthIn64bit = temp;
-
-	/* VFE_BUS_ENC_Cbcr_WR_BUFFER_CFG */
-	cmd.out2CbcrBurstLength = burstLength;
-	cmd.out2CbcrNumRows = in->output2.outputCbcr.outRowCount;
-	temp = (in->output2.outputCbcr.outRowIncrement + (out - 1)) / out;
-	cmd.out2CbcrRowIncrementIn64bit = temp;
-
-	/* AXI Output 1 Y Configuration */
-	/* VFE_BUS_VIEW_Y_WR_PING_ADDR  */
-	cmd.out1YPingAddr = out1->yPath.addressBuffer[0];
-
-	/* VFE_BUS_VIEW_Y_WR_PONG_ADDR */
-	cmd.out1YPongAddr = out1->yPath.addressBuffer[1];
-
-	/* VFE_BUS_VIEW_Y_WR_IMAGE_SIZE */
-	cmd.out1YImageHeight = in->output1.outputY.imageHeight;
-	temp = (in->output1.outputY.imageWidth + (out - 1)) / out;
-	cmd.out1YImageWidthin64bit = temp;
-
-	/* VFE_BUS_VIEW_Y_WR_BUFFER_CFG     */
-	cmd.out1YBurstLength = burstLength;
-	cmd.out1YNumRows = in->output1.outputY.outRowCount;
-
-	temp = (in->output1.outputY.outRowIncrement + (out - 1)) / out;
-	cmd.out1YRowIncrementIn64bit = temp;
-
-	/* AXI Output 1 Cbcr Configuration*/
-	cmd.out1CbcrPingAddr = out1->cbcrPath.addressBuffer[0];
-
-	/* VFE_BUS_VIEW_Cbcr_WR_PONG_ADDR  */
-	cmd.out1CbcrPongAddr = out1->cbcrPath.addressBuffer[1];
-
-	/* VFE_BUS_VIEW_Cbcr_WR_IMAGE_SIZE */
-	cmd.out1CbcrImageHeight = in->output1.outputCbcr.imageHeight;
-	temp = (in->output1.outputCbcr.imageWidth + (out - 1)) / out;
-	cmd.out1CbcrImageWidthIn64bit = temp;
-
-	cmd.out1CbcrBurstLength = burstLength;
-	cmd.out1CbcrNumRows = in->output1.outputCbcr.outRowCount;
-	temp = (in->output1.outputCbcr.outRowIncrement + (out - 1)) / out;
-
-	cmd.out1CbcrRowIncrementIn64bit = temp;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_BUS_ENC_Y_WR_PING_ADDR,
-		(uint32_t *)&cmd, sizeof(cmd));
-}
-
-static void vfe_reg_bus_cfg(struct vfe_bus_cfg_data *in)
-{
-	struct vfe_axi_bus_cfg cmd;
-
-	memset(&cmd, 0, sizeof(cmd));
-	cmd.stripeRdPathEn      = in->stripeRdPathEn;
-	cmd.encYWrPathEn        = in->encYWrPathEn;
-	cmd.encCbcrWrPathEn     = in->encCbcrWrPathEn;
-	cmd.viewYWrPathEn       = in->viewYWrPathEn;
-	cmd.viewCbcrWrPathEn    = in->viewCbcrWrPathEn;
-	cmd.rawPixelDataSize    = (uint32_t)in->rawPixelDataSize;
-	cmd.rawWritePathSelect  = (uint32_t)in->rawWritePathSelect;
-
-	/*  program vfe_bus_cfg */
-	writel(*((uint32_t *)&cmd), ctrl->vfebase + VFE_BUS_CFG);
-}
-
-static void vfe_reg_camif_config(struct vfe_camif_cfg_data *in)
-{
-	struct VFE_CAMIFConfigType cfg;
-
-	memset(&cfg, 0, sizeof(cfg));
-
-	cfg.VSyncEdge = in->camifCfgFromCmd.vSyncEdge;
-
-	cfg.HSyncEdge = in->camifCfgFromCmd.hSyncEdge;
-
-	cfg.syncMode = in->camifCfgFromCmd.syncMode;
-
-	cfg.vfeSubsampleEnable = in->camifCfgFromCmd.vfeSubSampleEnable;
-
-	cfg.busSubsampleEnable = in->camifCfgFromCmd.busSubSampleEnable;
-
-	cfg.camif2vfeEnable = in->camif2OutputEnable;
-
-	cfg.camif2busEnable = in->camif2BusEnable;
-
-	cfg.irqSubsampleEnable = in->camifCfgFromCmd.irqSubSampleEnable;
-
-	cfg.binningEnable = in->camifCfgFromCmd.binningEnable;
-
-	cfg.misrEnable = in->camifCfgFromCmd.misrEnable;
-
-	/*  program camif_config */
-	writel(*((uint32_t *)&cfg), ctrl->vfebase + CAMIF_CONFIG);
-}
-
-static void vfe_reg_bus_cmd(struct vfe_bus_cmd_data *in)
-{
-	struct vfe_buscmd cmd;
-	memset(&cmd, 0, sizeof(cmd));
-
-	cmd.stripeReload        = in->stripeReload;
-	cmd.busPingpongReload   = in->busPingpongReload;
-	cmd.statsPingpongReload = in->statsPingpongReload;
-
-	writel(*((uint32_t *)&cmd), ctrl->vfebase + VFE_BUS_CMD);
-
-	CDBG("bus command = 0x%x\n", (*((uint32_t *)&cmd)));
-
-	/* this is needed, as the control bits are pulse based.
-	 * Don't want to reload bus pingpong again. */
-	in->busPingpongReload = 0;
-	in->statsPingpongReload = 0;
-	in->stripeReload = 0;
-}
-
-static void vfe_reg_module_cfg(struct vfe_module_enable *in)
-{
-	struct vfe_mod_enable ena;
-
-	memset(&ena, 0, sizeof(ena));
-
-	ena.blackLevelCorrectionEnable = in->blackLevelCorrectionEnable;
-	ena.lensRollOffEnable          = in->lensRollOffEnable;
-	ena.demuxEnable                = in->demuxEnable;
-	ena.chromaUpsampleEnable       = in->chromaUpsampleEnable;
-	ena.demosaicEnable             = in->demosaicEnable;
-	ena.statsEnable                = in->statsEnable;
-	ena.cropEnable                 = in->cropEnable;
-	ena.mainScalerEnable           = in->mainScalerEnable;
-	ena.whiteBalanceEnable         = in->whiteBalanceEnable;
-	ena.colorCorrectionEnable      = in->colorCorrectionEnable;
-	ena.yHistEnable                = in->yHistEnable;
-	ena.skinToneEnable             = in->skinToneEnable;
-	ena.lumaAdaptationEnable       = in->lumaAdaptationEnable;
-	ena.rgbLUTEnable               = in->rgbLUTEnable;
-	ena.chromaEnhanEnable          = in->chromaEnhanEnable;
-	ena.asfEnable                  = in->asfEnable;
-	ena.chromaSuppressionEnable    = in->chromaSuppressionEnable;
-	ena.chromaSubsampleEnable      = in->chromaSubsampleEnable;
-	ena.scaler2YEnable             = in->scaler2YEnable;
-	ena.scaler2CbcrEnable          = in->scaler2CbcrEnable;
-
-	writel(*((uint32_t *)&ena), ctrl->vfebase + VFE_MODULE_CFG);
-}
-
-static void vfe_program_dmi_cfg(enum VFE_DMI_RAM_SEL bankSel)
-{
-	/* set bit 8 for auto increment. */
-	uint32_t value = (uint32_t) ctrl->vfebase + VFE_DMI_CFG_DEFAULT;
-
-	value += (uint32_t)bankSel;
-	/* CDBG("dmi cfg input bank is  0x%x\n", bankSel); */
-
-	writel(value, ctrl->vfebase + VFE_DMI_CFG);
-	writel(0, ctrl->vfebase + VFE_DMI_ADDR);
-}
-
-static void vfe_write_lens_roll_off_table(struct vfe_cmd_roll_off_config *in)
-{
-	uint16_t i;
-	uint32_t data;
-
-	uint16_t *initGr = in->initTableGr;
-	uint16_t *initGb = in->initTableGb;
-	uint16_t *initB =  in->initTableB;
-	uint16_t *initR =  in->initTableR;
-
-	int16_t *pDeltaGr = in->deltaTableGr;
-	int16_t *pDeltaGb = in->deltaTableGb;
-	int16_t *pDeltaB =  in->deltaTableB;
-	int16_t *pDeltaR =  in->deltaTableR;
-
-	vfe_program_dmi_cfg(ROLLOFF_RAM);
-
-	/* first pack and write init table */
-	for (i = 0; i < VFE_ROLL_OFF_INIT_TABLE_SIZE; i++) {
-		data = (((uint32_t)(*initR)) & 0x0000FFFF) |
-			(((uint32_t)(*initGr)) << 16);
-		initR++;
-		initGr++;
-
-		writel(data, ctrl->vfebase + VFE_DMI_DATA_LO);
-
-		data = (((uint32_t)(*initB)) & 0x0000FFFF) |
-			(((uint32_t)(*initGb))<<16);
-		initB++;
-		initGb++;
-
-		writel(data, ctrl->vfebase + VFE_DMI_DATA_LO);
-	}
-
-	/* there are gaps between the init table and delta table,
-	 * set the offset for delta table. */
-	writel(LENS_ROLL_OFF_DELTA_TABLE_OFFSET, ctrl->vfebase + VFE_DMI_ADDR);
-
-	/* pack and write delta table */
-	for (i = 0; i < VFE_ROLL_OFF_DELTA_TABLE_SIZE; i++) {
-		data = (((int)(*pDeltaR)) & 0x0000FFFF) |
-			(((int)(*pDeltaGr))<<16);
-		pDeltaR++;
-		pDeltaGr++;
-
-		writel(data, ctrl->vfebase + VFE_DMI_DATA_LO);
-
-		data = (((int)(*pDeltaB)) & 0x0000FFFF) |
-			(((int)(*pDeltaGb))<<16);
-		pDeltaB++;
-		pDeltaGb++;
-
-		writel(data, ctrl->vfebase + VFE_DMI_DATA_LO);
-	}
-
-	/* After DMI transfer, to make it safe, need to set the
-	 * DMI_CFG to unselect any SRAM
-	 */
-	/* unselect the SRAM Bank. */
-	writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG);
-}
-
-static void vfe_set_default_reg_values(void)
-{
-	writel(0x800080, ctrl->vfebase + VFE_DEMUX_GAIN_0);
-	writel(0x800080, ctrl->vfebase + VFE_DEMUX_GAIN_1);
-	writel(0xFFFFF, ctrl->vfebase + VFE_CGC_OVERRIDE);
-
-	/* default frame drop period and pattern */
-	writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_CFG);
-	writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_CFG);
-	writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_PATTERN);
-	writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_PATTERN);
-	writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_CFG);
-	writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR_CFG);
-	writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_PATTERN);
-	writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR_PATTERN);
-	writel(0, ctrl->vfebase + VFE_CLAMP_MIN_CFG);
-	writel(0xFFFFFF, ctrl->vfebase + VFE_CLAMP_MAX_CFG);
-}
-
-static void vfe_config_demux(uint32_t period, uint32_t even, uint32_t odd)
-{
-	writel(period, ctrl->vfebase + VFE_DEMUX_CFG);
-	writel(even, ctrl->vfebase + VFE_DEMUX_EVEN_CFG);
-	writel(odd, ctrl->vfebase + VFE_DEMUX_ODD_CFG);
-}
-
-static void vfe_pm_stop(void)
-{
-	writel(VFE_PERFORMANCE_MONITOR_STOP, ctrl->vfebase + VFE_BUS_PM_CMD);
-}
-
-static void vfe_camif_stop_immediately(void)
-{
-	writel(CAMIF_COMMAND_STOP_IMMEDIATELY, ctrl->vfebase + CAMIF_COMMAND);
-	writel(0, ctrl->vfebase + VFE_CGC_OVERRIDE);
-}
-
-static void vfe_program_reg_update_cmd(uint32_t value)
-{
-	writel(value, ctrl->vfebase + VFE_REG_UPDATE_CMD);
-}
-
-static void vfe_program_global_reset_cmd(uint32_t value)
-{
-	writel(value, ctrl->vfebase + VFE_GLOBAL_RESET_CMD);
-}
-
-static void vfe_program_axi_cmd(uint32_t value)
-{
-	writel(value, ctrl->vfebase + VFE_AXI_CMD);
-}
-
-static void vfe_program_irq_composite_mask(uint32_t value)
-{
-	writel(value, ctrl->vfebase + VFE_IRQ_COMPOSITE_MASK);
-}
-
-static inline void vfe_program_irq_mask(uint32_t value)
-{
-	writel(value, ctrl->vfebase + VFE_IRQ_MASK);
-}
-
-static uint32_t vfe_read_axi_status(void)
-{
-	return readl(ctrl->vfebase + VFE_AXI_STATUS);
-}
-
-static void
-vfe_set_stats_pingpong_address(struct vfe_stats_control *afControl,
-	struct vfe_stats_control *awbControl)
-{
-	afControl->hwRegPingAddress = (uint8_t *)
-		(ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR);
-	afControl->hwRegPongAddress = (uint8_t *)
-		(ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR);
-
-	awbControl->hwRegPingAddress = (uint8_t *)
-		(ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR);
-	awbControl->hwRegPongAddress = (uint8_t *)
-		(ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR);
-}
-
-static void vfe_program_lut_bank_sel(struct vfe_gamma_lut_sel *in)
-{
-	struct VFE_GammaLutSelect_ConfigCmdType cmd;
-
-	memset(&cmd, 0, sizeof(cmd));
-
-	cmd.ch0BankSelect = in->ch0BankSelect;
-	cmd.ch1BankSelect = in->ch1BankSelect;
-	cmd.ch2BankSelect = in->ch2BankSelect;
-	CDBG("VFE gamma lut bank selection is 0x%x\n", *((uint32_t *)&cmd));
-	vfe_prog_hw(ctrl->vfebase + VFE_LUT_BANK_SEL,
-		(uint32_t *)&cmd, sizeof(cmd));
-}
-
-static void vfe_program_stats_cmd(struct vfe_stats_cmd_data *in)
-{
-	struct VFE_StatsCmdType stats;
-	memset(&stats, 0, sizeof(stats));
-
-	stats.autoFocusEnable        = in->autoFocusEnable;
-	stats.axwEnable              = in->axwEnable;
-	stats.histEnable             = in->histEnable;
-	stats.clearHistEnable        = in->clearHistEnable;
-	stats.histAutoClearEnable    = in->histAutoClearEnable;
-	stats.colorConversionEnable  = in->colorConversionEnable;
-
-	writel(*((uint32_t *)&stats), ctrl->vfebase + VFE_STATS_CMD);
-}
-
-static void vfe_pm_start(struct vfe_cmd_bus_pm_start *in)
-{
-	struct VFE_Bus_Pm_ConfigCmdType cmd;
-	memset(&cmd, 0, sizeof(struct VFE_Bus_Pm_ConfigCmdType));
-
-	cmd.output2YWrPmEnable     = in->output2YWrPmEnable;
-	cmd.output2CbcrWrPmEnable  = in->output2CbcrWrPmEnable;
-	cmd.output1YWrPmEnable     = in->output1YWrPmEnable;
-	cmd.output1CbcrWrPmEnable  = in->output1CbcrWrPmEnable;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_BUS_PM_CFG,
-		(uint32_t *)&cmd, sizeof(cmd));
-}
-
-static void vfe_8k_pm_start(struct vfe_cmd_bus_pm_start *in)
-{
-	in->output1CbcrWrPmEnable = ctrl->vfeBusConfigLocal.viewCbcrWrPathEn;
-	in->output1YWrPmEnable    = ctrl->vfeBusConfigLocal.viewYWrPathEn;
-	in->output2CbcrWrPmEnable = ctrl->vfeBusConfigLocal.encCbcrWrPathEn;
-	in->output2YWrPmEnable    = ctrl->vfeBusConfigLocal.encYWrPathEn;
-
-	if (in->output1CbcrWrPmEnable || in->output1YWrPmEnable)
-		ctrl->viewPath.pmEnabled = TRUE;
-
-	if (in->output2CbcrWrPmEnable || in->output2YWrPmEnable)
-		ctrl->encPath.pmEnabled = TRUE;
-
-	vfe_pm_start(in);
-
-	writel(VFE_PERFORMANCE_MONITOR_GO, ctrl->vfebase + VFE_BUS_PM_CMD);
-}
-
-static uint32_t vfe_irq_pack(struct vfe_interrupt_mask data)
-{
-	struct vfe_irqenable packedData;
-
-	memset(&packedData, 0, sizeof(packedData));
-
-	packedData.camifErrorIrq          = data.camifErrorIrq;
-	packedData.camifSofIrq            = data.camifSofIrq;
-	packedData.camifEolIrq            = data.camifEolIrq;
-	packedData.camifEofIrq            = data.camifEofIrq;
-	packedData.camifEpoch1Irq         = data.camifEpoch1Irq;
-	packedData.camifEpoch2Irq         = data.camifEpoch2Irq;
-	packedData.camifOverflowIrq       = data.camifOverflowIrq;
-	packedData.ceIrq                  = data.ceIrq;
-	packedData.regUpdateIrq           = data.regUpdateIrq;
-	packedData.resetAckIrq            = data.resetAckIrq;
-	packedData.encYPingpongIrq        = data.encYPingpongIrq;
-	packedData.encCbcrPingpongIrq     = data.encCbcrPingpongIrq;
-	packedData.viewYPingpongIrq       = data.viewYPingpongIrq;
-	packedData.viewCbcrPingpongIrq    = data.viewCbcrPingpongIrq;
-	packedData.rdPingpongIrq          = data.rdPingpongIrq;
-	packedData.afPingpongIrq          = data.afPingpongIrq;
-	packedData.awbPingpongIrq         = data.awbPingpongIrq;
-	packedData.histPingpongIrq        = data.histPingpongIrq;
-	packedData.encIrq                 = data.encIrq;
-	packedData.viewIrq                = data.viewIrq;
-	packedData.busOverflowIrq         = data.busOverflowIrq;
-	packedData.afOverflowIrq          = data.afOverflowIrq;
-	packedData.awbOverflowIrq         = data.awbOverflowIrq;
-	packedData.syncTimer0Irq          = data.syncTimer0Irq;
-	packedData.syncTimer1Irq          = data.syncTimer1Irq;
-	packedData.syncTimer2Irq          = data.syncTimer2Irq;
-	packedData.asyncTimer0Irq         = data.asyncTimer0Irq;
-	packedData.asyncTimer1Irq         = data.asyncTimer1Irq;
-	packedData.asyncTimer2Irq         = data.asyncTimer2Irq;
-	packedData.asyncTimer3Irq         = data.asyncTimer3Irq;
-	packedData.axiErrorIrq            = data.axiErrorIrq;
-	packedData.violationIrq           = data.violationIrq;
-
-	return *((uint32_t *)&packedData);
-}
-
-static uint32_t
-vfe_irq_composite_pack(struct vfe_irq_composite_mask_config data)
-{
-	struct VFE_Irq_Composite_MaskType packedData;
-
-	memset(&packedData, 0, sizeof(packedData));
-
-	packedData.encIrqComMaskBits   = data.encIrqComMask;
-	packedData.viewIrqComMaskBits  = data.viewIrqComMask;
-	packedData.ceDoneSelBits       = data.ceDoneSel;
-
-	return *((uint32_t *)&packedData);
-}
-
-static void vfe_addr_convert(struct msm_vfe_phy_info *pinfo,
-				enum vfe_resp_msg type, void *data, void **ext,
-				int *elen)
-{
-	switch (type) {
-	case VFE_MSG_OUTPUT_P:
-	case VFE_MSG_OUTPUT_V:{
-		pinfo->planar0_off =
-			((struct vfe_message *)data)->_u.msgOutput2.yBuffer;
-		pinfo->planar1_off =
-			((struct vfe_message *)data)->_u.msgOutput2.
-			cbcrBuffer;
-		pinfo->planar2_off = pinfo->planar0_off;
-		ctrl->extdata.bpcInfo =
-			((struct vfe_message *)data)->_u.msgOutput2.bpcInfo;
-		ctrl->extdata.asfInfo =
-			((struct vfe_message *)data)->_u.msgOutput2.asfInfo;
-		ctrl->extdata.frameCounter =
-			((struct vfe_message *)data)->_u.msgOutput2.
-			frameCounter;
-		ctrl->extdata.pmData =
-		((struct vfe_message *)data)->_u.msgOutput2.pmData;
-		*ext = &ctrl->extdata;
-		*elen = sizeof(ctrl->extdata);
-	}
-		break;
-
-	case VFE_MSG_STATS_AF:
-		pinfo->sbuf_phy =
-		((struct vfe_message *)data)->_u.msgStatsAf.afBuffer;
-		break;
-
-	case VFE_MSG_STATS_WE:
-		pinfo->sbuf_phy =
-		((struct vfe_message *)data)->_u.msgStatsWbExp.awbBuffer;
-		break;
-
-	default:
-		break;
-	} /* switch */
-}
-
-static boolean vfe_send_preview_msg(struct msm_vfe_resp *rp,
-			struct vfe_message *msg, void *data);
-static boolean vfe_send_video_msg(struct msm_vfe_resp *rp,
-			struct vfe_message *msg, void *data);
-static boolean vfe_send_mainimage_msg(struct msm_vfe_resp *rp,
-			struct vfe_message *msg, void *data);
-static boolean vfe_send_thumbnail_msg(struct msm_vfe_resp *rp,
-			struct vfe_message *msg, void *data);
-static boolean vfe_send_af_stats_msg(struct msm_vfe_resp *rp,
-			struct vfe_message *msg, void *data);
-static boolean vfe_send_awb_stats_msg(struct msm_vfe_resp *rp,
-			struct vfe_message *msg, void *data);
-static boolean vfe_send_camif_error_msg(struct msm_vfe_resp *rp,
-			struct vfe_message *msg, void *data);
-static boolean vfe_send_bus_overflow_msg(struct msm_vfe_resp *rp,
-			struct vfe_message *msg, void *data);
-static boolean vfe_send_sof_msg(struct msm_vfe_resp *rp,
-			struct vfe_message *msg, void *data);
-
-static boolean invalid(struct msm_vfe_resp *rp,
-		struct vfe_message *_m, void *_d)
-{
-	BUG_ON(1); /* this function should not be called. */
-	return FALSE;
-}
-
-static struct {
-	boolean (*fn)(struct msm_vfe_resp *rp, struct vfe_message *msg,
-		void *data);
-	enum vfe_resp_msg rt; /* reponse type */
-} vfe_funcs[] = {
-	[VFE_MSG_ID_RESET_ACK] = { NULL, VFE_MSG_GENERAL },
-	[VFE_MSG_ID_START_ACK] = { NULL, VFE_MSG_GENERAL },
-	[VFE_MSG_ID_STOP_ACK] = { NULL, VFE_MSG_GENERAL },
-	[VFE_MSG_ID_UPDATE_ACK] = { NULL, VFE_MSG_GENERAL },
-	[VFE_MSG_ID_OUTPUT_P] = { vfe_send_preview_msg, VFE_MSG_OUTPUT_P },
-	[VFE_MSG_ID_OUTPUT_V] = { vfe_send_video_msg, VFE_MSG_OUTPUT_V },
-	[VFE_MSG_ID_OUTPUT_S] = { vfe_send_mainimage_msg, VFE_MSG_OUTPUT_S },
-	[VFE_MSG_ID_OUTPUT_T] = { vfe_send_thumbnail_msg, VFE_MSG_OUTPUT_T },
-	[VFE_MSG_ID_SNAPSHOT_DONE] = { NULL, VFE_MSG_SNAPSHOT },
-	[VFE_MSG_ID_STATS_AUTOFOCUS] = { vfe_send_af_stats_msg,
-		VFE_MSG_STATS_AF },
-	[VFE_MSG_ID_STATS_WB_EXP] = { vfe_send_awb_stats_msg,
-		VFE_MSG_STATS_WE },
-	[VFE_MSG_ID_EPOCH1] = { NULL, VFE_MSG_GENERAL },
-	[VFE_MSG_ID_EPOCH2] = { NULL, VFE_MSG_GENERAL },
-	[VFE_MSG_ID_SYNC_TIMER0_DONE] = { invalid },
-	[VFE_MSG_ID_SYNC_TIMER1_DONE] = { invalid },
-	[VFE_MSG_ID_SYNC_TIMER2_DONE] = { invalid },
-	[VFE_MSG_ID_ASYNC_TIMER0_DONE] = { invalid },
-	[VFE_MSG_ID_ASYNC_TIMER1_DONE] = { invalid },
-	[VFE_MSG_ID_ASYNC_TIMER2_DONE] = { invalid },
-	[VFE_MSG_ID_ASYNC_TIMER3_DONE] = { invalid },
-	[VFE_MSG_ID_AF_OVERFLOW] = { NULL, VFE_MSG_GENERAL },
-	[VFE_MSG_ID_AWB_OVERFLOW] = { NULL, VFE_MSG_GENERAL },
-	[VFE_MSG_ID_AXI_ERROR] = { NULL, VFE_MSG_GENERAL },
-	[VFE_MSG_ID_CAMIF_OVERFLOW] = { NULL, VFE_MSG_GENERAL },
-	[VFE_MSG_ID_VIOLATION] = { invalid },
-	[VFE_MSG_ID_CAMIF_ERROR] = { vfe_send_camif_error_msg,
-		VFE_MSG_GENERAL },
-	[VFE_MSG_ID_BUS_OVERFLOW] = { vfe_send_bus_overflow_msg,
-		VFE_MSG_GENERAL },
-	[VFE_MSG_ID_SOF_ACK] = { vfe_send_sof_msg,
-		VFE_MSG_GENERAL },
-};
-
-static void vfe_proc_ops(enum VFE_MESSAGE_ID id, void *data)
-{
-	struct msm_vfe_resp *rp;
-	struct vfe_message *msg;
-
-	if (id >= ARRAY_SIZE(vfe_funcs) || vfe_funcs[id].fn == invalid) {
-		pr_err("%s: invalid VFE message id %d\n", __func__, id);
-		return;
-	}
-
-	/* In 8k, OUTPUT1 & OUTPUT2 messages arrive before SNAPSHOT_DONE.
-	 * We don't send such messages to the user.  Note that we can do
-	 * this in the vfe_func[] callback, but that would cause us to
-	 * allocate and then immediately free the msm_vfe_resp structure,
-	 * which is wasteful.
-	 */
-	if ((ctrl->vfeOperationMode == VFE_START_OPERATION_MODE_SNAPSHOT) &&
-			(id == VFE_MSG_ID_OUTPUT_T ||
-			 id == VFE_MSG_ID_OUTPUT_S))
-		return;
-
-	rp = ctrl->resp->vfe_alloc(sizeof(*rp) +
-					(vfe_funcs[id].fn ? sizeof(*msg) : 0),
-					ctrl->syncdata,
-					GFP_ATOMIC);
-	if (!rp) {
-		pr_err("%s: out of memory\n", __func__);
-		return;
-	}
-
-	rp->type = vfe_funcs[id].rt;
-	rp->evt_msg.type = MSM_CAMERA_MSG;
-	rp->evt_msg.msg_id = id;
-
-	if (!vfe_funcs[id].fn) {
-		rp->evt_msg.len = 0;
-		rp->evt_msg.data = 0;
-	} else {
-		/* populate the message accordingly */
-		if (vfe_funcs[id].fn)
-			rp->evt_msg.data = msg =
-				(struct vfe_message *)(rp + 1);
-		else
-			rp->evt_msg.data = msg = 0;
-		rp->evt_msg.len = sizeof(*msg);
-		msg->_d = id;
-		if (vfe_funcs[id].fn(rp, msg, data) == FALSE) {
-			pr_warning("%s: freeing memory: handler for %d "
-				"returned false\n", __func__, id);
-			ctrl->resp->vfe_free(rp);
-			return;
-		}
-}
-
-	ctrl->resp->vfe_resp(rp, MSM_CAM_Q_VFE_MSG, ctrl->syncdata, GFP_KERNEL);
-}
-
-static boolean vfe_send_bus_overflow_msg(struct msm_vfe_resp *rp,
-			struct vfe_message *msg,
-			void *data)
-{
-#if 0
-	memcpy(&(msg->_u.msgBusOverflow),
-		&ctrl->vfePmData, sizeof(ctrl->vfePmData));
-#endif
-	return TRUE;
-}
-
-static boolean vfe_send_sof_msg(struct msm_vfe_resp *rp,
-			struct vfe_message *msg,
-			void *data)
-{
-	return TRUE;
-}
-static boolean vfe_send_camif_error_msg(struct msm_vfe_resp *rp,
-			struct vfe_message *msg,
-			void *data)
-{
-#if 0
-	memcpy(&(msg->_u.msgCamifError),
-	       &ctrl->vfeCamifStatusLocal, sizeof(ctrl->vfeCamifStatusLocal));
-#endif
-	return TRUE;
-}
-
-static void vfe_process_error_irq(struct vfe_interrupt_status *irqstatus)
-{
-	/* all possible error irq.  Note error irqs are not enabled, it is
-	 * checked only when other interrupts are present. */
-	if (irqstatus->afOverflowIrq)
-		vfe_proc_ops(VFE_MSG_ID_AF_OVERFLOW, NULL);
-
-	if (irqstatus->awbOverflowIrq)
-		vfe_proc_ops(VFE_MSG_ID_AWB_OVERFLOW, NULL);
-
-	if (irqstatus->axiErrorIrq)
-		vfe_proc_ops(VFE_MSG_ID_AXI_ERROR, NULL);
-
-	if (irqstatus->busOverflowIrq)
-		vfe_proc_ops(VFE_MSG_ID_BUS_OVERFLOW, NULL);
-
-	if (irqstatus->camifErrorIrq) {
-		CDBG("vfe_irq: camif errors\n");
-		vfe_proc_ops(VFE_MSG_ID_CAMIF_ERROR, NULL);
-	}
-
-	if (irqstatus->camifOverflowIrq)
-		vfe_proc_ops(VFE_MSG_ID_CAMIF_OVERFLOW, NULL);
-
-	if (irqstatus->violationIrq)
-		pr_err("%s: violation irq\n", __func__);
-}
-
-static void vfe_process_camif_sof_irq(void)
-{
-	/* increment the frame id number. */
-	ctrl->vfeFrameId++;
-
-	CDBG("camif_sof_irq, frameId = %d\n", ctrl->vfeFrameId);
-
-	/* In snapshot mode, if frame skip is programmed,
-	* need to check it accordingly to stop camif at
-	* correct frame boundary. For the dropped frames,
-	* there won't be any output path irqs, but there is
-	* still SOF irq, which can help us determine when
-	* to stop the camif.
-	*/
-	if (ctrl->vfeOperationMode) {
-		if ((1 << ctrl->vfeFrameSkipCount)&ctrl->vfeFrameSkipPattern) {
-
-			ctrl->vfeSnapShotCount--;
-			if (ctrl->vfeSnapShotCount == 0)
-				/* terminate vfe pipeline at frame boundary. */
-				writel(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
-					ctrl->vfebase + CAMIF_COMMAND);
-		}
-
-		/* update frame skip counter for bit checking. */
-		ctrl->vfeFrameSkipCount++;
-		if (ctrl->vfeFrameSkipCount == (ctrl->vfeFrameSkipPeriod + 1))
-			ctrl->vfeFrameSkipCount = 0;
-	}
-	vfe_proc_ops(VFE_MSG_ID_SOF_ACK, NULL);
-}
-
-static boolean vfe_get_af_pingpong_status(void)
-{
-	uint32_t busPingPongStatus =
-		readl(ctrl->vfebase + VFE_BUS_PINGPONG_STATUS);
-	return !!(busPingPongStatus & VFE_AF_PINGPONG_STATUS_BIT);
-}
-
-static uint32_t vfe_read_af_buf_addr(boolean pipo)
-{
-	if (pipo == FALSE)
-		return readl(ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR);
-	else
-		return readl(ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR);
-}
-
-static void vfe_update_af_buf_addr(boolean pipo, uint32_t addr)
-{
-	if (pipo == FALSE)
-		writel(addr, ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR);
-	else
-		writel(addr, ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR);
-}
-
-static boolean vfe_send_af_stats_msg(struct msm_vfe_resp *rp,
-		struct vfe_message *msg, void *data)
-{
-	uint32_t afBufAddress = (uint32_t)data;
-
-	/* fill message with right content. */
-	/* @todo This is causing issues, need further investigate */
-	/* spin_lock_irqsave(&ctrl->state_lock, flags); */
-	if (ctrl->vstate != VFE_STATE_ACTIVE)
-		return FALSE;
-
-	msg->_u.msgStatsAf.afBuffer = afBufAddress;
-	msg->_u.msgStatsAf.frameCounter = ctrl->vfeFrameId;
-
-	ctrl->afStatsControl.ackPending = TRUE;
-
-	vfe_addr_convert(&(rp->phy), rp->type, msg, NULL, NULL);
-	/* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
-	return TRUE;
-}
-
-static void vfe_process_stats_af_irq(void)
-{
-	boolean bufferAvailable;
-
-	if (!(ctrl->afStatsControl.ackPending)) {
-
-		/* read hardware status. */
-		ctrl->afStatsControl.pingPongStatus =
-			vfe_get_af_pingpong_status();
-
-		bufferAvailable = (ctrl->afStatsControl.pingPongStatus) ^ 1;
-
-		ctrl->afStatsControl.bufToRender =
-			vfe_read_af_buf_addr(bufferAvailable);
-
-		/* update the same buffer address (ping or pong) */
-		vfe_update_af_buf_addr(bufferAvailable,
-			ctrl->afStatsControl.nextFrameAddrBuf);
-
-		vfe_proc_ops(VFE_MSG_ID_STATS_AUTOFOCUS,
-			(void *)ctrl->afStatsControl.bufToRender);
-	} else
-		ctrl->afStatsControl.droppedStatsFrameCount++;
-}
-
-static boolean vfe_get_awb_pingpong_status(void)
-{
-	uint32_t busPingPongStatus =
-
-		readl(ctrl->vfebase + VFE_BUS_PINGPONG_STATUS);
-
-	return !!(busPingPongStatus & VFE_AWB_PINGPONG_STATUS_BIT);
-
-}
-
-static uint32_t vfe_read_awb_buf_addr(boolean pingpong)
-{
-	if (pingpong == FALSE)
-		return readl(ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR);
-	else
-		return readl(ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR);
-}
-
-static void vfe_update_awb_buf_addr(boolean pingpong, uint32_t addr)
-{
-	if (pingpong == FALSE)
-		writel(addr, ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR);
-	else
-		writel(addr, ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR);
-}
-
-static boolean vfe_send_awb_stats_msg(struct msm_vfe_resp *rp,
-		struct vfe_message *msg, void *data)
-{
-	uint32_t awbBufAddress = (uint32_t)data;
-
-	/* fill message with right content. */
-	/* @todo This is causing issues, need further investigate */
-	/* spin_lock_irqsave(&ctrl->state_lock, flags); */
-	if (ctrl->vstate != VFE_STATE_ACTIVE)
-		return FALSE;
-
-	msg->_u.msgStatsWbExp.awbBuffer = awbBufAddress;
-	msg->_u.msgStatsWbExp.frameCounter = ctrl->vfeFrameId;
-
-
-	ctrl->awbStatsControl.ackPending = TRUE;
-
-	vfe_addr_convert(&(rp->phy),
-			rp->type, msg,
-			NULL, NULL);
-
-	return TRUE;
-}
-
-static void vfe_process_stats_awb_irq(void)
-{
-	boolean bufferAvailable;
-
-	if (!(ctrl->awbStatsControl.ackPending)) {
-
-		ctrl->awbStatsControl.pingPongStatus =
-			vfe_get_awb_pingpong_status();
-
-		bufferAvailable = (ctrl->awbStatsControl.pingPongStatus) ^ 1;
-
-		ctrl->awbStatsControl.bufToRender =
-			vfe_read_awb_buf_addr(bufferAvailable);
-
-		vfe_update_awb_buf_addr(bufferAvailable,
-			ctrl->awbStatsControl.nextFrameAddrBuf);
-
-		vfe_proc_ops(VFE_MSG_ID_STATS_WB_EXP,
-			(void *)ctrl->awbStatsControl.bufToRender);
-
-	} else
-		ctrl->awbStatsControl.droppedStatsFrameCount++;
-}
-
-static void vfe_write_gamma_table(uint8_t channel,
-	boolean bank, int16_t *pTable)
-{
-	uint16_t i;
-
-	enum VFE_DMI_RAM_SEL dmiRamSel = NO_MEM_SELECTED;
-
-	switch (channel) {
-	case 0:
-		if (bank == 0)
-			dmiRamSel = RGBLUT_RAM_CH0_BANK0;
-		else
-			dmiRamSel = RGBLUT_RAM_CH0_BANK1;
-		break;
-
-	case 1:
-		if (bank == 0)
-			dmiRamSel = RGBLUT_RAM_CH1_BANK0;
-		else
-			dmiRamSel = RGBLUT_RAM_CH1_BANK1;
-		break;
-
-	case 2:
-		if (bank == 0)
-			dmiRamSel = RGBLUT_RAM_CH2_BANK0;
-		else
-			dmiRamSel = RGBLUT_RAM_CH2_BANK1;
-		break;
-
-	default:
-		break;
-	}
-
-	vfe_program_dmi_cfg(dmiRamSel);
-
-	for (i = 0; i < VFE_GAMMA_TABLE_LENGTH; i++) {
-		writel((uint32_t)(*pTable), ctrl->vfebase + VFE_DMI_DATA_LO);
-		pTable++;
-	}
-
-	/* After DMI transfer, need to set the DMI_CFG to unselect any SRAM
-	unselect the SRAM Bank. */
-	writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG);
-}
-
-static void vfe_prog_hw_testgen_cmd(uint32_t value)
-{
-	writel(value, ctrl->vfebase + VFE_HW_TESTGEN_CMD);
-}
-
-static inline void vfe_read_irq_status(struct vfe_irq_thread_msg *out)
-{
-	uint32_t *temp;
-
-	memset(out, 0, sizeof(struct vfe_irq_thread_msg));
-
-	temp = (uint32_t *)(ctrl->vfebase + VFE_IRQ_STATUS);
-	out->vfeIrqStatus = readl(temp);
-
-	temp = (uint32_t *)(ctrl->vfebase + CAMIF_STATUS);
-	out->camifStatus = readl(temp);
-
-/*	this for YUV performance tuning
-	writel(0x7, ctrl->vfebase + CAMIF_COMMAND);
-	writel(0x3, ctrl->vfebase + CAMIF_COMMAND);
-	CDBG("camifStatus  = 0x%x\n", out->camifStatus);
-*/
-/*
-	temp = (uint32_t *)(ctrl->vfebase + VFE_DEMOSAIC_STATUS);
-	out->demosaicStatus = readl(temp);
-
-	temp = (uint32_t *)(ctrl->vfebase + VFE_ASF_MAX_EDGE);
-	out->asfMaxEdge = readl(temp);
-
-	temp = (uint32_t *)(ctrl->vfebase + VFE_BUS_ENC_Y_WR_PM_STATS_0);
-*/
-
-#if 0
-	out->pmInfo.encPathPmInfo.yWrPmStats0      = readl(temp++);
-	out->pmInfo.encPathPmInfo.yWrPmStats1      = readl(temp++);
-	out->pmInfo.encPathPmInfo.cbcrWrPmStats0   = readl(temp++);
-	out->pmInfo.encPathPmInfo.cbcrWrPmStats1   = readl(temp++);
-	out->pmInfo.viewPathPmInfo.yWrPmStats0     = readl(temp++);
-	out->pmInfo.viewPathPmInfo.yWrPmStats1     = readl(temp++);
-	out->pmInfo.viewPathPmInfo.cbcrWrPmStats0  = readl(temp++);
-	out->pmInfo.viewPathPmInfo.cbcrWrPmStats1  = readl(temp);
-#endif /* if 0 Jeff */
-}
-
-static void
-vfe_parse_interrupt_status(struct vfe_interrupt_status *ret,
-uint32_t irqStatusIn)
-{
-	struct vfe_irqenable hwstat;
-	boolean temp;
-
-	memset(&hwstat, 0, sizeof(hwstat));
-	memset(ret, 0, sizeof(*ret));
-
-	hwstat = *((struct vfe_irqenable *)(&irqStatusIn));
-
-	ret->camifErrorIrq = hwstat.camifErrorIrq;
-	ret->camifSofIrq = hwstat.camifSofIrq;
-	ret->camifEolIrq = hwstat.camifEolIrq;
-	ret->camifEofIrq = hwstat.camifEofIrq;
-	ret->camifEpoch1Irq = hwstat.camifEpoch1Irq;
-	ret->camifEpoch2Irq = hwstat.camifEpoch2Irq;
-	ret->camifOverflowIrq = hwstat.camifOverflowIrq;
-	ret->ceIrq = hwstat.ceIrq;
-	ret->regUpdateIrq = hwstat.regUpdateIrq;
-	ret->resetAckIrq = hwstat.resetAckIrq;
-	ret->encYPingpongIrq = hwstat.encYPingpongIrq;
-	ret->encCbcrPingpongIrq = hwstat.encCbcrPingpongIrq;
-	ret->viewYPingpongIrq = hwstat.viewYPingpongIrq;
-	ret->viewCbcrPingpongIrq = hwstat.viewCbcrPingpongIrq;
-	ret->rdPingpongIrq = hwstat.rdPingpongIrq;
-	ret->afPingpongIrq = hwstat.afPingpongIrq;
-	ret->awbPingpongIrq = hwstat.awbPingpongIrq;
-	ret->histPingpongIrq = hwstat.histPingpongIrq;
-	ret->encIrq = hwstat.encIrq;
-	ret->viewIrq = hwstat.viewIrq;
-	ret->busOverflowIrq = hwstat.busOverflowIrq;
-	ret->afOverflowIrq = hwstat.afOverflowIrq;
-	ret->awbOverflowIrq = hwstat.awbOverflowIrq;
-	ret->syncTimer0Irq = hwstat.syncTimer0Irq;
-	ret->syncTimer1Irq = hwstat.syncTimer1Irq;
-	ret->syncTimer2Irq = hwstat.syncTimer2Irq;
-	ret->asyncTimer0Irq = hwstat.asyncTimer0Irq;
-	ret->asyncTimer1Irq = hwstat.asyncTimer1Irq;
-	ret->asyncTimer2Irq = hwstat.asyncTimer2Irq;
-	ret->asyncTimer3Irq = hwstat.asyncTimer3Irq;
-	ret->axiErrorIrq = hwstat.axiErrorIrq;
-	ret->violationIrq = hwstat.violationIrq;
-
-	/* logic OR of any error bits
-	 * although each irq corresponds to a bit, the data type here is a
-	 * boolean already. hence use logic operation.
-	 */
-	temp =
-	    ret->camifErrorIrq ||
-	    ret->camifOverflowIrq ||
-	    ret->afOverflowIrq ||
-	    ret->awbOverflowIrq ||
-	    ret->awbPingpongIrq ||
-	    ret->afPingpongIrq ||
-	    ret->busOverflowIrq || ret->axiErrorIrq || ret->violationIrq;
-
-	ret->anyErrorIrqs = temp;
-
-	/* logic OR of any output path bits*/
-	temp = ret->encYPingpongIrq || ret->encCbcrPingpongIrq || ret->encIrq;
-
-	ret->anyOutput2PathIrqs = temp;
-
-	temp = ret->viewYPingpongIrq || ret->viewCbcrPingpongIrq ||
-		ret->viewIrq;
-
-	ret->anyOutput1PathIrqs = temp;
-
-	ret->anyOutputPathIrqs =
-	    ret->anyOutput1PathIrqs || ret->anyOutput2PathIrqs;
-
-	/* logic OR of any sync timer bits*/
-	temp = ret->syncTimer0Irq || ret->syncTimer1Irq || ret->syncTimer2Irq;
-
-	ret->anySyncTimerIrqs = temp;
-
-	/* logic OR of any async timer bits*/
-	temp =
-	    ret->asyncTimer0Irq ||
-	    ret->asyncTimer1Irq || ret->asyncTimer2Irq || ret->asyncTimer3Irq;
-
-	ret->anyAsyncTimerIrqs = temp;
-
-	/* bool for all interrupts that are not allowed in idle state */
-	temp =
-	    ret->anyErrorIrqs ||
-	    ret->anyOutputPathIrqs ||
-	    ret->anySyncTimerIrqs ||
-	    ret->regUpdateIrq ||
-	    ret->awbPingpongIrq ||
-	    ret->afPingpongIrq ||
-	    ret->camifSofIrq || ret->camifEpoch2Irq || ret->camifEpoch1Irq;
-
-	ret->anyIrqForActiveStatesOnly = temp;
-}
-
-static void
-vfe_get_asf_frame_info(struct vfe_frame_asf_info *rc,
-struct vfe_irq_thread_msg *in)
-{
-	struct vfe_asf_info     asfInfoTemp;
-
-	memset(rc, 0, sizeof(*rc));
-	memset(&asfInfoTemp, 0, sizeof(asfInfoTemp));
-
-	asfInfoTemp = *((struct vfe_asf_info *)(&(in->asfMaxEdge)));
-
-	rc->asfHbiCount = asfInfoTemp.HBICount;
-	rc->asfMaxEdge = asfInfoTemp.maxEdge;
-}
-
-static void
-vfe_get_demosaic_frame_info(struct vfe_frame_bpc_info *rc,
-struct vfe_irq_thread_msg *in)
-{
-	struct vfe_bps_info     bpcInfoTemp;
-
-	memset(rc, 0, sizeof(*rc));
-	memset(&bpcInfoTemp, 0, sizeof(bpcInfoTemp));
-
-	bpcInfoTemp = *((struct vfe_bps_info *)(&(in->demosaicStatus)));
-
-	rc->greenDefectPixelCount = bpcInfoTemp.greenBadPixelCount;
-
-	rc->redBlueDefectPixelCount = bpcInfoTemp.RedBlueBadPixelCount;
-}
-
-static void
-vfe_get_camif_status(struct vfe_msg_camif_status *rc,
-struct vfe_irq_thread_msg *in)
-{
-	struct vfe_camif_stats camifStatusTemp;
-
-	memset(rc, 0, sizeof(*rc));
-	memset(&camifStatusTemp, 0, sizeof(camifStatusTemp));
-
-	camifStatusTemp = *((struct vfe_camif_stats *)(&(in->camifStatus)));
-
-	rc->camifState = (boolean) camifStatusTemp.camifHalt;
-	rc->lineCount = camifStatusTemp.lineCount;
-	rc->pixelCount = camifStatusTemp.pixelCount;
-}
-
-static void
-vfe_get_performance_monitor_data(struct vfe_bus_performance_monitor *rc,
-		struct vfe_irq_thread_msg *in)
-{
-	memset(rc, 0, sizeof(*rc));
-
-	rc->encPathPmInfo.yWrPmStats0 = in->pmInfo.encPathPmInfo.yWrPmStats0;
-	rc->encPathPmInfo.yWrPmStats1 = in->pmInfo.encPathPmInfo.yWrPmStats1;
-	rc->encPathPmInfo.cbcrWrPmStats0 =
-		in->pmInfo.encPathPmInfo.cbcrWrPmStats0;
-	rc->encPathPmInfo.cbcrWrPmStats1 =
-		in->pmInfo.encPathPmInfo.cbcrWrPmStats1;
-	rc->viewPathPmInfo.yWrPmStats0 = in->pmInfo.viewPathPmInfo.yWrPmStats0;
-	rc->viewPathPmInfo.yWrPmStats1 = in->pmInfo.viewPathPmInfo.yWrPmStats1;
-	rc->viewPathPmInfo.cbcrWrPmStats0 =
-		in->pmInfo.viewPathPmInfo.cbcrWrPmStats0;
-	rc->viewPathPmInfo.cbcrWrPmStats1 =
-	    in->pmInfo.viewPathPmInfo.cbcrWrPmStats1;
-}
-
-static void vfe_process_reg_update_irq(void)
-{
-	CDBG("vfe_process_reg_update_irq: ackPendingFlag is %d\n",
-	ctrl->vfeStartAckPendingFlag);
-	if (ctrl->vfeStartAckPendingFlag == TRUE) {
-		vfe_proc_ops(VFE_MSG_ID_START_ACK, NULL);
-		ctrl->vfeStartAckPendingFlag = FALSE;
-	} else
-		vfe_proc_ops(VFE_MSG_ID_UPDATE_ACK, NULL);
-}
-
-static void vfe_process_reset_irq(void)
-{
-	/* unsigned long flags; */
-
-	/* @todo This is causing issues, need further investigate */
-	/* spin_lock_irqsave(&ctrl->state_lock, flags); */
-	ctrl->vstate = VFE_STATE_IDLE;
-	/* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
-
-	if (ctrl->vfeStopAckPending == TRUE) {
-		ctrl->vfeStopAckPending = FALSE;
-		vfe_proc_ops(VFE_MSG_ID_STOP_ACK, NULL);
-	} else {
-		vfe_set_default_reg_values();
-		vfe_proc_ops(VFE_MSG_ID_RESET_ACK, NULL);
-	}
-}
-
-static void vfe_process_pingpong_irq(struct vfe_output_path *in,
-	uint8_t fragmentCount)
-{
-	uint16_t circularIndex;
-	uint32_t nextFragmentAddr;
-
-	/* get next fragment address from circular buffer */
-	circularIndex    = (in->fragIndex) % (2 * fragmentCount);
-	nextFragmentAddr = in->addressBuffer[circularIndex];
-
-	in->fragIndex = circularIndex + 1;
-
-	/* use next fragment to program hardware ping/pong address. */
-	if (in->hwCurrentFlag == ping) {
-		writel(nextFragmentAddr, in->hwRegPingAddress);
-		in->hwCurrentFlag = pong;
-
-	} else {
-		writel(nextFragmentAddr, in->hwRegPongAddress);
-		in->hwCurrentFlag = ping;
-	}
-}
-
-static boolean vfe_send_video_msg(struct msm_vfe_resp *rp,
-		struct vfe_message *msg, void *data)
-{
-	struct vfe_msg_output *pPayload = data;
-
-	if (ctrl->vstate != VFE_STATE_ACTIVE)
-		return FALSE;
-	memcpy(&(msg->_u),
-		(void *)pPayload, sizeof(struct vfe_msg_output));
-
-	rp->phy.output_id = OUTPUT_TYPE_V;
-	CDBG("vfe_send_video_msg rp->type= %d\n", rp->type);
-
-	vfe_addr_convert(&(rp->phy),
-			rp->type, msg,
-			&(rp->extdata), &(rp->extlen));
-	return TRUE;
-}
-
-static boolean vfe_send_preview_msg(struct msm_vfe_resp *rp,
-		struct vfe_message *msg, void *data)
-{
-	struct vfe_msg_output *pPayload = data;
-
-	if (ctrl->vstate != VFE_STATE_ACTIVE)
-		return FALSE;
-
-	memcpy(&(msg->_u), (void *)pPayload, sizeof(struct vfe_msg_output));
-
-	rp->phy.output_id = OUTPUT_TYPE_P;
-	CDBG("vfe_send_preview_msg rp->type= %d\n", rp->type);
-
-	vfe_addr_convert(&(rp->phy),
-			rp->type, msg,
-			&(rp->extdata), &(rp->extlen));
-
-	return TRUE;
-}
-
-
-static boolean vfe_send_thumbnail_msg(struct msm_vfe_resp *rp,
-		struct vfe_message *msg, void *data)
-{
-	struct vfe_msg_output *pPayload = data;
-
-	if (ctrl->vstate != VFE_STATE_ACTIVE)
-		return FALSE;
-
-	memcpy(&(msg->_u), (void *)pPayload, sizeof(struct vfe_msg_output));
-
-	rp->phy.output_id = OUTPUT_TYPE_T;
-	CDBG("vfe_send_thumbnail_msg rp->type= %d\n", rp->type);
-
-	if (ctrl->viewPath.snapshotPendingCount <= 1)
-		ctrl->viewPath.ackPending = FALSE;
-
-	vfe_addr_convert(&(rp->phy),
-			rp->type, msg,
-			&(rp->extdata), &(rp->extlen));
-	return TRUE;
-}
-
-static boolean vfe_send_mainimage_msg(struct msm_vfe_resp *rp,
-		struct vfe_message *msg, void *data)
-{
-	struct vfe_msg_output *pPayload = data;
-
-	if (ctrl->vstate != VFE_STATE_ACTIVE)
-		return FALSE;
-
-	memcpy(&(msg->_u), (void *)pPayload, sizeof(struct vfe_msg_output));
-
-	rp->phy.output_id = OUTPUT_TYPE_S;
-	CDBG("vfe_send_mainimage_msg rp->type= %d\n", rp->type);
-
-	if (ctrl->encPath.snapshotPendingCount <= 1) {
-		ctrl->encPath.ackPending = FALSE;
-	}
-
-	vfe_addr_convert(&(rp->phy),
-			rp->type, msg,
-			&(rp->extdata), &(rp->extlen));
-
-	return TRUE;
-}
-
-static void vfe_send_output_msg(boolean whichOutputPath,
-	uint32_t yPathAddr, uint32_t cbcrPathAddr)
-{
-	struct vfe_msg_output msgPayload;
-
-	msgPayload.yBuffer = yPathAddr;
-	msgPayload.cbcrBuffer = cbcrPathAddr;
-
-	/* asf info is common for both output1 and output2 */
-#if 0
-	msgPayload.asfInfo.asfHbiCount = ctrl->vfeAsfFrameInfo.asfHbiCount;
-	msgPayload.asfInfo.asfMaxEdge = ctrl->vfeAsfFrameInfo.asfMaxEdge;
-
-	/* demosaic info is common for both output1 and output2 */
-	msgPayload.bpcInfo.greenDefectPixelCount =
-		ctrl->vfeBpcFrameInfo.greenDefectPixelCount;
-	msgPayload.bpcInfo.redBlueDefectPixelCount =
-		ctrl->vfeBpcFrameInfo.redBlueDefectPixelCount;
-#endif /* if 0 */
-
-	/* frame ID is common for both paths. */
-	msgPayload.frameCounter = ctrl->vfeFrameId;
-
-	if (whichOutputPath) {
-		/* msgPayload.pmData = ctrl->vfePmData.encPathPmInfo; */
-		ctrl->encPath.ackPending = TRUE;
-
-		if (ctrl->vfeOperationMode == 0) {
-			if (ctrl->axiOutputMode ==
-				VFE_AXI_OUTPUT_MODE_Output1AndOutput2) {
-				/* video mode */
-				vfe_proc_ops(VFE_MSG_ID_OUTPUT_V, &msgPayload);
-			} else{
-				/* preview mode */
-				vfe_proc_ops(VFE_MSG_ID_OUTPUT_P, &msgPayload);
-			}
-		} else {
-			vfe_proc_ops(VFE_MSG_ID_OUTPUT_S, &msgPayload);
-		}
-
-	} else {
-		/* physical output1 path from vfe */
-		ctrl->viewPath.ackPending = TRUE;
-
-		if (ctrl->vfeOperationMode == 0) {
-			vfe_proc_ops(VFE_MSG_ID_OUTPUT_P, &msgPayload);
-			CDBG(" video mode display output.\n");
-
-		} else{
-			vfe_proc_ops(VFE_MSG_ID_OUTPUT_T, &msgPayload);
-			CDBG(" snapshot mode thumbnail output.\n");
-		}
-	}
-}
-
-static void vfe_process_frame_done_irq_multi_frag(struct vfe_output_path_combo
-						  *in)
-{
-	uint32_t yAddress, cbcrAddress;
-	uint16_t idx;
-	uint32_t *ptrY;
-	uint32_t *ptrCbcr;
-	const uint32_t *ptrSrc;
-	uint8_t i;
-
-	if (!in->ackPending) {
-
-		idx = (in->currentFrame) * (in->fragCount);
-
-		/* Send output message. */
-		yAddress = in->yPath.addressBuffer[idx];
-		cbcrAddress = in->cbcrPath.addressBuffer[idx];
-
-		/* copy next frame to current frame. */
-		ptrSrc  = in->nextFrameAddrBuf;
-		ptrY = (uint32_t *)&in->yPath.addressBuffer[idx];
-		ptrCbcr = (uint32_t *)&in->cbcrPath.addressBuffer[idx];
-
-		/* Copy Y address */
-		for (i = 0; i < in->fragCount; i++)
-			*ptrY++ = *ptrSrc++;
-
-		/* Copy Cbcr address */
-		for (i = 0; i < in->fragCount; i++)
-			*ptrCbcr++ = *ptrSrc++;
-
-		vfe_send_output_msg(in->whichOutputPath, yAddress, cbcrAddress);
-
-	} else {
-		if (in->whichOutputPath == 0)
-			ctrl->vfeDroppedFrameCounts.output1Count++;
-
-		if (in->whichOutputPath == 1)
-			ctrl->vfeDroppedFrameCounts.output2Count++;
-	}
-
-	/* toggle current frame. */
-	in->currentFrame = in->currentFrame^1;
-
-	if (ctrl->vfeOperationMode)
-		in->snapshotPendingCount--;
-}
-
-static void vfe_process_frame_done_irq_no_frag_io(
-		struct vfe_output_path_combo *in,
-		uint32_t *pNextAddr,
-	uint32_t *pdestRenderAddr)
-{
-	uint32_t busPingPongStatus;
-	uint32_t tempAddress;
-
-	/* 1. read hw status register. */
-	busPingPongStatus = readl(ctrl->vfebase + VFE_BUS_PINGPONG_STATUS);
-
-	CDBG("hardware status is 0x%x\n", busPingPongStatus);
-
-	/* 2. determine ping or pong */
-	/* use cbcr status */
-	busPingPongStatus = busPingPongStatus & (1<<(in->cbcrStatusBit));
-
-	/* 3. read out address and update address */
-	if (busPingPongStatus == 0) {
-		/* hw is working on ping, render pong buffer */
-		/* a. read out pong address */
-		/* read out y address. */
-		tempAddress = readl(in->yPath.hwRegPongAddress);
-
-		CDBG("pong 1 addr = 0x%x\n", tempAddress);
-		*pdestRenderAddr++ = tempAddress;
-		/* read out cbcr address. */
-		tempAddress = readl(in->cbcrPath.hwRegPongAddress);
-
-		CDBG("pong 2 addr = 0x%x\n", tempAddress);
-		*pdestRenderAddr = tempAddress;
-
-		/* b. update pong address */
-		writel(*pNextAddr++, in->yPath.hwRegPongAddress);
-		writel(*pNextAddr, in->cbcrPath.hwRegPongAddress);
-	} else {
-		/* hw is working on pong, render ping buffer */
-
-		/* a. read out ping address */
-		tempAddress = readl(in->yPath.hwRegPingAddress);
-		CDBG("ping 1 addr = 0x%x\n", tempAddress);
-		*pdestRenderAddr++ = tempAddress;
-		tempAddress = readl(in->cbcrPath.hwRegPingAddress);
-
-		CDBG("ping 2 addr = 0x%x\n", tempAddress);
-		*pdestRenderAddr = tempAddress;
-
-		/* b. update ping address */
-		writel(*pNextAddr++, in->yPath.hwRegPingAddress);
-		CDBG("NextAddress = 0x%x\n", *pNextAddr);
-		writel(*pNextAddr, in->cbcrPath.hwRegPingAddress);
-	}
-}
-
-static void vfe_process_frame_done_irq_no_frag(struct vfe_output_path_combo *in)
-{
-	uint32_t addressToRender[2];
-
-	if (!in->ackPending) {
-		vfe_process_frame_done_irq_no_frag_io(in,
-						      in->nextFrameAddrBuf,
-						      addressToRender);
-
-		/* use addressToRender to send out message. */
-		vfe_send_output_msg(in->whichOutputPath,
-				addressToRender[0], addressToRender[1]);
-
-	} else {
-		/* ackPending is still there, accumulate dropped frame count.
-		 * These count can be read through ioctrl command. */
-		CDBG("waiting frame ACK\n");
-
-		if (in->whichOutputPath == 0)
-			ctrl->vfeDroppedFrameCounts.output1Count++;
-
-		if (in->whichOutputPath == 1)
-			ctrl->vfeDroppedFrameCounts.output2Count++;
-	}
-
-	/* in case of multishot when upper layer did not ack, there will still
-	 * be a snapshot done msg sent out, even though the number of frames
-	 * sent out may be less than the desired number of frames.  snapshot
-	 * done msg would be helpful to indicate that vfe pipeline has stop,
-	 * and in good known state.
-	 */
-	if (ctrl->vfeOperationMode)
-		in->snapshotPendingCount--;
-}
-
-static void vfe_process_output_path_irq(struct vfe_interrupt_status *irqstatus)
-{
-	/* unsigned long flags; */
-
-	/* process the view path interrupts */
-	if (irqstatus->anyOutput1PathIrqs) {
-		if (ctrl->viewPath.multiFrag) {
-
-			if (irqstatus->viewCbcrPingpongIrq)
-				vfe_process_pingpong_irq(&
-							 (ctrl->viewPath.
-							  cbcrPath),
-							 ctrl->viewPath.
-							 fragCount);
-
-			if (irqstatus->viewYPingpongIrq)
-				vfe_process_pingpong_irq(&
-							 (ctrl->viewPath.yPath),
-							 ctrl->viewPath.
-							 fragCount);
-
-			if (irqstatus->viewIrq)
-				vfe_process_frame_done_irq_multi_frag(&ctrl->
-								      viewPath);
-
-		} else {
-			/* typical case for no fragment,
-			 only frame done irq is enabled. */
-			if (irqstatus->viewIrq)
-				vfe_process_frame_done_irq_no_frag(&ctrl->
-								   viewPath);
-		}
-	}
-
-	/* process the encoder path interrupts */
-	if (irqstatus->anyOutput2PathIrqs) {
-		if (ctrl->encPath.multiFrag) {
-			if (irqstatus->encCbcrPingpongIrq)
-				vfe_process_pingpong_irq(&
-							 (ctrl->encPath.
-							  cbcrPath),
-							 ctrl->encPath.
-							 fragCount);
-
-			if (irqstatus->encYPingpongIrq)
-				vfe_process_pingpong_irq(&(ctrl->encPath.yPath),
-							 ctrl->encPath.
-							 fragCount);
-
-			if (irqstatus->encIrq)
-				vfe_process_frame_done_irq_multi_frag(&ctrl->
-								      encPath);
-
-		} else {
-			if (irqstatus->encIrq)
-				vfe_process_frame_done_irq_no_frag(&ctrl->
-								   encPath);
-		}
-	}
-
-	if (ctrl->vfeOperationMode) {
-		if ((ctrl->encPath.snapshotPendingCount == 0) &&
-				(ctrl->viewPath.snapshotPendingCount == 0)) {
-
-			/* @todo This is causing issues, further investigate */
-			/* spin_lock_irqsave(&ctrl->state_lock, flags); */
-			ctrl->vstate = VFE_STATE_IDLE;
-			/* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
-
-			vfe_proc_ops(VFE_MSG_ID_SNAPSHOT_DONE, NULL);
-			vfe_camif_stop_immediately();
-			vfe_prog_hw_testgen_cmd(VFE_TEST_GEN_STOP);
-			vfe_pm_stop();
-		}
-	}
-}
-
-static void __vfe_do_tasklet(struct isr_queue_cmd *qcmd)
-{
-	if (qcmd->vfeInterruptStatus.regUpdateIrq) {
-		CDBG("irq regUpdateIrq\n");
-		vfe_process_reg_update_irq();
-	}
-
-	if (qcmd->vfeInterruptStatus.resetAckIrq) {
-		CDBG("%s: process resetAckIrq\n", __func__);
-		vfe_process_reset_irq();
-	}
-
-	if (ctrl->vstate != VFE_STATE_ACTIVE)
-		return;
-
-#if 0
-	if (qcmd->vfeInterruptStatus.camifEpoch1Irq)
-		vfe_proc_ops(VFE_MSG_ID_EPOCH1);
-
-	if (qcmd->vfeInterruptStatus.camifEpoch2Irq)
-		vfe_proc_ops(VFE_MSG_ID_EPOCH2);
-#endif /* Jeff */
-
-	/* next, check output path related interrupts. */
-	if (qcmd->vfeInterruptStatus.anyOutputPathIrqs) {
-		CDBG("irq: anyOutputPathIrqs\n");
-		vfe_process_output_path_irq(&qcmd->vfeInterruptStatus);
-	}
-
-	if (qcmd->vfeInterruptStatus.afPingpongIrq)
-		vfe_process_stats_af_irq();
-
-	if (qcmd->vfeInterruptStatus.awbPingpongIrq)
-		vfe_process_stats_awb_irq();
-
-	/* any error irqs*/
-	if (qcmd->vfeInterruptStatus.anyErrorIrqs)
-		vfe_process_error_irq(&qcmd->vfeInterruptStatus);
-
-#if 0
-	if (qcmd->vfeInterruptStatus.anySyncTimerIrqs)
-		vfe_process_sync_timer_irq();
-
-	if (qcmd->vfeInterruptStatus.anyAsyncTimerIrqs)
-		vfe_process_async_timer_irq();
-#endif /* Jeff */
-
-	if (qcmd->vfeInterruptStatus.camifSofIrq) {
-		CDBG("irq: camifSofIrq\n");
-		vfe_process_camif_sof_irq();
-	}
-}
-
-static struct isr_queue_cmd *get_irq_cmd_nosync(void)
-{
-	int old_get = ctrl->irq_get++;
-	ctrl->irq_get = ctrl->irq_get % ARRAY_SIZE(ctrl->irqs);
-	if (ctrl->irq_get == ctrl->irq_put) {
-		pr_err("%s: out of irq command packets\n", __func__);
-		ctrl->irq_get = old_get;
-		return NULL;
-	}
-
-	return ctrl->irqs + old_get;
-}
-
-static struct isr_queue_cmd *next_irq_cmd(void)
-{
-	unsigned long flags;
-	struct isr_queue_cmd *cmd;
-	spin_lock_irqsave(&ctrl->irqs_lock, flags);
-	if (ctrl->irq_get == ctrl->irq_put) {
-		spin_unlock_irqrestore(&ctrl->irqs_lock, flags);
-		return NULL; /* already empty */
-	}
-	cmd = ctrl->irqs + ctrl->irq_put;
-	spin_unlock_irqrestore(&ctrl->irqs_lock, flags);
-	return cmd;
-}
-
-static void put_irq_cmd(void)
-{
-	unsigned long flags;
-	spin_lock_irqsave(&ctrl->irqs_lock, flags);
-	if (ctrl->irq_get == ctrl->irq_put) {
-		spin_unlock_irqrestore(&ctrl->irqs_lock, flags);
-		return; /* already empty */
-	}
-	ctrl->irq_put++;
-	ctrl->irq_put %= ARRAY_SIZE(ctrl->irqs);
-	spin_unlock_irqrestore(&ctrl->irqs_lock, flags);
-}
-
-static void vfe_do_tasklet(unsigned long data)
-{
-	int cnt = 0;
-	unsigned long flags;
-	struct isr_queue_cmd *qcmd = NULL;
-
-	spin_lock_irqsave(&msm_vfe_ctrl_lock, flags);
-	if (!ctrl) {
-		spin_unlock_irqrestore(&msm_vfe_ctrl_lock, flags);
-		return;
-	}
-
-	CDBG("%s\n", __func__);
-
-	while ((qcmd = next_irq_cmd())) {
-		__vfe_do_tasklet(qcmd);
-		put_irq_cmd();
-		cnt++;
-	}
-
-	if (cnt > ARRAY_SIZE(ctrl->irqs)/2)
-		CDBG("%s: serviced %d vfe interrupts\n", __func__, cnt);
-
-	spin_unlock_irqrestore(&msm_vfe_ctrl_lock, flags);
-}
-
-DECLARE_TASKLET(vfe_tasklet, vfe_do_tasklet, 0);
-
-static irqreturn_t vfe_parse_irq(int irq_num, void *data)
-{
-	unsigned long flags;
-	uint32_t irqStatusLocal;
-	struct vfe_irq_thread_msg irq;
-	struct isr_queue_cmd *qcmd;
-
-	CDBG("vfe_parse_irq\n");
-
-	if (!atomic_read(&ctrl->vfe_serv_interrupt))
-		return IRQ_HANDLED;
-
-	vfe_read_irq_status(&irq);
-
-	if (irq.vfeIrqStatus == 0) {
-		CDBG("vfe_parse_irq: irq.vfeIrqStatus is 0\n");
-		return IRQ_HANDLED;
-	}
-
-	if (ctrl->vfeStopAckPending)
-		irqStatusLocal = (VFE_IMASK_WHILE_STOPPING & irq.vfeIrqStatus);
-	else
-		irqStatusLocal =
-			((ctrl->vfeImaskPacked | VFE_IMASK_ERROR_ONLY) &
-				irq.vfeIrqStatus);
-
-	spin_lock_irqsave(&ctrl->irqs_lock, flags);
-	qcmd = get_irq_cmd_nosync();
-	if (!qcmd) {
-		spin_unlock_irqrestore(&ctrl->irqs_lock, flags);
-		goto done;
-	}
-	/* first parse the interrupt status to local data structures. */
-	vfe_parse_interrupt_status(&qcmd->vfeInterruptStatus, irqStatusLocal);
-	vfe_get_asf_frame_info(&qcmd->vfeAsfFrameInfo, &irq);
-	vfe_get_demosaic_frame_info(&qcmd->vfeBpcFrameInfo, &irq);
-	vfe_get_camif_status(&qcmd->vfeCamifStatusLocal, &irq);
-	vfe_get_performance_monitor_data(&qcmd->vfePmData, &irq);
-	spin_unlock_irqrestore(&ctrl->irqs_lock, flags);
-	tasklet_schedule(&vfe_tasklet);
-
-done:
-	/* clear the pending interrupt of the same kind.*/
-	writel(irq.vfeIrqStatus, ctrl->vfebase + VFE_IRQ_CLEAR);
-
-	return IRQ_HANDLED;
-}
-
-int vfe_cmd_init(struct msm_vfe_callback *presp,
-	struct platform_device *pdev, void *sdata)
-{
-	struct resource	*vfemem, *vfeirq, *vfeio;
-	int rc;
-	struct msm_camera_sensor_info *s_info;
-	s_info = pdev->dev.platform_data;
-
-	pdev->resource = s_info->resource;
-	pdev->num_resources = s_info->num_resources;
-
-	vfemem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!vfemem) {
-		pr_err("%s: no mem resource\n", __func__);
-		return -ENODEV;
-	}
-
-	vfeirq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!vfeirq) {
-		pr_err("%s: no irq resource\n", __func__);
-		return -ENODEV;
-	}
-
-	vfeio = request_mem_region(vfemem->start,
-		resource_size(vfemem), pdev->name);
-	if (!vfeio) {
-		pr_err("%s: VFE region already claimed\n", __func__);
-		return -EBUSY;
-	}
-
-	ctrl = kzalloc(sizeof(struct msm_vfe8x_ctrl), GFP_KERNEL);
-	if (!ctrl) {
-		pr_err("%s: out of memory\n", __func__);
-		rc = -ENOMEM;
-		goto cmd_init_failed1;
-	}
-	atomic_set(&ctrl->vfe_serv_interrupt, 0);
-	ctrl->vfeirq  = vfeirq->start;
-
-	ctrl->vfebase =
-		ioremap(vfemem->start, (vfemem->end - vfemem->start) + 1);
-	if (!ctrl->vfebase) {
-		pr_err("%s: ioremap failed\n", __func__);
-		rc = -ENOMEM;
-		goto cmd_init_failed2;
-	}
-
-	rc = request_irq(ctrl->vfeirq, vfe_parse_irq,
-		IRQF_TRIGGER_RISING, "vfe", 0);
-	if (rc < 0) {
-		pr_err("%s: request_irq(%d) failed\n", __func__, ctrl->vfeirq);
-		goto cmd_init_failed2;
-	}
-
-	if (presp && presp->vfe_resp)
-		ctrl->resp = presp;
-	else {
-		pr_err("%s: no vfe_resp function\n", __func__);
-
-		rc = -EIO;
-		goto cmd_init_failed3;
-	}
-
-	ctrl->syncdata = sdata;
-	return 0;
-
-cmd_init_failed3:
-	disable_irq(ctrl->vfeirq);
-	free_irq(ctrl->vfeirq, 0);
-	iounmap(ctrl->vfebase);
-cmd_init_failed2:
-	kfree(ctrl);
-cmd_init_failed1:
-	release_mem_region(vfemem->start, (vfemem->end - vfemem->start) + 1);
-	return rc;
-}
-
-void vfe_cmd_release(struct platform_device *dev)
-{
-	struct resource	*mem;
-	unsigned long flags;
-	atomic_set(&ctrl->vfe_serv_interrupt, 0);
-	disable_irq(ctrl->vfeirq);
-	free_irq(ctrl->vfeirq, 0);
-
-	iounmap(ctrl->vfebase);
-	mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
-	release_mem_region(mem->start, (mem->end - mem->start) + 1);
-
-	spin_lock_irqsave(&msm_vfe_ctrl_lock, flags);
-	kfree(ctrl);
-	ctrl = 0;
-	spin_unlock_irqrestore(&msm_vfe_ctrl_lock, flags);
-}
-
-void vfe_stats_af_stop(void)
-{
-	ctrl->vfeStatsCmdLocal.autoFocusEnable = FALSE;
-	ctrl->vfeImaskLocal.afPingpongIrq = FALSE;
-}
-
-void vfe_stop(void)
-{
-	int spin_cnt = 0;
-	uint32_t vfeAxiStauts;
-
-	/* for reset hw modules, and send msg when reset_irq comes.*/
-	ctrl->vfeStopAckPending = TRUE;
-
-	ctrl->vfeStatsPingPongReloadFlag = FALSE;
-	vfe_pm_stop();
-
-	/* disable all interrupts.  */
-	vfe_program_irq_mask(VFE_DISABLE_ALL_IRQS);
-
-	/* in either continuous or snapshot mode, stop command can be issued
-	 * at any time.
-	 */
-	vfe_camif_stop_immediately();
-	vfe_program_axi_cmd(AXI_HALT);
-	vfe_prog_hw_testgen_cmd(VFE_TEST_GEN_STOP);
-
-	do {
-		vfeAxiStauts = vfe_read_axi_status();
-		spin_cnt++;
-	} while (!(vfeAxiStauts & AXI_STATUS_BUSY_MASK));
-	if (spin_cnt > 1)
-		pr_warning("%s: spin_cnt %d\n", __func__, spin_cnt);
-
-	vfe_program_axi_cmd(AXI_HALT_CLEAR);
-
-	/* clear all pending interrupts */
-	writel(VFE_CLEAR_ALL_IRQS, ctrl->vfebase + VFE_IRQ_CLEAR);
-
-	/* enable reset_ack and async timer interrupt only while stopping
-	 * the pipeline.
-	 */
-	vfe_program_irq_mask(VFE_IMASK_WHILE_STOPPING);
-
-	vfe_program_global_reset_cmd(VFE_RESET_UPON_STOP_CMD);
-}
-
-void vfe_update(void)
-{
-	ctrl->vfeModuleEnableLocal.statsEnable =
-		ctrl->vfeStatsCmdLocal.autoFocusEnable |
-		ctrl->vfeStatsCmdLocal.axwEnable;
-
-	vfe_reg_module_cfg(&ctrl->vfeModuleEnableLocal);
-
-	vfe_program_stats_cmd(&ctrl->vfeStatsCmdLocal);
-
-	ctrl->vfeImaskPacked = vfe_irq_pack(ctrl->vfeImaskLocal);
-	vfe_program_irq_mask(ctrl->vfeImaskPacked);
-
-	if ((ctrl->vfeModuleEnableLocal.statsEnable == TRUE) &&
-			(ctrl->vfeStatsPingPongReloadFlag == FALSE)) {
-		ctrl->vfeStatsPingPongReloadFlag = TRUE;
-
-		ctrl->vfeBusCmdLocal.statsPingpongReload = TRUE;
-		vfe_reg_bus_cmd(&ctrl->vfeBusCmdLocal);
-	}
-
-	vfe_program_reg_update_cmd(VFE_REG_UPDATE_TRIGGER);
-}
-
-int vfe_rgb_gamma_update(struct vfe_cmd_rgb_gamma_config *in)
-{
-	int rc = 0;
-
-	ctrl->vfeModuleEnableLocal.rgbLUTEnable = in->enable;
-
-	switch (in->channelSelect) {
-	case RGB_GAMMA_CH0_SELECTED:
-		ctrl->vfeGammaLutSel.ch0BankSelect ^= 1;
-		vfe_write_gamma_table(0,
-				      ctrl->vfeGammaLutSel.ch0BankSelect,
-				      in->table);
-		break;
-
-	case RGB_GAMMA_CH1_SELECTED:
-		ctrl->vfeGammaLutSel.ch1BankSelect ^= 1;
-		vfe_write_gamma_table(1,
-				      ctrl->vfeGammaLutSel.ch1BankSelect,
-				      in->table);
-		break;
-
-	case RGB_GAMMA_CH2_SELECTED:
-		ctrl->vfeGammaLutSel.ch2BankSelect ^= 1;
-		vfe_write_gamma_table(2,
-				      ctrl->vfeGammaLutSel.ch2BankSelect,
-				      in->table);
-		break;
-
-	case RGB_GAMMA_CH0_CH1_SELECTED:
-		ctrl->vfeGammaLutSel.ch0BankSelect ^= 1;
-		ctrl->vfeGammaLutSel.ch1BankSelect ^= 1;
-		vfe_write_gamma_table(0, ctrl->vfeGammaLutSel.ch0BankSelect,
-			in->table);
-		vfe_write_gamma_table(1, ctrl->vfeGammaLutSel.ch1BankSelect,
-			in->table);
-		break;
-
-	case RGB_GAMMA_CH0_CH2_SELECTED:
-		ctrl->vfeGammaLutSel.ch0BankSelect ^= 1;
-		ctrl->vfeGammaLutSel.ch2BankSelect ^= 1;
-		vfe_write_gamma_table(0, ctrl->vfeGammaLutSel.ch0BankSelect,
-			in->table);
-		vfe_write_gamma_table(2, ctrl->vfeGammaLutSel.ch2BankSelect,
-			in->table);
-		break;
-
-	case RGB_GAMMA_CH1_CH2_SELECTED:
-		ctrl->vfeGammaLutSel.ch1BankSelect ^= 1;
-		ctrl->vfeGammaLutSel.ch2BankSelect ^= 1;
-		vfe_write_gamma_table(1, ctrl->vfeGammaLutSel.ch1BankSelect,
-			in->table);
-		vfe_write_gamma_table(2, ctrl->vfeGammaLutSel.ch2BankSelect,
-			in->table);
-		break;
-
-	case RGB_GAMMA_CH0_CH1_CH2_SELECTED:
-		ctrl->vfeGammaLutSel.ch0BankSelect ^= 1;
-		ctrl->vfeGammaLutSel.ch1BankSelect ^= 1;
-		ctrl->vfeGammaLutSel.ch2BankSelect ^= 1;
-		vfe_write_gamma_table(0, ctrl->vfeGammaLutSel.ch0BankSelect,
-			in->table);
-		vfe_write_gamma_table(1, ctrl->vfeGammaLutSel.ch1BankSelect,
-			in->table);
-		vfe_write_gamma_table(2, ctrl->vfeGammaLutSel.ch2BankSelect,
-			in->table);
-		break;
-
-	default:
-		pr_err("%s: invalid gamma channel %d\n", __func__,
-			in->channelSelect);
-		return -EINVAL;
-	} /* switch */
-
-	/* update the gammaLutSel register. */
-	vfe_program_lut_bank_sel(&ctrl->vfeGammaLutSel);
-
-	return rc;
-}
-
-int vfe_rgb_gamma_config(struct vfe_cmd_rgb_gamma_config *in)
-{
-	int rc = 0;
-
-	ctrl->vfeModuleEnableLocal.rgbLUTEnable = in->enable;
-
-	switch (in->channelSelect) {
-	case RGB_GAMMA_CH0_SELECTED:
-vfe_write_gamma_table(0, 0, in->table);
-break;
-
-	case RGB_GAMMA_CH1_SELECTED:
-		vfe_write_gamma_table(1, 0, in->table);
-		break;
-
-	case RGB_GAMMA_CH2_SELECTED:
-		vfe_write_gamma_table(2, 0, in->table);
-		break;
-
-	case RGB_GAMMA_CH0_CH1_SELECTED:
-		vfe_write_gamma_table(0, 0, in->table);
-		vfe_write_gamma_table(1, 0, in->table);
-		break;
-
-	case RGB_GAMMA_CH0_CH2_SELECTED:
-		vfe_write_gamma_table(0, 0, in->table);
-		vfe_write_gamma_table(2, 0, in->table);
-		break;
-
-	case RGB_GAMMA_CH1_CH2_SELECTED:
-		vfe_write_gamma_table(1, 0, in->table);
-		vfe_write_gamma_table(2, 0, in->table);
-		break;
-
-	case RGB_GAMMA_CH0_CH1_CH2_SELECTED:
-		vfe_write_gamma_table(0, 0, in->table);
-		vfe_write_gamma_table(1, 0, in->table);
-		vfe_write_gamma_table(2, 0, in->table);
-		break;
-
-	default:
-		pr_err("%s: invalid gamma channel %d\n", __func__,
-			in->channelSelect);
-		rc = -EINVAL;
-		break;
-	} /* switch */
-
-	return rc;
-}
-
-void vfe_stats_af_ack(struct vfe_cmd_stats_af_ack *in)
-{
-	ctrl->afStatsControl.nextFrameAddrBuf = in->nextAFOutputBufferAddr;
-	ctrl->afStatsControl.ackPending = FALSE;
-}
-
-void vfe_stats_wb_exp_ack(struct vfe_cmd_stats_wb_exp_ack *in)
-{
-	ctrl->awbStatsControl.nextFrameAddrBuf = in->nextWbExpOutputBufferAddr;
-	ctrl->awbStatsControl.ackPending = FALSE;
-}
-
-
-void vfe_output_v_ack(struct vfe_cmd_output_ack *in)
-{
-	const uint32_t *psrc;
-	uint32_t *pdest;
-	uint8_t i;
-
-	pdest = ctrl->encPath.nextFrameAddrBuf;
-
-	CDBG("video_frame_ack: ack addr = 0x%x\n", in->ybufaddr[0]);
-
-	psrc = in->ybufaddr;
-	for (i = 0; i < ctrl->encPath.fragCount; i++)
-		*pdest++ = *psrc++;
-
-	psrc = in->chromabufaddr;
-	for (i = 0; i < ctrl->encPath.fragCount; i++)
-		*pdest++ = *psrc++;
-
-	ctrl->encPath.ackPending = FALSE;
-}
-
-void vfe_output_p_ack(struct vfe_cmd_output_ack *in)
-{
-	const uint32_t *psrc;
-	uint32_t *pdest;
-	uint8_t i;
-
-	if (ctrl->axiOutputMode == VFE_AXI_OUTPUT_MODE_Output1AndOutput2) {
-		/* video mode, preview comes from output1 path */
-
-	pdest = ctrl->viewPath.nextFrameAddrBuf;
-
-	psrc = in->ybufaddr;
-	for (i = 0; i < ctrl->viewPath.fragCount; i++)
-		*pdest++ = *psrc++;
-
-	psrc = in->chromabufaddr;
-	for (i = 0; i < ctrl->viewPath.fragCount; i++)
-		*pdest++ = *psrc++;
-
-	ctrl->viewPath.ackPending = FALSE;
-
-	} else { /* preview mode, preview comes from output2 path. */
-		pdest = ctrl->encPath.nextFrameAddrBuf;
-
-		psrc = in->ybufaddr;
-		for (i = 0; i < ctrl->encPath.fragCount; i++)
-			*pdest++ = *psrc++;
-
-		psrc = in->chromabufaddr;
-		for (i = 0; i < ctrl->encPath.fragCount; i++)
-			*pdest++ = *psrc++;
-
-		ctrl->encPath.ackPending = FALSE;
-
-	}
-}
-
-void vfe_start(struct vfe_cmd_start *in)
-{
-	uint32_t  pmstatus = 0;
-	boolean rawmode;
-	uint32_t  demperiod = 0;
-	uint32_t  demeven = 0;
-	uint32_t  demodd = 0;
-
-	/* derived from other commands.  (camif config, axi output config,
-	 * etc)
-	*/
-	struct vfe_cfg hwcfg;
-	struct vfe_upsample_cfg chromupcfg;
-
-	CDBG("vfe_start operationMode = %d\n", in->operationMode);
-
-	memset(&hwcfg, 0, sizeof(hwcfg));
-	memset(&chromupcfg, 0, sizeof(chromupcfg));
-
-	switch (in->pixel) {
-	case VFE_BAYER_RGRGRG:
-		demperiod = 1;
-		demeven = 0xC9;
-		demodd = 0xAC;
-		break;
-
-	case VFE_BAYER_GRGRGR:
-		demperiod = 1;
-		demeven = 0x9C;
-		demodd = 0xCA;
-		break;
-
-	case VFE_BAYER_BGBGBG:
-		demperiod = 1;
-		demeven = 0xCA;
-		demodd = 0x9C;
-		break;
-
-	case VFE_BAYER_GBGBGB:
-		demperiod = 1;
-		demeven = 0xAC;
-		demodd = 0xC9;
-		break;
-
-	case VFE_YUV_YCbYCr:
-		demperiod = 3;
-		demeven = 0x9CAC;
-		demodd = 0x9CAC;
-		break;
-
-	case VFE_YUV_YCrYCb:
-		demperiod = 3;
-		demeven = 0xAC9C;
-		demodd = 0xAC9C;
-		break;
-
-	case VFE_YUV_CbYCrY:
-		demperiod = 3;
-		demeven = 0xC9CA;
-		demodd = 0xC9CA;
-		break;
-
-	case VFE_YUV_CrYCbY:
-		demperiod = 3;
-		demeven = 0xCAC9;
-		demodd = 0xCAC9;
-		break;
-
-	default:
-		return;
-	}
-
-	vfe_config_demux(demperiod, demeven, demodd);
-
-	vfe_program_lut_bank_sel(&ctrl->vfeGammaLutSel);
-
-	/* save variables to local. */
-	ctrl->vfeOperationMode = in->operationMode;
-	if (ctrl->vfeOperationMode == VFE_START_OPERATION_MODE_SNAPSHOT) {
-
-		update_axi_qos(MSM_AXI_QOS_SNAPSHOT);
-		/* in snapshot mode, initialize snapshot count*/
-		ctrl->vfeSnapShotCount = in->snapshotCount;
-
-		/* save the requested count, this is temporarily done, to
-		help with HJR / multishot. */
-		ctrl->vfeRequestedSnapShotCount = ctrl->vfeSnapShotCount;
-
-		CDBG("requested snapshot count = %d\n", ctrl->vfeSnapShotCount);
-
-		/* Assumption is to have the same pattern and period for both
-		paths, if both paths are used. */
-		if (ctrl->viewPath.pathEnabled) {
-			ctrl->viewPath.snapshotPendingCount = in->snapshotCount;
-
-			ctrl->vfeFrameSkipPattern =
-				ctrl->vfeFrameSkip.output1Pattern;
-			ctrl->vfeFrameSkipPeriod =
-				ctrl->vfeFrameSkip.output1Period;
-		}
-
-		if (ctrl->encPath.pathEnabled) {
-			ctrl->encPath.snapshotPendingCount = in->snapshotCount;
-
-			ctrl->vfeFrameSkipPattern =
-				ctrl->vfeFrameSkip.output2Pattern;
-			ctrl->vfeFrameSkipPeriod =
-				ctrl->vfeFrameSkip.output2Period;
-		}
-	} else
-		update_axi_qos(MSM_AXI_QOS_PREVIEW);
-
-	/* enable color conversion for bayer sensor
-	if stats enabled, need to do color conversion. */
-	if (in->pixel <= VFE_BAYER_GBGBGB)
-		ctrl->vfeStatsCmdLocal.colorConversionEnable = TRUE;
-
-	vfe_program_stats_cmd(&ctrl->vfeStatsCmdLocal);
-
-	if (in->pixel >= VFE_YUV_YCbYCr)
-		ctrl->vfeModuleEnableLocal.chromaUpsampleEnable = TRUE;
-
-	ctrl->vfeModuleEnableLocal.demuxEnable = TRUE;
-
-	/* if any stats module is enabled, the main bit is enabled. */
-	ctrl->vfeModuleEnableLocal.statsEnable =
-		ctrl->vfeStatsCmdLocal.autoFocusEnable |
-		ctrl->vfeStatsCmdLocal.axwEnable;
-
-	vfe_reg_module_cfg(&ctrl->vfeModuleEnableLocal);
-
-	/* in case of offline processing, do not need to config camif. Having
-	 * bus output enabled in camif_config register might confuse the
-	 * hardware?
-	 */
-	if (in->inputSource != VFE_START_INPUT_SOURCE_AXI) {
-		vfe_reg_camif_config(&ctrl->vfeCamifConfigLocal);
-	} else {
-		/* offline processing, enable axi read */
-		ctrl->vfeBusConfigLocal.stripeRdPathEn = TRUE;
-		ctrl->vfeBusCmdLocal.stripeReload = TRUE;
-		ctrl->vfeBusConfigLocal.rawPixelDataSize =
-			ctrl->axiInputDataSize;
-	}
-
-	vfe_reg_bus_cfg(&ctrl->vfeBusConfigLocal);
-
-	/* directly from start command */
-	hwcfg.pixelPattern = in->pixel;
-	hwcfg.inputSource = in->inputSource;
-	writel(*(uint32_t *)&hwcfg, ctrl->vfebase + VFE_CFG);
-
-	/* regardless module enabled or not, it does not hurt
-	 * to program the cositing mode. */
-	chromupcfg.chromaCositingForYCbCrInputs = in->yuvInputCositingMode;
-
-	writel(*(uint32_t *)&chromupcfg,
-		ctrl->vfebase + VFE_CHROMA_UPSAMPLE_CFG);
-
-	/* MISR to monitor the axi read. */
-	writel(0xd8, ctrl->vfebase + VFE_BUS_MISR_MAST_CFG_0);
-
-	/* clear all pending interrupts. */
-	writel(VFE_CLEAR_ALL_IRQS, ctrl->vfebase + VFE_IRQ_CLEAR);
-
-	/*  define how composite interrupt work.  */
-	ctrl->vfeImaskCompositePacked =
-		vfe_irq_composite_pack(ctrl->vfeIrqCompositeMaskLocal);
-
-	vfe_program_irq_composite_mask(ctrl->vfeImaskCompositePacked);
-
-	/*  enable all necessary interrupts.      */
-	ctrl->vfeImaskLocal.camifSofIrq  = TRUE;
-	ctrl->vfeImaskLocal.regUpdateIrq = TRUE;
-	ctrl->vfeImaskLocal.resetAckIrq  = TRUE;
-
-	ctrl->vfeImaskPacked = vfe_irq_pack(ctrl->vfeImaskLocal);
-	vfe_program_irq_mask(ctrl->vfeImaskPacked);
-
-	/* enable bus performance monitor */
-	vfe_8k_pm_start(&ctrl->vfeBusPmConfigLocal);
-
-	/* trigger vfe reg update */
-	ctrl->vfeStartAckPendingFlag = TRUE;
-
-	/* write bus command to trigger reload of ping pong buffer. */
-	ctrl->vfeBusCmdLocal.busPingpongReload = TRUE;
-
-	if (ctrl->vfeModuleEnableLocal.statsEnable == TRUE) {
-		ctrl->vfeBusCmdLocal.statsPingpongReload = TRUE;
-		ctrl->vfeStatsPingPongReloadFlag = TRUE;
-	}
-
-	writel(VFE_REG_UPDATE_TRIGGER, ctrl->vfebase + VFE_REG_UPDATE_CMD);
-
-	/* program later than the reg update. */
-	vfe_reg_bus_cmd(&ctrl->vfeBusCmdLocal);
-
-	if ((in->inputSource ==
-			 VFE_START_INPUT_SOURCE_CAMIF) ||
-	    (in->inputSource == VFE_START_INPUT_SOURCE_TESTGEN))
-		writel(CAMIF_COMMAND_START, ctrl->vfebase + CAMIF_COMMAND);
-
-	/* start test gen if it is enabled */
-	if (ctrl->vfeTestGenStartFlag == TRUE) {
-		ctrl->vfeTestGenStartFlag = FALSE;
-		vfe_prog_hw_testgen_cmd(VFE_TEST_GEN_GO);
-	}
-
-	CDBG("ctrl->axiOutputMode = %d\n", ctrl->axiOutputMode);
-	if (ctrl->axiOutputMode == VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2) {
-		/* raw dump mode */
-		rawmode = TRUE;
-
-		while (rawmode) {
-			pmstatus =
-				readl(ctrl->vfebase +
-					VFE_BUS_ENC_CBCR_WR_PM_STATS_1);
-
-			if ((pmstatus & VFE_PM_BUF_MAX_CNT_MASK) != 0)
-				rawmode = FALSE;
-		}
-
-		vfe_proc_ops(VFE_MSG_ID_START_ACK, NULL);
-		ctrl->vfeStartAckPendingFlag = FALSE;
-	}
-
-	ctrl->vstate = VFE_STATE_ACTIVE;
-}
-
-void vfe_la_update(struct vfe_cmd_la_config *in)
-{
-	int16_t *pTable;
-	enum VFE_DMI_RAM_SEL dmiRamSel;
-	int i;
-
-	pTable = in->table;
-	ctrl->vfeModuleEnableLocal.lumaAdaptationEnable = in->enable;
-
-	/* toggle the bank to be used. */
-	ctrl->vfeLaBankSel ^= 1;
-
-	if (ctrl->vfeLaBankSel == 0)
-		dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK0;
-	else
-		dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK1;
-
-	/* configure the DMI_CFG to select right sram */
-	vfe_program_dmi_cfg(dmiRamSel);
-
-	for (i = 0; i < VFE_LA_TABLE_LENGTH; i++) {
-		writel((uint32_t)(*pTable), ctrl->vfebase + VFE_DMI_DATA_LO);
-		pTable++;
-	}
-
-	/* After DMI transfer, to make it safe, need to set
-	 * the DMI_CFG to unselect any SRAM */
-	writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG);
-	writel(ctrl->vfeLaBankSel, ctrl->vfebase + VFE_LA_CFG);
-}
-
-void vfe_la_config(struct vfe_cmd_la_config *in)
-{
-	uint16_t i;
-	int16_t  *pTable;
-	enum VFE_DMI_RAM_SEL dmiRamSel;
-
-	pTable = in->table;
-	ctrl->vfeModuleEnableLocal.lumaAdaptationEnable = in->enable;
-
-	if (ctrl->vfeLaBankSel == 0)
-		dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK0;
-	else
-		dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK1;
-
-	/* configure the DMI_CFG to select right sram */
-	vfe_program_dmi_cfg(dmiRamSel);
-
-	for (i = 0; i < VFE_LA_TABLE_LENGTH; i++) {
-		writel((uint32_t)(*pTable), ctrl->vfebase + VFE_DMI_DATA_LO);
-		pTable++;
-	}
-
-	/* After DMI transfer, to make it safe, need to set the
-	 * DMI_CFG to unselect any SRAM */
-	writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG);
-
-	/* can only be bank 0 or bank 1 for now. */
-	writel(ctrl->vfeLaBankSel, ctrl->vfebase + VFE_LA_CFG);
-	CDBG("VFE Luma adaptation bank selection is 0x%x\n",
-			 *(uint32_t *)&ctrl->vfeLaBankSel);
-}
-
-void vfe_test_gen_start(struct vfe_cmd_test_gen_start *in)
-{
-	struct VFE_TestGen_ConfigCmdType cmd;
-
-	memset(&cmd, 0, sizeof(cmd));
-
-	cmd.numFrame              = in->numFrame;
-	cmd.pixelDataSelect       = in->pixelDataSelect;
-	cmd.systematicDataSelect  = in->systematicDataSelect;
-	cmd.pixelDataSize         = (uint32_t)in->pixelDataSize;
-	cmd.hsyncEdge             = (uint32_t)in->hsyncEdge;
-	cmd.vsyncEdge             = (uint32_t)in->vsyncEdge;
-	cmd.imageWidth            = in->imageWidth;
-	cmd.imageHeight           = in->imageHeight;
-	cmd.sofOffset             = in->startOfFrameOffset;
-	cmd.eofNOffset            = in->endOfFrameNOffset;
-	cmd.solOffset             = in->startOfLineOffset;
-	cmd.eolNOffset            = in->endOfLineNOffset;
-	cmd.hBlankInterval        = in->hbi;
-	cmd.vBlankInterval        = in->vbl;
-	cmd.vBlankIntervalEnable  = in->vblEnable;
-	cmd.sofDummy              = in->startOfFrameDummyLine;
-	cmd.eofDummy              = in->endOfFrameDummyLine;
-	cmd.unicolorBarSelect     = in->unicolorBarSelect;
-	cmd.unicolorBarEnable     = in->unicolorBarEnable;
-	cmd.splitEnable           = in->colorBarsSplitEnable;
-	cmd.pixelPattern          = (uint32_t)in->colorBarsPixelPattern;
-	cmd.rotatePeriod          = in->colorBarsRotatePeriod;
-	cmd.randomSeed            = in->testGenRandomSeed;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_HW_TESTGEN_CFG,
-		(uint32_t *) &cmd, sizeof(cmd));
-}
-
-void vfe_frame_skip_update(struct vfe_cmd_frame_skip_update *in)
-{
-	struct VFE_FRAME_SKIP_UpdateCmdType cmd;
-
-	cmd.yPattern    = in->output1Pattern;
-	cmd.cbcrPattern = in->output1Pattern;
-	vfe_prog_hw(ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_PATTERN,
-		(uint32_t *)&cmd, sizeof(cmd));
-
-	cmd.yPattern    = in->output2Pattern;
-	cmd.cbcrPattern = in->output2Pattern;
-	vfe_prog_hw(ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_PATTERN,
-		(uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_frame_skip_config(struct vfe_cmd_frame_skip_config *in)
-{
-	struct vfe_frame_skip_cfg cmd;
-	memset(&cmd, 0, sizeof(cmd));
-
-	ctrl->vfeFrameSkip = *in;
-
-	cmd.output2YPeriod     = in->output2Period;
-	cmd.output2CbCrPeriod  = in->output2Period;
-	cmd.output2YPattern    = in->output2Pattern;
-	cmd.output2CbCrPattern = in->output2Pattern;
-	cmd.output1YPeriod     = in->output1Period;
-	cmd.output1CbCrPeriod  = in->output1Period;
-	cmd.output1YPattern    = in->output1Pattern;
-	cmd.output1CbCrPattern = in->output1Pattern;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_CFG,
-		(uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_output_clamp_config(struct vfe_cmd_output_clamp_config *in)
-{
-	struct vfe_output_clamp_cfg cmd;
-	memset(&cmd, 0, sizeof(cmd));
-
-	cmd.yChanMax  = in->maxCh0;
-	cmd.cbChanMax = in->maxCh1;
-	cmd.crChanMax = in->maxCh2;
-
-	cmd.yChanMin  = in->minCh0;
-	cmd.cbChanMin = in->minCh1;
-	cmd.crChanMin = in->minCh2;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_CLAMP_MAX_CFG, (uint32_t *)&cmd,
-		sizeof(cmd));
-}
-
-void vfe_camif_frame_update(struct vfe_cmds_camif_frame *in)
-{
-	struct vfe_camifframe_update cmd;
-
-	memset(&cmd, 0, sizeof(cmd));
-
-	cmd.pixelsPerLine = in->pixelsPerLine;
-	cmd.linesPerFrame = in->linesPerFrame;
-
-	vfe_prog_hw(ctrl->vfebase + CAMIF_FRAME_CONFIG, (uint32_t *)&cmd,
-		sizeof(cmd));
-}
-
-void vfe_color_correction_config(struct vfe_cmd_color_correction_config *in)
-{
-	struct vfe_color_correction_cfg cmd;
-
-	memset(&cmd, 0, sizeof(cmd));
-	ctrl->vfeModuleEnableLocal.colorCorrectionEnable = in->enable;
-
-	cmd.c0 = in->C0;
-	cmd.c1 = in->C1;
-	cmd.c2 = in->C2;
-	cmd.c3 = in->C3;
-	cmd.c4 = in->C4;
-	cmd.c5 = in->C5;
-	cmd.c6 = in->C6;
-	cmd.c7 = in->C7;
-	cmd.c8 = in->C8;
-
-	cmd.k0 = in->K0;
-	cmd.k1 = in->K1;
-	cmd.k2 = in->K2;
-
-	cmd.coefQFactor = in->coefQFactor;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_COLOR_CORRECT_COEFF_0,
-		(uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_demosaic_abf_update(struct vfe_cmd_demosaic_abf_update *in)
-{
-struct vfe_demosaic_cfg cmd;
-	struct vfe_demosaic_abf_cfg cmdabf;
-	uint32_t temp;
-
-	memset(&cmd, 0, sizeof(cmd));
-	temp = readl(ctrl->vfebase + VFE_DEMOSAIC_CFG);
-
-	cmd = *((struct vfe_demosaic_cfg *)(&temp));
-	cmd.abfEnable       = in->abfUpdate.enable;
-	cmd.forceAbfOn      = in->abfUpdate.forceOn;
-	cmd.abfShift        = in->abfUpdate.shift;
-	vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_CFG,
-		(uint32_t *)&cmd, sizeof(cmd));
-
-	cmdabf.lpThreshold  = in->abfUpdate.lpThreshold;
-	cmdabf.ratio        = in->abfUpdate.ratio;
-	cmdabf.minValue     = in->abfUpdate.min;
-	cmdabf.maxValue     = in->abfUpdate.max;
-	vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_ABF_CFG_0,
-		(uint32_t *)&cmdabf, sizeof(cmdabf));
-}
-
-void vfe_demosaic_bpc_update(struct vfe_cmd_demosaic_bpc_update *in)
-{
-	struct vfe_demosaic_cfg cmd;
-	struct vfe_demosaic_bpc_cfg cmdbpc;
-	uint32_t temp;
-
-	memset(&cmd, 0, sizeof(cmd));
-
-	temp = readl(ctrl->vfebase + VFE_DEMOSAIC_CFG);
-
-	cmd = *((struct vfe_demosaic_cfg *)(&temp));
-	cmd.badPixelCorrEnable = in->bpcUpdate.enable;
-	cmd.fminThreshold      = in->bpcUpdate.fminThreshold;
-	cmd.fmaxThreshold      = in->bpcUpdate.fmaxThreshold;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_CFG,
-		(uint32_t *)&cmd, sizeof(cmd));
-
-	cmdbpc.blueDiffThreshold  = in->bpcUpdate.blueDiffThreshold;
-	cmdbpc.redDiffThreshold   = in->bpcUpdate.redDiffThreshold;
-	cmdbpc.greenDiffThreshold = in->bpcUpdate.greenDiffThreshold;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_BPC_CFG_0,
-		(uint32_t *)&cmdbpc, sizeof(cmdbpc));
-}
-
-void vfe_demosaic_config(struct vfe_cmd_demosaic_config *in)
-{
-	struct vfe_demosaic_cfg cmd;
-	struct vfe_demosaic_bpc_cfg cmd_bpc;
-	struct vfe_demosaic_abf_cfg cmd_abf;
-
-	memset(&cmd, 0, sizeof(cmd));
-	memset(&cmd_bpc, 0, sizeof(cmd_bpc));
-	memset(&cmd_abf, 0, sizeof(cmd_abf));
-
-	ctrl->vfeModuleEnableLocal.demosaicEnable = in->enable;
-
-	cmd.abfEnable          = in->abfConfig.enable;
-	cmd.badPixelCorrEnable = in->bpcConfig.enable;
-	cmd.forceAbfOn         = in->abfConfig.forceOn;
-	cmd.abfShift           = in->abfConfig.shift;
-	cmd.fminThreshold      = in->bpcConfig.fminThreshold;
-	cmd.fmaxThreshold      = in->bpcConfig.fmaxThreshold;
-	cmd.slopeShift         = in->slopeShift;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_CFG,
-		(uint32_t *)&cmd, sizeof(cmd));
-
-	cmd_abf.lpThreshold = in->abfConfig.lpThreshold;
-	cmd_abf.ratio       = in->abfConfig.ratio;
-	cmd_abf.minValue    = in->abfConfig.min;
-	cmd_abf.maxValue    = in->abfConfig.max;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_ABF_CFG_0,
-		(uint32_t *)&cmd_abf, sizeof(cmd_abf));
-
-	cmd_bpc.blueDiffThreshold   = in->bpcConfig.blueDiffThreshold;
-	cmd_bpc.redDiffThreshold    = in->bpcConfig.redDiffThreshold;
-	cmd_bpc.greenDiffThreshold  = in->bpcConfig.greenDiffThreshold;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_BPC_CFG_0,
-		(uint32_t *)&cmd_bpc, sizeof(cmd_bpc));
-}
-
-void vfe_demux_channel_gain_update(struct vfe_cmd_demux_channel_gain_config *in)
-{
-	struct vfe_demux_cfg cmd;
-
-	memset(&cmd, 0, sizeof(cmd));
-
-	cmd.ch0EvenGain  = in->ch0EvenGain;
-	cmd.ch0OddGain   = in->ch0OddGain;
-	cmd.ch1Gain      = in->ch1Gain;
-	cmd.ch2Gain      = in->ch2Gain;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_DEMUX_GAIN_0,
-		(uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_demux_channel_gain_config(struct vfe_cmd_demux_channel_gain_config *in)
-{
-	struct vfe_demux_cfg cmd;
-
-	memset(&cmd, 0, sizeof(cmd));
-
-	cmd.ch0EvenGain = in->ch0EvenGain;
-	cmd.ch0OddGain  = in->ch0OddGain;
-	cmd.ch1Gain     = in->ch1Gain;
-	cmd.ch2Gain     = in->ch2Gain;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_DEMUX_GAIN_0,
-		(uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_black_level_update(struct vfe_cmd_black_level_config *in)
-{
-	struct vfe_blacklevel_cfg cmd;
-
-	memset(&cmd, 0, sizeof(cmd));
-	ctrl->vfeModuleEnableLocal.blackLevelCorrectionEnable = in->enable;
-
-	cmd.evenEvenAdjustment = in->evenEvenAdjustment;
-	cmd.evenOddAdjustment  = in->evenOddAdjustment;
-	cmd.oddEvenAdjustment  = in->oddEvenAdjustment;
-	cmd.oddOddAdjustment   = in->oddOddAdjustment;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_BLACK_EVEN_EVEN_VALUE,
-		(uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_black_level_config(struct vfe_cmd_black_level_config *in)
-{
-	struct vfe_blacklevel_cfg cmd;
-	memset(&cmd, 0, sizeof(cmd));
-
-	ctrl->vfeModuleEnableLocal.blackLevelCorrectionEnable = in->enable;
-
-	cmd.evenEvenAdjustment = in->evenEvenAdjustment;
-	cmd.evenOddAdjustment  = in->evenOddAdjustment;
-	cmd.oddEvenAdjustment  = in->oddEvenAdjustment;
-	cmd.oddOddAdjustment   = in->oddOddAdjustment;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_BLACK_EVEN_EVEN_VALUE,
-		(uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_asf_update(struct vfe_cmd_asf_update *in)
-{
-	struct vfe_asf_update cmd;
-	memset(&cmd, 0, sizeof(cmd));
-
-	ctrl->vfeModuleEnableLocal.asfEnable = in->enable;
-
-	cmd.smoothEnable     = in->smoothFilterEnabled;
-	cmd.sharpMode        = in->sharpMode;
-	cmd.smoothCoeff0     = in->smoothCoefCenter;
-	cmd.smoothCoeff1     = in->smoothCoefSurr;
-	cmd.cropEnable       = in->cropEnable;
-	cmd.sharpThresholdE1 = in->sharpThreshE1;
-	cmd.sharpDegreeK1    = in->sharpK1;
-	cmd.sharpDegreeK2    = in->sharpK2;
-	cmd.normalizeFactor  = in->normalizeFactor;
-	cmd.sharpThresholdE2 = in->sharpThreshE2;
-	cmd.sharpThresholdE3 = in->sharpThreshE3;
-	cmd.sharpThresholdE4 = in->sharpThreshE4;
-	cmd.sharpThresholdE5 = in->sharpThreshE5;
-	cmd.F1Coeff0         = in->filter1Coefficients[0];
-	cmd.F1Coeff1         = in->filter1Coefficients[1];
-	cmd.F1Coeff2         = in->filter1Coefficients[2];
-	cmd.F1Coeff3         = in->filter1Coefficients[3];
-	cmd.F1Coeff4         = in->filter1Coefficients[4];
-	cmd.F1Coeff5         = in->filter1Coefficients[5];
-	cmd.F1Coeff6         = in->filter1Coefficients[6];
-	cmd.F1Coeff7         = in->filter1Coefficients[7];
-	cmd.F1Coeff8         = in->filter1Coefficients[8];
-	cmd.F2Coeff0         = in->filter2Coefficients[0];
-	cmd.F2Coeff1         = in->filter2Coefficients[1];
-	cmd.F2Coeff2         = in->filter2Coefficients[2];
-	cmd.F2Coeff3         = in->filter2Coefficients[3];
-	cmd.F2Coeff4         = in->filter2Coefficients[4];
-	cmd.F2Coeff5         = in->filter2Coefficients[5];
-	cmd.F2Coeff6         = in->filter2Coefficients[6];
-	cmd.F2Coeff7         = in->filter2Coefficients[7];
-	cmd.F2Coeff8         = in->filter2Coefficients[8];
-
-	vfe_prog_hw(ctrl->vfebase + VFE_ASF_CFG,
-		(uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_asf_config(struct vfe_cmd_asf_config *in)
-{
-	struct vfe_asf_update     cmd;
-	struct vfe_asfcrop_cfg cmd2;
-
-	memset(&cmd, 0, sizeof(cmd));
-	memset(&cmd2, 0, sizeof(cmd2));
-
-	ctrl->vfeModuleEnableLocal.asfEnable = in->enable;
-
-	cmd.smoothEnable       = in->smoothFilterEnabled;
-	cmd.sharpMode          = in->sharpMode;
-	cmd.smoothCoeff0       = in->smoothCoefCenter;
-	cmd.smoothCoeff1       = in->smoothCoefSurr;
-	cmd.cropEnable         = in->cropEnable;
-	cmd.sharpThresholdE1   = in->sharpThreshE1;
-	cmd.sharpDegreeK1      = in->sharpK1;
-	cmd.sharpDegreeK2      = in->sharpK2;
-	cmd.normalizeFactor    = in->normalizeFactor;
-	cmd.sharpThresholdE2   = in->sharpThreshE2;
-	cmd.sharpThresholdE3   = in->sharpThreshE3;
-	cmd.sharpThresholdE4   = in->sharpThreshE4;
-	cmd.sharpThresholdE5   = in->sharpThreshE5;
-	cmd.F1Coeff0           = in->filter1Coefficients[0];
-	cmd.F1Coeff1           = in->filter1Coefficients[1];
-	cmd.F1Coeff2           = in->filter1Coefficients[2];
-	cmd.F1Coeff3           = in->filter1Coefficients[3];
-	cmd.F1Coeff4           = in->filter1Coefficients[4];
-	cmd.F1Coeff5           = in->filter1Coefficients[5];
-	cmd.F1Coeff6           = in->filter1Coefficients[6];
-	cmd.F1Coeff7           = in->filter1Coefficients[7];
-	cmd.F1Coeff8           = in->filter1Coefficients[8];
-	cmd.F2Coeff0           = in->filter2Coefficients[0];
-	cmd.F2Coeff1           = in->filter2Coefficients[1];
-	cmd.F2Coeff2           = in->filter2Coefficients[2];
-	cmd.F2Coeff3           = in->filter2Coefficients[3];
-	cmd.F2Coeff4           = in->filter2Coefficients[4];
-	cmd.F2Coeff5           = in->filter2Coefficients[5];
-	cmd.F2Coeff6           = in->filter2Coefficients[6];
-	cmd.F2Coeff7           = in->filter2Coefficients[7];
-	cmd.F2Coeff8           = in->filter2Coefficients[8];
-
-	vfe_prog_hw(ctrl->vfebase + VFE_ASF_CFG,
-		(uint32_t *)&cmd, sizeof(cmd));
-
-	cmd2.firstLine  = in->cropFirstLine;
-	cmd2.lastLine   = in->cropLastLine;
-	cmd2.firstPixel = in->cropFirstPixel;
-	cmd2.lastPixel  = in->cropLastPixel;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_ASF_CROP_WIDTH_CFG,
-		(uint32_t *)&cmd2, sizeof(cmd2));
-}
-
-void vfe_white_balance_config(struct vfe_cmd_white_balance_config *in)
-{
-	struct vfe_wb_cfg cmd;
-	memset(&cmd, 0, sizeof(cmd));
-
-	ctrl->vfeModuleEnableLocal.whiteBalanceEnable = in->enable;
-
-	cmd.ch0Gain = in->ch0Gain;
-	cmd.ch1Gain = in->ch1Gain;
-	cmd.ch2Gain = in->ch2Gain;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_WB_CFG,
-		(uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_chroma_sup_config(struct vfe_cmd_chroma_suppression_config *in)
-{
-	struct vfe_chroma_suppress_cfg cmd;
-	memset(&cmd, 0, sizeof(cmd));
-
-	ctrl->vfeModuleEnableLocal.chromaSuppressionEnable = in->enable;
-
-	cmd.m1  = in->m1;
-	cmd.m3  = in->m3;
-	cmd.n1  = in->n1;
-	cmd.n3  = in->n3;
-	cmd.mm1 = in->mm1;
-	cmd.nn1 = in->nn1;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_CHROMA_SUPPRESS_CFG_0,
-		(uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_roll_off_config(struct vfe_cmd_roll_off_config *in)
-{
-	struct vfe_rolloff_cfg cmd;
-	memset(&cmd, 0, sizeof(cmd));
-
-	ctrl->vfeModuleEnableLocal.lensRollOffEnable = in->enable;
-
-	cmd.gridWidth   = in->gridWidth;
-	cmd.gridHeight  = in->gridHeight;
-	cmd.yDelta      = in->yDelta;
-	cmd.gridX       = in->gridXIndex;
-	cmd.gridY       = in->gridYIndex;
-	cmd.pixelX      = in->gridPixelXIndex;
-	cmd.pixelY      = in->gridPixelYIndex;
-	cmd.yDeltaAccum = in->yDeltaAccum;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_ROLLOFF_CFG_0,
-		(uint32_t *)&cmd, sizeof(cmd));
-
-	vfe_write_lens_roll_off_table(in);
-}
-
-void vfe_chroma_subsample_config(struct vfe_cmd_chroma_subsample_config *in)
-{
-	struct vfe_chromasubsample_cfg cmd;
-	memset(&cmd, 0, sizeof(cmd));
-
-	ctrl->vfeModuleEnableLocal.chromaSubsampleEnable = in->enable;
-
-	cmd.hCositedPhase       = in->hCositedPhase;
-	cmd.vCositedPhase       = in->vCositedPhase;
-	cmd.hCosited            = in->hCosited;
-	cmd.vCosited            = in->vCosited;
-	cmd.hsubSampleEnable    = in->hsubSampleEnable;
-	cmd.vsubSampleEnable    = in->vsubSampleEnable;
-	cmd.cropEnable          = in->cropEnable;
-	cmd.cropWidthLastPixel  = in->cropWidthLastPixel;
-	cmd.cropWidthFirstPixel = in->cropWidthFirstPixel;
-	cmd.cropHeightLastLine  = in->cropHeightLastLine;
-	cmd.cropHeightFirstLine = in->cropHeightFirstLine;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_CHROMA_SUBSAMPLE_CFG,
-		(uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_chroma_enhan_config(struct vfe_cmd_chroma_enhan_config *in)
-{
-	struct vfe_chroma_enhance_cfg cmd;
-	struct vfe_color_convert_cfg cmd2;
-
-	memset(&cmd, 0, sizeof(cmd));
-	memset(&cmd2, 0, sizeof(cmd2));
-
-	ctrl->vfeModuleEnableLocal.chromaEnhanEnable = in->enable;
-
-	cmd.ap             = in->ap;
-	cmd.am             = in->am;
-	cmd.bp             = in->bp;
-	cmd.bm             = in->bm;
-	cmd.cp             = in->cp;
-	cmd.cm             = in->cm;
-	cmd.dp             = in->dp;
-	cmd.dm             = in->dm;
-	cmd.kcb            = in->kcb;
-	cmd.kcr            = in->kcr;
-
-	cmd2.v0            = in->RGBtoYConversionV0;
-	cmd2.v1            = in->RGBtoYConversionV1;
-	cmd2.v2            = in->RGBtoYConversionV2;
-	cmd2.ConvertOffset = in->RGBtoYConversionOffset;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_CHROMA_ENHAN_A,
-		(uint32_t *)&cmd, sizeof(cmd));
-
-	vfe_prog_hw(ctrl->vfebase + VFE_COLOR_CONVERT_COEFF_0,
-		(uint32_t *)&cmd2, sizeof(cmd2));
-}
-
-void vfe_scaler2cbcr_config(struct vfe_cmd_scaler2_config *in)
-{
-	struct vfe_scaler2_cfg cmd;
-
-	memset(&cmd, 0, sizeof(cmd));
-
-	ctrl->vfeModuleEnableLocal.scaler2CbcrEnable = in->enable;
-
-	cmd.hEnable              = in->hconfig.enable;
-	cmd.vEnable              = in->vconfig.enable;
-	cmd.inWidth              = in->hconfig.inputSize;
-	cmd.outWidth             = in->hconfig.outputSize;
-	cmd.horizPhaseMult       = in->hconfig.phaseMultiplicationFactor;
-	cmd.horizInterResolution = in->hconfig.interpolationResolution;
-	cmd.inHeight             = in->vconfig.inputSize;
-	cmd.outHeight            = in->vconfig.outputSize;
-	cmd.vertPhaseMult        = in->vconfig.phaseMultiplicationFactor;
-	cmd.vertInterResolution  = in->vconfig.interpolationResolution;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_SCALE_CBCR_CFG,
-		(uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_scaler2y_config(struct vfe_cmd_scaler2_config *in)
-{
-	struct vfe_scaler2_cfg cmd;
-
-	memset(&cmd, 0, sizeof(cmd));
-
-	ctrl->vfeModuleEnableLocal.scaler2YEnable = in->enable;
-
-	cmd.hEnable               = in->hconfig.enable;
-	cmd.vEnable               = in->vconfig.enable;
-	cmd.inWidth               = in->hconfig.inputSize;
-	cmd.outWidth              = in->hconfig.outputSize;
-	cmd.horizPhaseMult        = in->hconfig.phaseMultiplicationFactor;
-	cmd.horizInterResolution  = in->hconfig.interpolationResolution;
-	cmd.inHeight              = in->vconfig.inputSize;
-	cmd.outHeight             = in->vconfig.outputSize;
-	cmd.vertPhaseMult         = in->vconfig.phaseMultiplicationFactor;
-	cmd.vertInterResolution   = in->vconfig.interpolationResolution;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_SCALE_Y_CFG,
-		(uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_main_scaler_config(struct vfe_cmd_main_scaler_config *in)
-{
-	struct vfe_main_scaler_cfg cmd;
-
-	memset(&cmd, 0, sizeof(cmd));
-
-	ctrl->vfeModuleEnableLocal.mainScalerEnable = in->enable;
-
-	cmd.hEnable              = in->hconfig.enable;
-	cmd.vEnable              = in->vconfig.enable;
-	cmd.inWidth              = in->hconfig.inputSize;
-	cmd.outWidth             = in->hconfig.outputSize;
-	cmd.horizPhaseMult       = in->hconfig.phaseMultiplicationFactor;
-	cmd.horizInterResolution = in->hconfig.interpolationResolution;
-	cmd.horizMNInit          = in->MNInitH.MNCounterInit;
-	cmd.horizPhaseInit       = in->MNInitH.phaseInit;
-	cmd.inHeight             = in->vconfig.inputSize;
-	cmd.outHeight            = in->vconfig.outputSize;
-	cmd.vertPhaseMult        = in->vconfig.phaseMultiplicationFactor;
-	cmd.vertInterResolution  = in->vconfig.interpolationResolution;
-	cmd.vertMNInit           = in->MNInitV.MNCounterInit;
-	cmd.vertPhaseInit        = in->MNInitV.phaseInit;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_SCALE_CFG,
-		(uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_stats_wb_exp_stop(void)
-{
-	ctrl->vfeStatsCmdLocal.axwEnable = FALSE;
-	ctrl->vfeImaskLocal.awbPingpongIrq = FALSE;
-}
-
-void vfe_stats_update_wb_exp(struct vfe_cmd_stats_wb_exp_update *in)
-{
-	struct vfe_statsawb_update   cmd;
-	struct vfe_statsawbae_update cmd2;
-
-	memset(&cmd, 0, sizeof(cmd));
-	memset(&cmd2, 0, sizeof(cmd2));
-
-	cmd.m1  = in->awbMCFG[0];
-	cmd.m2  = in->awbMCFG[1];
-	cmd.m3  = in->awbMCFG[2];
-	cmd.m4  = in->awbMCFG[3];
-	cmd.c1  = in->awbCCFG[0];
-	cmd.c2  = in->awbCCFG[1];
-	cmd.c3  = in->awbCCFG[2];
-	cmd.c4  = in->awbCCFG[3];
-	vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWB_MCFG,
-		(uint32_t *)&cmd, sizeof(cmd));
-
-	cmd2.aeRegionCfg    = in->wbExpRegions;
-	cmd2.aeSubregionCfg = in->wbExpSubRegion;
-	cmd2.awbYMin        = in->awbYMin;
-	cmd2.awbYMax        = in->awbYMax;
-	vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWBAE_CFG,
-		(uint32_t *)&cmd2, sizeof(cmd2));
-}
-
-void vfe_stats_update_af(struct vfe_cmd_stats_af_update *in)
-{
-	struct vfe_statsaf_update cmd;
-	memset(&cmd, 0, sizeof(cmd));
-
-	cmd.windowVOffset = in->windowVOffset;
-	cmd.windowHOffset = in->windowHOffset;
-	cmd.windowMode    = in->windowMode;
-	cmd.windowHeight  = in->windowHeight;
-	cmd.windowWidth   = in->windowWidth;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_STATS_AF_CFG,
-		(uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_stats_start_wb_exp(struct vfe_cmd_stats_wb_exp_start *in)
-{
-	struct vfe_statsawb_update   cmd;
-	struct vfe_statsawbae_update cmd2;
-	struct vfe_statsaxw_hdr_cfg  cmd3;
-
-	ctrl->vfeStatsCmdLocal.axwEnable   =  in->enable;
-	ctrl->vfeImaskLocal.awbPingpongIrq = TRUE;
-
-	memset(&cmd, 0, sizeof(cmd));
-	memset(&cmd2, 0, sizeof(cmd2));
-	memset(&cmd3, 0, sizeof(cmd3));
-
-	cmd.m1  = in->awbMCFG[0];
-	cmd.m2  = in->awbMCFG[1];
-	cmd.m3  = in->awbMCFG[2];
-	cmd.m4  = in->awbMCFG[3];
-	cmd.c1  = in->awbCCFG[0];
-	cmd.c2  = in->awbCCFG[1];
-	cmd.c3  = in->awbCCFG[2];
-	cmd.c4  = in->awbCCFG[3];
-	vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWB_MCFG,
-		(uint32_t *)&cmd, sizeof(cmd));
-
-	cmd2.aeRegionCfg     = in->wbExpRegions;
-	cmd2.aeSubregionCfg  = in->wbExpSubRegion;
-	cmd2.awbYMin         = in->awbYMin;
-	cmd2.awbYMax         = in->awbYMax;
-	vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWBAE_CFG,
-		(uint32_t *)&cmd2, sizeof(cmd2));
-
-	cmd3.axwHeader       = in->axwHeader;
-	vfe_prog_hw(ctrl->vfebase + VFE_STATS_AXW_HEADER,
-		(uint32_t *)&cmd3, sizeof(cmd3));
-}
-
-void vfe_stats_start_af(struct vfe_cmd_stats_af_start *in)
-{
-	struct vfe_statsaf_update cmd;
-	struct vfe_statsaf_cfg    cmd2;
-
-	memset(&cmd, 0, sizeof(cmd));
-	memset(&cmd2, 0, sizeof(cmd2));
-
-	ctrl->vfeStatsCmdLocal.autoFocusEnable = in->enable;
-	ctrl->vfeImaskLocal.afPingpongIrq = TRUE;
-
-	cmd.windowVOffset = in->windowVOffset;
-	cmd.windowHOffset = in->windowHOffset;
-	cmd.windowMode    = in->windowMode;
-	cmd.windowHeight  = in->windowHeight;
-	cmd.windowWidth   = in->windowWidth;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_STATS_AF_CFG,
-		(uint32_t *)&cmd, sizeof(cmd));
-
-	cmd2.a00       = in->highPassCoef[0];
-	cmd2.a04       = in->highPassCoef[1];
-	cmd2.a20       = in->highPassCoef[2];
-	cmd2.a21       = in->highPassCoef[3];
-	cmd2.a22       = in->highPassCoef[4];
-	cmd2.a23       = in->highPassCoef[5];
-	cmd2.a24       = in->highPassCoef[6];
-	cmd2.fvMax     = in->metricMax;
-	cmd2.fvMetric  = in->metricSelection;
-	cmd2.afHeader  = in->bufferHeader;
-	cmd2.entry00   = in->gridForMultiWindows[0];
-	cmd2.entry01   = in->gridForMultiWindows[1];
-	cmd2.entry02   = in->gridForMultiWindows[2];
-	cmd2.entry03   = in->gridForMultiWindows[3];
-	cmd2.entry10   = in->gridForMultiWindows[4];
-	cmd2.entry11   = in->gridForMultiWindows[5];
-	cmd2.entry12   = in->gridForMultiWindows[6];
-	cmd2.entry13   = in->gridForMultiWindows[7];
-	cmd2.entry20   = in->gridForMultiWindows[8];
-	cmd2.entry21   = in->gridForMultiWindows[9];
-	cmd2.entry22   = in->gridForMultiWindows[10];
-	cmd2.entry23   = in->gridForMultiWindows[11];
-	cmd2.entry30   = in->gridForMultiWindows[12];
-	cmd2.entry31   = in->gridForMultiWindows[13];
-	cmd2.entry32   = in->gridForMultiWindows[14];
-	cmd2.entry33   = in->gridForMultiWindows[15];
-
-	vfe_prog_hw(ctrl->vfebase + VFE_STATS_AF_GRID_0,
-		(uint32_t *)&cmd2, sizeof(cmd2));
-}
-
-void vfe_stats_setting(struct vfe_cmd_stats_setting *in)
-{
-	struct vfe_statsframe cmd1;
-	struct vfe_busstats_wrprio cmd2;
-
-	memset(&cmd1, 0, sizeof(cmd1));
-	memset(&cmd2, 0, sizeof(cmd2));
-
-	ctrl->afStatsControl.addressBuffer[0] = in->afBuffer[0];
-	ctrl->afStatsControl.addressBuffer[1] = in->afBuffer[1];
-	ctrl->afStatsControl.nextFrameAddrBuf = in->afBuffer[2];
-
-	ctrl->awbStatsControl.addressBuffer[0] = in->awbBuffer[0];
-	ctrl->awbStatsControl.addressBuffer[1] = in->awbBuffer[1];
-	ctrl->awbStatsControl.nextFrameAddrBuf = in->awbBuffer[2];
-
-	cmd1.lastPixel = in->frameHDimension;
-	cmd1.lastLine  = in->frameVDimension;
-	vfe_prog_hw(ctrl->vfebase + VFE_STATS_FRAME_SIZE,
-		(uint32_t *)&cmd1, sizeof(cmd1));
-
-	cmd2.afBusPriority    = in->afBusPriority;
-	cmd2.awbBusPriority   = in->awbBusPriority;
-	cmd2.histBusPriority  = in->histBusPriority;
-	cmd2.afBusPriorityEn  = in->afBusPrioritySelection;
-	cmd2.awbBusPriorityEn = in->awbBusPrioritySelection;
-	cmd2.histBusPriorityEn = in->histBusPrioritySelection;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_BUS_STATS_WR_PRIORITY,
-		(uint32_t *)&cmd2, sizeof(cmd2));
-
-	/* Program the bus ping pong address for statistics modules. */
-	writel(in->afBuffer[0], ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR);
-	writel(in->afBuffer[1], ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR);
-	writel(in->awbBuffer[0],
-		ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR);
-	writel(in->awbBuffer[1],
-		ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR);
-	writel(in->histBuffer[0],
-		ctrl->vfebase + VFE_BUS_STATS_HIST_WR_PING_ADDR);
-	writel(in->histBuffer[1],
-		ctrl->vfebase + VFE_BUS_STATS_HIST_WR_PONG_ADDR);
-}
-
-void vfe_axi_input_config(struct vfe_cmd_axi_input_config *in)
-{
-	struct VFE_AxiInputCmdType cmd;
-	uint32_t xSizeWord, axiRdUnpackPattern;
-	uint8_t  axiInputPpw;
-	uint32_t busPingpongRdIrqEnable;
-
-	ctrl->vfeImaskLocal.rdPingpongIrq = TRUE;
-
-	switch (in->pixelSize) {
-	case VFE_RAW_PIXEL_DATA_SIZE_10BIT:
-		ctrl->axiInputDataSize = VFE_RAW_PIXEL_DATA_SIZE_10BIT;
-		break;
-
-	case VFE_RAW_PIXEL_DATA_SIZE_12BIT:
-		ctrl->axiInputDataSize = VFE_RAW_PIXEL_DATA_SIZE_12BIT;
-		break;
-
-	case VFE_RAW_PIXEL_DATA_SIZE_8BIT:
-	default:
-		ctrl->axiInputDataSize = VFE_RAW_PIXEL_DATA_SIZE_8BIT;
-		break;
-	}
-
-	memset(&cmd, 0, sizeof(cmd));
-
-	switch (in->pixelSize) {
-	case VFE_RAW_PIXEL_DATA_SIZE_10BIT:
-		axiInputPpw = 6;
-		axiRdUnpackPattern = 0xD43210;
-		break;
-
-	case VFE_RAW_PIXEL_DATA_SIZE_12BIT:
-		axiInputPpw = 5;
-		axiRdUnpackPattern = 0xC3210;
-		break;
-
-	case VFE_RAW_PIXEL_DATA_SIZE_8BIT:
-	default:
-		axiInputPpw = 8;
-		axiRdUnpackPattern = 0xF6543210;
-		break;
-	}
-
-	xSizeWord =
-		((((in->xOffset % axiInputPpw) + in->xSize) +
-			(axiInputPpw-1)) / axiInputPpw) - 1;
-
-	cmd.stripeStartAddr0  = in->fragAddr[0];
-	cmd.stripeStartAddr1  = in->fragAddr[1];
-	cmd.stripeStartAddr2  = in->fragAddr[2];
-	cmd.stripeStartAddr3  = in->fragAddr[3];
-	cmd.ySize             = in->ySize;
-	cmd.yOffsetDelta      = 0;
-	cmd.xSizeWord         = xSizeWord;
-	cmd.burstLength       = 1;
-	cmd.NumOfRows         = in->numOfRows;
-	cmd.RowIncrement = (in->rowIncrement + (axiInputPpw - 1)) / axiInputPpw;
-	cmd.mainUnpackHeight  = in->ySize;
-	cmd.mainUnpackWidth   = in->xSize - 1;
-	cmd.mainUnpackHbiSel  = (uint32_t)in->unpackHbi;
-	cmd.mainUnpackPhase   = in->unpackPhase;
-	cmd.unpackPattern     = axiRdUnpackPattern;
-	cmd.padLeft           = in->padRepeatCountLeft;
-	cmd.padRight          = in->padRepeatCountRight;
-	cmd.padTop            = in->padRepeatCountTop;
-	cmd.padBottom         = in->padRepeatCountBottom;
-	cmd.leftUnpackPattern0   = in->padLeftComponentSelectCycle0;
-	cmd.leftUnpackPattern1   = in->padLeftComponentSelectCycle1;
-	cmd.leftUnpackPattern2   = in->padLeftComponentSelectCycle2;
-	cmd.leftUnpackPattern3   = in->padLeftComponentSelectCycle3;
-	cmd.leftUnpackStop0      = in->padLeftStopCycle0;
-	cmd.leftUnpackStop1      = in->padLeftStopCycle1;
-	cmd.leftUnpackStop2      = in->padLeftStopCycle2;
-	cmd.leftUnpackStop3      = in->padLeftStopCycle3;
-	cmd.rightUnpackPattern0  = in->padRightComponentSelectCycle0;
-	cmd.rightUnpackPattern1  = in->padRightComponentSelectCycle1;
-	cmd.rightUnpackPattern2  = in->padRightComponentSelectCycle2;
-	cmd.rightUnpackPattern3  = in->padRightComponentSelectCycle3;
-	cmd.rightUnpackStop0     = in->padRightStopCycle0;
-	cmd.rightUnpackStop1     = in->padRightStopCycle1;
-	cmd.rightUnpackStop2     = in->padRightStopCycle2;
-	cmd.rightUnpackStop3     = in->padRightStopCycle3;
-	cmd.topUnapckPattern     = in->padTopLineCount;
-	cmd.bottomUnapckPattern  = in->padBottomLineCount;
-
-	/*  program vfe_bus_cfg */
-	vfe_prog_hw(ctrl->vfebase + VFE_BUS_STRIPE_RD_ADDR_0,
-		(uint32_t *)&cmd, sizeof(cmd));
-
-	/* hacking code, put it to default value */
-	busPingpongRdIrqEnable = 0xf;
-
-	writel(busPingpongRdIrqEnable, ctrl->vfebase + VFE_BUS_PINGPONG_IRQ_EN);
-}
-
-void vfe_axi_output_config(struct vfe_cmd_axi_output_config *in)
-{
-	/* local variable  */
-	uint32_t *pcircle;
-	uint32_t *pdest;
-	uint32_t *psrc;
-	uint8_t  i;
-	uint8_t  fcnt;
-	uint16_t axioutpw = 8;
-
-	/* parameters check, condition and usage mode check */
-	ctrl->encPath.fragCount = in->output2.fragmentCount;
-	if (ctrl->encPath.fragCount > 1)
-		ctrl->encPath.multiFrag = TRUE;
-
-	ctrl->viewPath.fragCount = in->output1.fragmentCount;
-	if (ctrl->viewPath.fragCount > 1)
-		ctrl->viewPath.multiFrag = TRUE;
-
-	/* VFE_BUS_CFG.  raw data size */
-	ctrl->vfeBusConfigLocal.rawPixelDataSize = in->outputDataSize;
-
-	switch (in->outputDataSize) {
-	case VFE_RAW_PIXEL_DATA_SIZE_8BIT:
-		axioutpw = 8;
-		break;
-
-	case VFE_RAW_PIXEL_DATA_SIZE_10BIT:
-		axioutpw = 6;
-		break;
-
-	case VFE_RAW_PIXEL_DATA_SIZE_12BIT:
-		axioutpw = 5;
-		break;
-	}
-
-	ctrl->axiOutputMode = in->outputMode;
-
-	CDBG("axiOutputMode = %d\n", ctrl->axiOutputMode);
-
-	switch (ctrl->axiOutputMode) {
-	case VFE_AXI_OUTPUT_MODE_Output1: {
-		ctrl->vfeCamifConfigLocal.camif2BusEnable   = FALSE;
-		ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE;
-		ctrl->vfeBusConfigLocal.rawWritePathSelect  =
-			VFE_RAW_OUTPUT_DISABLED;
-
-		ctrl->encPath.pathEnabled                   = FALSE;
-		ctrl->vfeImaskLocal.encIrq                  = FALSE;
-		ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
-			VFE_COMP_IRQ_BOTH_Y_CBCR;
-
-		ctrl->vfeBusConfigLocal.encYWrPathEn          = FALSE;
-		ctrl->vfeBusConfigLocal.encCbcrWrPathEn       = FALSE;
-		ctrl->viewPath.pathEnabled                    = TRUE;
-		ctrl->vfeImaskLocal.viewIrq                   = TRUE;
-		ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
-			VFE_COMP_IRQ_BOTH_Y_CBCR;
-
-		ctrl->vfeBusConfigLocal.viewYWrPathEn    = TRUE;
-		ctrl->vfeBusConfigLocal.viewCbcrWrPathEn = TRUE;
-
-		if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
-				ctrl->encPath.multiFrag)
-			ctrl->vfeImaskLocal.encYPingpongIrq    = TRUE;
-
-		if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
-				ctrl->encPath.multiFrag)
-			ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE;
-
-		if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
-				ctrl->viewPath.multiFrag)
-			ctrl->vfeImaskLocal.viewYPingpongIrq   = TRUE;
-
-		if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
-				ctrl->viewPath.multiFrag)
-			ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE;
-	} /* VFE_AXI_OUTPUT_MODE_Output1 */
-		break;
-
-	case VFE_AXI_OUTPUT_MODE_Output2: {
-		ctrl->vfeCamifConfigLocal.camif2BusEnable   = FALSE;
-		ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE;
-		ctrl->vfeBusConfigLocal.rawWritePathSelect  =
-			VFE_RAW_OUTPUT_DISABLED;
-
-		ctrl->encPath.pathEnabled                   = TRUE;
-		ctrl->vfeImaskLocal.encIrq                  = TRUE;
-		ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
-			VFE_COMP_IRQ_BOTH_Y_CBCR;
-
-		ctrl->vfeBusConfigLocal.encYWrPathEn        = TRUE;
-		ctrl->vfeBusConfigLocal.encCbcrWrPathEn     = TRUE;
-
-		ctrl->viewPath.pathEnabled                   = FALSE;
-		ctrl->vfeImaskLocal.viewIrq                  = FALSE;
-		ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
-			VFE_COMP_IRQ_BOTH_Y_CBCR;
-
-		ctrl->vfeBusConfigLocal.viewYWrPathEn        = FALSE;
-		ctrl->vfeBusConfigLocal.viewCbcrWrPathEn     = FALSE;
-
-		if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
-				ctrl->encPath.multiFrag)
-			ctrl->vfeImaskLocal.encYPingpongIrq    = TRUE;
-
-		if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
-				ctrl->encPath.multiFrag)
-			ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE;
-
-		if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
-				ctrl->viewPath.multiFrag)
-			ctrl->vfeImaskLocal.viewYPingpongIrq   = TRUE;
-
-		if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
-				ctrl->viewPath.multiFrag)
-			ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE;
-	} /* VFE_AXI_OUTPUT_MODE_Output2 */
-			break;
-
-	case VFE_AXI_OUTPUT_MODE_Output1AndOutput2: {
-		ctrl->vfeCamifConfigLocal.camif2BusEnable    = FALSE;
-		ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE;
-		ctrl->vfeBusConfigLocal.rawWritePathSelect   =
-			VFE_RAW_OUTPUT_DISABLED;
-
-		ctrl->encPath.pathEnabled                    = TRUE;
-		ctrl->vfeImaskLocal.encIrq                   = TRUE;
-		ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
-			VFE_COMP_IRQ_BOTH_Y_CBCR;
-
-		ctrl->vfeBusConfigLocal.encYWrPathEn         = TRUE;
-		ctrl->vfeBusConfigLocal.encCbcrWrPathEn      = TRUE;
-		ctrl->viewPath.pathEnabled                   = TRUE;
-		ctrl->vfeImaskLocal.viewIrq                  = TRUE;
-		ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
-			VFE_COMP_IRQ_BOTH_Y_CBCR;
-
-		ctrl->vfeBusConfigLocal.viewYWrPathEn        = TRUE;
-		ctrl->vfeBusConfigLocal.viewCbcrWrPathEn     = TRUE;
-
-		if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
-				ctrl->encPath.multiFrag)
-			ctrl->vfeImaskLocal.encYPingpongIrq    = TRUE;
-
-		if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
-				ctrl->encPath.multiFrag)
-			ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE;
-
-		if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
-				ctrl->viewPath.multiFrag)
-			ctrl->vfeImaskLocal.viewYPingpongIrq   = TRUE;
-
-		if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
-				ctrl->viewPath.multiFrag)
-			ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE;
-	} /* VFE_AXI_OUTPUT_MODE_Output1AndOutput2 */
-		break;
-
-	case VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2: {
-		/* For raw snapshot, we need both ping and pong buffer
-		 * initialized to the same address. Otherwise, if we
-		 * leave the pong buffer to NULL, there will be axi_error.
-		 * Note that ideally we should deal with this at upper layer,
-		 * which is in msm_vfe8x.c */
-		if (!in->output2.outputCbcr.outFragments[1][0]) {
-			in->output2.outputCbcr.outFragments[1][0] =
-				in->output2.outputCbcr.outFragments[0][0];
-		}
-
-		ctrl->vfeCamifConfigLocal.camif2BusEnable   = TRUE;
-		ctrl->vfeCamifConfigLocal.camif2OutputEnable = FALSE;
-		ctrl->vfeBusConfigLocal.rawWritePathSelect  =
-			VFE_RAW_OUTPUT_ENC_CBCR_PATH;
-
-		ctrl->encPath.pathEnabled                   = TRUE;
-		ctrl->vfeImaskLocal.encIrq                  = TRUE;
-		ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
-			VFE_COMP_IRQ_CBCR_ONLY;
-
-		ctrl->vfeBusConfigLocal.encYWrPathEn        = FALSE;
-		ctrl->vfeBusConfigLocal.encCbcrWrPathEn     = TRUE;
-
-		ctrl->viewPath.pathEnabled                   = FALSE;
-		ctrl->vfeImaskLocal.viewIrq                  = FALSE;
-		ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
-			VFE_COMP_IRQ_BOTH_Y_CBCR;
-
-		ctrl->vfeBusConfigLocal.viewYWrPathEn        = FALSE;
-		ctrl->vfeBusConfigLocal.viewCbcrWrPathEn     = FALSE;
-
-		if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
-				ctrl->encPath.multiFrag)
-			ctrl->vfeImaskLocal.encYPingpongIrq    = TRUE;
-
-		if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
-				ctrl->encPath.multiFrag)
-			ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE;
-
-		if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
-				ctrl->viewPath.multiFrag)
-			ctrl->vfeImaskLocal.viewYPingpongIrq   = TRUE;
-
-		if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
-				ctrl->viewPath.multiFrag)
-			ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE;
-	} /* VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2 */
-		break;
-
-	case VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1: {
-		ctrl->vfeCamifConfigLocal.camif2BusEnable   = TRUE;
-		ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE;
-		ctrl->vfeBusConfigLocal.rawWritePathSelect  =
-			VFE_RAW_OUTPUT_VIEW_CBCR_PATH;
-
-		ctrl->encPath.pathEnabled                   = TRUE;
-		ctrl->vfeImaskLocal.encIrq                  = TRUE;
-		ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
-			VFE_COMP_IRQ_BOTH_Y_CBCR;
-
-		ctrl->vfeBusConfigLocal.encYWrPathEn        = TRUE;
-		ctrl->vfeBusConfigLocal.encCbcrWrPathEn     = TRUE;
-
-		ctrl->viewPath.pathEnabled                   = TRUE;
-		ctrl->vfeImaskLocal.viewIrq                  = TRUE;
-		ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
-			VFE_COMP_IRQ_CBCR_ONLY;
-
-		ctrl->vfeBusConfigLocal.viewYWrPathEn        = FALSE;
-		ctrl->vfeBusConfigLocal.viewCbcrWrPathEn     = TRUE;
-
-		if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
-				ctrl->encPath.multiFrag)
-			ctrl->vfeImaskLocal.encYPingpongIrq    = TRUE;
-
-		if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
-				ctrl->encPath.multiFrag)
-			ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE;
-
-		if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
-				ctrl->viewPath.multiFrag)
-			ctrl->vfeImaskLocal.viewYPingpongIrq   = TRUE;
-
-		if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
-				ctrl->viewPath.multiFrag)
-			ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE;
-	} /* VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1 */
-		break;
-
-	case VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2: {
-		ctrl->vfeCamifConfigLocal.camif2BusEnable   = TRUE;
-		ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE;
-		ctrl->vfeBusConfigLocal.rawWritePathSelect  =
-			VFE_RAW_OUTPUT_ENC_CBCR_PATH;
-
-		ctrl->encPath.pathEnabled                     = TRUE;
-		ctrl->vfeImaskLocal.encIrq                    = TRUE;
-		ctrl->vfeIrqCompositeMaskLocal.encIrqComMask  =
-			VFE_COMP_IRQ_CBCR_ONLY;
-
-		ctrl->vfeBusConfigLocal.encYWrPathEn          = FALSE;
-		ctrl->vfeBusConfigLocal.encCbcrWrPathEn       = TRUE;
-
-		ctrl->viewPath.pathEnabled                    = TRUE;
-		ctrl->vfeImaskLocal.viewIrq                   = TRUE;
-
-		ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
-			VFE_COMP_IRQ_BOTH_Y_CBCR;
-
-		ctrl->vfeBusConfigLocal.viewYWrPathEn         = TRUE;
-		ctrl->vfeBusConfigLocal.viewCbcrWrPathEn      = TRUE;
-
-		if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
-				ctrl->encPath.multiFrag)
-			ctrl->vfeImaskLocal.encYPingpongIrq       = TRUE;
-
-		if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
-				ctrl->encPath.multiFrag)
-			ctrl->vfeImaskLocal.encCbcrPingpongIrq    = TRUE;
-
-		if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
-				ctrl->viewPath.multiFrag)
-			ctrl->vfeImaskLocal.viewYPingpongIrq      = TRUE;
-
-		if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
-				ctrl->viewPath.multiFrag)
-			ctrl->vfeImaskLocal.viewCbcrPingpongIrq   = TRUE;
-	} /* VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2 */
-		break;
-
-	case VFE_AXI_LAST_OUTPUT_MODE_ENUM:
-		break;
-	} /* switch */
-
-	/* Save the addresses for each path. */
-	/* output2 path */
-	fcnt = ctrl->encPath.fragCount;
-
-	pcircle = ctrl->encPath.yPath.addressBuffer;
-	pdest = ctrl->encPath.nextFrameAddrBuf;
-
-	psrc = &(in->output2.outputY.outFragments[0][0]);
-	for (i = 0; i < fcnt; i++)
-		*pcircle++ = *psrc++;
-
-	psrc = &(in->output2.outputY.outFragments[1][0]);
-	for (i = 0; i < fcnt; i++)
-		*pcircle++ = *psrc++;
-
-	psrc = &(in->output2.outputY.outFragments[2][0]);
-	for (i = 0; i < fcnt; i++)
-		*pdest++ = *psrc++;
-
-	pcircle = ctrl->encPath.cbcrPath.addressBuffer;
-
-	psrc = &(in->output2.outputCbcr.outFragments[0][0]);
-	for (i = 0; i < fcnt; i++)
-		*pcircle++ = *psrc++;
-
-	psrc = &(in->output2.outputCbcr.outFragments[1][0]);
-	for (i = 0; i < fcnt; i++)
-		*pcircle++ = *psrc++;
-
-	psrc = &(in->output2.outputCbcr.outFragments[2][0]);
-	for (i = 0; i < fcnt; i++)
-		*pdest++ = *psrc++;
-
-	vfe_set_bus_pipo_addr(&ctrl->viewPath, &ctrl->encPath);
-
-	ctrl->encPath.ackPending = FALSE;
-	ctrl->encPath.currentFrame = ping;
-	ctrl->encPath.whichOutputPath = 1;
-	ctrl->encPath.yPath.fragIndex = 2;
-	ctrl->encPath.cbcrPath.fragIndex = 2;
-	ctrl->encPath.yPath.hwCurrentFlag = ping;
-	ctrl->encPath.cbcrPath.hwCurrentFlag = ping;
-
-	/* output1 path */
-	pcircle = ctrl->viewPath.yPath.addressBuffer;
-	pdest = ctrl->viewPath.nextFrameAddrBuf;
-	fcnt = ctrl->viewPath.fragCount;
-
-	psrc = &(in->output1.outputY.outFragments[0][0]);
-	for (i = 0; i < fcnt; i++)
-		*pcircle++ = *psrc++;
-
-	psrc = &(in->output1.outputY.outFragments[1][0]);
-	for (i = 0; i < fcnt; i++)
-		*pcircle++ = *psrc++;
-
-	psrc = &(in->output1.outputY.outFragments[2][0]);
-	for (i = 0; i < fcnt; i++)
-		*pdest++ = *psrc++;
-
-	pcircle = ctrl->viewPath.cbcrPath.addressBuffer;
-
-	psrc = &(in->output1.outputCbcr.outFragments[0][0]);
-	for (i = 0; i < fcnt; i++)
-		*pcircle++ = *psrc++;
-
-	psrc = &(in->output1.outputCbcr.outFragments[1][0]);
-	for (i = 0; i < fcnt; i++)
-		*pcircle++ = *psrc++;
-
-	psrc = &(in->output1.outputCbcr.outFragments[2][0]);
-	for (i = 0; i < fcnt; i++)
-		*pdest++ = *psrc++;
-
-	ctrl->viewPath.ackPending = FALSE;
-	ctrl->viewPath.currentFrame = ping;
-	ctrl->viewPath.whichOutputPath = 0;
-	ctrl->viewPath.yPath.fragIndex = 2;
-	ctrl->viewPath.cbcrPath.fragIndex = 2;
-	ctrl->viewPath.yPath.hwCurrentFlag = ping;
-	ctrl->viewPath.cbcrPath.hwCurrentFlag = ping;
-
-	/* call to program the registers. */
-	vfe_axi_output(in, &ctrl->viewPath, &ctrl->encPath, axioutpw);
-}
-
-void vfe_camif_config(struct vfe_cmd_camif_config *in)
-{
-	struct vfe_camifcfg cmd;
-	memset(&cmd, 0, sizeof(cmd));
-
-	CDBG("camif.frame pixelsPerLine = %d\n", in->frame.pixelsPerLine);
-	CDBG("camif.frame linesPerFrame = %d\n", in->frame.linesPerFrame);
-	CDBG("camif.window firstpixel = %d\n", in->window.firstpixel);
-	CDBG("camif.window lastpixel = %d\n",  in->window.lastpixel);
-	CDBG("camif.window firstline = %d\n",  in->window.firstline);
-	CDBG("camif.window lastline = %d\n",   in->window.lastline);
-
-	/* determine if epoch interrupt needs to be enabled.  */
-	if ((in->epoch1.enable == TRUE) &&
-	    (in->epoch1.lineindex <= in->frame.linesPerFrame))
-		ctrl->vfeImaskLocal.camifEpoch1Irq = 1;
-
-	if ((in->epoch2.enable == TRUE) &&
-	    (in->epoch2.lineindex <= in->frame.linesPerFrame)) {
-		ctrl->vfeImaskLocal.camifEpoch2Irq = 1;
-	}
-
-	/*  save the content to program CAMIF_CONFIG seperately. */
-	ctrl->vfeCamifConfigLocal.camifCfgFromCmd = in->camifConfig;
-
-	/* EFS_Config */
-	cmd.efsEndOfLine     = in->EFS.efsendofline;
-	cmd.efsStartOfLine   = in->EFS.efsstartofline;
-	cmd.efsEndOfFrame    = in->EFS.efsendofframe;
-	cmd.efsStartOfFrame  = in->EFS.efsstartofframe;
-
-	/* Frame Config */
-	cmd.frameConfigPixelsPerLine = in->frame.pixelsPerLine;
-	cmd.frameConfigLinesPerFrame = in->frame.linesPerFrame;
-
-	/* Window Width Config */
-	cmd.windowWidthCfgLastPixel  = in->window.lastpixel;
-	cmd.windowWidthCfgFirstPixel = in->window.firstpixel;
-
-	/* Window Height Config */
-	cmd.windowHeightCfglastLine   = in->window.lastline;
-	cmd.windowHeightCfgfirstLine  = in->window.firstline;
-
-	/* Subsample 1 Config */
-	cmd.subsample1CfgPixelSkip = in->subsample.pixelskipmask;
-	cmd.subsample1CfgLineSkip  = in->subsample.lineskipmask;
-
-	/* Subsample 2 Config */
-	cmd.subsample2CfgFrameSkip      = in->subsample.frameskip;
-	cmd.subsample2CfgFrameSkipMode  = in->subsample.frameskipmode;
-	cmd.subsample2CfgPixelSkipWrap  = in->subsample.pixelskipwrap;
-
-	/* Epoch Interrupt */
-	cmd.epoch1Line = in->epoch1.lineindex;
-	cmd.epoch2Line = in->epoch2.lineindex;
-
-	vfe_prog_hw(ctrl->vfebase + CAMIF_EFS_CONFIG,
-		(uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_fov_crop_config(struct vfe_cmd_fov_crop_config *in)
-{
-	struct vfe_fov_crop_cfg cmd;
-	memset(&cmd, 0, sizeof(cmd));
-
-	ctrl->vfeModuleEnableLocal.cropEnable = in->enable;
-
-	/* FOV Corp, Part 1 */
-	cmd.lastPixel  = in->lastPixel;
-	cmd.firstPixel = in->firstPixel;
-
-	/* FOV Corp, Part 2 */
-	cmd.lastLine   = in->lastLine;
-	cmd.firstLine  = in->firstLine;
-
-	vfe_prog_hw(ctrl->vfebase + VFE_CROP_WIDTH_CFG,
-		(uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_get_hw_version(struct vfe_cmd_hw_version *out)
-{
-	uint32_t vfeHwVersionPacked;
-	struct vfe_hw_ver ver;
-
-	vfeHwVersionPacked = readl(ctrl->vfebase + VFE_HW_VERSION);
-
-	ver = *((struct vfe_hw_ver *)&vfeHwVersionPacked);
-
-	out->coreVersion  = ver.coreVersion;
-	out->minorVersion = ver.minorVersion;
-	out->majorVersion = ver.majorVersion;
-}
-
-static void vfe_reset_internal_variables(void)
-{
-	/* local variables to program the hardware. */
-	ctrl->vfeImaskPacked = 0;
-	ctrl->vfeImaskCompositePacked = 0;
-
-	/* FALSE = disable,  1 = enable. */
-	memset(&ctrl->vfeModuleEnableLocal, 0,
-		sizeof(ctrl->vfeModuleEnableLocal));
-
-	/* 0 = disable, 1 = enable */
-	memset(&ctrl->vfeCamifConfigLocal, 0,
-		sizeof(ctrl->vfeCamifConfigLocal));
-	/* 0 = disable, 1 = enable */
-	memset(&ctrl->vfeImaskLocal, 0, sizeof(ctrl->vfeImaskLocal));
-	memset(&ctrl->vfeStatsCmdLocal, 0, sizeof(ctrl->vfeStatsCmdLocal));
-	memset(&ctrl->vfeBusConfigLocal, 0, sizeof(ctrl->vfeBusConfigLocal));
-	memset(&ctrl->vfeBusPmConfigLocal, 0,
-		sizeof(ctrl->vfeBusPmConfigLocal));
-	memset(&ctrl->vfeBusCmdLocal, 0, sizeof(ctrl->vfeBusCmdLocal));
-	memset(&ctrl->vfeInterruptNameLocal, 0,
-		sizeof(ctrl->vfeInterruptNameLocal));
-	memset(&ctrl->vfeDroppedFrameCounts, 0,
-		sizeof(ctrl->vfeDroppedFrameCounts));
-	memset(&ctrl->vfeIrqThreadMsgLocal, 0,
-		sizeof(ctrl->vfeIrqThreadMsgLocal));
-
-	/* state control variables */
-	ctrl->vfeStartAckPendingFlag = FALSE;
-	ctrl->vfeStopAckPending = FALSE;
-	ctrl->vfeIrqCompositeMaskLocal.ceDoneSel = 0;
-	ctrl->vfeIrqCompositeMaskLocal.encIrqComMask = VFE_COMP_IRQ_BOTH_Y_CBCR;
-	ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
-		VFE_COMP_IRQ_BOTH_Y_CBCR;
-
-	ctrl->vstate = VFE_STATE_IDLE;
-
-	ctrl->axiOutputMode = VFE_AXI_LAST_OUTPUT_MODE_ENUM;
-	/* 0 for continuous mode, 1 for snapshot mode */
-	ctrl->vfeOperationMode = VFE_START_OPERATION_MODE_CONTINUOUS;
-	ctrl->vfeSnapShotCount = 0;
-	ctrl->vfeStatsPingPongReloadFlag = FALSE;
-	/* this is unsigned 32 bit integer. */
-	ctrl->vfeFrameId = 0;
-	ctrl->vfeFrameSkip.output1Pattern = 0xffffffff;
-	ctrl->vfeFrameSkip.output1Period  = 31;
-	ctrl->vfeFrameSkip.output2Pattern = 0xffffffff;
-	ctrl->vfeFrameSkip.output2Period  = 31;
-	ctrl->vfeFrameSkipPattern = 0xffffffff;
-	ctrl->vfeFrameSkipCount   = 0;
-	ctrl->vfeFrameSkipPeriod  = 31;
-
-	memset((void *)&ctrl->encPath, 0, sizeof(ctrl->encPath));
-	memset((void *)&ctrl->viewPath, 0, sizeof(ctrl->viewPath));
-
-	ctrl->encPath.whichOutputPath  = 1;
-	ctrl->encPath.cbcrStatusBit    = 5;
-	ctrl->viewPath.whichOutputPath = 0;
-	ctrl->viewPath.cbcrStatusBit   = 7;
-
-	ctrl->vfeTestGenStartFlag = FALSE;
-
-	/* default to bank 0. */
-	ctrl->vfeLaBankSel = 0;
-
-	/* default to bank 0 for all channels. */
-	memset(&ctrl->vfeGammaLutSel, 0, sizeof(ctrl->vfeGammaLutSel));
-
-	/* Stats control variables. */
-	memset(&ctrl->afStatsControl, 0, sizeof(ctrl->afStatsControl));
-	memset(&ctrl->awbStatsControl, 0, sizeof(ctrl->awbStatsControl));
-	vfe_set_stats_pingpong_address(&ctrl->afStatsControl,
-		&ctrl->awbStatsControl);
-}
-
-void vfe_reset(void)
-{
-	spin_lock_init(&msm_vfe_ctrl_lock);
-	vfe_reset_internal_variables();
-
-	atomic_set(&ctrl->vfe_serv_interrupt, 1);
-	ctrl->vfeImaskLocal.resetAckIrq = TRUE;
-	ctrl->vfeImaskPacked = vfe_irq_pack(ctrl->vfeImaskLocal);
-
-	/* disable all interrupts. */
-	writel(VFE_DISABLE_ALL_IRQS, ctrl->vfebase + VFE_IRQ_COMPOSITE_MASK);
-
-	/* clear all pending interrupts*/
-	writel(VFE_CLEAR_ALL_IRQS, ctrl->vfebase + VFE_IRQ_CLEAR);
-
-	/* enable reset_ack interrupt.  */
-	writel(ctrl->vfeImaskPacked, ctrl->vfebase + VFE_IRQ_MASK);
-
-	writel(VFE_RESET_UPON_RESET_CMD, ctrl->vfebase + VFE_GLOBAL_RESET_CMD);
-}
diff --git a/drivers/media/video/msm/vfe/msm_vfe8x_proc.h b/drivers/media/video/msm/vfe/msm_vfe8x_proc.h
deleted file mode 100644
index da00e8f..0000000
--- a/drivers/media/video/msm/vfe/msm_vfe8x_proc.h
+++ /dev/null
@@ -1,1563 +0,0 @@
-/* Copyright (c) 2009, Code Aurora Forum. 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 __MSM_VFE8X_REG_H__
-#define __MSM_VFE8X_REG_H__
-
-#include <mach/msm_iomap.h>
-#include <mach/camera.h>
-#include "msm_vfe8x.h"
-
-
-#define MSM_AXI_QOS_PREVIEW		128000
-#define MSM_AXI_QOS_SNAPSHOT	128000
-#define MSM_AXI_QOS_RECORDING	128000
-
-
-/* at start of camif,  bit 1:0 = 0x01:enable
- * image data capture at frame boundary. */
-#define CAMIF_COMMAND_START  0x00000005
-
-/* bit 2= 0x1:clear the CAMIF_STATUS register
- * value. */
-#define CAMIF_COMMAND_CLEAR  0x00000004
-
-/* at stop of vfe pipeline, for now it is assumed
- * that camif will stop at any time. Bit 1:0 = 0x10:
- * disable image data capture immediately. */
-#define CAMIF_COMMAND_STOP_IMMEDIATELY  0x00000002
-
-/* at stop of vfe pipeline, for now it is assumed
- * that camif will stop at any time. Bit 1:0 = 0x00:
- * disable image data capture at frame boundary */
-#define CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY  0x00000000
-
-/* to halt axi bridge */
-#define AXI_HALT  0x00000001
-
-/* clear the halt bit. */
-#define AXI_HALT_CLEAR  0x00000000
-
-/* reset the pipeline when stop command is issued.
- * (without reset the register.) bit 26-31 = 0,
- * domain reset, bit 0-9 = 1 for module reset, except
- * register module. */
-#define VFE_RESET_UPON_STOP_CMD  0x000003ef
-
-/* reset the pipeline when reset command.
- * bit 26-31 = 0, domain reset, bit 0-9 = 1 for module reset. */
-#define VFE_RESET_UPON_RESET_CMD  0x000003ff
-
-/* bit 5 is for axi status idle or busy.
- * 1 =  halted,  0 = busy */
-#define AXI_STATUS_BUSY_MASK 0x00000020
-
-/* bit 0 & bit 1 = 1, both y and cbcr irqs need to be present
- * for frame done interrupt */
-#define VFE_COMP_IRQ_BOTH_Y_CBCR 3
-
-/* bit 1 = 1, only cbcr irq triggers frame done interrupt */
-#define VFE_COMP_IRQ_CBCR_ONLY 2
-
-/* bit 0 = 1, only y irq triggers frame done interrupt */
-#define VFE_COMP_IRQ_Y_ONLY 1
-
-/* bit 0 = 1, PM go;   bit1 = 1, PM stop */
-#define VFE_PERFORMANCE_MONITOR_GO   0x00000001
-#define VFE_PERFORMANCE_MONITOR_STOP 0x00000002
-
-/* bit 0 = 1, test gen go;   bit1 = 1, test gen stop */
-#define VFE_TEST_GEN_GO   0x00000001
-#define VFE_TEST_GEN_STOP 0x00000002
-
-/* the chroma is assumed to be interpolated between
- * the luma samples.  JPEG 4:2:2 */
-#define VFE_CHROMA_UPSAMPLE_INTERPOLATED 0
-
-/* constants for irq registers */
-#define VFE_DISABLE_ALL_IRQS 0
-/* bit =1 is to clear the corresponding bit in VFE_IRQ_STATUS.  */
-#define VFE_CLEAR_ALL_IRQS   0xffffffff
-/* imask for while waiting for stop ack,  driver has already
- * requested stop, waiting for reset irq,
- * bit 29,28,27,26 for async timer, bit 9 for reset */
-#define VFE_IMASK_WHILE_STOPPING  0x3c000200
-
-/* when normal case, don't want to block error status.
- * bit 0,6,20,21,22,30,31 */
-#define VFE_IMASK_ERROR_ONLY             0xC0700041
-#define VFE_REG_UPDATE_TRIGGER           1
-#define VFE_PM_BUF_MAX_CNT_MASK          0xFF
-#define VFE_DMI_CFG_DEFAULT              0x00000100
-#define LENS_ROLL_OFF_DELTA_TABLE_OFFSET 32
-#define VFE_AF_PINGPONG_STATUS_BIT       0x100
-#define VFE_AWB_PINGPONG_STATUS_BIT      0x200
-
-/* VFE I/O registers */
-enum {
-	VFE_HW_VERSION                    = 0x00000000,
-	VFE_GLOBAL_RESET_CMD              = 0x00000004,
-	VFE_MODULE_RESET                  = 0x00000008,
-	VFE_CGC_OVERRIDE                  = 0x0000000C,
-	VFE_MODULE_CFG                    = 0x00000010,
-	VFE_CFG                           = 0x00000014,
-	VFE_IRQ_MASK                      = 0x00000018,
-	VFE_IRQ_CLEAR                     = 0x0000001C,
-VFE_IRQ_STATUS                    = 0x00000020,
-VFE_IRQ_COMPOSITE_MASK            = 0x00000024,
-VFE_BUS_CMD                       = 0x00000028,
-VFE_BUS_CFG                       = 0x0000002C,
-VFE_BUS_ENC_Y_WR_PING_ADDR        = 0x00000030,
-VFE_BUS_ENC_Y_WR_PONG_ADDR        = 0x00000034,
-VFE_BUS_ENC_Y_WR_IMAGE_SIZE       = 0x00000038,
-VFE_BUS_ENC_Y_WR_BUFFER_CFG       = 0x0000003C,
-VFE_BUS_ENC_CBCR_WR_PING_ADDR     = 0x00000040,
-VFE_BUS_ENC_CBCR_WR_PONG_ADDR     = 0x00000044,
-VFE_BUS_ENC_CBCR_WR_IMAGE_SIZE    = 0x00000048,
-VFE_BUS_ENC_CBCR_WR_BUFFER_CFG    = 0x0000004C,
-VFE_BUS_VIEW_Y_WR_PING_ADDR       = 0x00000050,
-VFE_BUS_VIEW_Y_WR_PONG_ADDR       = 0x00000054,
-VFE_BUS_VIEW_Y_WR_IMAGE_SIZE      = 0x00000058,
-VFE_BUS_VIEW_Y_WR_BUFFER_CFG      = 0x0000005C,
-VFE_BUS_VIEW_CBCR_WR_PING_ADDR    = 0x00000060,
-VFE_BUS_VIEW_CBCR_WR_PONG_ADDR    = 0x00000064,
-VFE_BUS_VIEW_CBCR_WR_IMAGE_SIZE   = 0x00000068,
-VFE_BUS_VIEW_CBCR_WR_BUFFER_CFG   = 0x0000006C,
-VFE_BUS_STATS_AF_WR_PING_ADDR     = 0x00000070,
-VFE_BUS_STATS_AF_WR_PONG_ADDR     = 0x00000074,
-VFE_BUS_STATS_AWB_WR_PING_ADDR    = 0x00000078,
-VFE_BUS_STATS_AWB_WR_PONG_ADDR    = 0x0000007C,
-VFE_BUS_STATS_HIST_WR_PING_ADDR   = 0x00000080,
-VFE_BUS_STATS_HIST_WR_PONG_ADDR   = 0x00000084,
-VFE_BUS_STATS_WR_PRIORITY         = 0x00000088,
-VFE_BUS_STRIPE_RD_ADDR_0          = 0x0000008C,
-VFE_BUS_STRIPE_RD_ADDR_1          = 0x00000090,
-VFE_BUS_STRIPE_RD_ADDR_2          = 0x00000094,
-VFE_BUS_STRIPE_RD_ADDR_3          = 0x00000098,
-VFE_BUS_STRIPE_RD_VSIZE           = 0x0000009C,
-VFE_BUS_STRIPE_RD_HSIZE           = 0x000000A0,
-VFE_BUS_STRIPE_RD_BUFFER_CFG      = 0x000000A4,
-VFE_BUS_STRIPE_RD_UNPACK_CFG      = 0x000000A8,
-VFE_BUS_STRIPE_RD_UNPACK          = 0x000000AC,
-VFE_BUS_STRIPE_RD_PAD_SIZE        = 0x000000B0,
-VFE_BUS_STRIPE_RD_PAD_L_UNPACK    = 0x000000B4,
-VFE_BUS_STRIPE_RD_PAD_R_UNPACK    = 0x000000B8,
-VFE_BUS_STRIPE_RD_PAD_TB_UNPACK   = 0x000000BC,
-VFE_BUS_PINGPONG_IRQ_EN           = 0x000000C0,
-VFE_BUS_PINGPONG_STATUS           = 0x000000C4,
-VFE_BUS_PM_CMD                    = 0x000000C8,
-VFE_BUS_PM_CFG                    = 0x000000CC,
-VFE_BUS_ENC_Y_WR_PM_STATS_0       = 0x000000D0,
-VFE_BUS_ENC_Y_WR_PM_STATS_1       = 0x000000D4,
-VFE_BUS_ENC_CBCR_WR_PM_STATS_0    = 0x000000D8,
-VFE_BUS_ENC_CBCR_WR_PM_STATS_1    = 0x000000DC,
-VFE_BUS_VIEW_Y_WR_PM_STATS_0      = 0x000000E0,
-VFE_BUS_VIEW_Y_WR_PM_STATS_1      = 0x000000E4,
-VFE_BUS_VIEW_CBCR_WR_PM_STATS_0   = 0x000000E8,
-VFE_BUS_VIEW_CBCR_WR_PM_STATS_1   = 0x000000EC,
-VFE_BUS_MISR_CFG                  = 0x000000F4,
-VFE_BUS_MISR_MAST_CFG_0           = 0x000000F8,
-VFE_BUS_MISR_MAST_CFG_1           = 0x000000FC,
-VFE_BUS_MISR_RD_VAL               = 0x00000100,
-VFE_AXI_CMD                       = 0x00000104,
-VFE_AXI_CFG                       = 0x00000108,
-VFE_AXI_STATUS                    = 0x0000010C,
-CAMIF_COMMAND                     = 0x00000110,
-CAMIF_CONFIG                      = 0x00000114,
-CAMIF_EFS_CONFIG                  = 0x00000118,
-CAMIF_FRAME_CONFIG                = 0x0000011C,
-CAMIF_WINDOW_WIDTH_CONFIG         = 0x00000120,
-CAMIF_WINDOW_HEIGHT_CONFIG        = 0x00000124,
-CAMIF_SUBSAMPLE1_CONFIG           = 0x00000128,
-CAMIF_SUBSAMPLE2_CONFIG           = 0x0000012C,
-CAMIF_EPOCH_IRQ                   = 0x00000130,
-CAMIF_STATUS                      = 0x00000134,
-CAMIF_MISR                        = 0x00000138,
-VFE_SYNC_TIMER_CMD                = 0x0000013C,
-VFE_SYNC_TIMER0_LINE_START        = 0x00000140,
-VFE_SYNC_TIMER0_PIXEL_START       = 0x00000144,
-VFE_SYNC_TIMER0_PIXEL_DURATION    = 0x00000148,
-VFE_SYNC_TIMER1_LINE_START        = 0x0000014C,
-VFE_SYNC_TIMER1_PIXEL_START       = 0x00000150,
-VFE_SYNC_TIMER1_PIXEL_DURATION    = 0x00000154,
-VFE_SYNC_TIMER2_LINE_START        = 0x00000158,
-VFE_SYNC_TIMER2_PIXEL_START       = 0x0000015C,
-VFE_SYNC_TIMER2_PIXEL_DURATION    = 0x00000160,
-VFE_SYNC_TIMER_POLARITY           = 0x00000164,
-VFE_ASYNC_TIMER_CMD               = 0x00000168,
-VFE_ASYNC_TIMER0_CFG_0            = 0x0000016C,
-VFE_ASYNC_TIMER0_CFG_1            = 0x00000170,
-VFE_ASYNC_TIMER1_CFG_0            = 0x00000174,
-VFE_ASYNC_TIMER1_CFG_1            = 0x00000178,
-VFE_ASYNC_TIMER2_CFG_0            = 0x0000017C,
-VFE_ASYNC_TIMER2_CFG_1            = 0x00000180,
-VFE_ASYNC_TIMER3_CFG_0            = 0x00000184,
-VFE_ASYNC_TIMER3_CFG_1            = 0x00000188,
-VFE_TIMER_SEL                     = 0x0000018C,
-VFE_REG_UPDATE_CMD                = 0x00000190,
-VFE_BLACK_EVEN_EVEN_VALUE         = 0x00000194,
-VFE_BLACK_EVEN_ODD_VALUE          = 0x00000198,
-VFE_BLACK_ODD_EVEN_VALUE          = 0x0000019C,
-VFE_BLACK_ODD_ODD_VALUE           = 0x000001A0,
-VFE_ROLLOFF_CFG_0                 = 0x000001A4,
-VFE_ROLLOFF_CFG_1                 = 0x000001A8,
-VFE_ROLLOFF_CFG_2                 = 0x000001AC,
-VFE_DEMUX_CFG                     = 0x000001B0,
-VFE_DEMUX_GAIN_0                  = 0x000001B4,
-VFE_DEMUX_GAIN_1                  = 0x000001B8,
-VFE_DEMUX_EVEN_CFG                = 0x000001BC,
-VFE_DEMUX_ODD_CFG                 = 0x000001C0,
-VFE_DEMOSAIC_CFG                  = 0x000001C4,
-VFE_DEMOSAIC_ABF_CFG_0            = 0x000001C8,
-VFE_DEMOSAIC_ABF_CFG_1            = 0x000001CC,
-VFE_DEMOSAIC_BPC_CFG_0            = 0x000001D0,
-VFE_DEMOSAIC_BPC_CFG_1            = 0x000001D4,
-VFE_DEMOSAIC_STATUS               = 0x000001D8,
-VFE_CHROMA_UPSAMPLE_CFG           = 0x000001DC,
-VFE_CROP_WIDTH_CFG                = 0x000001E0,
-VFE_CROP_HEIGHT_CFG               = 0x000001E4,
-VFE_COLOR_CORRECT_COEFF_0         = 0x000001E8,
-VFE_COLOR_CORRECT_COEFF_1         = 0x000001EC,
-VFE_COLOR_CORRECT_COEFF_2         = 0x000001F0,
-VFE_COLOR_CORRECT_COEFF_3         = 0x000001F4,
-VFE_COLOR_CORRECT_COEFF_4         = 0x000001F8,
-VFE_COLOR_CORRECT_COEFF_5         = 0x000001FC,
-VFE_COLOR_CORRECT_COEFF_6         = 0x00000200,
-VFE_COLOR_CORRECT_COEFF_7         = 0x00000204,
-VFE_COLOR_CORRECT_COEFF_8         = 0x00000208,
-VFE_COLOR_CORRECT_OFFSET_0        = 0x0000020C,
-VFE_COLOR_CORRECT_OFFSET_1        = 0x00000210,
-VFE_COLOR_CORRECT_OFFSET_2        = 0x00000214,
-VFE_COLOR_CORRECT_COEFF_Q         = 0x00000218,
-VFE_LA_CFG                        = 0x0000021C,
-VFE_LUT_BANK_SEL                  = 0x00000220,
-VFE_CHROMA_ENHAN_A                = 0x00000224,
-VFE_CHROMA_ENHAN_B                = 0x00000228,
-VFE_CHROMA_ENHAN_C                = 0x0000022C,
-VFE_CHROMA_ENHAN_D                = 0x00000230,
-VFE_CHROMA_ENHAN_K                = 0x00000234,
-VFE_COLOR_CONVERT_COEFF_0         = 0x00000238,
-VFE_COLOR_CONVERT_COEFF_1         = 0x0000023C,
-VFE_COLOR_CONVERT_COEFF_2         = 0x00000240,
-VFE_COLOR_CONVERT_OFFSET          = 0x00000244,
-VFE_ASF_CFG                       = 0x00000248,
-VFE_ASF_SHARP_CFG_0               = 0x0000024C,
-VFE_ASF_SHARP_CFG_1               = 0x00000250,
-VFE_ASF_SHARP_COEFF_0             = 0x00000254,
-VFE_ASF_SHARP_COEFF_1             = 0x00000258,
-VFE_ASF_SHARP_COEFF_2             = 0x0000025C,
-VFE_ASF_SHARP_COEFF_3             = 0x00000260,
-VFE_ASF_MAX_EDGE                  = 0x00000264,
-VFE_ASF_CROP_WIDTH_CFG            = 0x00000268,
-VFE_ASF_CROP_HEIGHT_CFG           = 0x0000026C,
-VFE_SCALE_CFG                     = 0x00000270,
-VFE_SCALE_H_IMAGE_SIZE_CFG        = 0x00000274,
-VFE_SCALE_H_PHASE_CFG             = 0x00000278,
-VFE_SCALE_H_STRIPE_CFG            = 0x0000027C,
-VFE_SCALE_V_IMAGE_SIZE_CFG        = 0x00000280,
-VFE_SCALE_V_PHASE_CFG             = 0x00000284,
-VFE_SCALE_V_STRIPE_CFG            = 0x00000288,
-VFE_SCALE_Y_CFG                   = 0x0000028C,
-VFE_SCALE_Y_H_IMAGE_SIZE_CFG      = 0x00000290,
-VFE_SCALE_Y_H_PHASE_CFG           = 0x00000294,
-VFE_SCALE_Y_V_IMAGE_SIZE_CFG      = 0x00000298,
-VFE_SCALE_Y_V_PHASE_CFG           = 0x0000029C,
-VFE_SCALE_CBCR_CFG                = 0x000002A0,
-VFE_SCALE_CBCR_H_IMAGE_SIZE_CFG   = 0x000002A4,
-VFE_SCALE_CBCR_H_PHASE_CFG        = 0x000002A8,
-VFE_SCALE_CBCR_V_IMAGE_SIZE_CFG   = 0x000002AC,
-VFE_SCALE_CBCR_V_PHASE_CFG        = 0x000002B0,
-VFE_WB_CFG                        = 0x000002B4,
-VFE_CHROMA_SUPPRESS_CFG_0         = 0x000002B8,
-VFE_CHROMA_SUPPRESS_CFG_1         = 0x000002BC,
-VFE_CHROMA_SUBSAMPLE_CFG          = 0x000002C0,
-VFE_CHROMA_SUB_CROP_WIDTH_CFG     = 0x000002C4,
-VFE_CHROMA_SUB_CROP_HEIGHT_CFG    = 0x000002C8,
-VFE_FRAMEDROP_ENC_Y_CFG           = 0x000002CC,
-VFE_FRAMEDROP_ENC_CBCR_CFG        = 0x000002D0,
-VFE_FRAMEDROP_ENC_Y_PATTERN       = 0x000002D4,
-VFE_FRAMEDROP_ENC_CBCR_PATTERN    = 0x000002D8,
-VFE_FRAMEDROP_VIEW_Y_CFG          = 0x000002DC,
-VFE_FRAMEDROP_VIEW_CBCR_CFG       = 0x000002E0,
-VFE_FRAMEDROP_VIEW_Y_PATTERN      = 0x000002E4,
-VFE_FRAMEDROP_VIEW_CBCR_PATTERN   = 0x000002E8,
-VFE_CLAMP_MAX_CFG                 = 0x000002EC,
-VFE_CLAMP_MIN_CFG                 = 0x000002F0,
-VFE_STATS_CMD                     = 0x000002F4,
-VFE_STATS_AF_CFG                  = 0x000002F8,
-VFE_STATS_AF_DIM                  = 0x000002FC,
-VFE_STATS_AF_GRID_0               = 0x00000300,
-VFE_STATS_AF_GRID_1               = 0x00000304,
-VFE_STATS_AF_GRID_2               = 0x00000308,
-VFE_STATS_AF_GRID_3               = 0x0000030C,
-VFE_STATS_AF_HEADER               = 0x00000310,
-VFE_STATS_AF_COEF0                = 0x00000314,
-VFE_STATS_AF_COEF1                = 0x00000318,
-VFE_STATS_AWBAE_CFG               = 0x0000031C,
-VFE_STATS_AXW_HEADER              = 0x00000320,
-VFE_STATS_AWB_MCFG                = 0x00000324,
-VFE_STATS_AWB_CCFG1               = 0x00000328,
-VFE_STATS_AWB_CCFG2               = 0x0000032C,
-VFE_STATS_HIST_HEADER             = 0x00000330,
-VFE_STATS_HIST_INNER_OFFSET       = 0x00000334,
-VFE_STATS_HIST_INNER_DIM          = 0x00000338,
-VFE_STATS_FRAME_SIZE              = 0x0000033C,
-VFE_DMI_CFG                       = 0x00000340,
-VFE_DMI_ADDR                      = 0x00000344,
-VFE_DMI_DATA_HI                   = 0x00000348,
-VFE_DMI_DATA_LO                   = 0x0000034C,
-VFE_DMI_RAM_AUTO_LOAD_CMD         = 0x00000350,
-VFE_DMI_RAM_AUTO_LOAD_STATUS      = 0x00000354,
-VFE_DMI_RAM_AUTO_LOAD_CFG         = 0x00000358,
-VFE_DMI_RAM_AUTO_LOAD_SEED        = 0x0000035C,
-VFE_TESTBUS_SEL                   = 0x00000360,
-VFE_TESTGEN_CFG                   = 0x00000364,
-VFE_SW_TESTGEN_CMD                = 0x00000368,
-VFE_HW_TESTGEN_CMD                = 0x0000036C,
-VFE_HW_TESTGEN_CFG                = 0x00000370,
-VFE_HW_TESTGEN_IMAGE_CFG          = 0x00000374,
-VFE_HW_TESTGEN_SOF_OFFSET_CFG     = 0x00000378,
-VFE_HW_TESTGEN_EOF_NOFFSET_CFG    = 0x0000037C,
-VFE_HW_TESTGEN_SOL_OFFSET_CFG     = 0x00000380,
-VFE_HW_TESTGEN_EOL_NOFFSET_CFG    = 0x00000384,
-VFE_HW_TESTGEN_HBI_CFG            = 0x00000388,
-VFE_HW_TESTGEN_VBL_CFG            = 0x0000038C,
-VFE_HW_TESTGEN_SOF_DUMMY_LINE_CFG2 = 0x00000390,
-VFE_HW_TESTGEN_EOF_DUMMY_LINE_CFG2 = 0x00000394,
-VFE_HW_TESTGEN_COLOR_BARS_CFG     = 0x00000398,
-VFE_HW_TESTGEN_RANDOM_CFG         = 0x0000039C,
-VFE_SPARE                         = 0x000003A0,
-};
-
-#define ping 0x0
-#define pong 0x1
-
-struct vfe_bus_cfg_data {
-	boolean                  stripeRdPathEn;
-	boolean                  encYWrPathEn;
-	boolean                  encCbcrWrPathEn;
-	boolean                  viewYWrPathEn;
-	boolean                  viewCbcrWrPathEn;
-	enum VFE_RAW_PIXEL_DATA_SIZE rawPixelDataSize;
-	enum VFE_RAW_WR_PATH_SEL     rawWritePathSelect;
-};
-
-struct vfe_camif_cfg_data {
-	boolean camif2OutputEnable;
-	boolean camif2BusEnable;
-	struct vfe_cmds_camif_cfg camifCfgFromCmd;
-};
-
-struct vfe_irq_composite_mask_config {
-	uint8_t encIrqComMask;
-	uint8_t viewIrqComMask;
-	uint8_t ceDoneSel;
-};
-
-/* define a structure for each output path.*/
-struct vfe_output_path {
-	uint32_t addressBuffer[8];
-	uint16_t fragIndex;
-	boolean  hwCurrentFlag;
-	uint8_t  *hwRegPingAddress;
-	uint8_t  *hwRegPongAddress;
-};
-
-struct vfe_output_path_combo {
-	boolean           whichOutputPath;
-	boolean           pathEnabled;
-	boolean           multiFrag;
-	uint8_t           fragCount;
-	boolean           ackPending;
-	uint8_t           currentFrame;
-	uint32_t          nextFrameAddrBuf[8];
-	struct vfe_output_path   yPath;
-	struct vfe_output_path   cbcrPath;
-	uint8_t           snapshotPendingCount;
-	boolean           pmEnabled;
-	uint8_t           cbcrStatusBit;
-};
-
-struct vfe_stats_control {
-	boolean  ackPending;
-	uint32_t addressBuffer[2];
-	uint32_t nextFrameAddrBuf;
-	boolean  pingPongStatus;
-	uint8_t  *hwRegPingAddress;
-	uint8_t  *hwRegPongAddress;
-	uint32_t droppedStatsFrameCount;
-	uint32_t bufToRender;
-};
-
-struct vfe_gamma_lut_sel {
-	boolean  ch0BankSelect;
-	boolean  ch1BankSelect;
-	boolean  ch2BankSelect;
-};
-
-struct vfe_interrupt_mask {
-	boolean  camifErrorIrq;
-	boolean  camifSofIrq;
-	boolean  camifEolIrq;
-	boolean  camifEofIrq;
-	boolean  camifEpoch1Irq;
-	boolean  camifEpoch2Irq;
-	boolean  camifOverflowIrq;
-	boolean  ceIrq;
-	boolean  regUpdateIrq;
-	boolean  resetAckIrq;
-	boolean  encYPingpongIrq;
-	boolean  encCbcrPingpongIrq;
-	boolean  viewYPingpongIrq;
-	boolean  viewCbcrPingpongIrq;
-	boolean  rdPingpongIrq;
-	boolean  afPingpongIrq;
-	boolean  awbPingpongIrq;
-	boolean  histPingpongIrq;
-	boolean  encIrq;
-	boolean  viewIrq;
-	boolean  busOverflowIrq;
-	boolean  afOverflowIrq;
-	boolean  awbOverflowIrq;
-	boolean  syncTimer0Irq;
-	boolean  syncTimer1Irq;
-	boolean  syncTimer2Irq;
-	boolean  asyncTimer0Irq;
-	boolean  asyncTimer1Irq;
-	boolean  asyncTimer2Irq;
-	boolean  asyncTimer3Irq;
-	boolean  axiErrorIrq;
-	boolean  violationIrq;
-};
-
-enum vfe_interrupt_name {
-	CAMIF_ERROR_IRQ,
-	CAMIF_SOF_IRQ,
-	CAMIF_EOL_IRQ,
-	CAMIF_EOF_IRQ,
-	CAMIF_EPOCH1_IRQ,
-	CAMIF_EPOCH2_IRQ,
-	CAMIF_OVERFLOW_IRQ,
-	CE_IRQ,
-	REG_UPDATE_IRQ,
-	RESET_ACK_IRQ,
-	ENC_Y_PINGPONG_IRQ,
-	ENC_CBCR_PINGPONG_IRQ,
-	VIEW_Y_PINGPONG_IRQ,
-	VIEW_CBCR_PINGPONG_IRQ,
-	RD_PINGPONG_IRQ,
-	AF_PINGPONG_IRQ,
-	AWB_PINGPONG_IRQ,
-	HIST_PINGPONG_IRQ,
-	ENC_IRQ,
-	VIEW_IRQ,
-	BUS_OVERFLOW_IRQ,
-	AF_OVERFLOW_IRQ,
-	AWB_OVERFLOW_IRQ,
-	SYNC_TIMER0_IRQ,
-	SYNC_TIMER1_IRQ,
-	SYNC_TIMER2_IRQ,
-	ASYNC_TIMER0_IRQ,
-	ASYNC_TIMER1_IRQ,
-	ASYNC_TIMER2_IRQ,
-	ASYNC_TIMER3_IRQ,
-	AXI_ERROR_IRQ,
-	VIOLATION_IRQ
-};
-
-enum VFE_DMI_RAM_SEL {
-	NO_MEM_SELECTED          = 0,
-	ROLLOFF_RAM              = 0x1,
-	RGBLUT_RAM_CH0_BANK0     = 0x2,
-	RGBLUT_RAM_CH0_BANK1     = 0x3,
-	RGBLUT_RAM_CH1_BANK0     = 0x4,
-	RGBLUT_RAM_CH1_BANK1     = 0x5,
-	RGBLUT_RAM_CH2_BANK0     = 0x6,
-	RGBLUT_RAM_CH2_BANK1     = 0x7,
-	STATS_HIST_CB_EVEN_RAM   = 0x8,
-	STATS_HIST_CB_ODD_RAM    = 0x9,
-	STATS_HIST_CR_EVEN_RAM   = 0xa,
-	STATS_HIST_CR_ODD_RAM    = 0xb,
-	RGBLUT_CHX_BANK0         = 0xc,
-	RGBLUT_CHX_BANK1         = 0xd,
-	LUMA_ADAPT_LUT_RAM_BANK0 = 0xe,
-	LUMA_ADAPT_LUT_RAM_BANK1 = 0xf
-};
-
-struct vfe_module_enable {
-	boolean  blackLevelCorrectionEnable;
-	boolean  lensRollOffEnable;
-	boolean  demuxEnable;
-	boolean  chromaUpsampleEnable;
-	boolean  demosaicEnable;
-	boolean  statsEnable;
-	boolean  cropEnable;
-	boolean  mainScalerEnable;
-	boolean  whiteBalanceEnable;
-	boolean  colorCorrectionEnable;
-	boolean  yHistEnable;
-	boolean  skinToneEnable;
-	boolean  lumaAdaptationEnable;
-	boolean  rgbLUTEnable;
-	boolean  chromaEnhanEnable;
-	boolean  asfEnable;
-	boolean  chromaSuppressionEnable;
-	boolean  chromaSubsampleEnable;
-	boolean  scaler2YEnable;
-	boolean  scaler2CbcrEnable;
-};
-
-struct vfe_bus_cmd_data {
-	boolean  stripeReload;
-	boolean  busPingpongReload;
-	boolean  statsPingpongReload;
-};
-
-struct vfe_stats_cmd_data {
-	boolean  autoFocusEnable;
-	boolean  axwEnable;
-	boolean  histEnable;
-	boolean  clearHistEnable;
-	boolean  histAutoClearEnable;
-	boolean  colorConversionEnable;
-};
-
-struct vfe_hw_ver {
-	uint32_t minorVersion:8;
-	uint32_t majorVersion:8;
-	uint32_t coreVersion:4;
-	uint32_t /* reserved */ : 12;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_cfg {
-	uint32_t pixelPattern:3;
-	uint32_t /* reserved */ : 13;
-	uint32_t inputSource:2;
-	uint32_t /* reserved */ : 14;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_buscmd {
-	uint32_t  stripeReload:1;
-	uint32_t  /* reserved */ : 3;
-	uint32_t  busPingpongReload:1;
-	uint32_t  statsPingpongReload:1;
-	uint32_t  /* reserved */ : 26;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_Irq_Composite_MaskType {
-	uint32_t  encIrqComMaskBits:2;
-	uint32_t  viewIrqComMaskBits:2;
-	uint32_t  ceDoneSelBits:5;
-	uint32_t  /* reserved */ : 23;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_mod_enable {
-	uint32_t blackLevelCorrectionEnable:1;
-	uint32_t lensRollOffEnable:1;
-	uint32_t demuxEnable:1;
-	uint32_t chromaUpsampleEnable:1;
-	uint32_t demosaicEnable:1;
-	uint32_t statsEnable:1;
-	uint32_t cropEnable:1;
-	uint32_t mainScalerEnable:1;
-	uint32_t whiteBalanceEnable:1;
-	uint32_t colorCorrectionEnable:1;
-	uint32_t yHistEnable:1;
-	uint32_t skinToneEnable:1;
-	uint32_t lumaAdaptationEnable:1;
-	uint32_t rgbLUTEnable:1;
-	uint32_t chromaEnhanEnable:1;
-	uint32_t asfEnable:1;
-	uint32_t chromaSuppressionEnable:1;
-	uint32_t chromaSubsampleEnable:1;
-	uint32_t scaler2YEnable:1;
-	uint32_t scaler2CbcrEnable:1;
-	uint32_t /* reserved */ : 14;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_irqenable {
-	uint32_t camifErrorIrq:1;
-	uint32_t camifSofIrq:1;
-	uint32_t camifEolIrq:1;
-	uint32_t camifEofIrq:1;
-	uint32_t camifEpoch1Irq:1;
-	uint32_t camifEpoch2Irq:1;
-	uint32_t camifOverflowIrq:1;
-	uint32_t ceIrq:1;
-	uint32_t regUpdateIrq:1;
-	uint32_t resetAckIrq:1;
-	uint32_t encYPingpongIrq:1;
-	uint32_t encCbcrPingpongIrq:1;
-	uint32_t viewYPingpongIrq:1;
-	uint32_t viewCbcrPingpongIrq:1;
-	uint32_t rdPingpongIrq:1;
-	uint32_t afPingpongIrq:1;
-	uint32_t awbPingpongIrq:1;
-	uint32_t histPingpongIrq:1;
-	uint32_t encIrq:1;
-	uint32_t viewIrq:1;
-	uint32_t busOverflowIrq:1;
-	uint32_t afOverflowIrq:1;
-	uint32_t awbOverflowIrq:1;
-	uint32_t syncTimer0Irq:1;
-	uint32_t syncTimer1Irq:1;
-	uint32_t syncTimer2Irq:1;
-	uint32_t asyncTimer0Irq:1;
-	uint32_t asyncTimer1Irq:1;
-	uint32_t asyncTimer2Irq:1;
-	uint32_t asyncTimer3Irq:1;
-	uint32_t axiErrorIrq:1;
-	uint32_t violationIrq:1;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_upsample_cfg {
-	uint32_t chromaCositingForYCbCrInputs:1;
-	uint32_t /* reserved */ : 31;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_CAMIFConfigType {
-	/* CAMIF Config */
-	uint32_t  /* reserved */ : 1;
-	uint32_t  VSyncEdge:1;
-	uint32_t  HSyncEdge:1;
-	uint32_t  syncMode:2;
-	uint32_t  vfeSubsampleEnable:1;
-	uint32_t  /* reserved */ : 1;
-	uint32_t  busSubsampleEnable:1;
-	uint32_t  camif2vfeEnable:1;
-	uint32_t  /* reserved */ : 1;
-	uint32_t  camif2busEnable:1;
-	uint32_t  irqSubsampleEnable:1;
-	uint32_t  binningEnable:1;
-	uint32_t  /* reserved */ : 18;
-	uint32_t  misrEnable:1;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_camifcfg {
-	/* EFS_Config */
-	uint32_t efsEndOfLine:8;
-	uint32_t efsStartOfLine:8;
-	uint32_t efsEndOfFrame:8;
-	uint32_t efsStartOfFrame:8;
-	/* Frame Config */
-	uint32_t frameConfigPixelsPerLine:14;
-	uint32_t /* reserved */ : 2;
-	uint32_t frameConfigLinesPerFrame:14;
-	uint32_t /* reserved */ : 2;
-	/* Window Width Config */
-	uint32_t windowWidthCfgLastPixel:14;
-	uint32_t /* reserved */ : 2;
-	uint32_t windowWidthCfgFirstPixel:14;
-	uint32_t /* reserved */ : 2;
-	/* Window Height Config */
-	uint32_t windowHeightCfglastLine:14;
-	uint32_t /* reserved */ : 2;
-	uint32_t windowHeightCfgfirstLine:14;
-	uint32_t /* reserved */ : 2;
-	/* Subsample 1 Config */
-	uint32_t subsample1CfgPixelSkip:16;
-	uint32_t subsample1CfgLineSkip:16;
-	/* Subsample 2 Config */
-	uint32_t subsample2CfgFrameSkip:4;
-	uint32_t subsample2CfgFrameSkipMode:1;
-	uint32_t subsample2CfgPixelSkipWrap:1;
-	uint32_t /* reserved */ : 26;
-	/* Epoch Interrupt */
-	uint32_t epoch1Line:14;
-	uint32_t /* reserved */ : 2;
-	uint32_t epoch2Line:14;
-	uint32_t /* reserved */ : 2;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_camifframe_update {
-	uint32_t pixelsPerLine:14;
-	uint32_t /* reserved */ : 2;
-	uint32_t linesPerFrame:14;
-	uint32_t /* reserved */ : 2;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_axi_bus_cfg {
-	uint32_t  stripeRdPathEn:1;
-	uint32_t  /* reserved */ : 3;
-	uint32_t  encYWrPathEn:1;
-	uint32_t  encCbcrWrPathEn:1;
-	uint32_t  viewYWrPathEn:1;
-	uint32_t  viewCbcrWrPathEn:1;
-	uint32_t  rawPixelDataSize:2;
-	uint32_t  rawWritePathSelect:2;
-	uint32_t  /* reserved */ : 20;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_axi_out_cfg {
-	uint32_t  out2YPingAddr:32;
-	uint32_t  out2YPongAddr:32;
-	uint32_t  out2YImageHeight:12;
-	uint32_t  /* reserved */ : 4;
-	uint32_t  out2YImageWidthin64bit:10;
-	uint32_t  /* reserved */ : 6;
-	uint32_t  out2YBurstLength:2;
-	uint32_t  /* reserved */ : 2;
-	uint32_t  out2YNumRows:12;
-	uint32_t  out2YRowIncrementIn64bit:12;
-	uint32_t  /* reserved */ : 4;
-	uint32_t  out2CbcrPingAddr:32;
-	uint32_t  out2CbcrPongAddr:32;
-	uint32_t  out2CbcrImageHeight:12;
-	uint32_t  /* reserved */ : 4;
-	uint32_t  out2CbcrImageWidthIn64bit:10;
-	uint32_t  /* reserved */ : 6;
-	uint32_t  out2CbcrBurstLength:2;
-	uint32_t  /* reserved */ : 2;
-	uint32_t  out2CbcrNumRows:12;
-	uint32_t  out2CbcrRowIncrementIn64bit:12;
-	uint32_t  /* reserved */ : 4;
-	uint32_t  out1YPingAddr:32;
-	uint32_t  out1YPongAddr:32;
-	uint32_t  out1YImageHeight:12;
-	uint32_t  /* reserved */ : 4;
-	uint32_t  out1YImageWidthin64bit:10;
-	uint32_t  /* reserved */ : 6;
-	uint32_t  out1YBurstLength:2;
-	uint32_t  /* reserved */ : 2;
-	uint32_t  out1YNumRows:12;
-	uint32_t  out1YRowIncrementIn64bit:12;
-	uint32_t  /* reserved */ : 4;
-	uint32_t  out1CbcrPingAddr:32;
-	uint32_t  out1CbcrPongAddr:32;
-	uint32_t  out1CbcrImageHeight:12;
-	uint32_t  /* reserved */ : 4;
-	uint32_t  out1CbcrImageWidthIn64bit:10;
-	uint32_t  /* reserved */ : 6;
-	uint32_t  out1CbcrBurstLength:2;
-	uint32_t  /* reserved */ : 2;
-	uint32_t  out1CbcrNumRows:12;
-	uint32_t  out1CbcrRowIncrementIn64bit:12;
-	uint32_t  /* reserved */ : 4;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_output_clamp_cfg {
-	/* Output Clamp Maximums */
-	uint32_t yChanMax:8;
-	uint32_t cbChanMax:8;
-	uint32_t crChanMax:8;
-	uint32_t /* reserved */ : 8;
-	/* Output Clamp Minimums */
-	uint32_t yChanMin:8;
-	uint32_t cbChanMin:8;
-	uint32_t crChanMin:8;
-	uint32_t /* reserved */ : 8;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_fov_crop_cfg {
-	uint32_t lastPixel:12;
-	uint32_t /* reserved */ : 4;
-	uint32_t firstPixel:12;
-	uint32_t /* reserved */ : 4;
-
-	/* FOV Corp, Part 2 */
-	uint32_t lastLine:12;
-	uint32_t /* reserved */ : 4;
-	uint32_t firstLine:12;
-	uint32_t /* reserved */ : 4;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_FRAME_SKIP_UpdateCmdType {
-	uint32_t  yPattern:32;
-	uint32_t  cbcrPattern:32;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_frame_skip_cfg {
-	/* Frame Drop Enc (output2) */
-	uint32_t output2YPeriod:5;
-	uint32_t /* reserved */	: 27;
-	uint32_t output2CbCrPeriod:5;
-	uint32_t /* reserved */ : 27;
-	uint32_t output2YPattern:32;
-	uint32_t output2CbCrPattern:32;
-	/* Frame Drop View (output1) */
-	uint32_t output1YPeriod:5;
-	uint32_t /* reserved */ : 27;
-	uint32_t output1CbCrPeriod:5;
-	uint32_t /* reserved */ : 27;
-	uint32_t output1YPattern:32;
-	uint32_t output1CbCrPattern:32;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_main_scaler_cfg {
-	/* Scaler Enable Config */
-	uint32_t hEnable:1;
-	uint32_t vEnable:1;
-	uint32_t /* reserved */ : 30;
-	/* Scale H Image Size Config */
-	uint32_t inWidth:12;
-	uint32_t /* reserved */ : 4;
-	uint32_t outWidth:12;
-	uint32_t /* reserved */ : 4;
-	/* Scale H Phase Config */
-	uint32_t horizPhaseMult:18;
-	uint32_t /* reserved */ : 2;
-	uint32_t horizInterResolution:2;
-	uint32_t /* reserved */ : 10;
-	/* Scale H Stripe Config */
-	uint32_t horizMNInit:12;
-	uint32_t /* reserved */ : 4;
-	uint32_t horizPhaseInit:15;
-	uint32_t /* reserved */ : 1;
-	/* Scale V Image Size Config */
-	uint32_t inHeight:12;
-	uint32_t /* reserved */ : 4;
-	uint32_t outHeight:12;
-	uint32_t /* reserved */ : 4;
-	/* Scale V Phase Config */
-	uint32_t vertPhaseMult:18;
-	uint32_t /* reserved */ : 2;
-	uint32_t vertInterResolution:2;
-	uint32_t /* reserved */ : 10;
-	/* Scale V Stripe Config */
-	uint32_t vertMNInit:12;
-	uint32_t /* reserved */ : 4;
-	uint32_t vertPhaseInit:15;
-	uint32_t /* reserved */ : 1;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_scaler2_cfg {
-	/* Scaler   Enable Config */
-	uint32_t  hEnable:1;
-	uint32_t  vEnable:1;
-	uint32_t  /* reserved */ : 30;
-	/* Scaler   H Image Size Config */
-	uint32_t  inWidth:12;
-	uint32_t  /* reserved */ : 4;
-	uint32_t  outWidth:12;
-	uint32_t  /* reserved */ : 4;
-	/* Scaler   H Phase Config */
-	uint32_t  horizPhaseMult:18;
-	uint32_t  /* reserved */ : 2;
-	uint32_t  horizInterResolution:2;
-	uint32_t  /* reserved */ : 10;
-	/* Scaler   V Image Size Config */
-	uint32_t  inHeight:12;
-	uint32_t  /* reserved */ : 4;
-	uint32_t  outHeight:12;
-	uint32_t  /* reserved */ : 4;
-	/* Scaler   V Phase Config */
-	uint32_t  vertPhaseMult:18;
-	uint32_t  /* reserved */ : 2;
-	uint32_t  vertInterResolution:2;
-	uint32_t  /* reserved */ : 10;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_rolloff_cfg {
-	/* Rolloff 0 Config */
-	uint32_t  gridWidth:9;
-	uint32_t  gridHeight:9;
-	uint32_t  yDelta:9;
-	uint32_t  /* reserved */ : 5;
-	/* Rolloff 1 Config*/
-	uint32_t  gridX:4;
-	uint32_t  gridY:4;
-	uint32_t  pixelX:9;
-	uint32_t  /* reserved */ : 3;
-	uint32_t  pixelY:9;
-	uint32_t  /* reserved */ : 3;
-	/* Rolloff 2 Config */
-	uint32_t  yDeltaAccum:12;
-	uint32_t  /* reserved */ : 20;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_asf_update {
-	/* ASF Config Command */
-	uint32_t smoothEnable:1;
-	uint32_t sharpMode:2;
-	uint32_t /* reserved */ : 1;
-	uint32_t smoothCoeff1:4;
-	uint32_t smoothCoeff0:8;
-	uint32_t pipeFlushCount:12;
-	uint32_t pipeFlushOvd:1;
-	uint32_t flushHaltOvd:1;
-	uint32_t cropEnable:1;
-	uint32_t /* reserved */ : 1;
-	/* Sharpening Config 0 */
-	uint32_t sharpThresholdE1:7;
-	uint32_t /* reserved */ : 1;
-	uint32_t sharpDegreeK1:5;
-	uint32_t /* reserved */ : 3;
-	uint32_t sharpDegreeK2:5;
-	uint32_t /* reserved */ : 3;
-	uint32_t normalizeFactor:7;
-	uint32_t /* reserved */ : 1;
-	/* Sharpening Config 1 */
-	uint32_t sharpThresholdE2:8;
-	uint32_t sharpThresholdE3:8;
-	uint32_t sharpThresholdE4:8;
-	uint32_t sharpThresholdE5:8;
-	/* Sharpening Coefficients 0 */
-	uint32_t F1Coeff0:6;
-	uint32_t F1Coeff1:6;
-	uint32_t F1Coeff2:6;
-	uint32_t F1Coeff3:6;
-	uint32_t F1Coeff4:6;
-	uint32_t /* reserved */ : 2;
-	/* Sharpening Coefficients 1 */
-	uint32_t F1Coeff5:6;
-	uint32_t F1Coeff6:6;
-	uint32_t F1Coeff7:6;
-	uint32_t F1Coeff8:7;
-	uint32_t /* reserved */ : 7;
-	/* Sharpening Coefficients 2 */
-	uint32_t F2Coeff0:6;
-	uint32_t F2Coeff1:6;
-	uint32_t F2Coeff2:6;
-	uint32_t F2Coeff3:6;
-	uint32_t F2Coeff4:6;
-	uint32_t /* reserved */ : 2;
-	/* Sharpening Coefficients 3 */
-	uint32_t F2Coeff5:6;
-	uint32_t F2Coeff6:6;
-	uint32_t F2Coeff7:6;
-	uint32_t F2Coeff8:7;
-	uint32_t /* reserved */ : 7;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_asfcrop_cfg {
-	/* ASF Crop Width Config */
-	uint32_t lastPixel:12;
-	uint32_t /* reserved */ : 4;
-	uint32_t firstPixel:12;
-	uint32_t /* reserved */ : 4;
-	/* ASP Crop Height Config */
-	uint32_t lastLine:12;
-	uint32_t /* reserved */ : 4;
-	uint32_t firstLine:12;
-	uint32_t /* reserved */ : 4;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_chroma_suppress_cfg {
-	/* Chroma Suppress 0 Config */
-	uint32_t m1:8;
-	uint32_t m3:8;
-	uint32_t n1:3;
-	uint32_t /* reserved */ : 1;
-	uint32_t n3:3;
-	uint32_t /* reserved */ : 9;
-	/* Chroma Suppress 1 Config */
-	uint32_t mm1:8;
-	uint32_t nn1:3;
-	uint32_t /* reserved */ : 21;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_chromasubsample_cfg {
-	/* Chroma Subsample Selection */
-	uint32_t  hCositedPhase:1;
-	uint32_t  vCositedPhase:1;
-	uint32_t  hCosited:1;
-	uint32_t  vCosited:1;
-	uint32_t  hsubSampleEnable:1;
-	uint32_t  vsubSampleEnable:1;
-	uint32_t  cropEnable:1;
-	uint32_t  /* reserved */ : 25;
-	uint32_t  cropWidthLastPixel:12;
-	uint32_t  /* reserved */ : 4;
-	uint32_t  cropWidthFirstPixel:12;
-	uint32_t  /* reserved */ : 4;
-	uint32_t  cropHeightLastLine:12;
-	uint32_t  /* reserved */ : 4;
-	uint32_t  cropHeightFirstLine:12;
-	uint32_t  /* reserved */ : 4;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_blacklevel_cfg {
-	/* Black Even-Even Value Config */
-	uint32_t    evenEvenAdjustment:9;
-	uint32_t   /* reserved */ : 23;
-	/* Black Even-Odd Value Config */
-	uint32_t    evenOddAdjustment:9;
-	uint32_t   /* reserved */ : 23;
-	/* Black Odd-Even Value Config */
-	uint32_t    oddEvenAdjustment:9;
-	uint32_t   /* reserved */ : 23;
-	/* Black Odd-Odd Value Config */
-	uint32_t    oddOddAdjustment:9;
-	uint32_t   /* reserved */ : 23;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_demux_cfg {
-	/* Demux Gain 0 Config */
-	uint32_t  ch0EvenGain:10;
-	uint32_t  /* reserved */ : 6;
-	uint32_t  ch0OddGain:10;
-	uint32_t  /* reserved */ : 6;
-	/* Demux Gain 1 Config */
-	uint32_t  ch1Gain:10;
-	uint32_t  /* reserved */ : 6;
-	uint32_t  ch2Gain:10;
-	uint32_t  /* reserved */ : 6;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_bps_info {
-  uint32_t greenBadPixelCount:8;
-  uint32_t /* reserved */ : 8;
-  uint32_t RedBlueBadPixelCount:8;
-  uint32_t /* reserved */ : 8;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_demosaic_cfg {
-	/* Demosaic Config */
-	uint32_t abfEnable:1;
-	uint32_t badPixelCorrEnable:1;
-	uint32_t forceAbfOn:1;
-	uint32_t /* reserved */ : 1;
-	uint32_t abfShift:4;
-	uint32_t fminThreshold:7;
-	uint32_t /* reserved */ : 1;
-	uint32_t fmaxThreshold:7;
-	uint32_t /* reserved */ : 5;
-	uint32_t slopeShift:3;
-	uint32_t /* reserved */ : 1;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_demosaic_bpc_cfg {
-	/* Demosaic BPC Config 0 */
-	uint32_t blueDiffThreshold:12;
-	uint32_t redDiffThreshold:12;
-	uint32_t /* reserved */ : 8;
-	/* Demosaic BPC Config 1 */
-	uint32_t greenDiffThreshold:12;
-	uint32_t /* reserved */ : 20;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_demosaic_abf_cfg {
-	/* Demosaic ABF Config 0 */
-	uint32_t lpThreshold:10;
-	uint32_t /* reserved */ : 22;
-	/* Demosaic ABF Config 1 */
-	uint32_t ratio:4;
-	uint32_t minValue:10;
-	uint32_t /* reserved */ : 2;
-	uint32_t maxValue:10;
-	uint32_t /* reserved */ : 6;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_color_correction_cfg {
-	/* Color Corr. Coefficient 0 Config */
-	uint32_t   c0:12;
-	uint32_t   /* reserved */ : 20;
-	/* Color Corr. Coefficient 1 Config */
-	uint32_t   c1:12;
-	uint32_t   /* reserved */ : 20;
-	/* Color Corr. Coefficient 2 Config */
-	uint32_t   c2:12;
-	uint32_t   /* reserved */ : 20;
-	/* Color Corr. Coefficient 3 Config */
-	uint32_t   c3:12;
-	uint32_t   /* reserved */ : 20;
-	/* Color Corr. Coefficient 4 Config */
-	uint32_t   c4:12;
-	uint32_t   /* reserved */ : 20;
-	/* Color Corr. Coefficient 5 Config */
-	uint32_t   c5:12;
-	uint32_t   /* reserved */ : 20;
-	/* Color Corr. Coefficient 6 Config */
-	uint32_t   c6:12;
-	uint32_t   /* reserved */ : 20;
-	/* Color Corr. Coefficient 7 Config */
-	uint32_t   c7:12;
-	uint32_t   /* reserved */ : 20;
-	/* Color Corr. Coefficient 8 Config */
-	uint32_t   c8:12;
-	uint32_t   /* reserved */ : 20;
-	/* Color Corr. Offset 0 Config */
-	uint32_t   k0:11;
-	uint32_t   /* reserved */ : 21;
-	/* Color Corr. Offset 1 Config */
-	uint32_t   k1:11;
-	uint32_t   /* reserved */ : 21;
-	/* Color Corr. Offset 2 Config */
-	uint32_t   k2:11;
-	uint32_t   /* reserved */ : 21;
-	/* Color Corr. Coefficient Q Config */
-	uint32_t   coefQFactor:2;
-	uint32_t   /* reserved */ : 30;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_LumaAdaptation_ConfigCmdType {
-	/* LA Config */
-	uint32_t   lutBankSelect:1;
-	uint32_t   /* reserved */ : 31;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_wb_cfg {
-	/* WB Config */
-	uint32_t ch0Gain:9;
-	uint32_t ch1Gain:9;
-	uint32_t ch2Gain:9;
-	uint32_t /* reserved */ : 5;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_GammaLutSelect_ConfigCmdType {
-	/* LUT Bank Select Config */
-	uint32_t   ch0BankSelect:1;
-	uint32_t   ch1BankSelect:1;
-	uint32_t   ch2BankSelect:1;
-	uint32_t   /* reserved */ : 29;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_chroma_enhance_cfg {
-	/* Chroma Enhance A Config */
-	uint32_t ap:11;
-	uint32_t /* reserved */ : 5;
-	uint32_t am:11;
-	uint32_t /* reserved */ : 5;
-	/* Chroma Enhance B Config */
-	uint32_t bp:11;
-	uint32_t /* reserved */ : 5;
-	uint32_t bm:11;
-	uint32_t /* reserved */ : 5;
-	/* Chroma Enhance C Config */
-	uint32_t cp:11;
-	uint32_t /* reserved */ : 5;
-	uint32_t cm:11;
-	uint32_t /* reserved */ : 5;
-	/* Chroma Enhance D Config */
-	uint32_t dp:11;
-	uint32_t /* reserved */ : 5;
-	uint32_t dm:11;
-	uint32_t /* reserved */ : 5;
-	/* Chroma Enhance K Config */
-	uint32_t kcb:11;
-	uint32_t /* reserved */ : 5;
-	uint32_t kcr:11;
-	uint32_t /* reserved */ : 5;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_color_convert_cfg {
-	/* Conversion Coefficient 0 */
-	uint32_t v0:12;
-	uint32_t /* reserved */ : 20;
-	/* Conversion Coefficient 1 */
-	uint32_t v1:12;
-	uint32_t /* reserved */ : 20;
-	/* Conversion Coefficient 2 */
-	uint32_t v2:12;
-	uint32_t /* reserved */ : 20;
-	/* Conversion Offset */
-	uint32_t ConvertOffset:8;
-	uint32_t /* reserved */ : 24;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_SyncTimer_ConfigCmdType {
-	/* Timer Line Start Config */
-	uint32_t       timerLineStart:12;
-	uint32_t       /* reserved */ : 20;
-	/* Timer Pixel Start Config */
-	uint32_t       timerPixelStart:18;
-	uint32_t       /* reserved */ : 14;
-	/* Timer Pixel Duration Config */
-	uint32_t       timerPixelDuration:28;
-	uint32_t       /* reserved */ : 4;
-	/* Sync Timer Polarity Config */
-	uint32_t       timer0Polarity:1;
-	uint32_t       timer1Polarity:1;
-	uint32_t       timer2Polarity:1;
-	uint32_t       /* reserved */ : 29;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_AsyncTimer_ConfigCmdType {
-	/* Async Timer Config 0 */
-	uint32_t     inactiveLength:20;
-	uint32_t     numRepetition:10;
-	uint32_t     /* reserved */ : 1;
-	uint32_t     polarity:1;
-	/* Async Timer Config 1 */
-	uint32_t     activeLength:20;
-	uint32_t     /* reserved */ : 12;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_AWBAEStatistics_ConfigCmdType {
-	/* AWB autoexposure Config */
-	uint32_t    aeRegionConfig:1;
-	uint32_t    aeSubregionConfig:1;
-	uint32_t    /* reserved */ : 14;
-	uint32_t    awbYMin:8;
-	uint32_t    awbYMax:8;
-	/* AXW Header */
-	uint32_t    axwHeader:8;
-	uint32_t    /* reserved */ : 24;
-	/* AWB Mconfig */
-	uint32_t    m4:8;
-	uint32_t    m3:8;
-	uint32_t    m2:8;
-	uint32_t    m1:8;
-	/* AWB Cconfig */
-	uint32_t    c2:12;
-	uint32_t    /* reserved */ : 4;
-	uint32_t    c1:12;
-	uint32_t    /* reserved */ : 4;
-	/* AWB Cconfig 2 */
-	uint32_t    c4:12;
-	uint32_t    /* reserved */ : 4;
-	uint32_t    c3:12;
-	uint32_t    /* reserved */ : 4;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_TestGen_ConfigCmdType {
-	/* HW Test Gen Config */
-	uint32_t   numFrame:10;
-	uint32_t   /* reserved */ : 2;
-	uint32_t   pixelDataSelect:1;
-	uint32_t   systematicDataSelect:1;
-	uint32_t   /* reserved */ : 2;
-	uint32_t   pixelDataSize:2;
-	uint32_t   hsyncEdge:1;
-	uint32_t   vsyncEdge:1;
-	uint32_t   /* reserved */ : 12;
-	/* HW Test Gen Image Config */
-	uint32_t   imageWidth:14;
-	uint32_t   /* reserved */ : 2;
-	uint32_t   imageHeight:14;
-	uint32_t   /* reserved */ : 2;
-	/* SOF Offset Config */
-	uint32_t   sofOffset:24;
-	uint32_t   /* reserved */ : 8;
-	/* EOF NOffset Config */
-	uint32_t   eofNOffset:24;
-	uint32_t   /* reserved */ : 8;
-	/* SOL Offset Config */
-	uint32_t   solOffset:9;
-	uint32_t   /* reserved */ : 23;
-	/* EOL NOffset Config */
-	uint32_t   eolNOffset:9;
-	uint32_t   /* reserved */ : 23;
-	/* HBI Config */
-	uint32_t   hBlankInterval:14;
-	uint32_t   /* reserved */ : 18;
-	/* VBL Config */
-	uint32_t   vBlankInterval:14;
-	uint32_t   /* reserved */ : 2;
-	uint32_t   vBlankIntervalEnable:1;
-	uint32_t   /* reserved */ : 15;
-	/* SOF Dummy Line Config */
-	uint32_t   sofDummy:8;
-	uint32_t   /* reserved */ : 24;
-	/* EOF Dummy Line Config */
-	uint32_t   eofDummy:8;
-	uint32_t   /* reserved */ : 24;
-	/* Color Bars Config */
-	uint32_t   unicolorBarSelect:3;
-	uint32_t   /* reserved */ : 1;
-	uint32_t   unicolorBarEnable:1;
-	uint32_t   splitEnable:1;
-	uint32_t   pixelPattern:2;
-	uint32_t   rotatePeriod:6;
-	uint32_t   /* reserved */ : 18;
-	/* Random Config */
-	uint32_t   randomSeed:16;
-	uint32_t   /* reserved */ : 16;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_Bus_Pm_ConfigCmdType {
-	/* VFE Bus Performance Monitor Config */
-	uint32_t  output2YWrPmEnable:1;
-	uint32_t  output2CbcrWrPmEnable:1;
-	uint32_t  output1YWrPmEnable:1;
-	uint32_t  output1CbcrWrPmEnable:1;
-	uint32_t  /* reserved */ : 28;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_asf_info {
-	/* asf max edge  */
-	uint32_t maxEdge:13;
-	uint32_t /* reserved */ : 3;
-	/* HBi count  */
-	uint32_t HBICount:12;
-	uint32_t /* reserved */ : 4;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_camif_stats {
-  uint32_t  pixelCount:14;
-  uint32_t  /* reserved */ : 2;
-  uint32_t  lineCount:14;
-  uint32_t  /* reserved */ : 1;
-  uint32_t  camifHalt:1;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_StatsCmdType {
-	uint32_t  autoFocusEnable:1;
-	uint32_t  axwEnable:1;
-	uint32_t  histEnable:1;
-	uint32_t  clearHistEnable:1;
-	uint32_t  histAutoClearEnable:1;
-	uint32_t  colorConversionEnable:1;
-	uint32_t  /* reserved */ : 26;
-} __attribute__((packed, aligned(4)));
-
-
-struct vfe_statsframe {
-	uint32_t lastPixel:12;
-	uint32_t /* reserved */ : 4;
-	uint32_t lastLine:12;
-	uint32_t /* reserved */ : 4;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_busstats_wrprio {
-	uint32_t afBusPriority:4;
-	uint32_t awbBusPriority:4;
-	uint32_t histBusPriority:4;
-	uint32_t afBusPriorityEn:1;
-	uint32_t awbBusPriorityEn:1;
-	uint32_t histBusPriorityEn:1;
-	uint32_t /* reserved */ : 17;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_statsaf_update {
-	/* VFE_STATS_AF_CFG */
-	uint32_t windowVOffset:12;
-	uint32_t /* reserved */ : 4;
-	uint32_t windowHOffset:12;
-	uint32_t /* reserved */ : 3;
-	uint32_t windowMode:1;
-
-	/* VFE_STATS_AF_DIM */
-	uint32_t windowHeight:12;
-	uint32_t /* reserved */ : 4;
-	uint32_t windowWidth:12;
-	uint32_t /* reserved */ : 4;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_statsaf_cfg {
-	/* VFE_STATS_AF_GRID_0 */
-	uint32_t  entry00:8;
-	uint32_t  entry01:8;
-	uint32_t  entry02:8;
-	uint32_t  entry03:8;
-
-	/* VFE_STATS_AF_GRID_1 */
-	uint32_t  entry10:8;
-	uint32_t  entry11:8;
-	uint32_t  entry12:8;
-	uint32_t  entry13:8;
-
-	/* VFE_STATS_AF_GRID_2 */
-	uint32_t  entry20:8;
-	uint32_t  entry21:8;
-	uint32_t  entry22:8;
-	uint32_t  entry23:8;
-
-	/* VFE_STATS_AF_GRID_3 */
-	uint32_t  entry30:8;
-	uint32_t  entry31:8;
-	uint32_t  entry32:8;
-	uint32_t  entry33:8;
-
-	/* VFE_STATS_AF_HEADER */
-	uint32_t  afHeader:8;
-	uint32_t  /* reserved */ : 24;
-	/*  VFE_STATS_AF_COEF0 */
-	uint32_t  a00:5;
-	uint32_t  a04:5;
-	uint32_t  fvMax:11;
-	uint32_t  fvMetric:1;
-	uint32_t  /* reserved */ : 10;
-
-	/* VFE_STATS_AF_COEF1 */
-	uint32_t  a20:5;
-	uint32_t  a21:5;
-	uint32_t  a22:5;
-	uint32_t  a23:5;
-	uint32_t  a24:5;
-	uint32_t  /* reserved */ : 7;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_statsawbae_update {
-	uint32_t  aeRegionCfg:1;
-	uint32_t  aeSubregionCfg:1;
-	uint32_t  /* reserved */ : 14;
-	uint32_t  awbYMin:8;
-	uint32_t  awbYMax:8;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_statsaxw_hdr_cfg {
-	/* Stats AXW Header Config */
-	uint32_t axwHeader:8;
-	uint32_t /* reserved */ : 24;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_statsawb_update {
-	/* AWB MConfig */
-	uint32_t  m4:8;
-	uint32_t  m3:8;
-	uint32_t  m2:8;
-	uint32_t  m1:8;
-
-	/* AWB CConfig1 */
-	uint32_t  c2:12;
-	uint32_t  /* reserved */ : 4;
-	uint32_t  c1:12;
-	uint32_t  /* reserved */ : 4;
-
-	/* AWB CConfig2 */
-	uint32_t  c4:12;
-	uint32_t  /* reserved */ : 4;
-	uint32_t  c3:12;
-	uint32_t  /* reserved */ : 4;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_SyncTimerCmdType {
-	uint32_t  hsyncCount:12;
-	uint32_t  /* reserved */ : 20;
-	uint32_t  pclkCount:18;
-	uint32_t  /* reserved */ : 14;
-	uint32_t  outputDuration:28;
-	uint32_t  /* reserved */ : 4;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_AsyncTimerCmdType {
-	/*  config 0 */
-	uint32_t    inactiveCount:20;
-	uint32_t    repeatCount:10;
-	uint32_t    /* reserved */ : 1;
-	uint32_t    polarity:1;
-	/*  config 1 */
-	uint32_t    activeCount:20;
-	uint32_t    /* reserved */ : 12;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_AxiInputCmdType {
-	uint32_t   stripeStartAddr0:32;
-	uint32_t   stripeStartAddr1:32;
-	uint32_t   stripeStartAddr2:32;
-	uint32_t   stripeStartAddr3:32;
-
-	uint32_t   ySize:12;
-	uint32_t   yOffsetDelta:12;
-	uint32_t   /* reserved */ : 8;
-
-	/* bus_stripe_rd_hSize */
-	uint32_t   /* reserved */ : 16;
-	uint32_t   xSizeWord:10;
-	uint32_t   /* reserved */ : 6;
-
-	/* bus_stripe_rd_buffer_cfg */
-	uint32_t   burstLength:2;
-	uint32_t   /* reserved */ : 2;
-	uint32_t   NumOfRows:12;
-	uint32_t   RowIncrement:12;
-	uint32_t   /* reserved */ : 4;
-
-	/* bus_stripe_rd_unpack_cfg */
-	uint32_t   mainUnpackHeight:12;
-	uint32_t   mainUnpackWidth:13;
-	uint32_t   mainUnpackHbiSel:3;
-	uint32_t   mainUnpackPhase:3;
-	uint32_t   /* reserved */ : 1;
-
-	/* bus_stripe_rd_unpack */
-	uint32_t   unpackPattern:32;
-
-	/* bus_stripe_rd_pad_size */
-	uint32_t   padLeft:7;
-	uint32_t   /* reserved */ : 1;
-	uint32_t   padRight:7;
-	uint32_t   /* reserved */ : 1;
-	uint32_t   padTop:7;
-	uint32_t   /* reserved */ : 1;
-	uint32_t   padBottom:7;
-	uint32_t   /* reserved */ : 1;
-
-	/* bus_stripe_rd_pad_L_unpack */
-	uint32_t   leftUnpackPattern0:4;
-	uint32_t   leftUnpackPattern1:4;
-	uint32_t   leftUnpackPattern2:4;
-	uint32_t   leftUnpackPattern3:4;
-	uint32_t   leftUnpackStop0:1;
-	uint32_t   leftUnpackStop1:1;
-	uint32_t   leftUnpackStop2:1;
-	uint32_t   leftUnpackStop3:1;
-	uint32_t   /* reserved */ : 12;
-
-	/* bus_stripe_rd_pad_R_unpack */
-	uint32_t   rightUnpackPattern0:4;
-	uint32_t   rightUnpackPattern1:4;
-	uint32_t   rightUnpackPattern2:4;
-	uint32_t   rightUnpackPattern3:4;
-	uint32_t   rightUnpackStop0:1;
-	uint32_t   rightUnpackStop1:1;
-	uint32_t   rightUnpackStop2:1;
-	uint32_t   rightUnpackStop3:1;
-	uint32_t   /* reserved */ : 12;
-
-	/* bus_stripe_rd_pad_tb_unpack */
-	uint32_t   topUnapckPattern:4;
-	uint32_t   /* reserved */ : 12;
-	uint32_t   bottomUnapckPattern:4;
-	uint32_t   /* reserved */ : 12;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_AxiRdFragIrqEnable {
-	uint32_t stripeRdFragirq0Enable:1;
-	uint32_t stripeRdFragirq1Enable:1;
-	uint32_t stripeRdFragirq2Enable:1;
-	uint32_t stripeRdFragirq3Enable:1;
-	uint32_t   /* reserved */ : 28;
-} __attribute__((packed, aligned(4)));
-
-int vfe_cmd_init(struct msm_vfe_callback *, struct platform_device *, void *);
-void vfe_stats_af_stop(void);
-void vfe_stop(void);
-void vfe_update(void);
-int vfe_rgb_gamma_update(struct vfe_cmd_rgb_gamma_config *);
-int vfe_rgb_gamma_config(struct vfe_cmd_rgb_gamma_config *);
-void vfe_stats_wb_exp_ack(struct vfe_cmd_stats_wb_exp_ack *);
-void vfe_stats_af_ack(struct vfe_cmd_stats_af_ack *);
-void vfe_start(struct vfe_cmd_start *);
-void vfe_la_update(struct vfe_cmd_la_config *);
-void vfe_la_config(struct vfe_cmd_la_config *);
-void vfe_test_gen_start(struct vfe_cmd_test_gen_start *);
-void vfe_frame_skip_update(struct vfe_cmd_frame_skip_update *);
-void vfe_frame_skip_config(struct vfe_cmd_frame_skip_config *);
-void vfe_output_clamp_config(struct vfe_cmd_output_clamp_config *);
-void vfe_camif_frame_update(struct vfe_cmds_camif_frame *);
-void vfe_color_correction_config(struct vfe_cmd_color_correction_config *);
-void vfe_demosaic_abf_update(struct vfe_cmd_demosaic_abf_update *);
-void vfe_demosaic_bpc_update(struct vfe_cmd_demosaic_bpc_update *);
-void vfe_demosaic_config(struct vfe_cmd_demosaic_config *);
-void vfe_demux_channel_gain_update(struct vfe_cmd_demux_channel_gain_config *);
-void vfe_demux_channel_gain_config(struct vfe_cmd_demux_channel_gain_config *);
-void vfe_black_level_update(struct vfe_cmd_black_level_config *);
-void vfe_black_level_config(struct vfe_cmd_black_level_config *);
-void vfe_asf_update(struct vfe_cmd_asf_update *);
-void vfe_asf_config(struct vfe_cmd_asf_config *);
-void vfe_white_balance_config(struct vfe_cmd_white_balance_config *);
-void vfe_chroma_sup_config(struct vfe_cmd_chroma_suppression_config *);
-void vfe_roll_off_config(struct vfe_cmd_roll_off_config *);
-void vfe_chroma_subsample_config(struct vfe_cmd_chroma_subsample_config *);
-void vfe_chroma_enhan_config(struct vfe_cmd_chroma_enhan_config *);
-void vfe_scaler2cbcr_config(struct vfe_cmd_scaler2_config *);
-void vfe_scaler2y_config(struct vfe_cmd_scaler2_config *);
-void vfe_main_scaler_config(struct vfe_cmd_main_scaler_config *);
-void vfe_stats_wb_exp_stop(void);
-void vfe_stats_update_wb_exp(struct vfe_cmd_stats_wb_exp_update *);
-void vfe_stats_update_af(struct vfe_cmd_stats_af_update *);
-void vfe_stats_start_wb_exp(struct vfe_cmd_stats_wb_exp_start *);
-void vfe_stats_start_af(struct vfe_cmd_stats_af_start *);
-void vfe_stats_setting(struct vfe_cmd_stats_setting *);
-void vfe_axi_input_config(struct vfe_cmd_axi_input_config *);
-void vfe_axi_output_config(struct vfe_cmd_axi_output_config *);
-void vfe_camif_config(struct vfe_cmd_camif_config *);
-void vfe_fov_crop_config(struct vfe_cmd_fov_crop_config *);
-void vfe_get_hw_version(struct vfe_cmd_hw_version *);
-void vfe_reset(void);
-void vfe_cmd_release(struct platform_device *);
-void vfe_output_p_ack(struct vfe_cmd_output_ack *);
-void vfe_output_v_ack(struct vfe_cmd_output_ack *);
-#endif /* __MSM_VFE8X_REG_H__ */
diff --git a/drivers/media/video/msm/vfe/msm_vfe_stats_buf.c b/drivers/media/video/msm/vfe/msm_vfe_stats_buf.c
deleted file mode 100644
index 36f8b11..0000000
--- a/drivers/media/video/msm/vfe/msm_vfe_stats_buf.c
+++ /dev/null
@@ -1,513 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/workqueue.h>
-#include <linux/delay.h>
-#include <linux/types.h>
-#include <linux/list.h>
-#include <linux/ioctl.h>
-#include <linux/spinlock.h>
-#include <linux/videodev2.h>
-#include <linux/proc_fs.h>
-#include <linux/vmalloc.h>
-
-#include <media/v4l2-dev.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-device.h>
-
-#include <linux/android_pmem.h>
-#include <media/msm_camera.h>
-#include <media/msm_isp.h>
-#include "msm.h"
-#include "msm_vfe_stats_buf.h"
-
-#ifdef CONFIG_MSM_CAMERA_DEBUG
-	#define D(fmt, args...) pr_debug("msm_stats: " fmt, ##args)
-#else
-	#define D(fmt, args...) do {} while (0)
-#endif
-
-static int msm_stats_init(struct msm_stats_bufq_ctrl *stats_ctrl)
-{
-	int rc = 0;
-	/* cannot get spinlock here */
-	if (stats_ctrl->init_done > 0) {
-		pr_err("%s: already initialized stats ctrl. no op", __func__);
-		return 0;
-	}
-	memset(stats_ctrl,  0,  sizeof(struct msm_stats_bufq_ctrl));
-	spin_lock_init(&stats_ctrl->lock);
-	stats_ctrl->init_done = 1;
-	return rc;
-}
-
-static int msm_stats_reqbuf(struct msm_stats_bufq_ctrl *stats_ctrl,
-	struct msm_stats_reqbuf *reqbuf,
-	struct ion_client *client)
-{
-	int rc = 0;
-	struct msm_stats_bufq *bufq;
-	struct msm_stats_meta_buf *bufs;
-	int idx = reqbuf->stats_type;
-	int i;
-
-	D("%s: type : %d, buf num : %d\n", __func__,
-		reqbuf->stats_type, reqbuf->num_buf);
-	if (reqbuf->num_buf > 0) {
-		if (stats_ctrl->bufq[idx]) {
-			/* already in use. Error */
-			pr_err("%s: stats type %d aleady requested",
-				 __func__, reqbuf->stats_type);
-			rc = -EEXIST;
-			goto end;
-		} else {
-			/* good case */
-			bufq = (struct msm_stats_bufq *)
-				kzalloc(
-					sizeof(struct msm_stats_bufq),
-					GFP_KERNEL);
-			if (!bufq) {
-				/* no memory */
-				rc = -ENOMEM;
-				pr_err("%s: no mem for stats type %d",
-					__func__, reqbuf->stats_type);
-				goto end;
-			}
-			bufs = (struct msm_stats_meta_buf *)
-				kzalloc((reqbuf->num_buf *
-					sizeof(struct msm_stats_meta_buf)),
-					GFP_KERNEL);
-			if (!bufs) {
-				/* no memory */
-				rc = -ENOMEM;
-				pr_err("%s: no mem for stats buf, stats type = %d",
-					__func__, reqbuf->stats_type);
-				kfree(bufq);
-				goto end;
-			}
-			/* init bufq list head */
-			INIT_LIST_HEAD(&bufq->head);
-			/* set the meta buf state to initialized */
-			bufq->num_bufs = reqbuf->num_buf;
-			for (i = 0; i < reqbuf->num_buf; i++)
-				bufs[i].state =
-					MSM_STATS_BUFFER_STATE_INITIALIZED;
-			bufq->bufs = bufs;
-			bufq->num_bufs = reqbuf->num_buf;
-			bufq->type = reqbuf->stats_type;
-			stats_ctrl->bufq[idx] = bufq;
-			/* done reqbuf (larger than zero case) */
-			goto end;
-		}
-	} else if (reqbuf->num_buf == 0) {
-		if (stats_ctrl->bufq[idx] == NULL) {
-			/* double free case? */
-			pr_err("%s: stats type %d aleady freed",
-				 __func__, reqbuf->stats_type);
-			rc = -ENXIO;
-			goto end;
-		} else {
-			/* good case. need to de-reqbuf */
-			kfree(stats_ctrl->bufq[idx]->bufs);
-			kfree(stats_ctrl->bufq[idx]);
-			stats_ctrl->bufq[idx] = NULL;
-			goto end;
-		}
-	} else {
-		/* error case */
-		pr_err("%s: stats type = %d, req_num_buf = %d, error",
-			   __func__, reqbuf->stats_type, reqbuf->num_buf);
-		rc = -EPERM;
-		goto end;
-	}
-end:
-	return rc;
-}
-static int msm_stats_deinit(struct msm_stats_bufq_ctrl *stats_ctrl)
-{
-	int rc = 0;
-	int i;
-
-	if (stats_ctrl->init_done == 0) {
-		pr_err("%s: not inited yet. no op", __func__);
-		return 0;
-	}
-	/* safe guard in case deallocate memory not done yet. */
-	for (i = 0; i < MSM_STATS_TYPE_MAX; i++) {
-		if (stats_ctrl->bufq[i]) {
-			if (stats_ctrl->bufq[i]->bufs) {
-				rc = -1;
-				pr_err("%s: stats type = %d, buf not freed yet",
-					 __func__, i);
-				BUG_ON(stats_ctrl->bufq[i]->bufs);
-			} else {
-				rc = -1;
-				pr_err("%s: stats type = %d, bufq not freed yet",
-					__func__, i);
-				BUG_ON(stats_ctrl->bufq[i]);
-			}
-		}
-	}
-	memset(stats_ctrl,  0,  sizeof(struct msm_stats_bufq_ctrl));
-	return rc;
-}
-
-#ifdef CONFIG_ANDROID_PMEM
-static int msm_stats_check_pmem_info(struct msm_stats_buf_info *info, int len)
-{
-	if (info->offset < len &&
-		info->offset + info->len <= len &&
-		info->planar0_off < len && info->planar1_off < len)
-		return 0;
-
-	pr_err("%s: check failed: off %d len %d y %d cbcr %d (total len %d)\n",
-		   __func__,
-		   info->offset,
-		   info->len,
-		   info->planar0_off,
-		   info->planar1_off,
-		   len);
-	return -EINVAL;
-}
-#endif
-
-static int msm_stats_buf_prepare(struct msm_stats_bufq_ctrl *stats_ctrl,
-	struct msm_stats_buf_info *info, struct ion_client *client,
-	int domain_num)
-{
-	unsigned long paddr;
-#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
-	unsigned long kvstart;
-	struct file *file;
-#endif
-	int rc = 0;
-	unsigned long len;
-	struct msm_stats_bufq *bufq = NULL;
-	struct msm_stats_meta_buf *stats_buf = NULL;
-
-	D("%s: type : %d, buf num : %d\n", __func__,
-		info->type, info->buf_idx);
-
-	bufq = stats_ctrl->bufq[info->type];
-	stats_buf = &bufq->bufs[info->buf_idx];
-	if (stats_buf->state == MSM_STATS_BUFFER_STATE_UNUSED) {
-		pr_err("%s: need reqbuf first, stats type = %d",
-			__func__, info->type);
-		rc = -1;
-		goto out1;
-	}
-	if (stats_buf->state != MSM_STATS_BUFFER_STATE_INITIALIZED) {
-		D("%s: stats already mapped, no op, stats type = %d",
-			__func__, info->type);
-		goto out1;
-	}
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	stats_buf->handle = ion_import_dma_buf(client, info->fd);
-	if (IS_ERR_OR_NULL(stats_buf->handle)) {
-		rc = -EINVAL;
-		pr_err("%s: stats_buf has null/error ION handle %p",
-			   __func__, stats_buf->handle);
-		goto out1;
-	}
-	if (ion_map_iommu(client, stats_buf->handle,
-			domain_num, 0, SZ_4K,
-			0, &paddr, &len, 0, 0) < 0) {
-		rc = -EINVAL;
-		pr_err("%s: cannot map address", __func__);
-		goto out2;
-	}
-#elif CONFIG_ANDROID_PMEM
-	rc = get_pmem_file(info->fd, &paddr, &kvstart, &len, &file);
-	if (rc < 0) {
-		pr_err("%s: get_pmem_file fd %d error %d\n",
-			   __func__, info->fd, rc);
-		goto out1;
-	}
-	stats_buf->file = file;
-#else
-	paddr = 0;
-	file = NULL;
-	kvstart = 0;
-#endif
-	if (!info->len)
-		info->len = len;
-	rc = msm_stats_check_pmem_info(info, len);
-	if (rc < 0) {
-		pr_err("%s: msm_stats_check_pmem_info err = %d", __func__, rc);
-		goto out3;
-	}
-	paddr += info->offset;
-	len = info->len;
-	stats_buf->paddr = paddr;
-	stats_buf->len = len;
-	memcpy(&stats_buf->info, info, sizeof(stats_buf->info));
-	D("%s Adding buf to list with type %d\n", __func__,
-	  stats_buf->info.type);
-	D("%s pmem_stats address is 0x%ld\n", __func__, paddr);
-	stats_buf->state = MSM_STATS_BUFFER_STATE_PREPARED;
-	return 0;
-out3:
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	ion_unmap_iommu(client, stats_buf->handle, domain_num, 0);
-#endif
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-out2:
-	ion_free(client, stats_buf->handle);
-#elif CONFIG_ANDROID_PMEM
-	put_pmem_file(stats_buf->file);
-#endif
-out1:
-	return rc;
-}
-static int msm_stats_buf_unprepare(struct msm_stats_bufq_ctrl *stats_ctrl,
-	enum msm_stats_enum_type stats_type, int buf_idx,
-	struct ion_client *client, int domain_num)
-{
-	int rc = 0;
-	struct msm_stats_bufq *bufq = NULL;
-	struct msm_stats_meta_buf *stats_buf = NULL;
-
-	D("%s: type : %d, idx : %d\n", __func__, stats_type, buf_idx);
-	bufq = stats_ctrl->bufq[stats_type];
-	stats_buf = &bufq->bufs[buf_idx];
-	if (stats_buf->state == MSM_STATS_BUFFER_STATE_UNUSED) {
-		pr_err("%s: need reqbuf first, stats type = %d",
-			__func__, stats_type);
-		rc = -1;
-		goto end;
-	}
-	if (stats_buf->state == MSM_STATS_BUFFER_STATE_INITIALIZED) {
-		D("%s: stats already mapped, no op, stats type = %d",
-			__func__, stats_type);
-		goto end;
-	}
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	ion_unmap_iommu(client, stats_buf->handle,
-					domain_num, 0);
-	ion_free(client, stats_buf->handle);
-#else
-	put_pmem_file(stats_buf->file);
-#endif
-	if (stats_buf->state == MSM_STATS_BUFFER_STATE_QUEUED) {
-		/* buf queued need delete from list */
-		D("%s: delete stats buf, type = %d, idx = %d",
-		  __func__,  stats_type,  buf_idx);
-		list_del_init(&stats_buf->list);
-	}
-end:
-	return rc;
-}
-
-static int msm_stats_bufq_flush(struct msm_stats_bufq_ctrl *stats_ctrl,
-	enum msm_stats_enum_type stats_type, struct ion_client *client)
-{
-	int rc = 0;
-	int i;
-	struct msm_stats_bufq *bufq = NULL;
-	struct msm_stats_meta_buf *stats_buf = NULL;
-
-	D("%s: type : %d\n", __func__, stats_type);
-	bufq = stats_ctrl->bufq[stats_type];
-
-	for (i = 0; i < bufq->num_bufs; i++) {
-		stats_buf = &bufq->bufs[i];
-		switch (stats_buf->state) {
-		case MSM_STATS_BUFFER_STATE_QUEUED:
-			/* buf queued in stats free queue */
-			stats_buf->state = MSM_STATS_BUFFER_STATE_PREPARED;
-			list_del_init(&stats_buf->list);
-			break;
-		case MSM_STATS_BUFFER_STATE_DEQUEUED:
-			/* if stats buf in VFE reset the state */
-			stats_buf->state = MSM_STATS_BUFFER_STATE_PREPARED;
-			break;
-		case MSM_STATS_BUFFER_STATE_DISPATCHED:
-			/* if stats buf in userspace reset the state */
-			stats_buf->state = MSM_STATS_BUFFER_STATE_PREPARED;
-			break;
-		default:
-			break;
-		}
-	}
-	return rc;
-}
-
-static int msm_stats_dqbuf(struct msm_stats_bufq_ctrl *stats_ctrl,
-	enum msm_stats_enum_type stats_type,
-	struct msm_stats_meta_buf **pp_stats_buf)
-{
-	int rc = 0;
-	struct msm_stats_bufq *bufq = NULL;
-	struct msm_stats_meta_buf *stats_buf = NULL;
-
-	D("%s: type : %d\n", __func__, stats_type);
-	*pp_stats_buf = NULL;
-	bufq = stats_ctrl->bufq[stats_type];
-
-	list_for_each_entry(stats_buf, &bufq->head, list) {
-		if (stats_buf->state == MSM_STATS_BUFFER_STATE_QUEUED) {
-			/* found one buf */
-			list_del_init(&stats_buf->list);
-			*pp_stats_buf = stats_buf;
-			break;
-		}
-	}
-	if (!(*pp_stats_buf)) {
-		D("%s: no free stats buf, type = %d",
-			__func__, stats_type);
-		rc = -1;
-		return rc;
-	}
-	stats_buf->state = MSM_STATS_BUFFER_STATE_DEQUEUED;
-	return rc;
-}
-
-
-static int msm_stats_querybuf(struct msm_stats_bufq_ctrl *stats_ctrl,
-	struct msm_stats_buf_info *info,
-	struct msm_stats_meta_buf **pp_stats_buf)
-{
-	int rc = 0;
-	struct msm_stats_bufq *bufq = NULL;
-
-	*pp_stats_buf = NULL;
-	D("%s: stats type : %d, buf_idx : %d", __func__, info->type,
-		   info->buf_idx);
-	bufq = stats_ctrl->bufq[info->type];
-	*pp_stats_buf = &bufq->bufs[info->buf_idx];
-
-	return rc;
-}
-
-static int msm_stats_qbuf(struct msm_stats_bufq_ctrl *stats_ctrl,
-	enum msm_stats_enum_type stats_type,
-	int buf_idx)
-{
-	int rc = 0;
-	struct msm_stats_bufq *bufq = NULL;
-	struct msm_stats_meta_buf *stats_buf = NULL;
-	D("%s: stats type : %d, buf_idx : %d", __func__, stats_type,
-		   buf_idx);
-
-	bufq = stats_ctrl->bufq[stats_type];
-	if (!bufq) {
-		pr_err("%s: null bufq, stats type = %d", __func__, stats_type);
-		rc = -1;
-		goto end;
-	}
-	if (buf_idx >= bufq->num_bufs) {
-		pr_err("%s: stats type = %d, its idx %d larger than buf count %d",
-			   __func__, stats_type, buf_idx, bufq->num_bufs);
-		rc = -1;
-		goto end;
-	}
-	stats_buf = &bufq->bufs[buf_idx];
-	switch (stats_buf->state) {
-	case MSM_STATS_BUFFER_STATE_PREPARED:
-	case MSM_STATS_BUFFER_STATE_DEQUEUED:
-	case MSM_STATS_BUFFER_STATE_DISPATCHED:
-		stats_buf->state = MSM_STATS_BUFFER_STATE_QUEUED;
-		list_add_tail(&stats_buf->list, &bufq->head);
-		break;
-	default:
-		pr_err("%s: incorrect state = %d, stats type = %d, cannot qbuf",
-			   __func__, stats_buf->state, stats_type);
-		rc = -1;
-		break;
-	}
-end:
-	return rc;
-}
-
-static int msm_stats_buf_dispatch(struct msm_stats_bufq_ctrl *stats_ctrl,
-	enum msm_stats_enum_type stats_type,
-	unsigned long phy_addr, int *buf_idx,
-	void **vaddr, int *fd,
-	struct ion_client *client)
-{
-	int rc = 0;
-	int i;
-	struct msm_stats_bufq *bufq = NULL;
-	struct msm_stats_meta_buf *stats_buf = NULL;
-	D("%s: stats type : %d\n", __func__, stats_type);
-
-	*buf_idx = -1;
-	*vaddr = NULL;
-	*fd = 0;
-	bufq = stats_ctrl->bufq[stats_type];
-	for (i = 0; i < bufq->num_bufs; i++) {
-		if (bufq->bufs[i].paddr == phy_addr) {
-			stats_buf = &bufq->bufs[i];
-			*buf_idx = i;
-			*vaddr = stats_buf->info.vaddr;
-			*fd = stats_buf->info.fd;
-			break;
-		}
-	}
-	if (!stats_buf) {
-		pr_err("%s: no match, phy_addr = 0x%ld, stats_type = %d",
-			   __func__, phy_addr, stats_type);
-		return -EFAULT;
-	}
-	switch (stats_buf->state) {
-	case MSM_STATS_BUFFER_STATE_DEQUEUED:
-		stats_buf->state = MSM_STATS_BUFFER_STATE_DISPATCHED;
-		break;
-	default:
-		pr_err("%s: type = %d, idx = %d, cur_state = %d,\n"
-			   "cannot set state to DISPATCHED\n",
-			   __func__, stats_type, *buf_idx, stats_buf->state);
-		rc = -EFAULT;
-		break;
-	}
-	return rc;
-}
-static int msm_stats_enqueue_buf(struct msm_stats_bufq_ctrl *stats_ctrl,
-	struct msm_stats_buf_info *info, struct ion_client *client,
-	int domain_num)
-{
-	int rc = 0;
-	D("%s: stats type : %d, idx : %d\n", __func__,
-		info->type, info->buf_idx);
-	rc = msm_stats_buf_prepare(stats_ctrl, info, client, domain_num);
-	if (rc < 0) {
-		pr_err("%s: buf_prepare failed, rc = %d", __func__, rc);
-		return -EINVAL;
-	}
-	rc = msm_stats_qbuf(stats_ctrl,   info->type, info->buf_idx);
-	if (rc < 0) {
-		pr_err("%s: msm_stats_qbuf failed, rc = %d", __func__, rc);
-		return -EINVAL;
-	}
-	return rc;
-}
-
-int msm_stats_buf_ops_init(struct msm_stats_bufq_ctrl *stats_ctrl,
-	struct ion_client *client, struct msm_stats_ops *ops)
-{
-	ops->stats_ctrl = stats_ctrl;
-	ops->client = client;
-	ops->enqueue_buf = msm_stats_enqueue_buf;
-	ops->qbuf = msm_stats_qbuf;
-	ops->dqbuf = msm_stats_dqbuf;
-	ops->bufq_flush = msm_stats_bufq_flush;
-	ops->buf_unprepare = msm_stats_buf_unprepare;
-	ops->buf_prepare = msm_stats_buf_prepare;
-	ops->reqbuf = msm_stats_reqbuf;
-	ops->querybuf = msm_stats_querybuf;
-	ops->dispatch = msm_stats_buf_dispatch;
-	ops->stats_ctrl_init = msm_stats_init;
-	ops->stats_ctrl_deinit = msm_stats_deinit;
-	return 0;
-}
-
diff --git a/drivers/media/video/msm/vfe/msm_vfe_stats_buf.h b/drivers/media/video/msm/vfe/msm_vfe_stats_buf.h
deleted file mode 100644
index bf3e70e..0000000
--- a/drivers/media/video/msm/vfe/msm_vfe_stats_buf.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 _MSM_STATS_BUF_H_
-#define _MSM_STATS_BUF_H_
-
-enum msm_stats_buffer_state {
-	MSM_STATS_BUFFER_STATE_UNUSED,	  /* not used */
-	MSM_STATS_BUFFER_STATE_INITIALIZED,	   /* REQBUF done */
-	MSM_STATS_BUFFER_STATE_PREPARED,	/* BUF mapped */
-	MSM_STATS_BUFFER_STATE_QUEUED,	  /* buf queued */
-	MSM_STATS_BUFFER_STATE_DEQUEUED,	/* in use in VFE */
-	MSM_STATS_BUFFER_STATE_DISPATCHED,	  /* sent to userspace */
-};
-
-struct msm_stats_meta_buf {
-	struct list_head list;
-	enum msm_stats_buffer_state state;
-	int type;
-	int fd;
-	uint32_t offset;
-	unsigned long paddr;
-	unsigned long len;
-	struct file *file;
-	struct msm_stats_buf_info info;
-	struct ion_handle *handle;
-};
-
-struct msm_stats_bufq {
-	struct list_head head;
-	int num_bufs;
-	int type;
-	struct msm_stats_meta_buf *bufs;
-};
-
-
-struct msm_stats_bufq_ctrl {
-	/* not use spin lock for now. Assume vfe holds spin lock */
-	spinlock_t lock;
-	int init_done;
-	struct msm_stats_bufq *bufq[MSM_STATS_TYPE_MAX];
-};
-
-struct msm_stats_ops {
-	struct msm_stats_bufq_ctrl *stats_ctrl;
-	struct ion_client *client;
-	int (*enqueue_buf) (struct msm_stats_bufq_ctrl *stats_ctrl,
-				struct msm_stats_buf_info *info,
-				struct ion_client *client, int domain_num);
-	int (*qbuf) (struct msm_stats_bufq_ctrl *stats_ctrl,
-				 enum msm_stats_enum_type stats_type,
-				 int buf_idx);
-	int (*dqbuf) (struct msm_stats_bufq_ctrl *stats_ctrl,
-				  enum msm_stats_enum_type stats_type,
-				  struct msm_stats_meta_buf **pp_stats_buf);
-	int (*bufq_flush) (struct msm_stats_bufq_ctrl *stats_ctrl,
-					   enum msm_stats_enum_type stats_type,
-					   struct ion_client *client);
-	int (*buf_unprepare) (struct msm_stats_bufq_ctrl *stats_ctrl,
-		enum msm_stats_enum_type stats_type,
-		int buf_idx,
-		struct ion_client *client, int domain_num);
-	int (*buf_prepare) (struct msm_stats_bufq_ctrl *stats_ctrl,
-				struct msm_stats_buf_info *info,
-				struct ion_client *client, int domain_num);
-	int (*reqbuf) (struct msm_stats_bufq_ctrl *stats_ctrl,
-				   struct msm_stats_reqbuf *reqbuf,
-				   struct ion_client *client);
-	int (*dispatch) (struct msm_stats_bufq_ctrl *stats_ctrl,
-		enum msm_stats_enum_type stats_type,
-		unsigned long phy_addr, int *buf_idx, void **vaddr, int *fd,
-		struct ion_client *client);
-	int (*querybuf) (struct msm_stats_bufq_ctrl *stats_ctrl,
-		struct msm_stats_buf_info *info,
-		struct msm_stats_meta_buf **pp_stats_buf);
-	int (*stats_ctrl_init) (struct msm_stats_bufq_ctrl *stats_ctrl);
-	int (*stats_ctrl_deinit) (struct msm_stats_bufq_ctrl *stats_ctrl);
-};
-
-int msm_stats_buf_ops_init(struct msm_stats_bufq_ctrl *stats_ctrl,
-	struct ion_client *client, struct msm_stats_ops *ops);
-
-#endif /* _MSM_STATS_BUF_H_ */
diff --git a/drivers/media/video/msm/vx6953.c b/drivers/media/video/msm/vx6953.c
deleted file mode 100644
index f933a76..0000000
--- a/drivers/media/video/msm/vx6953.c
+++ /dev/null
@@ -1,3667 +0,0 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. 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/delay.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/module.h>
-#include <media/msm_camera.h>
-#include <mach/gpio.h>
-#include <mach/camera.h>
-#include <linux/slab.h>
-#include "vx6953.h"
-
-/*=============================================================
-	SENSOR REGISTER DEFINES
-==============================================================*/
-
-#define REG_GROUPED_PARAMETER_HOLD			0x0104
-#define GROUPED_PARAMETER_HOLD_OFF			0x00
-#define GROUPED_PARAMETER_HOLD				0x01
-#define REG_MODE_SELECT					0x0100
-#define MODE_SELECT_STANDBY_MODE			0x00
-#define MODE_SELECT_STREAM				0x01
-/* Integration Time */
-#define REG_COARSE_INTEGRATION_TIME_HI			0x0202
-#define REG_COARSE_INTEGRATION_TIME_LO			0x0203
-/* Gain */
-#define REG_ANALOGUE_GAIN_CODE_GLOBAL_HI		0x0204
-#define REG_ANALOGUE_GAIN_CODE_GLOBAL_LO		0x0205
-/* Digital Gain */
-#define REG_DIGITAL_GAIN_GREEN_R_HI			0x020E
-#define REG_DIGITAL_GAIN_GREEN_R_LO			0x020F
-#define REG_DIGITAL_GAIN_RED_HI				0x0210
-#define REG_DIGITAL_GAIN_RED_LO				0x0211
-#define REG_DIGITAL_GAIN_BLUE_HI			0x0212
-#define REG_DIGITAL_GAIN_BLUE_LO			0x0213
-#define REG_DIGITAL_GAIN_GREEN_B_HI			0x0214
-#define REG_DIGITAL_GAIN_GREEN_B_LO			0x0215
-/* output bits setting */
-#define REG_0x0112					0x0112
-#define REG_0x0113					0x0113
-/* PLL registers */
-#define REG_VT_PIX_CLK_DIV				0x0301
-#define REG_PRE_PLL_CLK_DIV				0x0305
-#define REG_PLL_MULTIPLIER				0x0307
-#define REG_OP_PIX_CLK_DIV				0x0309
-#define REG_0x034c					0x034c
-#define REG_0x034d					0x034d
-#define REG_0x034e					0x034e
-#define REG_0x034f					0x034f
-#define REG_0x0387					0x0387
-#define REG_0x0383					0x0383
-#define REG_FRAME_LENGTH_LINES_HI			0x0340
-#define REG_FRAME_LENGTH_LINES_LO			0x0341
-#define REG_LINE_LENGTH_PCK_HI				0x0342
-#define REG_LINE_LENGTH_PCK_LO				0x0343
-#define REG_0x3030					0x3030
-#define REG_0x0111					0x0111
-#define REG_0x0136					0x0136
-#define REG_0x0137					0x0137
-#define REG_0x0b00					0x0b00
-#define REG_0x3001					0x3001
-#define REG_0x3004					0x3004
-#define REG_0x3007					0x3007
-#define REG_0x301a					0x301a
-#define REG_0x3101					0x3101
-#define REG_0x3364					0x3364
-#define REG_0x3365					0x3365
-#define REG_0x0b83					0x0b83
-#define REG_0x0b84					0x0b84
-#define REG_0x0b85					0x0b85
-#define REG_0x0b88					0x0b88
-#define REG_0x0b89					0x0b89
-#define REG_0x0b8a					0x0b8a
-#define REG_0x3005					0x3005
-#define REG_0x3010					0x3010
-#define REG_0x3036					0x3036
-#define REG_0x3041					0x3041
-#define REG_0x0b80					0x0b80
-#define REG_0x0900					0x0900
-#define REG_0x0901					0x0901
-#define REG_0x0902					0x0902
-#define REG_0x3016					0x3016
-#define REG_0x301d					0x301d
-#define REG_0x317e					0x317e
-#define REG_0x317f					0x317f
-#define REG_0x3400					0x3400
-#define REG_0x303a					0x303a
-#define REG_0x1716					0x1716
-#define REG_0x1717					0x1717
-#define REG_0x1718					0x1718
-#define REG_0x1719					0x1719
-#define REG_0x3006					0x3006
-#define REG_0x301b					0x301b
-#define REG_0x3098					0x3098
-#define REG_0x309d					0x309d
-#define REG_0x3011					0x3011
-#define REG_0x3035					0x3035
-#define REG_0x3045					0x3045
-#define REG_0x3210					0x3210
-#define	REG_0x0111					0x0111
-#define REG_0x3410					0x3410
-#define REG_0x0b06					0x0b06
-#define REG_0x0b07					0x0b07
-#define REG_0x0b08					0x0b08
-#define REG_0x0b09					0x0b09
-#define REG_0x3640					0x3640
-/* Test Pattern */
-#define REG_TEST_PATTERN_MODE				0x0601
-
-/*============================================================================
-							 TYPE DECLARATIONS
-============================================================================*/
-
-/* 16bit address - 8 bit context register structure */
-#define	VX6953_STM5M0EDOF_OFFSET	9
-#define	Q8		0x00000100
-#define	Q10		0x00000400
-#define	VX6953_STM5M0EDOF_MAX_SNAPSHOT_EXPOSURE_LINE_COUNT	2922
-#define	VX6953_STM5M0EDOF_DEFAULT_MASTER_CLK_RATE	24000000
-#define	VX6953_STM5M0EDOF_OP_PIXEL_CLOCK_RATE	79800000
-#define	VX6953_STM5M0EDOF_VT_PIXEL_CLOCK_RATE	88670000
-/* Full	Size */
-#define	VX6953_FULL_SIZE_WIDTH	2608
-#define	VX6953_FULL_SIZE_HEIGHT		1960
-#define	VX6953_FULL_SIZE_DUMMY_PIXELS	1
-#define	VX6953_FULL_SIZE_DUMMY_LINES	0
-/* Quarter Size	*/
-#define	VX6953_QTR_SIZE_WIDTH	1304
-#define	VX6953_QTR_SIZE_HEIGHT		980
-#define	VX6953_QTR_SIZE_DUMMY_PIXELS	1
-#define	VX6953_QTR_SIZE_DUMMY_LINES		0
-/* Blanking	as measured	on the scope */
-/* Full	Size */
-#define	VX6953_HRZ_FULL_BLK_PIXELS	348
-#define	VX6953_VER_FULL_BLK_LINES	40
-/* Quarter Size	*/
-#define	VX6953_HRZ_QTR_BLK_PIXELS	1628
-#define	VX6953_VER_QTR_BLK_LINES	28
-#define	MAX_LINE_LENGTH_PCK		8190
-#define	MAX_FRAME_LENGTH_LINES	16383
-#define	VX6953_REVISION_NUMBER_CUT2	0x10/*revision number	for	Cut2.0*/
-#define	VX6953_REVISION_NUMBER_CUT3	0x20/*revision number	for	Cut3.0*/
-/* FIXME: Changes from here */
-struct vx6953_work_t {
-	struct work_struct work;
-};
-
-static struct vx6953_work_t *vx6953_sensorw;
-static struct i2c_client *vx6953_client;
-
-struct vx6953_ctrl_t {
-	const struct  msm_camera_sensor_info *sensordata;
-
-	uint32_t sensormode;
-	uint32_t fps_divider;   	/* init to 1 * 0x00000400 */
-	uint32_t pict_fps_divider;  /* init to 1 * 0x00000400 */
-	uint16_t fps;
-
-	int16_t curr_lens_pos;
-	uint16_t curr_step_pos;
-	uint16_t my_reg_gain;
-	uint32_t my_reg_line_count;
-	uint16_t total_lines_per_frame;
-
-	enum vx6953_resolution_t prev_res;
-	enum vx6953_resolution_t pict_res;
-	enum vx6953_resolution_t curr_res;
-	enum vx6953_test_mode_t  set_test;
-	enum sensor_revision_t sensor_type;
-
-	enum edof_mode_t edof_mode;
-
-	unsigned short imgaddr;
-};
-
-
-static uint8_t vx6953_stm5m0edof_delay_msecs_stdby;
-static uint16_t vx6953_stm5m0edof_delay_msecs_stream = 20;
-static uint8_t count;
-static struct vx6953_ctrl_t *vx6953_ctrl;
-static DECLARE_WAIT_QUEUE_HEAD(vx6953_wait_queue);
-DEFINE_MUTEX(vx6953_mut);
-static struct vx6953_i2c_reg_conf patch_tbl_cut2[] = {
-	{0xFB94, 0},	/*intialise Data Xfer Status reg*/
-	{0xFB95, 0},	/*gain 1	  (0x00)*/
-	{0xFB96, 0},	/*gain 1.07   (0x10)*/
-	{0xFB97, 0},	/*gain 1.14   (0x20)*/
-	{0xFB98, 0},	/*gain 1.23   (0x30)*/
-	{0xFB99, 0},	/*gain 1.33   (0x40)*/
-	{0xFB9A, 0},	/*gain 1.45   (0x50)*/
-	{0xFB9B, 0},	/*gain 1.6    (0x60)*/
-	{0xFB9C, 0},	/*gain 1.78   (0x70)*/
-	{0xFB9D, 2},	/*gain 2	  (0x80)*/
-	{0xFB9E, 2},	/*gain 2.29   (0x90)*/
-	{0xFB9F, 3},	/*gain 2.67   (0xA0)*/
-	{0xFBA0, 3},	/*gain 3.2    (0xB0)*/
-	{0xFBA1, 4},	/*gain 4	  (0xC0)*/
-	{0xFBA2, 7},	/*gain 5.33   (0xD0)*/
-	{0xFBA3, 10},	/*gain 8	  (0xE0)*/
-	{0xFBA4, 11},	/*gain 9.14   (0xE4)*/
-	{0xFBA5, 13},	/*gain 10.67  (0xE8)*/
-	{0xFBA6, 15},	/*gain 12.8   (0xEC)*/
-	{0xFBA7, 19},	/*gain 16     (0xF0)*/
-	{0xF800, 0x12},
-	{0xF801, 0x06},
-	{0xF802, 0xf7},
-	{0xF803, 0x90},
-	{0xF804, 0x02},
-	{0xF805, 0x05},
-	{0xF806, 0xe0},
-	{0xF807, 0xff},
-	{0xF808, 0x65},
-	{0xF809, 0x7d},
-	{0xF80A, 0x70},
-	{0xF80B, 0x03},
-	{0xF80C, 0x02},
-	{0xF80D, 0xf9},
-	{0xF80E, 0x1c},
-	{0xF80F, 0x8f},
-	{0xF810, 0x7d},
-	{0xF811, 0xe4},
-	{0xF812, 0xf5},
-	{0xF813, 0x7a},
-	{0xF814, 0x75},
-	{0xF815, 0x78},
-	{0xF816, 0x30},
-	{0xF817, 0x75},
-	{0xF818, 0x79},
-	{0xF819, 0x53},
-	{0xF81A, 0x85},
-	{0xF81B, 0x79},
-	{0xF81C, 0x82},
-	{0xF81D, 0x85},
-	{0xF81E, 0x78},
-	{0xF81F, 0x83},
-	{0xF820, 0xe0},
-	{0xF821, 0xc3},
-	{0xF822, 0x95},
-	{0xF823, 0x7b},
-	{0xF824, 0xf0},
-	{0xF825, 0x74},
-	{0xF826, 0x02},
-	{0xF827, 0x25},
-	{0xF828, 0x79},
-	{0xF829, 0xf5},
-	{0xF82A, 0x79},
-	{0xF82B, 0xe4},
-	{0xF82C, 0x35},
-	{0xF82D, 0x78},
-	{0xF82E, 0xf5},
-	{0xF82F, 0x78},
-	{0xF830, 0x05},
-	{0xF831, 0x7a},
-	{0xF832, 0xe5},
-	{0xF833, 0x7a},
-	{0xF834, 0xb4},
-	{0xF835, 0x08},
-	{0xF836, 0xe3},
-	{0xF837, 0xe5},
-	{0xF838, 0x7d},
-	{0xF839, 0x70},
-	{0xF83A, 0x04},
-	{0xF83B, 0xff},
-	{0xF83C, 0x02},
-	{0xF83D, 0xf8},
-	{0xF83E, 0xe4},
-	{0xF83F, 0xe5},
-	{0xF840, 0x7d},
-	{0xF841, 0xb4},
-	{0xF842, 0x10},
-	{0xF843, 0x05},
-	{0xF844, 0x7f},
-	{0xF845, 0x01},
-	{0xF846, 0x02},
-	{0xF847, 0xf8},
-	{0xF848, 0xe4},
-	{0xF849, 0xe5},
-	{0xF84A, 0x7d},
-	{0xF84B, 0xb4},
-	{0xF84C, 0x20},
-	{0xF84D, 0x05},
-	{0xF84E, 0x7f},
-	{0xF84F, 0x02},
-	{0xF850, 0x02},
-	{0xF851, 0xf8},
-	{0xF852, 0xe4},
-	{0xF853, 0xe5},
-	{0xF854, 0x7d},
-	{0xF855, 0xb4},
-	{0xF856, 0x30},
-	{0xF857, 0x05},
-	{0xF858, 0x7f},
-	{0xF859, 0x03},
-	{0xF85A, 0x02},
-	{0xF85B, 0xf8},
-	{0xF85C, 0xe4},
-	{0xF85D, 0xe5},
-	{0xF85E, 0x7d},
-	{0xF85F, 0xb4},
-	{0xF860, 0x40},
-	{0xF861, 0x04},
-	{0xF862, 0x7f},
-	{0xF863, 0x04},
-	{0xF864, 0x80},
-	{0xF865, 0x7e},
-	{0xF866, 0xe5},
-	{0xF867, 0x7d},
-	{0xF868, 0xb4},
-	{0xF869, 0x50},
-	{0xF86A, 0x04},
-	{0xF86B, 0x7f},
-	{0xF86C, 0x05},
-	{0xF86D, 0x80},
-	{0xF86E, 0x75},
-	{0xF86F, 0xe5},
-	{0xF870, 0x7d},
-	{0xF871, 0xb4},
-	{0xF872, 0x60},
-	{0xF873, 0x04},
-	{0xF874, 0x7f},
-	{0xF875, 0x06},
-	{0xF876, 0x80},
-	{0xF877, 0x6c},
-	{0xF878, 0xe5},
-	{0xF879, 0x7d},
-	{0xF87A, 0xb4},
-	{0xF87B, 0x70},
-	{0xF87C, 0x04},
-	{0xF87D, 0x7f},
-	{0xF87E, 0x07},
-	{0xF87F, 0x80},
-	{0xF880, 0x63},
-	{0xF881, 0xe5},
-	{0xF882, 0x7d},
-	{0xF883, 0xb4},
-	{0xF884, 0x80},
-	{0xF885, 0x04},
-	{0xF886, 0x7f},
-	{0xF887, 0x08},
-	{0xF888, 0x80},
-	{0xF889, 0x5a},
-	{0xF88A, 0xe5},
-	{0xF88B, 0x7d},
-	{0xF88C, 0xb4},
-	{0xF88D, 0x90},
-	{0xF88E, 0x04},
-	{0xF88F, 0x7f},
-	{0xF890, 0x09},
-	{0xF891, 0x80},
-	{0xF892, 0x51},
-	{0xF893, 0xe5},
-	{0xF894, 0x7d},
-	{0xF895, 0xb4},
-	{0xF896, 0xa0},
-	{0xF897, 0x04},
-	{0xF898, 0x7f},
-	{0xF899, 0x0a},
-	{0xF89A, 0x80},
-	{0xF89B, 0x48},
-	{0xF89C, 0xe5},
-	{0xF89D, 0x7d},
-	{0xF89E, 0xb4},
-	{0xF89F, 0xb0},
-	{0xF8A0, 0x04},
-	{0xF8A1, 0x7f},
-	{0xF8A2, 0x0b},
-	{0xF8A3, 0x80},
-	{0xF8A4, 0x3f},
-	{0xF8A5, 0xe5},
-	{0xF8A6, 0x7d},
-	{0xF8A7, 0xb4},
-	{0xF8A8, 0xc0},
-	{0xF8A9, 0x04},
-	{0xF8AA, 0x7f},
-	{0xF8AB, 0x0c},
-	{0xF8AC, 0x80},
-	{0xF8AD, 0x36},
-	{0xF8AE, 0xe5},
-	{0xF8AF, 0x7d},
-	{0xF8B0, 0xb4},
-	{0xF8B1, 0xd0},
-	{0xF8B2, 0x04},
-	{0xF8B3, 0x7f},
-	{0xF8B4, 0x0d},
-	{0xF8B5, 0x80},
-	{0xF8B6, 0x2d},
-	{0xF8B7, 0xe5},
-	{0xF8B8, 0x7d},
-	{0xF8B9, 0xb4},
-	{0xF8BA, 0xe0},
-	{0xF8BB, 0x04},
-	{0xF8BC, 0x7f},
-	{0xF8BD, 0x0e},
-	{0xF8BE, 0x80},
-	{0xF8BF, 0x24},
-	{0xF8C0, 0xe5},
-	{0xF8C1, 0x7d},
-	{0xF8C2, 0xb4},
-	{0xF8C3, 0xe4},
-	{0xF8C4, 0x04},
-	{0xF8C5, 0x7f},
-	{0xF8C6, 0x0f},
-	{0xF8C7, 0x80},
-	{0xF8C8, 0x1b},
-	{0xF8C9, 0xe5},
-	{0xF8CA, 0x7d},
-	{0xF8CB, 0xb4},
-	{0xF8CC, 0xe8},
-	{0xF8CD, 0x04},
-	{0xF8CE, 0x7f},
-	{0xF8CF, 0x10},
-	{0xF8D0, 0x80},
-	{0xF8D1, 0x12},
-	{0xF8D2, 0xe5},
-	{0xF8D3, 0x7d},
-	{0xF8D4, 0xb4},
-	{0xF8D5, 0xec},
-	{0xF8D6, 0x04},
-	{0xF8D7, 0x7f},
-	{0xF8D8, 0x11},
-	{0xF8D9, 0x80},
-	{0xF8DA, 0x09},
-	{0xF8DB, 0xe5},
-	{0xF8DC, 0x7d},
-	{0xF8DD, 0x7f},
-	{0xF8DE, 0x00},
-	{0xF8DF, 0xb4},
-	{0xF8E0, 0xf0},
-	{0xF8E1, 0x02},
-	{0xF8E2, 0x7f},
-	{0xF8E3, 0x12},
-	{0xF8E4, 0x8f},
-	{0xF8E5, 0x7c},
-	{0xF8E6, 0xef},
-	{0xF8E7, 0x24},
-	{0xF8E8, 0x95},
-	{0xF8E9, 0xff},
-	{0xF8EA, 0xe4},
-	{0xF8EB, 0x34},
-	{0xF8EC, 0xfb},
-	{0xF8ED, 0x8f},
-	{0xF8EE, 0x82},
-	{0xF8EF, 0xf5},
-	{0xF8F0, 0x83},
-	{0xF8F1, 0xe4},
-	{0xF8F2, 0x93},
-	{0xF8F3, 0xf5},
-	{0xF8F4, 0x7c},
-	{0xF8F5, 0xf5},
-	{0xF8F6, 0x7b},
-	{0xF8F7, 0xe4},
-	{0xF8F8, 0xf5},
-	{0xF8F9, 0x7a},
-	{0xF8FA, 0x75},
-	{0xF8FB, 0x78},
-	{0xF8FC, 0x30},
-	{0xF8FD, 0x75},
-	{0xF8FE, 0x79},
-	{0xF8FF, 0x53},
-	{0xF900, 0x85},
-	{0xF901, 0x79},
-	{0xF902, 0x82},
-	{0xF903, 0x85},
-	{0xF904, 0x78},
-	{0xF905, 0x83},
-	{0xF906, 0xe0},
-	{0xF907, 0x25},
-	{0xF908, 0x7c},
-	{0xF909, 0xf0},
-	{0xF90A, 0x74},
-	{0xF90B, 0x02},
-	{0xF90C, 0x25},
-	{0xF90D, 0x79},
-	{0xF90E, 0xf5},
-	{0xF90F, 0x79},
-	{0xF910, 0xe4},
-	{0xF911, 0x35},
-	{0xF912, 0x78},
-	{0xF913, 0xf5},
-	{0xF914, 0x78},
-	{0xF915, 0x05},
-	{0xF916, 0x7a},
-	{0xF917, 0xe5},
-	{0xF918, 0x7a},
-	{0xF919, 0xb4},
-	{0xF91A, 0x08},
-	{0xF91B, 0xe4},
-	{0xF91C, 0x02},
-	{0xF91D, 0x18},
-	{0xF91E, 0x32},
-	{0xF91F, 0x22},
-	{0xF920, 0xf0},
-	{0xF921, 0x90},
-	{0xF922, 0xa0},
-	{0xF923, 0xf8},
-	{0xF924, 0xe0},
-	{0xF925, 0x70},
-	{0xF926, 0x02},
-	{0xF927, 0xa3},
-	{0xF928, 0xe0},
-	{0xF929, 0x70},
-	{0xF92A, 0x0a},
-	{0xF92B, 0x90},
-	{0xF92C, 0xa1},
-	{0xF92D, 0x10},
-	{0xF92E, 0xe0},
-	{0xF92F, 0xfe},
-	{0xF930, 0xa3},
-	{0xF931, 0xe0},
-	{0xF932, 0xff},
-	{0xF933, 0x80},
-	{0xF934, 0x04},
-	{0xF935, 0x7e},
-	{0xF936, 0x00},
-	{0xF937, 0x7f},
-	{0xF938, 0x00},
-	{0xF939, 0x8e},
-	{0xF93A, 0x7e},
-	{0xF93B, 0x8f},
-	{0xF93C, 0x7f},
-	{0xF93D, 0x90},
-	{0xF93E, 0x36},
-	{0xF93F, 0x0d},
-	{0xF940, 0xe0},
-	{0xF941, 0x44},
-	{0xF942, 0x02},
-	{0xF943, 0xf0},
-	{0xF944, 0x90},
-	{0xF945, 0x36},
-	{0xF946, 0x0e},
-	{0xF947, 0xe5},
-	{0xF948, 0x7e},
-	{0xF949, 0xf0},
-	{0xF94A, 0xa3},
-	{0xF94B, 0xe5},
-	{0xF94C, 0x7f},
-	{0xF94D, 0xf0},
-	{0xF94E, 0xe5},
-	{0xF94F, 0x3a},
-	{0xF950, 0x60},
-	{0xF951, 0x0c},
-	{0xF952, 0x90},
-	{0xF953, 0x36},
-	{0xF954, 0x09},
-	{0xF955, 0xe0},
-	{0xF956, 0x70},
-	{0xF957, 0x06},
-	{0xF958, 0x90},
-	{0xF959, 0x36},
-	{0xF95A, 0x08},
-	{0xF95B, 0xf0},
-	{0xF95C, 0xf5},
-	{0xF95D, 0x3a},
-	{0xF95E, 0x02},
-	{0xF95F, 0x03},
-	{0xF960, 0x94},
-	{0xF961, 0x22},
-	{0xF962, 0x78},
-	{0xF963, 0x07},
-	{0xF964, 0xe6},
-	{0xF965, 0xd3},
-	{0xF966, 0x94},
-	{0xF967, 0x00},
-	{0xF968, 0x40},
-	{0xF969, 0x16},
-	{0xF96A, 0x16},
-	{0xF96B, 0xe6},
-	{0xF96C, 0x90},
-	{0xF96D, 0x30},
-	{0xF96E, 0xa1},
-	{0xF96F, 0xf0},
-	{0xF970, 0x90},
-	{0xF971, 0x43},
-	{0xF972, 0x83},
-	{0xF973, 0xe0},
-	{0xF974, 0xb4},
-	{0xF975, 0x01},
-	{0xF976, 0x0f},
-	{0xF977, 0x90},
-	{0xF978, 0x43},
-	{0xF979, 0x87},
-	{0xF97A, 0xe0},
-	{0xF97B, 0xb4},
-	{0xF97C, 0x01},
-	{0xF97D, 0x08},
-	{0xF97E, 0x80},
-	{0xF97F, 0x00},
-	{0xF980, 0x90},
-	{0xF981, 0x30},
-	{0xF982, 0xa0},
-	{0xF983, 0x74},
-	{0xF984, 0x01},
-	{0xF985, 0xf0},
-	{0xF986, 0x22},
-	{0xF987, 0xf0},
-	{0xF988, 0x90},
-	{0xF989, 0x35},
-	{0xF98A, 0xba},
-	{0xF98B, 0xe0},
-	{0xF98C, 0xb4},
-	{0xF98D, 0x0a},
-	{0xF98E, 0x0d},
-	{0xF98F, 0xa3},
-	{0xF990, 0xe0},
-	{0xF991, 0xb4},
-	{0xF992, 0x01},
-	{0xF993, 0x08},
-	{0xF994, 0x90},
-	{0xF995, 0xfb},
-	{0xF996, 0x94},
-	{0xF997, 0xe0},
-	{0xF998, 0x90},
-	{0xF999, 0x35},
-	{0xF99A, 0xb8},
-	{0xF99B, 0xf0},
-	{0xF99C, 0xd0},
-	{0xF99D, 0xd0},
-	{0xF99E, 0xd0},
-	{0xF99F, 0x82},
-	{0xF9A0, 0xd0},
-	{0xF9A1, 0x83},
-	{0xF9A2, 0xd0},
-	{0xF9A3, 0xe0},
-	{0xF9A4, 0x32},
-	{0xF9A5, 0x22},
-	{0xF9A6, 0xe5},
-	{0xF9A7, 0x7f},
-	{0xF9A8, 0x45},
-	{0xF9A9, 0x7e},
-	{0xF9AA, 0x60},
-	{0xF9AB, 0x15},
-	{0xF9AC, 0x90},
-	{0xF9AD, 0x01},
-	{0xF9AE, 0x00},
-	{0xF9AF, 0xe0},
-	{0xF9B0, 0x70},
-	{0xF9B1, 0x0f},
-	{0xF9B2, 0x90},
-	{0xF9B3, 0xa0},
-	{0xF9B4, 0xf8},
-	{0xF9B5, 0xe5},
-	{0xF9B6, 0x7e},
-	{0xF9B7, 0xf0},
-	{0xF9B8, 0xa3},
-	{0xF9B9, 0xe5},
-	{0xF9BA, 0x7f},
-	{0xF9BB, 0xf0},
-	{0xF9BC, 0xe4},
-	{0xF9BD, 0xf5},
-	{0xF9BE, 0x7e},
-	{0xF9BF, 0xf5},
-	{0xF9C0, 0x7f},
-	{0xF9C1, 0x22},
-	{0xF9C2, 0x02},
-	{0xF9C3, 0x0e},
-	{0xF9C4, 0x79},
-	{0xF9C5, 0x22},
-	/* Offsets:*/
-	{0x35C6, 0x00},/* FIDDLEDARKCAL*/
-	{0x35C7, 0x00},
-	{0x35C8, 0x01},/*STOREDISTANCEATSTOPSTREAMING*/
-	{0x35C9, 0x20},
-	{0x35CA, 0x01},/*BRUCEFIX*/
-	{0x35CB, 0x62},
-	{0x35CC, 0x01},/*FIXDATAXFERSTATUSREG*/
-	{0x35CD, 0x87},
-	{0x35CE, 0x01},/*FOCUSDISTANCEUPDATE*/
-	{0x35CF, 0xA6},
-	{0x35D0, 0x01},/*SKIPEDOFRESET*/
-	{0x35D1, 0xC2},
-	{0x35D2, 0x00},
-	{0x35D3, 0xFB},
-	{0x35D4, 0x00},
-	{0x35D5, 0x94},
-	{0x35D6, 0x00},
-	{0x35D7, 0xFB},
-	{0x35D8, 0x00},
-	{0x35D9, 0x94},
-	{0x35DA, 0x00},
-	{0x35DB, 0xFB},
-	{0x35DC, 0x00},
-	{0x35DD, 0x94},
-	{0x35DE, 0x00},
-	{0x35DF, 0xFB},
-	{0x35E0, 0x00},
-	{0x35E1, 0x94},
-	{0x35E6, 0x18},/* FIDDLEDARKCAL*/
-	{0x35E7, 0x2F},
-	{0x35E8, 0x03},/* STOREDISTANCEATSTOPSTREAMING*/
-	{0x35E9, 0x93},
-	{0x35EA, 0x18},/* BRUCEFIX*/
-	{0x35EB, 0x99},
-	{0x35EC, 0x00},/* FIXDATAXFERSTATUSREG*/
-	{0x35ED, 0xA3},
-	{0x35EE, 0x21},/* FOCUSDISTANCEUPDATE*/
-	{0x35EF, 0x5B},
-	{0x35F0, 0x0E},/* SKIPEDOFRESET*/
-	{0x35F1, 0x74},
-	{0x35F2, 0x04},
-	{0x35F3, 0x64},
-	{0x35F4, 0x04},
-	{0x35F5, 0x65},
-	{0x35F6, 0x04},
-	{0x35F7, 0x7B},
-	{0x35F8, 0x04},
-	{0x35F9, 0x7C},
-	{0x35FA, 0x04},
-	{0x35FB, 0xDD},
-	{0x35FC, 0x04},
-	{0x35FD, 0xDE},
-	{0x35FE, 0x04},
-	{0x35FF, 0xEF},
-	{0x3600, 0x04},
-	{0x3601, 0xF0},
-	/*Jump/Data:*/
-	{0x35C2, 0x3F},/* Jump Reg*/
-	{0x35C3, 0xFF},/* Jump Reg*/
-	{0x35C4, 0x3F},/* Data Reg*/
-	{0x35C5, 0xC0},/* Data Reg*/
-	{0x35C0, 0x01},/* Enable*/
-
-};
-
-static struct vx6953_i2c_reg_conf cut3_cali_data[] = {
-		{0x360A, 0x07 },
-		{0x3530, 0x07 },
-		{0x35B5, 0x00 },
-		{0x35BC, 0x00 },
-		{0xAFF8, 0x00 },
-		{0xAFF9, 0x01 },
-		{0xF800, 0x90 },
-		{0xF801, 0x30 },
-		{0xF802, 0x31 },
-		{0xF803, 0xe0 },
-		{0xF804, 0xf5 },
-		{0xF805, 0x7d },
-		{0xF806, 0xb4 },
-		{0xF807, 0x01 },
-		{0xF808, 0x06 },
-		{0xF809, 0x75 },
-		{0xF80A, 0x7d },
-		{0xF80B, 0x03 },
-		{0xF80C, 0x74 },
-		{0xF80D, 0x03 },
-		{0xF80E, 0xf0 },
-		{0xF80F, 0x90 },
-		{0xF810, 0x30 },
-		{0xF811, 0x04 },
-		{0xF812, 0x74 },
-		{0xF813, 0x33 },
-		{0xF814, 0xf0 },
-		{0xF815, 0x90 },
-		{0xF816, 0x30 },
-		{0xF817, 0x06 },
-		{0xF818, 0xe4 },
-		{0xF819, 0xf0 },
-		{0xF81A, 0xa3 },
-		{0xF81B, 0x74 },
-		{0xF81C, 0x08 },
-		{0xF81D, 0xf0 },
-		{0xF81E, 0x90 },
-		{0xF81F, 0x30 },
-		{0xF820, 0x10 },
-		{0xF821, 0xe4 },
-		{0xF822, 0xf0 },
-		{0xF823, 0xa3 },
-		{0xF824, 0xf0 },
-		{0xF825, 0x90 },
-		{0xF826, 0x30 },
-		{0xF827, 0x16 },
-		{0xF828, 0x74 },
-		{0xF829, 0x1e },
-		{0xF82A, 0xf0 },
-		{0xF82B, 0x90 },
-		{0xF82C, 0x30 },
-		{0xF82D, 0x1a },
-		{0xF82E, 0x74 },
-		{0xF82F, 0x6a },
-		{0xF830, 0xf0 },
-		{0xF831, 0x90 },
-		{0xF832, 0x30 },
-		{0xF833, 0x30 },
-		{0xF834, 0x74 },
-		{0xF835, 0x08 },
-		{0xF836, 0xf0 },
-		{0xF837, 0x90 },
-		{0xF838, 0x30 },
-		{0xF839, 0x36 },
-		{0xF83A, 0x74 },
-		{0xF83B, 0x2c },
-		{0xF83C, 0xf0 },
-		{0xF83D, 0x90 },
-		{0xF83E, 0x30 },
-		{0xF83F, 0x41 },
-		{0xF840, 0xe4 },
-		{0xF841, 0xf0 },
-		{0xF842, 0xa3 },
-		{0xF843, 0x74 },
-		{0xF844, 0x24 },
-		{0xF845, 0xf0 },
-		{0xF846, 0x90 },
-		{0xF847, 0x30 },
-		{0xF848, 0x45 },
-		{0xF849, 0x74 },
-		{0xF84A, 0x81 },
-		{0xF84B, 0xf0 },
-		{0xF84C, 0x90 },
-		{0xF84D, 0x30 },
-		{0xF84E, 0x98 },
-		{0xF84F, 0x74 },
-		{0xF850, 0x01 },
-		{0xF851, 0xf0 },
-		{0xF852, 0x90 },
-		{0xF853, 0x30 },
-		{0xF854, 0x9d },
-		{0xF855, 0x74 },
-		{0xF856, 0x05 },
-		{0xF857, 0xf0 },
-		{0xF858, 0xe5 },
-		{0xF859, 0x7d },
-		{0xF85A, 0x70 },
-		{0xF85B, 0x22 },
-		{0xF85C, 0x90 },
-		{0xF85D, 0x02 },
-		{0xF85E, 0x00 },
-		{0xF85F, 0x74 },
-		{0xF860, 0x02 },
-		{0xF861, 0xf0 },
-		{0xF862, 0xa3 },
-		{0xF863, 0x74 },
-		{0xF864, 0x54 },
-		{0xF865, 0xf0 },
-		{0xF866, 0x90 },
-		{0xF867, 0x30 },
-		{0xF868, 0x05 },
-		{0xF869, 0x74 },
-		{0xF86A, 0x01 },
-		{0xF86B, 0xf0 },
-		{0xF86C, 0x90 },
-		{0xF86D, 0x30 },
-		{0xF86E, 0x1b },
-		{0xF86F, 0x74 },
-		{0xF870, 0x29 },
-		{0xF871, 0xf0 },
-		{0xF872, 0x90 },
-		{0xF873, 0x30 },
-		{0xF874, 0x30 },
-		{0xF875, 0xe4 },
-		{0xF876, 0xf0 },
-		{0xF877, 0x90 },
-		{0xF878, 0x30 },
-		{0xF879, 0x35 },
-		{0xF87A, 0x04 },
-		{0xF87B, 0xf0 },
-		{0xF87C, 0x80 },
-		{0xF87D, 0x69 },
-		{0xF87E, 0xe5 },
-		{0xF87F, 0x7d },
-		{0xF880, 0x64 },
-		{0xF881, 0x02 },
-		{0xF882, 0x70 },
-		{0xF883, 0x3c },
-		{0xF884, 0x90 },
-		{0xF885, 0x02 },
-		{0xF886, 0x00 },
-		{0xF887, 0x74 },
-		{0xF888, 0x04 },
-		{0xF889, 0xf0 },
-		{0xF88A, 0xa3 },
-		{0xF88B, 0x74 },
-		{0xF88C, 0x10 },
-		{0xF88D, 0xf0 },
-		{0xF88E, 0x90 },
-		{0xF88F, 0x30 },
-		{0xF890, 0x04 },
-		{0xF891, 0x74 },
-		{0xF892, 0x34 },
-		{0xF893, 0xf0 },
-		{0xF894, 0xa3 },
-		{0xF895, 0x74 },
-		{0xF896, 0x07 },
-		{0xF897, 0xf0 },
-		{0xF898, 0x90 },
-		{0xF899, 0x30 },
-		{0xF89A, 0x10 },
-		{0xF89B, 0x74 },
-		{0xF89C, 0x10 },
-		{0xF89D, 0xf0 },
-		{0xF89E, 0x90 },
-		{0xF89F, 0x30 },
-		{0xF8A0, 0x16 },
-		{0xF8A1, 0x74 },
-		{0xF8A2, 0x1f },
-		{0xF8A3, 0xf0 },
-		{0xF8A4, 0x90 },
-		{0xF8A5, 0x30 },
-		{0xF8A6, 0x1a },
-		{0xF8A7, 0x74 },
-		{0xF8A8, 0x62 },
-		{0xF8A9, 0xf0 },
-		{0xF8AA, 0xa3 },
-		{0xF8AB, 0x74 },
-		{0xF8AC, 0x2a },
-		{0xF8AD, 0xf0 },
-		{0xF8AE, 0x90 },
-		{0xF8AF, 0x30 },
-		{0xF8B0, 0x35 },
-		{0xF8B1, 0x74 },
-		{0xF8B2, 0x04 },
-		{0xF8B3, 0xf0 },
-		{0xF8B4, 0x90 },
-		{0xF8B5, 0x30 },
-		{0xF8B6, 0x41 },
-		{0xF8B7, 0x74 },
-		{0xF8B8, 0x60 },
-		{0xF8B9, 0xf0 },
-		{0xF8BA, 0xa3 },
-		{0xF8BB, 0x74 },
-		{0xF8BC, 0x64 },
-		{0xF8BD, 0xf0 },
-		{0xF8BE, 0x80 },
-		{0xF8BF, 0x27 },
-		{0xF8C0, 0xe5 },
-		{0xF8C1, 0x7d },
-		{0xF8C2, 0xb4 },
-		{0xF8C3, 0x03 },
-		{0xF8C4, 0x22 },
-		{0xF8C5, 0x90 },
-		{0xF8C6, 0x02 },
-		{0xF8C7, 0x00 },
-		{0xF8C8, 0x74 },
-		{0xF8C9, 0x02 },
-		{0xF8CA, 0xf0 },
-		{0xF8CB, 0xa3 },
-		{0xF8CC, 0x74 },
-		{0xF8CD, 0x26 },
-		{0xF8CE, 0xf0 },
-		{0xF8CF, 0x90 },
-		{0xF8D0, 0x30 },
-		{0xF8D1, 0x05 },
-		{0xF8D2, 0x74 },
-		{0xF8D3, 0x03 },
-		{0xF8D4, 0xf0 },
-		{0xF8D5, 0x90 },
-		{0xF8D6, 0x30 },
-		{0xF8D7, 0x11 },
-		{0xF8D8, 0x74 },
-		{0xF8D9, 0x01 },
-		{0xF8DA, 0xf0 },
-		{0xF8DB, 0x90 },
-		{0xF8DC, 0x30 },
-		{0xF8DD, 0x1b },
-		{0xF8DE, 0x74 },
-		{0xF8DF, 0x2a },
-		{0xF8E0, 0xf0 },
-		{0xF8E1, 0x90 },
-		{0xF8E2, 0x30 },
-		{0xF8E3, 0x35 },
-		{0xF8E4, 0x74 },
-		{0xF8E5, 0x03 },
-		{0xF8E6, 0xf0 },
-		{0xF8E7, 0x90 },
-		{0xF8E8, 0x41 },
-		{0xF8E9, 0x01 },
-		{0xF8EA, 0xe0 },
-		{0xF8EB, 0xf5 },
-		{0xF8EC, 0x79 },
-		{0xF8ED, 0x90 },
-		{0xF8EE, 0x43 },
-		{0xF8EF, 0x87 },
-		{0xF8F0, 0xe0 },
-		{0xF8F1, 0xf5 },
-		{0xF8F2, 0x7a },
-		{0xF8F3, 0x90 },
-		{0xF8F4, 0x42 },
-		{0xF8F5, 0x05 },
-		{0xF8F6, 0xe0 },
-		{0xF8F7, 0xf5 },
-		{0xF8F8, 0x7b },
-		{0xF8F9, 0x22 },
-		{0xF8FA, 0x78 },
-		{0xF8FB, 0x07 },
-		{0xF8FC, 0xe6 },
-		{0xF8FD, 0xf5 },
-		{0xF8FE, 0x7c },
-		{0xF8FF, 0xe5 },
-		{0xF900, 0x7c },
-		{0xF901, 0x60 },
-		{0xF902, 0x1e },
-		{0xF903, 0x90 },
-		{0xF904, 0x43 },
-		{0xF905, 0x83 },
-		{0xF906, 0xe0 },
-		{0xF907, 0xb4 },
-		{0xF908, 0x01 },
-		{0xF909, 0x17 },
-		{0xF90A, 0x90 },
-		{0xF90B, 0x43 },
-		{0xF90C, 0x87 },
-		{0xF90D, 0xe0 },
-		{0xF90E, 0xb4 },
-		{0xF90F, 0x01 },
-		{0xF910, 0x10 },
-		{0xF911, 0x15 },
-		{0xF912, 0x7c },
-		{0xF913, 0x90 },
-		{0xF914, 0x30 },
-		{0xF915, 0xa1 },
-		{0xF916, 0xe5 },
-		{0xF917, 0x7c },
-		{0xF918, 0xf0 },
-		{0xF919, 0x90 },
-		{0xF91A, 0x30 },
-		{0xF91B, 0xa0 },
-		{0xF91C, 0x74 },
-		{0xF91D, 0x01 },
-		{0xF91E, 0xf0 },
-		{0xF91F, 0x80 },
-		{0xF920, 0x05 },
-		{0xF921, 0xe4 },
-		{0xF922, 0x90 },
-		{0xF923, 0x30 },
-		{0xF924, 0xa0 },
-		{0xF925, 0xf0 },
-		{0xF926, 0x90 },
-		{0xF927, 0x41 },
-		{0xF928, 0x01 },
-		{0xF929, 0xe0 },
-		{0xF92A, 0xfc },
-		{0xF92B, 0x54 },
-		{0xF92C, 0x02 },
-		{0xF92D, 0xfe },
-		{0xF92E, 0xe5 },
-		{0xF92F, 0x79 },
-		{0xF930, 0x54 },
-		{0xF931, 0x02 },
-		{0xF932, 0xb5 },
-		{0xF933, 0x06 },
-		{0xF934, 0x0f },
-		{0xF935, 0x90 },
-		{0xF936, 0x43 },
-		{0xF937, 0x87 },
-		{0xF938, 0xe0 },
-		{0xF939, 0xb5 },
-		{0xF93A, 0x7a },
-		{0xF93B, 0x08 },
-		{0xF93C, 0x90 },
-		{0xF93D, 0x42 },
-		{0xF93E, 0x05 },
-		{0xF93F, 0xe0 },
-		{0xF940, 0x65 },
-		{0xF941, 0x7b },
-		{0xF942, 0x60 },
-		{0xF943, 0x0b },
-		{0xF944, 0x90 },
-		{0xF945, 0x30 },
-		{0xF946, 0x50 },
-		{0xF947, 0xe0 },
-		{0xF948, 0x54 },
-		{0xF949, 0xf9 },
-		{0xF94A, 0x44 },
-		{0xF94B, 0x02 },
-		{0xF94C, 0xf0 },
-		{0xF94D, 0x80 },
-		{0xF94E, 0x09 },
-		{0xF94F, 0x90 },
-		{0xF950, 0x30 },
-		{0xF951, 0x50 },
-		{0xF952, 0xe0 },
-		{0xF953, 0x54 },
-		{0xF954, 0xf9 },
-		{0xF955, 0x44 },
-		{0xF956, 0x04 },
-		{0xF957, 0xf0 },
-		{0xF958, 0x8c },
-		{0xF959, 0x79 },
-		{0xF95A, 0x90 },
-		{0xF95B, 0x43 },
-		{0xF95C, 0x87 },
-		{0xF95D, 0xe0 },
-		{0xF95E, 0xf5 },
-		{0xF95F, 0x7a },
-		{0xF960, 0x90 },
-		{0xF961, 0x42 },
-		{0xF962, 0x05 },
-		{0xF963, 0xe0 },
-		{0xF964, 0xf5 },
-		{0xF965, 0x7b },
-		{0xF966, 0x22 },
-		{0xF967, 0xc3 },
-		{0xF968, 0x90 },
-		{0xF969, 0x0b },
-		{0xF96A, 0x89 },
-		{0xF96B, 0xe0 },
-		{0xF96C, 0x94 },
-		{0xF96D, 0x1e },
-		{0xF96E, 0x90 },
-		{0xF96F, 0x0b },
-		{0xF970, 0x88 },
-		{0xF971, 0xe0 },
-		{0xF972, 0x94 },
-		{0xF973, 0x00 },
-		{0xF974, 0x50 },
-		{0xF975, 0x06 },
-		{0xF976, 0x7e },
-		{0xF977, 0x00 },
-		{0xF978, 0x7f },
-		{0xF979, 0x01 },
-		{0xF97A, 0x80 },
-		{0xF97B, 0x3d },
-		{0xF97C, 0xc3 },
-		{0xF97D, 0x90 },
-		{0xF97E, 0x0b },
-		{0xF97F, 0x89 },
-		{0xF980, 0xe0 },
-		{0xF981, 0x94 },
-		{0xF982, 0x3c },
-		{0xF983, 0x90 },
-		{0xF984, 0x0b },
-		{0xF985, 0x88 },
-		{0xF986, 0xe0 },
-		{0xF987, 0x94 },
-		{0xF988, 0x00 },
-		{0xF989, 0x50 },
-		{0xF98A, 0x06 },
-		{0xF98B, 0x7e },
-		{0xF98C, 0x00 },
-		{0xF98D, 0x7f },
-		{0xF98E, 0x02 },
-		{0xF98F, 0x80 },
-		{0xF990, 0x28 },
-		{0xF991, 0xc3 },
-		{0xF992, 0x90 },
-		{0xF993, 0x0b },
-		{0xF994, 0x89 },
-		{0xF995, 0xe0 },
-		{0xF996, 0x94 },
-		{0xF997, 0xfa },
-		{0xF998, 0x90 },
-		{0xF999, 0x0b },
-		{0xF99A, 0x88 },
-		{0xF99B, 0xe0 },
-		{0xF99C, 0x94 },
-		{0xF99D, 0x00 },
-		{0xF99E, 0x50 },
-		{0xF99F, 0x06 },
-		{0xF9A0, 0x7e },
-		{0xF9A1, 0x00 },
-		{0xF9A2, 0x7f },
-		{0xF9A3, 0x03 },
-		{0xF9A4, 0x80 },
-		{0xF9A5, 0x13 },
-		{0xF9A6, 0xc3 },
-		{0xF9A7, 0x90 },
-		{0xF9A8, 0x0b },
-		{0xF9A9, 0x88 },
-		{0xF9AA, 0xe0 },
-		{0xF9AB, 0x94 },
-		{0xF9AC, 0x80 },
-		{0xF9AD, 0x50 },
-		{0xF9AE, 0x06 },
-		{0xF9AF, 0x7e },
-		{0xF9B0, 0x00 },
-		{0xF9B1, 0x7f },
-		{0xF9B2, 0x04 },
-		{0xF9B3, 0x80 },
-		{0xF9B4, 0x04 },
-		{0xF9B5, 0xae },
-		{0xF9B6, 0x7e },
-		{0xF9B7, 0xaf },
-		{0xF9B8, 0x7f },
-		{0xF9B9, 0x90 },
-		{0xF9BA, 0xa0 },
-		{0xF9BB, 0xf8 },
-		{0xF9BC, 0xee },
-		{0xF9BD, 0xf0 },
-		{0xF9BE, 0xa3 },
-		{0xF9BF, 0xef },
-		{0xF9C0, 0xf0 },
-		{0xF9C1, 0x22 },
-		{0xF9C2, 0x90 },
-		{0xF9C3, 0x33 },
-		{0xF9C4, 0x82 },
-		{0xF9C5, 0xe0 },
-		{0xF9C6, 0xff },
-		{0xF9C7, 0x64 },
-		{0xF9C8, 0x01 },
-		{0xF9C9, 0x70 },
-		{0xF9CA, 0x30 },
-		{0xF9CB, 0xe5 },
-		{0xF9CC, 0x7f },
-		{0xF9CD, 0x64 },
-		{0xF9CE, 0x02 },
-		{0xF9CF, 0x45 },
-		{0xF9D0, 0x7e },
-		{0xF9D1, 0x70 },
-		{0xF9D2, 0x04 },
-		{0xF9D3, 0x7d },
-		{0xF9D4, 0x1e },
-		{0xF9D5, 0x80 },
-		{0xF9D6, 0x1d },
-		{0xF9D7, 0xe5 },
-		{0xF9D8, 0x7f },
-		{0xF9D9, 0x64 },
-		{0xF9DA, 0x03 },
-		{0xF9DB, 0x45 },
-		{0xF9DC, 0x7e },
-		{0xF9DD, 0x70 },
-		{0xF9DE, 0x04 },
-		{0xF9DF, 0x7d },
-		{0xF9E0, 0x3c },
-		{0xF9E1, 0x80 },
-		{0xF9E2, 0x11 },
-		{0xF9E3, 0xe5 },
-		{0xF9E4, 0x7f },
-		{0xF9E5, 0x64 },
-		{0xF9E6, 0x04 },
-		{0xF9E7, 0x45 },
-		{0xF9E8, 0x7e },
-		{0xF9E9, 0x70 },
-		{0xF9EA, 0x04 },
-		{0xF9EB, 0x7d },
-		{0xF9EC, 0xfa },
-		{0xF9ED, 0x80 },
-		{0xF9EE, 0x05 },
-		{0xF9EF, 0x90 },
-		{0xF9F0, 0x33 },
-		{0xF9F1, 0x81 },
-		{0xF9F2, 0xe0 },
-		{0xF9F3, 0xfd },
-		{0xF9F4, 0xae },
-		{0xF9F5, 0x05 },
-		{0xF9F6, 0x90 },
-		{0xF9F7, 0x33 },
-		{0xF9F8, 0x81 },
-		{0xF9F9, 0xed },
-		{0xF9FA, 0xf0 },
-		{0xF9FB, 0xef },
-		{0xF9FC, 0xb4 },
-		{0xF9FD, 0x01 },
-		{0xF9FE, 0x10 },
-		{0xF9FF, 0x90 },
-		{0xFA00, 0x01 },
-		{0xFA01, 0x00 },
-		{0xFA02, 0xe0 },
-		{0xFA03, 0x60 },
-		{0xFA04, 0x0a },
-		{0xFA05, 0x90 },
-		{0xFA06, 0xa1 },
-		{0xFA07, 0x10 },
-		{0xFA08, 0xe0 },
-		{0xFA09, 0xf5 },
-		{0xFA0A, 0x7e },
-		{0xFA0B, 0xa3 },
-		{0xFA0C, 0xe0 },
-		{0xFA0D, 0xf5 },
-		{0xFA0E, 0x7f },
-		{0xFA0F, 0x22 },
-		{0xFA10, 0x12 },
-		{0xFA11, 0x2f },
-		{0xFA12, 0x4d },
-		{0xFA13, 0x90 },
-		{0xFA14, 0x35 },
-		{0xFA15, 0x38 },
-		{0xFA16, 0xe0 },
-		{0xFA17, 0x70 },
-		{0xFA18, 0x05 },
-		{0xFA19, 0x12 },
-		{0xFA1A, 0x00 },
-		{0xFA1B, 0x0e },
-		{0xFA1C, 0x80 },
-		{0xFA1D, 0x03 },
-		{0xFA1E, 0x12 },
-		{0xFA1F, 0x07 },
-		{0xFA20, 0xc9 },
-		{0xFA21, 0x90 },
-		{0xFA22, 0x40 },
-		{0xFA23, 0x06 },
-		{0xFA24, 0xe0 },
-		{0xFA25, 0xf4 },
-		{0xFA26, 0x54 },
-		{0xFA27, 0x02 },
-		{0xFA28, 0xff },
-		{0xFA29, 0xe0 },
-		{0xFA2A, 0x54 },
-		{0xFA2B, 0x01 },
-		{0xFA2C, 0x4f },
-		{0xFA2D, 0x90 },
-		{0xFA2E, 0x31 },
-		{0xFA2F, 0x32 },
-		{0xFA30, 0xf0 },
-		{0xFA31, 0x90 },
-		{0xFA32, 0xfa },
-		{0xFA33, 0x9d },
-		{0xFA34, 0xe0 },
-		{0xFA35, 0x70 },
-		{0xFA36, 0x03 },
-		{0xFA37, 0x12 },
-		{0xFA38, 0x27 },
-		{0xFA39, 0x27 },
-		{0xFA3A, 0x02 },
-		{0xFA3B, 0x05 },
-		{0xFA3C, 0xac },
-		{0xFA3D, 0x22 },
-		{0xFA3E, 0xf0 },
-		{0xFA3F, 0xe5 },
-		{0xFA40, 0x3a },
-		{0xFA41, 0xb4 },
-		{0xFA42, 0x06 },
-		{0xFA43, 0x06 },
-		{0xFA44, 0x63 },
-		{0xFA45, 0x3e },
-		{0xFA46, 0x02 },
-		{0xFA47, 0x12 },
-		{0xFA48, 0x03 },
-		{0xFA49, 0xea },
-		{0xFA4A, 0x02 },
-		{0xFA4B, 0x17 },
-		{0xFA4C, 0x4a },
-		{0xFA4D, 0x22 },
-		{0x35C9, 0xFA },
-		{0x35CA, 0x01 },
-		{0x35CB, 0x67 },
-		{0x35CC, 0x01 },
-		{0x35CD, 0xC2 },
-		{0x35CE, 0x02 },
-		{0x35CF, 0x10 },
-		{0x35D0, 0x02 },
-		{0x35D1, 0x3E },
-		{0x35D3, 0xF6 },
-		{0x35D5, 0x07 },
-		{0x35D7, 0xA3 },
-		{0x35DB, 0x02 },
-		{0x35DD, 0x06 },
-		{0x35DF, 0x27 },
-		{0x35E6, 0x28 },
-		{0x35E7, 0x76 },
-		{0x35E8, 0x2A },
-		{0x35E9, 0x15 },
-		{0x35EA, 0x2D },
-		{0x35EB, 0x07 },
-		{0x35EC, 0x04 },
-		{0x35ED, 0x43 },
-		{0x35EE, 0x05 },
-		{0x35EF, 0xA9 },
-		{0x35F0, 0x17 },
-		{0x35F1, 0x41 },
-		{0x35F2, 0x24 },
-		{0x35F3, 0x88 },
-		{0x35F4, 0x01 },
-		{0x35F5, 0x54 },
-		{0x35F6, 0x01 },
-		{0x35F7, 0x55 },
-		{0x35F8, 0x2E },
-		{0x35F9, 0xF2 },
-		{0x35FA, 0x06 },
-		{0x35FB, 0x02 },
-		{0x35FC, 0x06 },
-		{0x35FD, 0x03 },
-		{0x35FE, 0x06 },
-		{0x35FF, 0x04 },
-		{0x3600, 0x0F },
-		{0x3601, 0x48 },
-		{0x3602, 0x0F },
-		{0x3603, 0x49 },
-		{0x3604, 0x0F },
-		{0x3605, 0x4A },
-		{0x35C2, 0xFF },
-		{0x35C3, 0xFF },
-		{0x35C4, 0xFF },
-		{0x35C5, 0xC0 },
-		{0x35C0, 0x01 },
-
-
-		{0xa098, 0x02 },
-		{0xa099, 0x87 },
-		{0xa09c, 0x00 },
-		{0xa09d, 0xc5 },
-		{0xa4ec, 0x05 },
-		{0xa4ed, 0x05 },
-		{0xa4f0, 0x04 },
-		{0xa4f1, 0x04 },
-		{0xa4f4, 0x04 },
-		{0xa4f5, 0x05 },
-		{0xa4f8, 0x05 },
-		{0xa4f9, 0x07 },
-		{0xa4fc, 0x07 },
-		{0xa4fd, 0x07 },
-		{0xa500, 0x07 },
-		{0xa501, 0x07 },
-		{0xa504, 0x08 },
-		{0xa505, 0x08 },
-		{0xa518, 0x01 },
-		{0xa519, 0x02 },
-		{0xa51c, 0x01 },
-		{0xa51d, 0x00 },
-		{0xa534, 0x00 },
-		{0xa535, 0x04 },
-		{0xa538, 0x04 },
-		{0xa539, 0x03 },
-		{0xa53c, 0x05 },
-		{0xa53d, 0x07 },
-		{0xa540, 0x07 },
-		{0xa541, 0x06 },
-		{0xa544, 0x07 },
-		{0xa545, 0x06 },
-		{0xa548, 0x05 },
-		{0xa549, 0x06 },
-		{0xa54c, 0x06 },
-		{0xa54d, 0x07 },
-		{0xa550, 0x07 },
-		{0xa551, 0x04 },
-		{0xa554, 0x04 },
-		{0xa555, 0x04 },
-		{0xa558, 0x05 },
-		{0xa559, 0x06 },
-		{0xa55c, 0x07 },
-		{0xa55d, 0x07 },
-		{0xa56c, 0x00 },
-		{0xa56d, 0x0a },
-		{0xa570, 0x08 },
-		{0xa571, 0x05 },
-		{0xa574, 0x04 },
-		{0xa575, 0x03 },
-		{0xa578, 0x04 },
-		{0xa579, 0x04 },
-		{0xa58c, 0x1f },
-		{0xa58d, 0x1b },
-		{0xa590, 0x17 },
-		{0xa591, 0x13 },
-		{0xa594, 0x10 },
-		{0xa595, 0x0d },
-		{0xa598, 0x0f },
-		{0xa599, 0x11 },
-		{0xa59c, 0x03 },
-		{0xa59d, 0x03 },
-		{0xa5a0, 0x03 },
-		{0xa5a1, 0x03 },
-		{0xa5a4, 0x03 },
-		{0xa5a5, 0x04 },
-		{0xa5a8, 0x05 },
-		{0xa5a9, 0x00 },
-		{0xa5ac, 0x00 },
-		{0xa5ad, 0x00 },
-		{0xa5b0, 0x00 },
-		{0xa5b1, 0x00 },
-		{0xa5b4, 0x00 },
-		{0xa5b5, 0x00 },
-		{0xa5c4, 0x1f },
-		{0xa5c5, 0x13 },
-		{0xa5c8, 0x14 },
-		{0xa5c9, 0x14 },
-		{0xa5cc, 0x14 },
-		{0xa5cd, 0x13 },
-		{0xa5d0, 0x17 },
-		{0xa5d1, 0x1a },
-		{0xa5f4, 0x05 },
-		{0xa5f5, 0x05 },
-		{0xa5f8, 0x05 },
-		{0xa5f9, 0x06 },
-		{0xa5fc, 0x06 },
-		{0xa5fd, 0x06 },
-		{0xa600, 0x06 },
-		{0xa601, 0x06 },
-		{0xa608, 0x07 },
-		{0xa609, 0x08 },
-		{0xa60c, 0x08 },
-		{0xa60d, 0x07 },
-		{0xa63c, 0x00 },
-		{0xa63d, 0x02 },
-		{0xa640, 0x02 },
-		{0xa641, 0x02 },
-		{0xa644, 0x02 },
-		{0xa645, 0x02 },
-		{0xa648, 0x03 },
-		{0xa649, 0x04 },
-		{0xa64c, 0x0a },
-		{0xa64d, 0x09 },
-		{0xa650, 0x08 },
-		{0xa651, 0x09 },
-		{0xa654, 0x09 },
-		{0xa655, 0x0a },
-		{0xa658, 0x0a },
-		{0xa659, 0x0a },
-		{0xa65c, 0x0a },
-		{0xa65d, 0x09 },
-		{0xa660, 0x09 },
-		{0xa661, 0x09 },
-		{0xa664, 0x09 },
-		{0xa665, 0x08 },
-		{0xa680, 0x01 },
-		{0xa681, 0x02 },
-		{0xa694, 0x1f },
-		{0xa695, 0x10 },
-		{0xa698, 0x0e },
-		{0xa699, 0x0c },
-		{0xa69c, 0x0d },
-		{0xa69d, 0x0d },
-		{0xa6a0, 0x0f },
-		{0xa6a1, 0x11 },
-		{0xa6a4, 0x00 },
-		{0xa6a5, 0x00 },
-		{0xa6a8, 0x00 },
-		{0xa6a9, 0x00 },
-		{0xa6ac, 0x00 },
-		{0xa6ad, 0x00 },
-		{0xa6b0, 0x00 },
-		{0xa6b1, 0x04 },
-		{0xa6b4, 0x04 },
-		{0xa6b5, 0x04 },
-		{0xa6b8, 0x04 },
-		{0xa6b9, 0x04 },
-		{0xa6bc, 0x05 },
-		{0xa6bd, 0x05 },
-		{0xa6c0, 0x1f },
-		{0xa6c1, 0x1f },
-		{0xa6c4, 0x1f },
-		{0xa6c5, 0x1f },
-		{0xa6c8, 0x1f },
-		{0xa6c9, 0x1f },
-		{0xa6cc, 0x1f },
-		{0xa6cd, 0x0b },
-		{0xa6d0, 0x0c },
-		{0xa6d1, 0x0d },
-		{0xa6d4, 0x0d },
-		{0xa6d5, 0x0d },
-		{0xa6d8, 0x11 },
-		{0xa6d9, 0x14 },
-		{0xa6fc, 0x02 },
-		{0xa6fd, 0x03 },
-		{0xa700, 0x03 },
-		{0xa701, 0x03 },
-		{0xa704, 0x03 },
-		{0xa705, 0x04 },
-		{0xa708, 0x05 },
-		{0xa709, 0x02 },
-		{0xa70c, 0x02 },
-		{0xa70d, 0x02 },
-		{0xa710, 0x03 },
-		{0xa711, 0x04 },
-		{0xa714, 0x04 },
-		{0xa715, 0x04 },
-		{0xa744, 0x00 },
-		{0xa745, 0x03 },
-		{0xa748, 0x04 },
-		{0xa749, 0x04 },
-		{0xa74c, 0x05 },
-		{0xa74d, 0x06 },
-		{0xa750, 0x07 },
-		{0xa751, 0x07 },
-		{0xa754, 0x05 },
-		{0xa755, 0x05 },
-		{0xa758, 0x05 },
-		{0xa759, 0x05 },
-		{0xa75c, 0x05 },
-		{0xa75d, 0x06 },
-		{0xa760, 0x07 },
-		{0xa761, 0x07 },
-		{0xa764, 0x06 },
-		{0xa765, 0x05 },
-		{0xa768, 0x05 },
-		{0xa769, 0x05 },
-		{0xa76c, 0x06 },
-		{0xa76d, 0x07 },
-		{0xa77c, 0x00 },
-		{0xa77d, 0x05 },
-		{0xa780, 0x05 },
-		{0xa781, 0x05 },
-		{0xa784, 0x05 },
-		{0xa785, 0x04 },
-		{0xa788, 0x05 },
-		{0xa789, 0x06 },
-		{0xa79c, 0x1f },
-		{0xa79d, 0x15 },
-		{0xa7a0, 0x13 },
-		{0xa7a1, 0x10 },
-		{0xa7a4, 0x0f },
-		{0xa7a5, 0x0d },
-		{0xa7a8, 0x11 },
-		{0xa7a9, 0x14 },
-		{0xa7ac, 0x02 },
-		{0xa7ad, 0x02 },
-		{0xa7b0, 0x02 },
-		{0xa7b1, 0x02 },
-		{0xa7b4, 0x02 },
-		{0xa7b5, 0x03 },
-		{0xa7b8, 0x03 },
-		{0xa7b9, 0x00 },
-		{0xa7bc, 0x00 },
-		{0xa7bd, 0x00 },
-		{0xa7c0, 0x00 },
-		{0xa7c1, 0x00 },
-		{0xa7c4, 0x00 },
-		{0xa7c5, 0x00 },
-		{0xa7d4, 0x1f },
-		{0xa7d5, 0x0d },
-		{0xa7d8, 0x0f },
-		{0xa7d9, 0x10 },
-		{0xa7dc, 0x10 },
-		{0xa7dd, 0x10 },
-		{0xa7e0, 0x13 },
-		{0xa7e1, 0x16 },
-		{0xa7f4, 0x00 },
-		{0xa7f5, 0x03 },
-		{0xa7f8, 0x04 },
-		{0xa7f9, 0x04 },
-		{0xa7fc, 0x04 },
-		{0xa7fd, 0x03 },
-		{0xa800, 0x03 },
-		{0xa801, 0x03 },
-		{0xa804, 0x03 },
-		{0xa805, 0x03 },
-		{0xa808, 0x03 },
-		{0xa809, 0x03 },
-		{0xa80c, 0x03 },
-		{0xa80d, 0x04 },
-		{0xa810, 0x04 },
-		{0xa811, 0x0a },
-		{0xa814, 0x0a },
-		{0xa815, 0x0a },
-		{0xa818, 0x0f },
-		{0xa819, 0x14 },
-		{0xa81c, 0x14 },
-		{0xa81d, 0x14 },
-		{0xa82c, 0x00 },
-		{0xa82d, 0x04 },
-		{0xa830, 0x02 },
-		{0xa831, 0x00 },
-		{0xa834, 0x00 },
-		{0xa835, 0x00 },
-		{0xa838, 0x00 },
-		{0xa839, 0x00 },
-		{0xa840, 0x1f },
-		{0xa841, 0x1f },
-		{0xa848, 0x1f },
-		{0xa849, 0x1f },
-		{0xa84c, 0x1f },
-		{0xa84d, 0x0c },
-		{0xa850, 0x0c },
-		{0xa851, 0x0c },
-		{0xa854, 0x0c },
-		{0xa855, 0x0c },
-		{0xa858, 0x0c },
-		{0xa859, 0x0c },
-		{0xa85c, 0x0c },
-		{0xa85d, 0x0c },
-		{0xa860, 0x0c },
-		{0xa861, 0x0c },
-		{0xa864, 0x0c },
-		{0xa865, 0x0c },
-		{0xa868, 0x0c },
-		{0xa869, 0x0c },
-		{0xa86c, 0x0c },
-		{0xa86d, 0x0c },
-		{0xa870, 0x0c },
-		{0xa871, 0x0c },
-		{0xa874, 0x0c },
-		{0xa875, 0x0c },
-		{0xa878, 0x1f },
-		{0xa879, 0x1f },
-		{0xa87c, 0x1f },
-		{0xa87d, 0x1f },
-		{0xa880, 0x1f },
-		{0xa881, 0x1f },
-		{0xa884, 0x1f },
-		{0xa885, 0x0c },
-		{0xa888, 0x0c },
-		{0xa889, 0x0c },
-		{0xa88c, 0x0c },
-		{0xa88d, 0x0c },
-		{0xa890, 0x0c },
-		{0xa891, 0x0c },
-		{0xa898, 0x1f },
-		{0xa899, 0x1f },
-		{0xa8a0, 0x1f },
-		{0xa8a1, 0x1f },
-		{0xa8a4, 0x1f },
-		{0xa8a5, 0x0c },
-		{0xa8a8, 0x0c },
-		{0xa8a9, 0x0c },
-		{0xa8ac, 0x0c },
-		{0xa8ad, 0x0c },
-		{0xa8b0, 0x0c },
-		{0xa8b1, 0x0c },
-		{0xa8b4, 0x0c },
-		{0xa8b5, 0x0c },
-		{0xa8b8, 0x0c },
-		{0xa8b9, 0x0c },
-		{0xa8bc, 0x0c },
-		{0xa8bd, 0x0c },
-		{0xa8c0, 0x0c },
-		{0xa8c1, 0x0c },
-		{0xa8c4, 0x0c },
-		{0xa8c5, 0x0c },
-		{0xa8c8, 0x0c },
-		{0xa8c9, 0x0c },
-		{0xa8cc, 0x0c },
-		{0xa8cd, 0x0c },
-		{0xa8d0, 0x1f },
-		{0xa8d1, 0x1f },
-		{0xa8d4, 0x1f },
-		{0xa8d5, 0x1f },
-		{0xa8d8, 0x1f },
-		{0xa8d9, 0x1f },
-		{0xa8dc, 0x1f },
-		{0xa8dd, 0x0c },
-		{0xa8e0, 0x0c },
-		{0xa8e1, 0x0c },
-		{0xa8e4, 0x0c },
-		{0xa8e5, 0x0c },
-		{0xa8e8, 0x0c },
-		{0xa8e9, 0x0c },
-		{0xa8f0, 0x1f },
-		{0xa8f1, 0x1f },
-		{0xa8f8, 0x1f },
-		{0xa8f9, 0x1f },
-		{0xa8fc, 0x1f },
-		{0xa8fd, 0x0c },
-		{0xa900, 0x0c },
-		{0xa901, 0x0c },
-		{0xa904, 0x0c },
-		{0xa905, 0x0c },
-		{0xa908, 0x0c },
-		{0xa909, 0x0c },
-		{0xa90c, 0x0c },
-		{0xa90d, 0x0c },
-		{0xa910, 0x0c },
-		{0xa911, 0x0c },
-		{0xa914, 0x0c },
-		{0xa915, 0x0c },
-		{0xa918, 0x0c },
-		{0xa919, 0x0c },
-		{0xa91c, 0x0c },
-		{0xa91d, 0x0c },
-		{0xa920, 0x0c },
-		{0xa921, 0x0c },
-		{0xa924, 0x0c },
-		{0xa925, 0x0c },
-		{0xa928, 0x1f },
-		{0xa929, 0x1f },
-		{0xa92c, 0x1f },
-		{0xa92d, 0x1f },
-		{0xa930, 0x1f },
-		{0xa931, 0x1f },
-		{0xa934, 0x1f },
-		{0xa935, 0x0c },
-		{0xa938, 0x0c },
-		{0xa939, 0x0c },
-		{0xa93c, 0x0c },
-		{0xa93d, 0x0c },
-		{0xa940, 0x0c },
-		{0xa941, 0x0c },
-		{0xa96c, 0x0d },
-		{0xa96d, 0x16 },
-		{0xa970, 0x19 },
-		{0xa971, 0x0e },
-		{0xa974, 0x16 },
-		{0xa975, 0x1a },
-		{0xa978, 0x0d },
-		{0xa979, 0x15 },
-		{0xa97c, 0x19 },
-		{0xa97d, 0x0d },
-		{0xa980, 0x15 },
-		{0xa981, 0x1a },
-		{0xa984, 0x0d },
-		{0xa985, 0x15 },
-		{0xa988, 0x1a },
-		{0xa989, 0x0d },
-		{0xa98c, 0x15 },
-		{0xa98d, 0x1a },
-		{0xa990, 0x0b },
-		{0xa991, 0x11 },
-		{0xa994, 0x02 },
-		{0xa995, 0x0e },
-		{0xa998, 0x16 },
-		{0xa999, 0x02 },
-		{0xa99c, 0x0c },
-		{0xa99d, 0x13 },
-		{0xa9a0, 0x02 },
-		{0xa9a1, 0x0c },
-		{0xa9a4, 0x12 },
-		{0xa9a5, 0x02 },
-		{0xa9a8, 0x0c },
-		{0xa9a9, 0x12 },
-		{0xa9ac, 0x02 },
-		{0xa9ad, 0x0c },
-		{0xa9b0, 0x12 },
-		{0xa9b1, 0x02 },
-		{0xa9b4, 0x10 },
-		{0xa9b5, 0x1e },
-		{0xa9b8, 0x0f },
-		{0xa9b9, 0x13 },
-		{0xa9bc, 0x20 },
-		{0xa9bd, 0x10 },
-		{0xa9c0, 0x11 },
-		{0xa9c1, 0x1e },
-		{0xa9c4, 0x10 },
-		{0xa9c5, 0x11 },
-		{0xa9c8, 0x1e },
-		{0xa9c9, 0x10 },
-		{0xa9cc, 0x11 },
-		{0xa9cd, 0x20 },
-		{0xa9d0, 0x10 },
-		{0xa9d1, 0x13 },
-		{0xa9d4, 0x24 },
-		{0xa9d5, 0x10 },
-		{0xa9f0, 0x02 },
-		{0xa9f1, 0x01 },
-		{0xa9f8, 0x19 },
-		{0xa9f9, 0x0b },
-		{0xa9fc, 0x0a },
-		{0xa9fd, 0x07 },
-		{0xaa00, 0x0c },
-		{0xaa01, 0x0e },
-		{0xaa08, 0x0c },
-		{0xaa09, 0x06 },
-		{0xaa0c, 0x0c },
-		{0xaa0d, 0x0a },
-		{0xaa24, 0x10 },
-		{0xaa25, 0x12 },
-		{0xaa28, 0x0b },
-		{0xaa29, 0x07 },
-		{0xaa2c, 0x10 },
-		{0xaa2d, 0x14 },
-		{0xaa34, 0x0e },
-		{0xaa35, 0x0e },
-		{0xaa38, 0x07 },
-		{0xaa39, 0x07 },
-		{0xaa3c, 0x0e },
-		{0xaa3d, 0x0c },
-		{0xaa48, 0x09 },
-		{0xaa49, 0x0c },
-		{0xaa4c, 0x0c },
-		{0xaa4d, 0x07 },
-		{0xaa54, 0x08 },
-		{0xaa55, 0x06 },
-		{0xaa58, 0x04 },
-		{0xaa59, 0x05 },
-		{0xaa5c, 0x06 },
-		{0xaa5d, 0x06 },
-		{0xaa68, 0x05 },
-		{0xaa69, 0x05 },
-		{0xaa6c, 0x04 },
-		{0xaa6d, 0x05 },
-		{0xaa74, 0x06 },
-		{0xaa75, 0x04 },
-		{0xaa78, 0x05 },
-		{0xaa79, 0x05 },
-		{0xaa7c, 0x04 },
-		{0xaa7d, 0x06 },
-		{0xac18, 0x14 },
-		{0xac19, 0x00 },
-		{0xac1c, 0x14 },
-		{0xac1d, 0x00 },
-		{0xac20, 0x14 },
-		{0xac21, 0x00 },
-		{0xac24, 0x14 },
-		{0xac25, 0x00 },
-		{0xac28, 0x14 },
-		{0xac29, 0x00 },
-		{0xac2c, 0x14 },
-		{0xac2d, 0x00 },
-		{0xac34, 0x16 },
-		{0xac35, 0x00 },
-		{0xac38, 0x16 },
-		{0xac39, 0x00 },
-		{0xac3c, 0x16 },
-		{0xac3d, 0x00 },
-		{0xac40, 0x16 },
-		{0xac41, 0x00 },
-		{0xac44, 0x16 },
-		{0xac45, 0x00 },
-		{0xac48, 0x16 },
-		{0xac49, 0x00 },
-		{0xac50, 0x1b },
-		{0xac51, 0x00 },
-		{0xac54, 0x1b },
-		{0xac55, 0x00 },
-		{0xac58, 0x1b },
-		{0xac59, 0x00 },
-		{0xac5c, 0x1b },
-		{0xac5d, 0x00 },
-		{0xac60, 0x1b },
-		{0xac61, 0x00 },
-		{0xac64, 0x1b },
-		{0xac65, 0x00 },
-		{0xac74, 0x09 },
-		{0xac75, 0x0c },
-		{0xac78, 0x0f },
-		{0xac79, 0x11 },
-		{0xac7c, 0x12 },
-		{0xac7d, 0x14 },
-		{0xac80, 0x09 },
-		{0xac81, 0x0c },
-		{0xac84, 0x0f },
-		{0xac85, 0x11 },
-		{0xac88, 0x12 },
-		{0xac89, 0x14 },
-		{0xac8c, 0x09 },
-		{0xac8d, 0x0c },
-		{0xac90, 0x0f },
-		{0xac91, 0x11 },
-		{0xac94, 0x12 },
-		{0xac95, 0x14 },
-		{0xac98, 0x09 },
-		{0xac99, 0x0c },
-		{0xac9c, 0x0f },
-		{0xac9d, 0x11 },
-		{0xaca0, 0x12 },
-		{0xaca1, 0x14 },
-		{0xaca4, 0x09 },
-		{0xaca5, 0x0c },
-		{0xaca8, 0x0f },
-		{0xaca9, 0x11 },
-		{0xacac, 0x12 },
-		{0xacad, 0x14 },
-		{0xacb0, 0x07 },
-		{0xacb1, 0x09 },
-		{0xacb4, 0x0c },
-		{0xacb5, 0x0d },
-		{0xacb8, 0x0d },
-		{0xacb9, 0x0e },
-		{0xacbc, 0x05 },
-		{0xacbd, 0x07 },
-		{0xacc0, 0x0a },
-		{0xacc1, 0x0b },
-		{0xacc4, 0x0b },
-		{0xacc5, 0x0c },
-		{0xacc8, 0x03 },
-		{0xacc9, 0x04 },
-		{0xaccc, 0x07 },
-		{0xaccd, 0x08 },
-		{0xacd0, 0x09 },
-		{0xacd1, 0x09 },
-		{0x35B5, 0x01 },
-		{0x35BC, 0x01 },
-		{0x360A, 0x02 },
-		{0xFA9B, 0x01 },
-};
-
-#define NUM_LSC_CAST_REGS      33
-
-enum LSC_Cast_t{
-	cast_H = 0,
-	cast_U30,
-	cast_CW,
-	cast_D,
-	cast_MAX
-};
-
-static short int LSC_CorrectionForCast[cast_MAX][NUM_LSC_CAST_REGS] = {
-	{-30, -20,  8, 11, -16, -26, -35, -53, -9, -10, 44, 57, -39,
-		-14, 50, -173, -38, -32, -1, 9, 39, 51, -33, -49, -28,
-		-22, 7, 11, -21, 17, -62, -56, 0},
-	{-29, -18,  6,  1,  17, -35, -77, 0, 5, -17, -6, -22, -41, -1,
-		-37, 83, -38, -32, 1, -2, 15, 25, -67, 19, -28, -22, 5,
-		2, -18, 21, -86, 0, 0},
-	{-10, -15, -4, -6,  -8,  -3, -63, 8, 25, -9, -39, -51, -9,
-		0, -21, 112, -10, -23, -7, -9, 10, 18, -11, 23, -10,
-		-15, -4, -6, -10, -3, -52, 7, 0},
-	{  5,   3, -4, -5,  -1,   3,   4, 8, 12, 3, -22, -21, 7, 17,
-		2, 35, 8, 2, -3, -2, -9, -5, 10, 4, 9, 2, -4, -5,
-		-2, 0, -6, 9, 0}
-};
-
-static unsigned short LSC_CastRegs[] = {
-	0xFB7E,			/* H   */
-	0xFB3C,			/* U30 */
-	0xFAFA,			/* CW  */
-	0xFAB8			/* D65 */
-};
-
-/*=============================================================*/
-
-static int vx6953_i2c_rxdata(unsigned short saddr,
-	unsigned char *rxdata, int length)
-{
-	struct i2c_msg msgs[] = {
-		{
-			.addr  = saddr,
-			.flags = 0,
-			.len   = 2,
-			.buf   = rxdata,
-		},
-		{
-			.addr  = saddr,
-			.flags = I2C_M_RD,
-			.len   = 2,
-			.buf   = rxdata,
-		},
-	};
-	if (i2c_transfer(vx6953_client->adapter, msgs, 2) < 0) {
-		CDBG("vx6953_i2c_rxdata failed!\n");
-		return -EIO;
-	}
-	return 0;
-}
-static int32_t vx6953_i2c_txdata(unsigned short saddr,
-				unsigned char *txdata, int length)
-{
-	struct i2c_msg msg[] = {
-		{
-			.addr = saddr,
-			.flags = 0,
-			.len = length,
-			.buf = txdata,
-		 },
-	};
-	if (i2c_transfer(vx6953_client->adapter, msg, 1) < 0) {
-		CDBG("vx6953_i2c_txdata faild 0x%x\n", vx6953_client->addr);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-
-static int32_t vx6953_i2c_read(unsigned short raddr,
-	unsigned short *rdata, int rlen)
-{
-	int32_t rc = 0;
-	unsigned char buf[2];
-	if (!rdata)
-		return -EIO;
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (raddr & 0xFF00) >> 8;
-	buf[1] = (raddr & 0x00FF);
-	rc = vx6953_i2c_rxdata(vx6953_client->addr>>1, buf, rlen);
-	if (rc < 0) {
-		CDBG("vx6953_i2c_read 0x%x failed!\n", raddr);
-		return rc;
-	}
-	*rdata = (rlen == 2 ? buf[0] << 8 | buf[1] : buf[0]);
-	return rc;
-}
-static int32_t vx6953_i2c_write_b_sensor(unsigned short waddr, uint8_t bdata)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[3];
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (waddr & 0xFF00) >> 8;
-	buf[1] = (waddr & 0x00FF);
-	buf[2] = bdata;
-	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
-	rc = vx6953_i2c_txdata(vx6953_client->addr>>1, buf, 3);
-	if (rc < 0) {
-		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
-			waddr, bdata);
-	}
-	return rc;
-}
-static int32_t vx6953_i2c_write_w_sensor(unsigned short waddr, uint16_t wdata)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[4];
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (waddr & 0xFF00) >> 8;
-	buf[1] = (waddr & 0x00FF);
-	buf[2] = (wdata & 0xFF00) >> 8;
-	buf[3] = (wdata & 0x00FF);
-	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, wdata);
-	rc = vx6953_i2c_txdata(vx6953_client->addr>>1, buf, 4);
-	if (rc < 0) {
-		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
-			waddr, wdata);
-	}
-	return rc;
-}
-static int32_t vx6953_i2c_write_seq_sensor(unsigned short waddr,
-	uint8_t *bdata, uint16_t len)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[len+2];
-	int i;
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (waddr & 0xFF00) >> 8;
-	buf[1] = (waddr & 0x00FF);
-	for (i = 2; i < len+2; i++)
-		buf[i] = *bdata++;
-	rc = vx6953_i2c_txdata(vx6953_client->addr>>1, buf, len+2);
-	if (rc < 0) {
-		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
-			 waddr, bdata[0]);
-	}
-	return rc;
-}
-
-static int32_t vx6953_i2c_write_w_table(struct vx6953_i2c_reg_conf const
-					 *reg_conf_tbl, int num)
-{
-	int i;
-	int32_t rc = -EIO;
-	for (i = 0; i < num; i++) {
-		rc = vx6953_i2c_write_b_sensor(reg_conf_tbl->waddr,
-			reg_conf_tbl->wdata);
-		if (rc < 0)
-			break;
-		reg_conf_tbl++;
-	}
-	return rc;
-}
-
-static void vx6953_get_pict_fps(uint16_t fps, uint16_t *pfps)
-{
-	/* input fps is preview fps in Q8 format */
-	uint16_t preview_frame_length_lines, snapshot_frame_length_lines;
-	uint16_t preview_line_length_pck, snapshot_line_length_pck;
-	uint32_t divider, d1, d2;
-	/* Total frame_length_lines and line_length_pck for preview */
-	preview_frame_length_lines = VX6953_QTR_SIZE_HEIGHT +
-		VX6953_VER_QTR_BLK_LINES;
-	preview_line_length_pck = VX6953_QTR_SIZE_WIDTH +
-		VX6953_HRZ_QTR_BLK_PIXELS;
-	/* Total frame_length_lines and line_length_pck for snapshot */
-	snapshot_frame_length_lines = VX6953_FULL_SIZE_HEIGHT +
-		VX6953_VER_FULL_BLK_LINES;
-	snapshot_line_length_pck = VX6953_FULL_SIZE_WIDTH +
-		VX6953_HRZ_FULL_BLK_PIXELS;
-	d1 = preview_frame_length_lines * 0x00000400/
-		snapshot_frame_length_lines;
-	d2 = preview_line_length_pck * 0x00000400/
-		snapshot_line_length_pck;
-	divider = d1 * d2 / 0x400;
-	/*Verify PCLK settings and frame sizes.*/
-	*pfps = (uint16_t) (fps * divider / 0x400);
-	/* 2 is the ratio of no.of snapshot channels
-	to number of preview channels */
-
-}
-
-static uint16_t vx6953_get_prev_lines_pf(void)
-{
-	if (vx6953_ctrl->prev_res == QTR_SIZE)
-		return VX6953_QTR_SIZE_HEIGHT + VX6953_VER_QTR_BLK_LINES;
-	else
-		return VX6953_FULL_SIZE_HEIGHT + VX6953_VER_FULL_BLK_LINES;
-
-}
-
-static uint16_t vx6953_get_prev_pixels_pl(void)
-{
-	if (vx6953_ctrl->prev_res == QTR_SIZE)
-		return VX6953_QTR_SIZE_WIDTH + VX6953_HRZ_QTR_BLK_PIXELS;
-	else
-		return VX6953_FULL_SIZE_WIDTH + VX6953_HRZ_FULL_BLK_PIXELS;
-}
-
-static uint16_t vx6953_get_pict_lines_pf(void)
-{
-		if (vx6953_ctrl->pict_res == QTR_SIZE)
-			return VX6953_QTR_SIZE_HEIGHT +
-				VX6953_VER_QTR_BLK_LINES;
-		else
-			return VX6953_FULL_SIZE_HEIGHT +
-				VX6953_VER_FULL_BLK_LINES;
-}
-
-static uint16_t vx6953_get_pict_pixels_pl(void)
-{
-	if (vx6953_ctrl->pict_res == QTR_SIZE)
-		return VX6953_QTR_SIZE_WIDTH +
-			VX6953_HRZ_QTR_BLK_PIXELS;
-	else
-		return VX6953_FULL_SIZE_WIDTH +
-			VX6953_HRZ_FULL_BLK_PIXELS;
-}
-
-static uint32_t vx6953_get_pict_max_exp_lc(void)
-{
-	if (vx6953_ctrl->pict_res == QTR_SIZE)
-		return (VX6953_QTR_SIZE_HEIGHT +
-			VX6953_VER_QTR_BLK_LINES)*24;
-	else
-		return (VX6953_FULL_SIZE_HEIGHT +
-			VX6953_VER_FULL_BLK_LINES)*24;
-}
-
-static int32_t vx6953_set_fps(struct fps_cfg	*fps)
-{
-	uint16_t total_lines_per_frame;
-	int32_t rc = 0;
-	total_lines_per_frame = (uint16_t)((VX6953_QTR_SIZE_HEIGHT +
-		VX6953_VER_QTR_BLK_LINES) * vx6953_ctrl->fps_divider/0x400);
-
-	vx6953_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
-		GROUPED_PARAMETER_HOLD);
-	if (vx6953_i2c_write_b_sensor(REG_FRAME_LENGTH_LINES_HI,
-		((total_lines_per_frame & 0xFF00) >> 8)) < 0)
-		return rc;
-	if (vx6953_i2c_write_b_sensor(REG_FRAME_LENGTH_LINES_LO,
-		(total_lines_per_frame & 0x00FF)) < 0)
-		return rc;
-	vx6953_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
-		GROUPED_PARAMETER_HOLD_OFF);
-	return rc;
-}
-
-static int32_t vx6953_write_exp_gain(uint16_t gain, uint32_t line)
-{
-	uint16_t line_length_pck, frame_length_lines;
-	uint8_t gain_hi, gain_lo;
-	uint8_t intg_time_hi, intg_time_lo;
-	uint8_t frame_length_lines_hi = 0, frame_length_lines_lo = 0;
-	int32_t rc = 0;
-	if (vx6953_ctrl->sensormode != SENSOR_SNAPSHOT_MODE) {
-		frame_length_lines = VX6953_QTR_SIZE_HEIGHT +
-		VX6953_VER_QTR_BLK_LINES;
-		line_length_pck = VX6953_QTR_SIZE_WIDTH +
-			VX6953_HRZ_QTR_BLK_PIXELS;
-		if (line > (frame_length_lines -
-			VX6953_STM5M0EDOF_OFFSET)) {
-			vx6953_ctrl->fps = (uint16_t) (30 * Q8 *
-			(frame_length_lines - VX6953_STM5M0EDOF_OFFSET)/
-			line);
-		} else {
-			vx6953_ctrl->fps = (uint16_t) (30 * Q8);
-		}
-	} else {
-		frame_length_lines = VX6953_FULL_SIZE_HEIGHT +
-				VX6953_VER_FULL_BLK_LINES;
-		line_length_pck = VX6953_FULL_SIZE_WIDTH +
-				VX6953_HRZ_FULL_BLK_PIXELS;
-	}
-
-	vx6953_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
-		GROUPED_PARAMETER_HOLD);
-	if ((line + VX6953_STM5M0EDOF_OFFSET) > MAX_FRAME_LENGTH_LINES) {
-		frame_length_lines = MAX_FRAME_LENGTH_LINES;
-		line = MAX_FRAME_LENGTH_LINES - VX6953_STM5M0EDOF_OFFSET;
-	} else if ((line + VX6953_STM5M0EDOF_OFFSET) > frame_length_lines) {
-		frame_length_lines = line + VX6953_STM5M0EDOF_OFFSET;
-		line = frame_length_lines;
-	}
-
-	frame_length_lines_hi = (uint8_t) ((frame_length_lines &
-		0xFF00) >> 8);
-	frame_length_lines_lo = (uint8_t) (frame_length_lines &
-		0x00FF);
-	vx6953_i2c_write_b_sensor(REG_FRAME_LENGTH_LINES_HI,
-		frame_length_lines_hi);
-	vx6953_i2c_write_b_sensor(REG_FRAME_LENGTH_LINES_LO,
-		frame_length_lines_lo);
-
-	/* update analogue gain registers */
-	gain_hi = (uint8_t) ((gain & 0xFF00) >> 8);
-	gain_lo = (uint8_t) (gain & 0x00FF);
-	vx6953_i2c_write_b_sensor(REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
-		gain_lo);
-	vx6953_i2c_write_b_sensor(REG_DIGITAL_GAIN_GREEN_R_LO, gain_hi);
-	vx6953_i2c_write_b_sensor(REG_DIGITAL_GAIN_RED_LO, gain_hi);
-	vx6953_i2c_write_b_sensor(REG_DIGITAL_GAIN_BLUE_LO, gain_hi);
-	vx6953_i2c_write_b_sensor(REG_DIGITAL_GAIN_GREEN_B_LO, gain_hi);
-	CDBG("%s, gain_hi 0x%x, gain_lo 0x%x\n", __func__,
-		gain_hi, gain_lo);
-	/* update line count registers */
-	intg_time_hi = (uint8_t) (((uint16_t)line & 0xFF00) >> 8);
-	intg_time_lo = (uint8_t) ((uint16_t)line & 0x00FF);
-	vx6953_i2c_write_b_sensor(REG_COARSE_INTEGRATION_TIME_HI,
-		intg_time_hi);
-	vx6953_i2c_write_b_sensor(REG_COARSE_INTEGRATION_TIME_LO,
-		intg_time_lo);
-	vx6953_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
-		GROUPED_PARAMETER_HOLD_OFF);
-
-	return rc;
-}
-
-static int32_t vx6953_set_pict_exp_gain(uint16_t gain, uint32_t line)
-{
-	int32_t rc = 0;
-	rc = vx6953_write_exp_gain(gain, line);
-	return rc;
-} /* endof vx6953_set_pict_exp_gain*/
-
-static int32_t vx6953_move_focus(int direction,
-	int32_t num_steps)
-{
-	return 0;
-}
-
-
-static int32_t vx6953_set_default_focus(uint8_t af_step)
-{
-	return 0;
-}
-
-static int32_t vx6953_test(enum vx6953_test_mode_t mo)
-{
-	int32_t rc = 0;
-	if (mo == TEST_OFF)
-		return rc;
-	else {
-		/* REG_0x30D8[4] is TESBYPEN: 0: Normal Operation,
-		1: Bypass Signal Processing
-		REG_0x30D8[5] is EBDMASK: 0:
-		Output Embedded data, 1: No output embedded data */
-		if (vx6953_i2c_write_b_sensor(REG_TEST_PATTERN_MODE,
-			(uint8_t) mo) < 0) {
-			return rc;
-		}
-	}
-	return rc;
-}
-
-static int vx6953_enable_edof(enum edof_mode_t edof_mode)
-{
-	int rc = 0;
-	if (edof_mode == VX6953_EDOF_ESTIMATION) {
-		/* EDof Estimation mode for preview */
-		if (vx6953_i2c_write_b_sensor(REG_0x0b80, 0x02) < 0)
-			return rc;
-		CDBG("VX6953_EDOF_ESTIMATION");
-	} else if (edof_mode == VX6953_EDOF_APPLICATION) {
-		/* EDof Application mode for Capture */
-		if (vx6953_i2c_write_b_sensor(REG_0x0b80, 0x01) < 0)
-			return rc;
-		CDBG("VX6953_EDOF_APPLICATION");
-	} else {
-		/* EDOF disabled */
-		if (vx6953_i2c_write_b_sensor(REG_0x0b80, 0x00) < 0)
-			return rc;
-		CDBG("VX6953_EDOF_DISABLE");
-	}
-	return rc;
-}
-
-static int32_t vx6953_patch_for_cut2(void)
-{
-	int32_t rc = 0;
-	rc = vx6953_i2c_write_w_table(patch_tbl_cut2,
-		ARRAY_SIZE(patch_tbl_cut2));
-	if (rc < 0)
-		return rc;
-
-	return rc;
-}
-
-static int32_t vx6953_lsc_patch(void)
-{
-	int32_t rc = 0;
-	int i, j;
-	short int  v;
-	unsigned short version = 0;
-	unsigned short LSC_Raw[NUM_LSC_CAST_REGS];
-	unsigned short LSC_Fixed[NUM_LSC_CAST_REGS];
-
-	vx6953_i2c_read(0x10, &version, 1);
-	CDBG("Cut 3 Version %d\n", version);
-	if (version != 1)
-		return 0;
-
-	vx6953_i2c_write_b_sensor(0x3640, 0x00);
-	for (j = cast_H; j < cast_MAX; j++) {
-		for (i = 0; i < NUM_LSC_CAST_REGS; i++) {
-			rc = vx6953_i2c_read(LSC_CastRegs[cast_D]+(2*i),
-								&LSC_Raw[i], 2);
-			if (rc < 0)
-				return rc;
-			v = LSC_Raw[i];
-			v +=  LSC_CorrectionForCast[j][i];
-			LSC_Fixed[i] = (unsigned short) v;
-		}
-		for (i = 0; i < NUM_LSC_CAST_REGS; i++) {
-			rc = vx6953_i2c_write_w_sensor(LSC_CastRegs[j]+(2*i),
-								LSC_Fixed[i]);
-			if (rc < 0)
-				return rc;
-		}
-	}
-	CDBG("vx6953_lsc_patch done\n");
-	return rc;
-}
-
-static int32_t vx6953_sensor_setting(int update_type, int rt)
-{
-
-	int32_t rc = 0;
-	unsigned short frame_cnt;
-	struct msm_camera_csi_params vx6953_csi_params;
-	if (vx6953_ctrl->sensor_type != VX6953_STM5M0EDOF_CUT_2) {
-		switch (update_type) {
-		case REG_INIT:
-		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
-			struct vx6953_i2c_reg_conf init_tbl[] = {
-				{REG_0x0112,
-					vx6953_regs.reg_pat_init[0].
-					reg_0x0112},
-				{REG_0x0113,
-					vx6953_regs.reg_pat_init[0].
-					reg_0x0113},
-				{REG_VT_PIX_CLK_DIV,
-					vx6953_regs.reg_pat_init[0].
-					vt_pix_clk_div},
-				{0x303, 0x01},
-				{0x30b, 0x01},
-				{REG_PRE_PLL_CLK_DIV,
-					vx6953_regs.reg_pat_init[0].
-					pre_pll_clk_div},
-				{REG_PLL_MULTIPLIER,
-					vx6953_regs.reg_pat_init[0].
-					pll_multiplier},
-				{REG_OP_PIX_CLK_DIV,
-					vx6953_regs.reg_pat_init[0].
-					op_pix_clk_div},
-				{REG_0x3210, 0x01},
-				{REG_0x0111,
-					vx6953_regs.reg_pat_init[0].
-					reg_0x0111},
-				{REG_0x0b00,
-					vx6953_regs.reg_pat_init[0].
-					reg_0x0b00},
-				{REG_0x0136,
-					vx6953_regs.reg_pat_init[0].
-					reg_0x0136},
-				{REG_0x0137,
-					vx6953_regs.reg_pat_init[0].
-					reg_0x0137},
-				{REG_0x0b06,
-					vx6953_regs.reg_pat_init[0].
-					reg_0x0b06},
-				{REG_0x0b07,
-					vx6953_regs.reg_pat_init[0].
-					reg_0x0b07},
-				{REG_0x0b08,
-					vx6953_regs.reg_pat_init[0].
-					reg_0x0b08},
-				{REG_0x0b09,
-					vx6953_regs.reg_pat_init[0].
-					reg_0x0b09},
-				{REG_0x0b83,
-					vx6953_regs.reg_pat_init[0].
-					reg_0x0b83},
-				{REG_0x0b84,
-					vx6953_regs.reg_pat_init[0].
-					reg_0x0b84},
-				{REG_0x0b85,
-					vx6953_regs.reg_pat_init[0].
-					reg_0x0b85},
-				{REG_0x0b88,
-					vx6953_regs.reg_pat_init[0].
-					reg_0x0b88},
-				{REG_0x0b89,
-					vx6953_regs.reg_pat_init[0].
-					reg_0x0b89},
-				{REG_0x0b8a,
-					vx6953_regs.reg_pat_init[0].
-					reg_0x0b8a},
-				{0x3393, 0x06},
-				{0x3394, 0x07},
-				{0x338d, 0x08},
-				{0x338e, 0x08},
-				{0x338f, 0x00},
-			};
-			/* reset fps_divider */
-			vx6953_ctrl->fps = 30 * Q8;
-			/* stop streaming */
-
-			count = 0;
-			CDBG("Init vx6953_sensor_setting standby\n");
-			if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
-				MODE_SELECT_STANDBY_MODE) < 0)
-				return rc;
-			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-			vx6953_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
-			GROUPED_PARAMETER_HOLD);
-
-			rc = vx6953_i2c_write_w_table(cut3_cali_data,
-				ARRAY_SIZE(cut3_cali_data));
-
-			vx6953_lsc_patch();
-
-			vx6953_i2c_write_w_sensor(0x100A, 0x07A3);
-			vx6953_i2c_write_w_sensor(0x114A, 0x002A);
-			vx6953_i2c_write_w_sensor(0x1716, 0x0204);
-			vx6953_i2c_write_w_sensor(0x1718, 0x0880);
-
-			rc = vx6953_i2c_write_w_table(&init_tbl[0],
-				ARRAY_SIZE(init_tbl));
-			if (rc < 0)
-				return rc;
-
-			msleep(10);
-
-		}
-		return rc;
-		case UPDATE_PERIODIC:
-		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
-			struct vx6953_i2c_reg_conf preview_mode_tbl[] = {
-				{0x200, 0x02},
-				{0x201, 0x26},
-				{REG_COARSE_INTEGRATION_TIME_HI,
-					vx6953_regs.reg_pat[rt].
-					coarse_integration_time_hi},
-				{REG_COARSE_INTEGRATION_TIME_LO,
-					vx6953_regs.reg_pat[rt].
-					coarse_integration_time_lo},
-				{REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
-					vx6953_regs.reg_pat[rt].
-					analogue_gain_code_global},
-				{REG_FRAME_LENGTH_LINES_HI,
-					vx6953_regs.reg_pat[rt].
-					frame_length_lines_hi},
-				{REG_FRAME_LENGTH_LINES_LO,
-					vx6953_regs.reg_pat[rt].
-					frame_length_lines_lo},
-				{REG_LINE_LENGTH_PCK_HI,
-					vx6953_regs.reg_pat[rt].
-					line_length_pck_hi},
-				{REG_LINE_LENGTH_PCK_LO,
-					vx6953_regs.reg_pat[rt].
-					line_length_pck_lo},
-				{REG_0x0b80,
-					vx6953_regs.reg_pat[rt].
-					reg_0x0b80},
-				{REG_0x0900,
-					vx6953_regs.reg_pat[rt].
-					reg_0x0900},
-				{REG_0x0901,
-					vx6953_regs.reg_pat[rt].
-					reg_0x0901},
-				{REG_0x0902,
-					vx6953_regs.reg_pat[rt].
-					reg_0x0902},
-				{REG_0x0383,
-					vx6953_regs.reg_pat[rt].
-					reg_0x0383},
-				{REG_0x0387,
-					vx6953_regs.reg_pat[rt].
-					reg_0x0387},
-				{REG_0x034c,
-					vx6953_regs.reg_pat[rt].
-					reg_0x034c},
-				{REG_0x034d,
-					vx6953_regs.reg_pat[rt].
-					reg_0x034d},
-				{REG_0x034e,
-					vx6953_regs.reg_pat[rt].
-					reg_0x034e},
-				{REG_0x034f,
-					vx6953_regs.reg_pat[rt].
-					reg_0x034f},
-				{REG_0x3640, 0x00},
-			};
-
-			struct vx6953_i2c_reg_conf snapshot_mode_tbl[] = {
-				{0x0200, 0x02},
-				{0x0201, 0x54},
-				{REG_COARSE_INTEGRATION_TIME_HI,
-					vx6953_regs.reg_pat[rt].
-					coarse_integration_time_hi},
-				{REG_COARSE_INTEGRATION_TIME_LO,
-					vx6953_regs.reg_pat[rt].
-					coarse_integration_time_lo},
-				{REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
-					vx6953_regs.reg_pat[rt].
-					analogue_gain_code_global},
-				{REG_FRAME_LENGTH_LINES_HI,
-					vx6953_regs.reg_pat[rt].
-					frame_length_lines_hi},
-				{REG_FRAME_LENGTH_LINES_LO,
-					vx6953_regs.reg_pat[rt].
-					frame_length_lines_lo},
-				{REG_LINE_LENGTH_PCK_HI,
-					vx6953_regs.reg_pat[rt].
-					line_length_pck_hi},
-				{REG_LINE_LENGTH_PCK_LO,
-					vx6953_regs.reg_pat[rt].
-					line_length_pck_lo},
-				{REG_0x0b80,
-					vx6953_regs.reg_pat[rt].
-					reg_0x0b80},
-				{REG_0x0900,
-					vx6953_regs.reg_pat[rt].
-					reg_0x0900},
-				{REG_0x0901,
-					vx6953_regs.reg_pat[rt].
-					reg_0x0901},
-				{REG_0x0902,
-					vx6953_regs.reg_pat[rt].
-					reg_0x0902},
-				{REG_0x0383,
-					vx6953_regs.reg_pat[rt].
-					reg_0x0383},
-				{REG_0x0387,
-					vx6953_regs.reg_pat[rt].
-					reg_0x0387},
-				{REG_0x034c,
-					vx6953_regs.reg_pat[rt].
-					reg_0x034c},
-				{REG_0x034d,
-					vx6953_regs.reg_pat[rt].
-					reg_0x034d},
-				{REG_0x034e,
-					vx6953_regs.reg_pat[rt].
-					reg_0x034e},
-				{REG_0x034f,
-					vx6953_regs.reg_pat[rt].
-					reg_0x034f},
-				{0x3140, 0x01},
-				{REG_0x3640, 0x00},
-			};
-			/* stop streaming */
-
-			if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
-				MODE_SELECT_STANDBY_MODE) < 0)
-				return rc;
-			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-
-			if (count == 0) {
-				vx6953_csi_params.data_format = CSI_8BIT;
-				vx6953_csi_params.lane_cnt = 1;
-				vx6953_csi_params.lane_assign = 0xe4;
-				vx6953_csi_params.dpcm_scheme = 0;
-				vx6953_csi_params.settle_cnt = 7;
-				rc = msm_camio_csi_config(&vx6953_csi_params);
-				if (rc < 0)
-					CDBG("config csi controller failed\n");
-
-				msleep(20);
-				count = 1;
-			}
-
-			vx6953_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
-			GROUPED_PARAMETER_HOLD);
-
-			if (rt == RES_PREVIEW) {
-				rc = vx6953_i2c_write_w_table(
-					&preview_mode_tbl[0],
-					ARRAY_SIZE(preview_mode_tbl));
-				if (rc < 0)
-					return rc;
-			}
-			if (rt == RES_CAPTURE) {
-				rc = vx6953_i2c_write_w_table(
-					&snapshot_mode_tbl[0],
-					ARRAY_SIZE(snapshot_mode_tbl));
-				if (rc < 0)
-					return rc;
-			}
-
-			vx6953_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
-			GROUPED_PARAMETER_HOLD_OFF);
-
-			/* Start sensor streaming */
-			if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
-				MODE_SELECT_STREAM) < 0)
-				return rc;
-			msleep(10);
-
-			if (vx6953_i2c_read(0x0005, &frame_cnt, 1) < 0)
-				return rc;
-
-			while (frame_cnt == 0xFF) {
-				if (vx6953_i2c_read(0x0005, &frame_cnt, 1) < 0)
-					return rc;
-				CDBG("frame_cnt=%d\n", frame_cnt);
-				msleep(2);
-			}
-		}
-		return rc;
-		default:
-			return rc;
-		}
-	} else {
-		switch (update_type) {
-		case REG_INIT:
-		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
-			struct vx6953_i2c_reg_conf init_tbl[] = {
-			{REG_0x0112,
-				vx6953_regs.reg_pat_init[0].reg_0x0112},
-			{REG_0x0113,
-				vx6953_regs.reg_pat_init[0].reg_0x0113},
-			{REG_VT_PIX_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				vt_pix_clk_div},
-			{REG_PRE_PLL_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				pre_pll_clk_div},
-			{REG_PLL_MULTIPLIER,
-				vx6953_regs.reg_pat_init[0].
-				pll_multiplier},
-			{REG_OP_PIX_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				op_pix_clk_div},
-			{REG_COARSE_INTEGRATION_TIME_HI,
-				vx6953_regs.reg_pat[rt].
-				coarse_integration_time_hi},
-			{REG_COARSE_INTEGRATION_TIME_LO,
-				vx6953_regs.reg_pat[rt].
-				coarse_integration_time_lo},
-			{REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
-				vx6953_regs.reg_pat[rt].
-				analogue_gain_code_global},
-			{REG_0x3030,
-				vx6953_regs.reg_pat_init[0].reg_0x3030},
-			/* 953 specific registers */
-			{REG_0x0111,
-				vx6953_regs.reg_pat_init[0].reg_0x0111},
-			{REG_0x0b00,
-				vx6953_regs.reg_pat_init[0].reg_0x0b00},
-			{REG_0x3001,
-				vx6953_regs.reg_pat_init[0].reg_0x3001},
-			{REG_0x3004,
-				vx6953_regs.reg_pat_init[0].reg_0x3004},
-			{REG_0x3007,
-				vx6953_regs.reg_pat_init[0].reg_0x3007},
-			{REG_0x3016,
-				vx6953_regs.reg_pat_init[0].reg_0x3016},
-			{REG_0x301d,
-				vx6953_regs.reg_pat_init[0].reg_0x301d},
-			{REG_0x317e,
-				vx6953_regs.reg_pat_init[0].reg_0x317e},
-			{REG_0x317f,
-				vx6953_regs.reg_pat_init[0].reg_0x317f},
-			{REG_0x3400,
-				vx6953_regs.reg_pat_init[0].reg_0x3400},
-			/* DEFCOR settings */
-			/*Single Defect Correction Weight DISABLE*/
-			{0x0b06,
-				vx6953_regs.reg_pat_init[0].reg_0x0b06},
-			/*Single_defect_correct_weight = auto*/
-			{0x0b07,
-				vx6953_regs.reg_pat_init[0].reg_0x0b07},
-			/*Dynamic couplet correction ENABLED*/
-			{0x0b08,
-				vx6953_regs.reg_pat_init[0].reg_0x0b08},
-			/*Dynamic couplet correction weight*/
-			{0x0b09,
-				vx6953_regs.reg_pat_init[0].reg_0x0b09},
-			/* Clock Setup */
-			/* Tell sensor ext clk is 24MHz*/
-			{0x0136,
-				vx6953_regs.reg_pat_init[0].reg_0x0136},
-			{0x0137,
-				vx6953_regs.reg_pat_init[0].reg_0x0137},
-			/* The white balance gains must be written
-			to the sensor every frame. */
-			/* Edof */
-			{REG_0x0b83,
-				vx6953_regs.reg_pat_init[0].reg_0x0b83},
-			{REG_0x0b84,
-				vx6953_regs.reg_pat_init[0].reg_0x0b84},
-			{0x0b85,
-				vx6953_regs.reg_pat_init[0].reg_0x0b85},
-			{0x0b88,
-				vx6953_regs.reg_pat_init[0].reg_0x0b88},
-			{0x0b89,
-				vx6953_regs.reg_pat_init[0].reg_0x0b89},
-			{REG_0x0b8a,
-				vx6953_regs.reg_pat_init[0].reg_0x0b8a},
-			/* Mode specific regieters */
-			{REG_FRAME_LENGTH_LINES_HI,
-				vx6953_regs.reg_pat[rt].
-				frame_length_lines_hi},
-			{REG_FRAME_LENGTH_LINES_LO,
-				vx6953_regs.reg_pat[rt].
-				frame_length_lines_lo},
-			{REG_LINE_LENGTH_PCK_HI,
-				vx6953_regs.reg_pat[rt].
-				line_length_pck_hi},
-			{REG_LINE_LENGTH_PCK_LO,
-				vx6953_regs.reg_pat[rt].
-				line_length_pck_lo},
-			{REG_0x3005,
-				vx6953_regs.reg_pat[rt].reg_0x3005},
-			{0x3010,
-				vx6953_regs.reg_pat[rt].reg_0x3010},
-			{REG_0x3011,
-				vx6953_regs.reg_pat[rt].reg_0x3011},
-			{REG_0x301a,
-				vx6953_regs.reg_pat[rt].reg_0x301a},
-			{REG_0x3035,
-				vx6953_regs.reg_pat[rt].reg_0x3035},
-			{REG_0x3036,
-				vx6953_regs.reg_pat[rt].reg_0x3036},
-			{REG_0x3041,
-				vx6953_regs.reg_pat[rt].reg_0x3041},
-			{0x3042,
-				vx6953_regs.reg_pat[rt].reg_0x3042},
-			{REG_0x3045,
-				vx6953_regs.reg_pat[rt].reg_0x3045},
-			/*EDOF: Estimation settings for Preview mode
-			Application settings for capture mode
-			(standard settings - Not tuned) */
-			{REG_0x0b80,
-				vx6953_regs.reg_pat[rt].reg_0x0b80},
-			{REG_0x0900,
-				vx6953_regs.reg_pat[rt].reg_0x0900},
-			{REG_0x0901,
-				vx6953_regs.reg_pat[rt].reg_0x0901},
-			{REG_0x0902,
-				vx6953_regs.reg_pat[rt].reg_0x0902},
-			{REG_0x0383,
-				vx6953_regs.reg_pat[rt].reg_0x0383},
-			{REG_0x0387,
-				vx6953_regs.reg_pat[rt].reg_0x0387},
-			/* Change output size / frame rate */
-			{REG_0x034c,
-				vx6953_regs.reg_pat[rt].reg_0x034c},
-			{REG_0x034d,
-				vx6953_regs.reg_pat[rt].reg_0x034d},
-			{REG_0x034e,
-				vx6953_regs.reg_pat[rt].reg_0x034e},
-			{REG_0x034f,
-				vx6953_regs.reg_pat[rt].reg_0x034f},
-			{REG_0x1716,
-				vx6953_regs.reg_pat[rt].reg_0x1716},
-			{REG_0x1717,
-				vx6953_regs.reg_pat[rt].reg_0x1717},
-			{REG_0x1718,
-				vx6953_regs.reg_pat[rt].reg_0x1718},
-			{REG_0x1719,
-				vx6953_regs.reg_pat[rt].reg_0x1719},
-			};
-						/* reset fps_divider */
-			vx6953_ctrl->fps = 30 * Q8;
-			/* stop streaming */
-
-			/* Reset everything first */
-			if (vx6953_i2c_write_b_sensor(0x103, 0x01) < 0) {
-				CDBG("S/W reset failed\n");
-				return rc;
-			} else
-				CDBG("S/W reset successful\n");
-
-			msleep(10);
-
-			CDBG("Init vx6953_sensor_setting standby\n");
-			if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
-				MODE_SELECT_STANDBY_MODE) < 0)
-				return rc;
-				/*vx6953_stm5m0edof_delay_msecs_stdby*/
-			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-			vx6953_patch_for_cut2();
-			rc = vx6953_i2c_write_w_table(&init_tbl[0],
-				ARRAY_SIZE(init_tbl));
-			if (rc < 0)
-				return rc;
-				msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-		}
-	return rc;
-	case UPDATE_PERIODIC:
-		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
-			struct vx6953_i2c_reg_conf init_mode_tbl[] =  {
-			{REG_0x0112,
-				vx6953_regs.reg_pat_init[0].reg_0x0112},
-			{REG_0x0113,
-				vx6953_regs.reg_pat_init[0].reg_0x0113},
-			{REG_VT_PIX_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				vt_pix_clk_div},
-			{REG_PRE_PLL_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				pre_pll_clk_div},
-			{REG_PLL_MULTIPLIER,
-				vx6953_regs.reg_pat_init[0].
-				pll_multiplier},
-			{REG_OP_PIX_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				op_pix_clk_div},
-			{REG_COARSE_INTEGRATION_TIME_HI,
-				vx6953_regs.reg_pat[rt].
-				coarse_integration_time_hi},
-			{REG_COARSE_INTEGRATION_TIME_LO,
-				vx6953_regs.reg_pat[rt].
-				coarse_integration_time_lo},
-			{REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
-				vx6953_regs.reg_pat[rt].
-				analogue_gain_code_global},
-			{REG_0x3030,
-				vx6953_regs.reg_pat_init[0].reg_0x3030},
-			/* 953 specific registers */
-			{REG_0x0111,
-				vx6953_regs.reg_pat_init[0].reg_0x0111},
-			{REG_0x0b00,
-				vx6953_regs.reg_pat_init[0].reg_0x0b00},
-			{REG_0x3001,
-				vx6953_regs.reg_pat_init[0].reg_0x3001},
-			{REG_0x3004,
-				vx6953_regs.reg_pat_init[0].reg_0x3004},
-			{REG_0x3007,
-				vx6953_regs.reg_pat_init[0].reg_0x3007},
-			{REG_0x3016,
-				vx6953_regs.reg_pat_init[0].reg_0x3016},
-			{REG_0x301d,
-				vx6953_regs.reg_pat_init[0].reg_0x301d},
-			{REG_0x317e,
-				vx6953_regs.reg_pat_init[0].reg_0x317e},
-			{REG_0x317f,
-				vx6953_regs.reg_pat_init[0].reg_0x317f},
-			{REG_0x3400,
-				vx6953_regs.reg_pat_init[0].reg_0x3400},
-			{0x0b06,
-				vx6953_regs.reg_pat_init[0].reg_0x0b06},
-			/*Single_defect_correct_weight = auto*/
-			{0x0b07,
-				vx6953_regs.reg_pat_init[0].reg_0x0b07},
-			/*Dynamic couplet correction ENABLED*/
-			{0x0b08,
-				vx6953_regs.reg_pat_init[0].reg_0x0b08},
-			/*Dynamic couplet correction weight*/
-			{0x0b09,
-				vx6953_regs.reg_pat_init[0].reg_0x0b09},
-			/* Clock Setup */
-			/* Tell sensor ext clk is 24MHz*/
-			{0x0136,
-				vx6953_regs.reg_pat_init[0].reg_0x0136},
-			{0x0137,
-				vx6953_regs.reg_pat_init[0].reg_0x0137},
-			/* The white balance gains must be written
-			to the sensor every frame. */
-			/* Edof */
-			{REG_0x0b83,
-				vx6953_regs.reg_pat_init[0].reg_0x0b83},
-			{REG_0x0b84,
-				vx6953_regs.reg_pat_init[0].reg_0x0b84},
-			{0x0b85,
-				vx6953_regs.reg_pat_init[0].reg_0x0b85},
-			{0x0b88,
-				vx6953_regs.reg_pat_init[0].reg_0x0b88},
-			{0x0b89,
-				vx6953_regs.reg_pat_init[0].reg_0x0b89},
-			{REG_0x0b8a,
-				vx6953_regs.reg_pat_init[0].reg_0x0b8a},
-			/* Mode specific regieters */
-			{REG_FRAME_LENGTH_LINES_HI,
-				vx6953_regs.reg_pat[rt].
-				frame_length_lines_hi},
-			{REG_FRAME_LENGTH_LINES_LO,
-				vx6953_regs.reg_pat[rt].
-				frame_length_lines_lo},
-			{REG_LINE_LENGTH_PCK_HI,
-				vx6953_regs.reg_pat[rt].
-				line_length_pck_hi},
-			{REG_LINE_LENGTH_PCK_LO,
-				vx6953_regs.reg_pat[rt].
-				line_length_pck_lo},
-			{REG_0x3005,
-				vx6953_regs.reg_pat[rt].reg_0x3005},
-			{0x3010,
-				vx6953_regs.reg_pat[rt].reg_0x3010},
-			{REG_0x3011,
-				vx6953_regs.reg_pat[rt].reg_0x3011},
-			{REG_0x301a,
-				vx6953_regs.reg_pat[rt].reg_0x301a},
-			{REG_0x3035,
-				vx6953_regs.reg_pat[rt].reg_0x3035},
-			{REG_0x3036,
-				vx6953_regs.reg_pat[rt].reg_0x3036},
-			{REG_0x3041,
-				vx6953_regs.reg_pat[rt].reg_0x3041},
-			{0x3042,
-				vx6953_regs.reg_pat[rt].reg_0x3042},
-			{REG_0x3045,
-				vx6953_regs.reg_pat[rt].reg_0x3045},
-			/*EDOF: Estimation settings for Preview mode
-			Application settings for capture mode
-			(standard settings - Not tuned) */
-			{REG_0x0b80,
-				vx6953_regs.reg_pat[rt].reg_0x0b80},
-			{REG_0x0900,
-				vx6953_regs.reg_pat[rt].reg_0x0900},
-			{REG_0x0901,
-				vx6953_regs.reg_pat[rt].reg_0x0901},
-			{REG_0x0902,
-				vx6953_regs.reg_pat[rt].reg_0x0902},
-			{REG_0x0383,
-				vx6953_regs.reg_pat[rt].reg_0x0383},
-			{REG_0x0387,
-				vx6953_regs.reg_pat[rt].reg_0x0387},
-			/* Change output size / frame rate */
-			{REG_0x034c,
-				vx6953_regs.reg_pat[rt].reg_0x034c},
-			{REG_0x034d,
-				vx6953_regs.reg_pat[rt].reg_0x034d},
-			{REG_0x034e,
-				vx6953_regs.reg_pat[rt].reg_0x034e},
-			{REG_0x034f,
-				vx6953_regs.reg_pat[rt].reg_0x034f},
-			{REG_0x1716,
-				vx6953_regs.reg_pat[rt].reg_0x1716},
-			{REG_0x1717,
-				vx6953_regs.reg_pat[rt].reg_0x1717},
-			{REG_0x1718,
-				vx6953_regs.reg_pat[rt].reg_0x1718},
-			{REG_0x1719,
-				vx6953_regs.reg_pat[rt].reg_0x1719},
-			};
-			struct vx6953_i2c_reg_conf mode_tbl[] = {
-			{REG_0x0112,
-				vx6953_regs.reg_pat_init[0].reg_0x0112},
-			{REG_0x0113,
-				vx6953_regs.reg_pat_init[0].reg_0x0113},
-			{REG_VT_PIX_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				vt_pix_clk_div},
-			{REG_PRE_PLL_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				pre_pll_clk_div},
-			{REG_PLL_MULTIPLIER,
-				vx6953_regs.reg_pat_init[0].
-				pll_multiplier},
-			{REG_OP_PIX_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				op_pix_clk_div},
-		/* Mode specific regieters */
-			{REG_FRAME_LENGTH_LINES_HI,
-				vx6953_regs.reg_pat[rt].frame_length_lines_hi},
-			{REG_FRAME_LENGTH_LINES_LO,
-				vx6953_regs.reg_pat[rt].frame_length_lines_lo},
-			{REG_LINE_LENGTH_PCK_HI,
-				vx6953_regs.reg_pat[rt].line_length_pck_hi},
-			{REG_LINE_LENGTH_PCK_LO,
-				vx6953_regs.reg_pat[rt].line_length_pck_lo},
-			{REG_0x3005, vx6953_regs.reg_pat[rt].reg_0x3005},
-			{0x3010, vx6953_regs.reg_pat[rt].reg_0x3010},
-			{REG_0x3011, vx6953_regs.reg_pat[rt].reg_0x3011},
-			{REG_0x301a, vx6953_regs.reg_pat[rt].reg_0x301a},
-			{REG_0x3035, vx6953_regs.reg_pat[rt].reg_0x3035},
-			{REG_0x3036, vx6953_regs.reg_pat[rt].reg_0x3036},
-			{REG_0x3041, vx6953_regs.reg_pat[rt].reg_0x3041},
-			{0x3042, vx6953_regs.reg_pat[rt].reg_0x3042},
-			{REG_0x3045, vx6953_regs.reg_pat[rt].reg_0x3045},
-			/*EDOF: Estimation settings for Preview mode
-			Application settings for capture
-			mode(standard settings - Not tuned) */
-			{REG_0x0b80, vx6953_regs.reg_pat[rt].reg_0x0b80},
-			{REG_0x0900, vx6953_regs.reg_pat[rt].reg_0x0900},
-			{REG_0x0901, vx6953_regs.reg_pat[rt].reg_0x0901},
-			{REG_0x0902, vx6953_regs.reg_pat[rt].reg_0x0902},
-			{REG_0x0383, vx6953_regs.reg_pat[rt].reg_0x0383},
-			{REG_0x0387, vx6953_regs.reg_pat[rt].reg_0x0387},
-			/* Change output size / frame rate */
-			{REG_0x034c, vx6953_regs.reg_pat[rt].reg_0x034c},
-			{REG_0x034d, vx6953_regs.reg_pat[rt].reg_0x034d},
-			{REG_0x034e, vx6953_regs.reg_pat[rt].reg_0x034e},
-			{REG_0x034f, vx6953_regs.reg_pat[rt].reg_0x034f},
-			/*{0x200, vx6953_regs.reg_pat[rt].reg_0x0200},
-			{0x201, vx6953_regs.reg_pat[rt].reg_0x0201},*/
-			{REG_0x1716, vx6953_regs.reg_pat[rt].reg_0x1716},
-			{REG_0x1717, vx6953_regs.reg_pat[rt].reg_0x1717},
-			{REG_0x1718, vx6953_regs.reg_pat[rt].reg_0x1718},
-			{REG_0x1719, vx6953_regs.reg_pat[rt].reg_0x1719},
-			};
-			/* stop streaming */
-			msleep(5);
-
-			/* Reset everything first */
-			if (vx6953_i2c_write_b_sensor(0x103, 0x01) < 0) {
-				CDBG("S/W reset failed\n");
-				return rc;
-			} else
-				CDBG("S/W reset successful\n");
-
-			msleep(10);
-
-			if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
-				MODE_SELECT_STANDBY_MODE) < 0)
-				return rc;
-			/*vx6953_stm5m0edof_delay_msecs_stdby*/
-			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-
-
-			vx6953_csi_params.data_format = CSI_8BIT;
-			vx6953_csi_params.lane_cnt = 1;
-			vx6953_csi_params.lane_assign = 0xe4;
-			vx6953_csi_params.dpcm_scheme = 0;
-			vx6953_csi_params.settle_cnt = 7;
-			rc = msm_camio_csi_config(&vx6953_csi_params);
-			if (rc < 0)
-				return rc;
-
-			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-
-			vx6953_patch_for_cut2();
-			rc = vx6953_i2c_write_w_table(&init_mode_tbl[0],
-				ARRAY_SIZE(init_mode_tbl));
-			if (rc < 0)
-				return rc;
-
-			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-
-			rc = vx6953_i2c_write_w_table(&mode_tbl[0],
-				ARRAY_SIZE(mode_tbl));
-			if (rc < 0)
-				return rc;
-
-			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-
-			/* Start sensor streaming */
-			if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
-				MODE_SELECT_STREAM) < 0)
-				return rc;
-			msleep(vx6953_stm5m0edof_delay_msecs_stream);
-
-			if (vx6953_i2c_read(0x0005, &frame_cnt, 1) < 0)
-				return rc;
-
-			while (frame_cnt == 0xFF) {
-				if (vx6953_i2c_read(0x0005, &frame_cnt, 1) < 0)
-					return rc;
-				CDBG("frame_cnt=%d", frame_cnt);
-				msleep(10);
-			}
-		}
-		return rc;
-	default:
-		return rc;
-	}
-	}
-	return rc;
-}
-
-
-static int32_t vx6953_video_config(int mode)
-{
-
-	int32_t	rc = 0;
-	int	rt;
-	/* change sensor resolution	if needed */
-	if (vx6953_ctrl->curr_res != vx6953_ctrl->prev_res) {
-		if (vx6953_ctrl->prev_res == QTR_SIZE) {
-			rt = RES_PREVIEW;
-			vx6953_stm5m0edof_delay_msecs_stdby	=
-				((((2 * 1000 * vx6953_ctrl->fps_divider) /
-				   vx6953_ctrl->fps) * Q8) / Q10) + 1;
-		} else {
-			rt = RES_CAPTURE;
-			vx6953_stm5m0edof_delay_msecs_stdby	=
-				((((1000 * vx6953_ctrl->fps_divider) /
-				   vx6953_ctrl->fps) * Q8) / Q10) + 1;
-		}
-		if (vx6953_sensor_setting(UPDATE_PERIODIC, rt) < 0)
-			return rc;
-	}
-	if (vx6953_ctrl->set_test) {
-		if (vx6953_test(vx6953_ctrl->set_test) < 0)
-			return	rc;
-	}
-	vx6953_ctrl->edof_mode = VX6953_EDOF_ESTIMATION;
-	rc = vx6953_enable_edof(vx6953_ctrl->edof_mode);
-	if (rc < 0)
-		return rc;
-	vx6953_ctrl->curr_res = vx6953_ctrl->prev_res;
-	vx6953_ctrl->sensormode = mode;
-	return rc;
-}
-
-static int32_t vx6953_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-	int rt;
-	/*change sensor resolution if needed */
-	if (vx6953_ctrl->curr_res != vx6953_ctrl->pict_res) {
-		if (vx6953_ctrl->pict_res == QTR_SIZE) {
-			rt = RES_PREVIEW;
-			vx6953_stm5m0edof_delay_msecs_stdby =
-				((((2 * 1000 * vx6953_ctrl->fps_divider) /
-				vx6953_ctrl->fps) * Q8) / Q10) + 1;
-		} else {
-			rt = RES_CAPTURE;
-			vx6953_stm5m0edof_delay_msecs_stdby =
-				((((1000 * vx6953_ctrl->fps_divider) /
-				vx6953_ctrl->fps) * Q8) / Q10) + 1;
-		}
-	if (vx6953_sensor_setting(UPDATE_PERIODIC, rt) < 0)
-		return rc;
-	}
-
-	vx6953_ctrl->edof_mode = VX6953_EDOF_APPLICATION;
-	if (vx6953_enable_edof(vx6953_ctrl->edof_mode) < 0)
-		return rc;
-	vx6953_ctrl->curr_res = vx6953_ctrl->pict_res;
-	vx6953_ctrl->sensormode = mode;
-	return rc;
-} /*end of vx6953_snapshot_config*/
-
-static int32_t vx6953_raw_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-	int rt;
-	/* change sensor resolution if needed */
-	if (vx6953_ctrl->curr_res != vx6953_ctrl->pict_res) {
-		if (vx6953_ctrl->pict_res == QTR_SIZE) {
-			rt = RES_PREVIEW;
-			vx6953_stm5m0edof_delay_msecs_stdby =
-				((((2 * 1000 * vx6953_ctrl->fps_divider)/
-				vx6953_ctrl->fps) * Q8) / Q10) + 1;
-		} else {
-			rt = RES_CAPTURE;
-			vx6953_stm5m0edof_delay_msecs_stdby =
-				((((1000 * vx6953_ctrl->fps_divider)/
-				vx6953_ctrl->fps) * Q8) / Q10) + 1;
-		}
-		if (vx6953_sensor_setting(UPDATE_PERIODIC, rt) < 0)
-			return rc;
-	}
-	vx6953_ctrl->edof_mode = VX6953_EDOF_APPLICATION;
-	if (vx6953_enable_edof(vx6953_ctrl->edof_mode) < 0)
-		return rc;
-	vx6953_ctrl->curr_res = vx6953_ctrl->pict_res;
-	vx6953_ctrl->sensormode = mode;
-	return rc;
-} /*end of vx6953_raw_snapshot_config*/
-static int32_t vx6953_set_sensor_mode(int mode,
-	int res)
-{
-	int32_t rc = 0;
-	switch (mode) {
-	case SENSOR_PREVIEW_MODE:
-		rc = vx6953_video_config(mode);
-		break;
-	case SENSOR_SNAPSHOT_MODE:
-		rc = vx6953_snapshot_config(mode);
-		break;
-	case SENSOR_RAW_SNAPSHOT_MODE:
-		rc = vx6953_raw_snapshot_config(mode);
-		break;
-	default:
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
-static int32_t vx6953_power_down(void)
-{
-	return 0;
-}
-
-
-static int vx6953_probe_init_done(const struct msm_camera_sensor_info *data)
-{
-	gpio_set_value_cansleep(data->sensor_reset, 0);
-	gpio_free(data->sensor_reset);
-	return 0;
-}
-static int vx6953_probe_init_sensor(const struct msm_camera_sensor_info *data)
-{
-	int32_t rc = 0;
-	unsigned short chipidl, chipidh;
-	CDBG("%s: %d\n", __func__, __LINE__);
-	rc = gpio_request(data->sensor_reset, "vx6953");
-	CDBG(" vx6953_probe_init_sensor \n");
-	if (!rc) {
-		CDBG("sensor_reset = %d\n", rc);
-		CDBG(" vx6953_probe_init_sensor 1\n");
-		gpio_direction_output(data->sensor_reset, 0);
-		msleep(10);
-		CDBG(" vx6953_probe_init_sensor 1\n");
-		gpio_set_value_cansleep(data->sensor_reset, 1);
-	} else {
-		CDBG(" vx6953_probe_init_sensor 2\n");
-		goto init_probe_done;
-	}
-	msleep(20);
-	CDBG(" vx6953_probe_init_sensor is called\n");
-	/* 3. Read sensor Model ID: */
-	rc = vx6953_i2c_read(0x0000, &chipidh, 1);
-	if (rc < 0) {
-		CDBG(" vx6953_probe_init_sensor 3\n");
-		goto init_probe_fail;
-	}
-	rc = vx6953_i2c_read(0x0001, &chipidl, 1);
-	if (rc < 0) {
-		CDBG(" vx6953_probe_init_sensor4\n");
-		goto init_probe_fail;
-	}
-	CDBG("vx6953 model_id = 0x%x  0x%x\n", chipidh, chipidl);
-	/* 4. Compare sensor ID to VX6953 ID: */
-	if (chipidh != 0x03 || chipidl != 0xB9) {
-		rc = -ENODEV;
-		CDBG("vx6953_probe_init_sensor fail chip id doesnot match\n");
-		goto init_probe_fail;
-	}
-	goto init_probe_done;
-init_probe_fail:
-	CDBG(" vx6953_probe_init_sensor fails\n");
-	vx6953_probe_init_done(data);
-init_probe_done:
-	CDBG(" vx6953_probe_init_sensor finishes\n");
-	return rc;
-	}
-/* camsensor_iu060f_vx6953_reset */
-int vx6953_sensor_open_init(const struct msm_camera_sensor_info *data)
-{
-	unsigned short revision_number;
-	int32_t rc = 0;
-
-	CDBG("%s: %d\n", __func__, __LINE__);
-	CDBG("Calling vx6953_sensor_open_init\n");
-	vx6953_ctrl = kzalloc(sizeof(struct vx6953_ctrl_t), GFP_KERNEL);
-	if (!vx6953_ctrl) {
-		CDBG("vx6953_init failed!\n");
-		rc = -ENOMEM;
-		goto init_done;
-	}
-	vx6953_ctrl->fps_divider = 1 * 0x00000400;
-	vx6953_ctrl->pict_fps_divider = 1 * 0x00000400;
-	vx6953_ctrl->set_test = TEST_OFF;
-	vx6953_ctrl->prev_res = QTR_SIZE;
-	vx6953_ctrl->pict_res = FULL_SIZE;
-	vx6953_ctrl->curr_res = INVALID_SIZE;
-	vx6953_ctrl->sensor_type = VX6953_STM5M0EDOF_CUT_2;
-	vx6953_ctrl->edof_mode = VX6953_EDOF_ESTIMATION;
-	if (data)
-		vx6953_ctrl->sensordata = data;
-	if (rc < 0) {
-		CDBG("Calling vx6953_sensor_open_init fail1\n");
-		return rc;
-	}
-	CDBG("%s: %d\n", __func__, __LINE__);
-	/* enable mclk first */
-	msm_camio_clk_rate_set(VX6953_STM5M0EDOF_DEFAULT_MASTER_CLK_RATE);
-	CDBG("%s: %d\n", __func__, __LINE__);
-	rc = vx6953_probe_init_sensor(data);
-	if (rc < 0) {
-		CDBG("Calling vx6953_sensor_open_init fail3\n");
-		goto init_fail;
-	}
-	if (vx6953_i2c_read(0x0002, &revision_number, 1) < 0)
-		return rc;
-		CDBG("sensor revision number major = 0x%x\n", revision_number);
-	if (vx6953_i2c_read(0x0018, &revision_number, 1) < 0)
-		return rc;
-		CDBG("sensor revision number = 0x%x\n", revision_number);
-	if (revision_number == VX6953_REVISION_NUMBER_CUT3) {
-		vx6953_ctrl->sensor_type = VX6953_STM5M0EDOF_CUT_3;
-		CDBG("VX6953 EDof Cut 3.0 sensor\n ");
-	} else if (revision_number == VX6953_REVISION_NUMBER_CUT2) {
-		vx6953_ctrl->sensor_type = VX6953_STM5M0EDOF_CUT_2;
-		CDBG("VX6953 EDof Cut 2.0 sensor\n ");
-	} else {/* Cut1.0 reads 0x00 for register 0x0018*/
-		vx6953_ctrl->sensor_type = VX6953_STM5M0EDOF_CUT_1;
-		CDBG("VX6953 EDof Cut 1.0 sensor\n ");
-	}
-	if (vx6953_ctrl->prev_res == QTR_SIZE) {
-		if (vx6953_sensor_setting(REG_INIT, RES_PREVIEW) < 0)
-			return rc;
-	} else {
-		if (vx6953_sensor_setting(REG_INIT, RES_CAPTURE) < 0)
-			return rc;
-	}
-	vx6953_ctrl->fps = 30*Q8;
-	if (rc < 0)
-		goto init_fail;
-	else
-		goto init_done;
-init_fail:
-	CDBG("init_fail\n");
-	vx6953_probe_init_done(data);
-	kfree(vx6953_ctrl);
-init_done:
-	CDBG("init_done\n");
-	return rc;
-} /*endof vx6953_sensor_open_init*/
-
-static int vx6953_init_client(struct i2c_client *client)
-{
-	/* Initialize the MSM_CAMI2C Chip */
-	init_waitqueue_head(&vx6953_wait_queue);
-	return 0;
-}
-
-static const struct i2c_device_id vx6953_i2c_id[] = {
-	{"vx6953", 0},
-	{ }
-};
-
-static int vx6953_i2c_probe(struct i2c_client *client,
-	const struct i2c_device_id *id)
-{
-	int rc = 0;
-	CDBG("vx6953_probe called!\n");
-
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		CDBG("i2c_check_functionality failed\n");
-		goto probe_failure;
-	}
-
-	vx6953_sensorw = kzalloc(sizeof(struct vx6953_work_t), GFP_KERNEL);
-	if (!vx6953_sensorw) {
-		CDBG("kzalloc failed.\n");
-		rc = -ENOMEM;
-		goto probe_failure;
-	}
-
-	i2c_set_clientdata(client, vx6953_sensorw);
-	vx6953_init_client(client);
-	vx6953_client = client;
-
-	msleep(50);
-
-	CDBG("vx6953_probe successed! rc = %d\n", rc);
-	return 0;
-
-probe_failure:
-	CDBG("vx6953_probe failed! rc = %d\n", rc);
-	return rc;
-}
-
-static int vx6953_send_wb_info(struct wb_info_cfg *wb)
-{
-	unsigned short read_data;
-	uint8_t temp[8];
-	int rc = 0;
-	int i = 0;
-
-	/* red_gain */
-	temp[2] = wb->red_gain >> 8;
-	temp[3] = wb->red_gain & 0xFF;
-
-	/* green_gain */
-	temp[0] = wb->green_gain >> 8;
-	temp[1] = wb->green_gain & 0xFF;
-	temp[6] = temp[0];
-	temp[7] = temp[1];
-
-	/* blue_gain */
-	temp[4] = wb->blue_gain >> 8;
-	temp[5] = wb->blue_gain & 0xFF;
-	rc = vx6953_i2c_write_seq_sensor(0x0B8E, &temp[0], 8);
-
-	for (i = 0; i < 6; i++) {
-		rc = vx6953_i2c_read(0x0B8E + i, &read_data, 1);
-		CDBG("%s addr 0x%x val %d \n", __func__, 0x0B8E + i, read_data);
-	}
-	rc = vx6953_i2c_read(0x0B82, &read_data, 1);
-	CDBG("%s addr 0x%x val %d \n", __func__, 0x0B82, read_data);
-	if (rc < 0)
-		return rc;
-	return rc;
-} /*end of vx6953_snapshot_config*/
-
-static int __exit vx6953_remove(struct i2c_client *client)
-{
-	struct vx6953_work_t_t *sensorw = i2c_get_clientdata(client);
-	free_irq(client->irq, sensorw);
-	vx6953_client = NULL;
-	kfree(sensorw);
-	return 0;
-}
-
-static struct i2c_driver vx6953_i2c_driver = {
-	.id_table = vx6953_i2c_id,
-	.probe  = vx6953_i2c_probe,
-	.remove = __exit_p(vx6953_i2c_remove),
-	.driver = {
-		.name = "vx6953",
-	},
-};
-
-int vx6953_sensor_config(void __user *argp)
-{
-	struct sensor_cfg_data cdata;
-	long   rc = 0;
-	if (copy_from_user(&cdata,
-		(void *)argp,
-		sizeof(struct sensor_cfg_data)))
-		return -EFAULT;
-	mutex_lock(&vx6953_mut);
-	CDBG("vx6953_sensor_config: cfgtype = %d\n",
-	cdata.cfgtype);
-		switch (cdata.cfgtype) {
-		case CFG_GET_PICT_FPS:
-			vx6953_get_pict_fps(
-				cdata.cfg.gfps.prevfps,
-				&(cdata.cfg.gfps.pictfps));
-
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_GET_PREV_L_PF:
-			cdata.cfg.prevl_pf =
-			vx6953_get_prev_lines_pf();
-
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_GET_PREV_P_PL:
-			cdata.cfg.prevp_pl =
-				vx6953_get_prev_pixels_pl();
-
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_GET_PICT_L_PF:
-			cdata.cfg.pictl_pf =
-				vx6953_get_pict_lines_pf();
-
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_GET_PICT_P_PL:
-			cdata.cfg.pictp_pl =
-				vx6953_get_pict_pixels_pl();
-
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_GET_PICT_MAX_EXP_LC:
-			cdata.cfg.pict_max_exp_lc =
-				vx6953_get_pict_max_exp_lc();
-
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_SET_FPS:
-		case CFG_SET_PICT_FPS:
-			rc = vx6953_set_fps(&(cdata.cfg.fps));
-			break;
-
-		case CFG_SET_EXP_GAIN:
-			rc =
-				vx6953_write_exp_gain(
-					cdata.cfg.exp_gain.gain,
-					cdata.cfg.exp_gain.line);
-			break;
-
-		case CFG_SET_PICT_EXP_GAIN:
-			rc =
-				vx6953_set_pict_exp_gain(
-				cdata.cfg.exp_gain.gain,
-				cdata.cfg.exp_gain.line);
-			break;
-
-		case CFG_SET_MODE:
-			rc = vx6953_set_sensor_mode(cdata.mode,
-					cdata.rs);
-			break;
-
-		case CFG_PWR_DOWN:
-			rc = vx6953_power_down();
-			break;
-
-		case CFG_MOVE_FOCUS:
-			rc =
-				vx6953_move_focus(
-				cdata.cfg.focus.dir,
-				cdata.cfg.focus.steps);
-			break;
-
-		case CFG_SET_DEFAULT_FOCUS:
-			rc =
-				vx6953_set_default_focus(
-				cdata.cfg.focus.steps);
-			break;
-
-		case CFG_SET_EFFECT:
-			rc = vx6953_set_default_focus(
-				cdata.cfg.effect);
-			break;
-
-
-		case CFG_SEND_WB_INFO:
-			rc = vx6953_send_wb_info(
-				&(cdata.cfg.wb_info));
-			break;
-
-		default:
-			rc = -EFAULT;
-			break;
-		}
-
-	mutex_unlock(&vx6953_mut);
-
-	return rc;
-}
-
-
-
-
-static int vx6953_sensor_release(void)
-{
-	int rc = -EBADF;
-	mutex_lock(&vx6953_mut);
-	vx6953_power_down();
-	gpio_direction_output(vx6953_ctrl->sensordata->sensor_reset, 0);
-	gpio_free(vx6953_ctrl->sensordata->sensor_reset);
-	kfree(vx6953_ctrl);
-	vx6953_ctrl = NULL;
-	CDBG("vx6953_release completed\n");
-	mutex_unlock(&vx6953_mut);
-
-	return rc;
-}
-
-static int vx6953_sensor_probe(const struct msm_camera_sensor_info *info,
-		struct msm_sensor_ctrl *s)
-{
-	int rc = 0;
-	rc = i2c_add_driver(&vx6953_i2c_driver);
-	if (rc < 0 || vx6953_client == NULL) {
-		rc = -ENOTSUPP;
-		goto probe_fail;
-	}
-	msm_camio_clk_rate_set(24000000);
-	rc = vx6953_probe_init_sensor(info);
-	if (rc < 0)
-		goto probe_fail;
-	s->s_init = vx6953_sensor_open_init;
-	s->s_release = vx6953_sensor_release;
-	s->s_config  = vx6953_sensor_config;
-	s->s_mount_angle  = info->sensor_platform_info->mount_angle;
-	vx6953_probe_init_done(info);
-	return rc;
-
-probe_fail:
-	CDBG("vx6953_sensor_probe: SENSOR PROBE FAILS!\n");
-	return rc;
-}
-
-static int __vx6953_probe(struct platform_device *pdev)
-{
-	return msm_camera_drv_start(pdev, vx6953_sensor_probe);
-}
-
-static struct platform_driver msm_camera_driver = {
-	.probe = __vx6953_probe,
-	.driver = {
-		.name = "msm_camera_vx6953",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init vx6953_init(void)
-{
-	return platform_driver_register(&msm_camera_driver);
-}
-
-module_init(vx6953_init);
-void vx6953_exit(void)
-{
-	i2c_del_driver(&vx6953_i2c_driver);
-}
-
-
diff --git a/drivers/media/video/msm/vx6953.h b/drivers/media/video/msm/vx6953.h
deleted file mode 100644
index 0e12063..0000000
--- a/drivers/media/video/msm/vx6953.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. 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 VX6953_H
-#define VX6953_H
-#include <linux/types.h>
-#include <mach/board.h>
-extern struct vx6953_reg vx6953_regs;
-struct reg_struct_init {
-	uint8_t reg_0x0112;      /* 0x0112*/
-	uint8_t reg_0x0113;      /* 0x0113*/
-	uint8_t vt_pix_clk_div;  /* 0x0301*/
-	uint8_t pre_pll_clk_div; /* 0x0305*/
-	uint8_t pll_multiplier;  /* 0x0307*/
-	uint8_t op_pix_clk_div;  /* 0x0309*/
-	uint8_t reg_0x3030;      /*0x3030*/
-	uint8_t reg_0x0111;      /*0x0111*/
-	uint8_t reg_0x0b00;      /*0x0b00*/
-	uint8_t reg_0x3001;      /*0x3001*/
-	uint8_t reg_0x3004;      /*0x3004*/
-	uint8_t reg_0x3007;      /*0x3007*/
-	uint8_t reg_0x3016;      /*0x3016*/
-	uint8_t reg_0x301d;      /*0x301d*/
-	uint8_t reg_0x317e;      /*0x317E*/
-	uint8_t reg_0x317f;      /*0x317F*/
-	uint8_t reg_0x3400;      /*0x3400*/
-	uint8_t reg_0x0b06;      /*0x0b06*/
-	uint8_t reg_0x0b07;      /*0x0b07*/
-	uint8_t reg_0x0b08;      /*0x0b08*/
-	uint8_t reg_0x0b09;      /*0x0b09*/
-	uint8_t reg_0x0136;
-	uint8_t reg_0x0137;
-	/* Edof */
-	uint8_t reg_0x0b83;      /*0x0b83*/
-	uint8_t reg_0x0b84;      /*0x0b84*/
-	uint8_t reg_0x0b85;      /*0x0b85*/
-	uint8_t reg_0x0b88;      /*0x0b88*/
-	uint8_t reg_0x0b89;      /*0x0b89*/
-	uint8_t reg_0x0b8a;      /*0x0b8a*/
-	};
-struct reg_struct {
-	uint8_t coarse_integration_time_hi; /*REG_COARSE_INTEGRATION_TIME_HI*/
-	uint8_t coarse_integration_time_lo; /*REG_COARSE_INTEGRATION_TIME_LO*/
-	uint8_t analogue_gain_code_global;
-	uint8_t frame_length_lines_hi; /* 0x0340*/
-	uint8_t frame_length_lines_lo; /* 0x0341*/
-	uint8_t line_length_pck_hi;    /* 0x0342*/
-	uint8_t line_length_pck_lo;    /* 0x0343*/
-	uint8_t reg_0x3005;   /* 0x3005*/
-	uint8_t reg_0x3010;  /* 0x3010*/
-	uint8_t reg_0x3011;  /* 0x3011*/
-	uint8_t reg_0x301a;  /* 0x301a*/
-	uint8_t reg_0x3035;  /* 0x3035*/
-	uint8_t reg_0x3036;   /* 0x3036*/
-	uint8_t reg_0x3041;  /*0x3041*/
-	uint8_t reg_0x3042;  /*0x3042*/
-	uint8_t reg_0x3045;  /*0x3045*/
-	uint8_t reg_0x0b80;   /* 0x0b80*/
-	uint8_t reg_0x0900;   /*0x0900*/
-	uint8_t reg_0x0901;   /* 0x0901*/
-	uint8_t reg_0x0902;   /*0x0902*/
-	uint8_t reg_0x0383;   /*0x0383*/
-	uint8_t reg_0x0387;   /* 0x0387*/
-	uint8_t reg_0x034c;   /* 0x034c*/
-	uint8_t reg_0x034d;   /*0x034d*/
-	uint8_t reg_0x034e;   /* 0x034e*/
-	uint8_t reg_0x034f;   /* 0x034f*/
-	uint8_t reg_0x1716; /*0x1716*/
-	uint8_t reg_0x1717; /*0x1717*/
-	uint8_t reg_0x1718; /*0x1718*/
-	uint8_t reg_0x1719; /*0x1719*/
-	uint8_t reg_0x3210;/*0x3210*/
-	uint8_t reg_0x111; /*0x111*/
-	uint8_t reg_0x3410;  /*0x3410*/
-	uint8_t reg_0x3098;
-	uint8_t reg_0x309D;
-	uint8_t reg_0x0200;
-	uint8_t reg_0x0201;
-	};
-struct vx6953_i2c_reg_conf {
-	unsigned short waddr;
-	unsigned short wdata;
-};
-
-enum vx6953_test_mode_t {
-	TEST_OFF,
-	TEST_1,
-	TEST_2,
-	TEST_3
-};
-
-enum vx6953_resolution_t {
-	QTR_SIZE,
-	FULL_SIZE,
-	INVALID_SIZE
-};
-enum vx6953_setting {
-	RES_PREVIEW,
-	RES_CAPTURE
-};
-enum mt9p012_reg_update {
-	/* Sensor egisters that need to be updated during initialization */
-	REG_INIT,
-	/* Sensor egisters that needs periodic I2C writes */
-	UPDATE_PERIODIC,
-	/* All the sensor Registers will be updated */
-	UPDATE_ALL,
-	/* Not valid update */
-	UPDATE_INVALID
-};
-
-enum sensor_revision_t {
-	VX6953_STM5M0EDOF_CUT_1,
-	VX6953_STM5M0EDOF_CUT_2,
-	VX6953_STM5M0EDOF_CUT_3
-};
-enum edof_mode_t {
-	VX6953_EDOF_DISABLE,       /* 0x00 */
-	VX6953_EDOF_APPLICATION,   /* 0x01 */
-	VX6953_EDOF_ESTIMATION     /* 0x02 */
-};
-struct vx6953_reg {
-	const struct reg_struct_init  *reg_pat_init;
-	const struct reg_struct  *reg_pat;
-};
-#endif /* VX6953_H */
diff --git a/drivers/media/video/msm/vx6953_reg.c b/drivers/media/video/msm/vx6953_reg.c
deleted file mode 100644
index 48fc71f..0000000
--- a/drivers/media/video/msm/vx6953_reg.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. 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 "vx6953.h"
-const struct reg_struct_init vx6953_reg_init[1] = {
-	{
-		10,			/*REG = 0x0112 , 10 bit */
-		10,			/*REG = 0x0113*/
-		9,			/*REG = 0x0301 vt_pix_clk_div*/
-		4,		/*REG = 0x0305 pre_pll_clk_div*/
-		133,		/*REG = 0x0307 pll_multiplier*/
-		10,		/*REG = 0x0309 op_pix_clk_div*/
-		0x08,		/*REG = 0x3030*/
-		0x02,		/*REG = 0x0111*/
-		0x01,		/*REG = 0x0b00 ,lens shading off */
-		0x30,		/*REG = 0x3001*/
-		0x33,		/*REG = 0x3004*/
-		0x09,		/*REG = 0x3007*/
-		0x1F,		/*REG = 0x3016*/
-		0x03,		/*REG = 0x301d*/
-		0x11,		/*REG = 0x317E*/
-		0x09,		/*REG = 0x317F*/
-		0x38,		/*REG = 0x3400*/
-		0x00,		/*REG_0x0b06*/
-		0x80,		/*REG_0x0b07*/
-		0x01,		/*REG_0x0b08*/
-		0x4F,		/*REG_0x0b09*/
-		0x18,		/*REG_0x0136*/
-		0x00,		/*/REG_0x0137*/
-		0x20,		/*REG = 0x0b83*/
-		0x90,		/*REG = 0x0b84*/
-		0x20,		/*REG = 0x0b85*/
-		0x80,		/*REG = 0x0b88*/
-		0x00,		/*REG = 0x0b89*/
-		0x00,		/*REG = 0x0b8a*/
-	}
-};
-const struct reg_struct vx6953_reg_pat[2] = {
-	{/* Preview */
-		0x03,	/*REG = 0x0202 coarse integration_time_hi*/
-		0xd0,	/*REG = 0x0203 coarse_integration_time_lo*/
-		0xc0,	/*REG = 0x0205 analogue_gain_code_global*/
-		0x03,	/*REG = 0x0340 frame_length_lines_hi*/
-		0xf0,	/*REG = 0x0341 frame_length_lines_lo*/
-		0x0b,	/*REG = 0x0342  line_length_pck_hi*/
-		0x74,	/*REG = 0x0343  line_length_pck_lo*/
-		0x03,	/*REG = 0x3005*/
-		0x00,	/*REG = 0x3010*/
-		0x01,	/*REG = 0x3011*/
-		0x6a,	/*REG = 0x301a*/
-		0x03,	/*REG = 0x3035*/
-		0x2c,	/*REG = 0x3036*/
-		0x00,	/*REG = 0x3041*/
-		0x24,	/*REG = 0x3042*/
-		0x81,	/*REG = 0x3045*/
-		0x02,	/*REG = 0x0b80 edof estimate*/
-		0x01,	/*REG = 0x0900*/
-		0x22,	/*REG = 0x0901*/
-		0x04,	/*REG = 0x0902*/
-		0x03,	/*REG = 0x0383*/
-		0x03,	/*REG = 0x0387*/
-		0x05,	/*REG = 0x034c*/
-		0x18,	/*REG = 0x034d*/
-		0x03,	/*REG = 0x034e*/
-		0xd4,	/*REG = 0x034f*/
-		0x02,	/*0x1716*/
-		0x04,	/*0x1717*/
-		0x08,	/*0x1718*/
-		0x2c,	/*0x1719*/
-		0x01,   /*0x3210*/
-		0x02,   /*0x111*/
-		0x01,   /*0x3410*/
-		0x01,   /*0x3098*/
-		0x05,   /*0x309D*/
-		0x02,
-		0x04,
-	},
-	{ /* Snapshot */
-		0x07,/*REG = 0x0202 coarse_integration_time_hi*/
-		0x00,/*REG = 0x0203 coarse_integration_time_lo*/
-		0xc0,/*REG = 0x0205 analogue_gain_code_global*/
-		0x07,/*REG = 0x0340 frame_length_lines_hi*/
-		0xd0,/*REG = 0x0341 frame_length_lines_lo*/
-		0x0b,/*REG = 0x0342 line_length_pck_hi*/
-		0x8c,/*REG = 0x0343 line_length_pck_lo*/
-		0x01,/*REG = 0x3005*/
-		0x00,/*REG = 0x3010*/
-		0x00,/*REG = 0x3011*/
-		0x55,/*REG = 0x301a*/
-		0x01,/*REG = 0x3035*/
-		0x23,/*REG = 0x3036*/
-		0x00,/*REG = 0x3041*/
-		0x24,/*REG = 0x3042*/
-		0xb7,/*REG = 0x3045*/
-		0x01,/*REG = 0x0b80 edof application*/
-		0x00,/*REG = 0x0900*/
-		0x00,/*REG = 0x0901*/
-		0x00,/*REG = 0x0902*/
-		0x01,/*REG = 0x0383*/
-		0x01,/*REG = 0x0387*/
-		0x0A,/*REG = 0x034c*/
-		0x30,/*REG = 0x034d*/
-		0x07,/*REG = 0x034e*/
-		0xA8,/*REG = 0x034f*/
-		0x02,/*0x1716*/
-		0x0d,/*0x1717*/
-		0x07,/*0x1718*/
-		0x7d,/*0x1719*/
-		0x01,/*0x3210*/
-		0x02,/*0x111*/
-		0x01,/*0x3410*/
-		0x01,/*0x3098*/
-		0x05, /*0x309D*/
-		0x02,
-		0x00,
-	}
-};
-
-
-
-struct vx6953_reg vx6953_regs = {
-	.reg_pat_init = &vx6953_reg_init[0],
-	.reg_pat = &vx6953_reg_pat[0],
-};
diff --git a/drivers/media/video/msm/vx6953_reg_v4l2.c b/drivers/media/video/msm/vx6953_reg_v4l2.c
deleted file mode 100644
index f16054b..0000000
--- a/drivers/media/video/msm/vx6953_reg_v4l2.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. 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 "vx6953_v4l2.h"
-const struct reg_struct_init vx6953_reg_init[1] = {
-	{
-		10,			/*REG = 0x0112 , 10 bit */
-		10,			/*REG = 0x0113*/
-		9,			/*REG = 0x0301 vt_pix_clk_div*/
-		4,		/*REG = 0x0305 pre_pll_clk_div*/
-		133,		/*REG = 0x0307 pll_multiplier*/
-		10,		/*REG = 0x0309 op_pix_clk_div*/
-		0x08,		/*REG = 0x3030*/
-		0x02,		/*REG = 0x0111*/
-		0x01,		/*REG = 0x0b00 ,lens shading off */
-		0x30,		/*REG = 0x3001*/
-		0x33,		/*REG = 0x3004*/
-		0x09,		/*REG = 0x3007*/
-		0x1F,		/*REG = 0x3016*/
-		0x03,		/*REG = 0x301d*/
-		0x11,		/*REG = 0x317E*/
-		0x09,		/*REG = 0x317F*/
-		0x38,		/*REG = 0x3400*/
-		0x00,		/*REG_0x0b06*/
-		0x80,		/*REG_0x0b07*/
-		0x01,		/*REG_0x0b08*/
-		0x4F,		/*REG_0x0b09*/
-		0x18,		/*REG_0x0136*/
-		0x00,		/*/REG_0x0137*/
-		0x20,		/*REG = 0x0b83*/
-		0x90,		/*REG = 0x0b84*/
-		0x20,		/*REG = 0x0b85*/
-		0x80,		/*REG = 0x0b88*/
-		0x00,		/*REG = 0x0b89*/
-		0x00,		/*REG = 0x0b8a*/
-	}
-};
-const struct reg_struct vx6953_reg_pat[2] = {
-	{/* Preview */
-		0x03,	/*REG = 0x0202 coarse integration_time_hi*/
-		0xd0,	/*REG = 0x0203 coarse_integration_time_lo*/
-		0xc0,	/*REG = 0x0205 analogue_gain_code_global*/
-		0x03,	/*REG = 0x0340 frame_length_lines_hi*/
-		0xf0,	/*REG = 0x0341 frame_length_lines_lo*/
-		0x0b,	/*REG = 0x0342  line_length_pck_hi*/
-		0xa5,	/*REG = 0x0343  line_length_pck_lo*/
-		0x03,	/*REG = 0x3005*/
-		0x00,	/*REG = 0x3010*/
-		0x01,	/*REG = 0x3011*/
-		0x6a,	/*REG = 0x301a*/
-		0x03,	/*REG = 0x3035*/
-		0x2c,	/*REG = 0x3036*/
-		0x00,	/*REG = 0x3041*/
-		0x24,	/*REG = 0x3042*/
-		0x81,	/*REG = 0x3045*/
-		0x02,	/*REG = 0x0b80 edof estimate*/
-		0x01,	/*REG = 0x0900*/
-		0x22,	/*REG = 0x0901*/
-		0x04,	/*REG = 0x0902*/
-		0x03,	/*REG = 0x0383*/
-		0x03,	/*REG = 0x0387*/
-		0x05,	/*REG = 0x034c*/
-		0x18,	/*REG = 0x034d*/
-		0x03,	/*REG = 0x034e*/
-		0xd4,	/*REG = 0x034f*/
-		0x02,	/*0x1716*/
-		0x04,	/*0x1717*/
-		0x08,	/*0x1718*/
-		0x80,	/*0x1719*/
-		0x01,   /*0x3210*/
-		0x02,   /*0x111*/
-		0x01,   /*0x3410*/
-		0x01,   /*0x3098*/
-		0x05,   /*0x309D*/
-		0x02,
-		0x04,
-	},
-	{ /* Snapshot */
-		0x07,/*REG = 0x0202 coarse_integration_time_hi*/
-		0x00,/*REG = 0x0203 coarse_integration_time_lo*/
-		0xc0,/*REG = 0x0205 analogue_gain_code_global*/
-		0x07,/*REG = 0x0340 frame_length_lines_hi*/
-		0xd0,/*REG = 0x0341 frame_length_lines_lo*/
-		0x0b,/*REG = 0x0342 line_length_pck_hi*/
-		0x8c,/*REG = 0x0343 line_length_pck_lo*/
-		0x01,/*REG = 0x3005*/
-		0x00,/*REG = 0x3010*/
-		0x00,/*REG = 0x3011*/
-		0x55,/*REG = 0x301a*/
-		0x01,/*REG = 0x3035*/
-		0x23,/*REG = 0x3036*/
-		0x00,/*REG = 0x3041*/
-		0x24,/*REG = 0x3042*/
-		0xb7,/*REG = 0x3045*/
-		0x01,/*REG = 0x0b80 edof application*/
-		0x00,/*REG = 0x0900*/
-		0x00,/*REG = 0x0901*/
-		0x00,/*REG = 0x0902*/
-		0x01,/*REG = 0x0383*/
-		0x01,/*REG = 0x0387*/
-		0x0A,/*REG = 0x034c*/
-		0x30,/*REG = 0x034d*/
-		0x07,/*REG = 0x034e*/
-		0xA8,/*REG = 0x034f*/
-		0x02,/*0x1716*/
-		0x0d,/*0x1717*/
-		0x07,/*0x1718*/
-		0x7d,/*0x1719*/
-		0x01,/*0x3210*/
-		0x02,/*0x111*/
-		0x01,/*0x3410*/
-		0x01,/*0x3098*/
-		0x05, /*0x309D*/
-		0x02,
-		0x00,
-	}
-};
-
-
-
-struct vx6953_reg vx6953_regs = {
-	.reg_pat_init = &vx6953_reg_init[0],
-	.reg_pat = &vx6953_reg_pat[0],
-};
diff --git a/drivers/media/video/msm/vx6953_v4l2.c b/drivers/media/video/msm/vx6953_v4l2.c
deleted file mode 100644
index 2e5e39b..0000000
--- a/drivers/media/video/msm/vx6953_v4l2.c
+++ /dev/null
@@ -1,4149 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. 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/delay.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <media/v4l2-subdev.h>
-#include <media/msm_camera.h>
-#include <mach/gpio.h>
-#include <mach/camera.h>
-#include <linux/slab.h>
-#include "vx6953_v4l2.h"
-#include "msm.h"
-
-#define V4L2_IDENT_VX6953  50000
-
-/*=============================================================
-	SENSOR REGISTER DEFINES
-==============================================================*/
-
-#define REG_GROUPED_PARAMETER_HOLD			0x0104
-#define GROUPED_PARAMETER_HOLD_OFF			0x00
-#define GROUPED_PARAMETER_HOLD				0x01
-#define REG_MODE_SELECT					0x0100
-#define MODE_SELECT_STANDBY_MODE			0x00
-#define MODE_SELECT_STREAM				0x01
-/* Integration Time */
-#define REG_COARSE_INTEGRATION_TIME_HI			0x0202
-#define REG_COARSE_INTEGRATION_TIME_LO			0x0203
-/* Gain */
-#define REG_ANALOGUE_GAIN_CODE_GLOBAL_HI		0x0204
-#define REG_ANALOGUE_GAIN_CODE_GLOBAL_LO		0x0205
-/* Digital Gain */
-#define REG_DIGITAL_GAIN_GREEN_R_HI			0x020E
-#define REG_DIGITAL_GAIN_GREEN_R_LO			0x020F
-#define REG_DIGITAL_GAIN_RED_HI				0x0210
-#define REG_DIGITAL_GAIN_RED_LO				0x0211
-#define REG_DIGITAL_GAIN_BLUE_HI			0x0212
-#define REG_DIGITAL_GAIN_BLUE_LO			0x0213
-#define REG_DIGITAL_GAIN_GREEN_B_HI			0x0214
-#define REG_DIGITAL_GAIN_GREEN_B_LO			0x0215
-/* output bits setting */
-#define REG_0x0112					0x0112
-#define REG_0x0113					0x0113
-/* PLL registers */
-#define REG_VT_PIX_CLK_DIV				0x0301
-#define REG_PRE_PLL_CLK_DIV				0x0305
-#define REG_PLL_MULTIPLIER				0x0307
-#define REG_OP_PIX_CLK_DIV				0x0309
-#define REG_0x034c					0x034c
-#define REG_0x034d					0x034d
-#define REG_0x034e					0x034e
-#define REG_0x034f					0x034f
-#define REG_0x0387					0x0387
-#define REG_0x0383					0x0383
-#define REG_FRAME_LENGTH_LINES_HI			0x0340
-#define REG_FRAME_LENGTH_LINES_LO			0x0341
-#define REG_LINE_LENGTH_PCK_HI				0x0342
-#define REG_LINE_LENGTH_PCK_LO				0x0343
-#define REG_0x3030					0x3030
-#define REG_0x0111					0x0111
-#define REG_0x0136					0x0136
-#define REG_0x0137					0x0137
-#define REG_0x0b00					0x0b00
-#define REG_0x3001					0x3001
-#define REG_0x3004					0x3004
-#define REG_0x3007					0x3007
-#define REG_0x301a					0x301a
-#define REG_0x3101					0x3101
-#define REG_0x3364					0x3364
-#define REG_0x3365					0x3365
-#define REG_0x0b83					0x0b83
-#define REG_0x0b84					0x0b84
-#define REG_0x0b85					0x0b85
-#define REG_0x0b88					0x0b88
-#define REG_0x0b89					0x0b89
-#define REG_0x0b8a					0x0b8a
-#define REG_0x3005					0x3005
-#define REG_0x3010					0x3010
-#define REG_0x3036					0x3036
-#define REG_0x3041					0x3041
-#define REG_0x0b80					0x0b80
-#define REG_0x0900					0x0900
-#define REG_0x0901					0x0901
-#define REG_0x0902					0x0902
-#define REG_0x3016					0x3016
-#define REG_0x301d					0x301d
-#define REG_0x317e					0x317e
-#define REG_0x317f					0x317f
-#define REG_0x3400					0x3400
-#define REG_0x303a					0x303a
-#define REG_0x1716					0x1716
-#define REG_0x1717					0x1717
-#define REG_0x1718					0x1718
-#define REG_0x1719					0x1719
-#define REG_0x3006					0x3006
-#define REG_0x301b					0x301b
-#define REG_0x3098					0x3098
-#define REG_0x309d					0x309d
-#define REG_0x3011					0x3011
-#define REG_0x3035					0x3035
-#define REG_0x3045					0x3045
-#define REG_0x3210					0x3210
-#define	REG_0x0111					0x0111
-#define REG_0x3410					0x3410
-/* Test Pattern */
-#define REG_TEST_PATTERN_MODE				0x0601
-
-/*============================================================================
-							 TYPE DECLARATIONS
-============================================================================*/
-
-/* 16bit address - 8 bit context register structure */
-#define	VX6953_STM5M0EDOF_OFFSET	9
-#define	Q8		0x00000100
-#define	Q10		0x00000400
-#define	VX6953_STM5M0EDOF_MAX_SNAPSHOT_EXPOSURE_LINE_COUNT	2922
-#define	VX6953_STM5M0EDOF_DEFAULT_MASTER_CLK_RATE	24000000
-#define	VX6953_STM5M0EDOF_OP_PIXEL_CLOCK_RATE	79800000
-#define	VX6953_STM5M0EDOF_VT_PIXEL_CLOCK_RATE	88670000
-/* Full	Size */
-#define	VX6953_FULL_SIZE_WIDTH	2608
-#define	VX6953_FULL_SIZE_HEIGHT		1960
-#define	VX6953_FULL_SIZE_DUMMY_PIXELS	1
-#define	VX6953_FULL_SIZE_DUMMY_LINES	0
-/* Quarter Size	*/
-#define	VX6953_QTR_SIZE_WIDTH	1304
-#define	VX6953_QTR_SIZE_HEIGHT		980
-#define	VX6953_QTR_SIZE_DUMMY_PIXELS	1
-#define	VX6953_QTR_SIZE_DUMMY_LINES		0
-/* Blanking	as measured	on the scope */
-/* Full	Size */
-#define	VX6953_HRZ_FULL_BLK_PIXELS	348
-#define	VX6953_VER_FULL_BLK_LINES	40
-/* Quarter Size	*/
-#define	VX6953_HRZ_QTR_BLK_PIXELS	1628
-#define	VX6953_VER_QTR_BLK_LINES	28
-#define	MAX_LINE_LENGTH_PCK		8190
-#define	VX6953_REVISION_NUMBER_CUT2	0x10/*revision number	for	Cut2.0*/
-#define	VX6953_REVISION_NUMBER_CUT3	0x20/*revision number	for	Cut3.0*/
-/* FIXME: Changes from here */
-struct vx6953_work_t {
-	struct work_struct work;
-};
-
-static struct vx6953_work_t *vx6953_sensorw;
-static struct i2c_client *vx6953_client;
-
-struct vx6953_ctrl_t {
-	const struct  msm_camera_sensor_info *sensordata;
-
-	uint32_t sensormode;
-	uint32_t fps_divider;  /* init to 1 * 0x00000400 */
-	uint32_t pict_fps_divider;  /* init to 1 * 0x00000400 */
-	uint16_t fps;
-
-	int16_t curr_lens_pos;
-	uint16_t curr_step_pos;
-	uint16_t my_reg_gain;
-	uint32_t my_reg_line_count;
-	uint16_t total_lines_per_frame;
-
-	enum vx6953_resolution_t prev_res;
-	enum vx6953_resolution_t pict_res;
-	enum vx6953_resolution_t curr_res;
-	enum vx6953_test_mode_t  set_test;
-	enum sensor_revision_t sensor_type;
-
-	enum edof_mode_t edof_mode;
-
-	unsigned short imgaddr;
-
-	struct v4l2_subdev *sensor_dev;
-	struct vx6953_format *fmt;
-};
-
-
-static uint8_t vx6953_stm5m0edof_delay_msecs_stdby;
-static uint16_t vx6953_stm5m0edof_delay_msecs_stream = 20;
-
-static struct vx6953_ctrl_t *vx6953_ctrl;
-static DECLARE_WAIT_QUEUE_HEAD(vx6953_wait_queue);
-DEFINE_MUTEX(vx6953_mut);
-static struct vx6953_i2c_reg_conf patch_tbl_cut2[] = {
-	{0xFB94, 0},	/*intialise Data Xfer Status reg*/
-	{0xFB95, 0},	/*gain 1	  (0x00)*/
-	{0xFB96, 0},	/*gain 1.07   (0x10)*/
-	{0xFB97, 0},	/*gain 1.14   (0x20)*/
-	{0xFB98, 0},	/*gain 1.23   (0x30)*/
-	{0xFB99, 0},	/*gain 1.33   (0x40)*/
-	{0xFB9A, 0},	/*gain 1.45   (0x50)*/
-	{0xFB9B, 0},	/*gain 1.6    (0x60)*/
-	{0xFB9C, 0},	/*gain 1.78   (0x70)*/
-	{0xFB9D, 2},	/*gain 2	  (0x80)*/
-	{0xFB9E, 2},	/*gain 2.29   (0x90)*/
-	{0xFB9F, 3},	/*gain 2.67   (0xA0)*/
-	{0xFBA0, 3},	/*gain 3.2    (0xB0)*/
-	{0xFBA1, 4},	/*gain 4	  (0xC0)*/
-	{0xFBA2, 7},	/*gain 5.33   (0xD0)*/
-	{0xFBA3, 10},	/*gain 8	  (0xE0)*/
-	{0xFBA4, 11},	/*gain 9.14   (0xE4)*/
-	{0xFBA5, 13},	/*gain 10.67  (0xE8)*/
-	{0xFBA6, 15},	/*gain 12.8   (0xEC)*/
-	{0xFBA7, 19},	/*gain 16     (0xF0)*/
-	{0xF800, 0x12},
-	{0xF801, 0x06},
-	{0xF802, 0xf7},
-	{0xF803, 0x90},
-	{0xF804, 0x02},
-	{0xF805, 0x05},
-	{0xF806, 0xe0},
-	{0xF807, 0xff},
-	{0xF808, 0x65},
-	{0xF809, 0x7d},
-	{0xF80A, 0x70},
-	{0xF80B, 0x03},
-	{0xF80C, 0x02},
-	{0xF80D, 0xf9},
-	{0xF80E, 0x1c},
-	{0xF80F, 0x8f},
-	{0xF810, 0x7d},
-	{0xF811, 0xe4},
-	{0xF812, 0xf5},
-	{0xF813, 0x7a},
-	{0xF814, 0x75},
-	{0xF815, 0x78},
-	{0xF816, 0x30},
-	{0xF817, 0x75},
-	{0xF818, 0x79},
-	{0xF819, 0x53},
-	{0xF81A, 0x85},
-	{0xF81B, 0x79},
-	{0xF81C, 0x82},
-	{0xF81D, 0x85},
-	{0xF81E, 0x78},
-	{0xF81F, 0x83},
-	{0xF820, 0xe0},
-	{0xF821, 0xc3},
-	{0xF822, 0x95},
-	{0xF823, 0x7b},
-	{0xF824, 0xf0},
-	{0xF825, 0x74},
-	{0xF826, 0x02},
-	{0xF827, 0x25},
-	{0xF828, 0x79},
-	{0xF829, 0xf5},
-	{0xF82A, 0x79},
-	{0xF82B, 0xe4},
-	{0xF82C, 0x35},
-	{0xF82D, 0x78},
-	{0xF82E, 0xf5},
-	{0xF82F, 0x78},
-	{0xF830, 0x05},
-	{0xF831, 0x7a},
-	{0xF832, 0xe5},
-	{0xF833, 0x7a},
-	{0xF834, 0xb4},
-	{0xF835, 0x08},
-	{0xF836, 0xe3},
-	{0xF837, 0xe5},
-	{0xF838, 0x7d},
-	{0xF839, 0x70},
-	{0xF83A, 0x04},
-	{0xF83B, 0xff},
-	{0xF83C, 0x02},
-	{0xF83D, 0xf8},
-	{0xF83E, 0xe4},
-	{0xF83F, 0xe5},
-	{0xF840, 0x7d},
-	{0xF841, 0xb4},
-	{0xF842, 0x10},
-	{0xF843, 0x05},
-	{0xF844, 0x7f},
-	{0xF845, 0x01},
-	{0xF846, 0x02},
-	{0xF847, 0xf8},
-	{0xF848, 0xe4},
-	{0xF849, 0xe5},
-	{0xF84A, 0x7d},
-	{0xF84B, 0xb4},
-	{0xF84C, 0x20},
-	{0xF84D, 0x05},
-	{0xF84E, 0x7f},
-	{0xF84F, 0x02},
-	{0xF850, 0x02},
-	{0xF851, 0xf8},
-	{0xF852, 0xe4},
-	{0xF853, 0xe5},
-	{0xF854, 0x7d},
-	{0xF855, 0xb4},
-	{0xF856, 0x30},
-	{0xF857, 0x05},
-	{0xF858, 0x7f},
-	{0xF859, 0x03},
-	{0xF85A, 0x02},
-	{0xF85B, 0xf8},
-	{0xF85C, 0xe4},
-	{0xF85D, 0xe5},
-	{0xF85E, 0x7d},
-	{0xF85F, 0xb4},
-	{0xF860, 0x40},
-	{0xF861, 0x04},
-	{0xF862, 0x7f},
-	{0xF863, 0x04},
-	{0xF864, 0x80},
-	{0xF865, 0x7e},
-	{0xF866, 0xe5},
-	{0xF867, 0x7d},
-	{0xF868, 0xb4},
-	{0xF869, 0x50},
-	{0xF86A, 0x04},
-	{0xF86B, 0x7f},
-	{0xF86C, 0x05},
-	{0xF86D, 0x80},
-	{0xF86E, 0x75},
-	{0xF86F, 0xe5},
-	{0xF870, 0x7d},
-	{0xF871, 0xb4},
-	{0xF872, 0x60},
-	{0xF873, 0x04},
-	{0xF874, 0x7f},
-	{0xF875, 0x06},
-	{0xF876, 0x80},
-	{0xF877, 0x6c},
-	{0xF878, 0xe5},
-	{0xF879, 0x7d},
-	{0xF87A, 0xb4},
-	{0xF87B, 0x70},
-	{0xF87C, 0x04},
-	{0xF87D, 0x7f},
-	{0xF87E, 0x07},
-	{0xF87F, 0x80},
-	{0xF880, 0x63},
-	{0xF881, 0xe5},
-	{0xF882, 0x7d},
-	{0xF883, 0xb4},
-	{0xF884, 0x80},
-	{0xF885, 0x04},
-	{0xF886, 0x7f},
-	{0xF887, 0x08},
-	{0xF888, 0x80},
-	{0xF889, 0x5a},
-	{0xF88A, 0xe5},
-	{0xF88B, 0x7d},
-	{0xF88C, 0xb4},
-	{0xF88D, 0x90},
-	{0xF88E, 0x04},
-	{0xF88F, 0x7f},
-	{0xF890, 0x09},
-	{0xF891, 0x80},
-	{0xF892, 0x51},
-	{0xF893, 0xe5},
-	{0xF894, 0x7d},
-	{0xF895, 0xb4},
-	{0xF896, 0xa0},
-	{0xF897, 0x04},
-	{0xF898, 0x7f},
-	{0xF899, 0x0a},
-	{0xF89A, 0x80},
-	{0xF89B, 0x48},
-	{0xF89C, 0xe5},
-	{0xF89D, 0x7d},
-	{0xF89E, 0xb4},
-	{0xF89F, 0xb0},
-	{0xF8A0, 0x04},
-	{0xF8A1, 0x7f},
-	{0xF8A2, 0x0b},
-	{0xF8A3, 0x80},
-	{0xF8A4, 0x3f},
-	{0xF8A5, 0xe5},
-	{0xF8A6, 0x7d},
-	{0xF8A7, 0xb4},
-	{0xF8A8, 0xc0},
-	{0xF8A9, 0x04},
-	{0xF8AA, 0x7f},
-	{0xF8AB, 0x0c},
-	{0xF8AC, 0x80},
-	{0xF8AD, 0x36},
-	{0xF8AE, 0xe5},
-	{0xF8AF, 0x7d},
-	{0xF8B0, 0xb4},
-	{0xF8B1, 0xd0},
-	{0xF8B2, 0x04},
-	{0xF8B3, 0x7f},
-	{0xF8B4, 0x0d},
-	{0xF8B5, 0x80},
-	{0xF8B6, 0x2d},
-	{0xF8B7, 0xe5},
-	{0xF8B8, 0x7d},
-	{0xF8B9, 0xb4},
-	{0xF8BA, 0xe0},
-	{0xF8BB, 0x04},
-	{0xF8BC, 0x7f},
-	{0xF8BD, 0x0e},
-	{0xF8BE, 0x80},
-	{0xF8BF, 0x24},
-	{0xF8C0, 0xe5},
-	{0xF8C1, 0x7d},
-	{0xF8C2, 0xb4},
-	{0xF8C3, 0xe4},
-	{0xF8C4, 0x04},
-	{0xF8C5, 0x7f},
-	{0xF8C6, 0x0f},
-	{0xF8C7, 0x80},
-	{0xF8C8, 0x1b},
-	{0xF8C9, 0xe5},
-	{0xF8CA, 0x7d},
-	{0xF8CB, 0xb4},
-	{0xF8CC, 0xe8},
-	{0xF8CD, 0x04},
-	{0xF8CE, 0x7f},
-	{0xF8CF, 0x10},
-	{0xF8D0, 0x80},
-	{0xF8D1, 0x12},
-	{0xF8D2, 0xe5},
-	{0xF8D3, 0x7d},
-	{0xF8D4, 0xb4},
-	{0xF8D5, 0xec},
-	{0xF8D6, 0x04},
-	{0xF8D7, 0x7f},
-	{0xF8D8, 0x11},
-	{0xF8D9, 0x80},
-	{0xF8DA, 0x09},
-	{0xF8DB, 0xe5},
-	{0xF8DC, 0x7d},
-	{0xF8DD, 0x7f},
-	{0xF8DE, 0x00},
-	{0xF8DF, 0xb4},
-	{0xF8E0, 0xf0},
-	{0xF8E1, 0x02},
-	{0xF8E2, 0x7f},
-	{0xF8E3, 0x12},
-	{0xF8E4, 0x8f},
-	{0xF8E5, 0x7c},
-	{0xF8E6, 0xef},
-	{0xF8E7, 0x24},
-	{0xF8E8, 0x95},
-	{0xF8E9, 0xff},
-	{0xF8EA, 0xe4},
-	{0xF8EB, 0x34},
-	{0xF8EC, 0xfb},
-	{0xF8ED, 0x8f},
-	{0xF8EE, 0x82},
-	{0xF8EF, 0xf5},
-	{0xF8F0, 0x83},
-	{0xF8F1, 0xe4},
-	{0xF8F2, 0x93},
-	{0xF8F3, 0xf5},
-	{0xF8F4, 0x7c},
-	{0xF8F5, 0xf5},
-	{0xF8F6, 0x7b},
-	{0xF8F7, 0xe4},
-	{0xF8F8, 0xf5},
-	{0xF8F9, 0x7a},
-	{0xF8FA, 0x75},
-	{0xF8FB, 0x78},
-	{0xF8FC, 0x30},
-	{0xF8FD, 0x75},
-	{0xF8FE, 0x79},
-	{0xF8FF, 0x53},
-	{0xF900, 0x85},
-	{0xF901, 0x79},
-	{0xF902, 0x82},
-	{0xF903, 0x85},
-	{0xF904, 0x78},
-	{0xF905, 0x83},
-	{0xF906, 0xe0},
-	{0xF907, 0x25},
-	{0xF908, 0x7c},
-	{0xF909, 0xf0},
-	{0xF90A, 0x74},
-	{0xF90B, 0x02},
-	{0xF90C, 0x25},
-	{0xF90D, 0x79},
-	{0xF90E, 0xf5},
-	{0xF90F, 0x79},
-	{0xF910, 0xe4},
-	{0xF911, 0x35},
-	{0xF912, 0x78},
-	{0xF913, 0xf5},
-	{0xF914, 0x78},
-	{0xF915, 0x05},
-	{0xF916, 0x7a},
-	{0xF917, 0xe5},
-	{0xF918, 0x7a},
-	{0xF919, 0xb4},
-	{0xF91A, 0x08},
-	{0xF91B, 0xe4},
-	{0xF91C, 0x02},
-	{0xF91D, 0x18},
-	{0xF91E, 0x32},
-	{0xF91F, 0x22},
-	{0xF920, 0xf0},
-	{0xF921, 0x90},
-	{0xF922, 0xa0},
-	{0xF923, 0xf8},
-	{0xF924, 0xe0},
-	{0xF925, 0x70},
-	{0xF926, 0x02},
-	{0xF927, 0xa3},
-	{0xF928, 0xe0},
-	{0xF929, 0x70},
-	{0xF92A, 0x0a},
-	{0xF92B, 0x90},
-	{0xF92C, 0xa1},
-	{0xF92D, 0x10},
-	{0xF92E, 0xe0},
-	{0xF92F, 0xfe},
-	{0xF930, 0xa3},
-	{0xF931, 0xe0},
-	{0xF932, 0xff},
-	{0xF933, 0x80},
-	{0xF934, 0x04},
-	{0xF935, 0x7e},
-	{0xF936, 0x00},
-	{0xF937, 0x7f},
-	{0xF938, 0x00},
-	{0xF939, 0x8e},
-	{0xF93A, 0x7e},
-	{0xF93B, 0x8f},
-	{0xF93C, 0x7f},
-	{0xF93D, 0x90},
-	{0xF93E, 0x36},
-	{0xF93F, 0x0d},
-	{0xF940, 0xe0},
-	{0xF941, 0x44},
-	{0xF942, 0x02},
-	{0xF943, 0xf0},
-	{0xF944, 0x90},
-	{0xF945, 0x36},
-	{0xF946, 0x0e},
-	{0xF947, 0xe5},
-	{0xF948, 0x7e},
-	{0xF949, 0xf0},
-	{0xF94A, 0xa3},
-	{0xF94B, 0xe5},
-	{0xF94C, 0x7f},
-	{0xF94D, 0xf0},
-	{0xF94E, 0xe5},
-	{0xF94F, 0x3a},
-	{0xF950, 0x60},
-	{0xF951, 0x0c},
-	{0xF952, 0x90},
-	{0xF953, 0x36},
-	{0xF954, 0x09},
-	{0xF955, 0xe0},
-	{0xF956, 0x70},
-	{0xF957, 0x06},
-	{0xF958, 0x90},
-	{0xF959, 0x36},
-	{0xF95A, 0x08},
-	{0xF95B, 0xf0},
-	{0xF95C, 0xf5},
-	{0xF95D, 0x3a},
-	{0xF95E, 0x02},
-	{0xF95F, 0x03},
-	{0xF960, 0x94},
-	{0xF961, 0x22},
-	{0xF962, 0x78},
-	{0xF963, 0x07},
-	{0xF964, 0xe6},
-	{0xF965, 0xd3},
-	{0xF966, 0x94},
-	{0xF967, 0x00},
-	{0xF968, 0x40},
-	{0xF969, 0x16},
-	{0xF96A, 0x16},
-	{0xF96B, 0xe6},
-	{0xF96C, 0x90},
-	{0xF96D, 0x30},
-	{0xF96E, 0xa1},
-	{0xF96F, 0xf0},
-	{0xF970, 0x90},
-	{0xF971, 0x43},
-	{0xF972, 0x83},
-	{0xF973, 0xe0},
-	{0xF974, 0xb4},
-	{0xF975, 0x01},
-	{0xF976, 0x0f},
-	{0xF977, 0x90},
-	{0xF978, 0x43},
-	{0xF979, 0x87},
-	{0xF97A, 0xe0},
-	{0xF97B, 0xb4},
-	{0xF97C, 0x01},
-	{0xF97D, 0x08},
-	{0xF97E, 0x80},
-	{0xF97F, 0x00},
-	{0xF980, 0x90},
-	{0xF981, 0x30},
-	{0xF982, 0xa0},
-	{0xF983, 0x74},
-	{0xF984, 0x01},
-	{0xF985, 0xf0},
-	{0xF986, 0x22},
-	{0xF987, 0xf0},
-	{0xF988, 0x90},
-	{0xF989, 0x35},
-	{0xF98A, 0xba},
-	{0xF98B, 0xe0},
-	{0xF98C, 0xb4},
-	{0xF98D, 0x0a},
-	{0xF98E, 0x0d},
-	{0xF98F, 0xa3},
-	{0xF990, 0xe0},
-	{0xF991, 0xb4},
-	{0xF992, 0x01},
-	{0xF993, 0x08},
-	{0xF994, 0x90},
-	{0xF995, 0xfb},
-	{0xF996, 0x94},
-	{0xF997, 0xe0},
-	{0xF998, 0x90},
-	{0xF999, 0x35},
-	{0xF99A, 0xb8},
-	{0xF99B, 0xf0},
-	{0xF99C, 0xd0},
-	{0xF99D, 0xd0},
-	{0xF99E, 0xd0},
-	{0xF99F, 0x82},
-	{0xF9A0, 0xd0},
-	{0xF9A1, 0x83},
-	{0xF9A2, 0xd0},
-	{0xF9A3, 0xe0},
-	{0xF9A4, 0x32},
-	{0xF9A5, 0x22},
-	{0xF9A6, 0xe5},
-	{0xF9A7, 0x7f},
-	{0xF9A8, 0x45},
-	{0xF9A9, 0x7e},
-	{0xF9AA, 0x60},
-	{0xF9AB, 0x15},
-	{0xF9AC, 0x90},
-	{0xF9AD, 0x01},
-	{0xF9AE, 0x00},
-	{0xF9AF, 0xe0},
-	{0xF9B0, 0x70},
-	{0xF9B1, 0x0f},
-	{0xF9B2, 0x90},
-	{0xF9B3, 0xa0},
-	{0xF9B4, 0xf8},
-	{0xF9B5, 0xe5},
-	{0xF9B6, 0x7e},
-	{0xF9B7, 0xf0},
-	{0xF9B8, 0xa3},
-	{0xF9B9, 0xe5},
-	{0xF9BA, 0x7f},
-	{0xF9BB, 0xf0},
-	{0xF9BC, 0xe4},
-	{0xF9BD, 0xf5},
-	{0xF9BE, 0x7e},
-	{0xF9BF, 0xf5},
-	{0xF9C0, 0x7f},
-	{0xF9C1, 0x22},
-	{0xF9C2, 0x02},
-	{0xF9C3, 0x0e},
-	{0xF9C4, 0x79},
-	{0xF9C5, 0x22},
-	/* Offsets:*/
-	{0x35C6, 0x00},/* FIDDLEDARKCAL*/
-	{0x35C7, 0x00},
-	{0x35C8, 0x01},/*STOREDISTANCEATSTOPSTREAMING*/
-	{0x35C9, 0x20},
-	{0x35CA, 0x01},/*BRUCEFIX*/
-	{0x35CB, 0x62},
-	{0x35CC, 0x01},/*FIXDATAXFERSTATUSREG*/
-	{0x35CD, 0x87},
-	{0x35CE, 0x01},/*FOCUSDISTANCEUPDATE*/
-	{0x35CF, 0xA6},
-	{0x35D0, 0x01},/*SKIPEDOFRESET*/
-	{0x35D1, 0xC2},
-	{0x35D2, 0x00},
-	{0x35D3, 0xFB},
-	{0x35D4, 0x00},
-	{0x35D5, 0x94},
-	{0x35D6, 0x00},
-	{0x35D7, 0xFB},
-	{0x35D8, 0x00},
-	{0x35D9, 0x94},
-	{0x35DA, 0x00},
-	{0x35DB, 0xFB},
-	{0x35DC, 0x00},
-	{0x35DD, 0x94},
-	{0x35DE, 0x00},
-	{0x35DF, 0xFB},
-	{0x35E0, 0x00},
-	{0x35E1, 0x94},
-	{0x35E6, 0x18},/* FIDDLEDARKCAL*/
-	{0x35E7, 0x2F},
-	{0x35E8, 0x03},/* STOREDISTANCEATSTOPSTREAMING*/
-	{0x35E9, 0x93},
-	{0x35EA, 0x18},/* BRUCEFIX*/
-	{0x35EB, 0x99},
-	{0x35EC, 0x00},/* FIXDATAXFERSTATUSREG*/
-	{0x35ED, 0xA3},
-	{0x35EE, 0x21},/* FOCUSDISTANCEUPDATE*/
-	{0x35EF, 0x5B},
-	{0x35F0, 0x0E},/* SKIPEDOFRESET*/
-	{0x35F1, 0x74},
-	{0x35F2, 0x04},
-	{0x35F3, 0x64},
-	{0x35F4, 0x04},
-	{0x35F5, 0x65},
-	{0x35F6, 0x04},
-	{0x35F7, 0x7B},
-	{0x35F8, 0x04},
-	{0x35F9, 0x7C},
-	{0x35FA, 0x04},
-	{0x35FB, 0xDD},
-	{0x35FC, 0x04},
-	{0x35FD, 0xDE},
-	{0x35FE, 0x04},
-	{0x35FF, 0xEF},
-	{0x3600, 0x04},
-	{0x3601, 0xF0},
-	/*Jump/Data:*/
-	{0x35C2, 0x3F},/* Jump Reg*/
-	{0x35C3, 0xFF},/* Jump Reg*/
-	{0x35C4, 0x3F},/* Data Reg*/
-	{0x35C5, 0xC0},/* Data Reg*/
-	{0x35C0, 0x01},/* Enable*/
-
-};
-
-static struct vx6953_i2c_reg_conf edof_tbl[] = {
-	{0xa098, 0x02},
-	{0xa099, 0x87},
-	{0xa09c, 0x00},
-	{0xa09d, 0xc5},
-	{0xa4ec, 0x05},
-	{0xa4ed, 0x05},
-	{0xa4f0, 0x04},
-	{0xa4f1, 0x04},
-	{0xa4f4, 0x04},
-	{0xa4f5, 0x05},
-	{0xa4f8, 0x05},
-	{0xa4f9, 0x07},
-	{0xa4fc, 0x07},
-	{0xa4fd, 0x07},
-	{0xa500, 0x07},
-	{0xa501, 0x07},
-	{0xa504, 0x08},
-	{0xa505, 0x08},
-	{0xa518, 0x01},
-	{0xa519, 0x02},
-	{0xa51c, 0x01},
-	{0xa51d, 0x00},
-	{0xa534, 0x00},
-	{0xa535, 0x04},
-	{0xa538, 0x04},
-	{0xa539, 0x03},
-	{0xa53c, 0x05},
-	{0xa53d, 0x07},
-	{0xa540, 0x07},
-	{0xa541, 0x06},
-	{0xa544, 0x07},
-	{0xa545, 0x06},
-	{0xa548, 0x05},
-	{0xa549, 0x06},
-	{0xa54c, 0x06},
-	{0xa54d, 0x07},
-	{0xa550, 0x07},
-	{0xa551, 0x04},
-	{0xa554, 0x04},
-	{0xa555, 0x04},
-	{0xa558, 0x05},
-	{0xa559, 0x06},
-	{0xa55c, 0x07},
-	{0xa55d, 0x07},
-	{0xa56c, 0x00},
-	{0xa56d, 0x0a},
-	{0xa570, 0x08},
-	{0xa571, 0x05},
-	{0xa574, 0x04},
-	{0xa575, 0x03},
-	{0xa578, 0x04},
-	{0xa579, 0x04},
-	{0xa58c, 0x1f},
-	{0xa58d, 0x1b},
-	{0xa590, 0x17},
-	{0xa591, 0x13},
-	{0xa594, 0x10},
-	{0xa595, 0x0d},
-	{0xa598, 0x0f},
-	{0xa599, 0x11},
-	{0xa59c, 0x03},
-	{0xa59d, 0x03},
-	{0xa5a0, 0x03},
-	{0xa5a1, 0x03},
-	{0xa5a4, 0x03},
-	{0xa5a5, 0x04},
-	{0xa5a8, 0x05},
-	{0xa5a9, 0x00},
-	{0xa5ac, 0x00},
-	{0xa5ad, 0x00},
-	{0xa5b0, 0x00},
-	{0xa5b1, 0x00},
-	{0xa5b4, 0x00},
-	{0xa5b5, 0x00},
-	{0xa5c4, 0x1f},
-	{0xa5c5, 0x13},
-	{0xa5c8, 0x14},
-	{0xa5c9, 0x14},
-	{0xa5cc, 0x14},
-	{0xa5cd, 0x13},
-	{0xa5d0, 0x17},
-	{0xa5d1, 0x1a},
-	{0xa5f4, 0x05},
-	{0xa5f5, 0x05},
-	{0xa5f8, 0x05},
-	{0xa5f9, 0x06},
-	{0xa5fc, 0x06},
-	{0xa5fd, 0x06},
-	{0xa600, 0x06},
-	{0xa601, 0x06},
-	{0xa608, 0x07},
-	{0xa609, 0x08},
-	{0xa60c, 0x08},
-	{0xa60d, 0x07},
-	{0xa63c, 0x00},
-	{0xa63d, 0x02},
-	{0xa640, 0x02},
-	{0xa641, 0x02},
-	{0xa644, 0x02},
-	{0xa645, 0x02},
-	{0xa648, 0x03},
-	{0xa649, 0x04},
-	{0xa64c, 0x0a},
-	{0xa64d, 0x09},
-	{0xa650, 0x08},
-	{0xa651, 0x09},
-	{0xa654, 0x09},
-	{0xa655, 0x0a},
-	{0xa658, 0x0a},
-	{0xa659, 0x0a},
-	{0xa65c, 0x0a},
-	{0xa65d, 0x09},
-	{0xa660, 0x09},
-	{0xa661, 0x09},
-	{0xa664, 0x09},
-	{0xa665, 0x08},
-	{0xa680, 0x01},
-	{0xa681, 0x02},
-	{0xa694, 0x1f},
-	{0xa695, 0x10},
-	{0xa698, 0x0e},
-	{0xa699, 0x0c},
-	{0xa69c, 0x0d},
-	{0xa69d, 0x0d},
-	{0xa6a0, 0x0f},
-	{0xa6a1, 0x11},
-	{0xa6a4, 0x00},
-	{0xa6a5, 0x00},
-	{0xa6a8, 0x00},
-	{0xa6a9, 0x00},
-	{0xa6ac, 0x00},
-	{0xa6ad, 0x00},
-	{0xa6b0, 0x00},
-	{0xa6b1, 0x04},
-	{0xa6b4, 0x04},
-	{0xa6b5, 0x04},
-	{0xa6b8, 0x04},
-	{0xa6b9, 0x04},
-	{0xa6bc, 0x05},
-	{0xa6bd, 0x05},
-	{0xa6c0, 0x1f},
-	{0xa6c1, 0x1f},
-	{0xa6c4, 0x1f},
-	{0xa6c5, 0x1f},
-	{0xa6c8, 0x1f},
-	{0xa6c9, 0x1f},
-	{0xa6cc, 0x1f},
-	{0xa6cd, 0x0b},
-	{0xa6d0, 0x0c},
-	{0xa6d1, 0x0d},
-	{0xa6d4, 0x0d},
-	{0xa6d5, 0x0d},
-	{0xa6d8, 0x11},
-	{0xa6d9, 0x14},
-	{0xa6fc, 0x02},
-	{0xa6fd, 0x03},
-	{0xa700, 0x03},
-	{0xa701, 0x03},
-	{0xa704, 0x03},
-	{0xa705, 0x04},
-	{0xa708, 0x05},
-	{0xa709, 0x02},
-	{0xa70c, 0x02},
-	{0xa70d, 0x02},
-	{0xa710, 0x03},
-	{0xa711, 0x04},
-	{0xa714, 0x04},
-	{0xa715, 0x04},
-	{0xa744, 0x00},
-	{0xa745, 0x03},
-	{0xa748, 0x04},
-	{0xa749, 0x04},
-	{0xa74c, 0x05},
-	{0xa74d, 0x06},
-	{0xa750, 0x07},
-	{0xa751, 0x07},
-	{0xa754, 0x05},
-	{0xa755, 0x05},
-	{0xa758, 0x05},
-	{0xa759, 0x05},
-	{0xa75c, 0x05},
-	{0xa75d, 0x06},
-	{0xa760, 0x07},
-	{0xa761, 0x07},
-	{0xa764, 0x06},
-	{0xa765, 0x05},
-	{0xa768, 0x05},
-	{0xa769, 0x05},
-	{0xa76c, 0x06},
-	{0xa76d, 0x07},
-	{0xa77c, 0x00},
-	{0xa77d, 0x05},
-	{0xa780, 0x05},
-	{0xa781, 0x05},
-	{0xa784, 0x05},
-	{0xa785, 0x04},
-	{0xa788, 0x05},
-	{0xa789, 0x06},
-	{0xa79c, 0x1f},
-	{0xa79d, 0x15},
-	{0xa7a0, 0x13},
-	{0xa7a1, 0x10},
-	{0xa7a4, 0x0f},
-	{0xa7a5, 0x0d},
-	{0xa7a8, 0x11},
-	{0xa7a9, 0x14},
-	{0xa7ac, 0x02},
-	{0xa7ad, 0x02},
-	{0xa7b0, 0x02},
-	{0xa7b1, 0x02},
-	{0xa7b4, 0x02},
-	{0xa7b5, 0x03},
-	{0xa7b8, 0x03},
-	{0xa7b9, 0x00},
-	{0xa7bc, 0x00},
-	{0xa7bd, 0x00},
-	{0xa7c0, 0x00},
-	{0xa7c1, 0x00},
-	{0xa7c4, 0x00},
-	{0xa7c5, 0x00},
-	{0xa7d4, 0x1f},
-	{0xa7d5, 0x0d},
-	{0xa7d8, 0x0f},
-	{0xa7d9, 0x10},
-	{0xa7dc, 0x10},
-	{0xa7dd, 0x10},
-	{0xa7e0, 0x13},
-	{0xa7e1, 0x16},
-	{0xa7f4, 0x00},
-	{0xa7f5, 0x03},
-	{0xa7f8, 0x04},
-	{0xa7f9, 0x04},
-	{0xa7fc, 0x04},
-	{0xa7fd, 0x03},
-	{0xa800, 0x03},
-	{0xa801, 0x03},
-	{0xa804, 0x03},
-	{0xa805, 0x03},
-	{0xa808, 0x03},
-	{0xa809, 0x03},
-	{0xa80c, 0x03},
-	{0xa80d, 0x04},
-	{0xa810, 0x04},
-	{0xa811, 0x0a},
-	{0xa814, 0x0a},
-	{0xa815, 0x0a},
-	{0xa818, 0x0f},
-	{0xa819, 0x14},
-	{0xa81c, 0x14},
-	{0xa81d, 0x14},
-	{0xa82c, 0x00},
-	{0xa82d, 0x04},
-	{0xa830, 0x02},
-	{0xa831, 0x00},
-	{0xa834, 0x00},
-	{0xa835, 0x00},
-	{0xa838, 0x00},
-	{0xa839, 0x00},
-	{0xa840, 0x1f},
-	{0xa841, 0x1f},
-	{0xa848, 0x1f},
-	{0xa849, 0x1f},
-	{0xa84c, 0x1f},
-	{0xa84d, 0x0c},
-	{0xa850, 0x0c},
-	{0xa851, 0x0c},
-	{0xa854, 0x0c},
-	{0xa855, 0x0c},
-	{0xa858, 0x0c},
-	{0xa859, 0x0c},
-	{0xa85c, 0x0c},
-	{0xa85d, 0x0c},
-	{0xa860, 0x0c},
-	{0xa861, 0x0c},
-	{0xa864, 0x0c},
-	{0xa865, 0x0c},
-	{0xa868, 0x0c},
-	{0xa869, 0x0c},
-	{0xa86c, 0x0c},
-	{0xa86d, 0x0c},
-	{0xa870, 0x0c},
-	{0xa871, 0x0c},
-	{0xa874, 0x0c},
-	{0xa875, 0x0c},
-	{0xa878, 0x1f},
-	{0xa879, 0x1f},
-	{0xa87c, 0x1f},
-	{0xa87d, 0x1f},
-	{0xa880, 0x1f},
-	{0xa881, 0x1f},
-	{0xa884, 0x1f},
-	{0xa885, 0x0c},
-	{0xa888, 0x0c},
-	{0xa889, 0x0c},
-	{0xa88c, 0x0c},
-	{0xa88d, 0x0c},
-	{0xa890, 0x0c},
-	{0xa891, 0x0c},
-	{0xa898, 0x1f},
-	{0xa899, 0x1f},
-	{0xa8a0, 0x1f},
-	{0xa8a1, 0x1f},
-	{0xa8a4, 0x1f},
-	{0xa8a5, 0x0c},
-	{0xa8a8, 0x0c},
-	{0xa8a9, 0x0c},
-	{0xa8ac, 0x0c},
-	{0xa8ad, 0x0c},
-	{0xa8b0, 0x0c},
-	{0xa8b1, 0x0c},
-	{0xa8b4, 0x0c},
-	{0xa8b5, 0x0c},
-	{0xa8b8, 0x0c},
-	{0xa8b9, 0x0c},
-	{0xa8bc, 0x0c},
-	{0xa8bd, 0x0c},
-	{0xa8c0, 0x0c},
-	{0xa8c1, 0x0c},
-	{0xa8c4, 0x0c},
-	{0xa8c5, 0x0c},
-	{0xa8c8, 0x0c},
-	{0xa8c9, 0x0c},
-	{0xa8cc, 0x0c},
-	{0xa8cd, 0x0c},
-	{0xa8d0, 0x1f},
-	{0xa8d1, 0x1f},
-	{0xa8d4, 0x1f},
-	{0xa8d5, 0x1f},
-	{0xa8d8, 0x1f},
-	{0xa8d9, 0x1f},
-	{0xa8dc, 0x1f},
-	{0xa8dd, 0x0c},
-	{0xa8e0, 0x0c},
-	{0xa8e1, 0x0c},
-	{0xa8e4, 0x0c},
-	{0xa8e5, 0x0c},
-	{0xa8e8, 0x0c},
-	{0xa8e9, 0x0c},
-	{0xa8f0, 0x1f},
-	{0xa8f1, 0x1f},
-	{0xa8f8, 0x1f},
-	{0xa8f9, 0x1f},
-	{0xa8fc, 0x1f},
-	{0xa8fd, 0x0c},
-	{0xa900, 0x0c},
-	{0xa901, 0x0c},
-	{0xa904, 0x0c},
-	{0xa905, 0x0c},
-	{0xa908, 0x0c},
-	{0xa909, 0x0c},
-	{0xa90c, 0x0c},
-	{0xa90d, 0x0c},
-	{0xa910, 0x0c},
-	{0xa911, 0x0c},
-	{0xa914, 0x0c},
-	{0xa915, 0x0c},
-	{0xa918, 0x0c},
-	{0xa919, 0x0c},
-	{0xa91c, 0x0c},
-	{0xa91d, 0x0c},
-	{0xa920, 0x0c},
-	{0xa921, 0x0c},
-	{0xa924, 0x0c},
-	{0xa925, 0x0c},
-	{0xa928, 0x1f},
-	{0xa929, 0x1f},
-	{0xa92c, 0x1f},
-	{0xa92d, 0x1f},
-	{0xa930, 0x1f},
-	{0xa931, 0x1f},
-	{0xa934, 0x1f},
-	{0xa935, 0x0c},
-	{0xa938, 0x0c},
-	{0xa939, 0x0c},
-	{0xa93c, 0x0c},
-	{0xa93d, 0x0c},
-	{0xa940, 0x0c},
-	{0xa941, 0x0c},
-	{0xa96c, 0x0d},
-	{0xa96d, 0x16},
-	{0xa970, 0x19},
-	{0xa971, 0x0e},
-	{0xa974, 0x16},
-	{0xa975, 0x1a},
-	{0xa978, 0x0d},
-	{0xa979, 0x15},
-	{0xa97c, 0x19},
-	{0xa97d, 0x0d},
-	{0xa980, 0x15},
-	{0xa981, 0x1a},
-	{0xa984, 0x0d},
-	{0xa985, 0x15},
-	{0xa988, 0x1a},
-	{0xa989, 0x0d},
-	{0xa98c, 0x15},
-	{0xa98d, 0x1a},
-	{0xa990, 0x0b},
-	{0xa991, 0x11},
-	{0xa994, 0x02},
-	{0xa995, 0x0e},
-	{0xa998, 0x16},
-	{0xa999, 0x02},
-	{0xa99c, 0x0c},
-	{0xa99d, 0x13},
-	{0xa9a0, 0x02},
-	{0xa9a1, 0x0c},
-	{0xa9a4, 0x12},
-	{0xa9a5, 0x02},
-	{0xa9a8, 0x0c},
-	{0xa9a9, 0x12},
-	{0xa9ac, 0x02},
-	{0xa9ad, 0x0c},
-	{0xa9b0, 0x12},
-	{0xa9b1, 0x02},
-	{0xa9b4, 0x10},
-	{0xa9b5, 0x1e},
-	{0xa9b8, 0x0f},
-	{0xa9b9, 0x13},
-	{0xa9bc, 0x20},
-	{0xa9bd, 0x10},
-	{0xa9c0, 0x11},
-	{0xa9c1, 0x1e},
-	{0xa9c4, 0x10},
-	{0xa9c5, 0x11},
-	{0xa9c8, 0x1e},
-	{0xa9c9, 0x10},
-	{0xa9cc, 0x11},
-	{0xa9cd, 0x20},
-	{0xa9d0, 0x10},
-	{0xa9d1, 0x13},
-	{0xa9d4, 0x24},
-	{0xa9d5, 0x10},
-	{0xa9f0, 0x02},
-	{0xa9f1, 0x01},
-	{0xa9f8, 0x19},
-	{0xa9f9, 0x0b},
-	{0xa9fc, 0x0a},
-	{0xa9fd, 0x07},
-	{0xaa00, 0x0c},
-	{0xaa01, 0x0e},
-	{0xaa08, 0x0c},
-	{0xaa09, 0x06},
-	{0xaa0c, 0x0c},
-	{0xaa0d, 0x0a},
-	{0xaa24, 0x10},
-	{0xaa25, 0x12},
-	{0xaa28, 0x0b},
-	{0xaa29, 0x07},
-	{0xaa2c, 0x10},
-	{0xaa2d, 0x14},
-	{0xaa34, 0x0e},
-	{0xaa35, 0x0e},
-	{0xaa38, 0x07},
-	{0xaa39, 0x07},
-	{0xaa3c, 0x0e},
-	{0xaa3d, 0x0c},
-	{0xaa48, 0x09},
-	{0xaa49, 0x0c},
-	{0xaa4c, 0x0c},
-	{0xaa4d, 0x07},
-	{0xaa54, 0x08},
-	{0xaa55, 0x06},
-	{0xaa58, 0x04},
-	{0xaa59, 0x05},
-	{0xaa5c, 0x06},
-	{0xaa5d, 0x06},
-	{0xaa68, 0x05},
-	{0xaa69, 0x05},
-	{0xaa6c, 0x04},
-	{0xaa6d, 0x05},
-	{0xaa74, 0x06},
-	{0xaa75, 0x04},
-	{0xaa78, 0x05},
-	{0xaa79, 0x05},
-	{0xaa7c, 0x04},
-	{0xaa7d, 0x06},
-	{0xac18, 0x14},
-	{0xac19, 0x00},
-	{0xac1c, 0x14},
-	{0xac1d, 0x00},
-	{0xac20, 0x14},
-	{0xac21, 0x00},
-	{0xac24, 0x14},
-	{0xac25, 0x00},
-	{0xac28, 0x14},
-	{0xac29, 0x00},
-	{0xac2c, 0x14},
-	{0xac2d, 0x00},
-	{0xac34, 0x16},
-	{0xac35, 0x00},
-	{0xac38, 0x16},
-	{0xac39, 0x00},
-	{0xac3c, 0x16},
-	{0xac3d, 0x00},
-	{0xac40, 0x16},
-	{0xac41, 0x00},
-	{0xac44, 0x16},
-	{0xac45, 0x00},
-	{0xac48, 0x16},
-	{0xac49, 0x00},
-	{0xac50, 0x1b},
-	{0xac51, 0x00},
-	{0xac54, 0x1b},
-	{0xac55, 0x00},
-	{0xac58, 0x1b},
-	{0xac59, 0x00},
-	{0xac5c, 0x1b},
-	{0xac5d, 0x00},
-	{0xac60, 0x1b},
-	{0xac61, 0x00},
-	{0xac64, 0x1b},
-	{0xac65, 0x00},
-	{0xac74, 0x09},
-	{0xac75, 0x0c},
-	{0xac78, 0x0f},
-	{0xac79, 0x11},
-	{0xac7c, 0x12},
-	{0xac7d, 0x14},
-	{0xac80, 0x09},
-	{0xac81, 0x0c},
-	{0xac84, 0x0f},
-	{0xac85, 0x11},
-	{0xac88, 0x12},
-	{0xac89, 0x14},
-	{0xac8c, 0x09},
-	{0xac8d, 0x0c},
-	{0xac90, 0x0f},
-	{0xac91, 0x11},
-	{0xac94, 0x12},
-	{0xac95, 0x14},
-	{0xac98, 0x09},
-	{0xac99, 0x0c},
-	{0xac9c, 0x0f},
-	{0xac9d, 0x11},
-	{0xaca0, 0x12},
-	{0xaca1, 0x14},
-	{0xaca4, 0x09},
-	{0xaca5, 0x0c},
-	{0xaca8, 0x0f},
-	{0xaca9, 0x11},
-	{0xacac, 0x12},
-	{0xacad, 0x14},
-	{0xacb0, 0x07},
-	{0xacb1, 0x09},
-	{0xacb4, 0x0c},
-	{0xacb5, 0x0d},
-	{0xacb8, 0x0d},
-	{0xacb9, 0x0e},
-	{0xacbc, 0x05},
-	{0xacbd, 0x07},
-	{0xacc0, 0x0a},
-	{0xacc1, 0x0b},
-	{0xacc4, 0x0b},
-	{0xacc5, 0x0c},
-	{0xacc8, 0x03},
-	{0xacc9, 0x04},
-	{0xaccc, 0x07},
-	{0xaccd, 0x08},
-	{0xacd0, 0x09},
-	{0xacd1, 0x09}
-};
-
-static struct vx6953_i2c_reg_conf patch_tbl_cut3[] = {
-	{0xF800, 0x90},
-	{0xF801, 0x30},
-	{0xF802, 0x31},
-	{0xF803, 0xe0},
-	{0xF804, 0xf5},
-	{0xF805, 0x7d},
-	{0xF806, 0xb4},
-	{0xF807, 0x01},
-	{0xF808, 0x06},
-	{0xF809, 0x75},
-	{0xF80A, 0x7d},
-	{0xF80B, 0x03},
-	{0xF80C, 0x74},
-	{0xF80D, 0x03},
-	{0xF80E, 0xf0},
-	{0xF80F, 0x90},
-	{0xF810, 0x30},
-	{0xF811, 0x04},
-	{0xF812, 0x74},
-	{0xF813, 0x33},
-	{0xF814, 0xf0},
-	{0xF815, 0x90},
-	{0xF816, 0x30},
-	{0xF817, 0x06},
-	{0xF818, 0xe4},
-	{0xF819, 0xf0},
-	{0xF81A, 0xa3},
-	{0xF81B, 0x74},
-	{0xF81C, 0x09},
-	{0xF81D, 0xf0},
-	{0xF81E, 0x90},
-	{0xF81F, 0x30},
-	{0xF820, 0x10},
-	{0xF821, 0xe4},
-	{0xF822, 0xf0},
-	{0xF823, 0xa3},
-	{0xF824, 0xf0},
-	{0xF825, 0x90},
-	{0xF826, 0x30},
-	{0xF827, 0x16},
-	{0xF828, 0x74},
-	{0xF829, 0x1e},
-	{0xF82A, 0xf0},
-	{0xF82B, 0x90},
-	{0xF82C, 0x30},
-	{0xF82D, 0x1a},
-	{0xF82E, 0x74},
-	{0xF82F, 0x6a},
-	{0xF830, 0xf0},
-	{0xF831, 0xa3},
-	{0xF832, 0x74},
-	{0xF833, 0x29},
-	{0xF834, 0xf0},
-	{0xF835, 0x90},
-	{0xF836, 0x30},
-	{0xF837, 0x30},
-	{0xF838, 0x74},
-	{0xF839, 0x08},
-	{0xF83A, 0xf0},
-	{0xF83B, 0x90},
-	{0xF83C, 0x30},
-	{0xF83D, 0x36},
-	{0xF83E, 0x74},
-	{0xF83F, 0x2c},
-	{0xF840, 0xf0},
-	{0xF841, 0x90},
-	{0xF842, 0x30},
-	{0xF843, 0x41},
-	{0xF844, 0xe4},
-	{0xF845, 0xf0},
-	{0xF846, 0xa3},
-	{0xF847, 0x74},
-	{0xF848, 0x24},
-	{0xF849, 0xf0},
-	{0xF84A, 0x90},
-	{0xF84B, 0x30},
-	{0xF84C, 0x45},
-	{0xF84D, 0x74},
-	{0xF84E, 0x81},
-	{0xF84F, 0xf0},
-	{0xF850, 0x90},
-	{0xF851, 0x30},
-	{0xF852, 0x98},
-	{0xF853, 0x74},
-	{0xF854, 0x01},
-	{0xF855, 0xf0},
-	{0xF856, 0x90},
-	{0xF857, 0x30},
-	{0xF858, 0x9d},
-	{0xF859, 0x74},
-	{0xF85A, 0x05},
-	{0xF85B, 0xf0},
-	{0xF85C, 0xe5},
-	{0xF85D, 0x7d},
-	{0xF85E, 0x70},
-	{0xF85F, 0x10},
-	{0xF860, 0x90},
-	{0xF861, 0x30},
-	{0xF862, 0x05},
-	{0xF863, 0x04},
-	{0xF864, 0xf0},
-	{0xF865, 0x90},
-	{0xF866, 0x30},
-	{0xF867, 0x30},
-	{0xF868, 0xe4},
-	{0xF869, 0xf0},
-	{0xF86A, 0x90},
-	{0xF86B, 0x30},
-	{0xF86C, 0x35},
-	{0xF86D, 0x04},
-	{0xF86E, 0xf0},
-	{0xF86F, 0x22},
-	{0xF870, 0xe5},
-	{0xF871, 0x7d},
-	{0xF872, 0x64},
-	{0xF873, 0x02},
-	{0xF874, 0x70},
-	{0xF875, 0x2d},
-	{0xF876, 0x90},
-	{0xF877, 0x30},
-	{0xF878, 0x04},
-	{0xF879, 0x74},
-	{0xF87A, 0x34},
-	{0xF87B, 0xf0},
-	{0xF87C, 0xa3},
-	{0xF87D, 0x74},
-	{0xF87E, 0x07},
-	{0xF87F, 0xf0},
-	{0xF880, 0x90},
-	{0xF881, 0x30},
-	{0xF882, 0x10},
-	{0xF883, 0x74},
-	{0xF884, 0x10},
-	{0xF885, 0xf0},
-	{0xF886, 0x90},
-	{0xF887, 0x30},
-	{0xF888, 0x16},
-	{0xF889, 0x74},
-	{0xF88A, 0x1f},
-	{0xF88B, 0xf0},
-	{0xF88C, 0x90},
-	{0xF88D, 0x30},
-	{0xF88E, 0x1a},
-	{0xF88F, 0x74},
-	{0xF890, 0x62},
-	{0xF891, 0xf0},
-	{0xF892, 0x90},
-	{0xF893, 0x30},
-	{0xF894, 0x35},
-	{0xF895, 0x74},
-	{0xF896, 0x04},
-	{0xF897, 0xf0},
-	{0xF898, 0x90},
-	{0xF899, 0x30},
-	{0xF89A, 0x41},
-	{0xF89B, 0x74},
-	{0xF89C, 0x60},
-	{0xF89D, 0xf0},
-	{0xF89E, 0xa3},
-	{0xF89F, 0x74},
-	{0xF8A0, 0x64},
-	{0xF8A1, 0xf0},
-	{0xF8A2, 0x22},
-	{0xF8A3, 0xe5},
-	{0xF8A4, 0x7d},
-	{0xF8A5, 0xb4},
-	{0xF8A6, 0x03},
-	{0xF8A7, 0x12},
-	{0xF8A8, 0x90},
-	{0xF8A9, 0x30},
-	{0xF8AA, 0x05},
-	{0xF8AB, 0x74},
-	{0xF8AC, 0x03},
-	{0xF8AD, 0xf0},
-	{0xF8AE, 0x90},
-	{0xF8AF, 0x30},
-	{0xF8B0, 0x11},
-	{0xF8B1, 0x74},
-	{0xF8B2, 0x01},
-	{0xF8B3, 0xf0},
-	{0xF8B4, 0x90},
-	{0xF8B5, 0x30},
-	{0xF8B6, 0x35},
-	{0xF8B7, 0x74},
-	{0xF8B8, 0x03},
-	{0xF8B9, 0xf0},
-	{0xF8BA, 0x22},
-	{0xF8BB, 0xc3},
-	{0xF8BC, 0x90},
-	{0xF8BD, 0x0b},
-	{0xF8BE, 0x89},
-	{0xF8BF, 0xe0},
-	{0xF8C0, 0x94},
-	{0xF8C1, 0x1e},
-	{0xF8C2, 0x90},
-	{0xF8C3, 0x0b},
-	{0xF8C4, 0x88},
-	{0xF8C5, 0xe0},
-	{0xF8C6, 0x94},
-	{0xF8C7, 0x00},
-	{0xF8C8, 0x50},
-	{0xF8C9, 0x06},
-	{0xF8CA, 0x7e},
-	{0xF8CB, 0x00},
-	{0xF8CC, 0x7f},
-	{0xF8CD, 0x01},
-	{0xF8CE, 0x80},
-	{0xF8CF, 0x3d},
-	{0xF8D0, 0xc3},
-	{0xF8D1, 0x90},
-	{0xF8D2, 0x0b},
-	{0xF8D3, 0x89},
-	{0xF8D4, 0xe0},
-	{0xF8D5, 0x94},
-	{0xF8D6, 0x3c},
-	{0xF8D7, 0x90},
-	{0xF8D8, 0x0b},
-	{0xF8D9, 0x88},
-	{0xF8DA, 0xe0},
-	{0xF8DB, 0x94},
-	{0xF8DC, 0x00},
-	{0xF8DD, 0x50},
-	{0xF8DE, 0x06},
-	{0xF8DF, 0x7e},
-	{0xF8E0, 0x00},
-	{0xF8E1, 0x7f},
-	{0xF8E2, 0x02},
-	{0xF8E3, 0x80},
-	{0xF8E4, 0x28},
-	{0xF8E5, 0xc3},
-	{0xF8E6, 0x90},
-	{0xF8E7, 0x0b},
-	{0xF8E8, 0x89},
-	{0xF8E9, 0xe0},
-	{0xF8EA, 0x94},
-	{0xF8EB, 0xfa},
-	{0xF8EC, 0x90},
-	{0xF8ED, 0x0b},
-	{0xF8EE, 0x88},
-	{0xF8EF, 0xe0},
-	{0xF8F0, 0x94},
-	{0xF8F1, 0x00},
-	{0xF8F2, 0x50},
-	{0xF8F3, 0x06},
-	{0xF8F4, 0x7e},
-	{0xF8F5, 0x00},
-	{0xF8F6, 0x7f},
-	{0xF8F7, 0x03},
-	{0xF8F8, 0x80},
-	{0xF8F9, 0x13},
-	{0xF8FA, 0xc3},
-	{0xF8FB, 0x90},
-	{0xF8FC, 0x0b},
-	{0xF8FD, 0x88},
-	{0xF8FE, 0xe0},
-	{0xF8FF, 0x94},
-	{0xF900, 0x80},
-	{0xF901, 0x50},
-	{0xF902, 0x06},
-	{0xF903, 0x7e},
-	{0xF904, 0x00},
-	{0xF905, 0x7f},
-	{0xF906, 0x04},
-	{0xF907, 0x80},
-	{0xF908, 0x04},
-	{0xF909, 0xae},
-	{0xF90A, 0x7e},
-	{0xF90B, 0xaf},
-	{0xF90C, 0x7f},
-	{0xF90D, 0x90},
-	{0xF90E, 0xa0},
-	{0xF90F, 0xf8},
-	{0xF910, 0xee},
-	{0xF911, 0xf0},
-	{0xF912, 0xa3},
-	{0xF913, 0xef},
-	{0xF914, 0xf0},
-	{0xF915, 0x22},
-	{0xF916, 0x90},
-	{0xF917, 0x33},
-	{0xF918, 0x82},
-	{0xF919, 0xe0},
-	{0xF91A, 0xff},
-	{0xF91B, 0x64},
-	{0xF91C, 0x01},
-	{0xF91D, 0x70},
-	{0xF91E, 0x30},
-	{0xF91F, 0xe5},
-	{0xF920, 0x7f},
-	{0xF921, 0x64},
-	{0xF922, 0x02},
-	{0xF923, 0x45},
-	{0xF924, 0x7e},
-	{0xF925, 0x70},
-	{0xF926, 0x04},
-	{0xF927, 0x7d},
-	{0xF928, 0x1e},
-	{0xF929, 0x80},
-	{0xF92A, 0x1d},
-	{0xF92B, 0xe5},
-	{0xF92C, 0x7f},
-	{0xF92D, 0x64},
-	{0xF92E, 0x03},
-	{0xF92F, 0x45},
-	{0xF930, 0x7e},
-	{0xF931, 0x70},
-	{0xF932, 0x04},
-	{0xF933, 0x7d},
-	{0xF934, 0x3c},
-	{0xF935, 0x80},
-	{0xF936, 0x11},
-	{0xF937, 0xe5},
-	{0xF938, 0x7f},
-	{0xF939, 0x64},
-	{0xF93A, 0x04},
-	{0xF93B, 0x45},
-	{0xF93C, 0x7e},
-	{0xF93D, 0x70},
-	{0xF93E, 0x04},
-	{0xF93F, 0x7d},
-	{0xF940, 0xfa},
-	{0xF941, 0x80},
-	{0xF942, 0x05},
-	{0xF943, 0x90},
-	{0xF944, 0x33},
-	{0xF945, 0x81},
-	{0xF946, 0xe0},
-	{0xF947, 0xfd},
-	{0xF948, 0xae},
-	{0xF949, 0x05},
-	{0xF94A, 0x90},
-	{0xF94B, 0x33},
-	{0xF94C, 0x81},
-	{0xF94D, 0xed},
-	{0xF94E, 0xf0},
-	{0xF94F, 0xef},
-	{0xF950, 0xb4},
-	{0xF951, 0x01},
-	{0xF952, 0x10},
-	{0xF953, 0x90},
-	{0xF954, 0x01},
-	{0xF955, 0x00},
-	{0xF956, 0xe0},
-	{0xF957, 0x60},
-	{0xF958, 0x0a},
-	{0xF959, 0x90},
-	{0xF95A, 0xa1},
-	{0xF95B, 0x10},
-	{0xF95C, 0xe0},
-	{0xF95D, 0xf5},
-	{0xF95E, 0x7e},
-	{0xF95F, 0xa3},
-	{0xF960, 0xe0},
-	{0xF961, 0xf5},
-	{0xF962, 0x7f},
-	{0xF963, 0x22},
-	{0xF964, 0x12},
-	{0xF965, 0x2f},
-	{0xF966, 0x4d},
-	{0xF967, 0x90},
-	{0xF968, 0x35},
-	{0xF969, 0x38},
-	{0xF96A, 0xe0},
-	{0xF96B, 0x70},
-	{0xF96C, 0x05},
-	{0xF96D, 0x12},
-	{0xF96E, 0x00},
-	{0xF96F, 0x0e},
-	{0xF970, 0x80},
-	{0xF971, 0x03},
-	{0xF972, 0x12},
-	{0xF973, 0x07},
-	{0xF974, 0xc9},
-	{0xF975, 0x90},
-	{0xF976, 0x40},
-	{0xF977, 0x06},
-	{0xF978, 0xe0},
-	{0xF979, 0xf4},
-	{0xF97A, 0x54},
-	{0xF97B, 0x02},
-	{0xF97C, 0xff},
-	{0xF97D, 0xe0},
-	{0xF97E, 0x54},
-	{0xF97F, 0x01},
-	{0xF980, 0x4f},
-	{0xF981, 0x90},
-	{0xF982, 0x31},
-	{0xF983, 0x32},
-	{0xF984, 0xf0},
-	{0xF985, 0x90},
-	{0xF986, 0xfa},
-	{0xF987, 0x9d},
-	{0xF988, 0xe0},
-	{0xF989, 0x70},
-	{0xF98A, 0x03},
-	{0xF98B, 0x12},
-	{0xF98C, 0x27},
-	{0xF98D, 0x27},
-	{0xF98E, 0x02},
-	{0xF98F, 0x05},
-	{0xF990, 0xac},
-	{0xF991, 0x22},
-	{0xF992, 0x78},
-	{0xF993, 0x07},
-	{0xF994, 0xe6},
-	{0xF995, 0xf5},
-	{0xF996, 0x7c},
-	{0xF997, 0xe5},
-	{0xF998, 0x7c},
-	{0xF999, 0x60},
-	{0xF99A, 0x1d},
-	{0xF99B, 0x90},
-	{0xF99C, 0x43},
-	{0xF99D, 0x83},
-	{0xF99E, 0xe0},
-	{0xF99F, 0xb4},
-	{0xF9A0, 0x01},
-	{0xF9A1, 0x16},
-	{0xF9A2, 0x90},
-	{0xF9A3, 0x43},
-	{0xF9A4, 0x87},
-	{0xF9A5, 0xe0},
-	{0xF9A6, 0xb4},
-	{0xF9A7, 0x01},
-	{0xF9A8, 0x0f},
-	{0xF9A9, 0x15},
-	{0xF9AA, 0x7c},
-	{0xF9AB, 0x90},
-	{0xF9AC, 0x30},
-	{0xF9AD, 0xa1},
-	{0xF9AE, 0xe5},
-	{0xF9AF, 0x7c},
-	{0xF9B0, 0xf0},
-	{0xF9B1, 0x90},
-	{0xF9B2, 0x30},
-	{0xF9B3, 0xa0},
-	{0xF9B4, 0x74},
-	{0xF9B5, 0x01},
-	{0xF9B6, 0xf0},
-	{0xF9B7, 0x22},
-	{0xF9B8, 0xe4},
-	{0xF9B9, 0x90},
-	{0xF9BA, 0x30},
-	{0xF9BB, 0xa0},
-	{0xF9BC, 0xf0},
-	{0xF9BD, 0x22},
-	{0xF9BE, 0xf0},
-	{0xF9BF, 0xe5},
-	{0xF9C0, 0x3a},
-	{0xF9C1, 0xb4},
-	{0xF9C2, 0x06},
-	{0xF9C3, 0x06},
-	{0xF9C4, 0x63},
-	{0xF9C5, 0x3e},
-	{0xF9C6, 0x02},
-	{0xF9C7, 0x12},
-	{0xF9C8, 0x03},
-	{0xF9C9, 0xea},
-	{0xF9CA, 0x02},
-	{0xF9CB, 0x17},
-	{0xF9CC, 0x4a},
-	{0xF9CD, 0x22},
-	{0x35C9, 0xBB},
-	{0x35CA, 0x01},
-	{0x35CB, 0x16},
-	{0x35CC, 0x01},
-	{0x35CD, 0x64},
-	{0x35CE, 0x01},
-	{0x35CF, 0x92},
-	{0x35D0, 0x01},
-	{0x35D1, 0xBE},
-	{0x35D3, 0xF6},
-	{0x35D5, 0x07},
-	{0x35D7, 0xA3},
-	{0x35DB, 0x02},
-	{0x35DD, 0x06},
-	{0x35DF, 0x1B},
-	{0x35E6, 0x28},
-	{0x35E7, 0x76},
-	{0x35E8, 0x2D},
-	{0x35E9, 0x07},
-	{0x35EA, 0x04},
-	{0x35EB, 0x43},
-	{0x35EC, 0x05},
-	{0x35ED, 0xA9},
-	{0x35EE, 0x2A},
-	{0x35EF, 0x15},
-	{0x35F0, 0x17},
-	{0x35F1, 0x41},
-	{0x35F2, 0x24},
-	{0x35F3, 0x88},
-	{0x35F4, 0x01},
-	{0x35F5, 0x54},
-	{0x35F6, 0x01},
-	{0x35F7, 0x55},
-	{0x35F8, 0x2E},
-	{0x35F9, 0xF2},
-	{0x35FA, 0x06},
-	{0x35FB, 0x02},
-	{0x35FC, 0x06},
-	{0x35FD, 0x03},
-	{0x35FE, 0x06},
-	{0x35FF, 0x04},
-	{0x35C2, 0x1F},
-	{0x35C3, 0xFF},
-	{0x35C4, 0x1F},
-	{0x35C5, 0xC0},
-	{0x35C0, 0x01},
-};
-
-struct vx6953_format {
-	enum v4l2_mbus_pixelcode code;
-	enum v4l2_colorspace colorspace;
-	u16 fmt;
-	u16 order;
-};
-
-static const struct vx6953_format vx6953_cfmts[] = {
-	{
-	.code   = V4L2_MBUS_FMT_YUYV8_2X8,
-	.colorspace = V4L2_COLORSPACE_JPEG,
-	.fmt    = 1,
-	.order    = 0,
-	}
-	/* more can be supported, to be added later */
-};
-
-
-/*=============================================================*/
-
-static int vx6953_i2c_rxdata(unsigned short saddr,
-	unsigned char *rxdata, int length)
-{
-	struct i2c_msg msgs[] = {
-		{
-			.addr  = saddr,
-			.flags = 0,
-			.len   = 2,
-			.buf   = rxdata,
-		},
-		{
-			.addr  = saddr,
-			.flags = I2C_M_RD,
-			.len   = 2,
-			.buf   = rxdata,
-		},
-	};
-	if (i2c_transfer(vx6953_client->adapter, msgs, 2) < 0) {
-		CDBG("vx6953_i2c_rxdata failed!\n");
-		return -EIO;
-	}
-	return 0;
-}
-static int32_t vx6953_i2c_txdata(unsigned short saddr,
-				unsigned char *txdata, int length)
-{
-	struct i2c_msg msg[] = {
-		{
-			.addr = saddr,
-			.flags = 0,
-			.len = length,
-			.buf = txdata,
-		 },
-	};
-	if (i2c_transfer(vx6953_client->adapter, msg, 1) < 0) {
-		CDBG("vx6953_i2c_txdata faild 0x%x\n", vx6953_client->addr);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-
-static int32_t vx6953_i2c_read(unsigned short raddr,
-	unsigned short *rdata, int rlen)
-{
-	int32_t rc = 0;
-	unsigned char buf[2];
-	if (!rdata)
-		return -EIO;
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (raddr & 0xFF00) >> 8;
-	buf[1] = (raddr & 0x00FF);
-	rc = vx6953_i2c_rxdata(vx6953_client->addr>>1, buf, rlen);
-	if (rc < 0) {
-		CDBG("vx6953_i2c_read 0x%x failed!\n", raddr);
-		return rc;
-	}
-	*rdata = (rlen == 2 ? buf[0] << 8 | buf[1] : buf[0]);
-	return rc;
-}
-static int32_t vx6953_i2c_write_b_sensor(unsigned short waddr, uint8_t bdata)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[3];
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (waddr & 0xFF00) >> 8;
-	buf[1] = (waddr & 0x00FF);
-	buf[2] = bdata;
-	CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
-	rc = vx6953_i2c_txdata(vx6953_client->addr>>1, buf, 3);
-	if (rc < 0) {
-		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
-			waddr, bdata);
-	}
-	return rc;
-}
-static int32_t vx6953_i2c_write_seq_sensor(unsigned short waddr,
-	uint8_t *bdata, uint16_t len)
-{
-	int32_t rc = -EFAULT;
-	unsigned char buf[len+2];
-	int i;
-	memset(buf, 0, sizeof(buf));
-	buf[0] = (waddr & 0xFF00) >> 8;
-	buf[1] = (waddr & 0x00FF);
-	for (i = 2; i < len+2; i++)
-		buf[i] = *bdata++;
-	rc = vx6953_i2c_txdata(vx6953_client->addr>>1, buf, len+2);
-	if (rc < 0) {
-		CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
-			 waddr, bdata[0]);
-	}
-	return rc;
-}
-
-static int32_t vx6953_i2c_write_w_table(struct vx6953_i2c_reg_conf const
-					 *reg_conf_tbl, int num)
-{
-	int i;
-	int32_t rc = -EIO;
-	for (i = 0; i < num; i++) {
-		rc = vx6953_i2c_write_b_sensor(reg_conf_tbl->waddr,
-			reg_conf_tbl->wdata);
-		if (rc < 0)
-			break;
-		reg_conf_tbl++;
-	}
-	return rc;
-}
-
-static void vx6953_get_pict_fps(uint16_t fps, uint16_t *pfps)
-{
-	/* input fps is preview fps in Q8 format */
-	uint16_t preview_frame_length_lines, snapshot_frame_length_lines;
-	uint16_t preview_line_length_pck, snapshot_line_length_pck;
-	uint32_t divider, d1, d2;
-	/* Total frame_length_lines and line_length_pck for preview */
-	preview_frame_length_lines = VX6953_QTR_SIZE_HEIGHT +
-		VX6953_VER_QTR_BLK_LINES;
-	preview_line_length_pck = VX6953_QTR_SIZE_WIDTH +
-		VX6953_HRZ_QTR_BLK_PIXELS;
-	/* Total frame_length_lines and line_length_pck for snapshot */
-	snapshot_frame_length_lines = VX6953_FULL_SIZE_HEIGHT +
-		VX6953_VER_FULL_BLK_LINES;
-	snapshot_line_length_pck = VX6953_FULL_SIZE_WIDTH +
-		VX6953_HRZ_FULL_BLK_PIXELS;
-	d1 = preview_frame_length_lines * 0x00000400/
-		snapshot_frame_length_lines;
-	d2 = preview_line_length_pck * 0x00000400/
-		snapshot_line_length_pck;
-	divider = d1 * d2 / 0x400;
-	/*Verify PCLK settings and frame sizes.*/
-	*pfps = (uint16_t) (fps * divider / 0x400);
-	/* 2 is the ratio of no.of snapshot channels
-	to number of preview channels */
-
-}
-
-static uint16_t vx6953_get_prev_lines_pf(void)
-{
-	if (vx6953_ctrl->prev_res == QTR_SIZE)
-		return VX6953_QTR_SIZE_HEIGHT + VX6953_VER_QTR_BLK_LINES;
-	else
-		return VX6953_FULL_SIZE_HEIGHT + VX6953_VER_FULL_BLK_LINES;
-
-}
-
-static uint16_t vx6953_get_prev_pixels_pl(void)
-{
-	if (vx6953_ctrl->prev_res == QTR_SIZE)
-		return VX6953_QTR_SIZE_WIDTH + VX6953_HRZ_QTR_BLK_PIXELS;
-	else
-		return VX6953_FULL_SIZE_WIDTH + VX6953_HRZ_FULL_BLK_PIXELS;
-}
-
-static uint16_t vx6953_get_pict_lines_pf(void)
-{
-		if (vx6953_ctrl->pict_res == QTR_SIZE)
-			return VX6953_QTR_SIZE_HEIGHT +
-				VX6953_VER_QTR_BLK_LINES;
-		else
-			return VX6953_FULL_SIZE_HEIGHT +
-				VX6953_VER_FULL_BLK_LINES;
-}
-
-static uint16_t vx6953_get_pict_pixels_pl(void)
-{
-	if (vx6953_ctrl->pict_res == QTR_SIZE)
-		return VX6953_QTR_SIZE_WIDTH +
-			VX6953_HRZ_QTR_BLK_PIXELS;
-	else
-		return VX6953_FULL_SIZE_WIDTH +
-			VX6953_HRZ_FULL_BLK_PIXELS;
-}
-
-static uint32_t vx6953_get_pict_max_exp_lc(void)
-{
-	if (vx6953_ctrl->pict_res == QTR_SIZE)
-		return (VX6953_QTR_SIZE_HEIGHT +
-			VX6953_VER_QTR_BLK_LINES)*24;
-	else
-		return (VX6953_FULL_SIZE_HEIGHT +
-			VX6953_VER_FULL_BLK_LINES)*24;
-}
-
-static int32_t vx6953_set_fps(struct fps_cfg	*fps)
-{
-	uint16_t total_lines_per_frame;
-	int32_t rc = 0;
-	total_lines_per_frame = (uint16_t)((VX6953_QTR_SIZE_HEIGHT +
-		VX6953_VER_QTR_BLK_LINES) * vx6953_ctrl->fps_divider/0x400);
-	if (vx6953_i2c_write_b_sensor(REG_FRAME_LENGTH_LINES_HI,
-		((total_lines_per_frame & 0xFF00) >> 8)) < 0)
-		return rc;
-	if (vx6953_i2c_write_b_sensor(REG_FRAME_LENGTH_LINES_LO,
-		(total_lines_per_frame & 0x00FF)) < 0)
-		return rc;
-	return rc;
-}
-
-static int32_t vx6953_write_exp_gain(uint16_t gain, uint32_t line)
-{
-	uint16_t line_length_pck, frame_length_lines;
-	uint8_t gain_hi, gain_lo;
-	uint8_t intg_time_hi, intg_time_lo;
-	uint8_t line_length_pck_hi = 0, line_length_pck_lo = 0;
-	uint16_t line_length_ratio = 1 * Q8;
-	int32_t rc = 0;
-	if (vx6953_ctrl->sensormode != SENSOR_SNAPSHOT_MODE) {
-		frame_length_lines = VX6953_QTR_SIZE_HEIGHT +
-		VX6953_VER_QTR_BLK_LINES;
-		line_length_pck = VX6953_QTR_SIZE_WIDTH +
-			VX6953_HRZ_QTR_BLK_PIXELS;
-		if (line > (frame_length_lines -
-			VX6953_STM5M0EDOF_OFFSET)) {
-			vx6953_ctrl->fps = (uint16_t) (30 * Q8 *
-			(frame_length_lines - VX6953_STM5M0EDOF_OFFSET)/
-			line);
-		} else {
-			vx6953_ctrl->fps = (uint16_t) (30 * Q8);
-		}
-	} else {
-		frame_length_lines = VX6953_FULL_SIZE_HEIGHT +
-				VX6953_VER_FULL_BLK_LINES;
-		line_length_pck = VX6953_FULL_SIZE_WIDTH +
-				VX6953_HRZ_FULL_BLK_PIXELS;
-	}
-	/* calculate line_length_ratio */
-	if ((frame_length_lines - VX6953_STM5M0EDOF_OFFSET) < line) {
-		line_length_ratio = (line*Q8) /
-			(frame_length_lines - VX6953_STM5M0EDOF_OFFSET);
-		line = frame_length_lines - VX6953_STM5M0EDOF_OFFSET;
-	} else {
-		line_length_ratio = 1*Q8;
-	}
-	vx6953_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
-		GROUPED_PARAMETER_HOLD);
-	line_length_pck = (line_length_pck >
-		MAX_LINE_LENGTH_PCK) ?
-		MAX_LINE_LENGTH_PCK : line_length_pck;
-	line_length_pck = (uint16_t) (line_length_pck *
-		line_length_ratio/Q8);
-	line_length_pck_hi = (uint8_t) ((line_length_pck &
-		0xFF00) >> 8);
-	line_length_pck_lo = (uint8_t) (line_length_pck &
-		0x00FF);
-	vx6953_i2c_write_b_sensor(REG_LINE_LENGTH_PCK_HI,
-		line_length_pck_hi);
-	vx6953_i2c_write_b_sensor(REG_LINE_LENGTH_PCK_LO,
-		line_length_pck_lo);
-	/* update analogue gain registers */
-	gain_hi = (uint8_t) ((gain & 0xFF00) >> 8);
-	gain_lo = (uint8_t) (gain & 0x00FF);
-	vx6953_i2c_write_b_sensor(REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
-		gain_lo);
-	vx6953_i2c_write_b_sensor(REG_DIGITAL_GAIN_GREEN_R_LO, gain_hi);
-	vx6953_i2c_write_b_sensor(REG_DIGITAL_GAIN_RED_LO, gain_hi);
-	vx6953_i2c_write_b_sensor(REG_DIGITAL_GAIN_BLUE_LO, gain_hi);
-	vx6953_i2c_write_b_sensor(REG_DIGITAL_GAIN_GREEN_B_LO, gain_hi);
-	CDBG("%s, gain_hi 0x%x, gain_lo 0x%x\n", __func__,
-		gain_hi, gain_lo);
-	/* update line count registers */
-	intg_time_hi = (uint8_t) (((uint16_t)line & 0xFF00) >> 8);
-	intg_time_lo = (uint8_t) ((uint16_t)line & 0x00FF);
-	vx6953_i2c_write_b_sensor(REG_COARSE_INTEGRATION_TIME_HI,
-		intg_time_hi);
-	vx6953_i2c_write_b_sensor(REG_COARSE_INTEGRATION_TIME_LO,
-		intg_time_lo);
-	vx6953_i2c_write_b_sensor(REG_GROUPED_PARAMETER_HOLD,
-		GROUPED_PARAMETER_HOLD_OFF);
-
-	return rc;
-}
-
-static int32_t vx6953_set_pict_exp_gain(uint16_t gain, uint32_t line)
-{
-	int32_t rc = 0;
-	rc = vx6953_write_exp_gain(gain, line);
-	return rc;
-} /* endof vx6953_set_pict_exp_gain*/
-
-static int32_t vx6953_move_focus(int direction,
-	int32_t num_steps)
-{
-	return 0;
-}
-
-
-static int32_t vx6953_set_default_focus(uint8_t af_step)
-{
-	return 0;
-}
-
-static int32_t vx6953_test(enum vx6953_test_mode_t mo)
-{
-	int32_t rc = 0;
-	if (mo == TEST_OFF)
-		return rc;
-	else {
-		/* REG_0x30D8[4] is TESBYPEN: 0: Normal Operation,
-		1: Bypass Signal Processing
-		REG_0x30D8[5] is EBDMASK: 0:
-		Output Embedded data, 1: No output embedded data */
-		if (vx6953_i2c_write_b_sensor(REG_TEST_PATTERN_MODE,
-			(uint8_t) mo) < 0) {
-			return rc;
-		}
-	}
-	return rc;
-}
-
-static int vx6953_enable_edof(enum edof_mode_t edof_mode)
-{
-	int rc = 0;
-	if (edof_mode == VX6953_EDOF_ESTIMATION) {
-		/* EDof Estimation mode for preview */
-		if (vx6953_i2c_write_b_sensor(REG_0x0b80, 0x02) < 0)
-			return rc;
-		CDBG("VX6953_EDOF_ESTIMATION");
-	} else if (edof_mode == VX6953_EDOF_APPLICATION) {
-		/* EDof Application mode for Capture */
-		if (vx6953_i2c_write_b_sensor(REG_0x0b80, 0x01) < 0)
-			return rc;
-		CDBG("VX6953_EDOF_APPLICATION");
-	} else {
-		/* EDOF disabled */
-		if (vx6953_i2c_write_b_sensor(REG_0x0b80, 0x00) < 0)
-			return rc;
-		CDBG("VX6953_EDOF_DISABLE");
-	}
-	return rc;
-}
-
-static int32_t vx6953_patch_for_cut2(void)
-{
-	int32_t rc = 0;
-	rc = vx6953_i2c_write_w_table(patch_tbl_cut2,
-		ARRAY_SIZE(patch_tbl_cut2));
-	if (rc < 0)
-		return rc;
-
-	return rc;
-}
-static int32_t vx6953_patch_for_cut3(void)
-{
-	int32_t rc = 0;
-	rc = vx6953_i2c_write_w_table(patch_tbl_cut3,
-		ARRAY_SIZE(patch_tbl_cut3));
-	if (rc < 0)
-		return rc;
-
-	return rc;
-}
-static int32_t vx6953_sensor_setting(int update_type, int rt)
-{
-
-	int32_t rc = 0;
-	unsigned short frame_cnt;
-	struct msm_camera_csi_params vx6953_csi_params;
-	if (vx6953_ctrl->sensor_type != VX6953_STM5M0EDOF_CUT_2) {
-		switch (update_type) {
-		case REG_INIT:
-		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
-			struct vx6953_i2c_reg_conf init_tbl[] = {
-			{REG_0x0112,
-				vx6953_regs.reg_pat_init[0].reg_0x0112},
-			{0x6003, 0x01},
-			{REG_0x0113,
-				vx6953_regs.reg_pat_init[0].reg_0x0113},
-			{REG_VT_PIX_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				vt_pix_clk_div},
-			{REG_PRE_PLL_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				pre_pll_clk_div},
-			{REG_PLL_MULTIPLIER,
-				vx6953_regs.reg_pat_init[0].
-				pll_multiplier},
-			{REG_OP_PIX_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				op_pix_clk_div},
-			{REG_COARSE_INTEGRATION_TIME_HI,
-				vx6953_regs.reg_pat[rt].
-				coarse_integration_time_hi},
-			{REG_COARSE_INTEGRATION_TIME_LO,
-				vx6953_regs.reg_pat[rt].
-				coarse_integration_time_lo},
-			{REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
-				vx6953_regs.reg_pat[rt].
-				analogue_gain_code_global},
-			{REG_0x3030,
-				vx6953_regs.reg_pat_init[0].reg_0x3030},
-			/* 953 specific registers */
-			{REG_0x0111,
-				vx6953_regs.reg_pat_init[0].reg_0x0111},
-			{REG_0x0b00,
-				vx6953_regs.reg_pat_init[0].reg_0x0b00},
-			{REG_0x3001,
-				vx6953_regs.reg_pat_init[0].reg_0x3001},
-			{REG_0x3004,
-				vx6953_regs.reg_pat_init[0].reg_0x3004},
-			{0x3006, 0x00},
-			{REG_0x3007,
-				vx6953_regs.reg_pat_init[0].reg_0x3007},
-			{0x301b, 0x29},
-			/* DEFCOR settings */
-			/*Single Defect Correction Weight DISABLE*/
-			{0x0b06,
-				vx6953_regs.reg_pat_init[0].reg_0x0b06},
-			/*Single_defect_correct_weight = auto*/
-			{0x0b07,
-				vx6953_regs.reg_pat_init[0].reg_0x0b07},
-			/*Dynamic couplet correction ENABLED*/
-			{0x0b08,
-				vx6953_regs.reg_pat_init[0].reg_0x0b08},
-			/*Dynamic couplet correction weight*/
-			{0x0b09,
-				vx6953_regs.reg_pat_init[0].reg_0x0b09},
-			/* Clock Setup */
-			/* Tell sensor ext clk is 24MHz*/
-			{REG_0x0136,
-				vx6953_regs.reg_pat_init[0].reg_0x0136},
-			{REG_0x0137,
-				vx6953_regs.reg_pat_init[0].reg_0x0137},
-			/* The white balance gains must be written
-			to the sensor every frame. */
-			/* Edof */
-			{REG_0x0b83,
-				vx6953_regs.reg_pat_init[0].reg_0x0b83},
-			{REG_0x0b84,
-				vx6953_regs.reg_pat_init[0].reg_0x0b84},
-			{REG_0x0b85,
-				vx6953_regs.reg_pat_init[0].reg_0x0b85},
-			{REG_0x0b88,
-				vx6953_regs.reg_pat_init[0].reg_0x0b88},
-			{REG_0x0b89,
-				vx6953_regs.reg_pat_init[0].reg_0x0b89},
-			{REG_0x0b8a,
-				vx6953_regs.reg_pat_init[0].reg_0x0b8a},
-			/* Mode specific regieters */
-			{REG_FRAME_LENGTH_LINES_HI,
-				vx6953_regs.reg_pat[rt].
-				frame_length_lines_hi},
-			{REG_FRAME_LENGTH_LINES_LO,
-				vx6953_regs.reg_pat[rt].
-				frame_length_lines_lo},
-			{REG_LINE_LENGTH_PCK_HI,
-				vx6953_regs.reg_pat[rt].
-				line_length_pck_hi},
-			{REG_LINE_LENGTH_PCK_LO,
-				vx6953_regs.reg_pat[rt].
-				line_length_pck_lo},
-			{REG_0x3005,
-				vx6953_regs.reg_pat[rt].reg_0x3005},
-			{0x3010,
-				vx6953_regs.reg_pat[rt].reg_0x3010},
-			{REG_0x3011,
-				vx6953_regs.reg_pat[rt].reg_0x3011},
-			{REG_0x301a,
-				vx6953_regs.reg_pat[rt].reg_0x301a},
-			{REG_0x3035,
-				vx6953_regs.reg_pat[rt].reg_0x3035},
-			{REG_0x3036,
-				vx6953_regs.reg_pat[rt].reg_0x3036},
-			{REG_0x3041,
-				vx6953_regs.reg_pat[rt].reg_0x3041},
-			{0x3042,
-				vx6953_regs.reg_pat[rt].reg_0x3042},
-			{REG_0x3045,
-				vx6953_regs.reg_pat[rt].reg_0x3045},
-			/*EDOF: Estimation settings for Preview mode
-			Application settings for capture mode
-			(standard settings - Not tuned) */
-			{REG_0x0b80,
-				vx6953_regs.reg_pat[rt].reg_0x0b80},
-			{REG_0x0900,
-				vx6953_regs.reg_pat[rt].reg_0x0900},
-			{REG_0x0901,
-				vx6953_regs.reg_pat[rt].reg_0x0901},
-			{REG_0x0902,
-				vx6953_regs.reg_pat[rt].reg_0x0902},
-			{REG_0x0383,
-				vx6953_regs.reg_pat[rt].reg_0x0383},
-			{REG_0x0387,
-				vx6953_regs.reg_pat[rt].reg_0x0387},
-			/* Change output size / frame rate */
-			{REG_0x034c,
-				vx6953_regs.reg_pat[rt].reg_0x034c},
-			{REG_0x034d,
-				vx6953_regs.reg_pat[rt].reg_0x034d},
-			{REG_0x034e,
-				vx6953_regs.reg_pat[rt].reg_0x034e},
-			{REG_0x034f,
-				vx6953_regs.reg_pat[rt].reg_0x034f},
-			};
-			/* reset fps_divider */
-			vx6953_ctrl->fps = 30 * Q8;
-			/* stop streaming */
-
-			/* Reset everything first */
-			if (vx6953_i2c_write_b_sensor(0x103, 0x01) < 0) {
-				CDBG("S/W reset failed\n");
-				return rc;
-			} else
-				CDBG("S/W reset successful\n");
-
-			msleep(10);
-
-			CDBG("Init vx6953_sensor_setting standby\n");
-			if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
-				MODE_SELECT_STANDBY_MODE) < 0)
-				return rc;
-			/*vx6953_stm5m0edof_delay_msecs_stdby*/
-			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-
-
-
-			vx6953_patch_for_cut3();
-			rc = vx6953_i2c_write_w_table(&init_tbl[0],
-				ARRAY_SIZE(init_tbl));
-			if (rc < 0)
-				return rc;
-
-			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-
-			vx6953_i2c_write_b_sensor(0x0b80, 0x00);
-			vx6953_i2c_write_b_sensor(0x3388, 0x03);
-			vx6953_i2c_write_b_sensor(0x3640, 0x00);
-
-			rc = vx6953_i2c_write_w_table(&edof_tbl[0],
-				ARRAY_SIZE(edof_tbl));
-			vx6953_i2c_write_b_sensor(0x3388, 0x00);
-
-		}
-		return rc;
-		case UPDATE_PERIODIC:
-		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
-			struct vx6953_i2c_reg_conf preview_mode_tbl[] = {
-			{REG_0x0112,
-				vx6953_regs.reg_pat_init[0].reg_0x0112},
-			{0x6003, 0x01},
-			{REG_0x0113,
-				vx6953_regs.reg_pat_init[0].reg_0x0113},
-			{REG_VT_PIX_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				vt_pix_clk_div},
-			{REG_PRE_PLL_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				pre_pll_clk_div},
-			{REG_PLL_MULTIPLIER,
-				vx6953_regs.reg_pat_init[0].
-				pll_multiplier},
-			{REG_OP_PIX_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				op_pix_clk_div},
-
-			{REG_COARSE_INTEGRATION_TIME_HI,
-				vx6953_regs.reg_pat[rt].
-				coarse_integration_time_hi},
-			{REG_COARSE_INTEGRATION_TIME_LO,
-				vx6953_regs.reg_pat[rt].
-				coarse_integration_time_lo},
-			{REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
-				vx6953_regs.reg_pat[rt].
-				analogue_gain_code_global},
-
-			{REG_0x3210, vx6953_regs.reg_pat[rt].reg_0x3210},
-			{REG_0x0111, vx6953_regs.reg_pat[rt].reg_0x111},
-			{REG_0x3410, vx6953_regs.reg_pat[rt].reg_0x3410},
-
-			{REG_0x3004,
-				vx6953_regs.reg_pat_init[0].reg_0x3004},
-			{REG_0x3006, 0x00},
-			{REG_0x3007,
-				vx6953_regs.reg_pat_init[0].reg_0x3007},
-			{REG_0x301b, 0x29},
-			{REG_0x3036,
-				vx6953_regs.reg_pat[rt].reg_0x3036},
-			{REG_0x3045, vx6953_regs.reg_pat[rt].reg_0x3045},
-			{REG_0x3098, vx6953_regs.reg_pat[rt].reg_0x3098},
-			{REG_0x309d, vx6953_regs.reg_pat[rt].reg_0x309D},
-
-			{REG_0x0900, vx6953_regs.reg_pat[rt].reg_0x0900},
-			{REG_0x0901, vx6953_regs.reg_pat[rt].reg_0x0901},
-			{REG_0x0902, vx6953_regs.reg_pat[rt].reg_0x0902},
-			{REG_0x0383, vx6953_regs.reg_pat[rt].reg_0x0383},
-			{REG_0x0387, vx6953_regs.reg_pat[rt].reg_0x0387},
-
-			{REG_FRAME_LENGTH_LINES_HI,
-				vx6953_regs.reg_pat[rt].
-				frame_length_lines_hi},
-			{REG_FRAME_LENGTH_LINES_LO,
-				vx6953_regs.reg_pat[rt].
-				frame_length_lines_lo},
-			{REG_LINE_LENGTH_PCK_HI,
-				vx6953_regs.reg_pat[rt].
-				line_length_pck_hi},
-			{REG_LINE_LENGTH_PCK_LO,
-				vx6953_regs.reg_pat[rt].
-				line_length_pck_lo},
-			{REG_0x034c,
-				vx6953_regs.reg_pat[rt].reg_0x034c},
-			{REG_0x034d,
-				vx6953_regs.reg_pat[rt].reg_0x034d},
-			{REG_0x034e,
-				vx6953_regs.reg_pat[rt].reg_0x034e},
-			{REG_0x034f,
-				vx6953_regs.reg_pat[rt].reg_0x034f},
-
-			{REG_0x3005, vx6953_regs.reg_pat[rt].reg_0x3005},
-			{REG_0x3010, vx6953_regs.reg_pat[rt].reg_0x3010},
-			{REG_0x3011, vx6953_regs.reg_pat[rt].reg_0x3011},
-			{REG_0x301a, vx6953_regs.reg_pat[rt].reg_0x301a},
-			{REG_0x3030, 0x08},
-			{REG_0x3035, vx6953_regs.reg_pat[rt].reg_0x3035},
-			{REG_0x3041, vx6953_regs.reg_pat[rt].reg_0x3041},
-			{0x3042, vx6953_regs.reg_pat[rt].reg_0x3042},
-
-			{0x200, vx6953_regs.reg_pat[rt].reg_0x0200},
-			{0x201, vx6953_regs.reg_pat[rt].reg_0x0201},
-
-			{0x0b06,
-				vx6953_regs.reg_pat_init[0].reg_0x0b06},
-			/*Single_defect_correct_weight = auto*/
-			{0x0b07,
-				vx6953_regs.reg_pat_init[0].reg_0x0b07},
-			/*Dynamic couplet correction ENABLED*/
-			{0x0b08,
-				vx6953_regs.reg_pat_init[0].reg_0x0b08},
-			/*Dynamic couplet correction weight*/
-			{0x0b09,
-				vx6953_regs.reg_pat_init[0].reg_0x0b09},
-
-			{REG_0x0136,
-				vx6953_regs.reg_pat_init[0].reg_0x0136},
-			{REG_0x0137,
-				vx6953_regs.reg_pat_init[0].reg_0x0137},
-
-			/*EDOF: Estimation settings for Preview mode
-			Application settings for capture
-			mode(standard settings - Not tuned) */
-			{REG_0x0b80, vx6953_regs.reg_pat[rt].reg_0x0b80},
-			{REG_0x0b83,
-				vx6953_regs.reg_pat_init[0].reg_0x0b83},
-			{REG_0x0b84,
-				vx6953_regs.reg_pat_init[0].reg_0x0b84},
-			{REG_0x0b85,
-				vx6953_regs.reg_pat_init[0].reg_0x0b85},
-			{REG_0x0b88,
-				vx6953_regs.reg_pat_init[0].reg_0x0b88},
-			{REG_0x0b89,
-				vx6953_regs.reg_pat_init[0].reg_0x0b89},
-			{REG_0x0b8a,
-				vx6953_regs.reg_pat_init[0].reg_0x0b8a},
-			{0x3393, 0x06}, /* man_spec_edof_ctrl_edof*/
-			{0x3394, 0x07}, /* man_spec_edof_ctrl_edof*/
-			};
-
-			struct vx6953_i2c_reg_conf snapshot_mode_tbl[] = {
-			{REG_MODE_SELECT,	MODE_SELECT_STANDBY_MODE},
-			{REG_0x0112,
-				vx6953_regs.reg_pat_init[0].reg_0x0112},
-			{0x6003, 0x01},
-			{REG_0x0113,
-				vx6953_regs.reg_pat_init[0].reg_0x0113},
-			{REG_VT_PIX_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				vt_pix_clk_div},
-			{0x303,	1}, /* VT_SYS_CLK_DIV */
-			{REG_PRE_PLL_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				pre_pll_clk_div},
-			{REG_PLL_MULTIPLIER,
-				vx6953_regs.reg_pat_init[0].
-				pll_multiplier},
-			{REG_OP_PIX_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				op_pix_clk_div},
-			{0x30b,	1},
-			{REG_COARSE_INTEGRATION_TIME_HI,
-				vx6953_regs.reg_pat[rt].
-				coarse_integration_time_hi},
-			{REG_COARSE_INTEGRATION_TIME_LO,
-				vx6953_regs.reg_pat[rt].
-				coarse_integration_time_lo},
-			{REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
-				vx6953_regs.reg_pat[rt].
-				analogue_gain_code_global},
-			{REG_LINE_LENGTH_PCK_HI,
-				vx6953_regs.reg_pat[rt].
-				line_length_pck_hi},
-			{REG_LINE_LENGTH_PCK_LO,
-				vx6953_regs.reg_pat[rt].
-				line_length_pck_lo},
-			{REG_FRAME_LENGTH_LINES_HI,
-				vx6953_regs.reg_pat[rt].
-				frame_length_lines_hi},
-			{REG_FRAME_LENGTH_LINES_LO,
-				vx6953_regs.reg_pat[rt].
-				frame_length_lines_lo},
-			{REG_0x3210, vx6953_regs.reg_pat[rt].reg_0x3210},
-			{REG_0x0111, vx6953_regs.reg_pat[rt].reg_0x111},
-
-			{REG_0x0b00,
-				vx6953_regs.reg_pat_init[0].reg_0x0b00},
-			{0x3140, 0x01},  /* AV2X2 block enabled */
-			{REG_0x3410, vx6953_regs.reg_pat[rt].reg_0x3410},
-			{0x0b06,
-				vx6953_regs.reg_pat_init[0].reg_0x0b06},
-			/*Single_defect_correct_weight = auto*/
-			{0x0b07,
-				vx6953_regs.reg_pat_init[0].reg_0x0b07},
-			/*Dynamic couplet correction ENABLED*/
-			{0x0b08,
-				vx6953_regs.reg_pat_init[0].reg_0x0b08},
-			/*Dynamic couplet correction weight*/
-			{0x0b09,
-				vx6953_regs.reg_pat_init[0].reg_0x0b09},
-
-
-			{REG_0x3004,
-				vx6953_regs.reg_pat_init[0].reg_0x3004},
-			{REG_0x3006, 0x00},
-			{REG_0x3007,
-				vx6953_regs.reg_pat_init[0].reg_0x3007},
-			{0x301A, 0x6A},
-			{REG_0x301b, 0x29},
-			{REG_0x3036,
-				vx6953_regs.reg_pat[rt].reg_0x3036},
-			{REG_0x3045, vx6953_regs.reg_pat[rt].reg_0x3045},
-			{REG_0x3098, vx6953_regs.reg_pat[rt].reg_0x3098},
-			{REG_0x309d, vx6953_regs.reg_pat[rt].reg_0x309D},
-
-			{REG_0x0136,
-				vx6953_regs.reg_pat_init[0].reg_0x0136},
-			{REG_0x0137,
-				vx6953_regs.reg_pat_init[0].reg_0x0137},
-
-			{REG_0x0b80, vx6953_regs.reg_pat[rt].reg_0x0b80},
-			{REG_0x0b83,
-				vx6953_regs.reg_pat_init[0].reg_0x0b83},
-			{REG_0x0b84,
-				vx6953_regs.reg_pat_init[0].reg_0x0b84},
-			{REG_0x0b85,
-				vx6953_regs.reg_pat_init[0].reg_0x0b85},
-			{REG_0x0b88,
-				vx6953_regs.reg_pat_init[0].reg_0x0b88},
-			{REG_0x0b89,
-				vx6953_regs.reg_pat_init[0].reg_0x0b89},
-			{REG_0x0b8a,
-				vx6953_regs.reg_pat_init[0].reg_0x0b8a},
-			{0x3393, 0x06}, /* man_spec_edof_ctrl*/
-			{0x3394, 0x07}, /* man_spec_edof_ctrl*/
-			};
-			/* stop streaming */
-			msleep(5);
-
-			/* Reset everything first */
-
-			if (vx6953_i2c_write_b_sensor(0x103, 0x01) < 0) {
-				CDBG("S/W reset failed\n");
-				return rc;
-			} else
-				CDBG("S/W reset successful\n");
-
-			msleep(10);
-
-			if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
-				MODE_SELECT_STANDBY_MODE) < 0)
-				return rc;
-			/*vx6953_stm5m0edof_delay_msecs_stdby*/
-			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-
-			vx6953_csi_params.data_format = CSI_8BIT;
-			vx6953_csi_params.lane_cnt = 1;
-			vx6953_csi_params.lane_assign = 0xe4;
-			vx6953_csi_params.dpcm_scheme = 0;
-			vx6953_csi_params.settle_cnt = 7;
-			rc = msm_camio_csi_config(&vx6953_csi_params);
-			if (rc < 0)
-				CDBG(" config csi controller failed\n");
-
-			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-
-			vx6953_patch_for_cut3();
-
-			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-
-			if (rt == RES_PREVIEW) {
-				rc = vx6953_i2c_write_w_table(
-					&preview_mode_tbl[0],
-					ARRAY_SIZE(preview_mode_tbl));
-				if (rc < 0)
-					return rc;
-			}
-			if (rt == RES_CAPTURE) {
-				rc = vx6953_i2c_write_w_table(
-					&snapshot_mode_tbl[0],
-					ARRAY_SIZE(snapshot_mode_tbl));
-				if (rc < 0)
-					return rc;
-			}
-			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-
-			/* Start sensor streaming */
-			if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
-				MODE_SELECT_STREAM) < 0)
-				return rc;
-			msleep(vx6953_stm5m0edof_delay_msecs_stream);
-			/* man_spec_edof_ctrl_tune_smooth_lowlight*/
-			vx6953_i2c_write_b_sensor(0x338d, 0x08);
-			/* man_spec_edof_ctrl_tune_smooth_indoor*/
-			vx6953_i2c_write_b_sensor(0x338e, 0x08);
-			/* man_spec_edof_ctrl_tune_smooth_outdoor*/
-			vx6953_i2c_write_b_sensor(0x338f, 0x00);
-			/*Apply Capture FPGA state machine reset*/
-			vx6953_i2c_write_b_sensor(0x16, 0x00);
-			msleep(100);
-			vx6953_i2c_write_b_sensor(0x16, 0x01);
-
-			if (vx6953_i2c_read(0x0005, &frame_cnt, 1) < 0)
-				return rc;
-
-			while (frame_cnt == 0xFF) {
-				if (vx6953_i2c_read(0x0005, &frame_cnt, 1) < 0)
-					return rc;
-				CDBG("frame_cnt=%d", frame_cnt);
-				msleep(10);
-			}
-		}
-		return rc;
-		default:
-			return rc;
-		}
-	} else {
-		switch (update_type) {
-		case REG_INIT:
-		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
-			struct vx6953_i2c_reg_conf init_tbl[] = {
-			{REG_0x0112,
-				vx6953_regs.reg_pat_init[0].reg_0x0112},
-			{REG_0x0113,
-				vx6953_regs.reg_pat_init[0].reg_0x0113},
-			{REG_VT_PIX_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				vt_pix_clk_div},
-			{REG_PRE_PLL_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				pre_pll_clk_div},
-			{REG_PLL_MULTIPLIER,
-				vx6953_regs.reg_pat_init[0].
-				pll_multiplier},
-			{REG_OP_PIX_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				op_pix_clk_div},
-			{REG_COARSE_INTEGRATION_TIME_HI,
-				vx6953_regs.reg_pat[rt].
-				coarse_integration_time_hi},
-			{REG_COARSE_INTEGRATION_TIME_LO,
-				vx6953_regs.reg_pat[rt].
-				coarse_integration_time_lo},
-			{REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
-				vx6953_regs.reg_pat[rt].
-				analogue_gain_code_global},
-			{REG_0x3030,
-				vx6953_regs.reg_pat_init[0].reg_0x3030},
-			/* 953 specific registers */
-			{REG_0x0111,
-				vx6953_regs.reg_pat_init[0].reg_0x0111},
-			{REG_0x0b00,
-				vx6953_regs.reg_pat_init[0].reg_0x0b00},
-			{REG_0x3001,
-				vx6953_regs.reg_pat_init[0].reg_0x3001},
-			{REG_0x3004,
-				vx6953_regs.reg_pat_init[0].reg_0x3004},
-			{REG_0x3007,
-				vx6953_regs.reg_pat_init[0].reg_0x3007},
-			{REG_0x3016,
-				vx6953_regs.reg_pat_init[0].reg_0x3016},
-			{REG_0x301d,
-				vx6953_regs.reg_pat_init[0].reg_0x301d},
-			{REG_0x317e,
-				vx6953_regs.reg_pat_init[0].reg_0x317e},
-			{REG_0x317f,
-				vx6953_regs.reg_pat_init[0].reg_0x317f},
-			{REG_0x3400,
-				vx6953_regs.reg_pat_init[0].reg_0x3400},
-			/* DEFCOR settings */
-			/*Single Defect Correction Weight DISABLE*/
-			{0x0b06,
-				vx6953_regs.reg_pat_init[0].reg_0x0b06},
-			/*Single_defect_correct_weight = auto*/
-			{0x0b07,
-				vx6953_regs.reg_pat_init[0].reg_0x0b07},
-			/*Dynamic couplet correction ENABLED*/
-			{0x0b08,
-				vx6953_regs.reg_pat_init[0].reg_0x0b08},
-			/*Dynamic couplet correction weight*/
-			{0x0b09,
-				vx6953_regs.reg_pat_init[0].reg_0x0b09},
-			/* Clock Setup */
-			/* Tell sensor ext clk is 24MHz*/
-			{0x0136,
-				vx6953_regs.reg_pat_init[0].reg_0x0136},
-			{0x0137,
-				vx6953_regs.reg_pat_init[0].reg_0x0137},
-			/* The white balance gains must be written
-			to the sensor every frame. */
-			/* Edof */
-			{REG_0x0b83,
-				vx6953_regs.reg_pat_init[0].reg_0x0b83},
-			{REG_0x0b84,
-				vx6953_regs.reg_pat_init[0].reg_0x0b84},
-			{0x0b85,
-				vx6953_regs.reg_pat_init[0].reg_0x0b85},
-			{0x0b88,
-				vx6953_regs.reg_pat_init[0].reg_0x0b88},
-			{0x0b89,
-				vx6953_regs.reg_pat_init[0].reg_0x0b89},
-			{REG_0x0b8a,
-				vx6953_regs.reg_pat_init[0].reg_0x0b8a},
-			/* Mode specific regieters */
-			{REG_FRAME_LENGTH_LINES_HI,
-				vx6953_regs.reg_pat[rt].
-				frame_length_lines_hi},
-			{REG_FRAME_LENGTH_LINES_LO,
-				vx6953_regs.reg_pat[rt].
-				frame_length_lines_lo},
-			{REG_LINE_LENGTH_PCK_HI,
-				vx6953_regs.reg_pat[rt].
-				line_length_pck_hi},
-			{REG_LINE_LENGTH_PCK_LO,
-				vx6953_regs.reg_pat[rt].
-				line_length_pck_lo},
-			{REG_0x3005,
-				vx6953_regs.reg_pat[rt].reg_0x3005},
-			{0x3010,
-				vx6953_regs.reg_pat[rt].reg_0x3010},
-			{REG_0x3011,
-				vx6953_regs.reg_pat[rt].reg_0x3011},
-			{REG_0x301a,
-				vx6953_regs.reg_pat[rt].reg_0x301a},
-			{REG_0x3035,
-				vx6953_regs.reg_pat[rt].reg_0x3035},
-			{REG_0x3036,
-				vx6953_regs.reg_pat[rt].reg_0x3036},
-			{REG_0x3041,
-				vx6953_regs.reg_pat[rt].reg_0x3041},
-			{0x3042,
-				vx6953_regs.reg_pat[rt].reg_0x3042},
-			{REG_0x3045,
-				vx6953_regs.reg_pat[rt].reg_0x3045},
-			/*EDOF: Estimation settings for Preview mode
-			Application settings for capture mode
-			(standard settings - Not tuned) */
-			{REG_0x0b80,
-				vx6953_regs.reg_pat[rt].reg_0x0b80},
-			{REG_0x0900,
-				vx6953_regs.reg_pat[rt].reg_0x0900},
-			{REG_0x0901,
-				vx6953_regs.reg_pat[rt].reg_0x0901},
-			{REG_0x0902,
-				vx6953_regs.reg_pat[rt].reg_0x0902},
-			{REG_0x0383,
-				vx6953_regs.reg_pat[rt].reg_0x0383},
-			{REG_0x0387,
-				vx6953_regs.reg_pat[rt].reg_0x0387},
-			/* Change output size / frame rate */
-			{REG_0x034c,
-				vx6953_regs.reg_pat[rt].reg_0x034c},
-			{REG_0x034d,
-				vx6953_regs.reg_pat[rt].reg_0x034d},
-			{REG_0x034e,
-				vx6953_regs.reg_pat[rt].reg_0x034e},
-			{REG_0x034f,
-				vx6953_regs.reg_pat[rt].reg_0x034f},
-			{REG_0x1716,
-				vx6953_regs.reg_pat[rt].reg_0x1716},
-			{REG_0x1717,
-				vx6953_regs.reg_pat[rt].reg_0x1717},
-			{REG_0x1718,
-				vx6953_regs.reg_pat[rt].reg_0x1718},
-			{REG_0x1719,
-				vx6953_regs.reg_pat[rt].reg_0x1719},
-			};
-			/* reset fps_divider */
-			vx6953_ctrl->fps = 30 * Q8;
-			/* stop streaming */
-
-			/* Reset everything first */
-			if (vx6953_i2c_write_b_sensor(0x103, 0x01) < 0) {
-				CDBG("S/W reset failed\n");
-				return rc;
-			} else
-				CDBG("S/W reset successful\n");
-
-			msleep(10);
-
-			CDBG("Init vx6953_sensor_setting standby\n");
-			if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
-				MODE_SELECT_STANDBY_MODE) < 0)
-				return rc;
-				/*vx6953_stm5m0edof_delay_msecs_stdby*/
-			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-			vx6953_patch_for_cut2();
-			rc = vx6953_i2c_write_w_table(&init_tbl[0],
-				ARRAY_SIZE(init_tbl));
-			if (rc < 0)
-				return rc;
-				msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-		}
-		return rc;
-		case UPDATE_PERIODIC:
-		if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
-			struct vx6953_i2c_reg_conf init_mode_tbl[] =  {
-			{REG_0x0112,
-				vx6953_regs.reg_pat_init[0].reg_0x0112},
-			{REG_0x0113,
-				vx6953_regs.reg_pat_init[0].reg_0x0113},
-			{REG_VT_PIX_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				vt_pix_clk_div},
-			{REG_PRE_PLL_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				pre_pll_clk_div},
-			{REG_PLL_MULTIPLIER,
-				vx6953_regs.reg_pat_init[0].
-				pll_multiplier},
-			{REG_OP_PIX_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				op_pix_clk_div},
-			{REG_COARSE_INTEGRATION_TIME_HI,
-				vx6953_regs.reg_pat[rt].
-				coarse_integration_time_hi},
-			{REG_COARSE_INTEGRATION_TIME_LO,
-				vx6953_regs.reg_pat[rt].
-				coarse_integration_time_lo},
-			{REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
-				vx6953_regs.reg_pat[rt].
-				analogue_gain_code_global},
-			{REG_0x3030,
-				vx6953_regs.reg_pat_init[0].reg_0x3030},
-			/* 953 specific registers */
-			{REG_0x0111,
-				vx6953_regs.reg_pat_init[0].reg_0x0111},
-			{REG_0x0b00,
-				vx6953_regs.reg_pat_init[0].reg_0x0b00},
-			{REG_0x3001,
-				vx6953_regs.reg_pat_init[0].reg_0x3001},
-			{REG_0x3004,
-				vx6953_regs.reg_pat_init[0].reg_0x3004},
-			{REG_0x3007,
-				vx6953_regs.reg_pat_init[0].reg_0x3007},
-			{REG_0x3016,
-				vx6953_regs.reg_pat_init[0].reg_0x3016},
-			{REG_0x301d,
-				vx6953_regs.reg_pat_init[0].reg_0x301d},
-			{REG_0x317e,
-				vx6953_regs.reg_pat_init[0].reg_0x317e},
-			{REG_0x317f,
-				vx6953_regs.reg_pat_init[0].reg_0x317f},
-			{REG_0x3400,
-				vx6953_regs.reg_pat_init[0].reg_0x3400},
-			{0x0b06,
-				vx6953_regs.reg_pat_init[0].reg_0x0b06},
-			/*Single_defect_correct_weight = auto*/
-			{0x0b07,
-				vx6953_regs.reg_pat_init[0].reg_0x0b07},
-			/*Dynamic couplet correction ENABLED*/
-			{0x0b08,
-				vx6953_regs.reg_pat_init[0].reg_0x0b08},
-			/*Dynamic couplet correction weight*/
-			{0x0b09,
-				vx6953_regs.reg_pat_init[0].reg_0x0b09},
-			/* Clock Setup */
-			/* Tell sensor ext clk is 24MHz*/
-			{0x0136,
-				vx6953_regs.reg_pat_init[0].reg_0x0136},
-			{0x0137,
-				vx6953_regs.reg_pat_init[0].reg_0x0137},
-			/* The white balance gains must be written
-			to the sensor every frame. */
-			/* Edof */
-			{REG_0x0b83,
-				vx6953_regs.reg_pat_init[0].reg_0x0b83},
-			{REG_0x0b84,
-				vx6953_regs.reg_pat_init[0].reg_0x0b84},
-			{0x0b85,
-				vx6953_regs.reg_pat_init[0].reg_0x0b85},
-			{0x0b88,
-				vx6953_regs.reg_pat_init[0].reg_0x0b88},
-			{0x0b89,
-				vx6953_regs.reg_pat_init[0].reg_0x0b89},
-			{REG_0x0b8a,
-				vx6953_regs.reg_pat_init[0].reg_0x0b8a},
-			/* Mode specific regieters */
-			{REG_FRAME_LENGTH_LINES_HI,
-				vx6953_regs.reg_pat[rt].
-				frame_length_lines_hi},
-			{REG_FRAME_LENGTH_LINES_LO,
-				vx6953_regs.reg_pat[rt].
-				frame_length_lines_lo},
-			{REG_LINE_LENGTH_PCK_HI,
-				vx6953_regs.reg_pat[rt].
-				line_length_pck_hi},
-			{REG_LINE_LENGTH_PCK_LO,
-				vx6953_regs.reg_pat[rt].
-				line_length_pck_lo},
-			{REG_0x3005,
-				vx6953_regs.reg_pat[rt].reg_0x3005},
-			{0x3010,
-				vx6953_regs.reg_pat[rt].reg_0x3010},
-			{REG_0x3011,
-				vx6953_regs.reg_pat[rt].reg_0x3011},
-			{REG_0x301a,
-				vx6953_regs.reg_pat[rt].reg_0x301a},
-			{REG_0x3035,
-				vx6953_regs.reg_pat[rt].reg_0x3035},
-			{REG_0x3036,
-				vx6953_regs.reg_pat[rt].reg_0x3036},
-			{REG_0x3041,
-				vx6953_regs.reg_pat[rt].reg_0x3041},
-			{0x3042,
-				vx6953_regs.reg_pat[rt].reg_0x3042},
-			{REG_0x3045,
-				vx6953_regs.reg_pat[rt].reg_0x3045},
-			/*EDOF: Estimation settings for Preview mode
-			Application settings for capture mode
-			(standard settings - Not tuned) */
-			{REG_0x0b80,
-				vx6953_regs.reg_pat[rt].reg_0x0b80},
-			{REG_0x0900,
-				vx6953_regs.reg_pat[rt].reg_0x0900},
-			{REG_0x0901,
-				vx6953_regs.reg_pat[rt].reg_0x0901},
-			{REG_0x0902,
-				vx6953_regs.reg_pat[rt].reg_0x0902},
-			{REG_0x0383,
-				vx6953_regs.reg_pat[rt].reg_0x0383},
-			{REG_0x0387,
-				vx6953_regs.reg_pat[rt].reg_0x0387},
-			/* Change output size / frame rate */
-			{REG_0x034c,
-				vx6953_regs.reg_pat[rt].reg_0x034c},
-			{REG_0x034d,
-				vx6953_regs.reg_pat[rt].reg_0x034d},
-			{REG_0x034e,
-				vx6953_regs.reg_pat[rt].reg_0x034e},
-			{REG_0x034f,
-				vx6953_regs.reg_pat[rt].reg_0x034f},
-			{REG_0x1716,
-				vx6953_regs.reg_pat[rt].reg_0x1716},
-			{REG_0x1717,
-				vx6953_regs.reg_pat[rt].reg_0x1717},
-			{REG_0x1718,
-				vx6953_regs.reg_pat[rt].reg_0x1718},
-			{REG_0x1719,
-				vx6953_regs.reg_pat[rt].reg_0x1719},
-			};
-			struct vx6953_i2c_reg_conf mode_tbl[] = {
-			{REG_0x0112,
-				vx6953_regs.reg_pat_init[0].reg_0x0112},
-			{REG_0x0113,
-				vx6953_regs.reg_pat_init[0].reg_0x0113},
-			{REG_VT_PIX_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				vt_pix_clk_div},
-			{REG_PRE_PLL_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				pre_pll_clk_div},
-			{REG_PLL_MULTIPLIER,
-				vx6953_regs.reg_pat_init[0].
-				pll_multiplier},
-			{REG_OP_PIX_CLK_DIV,
-				vx6953_regs.reg_pat_init[0].
-				op_pix_clk_div},
-		/* Mode specific regieters */
-			{REG_FRAME_LENGTH_LINES_HI,
-				vx6953_regs.reg_pat[rt].frame_length_lines_hi},
-			{REG_FRAME_LENGTH_LINES_LO,
-				vx6953_regs.reg_pat[rt].frame_length_lines_lo},
-			{REG_LINE_LENGTH_PCK_HI,
-				vx6953_regs.reg_pat[rt].line_length_pck_hi},
-			{REG_LINE_LENGTH_PCK_LO,
-				vx6953_regs.reg_pat[rt].line_length_pck_lo},
-			{REG_0x3005, vx6953_regs.reg_pat[rt].reg_0x3005},
-			{0x3010, vx6953_regs.reg_pat[rt].reg_0x3010},
-			{REG_0x3011, vx6953_regs.reg_pat[rt].reg_0x3011},
-			{REG_0x301a, vx6953_regs.reg_pat[rt].reg_0x301a},
-			{REG_0x3035, vx6953_regs.reg_pat[rt].reg_0x3035},
-			{REG_0x3036, vx6953_regs.reg_pat[rt].reg_0x3036},
-			{REG_0x3041, vx6953_regs.reg_pat[rt].reg_0x3041},
-			{0x3042, vx6953_regs.reg_pat[rt].reg_0x3042},
-			{REG_0x3045, vx6953_regs.reg_pat[rt].reg_0x3045},
-			/*EDOF: Estimation settings for Preview mode
-			Application settings for capture
-			mode(standard settings - Not tuned) */
-			{REG_0x0b80, vx6953_regs.reg_pat[rt].reg_0x0b80},
-			{REG_0x0900, vx6953_regs.reg_pat[rt].reg_0x0900},
-			{REG_0x0901, vx6953_regs.reg_pat[rt].reg_0x0901},
-			{REG_0x0902, vx6953_regs.reg_pat[rt].reg_0x0902},
-			{REG_0x0383, vx6953_regs.reg_pat[rt].reg_0x0383},
-			{REG_0x0387, vx6953_regs.reg_pat[rt].reg_0x0387},
-			/* Change output size / frame rate */
-			{REG_0x034c, vx6953_regs.reg_pat[rt].reg_0x034c},
-			{REG_0x034d, vx6953_regs.reg_pat[rt].reg_0x034d},
-			{REG_0x034e, vx6953_regs.reg_pat[rt].reg_0x034e},
-			{REG_0x034f, vx6953_regs.reg_pat[rt].reg_0x034f},
-			/*{0x200, vx6953_regs.reg_pat[rt].reg_0x0200},
-			{0x201, vx6953_regs.reg_pat[rt].reg_0x0201},*/
-			{REG_0x1716, vx6953_regs.reg_pat[rt].reg_0x1716},
-			{REG_0x1717, vx6953_regs.reg_pat[rt].reg_0x1717},
-			{REG_0x1718, vx6953_regs.reg_pat[rt].reg_0x1718},
-			{REG_0x1719, vx6953_regs.reg_pat[rt].reg_0x1719},
-			};
-			/* stop streaming */
-			msleep(5);
-
-			/* Reset everything first */
-			if (vx6953_i2c_write_b_sensor(0x103, 0x01) < 0) {
-				CDBG("S/W reset failed\n");
-				return rc;
-			} else
-				CDBG("S/W reset successful\n");
-
-			msleep(10);
-
-			if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
-				MODE_SELECT_STANDBY_MODE) < 0)
-				return rc;
-			/*vx6953_stm5m0edof_delay_msecs_stdby*/
-			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-
-			vx6953_csi_params.data_format = CSI_8BIT;
-			vx6953_csi_params.lane_cnt = 1;
-			vx6953_csi_params.lane_assign = 0xe4;
-			vx6953_csi_params.dpcm_scheme = 0;
-			vx6953_csi_params.settle_cnt = 7;
-			rc = msm_camio_csi_config(&vx6953_csi_params);
-			if (rc < 0)
-				CDBG(" config csi controller failed\n");
-
-			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-
-			vx6953_patch_for_cut2();
-			rc = vx6953_i2c_write_w_table(&init_mode_tbl[0],
-				ARRAY_SIZE(init_mode_tbl));
-			if (rc < 0)
-				return rc;
-
-			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-
-			rc = vx6953_i2c_write_w_table(&mode_tbl[0],
-				ARRAY_SIZE(mode_tbl));
-			if (rc < 0)
-				return rc;
-
-			msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-
-			/* Start sensor streaming */
-			if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
-				MODE_SELECT_STREAM) < 0)
-				return rc;
-			msleep(vx6953_stm5m0edof_delay_msecs_stream);
-
-			if (vx6953_i2c_read(0x0005, &frame_cnt, 1) < 0)
-				return rc;
-
-			while (frame_cnt == 0xFF) {
-				if (vx6953_i2c_read(0x0005, &frame_cnt, 1) < 0)
-					return rc;
-				CDBG("frame_cnt=%d", frame_cnt);
-				msleep(10);
-			}
-		}
-		return rc;
-		default:
-		return rc;
-	}
-	}
-	return rc;
-}
-
-
-static int32_t vx6953_video_config(int mode)
-{
-
-	int32_t	rc = 0;
-	int	rt;
-	/* change sensor resolution	if needed */
-	if (vx6953_ctrl->prev_res == QTR_SIZE) {
-		rt = RES_PREVIEW;
-		vx6953_stm5m0edof_delay_msecs_stdby	=
-			((((2 * 1000 * vx6953_ctrl->fps_divider) /
-			vx6953_ctrl->fps) * Q8) / Q10) + 1;
-	} else {
-		rt = RES_CAPTURE;
-		vx6953_stm5m0edof_delay_msecs_stdby	=
-			((((1000 * vx6953_ctrl->fps_divider) /
-			vx6953_ctrl->fps) * Q8) / Q10) + 1;
-	}
-	if (vx6953_sensor_setting(UPDATE_PERIODIC, rt) < 0)
-		return rc;
-	if (vx6953_ctrl->set_test) {
-		if (vx6953_test(vx6953_ctrl->set_test) < 0)
-			return	rc;
-	}
-	vx6953_ctrl->edof_mode = VX6953_EDOF_ESTIMATION;
-	rc = vx6953_enable_edof(vx6953_ctrl->edof_mode);
-	if (rc < 0)
-		return rc;
-	vx6953_ctrl->curr_res = vx6953_ctrl->prev_res;
-	vx6953_ctrl->sensormode = mode;
-	return rc;
-}
-
-static int32_t vx6953_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-	int rt;
-	/*change sensor resolution if needed */
-	if (vx6953_ctrl->curr_res != vx6953_ctrl->pict_res) {
-		if (vx6953_ctrl->pict_res == QTR_SIZE) {
-			rt = RES_PREVIEW;
-			vx6953_stm5m0edof_delay_msecs_stdby =
-				((((2 * 1000 * vx6953_ctrl->fps_divider) /
-				vx6953_ctrl->fps) * Q8) / Q10) + 1;
-		} else {
-			rt = RES_CAPTURE;
-			vx6953_stm5m0edof_delay_msecs_stdby =
-				((((1000 * vx6953_ctrl->fps_divider) /
-				vx6953_ctrl->fps) * Q8) / Q10) + 1;
-		}
-	if (vx6953_sensor_setting(UPDATE_PERIODIC, rt) < 0)
-		return rc;
-	}
-
-	vx6953_ctrl->edof_mode = VX6953_EDOF_APPLICATION;
-	if (vx6953_enable_edof(vx6953_ctrl->edof_mode) < 0)
-		return rc;
-	vx6953_ctrl->curr_res = vx6953_ctrl->pict_res;
-	vx6953_ctrl->sensormode = mode;
-	return rc;
-} /*end of vx6953_snapshot_config*/
-
-static int32_t vx6953_raw_snapshot_config(int mode)
-{
-	int32_t rc = 0;
-	int rt;
-	/* change sensor resolution if needed */
-	if (vx6953_ctrl->curr_res != vx6953_ctrl->pict_res) {
-		if (vx6953_ctrl->pict_res == QTR_SIZE) {
-			rt = RES_PREVIEW;
-			vx6953_stm5m0edof_delay_msecs_stdby =
-				((((2 * 1000 * vx6953_ctrl->fps_divider)/
-				vx6953_ctrl->fps) * Q8) / Q10) + 1;
-		} else {
-			rt = RES_CAPTURE;
-			vx6953_stm5m0edof_delay_msecs_stdby =
-				((((1000 * vx6953_ctrl->fps_divider)/
-				vx6953_ctrl->fps) * Q8) / Q10) + 1;
-		}
-		if (vx6953_sensor_setting(UPDATE_PERIODIC, rt) < 0)
-			return rc;
-	}
-	vx6953_ctrl->edof_mode = VX6953_EDOF_APPLICATION;
-	if (vx6953_enable_edof(vx6953_ctrl->edof_mode) < 0)
-		return rc;
-	vx6953_ctrl->curr_res = vx6953_ctrl->pict_res;
-	vx6953_ctrl->sensormode = mode;
-	return rc;
-} /*end of vx6953_raw_snapshot_config*/
-static int32_t vx6953_set_sensor_mode(int mode,
-	int res)
-{
-	int32_t rc = 0;
-	switch (mode) {
-	case SENSOR_PREVIEW_MODE:
-		rc = vx6953_video_config(mode);
-		break;
-	case SENSOR_SNAPSHOT_MODE:
-		rc = vx6953_snapshot_config(mode);
-		break;
-	case SENSOR_RAW_SNAPSHOT_MODE:
-		rc = vx6953_raw_snapshot_config(mode);
-		break;
-	default:
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
-static int32_t vx6953_power_down(void)
-{
-	vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
-	MODE_SELECT_STANDBY_MODE);
-	return 0;
-}
-
-
-static int vx6953_probe_init_done(const struct msm_camera_sensor_info *data)
-{
-	gpio_free(data->sensor_reset);
-	kfree(vx6953_ctrl);
-	vx6953_ctrl = NULL;
-	return 0;
-}
-static int vx6953_probe_init_sensor(const struct msm_camera_sensor_info *data)
-{
-	unsigned short revision_number;
-	int32_t rc = 0;
-	unsigned short chipidl, chipidh;
-	CDBG("%s: %d\n", __func__, __LINE__);
-	rc = gpio_request(data->sensor_reset, "vx6953");
-	CDBG(" vx6953_probe_init_sensor\n");
-	if (!rc) {
-		CDBG("sensor_reset = %d\n", rc);
-		CDBG(" vx6953_probe_init_sensor 1\n");
-		gpio_direction_output(data->sensor_reset, 0);
-		msleep(50);
-		CDBG(" vx6953_probe_init_sensor 1\n");
-		gpio_direction_output(data->sensor_reset, 1);
-		msleep(13);
-	} else {
-		CDBG(" vx6953_probe_init_sensor 2\n");
-		goto init_probe_done;
-	}
-	msleep(20);
-	CDBG(" vx6953_probe_init_sensor is called\n");
-	/* 3. Read sensor Model ID: */
-	rc = vx6953_i2c_read(0x0000, &chipidh, 1);
-	if (rc < 0) {
-		CDBG(" vx6953_probe_init_sensor 3\n");
-		goto init_probe_fail;
-	}
-	rc = vx6953_i2c_read(0x0001, &chipidl, 1);
-	if (rc < 0) {
-		CDBG(" vx6953_probe_init_sensor4\n");
-		goto init_probe_fail;
-	}
-	CDBG("vx6953 model_id = 0x%x  0x%x\n", chipidh, chipidl);
-	/* 4. Compare sensor ID to VX6953 ID: */
-	if (chipidh != 0x03 || chipidl != 0xB9) {
-		rc = -ENODEV;
-		CDBG("vx6953_probe_init_sensor fail chip id doesnot match\n");
-		goto init_probe_fail;
-	}
-
-	vx6953_ctrl = kzalloc(sizeof(struct vx6953_ctrl_t), GFP_KERNEL);
-	if (!vx6953_ctrl) {
-		CDBG("vx6953_init failed!\n");
-		rc = -ENOMEM;
-	}
-	vx6953_ctrl->fps_divider = 1 * 0x00000400;
-	vx6953_ctrl->pict_fps_divider = 1 * 0x00000400;
-	vx6953_ctrl->set_test = TEST_OFF;
-	vx6953_ctrl->prev_res = QTR_SIZE;
-	vx6953_ctrl->pict_res = FULL_SIZE;
-	vx6953_ctrl->curr_res = INVALID_SIZE;
-	vx6953_ctrl->sensor_type = VX6953_STM5M0EDOF_CUT_2;
-	vx6953_ctrl->edof_mode = VX6953_EDOF_ESTIMATION;
-
-	if (data)
-		vx6953_ctrl->sensordata = data;
-
-	if (vx6953_i2c_read(0x0002, &revision_number, 1) < 0)
-		return rc;
-		CDBG("sensor revision number major = 0x%x\n", revision_number);
-	if (vx6953_i2c_read(0x0018, &revision_number, 1) < 0)
-		return rc;
-		CDBG("sensor revision number = 0x%x\n", revision_number);
-	if (revision_number == VX6953_REVISION_NUMBER_CUT3) {
-		vx6953_ctrl->sensor_type = VX6953_STM5M0EDOF_CUT_3;
-		CDBG("VX6953 EDof Cut 3.0 sensor\n ");
-	} else if (revision_number == VX6953_REVISION_NUMBER_CUT2) {
-		vx6953_ctrl->sensor_type = VX6953_STM5M0EDOF_CUT_2;
-		CDBG("VX6953 EDof Cut 2.0 sensor\n ");
-	} else {/* Cut1.0 reads 0x00 for register 0x0018*/
-		vx6953_ctrl->sensor_type = VX6953_STM5M0EDOF_CUT_1;
-		CDBG("VX6953 EDof Cut 1.0 sensor\n ");
-	}
-
-	if (vx6953_ctrl->prev_res == QTR_SIZE) {
-		if (vx6953_sensor_setting(REG_INIT, RES_PREVIEW) < 0)
-			goto init_probe_fail;
-	} else {
-		if (vx6953_sensor_setting(REG_INIT, RES_CAPTURE) < 0)
-			goto init_probe_fail;
-	}
-
-	goto init_probe_done;
-init_probe_fail:
-	CDBG(" vx6953_probe_init_sensor fails\n");
-	gpio_direction_output(data->sensor_reset, 0);
-	vx6953_probe_init_done(data);
-init_probe_done:
-	CDBG(" vx6953_probe_init_sensor finishes\n");
-	return rc;
-	}
-/* camsensor_iu060f_vx6953_reset */
-int vx6953_sensor_open_init(const struct msm_camera_sensor_info *data)
-{
-	unsigned short revision_number;
-	int32_t rc = 0;
-
-	CDBG("%s: %d\n", __func__, __LINE__);
-	CDBG("Calling vx6953_sensor_open_init\n");
-	rc = gpio_request(data->sensor_reset, "vx6953");
-	if (!rc)
-		CDBG("vx6953 gpio_request fail\n");
-
-	vx6953_ctrl = kzalloc(sizeof(struct vx6953_ctrl_t), GFP_KERNEL);
-	if (!vx6953_ctrl) {
-		CDBG("vx6953_init failed!\n");
-		rc = -ENOMEM;
-		goto init_done;
-	}
-	vx6953_ctrl->fps_divider = 1 * 0x00000400;
-	vx6953_ctrl->pict_fps_divider = 1 * 0x00000400;
-	vx6953_ctrl->set_test = TEST_OFF;
-	vx6953_ctrl->prev_res = QTR_SIZE;
-	vx6953_ctrl->pict_res = FULL_SIZE;
-	vx6953_ctrl->curr_res = INVALID_SIZE;
-	vx6953_ctrl->sensor_type = VX6953_STM5M0EDOF_CUT_2;
-	vx6953_ctrl->edof_mode = VX6953_EDOF_ESTIMATION;
-	if (data)
-		vx6953_ctrl->sensordata = data;
-	if (rc < 0) {
-		CDBG("Calling vx6953_sensor_open_init fail1\n");
-		return rc;
-	}
-	CDBG("%s: %d\n", __func__, __LINE__);
-	/* enable mclk first */
-	msm_camio_clk_rate_set(VX6953_STM5M0EDOF_DEFAULT_MASTER_CLK_RATE);
-	CDBG("%s: %d\n", __func__, __LINE__);
-	if (vx6953_i2c_read(0x0002, &revision_number, 1) < 0)
-		return rc;
-		CDBG("sensor revision number major = 0x%x\n", revision_number);
-	if (vx6953_i2c_read(0x0018, &revision_number, 1) < 0)
-		return rc;
-		CDBG("sensor revision number = 0x%x\n", revision_number);
-	if (revision_number == VX6953_REVISION_NUMBER_CUT3) {
-		vx6953_ctrl->sensor_type = VX6953_STM5M0EDOF_CUT_3;
-		CDBG("VX6953 EDof Cut 3.0 sensor\n ");
-	} else if (revision_number == VX6953_REVISION_NUMBER_CUT2) {
-		vx6953_ctrl->sensor_type = VX6953_STM5M0EDOF_CUT_2;
-		CDBG("VX6953 EDof Cut 2.0 sensor\n ");
-	} else {/* Cut1.0 reads 0x00 for register 0x0018*/
-		vx6953_ctrl->sensor_type = VX6953_STM5M0EDOF_CUT_1;
-		CDBG("VX6953 EDof Cut 1.0 sensor\n ");
-	}
-
-	vx6953_ctrl->fps = 30*Q8;
-	if (rc < 0)
-		goto init_fail;
-	else
-		goto init_done;
-init_fail:
-	CDBG("init_fail\n");
-	gpio_direction_output(data->sensor_reset, 0);
-	vx6953_probe_init_done(data);
-init_done:
-	CDBG("init_done\n");
-	return rc;
-} /*endof vx6953_sensor_open_init*/
-
-static int vx6953_init_client(struct i2c_client *client)
-{
-	/* Initialize the MSM_CAMI2C Chip */
-	init_waitqueue_head(&vx6953_wait_queue);
-	return 0;
-}
-
-static const struct i2c_device_id vx6953_i2c_id[] = {
-	{"vx6953", 0},
-	{ }
-};
-
-static int vx6953_i2c_probe(struct i2c_client *client,
-	const struct i2c_device_id *id)
-{
-	int rc = 0;
-	CDBG("vx6953_probe called!\n");
-
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		CDBG("i2c_check_functionality failed\n");
-		goto probe_failure;
-	}
-
-	vx6953_sensorw = kzalloc(sizeof(struct vx6953_work_t), GFP_KERNEL);
-	if (!vx6953_sensorw) {
-		CDBG("kzalloc failed.\n");
-		rc = -ENOMEM;
-		goto probe_failure;
-	}
-
-	i2c_set_clientdata(client, vx6953_sensorw);
-	vx6953_init_client(client);
-	vx6953_client = client;
-
-	msleep(50);
-
-	CDBG("vx6953_probe successed! rc = %d\n", rc);
-	return 0;
-
-probe_failure:
-	CDBG("vx6953_probe failed! rc = %d\n", rc);
-	return rc;
-}
-
-static int vx6953_send_wb_info(struct wb_info_cfg *wb)
-{
-	unsigned short read_data;
-	uint8_t temp[8];
-	int rc = 0;
-	int i = 0;
-
-	/* red_gain */
-	temp[2] = wb->red_gain >> 8;
-	temp[3] = wb->red_gain & 0xFF;
-
-	/* green_gain */
-	temp[0] = wb->green_gain >> 8;
-	temp[1] = wb->green_gain & 0xFF;
-	temp[6] = temp[0];
-	temp[7] = temp[1];
-
-	/* blue_gain */
-	temp[4] = wb->blue_gain >> 8;
-	temp[5] = wb->blue_gain & 0xFF;
-	rc = vx6953_i2c_write_seq_sensor(0x0B8E, &temp[0], 8);
-
-	for (i = 0; i < 6; i++) {
-		rc = vx6953_i2c_read(0x0B8E + i, &read_data, 1);
-		CDBG("%s addr 0x%x val %d\n", __func__, 0x0B8E + i, read_data);
-	}
-	rc = vx6953_i2c_read(0x0B82, &read_data, 1);
-	CDBG("%s addr 0x%x val %d\n", __func__, 0x0B82, read_data);
-	if (rc < 0)
-		return rc;
-	return rc;
-} /*end of vx6953_snapshot_config*/
-
-static int __exit vx6953_remove(struct i2c_client *client)
-{
-	struct vx6953_work_t_t *sensorw = i2c_get_clientdata(client);
-	free_irq(client->irq, sensorw);
-	vx6953_client = NULL;
-	kfree(sensorw);
-	return 0;
-}
-
-static struct i2c_driver vx6953_i2c_driver = {
-	.id_table = vx6953_i2c_id,
-	.probe  = vx6953_i2c_probe,
-	.remove = __exit_p(vx6953_i2c_remove),
-	.driver = {
-		.name = "vx6953",
-	},
-};
-
-static int vx6953_sensor_config(void __user *argp)
-{
-	struct sensor_cfg_data cdata;
-	long   rc = 0;
-	if (copy_from_user(&cdata,
-		(void *)argp,
-		sizeof(struct sensor_cfg_data)))
-		return -EFAULT;
-	mutex_lock(&vx6953_mut);
-	CDBG("vx6953_sensor_config: cfgtype = %d\n",
-	cdata.cfgtype);
-		switch (cdata.cfgtype) {
-		case CFG_GET_PICT_FPS:
-			vx6953_get_pict_fps(
-				cdata.cfg.gfps.prevfps,
-				&(cdata.cfg.gfps.pictfps));
-
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_GET_PREV_L_PF:
-			cdata.cfg.prevl_pf =
-			vx6953_get_prev_lines_pf();
-
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_GET_PREV_P_PL:
-			cdata.cfg.prevp_pl =
-				vx6953_get_prev_pixels_pl();
-
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_GET_PICT_L_PF:
-			cdata.cfg.pictl_pf =
-				vx6953_get_pict_lines_pf();
-
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_GET_PICT_P_PL:
-			cdata.cfg.pictp_pl =
-				vx6953_get_pict_pixels_pl();
-
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_GET_PICT_MAX_EXP_LC:
-			cdata.cfg.pict_max_exp_lc =
-				vx6953_get_pict_max_exp_lc();
-
-			if (copy_to_user((void *)argp,
-				&cdata,
-				sizeof(struct sensor_cfg_data)))
-				rc = -EFAULT;
-			break;
-
-		case CFG_SET_FPS:
-		case CFG_SET_PICT_FPS:
-			rc = vx6953_set_fps(&(cdata.cfg.fps));
-			break;
-
-		case CFG_SET_EXP_GAIN:
-			rc =
-				vx6953_write_exp_gain(
-					cdata.cfg.exp_gain.gain,
-					cdata.cfg.exp_gain.line);
-			break;
-
-		case CFG_SET_PICT_EXP_GAIN:
-			rc =
-				vx6953_set_pict_exp_gain(
-				cdata.cfg.exp_gain.gain,
-				cdata.cfg.exp_gain.line);
-			break;
-
-		case CFG_SET_MODE:
-			rc = vx6953_set_sensor_mode(cdata.mode,
-					cdata.rs);
-			break;
-
-		case CFG_PWR_DOWN:
-			rc = vx6953_power_down();
-			break;
-
-		case CFG_MOVE_FOCUS:
-			rc =
-				vx6953_move_focus(
-				cdata.cfg.focus.dir,
-				cdata.cfg.focus.steps);
-			break;
-
-		case CFG_SET_DEFAULT_FOCUS:
-			rc =
-				vx6953_set_default_focus(
-				cdata.cfg.focus.steps);
-			break;
-
-		case CFG_SET_EFFECT:
-			rc = vx6953_set_default_focus(
-				cdata.cfg.effect);
-			break;
-
-
-		case CFG_SEND_WB_INFO:
-			rc = vx6953_send_wb_info(
-				&(cdata.cfg.wb_info));
-			break;
-
-		default:
-			rc = -EFAULT;
-			break;
-		}
-
-	mutex_unlock(&vx6953_mut);
-
-	return rc;
-}
-
-
-
-
-static int vx6953_sensor_release(void)
-{
-	int rc = -EBADF;
-	mutex_lock(&vx6953_mut);
-	vx6953_power_down();
-	gpio_free(vx6953_ctrl->sensordata->sensor_reset);
-	kfree(vx6953_ctrl);
-	vx6953_ctrl = NULL;
-	CDBG("vx6953_release completed\n");
-	mutex_unlock(&vx6953_mut);
-
-	return rc;
-}
-
-static int vx6953_g_chip_ident(struct v4l2_subdev *sd,
-			struct v4l2_dbg_chip_ident *id)
-{
-	/* TODO: Need to add this ID in v4l2-chip-ident.h */
-	id->ident    = V4L2_IDENT_VX6953;
-	id->revision = 0;
-
-	return 0;
-}
-
-static int vx6953_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *param)
-{
-	int ret = 0;
-	/* return current mode value */
-	param->parm.capture.capturemode = vx6953_ctrl->sensormode;
-	return ret;
-}
-
-static int vx6953_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *param)
-{
-	/* set the desired mode */
-	/* right now, the only purpose is to set the desired mode -
-	 preview or snapshot */
-	vx6953_ctrl->sensormode = param->parm.capture.capturemode;
-	return 0;
-}
-
-static int vx6953_s_stream(struct v4l2_subdev *sd, int enable)
-{
-	long rc = 0;
-	int mode = vx6953_ctrl->sensormode;
-	int rt = RES_PREVIEW;
-	unsigned short frame_cnt;
-	struct msm_camera_csi_params vx6953_csi_params;
-
-	CDBG("mode = %d, enable = %d\n", mode, enable);
-
-	if (!enable) {
-		/* turn off streaming */
-		/* TODO: Make call to I2C write to turn streaming off */
-		/* rc = vx6953_i2c_write_b_sensor(); */
-
-		struct vx6953_i2c_reg_conf init_tbl[] = {
-			{REG_0x0112,
-			vx6953_regs.reg_pat_init[0].reg_0x0112},
-			{0x6003, 0x01},
-			{REG_0x0113,
-			vx6953_regs.reg_pat_init[0].reg_0x0113},
-			{REG_VT_PIX_CLK_DIV,
-			vx6953_regs.reg_pat_init[0].
-			vt_pix_clk_div},
-			{REG_PRE_PLL_CLK_DIV,
-			vx6953_regs.reg_pat_init[0].
-			pre_pll_clk_div},
-			{REG_PLL_MULTIPLIER,
-			vx6953_regs.reg_pat_init[0].
-			pll_multiplier},
-			{REG_OP_PIX_CLK_DIV,
-			vx6953_regs.reg_pat_init[0].
-			op_pix_clk_div},
-			{REG_COARSE_INTEGRATION_TIME_HI,
-			vx6953_regs.reg_pat[rt].
-			coarse_integration_time_hi},
-			{REG_COARSE_INTEGRATION_TIME_LO,
-			vx6953_regs.reg_pat[rt].
-			coarse_integration_time_lo},
-			{REG_ANALOGUE_GAIN_CODE_GLOBAL_LO,
-			vx6953_regs.reg_pat[rt].
-			analogue_gain_code_global},
-			{REG_0x3030,
-			vx6953_regs.reg_pat_init[0].reg_0x3030},
-			/* 953 specific registers */
-			{REG_0x0111,
-			vx6953_regs.reg_pat_init[0].reg_0x0111},
-			{REG_0x0b00,
-			vx6953_regs.reg_pat_init[0].reg_0x0b00},
-			{REG_0x3001,
-			vx6953_regs.reg_pat_init[0].reg_0x3001},
-			{REG_0x3004,
-			vx6953_regs.reg_pat_init[0].reg_0x3004},
-			{0x3006, 0x00},
-			{REG_0x3007,
-			vx6953_regs.reg_pat_init[0].reg_0x3007},
-			{0x301b, 0x29},
-			/* DEFCOR settings */
-			/*Single Defect Correction Weight DISABLE*/
-			{0x0b06,
-			vx6953_regs.reg_pat_init[0].reg_0x0b06},
-			/*Single_defect_correct_weight = auto*/
-			{0x0b07,
-			vx6953_regs.reg_pat_init[0].reg_0x0b07},
-			/*Dynamic couplet correction ENABLED*/
-			{0x0b08,
-			vx6953_regs.reg_pat_init[0].reg_0x0b08},
-			/*Dynamic couplet correction weight*/
-			{0x0b09,
-			vx6953_regs.reg_pat_init[0].reg_0x0b09},
-			/* Clock Setup */
-			/* Tell sensor ext clk is 24MHz*/
-			{REG_0x0136,
-			vx6953_regs.reg_pat_init[0].reg_0x0136},
-			{REG_0x0137,
-			vx6953_regs.reg_pat_init[0].reg_0x0137},
-			/* The white balance gains must be written
-			 to the sensor every frame. */
-			/* Edof */
-			{REG_0x0b83,
-			vx6953_regs.reg_pat_init[0].reg_0x0b83},
-			{REG_0x0b84,
-			vx6953_regs.reg_pat_init[0].reg_0x0b84},
-			{REG_0x0b85,
-			vx6953_regs.reg_pat_init[0].reg_0x0b85},
-			{REG_0x0b88,
-			vx6953_regs.reg_pat_init[0].reg_0x0b88},
-			{REG_0x0b89,
-			vx6953_regs.reg_pat_init[0].reg_0x0b89},
-			{REG_0x0b8a,
-			vx6953_regs.reg_pat_init[0].reg_0x0b8a},
-			/* Mode specific regieters */
-			{REG_FRAME_LENGTH_LINES_HI,
-			vx6953_regs.reg_pat[rt].
-			frame_length_lines_hi},
-			{REG_FRAME_LENGTH_LINES_LO,
-			vx6953_regs.reg_pat[rt].
-			frame_length_lines_lo},
-			{REG_LINE_LENGTH_PCK_HI,
-			vx6953_regs.reg_pat[rt].
-			line_length_pck_hi},
-			{REG_LINE_LENGTH_PCK_LO,
-			vx6953_regs.reg_pat[rt].
-			line_length_pck_lo},
-			{REG_0x3005,
-			vx6953_regs.reg_pat[rt].reg_0x3005},
-			{0x3010,
-			vx6953_regs.reg_pat[rt].reg_0x3010},
-			{REG_0x3011,
-			vx6953_regs.reg_pat[rt].reg_0x3011},
-			{REG_0x301a,
-			vx6953_regs.reg_pat[rt].reg_0x301a},
-			{REG_0x3035,
-			vx6953_regs.reg_pat[rt].reg_0x3035},
-			{REG_0x3036,
-			vx6953_regs.reg_pat[rt].reg_0x3036},
-			{REG_0x3041,
-			vx6953_regs.reg_pat[rt].reg_0x3041},
-			{0x3042,
-			vx6953_regs.reg_pat[rt].reg_0x3042},
-			{REG_0x3045,
-			vx6953_regs.reg_pat[rt].reg_0x3045},
-			/*EDOF: Estimation settings for Preview mode
-			  Application settings for capture mode
-			  (standard settings - Not tuned) */
-			{REG_0x0b80,
-			vx6953_regs.reg_pat[rt].reg_0x0b80},
-			{REG_0x0900,
-			vx6953_regs.reg_pat[rt].reg_0x0900},
-			{REG_0x0901,
-			vx6953_regs.reg_pat[rt].reg_0x0901},
-			{REG_0x0902,
-			vx6953_regs.reg_pat[rt].reg_0x0902},
-			{REG_0x0383,
-			vx6953_regs.reg_pat[rt].reg_0x0383},
-			{REG_0x0387,
-			vx6953_regs.reg_pat[rt].reg_0x0387},
-			/* Change output size / frame rate */
-			{REG_0x034c,
-			vx6953_regs.reg_pat[rt].reg_0x034c},
-			{REG_0x034d,
-			vx6953_regs.reg_pat[rt].reg_0x034d},
-			{REG_0x034e,
-			vx6953_regs.reg_pat[rt].reg_0x034e},
-			{REG_0x034f,
-			vx6953_regs.reg_pat[rt].reg_0x034f},
-		};
-		/* reset fps_divider */
-		vx6953_ctrl->fps = 30 * Q8;
-		/* stop streaming */
-
-		/* Reset everything first */
-		if (vx6953_i2c_write_b_sensor(0x103, 0x01) < 0) {
-			CDBG("S/W reset failed\n");
-			return rc;
-		} else
-			CDBG("S/W reset successful\n");
-
-		msleep(10);
-
-		CDBG("Init vx6953_sensor_setting standby\n");
-		if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
-				    MODE_SELECT_STANDBY_MODE) < 0)
-			return rc;
-
-		/*vx6953_stm5m0edof_delay_msecs_stdby*/
-		msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-
-		vx6953_csi_params.data_format = CSI_8BIT;
-		vx6953_csi_params.lane_cnt = 1;
-		vx6953_csi_params.lane_assign = 0xe4;
-		vx6953_csi_params.dpcm_scheme = 0;
-		vx6953_csi_params.settle_cnt = 7;
-		rc = msm_camio_csi_config(&vx6953_csi_params);
-		if (rc < 0)
-			CDBG(" config csi controller failed\n");
-		msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-
-		vx6953_patch_for_cut3();
-		rc = vx6953_i2c_write_w_table(&init_tbl[0],
-					    ARRAY_SIZE(init_tbl));
-		if (rc < 0)
-			return rc;
-
-		msleep(vx6953_stm5m0edof_delay_msecs_stdby);
-
-		vx6953_i2c_write_b_sensor(0x0b80, 0x00);
-		vx6953_i2c_write_b_sensor(0x3388, 0x03);
-		vx6953_i2c_write_b_sensor(0x3640, 0x00);
-		return rc;
-	} else {
-		/* Start sensor streaming */
-		if (vx6953_i2c_write_b_sensor(REG_MODE_SELECT,
-					    MODE_SELECT_STREAM) < 0)
-			return rc;
-		CDBG("Init vx6953_sensor_setting stream\n");
-		msleep(vx6953_stm5m0edof_delay_msecs_stream);
-		if (vx6953_i2c_read(0x0005, &frame_cnt, 1) < 0)
-			return rc;
-
-		rc = vx6953_i2c_write_w_table(&edof_tbl[0],
-					    ARRAY_SIZE(edof_tbl));
-		vx6953_i2c_write_b_sensor(0x3388, 0x00);
-
-		while (frame_cnt == 0xFF) {
-			if (vx6953_i2c_read(0x0005, &frame_cnt, 1) < 0)
-				return rc;
-			CDBG("frame_cnt=%d", frame_cnt);
-			msleep(10);
-		}
-
-		/* set desired mode */
-		switch (mode) {
-		case SENSOR_PREVIEW_MODE:
-			CDBG("SENSOR_PREVIEW_MODE\n");
-			rc = vx6953_video_config(mode);
-			break;
-		case SENSOR_SNAPSHOT_MODE:
-			CDBG("SENSOR_SNAPSHOT_MODE\n");
-			rc = vx6953_snapshot_config(mode);
-			break;
-		case SENSOR_RAW_SNAPSHOT_MODE:
-			CDBG("SENSOR_RAW_SNAPSHOT_MODE\n");
-			rc = vx6953_raw_snapshot_config(mode);
-			break;
-		default:
-			CDBG("default\n");
-			return -EINVAL;
-		}
-	}
-
-	return 0;
-}
-
-static void vx6953_frame_check(u32 *width, u32 *height)
-{
-	/* get mode first */
-	int mode = vx6953_ctrl->sensormode;
-
-	switch (mode) {
-	case SENSOR_PREVIEW_MODE:
-		if (*width > VX6953_QTR_SIZE_WIDTH)
-			*width = VX6953_QTR_SIZE_WIDTH;
-
-		if (*height > VX6953_QTR_SIZE_HEIGHT)
-			*height = VX6953_QTR_SIZE_HEIGHT;
-		break;
-	case SENSOR_SNAPSHOT_MODE:
-	case SENSOR_RAW_SNAPSHOT_MODE:
-		if (*width > VX6953_HRZ_FULL_BLK_PIXELS)
-			*width = VX6953_HRZ_FULL_BLK_PIXELS;
-
-		if (*height > VX6953_VER_FULL_BLK_LINES)
-			*height = VX6953_VER_FULL_BLK_LINES;
-		break;
-	default:
-		break;
-	}
-}
-
-
-static int vx6953_set_params(struct i2c_client *client, u32 width, u32 height,
-			     enum v4l2_mbus_pixelcode code)
-{
-	int i;
-	vx6953_ctrl->fmt = NULL;
-
-	/*
-	 * frame size check
-	 */
-	vx6953_frame_check(&width, &height);
-
-	/*
-	 * get color format
-	 */
-	for (i = 0; i < ARRAY_SIZE(vx6953_cfmts); i++)
-		if (vx6953_cfmts[i].code == code)
-			break;
-	if (i == ARRAY_SIZE(vx6953_cfmts))
-		return -EINVAL;
-
-	/* sensor supports one fixed size depending upon the mode */
-	switch (vx6953_ctrl->sensormode) {
-	case SENSOR_PREVIEW_MODE:
-		vx6953_video_config(vx6953_ctrl->sensormode);
-		break;
-	case SENSOR_SNAPSHOT_MODE:
-		vx6953_snapshot_config(vx6953_ctrl->sensormode);
-		break;
-	case SENSOR_RAW_SNAPSHOT_MODE:
-		vx6953_raw_snapshot_config(vx6953_ctrl->sensormode);
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	/* why need this ? vx6953_ctrl->fmt = &(vx6953_cfmts[i]); */
-
-	return 0;
-}
-
-static int vx6953_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
-	/* right now we are not supporting, probably vfe can take care */
-	return -EINVAL;
-}
-
-static int vx6953_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
-	return -EINVAL;
-}
-
-static int vx6953_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
-	return -EINVAL;
-}
-
-static int vx6953_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
-{
-	/* by this time vx6953_client should already be set */
-	struct i2c_client *client = vx6953_client;
-
-	/* currently sensor supports fixed dimensions only
-	 * depending upon the mode*/
-	if (!vx6953_ctrl->fmt) {
-		int ret = vx6953_set_params(client, VX6953_QTR_SIZE_WIDTH,
-						VX6953_QTR_SIZE_HEIGHT,
-						V4L2_MBUS_FMT_YUYV8_2X8);
-		if (ret < 0)
-			return ret;
-	}
-
-	mf->width = vx6953_get_pict_pixels_pl();
-	mf->height  = vx6953_get_pict_lines_pf();
-	/* TODO: set colorspace */
-	mf->code  = vx6953_ctrl->fmt->code;
-	mf->field = V4L2_FIELD_NONE;
-
-	return 0;
-}
-
-static int vx6953_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
-{
-	/* by this time vx6953_client should already be set */
-	struct i2c_client *client = vx6953_client;
-
-	/* TODO: We need to define this function */
-	/* TODO: set colorspace */
-	return vx6953_set_params(client, mf->width, mf->height, mf->code);
-}
-
-static int vx6953_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(vx6953_cfmts); i++)
-		if (mf->code == vx6953_cfmts[i].code)
-			break;
-
-	if (i == ARRAY_SIZE(vx6953_cfmts))
-		return -EINVAL;
-
-	/* check that frame is within max sensor supported frame size */
-	vx6953_frame_check(&mf->width, &mf->height);
-
-	/* TODO: set colorspace */
-	mf->field = V4L2_FIELD_NONE;
-
-	return 0;
-}
-
-static int vx6953_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
-			   enum v4l2_mbus_pixelcode *code)
-{
-	printk(KERN_DEBUG "Index is %d\n", index);
-	if ((unsigned int)index >= ARRAY_SIZE(vx6953_cfmts))
-		return -EINVAL;
-
-	*code = vx6953_cfmts[index].code;
-	return 0;
-}
-
-static struct v4l2_subdev_core_ops vx6953_subdev_core_ops = {
-	.g_chip_ident = vx6953_g_chip_ident,
-};
-
-static struct v4l2_subdev_video_ops vx6953_subdev_video_ops = {
-	.g_parm			   = vx6953_g_parm,
-	.s_parm			   = vx6953_s_parm,
-	.s_stream = vx6953_s_stream,
-	.g_mbus_fmt = vx6953_g_fmt,
-	.s_mbus_fmt = vx6953_s_fmt,
-	.try_mbus_fmt = vx6953_try_fmt,
-	.cropcap  = vx6953_cropcap,
-	.g_crop   = vx6953_g_crop,
-	.s_crop   = vx6953_s_crop,
-	.enum_mbus_fmt  = vx6953_enum_fmt,
-};
-
-static struct v4l2_subdev_ops vx6953_subdev_ops = {
-	.core = &vx6953_subdev_core_ops,
-	.video  = &vx6953_subdev_video_ops,
-};
-
-static int vx6953_sensor_probe(const struct msm_camera_sensor_info *info,
-		struct msm_sensor_ctrl *s)
-{
-	int rc = 0;
-	rc = i2c_add_driver(&vx6953_i2c_driver);
-	if (rc < 0 || vx6953_client == NULL) {
-		rc = -ENOTSUPP;
-		goto probe_fail;
-	}
-	msm_camio_clk_rate_set(24000000);
-	rc = vx6953_probe_init_sensor(info);
-	if (rc < 0)
-		goto probe_fail;
-	s->s_init = vx6953_sensor_open_init;
-	s->s_release = vx6953_sensor_release;
-	s->s_config  = vx6953_sensor_config;
-	vx6953_probe_init_done(info);
-	return rc;
-
-probe_fail:
-	CDBG("vx6953_sensor_probe: SENSOR PROBE FAILS!\n");
-	return rc;
-}
-
-
-static int vx6953_sensor_probe_cb(const struct msm_camera_sensor_info *info,
-	struct v4l2_subdev *sdev, struct msm_sensor_ctrl *s)
-{
-	int rc = 0;
-	rc = vx6953_sensor_probe(info, s);
-	if (rc < 0)
-		return rc;
-
-	vx6953_ctrl = kzalloc(sizeof(struct vx6953_ctrl_t), GFP_KERNEL);
-	if (!vx6953_ctrl) {
-		CDBG("vx6953_sensor_probe failed!\n");
-		return -ENOMEM;
-	}
-
-	/* probe is successful, init a v4l2 subdevice */
-	printk(KERN_DEBUG "going into v4l2_i2c_subdev_init\n");
-	if (sdev) {
-		v4l2_i2c_subdev_init(sdev, vx6953_client,
-						&vx6953_subdev_ops);
-		vx6953_ctrl->sensor_dev = sdev;
-	}
-	return rc;
-}
-
-static int __vx6953_probe(struct platform_device *pdev)
-{
-	return msm_sensor_register(pdev, vx6953_sensor_probe_cb);
-}
-
-static struct platform_driver msm_camera_driver = {
-	.probe = __vx6953_probe,
-	.driver = {
-		.name = "msm_camera_vx6953",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init vx6953_init(void)
-{
-	return platform_driver_register(&msm_camera_driver);
-}
-
-module_init(vx6953_init);
-void vx6953_exit(void)
-{
-	i2c_del_driver(&vx6953_i2c_driver);
-}
-
-
diff --git a/drivers/media/video/msm/vx6953_v4l2.h b/drivers/media/video/msm/vx6953_v4l2.h
deleted file mode 100644
index e5428e9..0000000
--- a/drivers/media/video/msm/vx6953_v4l2.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. 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 VX6953_V4L2_H
-#define VX6953_V4L2_H
-#include <linux/types.h>
-#include <mach/board.h>
-extern struct vx6953_reg vx6953_regs;
-struct reg_struct_init {
-	uint8_t reg_0x0112;      /* 0x0112*/
-	uint8_t reg_0x0113;      /* 0x0113*/
-	uint8_t vt_pix_clk_div;  /* 0x0301*/
-	uint8_t pre_pll_clk_div; /* 0x0305*/
-	uint8_t pll_multiplier;  /* 0x0307*/
-	uint8_t op_pix_clk_div;  /* 0x0309*/
-	uint8_t reg_0x3030;      /*0x3030*/
-	uint8_t reg_0x0111;      /*0x0111*/
-	uint8_t reg_0x0b00;      /*0x0b00*/
-	uint8_t reg_0x3001;      /*0x3001*/
-	uint8_t reg_0x3004;      /*0x3004*/
-	uint8_t reg_0x3007;      /*0x3007*/
-	uint8_t reg_0x3016;      /*0x3016*/
-	uint8_t reg_0x301d;      /*0x301d*/
-	uint8_t reg_0x317e;      /*0x317E*/
-	uint8_t reg_0x317f;      /*0x317F*/
-	uint8_t reg_0x3400;      /*0x3400*/
-	uint8_t reg_0x0b06;      /*0x0b06*/
-	uint8_t reg_0x0b07;      /*0x0b07*/
-	uint8_t reg_0x0b08;      /*0x0b08*/
-	uint8_t reg_0x0b09;      /*0x0b09*/
-	uint8_t reg_0x0136;
-	uint8_t reg_0x0137;
-	/* Edof */
-	uint8_t reg_0x0b83;      /*0x0b83*/
-	uint8_t reg_0x0b84;      /*0x0b84*/
-	uint8_t reg_0x0b85;      /*0x0b85*/
-	uint8_t reg_0x0b88;      /*0x0b88*/
-	uint8_t reg_0x0b89;      /*0x0b89*/
-	uint8_t reg_0x0b8a;      /*0x0b8a*/
-	};
-struct reg_struct {
-	uint8_t coarse_integration_time_hi; /*REG_COARSE_INTEGRATION_TIME_HI*/
-	uint8_t coarse_integration_time_lo; /*REG_COARSE_INTEGRATION_TIME_LO*/
-	uint8_t analogue_gain_code_global;
-	uint8_t frame_length_lines_hi; /* 0x0340*/
-	uint8_t frame_length_lines_lo; /* 0x0341*/
-	uint8_t line_length_pck_hi;    /* 0x0342*/
-	uint8_t line_length_pck_lo;    /* 0x0343*/
-	uint8_t reg_0x3005;   /* 0x3005*/
-	uint8_t reg_0x3010;  /* 0x3010*/
-	uint8_t reg_0x3011;  /* 0x3011*/
-	uint8_t reg_0x301a;  /* 0x301a*/
-	uint8_t reg_0x3035;  /* 0x3035*/
-	uint8_t reg_0x3036;   /* 0x3036*/
-	uint8_t reg_0x3041;  /*0x3041*/
-	uint8_t reg_0x3042;  /*0x3042*/
-	uint8_t reg_0x3045;  /*0x3045*/
-	uint8_t reg_0x0b80;   /* 0x0b80*/
-	uint8_t reg_0x0900;   /*0x0900*/
-	uint8_t reg_0x0901;   /* 0x0901*/
-	uint8_t reg_0x0902;   /*0x0902*/
-	uint8_t reg_0x0383;   /*0x0383*/
-	uint8_t reg_0x0387;   /* 0x0387*/
-	uint8_t reg_0x034c;   /* 0x034c*/
-	uint8_t reg_0x034d;   /*0x034d*/
-	uint8_t reg_0x034e;   /* 0x034e*/
-	uint8_t reg_0x034f;   /* 0x034f*/
-	uint8_t reg_0x1716; /*0x1716*/
-	uint8_t reg_0x1717; /*0x1717*/
-	uint8_t reg_0x1718; /*0x1718*/
-	uint8_t reg_0x1719; /*0x1719*/
-	uint8_t reg_0x3210;/*0x3210*/
-	uint8_t reg_0x111; /*0x111*/
-	uint8_t reg_0x3410;  /*0x3410*/
-	uint8_t reg_0x3098;
-	uint8_t reg_0x309D;
-	uint8_t reg_0x0200;
-	uint8_t reg_0x0201;
-	};
-struct vx6953_i2c_reg_conf {
-	unsigned short waddr;
-	unsigned short wdata;
-};
-
-enum vx6953_test_mode_t {
-	TEST_OFF,
-	TEST_1,
-	TEST_2,
-	TEST_3
-};
-
-enum vx6953_resolution_t {
-	QTR_SIZE,
-	FULL_SIZE,
-	INVALID_SIZE
-};
-enum vx6953_setting {
-	RES_PREVIEW,
-	RES_CAPTURE
-};
-enum mt9p012_reg_update {
-	/* Sensor egisters that need to be updated during initialization */
-	REG_INIT,
-	/* Sensor egisters that needs periodic I2C writes */
-	UPDATE_PERIODIC,
-	/* All the sensor Registers will be updated */
-	UPDATE_ALL,
-	/* Not valid update */
-	UPDATE_INVALID
-};
-
-enum sensor_revision_t {
-	VX6953_STM5M0EDOF_CUT_1,
-	VX6953_STM5M0EDOF_CUT_2,
-	VX6953_STM5M0EDOF_CUT_3
-};
-enum edof_mode_t {
-	VX6953_EDOF_DISABLE,       /* 0x00 */
-	VX6953_EDOF_APPLICATION,   /* 0x01 */
-	VX6953_EDOF_ESTIMATION     /* 0x02 */
-};
-struct vx6953_reg {
-	const struct reg_struct_init  *reg_pat_init;
-	const struct reg_struct  *reg_pat;
-};
-#endif /* VX6953_H */
diff --git a/drivers/media/video/msm_vidc/Kconfig b/drivers/media/video/msm_vidc/Kconfig
deleted file mode 100644
index 6428180..0000000
--- a/drivers/media/video/msm_vidc/Kconfig
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# VIDEO CORE
-#
-
-menuconfig MSM_VIDC_V4L2
-	bool "Qualcomm MSM Video Core Driver"
-		depends on ARCH_MSM8974 && VIDEO_V4L2
-		default y
diff --git a/drivers/media/video/msm_vidc/Makefile b/drivers/media/video/msm_vidc/Makefile
deleted file mode 100644
index 2a1f40f..0000000
--- a/drivers/media/video/msm_vidc/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-obj-$(CONFIG_MSM_VIDC_V4L2) := 	msm_v4l2_vidc.o \
-				msm_vidc_common.o \
-				msm_vidc.o \
-				msm_vdec.o \
-				msm_venc.o \
-				msm_smem.o \
-				msm_vidc_debug.o \
-				vidc_hal.o \
-				vidc_hal_interrupt_handler.o \
diff --git a/drivers/media/video/msm_vidc/msm_smem.c b/drivers/media/video/msm_vidc/msm_smem.c
deleted file mode 100644
index eae18c4..0000000
--- a/drivers/media/video/msm_vidc/msm_smem.c
+++ /dev/null
@@ -1,374 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 <mach/iommu_domains.h>
-#include "msm_smem.h"
-#include "msm_vidc_debug.h"
-
-struct smem_client {
-	int mem_type;
-	void *clnt;
-};
-
-static int get_device_address(struct ion_client *clnt,
-		struct ion_handle *hndl, int domain_num, int partition_num,
-		unsigned long align, unsigned long *iova,
-		unsigned long *buffer_size, int flags)
-{
-	int rc;
-	if (!iova || !buffer_size || !hndl || !clnt) {
-		dprintk(VIDC_ERR, "Invalid params: %p, %p, %p, %p\n",
-				clnt, hndl, iova, buffer_size);
-		return -EINVAL;
-	}
-	dprintk(VIDC_DBG, "domain: %d, partition: %d\n",
-		domain_num, partition_num);
-	if (flags & SMEM_SECURE) {
-		if (flags & SMEM_INPUT)
-			rc = msm_ion_secure_buffer(clnt, hndl, 0x1, 0);
-		else
-			rc = msm_ion_secure_buffer(clnt, hndl, 0x2, 0);
-		if (rc) {
-			dprintk(VIDC_ERR, "Failed to secure memory\n");
-			goto mem_secure_failed;
-		}
-	}
-	rc = ion_map_iommu(clnt, hndl, domain_num, partition_num, align,
-			0, iova, buffer_size, 0, 0);
-	if (rc)
-		dprintk(VIDC_ERR,
-		"ion_map_iommu failed(%d).domain: %d,partition: %d\n",
-		rc, domain_num, partition_num);
-mem_secure_failed:
-	return rc;
-}
-
-static void put_device_address(struct ion_client *clnt,
-	struct ion_handle *hndl, int domain_num, int partition_num, int flags)
-{
-	ion_unmap_iommu(clnt, hndl, domain_num, partition_num);
-	if (flags & SMEM_SECURE) {
-		if (msm_ion_unsecure_buffer(clnt, hndl))
-			dprintk(VIDC_ERR, "Failed to unsecure memory\n");
-	}
-}
-
-static int ion_user_to_kernel(struct smem_client *client,
-			int fd, u32 offset, int domain, int partition,
-			struct msm_smem *mem, int flags)
-{
-	struct ion_handle *hndl;
-	unsigned long iova = 0;
-	unsigned long buffer_size = 0;
-	int rc = 0;
-	int align = SZ_4K;
-	hndl = ion_import_dma_buf(client->clnt, fd);
-	if (IS_ERR_OR_NULL(hndl)) {
-		dprintk(VIDC_ERR, "Failed to get handle: %p, %d, %d, %p\n",
-				client, fd, offset, hndl);
-		rc = -ENOMEM;
-		goto fail_import_fd;
-	}
-	mem->kvaddr = NULL;
-	mem->domain = domain;
-	mem->partition_num = partition;
-	mem->flags = flags;
-
-	if (flags & SMEM_SECURE)
-		align = ALIGN(align, SZ_1M);
-
-	rc = get_device_address(client->clnt, hndl, mem->domain,
-		mem->partition_num, align, &iova, &buffer_size, flags);
-	if (rc) {
-		dprintk(VIDC_ERR, "Failed to get device address: %d\n", rc);
-		goto fail_device_address;
-	}
-
-	mem->mem_type = client->mem_type;
-	mem->smem_priv = hndl;
-	mem->device_addr = iova;
-	mem->size = buffer_size;
-	dprintk(VIDC_DBG, "NOTE: Buffer device address: 0x%lx, size: %d\n",
-		mem->device_addr, mem->size);
-	return rc;
-fail_device_address:
-	ion_unmap_kernel(client->clnt, hndl);
-	ion_free(client->clnt, hndl);
-fail_import_fd:
-	return rc;
-}
-
-static int alloc_ion_mem(struct smem_client *client, size_t size,
-		u32 align, u32 flags, int domain, int partition,
-		struct msm_smem *mem, int map_kernel)
-{
-	struct ion_handle *hndl;
-	unsigned long iova = 0;
-	unsigned long buffer_size = 0;
-	unsigned long ionflags = 0;
-	unsigned long heap_mask = 0;
-	int rc = 0;
-	if (flags & SMEM_CACHED)
-		ionflags = ION_SET_CACHED(ionflags);
-	else
-		ionflags = ION_SET_UNCACHED(ionflags);
-
-	align = ALIGN(align, SZ_4K);
-	size = ALIGN(size, SZ_4K);
-
-	if (flags & SMEM_SECURE) {
-		ionflags |= ION_SECURE;
-		size = ALIGN(size, SZ_1M);
-		align = ALIGN(align, SZ_1M);
-	}
-
-	heap_mask = ION_HEAP(ION_CP_MM_HEAP_ID);
-	if (!(flags & SMEM_SECURE))
-		heap_mask |= ION_HEAP(ION_IOMMU_HEAP_ID);
-
-	dprintk(VIDC_DBG, "domain: %d, partition: %d\n",
-		domain, partition);
-	hndl = ion_alloc(client->clnt, size, align, heap_mask, ionflags);
-	if (IS_ERR_OR_NULL(hndl)) {
-		dprintk(VIDC_ERR,
-		"Failed to allocate shared memory = %p, %d, %d, 0x%lx\n",
-		client, size, align, ionflags);
-		rc = -ENOMEM;
-		goto fail_shared_mem_alloc;
-	}
-	mem->mem_type = client->mem_type;
-	mem->smem_priv = hndl;
-	mem->domain = domain;
-	mem->partition_num = partition;
-	mem->flags = flags;
-	if (map_kernel) {
-		mem->kvaddr = ion_map_kernel(client->clnt, hndl);
-		if (!mem->kvaddr) {
-			dprintk(VIDC_ERR,
-				"Failed to map shared mem in kernel\n");
-			rc = -EIO;
-			goto fail_map;
-		}
-	} else
-		mem->kvaddr = NULL;
-
-	rc = get_device_address(client->clnt, hndl, mem->domain,
-		mem->partition_num, align, &iova, &buffer_size, flags);
-	if (rc) {
-		dprintk(VIDC_ERR, "Failed to get device address: %d\n",
-			rc);
-		goto fail_device_address;
-	}
-	mem->device_addr = iova;
-	dprintk(VIDC_DBG,
-		"device_address = 0x%lx, kvaddr = 0x%p, size = %d\n",
-		mem->device_addr, mem->kvaddr, size);
-	mem->size = size;
-	return rc;
-fail_device_address:
-	ion_unmap_kernel(client->clnt, hndl);
-fail_map:
-	ion_free(client->clnt, hndl);
-fail_shared_mem_alloc:
-	return rc;
-}
-
-static void free_ion_mem(struct smem_client *client, struct msm_smem *mem)
-{
-	if (mem->device_addr)
-		put_device_address(client->clnt,
-			mem->smem_priv, mem->domain,
-			mem->partition_num, mem->flags);
-	if (mem->kvaddr)
-		ion_unmap_kernel(client->clnt, mem->smem_priv);
-	if (mem->smem_priv)
-		ion_free(client->clnt, mem->smem_priv);
-}
-
-static void *ion_new_client(void)
-{
-	struct ion_client *client = NULL;
-	client = msm_ion_client_create(-1, "video_client");
-	if (!client)
-		dprintk(VIDC_ERR, "Failed to create smem client\n");
-	return client;
-};
-
-static void ion_delete_client(struct smem_client *client)
-{
-	ion_client_destroy(client->clnt);
-}
-
-struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 offset,
-	int domain, int partition, int flags)
-{
-	struct smem_client *client = clt;
-	int rc = 0;
-	struct msm_smem *mem;
-	if (fd < 0) {
-		dprintk(VIDC_ERR, "Invalid fd: %d\n", fd);
-		return NULL;
-	}
-	mem = kzalloc(sizeof(*mem), GFP_KERNEL);
-	if (!mem) {
-		dprintk(VIDC_ERR, "Failed to allocte shared mem\n");
-		return NULL;
-	}
-	switch (client->mem_type) {
-	case SMEM_ION:
-		rc = ion_user_to_kernel(clt, fd, offset,
-			domain, partition, mem, flags);
-		break;
-	default:
-		dprintk(VIDC_ERR, "Mem type not supported\n");
-		rc = -EINVAL;
-		break;
-	}
-	if (rc) {
-		dprintk(VIDC_ERR, "Failed to allocate shared memory\n");
-		kfree(mem);
-		mem = NULL;
-	}
-	return mem;
-}
-
-static int ion_mem_clean_invalidate(struct smem_client *clt,
-	struct msm_smem *mem)
-{
-	/*
-	 * Note: We're always mapping into iommu as uncached
-	 * as a result we don't need to flush/clean anything
-	 */
-	return 0;
-}
-
-int msm_smem_clean_invalidate(void *clt, struct msm_smem *mem)
-{
-	struct smem_client *client = clt;
-	int rc;
-	if (!client || !mem) {
-		dprintk(VIDC_ERR, "Invalid  client/handle passed\n");
-		return -EINVAL;
-	}
-	switch (client->mem_type) {
-	case SMEM_ION:
-		rc = ion_mem_clean_invalidate(client, mem);
-		break;
-	default:
-		dprintk(VIDC_ERR, "Mem type not supported\n");
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
-
-void *msm_smem_new_client(enum smem_type mtype)
-{
-	struct smem_client *client = NULL;
-	void *clnt = NULL;
-	switch (mtype) {
-	case SMEM_ION:
-		clnt = ion_new_client();
-		break;
-	default:
-		dprintk(VIDC_ERR, "Mem type not supported\n");
-		break;
-	}
-	if (clnt) {
-		client = kzalloc(sizeof(*client), GFP_KERNEL);
-		if (client) {
-			client->mem_type = mtype;
-			client->clnt = clnt;
-		}
-	} else {
-		dprintk(VIDC_ERR, "Failed to create new client: mtype = %d\n",
-			mtype);
-	}
-	return client;
-};
-
-struct msm_smem *msm_smem_alloc(void *clt, size_t size, u32 align, u32 flags,
-		int domain, int partition, int map_kernel)
-{
-	struct smem_client *client;
-	int rc = 0;
-	struct msm_smem *mem;
-	client = clt;
-	if (!client) {
-		dprintk(VIDC_ERR, "Invalid  client passed\n");
-		return NULL;
-	}
-	if (!size) {
-		dprintk(VIDC_ERR, "No need to allocate memory of size: %d\n",
-			size);
-		return NULL;
-	}
-	mem = kzalloc(sizeof(*mem), GFP_KERNEL);
-	if (!mem) {
-		dprintk(VIDC_ERR, "Failed to allocate shared mem\n");
-		return NULL;
-	}
-	switch (client->mem_type) {
-	case SMEM_ION:
-		rc = alloc_ion_mem(client, size, align, flags,
-			domain, partition, mem, map_kernel);
-		break;
-	default:
-		dprintk(VIDC_ERR, "Mem type not supported\n");
-		rc = -EINVAL;
-		break;
-	}
-	if (rc) {
-		dprintk(VIDC_ERR, "Failed to allocate shared memory\n");
-		kfree(mem);
-		mem = NULL;
-	}
-	return mem;
-}
-
-void msm_smem_free(void *clt, struct msm_smem *mem)
-{
-	struct smem_client *client = clt;
-	if (!client || !mem) {
-		dprintk(VIDC_ERR, "Invalid  client/handle passed\n");
-		return;
-	}
-	switch (client->mem_type) {
-	case SMEM_ION:
-		free_ion_mem(client, mem);
-		break;
-	default:
-		dprintk(VIDC_ERR, "Mem type not supported\n");
-		break;
-	}
-	kfree(mem);
-};
-
-void msm_smem_delete_client(void *clt)
-{
-	struct smem_client *client = clt;
-	if (!client) {
-		dprintk(VIDC_ERR, "Invalid  client passed\n");
-		return;
-	}
-	switch (client->mem_type) {
-	case SMEM_ION:
-		ion_delete_client(client);
-		break;
-	default:
-		dprintk(VIDC_ERR, "Mem type not supported\n");
-		break;
-	}
-	kfree(client);
-}
diff --git a/drivers/media/video/msm_vidc/msm_smem.h b/drivers/media/video/msm_vidc/msm_smem.h
deleted file mode 100644
index 8241fdd..0000000
--- a/drivers/media/video/msm_vidc/msm_smem.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 _MSM_SMEM_H_
-#define _MSM_SMEM_H_
-
-#include <linux/types.h>
-#include <linux/msm_ion.h>
-
-enum smem_type {
-	SMEM_ION,
-};
-
-enum smem_prop {
-	SMEM_CACHED = 0x1,
-	SMEM_SECURE = 0x2,
-	SMEM_INPUT = 0x4,
-};
-
-struct msm_smem {
-	int mem_type;
-	size_t size;
-	void *kvaddr;
-	unsigned long device_addr;
-	int domain;
-	int partition_num;
-	int flags;
-	void *smem_priv;
-};
-
-void *msm_smem_new_client(enum smem_type mtype);
-struct msm_smem *msm_smem_alloc(void *clt, size_t size, u32 align, u32 flags,
-		int domain, int partition, int map_kernel);
-void msm_smem_free(void *clt, struct msm_smem *mem);
-void msm_smem_delete_client(void *clt);
-struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 offset, int
-		domain, int partition, int flags);
-int msm_smem_clean_invalidate(void *clt, struct msm_smem *mem);
-#endif
diff --git a/drivers/media/video/msm_vidc/msm_v4l2_vidc.c b/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
deleted file mode 100644
index 0979e99..0000000
--- a/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
+++ /dev/null
@@ -1,1491 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/types.h>
-#include <linux/list.h>
-#include <linux/ioctl.h>
-#include <linux/spinlock.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/debugfs.h>
-#include <linux/version.h>
-#include <linux/slab.h>
-#include <linux/of.h>
-#include <mach/iommu.h>
-#include <mach/iommu_domains.h>
-#include <media/msm_vidc.h>
-#include "msm_vidc_internal.h"
-#include "msm_vidc_debug.h"
-#include "vidc_hal_api.h"
-#include "msm_smem.h"
-
-#define BASE_DEVICE_NUMBER 32
-#define SHARED_QSIZE 0x1000000
-
-static struct msm_bus_vectors enc_ocmem_init_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
-		.dst = MSM_BUS_SLAVE_OCMEM,
-		.ab = 0,
-		.ib = 0,
-	},
-};
-
-static struct msm_bus_vectors enc_ocmem_perf1_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
-		.dst = MSM_BUS_SLAVE_OCMEM,
-		.ab = 138200000,
-		.ib = 1222000000,
-	},
-};
-
-static struct msm_bus_vectors enc_ocmem_perf2_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
-		.dst = MSM_BUS_SLAVE_OCMEM,
-		.ab = 414700000,
-		.ib = 1222000000,
-	},
-};
-
-static struct msm_bus_vectors enc_ocmem_perf3_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
-		.dst = MSM_BUS_SLAVE_OCMEM,
-		.ab = 940000000,
-		.ib = 2444000000U,
-	},
-};
-
-static struct msm_bus_vectors enc_ocmem_perf4_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
-		.dst = MSM_BUS_SLAVE_OCMEM,
-		.ab = 1880000000,
-		.ib = 2444000000U,
-	},
-};
-
-static struct msm_bus_vectors enc_ocmem_perf5_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
-		.dst = MSM_BUS_SLAVE_OCMEM,
-		.ab = 3008000000U,
-		.ib = 3910400000U,
-	},
-};
-
-static struct msm_bus_vectors enc_ocmem_perf6_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
-		.dst = MSM_BUS_SLAVE_OCMEM,
-		.ab = 3760000000U,
-		.ib = 4888000000ULL,
-	},
-};
-
-static struct msm_bus_vectors dec_ocmem_init_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
-		.dst = MSM_BUS_SLAVE_OCMEM,
-		.ab = 0,
-		.ib = 0,
-	},
-};
-
-static struct msm_bus_vectors dec_ocmem_perf1_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
-		.dst = MSM_BUS_SLAVE_OCMEM,
-		.ab = 176900000,
-		.ib = 1556640000,
-	},
-};
-
-static struct msm_bus_vectors dec_ocmem_perf2_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
-		.dst = MSM_BUS_SLAVE_OCMEM,
-		.ab = 456200000,
-		.ib = 1556640000,
-	},
-};
-
-static struct msm_bus_vectors dec_ocmem_perf3_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
-		.dst = MSM_BUS_SLAVE_OCMEM,
-		.ab = 864800000,
-		.ib = 1556640000,
-	},
-};
-
-static struct msm_bus_vectors dec_ocmem_perf4_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
-		.dst = MSM_BUS_SLAVE_OCMEM,
-		.ab = 1729600000,
-		.ib = 3113280000U,
-	},
-};
-
-static struct msm_bus_vectors dec_ocmem_perf5_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
-		.dst = MSM_BUS_SLAVE_OCMEM,
-		.ab = 2767360000U,
-		.ib = 4981248000ULL,
-	},
-};
-
-static struct msm_bus_vectors dec_ocmem_perf6_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
-		.dst = MSM_BUS_SLAVE_OCMEM,
-		.ab = 3459200000U,
-		.ib = 6226560000ULL,
-	},
-};
-
-static struct msm_bus_paths enc_ocmem_perf_vectors[]  = {
-	{
-		ARRAY_SIZE(enc_ocmem_init_vectors),
-		enc_ocmem_init_vectors,
-	},
-	{
-		ARRAY_SIZE(enc_ocmem_perf1_vectors),
-		enc_ocmem_perf1_vectors,
-	},
-	{
-		ARRAY_SIZE(enc_ocmem_perf2_vectors),
-		enc_ocmem_perf2_vectors,
-	},
-	{
-		ARRAY_SIZE(enc_ocmem_perf3_vectors),
-		enc_ocmem_perf3_vectors,
-	},
-	{
-		ARRAY_SIZE(enc_ocmem_perf4_vectors),
-		enc_ocmem_perf4_vectors,
-	},
-	{
-		ARRAY_SIZE(enc_ocmem_perf5_vectors),
-		enc_ocmem_perf5_vectors,
-	},
-	{
-		ARRAY_SIZE(enc_ocmem_perf6_vectors),
-		enc_ocmem_perf6_vectors,
-	},
-};
-
-static struct msm_bus_paths dec_ocmem_perf_vectors[]  = {
-	{
-		ARRAY_SIZE(dec_ocmem_init_vectors),
-		dec_ocmem_init_vectors,
-	},
-	{
-		ARRAY_SIZE(dec_ocmem_perf1_vectors),
-		dec_ocmem_perf1_vectors,
-	},
-	{
-		ARRAY_SIZE(dec_ocmem_perf2_vectors),
-		dec_ocmem_perf2_vectors,
-	},
-	{
-		ARRAY_SIZE(dec_ocmem_perf3_vectors),
-		dec_ocmem_perf3_vectors,
-	},
-	{
-		ARRAY_SIZE(dec_ocmem_perf4_vectors),
-		dec_ocmem_perf4_vectors,
-	},
-	{
-		ARRAY_SIZE(dec_ocmem_perf5_vectors),
-		dec_ocmem_perf5_vectors,
-	},
-	{
-		ARRAY_SIZE(dec_ocmem_perf6_vectors),
-		dec_ocmem_perf6_vectors,
-	},
-};
-
-
-static struct msm_bus_scale_pdata enc_ocmem_bus_data = {
-	.usecase = enc_ocmem_perf_vectors,
-	.num_usecases = ARRAY_SIZE(enc_ocmem_perf_vectors),
-	.name = "msm_vidc_enc_ocmem",
-};
-
-static struct msm_bus_scale_pdata dec_ocmem_bus_data = {
-	.usecase = dec_ocmem_perf_vectors,
-	.num_usecases = ARRAY_SIZE(dec_ocmem_perf_vectors),
-	.name = "msm_vidc_dec_ocmem",
-};
-
-static struct msm_bus_vectors enc_ddr_init_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab = 0,
-		.ib = 0,
-	},
-};
-
-
-static struct msm_bus_vectors enc_ddr_perf1_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab = 60000000,
-		.ib = 664950000,
-	},
-};
-
-static struct msm_bus_vectors enc_ddr_perf2_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab = 181000000,
-		.ib = 664950000,
-	},
-};
-
-static struct msm_bus_vectors enc_ddr_perf3_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab = 403000000,
-		.ib = 664950000,
-	},
-};
-
-static struct msm_bus_vectors enc_ddr_perf4_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab = 806000000,
-		.ib = 1329900000,
-	},
-};
-
-static struct msm_bus_vectors enc_ddr_perf5_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab = 1289600000,
-		.ib = 2127840000U,
-	},
-};
-
-static struct msm_bus_vectors enc_ddr_perf6_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab = 161200000,
-		.ib = 6400000000ULL,
-	},
-};
-
-static struct msm_bus_vectors dec_ddr_init_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab = 0,
-		.ib = 0,
-	},
-};
-
-static struct msm_bus_vectors dec_ddr_perf1_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab = 110000000,
-		.ib = 909000000,
-	},
-};
-
-static struct msm_bus_vectors dec_ddr_perf2_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab = 268000000,
-		.ib = 909000000,
-	},
-};
-
-static struct msm_bus_vectors dec_ddr_perf3_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab = 505000000,
-		.ib = 909000000,
-	},
-};
-
-static struct msm_bus_vectors dec_ddr_perf4_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab = 1010000000,
-		.ib = 1818000000,
-	},
-};
-
-static struct msm_bus_vectors dec_ddr_perf5_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab = 1616000000,
-		.ib = 2908800000U,
-	},
-};
-
-static struct msm_bus_vectors dec_ddr_perf6_vectors[]  = {
-	{
-		.src = MSM_BUS_MASTER_VIDEO_P0,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab = 2020000000U,
-		.ib = 6400000000ULL,
-	},
-};
-
-static struct msm_bus_paths enc_ddr_perf_vectors[]  = {
-	{
-		ARRAY_SIZE(enc_ddr_init_vectors),
-		enc_ddr_init_vectors,
-	},
-	{
-		ARRAY_SIZE(enc_ddr_perf1_vectors),
-		enc_ddr_perf1_vectors,
-	},
-	{
-		ARRAY_SIZE(enc_ddr_perf2_vectors),
-		enc_ddr_perf2_vectors,
-	},
-	{
-		ARRAY_SIZE(enc_ddr_perf3_vectors),
-		enc_ddr_perf3_vectors,
-	},
-	{
-		ARRAY_SIZE(enc_ddr_perf4_vectors),
-		enc_ddr_perf4_vectors,
-	},
-	{
-		ARRAY_SIZE(enc_ddr_perf5_vectors),
-		enc_ddr_perf5_vectors,
-	},
-	{
-		ARRAY_SIZE(enc_ddr_perf6_vectors),
-		enc_ddr_perf6_vectors,
-	},
-};
-
-static struct msm_bus_paths dec_ddr_perf_vectors[]  = {
-	{
-		ARRAY_SIZE(dec_ddr_init_vectors),
-		dec_ddr_init_vectors,
-	},
-	{
-		ARRAY_SIZE(dec_ddr_perf1_vectors),
-		dec_ddr_perf1_vectors,
-	},
-	{
-		ARRAY_SIZE(dec_ddr_perf2_vectors),
-		dec_ddr_perf2_vectors,
-	},
-	{
-		ARRAY_SIZE(dec_ddr_perf3_vectors),
-		dec_ddr_perf3_vectors,
-	},
-	{
-		ARRAY_SIZE(dec_ddr_perf4_vectors),
-		dec_ddr_perf4_vectors,
-	},
-	{
-		ARRAY_SIZE(dec_ddr_perf5_vectors),
-		dec_ddr_perf5_vectors,
-	},
-	{
-		ARRAY_SIZE(dec_ddr_perf6_vectors),
-		dec_ddr_perf6_vectors,
-	},
-};
-
-static struct msm_bus_scale_pdata enc_ddr_bus_data = {
-	.usecase = enc_ddr_perf_vectors,
-	.num_usecases = ARRAY_SIZE(enc_ddr_perf_vectors),
-	.name = "msm_vidc_enc_ddr",
-};
-
-static struct msm_bus_scale_pdata dec_ddr_bus_data = {
-	.usecase = dec_ddr_perf_vectors,
-	.num_usecases = ARRAY_SIZE(dec_ddr_perf_vectors),
-	.name = "msm_vidc_dec_ddr",
-};
-
-struct msm_vidc_drv *vidc_driver;
-
-struct buffer_info {
-	struct list_head list;
-	int type;
-	int num_planes;
-	int fd[VIDEO_MAX_PLANES];
-	int buff_off[VIDEO_MAX_PLANES];
-	int size[VIDEO_MAX_PLANES];
-	u32 uvaddr[VIDEO_MAX_PLANES];
-	u32 device_addr[VIDEO_MAX_PLANES];
-	struct msm_smem *handle[VIDEO_MAX_PLANES];
-};
-
-struct msm_v4l2_vid_inst {
-	struct msm_vidc_inst *vidc_inst;
-	void *mem_client;
-	struct list_head registered_bufs;
-};
-
-static inline struct msm_vidc_inst *get_vidc_inst(struct file *filp, void *fh)
-{
-	return container_of(filp->private_data,
-					struct msm_vidc_inst, event_handler);
-}
-
-static inline struct msm_v4l2_vid_inst *get_v4l2_inst(struct file *filp,
-			void *fh)
-{
-	struct msm_vidc_inst *vidc_inst;
-	vidc_inst = container_of(filp->private_data,
-			struct msm_vidc_inst, event_handler);
-	return (struct msm_v4l2_vid_inst *)vidc_inst->priv;
-}
-
-struct buffer_info *get_registered_buf(struct list_head *list,
-				int fd, u32 buff_off, u32 size, int *plane)
-{
-	struct buffer_info *temp;
-	struct buffer_info *ret = NULL;
-	int i;
-	if (!list || fd < 0 || !plane) {
-		dprintk(VIDC_ERR, "Invalid input\n");
-		goto err_invalid_input;
-	}
-	*plane = 0;
-	if (!list_empty(list)) {
-		list_for_each_entry(temp, list, list) {
-			for (i = 0; (i < temp->num_planes)
-				&& (i < VIDEO_MAX_PLANES); i++) {
-				if (temp && temp->fd[i] == fd &&
-						(CONTAINS(temp->buff_off[i],
-						temp->size[i], buff_off)
-						 || CONTAINS(buff_off,
-						 size, temp->buff_off[i])
-						 || OVERLAPS(buff_off, size,
-						 temp->buff_off[i],
-						 temp->size[i]))) {
-					dprintk(VIDC_DBG,
-							"This memory region is already mapped\n");
-					ret = temp;
-					*plane = i;
-					break;
-				}
-			}
-			if (ret)
-				break;
-		}
-	}
-err_invalid_input:
-	return ret;
-}
-
-struct buffer_info *get_same_fd_buffer(struct list_head *list,
-		int fd, int *plane)
-{
-	struct buffer_info *temp;
-	struct buffer_info *ret = NULL;
-	int i;
-	if (!list || fd < 0 || !plane) {
-		dprintk(VIDC_ERR, "Invalid input\n");
-		goto err_invalid_input;
-	}
-	*plane = 0;
-	if (!list_empty(list)) {
-		list_for_each_entry(temp, list, list) {
-			for (i = 0; (i < temp->num_planes)
-				&& (i < VIDEO_MAX_PLANES); i++) {
-				if (temp && temp->fd[i] == fd)  {
-					dprintk(VIDC_INFO,
-					"Found same fd buffer\n");
-					ret = temp;
-					*plane = i;
-					break;
-				}
-			}
-			if (ret)
-				break;
-		}
-	}
-err_invalid_input:
-	return ret;
-}
-static u32 device_to_uvaddr(struct list_head *list, u32 device_addr)
-{
-	struct buffer_info *temp;
-	u32 uvaddr = 0;
-	int i;
-	if (!list || !device_addr) {
-		dprintk(VIDC_ERR, "Invalid input\n");
-		goto err_invalid_input;
-	}
-	if (!list_empty(list)) {
-		list_for_each_entry(temp, list, list) {
-			for (i = 0; (i < temp->num_planes)
-				&& (i < VIDEO_MAX_PLANES); i++) {
-				if (temp && temp->device_addr[i]
-						== device_addr)  {
-					dprintk(VIDC_INFO,
-					"Found same fd buffer\n");
-					uvaddr = temp->uvaddr[i];
-					break;
-				}
-			}
-			if (uvaddr)
-				break;
-		}
-	}
-err_invalid_input:
-	return uvaddr;
-}
-
-static int msm_v4l2_open(struct file *filp)
-{
-	int rc = 0;
-	struct video_device *vdev = video_devdata(filp);
-	struct msm_video_device *vid_dev =
-		container_of(vdev, struct msm_video_device, vdev);
-	struct msm_vidc_core *core = video_drvdata(filp);
-	struct msm_v4l2_vid_inst *v4l2_inst = kzalloc(sizeof(*v4l2_inst),
-						GFP_KERNEL);
-	if (!v4l2_inst) {
-		dprintk(VIDC_ERR,
-			"Failed to allocate memory for this instance\n");
-		rc = -ENOMEM;
-		goto fail_nomem;
-	}
-	v4l2_inst->mem_client = msm_smem_new_client(SMEM_ION);
-	if (!v4l2_inst->mem_client) {
-		dprintk(VIDC_ERR, "Failed to create memory client\n");
-		rc = -ENOMEM;
-		goto fail_mem_client;
-	}
-
-	v4l2_inst->vidc_inst = msm_vidc_open(core->id, vid_dev->type);
-	if (!v4l2_inst->vidc_inst) {
-		dprintk(VIDC_ERR,
-		"Failed to create video instance, core: %d, type = %d\n",
-		core->id, vid_dev->type);
-		rc = -ENOMEM;
-		goto fail_open;
-	}
-	INIT_LIST_HEAD(&v4l2_inst->registered_bufs);
-	v4l2_inst->vidc_inst->priv = v4l2_inst;
-	clear_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags);
-	filp->private_data = &(v4l2_inst->vidc_inst->event_handler);
-	return rc;
-fail_open:
-	msm_smem_delete_client(v4l2_inst->mem_client);
-fail_mem_client:
-	kfree(v4l2_inst);
-fail_nomem:
-	return rc;
-}
-static int msm_v4l2_release_output_buffers(struct msm_v4l2_vid_inst *v4l2_inst)
-{
-	struct list_head *ptr, *next;
-	struct buffer_info *bi;
-	struct v4l2_buffer buffer_info;
-	struct v4l2_plane plane[VIDEO_MAX_PLANES];
-	int rc = 0;
-	int i;
-	list_for_each_safe(ptr, next, &v4l2_inst->registered_bufs) {
-		bi = list_entry(ptr, struct buffer_info, list);
-		if (bi->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-			buffer_info.type = bi->type;
-			for (i = 0; (i < bi->num_planes)
-				&& (i < VIDEO_MAX_PLANES); i++) {
-				plane[i].reserved[0] = bi->fd[i];
-				plane[i].reserved[1] = bi->buff_off[i];
-				plane[i].length = bi->size[i];
-				plane[i].m.userptr = bi->device_addr[i];
-				buffer_info.m.planes = plane;
-				dprintk(VIDC_DBG,
-					"Releasing buffer: %d, %d, %d\n",
-					buffer_info.m.planes[i].reserved[0],
-					buffer_info.m.planes[i].reserved[1],
-					buffer_info.m.planes[i].length);
-			}
-			buffer_info.length = bi->num_planes;
-			rc = msm_vidc_release_buf(v4l2_inst->vidc_inst,
-					&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);
-			list_del(&bi->list);
-			for (i = 0; i < bi->num_planes; i++) {
-				if (bi->handle[i])
-					msm_smem_free(v4l2_inst->mem_client,
-							bi->handle[i]);
-			}
-			kfree(bi);
-		}
-	}
-	return rc;
-}
-
-static int msm_v4l2_close(struct file *filp)
-{
-	int rc = 0;
-	struct list_head *ptr, *next;
-	struct buffer_info *bi;
-	struct msm_vidc_inst *vidc_inst;
-	struct msm_v4l2_vid_inst *v4l2_inst;
-	int i;
-	vidc_inst = get_vidc_inst(filp, NULL);
-	v4l2_inst = get_v4l2_inst(filp, NULL);
-	rc = msm_v4l2_release_output_buffers(v4l2_inst);
-	if (rc)
-		dprintk(VIDC_WARN,
-			"Failed in %s for release output buffers\n", __func__);
-	list_for_each_safe(ptr, next, &v4l2_inst->registered_bufs) {
-		bi = list_entry(ptr, struct buffer_info, list);
-		if (bi->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-			list_del(&bi->list);
-			for (i = 0; (i < bi->num_planes)
-				&& (i < VIDEO_MAX_PLANES); i++) {
-				if (bi->handle[i])
-					msm_smem_free(v4l2_inst->mem_client,
-							bi->handle[i]);
-			}
-			kfree(bi);
-		}
-	}
-	msm_smem_delete_client(v4l2_inst->mem_client);
-	rc = msm_vidc_close(vidc_inst);
-	kfree(v4l2_inst);
-	return rc;
-}
-
-static int msm_v4l2_querycap(struct file *filp, void *fh,
-			struct v4l2_capability *cap)
-{
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(filp, fh);
-	return msm_vidc_querycap((void *)vidc_inst, cap);
-}
-
-int msm_v4l2_enum_fmt(struct file *file, void *fh,
-					struct v4l2_fmtdesc *f)
-{
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
-	return msm_vidc_enum_fmt((void *)vidc_inst, f);
-}
-
-int msm_v4l2_s_fmt(struct file *file, void *fh,
-					struct v4l2_format *f)
-{
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
-	return msm_vidc_s_fmt((void *)vidc_inst, f);
-}
-
-int msm_v4l2_g_fmt(struct file *file, void *fh,
-					struct v4l2_format *f)
-{
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
-	return msm_vidc_g_fmt((void *)vidc_inst, f);
-}
-
-int msm_v4l2_s_ctrl(struct file *file, void *fh,
-					struct v4l2_control *a)
-{
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
-	return msm_vidc_s_ctrl((void *)vidc_inst, a);
-}
-
-int msm_v4l2_g_ctrl(struct file *file, void *fh,
-					struct v4l2_control *a)
-{
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
-	return msm_vidc_g_ctrl((void *)vidc_inst, a);
-}
-
-int msm_v4l2_reqbufs(struct file *file, void *fh,
-				struct v4l2_requestbuffers *b)
-{
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
-	struct msm_v4l2_vid_inst *v4l2_inst;
-	int rc = 0;
-	v4l2_inst = get_v4l2_inst(file, NULL);
-	if (b->count == 0)
-		rc = msm_v4l2_release_output_buffers(v4l2_inst);
-	if (rc)
-		dprintk(VIDC_WARN,
-			"Failed in %s for release output buffers\n", __func__);
-	return msm_vidc_reqbufs((void *)vidc_inst, b);
-}
-
-int msm_v4l2_prepare_buf(struct file *file, void *fh,
-				struct v4l2_buffer *b)
-{
-	struct msm_smem *handle = NULL;
-	struct buffer_info *binfo;
-	struct buffer_info *temp;
-	struct msm_vidc_inst *vidc_inst;
-	struct msm_v4l2_vid_inst *v4l2_inst;
-	int plane = 0;
-	int i, rc = 0;
-	int smem_flags = 0;
-	int domain;
-	vidc_inst = get_vidc_inst(file, fh);
-	v4l2_inst = get_v4l2_inst(file, fh);
-	if (!v4l2_inst->mem_client) {
-		dprintk(VIDC_ERR, "Failed to get memory client\n");
-		rc = -ENOMEM;
-		goto exit;
-	}
-	binfo = kzalloc(sizeof(*binfo), GFP_KERNEL);
-	if (!binfo) {
-		dprintk(VIDC_ERR, "Out of memory\n");
-		rc = -ENOMEM;
-		goto exit;
-	}
-	if (b->length > VIDEO_MAX_PLANES) {
-		dprintk(VIDC_ERR, "Num planes exceeds max: %d, %d\n",
-			b->length, VIDEO_MAX_PLANES);
-		rc = -EINVAL;
-		goto exit;
-	}
-	for (i = 0; i < b->length; ++i) {
-		smem_flags = 0;
-		if (EXTRADATA_IDX(b->length) &&
-			(i == EXTRADATA_IDX(b->length)) &&
-			!b->m.planes[i].length) {
-			continue;
-		}
-		temp = get_registered_buf(&v4l2_inst->registered_bufs,
-				b->m.planes[i].reserved[0],
-				b->m.planes[i].reserved[1],
-				b->m.planes[i].length, &plane);
-		if (temp) {
-			dprintk(VIDC_DBG,
-				"This memory region has already been prepared\n");
-			rc = -EINVAL;
-			kfree(binfo);
-			goto exit;
-		}
-		if ((vidc_inst->mode == VIDC_SECURE)
-				&& (!EXTRADATA_IDX(b->length)
-					|| (i != EXTRADATA_IDX(b->length)))) {
-			smem_flags |= SMEM_SECURE;
-			domain =
-			vidc_inst->core->resources.io_map[CP_MAP].domain;
-		} else
-			domain =
-			vidc_inst->core->resources.io_map[NS_MAP].domain;
-
-		if (b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
-			smem_flags |= SMEM_INPUT;
-
-		temp = get_same_fd_buffer(&v4l2_inst->registered_bufs,
-				b->m.planes[i].reserved[0], &plane);
-
-		if (temp) {
-			binfo->type = b->type;
-			binfo->fd[i] = b->m.planes[i].reserved[0];
-			binfo->buff_off[i] = b->m.planes[i].reserved[1];
-			binfo->size[i] = b->m.planes[i].length;
-			binfo->uvaddr[i] = b->m.planes[i].m.userptr;
-			binfo->device_addr[i] =
-			temp->handle[plane]->device_addr + binfo->buff_off[i];
-			binfo->handle[i] = NULL;
-		} else {
-			handle = msm_smem_user_to_kernel(v4l2_inst->mem_client,
-			b->m.planes[i].reserved[0],
-			b->m.planes[i].reserved[1],
-			domain,	0, smem_flags);
-			if (!handle) {
-				dprintk(VIDC_ERR,
-					"Failed to get device buffer address\n");
-				kfree(binfo);
-				goto exit;
-			}
-			binfo->type = b->type;
-			binfo->fd[i] = b->m.planes[i].reserved[0];
-			binfo->buff_off[i] = b->m.planes[i].reserved[1];
-			binfo->size[i] = b->m.planes[i].length;
-			binfo->uvaddr[i] = b->m.planes[i].m.userptr;
-			binfo->device_addr[i] =
-				handle->device_addr + binfo->buff_off[i];
-			binfo->handle[i] = handle;
-			dprintk(VIDC_DBG, "Registering buffer: %d, %d, %d\n",
-					b->m.planes[i].reserved[0],
-					b->m.planes[i].reserved[1],
-					b->m.planes[i].length);
-		}
-		b->m.planes[i].m.userptr = binfo->device_addr[i];
-	}
-	binfo->num_planes = b->length;
-	list_add_tail(&binfo->list, &v4l2_inst->registered_bufs);
-	rc = msm_vidc_prepare_buf(v4l2_inst->vidc_inst, b);
-exit:
-	return rc;
-}
-
-int msm_v4l2_qbuf(struct file *file, void *fh,
-				struct v4l2_buffer *b)
-{
-	struct msm_vidc_inst *vidc_inst;
-	struct msm_v4l2_vid_inst *v4l2_inst;
-	struct buffer_info *binfo;
-	int plane = 0;
-	int rc = 0;
-	int i;
-	if (b->length > VIDEO_MAX_PLANES) {
-		dprintk(VIDC_ERR, "num planes exceeds max: %d\n",
-			b->length);
-		return -EINVAL;
-	}
-	vidc_inst = get_vidc_inst(file, fh);
-	v4l2_inst = get_v4l2_inst(file, fh);
-	for (i = 0; i < b->length; ++i) {
-		if (EXTRADATA_IDX(b->length) &&
-			(i == EXTRADATA_IDX(b->length)) &&
-			!b->m.planes[i].length) {
-			b->m.planes[i].m.userptr = 0;
-			continue;
-		}
-		binfo = get_registered_buf(&v4l2_inst->registered_bufs,
-				b->m.planes[i].reserved[0],
-				b->m.planes[i].reserved[1],
-				b->m.planes[i].length, &plane);
-		if (!binfo) {
-			dprintk(VIDC_ERR,
-				"This buffer is not registered: %d, %d, %d\n",
-				b->m.planes[i].reserved[0],
-				b->m.planes[i].reserved[1],
-				b->m.planes[i].length);
-			rc = -EINVAL;
-			goto err_invalid_buff;
-		}
-		b->m.planes[i].m.userptr = binfo->device_addr[i];
-		dprintk(VIDC_DBG, "Queueing device address = 0x%x\n",
-				binfo->device_addr[i]);
-		if (binfo->handle[i]) {
-			rc = msm_smem_clean_invalidate(v4l2_inst->mem_client,
-					binfo->handle[i]);
-			if (rc) {
-				dprintk(VIDC_ERR,
-					"Failed to clean caches: %d\n", rc);
-				goto err_invalid_buff;
-			}
-		}
-	}
-	rc = msm_vidc_qbuf(v4l2_inst->vidc_inst, b);
-err_invalid_buff:
-	return rc;
-}
-
-int msm_v4l2_dqbuf(struct file *file, void *fh,
-				struct v4l2_buffer *b)
-{
-	int rc = 0;
-	int i;
-	struct msm_v4l2_vid_inst *v4l2_inst;
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
-	if (b->length > VIDEO_MAX_PLANES) {
-		dprintk(VIDC_ERR, "num planes exceed maximum: %d\n",
-			b->length);
-		return -EINVAL;
-	}
-	v4l2_inst = get_v4l2_inst(file, fh);
-	rc = msm_vidc_dqbuf((void *)vidc_inst, b);
-	if (rc) {
-		dprintk(VIDC_DBG,
-			"Failed to dqbuf, capability: %d, rc: %d\n",
-			b->type, rc);
-		goto fail_dq_buf;
-	}
-	for (i = 0; i < b->length; i++) {
-		if (EXTRADATA_IDX(b->length) &&
-				(i == EXTRADATA_IDX(b->length)) &&
-				!b->m.planes[i].m.userptr) {
-			continue;
-		}
-		b->m.planes[i].m.userptr = device_to_uvaddr(
-				&v4l2_inst->registered_bufs,
-				b->m.planes[i].m.userptr);
-		if (!b->m.planes[i].m.userptr) {
-			dprintk(VIDC_ERR,
-			"Failed to find user virtual address, 0x%lx, %d, %d\n",
-			b->m.planes[i].m.userptr, b->type, i);
-			rc = -EINVAL;
-			goto fail_dq_buf;
-		}
-	}
-fail_dq_buf:
-	return rc;
-}
-
-int msm_v4l2_streamon(struct file *file, void *fh,
-				enum v4l2_buf_type i)
-{
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
-	return msm_vidc_streamon((void *)vidc_inst, i);
-}
-
-int msm_v4l2_streamoff(struct file *file, void *fh,
-				enum v4l2_buf_type i)
-{
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
-	return msm_vidc_streamoff((void *)vidc_inst, i);
-}
-
-static int msm_v4l2_subscribe_event(struct v4l2_fh *fh,
-				struct v4l2_event_subscription *sub)
-{
-	struct msm_vidc_inst *vidc_inst = container_of(fh,
-			struct msm_vidc_inst, event_handler);
-	return msm_vidc_subscribe_event((void *)vidc_inst, sub);
-}
-
-static int msm_v4l2_unsubscribe_event(struct v4l2_fh *fh,
-				struct v4l2_event_subscription *sub)
-{
-	struct msm_vidc_inst *vidc_inst = container_of(fh,
-			struct msm_vidc_inst, event_handler);
-	return msm_vidc_unsubscribe_event((void *)vidc_inst, sub);
-}
-
-static int msm_v4l2_decoder_cmd(struct file *file, void *fh,
-				struct v4l2_decoder_cmd *dec)
-{
-	struct msm_v4l2_vid_inst *v4l2_inst;
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
-	int rc = 0;
-	v4l2_inst = get_v4l2_inst(file, NULL);
-	if (dec->cmd == V4L2_DEC_CMD_STOP)
-		rc = msm_v4l2_release_output_buffers(v4l2_inst);
-	if (rc)
-		dprintk(VIDC_WARN,
-			"Failed to release dec output buffers: %d\n", rc);
-	return msm_vidc_decoder_cmd((void *)vidc_inst, dec);
-}
-
-static int msm_v4l2_encoder_cmd(struct file *file, void *fh,
-				struct v4l2_encoder_cmd *enc)
-{
-	struct msm_v4l2_vid_inst *v4l2_inst;
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
-	int rc = 0;
-	v4l2_inst = get_v4l2_inst(file, NULL);
-	if (enc->cmd == V4L2_ENC_CMD_STOP)
-		rc = msm_v4l2_release_output_buffers(v4l2_inst);
-	if (rc)
-		dprintk(VIDC_WARN,
-			"Failed to release enc output buffers: %d\n", rc);
-	return msm_vidc_encoder_cmd((void *)vidc_inst, enc);
-}
-static int msm_v4l2_s_parm(struct file *file, void *fh,
-			struct v4l2_streamparm *a)
-{
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
-	return msm_vidc_s_parm((void *)vidc_inst, a);
-}
-static int msm_v4l2_g_parm(struct file *file, void *fh,
-		struct v4l2_streamparm *a)
-{
-	return 0;
-}
-static const struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = {
-	.vidioc_querycap = msm_v4l2_querycap,
-	.vidioc_enum_fmt_vid_cap_mplane = msm_v4l2_enum_fmt,
-	.vidioc_enum_fmt_vid_out_mplane = msm_v4l2_enum_fmt,
-	.vidioc_s_fmt_vid_cap_mplane = msm_v4l2_s_fmt,
-	.vidioc_s_fmt_vid_out_mplane = msm_v4l2_s_fmt,
-	.vidioc_g_fmt_vid_cap_mplane = msm_v4l2_g_fmt,
-	.vidioc_g_fmt_vid_out_mplane = msm_v4l2_g_fmt,
-	.vidioc_reqbufs = msm_v4l2_reqbufs,
-	.vidioc_prepare_buf = msm_v4l2_prepare_buf,
-	.vidioc_qbuf = msm_v4l2_qbuf,
-	.vidioc_dqbuf = msm_v4l2_dqbuf,
-	.vidioc_streamon = msm_v4l2_streamon,
-	.vidioc_streamoff = msm_v4l2_streamoff,
-	.vidioc_s_ctrl = msm_v4l2_s_ctrl,
-	.vidioc_g_ctrl = msm_v4l2_g_ctrl,
-	.vidioc_subscribe_event = msm_v4l2_subscribe_event,
-	.vidioc_unsubscribe_event = msm_v4l2_unsubscribe_event,
-	.vidioc_decoder_cmd = msm_v4l2_decoder_cmd,
-	.vidioc_encoder_cmd = msm_v4l2_encoder_cmd,
-	.vidioc_s_parm = msm_v4l2_s_parm,
-	.vidioc_g_parm = msm_v4l2_g_parm
-};
-
-static const struct v4l2_ioctl_ops msm_v4l2_enc_ioctl_ops = {
-};
-
-static unsigned int msm_v4l2_poll(struct file *filp,
-	struct poll_table_struct *pt)
-{
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(filp, NULL);
-	return msm_vidc_poll((void *)vidc_inst, filp, pt);
-}
-
-static const struct v4l2_file_operations msm_v4l2_vidc_fops = {
-	.owner = THIS_MODULE,
-	.open = msm_v4l2_open,
-	.release = msm_v4l2_close,
-	.ioctl = video_ioctl2,
-	.poll = msm_v4l2_poll,
-};
-
-void msm_vidc_release_video_device(struct video_device *pvdev)
-{
-}
-
-static size_t read_u32_array(struct platform_device *pdev,
-		char *name, u32 *arr, size_t size)
-{
-	int len;
-	size_t sz = 0;
-	struct device_node *np = pdev->dev.of_node;
-	if (!of_get_property(np, name, &len)) {
-		dprintk(VIDC_ERR, "Failed to read %s from device tree\n",
-			name);
-		goto fail_read;
-	}
-	sz = len / sizeof(u32);
-	if (sz <= 0) {
-		dprintk(VIDC_ERR, "%s not specified in device tree\n",
-			name);
-		goto fail_read;
-	}
-	if (sz > size) {
-		dprintk(VIDC_ERR, "Not enough memory to store %s values\n",
-			name);
-		goto fail_read;
-	}
-	if (of_property_read_u32_array(np, name, arr, sz)) {
-		dprintk(VIDC_ERR,
-			"error while reading %s from device tree\n",
-			name);
-		goto fail_read;
-	}
-	return sz;
-fail_read:
-	sz = 0;
-	return sz;
-}
-
-static int register_iommu_domains(struct platform_device *pdev,
-	struct msm_vidc_core *core)
-{
-	size_t len;
-	struct msm_iova_partition partition[2];
-	struct msm_iova_layout layout;
-	int rc = 0;
-	int i;
-	struct msm_vidc_iommu_info *io_map = core->resources.io_map;
-	strlcpy(io_map[CP_MAP].name, "vidc-cp-map",
-			sizeof(io_map[CP_MAP].name));
-	strlcpy(io_map[CP_MAP].ctx, "venus_cp",
-			sizeof(io_map[CP_MAP].ctx));
-	strlcpy(io_map[NS_MAP].name, "vidc-ns-map",
-			sizeof(io_map[NS_MAP].name));
-	strlcpy(io_map[NS_MAP].ctx, "venus_ns",
-			sizeof(io_map[NS_MAP].ctx));
-
-	for (i = 0; i < MAX_MAP; i++) {
-		len = read_u32_array(pdev, io_map[i].name,
-				io_map[i].addr_range,
-				(sizeof(io_map[i].addr_range)/sizeof(u32)));
-		if (!len) {
-			dprintk(VIDC_ERR,
-				"Error in reading cp address range\n");
-			rc = -EINVAL;
-			break;
-		}
-		partition[0].start = io_map[i].addr_range[0];
-		if (i == NS_MAP) {
-			partition[0].size =
-				io_map[i].addr_range[1] - SHARED_QSIZE;
-			partition[1].start =
-				partition[0].start + io_map[i].addr_range[1]
-					- SHARED_QSIZE;
-			partition[1].size = SHARED_QSIZE;
-			layout.npartitions = 2;
-			layout.is_secure = 0;
-		} else {
-			partition[0].size = io_map[i].addr_range[1];
-			layout.npartitions = 1;
-			layout.is_secure = 1;
-		}
-		layout.partitions = &partition[0];
-		layout.client_name = io_map[i].name;
-		layout.domain_flags = 0;
-		dprintk(VIDC_DBG, "Registering domain 1 with: %lx, %lx, %s\n",
-			partition[0].start, partition[0].size,
-			layout.client_name);
-		dprintk(VIDC_DBG, "Registering domain 2 with: %lx, %lx, %s\n",
-			partition[1].start, partition[1].size,
-			layout.client_name);
-		io_map[i].domain = msm_register_domain(&layout);
-		if (io_map[i].domain < 0) {
-			dprintk(VIDC_ERR, "Failed to register cp domain\n");
-			rc = -EINVAL;
-			break;
-		}
-	}
-	/* There is no api provided as msm_unregister_domain, so
-	 * we are not able to unregister the previously
-	 * registered domains if any domain registration fails.*/
-	BUG_ON(i < MAX_MAP);
-	return rc;
-}
-
-static inline int msm_vidc_init_clocks(struct platform_device *pdev,
-		struct msm_vidc_core *core)
-{
-	struct core_clock *cl;
-	int i;
-	int rc = 0;
-	struct core_clock *clock;
-	if (!core) {
-		dprintk(VIDC_ERR, "Invalid params: %p\n", core);
-		return -EINVAL;
-	}
-	clock = core->resources.clock;
-	strlcpy(clock[VCODEC_CLK].name, "core_clk",
-		sizeof(clock[VCODEC_CLK].name));
-	strlcpy(clock[VCODEC_AHB_CLK].name, "iface_clk",
-		sizeof(clock[VCODEC_AHB_CLK].name));
-	strlcpy(clock[VCODEC_AXI_CLK].name, "bus_clk",
-		sizeof(clock[VCODEC_AXI_CLK].name));
-	strlcpy(clock[VCODEC_OCMEM_CLK].name, "mem_clk",
-		sizeof(clock[VCODEC_OCMEM_CLK].name));
-
-	clock[VCODEC_CLK].count = read_u32_array(pdev,
-		"load-freq-tbl", (u32 *)clock[VCODEC_CLK].load_freq_tbl,
-		(sizeof(clock[VCODEC_CLK].load_freq_tbl)/sizeof(u32)));
-	clock[VCODEC_CLK].count /= 2;
-	dprintk(VIDC_DBG, "count = %d\n", clock[VCODEC_CLK].count);
-	if (!clock[VCODEC_CLK].count) {
-		dprintk(VIDC_ERR, "Failed to read clock frequency\n");
-		goto fail_init_clocks;
-	}
-	for (i = 0; i <	clock[VCODEC_CLK].count; i++) {
-		dprintk(VIDC_DBG,
-				"load = %d, freq = %d\n",
-				clock[VCODEC_CLK].load_freq_tbl[i].load,
-				clock[VCODEC_CLK].load_freq_tbl[i].freq
-			  );
-	}
-
-	for (i = 0; i < VCODEC_MAX_CLKS; i++) {
-		cl = &core->resources.clock[i];
-		if (!cl->clk) {
-			cl->clk = devm_clk_get(&pdev->dev, cl->name);
-			if (IS_ERR_OR_NULL(cl->clk)) {
-				dprintk(VIDC_ERR,
-					"Failed to get clock: %s\n", cl->name);
-				rc = PTR_ERR(cl->clk);
-				break;
-			}
-		}
-	}
-
-	if (i < VCODEC_MAX_CLKS) {
-		for (--i; i >= 0; i--) {
-			cl = &core->resources.clock[i];
-			clk_put(cl->clk);
-		}
-	}
-fail_init_clocks:
-	return rc;
-}
-
-static inline void msm_vidc_deinit_clocks(struct msm_vidc_core *core)
-{
-	int i;
-	if (!core) {
-		dprintk(VIDC_ERR, "Invalid args\n");
-		return;
-	}
-	for (i = 0; i < VCODEC_MAX_CLKS; i++)
-		clk_put(core->resources.clock[i].clk);
-}
-
-static int msm_vidc_initialize_core(struct platform_device *pdev,
-				struct msm_vidc_core *core)
-{
-	struct resource *res;
-	int i = 0;
-	int rc = 0;
-	struct on_chip_mem *ocmem;
-	if (!core)
-		return -EINVAL;
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		dprintk(VIDC_ERR, "Failed to get IORESOURCE_MEM\n");
-		rc = -ENODEV;
-		goto core_init_failed;
-	}
-	core->register_base = res->start;
-	core->register_size = resource_size(res);
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!res) {
-		dprintk(VIDC_ERR, "Failed to get IORESOURCE_IRQ\n");
-		rc = -ENODEV;
-		goto core_init_failed;
-	}
-	core->irq = res->start;
-	INIT_LIST_HEAD(&core->instances);
-	mutex_init(&core->sync_lock);
-	spin_lock_init(&core->lock);
-	core->base_addr = 0x0;
-	core->state = VIDC_CORE_UNINIT;
-	for (i = SYS_MSG_INDEX(SYS_MSG_START);
-		i <= SYS_MSG_INDEX(SYS_MSG_END); i++) {
-		init_completion(&core->completions[i]);
-	}
-	rc = msm_vidc_init_clocks(pdev, core);
-	if (rc) {
-		dprintk(VIDC_ERR, "Failed to init clocks\n");
-		rc = -ENODEV;
-		goto core_init_failed;
-	}
-	core->resources.bus_info.ddr_handle[MSM_VIDC_ENCODER] =
-		msm_bus_scale_register_client(&enc_ddr_bus_data);
-	if (!core->resources.bus_info.ddr_handle[MSM_VIDC_ENCODER]) {
-		dprintk(VIDC_ERR, "Failed to register bus scale client\n");
-		goto fail_register_enc_ddr_bus;
-	}
-	core->resources.bus_info.ddr_handle[MSM_VIDC_DECODER] =
-		msm_bus_scale_register_client(&dec_ddr_bus_data);
-	if (!core->resources.bus_info.ddr_handle[MSM_VIDC_DECODER]) {
-		dprintk(VIDC_ERR, "Failed to register bus scale client\n");
-		goto fail_register_dec_ddr_bus;
-	}
-	core->resources.bus_info.ocmem_handle[MSM_VIDC_ENCODER] =
-		msm_bus_scale_register_client(&enc_ocmem_bus_data);
-	if (!core->resources.bus_info.ocmem_handle[MSM_VIDC_ENCODER]) {
-		dprintk(VIDC_ERR, "Failed to register bus scale client\n");
-		goto fail_register_enc_ocmem;
-	}
-	core->resources.bus_info.ocmem_handle[MSM_VIDC_DECODER] =
-		msm_bus_scale_register_client(&dec_ocmem_bus_data);
-	if (!core->resources.bus_info.ocmem_handle[MSM_VIDC_DECODER]) {
-		dprintk(VIDC_ERR, "Failed to register bus scale client\n");
-		goto fail_register_dec_ocmem;
-	}
-	rc = register_iommu_domains(pdev, core);
-	if (rc) {
-		dprintk(VIDC_ERR, "Failed to register iommu domains: %d\n", rc);
-		goto fail_register_domains;
-	}
-	ocmem = &core->resources.ocmem;
-	ocmem->vidc_ocmem_nb.notifier_call = msm_vidc_ocmem_notify_handler;
-	ocmem->handle =
-		ocmem_notifier_register(OCMEM_VIDEO, &ocmem->vidc_ocmem_nb);
-	if (!ocmem->handle) {
-		dprintk(VIDC_WARN, "Failed to register OCMEM notifier.");
-		dprintk(VIDC_INFO, " Performance will be impacted\n");
-	}
-	return rc;
-fail_register_domains:
-	msm_bus_scale_unregister_client(
-		core->resources.bus_info.ocmem_handle[MSM_VIDC_DECODER]);
-fail_register_dec_ocmem:
-	msm_bus_scale_unregister_client(
-		core->resources.bus_info.ocmem_handle[MSM_VIDC_ENCODER]);
-fail_register_enc_ocmem:
-	msm_bus_scale_unregister_client(
-		core->resources.bus_info.ddr_handle[MSM_VIDC_DECODER]);
-fail_register_dec_ddr_bus:
-	msm_bus_scale_unregister_client(
-		core->resources.bus_info.ddr_handle[MSM_VIDC_ENCODER]);
-fail_register_enc_ddr_bus:
-	msm_vidc_deinit_clocks(core);
-core_init_failed:
-	return rc;
-}
-
-static int __devinit msm_vidc_probe(struct platform_device *pdev)
-{
-	int rc = 0;
-	struct msm_vidc_core *core;
-	unsigned long flags;
-	core = kzalloc(sizeof(*core), GFP_KERNEL);
-	if (!core || !vidc_driver) {
-		dprintk(VIDC_ERR,
-			"Failed to allocate memory for device core\n");
-		rc = -ENOMEM;
-		goto err_no_mem;
-	}
-	rc = msm_vidc_initialize_core(pdev, core);
-	if (rc) {
-		dprintk(VIDC_ERR, "Failed to init core\n");
-		goto err_v4l2_register;
-	}
-	rc = v4l2_device_register(&pdev->dev, &core->v4l2_dev);
-	if (rc) {
-		dprintk(VIDC_ERR, "Failed to register v4l2 device\n");
-		goto err_v4l2_register;
-	}
-	core->vdev[MSM_VIDC_DECODER].vdev.release =
-		msm_vidc_release_video_device;
-	core->vdev[MSM_VIDC_DECODER].vdev.fops = &msm_v4l2_vidc_fops;
-	core->vdev[MSM_VIDC_DECODER].vdev.ioctl_ops = &msm_v4l2_ioctl_ops;
-	core->vdev[MSM_VIDC_DECODER].type = MSM_VIDC_DECODER;
-	rc = video_register_device(&core->vdev[MSM_VIDC_DECODER].vdev,
-					VFL_TYPE_GRABBER, BASE_DEVICE_NUMBER);
-	if (rc) {
-		dprintk(VIDC_ERR, "Failed to register video decoder device");
-		goto err_dec_register;
-	}
-	video_set_drvdata(&core->vdev[MSM_VIDC_DECODER].vdev, core);
-
-	core->vdev[MSM_VIDC_ENCODER].vdev.release =
-		msm_vidc_release_video_device;
-	core->vdev[MSM_VIDC_ENCODER].vdev.fops = &msm_v4l2_vidc_fops;
-	core->vdev[MSM_VIDC_ENCODER].vdev.ioctl_ops = &msm_v4l2_ioctl_ops;
-	core->vdev[MSM_VIDC_ENCODER].type = MSM_VIDC_ENCODER;
-	rc = video_register_device(&core->vdev[MSM_VIDC_ENCODER].vdev,
-				VFL_TYPE_GRABBER, BASE_DEVICE_NUMBER + 1);
-	if (rc) {
-		dprintk(VIDC_ERR, "Failed to register video encoder device");
-		goto err_enc_register;
-	}
-	video_set_drvdata(&core->vdev[MSM_VIDC_ENCODER].vdev, core);
-	core->device = vidc_hal_add_device(core->id, core->base_addr,
-			core->register_base, core->register_size, core->irq,
-			&handle_cmd_response);
-	if (!core->device) {
-		dprintk(VIDC_ERR, "Failed to create interrupt handler");
-		goto err_cores_exceeded;
-	}
-
-	spin_lock_irqsave(&vidc_driver->lock, flags);
-	if (vidc_driver->num_cores  + 1 > MSM_VIDC_CORES_MAX) {
-		spin_unlock_irqrestore(&vidc_driver->lock, flags);
-		dprintk(VIDC_ERR, "Maximum cores already exist, core_no = %d\n",
-				vidc_driver->num_cores);
-		goto err_cores_exceeded;
-	}
-
-	core->id = vidc_driver->num_cores++;
-	list_add_tail(&core->list, &vidc_driver->cores);
-	spin_unlock_irqrestore(&vidc_driver->lock, flags);
-	core->debugfs_root = msm_vidc_debugfs_init_core(
-		core, vidc_driver->debugfs_root);
-	pdev->dev.platform_data = core;
-	return rc;
-
-err_cores_exceeded:
-	video_unregister_device(&core->vdev[MSM_VIDC_ENCODER].vdev);
-err_enc_register:
-	video_unregister_device(&core->vdev[MSM_VIDC_DECODER].vdev);
-err_dec_register:
-	v4l2_device_unregister(&core->v4l2_dev);
-err_v4l2_register:
-	kfree(core);
-err_no_mem:
-	return rc;
-}
-
-static int __devexit msm_vidc_remove(struct platform_device *pdev)
-{
-	int rc = 0;
-	struct msm_vidc_core *core = pdev->dev.platform_data;
-	int i;
-	for (i = 0; i < MSM_VIDC_MAX_DEVICES; ++i) {
-		msm_bus_scale_unregister_client(
-			core->resources.bus_info.ddr_handle[i]);
-		msm_bus_scale_unregister_client(
-			core->resources.bus_info.ocmem_handle[i]);
-	}
-	vidc_hal_delete_device(core->device);
-	video_unregister_device(&core->vdev[MSM_VIDC_ENCODER].vdev);
-	video_unregister_device(&core->vdev[MSM_VIDC_DECODER].vdev);
-	v4l2_device_unregister(&core->v4l2_dev);
-	if (core->resources.ocmem.handle)
-		ocmem_notifier_unregister(core->resources.ocmem.handle,
-				&core->resources.ocmem.vidc_ocmem_nb);
-	kfree(core);
-	return rc;
-}
-static const struct of_device_id msm_vidc_dt_match[] = {
-	{.compatible = "qcom,msm-vidc"},
-};
-
-MODULE_DEVICE_TABLE(of, msm_vidc_dt_match);
-
-static struct platform_driver msm_vidc_driver = {
-	.probe = msm_vidc_probe,
-	.remove = msm_vidc_remove,
-	.driver = {
-		.name = "msm_vidc",
-		.owner = THIS_MODULE,
-		.of_match_table = msm_vidc_dt_match,
-	},
-};
-
-static int __init msm_vidc_init(void)
-{
-	int rc = 0;
-	vidc_driver = kzalloc(sizeof(*vidc_driver),
-						GFP_KERNEL);
-	if (!vidc_driver) {
-		dprintk(VIDC_ERR,
-			"Failed to allocate memroy for msm_vidc_drv\n");
-		return -ENOMEM;
-	}
-
-	INIT_LIST_HEAD(&vidc_driver->cores);
-	spin_lock_init(&vidc_driver->lock);
-	vidc_driver->debugfs_root = debugfs_create_dir("msm_vidc", NULL);
-	if (!vidc_driver->debugfs_root)
-		dprintk(VIDC_ERR,
-			"Failed to create debugfs for msm_vidc\n");
-
-	rc = platform_driver_register(&msm_vidc_driver);
-	if (rc) {
-		dprintk(VIDC_ERR,
-			"Failed to register platform driver\n");
-		kfree(vidc_driver);
-		vidc_driver = NULL;
-	}
-
-	return rc;
-}
-
-static void __exit msm_vidc_exit(void)
-{
-	platform_driver_unregister(&msm_vidc_driver);
-	debugfs_remove_recursive(vidc_driver->debugfs_root);
-	kfree(vidc_driver);
-	vidc_driver = NULL;
-}
-
-module_init(msm_vidc_init);
-module_exit(msm_vidc_exit);
diff --git a/drivers/media/video/msm_vidc/msm_vdec.c b/drivers/media/video/msm_vidc/msm_vdec.c
deleted file mode 100644
index 440c704..0000000
--- a/drivers/media/video/msm_vidc/msm_vdec.c
+++ /dev/null
@@ -1,1354 +0,0 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/slab.h>
-
-#include "msm_vidc_internal.h"
-#include "msm_vidc_common.h"
-#include "vidc_hal_api.h"
-#include "msm_smem.h"
-#include "msm_vidc_debug.h"
-
-#define MSM_VDEC_DVC_NAME "msm_vdec_8974"
-#define DEFAULT_HEIGHT 720
-#define DEFAULT_WIDTH 1280
-#define MAX_SUPPORTED_WIDTH 3820
-#define MAX_SUPPORTED_HEIGHT 2160
-#define MIN_NUM_OUTPUT_BUFFERS 4
-#define MAX_NUM_OUTPUT_BUFFERS 6
-
-enum msm_vdec_ctrl_cluster {
-	MSM_VDEC_CTRL_CLUSTER_MAX = 1,
-};
-
-static const char *const mpeg_video_vidc_divx_format[] = {
-	"DIVX Format 3",
-	"DIVX Format 4",
-	"DIVX Format 5",
-	"DIVX Format 6",
-	NULL
-};
-static const char *mpeg_video_stream_format[] = {
-	"NAL Format Start Codes",
-	"NAL Format One NAL Per Buffer",
-	"NAL Format One Byte Length",
-	"NAL Format Two Byte Length",
-	"NAL Format Four Byte Length",
-	NULL
-};
-static const char *const mpeg_video_output_order[] = {
-	"Display Order",
-	"Decode Order",
-	NULL
-};
-static const char *const mpeg_video_vidc_extradata[] = {
-	"Extradata none",
-	"Extradata MB Quantization",
-	"Extradata Interlace Video",
-	"Extradata VC1 Framedisp",
-	"Extradata VC1 Seqdisp",
-	"Extradata timestamp",
-	"Extradata S3D Frame Packing",
-	"Extradata Frame Rate",
-	"Extradata Panscan Window",
-	"Extradata Recovery point SEI",
-	"Extradata Closed Caption UD",
-	"Extradata AFD UD",
-	"Extradata Multislice info",
-	"Extradata number of concealed MB",
-	"Extradata metadata filler",
-	"Extradata input crop",
-	"Extradata digital zoom",
-	"Extradata aspect ratio",
-};
-
-static struct msm_vidc_ctrl msm_vdec_ctrls[] = {
-	{
-		.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT,
-		.name = "NAL Format",
-		.type = V4L2_CTRL_TYPE_MENU,
-		.minimum = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES,
-		.maximum = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH,
-		.default_value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES,
-		.menu_skip_mask = ~(
-		(1 << V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES) |
-		(1 << V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_ONE_NAL_PER_BUFFER) |
-		(1 << V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_ONE_BYTE_LENGTH) |
-		(1 << V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH) |
-		(1 << V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH)
-		),
-		.qmenu = mpeg_video_stream_format,
-		.step = 0,
-		.cluster = 0,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER,
-		.name = "Output Order",
-		.type = V4L2_CTRL_TYPE_MENU,
-		.minimum = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY,
-		.maximum = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE,
-		.default_value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY,
-		.menu_skip_mask = ~(
-			(1 << V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY) |
-			(1 << V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE)
-			),
-		.qmenu = mpeg_video_output_order,
-		.step = 0,
-		.cluster = 0,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_PICTURE_TYPE,
-		.name = "Picture Type Decoding",
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.minimum = 1,
-		.maximum = 15,
-		.default_value = 15,
-		.step = 1,
-		.menu_skip_mask = 0,
-		.qmenu = NULL,
-		.cluster = 0,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO,
-		.name = "Keep Aspect Ratio",
-		.type = V4L2_CTRL_TYPE_BOOLEAN,
-		.minimum = 0,
-		.maximum = 1,
-		.default_value = 0,
-		.step = 1,
-		.menu_skip_mask = 0,
-		.qmenu = NULL,
-		.cluster = 0,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDC_VIDEO_POST_LOOP_DEBLOCKER_MODE,
-		.name = "Deblocker Mode",
-		.type = V4L2_CTRL_TYPE_BOOLEAN,
-		.minimum = 0,
-		.maximum = 1,
-		.default_value = 0,
-		.step = 1,
-		.menu_skip_mask = 0,
-		.qmenu = NULL,
-		.cluster = 0,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT,
-		.name = "Divx Format",
-		.type = V4L2_CTRL_TYPE_MENU,
-		.minimum = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4,
-		.maximum = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6,
-		.default_value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4,
-		.menu_skip_mask = ~(
-			(1 << V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4) |
-			(1 << V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5) |
-			(1 << V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6)
-			),
-		.qmenu = mpeg_video_vidc_divx_format,
-		.step = 0,
-		.cluster = 0,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDC_VIDEO_MB_ERROR_MAP_REPORTING,
-		.name = "MB Error Map Reporting",
-		.type = V4L2_CTRL_TYPE_BOOLEAN,
-		.minimum = 0,
-		.maximum = 1,
-		.default_value = 0,
-		.step = 1,
-		.menu_skip_mask = 0,
-		.qmenu = NULL,
-		.cluster = 0,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER,
-		.name = "control",
-		.type = V4L2_CTRL_TYPE_BOOLEAN,
-		.minimum = 0,
-		.maximum = 1,
-		.default_value = 0,
-		.step = 1,
-		.menu_skip_mask = 0,
-		.qmenu = NULL,
-		.cluster = 0,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE,
-		.name = "Sync Frame Decode",
-		.type = V4L2_CTRL_TYPE_BOOLEAN,
-		.minimum = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_DISABLE,
-		.maximum = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE,
-		.default_value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_DISABLE,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE,
-		.name = "Secure mode",
-		.type = V4L2_CTRL_TYPE_BUTTON,
-		.minimum = 0,
-		.maximum = 0,
-		.default_value = 0,
-		.step = 0,
-		.menu_skip_mask = 0,
-		.qmenu = NULL,
-		.cluster = 0,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA,
-		.name = "Extradata Type",
-		.type = V4L2_CTRL_TYPE_MENU,
-		.minimum = V4L2_MPEG_VIDC_EXTRADATA_NONE,
-		.maximum = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO,
-		.default_value = V4L2_MPEG_VIDC_EXTRADATA_NONE,
-		.menu_skip_mask = ~(
-			(1 << V4L2_MPEG_VIDC_EXTRADATA_NONE) |
-			(1 << V4L2_MPEG_VIDC_EXTRADATA_MB_QUANTIZATION) |
-			(1 << V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO) |
-			(1 << V4L2_MPEG_VIDC_EXTRADATA_VC1_FRAMEDISP) |
-			(1 << V4L2_MPEG_VIDC_EXTRADATA_VC1_SEQDISP) |
-			(1 << V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP) |
-			(1 << V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING) |
-			(1 << V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE) |
-			(1 << V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW) |
-			(1 << V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI) |
-			(1 << V4L2_MPEG_VIDC_EXTRADATA_CLOSED_CAPTION_UD) |
-			(1 << V4L2_MPEG_VIDC_EXTRADATA_AFD_UD) |
-			(1 << V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO) |
-			(1 << V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB) |
-			(1 << V4L2_MPEG_VIDC_EXTRADATA_METADATA_FILLER) |
-			(1 << V4L2_MPEG_VIDC_INDEX_EXTRADATA_INPUT_CROP) |
-			(1 << V4L2_MPEG_VIDC_INDEX_EXTRADATA_DIGITAL_ZOOM) |
-			(1 << V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO)
-			),
-		.qmenu = mpeg_video_vidc_extradata,
-		.step = 0,
-	},
-};
-
-#define NUM_CTRLS ARRAY_SIZE(msm_vdec_ctrls)
-
-static u32 get_frame_size_nv12(int plane,
-					u32 height, u32 width)
-{
-	return VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
-}
-
-static u32 get_frame_size_compressed(int plane,
-					u32 height, u32 width)
-{
-	return (MAX_SUPPORTED_WIDTH * MAX_SUPPORTED_HEIGHT * 3/2)/2;
-}
-
-static const struct msm_vidc_format vdec_formats[] = {
-	{
-		.name = "YCbCr Semiplanar 4:2:0",
-		.description = "Y/CbCr 4:2:0",
-		.fourcc = V4L2_PIX_FMT_NV12,
-		.num_planes = 2,
-		.get_frame_size = get_frame_size_nv12,
-		.type = CAPTURE_PORT,
-	},
-	{
-		.name = "Mpeg4",
-		.description = "Mpeg4 compressed format",
-		.fourcc = V4L2_PIX_FMT_MPEG4,
-		.num_planes = 1,
-		.get_frame_size = get_frame_size_compressed,
-		.type = OUTPUT_PORT,
-	},
-	{
-		.name = "Mpeg2",
-		.description = "Mpeg2 compressed format",
-		.fourcc = V4L2_PIX_FMT_MPEG2,
-		.num_planes = 1,
-		.get_frame_size = get_frame_size_compressed,
-		.type = OUTPUT_PORT,
-	},
-	{
-		.name = "H263",
-		.description = "H263 compressed format",
-		.fourcc = V4L2_PIX_FMT_H263,
-		.num_planes = 1,
-		.get_frame_size = get_frame_size_compressed,
-		.type = OUTPUT_PORT,
-	},
-	{
-		.name = "VC1",
-		.description = "VC-1 compressed format",
-		.fourcc = V4L2_PIX_FMT_VC1_ANNEX_G,
-		.num_planes = 1,
-		.get_frame_size = get_frame_size_compressed,
-		.type = OUTPUT_PORT,
-	},
-	{
-		.name = "VC1 SP",
-		.description = "VC-1 compressed format G",
-		.fourcc = V4L2_PIX_FMT_VC1_ANNEX_L,
-		.num_planes = 1,
-		.get_frame_size = get_frame_size_compressed,
-		.type = OUTPUT_PORT,
-	},
-	{
-		.name = "H264",
-		.description = "H264 compressed format",
-		.fourcc = V4L2_PIX_FMT_H264,
-		.num_planes = 1,
-		.get_frame_size = get_frame_size_compressed,
-		.type = OUTPUT_PORT,
-	},
-	{
-		.name = "VP8",
-		.description = "VP8 compressed format",
-		.fourcc = V4L2_PIX_FMT_VP8,
-		.num_planes = 1,
-		.get_frame_size = get_frame_size_compressed,
-		.type = OUTPUT_PORT,
-	},
-	{
-		.name = "DIVX 311",
-		.description = "DIVX 311 compressed format",
-		.fourcc = V4L2_PIX_FMT_DIVX_311,
-		.num_planes = 1,
-		.get_frame_size = get_frame_size_compressed,
-		.type = OUTPUT_PORT,
-	},
-	{
-		.name = "DIVX",
-		.description = "DIVX 4/5/6 compressed format",
-		.fourcc = V4L2_PIX_FMT_DIVX,
-		.num_planes = 1,
-		.get_frame_size = get_frame_size_compressed,
-		.type = OUTPUT_PORT,
-	}
-};
-
-int msm_vdec_streamon(struct msm_vidc_inst *inst, enum v4l2_buf_type i)
-{
-	int rc = 0;
-	struct buf_queue *q;
-	q = msm_comm_get_vb2q(inst, i);
-	if (!q) {
-		dprintk(VIDC_ERR,
-			"Failed to find buffer queue for type = %d\n", i);
-		return -EINVAL;
-	}
-	dprintk(VIDC_DBG, "Calling streamon\n");
-	mutex_lock(&q->lock);
-	rc = vb2_streamon(&q->vb2_bufq, i);
-	mutex_unlock(&q->lock);
-	if (rc)
-		dprintk(VIDC_ERR, "streamon failed on port: %d\n", i);
-	return rc;
-}
-
-int msm_vdec_streamoff(struct msm_vidc_inst *inst, enum v4l2_buf_type i)
-{
-	int rc = 0;
-	struct buf_queue *q;
-
-	q = msm_comm_get_vb2q(inst, i);
-	if (!q) {
-		dprintk(VIDC_ERR,
-			"Failed to find buffer queue for type = %d\n", i);
-		return -EINVAL;
-	}
-	dprintk(VIDC_DBG, "Calling streamoff\n");
-	mutex_lock(&q->lock);
-	rc = vb2_streamoff(&q->vb2_bufq, i);
-	mutex_unlock(&q->lock);
-	if (rc)
-		dprintk(VIDC_ERR, "streamoff failed on port: %d\n", i);
-	return rc;
-}
-
-int msm_vdec_prepare_buf(struct msm_vidc_inst *inst,
-					struct v4l2_buffer *b)
-{
-	int rc = 0;
-	struct vidc_buffer_addr_info buffer_info;
-	int extra_idx = 0;
-	int i;
-	switch (b->type) {
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-		break;
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
-			if (b->length != inst->fmts[CAPTURE_PORT]->num_planes) {
-				dprintk(VIDC_ERR,
-				"Planes mismatch: needed: %d, allocated: %d\n",
-				inst->fmts[CAPTURE_PORT]->num_planes,
-				b->length);
-				rc = -EINVAL;
-				break;
-			}
-			for (i = 0; (i < b->length)
-				&& (i < VIDEO_MAX_PLANES); ++i) {
-				dprintk(VIDC_DBG,
-				"prepare plane: %d, device_addr = 0x%lx, size = %d\n",
-				i, b->m.planes[i].m.userptr,
-				b->m.planes[i].length);
-			}
-			buffer_info.buffer_size = b->m.planes[0].length;
-			buffer_info.buffer_type = HAL_BUFFER_OUTPUT;
-			buffer_info.num_buffers = 1;
-			buffer_info.align_device_addr =
-				b->m.planes[0].m.userptr;
-			extra_idx = EXTRADATA_IDX(b->length);
-			if (extra_idx && (extra_idx < VIDEO_MAX_PLANES) &&
-				b->m.planes[extra_idx].m.userptr) {
-				buffer_info.extradata_addr =
-					b->m.planes[extra_idx].m.userptr;
-				dprintk(VIDC_DBG,
-				"extradata: 0x%lx\n",
-				b->m.planes[extra_idx].m.userptr);
-				buffer_info.extradata_size =
-					b->m.planes[extra_idx].length;
-			} else {
-				buffer_info.extradata_addr = 0;
-				buffer_info.extradata_size = 0;
-			}
-			rc = vidc_hal_session_set_buffers((void *)inst->session,
-					&buffer_info);
-			if (rc)
-				dprintk(VIDC_ERR,
-				"vidc_hal_session_set_buffers failed");
-		break;
-	default:
-		dprintk(VIDC_ERR, "Buffer type not recognized: %d\n", b->type);
-		break;
-	}
-	return rc;
-}
-
-int msm_vdec_release_buf(struct msm_vidc_inst *inst,
-					struct v4l2_buffer *b)
-{
-	int rc = 0;
-	struct vidc_buffer_addr_info buffer_info;
-	struct msm_vidc_core *core = inst->core;
-	int extra_idx = 0;
-	int i;
-	if (inst->state == MSM_VIDC_CORE_INVALID ||
-			core->state == VIDC_CORE_INVALID) {
-		dprintk(VIDC_ERR,
-			"Core %p in bad state, ignoring release output buf\n",
-				core);
-		goto exit;
-	}
-	if (!inst->in_reconfig) {
-		rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
-		if (rc) {
-			dprintk(VIDC_ERR,
-				"Failed to move inst: %p to relase res done\n",
-				inst);
-			goto exit;
-		}
-	}
-	switch (b->type) {
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-		break;
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
-			if (b->length !=
-				inst->fmts[CAPTURE_PORT]->num_planes) {
-				dprintk(VIDC_ERR,
-				"Planes mismatch: needed: %d, to release: %d\n",
-				inst->fmts[CAPTURE_PORT]->num_planes,
-				b->length);
-				rc = -EINVAL;
-				break;
-			}
-			for (i = 0; i < b->length; ++i) {
-				dprintk(VIDC_DBG,
-				"Release plane: %d device_addr = 0x%lx, size = %d\n",
-				i, b->m.planes[i].m.userptr,
-				b->m.planes[i].length);
-			}
-			buffer_info.buffer_size = b->m.planes[0].length;
-			buffer_info.buffer_type = HAL_BUFFER_OUTPUT;
-			buffer_info.num_buffers = 1;
-			buffer_info.align_device_addr =
-				 b->m.planes[0].m.userptr;
-			extra_idx = EXTRADATA_IDX(b->length);
-			if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)
-				&& b->m.planes[extra_idx].m.userptr)
-				buffer_info.extradata_addr =
-					b->m.planes[extra_idx].m.userptr;
-			else
-				buffer_info.extradata_addr = 0;
-			buffer_info.response_required = false;
-			rc = vidc_hal_session_release_buffers(
-					(void *)inst->session, &buffer_info);
-			if (rc)
-				dprintk(VIDC_ERR,
-				"vidc_hal_session_release_buffers failed");
-		break;
-	default:
-		dprintk(VIDC_ERR, "Buffer type not recognized: %d\n", b->type);
-		break;
-	}
-exit:
-	return rc;
-}
-
-int msm_vdec_qbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b)
-{
-	struct buf_queue *q = NULL;
-	int rc = 0;
-	q = msm_comm_get_vb2q(inst, b->type);
-	if (!q) {
-		dprintk(VIDC_ERR, "Failed to find buffer queue for type = %d\n"
-			, b->type);
-		return -EINVAL;
-	}
-	mutex_lock(&q->lock);
-	rc = vb2_qbuf(&q->vb2_bufq, b);
-	mutex_unlock(&q->lock);
-	if (rc)
-		dprintk(VIDC_ERR, "Failed to qbuf, %d\n", rc);
-	return rc;
-}
-int msm_vdec_dqbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b)
-{
-	struct buf_queue *q = NULL;
-	int rc = 0;
-	q = msm_comm_get_vb2q(inst, b->type);
-	if (!q) {
-		dprintk(VIDC_ERR, "Failed to find buffer queue for type = %d\n"
-			, b->type);
-		return -EINVAL;
-	}
-	mutex_lock(&q->lock);
-	rc = vb2_dqbuf(&q->vb2_bufq, b, true);
-	mutex_unlock(&q->lock);
-	if (rc)
-		dprintk(VIDC_DBG, "Failed to dqbuf, %d\n", rc);
-	return rc;
-}
-
-int msm_vdec_reqbufs(struct msm_vidc_inst *inst, struct v4l2_requestbuffers *b)
-{
-	struct buf_queue *q = NULL;
-	int rc = 0;
-	if (!inst || !b) {
-		dprintk(VIDC_ERR,
-			"Invalid input, inst = %p, buffer = %p\n", inst, b);
-		return -EINVAL;
-	}
-	q = msm_comm_get_vb2q(inst, b->type);
-	if (!q) {
-		dprintk(VIDC_ERR, "Failed to find buffer queue for type = %d\n"
-			, b->type);
-		return -EINVAL;
-	}
-
-	mutex_lock(&q->lock);
-	rc = vb2_reqbufs(&q->vb2_bufq, b);
-	mutex_unlock(&q->lock);
-	if (rc)
-		dprintk(VIDC_ERR, "Failed to get reqbufs, %d\n", rc);
-	return rc;
-}
-
-int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
-{
-	const struct msm_vidc_format *fmt = NULL;
-	struct hal_frame_size frame_sz;
-	int extra_idx = 0;
-	int rc = 0;
-	int ret;
-	int i;
-	if (!inst || !f) {
-		dprintk(VIDC_ERR,
-			"Invalid input, inst = %p, format = %p\n", inst, f);
-		return -EINVAL;
-	}
-	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
-		fmt = inst->fmts[CAPTURE_PORT];
-	else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
-		fmt = inst->fmts[OUTPUT_PORT];
-
-	if (fmt) {
-		f->fmt.pix_mp.pixelformat = fmt->fourcc;
-		f->fmt.pix_mp.num_planes = fmt->num_planes;
-		if (inst->in_reconfig == true) {
-			inst->prop.height = inst->reconfig_height;
-			inst->prop.width = inst->reconfig_width;
-		}
-		f->fmt.pix_mp.height = inst->prop.height;
-		f->fmt.pix_mp.width = inst->prop.width;
-		frame_sz.buffer_type = HAL_BUFFER_OUTPUT;
-		frame_sz.width = inst->prop.width;
-		frame_sz.height = inst->prop.height;
-		dprintk(VIDC_DBG, "width = %d, height = %d\n",
-				frame_sz.width, frame_sz.height);
-		ret = msm_comm_try_set_prop(inst,
-			HAL_PARAM_FRAME_SIZE, &frame_sz);
-		ret = ret || msm_comm_try_get_bufreqs(inst);
-		if (ret || (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)) {
-			for (i = 0; i < fmt->num_planes; ++i) {
-				f->fmt.pix_mp.plane_fmt[i].sizeimage =
-					fmt->get_frame_size(i,
-						f->fmt.pix_mp.height,
-						f->fmt.pix_mp.width);
-				inst->bufq[OUTPUT_PORT].
-					vb2_bufq.plane_sizes[i] =
-					f->fmt.pix_mp.plane_fmt[i].sizeimage;
-			}
-		} else {
-			f->fmt.pix_mp.plane_fmt[0].sizeimage =
-			inst->buff_req.buffer[HAL_BUFFER_OUTPUT].buffer_size;
-			extra_idx = EXTRADATA_IDX(fmt->num_planes);
-			if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
-				f->fmt.pix_mp.plane_fmt[extra_idx].sizeimage =
-		inst->buff_req.buffer[HAL_BUFFER_EXTRADATA_OUTPUT].buffer_size;
-			}
-			for (i = 0; i < fmt->num_planes; ++i)
-				inst->bufq[CAPTURE_PORT].
-					vb2_bufq.plane_sizes[i] =
-					f->fmt.pix_mp.plane_fmt[i].sizeimage;
-
-		}
-	} else {
-		dprintk(VIDC_ERR,
-			"Buf type not recognized, type = %d\n",
-			f->type);
-		rc = -EINVAL;
-	}
-	return rc;
-}
-int msm_vdec_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a)
-{
-	u32 us_per_frame = 0;
-	int rc = 0;
-	if (a->parm.output.timeperframe.denominator) {
-		switch (a->type) {
-		case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-			us_per_frame = a->parm.output.timeperframe.numerator/
-				a->parm.output.timeperframe.denominator;
-			break;
-		case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
-			us_per_frame = a->parm.capture.timeperframe.numerator/
-				a->parm.capture.timeperframe.denominator;
-			break;
-		default:
-			dprintk(VIDC_ERR,
-				"Scale clocks : Unknown buffer type\n");
-			break;
-		}
-	}
-	if (!us_per_frame) {
-		dprintk(VIDC_ERR,
-				"Failed to scale clocks : time between frames is 0\n");
-		rc = -EINVAL;
-		goto exit;
-	}
-	inst->prop.fps = (u8) (USEC_PER_SEC / us_per_frame);
-	if (inst->prop.fps) {
-		msm_comm_scale_clocks_and_bus(inst);
-	}
-exit:
-	return rc;
-}
-int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
-{
-	const struct msm_vidc_format *fmt = NULL;
-	struct hal_frame_size frame_sz;
-	int extra_idx = 0;
-	int rc = 0;
-	int ret = 0;
-	int i;
-	if (!inst || !f) {
-		dprintk(VIDC_ERR,
-			"Invalid input, inst = %p, format = %p\n", inst, f);
-		return -EINVAL;
-	}
-	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-		struct hal_frame_size frame_sz;
-
-		fmt = msm_comm_get_pixel_fmt_fourcc(vdec_formats,
-			ARRAY_SIZE(vdec_formats), f->fmt.pix_mp.pixelformat,
-			CAPTURE_PORT);
-		if (!fmt || (fmt && fmt->type != CAPTURE_PORT)) {
-			dprintk(VIDC_ERR,
-				"Format: %d not supported on CAPTURE port\n",
-				f->fmt.pix_mp.pixelformat);
-			rc = -EINVAL;
-			goto err_invalid_fmt;
-		}
-		inst->fmts[fmt->type] = fmt;
-		frame_sz.buffer_type = HAL_BUFFER_OUTPUT;
-		frame_sz.width = inst->prop.width;
-		frame_sz.height = inst->prop.height;
-		dprintk(VIDC_DBG, "width = %d, height = %d\n",
-				frame_sz.width, frame_sz.height);
-		ret = msm_comm_try_set_prop(inst,
-			HAL_PARAM_FRAME_SIZE, &frame_sz);
-		ret = ret || msm_comm_try_get_bufreqs(inst);
-		if (ret) {
-			for (i = 0; i < fmt->num_planes; ++i) {
-				f->fmt.pix_mp.plane_fmt[i].sizeimage =
-					fmt->get_frame_size(i,
-						f->fmt.pix_mp.height,
-						f->fmt.pix_mp.width);
-			}
-		} else {
-			f->fmt.pix_mp.plane_fmt[0].sizeimage =
-			inst->buff_req.buffer[HAL_BUFFER_OUTPUT].buffer_size;
-			extra_idx = EXTRADATA_IDX(fmt->num_planes);
-			if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
-				f->fmt.pix_mp.plane_fmt[1].sizeimage =
-		inst->buff_req.buffer[HAL_BUFFER_EXTRADATA_OUTPUT].buffer_size;
-			}
-		}
-		f->fmt.pix_mp.num_planes = fmt->num_planes;
-		for (i = 0; i < fmt->num_planes; ++i) {
-			inst->bufq[CAPTURE_PORT].vb2_bufq.plane_sizes[i] =
-				f->fmt.pix_mp.plane_fmt[i].sizeimage;
-		}
-	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-		inst->prop.width = f->fmt.pix_mp.width;
-		inst->prop.height = f->fmt.pix_mp.height;
-		fmt = msm_comm_get_pixel_fmt_fourcc(vdec_formats,
-				ARRAY_SIZE(vdec_formats),
-				f->fmt.pix_mp.pixelformat,
-				OUTPUT_PORT);
-		if (!fmt || fmt->type != OUTPUT_PORT) {
-			dprintk(VIDC_ERR,
-			"Format: %d not supported on OUTPUT port\n",
-			f->fmt.pix_mp.pixelformat);
-			rc = -EINVAL;
-			goto err_invalid_fmt;
-		}
-		inst->fmts[fmt->type] = fmt;
-		rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
-		if (rc) {
-			dprintk(VIDC_ERR, "Failed to open instance\n");
-			goto err_invalid_fmt;
-		}
-		frame_sz.buffer_type = HAL_BUFFER_INPUT;
-		frame_sz.width = inst->prop.width;
-		frame_sz.height = inst->prop.height;
-		msm_comm_try_set_prop(inst, HAL_PARAM_FRAME_SIZE, &frame_sz);
-		f->fmt.pix_mp.plane_fmt[0].sizeimage =
-			fmt->get_frame_size(0, f->fmt.pix_mp.height,
-					f->fmt.pix_mp.width);
-		f->fmt.pix_mp.num_planes = fmt->num_planes;
-		for (i = 0; i < fmt->num_planes; ++i) {
-			inst->bufq[OUTPUT_PORT].vb2_bufq.plane_sizes[i] =
-				f->fmt.pix_mp.plane_fmt[i].sizeimage;
-		}
-	}
-err_invalid_fmt:
-	return rc;
-}
-
-int msm_vdec_querycap(struct msm_vidc_inst *inst, struct v4l2_capability *cap)
-{
-	if (!inst || !cap) {
-		dprintk(VIDC_ERR,
-			"Invalid input, inst = %p, cap = %p\n", inst, cap);
-		return -EINVAL;
-	}
-	strlcpy(cap->driver, MSM_VIDC_DRV_NAME, sizeof(cap->driver));
-	strlcpy(cap->card, MSM_VDEC_DVC_NAME, sizeof(cap->card));
-	cap->bus_info[0] = 0;
-	cap->version = MSM_VIDC_VERSION;
-	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
-						V4L2_CAP_VIDEO_OUTPUT_MPLANE |
-						V4L2_CAP_STREAMING;
-	memset(cap->reserved, 0, sizeof(cap->reserved));
-	return 0;
-}
-
-int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f)
-{
-	const struct msm_vidc_format *fmt = NULL;
-	int rc = 0;
-	if (!inst || !f) {
-		dprintk(VIDC_ERR,
-			"Invalid input, inst = %p, f = %p\n", inst, f);
-		return -EINVAL;
-	}
-	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-		fmt = msm_comm_get_pixel_fmt_index(vdec_formats,
-			ARRAY_SIZE(vdec_formats), f->index, CAPTURE_PORT);
-	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-		fmt = msm_comm_get_pixel_fmt_index(vdec_formats,
-			ARRAY_SIZE(vdec_formats), f->index, OUTPUT_PORT);
-		f->flags = V4L2_FMT_FLAG_COMPRESSED;
-	}
-
-	memset(f->reserved, 0 , sizeof(f->reserved));
-	if (fmt) {
-		strlcpy(f->description, fmt->description,
-				sizeof(f->description));
-		f->pixelformat = fmt->fourcc;
-	} else {
-		dprintk(VIDC_INFO, "No more formats found\n");
-		rc = -EINVAL;
-	}
-	return rc;
-}
-
-static int msm_vdec_queue_setup(struct vb2_queue *q,
-				const struct v4l2_format *fmt,
-				unsigned int *num_buffers,
-				unsigned int *num_planes, unsigned int sizes[],
-				void *alloc_ctxs[])
-{
-	int i, rc = 0;
-	struct msm_vidc_inst *inst;
-	unsigned long flags;
-	struct hal_buffer_requirements *bufreq;
-	int extra_idx = 0;
-	if (!q || !num_buffers || !num_planes
-		|| !sizes || !q->drv_priv) {
-		dprintk(VIDC_ERR, "Invalid input, q = %p, %p, %p\n",
-			q, num_buffers, num_planes);
-		return -EINVAL;
-	}
-	inst = q->drv_priv;
-	switch (q->type) {
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-		*num_planes = inst->fmts[OUTPUT_PORT]->num_planes;
-		if (*num_buffers < MIN_NUM_OUTPUT_BUFFERS ||
-				*num_buffers > MAX_NUM_OUTPUT_BUFFERS)
-			*num_buffers = MIN_NUM_OUTPUT_BUFFERS;
-		for (i = 0; i < *num_planes; i++) {
-			sizes[i] = inst->fmts[OUTPUT_PORT]->get_frame_size(
-					i, inst->prop.height, inst->prop.width);
-		}
-		break;
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
-		dprintk(VIDC_DBG, "Getting bufreqs on capture plane\n");
-		*num_planes = inst->fmts[CAPTURE_PORT]->num_planes;
-		rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
-		if (rc) {
-			dprintk(VIDC_ERR, "Failed to open instance\n");
-			break;
-		}
-		rc = msm_comm_try_get_bufreqs(inst);
-		if (rc) {
-			dprintk(VIDC_ERR,
-				"Failed to get buffer requirements: %d\n", rc);
-			break;
-		}
-		spin_lock_irqsave(&inst->lock, flags);
-		if (*num_buffers && *num_buffers >
-			inst->buff_req.buffer[HAL_BUFFER_OUTPUT].
-				buffer_count_actual) {
-			struct hal_buffer_count_actual new_buf_count;
-			enum hal_property property_id =
-				HAL_PARAM_BUFFER_COUNT_ACTUAL;
-
-			new_buf_count.buffer_type = HAL_BUFFER_OUTPUT;
-			new_buf_count.buffer_count_actual = *num_buffers;
-			rc = vidc_hal_session_set_property(inst->session,
-					property_id, &new_buf_count);
-
-		}
-		bufreq = &inst->buff_req.buffer[HAL_BUFFER_OUTPUT];
-		if (bufreq->buffer_count_actual > *num_buffers)
-			*num_buffers =  bufreq->buffer_count_actual;
-		else
-			bufreq->buffer_count_actual = *num_buffers ;
-		spin_unlock_irqrestore(&inst->lock, flags);
-		dprintk(VIDC_DBG, "count =  %d, size = %d, alignment = %d\n",
-				inst->buff_req.buffer[1].buffer_count_actual,
-				inst->buff_req.buffer[1].buffer_size,
-				inst->buff_req.buffer[1].buffer_alignment);
-		sizes[0] = inst->buff_req.buffer[HAL_BUFFER_OUTPUT].buffer_size;
-		extra_idx =
-			EXTRADATA_IDX(inst->fmts[CAPTURE_PORT]->num_planes);
-		if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
-			sizes[extra_idx] =
-		inst->buff_req.buffer[HAL_BUFFER_EXTRADATA_OUTPUT].buffer_size;
-		}
-		break;
-	default:
-		dprintk(VIDC_ERR, "Invalid q type = %d\n", q->type);
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
-
-static inline int start_streaming(struct msm_vidc_inst *inst)
-{
-	int rc = 0;
-	struct vb2_buf_entry *temp;
-	struct list_head *ptr, *next;
-	inst->in_reconfig = false;
-	rc = msm_comm_set_scratch_buffers(inst);
-	if (rc) {
-		dprintk(VIDC_ERR,
-			"Failed to set scratch buffers: %d\n", rc);
-		goto fail_start;
-	}
-	rc = msm_comm_set_persist_buffers(inst);
-	if (rc) {
-		dprintk(VIDC_ERR,
-			"Failed to set persist buffers: %d\n", rc);
-		goto fail_start;
-	}
-	msm_comm_scale_clocks_and_bus(inst);
-	rc = msm_comm_try_state(inst, MSM_VIDC_START_DONE);
-	if (rc) {
-		dprintk(VIDC_ERR,
-			"Failed to move inst: %p to start done state\n", inst);
-		goto fail_start;
-	}
-
-	mutex_lock(&inst->sync_lock);
-	if (!list_empty(&inst->pendingq)) {
-		list_for_each_safe(ptr, next, &inst->pendingq) {
-			temp = list_entry(ptr, struct vb2_buf_entry, list);
-			rc = msm_comm_qbuf(temp->vb);
-			if (rc) {
-				dprintk(VIDC_ERR,
-					"Failed to qbuf to hardware\n");
-				break;
-			}
-			list_del(&temp->list);
-			kfree(temp);
-		}
-	}
-	mutex_unlock(&inst->sync_lock);
-	return rc;
-fail_start:
-	return rc;
-}
-
-static inline int stop_streaming(struct msm_vidc_inst *inst)
-{
-	int rc = 0;
-	rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
-	if (rc)
-		dprintk(VIDC_ERR,
-			"Failed to move inst: %p to start done state\n", inst);
-	return rc;
-}
-
-static int msm_vdec_start_streaming(struct vb2_queue *q, unsigned int count)
-{
-	struct msm_vidc_inst *inst;
-	int rc = 0;
-	if (!q || !q->drv_priv) {
-		dprintk(VIDC_ERR, "Invalid input, q = %p\n", q);
-		return -EINVAL;
-	}
-	inst = q->drv_priv;
-	dprintk(VIDC_DBG,
-		"Streamon called on: %d capability\n", q->type);
-	switch (q->type) {
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-		if (inst->bufq[CAPTURE_PORT].vb2_bufq.streaming)
-			rc = start_streaming(inst);
-		break;
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
-		if (inst->bufq[OUTPUT_PORT].vb2_bufq.streaming)
-			rc = start_streaming(inst);
-		break;
-	default:
-		dprintk(VIDC_ERR, "Q-type is not supported: %d\n", q->type);
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
-
-static int msm_vdec_stop_streaming(struct vb2_queue *q)
-{
-	struct msm_vidc_inst *inst;
-	int rc = 0;
-	if (!q || !q->drv_priv) {
-		dprintk(VIDC_ERR, "Invalid input, q = %p\n", q);
-		return -EINVAL;
-	}
-	inst = q->drv_priv;
-	dprintk(VIDC_DBG, "Streamoff called on: %d capability\n", q->type);
-	switch (q->type) {
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-		if (!inst->bufq[CAPTURE_PORT].vb2_bufq.streaming)
-			rc = stop_streaming(inst);
-		break;
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
-		if (!inst->bufq[OUTPUT_PORT].vb2_bufq.streaming)
-			rc = stop_streaming(inst);
-		break;
-	default:
-		dprintk(VIDC_ERR,
-			"Q-type is not supported: %d\n", q->type);
-		rc = -EINVAL;
-		break;
-	}
-	msm_comm_scale_clocks_and_bus(inst);
-
-	if (rc)
-		dprintk(VIDC_ERR,
-			"Failed to move inst: %p, cap = %d to state: %d\n",
-			inst, q->type, MSM_VIDC_RELEASE_RESOURCES_DONE);
-	return rc;
-}
-
-static void msm_vdec_buf_queue(struct vb2_buffer *vb)
-{
-	int rc;
-	rc = msm_comm_qbuf(vb);
-	if (rc)
-		dprintk(VIDC_ERR, "Failed to queue buffer: %d\n", rc);
-}
-
-int msm_vdec_cmd(struct msm_vidc_inst *inst, struct v4l2_decoder_cmd *dec)
-{
-	int rc = 0;
-	struct v4l2_event dqevent = {0};
-	struct msm_vidc_core *core = inst->core;
-	switch (dec->cmd) {
-	case V4L2_DEC_QCOM_CMD_FLUSH:
-		rc = msm_comm_flush(inst, dec->flags);
-		break;
-	case V4L2_DEC_CMD_STOP:
-		rc = msm_comm_release_scratch_buffers(inst);
-		if (rc)
-			dprintk(VIDC_ERR,
-				"Failed to release scratch buffers: %d\n", rc);
-		rc = msm_comm_release_persist_buffers(inst);
-		if (rc)
-			pr_err("Failed to release persist buffers: %d\n", rc);
-		if (inst->state == MSM_VIDC_CORE_INVALID ||
-			core->state == VIDC_CORE_INVALID) {
-			dprintk(VIDC_ERR,
-				"Core %p in bad state, Sending CLOSE event\n",
-					core);
-			dqevent.type = V4L2_EVENT_MSM_VIDC_CLOSE_DONE;
-			v4l2_event_queue_fh(&inst->event_handler, &dqevent);
-			goto exit;
-		}
-		rc = msm_comm_try_state(inst, MSM_VIDC_CLOSE_DONE);
-		break;
-	default:
-		dprintk(VIDC_ERR, "Unknown Decoder Command\n");
-		rc = -ENOTSUPP;
-		goto exit;
-	}
-	if (rc) {
-		dprintk(VIDC_ERR, "Failed to exec decoder cmd %d\n", dec->cmd);
-		goto exit;
-	}
-exit:
-	return rc;
-}
-
-
-static const struct vb2_ops msm_vdec_vb2q_ops = {
-	.queue_setup = msm_vdec_queue_setup,
-	.start_streaming = msm_vdec_start_streaming,
-	.buf_queue = msm_vdec_buf_queue,
-	.stop_streaming = msm_vdec_stop_streaming,
-};
-
-const struct vb2_ops *msm_vdec_get_vb2q_ops(void)
-{
-	return &msm_vdec_vb2q_ops;
-}
-
-int msm_vdec_inst_init(struct msm_vidc_inst *inst)
-{
-	int rc = 0;
-	if (!inst) {
-		dprintk(VIDC_ERR, "Invalid input = %p\n", inst);
-		return -EINVAL;
-	}
-	inst->fmts[OUTPUT_PORT] = &vdec_formats[1];
-	inst->fmts[CAPTURE_PORT] = &vdec_formats[0];
-	inst->prop.height = DEFAULT_HEIGHT;
-	inst->prop.width = DEFAULT_WIDTH;
-	inst->prop.fps = 30;
-	inst->prop.prev_time_stamp = 0;
-	return rc;
-}
-
-static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
-{
-	int rc = 0;
-	struct v4l2_control control;
-	struct hal_nal_stream_format_supported stream_format;
-	struct hal_enable_picture enable_picture;
-	struct hal_enable hal_property;/*, prop;*/
-	u32 control_idx = 0;
-	enum hal_property property_id = 0;
-	u32 property_val = 0;
-	void *pdata;
-
-	switch (ctrl->id) {
-	case V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT:
-		property_id =
-		HAL_PARAM_NAL_STREAM_FORMAT_SELECT;
-		stream_format.nal_stream_format_supported =
-		(0x00000001 << ctrl->val);
-		pdata = &stream_format;
-		break;
-	case V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER:
-		property_id = HAL_PARAM_VDEC_OUTPUT_ORDER;
-		property_val = ctrl->val;
-		pdata = &property_val;
-		break;
-	case V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_PICTURE_TYPE:
-		property_id =
-			HAL_PARAM_VDEC_PICTURE_TYPE_DECODE;
-		enable_picture.picture_type = ctrl->val;
-		pdata = &enable_picture;
-		break;
-	case V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO:
-		property_id =
-			HAL_PARAM_VDEC_OUTPUT2_KEEP_ASPECT_RATIO;
-		hal_property.enable = ctrl->val;
-		pdata = &hal_property;
-		break;
-	case V4L2_CID_MPEG_VIDC_VIDEO_POST_LOOP_DEBLOCKER_MODE:
-		property_id =
-			HAL_CONFIG_VDEC_POST_LOOP_DEBLOCKER;
-		hal_property.enable = ctrl->val;
-		pdata = &hal_property;
-		break;
-	case V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT:
-		property_id = HAL_PARAM_DIVX_FORMAT;
-		property_val = ctrl->val;
-		pdata = &property_val;
-		break;
-	case V4L2_CID_MPEG_VIDC_VIDEO_MB_ERROR_MAP_REPORTING:
-		property_id =
-			HAL_CONFIG_VDEC_MB_ERROR_MAP_REPORTING;
-		hal_property.enable = ctrl->val;
-		pdata = &hal_property;
-		break;
-	case V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER:
-		property_id =
-			HAL_PARAM_VDEC_CONTINUE_DATA_TRANSFER;
-		hal_property.enable = ctrl->val;
-		pdata = &hal_property;
-		break;
-	case V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE:
-		property_id =
-			HAL_PARAM_VDEC_SYNC_FRAME_DECODE;
-		hal_property.enable = ctrl->val;
-		pdata = &hal_property;
-		break;
-	case V4L2_CID_MPEG_VIDC_VIDEO_SECURE:
-		inst->mode = VIDC_SECURE;
-		dprintk(VIDC_DBG, "Setting secure mode to :%d\n", inst->mode);
-		break;
-	case V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA:
-	{
-		struct hal_extradata_enable extra;
-		property_id = HAL_PARAM_INDEX_EXTRADATA;
-		extra.index = msm_comm_get_hal_extradata_index(ctrl->val);
-		extra.enable = 1;
-		pdata = &extra;
-		break;
-	}
-	default:
-		break;
-	}
-
-	if (property_id) {
-		dprintk(VIDC_DBG,
-			"Control: HAL property=%d,ctrl_id=%d,ctrl_value=%d\n",
-			property_id,
-			msm_vdec_ctrls[control_idx].id,
-			control.value);
-			rc = vidc_hal_session_set_property((void *)
-				inst->session, property_id,
-					pdata);
-	}
-
-	return rc;
-}
-
-static int msm_vdec_op_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-	int rc = 0, c = 0;
-	struct msm_vidc_inst *inst = container_of(ctrl->handler,
-				struct msm_vidc_inst, ctrl_handler);
-	rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
-	if (rc) {
-		dprintk(VIDC_ERR,
-			"Failed to move inst: %p to start done state\n", inst);
-		goto failed_open_done;
-	}
-
-	for (c = 0; c < ctrl->ncontrols; ++c) {
-		if (ctrl->cluster[c]->is_new) {
-			rc = try_set_ctrl(inst, ctrl->cluster[c]);
-			if (rc) {
-				dprintk(VIDC_ERR, "Failed setting %x",
-						ctrl->cluster[c]->id);
-				break;
-			}
-		}
-	}
-
-failed_open_done:
-	if (rc)
-		dprintk(VIDC_ERR, "Failed to set hal property for framesize\n");
-	return rc;
-}
-
-static int msm_vdec_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
-{
-	return 0;
-}
-
-static const struct v4l2_ctrl_ops msm_vdec_ctrl_ops = {
-
-	.s_ctrl = msm_vdec_op_s_ctrl,
-	.g_volatile_ctrl = msm_vdec_op_g_volatile_ctrl,
-};
-
-const struct v4l2_ctrl_ops *msm_vdec_get_ctrl_ops(void)
-{
-	return &msm_vdec_ctrl_ops;
-}
-
-int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl)
-{
-	return v4l2_s_ctrl(NULL, &inst->ctrl_handler, ctrl);
-}
-int msm_vdec_g_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl)
-{
-	return v4l2_g_ctrl(&inst->ctrl_handler, ctrl);
-}
-
-static struct v4l2_ctrl **get_cluster(int type, int *size)
-{
-	int c = 0, sz = 0;
-	struct v4l2_ctrl **cluster = kmalloc(sizeof(struct v4l2_ctrl *) *
-			NUM_CTRLS, GFP_KERNEL);
-
-	if (type <= 0 || !size || !cluster)
-		return NULL;
-
-	for (c = 0; c < NUM_CTRLS; c++) {
-		if (msm_vdec_ctrls[c].cluster == type) {
-			cluster[sz] = msm_vdec_ctrls[c].priv;
-			++sz;
-		}
-	}
-
-	*size = sz;
-	return cluster;
-}
-
-int msm_vdec_ctrl_init(struct msm_vidc_inst *inst)
-{
-	int idx = 0;
-	struct v4l2_ctrl_config ctrl_cfg;
-	int ret_val = 0;
-
-	ret_val = v4l2_ctrl_handler_init(&inst->ctrl_handler, NUM_CTRLS);
-
-	if (ret_val) {
-		dprintk(VIDC_ERR, "CTRL ERR: Control handler init failed, %d\n",
-				inst->ctrl_handler.error);
-		return ret_val;
-	}
-
-	for (; idx < NUM_CTRLS; idx++) {
-		struct v4l2_ctrl *ctrl = NULL;
-		if (IS_PRIV_CTRL(msm_vdec_ctrls[idx].id)) {
-			/*add private control*/
-			ctrl_cfg.def = msm_vdec_ctrls[idx].default_value;
-			ctrl_cfg.flags = 0;
-			ctrl_cfg.id = msm_vdec_ctrls[idx].id;
-			/* ctrl_cfg.is_private =
-			 * msm_vdec_ctrls[idx].is_private;
-			 * ctrl_cfg.is_volatile =
-			 * msm_vdec_ctrls[idx].is_volatile;*/
-			ctrl_cfg.max = msm_vdec_ctrls[idx].maximum;
-			ctrl_cfg.min = msm_vdec_ctrls[idx].minimum;
-			ctrl_cfg.menu_skip_mask =
-				msm_vdec_ctrls[idx].menu_skip_mask;
-			ctrl_cfg.name = msm_vdec_ctrls[idx].name;
-			ctrl_cfg.ops = &msm_vdec_ctrl_ops;
-			ctrl_cfg.step = msm_vdec_ctrls[idx].step;
-			ctrl_cfg.type = msm_vdec_ctrls[idx].type;
-			ctrl_cfg.qmenu = msm_vdec_ctrls[idx].qmenu;
-
-			ctrl = v4l2_ctrl_new_custom(&inst->ctrl_handler,
-					&ctrl_cfg, NULL);
-		} else {
-			if (msm_vdec_ctrls[idx].type == V4L2_CTRL_TYPE_MENU) {
-				ctrl = v4l2_ctrl_new_std_menu(
-					&inst->ctrl_handler,
-					&msm_vdec_ctrl_ops,
-					msm_vdec_ctrls[idx].id,
-					msm_vdec_ctrls[idx].maximum,
-					msm_vdec_ctrls[idx].menu_skip_mask,
-					msm_vdec_ctrls[idx].default_value);
-			} else {
-				ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler,
-					&msm_vdec_ctrl_ops,
-					msm_vdec_ctrls[idx].id,
-					msm_vdec_ctrls[idx].minimum,
-					msm_vdec_ctrls[idx].maximum,
-					msm_vdec_ctrls[idx].step,
-					msm_vdec_ctrls[idx].default_value);
-			}
-		}
-
-
-		msm_vdec_ctrls[idx].priv = ctrl;
-	}
-	ret_val = inst->ctrl_handler.error;
-	if (ret_val)
-		dprintk(VIDC_ERR,
-			"Error adding ctrls to ctrl handle, %d\n",
-			inst->ctrl_handler.error);
-
-	/* Construct clusters */
-	for (idx = 1; idx < MSM_VDEC_CTRL_CLUSTER_MAX; ++idx) {
-		struct msm_vidc_ctrl_cluster *temp = NULL;
-		struct v4l2_ctrl **cluster = NULL;
-		int cluster_size = 0;
-
-		cluster = get_cluster(idx, &cluster_size);
-		if (!cluster || !cluster_size) {
-			dprintk(VIDC_WARN, "Failed to setup cluster of type %d",
-					idx);
-			continue;
-		}
-
-		v4l2_ctrl_cluster(cluster_size, cluster);
-
-		temp = kzalloc(sizeof(*temp), GFP_KERNEL);
-		if (!temp) {
-			ret_val = -ENOMEM;
-			break;
-		}
-
-		temp->cluster = cluster;
-		INIT_LIST_HEAD(&temp->list);
-		list_add_tail(&temp->list, &inst->ctrl_clusters);
-	}
-	return ret_val;
-}
-
-int msm_vdec_ctrl_deinit(struct msm_vidc_inst *inst)
-{
-	struct msm_vidc_ctrl_cluster *curr, *next;
-	list_for_each_entry_safe(curr, next, &inst->ctrl_clusters, list) {
-		kfree(curr->cluster);
-		kfree(curr);
-	}
-
-	return 0;
-}
diff --git a/drivers/media/video/msm_vidc/msm_vdec.h b/drivers/media/video/msm_vidc/msm_vdec.h
deleted file mode 100644
index 73a516e..0000000
--- a/drivers/media/video/msm_vidc/msm_vdec.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 _MSM_VDEC_H_
-#define _MSM_VDEC_H_
-
-#include <media/msm_vidc.h>
-#include "msm_vidc_internal.h"
-
-int msm_vdec_inst_init(struct msm_vidc_inst *inst);
-int msm_vdec_ctrl_init(struct msm_vidc_inst *inst);
-int msm_vdec_ctrl_deinit(struct msm_vidc_inst *inst);
-int msm_vdec_querycap(void *instance, struct v4l2_capability *cap);
-int msm_vdec_enum_fmt(void *instance, struct v4l2_fmtdesc *f);
-int msm_vdec_s_fmt(void *instance, struct v4l2_format *f);
-int msm_vdec_g_fmt(void *instance, struct v4l2_format *f);
-int msm_vdec_s_ctrl(void *instance, struct v4l2_control *a);
-int msm_vdec_g_ctrl(void *instance, struct v4l2_control *a);
-int msm_vdec_reqbufs(void *instance, struct v4l2_requestbuffers *b);
-int msm_vdec_prepare_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
-int msm_vdec_release_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
-int msm_vdec_qbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
-int msm_vdec_dqbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
-int msm_vdec_streamon(struct msm_vidc_inst *inst, enum v4l2_buf_type i);
-int msm_vdec_streamoff(struct msm_vidc_inst *inst, enum v4l2_buf_type i);
-int msm_vdec_cmd(struct msm_vidc_inst *inst, struct v4l2_decoder_cmd *dec);
-int msm_vdec_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a);
-struct vb2_ops *msm_vdec_get_vb2q_ops(void);
-
-#endif
diff --git a/drivers/media/video/msm_vidc/msm_venc.c b/drivers/media/video/msm_vidc/msm_venc.c
deleted file mode 100644
index 0fa56b7..0000000
--- a/drivers/media/video/msm_vidc/msm_venc.c
+++ /dev/null
@@ -1,2023 +0,0 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-#include <linux/slab.h>
-
-#include "msm_vidc_internal.h"
-#include "msm_vidc_common.h"
-#include "vidc_hal_api.h"
-#include "msm_smem.h"
-#include "msm_vidc_debug.h"
-
-#define MSM_VENC_DVC_NAME "msm_venc_8974"
-#define DEFAULT_HEIGHT 720
-#define DEFAULT_WIDTH 1280
-#define MIN_NUM_OUTPUT_BUFFERS 4
-#define MAX_NUM_OUTPUT_BUFFERS 8
-#define MIN_BIT_RATE 64000
-#define MAX_BIT_RATE 160000000
-#define DEFAULT_BIT_RATE 64000
-#define BIT_RATE_STEP 100
-#define MIN_FRAME_RATE 65536
-#define MAX_FRAME_RATE 15728640
-#define DEFAULT_FRAME_RATE 1966080
-#define DEFAULT_IR_MBS 30
-#define MAX_SLICE_BYTE_SIZE 1024
-#define MIN_SLICE_BYTE_SIZE 1024
-#define MAX_SLICE_MB_SIZE 300
-#define I_FRAME_QP 26
-#define P_FRAME_QP 28
-#define B_FRAME_QP 30
-#define MAX_INTRA_REFRESH_MBS 300
-#define L_MODE V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY
-#define CODING V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY
-
-static const char *const mpeg_video_rate_control[] = {
-	"No Rate Control",
-	"VBR VFR",
-	"VBR CFR",
-	"CBR VFR",
-	"CBR CFR",
-	NULL
-};
-
-static const char *const mpeg_video_rotation[] = {
-	"No Rotation",
-	"90 Degree Rotation",
-	"180 Degree Rotation",
-	"270 Degree Rotation",
-	NULL
-};
-
-static const char *const h264_video_entropy_cabac_model[] = {
-	"Model 0",
-	"Model 1",
-	"Model 2",
-	NULL
-};
-
-static const char *const h263_level[] = {
-	"1.0",
-	"2.0",
-	"3.0",
-	"4.0",
-	"4.5",
-	"5.0",
-	"6.0",
-	"7.0",
-};
-
-static const char *const h263_profile[] = {
-	"Baseline",
-	"H320 Coding",
-	"Backward Compatible",
-	"ISWV2",
-	"ISWV3",
-	"High Compression",
-	"Internet",
-	"Interlace",
-	"High Latency",
-};
-
-enum msm_venc_ctrl_cluster {
-	MSM_VENC_CTRL_CLUSTER_QP = 1,
-	MSM_VENC_CTRL_CLUSTER_INTRA_PERIOD,
-	MSM_VENC_CTRL_CLUSTER_H264_PROFILE_LEVEL,
-	MSM_VENC_CTRL_CLUSTER_MPEG_PROFILE_LEVEL,
-	MSM_VENC_CTRL_CLUSTER_H263_PROFILE_LEVEL,
-	MSM_VENC_CTRL_CLUSTER_H264_ENTROPY,
-	MSM_VENC_CTRL_CLUSTER_SLICING,
-	MSM_VENC_CTRL_CLUSTER_INTRA_REFRESH,
-	MSM_VENC_CTRL_CLUSTER_BITRATE,
-	MSM_VENC_CTRL_CLUSTER_MAX,
-};
-
-static struct msm_vidc_ctrl msm_venc_ctrls[] = {
-	{
-		.id = V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE,
-		.name = "Frame Rate",
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.minimum = MIN_FRAME_RATE,
-		.maximum = MAX_FRAME_RATE,
-		.default_value = MIN_FRAME_RATE,
-		.step = 1,
-		.menu_skip_mask = 0,
-		.qmenu = NULL,
-		.cluster = 0,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD,
-		.name = "IDR Period",
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.minimum = 1,
-		.maximum = 10*MAX_FRAME_RATE,
-		.default_value = DEFAULT_FRAME_RATE,
-		.step = 1,
-		.menu_skip_mask = 0,
-		.qmenu = NULL,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDEO_H264_I_PERIOD,
-		.name = "Intra Period",
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.minimum = 1,
-		.maximum = 10*MAX_FRAME_RATE,
-		.default_value = DEFAULT_FRAME_RATE,
-		.step = 1,
-		.menu_skip_mask = 0,
-		.qmenu = NULL,
-		.cluster = MSM_VENC_CTRL_CLUSTER_INTRA_PERIOD,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES,
-		.name = "Intra Period for P frames",
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.minimum = 0,
-		.maximum = 10*DEFAULT_FRAME_RATE,
-		.default_value = 2*DEFAULT_FRAME_RATE-1,
-		.step = 1,
-		.menu_skip_mask = 0,
-		.qmenu = NULL,
-		.cluster = MSM_VENC_CTRL_CLUSTER_INTRA_PERIOD,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES,
-		.name = "Intra Period for B frames",
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.minimum = 0,
-		.maximum = 2,
-		.default_value = 0,
-		.step = 1,
-		.menu_skip_mask = 0,
-		.qmenu = NULL,
-		.cluster = MSM_VENC_CTRL_CLUSTER_INTRA_PERIOD,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME,
-		.name = "Request I Frame",
-		.type = V4L2_CTRL_TYPE_BUTTON,
-		.minimum = 0,
-		.maximum = 0,
-		.default_value = 0,
-		.step = 0,
-		.menu_skip_mask = 0,
-		.qmenu = NULL,
-		.cluster = 0,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL,
-		.name = "Video Framerate and Bitrate Control",
-		.type = V4L2_CTRL_TYPE_MENU,
-		.minimum = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF,
-		.maximum = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR,
-		.default_value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF,
-		.step = 0,
-		.menu_skip_mask = ~(
-		(1 << V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF) |
-		(1 << V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR) |
-		(1 << V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR) |
-		(1 << V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR) |
-		(1 << V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR)
-		),
-		.qmenu = mpeg_video_rate_control,
-		.cluster = MSM_VENC_CTRL_CLUSTER_BITRATE,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
-		.name = "Bitrate Control",
-		.type = V4L2_CTRL_TYPE_MENU,
-		.minimum = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
-		.maximum = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
-		.default_value = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
-		.step = 0,
-		.menu_skip_mask = ~(
-		(1 << V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) |
-		(1 << V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
-		),
-		.qmenu = mpeg_video_rate_control,
-		.cluster = MSM_VENC_CTRL_CLUSTER_BITRATE,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDEO_BITRATE,
-		.name = "Bit Rate",
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.minimum = MIN_BIT_RATE,
-		.maximum = MAX_BIT_RATE,
-		.default_value = DEFAULT_BIT_RATE,
-		.step = BIT_RATE_STEP,
-		.menu_skip_mask = 0,
-		.qmenu = NULL,
-		.cluster = MSM_VENC_CTRL_CLUSTER_BITRATE,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE,
-		.name = "Entropy Mode",
-		.type = V4L2_CTRL_TYPE_MENU,
-		.minimum = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,
-		.maximum = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,
-		.default_value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,
-		.step = 0,
-		.menu_skip_mask = ~(
-		(1 << V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC) |
-		(1 << V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC)
-		),
-		.cluster = MSM_VENC_CTRL_CLUSTER_H264_ENTROPY,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL,
-		.name = "CABAC Model",
-		.type = V4L2_CTRL_TYPE_MENU,
-		.minimum = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0,
-		.maximum = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_1,
-		.default_value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0,
-		.step = 0,
-		.menu_skip_mask = ~(
-		(1 << V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0) |
-		(1 << V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_1) |
-		(1 << V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_2)
-		),
-		.qmenu = h264_video_entropy_cabac_model,
-		.cluster = MSM_VENC_CTRL_CLUSTER_H264_ENTROPY,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE,
-		.name = "MPEG4 Profile",
-		.type = V4L2_CTRL_TYPE_MENU,
-		.minimum = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE,
-		.maximum = CODING,
-		.default_value = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE,
-		.step = 1,
-		.menu_skip_mask = 0,
-		.cluster = MSM_VENC_CTRL_CLUSTER_MPEG_PROFILE_LEVEL,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL,
-		.name = "MPEG4 Level",
-		.type = V4L2_CTRL_TYPE_MENU,
-		.minimum = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0,
-		.maximum = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5,
-		.default_value = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0,
-		.step = 1,
-		.menu_skip_mask = 0,
-		.cluster = MSM_VENC_CTRL_CLUSTER_MPEG_PROFILE_LEVEL,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE,
-		.name = "H264 Profile",
-		.type = V4L2_CTRL_TYPE_MENU,
-		.minimum = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
-		.maximum = V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH,
-		.default_value = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
-		.step = 1,
-		.menu_skip_mask = 0,
-		.cluster = MSM_VENC_CTRL_CLUSTER_H264_PROFILE_LEVEL,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL,
-		.name = "H264 Level",
-		.type = V4L2_CTRL_TYPE_MENU,
-		.minimum = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
-		.maximum = V4L2_MPEG_VIDEO_H264_LEVEL_5_1,
-		.default_value = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
-		.step = 0,
-		.menu_skip_mask = 0,
-		.cluster = MSM_VENC_CTRL_CLUSTER_H264_PROFILE_LEVEL,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE,
-		.name = "H263 Profile",
-		.type = V4L2_CTRL_TYPE_MENU,
-		.minimum = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE,
-		.maximum = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY,
-		.default_value = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE,
-		.menu_skip_mask = ~(
-		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE) |
-		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING) |
-		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE) |
-		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2) |
-		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3) |
-		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION) |
-		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET) |
-		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE) |
-		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY)
-		),
-		.qmenu = h263_profile,
-		.cluster = MSM_VENC_CTRL_CLUSTER_H263_PROFILE_LEVEL,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL,
-		.name = "H263 Level",
-		.type = V4L2_CTRL_TYPE_MENU,
-		.minimum = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0,
-		.maximum = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0,
-		.default_value = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0,
-		.menu_skip_mask = ~(
-		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0) |
-		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0) |
-		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0) |
-		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0) |
-		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0) |
-		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0) |
-		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0)
-		),
-		.qmenu = h263_level,
-		.cluster = MSM_VENC_CTRL_CLUSTER_H263_PROFILE_LEVEL,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION,
-		.name = "Rotation",
-		.type = V4L2_CTRL_TYPE_MENU,
-		.minimum = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_NONE,
-		.maximum = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_270,
-		.default_value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_NONE,
-		.step = 0,
-		.menu_skip_mask = ~(
-		(1 << V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_NONE) |
-		(1 << V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_90) |
-		(1 << V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_180) |
-		(1 << V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_270)
-		),
-		.qmenu = mpeg_video_rotation,
-		.cluster = 0,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP,
-		.name = "I Frame Quantization",
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.minimum = 1,
-		.maximum = 51,
-		.default_value = I_FRAME_QP,
-		.step = 1,
-		.menu_skip_mask = 0,
-		.qmenu = NULL,
-		.cluster = MSM_VENC_CTRL_CLUSTER_QP,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP,
-		.name = "P Frame Quantization",
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.minimum = 1,
-		.maximum = 51,
-		.default_value = P_FRAME_QP,
-		.step = 1,
-		.menu_skip_mask = 0,
-		.qmenu = NULL,
-		.cluster = MSM_VENC_CTRL_CLUSTER_QP,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP,
-		.name = "B Frame Quantization",
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.minimum = 1,
-		.maximum = 51,
-		.default_value = B_FRAME_QP,
-		.step = 1,
-		.menu_skip_mask = 0,
-		.qmenu = NULL,
-		.cluster = MSM_VENC_CTRL_CLUSTER_QP,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE,
-		.name = "Slice Mode",
-		.type = V4L2_CTRL_TYPE_MENU,
-		.minimum = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
-		.maximum = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES,
-		.default_value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
-		.step = 1,
-		.menu_skip_mask = 0,
-		.cluster = MSM_VENC_CTRL_CLUSTER_SLICING,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES,
-		.name = "Slice Byte Size",
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.minimum = MIN_SLICE_BYTE_SIZE,
-		.maximum = MAX_SLICE_BYTE_SIZE,
-		.default_value = 0,
-		.step = 1,
-		.menu_skip_mask = 0,
-		.qmenu = NULL,
-		.cluster = MSM_VENC_CTRL_CLUSTER_SLICING,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB,
-		.name = "Slice MB Size",
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.minimum = 1,
-		.maximum = MAX_SLICE_MB_SIZE,
-		.default_value = 0,
-		.step = 1,
-		.menu_skip_mask = 0,
-		.qmenu = NULL,
-		.cluster = MSM_VENC_CTRL_CLUSTER_SLICING,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE,
-		.name = "Intra Refresh Mode",
-		.type = V4L2_CTRL_TYPE_MENU,
-		.minimum = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_NONE,
-		.maximum = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM,
-		.default_value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_NONE,
-		.step = 0,
-		.menu_skip_mask = ~(
-		(1 << V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_NONE) |
-		(1 << V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC) |
-		(1 << V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_ADAPTIVE) |
-		(1 << V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC_ADAPTIVE) |
-		(1 << V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM)
-		),
-		.cluster = MSM_VENC_CTRL_CLUSTER_INTRA_REFRESH,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS,
-		.name = "Intra Refresh AIR MBS",
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.minimum = 0,
-		.maximum = MAX_INTRA_REFRESH_MBS,
-		.default_value = 0,
-		.step = 1,
-		.menu_skip_mask = 0,
-		.qmenu = NULL,
-		.cluster = MSM_VENC_CTRL_CLUSTER_INTRA_REFRESH,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF,
-		.name = "Intra Refresh AIR REF",
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.minimum = 0,
-		.maximum = MAX_INTRA_REFRESH_MBS,
-		.default_value = 0,
-		.step = 1,
-		.menu_skip_mask = 0,
-		.qmenu = NULL,
-		.cluster = MSM_VENC_CTRL_CLUSTER_INTRA_REFRESH,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS,
-		.name = "Intra Refresh CIR MBS",
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.minimum = 0,
-		.maximum = MAX_INTRA_REFRESH_MBS,
-		.default_value = 0,
-		.step = 1,
-		.menu_skip_mask = 0,
-		.qmenu = NULL,
-		.cluster = MSM_VENC_CTRL_CLUSTER_INTRA_REFRESH,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA,
-		.name = "H.264 Loop Filter Alpha Offset",
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.minimum = -6,
-		.maximum = 6,
-		.default_value = 0,
-		.step = 1,
-		.menu_skip_mask = 0,
-		.qmenu = NULL,
-		.cluster = 0,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA,
-		.name = "H.264 Loop Filter Beta Offset",
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.minimum = -6,
-		.maximum = 6,
-		.default_value = 0,
-		.step = 1,
-		.menu_skip_mask = 0,
-		.qmenu = NULL,
-		.cluster = 0,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE,
-		.name = "H.264 Loop Filter Mode",
-		.type = V4L2_CTRL_TYPE_MENU,
-		.minimum = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED,
-		.maximum = L_MODE,
-		.default_value = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED,
-		.step = 1,
-		.menu_skip_mask = ~(
-		(1 << V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED) |
-		(1 << V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED) |
-		(1 << L_MODE)
-		),
-		.cluster = 0,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE,
-		.name = "Sequence Header Mode",
-		.type = V4L2_CTRL_TYPE_MENU,
-		.minimum = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE,
-		.maximum = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME,
-		.default_value =
-			V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME,
-		.step = 1,
-		.menu_skip_mask = ~(
-		(1 << V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) |
-		(1 << V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME)
-		),
-		.qmenu = NULL,
-		.cluster = 0,
-	}
-};
-
-#define NUM_CTRLS ARRAY_SIZE(msm_venc_ctrls)
-
-static u32 get_frame_size_nv12(int plane, u32 height, u32 width)
-{
-	return VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
-}
-
-static u32 get_frame_size_nv21(int plane, u32 height, u32 width)
-{
-	return height * width * 2;
-}
-
-static u32 get_frame_size_compressed(int plane, u32 height, u32 width)
-{
-	int sz = ((height + 31) & (~31)) * ((width + 31) & (~31)) * 3/2;
-	sz = (sz + 4095) & (~4095);
-	return sz;
-}
-
-static const struct msm_vidc_format venc_formats[] = {
-	{
-		.name = "YCbCr Semiplanar 4:2:0",
-		.description = "Y/CbCr 4:2:0",
-		.fourcc = V4L2_PIX_FMT_NV12,
-		.num_planes = 1,
-		.get_frame_size = get_frame_size_nv12,
-		.type = OUTPUT_PORT,
-	},
-	{
-		.name = "Mpeg4",
-		.description = "Mpeg4 compressed format",
-		.fourcc = V4L2_PIX_FMT_MPEG4,
-		.num_planes = 1,
-		.get_frame_size = get_frame_size_compressed,
-		.type = CAPTURE_PORT,
-	},
-	{
-		.name = "H263",
-		.description = "H263 compressed format",
-		.fourcc = V4L2_PIX_FMT_H263,
-		.num_planes = 1,
-		.get_frame_size = get_frame_size_compressed,
-		.type = CAPTURE_PORT,
-	},
-	{
-		.name = "H264",
-		.description = "H264 compressed format",
-		.fourcc = V4L2_PIX_FMT_H264,
-		.num_planes = 1,
-		.get_frame_size = get_frame_size_compressed,
-		.type = CAPTURE_PORT,
-	},
-	{
-		.name = "VP8",
-		.description = "VP8 compressed format",
-		.fourcc = V4L2_PIX_FMT_VP8,
-		.num_planes = 1,
-		.get_frame_size = get_frame_size_compressed,
-		.type = CAPTURE_PORT,
-	},
-	{
-		.name = "YCrCb Semiplanar 4:2:0",
-		.description = "Y/CrCb 4:2:0",
-		.fourcc = V4L2_PIX_FMT_NV21,
-		.num_planes = 1,
-		.get_frame_size = get_frame_size_nv21,
-		.type = OUTPUT_PORT,
-	},
-};
-
-static int msm_venc_queue_setup(struct vb2_queue *q,
-				const struct v4l2_format *fmt,
-				unsigned int *num_buffers,
-				unsigned int *num_planes, unsigned int sizes[],
-				void *alloc_ctxs[])
-{
-	int i, rc = 0;
-	struct msm_vidc_inst *inst;
-	struct hal_buffer_count_actual new_buf_count;
-	enum hal_property property_id;
-	unsigned long flags;
-	if (!q || !q->drv_priv) {
-		dprintk(VIDC_ERR, "Invalid input, q = %p\n", q);
-		return -EINVAL;
-	}
-	inst = q->drv_priv;
-	switch (q->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
-		*num_planes = 1;
-		if (*num_buffers < MIN_NUM_OUTPUT_BUFFERS ||
-				*num_buffers > MAX_NUM_OUTPUT_BUFFERS)
-			*num_buffers = MIN_NUM_OUTPUT_BUFFERS;
-		for (i = 0; i < *num_planes; i++) {
-			sizes[i] = inst->fmts[CAPTURE_PORT]->get_frame_size(
-					i, inst->prop.height, inst->prop.width);
-		}
-		break;
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-		rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
-		if (rc) {
-			dprintk(VIDC_ERR, "Failed to open instance\n");
-			break;
-		}
-		rc = msm_comm_try_get_bufreqs(inst);
-		if (rc) {
-			dprintk(VIDC_ERR,
-				"Failed to get buffer requirements: %d\n", rc);
-			break;
-		}
-		*num_planes = 1;
-		spin_lock_irqsave(&inst->lock, flags);
-		*num_buffers = inst->buff_req.buffer[0].buffer_count_actual =
-			max(*num_buffers, inst->buff_req.buffer[0].
-				buffer_count_actual);
-		spin_unlock_irqrestore(&inst->lock, flags);
-		property_id = HAL_PARAM_BUFFER_COUNT_ACTUAL;
-		new_buf_count.buffer_type = HAL_BUFFER_INPUT;
-		new_buf_count.buffer_count_actual = *num_buffers;
-		rc = vidc_hal_session_set_property(inst->session,
-					property_id, &new_buf_count);
-		dprintk(VIDC_DBG, "size = %d, alignment = %d, count = %d\n",
-				inst->buff_req.buffer[0].buffer_size,
-				inst->buff_req.buffer[0].buffer_alignment,
-				inst->buff_req.buffer[0].buffer_count_actual);
-		for (i = 0; i < *num_planes; i++) {
-			sizes[i] = inst->fmts[OUTPUT_PORT]->get_frame_size(
-					i, inst->prop.height, inst->prop.width);
-		}
-		break;
-	default:
-		dprintk(VIDC_ERR, "Invalid q type = %d\n", q->type);
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
-
-static inline int start_streaming(struct msm_vidc_inst *inst)
-{
-	int rc = 0;
-	struct vb2_buf_entry *temp;
-	struct list_head *ptr, *next;
-
-	rc = msm_comm_try_get_bufreqs(inst);
-	if (rc) {
-		dprintk(VIDC_ERR,
-			"Failed to get Buffer Requirements : %d\n", rc);
-		goto fail_start;
-	}
-	rc = msm_comm_set_scratch_buffers(inst);
-	if (rc) {
-		dprintk(VIDC_ERR, "Failed to set scratch buffers: %d\n", rc);
-		goto fail_start;
-	}
-	rc = msm_comm_set_persist_buffers(inst);
-	if (rc) {
-		dprintk(VIDC_ERR, "Failed to set persist buffers: %d\n", rc);
-		goto fail_start;
-	}
-	msm_comm_scale_clocks_and_bus(inst);
-
-	rc = msm_comm_try_state(inst, MSM_VIDC_START_DONE);
-	if (rc) {
-		dprintk(VIDC_ERR,
-			"Failed to move inst: %p to start done state\n", inst);
-		goto fail_start;
-	}
-	mutex_lock(&inst->sync_lock);
-	if (!list_empty(&inst->pendingq)) {
-		list_for_each_safe(ptr, next, &inst->pendingq) {
-			temp = list_entry(ptr, struct vb2_buf_entry, list);
-			rc = msm_comm_qbuf(temp->vb);
-			if (rc) {
-				dprintk(VIDC_ERR,
-					"Failed to qbuf to hardware\n");
-				break;
-			}
-			list_del(&temp->list);
-			kfree(temp);
-		}
-	}
-	mutex_unlock(&inst->sync_lock);
-	return rc;
-fail_start:
-	return rc;
-}
-
-static int msm_venc_start_streaming(struct vb2_queue *q, unsigned int count)
-{
-	struct msm_vidc_inst *inst;
-	int rc = 0;
-	if (!q || !q->drv_priv) {
-		dprintk(VIDC_ERR, "Invalid input, q = %p\n", q);
-		return -EINVAL;
-	}
-	inst = q->drv_priv;
-	dprintk(VIDC_DBG, "Streamon called on: %d capability\n", q->type);
-	switch (q->type) {
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-		if (inst->bufq[CAPTURE_PORT].vb2_bufq.streaming)
-			rc = start_streaming(inst);
-		break;
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
-		if (inst->bufq[OUTPUT_PORT].vb2_bufq.streaming)
-			rc = start_streaming(inst);
-		break;
-	default:
-		dprintk(VIDC_ERR, "Q-type is not supported: %d\n", q->type);
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
-
-static int msm_venc_stop_streaming(struct vb2_queue *q)
-{
-	struct msm_vidc_inst *inst;
-	int rc = 0;
-	if (!q || !q->drv_priv) {
-		dprintk(VIDC_ERR, "Invalid input, q = %p\n", q);
-		return -EINVAL;
-	}
-	inst = q->drv_priv;
-	dprintk(VIDC_DBG, "Streamoff called on: %d capability\n", q->type);
-	switch (q->type) {
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-		break;
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
-		rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
-		break;
-	default:
-		dprintk(VIDC_ERR, "Q-type is not supported: %d\n", q->type);
-		rc = -EINVAL;
-		break;
-	}
-	msm_comm_scale_clocks_and_bus(inst);
-
-	if (rc)
-		dprintk(VIDC_ERR,
-			"Failed to move inst: %p, cap = %d to state: %d\n",
-			inst, q->type, MSM_VIDC_CLOSE_DONE);
-	return rc;
-}
-
-static void msm_venc_buf_queue(struct vb2_buffer *vb)
-{
-	int rc;
-	rc = msm_comm_qbuf(vb);
-	if (rc)
-		dprintk(VIDC_ERR, "Failed to queue buffer: %d\n", rc);
-}
-
-static const struct vb2_ops msm_venc_vb2q_ops = {
-	.queue_setup = msm_venc_queue_setup,
-	.start_streaming = msm_venc_start_streaming,
-	.buf_queue = msm_venc_buf_queue,
-	.stop_streaming = msm_venc_stop_streaming,
-};
-
-const struct vb2_ops *msm_venc_get_vb2q_ops(void)
-{
-	return &msm_venc_vb2q_ops;
-}
-
-static struct v4l2_ctrl *get_ctrl_from_cluster(int id,
-		struct v4l2_ctrl **cluster, int ncontrols)
-{
-	int c;
-
-	for (c = 0; c < ncontrols; ++c)
-		if (cluster[c]->id == id)
-			return cluster[c];
-	return NULL;
-}
-
-/* Helper function to translate V4L2_* to HAL_* */
-static inline int venc_v4l2_to_hal(int id, int value)
-{
-	switch (id) {
-	/* MPEG4 */
-	case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
-		switch (value) {
-		case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0:
-			return HAL_MPEG4_LEVEL_0;
-		case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B:
-			return HAL_MPEG4_LEVEL_0b;
-		case V4L2_MPEG_VIDEO_MPEG4_LEVEL_1:
-			return HAL_MPEG4_LEVEL_1;
-		case V4L2_MPEG_VIDEO_MPEG4_LEVEL_2:
-			return HAL_MPEG4_LEVEL_2;
-		case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3:
-			return HAL_MPEG4_LEVEL_3;
-		case V4L2_MPEG_VIDEO_MPEG4_LEVEL_4:
-			return HAL_MPEG4_LEVEL_4;
-		case V4L2_MPEG_VIDEO_MPEG4_LEVEL_5:
-			return HAL_MPEG4_LEVEL_5;
-		default:
-			goto unknown_value;
-		}
-	case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
-		switch (value) {
-		case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
-			return HAL_MPEG4_PROFILE_SIMPLE;
-		case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
-			return HAL_MPEG4_PROFILE_ADVANCEDSIMPLE;
-		default:
-			goto unknown_value;
-		}
-	/* H264 */
-	case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
-		switch (value) {
-		case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
-			return HAL_H264_PROFILE_BASELINE;
-		case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
-			return HAL_H264_PROFILE_MAIN;
-		case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
-			return HAL_H264_PROFILE_EXTENDED;
-		case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
-			return HAL_H264_PROFILE_HIGH;
-		case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
-			return HAL_H264_PROFILE_HIGH10;
-		case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
-			return HAL_H264_PROFILE_HIGH422;
-		case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
-			return HAL_H264_PROFILE_HIGH444;
-		default:
-			goto unknown_value;
-		}
-	case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
-		switch (value) {
-		case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
-			return HAL_H264_LEVEL_1;
-		case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
-			return HAL_H264_LEVEL_1b;
-		case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
-			return HAL_H264_LEVEL_11;
-		case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
-			return HAL_H264_LEVEL_12;
-		case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
-			return HAL_H264_LEVEL_13;
-		case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
-			return HAL_H264_LEVEL_2;
-		case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
-			return HAL_H264_LEVEL_21;
-		case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
-			return HAL_H264_LEVEL_22;
-		case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
-			return HAL_H264_LEVEL_3;
-		case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
-			return HAL_H264_LEVEL_31;
-		case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
-			return HAL_H264_LEVEL_32;
-		case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
-			return HAL_H264_LEVEL_4;
-		case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
-			return HAL_H264_LEVEL_41;
-		case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
-			return HAL_H264_LEVEL_42;
-		case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
-			return HAL_H264_LEVEL_3;
-		case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
-			return HAL_H264_LEVEL_51;
-		default:
-			goto unknown_value;
-		}
-		/* H263 */
-	case V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE:
-		switch (value) {
-		case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE:
-			return HAL_H263_PROFILE_BASELINE;
-		case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING:
-			return HAL_H263_PROFILE_H320CODING;
-		case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE:
-			return HAL_H263_PROFILE_BACKWARDCOMPATIBLE;
-		case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2:
-			return HAL_H263_PROFILE_ISWV2;
-		case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3:
-			return HAL_H263_PROFILE_ISWV3;
-		case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION:
-			return HAL_H263_PROFILE_HIGHCOMPRESSION;
-		case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET:
-			return HAL_H263_PROFILE_INTERNET;
-		case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE:
-			return HAL_H263_PROFILE_INTERLACE;
-		case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY:
-			return HAL_H263_PROFILE_HIGHLATENCY;
-		default:
-			goto unknown_value;
-		}
-	case V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL:
-		switch (value) {
-		case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0:
-			return HAL_H263_LEVEL_10;
-		case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0:
-			return HAL_H263_LEVEL_20;
-		case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0:
-			return HAL_H263_LEVEL_30;
-		case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0:
-			return HAL_H263_LEVEL_40;
-		case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_5:
-			return HAL_H263_LEVEL_45;
-		case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0:
-			return HAL_H263_LEVEL_50;
-		case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0:
-			return HAL_H263_LEVEL_60;
-		case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0:
-			return HAL_H263_LEVEL_70;
-		default:
-			goto unknown_value;
-		}
-	}
-
-unknown_value:
-	dprintk(VIDC_WARN, "Unknown control (%x, %d)", id, value);
-	return -EINVAL;
-}
-
-static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
-{
-	int rc = 0;
-	struct hal_frame_rate frame_rate;
-	struct hal_request_iframe request_iframe;
-	struct hal_bitrate bitrate;
-	struct hal_profile_level profile_level;
-	struct hal_h264_entropy_control h264_entropy_control;
-	struct hal_quantization quantization;
-	struct hal_intra_period intra_period;
-	struct hal_idr_period idr_period;
-	struct hal_operations operations;
-	struct hal_intra_refresh intra_refresh;
-	struct hal_multi_slice_control multi_slice_control;
-	struct hal_h264_db_control h264_db_control;
-	struct hal_enable enable;
-	u32 property_id = 0, property_val = 0;
-	void *pdata;
-	struct v4l2_ctrl *temp_ctrl = NULL;
-
-	/* Small helper macro for quickly getting a control and err checking */
-#define TRY_GET_CTRL(__ctrl_id) ({ \
-		struct v4l2_ctrl *__temp; \
-		__temp = get_ctrl_from_cluster( \
-			__ctrl_id, \
-			ctrl->cluster, ctrl->ncontrols); \
-		if (!__temp) { \
-			dprintk(VIDC_ERR, "Can't find %s (%x) in cluster", \
-				#__ctrl_id, __ctrl_id); \
-			rc = -ENOENT; \
-			break; \
-		} \
-		__temp; \
-	})
-
-	switch (ctrl->id) {
-	case V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE:
-		property_id =
-			HAL_CONFIG_FRAME_RATE;
-		frame_rate.frame_rate = ctrl->val;
-		frame_rate.buffer_type = HAL_BUFFER_OUTPUT;
-		pdata = &frame_rate;
-		break;
-	case V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD:
-		property_id =
-			HAL_CONFIG_VENC_IDR_PERIOD;
-		idr_period.idr_period = ctrl->val;
-		pdata = &idr_period;
-		break;
-	case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD: {
-		struct v4l2_ctrl *b;
-		b = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES);
-
-		if (inst->fmts[CAPTURE_PORT]->fourcc != V4L2_PIX_FMT_H264 &&
-			inst->fmts[CAPTURE_PORT]->fourcc !=
-				V4L2_PIX_FMT_H264_NO_SC) {
-			dprintk(VIDC_ERR, "Control 0x%x only valid for H264",
-					ctrl->id);
-			rc = -ENOTSUPP;
-			break;
-		}
-
-		/*
-		 * We can't set the I-period explicitly. So set it implicitly
-		 * by setting the number of P and B frames per I-period
-		 */
-		property_id = HAL_CONFIG_VENC_INTRA_PERIOD;
-		intra_period.pframes = (ctrl->val - 1) - b->val;
-		intra_period.bframes = b->val;
-		pdata = &intra_period;
-		break;
-	}
-	case V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES:
-		temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES);
-
-		property_id =
-			HAL_CONFIG_VENC_INTRA_PERIOD;
-		intra_period.pframes = ctrl->val;
-		intra_period.bframes = temp_ctrl->val;
-		pdata = &intra_period;
-		break;
-	case V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES:
-		temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES);
-
-		property_id =
-			HAL_CONFIG_VENC_INTRA_PERIOD;
-		intra_period.bframes = ctrl->val;
-		intra_period.pframes = temp_ctrl->val;
-		pdata = &intra_period;
-		break;
-	case V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME:
-		property_id =
-			HAL_CONFIG_VENC_REQUEST_IFRAME;
-		request_iframe.enable = true;
-		pdata = &request_iframe;
-		break;
-	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
-	{
-		bool cfr = true, cbr = true;
-		int final_mode = 0;
-
-		temp_ctrl = TRY_GET_CTRL(
-			V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL);
-
-		switch (temp_ctrl->val) {
-		case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF:
-			/* Let's assume CFR */
-		case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR:
-		case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR:
-			cfr = true;
-			break;
-		case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR:
-		case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR:
-			cfr = false;
-			break;
-		default:
-			dprintk(VIDC_WARN, "Unknown framerate mode");
-		}
-
-		switch (ctrl->val) {
-		case V4L2_MPEG_VIDEO_BITRATE_MODE_VBR:
-			cbr = false;
-			break;
-		case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR:
-			cbr = true;
-			break;
-		default:
-			dprintk(VIDC_WARN, "Unknown bitrate mode");
-		}
-
-		if (!cfr && !cbr)
-			final_mode =
-				V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR;
-		else if (!cfr && cbr)
-			final_mode =
-				V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR;
-		else if (cfr && !cbr)
-			final_mode =
-				V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR;
-		else /* ... if (cfr && cbr) */
-			final_mode =
-				V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR;
-
-		property_id = HAL_PARAM_VENC_RATE_CONTROL;
-		property_val = final_mode;
-		pdata = &property_val;
-		break;
-	}
-	case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL:
-		property_id = HAL_PARAM_VENC_RATE_CONTROL;
-		property_val = ctrl->val;
-		pdata = &property_val;
-		break;
-	case V4L2_CID_MPEG_VIDEO_BITRATE:
-		property_id =
-			HAL_CONFIG_VENC_TARGET_BITRATE;
-		bitrate.bit_rate = ctrl->val;
-		pdata = &bitrate;
-		break;
-	case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
-		temp_ctrl = TRY_GET_CTRL(
-			V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL);
-
-		property_id =
-			HAL_PARAM_VENC_H264_ENTROPY_CONTROL;
-		h264_entropy_control.entropy_mode = ctrl->val;
-		h264_entropy_control.cabac_model = temp_ctrl->val;
-		pdata = &h264_entropy_control;
-		break;
-	case V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL:
-		temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE);
-
-		property_id =
-			HAL_PARAM_VENC_H264_ENTROPY_CONTROL;
-		h264_entropy_control.cabac_model = ctrl->val;
-		h264_entropy_control.entropy_mode = temp_ctrl->val;
-		pdata = &h264_entropy_control;
-		break;
-	case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
-		temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL);
-
-		property_id =
-			HAL_PARAM_PROFILE_LEVEL_CURRENT;
-		profile_level.profile =  venc_v4l2_to_hal(ctrl->id,
-						ctrl->val);
-		profile_level.level = venc_v4l2_to_hal(
-				V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL,
-				temp_ctrl->val);
-		pdata = &profile_level;
-		break;
-	case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
-		temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE);
-
-		property_id =
-			HAL_PARAM_PROFILE_LEVEL_CURRENT;
-		profile_level.level = venc_v4l2_to_hal(ctrl->id,
-							ctrl->val);
-		profile_level.profile = venc_v4l2_to_hal(
-				V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE,
-				temp_ctrl->val);
-		pdata = &profile_level;
-		break;
-	case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
-		temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_LEVEL);
-
-		property_id =
-			HAL_PARAM_PROFILE_LEVEL_CURRENT;
-		profile_level.profile = venc_v4l2_to_hal(ctrl->id,
-							ctrl->val);
-		profile_level.level = venc_v4l2_to_hal(
-				V4L2_CID_MPEG_VIDEO_H264_LEVEL,
-				temp_ctrl->val);
-		pdata = &profile_level;
-		dprintk(VIDC_DBG, "\nprofile: %d\n",
-			   profile_level.profile);
-		break;
-	case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
-		temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_PROFILE);
-
-		property_id =
-			HAL_PARAM_PROFILE_LEVEL_CURRENT;
-		profile_level.level = venc_v4l2_to_hal(ctrl->id,
-							ctrl->val);
-		profile_level.profile = venc_v4l2_to_hal(
-				V4L2_CID_MPEG_VIDEO_H264_PROFILE,
-				temp_ctrl->val);
-		pdata = &profile_level;
-		dprintk(VIDC_DBG, "\nLevel: %d\n",
-			   profile_level.level);
-		break;
-	case V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE:
-		temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL);
-
-		property_id =
-			HAL_PARAM_PROFILE_LEVEL_CURRENT;
-		profile_level.profile = venc_v4l2_to_hal(ctrl->id,
-							ctrl->val);
-		profile_level.level = venc_v4l2_to_hal(
-				V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL,
-				temp_ctrl->val);
-		pdata = &profile_level;
-		break;
-	case V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL:
-		temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE);
-
-		property_id =
-			HAL_PARAM_PROFILE_LEVEL_CURRENT;
-		profile_level.level = venc_v4l2_to_hal(ctrl->id,
-							ctrl->val);
-		profile_level.profile = venc_v4l2_to_hal(
-				V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE,
-				ctrl->val);
-		pdata = &profile_level;
-		break;
-	case V4L2_CID_MPEG_VIDC_VIDEO_ROTATION:
-		property_id =
-			HAL_CONFIG_VPE_OPERATIONS;
-		operations.rotate = ctrl->val;
-		pdata = &operations;
-		break;
-	case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: {
-		struct v4l2_ctrl *qpp, *qpb;
-
-		qpp = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP);
-		qpb = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP);
-
-		property_id =
-			HAL_PARAM_VENC_SESSION_QP;
-		quantization.qpi = ctrl->val;
-		quantization.qpp = qpp->val;
-		quantization.qpb = qpb->val;
-
-		pdata = &quantization;
-		break;
-	}
-	case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP: {
-		struct v4l2_ctrl *qpi, *qpb;
-
-		qpi = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP);
-		qpb = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP);
-
-		property_id =
-			HAL_PARAM_VENC_SESSION_QP;
-		quantization.qpp = ctrl->val;
-		quantization.qpi = qpi->val;
-		quantization.qpb = qpb->val;
-
-		pdata = &quantization;
-		break;
-	}
-	case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP: {
-		struct v4l2_ctrl *qpi, *qpp;
-
-		qpi = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP);
-		qpp = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP);
-
-		property_id =
-			HAL_PARAM_VENC_SESSION_QP;
-		quantization.qpb = ctrl->val;
-		quantization.qpi = qpi->val;
-		quantization.qpp = qpp->val;
-
-		pdata = &quantization;
-		break;
-	}
-	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: {
-		int temp = 0;
-
-		switch (ctrl->val) {
-		case V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB:
-			temp = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
-			break;
-		case V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES:
-			temp = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
-			break;
-		case V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE:
-		default:
-			temp = 0;
-			break;
-		}
-
-		if (temp)
-			temp_ctrl = TRY_GET_CTRL(temp);
-
-		property_id =
-			HAL_PARAM_VENC_MULTI_SLICE_CONTROL;
-		multi_slice_control.multi_slice = ctrl->val;
-		multi_slice_control.slice_size = temp ? temp_ctrl->val : 0;
-
-		pdata = &multi_slice_control;
-		break;
-	}
-	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
-	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
-		temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE);
-
-		property_id =
-			HAL_PARAM_VENC_MULTI_SLICE_CONTROL;
-		multi_slice_control.multi_slice = temp_ctrl->val;
-		multi_slice_control.slice_size = ctrl->val;
-		pdata = &multi_slice_control;
-		break;
-	case V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE: {
-		struct v4l2_ctrl *air_mbs, *air_ref, *cir_mbs;
-		air_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS);
-		air_ref = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF);
-		cir_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS);
-
-		property_id =
-			HAL_PARAM_VENC_INTRA_REFRESH;
-
-		intra_refresh.mode = ctrl->val;
-		intra_refresh.air_mbs = air_mbs->val;
-		intra_refresh.air_ref = air_ref->val;
-		intra_refresh.cir_mbs = cir_mbs->val;
-
-		pdata = &intra_refresh;
-		break;
-	}
-	case V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS: {
-		struct v4l2_ctrl *ir_mode, *air_ref, *cir_mbs;
-		ir_mode = TRY_GET_CTRL(
-				V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE);
-		air_ref = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF);
-		cir_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS);
-
-		property_id =
-			HAL_PARAM_VENC_INTRA_REFRESH;
-		intra_refresh.air_mbs = ctrl->val;
-		intra_refresh.mode = ir_mode->val;
-		intra_refresh.air_ref = air_ref->val;
-		intra_refresh.cir_mbs = cir_mbs->val;
-
-		pdata = &intra_refresh;
-		break;
-	}
-	case V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF: {
-		struct v4l2_ctrl *ir_mode, *air_mbs, *cir_mbs;
-		ir_mode = TRY_GET_CTRL(
-				V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE);
-		air_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS);
-		cir_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS);
-
-		property_id =
-			HAL_PARAM_VENC_INTRA_REFRESH;
-		intra_refresh.air_ref = ctrl->val;
-		intra_refresh.air_mbs = air_mbs->val;
-		intra_refresh.mode = ir_mode->val;
-		intra_refresh.cir_mbs = cir_mbs->val;
-
-		pdata = &intra_refresh;
-		break;
-	}
-	case V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS: {
-		struct v4l2_ctrl *ir_mode, *air_mbs, *air_ref;
-
-		ir_mode = TRY_GET_CTRL(
-				V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE);
-		air_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS);
-		air_ref = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF);
-
-		property_id =
-			HAL_PARAM_VENC_INTRA_REFRESH;
-
-		intra_refresh.cir_mbs = ctrl->val;
-		intra_refresh.air_mbs = air_mbs->val;
-		intra_refresh.air_ref = air_ref->val;
-		intra_refresh.mode = ir_mode->val;
-
-		pdata = &intra_refresh;
-		break;
-	}
-	case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:
-		property_id =
-			HAL_PARAM_VENC_H264_DEBLOCK_CONTROL;
-		h264_db_control.mode = ctrl->val;
-		pdata = &h264_db_control;
-		break;
-	case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA:
-		property_id =
-			HAL_PARAM_VENC_H264_DEBLOCK_CONTROL;
-		h264_db_control.slice_alpha_offset = ctrl->val;
-		pdata = &h264_db_control;
-		break;
-	case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA:
-		property_id =
-			HAL_PARAM_VENC_H264_DEBLOCK_CONTROL;
-		h264_db_control.slice_beta_offset = ctrl->val;
-		pdata = &h264_db_control;
-		break;
-	case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
-		property_id =
-			HAL_PARAM_VENC_SYNC_FRAME_SEQUENCE_HEADER;
-
-		switch (ctrl->val) {
-		case V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE:
-			enable.enable = 0;
-			break;
-		case V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME:
-			enable.enable = 1;
-			break;
-		case V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME:
-		default:
-			rc = -ENOTSUPP;
-			break;
-		}
-		pdata = &enable;
-		break;
-	default:
-		rc = -ENOTSUPP;
-		break;
-	}
-#undef TRY_GET_CTRL
-
-	if (property_id) {
-		dprintk(VIDC_DBG, "Control: HAL property=%d,ctrl_value=%d\n",
-				property_id,
-				ctrl->val);
-		rc = vidc_hal_session_set_property((void *)inst->session,
-				property_id, pdata);
-	}
-
-	return rc;
-}
-
-static int msm_venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-
-	int rc = 0, c = 0;
-	struct msm_vidc_inst *inst = container_of(ctrl->handler,
-					struct msm_vidc_inst, ctrl_handler);
-	rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
-
-	if (rc) {
-		dprintk(VIDC_ERR,
-			"Failed to move inst: %p to start done state\n", inst);
-		goto failed_open_done;
-	}
-
-	for (c = 0; c < ctrl->ncontrols; ++c) {
-		if (ctrl->cluster[c]->is_new) {
-			rc = try_set_ctrl(inst, ctrl->cluster[c]);
-			if (rc) {
-				dprintk(VIDC_ERR, "Failed setting %x",
-						ctrl->cluster[c]->id);
-				break;
-			}
-		}
-	}
-failed_open_done:
-	if (rc)
-		dprintk(VIDC_ERR, "Failed to set hal property\n");
-	return rc;
-}
-
-static int msm_venc_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
-{
-	return 0;
-}
-
-static const struct v4l2_ctrl_ops msm_venc_ctrl_ops = {
-
-	.s_ctrl = msm_venc_op_s_ctrl,
-	.g_volatile_ctrl = msm_venc_op_g_volatile_ctrl,
-};
-
-const struct v4l2_ctrl_ops *msm_venc_get_ctrl_ops(void)
-{
-	return &msm_venc_ctrl_ops;
-}
-
-int msm_venc_inst_init(struct msm_vidc_inst *inst)
-{
-	int rc = 0;
-	if (!inst) {
-		dprintk(VIDC_ERR, "Invalid input = %p\n", inst);
-		return -EINVAL;
-	}
-	inst->fmts[CAPTURE_PORT] = &venc_formats[1];
-	inst->fmts[OUTPUT_PORT] = &venc_formats[0];
-	inst->prop.height = DEFAULT_HEIGHT;
-	inst->prop.width = DEFAULT_WIDTH;
-	inst->prop.fps = 30;
-	return rc;
-}
-
-int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl)
-{
-	return v4l2_s_ctrl(NULL, &inst->ctrl_handler, ctrl);
-}
-int msm_venc_g_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl)
-{
-	return v4l2_g_ctrl(&inst->ctrl_handler, ctrl);
-}
-
-int msm_venc_cmd(struct msm_vidc_inst *inst, struct v4l2_encoder_cmd *enc)
-{
-	int rc = 0;
-	struct v4l2_event dqevent = {0};
-	struct msm_vidc_core *core;
-	core = inst->core;
-	switch (enc->cmd) {
-	case V4L2_ENC_QCOM_CMD_FLUSH:
-		rc = msm_comm_flush(inst, enc->flags);
-		break;
-	case V4L2_ENC_CMD_STOP:
-		if (inst->state == MSM_VIDC_CORE_INVALID ||
-			core->state == VIDC_CORE_INVALID) {
-			dqevent.type = V4L2_EVENT_MSM_VIDC_CLOSE_DONE;
-			v4l2_event_queue_fh(&inst->event_handler, &dqevent);
-			return rc;
-		}
-		rc = msm_comm_release_scratch_buffers(inst);
-		if (rc)
-			dprintk(VIDC_ERR, "Failed to release scratch buf:%d\n",
-				rc);
-		rc = msm_comm_release_persist_buffers(inst);
-		if (rc)
-			dprintk(VIDC_ERR, "Failed to release persist buf:%d\n",
-				rc);
-		rc = msm_comm_try_state(inst, MSM_VIDC_CLOSE_DONE);
-		break;
-	}
-	if (rc)
-		dprintk(VIDC_ERR,
-			"Command: %d failed with rc = %d\n", enc->cmd, rc);
-	return rc;
-}
-
-int msm_venc_querycap(struct msm_vidc_inst *inst, struct v4l2_capability *cap)
-{
-	if (!inst || !cap) {
-		dprintk(VIDC_ERR,
-			"Invalid input, inst = %p, cap = %p\n", inst, cap);
-		return -EINVAL;
-	}
-	strlcpy(cap->driver, MSM_VIDC_DRV_NAME, sizeof(cap->driver));
-	strlcpy(cap->card, MSM_VENC_DVC_NAME, sizeof(cap->card));
-	cap->bus_info[0] = 0;
-	cap->version = MSM_VIDC_VERSION;
-	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
-						V4L2_CAP_VIDEO_OUTPUT_MPLANE |
-						V4L2_CAP_STREAMING;
-	memset(cap->reserved, 0, sizeof(cap->reserved));
-	return 0;
-}
-
-int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f)
-{
-	const struct msm_vidc_format *fmt = NULL;
-	int rc = 0;
-	if (!inst || !f) {
-		dprintk(VIDC_ERR,
-			"Invalid input, inst = %p, f = %p\n", inst, f);
-		return -EINVAL;
-	}
-	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-		fmt = msm_comm_get_pixel_fmt_index(venc_formats,
-			ARRAY_SIZE(venc_formats), f->index, CAPTURE_PORT);
-	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-		fmt = msm_comm_get_pixel_fmt_index(venc_formats,
-			ARRAY_SIZE(venc_formats), f->index, OUTPUT_PORT);
-		f->flags = V4L2_FMT_FLAG_COMPRESSED;
-	}
-
-	memset(f->reserved, 0 , sizeof(f->reserved));
-	if (fmt) {
-		strlcpy(f->description, fmt->description,
-				sizeof(f->description));
-		f->pixelformat = fmt->fourcc;
-	} else {
-		dprintk(VIDC_ERR, "No more formats found\n");
-		rc = -EINVAL;
-	}
-	return rc;
-}
-
-int msm_venc_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a)
-{
-	u32 property_id = 0, us_per_frame = 0;
-	void *pdata;
-	int rc = 0;
-	struct hal_frame_rate frame_rate;
-	property_id = HAL_CONFIG_FRAME_RATE;
-	if (a->parm.output.timeperframe.denominator) {
-		switch (a->type) {
-		case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-		case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
-			us_per_frame = a->parm.output.timeperframe.numerator *
-				USEC_PER_SEC / a->parm.output.\
-				timeperframe.denominator;
-			break;
-		default:
-			dprintk(VIDC_ERR,
-				"Scale clocks : Unknown buffer type\n");
-			break;
-		}
-	}
-
-	if (!us_per_frame) {
-		dprintk(VIDC_ERR,
-			"Failed to scale clocks : time between frames is 0\n");
-		rc = -EINVAL;
-		goto exit;
-	}
-	inst->prop.fps = (u8) (USEC_PER_SEC / us_per_frame);
-	if (inst->prop.fps) {
-		frame_rate.frame_rate = inst->prop.fps * (0x1<<16);
-		frame_rate.buffer_type = HAL_BUFFER_OUTPUT;
-		pdata = &frame_rate;
-		rc = vidc_hal_session_set_property((void *)inst->session,
-				property_id, pdata);
-		if (rc) {
-			dprintk(VIDC_WARN,
-				"Failed to set frame rate %d\n", rc);
-		}
-		msm_comm_scale_clocks_and_bus(inst);
-	}
-exit:
-	return rc;
-}
-int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
-{
-	const struct msm_vidc_format *fmt = NULL;
-	struct hal_frame_size frame_sz;
-	int rc = 0;
-	int i;
-	if (!inst || !f) {
-		dprintk(VIDC_ERR,
-			"Invalid input, inst = %p, format = %p\n", inst, f);
-		return -EINVAL;
-	}
-	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-		fmt = msm_comm_get_pixel_fmt_fourcc(venc_formats,
-			ARRAY_SIZE(venc_formats), f->fmt.pix_mp.pixelformat,
-			CAPTURE_PORT);
-		if (fmt && fmt->type != CAPTURE_PORT) {
-			dprintk(VIDC_ERR,
-				"Format: %d not supported on CAPTURE port\n",
-				f->fmt.pix_mp.pixelformat);
-			rc = -EINVAL;
-			goto exit;
-		}
-	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-		inst->prop.width = f->fmt.pix_mp.width;
-		inst->prop.height = f->fmt.pix_mp.height;
-		frame_sz.buffer_type = HAL_BUFFER_INPUT;
-		frame_sz.width = inst->prop.width;
-		frame_sz.height = inst->prop.height;
-		dprintk(VIDC_DBG, "width = %d, height = %d\n",
-				frame_sz.width, frame_sz.height);
-		rc = vidc_hal_session_set_property((void *)inst->session,
-				HAL_PARAM_FRAME_SIZE, &frame_sz);
-		if (rc) {
-			dprintk(VIDC_ERR,
-				"Failed to set framesize for Output port\n");
-			goto exit;
-		}
-		frame_sz.buffer_type = HAL_BUFFER_OUTPUT;
-		rc = vidc_hal_session_set_property((void *)inst->session,
-				HAL_PARAM_FRAME_SIZE, &frame_sz);
-		if (rc) {
-			dprintk(VIDC_ERR,
-				"Failed to set hal property for framesize\n");
-			goto exit;
-		}
-		fmt = msm_comm_get_pixel_fmt_fourcc(venc_formats,
-			ARRAY_SIZE(venc_formats), f->fmt.pix_mp.pixelformat,
-			OUTPUT_PORT);
-		if (fmt && fmt->type != OUTPUT_PORT) {
-			dprintk(VIDC_ERR,
-				"Format: %d not supported on OUTPUT port\n",
-				f->fmt.pix_mp.pixelformat);
-			rc = -EINVAL;
-			goto exit;
-		}
-	}
-
-	if (fmt) {
-		f->fmt.pix_mp.num_planes = fmt->num_planes;
-		for (i = 0; i < fmt->num_planes; ++i) {
-			f->fmt.pix_mp.plane_fmt[i].sizeimage =
-				fmt->get_frame_size(i, f->fmt.pix_mp.height,
-						f->fmt.pix_mp.width);
-		}
-		inst->fmts[fmt->type] = fmt;
-		if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-			rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
-			if (rc) {
-				dprintk(VIDC_ERR, "Failed to open instance\n");
-				goto exit;
-			}
-		}
-	} else {
-		dprintk(VIDC_ERR, "Buf type not recognized, type = %d\n",
-					f->type);
-		rc = -EINVAL;
-	}
-exit:
-	return rc;
-}
-
-int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
-{
-	const struct msm_vidc_format *fmt = NULL;
-	int rc = 0;
-	int i;
-	if (!inst || !f) {
-		dprintk(VIDC_ERR,
-			"Invalid input, inst = %p, format = %p\n", inst, f);
-		return -EINVAL;
-	}
-	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
-		fmt = inst->fmts[CAPTURE_PORT];
-	else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
-		fmt = inst->fmts[OUTPUT_PORT];
-
-	if (fmt) {
-		f->fmt.pix_mp.pixelformat = fmt->fourcc;
-		f->fmt.pix_mp.height = inst->prop.height;
-		f->fmt.pix_mp.width = inst->prop.width;
-		f->fmt.pix_mp.num_planes = fmt->num_planes;
-		for (i = 0; i < fmt->num_planes; ++i) {
-			f->fmt.pix_mp.plane_fmt[i].sizeimage =
-			fmt->get_frame_size(i, inst->prop.height,
-					inst->prop.width);
-		}
-	} else {
-		dprintk(VIDC_ERR,
-			"Buf type not recognized, type = %d\n",	f->type);
-		rc = -EINVAL;
-	}
-	return rc;
-}
-
-int msm_venc_reqbufs(struct msm_vidc_inst *inst, struct v4l2_requestbuffers *b)
-{
-	struct buf_queue *q = NULL;
-	int rc = 0;
-	if (!inst || !b) {
-		dprintk(VIDC_ERR,
-			"Invalid input, inst = %p, buffer = %p\n", inst, b);
-		return -EINVAL;
-	}
-	q = msm_comm_get_vb2q(inst, b->type);
-	if (!q) {
-		dprintk(VIDC_ERR,
-		"Failed to find buffer queue for type = %d\n", b->type);
-		return -EINVAL;
-	}
-
-	mutex_lock(&q->lock);
-	rc = vb2_reqbufs(&q->vb2_bufq, b);
-	mutex_unlock(&q->lock);
-	if (rc)
-		dprintk(VIDC_ERR, "Failed to get reqbufs, %d\n", rc);
-	return rc;
-}
-
-int msm_venc_prepare_buf(struct msm_vidc_inst *inst,
-					struct v4l2_buffer *b)
-{
-	int rc = 0;
-	int i;
-	struct vidc_buffer_addr_info buffer_info;
-
-	switch (b->type) {
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-		break;
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
-		for (i = 0; i < b->length; i++) {
-			dprintk(VIDC_DBG,
-				"device_addr = %ld, size = %d\n",
-				b->m.planes[i].m.userptr,
-				b->m.planes[i].length);
-			buffer_info.buffer_size = b->m.planes[i].length;
-			buffer_info.buffer_type = HAL_BUFFER_OUTPUT;
-			buffer_info.num_buffers = 1;
-			buffer_info.align_device_addr =
-				b->m.planes[i].m.userptr;
-			buffer_info.extradata_size = 0;
-			buffer_info.extradata_addr = 0;
-			rc = vidc_hal_session_set_buffers((void *)inst->session,
-					&buffer_info);
-			if (rc)
-				dprintk(VIDC_ERR,
-					"vidc_hal_session_set_buffers failed");
-		}
-		break;
-	default:
-		dprintk(VIDC_ERR,
-			"Buffer type not recognized: %d\n", b->type);
-		break;
-	}
-	return rc;
-}
-
-int msm_venc_release_buf(struct msm_vidc_inst *inst,
-					struct v4l2_buffer *b)
-{
-	int rc = 0;
-	int i;
-	struct vidc_buffer_addr_info buffer_info;
-	rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
-	if (rc) {
-		dprintk(VIDC_ERR,
-			"Failed to move inst: %p to release res done state\n",
-			inst);
-		goto exit;
-	}
-	switch (b->type) {
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-		break;
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
-		for (i = 0; i < b->length; i++) {
-			dprintk(VIDC_DBG,
-				"Release device_addr = %ld, size = %d, %d\n",
-				b->m.planes[i].m.userptr,
-				b->m.planes[i].length, inst->state);
-			buffer_info.buffer_size = b->m.planes[i].length;
-			buffer_info.buffer_type = HAL_BUFFER_OUTPUT;
-			buffer_info.num_buffers = 1;
-			buffer_info.align_device_addr =
-				 b->m.planes[i].m.userptr;
-			buffer_info.extradata_size = 0;
-			buffer_info.extradata_addr = 0;
-			buffer_info.response_required = false;
-			rc = vidc_hal_session_release_buffers(
-				(void *)inst->session, &buffer_info);
-			if (rc)
-				dprintk(VIDC_ERR,
-					"vidc_hal_session_release_buffers failed\n");
-		}
-		break;
-	default:
-		dprintk(VIDC_ERR, "Buffer type not recognized: %d\n", b->type);
-		break;
-	}
-exit:
-	return rc;
-}
-
-int msm_venc_qbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b)
-{
-	struct buf_queue *q = NULL;
-	int rc = 0;
-	q = msm_comm_get_vb2q(inst, b->type);
-	if (!q) {
-		dprintk(VIDC_ERR,
-			"Failed to find buffer queue for type = %d\n", b->type);
-		return -EINVAL;
-	}
-	mutex_lock(&q->lock);
-	rc = vb2_qbuf(&q->vb2_bufq, b);
-	mutex_unlock(&q->lock);
-	if (rc)
-		dprintk(VIDC_ERR, "Failed to qbuf, %d\n", rc);
-	return rc;
-}
-
-int msm_venc_dqbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b)
-{
-	struct buf_queue *q = NULL;
-	int rc = 0;
-	q = msm_comm_get_vb2q(inst, b->type);
-	if (!q) {
-		dprintk(VIDC_ERR,
-			"Failed to find buffer queue for type = %d\n", b->type);
-		return -EINVAL;
-	}
-	mutex_lock(&q->lock);
-	rc = vb2_dqbuf(&q->vb2_bufq, b, true);
-	mutex_unlock(&q->lock);
-	if (rc)
-		dprintk(VIDC_DBG, "Failed to dqbuf, %d\n", rc);
-	return rc;
-}
-
-int msm_venc_streamon(struct msm_vidc_inst *inst, enum v4l2_buf_type i)
-{
-	int rc = 0;
-	struct buf_queue *q;
-	q = msm_comm_get_vb2q(inst, i);
-	if (!q) {
-		dprintk(VIDC_ERR,
-			"Failed to find buffer queue for type = %d\n", i);
-		return -EINVAL;
-	}
-	dprintk(VIDC_DBG, "Calling streamon\n");
-	mutex_lock(&q->lock);
-	rc = vb2_streamon(&q->vb2_bufq, i);
-	mutex_unlock(&q->lock);
-	if (rc)
-		dprintk(VIDC_ERR, "streamon failed on port: %d\n", i);
-	return rc;
-}
-
-int msm_venc_streamoff(struct msm_vidc_inst *inst, enum v4l2_buf_type i)
-{
-	int rc = 0;
-	struct buf_queue *q;
-	q = msm_comm_get_vb2q(inst, i);
-	if (!q) {
-		dprintk(VIDC_ERR,
-			"Failed to find buffer queue for type = %d\n", i);
-		return -EINVAL;
-	}
-	dprintk(VIDC_DBG, "Calling streamoff on port: %d\n", i);
-	mutex_lock(&q->lock);
-	rc = vb2_streamoff(&q->vb2_bufq, i);
-	mutex_unlock(&q->lock);
-	if (rc)
-		dprintk(VIDC_ERR, "streamoff failed on port: %d\n", i);
-	return rc;
-}
-
-static struct v4l2_ctrl **get_cluster(int type, int *size)
-{
-	int c = 0, sz = 0;
-	struct v4l2_ctrl **cluster = kmalloc(sizeof(struct v4l2_ctrl *) *
-			NUM_CTRLS, GFP_KERNEL);
-
-	if (type <= 0 || !size || !cluster)
-		return NULL;
-
-	for (c = 0; c < NUM_CTRLS; c++) {
-		if (msm_venc_ctrls[c].cluster == type) {
-			cluster[sz] = msm_venc_ctrls[c].priv;
-			++sz;
-		}
-	}
-
-	*size = sz;
-	return cluster;
-}
-
-int msm_venc_ctrl_init(struct msm_vidc_inst *inst)
-{
-
-	int idx = 0;
-	struct v4l2_ctrl_config ctrl_cfg;
-	int ret_val = 0;
-	ret_val = v4l2_ctrl_handler_init(&inst->ctrl_handler, NUM_CTRLS);
-	if (ret_val) {
-		dprintk(VIDC_ERR, "CTRL ERR: Control handler init failed, %d\n",
-			inst->ctrl_handler.error);
-		return ret_val;
-	}
-
-	for (; idx < NUM_CTRLS; idx++) {
-		struct v4l2_ctrl *ctrl = NULL;
-		if (IS_PRIV_CTRL(msm_venc_ctrls[idx].id)) {
-			ctrl_cfg.def = msm_venc_ctrls[idx].default_value;
-			ctrl_cfg.flags = 0;
-			ctrl_cfg.id = msm_venc_ctrls[idx].id;
-			ctrl_cfg.max = msm_venc_ctrls[idx].maximum;
-			ctrl_cfg.min = msm_venc_ctrls[idx].minimum;
-			ctrl_cfg.menu_skip_mask =
-				msm_venc_ctrls[idx].menu_skip_mask;
-			ctrl_cfg.name = msm_venc_ctrls[idx].name;
-			ctrl_cfg.ops = &msm_venc_ctrl_ops;
-			ctrl_cfg.step = msm_venc_ctrls[idx].step;
-			ctrl_cfg.type = msm_venc_ctrls[idx].type;
-			ctrl_cfg.qmenu = msm_venc_ctrls[idx].qmenu;
-			ctrl = v4l2_ctrl_new_custom(
-					&inst->ctrl_handler,
-					&ctrl_cfg, NULL);
-		} else {
-			if (msm_venc_ctrls[idx].type == V4L2_CTRL_TYPE_MENU) {
-				ctrl = v4l2_ctrl_new_std_menu(
-					&inst->ctrl_handler,
-					&msm_venc_ctrl_ops,
-					msm_venc_ctrls[idx].id,
-					msm_venc_ctrls[idx].maximum,
-					msm_venc_ctrls[idx].menu_skip_mask,
-					msm_venc_ctrls[idx].default_value);
-			} else {
-				ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler,
-					&msm_venc_ctrl_ops,
-					msm_venc_ctrls[idx].id,
-					msm_venc_ctrls[idx].minimum,
-					msm_venc_ctrls[idx].maximum,
-					msm_venc_ctrls[idx].step,
-					msm_venc_ctrls[idx].default_value);
-			}
-		}
-
-		msm_venc_ctrls[idx].priv = ctrl;
-	}
-	ret_val = inst->ctrl_handler.error;
-	if (ret_val)
-		dprintk(VIDC_ERR,
-			"CTRL ERR: Error adding ctrls to ctrl handle, %d\n",
-			inst->ctrl_handler.error);
-
-	/* Construct clusters */
-	for (idx = 1; idx < MSM_VENC_CTRL_CLUSTER_MAX; ++idx) {
-		struct msm_vidc_ctrl_cluster *temp = NULL;
-		struct v4l2_ctrl **cluster = NULL;
-		int cluster_size = 0;
-
-		cluster = get_cluster(idx, &cluster_size);
-		if (!cluster || !cluster_size) {
-			dprintk(VIDC_WARN, "Failed to setup cluster of type %d",
-					idx);
-			continue;
-		}
-
-		v4l2_ctrl_cluster(cluster_size, cluster);
-
-		temp = kzalloc(sizeof(*temp), GFP_KERNEL);
-		if (!temp) {
-			ret_val = -ENOMEM;
-			break;
-		}
-
-		temp->cluster = cluster;
-		INIT_LIST_HEAD(&temp->list);
-		list_add_tail(&temp->list, &inst->ctrl_clusters);
-	}
-
-	return ret_val;
-}
-
-int msm_venc_ctrl_deinit(struct msm_vidc_inst *inst)
-{
-	struct msm_vidc_ctrl_cluster *curr, *next;
-	list_for_each_entry_safe(curr, next, &inst->ctrl_clusters, list) {
-		kfree(curr->cluster);
-		kfree(curr);
-	}
-
-	return 0;
-}
diff --git a/drivers/media/video/msm_vidc/msm_venc.h b/drivers/media/video/msm_vidc/msm_venc.h
deleted file mode 100644
index c098773..0000000
--- a/drivers/media/video/msm_vidc/msm_venc.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 _MSM_VENC_H_
-#define _MSM_VENC_H_
-
-#include <media/msm_vidc.h>
-#include "msm_vidc_internal.h"
-
-int msm_venc_inst_init(struct msm_vidc_inst *inst);
-int msm_venc_ctrl_init(struct msm_vidc_inst *inst);
-int msm_venc_ctrl_deinit(struct msm_vidc_inst *inst);
-int msm_venc_querycap(void *instance, struct v4l2_capability *cap);
-int msm_venc_enum_fmt(void *instance, struct v4l2_fmtdesc *f);
-int msm_venc_s_fmt(void *instance, struct v4l2_format *f);
-int msm_venc_g_fmt(void *instance, struct v4l2_format *f);
-int msm_venc_s_ctrl(void *instance, struct v4l2_control *a);
-int msm_venc_g_ctrl(void *instance, struct v4l2_control *a);
-int msm_venc_reqbufs(void *instance, struct v4l2_requestbuffers *b);
-int msm_venc_prepare_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
-int msm_venc_release_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
-int msm_venc_qbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
-int msm_venc_dqbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
-int msm_venc_streamon(struct msm_vidc_inst *inst, enum v4l2_buf_type i);
-int msm_venc_streamoff(struct msm_vidc_inst *inst, enum v4l2_buf_type i);
-int msm_venc_cmd(struct msm_vidc_inst *inst, struct v4l2_encoder_cmd *enc);
-int msm_venc_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a);
-struct vb2_ops *msm_venc_get_vb2q_ops(void);
-
-#endif
diff --git a/drivers/media/video/msm_vidc/msm_vidc.c b/drivers/media/video/msm_vidc/msm_vidc.c
deleted file mode 100644
index 13180c5..0000000
--- a/drivers/media/video/msm_vidc/msm_vidc.c
+++ /dev/null
@@ -1,577 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/sched.h>
-#include <linux/slab.h>
-#include <media/msm_vidc.h>
-#include "msm_vidc_internal.h"
-#include "msm_vidc_debug.h"
-#include "msm_vdec.h"
-#include "msm_venc.h"
-#include "msm_vidc_common.h"
-#include "msm_smem.h"
-#include <linux/delay.h>
-
-#define MAX_EVENTS 30
-
-static int get_poll_flags(void *instance)
-{
-	struct msm_vidc_inst *inst = instance;
-	struct vb2_queue *outq = &inst->bufq[OUTPUT_PORT].vb2_bufq;
-	struct vb2_queue *capq = &inst->bufq[CAPTURE_PORT].vb2_bufq;
-	struct vb2_buffer *out_vb = NULL;
-	struct vb2_buffer *cap_vb = NULL;
-	unsigned long flags;
-	int rc = 0;
-
-	if (v4l2_event_pending(&inst->event_handler))
-		rc |= POLLPRI;
-
-	spin_lock_irqsave(&capq->done_lock, flags);
-	if (!list_empty(&capq->done_list))
-		cap_vb = list_first_entry(&capq->done_list, struct vb2_buffer,
-								done_entry);
-	if (cap_vb && (cap_vb->state == VB2_BUF_STATE_DONE
-				|| cap_vb->state == VB2_BUF_STATE_ERROR))
-		rc |= POLLIN | POLLRDNORM;
-	spin_unlock_irqrestore(&capq->done_lock, flags);
-
-	spin_lock_irqsave(&outq->done_lock, flags);
-	if (!list_empty(&outq->done_list))
-		out_vb = list_first_entry(&outq->done_list, struct vb2_buffer,
-								done_entry);
-	if (out_vb && (out_vb->state == VB2_BUF_STATE_DONE
-				|| out_vb->state == VB2_BUF_STATE_ERROR))
-		rc |= POLLOUT | POLLWRNORM;
-	spin_unlock_irqrestore(&outq->done_lock, flags);
-
-	return rc;
-}
-
-int msm_vidc_poll(void *instance, struct file *filp,
-		struct poll_table_struct *wait)
-{
-	struct msm_vidc_inst *inst = instance;
-	struct vb2_queue *outq = &inst->bufq[OUTPUT_PORT].vb2_bufq;
-	struct vb2_queue *capq = &inst->bufq[CAPTURE_PORT].vb2_bufq;
-
-	poll_wait(filp, &inst->event_handler.wait, wait);
-	poll_wait(filp, &capq->done_wq, wait);
-	poll_wait(filp, &outq->done_wq, wait);
-	return get_poll_flags(inst);
-}
-
-/* Kernel client alternative for msm_vidc_poll */
-int msm_vidc_wait(void *instance)
-{
-	struct msm_vidc_inst *inst = instance;
-	int rc = 0;
-
-	wait_event(inst->kernel_event_queue, (rc = get_poll_flags(inst)));
-	return rc;
-}
-
-int msm_vidc_get_iommu_maps(void *instance,
-		struct msm_vidc_iommu_info maps[MAX_MAP])
-{
-	struct msm_vidc_inst *inst = instance;
-	int c = 0;
-
-	if (!inst || !maps)
-		return -EINVAL;
-
-	for (c = 0; c < MAX_MAP; ++c)
-		maps[c] = inst->core->resources.io_map[c];
-
-	return 0;
-}
-
-int msm_vidc_querycap(void *instance, struct v4l2_capability *cap)
-{
-	struct msm_vidc_inst *inst = instance;
-
-	if (!inst || !cap)
-		return -EINVAL;
-
-	if (inst->session_type == MSM_VIDC_DECODER)
-		return msm_vdec_querycap(instance, cap);
-	else if (inst->session_type == MSM_VIDC_ENCODER)
-		return msm_venc_querycap(instance, cap);
-	return -EINVAL;
-}
-int msm_vidc_s_parm(void *instance,
-		struct v4l2_streamparm *a)
-{
-	struct msm_vidc_inst *inst = instance;
-
-	if (!inst || !a)
-		return -EINVAL;
-	if (inst->session_type == MSM_VIDC_DECODER)
-		return msm_vdec_s_parm(instance, a);
-	else if (inst->session_type == MSM_VIDC_ENCODER)
-		return msm_venc_s_parm(instance, a);
-	return -EINVAL;
-}
-int msm_vidc_enum_fmt(void *instance, struct v4l2_fmtdesc *f)
-{
-	struct msm_vidc_inst *inst = instance;
-
-	if (!inst || !f)
-		return -EINVAL;
-
-	if (inst->session_type == MSM_VIDC_DECODER)
-		return msm_vdec_enum_fmt(instance, f);
-	else if (inst->session_type == MSM_VIDC_ENCODER)
-		return msm_venc_enum_fmt(instance, f);
-	return -EINVAL;
-}
-int msm_vidc_s_fmt(void *instance, struct v4l2_format *f)
-{
-	struct msm_vidc_inst *inst = instance;
-
-	if (!inst || !f)
-		return -EINVAL;
-
-	if (inst->session_type == MSM_VIDC_DECODER)
-		return msm_vdec_s_fmt(instance, f);
-	if (inst->session_type == MSM_VIDC_ENCODER)
-		return msm_venc_s_fmt(instance, f);
-	return -EINVAL;
-}
-int msm_vidc_g_fmt(void *instance, struct v4l2_format *f)
-{
-	struct msm_vidc_inst *inst = instance;
-
-	if (!inst || !f)
-		return -EINVAL;
-
-	if (inst->session_type == MSM_VIDC_DECODER)
-		return msm_vdec_g_fmt(instance, f);
-	else if (inst->session_type == MSM_VIDC_ENCODER)
-		return msm_venc_g_fmt(instance, f);
-	return -EINVAL;
-}
-int msm_vidc_s_ctrl(void *instance, struct v4l2_control *control)
-{
-	struct msm_vidc_inst *inst = instance;
-
-	if (!inst || !control)
-		return -EINVAL;
-
-	if (inst->session_type == MSM_VIDC_DECODER)
-		return msm_vdec_s_ctrl(instance, control);
-	if (inst->session_type == MSM_VIDC_ENCODER)
-		return msm_venc_s_ctrl(instance, control);
-	return -EINVAL;
-}
-int msm_vidc_g_ctrl(void *instance, struct v4l2_control *control)
-{
-	struct msm_vidc_inst *inst = instance;
-
-	if (!inst || !control)
-		return -EINVAL;
-
-	if (inst->session_type == MSM_VIDC_DECODER)
-		return msm_vdec_g_ctrl(instance, control);
-	if (inst->session_type == MSM_VIDC_ENCODER)
-		return msm_venc_g_ctrl(instance, control);
-	return -EINVAL;
-}
-int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b)
-{
-	struct msm_vidc_inst *inst = instance;
-
-	if (!inst || !b)
-		return -EINVAL;
-
-	if (inst->session_type == MSM_VIDC_DECODER)
-		return msm_vdec_reqbufs(instance, b);
-	if (inst->session_type == MSM_VIDC_ENCODER)
-		return msm_venc_reqbufs(instance, b);
-	return -EINVAL;
-}
-
-int msm_vidc_prepare_buf(void *instance, struct v4l2_buffer *b)
-{
-	struct msm_vidc_inst *inst = instance;
-
-	if (!inst || !b)
-		return -EINVAL;
-
-	if (inst->session_type == MSM_VIDC_DECODER)
-		return msm_vdec_prepare_buf(instance, b);
-	if (inst->session_type == MSM_VIDC_ENCODER)
-		return msm_venc_prepare_buf(instance, b);
-	return -EINVAL;
-}
-
-int msm_vidc_release_buf(void *instance, struct v4l2_buffer *b)
-{
-	struct msm_vidc_inst *inst = instance;
-
-	if (!inst || !b)
-		return -EINVAL;
-
-	if (inst->session_type == MSM_VIDC_DECODER)
-		return msm_vdec_release_buf(instance, b);
-	if (inst->session_type == MSM_VIDC_ENCODER)
-		return msm_venc_release_buf(instance, b);
-	return -EINVAL;
-}
-
-int msm_vidc_encoder_cmd(void *instance, struct v4l2_encoder_cmd *enc)
-{
-	struct msm_vidc_inst *inst = instance;
-	if (inst->session_type == MSM_VIDC_ENCODER)
-		return msm_venc_cmd(instance, enc);
-	return -EINVAL;
-}
-
-int msm_vidc_decoder_cmd(void *instance, struct v4l2_decoder_cmd *dec)
-{
-	struct msm_vidc_inst *inst = instance;
-	if (inst->session_type == MSM_VIDC_DECODER)
-		return msm_vdec_cmd(instance, dec);
-	return -EINVAL;
-}
-
-int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b)
-{
-	struct msm_vidc_inst *inst = instance;
-
-	if (!inst || !b)
-		return -EINVAL;
-
-	if (inst->session_type == MSM_VIDC_DECODER)
-		return msm_vdec_qbuf(instance, b);
-	if (inst->session_type == MSM_VIDC_ENCODER)
-		return msm_venc_qbuf(instance, b);
-	return -EINVAL;
-}
-
-int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b)
-{
-	struct msm_vidc_inst *inst = instance;
-
-	if (!inst || !b)
-		return -EINVAL;
-
-	if (inst->session_type == MSM_VIDC_DECODER)
-		return msm_vdec_dqbuf(instance, b);
-	if (inst->session_type == MSM_VIDC_ENCODER)
-		return msm_venc_dqbuf(instance, b);
-	return -EINVAL;
-}
-
-int msm_vidc_streamon(void *instance, enum v4l2_buf_type i)
-{
-	struct msm_vidc_inst *inst = instance;
-
-	if (!inst)
-		return -EINVAL;
-
-	if (inst->session_type == MSM_VIDC_DECODER)
-		return msm_vdec_streamon(instance, i);
-	if (inst->session_type == MSM_VIDC_ENCODER)
-		return msm_venc_streamon(instance, i);
-	return -EINVAL;
-}
-
-int msm_vidc_streamoff(void *instance, enum v4l2_buf_type i)
-{
-	struct msm_vidc_inst *inst = instance;
-
-	if (!inst)
-		return -EINVAL;
-
-	if (inst->session_type == MSM_VIDC_DECODER)
-		return msm_vdec_streamoff(instance, i);
-	if (inst->session_type == MSM_VIDC_ENCODER)
-		return msm_venc_streamoff(instance, i);
-	return -EINVAL;
-}
-
-static void *vidc_get_userptr(void *alloc_ctx, unsigned long vaddr,
-				unsigned long size, int write)
-{
-	return (void *)0xdeadbeef;
-}
-
-static void vidc_put_userptr(void *buf_priv)
-{
-}
-
-static const struct vb2_mem_ops msm_vidc_vb2_mem_ops = {
-	.get_userptr = vidc_get_userptr,
-	.put_userptr = vidc_put_userptr,
-};
-
-static inline int vb2_bufq_init(struct msm_vidc_inst *inst,
-		enum v4l2_buf_type type, enum session_type sess)
-{
-	struct vb2_queue *q = NULL;
-	if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-		q = &inst->bufq[CAPTURE_PORT].vb2_bufq;
-	} else if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-		q = &inst->bufq[OUTPUT_PORT].vb2_bufq;
-	} else {
-		dprintk(VIDC_ERR, "buf_type = %d not recognised\n", type);
-		return -EINVAL;
-	}
-	q->type = type;
-	q->io_modes = VB2_MMAP | VB2_USERPTR;
-	q->io_flags = 0;
-	if (sess == MSM_VIDC_DECODER)
-		q->ops = msm_vdec_get_vb2q_ops();
-	else if (sess == MSM_VIDC_ENCODER)
-		q->ops = msm_venc_get_vb2q_ops();
-	q->mem_ops = &msm_vidc_vb2_mem_ops;
-	q->drv_priv = inst;
-	return vb2_queue_init(q);
-}
-
-static int setup_event_queue(void *inst,
-				struct video_device *pvdev)
-{
-	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);
-
-	return rc;
-}
-
-int msm_vidc_subscribe_event(void *inst, struct v4l2_event_subscription *sub)
-{
-	int rc = 0;
-	struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
-
-	if (!inst || !sub)
-		return -EINVAL;
-
-	rc = v4l2_event_subscribe(&vidc_inst->event_handler, sub, MAX_EVENTS);
-	return rc;
-}
-
-
-int msm_vidc_unsubscribe_event(void *inst, struct v4l2_event_subscription *sub)
-{
-	int rc = 0;
-	struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
-
-	if (!inst || !sub)
-		return -EINVAL;
-
-	rc = v4l2_event_unsubscribe(&vidc_inst->event_handler, sub);
-	return rc;
-}
-
-int msm_vidc_dqevent(void *inst, struct v4l2_event *event)
-{
-	int rc = 0;
-	struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
-
-	if (!inst || !event)
-		return -EINVAL;
-
-	rc = v4l2_event_dequeue(&vidc_inst->event_handler, event, false);
-	return rc;
-}
-
-void *msm_vidc_open(int core_id, int session_type)
-{
-	struct msm_vidc_inst *inst = NULL;
-	struct msm_vidc_core *core = NULL;
-	unsigned long flags;
-	int rc = 0;
-	int i = 0;
-	if (core_id >= MSM_VIDC_CORES_MAX ||
-			session_type >= MSM_VIDC_MAX_DEVICES) {
-		dprintk(VIDC_ERR, "Invalid input, core_id = %d, session = %d\n",
-			core_id, session_type);
-		goto err_invalid_core;
-	}
-	core = get_vidc_core(core_id);
-	if (!core) {
-		dprintk(VIDC_ERR,
-			"Failed to find core for core_id = %d\n", core_id);
-		goto err_invalid_core;
-	}
-
-	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
-	if (!inst) {
-		dprintk(VIDC_ERR, "Failed to allocate memory\n");
-		rc = -ENOMEM;
-		goto err_invalid_core;
-	}
-
-	pr_info(VIDC_DBG_TAG "Opening video instance: %p, %d\n",
-		VIDC_INFO, inst, session_type);
-	mutex_init(&inst->sync_lock);
-	mutex_init(&inst->bufq[CAPTURE_PORT].lock);
-	mutex_init(&inst->bufq[OUTPUT_PORT].lock);
-	spin_lock_init(&inst->lock);
-	inst->session_type = session_type;
-	INIT_LIST_HEAD(&inst->pendingq);
-	INIT_LIST_HEAD(&inst->internalbufs);
-	INIT_LIST_HEAD(&inst->persistbufs);
-	INIT_LIST_HEAD(&inst->ctrl_clusters);
-	init_waitqueue_head(&inst->kernel_event_queue);
-	inst->state = MSM_VIDC_CORE_UNINIT_DONE;
-	inst->core = core;
-
-	for (i = SESSION_MSG_INDEX(SESSION_MSG_START);
-		i <= SESSION_MSG_INDEX(SESSION_MSG_END); i++) {
-		init_completion(&inst->completions[i]);
-	}
-	inst->mem_client = msm_smem_new_client(SMEM_ION);
-	if (!inst->mem_client) {
-		dprintk(VIDC_ERR, "Failed to create memory client\n");
-		goto fail_mem_client;
-	}
-	if (session_type == MSM_VIDC_DECODER) {
-		msm_vdec_inst_init(inst);
-		msm_vdec_ctrl_init(inst);
-	} else if (session_type == MSM_VIDC_ENCODER) {
-		msm_venc_inst_init(inst);
-		msm_venc_ctrl_init(inst);
-	}
-
-	rc = vb2_bufq_init(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
-			session_type);
-	if (rc) {
-		dprintk(VIDC_ERR,
-			"Failed to initialize vb2 queue on capture port\n");
-		goto fail_init;
-	}
-	rc = vb2_bufq_init(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
-			session_type);
-	if (rc) {
-		dprintk(VIDC_ERR,
-			"Failed to initialize vb2 queue on capture port\n");
-		goto fail_init;
-	}
-	rc = msm_comm_try_state(inst, MSM_VIDC_CORE_INIT);
-	if (rc) {
-		dprintk(VIDC_ERR,
-			"Failed to move video instance to init state\n");
-		goto fail_init;
-	}
-	inst->debugfs_root =
-		msm_vidc_debugfs_init_inst(inst, core->debugfs_root);
-
-	setup_event_queue(inst, &core->vdev[core_id].vdev);
-
-	spin_lock_irqsave(&core->lock, flags);
-	list_add_tail(&inst->list, &core->instances);
-	spin_unlock_irqrestore(&core->lock, flags);
-	return inst;
-fail_init:
-	msm_smem_delete_client(inst->mem_client);
-fail_mem_client:
-	kfree(inst);
-	inst = NULL;
-err_invalid_core:
-	return inst;
-}
-
-static void cleanup_instance(struct msm_vidc_inst *inst)
-{
-	unsigned long flags;
-	struct list_head *ptr, *next;
-	struct vb2_buf_entry *entry;
-	struct internal_buf *buf;
-	if (inst) {
-		spin_lock_irqsave(&inst->lock, flags);
-		if (!list_empty(&inst->pendingq)) {
-			list_for_each_safe(ptr, next, &inst->pendingq) {
-				entry = list_entry(ptr, struct vb2_buf_entry,
-						list);
-				list_del(&entry->list);
-				kfree(entry);
-			}
-		}
-		if (!list_empty(&inst->internalbufs)) {
-			list_for_each_safe(ptr, next, &inst->internalbufs) {
-				buf = list_entry(ptr, struct internal_buf,
-						list);
-				list_del(&buf->list);
-				spin_unlock_irqrestore(&inst->lock, flags);
-				msm_smem_free(inst->mem_client, buf->handle);
-				kfree(buf);
-				spin_lock_irqsave(&inst->lock, flags);
-			}
-		}
-		if (!list_empty(&inst->persistbufs)) {
-			list_for_each_safe(ptr, next, &inst->persistbufs) {
-				buf = list_entry(ptr, struct internal_buf,
-						list);
-				list_del(&buf->list);
-				spin_unlock_irqrestore(&inst->lock, flags);
-				msm_smem_free(inst->mem_client, buf->handle);
-				kfree(buf);
-				spin_lock_irqsave(&inst->lock, flags);
-			}
-		}
-		if (inst->extradata_handle) {
-			spin_unlock_irqrestore(&inst->lock, flags);
-			msm_smem_free(inst->mem_client, inst->extradata_handle);
-			spin_lock_irqsave(&inst->lock, flags);
-		}
-		spin_unlock_irqrestore(&inst->lock, flags);
-		msm_smem_delete_client(inst->mem_client);
-		debugfs_remove_recursive(inst->debugfs_root);
-	}
-}
-
-int msm_vidc_close(void *instance)
-{
-	struct msm_vidc_inst *inst = instance;
-	struct msm_vidc_inst *temp;
-	struct msm_vidc_core *core;
-	struct list_head *ptr, *next;
-	int rc = 0;
-
-	if (!inst)
-		return -EINVAL;
-
-	core = inst->core;
-	mutex_lock(&core->sync_lock);
-	list_for_each_safe(ptr, next, &core->instances) {
-		temp = list_entry(ptr, struct msm_vidc_inst, list);
-		if (temp == inst)
-			list_del(&inst->list);
-	}
-	mutex_unlock(&core->sync_lock);
-
-	if (inst->session_type == MSM_VIDC_DECODER)
-		msm_vdec_ctrl_deinit(inst);
-	else if (inst->session_type == MSM_VIDC_ENCODER)
-		msm_venc_ctrl_deinit(inst);
-
-	cleanup_instance(inst);
-	if (inst->state != MSM_VIDC_CORE_INVALID &&
-		core->state != VIDC_CORE_INVALID)
-		rc = msm_comm_try_state(inst, MSM_VIDC_CORE_UNINIT);
-	else
-		rc = msm_comm_force_cleanup(inst);
-	if (rc)
-		dprintk(VIDC_ERR,
-			"Failed to move video instance to uninit state\n");
-	pr_info(VIDC_DBG_TAG "Closed video instance: %p\n", VIDC_INFO, inst);
-	kfree(inst);
-	return 0;
-}
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.c b/drivers/media/video/msm_vidc/msm_vidc_common.c
deleted file mode 100644
index e00528f..0000000
--- a/drivers/media/video/msm_vidc/msm_vidc_common.c
+++ /dev/null
@@ -1,2402 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/sched.h>
-#include <linux/slab.h>
-#include <linux/iommu.h>
-#include <asm/div64.h>
-#include <mach/iommu.h>
-#include <mach/iommu_domains.h>
-#include <mach/subsystem_restart.h>
-#include <mach/scm.h>
-
-#include "msm_vidc_common.h"
-#include "vidc_hal_api.h"
-#include "msm_smem.h"
-#include "msm_vidc_debug.h"
-
-#define HW_RESPONSE_TIMEOUT (5 * 60 * 1000)
-
-#define IS_ALREADY_IN_STATE(__p, __d) ({\
-	int __rc = (__p >= __d);\
-	__rc; \
-})
-
-#define V4L2_EVENT_SEQ_CHANGED_SUFFICIENT \
-		V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT
-#define V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT \
-		V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT
-
-#define NUM_MBS_PER_SEC(__height, __width, __fps) ({\
-	(__height >> 4) * (__width >> 4) * __fps; \
-})
-
-#define VIDC_BUS_LOAD(__height, __width, __fps, __br) ({\
-	__height * __width * __fps; \
-})
-
-#define GET_NUM_MBS(__h, __w) ({\
-	u32 __mbs = (__h >> 4) * (__w >> 4);\
-	__mbs;\
-})
-
-#define TZBSP_MEM_PROTECT_VIDEO_VAR 0x8
-struct tzbsp_memprot {
-	u32 cp_start;
-	u32 cp_size;
-	u32 cp_nonpixel_start;
-	u32 cp_nonpixel_size;
-};
-
-struct tzbsp_resp {
-	int ret;
-};
-
-#define TIME_DIFF_THRESHOLD 200
-
-static const u32 bus_table[] = {
-	36000,
-	110400,
-	244800,
-	489000,
-	783360,
-	979200,
-};
-
-static int get_bus_vector(int load)
-{
-	int num_rows = sizeof(bus_table)/(sizeof(u32));
-	int i;
-	for (i = 0; i < num_rows; i++) {
-		if (load <= bus_table[i])
-			break;
-	}
-	i++;
-	dprintk(VIDC_DBG, "Required bus = %d\n", i);
-	return i;
-}
-
-static int msm_comm_get_load(struct msm_vidc_core *core,
-	enum session_type type)
-{
-	struct msm_vidc_inst *inst = NULL;
-	int num_mbs_per_sec = 0;
-	unsigned long flags;
-	if (!core) {
-		dprintk(VIDC_ERR, "Invalid args: %p\n", core);
-		return -EINVAL;
-	}
-	list_for_each_entry(inst, &core->instances, list) {
-		spin_lock_irqsave(&inst->lock, flags);
-		if (inst->session_type == type &&
-			inst->state >= MSM_VIDC_OPEN_DONE &&
-			inst->state < MSM_VIDC_STOP_DONE) {
-			num_mbs_per_sec += NUM_MBS_PER_SEC(inst->prop.height,
-					inst->prop.width, inst->prop.fps);
-		}
-		spin_unlock_irqrestore(&inst->lock, flags);
-	}
-	return num_mbs_per_sec;
-}
-
-static unsigned long get_clock_rate(struct core_clock *clock,
-	int num_mbs_per_sec)
-{
-	int num_rows = clock->count;
-	struct load_freq_table *table = clock->load_freq_tbl;
-	unsigned long ret = table[num_rows-1].freq;
-	int i;
-	for (i = 0; i < num_rows; i++) {
-		if (num_mbs_per_sec > table[i].load)
-			break;
-		ret = table[i].freq;
-	}
-	dprintk(VIDC_DBG, "Required clock rate = %lu\n", ret);
-	return ret;
-}
-
-static int msm_comm_scale_bus(struct msm_vidc_core *core,
-	enum session_type type, enum mem_type mtype)
-{
-	int load;
-	int rc = 0;
-	u32 handle = 0;
-	if (!core || type >= MSM_VIDC_MAX_DEVICES) {
-		dprintk(VIDC_ERR, "Invalid args: %p, %d\n", core, type);
-		return -EINVAL;
-	}
-	load = msm_comm_get_load(core, type);
-	if (mtype & DDR_MEM)
-		handle = core->resources.bus_info.ddr_handle[type];
-	if (mtype & OCMEM_MEM)
-		handle = core->resources.bus_info.ocmem_handle[type];
-	if (handle) {
-		rc = msm_bus_scale_client_update_request(
-				handle, get_bus_vector(load));
-		if (rc)
-			dprintk(VIDC_ERR, "Failed to scale bus: %d\n", rc);
-	} else {
-		dprintk(VIDC_ERR, "Failed to scale bus, mtype: %d\n",
-				mtype);
-		rc = -EINVAL;
-	}
-	return rc;
-}
-
-static void msm_comm_unvote_buses(struct msm_vidc_core *core,
-	enum mem_type mtype)
-{
-	int i;
-	for (i = 0; i < MSM_VIDC_MAX_DEVICES; i++) {
-		if ((mtype & DDR_MEM) &&
-			msm_bus_scale_client_update_request(
-				core->resources.bus_info.ddr_handle[i],
-				0)) {
-			dprintk(VIDC_WARN,
-				"Failed to unvote for DDR accesses\n");
-		}
-		if ((mtype & OCMEM_MEM) &&
-			msm_bus_scale_client_update_request(
-				core->resources.bus_info.ocmem_handle[i],
-				0)) {
-			dprintk(VIDC_WARN,
-				"Failed to unvote for OCMEM accesses\n");
-		}
-	}
-}
-
-static int protect_cp_mem(struct msm_vidc_core *core)
-{
-	struct tzbsp_memprot memprot;
-	unsigned int resp = 0;
-	int rc = 0;
-	struct msm_vidc_iommu_info *io_map = core->resources.io_map;
-	if (!io_map) {
-		dprintk(VIDC_ERR, "invalid params: %p\n", io_map);
-		return -EINVAL;
-	}
-	memprot.cp_start = 0x0;
-	memprot.cp_size = io_map[CP_MAP].addr_range[0] +
-			io_map[CP_MAP].addr_range[1];
-	memprot.cp_nonpixel_start = 0;
-	memprot.cp_nonpixel_size = 0;
-
-	rc = scm_call(SCM_SVC_CP, TZBSP_MEM_PROTECT_VIDEO_VAR, &memprot,
-			sizeof(memprot), &resp, sizeof(resp));
-	if (rc)
-		dprintk(VIDC_ERR,
-		"Failed to protect memory , rc is :%d, response : %d\n",
-		rc, resp);
-	return rc;
-}
-
-struct msm_vidc_core *get_vidc_core(int core_id)
-{
-	struct msm_vidc_core *core;
-	int found = 0;
-	unsigned long flags;
-	if (core_id > MSM_VIDC_CORES_MAX) {
-		dprintk(VIDC_ERR, "Core id = %d is greater than max = %d\n",
-			core_id, MSM_VIDC_CORES_MAX);
-		return NULL;
-	}
-	spin_lock_irqsave(&vidc_driver->lock, flags);
-	list_for_each_entry(core, &vidc_driver->cores, list) {
-		if (core && core->id == core_id)
-			found = 1;
-			break;
-	}
-	spin_unlock_irqrestore(&vidc_driver->lock, flags);
-	if (found)
-		return core;
-	return NULL;
-}
-
-static int msm_comm_iommu_attach(struct msm_vidc_core *core)
-{
-	int rc;
-	struct iommu_domain *domain;
-	int i;
-	struct msm_vidc_iommu_info *io_map;
-	struct device *dev;
-	for (i = 0; i < MAX_MAP; i++) {
-		io_map = &core->resources.io_map[i];
-		dev = msm_iommu_get_ctx(io_map->ctx);
-		domain = msm_get_iommu_domain(io_map->domain);
-		if (IS_ERR_OR_NULL(domain)) {
-			dprintk(VIDC_ERR,
-				"Failed to get domain: %s\n", io_map->name);
-			rc = PTR_ERR(domain);
-			break;
-		}
-		rc = iommu_attach_device(domain, dev);
-		if (rc) {
-			dprintk(VIDC_ERR,
-				"IOMMU attach failed: %s\n", io_map->name);
-			break;
-		}
-	}
-	if (i < MAX_MAP) {
-		i--;
-		for (; i >= 0; i--) {
-			io_map = &core->resources.io_map[i];
-			dev = msm_iommu_get_ctx(io_map->ctx);
-			domain = msm_get_iommu_domain(io_map->domain);
-			if (dev && domain)
-				iommu_detach_device(domain, dev);
-		}
-	}
-	return rc;
-}
-
-static void msm_comm_iommu_detach(struct msm_vidc_core *core)
-{
-	struct device *dev;
-	struct iommu_domain *domain;
-	struct msm_vidc_iommu_info *io_map;
-	int i;
-	if (!core) {
-		dprintk(VIDC_ERR, "Invalid paramter: %p\n", core);
-		return;
-	}
-	for (i = 0; i < MAX_MAP; i++) {
-		io_map = &core->resources.io_map[i];
-		dev = msm_iommu_get_ctx(io_map->ctx);
-		domain = msm_get_iommu_domain(io_map->domain);
-		if (dev && domain)
-			iommu_detach_device(domain, dev);
-	}
-}
-
-const struct msm_vidc_format *msm_comm_get_pixel_fmt_index(
-	const struct msm_vidc_format fmt[], int size, int index, int fmt_type)
-{
-	int i, k = 0;
-	if (!fmt || index < 0) {
-		dprintk(VIDC_ERR, "Invalid inputs, fmt = %p, index = %d\n",
-						fmt, index);
-		return NULL;
-	}
-	for (i = 0; i < size; i++) {
-		if (fmt[i].type != fmt_type)
-			continue;
-		if (k == index)
-			break;
-		k++;
-	}
-	if (i == size) {
-		dprintk(VIDC_INFO, "Format not found\n");
-		return NULL;
-	}
-	return &fmt[i];
-}
-const struct msm_vidc_format *msm_comm_get_pixel_fmt_fourcc(
-	const struct msm_vidc_format fmt[], int size, int fourcc, int fmt_type)
-{
-	int i;
-	if (!fmt) {
-		dprintk(VIDC_ERR, "Invalid inputs, fmt = %p\n", fmt);
-		return NULL;
-	}
-	for (i = 0; i < size; i++) {
-		if (fmt[i].fourcc == fourcc)
-				break;
-	}
-	if (i == size) {
-		dprintk(VIDC_INFO, "Format not found\n");
-		return NULL;
-	}
-	return &fmt[i];
-}
-
-struct buf_queue *msm_comm_get_vb2q(
-		struct msm_vidc_inst *inst,	enum v4l2_buf_type type)
-{
-	if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
-		return &inst->bufq[CAPTURE_PORT];
-	if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
-		return &inst->bufq[OUTPUT_PORT];
-	return NULL;
-}
-
-static void handle_sys_init_done(enum command_response cmd, void *data)
-{
-	struct msm_vidc_cb_cmd_done *response = data;
-	struct msm_vidc_core *core;
-	struct vidc_hal_sys_init_done *sys_init_msg;
-	int index = SYS_MSG_INDEX(cmd);
-	if (!response) {
-		dprintk(VIDC_ERR,
-			"Failed to get valid response for sys init\n");
-		return;
-	}
-	core = get_vidc_core(response->device_id);
-	if (!core) {
-		dprintk(VIDC_ERR, "Wrong device_id received\n");
-		return;
-	}
-	dprintk(VIDC_DBG, "index = %d\n", index);
-	dprintk(VIDC_DBG, "ptr = %p\n", &(core->completions[index]));
-	complete(&(core->completions[index]));
-	sys_init_msg = response->data;
-	if (!sys_init_msg) {
-		dprintk(VIDC_ERR, "sys_init_done message not proper\n");
-		return;
-	}
-}
-
-static void handle_session_release_buf_done(enum command_response cmd,
-	void *data)
-{
-	struct msm_vidc_cb_cmd_done *response = data;
-	struct msm_vidc_inst *inst;
-	struct internal_buf *buf;
-	struct list_head *ptr, *next;
-	struct hal_buffer_info *buffer;
-	u32 address, buf_found = false;
-
-	if (!response || !response->data) {
-		dprintk(VIDC_ERR, "Invalid release_buf_done response\n");
-		return;
-	}
-
-	inst = (struct msm_vidc_inst *)response->session_id;
-	buffer = (struct hal_buffer_info *) response->data;
-	address = (u32) buffer->buffer_addr;
-
-	list_for_each_safe(ptr, next, &inst->internalbufs) {
-		buf = list_entry(ptr, struct internal_buf, list);
-		if (address == buf->handle->device_addr) {
-			dprintk(VIDC_DBG, "releasing scratch: 0x%x",
-					(u32) buf->handle->device_addr);
-					buf_found = true;
-		}
-	}
-
-	list_for_each_safe(ptr, next, &inst->persistbufs) {
-		buf = list_entry(ptr, struct internal_buf, list);
-		if (address == (u32) buf->handle->device_addr) {
-			dprintk(VIDC_DBG, "releasing persist: 0x%x",
-					(u32) buf->handle->device_addr);
-			buf_found = true;
-		}
-	}
-
-	if (!buf_found)
-		dprintk(VIDC_ERR, "invalid buffer received from firmware");
-	complete(&inst->completions[SESSION_MSG_INDEX(cmd)]);
-}
-
-static void handle_sys_release_res_done(
-	enum command_response cmd, void *data)
-{
-	struct msm_vidc_cb_cmd_done *response = data;
-	struct msm_vidc_core *core;
-	if (!response) {
-		dprintk(VIDC_ERR,
-			"Failed to get valid response for sys init\n");
-		return;
-	}
-	core = get_vidc_core(response->device_id);
-	if (!core) {
-		dprintk(VIDC_ERR, "Wrong device_id received\n");
-		return;
-	}
-	complete(&core->completions[SYS_MSG_INDEX(cmd)]);
-}
-
-static void change_inst_state(struct msm_vidc_inst *inst,
-	enum instance_state state)
-{
-	unsigned long flags;
-	spin_lock_irqsave(&inst->lock, flags);
-	dprintk(VIDC_DBG, "Moved inst: %p from state: %d to state: %d\n",
-		   inst, inst->state, state);
-	inst->state = state;
-	spin_unlock_irqrestore(&inst->lock, flags);
-}
-
-static int signal_session_msg_receipt(enum command_response cmd,
-		struct msm_vidc_inst *inst)
-{
-	if (!inst) {
-		dprintk(VIDC_ERR, "Invalid(%p) instance id\n", inst);
-		return -EINVAL;
-	}
-	complete(&inst->completions[SESSION_MSG_INDEX(cmd)]);
-	return 0;
-}
-
-static int wait_for_sess_signal_receipt(struct msm_vidc_inst *inst,
-	enum command_response cmd)
-{
-	int rc = 0;
-	rc = wait_for_completion_interruptible_timeout(
-		&inst->completions[SESSION_MSG_INDEX(cmd)],
-		msecs_to_jiffies(HW_RESPONSE_TIMEOUT));
-	if (!rc) {
-		dprintk(VIDC_ERR, "Wait interrupted or timeout: %d\n", rc);
-		rc = -EIO;
-	} else {
-		rc = 0;
-	}
-	return rc;
-}
-
-static int wait_for_state(struct msm_vidc_inst *inst,
-	enum instance_state flipped_state,
-	enum instance_state desired_state,
-	enum command_response hal_cmd)
-{
-	int rc = 0;
-	if (IS_ALREADY_IN_STATE(flipped_state, desired_state)) {
-		dprintk(VIDC_INFO, "inst: %p is already in state: %d\n",
-						inst, inst->state);
-		goto err_same_state;
-	}
-	dprintk(VIDC_DBG, "Waiting for hal_cmd: %d\n", hal_cmd);
-	rc = wait_for_sess_signal_receipt(inst, hal_cmd);
-	if (!rc)
-		change_inst_state(inst, desired_state);
-err_same_state:
-	return rc;
-}
-
-static void handle_session_init_done(enum command_response cmd, void *data)
-{
-	struct msm_vidc_cb_cmd_done *response = data;
-	struct msm_vidc_inst *inst;
-	if (response) {
-		inst = (struct msm_vidc_inst *)response->session_id;
-		signal_session_msg_receipt(cmd, inst);
-	} else {
-		dprintk(VIDC_ERR,
-			"Failed to get valid response for session init\n");
-	}
-}
-
-static void handle_event_change(enum command_response cmd, void *data)
-{
-	struct msm_vidc_cb_cmd_done *response = data;
-	struct msm_vidc_inst *inst;
-	struct v4l2_event dqevent;
-	struct v4l2_control control = {0};
-	struct msm_vidc_cb_event *event_notify;
-	int rc = 0;
-	if (response) {
-		inst = (struct msm_vidc_inst *)response->session_id;
-		dqevent.id = 0;
-		event_notify = (struct msm_vidc_cb_event *) response->data;
-		switch (event_notify->hal_event_type) {
-		case HAL_EVENT_SEQ_CHANGED_SUFFICIENT_RESOURCES:
-			dqevent.type =
-				V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT;
-			control.id =
-				V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
-			rc = v4l2_g_ctrl(&inst->ctrl_handler, &control);
-			if (rc)
-				dprintk(VIDC_WARN,
-					"Failed to get Smooth streamng flag\n");
-			if (!rc && control.value == true)
-				dqevent.type =
-					V4L2_EVENT_SEQ_CHANGED_SUFFICIENT;
-			break;
-		case HAL_EVENT_SEQ_CHANGED_INSUFFICIENT_RESOURCES:
-			dqevent.type =
-				V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT;
-			break;
-		default:
-			break;
-		}
-		inst->reconfig_height = event_notify->height;
-		inst->reconfig_width = event_notify->width;
-		inst->in_reconfig = true;
-		v4l2_event_queue_fh(&inst->event_handler, &dqevent);
-		wake_up(&inst->kernel_event_queue);
-		return;
-	} else {
-		dprintk(VIDC_ERR,
-			"Failed to get valid response for event_change\n");
-	}
-}
-
-static void handle_session_prop_info(enum command_response cmd, void *data)
-{
-	struct msm_vidc_cb_cmd_done *response = data;
-	struct msm_vidc_inst *inst;
-	unsigned long flags;
-	int i;
-	if (!response || !response->data) {
-		dprintk(VIDC_ERR,
-			"Failed to get valid response for prop info\n");
-		return;
-	}
-	inst = (struct msm_vidc_inst *)response->session_id;
-	spin_lock_irqsave(&inst->lock, flags);
-	memcpy(&inst->buff_req, response->data,
-			sizeof(struct buffer_requirements));
-	spin_unlock_irqrestore(&inst->lock, flags);
-	for (i = 0; i < 8; i++) {
-		dprintk(VIDC_DBG,
-			"buffer type: %d, count : %d, size: %d\n",
-			inst->buff_req.buffer[i].buffer_type,
-			inst->buff_req.buffer[i].buffer_count_actual,
-			inst->buff_req.buffer[i].buffer_size);
-	}
-	signal_session_msg_receipt(cmd, inst);
-}
-
-static void handle_load_resource_done(enum command_response cmd, void *data)
-{
-	struct msm_vidc_cb_cmd_done *response = data;
-	struct msm_vidc_inst *inst;
-	if (response)
-		inst = (struct msm_vidc_inst *)response->session_id;
-	else
-		dprintk(VIDC_ERR,
-			"Failed to get valid response for load resource\n");
-}
-
-static void handle_start_done(enum command_response cmd, void *data)
-{
-	struct msm_vidc_cb_cmd_done *response = data;
-	struct msm_vidc_inst *inst;
-	if (response) {
-		inst = (struct msm_vidc_inst *)response->session_id;
-		signal_session_msg_receipt(cmd, inst);
-	} else {
-		dprintk(VIDC_ERR,
-			"Failed to get valid response for start\n");
-	}
-}
-
-static void handle_stop_done(enum command_response cmd, void *data)
-{
-	struct msm_vidc_cb_cmd_done *response = data;
-	struct msm_vidc_inst *inst;
-	if (response) {
-		inst = (struct msm_vidc_inst *)response->session_id;
-		signal_session_msg_receipt(cmd, inst);
-	} else {
-		dprintk(VIDC_ERR,
-			"Failed to get valid response for stop\n");
-	}
-}
-
-static void handle_release_res_done(enum command_response cmd, void *data)
-{
-	struct msm_vidc_cb_cmd_done *response = data;
-	struct msm_vidc_inst *inst;
-	if (response) {
-		inst = (struct msm_vidc_inst *)response->session_id;
-		signal_session_msg_receipt(cmd, inst);
-	} else {
-		dprintk(VIDC_ERR,
-			"Failed to get valid response for release resource\n");
-	}
-}
-
-static void handle_session_flush(enum command_response cmd, void *data)
-{
-	struct msm_vidc_cb_cmd_done *response = data;
-	struct msm_vidc_inst *inst;
-	struct v4l2_event dqevent;
-	if (response) {
-		inst = (struct msm_vidc_inst *)response->session_id;
-		dqevent.type = V4L2_EVENT_MSM_VIDC_FLUSH_DONE;
-		dqevent.id = 0;
-		v4l2_event_queue_fh(&inst->event_handler, &dqevent);
-		wake_up(&inst->kernel_event_queue);
-	} else {
-		dprintk(VIDC_ERR, "Failed to get valid response for flush\n");
-	}
-}
-
-static void handle_session_error(enum command_response cmd, void *data)
-{
-	struct msm_vidc_cb_cmd_done *response = data;
-	struct msm_vidc_inst *inst = NULL;
-	struct v4l2_event dqevent;
-	if (response) {
-		inst = (struct msm_vidc_inst *)response->session_id;
-		if (inst) {
-			dprintk(VIDC_WARN,
-				"Session error receivd for session %p\n", inst);
-			mutex_lock(&inst->sync_lock);
-			inst->state = MSM_VIDC_CORE_INVALID;
-			mutex_unlock(&inst->sync_lock);
-			dqevent.type = V4L2_EVENT_MSM_VIDC_SYS_ERROR;
-			dqevent.id = 0;
-			v4l2_event_queue_fh(&inst->event_handler, &dqevent);
-			wake_up(&inst->kernel_event_queue);
-		}
-	} else {
-		dprintk(VIDC_ERR,
-			"Failed to get valid response for session error\n");
-	}
-}
-static void handle_sys_error(enum command_response cmd, void *data)
-{
-	struct msm_vidc_cb_cmd_done *response = data;
-	struct msm_vidc_inst *inst = NULL ;
-	struct msm_vidc_core *core = NULL;
-	struct v4l2_event dqevent;
-	unsigned long flags;
-	if (response) {
-		core = get_vidc_core(response->device_id);
-		dprintk(VIDC_WARN, "SYS_ERROR received for core %p\n", core);
-		if (core) {
-			spin_lock_irqsave(&core->lock, flags);
-			core->state = VIDC_CORE_INVALID;
-			spin_unlock_irqrestore(&core->lock, flags);
-			dqevent.type = V4L2_EVENT_MSM_VIDC_SYS_ERROR;
-			dqevent.id = 0;
-			list_for_each_entry(inst, &core->instances,
-					list) {
-				v4l2_event_queue_fh(&inst->event_handler,
-						&dqevent);
-
-				spin_lock_irqsave(&inst->lock, flags);
-				inst->state = MSM_VIDC_CORE_INVALID;
-				spin_unlock_irqrestore(&inst->lock, flags);
-
-				wake_up(&inst->kernel_event_queue);
-			}
-		} else {
-			dprintk(VIDC_ERR,
-				"Got SYS_ERR but unable to identify core");
-		}
-	} else {
-		dprintk(VIDC_ERR,
-			"Failed to get valid response for sys error\n");
-	}
-}
-
-static void handle_sys_watchdog_timeout(enum command_response cmd, void *data)
-{
-	struct msm_vidc_cb_cmd_done *response = data;
-	struct msm_vidc_inst *inst;
-	struct msm_vidc_core *core = NULL;
-	struct v4l2_event dqevent;
-	unsigned long flags;
-	dprintk(VIDC_ERR, "Venus Subsystem crashed\n");
-	core = get_vidc_core(response->device_id);
-	if (!core) {
-		dprintk(VIDC_ERR, "Wrong device_id received\n");
-		return;
-	}
-	subsystem_crashed("venus");
-	spin_lock_irqsave(&core->lock, flags);
-	core->state = VIDC_CORE_INVALID;
-	spin_unlock_irqrestore(&core->lock, flags);
-	dqevent.type = V4L2_EVENT_MSM_VIDC_SYS_ERROR;
-	dqevent.id = 0;
-	list_for_each_entry(inst, &core->instances, list) {
-		if (inst) {
-			v4l2_event_queue_fh(&inst->event_handler, &dqevent);
-			spin_lock_irqsave(&inst->lock, flags);
-			inst->state = MSM_VIDC_CORE_INVALID;
-			inst->session = NULL;
-			spin_unlock_irqrestore(&inst->lock, flags);
-		}
-	}
-}
-
-static void handle_session_close(enum command_response cmd, void *data)
-{
-	struct msm_vidc_cb_cmd_done *response = data;
-	struct msm_vidc_inst *inst;
-	struct v4l2_event dqevent;
-	if (response) {
-		inst = (struct msm_vidc_inst *)response->session_id;
-		signal_session_msg_receipt(cmd, inst);
-		dqevent.type = V4L2_EVENT_MSM_VIDC_CLOSE_DONE;
-		dqevent.id = 0;
-		v4l2_event_queue_fh(&inst->event_handler, &dqevent);
-		inst->session = NULL;
-		wake_up(&inst->kernel_event_queue);
-		show_stats(inst);
-	} else {
-		dprintk(VIDC_ERR,
-			"Failed to get valid response for session close\n");
-	}
-}
-
-static struct vb2_buffer *get_vb_from_device_addr(struct buf_queue *bufq,
-		u32 dev_addr)
-{
-	struct vb2_buffer *vb = NULL;
-	struct vb2_queue *q = NULL;
-	int found = 0;
-	if (!bufq) {
-		dprintk(VIDC_ERR, "Invalid parameter\n");
-		return NULL;
-	}
-	q = &bufq->vb2_bufq;
-	mutex_lock(&bufq->lock);
-	list_for_each_entry(vb, &q->queued_list, queued_entry) {
-		if (vb->v4l2_planes[0].m.userptr == dev_addr) {
-			found = 1;
-			break;
-		}
-	}
-	mutex_unlock(&bufq->lock);
-	if (!found) {
-		dprintk(VIDC_ERR,
-			"Failed to find the buffer in queued list: 0x%x, %d\n",
-			dev_addr, q->type);
-		vb = NULL;
-	}
-	return vb;
-}
-
-static void handle_ebd(enum command_response cmd, void *data)
-{
-	struct msm_vidc_cb_data_done *response = data;
-	struct vb2_buffer *vb;
-	struct msm_vidc_inst *inst;
-	if (!response) {
-		dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
-		return;
-	}
-	vb = response->clnt_data;
-	inst = (struct msm_vidc_inst *)response->session_id;
-	if (vb) {
-		mutex_lock(&inst->bufq[OUTPUT_PORT].lock);
-		vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
-		mutex_unlock(&inst->bufq[OUTPUT_PORT].lock);
-		wake_up(&inst->kernel_event_queue);
-		msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_EBD);
-	}
-}
-
-static void msm_comm_update_clocks(struct msm_vidc_inst *inst,
-	u64 cur_time_stamp)
-{
-	u32 new_time_diff = 0, cur_time_diff = 0;
-	u8 updated_fps = 0;
-	struct v4l2_ctrl *ctrl = NULL;
-	u32 output_order = 0;
-
-	if (inst->session_type == MSM_VIDC_ENCODER)
-		goto exit;
-	if (cur_time_stamp >= LLONG_MAX) {
-		dprintk(VIDC_WARN,
-			"Clock scaling failed : Timestamp invalid\n");
-		goto exit;
-	}
-	ctrl = v4l2_ctrl_find(&inst->ctrl_handler,
-		V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER);
-	if (!ctrl) {
-		dprintk(VIDC_WARN, "Unable to find output order control\n");
-		dprintk(VIDC_WARN,
-			"Performance might be impacted for higher fps clips\n");
-		goto exit;
-	}
-	output_order = v4l2_ctrl_g_ctrl(ctrl);
-	if (output_order == V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY) {
-		new_time_diff =
-			(u32)(cur_time_stamp - inst->prop.prev_time_stamp);
-		inst->prop.prev_time_stamp = cur_time_stamp;
-		if (!new_time_diff)
-			goto exit;
-		if (inst->prop.fps)
-			cur_time_diff = USEC_PER_SEC / inst->prop.fps;
-		cur_time_diff = cur_time_diff > new_time_diff ?
-			cur_time_diff - new_time_diff :
-			new_time_diff - cur_time_diff;
-		if (cur_time_diff > TIME_DIFF_THRESHOLD) {
-			updated_fps = (u8) (USEC_PER_SEC / new_time_diff);
-			if (updated_fps && (updated_fps != inst->prop.fps)) {
-				inst->prop.fps = updated_fps;
-				dprintk(VIDC_DBG,
-						"Updating clocks: Decoding fps = %d\n",
-						inst->prop.fps);
-				msm_comm_scale_clocks_and_bus(inst);
-			}
-		}
-	}
-exit:
-	return;
-}
-
-static void handle_fbd(enum command_response cmd, void *data)
-{
-	struct msm_vidc_cb_data_done *response = data;
-	struct msm_vidc_inst *inst;
-	struct vb2_buffer *vb;
-	struct vidc_hal_fbd *fill_buf_done;
-
-	if (!response) {
-		dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
-		return;
-	}
-	inst = (struct msm_vidc_inst *)response->session_id;
-	fill_buf_done = (struct vidc_hal_fbd *)&response->output_done;
-	vb = get_vb_from_device_addr(&inst->bufq[CAPTURE_PORT],
-		(u32)fill_buf_done->packet_buffer1);
-	if (vb) {
-		vb->v4l2_planes[0].bytesused = fill_buf_done->filled_len1;
-		if (!(fill_buf_done->flags1 &
-			HAL_BUFFERFLAG_TIMESTAMPINVALID)) {
-			int64_t time_usec = fill_buf_done->timestamp_hi;
-			time_usec = (time_usec << 32) |
-				fill_buf_done->timestamp_lo;
-			vb->v4l2_buf.timestamp =
-				ns_to_timeval(time_usec * NSEC_PER_USEC);
-				msm_comm_update_clocks(inst, time_usec);
-		}
-		vb->v4l2_buf.flags = 0;
-
-		if (fill_buf_done->flags1 & HAL_BUFFERFLAG_EOS)
-			vb->v4l2_buf.flags |= V4L2_BUF_FLAG_EOS;
-		if (fill_buf_done->flags1 & HAL_BUFFERFLAG_CODECCONFIG)
-			vb->v4l2_buf.flags &= ~V4L2_QCOM_BUF_FLAG_CODECCONFIG;
-		if (fill_buf_done->flags1 & HAL_BUFFERFLAG_SYNCFRAME)
-			vb->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME;
-		if (fill_buf_done->flags1 & HAL_BUFFERFLAG_EOSEQ)
-			vb->v4l2_buf.flags |= V4L2_QCOM_BUF_FLAG_EOSEQ;
-		switch (fill_buf_done->picture_type) {
-		case HAL_PICTURE_IDR:
-		case HAL_PICTURE_I:
-			vb->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME;
-			break;
-		case HAL_PICTURE_P:
-			vb->v4l2_buf.flags |= V4L2_BUF_FLAG_PFRAME;
-			break;
-		case HAL_PICTURE_B:
-			vb->v4l2_buf.flags |= V4L2_BUF_FLAG_BFRAME;
-			break;
-		case HAL_FRAME_NOTCODED:
-		case HAL_UNUSED_PICT:
-			/* Do we need to care about these? */
-		case HAL_FRAME_YUV:
-			break;
-		default:
-			break;
-		}
-		inst->count.fbd++;
-		if (fill_buf_done->filled_len1)
-			msm_vidc_debugfs_update(inst,
-				MSM_VIDC_DEBUGFS_EVENT_FBD);
-
-		dprintk(VIDC_DBG, "Filled length = %d; flags %x\n",
-				vb->v4l2_planes[0].bytesused,
-				vb->v4l2_buf.flags);
-		mutex_lock(&inst->bufq[CAPTURE_PORT].lock);
-		vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
-		mutex_unlock(&inst->bufq[CAPTURE_PORT].lock);
-		wake_up(&inst->kernel_event_queue);
-	} else {
-		/*
-		 * FIXME:
-		 * Special handling for EOS case: if we sent a 0 length input
-		 * buf with EOS set, Venus doesn't return a valid output buffer.
-		 * So pick up a random buffer that's with us, and send it to
-		 * v4l2 client with EOS flag set.
-		 *
-		 * This would normally be OK unless client decides to send
-		 * frames even after EOS.
-		 *
-		 * This should be fixed in upcoming versions of firmware
-		 */
-		if (fill_buf_done->flags1 & HAL_BUFFERFLAG_EOS
-			&& fill_buf_done->filled_len1 == 0) {
-			struct buf_queue *q = &inst->bufq[CAPTURE_PORT];
-
-			if (!list_empty(&q->vb2_bufq.queued_list)) {
-				vb = list_first_entry(&q->vb2_bufq.queued_list,
-					struct vb2_buffer, queued_entry);
-				vb->v4l2_planes[0].bytesused = 0;
-				vb->v4l2_buf.flags |= V4L2_BUF_FLAG_EOS;
-				mutex_lock(&q->lock);
-				vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
-				mutex_unlock(&q->lock);
-			}
-
-		}
-	}
-}
-
-static void  handle_seq_hdr_done(enum command_response cmd, void *data)
-{
-	struct msm_vidc_cb_data_done *response = data;
-	struct msm_vidc_inst *inst;
-	struct vb2_buffer *vb;
-	struct vidc_hal_fbd *fill_buf_done;
-	if (!response) {
-		dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
-		return;
-	}
-	inst = (struct msm_vidc_inst *)response->session_id;
-	fill_buf_done = (struct vidc_hal_fbd *)&response->output_done;
-	vb = get_vb_from_device_addr(&inst->bufq[CAPTURE_PORT],
-		(u32)fill_buf_done->packet_buffer1);
-	if (vb)
-		vb->v4l2_planes[0].bytesused = fill_buf_done->filled_len1;
-
-	vb->v4l2_buf.flags = V4L2_QCOM_BUF_FLAG_CODECCONFIG;
-
-	dprintk(VIDC_DBG, "Filled length = %d; flags %x\n",
-				vb->v4l2_planes[0].bytesused,
-				vb->v4l2_buf.flags);
-	mutex_lock(&inst->bufq[CAPTURE_PORT].lock);
-	vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
-	mutex_unlock(&inst->bufq[CAPTURE_PORT].lock);
-}
-
-void handle_cmd_response(enum command_response cmd, void *data)
-{
-	dprintk(VIDC_DBG, "Command response = %d\n", cmd);
-	switch (cmd) {
-	case SYS_INIT_DONE:
-		handle_sys_init_done(cmd, data);
-		break;
-	case RELEASE_RESOURCE_DONE:
-		handle_sys_release_res_done(cmd, data);
-		break;
-	case SESSION_INIT_DONE:
-		handle_session_init_done(cmd, data);
-		break;
-	case SESSION_PROPERTY_INFO:
-		handle_session_prop_info(cmd, data);
-		break;
-	case SESSION_LOAD_RESOURCE_DONE:
-		handle_load_resource_done(cmd, data);
-		break;
-	case SESSION_START_DONE:
-		handle_start_done(cmd, data);
-		break;
-	case SESSION_ETB_DONE:
-		handle_ebd(cmd, data);
-		break;
-	case SESSION_FTB_DONE:
-		handle_fbd(cmd, data);
-		break;
-	case SESSION_STOP_DONE:
-		handle_stop_done(cmd, data);
-		break;
-	case SESSION_RELEASE_RESOURCE_DONE:
-		handle_release_res_done(cmd, data);
-		break;
-	case SESSION_END_DONE:
-		handle_session_close(cmd, data);
-		break;
-	case VIDC_EVENT_CHANGE:
-		handle_event_change(cmd, data);
-		break;
-	case SESSION_FLUSH_DONE:
-		handle_session_flush(cmd, data);
-		break;
-	case SESSION_GET_SEQ_HDR_DONE:
-		handle_seq_hdr_done(cmd, data);
-		break;
-	case SYS_WATCHDOG_TIMEOUT:
-		handle_sys_watchdog_timeout(cmd, data);
-		break;
-	case SYS_ERROR:
-		handle_sys_error(cmd, data);
-		break;
-	case SESSION_ERROR:
-		handle_session_error(cmd, data);
-		break;
-	case SESSION_RELEASE_BUFFER_DONE:
-		handle_session_release_buf_done(cmd, data);
-		break;
-	default:
-		dprintk(VIDC_ERR, "response unhandled\n");
-		break;
-	}
-}
-
-static int msm_comm_scale_clocks(struct msm_vidc_core *core)
-{
-	int num_mbs_per_sec;
-	int rc = 0;
-	if (!core) {
-		dprintk(VIDC_ERR, "Invalid args: %p\n", core);
-		return -EINVAL;
-	}
-	num_mbs_per_sec = msm_comm_get_load(core, MSM_VIDC_ENCODER);
-	num_mbs_per_sec += msm_comm_get_load(core, MSM_VIDC_DECODER);
-	dprintk(VIDC_INFO, "num_mbs_per_sec = %d\n", num_mbs_per_sec);
-	rc = clk_set_rate(core->resources.clock[VCODEC_CLK].clk,
-			get_clock_rate(&core->resources.clock[VCODEC_CLK],
-				num_mbs_per_sec));
-	if (rc)
-		dprintk(VIDC_ERR, "Failed to set clock rate: %d\n", rc);
-	return rc;
-}
-
-static inline int msm_comm_enable_clks(struct msm_vidc_core *core)
-{
-	int i;
-	struct core_clock *cl;
-	int rc = 0;
-	if (!core) {
-		dprintk(VIDC_ERR, "Invalid params: %p\n", core);
-		return -EINVAL;
-	}
-	for (i = 0; i < VCODEC_MAX_CLKS; i++) {
-		cl = &core->resources.clock[i];
-		rc = clk_prepare_enable(cl->clk);
-		if (rc) {
-			dprintk(VIDC_ERR, "Failed to enable clocks\n");
-			goto fail_clk_enable;
-		} else {
-			dprintk(VIDC_DBG, "Clock: %s enabled\n", cl->name);
-		}
-	}
-	return rc;
-fail_clk_enable:
-	for (; i >= 0; i--) {
-		cl = &core->resources.clock[i];
-		clk_disable_unprepare(cl->clk);
-	}
-	return rc;
-}
-
-static inline void msm_comm_disable_clks(struct msm_vidc_core *core)
-{
-	int i;
-	struct core_clock *cl;
-	if (!core) {
-		dprintk(VIDC_ERR, "Invalid params: %p\n", core);
-		return;
-	}
-	for (i = 0; i < VCODEC_MAX_CLKS; i++) {
-		cl = &core->resources.clock[i];
-		clk_disable_unprepare(cl->clk);
-	}
-}
-
-void msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst)
-{
-	struct msm_vidc_core *core = inst->core;
-	if (!inst) {
-		dprintk(VIDC_WARN, "Invalid params\n");
-		return;
-	}
-	if (msm_comm_scale_clocks(core)) {
-		dprintk(VIDC_WARN,
-				"Failed to scale clocks. Performance might be impacted\n");
-	}
-	if (msm_comm_scale_bus(core, inst->session_type, DDR_MEM)) {
-		dprintk(VIDC_WARN,
-				"Failed to scale DDR bus. Performance might be impacted\n");
-	}
-	if (core->resources.ocmem.buf) {
-		if (msm_comm_scale_bus(core, inst->session_type,
-					OCMEM_MEM))
-			dprintk(VIDC_WARN,
-					"Failed to scale OCMEM bus. Performance might be impacted\n");
-	}
-}
-
-static int msm_comm_load_fw(struct msm_vidc_core *core)
-{
-	int rc = 0;
-	if (!core) {
-		dprintk(VIDC_ERR, "Invalid paramter: %p\n", core);
-		return -EINVAL;
-	}
-	if (!core->resources.fw.cookie)
-		core->resources.fw.cookie = subsystem_get("venus");
-
-	if (IS_ERR_OR_NULL(core->resources.fw.cookie)) {
-		dprintk(VIDC_ERR, "Failed to download firmware\n");
-		rc = -ENOMEM;
-		goto fail_load_fw;
-	}
-	/*Clocks can be enabled only after pil_get since
-	 * gdsc is turned-on in pil_get*/
-	rc = msm_comm_enable_clks(core);
-	if (rc) {
-		dprintk(VIDC_ERR, "Failed to enable clocks: %d\n", rc);
-		goto fail_enable_clks;
-	}
-
-	rc = protect_cp_mem(core);
-	if (rc) {
-		dprintk(VIDC_ERR, "Failed to protect memory\n");
-		goto fail_iommu_attach;
-	}
-
-	rc = msm_comm_iommu_attach(core);
-	if (rc) {
-		dprintk(VIDC_ERR, "Failed to attach iommu");
-		goto fail_iommu_attach;
-	}
-	return rc;
-fail_iommu_attach:
-	msm_comm_disable_clks(core);
-fail_enable_clks:
-	subsystem_put(core->resources.fw.cookie);
-	core->resources.fw.cookie = NULL;
-fail_load_fw:
-	return rc;
-}
-
-static void msm_comm_unload_fw(struct msm_vidc_core *core)
-{
-	if (!core) {
-		dprintk(VIDC_ERR, "Invalid paramter: %p\n", core);
-		return;
-	}
-	if (core->resources.fw.cookie) {
-		msm_comm_iommu_detach(core);
-		msm_comm_disable_clks(core);
-		subsystem_put(core->resources.fw.cookie);
-		core->resources.fw.cookie = NULL;
-	}
-}
-
-static inline unsigned long get_ocmem_requirement(u32 height, u32 width)
-{
-	int num_mbs = 0;
-	num_mbs = GET_NUM_MBS(height, width);
-	/*TODO: This should be changes once the numbers are
-	 * available from firmware*/
-	return 512 * 1024;
-}
-
-static int msm_comm_set_ocmem(struct msm_vidc_core *core,
-	struct ocmem_buf *ocmem)
-{
-	struct vidc_resource_hdr rhdr;
-	int rc = 0;
-	if (!core || !ocmem) {
-		dprintk(VIDC_ERR, "Invalid params, core:%p, ocmem: %p\n",
-			core, ocmem);
-		return -EINVAL;
-	}
-	rhdr.resource_id = VIDC_RESOURCE_OCMEM;
-	rhdr.resource_handle = (u32) &core->resources.ocmem;
-	rhdr.size =	ocmem->len;
-	rc = vidc_hal_core_set_resource(core->device, &rhdr, ocmem);
-	if (rc) {
-		dprintk(VIDC_ERR, "Failed to set OCMEM on driver\n");
-		goto ocmem_set_failed;
-	}
-	dprintk(VIDC_DBG, "OCMEM set, addr = %lx, size: %ld\n",
-		ocmem->addr, ocmem->len);
-ocmem_set_failed:
-	return rc;
-}
-
-static int msm_comm_unset_ocmem(struct msm_vidc_core *core)
-{
-	struct vidc_resource_hdr rhdr;
-	int rc = 0;
-	if (!core || !core->resources.ocmem.buf) {
-		dprintk(VIDC_ERR, "Invalid params, core:%p\n",	core);
-		return -EINVAL;
-	}
-	if (core->state == VIDC_CORE_INVALID) {
-		dprintk(VIDC_ERR,
-				"Core is in bad state. Cannot unset ocmem\n");
-		return -EIO;
-	}
-	rhdr.resource_id = VIDC_RESOURCE_OCMEM;
-	rhdr.resource_handle = (u32) &core->resources.ocmem;
-	init_completion(
-		&core->completions[SYS_MSG_INDEX(RELEASE_RESOURCE_DONE)]);
-	rc = vidc_hal_core_release_resource(core->device, &rhdr);
-	if (rc) {
-		dprintk(VIDC_ERR, "Failed to set OCMEM on driver\n");
-		goto release_ocmem_failed;
-	}
-	rc = wait_for_completion_timeout(
-		&core->completions[SYS_MSG_INDEX(RELEASE_RESOURCE_DONE)],
-		msecs_to_jiffies(HW_RESPONSE_TIMEOUT));
-	if (!rc) {
-		dprintk(VIDC_ERR, "Wait interrupted or timeout: %d\n", rc);
-		rc = -EIO;
-		goto release_ocmem_failed;
-	}
-release_ocmem_failed:
-	return rc;
-}
-
-static int msm_comm_alloc_ocmem(struct msm_vidc_core *core,
-		unsigned long size)
-{
-	int rc = 0;
-	struct ocmem_buf *ocmem_buffer;
-	mutex_lock(&core->sync_lock);
-	if (!core || !size) {
-		dprintk(VIDC_ERR,
-			"Invalid param, core: %p, size: %lu\n", core, size);
-		return -EINVAL;
-	}
-	ocmem_buffer = core->resources.ocmem.buf;
-	if (!ocmem_buffer ||
-		ocmem_buffer->len < size) {
-		ocmem_buffer = ocmem_allocate_nb(OCMEM_VIDEO, size);
-		if (IS_ERR_OR_NULL(ocmem_buffer)) {
-			dprintk(VIDC_ERR,
-				"ocmem_allocate_nb failed: %d\n",
-				(u32) ocmem_buffer);
-			rc = -ENOMEM;
-		}
-		core->resources.ocmem.buf = ocmem_buffer;
-		rc = msm_comm_set_ocmem(core, ocmem_buffer);
-		if (rc) {
-			dprintk(VIDC_ERR, "Failed to set ocmem: %d\n", rc);
-			goto ocmem_set_failed;
-		}
-	} else
-		dprintk(VIDC_DBG,
-			"OCMEM is enough. reqd: %lu, available: %lu\n",
-			size, ocmem_buffer->len);
-
-ocmem_set_failed:
-	mutex_unlock(&core->sync_lock);
-	return rc;
-}
-
-static int msm_comm_free_ocmem(struct msm_vidc_core *core)
-{
-	int rc = 0;
-	if (core->resources.ocmem.buf) {
-		rc = ocmem_free(OCMEM_VIDEO, core->resources.ocmem.buf);
-		if (rc)
-			dprintk(VIDC_ERR, "Failed to free ocmem\n");
-	}
-	core->resources.ocmem.buf = NULL;
-	return rc;
-}
-
-int msm_vidc_ocmem_notify_handler(struct notifier_block *this,
-		unsigned long event, void *data)
-{
-	struct ocmem_buf *buff = data;
-	struct msm_vidc_core *core;
-	struct msm_vidc_resources *resources;
-	struct on_chip_mem *ocmem;
-	int rc = NOTIFY_DONE;
-	if (event == OCMEM_ALLOC_GROW) {
-		ocmem = container_of(this, struct on_chip_mem, vidc_ocmem_nb);
-		if (!ocmem) {
-			dprintk(VIDC_ERR, "Wrong handler passed\n");
-			rc = NOTIFY_BAD;
-			goto bad_notfier;
-		}
-		resources = container_of(ocmem,
-			struct msm_vidc_resources, ocmem);
-		core = container_of(resources,
-			struct msm_vidc_core, resources);
-		if (msm_comm_set_ocmem(core, buff)) {
-			dprintk(VIDC_ERR, "Failed to set ocmem: %d\n", rc);
-			goto ocmem_set_failed;
-		}
-		rc = NOTIFY_OK;
-	}
-ocmem_set_failed:
-bad_notfier:
-	return rc;
-}
-
-static int msm_comm_init_core_done(struct msm_vidc_inst *inst)
-{
-	struct msm_vidc_core *core = inst->core;
-	unsigned long flags;
-	int rc = 0;
-	mutex_lock(&core->sync_lock);
-	if (core->state >= VIDC_CORE_INIT_DONE) {
-		dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n",
-				core->id, core->state);
-		goto core_already_inited;
-	}
-	dprintk(VIDC_DBG, "Waiting for SYS_INIT_DONE\n");
-	rc = wait_for_completion_timeout(
-		&core->completions[SYS_MSG_INDEX(SYS_INIT_DONE)],
-		msecs_to_jiffies(HW_RESPONSE_TIMEOUT));
-	if (!rc) {
-		dprintk(VIDC_ERR, "Wait interrupted or timeout: %d\n", rc);
-		rc = -EIO;
-		goto exit;
-	} else {
-		spin_lock_irqsave(&core->lock, flags);
-		core->state = VIDC_CORE_INIT_DONE;
-		spin_unlock_irqrestore(&core->lock, flags);
-	}
-	dprintk(VIDC_DBG, "SYS_INIT_DONE!!!\n");
-core_already_inited:
-	change_inst_state(inst, MSM_VIDC_CORE_INIT_DONE);
-	rc = 0;
-exit:
-	mutex_unlock(&core->sync_lock);
-	return rc;
-}
-
-static int msm_comm_init_core(struct msm_vidc_inst *inst)
-{
-	int rc = 0;
-	struct msm_vidc_core *core = inst->core;
-	unsigned long flags;
-	mutex_lock(&core->sync_lock);
-	if (core->state >= VIDC_CORE_INIT) {
-		dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n",
-				core->id, core->state);
-		goto core_already_inited;
-	}
-
-	rc = msm_comm_scale_bus(core, inst->session_type, DDR_MEM);
-	if (rc) {
-		dprintk(VIDC_ERR, "Failed to scale DDR bus: %d\n", rc);
-		goto fail_scale_bus;
-	}
-
-	rc = msm_comm_load_fw(core);
-	if (rc) {
-		dprintk(VIDC_ERR, "Failed to load video firmware\n");
-		goto fail_load_fw;
-	}
-	rc = msm_comm_scale_clocks(core);
-	if (rc) {
-		dprintk(VIDC_ERR, "Failed to scale clocks: %d\n", rc);
-		goto fail_core_init;
-	}
-
-	init_completion(&core->completions[SYS_MSG_INDEX(SYS_INIT_DONE)]);
-	rc = vidc_hal_core_init(core->device,
-		core->resources.io_map[NS_MAP].domain);
-	if (rc) {
-		dprintk(VIDC_ERR, "Failed to init core, id = %d\n", core->id);
-		goto fail_core_init;
-	}
-	spin_lock_irqsave(&core->lock, flags);
-	core->state = VIDC_CORE_INIT;
-	spin_unlock_irqrestore(&core->lock, flags);
-core_already_inited:
-	change_inst_state(inst, MSM_VIDC_CORE_INIT);
-	mutex_unlock(&core->sync_lock);
-	return rc;
-fail_core_init:
-	msm_comm_unload_fw(core);
-fail_load_fw:
-	msm_comm_unvote_buses(core, DDR_MEM);
-fail_scale_bus:
-	mutex_unlock(&core->sync_lock);
-	return rc;
-}
-
-static int msm_vidc_deinit_core(struct msm_vidc_inst *inst)
-{
-	int rc = 0;
-	struct msm_vidc_core *core = inst->core;
-	unsigned long flags;
-	mutex_lock(&core->sync_lock);
-	if (core->state == VIDC_CORE_UNINIT) {
-		dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n",
-				core->id, core->state);
-		goto core_already_uninited;
-	}
-	msm_comm_scale_clocks_and_bus(inst);
-	if (list_empty(&core->instances)) {
-		msm_comm_unset_ocmem(core);
-		msm_comm_free_ocmem(core);
-		dprintk(VIDC_DBG, "Calling vidc_hal_core_release\n");
-		rc = vidc_hal_core_release(core->device);
-		if (rc) {
-			dprintk(VIDC_ERR, "Failed to release core, id = %d\n",
-							core->id);
-			goto exit;
-		}
-		spin_lock_irqsave(&core->lock, flags);
-		core->state = VIDC_CORE_UNINIT;
-		spin_unlock_irqrestore(&core->lock, flags);
-		msm_comm_unload_fw(core);
-		msm_comm_unvote_buses(core, DDR_MEM|OCMEM_MEM);
-	}
-core_already_uninited:
-	change_inst_state(inst, MSM_VIDC_CORE_UNINIT);
-exit:
-	mutex_unlock(&core->sync_lock);
-	return rc;
-}
-
-int msm_comm_force_cleanup(struct msm_vidc_inst *inst)
-{
-	return msm_vidc_deinit_core(inst);
-}
-
-static enum hal_domain get_hal_domain(int session_type)
-{
-	enum hal_domain domain;
-	switch (session_type) {
-	case MSM_VIDC_ENCODER:
-		domain = HAL_VIDEO_DOMAIN_ENCODER;
-		break;
-	case MSM_VIDC_DECODER:
-		domain = HAL_VIDEO_DOMAIN_DECODER;
-		break;
-	default:
-		dprintk(VIDC_ERR, "Wrong domain\n");
-		domain = HAL_UNUSED_DOMAIN;
-		break;
-	}
-	return domain;
-}
-
-static enum hal_video_codec get_hal_codec_type(int fourcc)
-{
-	enum hal_video_codec codec;
-	dprintk(VIDC_DBG, "codec is 0x%x", fourcc);
-	switch (fourcc) {
-	case V4L2_PIX_FMT_H264:
-	case V4L2_PIX_FMT_H264_NO_SC:
-		codec = HAL_VIDEO_CODEC_H264;
-		break;
-	case V4L2_PIX_FMT_H263:
-		codec = HAL_VIDEO_CODEC_H263;
-		break;
-	case V4L2_PIX_FMT_MPEG1:
-		codec = HAL_VIDEO_CODEC_MPEG1;
-		break;
-	case V4L2_PIX_FMT_MPEG2:
-		codec = HAL_VIDEO_CODEC_MPEG2;
-		break;
-	case V4L2_PIX_FMT_MPEG4:
-		codec = HAL_VIDEO_CODEC_MPEG4;
-		break;
-	case V4L2_PIX_FMT_VC1_ANNEX_G:
-	case V4L2_PIX_FMT_VC1_ANNEX_L:
-		codec = HAL_VIDEO_CODEC_VC1;
-		break;
-	case V4L2_PIX_FMT_VP8:
-		codec = HAL_VIDEO_CODEC_VP8;
-		break;
-	case V4L2_PIX_FMT_DIVX_311:
-		codec = HAL_VIDEO_CODEC_DIVX_311;
-		break;
-	case V4L2_PIX_FMT_DIVX:
-		codec = HAL_VIDEO_CODEC_DIVX;
-		break;
-		/*HAL_VIDEO_CODEC_MVC
-		  HAL_VIDEO_CODEC_SPARK
-		  HAL_VIDEO_CODEC_VP6
-		  HAL_VIDEO_CODEC_VP7*/
-	default:
-		dprintk(VIDC_ERR, "Wrong codec: %d\n", fourcc);
-		codec = HAL_UNUSED_CODEC;
-	}
-	return codec;
-}
-
-static int msm_comm_session_init(int flipped_state,
-	struct msm_vidc_inst *inst)
-{
-	int rc = 0;
-	int fourcc = 0;
-	if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_OPEN)) {
-		dprintk(VIDC_INFO, "inst: %p is already in state: %d\n",
-						inst, inst->state);
-		goto exit;
-	}
-	if (inst->session_type == MSM_VIDC_DECODER) {
-		fourcc = inst->fmts[OUTPUT_PORT]->fourcc;
-	} else if (inst->session_type == MSM_VIDC_ENCODER) {
-		fourcc = inst->fmts[CAPTURE_PORT]->fourcc;
-	} else {
-		dprintk(VIDC_ERR, "Invalid session\n");
-		return -EINVAL;
-	}
-	init_completion(
-		&inst->completions[SESSION_MSG_INDEX(SESSION_INIT_DONE)]);
-	inst->session = vidc_hal_session_init(inst->core->device, (u32) inst,
-					get_hal_domain(inst->session_type),
-					get_hal_codec_type(fourcc));
-	if (!inst->session) {
-		dprintk(VIDC_ERR,
-			"Failed to call session init for: %d, %d, %d, %d\n",
-			(int)inst->core->device, (int)inst,
-			inst->session_type, fourcc);
-		goto exit;
-	}
-	inst->ftb_count = 0;
-	change_inst_state(inst, MSM_VIDC_OPEN);
-exit:
-	return rc;
-}
-
-static int msm_vidc_load_resources(int flipped_state,
-	struct msm_vidc_inst *inst)
-{
-	int rc = 0;
-	u32 ocmem_sz = 0;
-	if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_LOAD_RESOURCES)) {
-		dprintk(VIDC_INFO, "inst: %p is already in state: %d\n",
-						inst, inst->state);
-		goto exit;
-	}
-	ocmem_sz = get_ocmem_requirement(inst->prop.height, inst->prop.width);
-	rc = msm_comm_scale_bus(inst->core, inst->session_type, OCMEM_MEM);
-	if (!rc) {
-		rc = msm_comm_alloc_ocmem(inst->core, ocmem_sz);
-		if (rc) {
-			dprintk(VIDC_WARN,
-			"Failed to allocate OCMEM. Performance will be impacted\n");
-			msm_comm_unvote_buses(inst->core, OCMEM_MEM);
-		}
-	} else {
-		dprintk(VIDC_WARN,
-		"Failed to vote for OCMEM BW. Performance will be impacted\n");
-	}
-	rc = vidc_hal_session_load_res((void *) inst->session);
-	if (rc) {
-		dprintk(VIDC_ERR,
-			"Failed to send load resources\n");
-		goto exit;
-	}
-	change_inst_state(inst, MSM_VIDC_LOAD_RESOURCES);
-exit:
-	return rc;
-}
-
-static int msm_vidc_start(int flipped_state, struct msm_vidc_inst *inst)
-{
-	int rc = 0;
-	if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_START)) {
-		dprintk(VIDC_INFO,
-			"inst: %p is already in state: %d\n",
-			inst, inst->state);
-		goto exit;
-	}
-	init_completion(
-		&inst->completions[SESSION_MSG_INDEX(SESSION_START_DONE)]);
-	rc = vidc_hal_session_start((void *) inst->session);
-	if (rc) {
-		dprintk(VIDC_ERR,
-			"Failed to send start\n");
-		goto exit;
-	}
-	change_inst_state(inst, MSM_VIDC_START);
-exit:
-	return rc;
-}
-
-static int msm_vidc_stop(int flipped_state, struct msm_vidc_inst *inst)
-{
-	int rc = 0;
-	if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_STOP)) {
-		dprintk(VIDC_INFO,
-			"inst: %p is already in state: %d\n",
-			inst, inst->state);
-		goto exit;
-	}
-	dprintk(VIDC_DBG, "Send Stop to hal\n");
-	init_completion(
-		&inst->completions[SESSION_MSG_INDEX(SESSION_STOP_DONE)]);
-	rc = vidc_hal_session_stop((void *) inst->session);
-	if (rc) {
-		dprintk(VIDC_ERR, "Failed to send stop\n");
-		goto exit;
-	}
-	change_inst_state(inst, MSM_VIDC_STOP);
-exit:
-	return rc;
-}
-
-static int msm_vidc_release_res(int flipped_state, struct msm_vidc_inst *inst)
-{
-	int rc = 0;
-	if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_RELEASE_RESOURCES)) {
-		dprintk(VIDC_INFO,
-			"inst: %p is already in state: %d\n",
-			inst, inst->state);
-		goto exit;
-	}
-	dprintk(VIDC_DBG,
-		"Send release res to hal\n");
-	init_completion(
-	&inst->completions[SESSION_MSG_INDEX(SESSION_RELEASE_RESOURCE_DONE)]);
-	rc = vidc_hal_session_release_res((void *) inst->session);
-	if (rc) {
-		dprintk(VIDC_ERR,
-			"Failed to send release resources\n");
-		goto exit;
-	}
-	change_inst_state(inst, MSM_VIDC_RELEASE_RESOURCES);
-exit:
-	return rc;
-}
-
-static int msm_comm_session_close(int flipped_state, struct msm_vidc_inst *inst)
-{
-	int rc = 0;
-	if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_CLOSE)) {
-		dprintk(VIDC_INFO,
-			"inst: %p is already in state: %d\n",
-						inst, inst->state);
-		goto exit;
-	}
-	dprintk(VIDC_DBG,
-		"Send session close to hal\n");
-	init_completion(
-		&inst->completions[SESSION_MSG_INDEX(SESSION_END_DONE)]);
-	rc = vidc_hal_session_end((void *) inst->session);
-	if (rc) {
-		dprintk(VIDC_ERR,
-			"Failed to send close\n");
-		goto exit;
-	}
-	change_inst_state(inst, MSM_VIDC_OPEN);
-exit:
-	return rc;
-}
-
-static int get_flipped_state(int present_state,
-	int desired_state)
-{
-	int flipped_state = present_state;
-	if (flipped_state < MSM_VIDC_STOP
-			&& desired_state > MSM_VIDC_STOP) {
-		flipped_state = MSM_VIDC_STOP + (MSM_VIDC_STOP - flipped_state);
-		flipped_state &= 0xFFFE;
-		flipped_state = flipped_state - 1;
-	} else if (flipped_state > MSM_VIDC_STOP
-			&& desired_state < MSM_VIDC_STOP) {
-		flipped_state = MSM_VIDC_STOP -
-			(flipped_state - MSM_VIDC_STOP + 1);
-		flipped_state &= 0xFFFE;
-		flipped_state = flipped_state - 1;
-	}
-	return flipped_state;
-}
-
-int msm_comm_try_state(struct msm_vidc_inst *inst, int state)
-{
-	int rc = 0;
-	int flipped_state;
-	struct msm_vidc_core *core;
-	if (!inst) {
-		dprintk(VIDC_ERR,
-				"Invalid instance pointer = %p\n", inst);
-		return -EINVAL;
-	}
-	dprintk(VIDC_DBG,
-			"Trying to move inst: %p from: 0x%x to 0x%x\n",
-			inst, inst->state, state);
-	core = inst->core;
-	if (!core) {
-		dprintk(VIDC_ERR,
-				"Invalid core pointer = %p\n", inst);
-		return -EINVAL;
-	}
-	mutex_lock(&inst->sync_lock);
-	if (inst->state == MSM_VIDC_CORE_INVALID ||
-			core->state == VIDC_CORE_INVALID) {
-		dprintk(VIDC_ERR,
-				"Core is in bad state can't change the state");
-		goto exit;
-	}
-	flipped_state = get_flipped_state(inst->state, state);
-	dprintk(VIDC_DBG,
-			"flipped_state = 0x%x\n", flipped_state);
-	switch (flipped_state) {
-	case MSM_VIDC_CORE_UNINIT_DONE:
-	case MSM_VIDC_CORE_INIT:
-		rc = msm_comm_init_core(inst);
-		if (rc || state <= get_flipped_state(inst->state, state))
-			break;
-	case MSM_VIDC_CORE_INIT_DONE:
-		rc = msm_comm_init_core_done(inst);
-		if (rc || state <= get_flipped_state(inst->state, state))
-			break;
-	case MSM_VIDC_OPEN:
-		rc = msm_comm_session_init(flipped_state, inst);
-		if (rc || state <= get_flipped_state(inst->state, state))
-			break;
-	case MSM_VIDC_OPEN_DONE:
-		rc = wait_for_state(inst, flipped_state, MSM_VIDC_OPEN_DONE,
-			SESSION_INIT_DONE);
-		if (rc || state <= get_flipped_state(inst->state, state))
-			break;
-	case MSM_VIDC_LOAD_RESOURCES:
-		rc = msm_vidc_load_resources(flipped_state, inst);
-		if (rc || state <= get_flipped_state(inst->state, state))
-			break;
-	case MSM_VIDC_LOAD_RESOURCES_DONE:
-	case MSM_VIDC_START:
-		rc = msm_vidc_start(flipped_state, inst);
-		if (rc || state <= get_flipped_state(inst->state, state))
-			break;
-	case MSM_VIDC_START_DONE:
-		rc = wait_for_state(inst, flipped_state, MSM_VIDC_START_DONE,
-				SESSION_START_DONE);
-		if (rc || state <= get_flipped_state(inst->state, state))
-			break;
-	case MSM_VIDC_STOP:
-		rc = msm_vidc_stop(flipped_state, inst);
-		if (rc || state <= get_flipped_state(inst->state, state))
-			break;
-	case MSM_VIDC_STOP_DONE:
-		rc = wait_for_state(inst, flipped_state, MSM_VIDC_STOP_DONE,
-				SESSION_STOP_DONE);
-		if (rc || state <= get_flipped_state(inst->state, state))
-			break;
-		dprintk(VIDC_DBG, "Moving to Stop Done state\n");
-	case MSM_VIDC_RELEASE_RESOURCES:
-		rc = msm_vidc_release_res(flipped_state, inst);
-		if (rc || state <= get_flipped_state(inst->state, state))
-			break;
-	case MSM_VIDC_RELEASE_RESOURCES_DONE:
-		rc = wait_for_state(inst, flipped_state,
-			MSM_VIDC_RELEASE_RESOURCES_DONE,
-			SESSION_RELEASE_RESOURCE_DONE);
-		if (rc || state <= get_flipped_state(inst->state, state))
-			break;
-		dprintk(VIDC_DBG,
-				"Moving to release resources done state\n");
-	case MSM_VIDC_CLOSE:
-		rc = msm_comm_session_close(flipped_state, inst);
-		if (rc || state <= get_flipped_state(inst->state, state))
-			break;
-	case MSM_VIDC_CLOSE_DONE:
-		rc = wait_for_state(inst, flipped_state, MSM_VIDC_CLOSE_DONE,
-				SESSION_END_DONE);
-		if (rc || state <= get_flipped_state(inst->state, state))
-			break;
-	case MSM_VIDC_CORE_UNINIT:
-		dprintk(VIDC_DBG, "Sending core uninit\n");
-		rc = msm_vidc_deinit_core(inst);
-		if (rc || state == get_flipped_state(inst->state, state))
-			break;
-	default:
-		dprintk(VIDC_ERR, "State not recognized\n");
-		rc = -EINVAL;
-		break;
-	}
-exit:
-	mutex_unlock(&inst->sync_lock);
-	if (rc)
-		dprintk(VIDC_ERR,
-				"Failed to move from state: %d to %d\n",
-				inst->state, state);
-	return rc;
-}
-int msm_comm_qbuf(struct vb2_buffer *vb)
-{
-	int rc = 0;
-	struct vb2_queue *q;
-	struct msm_vidc_inst *inst;
-	struct vb2_buf_entry *entry;
-	struct vidc_frame_data frame_data;
-	struct msm_vidc_core *core;
-	q = vb->vb2_queue;
-	inst = q->drv_priv;
-	if (!inst || !vb) {
-		dprintk(VIDC_ERR, "Invalid input: %p, %p\n", inst, vb);
-		return -EINVAL;
-	}
-	core = inst->core;
-	if (!core) {
-		dprintk(VIDC_ERR,
-			"Invalid input: %p, %p, %p\n", inst, core, vb);
-		return -EINVAL;
-	}
-
-	if (inst->state == MSM_VIDC_CORE_INVALID ||
-		core->state == VIDC_CORE_INVALID) {
-		dprintk(VIDC_ERR, "Core is in bad state. Can't Queue\n");
-		return -EINVAL;
-	}
-	if (inst->state != MSM_VIDC_START_DONE) {
-			entry = kzalloc(sizeof(*entry), GFP_KERNEL);
-			if (!entry) {
-				dprintk(VIDC_ERR, "Out of memory\n");
-				goto err_no_mem;
-			}
-			entry->vb = vb;
-			mutex_lock(&inst->sync_lock);
-			list_add_tail(&entry->list, &inst->pendingq);
-			mutex_unlock(&inst->sync_lock);
-	} else {
-		int64_t time_usec = timeval_to_ns(&vb->v4l2_buf.timestamp);
-		do_div(time_usec, NSEC_PER_USEC);
-		memset(&frame_data, 0 , sizeof(struct vidc_frame_data));
-		frame_data.alloc_len = vb->v4l2_planes[0].length;
-		frame_data.filled_len = vb->v4l2_planes[0].bytesused;
-		frame_data.device_addr = vb->v4l2_planes[0].m.userptr;
-		frame_data.timestamp = time_usec;
-		frame_data.flags = 0;
-		frame_data.clnt_data = (u32)vb;
-		if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-			frame_data.buffer_type = HAL_BUFFER_INPUT;
-			if (vb->v4l2_buf.flags & V4L2_BUF_FLAG_EOS) {
-				frame_data.flags |= HAL_BUFFERFLAG_EOS;
-				dprintk(VIDC_DBG,
-					"Received EOS on output capability\n");
-			}
-
-			if (vb->v4l2_buf.flags &
-					V4L2_QCOM_BUF_FLAG_CODECCONFIG) {
-				frame_data.flags |= HAL_BUFFERFLAG_CODECCONFIG;
-				dprintk(VIDC_DBG,
-					"Received CODECCONFIG on output cap\n");
-			}
-			dprintk(VIDC_DBG,
-				"Sending etb to hal: Alloc: %d :filled: %d\n",
-				frame_data.alloc_len, frame_data.filled_len);
-			rc = vidc_hal_session_etb((void *) inst->session,
-					&frame_data);
-			if (!rc)
-				msm_vidc_debugfs_update(inst,
-					MSM_VIDC_DEBUGFS_EVENT_ETB);
-			dprintk(VIDC_DBG, "Sent etb to HAL\n");
-		} else if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-			struct vidc_seq_hdr seq_hdr;
-			int extra_idx = 0;
-			frame_data.filled_len = 0;
-			frame_data.offset = 0;
-			frame_data.alloc_len = vb->v4l2_planes[0].length;
-			frame_data.buffer_type = HAL_BUFFER_OUTPUT;
-			extra_idx =
-			EXTRADATA_IDX(inst->fmts[CAPTURE_PORT]->num_planes);
-			if (extra_idx && (extra_idx < VIDEO_MAX_PLANES) &&
-				vb->v4l2_planes[extra_idx].m.userptr)
-				frame_data.extradata_addr =
-					vb->v4l2_planes[extra_idx].m.userptr;
-			dprintk(VIDC_DBG,
-				"Sending ftb to hal: Alloc: %d :filled: %d",
-				frame_data.alloc_len, frame_data.filled_len);
-			dprintk(VIDC_DBG,
-				" extradata_addr: %d\n",
-				frame_data.extradata_addr);
-			if (!inst->ftb_count &&
-			   inst->session_type == MSM_VIDC_ENCODER) {
-				seq_hdr.seq_hdr = (u8 *) vb->v4l2_planes[0].
-					m.userptr;
-				seq_hdr.seq_hdr_len = vb->v4l2_planes[0].length;
-				rc = vidc_hal_session_get_seq_hdr((void *)
-						inst->session, &seq_hdr);
-				if (!rc) {
-					inst->vb2_seq_hdr = vb;
-					dprintk(VIDC_DBG, "Seq_hdr: %p\n",
-						inst->vb2_seq_hdr);
-				}
-			} else {
-				rc = vidc_hal_session_ftb((void *)
-					inst->session, &frame_data);
-			if (!rc)
-				msm_vidc_debugfs_update(inst,
-					MSM_VIDC_DEBUGFS_EVENT_FTB);
-			}
-			inst->ftb_count++;
-		} else {
-			dprintk(VIDC_ERR,
-				"This capability is not supported: %d\n",
-				q->type);
-			rc = -EINVAL;
-		}
-	}
-	if (rc)
-		dprintk(VIDC_ERR, "Failed to queue buffer\n");
-err_no_mem:
-	return rc;
-}
-
-int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst)
-{
-	int rc = 0;
-	mutex_lock(&inst->sync_lock);
-	if (inst->state < MSM_VIDC_OPEN_DONE || inst->state >= MSM_VIDC_CLOSE) {
-		dprintk(VIDC_ERR,
-			"Not in proper state to query buffer requirements\n");
-		rc = -EAGAIN;
-		goto exit;
-	}
-	init_completion(
-		&inst->completions[SESSION_MSG_INDEX(SESSION_PROPERTY_INFO)]);
-	rc = vidc_hal_session_get_buf_req((void *) inst->session);
-	if (rc) {
-		dprintk(VIDC_ERR, "Failed to get property\n");
-		goto exit;
-	}
-	rc = wait_for_completion_timeout(
-		&inst->completions[SESSION_MSG_INDEX(SESSION_PROPERTY_INFO)],
-		msecs_to_jiffies(HW_RESPONSE_TIMEOUT));
-	if (!rc) {
-		dprintk(VIDC_ERR,
-			"Wait interrupted or timeout: %d\n", rc);
-		rc = -EIO;
-		goto exit;
-	}
-	rc = 0;
-exit:
-	mutex_unlock(&inst->sync_lock);
-	return rc;
-}
-int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst)
-{
-	struct msm_smem *handle;
-	struct list_head *ptr, *next;
-	struct internal_buf *buf;
-	struct vidc_buffer_addr_info buffer_info;
-	int rc = 0;
-	unsigned long flags;
-	struct msm_vidc_core *core;
-	if (!inst) {
-		dprintk(VIDC_ERR,
-				"Invalid instance pointer = %p\n", inst);
-		return -EINVAL;
-	}
-	core = inst->core;
-	if (!core) {
-		dprintk(VIDC_ERR,
-				"Invalid core pointer = %p\n", core);
-		return -EINVAL;
-	}
-	spin_lock_irqsave(&inst->lock, flags);
-	if (!list_empty(&inst->internalbufs)) {
-		list_for_each_safe(ptr, next, &inst->internalbufs) {
-			buf = list_entry(ptr, struct internal_buf,
-					list);
-			handle = buf->handle;
-			buffer_info.buffer_size = handle->size;
-			buffer_info.buffer_type = HAL_BUFFER_INTERNAL_SCRATCH;
-			buffer_info.num_buffers = 1;
-			buffer_info.align_device_addr = handle->device_addr;
-			if (inst->state != MSM_VIDC_CORE_INVALID &&
-					core->state != VIDC_CORE_INVALID) {
-				buffer_info.response_required = true;
-				init_completion(
-				   &inst->completions[SESSION_MSG_INDEX
-				   (SESSION_RELEASE_BUFFER_DONE)]);
-				rc = vidc_hal_session_release_buffers(
-						(void *) inst->session,
-							&buffer_info);
-				if (rc)
-					dprintk(VIDC_WARN,
-						"Rel scrtch buf fail:0x%x, %d",
-						buffer_info.align_device_addr,
-						buffer_info.buffer_size);
-				spin_unlock_irqrestore(&inst->lock, flags);
-				rc = wait_for_sess_signal_receipt(inst,
-					SESSION_RELEASE_BUFFER_DONE);
-				spin_lock_irqsave(&inst->lock, flags);
-			}
-			list_del(&buf->list);
-			spin_unlock_irqrestore(&inst->lock, flags);
-			msm_smem_free(inst->mem_client, buf->handle);
-			kfree(buf);
-			spin_lock_irqsave(&inst->lock, flags);
-		}
-	}
-	spin_unlock_irqrestore(&inst->lock, flags);
-	return rc;
-}
-
-int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst)
-{
-	struct msm_smem *handle;
-	struct list_head *ptr, *next;
-	struct internal_buf *buf;
-	struct vidc_buffer_addr_info buffer_info;
-	int rc = 0;
-	unsigned long flags;
-	struct msm_vidc_core *core;
-	if (!inst) {
-		dprintk(VIDC_ERR,
-				"Invalid instance pointer = %p\n", inst);
-		return -EINVAL;
-	}
-	core = inst->core;
-	if (!core) {
-		dprintk(VIDC_ERR,
-				"Invalid core pointer = %p\n", core);
-		return -EINVAL;
-	}
-	spin_lock_irqsave(&inst->lock, flags);
-	if (!list_empty(&inst->persistbufs)) {
-		list_for_each_safe(ptr, next, &inst->persistbufs) {
-			buf = list_entry(ptr, struct internal_buf,
-					list);
-			handle = buf->handle;
-			buffer_info.buffer_size = handle->size;
-			buffer_info.buffer_type = HAL_BUFFER_INTERNAL_PERSIST;
-			buffer_info.num_buffers = 1;
-			buffer_info.align_device_addr = handle->device_addr;
-			if (inst->state != MSM_VIDC_CORE_INVALID &&
-					core->state != VIDC_CORE_INVALID) {
-				buffer_info.response_required = true;
-				init_completion(
-				   &inst->completions[SESSION_MSG_INDEX
-				   (SESSION_RELEASE_BUFFER_DONE)]);
-				rc = vidc_hal_session_release_buffers(
-						(void *) inst->session,
-							&buffer_info);
-				if (rc)
-					dprintk(VIDC_WARN,
-						"Rel prst buf fail:0x%x, %d",
-						buffer_info.align_device_addr,
-						buffer_info.buffer_size);
-				spin_unlock_irqrestore(&inst->lock, flags);
-				rc = wait_for_sess_signal_receipt(inst,
-					SESSION_RELEASE_BUFFER_DONE);
-				spin_lock_irqsave(&inst->lock, flags);
-			}
-			list_del(&buf->list);
-			spin_unlock_irqrestore(&inst->lock, flags);
-			msm_smem_free(inst->mem_client, buf->handle);
-			kfree(buf);
-			spin_lock_irqsave(&inst->lock, flags);
-		}
-	}
-	spin_unlock_irqrestore(&inst->lock, flags);
-	return rc;
-}
-
-int msm_comm_try_set_prop(struct msm_vidc_inst *inst,
-	enum hal_property ptype, void *pdata)
-{
-	int rc = 0;
-	if (!inst) {
-		dprintk(VIDC_ERR, "Invalid input: %p\n", inst);
-		return -EINVAL;
-	}
-	mutex_lock(&inst->sync_lock);
-	if (inst->state < MSM_VIDC_OPEN_DONE || inst->state >= MSM_VIDC_CLOSE) {
-		dprintk(VIDC_ERR, "Not in proper state to set property\n");
-		rc = -EAGAIN;
-		goto exit;
-	}
-	rc = vidc_hal_session_set_property((void *)inst->session,
-			ptype, pdata);
-	if (rc)
-		dprintk(VIDC_ERR, "Failed to set hal property for framesize\n");
-exit:
-	mutex_unlock(&inst->sync_lock);
-	return rc;
-}
-
-int msm_comm_set_scratch_buffers(struct msm_vidc_inst *inst)
-{
-	int rc = 0;
-	struct msm_smem *handle;
-	struct internal_buf *binfo;
-	struct vidc_buffer_addr_info buffer_info;
-	unsigned long flags;
-	int domain;
-	unsigned long smem_flags = 0;
-	struct hal_buffer_requirements *scratch_buf =
-		&inst->buff_req.buffer[HAL_BUFFER_INTERNAL_SCRATCH];
-	int i;
-	dprintk(VIDC_DBG,
-		"scratch: num = %d, size = %d\n",
-		scratch_buf->buffer_count_actual,
-		scratch_buf->buffer_size);
-	if (msm_comm_release_scratch_buffers(inst))
-		dprintk(VIDC_WARN, "Failed to release scratch buffers\n");
-	if (inst->mode == VIDC_SECURE) {
-		domain = inst->core->resources.io_map[CP_MAP].domain;
-		smem_flags |= SMEM_SECURE;
-	} else
-		domain = inst->core->resources.io_map[NS_MAP].domain;
-
-	if (scratch_buf->buffer_size) {
-		for (i = 0; i < scratch_buf->buffer_count_actual;
-				i++) {
-			handle = msm_smem_alloc(inst->mem_client,
-				scratch_buf->buffer_size, 1, smem_flags,
-				domain, 0, 0);
-			if (!handle) {
-				dprintk(VIDC_ERR,
-					"Failed to allocate scratch memory\n");
-				rc = -ENOMEM;
-				goto err_no_mem;
-			}
-			binfo = kzalloc(sizeof(*binfo), GFP_KERNEL);
-			if (!binfo) {
-				dprintk(VIDC_ERR, "Out of memory\n");
-				rc = -ENOMEM;
-				goto fail_kzalloc;
-			}
-			binfo->handle = handle;
-			buffer_info.buffer_size = scratch_buf->buffer_size;
-			buffer_info.buffer_type = HAL_BUFFER_INTERNAL_SCRATCH;
-			buffer_info.num_buffers = 1;
-			buffer_info.align_device_addr = handle->device_addr;
-			dprintk(VIDC_DBG, "Scratch buffer address: %x",
-					buffer_info.align_device_addr);
-			rc = vidc_hal_session_set_buffers(
-					(void *) inst->session,	&buffer_info);
-			if (rc) {
-				dprintk(VIDC_ERR,
-					"vidc_hal_session_set_buffers failed");
-				goto fail_set_buffers;
-			}
-			spin_lock_irqsave(&inst->lock, flags);
-			list_add_tail(&binfo->list, &inst->internalbufs);
-			spin_unlock_irqrestore(&inst->lock, flags);
-		}
-	}
-	return rc;
-fail_set_buffers:
-	kfree(binfo);
-fail_kzalloc:
-	msm_smem_free(inst->mem_client, handle);
-err_no_mem:
-	return rc;
-}
-
-int msm_comm_set_persist_buffers(struct msm_vidc_inst *inst)
-{
-	int rc = 0;
-	struct msm_smem *handle;
-	struct internal_buf *binfo;
-	struct vidc_buffer_addr_info buffer_info;
-	unsigned long flags;
-	unsigned long smem_flags = 0;
-	int domain;
-	struct hal_buffer_requirements *persist_buf =
-		&inst->buff_req.buffer[HAL_BUFFER_INTERNAL_PERSIST];
-	int i;
-	dprintk(VIDC_DBG,
-		"persist: num = %d, size = %d\n",
-		persist_buf->buffer_count_actual,
-		persist_buf->buffer_size);
-	if (!list_empty(&inst->persistbufs)) {
-		dprintk(VIDC_ERR,
-			"Persist buffers already allocated\n");
-		return rc;
-	}
-
-	if (inst->mode == VIDC_SECURE) {
-		domain = inst->core->resources.io_map[CP_MAP].domain;
-		flags |= SMEM_SECURE;
-	} else
-		domain = inst->core->resources.io_map[NS_MAP].domain;
-
-	if (persist_buf->buffer_size) {
-		for (i = 0;	i <	persist_buf->buffer_count_actual; i++) {
-			handle = msm_smem_alloc(inst->mem_client,
-				persist_buf->buffer_size, 1, smem_flags,
-				domain, 0, 0);
-			if (!handle) {
-				dprintk(VIDC_ERR,
-					"Failed to allocate persist memory\n");
-				rc = -ENOMEM;
-				goto err_no_mem;
-			}
-			binfo = kzalloc(sizeof(*binfo), GFP_KERNEL);
-			if (!binfo) {
-				dprintk(VIDC_ERR, "Out of memory\n");
-				rc = -ENOMEM;
-				goto fail_kzalloc;
-			}
-			binfo->handle = handle;
-			buffer_info.buffer_size = persist_buf->buffer_size;
-			buffer_info.buffer_type = HAL_BUFFER_INTERNAL_PERSIST;
-			buffer_info.num_buffers = 1;
-			buffer_info.align_device_addr = handle->device_addr;
-			dprintk(VIDC_DBG, "Persist buffer address: %x",
-					buffer_info.align_device_addr);
-			rc = vidc_hal_session_set_buffers(
-				(void *) inst->session, &buffer_info);
-			if (rc) {
-				dprintk(VIDC_ERR,
-					"vidc_hal_session_set_buffers failed");
-				goto fail_set_buffers;
-			}
-			spin_lock_irqsave(&inst->lock, flags);
-			list_add_tail(&binfo->list, &inst->persistbufs);
-			spin_unlock_irqrestore(&inst->lock, flags);
-		}
-	}
-	return rc;
-fail_set_buffers:
-	kfree(binfo);
-fail_kzalloc:
-	msm_smem_free(inst->mem_client, handle);
-err_no_mem:
-	return rc;
-}
-
-static void msm_comm_flush_in_invalid_state(struct msm_vidc_inst *inst)
-{
-	struct v4l2_event dqevent = {0};
-	struct list_head *ptr, *next;
-	struct vb2_buffer *vb;
-	if (!list_empty(&inst->bufq[CAPTURE_PORT].
-				vb2_bufq.queued_list)) {
-		list_for_each_safe(ptr, next,
-				&inst->bufq[CAPTURE_PORT].
-				vb2_bufq.queued_list) {
-			vb = container_of(ptr,
-					struct vb2_buffer,
-					queued_entry);
-			if (vb) {
-				vb->v4l2_planes[0].bytesused = 0;
-				mutex_lock(&inst->bufq[CAPTURE_PORT].lock);
-				vb2_buffer_done(vb,
-						VB2_BUF_STATE_DONE);
-				mutex_unlock(&inst->bufq[CAPTURE_PORT].lock);
-			}
-		}
-	}
-	if (!list_empty(&inst->bufq[OUTPUT_PORT].
-				vb2_bufq.queued_list)) {
-		list_for_each_safe(ptr, next,
-				&inst->bufq[OUTPUT_PORT].
-				vb2_bufq.queued_list) {
-			vb = container_of(ptr,
-					struct vb2_buffer,
-					queued_entry);
-			if (vb) {
-				vb->v4l2_planes[0].bytesused = 0;
-				mutex_lock(&inst->bufq[OUTPUT_PORT].lock);
-				vb2_buffer_done(vb,
-						VB2_BUF_STATE_DONE);
-				mutex_unlock(&inst->bufq[OUTPUT_PORT].lock);
-			}
-		}
-	}
-	dqevent.type = V4L2_EVENT_MSM_VIDC_FLUSH_DONE;
-	dqevent.id = 0;
-	v4l2_event_queue_fh(&inst->event_handler, &dqevent);
-	return;
-}
-int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags)
-{
-	int rc =  0;
-	bool ip_flush = false;
-	bool op_flush = false;
-	struct list_head *ptr, *next;
-	struct vb2_buf_entry *temp;
-	struct mutex *lock;
-	struct msm_vidc_core *core;
-	if (!inst) {
-		dprintk(VIDC_ERR,
-				"Invalid instance pointer = %p\n", inst);
-		return -EINVAL;
-	}
-	core = inst->core;
-	if (!core) {
-		dprintk(VIDC_ERR,
-				"Invalid core pointer = %p\n", core);
-		return -EINVAL;
-	}
-
-	ip_flush = flags & V4L2_QCOM_CMD_FLUSH_OUTPUT;
-	op_flush = flags & V4L2_QCOM_CMD_FLUSH_CAPTURE;
-
-	if (ip_flush && !op_flush) {
-		dprintk(VIDC_WARN, "Input only flush not supported\n");
-		return 0;
-	}
-	if (inst->state == MSM_VIDC_CORE_INVALID ||
-			core->state == VIDC_CORE_INVALID) {
-		dprintk(VIDC_ERR,
-				"Core %p and inst %p are in bad state\n",
-					core, inst);
-		msm_comm_flush_in_invalid_state(inst);
-	}
-
-	mutex_lock(&inst->sync_lock);
-	if (inst->in_reconfig && !ip_flush && op_flush) {
-		if (!list_empty(&inst->pendingq)) {
-			/*Execution can never reach here since port reconfig
-			 * wont happen unless pendingq is emptied out
-			 * (both pendingq and flush being secured with same
-			 * lock). Printing a message here incase this breaks.*/
-			dprintk(VIDC_WARN,
-			"FLUSH BUG: Pending q not empty! It should be empty\n");
-		}
-		rc = vidc_hal_session_flush(inst->session,
-				HAL_FLUSH_OUTPUT);
-	} else {
-		if (!list_empty(&inst->pendingq)) {
-			/*If flush is called after queueing buffers but before
-			 * streamon driver should flush the pending queue*/
-			list_for_each_safe(ptr, next, &inst->pendingq) {
-				temp =
-				list_entry(ptr, struct vb2_buf_entry, list);
-				if (temp->vb->v4l2_buf.type ==
-					V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
-					lock = &inst->bufq[CAPTURE_PORT].lock;
-				else
-					lock = &inst->bufq[OUTPUT_PORT].lock;
-				mutex_lock(lock);
-				vb2_buffer_done(temp->vb, VB2_BUF_STATE_DONE);
-				mutex_unlock(lock);
-				list_del(&temp->list);
-				kfree(temp);
-			}
-		}
-		rc = vidc_hal_session_flush(inst->session,
-				HAL_FLUSH_ALL);
-	}
-	mutex_unlock(&inst->sync_lock);
-	return rc;
-}
-
-
-enum hal_extradata_id msm_comm_get_hal_extradata_index(
-	enum v4l2_mpeg_vidc_extradata index)
-{
-	int ret = 0;
-	switch (index) {
-	case V4L2_MPEG_VIDC_EXTRADATA_NONE:
-		ret = HAL_EXTRADATA_NONE;
-		break;
-	case V4L2_MPEG_VIDC_EXTRADATA_MB_QUANTIZATION:
-		ret = HAL_EXTRADATA_MB_QUANTIZATION;
-		break;
-	case V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO:
-		ret = HAL_EXTRADATA_INTERLACE_VIDEO;
-		break;
-	case V4L2_MPEG_VIDC_EXTRADATA_VC1_FRAMEDISP:
-		ret = HAL_EXTRADATA_VC1_FRAMEDISP;
-		break;
-	case V4L2_MPEG_VIDC_EXTRADATA_VC1_SEQDISP:
-		ret = HAL_EXTRADATA_VC1_SEQDISP;
-		break;
-	case V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP:
-		ret = HAL_EXTRADATA_TIMESTAMP;
-		break;
-	case V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING:
-		ret = HAL_EXTRADATA_S3D_FRAME_PACKING;
-		break;
-	case V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE:
-		ret = HAL_EXTRADATA_FRAME_RATE;
-		break;
-	case V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW:
-		ret = HAL_EXTRADATA_PANSCAN_WINDOW;
-		break;
-	case V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI:
-		ret = HAL_EXTRADATA_RECOVERY_POINT_SEI;
-		break;
-	case V4L2_MPEG_VIDC_EXTRADATA_CLOSED_CAPTION_UD:
-		ret = HAL_EXTRADATA_CLOSED_CAPTION_UD;
-		break;
-	case V4L2_MPEG_VIDC_EXTRADATA_AFD_UD:
-		ret = HAL_EXTRADATA_AFD_UD;
-		break;
-	case V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO:
-		ret = HAL_EXTRADATA_MULTISLICE_INFO;
-		break;
-	case V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB:
-		ret = HAL_EXTRADATA_NUM_CONCEALED_MB;
-		break;
-	case V4L2_MPEG_VIDC_EXTRADATA_METADATA_FILLER:
-		ret = HAL_EXTRADATA_METADATA_FILLER;
-		break;
-	default:
-		dprintk(VIDC_WARN, "Extradata not found: %d\n", index);
-		break;
-	}
-	return ret;
-};
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.h b/drivers/media/video/msm_vidc/msm_vidc_common.h
deleted file mode 100644
index 27eab6f..0000000
--- a/drivers/media/video/msm_vidc/msm_vidc_common.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 _MSM_VIDC_COMMON_H_
-#define _MSM_VIDC_COMMON_H_
-#include "msm_vidc_internal.h"
-struct vb2_buf_entry {
-	struct list_head list;
-	struct vb2_buffer *vb;
-};
-struct msm_vidc_core *get_vidc_core(int core_id);
-const struct msm_vidc_format *msm_comm_get_pixel_fmt_index(
-	const struct msm_vidc_format fmt[], int size, int index, int fmt_type);
-const struct msm_vidc_format *msm_comm_get_pixel_fmt_fourcc(
-	const struct msm_vidc_format fmt[], int size, int fourcc, int fmt_type);
-struct buf_queue *msm_comm_get_vb2q(
-		struct msm_vidc_inst *inst, enum v4l2_buf_type type);
-int msm_comm_try_state(struct msm_vidc_inst *inst, int state);
-int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst);
-int msm_comm_try_set_prop(struct msm_vidc_inst *inst,
-	enum hal_property ptype, void *pdata);
-int msm_comm_set_scratch_buffers(struct msm_vidc_inst *inst);
-int msm_comm_set_persist_buffers(struct msm_vidc_inst *inst);
-int msm_comm_qbuf(struct vb2_buffer *vb);
-void msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst);
-int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags);
-int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst);
-int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst);
-int msm_comm_force_cleanup(struct msm_vidc_inst *inst);
-enum hal_extradata_id msm_comm_get_hal_extradata_index(
-	enum v4l2_mpeg_vidc_extradata index);
-#define IS_PRIV_CTRL(idx) (\
-		(V4L2_CTRL_ID2CLASS(idx) == V4L2_CTRL_CLASS_MPEG) && \
-		V4L2_CTRL_DRIVER_PRIV(idx))
-
-#endif
diff --git a/drivers/media/video/msm_vidc/msm_vidc_debug.c b/drivers/media/video/msm_vidc/msm_vidc_debug.c
deleted file mode 100644
index f91d0dd..0000000
--- a/drivers/media/video/msm_vidc/msm_vidc_debug.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 "msm_vidc_debug.h"
-
-#define MAX_DBG_BUF_SIZE 4096
-int msm_vidc_debug;
-int msm_fw_debug;
-
-struct debug_buffer {
-	char ptr[MAX_DBG_BUF_SIZE];
-	char *curr;
-	u32 filled_size;
-};
-
-static struct debug_buffer dbg_buf;
-
-#define INIT_DBG_BUF(__buf) ({ \
-	__buf.curr = __buf.ptr;\
-	__buf.filled_size = 0; \
-})
-
-static int core_info_open(struct inode *inode, struct file *file)
-{
-	file->private_data = inode->i_private;
-	return 0;
-}
-
-static u32 write_str(struct debug_buffer *buffer, const char *fmt, ...)
-{
-	va_list args;
-	u32 size;
-	va_start(args, fmt);
-	size = vscnprintf(buffer->curr, MAX_DBG_BUF_SIZE - 1, fmt, args);
-	va_end(args);
-	buffer->curr += size;
-	buffer->filled_size += size;
-	return size;
-}
-
-static ssize_t core_info_read(struct file *file, char __user *buf,
-		size_t count, loff_t *ppos)
-{
-	struct msm_vidc_core *core = file->private_data;
-	int i = 0;
-	if (!core) {
-		dprintk(VIDC_ERR, "Invalid params, core: %p\n", core);
-		return 0;
-	}
-	INIT_DBG_BUF(dbg_buf);
-	write_str(&dbg_buf, "===============================\n");
-	write_str(&dbg_buf, "CORE %d: 0x%p\n", core->id, core);
-	write_str(&dbg_buf, "===============================\n");
-	write_str(&dbg_buf, "state: %d\n", core->state);
-	write_str(&dbg_buf, "base addr: 0x%x\n", core->base_addr);
-	write_str(&dbg_buf, "register_base: 0x%x\n", core->register_base);
-	write_str(&dbg_buf, "register_size: %u\n", core->register_size);
-	write_str(&dbg_buf, "irq: %u\n", core->irq);
-	for (i = SYS_MSG_START; i < SYS_MSG_END; i++) {
-		write_str(&dbg_buf, "completions[%d]: %s\n", i,
-			completion_done(&core->completions[SYS_MSG_INDEX(i)]) ?
-			"pending" : "done");
-	}
-	return simple_read_from_buffer(buf, count, ppos,
-			dbg_buf.ptr, dbg_buf.filled_size);
-}
-
-static const struct file_operations core_info_fops = {
-	.open = core_info_open,
-	.read = core_info_read,
-};
-
-struct dentry *msm_vidc_debugfs_init_core(struct msm_vidc_core *core,
-		struct dentry *parent)
-{
-	struct dentry *dir = NULL;
-	char debugfs_name[MAX_DEBUGFS_NAME];
-	if (!core) {
-		dprintk(VIDC_ERR, "Invalid params, core: %p\n", core);
-		goto failed_create_dir;
-	}
-	msm_vidc_debug = 0;
-	msm_fw_debug = 0;
-	snprintf(debugfs_name, MAX_DEBUGFS_NAME, "core%d", core->id);
-	dir = debugfs_create_dir(debugfs_name, parent);
-	if (!dir) {
-		dprintk(VIDC_ERR, "Failed to create debugfs for msm_vidc\n");
-		goto failed_create_dir;
-	}
-	if (!debugfs_create_file("info", S_IRUGO, dir, core, &core_info_fops)) {
-		dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
-		goto failed_create_dir;
-	}
-	if (!debugfs_create_u32("debug_level", S_IRUGO | S_IWUSR,
-			parent,	&msm_vidc_debug)) {
-		dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
-		goto failed_create_dir;
-	}
-	msm_vidc_debug = 0x3;
-	if (!debugfs_create_u32("fw_level", S_IRUGO | S_IWUSR,
-			parent, &msm_fw_debug)) {
-		dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
-		goto failed_create_dir;
-	}
-	msm_fw_debug = 0x18;
-failed_create_dir:
-	return dir;
-}
-
-static int inst_info_open(struct inode *inode, struct file *file)
-{
-	file->private_data = inode->i_private;
-	return 0;
-}
-
-static ssize_t inst_info_read(struct file *file, char __user *buf,
-		size_t count, loff_t *ppos)
-{
-	struct msm_vidc_inst *inst = file->private_data;
-	int i, j;
-	if (!inst) {
-		dprintk(VIDC_ERR, "Invalid params, core: %p\n", inst);
-		return 0;
-	}
-	INIT_DBG_BUF(dbg_buf);
-	write_str(&dbg_buf, "===============================\n");
-	write_str(&dbg_buf, "INSTANCE: 0x%p (%s)\n", inst,
-		inst->session_type == MSM_VIDC_ENCODER ? "Encoder" : "Decoder");
-	write_str(&dbg_buf, "===============================\n");
-	write_str(&dbg_buf, "core: 0x%p\n", inst->core);
-	write_str(&dbg_buf, "height: %d\n", inst->prop.height);
-	write_str(&dbg_buf, "width: %d\n", inst->prop.width);
-	write_str(&dbg_buf, "state: %d\n", inst->state);
-	write_str(&dbg_buf, "-----------Formats-------------\n");
-	for (i = 0; i < MAX_PORT_NUM; i++) {
-		write_str(&dbg_buf, "capability: %s\n", i == OUTPUT_PORT ?
-			"Output" : "Capture");
-		write_str(&dbg_buf, "name : %s\n", inst->fmts[i]->name);
-		write_str(&dbg_buf, "planes : %d\n", inst->fmts[i]->num_planes);
-		write_str(
-		&dbg_buf, "type: %s\n", inst->fmts[i]->type == OUTPUT_PORT ?
-		"Output" : "Capture");
-		for (j = 0; j < inst->fmts[i]->num_planes; j++)
-			write_str(&dbg_buf, "size for plane %d: %u\n", j,
-			inst->fmts[i]->get_frame_size(j,
-			inst->prop.height, inst->prop.width));
-	}
-	write_str(&dbg_buf, "-------------------------------\n");
-	for (i = SESSION_MSG_START; i < SESSION_MSG_END; i++) {
-		write_str(&dbg_buf, "completions[%d]: %s\n", i,
-		completion_done(&inst->completions[SESSION_MSG_INDEX(i)]) ?
-		"pending" : "done");
-	}
-	return simple_read_from_buffer(buf, count, ppos,
-		dbg_buf.ptr, dbg_buf.filled_size);
-}
-
-static const struct file_operations inst_info_fops = {
-	.open = inst_info_open,
-	.read = inst_info_read,
-};
-
-struct dentry *msm_vidc_debugfs_init_inst(struct msm_vidc_inst *inst,
-		struct dentry *parent)
-{
-	struct dentry *dir = NULL;
-	char debugfs_name[MAX_DEBUGFS_NAME];
-	if (!inst) {
-		dprintk(VIDC_ERR, "Invalid params, inst: %p\n", inst);
-		goto failed_create_dir;
-	}
-	snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%p", inst);
-	dir = debugfs_create_dir(debugfs_name, parent);
-	if (!dir) {
-		dprintk(VIDC_ERR, "Failed to create debugfs for msm_vidc\n");
-		goto failed_create_dir;
-	}
-	if (!debugfs_create_file("info", S_IRUGO, dir, inst, &inst_info_fops)) {
-		dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
-		goto failed_create_dir;
-	}
-	inst->debug.pdata[FRAME_PROCESSING].sampling = true;
-failed_create_dir:
-	return dir;
-}
-
-void msm_vidc_debugfs_update(struct msm_vidc_inst *inst,
-	enum msm_vidc_debugfs_event e)
-{
-	struct msm_vidc_debug *d = &inst->debug;
-	char a[64] = "Frame processing";
-	switch (e) {
-	case MSM_VIDC_DEBUGFS_EVENT_ETB:
-		inst->count.etb++;
-		if (inst->count.ebd && inst->count.ftb > inst->count.fbd) {
-			d->pdata[FRAME_PROCESSING].name[0] = '\0';
-			tic(inst, FRAME_PROCESSING, a);
-		}
-	break;
-	case MSM_VIDC_DEBUGFS_EVENT_EBD:
-		inst->count.ebd++;
-		if (inst->count.ebd && inst->count.ebd == inst->count.etb)
-			toc(inst, FRAME_PROCESSING);
-	break;
-	case MSM_VIDC_DEBUGFS_EVENT_FTB: {
-		inst->count.ftb++;
-		if (inst->count.ebd && inst->count.etb > inst->count.ebd) {
-			d->pdata[FRAME_PROCESSING].name[0] = '\0';
-			tic(inst, FRAME_PROCESSING, a);
-		}
-	}
-	break;
-	case MSM_VIDC_DEBUGFS_EVENT_FBD:
-		inst->debug.samples++;
-		if (inst->count.ebd && inst->count.fbd == inst->count.ftb)
-			toc(inst, FRAME_PROCESSING);
-		break;
-	default:
-		dprintk(VIDC_ERR, "Invalid state in debugfs: %d\n", e);
-		break;
-	}
-}
-
diff --git a/drivers/media/video/msm_vidc/msm_vidc_debug.h b/drivers/media/video/msm_vidc/msm_vidc_debug.h
deleted file mode 100644
index 995daf0..0000000
--- a/drivers/media/video/msm_vidc/msm_vidc_debug.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 __MSM_VIDC_DEBUG__
-#define __MSM_VIDC_DEBUG__
-#include <linux/debugfs.h>
-#include <linux/delay.h>
-#include "msm_vidc_internal.h"
-
-#define VIDC_DBG_TAG "msm_vidc: %d: "
-
-/* To enable messages OR these values and
- * echo the result to debugfs file.
- *
- * To enable all messages set debug_level = 0x101F
- */
-
-enum vidc_msg_prio {
-	VIDC_ERR  = 0x0001,
-	VIDC_WARN = 0x0002,
-	VIDC_INFO = 0x0004,
-	VIDC_DBG  = 0x0008,
-	VIDC_PROF = 0x0010,
-	VIDC_FW   = 0x1000,
-};
-
-enum msm_vidc_debugfs_event {
-	MSM_VIDC_DEBUGFS_EVENT_ETB,
-	MSM_VIDC_DEBUGFS_EVENT_EBD,
-	MSM_VIDC_DEBUGFS_EVENT_FTB,
-	MSM_VIDC_DEBUGFS_EVENT_FBD,
-};
-
-extern int msm_vidc_debug;
-extern int msm_fw_debug;
-
-#define dprintk(__level, __fmt, arg...)	\
-	do { \
-		if (msm_vidc_debug & __level) \
-			printk(KERN_DEBUG VIDC_DBG_TAG \
-				__fmt, __level, ## arg); \
-	} while (0)
-
-struct dentry *msm_vidc_debugfs_init_core(struct msm_vidc_core *core,
-		struct dentry *parent);
-struct dentry *msm_vidc_debugfs_init_inst(struct msm_vidc_inst *inst,
-		struct dentry *parent);
-void msm_vidc_debugfs_update(struct msm_vidc_inst *inst,
-		enum msm_vidc_debugfs_event e);
-
-static inline void tic(struct msm_vidc_inst *i, enum profiling_points p,
-				 char *b)
-{
-	struct timeval __ddl_tv;
-	if (!i->debug.pdata[p].name[0])
-		memcpy(i->debug.pdata[p].name, b, 64);
-	if ((msm_vidc_debug & VIDC_PROF) &&
-		i->debug.pdata[p].sampling) {
-		do_gettimeofday(&__ddl_tv);
-		i->debug.pdata[p].start =
-			(__ddl_tv.tv_sec * 1000) + (__ddl_tv.tv_usec / 1000);
-			i->debug.pdata[p].sampling = false;
-	}
-}
-
-static inline void toc(struct msm_vidc_inst *i, enum profiling_points p)
-{
-	struct timeval __ddl_tv;
-	if ((msm_vidc_debug & VIDC_PROF) &&
-		!i->debug.pdata[p].sampling) {
-		do_gettimeofday(&__ddl_tv);
-		i->debug.pdata[p].stop = (__ddl_tv.tv_sec * 1000)
-		+ (__ddl_tv.tv_usec / 1000);
-		i->debug.pdata[p].cumulative +=
-		(i->debug.pdata[p].stop - i->debug.pdata[p].start);
-		i->debug.pdata[p].sampling = true;
-	}
-}
-
-static inline void show_stats(struct msm_vidc_inst *i)
-{
-	int x;
-	for (x = 0; x < MAX_PROFILING_POINTS; x++) {
-		if ((i->debug.pdata[x].name[0])  &&
-			(msm_vidc_debug & VIDC_PROF)) {
-			dprintk(VIDC_PROF, "%s averaged %d ms/sample\n",
-				i->debug.pdata[x].name,
-				i->debug.pdata[x].cumulative /
-					i->debug.samples);
-			dprintk(VIDC_PROF, "%s Samples: %d",
-					i->debug.pdata[x].name,
-					i->debug.samples);
-		}
-	}
-}
-
-#endif
diff --git a/drivers/media/video/msm_vidc/msm_vidc_internal.h b/drivers/media/video/msm_vidc/msm_vidc_internal.h
deleted file mode 100644
index aadb4c2..0000000
--- a/drivers/media/video/msm_vidc/msm_vidc_internal.h
+++ /dev/null
@@ -1,294 +0,0 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef _MSM_VIDC_INTERNAL_H_
-#define _MSM_VIDC_INTERNAL_H_
-
-#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <linux/types.h>
-#include <linux/completion.h>
-#include <linux/clk.h>
-#include <linux/wait.h>
-#include <mach/msm_bus.h>
-#include <mach/msm_bus_board.h>
-#include <mach/ocmem.h>
-#include <media/v4l2-dev.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-ctrls.h>
-#include <media/videobuf2-core.h>
-#include <media/msm_vidc.h>
-#include <media/msm_media_info.h>
-
-#include "vidc_hal_api.h"
-
-#define MSM_VIDC_DRV_NAME "msm_vidc_driver"
-#define MSM_VIDC_VERSION KERNEL_VERSION(0, 0, 1);
-#define MAX_DEBUGFS_NAME 50
-#define DEFAULT_TIMEOUT 3
-
-#define V4L2_EVENT_VIDC_BASE  10
-
-#define SYS_MSG_START VIDC_EVENT_CHANGE
-#define SYS_MSG_END SYS_DEBUG
-#define SESSION_MSG_START SESSION_LOAD_RESOURCE_DONE
-#define SESSION_MSG_END SESSION_PROPERTY_INFO
-#define SYS_MSG_INDEX(__msg) (__msg - SYS_MSG_START)
-#define SESSION_MSG_INDEX(__msg) (__msg - SESSION_MSG_START)
-
-#define MAX_NAME_LENGTH 64
-
-#define EXTRADATA_IDX(__num_planes) (__num_planes - 1)
-enum vidc_ports {
-	OUTPUT_PORT,
-	CAPTURE_PORT,
-	MAX_PORT_NUM
-};
-
-enum vidc_core_state {
-	VIDC_CORE_UNINIT = 0,
-	VIDC_CORE_INIT,
-	VIDC_CORE_INIT_DONE,
-	VIDC_CORE_INVALID
-};
-
-/*Donot change the enum values unless
- * you know what you are doing*/
-enum instance_state {
-	MSM_VIDC_CORE_UNINIT_DONE = 0x0001,
-	MSM_VIDC_CORE_INIT,
-	MSM_VIDC_CORE_INIT_DONE,
-	MSM_VIDC_OPEN,
-	MSM_VIDC_OPEN_DONE,
-	MSM_VIDC_LOAD_RESOURCES,
-	MSM_VIDC_LOAD_RESOURCES_DONE,
-	MSM_VIDC_START,
-	MSM_VIDC_START_DONE,
-	MSM_VIDC_STOP,
-	MSM_VIDC_STOP_DONE,
-	MSM_VIDC_RELEASE_RESOURCES,
-	MSM_VIDC_RELEASE_RESOURCES_DONE,
-	MSM_VIDC_CLOSE,
-	MSM_VIDC_CLOSE_DONE,
-	MSM_VIDC_CORE_UNINIT,
-	MSM_VIDC_CORE_INVALID
-};
-
-struct buf_info {
-	struct list_head list;
-	struct vb2_buffer *buf;
-};
-
-struct internal_buf {
-	struct list_head list;
-	struct msm_smem *handle;
-};
-
-struct msm_vidc_format {
-	char name[MAX_NAME_LENGTH];
-	u8 description[32];
-	u32 fourcc;
-	int num_planes;
-	int type;
-	u32 (*get_frame_size)(int plane, u32 height, u32 width);
-};
-
-struct msm_vidc_drv {
-	spinlock_t lock;
-	struct list_head cores;
-	int num_cores;
-	struct dentry *debugfs_root;
-};
-
-struct msm_video_device {
-	int type;
-	struct video_device vdev;
-};
-
-struct msm_vidc_fw {
-	void *cookie;
-};
-
-enum vidc_clocks {
-	VCODEC_CLK,
-	VCODEC_AHB_CLK,
-	VCODEC_AXI_CLK,
-	VCODEC_OCMEM_CLK,
-	VCODEC_MAX_CLKS
-};
-
-struct load_freq_table {
-	u32 load;
-	u32 freq;
-};
-
-enum mem_type {
-	DDR_MEM = 0x1,
-	OCMEM_MEM = 0x2,
-};
-
-struct core_clock {
-	char name[MAX_NAME_LENGTH];
-	struct clk *clk;
-	u32 count;
-	struct load_freq_table load_freq_tbl[8];
-};
-
-struct vidc_bus_info {
-	u32 ddr_handle[MSM_VIDC_MAX_DEVICES];
-	u32 ocmem_handle[MSM_VIDC_MAX_DEVICES];
-};
-
-struct on_chip_mem {
-	struct ocmem_buf *buf;
-	struct notifier_block vidc_ocmem_nb;
-	void *handle;
-};
-
-struct msm_vidc_resources {
-	struct msm_vidc_fw fw;
-	struct msm_vidc_iommu_info io_map[MAX_MAP];
-	struct core_clock clock[VCODEC_MAX_CLKS];
-	struct vidc_bus_info bus_info;
-	struct on_chip_mem ocmem;
-};
-
-struct session_prop {
-	u32 width;
-	u32 height;
-	u32 fps;
-	u32 bitrate;
-	u64 prev_time_stamp;
-};
-
-struct buf_queue {
-	struct vb2_queue vb2_bufq;
-	struct mutex lock;
-};
-
-enum profiling_points {
-	SYS_INIT = 0,
-	SESSION_INIT,
-	LOAD_RESOURCES,
-	FRAME_PROCESSING,
-	FW_IDLE,
-	MAX_PROFILING_POINTS,
-};
-
-struct buf_count {
-	int etb;
-	int ftb;
-	int fbd;
-	int ebd;
-};
-
-struct profile_data {
-	int start;
-	int stop;
-	int cumulative;
-	char name[64];
-	int sampling;
-	int average;
-};
-
-struct msm_vidc_debug {
-	struct profile_data pdata[MAX_PROFILING_POINTS];
-	int profile;
-	int samples;
-};
-
-enum msm_vidc_mode {
-	VIDC_NON_SECURE,
-	VIDC_SECURE,
-};
-
-struct msm_vidc_core {
-	struct list_head list;
-	struct mutex sync_lock;
-	int id;
-	void *device;
-	struct msm_video_device vdev[MSM_VIDC_MAX_DEVICES];
-	struct v4l2_device v4l2_dev;
-	spinlock_t lock;
-	struct list_head instances;
-	struct dentry *debugfs_root;
-	u32 base_addr;
-	u32 register_base;
-	u32 register_size;
-	u32 irq;
-	enum vidc_core_state state;
-	struct msm_vidc_resources resources;
-	struct completion completions[SYS_MSG_END - SYS_MSG_START + 1];
-};
-
-struct msm_vidc_inst {
-	struct list_head list;
-	struct mutex sync_lock;
-	struct msm_vidc_core *core;
-	int session_type;
-	void *session;
-	struct session_prop prop;
-	int state;
-	const struct msm_vidc_format *fmts[MAX_PORT_NUM];
-	struct buf_queue bufq[MAX_PORT_NUM];
-	spinlock_t lock;
-	struct list_head pendingq;
-	struct list_head internalbufs;
-	struct list_head persistbufs;
-	struct buffer_requirements buff_req;
-	void *mem_client;
-	struct v4l2_ctrl_handler ctrl_handler;
-	struct completion completions[SESSION_MSG_END - SESSION_MSG_START + 1];
-	struct list_head ctrl_clusters;
-	struct v4l2_fh event_handler;
-	struct msm_smem *extradata_handle;
-	wait_queue_head_t kernel_event_queue;
-	bool in_reconfig;
-	u32 reconfig_width;
-	u32 reconfig_height;
-	struct dentry *debugfs_root;
-	u32 ftb_count;
-	struct vb2_buffer *vb2_seq_hdr;
-	void *priv;
-	struct msm_vidc_debug debug;
-	struct buf_count count;
-	enum msm_vidc_mode mode;
-};
-
-extern struct msm_vidc_drv *vidc_driver;
-
-struct msm_vidc_ctrl_cluster {
-	struct v4l2_ctrl **cluster;
-	struct list_head list;
-};
-
-struct msm_vidc_ctrl {
-	u32 id;
-	char name[MAX_NAME_LENGTH];
-	enum v4l2_ctrl_type type;
-	s32 minimum;
-	s32 maximum;
-	s32 default_value;
-	u32 step;
-	u32 menu_skip_mask;
-	const char * const *qmenu;
-	u32 cluster;
-	struct v4l2_ctrl *priv;
-};
-
-void handle_cmd_response(enum command_response cmd, void *data);
-int msm_vidc_ocmem_notify_handler(struct notifier_block *this,
-		unsigned long event, void *data);
-#endif
diff --git a/drivers/media/video/msm_vidc/vidc_hal.c b/drivers/media/video/msm_vidc/vidc_hal.c
deleted file mode 100644
index 10ab0dd..0000000
--- a/drivers/media/video/msm_vidc/vidc_hal.c
+++ /dev/null
@@ -1,2388 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/workqueue.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <mach/ocmem.h>
-
-#include <asm/memory.h>
-#include "vidc_hal.h"
-#include "vidc_hal_io.h"
-#include "msm_vidc_debug.h"
-
-#define FIRMWARE_SIZE			0X00A00000
-#define REG_ADDR_OFFSET_BITMASK	0x000FFFFF
-
-/*Workaround for virtio */
-#define HFI_VIRTIO_FW_BIAS		0x0
-
-struct hal_device_data hal_ctxt;
-
-static void hal_virtio_modify_cmd_packet(u8 *packet)
-{
-	struct hfi_cmd_sys_session_init_packet *sys_init;
-	struct hal_session *sess;
-	u8 i;
-
-	if (!packet) {
-		dprintk(VIDC_ERR, "Invalid Param");
-		return;
-	}
-
-	sys_init = (struct hfi_cmd_sys_session_init_packet *)packet;
-	sess = (struct hal_session *) sys_init->session_id;
-	switch (sys_init->packet_type) {
-	case HFI_CMD_SESSION_EMPTY_BUFFER:
-		if (sess->is_decoder) {
-			struct hfi_cmd_session_empty_buffer_compressed_packet
-			*pkt = (struct
-			hfi_cmd_session_empty_buffer_compressed_packet
-			*) packet;
-			pkt->packet_buffer -= HFI_VIRTIO_FW_BIAS;
-		} else {
-			struct
-			hfi_cmd_session_empty_buffer_uncompressed_plane0_packet
-			*pkt = (struct
-			hfi_cmd_session_empty_buffer_uncompressed_plane0_packet
-			*) packet;
-			pkt->packet_buffer -= HFI_VIRTIO_FW_BIAS;
-		}
-		break;
-	case HFI_CMD_SESSION_FILL_BUFFER:
-	{
-		struct hfi_cmd_session_fill_buffer_packet *pkt =
-			(struct hfi_cmd_session_fill_buffer_packet *)packet;
-		pkt->packet_buffer -= HFI_VIRTIO_FW_BIAS;
-		break;
-	}
-	case HFI_CMD_SESSION_SET_BUFFERS:
-	{
-		struct hfi_cmd_session_set_buffers_packet *pkt =
-			(struct hfi_cmd_session_set_buffers_packet *)packet;
-		if ((pkt->buffer_type == HFI_BUFFER_OUTPUT) ||
-			(pkt->buffer_type == HFI_BUFFER_OUTPUT2)) {
-			struct hfi_buffer_info *buff;
-			buff = (struct hfi_buffer_info *) pkt->rg_buffer_info;
-			buff->buffer_addr -= HFI_VIRTIO_FW_BIAS;
-			buff->extra_data_addr -= HFI_VIRTIO_FW_BIAS;
-		} else {
-			for (i = 0; i < pkt->num_buffers; i++)
-				pkt->rg_buffer_info[i] -= HFI_VIRTIO_FW_BIAS;
-		}
-		break;
-	}
-	case HFI_CMD_SESSION_RELEASE_BUFFERS:
-	{
-		struct hfi_cmd_session_release_buffer_packet *pkt =
-			(struct hfi_cmd_session_release_buffer_packet *)packet;
-		if ((pkt->buffer_type == HFI_BUFFER_OUTPUT) ||
-			(pkt->buffer_type == HFI_BUFFER_OUTPUT2)) {
-			struct hfi_buffer_info *buff;
-			buff = (struct hfi_buffer_info *) pkt->rg_buffer_info;
-			buff->buffer_addr -= HFI_VIRTIO_FW_BIAS;
-			buff->extra_data_addr -= HFI_VIRTIO_FW_BIAS;
-		} else {
-			for (i = 0; i < pkt->num_buffers; i++)
-				pkt->rg_buffer_info[i] -= HFI_VIRTIO_FW_BIAS;
-		}
-		break;
-	}
-	case HFI_CMD_SESSION_PARSE_SEQUENCE_HEADER:
-	{
-		struct hfi_cmd_session_parse_sequence_header_packet *pkt =
-			(struct hfi_cmd_session_parse_sequence_header_packet *)
-		packet;
-		pkt->packet_buffer -= HFI_VIRTIO_FW_BIAS;
-		break;
-	}
-	case HFI_CMD_SESSION_GET_SEQUENCE_HEADER:
-	{
-		struct hfi_cmd_session_get_sequence_header_packet *pkt =
-			(struct hfi_cmd_session_get_sequence_header_packet *)
-		packet;
-		pkt->packet_buffer -= HFI_VIRTIO_FW_BIAS;
-		break;
-	}
-	default:
-		break;
-	}
-}
-
-static int write_queue(void *info, u8 *packet, u32 *rx_req_is_set)
-{
-	struct hfi_queue_header *queue;
-	u32 packet_size_in_words, new_write_idx;
-	struct vidc_iface_q_info *qinfo;
-	u32 empty_space, read_idx;
-	u32 *write_ptr;
-
-	if (!info || !packet || !rx_req_is_set) {
-		dprintk(VIDC_ERR, "Invalid Params");
-		return -EINVAL;
-	}
-
-	qinfo =	(struct vidc_iface_q_info *) info;
-	hal_virtio_modify_cmd_packet(packet);
-
-	queue = (struct hfi_queue_header *) qinfo->q_hdr;
-
-	if (!queue) {
-		dprintk(VIDC_ERR, "queue not present");
-		return -ENOENT;
-	}
-
-	packet_size_in_words = (*(u32 *)packet) >> 2;
-	dprintk(VIDC_DBG, "Packet_size in words: %d", packet_size_in_words);
-
-	if (packet_size_in_words == 0) {
-		dprintk(VIDC_ERR, "Zero packet size");
-		return -ENODATA;
-	}
-
-	read_idx = queue->qhdr_read_idx;
-
-	empty_space = (queue->qhdr_write_idx >=  read_idx) ?
-		(queue->qhdr_q_size - (queue->qhdr_write_idx -  read_idx)) :
-		(read_idx - queue->qhdr_write_idx);
-	dprintk(VIDC_DBG, "Empty_space: %d", empty_space);
-	if (empty_space <= packet_size_in_words) {
-		queue->qhdr_tx_req =  1;
-		dprintk(VIDC_ERR, "Insufficient size (%d) to write (%d)",
-					  empty_space, packet_size_in_words);
-		return -ENOTEMPTY;
-	}
-
-	queue->qhdr_tx_req =  0;
-
-	new_write_idx = (queue->qhdr_write_idx + packet_size_in_words);
-	write_ptr = (u32 *)((qinfo->q_array.align_virtual_addr) +
-		(queue->qhdr_write_idx << 2));
-	dprintk(VIDC_DBG, "Write Ptr: %d", (u32) write_ptr);
-	if (new_write_idx < queue->qhdr_q_size) {
-		memcpy(write_ptr, packet, packet_size_in_words << 2);
-	} else {
-		new_write_idx -= queue->qhdr_q_size;
-		memcpy(write_ptr, packet, (packet_size_in_words -
-			new_write_idx) << 2);
-		memcpy((void *)qinfo->q_array.align_virtual_addr,
-			packet + ((packet_size_in_words - new_write_idx) << 2),
-			new_write_idx  << 2);
-	}
-	queue->qhdr_write_idx = new_write_idx;
-	*rx_req_is_set = (1 == queue->qhdr_rx_req) ? 1 : 0;
-	dprintk(VIDC_DBG, "Out : ");
-	return 0;
-}
-
-static void hal_virtio_modify_msg_packet(u8 *packet)
-{
-	struct hfi_msg_sys_session_init_done_packet *sys_idle;
-	struct hal_session *sess;
-
-	if (!packet) {
-		dprintk(VIDC_ERR, "Invalid Param: ");
-		return;
-	}
-
-	sys_idle = (struct hfi_msg_sys_session_init_done_packet *)packet;
-	sess = (struct hal_session *) sys_idle->session_id;
-
-	switch (sys_idle->packet_type) {
-	case HFI_MSG_SESSION_FILL_BUFFER_DONE:
-		if (sess->is_decoder) {
-			struct
-			hfi_msg_session_fbd_uncompressed_plane0_packet
-			*pkt_uc = (struct
-			hfi_msg_session_fbd_uncompressed_plane0_packet
-			*) packet;
-			pkt_uc->packet_buffer += HFI_VIRTIO_FW_BIAS;
-		} else {
-			struct
-			hfi_msg_session_fill_buffer_done_compressed_packet
-			*pkt = (struct
-			hfi_msg_session_fill_buffer_done_compressed_packet
-			*) packet;
-			pkt->packet_buffer += HFI_VIRTIO_FW_BIAS;
-		}
-		break;
-	case HFI_MSG_SESSION_EMPTY_BUFFER_DONE:
-	{
-		struct hfi_msg_session_empty_buffer_done_packet *pkt =
-		(struct hfi_msg_session_empty_buffer_done_packet *)packet;
-		pkt->packet_buffer += HFI_VIRTIO_FW_BIAS;
-		break;
-	}
-	case HFI_MSG_SESSION_GET_SEQUENCE_HEADER_DONE:
-	{
-		struct
-		hfi_msg_session_get_sequence_header_done_packet
-		*pkt =
-		(struct hfi_msg_session_get_sequence_header_done_packet *)
-		packet;
-		pkt->sequence_header += HFI_VIRTIO_FW_BIAS;
-		break;
-	}
-	default:
-		break;
-	}
-}
-
-static int read_queue(void *info, u8 *packet, u32 *pb_tx_req_is_set)
-{
-	struct hfi_queue_header *queue;
-	u32 packet_size_in_words, new_read_idx;
-	u32 *read_ptr;
-	struct vidc_iface_q_info *qinfo;
-
-	if (!info || !packet || !pb_tx_req_is_set) {
-		dprintk(VIDC_ERR, "Invalid Params");
-		return -EINVAL;
-	}
-
-	qinfo =	(struct vidc_iface_q_info *) info;
-	queue = (struct hfi_queue_header *) qinfo->q_hdr;
-
-	if (!queue) {
-		dprintk(VIDC_ERR, "Queue memory is not allocated\n");
-		return -ENOMEM;
-	}
-
-	if (queue->qhdr_read_idx == queue->qhdr_write_idx) {
-		queue->qhdr_rx_req = 1;
-		*pb_tx_req_is_set = 0;
-		return -EPERM;
-	}
-
-	read_ptr = (u32 *)((qinfo->q_array.align_virtual_addr) +
-				(queue->qhdr_read_idx << 2));
-	packet_size_in_words = (*read_ptr) >> 2;
-	dprintk(VIDC_DBG, "packet_size_in_words: %d", packet_size_in_words);
-	if (packet_size_in_words == 0) {
-		dprintk(VIDC_ERR, "Zero packet size");
-		return -ENODATA;
-	}
-
-	new_read_idx = queue->qhdr_read_idx + packet_size_in_words;
-	dprintk(VIDC_DBG, "Read Ptr: %d", (u32) new_read_idx);
-	if (new_read_idx < queue->qhdr_q_size) {
-		memcpy(packet, read_ptr,
-			packet_size_in_words << 2);
-	} else {
-		new_read_idx -= queue->qhdr_q_size;
-		memcpy(packet, read_ptr,
-			(packet_size_in_words - new_read_idx) << 2);
-		memcpy(packet + ((packet_size_in_words -
-			new_read_idx) << 2),
-			(u8 *)qinfo->q_array.align_virtual_addr,
-			new_read_idx << 2);
-	}
-
-	queue->qhdr_read_idx = new_read_idx;
-
-	if (queue->qhdr_read_idx != queue->qhdr_write_idx)
-		queue->qhdr_rx_req = 0;
-	else
-		queue->qhdr_rx_req = 1;
-
-	*pb_tx_req_is_set = (1 == queue->qhdr_tx_req) ? 1 : 0;
-	hal_virtio_modify_msg_packet(packet);
-	dprintk(VIDC_DBG, "Out : ");
-	return 0;
-}
-
-static int vidc_hal_alloc(void *mem, void *clnt, u32 size, u32 align, u32 flags,
-		int domain)
-{
-	struct vidc_mem_addr *vmem;
-	struct msm_smem *alloc;
-	int rc = 0;
-
-	if (!mem || !clnt || !size) {
-		dprintk(VIDC_ERR, "Invalid Params");
-		return -EINVAL;
-	}
-	vmem = (struct vidc_mem_addr *)mem;
-	dprintk(VIDC_INFO, "start to alloc: size:%d, Flags: %d", size, flags);
-
-	alloc  = msm_smem_alloc(clnt, size, align, flags, domain, 1, 1);
-	dprintk(VIDC_DBG, "Alloc done");
-	if (!alloc) {
-		dprintk(VIDC_ERR, "Alloc failed\n");
-		rc = -ENOMEM;
-		goto fail_smem_alloc;
-	}
-	rc = msm_smem_clean_invalidate(clnt, alloc);
-	if (rc) {
-		dprintk(VIDC_ERR, "NOTE: Failed to clean caches\n");
-		goto fail_clean_cache;
-	}
-	dprintk(VIDC_DBG, "vidc_hal_alloc:ptr=%p,size=%d",
-			alloc->kvaddr, size);
-	vmem->mem_size = alloc->size;
-	vmem->mem_data = alloc;
-	vmem->align_virtual_addr = (u8 *) alloc->kvaddr;
-	vmem->align_device_addr = (u8 *)alloc->device_addr;
-	return rc;
-fail_clean_cache:
-	msm_smem_free(clnt, alloc);
-fail_smem_alloc:
-	return rc;
-}
-
-static void vidc_hal_free(struct smem_client *clnt, struct msm_smem *mem)
-{
-	msm_smem_free(clnt, mem);
-}
-
-static void write_register(u8 *base_addr, u32 reg, u32 value, u8 *vaddr)
-{
-	u32 hwiosymaddr = reg;
-
-	reg &= REG_ADDR_OFFSET_BITMASK;
-	if (reg == (u32)VIDC_CPU_CS_SCIACMDARG2) {
-		/* workaround to offset of FW bias */
-		struct hfi_queue_header *qhdr;
-		struct hfi_queue_table_header *qtbl_hdr =
-			(struct hfi_queue_table_header *)vaddr;
-
-		qhdr = VIDC_IFACEQ_GET_QHDR_START_ADDR(qtbl_hdr, 0);
-		qhdr->qhdr_start_addr -= HFI_VIRTIO_FW_BIAS;
-
-		qhdr = VIDC_IFACEQ_GET_QHDR_START_ADDR(qtbl_hdr, 1);
-		qhdr->qhdr_start_addr -= HFI_VIRTIO_FW_BIAS;
-
-		qhdr = VIDC_IFACEQ_GET_QHDR_START_ADDR(qtbl_hdr, 2);
-		qhdr->qhdr_start_addr -= HFI_VIRTIO_FW_BIAS;
-		value -= HFI_VIRTIO_FW_BIAS;
-	}
-
-	hwiosymaddr = ((u32)base_addr + (hwiosymaddr));
-	dprintk(VIDC_DBG, "Base addr: 0x%x, written to: 0x%x, Value: 0x%x...",
-			(u32)base_addr, hwiosymaddr, value);
-	writel_relaxed(value, hwiosymaddr);
-	wmb();
-}
-
-static int read_register(u8 *base_addr, u32 reg)
-{
-	int rc = readl_relaxed((u32)base_addr + reg);
-	rmb();
-	return rc;
-}
-
-static int vidc_hal_iface_cmdq_write(struct hal_device *device, void *pkt)
-{
-	u32 rx_req_is_set = 0;
-	struct vidc_iface_q_info *q_info;
-	int result = -EPERM;
-
-	if (!device || !pkt) {
-		dprintk(VIDC_ERR, "Invalid Params");
-		return -EINVAL;
-	}
-
-	spin_lock(&device->write_lock);
-	q_info = &device->iface_queues[VIDC_IFACEQ_CMDQ_IDX];
-	if (!q_info) {
-		dprintk(VIDC_ERR, "cannot write to shared Q's");
-		goto err_q_write;
-	}
-
-	if (!write_queue(q_info, (u8 *)pkt, &rx_req_is_set)) {
-		if (rx_req_is_set)
-			write_register(device->hal_data->register_base_addr,
-				VIDC_CPU_IC_SOFTINT,
-				1 << VIDC_CPU_IC_SOFTINT_H2A_SHFT, 0);
-		result = 0;
-	} else {
-		dprintk(VIDC_ERR, "vidc_hal_iface_cmdq_write:queue_full");
-	}
-err_q_write:
-	spin_unlock(&device->write_lock);
-	return result;
-}
-
-int vidc_hal_iface_msgq_read(struct hal_device *device, void *pkt)
-{
-	u32 tx_req_is_set = 0;
-	int rc = 0;
-	struct vidc_iface_q_info *q_info;
-
-	if (!pkt) {
-		dprintk(VIDC_ERR, "Invalid Params");
-		return -EINVAL;
-	}
-	spin_lock(&device->read_lock);
-	if (device->iface_queues[VIDC_IFACEQ_MSGQ_IDX].
-		q_array.align_virtual_addr == 0) {
-		dprintk(VIDC_ERR, "cannot read from shared MSG Q's");
-		rc = -ENODATA;
-		goto read_error;
-	}
-	q_info = &device->iface_queues[VIDC_IFACEQ_MSGQ_IDX];
-
-	if (!read_queue(q_info, (u8 *)pkt, &tx_req_is_set)) {
-		if (tx_req_is_set)
-			write_register(device->hal_data->register_base_addr,
-				VIDC_CPU_IC_SOFTINT,
-				1 << VIDC_CPU_IC_SOFTINT_H2A_SHFT, 0);
-		rc = 0;
-	} else {
-		dprintk(VIDC_INFO, "vidc_hal_iface_msgq_read:queue_empty");
-		rc = -ENODATA;
-	}
-read_error:
-	spin_unlock(&device->read_lock);
-	return rc;
-}
-
-int vidc_hal_iface_dbgq_read(struct hal_device *device, void *pkt)
-{
-	u32 tx_req_is_set = 0;
-	int rc = 0;
-	struct vidc_iface_q_info *q_info;
-
-	if (!pkt) {
-		dprintk(VIDC_ERR, "Invalid Params");
-		return -EINVAL;
-	}
-	spin_lock(&device->read_lock);
-	if (device->iface_queues[VIDC_IFACEQ_DBGQ_IDX].
-		q_array.align_virtual_addr == 0) {
-		dprintk(VIDC_ERR, "cannot read from shared DBG Q's");
-		rc = -ENODATA;
-		goto dbg_error;
-	}
-	q_info = &device->iface_queues[VIDC_IFACEQ_DBGQ_IDX];
-	if (!read_queue(q_info, (u8 *)pkt, &tx_req_is_set)) {
-		if (tx_req_is_set)
-			write_register(device->hal_data->register_base_addr,
-			VIDC_CPU_IC_SOFTINT,
-			1 << VIDC_CPU_IC_SOFTINT_H2A_SHFT, 0);
-		rc = 0;
-	} else {
-		dprintk(VIDC_INFO, "vidc_hal_iface_dbgq_read:queue_empty");
-		rc = -ENODATA;
-	}
-dbg_error:
-	spin_unlock(&device->read_lock);
-	return rc;
-}
-
-static void vidc_hal_set_queue_hdr_defaults(struct hfi_queue_header *q_hdr)
-{
-	q_hdr->qhdr_status = 0x1;
-	q_hdr->qhdr_type = VIDC_IFACEQ_DFLT_QHDR;
-	q_hdr->qhdr_q_size = VIDC_IFACEQ_QUEUE_SIZE / 4;
-	q_hdr->qhdr_pkt_size = 0;
-	q_hdr->qhdr_rx_wm = 0x1;
-	q_hdr->qhdr_tx_wm = 0x1;
-	q_hdr->qhdr_rx_req = 0x1;
-	q_hdr->qhdr_tx_req = 0x0;
-	q_hdr->qhdr_rx_irq_status = 0x0;
-	q_hdr->qhdr_tx_irq_status = 0x0;
-	q_hdr->qhdr_read_idx = 0x0;
-	q_hdr->qhdr_write_idx = 0x0;
-}
-
-static void vidc_hal_interface_queues_release(struct hal_device *device)
-{
-	int i;
-
-	vidc_hal_free(device->hal_client, device->mem_addr.mem_data);
-
-	for (i = 0; i < VIDC_IFACEQ_NUMQ; i++) {
-		device->iface_queues[i].q_hdr = NULL;
-		device->iface_queues[i].q_array.mem_data = NULL;
-		device->iface_queues[i].q_array.align_virtual_addr = NULL;
-		device->iface_queues[i].q_array.align_device_addr = NULL;
-	}
-	device->iface_q_table.align_virtual_addr = NULL;
-	device->iface_q_table.align_device_addr = NULL;
-
-	device->qdss.align_virtual_addr = NULL;
-	device->qdss.align_device_addr = NULL;
-
-	device->sfr.align_virtual_addr = NULL;
-	device->sfr.align_device_addr = NULL;
-
-	device->mem_addr.align_virtual_addr = NULL;
-	device->mem_addr.align_device_addr = NULL;
-
-	msm_smem_delete_client(device->hal_client);
-	device->hal_client = NULL;
-}
-
-static int vidc_hal_interface_queues_init(struct hal_device *dev, int domain)
-{
-	struct hfi_queue_table_header *q_tbl_hdr;
-	struct hfi_queue_header *q_hdr;
-	u8 i;
-	int rc = 0;
-	struct vidc_iface_q_info *iface_q;
-	struct hfi_sfr_struct *vsfr;
-	struct vidc_mem_addr *mem_addr;
-	int offset = 0;
-	int size_1m = 1024 * 1024;
-	int uc_size = (UC_SIZE + size_1m - 1) & (~(size_1m - 1));
-	mem_addr = &dev->mem_addr;
-	rc = vidc_hal_alloc((void *) mem_addr,
-			dev->hal_client, uc_size, 1,
-			0, domain);
-	if (rc) {
-		dprintk(VIDC_ERR, "iface_q_table_alloc_fail");
-		return -ENOMEM;
-	}
-	dev->iface_q_table.align_virtual_addr = mem_addr->align_virtual_addr;
-	dev->iface_q_table.align_device_addr = mem_addr->align_device_addr;
-	dev->iface_q_table.mem_size = VIDC_IFACEQ_TABLE_SIZE;
-	dev->iface_q_table.mem_data = NULL;
-	offset += dev->iface_q_table.mem_size;
-
-	for (i = 0; i < VIDC_IFACEQ_NUMQ; i++) {
-		iface_q = &dev->iface_queues[i];
-		iface_q->q_array.align_device_addr =
-			mem_addr->align_device_addr + offset;
-		iface_q->q_array.align_virtual_addr =
-			mem_addr->align_virtual_addr + offset;
-		iface_q->q_array.mem_size = VIDC_IFACEQ_QUEUE_SIZE;
-		iface_q->q_array.mem_data = NULL;
-		offset += iface_q->q_array.mem_size;
-		iface_q->q_hdr = VIDC_IFACEQ_GET_QHDR_START_ADDR(
-				dev->iface_q_table.align_virtual_addr, i);
-		vidc_hal_set_queue_hdr_defaults(iface_q->q_hdr);
-	}
-
-	dev->qdss.align_device_addr = mem_addr->align_device_addr + offset;
-	dev->qdss.align_virtual_addr = mem_addr->align_virtual_addr + offset;
-	dev->qdss.mem_size = QDSS_SIZE;
-	dev->qdss.mem_data = NULL;
-	offset += dev->qdss.mem_size;
-
-	dev->sfr.align_device_addr = mem_addr->align_device_addr + offset;
-	dev->sfr.align_virtual_addr = mem_addr->align_virtual_addr + offset;
-	dev->sfr.mem_size = SFR_SIZE;
-	dev->sfr.mem_data = NULL;
-	offset += dev->sfr.mem_size;
-
-	q_tbl_hdr = (struct hfi_queue_table_header *)
-			dev->iface_q_table.align_virtual_addr;
-	q_tbl_hdr->qtbl_version = 0;
-	q_tbl_hdr->qtbl_size = VIDC_IFACEQ_TABLE_SIZE;
-	q_tbl_hdr->qtbl_qhdr0_offset = sizeof(
-		struct hfi_queue_table_header);
-	q_tbl_hdr->qtbl_qhdr_size = sizeof(
-		struct hfi_queue_header);
-	q_tbl_hdr->qtbl_num_q = VIDC_IFACEQ_NUMQ;
-	q_tbl_hdr->qtbl_num_active_q = VIDC_IFACEQ_NUMQ;
-
-	iface_q = &dev->iface_queues[VIDC_IFACEQ_CMDQ_IDX];
-	q_hdr = iface_q->q_hdr;
-	q_hdr->qhdr_start_addr = (u32)
-		iface_q->q_array.align_device_addr;
-	q_hdr->qhdr_type |= HFI_Q_ID_HOST_TO_CTRL_CMD_Q;
-
-	iface_q = &dev->iface_queues[VIDC_IFACEQ_MSGQ_IDX];
-	q_hdr = iface_q->q_hdr;
-	q_hdr->qhdr_start_addr = (u32)
-		iface_q->q_array.align_device_addr;
-	q_hdr->qhdr_type |= HFI_Q_ID_CTRL_TO_HOST_MSG_Q;
-
-	iface_q = &dev->iface_queues[VIDC_IFACEQ_DBGQ_IDX];
-	q_hdr = iface_q->q_hdr;
-	q_hdr->qhdr_start_addr = (u32)
-		iface_q->q_array.align_device_addr;
-	q_hdr->qhdr_type |= HFI_Q_ID_CTRL_TO_HOST_DEBUG_Q;
-
-	write_register(dev->hal_data->register_base_addr,
-			VIDC_UC_REGION_ADDR,
-			(u32) mem_addr->align_device_addr, 0);
-	write_register(dev->hal_data->register_base_addr,
-			VIDC_UC_REGION_SIZE, mem_addr->mem_size, 0);
-	write_register(dev->hal_data->register_base_addr,
-		VIDC_CPU_CS_SCIACMDARG2,
-		(u32) dev->iface_q_table.align_device_addr,
-		dev->iface_q_table.align_virtual_addr);
-	write_register(dev->hal_data->register_base_addr,
-		VIDC_CPU_CS_SCIACMDARG1, 0x01,
-		dev->iface_q_table.align_virtual_addr);
-	write_register(dev->hal_data->register_base_addr,
-			VIDC_MMAP_ADDR,
-			(u32) dev->qdss.align_device_addr, 0);
-
-	vsfr = (struct hfi_sfr_struct *) dev->sfr.align_virtual_addr;
-	vsfr->bufSize = SFR_SIZE;
-
-	write_register(dev->hal_data->register_base_addr,
-			VIDC_SFR_ADDR, (u32)dev->sfr.align_device_addr , 0);
-	return 0;
-}
-
-static int vidc_hal_core_start_cpu(struct hal_device *device)
-{
-	u32 ctrl_status = 0, count = 0, rc = 0;
-	int max_tries = 100;
-	write_register(device->hal_data->register_base_addr,
-			VIDC_WRAPPER_INTR_MASK, 0x8, 0);
-	write_register(device->hal_data->register_base_addr,
-			VIDC_CPU_CS_SCIACMDARG3, 1, 0);
-
-	while (!ctrl_status && count < max_tries) {
-		ctrl_status = read_register(
-		device->hal_data->register_base_addr,
-		VIDC_CPU_CS_SCIACMDARG0);
-		if ((ctrl_status & 0xFE) == 0x4) {
-			dprintk(VIDC_ERR, "invalid setting for UC_REGION\n");
-			break;
-		}
-		usleep_range(500, 1000);
-		count++;
-	}
-	if (count >= max_tries)
-		rc = -ETIME;
-	return rc;
-}
-
-static void set_vbif_registers(struct hal_device *device)
-{
-	/*Disable Dynamic clock gating for Venus VBIF*/
-	write_register(device->hal_data->register_base_addr,
-				   VIDC_VENUS_VBIF_CLK_ON, 1, 0);
-	write_register(device->hal_data->register_base_addr,
-			VIDC_VBIF_OUT_AXI_AOOO_EN, 0x00001FFF, 0);
-	write_register(device->hal_data->register_base_addr,
-			VIDC_VBIF_OUT_AXI_AOOO, 0x1FFF1FFF, 0);
-	write_register(device->hal_data->register_base_addr,
-			VIDC_VBIF_IN_RD_LIM_CONF0, 0x10101001, 0);
-	write_register(device->hal_data->register_base_addr,
-			VIDC_VBIF_IN_RD_LIM_CONF1, 0x10101010, 0);
-	write_register(device->hal_data->register_base_addr,
-			VIDC_VBIF_IN_RD_LIM_CONF2, 0x10101010, 0);
-	write_register(device->hal_data->register_base_addr,
-			VIDC_VBIF_IN_RD_LIM_CONF3, 0x00000010, 0);
-	write_register(device->hal_data->register_base_addr,
-			VIDC_VBIF_IN_WR_LIM_CONF0, 0x1010100f, 0);
-	write_register(device->hal_data->register_base_addr,
-			VIDC_VBIF_IN_WR_LIM_CONF1, 0x10101010, 0);
-	write_register(device->hal_data->register_base_addr,
-			VIDC_VBIF_IN_WR_LIM_CONF2, 0x10101010, 0);
-	write_register(device->hal_data->register_base_addr,
-			VIDC_VBIF_IN_WR_LIM_CONF3, 0x00000010, 0);
-	write_register(device->hal_data->register_base_addr,
-			VIDC_VBIF_OUT_RD_LIM_CONF0, 0x00001010, 0);
-	write_register(device->hal_data->register_base_addr,
-			VIDC_VBIF_OUT_WR_LIM_CONF0, 0x00001010, 0);
-	write_register(device->hal_data->register_base_addr,
-			VIDC_VBIF_ARB_CTL, 0x00000030, 0);
-	write_register(device->hal_data->register_base_addr,
-			VIDC_VENUS_VBIF_DDR_OUT_MAX_BURST, 0x00000707, 0);
-	write_register(device->hal_data->register_base_addr,
-			VIDC_VENUS_VBIF_OCMEM_OUT_MAX_BURST, 0x00000707, 0);
-	write_register(device->hal_data->register_base_addr,
-			VIDC_VENUS_VBIF_ROUND_ROBIN_QOS_ARB, 0x00000001, 0);
-	write_register(device->hal_data->register_base_addr,
-			VIDC_VENUS0_WRAPPER_VBIF_REQ_PRIORITY, 0x5555556, 0);
-	write_register(device->hal_data->register_base_addr,
-			VIDC_VENUS0_WRAPPER_VBIF_PRIORITY_LEVEL, 0, 0);
-}
-
-static int vidc_hal_sys_set_debug(struct hal_device *device, int debug)
-{
-	struct hfi_debug_config *hfi;
-	u8 packet[VIDC_IFACEQ_VAR_SMALL_PKT_SIZE];
-	struct hfi_cmd_sys_set_property_packet *pkt =
-		(struct hfi_cmd_sys_set_property_packet *) &packet;
-	pkt->size = sizeof(struct hfi_cmd_sys_set_property_packet) +
-		sizeof(struct hfi_debug_config) + sizeof(u32);
-	pkt->packet_type = HFI_CMD_SYS_SET_PROPERTY;
-	pkt->num_properties = 1;
-	pkt->rg_property_data[0] = HFI_PROPERTY_SYS_DEBUG_CONFIG;
-	hfi = (struct hfi_debug_config *) &pkt->rg_property_data[1];
-	hfi->debug_config = debug;
-	if (vidc_hal_iface_cmdq_write(device, pkt))
-		return -ENOTEMPTY;
-	return 0;
-}
-
-int vidc_hal_core_init(void *device, int domain)
-{
-	struct hfi_cmd_sys_init_packet pkt;
-	int rc = 0;
-	struct hal_device *dev;
-
-	if (device) {
-		dev = device;
-	} else {
-		dprintk(VIDC_ERR, "Invalid device");
-		return -ENODEV;
-	}
-	dev->intr_status = 0;
-	enable_irq(dev->hal_data->irq);
-	INIT_LIST_HEAD(&dev->sess_head);
-	spin_lock_init(&dev->read_lock);
-	spin_lock_init(&dev->write_lock);
-	set_vbif_registers(dev);
-
-	if (!dev->hal_client) {
-		dev->hal_client = msm_smem_new_client(SMEM_ION);
-		if (dev->hal_client == NULL) {
-			dprintk(VIDC_ERR, "Failed to alloc ION_Client");
-			rc = -ENODEV;
-			goto err_no_mem;
-		}
-
-		dprintk(VIDC_DBG, "Dev_Virt: 0x%x, Reg_Virt: 0x%x",
-		dev->hal_data->device_base_addr,
-		(u32) dev->hal_data->register_base_addr);
-
-		rc = vidc_hal_interface_queues_init(dev, domain);
-		if (rc) {
-			dprintk(VIDC_ERR, "failed to init queues");
-			rc = -ENOMEM;
-			goto err_no_mem;
-		}
-	} else {
-		dprintk(VIDC_ERR, "hal_client exists");
-		rc = -EEXIST;
-		goto err_no_mem;
-	}
-	write_register(dev->hal_data->register_base_addr,
-		VIDC_CTRL_INIT, 0x1, 0);
-	rc = vidc_hal_core_start_cpu(dev);
-	if (rc) {
-		dprintk(VIDC_ERR, "Failed to start core");
-		rc = -ENODEV;
-		goto err_no_dev;
-	}
-
-	pkt.size = sizeof(struct hfi_cmd_sys_init_packet);
-	pkt.packet_type = HFI_CMD_SYS_INIT;
-	pkt.arch_type = HFI_ARCH_OX_OFFSET;
-	if (vidc_hal_iface_cmdq_write(dev, &pkt)) {
-		rc = -ENOTEMPTY;
-		goto err_write_fail;
-	}
-	return rc;
-err_no_dev:
-err_write_fail:
-err_no_mem:
-	disable_irq_nosync(dev->hal_data->irq);
-	return rc;
-}
-
-int vidc_hal_core_release(void *device)
-{
-	struct hal_device *dev;
-	if (device) {
-		dev = device;
-	} else {
-		dprintk(VIDC_ERR, "invalid device");
-		return -ENODEV;
-	}
-	if (dev->hal_client) {
-		write_register(dev->hal_data->register_base_addr,
-				VIDC_CPU_CS_SCIACMDARG3, 0, 0);
-		disable_irq_nosync(dev->hal_data->irq);
-		vidc_hal_interface_queues_release(dev);
-	}
-	dprintk(VIDC_INFO, "HAL exited\n");
-	return 0;
-}
-
-int vidc_hal_core_pc_prep(void *device)
-{
-	struct hfi_cmd_sys_pc_prep_packet pkt;
-	int rc = 0;
-	struct hal_device *dev;
-
-	if (device) {
-		dev = device;
-	} else {
-		dprintk(VIDC_ERR, "invalid device");
-		return -ENODEV;
-	}
-	pkt.size = sizeof(struct hfi_cmd_sys_pc_prep_packet);
-	pkt.packet_type = HFI_CMD_SYS_PC_PREP;
-	if (vidc_hal_iface_cmdq_write(dev, &pkt))
-		rc = -ENOTEMPTY;
-	return rc;
-}
-
-static void vidc_hal_core_clear_interrupt(struct hal_device *device)
-{
-	u32 intr_status = 0;
-
-	if (!device->callback)
-		return;
-
-	intr_status = read_register(
-		device->hal_data->register_base_addr,
-		VIDC_WRAPPER_INTR_STATUS);
-
-	if ((intr_status & VIDC_WRAPPER_INTR_STATUS_A2H_BMSK) ||
-		(intr_status & VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK)) {
-		device->intr_status |= intr_status;
-		dprintk(VIDC_DBG, "INTERRUPT for device: 0x%x: "
-			"times: %d interrupt_status: %d",
-			(u32) device, ++device->reg_count, intr_status);
-	} else {
-		dprintk(VIDC_INFO, "SPURIOUS_INTR for device: 0x%x: "
-			"times: %d interrupt_status: %d",
-			(u32) device, ++device->spur_count, intr_status);
-	}
-	write_register(device->hal_data->register_base_addr,
-			VIDC_CPU_CS_A2HSOFTINTCLR, 1, 0);
-	write_register(device->hal_data->register_base_addr,
-			VIDC_WRAPPER_INTR_CLEAR, intr_status, 0);
-	dprintk(VIDC_DBG, "Cleared WRAPPER/A2H interrupt");
-}
-
-int vidc_hal_core_set_resource(void *device,
-		struct vidc_resource_hdr *resource_hdr, void *resource_value)
-{
-	struct hfi_cmd_sys_set_resource_packet *pkt;
-	u8 packet[VIDC_IFACEQ_VAR_SMALL_PKT_SIZE];
-	int rc = 0;
-	struct hal_device *dev;
-
-	if (!device || !resource_hdr || !resource_value) {
-		dprintk(VIDC_ERR, "set_res: Invalid Params");
-		return -EINVAL;
-	} else {
-		dev = device;
-	}
-
-	pkt = (struct hfi_cmd_sys_set_resource_packet *) packet;
-
-	pkt->size = sizeof(struct hfi_cmd_sys_set_resource_packet);
-	pkt->packet_type = HFI_CMD_SYS_SET_RESOURCE;
-	pkt->resource_handle = resource_hdr->resource_handle;
-
-	switch (resource_hdr->resource_id) {
-	case VIDC_RESOURCE_OCMEM:
-	{
-		struct hfi_resource_ocmem *hfioc_mem =
-			(struct hfi_resource_ocmem *)
-			&pkt->rg_resource_data[0];
-		struct ocmem_buf *ocmem =
-			(struct ocmem_buf *) resource_value;
-
-		pkt->resource_type = HFI_RESOURCE_OCMEM;
-		hfioc_mem->size = (u32) ocmem->len;
-		hfioc_mem->mem = (u8 *) ocmem->addr;
-		pkt->size += sizeof(struct hfi_resource_ocmem);
-		if (vidc_hal_iface_cmdq_write(dev, pkt))
-			rc = -ENOTEMPTY;
-		break;
-	}
-	default:
-		dprintk(VIDC_INFO, "Invalid res_id in set_res %d",
-						resource_hdr->resource_id);
-		break;
-	}
-	return rc;
-}
-
-int vidc_hal_core_release_resource(void *device,
-			struct vidc_resource_hdr *resource_hdr)
-{
-	struct hfi_cmd_sys_release_resource_packet pkt;
-	int rc = 0;
-	struct hal_device *dev;
-
-	if (!device || !resource_hdr) {
-		dprintk(VIDC_ERR, "Inv-Params in rel_res");
-		return -EINVAL;
-	} else {
-		dev = device;
-	}
-
-	pkt.size = sizeof(struct hfi_cmd_sys_release_resource_packet);
-	pkt.packet_type = HFI_CMD_SYS_RELEASE_RESOURCE;
-	pkt.resource_type = resource_hdr->resource_id;
-	pkt.resource_handle = resource_hdr->resource_handle;
-
-	if (vidc_hal_iface_cmdq_write(dev, &pkt))
-		rc = -ENOTEMPTY;
-	return rc;
-}
-
-int vidc_hal_core_ping(void *device)
-{
-	struct hfi_cmd_sys_ping_packet pkt;
-	int rc = 0;
-	struct hal_device *dev;
-
-	if (device) {
-		dev = device;
-	} else {
-		dprintk(VIDC_ERR, "invalid device");
-		return -ENODEV;
-	}
-	pkt.size = sizeof(struct hfi_cmd_sys_ping_packet);
-	pkt.packet_type = HFI_CMD_SYS_PING;
-
-	if (vidc_hal_iface_cmdq_write(dev, &pkt))
-		rc = -ENOTEMPTY;
-	return rc;
-}
-static u32 get_hfi_buffer(int hal_buffer)
-{
-	u32 buffer;
-	switch (hal_buffer) {
-	case HAL_BUFFER_INPUT:
-		buffer = HFI_BUFFER_INPUT;
-		break;
-	case HAL_BUFFER_OUTPUT:
-		buffer = HFI_BUFFER_OUTPUT;
-		break;
-	case HAL_BUFFER_OUTPUT2:
-		buffer = HFI_BUFFER_OUTPUT;
-		break;
-	case HAL_BUFFER_EXTRADATA_INPUT:
-		buffer = HFI_BUFFER_EXTRADATA_INPUT;
-		break;
-	case HAL_BUFFER_EXTRADATA_OUTPUT:
-		buffer = HFI_BUFFER_EXTRADATA_OUTPUT;
-		break;
-	case HAL_BUFFER_EXTRADATA_OUTPUT2:
-		buffer = HFI_BUFFER_EXTRADATA_OUTPUT2;
-		break;
-	case HAL_BUFFER_INTERNAL_SCRATCH:
-		buffer = HFI_BUFFER_INTERNAL_SCRATCH;
-		break;
-	case HAL_BUFFER_INTERNAL_PERSIST:
-		buffer = HFI_BUFFER_INTERNAL_PERSIST;
-		break;
-	default:
-		dprintk(VIDC_ERR, "Invalid buffer :0x%x\n",
-				hal_buffer);
-		buffer = 0;
-		break;
-	}
-	return buffer;
-}
-
-
-static int get_hfi_extradata_index(enum hal_extradata_id index)
-{
-	int ret = 0;
-	switch (index) {
-	case HAL_EXTRADATA_MB_QUANTIZATION:
-		ret = HFI_PROPERTY_PARAM_VDEC_MB_QUANTIZATION;
-		break;
-	case HAL_EXTRADATA_INTERLACE_VIDEO:
-		ret = HFI_PROPERTY_PARAM_VDEC_INTERLACE_VIDEO_EXTRADATA;
-		break;
-	case HAL_EXTRADATA_VC1_FRAMEDISP:
-		ret = HFI_PROPERTY_PARAM_VDEC_VC1_FRAMEDISP_EXTRADATA;
-		break;
-	case HAL_EXTRADATA_VC1_SEQDISP:
-		ret = HFI_PROPERTY_PARAM_VDEC_VC1_SEQDISP_EXTRADATA;
-		break;
-	case HAL_EXTRADATA_TIMESTAMP:
-		ret = HFI_PROPERTY_PARAM_VDEC_TIMESTAMP_EXTRADATA;
-		break;
-	case HAL_EXTRADATA_S3D_FRAME_PACKING:
-		ret = HFI_PROPERTY_PARAM_S3D_FRAME_PACKING_EXTRADATA;
-		break;
-	case HAL_EXTRADATA_FRAME_RATE:
-		ret = HFI_PROPERTY_PARAM_VDEC_FRAME_RATE_EXTRADATA;
-		break;
-	case HAL_EXTRADATA_PANSCAN_WINDOW:
-		ret = HFI_PROPERTY_PARAM_VDEC_PANSCAN_WNDW_EXTRADATA;
-		break;
-	case HAL_EXTRADATA_RECOVERY_POINT_SEI:
-		ret = HFI_PROPERTY_PARAM_VDEC_RECOVERY_POINT_SEI_EXTRADATA;
-		break;
-	case HAL_EXTRADATA_CLOSED_CAPTION_UD:
-		ret = HFI_PROPERTY_PARAM_VDEC_CLOSED_CAPTION_EXTRADATA;
-		break;
-	case HAL_EXTRADATA_AFD_UD:
-		ret = HFI_PROPERTY_PARAM_VDEC_AFD_EXTRADATA;
-		break;
-	case HAL_EXTRADATA_MULTISLICE_INFO:
-		ret = HFI_PROPERTY_PARAM_VENC_MULTI_SLICE_INFO;
-		break;
-	case HAL_EXTRADATA_NUM_CONCEALED_MB:
-		ret = HFI_PROPERTY_PARAM_VDEC_NUM_CONCEALED_MB;
-		break;
-	case HAL_EXTRADATA_INDEX:
-		ret = HFI_PROPERTY_PARAM_EXTRA_DATA_HEADER_CONFIG;
-		break;
-	default:
-		dprintk(VIDC_WARN, "Extradata index not found: %d\n", index);
-		break;
-	}
-	return ret;
-}
-
-int vidc_hal_session_set_property(void *sess,
-	enum hal_property ptype, void *pdata)
-{
-	u8 packet[VIDC_IFACEQ_VAR_LARGE_PKT_SIZE];
-	struct hfi_cmd_session_set_property_packet *pkt =
-		(struct hfi_cmd_session_set_property_packet *) &packet;
-	struct hal_session *session;
-	int rc = 0;
-
-	if (!sess || !pdata) {
-		dprintk(VIDC_ERR, "Invalid Params");
-		return -EINVAL;
-	} else {
-		session = sess;
-	}
-
-	dprintk(VIDC_INFO, "in set_prop,with prop id: 0x%x", ptype);
-	pkt->size = sizeof(struct hfi_cmd_session_set_property_packet);
-	pkt->packet_type = HFI_CMD_SESSION_SET_PROPERTY;
-	pkt->session_id = (u32) session;
-	pkt->num_properties = 1;
-
-	switch (ptype) {
-	case HAL_CONFIG_FRAME_RATE:
-	{
-		struct hfi_frame_rate *hfi;
-		u32 buffer;
-		struct hal_frame_rate *prop =
-			(struct hal_frame_rate *) pdata;
-		pkt->rg_property_data[0] = HFI_PROPERTY_CONFIG_FRAME_RATE;
-		hfi = (struct hfi_frame_rate *) &pkt->rg_property_data[1];
-		buffer = get_hfi_buffer(prop->buffer_type);
-		if (buffer)
-			hfi->buffer_type = buffer;
-		else
-			return -EINVAL;
-		hfi->frame_rate = prop->frame_rate;
-		pkt->size += sizeof(u32) + sizeof(struct hfi_frame_rate);
-		break;
-	}
-	case HAL_PARAM_UNCOMPRESSED_FORMAT_SELECT:
-	{
-		u32 buffer;
-		struct hfi_uncompressed_format_select *hfi;
-		struct hal_uncompressed_format_select *prop =
-			(struct hal_uncompressed_format_select *) pdata;
-		pkt->rg_property_data[0] =
-			HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT;
-		hfi = (struct hfi_uncompressed_format_select *)
-			&pkt->rg_property_data[1];
-		buffer = get_hfi_buffer(prop->buffer_type);
-		if (buffer)
-			hfi->buffer_type = buffer;
-		else
-			return -EINVAL;
-		hfi->format = prop->format;
-		pkt->size += sizeof(u32) + sizeof(struct
-			hfi_uncompressed_format_select);
-		break;
-	}
-	case HAL_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO:
-		break;
-	case HAL_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO:
-		break;
-	case HAL_PARAM_EXTRA_DATA_HEADER_CONFIG:
-		break;
-	case HAL_PARAM_FRAME_SIZE:
-	{
-		u32 buffer;
-		struct hfi_frame_size *hfi;
-		struct hal_frame_size *prop = (struct hal_frame_size *) pdata;
-		pkt->rg_property_data[0] = HFI_PROPERTY_PARAM_FRAME_SIZE;
-		hfi = (struct hfi_frame_size *) &pkt->rg_property_data[1];
-		buffer = get_hfi_buffer(prop->buffer_type);
-		if (buffer)
-			hfi->buffer_type = buffer;
-		else
-			return -EINVAL;
-		hfi->height = prop->height;
-		hfi->width = prop->width;
-		pkt->size += sizeof(u32) + sizeof(struct hfi_frame_size);
-		break;
-	}
-	case HAL_CONFIG_REALTIME:
-	{
-		struct hfi_enable *hfi;
-		pkt->rg_property_data[0] = HFI_PROPERTY_CONFIG_REALTIME;
-		hfi = (struct hfi_enable *) &pkt->rg_property_data[1];
-		hfi->enable = ((struct hfi_enable *) pdata)->enable;
-		pkt->size += sizeof(u32) * 2;
-		break;
-	}
-	case HAL_PARAM_BUFFER_COUNT_ACTUAL:
-	{
-		u32 buffer;
-		struct hfi_buffer_count_actual *hfi;
-		struct hal_buffer_count_actual *prop =
-			(struct hal_buffer_count_actual *) pdata;
-		pkt->rg_property_data[0] =
-			HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL;
-		hfi = (struct hfi_buffer_count_actual *)
-				&pkt->rg_property_data[1];
-		hfi->buffer_count_actual = prop->buffer_count_actual;
-		buffer = get_hfi_buffer(prop->buffer_type);
-		if (buffer)
-			hfi->buffer_type = buffer;
-		else
-			return -EINVAL;
-		pkt->size += sizeof(u32) + sizeof(struct
-					hfi_buffer_count_actual);
-		break;
-	}
-	case HAL_PARAM_NAL_STREAM_FORMAT_SELECT:
-	{
-		struct hal_nal_stream_format_supported *prop =
-			(struct hal_nal_stream_format_supported *)pdata;
-		pkt->rg_property_data[0] =
-			HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SELECT;
-		dprintk(VIDC_DBG, "data is :%d",
-				prop->nal_stream_format_supported);
-		switch (prop->nal_stream_format_supported) {
-		case HAL_NAL_FORMAT_STARTCODES:
-			pkt->rg_property_data[1] =
-				HFI_NAL_FORMAT_STARTCODES;
-			break;
-		case HAL_NAL_FORMAT_ONE_NAL_PER_BUFFER:
-			pkt->rg_property_data[1] =
-				HFI_NAL_FORMAT_ONE_NAL_PER_BUFFER;
-			break;
-		case HAL_NAL_FORMAT_ONE_BYTE_LENGTH:
-			pkt->rg_property_data[1] =
-				HFI_NAL_FORMAT_ONE_BYTE_LENGTH;
-			break;
-		case HAL_NAL_FORMAT_TWO_BYTE_LENGTH:
-			pkt->rg_property_data[1] =
-				HFI_NAL_FORMAT_TWO_BYTE_LENGTH;
-			break;
-		case HAL_NAL_FORMAT_FOUR_BYTE_LENGTH:
-			pkt->rg_property_data[1] =
-				HFI_NAL_FORMAT_FOUR_BYTE_LENGTH;
-			break;
-		default:
-			dprintk(VIDC_ERR, "Invalid nal format: 0x%x",
-				  prop->nal_stream_format_supported);
-			break;
-		}
-		pkt->size += sizeof(u32) * 2;
-		break;
-	}
-	case HAL_PARAM_VDEC_OUTPUT_ORDER:
-	{
-		int *data = (int *) pdata;
-		pkt->rg_property_data[0] =
-			HFI_PROPERTY_PARAM_VDEC_OUTPUT_ORDER;
-		switch (*data) {
-		case HAL_OUTPUT_ORDER_DECODE:
-			pkt->rg_property_data[1] = HFI_OUTPUT_ORDER_DECODE;
-			break;
-		case HAL_OUTPUT_ORDER_DISPLAY:
-			pkt->rg_property_data[1] = HFI_OUTPUT_ORDER_DISPLAY;
-			break;
-		default:
-			dprintk(VIDC_ERR, "invalid output order: 0x%x",
-						  *data);
-			break;
-		}
-		pkt->size += sizeof(u32) * 2;
-		break;
-	}
-	case HAL_PARAM_VDEC_PICTURE_TYPE_DECODE:
-	{
-		struct hfi_enable_picture *hfi;
-		pkt->rg_property_data[0] =
-			HFI_PROPERTY_PARAM_VDEC_PICTURE_TYPE_DECODE;
-		hfi = (struct hfi_enable_picture *) &pkt->rg_property_data[1];
-		hfi->picture_type = (u32) pdata;
-		pkt->size += sizeof(u32) * 2;
-		break;
-	}
-	case HAL_PARAM_VDEC_OUTPUT2_KEEP_ASPECT_RATIO:
-	{
-		struct hfi_enable *hfi;
-		pkt->rg_property_data[0] =
-			HFI_PROPERTY_PARAM_VDEC_OUTPUT2_KEEP_ASPECT_RATIO;
-		hfi = (struct hfi_enable *) &pkt->rg_property_data[1];
-		hfi->enable = ((struct hfi_enable *) pdata)->enable;
-		pkt->size += sizeof(u32) * 2;
-		break;
-	}
-	case HAL_CONFIG_VDEC_POST_LOOP_DEBLOCKER:
-	{
-		struct hfi_enable *hfi;
-		pkt->rg_property_data[0] =
-			HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER;
-		hfi = (struct hfi_enable *) &pkt->rg_property_data[1];
-		hfi->enable = ((struct hfi_enable *) pdata)->enable;
-		pkt->size += sizeof(u32) * 2;
-		break;
-	}
-	case HAL_PARAM_VDEC_MULTI_STREAM:
-	{
-		u32 buffer;
-		struct hfi_multi_stream *hfi;
-		struct hal_multi_stream *prop =
-			(struct hal_multi_stream *) pdata;
-		pkt->rg_property_data[0] =
-			HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM;
-		hfi = (struct hfi_multi_stream *) &pkt->rg_property_data[1];
-		buffer = get_hfi_buffer(prop->buffer_type);
-		if (buffer)
-			hfi->buffer_type = buffer;
-		else
-			return -EINVAL;
-		hfi->enable = prop->enable;
-		hfi->width = prop->width;
-		hfi->height = prop->height;
-		pkt->size += sizeof(u32) + sizeof(struct hfi_multi_stream);
-		break;
-	}
-	case HAL_PARAM_VDEC_DISPLAY_PICTURE_BUFFER_COUNT:
-	{
-		struct hfi_display_picture_buffer_count *hfi;
-		struct hal_display_picture_buffer_count *prop =
-			(struct hal_display_picture_buffer_count *) pdata;
-		pkt->rg_property_data[0] =
-			HFI_PROPERTY_PARAM_VDEC_DISPLAY_PICTURE_BUFFER_COUNT;
-		hfi = (struct hfi_display_picture_buffer_count *)
-			&pkt->rg_property_data[1];
-		hfi->count = prop->count;
-		hfi->enable = prop->enable;
-		pkt->size += sizeof(u32) +
-			sizeof(struct hfi_display_picture_buffer_count);
-		break;
-	}
-	case HAL_PARAM_DIVX_FORMAT:
-	{
-		int *data = pdata;
-		pkt->rg_property_data[0] = HFI_PROPERTY_PARAM_DIVX_FORMAT;
-		switch (*data) {
-		case HAL_DIVX_FORMAT_4:
-			pkt->rg_property_data[1] = HFI_DIVX_FORMAT_4;
-			break;
-		case HAL_DIVX_FORMAT_5:
-			pkt->rg_property_data[1] = HFI_DIVX_FORMAT_5;
-			break;
-		case HAL_DIVX_FORMAT_6:
-			pkt->rg_property_data[1] = HFI_DIVX_FORMAT_6;
-			break;
-		default:
-			dprintk(VIDC_ERR, "Invalid divx format: 0x%x", *data);
-			break;
-		}
-		pkt->size += sizeof(u32) * 2;
-		break;
-	}
-	case HAL_CONFIG_VDEC_MB_ERROR_MAP_REPORTING:
-	{
-		struct hfi_enable *hfi;
-		pkt->rg_property_data[0] =
-			HFI_PROPERTY_CONFIG_VDEC_MB_ERROR_MAP_REPORTING;
-		hfi = (struct hfi_enable *) &pkt->rg_property_data[1];
-		hfi->enable = ((struct hfi_enable *) pdata)->enable;
-		pkt->size += sizeof(u32) * 2;
-		break;
-	}
-	case HAL_PARAM_VDEC_CONTINUE_DATA_TRANSFER:
-	{
-		struct hfi_enable *hfi;
-		pkt->rg_property_data[0] =
-			HFI_PROPERTY_PARAM_VDEC_CONTINUE_DATA_TRANSFER;
-		hfi = (struct hfi_enable *) &pkt->rg_property_data[1];
-		hfi->enable = ((struct hfi_enable *) pdata)->enable;
-		pkt->size += sizeof(u32) * 2;
-		break;
-	}
-	case HAL_PARAM_VDEC_SYNC_FRAME_DECODE:
-	{
-		struct hfi_enable *hfi;
-		pkt->rg_property_data[0] =
-			HFI_PROPERTY_PARAM_VDEC_THUMBNAIL_MODE;
-		hfi = (struct hfi_enable *) &pkt->rg_property_data[1];
-		hfi->enable = ((struct hfi_enable *) pdata)->enable;
-		pkt->size += sizeof(u32) * 2;
-		break;
-	}
-	case HAL_PARAM_VENC_SYNC_FRAME_SEQUENCE_HEADER:
-	{
-		struct hfi_enable *hfi;
-		pkt->rg_property_data[0] =
-			HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER;
-		hfi = (struct hfi_enable *) &pkt->rg_property_data[1];
-		hfi->enable = ((struct hfi_enable *) pdata)->enable;
-		pkt->size += sizeof(u32) * 2;
-		break;
-	}
-	case HAL_CONFIG_VENC_REQUEST_IFRAME:
-		pkt->rg_property_data[0] =
-			HFI_PROPERTY_CONFIG_VENC_REQUEST_SYNC_FRAME;
-		pkt->size += sizeof(u32);
-		break;
-	case HAL_PARAM_VENC_MPEG4_SHORT_HEADER:
-		break;
-	case HAL_PARAM_VENC_MPEG4_AC_PREDICTION:
-		break;
-	case HAL_CONFIG_VENC_TARGET_BITRATE:
-	{
-		struct hfi_bitrate *hfi;
-		pkt->rg_property_data[0] =
-			HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE;
-		hfi = (struct hfi_bitrate *) &pkt->rg_property_data[1];
-		hfi->bit_rate = ((struct hal_bitrate *)pdata)->bit_rate;
-		pkt->size += sizeof(u32) * 2;
-		break;
-	}
-	case HAL_PARAM_PROFILE_LEVEL_CURRENT:
-	{
-		struct hfi_profile_level *hfi;
-		struct hal_profile_level *prop =
-			(struct hal_profile_level *) pdata;
-		pkt->rg_property_data[0] =
-			HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT;
-		hfi = (struct hfi_profile_level *)
-			&pkt->rg_property_data[1];
-		hfi->level = (u32) prop->level;
-		hfi->profile = prop->profile;
-		if (!hfi->profile)
-			hfi->profile = HFI_H264_PROFILE_HIGH;
-		if (!hfi->level)
-			hfi->level = 1;
-		pkt->size += sizeof(u32) + sizeof(struct hfi_profile_level);
-		break;
-	}
-	case HAL_PARAM_VENC_H264_ENTROPY_CONTROL:
-	{
-		struct hfi_h264_entropy_control *hfi;
-		struct hal_h264_entropy_control *prop =
-			(struct hal_h264_entropy_control *) pdata;
-		pkt->rg_property_data[0] =
-			HFI_PROPERTY_PARAM_VENC_H264_ENTROPY_CONTROL;
-		hfi = (struct hfi_h264_entropy_control *)
-			&pkt->rg_property_data[1];
-		switch (prop->entropy_mode) {
-		case HAL_H264_ENTROPY_CAVLC:
-			hfi->cabac_model = HFI_H264_ENTROPY_CAVLC;
-			break;
-		case HAL_H264_ENTROPY_CABAC:
-			hfi->cabac_model = HFI_H264_ENTROPY_CABAC;
-			switch (prop->cabac_model) {
-			case HAL_H264_CABAC_MODEL_0:
-				hfi->cabac_model = HFI_H264_CABAC_MODEL_0;
-				break;
-			case HAL_H264_CABAC_MODEL_1:
-				hfi->cabac_model = HFI_H264_CABAC_MODEL_1;
-				break;
-			case HAL_H264_CABAC_MODEL_2:
-				hfi->cabac_model = HFI_H264_CABAC_MODEL_2;
-				break;
-			default:
-				dprintk(VIDC_ERR,
-					"Invalid cabac model 0x%x",
-					prop->entropy_mode);
-				break;
-			}
-		break;
-		default:
-			dprintk(VIDC_ERR,
-				"Invalid entropy selected: 0x%x",
-				prop->cabac_model);
-			break;
-		}
-		pkt->size += sizeof(u32) + sizeof(
-			struct hfi_h264_entropy_control);
-		break;
-	}
-	case HAL_PARAM_VENC_RATE_CONTROL:
-	{
-		u32 *rc;
-		pkt->rg_property_data[0] =
-			HFI_PROPERTY_PARAM_VENC_RATE_CONTROL;
-		rc = (u32 *)pdata;
-		switch ((enum hal_rate_control) *rc) {
-		case HAL_RATE_CONTROL_OFF:
-		pkt->rg_property_data[1] = HFI_RATE_CONTROL_OFF;
-			break;
-		case HAL_RATE_CONTROL_CBR_CFR:
-		pkt->rg_property_data[1] = HFI_RATE_CONTROL_CBR_CFR;
-			break;
-		case HAL_RATE_CONTROL_CBR_VFR:
-		pkt->rg_property_data[1] = HFI_RATE_CONTROL_CBR_VFR;
-			break;
-		case HAL_RATE_CONTROL_VBR_CFR:
-		pkt->rg_property_data[1] = HFI_RATE_CONTROL_VBR_CFR;
-			break;
-		case HAL_RATE_CONTROL_VBR_VFR:
-		pkt->rg_property_data[1] = HFI_RATE_CONTROL_VBR_VFR;
-			break;
-		default:
-			dprintk(VIDC_ERR, "Invalid Rate control setting: 0x%x",
-						  (int) pdata);
-			break;
-		}
-		pkt->size += sizeof(u32) * 2;
-		break;
-	}
-	case HAL_PARAM_VENC_MPEG4_TIME_RESOLUTION:
-	{
-		struct hfi_mpeg4_time_resolution *hfi;
-		pkt->rg_property_data[0] =
-			HFI_PROPERTY_PARAM_VENC_MPEG4_TIME_RESOLUTION;
-		hfi = (struct hfi_mpeg4_time_resolution *)
-			&pkt->rg_property_data[1];
-		hfi->time_increment_resolution =
-			((struct hal_mpeg4_time_resolution *)pdata)->
-					time_increment_resolution;
-		pkt->size += sizeof(u32) * 2;
-		break;
-	}
-	case HAL_PARAM_VENC_MPEG4_HEADER_EXTENSION:
-	{
-		struct hfi_mpeg4_header_extension *hfi;
-		pkt->rg_property_data[0] =
-			HFI_PROPERTY_PARAM_VENC_MPEG4_HEADER_EXTENSION;
-		hfi = (struct hfi_mpeg4_header_extension *)
-			&pkt->rg_property_data[1];
-		hfi->header_extension = (u32) pdata;
-		pkt->size += sizeof(u32) * 2;
-		break;
-	}
-	case HAL_PARAM_VENC_H264_DEBLOCK_CONTROL:
-	{
-		struct hfi_h264_db_control *hfi;
-		struct hal_h264_db_control *prop =
-			(struct hal_h264_db_control *) pdata;
-		pkt->rg_property_data[0] =
-			HFI_PROPERTY_PARAM_VENC_H264_DEBLOCK_CONTROL;
-		hfi = (struct hfi_h264_db_control *) &pkt->rg_property_data[1];
-		switch (prop->mode) {
-		case HAL_H264_DB_MODE_DISABLE:
-			hfi->mode = HFI_H264_DB_MODE_DISABLE;
-			break;
-		case HAL_H264_DB_MODE_SKIP_SLICE_BOUNDARY:
-			hfi->mode = HFI_H264_DB_MODE_SKIP_SLICE_BOUNDARY;
-			break;
-		case HAL_H264_DB_MODE_ALL_BOUNDARY:
-			hfi->mode = HFI_H264_DB_MODE_ALL_BOUNDARY;
-			break;
-		default:
-			dprintk(VIDC_ERR, "Invalid deblocking mode: 0x%x",
-						  prop->mode);
-			break;
-		}
-		hfi->slice_alpha_offset = prop->slice_alpha_offset;
-		hfi->slice_beta_offset = prop->slice_beta_offset;
-		pkt->size += sizeof(u32) +
-			sizeof(struct hfi_h264_db_control);
-		break;
-	}
-	case HAL_PARAM_VENC_SESSION_QP:
-	{
-		struct hfi_quantization *hfi;
-		pkt->rg_property_data[0] =
-			HFI_PROPERTY_PARAM_VENC_SESSION_QP;
-		hfi = (struct hfi_quantization *) &pkt->rg_property_data[1];
-		memcpy(hfi, (struct hfi_quantization *) pdata,
-				sizeof(struct hfi_quantization));
-		pkt->size += sizeof(u32) + sizeof(struct hfi_quantization);
-		break;
-	}
-	case HAL_CONFIG_VENC_INTRA_PERIOD:
-	{
-		struct hfi_intra_period *hfi;
-		pkt->rg_property_data[0] =
-			HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD;
-		hfi = (struct hfi_intra_period *) &pkt->rg_property_data[1];
-		memcpy(hfi, (struct hfi_intra_period *) pdata,
-				sizeof(struct hfi_intra_period));
-		pkt->size += sizeof(u32) + sizeof(struct hfi_intra_period);
-		break;
-	}
-	case HAL_CONFIG_VENC_IDR_PERIOD:
-	{
-		struct hfi_idr_period *hfi;
-		pkt->rg_property_data[0] = HFI_PROPERTY_CONFIG_VENC_IDR_PERIOD;
-		hfi = (struct hfi_idr_period *) &pkt->rg_property_data[1];
-		hfi->idr_period = ((struct hfi_idr_period *) pdata)->idr_period;
-		pkt->size += sizeof(u32) * 2;
-		break;
-	}
-	case HAL_CONFIG_VPE_OPERATIONS:
-		break;
-	case HAL_PARAM_VENC_INTRA_REFRESH:
-	{
-		struct hfi_intra_refresh *hfi;
-		struct hal_intra_refresh *prop =
-			(struct hal_intra_refresh *) pdata;
-		pkt->rg_property_data[0] =
-			HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH;
-		hfi = (struct hfi_intra_refresh *) &pkt->rg_property_data[1];
-		switch (prop->mode) {
-		case HAL_INTRA_REFRESH_NONE:
-			hfi->mode = HFI_INTRA_REFRESH_NONE;
-			break;
-		case HAL_INTRA_REFRESH_ADAPTIVE:
-			hfi->mode = HFI_INTRA_REFRESH_ADAPTIVE;
-			break;
-		case HAL_INTRA_REFRESH_CYCLIC:
-			hfi->mode = HFI_INTRA_REFRESH_CYCLIC;
-			break;
-		case HAL_INTRA_REFRESH_CYCLIC_ADAPTIVE:
-			hfi->mode = HFI_INTRA_REFRESH_CYCLIC_ADAPTIVE;
-			break;
-		case HAL_INTRA_REFRESH_RANDOM:
-			hfi->mode = HFI_INTRA_REFRESH_RANDOM;
-			break;
-		default:
-			dprintk(VIDC_ERR, "Invalid intra refresh setting: 0x%x",
-				prop->mode);
-			break;
-		}
-		hfi->air_mbs = prop->air_mbs;
-		hfi->air_ref = prop->air_ref;
-		hfi->cir_mbs = prop->cir_mbs;
-		pkt->size += sizeof(u32) + sizeof(struct hfi_intra_refresh);
-		break;
-	}
-	case HAL_PARAM_VENC_MULTI_SLICE_CONTROL:
-	{
-		struct hfi_multi_slice_control *hfi;
-		struct hal_multi_slice_control *prop =
-			(struct hal_multi_slice_control *) pdata;
-		pkt->rg_property_data[0] =
-			HFI_PROPERTY_PARAM_VENC_MULTI_SLICE_CONTROL;
-		hfi = (struct hfi_multi_slice_control *)
-			&pkt->rg_property_data[1];
-		switch (prop->multi_slice) {
-		case HAL_MULTI_SLICE_OFF:
-			hfi->multi_slice = HFI_MULTI_SLICE_OFF;
-			break;
-		case HAL_MULTI_SLICE_GOB:
-			hfi->multi_slice = HFI_MULTI_SLICE_GOB;
-			break;
-		case HAL_MULTI_SLICE_BY_MB_COUNT:
-			hfi->multi_slice = HFI_MULTI_SLICE_BY_MB_COUNT;
-			break;
-		case HAL_MULTI_SLICE_BY_BYTE_COUNT:
-			hfi->multi_slice = HFI_MULTI_SLICE_BY_BYTE_COUNT;
-			break;
-		default:
-			dprintk(VIDC_ERR, "Invalid slice settings: 0x%x",
-				prop->multi_slice);
-			break;
-		}
-		hfi->slice_size = prop->slice_size;
-		pkt->size += sizeof(u32) + sizeof(struct
-					hfi_multi_slice_control);
-		break;
-	}
-	case HAL_PARAM_INDEX_EXTRADATA:
-	{
-		struct hfi_index_extradata_config *hfi;
-		struct hal_extradata_enable *extra = pdata;
-		int index = 0;
-		pkt->rg_property_data[0] =
-			get_hfi_extradata_index(extra->index);
-		hfi =
-			(struct hfi_index_extradata_config *)
-			&pkt->rg_property_data[1];
-		hfi->enable = extra->enable;
-		index = get_hfi_extradata_index(extra->index);
-		if (index)
-			hfi->index_extra_data_id = index;
-		else {
-			dprintk(VIDC_WARN,
-				"Failed to find extradata index: %d\n",
-				index);
-			rc = -EINVAL;
-		}
-		pkt->size += sizeof(u32) +
-			sizeof(struct hfi_index_extradata_config);
-		break;
-	}
-	case HAL_CONFIG_VPE_DEINTERLACE:
-		break;
-	/* FOLLOWING PROPERTIES ARE NOT IMPLEMENTED IN CORE YET */
-	case HAL_CONFIG_BUFFER_REQUIREMENTS:
-	case HAL_CONFIG_PRIORITY:
-	case HAL_CONFIG_BATCH_INFO:
-	case HAL_PARAM_METADATA_PASS_THROUGH:
-	case HAL_SYS_IDLE_INDICATOR:
-	case HAL_PARAM_UNCOMPRESSED_FORMAT_SUPPORTED:
-	case HAL_PARAM_INTERLACE_FORMAT_SUPPORTED:
-	case HAL_PARAM_CHROMA_SITE:
-	case HAL_PARAM_PROPERTIES_SUPPORTED:
-	case HAL_PARAM_PROFILE_LEVEL_SUPPORTED:
-	case HAL_PARAM_CAPABILITY_SUPPORTED:
-	case HAL_PARAM_NAL_STREAM_FORMAT_SUPPORTED:
-	case HAL_PARAM_MULTI_VIEW_FORMAT:
-	case HAL_PARAM_MAX_SEQUENCE_HEADER_SIZE:
-	case HAL_PARAM_CODEC_SUPPORTED:
-	case HAL_PARAM_VDEC_MULTI_VIEW_SELECT:
-	case HAL_PARAM_VDEC_MB_QUANTIZATION:
-	case HAL_PARAM_VDEC_NUM_CONCEALED_MB:
-	case HAL_PARAM_VDEC_H264_ENTROPY_SWITCHING:
-	case HAL_PARAM_VENC_SLICE_DELIVERY_MODE:
-	case HAL_PARAM_VENC_MPEG4_DATA_PARTITIONING:
-
-	case HAL_CONFIG_BUFFER_COUNT_ACTUAL:
-	case HAL_CONFIG_VDEC_MULTI_STREAM:
-	case HAL_PARAM_VENC_MULTI_SLICE_INFO:
-	case HAL_CONFIG_VENC_TIMESTAMP_SCALE:
-	case HAL_PARAM_VENC_LOW_LATENCY:
-	default:
-		dprintk(VIDC_INFO, "DEFAULT: Calling 0x%x", ptype);
-		break;
-	}
-	if (!rc)
-		rc = vidc_hal_iface_cmdq_write(session->device, pkt);
-
-	return rc;
-}
-
-int vidc_hal_session_get_property(void *sess,
-	enum hal_property ptype, void *pdata)
-{
-	struct hal_session *session;
-
-	if (!sess || !pdata) {
-		dprintk(VIDC_ERR, "Invalid Params in ");
-		return -EINVAL;
-	} else {
-		session = sess;
-	}
-	dprintk(VIDC_INFO, "IN func: , with property id: %d", ptype);
-
-	switch (ptype) {
-	case HAL_CONFIG_FRAME_RATE:
-		break;
-	case HAL_PARAM_UNCOMPRESSED_FORMAT_SELECT:
-		break;
-	case HAL_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO:
-		break;
-	case HAL_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO:
-		break;
-	case HAL_PARAM_EXTRA_DATA_HEADER_CONFIG:
-		break;
-	case HAL_PARAM_FRAME_SIZE:
-		break;
-	case HAL_CONFIG_REALTIME:
-		break;
-	case HAL_PARAM_BUFFER_COUNT_ACTUAL:
-		break;
-	case HAL_PARAM_NAL_STREAM_FORMAT_SELECT:
-		break;
-	case HAL_PARAM_VDEC_OUTPUT_ORDER:
-		break;
-	case HAL_PARAM_VDEC_PICTURE_TYPE_DECODE:
-		break;
-	case HAL_PARAM_VDEC_OUTPUT2_KEEP_ASPECT_RATIO:
-		break;
-	case HAL_CONFIG_VDEC_POST_LOOP_DEBLOCKER:
-		break;
-	case HAL_PARAM_VDEC_MULTI_STREAM:
-		break;
-	case HAL_PARAM_VDEC_DISPLAY_PICTURE_BUFFER_COUNT:
-		break;
-	case HAL_PARAM_DIVX_FORMAT:
-		break;
-	case HAL_CONFIG_VDEC_MB_ERROR_MAP_REPORTING:
-		break;
-	case HAL_PARAM_VDEC_CONTINUE_DATA_TRANSFER:
-		break;
-	case HAL_CONFIG_VDEC_MB_ERROR_MAP:
-		break;
-	case HAL_CONFIG_VENC_REQUEST_IFRAME:
-		break;
-	case HAL_PARAM_VENC_MPEG4_SHORT_HEADER:
-		break;
-	case HAL_PARAM_VENC_MPEG4_AC_PREDICTION:
-		break;
-	case HAL_CONFIG_VENC_TARGET_BITRATE:
-		break;
-	case HAL_PARAM_PROFILE_LEVEL_CURRENT:
-		break;
-	case HAL_PARAM_VENC_H264_ENTROPY_CONTROL:
-		break;
-	case HAL_PARAM_VENC_RATE_CONTROL:
-		break;
-	case HAL_PARAM_VENC_MPEG4_TIME_RESOLUTION:
-		break;
-	case HAL_PARAM_VENC_MPEG4_HEADER_EXTENSION:
-		break;
-	case HAL_PARAM_VENC_H264_DEBLOCK_CONTROL:
-		break;
-	case HAL_PARAM_VENC_SESSION_QP:
-		break;
-	case HAL_CONFIG_VENC_INTRA_PERIOD:
-		break;
-	case HAL_CONFIG_VENC_IDR_PERIOD:
-		break;
-	case HAL_CONFIG_VPE_OPERATIONS:
-		break;
-	case HAL_PARAM_VENC_INTRA_REFRESH:
-		break;
-	case HAL_PARAM_VENC_MULTI_SLICE_CONTROL:
-		break;
-	case HAL_CONFIG_VPE_DEINTERLACE:
-		break;
-	case HAL_SYS_DEBUG_CONFIG:
-		break;
-	/*FOLLOWING PROPERTIES ARE NOT IMPLEMENTED IN CORE YET*/
-	case HAL_CONFIG_BUFFER_REQUIREMENTS:
-	case HAL_CONFIG_PRIORITY:
-	case HAL_CONFIG_BATCH_INFO:
-	case HAL_PARAM_METADATA_PASS_THROUGH:
-	case HAL_SYS_IDLE_INDICATOR:
-	case HAL_PARAM_UNCOMPRESSED_FORMAT_SUPPORTED:
-	case HAL_PARAM_INTERLACE_FORMAT_SUPPORTED:
-	case HAL_PARAM_CHROMA_SITE:
-	case HAL_PARAM_PROPERTIES_SUPPORTED:
-	case HAL_PARAM_PROFILE_LEVEL_SUPPORTED:
-	case HAL_PARAM_CAPABILITY_SUPPORTED:
-	case HAL_PARAM_NAL_STREAM_FORMAT_SUPPORTED:
-	case HAL_PARAM_MULTI_VIEW_FORMAT:
-	case HAL_PARAM_MAX_SEQUENCE_HEADER_SIZE:
-	case HAL_PARAM_CODEC_SUPPORTED:
-	case HAL_PARAM_VDEC_MULTI_VIEW_SELECT:
-	case HAL_PARAM_VDEC_MB_QUANTIZATION:
-	case HAL_PARAM_VDEC_NUM_CONCEALED_MB:
-	case HAL_PARAM_VDEC_H264_ENTROPY_SWITCHING:
-	case HAL_PARAM_VENC_SLICE_DELIVERY_MODE:
-	case HAL_PARAM_VENC_MPEG4_DATA_PARTITIONING:
-
-	case HAL_CONFIG_BUFFER_COUNT_ACTUAL:
-	case HAL_CONFIG_VDEC_MULTI_STREAM:
-	case HAL_PARAM_VENC_MULTI_SLICE_INFO:
-	case HAL_CONFIG_VENC_TIMESTAMP_SCALE:
-	case HAL_PARAM_VENC_LOW_LATENCY:
-	default:
-		dprintk(VIDC_INFO, "DEFAULT: Calling 0x%x", ptype);
-		break;
-	}
-	return 0;
-}
-
-void *vidc_hal_session_init(void *device, u32 session_id,
-	enum hal_domain session_type, enum hal_video_codec codec_type)
-{
-	struct hfi_cmd_sys_session_init_packet pkt;
-	struct hal_session *new_session;
-	struct hal_device *dev;
-
-	if (device) {
-		dev = device;
-	} else {
-		dprintk(VIDC_ERR, "invalid device");
-		return NULL;
-	}
-
-	new_session = (struct hal_session *)
-		kzalloc(sizeof(struct hal_session), GFP_KERNEL);
-	new_session->session_id = (u32) session_id;
-	if (session_type == 1)
-		new_session->is_decoder = 0;
-	else if (session_type == 2)
-		new_session->is_decoder = 1;
-	new_session->device = dev;
-	list_add_tail(&new_session->list, &dev->sess_head);
-	pkt.size = sizeof(struct hfi_cmd_sys_session_init_packet);
-	pkt.packet_type = HFI_CMD_SYS_SESSION_INIT;
-	pkt.session_id = (u32) new_session;
-	pkt.session_domain = session_type;
-	pkt.session_codec = codec_type;
-	if (vidc_hal_iface_cmdq_write(dev, &pkt))
-		return NULL;
-	if (vidc_hal_sys_set_debug(dev, msm_fw_debug))
-		dprintk(VIDC_ERR, "Setting fw_debug msg ON failed");
-	return (void *) new_session;
-}
-
-static int vidc_hal_send_session_cmd(void *session_id,
-	 int pkt_type)
-{
-	struct vidc_hal_session_cmd_pkt pkt;
-	int rc = 0;
-	struct hal_session *session;
-
-	if (session_id) {
-		session = session_id;
-	} else {
-		dprintk(VIDC_ERR, "invalid session");
-		return -ENODEV;
-	}
-
-	pkt.size = sizeof(struct vidc_hal_session_cmd_pkt);
-	pkt.packet_type = pkt_type;
-	pkt.session_id = (u32) session;
-
-	if (vidc_hal_iface_cmdq_write(session->device, &pkt))
-		rc = -ENOTEMPTY;
-	return rc;
-}
-
-int vidc_hal_session_end(void *session)
-{
-	return vidc_hal_send_session_cmd(session,
-		HFI_CMD_SYS_SESSION_END);
-}
-
-int vidc_hal_session_abort(void *session)
-{
-	return vidc_hal_send_session_cmd(session,
-		HFI_CMD_SYS_SESSION_ABORT);
-}
-
-int vidc_hal_session_set_buffers(void *sess,
-	struct vidc_buffer_addr_info *buffer_info)
-{
-	u32 buffer;
-	struct hfi_cmd_session_set_buffers_packet *pkt;
-	u8 packet[VIDC_IFACEQ_VAR_LARGE_PKT_SIZE];
-	int rc = 0;
-	u16 i;
-	struct hal_session *session;
-
-	if (!sess || !buffer_info) {
-		dprintk(VIDC_ERR, "Invalid Params");
-		return -EINVAL;
-	} else {
-		session = sess;
-	}
-
-	if (buffer_info->buffer_type == HAL_BUFFER_INPUT)
-		return 0;
-
-	pkt = (struct hfi_cmd_session_set_buffers_packet *)packet;
-
-	pkt->size = sizeof(struct hfi_cmd_session_set_buffers_packet) +
-		((buffer_info->num_buffers - 1) * sizeof(u32));
-	pkt->packet_type = HFI_CMD_SESSION_SET_BUFFERS;
-	pkt->session_id = (u32) session;
-	pkt->buffer_size = buffer_info->buffer_size;
-	pkt->min_buffer_size = buffer_info->buffer_size;
-	pkt->num_buffers = buffer_info->num_buffers;
-
-	if ((buffer_info->buffer_type == HAL_BUFFER_OUTPUT) ||
-		(buffer_info->buffer_type == HAL_BUFFER_OUTPUT2)) {
-		struct hfi_buffer_info *buff;
-		pkt->extra_data_size = buffer_info->extradata_size;
-		pkt->size = sizeof(struct hfi_cmd_session_set_buffers_packet) -
-			sizeof(u32) + ((buffer_info->num_buffers) *
-			sizeof(struct hfi_buffer_info));
-		buff = (struct hfi_buffer_info *) pkt->rg_buffer_info;
-		for (i = 0; i < pkt->num_buffers; i++) {
-			buff->buffer_addr =
-				buffer_info->align_device_addr;
-			buff->extra_data_addr =
-				buffer_info->extradata_addr;
-		}
-	} else {
-		pkt->extra_data_size = 0;
-		pkt->size = sizeof(struct hfi_cmd_session_set_buffers_packet) +
-			((buffer_info->num_buffers - 1) * sizeof(u32));
-		for (i = 0; i < pkt->num_buffers; i++)
-			pkt->rg_buffer_info[i] =
-			buffer_info->align_device_addr;
-	}
-	buffer = get_hfi_buffer(buffer_info->buffer_type);
-	if (buffer)
-		pkt->buffer_type = buffer;
-	else
-		return -EINVAL;
-	dprintk(VIDC_INFO, "set buffers: 0x%x", buffer_info->buffer_type);
-	if (vidc_hal_iface_cmdq_write(session->device, pkt))
-		rc = -ENOTEMPTY;
-	return rc;
-}
-
-int vidc_hal_session_release_buffers(void *sess,
-	struct vidc_buffer_addr_info *buffer_info)
-{
-	u32 buffer;
-	struct hfi_cmd_session_release_buffer_packet *pkt;
-	u8 packet[VIDC_IFACEQ_VAR_LARGE_PKT_SIZE];
-	int rc = 0;
-	u32 i;
-	struct hal_session *session;
-
-	if (!sess || !buffer_info) {
-		dprintk(VIDC_ERR, "Invalid Params");
-		return -EINVAL;
-	} else {
-		session = sess;
-	}
-
-	if (buffer_info->buffer_type == HAL_BUFFER_INPUT)
-		return 0;
-
-	pkt = (struct hfi_cmd_session_release_buffer_packet *) packet;
-	pkt->size = sizeof(struct hfi_cmd_session_release_buffer_packet) +
-		((buffer_info->num_buffers - 1) * sizeof(u32));
-	pkt->packet_type = HFI_CMD_SESSION_RELEASE_BUFFERS;
-	pkt->session_id = (u32) session;
-	pkt->buffer_size = buffer_info->buffer_size;
-	pkt->num_buffers = buffer_info->num_buffers;
-
-	if ((buffer_info->buffer_type == HAL_BUFFER_OUTPUT) ||
-		(buffer_info->buffer_type == HAL_BUFFER_OUTPUT2)) {
-		struct hfi_buffer_info *buff;
-		buff = (struct hfi_buffer_info *) pkt->rg_buffer_info;
-		for (i = 0; i < pkt->num_buffers; i++) {
-			buff->buffer_addr =
-				buffer_info->align_device_addr;
-			buff->extra_data_addr =
-				buffer_info->extradata_addr;
-		}
-		pkt->extra_data_size = buffer_info->extradata_size;
-		pkt->size = sizeof(struct hfi_cmd_session_set_buffers_packet) -
-			sizeof(u32) + ((buffer_info->num_buffers) *
-			sizeof(struct hfi_buffer_info));
-	} else {
-		for (i = 0; i < pkt->num_buffers; i++)
-			pkt->rg_buffer_info[i] =
-			buffer_info->align_device_addr;
-		pkt->extra_data_size = 0;
-		pkt->size = sizeof(struct hfi_cmd_session_set_buffers_packet) +
-			((buffer_info->num_buffers - 1) * sizeof(u32));
-	}
-	pkt->response_req = buffer_info->response_required;
-	buffer = get_hfi_buffer(buffer_info->buffer_type);
-	if (buffer)
-		pkt->buffer_type = buffer;
-	else
-		return -EINVAL;
-	dprintk(VIDC_INFO, "Release buffers: 0x%x", buffer_info->buffer_type);
-	if (vidc_hal_iface_cmdq_write(session->device, pkt))
-		rc = -ENOTEMPTY;
-	return rc;
-}
-
-int vidc_hal_session_load_res(void *sess)
-{
-	return vidc_hal_send_session_cmd(sess,
-		HFI_CMD_SESSION_LOAD_RESOURCES);
-}
-
-int vidc_hal_session_release_res(void *sess)
-{
-	return vidc_hal_send_session_cmd(sess,
-		HFI_CMD_SESSION_RELEASE_RESOURCES);
-}
-
-int vidc_hal_session_start(void *sess)
-{
-	return vidc_hal_send_session_cmd(sess,
-		HFI_CMD_SESSION_START);
-}
-
-int vidc_hal_session_stop(void *sess)
-{
-	return vidc_hal_send_session_cmd(sess,
-		HFI_CMD_SESSION_STOP);
-}
-
-int vidc_hal_session_suspend(void *sess)
-{
-	return vidc_hal_send_session_cmd(sess,
-		HFI_CMD_SESSION_SUSPEND);
-}
-
-int vidc_hal_session_resume(void *sess)
-{
-	return vidc_hal_send_session_cmd(sess,
-		HFI_CMD_SESSION_RESUME);
-}
-
-int vidc_hal_session_etb(void *sess, struct vidc_frame_data *input_frame)
-{
-	int rc = 0;
-	struct hal_session *session;
-
-	if (!sess || !input_frame) {
-		dprintk(VIDC_ERR, "Invalid Params");
-		return -EINVAL;
-	} else {
-		session = sess;
-	}
-
-	if (session->is_decoder) {
-		struct hfi_cmd_session_empty_buffer_compressed_packet pkt;
-		pkt.size = sizeof(
-			struct hfi_cmd_session_empty_buffer_compressed_packet);
-		pkt.packet_type = HFI_CMD_SESSION_EMPTY_BUFFER;
-		pkt.session_id = (u32) session;
-		pkt.time_stamp_hi = (int) (((u64)input_frame->timestamp) >> 32);
-		pkt.time_stamp_lo = (int) input_frame->timestamp;
-		pkt.flags = input_frame->flags;
-		pkt.mark_target = input_frame->mark_target;
-		pkt.mark_data = input_frame->mark_data;
-		pkt.offset = input_frame->offset;
-		pkt.alloc_len = input_frame->alloc_len;
-		pkt.filled_len = input_frame->filled_len;
-		pkt.input_tag = input_frame->clnt_data;
-		pkt.packet_buffer = (u8 *) input_frame->device_addr;
-		dprintk(VIDC_DBG, "Q DECODER INPUT BUFFER");
-		if (vidc_hal_iface_cmdq_write(session->device, &pkt))
-			rc = -ENOTEMPTY;
-	} else {
-		struct hfi_cmd_session_empty_buffer_uncompressed_plane0_packet
-			pkt;
-		pkt.size = sizeof(struct
-		hfi_cmd_session_empty_buffer_uncompressed_plane0_packet);
-		pkt.packet_type = HFI_CMD_SESSION_EMPTY_BUFFER;
-		pkt.session_id = (u32) session;
-		pkt.view_id = 0;
-		pkt.time_stamp_hi = (u32) (((u64)input_frame->timestamp) >> 32);
-		pkt.time_stamp_lo = (u32) input_frame->timestamp;
-		pkt.flags = input_frame->flags;
-		pkt.mark_target = input_frame->mark_target;
-		pkt.mark_data = input_frame->mark_data;
-		pkt.offset = input_frame->offset;
-		pkt.alloc_len = input_frame->alloc_len;
-		pkt.filled_len = input_frame->filled_len;
-		pkt.input_tag = input_frame->clnt_data;
-		pkt.packet_buffer = (u8 *) input_frame->device_addr;
-		dprintk(VIDC_DBG, "Q ENCODER INPUT BUFFER");
-		if (vidc_hal_iface_cmdq_write(session->device, &pkt))
-			rc = -ENOTEMPTY;
-	}
-	return rc;
-}
-
-int vidc_hal_session_ftb(void *sess,
-	struct vidc_frame_data *output_frame)
-{
-	struct hfi_cmd_session_fill_buffer_packet pkt;
-	int rc = 0;
-	struct hal_session *session;
-
-	if (!sess || !output_frame) {
-		dprintk(VIDC_ERR, "Invalid Params");
-		return -EINVAL;
-	} else {
-		session = sess;
-	}
-
-	pkt.size = sizeof(struct hfi_cmd_session_fill_buffer_packet);
-	pkt.packet_type = HFI_CMD_SESSION_FILL_BUFFER;
-	pkt.session_id = (u32) session;
-	if (output_frame->buffer_type == HAL_BUFFER_OUTPUT)
-		pkt.stream_id = 0;
-	else if (output_frame->buffer_type == HAL_BUFFER_OUTPUT2)
-		pkt.stream_id = 1;
-	pkt.packet_buffer = (u8 *) output_frame->device_addr;
-	pkt.extra_data_buffer =
-		(u8 *) output_frame->extradata_addr;
-	pkt.alloc_len = output_frame->alloc_len;
-	pkt.filled_len = output_frame->filled_len;
-	pkt.offset = output_frame->offset;
-	dprintk(VIDC_DBG, "### Q OUTPUT BUFFER ###: %d, %d, %d\n",
-			pkt.alloc_len, pkt.filled_len, pkt.offset);
-	if (vidc_hal_iface_cmdq_write(session->device, &pkt))
-		rc = -ENOTEMPTY;
-	return rc;
-}
-
-int vidc_hal_session_parse_seq_hdr(void *sess,
-	struct vidc_seq_hdr *seq_hdr)
-{
-	struct hfi_cmd_session_parse_sequence_header_packet *pkt;
-	int rc = 0;
-	u8 packet[VIDC_IFACEQ_VAR_SMALL_PKT_SIZE];
-	struct hal_session *session;
-
-	if (!sess || !seq_hdr) {
-		dprintk(VIDC_ERR, "Invalid Params");
-		return -EINVAL;
-	} else {
-		session = sess;
-	}
-
-	pkt = (struct hfi_cmd_session_parse_sequence_header_packet *) packet;
-	pkt->size = sizeof(struct hfi_cmd_session_parse_sequence_header_packet);
-	pkt->packet_type = HFI_CMD_SESSION_PARSE_SEQUENCE_HEADER;
-	pkt->session_id = (u32) session;
-	pkt->header_len = seq_hdr->seq_hdr_len;
-	pkt->packet_buffer = seq_hdr->seq_hdr;
-
-	if (vidc_hal_iface_cmdq_write(session->device, pkt))
-		rc = -ENOTEMPTY;
-	return rc;
-}
-
-int vidc_hal_session_get_seq_hdr(void *sess,
-	struct vidc_seq_hdr *seq_hdr)
-{
-	struct hfi_cmd_session_get_sequence_header_packet *pkt;
-	int rc = 0;
-	u8 packet[VIDC_IFACEQ_VAR_SMALL_PKT_SIZE];
-	struct hal_session *session;
-
-	if (!sess || !seq_hdr) {
-		dprintk(VIDC_ERR, "Invalid Params");
-		return -EINVAL;
-	} else {
-		session = sess;
-	}
-
-	pkt = (struct hfi_cmd_session_get_sequence_header_packet *) packet;
-	pkt->size = sizeof(struct hfi_cmd_session_get_sequence_header_packet);
-	pkt->packet_type = HFI_CMD_SESSION_GET_SEQUENCE_HEADER;
-	pkt->session_id = (u32) session;
-	pkt->buffer_len = seq_hdr->seq_hdr_len;
-	pkt->packet_buffer = seq_hdr->seq_hdr;
-
-	if (vidc_hal_iface_cmdq_write(session->device, pkt))
-		rc = -ENOTEMPTY;
-	return rc;
-}
-
-int vidc_hal_session_get_buf_req(void *sess)
-{
-	struct hfi_cmd_session_get_property_packet pkt;
-	int rc = 0;
-	struct hal_session *session;
-
-	if (sess) {
-		session = sess;
-	} else {
-		dprintk(VIDC_ERR, "invalid session");
-		return -ENODEV;
-	}
-
-	pkt.size = sizeof(struct hfi_cmd_session_get_property_packet);
-	pkt.packet_type = HFI_CMD_SESSION_GET_PROPERTY;
-	pkt.session_id = (u32) session;
-	pkt.num_properties = 1;
-	pkt.rg_property_data[0] = HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS;
-	if (vidc_hal_iface_cmdq_write(session->device, &pkt))
-		rc = -ENOTEMPTY;
-	return rc;
-}
-
-int vidc_hal_session_flush(void *sess, enum hal_flush flush_mode)
-{
-	struct hfi_cmd_session_flush_packet pkt;
-	int rc = 0;
-	struct hal_session *session;
-
-	if (sess) {
-		session = sess;
-	} else {
-		dprintk(VIDC_ERR, "invalid session");
-		return -ENODEV;
-	}
-
-	pkt.size = sizeof(struct hfi_cmd_session_flush_packet);
-	pkt.packet_type = HFI_CMD_SESSION_FLUSH;
-	pkt.session_id = (u32) session;
-	switch (flush_mode) {
-	case HAL_FLUSH_INPUT:
-		pkt.flush_type = HFI_FLUSH_INPUT;
-		break;
-	case HAL_FLUSH_OUTPUT:
-		pkt.flush_type = HFI_FLUSH_OUTPUT;
-		break;
-	case HAL_FLUSH_OUTPUT2:
-		pkt.flush_type = HFI_FLUSH_OUTPUT2;
-		break;
-	case HAL_FLUSH_ALL:
-		pkt.flush_type = HFI_FLUSH_ALL;
-		break;
-	default:
-		dprintk(VIDC_ERR, "Invalid flush mode: 0x%x\n", flush_mode);
-		break;
-	}
-	if (vidc_hal_iface_cmdq_write(session->device, &pkt))
-		rc = -ENOTEMPTY;
-	return rc;
-}
-
-static int vidc_hal_check_core_registered(
-	struct hal_device_data core, u32 fw_addr,
-	u32 reg_addr, u32 reg_size, u32 irq)
-{
-	struct hal_device *device;
-	struct list_head *curr, *next;
-
-	if (core.dev_count) {
-		list_for_each_safe(curr, next, &core.dev_head) {
-			device = list_entry(curr, struct hal_device, list);
-			if (device && device->hal_data->irq == irq &&
-				(CONTAINS(device->hal_data->
-						device_base_addr,
-						FIRMWARE_SIZE, fw_addr) ||
-				CONTAINS(fw_addr, FIRMWARE_SIZE,
-						device->hal_data->
-						device_base_addr) ||
-				CONTAINS((u32)device->hal_data->
-						register_base_addr,
-						reg_size, reg_addr) ||
-				CONTAINS(reg_addr, reg_size,
-						(u32)device->hal_data->
-						register_base_addr) ||
-				OVERLAPS((u32)device->hal_data->
-						register_base_addr,
-						reg_size, reg_addr, reg_size) ||
-				OVERLAPS(reg_addr, reg_size,
-						(u32)device->hal_data->
-						register_base_addr, reg_size) ||
-				OVERLAPS(device->hal_data->
-						device_base_addr,
-						FIRMWARE_SIZE, fw_addr,
-						FIRMWARE_SIZE) ||
-				OVERLAPS(fw_addr, FIRMWARE_SIZE,
-						device->hal_data->
-						device_base_addr,
-						FIRMWARE_SIZE))) {
-				return 0;
-			} else {
-				dprintk(VIDC_INFO, "Device not registered");
-				return -EINVAL;
-			}
-		}
-	} else {
-		dprintk(VIDC_INFO, "no device Registered");
-	}
-	return -EINVAL;
-}
-
-static void vidc_hal_core_work_handler(struct work_struct *work)
-{
-	struct hal_device *device = list_first_entry(
-		&hal_ctxt.dev_head, struct hal_device, list);
-
-	dprintk(VIDC_INFO, " GOT INTERRUPT () ");
-	if (!device->callback) {
-		dprintk(VIDC_ERR, "No interrupt callback function: %p\n",
-				device);
-		return;
-	}
-	vidc_hal_core_clear_interrupt(device);
-	vidc_hal_response_handler(device);
-	enable_irq(device->hal_data->irq);
-}
-static DECLARE_WORK(vidc_hal_work, vidc_hal_core_work_handler);
-
-static irqreturn_t vidc_hal_isr(int irq, void *dev)
-{
-	struct hal_device *device = dev;
-	dprintk(VIDC_INFO, "vidc_hal_isr() %d ", irq);
-	disable_irq_nosync(irq);
-	queue_work(device->vidc_workq, &vidc_hal_work);
-	dprintk(VIDC_INFO, "vidc_hal_isr() %d ", irq);
-	return IRQ_HANDLED;
-}
-
-void *vidc_hal_add_device(u32 device_id, u32 fw_base_addr, u32 reg_base,
-		u32 reg_size, u32 irq,
-		void (*callback) (enum command_response cmd, void *data))
-{
-	struct hal_device *hdevice = NULL;
-	struct hal_data *hal = NULL;
-	int rc = 0;
-
-	if (device_id || !reg_base || !reg_size ||
-			!irq || !callback) {
-		dprintk(VIDC_ERR, "Invalid Paramters");
-		return NULL;
-	} else {
-		dprintk(VIDC_INFO, "entered , device_id: %d", device_id);
-	}
-
-	if (vidc_hal_check_core_registered(hal_ctxt, fw_base_addr,
-						reg_base, reg_size, irq)) {
-		dprintk(VIDC_DBG, "HAL_DATA will be assigned now");
-		hal = (struct hal_data *)
-			kzalloc(sizeof(struct hal_data), GFP_KERNEL);
-		if (!hal) {
-			dprintk(VIDC_ERR, "Failed to alloc");
-			return NULL;
-		}
-		hal->irq = irq;
-		hal->device_base_addr = fw_base_addr;
-		hal->register_base_addr =
-			ioremap_nocache(reg_base, reg_size);
-		if (!hal->register_base_addr) {
-			dprintk(VIDC_ERR,
-				"could not map reg addr %d of size %d",
-				reg_base, reg_size);
-			goto err_map;
-		}
-		INIT_LIST_HEAD(&hal_ctxt.dev_head);
-	} else {
-		dprintk(VIDC_ERR, "Core present/Already added");
-		return NULL;
-	}
-
-	hdevice = (struct hal_device *)
-			kzalloc(sizeof(struct hal_device), GFP_KERNEL);
-	if (!hdevice) {
-		dprintk(VIDC_ERR, "failed to allocate new device");
-		goto err_map;
-	}
-
-	INIT_LIST_HEAD(&hdevice->list);
-	list_add_tail(&hdevice->list, &hal_ctxt.dev_head);
-	hal_ctxt.dev_count++;
-	hdevice->device_id = device_id;
-	hdevice->hal_data = hal;
-	hdevice->callback = callback;
-
-	hdevice->vidc_workq = create_singlethread_workqueue(
-		"msm_vidc_workerq");
-	if (!hdevice->vidc_workq) {
-		dprintk(VIDC_ERR, ": create workq failed\n");
-		goto error_createq;
-	}
-
-	rc = request_irq(irq, vidc_hal_isr, IRQF_TRIGGER_HIGH,
-			"msm_vidc", hdevice);
-	if (unlikely(rc)) {
-		dprintk(VIDC_ERR, "() :request_irq failed\n");
-		goto error_irq_fail;
-	}
-	disable_irq_nosync(irq);
-	return (void *) hdevice;
-error_irq_fail:
-	destroy_workqueue(hdevice->vidc_workq);
-error_createq:
-	hal_ctxt.dev_count--;
-	list_del(&hal_ctxt.dev_head);
-err_map:
-	kfree(hal);
-	return NULL;
-}
-
-void vidc_hal_delete_device(void *device)
-{
-	struct hal_device *close, *dev;
-
-	if (device) {
-		dev = (struct hal_device *) device;
-		list_for_each_entry(close, &hal_ctxt.dev_head, list) {
-			if (close->hal_data->irq == dev->hal_data->irq) {
-				hal_ctxt.dev_count--;
-				free_irq(dev->hal_data->irq, close);
-				list_del(&close->list);
-				destroy_workqueue(close->vidc_workq);
-				kfree(close->hal_data);
-				kfree(close);
-				break;
-			}
-		}
-
-	}
-}
diff --git a/drivers/media/video/msm_vidc/vidc_hal.h b/drivers/media/video/msm_vidc/vidc_hal.h
deleted file mode 100644
index c8a7d43..0000000
--- a/drivers/media/video/msm_vidc/vidc_hal.h
+++ /dev/null
@@ -1,950 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 __H_VIDC_HAL_H__
-#define __H_VIDC_HAL_H__
-
-#include <linux/spinlock.h>
-#include <linux/mutex.h>
-#include "vidc_hal_api.h"
-#include "msm_smem.h"
-#include "vidc_hal_helper.h"
-
-#define HFI_MASK_QHDR_TX_TYPE			0xFF000000
-#define HFI_MASK_QHDR_RX_TYPE			0x00FF0000
-#define HFI_MASK_QHDR_PRI_TYPE			0x0000FF00
-#define HFI_MASK_QHDR_Q_ID_TYPE			0x000000FF
-#define HFI_Q_ID_HOST_TO_CTRL_CMD_Q		0x00
-#define HFI_Q_ID_CTRL_TO_HOST_MSG_Q		0x01
-#define HFI_Q_ID_CTRL_TO_HOST_DEBUG_Q	0x02
-#define HFI_MASK_QHDR_STATUS			0x000000FF
-
-#define VIDC_MAX_UNCOMPRESSED_FMT_PLANES	3
-
-#define VIDC_IFACEQ_NUMQ					3
-#define VIDC_IFACEQ_CMDQ_IDX				0
-#define VIDC_IFACEQ_MSGQ_IDX				1
-#define VIDC_IFACEQ_DBGQ_IDX				2
-
-#define VIDC_IFACEQ_MAX_PKT_SIZE			1024
-#define VIDC_IFACEQ_MED_PKT_SIZE			768
-#define VIDC_IFACEQ_MIN_PKT_SIZE			8
-#define VIDC_IFACEQ_VAR_SMALL_PKT_SIZE		100
-#define VIDC_IFACEQ_VAR_LARGE_PKT_SIZE		512
-#define VIDC_IFACEQ_MAX_BUF_COUNT			50
-#define VIDC_IFACE_MAX_PARALLEL_CLNTS		16
-#define VIDC_IFACEQ_DFLT_QHDR				0x01010000
-
-struct hfi_queue_table_header {
-	u32 qtbl_version;
-	u32 qtbl_size;
-	u32 qtbl_qhdr0_offset;
-	u32 qtbl_qhdr_size;
-	u32 qtbl_num_q;
-	u32 qtbl_num_active_q;
-};
-
-struct hfi_queue_header {
-	u32 qhdr_status;
-	u32 qhdr_start_addr;
-	u32 qhdr_type;
-	u32 qhdr_q_size;
-	u32 qhdr_pkt_size;
-	u32 qhdr_pkt_drop_cnt;
-	u32 qhdr_rx_wm;
-	u32 qhdr_tx_wm;
-	u32 qhdr_rx_req;
-	u32 qhdr_tx_req;
-	u32 qhdr_rx_irq_status;
-	u32 qhdr_tx_irq_status;
-	u32 qhdr_read_idx;
-	u32 qhdr_write_idx;
-};
-
-#define VIDC_IFACEQ_TABLE_SIZE (sizeof(struct hfi_queue_table_header) \
-	+ sizeof(struct hfi_queue_header) * VIDC_IFACEQ_NUMQ)
-
-#define VIDC_IFACEQ_QUEUE_SIZE	(VIDC_IFACEQ_MAX_PKT_SIZE *  \
-	VIDC_IFACEQ_MAX_BUF_COUNT * VIDC_IFACE_MAX_PARALLEL_CLNTS)
-
-#define VIDC_IFACEQ_GET_QHDR_START_ADDR(ptr, i)     \
-	(void *)((((u32)ptr) + sizeof(struct hfi_queue_table_header)) + \
-		(i * sizeof(struct hfi_queue_header)))
-
-#define QDSS_SIZE 4096
-#define SFR_SIZE 4096
-
-#define UC_SIZE (VIDC_IFACEQ_TABLE_SIZE + \
-	(VIDC_IFACEQ_QUEUE_SIZE * VIDC_IFACEQ_NUMQ) + QDSS_SIZE + SFR_SIZE)
-
-enum vidc_hw_reg {
-	VIDC_HWREG_CTRL_STATUS =  0x1,
-	VIDC_HWREG_QTBL_INFO =  0x2,
-	VIDC_HWREG_QTBL_ADDR =  0x3,
-	VIDC_HWREG_CTRLR_RESET =  0x4,
-	VIDC_HWREG_IFACEQ_FWRXREQ =  0x5,
-	VIDC_HWREG_IFACEQ_FWTXREQ =  0x6,
-	VIDC_HWREG_VHI_SOFTINTEN =  0x7,
-	VIDC_HWREG_VHI_SOFTINTSTATUS =  0x8,
-	VIDC_HWREG_VHI_SOFTINTCLR =  0x9,
-	VIDC_HWREG_HVI_SOFTINTEN =  0xA,
-};
-
-#define HFI_EVENT_SESSION_SEQUENCE_CHANGED (HFI_OX_BASE + 0x3)
-#define HFI_EVENT_SESSION_PROPERTY_CHANGED (HFI_OX_BASE + 0x4)
-
-#define HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUFFER_RESOURCES	\
-	(HFI_OX_BASE + 0x1)
-#define HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUFFER_RESOURCES	\
-	(HFI_OX_BASE + 0x2)
-
-#define HFI_BUFFERFLAG_EOS				0x00000001
-#define HFI_BUFFERFLAG_STARTTIME		0x00000002
-#define HFI_BUFFERFLAG_DECODEONLY		0x00000004
-#define HFI_BUFFERFLAG_DATACORRUPT		0x00000008
-#define HFI_BUFFERFLAG_ENDOFFRAME		0x00000010
-#define HFI_BUFFERFLAG_SYNCFRAME		0x00000020
-#define HFI_BUFFERFLAG_EXTRADATA		0x00000040
-#define HFI_BUFFERFLAG_CODECCONFIG		0x00000080
-#define HFI_BUFFERFLAG_TIMESTAMPINVALID	0x00000100
-#define HFI_BUFFERFLAG_READONLY			0x00000200
-#define HFI_BUFFERFLAG_ENDOFSUBFRAME	0x00000400
-#define HFI_BUFFERFLAG_EOSEQ			0x00200000
-#define HFI_BUFFERFLAG_DISCONTINUITY	0x80000000
-#define HFI_BUFFERFLAG_TEI				0x40000000
-
-#define HFI_ERR_SESSION_EMPTY_BUFFER_DONE_OUTPUT_PENDING	\
-	(HFI_OX_BASE + 0x1001)
-#define HFI_ERR_SESSION_SAME_STATE_OPERATION		\
-	(HFI_OX_BASE + 0x1002)
-#define HFI_ERR_SESSION_SYNC_FRAME_NOT_DETECTED		\
-	(HFI_OX_BASE + 0x1003)
-#define  HFI_ERR_SESSION_START_CODE_NOT_FOUND		\
-	(HFI_OX_BASE + 0x1004)
-
-#define HFI_BUFFER_INTERNAL_SCRATCH (HFI_OX_BASE + 0x1)
-#define HFI_BUFFER_EXTRADATA_INPUT (HFI_OX_BASE + 0x2)
-#define HFI_BUFFER_EXTRADATA_OUTPUT (HFI_OX_BASE + 0x3)
-#define HFI_BUFFER_EXTRADATA_OUTPUT2 (HFI_OX_BASE + 0x4)
-
-#define HFI_BUFFER_MODE_STATIC (HFI_OX_BASE + 0x1)
-#define HFI_BUFFER_MODE_RING (HFI_OX_BASE + 0x2)
-
-struct hfi_buffer_alloc_mode {
-	u32 buffer_type;
-	u32 buffer_mode;
-};
-
-#define HFI_FLUSH_INPUT (HFI_OX_BASE + 0x1)
-#define HFI_FLUSH_OUTPUT (HFI_OX_BASE + 0x2)
-#define HFI_FLUSH_OUTPUT2 (HFI_OX_BASE + 0x3)
-#define HFI_FLUSH_ALL (HFI_OX_BASE + 0x4)
-
-#define HFI_EXTRADATA_NONE					0x00000000
-#define HFI_EXTRADATA_MB_QUANTIZATION		0x00000001
-#define HFI_EXTRADATA_INTERLACE_VIDEO		0x00000002
-#define HFI_EXTRADATA_VC1_FRAMEDISP			0x00000003
-#define HFI_EXTRADATA_VC1_SEQDISP			0x00000004
-#define HFI_EXTRADATA_TIMESTAMP				0x00000005
-#define HFI_EXTRADATA_S3D_FRAME_PACKING		0x00000006
-#define HFI_EXTRADATA_FRAME_RATE			0x00000007
-#define HFI_EXTRADATA_PANSCAN_WINDOW		0x00000008
-#define HFI_EXTRADATA_RECOVERY_POINT_SEI	0x00000009
-#define HFI_EXTRADATA_CLOSED_CAPTION_UD		0x0000000A
-#define HFI_EXTRADATA_AFD_UD				0x0000000B
-#define HFI_EXTRADATA_MULTISLICE_INFO		0x7F100000
-#define HFI_EXTRADATA_NUM_CONCEALED_MB		0x7F100001
-#define HFI_EXTRADATA_INDEX					0x7F100002
-#define HFI_EXTRADATA_METADATA_FILLER		0x7FE00002
-
-#define HFI_INDEX_EXTRADATA_INPUT_CROP		0x0700000E
-#define HFI_INDEX_EXTRADATA_DIGITAL_ZOOM	0x07000010
-#define HFI_INDEX_EXTRADATA_ASPECT_RATIO	0x7F100003
-
-struct hfi_index_extradata_config {
-	int enable;
-	u32 index_extra_data_id;
-};
-
-struct hfi_extradata_header {
-	u32 size;
-	u32 version;
-	u32 port_index;
-	u32 type;
-	u32 data_size;
-	u8 rg_data[1];
-};
-
-#define HFI_INTERLACE_FRAME_PROGRESSIVE					0x01
-#define HFI_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST	0x02
-#define HFI_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST	0x04
-#define HFI_INTERLACE_FRAME_TOPFIELDFIRST				0x08
-#define HFI_INTERLACE_FRAME_BOTTOMFIELDFIRST			0x10
-
-#define HFI_PROPERTY_SYS_OX_START			\
-	(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + 0x0000)
-#define HFI_PROPERTY_SYS_IDLE_INDICATOR		\
-	(HFI_PROPERTY_SYS_OX_START + 0x001)
-
-#define HFI_PROPERTY_PARAM_OX_START				\
-	(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + 0x1000)
-#define HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL			\
-	(HFI_PROPERTY_PARAM_OX_START + 0x001)
-#define HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO	\
-	(HFI_PROPERTY_PARAM_OX_START + 0x002)
-#define HFI_PROPERTY_PARAM_INTERLACE_FORMAT_SUPPORTED	\
-	(HFI_PROPERTY_PARAM_OX_START + 0x003)
-#define HFI_PROPERTY_PARAM_CHROMA_SITE					\
-(HFI_PROPERTY_PARAM_OX_START + 0x004)
-#define HFI_PROPERTY_PARAM_EXTRA_DATA_HEADER_CONFIG		\
-	(HFI_PROPERTY_PARAM_OX_START + 0x005)
-#define HFI_PROPERTY_PARAM_INDEX_EXTRADATA             \
-	(HFI_PROPERTY_PARAM_OX_START + 0x006)
-#define HFI_PROPERTY_PARAM_DIVX_FORMAT					\
-	(HFI_PROPERTY_PARAM_OX_START + 0x007)
-#define HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE			\
-	(HFI_PROPERTY_PARAM_OX_START + 0x008)
-#define HFI_PROPERTY_PARAM_S3D_FRAME_PACKING_EXTRADATA	\
-	(HFI_PROPERTY_PARAM_OX_START + 0x009)
-
-#define HFI_PROPERTY_CONFIG_OX_START					\
-	(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + 0x02000)
-#define HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS			\
-	(HFI_PROPERTY_CONFIG_OX_START + 0x001)
-#define HFI_PROPERTY_CONFIG_REALTIME					\
-	(HFI_PROPERTY_CONFIG_OX_START + 0x002)
-#define HFI_PROPERTY_CONFIG_PRIORITY					\
-	(HFI_PROPERTY_CONFIG_OX_START + 0x003)
-#define HFI_PROPERTY_CONFIG_BATCH_INFO					\
-	(HFI_PROPERTY_CONFIG_OX_START + 0x004)
-
-#define HFI_PROPERTY_PARAM_VDEC_OX_START				\
-	(HFI_DOMAIN_BASE_VDEC + HFI_ARCH_OX_OFFSET + 0x3000)
-#define HFI_PROPERTY_PARAM_VDEC_CONTINUE_DATA_TRANSFER	\
-	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x001)
-#define HFI_PROPERTY_PARAM_VDEC_DISPLAY_PICTURE_BUFFER_COUNT\
-	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x002)
-#define HFI_PROPERTY_PARAM_VDEC_MULTI_VIEW_SELECT		\
-	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x003)
-#define HFI_PROPERTY_PARAM_VDEC_PICTURE_TYPE_DECODE		\
-	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x004)
-#define HFI_PROPERTY_PARAM_VDEC_OUTPUT_ORDER			\
-	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x005)
-#define HFI_PROPERTY_PARAM_VDEC_MB_QUANTIZATION			\
-	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x006)
-#define HFI_PROPERTY_PARAM_VDEC_NUM_CONCEALED_MB		\
-	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x007)
-#define HFI_PROPERTY_PARAM_VDEC_H264_ENTROPY_SWITCHING	\
-	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x008)
-#define HFI_PROPERTY_PARAM_VDEC_OUTPUT2_KEEP_ASPECT_RATIO\
-	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x009)
-#define HFI_PROPERTY_PARAM_VDEC_FRAME_RATE_EXTRADATA  \
-	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x00A)
-#define HFI_PROPERTY_PARAM_VDEC_PANSCAN_WNDW_EXTRADATA \
-	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x00B)
-#define HFI_PROPERTY_PARAM_VDEC_RECOVERY_POINT_SEI_EXTRADATA \
-	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x00C)
-#define HFI_PROPERTY_PARAM_VDEC_THUMBNAIL_MODE   \
-	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x00D)
-
-#define HFI_PROPERTY_PARAM_VDEC_FRAME_ASSEMBLY		\
-	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x00E)
-#define HFI_PROPERTY_PARAM_VDEC_CLOSED_CAPTION_EXTRADATA	\
-	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x00F)
-#define HFI_PROPERTY_PARAM_VDEC_AFD_EXTRADATA		\
-	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x010)
-#define HFI_PROPERTY_PARAM_VDEC_VC1_FRAMEDISP_EXTRADATA		\
-	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x011)
-#define HFI_PROPERTY_PARAM_VDEC_VC1_SEQDISP_EXTRADATA		\
-	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x012)
-#define HFI_PROPERTY_PARAM_VDEC_TIMESTAMP_EXTRADATA			\
-	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x013)
-#define HFI_PROPERTY_PARAM_VDEC_INTERLACE_VIDEO_EXTRADATA	\
-	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x014)
-#define HFI_PROPERTY_PARAM_VDEC_AVC_SESSION_SELECT \
-	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x015)
-
-#define HFI_PROPERTY_CONFIG_VDEC_OX_START				\
-	(HFI_DOMAIN_BASE_VDEC + HFI_ARCH_OX_OFFSET + 0x0000)
-#define HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER	\
-	(HFI_PROPERTY_CONFIG_VDEC_OX_START + 0x001)
-#define HFI_PROPERTY_CONFIG_VDEC_MB_ERROR_MAP_REPORTING	\
-	(HFI_PROPERTY_CONFIG_VDEC_OX_START + 0x002)
-#define HFI_PROPERTY_CONFIG_VDEC_MB_ERROR_MAP			\
-	(HFI_PROPERTY_CONFIG_VDEC_OX_START + 0x003)
-
-#define HFI_PROPERTY_PARAM_VENC_OX_START				\
-	(HFI_DOMAIN_BASE_VENC + HFI_ARCH_OX_OFFSET + 0x5000)
-#define  HFI_PROPERTY_PARAM_VENC_MULTI_SLICE_INFO       \
-	(HFI_PROPERTY_PARAM_VENC_OX_START + 0x001)
-#define  HFI_PROPERTY_PARAM_VENC_H264_IDR_S3D_FRAME_PACKING_NAL \
-	(HFI_PROPERTY_PARAM_VENC_OX_START + 0x002)
-
-#define HFI_PROPERTY_CONFIG_VENC_OX_START				\
-	(HFI_DOMAIN_BASE_VENC + HFI_ARCH_OX_OFFSET + 0x6000)
-#define  HFI_PROPERTY_CONFIG_VENC_FRAME_QP				\
-	(HFI_PROPERTY_CONFIG_VENC_OX_START + 0x001)
-
-#define HFI_PROPERTY_PARAM_VPE_OX_START					\
-	(HFI_DOMAIN_BASE_VPE + HFI_ARCH_OX_OFFSET + 0x7000)
-#define HFI_PROPERTY_CONFIG_VPE_OX_START				\
-	(HFI_DOMAIN_BASE_VPE + HFI_ARCH_OX_OFFSET + 0x8000)
-
-struct hfi_batch_info {
-	u32 input_batch_count;
-	u32 output_batch_count;
-};
-
-struct hfi_buffer_count_actual {
-	u32 buffer_type;
-	u32 buffer_count_actual;
-};
-
-struct hfi_buffer_requirements {
-	u32 buffer_type;
-	u32 buffer_size;
-	u32 buffer_region_size;
-	u32 buffer_hold_count;
-	u32 buffer_count_min;
-	u32 buffer_count_actual;
-	u32 contiguous;
-	u32 buffer_alignment;
-};
-
-#define HFI_CHROMA_SITE_0			(HFI_OX_BASE + 0x1)
-#define HFI_CHROMA_SITE_1			(HFI_OX_BASE + 0x2)
-#define HFI_CHROMA_SITE_2			(HFI_OX_BASE + 0x3)
-#define HFI_CHROMA_SITE_3			(HFI_OX_BASE + 0x4)
-#define HFI_CHROMA_SITE_4			(HFI_OX_BASE + 0x5)
-#define HFI_CHROMA_SITE_5			(HFI_OX_BASE + 0x6)
-
-struct hfi_data_payload {
-	u32 size;
-	u8 rg_data[1];
-};
-
-struct hfi_enable_picture {
-	u32 picture_type;
-};
-
-struct hfi_display_picture_buffer_count {
-	int enable;
-	u32 count;
-};
-
-struct hfi_extra_data_header_config {
-	u32 type;
-	u32 buffer_type;
-	u32 version;
-	u32 port_index;
-	u32 client_extra_data_id;
-};
-
-struct hfi_interlace_format_supported {
-	u32 buffer_type;
-	u32 format;
-};
-
-struct hfi_mb_error_map {
-	u32 error_map_size;
-	u8 rg_error_map[1];
-};
-
-struct hfi_metadata_pass_through {
-	int enable;
-	u32 size;
-};
-
-struct hfi_multi_view_select {
-	u32 view_index;
-};
-
-#define HFI_PRIORITY_LOW		10
-#define HFI_PRIOIRTY_MEDIUM		20
-#define HFI_PRIORITY_HIGH		30
-
-#define HFI_OUTPUT_ORDER_DISPLAY	(HFI_OX_BASE + 0x1)
-#define HFI_OUTPUT_ORDER_DECODE		(HFI_OX_BASE + 0x2)
-
-#define HFI_RATE_CONTROL_OFF		(HFI_OX_BASE + 0x1)
-#define HFI_RATE_CONTROL_VBR_VFR	(HFI_OX_BASE + 0x2)
-#define HFI_RATE_CONTROL_VBR_CFR	(HFI_OX_BASE + 0x3)
-#define HFI_RATE_CONTROL_CBR_VFR	(HFI_OX_BASE + 0x4)
-#define HFI_RATE_CONTROL_CBR_CFR	(HFI_OX_BASE + 0x5)
-
-struct hfi_uncompressed_plane_actual_constraints_info {
-	u32 buffer_type;
-	u32 num_planes;
-	struct hfi_uncompressed_plane_constraints rg_plane_format[1];
-};
-
-#define HFI_CMD_SYS_OX_START		\
-(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + HFI_CMD_START_OFFSET + 0x0000)
-#define HFI_CMD_SYS_SESSION_ABORT	(HFI_CMD_SYS_OX_START + 0x001)
-#define HFI_CMD_SYS_PING		(HFI_CMD_SYS_OX_START + 0x002)
-
-#define HFI_CMD_SESSION_OX_START	\
-(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + HFI_CMD_START_OFFSET + 0x1000)
-#define HFI_CMD_SESSION_LOAD_RESOURCES	(HFI_CMD_SESSION_OX_START + 0x001)
-#define HFI_CMD_SESSION_START		(HFI_CMD_SESSION_OX_START + 0x002)
-#define HFI_CMD_SESSION_STOP		(HFI_CMD_SESSION_OX_START + 0x003)
-#define HFI_CMD_SESSION_EMPTY_BUFFER	(HFI_CMD_SESSION_OX_START + 0x004)
-#define HFI_CMD_SESSION_FILL_BUFFER	(HFI_CMD_SESSION_OX_START + 0x005)
-#define HFI_CMD_SESSION_SUSPEND		(HFI_CMD_SESSION_OX_START + 0x006)
-#define HFI_CMD_SESSION_RESUME		(HFI_CMD_SESSION_OX_START + 0x007)
-#define HFI_CMD_SESSION_FLUSH		(HFI_CMD_SESSION_OX_START + 0x008)
-#define HFI_CMD_SESSION_GET_PROPERTY	(HFI_CMD_SESSION_OX_START + 0x009)
-#define HFI_CMD_SESSION_PARSE_SEQUENCE_HEADER	\
-	(HFI_CMD_SESSION_OX_START + 0x00A)
-#define HFI_CMD_SESSION_RELEASE_BUFFERS		\
-	(HFI_CMD_SESSION_OX_START + 0x00B)
-#define HFI_CMD_SESSION_RELEASE_RESOURCES	\
-	(HFI_CMD_SESSION_OX_START + 0x00C)
-
-#define HFI_MSG_SYS_OX_START			\
-(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + HFI_MSG_START_OFFSET + 0x0000)
-#define HFI_MSG_SYS_IDLE		(HFI_MSG_SYS_OX_START + 0x1)
-#define HFI_MSG_SYS_PING_ACK	(HFI_MSG_SYS_OX_START + 0x2)
-#define HFI_MSG_SYS_PROPERTY_INFO	(HFI_MSG_SYS_OX_START + 0x3)
-#define HFI_MSG_SYS_SESSION_ABORT_DONE	(HFI_MSG_SYS_OX_START + 0x4)
-
-#define HFI_MSG_SESSION_OX_START		\
-(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + HFI_MSG_START_OFFSET + 0x1000)
-#define HFI_MSG_SESSION_LOAD_RESOURCES_DONE	(HFI_MSG_SESSION_OX_START + 0x1)
-#define HFI_MSG_SESSION_START_DONE		(HFI_MSG_SESSION_OX_START + 0x2)
-#define HFI_MSG_SESSION_STOP_DONE		(HFI_MSG_SESSION_OX_START + 0x3)
-#define HFI_MSG_SESSION_SUSPEND_DONE	(HFI_MSG_SESSION_OX_START + 0x4)
-#define HFI_MSG_SESSION_RESUME_DONE		(HFI_MSG_SESSION_OX_START + 0x5)
-#define HFI_MSG_SESSION_FLUSH_DONE		(HFI_MSG_SESSION_OX_START + 0x6)
-#define HFI_MSG_SESSION_EMPTY_BUFFER_DONE	(HFI_MSG_SESSION_OX_START + 0x7)
-#define HFI_MSG_SESSION_FILL_BUFFER_DONE	(HFI_MSG_SESSION_OX_START + 0x8)
-#define HFI_MSG_SESSION_PROPERTY_INFO		(HFI_MSG_SESSION_OX_START + 0x9)
-#define HFI_MSG_SESSION_RELEASE_RESOURCES_DONE	\
-	(HFI_MSG_SESSION_OX_START + 0xA)
-#define HFI_MSG_SESSION_PARSE_SEQUENCE_HEADER_DONE		\
-	(HFI_MSG_SESSION_OX_START + 0xB)
-#define  HFI_MSG_SESSION_RELEASE_BUFFERS_DONE			\
-	(HFI_MSG_SESSION_OX_START + 0xC)
-
-struct hfi_cmd_sys_session_abort_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-};
-
-struct hfi_cmd_sys_ping_packet {
-	u32 size;
-	u32 packet_type;
-	u32 client_data;
-};
-
-struct hfi_cmd_session_load_resources_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-};
-
-struct hfi_cmd_session_start_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-};
-
-struct hfi_cmd_session_stop_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-};
-
-struct hfi_cmd_session_empty_buffer_compressed_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 time_stamp_hi;
-	u32 time_stamp_lo;
-	u32 flags;
-	u32 mark_target;
-	u32 mark_data;
-	u32 offset;
-	u32 alloc_len;
-	u32 filled_len;
-	u32 input_tag;
-	u8 *packet_buffer;
-	u8 *extra_data_buffer;
-	u32 rgData[0];
-};
-
-struct hfi_cmd_session_empty_buffer_uncompressed_plane0_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 view_id;
-	u32 time_stamp_hi;
-	u32 time_stamp_lo;
-	u32 flags;
-	u32 mark_target;
-	u32 mark_data;
-	u32 alloc_len;
-	u32 filled_len;
-	u32 offset;
-	u32 input_tag;
-	u8 *packet_buffer;
-	u8 *extra_data_buffer;
-	u32 rgData[0];
-};
-
-struct hfi_cmd_session_empty_buffer_uncompressed_plane1_packet {
-	u32 flags;
-	u32 alloc_len;
-	u32 filled_len;
-	u32 offset;
-	u8 *packet_buffer2;
-	u32 rgData[0];
-};
-
-struct hfi_cmd_session_empty_buffer_uncompressed_plane2_packet {
-	u32 flags;
-	u32 alloc_len;
-	u32 filled_len;
-	u32 offset;
-	u8 *packet_buffer3;
-	u32 rgData[0];
-};
-
-struct hfi_cmd_session_fill_buffer_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 stream_id;
-	u32 offset;
-	u32 alloc_len;
-	u32 filled_len;
-	u32 output_tag;
-	u8 *packet_buffer;
-	u8 *extra_data_buffer;
-	u32 rgData[0];
-};
-
-struct hfi_cmd_session_flush_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 flush_type;
-};
-
-struct hfi_cmd_session_suspend_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-};
-
-struct hfi_cmd_session_resume_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-};
-
-struct hfi_cmd_session_get_property_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 num_properties;
-	u32 rg_property_data[1];
-};
-
-struct hfi_cmd_session_release_buffer_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 buffer_type;
-	u32 buffer_size;
-	u32 extra_data_size;
-	int response_req;
-	u32 num_buffers;
-	u32 rg_buffer_info[1];
-};
-
-struct hfi_cmd_session_release_resources_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-};
-
-struct hfi_cmd_session_parse_sequence_header_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 header_len;
-	u8 *packet_buffer;
-};
-
-struct hfi_msg_sys_session_abort_done_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 error_type;
-};
-
-struct hfi_msg_sys_idle_packet {
-	u32 size;
-	u32 packet_type;
-};
-
-struct hfi_msg_sys_ping_ack_packet {
-	u32 size;
-	u32 packet_type;
-	u32 client_data;
-};
-
-struct hfi_msg_sys_property_info_packet {
-	u32 size;
-	u32 packet_type;
-	u32 num_properties;
-	u32 rg_property_data[1];
-};
-
-struct hfi_msg_session_load_resources_done_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 error_type;
-};
-
-struct hfi_msg_session_start_done_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 error_type;
-};
-
-struct hfi_msg_session_stop_done_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 error_type;
-};
-
-struct hfi_msg_session_suspend_done_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 error_type;
-};
-
-struct hfi_msg_session_resume_done_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 error_type;
-};
-
-struct hfi_msg_session_flush_done_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 error_type;
-	u32 flush_type;
-};
-
-struct hfi_msg_session_empty_buffer_done_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 error_type;
-	u32 offset;
-	u32 filled_len;
-	u32 input_tag;
-	u8 *packet_buffer;
-	u8 *extra_data_buffer;
-	u32 rgData[0];
-};
-
-struct hfi_msg_session_fill_buffer_done_compressed_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 time_stamp_hi;
-	u32 time_stamp_lo;
-	u32 error_type;
-	u32 flags;
-	u32 mark_target;
-	u32 mark_data;
-	u32 stats;
-	u32 offset;
-	u32 alloc_len;
-	u32 filled_len;
-	u32 input_tag;
-	u32 output_tag;
-	u32 picture_type;
-	u8 *packet_buffer;
-	u8 *extra_data_buffer;
-	u32 rgData[0];
-};
-
-struct hfi_msg_session_fbd_uncompressed_plane0_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 stream_id;
-	u32 view_id;
-	u32 error_type;
-	u32 time_stamp_hi;
-	u32 time_stamp_lo;
-	u32 flags;
-	u32 mark_target;
-	u32 mark_data;
-	u32 stats;
-	u32 alloc_len;
-	u32 filled_len;
-	u32 offset;
-	u32 frame_width;
-	u32 frame_height;
-	u32 start_x_coord;
-	u32 start_y_coord;
-	u32 input_tag;
-	u32 input_tag2;
-	u32 output_tag;
-	u32 picture_type;
-	u8 *packet_buffer;
-	u8 *extra_data_buffer;
-	u32 rgData[0];
-};
-
-struct hfi_msg_session_fill_buffer_done_uncompressed_plane1_packet {
-	u32 flags;
-	u32 alloc_len;
-	u32 filled_len;
-	u32 offset;
-	u8 *packet_buffer2;
-	u32 rgData[0];
-};
-
-struct hfi_msg_session_fill_buffer_done_uncompressed_plane2_packet {
-	u32 flags;
-	u32 alloc_len;
-	u32 filled_len;
-	u32 offset;
-	u8 *packet_buffer3;
-	u32 rgData[0];
-};
-
-struct hfi_msg_session_parse_sequence_header_done_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 error_type;
-	u32 num_properties;
-	u32 rg_property_data[1];
-};
-
-struct hfi_msg_session_property_info_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 num_properties;
-	u32 rg_property_data[1];
-};
-
-struct hfi_msg_session_release_resources_done_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 error_type;
-};
-
-struct hfi_msg_session_release_buffers_done_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 error_type;
-	u32 num_buffers;
-	u32 rg_buffer_info[1];
-};
-
-struct hfi_extradata_mb_quantization_payload {
-	u8 rg_mb_qp[1];
-};
-
-struct hfi_extradata_vc1_pswnd {
-	u32 ps_wnd_h_offset;
-	u32 ps_wnd_v_offset;
-	u32 ps_wnd_width;
-	u32 ps_wnd_height;
-};
-
-struct hfi_extradata_vc1_framedisp_payload {
-	u32 res_pic;
-	u32 ref;
-	u32 range_map_present;
-	u32 range_map_y;
-	u32 range_map_uv;
-	u32 num_pan_scan_wnds;
-	struct hfi_extradata_vc1_pswnd rg_ps_wnd[1];
-};
-
-struct hfi_extradata_vc1_seqdisp_payload {
-	u32 prog_seg_frm;
-	u32 uv_sampling_fmt;
-	u32 color_fmt_flag;
-	u32 color_primaries;
-	u32 transfer_char;
-	u32 mat_coeff;
-	u32 aspect_ratio;
-	u32 aspect_horiz;
-	u32 aspect_vert;
-};
-
-struct hfi_extradata_timestamp_payload {
-	u32 time_stamp_low;
-	u32 time_stamp_high;
-};
-
-
-struct hfi_extradata_s3d_frame_packing_payload {
-	u32 fpa_id;
-	int cancel_flag;
-	u32 fpa_type;
-	int quin_cunx_flag;
-	u32 content_interprtation_type;
-	int spatial_flipping_flag;
-	int frame0_flipped_flag;
-	int field_views_flag;
-	int current_frame_isFrame0_flag;
-	int frame0_self_contained_flag;
-	int frame1_self_contained_flag;
-	u32 frame0_graid_pos_x;
-	u32 frame0_graid_pos_y;
-	u32 frame1_graid_pos_x;
-	u32 frame1_graid_pos_y;
-	u32 fpa_reserved_byte;
-	u32 fpa_repetition_period;
-	int fpa_extension_flag;
-};
-
-struct hfi_extradata_interlace_video_payload {
-	u32 format;
-};
-
-struct hfi_extradata_num_concealed_mb_payload {
-	u32 num_mb_concealed;
-};
-
-struct hfi_extradata_sliceinfo {
-	u32 offset_in_stream;
-	u32 slice_length;
-};
-
-struct hfi_extradata_multislice_info_payload {
-	u32 num_slices;
-	struct hfi_extradata_sliceinfo rg_slice_info[1];
-};
-
-struct hfi_index_extradata_input_crop_payload {
-	u32 size;
-	u32 version;
-	u32 port_index;
-	u32 left;
-	u32 top;
-	u32 width;
-	u32 height;
-};
-
-struct hfi_index_extradata_digital_zoom_payload {
-	u32 size;
-	u32 version;
-	u32 port_index;
-	int width;
-	int height;
-};
-
-struct hfi_index_extradata_aspect_ratio_payload {
-	u32 size;
-	u32 version;
-	u32 port_index;
-	u32 aspect_width;
-	u32 aspect_height;
-};
-struct hfi_extradata_panscan_wndw_payload {
-	u32 num_window;
-	struct hfi_extradata_vc1_pswnd wnd[1];
-};
-
-struct hfi_extradata_frame_type_payload {
-	u32 frame_rate;
-};
-
-struct hfi_extradata_recovery_point_sei_payload {
-	u32 flag;
-};
-
-struct vidc_mem_addr {
-	u8 *align_device_addr;
-	u8 *align_virtual_addr;
-	u32 mem_size;
-	struct msm_smem *mem_data;
-};
-
-struct vidc_iface_q_info {
-	void *q_hdr;
-	struct vidc_mem_addr q_array;
-};
-
-/* Internal data used in vidc_hal not exposed to msm_vidc*/
-
-struct hal_data {
-	u32 irq;
-	u32 device_base_addr;
-	u8 *register_base_addr;
-};
-
-struct hal_device {
-	struct list_head list;
-	struct list_head sess_head;
-	u32 intr_status;
-	u32 device_id;
-	spinlock_t read_lock;
-	spinlock_t write_lock;
-	void (*callback) (u32 response, void *callback);
-	struct vidc_mem_addr iface_q_table;
-	struct vidc_mem_addr qdss;
-	struct vidc_mem_addr sfr;
-	struct vidc_mem_addr mem_addr;
-	struct vidc_iface_q_info iface_queues[VIDC_IFACEQ_NUMQ];
-	struct smem_client *hal_client;
-	struct hal_data *hal_data;
-	struct workqueue_struct *vidc_workq;
-	int spur_count;
-	int reg_count;
-};
-
-struct hal_session {
-	struct list_head list;
-	u32 session_id;
-	u32 is_decoder;
-	struct hal_device *device;
-};
-
-struct hal_device_data {
-	struct list_head dev_head;
-	int dev_count;
-};
-
-extern struct hal_device_data hal_ctxt;
-
-int vidc_hal_iface_msgq_read(struct hal_device *device, void *pkt);
-int vidc_hal_iface_dbgq_read(struct hal_device *device, void *pkt);
-
-/* Interrupt Processing:*/
-void vidc_hal_response_handler(struct hal_device *device);
-
-#endif
diff --git a/drivers/media/video/msm_vidc/vidc_hal_api.h b/drivers/media/video/msm_vidc/vidc_hal_api.h
deleted file mode 100644
index 3e70342..0000000
--- a/drivers/media/video/msm_vidc/vidc_hal_api.h
+++ /dev/null
@@ -1,1026 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 __VIDC_HAL_API_H__
-#define __VIDC_HAL_API_H__
-
-#include <linux/types.h>
-
-#define CONTAINS(__a, __sz, __t) ({\
-	int __rc = __t >= __a && \
-			__t < __a + __sz; \
-	__rc; \
-})
-
-#define OVERLAPS(__t, __tsz, __a, __asz) ({\
-	int __rc = __t <= __a && \
-			__t + __tsz >= __a + __asz; \
-	__rc; \
-})
-
-#define HAL_BUFFERFLAG_EOS              0x00000001
-#define HAL_BUFFERFLAG_STARTTIME        0x00000002
-#define HAL_BUFFERFLAG_DECODEONLY       0x00000004
-#define HAL_BUFFERFLAG_DATACORRUPT      0x00000008
-#define HAL_BUFFERFLAG_ENDOFFRAME       0x00000010
-#define HAL_BUFFERFLAG_SYNCFRAME        0x00000020
-#define HAL_BUFFERFLAG_EXTRADATA        0x00000040
-#define HAL_BUFFERFLAG_CODECCONFIG      0x00000080
-#define HAL_BUFFERFLAG_TIMESTAMPINVALID 0x00000100
-#define HAL_BUFFERFLAG_READONLY         0x00000200
-#define HAL_BUFFERFLAG_ENDOFSUBFRAME    0x00000400
-#define HAL_BUFFERFLAG_EOSEQ            0x00200000
-
-#define HAL_DEBUG_MSG_LOW				0x00000001
-#define HAL_DEBUG_MSG_MEDIUM			0x00000002
-#define HAL_DEBUG_MSG_HIGH				0x00000004
-#define HAL_DEBUG_MSG_ERROR				0x00000008
-#define HAL_DEBUG_MSG_FATAL				0x00000010
-
-enum vidc_status {
-	VIDC_ERR_NONE = 0x0,
-	VIDC_ERR_FAIL = 0x80000000,
-	VIDC_ERR_ALLOC_FAIL,
-	VIDC_ERR_ILLEGAL_OP,
-	VIDC_ERR_BAD_PARAM,
-	VIDC_ERR_BAD_HANDLE,
-	VIDC_ERR_NOT_SUPPORTED,
-	VIDC_ERR_BAD_STATE,
-	VIDC_ERR_MAX_CLIENT,
-	VIDC_ERR_IFRAME_EXPECTED,
-	VIDC_ERR_HW_FATAL,
-	VIDC_ERR_BITSTREAM_ERR,
-	VIDC_ERR_INDEX_NOMORE,
-	VIDC_ERR_SEQHDR_PARSE_FAIL,
-	VIDC_ERR_INSUFFICIENT_BUFFER,
-	VIDC_ERR_BAD_POWER_STATE,
-	VIDC_ERR_NO_VALID_SESSION,
-	VIDC_ERR_TIMEOUT,
-	VIDC_ERR_CMDQFULL,
-	VIDC_ERR_CLIENT_PRESENT = 0x90000001,
-	VIDC_ERR_CLIENT_FATAL,
-	VIDC_ERR_CMD_QUEUE_FULL,
-	VIDC_ERR_UNUSED = 0x10000000
-};
-
-enum hal_extradata_id {
-	HAL_EXTRADATA_NONE,
-	HAL_EXTRADATA_MB_QUANTIZATION,
-	HAL_EXTRADATA_INTERLACE_VIDEO,
-	HAL_EXTRADATA_VC1_FRAMEDISP,
-	HAL_EXTRADATA_VC1_SEQDISP,
-	HAL_EXTRADATA_TIMESTAMP,
-	HAL_EXTRADATA_S3D_FRAME_PACKING,
-	HAL_EXTRADATA_FRAME_RATE,
-	HAL_EXTRADATA_PANSCAN_WINDOW,
-	HAL_EXTRADATA_RECOVERY_POINT_SEI,
-	HAL_EXTRADATA_CLOSED_CAPTION_UD,
-	HAL_EXTRADATA_AFD_UD,
-	HAL_EXTRADATA_MULTISLICE_INFO,
-	HAL_EXTRADATA_INDEX,
-	HAL_EXTRADATA_NUM_CONCEALED_MB,
-	HAL_EXTRADATA_METADATA_FILLER,
-};
-
-enum hal_property {
-	HAL_CONFIG_FRAME_RATE = 0x04000001,
-	HAL_PARAM_UNCOMPRESSED_FORMAT_SELECT,
-	HAL_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO,
-	HAL_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO,
-	HAL_PARAM_EXTRA_DATA_HEADER_CONFIG,
-	HAL_PARAM_INDEX_EXTRADATA,
-	HAL_PARAM_FRAME_SIZE,
-	HAL_CONFIG_REALTIME,
-	HAL_PARAM_BUFFER_COUNT_ACTUAL,
-	HAL_PARAM_NAL_STREAM_FORMAT_SELECT,
-	HAL_PARAM_VDEC_OUTPUT_ORDER,
-	HAL_PARAM_VDEC_PICTURE_TYPE_DECODE,
-	HAL_PARAM_VDEC_OUTPUT2_KEEP_ASPECT_RATIO,
-	HAL_CONFIG_VDEC_POST_LOOP_DEBLOCKER,
-	HAL_PARAM_VDEC_MULTI_STREAM,
-	HAL_PARAM_VDEC_DISPLAY_PICTURE_BUFFER_COUNT,
-	HAL_PARAM_DIVX_FORMAT,
-	HAL_CONFIG_VDEC_MB_ERROR_MAP_REPORTING,
-	HAL_PARAM_VDEC_CONTINUE_DATA_TRANSFER,
-	HAL_CONFIG_VDEC_MB_ERROR_MAP,
-	HAL_CONFIG_VENC_REQUEST_IFRAME,
-	HAL_PARAM_VENC_MPEG4_SHORT_HEADER,
-	HAL_PARAM_VENC_MPEG4_AC_PREDICTION,
-	HAL_CONFIG_VENC_TARGET_BITRATE,
-	HAL_PARAM_PROFILE_LEVEL_CURRENT,
-	HAL_PARAM_VENC_H264_ENTROPY_CONTROL,
-	HAL_PARAM_VENC_RATE_CONTROL,
-	HAL_PARAM_VENC_MPEG4_TIME_RESOLUTION,
-	HAL_PARAM_VENC_MPEG4_HEADER_EXTENSION,
-	HAL_PARAM_VENC_H264_DEBLOCK_CONTROL,
-	HAL_PARAM_VENC_TEMPORAL_SPATIAL_TRADEOFF,
-	HAL_PARAM_VENC_SESSION_QP,
-	HAL_CONFIG_VENC_INTRA_PERIOD,
-	HAL_CONFIG_VENC_IDR_PERIOD,
-	HAL_CONFIG_VPE_OPERATIONS,
-	HAL_PARAM_VENC_INTRA_REFRESH,
-	HAL_PARAM_VENC_MULTI_SLICE_CONTROL,
-	HAL_CONFIG_VPE_DEINTERLACE,
-	HAL_SYS_DEBUG_CONFIG,
-	HAL_CONFIG_BUFFER_REQUIREMENTS,
-	HAL_CONFIG_PRIORITY,
-	HAL_CONFIG_BATCH_INFO,
-	HAL_PARAM_METADATA_PASS_THROUGH,
-	HAL_SYS_IDLE_INDICATOR,
-	HAL_PARAM_UNCOMPRESSED_FORMAT_SUPPORTED,
-	HAL_PARAM_INTERLACE_FORMAT_SUPPORTED,
-	HAL_PARAM_CHROMA_SITE,
-	HAL_PARAM_PROPERTIES_SUPPORTED,
-	HAL_PARAM_PROFILE_LEVEL_SUPPORTED,
-	HAL_PARAM_CAPABILITY_SUPPORTED,
-	HAL_PARAM_NAL_STREAM_FORMAT_SUPPORTED,
-	HAL_PARAM_MULTI_VIEW_FORMAT,
-	HAL_PARAM_MAX_SEQUENCE_HEADER_SIZE,
-	HAL_PARAM_CODEC_SUPPORTED,
-	HAL_PARAM_VDEC_MULTI_VIEW_SELECT,
-	HAL_PARAM_VDEC_MB_QUANTIZATION,
-	HAL_PARAM_VDEC_NUM_CONCEALED_MB,
-	HAL_PARAM_VDEC_H264_ENTROPY_SWITCHING,
-	HAL_PARAM_VENC_SLICE_DELIVERY_MODE,
-	HAL_PARAM_VENC_MPEG4_DATA_PARTITIONING,
-	HAL_CONFIG_BUFFER_COUNT_ACTUAL,
-	HAL_CONFIG_VDEC_MULTI_STREAM,
-	HAL_PARAM_VENC_MULTI_SLICE_INFO,
-	HAL_CONFIG_VENC_TIMESTAMP_SCALE,
-	HAL_PARAM_VENC_LOW_LATENCY,
-	HAL_PARAM_VENC_SYNC_FRAME_SEQUENCE_HEADER,
-	HAL_PARAM_VDEC_SYNC_FRAME_DECODE,
-};
-
-enum hal_domain {
-	HAL_VIDEO_DOMAIN_VPE,
-	HAL_VIDEO_DOMAIN_ENCODER,
-	HAL_VIDEO_DOMAIN_DECODER,
-	HAL_UNUSED_DOMAIN = 0x10000000,
-};
-
-enum hal_video_codec {
-	HAL_VIDEO_CODEC_UNKNOWN  = 0x00000000,
-	HAL_VIDEO_CODEC_MVC      = 0x00000001,
-	HAL_VIDEO_CODEC_H264     = 0x00000002,
-	HAL_VIDEO_CODEC_H263     = 0x00000004,
-	HAL_VIDEO_CODEC_MPEG1    = 0x00000008,
-	HAL_VIDEO_CODEC_MPEG2    = 0x00000010,
-	HAL_VIDEO_CODEC_MPEG4    = 0x00000020,
-	HAL_VIDEO_CODEC_DIVX_311 = 0x00000040,
-	HAL_VIDEO_CODEC_DIVX     = 0x00000080,
-	HAL_VIDEO_CODEC_VC1      = 0x00000100,
-	HAL_VIDEO_CODEC_SPARK    = 0x00000200,
-	HAL_VIDEO_CODEC_VP6      = 0x00000400,
-	HAL_VIDEO_CODEC_VP7      = 0x00000800,
-	HAL_VIDEO_CODEC_VP8      = 0x00001000,
-	HAL_UNUSED_CODEC = 0x10000000,
-};
-
-enum hal_h263_profile {
-	HAL_H263_PROFILE_BASELINE           = 0x00000001,
-	HAL_H263_PROFILE_H320CODING         = 0x00000002,
-	HAL_H263_PROFILE_BACKWARDCOMPATIBLE = 0x00000004,
-	HAL_H263_PROFILE_ISWV2              = 0x00000008,
-	HAL_H263_PROFILE_ISWV3              = 0x00000010,
-	HAL_H263_PROFILE_HIGHCOMPRESSION    = 0x00000020,
-	HAL_H263_PROFILE_INTERNET           = 0x00000040,
-	HAL_H263_PROFILE_INTERLACE          = 0x00000080,
-	HAL_H263_PROFILE_HIGHLATENCY        = 0x00000100,
-	HAL_UNUSED_H263_PROFILE = 0x10000000,
-};
-
-enum hal_h263_level {
-	HAL_H263_LEVEL_10 = 0x00000001,
-	HAL_H263_LEVEL_20 = 0x00000002,
-	HAL_H263_LEVEL_30 = 0x00000004,
-	HAL_H263_LEVEL_40 = 0x00000008,
-	HAL_H263_LEVEL_45 = 0x00000010,
-	HAL_H263_LEVEL_50 = 0x00000020,
-	HAL_H263_LEVEL_60 = 0x00000040,
-	HAL_H263_LEVEL_70 = 0x00000080,
-	HAL_UNUSED_H263_LEVEL = 0x10000000,
-};
-
-enum hal_mpeg2_profile {
-	HAL_MPEG2_PROFILE_SIMPLE  = 0x00000001,
-	HAL_MPEG2_PROFILE_MAIN    = 0x00000002,
-	HAL_MPEG2_PROFILE_422     = 0x00000004,
-	HAL_MPEG2_PROFILE_SNR     = 0x00000008,
-	HAL_MPEG2_PROFILE_SPATIAL = 0x00000010,
-	HAL_MPEG2_PROFILE_HIGH    = 0x00000020,
-	HAL_UNUSED_MPEG2_PROFILE = 0x10000000,
-};
-
-enum hal_mpeg2_level {
-	HAL_MPEG2_LEVEL_LL  = 0x00000001,
-	HAL_MPEG2_LEVEL_ML  = 0x00000002,
-	HAL_MPEG2_LEVEL_H14 = 0x00000004,
-	HAL_MPEG2_LEVEL_HL  = 0x00000008,
-	HAL_UNUSED_MEPG2_LEVEL = 0x10000000,
-};
-
-enum hal_mpeg4_profile {
-	HAL_MPEG4_PROFILE_SIMPLE           = 0x00000001,
-	HAL_MPEG4_PROFILE_ADVANCEDSIMPLE   = 0x00000002,
-	HAL_MPEG4_PROFILE_CORE             = 0x00000004,
-	HAL_MPEG4_PROFILE_MAIN             = 0x00000008,
-	HAL_MPEG4_PROFILE_NBIT             = 0x00000010,
-	HAL_MPEG4_PROFILE_SCALABLETEXTURE  = 0x00000020,
-	HAL_MPEG4_PROFILE_SIMPLEFACE       = 0x00000040,
-	HAL_MPEG4_PROFILE_SIMPLEFBA        = 0x00000080,
-	HAL_MPEG4_PROFILE_BASICANIMATED    = 0x00000100,
-	HAL_MPEG4_PROFILE_HYBRID           = 0x00000200,
-	HAL_MPEG4_PROFILE_ADVANCEDREALTIME = 0x00000400,
-	HAL_MPEG4_PROFILE_CORESCALABLE     = 0x00000800,
-	HAL_MPEG4_PROFILE_ADVANCEDCODING   = 0x00001000,
-	HAL_MPEG4_PROFILE_ADVANCEDCORE     = 0x00002000,
-	HAL_MPEG4_PROFILE_ADVANCEDSCALABLE = 0x00004000,
-	HAL_MPEG4_PROFILE_SIMPLESCALABLE   = 0x00008000,
-	HAL_UNUSED_MPEG4_PROFILE = 0x10000000,
-};
-
-enum hal_mpeg4_level {
-	HAL_MPEG4_LEVEL_0  = 0x00000001,
-	HAL_MPEG4_LEVEL_0b = 0x00000002,
-	HAL_MPEG4_LEVEL_1  = 0x00000004,
-	HAL_MPEG4_LEVEL_2  = 0x00000008,
-	HAL_MPEG4_LEVEL_3  = 0x00000010,
-	HAL_MPEG4_LEVEL_4  = 0x00000020,
-	HAL_MPEG4_LEVEL_4a = 0x00000040,
-	HAL_MPEG4_LEVEL_5  = 0x00000080,
-	HAL_MPEG4_LEVEL_VENDOR_START_UNUSED = 0x7F000000,
-	HAL_MPEG4_LEVEL_6  = 0x7F000001,
-	HAL_MPEG4_LEVEL_7  = 0x7F000002,
-	HAL_MPEG4_LEVEL_8  = 0x7F000003,
-	HAL_MPEG4_LEVEL_9  = 0x7F000004,
-	HAL_MPEG4_LEVEL_3b = 0x7F000005,
-	HAL_UNUSED_MPEG4_LEVEL = 0x10000000,
-};
-
-enum hal_h264_profile {
-	HAL_H264_PROFILE_BASELINE = 0x00000001,
-	HAL_H264_PROFILE_MAIN     = 0x00000002,
-	HAL_H264_PROFILE_HIGH     = 0x00000004,
-	HAL_H264_PROFILE_EXTENDED = 0x00000008,
-	HAL_H264_PROFILE_HIGH10   = 0x00000010,
-	HAL_H264_PROFILE_HIGH422  = 0x00000020,
-	HAL_H264_PROFILE_HIGH444  = 0x00000040,
-	HAL_H264_PROFILE_CONSTRAINED_HIGH  = 0x00000080,
-	HAL_UNUSED_H264_PROFILE = 0x10000000,
-};
-
-enum hal_h264_level {
-	HAL_H264_LEVEL_1  = 0x00000001,
-	HAL_H264_LEVEL_1b = 0x00000002,
-	HAL_H264_LEVEL_11 = 0x00000004,
-	HAL_H264_LEVEL_12 = 0x00000008,
-	HAL_H264_LEVEL_13 = 0x00000010,
-	HAL_H264_LEVEL_2  = 0x00000020,
-	HAL_H264_LEVEL_21 = 0x00000040,
-	HAL_H264_LEVEL_22 = 0x00000080,
-	HAL_H264_LEVEL_3  = 0x00000100,
-	HAL_H264_LEVEL_31 = 0x00000200,
-	HAL_H264_LEVEL_32 = 0x00000400,
-	HAL_H264_LEVEL_4  = 0x00000800,
-	HAL_H264_LEVEL_41 = 0x00001000,
-	HAL_H264_LEVEL_42 = 0x00002000,
-	HAL_H264_LEVEL_5  = 0x00004000,
-	HAL_H264_LEVEL_51 = 0x00008000,
-	HAL_UNUSED_H264_LEVEL = 0x10000000,
-};
-
-enum hal_vpx_profile {
-	HAL_VPX_PROFILE_SIMPLE    = 0x00000001,
-	HAL_VPX_PROFILE_ADVANCED  = 0x00000002,
-	HAL_VPX_PROFILE_VERSION_0 = 0x00000004,
-	HAL_VPX_PROFILE_VERSION_1 = 0x00000008,
-	HAL_VPX_PROFILE_VERSION_2 = 0x00000010,
-	HAL_VPX_PROFILE_VERSION_3 = 0x00000020,
-	HAL_VPX_PROFILE_UNUSED = 0x10000000,
-};
-
-enum hal_vc1_profile {
-	HAL_VC1_PROFILE_SIMPLE   = 0x00000001,
-	HAL_VC1_PROFILE_MAIN     = 0x00000002,
-	HAL_VC1_PROFILE_ADVANCED = 0x00000004,
-	HAL_UNUSED_VC1_PROFILE = 0x10000000,
-};
-
-enum hal_vc1_level {
-	HAL_VC1_LEVEL_LOW    = 0x00000001,
-	HAL_VC1_LEVEL_MEDIUM = 0x00000002,
-	HAL_VC1_LEVEL_HIGH   = 0x00000004,
-	HAL_VC1_LEVEL_0      = 0x00000008,
-	HAL_VC1_LEVEL_1      = 0x00000010,
-	HAL_VC1_LEVEL_2      = 0x00000020,
-	HAL_VC1_LEVEL_3      = 0x00000040,
-	HAL_VC1_LEVEL_4      = 0x00000080,
-	HAL_UNUSED_VC1_LEVEL = 0x10000000,
-};
-
-enum hal_divx_format {
-	HAL_DIVX_FORMAT_4,
-	HAL_DIVX_FORMAT_5,
-	HAL_DIVX_FORMAT_6,
-	HAL_UNUSED_DIVX_FORMAT = 0x10000000,
-};
-
-enum hal_divx_profile {
-	HAL_DIVX_PROFILE_QMOBILE  = 0x00000001,
-	HAL_DIVX_PROFILE_MOBILE   = 0x00000002,
-	HAL_DIVX_PROFILE_MT       = 0x00000004,
-	HAL_DIVX_PROFILE_HT       = 0x00000008,
-	HAL_DIVX_PROFILE_HD       = 0x00000010,
-	HAL_UNUSED_DIVX_PROFILE = 0x10000000,
-};
-
-enum hal_mvc_profile {
-	HAL_MVC_PROFILE_STEREO_HIGH  = 0x00000001,
-	HAL_MVC_PROFILE_MV_HIGH      = 0x00000002,
-	HAL_UNUSED_MVC_PROFILE = 0x10000000,
-};
-
-enum hal_mvc_level {
-	HAL_MVC_LEVEL_1  = 0x00000001,
-	HAL_MVC_LEVEL_1b = 0x00000002,
-	HAL_MVC_LEVEL_11 = 0x00000004,
-	HAL_MVC_LEVEL_12 = 0x00000008,
-	HAL_MVC_LEVEL_13 = 0x00000010,
-	HAL_MVC_LEVEL_2  = 0x00000020,
-	HAL_MVC_LEVEL_21 = 0x00000040,
-	HAL_MVC_LEVEL_22 = 0x00000080,
-	HAL_MVC_LEVEL_3  = 0x00000100,
-	HAL_MVC_LEVEL_31 = 0x00000200,
-	HAL_MVC_LEVEL_32 = 0x00000400,
-	HAL_MVC_LEVEL_4  = 0x00000800,
-	HAL_MVC_LEVEL_41 = 0x00001000,
-	HAL_MVC_LEVEL_42 = 0x00002000,
-	HAL_MVC_LEVEL_5  = 0x00004000,
-	HAL_MVC_LEVEL_51 = 0x00008000,
-	HAL_UNUSED_MVC_LEVEL = 0x10000000,
-};
-
-enum hal_buffer {
-	HAL_BUFFER_INPUT,
-	HAL_BUFFER_OUTPUT,
-	HAL_BUFFER_OUTPUT2,
-	HAL_BUFFER_EXTRADATA_INPUT,
-	HAL_BUFFER_EXTRADATA_OUTPUT,
-	HAL_BUFFER_EXTRADATA_OUTPUT2,
-	HAL_BUFFER_INTERNAL_SCRATCH,
-	HAL_BUFFER_INTERNAL_PERSIST,
-	HAL_BUFFER_MAX
-};
-
-struct hal_frame_rate {
-	enum hal_buffer buffer_type;
-	u32 frame_rate;
-};
-
-enum hal_uncompressed_format {
-	HAL_COLOR_FORMAT_MONOCHROME,
-	HAL_COLOR_FORMAT_NV12,
-	HAL_COLOR_FORMAT_NV21,
-	HAL_COLOR_FORMAT_NV12_4x4TILE,
-	HAL_COLOR_FORMAT_NV21_4x4TILE,
-	HAL_COLOR_FORMAT_YUYV,
-	HAL_COLOR_FORMAT_YVYU,
-	HAL_COLOR_FORMAT_UYVY,
-	HAL_COLOR_FORMAT_VYUY,
-	HAL_COLOR_FORMAT_RGB565,
-	HAL_COLOR_FORMAT_BGR565,
-	HAL_COLOR_FORMAT_RGB888,
-	HAL_COLOR_FORMAT_BGR888,
-	HAL_UNUSED_COLOR = 0x10000000,
-};
-
-struct hal_uncompressed_format_select {
-	enum hal_buffer buffer_type;
-	enum hal_uncompressed_format format;
-};
-
-struct hal_uncompressed_plane_actual {
-	int actual_stride;
-	u32 actual_plane_buffer_height;
-};
-
-struct hal_uncompressed_plane_actual_info {
-	enum hal_buffer buffer_type;
-	u32 num_planes;
-	struct hal_uncompressed_plane_actual rg_plane_format[1];
-};
-
-struct hal_uncompressed_plane_constraints {
-	u32 stride_multiples;
-	u32 max_stride;
-	u32 min_plane_buffer_height_multiple;
-	u32 buffer_alignment;
-};
-
-struct hal_uncompressed_plane_actual_constraints_info {
-	enum hal_buffer buffer_type;
-	u32 num_planes;
-	struct hal_uncompressed_plane_constraints rg_plane_format[1];
-};
-
-struct hal_extra_data_header_config {
-	u32 type;
-	enum hal_buffer buffer_type;
-	u32 version;
-	u32 port_index;
-	u32 client_extradata_id;
-};
-
-struct hal_frame_size {
-	enum hal_buffer buffer_type;
-	u32 width;
-	u32 height;
-};
-
-struct hal_enable {
-	u32 enable;
-};
-
-struct hal_buffer_count_actual {
-	enum hal_buffer buffer_type;
-	u32 buffer_count_actual;
-};
-
-enum hal_nal_stream_format {
-	HAL_NAL_FORMAT_STARTCODES         = 0x00000001,
-	HAL_NAL_FORMAT_ONE_NAL_PER_BUFFER = 0x00000002,
-	HAL_NAL_FORMAT_ONE_BYTE_LENGTH    = 0x00000004,
-	HAL_NAL_FORMAT_TWO_BYTE_LENGTH    = 0x00000008,
-	HAL_NAL_FORMAT_FOUR_BYTE_LENGTH   = 0x00000010,
-};
-
-enum hal_output_order {
-	HAL_OUTPUT_ORDER_DISPLAY,
-	HAL_OUTPUT_ORDER_DECODE,
-	HAL_UNUSED_OUTPUT = 0x10000000,
-};
-
-enum hal_picture {
-	HAL_PICTURE_I = 0x01,
-	HAL_PICTURE_P = 0x02,
-	HAL_PICTURE_B = 0x04,
-	HAL_PICTURE_IDR = 0x7F001000,
-	HAL_FRAME_NOTCODED = 0x7F002000,
-	HAL_FRAME_YUV = 0x7F004000,
-	HAL_UNUSED_PICT = 0x10000000,
-};
-
-struct hal_extradata_enable {
-	u32 enable;
-	enum hal_extradata_id index;
-};
-
-struct hal_enable_picture {
-	u32 picture_type;
-};
-
-struct hal_multi_stream {
-	enum hal_buffer buffer_type;
-	u32 enable;
-	u32 width;
-	u32 height;
-};
-
-struct hal_display_picture_buffer_count {
-	u32 enable;
-	u32 count;
-};
-
-struct hal_mb_error_map {
-	u32 error_map_size;
-	u8 rg_error_map[1];
-};
-
-struct hal_request_iframe {
-	u32 enable;
-};
-
-struct hal_bitrate {
-	u32 bit_rate;
-};
-
-struct hal_profile_level {
-	u32 profile;
-	u32 level;
-};
-/*
-struct hal_profile_level_range {
-	u32 profile;
-	u32 min_level;
-	u32 max_level;
-}
-
-struct hal_profile_level_supported {
-	u32 profile_count;
-	struct hal_profile_level_range profile_level[1];
-};
-*/
-enum hal_h264_entropy {
-	HAL_H264_ENTROPY_CAVLC,
-	HAL_H264_ENTROPY_CABAC,
-	HAL_UNUSED_ENTROPY = 0x10000000,
-};
-
-enum hal_h264_cabac_model {
-	HAL_H264_CABAC_MODEL_0,
-	HAL_H264_CABAC_MODEL_1,
-	HAL_H264_CABAC_MODEL_2,
-	HAL_UNUSED_CABAC = 0x10000000,
-};
-
-struct hal_h264_entropy_control {
-	enum hal_h264_entropy entropy_mode;
-	enum hal_h264_cabac_model cabac_model;
-};
-
-enum hal_rate_control {
-	HAL_RATE_CONTROL_OFF,
-	HAL_RATE_CONTROL_VBR_VFR,
-	HAL_RATE_CONTROL_VBR_CFR,
-	HAL_RATE_CONTROL_CBR_VFR,
-	HAL_RATE_CONTROL_CBR_CFR,
-	HAL_UNUSED_RC = 0x10000000,
-};
-
-struct hal_mpeg4_time_resolution {
-	u32 time_increment_resolution;
-};
-
-struct hal_mpeg4_header_extension {
-	u32 header_extension;
-};
-
-enum hal_h264_db_mode {
-	HAL_H264_DB_MODE_DISABLE,
-	HAL_H264_DB_MODE_SKIP_SLICE_BOUNDARY,
-	HAL_H264_DB_MODE_ALL_BOUNDARY,
-	HAL_UNUSED_H264_DB = 0x10000000,
-};
-
-struct hal_h264_db_control {
-	enum hal_h264_db_mode mode;
-	int slice_alpha_offset;
-	int slice_beta_offset;
-};
-
-struct hal_temporal_spatial_tradeoff {
-	u32 ts_factor;
-};
-
-struct hal_quantization {
-	u32 qpi;
-	u32 qpp;
-	u32 qpb;
-};
-
-struct hal_intra_period {
-	u32 pframes;
-	u32 bframes;
-};
-
-struct hal_idr_period {
-	u32 idr_period;
-};
-
-enum hal_rotate {
-	HAL_ROTATE_NONE,
-	HAL_ROTATE_90,
-	HAL_ROTATE_180,
-	HAL_ROTATE_270,
-	HAL_UNUSED_ROTATE = 0x10000000,
-};
-
-enum hal_flip {
-	HAL_FLIP_NONE,
-	HAL_FLIP_HORIZONTAL,
-	HAL_FLIP_VERTICAL,
-	HAL_UNUSED_FLIP = 0x10000000,
-};
-
-struct hal_operations {
-	enum hal_rotate rotate;
-	enum hal_flip flip;
-};
-
-enum hal_intra_refresh_mode {
-	HAL_INTRA_REFRESH_NONE,
-	HAL_INTRA_REFRESH_CYCLIC,
-	HAL_INTRA_REFRESH_ADAPTIVE,
-	HAL_INTRA_REFRESH_CYCLIC_ADAPTIVE,
-	HAL_INTRA_REFRESH_RANDOM,
-	HAL_UNUSED_INTRA = 0x10000000,
-};
-
-struct hal_intra_refresh {
-	enum hal_intra_refresh_mode mode;
-	u32 air_mbs;
-	u32 air_ref;
-	u32 cir_mbs;
-};
-
-enum hal_multi_slice {
-	HAL_MULTI_SLICE_OFF,
-	HAL_MULTI_SLICE_BY_MB_COUNT,
-	HAL_MULTI_SLICE_BY_BYTE_COUNT,
-	HAL_MULTI_SLICE_GOB,
-	HAL_UNUSED_SLICE = 0x10000000,
-};
-
-struct hal_multi_slice_control {
-	enum hal_multi_slice multi_slice;
-	u32 slice_size;
-};
-
-struct hal_debug_config {
-	u32 debug_config;
-};
-
-struct hal_buffer_requirements {
-	enum hal_buffer buffer_type;
-	u32 buffer_size;
-	u32 buffer_region_size;
-	u32 buffer_hold_count;
-	u32 buffer_count_min;
-	u32 buffer_count_actual;
-	u32 contiguous;
-	u32 buffer_alignment;
-};
-
-enum hal_priority {/* Priority increases with number */
-	HAL_PRIORITY_LOW = 10,
-	HAL_PRIOIRTY_MEDIUM = 20,
-	HAL_PRIORITY_HIGH = 30,
-	HAL_UNUSED_PRIORITY = 0x10000000,
-};
-
-struct hal_batch_info {
-	u32 input_batch_count;
-	u32 output_batch_count;
-};
-
-struct hal_metadata_pass_through {
-	u32 enable;
-	u32 size;
-};
-
-struct hal_uncompressed_format_supported {
-	enum hal_buffer buffer_type;
-	u32 format_entries;
-	u32 rg_format_info[1];
-};
-
-enum hal_interlace_format {
-	HAL_INTERLACE_FRAME_PROGRESSIVE                 = 0x01,
-	HAL_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST    = 0x02,
-	HAL_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST = 0x04,
-	HAL_INTERLACE_FRAME_TOPFIELDFIRST               = 0x08,
-	HAL_INTERLACE_FRAME_BOTTOMFIELDFIRST            = 0x10,
-	HAL_UNUSED_INTERLACE = 0x10000000,
-};
-
-struct hal_interlace_format_supported {
-	enum hal_buffer buffer_type;
-	enum hal_interlace_format format;
-};
-
-enum hal_chroma_site {
-	HAL_CHROMA_SITE_0,
-	HAL_CHROMA_SITE_1,
-	HAL_UNUSED_CHROMA = 0x10000000,
-};
-
-struct hal_properties_supported {
-	u32 num_properties;
-	u32 rg_properties[1];
-};
-
-enum hal_capability {
-	HAL_CAPABILITY_FRAME_WIDTH,
-	HAL_CAPABILITY_FRAME_HEIGHT,
-	HAL_CAPABILITY_MBS_PER_FRAME,
-	HAL_CAPABILITY_MBS_PER_SECOND,
-	HAL_CAPABILITY_FRAMERATE,
-	HAL_CAPABILITY_SCALE_X,
-	HAL_CAPABILITY_SCALE_Y,
-	HAL_CAPABILITY_BITRATE,
-	HAL_UNUSED_CAPABILITY = 0x10000000,
-};
-
-struct hal_capability_supported {
-	enum hal_capability capability_type;
-	u32 min;
-	u32 max;
-	u32 step_size;
-};
-
-struct hal_capability_supported_info {
-	u32 num_capabilities;
-	struct hal_capability_supported rg_data[1];
-};
-
-struct hal_nal_stream_format_supported {
-	u32 nal_stream_format_supported;
-};
-
-struct hal_multi_view_format {
-	u32 views;
-	u32 rg_view_order[1];
-};
-
-struct hal_seq_header_info {
-	u32 nax_header_len;
-};
-
-struct hal_codec_supported {
-	u32 decoder_codec_supported;
-	u32 encoder_codec_supported;
-};
-
-struct hal_multi_view_select {
-	u32 view_index;
-};
-
-struct hal_timestamp_scale {
-	u32 time_stamp_scale;
-};
-
-enum vidc_resource_id {
-	VIDC_RESOURCE_OCMEM = 0x00000001,
-	VIDC_UNUSED_RESORUCE = 0x10000000,
-};
-
-struct vidc_resource_hdr {
-	enum vidc_resource_id resource_id;
-	u32 resource_handle;
-	u32 size;
-};
-
-struct vidc_buffer_addr_info {
-	enum hal_buffer buffer_type;
-	u32 buffer_size;
-	u32 num_buffers;
-	u32 align_device_addr;
-	u32 extradata_size;
-	u32 extradata_addr;
-	u32 response_required;
-};
-
-struct hal_buffer_info {
-	u32 buffer_addr;
-	u32 extra_data_addr;
-};
-
-struct vidc_frame_plane_config {
-	u32 left;
-	u32 top;
-	u32 width;
-	u32 height;
-	u32 stride;
-	u32 scan_lines;
-};
-
-struct vidc_uncompressed_frame_config {
-	struct vidc_frame_plane_config luma_plane;
-	struct vidc_frame_plane_config chroma_plane;
-};
-
-struct vidc_frame_data {
-	enum hal_buffer buffer_type;
-	u32 device_addr;
-	u32 extradata_addr;
-	int64_t timestamp;
-	u32 flags;
-	u32 offset;
-	u32 alloc_len;
-	u32 filled_len;
-	u32 mark_target;
-	u32 mark_data;
-	u32 clnt_data;
-};
-
-struct vidc_seq_hdr {
-	u8 *seq_hdr;
-	u32 seq_hdr_len;
-};
-
-enum hal_flush {
-	HAL_FLUSH_INPUT,
-	HAL_FLUSH_OUTPUT,
-	HAL_FLUSH_OUTPUT2,
-	HAL_FLUSH_ALL,
-	HAL_UNUSED_FLUSH = 0x10000000,
-};
-
-enum hal_event_type {
-	HAL_EVENT_SEQ_CHANGED_SUFFICIENT_RESOURCES,
-	HAL_EVENT_SEQ_CHANGED_INSUFFICIENT_RESOURCES,
-	HAL_UNUSED_SEQCHG = 0x10000000,
-};
-
-/* HAL Response */
-
-enum command_response {
-/* SYSTEM COMMANDS_DONE*/
-	VIDC_EVENT_CHANGE,
-	SYS_INIT_DONE,
-	SET_RESOURCE_DONE,
-	RELEASE_RESOURCE_DONE,
-	PING_ACK_DONE,
-	PC_PREP_DONE,
-	SYS_IDLE,
-	SYS_DEBUG,
-	SYS_WATCHDOG_TIMEOUT,
-	SYS_ERROR,
-/* SESSION COMMANDS_DONE */
-	SESSION_LOAD_RESOURCE_DONE,
-	SESSION_INIT_DONE,
-	SESSION_END_DONE,
-	SESSION_ABORT_DONE,
-	SESSION_START_DONE,
-	SESSION_STOP_DONE,
-	SESSION_ETB_DONE,
-	SESSION_FTB_DONE,
-	SESSION_FLUSH_DONE,
-	SESSION_SUSPEND_DONE,
-	SESSION_RESUME_DONE,
-	SESSION_SET_PROP_DONE,
-	SESSION_GET_PROP_DONE,
-	SESSION_PARSE_SEQ_HDR_DONE,
-	SESSION_GET_SEQ_HDR_DONE,
-	SESSION_RELEASE_BUFFER_DONE,
-	SESSION_RELEASE_RESOURCE_DONE,
-	SESSION_PROPERTY_INFO,
-	SESSION_ERROR,
-	RESPONSE_UNUSED = 0x10000000,
-};
-
-/* Command Callback structure */
-
-struct msm_vidc_cb_cmd_done {
-	u32 device_id;
-	u32 session_id;
-	u32 status;
-	u32 size;
-	void *data;
-};
-
-struct msm_vidc_cb_event {
-	u32 device_id;
-	u32 session_id;
-	u32 status;
-	u32 height;
-	u32 width;
-	u32 hal_event_type;
-};
-
-/* Data callback structure */
-
-struct vidc_hal_ebd {
-	u32 timestamp_hi;
-	u32 timestamp_lo;
-	u32 flags;
-	u32 mark_target;
-	u32 mark_data;
-	u32 stats;
-	u32 offset;
-	u32 alloc_len;
-	u32 filled_len;
-	enum hal_picture picture_type;
-	u8 *packet_buffer;
-	u8 *extra_data_buffer;
-};
-
-struct vidc_hal_fbd {
-	u32 stream_id;
-	u32 view_id;
-	u32 timestamp_hi;
-	u32 timestamp_lo;
-	u32 flags1;
-	u32 mark_target;
-	u32 mark_data;
-	u32 stats;
-	u32 alloc_len1;
-	u32 filled_len1;
-	u32 offset1;
-	u32 frame_width;
-	u32 frame_height;
-	u32 start_xCoord;
-	u32 start_yCoord;
-	u32 input_tag;
-	u32 input_tag1;
-	enum hal_picture picture_type;
-	u8 *packet_buffer1;
-	u8 *extra_data_buffer;
-	u32 flags2;
-	u32 alloc_len2;
-	u32 filled_len2;
-	u32 offset2;
-	u8 *packet_buffer2;
-	u32 flags3;
-	u32 alloc_len3;
-	u32 filled_len3;
-	u32 offset3;
-	u8 *packet_buffer3;
-	enum hal_buffer buffer_type;
-};
-
-struct msm_vidc_cb_data_done {
-	u32 device_id;
-	u32 session_id;
-	u32 status;
-	u32 size;
-	void *clnt_data;
-	union {
-		struct vidc_hal_ebd input_done;
-		struct vidc_hal_fbd output_done;
-	};
-};
-
-struct vidc_hal_sys_init_done {
-	u32 enc_codec_supported;
-	u32 dec_codec_supported;
-};
-
-struct vidc_hal_session_init_done {
-	struct hal_capability_supported width;
-	struct hal_capability_supported height;
-	struct hal_capability_supported mbs_per_frame;
-	struct hal_capability_supported mbs_per_sec;
-	struct hal_capability_supported frame_rate;
-	struct hal_capability_supported scale_x;
-	struct hal_capability_supported scale_y;
-	struct hal_capability_supported bitrate;
-	struct hal_uncompressed_format_supported uncomp_format;
-	struct hal_interlace_format_supported HAL_format;
-	struct hal_nal_stream_format_supported nal_stream_format;
-/*	struct hal_profile_level_supported profile_level;
-	// allocate and released memory for above. */
-	struct hal_intra_refresh intra_refresh;
-	struct hal_seq_header_info seq_hdr_info;
-};
-
-struct buffer_requirements {
-	struct hal_buffer_requirements buffer[HAL_BUFFER_MAX];
-};
-
-/* VIDC_HAL CORE API's */
-int vidc_hal_core_init(void *device, int domain);
-int vidc_hal_core_release(void *device);
-int vidc_hal_core_pc_prep(void *device);
-int vidc_hal_core_set_resource(void *device,
-	struct vidc_resource_hdr *resource_hdr, void *resource_value);
-int vidc_hal_core_release_resource(void *device,
-	struct vidc_resource_hdr *resource_hdr);
-int vidc_hal_core_ping(void *device);
-
-/* VIDC_HAL SESSION API's */
-void *vidc_hal_session_init(void *device, u32 session_id,
-	enum hal_domain session_type, enum hal_video_codec codec_type);
-int vidc_hal_session_end(void *session);
-int vidc_hal_session_abort(void *session);
-int vidc_hal_session_set_buffers(void *sess,
-	struct vidc_buffer_addr_info *buffer_info);
-int vidc_hal_session_release_buffers(void *sess,
-	struct vidc_buffer_addr_info *buffer_info);
-int vidc_hal_session_load_res(void *sess);
-int vidc_hal_session_release_res(void *sess);
-int vidc_hal_session_start(void *sess);
-int vidc_hal_session_stop(void *sess);
-int vidc_hal_session_suspend(void *sess);
-int vidc_hal_session_resume(void *sess);
-int vidc_hal_session_etb(void *sess,
-	struct vidc_frame_data *input_frame);
-int vidc_hal_session_ftb(void *sess,
-	struct vidc_frame_data *output_frame);
-int vidc_hal_session_parse_seq_hdr(void *sess,
-	struct vidc_seq_hdr *seq_hdr);
-int vidc_hal_session_get_seq_hdr(void *sess,
-	struct vidc_seq_hdr *seq_hdr);
-int vidc_hal_session_get_buf_req(void *sess);
-int vidc_hal_session_flush(void *sess, enum hal_flush flush_mode);
-int vidc_hal_session_set_property(void *sess, enum hal_property ptype,
-								  void *pdata);
-int vidc_hal_session_get_property(void *sess, enum hal_property ptype,
-								  void *pdata);
-void *vidc_hal_add_device(u32 device_id, u32 base_addr,
-	u32 reg_base, u32 reg_size, u32 irq,
-	void (*callback) (enum command_response cmd, void *data));
-void vidc_hal_delete_device(void *device);
-
-#endif /*__VIDC_HAL_API_H__ */
diff --git a/drivers/media/video/msm_vidc/vidc_hal_helper.h b/drivers/media/video/msm_vidc/vidc_hal_helper.h
deleted file mode 100644
index 9f805d7..0000000
--- a/drivers/media/video/msm_vidc/vidc_hal_helper.h
+++ /dev/null
@@ -1,874 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 __H_VIDC_HAL_HELPER_H__
-#define __H_VIDC_HAL_HELPER_H__
-
-#define HFI_COMMON_BASE				(0)
-#define HFI_OX_BASE					(0x01000000)
-
-#define HFI_VIDEO_DOMAIN_ENCODER	(HFI_COMMON_BASE + 0x1)
-#define HFI_VIDEO_DOMAIN_DECODER	(HFI_COMMON_BASE + 0x2)
-#define HFI_VIDEO_DOMAIN_VPE		(HFI_COMMON_BASE + 0x4)
-#define HFI_VIDEO_DOMAIN_MBI		(HFI_COMMON_BASE + 0x8)
-
-#define HFI_DOMAIN_BASE_COMMON		(HFI_COMMON_BASE + 0)
-#define HFI_DOMAIN_BASE_VDEC		(HFI_COMMON_BASE + 0x01000000)
-#define HFI_DOMAIN_BASE_VENC		(HFI_COMMON_BASE + 0x02000000)
-#define HFI_DOMAIN_BASE_VPE			(HFI_COMMON_BASE + 0x03000000)
-
-#define HFI_VIDEO_ARCH_OX			(HFI_COMMON_BASE + 0x1)
-
-#define HFI_ARCH_COMMON_OFFSET		(0)
-#define HFI_ARCH_OX_OFFSET			(0x00200000)
-
-#define  HFI_CMD_START_OFFSET		(0x00010000)
-#define  HFI_MSG_START_OFFSET		(0x00020000)
-
-#define HFI_ERR_NONE						HFI_COMMON_BASE
-#define HFI_ERR_SYS_FATAL				(HFI_COMMON_BASE + 0x1)
-#define HFI_ERR_SYS_INVALID_PARAMETER		(HFI_COMMON_BASE + 0x2)
-#define HFI_ERR_SYS_VERSION_MISMATCH		(HFI_COMMON_BASE + 0x3)
-#define HFI_ERR_SYS_INSUFFICIENT_RESOURCES	(HFI_COMMON_BASE + 0x4)
-#define HFI_ERR_SYS_MAX_SESSIONS_REACHED	(HFI_COMMON_BASE + 0x5)
-#define HFI_ERR_SYS_UNSUPPORTED_CODEC		(HFI_COMMON_BASE + 0x6)
-#define HFI_ERR_SYS_SESSION_IN_USE			(HFI_COMMON_BASE + 0x7)
-#define HFI_ERR_SYS_SESSION_ID_OUT_OF_RANGE	(HFI_COMMON_BASE + 0x8)
-#define HFI_ERR_SYS_UNSUPPORTED_DOMAIN		(HFI_COMMON_BASE + 0x9)
-
-#define HFI_ERR_SESSION_FATAL			(HFI_COMMON_BASE + 0x1001)
-#define HFI_ERR_SESSION_INVALID_PARAMETER	(HFI_COMMON_BASE + 0x1002)
-#define HFI_ERR_SESSION_BAD_POINTER		(HFI_COMMON_BASE + 0x1003)
-#define HFI_ERR_SESSION_INVALID_SESSION_ID	(HFI_COMMON_BASE + 0x1004)
-#define HFI_ERR_SESSION_INVALID_STREAM_ID	(HFI_COMMON_BASE + 0x1005)
-#define HFI_ERR_SESSION_INCORRECT_STATE_OPERATION		\
-	(HFI_COMMON_BASE + 0x1006)
-#define HFI_ERR_SESSION_UNSUPPORTED_PROPERTY	(HFI_COMMON_BASE + 0x1007)
-
-#define HFI_ERR_SESSION_UNSUPPORTED_SETTING	(HFI_COMMON_BASE + 0x1008)
-
-#define HFI_ERR_SESSION_INSUFFICIENT_RESOURCES	(HFI_COMMON_BASE + 0x1009)
-
-#define HFI_ERR_SESSION_STREAM_CORRUPT_OUTPUT_STALLED	\
-	(HFI_COMMON_BASE + 0x100A)
-
-#define HFI_ERR_SESSION_STREAM_CORRUPT		(HFI_COMMON_BASE + 0x100B)
-#define HFI_ERR_SESSION_ENC_OVERFLOW		(HFI_COMMON_BASE + 0x100C)
-#define  HFI_ERR_SESSION_UNSUPPORTED_STREAM	(HFI_COMMON_BASE + 0x100D)
-
-#define HFI_EVENT_SYS_ERROR				(HFI_COMMON_BASE + 0x1)
-#define HFI_EVENT_SESSION_ERROR			(HFI_COMMON_BASE + 0x2)
-
-#define HFI_VIDEO_CODEC_H264				0x00000002
-#define HFI_VIDEO_CODEC_H263				0x00000004
-#define HFI_VIDEO_CODEC_MPEG1				0x00000008
-#define HFI_VIDEO_CODEC_MPEG2				0x00000010
-#define HFI_VIDEO_CODEC_MPEG4				0x00000020
-#define HFI_VIDEO_CODEC_DIVX_311			0x00000040
-#define HFI_VIDEO_CODEC_DIVX				0x00000080
-#define HFI_VIDEO_CODEC_VC1					0x00000100
-#define HFI_VIDEO_CODEC_SPARK				0x00000200
-#define HFI_VIDEO_CODEC_VP8					0x00001000
-
-#define HFI_H264_PROFILE_BASELINE			0x00000001
-#define HFI_H264_PROFILE_MAIN				0x00000002
-#define HFI_H264_PROFILE_HIGH				0x00000004
-#define HFI_H264_PROFILE_STEREO_HIGH		0x00000008
-#define HFI_H264_PROFILE_MULTIVIEW_HIGH		0x00000010
-#define HFI_H264_PROFILE_CONSTRAINED_BASE	0x00000020
-#define HFI_H264_PROFILE_CONSTRAINED_HIGH	0x00000040
-
-#define HFI_H264_LEVEL_1					0x00000001
-#define HFI_H264_LEVEL_1b					0x00000002
-#define HFI_H264_LEVEL_11					0x00000004
-#define HFI_H264_LEVEL_12					0x00000008
-#define HFI_H264_LEVEL_13					0x00000010
-#define HFI_H264_LEVEL_2					0x00000020
-#define HFI_H264_LEVEL_21					0x00000040
-#define HFI_H264_LEVEL_22					0x00000080
-#define HFI_H264_LEVEL_3					0x00000100
-#define HFI_H264_LEVEL_31					0x00000200
-#define HFI_H264_LEVEL_32					0x00000400
-#define HFI_H264_LEVEL_4					0x00000800
-#define HFI_H264_LEVEL_41					0x00001000
-#define HFI_H264_LEVEL_42					0x00002000
-#define HFI_H264_LEVEL_5					0x00004000
-#define HFI_H264_LEVEL_51					0x00008000
-
-#define HFI_H263_PROFILE_BASELINE			0x00000001
-
-#define HFI_H263_LEVEL_10					0x00000001
-#define HFI_H263_LEVEL_20					0x00000002
-#define HFI_H263_LEVEL_30					0x00000004
-#define HFI_H263_LEVEL_40					0x00000008
-#define HFI_H263_LEVEL_45					0x00000010
-#define HFI_H263_LEVEL_50					0x00000020
-#define HFI_H263_LEVEL_60					0x00000040
-#define HFI_H263_LEVEL_70					0x00000080
-
-#define HFI_MPEG2_PROFILE_SIMPLE			0x00000001
-#define HFI_MPEG2_PROFILE_MAIN				0x00000002
-#define HFI_MPEG2_PROFILE_422				0x00000004
-#define HFI_MPEG2_PROFILE_SNR				0x00000008
-#define HFI_MPEG2_PROFILE_SPATIAL			0x00000010
-#define HFI_MPEG2_PROFILE_HIGH				0x00000020
-
-#define HFI_MPEG2_LEVEL_LL					0x00000001
-#define HFI_MPEG2_LEVEL_ML					0x00000002
-#define HFI_MPEG2_LEVEL_H14					0x00000004
-#define HFI_MPEG2_LEVEL_HL					0x00000008
-
-#define HFI_MPEG4_PROFILE_SIMPLE			0x00000001
-#define HFI_MPEG4_PROFILE_ADVANCEDSIMPLE	0x00000002
-
-#define HFI_MPEG4_LEVEL_0					0x00000001
-#define HFI_MPEG4_LEVEL_0b					0x00000002
-#define HFI_MPEG4_LEVEL_1					0x00000004
-#define HFI_MPEG4_LEVEL_2					0x00000008
-#define HFI_MPEG4_LEVEL_3					0x00000010
-#define HFI_MPEG4_LEVEL_4					0x00000020
-#define HFI_MPEG4_LEVEL_4a					0x00000040
-#define HFI_MPEG4_LEVEL_5					0x00000080
-#define HFI_MPEG4_LEVEL_6					0x00000100
-#define HFI_MPEG4_LEVEL_7					0x00000200
-#define HFI_MPEG4_LEVEL_8					0x00000400
-#define HFI_MPEG4_LEVEL_9					0x00000800
-#define HFI_MPEG4_LEVEL_3b					0x00001000
-
-#define HFI_VC1_PROFILE_SIMPLE				0x00000001
-#define HFI_VC1_PROFILE_MAIN				0x00000002
-#define HFI_VC1_PROFILE_ADVANCED			0x00000004
-
-#define HFI_VC1_LEVEL_LOW					0x00000001
-#define HFI_VC1_LEVEL_MEDIUM				0x00000002
-#define HFI_VC1_LEVEL_HIGH					0x00000004
-#define HFI_VC1_LEVEL_0						0x00000008
-#define HFI_VC1_LEVEL_1						0x00000010
-#define HFI_VC1_LEVEL_2						0x00000020
-#define HFI_VC1_LEVEL_3						0x00000040
-#define HFI_VC1_LEVEL_4						0x00000080
-
-#define HFI_VPX_PROFILE_SIMPLE				0x00000001
-#define HFI_VPX_PROFILE_ADVANCED			0x00000002
-#define HFI_VPX_PROFILE_VERSION_0			0x00000004
-#define HFI_VPX_PROFILE_VERSION_1			0x00000008
-#define HFI_VPX_PROFILE_VERSION_2			0x00000010
-#define HFI_VPX_PROFILE_VERSION_3			0x00000020
-
-#define HFI_DIVX_FORMAT_4				(HFI_COMMON_BASE + 0x1)
-#define HFI_DIVX_FORMAT_5				(HFI_COMMON_BASE + 0x2)
-#define HFI_DIVX_FORMAT_6				(HFI_COMMON_BASE + 0x3)
-
-#define HFI_DIVX_PROFILE_QMOBILE		0x00000001
-#define HFI_DIVX_PROFILE_MOBILE			0x00000002
-#define HFI_DIVX_PROFILE_MT				0x00000004
-#define HFI_DIVX_PROFILE_HT				0x00000008
-#define HFI_DIVX_PROFILE_HD				0x00000010
-
-#define HFI_BUFFER_INPUT				(HFI_COMMON_BASE + 0x1)
-#define HFI_BUFFER_OUTPUT				(HFI_COMMON_BASE + 0x2)
-#define HFI_BUFFER_OUTPUT2				(HFI_COMMON_BASE + 0x3)
-#define HFI_BUFFER_INTERNAL_PERSIST		(HFI_COMMON_BASE + 0x4)
-
-struct hfi_buffer_info {
-	u32 buffer_addr;
-	u32 extra_data_addr;
-};
-
-#define HFI_PROPERTY_SYS_COMMON_START		\
-	(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET + 0x0000)
-#define HFI_PROPERTY_SYS_DEBUG_CONFIG		\
-	(HFI_PROPERTY_SYS_COMMON_START + 0x001)
-#define HFI_PROPERTY_SYS_RESOURCE_OCMEM_REQUIREMENT_INFO	\
-	(HFI_PROPERTY_SYS_COMMON_START + 0x002)
-#define HFI_PROPERTY_SYS_CONFIG_VCODEC_CLKFREQ				\
-	(HFI_PROPERTY_SYS_COMMON_START + 0x003)
-
-#define HFI_PROPERTY_PARAM_COMMON_START	\
-	(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET + 0x1000)
-#define HFI_PROPERTY_PARAM_FRAME_SIZE		\
-	(HFI_PROPERTY_PARAM_COMMON_START + 0x001)
-#define HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO	\
-	(HFI_PROPERTY_PARAM_COMMON_START + 0x002)
-#define HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT		\
-	(HFI_PROPERTY_PARAM_COMMON_START + 0x003)
-#define HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SUPPORTED	\
-	(HFI_PROPERTY_PARAM_COMMON_START + 0x004)
-#define HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT			\
-	(HFI_PROPERTY_PARAM_COMMON_START + 0x005)
-#define HFI_PROPERTY_PARAM_PROFILE_LEVEL_SUPPORTED			\
-	(HFI_PROPERTY_PARAM_COMMON_START + 0x006)
-#define HFI_PROPERTY_PARAM_CAPABILITY_SUPPORTED				\
-	(HFI_PROPERTY_PARAM_COMMON_START + 0x007)
-#define HFI_PROPERTY_PARAM_PROPERTIES_SUPPORTED				\
-	(HFI_PROPERTY_PARAM_COMMON_START + 0x008)
-#define HFI_PROPERTY_PARAM_CODEC_SUPPORTED			\
-	(HFI_PROPERTY_PARAM_COMMON_START + 0x009)
-#define HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SUPPORTED		\
-	(HFI_PROPERTY_PARAM_COMMON_START + 0x00A)
-#define HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SELECT			\
-	(HFI_PROPERTY_PARAM_COMMON_START + 0x00B)
-#define HFI_PROPERTY_PARAM_MULTI_VIEW_FORMAT				\
-	(HFI_PROPERTY_PARAM_COMMON_START + 0x00C)
-#define  HFI_PROPERTY_PARAM_MAX_SEQUENCE_HEADER_SIZE        \
-	(HFI_PROPERTY_PARAM_COMMON_START + 0x00D)
-#define  HFI_PROPERTY_PARAM_CODEC_MASK_SUPPORTED            \
-	(HFI_PROPERTY_PARAM_COMMON_START + 0x00E)
-#define HFI_PROPERTY_PARAM_MVC_BUFFER_LAYOUT \
-	(HFI_PROPERTY_PARAM_COMMON_START + 0x00F)
-
-#define HFI_PROPERTY_CONFIG_COMMON_START				\
-	(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET + 0x2000)
-#define HFI_PROPERTY_CONFIG_FRAME_RATE					\
-	(HFI_PROPERTY_CONFIG_COMMON_START + 0x001)
-
-#define HFI_PROPERTY_PARAM_VDEC_COMMON_START				\
-	(HFI_DOMAIN_BASE_VDEC + HFI_ARCH_COMMON_OFFSET + 0x3000)
-#define HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM				\
-	(HFI_PROPERTY_PARAM_VDEC_COMMON_START + 0x001)
-#define  HFI_PROPERTY_PARAM_VDEC_CONCEAL_COLOR              \
-	(HFI_PROPERTY_PARAM_VDEC_COMMON_START + 0x002)
-
-#define HFI_PROPERTY_CONFIG_VDEC_COMMON_START				\
-	(HFI_DOMAIN_BASE_VDEC + HFI_ARCH_COMMON_OFFSET + 0x4000)
-
-#define HFI_PROPERTY_PARAM_VENC_COMMON_START				\
-	(HFI_DOMAIN_BASE_VENC + HFI_ARCH_COMMON_OFFSET + 0x5000)
-#define HFI_PROPERTY_PARAM_VENC_SLICE_DELIVERY_MODE			\
-	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x001)
-#define HFI_PROPERTY_PARAM_VENC_H264_ENTROPY_CONTROL		\
-	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x002)
-#define HFI_PROPERTY_PARAM_VENC_H264_DEBLOCK_CONTROL		\
-	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x003)
-#define HFI_PROPERTY_PARAM_VENC_RATE_CONTROL				\
-	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x004)
-#define  HFI_PROPERTY_PARAM_VENC_H264_PICORDER_CNT_TYPE     \
-	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x005)
-#define HFI_PROPERTY_PARAM_VENC_SESSION_QP				\
-	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x006)
-#define HFI_PROPERTY_PARAM_VENC_MPEG4_AC_PREDICTION			\
-	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x007)
-#define  HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE           \
-	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x008)
-#define HFI_PROPERTY_PARAM_VENC_MPEG4_TIME_RESOLUTION		\
-	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x009)
-#define HFI_PROPERTY_PARAM_VENC_MPEG4_SHORT_HEADER			\
-	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x00A)
-#define HFI_PROPERTY_PARAM_VENC_MPEG4_HEADER_EXTENSION		\
-	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x00B)
-#define  HFI_PROPERTY_PARAM_VENC_OPEN_GOP                   \
-	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x00C)
-#define HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH				\
-	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x00D)
-#define HFI_PROPERTY_PARAM_VENC_MULTI_SLICE_CONTROL			\
-	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x00E)
-#define  HFI_PROPERTY_PARAM_VENC_VBV_HRD_BUF_SIZE           \
-	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x00F)
-#define  HFI_PROPERTY_PARAM_VENC_QUALITY_VS_SPEED           \
-	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x010)
-#define HFI_PROPERTY_PARAM_VENC_ADVANCED				\
-	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x012)
-#define  HFI_PROPERTY_PARAM_VENC_H264_SPS_ID                \
-	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x014)
-#define  HFI_PROPERTY_PARAM_VENC_H264_PPS_ID               \
-	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x015)
-#define HFI_PROPERTY_PARAM_VENC_H264_GENERATE_AUDNAL	\
-	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x016)
-#define HFI_PROPERTY_PARAM_VENC_ASPECT_RATIO			\
-	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x017)
-#define HFI_PROPERTY_PARAM_VENC_NUMREF					\
-	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x018)
-#define HFI_PROPERTY_PARAM_VENC_MULTIREF_P				\
-	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x019)
-#define HFI_PROPERTY_PARAM_VENC_HIER_P_NUM_ENH_LAYER	\
-	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01A)
-
-#define HFI_PROPERTY_PARAM_VENC_H264_NAL_SVC_EXT		\
-	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01B)
-
-#define HFI_PROPERTY_CONFIG_VENC_COMMON_START				\
-	(HFI_DOMAIN_BASE_VENC + HFI_ARCH_COMMON_OFFSET + 0x6000)
-#define HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE				\
-	(HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x001)
-#define HFI_PROPERTY_CONFIG_VENC_IDR_PERIOD				\
-	(HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x002)
-#define HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD				\
-	(HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x003)
-#define HFI_PROPERTY_CONFIG_VENC_REQUEST_SYNC_FRAME			\
-	(HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x004)
-#define  HFI_PROPERTY_CONFIG_VENC_SLICE_SIZE                \
-	(HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x005)
-#define HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE				\
-	(HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x007)
-
-#define HFI_PROPERTY_PARAM_VPE_COMMON_START				\
-	(HFI_DOMAIN_BASE_VPE + HFI_ARCH_COMMON_OFFSET + 0x7000)
-#define  HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER	\
-	(HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x008)
-
-#define HFI_PROPERTY_CONFIG_VPE_COMMON_START				\
-	(HFI_DOMAIN_BASE_VPE + HFI_ARCH_COMMON_OFFSET + 0x8000)
-#define HFI_PROPERTY_CONFIG_VPE_DEINTERLACE				\
-	(HFI_PROPERTY_CONFIG_VPE_COMMON_START + 0x001)
-#define HFI_PROPERTY_CONFIG_VPE_OPERATIONS				\
-	(HFI_PROPERTY_CONFIG_VPE_COMMON_START + 0x002)
-
-struct hfi_bitrate {
-	u32 bit_rate;
-	u32 layer_id;
-};
-
-#define HFI_CAPABILITY_FRAME_WIDTH			(HFI_COMMON_BASE + 0x1)
-#define HFI_CAPABILITY_FRAME_HEIGHT			(HFI_COMMON_BASE + 0x2)
-#define HFI_CAPABILITY_MBS_PER_FRAME		(HFI_COMMON_BASE + 0x3)
-#define HFI_CAPABILITY_MBS_PER_SECOND		(HFI_COMMON_BASE + 0x4)
-#define HFI_CAPABILITY_FRAMERATE			(HFI_COMMON_BASE + 0x5)
-#define HFI_CAPABILITY_SCALE_X				(HFI_COMMON_BASE + 0x6)
-#define HFI_CAPABILITY_SCALE_Y				(HFI_COMMON_BASE + 0x7)
-#define HFI_CAPABILITY_BITRATE				(HFI_COMMON_BASE + 0x8)
-#define  HFI_CAPABILITY_BFRAME				(HFI_COMMON_BASE + 0x9)
-#define  HFI_CAPABILITY_HIER_P_NUM_ENH_LAYERS   (HFI_COMMON_BASE + 0x10)
-
-struct hfi_capability_supported {
-	u32 capability_type;
-	u32 min;
-	u32 max;
-	u32 step_size;
-};
-
-struct hfi_capability_supported_info {
-	u32 num_capabilities;
-	struct hfi_capability_supported rg_data[1];
-};
-
-#define HFI_DEBUG_MSG_LOW					0x00000001
-#define HFI_DEBUG_MSG_MEDIUM				0x00000002
-#define HFI_DEBUG_MSG_HIGH					0x00000004
-#define HFI_DEBUG_MSG_ERROR					0x00000008
-#define HFI_DEBUG_MSG_FATAL					0x00000010
-#define HFI_DEBUG_MSG_PERF					0x00000020
-
-#define HFI_DEBUG_MODE_QUEUE				0x00000001
-#define HFI_DEBUG_MODE_QDSS					0x00000002
-
-struct hfi_debug_config {
-	u32 debug_config;
-	u32 debug_mode;
-};
-
-struct hfi_enable {
-	int enable;
-};
-
-#define HFI_H264_DB_MODE_DISABLE			(HFI_COMMON_BASE + 0x1)
-#define HFI_H264_DB_MODE_SKIP_SLICE_BOUNDARY	\
-	(HFI_COMMON_BASE + 0x2)
-#define HFI_H264_DB_MODE_ALL_BOUNDARY		(HFI_COMMON_BASE + 0x3)
-
-struct hfi_h264_db_control {
-	u32 mode;
-	int slice_alpha_offset;
-	int slice_beta_offset;
-};
-
-#define HFI_H264_ENTROPY_CAVLC				(HFI_COMMON_BASE + 0x1)
-#define HFI_H264_ENTROPY_CABAC				(HFI_COMMON_BASE + 0x2)
-
-#define HFI_H264_CABAC_MODEL_0				(HFI_COMMON_BASE + 0x1)
-#define HFI_H264_CABAC_MODEL_1				(HFI_COMMON_BASE + 0x2)
-#define HFI_H264_CABAC_MODEL_2				(HFI_COMMON_BASE + 0x3)
-
-struct hfi_h264_entropy_control {
-	u32 entropy_mode;
-	u32 cabac_model;
-};
-
-struct hfi_frame_rate {
-	u32 buffer_type;
-	u32 frame_rate;
-};
-
-#define HFI_INTRA_REFRESH_NONE				(HFI_COMMON_BASE + 0x1)
-#define HFI_INTRA_REFRESH_CYCLIC			(HFI_COMMON_BASE + 0x2)
-#define HFI_INTRA_REFRESH_ADAPTIVE			(HFI_COMMON_BASE + 0x3)
-#define HFI_INTRA_REFRESH_CYCLIC_ADAPTIVE	(HFI_COMMON_BASE + 0x4)
-#define HFI_INTRA_REFRESH_RANDOM			(HFI_COMMON_BASE + 0x5)
-
-struct hfi_intra_refresh {
-	u32 mode;
-	u32 air_mbs;
-	u32 air_ref;
-	u32 cir_mbs;
-};
-
-struct hfi_idr_period {
-	u32 idr_period;
-};
-
-struct hfi_intra_period {
-	u32 pframes;
-	u32 bframes;
-};
-
-struct hfi_mpeg4_header_extension {
-	u32 header_extension;
-};
-
-struct hfi_mpeg4_time_resolution {
-	u32 time_increment_resolution;
-};
-
-struct hfi_multi_stream {
-	u32 buffer_type;
-	u32 enable;
-	u32 width;
-	u32 height;
-};
-
-struct hfi_multi_view_format {
-	u32 views;
-	u32 rg_view_order[1];
-};
-
-#define HFI_MULTI_SLICE_OFF				(HFI_COMMON_BASE + 0x1)
-#define HFI_MULTI_SLICE_BY_MB_COUNT		(HFI_COMMON_BASE + 0x2)
-#define HFI_MULTI_SLICE_BY_BYTE_COUNT	(HFI_COMMON_BASE + 0x3)
-#define HFI_MULTI_SLICE_GOB				(HFI_COMMON_BASE + 0x4)
-
-struct hfi_multi_slice_control {
-	u32 multi_slice;
-	u32 slice_size;
-};
-
-#define HFI_NAL_FORMAT_STARTCODES			0x00000001
-#define HFI_NAL_FORMAT_ONE_NAL_PER_BUFFER	0x00000002
-#define HFI_NAL_FORMAT_ONE_BYTE_LENGTH		0x00000004
-#define HFI_NAL_FORMAT_TWO_BYTE_LENGTH		0x00000008
-#define HFI_NAL_FORMAT_FOUR_BYTE_LENGTH		0x00000010
-
-struct hfi_nal_stream_format_supported {
-	u32 nal_stream_format_supported;
-};
-
-#define HFI_PICTURE_TYPE_I					0x01
-#define HFI_PICTURE_TYPE_P					0x02
-#define HFI_PICTURE_TYPE_B					0x04
-#define HFI_PICTURE_TYPE_IDR				0x08
-
-struct hfi_profile_level {
-	u32 profile;
-	u32 level;
-};
-
-struct hfi_profile_level_supported {
-	u32 profile_count;
-	struct hfi_profile_level rg_profile_level[1];
-};
-
-struct hfi_quality_vs_speed {
-	u32 quality_vs_speed;
-};
-
-struct hfi_quantization {
-	u32 qp_i;
-	u32 qp_p;
-	u32 qp_b;
-	u32 layer_id;
-};
-
-struct hfi_quantization_range {
-	u32 min_qp;
-	u32 max_qp;
-	u32 layer_id;
-};
-
-struct hfi_frame_size {
-	u32 buffer_type;
-	u32 width;
-	u32 height;
-};
-
-#define HFI_COLOR_FORMAT_MONOCHROME			(HFI_COMMON_BASE + 0x1)
-#define HFI_COLOR_FORMAT_NV12				(HFI_COMMON_BASE + 0x2)
-#define HFI_COLOR_FORMAT_NV21				(HFI_COMMON_BASE + 0x3)
-#define HFI_COLOR_FORMAT_NV12_4x4TILE		(HFI_COMMON_BASE + 0x4)
-#define HFI_COLOR_FORMAT_NV21_4x4TILE		(HFI_COMMON_BASE + 0x5)
-#define HFI_COLOR_FORMAT_YUYV				(HFI_COMMON_BASE + 0x6)
-#define HFI_COLOR_FORMAT_YVYU				(HFI_COMMON_BASE + 0x7)
-#define HFI_COLOR_FORMAT_UYVY				(HFI_COMMON_BASE + 0x8)
-#define HFI_COLOR_FORMAT_VYUY				(HFI_COMMON_BASE + 0x9)
-#define HFI_COLOR_FORMAT_RGB565				(HFI_COMMON_BASE + 0xA)
-#define HFI_COLOR_FORMAT_BGR565				(HFI_COMMON_BASE + 0xB)
-#define HFI_COLOR_FORMAT_RGB888				(HFI_COMMON_BASE + 0xC)
-#define HFI_COLOR_FORMAT_BGR888				(HFI_COMMON_BASE + 0xD)
-
-struct hfi_uncompressed_format_select {
-	u32 buffer_type;
-	u32 format;
-};
-
-struct hfi_uncompressed_format_supported {
-	u32 buffer_type;
-	u32 format_entries;
-	u32 rg_format_info[1];
-};
-
-struct hfi_uncompressed_plane_actual {
-	int actual_stride;
-	u32 actual_plane_buffer_height;
-};
-
-struct hfi_uncompressed_plane_actual_info {
-	u32 buffer_type;
-	u32 num_planes;
-	struct hfi_uncompressed_plane_actual rg_plane_format[1];
-};
-
-struct hfi_uncompressed_plane_constraints {
-	u32 stride_multiples;
-	u32 max_stride;
-	u32 min_plane_buffer_height_multiple;
-	u32 buffer_alignment;
-};
-
-struct hfi_uncompressed_plane_info {
-	u32 format;
-	u32 num_planes;
-	struct hfi_uncompressed_plane_constraints rg_plane_format[1];
-};
-
-struct hfi_codec_supported {
-	u32 decoder_codec_supported;
-	u32 encoder_codec_supported;
-};
-
-struct hfi_properties_supported {
-	u32 num_properties;
-	u32 rg_properties[1];
-};
-
-#define HFI_ROTATE_NONE					(HFI_COMMON_BASE + 0x1)
-#define HFI_ROTATE_90					(HFI_COMMON_BASE + 0x2)
-#define HFI_ROTATE_180					(HFI_COMMON_BASE + 0x3)
-#define HFI_ROTATE_270					(HFI_COMMON_BASE + 0x4)
-
-#define HFI_FLIP_NONE					(HFI_COMMON_BASE + 0x1)
-#define HFI_FLIP_HORIZONTAL				(HFI_COMMON_BASE + 0x2)
-#define HFI_FLIP_VERTICAL				(HFI_COMMON_BASE + 0x3)
-
-struct hfi_operations {
-	u32 rotate;
-	u32 flip;
-};
-
-#define HFI_RESOURCE_OCMEM 0x00000001
-
-struct hfi_resource_ocmem {
-	u32 size;
-	u8 *mem;
-};
-
-struct hfi_resource_ocmem_requirement {
-	u32 session_domain;
-	u32 width;
-	u32 height;
-	u32 size;
-};
-
-struct hfi_resource_ocmem_requirement_info {
-	u32 num_entries;
-	struct hfi_resource_ocmem_requirement rg_requirements[1];
-};
-
-struct hfi_venc_config_advanced {
-	u8 pipe2d;
-	u8 hw_mode;
-	u8 low_delay_enforce;
-	u8 worker_vppsg_delay;
-	int close_gop;
-	int h264_constrain_intra_pred;
-	int h264_transform_8x8_flag;
-	int mpeg4_qpel_enable;
-	int multi_refp_en;
-	int qmatrix_en;
-	u8 vpp_info_packet_mode;
-	u8 ref_tile_mode;
-	u8 bitstream_flush_mode;
-	u32 vppsg_vspap_fb_sync_delay;
-	u32 rc_initial_delay;
-	u32 peak_bitrate_constraint;
-	u32 ds_display_frame_width;
-	u32 ds_display_frame_height;
-	u32 perf_tune_param_ptr;
-	u32 input_x_offset;
-	u32 input_y_offset;
-	u32 input_roi_width;
-	u32 input_roi_height;
-	u32 vsp_fifo_dma_sel;
-	u32 h264_num_ref_frames;
-};
-
-struct hfi_vbv_hrd_bufsize {
-	u32 buffer_size;
-};
-
-struct hfi_codec_mask_supported {
-	u32 codecs;
-	u32 video_domains;
-};
-
-struct hfi_seq_header_info {
-	u32 max_hader_len;
-};
-struct hfi_aspect_ratio {
-	u32 aspect_width;
-	u32 aspect_height;
-};
-#define HFI_MVC_BUFFER_LAYOUT_TOP_BOTTOM  (0)
-#define HFI_MVC_BUFFER_LAYOUT_SIDEBYSIDE  (1)
-#define HFI_MVC_BUFFER_LAYOUT_SEQ         (2)
-struct hfi_mvc_buffer_lauout_descp_type {
-	u32    layout_type;
-	u32    bright_view_first;
-	u32    ngap;
-};
-
-
-#define HFI_CMD_SYS_COMMON_START			\
-(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET + HFI_CMD_START_OFFSET \
-	+ 0x0000)
-#define HFI_CMD_SYS_INIT		(HFI_CMD_SYS_COMMON_START + 0x001)
-#define HFI_CMD_SYS_PC_PREP		(HFI_CMD_SYS_COMMON_START + 0x002)
-#define HFI_CMD_SYS_SET_RESOURCE	(HFI_CMD_SYS_COMMON_START + 0x003)
-#define HFI_CMD_SYS_RELEASE_RESOURCE (HFI_CMD_SYS_COMMON_START + 0x004)
-#define HFI_CMD_SYS_SET_PROPERTY	(HFI_CMD_SYS_COMMON_START + 0x005)
-#define HFI_CMD_SYS_GET_PROPERTY	(HFI_CMD_SYS_COMMON_START + 0x006)
-#define HFI_CMD_SYS_SESSION_INIT	(HFI_CMD_SYS_COMMON_START + 0x007)
-#define HFI_CMD_SYS_SESSION_END		(HFI_CMD_SYS_COMMON_START + 0x008)
-#define HFI_CMD_SYS_SET_BUFFERS		(HFI_CMD_SYS_COMMON_START + 0x009)
-#define HFI_CMD_SYS_TEST_START		(HFI_CMD_SYS_COMMON_START + 0x100)
-
-#define HFI_CMD_SESSION_COMMON_START		\
-	(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET +	\
-	HFI_CMD_START_OFFSET + 0x1000)
-#define HFI_CMD_SESSION_SET_PROPERTY		\
-	(HFI_CMD_SESSION_COMMON_START + 0x001)
-#define HFI_CMD_SESSION_SET_BUFFERS			\
-	(HFI_CMD_SESSION_COMMON_START + 0x002)
-#define HFI_CMD_SESSION_GET_SEQUENCE_HEADER	\
-	(HFI_CMD_SESSION_COMMON_START + 0x003)
-
-#define HFI_MSG_SYS_COMMON_START			\
-	(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET +	\
-	HFI_MSG_START_OFFSET + 0x0000)
-#define HFI_MSG_SYS_INIT_DONE			(HFI_MSG_SYS_COMMON_START + 0x1)
-#define HFI_MSG_SYS_PC_PREP_DONE		(HFI_MSG_SYS_COMMON_START + 0x2)
-#define HFI_MSG_SYS_RELEASE_RESOURCE	(HFI_MSG_SYS_COMMON_START + 0x3)
-#define HFI_MSG_SYS_DEBUG			(HFI_MSG_SYS_COMMON_START + 0x4)
-#define HFI_MSG_SYS_SESSION_INIT_DONE	(HFI_MSG_SYS_COMMON_START + 0x6)
-#define HFI_MSG_SYS_SESSION_END_DONE	(HFI_MSG_SYS_COMMON_START + 0x7)
-
-#define HFI_MSG_SESSION_COMMON_START		\
-	(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET +	\
-	HFI_MSG_START_OFFSET + 0x1000)
-#define HFI_MSG_EVENT_NOTIFY	(HFI_MSG_SESSION_COMMON_START + 0x1)
-#define HFI_MSG_SESSION_GET_SEQUENCE_HEADER_DONE	\
-	(HFI_MSG_SESSION_COMMON_START + 0x2)
-
-struct vidc_hal_msg_pkt_hdr {
-	u32 size;
-	u32 packet;
-};
-
-struct vidc_hal_session_cmd_pkt {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-};
-
-struct hfi_cmd_sys_init_packet {
-	u32 size;
-	u32 packet_type;
-	u32 arch_type;
-};
-
-struct hfi_cmd_sys_pc_prep_packet {
-	u32 size;
-	u32 packet_type;
-};
-
-struct hfi_cmd_sys_set_resource_packet {
-	u32 size;
-	u32 packet_type;
-	u32 resource_handle;
-	u32 resource_type;
-	u32 rg_resource_data[1];
-};
-
-struct hfi_cmd_sys_release_resource_packet {
-	u32 size;
-	u32 packet_type;
-	u32 resource_type;
-	u32 resource_handle;
-};
-
-struct hfi_cmd_sys_set_property_packet {
-	u32 size;
-	u32 packet_type;
-	u32 num_properties;
-	u32 rg_property_data[1];
-};
-
-struct hfi_cmd_sys_get_property_packet {
-	u32 size;
-	u32 packet_type;
-	u32 num_properties;
-	u32 rg_property_data[1];
-};
-
-struct hfi_cmd_sys_session_init_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 session_domain;
-	u32 session_codec;
-};
-
-struct hfi_cmd_sys_session_end_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-};
-
-struct hfi_cmd_sys_set_buffers_packet {
-	u32 size;
-	u32 packet_type;
-	u32 buffer_type;
-	u32 buffer_size;
-	u32 num_buffers;
-	u32 rg_buffer_addr[1];
-};
-
-struct hfi_cmd_session_set_property_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 num_properties;
-	u32 rg_property_data[0];
-};
-
-struct hfi_cmd_session_set_buffers_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 buffer_type;
-	u32 buffer_size;
-	u32 extra_data_size;
-	u32 min_buffer_size;
-	u32 num_buffers;
-	u32 rg_buffer_info[1];
-};
-
-struct hfi_cmd_session_get_sequence_header_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 buffer_len;
-	u8 *packet_buffer;
-};
-
-struct hfi_msg_event_notify_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 event_id;
-	u32 event_data1;
-	u32 event_data2;
-	u32 rg_ext_event_data[1];
-};
-
-struct hfi_msg_sys_init_done_packet {
-	u32 size;
-	u32 packet_type;
-	u32 error_type;
-	u32 num_properties;
-	u32 rg_property_data[1];
-};
-
-struct hfi_msg_sys_pc_prep_done_packet {
-	u32 size;
-	u32 packet_type;
-	u32 error_type;
-};
-
-struct hfi_msg_sys_release_resource_done_packet {
-	u32 size;
-	u32 packet_type;
-	u32 resource_handle;
-	u32 error_type;
-};
-
-struct hfi_msg_sys_session_init_done_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 error_type;
-	u32 num_properties;
-	u32 rg_property_data[1];
-};
-
-struct hfi_msg_sys_session_end_done_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 error_type;
-};
-
-struct hfi_msg_session_get_sequence_header_done_packet {
-	u32 size;
-	u32 packet_type;
-	u32 session_id;
-	u32 error_type;
-	u32 header_len;
-	u8 *sequence_header;
-};
-
-struct hfi_msg_sys_debug_packet {
-	u32 size;
-	u32 packet_type;
-	u32 msg_type;
-	u32 msg_size;
-	u32 time_stamp_hi;
-	u32 time_stamp_lo;
-	u8 rg_msg_data[1];
-};
-
-enum HFI_VENUS_QTBL_STATUS {
-	HFI_VENUS_QTBL_DISABLED = 0x00,
-	HFI_VENUS_QTBL_ENABLED = 0x01,
-	HFI_VENUS_QTBL_INITIALIZING = 0x02,
-	HFI_VENUS_QTBL_DEINITIALIZING = 0x03
-};
-
-enum HFI_VENUS_CTRL_INIT_STATUS {
-	HFI_VENUS_CTRL_NOT_INIT = 0x0,
-	HFI_VENUS_CTRL_READY = 0x1,
-	HFI_VENUS_CTRL_ERROR_FATAL = 0x2
-};
-
-struct hfi_sfr_struct {
-	u32 bufSize;
-	u8 rg_data[1];
-};
-
-#endif
diff --git a/drivers/media/video/msm_vidc/vidc_hal_interrupt_handler.c b/drivers/media/video/msm_vidc/vidc_hal_interrupt_handler.c
deleted file mode 100644
index 8201b0e..0000000
--- a/drivers/media/video/msm_vidc/vidc_hal_interrupt_handler.c
+++ /dev/null
@@ -1,928 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/list.h>
-#include <linux/interrupt.h>
-#include "vidc_hal.h"
-#include "vidc_hal_io.h"
-#include "msm_vidc_debug.h"
-
-static enum vidc_status vidc_map_hal_err_status(int hfi_err)
-{
-	enum vidc_status vidc_err;
-	switch (hfi_err) {
-	case HFI_ERR_NONE:
-	case HFI_ERR_SESSION_SAME_STATE_OPERATION:
-		vidc_err = VIDC_ERR_NONE;
-		break;
-	case HFI_ERR_SYS_FATAL:
-		vidc_err = VIDC_ERR_HW_FATAL;
-		break;
-	case HFI_ERR_SYS_VERSION_MISMATCH:
-	case HFI_ERR_SYS_INVALID_PARAMETER:
-	case HFI_ERR_SYS_SESSION_ID_OUT_OF_RANGE:
-	case HFI_ERR_SESSION_INVALID_PARAMETER:
-	case HFI_ERR_SESSION_INVALID_SESSION_ID:
-	case HFI_ERR_SESSION_INVALID_STREAM_ID:
-		vidc_err = VIDC_ERR_BAD_PARAM;
-		break;
-	case HFI_ERR_SYS_INSUFFICIENT_RESOURCES:
-	case HFI_ERR_SYS_UNSUPPORTED_DOMAIN:
-	case HFI_ERR_SYS_UNSUPPORTED_CODEC:
-	case HFI_ERR_SESSION_UNSUPPORTED_PROPERTY:
-	case HFI_ERR_SESSION_UNSUPPORTED_SETTING:
-	case HFI_ERR_SESSION_INSUFFICIENT_RESOURCES:
-		vidc_err = VIDC_ERR_NOT_SUPPORTED;
-		break;
-	case HFI_ERR_SYS_MAX_SESSIONS_REACHED:
-		vidc_err = VIDC_ERR_MAX_CLIENT;
-		break;
-	case HFI_ERR_SYS_SESSION_IN_USE:
-		vidc_err = VIDC_ERR_CLIENT_PRESENT;
-		break;
-	case HFI_ERR_SESSION_FATAL:
-		vidc_err = VIDC_ERR_CLIENT_FATAL;
-		break;
-	case HFI_ERR_SESSION_BAD_POINTER:
-		vidc_err = VIDC_ERR_BAD_PARAM;
-		break;
-	case HFI_ERR_SESSION_INCORRECT_STATE_OPERATION:
-		vidc_err = VIDC_ERR_BAD_STATE;
-		break;
-	case HFI_ERR_SESSION_STREAM_CORRUPT:
-	case HFI_ERR_SESSION_STREAM_CORRUPT_OUTPUT_STALLED:
-		vidc_err = VIDC_ERR_BITSTREAM_ERR;
-		break;
-	case HFI_ERR_SESSION_SYNC_FRAME_NOT_DETECTED:
-		vidc_err = VIDC_ERR_IFRAME_EXPECTED;
-		break;
-	case HFI_ERR_SESSION_EMPTY_BUFFER_DONE_OUTPUT_PENDING:
-	default:
-		vidc_err = VIDC_ERR_FAIL;
-		break;
-	}
-	return vidc_err;
-}
-
-void hal_process_sess_evt_seq_changed(struct hal_device *device,
-	struct hfi_msg_event_notify_packet *pkt)
-{
-	struct msm_vidc_cb_cmd_done cmd_done;
-	struct msm_vidc_cb_event event_notify;
-	int num_properties_changed;
-	struct hfi_frame_size frame_sz;
-	u8 *data_ptr;
-	int prop_id;
-	dprintk(VIDC_DBG, "RECEIVED:EVENT_NOTIFY");
-	if (sizeof(struct hfi_msg_event_notify_packet)
-		> pkt->size) {
-		dprintk(VIDC_ERR, "hal_process_session_init_done:bad_pkt_size");
-		return;
-	}
-
-	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
-	memset(&event_notify, 0, sizeof(struct
-				msm_vidc_cb_event));
-
-	cmd_done.device_id = device->device_id;
-	cmd_done.session_id = ((struct hal_session *) pkt->session_id)->
-		session_id;
-	cmd_done.status = VIDC_ERR_NONE;
-	cmd_done.size = sizeof(struct msm_vidc_cb_event);
-	num_properties_changed = pkt->event_data2;
-	switch (pkt->event_data1) {
-	case HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUFFER_RESOURCES:
-		event_notify.hal_event_type =
-			HAL_EVENT_SEQ_CHANGED_SUFFICIENT_RESOURCES;
-		break;
-	case HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUFFER_RESOURCES:
-		event_notify.hal_event_type =
-			HAL_EVENT_SEQ_CHANGED_INSUFFICIENT_RESOURCES;
-		break;
-	default:
-		break;
-	}
-	if (num_properties_changed) {
-		data_ptr = (u8 *) &pkt->rg_ext_event_data[0];
-		do {
-			prop_id = (int) *((u32 *)data_ptr);
-			switch (prop_id) {
-			case HFI_PROPERTY_PARAM_FRAME_SIZE:
-				frame_sz.buffer_type =
-					(int) *((((u32 *)data_ptr)+1));
-				frame_sz.width =
-					event_notify.width =
-						*((((u32 *)data_ptr)+2));
-				frame_sz.height =
-					event_notify.height =
-						*((((u32 *)data_ptr)+3));
-				data_ptr += 4;
-			break;
-			default:
-			break;
-			}
-			num_properties_changed--;
-		} while (num_properties_changed > 0);
-	}
-	cmd_done.data = &event_notify;
-	device->callback(VIDC_EVENT_CHANGE, &cmd_done);
-}
-static void hal_process_sys_watchdog_timeout(struct hal_device *device)
-{
-	struct msm_vidc_cb_cmd_done cmd_done;
-	device->intr_status &= ~VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK;
-	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
-	cmd_done.device_id = device->device_id;
-	device->callback(SYS_WATCHDOG_TIMEOUT, &cmd_done);
-}
-static void hal_process_sys_error(struct hal_device *device)
-{
-	struct msm_vidc_cb_cmd_done cmd_done;
-	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
-	cmd_done.device_id = device->device_id;
-	device->callback(SYS_ERROR, &cmd_done);
-}
-static void hal_process_session_error(struct hal_device *device,
-		struct hfi_msg_event_notify_packet *pkt)
-{
-	struct msm_vidc_cb_cmd_done cmd_done;
-	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
-	cmd_done.device_id = device->device_id;
-	cmd_done.session_id = ((struct hal_session *) pkt->session_id)->
-		session_id;
-	device->callback(SESSION_ERROR, &cmd_done);
-}
-static void hal_process_event_notify(struct hal_device *device,
-	struct hfi_msg_event_notify_packet *pkt)
-{
-	dprintk(VIDC_DBG, "RECVD:EVENT_NOTIFY");
-
-	if (!device || !pkt ||
-		pkt->size < sizeof(struct hfi_msg_event_notify_packet)) {
-		dprintk(VIDC_ERR, "Invalid Params");
-		return;
-	}
-
-	switch (pkt->event_id) {
-	case HFI_EVENT_SYS_ERROR:
-		dprintk(VIDC_ERR, "HFI_EVENT_SYS_ERROR: %d\n",
-			pkt->event_data1);
-		hal_process_sys_error(device);
-		break;
-	case HFI_EVENT_SESSION_ERROR:
-		dprintk(VIDC_ERR, "HFI_EVENT_SESSION_ERROR");
-		hal_process_session_error(device, pkt);
-		break;
-	case HFI_EVENT_SESSION_SEQUENCE_CHANGED:
-		dprintk(VIDC_INFO, "HFI_EVENT_SESSION_SEQUENCE_CHANGED");
-		hal_process_sess_evt_seq_changed(device, pkt);
-		break;
-	case HFI_EVENT_SESSION_PROPERTY_CHANGED:
-		dprintk(VIDC_INFO, "HFI_EVENT_SESSION_PROPERTY_CHANGED");
-		break;
-	default:
-		dprintk(VIDC_WARN, "hal_process_event_notify:unkown_event_id");
-		break;
-	}
-}
-static void hal_process_sys_init_done(struct hal_device *device,
-		struct hfi_msg_sys_init_done_packet *pkt)
-{
-	struct msm_vidc_cb_cmd_done cmd_done;
-	struct vidc_hal_sys_init_done sys_init_done;
-	u32 rem_bytes, bytes_read = 0, num_properties;
-	u8 *data_ptr;
-	int prop_id;
-	enum vidc_status status = VIDC_ERR_NONE;
-
-	dprintk(VIDC_DBG, "RECEIVED:SYS_INIT_DONE");
-	if (sizeof(struct hfi_msg_sys_init_done_packet) > pkt->size) {
-		dprintk(VIDC_ERR, "hal_process_sys_init_done:bad_pkt_size: %d",
-				pkt->size);
-		return;
-	}
-
-	status = vidc_map_hal_err_status((u32)pkt->error_type);
-
-	if (!status) {
-		if (pkt->num_properties == 0) {
-			dprintk(VIDC_ERR, "hal_process_sys_init_done:"
-						"no_properties");
-			status = VIDC_ERR_FAIL;
-			goto err_no_prop;
-		}
-
-		rem_bytes = pkt->size - sizeof(struct
-			hfi_msg_sys_init_done_packet) + sizeof(u32);
-
-		if (rem_bytes == 0) {
-			dprintk(VIDC_ERR, "hal_process_sys_init_done:"
-						"missing_prop_info");
-			status = VIDC_ERR_FAIL;
-			goto err_no_prop;
-		}
-		memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
-		memset(&sys_init_done, 0, sizeof(struct
-				vidc_hal_sys_init_done));
-
-		data_ptr = (u8 *) &pkt->rg_property_data[0];
-		num_properties = pkt->num_properties;
-
-		while ((num_properties != 0) && (rem_bytes >= sizeof(u32))) {
-			prop_id = *((u32 *)data_ptr);
-			data_ptr = data_ptr + 4;
-
-			switch (prop_id) {
-			case HFI_PROPERTY_PARAM_CODEC_SUPPORTED:
-			{
-				struct hfi_codec_supported *prop =
-					(struct hfi_codec_supported *) data_ptr;
-				if (rem_bytes < sizeof(struct
-						hfi_codec_supported)) {
-					status = VIDC_ERR_BAD_PARAM;
-					break;
-				}
-				sys_init_done.dec_codec_supported =
-					prop->decoder_codec_supported;
-				sys_init_done.enc_codec_supported =
-					prop->encoder_codec_supported;
-				break;
-			}
-			default:
-				dprintk(VIDC_ERR, "hal_process_sys_init_done:"
-							"bad_prop_id");
-				status = VIDC_ERR_BAD_PARAM;
-				break;
-			}
-			if (!status) {
-				rem_bytes -= bytes_read;
-				data_ptr += bytes_read;
-				num_properties--;
-			}
-		}
-	}
-err_no_prop:
-	cmd_done.device_id = device->device_id;
-	cmd_done.session_id = 0;
-	cmd_done.status = (u32) status;
-	cmd_done.size = sizeof(struct vidc_hal_sys_init_done);
-	cmd_done.data = (void *) &sys_init_done;
-	device->callback(SYS_INIT_DONE, &cmd_done);
-}
-
-static void hal_process_sys_rel_resource_done(struct hal_device *device,
-	struct hfi_msg_sys_release_resource_done_packet *pkt)
-{
-	struct msm_vidc_cb_cmd_done cmd_done;
-	enum vidc_status status = VIDC_ERR_NONE;
-	u32 pkt_size;
-	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
-	dprintk(VIDC_DBG, "RECEIVED:SYS_RELEASE_RESOURCE_DONE");
-	pkt_size = sizeof(struct hfi_msg_sys_release_resource_done_packet);
-	if (pkt_size > pkt->size) {
-		dprintk(VIDC_ERR,
-			"hal_process_sys_rel_resource_done:bad size:%d",
-			pkt->size);
-		return;
-	}
-	status = vidc_map_hal_err_status((u32)pkt->error_type);
-	cmd_done.device_id = device->device_id;
-	cmd_done.session_id = 0;
-	cmd_done.status = (u32) status;
-	cmd_done.size = 0;
-	cmd_done.data = NULL;
-	device->callback(RELEASE_RESOURCE_DONE, &cmd_done);
-}
-
-enum vidc_status vidc_hal_process_sess_init_done_prop_read(
-	struct hfi_msg_sys_session_init_done_packet *pkt,
-	struct msm_vidc_cb_cmd_done *cmddone)
-{
-	return VIDC_ERR_NONE;
-}
-
-static void hal_process_sess_get_prop_buf_req(
-	struct hfi_msg_session_property_info_packet *prop,
-	struct buffer_requirements *buffreq)
-{
-	struct hfi_buffer_requirements *hfi_buf_req;
-	u32 req_bytes;
-
-	dprintk(VIDC_DBG, "Entered ");
-	if (!prop) {
-		dprintk(VIDC_ERR,
-			"hal_process_sess_get_prop_buf_req:bad_prop: %p",
-			prop);
-		return;
-	}
-	req_bytes = prop->size - sizeof(
-	struct hfi_msg_session_property_info_packet);
-
-	if (!req_bytes || (req_bytes % sizeof(
-		struct hfi_buffer_requirements)) ||
-		(!prop->rg_property_data[1])) {
-		dprintk(VIDC_ERR,
-			"hal_process_sess_get_prop_buf_req:bad_pkt: %d",
-			req_bytes);
-		return;
-	}
-
-	hfi_buf_req = (struct hfi_buffer_requirements *)
-		&prop->rg_property_data[1];
-
-	while (req_bytes) {
-		if ((hfi_buf_req->buffer_size) &&
-			((hfi_buf_req->buffer_count_min > hfi_buf_req->
-			buffer_count_actual)))
-				dprintk(VIDC_WARN,
-					"hal_process_sess_get_prop_buf_req:"
-					"bad_buf_req");
-
-		dprintk(VIDC_DBG, "got buffer requirements for: %d",
-					hfi_buf_req->buffer_type);
-		switch (hfi_buf_req->buffer_type) {
-		case HFI_BUFFER_INPUT:
-			memcpy(&buffreq->buffer[0], hfi_buf_req,
-				sizeof(struct hfi_buffer_requirements));
-			buffreq->buffer[0].buffer_type = HAL_BUFFER_INPUT;
-			break;
-		case HFI_BUFFER_OUTPUT:
-			memcpy(&buffreq->buffer[1], hfi_buf_req,
-			sizeof(struct hfi_buffer_requirements));
-			buffreq->buffer[1].buffer_type = HAL_BUFFER_OUTPUT;
-			break;
-		case HFI_BUFFER_OUTPUT2:
-			memcpy(&buffreq->buffer[2], hfi_buf_req,
-				sizeof(struct hfi_buffer_requirements));
-			buffreq->buffer[2].buffer_type = HAL_BUFFER_OUTPUT2;
-			break;
-		case HFI_BUFFER_EXTRADATA_INPUT:
-			memcpy(&buffreq->buffer[3], hfi_buf_req,
-				sizeof(struct hfi_buffer_requirements));
-			buffreq->buffer[3].buffer_type =
-				HAL_BUFFER_EXTRADATA_INPUT;
-			break;
-		case HFI_BUFFER_EXTRADATA_OUTPUT:
-			memcpy(&buffreq->buffer[4], hfi_buf_req,
-				sizeof(struct hfi_buffer_requirements));
-			buffreq->buffer[4].buffer_type =
-				HAL_BUFFER_EXTRADATA_OUTPUT;
-			break;
-		case HFI_BUFFER_EXTRADATA_OUTPUT2:
-			memcpy(&buffreq->buffer[5], hfi_buf_req,
-				sizeof(struct hfi_buffer_requirements));
-			buffreq->buffer[5].buffer_type =
-				HAL_BUFFER_EXTRADATA_OUTPUT2;
-			break;
-		case HFI_BUFFER_INTERNAL_SCRATCH:
-			memcpy(&buffreq->buffer[6], hfi_buf_req,
-			sizeof(struct hfi_buffer_requirements));
-			buffreq->buffer[6].buffer_type =
-				HAL_BUFFER_INTERNAL_SCRATCH;
-			break;
-		case HFI_BUFFER_INTERNAL_PERSIST:
-			memcpy(&buffreq->buffer[7], hfi_buf_req,
-			sizeof(struct hfi_buffer_requirements));
-			buffreq->buffer[7].buffer_type =
-				HAL_BUFFER_INTERNAL_PERSIST;
-			break;
-		default:
-			dprintk(VIDC_ERR,
-			"hal_process_sess_get_prop_buf_req: bad_buffer_type: %d",
-			hfi_buf_req->buffer_type);
-			break;
-		}
-		req_bytes -= sizeof(struct hfi_buffer_requirements);
-		hfi_buf_req++;
-	}
-}
-
-static void hal_process_session_prop_info(struct hal_device *device,
-	struct hfi_msg_session_property_info_packet *pkt)
-{
-	struct msm_vidc_cb_cmd_done cmd_done;
-	struct buffer_requirements buff_req;
-
-	dprintk(VIDC_DBG, "Received SESSION_PROPERTY_INFO");
-
-	if (pkt->size < sizeof(struct hfi_msg_session_property_info_packet)) {
-		dprintk(VIDC_ERR, "hal_process_session_prop_info:bad_pkt_size");
-		return;
-	}
-
-	if (pkt->num_properties == 0) {
-		dprintk(VIDC_ERR,
-			"hal_process_session_prop_info:no_properties");
-		return;
-	}
-
-	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
-	memset(&buff_req, 0, sizeof(struct buffer_requirements));
-
-	switch (pkt->rg_property_data[0]) {
-	case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:
-		hal_process_sess_get_prop_buf_req(pkt, &buff_req);
-		cmd_done.device_id = device->device_id;
-		cmd_done.session_id =
-			((struct hal_session *) pkt->session_id)->session_id;
-		cmd_done.status = VIDC_ERR_NONE;
-		cmd_done.data = &buff_req;
-		cmd_done.size = sizeof(struct buffer_requirements);
-		device->callback(SESSION_PROPERTY_INFO, &cmd_done);
-		break;
-	default:
-		dprintk(VIDC_ERR, "hal_process_session_prop_info:"
-					"unknown_prop_id: %d",
-				pkt->rg_property_data[0]);
-		break;
-	}
-}
-
-static void hal_process_session_init_done(struct hal_device *device,
-	struct hfi_msg_sys_session_init_done_packet *pkt)
-{
-	struct msm_vidc_cb_cmd_done cmd_done;
-	struct vidc_hal_session_init_done session_init_done;
-
-	dprintk(VIDC_DBG, "RECEIVED:SESSION_INIT_DONE");
-	if (sizeof(struct hfi_msg_sys_session_init_done_packet)
-		> pkt->size) {
-		dprintk(VIDC_ERR, "hal_process_session_init_done:bad_pkt_size");
-		return;
-	}
-
-	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
-	memset(&session_init_done, 0, sizeof(struct
-				vidc_hal_session_init_done));
-
-	cmd_done.device_id = device->device_id;
-	cmd_done.session_id =
-		((struct hal_session *) pkt->session_id)->session_id;
-	cmd_done.status = vidc_map_hal_err_status((u32)pkt->error_type);
-	cmd_done.data = &session_init_done;
-	if (!cmd_done.status) {
-		cmd_done.status = vidc_hal_process_sess_init_done_prop_read(
-			pkt, &cmd_done);
-	}
-	cmd_done.size = sizeof(struct vidc_hal_session_init_done);
-	device->callback(SESSION_INIT_DONE, &cmd_done);
-}
-
-static void hal_process_session_load_res_done(struct hal_device *device,
-	struct hfi_msg_session_load_resources_done_packet *pkt)
-{
-	struct msm_vidc_cb_cmd_done cmd_done;
-	dprintk(VIDC_DBG, "RECEIVED:SESSION_LOAD_RESOURCES_DONE");
-
-	if (sizeof(struct hfi_msg_session_load_resources_done_packet) !=
-		pkt->size) {
-		dprintk(VIDC_ERR, "hal_process_session_load_res_done:"
-		" bad packet size: %d", pkt->size);
-		return;
-	}
-
-	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
-
-	cmd_done.device_id = device->device_id;
-	cmd_done.session_id =
-		((struct hal_session *) pkt->session_id)->session_id;
-	cmd_done.status = vidc_map_hal_err_status((u32)pkt->error_type);
-	cmd_done.data = NULL;
-	cmd_done.size = 0;
-	device->callback(SESSION_LOAD_RESOURCE_DONE, &cmd_done);
-}
-
-static void hal_process_session_flush_done(struct hal_device *device,
-	struct hfi_msg_session_flush_done_packet *pkt)
-{
-	struct msm_vidc_cb_cmd_done cmd_done;
-
-	dprintk(VIDC_DBG, "RECEIVED:SESSION_FLUSH_DONE");
-
-	if (sizeof(struct hfi_msg_session_flush_done_packet) != pkt->size) {
-		dprintk(VIDC_ERR, "hal_process_session_flush_done: "
-		"bad packet size: %d", pkt->size);
-		return;
-	}
-
-	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
-	cmd_done.device_id = device->device_id;
-	cmd_done.session_id =
-		((struct hal_session *) pkt->session_id)->session_id;
-	cmd_done.status = vidc_map_hal_err_status((u32)pkt->error_type);
-	cmd_done.data = (void *) pkt->flush_type;
-	cmd_done.size = sizeof(u32);
-	device->callback(SESSION_FLUSH_DONE, &cmd_done);
-}
-
-static void hal_process_session_etb_done(struct hal_device *device,
-	struct hfi_msg_session_empty_buffer_done_packet *pkt)
-{
-	struct msm_vidc_cb_data_done data_done;
-
-	dprintk(VIDC_DBG, "RECEIVED:SESSION_ETB_DONE");
-
-	if (!pkt || pkt->size <
-		sizeof(struct hfi_msg_session_empty_buffer_done_packet)) {
-		dprintk(VIDC_ERR, "hal_process_session_etb_done:bad_pkt_size");
-		return;
-	}
-
-	memset(&data_done, 0, sizeof(struct msm_vidc_cb_data_done));
-
-	data_done.device_id = device->device_id;
-	data_done.session_id =
-		((struct hal_session *) pkt->session_id)->session_id;
-	data_done.status = vidc_map_hal_err_status((u32) pkt->error_type);
-	data_done.size = sizeof(struct msm_vidc_cb_data_done);
-	data_done.clnt_data = (void *)pkt->input_tag;
-	data_done.input_done.offset = pkt->offset;
-	data_done.input_done.filled_len = pkt->filled_len;
-	data_done.input_done.packet_buffer = pkt->packet_buffer;
-	device->callback(SESSION_ETB_DONE, &data_done);
-}
-
-static void hal_process_session_ftb_done(struct hal_device *device,
-			void *msg_hdr)
-{
-	struct msm_vidc_cb_data_done data_done;
-	struct hfi_msg_session_fill_buffer_done_compressed_packet *pack =
-	(struct hfi_msg_session_fill_buffer_done_compressed_packet *) msg_hdr;
-	u32 is_decoder = ((struct hal_session *)pack->session_id)->is_decoder;
-	struct hal_session *session;
-
-	if (!msg_hdr) {
-		dprintk(VIDC_ERR, "Invalid Params");
-		return;
-	}
-
-	session = (struct hal_session *)
-		((struct hal_session *)	pack->session_id)->session_id;
-	dprintk(VIDC_DBG, "RECEIVED:SESSION_FTB_DONE");
-
-	memset(&data_done, 0, sizeof(struct msm_vidc_cb_data_done));
-
-	if (is_decoder == 0) {
-		struct hfi_msg_session_fill_buffer_done_compressed_packet *pkt =
-		(struct hfi_msg_session_fill_buffer_done_compressed_packet *)
-		msg_hdr;
-		if (sizeof(struct
-			hfi_msg_session_fill_buffer_done_compressed_packet)
-			> pkt->size) {
-			dprintk(VIDC_ERR,
-				"hal_process_session_ftb_done: bad_pkt_size");
-			return;
-		} else if (pkt->error_type != HFI_ERR_NONE) {
-			dprintk(VIDC_ERR,
-				"got buffer back with error %x",
-				pkt->error_type);
-			/* Proceed with the FBD */
-		}
-
-		data_done.device_id = device->device_id;
-		data_done.session_id = (u32) session;
-		data_done.status = vidc_map_hal_err_status((u32)
-							pkt->error_type);
-		data_done.size = sizeof(struct msm_vidc_cb_data_done);
-		data_done.clnt_data = (void *) pkt->input_tag;
-
-		data_done.output_done.timestamp_hi = pkt->time_stamp_hi;
-		data_done.output_done.timestamp_lo = pkt->time_stamp_lo;
-		data_done.output_done.flags1 = pkt->flags;
-		data_done.output_done.mark_target = pkt->mark_target;
-		data_done.output_done.mark_data = pkt->mark_data;
-		data_done.output_done.stats = pkt->stats;
-		data_done.output_done.offset1 = pkt->offset;
-		data_done.output_done.alloc_len1 = pkt->alloc_len;
-		data_done.output_done.filled_len1 = pkt->filled_len;
-		data_done.output_done.picture_type = pkt->picture_type;
-		data_done.output_done.packet_buffer1 = pkt->packet_buffer;
-		data_done.output_done.extra_data_buffer =
-			pkt->extra_data_buffer;
-		dprintk(VIDC_DBG, "FBD: Received buf: %p, of len: %d\n",
-				   pkt->packet_buffer, pkt->filled_len);
-	} else if (is_decoder == 1) {
-		struct hfi_msg_session_fbd_uncompressed_plane0_packet *pkt =
-		(struct	hfi_msg_session_fbd_uncompressed_plane0_packet *)
-		msg_hdr;
-		if (sizeof(struct
-		hfi_msg_session_fbd_uncompressed_plane0_packet)
-		> pkt->size) {
-			dprintk(VIDC_ERR, "hal_process_session_ftb_done:"
-						"bad_pkt_size");
-			return;
-		}
-
-		data_done.device_id = device->device_id;
-		data_done.session_id = (u32) session;
-		data_done.status = vidc_map_hal_err_status((u32)
-			pkt->error_type);
-		data_done.size = sizeof(struct msm_vidc_cb_data_done);
-		data_done.clnt_data = (void *)pkt->input_tag;
-
-		data_done.output_done.stream_id = pkt->stream_id;
-		data_done.output_done.view_id = pkt->view_id;
-		data_done.output_done.timestamp_hi = pkt->time_stamp_hi;
-		data_done.output_done.timestamp_lo = pkt->time_stamp_lo;
-		data_done.output_done.flags1 = pkt->flags;
-		data_done.output_done.mark_target = pkt->mark_target;
-		data_done.output_done.mark_data = pkt->mark_data;
-		data_done.output_done.stats = pkt->stats;
-		data_done.output_done.alloc_len1 = pkt->alloc_len;
-		data_done.output_done.filled_len1 = pkt->filled_len;
-		data_done.output_done.offset1 = pkt->offset;
-		data_done.output_done.frame_width = pkt->frame_width;
-		data_done.output_done.frame_height = pkt->frame_height;
-		data_done.output_done.start_xCoord = pkt->start_x_coord;
-		data_done.output_done.start_yCoord = pkt->start_y_coord;
-		data_done.output_done.input_tag1 = pkt->input_tag;
-		data_done.output_done.picture_type = pkt->picture_type;
-		data_done.output_done.packet_buffer1 = pkt->packet_buffer;
-		data_done.output_done.extra_data_buffer =
-			pkt->extra_data_buffer;
-
-		if (pkt->stream_id == 0)
-			data_done.output_done.buffer_type = HAL_BUFFER_OUTPUT;
-		else if (pkt->stream_id == 1)
-			data_done.output_done.buffer_type = HAL_BUFFER_OUTPUT2;
-		}
-	device->callback(SESSION_FTB_DONE, &data_done);
-}
-
-static void hal_process_session_start_done(struct hal_device *device,
-	struct hfi_msg_session_start_done_packet *pkt)
-{
-	struct msm_vidc_cb_cmd_done cmd_done;
-
-	dprintk(VIDC_DBG, "RECEIVED:SESSION_START_DONE");
-
-	if (!pkt || pkt->size !=
-		sizeof(struct hfi_msg_session_start_done_packet)) {
-		dprintk(VIDC_ERR, "hal_process_session_start_done:"
-		"bad packet/packet size: %d", pkt->size);
-		return;
-	}
-
-	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
-	cmd_done.device_id = device->device_id;
-	cmd_done.session_id =
-		((struct hal_session *) pkt->session_id)->session_id;
-	cmd_done.status = vidc_map_hal_err_status((u32)pkt->error_type);
-	cmd_done.data = NULL;
-	cmd_done.size = 0;
-	device->callback(SESSION_START_DONE, &cmd_done);
-}
-
-static void hal_process_session_stop_done(struct hal_device *device,
-	struct hfi_msg_session_stop_done_packet *pkt)
-{
-	struct msm_vidc_cb_cmd_done cmd_done;
-
-	dprintk(VIDC_DBG, "RECEIVED:SESSION_STOP_DONE");
-
-	if (!pkt || pkt->size !=
-		sizeof(struct hfi_msg_session_stop_done_packet)) {
-		dprintk(VIDC_ERR, "hal_process_session_stop_done:"
-		"bad packet/packet size: %d", pkt->size);
-		return;
-	}
-
-	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
-	cmd_done.device_id = device->device_id;
-	cmd_done.session_id =
-		((struct hal_session *) pkt->session_id)->session_id;
-	cmd_done.status = vidc_map_hal_err_status((u32)pkt->error_type);
-	cmd_done.data = NULL;
-	cmd_done.size = 0;
-	device->callback(SESSION_STOP_DONE, &cmd_done);
-}
-
-static void hal_process_session_rel_res_done(struct hal_device *device,
-	struct hfi_msg_session_release_resources_done_packet *pkt)
-{
-	struct msm_vidc_cb_cmd_done cmd_done;
-
-	dprintk(VIDC_DBG, "RECEIVED:SESSION_RELEASE_RESOURCES_DONE");
-
-	if (!pkt || pkt->size !=
-		sizeof(struct hfi_msg_session_release_resources_done_packet)) {
-		dprintk(VIDC_ERR, "hal_process_session_rel_res_done:"
-		"bad packet/packet size: %d", pkt->size);
-		return;
-	}
-
-	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
-	cmd_done.device_id = device->device_id;
-	cmd_done.session_id =
-		((struct hal_session *) pkt->session_id)->session_id;
-	cmd_done.status = vidc_map_hal_err_status((u32)pkt->error_type);
-	cmd_done.data = NULL;
-	cmd_done.size = 0;
-	device->callback(SESSION_RELEASE_RESOURCE_DONE, &cmd_done);
-}
-
-static void hal_process_session_rel_buf_done(struct hal_device *device,
-	struct hfi_msg_session_release_buffers_done_packet *pkt)
-{
-	struct msm_vidc_cb_cmd_done cmd_done;
-	if (!pkt || pkt->size !=
-		sizeof(struct
-			   hfi_msg_session_release_buffers_done_packet)) {
-		dprintk(VIDC_ERR, "bad packet/packet size: %d", pkt->size);
-		return;
-	}
-	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
-	cmd_done.device_id = device->device_id;
-	cmd_done.size = sizeof(struct msm_vidc_cb_cmd_done);
-	cmd_done.session_id =
-		((struct hal_session *) pkt->session_id)->session_id;
-	cmd_done.status = vidc_map_hal_err_status((u32)pkt->error_type);
-	if (pkt->rg_buffer_info) {
-		cmd_done.data = (void *) &pkt->rg_buffer_info;
-		cmd_done.size = sizeof(struct hfi_buffer_info);
-	} else {
-		dprintk(VIDC_ERR, "invalid payload in rel_buff_done\n");
-	}
-	device->callback(SESSION_RELEASE_BUFFER_DONE, &cmd_done);
-}
-
-static void hal_process_session_end_done(struct hal_device *device,
-	struct hfi_msg_sys_session_end_done_packet *pkt)
-{
-	struct msm_vidc_cb_cmd_done cmd_done;
-	struct hal_session *sess_close;
-
-	dprintk(VIDC_DBG, "RECEIVED:SESSION_END_DONE");
-
-	if (!pkt || pkt->size !=
-		sizeof(struct hfi_msg_sys_session_end_done_packet)) {
-		dprintk(VIDC_ERR, "hal_process_session_end_done: "
-		"bad packet/packet size: %d", pkt->size);
-		return;
-	}
-
-	sess_close = (struct hal_session *)pkt->session_id;
-	dprintk(VIDC_INFO, "deleted the session: 0x%x",
-			sess_close->session_id);
-	list_del(&sess_close->list);
-	kfree(sess_close);
-
-	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
-	cmd_done.device_id = device->device_id;
-	cmd_done.session_id =
-		((struct hal_session *) pkt->session_id)->session_id;
-	cmd_done.status = vidc_map_hal_err_status((u32)pkt->error_type);
-	cmd_done.data = NULL;
-	cmd_done.size = 0;
-	device->callback(SESSION_END_DONE, &cmd_done);
-}
-
-static void hal_process_session_get_seq_hdr_done(struct hal_device *device,
-	struct hfi_msg_session_get_sequence_header_done_packet *pkt)
-{
-	struct msm_vidc_cb_data_done data_done;
-	if (!pkt || pkt->size !=
-		sizeof(struct
-		hfi_msg_session_get_sequence_header_done_packet)) {
-		dprintk(VIDC_ERR, "bad packet/packet size: %d", pkt->size);
-		return;
-	}
-	memset(&data_done, 0, sizeof(struct msm_vidc_cb_data_done));
-	data_done.device_id = device->device_id;
-	data_done.size = sizeof(struct msm_vidc_cb_data_done);
-	data_done.session_id =
-		((struct hal_session *) pkt->session_id)->session_id;
-	data_done.status = vidc_map_hal_err_status((u32)pkt->error_type);
-	data_done.output_done.packet_buffer1 = pkt->sequence_header;
-	data_done.output_done.filled_len1 = pkt->header_len;
-	dprintk(VIDC_INFO, "seq_hdr: %p, Length: %d",
-		   pkt->sequence_header, pkt->header_len);
-	device->callback(SESSION_GET_SEQ_HDR_DONE, &data_done);
-}
-
-static void hal_process_msg_packet(struct hal_device *device,
-	struct vidc_hal_msg_pkt_hdr *msg_hdr)
-{
-	if (!device || !msg_hdr || msg_hdr->size <
-		VIDC_IFACEQ_MIN_PKT_SIZE) {
-		dprintk(VIDC_ERR, "hal_process_msg_packet:bad"
-			"packet/packet size: %d", msg_hdr->size);
-		return;
-	}
-
-	dprintk(VIDC_INFO, "Received: 0x%x in ", msg_hdr->packet);
-	if ((device->intr_status & VIDC_WRAPPER_INTR_CLEAR_A2HWD_BMSK)) {
-		dprintk(VIDC_ERR, "Received: Watchdog timeout %s", __func__);
-		hal_process_sys_watchdog_timeout(device);
-		return;
-	}
-
-	switch (msg_hdr->packet) {
-	case HFI_MSG_EVENT_NOTIFY:
-		hal_process_event_notify(device,
-			(struct hfi_msg_event_notify_packet *) msg_hdr);
-		break;
-	case  HFI_MSG_SYS_INIT_DONE:
-		hal_process_sys_init_done(device,
-			(struct hfi_msg_sys_init_done_packet *)
-					msg_hdr);
-		break;
-	case HFI_MSG_SYS_SESSION_INIT_DONE:
-		hal_process_session_init_done(device,
-			(struct hfi_msg_sys_session_init_done_packet *)
-					msg_hdr);
-		break;
-	case HFI_MSG_SYS_SESSION_END_DONE:
-		hal_process_session_end_done(device,
-			(struct hfi_msg_sys_session_end_done_packet *)
-					msg_hdr);
-		break;
-	case HFI_MSG_SESSION_LOAD_RESOURCES_DONE:
-		hal_process_session_load_res_done(device,
-			(struct hfi_msg_session_load_resources_done_packet *)
-					msg_hdr);
-		break;
-	case HFI_MSG_SESSION_START_DONE:
-		hal_process_session_start_done(device,
-			(struct hfi_msg_session_start_done_packet *)
-					msg_hdr);
-		break;
-	case HFI_MSG_SESSION_STOP_DONE:
-		hal_process_session_stop_done(device,
-			(struct hfi_msg_session_stop_done_packet *)
-					msg_hdr);
-		break;
-	case HFI_MSG_SESSION_EMPTY_BUFFER_DONE:
-		hal_process_session_etb_done(device,
-			(struct hfi_msg_session_empty_buffer_done_packet *)
-					msg_hdr);
-		break;
-	case HFI_MSG_SESSION_FILL_BUFFER_DONE:
-		hal_process_session_ftb_done(device, msg_hdr);
-		break;
-	case HFI_MSG_SESSION_FLUSH_DONE:
-		hal_process_session_flush_done(device,
-			(struct hfi_msg_session_flush_done_packet *)
-					msg_hdr);
-		break;
-	case HFI_MSG_SESSION_PROPERTY_INFO:
-		hal_process_session_prop_info(device,
-			(struct hfi_msg_session_property_info_packet *)
-					msg_hdr);
-		break;
-	case HFI_MSG_SESSION_RELEASE_RESOURCES_DONE:
-		hal_process_session_rel_res_done(device,
-			(struct hfi_msg_session_release_resources_done_packet *)
-					msg_hdr);
-		break;
-	case HFI_MSG_SYS_RELEASE_RESOURCE:
-		hal_process_sys_rel_resource_done(device,
-			(struct hfi_msg_sys_release_resource_done_packet *)
-			msg_hdr);
-		break;
-	case HFI_MSG_SESSION_GET_SEQUENCE_HEADER_DONE:
-		hal_process_session_get_seq_hdr_done(device, (struct
-			hfi_msg_session_get_sequence_header_done_packet
-			 *) msg_hdr);
-		break;
-	case HFI_MSG_SESSION_RELEASE_BUFFERS_DONE:
-		hal_process_session_rel_buf_done(device, (struct
-			hfi_msg_session_release_buffers_done_packet
-			*) msg_hdr);
-		break;
-	default:
-		dprintk(VIDC_ERR, "UNKNOWN_MSG_TYPE : %d", msg_hdr->packet);
-		break;
-	}
-}
-
-void vidc_hal_response_handler(struct hal_device *device)
-{
-	u8 packet[VIDC_IFACEQ_MED_PKT_SIZE];
-
-	dprintk(VIDC_INFO, "#####vidc_hal_response_handler#####\n");
-	if (device) {
-		while (!vidc_hal_iface_msgq_read(device, packet)) {
-			hal_process_msg_packet(device,
-				(struct vidc_hal_msg_pkt_hdr *) packet);
-		}
-		while (!vidc_hal_iface_dbgq_read(device, packet)) {
-			struct hfi_msg_sys_debug_packet *pkt =
-				(struct hfi_msg_sys_debug_packet *) packet;
-			dprintk(VIDC_FW, "FW-SAYS: %s", pkt->rg_msg_data);
-		}
-	} else {
-		dprintk(VIDC_ERR, "SPURIOUS_INTERRUPT");
-	}
-}
diff --git a/drivers/media/video/msm_vidc/vidc_hal_io.h b/drivers/media/video/msm_vidc/vidc_hal_io.h
deleted file mode 100644
index 9888adb..0000000
--- a/drivers/media/video/msm_vidc/vidc_hal_io.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 __VIDCHALIO_H__
-#define __VIDCHALIO_H__
-
-#include <linux/io.h>
-
-#define VENUS_VCODEC_SS_CLOCK_HALT     0x0000000C
-#define VENUS_VPP_CORE_SW_RESET        0x00042004
-#define VENUS_VPP_CTRL_CTRL_RESET      0x00041008
-
-#define VIDC_VBIF_BASE_OFFS			0x00080000
-#define VIDC_VBIF_VERSION			(VIDC_VBIF_BASE_OFFS + 0x00)
-#define VIDC_VENUS_VBIF_DDR_OUT_MAX_BURST		\
-			(VIDC_VBIF_BASE_OFFS + 0xD8)
-#define VIDC_VENUS_VBIF_OCMEM_OUT_MAX_BURST		\
-			(VIDC_VBIF_BASE_OFFS + 0xDC)
-#define VIDC_VENUS_VBIF_ROUND_ROBIN_QOS_ARB		\
-			(VIDC_VBIF_BASE_OFFS + 0x124)
-
-#define VIDC_CPU_BASE_OFFS			0x000C0000
-#define VIDC_CPU_CS_BASE_OFFS		(VIDC_CPU_BASE_OFFS + 0x00012000)
-#define VIDC_CPU_IC_BASE_OFFS		(VIDC_CPU_BASE_OFFS + 0x0001F000)
-
-#define VIDC_CPU_CS_REMAP_OFFS		(VIDC_CPU_CS_BASE_OFFS + 0x00)
-#define VIDC_CPU_CS_TIMER_CONTROL	(VIDC_CPU_CS_BASE_OFFS + 0x04)
-#define VIDC_CPU_CS_A2HSOFTINTEN	(VIDC_CPU_CS_BASE_OFFS + 0x10)
-#define VIDC_CPU_CS_A2HSOFTINTENCLR	(VIDC_CPU_CS_BASE_OFFS + 0x14)
-#define VIDC_CPU_CS_A2HSOFTINT		(VIDC_CPU_CS_BASE_OFFS + 0x18)
-#define VIDC_CPU_CS_A2HSOFTINTCLR	(VIDC_CPU_CS_BASE_OFFS + 0x1C)
-#define VIDC_CPU_CS_SCIACMD			(VIDC_CPU_CS_BASE_OFFS + 0x48)
-
-/* HFI_CTRL_STATUS */
-#define VIDC_CPU_CS_SCIACMDARG0		(VIDC_CPU_CS_BASE_OFFS + 0x4C)
-#define VIDC_CPU_CS_SCIACMDARG0_BMSK	0xff
-#define VIDC_CPU_CS_SCIACMDARG0_SHFT	0x0
-#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK	0xfe
-#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_SHFT	0x1
-#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_STATUS_BMSK	0x1
-#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_STATUS_SHFT	0x0
-
-/* HFI_QTBL_INFO */
-#define VIDC_CPU_CS_SCIACMDARG1		(VIDC_CPU_CS_BASE_OFFS + 0x50)
-
-/* HFI_QTBL_ADDR */
-#define VIDC_CPU_CS_SCIACMDARG2		(VIDC_CPU_CS_BASE_OFFS + 0x54)
-
-/* HFI_VERSION_INFO */
-#define VIDC_CPU_CS_SCIACMDARG3		(VIDC_CPU_CS_BASE_OFFS + 0x58)
-#define VIDC_CPU_IC_IRQSTATUS		(VIDC_CPU_IC_BASE_OFFS + 0x00)
-#define VIDC_CPU_IC_FIQSTATUS		(VIDC_CPU_IC_BASE_OFFS + 0x04)
-#define VIDC_CPU_IC_RAWINTR			(VIDC_CPU_IC_BASE_OFFS + 0x08)
-#define VIDC_CPU_IC_INTSELECT		(VIDC_CPU_IC_BASE_OFFS + 0x0C)
-#define VIDC_CPU_IC_INTENABLE		(VIDC_CPU_IC_BASE_OFFS + 0x10)
-#define VIDC_CPU_IC_INTENACLEAR		(VIDC_CPU_IC_BASE_OFFS + 0x14)
-#define VIDC_CPU_IC_SOFTINT			(VIDC_CPU_IC_BASE_OFFS + 0x18)
-#define VIDC_CPU_IC_SOFTINT_H2A_BMSK	0x8000
-#define VIDC_CPU_IC_SOFTINT_H2A_SHFT	0xF
-#define VIDC_CPU_IC_SOFTINTCLEAR	(VIDC_CPU_IC_BASE_OFFS + 0x1C)
-
-/*---------------------------------------------------------------------------
- * MODULE: vidc_wrapper
- *--------------------------------------------------------------------------*/
-#define VIDC_WRAPPER_BASE_OFFS		0x000E0000
-
-#define VIDC_WRAPPER_HW_VERSION		(VIDC_WRAPPER_BASE_OFFS + 0x00)
-#define VIDC_WRAPPER_CLOCK_CONFIG	(VIDC_WRAPPER_BASE_OFFS + 0x04)
-
-#define VIDC_WRAPPER_INTR_STATUS	(VIDC_WRAPPER_BASE_OFFS + 0x0C)
-#define VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK	0x10
-#define VIDC_WRAPPER_INTR_STATUS_A2HWD_SHFT	0x4
-#define VIDC_WRAPPER_INTR_STATUS_A2H_BMSK	0x4
-#define VIDC_WRAPPER_INTR_STATUS_A2H_SHFT	0x2
-
-#define VIDC_WRAPPER_INTR_MASK		(VIDC_WRAPPER_BASE_OFFS + 0x10)
-#define VIDC_WRAPPER_INTR_MASK_A2HWD_BMSK	0x10
-#define VIDC_WRAPPER_INTR_MASK_A2HWD_SHFT	0x4
-#define VIDC_WRAPPER_INTR_MASK_A2H_BMSK		0x4
-#define VIDC_WRAPPER_INTR_MASK_A2H_SHFT		0x2
-
-#define VIDC_WRAPPER_INTR_CLEAR		(VIDC_WRAPPER_BASE_OFFS + 0x14)
-#define VIDC_WRAPPER_INTR_CLEAR_A2HWD_BMSK	0x10
-#define VIDC_WRAPPER_INTR_CLEAR_A2HWD_SHFT	0x4
-#define VIDC_WRAPPER_INTR_CLEAR_A2H_BMSK	0x4
-#define VIDC_WRAPPER_INTR_CLEAR_A2H_SHFT	0x2
-
-#define VIDC_WRAPPER_VBIF_XIN_SW_RESET	(VIDC_WRAPPER_BASE_OFFS + 0x18)
-#define VIDC_WRAPPER_VBIF_XIN_STATUS	(VIDC_WRAPPER_BASE_OFFS + 0x1C)
-#define VIDC_WRAPPER_CPU_CLOCK_CONFIG	(VIDC_WRAPPER_BASE_OFFS + 0x2000)
-#define VIDC_WRAPPER_VBIF_XIN_CPU_SW_RESET	\
-				(VIDC_WRAPPER_BASE_OFFS + 0x2004)
-#define VIDC_WRAPPER_AXI_HALT		(VIDC_WRAPPER_BASE_OFFS + 0x2008)
-#define VIDC_WRAPPER_AXI_HALT_STATUS	(VIDC_WRAPPER_BASE_OFFS + 0x200C)
-#define VIDC_WRAPPER_CPU_CGC_DIS	(VIDC_WRAPPER_BASE_OFFS + 0x2010)
-#define VIDC_VENUS_VBIF_CLK_ON		(VIDC_VBIF_BASE_OFFS + 0x4)
-#define VIDC_VBIF_IN_RD_LIM_CONF0       (VIDC_VBIF_BASE_OFFS + 0xB0)
-#define VIDC_VBIF_IN_RD_LIM_CONF1       (VIDC_VBIF_BASE_OFFS + 0xB4)
-#define VIDC_VBIF_IN_RD_LIM_CONF2       (VIDC_VBIF_BASE_OFFS + 0xB8)
-#define VIDC_VBIF_IN_RD_LIM_CONF3       (VIDC_VBIF_BASE_OFFS + 0xBC)
-#define VIDC_VBIF_IN_WR_LIM_CONF0       (VIDC_VBIF_BASE_OFFS + 0xC0)
-#define VIDC_VBIF_IN_WR_LIM_CONF1       (VIDC_VBIF_BASE_OFFS + 0xC4)
-#define VIDC_VBIF_IN_WR_LIM_CONF2       (VIDC_VBIF_BASE_OFFS + 0xC8)
-#define VIDC_VBIF_IN_WR_LIM_CONF3       (VIDC_VBIF_BASE_OFFS + 0xCC)
-#define VIDC_VBIF_OUT_RD_LIM_CONF0      (VIDC_VBIF_BASE_OFFS + 0xD0)
-#define VIDC_VBIF_OUT_WR_LIM_CONF0      (VIDC_VBIF_BASE_OFFS + 0xD4)
-#define VIDC_VBIF_DDR_OUT_MAX_BURST     (VIDC_VBIF_BASE_OFFS + 0xD8)
-#define VIDC_VBIF_OCMEM_OUT_MAX_BURST   (VIDC_VBIF_BASE_OFFS + 0xDC)
-#define VIDC_VBIF_DDR_ARB_CONF0         (VIDC_VBIF_BASE_OFFS + 0xF4)
-#define VIDC_VBIF_DDR_ARB_CONF1         (VIDC_VBIF_BASE_OFFS + 0xF8)
-#define VIDC_VBIF_ROUND_ROBIN_QOS_ARB   (VIDC_VBIF_BASE_OFFS + 0x124)
-#define VIDC_VBIF_OUT_AXI_AOOO_EN       (VIDC_VBIF_BASE_OFFS + 0x178)
-#define VIDC_VBIF_OUT_AXI_AOOO          (VIDC_VBIF_BASE_OFFS + 0x17C)
-#define VIDC_VBIF_ARB_CTL               (VIDC_VBIF_BASE_OFFS + 0xF0)
-#define VIDC_VBIF_OUT_AXI_AMEMTYPE_CONF0 (VIDC_VBIF_BASE_OFFS + 0x160)
-#define VIDC_VBIF_OUT_AXI_AMEMTYPE_CONF1 (VIDC_VBIF_BASE_OFFS + 0x164)
-#define VIDC_VBIF_ADDR_TRANS_EN         (VIDC_VBIF_BASE_OFFS + 0xC00)
-#define VIDC_VBIF_AT_OLD_BASE           (VIDC_VBIF_BASE_OFFS + 0xC04)
-#define VIDC_VBIF_AT_OLD_HIGH           (VIDC_VBIF_BASE_OFFS + 0xC08)
-#define VIDC_VBIF_AT_NEW_BASE           (VIDC_VBIF_BASE_OFFS + 0xC10)
-#define VIDC_VBIF_AT_NEW_HIGH           (VIDC_VBIF_BASE_OFFS + 0xC18)
-
-#define VIDC_VENUS0_WRAPPER_VBIF_REQ_PRIORITY \
-	(VIDC_WRAPPER_BASE_OFFS + 0x20)
-#define VIDC_VENUS0_WRAPPER_VBIF_PRIORITY_LEVEL \
-	(VIDC_WRAPPER_BASE_OFFS + 0x24)
-
-#define VIDC_CTRL_INIT 0x000D2048
-#define VIDC_CTRL_INIT_RESERVED_BITS31_1__M 0xFFFFFFFE
-#define VIDC_CTRL_INIT_RESERVED_BITS31_1__S 1
-#define VIDC_CTRL_INIT_CTRL__M 0x00000001
-#define VIDC_CTRL_INIT_CTRL__S 0
-
-#define VIDC_CTRL_STATUS 0x000D204C
-#define VIDC_CTRL_STATUS_RESERVED_BITS31_8__M 0xFFFFFF00
-#define VIDC_CTRL_STATUS_RESERVED_BITS31_8__S 8
-#define VIDC_CTRL_ERROR_STATUS__M             0x000000FE
-#define VIDC_CTRL_ERROR_STATUS__S             1
-#define VIDC_CTRL_INIT_STATUS__M              0x00000001
-#define VIDC_CTRL_INIT_STATUS__S              0
-
-#define VIDC_QTBL_INFO 0x000D2050
-#define VIDC_QTBL_HOSTID__M 0xFF000000
-#define VIDC_QTBL_HOSTID__S 24
-#define VIDC_QTBL_INFO_RESERVED_BITS23_8__M 0x00FFFF00
-#define VIDC_QTBL_INFO_RESERVED_BITS23_8__S 8
-#define VIDC_QTBL_STATUS__M 0x000000FF
-#define VIDC_QTBL_STATUS__S 0
-
-#define VIDC_QTBL_ADDR 0x000D2054
-
-#define VIDC_VERSION_INFO 0x000D2058
-#define VIDC_VERSION_INFO_MAJOR__M  0xF0000000
-#define VIDC_VERSION_INFO_MAJOR__S  28
-#define VIDC_VERSION_INFO_MINOR__M  0x0FFFFFE0
-#define VIDC_VERSION_INFO_MINOR__S  5
-#define VIDC_VERSION_INFO_BRANCH__M 0x0000001F
-#define VIDC_VERSION_INFO_BRANCH__S 0
-
-#define VIDC_SFR_ADDR 0x000D205C
-#define VIDC_MMAP_ADDR 0x000D2060
-#define VIDC_UC_REGION_ADDR 0x000D2064
-#define VIDC_UC_REGION_SIZE 0x000D2068
-
-#endif
diff --git a/drivers/media/video/msm_wfd/enc-mfc-subdev.c b/drivers/media/video/msm_wfd/enc-mfc-subdev.c
deleted file mode 100644
index aadf5ed..0000000
--- a/drivers/media/video/msm_wfd/enc-mfc-subdev.c
+++ /dev/null
@@ -1,2564 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 <media/v4l2-subdev.h>
-#include <mach/iommu_domains.h>
-#include "enc-subdev.h"
-#include "wfd-util.h"
-#include <media/msm/vcd_api.h>
-#include <media/msm/vidc_init.h>
-#include <media/msm/vcd_property.h>
-#include <linux/time.h>
-#include <linux/ktime.h>
-
-#define VID_ENC_MAX_ENCODER_CLIENTS 1
-#define MAX_NUM_CTRLS 20
-#define V4L2_FRAME_FLAGS (V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_PFRAME | \
-		V4L2_BUF_FLAG_BFRAME | V4L2_QCOM_BUF_FLAG_CODECCONFIG)
-
-static long venc_fill_outbuf(struct v4l2_subdev *sd, void *arg);
-
-struct venc_inst {
-	struct video_client_ctx venc_client;
-	void *cbdata;
-	void (*op_buffer_done)(void *cookie, u32 status,
-			struct vb2_buffer *buf);
-	void (*ip_buffer_done)(void *cookie, u32 status,
-			struct mem_region *mregion);
-	u32 width;
-	u32 height;
-	int secure;
-	struct mem_region unqueued_op_bufs;
-	bool streaming;
-	enum venc_framerate_modes framerate_mode;
-};
-
-struct venc {
-	s32 device_handle;
-	void *virt_base;
-	struct venc_inst venc_clients[VID_ENC_MAX_ENCODER_CLIENTS];
-	struct mutex lock;
-	struct ion_client *iclient;
-};
-
-static struct venc venc_p;
-
-static void *venc_map_dev_base_addr(void *device_name)
-{
-		return venc_p.virt_base;
-}
-
-static void venc_interrupt_deregister(void)
-{
-}
-
-static void venc_interrupt_register(void *device_name)
-{
-}
-
-static void venc_interrupt_clear(void)
-{
-}
-
-int venc_load_fw(struct v4l2_subdev *sd)
-{
-	return !vidc_load_firmware();
-}
-
-static u32 venc_get_empty_client_index(void)
-{
-	u32 i;
-	u32 found = false;
-
-	for (i = 0; i < VID_ENC_MAX_ENCODER_CLIENTS; i++) {
-		if (!venc_p.venc_clients[i].venc_client.vcd_handle) {
-			found = true;
-			break;
-		}
-	}
-	if (!found) {
-		WFD_MSG_ERR("%s():ERROR No space for new client\n",
-				__func__);
-		return -ENOMEM;
-	}
-	WFD_MSG_INFO("%s(): available client index = %u\n",
-				__func__, i);
-	return i;
-}
-
-int venc_init(struct v4l2_subdev *sd, u32 val)
-{
-	struct vcd_init_config vcd_init_config;
-	mutex_init(&venc_p.lock);
-	venc_p.virt_base = vidc_get_ioaddr();
-	vcd_init_config.device_name = "VIDC";
-	vcd_init_config.map_dev_base_addr = venc_map_dev_base_addr;
-	vcd_init_config.interrupt_clr = venc_interrupt_clear;
-	vcd_init_config.register_isr = venc_interrupt_register;
-	vcd_init_config.deregister_isr = venc_interrupt_deregister;
-	vcd_init(&vcd_init_config, &venc_p.device_handle);
-	return 0;
-}
-
-static void venc_notify_client(struct video_client_ctx *client_ctx)
-{
-	if (client_ctx)
-		complete(&client_ctx->event);
-}
-
-static void venc_open_done(struct video_client_ctx *client_ctx,
-	struct vcd_handle_container *handle_container)
-{
-	if (client_ctx) {
-		if (handle_container)
-			client_ctx->vcd_handle = handle_container->handle;
-		else
-			WFD_MSG_ERR("handle_container is NULL\n");
-		venc_notify_client(client_ctx);
-	} else
-		WFD_MSG_ERR("ERROR. client_ctx is NULL");
-}
-
-static void venc_start_done(struct video_client_ctx *client_ctx, u32 status)
-{
-	if (client_ctx)
-		venc_notify_client(client_ctx);
-	else
-		WFD_MSG_ERR("ERROR. client_ctx is NULL");
-}
-
-static void venc_stop_done(struct video_client_ctx *client_ctx, u32 status)
-{
-	WFD_MSG_DBG("Inside venc_stop_done: E\n");
-	if (client_ctx)
-		venc_notify_client(client_ctx);
-	else
-		WFD_MSG_ERR("ERROR. client_ctx is NULL");
-	WFD_MSG_DBG("Inside venc_stop_done: X\n");
-}
-
-static void venc_cb(u32 event, u32 status, void *info, u32 size, void *handle,
-		void *const client_data)
-{
-	struct venc_inst *inst = client_data;
-	struct video_client_ctx *client_ctx = &inst->venc_client;
-	struct vb2_buffer *vbuf;
-	struct mem_region *mregion;
-	struct vcd_frame_data *frame_data = (struct vcd_frame_data *)info;
-
-	if (!client_ctx) {
-		WFD_MSG_ERR("Client context is NULL\n");
-		return;
-	}
-	client_ctx->event_status = status;
-	switch (event) {
-	case VCD_EVT_RESP_OPEN:
-		WFD_MSG_DBG("EVENT: open done = %d\n", event);
-		venc_open_done(client_ctx,
-				(struct vcd_handle_container *)info);
-		break;
-	case VCD_EVT_RESP_INPUT_DONE:
-	case VCD_EVT_RESP_INPUT_FLUSHED:
-		WFD_MSG_DBG("EVENT: input done = %d\n", event);
-		mregion = (struct mem_region *)
-			frame_data->frm_clnt_data;
-		inst->ip_buffer_done(inst->cbdata, status, mregion);
-		break;
-	case VCD_EVT_RESP_OUTPUT_DONE:
-	case VCD_EVT_RESP_OUTPUT_FLUSHED:
-		WFD_MSG_DBG("EVENT: output done = %d\n", event);
-		vbuf = (struct vb2_buffer *)
-			frame_data->frm_clnt_data;
-		vbuf->v4l2_planes[0].bytesused =
-			frame_data->data_len;
-
-		vbuf->v4l2_buf.flags &= ~(V4L2_FRAME_FLAGS);
-		switch (frame_data->frame) {
-		case VCD_FRAME_I:
-		case VCD_FRAME_IDR:
-			vbuf->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME;
-			break;
-		case VCD_FRAME_P:
-			vbuf->v4l2_buf.flags |= V4L2_BUF_FLAG_PFRAME;
-			break;
-		case VCD_FRAME_B:
-			vbuf->v4l2_buf.flags |= V4L2_BUF_FLAG_BFRAME;
-			break;
-		default:
-			break;
-		}
-
-		if (frame_data->flags & VCD_FRAME_FLAG_CODECCONFIG)
-			vbuf->v4l2_buf.flags |= V4L2_QCOM_BUF_FLAG_CODECCONFIG;
-
-		vbuf->v4l2_buf.timestamp =
-			ns_to_timeval(frame_data->time_stamp * NSEC_PER_USEC);
-
-		WFD_MSG_DBG("bytes used %d, ts: %d.%d, frame type is %d\n",
-				frame_data->data_len,
-				(int)vbuf->v4l2_buf.timestamp.tv_sec,
-				(int)vbuf->v4l2_buf.timestamp.tv_usec,
-				frame_data->frame);
-
-		/*
-		 * Output buffers are enc-subdev and vcd's problem, so
-		 * if buffer is cached, need to flush before giving to
-		 * client. So doing the dirty stuff in this little context
-		 */
-		{
-			unsigned long kvaddr, phys_addr;
-			s32 buffer_index = -1, ion_flags = 0;
-			struct ion_handle *ion_handle;
-			int pmem_fd;
-			struct file *filp;
-			bool rc;
-
-			rc = vidc_lookup_addr_table(client_ctx,
-					BUFFER_TYPE_OUTPUT, true,
-					(unsigned long *)&frame_data->
-					frm_clnt_data, &kvaddr, &phys_addr,
-					&pmem_fd, &filp, &buffer_index);
-
-			if (rc)
-				ion_flags = vidc_get_fd_info(client_ctx,
-					BUFFER_TYPE_OUTPUT, pmem_fd,
-					kvaddr, buffer_index, &ion_handle);
-			else
-				WFD_MSG_ERR("Got an output buffer that we " \
-						"couldn't recognize!\n");
-
-			if (msm_ion_do_cache_op(client_ctx->user_ion_client,
-				ion_handle, &kvaddr, frame_data->data_len,
-				ION_IOC_CLEAN_INV_CACHES))
-				WFD_MSG_ERR("OP buffer flush failed\n");
-
-		}
-
-		inst->op_buffer_done(inst->cbdata, status, vbuf);
-		break;
-	case VCD_EVT_RESP_START:
-		WFD_MSG_DBG("EVENT: start done = %d\n", event);
-		venc_start_done(client_ctx, status);
-		/*TODO: should wait for this event*/
-		break;
-	case VCD_EVT_RESP_STOP:
-		WFD_MSG_DBG("EVENT: not expected = %d\n", event);
-		venc_stop_done(client_ctx, status);
-		break;
-	case VCD_EVT_RESP_FLUSH_INPUT_DONE:
-	case VCD_EVT_RESP_FLUSH_OUTPUT_DONE:
-		venc_notify_client(client_ctx);
-		break;
-	case VCD_EVT_RESP_PAUSE:
-	case VCD_EVT_IND_OUTPUT_RECONFIG:
-		WFD_MSG_DBG("EVENT: not expected = %d\n", event);
-		break;
-	case VCD_EVT_IND_HWERRFATAL:
-	case VCD_EVT_IND_RESOURCES_LOST:
-		WFD_MSG_DBG("EVENT: error = %d\n", event);
-		break;
-	default:
-		WFD_MSG_ERR("Invalid event type = %u\n", event);
-		break;
-	}
-}
-
-static long venc_open(struct v4l2_subdev *sd, void *arg)
-{
-	u32 client_index;
-	int rc = 0;
-	struct venc_inst *inst;
-	struct video_client_ctx *client_ctx;
-	struct venc_msg_ops *vmops  =  arg;
-	int flags = 0;
-	mutex_lock(&venc_p.lock);
-	client_index = venc_get_empty_client_index();
-	if (client_index < 0) {
-		WFD_MSG_ERR("No free clients, client_index = %d\n",
-				client_index);
-		rc = -ENODEV;
-		goto no_free_client;
-	}
-	inst = &venc_p.venc_clients[client_index];
-	client_ctx = &inst->venc_client;
-	init_completion(&client_ctx->event);
-	mutex_init(&client_ctx->msg_queue_lock);
-	mutex_init(&client_ctx->enrty_queue_lock);
-	INIT_LIST_HEAD(&client_ctx->msg_queue);
-	init_waitqueue_head(&client_ctx->msg_wait);
-	inst->op_buffer_done = vmops->op_buffer_done;
-	inst->ip_buffer_done = vmops->ip_buffer_done;
-	INIT_LIST_HEAD(&inst->unqueued_op_bufs.list);
-	inst->cbdata = vmops->cbdata;
-	inst->secure = vmops->secure;
-	inst->streaming = false;
-	inst->framerate_mode = VENC_MODE_VFR;
-
-	if (vmops->secure) {
-		WFD_MSG_ERR("OPENING SECURE SESSION\n");
-		flags |= VCD_CP_SESSION;
-	}
-	if (vcd_get_ion_status()) {
-		client_ctx->user_ion_client = vcd_get_ion_client();
-		if (!client_ctx->user_ion_client) {
-			WFD_MSG_ERR("vcd_open ion get client failed");
-			return -EFAULT;
-		}
-	}
-
-	rc = vcd_open(venc_p.device_handle, false, venc_cb,
-				inst, flags);
-	if (rc) {
-		WFD_MSG_ERR("vcd_open failed, rc = %d\n", rc);
-		rc = -ENODEV;
-		goto no_free_client;
-	}
-	wait_for_completion(&client_ctx->event);
-	if (client_ctx->event_status) {
-		WFD_MSG_ERR("callback for vcd_open returned error: %u",
-				client_ctx->event_status);
-		goto no_free_client;
-	}
-	WFD_MSG_ERR("NOTE: client_ctx = %p\n", client_ctx);
-	vmops->cookie = inst;
-	sd->dev_priv = inst;
-no_free_client:
-	mutex_unlock(&venc_p.lock);
-	return rc;
-}
-
-static long venc_close(struct v4l2_subdev *sd, void *arg)
-{
-	long rc = 0;
-	struct venc_inst *inst;
-	struct video_client_ctx *client_ctx = NULL;
-	mutex_lock(&venc_p.lock);
-	inst = sd->dev_priv;
-	client_ctx = &inst->venc_client;
-	if (!client_ctx || !client_ctx->vcd_handle) {
-		WFD_MSG_ERR("Invalid client context in close\n");
-		rc = -ENODEV;
-		goto end;
-	}
-	rc = vcd_close(client_ctx->vcd_handle);
-	if (rc) {
-		WFD_MSG_ERR("Failed to close encoder subdevice\n");
-		goto end;
-	}
-	memset((void *)client_ctx, 0,
-			sizeof(struct video_client_ctx));
-end:
-	mutex_unlock(&venc_p.lock);
-	return rc;
-}
-
-static long venc_get_buffer_req(struct v4l2_subdev *sd, void *arg)
-{
-	int rc = 0;
-	struct v4l2_requestbuffers *b = arg;
-	struct vcd_buffer_requirement buf_req;
-	struct venc_inst *inst = sd->dev_priv;
-	struct video_client_ctx *client_ctx = &inst->venc_client;
-	if (!client_ctx) {
-		WFD_MSG_ERR("Invalid client context");
-		rc = -EINVAL;
-		goto err;
-	}
-	rc = vcd_get_buffer_requirements(client_ctx->vcd_handle,
-			VCD_BUFFER_OUTPUT, &buf_req);
-	if (rc) {
-		WFD_MSG_ERR("Failed to get out buf reqs rc = %d", rc);
-		goto err;
-	}
-
-	buf_req.actual_count = b->count = max(buf_req.min_count, b->count);
-	rc = vcd_set_buffer_requirements(client_ctx->vcd_handle,
-			VCD_BUFFER_OUTPUT, &buf_req);
-	if (rc) {
-		WFD_MSG_ERR("Failed to set out buf reqs rc = %d", rc);
-		goto err;
-	}
-
-err:
-	return rc;
-}
-
-static long venc_set_buffer_req(struct v4l2_subdev *sd, void *arg)
-{
-	int rc = 0;
-	struct bufreq *b = arg;
-	struct vcd_buffer_requirement buf_req;
-	struct venc_inst *inst = sd->dev_priv;
-	struct video_client_ctx *client_ctx = &inst->venc_client;
-	int aligned_width, aligned_height;
-	if (!client_ctx) {
-		WFD_MSG_ERR("Invalid client context");
-		rc = -EINVAL;
-		goto err;
-	}
-	aligned_width = ALIGN(b->width, 16);
-	aligned_height = ALIGN(b->height, 16);
-
-	if (aligned_width != b->width) {
-		WFD_MSG_ERR("Width not 16 byte aligned\n");
-		rc = -EINVAL;
-		goto err;
-	}
-
-	buf_req.actual_count = b->count;
-	buf_req.min_count = b->count;
-	buf_req.max_count = b->count;
-	buf_req.sz = ALIGN(aligned_height * aligned_width, SZ_2K)
-		+ ALIGN(aligned_height * aligned_width * 1/2, SZ_2K);
-	buf_req.align = SZ_4K;
-	inst->width = b->width;
-	inst->height = b->height;
-	rc = vcd_set_buffer_requirements(client_ctx->vcd_handle,
-			VCD_BUFFER_INPUT, &buf_req);
-	if (rc) {
-		WFD_MSG_ERR("Failed to get out buf reqs rc = %d", rc);
-		goto err;
-	}
-	b->size = buf_req.sz;
-err:
-	return rc;
-}
-
-static long venc_start(struct v4l2_subdev *sd)
-{
-	struct venc_inst *inst = sd->dev_priv;
-	struct video_client_ctx *client_ctx = &inst->venc_client;
-	struct mem_region *curr = NULL, *temp = NULL;
-	int rc;
-	if (!client_ctx) {
-		WFD_MSG_ERR("Client context is NULL");
-		return -EINVAL;
-	}
-
-	rc = vcd_encode_start(client_ctx->vcd_handle);
-	if (rc) {
-		WFD_MSG_ERR("vcd_encode_start failed, rc = %d\n", rc);
-		goto err;
-	}
-	wait_for_completion(&client_ctx->event);
-	if (client_ctx->event_status)
-		WFD_MSG_ERR("callback for vcd_encode_start returned error: %u",
-				client_ctx->event_status);
-
-	inst->streaming = true;
-	/* Push any buffers that we have held back */
-	list_for_each_entry_safe(curr, temp,
-			&inst->unqueued_op_bufs.list, list) {
-		venc_fill_outbuf(sd, curr);
-		list_del(&curr->list);
-		kfree(curr);
-	}
-err:
-	return rc;
-}
-
-static long venc_stop(struct v4l2_subdev *sd)
-{
-	struct venc_inst *inst = sd->dev_priv;
-	struct video_client_ctx *client_ctx = &inst->venc_client;
-	struct mem_region *curr = NULL, *temp = NULL;
-	int rc;
-	if (!client_ctx) {
-		WFD_MSG_ERR("Client context is NULL");
-		return -EINVAL;
-	}
-	rc = vcd_stop(client_ctx->vcd_handle);
-	wait_for_completion(&client_ctx->event);
-	inst->streaming = false;
-	/* Drop whatever frames we haven't queued */
-	list_for_each_entry_safe(curr, temp,
-			&inst->unqueued_op_bufs.list, list) {
-		inst->op_buffer_done(inst->cbdata, 0,
-				(struct vb2_buffer *)curr->cookie);
-		list_del(&curr->list);
-		kfree(curr);
-	}
-	return rc;
-}
-
-static long venc_set_codec(struct video_client_ctx *client_ctx, __s32 codec)
-{
-	struct vcd_property_codec vcd_property_codec;
-	struct vcd_property_hdr vcd_property_hdr;
-	vcd_property_hdr.prop_id = VCD_I_CODEC;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
-	vcd_property_codec.codec = VCD_CODEC_H264;
-
-	switch (codec) {
-	case V4L2_PIX_FMT_H264:
-		vcd_property_codec.codec = VCD_CODEC_H264;
-		break;
-	case V4L2_PIX_FMT_MPEG4:
-		vcd_property_codec.codec = VCD_CODEC_MPEG4;
-		break;
-	default:
-		WFD_MSG_ERR("Codec not supported, defaulting to h264\n");
-		break;
-	}
-	return vcd_set_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &vcd_property_codec);
-}
-
-static long venc_set_codec_level(struct video_client_ctx *client_ctx,
-					__s32 codec, __s32 level)
-{
-	struct vcd_property_level vcd_property_level;
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_codec vcd_property_codec;
-
-	int rc = 0;
-	int mpeg4_base = VCD_LEVEL_MPEG4_0;
-	int h264_base = VCD_LEVEL_H264_1;
-
-	/* Validate params */
-	vcd_property_hdr.prop_id = VCD_I_CODEC;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
-	rc = vcd_get_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &vcd_property_codec);
-
-	if (rc < 0) {
-		WFD_MSG_ERR("Error getting codec property");
-		rc = -EINVAL;
-		goto err;
-	}
-
-	if (!((vcd_property_codec.codec == VCD_CODEC_H264
-		&& codec == V4L2_CID_MPEG_VIDEO_H264_LEVEL) ||
-		(vcd_property_codec.codec == VCD_CODEC_MPEG4
-		&& codec == V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL))) {
-		WFD_MSG_ERR("Attempting to set %d for codec type %d",
-			codec, vcd_property_codec.codec);
-		rc = -EINVAL;
-		goto err;
-	}
-
-	/* Set property */
-	vcd_property_hdr.prop_id = VCD_I_LEVEL;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_level);
-
-	if (codec == V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL) {
-		vcd_property_level.level = mpeg4_base + level;
-
-		if (vcd_property_level.level < VCD_LEVEL_MPEG4_0
-			|| vcd_property_level.level > VCD_LEVEL_MPEG4_X) {
-			WFD_MSG_ERR("Level (%d) out of range for codec (%d)\n",
-					level, codec);
-
-			rc = -EINVAL;
-			goto err;
-		}
-	} else if (codec == V4L2_CID_MPEG_VIDEO_H264_LEVEL) {
-		vcd_property_level.level = h264_base + level;
-
-		if (vcd_property_level.level < VCD_LEVEL_H264_1
-			|| vcd_property_level.level > VCD_LEVEL_H264_5p1) {
-			WFD_MSG_ERR("Level (%d) out of range for codec (%d)\n",
-					level, codec);
-
-			rc = -EINVAL;
-			goto err;
-		}
-	} else {
-		WFD_MSG_ERR("Codec (%d) not supported, not setting level (%d)",
-				codec, level);
-		rc = -ENOTSUPP;
-		goto err;
-	}
-
-	rc = vcd_set_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &vcd_property_level);
-err:
-	return rc;
-}
-
-static long venc_get_codec_level(struct video_client_ctx *client_ctx,
-					__s32 codec, __s32 *level)
-{
-	struct vcd_property_level vcd_property_level;
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_codec vcd_property_codec;
-
-	int rc = 0;
-	int mpeg4_base = VCD_LEVEL_MPEG4_0;
-	int h264_base = VCD_LEVEL_H264_1;
-
-	/* Validate params */
-	vcd_property_hdr.prop_id = VCD_I_CODEC;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
-	rc = vcd_get_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &vcd_property_codec);
-
-	if (rc < 0) {
-		WFD_MSG_ERR("Error getting codec property");
-		rc = -EINVAL;
-		goto err;
-	}
-
-	if (!((vcd_property_codec.codec == VCD_CODEC_H264
-		&& codec == V4L2_CID_MPEG_VIDEO_H264_LEVEL) ||
-		(vcd_property_codec.codec == VCD_CODEC_MPEG4
-		&& codec == V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL))) {
-		WFD_MSG_ERR("Attempting to get %d for codec type %d",
-			codec, vcd_property_codec.codec);
-		rc = -EINVAL;
-		goto err;
-	}
-
-	vcd_property_hdr.prop_id = VCD_I_LEVEL;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_level);
-
-	rc = vcd_get_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &vcd_property_level);
-	if (rc < 0) {
-		rc = -EINVAL;
-		goto err;
-	}
-
-	if (codec == V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL) {
-		*level = vcd_property_level.level - mpeg4_base;
-	} else if (codec == V4L2_CID_MPEG_VIDEO_H264_LEVEL) {
-		*level = vcd_property_level.level - h264_base;
-	} else {
-		WFD_MSG_ERR("Codec (%d) not supported", codec);
-		rc = -ENOTSUPP;
-		goto err;
-	}
-
-err:
-	return rc;
-}
-
-static long venc_set_codec_profile(struct video_client_ctx *client_ctx,
-					__s32 codec, __s32 profile)
-{
-	struct vcd_property_profile vcd_property_profile;
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_codec vcd_property_codec;
-	struct vcd_property_i_period vcd_property_i_period;
-	int rc = 0;
-
-	/* Validate params */
-	vcd_property_hdr.prop_id = VCD_I_CODEC;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
-	rc = vcd_get_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &vcd_property_codec);
-
-	if (rc < 0) {
-		WFD_MSG_ERR("Error getting codec property");
-		rc = -EINVAL;
-		goto err_set_profile;
-	}
-
-	if (!((vcd_property_codec.codec == VCD_CODEC_H264
-		&& codec == V4L2_CID_MPEG_VIDEO_H264_PROFILE) ||
-		(vcd_property_codec.codec == VCD_CODEC_MPEG4
-		&& codec == V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE))) {
-		WFD_MSG_ERR("Attempting to set %d for codec type %d",
-			codec, vcd_property_codec.codec);
-		rc = -EINVAL;
-		goto err_set_profile;
-	}
-
-	/* Set property */
-	vcd_property_hdr.prop_id = VCD_I_PROFILE;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_profile);
-
-	if (codec == V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE) {
-		switch (profile) {
-		case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
-			vcd_property_profile.profile = VCD_PROFILE_MPEG4_SP;
-			break;
-		case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
-			vcd_property_profile.profile = VCD_PROFILE_MPEG4_ASP;
-			break;
-		default:
-			WFD_MSG_ERR("Profile %d not supported, defaulting " \
-					"to simple (%d)", profile,
-					VCD_PROFILE_MPEG4_SP);
-			vcd_property_profile.profile = VCD_PROFILE_MPEG4_SP;
-			break;
-		}
-	} else if (codec == V4L2_CID_MPEG_VIDEO_H264_PROFILE) {
-		switch (profile) {
-		case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
-			vcd_property_profile.profile =
-				VCD_PROFILE_H264_BASELINE;
-			break;
-		case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
-			vcd_property_profile.profile = VCD_PROFILE_H264_MAIN;
-			break;
-		case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
-			vcd_property_profile.profile = VCD_PROFILE_H264_HIGH;
-			break;
-		default:
-			WFD_MSG_ERR("Profile %d not supported, defaulting " \
-					"to baseline (%d)", profile,
-					VCD_PROFILE_H264_BASELINE);
-			vcd_property_profile.profile =
-				VCD_PROFILE_H264_BASELINE;
-			break;
-		}
-	} else {
-		WFD_MSG_ERR("Codec (%d) not supported, not "\
-				"setting profile (%d)",	codec, profile);
-		rc = -ENOTSUPP;
-		goto err_set_profile;
-	}
-
-	rc = vcd_set_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &vcd_property_profile);
-
-	/* Disable B-frames, since VSG doesn't support out of order i/p bufs */
-	vcd_property_hdr.prop_id = VCD_I_INTRA_PERIOD;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_i_period);
-
-	rc = vcd_get_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &vcd_property_i_period);
-	if (rc) {
-		WFD_MSG_ERR("Error getting I-period property");
-		goto err_set_profile;
-	}
-	vcd_property_i_period.b_frames = 0;
-	rc = vcd_set_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &vcd_property_i_period);
-	if (rc) {
-		WFD_MSG_ERR("Error setting I-period property");
-		goto err_set_profile;
-	}
-
-err_set_profile:
-	return rc;
-}
-
-static long venc_get_codec_profile(struct video_client_ctx *client_ctx,
-		__s32 codec, __s32 *profile)
-{
-	struct vcd_property_profile vcd_property_profile;
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_codec vcd_property_codec;
-	int rc = 0;
-
-	/* Validate params */
-	vcd_property_hdr.prop_id = VCD_I_CODEC;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
-	rc = vcd_get_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &vcd_property_codec);
-
-	if (rc < 0) {
-		WFD_MSG_ERR("Error getting codec property");
-		rc = -EINVAL;
-		goto err;
-	}
-
-	if (!((vcd_property_codec.codec == VCD_CODEC_H264
-		&& codec == V4L2_CID_MPEG_VIDEO_H264_PROFILE) ||
-		(vcd_property_codec.codec == VCD_CODEC_MPEG4
-		&& codec == V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE))) {
-		WFD_MSG_ERR("Attempting to set %d for codec type %d",
-			codec, vcd_property_codec.codec);
-		rc = -EINVAL;
-		goto err;
-	}
-
-	/* Set property */
-	vcd_property_hdr.prop_id = VCD_I_PROFILE;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_profile);
-
-	rc = vcd_get_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &vcd_property_profile);
-
-	if (rc < 0) {
-		WFD_MSG_ERR("Unable to get property");
-		rc = -EINVAL;
-		goto err;
-	}
-
-	switch (vcd_property_profile.profile) {
-	case VCD_PROFILE_MPEG4_SP:
-		*profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
-		break;
-	case VCD_PROFILE_MPEG4_ASP:
-		*profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE;
-		break;
-	case VCD_PROFILE_H264_BASELINE:
-		*profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
-		break;
-	case VCD_PROFILE_H264_MAIN:
-		*profile = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
-		break;
-	case VCD_PROFILE_H264_HIGH:
-		*profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
-		break;
-	default:
-		WFD_MSG_ERR("Unexpected profile");
-		rc = -EINVAL;
-		goto err;
-		break;
-	}
-err:
-	return rc;
-}
-
-static long venc_set_h264_intra_period(struct video_client_ctx *client_ctx,
-		__s32 period)
-{
-	struct vcd_property_i_period vcd_property_i_period;
-	struct vcd_property_codec vcd_property_codec;
-	struct vcd_property_hdr vcd_property_hdr;
-	int rc = 0;
-
-	vcd_property_hdr.prop_id = VCD_I_CODEC;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
-
-	rc = vcd_get_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &vcd_property_codec);
-
-	if (rc < 0) {
-		WFD_MSG_ERR("Error getting codec property\n");
-		goto err;
-	}
-
-	if (vcd_property_codec.codec != VCD_CODEC_H264) {
-		rc = -ENOTSUPP;
-		WFD_MSG_ERR("Control not supported for non H264 codec\n");
-		goto err;
-	}
-
-	vcd_property_hdr.prop_id = VCD_I_INTRA_PERIOD;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_i_period);
-
-	vcd_property_i_period.p_frames = period - 1;
-	vcd_property_i_period.b_frames = 0;
-
-	rc = vcd_set_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &vcd_property_i_period);
-
-	if (rc < 0) {
-		WFD_MSG_ERR("Error setting intra period\n");
-		goto err;
-	}
-
-err:
-	return rc;
-}
-
-static long venc_get_h264_intra_period(struct video_client_ctx *client_ctx,
-		__s32 *period)
-{
-	struct vcd_property_i_period vcd_property_i_period;
-	struct vcd_property_codec vcd_property_codec;
-	struct vcd_property_hdr vcd_property_hdr;
-	int rc = 0;
-
-	vcd_property_hdr.prop_id = VCD_I_CODEC;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
-
-	rc = vcd_get_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &vcd_property_codec);
-
-	if (rc < 0) {
-		WFD_MSG_ERR("Error getting codec property\n");
-		goto err;
-	}
-
-	if (vcd_property_codec.codec != VCD_CODEC_H264) {
-		rc = -ENOTSUPP;
-		WFD_MSG_ERR("Control not supported for non H264 codec\n");
-		goto err;
-	}
-
-	vcd_property_hdr.prop_id = VCD_I_INTRA_PERIOD;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_i_period);
-
-	rc = vcd_get_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &vcd_property_i_period);
-
-	if (rc < 0) {
-		WFD_MSG_ERR("Error getting intra period\n");
-		goto err;
-	}
-
-	*period = vcd_property_i_period.p_frames + 1;
-err:
-	return rc;
-}
-
-static long venc_request_frame(struct video_client_ctx *client_ctx, __s32 type)
-{
-	struct vcd_property_req_i_frame vcd_property_req_i_frame;
-	struct vcd_property_hdr vcd_property_hdr;
-
-	vcd_property_hdr.prop_id = VCD_I_REQ_IFRAME;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_req_i_frame);
-	vcd_property_req_i_frame.req_i_frame = 1;
-
-	return vcd_set_property(client_ctx->vcd_handle,
-			&vcd_property_hdr, &vcd_property_req_i_frame);
-
-}
-
-static long venc_set_bitrate(struct video_client_ctx *client_ctx,
-			__s32 bitrate)
-{
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_target_bitrate bit_rate;
-	if (!client_ctx || !bitrate)
-		return -EINVAL;
-
-	vcd_property_hdr.prop_id = VCD_I_TARGET_BITRATE;
-	vcd_property_hdr.sz =
-			sizeof(struct vcd_property_target_bitrate);
-	bit_rate.target_bitrate = bitrate;
-	return vcd_set_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &bit_rate);
-}
-
-static long venc_get_bitrate(struct video_client_ctx *client_ctx,
-			__s32 *bitrate)
-{
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_target_bitrate bit_rate;
-	int rc = 0;
-
-	if (!client_ctx || !bitrate)
-		return -EINVAL;
-
-	vcd_property_hdr.prop_id = VCD_I_TARGET_BITRATE;
-	vcd_property_hdr.sz =
-			sizeof(struct vcd_property_target_bitrate);
-	rc = vcd_get_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &bit_rate);
-
-	if (rc < 0) {
-		WFD_MSG_ERR("Failed getting property for bitrate");
-		return rc;
-	}
-
-	*bitrate = bit_rate.target_bitrate;
-	return rc;
-}
-
-static long venc_set_bitrate_mode(struct video_client_ctx *client_ctx,
-			__s32 mode)
-{
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_rate_control rate_control;
-	int rc = 0;
-
-	if (!client_ctx) {
-		rc = -EINVAL;
-		goto err;
-	}
-
-	vcd_property_hdr.prop_id = VCD_I_RATE_CONTROL;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_rate_control);
-	/*
-	 * XXX: V4L doesn't seem have a control to toggle between CFR
-	 * and VFR, so assuming worse case VFR.
-	 */
-	switch (mode) {
-	case V4L2_MPEG_VIDEO_BITRATE_MODE_VBR:
-		rate_control.rate_control = VCD_RATE_CONTROL_VBR_VFR;
-		break;
-	case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR:
-		rate_control.rate_control = VCD_RATE_CONTROL_CBR_VFR;
-		break;
-	default:
-		WFD_MSG_ERR("unknown bitrate mode %d", mode);
-		rc = -EINVAL;
-		goto err;
-	}
-
-	rc = vcd_set_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &rate_control);
-err:
-	return rc;
-}
-
-static long venc_get_bitrate_mode(struct video_client_ctx *client_ctx,
-			__s32 *mode)
-{
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_rate_control rate_control;
-	int rc = 0;
-
-	if (!client_ctx)
-		return -EINVAL;
-
-	vcd_property_hdr.prop_id = VCD_I_RATE_CONTROL;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_rate_control);
-	rc = vcd_get_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &rate_control);
-
-	switch (rate_control.rate_control) {
-	case VCD_RATE_CONTROL_CBR_VFR:
-	case VCD_RATE_CONTROL_CBR_CFR:
-		*mode = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
-		break;
-	case VCD_RATE_CONTROL_VBR_VFR:
-	case VCD_RATE_CONTROL_VBR_CFR:
-		*mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR;
-		break;
-	default:
-		WFD_MSG_ERR("unknown bitrate mode %d",
-				rate_control.rate_control);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static long venc_set_frame_size(struct video_client_ctx *client_ctx,
-				u32 height, u32 width)
-{
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_frame_size frame_size;
-	vcd_property_hdr.prop_id = VCD_I_FRAME_SIZE;
-	vcd_property_hdr.sz =
-		sizeof(struct vcd_property_frame_size);
-	frame_size.height = height;
-	frame_size.width = width;
-	return vcd_set_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &frame_size);
-}
-
-static long venc_set_format(struct v4l2_subdev *sd, void *arg)
-{
-	struct venc_inst *inst;
-	struct video_client_ctx *client_ctx;
-	struct v4l2_format *fmt = arg;
-	struct vcd_buffer_requirement buf_req;
-	int rc = 0;
-
-	inst = sd->dev_priv;
-	client_ctx = &inst->venc_client;
-	if (!inst || !client_ctx || !fmt) {
-		WFD_MSG_ERR("Invalid parameters\n");
-		return -EINVAL;
-	}
-	rc = venc_set_codec(client_ctx, fmt->fmt.pix.pixelformat);
-	if (rc) {
-		WFD_MSG_ERR("Failed to set codec, rc = %d\n", rc);
-		goto err;
-	}
-
-	rc = venc_set_frame_size(client_ctx, fmt->fmt.pix.height,
-				fmt->fmt.pix.width);
-	if (rc) {
-		WFD_MSG_ERR("Failed to set frame size, rc = %d\n", rc);
-		goto err;
-	}
-	rc = vcd_get_buffer_requirements(client_ctx->vcd_handle,
-			VCD_BUFFER_OUTPUT, &buf_req);
-	if (rc) {
-		WFD_MSG_ERR("Failed to get buf requrements, rc = %d\n", rc);
-		goto err;
-	}
-	fmt->fmt.pix.sizeimage = buf_req.sz;
-err:
-	return rc;
-}
-
-static long venc_set_framerate(struct v4l2_subdev *sd,
-				void *arg)
-{
-	struct venc_inst *inst = sd->dev_priv;
-	struct video_client_ctx *client_ctx = &inst->venc_client;
-	struct v4l2_fract *frate = arg;
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_frame_rate vcd_frame_rate;
-	struct vcd_property_vop_timing_constant_delta vcd_delta;
-	int rc;
-	vcd_property_hdr.prop_id = VCD_I_FRAME_RATE;
-	vcd_property_hdr.sz =
-				sizeof(struct vcd_property_frame_rate);
-	/* v4l2 passes in "fps" as "spf", so take reciprocal*/
-	vcd_frame_rate.fps_denominator = frate->numerator;
-	vcd_frame_rate.fps_numerator = frate->denominator;
-	rc = vcd_set_property(client_ctx->vcd_handle,
-					&vcd_property_hdr, &vcd_frame_rate);
-	if (rc) {
-		WFD_MSG_ERR("Failed to set frame rate, rc = %d\n", rc);
-		goto set_framerate_fail;
-	}
-
-	vcd_property_hdr.prop_id = VCD_I_VOP_TIMING_CONSTANT_DELTA;
-	vcd_property_hdr.sz = sizeof(vcd_delta);
-
-	vcd_delta.constant_delta = (frate->numerator * USEC_PER_SEC) /
-					frate->denominator;
-	rc = vcd_set_property(client_ctx->vcd_handle,
-					&vcd_property_hdr, &vcd_delta);
-
-	if (rc) {
-		WFD_MSG_ERR("Failed to set frame delta, rc = %d", rc);
-		goto set_framerate_fail;
-	}
-
-set_framerate_fail:
-	return rc;
-}
-
-static long venc_set_framerate_mode(struct v4l2_subdev *sd,
-				void *arg)
-{
-	struct venc_inst *inst = sd->dev_priv;
-	inst->framerate_mode = *(enum venc_framerate_modes *)arg;
-	return 0;
-}
-
-static long venc_set_qp_value(struct video_client_ctx *client_ctx,
-		__s32 frametype, __s32 qp)
-{
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_session_qp vcd_property_session_qp;
-	int rc = 0;
-
-	if (!client_ctx) {
-		WFD_MSG_ERR("Invalid parameters\n");
-		return -EINVAL;
-	}
-
-	vcd_property_hdr.prop_id = VCD_I_SESSION_QP;
-	vcd_property_hdr.sz = sizeof(vcd_property_session_qp);
-
-	rc = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
-			&vcd_property_session_qp);
-
-	if (rc) {
-		WFD_MSG_ERR("Failed to get session qp\n");
-		goto err;
-	}
-
-	switch (frametype) {
-	case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
-		vcd_property_session_qp.i_frame_qp = qp;
-		break;
-	case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
-		vcd_property_session_qp.p_frame_qp = qp;
-		break;
-	case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
-		vcd_property_session_qp.b_frame_qp = qp;
-		break;
-	case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP:
-	case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP:
-	case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP:
-	case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP:
-	case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP:
-	case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP:
-		rc = -ENOTSUPP;
-		goto err;
-	default:
-		rc = -EINVAL;
-		goto err;
-	}
-
-
-	rc = vcd_set_property(client_ctx->vcd_handle, &vcd_property_hdr,
-			&vcd_property_session_qp);
-
-	if (rc) {
-		WFD_MSG_ERR("Failed to set session qp\n");
-		goto err;
-	}
-err:
-	return rc;
-}
-
-static long venc_get_qp_value(struct video_client_ctx *client_ctx,
-		__s32 frametype, __s32 *qp)
-{
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_session_qp vcd_property_session_qp;
-	int rc = 0;
-
-	if (!client_ctx) {
-		WFD_MSG_ERR("Invalid parameters\n");
-		return -EINVAL;
-	}
-
-	vcd_property_hdr.prop_id = VCD_I_SESSION_QP;
-	vcd_property_hdr.sz = sizeof(vcd_property_session_qp);
-
-	rc = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
-			&vcd_property_session_qp);
-
-	if (rc) {
-		WFD_MSG_ERR("Failed to get session qp\n");
-		goto err;
-	}
-
-	switch (frametype) {
-	case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP:
-	case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP:
-	case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
-		*qp = vcd_property_session_qp.i_frame_qp;
-		break;
-	case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP:
-	case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP:
-	case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
-		*qp = vcd_property_session_qp.p_frame_qp;
-		break;
-	case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP:
-	case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP:
-	case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
-		*qp = vcd_property_session_qp.b_frame_qp;
-		break;
-	default:
-		rc = -EINVAL;
-		goto err;
-	}
-
-err:
-	return rc;
-}
-
-static long venc_set_qp_range(struct video_client_ctx *client_ctx,
-		__s32 type, __s32 qp)
-{
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_qp_range vcd_property_qp_range;
-	int rc = 0;
-
-	if (!client_ctx) {
-		WFD_MSG_ERR("Invalid parameters\n");
-		return -EINVAL;
-	}
-
-	vcd_property_hdr.prop_id = VCD_I_QP_RANGE;
-	vcd_property_hdr.sz = sizeof(vcd_property_qp_range);
-
-	rc = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
-			&vcd_property_qp_range);
-
-	if (rc) {
-		WFD_MSG_ERR("Failed to get qp range\n");
-		goto err;
-	}
-
-	switch (type) {
-	case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP:
-	case V4L2_CID_MPEG_VIDEO_H263_MIN_QP:
-	case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
-		vcd_property_qp_range.min_qp = qp;
-		break;
-	case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP:
-	case V4L2_CID_MPEG_VIDEO_H263_MAX_QP:
-	case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
-		vcd_property_qp_range.max_qp = qp;
-		break;
-	default:
-		rc = -EINVAL;
-		goto err;
-	}
-
-	rc = vcd_set_property(client_ctx->vcd_handle, &vcd_property_hdr,
-			&vcd_property_qp_range);
-
-	if (rc) {
-		WFD_MSG_ERR("Failed to set qp range\n");
-		goto err;
-	}
-err:
-	return rc;
-}
-
-static long venc_get_qp_range(struct video_client_ctx *client_ctx,
-		__s32 type, __s32 *qp)
-{
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_qp_range vcd_property_qp_range;
-	int rc = 0;
-
-	if (!client_ctx) {
-		WFD_MSG_ERR("Invalid parameters\n");
-		return -EINVAL;
-	}
-
-	vcd_property_hdr.prop_id = VCD_I_QP_RANGE;
-	vcd_property_hdr.sz = sizeof(vcd_property_qp_range);
-
-	rc = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
-			&vcd_property_qp_range);
-
-	if (rc) {
-		WFD_MSG_ERR("Failed to get qp range\n");
-		goto err;
-	}
-
-	switch (type) {
-	case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP:
-	case V4L2_CID_MPEG_VIDEO_H263_MIN_QP:
-	case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
-		*qp = vcd_property_qp_range.min_qp;
-		break;
-	case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP:
-	case V4L2_CID_MPEG_VIDEO_H263_MAX_QP:
-	case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
-		*qp = vcd_property_qp_range.max_qp;
-		break;
-	default:
-		rc = -EINVAL;
-		goto err;
-	}
-
-	rc = vcd_set_property(client_ctx->vcd_handle, &vcd_property_hdr,
-			&vcd_property_qp_range);
-
-	if (rc) {
-		WFD_MSG_ERR("Failed to set qp range\n");
-		goto err;
-	}
-err:
-	return rc;
-}
-static long venc_set_max_perf_level(struct video_client_ctx *client_ctx,
-		__s32 value)
-{
-	int rc = 0;
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_perf_level perf;
-	int level = 0;
-
-	switch (value) {
-	case V4L2_CID_MPEG_VIDC_PERF_LEVEL_PERFORMANCE:
-		level = VCD_PERF_LEVEL2;
-		break;
-	case V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO:
-		level = VCD_PERF_LEVEL_TURBO;
-		break;
-	default:
-		WFD_MSG_ERR("Unknown performance level: %d\n", value);
-		rc = -ENOTSUPP;
-		goto err_set_perf_level;
-	}
-
-	vcd_property_hdr.prop_id = VCD_REQ_PERF_LEVEL;
-	vcd_property_hdr.sz =
-		sizeof(struct vcd_property_perf_level);
-	perf.level = level;
-	rc = vcd_set_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &perf);
-err_set_perf_level:
-	return rc;
-}
-
-static long venc_set_avc_delimiter(struct video_client_ctx *client_ctx,
-			__s32 flag)
-{
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_avc_delimiter_enable delimiter_flag;
-	if (!client_ctx)
-		return -EINVAL;
-
-	vcd_property_hdr.prop_id = VCD_I_ENABLE_DELIMITER_FLAG;
-	vcd_property_hdr.sz =
-			sizeof(struct vcd_property_avc_delimiter_enable);
-	delimiter_flag.avc_delimiter_enable_flag = flag;
-	return vcd_set_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &delimiter_flag);
-}
-
-static long venc_get_avc_delimiter(struct video_client_ctx *client_ctx,
-			__s32 *flag)
-{
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_avc_delimiter_enable delimiter_flag;
-	int rc = 0;
-
-	if (!client_ctx || !flag)
-		return -EINVAL;
-
-	vcd_property_hdr.prop_id = VCD_I_ENABLE_DELIMITER_FLAG;
-	vcd_property_hdr.sz =
-			sizeof(struct vcd_property_avc_delimiter_enable);
-	rc = vcd_get_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &delimiter_flag);
-
-	if (rc < 0) {
-		WFD_MSG_ERR("Failed getting property for delimiter");
-		return rc;
-	}
-
-	*flag = delimiter_flag.avc_delimiter_enable_flag;
-	return rc;
-}
-
-static long venc_set_vui_timing_info(struct video_client_ctx *client_ctx,
-			struct venc_inst *inst, __s32 flag)
-{
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_vui_timing_info_enable vui_timing_info_enable;
-
-	if (!client_ctx)
-		return -EINVAL;
-	if (inst->framerate_mode == VENC_MODE_VFR) {
-		WFD_MSG_ERR("VUI timing info not suported in VFR mode ");
-		return -EINVAL;
-	}
-	vcd_property_hdr.prop_id = VCD_I_ENABLE_VUI_TIMING_INFO;
-	vcd_property_hdr.sz =
-			sizeof(struct vcd_property_vui_timing_info_enable);
-	vui_timing_info_enable.vui_timing_info = flag;
-	return vcd_set_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &vui_timing_info_enable);
-}
-
-static long venc_get_vui_timing_info(struct video_client_ctx *client_ctx,
-			__s32 *flag)
-{
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_vui_timing_info_enable vui_timing_info_enable;
-	int rc = 0;
-
-	if (!client_ctx || !flag)
-		return -EINVAL;
-
-	vcd_property_hdr.prop_id = VCD_I_ENABLE_VUI_TIMING_INFO;
-	vcd_property_hdr.sz =
-			sizeof(struct vcd_property_vui_timing_info_enable);
-	rc = vcd_get_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &vui_timing_info_enable);
-
-	if (rc < 0) {
-		WFD_MSG_ERR("Failed getting property for VUI timing info");
-		return rc;
-	}
-
-	*flag = vui_timing_info_enable.vui_timing_info;
-	return rc;
-}
-
-static long venc_set_header_mode(struct video_client_ctx *client_ctx,
-		__s32 mode)
-{
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_sps_pps_for_idr_enable sps_pps_for_idr_enable;
-	int rc = 0;
-
-	if (!client_ctx) {
-		WFD_MSG_ERR("Invalid parameters\n");
-		rc = -EINVAL;
-		goto err;
-	}
-
-	vcd_property_hdr.prop_id = VCD_I_ENABLE_SPS_PPS_FOR_IDR;
-	vcd_property_hdr.sz = sizeof(sps_pps_for_idr_enable);
-	switch (mode) {
-	case V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE:
-		sps_pps_for_idr_enable.sps_pps_for_idr_enable_flag = 0;
-		break;
-	case V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME:
-		sps_pps_for_idr_enable.sps_pps_for_idr_enable_flag = 1;
-		break;
-	case V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME:
-	default:
-		WFD_MSG_ERR("Video header mode %d not supported\n",
-				mode);
-		rc = -ENOTSUPP;
-		goto err;
-	}
-
-	rc =  vcd_set_property(client_ctx->vcd_handle, &vcd_property_hdr,
-			&sps_pps_for_idr_enable);
-	if (rc) {
-		WFD_MSG_ERR("Failed to set enable_sps_pps_for_idr\n");
-		goto err;
-	}
-err:
-	return rc;
-}
-
-static long venc_get_header_mode(struct video_client_ctx *client_ctx,
-		__s32 *mode)
-{
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_sps_pps_for_idr_enable sps_pps_for_idr_enable;
-	int rc = 0;
-
-	if (!client_ctx) {
-		WFD_MSG_ERR("Invalid parameters\n");
-		rc = -EINVAL;
-		goto err;
-	}
-
-	vcd_property_hdr.prop_id = VCD_I_ENABLE_SPS_PPS_FOR_IDR;
-	vcd_property_hdr.sz = sizeof(sps_pps_for_idr_enable);
-	rc =  vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
-			&sps_pps_for_idr_enable);
-	if (rc) {
-		WFD_MSG_ERR("Failed to get sps/pps for idr enable\n");
-		goto err;
-	}
-
-	*mode = sps_pps_for_idr_enable.sps_pps_for_idr_enable_flag ?
-		V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME :
-		V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
-err:
-	return rc;
-}
-
-static long venc_set_multislicing_mode(struct video_client_ctx *client_ctx,
-			__u32 control, __s32 value)
-{
-	int rc = 0;
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_frame_size vcd_frame_size;
-	struct vcd_buffer_requirement vcd_buf_req;
-	struct vcd_property_multi_slice vcd_multi_slice;
-
-	if (!client_ctx) {
-		WFD_MSG_ERR("Invalid parameters\n");
-		rc = -EINVAL;
-		goto set_multislicing_mode_fail;
-	}
-
-	vcd_property_hdr.prop_id = VCD_I_FRAME_SIZE;
-	vcd_property_hdr.sz =
-		sizeof(vcd_frame_size);
-	rc = vcd_get_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &vcd_frame_size);
-
-	if (rc) {
-		WFD_MSG_ERR("Failed to get frame size\n");
-		goto set_multislicing_mode_fail;
-	}
-
-	rc = vcd_get_buffer_requirements(client_ctx->vcd_handle,
-			VCD_BUFFER_OUTPUT, &vcd_buf_req);
-
-	if (rc) {
-		WFD_MSG_ERR("Failed to get buf reqs\n");
-		goto set_multislicing_mode_fail;
-	}
-
-	vcd_property_hdr.prop_id = VCD_I_MULTI_SLICE;
-	vcd_property_hdr.sz = sizeof(vcd_multi_slice);
-	rc = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
-			&vcd_multi_slice);
-	if (rc) {
-		WFD_MSG_ERR("Failed to get multi slice\n");
-		goto set_multislicing_mode_fail;
-	}
-
-	switch (control) {
-	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
-		if (vcd_multi_slice.m_slice_sel !=
-				VCD_MSLICE_BY_BYTE_COUNT) {
-			WFD_MSG_ERR("Not in proper mode\n");
-			goto set_multislicing_mode_fail;
-		}
-		vcd_multi_slice.m_slice_size = value;
-		break;
-
-	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
-		if (vcd_multi_slice.m_slice_sel !=
-				VCD_MSLICE_BY_MB_COUNT) {
-			WFD_MSG_ERR("Not in proper mode\n");
-			goto set_multislicing_mode_fail;
-		}
-		vcd_multi_slice.m_slice_size = value;
-		break;
-
-	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
-		switch (value) {
-		case V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE:
-			vcd_multi_slice.m_slice_sel = VCD_MSLICE_OFF;
-			break;
-		case V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB:
-			vcd_multi_slice.m_slice_sel = VCD_MSLICE_BY_MB_COUNT;
-			/* Just a temporary size until client calls
-			 * V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB */
-			vcd_multi_slice.m_slice_size =
-				(vcd_frame_size.stride / 16) *
-				(vcd_frame_size.scan_lines / 16);
-			break;
-		case V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES:
-			vcd_multi_slice.m_slice_sel = VCD_MSLICE_BY_BYTE_COUNT;
-			/* Just a temporary size until client calls
-			 * V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES */
-			vcd_multi_slice.m_slice_size = vcd_buf_req.sz;
-			break;
-		default:
-			WFD_MSG_ERR("Unrecognized mode %d\n", value);
-			rc = -ENOTSUPP;
-			goto set_multislicing_mode_fail;
-		}
-
-		break;
-	default:
-		rc = -EINVAL;
-		goto set_multislicing_mode_fail;
-	}
-
-	rc = vcd_set_property(client_ctx->vcd_handle, &vcd_property_hdr,
-			&vcd_multi_slice);
-	if (rc) {
-		WFD_MSG_ERR("Failed to set multi slice\n");
-		goto set_multislicing_mode_fail;
-	}
-
-set_multislicing_mode_fail:
-	return rc;
-}
-
-static long venc_get_multislicing_mode(struct video_client_ctx *client_ctx,
-			__u32 control, __s32 *value)
-{
-	int rc = 0;
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_frame_size vcd_frame_size;
-	struct vcd_buffer_requirement vcd_buf_req;
-	struct vcd_property_multi_slice vcd_multi_slice;
-
-	if (!client_ctx) {
-		WFD_MSG_ERR("Invalid parameters\n");
-		rc = -EINVAL;
-		goto get_multislicing_mode_fail;
-	}
-
-	vcd_property_hdr.prop_id = VCD_I_FRAME_SIZE;
-	vcd_property_hdr.sz =
-		sizeof(vcd_frame_size);
-	rc = vcd_get_property(client_ctx->vcd_handle,
-				&vcd_property_hdr, &vcd_frame_size);
-
-	if (rc) {
-		WFD_MSG_ERR("Failed to get frame size\n");
-		goto get_multislicing_mode_fail;
-	}
-
-	vcd_property_hdr.prop_id = VCD_I_MULTI_SLICE;
-	vcd_property_hdr.sz = sizeof(vcd_multi_slice);
-	rc = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
-			&vcd_multi_slice);
-	if (rc) {
-		WFD_MSG_ERR("Failed to get multi slice\n");
-		goto get_multislicing_mode_fail;
-	}
-
-	rc = vcd_get_buffer_requirements(client_ctx->vcd_handle,
-			VCD_BUFFER_OUTPUT, &vcd_buf_req);
-
-	if (rc) {
-		WFD_MSG_ERR("Failed to get buf reqs\n");
-		goto get_multislicing_mode_fail;
-	}
-
-	switch (control) {
-	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
-		if (vcd_multi_slice.m_slice_sel == VCD_MSLICE_BY_BYTE_COUNT)
-			*value = vcd_multi_slice.m_slice_size;
-		else {
-			WFD_MSG_ERR("Invalid query when in slice mode %d\n",
-					vcd_multi_slice.m_slice_sel);
-			rc = -EINVAL;
-			goto get_multislicing_mode_fail;
-		}
-		break;
-
-	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
-		if (vcd_multi_slice.m_slice_sel == VCD_MSLICE_BY_MB_COUNT)
-			*value = vcd_multi_slice.m_slice_size;
-		else {
-			WFD_MSG_ERR("Invalid query when in slice mode %d\n",
-					vcd_multi_slice.m_slice_sel);
-			rc = -EINVAL;
-			goto get_multislicing_mode_fail;
-		}
-		break;
-
-	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
-		switch (vcd_multi_slice.m_slice_sel) {
-		case VCD_MSLICE_OFF:
-			*value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
-			break;
-		case VCD_MSLICE_BY_MB_COUNT:
-			*value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB;
-			break;
-		case VCD_MSLICE_BY_BYTE_COUNT:
-			*value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES;
-			break;
-		default:
-			WFD_MSG_ERR("Encoder in an unknown mode %d\n",
-					vcd_multi_slice.m_slice_sel);
-			rc = -ENOENT;
-			goto get_multislicing_mode_fail;
-
-		}
-		break;
-	default:
-		rc = -EINVAL;
-		goto get_multislicing_mode_fail;
-	}
-
-get_multislicing_mode_fail:
-	return rc;
-}
-
-static long venc_set_entropy_mode(struct video_client_ctx *client_ctx,
-		__s32 value)
-{
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_entropy_control entropy_control;
-	int rc = 0;
-
-	if (!client_ctx) {
-		WFD_MSG_ERR("Invalid parameters\n");
-		rc = -EINVAL;
-		goto set_entropy_mode_fail;
-	}
-
-	vcd_property_hdr.prop_id = VCD_I_ENTROPY_CTRL;
-	vcd_property_hdr.sz = sizeof(entropy_control);
-
-	switch (value) {
-	case V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC:
-		entropy_control.entropy_sel = VCD_ENTROPY_SEL_CAVLC;
-		break;
-	case V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC:
-		entropy_control.entropy_sel = VCD_ENTROPY_SEL_CABAC;
-		entropy_control.cabac_model = VCD_CABAC_MODEL_NUMBER_0;
-		break;
-	default:
-		WFD_MSG_ERR("Entropy type %d not supported\n", value);
-		rc = -ENOTSUPP;
-		goto set_entropy_mode_fail;
-	}
-	rc = vcd_set_property(client_ctx->vcd_handle, &vcd_property_hdr,
-			&entropy_control);
-	if (rc) {
-		WFD_MSG_ERR("Failed to set entropy mode\n");
-		goto set_entropy_mode_fail;
-	}
-
-set_entropy_mode_fail:
-	return rc;
-}
-
-static long venc_get_entropy_mode(struct video_client_ctx *client_ctx,
-		__s32 *value)
-{
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_entropy_control entropy_control;
-	int rc = 0;
-
-	if (!client_ctx || !value) {
-		WFD_MSG_ERR("Invalid parameters\n");
-		rc = -EINVAL;
-		goto get_entropy_mode_fail;
-	}
-
-	vcd_property_hdr.prop_id = VCD_I_ENTROPY_CTRL;
-	vcd_property_hdr.sz = sizeof(entropy_control);
-
-	rc = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
-			&entropy_control);
-
-	if (rc) {
-		WFD_MSG_ERR("Failed to get entropy mode\n");
-		goto get_entropy_mode_fail;
-	}
-
-	switch (entropy_control.entropy_sel) {
-	case VCD_ENTROPY_SEL_CAVLC:
-		*value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
-		break;
-	case VCD_ENTROPY_SEL_CABAC:
-		*value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC;
-		break;
-	default:
-		WFD_MSG_ERR("Entropy type %d not known\n",
-				entropy_control.entropy_sel);
-		rc = -EINVAL;
-		goto get_entropy_mode_fail;
-	}
-get_entropy_mode_fail:
-	return rc;
-}
-
-static long venc_set_cyclic_intra_refresh_mb(
-		struct video_client_ctx *client_ctx,
-		__s32 value)
-{
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_intra_refresh_mb_number cir_mb_num;
-	int rc = 0;
-
-	if (!client_ctx) {
-		WFD_MSG_ERR("Invalid parameters\n");
-		rc = -EINVAL;
-		goto set_cir_mbs_fail;
-	}
-
-	vcd_property_hdr.prop_id = VCD_I_INTRA_REFRESH;
-	vcd_property_hdr.sz = sizeof(cir_mb_num);
-
-	cir_mb_num.cir_mb_number = value;
-
-	rc = vcd_set_property(client_ctx->vcd_handle, &vcd_property_hdr,
-			&cir_mb_num);
-	if (rc) {
-		WFD_MSG_ERR("Failed to set CIR MBs\n");
-		goto set_cir_mbs_fail;
-	}
-
-set_cir_mbs_fail:
-	return rc;
-}
-
-static long venc_get_cyclic_intra_refresh_mb(
-		struct video_client_ctx *client_ctx,
-		__s32 *value)
-{
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_intra_refresh_mb_number cir_mb_num;
-	int rc = 0;
-
-	if (!client_ctx || !value) {
-		WFD_MSG_ERR("Invalid parameters\n");
-		rc = -EINVAL;
-		goto get_cir_mbs_fail;
-	}
-
-	vcd_property_hdr.prop_id = VCD_I_INTRA_REFRESH;
-	vcd_property_hdr.sz = sizeof(cir_mb_num);
-
-	rc = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
-			&cir_mb_num);
-	if (rc) {
-		WFD_MSG_ERR("Failed to set CIR MBs\n");
-		goto get_cir_mbs_fail;
-	}
-
-	*value = cir_mb_num.cir_mb_number;
-
-get_cir_mbs_fail:
-	return rc;
-}
-static long venc_set_input_buffer(struct v4l2_subdev *sd, void *arg)
-{
-	struct mem_region *mregion = arg;
-	struct venc_inst *inst = sd->dev_priv;
-	unsigned long paddr, kvaddr, temp;
-	struct video_client_ctx *client_ctx = &inst->venc_client;
-	int rc = 0;
-
-	if (!client_ctx || !mregion) {
-		WFD_MSG_ERR("Invalid input\n");
-		rc = -EINVAL;
-		goto ins_table_fail;
-	}
-
-	kvaddr = (unsigned long)mregion->kvaddr;
-	paddr = (unsigned long)mregion->paddr;
-
-	if (!kvaddr || !paddr) {
-		WFD_MSG_ERR("Invalid addresses\n");
-		rc = -EINVAL;
-		goto ins_table_fail;
-	}
-
-	/*
-	 * Just a note: the third arg of vidc_insert_\
-	 * addr_table_kernel is supposed to be a userspace
-	 * address that is used as a key in the table. As
-	 * these bufs never leave the kernel, we need to have
-	 * an unique value to use as a key.  So re-using kernel
-	 * virtual addr for this purpose
-	 */
-	rc = vidc_insert_addr_table_kernel(client_ctx,
-		BUFFER_TYPE_INPUT, kvaddr, kvaddr,
-		paddr, 32, mregion->size);
-
-	if (rc == (u32)false) {
-		WFD_MSG_ERR("Failed to insert input buffer into table\n");
-		rc = -EFAULT;
-		goto ins_table_fail;
-	}
-
-	rc = vcd_set_buffer(client_ctx->vcd_handle,
-			VCD_BUFFER_INPUT, (u8 *)kvaddr,
-			mregion->size);
-
-	if (rc) {
-		WFD_MSG_ERR("Failed to set input buffer\n");
-		rc = -EFAULT;
-		goto set_input_buf_fail;
-	}
-
-
-	return rc;
-
-set_input_buf_fail:
-	vidc_delete_addr_table(client_ctx, BUFFER_TYPE_INPUT,
-			kvaddr, &temp);
-ins_table_fail:
-	return rc;
-}
-
-static long venc_set_output_buffer(struct v4l2_subdev *sd, void *arg)
-{
-	int rc = 0;
-	struct venc_inst *inst = sd->dev_priv;
-	struct video_client_ctx *client_ctx = &inst->venc_client;
-	struct mem_region *mregion = arg;
-	if (!client_ctx || !mregion) {
-		WFD_MSG_ERR("Invalid input\n");
-		return -EINVAL;
-	}
-	WFD_MSG_DBG("size = %u, offset = %u fd = %d\n", mregion->size,
-				mregion->offset, mregion->fd);
-	rc = vidc_insert_addr_table(client_ctx, BUFFER_TYPE_OUTPUT,
-					mregion->cookie,
-					(unsigned long *)&mregion->kvaddr,
-					mregion->fd,
-					mregion->offset,
-					32,
-					mregion->size);
-	if (rc == (u32)false) {
-		WFD_MSG_ERR("Failed to insert outbuf in table\n");
-		rc = -EINVAL;
-		goto err;
-	}
-	WFD_MSG_DBG("size = %u, %p\n", mregion->size, mregion->kvaddr);
-
-	rc = vcd_set_buffer(client_ctx->vcd_handle,
-				    VCD_BUFFER_OUTPUT, (u8 *) mregion->kvaddr,
-				    mregion->size);
-	if (rc)
-		WFD_MSG_ERR("Failed to set outbuf on encoder\n");
-err:
-	return rc;
-}
-
-static long venc_fill_outbuf(struct v4l2_subdev *sd, void *arg)
-{
-	int rc = 0;
-	struct venc_inst *inst = sd->dev_priv;
-	struct video_client_ctx *client_ctx = &inst->venc_client;
-	struct mem_region *mregion = arg;
-	struct vcd_frame_data vcd_frame = {0};
-	unsigned long kernel_vaddr, phy_addr, user_vaddr;
-	int pmem_fd;
-	struct file *file;
-	s32 buffer_index = -1;
-
-	if (inst->streaming) {
-		user_vaddr = mregion->cookie;
-		rc = vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT,
-				true, &user_vaddr,
-				&kernel_vaddr, &phy_addr, &pmem_fd, &file,
-				&buffer_index);
-		if (!rc) {
-			WFD_MSG_ERR("Address lookup failed\n");
-			goto err;
-		}
-		vcd_frame.virtual = (u8 *) kernel_vaddr;
-		vcd_frame.frm_clnt_data = mregion->cookie;
-		vcd_frame.alloc_len = mregion->size;
-
-		rc = vcd_fill_output_buffer(client_ctx->vcd_handle, &vcd_frame);
-		if (rc)
-			WFD_MSG_ERR("Failed to fill output buffer on encoder");
-	} else {
-		struct mem_region *temp = kzalloc(sizeof(*temp), GFP_KERNEL);
-		*temp = *mregion;
-		INIT_LIST_HEAD(&temp->list);
-		list_add_tail(&temp->list, &inst->unqueued_op_bufs.list);
-	}
-err:
-	return rc;
-}
-
-static long venc_encode_frame(struct v4l2_subdev *sd, void *arg)
-{
-	int rc = 0;
-	struct venc_inst *inst = sd->dev_priv;
-	struct video_client_ctx *client_ctx = &inst->venc_client;
-	struct venc_buf_info *venc_buf = arg;
-	struct mem_region *mregion = venc_buf->mregion;
-	struct vcd_frame_data vcd_input_buffer = {0};
-	int64_t ts = 0;
-
-	ts = venc_buf->timestamp;
-	do_div(ts, NSEC_PER_USEC);
-
-	vcd_input_buffer.virtual = mregion->kvaddr;
-	vcd_input_buffer.frm_clnt_data = (u32)mregion;
-	vcd_input_buffer.ip_frm_tag = (u32)mregion;
-	vcd_input_buffer.data_len = mregion->size;
-	vcd_input_buffer.time_stamp = ts;
-	vcd_input_buffer.offset = 0;
-
-	rc = vcd_encode_frame(client_ctx->vcd_handle,
-			&vcd_input_buffer);
-
-	if (rc)
-		WFD_MSG_ERR("encode frame failed\n");
-	return rc;
-}
-
-static long venc_alloc_recon_buffers(struct v4l2_subdev *sd, void *arg)
-{
-	int rc = 0;
-	struct venc_inst *inst = sd->dev_priv;
-	struct video_client_ctx *client_ctx = &inst->venc_client;
-	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_buffer_size control;
-	struct vcd_property_enc_recon_buffer *ctrl = NULL;
-	unsigned long phy_addr;
-	int i = 0;
-	int heap_mask = 0;
-	u32 ion_flags = 0;
-	u32 len;
-	control.width = inst->width;
-	control.height = inst->height;
-	vcd_property_hdr.prop_id = VCD_I_GET_RECON_BUFFER_SIZE;
-	vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size);
-
-	rc = vcd_get_property(client_ctx->vcd_handle,
-					&vcd_property_hdr, &control);
-	if (rc) {
-		WFD_MSG_ERR("Failed to get recon buf size\n");
-		goto err;
-	}
-	heap_mask = ION_HEAP(ION_CP_MM_HEAP_ID);
-	heap_mask |= inst->secure ? 0 : ION_HEAP(ION_IOMMU_HEAP_ID);
-	ion_flags |= inst->secure ? ION_SECURE : 0;
-
-	if (vcd_get_ion_status()) {
-		for (i = 0; i < 4; ++i) {
-			ctrl = &client_ctx->recon_buffer[i];
-			ctrl->buffer_size = control.size;
-			ctrl->pmem_fd = 0;
-			ctrl->offset = 0;
-			ctrl->user_virtual_addr = (void *)i;
-			client_ctx->recon_buffer_ion_handle[i]
-				= ion_alloc(client_ctx->user_ion_client,
-			control.size, SZ_8K, heap_mask, ion_flags);
-
-			ctrl->kernel_virtual_addr = ion_map_kernel(
-				client_ctx->user_ion_client,
-				client_ctx->recon_buffer_ion_handle[i]);
-
-			if (IS_ERR_OR_NULL(ctrl->kernel_virtual_addr)) {
-				WFD_MSG_ERR("ion map kernel failed\n");
-				rc = -EINVAL;
-				goto free_ion_alloc;
-			}
-
-			if (inst->secure) {
-				rc = ion_phys(client_ctx->user_ion_client,
-					client_ctx->recon_buffer_ion_handle[i],
-					&phy_addr, (size_t *)&len);
-				if (rc || !phy_addr) {
-					WFD_MSG_ERR("ion physical failed\n");
-					goto unmap_ion_alloc;
-				}
-			} else {
-				rc = ion_map_iommu(client_ctx->user_ion_client,
-					client_ctx->recon_buffer_ion_handle[i],
-					VIDEO_DOMAIN, VIDEO_MAIN_POOL, SZ_4K,
-					0, &phy_addr, (unsigned long *)&len,
-					0, 0);
-				 if (rc || !phy_addr) {
-					WFD_MSG_ERR(
-						"ion map iommu failed, rc = %d, phy_addr = 0x%lx\n",
-						rc, phy_addr);
-					goto unmap_ion_alloc;
-				}
-
-			}
-			ctrl->physical_addr =  (u8 *) phy_addr;
-			ctrl->dev_addr = ctrl->physical_addr;
-			vcd_property_hdr.prop_id = VCD_I_RECON_BUFFERS;
-			vcd_property_hdr.sz =
-				sizeof(struct vcd_property_enc_recon_buffer);
-			rc = vcd_set_property(client_ctx->vcd_handle,
-					&vcd_property_hdr, ctrl);
-			if (rc) {
-				WFD_MSG_ERR("Failed to set recon buffers\n");
-				goto unmap_ion_iommu;
-			}
-		}
-	} else {
-		WFD_MSG_ERR("PMEM not suported\n");
-		return -ENOMEM;
-	}
-	return rc;
-unmap_ion_iommu:
-	if (!inst->secure) {
-		if (client_ctx->recon_buffer_ion_handle[i]) {
-			ion_unmap_iommu(client_ctx->user_ion_client,
-				client_ctx->recon_buffer_ion_handle[i],
-				VIDEO_DOMAIN, VIDEO_MAIN_POOL);
-		}
-	}
-unmap_ion_alloc:
-	if (client_ctx->recon_buffer_ion_handle[i]) {
-		ion_unmap_kernel(client_ctx->user_ion_client,
-			client_ctx->recon_buffer_ion_handle[i]);
-		ctrl->kernel_virtual_addr = NULL;
-		ctrl->physical_addr = NULL;
-	}
-free_ion_alloc:
-	if (client_ctx->recon_buffer_ion_handle[i]) {
-		ion_free(client_ctx->user_ion_client,
-			client_ctx->recon_buffer_ion_handle[i]);
-		client_ctx->recon_buffer_ion_handle[i] = NULL;
-	}
-	WFD_MSG_ERR("Failed to allo recon buffers\n");
-err:
-	return rc;
-}
-
-static long venc_free_output_buffer(struct v4l2_subdev *sd, void *arg)
-{
-	int rc = 0;
-	struct venc_inst *inst = sd->dev_priv;
-	struct video_client_ctx *client_ctx = &inst->venc_client;
-	struct mem_region *mregion = arg;
-	unsigned long kernel_vaddr, user_vaddr;
-
-	if (!client_ctx || !mregion) {
-		WFD_MSG_ERR("Invalid input\n");
-		return -EINVAL;
-	}
-
-	user_vaddr = mregion->cookie;
-	rc = vidc_delete_addr_table(client_ctx, BUFFER_TYPE_OUTPUT,
-				user_vaddr,
-				&kernel_vaddr);
-	if (!rc) {
-		WFD_MSG_ERR("Failed to delete buf from address table\n");
-		return -EINVAL;
-	}
-	return vcd_free_buffer(client_ctx->vcd_handle, VCD_BUFFER_OUTPUT,
-					 (u8 *)kernel_vaddr);
-}
-
-static long venc_flush_buffers(struct v4l2_subdev *sd, void *arg)
-{
-	int rc = 0;
-	struct venc_inst *inst = sd->dev_priv;
-	struct video_client_ctx *client_ctx = &inst->venc_client;
-	if (!client_ctx) {
-		WFD_MSG_ERR("Invalid input\n");
-		return -EINVAL;
-	}
-	rc = vcd_flush(client_ctx->vcd_handle, VCD_FLUSH_INPUT);
-	if (rc) {
-		WFD_MSG_ERR("Failed to flush input buffers\n");
-		rc = -EIO;
-		goto flush_failed;
-	}
-	wait_for_completion(&client_ctx->event);
-	if (client_ctx->event_status) {
-		WFD_MSG_ERR("callback for vcd_flush input returned error: %u",
-				client_ctx->event_status);
-		rc = -EIO;
-		goto flush_failed;
-	}
-	rc = vcd_flush(client_ctx->vcd_handle, VCD_FLUSH_OUTPUT);
-	if (rc) {
-		WFD_MSG_ERR("Failed to flush output buffers\n");
-		rc = -EIO;
-		goto flush_failed;
-	}
-	wait_for_completion(&client_ctx->event);
-	if (client_ctx->event_status) {
-		WFD_MSG_ERR("callback for vcd_flush output returned error: %u",
-				client_ctx->event_status);
-		rc = -EIO;
-		goto flush_failed;
-	}
-
-flush_failed:
-	return rc;
-}
-
-static long venc_free_input_buffer(struct v4l2_subdev *sd, void *arg)
-{
-	int del_rc = 0, free_rc = 0;
-	struct venc_inst *inst = sd->dev_priv;
-	struct video_client_ctx *client_ctx = &inst->venc_client;
-	struct mem_region *mregion = arg;
-	unsigned long vidc_kvaddr;
-
-	if (!client_ctx || !mregion) {
-		WFD_MSG_ERR("Invalid input\n");
-		return -EINVAL;
-	}
-
-	del_rc = vidc_delete_addr_table(client_ctx, BUFFER_TYPE_INPUT,
-				(unsigned long)mregion->kvaddr,
-				&vidc_kvaddr);
-	/*
-	 * Even if something went wrong in when
-	 * deleting from table, call vcd_free_buf
-	 */
-	if (del_rc == (u32)false) {
-		WFD_MSG_ERR("Failed to delete buf from address table\n");
-		del_rc = -ENOKEY;
-	} else if ((u8 *)vidc_kvaddr != mregion->kvaddr) {
-		WFD_MSG_ERR("Failed to find expected buffer\n");
-		del_rc = -EINVAL;
-	} else
-		del_rc = 0;
-
-	free_rc = vcd_free_buffer(client_ctx->vcd_handle, VCD_BUFFER_INPUT,
-					 (u8 *)vidc_kvaddr);
-
-	if (free_rc) {
-		WFD_MSG_ERR("Failed to free buffer from encoder\n");
-		free_rc = -EINVAL;
-	}
-
-	return del_rc ? del_rc : free_rc;
-}
-
-static long venc_free_recon_buffers(struct v4l2_subdev *sd, void *arg)
-{
-	int rc = 0;
-	struct venc_inst *inst = sd->dev_priv;
-	struct video_client_ctx *client_ctx = &inst->venc_client;
-	struct vcd_property_hdr vcd_property_hdr;
-	int i;
-
-	if (vcd_get_ion_status()) {
-		for (i = 0; i < 4; i++) {
-			vcd_property_hdr.prop_id = VCD_I_FREE_RECON_BUFFERS;
-			vcd_property_hdr.sz =
-				sizeof(struct vcd_property_buffer_size);
-			rc = vcd_set_property(client_ctx->vcd_handle,
-			&vcd_property_hdr, &client_ctx->recon_buffer[i]);
-			if (rc)
-				WFD_MSG_ERR("Failed to free recon buffer\n");
-
-			if (!IS_ERR_OR_NULL(
-				client_ctx->recon_buffer_ion_handle[i])) {
-				if (!inst->secure) {
-					ion_unmap_iommu(
-					client_ctx->user_ion_client,
-					client_ctx->recon_buffer_ion_handle[i],
-					VIDEO_DOMAIN, VIDEO_MAIN_POOL);
-				}
-				ion_unmap_kernel(client_ctx->user_ion_client,
-					client_ctx->recon_buffer_ion_handle[i]);
-				ion_free(client_ctx->user_ion_client,
-					client_ctx->recon_buffer_ion_handle[i]);
-				client_ctx->recon_buffer_ion_handle[i] = NULL;
-			}
-		}
-	}
-	return rc;
-}
-
-static long venc_set_property(struct v4l2_subdev *sd, void *arg)
-{
-	int rc = 0;
-	struct venc_inst *inst = sd->dev_priv;
-	struct v4l2_control *ctrl = arg;
-	struct video_client_ctx *client_ctx = &inst->venc_client;
-	switch (ctrl->id) {
-	case V4L2_CID_MPEG_VIDEO_BITRATE:
-		rc = venc_set_bitrate(client_ctx, ctrl->value);
-		break;
-	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
-		rc = venc_set_bitrate_mode(client_ctx, ctrl->value);
-		break;
-	case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:
-		rc = venc_set_h264_intra_period(client_ctx, ctrl->value);
-		break;
-	case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
-		rc = venc_set_codec_level(client_ctx, ctrl->id, ctrl->value);
-		break;
-	case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
-		rc = venc_set_codec_profile(client_ctx, ctrl->id, ctrl->value);
-		break;
-	case V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME:
-		rc = venc_request_frame(client_ctx, ctrl->value);
-		break;
-	case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
-	case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
-	case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
-	case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP:
-	case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP:
-	case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP:
-	case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP:
-	case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP:
-	case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP:
-		rc = venc_set_qp_value(client_ctx, ctrl->id, ctrl->value);
-		break;
-	case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP:
-	case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP:
-	case V4L2_CID_MPEG_VIDEO_H263_MIN_QP:
-	case V4L2_CID_MPEG_VIDEO_H263_MAX_QP:
-	case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
-	case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
-		rc = venc_set_qp_range(client_ctx, ctrl->id, ctrl->value);
-		break;
-	case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
-		rc = venc_set_header_mode(client_ctx, ctrl->value);
-		break;
-	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
-	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
-	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
-		rc = venc_set_multislicing_mode(client_ctx, ctrl->id,
-				ctrl->value);
-		break;
-	case V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL:
-		rc = venc_set_max_perf_level(client_ctx, ctrl->value);
-		break;
-	case V4L2_CID_MPEG_VIDC_VIDEO_H264_AU_DELIMITER:
-		rc = venc_set_avc_delimiter(client_ctx, ctrl->value);
-		break;
-	case V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO:
-		rc = venc_set_vui_timing_info(client_ctx, inst, ctrl->value);
-		break;
-	case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
-		rc = venc_set_entropy_mode(client_ctx, ctrl->value);
-		break;
-	case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
-		rc = venc_set_cyclic_intra_refresh_mb(client_ctx, ctrl->value);
-		break;
-	default:
-		WFD_MSG_ERR("Set property not suported: %d\n", ctrl->id);
-		rc = -ENOTSUPP;
-		break;
-	}
-	return rc;
-}
-
-static long venc_get_property(struct v4l2_subdev *sd, void *arg)
-{
-	int rc = 0;
-	struct venc_inst *inst = sd->dev_priv;
-	struct v4l2_control *ctrl = arg;
-	struct video_client_ctx *client_ctx = &inst->venc_client;
-
-	switch (ctrl->id) {
-	case V4L2_CID_MPEG_VIDEO_BITRATE:
-		rc = venc_get_bitrate(client_ctx, &ctrl->value);
-		break;
-	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
-		rc = venc_get_bitrate_mode(client_ctx, &ctrl->value);
-		break;
-	case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
-		rc = venc_get_codec_level(client_ctx, ctrl->id, &ctrl->value);
-		break;
-	case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
-		rc = venc_get_codec_profile(client_ctx, ctrl->id, &ctrl->value);
-		break;
-	case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:
-		rc = venc_get_h264_intra_period(client_ctx, &ctrl->value);
-		break;
-	case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
-	case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
-	case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
-	case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP:
-	case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP:
-	case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP:
-	case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP:
-	case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP:
-	case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP:
-		rc = venc_get_qp_value(client_ctx, ctrl->id, &ctrl->value);
-		break;
-	case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP:
-	case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP:
-	case V4L2_CID_MPEG_VIDEO_H263_MIN_QP:
-	case V4L2_CID_MPEG_VIDEO_H263_MAX_QP:
-	case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
-	case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
-		rc = venc_get_qp_range(client_ctx, ctrl->id, &ctrl->value);
-		break;
-	case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
-		rc = venc_get_header_mode(client_ctx, &ctrl->value);
-		break;
-	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
-	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
-	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
-		rc = venc_get_multislicing_mode(client_ctx, ctrl->id,
-				&ctrl->value);
-		break;
-	case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
-		rc = venc_get_entropy_mode(client_ctx, &ctrl->value);
-		break;
-	case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
-		rc = venc_get_cyclic_intra_refresh_mb(client_ctx, &ctrl->value);
-		break;
-	case V4L2_CID_MPEG_VIDC_VIDEO_H264_AU_DELIMITER:
-		rc = venc_get_avc_delimiter(client_ctx, &ctrl->value);
-		break;
-	case V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO:
-		rc = venc_get_vui_timing_info(client_ctx, &ctrl->value);
-		break;
-	default:
-		WFD_MSG_ERR("Get property not suported: %d\n", ctrl->id);
-		rc = -ENOTSUPP;
-		break;
-	}
-	return rc;
-}
-
-long venc_mmap(struct v4l2_subdev *sd, void *arg)
-{
-	struct venc_inst *inst = sd->dev_priv;
-	struct mem_region_map *mmap = arg;
-	struct mem_region *mregion = NULL;
-	unsigned long rc = 0, size = 0;
-	void *paddr = NULL;
-
-	if (!sd) {
-		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
-		return -EINVAL;
-	} else if (!mmap || !mmap->mregion) {
-		WFD_MSG_ERR("Memregion required for %s\n", __func__);
-		return -EINVAL;
-	}
-
-	mregion = mmap->mregion;
-	if (mregion->size % SZ_4K != 0) {
-		WFD_MSG_ERR("Memregion not aligned to %d\n", SZ_4K);
-		return -EINVAL;
-	}
-
-	if (inst->secure) {
-		rc = ion_phys(mmap->ion_client, mregion->ion_handle,
-				(unsigned long *)&paddr,
-				(size_t *)&size);
-	} else {
-		rc = ion_map_iommu(mmap->ion_client, mregion->ion_handle,
-				VIDEO_DOMAIN, VIDEO_MAIN_POOL, SZ_4K,
-				0, (unsigned long *)&paddr,
-				&size, 0, 0);
-	}
-
-	if (rc) {
-		WFD_MSG_ERR("Failed to get physical addr\n");
-		paddr = NULL;
-	} else if (size < mregion->size) {
-		WFD_MSG_ERR("Failed to map enough memory\n");
-		rc = -ENOMEM;
-	}
-
-	mregion->paddr = paddr;
-	return rc;
-}
-
-long venc_munmap(struct v4l2_subdev *sd, void *arg)
-{
-	struct venc_inst *inst = sd->dev_priv;
-	struct mem_region_map *mmap = arg;
-	struct mem_region *mregion = NULL;
-	if (!sd) {
-		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
-		return -EINVAL;
-	} else if (!mregion) {
-		WFD_MSG_ERR("Memregion required for %s\n", __func__);
-		return -EINVAL;
-	}
-
-	mregion = mmap->mregion;
-	if (!inst->secure) {
-		ion_unmap_iommu(mmap->ion_client, mregion->ion_handle,
-				VIDEO_DOMAIN, VIDEO_MAIN_POOL);
-	}
-
-	return 0;
-}
-
-long venc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
-{
-	long rc = 0;
-	switch (cmd) {
-	case OPEN:
-		rc = venc_open(sd, arg);
-		break;
-	case CLOSE:
-		rc = venc_close(sd, arg);
-		break;
-	case ENCODE_START:
-		rc = venc_start(sd);
-		break;
-	case ENCODE_FRAME:
-		venc_encode_frame(sd, arg);
-		break;
-	case ENCODE_STOP:
-		rc = venc_stop(sd);
-		break;
-	case SET_PROP:
-		rc = venc_set_property(sd, arg);
-		break;
-	case GET_PROP:
-		rc = venc_get_property(sd, arg);
-		break;
-	case GET_BUFFER_REQ:
-		rc = venc_get_buffer_req(sd, arg);
-		break;
-	case SET_BUFFER_REQ:
-		rc = venc_set_buffer_req(sd, arg);
-		break;
-	case FREE_BUFFER:
-		break;
-	case FILL_OUTPUT_BUFFER:
-		rc = venc_fill_outbuf(sd, arg);
-		break;
-	case SET_FORMAT:
-		rc = venc_set_format(sd, arg);
-		break;
-	case SET_FRAMERATE:
-		rc = venc_set_framerate(sd, arg);
-		break;
-	case SET_INPUT_BUFFER:
-		rc = venc_set_input_buffer(sd, arg);
-		break;
-	case SET_OUTPUT_BUFFER:
-		rc = venc_set_output_buffer(sd, arg);
-		break;
-	case ALLOC_RECON_BUFFERS:
-		rc = venc_alloc_recon_buffers(sd, arg);
-		break;
-	case FREE_OUTPUT_BUFFER:
-		rc = venc_free_output_buffer(sd, arg);
-		break;
-	case FREE_INPUT_BUFFER:
-		rc = venc_free_input_buffer(sd, arg);
-		break;
-	case FREE_RECON_BUFFERS:
-		rc = venc_free_recon_buffers(sd, arg);
-		break;
-	case ENCODE_FLUSH:
-		rc = venc_flush_buffers(sd, arg);
-		break;
-	case ENC_MMAP:
-		rc = venc_mmap(sd, arg);
-		break;
-	case ENC_MUNMAP:
-		rc = venc_munmap(sd, arg);
-		break;
-	case SET_FRAMERATE_MODE:
-		rc = venc_set_framerate_mode(sd, arg);
-		break;
-	default:
-		rc = -1;
-		break;
-	}
-	return rc;
-}
diff --git a/drivers/media/video/msm_wfd/enc-subdev.h b/drivers/media/video/msm_wfd/enc-subdev.h
deleted file mode 100644
index 25373e4..0000000
--- a/drivers/media/video/msm_wfd/enc-subdev.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 _WFD_ENC_SUBDEV_
-#define _WFD_ENC_SUBDEV_
-
-#include <linux/list.h>
-#include <linux/msm_ion.h>
-#include <media/v4l2-subdev.h>
-#include <media/videobuf2-core.h>
-#define VENC_MAGIC_IOCTL 'V'
-
-enum venc_framerate_modes {
-	VENC_MODE_CFR,
-	VENC_MODE_VFR,
-};
-
-struct mem_region {
-	struct list_head list;
-	u8 *kvaddr;
-	u8 *paddr;
-	u32 size;
-	u32 offset;
-	u32 fd;
-	u32 cookie;
-	struct ion_handle *ion_handle;
-};
-
-/* FIXME: need to come with a less stupid name */
-struct mem_region_map {
-	struct mem_region *mregion;
-	struct ion_client *ion_client;
-	uint32_t flags;
-	void *cookie;
-};
-
-struct bufreq {
-	u32 count;
-	u32 height;
-	u32 width;
-	u32 size;
-};
-
-struct venc_buf_info {
-	u64 timestamp;
-	struct mem_region *mregion;
-};
-
-struct venc_msg_ops {
-	void *cookie;
-	void *cbdata;
-	bool secure;
-	void (*op_buffer_done)(void *cookie, u32 status,
-			struct vb2_buffer *buf);
-	void (*ip_buffer_done)(void *cookie, u32 status,
-			struct mem_region *mregion);
-};
-
-static inline bool mem_region_equals(struct mem_region *a,
-		struct mem_region *b)
-{
-	if (a == b)
-		return true;
-	else if (a->fd || b->fd)
-		return (a->fd == b->fd) &&
-			(a->offset == b->offset);
-	else if (a->kvaddr || b->kvaddr)
-		return a->kvaddr == b->kvaddr;
-	else
-		return false;
-}
-
-#define OPEN  _IOR('V', 1, void *)
-#define CLOSE  _IO('V', 2)
-#define ENCODE_START  _IO('V', 3)
-#define ENCODE_FRAME  _IOW('V', 4, struct venc_buf_info *)
-#define PAUSE  _IO('V', 5)
-#define RESUME  _IO('V', 6)
-#define FLUSH  _IO('V', 7)
-#define ENCODE_STOP  _IO('V', 8)
-#define SET_PROP  _IO('V', 9)
-#define GET_PROP  _IO('V', 10)
-#define SET_BUFFER_REQ  _IOWR('V', 11, struct v4l2_requestbuffers *)
-#define GET_BUFFER_REQ  _IOWR('V', 12, struct v4l2_requestbuffers *)
-#define ALLOCATE_BUFFER  _IO('V', 13)
-#define FREE_BUFFER  _IO('V', 14)
-#define FILL_OUTPUT_BUFFER  _IO('V', 15)
-#define SET_FORMAT _IOW('V', 16, struct v4l2_format *)
-#define SET_FRAMERATE _IOW('V', 17, struct v4l2_fract *)
-#define SET_INPUT_BUFFER _IOWR('V', 18, struct mem_region *)
-#define SET_OUTPUT_BUFFER _IOWR('V', 19, struct mem_region *)
-#define ALLOC_RECON_BUFFERS _IO('V', 20)
-#define FREE_OUTPUT_BUFFER _IOWR('V', 21, struct mem_region *)
-#define FREE_INPUT_BUFFER _IOWR('V', 22, struct mem_region *)
-#define FREE_RECON_BUFFERS _IO('V', 23)
-#define ENCODE_FLUSH _IO('V', 24)
-#define ENC_MMAP _IOWR('V', 25, struct mem_region_map *)
-#define ENC_MUNMAP _IOWR('V', 26, struct mem_region_map *)
-#define SET_FRAMERATE_MODE _IO('V', 27)
-
-extern int venc_init(struct v4l2_subdev *sd, u32 val);
-extern int venc_load_fw(struct v4l2_subdev *sd);
-extern long venc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg);
-
-
-#endif /* _WFD_ENC_SUBDEV_ */
diff --git a/drivers/media/video/msm_wfd/enc-venus-subdev.c b/drivers/media/video/msm_wfd/enc-venus-subdev.c
deleted file mode 100644
index 73a3d8e..0000000
--- a/drivers/media/video/msm_wfd/enc-venus-subdev.c
+++ /dev/null
@@ -1,1238 +0,0 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License version 2 and
-* only version 2 as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-*/
-
-#include <linux/bitmap.h>
-#include <linux/completion.h>
-#include <linux/ion.h>
-#include <linux/kthread.h>
-#include <linux/list.h>
-#include <linux/mutex.h>
-#include <linux/wait.h>
-#include <mach/iommu_domains.h>
-#include <media/msm_vidc.h>
-#include <media/v4l2-subdev.h>
-#include "enc-subdev.h"
-#include "wfd-util.h"
-
-#define BUF_TYPE_OUTPUT V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
-#define BUF_TYPE_INPUT V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
-
-static struct ion_client *venc_ion_client;
-
-struct index_bitmap {
-	unsigned long *bitmap;
-	int size;
-	int size_bits; /*Size in bits, not necessarily size/8 */
-};
-
-struct venc_inst {
-	void *vidc_context;
-	struct mutex lock;
-	struct venc_msg_ops vmops;
-	struct mem_region registered_input_bufs, registered_output_bufs;
-	struct index_bitmap free_input_indices, free_output_indices;
-	int num_output_planes, num_input_planes;
-	struct task_struct *callback_thread;
-	bool callback_thread_running;
-	struct completion dq_complete, cmd_complete;
-	bool secure;
-	int domain;
-};
-
-int venc_load_fw(struct v4l2_subdev *sd)
-{
-	/*No need to explicitly load the fw */
-	return 0;
-}
-
-int venc_init(struct v4l2_subdev *sd, u32 val)
-{
-	if (!venc_ion_client)
-		venc_ion_client = msm_ion_client_create(-1, "wfd_enc_subdev");
-
-	return venc_ion_client ? 0 : -ENOMEM;
-}
-
-static int next_free_index(struct index_bitmap *index_bitmap)
-{
-	int index = find_first_zero_bit(index_bitmap->bitmap,
-			index_bitmap->size_bits);
-
-	return (index >= index_bitmap->size_bits) ?
-		-1 : index;
-}
-
-static int mark_index_busy(struct index_bitmap *index_bitmap, int index)
-{
-	if (index > index_bitmap->size_bits) {
-		WFD_MSG_WARN("Marking unknown index as busy\n");
-		return -EINVAL;
-	}
-	set_bit(index, index_bitmap->bitmap);
-	return 0;
-}
-
-static int mark_index_free(struct index_bitmap *index_bitmap, int index)
-{
-	if (index > index_bitmap->size_bits) {
-		WFD_MSG_WARN("Marking unknown index as free\n");
-		return -EINVAL;
-	}
-	clear_bit(index, index_bitmap->bitmap);
-	return 0;
-}
-
-static int get_list_len(struct mem_region *list)
-{
-	struct mem_region *curr = NULL;
-	int index = 0;
-	list_for_each_entry(curr, &list->list, list) {
-		++index;
-	}
-
-	return index;
-}
-
-static struct mem_region *get_registered_mregion(struct mem_region *list,
-		struct mem_region *mregion)
-{
-	struct mem_region *curr = NULL;
-	list_for_each_entry(curr, &list->list, list) {
-		if (unlikely(mem_region_equals(curr, mregion)))
-			return curr;
-	}
-
-	return NULL;
-}
-
-static int venc_vidc_callback_thread(void *data)
-{
-	struct venc_inst *inst = data;
-	WFD_MSG_DBG("Starting callback thread\n");
-	while (!kthread_should_stop()) {
-		bool dequeue_buf = false;
-		struct v4l2_buffer buffer = {0};
-		struct v4l2_event event = {0};
-		int num_planes = 0;
-		int flags = msm_vidc_wait(inst->vidc_context);
-
-		if (flags & POLLERR) {
-			WFD_MSG_ERR("Encoder reported error\n");
-			break;
-		}
-
-		if (flags & POLLPRI) {
-			bool bail_out = false;
-
-			msm_vidc_dqevent(inst->vidc_context, &event);
-			if (event.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
-				WFD_MSG_DBG("enc callback thread shutting " \
-						"down normally\n");
-				bail_out = true;
-			} else {
-				WFD_MSG_ERR("Got unknown event %d, ignoring\n",
-						event.id);
-			}
-
-			complete_all(&inst->cmd_complete);
-			if (bail_out)
-				break;
-		}
-
-		if (flags & POLLIN || flags & POLLRDNORM) {
-			buffer.type = BUF_TYPE_OUTPUT;
-			dequeue_buf = true;
-			num_planes = inst->num_output_planes;
-			WFD_MSG_DBG("Output buffer ready!\n");
-		}
-
-		if (flags & POLLOUT || flags & POLLWRNORM) {
-			buffer.type = BUF_TYPE_INPUT;
-			dequeue_buf = true;
-			num_planes = inst->num_input_planes;
-			WFD_MSG_DBG("Input buffer ready!\n");
-		}
-
-		if (dequeue_buf) {
-			int rc = 0;
-			struct v4l2_plane *planes = NULL;
-			struct mem_region *curr = NULL, *mregion = NULL;
-			struct list_head *reg_bufs = NULL;
-			struct index_bitmap *bitmap = NULL;
-
-			planes = kzalloc(sizeof(*planes) * num_planes,
-					GFP_KERNEL);
-			buffer.m.planes = planes;
-			buffer.length = 1;
-			buffer.memory = V4L2_MEMORY_USERPTR;
-			rc = msm_vidc_dqbuf(inst->vidc_context, &buffer);
-
-			if (rc) {
-				WFD_MSG_ERR("Error dequeuing buffer " \
-						"from vidc: %d", rc);
-				goto abort_dequeue;
-			}
-
-			reg_bufs = buffer.type == BUF_TYPE_OUTPUT ?
-				&inst->registered_output_bufs.list :
-				&inst->registered_input_bufs.list;
-
-			bitmap = buffer.type == BUF_TYPE_OUTPUT ?
-				&inst->free_output_indices :
-				&inst->free_input_indices;
-
-			list_for_each_entry(curr, reg_bufs, list) {
-				if ((u32)curr->paddr ==
-						buffer.m.planes[0].m.userptr) {
-					mregion = curr;
-					break;
-				}
-			}
-
-			if (!mregion) {
-				WFD_MSG_ERR("Got done msg for unknown buf\n");
-				goto abort_dequeue;
-			}
-
-			if (buffer.type == BUF_TYPE_OUTPUT &&
-				inst->vmops.op_buffer_done) {
-				struct vb2_buffer *vb =
-					(struct vb2_buffer *)mregion->cookie;
-
-				vb->v4l2_buf.flags = buffer.flags;
-				vb->v4l2_buf.timestamp = buffer.timestamp;
-				vb->v4l2_planes[0].bytesused =
-					buffer.m.planes[0].bytesused;
-
-				inst->vmops.op_buffer_done(
-					inst->vmops.cbdata, 0, vb);
-			} else if (buffer.type == BUF_TYPE_INPUT &&
-					inst->vmops.ip_buffer_done) {
-				inst->vmops.ip_buffer_done(
-						inst->vmops.cbdata,
-						0, mregion);
-			}
-
-			complete_all(&inst->dq_complete);
-			mutex_lock(&inst->lock);
-			mark_index_free(bitmap, buffer.index);
-			mutex_unlock(&inst->lock);
-abort_dequeue:
-			kfree(planes);
-		}
-	}
-
-
-	WFD_MSG_DBG("Exiting callback thread\n");
-	mutex_lock(&inst->lock);
-	inst->callback_thread_running = false;
-	mutex_unlock(&inst->lock);
-	return 0;
-}
-
-static long set_default_properties(struct venc_inst *inst)
-{
-	struct v4l2_control ctrl = {0};
-
-	/* Set the IDR period as 1.  The venus core doesn't give
-	 * the sps/pps for I-frames, only IDR. */
-	ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
-	ctrl.value = 1;
-
-	return msm_vidc_s_ctrl(inst->vidc_context, &ctrl);
-}
-
-static long venc_open(struct v4l2_subdev *sd, void *arg)
-{
-	struct venc_inst *inst = NULL;
-	struct venc_msg_ops *vmops = arg;
-	struct v4l2_event_subscription event = {0};
-	struct msm_vidc_iommu_info maps[MAX_MAP];
-	int rc = 0;
-
-	if (!vmops) {
-		WFD_MSG_ERR("Callbacks required for %s\n", __func__);
-		rc = -EINVAL;
-		goto venc_open_fail;
-	} else if (!sd) {
-		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
-		rc = -EINVAL;
-		goto venc_open_fail;
-	}
-
-	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
-	if (!inst) {
-		WFD_MSG_ERR("Failed to allocate memory\n");
-		rc = -EINVAL;
-		goto venc_open_fail;
-	}
-
-	inst->secure = false;
-	inst->vmops = *vmops;
-	INIT_LIST_HEAD(&inst->registered_output_bufs.list);
-	INIT_LIST_HEAD(&inst->registered_input_bufs.list);
-	init_completion(&inst->dq_complete);
-	init_completion(&inst->cmd_complete);
-	mutex_init(&inst->lock);
-	inst->vidc_context = msm_vidc_open(MSM_VIDC_CORE_0, MSM_VIDC_ENCODER);
-	if (!inst->vidc_context) {
-		WFD_MSG_ERR("Failed to create vidc context\n");
-		rc = -ENXIO;
-		goto vidc_open_fail;
-	}
-
-	event.type = V4L2_EVENT_MSM_VIDC_CLOSE_DONE;
-	rc = msm_vidc_subscribe_event(inst->vidc_context, &event);
-	if (rc) {
-		WFD_MSG_ERR("Failed to subscribe to CLOSE_DONE event\n");
-		goto vidc_subscribe_fail;
-	}
-
-	event.type = V4L2_EVENT_MSM_VIDC_FLUSH_DONE;
-	rc = msm_vidc_subscribe_event(inst->vidc_context, &event);
-	if (rc) {
-		WFD_MSG_ERR("Failed to subscribe to FLUSH_DONE event\n");
-		goto vidc_subscribe_fail;
-	}
-
-	rc = msm_vidc_get_iommu_maps(inst->vidc_context, maps);
-	if (rc) {
-		WFD_MSG_ERR("Failed to retreive domain mappings\n");
-		rc = -ENODATA;
-		goto vidc_subscribe_fail;
-	}
-
-	inst->domain = maps[inst->secure ? CP_MAP : NS_MAP].domain;
-
-	inst->callback_thread = kthread_run(venc_vidc_callback_thread, inst,
-					"venc_vidc_callback_thread");
-	if (IS_ERR(inst->callback_thread)) {
-		WFD_MSG_ERR("Failed to create callback thread\n");
-		rc = PTR_ERR(inst->callback_thread);
-		inst->callback_thread = NULL;
-		goto vidc_kthread_create_fail;
-	}
-	inst->callback_thread_running = true;
-
-	sd->dev_priv = inst;
-	vmops->cookie = inst;
-	return 0;
-vidc_kthread_create_fail:
-	event.type = V4L2_EVENT_MSM_VIDC_CLOSE_DONE;
-	msm_vidc_unsubscribe_event(inst->vidc_context, &event);
-
-	event.type = V4L2_EVENT_MSM_VIDC_FLUSH_DONE;
-	msm_vidc_unsubscribe_event(inst->vidc_context, &event);
-vidc_subscribe_fail:
-	msm_vidc_close(inst->vidc_context);
-vidc_open_fail:
-	kfree(inst);
-venc_open_fail:
-	return rc;
-}
-
-static long venc_close(struct v4l2_subdev *sd, void *arg)
-{
-	struct venc_inst *inst = NULL;
-	struct v4l2_event_subscription event = {0};
-	struct v4l2_encoder_cmd enc_cmd = {0};
-	int rc = 0;
-
-	if (!sd) {
-		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
-		rc = -EINVAL;
-		goto venc_close_fail;
-	}
-
-	inst = (struct venc_inst *)sd->dev_priv;
-	enc_cmd.cmd = V4L2_ENC_CMD_STOP;
-	msm_vidc_encoder_cmd(inst->vidc_context, &enc_cmd);
-
-	wait_for_completion(&inst->cmd_complete);
-
-	if (inst->callback_thread && inst->callback_thread_running)
-		kthread_stop(inst->callback_thread);
-
-	event.type = V4L2_EVENT_MSM_VIDC_CLOSE_DONE;
-	rc = msm_vidc_unsubscribe_event(inst->vidc_context, &event);
-	if (rc)
-		WFD_MSG_WARN("Failed to unsubscribe close event\n");
-
-	event.type = V4L2_EVENT_MSM_VIDC_FLUSH_DONE;
-	rc = msm_vidc_unsubscribe_event(inst->vidc_context, &event);
-	if (rc)
-		WFD_MSG_WARN("Failed to unsubscribe flush event\n");
-
-	rc = msm_vidc_close(inst->vidc_context);
-	if (rc)
-		WFD_MSG_WARN("Failed to close vidc context\n");
-
-	kfree(inst);
-	sd->dev_priv = inst = NULL;
-venc_close_fail:
-	return rc;
-}
-
-static long venc_get_buffer_req(struct v4l2_subdev *sd, void *arg)
-{
-	int rc = 0;
-	struct venc_inst *inst = NULL;
-	struct bufreq *bufreq = arg;
-	struct v4l2_requestbuffers v4l2_bufreq = {0};
-	struct v4l2_format v4l2_format = {0};
-
-	if (!sd) {
-		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
-		rc = -EINVAL;
-		goto venc_buf_req_fail;
-	} else if (!arg) {
-		WFD_MSG_ERR("Invalid buffer requirements\n");
-		rc = -EINVAL;
-		goto venc_buf_req_fail;
-	}
-
-	inst = (struct venc_inst *)sd->dev_priv;
-	/* Get buffer count */
-	v4l2_bufreq = (struct v4l2_requestbuffers) {
-		.count = bufreq->count,
-		.type = BUF_TYPE_OUTPUT,
-		.memory = V4L2_MEMORY_USERPTR,
-	};
-
-	rc = msm_vidc_reqbufs(inst->vidc_context, &v4l2_bufreq);
-	if (rc) {
-		WFD_MSG_ERR("Failed getting buffer requirements\n");
-		goto venc_buf_req_fail;
-	}
-
-	/* Get buffer size */
-	v4l2_format.type = BUF_TYPE_OUTPUT;
-	rc = msm_vidc_g_fmt(inst->vidc_context, &v4l2_format);
-	if (rc) {
-		WFD_MSG_ERR("Failed getting OP buffer size\n");
-		goto venc_buf_req_fail;
-	}
-
-	bufreq->count = v4l2_bufreq.count;
-	bufreq->size = v4l2_format.fmt.pix_mp.plane_fmt[0].sizeimage;
-
-	inst->free_output_indices.size_bits = bufreq->count;
-	inst->free_output_indices.size = roundup(bufreq->count,
-				sizeof(unsigned long)) / sizeof(unsigned long);
-	inst->free_output_indices.bitmap = kzalloc(inst->free_output_indices.
-						size, GFP_KERNEL);
-venc_buf_req_fail:
-	return rc;
-}
-
-static long venc_set_buffer_req(struct v4l2_subdev *sd, void *arg)
-{
-	int rc = 0;
-	struct venc_inst *inst = NULL;
-	struct bufreq *bufreq = arg;
-	struct v4l2_requestbuffers v4l2_bufreq = {0};
-	struct v4l2_format v4l2_format = {0};
-
-	if (!sd) {
-		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
-		rc = -EINVAL;
-		goto venc_buf_req_fail;
-	} else if (!arg) {
-		WFD_MSG_ERR("Invalid buffer requirements\n");
-		rc = -EINVAL;
-		goto venc_buf_req_fail;
-	}
-
-	inst = (struct venc_inst *)sd->dev_priv;
-
-	/* Attempt to set buffer count */
-	v4l2_bufreq = (struct v4l2_requestbuffers) {
-		.count = bufreq->count,
-		.type = BUF_TYPE_INPUT,
-		.memory = V4L2_MEMORY_USERPTR,
-	};
-
-	rc = msm_vidc_reqbufs(inst->vidc_context, &v4l2_bufreq);
-	if (rc) {
-		WFD_MSG_ERR("Failed getting buffer requirements");
-		goto venc_buf_req_fail;
-	}
-
-	/* Get buffer size */
-	v4l2_format.type = BUF_TYPE_INPUT;
-	rc = msm_vidc_g_fmt(inst->vidc_context, &v4l2_format);
-	if (rc) {
-		WFD_MSG_ERR("Failed getting OP buffer size\n");
-		goto venc_buf_req_fail;
-	}
-
-	bufreq->count = v4l2_bufreq.count;
-	bufreq->size = v4l2_format.fmt.pix_mp.plane_fmt[0].sizeimage;
-
-	inst->free_input_indices.size_bits = bufreq->count;
-	inst->free_input_indices.size = roundup(bufreq->count,
-				sizeof(unsigned long)) / sizeof(unsigned long);
-	inst->free_input_indices.bitmap = kzalloc(inst->free_input_indices.
-						size, GFP_KERNEL);
-venc_buf_req_fail:
-	return rc;
-}
-
-static long venc_start(struct v4l2_subdev *sd)
-{
-	struct venc_inst *inst = NULL;
-	int rc = 0;
-
-	if (!sd) {
-		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
-		rc = -EINVAL;
-		goto venc_start_fail;
-	}
-
-	inst = (struct venc_inst *)sd->dev_priv;
-
-	if (set_default_properties(inst))
-		WFD_MSG_WARN("Couldn't set default properties\n");
-
-	rc = msm_vidc_streamon(inst->vidc_context, BUF_TYPE_OUTPUT);
-	if (rc) {
-		WFD_MSG_ERR("Failed to streamon vidc's output port");
-		goto venc_start_fail;
-	}
-
-	rc = msm_vidc_streamon(inst->vidc_context, BUF_TYPE_INPUT);
-	if (rc) {
-		WFD_MSG_ERR("Failed to streamon vidc's input port");
-		goto venc_start_fail;
-	}
-
-venc_start_fail:
-	return rc;
-}
-
-static long venc_stop(struct v4l2_subdev *sd)
-{
-	struct venc_inst *inst = NULL;
-	int rc = 0;
-
-	if (!sd) {
-		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
-		rc = -EINVAL;
-		goto venc_stop_fail;
-	}
-
-	inst = (struct venc_inst *)sd->dev_priv;
-
-	rc = msm_vidc_streamoff(inst->vidc_context, BUF_TYPE_INPUT);
-	if (rc) {
-		WFD_MSG_ERR("Failed to streamoff vidc's input port");
-		goto venc_stop_fail;
-	}
-
-	rc = msm_vidc_streamoff(inst->vidc_context, BUF_TYPE_OUTPUT);
-	if (rc) {
-		WFD_MSG_ERR("Failed to streamoff vidc's output port");
-		goto venc_stop_fail;
-	}
-
-venc_stop_fail:
-	return rc;
-}
-
-static long venc_set_input_buffer(struct v4l2_subdev *sd, void *arg)
-{
-	int rc = 0;
-	struct venc_inst *inst = NULL;
-	struct v4l2_buffer buf = {0};
-	struct v4l2_plane plane = {0};
-	struct mem_region *mregion = arg;
-
-	if (!sd) {
-		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
-		rc =  -EINVAL;
-		goto set_input_buffer_fail;
-	} else if (!arg) {
-		WFD_MSG_ERR("Invalid input buffer\n");
-		rc =  -EINVAL;
-		goto set_input_buffer_fail;
-	}
-
-	inst = (struct venc_inst *)sd->dev_priv;
-	if (get_registered_mregion(&inst->registered_input_bufs, mregion)) {
-		WFD_MSG_ERR("Duplicate input buffer\n");
-		rc = -EEXIST;
-		goto set_input_buffer_fail;
-	}
-
-	mregion = kzalloc(sizeof(*mregion), GFP_KERNEL);
-	*mregion = *(struct mem_region *)arg;
-
-	plane = (struct v4l2_plane) {
-		.length = mregion->size,
-		.m.userptr = (u32)mregion->paddr,
-	};
-
-	buf = (struct v4l2_buffer) {
-		.index = get_list_len(&inst->registered_input_bufs),
-		.type = BUF_TYPE_INPUT,
-		.bytesused = 0,
-		.memory = V4L2_MEMORY_USERPTR,
-		.m.planes = &plane,
-		.length = 1,
-	};
-
-	WFD_MSG_DBG("Prepare %p with index, %d",
-		(void *)buf.m.planes[0].m.userptr, buf.index);
-	rc = msm_vidc_prepare_buf(inst->vidc_context, &buf);
-	if (rc) {
-		WFD_MSG_ERR("Failed to prepare input buffer\n");
-		goto set_input_buffer_fail;
-	}
-
-	list_add_tail(&mregion->list, &inst->registered_input_bufs.list);
-	return 0;
-set_input_buffer_fail:
-	kfree(mregion);
-	return rc;
-}
-
-static int venc_map_user_to_kernel(struct venc_inst *inst,
-		struct mem_region *mregion)
-{
-	int rc = 0;
-	unsigned long flags = 0, size = 0;
-	if (!mregion) {
-		rc = -EINVAL;
-		goto venc_map_fail;
-	}
-
-	mregion->ion_handle = ion_import_dma_buf(venc_ion_client, mregion->fd);
-	if (IS_ERR_OR_NULL(mregion->ion_handle)) {
-		rc = PTR_ERR(mregion->ion_handle);
-		WFD_MSG_ERR("Failed to get handle: %p, %d, %d, %d\n",
-			venc_ion_client, mregion->fd, mregion->offset, rc);
-		mregion->ion_handle = NULL;
-		goto venc_map_fail;
-	}
-
-	rc = ion_handle_get_flags(venc_ion_client, mregion->ion_handle, &flags);
-	if (rc) {
-		WFD_MSG_ERR("Failed to get ion flags %d\n", rc);
-		goto venc_map_fail;
-	}
-
-	mregion->kvaddr = ion_map_kernel(venc_ion_client,
-				mregion->ion_handle);
-
-	if (IS_ERR_OR_NULL(mregion->kvaddr)) {
-		WFD_MSG_ERR("Failed to map buffer into kernel\n");
-		rc = PTR_ERR(mregion->kvaddr);
-		mregion->kvaddr = NULL;
-		goto venc_map_fail;
-	}
-
-	rc = ion_map_iommu(venc_ion_client, mregion->ion_handle,
-			inst->domain, 0, SZ_4K, 0,
-			(unsigned long *)&mregion->paddr, &size, flags, 0);
-
-	if (rc) {
-		WFD_MSG_ERR("Failed to map into iommu\n");
-		goto venc_map_iommu_map_fail;
-	} else if (size < mregion->size) {
-		WFD_MSG_ERR("Failed to iommu map the correct size\n");
-		goto venc_map_iommu_size_fail;
-	}
-
-	return 0;
-venc_map_iommu_size_fail:
-	ion_unmap_iommu(venc_ion_client, mregion->ion_handle,
-			inst->domain, 0);
-venc_map_iommu_map_fail:
-	ion_unmap_kernel(venc_ion_client, mregion->ion_handle);
-venc_map_fail:
-	return rc;
-}
-
-static int venc_unmap_user_to_kernel(struct venc_inst *inst,
-		struct mem_region *mregion)
-{
-	if (!mregion || !mregion->ion_handle)
-		return 0;
-
-	if (mregion->paddr) {
-		ion_unmap_iommu(venc_ion_client, mregion->ion_handle,
-				inst->domain, 0);
-		mregion->paddr = NULL;
-	}
-
-	if (mregion->kvaddr) {
-		ion_unmap_kernel(venc_ion_client, mregion->ion_handle);
-		mregion->kvaddr = NULL;
-	}
-
-
-	return 0;
-}
-
-static long venc_set_output_buffer(struct v4l2_subdev *sd, void *arg)
-{
-	int rc = 0;
-	struct venc_inst *inst = NULL;
-	struct v4l2_buffer buf = {0};
-	struct v4l2_plane plane = {0};
-	struct mem_region *mregion = arg;
-
-	if (!sd) {
-		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
-		rc = -EINVAL;
-		goto venc_set_output_buffer_fail;
-	} else if (!mregion) {
-		WFD_MSG_ERR("Invalid output buffer\n");
-		rc = -EINVAL;
-		goto venc_set_output_buffer_fail;
-	}
-
-	inst = (struct venc_inst *)sd->dev_priv;
-
-	/* Check if buf already registered */
-	if (get_registered_mregion(&inst->registered_output_bufs, mregion)) {
-		WFD_MSG_ERR("Duplicate output buffer\n");
-		rc = -EEXIST;
-		goto venc_set_output_buffer_fail;
-	}
-
-	mregion = kzalloc(sizeof(*mregion), GFP_KERNEL);
-
-	if (!mregion) {
-		WFD_MSG_ERR("Failed to allocate memory\n");
-		goto venc_set_output_buffer_fail;
-	}
-
-	*mregion = *(struct mem_region *)arg;
-	INIT_LIST_HEAD(&mregion->list);
-
-	rc = venc_map_user_to_kernel(inst, mregion);
-	if (rc) {
-		WFD_MSG_ERR("Failed to map output buffer\n");
-		goto venc_set_output_buffer_map_fail;
-	}
-
-	plane = (struct v4l2_plane) {
-		.length = mregion->size,
-		.m.userptr = (u32)mregion->paddr,
-	};
-
-	buf = (struct v4l2_buffer) {
-		.index = get_list_len(&inst->registered_output_bufs),
-		.type = BUF_TYPE_OUTPUT,
-		.bytesused = 0,
-		.memory = V4L2_MEMORY_USERPTR,
-		.m.planes = &plane,
-		.length = 1,
-	};
-
-	WFD_MSG_DBG("Prepare %p with index, %d",
-		(void *)buf.m.planes[0].m.userptr, buf.index);
-	rc = msm_vidc_prepare_buf(inst->vidc_context, &buf);
-	if (rc) {
-		WFD_MSG_ERR("Failed to prepare output buffer\n");
-		goto venc_set_output_buffer_prepare_fail;
-	}
-
-	list_add_tail(&mregion->list, &inst->registered_output_bufs.list);
-	return rc;
-venc_set_output_buffer_prepare_fail:
-	venc_unmap_user_to_kernel(inst, mregion);
-venc_set_output_buffer_map_fail:
-	kfree(mregion);
-venc_set_output_buffer_fail:
-	return rc;
-}
-
-static long venc_set_format(struct v4l2_subdev *sd, void *arg)
-{
-	struct venc_inst *inst = NULL;
-	struct v4l2_format *fmt = arg, temp;
-	int rc = 0;
-
-	if (!sd) {
-		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
-		rc = -EINVAL;
-		goto venc_set_format_fail;
-	} else if (!fmt) {
-		WFD_MSG_ERR("Invalid format\n");
-		rc = -EINVAL;
-		goto venc_set_format_fail;
-	} else if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-		WFD_MSG_ERR("Invalid buffer type %d\n", fmt->type);
-		rc = -ENOTSUPP;
-		goto venc_set_format_fail;
-	}
-
-	inst = (struct venc_inst *)sd->dev_priv;
-	temp = (struct v4l2_format) {
-		.type = BUF_TYPE_OUTPUT,
-		.fmt.pix_mp = (struct v4l2_pix_format_mplane) {
-			.width = fmt->fmt.pix.width,
-			.height = fmt->fmt.pix.height,
-			.pixelformat = fmt->fmt.pix.pixelformat,
-		},
-	};
-
-	rc = msm_vidc_s_fmt(inst->vidc_context, &temp);
-
-	if (rc) {
-		WFD_MSG_ERR("Failed to format for output port\n");
-		goto venc_set_format_fail;
-	} else if (!temp.fmt.pix_mp.num_planes) {
-		WFD_MSG_ERR("No. of planes for output buffers make no sense\n");
-		rc = -EINVAL;
-		goto venc_set_format_fail;
-	}
-	fmt->fmt.pix.sizeimage = temp.fmt.pix_mp.plane_fmt[0].sizeimage;
-	inst->num_output_planes = temp.fmt.pix_mp.num_planes;
-
-	temp.type = BUF_TYPE_INPUT;
-	temp.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
-	rc = msm_vidc_s_fmt(inst->vidc_context, &temp);
-	inst->num_input_planes = temp.fmt.pix_mp.num_planes;
-
-	if (rc) {
-		WFD_MSG_ERR("Failed to format for input port\n");
-		goto venc_set_format_fail;
-	}
-venc_set_format_fail:
-	return rc;
-}
-
-static long venc_set_framerate(struct v4l2_subdev *sd, void *arg)
-{
-	struct venc_inst *inst = NULL;
-	struct v4l2_streamparm p = {0};
-
-	if (!sd) {
-		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
-		return -EINVAL;
-	} else if (!arg) {
-		WFD_MSG_ERR("Invalid framerate\n");
-		return -EINVAL;
-	}
-
-	inst = (struct venc_inst *)sd->dev_priv;
-	p.type = BUF_TYPE_INPUT;
-	p.parm.output.timeperframe = *(struct v4l2_fract *)arg;
-	return msm_vidc_s_parm(inst->vidc_context, &p);
-}
-
-static long venc_fill_outbuf(struct v4l2_subdev *sd, void *arg)
-{
-	struct venc_inst *inst = NULL;
-	struct mem_region *mregion = NULL;
-	struct v4l2_buffer buffer = {0};
-	struct v4l2_plane plane = {0};
-	int index = 0, rc = 0;
-
-	if (!sd) {
-		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
-		return -EINVAL;
-	} else if (!arg) {
-		WFD_MSG_ERR("Invalid output buffer ot fill\n");
-		return -EINVAL;
-	}
-
-	inst = (struct venc_inst *)sd->dev_priv;
-	mregion = get_registered_mregion(&inst->registered_output_bufs, arg);
-
-	if (!mregion) {
-		WFD_MSG_ERR("Output buffer not registered\n");
-		return -ENOENT;
-	}
-
-	plane = (struct v4l2_plane) {
-		.length = mregion->size,
-		.m.userptr = (u32)mregion->paddr,
-	};
-
-	while (true) {
-		mutex_lock(&inst->lock);
-		index = next_free_index(&inst->free_output_indices);
-		mutex_unlock(&inst->lock);
-
-		if (index < 0)
-			wait_for_completion(&inst->dq_complete);
-		else
-			break;
-	}
-
-	buffer = (struct v4l2_buffer) {
-		.index = index,
-		.type = BUF_TYPE_OUTPUT,
-		.memory = V4L2_MEMORY_USERPTR,
-		.m.planes = &plane,
-		.length = 1,
-	};
-
-	WFD_MSG_DBG("Fill buffer %p with index, %d",
-		(void *)buffer.m.planes[0].m.userptr, buffer.index);
-	rc = msm_vidc_qbuf(inst->vidc_context, &buffer);
-	if (!rc) {
-		mutex_lock(&inst->lock);
-		mark_index_busy(&inst->free_output_indices, index);
-		mutex_unlock(&inst->lock);
-	}
-	return rc;
-
-}
-
-static long venc_encode_frame(struct v4l2_subdev *sd, void *arg)
-{
-	struct venc_inst *inst = NULL;
-	struct venc_buf_info *venc_buf = arg;
-	struct mem_region *mregion = NULL;
-	struct v4l2_buffer buffer = {0};
-	struct v4l2_plane plane = {0};
-	int index = 0, rc = 0;
-
-	if (!sd) {
-		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
-		return -EINVAL;
-	} else if (!venc_buf) {
-		WFD_MSG_ERR("Invalid output buffer ot fill\n");
-		return -EINVAL;
-	}
-
-	inst = (struct venc_inst *)sd->dev_priv;
-	mregion = venc_buf->mregion;
-
-	plane = (struct v4l2_plane) {
-		.length = mregion->size,
-		.m.userptr = (u32)mregion->paddr,
-		.bytesused = mregion->size,
-	};
-
-	while (true) {
-		mutex_lock(&inst->lock);
-		index = next_free_index(&inst->free_input_indices);
-		mutex_unlock(&inst->lock);
-
-		if (index < 0)
-			wait_for_completion(&inst->dq_complete);
-		else
-			break;
-	}
-
-	buffer = (struct v4l2_buffer) {
-		.index = index,
-		.type = BUF_TYPE_INPUT,
-		.timestamp = ns_to_timeval(venc_buf->timestamp),
-		.memory = V4L2_MEMORY_USERPTR,
-		.m.planes = &plane,
-		.length = 1,
-	};
-
-	WFD_MSG_DBG("Encode buffer %p with index, %d",
-		(void *)buffer.m.planes[0].m.userptr, buffer.index);
-	rc = msm_vidc_qbuf(inst->vidc_context, &buffer);
-	if (!rc) {
-		mutex_lock(&inst->lock);
-		mark_index_busy(&inst->free_input_indices, index);
-		mutex_unlock(&inst->lock);
-	}
-	return rc;
-}
-
-static long venc_alloc_recon_buffers(struct v4l2_subdev *sd, void *arg)
-{
-	/* vidc driver allocates internally on streamon */
-	return 0;
-}
-
-static long venc_free_buffer(struct venc_inst *inst, int type,
-		struct mem_region *to_free, bool unmap_user_buffer)
-{
-	struct mem_region *mregion = NULL;
-	struct mem_region *buf_list = NULL;
-
-	if (type == BUF_TYPE_OUTPUT) {
-		buf_list = &inst->registered_output_bufs;
-	} else if (type == BUF_TYPE_INPUT) {
-		buf_list = &inst->registered_input_bufs;
-	} else {
-		WFD_MSG_ERR("Trying to free a buffer of unknown type\n");
-		return -EINVAL;
-	}
-
-	mregion = get_registered_mregion(buf_list, to_free);
-
-	if (!mregion) {
-		WFD_MSG_ERR("Buffer not registered, cannot free\n");
-		return -ENOENT;
-	}
-
-	if (unmap_user_buffer) {
-		int rc = venc_unmap_user_to_kernel(inst, mregion);
-		if (rc)
-			WFD_MSG_WARN("Unable to unmap user buffer\n");
-	}
-
-	list_del(&mregion->list);
-	kfree(mregion);
-	return 0;
-}
-static long venc_free_output_buffer(struct v4l2_subdev *sd, void *arg)
-{
-	int rc = 0;
-	struct venc_inst *inst = NULL;
-
-	if (!sd) {
-		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
-		rc = -EINVAL;
-		goto venc_free_output_buffer_fail;
-	} else if (!arg) {
-		WFD_MSG_ERR("Invalid output buffer\n");
-		rc = -EINVAL;
-		goto venc_free_output_buffer_fail;
-	}
-
-	inst = (struct venc_inst *)sd->dev_priv;
-	return venc_free_buffer(inst, BUF_TYPE_OUTPUT, arg, true);
-venc_free_output_buffer_fail:
-	return rc;
-}
-
-static long venc_flush_buffers(struct v4l2_subdev *sd, void *arg)
-{
-	struct venc_inst *inst = NULL;
-	struct v4l2_encoder_cmd enc_cmd = {0};
-	int rc = 0;
-
-	if (!sd) {
-		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
-		rc = -EINVAL;
-		goto venc_flush_buffers_fail;
-	}
-
-	inst = (struct venc_inst *)sd->dev_priv;
-
-	enc_cmd.cmd = V4L2_ENC_QCOM_CMD_FLUSH;
-	enc_cmd.flags = V4L2_QCOM_CMD_FLUSH_OUTPUT |
-		V4L2_QCOM_CMD_FLUSH_CAPTURE;
-	msm_vidc_encoder_cmd(inst->vidc_context, &enc_cmd);
-
-	wait_for_completion(&inst->cmd_complete);
-venc_flush_buffers_fail:
-	return rc;
-}
-
-static long venc_free_input_buffer(struct v4l2_subdev *sd, void *arg)
-{
-	int rc = 0;
-	struct venc_inst *inst = NULL;
-
-	if (!sd) {
-		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
-		rc = -EINVAL;
-		goto venc_free_input_buffer_fail;
-	} else if (!arg) {
-		WFD_MSG_ERR("Invalid output buffer\n");
-		rc = -EINVAL;
-		goto venc_free_input_buffer_fail;
-	}
-
-	inst = (struct venc_inst *)sd->dev_priv;
-	return venc_free_buffer(inst, BUF_TYPE_INPUT, arg, false);
-venc_free_input_buffer_fail:
-	return rc;
-}
-
-static long venc_free_recon_buffers(struct v4l2_subdev *sd, void *arg)
-{
-	/* vidc driver takes care of this */
-	return 0;
-}
-
-static long venc_set_property(struct v4l2_subdev *sd, void *arg)
-{
-	struct venc_inst *inst = NULL;
-
-	if (!sd) {
-		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
-		return -EINVAL;
-	}
-
-	inst = (struct venc_inst *)sd->dev_priv;
-	return msm_vidc_s_ctrl(inst->vidc_context, (struct v4l2_control *)arg);
-}
-
-static long venc_get_property(struct v4l2_subdev *sd, void *arg)
-{
-	struct venc_inst *inst = NULL;
-
-	if (!sd) {
-		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
-		return -EINVAL;
-	}
-
-	inst = (struct venc_inst *)sd->dev_priv;
-	return msm_vidc_g_ctrl(inst->vidc_context, (struct v4l2_control *)arg);
-}
-
-long venc_mmap(struct v4l2_subdev *sd, void *arg)
-{
-	struct mem_region_map *mmap = arg;
-	struct mem_region *mregion = NULL;
-	unsigned long rc = 0, size = 0;
-	void *paddr = NULL;
-	struct venc_inst *inst = NULL;
-
-	if (!sd) {
-		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
-		return -EINVAL;
-	} else if (!mmap || !mmap->mregion) {
-		WFD_MSG_ERR("Memregion required for %s\n", __func__);
-		return -EINVAL;
-	}
-
-	inst = (struct venc_inst *)sd->dev_priv;
-	mregion = mmap->mregion;
-	if (mregion->size % SZ_4K != 0) {
-		WFD_MSG_ERR("Memregion not aligned to %d\n", SZ_4K);
-		return -EINVAL;
-	}
-
-	rc = ion_map_iommu(mmap->ion_client, mregion->ion_handle,
-			inst->domain, 0, SZ_4K, 0, (unsigned long *)&paddr,
-			&size, 0, 0);
-
-	if (rc) {
-		WFD_MSG_ERR("Failed to get physical addr\n");
-		paddr = NULL;
-	} else if (size < mregion->size) {
-		WFD_MSG_ERR("Failed to map enough memory\n");
-		rc = -ENOMEM;
-	}
-
-	mregion->paddr = paddr;
-	return rc;
-}
-
-long venc_munmap(struct v4l2_subdev *sd, void *arg)
-{
-	struct mem_region_map *mmap = arg;
-	struct mem_region *mregion = NULL;
-	struct venc_inst *inst = NULL;
-
-	if (!sd) {
-		WFD_MSG_ERR("Subdevice required for %s\n", __func__);
-		return -EINVAL;
-	} else if (!mmap || !mmap->mregion) {
-		WFD_MSG_ERR("Memregion required for %s\n", __func__);
-		return -EINVAL;
-	}
-
-	inst = (struct venc_inst *)sd->dev_priv;
-	mregion = mmap->mregion;
-
-	ion_unmap_iommu(mmap->ion_client, mregion->ion_handle,
-			inst->domain, 0);
-	return 0;
-}
-
-static long venc_set_framerate_mode(struct v4l2_subdev *sd,
-				void *arg)
-{
-	/* TODO: Unsupported for now, but return false success
-	 * to preserve binary compatibility for userspace apps
-	 * across targets */
-	return 0;
-}
-
-long venc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
-{
-	long rc = 0;
-	switch (cmd) {
-	case OPEN:
-		rc = venc_open(sd, arg);
-		break;
-	case CLOSE:
-		rc = venc_close(sd, arg);
-		break;
-	case ENCODE_START:
-		rc = venc_start(sd);
-		break;
-	case ENCODE_FRAME:
-		venc_encode_frame(sd, arg);
-		break;
-	case ENCODE_STOP:
-		rc = venc_stop(sd);
-		break;
-	case SET_PROP:
-		rc = venc_set_property(sd, arg);
-		break;
-	case GET_PROP:
-		rc = venc_get_property(sd, arg);
-		break;
-	case GET_BUFFER_REQ:
-		rc = venc_get_buffer_req(sd, arg);
-		break;
-	case SET_BUFFER_REQ:
-		rc = venc_set_buffer_req(sd, arg);
-		break;
-	case FREE_BUFFER:
-		break;
-	case FILL_OUTPUT_BUFFER:
-		rc = venc_fill_outbuf(sd, arg);
-		break;
-	case SET_FORMAT:
-		rc = venc_set_format(sd, arg);
-		break;
-	case SET_FRAMERATE:
-		rc = venc_set_framerate(sd, arg);
-		break;
-	case SET_INPUT_BUFFER:
-		rc = venc_set_input_buffer(sd, arg);
-		break;
-	case SET_OUTPUT_BUFFER:
-		rc = venc_set_output_buffer(sd, arg);
-		break;
-	case ALLOC_RECON_BUFFERS:
-		rc = venc_alloc_recon_buffers(sd, arg);
-		break;
-	case FREE_OUTPUT_BUFFER:
-		rc = venc_free_output_buffer(sd, arg);
-		break;
-	case FREE_INPUT_BUFFER:
-		rc = venc_free_input_buffer(sd, arg);
-		break;
-	case FREE_RECON_BUFFERS:
-		rc = venc_free_recon_buffers(sd, arg);
-		break;
-	case ENCODE_FLUSH:
-		rc = venc_flush_buffers(sd, arg);
-		break;
-	case ENC_MMAP:
-		rc = venc_mmap(sd, arg);
-		break;
-	case ENC_MUNMAP:
-		rc = venc_munmap(sd, arg);
-		break;
-	case SET_FRAMERATE_MODE:
-		rc = venc_set_framerate_mode(sd, arg);
-		break;
-	default:
-		WFD_MSG_ERR("Unknown ioctl %d to enc-subdev\n", cmd);
-		rc = -ENOTSUPP;
-		break;
-	}
-	return rc;
-}
diff --git a/drivers/media/video/msm_wfd/mdp-4-subdev.c b/drivers/media/video/msm_wfd/mdp-4-subdev.c
deleted file mode 100644
index c68d5d4..0000000
--- a/drivers/media/video/msm_wfd/mdp-4-subdev.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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/msm_mdp.h>
-#include <mach/iommu_domains.h>
-#include <media/videobuf2-core.h>
-#include "enc-subdev.h"
-#include "mdp-subdev.h"
-#include "wfd-util.h"
-
-struct mdp_instance {
-	struct fb_info *mdp;
-	u32 height;
-	u32 width;
-	bool secure;
-	bool uses_iommu_split_domain;
-};
-
-int mdp_init(struct v4l2_subdev *sd, u32 val)
-{
-	return 0;
-}
-
-int mdp_open(struct v4l2_subdev *sd, void *arg)
-{
-	struct mdp_instance *inst = kzalloc(sizeof(struct mdp_instance),
-					GFP_KERNEL);
-	struct mdp_msg_ops *mops = arg;
-	int rc = 0;
-	struct fb_info *fbi = NULL;
-
-	if (!inst) {
-		WFD_MSG_ERR("Out of memory\n");
-		rc = -ENOMEM;
-		goto mdp_open_fail;
-	} else if (!mops) {
-		WFD_MSG_ERR("Invalid arguments\n");
-		rc = -EINVAL;
-		goto mdp_open_fail;
-	}
-
-	fbi = msm_fb_get_writeback_fb();
-	if (!fbi) {
-		WFD_MSG_ERR("Failed to acquire mdp instance\n");
-		rc = -ENODEV;
-		goto mdp_open_fail;
-	}
-
-	/*Tell HDMI daemon to open fb2*/
-	rc = kobject_uevent(&fbi->dev->kobj, KOBJ_ADD);
-	if (rc) {
-		WFD_MSG_ERR("Failed add to kobj");
-		goto mdp_open_fail;
-	}
-
-	msm_fb_writeback_init(fbi);
-	inst->mdp = fbi;
-	inst->secure = mops->secure;
-	inst->uses_iommu_split_domain = mops->iommu_split_domain;
-
-	mops->cookie = inst;
-	return rc;
-mdp_open_fail:
-	kfree(inst);
-	return rc;
-}
-
-int mdp_start(struct v4l2_subdev *sd, void *arg)
-{
-	struct mdp_instance *inst = arg;
-	int rc = 0;
-	struct fb_info *fbi = NULL;
-	if (inst) {
-		rc = msm_fb_writeback_start(inst->mdp);
-		if (rc) {
-			WFD_MSG_ERR("Failed to start MDP mode\n");
-			goto exit;
-		}
-		fbi = msm_fb_get_writeback_fb();
-		if (!fbi) {
-			WFD_MSG_ERR("Failed to acquire mdp instance\n");
-			rc = -ENODEV;
-			goto exit;
-		}
-		rc = kobject_uevent(&fbi->dev->kobj, KOBJ_ONLINE);
-		if (rc)
-			WFD_MSG_ERR("Failed to send ONLINE event\n");
-	}
-exit:
-	return rc;
-}
-int mdp_stop(struct v4l2_subdev *sd, void *arg)
-{
-	struct mdp_instance *inst = arg;
-	int rc = 0;
-	struct fb_info *fbi = NULL;
-	if (inst) {
-		rc = msm_fb_writeback_stop(inst->mdp);
-		if (rc) {
-			WFD_MSG_ERR("Failed to stop writeback mode\n");
-			return rc;
-		}
-		fbi = (struct fb_info *)inst->mdp;
-		rc = kobject_uevent(&fbi->dev->kobj, KOBJ_OFFLINE);
-		if (rc) {
-			WFD_MSG_ERR("Failed to send offline event\n");
-			return -EIO;
-		}
-	}
-	return 0;
-}
-int mdp_close(struct v4l2_subdev *sd, void *arg)
-{
-	struct mdp_instance *inst = arg;
-	struct fb_info *fbi = NULL;
-	if (inst) {
-		fbi = (struct fb_info *)inst->mdp;
-		msm_fb_writeback_terminate(fbi);
-		kfree(inst);
-	}
-	return 0;
-}
-int mdp_q_buffer(struct v4l2_subdev *sd, void *arg)
-{
-	int rc = 0;
-	struct mdp_buf_info *binfo = arg;
-	struct msmfb_data fbdata;
-	struct mdp_instance *inst;
-	if (!binfo || !binfo->inst || !binfo->cookie) {
-		WFD_MSG_ERR("Invalid argument\n");
-		return -EINVAL;
-	}
-	inst = binfo->inst;
-	fbdata.offset = binfo->offset;
-	fbdata.memory_id = binfo->fd;
-	fbdata.iova = binfo->paddr;
-	fbdata.id = 0;
-	fbdata.flags = 0;
-	fbdata.priv = (uint32_t)binfo->cookie;
-
-	WFD_MSG_INFO("queue buffer to mdp with offset = %u, fd = %u, "\
-			"priv = %p, iova = %p\n",
-			fbdata.offset, fbdata.memory_id,
-			(void *)fbdata.priv, (void *)fbdata.iova);
-	rc = msm_fb_writeback_queue_buffer(inst->mdp, &fbdata);
-
-	if (rc)
-		WFD_MSG_ERR("Failed to queue buffer\n");
-	return rc;
-}
-int mdp_dq_buffer(struct v4l2_subdev *sd, void *arg)
-{
-	int rc = 0;
-	struct mdp_buf_info *obuf = arg;
-	struct msmfb_data fbdata;
-	struct mdp_instance *inst;
-	if (!arg) {
-		WFD_MSG_ERR("Invalid argument\n");
-		return -EINVAL;
-	}
-
-	inst = obuf->inst;
-	fbdata.flags = MSMFB_WRITEBACK_DEQUEUE_BLOCKING;
-	rc = msm_fb_writeback_dequeue_buffer(inst->mdp, &fbdata);
-	if (rc) {
-		WFD_MSG_ERR("Failed to dequeue buffer\n");
-		return rc;
-	}
-	WFD_MSG_DBG("dequeue buf from mdp with priv = %u\n",
-			fbdata.priv);
-	obuf->cookie = (void *)fbdata.priv;
-	return rc;
-}
-int mdp_set_prop(struct v4l2_subdev *sd, void *arg)
-{
-	struct mdp_prop *prop = (struct mdp_prop *)arg;
-	struct mdp_instance *inst = prop->inst;
-	if (!prop || !inst) {
-		WFD_MSG_ERR("Invalid arguments\n");
-		return -EINVAL;
-	}
-	inst->height = prop->height;
-	inst->width = prop->width;
-	return 0;
-}
-
-int mdp_mmap(struct v4l2_subdev *sd, void *arg)
-{
-	int rc = 0, domain = -1;
-	struct mem_region_map *mmap = arg;
-	struct mem_region *mregion;
-	bool use_iommu = true;
-	struct mdp_instance *inst = NULL;
-
-	if (!mmap || !mmap->mregion || !mmap->cookie) {
-		WFD_MSG_ERR("Invalid argument\n");
-		return -EINVAL;
-	}
-
-	inst = mmap->cookie;
-	mregion = mmap->mregion;
-	if (mregion->size % SZ_4K != 0) {
-		WFD_MSG_ERR("Memregion not aligned to %d\n", SZ_4K);
-		return -EINVAL;
-	}
-
-	if (inst->uses_iommu_split_domain) {
-		if (inst->secure)
-			use_iommu = false;
-		else
-			domain = DISPLAY_WRITE_DOMAIN;
-	} else {
-		domain = DISPLAY_READ_DOMAIN;
-	}
-
-	if (use_iommu) {
-		rc = ion_map_iommu(mmap->ion_client, mregion->ion_handle,
-				domain, GEN_POOL, SZ_4K, 0,
-				(unsigned long *)&mregion->paddr,
-				(unsigned long *)&mregion->size,
-				0, 0);
-	} else {
-		rc = ion_phys(mmap->ion_client,	mregion->ion_handle,
-				(unsigned long *)&mregion->paddr,
-				(size_t *)&mregion->size);
-	}
-
-	return rc;
-}
-
-int mdp_munmap(struct v4l2_subdev *sd, void *arg)
-{
-	struct mem_region_map *mmap = arg;
-	struct mem_region *mregion;
-	bool use_iommu = false;
-	int domain = -1;
-	struct mdp_instance *inst = NULL;
-
-	if (!mmap || !mmap->mregion || !mmap->cookie) {
-		WFD_MSG_ERR("Invalid argument\n");
-		return -EINVAL;
-	}
-
-	inst = mmap->cookie;
-	mregion = mmap->mregion;
-
-	if (inst->uses_iommu_split_domain) {
-		if (inst->secure)
-			use_iommu = false;
-		else
-			domain = DISPLAY_WRITE_DOMAIN;
-	} else {
-		domain = DISPLAY_READ_DOMAIN;
-	}
-
-	if (use_iommu)
-		ion_unmap_iommu(mmap->ion_client,
-				mregion->ion_handle,
-				domain, GEN_POOL);
-
-	return 0;
-}
-
-long mdp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
-{
-	int rc = 0;
-	if (!sd) {
-		WFD_MSG_ERR("Invalid arguments\n");
-		return -EINVAL;
-	}
-	switch (cmd) {
-	case MDP_Q_BUFFER:
-		rc = mdp_q_buffer(sd, arg);
-		break;
-	case MDP_DQ_BUFFER:
-		rc = mdp_dq_buffer(sd, arg);
-		break;
-	case MDP_OPEN:
-		rc = mdp_open(sd, arg);
-		break;
-	case MDP_START:
-		rc = mdp_start(sd, arg);
-		break;
-	case MDP_STOP:
-		rc = mdp_stop(sd, arg);
-		break;
-	case MDP_SET_PROP:
-		rc = mdp_set_prop(sd, arg);
-		break;
-	case MDP_CLOSE:
-		rc = mdp_close(sd, arg);
-		break;
-	case MDP_MMAP:
-		rc = mdp_mmap(sd, arg);
-		break;
-	case MDP_MUNMAP:
-		rc = mdp_munmap(sd, arg);
-		break;
-	default:
-		WFD_MSG_ERR("IOCTL: %u not supported\n", cmd);
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
diff --git a/drivers/media/video/msm_wfd/mdp-5-subdev.c b/drivers/media/video/msm_wfd/mdp-5-subdev.c
deleted file mode 100644
index 4f29389..0000000
--- a/drivers/media/video/msm_wfd/mdp-5-subdev.c
+++ /dev/null
@@ -1,286 +0,0 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License version 2 and
-* only version 2 as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-*/
-#include <linux/msm_mdp.h>
-#include <mach/iommu_domains.h>
-#include <media/videobuf2-core.h>
-#include "enc-subdev.h"
-#include "mdp-subdev.h"
-#include "wfd-util.h"
-
-
-struct mdp_instance {
-	struct fb_info *mdp;
-	u32 height;
-	u32 width;
-	bool secure;
-};
-
-int mdp_init(struct v4l2_subdev *sd, u32 val)
-{
-	return 0;
-}
-
-int mdp_open(struct v4l2_subdev *sd, void *arg)
-{
-	struct mdp_instance *inst = kzalloc(sizeof(struct mdp_instance),
-					GFP_KERNEL);
-	struct mdp_msg_ops *mops = arg;
-	int rc = 0;
-	struct fb_info *fbi = NULL;
-
-	if (!inst) {
-		WFD_MSG_ERR("Out of memory\n");
-		rc = -ENOMEM;
-		goto mdp_open_fail;
-	} else if (!mops) {
-		WFD_MSG_ERR("Invalid arguments\n");
-		rc = -EINVAL;
-		goto mdp_open_fail;
-	}
-
-	fbi = msm_fb_get_writeback_fb();
-	if (!fbi) {
-		WFD_MSG_ERR("Failed to acquire mdp instance\n");
-		rc = -ENODEV;
-		goto mdp_open_fail;
-	}
-
-	/*Tell HDMI daemon to open fb2*/
-	rc = kobject_uevent(&fbi->dev->kobj, KOBJ_ADD);
-	if (rc)
-		WFD_MSG_ERR("Failed add to kobj");
-
-	msm_fb_writeback_init(fbi);
-	inst->mdp = fbi;
-	inst->secure = mops->secure;
-
-	mops->cookie = inst;
-	return rc;
-mdp_open_fail:
-	kfree(inst);
-	return rc;
-}
-
-int mdp_start(struct v4l2_subdev *sd, void *arg)
-{
-	struct mdp_instance *inst = arg;
-	int rc = 0;
-	struct fb_info *fbi = NULL;
-	if (inst) {
-		rc = msm_fb_writeback_start(inst->mdp);
-		if (rc) {
-			WFD_MSG_ERR("Failed to start MDP mode\n");
-			goto exit;
-		}
-		fbi = msm_fb_get_writeback_fb();
-		if (!fbi) {
-			WFD_MSG_ERR("Failed to acquire mdp instance\n");
-			rc = -ENODEV;
-			goto exit;
-		}
-		rc = kobject_uevent(&fbi->dev->kobj, KOBJ_ONLINE);
-		if (rc)
-			WFD_MSG_ERR("Failed to send ONLINE event\n");
-	}
-exit:
-	return rc;
-}
-
-int mdp_stop(struct v4l2_subdev *sd, void *arg)
-{
-	struct mdp_instance *inst = arg;
-	int rc = 0;
-	struct fb_info *fbi = NULL;
-	if (inst) {
-		rc = msm_fb_writeback_stop(inst->mdp);
-		if (rc) {
-			WFD_MSG_ERR("Failed to stop writeback mode\n");
-			return rc;
-		}
-		fbi = (struct fb_info *)inst->mdp;
-		rc = kobject_uevent(&fbi->dev->kobj, KOBJ_OFFLINE);
-		if (rc) {
-			WFD_MSG_ERR("Failed to send offline event\n");
-			return -EIO;
-		}
-	}
-	return 0;
-}
-int mdp_close(struct v4l2_subdev *sd, void *arg)
-{
-	struct mdp_instance *inst = arg;
-	struct fb_info *fbi = NULL;
-	if (inst) {
-		fbi = (struct fb_info *)inst->mdp;
-		msm_fb_writeback_terminate(fbi);
-		kfree(inst);
-	}
-	return 0;
-}
-int mdp_q_buffer(struct v4l2_subdev *sd, void *arg)
-{
-	int rc = 0;
-	struct mdp_buf_info *binfo = arg;
-	struct msmfb_data fbdata;
-	struct mdp_instance *inst;
-	if (!binfo || !binfo->inst || !binfo->cookie) {
-		WFD_MSG_ERR("Invalid argument\n");
-		return -EINVAL;
-	}
-	inst = binfo->inst;
-	fbdata.offset = binfo->offset;
-	fbdata.memory_id = binfo->fd;
-	fbdata.iova = binfo->paddr;
-	fbdata.id = 0;
-	fbdata.flags = 0;
-	fbdata.priv = (uint32_t)binfo->cookie;
-
-	WFD_MSG_DBG("queue buffer to mdp with offset = %u, fd = %u, "\
-			"priv = %p, iova = %p\n",
-			fbdata.offset, fbdata.memory_id,
-			(void *)fbdata.priv, (void *)fbdata.iova);
-	rc = msm_fb_writeback_queue_buffer(inst->mdp, &fbdata);
-
-	if (rc)
-		WFD_MSG_ERR("Failed to queue buffer\n");
-	return rc;
-}
-int mdp_dq_buffer(struct v4l2_subdev *sd, void *arg)
-{
-	int rc = 0;
-	struct mdp_buf_info *obuf = arg;
-	struct msmfb_data fbdata;
-	struct mdp_instance *inst;
-	if (!arg) {
-		WFD_MSG_ERR("Invalid argument\n");
-		return -EINVAL;
-	}
-
-	inst = obuf->inst;
-	fbdata.flags = MSMFB_WRITEBACK_DEQUEUE_BLOCKING;
-	rc = msm_fb_writeback_dequeue_buffer(inst->mdp, &fbdata);
-	if (rc) {
-		WFD_MSG_ERR("Failed to dequeue buffer\n");
-		return rc;
-	}
-	WFD_MSG_DBG("dequeue buf from mdp with priv = %u\n",
-			fbdata.priv);
-	obuf->cookie = (void *)fbdata.priv;
-	return rc;
-}
-int mdp_set_prop(struct v4l2_subdev *sd, void *arg)
-{
-	struct mdp_prop *prop = (struct mdp_prop *)arg;
-	struct mdp_instance *inst = prop->inst;
-	if (!prop || !inst) {
-		WFD_MSG_ERR("Invalid arguments\n");
-		return -EINVAL;
-	}
-	inst->height = prop->height;
-	inst->width = prop->width;
-	return 0;
-}
-
-int mdp_mmap(struct v4l2_subdev *sd, void *arg)
-{
-	int rc = 0;
-	struct mem_region_map *mmap = arg;
-	struct mem_region *mregion;
-	bool domain = -1;
-	struct mdp_instance *inst = NULL;
-
-	if (!mmap || !mmap->mregion || !mmap->cookie) {
-		WFD_MSG_ERR("Invalid argument\n");
-		return -EINVAL;
-	}
-
-	inst = mmap->cookie;
-	mregion = mmap->mregion;
-	if (mregion->size % SZ_4K != 0) {
-		WFD_MSG_ERR("Memregion not aligned to %d\n", SZ_4K);
-		return -EINVAL;
-	}
-
-	domain = msm_fb_get_iommu_domain();
-	rc = ion_map_iommu(mmap->ion_client, mregion->ion_handle,
-			domain, 0, SZ_4K, 0,
-			(unsigned long *)&mregion->paddr,
-			(unsigned long *)&mregion->size,
-			0, 0);
-	return rc;
-}
-
-int mdp_munmap(struct v4l2_subdev *sd, void *arg)
-{
-	struct mem_region_map *mmap = arg;
-	struct mem_region *mregion;
-	bool domain = -1;
-	struct mdp_instance *inst = NULL;
-
-	if (!mmap || !mmap->mregion || !mmap->cookie) {
-		WFD_MSG_ERR("Invalid argument\n");
-		return -EINVAL;
-	}
-
-	inst = mmap->cookie;
-	mregion = mmap->mregion;
-
-	domain = msm_fb_get_iommu_domain();
-	ion_unmap_iommu(mmap->ion_client,
-			mregion->ion_handle,
-			domain, 0);
-	return 0;
-}
-
-long mdp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
-{
-	int rc = 0;
-	if (!sd) {
-		WFD_MSG_ERR("Invalid arguments\n");
-		return -EINVAL;
-	}
-	switch (cmd) {
-	case MDP_Q_BUFFER:
-		rc = mdp_q_buffer(sd, arg);
-		break;
-	case MDP_DQ_BUFFER:
-		rc = mdp_dq_buffer(sd, arg);
-		break;
-	case MDP_OPEN:
-		rc = mdp_open(sd, arg);
-		break;
-	case MDP_START:
-		rc = mdp_start(sd, arg);
-		break;
-	case MDP_STOP:
-		rc = mdp_stop(sd, arg);
-		break;
-	case MDP_SET_PROP:
-		rc = mdp_set_prop(sd, arg);
-		break;
-	case MDP_CLOSE:
-		rc = mdp_close(sd, arg);
-		break;
-	case MDP_MMAP:
-		rc = mdp_mmap(sd, arg);
-		break;
-	case MDP_MUNMAP:
-		rc = mdp_munmap(sd, arg);
-		break;
-	default:
-		WFD_MSG_ERR("IOCTL: %u not supported\n", cmd);
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
diff --git a/drivers/media/video/msm_wfd/mdp-dummy-subdev.c b/drivers/media/video/msm_wfd/mdp-dummy-subdev.c
deleted file mode 100644
index b2db208..0000000
--- a/drivers/media/video/msm_wfd/mdp-dummy-subdev.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License version 2 and
-* only version 2 as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-*/
-#include <linux/list.h>
-#include <linux/msm_mdp.h>
-#include <media/videobuf2-core.h>
-
-#include "enc-subdev.h"
-#include "mdp-subdev.h"
-#include "wfd-util.h"
-
-struct mdp_buf_queue {
-	struct mdp_buf_info mdp_buf_info;
-	struct list_head node;
-};
-
-struct mdp_instance {
-	struct mdp_buf_queue mdp_bufs;
-	struct mutex mutex;
-};
-
-int mdp_init(struct v4l2_subdev *sd, u32 val)
-{
-	return 0;
-}
-int mdp_open(struct v4l2_subdev *sd, void *arg)
-{
-	struct mdp_instance *inst = kzalloc(sizeof(struct mdp_instance),
-					GFP_KERNEL);
-	void **cookie = (void **)arg;
-	int rc = 0;
-
-	if (!inst) {
-		WFD_MSG_ERR("Out of memory\n");
-		return -ENOMEM;
-	}
-
-	INIT_LIST_HEAD(&inst->mdp_bufs.node);
-	mutex_init(&inst->mutex);
-	*cookie = inst;
-	return rc;
-}
-
-int mdp_start(struct v4l2_subdev *sd, void *arg)
-{
-	return 0;
-}
-int mdp_stop(struct v4l2_subdev *sd, void *arg)
-{
-	return 0;
-}
-int mdp_close(struct v4l2_subdev *sd, void *arg)
-{
-	return 0;
-}
-int mdp_q_buffer(struct v4l2_subdev *sd, void *arg)
-{
-	static int foo;
-	int rc = 0;
-	struct mdp_buf_info *binfo = arg;
-	struct mdp_instance *inst = NULL;
-
-	if (!binfo || !binfo->inst || !binfo->cookie) {
-		WFD_MSG_ERR("Invalid argument\n");
-		return -EINVAL;
-	}
-
-
-	inst = binfo->inst;
-	if (binfo->kvaddr) {
-		struct mdp_buf_queue *new_entry = kzalloc(sizeof(*new_entry),
-				GFP_KERNEL);
-		memset((void *)binfo->kvaddr, foo++, 1024);
-		new_entry->mdp_buf_info = *binfo;
-		mutex_lock(&inst->mutex);
-		list_add_tail(&new_entry->node, &inst->mdp_bufs.node);
-		mutex_unlock(&inst->mutex);
-		WFD_MSG_DBG("Queue %p with cookie %p\n",
-			(void *)binfo->paddr, (void *)binfo->cookie);
-	} else {
-		rc = -EINVAL;
-	}
-
-	return rc;
-}
-int mdp_dq_buffer(struct v4l2_subdev *sd, void *arg)
-{
-	struct mdp_buf_info *binfo = arg;
-	struct mdp_buf_queue *head = NULL;
-	struct mdp_instance *inst = NULL;
-
-	inst = binfo->inst;
-
-	while (head == NULL) {
-		mutex_lock(&inst->mutex);
-		if (!list_empty(&inst->mdp_bufs.node))
-			head = list_first_entry(&inst->mdp_bufs.node,
-					struct mdp_buf_queue, node);
-		mutex_unlock(&inst->mutex);
-	}
-
-	if (head == NULL)
-		return -ENOBUFS;
-
-	mutex_lock(&inst->mutex);
-	list_del(&head->node);
-	mutex_unlock(&inst->mutex);
-
-	*binfo = head->mdp_buf_info;
-	WFD_MSG_DBG("Dequeue %p with cookie %p\n",
-		(void *)binfo->paddr, (void *)binfo->cookie);
-	return 0;
-
-}
-int mdp_set_prop(struct v4l2_subdev *sd, void *arg)
-{
-	return 0;
-}
-
-int mdp_mmap(struct v4l2_subdev *sd, void *arg)
-{
-	int rc = 0;
-	struct mem_region_map *mmap = arg;
-	struct mem_region *mregion;
-
-	mregion = mmap->mregion;
-	mregion->paddr = mregion->kvaddr;
-	return rc;
-}
-
-int mdp_munmap(struct v4l2_subdev *sd, void *arg)
-{
-	/* Whatever */
-	return 0;
-}
-
-long mdp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
-{
-	int rc = 0;
-	if (!sd) {
-		WFD_MSG_ERR("Invalid arguments\n");
-		return -EINVAL;
-	}
-	switch (cmd) {
-	case MDP_Q_BUFFER:
-		rc = mdp_q_buffer(sd, arg);
-		break;
-	case MDP_DQ_BUFFER:
-		rc = mdp_dq_buffer(sd, arg);
-		break;
-	case MDP_OPEN:
-		rc = mdp_open(sd, arg);
-		break;
-	case MDP_START:
-		rc = mdp_start(sd, arg);
-		break;
-	case MDP_STOP:
-		rc = mdp_stop(sd, arg);
-		break;
-	case MDP_SET_PROP:
-		rc = mdp_set_prop(sd, arg);
-		break;
-	case MDP_CLOSE:
-		rc = mdp_close(sd, arg);
-		break;
-	case MDP_MMAP:
-		rc = mdp_mmap(sd, arg);
-		break;
-	case MDP_MUNMAP:
-		rc = mdp_munmap(sd, arg);
-		break;
-	default:
-		WFD_MSG_ERR("IOCTL: %u not supported\n", cmd);
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
diff --git a/drivers/media/video/msm_wfd/mdp-subdev.h b/drivers/media/video/msm_wfd/mdp-subdev.h
deleted file mode 100644
index 5e81e3c..0000000
--- a/drivers/media/video/msm_wfd/mdp-subdev.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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 _WFD_MDP_SUBDEV_
-#define _WFD_MDP_SUBDEV_
-
-#include <linux/videodev2.h>
-#include <media/v4l2-subdev.h>
-
-#define MDP_MAGIC_IOCTL 'M'
-
-struct mdp_buf_info {
-	void *inst;
-	void *cookie;
-	u32 fd;
-	u32 offset;
-	u32 kvaddr;
-	u32 paddr;
-};
-
-struct mdp_prop {
-	void *inst;
-	u32 height;
-	u32 width;
-};
-
-struct mdp_msg_ops {
-	void *cookie;
-	bool secure;
-	bool iommu_split_domain;
-};
-
-static inline bool mdp_buf_info_equals(struct mdp_buf_info *a,
-		struct mdp_buf_info *b)
-{
-	return a->inst == b->inst
-		&& a->fd == b->fd
-		&& a->offset == b->offset
-		&& a->kvaddr == b->kvaddr
-		&& a->paddr == b->paddr;
-}
-
-#define MDP_Q_BUFFER  _IOW(MDP_MAGIC_IOCTL, 1, struct mdp_buf_info *)
-#define MDP_DQ_BUFFER  _IOR(MDP_MAGIC_IOCTL, 2, struct mdp_out_buf *)
-#define MDP_OPEN  _IOR(MDP_MAGIC_IOCTL, 3, void **)
-#define MDP_SET_PROP  _IOW(MDP_MAGIC_IOCTL, 4, struct mdp_prop *)
-#define MDP_CLOSE  _IOR(MDP_MAGIC_IOCTL, 5, void *)
-#define MDP_START  _IOR(MDP_MAGIC_IOCTL, 6, void *)
-#define MDP_STOP  _IOR(MDP_MAGIC_IOCTL, 7, void *)
-#define MDP_MMAP  _IOR(MDP_MAGIC_IOCTL, 8, struct mem_region_map *)
-#define MDP_MUNMAP  _IOR(MDP_MAGIC_IOCTL, 9, struct mem_region_map *)
-
-
-extern int mdp_init(struct v4l2_subdev *sd, u32 val);
-extern long mdp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg);
-
-
-#endif /* _WFD_MDP_SUBDEV_ */
diff --git a/drivers/media/video/msm_wfd/vsg-subdev.c b/drivers/media/video/msm_wfd/vsg-subdev.c
deleted file mode 100644
index 73b840b..0000000
--- a/drivers/media/video/msm_wfd/vsg-subdev.c
+++ /dev/null
@@ -1,700 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/hrtimer.h>
-#include <linux/time.h>
-#include <linux/list.h>
-#include <media/videobuf2-core.h>
-#include "enc-subdev.h"
-#include "vsg-subdev.h"
-#include "wfd-util.h"
-
-#define DEFAULT_FRAME_INTERVAL (66*NSEC_PER_MSEC)
-#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
-
-static int vsg_release_input_buffer(struct vsg_context *context,
-		struct vsg_buf_info *buf)
-{
-	WFD_MSG_DBG("Releasing frame with ts %lld ms, paddr %p\n",
-			timespec_to_ns(&buf->time),
-			(void *)buf->mdp_buf_info.paddr);
-
-	if (buf->flags & VSG_NEVER_RELEASE)
-		WFD_MSG_WARN("Warning releasing buffer that's"
-				"not supposed to be released\n");
-
-	return context->vmops.release_input_frame(context->vmops.cbdata,
-			buf);
-
-}
-
-static int vsg_encode_frame(struct vsg_context *context,
-		struct vsg_buf_info *buf)
-{
-	WFD_MSG_DBG("Encoding frame with ts %lld ms, paddr %p\n",
-			timespec_to_ns(&buf->time),
-			(void *)buf->mdp_buf_info.paddr);
-
-	return context->vmops.encode_frame(context->vmops.cbdata,
-			buf);
-}
-
-static void vsg_set_last_buffer(struct vsg_context *context,
-		struct vsg_buf_info *buf)
-{
-	if (buf->flags & VSG_NEVER_SET_LAST_BUFFER)
-		WFD_MSG_WARN("Shouldn't be setting this to last buffer\n");
-
-	context->last_buffer = buf;
-
-	WFD_MSG_DBG("Setting last buffer to paddr %p\n",
-			(void *)buf->mdp_buf_info.paddr);
-}
-
-static void vsg_encode_helper_func(struct work_struct *task)
-{
-	struct vsg_encode_work *work =
-		container_of(task, struct vsg_encode_work, work);
-
-	/*
-	 * Note: don't need to lock for context below as we only
-	 * access fields that are "static".
-	 */
-	int rc = vsg_encode_frame(work->context, work->buf);
-	if (rc < 0) {
-		mutex_lock(&work->context->mutex);
-		work->context->state = VSG_STATE_ERROR;
-		mutex_unlock(&work->context->mutex);
-	}
-	kfree(work);
-}
-
-static void vsg_work_func(struct work_struct *task)
-{
-	struct vsg_work *work =
-		container_of(task, struct vsg_work, work);
-	struct vsg_encode_work *encode_work;
-	struct vsg_context *context = work->context;
-	struct vsg_buf_info *buf_info = NULL, *temp = NULL;
-	int rc = 0, count = 0;
-	mutex_lock(&context->mutex);
-
-	if (list_empty(&context->free_queue.node)) {
-		WFD_MSG_DBG("%s: queue empty doing nothing\n", __func__);
-		goto err_skip_encode;
-	} else if (context->state != VSG_STATE_STARTED) {
-		WFD_MSG_DBG("%s: vsg is stopped or in error state "
-				"doing nothing\n", __func__);
-		goto err_skip_encode;
-	}
-
-	list_for_each_entry(temp, &context->busy_queue.node, node) {
-		if (++count > MAX_BUFS_BUSY_WITH_ENC) {
-			WFD_MSG_WARN("Skipping encode, too many "
-				"buffers with encoder");
-			goto err_skip_encode;
-		}
-	}
-
-	buf_info = list_first_entry(&context->free_queue.node,
-			struct vsg_buf_info, node);
-	list_del(&buf_info->node);
-	INIT_LIST_HEAD(&buf_info->node);
-
-	ktime_get_ts(&buf_info->time);
-	hrtimer_forward_now(&context->threshold_timer, ns_to_ktime(
-				context->max_frame_interval));
-
-	temp = NULL;
-	list_for_each_entry(temp, &context->busy_queue.node, node) {
-		if (mdp_buf_info_equals(&temp->mdp_buf_info,
-					&buf_info->mdp_buf_info)) {
-			temp->flags |= VSG_NEVER_RELEASE;
-		}
-	}
-
-	if (context->last_buffer &&
-		mdp_buf_info_equals(&context->last_buffer->mdp_buf_info,
-			&buf_info->mdp_buf_info)) {
-		context->last_buffer->flags |= VSG_NEVER_RELEASE;
-	}
-
-	encode_work = kmalloc(sizeof(*encode_work), GFP_KERNEL);
-	encode_work->buf = buf_info;
-	encode_work->context = context;
-	INIT_WORK(&encode_work->work, vsg_encode_helper_func);
-	rc = queue_work(context->work_queue, &encode_work->work);
-	if (!rc) {
-		WFD_MSG_ERR("Queueing buffer for encode failed\n");
-		kfree(encode_work);
-		encode_work = NULL;
-		goto err_skip_encode;
-	}
-
-	buf_info->flags |= VSG_BUF_BEING_ENCODED;
-	if (!(buf_info->flags & VSG_NEVER_SET_LAST_BUFFER)) {
-		if (context->last_buffer) {
-			struct vsg_buf_info *old_last_buffer =
-				context->last_buffer;
-			bool last_buf_with_us = old_last_buffer &&
-				!(old_last_buffer->flags &
-					VSG_BUF_BEING_ENCODED);
-			bool can_release = old_last_buffer &&
-				!(old_last_buffer->flags &
-					VSG_NEVER_RELEASE);
-
-			if (old_last_buffer && last_buf_with_us
-				&& can_release) {
-				vsg_release_input_buffer(context,
-					old_last_buffer);
-				kfree(old_last_buffer);
-			}
-		}
-		vsg_set_last_buffer(context, buf_info);
-	}
-
-	list_add_tail(&buf_info->node, &context->busy_queue.node);
-err_skip_encode:
-	mutex_unlock(&context->mutex);
-	kfree(work);
-}
-
-static void vsg_timer_helper_func(struct work_struct *task)
-{
-	struct vsg_work *work =
-		container_of(task, struct vsg_work, work);
-	struct vsg_work *new_work = NULL;
-	struct vsg_context *context = work->context;
-	int num_bufs_to_queue = 1, c = 0;
-
-	mutex_lock(&context->mutex);
-
-	if (context->state != VSG_STATE_STARTED)
-		goto err_locked;
-
-	if (list_empty(&context->free_queue.node)
-		&& context->last_buffer) {
-		struct vsg_buf_info *info = NULL, *buf_to_encode = NULL;
-
-		if (context->mode == VSG_MODE_CFR)
-			num_bufs_to_queue = 1;
-		else if (context->mode == VSG_MODE_VFR)
-			num_bufs_to_queue = 2;
-
-		for (c = 0; c < num_bufs_to_queue; ++c) {
-			info = kzalloc(sizeof(*info), GFP_KERNEL);
-
-			if (!info) {
-				WFD_MSG_ERR("Couldn't allocate memory in %s\n",
-					__func__);
-				goto err_locked;
-			}
-
-			buf_to_encode = context->last_buffer;
-
-			info->mdp_buf_info = buf_to_encode->mdp_buf_info;
-			info->flags = 0;
-			INIT_LIST_HEAD(&info->node);
-
-			list_add_tail(&info->node, &context->free_queue.node);
-			WFD_MSG_DBG("Regenerated frame with paddr %p\n",
-				(void *)info->mdp_buf_info.paddr);
-		}
-	}
-
-	for (c = 0; c < num_bufs_to_queue; ++c) {
-		new_work = kzalloc(sizeof(*new_work), GFP_KERNEL);
-		if (!new_work) {
-			WFD_MSG_ERR("Unable to allocate memory"
-					"to queue buffer\n");
-			goto err_locked;
-		}
-
-		INIT_WORK(&new_work->work, vsg_work_func);
-		new_work->context = context;
-		queue_work(context->work_queue, &new_work->work);
-	}
-
-err_locked:
-	mutex_unlock(&context->mutex);
-	kfree(work);
-}
-
-static enum hrtimer_restart vsg_threshold_timeout_func(struct hrtimer *timer)
-{
-	struct vsg_context *context = NULL;
-	struct vsg_work *task = NULL;
-
-	task = kzalloc(sizeof(*task), GFP_ATOMIC);
-	context = container_of(timer, struct vsg_context,
-			threshold_timer);
-	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;
-
-	queue_work(context->work_queue, &task->work);
-threshold_err_bad_param:
-	hrtimer_forward_now(&context->threshold_timer, ns_to_ktime(
-				context->max_frame_interval));
-	return HRTIMER_RESTART;
-threshold_err_no_context:
-	return HRTIMER_NORESTART;
-}
-
-int vsg_init(struct v4l2_subdev *sd, u32 val)
-{
-	return 0;
-}
-
-static int vsg_open(struct v4l2_subdev *sd, void *arg)
-{
-	struct vsg_context *context = NULL;
-
-	if (!arg || !sd)
-		return -EINVAL;
-
-	context = kzalloc(sizeof(*context), GFP_KERNEL);
-	INIT_LIST_HEAD(&context->free_queue.node);
-	INIT_LIST_HEAD(&context->busy_queue.node);
-
-	context->vmops = *(struct vsg_msg_ops *)arg;
-	context->work_queue = create_singlethread_workqueue("v4l-vsg");
-
-	context->frame_interval = DEFAULT_FRAME_INTERVAL;
-	context->max_frame_interval = DEFAULT_MAX_FRAME_INTERVAL;
-
-	hrtimer_init(&context->threshold_timer, CLOCK_MONOTONIC,
-			HRTIMER_MODE_REL);
-	context->threshold_timer.function = vsg_threshold_timeout_func;
-
-	context->last_buffer = NULL;
-	context->mode = DEFAULT_MODE;
-	context->state = VSG_STATE_NONE;
-	mutex_init(&context->mutex);
-
-	sd->dev_priv = context;
-	return 0;
-}
-
-static int vsg_close(struct v4l2_subdev *sd)
-{
-	struct vsg_context *context = NULL;
-
-	if (!sd)
-		return -EINVAL;
-
-	context = (struct vsg_context *)sd->dev_priv;
-	destroy_workqueue(context->work_queue);
-	kfree(context);
-	return 0;
-}
-
-static int vsg_start(struct v4l2_subdev *sd)
-{
-	struct vsg_context *context = NULL;
-
-	if (!sd) {
-		WFD_MSG_ERR("ERROR, invalid arguments into %s\n", __func__);
-		return -EINVAL;
-	}
-
-	context = (struct vsg_context *)sd->dev_priv;
-
-	if (context->state == VSG_STATE_STARTED) {
-		WFD_MSG_ERR("VSG not stopped, start not allowed\n");
-		return -EINPROGRESS;
-	} else if (context->state == VSG_STATE_ERROR) {
-		WFD_MSG_ERR("VSG in error state, not allowed to restart\n");
-		return -ENOTRECOVERABLE;
-	}
-
-	context->state = VSG_STATE_STARTED;
-	hrtimer_start(&context->threshold_timer, ns_to_ktime(context->
-			max_frame_interval), HRTIMER_MODE_REL);
-	return 0;
-}
-
-static int vsg_stop(struct v4l2_subdev *sd)
-{
-	struct vsg_context *context = NULL;
-
-	if (!sd) {
-		WFD_MSG_ERR("ERROR, invalid arguments into %s\n", __func__);
-		return -EINVAL;
-	}
-
-	context = (struct vsg_context *)sd->dev_priv;
-
-	mutex_lock(&context->mutex);
-	context->state = VSG_STATE_STOPPED;
-	{ /*delete pending buffers as we're not going to encode them*/
-		struct list_head *pos, *next;
-		list_for_each_safe(pos, next, &context->free_queue.node) {
-			struct vsg_buf_info *temp =
-				list_entry(pos, struct vsg_buf_info, node);
-			list_del(&temp->node);
-			kfree(temp);
-		}
-	}
-
-	hrtimer_cancel(&context->threshold_timer);
-
-	mutex_unlock(&context->mutex);
-
-	flush_workqueue(context->work_queue);
-	return 0;
-}
-
-static long vsg_queue_buffer(struct v4l2_subdev *sd, void *arg)
-{
-	struct vsg_context *context = NULL;
-	struct vsg_buf_info *buf_info = kzalloc(sizeof(*buf_info), GFP_KERNEL);
-	int rc = 0;
-	bool push = false;
-
-	if (!arg || !sd) {
-		WFD_MSG_ERR("ERROR, invalid arguments into %s\n", __func__);
-		rc = -EINVAL;
-		goto queue_err_bad_param;
-	} else if (!buf_info) {
-		WFD_MSG_ERR("ERROR, out of memory in %s\n", __func__);
-		rc = -ENOMEM;
-		goto queue_err_bad_param;
-	}
-
-	context = (struct vsg_context *)sd->dev_priv;
-	mutex_lock(&context->mutex);
-
-	*buf_info = *(struct vsg_buf_info *)arg;
-	INIT_LIST_HEAD(&buf_info->node);
-	buf_info->flags = 0;
-	ktime_get_ts(&buf_info->time);
-
-	WFD_MSG_DBG("Queue frame with paddr %p\n",
-			(void *)buf_info->mdp_buf_info.paddr);
-
-	{ /*return pending buffers as we're not going to encode them*/
-		struct list_head *pos, *next;
-		list_for_each_safe(pos, next, &context->free_queue.node) {
-			struct vsg_buf_info *temp =
-				list_entry(pos, struct vsg_buf_info, node);
-			bool is_last_buffer = context->last_buffer &&
-				mdp_buf_info_equals(
-					&context->last_buffer->mdp_buf_info,
-					&temp->mdp_buf_info);
-
-			list_del(&temp->node);
-
-			if (!is_last_buffer &&
-				!(temp->flags & VSG_NEVER_RELEASE)) {
-				vsg_release_input_buffer(context, temp);
-				kfree(temp);
-			}
-		}
-	}
-
-	list_add_tail(&buf_info->node, &context->free_queue.node);
-
-	if (context->mode == VSG_MODE_VFR) {
-		if (!context->last_buffer)
-			push = true;
-		else {
-			struct timespec diff = timespec_sub(buf_info->time,
-					context->last_buffer->time);
-			struct timespec temp = ns_to_timespec(
-						context->frame_interval);
-
-			if (timespec_compare(&diff, &temp) >= 0)
-				push = true;
-		}
-	} else if (context->mode == VSG_MODE_CFR) {
-		if (!context->last_buffer) {
-			push = true;
-			/*
-			 * We need to reset the timer after pushing the buffer
-			 * otherwise, diff between two consecutive frames might
-			 * be less than max_frame_interval (for just one sample)
-			 */
-			hrtimer_forward_now(&context->threshold_timer,
-				ns_to_ktime(context->max_frame_interval));
-		}
-	}
-
-	if (push) {
-		struct vsg_work *new_work =
-			kzalloc(sizeof(*new_work), GFP_KERNEL);
-
-		INIT_WORK(&new_work->work, vsg_work_func);
-		new_work->context = context;
-		queue_work(context->work_queue, &new_work->work);
-	}
-
-	mutex_unlock(&context->mutex);
-queue_err_bad_param:
-	if (rc < 0)
-		kfree(buf_info);
-
-	return rc;
-}
-
-static long vsg_return_ip_buffer(struct v4l2_subdev *sd, void *arg)
-{
-	struct vsg_context *context = NULL;
-	struct vsg_buf_info *buf_info, *last_buffer,
-			*expected_buffer;
-	int rc = 0;
-
-	if (!arg || !sd) {
-		WFD_MSG_ERR("ERROR, invalid arguments into %s\n", __func__);
-		rc = -EINVAL;
-		goto return_ip_buf_err_bad_param;
-	}
-
-	context = (struct vsg_context *)sd->dev_priv;
-	mutex_lock(&context->mutex);
-	buf_info = (struct vsg_buf_info *)arg;
-	last_buffer = context->last_buffer;
-
-	expected_buffer = list_first_entry(&context->busy_queue.node,
-			struct vsg_buf_info, node);
-
-	WFD_MSG_DBG("Return frame with paddr %p\n",
-			(void *)buf_info->mdp_buf_info.paddr);
-
-	if (!expected_buffer) {
-		WFD_MSG_ERR("Unexpectedly received buffer from enc with "
-			"paddr %p\n", (void *)buf_info->mdp_buf_info.paddr);
-		goto return_ip_buf_bad_buf;
-	}
-
-	expected_buffer->flags &= ~VSG_BUF_BEING_ENCODED;
-	if (mdp_buf_info_equals(&expected_buffer->mdp_buf_info,
-				&buf_info->mdp_buf_info)) {
-		bool is_same_buffer = context->last_buffer &&
-			mdp_buf_info_equals(
-					&context->last_buffer->mdp_buf_info,
-					&expected_buffer->mdp_buf_info);
-
-		list_del(&expected_buffer->node);
-		if (!is_same_buffer &&
-			!(expected_buffer->flags & VSG_NEVER_RELEASE)) {
-			vsg_release_input_buffer(context, expected_buffer);
-			kfree(expected_buffer);
-		}
-	} else {
-		WFD_MSG_ERR("Returned buffer %p is not latest buffer, "
-				"expected %p\n",
-				(void *)buf_info->mdp_buf_info.paddr,
-				(void *)expected_buffer->mdp_buf_info.paddr);
-		rc = -EINVAL;
-		goto return_ip_buf_bad_buf;
-	}
-
-return_ip_buf_bad_buf:
-	mutex_unlock(&context->mutex);
-return_ip_buf_err_bad_param:
-	return rc;
-}
-
-static long vsg_set_frame_interval(struct v4l2_subdev *sd, void *arg)
-{
-	struct vsg_context *context = NULL;
-	int64_t interval;
-
-	if (!arg || !sd) {
-		WFD_MSG_ERR("ERROR, invalid arguments into %s\n", __func__);
-		return -EINVAL;
-	}
-
-	context = (struct vsg_context *)sd->dev_priv;
-	interval = *(int64_t *)arg;
-
-	if (interval <= 0) {
-		WFD_MSG_ERR("ERROR, invalid interval %lld into %s\n",
-				interval, __func__);
-		return -EINVAL;
-	}
-
-	mutex_lock(&context->mutex);
-
-	context->frame_interval = interval;
-	if (interval > context->max_frame_interval) {
-		WFD_MSG_WARN("Changing max frame interval from %lld to %lld\n",
-				context->max_frame_interval, interval);
-		context->max_frame_interval = interval;
-	}
-
-	mutex_unlock(&context->mutex);
-	return 0;
-}
-
-static long vsg_get_frame_interval(struct v4l2_subdev *sd, void *arg)
-{
-	struct vsg_context *context = NULL;
-
-	if (!arg || !sd) {
-		WFD_MSG_ERR("ERROR, invalid arguments into %s\n", __func__);
-		return -EINVAL;
-	}
-
-	context = (struct vsg_context *)sd->dev_priv;
-	mutex_lock(&context->mutex);
-	*(int64_t *)arg = context->frame_interval;
-	mutex_unlock(&context->mutex);
-
-	return 0;
-}
-
-static long vsg_set_max_frame_interval(struct v4l2_subdev *sd, void *arg)
-{
-	struct vsg_context *context = NULL;
-	int64_t interval;
-
-	if (!arg || !sd) {
-		WFD_MSG_ERR("ERROR, invalid arguments into %s\n", __func__);
-		return -EINVAL;
-	}
-
-	context = (struct vsg_context *)sd->dev_priv;
-	interval = *(int64_t *)arg;
-
-	if (interval <= 0) {
-		WFD_MSG_ERR("ERROR, invalid interval %lld into %s\n",
-				interval, __func__);
-		return -EINVAL;
-	}
-
-	mutex_lock(&context->mutex);
-
-	context->max_frame_interval = interval;
-	if (interval < context->frame_interval) {
-		WFD_MSG_WARN("Changing frame interval from %lld to %lld\n",
-				context->frame_interval, interval);
-		context->frame_interval = interval;
-	}
-
-	mutex_unlock(&context->mutex);
-
-	return 0;
-}
-
-static long vsg_get_max_frame_interval(struct v4l2_subdev *sd, void *arg)
-{
-	struct vsg_context *context = NULL;
-
-	if (!arg || !sd) {
-		WFD_MSG_ERR("ERROR, invalid arguments into %s\n", __func__);
-		return -EINVAL;
-	}
-
-	context = (struct vsg_context *)sd->dev_priv;
-	mutex_lock(&context->mutex);
-	*(int64_t *)arg = context->max_frame_interval;
-	mutex_unlock(&context->mutex);
-
-	return 0;
-}
-
-static long vsg_set_mode(struct v4l2_subdev *sd, void *arg)
-{
-	struct vsg_context *context = NULL;
-	enum vsg_modes *mode = NULL;
-	int rc = 0;
-
-	if (!arg || !sd) {
-		WFD_MSG_ERR("ERROR, invalid arguments into %s\n", __func__);
-		rc = -EINVAL;
-		goto set_mode_err_bad_parm;
-	}
-
-	context = (struct vsg_context *)sd->dev_priv;
-	mutex_lock(&context->mutex);
-	mode = arg;
-
-	switch (*mode) {
-	case VSG_MODE_CFR:
-		context->max_frame_interval = context->frame_interval;
-		/*fall through*/
-	case VSG_MODE_VFR:
-		context->mode = *mode;
-		break;
-	default:
-		context->mode = DEFAULT_MODE;
-		rc = -EINVAL;
-		goto set_mode_err_bad_mode;
-		break;
-	}
-
-set_mode_err_bad_mode:
-	mutex_unlock(&context->mutex);
-set_mode_err_bad_parm:
-	return rc;
-}
-
-long vsg_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
-{
-	int rc = 0;
-
-	WFD_MSG_DBG("VSG ioctl: %d\n", cmd);
-	if (sd == NULL)
-		return -EINVAL;
-
-	switch (cmd) {
-	case VSG_OPEN:
-		rc = vsg_open(sd, arg);
-		break;
-	case VSG_CLOSE:
-		rc = vsg_close(sd);
-		break;
-	case VSG_START:
-		rc = vsg_start(sd);
-		break;
-	case VSG_STOP:
-		rc = vsg_stop(sd);
-		break;
-	case VSG_Q_BUFFER:
-		rc = vsg_queue_buffer(sd, arg);
-		break;
-	case VSG_RETURN_IP_BUFFER:
-		rc = vsg_return_ip_buffer(sd, arg);
-		break;
-	case VSG_GET_FRAME_INTERVAL:
-		rc = vsg_get_frame_interval(sd, arg);
-		break;
-	case VSG_SET_FRAME_INTERVAL:
-		rc = vsg_set_frame_interval(sd, arg);
-		break;
-	case VSG_GET_MAX_FRAME_INTERVAL:
-		rc = vsg_get_max_frame_interval(sd, arg);
-		break;
-	case VSG_SET_MAX_FRAME_INTERVAL:
-		rc = vsg_set_max_frame_interval(sd, arg);
-		break;
-	case VSG_SET_MODE:
-		rc = vsg_set_mode(sd, arg);
-		break;
-	default:
-		rc = -ENOTSUPP;
-		break;
-	}
-
-	return rc;
-}
diff --git a/drivers/media/video/msm_wfd/vsg-subdev.h b/drivers/media/video/msm_wfd/vsg-subdev.h
deleted file mode 100644
index dfc2e2e..0000000
--- a/drivers/media/video/msm_wfd/vsg-subdev.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 _WFD_VSG_SUBDEV_
-#define _WFD_VSG_SUBDEV_
-
-#include <linux/videodev2.h>
-#include <linux/list.h>
-#include <linux/ktime.h>
-#include <linux/workqueue.h>
-#include <media/v4l2-subdev.h>
-#include "mdp-subdev.h"
-
-#define VSG_MAGIC_IOCTL 'V'
-
-enum vsg_flags {
-	VSG_NEVER_RELEASE = 1<<0,
-	VSG_NEVER_SET_LAST_BUFFER = 1<<1,
-	VSG_BUF_BEING_ENCODED = 1<<2,
-};
-
-enum vsg_modes {
-	VSG_MODE_CFR,
-	VSG_MODE_VFR,
-};
-
-enum vsg_states {
-	VSG_STATE_NONE,
-	VSG_STATE_STARTED,
-	VSG_STATE_STOPPED,
-	VSG_STATE_ERROR
-};
-
-struct vsg_buf_info {
-	struct mdp_buf_info mdp_buf_info;
-	struct timespec time;
-	/* Internal */
-	struct list_head node;
-	uint32_t flags;
-};
-
-struct vsg_msg_ops {
-	void *cbdata;
-	int (*encode_frame)(void *cbdata, struct vsg_buf_info *buffer);
-	int (*release_input_frame)(void *cbdata, struct vsg_buf_info *buffer);
-};
-
-struct vsg_context {
-	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;
-	struct workqueue_struct *work_queue;
-	struct hrtimer threshold_timer;
-	struct mutex mutex;
-	struct vsg_buf_info *last_buffer;
-	int mode;
-	int state;
-};
-
-struct vsg_work {
-	struct vsg_context *context;
-	struct work_struct work;
-};
-
-struct vsg_encode_work {
-	struct vsg_buf_info *buf;
-	struct vsg_context *context;
-	struct work_struct work;
-};
-
-#define VSG_OPEN  _IO(VSG_MAGIC_IOCTL, 1)
-#define VSG_CLOSE  _IO(VSG_MAGIC_IOCTL, 2)
-#define VSG_START  _IO(VSG_MAGIC_IOCTL, 3)
-#define VSG_STOP  _IO(VSG_MAGIC_IOCTL, 4)
-#define VSG_Q_BUFFER  _IOW(VSG_MAGIC_IOCTL, 5, struct vsg_buf_info *)
-#define VSG_DQ_BUFFER  _IOR(VSG_MAGIC_IOCTL, 6, struct vsg_out_buf *)
-#define VSG_RETURN_IP_BUFFER _IOW(VSG_MAGIC_IOCTL, 7, struct vsg_buf_info *)
-#define VSG_ENCODE_DONE _IO(VSG_MAGIC_IOCTL, 8)
-/* Time related arguments for frame interval ioctls are always in nanosecs*/
-#define VSG_SET_FRAME_INTERVAL _IOW(VSG_MAGIC_IOCTL, 9, int64_t *)
-#define VSG_GET_FRAME_INTERVAL _IOR(VSG_MAGIC_IOCTL, 10, int64_t *)
-#define VSG_SET_MAX_FRAME_INTERVAL _IOW(VSG_MAGIC_IOCTL, 11, int64_t *)
-#define VSG_GET_MAX_FRAME_INTERVAL _IOR(VSG_MAGIC_IOCTL, 12, int64_t *)
-#define VSG_SET_MODE _IOW(VSG_MAGIC_IOCTL, 13, enum vsg_modes *)
-
-extern int vsg_init(struct v4l2_subdev *sd, u32 val);
-extern long vsg_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg);
-
-#endif /* _WFD_VSG_SUBDEV_ */
diff --git a/drivers/media/video/msm_wfd/wfd-ioctl.c b/drivers/media/video/msm_wfd/wfd-ioctl.c
deleted file mode 100644
index 74194ff..0000000
--- a/drivers/media/video/msm_wfd/wfd-ioctl.c
+++ /dev/null
@@ -1,1685 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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/types.h>
-#include <linux/list.h>
-#include <linux/ioctl.h>
-#include <linux/spinlock.h>
-#include <linux/init.h>
-#include <linux/version.h>
-#include <linux/platform_device.h>
-#include <linux/android_pmem.h>
-#include <linux/sched.h>
-#include <linux/kthread.h>
-#include <linux/time.h>
-#include <mach/board.h>
-
-#include <media/v4l2-dev.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-#include <media/videobuf2-core.h>
-#include <media/videobuf2-msm-mem.h>
-#include "wfd-util.h"
-#include "mdp-subdev.h"
-#include "enc-subdev.h"
-#include "vsg-subdev.h"
-
-#define WFD_VERSION KERNEL_VERSION(0, 0, 1)
-#define WFD_NUM_DEVICES 2
-#define WFD_DEVICE_NUMBER_BASE 38
-#define WFD_DEVICE_SECURE (WFD_DEVICE_NUMBER_BASE + 1)
-#define DEFAULT_WFD_WIDTH 1280
-#define DEFAULT_WFD_HEIGHT 720
-#define VENC_INPUT_BUFFERS 4
-
-struct wfd_device {
-	struct mutex dev_lock;
-	struct platform_device *pdev;
-	struct v4l2_device v4l2_dev;
-	struct video_device *pvdev;
-	struct v4l2_subdev mdp_sdev;
-	struct v4l2_subdev enc_sdev;
-	struct v4l2_subdev vsg_sdev;
-	struct ion_client *ion_client;
-	bool secure_device;
-	bool in_use;
-	bool mdp_iommu_split_domain;
-};
-
-struct mem_info {
-	u32 fd;
-	u32 offset;
-};
-
-struct mem_info_entry {
-	struct list_head list;
-	unsigned long userptr;
-	struct mem_info minfo;
-};
-
-struct mem_region_pair {
-	struct mem_region *enc;
-	struct mem_region *mdp;
-	struct list_head list;
-};
-
-struct wfd_inst {
-	struct vb2_queue vid_bufq;
-	spinlock_t inst_lock;
-	u32 buf_count;
-	struct task_struct *mdp_task;
-	void *mdp_inst;
-	void *venc_inst;
-	u32 height;
-	u32 width;
-	u32 pixelformat;
-	struct list_head minfo_list;
-	bool streamoff;
-	u32 input_bufs_allocated;
-	u32 input_buf_size;
-	u32 out_buf_size;
-	struct list_head input_mem_list;
-	struct wfd_stats stats;
-	struct completion stop_mdp_thread;
-};
-
-struct wfd_vid_buffer {
-	struct vb2_buffer    vidbuf;
-};
-
-static int wfd_vidbuf_queue_setup(struct vb2_queue *q,
-				   const struct v4l2_format *fmt,
-				   unsigned int *num_buffers,
-				   unsigned int *num_planes,
-				   unsigned int sizes[], void *alloc_ctxs[])
-{
-	struct file *priv_data = (struct file *)(q->drv_priv);
-	struct wfd_inst *inst = (struct wfd_inst *)priv_data->private_data;
-	unsigned long flags;
-	int i;
-
-	WFD_MSG_DBG("In %s\n", __func__);
-	if (num_buffers == NULL || num_planes == NULL)
-		return -EINVAL;
-
-	*num_planes = 1;
-	spin_lock_irqsave(&inst->inst_lock, flags);
-	for (i = 0; i < *num_planes; ++i) {
-		sizes[i] = inst->out_buf_size;
-		alloc_ctxs[i] = inst;
-	}
-	spin_unlock_irqrestore(&inst->inst_lock, flags);
-
-	return 0;
-}
-
-void wfd_vidbuf_wait_prepare(struct vb2_queue *q)
-{
-}
-void wfd_vidbuf_wait_finish(struct vb2_queue *q)
-{
-}
-
-static unsigned long wfd_enc_addr_to_mdp_addr(struct wfd_inst *inst,
-		unsigned long addr)
-{
-	struct list_head *ptr, *next;
-	struct mem_region_pair *mpair;
-	if (!list_empty(&inst->input_mem_list)) {
-		list_for_each_safe(ptr, next,
-				&inst->input_mem_list) {
-			mpair = list_entry(ptr, struct mem_region_pair,
-					list);
-			if (mpair->enc->paddr == (u8 *)addr)
-				return (unsigned long)mpair->mdp->paddr;
-		}
-	}
-
-	return (unsigned long)NULL;
-}
-
-static int wfd_allocate_ion_buffer(struct ion_client *client,
-		bool secure, struct mem_region *mregion)
-{
-	struct ion_handle *handle = NULL;
-	void *kvaddr = NULL;
-	unsigned int alloc_regions = 0;
-	unsigned int ion_flags = 0;
-	int rc = 0;
-
-	alloc_regions = ION_HEAP(ION_CP_MM_HEAP_ID);
-	alloc_regions |= secure ? 0 :
-				ION_HEAP(ION_IOMMU_HEAP_ID);
-	ion_flags |= secure ? ION_SECURE : 0;
-	handle = ion_alloc(client,
-			mregion->size, SZ_4K, alloc_regions, ion_flags);
-
-	if (IS_ERR_OR_NULL(handle)) {
-		WFD_MSG_ERR("Failed to allocate input buffer\n");
-		rc = PTR_ERR(handle);
-		goto alloc_fail;
-	}
-
-	kvaddr = ion_map_kernel(client, handle);
-
-	if (IS_ERR_OR_NULL(kvaddr)) {
-		WFD_MSG_ERR("Failed to get virtual addr\n");
-		rc = PTR_ERR(kvaddr);
-		goto alloc_fail;
-	}
-
-	mregion->kvaddr = kvaddr;
-	mregion->ion_handle = handle;
-
-	return rc;
-alloc_fail:
-	if (!IS_ERR_OR_NULL(handle)) {
-		if (!IS_ERR_OR_NULL(kvaddr))
-			ion_unmap_kernel(client, handle);
-
-		ion_free(client, handle);
-
-		mregion->kvaddr = NULL;
-		mregion->paddr = NULL;
-		mregion->ion_handle = NULL;
-	}
-	return rc;
-}
-
-/* Doesn't do iommu unmap */
-static int wfd_free_ion_buffer(struct ion_client *client,
-		struct mem_region *mregion)
-{
-	if (!client || !mregion) {
-		WFD_MSG_ERR("Failed to free ion buffer: "
-				"Invalid client or region");
-		return -EINVAL;
-	}
-	ion_unmap_kernel(client, mregion->ion_handle);
-	ion_free(client, mregion->ion_handle);
-	return 0;
-}
-
-static int wfd_flush_ion_buffer(struct ion_client *client,
-		struct mem_region *mregion)
-{
-	if (!client || !mregion) {
-		WFD_MSG_ERR("Failed to flush ion buffer: "
-				"Invalid client or region");
-		return -EINVAL;
-	} else if (!mregion->ion_handle) {
-		WFD_MSG_ERR("Failed to flush ion buffer: "
-				"not an ion buffer");
-		return -EINVAL;
-	}
-
-	return msm_ion_do_cache_op(client,
-			mregion->ion_handle,
-			mregion->kvaddr,
-			mregion->size,
-			ION_IOC_INV_CACHES);
-
-}
-int wfd_allocate_input_buffers(struct wfd_device *wfd_dev,
-			struct wfd_inst *inst)
-{
-	int i;
-	struct mem_region *enc_mregion, *mdp_mregion;
-	struct mem_region_pair *mpair;
-	int rc;
-	unsigned long flags;
-	struct mdp_buf_info mdp_buf = {0};
-	struct mem_region_map mmap_context = {0};
-	spin_lock_irqsave(&inst->inst_lock, flags);
-	if (inst->input_bufs_allocated) {
-		spin_unlock_irqrestore(&inst->inst_lock, flags);
-		return 0;
-	}
-	inst->input_bufs_allocated = true;
-	spin_unlock_irqrestore(&inst->inst_lock, flags);
-
-	for (i = 0; i < VENC_INPUT_BUFFERS; ++i) {
-		mpair = kzalloc(sizeof(*mpair), GFP_KERNEL);
-		enc_mregion = kzalloc(sizeof(*enc_mregion), GFP_KERNEL);
-		mdp_mregion = kzalloc(sizeof(*enc_mregion), GFP_KERNEL);
-		enc_mregion->size = ALIGN(inst->input_buf_size, SZ_4K);
-
-		rc = wfd_allocate_ion_buffer(wfd_dev->ion_client,
-				wfd_dev->secure_device, enc_mregion);
-		if (rc) {
-			WFD_MSG_ERR("Failed to allocate input memory\n");
-			goto alloc_fail;
-		}
-
-		mmap_context.mregion = enc_mregion;
-		mmap_context.ion_client = wfd_dev->ion_client;
-		rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
-				ENC_MMAP, &mmap_context);
-		if (rc || !enc_mregion->paddr) {
-			WFD_MSG_ERR("Failed to map input memory\n");
-			goto alloc_fail;
-		}
-
-		WFD_MSG_DBG("NOTE: enc paddr = [%p->%p], kvaddr = %p\n",
-				enc_mregion->paddr, (int8_t *)
-				enc_mregion->paddr + enc_mregion->size,
-				enc_mregion->kvaddr);
-
-		rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
-				SET_INPUT_BUFFER, (void *)enc_mregion);
-		if (rc) {
-			WFD_MSG_ERR("Setting enc input buffer failed\n");
-			goto set_input_fail;
-		}
-
-		/* map the buffer from encoder to mdp */
-		mdp_mregion->kvaddr = enc_mregion->kvaddr;
-		mdp_mregion->size = enc_mregion->size;
-		mdp_mregion->offset = enc_mregion->offset;
-		mdp_mregion->fd = enc_mregion->fd;
-		mdp_mregion->cookie = 0;
-		mdp_mregion->ion_handle = enc_mregion->ion_handle;
-
-		memset(&mmap_context, 0, sizeof(mmap_context));
-		mmap_context.mregion = mdp_mregion;
-		mmap_context.ion_client = wfd_dev->ion_client;
-		mmap_context.cookie = inst->mdp_inst;
-		rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl,
-				MDP_MMAP, (void *)&mmap_context);
-
-		if (rc || !mdp_mregion->paddr) {
-			WFD_MSG_ERR(
-				"Failed to map to mdp, rc = %d, paddr = 0x%p\n",
-				rc, mdp_mregion->paddr);
-			mdp_mregion->kvaddr = NULL;
-			mdp_mregion->paddr = NULL;
-			mdp_mregion->ion_handle = NULL;
-			goto mdp_mmap_fail;
-		}
-
-		mdp_buf.inst = inst->mdp_inst;
-		mdp_buf.cookie = enc_mregion;
-		mdp_buf.kvaddr = (u32) mdp_mregion->kvaddr;
-		mdp_buf.paddr = (u32) mdp_mregion->paddr;
-
-		WFD_MSG_DBG("NOTE: mdp paddr = [%p->%p], kvaddr = %p\n",
-				mdp_mregion->paddr, (void *)
-				((int)mdp_mregion->paddr + mdp_mregion->size),
-				mdp_mregion->kvaddr);
-
-		rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl,
-				MDP_Q_BUFFER, (void *)&mdp_buf);
-		if (rc) {
-			WFD_MSG_ERR("Unable to queue the"
-					" buffer to mdp\n");
-			goto mdp_q_fail;
-		} else {
-			wfd_stats_update(&inst->stats,
-					WFD_STAT_EVENT_MDP_QUEUE);
-		}
-
-		INIT_LIST_HEAD(&mpair->list);
-		mpair->enc = enc_mregion;
-		mpair->mdp = mdp_mregion;
-		list_add_tail(&mpair->list, &inst->input_mem_list);
-
-	}
-
-	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
-			ALLOC_RECON_BUFFERS, NULL);
-	if (rc) {
-		WFD_MSG_ERR("Failed to allocate recon buffers\n");
-		goto recon_alloc_fail;
-	}
-	return rc;
-
-	/*
-	 * Clean up only the buffer that we failed in setting up.
-	 * Caller will clean up the rest by calling free_input_buffers()
-	 */
-mdp_q_fail:
-	memset(&mmap_context, 0, sizeof(mmap_context));
-	mmap_context.mregion = mdp_mregion;
-	mmap_context.ion_client = wfd_dev->ion_client;
-	mmap_context.cookie = inst->mdp_inst;
-	v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl,
-			MDP_MUNMAP, (void *)&mmap_context);
-mdp_mmap_fail:
-	v4l2_subdev_call(&wfd_dev->enc_sdev,
-			core, ioctl, FREE_INPUT_BUFFER,
-			(void *)enc_mregion);
-set_input_fail:
-	memset(&mmap_context, 0, sizeof(mmap_context));
-	mmap_context.ion_client = wfd_dev->ion_client;
-	mmap_context.mregion = enc_mregion;
-	v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
-			ENC_MUNMAP, &mmap_context);
-alloc_fail:
-	kfree(mpair);
-	kfree(enc_mregion);
-	kfree(mdp_mregion);
-recon_alloc_fail:
-	return rc;
-}
-void wfd_free_input_buffers(struct wfd_device *wfd_dev,
-			struct wfd_inst *inst)
-{
-	struct list_head *ptr, *next;
-	struct mem_region_pair *mpair;
-	unsigned long flags;
-	int rc = 0;
-	spin_lock_irqsave(&inst->inst_lock, flags);
-	if (!inst->input_bufs_allocated) {
-		spin_unlock_irqrestore(&inst->inst_lock, flags);
-		return;
-	}
-	inst->input_bufs_allocated = false;
-	spin_unlock_irqrestore(&inst->inst_lock, flags);
-	if (!list_empty(&inst->input_mem_list)) {
-		list_for_each_safe(ptr, next,
-				&inst->input_mem_list) {
-			mpair = list_entry(ptr, struct mem_region_pair,
-						list);
-			rc = v4l2_subdev_call(&wfd_dev->enc_sdev,
-					core, ioctl, FREE_INPUT_BUFFER,
-					(void *)mpair->enc);
-
-			if (rc)
-				WFD_MSG_ERR("Failed to free buffers "
-						"from encoder\n");
-
-			if (mpair->mdp->paddr) {
-				struct mem_region_map temp = {0};
-
-				temp.ion_client = wfd_dev->ion_client;
-				temp.mregion = mpair->mdp;
-				temp.cookie = inst->mdp_inst;
-
-				v4l2_subdev_call(&wfd_dev->mdp_sdev, core,
-						ioctl, MDP_MUNMAP,
-						(void *)&temp);
-			}
-
-			if (mpair->enc->paddr) {
-				struct mem_region_map temp = {0};
-				temp.ion_client = wfd_dev->ion_client;
-				temp.mregion = mpair->enc;
-				v4l2_subdev_call(&wfd_dev->enc_sdev,
-					core, ioctl, ENC_MUNMAP, &temp);
-			}
-
-			wfd_free_ion_buffer(wfd_dev->ion_client, mpair->enc);
-			list_del(&mpair->list);
-			kfree(mpair->enc);
-			kfree(mpair->mdp);
-			kfree(mpair);
-		}
-	}
-	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
-			FREE_RECON_BUFFERS, NULL);
-	if (rc)
-		WFD_MSG_ERR("Failed to free recon buffers\n");
-}
-
-struct mem_info *wfd_get_mem_info(struct wfd_inst *inst,
-			unsigned long userptr)
-{
-	struct mem_info_entry *temp;
-	struct mem_info *ret = NULL;
-	unsigned long flags;
-	spin_lock_irqsave(&inst->inst_lock, flags);
-	if (!list_empty(&inst->minfo_list)) {
-		list_for_each_entry(temp, &inst->minfo_list, list) {
-			if (temp && temp->userptr == userptr) {
-				ret = &temp->minfo;
-				break;
-			}
-		}
-	}
-	spin_unlock_irqrestore(&inst->inst_lock, flags);
-	return ret;
-}
-void wfd_put_mem_info(struct wfd_inst *inst,
-			struct mem_info *minfo)
-{
-	struct list_head *ptr, *next;
-	struct mem_info_entry *temp;
-	unsigned long flags;
-	spin_lock_irqsave(&inst->inst_lock, flags);
-	if (!list_empty(&inst->minfo_list)) {
-		list_for_each_safe(ptr, next,
-				&inst->minfo_list) {
-			temp = list_entry(ptr, struct mem_info_entry,
-						list);
-			if (temp && (&temp->minfo == minfo)) {
-				list_del(&temp->list);
-				kfree(temp);
-			}
-		}
-	}
-	spin_unlock_irqrestore(&inst->inst_lock, flags);
-}
-static void wfd_unregister_out_buf(struct wfd_inst *inst,
-		struct mem_info *minfo)
-{
-	if (!minfo || !inst) {
-		WFD_MSG_ERR("Invalid arguments\n");
-		return;
-	}
-	wfd_put_mem_info(inst, minfo);
-}
-int wfd_vidbuf_buf_init(struct vb2_buffer *vb)
-{
-	int rc = 0;
-	struct vb2_queue *q = vb->vb2_queue;
-	struct file *priv_data = (struct file *)(q->drv_priv);
-	struct wfd_inst *inst = (struct wfd_inst *)priv_data->private_data;
-	struct wfd_device *wfd_dev =
-		(struct wfd_device *)video_drvdata(priv_data);
-	struct mem_info *minfo = vb2_plane_cookie(vb, 0);
-	struct mem_region mregion;
-	mregion.fd = minfo->fd;
-	mregion.offset = minfo->offset;
-	mregion.cookie = (u32)vb;
-	/*TODO: should be fixed in kernel 3.2*/
-	mregion.size =  inst->out_buf_size;
-
-	if (inst && !inst->vid_bufq.streaming) {
-		rc = wfd_allocate_input_buffers(wfd_dev, inst);
-		if (rc) {
-			WFD_MSG_ERR("Failed to allocate input buffers\n");
-			goto free_input_bufs;
-		}
-		rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
-				SET_OUTPUT_BUFFER, (void *)&mregion);
-		if (rc) {
-			WFD_MSG_ERR("Failed to set output buffer\n");
-			goto free_input_bufs;
-		}
-	}
-	return rc;
-free_input_bufs:
-	wfd_free_input_buffers(wfd_dev, inst);
-	return rc;
-}
-
-int wfd_vidbuf_buf_prepare(struct vb2_buffer *vb)
-{
-	return 0;
-}
-
-int wfd_vidbuf_buf_finish(struct vb2_buffer *vb)
-{
-	return 0;
-}
-
-void wfd_vidbuf_buf_cleanup(struct vb2_buffer *vb)
-{
-	int rc = 0;
-	struct vb2_queue *q = vb->vb2_queue;
-	struct file *priv_data = (struct file *)(q->drv_priv);
-	struct wfd_device *wfd_dev =
-		(struct wfd_device *)video_drvdata(priv_data);
-	struct wfd_inst *inst = (struct wfd_inst *)priv_data->private_data;
-	struct mem_info *minfo = vb2_plane_cookie(vb, 0);
-	struct mem_region mregion;
-
-	if (minfo == NULL) {
-		WFD_MSG_DBG("not freeing buffers since allocation failed");
-		return;
-	}
-
-	mregion.fd = minfo->fd;
-	mregion.offset = minfo->offset;
-	mregion.cookie = (u32)vb;
-	mregion.size =  inst->out_buf_size;
-
-	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
-			FREE_OUTPUT_BUFFER, (void *)&mregion);
-	if (rc)
-		WFD_MSG_ERR("Failed to free output buffer\n");
-	wfd_unregister_out_buf(inst, minfo);
-}
-
-static int mdp_output_thread(void *data)
-{
-	int rc = 0, no_sig_wait = 0;
-	struct file *filp = (struct file *)data;
-	struct wfd_inst *inst = filp->private_data;
-	struct wfd_device *wfd_dev =
-		(struct wfd_device *)video_drvdata(filp);
-	struct mdp_buf_info obuf_mdp = {inst->mdp_inst, 0, 0, 0};
-	struct mem_region *mregion;
-	struct vsg_buf_info ibuf_vsg;
-	while (!kthread_should_stop()) {
-		if (rc) {
-			WFD_MSG_DBG("%s() error in output thread\n", __func__);
-			if (!no_sig_wait) {
-				wait_for_completion(&inst->stop_mdp_thread);
-				no_sig_wait = 1;
-			}
-			continue;
-		}
-		WFD_MSG_DBG("waiting for mdp output\n");
-		rc = v4l2_subdev_call(&wfd_dev->mdp_sdev,
-			core, ioctl, MDP_DQ_BUFFER, (void *)&obuf_mdp);
-
-		if (rc) {
-			if (rc != -ENOBUFS)
-				WFD_MSG_ERR("MDP reported err %d\n", rc);
-
-			WFD_MSG_ERR("Streamoff called\n");
-			continue;
-		} else {
-			wfd_stats_update(&inst->stats,
-				WFD_STAT_EVENT_MDP_DEQUEUE);
-		}
-
-		mregion = obuf_mdp.cookie;
-		if (!mregion) {
-			WFD_MSG_ERR("mdp cookie is null\n");
-			rc = -EINVAL;
-			continue;
-		}
-
-		ibuf_vsg.mdp_buf_info = obuf_mdp;
-		ibuf_vsg.mdp_buf_info.inst = inst->mdp_inst;
-		ibuf_vsg.mdp_buf_info.cookie = mregion;
-		ibuf_vsg.mdp_buf_info.kvaddr = (u32) mregion->kvaddr;
-		ibuf_vsg.mdp_buf_info.paddr =
-			(u32)wfd_enc_addr_to_mdp_addr(inst,
-					(unsigned long)mregion->paddr);
-		rc = v4l2_subdev_call(&wfd_dev->vsg_sdev,
-			core, ioctl, VSG_Q_BUFFER, (void *)&ibuf_vsg);
-
-		if (rc) {
-			WFD_MSG_ERR("Failed to queue frame to vsg\n");
-			continue;
-		} else {
-			wfd_stats_update(&inst->stats,
-				WFD_STAT_EVENT_VSG_QUEUE);
-		}
-	}
-	WFD_MSG_DBG("Exiting the thread\n");
-	return rc;
-}
-
-int wfd_vidbuf_start_streaming(struct vb2_queue *q, unsigned int count)
-{
-	struct file *priv_data = (struct file *)(q->drv_priv);
-	struct wfd_device *wfd_dev =
-		(struct wfd_device *)video_drvdata(priv_data);
-	struct wfd_inst *inst = (struct wfd_inst *)priv_data->private_data;
-	int rc = 0;
-
-	WFD_MSG_ERR("Stream on called\n");
-	WFD_MSG_DBG("enc start\n");
-	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
-			ENCODE_START, (void *)inst->venc_inst);
-	if (rc) {
-		WFD_MSG_ERR("Failed to start encoder\n");
-		goto subdev_start_fail;
-	}
-
-	WFD_MSG_DBG("vsg start\n");
-	rc = v4l2_subdev_call(&wfd_dev->vsg_sdev, core, ioctl,
-			VSG_START, NULL);
-	if (rc) {
-		WFD_MSG_ERR("Failed to start vsg\n");
-		goto subdev_start_fail;
-	}
-	init_completion(&inst->stop_mdp_thread);
-	inst->mdp_task = kthread_run(mdp_output_thread, priv_data,
-				"mdp_output_thread");
-	if (IS_ERR(inst->mdp_task)) {
-		rc = PTR_ERR(inst->mdp_task);
-		goto subdev_start_fail;
-	}
-	WFD_MSG_DBG("mdp start\n");
-	rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl,
-			 MDP_START, (void *)inst->mdp_inst);
-	if (rc)
-		WFD_MSG_ERR("Failed to start MDP\n");
-subdev_start_fail:
-	return rc;
-}
-
-int wfd_vidbuf_stop_streaming(struct vb2_queue *q)
-{
-	struct file *priv_data = (struct file *)(q->drv_priv);
-	struct wfd_device *wfd_dev =
-		(struct wfd_device *)video_drvdata(priv_data);
-	struct wfd_inst *inst = (struct wfd_inst *)priv_data->private_data;
-	int rc = 0;
-	WFD_MSG_DBG("mdp stop\n");
-	rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl,
-			 MDP_STOP, (void *)inst->mdp_inst);
-	if (rc)
-		WFD_MSG_ERR("Failed to stop MDP\n");
-
-	WFD_MSG_DBG("vsg stop\n");
-	rc = v4l2_subdev_call(&wfd_dev->vsg_sdev, core, ioctl,
-			 VSG_STOP, NULL);
-	if (rc)
-		WFD_MSG_ERR("Failed to stop VSG\n");
-
-	complete(&inst->stop_mdp_thread);
-	kthread_stop(inst->mdp_task);
-	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
-			ENCODE_FLUSH, (void *)inst->venc_inst);
-	if (rc)
-		WFD_MSG_ERR("Failed to flush encoder\n");
-	WFD_MSG_DBG("enc stop\n");
-	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
-			ENCODE_STOP, (void *)inst->venc_inst);
-	if (rc)
-		WFD_MSG_ERR("Failed to stop encoder\n");
-
-	return rc;
-}
-
-void wfd_vidbuf_buf_queue(struct vb2_buffer *vb)
-{
-	int rc = 0;
-	struct vb2_queue *q = vb->vb2_queue;
-	struct file *priv_data = (struct file *)(q->drv_priv);
-	struct wfd_device *wfd_dev =
-		(struct wfd_device *)video_drvdata(priv_data);
-	struct wfd_inst *inst = (struct wfd_inst *)priv_data->private_data;
-	struct mem_region mregion;
-	struct mem_info *minfo = vb2_plane_cookie(vb, 0);
-	mregion.fd = minfo->fd;
-	mregion.offset = minfo->offset;
-	mregion.cookie = (u32)vb;
-	mregion.size =  inst->out_buf_size;
-	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
-			FILL_OUTPUT_BUFFER, (void *)&mregion);
-	if (rc) {
-		WFD_MSG_ERR("Failed to fill output buffer\n");
-	}
-}
-
-static struct vb2_ops wfd_vidbuf_ops = {
-	.queue_setup = wfd_vidbuf_queue_setup,
-
-	.wait_prepare = wfd_vidbuf_wait_prepare,
-	.wait_finish = wfd_vidbuf_wait_finish,
-
-	.buf_init = wfd_vidbuf_buf_init,
-	.buf_prepare = wfd_vidbuf_buf_prepare,
-	.buf_finish = wfd_vidbuf_buf_finish,
-	.buf_cleanup = wfd_vidbuf_buf_cleanup,
-
-	.start_streaming = wfd_vidbuf_start_streaming,
-	.stop_streaming = wfd_vidbuf_stop_streaming,
-
-	.buf_queue = wfd_vidbuf_buf_queue,
-};
-
-static const struct v4l2_subdev_core_ops mdp_subdev_core_ops = {
-	.init = mdp_init,
-	.ioctl = mdp_ioctl,
-};
-
-static const struct v4l2_subdev_ops mdp_subdev_ops = {
-	.core = &mdp_subdev_core_ops,
-};
-
-static const struct v4l2_subdev_core_ops enc_subdev_core_ops = {
-	.init = venc_init,
-	.load_fw = venc_load_fw,
-	.ioctl = venc_ioctl,
-};
-
-static const struct v4l2_subdev_ops enc_subdev_ops = {
-	.core = &enc_subdev_core_ops,
-};
-
-static const struct v4l2_subdev_core_ops vsg_subdev_core_ops = {
-	.init = vsg_init,
-	.ioctl = vsg_ioctl,
-};
-
-static const struct v4l2_subdev_ops vsg_subdev_ops = {
-	.core = &vsg_subdev_core_ops,
-};
-
-static int wfdioc_querycap(struct file *filp, void *fh,
-		struct v4l2_capability *cap) {
-	WFD_MSG_DBG("wfdioc_querycap: E\n");
-	memset(cap, 0, sizeof(struct v4l2_capability));
-	strlcpy(cap->driver, "wifi-display", sizeof(cap->driver));
-	strlcpy(cap->card, "msm", sizeof(cap->card));
-	cap->version = WFD_VERSION;
-	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
-	WFD_MSG_DBG("wfdioc_querycap: X\n");
-	return 0;
-}
-static int wfdioc_g_fmt(struct file *filp, void *fh,
-			struct v4l2_format *fmt)
-{
-	struct wfd_inst *inst = filp->private_data;
-	unsigned long flags;
-	if (!fmt) {
-		WFD_MSG_ERR("Invalid argument\n");
-		return -EINVAL;
-	}
-	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-		WFD_MSG_ERR("Only V4L2_BUF_TYPE_VIDEO_CAPTURE is supported\n");
-		return -EINVAL;
-	}
-	spin_lock_irqsave(&inst->inst_lock, flags);
-	fmt->fmt.pix.width = inst->width;
-	fmt->fmt.pix.height = inst->height;
-	fmt->fmt.pix.pixelformat = inst->pixelformat;
-	fmt->fmt.pix.sizeimage = inst->out_buf_size;
-	fmt->fmt.pix.priv = 0;
-	spin_unlock_irqrestore(&inst->inst_lock, flags);
-	return 0;
-}
-
-static int wfdioc_s_fmt(struct file *filp, void *fh,
-			struct v4l2_format *fmt)
-{
-	int rc = 0;
-	struct wfd_inst *inst = filp->private_data;
-	struct wfd_device *wfd_dev = video_drvdata(filp);
-	struct mdp_prop prop;
-	unsigned long flags;
-	struct bufreq breq;
-	if (!fmt) {
-		WFD_MSG_ERR("Invalid argument\n");
-		return -EINVAL;
-	}
-	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
-		fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_H264) {
-		WFD_MSG_ERR("Only V4L2_BUF_TYPE_VIDEO_CAPTURE and "
-				"V4L2_PIX_FMT_H264 are supported\n");
-		return -EINVAL;
-	}
-
-	if (fmt->fmt.pix.width % 16) {
-		WFD_MSG_ERR("Only 16 byte aligned widths are supported\n");
-		return -ENOTSUPP;
-	}
-	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl, SET_FORMAT,
-				(void *)fmt);
-	if (rc) {
-		WFD_MSG_ERR("Failed to set format on encoder, rc = %d\n", rc);
-		return rc;
-	}
-	breq.count = VENC_INPUT_BUFFERS;
-	breq.height = fmt->fmt.pix.height;
-	breq.width = fmt->fmt.pix.width;
-	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
-			SET_BUFFER_REQ, (void *)&breq);
-	if (rc) {
-		WFD_MSG_ERR("Failed to set buffer reqs on encoder\n");
-		return rc;
-	}
-	spin_lock_irqsave(&inst->inst_lock, flags);
-	inst->input_buf_size = breq.size;
-	inst->out_buf_size = fmt->fmt.pix.sizeimage;
-	prop.height = inst->height = fmt->fmt.pix.height;
-	prop.width = inst->width = fmt->fmt.pix.width;
-	prop.inst = inst->mdp_inst;
-	spin_unlock_irqrestore(&inst->inst_lock, flags);
-	rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl, MDP_SET_PROP,
-				(void *)&prop);
-	if (rc)
-		WFD_MSG_ERR("Failed to set height/width property on mdp\n");
-	return rc;
-}
-static int wfdioc_reqbufs(struct file *filp, void *fh,
-		struct v4l2_requestbuffers *b)
-{
-	struct wfd_inst *inst = filp->private_data;
-	struct wfd_device *wfd_dev = video_drvdata(filp);
-	unsigned long flags;
-	int rc = 0;
-
-	if (b->type != V4L2_CAP_VIDEO_CAPTURE ||
-		b->memory != V4L2_MEMORY_USERPTR) {
-		WFD_MSG_ERR("Only V4L2_CAP_VIDEO_CAPTURE and "
-		"V4L2_MEMORY_USERPTR are supported\n");
-		return -EINVAL;
-	}
-	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
-			GET_BUFFER_REQ, (void *)b);
-	if (rc) {
-		WFD_MSG_ERR("Failed to get buf reqs from encoder\n");
-		return rc;
-	}
-	spin_lock_irqsave(&inst->inst_lock, flags);
-	inst->buf_count = b->count;
-	spin_unlock_irqrestore(&inst->inst_lock, flags);
-	rc = vb2_reqbufs(&inst->vid_bufq, b);
-	return rc;
-}
-static int wfd_register_out_buf(struct wfd_inst *inst,
-		struct v4l2_buffer *b)
-{
-	struct mem_info_entry *minfo_entry;
-	struct mem_info *minfo;
-	unsigned long flags;
-	if (!b || !inst || !b->reserved) {
-		WFD_MSG_ERR("Invalid arguments\n");
-		return -EINVAL;
-	}
-	minfo = wfd_get_mem_info(inst, b->m.userptr);
-	if (!minfo) {
-		minfo_entry = kzalloc(sizeof(struct mem_info_entry),
-				GFP_KERNEL);
-		if (copy_from_user(&minfo_entry->minfo, (void *)b->reserved,
-					sizeof(struct mem_info))) {
-			WFD_MSG_ERR(" copy_from_user failed. Populate"
-					" v4l2_buffer->reserved with meminfo\n");
-			return -EINVAL;
-		}
-		minfo_entry->userptr = b->m.userptr;
-		spin_lock_irqsave(&inst->inst_lock, flags);
-		list_add_tail(&minfo_entry->list, &inst->minfo_list);
-		spin_unlock_irqrestore(&inst->inst_lock, flags);
-	} else
-		WFD_MSG_DBG("Buffer already registered\n");
-
-	return 0;
-}
-static int wfdioc_qbuf(struct file *filp, void *fh,
-		struct v4l2_buffer *b)
-{
-	int rc = 0;
-	struct wfd_inst *inst = filp->private_data;
-	if (!inst || !b ||
-			(b->index < 0 || b->index >= inst->buf_count)) {
-		WFD_MSG_ERR("Invalid input parameters to QBUF IOCTL\n");
-		return -EINVAL;
-	}
-	rc = wfd_register_out_buf(inst, b);
-	if (rc) {
-		WFD_MSG_ERR("Failed to register buffer\n");
-		return rc;
-	}
-
-	rc = vb2_qbuf(&inst->vid_bufq, b);
-	if (rc)
-		WFD_MSG_ERR("Failed to queue buffer\n");
-	else
-		wfd_stats_update(&inst->stats, WFD_STAT_EVENT_CLIENT_QUEUE);
-
-	return rc;
-}
-
-static int wfdioc_streamon(struct file *filp, void *fh,
-		enum v4l2_buf_type i)
-{
-	int rc = 0;
-	struct wfd_inst *inst = filp->private_data;
-	unsigned long flags;
-	if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-		WFD_MSG_ERR("stream on for buffer type = %d is not "
-			"supported.\n", i);
-		return -EINVAL;
-	}
-
-	spin_lock_irqsave(&inst->inst_lock, flags);
-	inst->streamoff = false;
-	spin_unlock_irqrestore(&inst->inst_lock, flags);
-
-	rc = vb2_streamon(&inst->vid_bufq, i);
-	if (rc) {
-		WFD_MSG_ERR("videobuf_streamon failed with err = %d\n", rc);
-		goto vidbuf_streamon_failed;
-	}
-	return rc;
-
-vidbuf_streamon_failed:
-	vb2_streamoff(&inst->vid_bufq, i);
-	return rc;
-}
-static int wfdioc_streamoff(struct file *filp, void *fh,
-		enum v4l2_buf_type i)
-{
-	struct wfd_inst *inst = filp->private_data;
-	unsigned long flags;
-
-	if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-		WFD_MSG_ERR("stream off for buffer type = %d is not "
-			"supported.\n", i);
-		return -EINVAL;
-	}
-
-	spin_lock_irqsave(&inst->inst_lock, flags);
-	if (inst->streamoff) {
-		WFD_MSG_ERR("Module is already in streamoff state\n");
-		spin_unlock_irqrestore(&inst->inst_lock, flags);
-		return -EINVAL;
-	}
-	inst->streamoff = true;
-	spin_unlock_irqrestore(&inst->inst_lock, flags);
-	WFD_MSG_DBG("Calling videobuf_streamoff\n");
-	vb2_streamoff(&inst->vid_bufq, i);
-	return 0;
-}
-static int wfdioc_dqbuf(struct file *filp, void *fh,
-		struct v4l2_buffer *b)
-{
-	struct wfd_inst *inst = filp->private_data;
-	int rc;
-
-	WFD_MSG_DBG("Waiting to dequeue buffer\n");
-	rc = vb2_dqbuf(&inst->vid_bufq, b, 0);
-
-	if (rc)
-		WFD_MSG_ERR("Failed to dequeue buffer\n");
-	else
-		wfd_stats_update(&inst->stats, WFD_STAT_EVENT_CLIENT_DEQUEUE);
-
-	return rc;
-}
-static int wfdioc_g_ctrl(struct file *filp, void *fh,
-					struct v4l2_control *a)
-{
-	int rc = 0;
-	struct wfd_device *wfd_dev = video_drvdata(filp);
-	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core,
-			ioctl, GET_PROP, a);
-	if (rc)
-		WFD_MSG_ERR("Failed to get encoder property\n");
-	return rc;
-}
-static int wfdioc_s_ctrl(struct file *filp, void *fh,
-					struct v4l2_control *a)
-{
-	int rc = 0;
-	struct wfd_device *wfd_dev = video_drvdata(filp);
-	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core,
-			ioctl, SET_PROP, a);
-	if (rc)
-		WFD_MSG_ERR("Failed to set encoder property\n");
-	return rc;
-}
-
-static int wfdioc_g_parm(struct file *filp, void *fh,
-		struct v4l2_streamparm *a)
-{
-	int rc = 0;
-	struct wfd_device *wfd_dev = video_drvdata(filp);
-	struct wfd_inst *inst = filp->private_data;
-	int64_t frame_interval = 0,
-		max_frame_interval = 0; /* both in nsecs*/
-	struct v4l2_qcom_frameskip frameskip, *usr_frameskip;
-
-	usr_frameskip = (struct v4l2_qcom_frameskip *)
-			a->parm.capture.extendedmode;
-
-	if (!usr_frameskip) {
-		rc = -EINVAL;
-		goto get_parm_fail;
-	}
-	rc = v4l2_subdev_call(&wfd_dev->vsg_sdev, core,
-			ioctl, VSG_GET_FRAME_INTERVAL, &frame_interval);
-
-	if (rc < 0)
-		goto get_parm_fail;
-
-	rc = v4l2_subdev_call(&wfd_dev->vsg_sdev, core,
-			ioctl, VSG_GET_MAX_FRAME_INTERVAL, &max_frame_interval);
-
-	if (rc < 0)
-		goto get_parm_fail;
-
-	frameskip = (struct v4l2_qcom_frameskip) {
-		.maxframeinterval = max_frame_interval,
-	};
-
-	a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	a->parm.capture = (struct v4l2_captureparm) {
-		.capability = V4L2_CAP_TIMEPERFRAME,
-		.capturemode = 0,
-		.timeperframe = (struct v4l2_fract) {
-			.numerator = frame_interval,
-			.denominator = NSEC_PER_SEC,
-		},
-		.readbuffers = inst->buf_count,
-		.extendedmode = (__u32)usr_frameskip,
-		.reserved = {0}
-	};
-
-	rc = copy_to_user((void *)a->parm.capture.extendedmode,
-			&frameskip, sizeof(frameskip));
-	if (rc < 0)
-		goto get_parm_fail;
-
-get_parm_fail:
-	return rc;
-}
-
-static int wfdioc_s_parm(struct file *filp, void *fh,
-		struct v4l2_streamparm *a)
-{
-	int rc = 0;
-	struct wfd_device *wfd_dev = video_drvdata(filp);
-	struct wfd_inst *inst = filp->private_data;
-	struct v4l2_qcom_frameskip frameskip;
-	int64_t frame_interval, max_frame_interval;
-	void *extendedmode = NULL;
-	enum vsg_modes vsg_mode = VSG_MODE_VFR;
-	enum venc_framerate_modes venc_mode = VENC_MODE_VFR;
-
-
-	if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-		rc = -ENOTSUPP;
-		goto set_parm_fail;
-	}
-
-	if (a->parm.capture.readbuffers == 0 ||
-		a->parm.capture.readbuffers == inst->buf_count) {
-		a->parm.capture.readbuffers = inst->buf_count;
-	} else {
-		rc = -EINVAL;
-		goto set_parm_fail;
-	}
-
-	extendedmode = (void *)a->parm.capture.extendedmode;
-	if (a->parm.capture.capability & V4L2_CAP_TIMEPERFRAME) {
-		if (a->parm.capture.timeperframe.denominator == 0) {
-			rc = -EINVAL;
-			goto set_parm_fail;
-		}
-		frame_interval =
-			a->parm.capture.timeperframe.numerator * NSEC_PER_SEC /
-			a->parm.capture.timeperframe.denominator;
-
-		rc = v4l2_subdev_call(&wfd_dev->vsg_sdev, core,
-				ioctl, VSG_SET_FRAME_INTERVAL,
-				&frame_interval);
-
-		if (rc)
-			goto set_parm_fail;
-
-		rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core,
-				ioctl, SET_FRAMERATE,
-				&a->parm.capture.timeperframe);
-
-		if (rc)
-			goto set_parm_fail;
-	}
-
-	if (a->parm.capture.capability & V4L2_CAP_QCOM_FRAMESKIP &&
-		extendedmode) {
-		rc = copy_from_user(&frameskip,
-				extendedmode, sizeof(frameskip));
-
-		if (rc)
-			goto set_parm_fail;
-
-		max_frame_interval = (int64_t)frameskip.maxframeinterval;
-		vsg_mode = VSG_MODE_VFR;
-		venc_mode = VENC_MODE_VFR;
-
-		rc = v4l2_subdev_call(&wfd_dev->vsg_sdev, core,
-				ioctl, VSG_SET_MAX_FRAME_INTERVAL,
-				&max_frame_interval);
-
-		if (rc)
-			goto set_parm_fail;
-	} else {
-		vsg_mode = VSG_MODE_CFR;
-		venc_mode = VENC_MODE_CFR;
-	}
-
-	rc = v4l2_subdev_call(&wfd_dev->vsg_sdev, core,
-			ioctl, VSG_SET_MODE, &vsg_mode);
-	if (rc) {
-		WFD_MSG_ERR("Setting FR mode for VSG failed\n");
-		goto set_parm_fail;
-	}
-
-	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core,
-			ioctl, SET_FRAMERATE_MODE,
-			&venc_mode);
-	if (rc) {
-		WFD_MSG_ERR("Setting FR mode for VENC failed\n");
-		goto set_parm_fail;
-	}
-
-set_parm_fail:
-	return rc;
-}
-
-static const struct v4l2_ioctl_ops g_wfd_ioctl_ops = {
-	.vidioc_querycap = wfdioc_querycap,
-	.vidioc_s_fmt_vid_cap = wfdioc_s_fmt,
-	.vidioc_g_fmt_vid_cap = wfdioc_g_fmt,
-	.vidioc_reqbufs = wfdioc_reqbufs,
-	.vidioc_qbuf = wfdioc_qbuf,
-	.vidioc_streamon = wfdioc_streamon,
-	.vidioc_streamoff = wfdioc_streamoff,
-	.vidioc_dqbuf = wfdioc_dqbuf,
-	.vidioc_g_ctrl = wfdioc_g_ctrl,
-	.vidioc_s_ctrl = wfdioc_s_ctrl,
-	.vidioc_g_parm = wfdioc_g_parm,
-	.vidioc_s_parm = wfdioc_s_parm,
-};
-static int wfd_set_default_properties(struct file *filp)
-{
-	unsigned long flags;
-	struct v4l2_format fmt;
-	struct v4l2_control ctrl;
-	struct wfd_inst *inst = filp->private_data;
-	if (!inst) {
-		WFD_MSG_ERR("Invalid argument\n");
-		return -EINVAL;
-	}
-	spin_lock_irqsave(&inst->inst_lock, flags);
-	fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	fmt.fmt.pix.height = inst->height = DEFAULT_WFD_HEIGHT;
-	fmt.fmt.pix.width = inst->width = DEFAULT_WFD_WIDTH;
-	fmt.fmt.pix.pixelformat = inst->pixelformat
-			= V4L2_PIX_FMT_H264;
-	spin_unlock_irqrestore(&inst->inst_lock, flags);
-	wfdioc_s_fmt(filp, filp->private_data, &fmt);
-
-	ctrl.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
-	ctrl.value = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME;
-	wfdioc_s_ctrl(filp, filp->private_data, &ctrl);
-	return 0;
-}
-static void venc_op_buffer_done(void *cookie, u32 status,
-			struct vb2_buffer *buf)
-{
-	WFD_MSG_DBG("yay!! got callback\n");
-	vb2_buffer_done(buf, VB2_BUF_STATE_DONE);
-}
-
-static void venc_ip_buffer_done(void *cookie, u32 status,
-			struct mem_region *mregion)
-{
-	struct file *filp = cookie;
-	struct wfd_inst *inst = filp->private_data;
-	struct vsg_buf_info buf;
-	struct mdp_buf_info mdp_buf = {0};
-	struct wfd_device *wfd_dev =
-		(struct wfd_device *)video_drvdata(filp);
-	int rc = 0;
-	WFD_MSG_DBG("yay!! got ip callback\n");
-	mdp_buf.inst = inst->mdp_inst;
-	mdp_buf.cookie = mregion;
-	mdp_buf.kvaddr = (u32) mregion->kvaddr;
-	mdp_buf.paddr =
-		(u32)wfd_enc_addr_to_mdp_addr(inst,
-			(unsigned long)mregion->paddr);
-	buf.mdp_buf_info = mdp_buf;
-
-	rc = v4l2_subdev_call(&wfd_dev->vsg_sdev, core,
-			ioctl, VSG_RETURN_IP_BUFFER, (void *)&buf);
-	if (rc)
-		WFD_MSG_ERR("Failed to return buffer to vsg\n");
-	else
-		wfd_stats_update(&inst->stats, WFD_STAT_EVENT_ENC_DEQUEUE);
-
-}
-
-static int vsg_release_input_frame(void *cookie, struct vsg_buf_info *buf)
-{
-	struct file *filp = cookie;
-	struct wfd_inst *inst = filp->private_data;
-	struct wfd_device *wfd_dev =
-		(struct wfd_device *)video_drvdata(filp);
-	int rc = 0;
-
-	rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core,
-			ioctl, MDP_Q_BUFFER, buf);
-	if (rc)
-		WFD_MSG_ERR("Failed to Q buffer to mdp\n");
-	else {
-		wfd_stats_update(&inst->stats, WFD_STAT_EVENT_MDP_QUEUE);
-		wfd_stats_update(&inst->stats, WFD_STAT_EVENT_VSG_DEQUEUE);
-	}
-
-	return rc;
-}
-
-static int vsg_encode_frame(void *cookie, struct vsg_buf_info *buf)
-{
-	struct file *filp = cookie;
-	struct wfd_inst *inst = filp->private_data;
-	struct wfd_device *wfd_dev =
-		(struct wfd_device *)video_drvdata(filp);
-	struct venc_buf_info venc_buf;
-	int rc = 0;
-
-	if (!buf)
-		return -EINVAL;
-
-	venc_buf = (struct venc_buf_info){
-		.timestamp = timespec_to_ns(&buf->time),
-		.mregion = buf->mdp_buf_info.cookie
-	};
-
-	wfd_flush_ion_buffer(wfd_dev->ion_client, venc_buf.mregion);
-
-	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
-			ENCODE_FRAME, &venc_buf);
-
-	if (rc)
-		WFD_MSG_ERR("Encode failed\n");
-	else
-		wfd_stats_update(&inst->stats, WFD_STAT_EVENT_ENC_QUEUE);
-
-	return rc;
-}
-
-void *wfd_vb2_mem_ops_get_userptr(void *alloc_ctx, unsigned long vaddr,
-					unsigned long size, int write)
-{
-	return wfd_get_mem_info(alloc_ctx, vaddr);
-}
-
-void wfd_vb2_mem_ops_put_userptr(void *buf_priv)
-{
-	/*TODO: Free the list*/
-}
-
-void *wfd_vb2_mem_ops_cookie(void *buf_priv)
-{
-	return buf_priv;
-}
-
-
-static struct vb2_mem_ops wfd_vb2_mem_ops = {
-	.get_userptr = wfd_vb2_mem_ops_get_userptr,
-	.put_userptr = wfd_vb2_mem_ops_put_userptr,
-	.cookie = wfd_vb2_mem_ops_cookie,
-};
-
-int wfd_initialize_vb2_queue(struct vb2_queue *q, void *priv)
-{
-	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	q->io_modes = VB2_USERPTR;
-	q->ops = &wfd_vidbuf_ops;
-	q->mem_ops = &wfd_vb2_mem_ops;
-	q->drv_priv = priv;
-	return vb2_queue_init(q);
-}
-
-static int wfd_open(struct file *filp)
-{
-	int rc = 0;
-	struct wfd_inst *inst = NULL;
-	struct wfd_device *wfd_dev = NULL;
-	struct venc_msg_ops enc_mops;
-	struct mdp_msg_ops mdp_mops;
-	struct vsg_msg_ops vsg_mops;
-
-	WFD_MSG_DBG("wfd_open: E\n");
-	wfd_dev = video_drvdata(filp);
-	if (!wfd_dev) {
-		rc = -EINVAL;
-		goto err_dev_busy;
-	}
-	mutex_lock(&wfd_dev->dev_lock);
-	if (wfd_dev->in_use) {
-		WFD_MSG_ERR("Device already in use.\n");
-		rc = -EBUSY;
-		mutex_unlock(&wfd_dev->dev_lock);
-		goto err_dev_busy;
-	}
-
-	wfd_dev->in_use = true;
-	mutex_unlock(&wfd_dev->dev_lock);
-
-	inst = kzalloc(sizeof(struct wfd_inst), GFP_KERNEL);
-	if (!inst) {
-		WFD_MSG_ERR("Could not allocate memory for "
-			"wfd instance\n");
-		rc = -ENOMEM;
-		goto err_mdp_open;
-	}
-	filp->private_data = inst;
-	spin_lock_init(&inst->inst_lock);
-	INIT_LIST_HEAD(&inst->input_mem_list);
-	INIT_LIST_HEAD(&inst->minfo_list);
-
-	wfd_stats_init(&inst->stats, MINOR(filp->f_dentry->d_inode->i_rdev));
-
-	mdp_mops.secure = wfd_dev->secure_device;
-	mdp_mops.iommu_split_domain = wfd_dev->mdp_iommu_split_domain;
-	rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl, MDP_OPEN,
-				(void *)&mdp_mops);
-	if (rc) {
-		WFD_MSG_ERR("Failed to open mdp subdevice: %d\n", rc);
-		goto err_mdp_open;
-	}
-	inst->mdp_inst = mdp_mops.cookie;
-
-	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, load_fw);
-	if (rc) {
-		WFD_MSG_ERR("Failed to load video encoder firmware: %d\n", rc);
-		goto err_venc;
-	}
-	enc_mops.op_buffer_done = venc_op_buffer_done;
-	enc_mops.ip_buffer_done = venc_ip_buffer_done;
-	enc_mops.cbdata = filp;
-	enc_mops.secure = wfd_dev->secure_device;
-	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl, OPEN,
-				(void *)&enc_mops);
-	if (rc || !enc_mops.cookie) {
-		WFD_MSG_ERR("Failed to open encoder subdevice: %d\n", rc);
-		goto err_venc;
-	}
-	inst->venc_inst = enc_mops.cookie;
-
-	vsg_mops.encode_frame = vsg_encode_frame;
-	vsg_mops.release_input_frame = vsg_release_input_frame;
-	vsg_mops.cbdata = filp;
-	rc = v4l2_subdev_call(&wfd_dev->vsg_sdev, core, ioctl, VSG_OPEN,
-				&vsg_mops);
-	if (rc) {
-		WFD_MSG_ERR("Failed to open vsg subdevice: %d\n", rc);
-		goto err_vsg_open;
-	}
-
-	wfd_initialize_vb2_queue(&inst->vid_bufq, filp);
-	wfd_set_default_properties(filp);
-	WFD_MSG_DBG("wfd_open: X\n");
-	return rc;
-
-err_vsg_open:
-	v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl, CLOSE, NULL);
-err_venc:
-	v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl,
-				MDP_CLOSE, (void *)inst->mdp_inst);
-err_mdp_open:
-	mutex_lock(&wfd_dev->dev_lock);
-	wfd_dev->in_use = false;
-	mutex_unlock(&wfd_dev->dev_lock);
-	kfree(inst);
-err_dev_busy:
-	return rc;
-}
-
-static int wfd_close(struct file *filp)
-{
-	struct wfd_inst *inst;
-	struct wfd_device *wfd_dev;
-	int rc = 0;
-	wfd_dev = video_drvdata(filp);
-	WFD_MSG_DBG("wfd_close: E\n");
-	inst = filp->private_data;
-	if (inst) {
-		wfdioc_streamoff(filp, NULL, V4L2_BUF_TYPE_VIDEO_CAPTURE);
-		rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl,
-				MDP_CLOSE, (void *)inst->mdp_inst);
-		if (rc)
-			WFD_MSG_ERR("Failed to CLOSE mdp subdevice: %d\n", rc);
-
-		vb2_queue_release(&inst->vid_bufq);
-		wfd_free_input_buffers(wfd_dev, inst);
-		rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
-				CLOSE, (void *)inst->venc_inst);
-
-		if (rc)
-			WFD_MSG_ERR("Failed to CLOSE enc subdev: %d\n", rc);
-
-		rc = v4l2_subdev_call(&wfd_dev->vsg_sdev, core, ioctl,
-				VSG_CLOSE, NULL);
-
-		if (rc)
-			WFD_MSG_ERR("Failed to CLOSE vsg subdev: %d\n", rc);
-
-		wfd_stats_deinit(&inst->stats);
-		kfree(inst);
-	}
-
-	mutex_lock(&wfd_dev->dev_lock);
-	wfd_dev->in_use = false;
-	mutex_unlock(&wfd_dev->dev_lock);
-
-	WFD_MSG_DBG("wfd_close: X\n");
-	return 0;
-}
-static const struct v4l2_file_operations g_wfd_fops = {
-	.owner = THIS_MODULE,
-	.open = wfd_open,
-	.release = wfd_close,
-	.ioctl = video_ioctl2
-};
-void release_video_device(struct video_device *pvdev)
-{
-
-}
-
-static int wfd_dev_setup(struct wfd_device *wfd_dev, int dev_num,
-		struct platform_device *pdev)
-{
-	int rc = 0;
-	rc = v4l2_device_register(&pdev->dev, &wfd_dev->v4l2_dev);
-	if (rc) {
-		WFD_MSG_ERR("Failed to register the video device\n");
-		goto err_v4l2_registration;
-	}
-	wfd_dev->pvdev = video_device_alloc();
-	if (!wfd_dev->pvdev) {
-		WFD_MSG_ERR("Failed to allocate video device\n");
-		goto err_video_device_alloc;
-	}
-
-	wfd_dev->pvdev->release = release_video_device;
-	wfd_dev->pvdev->fops = &g_wfd_fops;
-	wfd_dev->pvdev->ioctl_ops = &g_wfd_ioctl_ops;
-
-	rc = video_register_device(wfd_dev->pvdev, VFL_TYPE_GRABBER,
-			dev_num);
-	if (rc) {
-		WFD_MSG_ERR("Failed to register the device\n");
-		goto err_video_register_device;
-	}
-	video_set_drvdata(wfd_dev->pvdev, wfd_dev);
-
-	v4l2_subdev_init(&wfd_dev->mdp_sdev, &mdp_subdev_ops);
-	strncpy(wfd_dev->mdp_sdev.name, "wfd-mdp", V4L2_SUBDEV_NAME_SIZE);
-	rc = v4l2_device_register_subdev(&wfd_dev->v4l2_dev,
-			&wfd_dev->mdp_sdev);
-	if (rc) {
-		WFD_MSG_ERR("Failed to register mdp subdevice: %d\n", rc);
-		goto err_mdp_register_subdev;
-	}
-
-	v4l2_subdev_init(&wfd_dev->enc_sdev, &enc_subdev_ops);
-	strncpy(wfd_dev->enc_sdev.name, "wfd-venc", V4L2_SUBDEV_NAME_SIZE);
-	rc = v4l2_device_register_subdev(&wfd_dev->v4l2_dev,
-			&wfd_dev->enc_sdev);
-	if (rc) {
-		WFD_MSG_ERR("Failed to register encoder subdevice: %d\n", rc);
-		goto err_venc_register_subdev;
-	}
-	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, init, 0);
-	if (rc) {
-		WFD_MSG_ERR("Failed to initiate encoder device %d\n", rc);
-		goto err_venc_init;
-	}
-
-	v4l2_subdev_init(&wfd_dev->vsg_sdev, &vsg_subdev_ops);
-	strncpy(wfd_dev->vsg_sdev.name, "wfd-vsg", V4L2_SUBDEV_NAME_SIZE);
-	rc = v4l2_device_register_subdev(&wfd_dev->v4l2_dev,
-			&wfd_dev->vsg_sdev);
-	if (rc) {
-		WFD_MSG_ERR("Failed to register vsg subdevice: %d\n", rc);
-		goto err_venc_init;
-	}
-
-	WFD_MSG_DBG("__wfd_probe: X\n");
-	return rc;
-
-err_venc_init:
-	v4l2_device_unregister_subdev(&wfd_dev->enc_sdev);
-err_venc_register_subdev:
-	v4l2_device_unregister_subdev(&wfd_dev->mdp_sdev);
-err_mdp_register_subdev:
-	video_unregister_device(wfd_dev->pvdev);
-err_video_register_device:
-	video_device_release(wfd_dev->pvdev);
-err_video_device_alloc:
-	v4l2_device_unregister(&wfd_dev->v4l2_dev);
-err_v4l2_registration:
-	return rc;
-}
-static int __devinit __wfd_probe(struct platform_device *pdev)
-{
-	int rc = 0, c = 0;
-	struct wfd_device *wfd_dev; /* Should be taken as an array*/
-	struct ion_client *ion_client = NULL;
-	struct msm_wfd_platform_data *wfd_priv;
-
-	WFD_MSG_DBG("__wfd_probe: E\n");
-	wfd_dev = kzalloc(sizeof(*wfd_dev)*WFD_NUM_DEVICES, GFP_KERNEL);
-	if (!wfd_dev) {
-		WFD_MSG_ERR("Could not allocate memory for "
-				"wfd device\n");
-		rc = -ENOMEM;
-		goto err_v4l2_probe;
-	}
-
-	wfd_priv = pdev->dev.platform_data;
-
-	pdev->dev.platform_data = (void *) wfd_dev;
-
-	ion_client = msm_ion_client_create(-1, "wfd");
-
-	rc = wfd_stats_setup();
-	if (rc) {
-		WFD_MSG_ERR("No debugfs support: %d\n", rc);
-		/* Don't treat this as a fatal err */
-		rc = 0;
-	}
-
-	if (!ion_client) {
-		WFD_MSG_ERR("Failed to create ion client\n");
-		rc = -ENODEV;
-		goto err_v4l2_probe;
-	}
-
-	for (c = 0; c < WFD_NUM_DEVICES; ++c) {
-		rc = wfd_dev_setup(&wfd_dev[c],
-			WFD_DEVICE_NUMBER_BASE + c, pdev);
-
-		if (rc) {
-			/* Clear out old devices */
-			for (--c; c >= 0; --c) {
-				v4l2_device_unregister_subdev(
-						&wfd_dev[c].vsg_sdev);
-				v4l2_device_unregister_subdev(
-						&wfd_dev[c].enc_sdev);
-				v4l2_device_unregister_subdev(
-						&wfd_dev[c].mdp_sdev);
-				video_unregister_device(wfd_dev[c].pvdev);
-				video_device_release(wfd_dev[c].pvdev);
-				v4l2_device_unregister(&wfd_dev[c].v4l2_dev);
-			}
-
-			goto err_v4l2_probe;
-		}
-
-		/* Other device specific stuff */
-		mutex_init(&wfd_dev[c].dev_lock);
-		wfd_dev[c].ion_client = ion_client;
-		wfd_dev[c].in_use = false;
-		if (wfd_priv && wfd_priv->wfd_check_mdp_iommu_split) {
-			wfd_dev[c].mdp_iommu_split_domain =
-				wfd_priv->wfd_check_mdp_iommu_split();
-		}
-
-		switch (WFD_DEVICE_NUMBER_BASE + c) {
-		case WFD_DEVICE_SECURE:
-			wfd_dev[c].secure_device = true;
-			break;
-		default:
-			break;
-		}
-
-	}
-	WFD_MSG_DBG("__wfd_probe: X\n");
-	return rc;
-err_v4l2_probe:
-	kfree(wfd_dev);
-	return rc;
-}
-
-static int __devexit __wfd_remove(struct platform_device *pdev)
-{
-	struct wfd_device *wfd_dev;
-	int c = 0;
-
-	wfd_dev = (struct wfd_device *)pdev->dev.platform_data;
-
-	WFD_MSG_DBG("Inside wfd_remove\n");
-	if (!wfd_dev) {
-		WFD_MSG_ERR("Error removing WFD device");
-		return -ENODEV;
-	}
-
-	wfd_stats_teardown();
-	for (c = 0; c < WFD_NUM_DEVICES; ++c) {
-		v4l2_device_unregister_subdev(&wfd_dev[c].vsg_sdev);
-		v4l2_device_unregister_subdev(&wfd_dev[c].enc_sdev);
-		v4l2_device_unregister_subdev(&wfd_dev[c].mdp_sdev);
-		video_unregister_device(wfd_dev[c].pvdev);
-		video_device_release(wfd_dev[c].pvdev);
-		v4l2_device_unregister(&wfd_dev[c].v4l2_dev);
-	}
-
-	kfree(wfd_dev);
-	return 0;
-}
-
-static const struct of_device_id msm_wfd_dt_match[] = {
-	{.compatible = "qcom,msm-wfd"},
-	{}
-};
-
-MODULE_DEVICE_TABLE(of, msm_vidc_dt_match);
-
-static struct platform_driver wfd_driver = {
-	.probe =  __wfd_probe,
-	.remove = __wfd_remove,
-	.driver = {
-		.name = "msm_wfd",
-		.owner = THIS_MODULE,
-		.of_match_table = msm_wfd_dt_match,
-	}
-};
-
-static int __init wfd_init(void)
-{
-	int rc = 0;
-	WFD_MSG_DBG("Calling init function of wfd driver\n");
-	rc = platform_driver_register(&wfd_driver);
-	if (rc) {
-		WFD_MSG_ERR("failed to load the driver\n");
-		goto err_platform_registration;
-	}
-err_platform_registration:
-	return rc;
-}
-
-static void __exit wfd_exit(void)
-{
-	WFD_MSG_DBG("wfd_exit: X\n");
-	platform_driver_unregister(&wfd_driver);
-}
-
-module_init(wfd_init);
-module_exit(wfd_exit);
diff --git a/drivers/media/video/msm_wfd/wfd-util.c b/drivers/media/video/msm_wfd/wfd-util.c
deleted file mode 100644
index 28a6084..0000000
--- a/drivers/media/video/msm_wfd/wfd-util.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/debugfs.h>
-#include <linux/hrtimer.h>
-#include <linux/limits.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-
-#include "wfd-util.h"
-
-static struct dentry *wfd_debugfs_root;
-
-int wfd_stats_setup()
-{
-	wfd_debugfs_root = debugfs_create_dir("wfd", NULL);
-
-	if (wfd_debugfs_root == ERR_PTR(-ENODEV))
-		return -ENODEV;
-	else if (!wfd_debugfs_root)
-		return -ENOMEM;
-	else
-		return 0;
-}
-
-void wfd_stats_teardown()
-{
-	if (wfd_debugfs_root)
-		debugfs_remove_recursive(wfd_debugfs_root);
-}
-
-int wfd_stats_init(struct wfd_stats *stats, int device)
-{
-	char device_str[NAME_MAX] = "";
-	int rc = 0;
-
-	if (!stats) {
-		rc = -EINVAL;
-		goto wfd_stats_init_fail;
-	} else if (!wfd_debugfs_root) {
-		WFD_MSG_ERR("wfd debugfs root does not exist\n");
-		rc = -ENOENT;
-		goto wfd_stats_init_fail;
-	}
-
-	memset(stats, 0, sizeof(*stats));
-	INIT_LIST_HEAD(&stats->enc_queue);
-
-	snprintf(device_str, sizeof(device_str), "%d", device);
-	stats->d_parent = debugfs_create_dir(device_str, wfd_debugfs_root);
-	if (IS_ERR(stats->d_parent)) {
-		rc = PTR_ERR(stats->d_parent);
-		stats->d_parent = NULL;
-		goto wfd_stats_init_fail;
-	}
-
-	stats->d_v4l2_buf_count = debugfs_create_u32("v4l2_buf_count", S_IRUGO,
-			stats->d_parent, &stats->v4l2_buf_count);
-	if (IS_ERR(stats->d_v4l2_buf_count)) {
-		rc = PTR_ERR(stats->d_v4l2_buf_count);
-		stats->d_v4l2_buf_count = NULL;
-		goto wfd_stats_init_fail;
-	}
-
-	stats->d_mdp_buf_count = debugfs_create_u32("mdp_buf_count", S_IRUGO,
-			stats->d_parent, &stats->mdp_buf_count);
-	if (IS_ERR(stats->d_mdp_buf_count)) {
-		rc = PTR_ERR(stats->d_mdp_buf_count);
-		stats->d_mdp_buf_count = NULL;
-		goto wfd_stats_init_fail;
-	}
-
-	stats->d_vsg_buf_count = debugfs_create_u32("vsg_buf_count", S_IRUGO,
-			stats->d_parent, &stats->vsg_buf_count);
-	if (IS_ERR(stats->d_vsg_buf_count)) {
-		rc = PTR_ERR(stats->d_vsg_buf_count);
-		stats->d_vsg_buf_count = NULL;
-		goto wfd_stats_init_fail;
-	}
-
-	stats->d_enc_buf_count = debugfs_create_u32("enc_buf_count", S_IRUGO,
-			stats->d_parent, &stats->enc_buf_count);
-	if (IS_ERR(stats->d_enc_buf_count)) {
-		rc = PTR_ERR(stats->d_enc_buf_count);
-		stats->d_enc_buf_count = NULL;
-		goto wfd_stats_init_fail;
-	}
-
-	stats->d_frames_encoded = debugfs_create_u32("frames_encoded", S_IRUGO,
-			stats->d_parent, &stats->frames_encoded);
-	if (IS_ERR(stats->d_frames_encoded)) {
-		rc = PTR_ERR(stats->d_frames_encoded);
-		stats->d_frames_encoded = NULL;
-		goto wfd_stats_init_fail;
-	}
-
-	stats->d_mdp_updates = debugfs_create_u32("mdp_updates", S_IRUGO,
-			stats->d_parent, &stats->mdp_updates);
-	if (IS_ERR(stats->d_mdp_updates)) {
-		rc = PTR_ERR(stats->d_mdp_updates);
-		stats->d_mdp_updates = NULL;
-		goto wfd_stats_init_fail;
-	}
-
-	stats->d_enc_avg_latency = debugfs_create_u32("enc_avg_latency",
-			S_IRUGO, stats->d_parent, &stats->enc_avg_latency);
-	if (IS_ERR(stats->d_enc_avg_latency)) {
-		rc = PTR_ERR(stats->d_enc_avg_latency);
-		stats->d_enc_avg_latency = NULL;
-		goto wfd_stats_init_fail;
-	}
-
-	return rc;
-wfd_stats_init_fail:
-	return rc;
-}
-
-int wfd_stats_update(struct wfd_stats *stats, enum wfd_stats_event event)
-{
-	int rc = 0;
-	switch (event) {
-	case WFD_STAT_EVENT_CLIENT_QUEUE:
-		stats->v4l2_buf_count++;
-		break;
-	case WFD_STAT_EVENT_CLIENT_DEQUEUE: {
-		struct wfd_stats_encode_sample *sample = NULL;
-
-		stats->v4l2_buf_count--;
-
-		if (!list_empty(&stats->enc_queue))
-			sample = list_first_entry(&stats->enc_queue,
-					struct wfd_stats_encode_sample,
-					list);
-		if (sample) {
-			ktime_t kdiff = ktime_sub(ktime_get(),
-						sample->encode_start_ts);
-			uint32_t diff = ktime_to_ms(kdiff);
-
-			stats->enc_cumulative_latency += diff;
-			stats->enc_latency_samples++;
-			stats->enc_avg_latency = stats->enc_cumulative_latency /
-				stats->enc_latency_samples;
-
-			list_del(&sample->list);
-			kfree(sample);
-			sample = NULL;
-		}
-		break;
-	}
-	case WFD_STAT_EVENT_MDP_QUEUE:
-		stats->mdp_buf_count++;
-		break;
-	case WFD_STAT_EVENT_MDP_DEQUEUE:
-		stats->mdp_buf_count--;
-		stats->mdp_updates++;
-		break;
-	case WFD_STAT_EVENT_ENC_QUEUE: {
-		struct wfd_stats_encode_sample *sample = NULL;
-
-		stats->enc_buf_count++;
-		stats->frames_encoded++;
-
-		sample = kzalloc(sizeof(*sample), GFP_KERNEL);
-		if (sample) {
-			INIT_LIST_HEAD(&sample->list);
-			sample->encode_start_ts = ktime_get();
-			list_add_tail(&sample->list, &stats->enc_queue);
-		} else {
-			WFD_MSG_WARN("Unable to measure latency\n");
-		}
-		break;
-	}
-	case WFD_STAT_EVENT_ENC_DEQUEUE:
-		stats->enc_buf_count--;
-		break;
-	case WFD_STAT_EVENT_VSG_QUEUE:
-		stats->vsg_buf_count++;
-		break;
-	case WFD_STAT_EVENT_VSG_DEQUEUE:
-		stats->vsg_buf_count--;
-		break;
-	default:
-		rc = -ENOTSUPP;
-	}
-
-	return rc;
-}
-
-int wfd_stats_deinit(struct wfd_stats *stats)
-{
-	WFD_MSG_DBG("Latencies: avg enc. latency %d",
-			stats->enc_avg_latency);
-	/* Delete all debugfs files in one shot :) */
-	if (stats->d_parent)
-		debugfs_remove_recursive(stats->d_parent);
-
-	stats->d_parent =
-	stats->d_v4l2_buf_count =
-	stats->d_mdp_buf_count =
-	stats->d_vsg_buf_count =
-	stats->d_enc_buf_count =
-	stats->d_frames_encoded =
-	stats->d_mdp_updates =
-	stats->d_enc_avg_latency = NULL;
-
-	return 0;
-}
diff --git a/drivers/media/video/msm_wfd/wfd-util.h b/drivers/media/video/msm_wfd/wfd-util.h
deleted file mode 100644
index 2fe7360..0000000
--- a/drivers/media/video/msm_wfd/wfd-util.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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/debugfs.h>
-#include <linux/list.h>
-#include <linux/ktime.h>
-
-#ifndef _WFD_UTIL_H_
-#define _WFD_UTIL_H_
-
-/*#define DEBUG_WFD*/
-
-#define WFD_TAG "wfd: "
-#define WFD_MSG_INFO(fmt...) pr_info(WFD_TAG fmt)
-#define WFD_MSG_WARN(fmt...) pr_warning(WFD_TAG fmt)
-#define WFD_MSG_ERR(fmt...) pr_err(KERN_ERR WFD_TAG fmt)
-#define WFD_MSG_CRIT(fmt...) pr_crit(KERN_CRIT WFD_TAG fmt)
-#define WFD_MSG_DBG(fmt...) pr_debug(WFD_TAG fmt)
-
-
-struct wfd_stats_encode_sample {
-	ktime_t encode_start_ts;
-	struct list_head list;
-};
-
-struct wfd_stats {
-	/* Output Buffers */
-	uint32_t v4l2_buf_count;
-
-	/* Input Buffers */
-	uint32_t mdp_buf_count;
-	uint32_t vsg_buf_count;
-	uint32_t enc_buf_count;
-
-	/* Other */
-	uint32_t frames_encoded;
-	uint32_t mdp_updates;
-
-	uint32_t enc_avg_latency;
-	uint32_t enc_cumulative_latency;
-	uint32_t enc_latency_samples;
-	struct list_head enc_queue;
-
-	/* Debugfs entries */
-	struct dentry *d_parent;
-	struct dentry *d_v4l2_buf_count;
-	struct dentry *d_mdp_buf_count;
-	struct dentry *d_vsg_buf_count;
-	struct dentry *d_enc_buf_count;
-	struct dentry *d_frames_encoded;
-	struct dentry *d_mdp_updates;
-	struct dentry *d_enc_avg_latency;
-};
-
-enum wfd_stats_event {
-	WFD_STAT_EVENT_CLIENT_QUEUE,
-	WFD_STAT_EVENT_CLIENT_DEQUEUE,
-
-	WFD_STAT_EVENT_MDP_QUEUE,
-	WFD_STAT_EVENT_MDP_DEQUEUE,
-
-	WFD_STAT_EVENT_VSG_QUEUE,
-	WFD_STAT_EVENT_VSG_DEQUEUE,
-
-	WFD_STAT_EVENT_ENC_QUEUE,
-	WFD_STAT_EVENT_ENC_DEQUEUE,
-};
-
-int wfd_stats_setup(void);
-int wfd_stats_init(struct wfd_stats *, int device);
-int wfd_stats_update(struct wfd_stats *, enum wfd_stats_event);
-int wfd_stats_deinit(struct wfd_stats *);
-void wfd_stats_teardown(void);
-#endif
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index 4012fec..3222ea0 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -259,6 +259,7 @@
 		"Single",
 		"Max Macroblocks",
 		"Max Bytes",
+		"GOB",
 		NULL,
 	};
 	static const char * const entropy_mode[] = {
diff --git a/drivers/media/video/vcap_v4l2.c b/drivers/media/video/vcap_v4l2.c
deleted file mode 100644
index 5b76c35..0000000
--- a/drivers/media/video/vcap_v4l2.c
+++ /dev/null
@@ -1,2505 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/io.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/mutex.h>
-#include <linux/videodev2.h>
-#include <linux/platform_device.h>
-#include <linux/memory_alloc.h>
-#include <linux/ctype.h>
-#include <linux/debugfs.h>
-#include <linux/regulator/consumer.h>
-#include <linux/clk.h>
-#include <linux/interrupt.h>
-#include <linux/iommu.h>
-
-#include <mach/board.h>
-#include <mach/gpio.h>
-#include <mach/irqs.h>
-#include <mach/clk.h>
-#include <mach/msm_bus.h>
-#include <mach/msm_bus_board.h>
-#include <mach/iommu.h>
-#include <mach/iommu_domains.h>
-
-#include <media/videobuf2-msm-mem.h>
-#include <media/videobuf2-vmalloc.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-fh.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-event.h>
-#include <media/vcap_v4l2.h>
-#include <media/vcap_fmt.h>
-
-#include "vcap_vc.h"
-#include "vcap_vp.h"
-
-#define NUM_INPUTS 1
-#define MSM_VCAP_DRV_NAME "msm_vcap"
-
-static struct vcap_dev *vcap_ctrl;
-
-#ifdef CONFIG_DEBUG_FS
-static struct dentry *vcap_debugfs_base;
-static struct reg_range debug_reg_range[] = {
-	{
-		VCAP_REG_RANGE_1_MIN,
-		VCAP_REG_RANGE_1_MAX,
-	},
-	{
-		VCAP_REG_RANGE_2_MIN,
-		VCAP_REG_RANGE_2_MAX,
-	},
-	{
-		VCAP_REG_RANGE_3_MIN,
-		VCAP_REG_RANGE_3_MAX,
-	},
-	{
-		VCAP_REG_RANGE_4_MIN,
-		VCAP_REG_RANGE_4_MAX,
-	},
-	{
-		VCAP_REG_RANGE_5_MIN,
-		VCAP_REG_RANGE_5_MAX,
-	},
-};
-#endif
-
-static int vcap_reg_powerup(struct vcap_dev *dev)
-{
-	dev->fs_vcap = regulator_get(dev->ddev, "fs_vcap");
-	if (IS_ERR(dev->fs_vcap)) {
-		pr_err("%s: Regulator FS_VCAP get failed %ld\n", __func__,
-			PTR_ERR(dev->fs_vcap));
-		dev->fs_vcap = NULL;
-		return -EINVAL;
-	} else if (regulator_enable(dev->fs_vcap)) {
-		pr_err("%s: Regulator FS_VCAP enable failed\n", __func__);
-		regulator_put(dev->fs_vcap);
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static void vcap_reg_powerdown(struct vcap_dev *dev)
-{
-	if (dev->fs_vcap == NULL)
-		return;
-	regulator_disable(dev->fs_vcap);
-	regulator_put(dev->fs_vcap);
-	dev->fs_vcap = NULL;
-	return;
-}
-
-static int vcap_config_gpios(int on, struct vcap_platform_data *pdata)
-{
-	int i, ret;
-	int num_gpios = pdata->num_gpios;
-	unsigned *gpios = pdata->gpios;
-
-	pr_debug("GPIO config start\n");
-	if (on) {
-		for (i = 0; i < num_gpios; i++) {
-			ret = gpio_request(gpios[i], "vcap:vc");
-			if (ret) {
-				pr_err("VCAP: failed at GPIO %d to request\n",
-						gpios[i]);
-				goto gpio_failed;
-			}
-			ret = gpio_direction_input(gpios[i]);
-			if (ret) {
-				pr_err("VCAP: failed at GPIO %d to set to input\n",
-					gpios[i]);
-				i++;
-				goto gpio_failed;
-			}
-		}
-	} else {
-		for (i = 0; i < num_gpios; i++)
-			gpio_free(gpios[i]);
-	}
-	pr_debug("GPIO config exit\n");
-	return 0;
-gpio_failed:
-	for (i--; i >= 0; i--)
-		gpio_free(gpios[i]);
-	return -EINVAL;
-}
-
-static int vcap_clk_powerup(struct vcap_dev *dev, struct device *ddev,
-		unsigned long rate)
-{
-	int ret = 0;
-
-	dev->vcap_clk = clk_get(ddev, "core_clk");
-	if (IS_ERR(dev->vcap_clk)) {
-		dev->vcap_clk = NULL;
-		pr_err("%s: Could not clk_get core_clk\n", __func__);
-		clk_put(dev->vcap_clk);
-		dev->vcap_clk = NULL;
-		return -EINVAL;
-	}
-
-	clk_prepare(dev->vcap_clk);
-	ret = clk_enable(dev->vcap_clk);
-	if (ret) {
-		pr_err("%s: Failed core clk_enable %d\n", __func__, ret);
-		goto fail_vcap_clk_unprep;
-	}
-
-	rate = clk_round_rate(dev->vcap_clk, rate);
-	if (rate < 0) {
-		pr_err("%s: Failed core rnd_rate\n", __func__);
-		goto fail_vcap_clk;
-	}
-	ret = clk_set_rate(dev->vcap_clk, rate);
-	if (ret < 0) {
-		pr_err("%s: Failed core set_rate %d\n", __func__, ret);
-		goto fail_vcap_clk;
-	}
-	dev->dbg_p.clk_rate = (uint32_t) rate;
-
-	dev->vcap_npl_clk = clk_get(ddev, "vcap_npl_clk");
-	if (IS_ERR(dev->vcap_npl_clk)) {
-		dev->vcap_npl_clk = NULL;
-		pr_err("%s: Could not clk_get npl\n", __func__);
-		clk_put(dev->vcap_npl_clk);
-		dev->vcap_npl_clk = NULL;
-		goto fail_vcap_clk;
-	}
-
-	clk_prepare(dev->vcap_npl_clk);
-	ret = clk_enable(dev->vcap_npl_clk);
-	if (ret) {
-		pr_err("%s:Failed npl clk_enable %d\n", __func__, ret);
-		goto fail_vcap_npl_clk_unprep;
-	}
-
-	dev->vcap_p_clk = clk_get(ddev, "iface_clk");
-	if (IS_ERR(dev->vcap_p_clk)) {
-		dev->vcap_p_clk = NULL;
-		pr_err("%s: Could not clk_get pix(AHB)\n", __func__);
-		clk_put(dev->vcap_p_clk);
-		dev->vcap_p_clk = NULL;
-		goto fail_vcap_npl_clk;
-	}
-
-	clk_prepare(dev->vcap_p_clk);
-	ret = clk_enable(dev->vcap_p_clk);
-	if (ret) {
-		pr_err("%s: Failed pix(AHB) clk_enable %d\n", __func__, ret);
-		goto fail_vcap_p_clk_unprep;
-	}
-	return 0;
-
-fail_vcap_p_clk_unprep:
-	clk_unprepare(dev->vcap_p_clk);
-	clk_put(dev->vcap_p_clk);
-	dev->vcap_p_clk = NULL;
-
-fail_vcap_npl_clk:
-	clk_disable(dev->vcap_npl_clk);
-fail_vcap_npl_clk_unprep:
-	clk_unprepare(dev->vcap_npl_clk);
-	clk_put(dev->vcap_npl_clk);
-	dev->vcap_npl_clk = NULL;
-
-fail_vcap_clk:
-	dev->dbg_p.clk_rate = 0;
-	clk_disable(dev->vcap_clk);
-fail_vcap_clk_unprep:
-	clk_unprepare(dev->vcap_clk);
-	clk_put(dev->vcap_clk);
-	dev->vcap_clk = NULL;
-	return -EINVAL;
-}
-
-static void vcap_clk_powerdown(struct vcap_dev *dev)
-{
-	if (dev->vcap_p_clk != NULL) {
-		clk_disable(dev->vcap_p_clk);
-		clk_unprepare(dev->vcap_p_clk);
-		clk_put(dev->vcap_p_clk);
-		dev->vcap_p_clk = NULL;
-	}
-
-	if (dev->vcap_npl_clk != NULL) {
-		clk_disable(dev->vcap_npl_clk);
-		clk_unprepare(dev->vcap_npl_clk);
-		clk_put(dev->vcap_npl_clk);
-		dev->vcap_npl_clk = NULL;
-	}
-
-	if (dev->vcap_clk != NULL) {
-		clk_disable(dev->vcap_clk);
-		clk_unprepare(dev->vcap_clk);
-		clk_put(dev->vcap_clk);
-		dev->vcap_clk = NULL;
-	}
-
-	dev->dbg_p.clk_rate = 0;
-}
-
-static int vcap_get_bus_client_handle(struct vcap_dev *dev)
-{
-	struct msm_bus_scale_pdata *vcap_axi_client_pdata =
-			dev->vcap_pdata->bus_client_pdata;
-	dev->bus_client_handle =
-			msm_bus_scale_register_client(vcap_axi_client_pdata);
-
-	return 0;
-}
-
-static int vcap_enable(struct vcap_dev *dev, struct device *ddev,
-		unsigned long rate)
-{
-	int rc;
-	pr_debug("Enter %s", __func__);
-
-	rc = vcap_reg_powerup(dev);
-	if (rc < 0)
-		goto reg_failed;
-	rc = vcap_clk_powerup(dev, ddev, rate);
-	if (rc < 0)
-		goto clk_failed;
-	rc = vcap_get_bus_client_handle(dev);
-	if (rc < 0)
-		goto bus_r_failed;
-	rc = vcap_config_gpios(1, dev->vcap_pdata);
-	if (rc < 0)
-		goto gpio_failed;
-	rc = iommu_attach_device(dev->iommu_vcap_domain, dev->vc_iommu_ctx);
-	if (rc < 0)
-		goto vc_iommu_attach_failed;
-	rc = iommu_attach_device(dev->iommu_vcap_domain, dev->vp_iommu_ctx);
-	if (rc < 0)
-		goto vp_iommu_attach_failed;
-	writel_relaxed(0x00030003, VCAP_OFFSET(0xD78));
-	writel_relaxed(0x00030003, VCAP_OFFSET(0xD7C));
-	pr_debug("Success Exit %s", __func__);
-	return 0;
-
-vp_iommu_attach_failed:
-	iommu_detach_device(dev->iommu_vcap_domain, dev->vc_iommu_ctx);
-vc_iommu_attach_failed:
-	vcap_config_gpios(0, dev->vcap_pdata);
-gpio_failed:
-	msm_bus_scale_unregister_client(dev->bus_client_handle);
-	dev->bus_client_handle = 0;
-bus_r_failed:
-	vcap_clk_powerdown(dev);
-clk_failed:
-	vcap_reg_powerdown(dev);
-reg_failed:
-	return rc;
-}
-
-static int vcap_disable(struct vcap_dev *dev)
-{
-	pr_debug("Enter %s", __func__);
-	iommu_detach_device(dev->iommu_vcap_domain, dev->vp_iommu_ctx);
-	iommu_detach_device(dev->iommu_vcap_domain, dev->vc_iommu_ctx);
-
-	vcap_config_gpios(0, dev->vcap_pdata);
-
-	msm_bus_scale_unregister_client(dev->bus_client_handle);
-	dev->bus_client_handle = 0;
-	dev->dbg_p.bw_request = 0;
-	vcap_clk_powerdown(dev);
-	vcap_reg_powerdown(dev);
-	return 0;
-}
-
-static int vcap_register_domain(void)
-{
-	struct msm_iova_partition vcap_partition = {
-		.start = 0,
-		.size = SZ_2G,
-	};
-	struct msm_iova_layout vcap_layout = {
-		.partitions = &vcap_partition,
-		.npartitions = 1,
-		.client_name = "vcap",
-		.domain_flags = 0,
-	};
-
-	return msm_register_domain(&vcap_layout);
-}
-
-enum vcap_op_mode determine_mode(struct vcap_client_data *cd)
-{
-	if (cd->set_cap == 1 && cd->set_vp_o == 0 &&
-			cd->set_decode == 0)
-		return VC_VCAP_OP;
-	else if (cd->set_cap == 1 && cd->set_vp_o == 1 &&
-			cd->set_decode == 0)
-		return VC_AND_VP_VCAP_OP;
-	else if (cd->set_cap == 0 && cd->set_vp_o == 1 &&
-			cd->set_decode == 1)
-		return VP_VCAP_OP;
-	else
-		return UNKNOWN_VCAP_OP;
-}
-
-void dealloc_resources(struct vcap_client_data *cd)
-{
-	cd->set_cap = false;
-	cd->set_decode = false;
-	cd->set_vp_o = false;
-}
-
-/* VCAP Internal QBUF and DQBUF for VC + VP */
-int vcvp_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
-{
-	struct vb2_buffer *vb;
-
-	if (q->fileio) {
-		pr_debug("%s: file io in progress\n", __func__);
-		return -EBUSY;
-	}
-
-	if (b->type != q->type) {
-		pr_debug("%s: invalid buffer type\n", __func__);
-		return -EINVAL;
-	}
-
-	if (b->index >= q->num_buffers) {
-		pr_debug("%s: buffer index out of range\n", __func__);
-		return -EINVAL;
-	}
-
-	vb = q->bufs[b->index];
-	if (NULL == vb) {
-		pr_debug("%s: buffer is NULL\n", __func__);
-		return -EINVAL;
-	}
-
-	if (b->memory != q->memory) {
-		pr_debug("%s: invalid memory type\n", __func__);
-		return -EINVAL;
-	}
-
-	if (vb->state != VB2_BUF_STATE_DEQUEUED &&
-			vb->state != VB2_BUF_STATE_PREPARED) {
-		pr_err("%s: buffer already in use\n", __func__);
-		return -EINVAL;
-	}
-
-	vb->v4l2_buf.timestamp = b->timestamp;
-	vb->v4l2_buf.field = b->field;
-	list_add_tail(&vb->queued_entry, &q->queued_list);
-	vb->state = VB2_BUF_STATE_QUEUED;
-
-	if (q->streaming) {
-		vb->state = VB2_BUF_STATE_ACTIVE;
-		atomic_inc(&q->queued_count);
-		q->ops->buf_queue(vb);
-	}
-	return 0;
-}
-
-int vcvp_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b)
-{
-	struct vb2_buffer *vb = NULL;
-	unsigned long flags;
-
-	if (q->fileio) {
-		pr_debug("%s: file io in progress\n", __func__);
-		return -EBUSY;
-	}
-
-	if (b->type != q->type) {
-		pr_debug("%s: invalid buffer type\n", __func__);
-		return -EINVAL;
-	}
-
-	if (!q->streaming) {
-		pr_debug("Streaming off, will not wait for buffers\n");
-		return -EINVAL;
-	}
-
-	if (!list_empty(&q->done_list)) {
-		spin_lock_irqsave(&q->done_lock, flags);
-		vb = list_first_entry(&q->done_list, struct vb2_buffer,
-				done_entry);
-		list_del(&vb->done_entry);
-		spin_unlock_irqrestore(&q->done_lock, flags);
-
-		switch (vb->state) {
-		case VB2_BUF_STATE_DONE:
-			pr_debug("%s: Returning done buffer\n", __func__);
-			break;
-		case VB2_BUF_STATE_ERROR:
-			pr_debug("%s: Ret done buf with err\n", __func__);
-			break;
-		default:
-			pr_debug("%s: Invalid buffer state\n", __func__);
-			return -EINVAL;
-		}
-
-		memcpy(b, &vb->v4l2_buf, offsetof(struct v4l2_buffer, m));
-
-		list_del(&vb->queued_entry);
-
-		vb->state = VB2_BUF_STATE_DEQUEUED;
-		return 0;
-	}
-
-	pr_debug("%s: No buffers to dequeue\n", __func__);
-	return -EAGAIN;
-}
-
-int get_phys_addr(struct vcap_dev *dev, struct vb2_queue *q,
-				  struct v4l2_buffer *b)
-{
-	struct vb2_buffer *vb;
-	struct vcap_buffer *buf;
-	unsigned long len, offset;
-	int rc;
-
-	if (q->fileio) {
-		pr_debug("%s: file io in progress\n", __func__);
-		return -EBUSY;
-	}
-
-	if (b->type != q->type) {
-		pr_debug("%s: invalid buffer type\n", __func__);
-		return -EINVAL;
-	}
-
-	if (b->index >= q->num_buffers) {
-		pr_debug("%s: buffer index out of range\n", __func__);
-		return -EINVAL;
-	}
-
-	vb = q->bufs[b->index];
-	if (NULL == vb) {
-		pr_debug("%s: buffer is NULL\n", __func__);
-		return -EINVAL;
-	}
-
-	if (vb->state != VB2_BUF_STATE_DEQUEUED) {
-		pr_debug("%s: buffer already in use\n", __func__);
-		return -EINVAL;
-	}
-
-	buf = container_of(vb, struct vcap_buffer, vb);
-
-	buf->ion_handle = ion_import_dma_buf(dev->ion_client, b->m.userptr);
-	if (IS_ERR_OR_NULL((void *)buf->ion_handle)) {
-		pr_err("%s: Could not alloc memory\n", __func__);
-		buf->ion_handle = NULL;
-		return -ENOMEM;
-	}
-	rc = ion_map_iommu(dev->ion_client, buf->ion_handle,
-		dev->domain_num, 0, SZ_4K, 0, &buf->paddr, &len,
-		0, 0);
-	if (rc < 0) {
-		pr_err("%s: Could not get phys addr\n", __func__);
-		ion_free(dev->ion_client, buf->ion_handle);
-		buf->ion_handle = NULL;
-		return -EFAULT;
-	}
-
-	offset = b->reserved;
-	buf->paddr += offset;
-	return 0;
-}
-
-void free_ion_handle_work(struct vcap_client_data *c_data,
-	struct vb2_buffer *vb)
-{
-	struct vcap_buffer *buf;
-	struct vcap_dev *dev = c_data->dev;
-	struct ion_handle *handle;
-	unsigned long flags = 0;
-
-	buf = container_of(vb, struct vcap_buffer, vb);
-
-	spin_lock_irqsave(&c_data->cap_slock, flags);
-	handle = buf->ion_handle;
-	buf->ion_handle = NULL;
-	spin_unlock_irqrestore(&c_data->cap_slock, flags);
-
-	if (handle == NULL) {
-		pr_debug("%s: no ION handle to free\n", __func__);
-		return;
-	}
-	buf->paddr = 0;
-	ion_unmap_iommu(dev->ion_client, handle, dev->domain_num, 0);
-	ion_free(dev->ion_client, handle);
-	return;
-}
-
-int free_ion_handle(struct vcap_client_data *c_data, struct vb2_queue *q,
-					 struct v4l2_buffer *b)
-{
-	struct vb2_buffer *vb;
-
-	if (q->fileio)
-		return -EBUSY;
-
-	if (b->type != q->type)
-		return -EINVAL;
-
-	if (b->index >= q->num_buffers)
-		return -EINVAL;
-
-	vb = q->bufs[b->index];
-	if (NULL == vb)
-		return -EINVAL;
-
-	free_ion_handle_work(c_data, vb);
-	return 0;
-}
-
-void free_ion_on_q_bufs(struct vb2_queue *vq)
-{
-	struct vcap_client_data *c_data = vb2_get_drv_priv(vq);
-	struct vb2_buffer *vb;
-
-	if (!vq->streaming) {
-		list_for_each_entry(vb, &vq->queued_list, queued_entry)
-			free_ion_handle_work(c_data, vb);
-	}
-}
-
-/* VC Videobuf operations */
-static void wait_prepare(struct vb2_queue *q)
-{
-	struct vcap_client_data *c_data = vb2_get_drv_priv(q);
-	mutex_unlock(&c_data->mutex);
-}
-
-static void wait_finish(struct vb2_queue *q)
-{
-	struct vcap_client_data *c_data = vb2_get_drv_priv(q);
-	mutex_lock(&c_data->mutex);
-}
-
-static int capture_queue_setup(struct vb2_queue *vq,
-			       const struct v4l2_format *fmt,
-			       unsigned int *nbuffers,
-			       unsigned int *nplanes, unsigned int sizes[],
-			       void *alloc_ctxs[])
-{
-	*nbuffers += vcap_ctrl->vc_tot_buf;
-	if (*nbuffers > VIDEO_MAX_FRAME)
-		return -EINVAL;
-	*nplanes = 1;
-	return 0;
-}
-
-static int capture_buffer_init(struct vb2_buffer *vb)
-{
-	return 0;
-}
-
-static int capture_buffer_prepare(struct vb2_buffer *vb)
-{
-	return 0;
-}
-
-static void capture_buffer_queue(struct vb2_buffer *vb)
-{
-	struct vcap_client_data *c_data = vb2_get_drv_priv(vb->vb2_queue);
-	struct vcap_buffer *buf = container_of(vb, struct vcap_buffer, vb);
-	struct vc_action *vc_action = &c_data->vc_action;
-	struct vb2_queue *q = vb->vb2_queue;
-	unsigned long flags = 0;
-
-	spin_lock_irqsave(&c_data->cap_slock, flags);
-	list_add_tail(&buf->list, &vc_action->active);
-	spin_unlock_irqrestore(&c_data->cap_slock, flags);
-
-	if (atomic_read(&c_data->dev->vc_enabled) == 0) {
-		if (atomic_read(&q->queued_count) >= c_data->vc_action.tot_buf)
-			if (vc_hw_kick_off(c_data) == 0)
-				atomic_set(&c_data->dev->vc_enabled, 1);
-	}
-}
-
-static int capture_start_streaming(struct vb2_queue *vq, unsigned int count)
-{
-	struct vcap_client_data *c_data = vb2_get_drv_priv(vq);
-	pr_debug("VC start streaming\n");
-	return vc_start_capture(c_data);
-}
-
-static int capture_stop_streaming(struct vb2_queue *vq)
-{
-	struct vcap_client_data *c_data = vb2_get_drv_priv(vq);
-	struct vb2_buffer *vb;
-
-	vc_stop_capture(c_data);
-
-	while (!list_empty(&c_data->vc_action.active)) {
-		struct vcap_buffer *buf;
-		buf = list_entry(c_data->vc_action.active.next,
-			struct vcap_buffer, list);
-		list_del(&buf->list);
-		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
-	}
-
-	/* clean ion handles */
-	list_for_each_entry(vb, &vq->queued_list, queued_entry)
-		free_ion_handle_work(c_data, vb);
-	return 0;
-}
-
-static int capture_buffer_finish(struct vb2_buffer *vb)
-{
-	return 0;
-}
-
-static void capture_buffer_cleanup(struct vb2_buffer *vb)
-{
-}
-
-static struct vb2_ops capture_video_qops = {
-	.queue_setup		= capture_queue_setup,
-	.wait_finish		= wait_finish,
-	.wait_prepare		= wait_prepare,
-	.buf_init			= capture_buffer_init,
-	.buf_prepare		= capture_buffer_prepare,
-	.buf_queue			= capture_buffer_queue,
-	.start_streaming	= capture_start_streaming,
-	.stop_streaming		= capture_stop_streaming,
-	.buf_finish			= capture_buffer_finish,
-	.buf_cleanup		= capture_buffer_cleanup,
-};
-
-/* VP I/P Videobuf operations */
-
-static int vp_in_queue_setup(struct vb2_queue *vq,
-			     const struct v4l2_format *fmt,
-			     unsigned int *nbuffers,
-			     unsigned int *nplanes, unsigned int sizes[],
-			     void *alloc_ctxs[])
-{
-	if (*nbuffers >= VIDEO_MAX_FRAME && *nbuffers < 5)
-		*nbuffers = 5;
-
-	*nplanes = 1;
-	return 0;
-}
-
-static int vp_in_buffer_init(struct vb2_buffer *vb)
-{
-	return 0;
-}
-
-static int vp_in_buffer_prepare(struct vb2_buffer *vb)
-{
-	return 0;
-}
-
-static void vp_in_buffer_queue(struct vb2_buffer *vb)
-{
-	struct vcap_client_data *cd = vb2_get_drv_priv(vb->vb2_queue);
-	struct vcap_buffer *buf = container_of(vb, struct vcap_buffer, vb);
-	struct vp_action *vp_act = &cd->vp_action;
-	struct vb2_queue *q = vb->vb2_queue;
-	unsigned long flags = 0;
-
-	spin_lock_irqsave(&cd->cap_slock, flags);
-	list_add_tail(&buf->list, &vp_act->in_active);
-	spin_unlock_irqrestore(&cd->cap_slock, flags);
-
-	if (atomic_read(&cd->dev->vp_enabled) == 0) {
-		if (cd->vp_action.vp_state == VP_FRAME1) {
-			if (atomic_read(&q->queued_count) > 1 &&
-				atomic_read(&cd->vp_out_vidq.queued_count) > 0)
-				/* Valid code flow for VC-VP mode */
-				kickoff_vp(cd);
-		} else {
-			/* VP has already kicked off just needs cont */
-			continue_vp(cd);
-		}
-	}
-}
-
-static int vp_in_start_streaming(struct vb2_queue *vq, unsigned int count)
-{
-	pr_debug("VP IN start streaming\n");
-	return 0;
-}
-
-static int vp_in_stop_streaming(struct vb2_queue *vq)
-{
-	struct vcap_client_data *c_data = vb2_get_drv_priv(vq);
-	struct vb2_buffer *vb;
-
-	pr_debug("VP IN stop streaming\n");
-	vp_stop_capture(c_data);
-
-	while (!list_empty(&c_data->vp_action.in_active)) {
-		struct vcap_buffer *buf;
-		buf = list_entry(c_data->vp_action.in_active.next,
-			struct vcap_buffer, list);
-		list_del(&buf->list);
-		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
-	}
-
-	/* clean ion handles */
-	list_for_each_entry(vb, &vq->queued_list, queued_entry)
-		free_ion_handle_work(c_data, vb);
-	return 0;
-}
-
-static int vp_in_buffer_finish(struct vb2_buffer *vb)
-{
-	return 0;
-}
-
-static void vp_in_buffer_cleanup(struct vb2_buffer *vb)
-{
-}
-
-static struct vb2_ops vp_in_video_qops = {
-	.queue_setup		= vp_in_queue_setup,
-	.wait_finish		= wait_finish,
-	.wait_prepare		= wait_prepare,
-	.buf_init			= vp_in_buffer_init,
-	.buf_prepare		= vp_in_buffer_prepare,
-	.buf_queue			= vp_in_buffer_queue,
-	.start_streaming	= vp_in_start_streaming,
-	.stop_streaming		= vp_in_stop_streaming,
-	.buf_finish			= vp_in_buffer_finish,
-	.buf_cleanup		= vp_in_buffer_cleanup,
-};
-
-
-/* VP O/P Videobuf operations */
-
-static int vp_out_queue_setup(struct vb2_queue *vq,
-			      const struct v4l2_format *fmt,
-			      unsigned int *nbuffers,
-			      unsigned int *nplanes, unsigned int sizes[],
-			      void *alloc_ctxs[])
-{
-	if (*nbuffers >= VIDEO_MAX_FRAME && *nbuffers < 3)
-		*nbuffers = 3;
-
-	*nplanes = 1;
-	return 0;
-}
-
-static int vp_out_buffer_init(struct vb2_buffer *vb)
-{
-	return 0;
-}
-
-static int vp_out_buffer_prepare(struct vb2_buffer *vb)
-{
-	return 0;
-}
-
-static void vp_out_buffer_queue(struct vb2_buffer *vb)
-{
-	struct vcap_client_data *cd = vb2_get_drv_priv(vb->vb2_queue);
-	struct vcap_buffer *buf = container_of(vb, struct vcap_buffer, vb);
-	struct vp_action *vp_act = &cd->vp_action;
-	struct vb2_queue *q = vb->vb2_queue;
-	unsigned long flags = 0;
-
-	spin_lock_irqsave(&cd->cap_slock, flags);
-	list_add_tail(&buf->list, &vp_act->out_active);
-	spin_unlock_irqrestore(&cd->cap_slock, flags);
-
-	if (atomic_read(&cd->dev->vp_enabled) == 0) {
-		if (cd->vp_action.vp_state == VP_FRAME1) {
-			if (atomic_read(&q->queued_count) > 0 &&
-				atomic_read(&
-					cd->vp_in_vidq.queued_count) > 1)
-				kickoff_vp(cd);
-		} else {
-			/* VP has already kicked off just needs cont */
-			continue_vp(cd);
-		}
-	}
-}
-
-static int vp_out_start_streaming(struct vb2_queue *vq, unsigned int count)
-{
-	return 0;
-}
-
-static int vp_out_stop_streaming(struct vb2_queue *vq)
-{
-	struct vcap_client_data *c_data = vb2_get_drv_priv(vq);
-	struct vb2_buffer *vb;
-
-	pr_debug("VP OUT q stop streaming\n");
-	vp_stop_capture(c_data);
-
-	while (!list_empty(&c_data->vp_action.out_active)) {
-		struct vcap_buffer *buf;
-		buf = list_entry(c_data->vp_action.out_active.next,
-			struct vcap_buffer, list);
-		list_del(&buf->list);
-		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
-	}
-
-	/* clean ion handles */
-	list_for_each_entry(vb, &vq->queued_list, queued_entry)
-		free_ion_handle_work(c_data, vb);
-	return 0;
-}
-
-static int vp_out_buffer_finish(struct vb2_buffer *vb)
-{
-	return 0;
-}
-
-static void vp_out_buffer_cleanup(struct vb2_buffer *vb)
-{
-}
-
-static struct vb2_ops vp_out_video_qops = {
-	.queue_setup		= vp_out_queue_setup,
-	.wait_finish		= wait_finish,
-	.wait_prepare		= wait_prepare,
-	.buf_init			= vp_out_buffer_init,
-	.buf_prepare		= vp_out_buffer_prepare,
-	.buf_queue			= vp_out_buffer_queue,
-	.start_streaming	= vp_out_start_streaming,
-	.stop_streaming		= vp_out_stop_streaming,
-	.buf_finish			= vp_out_buffer_finish,
-	.buf_cleanup		= vp_out_buffer_cleanup,
-};
-
-/* IOCTL vidioc handling */
-
-static int vidioc_querycap(struct file *file, void  *priv,
-					struct v4l2_capability *cap)
-{
-	struct vcap_dev *dev = video_drvdata(file);
-
-	strlcpy(cap->driver, MSM_VCAP_DRV_NAME, sizeof(cap->driver));
-	strlcpy(cap->card, MSM_VCAP_DRV_NAME, sizeof(cap->card));
-	strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info));
-	cap->version = 0x10000000;
-	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
-	return 0;
-}
-
-static int vidioc_enum_input(struct file *file, void *priv,
-				struct v4l2_input *inp)
-{
-	if (inp->index >= NUM_INPUTS)
-		return -EINVAL;
-	return 0;
-}
-
-static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
-					struct v4l2_format *f)
-{
-	return 0;
-}
-
-static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
-			struct v4l2_format *f)
-{
-	return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
-					struct v4l2_format *f)
-{
-	int size;
-	struct vcap_priv_fmt *priv_fmt;
-	struct v4l2_format_vc_ext *vc_format;
-	struct vcap_client_data *c_data = to_client_data(file->private_data);
-
-	priv_fmt = (struct vcap_priv_fmt *) f->fmt.raw_data;
-
-	switch (priv_fmt->type) {
-	case VC_TYPE:
-		vc_format = (struct v4l2_format_vc_ext *) &priv_fmt->u.timing;
-		c_data->vc_format = *vc_format;
-		c_data->stride = priv_fmt->stride;
-
-		size = (c_data->vc_format.hactive_end -
-			c_data->vc_format.hactive_start);
-		if (c_data->stride == VC_STRIDE_32)
-			size = VCAP_STRIDE_CALC(size, VCAP_STRIDE_ALIGN_32);
-		else
-			size = VCAP_STRIDE_CALC(size, VCAP_STRIDE_ALIGN_16);
-
-
-		if (c_data->vc_format.color_space)
-			size *= 3;
-		else
-			size *= 2;
-
-		priv_fmt->u.timing.bytesperline = size;
-		size *= (c_data->vc_format.vactive_end -
-			c_data->vc_format.vactive_start);
-		priv_fmt->u.timing.sizeimage = size;
-		c_data->set_cap = true;
-		break;
-	case VP_IN_TYPE:
-		c_data->vp_in_fmt.width = priv_fmt->u.pix.width;
-		c_data->vp_in_fmt.height = priv_fmt->u.pix.height;
-		c_data->vp_in_fmt.pixfmt = priv_fmt->u.pix.pixelformat;
-
-		size = c_data->vp_in_fmt.width * c_data->vp_in_fmt.height;
-		if (c_data->vp_in_fmt.pixfmt == V4L2_PIX_FMT_NV16)
-			size = size * 2;
-		else
-			size = size / 2 * 3;
-		priv_fmt->u.pix.sizeimage = size;
-		c_data->set_decode = true;
-		break;
-	case VP_OUT_TYPE:
-		c_data->vp_out_fmt.width = priv_fmt->u.pix.width;
-		c_data->vp_out_fmt.height = priv_fmt->u.pix.height;
-		c_data->vp_out_fmt.pixfmt = priv_fmt->u.pix.pixelformat;
-
-		size = c_data->vp_out_fmt.width * c_data->vp_out_fmt.height;
-		if (c_data->vp_out_fmt.pixfmt == V4L2_PIX_FMT_NV16)
-			size = size * 2;
-		else
-			size = size / 2 * 3;
-		priv_fmt->u.pix.sizeimage = size;
-		c_data->set_vp_o = true;
-		break;
-	default:
-		break;
-	}
-
-	return 0;
-}
-
-static int vidioc_reqbufs(struct file *file, void *priv,
-			  struct v4l2_requestbuffers *rb)
-{
-	struct vcap_client_data *c_data = to_client_data(file->private_data);
-	struct vcap_dev *dev = c_data->dev;
-	int rc;
-
-	pr_debug("VCAP: In Req Buf %08x\n", (unsigned int)rb->type);
-	c_data->op_mode = determine_mode(c_data);
-	if (c_data->op_mode == UNKNOWN_VCAP_OP) {
-		pr_err("VCAP Error: %s: VCAP in unknown mode\n", __func__);
-		return -ENOTRECOVERABLE;
-	}
-
-	switch (rb->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-		if (c_data->op_mode == VC_AND_VP_VCAP_OP) {
-			if (c_data->vc_format.color_space) {
-				pr_err("VCAP Err: %s: VP No RGB support\n",
-					__func__);
-				return -ENOTRECOVERABLE;
-			}
-			if (!c_data->vc_format.mode) {
-				pr_err("VCAP Err: VP No prog support\n");
-				return -ENOTRECOVERABLE;
-			}
-			if (rb->count <= VCAP_VP_MIN_BUF) {
-				pr_err("VCAP Err: Not enough buf for VC_VP\n");
-				return -EINVAL;
-			}
-			rc = vb2_reqbufs(&c_data->vc_vidq, rb);
-			if (rc < 0)
-				return rc;
-
-			c_data->vp_in_fmt.width =
-				(c_data->vc_format.hactive_end -
-				c_data->vc_format.hactive_start);
-			c_data->vp_in_fmt.height =
-				(c_data->vc_format.vactive_end -
-				c_data->vc_format.vactive_start);
-			/* VC outputs YCbCr 4:2:2 */
-			c_data->vp_in_fmt.pixfmt = V4L2_PIX_FMT_NV16;
-			rb->type = V4L2_BUF_TYPE_INTERLACED_IN_DECODER;
-			rc = vb2_reqbufs(&c_data->vp_in_vidq, rb);
-			rb->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-			c_data->vc_action.tot_buf = dev->vc_tot_buf;
-			return rc;
-
-		} else {
-			rc = vb2_reqbufs(&c_data->vc_vidq, rb);
-			c_data->vc_action.tot_buf = dev->vc_tot_buf;
-			return rc;
-		}
-	case V4L2_BUF_TYPE_INTERLACED_IN_DECODER:
-		return vb2_reqbufs(&c_data->vp_in_vidq, rb);
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-		return vb2_reqbufs(&c_data->vp_out_vidq, rb);
-	default:
-		pr_err("VCAP Error: %s: Unknown buffer type\n", __func__);
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
-	struct vcap_client_data *c_data = to_client_data(file->private_data);
-
-	switch (p->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-		return vb2_querybuf(&c_data->vc_vidq, p);
-	default:
-		pr_err("VCAP Error: %s: Unknown buffer type\n", __func__);
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
-	struct vcap_client_data *c_data = to_client_data(file->private_data);
-	struct vb2_buffer *vb;
-	struct vb2_queue *q;
-	int rc;
-
-	pr_debug("VCAP In Q Buf %08x\n", (unsigned int)p->type);
-	switch (p->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-		if (c_data->op_mode == VC_AND_VP_VCAP_OP) {
-			/* If buffer in vp_in_q it will be coming back */
-			q = &c_data->vp_in_vidq;
-			if (p->index >= q->num_buffers) {
-				pr_debug("VCAP qbuf: buffer index out of range\n");
-				return -EINVAL;
-			}
-
-			vb = q->bufs[p->index];
-			if (NULL == vb) {
-				pr_debug("VCAP qbuf: buffer is NULL\n");
-				return -EINVAL;
-			}
-
-			if (vb->state != VB2_BUF_STATE_DEQUEUED) {
-				pr_debug("VCAP qbuf: buffer already in use\n");
-				return -EINVAL;
-			}
-			rc = get_phys_addr(c_data->dev, &c_data->vc_vidq, p);
-			if (rc < 0)
-				return rc;
-			rc = vcvp_qbuf(&c_data->vc_vidq, p);
-			if (rc < 0)
-				free_ion_handle(c_data,
-					&c_data->vc_vidq, p);
-			return rc;
-		}
-		rc = get_phys_addr(c_data->dev, &c_data->vc_vidq, p);
-		if (rc < 0)
-			return rc;
-		mutex_lock(&c_data->mutex);
-		rc = vb2_qbuf(&c_data->vc_vidq, p);
-		mutex_unlock(&c_data->mutex);
-		if (rc < 0)
-			free_ion_handle(c_data, &c_data->vc_vidq, p);
-		return rc;
-	case V4L2_BUF_TYPE_INTERLACED_IN_DECODER:
-		if (c_data->op_mode == VC_AND_VP_VCAP_OP)
-			return -EINVAL;
-		rc = get_phys_addr(c_data->dev, &c_data->vp_in_vidq, p);
-		if (rc < 0)
-			return rc;
-		mutex_lock(&c_data->mutex);
-		rc = vb2_qbuf(&c_data->vp_in_vidq, p);
-		mutex_unlock(&c_data->mutex);
-		if (rc < 0)
-			free_ion_handle(c_data, &c_data->vp_in_vidq, p);
-		return rc;
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-		rc = get_phys_addr(c_data->dev, &c_data->vp_out_vidq, p);
-		if (rc < 0)
-			return rc;
-		mutex_lock(&c_data->mutex);
-		rc = vb2_qbuf(&c_data->vp_out_vidq, p);
-		mutex_unlock(&c_data->mutex);
-		if (rc < 0)
-			free_ion_handle(c_data, &c_data->vp_out_vidq, p);
-		return rc;
-	default:
-		pr_err("VCAP Error: %s: Unknown buffer type\n", __func__);
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
-	struct vcap_client_data *c_data = to_client_data(file->private_data);
-	int rc;
-
-	if (c_data->streaming == 0)
-		return -EPERM;
-
-	pr_debug("VCAP In DQ Buf %08x\n", (unsigned int)p->type);
-	switch (p->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-		if (c_data->op_mode == VC_AND_VP_VCAP_OP)
-			return -EINVAL;
-		mutex_lock(&c_data->mutex);
-		rc = vb2_dqbuf(&c_data->vc_vidq, p, file->f_flags & O_NONBLOCK);
-		mutex_unlock(&c_data->mutex);
-		if (rc < 0)
-			return rc;
-		return free_ion_handle(c_data, &c_data->vc_vidq, p);
-	case V4L2_BUF_TYPE_INTERLACED_IN_DECODER:
-		if (c_data->op_mode == VC_AND_VP_VCAP_OP)
-			return -EINVAL;
-		mutex_lock(&c_data->mutex);
-		rc = vb2_dqbuf(&c_data->vp_in_vidq, p, file->f_flags &
-				O_NONBLOCK);
-		mutex_unlock(&c_data->mutex);
-		if (rc < 0)
-			return rc;
-		return free_ion_handle(c_data, &c_data->vp_in_vidq, p);
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-		mutex_lock(&c_data->mutex);
-		rc = vb2_dqbuf(&c_data->vp_out_vidq, p, file->f_flags &
-				O_NONBLOCK);
-		mutex_unlock(&c_data->mutex);
-		if (rc < 0)
-			return rc;
-		return free_ion_handle(c_data, &c_data->vp_out_vidq, p);
-	default:
-		pr_err("VCAP Error: %s: Unknown buffer type", __func__);
-		return -EINVAL;
-	}
-	return 0;
-}
-
-/*
- * When calling streamon on multiple queues there is a need to first verify
- * that the steamon will succeed on all queues, similarly for streamoff
- */
-int streamon_validate_q(struct vb2_queue *q)
-{
-	if (q->fileio) {
-		pr_debug("%s: file io in progress\n", __func__);
-		return -EBUSY;
-	}
-
-	if (q->streaming) {
-		pr_debug("%s: already streaming\n", __func__);
-		return -EBUSY;
-	}
-
-	if (V4L2_TYPE_IS_OUTPUT(q->type)) {
-		if (list_empty(&q->queued_list)) {
-			pr_debug("%s: no output buffers queued\n", __func__);
-			return -EINVAL;
-		}
-	}
-	return 0;
-}
-
-int request_bus_bw(struct vcap_dev *dev, unsigned long rate)
-{
-	struct msm_bus_paths *bus_vectors;
-	int idx, length;
-	bus_vectors = dev->vcap_pdata->bus_client_pdata->usecase;
-	length = dev->vcap_pdata->bus_client_pdata->num_usecases;
-	idx = 0;
-	do {
-		if (rate <= bus_vectors[idx].vectors[0].ab)
-			break;
-		idx++;
-	} while (idx < length);
-	if (idx == length) {
-		pr_info("VCAP: Defaulting to highest BW request\n");
-		idx--;
-	}
-	msm_bus_scale_client_update_request(dev->bus_client_handle, idx);
-	dev->dbg_p.bw_request = bus_vectors[idx].vectors[0].ab;
-	return 0;
-}
-
-static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
-{
-	struct vcap_client_data *c_data = to_client_data(file->private_data);
-	struct vcap_dev *dev = c_data->dev;
-	int rc;
-	unsigned long rate;
-	long rate_rc;
-
-	pr_debug("VCAP: In Stream ON\n");
-	if (determine_mode(c_data) != c_data->op_mode) {
-		pr_err("VCAP Error: %s: s_fmt called after req_buf", __func__);
-		return -ENOTRECOVERABLE;
-	}
-
-	if (!dev->vp_dummy_complete) {
-		pr_err("VCAP Err: %s: VP dummy read not complete",
-			__func__);
-		return -EINVAL;
-	}
-
-	switch (c_data->op_mode) {
-	case VC_VCAP_OP:
-		mutex_lock(&dev->dev_mutex);
-		if (dev->vc_resource) {
-			pr_err("VCAP Err: %s: VC resource taken", __func__);
-			mutex_unlock(&dev->dev_mutex);
-			return -EBUSY;
-		}
-		dev->vc_resource = 1;
-		mutex_unlock(&dev->dev_mutex);
-
-		c_data->dev->vc_client = c_data;
-
-		if (!c_data->vc_format.clk_freq) {
-			rc = -EINVAL;
-			goto free_res;
-		}
-
-		rate = c_data->vc_format.clk_freq / 100 * 102;
-		rate_rc = clk_round_rate(dev->vcap_clk, rate);
-		if (rate_rc <= 0) {
-			pr_err("%s: Failed core rnd_rate\n", __func__);
-			rc = -EINVAL;
-			goto free_res;
-		}
-		rate = (unsigned long)rate_rc;
-		rc = clk_set_rate(dev->vcap_clk, rate);
-		if (rc < 0)
-			goto free_res;
-
-		dev->dbg_p.clk_rate = (uint32_t) rate;
-
-		rate = (c_data->vc_format.hactive_end -
-			c_data->vc_format.hactive_start);
-
-		if (c_data->vc_format.color_space)
-			rate *= 3;
-		else
-			rate *= 2;
-
-		rate *= (c_data->vc_format.vactive_end -
-			c_data->vc_format.vactive_start);
-		rate *= c_data->vc_format.frame_rate;
-		if (rate == 0)
-			goto free_res;
-
-		rc = request_bus_bw(dev, rate);
-		if (rc < 0)
-			goto free_res;
-
-		config_vc_format(c_data);
-		c_data->streaming = 1;
-		rc = vb2_streamon(&c_data->vc_vidq, i);
-		if (rc < 0)
-			goto free_res;
-		break;
-	case VP_VCAP_OP:
-		mutex_lock(&dev->dev_mutex);
-		if (dev->vp_resource) {
-			pr_err("VCAP Err: %s: VP resource taken", __func__);
-			mutex_unlock(&dev->dev_mutex);
-			return -EBUSY;
-		}
-		dev->vp_resource = 1;
-		mutex_unlock(&dev->dev_mutex);
-		c_data->dev->vp_client = c_data;
-
-		rate = 160000000;
-		rate_rc = clk_round_rate(dev->vcap_clk, rate);
-		if (rate_rc <= 0) {
-			pr_err("%s: Failed core rnd_rate\n", __func__);
-			rc = -EINVAL;
-			goto free_res;
-		}
-		rate = (unsigned long)rate_rc;
-		rc = clk_set_rate(dev->vcap_clk, rate);
-
-		dev->dbg_p.clk_rate = (uint32_t) rate;
-		if (rc < 0)
-			goto free_res;
-
-		rate = c_data->vp_out_fmt.width *
-			c_data->vp_out_fmt.height * 240;
-		rc = request_bus_bw(dev, rate);
-		if (rc < 0)
-			goto free_res;
-
-		rc = streamon_validate_q(&c_data->vp_in_vidq);
-		if (rc < 0)
-			goto free_res;
-		rc = streamon_validate_q(&c_data->vp_out_vidq);
-		if (rc < 0)
-			goto free_res;
-
-		rc = config_vp_format(c_data);
-		if (rc < 0)
-			goto free_res;
-		rc = init_motion_buf(c_data);
-		if (rc < 0)
-			goto free_res;
-		if (dev->nr_param.mode) {
-			rc = init_nr_buf(c_data);
-			if (rc < 0)
-				goto s_on_deinit_m_buf;
-		}
-
-		c_data->vp_action.vp_state = VP_FRAME1;
-		c_data->streaming = 1;
-
-		rc = vb2_streamon(&c_data->vp_in_vidq,
-				V4L2_BUF_TYPE_INTERLACED_IN_DECODER);
-		if (rc < 0)
-			goto s_on_deinit_nr_buf;
-
-		rc = vb2_streamon(&c_data->vp_out_vidq,
-				V4L2_BUF_TYPE_VIDEO_OUTPUT);
-		if (rc < 0)
-			goto s_on_deinit_nr_buf;
-		break;
-	case VC_AND_VP_VCAP_OP:
-		mutex_lock(&dev->dev_mutex);
-		if (dev->vc_resource || dev->vp_resource) {
-			pr_err("VCAP Err: %s: VC/VP resource taken",
-				__func__);
-			mutex_unlock(&dev->dev_mutex);
-			return -EBUSY;
-		}
-		dev->vc_resource = 1;
-		dev->vp_resource = 1;
-		mutex_unlock(&dev->dev_mutex);
-		c_data->dev->vc_client = c_data;
-		c_data->dev->vp_client = c_data;
-
-		if (!c_data->vc_format.clk_freq) {
-			rc = -EINVAL;
-			goto free_res;
-		}
-
-		rate = c_data->vc_format.clk_freq / 100 * 102;
-		if ((c_data->vc_format.hactive_end -
-				c_data->vc_format.hactive_start) > 539)
-			rate = 200000000;
-		rate_rc = clk_round_rate(dev->vcap_clk, rate);
-		if (rate_rc <= 0) {
-			pr_err("%s: Failed core rnd_rate\n", __func__);
-			rc = -EINVAL;
-			goto free_res;
-		}
-		rate = (unsigned long)rate_rc;
-		rc = clk_set_rate(dev->vcap_clk, rate);
-		if (rc < 0)
-			goto free_res;
-
-		dev->dbg_p.clk_rate = (uint32_t) rate;
-
-		rate = (c_data->vc_format.hactive_end -
-			c_data->vc_format.hactive_start);
-
-		if (c_data->vc_format.color_space)
-			rate *= 3;
-		else
-			rate *= 2;
-
-		rate *= (c_data->vc_format.vactive_end -
-			c_data->vc_format.vactive_start);
-		rate *= c_data->vc_format.frame_rate;
-		rate *= 2;
-		if (rate == 0)
-			goto free_res;
-
-		rc = request_bus_bw(dev, rate);
-		if (rc < 0)
-			goto free_res;
-
-		rc = streamon_validate_q(&c_data->vc_vidq);
-		if (rc < 0)
-			return rc;
-		rc = streamon_validate_q(&c_data->vp_in_vidq);
-		if (rc < 0)
-			goto free_res;
-		rc = streamon_validate_q(&c_data->vp_out_vidq);
-		if (rc < 0)
-			goto free_res;
-
-		rc = config_vc_format(c_data);
-		if (rc < 0)
-			goto free_res;
-		rc = config_vp_format(c_data);
-		if (rc < 0)
-			goto free_res;
-		rc = init_motion_buf(c_data);
-		if (rc < 0)
-			goto free_res;
-
-		if (dev->nr_param.mode) {
-			rc = init_nr_buf(c_data);
-			if (rc < 0)
-				goto s_on_deinit_m_buf;
-		}
-
-		c_data->dev->vc_to_vp_work.cd = c_data;
-		c_data->vp_action.vp_state = VP_FRAME1;
-		c_data->streaming = 1;
-
-		/* These stream on calls should not fail */
-		rc = vb2_streamon(&c_data->vc_vidq,
-				V4L2_BUF_TYPE_VIDEO_CAPTURE);
-		if (rc < 0)
-			goto s_on_deinit_nr_buf;
-
-		rc = vb2_streamon(&c_data->vp_in_vidq,
-				V4L2_BUF_TYPE_INTERLACED_IN_DECODER);
-		if (rc < 0)
-			goto s_on_deinit_nr_buf;
-
-		rc = vb2_streamon(&c_data->vp_out_vidq,
-				V4L2_BUF_TYPE_VIDEO_OUTPUT);
-		if (rc < 0)
-			goto s_on_deinit_nr_buf;
-		break;
-	default:
-		pr_err("VCAP Error: %s: Operation Mode type", __func__);
-		return -ENOTRECOVERABLE;
-	}
-	return 0;
-
-s_on_deinit_nr_buf:
-	if (dev->nr_param.mode)
-		deinit_nr_buf(c_data);
-s_on_deinit_m_buf:
-	deinit_motion_buf(c_data);
-free_res:
-	mutex_lock(&dev->dev_mutex);
-	if (c_data->op_mode == VC_VCAP_OP) {
-		dev->vc_resource = 0;
-		c_data->dev->vc_client = NULL;
-	} else if (c_data->op_mode == VP_VCAP_OP) {
-		dev->vp_resource = 0;
-		c_data->dev->vp_client = NULL;
-	} else if (c_data->op_mode == VC_AND_VP_VCAP_OP) {
-		c_data->dev->vc_client = NULL;
-		c_data->dev->vp_client = NULL;
-		dev->vc_resource = 0;
-		dev->vp_resource = 0;
-	}
-	mutex_unlock(&dev->dev_mutex);
-	return rc;
-}
-
-int streamoff_validate_q(struct vb2_queue *q)
-{
-	if (q->fileio) {
-		pr_debug("%s: file io in progress\n", __func__);
-		return -EBUSY;
-	}
-
-	if (!q->streaming) {
-		pr_debug("%s: not streaming\n", __func__);
-		return -EINVAL;
-	}
-	return 0;
-}
-
-int streamoff_work(struct vcap_client_data *c_data)
-{
-	struct vcap_dev *dev = c_data->dev;
-	int rc;
-	switch (c_data->op_mode) {
-	case VC_VCAP_OP:
-		if (c_data != dev->vc_client) {
-			pr_err("VCAP Err: %s: VC held by other client",
-				__func__);
-			return -EBUSY;
-		}
-		mutex_lock(&dev->dev_mutex);
-		if (!dev->vc_resource) {
-			pr_err("VCAP Err: %s: VC res not acquired", __func__);
-			mutex_unlock(&dev->dev_mutex);
-			return -EBUSY;
-		}
-		dev->vc_resource = 0;
-		mutex_unlock(&dev->dev_mutex);
-		c_data->streaming = 0;
-		mutex_lock(&c_data->mutex);
-		rc = vb2_streamoff(&c_data->vc_vidq,
-				V4L2_BUF_TYPE_VIDEO_CAPTURE);
-		mutex_unlock(&c_data->mutex);
-		if (rc >= 0)
-			atomic_set(&c_data->dev->vc_enabled, 0);
-		return rc;
-	case VP_VCAP_OP:
-		if (c_data != dev->vp_client) {
-			pr_err("VCAP Err: %s: VP held by other client",
-				__func__);
-			return -EBUSY;
-		}
-		mutex_lock(&dev->dev_mutex);
-		if (!dev->vp_resource) {
-			pr_err("VCAP Err: %s: VP res not acquired", __func__);
-			mutex_unlock(&dev->dev_mutex);
-			return -EBUSY;
-		}
-		dev->vp_resource = 0;
-		mutex_unlock(&dev->dev_mutex);
-		rc = streamoff_validate_q(&c_data->vp_in_vidq);
-		if (rc < 0)
-			return rc;
-		rc = streamoff_validate_q(&c_data->vp_out_vidq);
-		if (rc < 0)
-			return rc;
-		c_data->streaming = 0;
-
-		mutex_unlock(&dev->dev_mutex);
-		/* These stream on calls should not fail */
-		rc = vb2_streamoff(&c_data->vp_in_vidq,
-				V4L2_BUF_TYPE_INTERLACED_IN_DECODER);
-		if (rc < 0) {
-			mutex_unlock(&c_data->mutex);
-			return rc;
-		}
-
-		rc = vb2_streamoff(&c_data->vp_out_vidq,
-				V4L2_BUF_TYPE_VIDEO_OUTPUT);
-		mutex_unlock(&c_data->mutex);
-		if (rc < 0)
-			return rc;
-
-		deinit_motion_buf(c_data);
-		if (dev->nr_param.mode)
-			deinit_nr_buf(c_data);
-		atomic_set(&c_data->dev->vp_enabled, 0);
-		return rc;
-	case VC_AND_VP_VCAP_OP:
-		if (c_data != dev->vp_client || c_data != dev->vc_client) {
-			pr_err("VCAP Err: %s: VC/VP held by other client",
-				__func__);
-			return -EBUSY;
-		}
-		mutex_lock(&dev->dev_mutex);
-		if (!(dev->vc_resource || dev->vp_resource)) {
-			pr_err("VCAP Err: %s: VC or VP res not acquired",
-				__func__);
-			mutex_unlock(&dev->dev_mutex);
-			return -EBUSY;
-		}
-		dev->vc_resource = 0;
-		dev->vp_resource = 0;
-		mutex_unlock(&dev->dev_mutex);
-		rc = streamoff_validate_q(&c_data->vc_vidq);
-		if (rc < 0)
-			return rc;
-		rc = streamoff_validate_q(&c_data->vp_in_vidq);
-		if (rc < 0)
-			return rc;
-		rc = streamoff_validate_q(&c_data->vp_out_vidq);
-		if (rc < 0)
-			return rc;
-
-		c_data->streaming = 0;
-		mutex_lock(&c_data->mutex);
-		/* These stream on calls should not fail */
-		rc = vb2_streamoff(&c_data->vc_vidq,
-				V4L2_BUF_TYPE_VIDEO_CAPTURE);
-		if (rc < 0) {
-			mutex_unlock(&c_data->mutex);
-			return rc;
-		}
-
-		rc = vb2_streamoff(&c_data->vp_in_vidq,
-				V4L2_BUF_TYPE_INTERLACED_IN_DECODER);
-		if (rc < 0) {
-			mutex_unlock(&c_data->mutex);
-			return rc;
-		}
-
-		rc = vb2_streamoff(&c_data->vp_out_vidq,
-				V4L2_BUF_TYPE_VIDEO_OUTPUT);
-		mutex_unlock(&c_data->mutex);
-		if (rc < 0)
-			return rc;
-
-		deinit_motion_buf(c_data);
-		if (dev->nr_param.mode)
-			deinit_nr_buf(c_data);
-		atomic_set(&c_data->dev->vc_enabled, 0);
-		atomic_set(&c_data->dev->vp_enabled, 0);
-		return rc;
-	default:
-		pr_err("VCAP Error: %s: Unknown Operation mode", __func__);
-		return -ENOTRECOVERABLE;
-	}
-}
-
-static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
-	struct vcap_client_data *c_data = to_client_data(file->private_data);
-	return streamoff_work(c_data);
-}
-
-static int vidioc_subscribe_event(struct v4l2_fh *fh,
-			struct v4l2_event_subscription *sub)
-{
-	int rc;
-	if (sub->type == V4L2_EVENT_ALL) {
-		sub->type = V4L2_EVENT_PRIVATE_START +
-				VCAP_GENERIC_NOTIFY_EVENT;
-		sub->id = 0;
-		do {
-			rc = v4l2_event_subscribe(fh, sub, 16);
-			if (rc < 0) {
-				sub->type = V4L2_EVENT_ALL;
-				v4l2_event_unsubscribe(fh, sub);
-				return rc;
-			}
-			sub->type++;
-		} while (sub->type !=
-			V4L2_EVENT_PRIVATE_START + VCAP_MAX_NOTIFY_EVENT);
-	} else {
-		rc = v4l2_event_subscribe(fh, sub, 16);
-	}
-	return rc;
-}
-
-static int vidioc_unsubscribe_event(struct v4l2_fh *fh,
-			struct v4l2_event_subscription *sub)
-{
-	return v4l2_event_unsubscribe(fh, sub);
-}
-
-static long vidioc_default(struct file *file, void *fh, bool valid_prio,
-						int cmd, void *arg)
-{
-	struct vcap_client_data *c_data = to_client_data(file->private_data);
-	struct vcap_dev *dev = c_data->dev;
-	struct nr_param *param;
-	int	val;
-	unsigned long flags = 0;
-	int ret;
-
-	switch (cmd) {
-	case VCAPIOC_NR_S_PARAMS:
-
-		if (c_data->streaming != 0 &&
-				(!(!((struct nr_param *) arg)->mode) !=
-				!(!(dev->nr_param.mode)))) {
-			pr_err("ERR: Trying to toggle on/off while VP is already running");
-			return -EBUSY;
-		}
-
-
-		spin_lock_irqsave(&c_data->cap_slock, flags);
-		ret = nr_s_param(c_data, (struct nr_param *) arg);
-		if (ret < 0) {
-			spin_unlock_irqrestore(&c_data->cap_slock, flags);
-			return ret;
-		}
-		param = (struct nr_param *) arg;
-		dev->nr_param = *param;
-		if (param->mode == NR_AUTO)
-			s_default_nr_val(&dev->nr_param);
-		dev->nr_update = true;
-		spin_unlock_irqrestore(&c_data->cap_slock, flags);
-		break;
-	case VCAPIOC_NR_G_PARAMS:
-		*((struct nr_param *)arg) = dev->nr_param;
-		if (dev->nr_param.mode != NR_DISABLE) {
-			if (c_data->streaming)
-				nr_g_param(c_data, (struct nr_param *) arg);
-			else
-				(*(struct nr_param *) arg) =
-					dev->nr_param;
-		}
-		break;
-	case VCAPIOC_S_NUM_VC_BUF:
-		val = (*(int *) arg);
-		if (val < VCAP_VC_MIN_BUF || val > VCAP_VC_MAX_BUF)
-			return -EINVAL;
-		dev->vc_tot_buf = (uint8_t) val;
-		break;
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
-/* VCAP fops */
-static void *vcap_ops_get_userptr(void *alloc_ctx, unsigned long vaddr,
-					unsigned long size, int write)
-{
-	struct vcap_buf_info *mem;
-	mem = kzalloc(sizeof(*mem), GFP_KERNEL);
-	if (!mem)
-		return ERR_PTR(-ENOMEM);
-	mem->vaddr = vaddr;
-	mem->size = size;
-	return mem;
-}
-
-static void vcap_ops_put_userptr(void *buf_priv)
-{
-	kfree(buf_priv);
-}
-
-const struct vb2_mem_ops vcap_mem_ops = {
-	.get_userptr =		vcap_ops_get_userptr,
-	.put_userptr =		vcap_ops_put_userptr,
-};
-
-static int vcap_open(struct file *file)
-{
-	struct vcap_dev *dev = video_drvdata(file);
-	struct vcap_client_data *c_data;
-	struct vb2_queue *q;
-	int ret;
-	if (!dev)
-		return -EINVAL;
-	c_data = kzalloc(sizeof(*c_data), GFP_KERNEL);
-	if (!c_data)
-		return -ENOMEM;
-
-	c_data->dev = dev;
-
-	spin_lock_init(&c_data->cap_slock);
-	mutex_init(&c_data->mutex);
-
-	/* initialize vc queue */
-	q = &c_data->vc_vidq;
-	memset(q, 0, sizeof(c_data->vc_vidq));
-	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	q->io_modes = VB2_USERPTR;
-	q->drv_priv = c_data;
-	q->buf_struct_size = sizeof(struct vcap_buffer);
-	q->ops = &capture_video_qops;
-	q->mem_ops = &vcap_mem_ops;
-	ret = vb2_queue_init(q);
-	if (ret < 0)
-		goto vc_q_failed;
-
-	/* initialize vp in queue */
-	q = &c_data->vp_in_vidq;
-	memset(q, 0, sizeof(c_data->vp_in_vidq));
-	q->type = V4L2_BUF_TYPE_INTERLACED_IN_DECODER;
-	q->io_modes = VB2_USERPTR;
-	q->drv_priv = c_data;
-	q->buf_struct_size = sizeof(struct vcap_buffer);
-	q->ops = &vp_in_video_qops;
-	q->mem_ops = &vcap_mem_ops;
-	ret = vb2_queue_init(q);
-	if (ret < 0)
-		goto vp_in_q_failed;
-
-	/* initialize vp out queue */
-	q = &c_data->vp_out_vidq;
-	memset(q, 0, sizeof(c_data->vp_out_vidq));
-	q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-	q->io_modes = VB2_USERPTR;
-	q->drv_priv = c_data;
-	q->buf_struct_size = sizeof(struct vcap_buffer);
-	q->ops = &vp_out_video_qops;
-	q->mem_ops = &vcap_mem_ops;
-
-	ret = vb2_queue_init(q);
-	if (ret < 0)
-		goto vp_out_q_failed;
-
-	INIT_LIST_HEAD(&c_data->vc_action.active);
-	INIT_LIST_HEAD(&c_data->vp_action.in_active);
-	INIT_LIST_HEAD(&c_data->vp_action.out_active);
-
-	v4l2_fh_init(&c_data->vfh, dev->vfd);
-	v4l2_fh_add(&c_data->vfh);
-
-	mutex_lock(&dev->dev_mutex);
-	atomic_inc(&dev->open_clients);
-	ret = atomic_read(&dev->open_clients);
-	if (ret == 1) {
-		ret = vcap_enable(dev, dev->ddev, 54860000);
-		if (ret < 0) {
-			pr_err("Err: %s: Power on vcap failed", __func__);
-			mutex_unlock(&dev->dev_mutex);
-			goto vcap_power_failed;
-		}
-
-		ret = vp_dummy_event(c_data);
-		if (ret < 0) {
-			pr_err("Err: %s: Dummy Event failed", __func__);
-			mutex_unlock(&dev->dev_mutex);
-			vcap_disable(dev);
-			goto vcap_power_failed;
-		}
-	}
-	mutex_unlock(&dev->dev_mutex);
-
-	file->private_data = &c_data->vfh;
-	return 0;
-
-vcap_power_failed:
-	atomic_dec(&dev->open_clients);
-
-	v4l2_fh_del(&c_data->vfh);
-	v4l2_fh_exit(&c_data->vfh);
-	vb2_queue_release(&c_data->vp_out_vidq);
-vp_out_q_failed:
-	vb2_queue_release(&c_data->vp_in_vidq);
-vp_in_q_failed:
-	vb2_queue_release(&c_data->vc_vidq);
-vc_q_failed:
-	mutex_destroy(&c_data->mutex);
-	kfree(c_data);
-	return ret;
-}
-
-static int vcap_close(struct file *file)
-{
-	struct vcap_dev *dev = video_drvdata(file);
-	struct vcap_client_data *c_data = to_client_data(file->private_data);
-	int ret;
-
-	if (c_data == NULL)
-		return 0;
-
-	if (c_data->streaming)
-		streamoff_work(c_data);
-
-	mutex_lock(&dev->dev_mutex);
-	atomic_dec(&dev->open_clients);
-	ret = atomic_read(&dev->open_clients);
-	mutex_unlock(&dev->dev_mutex);
-	if (ret == 0) {
-		vcap_disable(dev);
-		dev->vc_tot_buf = 2;
-		dev->vp_dummy_complete = false;
-	}
-	v4l2_fh_del(&c_data->vfh);
-	v4l2_fh_exit(&c_data->vfh);
-	free_ion_on_q_bufs(&c_data->vp_out_vidq);
-	free_ion_on_q_bufs(&c_data->vp_in_vidq);
-	free_ion_on_q_bufs(&c_data->vc_vidq);
-
-	vb2_queue_release(&c_data->vp_out_vidq);
-	vb2_queue_release(&c_data->vp_in_vidq);
-	vb2_queue_release(&c_data->vc_vidq);
-	if (c_data->dev->vc_client == c_data)
-		c_data->dev->vc_client = NULL;
-	if (c_data->dev->vp_client == c_data)
-		c_data->dev->vp_client = NULL;
-	mutex_destroy(&c_data->mutex);
-	kfree(c_data);
-	return 0;
-}
-
-unsigned int poll_work(struct vb2_queue *q, struct file *file,
-	poll_table *wait, bool write_q)
-{
-	unsigned long flags;
-	struct vb2_buffer *vb = NULL;
-
-	if (q->num_buffers == 0)
-		return POLLERR;
-
-	if (list_empty(&q->queued_list))
-		return POLLERR;
-
-	poll_wait(file, &q->done_wq, wait);
-
-	spin_lock_irqsave(&q->done_lock, flags);
-	if (!list_empty(&q->done_list))
-		vb = list_first_entry(&q->done_list, struct vb2_buffer,
-					done_entry);
-	spin_unlock_irqrestore(&q->done_lock, flags);
-
-	if (vb && (vb->state == VB2_BUF_STATE_DONE
-			|| vb->state == VB2_BUF_STATE_ERROR)) {
-		return (write_q) ? POLLOUT | POLLWRNORM :
-			POLLIN | POLLRDNORM;
-	}
-	return 0;
-}
-
-static unsigned int vcap_poll(struct file *file,
-				  struct poll_table_struct *wait)
-{
-	struct vcap_client_data *c_data = to_client_data(file->private_data);
-	struct vb2_queue *q;
-	unsigned int mask = 0;
-
-	if (c_data->streaming == 0)
-		return 0;
-
-	pr_debug("%s: Enter slect/poll\n", __func__);
-
-	switch (c_data->op_mode) {
-	case VC_VCAP_OP:
-		q = &c_data->vc_vidq;
-		mask = vb2_poll(q, file, wait);
-		break;
-	case VP_VCAP_OP:
-		q = &c_data->vp_in_vidq;
-		mask = poll_work(q, file, wait, 0);
-		q = &c_data->vp_out_vidq;
-		mask |= poll_work(q, file, wait, 1);
-		break;
-	case VC_AND_VP_VCAP_OP:
-		q = &c_data->vp_out_vidq;
-		mask = poll_work(q, file, wait, 0);
-		break;
-	default:
-		pr_err("VCAP Error: %s: Unknown operation mode", __func__);
-		return POLLERR;
-	}
-	if (v4l2_event_pending(&c_data->vfh))
-		mask |= POLLPRI;
-	poll_wait(file, &(c_data->vfh.wait), wait);
-	return mask;
-}
-/* V4L2 and video device structures */
-
-static const struct v4l2_file_operations vcap_fops = {
-	.owner		= THIS_MODULE,
-	.open		= vcap_open,
-	.release	= vcap_close,
-	.poll		= vcap_poll,
-	.unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
-};
-
-static const struct v4l2_ioctl_ops vcap_ioctl_ops = {
-	.vidioc_querycap      = vidioc_querycap,
-	.vidioc_enum_input    = vidioc_enum_input,
-	.vidioc_g_fmt_vid_cap     = vidioc_g_fmt_vid_cap,
-	.vidioc_try_fmt_vid_cap   = vidioc_try_fmt_vid_cap,
-	.vidioc_s_fmt_vid_cap     = vidioc_s_fmt_vid_cap,
-	.vidioc_s_fmt_type_private     = vidioc_s_fmt_vid_cap,
-	.vidioc_g_fmt_type_private     = vidioc_g_fmt_vid_cap,
-	.vidioc_s_fmt_vid_out_mplane	= vidioc_s_fmt_vid_cap,
-	.vidioc_g_fmt_vid_out_mplane	= vidioc_g_fmt_vid_cap,
-	.vidioc_reqbufs       = vidioc_reqbufs,
-	.vidioc_querybuf      = vidioc_querybuf,
-	.vidioc_qbuf          = vidioc_qbuf,
-	.vidioc_dqbuf         = vidioc_dqbuf,
-	.vidioc_streamon      = vidioc_streamon,
-	.vidioc_streamoff     = vidioc_streamoff,
-
-	.vidioc_subscribe_event = vidioc_subscribe_event,
-	.vidioc_unsubscribe_event = vidioc_unsubscribe_event,
-	.vidioc_default = vidioc_default,
-};
-
-static struct video_device vcap_template = {
-	.name		= "vcap",
-	.fops		= &vcap_fops,
-	.ioctl_ops	= &vcap_ioctl_ops,
-	.release	= video_device_release,
-};
-
-static irqreturn_t vcap_vp_handler(int irq_num, void *data)
-{
-	return vp_handler(vcap_ctrl);
-}
-
-static irqreturn_t vcap_vc_handler(int irq_num, void *data)
-{
-	return vc_handler(vcap_ctrl);
-}
-
-#ifdef CONFIG_DEBUG_FS
-/* Query VCAP resource usage */
-static ssize_t read_dump_info(struct file *file, char __user *user_buf,
-	size_t len, loff_t *ppos)
-{
-	struct vcap_dev *dev = file->private_data;
-	char str_buf[512];
-	size_t tot_size = 0, size;
-
-	if (dev->vc_client) {
-		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
-			"VCAP: VC\n");
-		tot_size += size;
-		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
-			"vc_resourse = %d\n", dev->vc_resource);
-		tot_size += size;
-		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
-			"vc_enabled = %d\n", atomic_read(&dev->vc_enabled));
-		tot_size += size;
-		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
-			"vc_client id = %p\n", dev->vc_client);
-		tot_size += size;
-		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
-			"vc_queue_count = %d\n",
-			atomic_read(&dev->vc_client->vc_vidq.queued_count));
-		tot_size += size;
-		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
-			"vc_total_buffers = %d\n",
-			dev->vc_client->vc_action.tot_buf);
-		tot_size += size;
-	} else {
-		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
-				"VCAP: VC not in use\n");
-		tot_size += size;
-	}
-	if (dev->vp_client) {
-		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
-			"VCAP: VP\n");
-		tot_size += size;
-		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
-			"vp_resourse = %d\n", dev->vp_resource);
-		tot_size += size;
-		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
-			"vp_enabled = %d\n", atomic_read(&dev->vp_enabled));
-		tot_size += size;
-		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
-			"vp_client id = %p\n", dev->vp_client);
-		tot_size += size;
-		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
-			"vp_in_queue_count = %d\n",
-			atomic_read(
-				&dev->vp_client->vp_in_vidq.queued_count));
-		tot_size += size;
-		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
-			"vp_out_queue_count = %d\n",
-			atomic_read(
-				&dev->vp_client->vp_out_vidq.queued_count));
-		tot_size += size;
-	} else {
-		size = scnprintf(str_buf + tot_size, sizeof(str_buf) - tot_size,
-			"VCAP: VP not in use\n");
-		tot_size += size;
-	}
-
-	return simple_read_from_buffer(user_buf, len, ppos, str_buf, tot_size);
-}
-
-static const struct file_operations dump_info_fops = {
-	.read =		read_dump_info,
-	.open =		simple_open,
-	.llseek =	default_llseek,
-};
-
-static int vcap_debug_clk_rate_get(void *data, u64 *val)
-{
-	struct vcap_dev *dev = data;
-	*val = (u64)dev->dbg_p.clk_rate;
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(clk_rate_fops, vcap_debug_clk_rate_get,
-	NULL, "%llu\n");
-
-static int vcap_debug_bw_req_get(void *data, u64 *val)
-{
-	struct vcap_dev *dev = data;
-	*val = (u64)dev->dbg_p.bw_request;
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(bw_req_fops, vcap_debug_bw_req_get,
-	NULL, "%llu\n");
-
-static int vcap_debug_drop_frames_get(void *data, u64 *val)
-{
-	struct vcap_dev *dev = data;
-	struct timeval tv;
-	int drop_count;
-
-	if (!dev->vc_resource)
-		return -EPERM;
-	drop_count = atomic_read(&dev->dbg_p.vc_drop_count);
-	atomic_set(&dev->dbg_p.vc_drop_count, 0);
-
-	do_gettimeofday(&tv);
-	dev->dbg_p.vc_timestamp = (uint32_t) (tv.tv_sec * VCAP_USEC +
-		tv.tv_usec);
-
-	*val = (u64)drop_count;
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(tot_frame_drop_fops, vcap_debug_drop_frames_get,
-	NULL, "%llu\n");
-
-static int vcap_debug_drop_fps_get(void *data, u64 *val)
-{
-	struct vcap_dev *dev = data;
-	struct timeval tv;
-	int drop_count;
-	uint32_t new_ts;
-
-	if (!dev->vc_resource)
-		return -EPERM;
-	drop_count = atomic_read(&dev->dbg_p.vc_drop_count);
-	atomic_set(&dev->dbg_p.vc_drop_count, 0);
-
-	do_gettimeofday(&tv);
-	new_ts = (uint32_t) (tv.tv_sec * VCAP_USEC +
-		tv.tv_usec);
-
-	if ((new_ts - dev->dbg_p.vc_timestamp) / VCAP_USEC &&
-				new_ts > dev->dbg_p.vc_timestamp)
-		drop_count /= ((new_ts - dev->dbg_p.vc_timestamp) / VCAP_USEC);
-	else
-		drop_count = 0;
-
-	dev->dbg_p.vc_timestamp = new_ts;
-	*val = (u64)drop_count;
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(drop_fps_fops, vcap_debug_drop_fps_get,
-	NULL, "%llu\n");
-
-static int vcap_debug_vp_lat_get(void *data, u64 *val)
-{
-	struct vcap_dev *dev = data;
-
-	if (!dev->vp_resource)
-		return -EPERM;
-	*val = (u64)dev->dbg_p.vp_ewma;
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(vp_lat_fops, vcap_debug_vp_lat_get,
-	NULL, "%llu\n");
-
-/* Read/Write to VCAP Registers */
-static int vcap_debug_reg_set(void *data, u64 val)
-{
-	struct vcap_dev *dev = data;
-	int i;
-	for (i = 0; i < ARRAY_SIZE(debug_reg_range); i++) {
-		if (val >= debug_reg_range[i].min_val && val <=
-				debug_reg_range[i].max_val)
-			break;
-	}
-	if (i == ARRAY_SIZE(debug_reg_range))
-		return -EINVAL;
-	dev->dbg_p.reg_addr = (uint32_t) val;
-	return 0;
-}
-
-static int vcap_debug_reg_get(void *data, u64 *val)
-{
-	struct vcap_dev *dev = data;
-	*val = (u64)dev->dbg_p.reg_addr;
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(vcap_reg_fops, vcap_debug_reg_get,
-	vcap_debug_reg_set, "0x%08llx\n")
-
-static int vcap_debug_reg_rdwr_set(void *data, u64 val)
-{
-	struct vcap_dev *dev = data;
-	u32 reg_val = (u32) val;
-
-	writel_iowmb(reg_val, VCAP_OFFSET(dev->dbg_p.reg_addr));
-	return 0;
-}
-
-static int vcap_debug_reg_rdwr_get(void *data, u64 *val)
-{
-	struct vcap_dev *dev = data;
-	*val = (u64)readl_relaxed(VCAP_OFFSET(dev->dbg_p.reg_addr));
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(vcap_reg_rdwr_fops, vcap_debug_reg_rdwr_get,
-	vcap_debug_reg_rdwr_set, "0x%08llx\n");
-
-static int vcap_debugfs_init(struct vcap_dev *dev)
-{
-	vcap_debugfs_base = debugfs_create_dir("vcap", NULL);
-	if (!vcap_debugfs_base)
-		return -ENOMEM;
-
-	if (!debugfs_create_file("dump_info", S_IRUGO,
-			vcap_debugfs_base, dev, &dump_info_fops))
-		goto error;
-
-	if (!debugfs_create_file("vcap_core_clk_rate", S_IRUGO,
-			vcap_debugfs_base, dev, &clk_rate_fops))
-		goto error;
-
-	if (!debugfs_create_file("vcap_bw_req", S_IRUGO,
-			vcap_debugfs_base, dev, &bw_req_fops))
-		goto error;
-
-	if (!debugfs_create_file("vc_total_frames_drop", S_IRUGO,
-			vcap_debugfs_base, dev, &tot_frame_drop_fops))
-		goto error;
-
-	if (!debugfs_create_file("vc_drop_fps", S_IRUGO,
-			vcap_debugfs_base, dev, &drop_fps_fops))
-		goto error;
-
-	if (!debugfs_create_file("vp_avg_completion_t", S_IRUGO,
-			vcap_debugfs_base, dev, &vp_lat_fops))
-		goto error;
-
-	if (!debugfs_create_file("vcap_reg_addr", S_IRUGO | S_IWUSR,
-			vcap_debugfs_base, dev, &vcap_reg_fops))
-		goto error;
-
-	if (!debugfs_create_file("vcap_reg_val", S_IRUGO | S_IWUSR,
-			vcap_debugfs_base, dev, &vcap_reg_rdwr_fops))
-		goto error;
-	return 0;
-
-error:
-	debugfs_remove_recursive(vcap_debugfs_base);
-	vcap_debugfs_base = NULL;
-	return -ENOMEM;
-}
-
-static void vcap_debugfs_remove(void)
-{
-	if (vcap_debugfs_base) {
-		debugfs_remove_recursive(vcap_debugfs_base);
-		vcap_debugfs_base = NULL;
-	}
-}
-#else
-
-static int vcap_debugfs_init(struct vcap_dev *dev)
-{
-	return 0;
-}
-static void vcap_debugfs_remove(void) {}
-#endif
-
-static int __devinit vcap_probe(struct platform_device *pdev)
-{
-	struct vcap_dev *dev;
-	struct video_device *vfd;
-	int ret;
-
-	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-	if (!dev)
-		return -ENOMEM;
-	vcap_ctrl = dev;
-	dev->vcap_pdata = pdev->dev.platform_data;
-
-	dev->vcapmem = platform_get_resource_byname(pdev,
-			IORESOURCE_MEM, "vcap");
-	if (!dev->vcapmem) {
-		pr_err("VCAP: %s: no mem resource?\n", __func__);
-		ret = -ENODEV;
-		goto free_dev;
-	}
-
-	dev->vcapio = request_mem_region(dev->vcapmem->start,
-		resource_size(dev->vcapmem), pdev->name);
-	if (!dev->vcapio) {
-		pr_err("VCAP: %s: no valid mem region\n", __func__);
-		ret = -EBUSY;
-		goto free_dev;
-	}
-
-	dev->vcapbase = ioremap(dev->vcapmem->start,
-		resource_size(dev->vcapmem));
-	if (!dev->vcapbase) {
-		ret = -ENOMEM;
-		pr_err("VCAP: %s: vcap ioremap failed\n", __func__);
-		goto free_resource;
-	}
-
-	dev->vcirq = platform_get_resource_byname(pdev,
-					IORESOURCE_IRQ, "vc_irq");
-	if (!dev->vcirq) {
-		pr_err("%s: no vc irq resource?\n", __func__);
-		ret = -ENODEV;
-		goto free_resource;
-	}
-	dev->vpirq = platform_get_resource_byname(pdev,
-					IORESOURCE_IRQ, "vp_irq");
-	if (!dev->vpirq) {
-		pr_err("%s: no vp irq resource?\n", __func__);
-		ret = -ENODEV;
-		goto free_resource;
-	}
-
-
-	ret = request_irq(dev->vcirq->start, vcap_vc_handler,
-		IRQF_TRIGGER_HIGH, "vc_irq", 0);
-	if (ret < 0) {
-		pr_err("%s: vc irq request fail\n", __func__);
-		ret = -EBUSY;
-		goto free_resource;
-	}
-	disable_irq(dev->vcirq->start);
-
-	ret = request_irq(dev->vpirq->start, vcap_vp_handler,
-		IRQF_TRIGGER_RISING, "vp_irq", 0);
-
-	if (ret < 0) {
-		pr_err("%s: vp irq request fail\n", __func__);
-		ret = -EBUSY;
-		goto free_resource;
-	}
-	disable_irq(dev->vpirq->start);
-
-	snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name),
-			"%s", MSM_VCAP_DRV_NAME);
-
-	ret = v4l2_device_register(NULL, &dev->v4l2_dev);
-	if (ret)
-		goto free_resource;
-
-	dev->vc_iommu_ctx = msm_iommu_get_ctx("vcap_vc");
-	if (!dev->vc_iommu_ctx) {
-		pr_err("%s: No iommu vc context found\n", __func__);
-		ret = -ENODEV;
-		goto free_resource;
-	}
-
-	dev->vp_iommu_ctx = msm_iommu_get_ctx("vcap_vp");
-	if (!dev->vp_iommu_ctx) {
-		pr_err("%s: No iommu vp context found\n", __func__);
-		ret = -ENODEV;
-		goto free_resource;
-	}
-
-	dev->domain_num = vcap_register_domain();
-	if (dev->domain_num < 0) {
-		pr_err("%s: VCAP iommu domain register failed\n", __func__);
-		ret = -ENODEV;
-		goto free_resource;
-	}
-
-	dev->iommu_vcap_domain = msm_get_iommu_domain(dev->domain_num);
-	if (!dev->iommu_vcap_domain) {
-		pr_err("%s: No iommu vcap domain found\n", __func__);
-		ret = -ENODEV;
-		goto free_resource;
-	}
-
-	ret = vcap_enable(dev, &pdev->dev, 54860000);
-	if (ret)
-		goto unreg_dev;
-	msm_bus_scale_client_update_request(dev->bus_client_handle, 0);
-	dev->dbg_p.bw_request = 0;
-
-	ret = detect_vc(dev);
-
-	if (ret)
-		goto power_down;
-
-	/* init video device*/
-	vfd = video_device_alloc();
-	if (!vfd) {
-		ret = -ENOMEM;
-		goto deinit_vc;
-	}
-
-	*vfd = vcap_template;
-	vfd->v4l2_dev = &dev->v4l2_dev;
-
-	ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
-	if (ret < 0)
-		goto rel_vdev;
-
-	dev->vfd = vfd;
-	video_set_drvdata(vfd, dev);
-
-	dev->vcap_wq = create_workqueue("vcap");
-	if (!dev->vcap_wq) {
-		ret = -ENOMEM;
-		pr_err("Could not create workqueue");
-		goto rel_vdev;
-	}
-
-	dev->ion_client = msm_ion_client_create(-1, "vcap");
-	if (IS_ERR((void *)dev->ion_client)) {
-		pr_err("could not get ion client");
-		ret = PTR_ERR(dev->ion_client);
-		dev->ion_client = NULL;
-		goto rel_vcap_wq;
-	}
-
-	atomic_set(&dev->dbg_p.vc_drop_count, 0);
-	ret = vcap_debugfs_init(dev);
-	if (ret < 0)
-		pr_err("VCAP debugfs failed to load");
-
-	dev->vc_tot_buf = 2;
-	atomic_set(&dev->vc_enabled, 0);
-	atomic_set(&dev->vp_enabled, 0);
-	atomic_set(&dev->open_clients, 0);
-	dev->ddev = &pdev->dev;
-	mutex_init(&dev->dev_mutex);
-	init_waitqueue_head(&dev->vp_dummy_waitq);
-	vcap_disable(dev);
-
-	return 0;
-rel_vcap_wq:
-	destroy_workqueue(dev->vcap_wq);
-rel_vdev:
-	video_device_release(vfd);
-deinit_vc:
-	deinit_vc();
-power_down:
-	vcap_disable(dev);
-unreg_dev:
-	v4l2_device_unregister(&dev->v4l2_dev);
-free_resource:
-	iounmap(dev->vcapbase);
-	release_mem_region(dev->vcapmem->start, resource_size(dev->vcapmem));
-free_dev:
-	vcap_ctrl = NULL;
-	kfree(dev);
-	return ret;
-}
-
-static int __devexit vcap_remove(struct platform_device *pdev)
-{
-	struct vcap_dev *dev = vcap_ctrl;
-	vcap_debugfs_remove();
-	ion_client_destroy(dev->ion_client);
-	flush_workqueue(dev->vcap_wq);
-	destroy_workqueue(dev->vcap_wq);
-	video_device_release(dev->vfd);
-	deinit_vc();
-	vcap_disable(dev);
-	v4l2_device_unregister(&dev->v4l2_dev);
-	iounmap(dev->vcapbase);
-	release_mem_region(dev->vcapmem->start, resource_size(dev->vcapmem));
-	vcap_ctrl = NULL;
-	kfree(dev);
-
-	return 0;
-}
-
-struct platform_driver vcap_platform_driver = {
-	.driver		= {
-		.name	= MSM_VCAP_DRV_NAME,
-		.owner	= THIS_MODULE,
-	},
-	.probe		= vcap_probe,
-	.remove		= vcap_remove,
-};
-
-static int __init vcap_init_module(void)
-{
-	return platform_driver_register(&vcap_platform_driver);
-}
-
-static void __exit vcap_exit_module(void)
-{
-	platform_driver_unregister(&vcap_platform_driver);
-}
-
-module_init(vcap_init_module);
-module_exit(vcap_exit_module);
-MODULE_DESCRIPTION("VCAP driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/vcap_vc.c b/drivers/media/video/vcap_vc.c
deleted file mode 100644
index 642074f..0000000
--- a/drivers/media/video/vcap_vc.c
+++ /dev/null
@@ -1,571 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/init.h>
-#include <linux/sched.h>
-#include <linux/kthread.h>
-#include <linux/freezer.h>
-#include <mach/camera.h>
-#include <linux/io.h>
-#include <linux/regulator/consumer.h>
-#include <mach/clk.h>
-#include <linux/clk.h>
-
-#include <media/v4l2-event.h>
-#include <media/vcap_v4l2.h>
-#include <media/vcap_fmt.h>
-#include "vcap_vc.h"
-
-void config_buffer(struct vcap_client_data *c_data,
-			struct vcap_buffer *buf,
-			void __iomem *y_addr,
-			void __iomem *c_addr)
-{
-	if (c_data->vc_format.color_space == HAL_VCAP_RGB) {
-		writel_relaxed(buf->paddr, y_addr);
-	} else {
-		int size = (c_data->vc_format.hactive_end -
-				c_data->vc_format.hactive_start);
-		if (c_data->stride == VC_STRIDE_32)
-			size = VCAP_STRIDE_CALC(size, VCAP_STRIDE_ALIGN_32);
-		else
-			size = VCAP_STRIDE_CALC(size, VCAP_STRIDE_ALIGN_16);
-		size *= (c_data->vc_format.vactive_end -
-				c_data->vc_format.vactive_start);
-		writel_relaxed(buf->paddr, y_addr);
-		writel_relaxed(buf->paddr + size, c_addr);
-	}
-}
-
-static void mov_buf_to_vp(struct work_struct *work)
-{
-	struct vp_work_t *vp_work = container_of(work, struct vp_work_t, work);
-	struct v4l2_buffer p;
-	struct vb2_buffer *vb_vc;
-	struct vcap_buffer *buf_vc;
-	struct vb2_buffer *vb_vp;
-	struct vcap_buffer *buf_vp;
-
-	int rc;
-	p.memory = V4L2_MEMORY_USERPTR;
-	while (1) {
-		p.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		if (!vp_work->cd->streaming)
-			return;
-		rc = vcvp_dqbuf(&vp_work->cd->vc_vidq, &p);
-		if (rc < 0)
-			return;
-
-		vb_vc = vp_work->cd->vc_vidq.bufs[p.index];
-		if (NULL == vb_vc) {
-			pr_debug("%s: buffer is NULL\n", __func__);
-			vcvp_qbuf(&vp_work->cd->vc_vidq, &p);
-			return;
-		}
-		buf_vc = container_of(vb_vc, struct vcap_buffer, vb);
-
-		vb_vp = vp_work->cd->vp_in_vidq.bufs[p.index];
-		if (NULL == vb_vp) {
-			pr_debug("%s: buffer is NULL\n", __func__);
-			vcvp_qbuf(&vp_work->cd->vc_vidq, &p);
-			return;
-		}
-		buf_vp = container_of(vb_vp, struct vcap_buffer, vb);
-		buf_vp->ion_handle = buf_vc->ion_handle;
-		buf_vp->paddr = buf_vc->paddr;
-		buf_vc->ion_handle = NULL;
-		buf_vc->paddr = 0;
-
-		p.type = V4L2_BUF_TYPE_INTERLACED_IN_DECODER;
-
-		/* This call should not fail */
-		rc = vcvp_qbuf(&vp_work->cd->vp_in_vidq, &p);
-		if (rc < 0) {
-			pr_err("%s: qbuf to vp_in failed\n", __func__);
-			buf_vc->ion_handle = buf_vp->ion_handle;
-			buf_vc->paddr = buf_vp->paddr;
-			buf_vp->ion_handle = NULL;
-			buf_vp->paddr = 0;
-			p.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-			vcvp_qbuf(&vp_work->cd->vc_vidq, &p);
-		}
-	}
-}
-
-static uint8_t correct_buf_num(uint32_t reg)
-{
-	int i;
-	bool block_found = false;
-	for (i = 0; i < VCAP_VC_MAX_BUF; i++) {
-		if (reg & (0x2 << i)) {
-			block_found = true;
-			continue;
-		}
-		if (block_found)
-			return i;
-	}
-	return 0;
-}
-
-static struct timeval interpolate_ts(struct timeval tv, uint32_t delta)
-{
-	if (tv.tv_usec < delta) {
-		tv.tv_sec--;
-		tv.tv_usec += VCAP_USEC - delta;
-	} else {
-		tv.tv_usec -= delta;
-	}
-	return tv;
-}
-
-inline void vc_isr_error_checking(struct vcap_dev *dev,
-		struct v4l2_event v4l2_evt, uint32_t irq)
-{
-	if (irq & 0x8000200) {
-		writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
-		v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
-			VCAP_VC_PIX_ERR_EVENT;
-		v4l2_event_queue(dev->vfd, &v4l2_evt);
-	}
-	if (irq & 0x40000200) {
-		writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
-		v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
-			VCAP_VC_LINE_ERR_EVENT;
-		v4l2_event_queue(dev->vfd, &v4l2_evt);
-	}
-	if (irq & 0x20000200) {
-		writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
-		v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
-			VCAP_VC_VSYNC_ERR_EVENT;
-		v4l2_event_queue(dev->vfd, &v4l2_evt);
-	}
-	if (irq & 0x00001000) {
-		writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
-		v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
-			VCAP_VC_VSYNC_SEQ_ERR;
-		v4l2_event_queue(dev->vfd, &v4l2_evt);
-	}
-	if (irq & 0x00000800) {
-		writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
-		v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
-			VCAP_VC_NPL_OFLOW_ERR_EVENT;
-		v4l2_event_queue(dev->vfd, &v4l2_evt);
-	}
-	if (irq & 0x00000400) {
-		writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
-		v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
-			VCAP_VC_LBUF_OFLOW_ERR_EVENT;
-		v4l2_event_queue(dev->vfd, &v4l2_evt);
-	}
-}
-
-inline uint8_t vc_isr_buffer_done_count(struct vcap_dev *dev,
-		struct vcap_client_data *c_data, uint32_t irq)
-{
-	int i;
-	uint8_t done_count = 0;
-	for (i = 0; i < VCAP_VC_MAX_BUF; i++) {
-		if (0x2 & (irq >> i))
-			done_count++;
-	}
-	return done_count;
-}
-
-inline bool vc_isr_verify_expect_buf_rdy(struct vcap_dev *dev,
-		struct vcap_client_data *c_data, struct v4l2_event v4l2_evt,
-		uint32_t irq, uint8_t done_count, uint8_t tot, uint8_t buf_num)
-{
-	int i;
-	/* Double check expected buffers are done */
-	for (i = 0; i < done_count; i++) {
-		if (!(irq & (0x1 << (((buf_num + i) % tot) + 1)))) {
-			v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
-				VCAP_VC_UNEXPECT_BUF_DONE;
-			v4l2_event_queue(dev->vfd, &v4l2_evt);
-			pr_debug("Unexpected buffer done\n");
-			c_data->vc_action.buf_num =
-				correct_buf_num(irq) % tot;
-			return true;
-		}
-	}
-	return false;
-}
-
-inline void vc_isr_update_timestamp(struct vcap_dev *dev,
-		struct vcap_client_data *c_data)
-{
-	uint32_t timestamp;
-
-	timestamp = readl_relaxed(VCAP_VC_TIMESTAMP);
-	if (timestamp < c_data->vc_action.last_ts) {
-		c_data->vc_action.vc_ts.tv_usec +=
-			(0xFFFFFFFF - c_data->vc_action.last_ts) +
-			timestamp + 1;
-	} else {
-		c_data->vc_action.vc_ts.tv_usec +=
-			timestamp - c_data->vc_action.last_ts;
-	}
-
-	c_data->vc_action.vc_ts.tv_sec +=
-		c_data->vc_action.vc_ts.tv_usec / VCAP_USEC;
-	c_data->vc_action.vc_ts.tv_usec =
-		c_data->vc_action.vc_ts.tv_usec % VCAP_USEC;
-	c_data->vc_action.last_ts = timestamp;
-}
-
-inline void vc_isr_no_new_buffer(struct vcap_dev *dev,
-		struct vcap_client_data *c_data, struct v4l2_event v4l2_evt)
-{
-	v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
-		VCAP_VC_BUF_OVERWRITE_EVENT;
-	v4l2_event_queue(dev->vfd, &v4l2_evt);
-
-	c_data->vc_action.field_dropped =
-		!c_data->vc_action.field_dropped;
-
-	c_data->vc_action.field1 =
-		!c_data->vc_action.field1;
-	atomic_inc(&dev->dbg_p.vc_drop_count);
-}
-
-inline void vc_isr_switch_buffers(struct vcap_dev *dev,
-		struct vcap_client_data *c_data, struct vcap_buffer *buf,
-		struct vb2_buffer *vb, uint8_t idx, int done_count, int i)
-{
-	/* Config vc with this new buffer */
-	config_buffer(c_data, buf, VCAP_VC_Y_ADDR_1 + 0x8 * idx,
-			VCAP_VC_C_ADDR_1 + 0x8 * idx);
-	vb->v4l2_buf.timestamp = interpolate_ts(
-		c_data->vc_action.vc_ts,
-		1000000 / c_data->vc_format.frame_rate *
-		(done_count - 1 - i));
-	if (c_data->vc_format.mode == HAL_VCAP_MODE_INT) {
-		if (c_data->vc_action.field1)
-			vb->v4l2_buf.field = V4L2_FIELD_TOP;
-		else
-			vb->v4l2_buf.field = V4L2_FIELD_BOTTOM;
-
-		c_data->vc_action.field1 =
-			!c_data->vc_action.field1;
-	}
-	vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
-	c_data->vc_action.buf[idx] = buf;
-}
-
-inline bool vc_isr_change_buffers(struct vcap_dev *dev,
-		struct vcap_client_data *c_data, struct v4l2_event v4l2_evt,
-		int done_count, uint8_t tot, uint8_t buf_num)
-{
-	struct vb2_buffer *vb = NULL;
-	struct vcap_buffer *buf;
-	bool schedule_work = false;
-	uint8_t idx;
-	int i;
-
-	for (i = 0; i < done_count; i++) {
-		idx = (buf_num + i) % tot;
-		vb = &c_data->vc_action.buf[idx]->vb;
-		spin_lock(&c_data->cap_slock);
-		if (list_empty(&c_data->vc_action.active)) {
-			spin_unlock(&c_data->cap_slock);
-			vc_isr_no_new_buffer(dev, c_data, v4l2_evt);
-			continue;
-		}
-		if (c_data->vc_format.mode == HAL_VCAP_MODE_INT &&
-				c_data->vc_action.field_dropped) {
-			spin_unlock(&c_data->cap_slock);
-			vc_isr_no_new_buffer(dev, c_data, v4l2_evt);
-			continue;
-		}
-		buf = list_entry(c_data->vc_action.active.next,
-				struct vcap_buffer, list);
-		list_del(&buf->list);
-		spin_unlock(&c_data->cap_slock);
-		vc_isr_switch_buffers(dev, c_data, buf, vb, idx, done_count, i);
-		schedule_work = true;
-	}
-	return schedule_work;
-}
-
-irqreturn_t vc_handler(struct vcap_dev *dev)
-{
-	uint32_t irq;
-	struct vcap_client_data *c_data;
-	struct v4l2_event v4l2_evt;
-	uint8_t done_count = 0, buf_num, tot;
-	bool schedule_work = false;
-
-	v4l2_evt.id = 0;
-	irq = readl_relaxed(VCAP_VC_INT_STATUS);
-	writel_relaxed(irq, VCAP_VC_INT_CLEAR);
-
-	pr_debug("%s: irq=0x%08x\n", __func__, irq);
-
-	if (dev->vc_client == NULL) {
-		/* This should never happen */
-		pr_err("VC: There is no active vc client\n");
-		return IRQ_HANDLED;
-	}
-
-	c_data = dev->vc_client;
-	if (!c_data->streaming) {
-		pr_err("VC no longer streaming\n");
-		return IRQ_HANDLED;
-	}
-
-	if (irq == VC_VSYNC_MASK) {
-		if (c_data->vc_format.mode == HAL_VCAP_MODE_INT)
-			c_data->vc_action.field1 = irq & 0x1;
-		return IRQ_HANDLED;
-	}
-
-	if (irq & VC_ERR_MASK) {
-		vc_isr_error_checking(dev, v4l2_evt, irq);
-		return IRQ_HANDLED;
-	}
-
-	if (!(irq & VC_BUFFER_MASK)) {
-		pr_debug("No frames done\n");
-		return IRQ_HANDLED;
-	}
-
-	done_count = vc_isr_buffer_done_count(dev, c_data, irq);
-	buf_num = c_data->vc_action.buf_num;
-	tot = c_data->vc_action.tot_buf;
-
-	if (vc_isr_verify_expect_buf_rdy(dev, c_data,
-			v4l2_evt, irq, done_count, tot, buf_num))
-		return IRQ_HANDLED;
-
-	vc_isr_update_timestamp(dev, c_data);
-
-	c_data->vc_action.buf_num = (buf_num + done_count) % tot;
-
-	schedule_work = vc_isr_change_buffers(dev, c_data, v4l2_evt,
-		done_count, tot, buf_num);
-
-	if (schedule_work && c_data->op_mode == VC_AND_VP_VCAP_OP)
-		queue_work(dev->vcap_wq, &dev->vc_to_vp_work.work);
-
-	return IRQ_HANDLED;
-}
-
-int vc_start_capture(struct vcap_client_data *c_data)
-{
-	return 0;
-}
-
-int vc_hw_kick_off(struct vcap_client_data *c_data)
-{
-	struct vc_action *vc_action = &c_data->vc_action;
-	struct vcap_dev *dev;
-	struct timeval tv;
-	unsigned long flags = 0;
-	int rc, i, counter = 0;
-	struct vcap_buffer *buf;
-
-	dev = c_data->dev;
-	pr_debug("Start Kickoff\n");
-
-	if (dev->vc_client == NULL) {
-		pr_err("No active vc client\n");
-		return -ENODEV;
-	}
-	c_data->vc_action.buf_num = 0;
-	spin_lock_irqsave(&dev->vc_client->cap_slock, flags);
-	if (list_empty(&dev->vc_client->vc_action.active)) {
-		spin_unlock_irqrestore(&dev->vc_client->cap_slock, flags);
-		pr_err("%s: VC We have no more avilable buffers\n",
-				__func__);
-		return -EINVAL;
-	}
-
-	list_for_each_entry(buf, &vc_action->active, list)
-		counter++;
-
-	if (counter < c_data->vc_action.tot_buf) {
-		/* not enough buffers have been queued */
-		spin_unlock_irqrestore(&dev->vc_client->cap_slock, flags);
-		return -EINVAL;
-	}
-
-	for (i = 0; i < c_data->vc_action.tot_buf; i++) {
-		vc_action->buf[i] = list_entry(vc_action->active.next,
-			struct vcap_buffer, list);
-		list_del(&vc_action->buf[i]->list);
-	}
-	spin_unlock_irqrestore(&dev->vc_client->cap_slock, flags);
-
-	for (i = 0; i < c_data->vc_action.tot_buf; i++) {
-		config_buffer(c_data, vc_action->buf[i],
-			VCAP_VC_Y_ADDR_1 + i * 8,
-			VCAP_VC_C_ADDR_1 + i * 8);
-	}
-
-	c_data->vc_action.last_ts = readl_relaxed(VCAP_VC_TIMESTAMP);
-	c_data->vc_action.vc_ts.tv_sec =
-		c_data->vc_action.last_ts / VCAP_USEC;
-	c_data->vc_action.vc_ts.tv_usec =
-		c_data->vc_action.last_ts % VCAP_USEC;
-
-	atomic_set(&dev->dbg_p.vc_drop_count, 0);
-	do_gettimeofday(&tv);
-	dev->dbg_p.vc_timestamp = (uint32_t) (tv.tv_sec * VCAP_USEC +
-		tv.tv_usec);
-
-	rc = 0;
-	for (i = 0; i < c_data->vc_action.tot_buf; i++)
-		rc = rc << 1 | 0x2;
-	rc |= VC_ERR_MASK;
-	rc |= VC_VSYNC_MASK;
-	writel_relaxed(rc, VCAP_VC_INT_MASK);
-
-	enable_irq(dev->vcirq->start);
-	rc = readl_relaxed(VCAP_VC_CTRL);
-	writel_iowmb(rc | 0x1, VCAP_VC_CTRL);
-
-	return 0;
-}
-
-void vc_stop_capture(struct vcap_client_data *c_data)
-{
-	struct vcap_dev *dev = c_data->dev;
-	unsigned int reg;
-	int timeout;
-
-	writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
-	writel_iowmb(0x0, VCAP_VC_INT_MASK);
-	flush_workqueue(dev->vcap_wq);
-	if (atomic_read(&dev->vc_enabled) == 1)
-		disable_irq_nosync(dev->vcirq->start);
-
-	writel_iowmb(0x00000000, VCAP_VC_CTRL);
-	writel_iowmb(0x00000001, VCAP_SW_RESET_REQ);
-	timeout = 10000;
-	while (1) {
-		reg = (readl_relaxed(VCAP_SW_RESET_STATUS) & 0x1);
-		if (!reg)
-			break;
-		timeout--;
-		if (timeout == 0) {
-			/* This should not happen */
-			pr_err("VC is not resetting properly\n");
-			writel_iowmb(0x00000000, VCAP_SW_RESET_REQ);
-			break;
-		}
-	}
-
-	reg = readl_relaxed(VCAP_VC_NPL_CTRL);
-	reg = readl_relaxed(VCAP_VC_NPL_CTRL);
-	writel_iowmb(0x00000002, VCAP_VC_NPL_CTRL);
-}
-
-int config_vc_format(struct vcap_client_data *c_data)
-{
-	struct vcap_dev *dev;
-	unsigned int rc;
-	int timeout;
-	struct v4l2_format_vc_ext *vc_format = &c_data->vc_format;
-	dev = c_data->dev;
-
-	/* restart VC */
-	writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
-	writel_iowmb(0x00000001, VCAP_SW_RESET_REQ);
-	timeout = 10000;
-	while (1) {
-		if (!(readl_relaxed(VCAP_SW_RESET_STATUS) & 0x1))
-			break;
-		timeout--;
-		if (timeout == 0) {
-			pr_err("VC is not resetting properly\n");
-			writel_iowmb(0x00000002, VCAP_VC_NPL_CTRL);
-			return -EINVAL;
-		}
-	}
-
-	rc = readl_relaxed(VCAP_VC_NPL_CTRL);
-	rc = readl_relaxed(VCAP_VC_NPL_CTRL);
-	writel_iowmb(0x00000002, VCAP_VC_NPL_CTRL);
-
-	pr_debug("%s: Starting VC configuration\n", __func__);
-	writel_iowmb(0x00000002, VCAP_VC_NPL_CTRL);
-	writel_iowmb(0x00000004 | vc_format->color_space << 1 |
-			vc_format->mode << 3 |
-			(c_data->vc_action.tot_buf - 2) << 4 |
-			vc_format->mode << 10,
-			VCAP_VC_CTRL);
-
-	writel_relaxed(vc_format->d_polar << 8 |
-			vc_format->h_polar << 4 |
-			vc_format->v_polar << 0, VCAP_VC_POLARITY);
-
-	writel_relaxed(((vc_format->htotal << 16) | vc_format->vtotal),
-			VCAP_VC_V_H_TOTAL);
-	writel_relaxed(((vc_format->hactive_end << 16) |
-			vc_format->hactive_start), VCAP_VC_H_ACTIVE);
-
-	writel_relaxed(((vc_format->vactive_end << 16) |
-			vc_format->vactive_start), VCAP_VC_V_ACTIVE);
-	writel_relaxed(((vc_format->f2_vactive_end << 16) |
-			vc_format->f2_vactive_start), VCAP_VC_V_ACTIVE_F2);
-	writel_relaxed(((vc_format->vsync_end << 16) | vc_format->vsync_start),
-			VCAP_VC_VSYNC_VPOS);
-	writel_relaxed(((vc_format->f2_vsync_v_end << 16) |
-			vc_format->f2_vsync_v_start), VCAP_VC_VSYNC_F2_VPOS);
-	writel_relaxed(((vc_format->hsync_end << 16) |
-			vc_format->hsync_start), VCAP_VC_HSYNC_HPOS);
-	writel_relaxed(((vc_format->f2_vsync_h_end << 16) |
-			vc_format->f2_vsync_h_start), VCAP_VC_VSYNC_F2_HPOS);
-	writel_iowmb(0x000033FF, VCAP_VC_BUF_CTRL);
-
-	rc = vc_format->hactive_end - vc_format->hactive_start;
-	if (c_data->stride == VC_STRIDE_32)
-		rc = VCAP_STRIDE_CALC(rc, VCAP_STRIDE_ALIGN_32);
-	else
-		rc = VCAP_STRIDE_CALC(rc, VCAP_STRIDE_ALIGN_16);
-	if (vc_format->color_space)
-		rc *= 3;
-
-	writel_relaxed(rc, VCAP_VC_Y_STRIDE);
-	writel_relaxed(rc, VCAP_VC_C_STRIDE);
-
-	writel_relaxed(0x00010033 , VCAP_OFFSET(0x0898));
-	writel_relaxed(0x00010fff , VCAP_OFFSET(0x089c));
-	writel_relaxed(0x0a418820, VCAP_VC_IN_CTRL1);
-	writel_relaxed(0x16a4a0e6, VCAP_VC_IN_CTRL2);
-	writel_relaxed(0x2307b9ac, VCAP_VC_IN_CTRL3);
-	writel_relaxed(0x2f6ad272, VCAP_VC_IN_CTRL4);
-	writel_relaxed(0x00006b38, VCAP_VC_IN_CTRL5);
-
-	writel_iowmb(0x00000001 , VCAP_OFFSET(0x0d00));
-	pr_debug("%s: Done VC configuration\n", __func__);
-
-	return 0;
-}
-
-int detect_vc(struct vcap_dev *dev)
-{
-	int result;
-	result = readl_relaxed(VCAP_HARDWARE_VERSION_REG);
-	pr_debug("Hardware version: %08x\n", result);
-	if (result != VCAP_HARDWARE_VERSION)
-		return -ENODEV;
-	INIT_WORK(&dev->vc_to_vp_work.work, mov_buf_to_vp);
-	return 0;
-}
-
-int deinit_vc(void)
-{
-	return 0;
-}
diff --git a/drivers/media/video/vcap_vc.h b/drivers/media/video/vcap_vc.h
deleted file mode 100644
index 9c3f5a7..0000000
--- a/drivers/media/video/vcap_vc.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 VCAP_VC_H
-#define VCAP_VC_H
-
-#include <linux/interrupt.h>
-
-#include <media/vcap_v4l2.h>
-
-#define VCAP_HARDWARE_VERSION 0x10000000
-
-#define VCAP_HARDWARE_VERSION_REG (VCAP_BASE + 0x0000)
-
-#define VCAP_VC_CTRL (VCAP_BASE + 0x0800)
-#define VCAP_VC_NPL_CTRL (VCAP_BASE + 0x0804)
-#define VCAP_VC_POLARITY (VCAP_BASE + 0x081c)
-#define VCAP_VC_V_H_TOTAL (VCAP_BASE + 0x0820)
-#define VCAP_VC_H_ACTIVE (VCAP_BASE + 0x0824)
-#define VCAP_VC_V_ACTIVE (VCAP_BASE + 0x0828)
-#define VCAP_VC_V_ACTIVE_F2 (VCAP_BASE + 0x0830)
-#define VCAP_VC_VSYNC_VPOS (VCAP_BASE + 0x0834)
-#define VCAP_VC_VSYNC_F2_VPOS (VCAP_BASE + 0x0838)
-#define VCAP_VC_HSYNC_HPOS (VCAP_BASE + 0x0840)
-#define VCAP_VC_VSYNC_F2_HPOS (VCAP_BASE + 0x083c)
-#define VCAP_VC_BUF_CTRL (VCAP_BASE + 0x0848)
-
-#define VCAP_VC_Y_STRIDE (VCAP_BASE + 0x084c)
-#define VCAP_VC_C_STRIDE (VCAP_BASE + 0x0850)
-
-#define VCAP_VC_Y_ADDR_1 (VCAP_BASE + 0x0854)
-#define VCAP_VC_C_ADDR_1 (VCAP_BASE + 0x0858)
-#define VCAP_VC_Y_ADDR_2 (VCAP_BASE + 0x085c)
-#define VCAP_VC_C_ADDR_2 (VCAP_BASE + 0x0860)
-#define VCAP_VC_Y_ADDR_3 (VCAP_BASE + 0x0864)
-#define VCAP_VC_C_ADDR_3 (VCAP_BASE + 0x0868)
-#define VCAP_VC_Y_ADDR_4 (VCAP_BASE + 0x086c)
-#define VCAP_VC_C_ADDR_4 (VCAP_BASE + 0x0870)
-#define VCAP_VC_Y_ADDR_5 (VCAP_BASE + 0x0874)
-#define VCAP_VC_C_ADDR_5 (VCAP_BASE + 0x0878)
-#define VCAP_VC_Y_ADDR_6 (VCAP_BASE + 0x087c)
-#define VCAP_VC_C_ADDR_6 (VCAP_BASE + 0x0880)
-
-#define VCAP_VC_IN_CTRL1 (VCAP_BASE + 0x0808)
-#define VCAP_VC_IN_CTRL2 (VCAP_BASE + 0x080c)
-#define VCAP_VC_IN_CTRL3 (VCAP_BASE + 0x0810)
-#define VCAP_VC_IN_CTRL4 (VCAP_BASE + 0x0814)
-#define VCAP_VC_IN_CTRL5 (VCAP_BASE + 0x0818)
-
-#define VCAP_VC_INT_MASK (VCAP_BASE + 0x0884)
-#define VCAP_VC_INT_CLEAR (VCAP_BASE + 0x0888)
-#define VCAP_VC_INT_STATUS (VCAP_BASE + 0x088c)
-#define VCAP_VC_TIMESTAMP (VCAP_BASE + 0x0034)
-
-#define VC_BUFFER_WRITTEN (0x3 << 1)
-#define VC_BUFFER_MASK 0x7E
-#define VC_ERR_MASK 0xE0001E00
-#define VC_VSYNC_MASK 0x1
-
-int vc_start_capture(struct vcap_client_data *c_data);
-int vc_hw_kick_off(struct vcap_client_data *c_data);
-void vc_stop_capture(struct vcap_client_data *c_data);
-int config_vc_format(struct vcap_client_data *c_data);
-int detect_vc(struct vcap_dev *dev);
-int deinit_vc(void);
-irqreturn_t vc_handler(struct vcap_dev *dev);
-#endif
diff --git a/drivers/media/video/vcap_vp.c b/drivers/media/video/vcap_vp.c
deleted file mode 100644
index 06891899..0000000
--- a/drivers/media/video/vcap_vp.c
+++ /dev/null
@@ -1,904 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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/init.h>
-#include <linux/sched.h>
-#include <linux/kthread.h>
-#include <linux/freezer.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include <mach/camera.h>
-#include <mach/clk.h>
-
-#include <media/v4l2-event.h>
-#include <media/vcap_v4l2.h>
-#include <media/vcap_fmt.h>
-
-#include "vcap_vp.h"
-
-void config_nr_buffer(struct vcap_client_data *c_data,
-			struct vcap_buffer *buf)
-{
-	struct vcap_dev *dev = c_data->dev;
-	int size = c_data->vp_in_fmt.height * c_data->vp_in_fmt.width;
-
-	writel_relaxed(buf->paddr, VCAP_VP_NR_T2_Y_BASE_ADDR);
-	writel_relaxed(buf->paddr + size, VCAP_VP_NR_T2_C_BASE_ADDR);
-}
-
-void config_in_buffer(struct vcap_client_data *c_data,
-			struct vcap_buffer *buf)
-{
-	struct vcap_dev *dev = c_data->dev;
-	int size = c_data->vp_in_fmt.height * c_data->vp_in_fmt.width;
-
-	writel_relaxed(buf->paddr, VCAP_VP_T2_Y_BASE_ADDR);
-	writel_relaxed(buf->paddr + size, VCAP_VP_T2_C_BASE_ADDR);
-}
-
-void config_out_buffer(struct vcap_client_data *c_data,
-			struct vcap_buffer *buf)
-{
-	struct vcap_dev *dev = c_data->dev;
-	int size;
-	size = c_data->vp_out_fmt.height * c_data->vp_out_fmt.width;
-	writel_relaxed(buf->paddr, VCAP_VP_OUT_Y_BASE_ADDR);
-	writel_relaxed(buf->paddr + size, VCAP_VP_OUT_C_BASE_ADDR);
-}
-
-int vp_setup_buffers(struct vcap_client_data *c_data)
-{
-	struct vp_action *vp_act;
-	struct vcap_dev *dev;
-	unsigned long flags = 0;
-
-	if (!c_data->streaming)
-		return -ENOEXEC;
-	dev = c_data->dev;
-	pr_debug("VP: Start setup buffers\n");
-
-	if (dev->vp_shutdown) {
-		pr_debug("%s: VP shutting down, no buf setup\n",
-			__func__);
-		return -EPERM;
-	}
-
-	/* No need to verify vp_client is not NULL caller does so */
-	vp_act = &dev->vp_client->vp_action;
-
-	spin_lock_irqsave(&dev->vp_client->cap_slock, flags);
-	if (list_empty(&vp_act->in_active)) {
-		spin_unlock_irqrestore(&dev->vp_client->cap_slock, flags);
-		pr_debug("%s: VP We have no more input buffers\n",
-				__func__);
-		return -EAGAIN;
-	}
-
-	if (list_empty(&vp_act->out_active)) {
-		spin_unlock_irqrestore(&dev->vp_client->cap_slock,
-			flags);
-		pr_debug("%s: VP We have no more output buffers\n",
-		   __func__);
-		return -EAGAIN;
-	}
-
-	vp_act->bufT2 = list_entry(vp_act->in_active.next,
-			struct vcap_buffer, list);
-	list_del(&vp_act->bufT2->list);
-
-	vp_act->bufOut = list_entry(vp_act->out_active.next,
-			struct vcap_buffer, list);
-	list_del(&vp_act->bufOut->list);
-	spin_unlock_irqrestore(&dev->vp_client->cap_slock, flags);
-
-	config_in_buffer(c_data, vp_act->bufT2);
-	config_out_buffer(c_data, vp_act->bufOut);
-	return 0;
-}
-
-static void mov_buf_to_vc(struct work_struct *work)
-{
-	struct vp_work_t *vp_work = container_of(work, struct vp_work_t, work);
-	struct v4l2_buffer p;
-	struct vb2_buffer *vb_vc;
-	struct vcap_buffer *buf_vc;
-	struct vb2_buffer *vb_vp;
-	struct vcap_buffer *buf_vp;
-	int rc;
-
-	p.memory = V4L2_MEMORY_USERPTR;
-
-	/* This loop exits when there is no more buffers left */
-	while (1) {
-		p.type = V4L2_BUF_TYPE_INTERLACED_IN_DECODER;
-		if (!vp_work->cd->streaming)
-			return;
-		rc = vcvp_dqbuf(&vp_work->cd->vp_in_vidq, &p);
-		if (rc < 0)
-			return;
-
-		vb_vc = vp_work->cd->vc_vidq.bufs[p.index];
-		if (NULL == vb_vc) {
-			pr_debug("%s: buffer is NULL\n", __func__);
-			vcvp_qbuf(&vp_work->cd->vp_in_vidq, &p);
-			return;
-		}
-		buf_vc = container_of(vb_vc, struct vcap_buffer, vb);
-
-		vb_vp = vp_work->cd->vp_in_vidq.bufs[p.index];
-		if (NULL == vb_vp) {
-			pr_debug("%s: buffer is NULL\n", __func__);
-			vcvp_qbuf(&vp_work->cd->vp_in_vidq, &p);
-			return;
-		}
-		buf_vp = container_of(vb_vp, struct vcap_buffer, vb);
-		buf_vc->ion_handle = buf_vp->ion_handle;
-		buf_vc->paddr = buf_vp->paddr;
-		buf_vp->ion_handle = NULL;
-		buf_vp->paddr = 0;
-
-		p.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		/* This call should not fail */
-		rc = vcvp_qbuf(&vp_work->cd->vc_vidq, &p);
-		if (rc < 0) {
-			pr_err("%s: qbuf to vc failed\n", __func__);
-			buf_vp->ion_handle = buf_vc->ion_handle;
-			buf_vp->paddr = buf_vc->paddr;
-			buf_vc->ion_handle = NULL;
-			buf_vc->paddr = 0;
-			p.type = V4L2_BUF_TYPE_INTERLACED_IN_DECODER;
-			vcvp_qbuf(&vp_work->cd->vp_in_vidq, &p);
-		}
-	}
-}
-
-void update_nr_value(struct vcap_dev *dev)
-{
-	struct nr_param *par;
-	uint32_t val = 0;
-	par = &dev->nr_param;
-	if (par->mode == NR_MANUAL) {
-		writel_relaxed(par->window << 24 | par->decay_ratio << 20,
-			VCAP_VP_NR_CONFIG);
-		if (par->threshold)
-			val = VP_NR_DYNAMIC_THRESHOLD;
-		writel_relaxed(val |
-			par->luma.max_blend_ratio << 24 |
-			par->luma.scale_diff_ratio << 12 |
-			par->luma.diff_limit_ratio << 8  |
-			par->luma.scale_motion_ratio << 4 |
-			par->luma.blend_limit_ratio << 0,
-			VCAP_VP_NR_LUMA_CONFIG);
-		writel_relaxed(val |
-			par->chroma.max_blend_ratio << 24 |
-			par->chroma.scale_diff_ratio << 12 |
-			par->chroma.diff_limit_ratio << 8  |
-			par->chroma.scale_motion_ratio << 4 |
-			par->chroma.blend_limit_ratio << 0,
-			VCAP_VP_NR_CHROMA_CONFIG);
-	}
-	dev->nr_update = false;
-}
-
-static void vp_wq_fnc(struct work_struct *work)
-{
-	struct vp_work_t *vp_work = container_of(work, struct vp_work_t, work);
-	struct vcap_dev *dev;
-	struct vp_action *vp_act;
-	struct timeval tv;
-	unsigned long flags = 0;
-	uint32_t irq;
-	int rc;
-	bool top_field = 0;
-
-	if (vp_work && vp_work->cd && vp_work->cd->dev)
-		dev = vp_work->cd->dev;
-	else
-		return;
-
-	vp_act = &dev->vp_client->vp_action;
-
-	rc = readl_relaxed(VCAP_OFFSET(0x048));
-	while (!(rc & 0x00000100))
-		rc = readl_relaxed(VCAP_OFFSET(0x048));
-
-	irq = readl_relaxed(VCAP_VP_INT_STATUS);
-
-	writel_relaxed(0x00000000, VCAP_VP_BAL_VMOTION_STATE);
-	writel_relaxed(0x40000000, VCAP_VP_REDUCT_AVG_MOTION2);
-
-	spin_lock_irqsave(&dev->vp_client->cap_slock, flags);
-	if (dev->nr_update == true)
-		update_nr_value(dev);
-	spin_unlock_irqrestore(&dev->vp_client->cap_slock, flags);
-
-	/* Queue the done buffers */
-	if (vp_act->vp_state == VP_NORMAL &&
-			vp_act->bufNR.nr_pos != TM1_BUF) {
-		vb2_buffer_done(&vp_act->bufTm1->vb, VB2_BUF_STATE_DONE);
-		if (vp_work->cd->op_mode == VC_AND_VP_VCAP_OP)
-			queue_work(dev->vcap_wq, &dev->vp_to_vc_work.work);
-	}
-
-	if (vp_act->bufT0 != NULL && vp_act->vp_state == VP_NORMAL) {
-		vp_act->bufOut->vb.v4l2_buf.timestamp =
-			vp_act->bufT0->vb.v4l2_buf.timestamp;
-	}
-	vb2_buffer_done(&vp_act->bufOut->vb, VB2_BUF_STATE_DONE);
-
-	/* Cycle to next state */
-	if (vp_act->vp_state != VP_NORMAL)
-		vp_act->vp_state++;
-
-	/* Cycle Buffers*/
-	if (dev->nr_param.mode) {
-		if (vp_act->bufNR.nr_pos == TM1_BUF)
-			vp_act->bufNR.nr_pos = BUF_NOT_IN_USE;
-
-		if (vp_act->bufNR.nr_pos != BUF_NOT_IN_USE)
-			vp_act->bufNR.nr_pos++;
-
-		vp_act->bufTm1 = vp_act->bufT0;
-		vp_act->bufT0 = vp_act->bufT1;
-		vp_act->bufT1 = vp_act->bufNRT2;
-		vp_act->bufNRT2 = vp_act->bufT2;
-		config_nr_buffer(vp_work->cd, vp_act->bufNRT2);
-	} else {
-		vp_act->bufTm1 = vp_act->bufT0;
-		vp_act->bufT0 = vp_act->bufT1;
-		vp_act->bufT1 = vp_act->bufT2;
-	}
-
-	rc = vp_setup_buffers(vp_work->cd);
-	if (rc < 0) {
-		/* setup_buf failed because we are waiting for buffers */
-		writel_relaxed(0x00000000, VCAP_VP_INTERRUPT_ENABLE);
-		writel_iowmb(irq, VCAP_VP_INT_CLEAR);
-		atomic_set(&dev->vp_enabled, 0);
-		if (dev->vp_shutdown)
-			wake_up(&dev->vp_dummy_waitq);
-		return;
-	}
-
-	/* Config VP */
-	if (vp_act->bufT2->vb.v4l2_buf.field == V4L2_FIELD_BOTTOM)
-		top_field = 1;
-
-	writel_iowmb(0x00000000 | top_field, VCAP_VP_CTRL);
-	writel_iowmb(0x00010000 | top_field, VCAP_VP_CTRL);
-	enable_irq(dev->vpirq->start);
-
-	do_gettimeofday(&tv);
-	dev->dbg_p.vp_timestamp = (uint32_t) (tv.tv_sec * VCAP_USEC +
-	tv.tv_usec);
-
-	writel_iowmb(irq, VCAP_VP_INT_CLEAR);
-}
-
-irqreturn_t vp_handler(struct vcap_dev *dev)
-{
-	struct vcap_client_data *c_data;
-	struct vp_action *vp_act;
-	struct v4l2_event v4l2_evt;
-	uint32_t irq;
-	int rc;
-	struct timeval tv;
-	uint32_t new_ts;
-
-	irq = readl_relaxed(VCAP_VP_INT_STATUS);
-	if (dev->vp_dummy_event == true) {
-		writel_relaxed(irq, VCAP_VP_INT_CLEAR);
-		dev->vp_dummy_complete = true;
-		wake_up(&dev->vp_dummy_waitq);
-		return IRQ_HANDLED;
-	}
-
-	if (irq & 0x02000000) {
-		v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
-			VCAP_VP_REG_R_ERR_EVENT;
-		v4l2_event_queue(dev->vfd, &v4l2_evt);
-	}
-	if (irq & 0x01000000) {
-		v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
-			VCAP_VP_REG_W_ERR_EVENT;
-		v4l2_event_queue(dev->vfd, &v4l2_evt);
-	}
-	if (irq & 0x00020000) {
-		v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
-			VCAP_VP_IN_HEIGHT_ERR_EVENT;
-		v4l2_event_queue(dev->vfd, &v4l2_evt);
-	}
-	if (irq & 0x00010000) {
-		v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
-			VCAP_VP_IN_WIDTH_ERR_EVENT;
-		v4l2_event_queue(dev->vfd, &v4l2_evt);
-	}
-
-	pr_debug("%s: irq=0x%08x\n", __func__, irq);
-	if (!(irq & (VP_PIC_DONE | VP_MODE_CHANGE))) {
-		writel_relaxed(irq, VCAP_VP_INT_CLEAR);
-		pr_err("VP IRQ shows some error\n");
-		return IRQ_HANDLED;
-	}
-
-	if (dev->vp_client == NULL) {
-		writel_relaxed(irq, VCAP_VP_INT_CLEAR);
-		pr_err("VC: There is no active vp client\n");
-		return IRQ_HANDLED;
-	}
-
-	vp_act = &dev->vp_client->vp_action;
-	c_data = dev->vp_client;
-
-	if (vp_act->vp_state == VP_UNKNOWN) {
-		writel_relaxed(irq, VCAP_VP_INT_CLEAR);
-		pr_err("%s: VP is in an unknown state\n",
-				__func__);
-		return -EAGAIN;
-	}
-
-	do_gettimeofday(&tv);
-	new_ts = (uint32_t) (tv.tv_sec * VCAP_USEC +
-		tv.tv_usec);
-	if (new_ts > dev->dbg_p.vp_timestamp) {
-		dev->dbg_p.vp_ewma = ((new_ts - dev->dbg_p.vp_timestamp) /
-			10 + (dev->dbg_p.vp_ewma / 10 * 9));
-	}
-
-	dev->dbg_p.vp_timestamp = (uint32_t) (tv.tv_sec * VCAP_USEC +
-	tv.tv_usec);
-
-	INIT_WORK(&dev->vp_work.work, vp_wq_fnc);
-	dev->vp_work.cd = c_data;
-	rc = queue_work(dev->vcap_wq, &dev->vp_work.work);
-
-	disable_irq_nosync(dev->vpirq->start);
-	return IRQ_HANDLED;
-}
-
-int vp_sw_reset(struct vcap_dev *dev)
-{
-	int timeout;
-	writel_iowmb(0x00000010, VCAP_SW_RESET_REQ);
-	timeout = 10000;
-	while (1) {
-		if (!(readl_relaxed(VCAP_SW_RESET_STATUS) & 0x10))
-			break;
-		timeout--;
-		if (timeout == 0) {
-			/* This should not happen */
-			pr_err("VP is not resetting properly\n");
-			writel_iowmb(0x00000000, VCAP_SW_RESET_REQ);
-			return -EINVAL;
-		}
-	}
-	return 0;
-}
-
-void vp_stop_capture(struct vcap_client_data *c_data)
-{
-	struct vcap_dev *dev = c_data->dev;
-	int rc;
-
-	dev->vp_shutdown = true;
-	flush_workqueue(dev->vcap_wq);
-
-	if (atomic_read(&dev->vp_enabled) == 1) {
-		rc = wait_event_interruptible_timeout(dev->vp_dummy_waitq,
-				!atomic_read(&dev->vp_enabled),
-				msecs_to_jiffies(50));
-		if (rc == 0 && atomic_read(&dev->vp_enabled) == 1) {
-			/* This should not happen, if it does hw is stuck */
-			disable_irq_nosync(dev->vpirq->start);
-			atomic_set(&dev->vp_enabled, 0);
-			pr_err("%s: VP Timeout and VP still running\n",
-				__func__);
-		}
-	}
-
-	vp_sw_reset(dev);
-	dev->vp_shutdown = false;
-}
-
-int config_vp_format(struct vcap_client_data *c_data)
-{
-	struct vcap_dev *dev = c_data->dev;
-	int rc;
-
-	INIT_WORK(&dev->vp_to_vc_work.work, mov_buf_to_vc);
-	dev->vp_to_vc_work.cd = c_data;
-
-	/* SW restart VP */
-	rc = vp_sw_reset(dev);
-	if (rc < 0)
-		return rc;
-
-	/* Film Mode related settings */
-	writel_iowmb(0x00000000, VCAP_VP_FILM_PROJECTION_T0);
-	writel_relaxed(0x00000000, VCAP_VP_FILM_PROJECTION_T2);
-	writel_relaxed(0x00000000, VCAP_VP_FILM_PAST_MAX_PROJ);
-	writel_relaxed(0x00000000, VCAP_VP_FILM_PAST_MIN_PROJ);
-	writel_relaxed(0x00000000, VCAP_VP_FILM_SEQUENCE_HIST);
-	writel_relaxed(0x00000000, VCAP_VP_FILM_MODE_STATE);
-
-	writel_relaxed(0x00000000, VCAP_VP_BAL_VMOTION_STATE);
-	writel_relaxed(0x00000010, VCAP_VP_REDUCT_AVG_MOTION);
-	writel_relaxed(0x40000000, VCAP_VP_REDUCT_AVG_MOTION2);
-	writel_relaxed(0x40000000, VCAP_VP_NR_AVG_LUMA);
-	writel_relaxed(0x40000000, VCAP_VP_NR_AVG_CHROMA);
-	writel_relaxed(0x40000000, VCAP_VP_NR_CTRL_LUMA);
-	writel_relaxed(0x40000000, VCAP_VP_NR_CTRL_CHROMA);
-	writel_relaxed(0x00000000, VCAP_VP_BAL_AVG_BLEND);
-	writel_relaxed(0x00000000, VCAP_VP_VMOTION_HIST);
-	writel_relaxed(0x05047D19, VCAP_VP_FILM_ANALYSIS_CONFIG);
-	writel_relaxed(0x20260200, VCAP_VP_FILM_STATE_CONFIG);
-	writel_relaxed(0x23A60114, VCAP_VP_FVM_CONFIG);
-	writel_relaxed(0x03043210, VCAP_VP_FILM_ANALYSIS_CONFIG2);
-	writel_relaxed(0x04DB7A51, VCAP_VP_MIXED_ANALYSIS_CONFIG);
-	writel_relaxed(0x14224916, VCAP_VP_SPATIAL_CONFIG);
-	writel_relaxed(0x83270400, VCAP_VP_SPATIAL_CONFIG2);
-	writel_relaxed(0x0F000F92, VCAP_VP_SPATIAL_CONFIG3);
-	writel_relaxed(0x00000000, VCAP_VP_TEMPORAL_CONFIG);
-	writel_relaxed(0x00000000, VCAP_VP_PIXEL_DIFF_CONFIG);
-	writel_relaxed(0x0C090511, VCAP_VP_H_FREQ_CONFIG);
-	writel_relaxed(0x0A000000, VCAP_VP_NR_CONFIG);
-	writel_relaxed(0x008F4149, VCAP_VP_NR_LUMA_CONFIG);
-	writel_relaxed(0x008F4149, VCAP_VP_NR_CHROMA_CONFIG);
-	writel_relaxed(0x43C0FD0C, VCAP_VP_BAL_CONFIG);
-	writel_relaxed(0x00000255, VCAP_VP_BAL_MOTION_CONFIG);
-	writel_relaxed(0x24154252, VCAP_VP_BAL_LIGHT_COMB);
-	writel_relaxed(0x10024414, VCAP_VP_BAL_VMOTION_CONFIG);
-	writel_relaxed(0x00000002, VCAP_VP_NR_CONFIG2);
-	writel_relaxed((c_data->vp_out_fmt.height-1)<<16 |
-			(c_data->vp_out_fmt.width - 1), VCAP_VP_FRAME_SIZE);
-	writel_relaxed(0x00000000, VCAP_VP_SPLIT_SCRN_CTRL);
-
-	return 0;
-}
-
-int init_motion_buf(struct vcap_client_data *c_data)
-{
-	int rc;
-	struct vcap_dev *dev = c_data->dev;
-	struct ion_handle *handle = NULL;
-	unsigned long paddr, len, ionflag = 0;
-	void *vaddr;
-	size_t size = ((c_data->vp_out_fmt.width + 63) >> 6) *
-		((c_data->vp_out_fmt.height + 7) >> 3) * 16;
-
-	if (c_data->vp_action.motionHandle) {
-		pr_err("Motion buffer has already been created");
-		return -ENOEXEC;
-	}
-
-	handle = ion_alloc(dev->ion_client, size, SZ_4K,
-			ION_HEAP(ION_CP_MM_HEAP_ID), 0);
-	if (IS_ERR_OR_NULL(handle)) {
-		pr_err("%s: ion_alloc failed\n", __func__);
-		return -ENOMEM;
-	}
-
-	rc = ion_handle_get_flags(dev->ion_client, handle, &ionflag);
-	if (rc) {
-		pr_err("%s: get flags ion handle failed\n", __func__);
-		ion_free(dev->ion_client, handle);
-		return rc;
-	}
-
-	vaddr = ion_map_kernel(dev->ion_client, handle);
-	if (IS_ERR(vaddr)) {
-		pr_err("%s: Map motion buffer failed\n", __func__);
-		ion_free(dev->ion_client, handle);
-		rc = -ENOMEM;
-		return rc;
-	}
-
-	memset(vaddr, 0, size);
-	ion_unmap_kernel(dev->ion_client, handle);
-
-	rc = ion_map_iommu(dev->ion_client, handle,
-		dev->domain_num, 0, SZ_4K, 0, &paddr, &len,
-		0, 0);
-	if (rc < 0) {
-		pr_err("%s: map_iommu failed\n", __func__);
-		ion_free(dev->ion_client, handle);
-		return rc;
-	}
-
-	c_data->vp_action.motionHandle = handle;
-
-	vaddr = NULL;
-
-	writel_iowmb(paddr, VCAP_VP_MOTION_EST_ADDR);
-	return 0;
-}
-
-void deinit_motion_buf(struct vcap_client_data *c_data)
-{
-	struct vcap_dev *dev = c_data->dev;
-	if (!c_data->vp_action.motionHandle) {
-		pr_err("Motion buffer has not been created");
-		return;
-	}
-
-	writel_iowmb(0x00000000, VCAP_VP_MOTION_EST_ADDR);
-	ion_unmap_iommu(dev->ion_client, c_data->vp_action.motionHandle,
-			dev->domain_num, 0);
-	ion_free(dev->ion_client, c_data->vp_action.motionHandle);
-	c_data->vp_action.motionHandle = NULL;
-	return;
-}
-
-int init_nr_buf(struct vcap_client_data *c_data)
-{
-	struct vcap_dev *dev = c_data->dev;
-	struct ion_handle *handle = NULL;
-	size_t frame_size, tot_size;
-	unsigned long paddr, len;
-	int rc;
-
-	if (c_data->vp_action.bufNR.nr_handle) {
-		pr_err("NR buffer has already been created");
-		return -ENOEXEC;
-	}
-
-	frame_size = c_data->vp_in_fmt.width * c_data->vp_in_fmt.height;
-	if (c_data->vp_in_fmt.pixfmt == V4L2_PIX_FMT_NV16)
-		tot_size = frame_size * 2;
-	else
-		tot_size = frame_size / 2 * 3;
-
-	handle = ion_alloc(dev->ion_client, tot_size, SZ_4K,
-			ION_HEAP(ION_CP_MM_HEAP_ID), 0);
-	if (IS_ERR_OR_NULL(handle)) {
-		pr_err("%s: ion_alloc failed\n", __func__);
-		return -ENOMEM;
-	}
-
-	rc = ion_map_iommu(dev->ion_client, handle,
-		dev->domain_num, 0, SZ_4K, 0, &paddr, &len,
-		0, 0);
-	if (rc < 0) {
-		pr_err("%s: map_iommu failed\n", __func__);
-		ion_free(dev->ion_client, handle);
-		return rc;
-	}
-
-	c_data->vp_action.bufNR.nr_handle = handle;
-	update_nr_value(dev);
-
-	c_data->vp_action.bufNR.paddr = paddr;
-	rc = readl_relaxed(VCAP_VP_NR_CONFIG2);
-	rc |= (((c_data->vp_out_fmt.width / 16) << 20) | 0x1);
-	writel_relaxed(rc, VCAP_VP_NR_CONFIG2);
-	writel_relaxed(paddr, VCAP_VP_NR_T2_Y_BASE_ADDR);
-	writel_relaxed(paddr + frame_size, VCAP_VP_NR_T2_C_BASE_ADDR);
-	c_data->vp_action.bufNR.nr_pos = NRT2_BUF;
-	return 0;
-}
-
-void deinit_nr_buf(struct vcap_client_data *c_data)
-{
-	struct vcap_dev *dev = c_data->dev;
-	struct nr_buffer *buf;
-	uint32_t rc;
-
-	if (!c_data->vp_action.bufNR.nr_handle) {
-		pr_err("NR buffer has not been created");
-		return;
-	}
-	buf = &c_data->vp_action.bufNR;
-
-	rc = readl_relaxed(VCAP_VP_NR_CONFIG2);
-	rc &= !(0x0FF00001);
-	writel_relaxed(rc, VCAP_VP_NR_CONFIG2);
-
-	ion_unmap_iommu(dev->ion_client, buf->nr_handle, dev->domain_num, 0);
-	ion_free(dev->ion_client, buf->nr_handle);
-	buf->nr_handle = NULL;
-	buf->paddr = 0;
-	return;
-}
-
-int nr_s_param(struct vcap_client_data *c_data, struct nr_param *param)
-{
-	if (param->mode != NR_MANUAL)
-		return 0;
-
-	/* Verify values in range */
-	if (param->window > VP_NR_MAX_WINDOW)
-		return -EINVAL;
-	if (param->luma.max_blend_ratio > VP_NR_MAX_RATIO)
-		return -EINVAL;
-	if (param->luma.scale_diff_ratio > VP_NR_MAX_RATIO)
-		return -EINVAL;
-	if (param->luma.diff_limit_ratio > VP_NR_MAX_RATIO)
-		return -EINVAL;
-	if (param->luma.scale_motion_ratio > VP_NR_MAX_RATIO)
-		return -EINVAL;
-	if (param->luma.blend_limit_ratio > VP_NR_MAX_RATIO)
-		return -EINVAL;
-	if (param->chroma.max_blend_ratio > VP_NR_MAX_RATIO)
-		return -EINVAL;
-	if (param->chroma.scale_diff_ratio > VP_NR_MAX_RATIO)
-		return -EINVAL;
-	if (param->chroma.diff_limit_ratio > VP_NR_MAX_RATIO)
-		return -EINVAL;
-	if (param->chroma.scale_motion_ratio > VP_NR_MAX_RATIO)
-		return -EINVAL;
-	if (param->chroma.blend_limit_ratio > VP_NR_MAX_RATIO)
-		return -EINVAL;
-	return 0;
-}
-
-void nr_g_param(struct vcap_client_data *c_data, struct nr_param *param)
-{
-	struct vcap_dev *dev = c_data->dev;
-	uint32_t rc;
-	rc = readl_relaxed(VCAP_VP_NR_CONFIG);
-	param->window = BITS_VALUE(rc, 24, 4);
-	param->decay_ratio = BITS_VALUE(rc, 20, 3);
-
-	rc = readl_relaxed(VCAP_VP_NR_LUMA_CONFIG);
-	param->threshold = NR_THRESHOLD_STATIC;
-	if (BITS_VALUE(rc, 16, 1))
-		param->threshold = NR_THRESHOLD_DYNAMIC;
-	param->luma.max_blend_ratio = BITS_VALUE(rc, 24, 4);
-	param->luma.scale_diff_ratio = BITS_VALUE(rc, 12, 4);
-	param->luma.diff_limit_ratio = BITS_VALUE(rc, 8, 4);
-	param->luma.scale_motion_ratio = BITS_VALUE(rc, 4, 4);
-	param->luma.blend_limit_ratio = BITS_VALUE(rc, 0, 4);
-
-	rc = readl_relaxed(VCAP_VP_NR_CHROMA_CONFIG);
-	param->chroma.max_blend_ratio = BITS_VALUE(rc, 24, 4);
-	param->chroma.scale_diff_ratio = BITS_VALUE(rc, 12, 4);
-	param->chroma.diff_limit_ratio = BITS_VALUE(rc, 8, 4);
-	param->chroma.scale_motion_ratio = BITS_VALUE(rc, 4, 4);
-	param->chroma.blend_limit_ratio = BITS_VALUE(rc, 0, 4);
-}
-
-void s_default_nr_val(struct nr_param *param)
-{
-	param->threshold = NR_THRESHOLD_STATIC;
-	param->window = 10;
-	param->decay_ratio = 0;
-	param->luma.max_blend_ratio = 0;
-	param->luma.scale_diff_ratio = 4;
-	param->luma.diff_limit_ratio = 1;
-	param->luma.scale_motion_ratio = 4;
-	param->luma.blend_limit_ratio = 9;
-	param->chroma.max_blend_ratio = 0;
-	param->chroma.scale_diff_ratio = 4;
-	param->chroma.diff_limit_ratio = 1;
-	param->chroma.scale_motion_ratio = 4;
-	param->chroma.blend_limit_ratio = 9;
-}
-
-int vp_dummy_event(struct vcap_client_data *c_data)
-{
-	struct vcap_dev *dev = c_data->dev;
-	unsigned int width, height;
-	struct ion_handle *handle = NULL;
-	unsigned long paddr, len;
-	uint32_t reg;
-	int rc = 0;
-
-	pr_debug("%s: Start VP dummy event\n", __func__);
-	handle = ion_alloc(dev->ion_client, 0x1200, SZ_4K,
-			ION_HEAP(ION_CP_MM_HEAP_ID), 0);
-	if (IS_ERR_OR_NULL(handle)) {
-		pr_err("%s: ion_alloc failed\n", __func__);
-		return -ENOMEM;
-	}
-
-	rc = ion_map_iommu(dev->ion_client, handle,
-		dev->domain_num, 0, SZ_4K, 0, &paddr, &len,
-		0, 0);
-	if (rc < 0) {
-		pr_err("%s: map_iommu failed\n", __func__);
-		ion_free(dev->ion_client, handle);
-		return rc;
-	}
-
-	width = c_data->vp_out_fmt.width;
-	height = c_data->vp_out_fmt.height;
-
-	c_data->vp_out_fmt.width = 0x3F;
-	c_data->vp_out_fmt.height = 0x16;
-
-	config_vp_format(c_data);
-	writel_relaxed(paddr, VCAP_VP_T1_Y_BASE_ADDR);
-	writel_relaxed(paddr + 0x2C0, VCAP_VP_T1_C_BASE_ADDR);
-	writel_relaxed(paddr + 0x440, VCAP_VP_T2_Y_BASE_ADDR);
-	writel_relaxed(paddr + 0x700, VCAP_VP_T2_C_BASE_ADDR);
-	writel_relaxed(paddr + 0x880, VCAP_VP_OUT_Y_BASE_ADDR);
-	writel_relaxed(paddr + 0xB40, VCAP_VP_OUT_C_BASE_ADDR);
-	writel_iowmb(paddr + 0x1100, VCAP_VP_MOTION_EST_ADDR);
-	writel_relaxed(4 << 20 | 0x2 << 4, VCAP_VP_IN_CONFIG);
-	writel_relaxed(4 << 20 | 0x1 << 4, VCAP_VP_OUT_CONFIG);
-
-	dev->vp_dummy_event = true;
-
-	enable_irq(dev->vpirq->start);
-	writel_relaxed(0x01100101, VCAP_VP_INTERRUPT_ENABLE);
-	writel_iowmb(0x00000000, VCAP_VP_CTRL);
-	writel_iowmb(0x00010000, VCAP_VP_CTRL);
-
-	rc = wait_event_interruptible_timeout(dev->vp_dummy_waitq,
-		dev->vp_dummy_complete, msecs_to_jiffies(50));
-	if (!rc && !dev->vp_dummy_complete) {
-		pr_err("%s: VP dummy event timeout", __func__);
-		rc = -ETIME;
-
-		vp_sw_reset(dev);
-		dev->vp_dummy_complete = false;
-	}
-
-	writel_relaxed(0x00000000, VCAP_VP_INTERRUPT_ENABLE);
-	disable_irq(dev->vpirq->start);
-	dev->vp_dummy_event = false;
-
-	reg = readl_relaxed(VCAP_OFFSET(0x0D94));
-	writel_relaxed(reg, VCAP_OFFSET(0x0D9C));
-
-	c_data->vp_out_fmt.width = width;
-	c_data->vp_out_fmt.height = height;
-	ion_unmap_iommu(dev->ion_client, handle, dev->domain_num, 0);
-	ion_free(dev->ion_client, handle);
-
-	pr_debug("%s: Exit VP dummy event\n", __func__);
-	return rc;
-}
-
-int kickoff_vp(struct vcap_client_data *c_data)
-{
-	struct vcap_dev *dev;
-	struct vp_action *vp_act;
-	struct timeval tv;
-	unsigned long flags = 0;
-	unsigned int chroma_fmt = 0;
-	int size;
-	bool top_field = 0;
-
-	if (!c_data->streaming)
-		return -ENOEXEC;
-
-	dev = c_data->dev;
-	pr_debug("Start VP Kickoff\n");
-
-	if (dev->vp_client == NULL) {
-		pr_err("No active vp client\n");
-		return -ENODEV;
-	}
-	vp_act = &dev->vp_client->vp_action;
-
-	spin_lock_irqsave(&dev->vp_client->cap_slock, flags);
-	if (list_empty(&vp_act->in_active)) {
-		spin_unlock_irqrestore(&dev->vp_client->cap_slock, flags);
-		pr_err("%s: VP We have no more input buffers\n",
-				__func__);
-		return -EAGAIN;
-	}
-
-	vp_act->bufT1 = list_entry(vp_act->in_active.next,
-			struct vcap_buffer, list);
-	list_del(&vp_act->bufT1->list);
-
-	if (list_empty(&vp_act->in_active)) {
-		spin_unlock_irqrestore(&dev->vp_client->cap_slock, flags);
-		list_add(&vp_act->bufT1->list, &vp_act->in_active);
-		pr_err("%s: VP We have no more input buffers\n",
-				__func__);
-		return -EAGAIN;
-	}
-
-	vp_act->bufT2 = list_entry(vp_act->in_active.next,
-			struct vcap_buffer, list);
-	list_del(&vp_act->bufT2->list);
-
-	if (list_empty(&vp_act->out_active)) {
-		spin_unlock_irqrestore(&dev->vp_client->cap_slock, flags);
-		list_add(&vp_act->bufT2->list, &vp_act->in_active);
-		list_add(&vp_act->bufT1->list, &vp_act->in_active);
-		pr_err("%s: VP We have no more output buffers\n",
-				__func__);
-		return -EAGAIN;
-	}
-
-	vp_act->bufOut = list_entry(vp_act->out_active.next,
-			struct vcap_buffer, list);
-	list_del(&vp_act->bufOut->list);
-	spin_unlock_irqrestore(&dev->vp_client->cap_slock, flags);
-
-	size = c_data->vp_in_fmt.height * c_data->vp_in_fmt.width;
-	writel_relaxed(vp_act->bufT1->paddr, VCAP_VP_T1_Y_BASE_ADDR);
-	writel_relaxed(vp_act->bufT1->paddr + size, VCAP_VP_T1_C_BASE_ADDR);
-
-	config_in_buffer(c_data, vp_act->bufT2);
-	config_out_buffer(c_data, vp_act->bufOut);
-
-	/* Config VP */
-	if (c_data->vp_in_fmt.pixfmt == V4L2_PIX_FMT_NV16)
-		chroma_fmt = 1;
-	writel_relaxed((c_data->vp_in_fmt.width / 16) << 20 |
-			chroma_fmt << 11 | 0x2 << 4, VCAP_VP_IN_CONFIG);
-
-	chroma_fmt = 0;
-	if (c_data->vp_out_fmt.pixfmt == V4L2_PIX_FMT_NV16)
-		chroma_fmt = 1;
-
-	writel_relaxed((c_data->vp_out_fmt.width / 16) << 20 |
-			chroma_fmt << 11 | 0x1 << 4, VCAP_VP_OUT_CONFIG);
-
-	/* Enable Interrupt */
-	if (vp_act->bufT2->vb.v4l2_buf.field == V4L2_FIELD_BOTTOM)
-		top_field = 1;
-	vp_act->vp_state = VP_FRAME2;
-	writel_relaxed(0x01100001, VCAP_VP_INTERRUPT_ENABLE);
-	writel_iowmb(0x00000000 | top_field, VCAP_VP_CTRL);
-	writel_iowmb(0x00010000 | top_field, VCAP_VP_CTRL);
-	atomic_set(&c_data->dev->vp_enabled, 1);
-	enable_irq(dev->vpirq->start);
-
-	do_gettimeofday(&tv);
-	dev->dbg_p.vp_timestamp = (uint32_t) (tv.tv_sec * VCAP_USEC +
-	tv.tv_usec);
-
-	return 0;
-}
-
-int continue_vp(struct vcap_client_data *c_data)
-{
-	struct vcap_dev *dev;
-	struct vp_action *vp_act;
-	struct timeval tv;
-	int rc;
-	bool top_field = 0;
-
-	pr_debug("Start VP Continue\n");
-	dev = c_data->dev;
-
-	if (dev->vp_client == NULL) {
-		pr_err("No active vp client\n");
-		return -ENODEV;
-	}
-	vp_act = &dev->vp_client->vp_action;
-
-	if (vp_act->vp_state == VP_UNKNOWN) {
-		pr_err("%s: VP is in an unknown state\n",
-				__func__);
-		return -EAGAIN;
-	}
-
-	rc = vp_setup_buffers(c_data);
-	if (rc < 0)
-		return rc;
-
-	if (vp_act->bufT2->vb.v4l2_buf.field == V4L2_FIELD_BOTTOM)
-		top_field = 1;
-
-	/* Config VP & Enable Interrupt */
-	writel_relaxed(0x01100001, VCAP_VP_INTERRUPT_ENABLE);
-	writel_iowmb(0x00000000 | top_field, VCAP_VP_CTRL);
-	writel_iowmb(0x00010000 | top_field, VCAP_VP_CTRL);
-
-	atomic_set(&c_data->dev->vp_enabled, 1);
-	enable_irq(dev->vpirq->start);
-
-	do_gettimeofday(&tv);
-	dev->dbg_p.vp_timestamp = (uint32_t) (tv.tv_sec * VCAP_USEC +
-	tv.tv_usec);
-
-	return 0;
-}
diff --git a/drivers/media/video/vcap_vp.h b/drivers/media/video/vcap_vp.h
deleted file mode 100644
index 70b10c3..0000000
--- a/drivers/media/video/vcap_vp.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 VCAP_VP_H
-#define VCAP_VP_H
-
-#include <linux/interrupt.h>
-
-#include <media/vcap_v4l2.h>
-
-#define VCAP_VP_INT_STATUS (VCAP_BASE + 0x404)
-#define VCAP_VP_INT_CLEAR (VCAP_BASE + 0x40C)
-
-#define VCAP_VP_SW_RESET (VCAP_BASE + 0x410)
-#define VCAP_VP_INTERRUPT_ENABLE (VCAP_BASE + 0x408)
-
-#define VCAP_VP_FILM_PROJECTION_T0 (VCAP_BASE + 0x50C)
-#define VCAP_VP_FILM_PROJECTION_T2 (VCAP_BASE + 0x508)
-#define VCAP_VP_FILM_PAST_MAX_PROJ (VCAP_BASE + 0x510)
-#define VCAP_VP_FILM_PAST_MIN_PROJ (VCAP_BASE + 0x514)
-#define VCAP_VP_FILM_SEQUENCE_HIST (VCAP_BASE + 0x504)
-#define VCAP_VP_FILM_MODE_STATE (VCAP_BASE + 0x500)
-
-#define VCAP_VP_BAL_VMOTION_STATE (VCAP_BASE + 0x690)
-#define VCAP_VP_REDUCT_AVG_MOTION (VCAP_BASE + 0x610)
-#define VCAP_VP_REDUCT_AVG_MOTION2 (VCAP_BASE + 0x614)
-
-#define VCAP_VP_NR_AVG_LUMA (VCAP_BASE + 0x608)
-#define VCAP_VP_NR_AVG_CHROMA (VCAP_BASE + 0x60C)
-#define VCAP_VP_NR_CTRL_LUMA (VCAP_BASE + 0x600)
-#define VCAP_VP_NR_CTRL_CHROMA (VCAP_BASE + 0x604)
-
-#define VCAP_VP_BAL_AVG_BLEND (VCAP_BASE + 0x694)
-#define VCAP_VP_VMOTION_HIST (VCAP_BASE + 0x6F8)
-
-#define VCAP_VP_MOTION_EST_ADDR (VCAP_BASE + 0x4E0)
-#define VCAP_VP_FILM_ANALYSIS_CONFIG (VCAP_BASE + 0x520)
-#define VCAP_VP_FILM_STATE_CONFIG (VCAP_BASE + 0x524)
-
-#define VCAP_VP_FVM_CONFIG (VCAP_BASE + 0x550)
-#define VCAP_VP_FILM_ANALYSIS_CONFIG2 (VCAP_BASE + 0x52C)
-#define VCAP_VP_MIXED_ANALYSIS_CONFIG (VCAP_BASE + 0x530)
-
-#define VCAP_VP_SPATIAL_CONFIG (VCAP_BASE + 0x580)
-#define VCAP_VP_SPATIAL_CONFIG2 (VCAP_BASE + 0x584)
-#define VCAP_VP_SPATIAL_CONFIG3 (VCAP_BASE + 0x588)
-#define VCAP_VP_TEMPORAL_CONFIG (VCAP_BASE + 0x5C0)
-
-#define VCAP_VP_PIXEL_DIFF_CONFIG (VCAP_BASE + 0x6FC)
-#define VCAP_VP_H_FREQ_CONFIG (VCAP_BASE + 0x528)
-#define VCAP_VP_NR_CONFIG (VCAP_BASE + 0x620)
-#define VCAP_VP_NR_LUMA_CONFIG (VCAP_BASE + 0x624)
-#define VCAP_VP_NR_CHROMA_CONFIG (VCAP_BASE + 0x628)
-#define VCAP_VP_BAL_CONFIG (VCAP_BASE + 0x680)
-#define VCAP_VP_BAL_MOTION_CONFIG (VCAP_BASE + 0x684)
-#define VCAP_VP_BAL_LIGHT_COMB (VCAP_BASE + 0x688)
-#define VCAP_VP_BAL_VMOTION_CONFIG (VCAP_BASE + 0x68C)
-
-#define VCAP_VP_NR_CONFIG2 (VCAP_BASE + 0x484)
-#define VCAP_VP_FRAME_SIZE (VCAP_BASE + 0x48C)
-#define VCAP_VP_SPLIT_SCRN_CTRL (VCAP_BASE + 0x750)
-
-#define VCAP_VP_IN_CONFIG (VCAP_BASE + 0x480)
-#define VCAP_VP_OUT_CONFIG (VCAP_BASE + 0x488)
-
-#define VCAP_VP_T2_Y_BASE_ADDR (VCAP_BASE + 0x4C0)
-#define VCAP_VP_T2_C_BASE_ADDR (VCAP_BASE + 0x4C4)
-#define VCAP_VP_OUT_Y_BASE_ADDR (VCAP_BASE + 0x4CC)
-#define VCAP_VP_OUT_C_BASE_ADDR (VCAP_BASE + 0x4D0)
-#define VCAP_VP_OUT_CR_BASE_ADDR (VCAP_BASE + 0x4D4)
-
-#define VCAP_VP_CTRL (VCAP_BASE + 0x4D8)
-
-#define VCAP_VP_T1_Y_BASE_ADDR (VCAP_BASE + 0x4A8)
-#define VCAP_VP_T1_C_BASE_ADDR (VCAP_BASE + 0x4Ac)
-#define VCAP_VP_NR_T2_Y_BASE_ADDR (VCAP_BASE + 0x4B4)
-#define VCAP_VP_NR_T2_C_BASE_ADDR (VCAP_BASE + 0x4B8)
-
-#define VP_PIC_DONE (0x1 << 0)
-#define VP_MODE_CHANGE (0x1 << 8)
-
-#define VP_NR_MAX_WINDOW 120
-#define VP_NR_MAX_RATIO  16
-#define VP_NR_DYNAMIC_THRESHOLD 0x000F0000
-
-#define BITS_MASK(start, num_of_bits) \
-	(((1 << (num_of_bits)) - 1) << (start))
-
-#define BITS_VALUE(x, start, num_of_bits)  \
-	(((x) & BITS_MASK(start, num_of_bits)) >> (start))
-
-irqreturn_t vp_handler(struct vcap_dev *dev);
-int config_vp_format(struct vcap_client_data *c_data);
-void vp_stop_capture(struct vcap_client_data *c_data);
-int init_motion_buf(struct vcap_client_data *c_data);
-void deinit_motion_buf(struct vcap_client_data *c_data);
-int init_nr_buf(struct vcap_client_data *c_data);
-void deinit_nr_buf(struct vcap_client_data *c_data);
-int nr_s_param(struct vcap_client_data *c_data, struct nr_param *param);
-void nr_g_param(struct vcap_client_data *c_data, struct nr_param *param);
-void s_default_nr_val(struct nr_param *param);
-int kickoff_vp(struct vcap_client_data *c_data);
-int continue_vp(struct vcap_client_data *c_data);
-int vp_dummy_event(struct vcap_client_data *c_data);
-
-#endif
diff --git a/drivers/media/video/videobuf-msm-mem.c b/drivers/media/video/videobuf-msm-mem.c
index 5646f9f..9e2cc22 100644
--- a/drivers/media/video/videobuf-msm-mem.c
+++ b/drivers/media/video/videobuf-msm-mem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. All rights reserved.
  *
  * Based on videobuf-dma-contig.c,
  * (c) 2008 Magnus Damm
diff --git a/drivers/media/video/videobuf2-msm-mem.c b/drivers/media/video/videobuf2-msm-mem.c
index 97bc7c3..cd07db8 100644
--- a/drivers/media/video/videobuf2-msm-mem.c
+++ b/drivers/media/video/videobuf2-msm-mem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * Based on videobuf-dma-contig.c,
  * (c) 2008 Magnus Damm
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 464f19f..ff0fc74 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1054,6 +1054,16 @@
 	  The WCD9320 codec support either I2C/I2S or Slimbus for
 	  control and data exchnage with master processor.
 
+config WCD9306_CODEC
+	tristate "WCD9306 Codec"
+	select SLIMBUS
+	select MFD_CORE
+	help
+	  Enables the WCD9xxx codec core driver. The core driver provides
+	  read/write capability to registers which are part of the
+	  WCD9306 core and gives the ability to use the WCD9306 codec.
+	  The WCD9306 codec supports either I2C/I2S or Slimbus for
+	  control and data exchnage with master processor.
 
 config MFD_RC5T583
 	bool "Ricoh RC5T583 Power Management system device"
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 07552c8..ce65e3f 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -81,6 +81,7 @@
 obj-$(CONFIG_WCD9310_CODEC)       += wcd9xxx-core.o wcd9xxx-irq.o wcd9xxx-slimslave.o
 obj-$(CONFIG_WCD9304_CODEC)       += wcd9xxx-core.o wcd9xxx-irq.o wcd9xxx-slimslave.o
 obj-$(CONFIG_WCD9320_CODEC)       += wcd9xxx-core.o wcd9xxx-irq.o wcd9xxx-slimslave.o
+obj-$(CONFIG_WCD9306_CODEC)       += wcd9xxx-core.o wcd9xxx-irq.o wcd9xxx-slimslave.o
 
 
 ifeq ($(CONFIG_SA1100_ASSABET),y)
diff --git a/drivers/mfd/marimba-codec.c b/drivers/mfd/marimba-codec.c
index 6416e0a..2ba251c 100644
--- a/drivers/mfd/marimba-codec.c
+++ b/drivers/mfd/marimba-codec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/drivers/mfd/marimba-core.c b/drivers/mfd/marimba-core.c
index 26f3ece..dfe11f7 100644
--- a/drivers/mfd/marimba-core.c
+++ b/drivers/mfd/marimba-core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/drivers/mfd/marimba-tsadc.c b/drivers/mfd/marimba-tsadc.c
index 32b93e1..c933b48 100644
--- a/drivers/mfd/marimba-tsadc.c
+++ b/drivers/mfd/marimba-tsadc.c
@@ -1,7 +1,7 @@
 /*
  * Marimba TSADC driver.
  *
- * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-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
diff --git a/drivers/mfd/msm-adie-codec.c b/drivers/mfd/msm-adie-codec.c
index d9414ed..b9e317e 100644
--- a/drivers/mfd/msm-adie-codec.c
+++ b/drivers/mfd/msm-adie-codec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/mfd/pm8018-core.c b/drivers/mfd/pm8018-core.c
index a91152f..ab45738 100644
--- a/drivers/mfd/pm8018-core.c
+++ b/drivers/mfd/pm8018-core.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/drivers/mfd/pm8038-core.c b/drivers/mfd/pm8038-core.c
index 4996279..803920f 100644
--- a/drivers/mfd/pm8038-core.c
+++ b/drivers/mfd/pm8038-core.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
@@ -711,6 +711,8 @@
 	}
 
 	if (pdata->ccadc_pdata) {
+		pdata->ccadc_pdata->ccadc_cdata.batt_temp_channel
+						= CHANNEL_BATT_THERM;
 		ccadc_cell.platform_data = pdata->ccadc_pdata;
 		ccadc_cell.pdata_size =
 				sizeof(struct pm8xxx_ccadc_platform_data);
diff --git a/drivers/mfd/pm8821-core.c b/drivers/mfd/pm8821-core.c
index fe3e67e..48ec748 100644
--- a/drivers/mfd/pm8821-core.c
+++ b/drivers/mfd/pm8821-core.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/drivers/mfd/pm8821-irq.c b/drivers/mfd/pm8821-irq.c
index ff68c08..201fab7 100644
--- a/drivers/mfd/pm8821-irq.c
+++ b/drivers/mfd/pm8821-irq.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c
index 7d63129..088c756 100644
--- a/drivers/mfd/pm8921-core.c
+++ b/drivers/mfd/pm8921-core.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
@@ -804,6 +804,8 @@
 	}
 
 	if (pdata->ccadc_pdata) {
+		pdata->ccadc_pdata->ccadc_cdata.batt_temp_channel
+						= CHANNEL_BATT_THERM;
 		ccadc_cell.platform_data = pdata->ccadc_pdata;
 		ccadc_cell.pdata_size =
 				sizeof(struct pm8xxx_ccadc_platform_data);
diff --git a/drivers/mfd/pm8xxx-batt-alarm.c b/drivers/mfd/pm8xxx-batt-alarm.c
index 1d30db9..88aab98 100644
--- a/drivers/mfd/pm8xxx-batt-alarm.c
+++ b/drivers/mfd/pm8xxx-batt-alarm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/mfd/pm8xxx-debug.c b/drivers/mfd/pm8xxx-debug.c
index d450db3..b58b6fe 100644
--- a/drivers/mfd/pm8xxx-debug.c
+++ b/drivers/mfd/pm8xxx-debug.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/drivers/mfd/pm8xxx-irq.c b/drivers/mfd/pm8xxx-irq.c
index cc156b3..999b53f 100644
--- a/drivers/mfd/pm8xxx-irq.c
+++ b/drivers/mfd/pm8xxx-irq.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/drivers/mfd/pm8xxx-misc.c b/drivers/mfd/pm8xxx-misc.c
index fb57bd0..fce1547 100644
--- a/drivers/mfd/pm8xxx-misc.c
+++ b/drivers/mfd/pm8xxx-misc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/drivers/mfd/pm8xxx-pwm.c b/drivers/mfd/pm8xxx-pwm.c
index 0e4240c..caaba81 100644
--- a/drivers/mfd/pm8xxx-pwm.c
+++ b/drivers/mfd/pm8xxx-pwm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/drivers/mfd/pm8xxx-spk.c b/drivers/mfd/pm8xxx-spk.c
index 4366717..84eafceb 100644
--- a/drivers/mfd/pm8xxx-spk.c
+++ b/drivers/mfd/pm8xxx-spk.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/mfd/pmic8058.c b/drivers/mfd/pmic8058.c
index 8f7ab2d..7ecd73e 100644
--- a/drivers/mfd/pmic8058.c
+++ b/drivers/mfd/pmic8058.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/drivers/mfd/pmic8901.c b/drivers/mfd/pmic8901.c
index 955258c..1ca5331 100644
--- a/drivers/mfd/pmic8901.c
+++ b/drivers/mfd/pmic8901.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/mfd/timpani-codec.c b/drivers/mfd/timpani-codec.c
index 1e0a839..164ffcc 100644
--- a/drivers/mfd/timpani-codec.c
+++ b/drivers/mfd/timpani-codec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/mfd/tps65023.c b/drivers/mfd/tps65023.c
index 318692f..546aded 100644
--- a/drivers/mfd/tps65023.c
+++ b/drivers/mfd/tps65023.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c
index d43b399..6c60e04 100644
--- a/drivers/mfd/wcd9xxx-core.c
+++ b/drivers/mfd/wcd9xxx-core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -46,6 +46,11 @@
 #define WCD9XXX_I2C_DIGITAL_1	2
 #define WCD9XXX_I2C_DIGITAL_2	3
 
+/* Number of return values needs to be checked for each
+ * registration of Slimbus of I2C bus for each codec
+ */
+#define NUM_WCD9XXX_REG_RET	8
+
 struct wcd9xxx_i2c {
 	struct i2c_client *client;
 	struct i2c_msg xfer_msg[2];
@@ -54,10 +59,15 @@
 };
 
 static char *taiko_supplies[] = {
-	"cdc-vdd-buck", "cdc-vdd-tx-h", "cdc-vdd-rx-h", "cdc-vddpx-1",
+	WCD9XXX_SUPPLY_BUCK_NAME, "cdc-vdd-tx-h", "cdc-vdd-rx-h", "cdc-vddpx-1",
 	"cdc-vdd-a-1p2v", "cdc-vddcx-1", "cdc-vddcx-2",
 };
 
+static char *tapan_supplies[] = {
+	WCD9XXX_SUPPLY_BUCK_NAME, "cdc-vdd-h", "cdc-vdd-px",
+	"cdc-vdd-a-1p2v", "cdc-vdd-cx"
+};
+
 static int wcd9xxx_dt_parse_vreg_info(struct device *dev,
 	struct wcd9xxx_regulator *vreg, const char *vreg_name);
 static int wcd9xxx_dt_parse_micbias_info(struct device *dev,
@@ -275,24 +285,52 @@
 	},
 };
 
+static struct mfd_cell tapan_devs[] = {
+	{
+		.name = "tapan_codec",
+	},
+};
+
 static struct wcd9xx_codec_type {
 	u8 byte[4];
 	struct mfd_cell *dev;
 	int size;
 	int num_irqs;
+	int version; /* -1 to retrive version from chip version register */
+	enum wcd9xxx_slim_slave_addr_type slim_slave_type;
 } wcd9xxx_codecs[] = {
-	{{0x2, 0x0, 0x0, 0x1}, tabla_devs, ARRAY_SIZE(tabla_devs),
-	 TABLA_NUM_IRQS},
-	{{0x1, 0x0, 0x0, 0x1}, tabla1x_devs, ARRAY_SIZE(tabla1x_devs),
-	 TABLA_NUM_IRQS},
-	{{0x0, 0x0, 0x2, 0x1}, taiko_devs, ARRAY_SIZE(taiko_devs),
-	 TAIKO_NUM_IRQS},
-	{{0x0, 0x0, 0x0, 0x1}, sitar_devs, ARRAY_SIZE(sitar_devs),
-	 SITAR_NUM_IRQS},
-	{{0x1, 0x0, 0x1, 0x1}, sitar_devs, ARRAY_SIZE(sitar_devs),
-	 SITAR_NUM_IRQS},
-	{{0x2, 0x0, 0x1, 0x1}, sitar_devs, ARRAY_SIZE(sitar_devs),
-	 SITAR_NUM_IRQS},
+	{
+	 {0x2, 0x0, 0x0, 0x1}, tabla_devs, ARRAY_SIZE(tabla_devs),
+	 TABLA_NUM_IRQS, -1, WCD9XXX_SLIM_SLAVE_ADDR_TYPE_TABLA
+	},
+	{
+	 {0x1, 0x0, 0x0, 0x1}, tabla1x_devs, ARRAY_SIZE(tabla1x_devs),
+	 TABLA_NUM_IRQS, -1, WCD9XXX_SLIM_SLAVE_ADDR_TYPE_TABLA
+	},
+	{ /* wcd9320 version 1 */
+	 {0x0, 0x0, 0x2, 0x1}, taiko_devs, ARRAY_SIZE(taiko_devs),
+	  TAIKO_NUM_IRQS, 1, WCD9XXX_SLIM_SLAVE_ADDR_TYPE_TAIKO
+	},
+	{ /* wcd9320 version 2 */
+	 {0x1, 0x0, 0x2, 0x1}, taiko_devs, ARRAY_SIZE(taiko_devs),
+	 TAIKO_NUM_IRQS, 2, WCD9XXX_SLIM_SLAVE_ADDR_TYPE_TAIKO
+	},
+	{
+	 {0x0, 0x0, 0x3, 0x1}, tapan_devs, ARRAY_SIZE(tapan_devs),
+	 TAPAN_NUM_IRQS, -1, WCD9XXX_SLIM_SLAVE_ADDR_TYPE_TAIKO
+	},
+	{
+	 {0x0, 0x0, 0x0, 0x1}, sitar_devs, ARRAY_SIZE(sitar_devs),
+	 SITAR_NUM_IRQS, -1, WCD9XXX_SLIM_SLAVE_ADDR_TYPE_TABLA
+	},
+	{
+	 {0x1, 0x0, 0x1, 0x1}, sitar_devs, ARRAY_SIZE(sitar_devs),
+	 SITAR_NUM_IRQS, -1, WCD9XXX_SLIM_SLAVE_ADDR_TYPE_TABLA
+	},
+	{
+	 {0x2, 0x0, 0x1, 0x1}, sitar_devs, ARRAY_SIZE(sitar_devs),
+	 SITAR_NUM_IRQS, -1, WCD9XXX_SLIM_SLAVE_ADDR_TYPE_TABLA
+	},
 };
 
 static void wcd9xxx_bring_up(struct wcd9xxx *wcd9xxx)
@@ -316,7 +354,7 @@
 {
 	int ret;
 
-	if (wcd9xxx->reset_gpio) {
+	if (wcd9xxx->reset_gpio && wcd9xxx->slim_device_bootup) {
 		ret = gpio_request(wcd9xxx->reset_gpio, "CDC_RESET");
 		if (ret) {
 			pr_err("%s: Failed to request gpio %d\n", __func__,
@@ -324,7 +362,8 @@
 			wcd9xxx->reset_gpio = 0;
 			return ret;
 		}
-
+	}
+	if (wcd9xxx->reset_gpio) {
 		gpio_direction_output(wcd9xxx->reset_gpio, 0);
 		msleep(20);
 		gpio_direction_output(wcd9xxx->reset_gpio, 1);
@@ -374,6 +413,10 @@
 			*wcd9xxx_dev = wcd9xxx_codecs[i].dev;
 			*wcd9xxx_dev_size = wcd9xxx_codecs[i].size;
 			*wcd9xxx_dev_num_irqs = wcd9xxx_codecs[i].num_irqs;
+			wcd9xxx->slim_slave_type =
+			    wcd9xxx_codecs[i].slim_slave_type;
+			if (wcd9xxx_codecs[i].version > -1)
+				wcd9xxx->version = wcd9xxx_codecs[i].version;
 			break;
 		}
 		i++;
@@ -862,6 +905,7 @@
 		dev_set_drvdata(&client->dev, wcd9xxx);
 		wcd9xxx->dev = &client->dev;
 		wcd9xxx->reset_gpio = pdata->reset_gpio;
+		wcd9xxx->slim_device_bootup = true;
 		if (client->dev.of_node)
 			wcd9xxx->mclk_rate = pdata->mclk_rate;
 		ret = wcd9xxx_enable_supplies(wcd9xxx, pdata);
@@ -987,92 +1031,54 @@
 	return 0;
 }
 
+static int wcd9xxx_read_of_property_u32(struct device *dev,
+	const char *name, u32 *val)
+{
+	int ret = 0;
+	ret = of_property_read_u32(dev->of_node, name, val);
+	if (ret)
+		dev_err(dev, "Looking up %s property in node %s failed",
+				name, dev->of_node->full_name);
+	return ret;
+}
+
 static int wcd9xxx_dt_parse_micbias_info(struct device *dev,
 	struct wcd9xxx_micbias_setting *micbias)
 {
-	int ret = 0;
-	char prop_name[CODEC_DT_MAX_PROP_SIZE];
 	u32 prop_val;
 
-	snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
-			"qcom,cdc-micbias-ldoh-v");
-	ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
-	if (ret) {
-		dev_err(dev, "Looking up %s property in node %s failed",
-			prop_name, dev->of_node->full_name);
-		return -ENODEV;
-	}
-	micbias->ldoh_v  =  (u8)prop_val;
+	if (!(wcd9xxx_read_of_property_u32(dev, "qcom,cdc-micbias-ldoh-v",
+				&prop_val)))
+		micbias->ldoh_v  =  (u8)prop_val;
 
-	snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
-			"qcom,cdc-micbias-cfilt1-mv");
-	ret = of_property_read_u32(dev->of_node, prop_name,
-				   &micbias->cfilt1_mv);
-	if (ret) {
-		dev_err(dev, "Looking up %s property in node %s failed",
-			prop_name, dev->of_node->full_name);
-		return -ENODEV;
-	}
+	wcd9xxx_read_of_property_u32(dev, "qcom,cdc-micbias-cfilt1-mv",
+				&micbias->cfilt1_mv);
 
-	snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
-			"qcom,cdc-micbias-cfilt2-mv");
-	ret = of_property_read_u32(dev->of_node, prop_name,
-				   &micbias->cfilt2_mv);
-	if (ret) {
-		dev_err(dev, "Looking up %s property in node %s failed",
-			prop_name, dev->of_node->full_name);
-		return -ENODEV;
-	}
+	wcd9xxx_read_of_property_u32(dev, "qcom,cdc-micbias-cfilt2-mv",
+				&micbias->cfilt2_mv);
 
-	snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
-			"qcom,cdc-micbias-cfilt3-mv");
-	ret = of_property_read_u32(dev->of_node, prop_name,
-				   &micbias->cfilt3_mv);
-	if (ret) {
-		dev_err(dev, "Looking up %s property in node %s failed",
-			prop_name, dev->of_node->full_name);
-		return -ENODEV;
-	}
+	wcd9xxx_read_of_property_u32(dev, "qcom,cdc-micbias-cfilt3-mv",
+				&micbias->cfilt3_mv);
 
-	snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
-			"qcom,cdc-micbias1-cfilt-sel");
-	ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
-	if (ret) {
-		dev_err(dev, "Looking up %s property in node %s failed",
-			prop_name, dev->of_node->full_name);
-		return -ENODEV;
-	}
-	micbias->bias1_cfilt_sel = (u8)prop_val;
+	/* Read micbias values for codec. Does not matter even if a few
+	 * micbias values are not defined in the Device Tree. Codec will
+	 * anyway not use those values
+	 */
+	if (!(wcd9xxx_read_of_property_u32(dev, "qcom,cdc-micbias1-cfilt-sel",
+				&prop_val)))
+		micbias->bias1_cfilt_sel = (u8)prop_val;
 
-	snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
-			"qcom,cdc-micbias2-cfilt-sel");
-	ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
-	if (ret) {
-		dev_err(dev, "Looking up %s property in node %s failed",
-			prop_name, dev->of_node->full_name);
-		return -ENODEV;
-	}
-	micbias->bias2_cfilt_sel = (u8)prop_val;
+	if (!(wcd9xxx_read_of_property_u32(dev, "qcom,cdc-micbias2-cfilt-sel",
+				&prop_val)))
+		micbias->bias2_cfilt_sel = (u8)prop_val;
 
-	snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
-			"qcom,cdc-micbias3-cfilt-sel");
-	ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
-	if (ret) {
-		dev_err(dev, "Looking up %s property in node %s failed",
-			prop_name, dev->of_node->full_name);
-		return -ENODEV;
-	}
-	micbias->bias3_cfilt_sel = (u8)prop_val;
+	if (!(wcd9xxx_read_of_property_u32(dev, "qcom,cdc-micbias3-cfilt-sel",
+				&prop_val)))
+		micbias->bias3_cfilt_sel = (u8)prop_val;
 
-	snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
-			"qcom,cdc-micbias4-cfilt-sel");
-	ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
-	if (ret) {
-		dev_err(dev, "Looking up %s property in node %s failed",
-			prop_name, dev->of_node->full_name);
-		return -ENODEV;
-	}
-	micbias->bias4_cfilt_sel = (u8)prop_val;
+	if (!(wcd9xxx_read_of_property_u32(dev, "qcom,cdc-micbias4-cfilt-sel",
+				&prop_val)))
+		micbias->bias4_cfilt_sel = (u8)prop_val;
 
 	/* micbias external cap */
 	micbias->bias1_cap_mode =
@@ -1153,6 +1159,9 @@
 		(!strcmp(dev_name(dev), WCD9XXX_I2C_GSBI_SLAVE_ID))) {
 		codec_supplies = taiko_supplies;
 		num_of_supplies = ARRAY_SIZE(taiko_supplies);
+	} else if (!strcmp(dev_name(dev), "tapan-slim-pgd")) {
+		codec_supplies = tapan_supplies;
+		num_of_supplies = ARRAY_SIZE(tapan_supplies);
 	} else {
 		dev_err(dev, "%s unsupported device %s\n",
 				__func__, dev_name(dev));
@@ -1276,6 +1285,7 @@
 	wcd9xxx->reset_gpio = pdata->reset_gpio;
 	wcd9xxx->dev = &slim->dev;
 	wcd9xxx->mclk_rate = pdata->mclk_rate;
+	wcd9xxx->slim_device_bootup = true;
 
 	ret = wcd9xxx_enable_supplies(wcd9xxx, pdata);
 	if (ret)
@@ -1395,6 +1405,29 @@
 	return ret;
 }
 
+static int wcd9xxx_device_up(struct wcd9xxx *wcd9xxx)
+{
+	int ret = 0;
+
+	if (wcd9xxx->slim_device_bootup) {
+		wcd9xxx->slim_device_bootup = false;
+		return 0;
+	}
+	ret = wcd9xxx_reset(wcd9xxx);
+	if (ret)
+		pr_err("%s: Resetting Codec failed\n", __func__);
+
+	wcd9xxx_bring_up(wcd9xxx);
+	wcd9xxx->post_reset(wcd9xxx);
+	return ret;
+}
+
+static int wcd9xxx_slim_device_up(struct slim_device *sldev)
+{
+	struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev);
+	return wcd9xxx_device_up(wcd9xxx);
+}
+
 static int wcd9xxx_slim_resume(struct slim_device *sldev)
 {
 	struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev);
@@ -1550,6 +1583,24 @@
 	.id_table = taiko_slimtest_id,
 	.resume = wcd9xxx_slim_resume,
 	.suspend = wcd9xxx_slim_suspend,
+	.device_up = wcd9xxx_slim_device_up,
+};
+
+static const struct slim_device_id tapan_slimtest_id[] = {
+	{"tapan-slim-pgd", 0},
+	{}
+};
+
+static struct slim_driver tapan_slim_driver = {
+	.driver = {
+		.name = "tapan-slim",
+		.owner = THIS_MODULE,
+	},
+	.probe = wcd9xxx_slim_probe,
+	.remove = wcd9xxx_slim_remove,
+	.id_table = tapan_slimtest_id,
+	.resume = wcd9xxx_slim_resume,
+	.suspend = wcd9xxx_slim_suspend,
 };
 
 static struct i2c_device_id wcd9xxx_id_table[] = {
@@ -1596,39 +1647,48 @@
 
 static int __init wcd9xxx_init(void)
 {
-	int ret1, ret2, ret3, ret4, ret5, ret6, ret7;
+	int ret[NUM_WCD9XXX_REG_RET];
+	int i = 0;
 
 	wcd9xxx_intf = WCD9XXX_INTERFACE_TYPE_PROBING;
 
-	ret1 = slim_driver_register(&tabla_slim_driver);
-	if (ret1 != 0)
-		pr_err("Failed to register tabla SB driver: %d\n", ret1);
+	ret[0] = slim_driver_register(&tabla_slim_driver);
+	if (ret[0])
+		pr_err("Failed to register tabla SB driver: %d\n", ret[0]);
 
-	ret2 = slim_driver_register(&tabla2x_slim_driver);
-	if (ret2 != 0)
-		pr_err("Failed to register tabla2x SB driver: %d\n", ret2);
+	ret[1] = slim_driver_register(&tabla2x_slim_driver);
+	if (ret[1])
+		pr_err("Failed to register tabla2x SB driver: %d\n", ret[1]);
 
-	ret3 = i2c_add_driver(&tabla_i2c_driver);
-	if (ret3 != 0)
-		pr_err("failed to add the tabla2x I2C driver\n");
+	ret[2] = i2c_add_driver(&tabla_i2c_driver);
+	if (ret[2])
+		pr_err("failed to add the tabla2x I2C driver: %d\n", ret[2]);
 
-	ret4 = slim_driver_register(&sitar_slim_driver);
-	if (ret4 != 0)
-		pr_err("Failed to register sitar SB driver: %d\n", ret4);
+	ret[3] = slim_driver_register(&sitar_slim_driver);
+	if (ret[3])
+		pr_err("Failed to register sitar SB driver: %d\n", ret[3]);
 
-	ret5 = slim_driver_register(&sitar1p1_slim_driver);
-	if (ret5 != 0)
-		pr_err("Failed to register sitar SB driver: %d\n", ret5);
+	ret[4] = slim_driver_register(&sitar1p1_slim_driver);
+	if (ret[4])
+		pr_err("Failed to register sitar SB driver: %d\n", ret[4]);
 
-	ret6 = slim_driver_register(&taiko_slim_driver);
-	if (ret6 != 0)
-		pr_err("Failed to register taiko SB driver: %d\n", ret6);
+	ret[5] = slim_driver_register(&taiko_slim_driver);
+	if (ret[5])
+		pr_err("Failed to register taiko SB driver: %d\n", ret[5]);
 
-	ret7 = i2c_add_driver(&wcd9xxx_i2c_driver);
-	if (ret7 != 0)
-		pr_err("failed to add the wcd9xxx I2C driver\n");
+	ret[6] = i2c_add_driver(&wcd9xxx_i2c_driver);
+	if (ret[6])
+		pr_err("failed to add the wcd9xxx I2C driver: %d\n", ret[6]);
 
-	return (ret1 && ret2 && ret3 && ret4 && ret5 && ret6 && ret7) ? -1 : 0;
+	ret[7] = slim_driver_register(&tapan_slim_driver);
+	if (ret[7])
+		pr_err("Failed to register tapan SB driver: %d\n", ret[7]);
+
+	for (i = 0; i < NUM_WCD9XXX_REG_RET; i++) {
+		if (ret[i])
+			return ret[i];
+	}
+	return 0;
 }
 module_init(wcd9xxx_init);
 
diff --git a/drivers/mfd/wcd9xxx-irq.c b/drivers/mfd/wcd9xxx-irq.c
index 23e0fcc..f2c3959 100644
--- a/drivers/mfd/wcd9xxx-irq.c
+++ b/drivers/mfd/wcd9xxx-irq.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
@@ -182,23 +182,37 @@
 }
 EXPORT_SYMBOL_GPL(wcd9xxx_unlock_sleep);
 
+void wcd9xxx_nested_irq_lock(struct wcd9xxx *wcd9xxx)
+{
+	mutex_lock(&wcd9xxx->nested_irq_lock);
+}
+
+void wcd9xxx_nested_irq_unlock(struct wcd9xxx *wcd9xxx)
+{
+	mutex_unlock(&wcd9xxx->nested_irq_lock);
+}
+
 static void wcd9xxx_irq_dispatch(struct wcd9xxx *wcd9xxx, int irqbit)
 {
 	if ((irqbit <= WCD9XXX_IRQ_MBHC_INSERTION) &&
 	    (irqbit >= WCD9XXX_IRQ_MBHC_REMOVAL)) {
+		wcd9xxx_nested_irq_lock(wcd9xxx);
 		wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_INTR_CLEAR0 +
 					   BIT_BYTE(irqbit),
 				  BYTE_BIT_MASK(irqbit));
 		if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C)
 			wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_INTR_MODE, 0x02);
 		handle_nested_irq(phyirq_to_virq(wcd9xxx, irqbit));
+		wcd9xxx_nested_irq_unlock(wcd9xxx);
 	} else {
+		wcd9xxx_nested_irq_lock(wcd9xxx);
 		handle_nested_irq(phyirq_to_virq(wcd9xxx, irqbit));
 		wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_INTR_CLEAR0 +
 					   BIT_BYTE(irqbit),
 				  BYTE_BIT_MASK(irqbit));
 		if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C)
 			wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_INTR_MODE, 0x02);
+		wcd9xxx_nested_irq_unlock(wcd9xxx);
 	}
 }
 
@@ -325,11 +339,13 @@
 	u8 irq_level[wcd9xxx_num_irq_regs(wcd9xxx)];
 
 	mutex_init(&wcd9xxx->irq_lock);
+	mutex_init(&wcd9xxx->nested_irq_lock);
 
 	wcd9xxx->irq = wcd9xxx_irq_get_upstream_irq(wcd9xxx);
 	if (!wcd9xxx->irq) {
 		pr_warn("%s: irq driver is not yet initialized\n", __func__);
 		mutex_destroy(&wcd9xxx->irq_lock);
+		mutex_destroy(&wcd9xxx->nested_irq_lock);
 		return -EPROBE_DEFER;
 	}
 	pr_debug("%s: probed irq %d\n", __func__, wcd9xxx->irq);
@@ -339,6 +355,8 @@
 	if (ret) {
 		pr_err("%s: Failed to setup downstream IRQ\n", __func__);
 		wcd9xxx_irq_put_upstream_irq(wcd9xxx);
+		mutex_destroy(&wcd9xxx->irq_lock);
+		mutex_destroy(&wcd9xxx->nested_irq_lock);
 		return ret;
 	}
 
@@ -388,6 +406,7 @@
 		pr_err("%s: Failed to init wcd9xxx irq\n", __func__);
 		wcd9xxx_irq_put_upstream_irq(wcd9xxx);
 		mutex_destroy(&wcd9xxx->irq_lock);
+		mutex_destroy(&wcd9xxx->nested_irq_lock);
 	}
 
 	return ret;
@@ -424,6 +443,7 @@
 		device_init_wakeup(wcd9xxx->dev, 0);
 	}
 	mutex_destroy(&wcd9xxx->irq_lock);
+	mutex_destroy(&wcd9xxx->nested_irq_lock);
 }
 
 #ifndef CONFIG_OF
diff --git a/drivers/mfd/wcd9xxx-slimslave.c b/drivers/mfd/wcd9xxx-slimslave.c
index 948cb6e..f2d71b6 100644
--- a/drivers/mfd/wcd9xxx-slimslave.c
+++ b/drivers/mfd/wcd9xxx-slimslave.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -14,8 +14,6 @@
 #include <linux/mfd/wcd9xxx/wcd9xxx-slimslave.h>
 #include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
 
-#define WCD9XXX_CHIP_ID_TAIKO 0x00000201
-
 struct wcd9xxx_slim_sch {
 	u16 rx_port_ch_reg_base;
 	u16 port_tx_cfg_reg_base;
@@ -33,22 +31,15 @@
 
 static int wcd9xxx_configure_ports(struct wcd9xxx *wcd9xxx)
 {
-	int i;
-	u32 id;
-	for (i = 0; i < 4; i++)
-		((u8 *)&id)[i] = wcd9xxx_reg_read(wcd9xxx,
-						  WCD9XXX_A_CHIP_ID_BYTE_0 + i);
-	id = cpu_to_be32(id);
-	pr_debug("%s: chip id 0x%08x\n", __func__, id);
-	if (id != WCD9XXX_CHIP_ID_TAIKO) {
-		sh_ch.rx_port_ch_reg_base = 0x180 ;
+	if (wcd9xxx->slim_slave_type == WCD9XXX_SLIM_SLAVE_ADDR_TYPE_TABLA) {
+		sh_ch.rx_port_ch_reg_base = 0x180;
 		sh_ch.port_rx_cfg_reg_base = 0x040;
 		sh_ch.port_tx_cfg_reg_base = 0x040;
 	} else {
 		sh_ch.rx_port_ch_reg_base =
 			0x180 - (TAIKO_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS * 4);
 		sh_ch.port_rx_cfg_reg_base =
-			0x040 - TAIKO_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS ;
+			0x040 - TAIKO_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS;
 		sh_ch.port_tx_cfg_reg_base = 0x050;
 	}
 
@@ -223,7 +214,7 @@
 	prop.dataf = SLIM_CH_DATAF_NOT_DEFINED;
 	prop.auxf = SLIM_CH_AUXF_NOT_APPLICABLE;
 	prop.ratem = (rate/4000);
-	prop.sampleszbits = 16;
+	prop.sampleszbits = bit_width;
 
 	pr_debug("Before slim_define_ch:\n"
 		 "ch_cnt %d,ch_h[0] %d ch_h[1] %d, grph %d\n",
diff --git a/drivers/misc/isa1200.c b/drivers/misc/isa1200.c
index 604ffd7..c6d08d1 100644
--- a/drivers/misc/isa1200.c
+++ b/drivers/misc/isa1200.c
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 2009 Samsung Electronics
  *  Kyungmin Park <kyungmin.park@samsung.com>
- *  Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *  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 as
@@ -23,6 +23,7 @@
 #include <linux/clk.h>
 #include <linux/i2c/isa1200.h>
 #include "../staging/android/timed_output.h"
+#include <linux/of_gpio.h>
 
 #define ISA1200_HCTRL0		0x30
 #define ISA1200_HCTRL1		0x31
@@ -121,7 +122,7 @@
 
 			/* vote for clock */
 			if (haptic->pdata->need_pwm_clk && !haptic->clk_on) {
-				rc = clk_enable(haptic->pwm_clk);
+				rc = clk_prepare_enable(haptic->pwm_clk);
 				if (rc < 0) {
 					pr_err("%s: clk enable failed\n",
 								__func__);
@@ -163,7 +164,7 @@
 
 			/* de-vote clock */
 			if (haptic->pdata->need_pwm_clk && haptic->clk_on) {
-				clk_disable(haptic->pwm_clk);
+				clk_disable_unprepare(haptic->pwm_clk);
 				haptic->clk_on = false;
 			}
 			/* check for board specific clk callback */
@@ -180,7 +181,7 @@
 
 dis_clk:
 	if (haptic->pdata->need_pwm_clk && haptic->clk_on) {
-		clk_disable(haptic->pwm_clk);
+		clk_disable_unprepare(haptic->pwm_clk);
 		haptic->clk_on = false;
 	}
 
@@ -406,10 +407,10 @@
 
 	for (i = 0; i < num_reg; i++) {
 		haptic->regs[i] = regulator_get(&haptic->client->dev,
-							reg_info[i].name);
+						reg_info[i].name);
 		if (IS_ERR(haptic->regs[i])) {
 			rc = PTR_ERR(haptic->regs[i]);
-			pr_err("%s:regulator get failed(%d)\n",	__func__, rc);
+			pr_err("%s:regulator get failed(%d)\n", __func__, rc);
 			goto put_regs;
 		}
 
@@ -438,6 +439,138 @@
 	return rc;
 }
 
+#ifdef CONFIG_OF
+static int isa1200_parse_dt(struct device *dev,
+			struct isa1200_platform_data *pdata)
+{
+	struct device_node *temp, *np = dev->of_node;
+	struct isa1200_regulator *reg_info;
+	enum of_gpio_flags hap_en_flags = OF_GPIO_ACTIVE_LOW;
+	enum of_gpio_flags hap_len_flags = OF_GPIO_ACTIVE_LOW;
+	int rc = 0;
+	u32 temp_val;
+	const char *temp_string;
+
+	rc = of_property_read_string(np, "label", &pdata->name);
+	if (rc) {
+		dev_err(dev, "Unable to read device name\n");
+		return rc;
+	}
+
+	pdata->chip_en = of_property_read_bool(np, "imagis,chip-en");
+	pdata->ext_clk_en = of_property_read_bool(np, "imagis,ext-clk-en");
+	pdata->is_erm = of_property_read_bool(np, "imagis,is-erm");
+	pdata->overdrive_high =
+		of_property_read_bool(np, "imagis,overdrive-high");
+	pdata->overdrive_en = of_property_read_bool(np, "imagis,overdrive-en");
+	pdata->smart_en = of_property_read_bool(np, "imagis,smart-en");
+	pdata->need_pwm_clk = of_property_read_bool(np, "imagis,need-pwm-clk");
+
+	pdata->hap_en_gpio = of_get_named_gpio_flags(np,
+				"imagis,hap-en-gpio", 0, &hap_en_flags);
+	pdata->hap_len_gpio = of_get_named_gpio_flags(np,
+				"imagis,hap-len-gpio", 0, &hap_len_flags);
+
+	rc = of_property_read_u32(np, "imagis,max-timeout",
+				&pdata->max_timeout);
+	if (rc) {
+		dev_err(dev, "Unable to read max timeout\n");
+		return rc;
+	}
+
+	rc = of_property_read_u32(np, "imagis,pwm-div", &pdata->pwm_fd.pwm_div);
+	if (rc && (rc != -EINVAL)) {
+		dev_err(dev, "Unable to read pwm division\n");
+		return rc;
+	}
+
+	rc = of_property_read_u32(np, "imagis,pwm-freq",
+			&pdata->pwm_fd.pwm_freq);
+	if (rc && (rc != -EINVAL)) {
+		dev_err(dev, "Unable to read pwm frequency\n");
+		return rc;
+	}
+
+	rc = of_property_read_u32(np, "imagis,pwm-ch-id", &pdata->pwm_ch_id);
+	if (rc && (rc != -EINVAL)) {
+		dev_err(dev, "Unable to read pwm channel id\n");
+		return rc;
+	}
+
+	rc = of_property_read_u32(np, "imagis,mode-ctrl", &pdata->mode_ctrl);
+	if (rc) {
+		dev_err(dev, "Unable to read control mode\n");
+		return rc;
+	}
+
+	rc = of_property_read_u32(np, "imagis,duty", &pdata->duty);
+	if (rc && (rc != -EINVAL)) {
+		dev_err(dev, "Unable to read duty cycle\n");
+		return rc;
+	}
+
+	pdata->num_regulators = 0;
+	temp = NULL;
+	while ((temp = of_get_next_child(np, temp)))
+		pdata->num_regulators++;
+
+	if (!pdata->num_regulators)
+		return 0;
+
+	reg_info = devm_kzalloc(dev, pdata->num_regulators *
+				sizeof(struct isa1200_regulator), GFP_KERNEL);
+	if (!reg_info)
+		return -ENOMEM;
+
+	pdata->regulator_info = reg_info;
+
+	for_each_child_of_node(np, temp) {
+		rc = of_property_read_string(temp,
+			"regulator-name", &temp_string);
+		if (rc) {
+			dev_err(dev, "Unable to read regulator name\n");
+			return rc;
+		} else
+			reg_info->name = temp_string;
+
+		rc = of_property_read_u32(temp, "regulator-max-microvolt",
+			&temp_val);
+		if (rc) {
+			dev_err(dev, "Unable to read max uV\n");
+			return rc;
+		} else
+			reg_info->max_uV = temp_val;
+
+		rc = of_property_read_u32(temp, "regulator-min-microvolt",
+			&temp_val);
+		if (rc) {
+			dev_err(dev, "Unable to read min uV\n");
+			return rc;
+		} else
+			reg_info->min_uV = temp_val;
+
+		rc = of_property_read_u32(temp, "regulator-max-microamp",
+			&temp_val);
+		if (rc) {
+			dev_err(dev, "Unable to read load uA\n");
+			return rc;
+		} else
+			reg_info->load_uA = temp_val;
+
+		reg_info++;
+	}
+
+	return 0;
+}
+#else
+static int isa1200_parse_dt(struct device *dev,
+		struct isa1200_platform_data *pdata)
+{
+	return -ENODEV;
+}
+#endif
+
+
 static int __devinit isa1200_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
@@ -452,7 +585,22 @@
 		return -EIO;
 	}
 
-	pdata = client->dev.platform_data;
+	if (client->dev.of_node) {
+		pdata = devm_kzalloc(&client->dev,
+			sizeof(struct isa1200_platform_data), GFP_KERNEL);
+		if (!pdata) {
+			dev_err(&client->dev, "Failed to allocate memory\n");
+			return -ENOMEM;
+		}
+
+		ret = isa1200_parse_dt(&client->dev, pdata);
+		if (ret) {
+			dev_err(&client->dev, "Parsing DT failed(%d)", ret);
+			return ret;
+		}
+	} else
+		pdata = client->dev.platform_data;
+
 	if (!pdata) {
 		dev_err(&client->dev, "%s: no platform data\n", __func__);
 		return -EINVAL;
@@ -714,10 +862,19 @@
 	{ },
 };
 MODULE_DEVICE_TABLE(i2c, isa1200_id);
+#ifdef CONFIG_OF
+static struct of_device_id isa1200_match_table[] = {
+	{ .compatible = "imagis,isa1200",},
+	{ },
+};
+#else
+#define isa1200_match_table NULL
+#endif
 
 static struct i2c_driver isa1200_driver = {
 	.driver	= {
 		.name	= "isa1200",
+		.of_match_table = isa1200_match_table,
 	},
 	.probe		= isa1200_probe,
 	.remove		= __devexit_p(isa1200_remove),
diff --git a/drivers/misc/msm_migrate_pages.c b/drivers/misc/msm_migrate_pages.c
index 6dcdd02..c4aa1f8 100644
--- a/drivers/misc/msm_migrate_pages.c
+++ b/drivers/misc/msm_migrate_pages.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/drivers/misc/pm8xxx-nfc.c b/drivers/misc/pm8xxx-nfc.c
index 1aaa3e3..eeb3e2c 100644
--- a/drivers/misc/pm8xxx-nfc.c
+++ b/drivers/misc/pm8xxx-nfc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010,2011 Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/misc/pm8xxx-upl.c b/drivers/misc/pm8xxx-upl.c
index d3d9746f..5a1b36f 100644
--- a/drivers/misc/pm8xxx-upl.c
+++ b/drivers/misc/pm8xxx-upl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010,2011 Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/misc/pm8xxx-vibrator.c b/drivers/misc/pm8xxx-vibrator.c
index 62e7b45..bfe5b3c 100644
--- a/drivers/misc/pm8xxx-vibrator.c
+++ b/drivers/misc/pm8xxx-vibrator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/misc/pmem.c b/drivers/misc/pmem.c
index 0ab5b69..e91db7a 100644
--- a/drivers/misc/pmem.c
+++ b/drivers/misc/pmem.c
@@ -1,7 +1,7 @@
 /* drivers/android/pmem.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/misc/pmic8058-pwm.c b/drivers/misc/pmic8058-pwm.c
index 33407b7..996a81e 100644
--- a/drivers/misc/pmic8058-pwm.c
+++ b/drivers/misc/pmic8058-pwm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/misc/pmic8058-xoadc.c b/drivers/misc/pmic8058-xoadc.c
index 3452672..bdcaa4d 100644
--- a/drivers/misc/pmic8058-xoadc.c
+++ b/drivers/misc/pmic8058-xoadc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/misc/qfp_fuse.c b/drivers/misc/qfp_fuse.c
index 341e5b2..3a088dc 100644
--- a/drivers/misc/qfp_fuse.c
+++ b/drivers/misc/qfp_fuse.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index c415952..9e22ffb 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -2,7 +2,7 @@
 
 /*Qualcomm Secure Execution Environment Communicator (QSEECOM) driver
  *
- * Copyright (c) 2012, Code Aurora Forum. 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
@@ -42,6 +42,7 @@
 #include <mach/scm.h>
 #include <mach/subsystem_restart.h>
 #include <mach/socinfo.h>
+#include <mach/qseecomi.h>
 #include "qseecom_legacy.h"
 #include "qseecom_kernel.h"
 
@@ -58,116 +59,13 @@
 #define QSEE_CE_CLK_100MHZ		100000000
 #define QSEE_CE_CLK_50MHZ		50000000
 
-#define QSEECOM_MAX_SG_ENTRY	10
-
-enum qseecom_command_scm_resp_type {
-	QSEOS_APP_ID = 0xEE01,
-	QSEOS_LISTENER_ID
-};
-
-enum qseecom_qceos_cmd_id {
-	QSEOS_APP_START_COMMAND      = 0x01,
-	QSEOS_APP_SHUTDOWN_COMMAND,
-	QSEOS_APP_LOOKUP_COMMAND,
-	QSEOS_REGISTER_LISTENER,
-	QSEOS_DEREGISTER_LISTENER,
-	QSEOS_CLIENT_SEND_DATA_COMMAND,
-	QSEOS_LISTENER_DATA_RSP_COMMAND,
-	QSEOS_LOAD_EXTERNAL_ELF_COMMAND,
-	QSEOS_UNLOAD_EXTERNAL_ELF_COMMAND,
-	QSEOS_GET_APP_STATE_COMMAND,
-	QSEOS_LOAD_SERV_IMAGE_COMMAND,
-	QSEOS_UNLOAD_SERV_IMAGE_COMMAND,
-	QSEOS_APP_REGION_NOTIFICATION,
-	QSEOS_CMD_MAX     = 0xEFFFFFFF
-};
-
-enum qseecom_qceos_cmd_status {
-	QSEOS_RESULT_SUCCESS = 0,
-	QSEOS_RESULT_INCOMPLETE,
-	QSEOS_RESULT_FAILURE  = 0xFFFFFFFF
-};
+#define QSEECOM_MAX_SG_ENTRY	512
 
 enum qseecom_clk_definitions {
 	CLK_DFAB = 0,
 	CLK_SFPB,
 };
 
-__packed  struct qsee_apps_region_info_ireq {
-	uint32_t qsee_cmd_id;
-	uint32_t addr;
-	uint32_t size;
-};
-
-__packed struct qseecom_check_app_ireq {
-	uint32_t qsee_cmd_id;
-	char     app_name[MAX_APP_NAME_SIZE];
-};
-
-__packed struct qseecom_load_app_ireq {
-	uint32_t qsee_cmd_id;
-	uint32_t mdt_len;		/* Length of the mdt file */
-	uint32_t img_len;		/* Length of .bxx and .mdt files */
-	uint32_t phy_addr;		/* phy addr of the start of image */
-	char     app_name[MAX_APP_NAME_SIZE];	/* application name*/
-};
-
-__packed struct qseecom_unload_app_ireq {
-	uint32_t qsee_cmd_id;
-	uint32_t  app_id;
-};
-
-__packed struct qseecom_load_lib_image_ireq {
-	uint32_t qsee_cmd_id;
-	uint32_t mdt_len;
-	uint32_t img_len;
-	uint32_t phy_addr;
-};
-
-__packed struct qseecom_unload_lib_image_ireq {
-	uint32_t qsee_cmd_id;
-};
-
-__packed struct qseecom_register_listener_ireq {
-	uint32_t qsee_cmd_id;
-	uint32_t listener_id;
-	void *sb_ptr;
-	uint32_t sb_len;
-};
-
-__packed struct qseecom_unregister_listener_ireq {
-	uint32_t qsee_cmd_id;
-	uint32_t  listener_id;
-};
-
-__packed struct qseecom_client_send_data_ireq {
-	uint32_t qsee_cmd_id;
-	uint32_t app_id;
-	void *req_ptr;
-	uint32_t req_len;
-	void *rsp_ptr;   /* First 4 bytes should always be the return status */
-	uint32_t rsp_len;
-};
-
-/* send_data resp */
-__packed struct qseecom_client_listener_data_irsp {
-	uint32_t qsee_cmd_id;
-	uint32_t listener_id;
-};
-
-/*
- * struct qseecom_command_scm_resp - qseecom response buffer
- * @cmd_status: value from enum tz_sched_cmd_status
- * @sb_in_rsp_addr: points to physical location of response
- *                buffer
- * @sb_in_rsp_len: length of command response
- */
-__packed struct qseecom_command_scm_resp {
-	uint32_t result;
-	enum qseecom_command_scm_resp_type resp_type;
-	unsigned int data;
-};
-
 static struct class *driver_class;
 static dev_t qseecom_device_no;
 static struct cdev qseecom_cdev;
@@ -586,6 +484,7 @@
 					struct qseecom_command_scm_resp *resp)
 {
 	int ret = 0;
+	int rc = 0;
 	uint32_t lstnr;
 	unsigned long flags;
 	struct qseecom_client_listener_data_irsp send_data_rsp;
@@ -624,8 +523,12 @@
 		if (data->abort) {
 			pr_err("Aborting listener service %d\n",
 				data->listener.id);
-			return -ENODEV;
+			rc = -ENODEV;
+			send_data_rsp.status  = QSEOS_RESULT_FAILURE;
+		} else {
+			send_data_rsp.status  = QSEOS_RESULT_SUCCESS;
 		}
+
 		qseecom.send_resp_flag = 0;
 		send_data_rsp.qsee_cmd_id = QSEOS_LISTENER_DATA_RSP_COMMAND;
 		send_data_rsp.listener_id  = lstnr ;
@@ -644,6 +547,9 @@
 			return -EINVAL;
 		}
 	}
+	if (rc)
+		return rc;
+
 	return ret;
 }
 
@@ -757,6 +663,9 @@
 			&resp, sizeof(resp));
 		if (ret) {
 			pr_err("scm_call to load app failed\n");
+			if (!IS_ERR_OR_NULL(ihandle))
+				ion_free(qseecom.ion_clnt, ihandle);
+			qsee_disable_clock_vote(data, CLK_SFPB);
 			return -EINVAL;
 		}
 
@@ -1455,7 +1364,7 @@
 	return ret;
 }
 
-static int qseecom_load_commonlib_image(void)
+static int qseecom_load_commonlib_image(struct qseecom_dev_handle *data)
 {
 	int32_t ret = 0;
 	uint32_t fw_size = 0;
@@ -1463,7 +1372,7 @@
 	struct qseecom_command_scm_resp resp;
 	u8 *img_data = NULL;
 
-	if (__qseecom_get_fw_size("commonlib", &fw_size))
+	if (__qseecom_get_fw_size("cmnlib", &fw_size))
 		return -EIO;
 
 	img_data = kzalloc(fw_size, GFP_KERNEL);
@@ -1471,7 +1380,7 @@
 		pr_err("Mem allocation for lib image data failed\n");
 		return -ENOMEM;
 	}
-	ret = __qseecom_get_fw_data("commonlib", img_data, &load_req);
+	ret = __qseecom_get_fw_data("cmnlib", img_data, &load_req);
 	if (ret) {
 		kzfree(img_data);
 		return -EIO;
@@ -1482,7 +1391,6 @@
 	ret = scm_call(SCM_SVC_TZSCHEDULER, 1, &load_req,
 				sizeof(struct qseecom_load_lib_image_ireq),
 							&resp, sizeof(resp));
-	kzfree(img_data);
 	if (ret) {
 		pr_err("scm_call to load failed : ret %d\n", ret);
 		ret = -EIO;
@@ -1495,6 +1403,12 @@
 						resp.result);
 			ret = -EINVAL;
 			break;
+		case  QSEOS_RESULT_INCOMPLETE:
+			ret = __qseecom_process_incomplete_cmd(data, &resp);
+			if (ret)
+				pr_err("process_incomplete_cmd failed err: %d\n",
+					ret);
+			break;
 		default:
 			pr_err("scm call return unknown response %d\n",
 						resp.result);
@@ -1502,6 +1416,7 @@
 			break;
 		}
 	}
+	kzfree(img_data);
 	return ret;
 }
 
@@ -1555,25 +1470,6 @@
 		return -EINVAL;
 	}
 
-	if (qseecom.qsee_version > QSEEE_VERSION_00) {
-		mutex_lock(&app_access_lock);
-		if (qseecom.commonlib_loaded == false) {
-			ret = qseecom_load_commonlib_image();
-			if (ret == 0)
-				qseecom.commonlib_loaded = true;
-		}
-		mutex_unlock(&app_access_lock);
-	}
-
-	if (ret)
-		return -EIO;
-
-	app_ireq.qsee_cmd_id = QSEOS_APP_LOOKUP_COMMAND;
-	memcpy(app_ireq.app_name, app_name, MAX_APP_NAME_SIZE);
-	ret = __qseecom_check_app_exists(app_ireq);
-	if (ret < 0)
-		return -EINVAL;
-
 	*handle = kzalloc(sizeof(struct qseecom_handle), GFP_KERNEL);
 	if (!(*handle)) {
 		pr_err("failed to allocate memory for kernel client handle\n");
@@ -1610,6 +1506,34 @@
 		return -EINVAL;
 	}
 
+	if (qseecom.qsee_version > QSEEE_VERSION_00) {
+		mutex_lock(&app_access_lock);
+		if (qseecom.commonlib_loaded == false) {
+			ret = qseecom_load_commonlib_image(data);
+			if (ret == 0)
+				qseecom.commonlib_loaded = true;
+		}
+		mutex_unlock(&app_access_lock);
+	}
+
+	if (ret) {
+		pr_err("Failed to loadd commonlib image\n");
+		kfree(data);
+		kfree(*handle);
+		*handle = NULL;
+		return -EIO;
+	}
+
+	app_ireq.qsee_cmd_id = QSEOS_APP_LOOKUP_COMMAND;
+	memcpy(app_ireq.app_name, app_name, MAX_APP_NAME_SIZE);
+	ret = __qseecom_check_app_exists(app_ireq);
+	if (ret < 0) {
+		kzfree(data);
+		kfree(*handle);
+		*handle = NULL;
+		return -EINVAL;
+	}
+
 	if (ret > 0) {
 		pr_warn("App id %d for [%s] app exists\n", ret,
 			(char *)app_ireq.app_name);
@@ -1637,6 +1561,7 @@
 
 		if (ret < 0) {
 			kfree(*handle);
+			kfree(data);
 			*handle = NULL;
 			return ret;
 		}
@@ -1646,6 +1571,9 @@
 		entry = kmalloc(sizeof(*entry), GFP_KERNEL);
 		if (!entry) {
 			pr_err("kmalloc failed\n");
+			kfree(data);
+			kfree(*handle);
+			*handle = NULL;
 			return -ENOMEM;
 		}
 		entry->app_id = ret;
@@ -1662,6 +1590,7 @@
 	/* Populate the structure for sending scm call to load image */
 	data->client.sb_virt = (char *) ion_map_kernel(qseecom.ion_clnt,
 							data->client.ihandle);
+	data->client.user_virt_sb_base = (uint32_t)data->client.sb_virt;
 	data->client.sb_phys = pa;
 	(*handle)->dev = (void *)data;
 	(*handle)->sbuf = (unsigned char *)data->client.sb_virt;
@@ -1686,8 +1615,8 @@
 int qseecom_shutdown_app(struct qseecom_handle **handle)
 {
 	int ret = -EINVAL;
-	struct qseecom_dev_handle *data =
-			(struct qseecom_dev_handle *) ((*handle)->dev);
+	struct qseecom_dev_handle *data;
+
 	struct qseecom_registered_kclient_list *kclient = NULL;
 	unsigned long flags = 0;
 	bool found_handle = false;
@@ -1696,11 +1625,11 @@
 		pr_err("This functionality is UNSUPPORTED in version 1.3\n");
 		return -EINVAL;
 	}
-	if (*handle == NULL) {
+	if ((handle == NULL)  || (*handle == NULL)) {
 		pr_err("Handle is not initialized\n");
 		return -EINVAL;
 	}
-
+	data =	(struct qseecom_dev_handle *) ((*handle)->dev);
 	spin_lock_irqsave(&qseecom.registered_kclient_list_lock, flags);
 	list_for_each_entry(kclient, &qseecom.registered_kclient_list_head,
 				list) {
@@ -1771,16 +1700,25 @@
 
 int qseecom_set_bandwidth(struct qseecom_handle *handle, bool high)
 {
+	int ret = 0;
 	if ((handle == NULL) || (handle->dev == NULL)) {
 		pr_err("No valid kernel client\n");
 		return -EINVAL;
 	}
-	if (high)
-		return qsee_vote_for_clock(handle->dev, CLK_DFAB);
-	else {
+	if (high) {
+		ret = qsee_vote_for_clock(handle->dev, CLK_DFAB);
+		if (ret)
+			pr_err("Failed to vote for DFAB clock%d\n", ret);
+		ret = qsee_vote_for_clock(handle->dev, CLK_SFPB);
+		if (ret) {
+			pr_err("Failed to vote for SFPB clock%d\n", ret);
+			qsee_disable_clock_vote(handle->dev, CLK_DFAB);
+		}
+	} else {
 		qsee_disable_clock_vote(handle->dev, CLK_DFAB);
-		return 0;
+		qsee_disable_clock_vote(handle->dev, CLK_SFPB);
 	}
+	return ret;
 }
 EXPORT_SYMBOL(qseecom_set_bandwidth);
 
@@ -2241,7 +2179,7 @@
 		atomic_inc(&data->ioctl_count);
 		if (qseecom.qsee_version > QSEEE_VERSION_00) {
 			if (qseecom.commonlib_loaded == false) {
-				ret = qseecom_load_commonlib_image();
+				ret = qseecom_load_commonlib_image(data);
 				if (ret == 0)
 					qseecom.commonlib_loaded = true;
 			}
@@ -2277,12 +2215,16 @@
 		ret = qsee_vote_for_clock(data, CLK_DFAB);
 		if (ret)
 			pr_err("Failed to vote for DFAB clock%d\n", ret);
+		ret = qsee_vote_for_clock(data, CLK_SFPB);
+		if (ret)
+			pr_err("Failed to vote for SFPB clock%d\n", ret);
 		atomic_dec(&data->ioctl_count);
 		break;
 	}
 	case QSEECOM_IOCTL_PERF_DISABLE_REQ:{
 		atomic_inc(&data->ioctl_count);
 		qsee_disable_clock_vote(data, CLK_DFAB);
+		qsee_disable_clock_vote(data, CLK_SFPB);
 		atomic_dec(&data->ioctl_count);
 		break;
 	}
diff --git a/drivers/misc/qseecom_kernel.h b/drivers/misc/qseecom_kernel.h
index 0c93ef2..c6c8fc9 100644
--- a/drivers/misc/qseecom_kernel.h
+++ b/drivers/misc/qseecom_kernel.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
@@ -14,6 +14,12 @@
 #define __QSEECOM_KERNEL_H_
 
 #include <linux/types.h>
+
+#define QSEECOM_ALIGN_SIZE	0x40
+#define QSEECOM_ALIGN_MASK	(QSEECOM_ALIGN_SIZE - 1)
+#define QSEECOM_ALIGN(x)	\
+	((x + QSEECOM_ALIGN_SIZE) & (~QSEECOM_ALIGN_MASK))
+
 /*
  * struct qseecom_handle -
  *      Handle to the qseecom device for kernel clients
diff --git a/drivers/misc/qseecom_legacy.h b/drivers/misc/qseecom_legacy.h
index 66f87e9..35d6e06 100644
--- a/drivers/misc/qseecom_legacy.h
+++ b/drivers/misc/qseecom_legacy.h
@@ -1,6 +1,6 @@
 /* Qualcomm Secure Execution Environment Communicator (QSEECOM) driver
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/misc/smsc_hub.c b/drivers/misc/smsc_hub.c
index 31f18ed..41d9ff8 100644
--- a/drivers/misc/smsc_hub.c
+++ b/drivers/misc/smsc_hub.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -471,7 +471,8 @@
 	}
 	pm_runtime_disable(&pdev->dev);
 
-	regulator_disable(smsc_hub->hub_vbus_reg);
+	if (!IS_ERR(smsc_hub->hub_vbus_reg))
+		regulator_disable(smsc_hub->hub_vbus_reg);
 	msm_hsic_hub_init_gpio(smsc_hub, 0);
 	msm_hsic_hub_init_clock(smsc_hub, 0);
 	msm_hsic_hub_init_vdd(smsc_hub, 0);
@@ -491,9 +492,7 @@
 {
 	int ret = 0;
 
-	if (!IS_ERR(smsc_hub->ref_clk)) {
-		clk_disable_unprepare(smsc_hub->ref_clk);
-	} else {
+	if (smsc_hub->xo_handle) {
 		ret = msm_xo_mode_vote(smsc_hub->xo_handle, MSM_XO_MODE_OFF);
 		if (ret) {
 			pr_err("%s: failed to devote for TCXO\n"
@@ -507,9 +506,7 @@
 {
 	int ret = 0;
 
-	if (!IS_ERR(smsc_hub->ref_clk)) {
-		clk_prepare_enable(smsc_hub->ref_clk);
-	} else {
+	if (smsc_hub->xo_handle) {
 		ret = msm_xo_mode_vote(smsc_hub->xo_handle, MSM_XO_MODE_ON);
 		if (ret) {
 			pr_err("%s: failed to vote for TCXO\n"
diff --git a/drivers/misc/tsif.c b/drivers/misc/tsif.c
index b7b1203..05f6c86 100644
--- a/drivers/misc/tsif.c
+++ b/drivers/misc/tsif.c
@@ -1,7 +1,7 @@
 /*
  * TSIF Driver
  *
- * Copyright (c) 2009-2012, Code Aurora Forum. 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
@@ -1770,6 +1770,22 @@
 }
 EXPORT_SYMBOL(tsif_stop);
 
+int tsif_get_ref_clk_counter(void *cookie, u32 *tcr_counter)
+{
+	struct msm_tsif_device *tsif_device = cookie;
+
+	if (!tsif_device || !tcr_counter)
+		return -EINVAL;
+
+	if (tsif_device->state == tsif_state_running)
+		*tcr_counter = ioread32(tsif_device->base + TSIF_CLK_REF_OFF);
+	else
+		*tcr_counter = 0;
+
+	return 0;
+}
+EXPORT_SYMBOL(tsif_get_ref_clk_counter);
+
 void tsif_reclaim_packets(void *cookie, int read_index)
 {
 	struct msm_tsif_device *tsif_device = cookie;
diff --git a/drivers/misc/tsif_chrdev.c b/drivers/misc/tsif_chrdev.c
index 122c7ed..a53bc9a 100644
--- a/drivers/misc/tsif_chrdev.c
+++ b/drivers/misc/tsif_chrdev.c
@@ -4,7 +4,7 @@
  * Character device that, being read
  * returns stream of TSIF packets.
  *
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights
+ * Copyright (c) 2009-2011, The Linux Foundation. All rights
  * reserved.
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/drivers/misc/tspp.c b/drivers/misc/tspp.c
index eebaab9..9598d45 100644
--- a/drivers/misc/tspp.c
+++ b/drivers/misc/tspp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -25,6 +25,7 @@
 #include <linux/slab.h>          /* kfree, kzalloc */
 #include <linux/ioport.h>        /* XXX_ mem_region */
 #include <linux/dma-mapping.h>   /* dma_XXX */
+#include <linux/dmapool.h>       /* DMA pools */
 #include <linux/delay.h>         /* msleep */
 #include <linux/platform_device.h>
 #include <linux/clk.h>
@@ -40,11 +41,15 @@
 #include <mach/dma.h>
 #include <mach/msm_tspp.h>
 #include <linux/debugfs.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/string.h>
 
 /*
  * General defines
  */
 #define TSPP_TSIF_INSTANCES            2
+#define TSPP_GPIOS_PER_TSIF            4
 #define TSPP_FILTER_TABLES             3
 #define TSPP_MAX_DEVICES               1
 #define TSPP_NUM_CHANNELS              16
@@ -65,6 +70,14 @@
 #define TSPP_MAX_BUFFER_SIZE           (32 * 1024 - 1)
 
 /*
+ * Returns whether to use DMA pool for TSPP output buffers.
+ * For buffers smaller than page size, using DMA pool
+ * provides better memory utilization as dma_alloc_coherent
+ * allocates minimum of page size.
+ */
+#define TSPP_USE_DMA_POOL(buff_size)   ((buff_size) < PAGE_SIZE)
+
+/*
  * Max allowed TSPP buffers/descriptors.
  * If SPS desc FIFO holds X descriptors, we can queue up to X-1 descriptors.
  */
@@ -398,6 +411,7 @@
 	void *notify_data;       /* data to be passed with the notifier */
 	u32 expiration_period_ms; /* notification on partially filled buffers */
 	struct timer_list expiration_timer;
+	struct dma_pool *dma_pool;
 	tspp_memfree *memfree;   /* user defined memory free function */
 	void *user_info; /* user cookie passed to memory alloc/free function */
 };
@@ -637,45 +651,26 @@
 }
 
 /*** GPIO functions ***/
-static void tspp_gpios_free(const struct msm_gpio *table, int size)
-{
-	int i;
-	const struct msm_gpio *g;
-	for (i = size-1; i >= 0; i--) {
-		g = table + i;
-		gpio_free(GPIO_PIN(g->gpio_cfg));
-	}
-}
-
-static int tspp_gpios_request(const struct msm_gpio *table, int size)
-{
-	int rc;
-	int i;
-	const struct msm_gpio *g;
-	for (i = 0; i < size; i++) {
-		g = table + i;
-		rc = gpio_request(GPIO_PIN(g->gpio_cfg), g->label);
-		if (rc) {
-			pr_err("tspp: gpio_request(%d) <%s> failed: %d\n",
-			       GPIO_PIN(g->gpio_cfg), g->label ?: "?", rc);
-			goto err;
-		}
-	}
-	return 0;
-err:
-	tspp_gpios_free(table, i);
-	return rc;
-}
-
-static int tspp_gpios_disable(const struct msm_gpio *table, int size)
+static int tspp_gpios_disable(const struct tspp_tsif_device *tsif_device,
+				const struct msm_gpio *table,
+				int size)
 {
 	int rc = 0;
 	int i;
 	const struct msm_gpio *g;
+
 	for (i = size-1; i >= 0; i--) {
 		int tmp;
 		g = table + i;
-		tmp = gpio_tlmm_config(g->gpio_cfg, GPIO_CFG_DISABLE);
+
+		/* don't use sync GPIO when not working in mode 2 */
+		if ((tsif_device->mode != TSPP_TSIF_MODE_2) &&
+			(strnstr(g->label, "sync", strlen(g->label)) != NULL))
+			continue;
+
+		tmp = gpio_tlmm_config(GPIO_CFG(GPIO_PIN(g->gpio_cfg),
+			0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+			GPIO_CFG_DISABLE);
 		if (tmp) {
 			pr_err("tspp_gpios_disable(0x%08x, GPIO_CFG_DISABLE) <%s> failed: %d\n",
 			       g->gpio_cfg, g->label ?: "?", rc);
@@ -691,13 +686,22 @@
 	return rc;
 }
 
-static int tspp_gpios_enable(const struct msm_gpio *table, int size)
+static int tspp_gpios_enable(const struct tspp_tsif_device *tsif_device,
+				const struct msm_gpio *table,
+				int size)
 {
 	int rc;
 	int i;
 	const struct msm_gpio *g;
+
 	for (i = 0; i < size; i++) {
 		g = table + i;
+
+		/* don't use sync GPIO when not working in mode 2 */
+		if ((tsif_device->mode != TSPP_TSIF_MODE_2) &&
+			(strnstr(g->label, "sync", strlen(g->label)) != NULL))
+			continue;
+
 		rc = gpio_tlmm_config(g->gpio_cfg, GPIO_CFG_ENABLE);
 		if (rc) {
 			pr_err("tspp: gpio_tlmm_config(0x%08x, GPIO_CFG_ENABLE) <%s> failed: %d\n",
@@ -711,44 +715,59 @@
 	}
 	return 0;
 err:
-	tspp_gpios_disable(table, i);
+	tspp_gpios_disable(tsif_device, table, i);
+
 	return rc;
 }
 
-static int tspp_gpios_request_enable(const struct msm_gpio *table, int size)
-{
-	int rc = tspp_gpios_request(table, size);
-	if (rc)
-		return rc;
-	rc = tspp_gpios_enable(table, size);
-	if (rc)
-		tspp_gpios_free(table, size);
-	return rc;
-}
 
-static void tspp_gpios_disable_free(const struct msm_gpio *table, int size)
+static int tspp_config_gpios(struct tspp_device *device,
+				enum tspp_source source,
+				int enable)
 {
-	tspp_gpios_disable(table, size);
-	tspp_gpios_free(table, size);
-}
+	const struct msm_gpio *table;
+	struct msm_tspp_platform_data *pdata = device->pdev->dev.platform_data;
+	int num_gpios = (pdata->num_gpios / TSPP_TSIF_INSTANCES);
+	int i = 0;
 
-static int tspp_start_gpios(struct tspp_device *device)
-{
-	struct msm_tspp_platform_data *pdata =
-		device->pdev->dev.platform_data;
-	return tspp_gpios_request_enable(pdata->gpios, pdata->num_gpios);
-}
+	if (num_gpios != TSPP_GPIOS_PER_TSIF) {
+		pr_err("tspp %s: unexpected number of GPIOs %d, expected %d\n",
+			__func__, num_gpios, TSPP_GPIOS_PER_TSIF);
+		return -EINVAL;
+	}
 
-static void tspp_stop_gpios(struct tspp_device *device)
-{
-	struct msm_tspp_platform_data *pdata =
-		device->pdev->dev.platform_data;
-	tspp_gpios_disable_free(pdata->gpios, pdata->num_gpios);
+	/*
+	 * Note: this code assumes that the GPIO definitions in the
+	 * pdata->gpios table are according to the TSIF instance number,
+	 * i.e., that TSIF0 GPIOs are defined first, then TSIF1 GPIOs etc.
+	 */
+	switch (source) {
+	case TSPP_SOURCE_TSIF0:
+		i = 0;
+		break;
+	case TSPP_SOURCE_TSIF1:
+		i = 1;
+		break;
+	default:
+		pr_err("tspp %s: invalid source\n", __func__);
+		return -EINVAL;
+	}
+
+	table = pdata->gpios + (i * num_gpios);
+	if (enable)
+		return tspp_gpios_enable(&device->tsif[i], table, num_gpios);
+	else
+		return tspp_gpios_disable(&device->tsif[i], table, num_gpios);
 }
 
 /*** Clock functions ***/
 static int tspp_clock_start(struct tspp_device *device)
 {
+	if (device == NULL) {
+		pr_err("tspp: Can't start clocks, invalid device\n");
+		return -EINVAL;
+	}
+
 	if (device->tsif_pclk && clk_prepare_enable(device->tsif_pclk) != 0) {
 		pr_err("tspp: Can't start pclk");
 		return -EBUSY;
@@ -766,11 +785,16 @@
 
 static void tspp_clock_stop(struct tspp_device *device)
 {
+	if (device == NULL) {
+		pr_err("tspp: Can't stop clocks, invalid device\n");
+		return;
+	}
+
 	if (device->tsif_pclk)
-		clk_disable(device->tsif_pclk);
+		clk_disable_unprepare(device->tsif_pclk);
 
 	if (device->tsif_ref_clk)
-		clk_disable(device->tsif_ref_clk);
+		clk_disable_unprepare(device->tsif_ref_clk);
 }
 
 /*** TSIF functions ***/
@@ -898,7 +922,7 @@
 }
 
 static int tspp_alloc_buffer(u32 channel_id, struct tspp_data_descriptor *desc,
-	u32 size, tspp_allocator *alloc, void *user)
+	u32 size, struct dma_pool *dma_pool, tspp_allocator *alloc, void *user)
 {
 	if (size < TSPP_MIN_BUFFER_SIZE ||
 		size > TSPP_MAX_BUFFER_SIZE) {
@@ -911,10 +935,15 @@
 		desc->virt_base = alloc(channel_id, size,
 			&desc->phys_base, user);
 	} else {
-		desc->virt_base = dma_alloc_coherent(NULL, size,
-			&desc->phys_base, GFP_KERNEL);
+		if (!dma_pool)
+			desc->virt_base = dma_alloc_coherent(NULL, size,
+				&desc->phys_base, GFP_KERNEL);
+		else
+			desc->virt_base = dma_pool_alloc(dma_pool, GFP_KERNEL,
+				&desc->phys_base);
+
 		if (desc->virt_base == 0) {
-			pr_err("tspp dma alloc coherent failed %i", size);
+			pr_err("tspp: dma buffer allocation failed %i\n", size);
 			return -ENOMEM;
 		}
 	}
@@ -1005,7 +1034,7 @@
 			TSPP_CONFIG_PS_CONT_ERR_MASK);
 	TSPP_CONFIG_SET_PACKET_LENGTH(val, TSPP_PACKET_LENGTH);
 	writel_relaxed(val, pdev->base + TSPP_CONFIG);
-	writel_relaxed(0x000fffff, pdev->base + TSPP_IRQ_MASK);
+	writel_relaxed(0x0007ffff, pdev->base + TSPP_IRQ_MASK);
 	writel_relaxed(0x000fffff, pdev->base + TSPP_IRQ_CLEAR);
 	writel_relaxed(0, pdev->base + TSPP_RST);
 	wmb();
@@ -1225,10 +1254,15 @@
 					pbuf->desc.phys_base,
 					channel->user_info);
 			} else {
-				dma_free_coherent(NULL,
-					pbuf->desc.size,
-					pbuf->desc.virt_base,
-					pbuf->desc.phys_base);
+				if (!channel->dma_pool)
+					dma_free_coherent(NULL,
+						pbuf->desc.size,
+						pbuf->desc.virt_base,
+						pbuf->desc.phys_base);
+				else
+					dma_pool_free(channel->dma_pool,
+						pbuf->desc.virt_base,
+						pbuf->desc.phys_base);
 			}
 			pbuf->desc.phys_base = 0;
 		}
@@ -1286,26 +1320,38 @@
 
 	switch (source->source) {
 	case TSPP_SOURCE_TSIF0:
+		if (tspp_config_gpios(pdev, channel->src, 1) != 0) {
+			pr_err("tspp: error enabling tsif0 GPIOs\n");
+			return -EBUSY;
+		}
 		/* make sure TSIF0 is running & enabled */
 		if (tspp_start_tsif(&pdev->tsif[0]) != 0) {
 			pr_err("tspp: error starting tsif0");
 			return -EBUSY;
 		}
-		val = readl_relaxed(pdev->base + TSPP_CONTROL);
-		writel_relaxed(val & ~TSPP_CONTROL_TSP_TSIF0_SRC_DIS,
-			pdev->base + TSPP_CONTROL);
-		wmb();
+		if (pdev->tsif[0].ref_count == 1) {
+			val = readl_relaxed(pdev->base + TSPP_CONTROL);
+			writel_relaxed(val & ~TSPP_CONTROL_TSP_TSIF0_SRC_DIS,
+				pdev->base + TSPP_CONTROL);
+			wmb();
+		}
 		break;
 	case TSPP_SOURCE_TSIF1:
+		if (tspp_config_gpios(pdev, channel->src, 1) != 0) {
+			pr_err("tspp: error enabling tsif1 GPIOs\n");
+			return -EBUSY;
+		}
 		/* make sure TSIF1 is running & enabled */
 		if (tspp_start_tsif(&pdev->tsif[1]) != 0) {
 			pr_err("tspp: error starting tsif1");
 			return -EBUSY;
 		}
-		val = readl_relaxed(pdev->base + TSPP_CONTROL);
-		writel_relaxed(val & ~TSPP_CONTROL_TSP_TSIF1_SRC_DIS,
-			pdev->base + TSPP_CONTROL);
-		wmb();
+		if (pdev->tsif[1].ref_count == 1) {
+			val = readl_relaxed(pdev->base + TSPP_CONTROL);
+			writel_relaxed(val & ~TSPP_CONTROL_TSP_TSIF1_SRC_DIS,
+				pdev->base + TSPP_CONTROL);
+			wmb();
+		}
 		break;
 	case TSPP_SOURCE_MEM:
 		break;
@@ -1331,6 +1377,7 @@
 int tspp_close_stream(u32 dev, u32 channel_id)
 {
 	u32 val;
+	u32 prev_ref_count;
 	struct tspp_device *pdev;
 	struct tspp_channel *channel;
 
@@ -1347,17 +1394,30 @@
 
 	switch (channel->src) {
 	case TSPP_SOURCE_TSIF0:
+		prev_ref_count = pdev->tsif[0].ref_count;
 		tspp_stop_tsif(&pdev->tsif[0]);
-		val = readl_relaxed(pdev->base + TSPP_CONTROL);
-		writel_relaxed(val | TSPP_CONTROL_TSP_TSIF0_SRC_DIS,
-			pdev->base + TSPP_CONTROL);
-		wmb();
+		if (tspp_config_gpios(pdev, channel->src, 0) != 0)
+			pr_err("tspp: error disabling tsif0 GPIOs\n");
+
+		if (prev_ref_count == 1) {
+			val = readl_relaxed(pdev->base + TSPP_CONTROL);
+			writel_relaxed(val | TSPP_CONTROL_TSP_TSIF0_SRC_DIS,
+				pdev->base + TSPP_CONTROL);
+			wmb();
+		}
 		break;
 	case TSPP_SOURCE_TSIF1:
+		prev_ref_count = pdev->tsif[1].ref_count;
 		tspp_stop_tsif(&pdev->tsif[1]);
-		val = readl_relaxed(pdev->base + TSPP_CONTROL);
-		writel_relaxed(val | TSPP_CONTROL_TSP_TSIF1_SRC_DIS,
-			pdev->base + TSPP_CONTROL);
+		if (tspp_config_gpios(pdev, channel->src, 0) != 0)
+			pr_err("tspp: error disabling tsif0 GPIOs\n");
+
+		if (prev_ref_count == 1) {
+			val = readl_relaxed(pdev->base + TSPP_CONTROL);
+			writel_relaxed(val | TSPP_CONTROL_TSP_TSIF1_SRC_DIS,
+				pdev->base + TSPP_CONTROL);
+			wmb();
+		}
 		break;
 	case TSPP_SOURCE_MEM:
 		break;
@@ -1407,9 +1467,13 @@
 	event = &channel->event;
 
 	/* start the clocks if needed */
-	tspp_clock_start(pdev);
-	if (tspp_channels_in_use(pdev) == 0)
+	if (tspp_channels_in_use(pdev) == 0) {
+		rc = tspp_clock_start(pdev);
+		if (rc)
+			return rc;
+
 		wake_lock(&pdev->wake_lock);
+	}
 
 	/* mark it as used */
 	channel->used = 1;
@@ -1556,9 +1620,6 @@
 	}
 	channel->filter_count = 0;
 
-	/* stop the stream */
-	tspp_close_stream(dev, channel->id);
-
 	/* disconnect the bam */
 	if (sps_disconnect(channel->pipe) != 0)
 		pr_warn("tspp: Error freeing sps endpoint (%i)", channel->id);
@@ -1568,6 +1629,10 @@
 		config->desc.phys_base);
 
 	tspp_destroy_buffers(channel_id, channel);
+	if (channel->dma_pool) {
+		dma_pool_destroy(channel->dma_pool);
+		channel->dma_pool = NULL;
+	}
 
 	channel->src = TSPP_SOURCE_NONE;
 	channel->mode = TSPP_MODE_DISABLED;
@@ -1580,15 +1645,67 @@
 	channel->locked = NULL;
 	channel->used = 0;
 
-	if (tspp_channels_in_use(pdev) == 0)
+	if (tspp_channels_in_use(pdev) == 0) {
 		wake_unlock(&pdev->wake_lock);
-	tspp_clock_stop(pdev);
+		tspp_clock_stop(pdev);
+	}
+
+	pm_runtime_put(&pdev->pdev->dev);
 
 	return 0;
 }
 EXPORT_SYMBOL(tspp_close_channel);
 
 /**
+ * tspp_get_ref_clk_counter - return the TSIF clock reference (TCR) counter.
+ *
+ * @dev: TSPP device (up to TSPP_MAX_DEVICES)
+ * @source: The TSIF source from which the counter should be read
+ * @tcr_counter: the value of TCR counter
+ *
+ * Return  error status
+ *
+ * TCR increments at a rate equal to 27 MHz/256 = 105.47 kHz.
+ * If source is neither TSIF 0 or TSIF1 0 is returned.
+ */
+int tspp_get_ref_clk_counter(u32 dev, enum tspp_source source, u32 *tcr_counter)
+{
+	struct tspp_device *pdev;
+	struct tspp_tsif_device *tsif_device;
+
+	if (!tcr_counter)
+		return -EINVAL;
+
+	pdev = tspp_find_by_id(dev);
+	if (!pdev) {
+		pr_err("tspp_get_ref_clk_counter: can't find device %i\n", dev);
+		return -ENODEV;
+	}
+
+	switch (source) {
+	case TSPP_SOURCE_TSIF0:
+		tsif_device = &pdev->tsif[0];
+		break;
+
+	case TSPP_SOURCE_TSIF1:
+		tsif_device = &pdev->tsif[1];
+		break;
+
+	default:
+		tsif_device = NULL;
+		break;
+	}
+
+	if (tsif_device && tsif_device->ref_count)
+		*tcr_counter = ioread32(tsif_device->base + TSIF_CLK_REF_OFF);
+	else
+		*tcr_counter = 0;
+
+	return 0;
+}
+EXPORT_SYMBOL(tspp_get_ref_clk_counter);
+
+/**
  * tspp_add_filter - add a TSPP filter to a channel.
  *
  * @dev: TSPP device (up to TSPP_MAX_DEVICES)
@@ -1704,7 +1821,7 @@
 	 */
 	if (channel->buffer_count == 0) {
 		channel->buffer_size =
-			tspp_align_buffer_size_by_mode(channel->buffer_size,
+		tspp_align_buffer_size_by_mode(channel->buffer_size,
 							channel->mode);
 		rc = tspp_allocate_buffers(dev, channel->id,
 					channel->max_buffers,
@@ -2072,6 +2189,7 @@
 	}
 
 	channel = &pdev->channels[channel_id];
+
 	/* allow buffer allocation only if there was no previous buffer
 	 * allocation for this channel.
 	 */
@@ -2101,6 +2219,22 @@
 	channel->memfree = memfree;
 	channel->user_info = user;
 
+	/*
+	 * For small buffers, create a DMA pool so that memory
+	 * is not wasted through dma_alloc_coherent.
+	 */
+	if (TSPP_USE_DMA_POOL(channel->buffer_size)) {
+		channel->dma_pool = dma_pool_create("tspp",
+			NULL, channel->buffer_size, 0, 0);
+		if (!channel->dma_pool) {
+			pr_err("%s: Can't allocate memory pool\n", __func__);
+			return -ENOMEM;
+		}
+	} else {
+		channel->dma_pool = NULL;
+	}
+
+
 	for (channel->buffer_count = 0;
 		channel->buffer_count < channel->max_buffers;
 		channel->buffer_count++) {
@@ -2117,7 +2251,8 @@
 		desc->desc.id = channel->buffer_count;
 		/* allocate the buffer */
 		if (tspp_alloc_buffer(channel_id, &desc->desc,
-			channel->buffer_size, alloc, user) != 0) {
+			channel->buffer_size, channel->dma_pool,
+			alloc, user) != 0) {
 			kfree(desc);
 			pr_warn("%s: Can't allocate buffer %i",
 				__func__, channel->buffer_count);
@@ -2154,6 +2289,11 @@
 		 */
 		tspp_destroy_buffers(channel_id, channel);
 		channel->buffer_count = 0;
+
+		if (channel->dma_pool) {
+			dma_pool_destroy(channel->dma_pool);
+			channel->dma_pool = NULL;
+		}
 		return -ENOMEM;
 	}
 
@@ -2292,8 +2432,10 @@
 		 */
 		if (buffer->read_index == buffer->filled) {
 			buffer->state = TSPP_BUF_STATE_WAITING;
+
 			if (tspp_queue_buffer(channel, buffer))
 				pr_err("tspp: can't submit transfer");
+
 			channel->locked = channel->read;
 			channel->read = channel->read->next;
 		}
@@ -2317,7 +2459,7 @@
 	channel = filp->private_data;
 	dev = channel->pdev->pdev->id;
 
-	if (!param1)
+	if ((param0 != TSPP_IOCTL_CLOSE_STREAM) && !param1)
 		return -EINVAL;
 
 	switch (param0) {
@@ -2384,6 +2526,9 @@
 			sizeof(struct tspp_buffer)) == 0)
 			rc = tspp_set_buffer_size(channel, &b);
 		break;
+	case TSPP_IOCTL_CLOSE_STREAM:
+		rc = tspp_close_stream(dev, channel->id);
+		break;
 	default:
 		pr_err("tspp: Unknown ioctl %i", param0);
 	}
@@ -2505,6 +2650,137 @@
 	}
 }
 
+/* copy device-tree data to platfrom data struct */
+static __devinit struct msm_tspp_platform_data *
+msm_tspp_dt_to_pdata(struct platform_device *pdev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	struct msm_tspp_platform_data *data;
+	struct msm_gpio *gpios;
+	int i, rc;
+	int gpio;
+	u32 gpio_func;
+
+	/* Note: memory allocated by devm_kzalloc is freed automatically */
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+	if (!data) {
+		pr_err("tspp: Unable to allocate platform data\n");
+		return NULL;
+	}
+	rc = of_property_read_string(node, "qcom,tsif-pclk", &data->tsif_pclk);
+	if (rc) {
+		pr_err("tspp: Could not find tsif-pclk property, err = %d\n",
+			rc);
+		return NULL;
+	}
+	rc = of_property_read_string(node, "qcom,tsif-ref-clk",
+			&data->tsif_ref_clk);
+	if (rc) {
+		pr_err("tspp: Could not find tsif-ref-clk property, err = %d\n",
+			rc);
+		return NULL;
+	}
+
+	data->num_gpios = of_gpio_count(node);
+	if (data->num_gpios == 0) {
+		pr_err("tspp: Could not find GPIO definitions\n");
+		return NULL;
+	}
+	gpios = devm_kzalloc(&pdev->dev,
+			(data->num_gpios * sizeof(struct msm_gpio)),
+			GFP_KERNEL);
+	if (!gpios) {
+		pr_err("tspp: Unable to allocate memory for GPIOs table\n");
+		return NULL;
+	}
+	/* Assuming GPIO FUNC property is the same for all GPIOs */
+	if (of_property_read_u32(node, "qcom,gpios-func", &gpio_func)) {
+		pr_err("tspp: Could not find gpios-func property\n");
+		return NULL;
+	}
+	for (i = 0; i < data->num_gpios; i++) {
+		gpio = of_get_gpio(node, i);
+		gpios[i].gpio_cfg = GPIO_CFG(gpio, gpio_func,
+						GPIO_CFG_INPUT,
+						GPIO_CFG_PULL_DOWN,
+						GPIO_CFG_2MA);
+		rc = of_property_read_string_index(node, "qcom,gpio-names",
+						i, &gpios[i].label);
+		if (rc)
+			pr_warn("tspp: Could not find gpio-names property\n");
+	}
+
+	data->gpios = gpios;
+
+	return data;
+}
+
+static int msm_tspp_map_irqs(struct platform_device *pdev,
+				struct tspp_device *device)
+{
+	int rc;
+	int i;
+
+	/* get IRQ numbers from platform information */
+
+	/* map TSPP IRQ */
+	rc = platform_get_irq_byname(pdev, "TSIF_TSPP_IRQ");
+	if (rc > 0) {
+		device->tspp_irq = rc;
+		rc = request_irq(device->tspp_irq, tspp_isr, IRQF_SHARED,
+				 dev_name(&pdev->dev), device);
+		if (rc) {
+			dev_err(&pdev->dev,
+				"failed to request TSPP IRQ %d : %d",
+				device->tspp_irq, rc);
+			device->tspp_irq = 0;
+			return -EINVAL;
+		}
+	} else {
+		dev_err(&pdev->dev, "failed to get TSPP IRQ");
+		return -EINVAL;
+	}
+
+	/* map TSIF IRQs */
+	rc = platform_get_irq_byname(pdev, "TSIF0_IRQ");
+	if (rc > 0) {
+		device->tsif[0].tsif_irq = rc;
+	} else {
+		dev_err(&pdev->dev, "failed to get TSIF0 IRQ");
+		return -EINVAL;
+	}
+
+	rc = platform_get_irq_byname(pdev, "TSIF1_IRQ");
+	if (rc > 0) {
+		device->tsif[1].tsif_irq = rc;
+	} else {
+		dev_err(&pdev->dev, "failed to get TSIF1 IRQ");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < TSPP_TSIF_INSTANCES; i++) {
+		rc = request_irq(device->tsif[i].tsif_irq,
+				tsif_isr, IRQF_SHARED,
+				dev_name(&pdev->dev), &device->tsif[i]);
+		if (rc) {
+			dev_warn(&pdev->dev, "failed to request TSIF%d IRQ: %d",
+				i, rc);
+			device->tsif[i].tsif_irq = 0;
+		}
+	}
+
+	/* map BAM IRQ */
+	rc = platform_get_irq_byname(pdev, "TSIF_BAM_IRQ");
+	if (rc > 0) {
+		device->bam_irq = rc;
+	} else {
+		dev_err(&pdev->dev, "failed to get TSPP BAM IRQ");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int __devinit msm_tspp_probe(struct platform_device *pdev)
 {
 	int rc = -ENODEV;
@@ -2518,8 +2794,20 @@
 	struct resource *mem_bam;
 	struct tspp_channel *channel;
 
-	/* must have platform data */
-	data = pdev->dev.platform_data;
+	if (pdev->dev.of_node) {
+		/* get information from device tree */
+		data = msm_tspp_dt_to_pdata(pdev);
+		/* get device ID */
+		rc = of_property_read_u32(pdev->dev.of_node,
+					"cell-index", &pdev->id);
+		if (rc)
+			pdev->id = -1;
+
+		pdev->dev.platform_data = data;
+	} else {
+		/* must have platform data */
+		data = pdev->dev.platform_data;
+	}
 	if (!data) {
 		pr_err("tspp: Platform data not available");
 		rc = -EINVAL;
@@ -2568,7 +2856,8 @@
 	}
 
 	/* map I/O memory */
-	mem_tsif0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mem_tsif0 = platform_get_resource_byname(pdev,
+				IORESOURCE_MEM, "MSM_TSIF0_PHYS");
 	if (!mem_tsif0) {
 		pr_err("tspp: Missing tsif0 MEM resource");
 		rc = -ENXIO;
@@ -2581,7 +2870,8 @@
 		goto err_map_tsif0;
 	}
 
-	mem_tsif1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	mem_tsif1 = platform_get_resource_byname(pdev,
+				IORESOURCE_MEM, "MSM_TSIF1_PHYS");
 	if (!mem_tsif1) {
 		dev_err(&pdev->dev, "Missing tsif1 MEM resource");
 		rc = -ENXIO;
@@ -2594,7 +2884,8 @@
 		goto err_map_tsif1;
 	}
 
-	mem_tspp = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+	mem_tspp = platform_get_resource_byname(pdev,
+				IORESOURCE_MEM, "MSM_TSPP_PHYS");
 	if (!mem_tspp) {
 		dev_err(&pdev->dev, "Missing MEM resource");
 		rc = -ENXIO;
@@ -2606,7 +2897,8 @@
 		goto err_map_dev;
 	}
 
-	mem_bam = platform_get_resource(pdev, IORESOURCE_MEM, 3);
+	mem_bam = platform_get_resource_byname(pdev,
+				IORESOURCE_MEM, "MSM_TSPP_BAM_PHYS");
 	if (!mem_bam) {
 		pr_err("tspp: Missing bam MEM resource");
 		rc = -ENXIO;
@@ -2621,44 +2913,8 @@
 		goto err_map_bam;
 	}
 
-	/* map TSPP IRQ */
-	rc = platform_get_irq(pdev, 0);
-	if (rc > 0) {
-		device->tspp_irq = rc;
-		rc = request_irq(device->tspp_irq, tspp_isr, IRQF_SHARED,
-				 dev_name(&pdev->dev), device);
-		if (rc) {
-			dev_err(&pdev->dev, "failed to request IRQ %d : %d",
-				device->tspp_irq, rc);
-			goto err_irq;
-		}
-	} else {
-		dev_err(&pdev->dev, "failed to get tspp IRQ");
+	if (msm_tspp_map_irqs(pdev, device))
 		goto err_irq;
-	}
-
-	/* map TSIF IRQs */
-	device->tsif[0].tsif_irq = TSIF1_IRQ;
-	device->tsif[1].tsif_irq = TSIF2_IRQ;
-
-	for (i = 0; i < TSPP_TSIF_INSTANCES; i++) {
-		rc = request_irq(device->tsif[i].tsif_irq,
-				tsif_isr, IRQF_SHARED,
-				dev_name(&pdev->dev), &device->tsif[i]);
-		if (rc) {
-			dev_warn(&pdev->dev, "failed to request TSIF%d IRQ: %d",
-				i, rc);
-			device->tsif[i].tsif_irq = 0;
-		}
-	}
-
-	/* BAM IRQ */
-	device->bam_irq = TSIF_BAM_IRQ;
-
-	/* GPIOs */
-	rc = tspp_start_gpios(device);
-	if (rc)
-		goto err_gpio;
 
 	/* power management */
 	pm_runtime_set_active(&pdev->dev);
@@ -2688,17 +2944,17 @@
 	device->bam_props.irq = device->bam_irq;
 	device->bam_props.manage = SPS_BAM_MGR_LOCAL;
 
+	if (tspp_clock_start(device) != 0) {
+		dev_err(&pdev->dev, "Can't start clocks");
+		goto err_clock;
+	}
+
 	if (sps_register_bam_device(&device->bam_props,
 		&device->bam_handle) != 0) {
 		pr_err("tspp: failed to register bam");
 		goto err_bam;
 	}
 
-	if (tspp_clock_start(device) != 0) {
-		dev_err(&pdev->dev, "Can't start clocks");
-		goto err_clock;
-	}
-
 	spin_lock_init(&device->spinlock);
 	tasklet_init(&device->tlet, tspp_sps_complete_tlet,
 			(unsigned long)device);
@@ -2707,7 +2963,11 @@
 	tspp_global_reset(device);
 
 	version = readl_relaxed(device->base + TSPP_VERSION);
-	if (version != 1)
+	/*
+	 * TSPP version can be bits [7:0] or alternatively,
+	 * TSPP major version is bits [31:28].
+	 */
+	if ((version != 0x1) && (((version >> 28) & 0xF) != 0x1))
 		pr_warn("tspp: unrecognized hw version=%i", version);
 
 	/* initialize the channels */
@@ -2727,21 +2987,27 @@
 	return 0;
 
 err_channel:
-	/* uninitialize channels */
+	/* un-initialize channels */
 	for (j = 0; j < i; j++) {
 		channel = &(device->channels[i]);
 		device_destroy(tspp_class, channel->cdev.dev);
 		cdev_del(&channel->cdev);
 	}
-err_clock:
+
 	sps_deregister_bam_device(device->bam_handle);
+err_clock:
 err_bam:
 	tspp_debugfs_exit(device);
 	for (i = 0; i < TSPP_TSIF_INSTANCES; i++)
 		tsif_debugfs_exit(&device->tsif[i]);
-err_gpio:
 err_irq:
-	tspp_stop_gpios(device);
+	for (i = 0; i < TSPP_TSIF_INSTANCES; i++) {
+		if (device->tsif[i].tsif_irq)
+			free_irq(device->tsif[i].tsif_irq,  &device->tsif[i]);
+	}
+	if (device->tspp_irq)
+		free_irq(device->tspp_irq, device);
+
 	iounmap(device->bam_props.virt_addr);
 err_map_bam:
 err_res_bam:
@@ -2770,6 +3036,7 @@
 {
 	struct tspp_channel *channel;
 	u32 i;
+	int rc;
 
 	struct tspp_device *device = platform_get_drvdata(pdev);
 
@@ -2781,7 +3048,12 @@
 		cdev_del(&channel->cdev);
 	}
 
-	sps_deregister_bam_device(device->bam_handle);
+	/* de-registering BAM device requires clocks */
+	rc = tspp_clock_start(device);
+	if (rc == 0) {
+		sps_deregister_bam_device(device->bam_handle);
+		tspp_clock_stop(device);
+	}
 
 	for (i = 0; i < TSPP_TSIF_INSTANCES; i++) {
 		tsif_debugfs_exit(&device->tsif[i]);
@@ -2791,7 +3063,6 @@
 
 	wake_lock_destroy(&device->wake_lock);
 	free_irq(device->tspp_irq, device);
-	tspp_stop_gpios(device);
 
 	iounmap(device->bam_props.virt_addr);
 	iounmap(device->base);
@@ -2805,7 +3076,7 @@
 		clk_put(device->tsif_pclk);
 
 	pm_runtime_disable(&pdev->dev);
-	pm_runtime_put(&pdev->dev);
+
 	kfree(device);
 
 	return 0;
@@ -2830,12 +3101,18 @@
 	.runtime_resume = tspp_runtime_resume,
 };
 
+static struct of_device_id msm_match_table[] = {
+	{.compatible = "qcom,msm_tspp"},
+	{}
+};
+
 static struct platform_driver msm_tspp_driver = {
 	.probe          = msm_tspp_probe,
 	.remove         = __exit_p(msm_tspp_remove),
 	.driver         = {
 		.name   = "msm_tspp",
 		.pm     = &tspp_dev_pm_ops,
+		.of_match_table = msm_match_table,
 	},
 };
 
diff --git a/drivers/mmc/card/Kconfig b/drivers/mmc/card/Kconfig
index a1bea00..33f0600 100644
--- a/drivers/mmc/card/Kconfig
+++ b/drivers/mmc/card/Kconfig
@@ -80,7 +80,6 @@
 config MMC_BLOCK_TEST
 	tristate "MMC block test"
 	depends on MMC_BLOCK && IOSCHED_TEST
-	default y
 	help
 	  MMC block test can be used with test iosched to test the MMC block
 	  device.
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 0b5449e..a037c17 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -57,6 +57,7 @@
 #define INAND_CMD38_ARG_SECERASE 0x80
 #define INAND_CMD38_ARG_SECTRIM1 0x81
 #define INAND_CMD38_ARG_SECTRIM2 0x88
+#define MMC_BLK_TIMEOUT_MS  (30 * 1000)        /* 30 sec timeout */
 
 #define MMC_SANITIZE_REQ_TIMEOUT 240000 /* msec */
 
@@ -121,7 +122,8 @@
 	struct device_attribute force_ro;
 	struct device_attribute power_ro_lock;
 	struct device_attribute num_wr_reqs_to_start_packing;
-	struct device_attribute min_sectors_to_check_bkops_status;
+	struct device_attribute bkops_check_threshold;
+	struct device_attribute no_pack_for_random;
 	int	area_type;
 };
 
@@ -332,47 +334,113 @@
 }
 
 static ssize_t
-min_sectors_to_check_bkops_status_show(struct device *dev,
+bkops_check_threshold_show(struct device *dev,
 				  struct device_attribute *attr, char *buf)
 {
 	struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
-	unsigned int min_sectors_to_check_bkops_status;
 	struct mmc_card *card = md->queue.card;
 	int ret;
 
 	if (!card)
 		ret = -EINVAL;
-	else {
-	    min_sectors_to_check_bkops_status =
-		    card->bkops_info.min_sectors_to_queue_delayed_work;
+	else
 	    ret = snprintf(buf, PAGE_SIZE, "%d\n",
-			   min_sectors_to_check_bkops_status);
-	}
+		card->bkops_info.size_percentage_to_queue_delayed_work);
 
 	mmc_blk_put(md);
 	return ret;
 }
 
 static ssize_t
-min_sectors_to_check_bkops_status_store(struct device *dev,
+bkops_check_threshold_store(struct device *dev,
 				 struct device_attribute *attr,
 				 const char *buf, size_t count)
 {
 	int value;
 	struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
 	struct mmc_card *card = md->queue.card;
+	unsigned int card_size;
+	int ret = count;
 
-	if (!card)
-		return -EINVAL;
+	if (!card) {
+		ret = -EINVAL;
+		goto exit;
+	}
 
 	sscanf(buf, "%d", &value);
-	if (value >= 0)
-		card->bkops_info.min_sectors_to_queue_delayed_work = value;
+	if ((value <= 0) || (value >= 100)) {
+		ret = -EINVAL;
+		goto exit;
+	}
 
+	card_size = (unsigned int)get_capacity(md->disk);
+	if (card_size <= 0) {
+		ret = -EINVAL;
+		goto exit;
+	}
+	card->bkops_info.size_percentage_to_queue_delayed_work = value;
+	card->bkops_info.min_sectors_to_queue_delayed_work =
+		(card_size * value) / 100;
+
+	pr_debug("%s: size_percentage = %d, min_sectors = %d",
+			mmc_hostname(card->host),
+			card->bkops_info.size_percentage_to_queue_delayed_work,
+			card->bkops_info.min_sectors_to_queue_delayed_work);
+
+exit:
 	mmc_blk_put(md);
 	return count;
 }
 
+static ssize_t
+no_pack_for_random_show(struct device *dev,
+				  struct device_attribute *attr, char *buf)
+{
+	struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
+	int ret;
+
+	ret = snprintf(buf, PAGE_SIZE, "%d\n", md->queue.no_pack_for_random);
+
+	mmc_blk_put(md);
+	return ret;
+}
+
+static ssize_t
+no_pack_for_random_store(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf, size_t count)
+{
+	int value;
+	struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
+	struct mmc_card *card = md->queue.card;
+	int ret = count;
+
+	if (!card) {
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	sscanf(buf, "%d", &value);
+
+	if (value < 0) {
+		pr_err("%s: value %d is not valid. old value remains = %d",
+			mmc_hostname(card->host), value,
+			md->queue.no_pack_for_random);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	md->queue.no_pack_for_random = (value > 0) ?  true : false;
+
+	pr_debug("%s: no_pack_for_random: new value = %d",
+		mmc_hostname(card->host),
+		md->queue.no_pack_for_random);
+
+exit:
+	mmc_blk_put(md);
+	return ret;
+}
+
 static int mmc_blk_open(struct block_device *bdev, fmode_t mode)
 {
 	struct mmc_blk_data *md = mmc_blk_get(bdev->bd_disk);
@@ -510,8 +578,6 @@
 	struct mmc_request mrq = {NULL};
 	struct scatterlist sg;
 	int err;
-	int is_rpmb = false;
-	u32 status = 0;
 
 	/*
 	 * The caller must have CAP_SYS_RAWIO, and must be calling this on the
@@ -531,9 +597,6 @@
 		goto cmd_done;
 	}
 
-	if (md->area_type & MMC_BLK_DATA_AREA_RPMB)
-		is_rpmb = true;
-
 	card = md->queue.card;
 	if (IS_ERR(card)) {
 		err = PTR_ERR(card);
@@ -594,13 +657,6 @@
 			goto cmd_rel_host;
 	}
 
-	if (is_rpmb) {
-		err = mmc_set_blockcount(card, data.blocks,
-			idata->ic.write_flag & (1 << 31));
-		if (err)
-			goto cmd_rel_host;
-	}
-
 	mmc_wait_for_req(card->host, &mrq);
 
 	if (cmd.error) {
@@ -636,7 +692,171 @@
 		}
 	}
 
-	if (is_rpmb) {
+cmd_rel_host:
+	mmc_release_host(card->host);
+
+cmd_done:
+	mmc_blk_put(md);
+	kfree(idata->buf);
+	kfree(idata);
+	return err;
+}
+
+struct mmc_blk_ioc_rpmb_data {
+	struct mmc_blk_ioc_data *data[MMC_IOC_MAX_RPMB_CMD];
+};
+
+static struct mmc_blk_ioc_rpmb_data *mmc_blk_ioctl_rpmb_copy_from_user(
+	struct mmc_ioc_rpmb __user *user)
+{
+	struct mmc_blk_ioc_rpmb_data *idata;
+	int err, i;
+
+	idata = kzalloc(sizeof(*idata), GFP_KERNEL);
+	if (!idata) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	for (i = 0; i < MMC_IOC_MAX_RPMB_CMD; i++) {
+		idata->data[i] = mmc_blk_ioctl_copy_from_user(&(user->cmds[i]));
+		if (IS_ERR(idata->data[i])) {
+			err = PTR_ERR(idata->data[i]);
+			goto copy_err;
+		}
+	}
+
+	return idata;
+
+copy_err:
+	while (--i >= 0) {
+		kfree(idata->data[i]->buf);
+		kfree(idata->data[i]);
+	}
+	kfree(idata);
+out:
+	return ERR_PTR(err);
+}
+
+static int mmc_blk_ioctl_rpmb_cmd(struct block_device *bdev,
+	struct mmc_ioc_rpmb __user *ic_ptr)
+{
+	struct mmc_blk_ioc_rpmb_data *idata;
+	struct mmc_blk_data *md;
+	struct mmc_card *card;
+	struct mmc_command cmd = {0};
+	struct mmc_data data = {0};
+	struct mmc_request mrq = {NULL};
+	struct scatterlist sg;
+	int err = 0, i = 0;
+	u32 status = 0;
+
+	/* The caller must have CAP_SYS_RAWIO */
+	if (!capable(CAP_SYS_RAWIO))
+		return -EPERM;
+
+	md = mmc_blk_get(bdev->bd_disk);
+	/* make sure this is a rpmb partition */
+	if ((!md) || (!(md->area_type & MMC_BLK_DATA_AREA_RPMB))) {
+		err = -EINVAL;
+		goto cmd_done;
+	}
+
+	idata = mmc_blk_ioctl_rpmb_copy_from_user(ic_ptr);
+	if (IS_ERR(idata)) {
+		err = PTR_ERR(idata);
+		goto cmd_done;
+	}
+
+	card = md->queue.card;
+	if (IS_ERR(card)) {
+		err = PTR_ERR(card);
+		goto idata_free;
+	}
+
+	mmc_claim_host(card->host);
+
+	err = mmc_blk_part_switch(card, md);
+	if (err)
+		goto cmd_rel_host;
+
+	for (i = 0; i < MMC_IOC_MAX_RPMB_CMD; i++) {
+		struct mmc_blk_ioc_data *curr_data;
+		struct mmc_ioc_cmd *curr_cmd;
+
+		curr_data = idata->data[i];
+		curr_cmd = &curr_data->ic;
+		if (!curr_cmd->opcode)
+			break;
+
+		cmd.opcode = curr_cmd->opcode;
+		cmd.arg = curr_cmd->arg;
+		cmd.flags = curr_cmd->flags;
+
+		if (curr_data->buf_bytes) {
+			data.sg = &sg;
+			data.sg_len = 1;
+			data.blksz = curr_cmd->blksz;
+			data.blocks = curr_cmd->blocks;
+
+			sg_init_one(data.sg, curr_data->buf,
+					curr_data->buf_bytes);
+
+			if (curr_cmd->write_flag)
+				data.flags = MMC_DATA_WRITE;
+			else
+				data.flags = MMC_DATA_READ;
+
+			/* data.flags must already be set before doing this. */
+			mmc_set_data_timeout(&data, card);
+
+			/*
+			 * Allow overriding the timeout_ns for empirical tuning.
+			 */
+			if (curr_cmd->data_timeout_ns)
+				data.timeout_ns = curr_cmd->data_timeout_ns;
+
+			mrq.data = &data;
+		}
+
+		mrq.cmd = &cmd;
+
+		err = mmc_set_blockcount(card, data.blocks,
+				curr_cmd->write_flag & (1 << 31));
+		if (err)
+			goto cmd_rel_host;
+
+		mmc_wait_for_req(card->host, &mrq);
+
+		if (cmd.error) {
+			dev_err(mmc_dev(card->host), "%s: cmd error %d\n",
+					__func__, cmd.error);
+			err = cmd.error;
+			goto cmd_rel_host;
+		}
+		if (data.error) {
+			dev_err(mmc_dev(card->host), "%s: data error %d\n",
+					__func__, data.error);
+			err = data.error;
+			goto cmd_rel_host;
+		}
+
+		if (copy_to_user(&(ic_ptr->cmds[i].response), cmd.resp,
+					sizeof(cmd.resp))) {
+			err = -EFAULT;
+			goto cmd_rel_host;
+		}
+
+		if (!curr_cmd->write_flag) {
+			if (copy_to_user((void __user *)(unsigned long)
+						curr_cmd->data_ptr,
+						curr_data->buf,
+						curr_data->buf_bytes)) {
+				err = -EFAULT;
+				goto cmd_rel_host;
+			}
+		}
+
 		/*
 		 * Ensure RPMB command has completed by polling CMD13
 		 * "Send Status".
@@ -651,10 +871,15 @@
 cmd_rel_host:
 	mmc_release_host(card->host);
 
+idata_free:
+	for (i = 0; i < MMC_IOC_MAX_RPMB_CMD; i++) {
+		kfree(idata->data[i]->buf);
+		kfree(idata->data[i]);
+	}
+	kfree(idata);
+
 cmd_done:
 	mmc_blk_put(md);
-	kfree(idata->buf);
-	kfree(idata);
 	return err;
 }
 
@@ -664,6 +889,9 @@
 	int ret = -EINVAL;
 	if (cmd == MMC_IOC_CMD)
 		ret = mmc_blk_ioctl_cmd(bdev, (struct mmc_ioc_cmd __user *)arg);
+	if (cmd == MMC_IOC_RPMB_CMD)
+		ret = mmc_blk_ioctl_rpmb_cmd(bdev,
+				(struct mmc_ioc_rpmb __user *)arg);
 	return ret;
 }
 
@@ -692,7 +920,8 @@
 	int ret;
 	struct mmc_blk_data *main_md = mmc_get_drvdata(card);
 
-	if (main_md->part_curr == md->part_type)
+	if ((main_md->part_curr == md->part_type) &&
+	    (card->part_curr == md->part_type))
 		return 0;
 
 	if (mmc_card_mmc(card)) {
@@ -708,6 +937,7 @@
 			return ret;
 
 		card->ext_csd.part_config = part_config;
+		card->part_curr = md->part_type;
 	}
 
 	main_md->part_curr = md->part_type;
@@ -1233,6 +1463,9 @@
 	 */
 	if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {
 		u32 status;
+		unsigned long timeout;
+
+		timeout = jiffies + msecs_to_jiffies(MMC_BLK_TIMEOUT_MS);
 		do {
 			int err = get_card_status(card, &status, 5);
 			if (err) {
@@ -1240,6 +1473,17 @@
 				       req->rq_disk->disk_name, err);
 				return MMC_BLK_CMD_ERR;
 			}
+
+			/* Timeout if the device never becomes ready for data
+			 * and never leaves the program state.
+			 */
+			if (time_after(jiffies, timeout)) {
+				pr_err("%s: Card stuck in programming state!"\
+					" %s %s\n", mmc_hostname(card->host),
+					req->rq_disk->disk_name, __func__);
+
+				return MMC_BLK_CMD_ERR;
+			}
 			/*
 			 * Some cards mishandle the status bits,
 			 * so make sure to check both the busy
@@ -1281,6 +1525,120 @@
 	return MMC_BLK_SUCCESS;
 }
 
+/*
+ * mmc_blk_reinsert_req() - re-insert request back to the scheduler
+ * @areq:	request to re-insert.
+ *
+ * Request may be packed or single. When fails to reinsert request, it will be
+ * requeued to the the dispatch queue.
+ */
+static void mmc_blk_reinsert_req(struct mmc_async_req *areq)
+{
+	struct request *prq;
+	int ret = 0;
+	struct mmc_queue_req *mq_rq;
+	struct request_queue *q;
+
+	mq_rq = container_of(areq, struct mmc_queue_req, mmc_active);
+	q = mq_rq->req->q;
+	if (mq_rq->packed_cmd != MMC_PACKED_NONE) {
+		while (!list_empty(&mq_rq->packed_list)) {
+			/* return requests in reverse order */
+			prq = list_entry_rq(mq_rq->packed_list.prev);
+			list_del_init(&prq->queuelist);
+			spin_lock_irq(q->queue_lock);
+			ret = blk_reinsert_request(q, prq);
+			if (ret) {
+				blk_requeue_request(q, prq);
+				spin_unlock_irq(q->queue_lock);
+				goto reinsert_error;
+			}
+			spin_unlock_irq(q->queue_lock);
+		}
+	} else {
+		spin_lock_irq(q->queue_lock);
+		ret = blk_reinsert_request(q, mq_rq->req);
+		if (ret)
+			blk_requeue_request(q, mq_rq->req);
+		spin_unlock_irq(q->queue_lock);
+	}
+	return;
+
+reinsert_error:
+	pr_err("%s: blk_reinsert_request() failed (%d)",
+			mq_rq->req->rq_disk->disk_name, ret);
+	/*
+	 * -EIO will be reported for this request and rest of packed_list.
+	 *  Urgent request will be proceeded anyway, while upper layer
+	 *  responsibility to re-send failed requests
+	 */
+	while (!list_empty(&mq_rq->packed_list)) {
+		prq = list_entry_rq(mq_rq->packed_list.next);
+		list_del_init(&prq->queuelist);
+		spin_lock_irq(q->queue_lock);
+		blk_requeue_request(q, prq);
+		spin_unlock_irq(q->queue_lock);
+	}
+}
+
+/*
+ * mmc_blk_update_interrupted_req() - update of the stopped request
+ * @card:	the MMC card associated with the request.
+ * @areq:	interrupted async request.
+ *
+ * Get stopped request state from card and update successfully done part of
+ * the request by setting packed_fail_idx.  The packed_fail_idx is index of
+ * first uncompleted request in packed request list, for non-packed request
+ * packed_fail_idx remains unchanged.
+ *
+ * Returns: MMC_BLK_SUCCESS for success, MMC_BLK_ABORT otherwise
+ */
+static int mmc_blk_update_interrupted_req(struct mmc_card *card,
+					struct mmc_async_req *areq)
+{
+	int ret = MMC_BLK_SUCCESS;
+	u8 *ext_csd;
+	int correctly_done;
+	struct mmc_queue_req *mq_rq = container_of(areq, struct mmc_queue_req,
+				      mmc_active);
+	struct request *prq;
+	u8 req_index = 0;
+
+	if (mq_rq->packed_cmd == MMC_PACKED_NONE)
+		return MMC_BLK_SUCCESS;
+
+	ext_csd = kmalloc(512, GFP_KERNEL);
+	if (!ext_csd)
+		return MMC_BLK_ABORT;
+
+	/* get correctly programmed sectors number from card */
+	ret = mmc_send_ext_csd(card, ext_csd);
+	if (ret) {
+		pr_err("%s: error %d reading ext_csd\n",
+				mmc_hostname(card->host), ret);
+		ret = MMC_BLK_ABORT;
+		goto exit;
+	}
+	correctly_done = card->ext_csd.data_sector_size *
+		(ext_csd[EXT_CSD_CORRECTLY_PRG_SECTORS_NUM + 0] << 0 |
+		 ext_csd[EXT_CSD_CORRECTLY_PRG_SECTORS_NUM + 1] << 8 |
+		 ext_csd[EXT_CSD_CORRECTLY_PRG_SECTORS_NUM + 2] << 16 |
+		 ext_csd[EXT_CSD_CORRECTLY_PRG_SECTORS_NUM + 3] << 24);
+
+	list_for_each_entry(prq, &mq_rq->packed_list, queuelist) {
+		if ((correctly_done - (int)blk_rq_bytes(prq)) < 0) {
+			/* prq is not successfull */
+			mq_rq->packed_fail_idx = req_index;
+			break;
+		}
+		correctly_done -= blk_rq_bytes(prq);
+		req_index++;
+	}
+exit:
+	kfree(ext_csd);
+	return ret;
+}
+
 static int mmc_blk_packed_err_check(struct mmc_card *card,
 				    struct mmc_async_req *areq)
 {
@@ -1477,10 +1835,27 @@
 		mqrq->mmc_active.err_check = mq->err_check_fn;
 	else
 		mqrq->mmc_active.err_check = mmc_blk_err_check;
+	mqrq->mmc_active.reinsert_req = mmc_blk_reinsert_req;
+	mqrq->mmc_active.update_interrupted_req =
+		mmc_blk_update_interrupted_req;
 
 	mmc_queue_bounce_pre(mqrq);
 }
 
+/**
+ * mmc_blk_disable_wr_packing() - disables packing mode
+ * @mq:	MMC queue.
+ *
+ */
+void mmc_blk_disable_wr_packing(struct mmc_queue *mq)
+{
+	if (mq) {
+		mq->wr_packing_enabled = false;
+		mq->num_of_potential_packed_wr_reqs = 0;
+	}
+}
+EXPORT_SYMBOL(mmc_blk_disable_wr_packing);
+
 static void mmc_blk_write_packing_control(struct mmc_queue *mq,
 					  struct request *req)
 {
@@ -1515,8 +1890,7 @@
 	data_dir = rq_data_dir(req);
 
 	if (data_dir == READ) {
-		mq->num_of_potential_packed_wr_reqs = 0;
-		mq->wr_packing_enabled = false;
+		mmc_blk_disable_wr_packing(mq);
 		return;
 	} else if (data_dir == WRITE) {
 		mq->num_of_potential_packed_wr_reqs++;
@@ -1596,6 +1970,9 @@
 			!IS_ALIGNED(blk_rq_sectors(cur), 8))
 		goto no_packed;
 
+	if (cur->cmd_flags & REQ_FUA)
+		goto no_packed;
+
 	max_blk_count = min(card->host->max_blk_count,
 			card->host->max_req_size >> 9);
 	if (unlikely(max_blk_count > 0xffff))
@@ -1635,6 +2012,12 @@
 			break;
 		}
 
+		if (next->cmd_flags & REQ_FUA) {
+			MMC_BLK_UPDATE_STOP_REASON(stats, FUA);
+			put_back = 1;
+			break;
+		}
+
 		if (rq_data_dir(cur) != rq_data_dir(next)) {
 			MMC_BLK_UPDATE_STOP_REASON(stats, WRONG_DATA_DIR);
 			put_back = 1;
@@ -1664,6 +2047,15 @@
 			break;
 		}
 
+		if (mq->no_pack_for_random) {
+			if ((blk_rq_pos(cur) + blk_rq_sectors(cur)) !=
+			    blk_rq_pos(next)) {
+				MMC_BLK_UPDATE_STOP_REASON(stats, RANDOM);
+				put_back = 1;
+				break;
+			}
+		}
+
 		if (rq_data_dir(next) == WRITE) {
 			mq->num_of_potential_packed_wr_reqs++;
 			if (card->ext_csd.bkops_en)
@@ -1789,6 +2181,11 @@
 	if (mq->packed_test_fn)
 		mq->packed_test_fn(mq->queue, mqrq);
 
+
+	mqrq->mmc_active.reinsert_req = mmc_blk_reinsert_req;
+	mqrq->mmc_active.update_interrupted_req =
+		mmc_blk_update_interrupted_req;
+
 	mmc_queue_bounce_pre(mqrq);
 }
 
@@ -1850,13 +2247,15 @@
 	mmc_blk_clear_packed(mq_rq);
 	return ret;
 }
-static void mmc_blk_abort_packed_req(struct mmc_queue_req *mq_rq)
+static void mmc_blk_abort_packed_req(struct mmc_queue_req *mq_rq,
+					unsigned int cmd_flags)
 {
 	struct request *prq;
 
 	while (!list_empty(&mq_rq->packed_list)) {
 		prq = list_entry_rq(mq_rq->packed_list.next);
 		list_del_init(&prq->queuelist);
+		prq->cmd_flags |= cmd_flags;
 		blk_end_request(prq, -EIO, blk_rq_bytes(prq));
 	}
 
@@ -1917,8 +2316,11 @@
 		} else
 			areq = NULL;
 		areq = mmc_start_req(card->host, areq, (int *) &status);
-		if (!areq)
+		if (!areq) {
+			if (status == MMC_BLK_NEW_REQUEST)
+				mq->flags |= MMC_QUEUE_NEW_REQUEST;
 			return 0;
+		}
 
 		mq_rq = container_of(areq, struct mmc_queue_req, mmc_active);
 		brq = &mq_rq->brq;
@@ -1927,6 +2329,19 @@
 		mmc_queue_bounce_post(mq_rq);
 
 		switch (status) {
+		case MMC_BLK_URGENT:
+			if (mq_rq->packed_cmd != MMC_PACKED_NONE) {
+				/* complete successfully transmitted part */
+				if (mmc_blk_end_packed_req(mq_rq))
+					/* process for not transmitted part */
+					mmc_blk_reinsert_req(areq);
+			} else {
+				mmc_blk_reinsert_req(areq);
+			}
+
+			mq->flags |= MMC_QUEUE_URGENT_REQUEST;
+			ret = 0;
+			break;
 		case MMC_BLK_SUCCESS:
 		case MMC_BLK_PARTIAL:
 			/*
@@ -1999,6 +2414,11 @@
 			break;
 		case MMC_BLK_NOMEDIUM:
 			goto cmd_abort;
+		default:
+			pr_err("%s:%s: Unhandled return value (%d)",
+					req->rq_disk->disk_name,
+					__func__, status);
+			goto cmd_abort;
 		}
 
 		if (ret) {
@@ -2031,19 +2451,28 @@
 			ret = blk_end_request(req, -EIO,
 					blk_rq_cur_bytes(req));
 	} else {
-		mmc_blk_abort_packed_req(mq_rq);
+		mmc_blk_abort_packed_req(mq_rq, 0);
 	}
 
  start_new_req:
 	if (rqc) {
-		/*
-		 * If current request is packed, it needs to put back.
-		 */
-		if (mq->mqrq_cur->packed_cmd != MMC_PACKED_NONE)
-			mmc_blk_revert_packed_req(mq, mq->mqrq_cur);
+		if (mmc_card_removed(card)) {
+			if (mq_rq->packed_cmd == MMC_PACKED_NONE) {
+				rqc->cmd_flags |= REQ_QUIET;
+				blk_end_request_all(rqc, -EIO);
+			} else {
+				mmc_blk_abort_packed_req(mq_rq, REQ_QUIET);
+			}
+		} else {
+			/* If current request is packed, it needs to put back */
+			if (mq_rq->packed_cmd != MMC_PACKED_NONE)
+				mmc_blk_revert_packed_req(mq, mq->mqrq_cur);
 
-		mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq);
-		mmc_start_req(card->host, &mq->mqrq_cur->mmc_active, NULL);
+			mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq);
+			mmc_start_req(card->host,
+					&mq->mqrq_cur->mmc_active,
+					NULL);
+		}
 	}
 
 	return 0;
@@ -2054,6 +2483,8 @@
 	int ret;
 	struct mmc_blk_data *md = mq->data;
 	struct mmc_card *card = md->queue.card;
+	struct mmc_host *host = card->host;
+	unsigned long flags;
 
 #ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
 	if (mmc_bus_needs_resume(card->host)) {
@@ -2062,9 +2493,12 @@
 	}
 #endif
 
-	if (req && !mq->mqrq_prev->req)
+	if (req && !mq->mqrq_prev->req) {
 		/* claim host only for the first request */
 		mmc_claim_host(card->host);
+		if (card->ext_csd.bkops_en)
+			mmc_stop_bkops(card);
+	}
 
 	ret = mmc_blk_part_switch(card, md);
 	if (ret) {
@@ -2077,6 +2511,8 @@
 
 	mmc_blk_write_packing_control(mq, req);
 
+	mq->flags &= ~MMC_QUEUE_NEW_REQUEST;
+	mq->flags &= ~MMC_QUEUE_URGENT_REQUEST;
 	if (req && req->cmd_flags & REQ_SANITIZE) {
 		/* complete ongoing async transfer before issuing sanitize */
 		if (card->host && card->host->areq)
@@ -2097,13 +2533,22 @@
 			mmc_blk_issue_rw_rq(mq, NULL);
 		ret = mmc_blk_issue_flush(mq, req);
 	} else {
+		if (!req && host->areq) {
+			spin_lock_irqsave(&host->context_info.lock, flags);
+			host->context_info.is_waiting_last_req = true;
+			spin_unlock_irqrestore(&host->context_info.lock, flags);
+		}
 		ret = mmc_blk_issue_rw_rq(mq, req);
 	}
 
 out:
-	if (!req)
+	if ((!req && !(mq->flags & MMC_QUEUE_NEW_REQUEST)) ||
+			(mq->flags & MMC_QUEUE_URGENT_REQUEST)) {
+		if (mmc_card_need_bkops(card))
+			mmc_start_bkops(card, false);
 		/* release host only when there are no more requests */
 		mmc_release_host(card->host);
+	}
 	return ret;
 }
 
@@ -2122,6 +2567,8 @@
 {
 	struct mmc_blk_data *md;
 	int devidx, ret;
+	unsigned int percentage =
+		BKOPS_SIZE_PERCENTAGE_TO_QUEUE_DELAYED_WORK;
 
 	devidx = find_first_zero_bit(dev_use, max_devices);
 	if (devidx >= max_devices)
@@ -2201,6 +2648,10 @@
 	blk_queue_logical_block_size(md->queue.queue, 512);
 	set_capacity(md->disk, size);
 
+	card->bkops_info.size_percentage_to_queue_delayed_work = percentage;
+	card->bkops_info.min_sectors_to_queue_delayed_work =
+		((unsigned int)size * percentage) / 100;
+
 	if (mmc_host_cmd23(card->host)) {
 		if (mmc_card_mmc(card) ||
 		    (mmc_card_sd(card) &&
@@ -2393,22 +2844,32 @@
 	if (ret)
 		goto num_wr_reqs_to_start_packing_fail;
 
-	md->min_sectors_to_check_bkops_status.show =
-		min_sectors_to_check_bkops_status_show;
-	md->min_sectors_to_check_bkops_status.store =
-		min_sectors_to_check_bkops_status_store;
-	sysfs_attr_init(&md->min_sectors_to_check_bkops_status.attr);
-	md->min_sectors_to_check_bkops_status.attr.name =
-		"min_sectors_to_check_bkops_status";
-	md->min_sectors_to_check_bkops_status.attr.mode = S_IRUGO | S_IWUSR;
+	md->bkops_check_threshold.show = bkops_check_threshold_show;
+	md->bkops_check_threshold.store = bkops_check_threshold_store;
+	sysfs_attr_init(&md->bkops_check_threshold.attr);
+	md->bkops_check_threshold.attr.name = "bkops_check_threshold";
+	md->bkops_check_threshold.attr.mode = S_IRUGO | S_IWUSR;
 	ret = device_create_file(disk_to_dev(md->disk),
-				 &md->min_sectors_to_check_bkops_status);
+				 &md->bkops_check_threshold);
 	if (ret)
-		goto min_sectors_to_check_bkops_status_fails;
+		goto bkops_check_threshold_fails;
+
+	md->no_pack_for_random.show = no_pack_for_random_show;
+	md->no_pack_for_random.store = no_pack_for_random_store;
+	sysfs_attr_init(&md->no_pack_for_random.attr);
+	md->no_pack_for_random.attr.name = "no_pack_for_random";
+	md->no_pack_for_random.attr.mode = S_IRUGO | S_IWUSR;
+	ret = device_create_file(disk_to_dev(md->disk),
+				 &md->no_pack_for_random);
+	if (ret)
+		goto no_pack_for_random_fails;
 
 	return ret;
 
-min_sectors_to_check_bkops_status_fails:
+no_pack_for_random_fails:
+	device_remove_file(disk_to_dev(md->disk),
+			   &md->bkops_check_threshold);
+bkops_check_threshold_fails:
 	device_remove_file(disk_to_dev(md->disk),
 			   &md->num_wr_reqs_to_start_packing);
 num_wr_reqs_to_start_packing_fail:
diff --git a/drivers/mmc/card/mmc_block_test.c b/drivers/mmc/card/mmc_block_test.c
index 610a822..7a4d19e 100644
--- a/drivers/mmc/card/mmc_block_test.c
+++ b/drivers/mmc/card/mmc_block_test.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
@@ -26,7 +26,7 @@
 
 #define MODULE_NAME "mmc_block_test"
 #define TEST_MAX_SECTOR_RANGE		(600*1024*1024) /* 600 MB */
-#define TEST_MAX_BIOS_PER_REQ		120
+#define TEST_MAX_BIOS_PER_REQ		128
 #define CMD23_PACKED_BIT	(1 << 30)
 #define LARGE_PRIME_1	1103515367
 #define LARGE_PRIME_2	35757
@@ -37,37 +37,40 @@
 #define SECTOR_SIZE 512
 #define NUM_OF_SECTORS_PER_BIO		((BIO_U32_SIZE * 4) / SECTOR_SIZE)
 #define BIO_TO_SECTOR(x)		(x * NUM_OF_SECTORS_PER_BIO)
-/* the desired long test size to be written or read */
-#define LONG_TEST_MAX_NUM_BYTES (50*1024*1024) /* 50MB */
+/* the desired long test size to be read */
+#define LONG_READ_TEST_MAX_NUM_BYTES (50*1024*1024) /* 50MB */
+/* the minimum amount of requests that will be created */
+#define LONG_WRITE_TEST_MIN_NUM_REQS 200 /* 100MB */
 /* request queue limitation is 128 requests, and we leave 10 spare requests */
 #define TEST_MAX_REQUESTS 118
-#define LONG_TEST_MAX_NUM_REQS	(LONG_TEST_MAX_NUM_BYTES / \
+#define LONG_READ_TEST_MAX_NUM_REQS	(LONG_READ_TEST_MAX_NUM_BYTES / \
 		(TEST_MAX_BIOS_PER_REQ * sizeof(int) * BIO_U32_SIZE))
 /* this doesn't allow the test requests num to be greater than the maximum */
-#define LONG_TEST_ACTUAL_NUM_REQS  \
-			((TEST_MAX_REQUESTS < LONG_TEST_MAX_NUM_REQS) ? \
-				TEST_MAX_REQUESTS : LONG_TEST_MAX_NUM_REQS)
+#define LONG_READ_TEST_ACTUAL_NUM_REQS  \
+			((TEST_MAX_REQUESTS < LONG_READ_TEST_MAX_NUM_REQS) ? \
+				TEST_MAX_REQUESTS : LONG_READ_TEST_MAX_NUM_REQS)
 #define MB_MSEC_RATIO_APPROXIMATION ((1024 * 1024) / 1000)
 /* actual number of bytes in test */
-#define LONG_TEST_ACTUAL_BYTE_NUM  (LONG_TEST_ACTUAL_NUM_REQS *  \
+#define LONG_READ_NUM_BYTES  (LONG_READ_TEST_ACTUAL_NUM_REQS *  \
 			(TEST_MAX_BIOS_PER_REQ * sizeof(int) * BIO_U32_SIZE))
 /* actual number of MiB in test multiplied by 10, for single digit precision*/
-#define LONG_TEST_ACTUAL_MB_NUM_X_10 ((LONG_TEST_ACTUAL_BYTE_NUM * 10) / \
-					(1024 * 1024))
+#define BYTE_TO_MB_x_10(x) ((x * 10) / (1024 * 1024))
 /* extract integer value */
-#define LONG_TEST_SIZE_INTEGER (LONG_TEST_ACTUAL_MB_NUM_X_10 / 10)
+#define LONG_TEST_SIZE_INTEGER(x) (BYTE_TO_MB_x_10(x) / 10)
 /* and calculate the MiB value fraction */
-#define LONG_TEST_SIZE_FRACTION (LONG_TEST_ACTUAL_MB_NUM_X_10 - \
-		(LONG_TEST_SIZE_INTEGER * 10))
+#define LONG_TEST_SIZE_FRACTION(x) (BYTE_TO_MB_x_10(x) - \
+		(LONG_TEST_SIZE_INTEGER(x) * 10))
+#define LONG_WRITE_TEST_SLEEP_TIME_MS 5
 
 #define test_pr_debug(fmt, args...) pr_debug("%s: "fmt"\n", MODULE_NAME, args)
 #define test_pr_info(fmt, args...) pr_info("%s: "fmt"\n", MODULE_NAME, args)
 #define test_pr_err(fmt, args...) pr_err("%s: "fmt"\n", MODULE_NAME, args)
 
 #define SANITIZE_TEST_TIMEOUT 240000
+#define NEW_REQ_TEST_SLEEP_TIME 1
+#define NEW_REQ_TEST_NUM_BIOS 64
 #define TEST_REQUEST_NUM_OF_BIOS	3
 
-
 #define CHECK_BKOPS_STATS(stats, exp_bkops, exp_hpi, exp_suspend)	\
 				   ((stats.bkops != exp_bkops) ||	\
 				    (stats.hpi != exp_hpi) ||		\
@@ -153,6 +156,8 @@
 
 	TEST_LONG_SEQUENTIAL_READ,
 	TEST_LONG_SEQUENTIAL_WRITE,
+
+	TEST_NEW_REQ_NOTIFICATION,
 };
 
 enum mmc_block_test_group {
@@ -163,6 +168,7 @@
 	TEST_SEND_INVALID_GROUP,
 	TEST_PACKING_CONTROL_GROUP,
 	TEST_BKOPS_GROUP,
+	TEST_NEW_NOTIFICATION_GROUP,
 };
 
 enum bkops_test_stages {
@@ -182,6 +188,7 @@
 	struct dentry *bkops_test;
 	struct dentry *long_sequential_read_test;
 	struct dentry *long_sequential_write_test;
+	struct dentry *new_req_notification_test;
 };
 
 struct mmc_block_test_data {
@@ -217,6 +224,8 @@
 	enum bkops_test_stages	bkops_stage;
 	/* A wait queue for BKOPs tests */
 	wait_queue_head_t bkops_wait_q;
+	/* A counter for the number of test requests completed */
+	unsigned int completed_req_count;
 };
 
 static struct mmc_block_test_data *mbtd;
@@ -651,6 +660,8 @@
 		return "\"long sequential read\"";
 	case TEST_LONG_SEQUENTIAL_WRITE:
 		return "\"long sequential write\"";
+	case TEST_NEW_REQ_NOTIFICATION:
+		return "\"new request notification test\"";
 	default:
 		return " Unknown testcase";
 	}
@@ -971,8 +982,6 @@
 			     __func__, mbtd->random_test_seed);
 	}
 
-	mmc_blk_init_packed_statistics(mq->card);
-
 	ret = prepare_request_add_write_reqs(td, num_requests, is_err_expected,
 					     is_random);
 	if (ret)
@@ -1068,8 +1077,6 @@
 			     __func__, mbtd->random_test_seed);
 	}
 
-	mmc_blk_init_packed_statistics(mq->card);
-
 	if (td->test_info.testcase ==
 			TEST_PACK_MIX_NO_PACKED_PACKED_NO_PACKED) {
 		temp_num_req = num_requests;
@@ -1191,9 +1198,9 @@
 		break;
 	case TEST_PACKING_NOT_EXP_LESS_THAN_TRIGGER_REQUESTS:
 	case TEST_PACKING_NOT_EXP_TRIGGER_REQUESTS:
-		mbtd->exp_packed_stats.packing_events[num_packed_reqs] = 1;
 		break;
 	default:
+		BUG_ON(num_packed_reqs < 0);
 		mbtd->exp_packed_stats.pack_stop_reason[EMPTY_QUEUE] = 1;
 		mbtd->exp_packed_stats.packing_events[num_packed_reqs] = 1;
 	}
@@ -1224,8 +1231,6 @@
 
 	max_packed_reqs = mq->card->ext_csd.max_packed_writes;
 
-	mmc_blk_init_packed_statistics(mq->card);
-
 	for (i = 1; i <= num_requests; i++) {
 		if (i > (num_requests / 2))
 			is_err_expected = 1;
@@ -1335,13 +1340,12 @@
 	return num_requests;
 }
 
-static int prepare_long_test_requests(struct test_data *td)
+static int prepare_long_read_test_requests(struct test_data *td)
 {
 
 	int ret;
 	int start_sec;
 	int j;
-	int test_direction;
 
 	if (td)
 		start_sec = td->start_sector;
@@ -1350,23 +1354,18 @@
 		return -EINVAL;
 	}
 
-	if (td->test_info.testcase == TEST_LONG_SEQUENTIAL_WRITE)
-		test_direction = WRITE;
-	else
-		test_direction = READ;
+	test_pr_info("%s: Adding %d read requests, first req_id=%d", __func__,
+		     LONG_READ_TEST_ACTUAL_NUM_REQS, td->wr_rd_next_req_id);
 
-	test_pr_info("%s: Adding %d write requests, first req_id=%d", __func__,
-		     LONG_TEST_ACTUAL_NUM_REQS, td->wr_rd_next_req_id);
+	for (j = 0; j < LONG_READ_TEST_ACTUAL_NUM_REQS; j++) {
 
-	for (j = 0; j < LONG_TEST_ACTUAL_NUM_REQS; j++) {
-
-		ret = test_iosched_add_wr_rd_test_req(0, test_direction,
+		ret = test_iosched_add_wr_rd_test_req(0, READ,
 						start_sec,
 						TEST_MAX_BIOS_PER_REQ,
 						TEST_NO_PATTERN, NULL);
 		if (ret) {
-			test_pr_err("%s: failed to add a bio request",
-				     __func__);
+			test_pr_err("%s: failed to add a read request, err = %d"
+				    , __func__, ret);
 			return ret;
 		}
 
@@ -1486,10 +1485,8 @@
 			test_packed_trigger, is_random);
 		break;
 	case TEST_LONG_SEQUENTIAL_WRITE:
-		ret = prepare_long_test_requests(td);
-		break;
 	case TEST_LONG_SEQUENTIAL_READ:
-		ret = prepare_long_test_requests(td);
+		ret = prepare_long_read_test_requests(td);
 		break;
 	default:
 		test_pr_info("%s: Invalid test case...", __func__);
@@ -1499,6 +1496,44 @@
 	return ret;
 }
 
+static int run_packed_test(struct test_data *td)
+{
+	struct mmc_queue *mq;
+	struct request_queue *req_q;
+
+	if (!td) {
+		pr_err("%s: NULL td", __func__);
+		return -EINVAL;
+	}
+
+	req_q = td->req_q;
+
+	if (!req_q) {
+		pr_err("%s: NULL request queue", __func__);
+		return -EINVAL;
+	}
+
+	mq = req_q->queuedata;
+	if (!mq) {
+		test_pr_err("%s: NULL mq", __func__);
+		return -EINVAL;
+	}
+	mmc_blk_init_packed_statistics(mq->card);
+
+	if (td->test_info.testcase != TEST_PACK_MIX_PACKED_NO_PACKED_PACKED) {
+		/*
+		 * Verify that the packing is disabled before starting the
+		 * test
+		 */
+		mq->wr_packing_enabled = false;
+		mq->num_of_potential_packed_wr_reqs = 0;
+	}
+
+	__blk_run_queue(td->req_q);
+
+	return 0;
+}
+
 /*
  * An implementation for the post_test_fn in the test_info data structure.
  * In our case we just reset the function pointers in the mmc_queue in order for
@@ -1877,8 +1912,6 @@
 			break;
 		}
 
-		td->next_req = list_entry(td->test_queue.prev,
-				struct test_request, queuelist);
 		__blk_run_queue(q);
 		wait_event(mbtd->bkops_wait_q,
 			   mbtd->bkops_stage == BKOPS_STAGE_4);
@@ -1908,8 +1941,6 @@
 			break;
 		}
 
-		td->next_req = list_entry(td->test_queue.prev,
-				struct test_request, queuelist);
 		__blk_run_queue(q);
 		wait_event(mbtd->bkops_wait_q,
 			   mbtd->bkops_stage == BKOPS_STAGE_4);
@@ -1939,8 +1970,6 @@
 			break;
 		}
 
-		td->next_req = list_entry(td->test_queue.prev,
-				struct test_request, queuelist);
 		__blk_run_queue(q);
 		wait_event(mbtd->bkops_wait_q,
 			   mbtd->bkops_stage == BKOPS_STAGE_2);
@@ -1958,8 +1987,6 @@
 			break;
 		}
 
-		td->next_req = list_entry(td->test_queue.prev,
-				struct test_request, queuelist);
 		__blk_run_queue(q);
 
 		wait_event(mbtd->bkops_wait_q,
@@ -1999,8 +2026,6 @@
 			break;
 		}
 
-		td->next_req = list_entry(td->test_queue.next,
-				struct test_request, queuelist);
 		__blk_run_queue(q);
 		wait_event(mbtd->bkops_wait_q,
 			   mbtd->bkops_stage == BKOPS_STAGE_2);
@@ -2018,8 +2043,6 @@
 			break;
 		}
 
-		td->next_req = list_entry(td->test_queue.prev,
-				struct test_request, queuelist);
 		__blk_run_queue(q);
 
 		wait_event(mbtd->bkops_wait_q,
@@ -2037,6 +2060,153 @@
 	return ret;
 }
 
+/*
+ * new_req_post_test() - Do post test operations for
+ * new_req_notification test: disable the statistics and clear
+ * the feature flags.
+ * @td		The test_data for the new_req test that has
+ *		ended.
+ */
+static int new_req_post_test(struct test_data *td)
+{
+	struct mmc_queue *mq;
+
+	if (!td || !td->req_q)
+		goto exit;
+
+	mq = (struct mmc_queue *)td->req_q->queuedata;
+
+	if (!mq || !mq->card)
+		goto exit;
+
+	test_pr_info("Completed %d requests",
+			mbtd->completed_req_count);
+
+exit:
+	return 0;
+}
+
+/*
+ * check_new_req_result() - Print out the number of completed
+ * requests. Assigned to the check_test_result_fn pointer,
+ * therefore the name.
+ * @td		The test_data for the new_req test that has
+ *		ended.
+ */
+static int check_new_req_result(struct test_data *td)
+{
+	test_pr_info("%s: Test results: Completed %d requests",
+			__func__, mbtd->completed_req_count);
+	return 0;
+}
+
+/*
+ * new_req_free_end_io_fn() - Remove request from queuelist and
+ * free request's allocated memory. Used as a call-back
+ * assigned to end_io member in request struct.
+ * @rq		The request to be freed
+ * @err		Unused
+ */
+static void new_req_free_end_io_fn(struct request *rq, int err)
+{
+	struct test_request *test_rq =
+		(struct test_request *)rq->elv.priv[0];
+	struct test_data *ptd = test_get_test_data();
+
+	BUG_ON(!test_rq);
+
+	spin_lock_irq(&ptd->lock);
+	list_del_init(&test_rq->queuelist);
+	ptd->dispatched_count--;
+	spin_unlock_irq(&ptd->lock);
+
+	__blk_put_request(ptd->req_q, test_rq->rq);
+	kfree(test_rq->bios_buffer);
+	kfree(test_rq);
+	mbtd->completed_req_count++;
+}
+
+static int prepare_new_req(struct test_data *td)
+{
+	struct request_queue *q = td->req_q;
+	struct mmc_queue *mq = (struct mmc_queue *)q->queuedata;
+
+	mmc_blk_init_packed_statistics(mq->card);
+	mbtd->completed_req_count = 0;
+
+	return 0;
+}
+
+static int run_new_req(struct test_data *ptd)
+{
+	int ret = 0;
+	int i;
+	unsigned int requests_count = 2;
+	unsigned int bio_num;
+	struct test_request *test_rq = NULL;
+
+	while (1) {
+		for (i = 0; i < requests_count; i++) {
+			bio_num =  TEST_MAX_BIOS_PER_REQ;
+			test_rq = test_iosched_create_test_req(0, READ,
+					ptd->start_sector,
+					bio_num, TEST_PATTERN_5A,
+					new_req_free_end_io_fn);
+			if (test_rq) {
+				spin_lock_irq(ptd->req_q->queue_lock);
+				list_add_tail(&test_rq->queuelist,
+					      &ptd->test_queue);
+				ptd->test_count++;
+				spin_unlock_irq(ptd->req_q->queue_lock);
+			} else {
+				test_pr_err("%s: failed to create read request",
+					     __func__);
+				ret = -ENODEV;
+				break;
+			}
+		}
+
+		__blk_run_queue(ptd->req_q);
+		/* wait while a mmc layer will send all requests in test_queue*/
+		while (!list_empty(&ptd->test_queue))
+			msleep(NEW_REQ_TEST_SLEEP_TIME);
+
+		/* test finish criteria */
+		if (mbtd->completed_req_count > 1000) {
+			if (ptd->dispatched_count)
+				continue;
+			else
+				break;
+		}
+
+		for (i = 0; i < requests_count; i++) {
+			bio_num =  NEW_REQ_TEST_NUM_BIOS;
+			test_rq = test_iosched_create_test_req(0, READ,
+					ptd->start_sector,
+					bio_num, TEST_PATTERN_5A,
+					new_req_free_end_io_fn);
+			if (test_rq) {
+				spin_lock_irq(ptd->req_q->queue_lock);
+				list_add_tail(&test_rq->queuelist,
+					      &ptd->test_queue);
+				ptd->test_count++;
+				spin_unlock_irq(ptd->req_q->queue_lock);
+			} else {
+				test_pr_err("%s: failed to create read request",
+					     __func__);
+				ret = -ENODEV;
+				break;
+			}
+		}
+		__blk_run_queue(ptd->req_q);
+	}
+
+	test_iosched_mark_test_completion();
+	test_pr_info("%s: EXIT: %d code", __func__, ret);
+
+	return ret;
+}
+
 static bool message_repeat;
 static int test_open(struct inode *inode, struct file *file)
 {
@@ -2077,6 +2247,7 @@
 
 	mbtd->test_info.data = mbtd;
 	mbtd->test_info.prepare_test_fn = prepare_test;
+	mbtd->test_info.run_test_fn = run_packed_test;
 	mbtd->test_info.check_test_result_fn = check_wr_packing_statistics;
 	mbtd->test_info.get_test_case_str_fn = get_test_case_str;
 	mbtd->test_info.post_test_fn = post_test;
@@ -2175,6 +2346,7 @@
 
 	mbtd->test_info.data = mbtd;
 	mbtd->test_info.prepare_test_fn = prepare_test;
+	mbtd->test_info.run_test_fn = run_packed_test;
 	mbtd->test_info.check_test_result_fn = check_wr_packing_statistics;
 	mbtd->test_info.get_test_case_str_fn = get_test_case_str;
 	mbtd->test_info.post_test_fn = post_test;
@@ -2274,6 +2446,7 @@
 
 	mbtd->test_info.data = mbtd;
 	mbtd->test_info.prepare_test_fn = prepare_test;
+	mbtd->test_info.run_test_fn = run_packed_test;
 	mbtd->test_info.check_test_result_fn = check_wr_packing_statistics;
 	mbtd->test_info.get_test_case_str_fn = get_test_case_str;
 	mbtd->test_info.post_test_fn = post_test;
@@ -2386,6 +2559,7 @@
 
 	mbtd->test_info.data = mbtd;
 	mbtd->test_info.prepare_test_fn = prepare_test;
+	mbtd->test_info.run_test_fn = run_packed_test;
 	mbtd->test_info.check_test_result_fn = check_wr_packing_statistics;
 	mbtd->test_info.get_test_case_str_fn = get_test_case_str;
 
@@ -2587,7 +2761,7 @@
 	int ret = 0;
 	int i = 0;
 	int number = -1;
-	unsigned int mtime, integer, fraction;
+	unsigned long mtime, integer, fraction;
 
 	test_pr_info("%s: -- Long Sequential Read TEST --", __func__);
 
@@ -2615,21 +2789,22 @@
 
 		mtime = jiffies_to_msecs(mbtd->test_info.test_duration);
 
-		test_pr_info("%s: time is %u msec, size is %u.%u MiB",
-			__func__, mtime, LONG_TEST_SIZE_INTEGER,
-			      LONG_TEST_SIZE_FRACTION);
+		test_pr_info("%s: time is %lu msec, size is %u.%u MiB",
+			__func__, mtime,
+			LONG_TEST_SIZE_INTEGER(LONG_READ_NUM_BYTES),
+			LONG_TEST_SIZE_FRACTION(LONG_READ_NUM_BYTES));
 
 		/* we first multiply in order not to lose precision */
 		mtime *= MB_MSEC_RATIO_APPROXIMATION;
 		/* divide values to get a MiB/sec integer value with one
 		   digit of precision. Multiply by 10 for one digit precision
 		 */
-		fraction = integer = (LONG_TEST_ACTUAL_BYTE_NUM * 10) / mtime;
+		fraction = integer = (LONG_READ_NUM_BYTES * 10) / mtime;
 		integer /= 10;
 		/* and calculate the MiB value fraction */
 		fraction -= integer * 10;
 
-		test_pr_info("%s: Throughput: %u.%u MiB/sec\n"
+		test_pr_info("%s: Throughput: %lu.%lu MiB/sec\n"
 			, __func__, integer, fraction);
 
 		/* Allow FS requests to be dispatched */
@@ -2668,6 +2843,72 @@
 	.read = long_sequential_read_test_read,
 };
 
+static void long_seq_write_free_end_io_fn(struct request *rq, int err)
+{
+	struct test_request *test_rq =
+		(struct test_request *)rq->elv.priv[0];
+	struct test_data *ptd = test_get_test_data();
+
+	BUG_ON(!test_rq);
+
+	spin_lock_irq(&ptd->lock);
+	list_del_init(&test_rq->queuelist);
+	ptd->dispatched_count--;
+	__blk_put_request(ptd->req_q, test_rq->rq);
+	spin_unlock_irq(&ptd->lock);
+
+	kfree(test_rq->bios_buffer);
+	kfree(test_rq);
+	mbtd->completed_req_count++;
+
+	check_test_completion();
+}
+
+static int run_long_seq_write(struct test_data *td)
+{
+	int ret = 0;
+	int i;
+
+	td->test_count = 0;
+	mbtd->completed_req_count = 0;
+
+	test_pr_info("%s: Adding at least %d write requests, first req_id=%d",
+		     __func__, LONG_WRITE_TEST_MIN_NUM_REQS,
+		     td->wr_rd_next_req_id);
+
+	do {
+		for (i = 0; i < TEST_MAX_REQUESTS; i++) {
+			/*
+			 * since our requests come from a pool containing 128
+			 * requests, we don't want to exhaust this quantity,
+			 * therefore we add up to TEST_MAX_REQUESTS (which
+			 * includes a safety margin) and then call the mmc layer
+			 * to fetch them
+			 */
+			if (td->test_count > TEST_MAX_REQUESTS)
+				break;
+
+			ret = test_iosched_add_wr_rd_test_req(0, WRITE,
+				  td->start_sector, TEST_MAX_BIOS_PER_REQ,
+				  TEST_PATTERN_5A,
+				  long_seq_write_free_end_io_fn);
+			 if (ret) {
+				test_pr_err("%s: failed to create write request"
+					    , __func__);
+				break;
+			}
+		}
+
+		__blk_run_queue(td->req_q);
+
+	} while (mbtd->completed_req_count < LONG_WRITE_TEST_MIN_NUM_REQS);
+
+	test_pr_info("%s: completed %d requests", __func__,
+		     mbtd->completed_req_count);
+
+	return ret;
+}
+
 static ssize_t long_sequential_write_test_write(struct file *file,
 				const char __user *buf,
 				size_t count,
@@ -2676,7 +2917,7 @@
 	int ret = 0;
 	int i = 0;
 	int number = -1;
-	unsigned int mtime, integer, fraction;
+	unsigned long mtime, integer, fraction, byte_count;
 
 	test_pr_info("%s: -- Long Sequential Write TEST --", __func__);
 
@@ -2689,13 +2930,16 @@
 	mbtd->test_group = TEST_GENERAL_GROUP;
 
 	mbtd->test_info.data = mbtd;
-	mbtd->test_info.prepare_test_fn = prepare_test;
 	mbtd->test_info.get_test_case_str_fn = get_test_case_str;
+	mbtd->test_info.run_test_fn = run_long_seq_write;
 
 	for (i = 0 ; i < number ; ++i) {
 		test_pr_info("%s: Cycle # %d / %d", __func__, i+1, number);
 		test_pr_info("%s: ====================", __func__);
 
+		integer = 0;
+		fraction = 0;
+		mbtd->test_info.test_byte_count = 0;
 		mbtd->test_info.testcase = TEST_LONG_SEQUENTIAL_WRITE;
 		mbtd->is_random = NON_RANDOM_TEST;
 		ret = test_iosched_start_test(&mbtd->test_info);
@@ -2703,22 +2947,23 @@
 			break;
 
 		mtime = jiffies_to_msecs(mbtd->test_info.test_duration);
+		byte_count = mbtd->test_info.test_byte_count;
 
-		test_pr_info("%s: time is %u msec, size is %u.%u MiB",
-			__func__, mtime, LONG_TEST_SIZE_INTEGER,
-			      LONG_TEST_SIZE_FRACTION);
+		test_pr_info("%s: time is %lu msec, size is %lu.%lu MiB",
+			__func__, mtime, LONG_TEST_SIZE_INTEGER(byte_count),
+			      LONG_TEST_SIZE_FRACTION(byte_count));
 
 		/* we first multiply in order not to lose precision */
 		mtime *= MB_MSEC_RATIO_APPROXIMATION;
 		/* divide values to get a MiB/sec integer value with one
 		   digit of precision
 		 */
-		fraction = integer = (LONG_TEST_ACTUAL_BYTE_NUM * 10) / mtime;
+		fraction = integer = (byte_count * 10) / mtime;
 		integer /= 10;
 		/* and calculate the MiB value fraction */
 		fraction -= integer * 10;
 
-		test_pr_info("%s: Throughput: %u.%u MiB/sec\n",
+		test_pr_info("%s: Throughput: %lu.%lu MiB/sec\n",
 			__func__, integer, fraction);
 
 		/* Allow FS requests to be dispatched */
@@ -2757,6 +3002,73 @@
 	.read = long_sequential_write_test_read,
 };
 
+static ssize_t new_req_notification_test_write(struct file *file,
+				const char __user *buf,
+				size_t count,
+				loff_t *ppos)
+{
+	int ret = 0;
+	int i = 0;
+	int number = -1;
+
+	test_pr_info("%s: -- new_req_notification TEST --", __func__);
+
+	sscanf(buf, "%d", &number);
+
+	if (number <= 0)
+		number = 1;
+
+	mbtd->test_group = TEST_NEW_NOTIFICATION_GROUP;
+
+	memset(&mbtd->test_info, 0, sizeof(struct test_info));
+
+	mbtd->test_info.data = mbtd;
+	mbtd->test_info.prepare_test_fn = prepare_new_req;
+	mbtd->test_info.check_test_result_fn = check_new_req_result;
+	mbtd->test_info.get_test_case_str_fn = get_test_case_str;
+	mbtd->test_info.run_test_fn = run_new_req;
+	mbtd->test_info.timeout_msec = 10 * 60 * 1000; /* 1 min */
+	mbtd->test_info.post_test_fn = new_req_post_test;
+
+	for (i = 0 ; i < number ; ++i) {
+		test_pr_info("%s: Cycle # %d / %d", __func__, i+1, number);
+		test_pr_info("%s: ===================", __func__);
+		test_pr_info("%s: start test case TEST_NEW_REQ_NOTIFICATION",
+			      __func__);
+		mbtd->test_info.testcase = TEST_NEW_REQ_NOTIFICATION;
+		ret = test_iosched_start_test(&mbtd->test_info);
+		if (ret) {
+			test_pr_info("%s: break from new_req tests loop",
+				      __func__);
+			break;
+		}
+	}
+	return count;
+}
+
+static ssize_t new_req_notification_test_read(struct file *file,
+			       char __user *buffer,
+			       size_t count,
+			       loff_t *offset)
+{
+	memset((void *)buffer, 0, count);
+
+	snprintf(buffer, count,
+		 "\nnew_req_notification_test\n========================\n"
+		 "Description:\n"
+		 "This test checks following scenarious\n"
+		 "- new request arrives after a NULL request was sent to the "
+		 "mmc_queue,\n"
+		 "which is waiting for completion of a former request\n");
+
+	return strnlen(buffer, count);
+}
+
+const struct file_operations new_req_notification_test_ops = {
+	.open = test_open,
+	.write = new_req_notification_test_write,
+	.read = new_req_notification_test_read,
+};
 
 static void mmc_block_test_debugfs_cleanup(void)
 {
@@ -2769,6 +3081,7 @@
 	debugfs_remove(mbtd->debug.bkops_test);
 	debugfs_remove(mbtd->debug.long_sequential_read_test);
 	debugfs_remove(mbtd->debug.long_sequential_write_test);
+	debugfs_remove(mbtd->debug.new_req_notification_test);
 }
 
 static int mmc_block_test_debugfs_init(void)
@@ -2848,6 +3161,16 @@
 				    NULL,
 				    &bkops_test_ops);
 
+	mbtd->debug.new_req_notification_test =
+		debugfs_create_file("new_req_notification_test",
+				    S_IRUGO | S_IWUGO,
+				    tests_root,
+				    NULL,
+				    &new_req_notification_test_ops);
+
+	if (!mbtd->debug.new_req_notification_test)
+		goto err_nomem;
+
 	if (!mbtd->debug.bkops_test)
 		goto err_nomem;
 
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index 8eb787d..64ece67 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -22,7 +22,6 @@
 
 #define MMC_QUEUE_BOUNCESZ	65536
 
-#define MMC_QUEUE_SUSPENDED	(1 << 0)
 
 /*
  * Based on benchmark tests the default num of requests to trigger the write
@@ -75,19 +74,24 @@
 		spin_unlock_irq(q->queue_lock);
 
 		if (req || mq->mqrq_prev->req) {
-			/*
-			 * If this is the first request, BKOPs might be in
-			 * progress and needs to be stopped before issuing the
-			 * request
-			 */
-			if (card->ext_csd.bkops_en &&
-			    card->bkops_info.started_delayed_bkops) {
-				card->bkops_info.started_delayed_bkops = false;
-				mmc_stop_bkops(card);
-			}
-
 			set_current_state(TASK_RUNNING);
 			mq->issue_fn(mq, req);
+			if (mq->flags & MMC_QUEUE_NEW_REQUEST) {
+				continue; /* fetch again */
+			} else if (mq->flags & MMC_QUEUE_URGENT_REQUEST) {
+				mq->mqrq_cur->brq.mrq.data = NULL;
+				mq->mqrq_cur->req = NULL;
+			}
+
+			/*
+			 * Current request becomes previous request
+			 * and vice versa.
+			 */
+			mq->mqrq_prev->brq.mrq.data = NULL;
+			mq->mqrq_prev->req = NULL;
+			tmp = mq->mqrq_prev;
+			mq->mqrq_prev = mq->mqrq_cur;
+			mq->mqrq_cur = tmp;
 		} else {
 			if (kthread_should_stop()) {
 				set_current_state(TASK_RUNNING);
@@ -98,13 +102,6 @@
 			schedule();
 			down(&mq->thread_sem);
 		}
-
-		/* Current request becomes previous request and vice versa. */
-		mq->mqrq_prev->brq.mrq.data = NULL;
-		mq->mqrq_prev->req = NULL;
-		tmp = mq->mqrq_prev;
-		mq->mqrq_prev = mq->mqrq_cur;
-		mq->mqrq_cur = tmp;
 	} while (1);
 	up(&mq->thread_sem);
 
@@ -121,6 +118,8 @@
 {
 	struct mmc_queue *mq = q->queuedata;
 	struct request *req;
+	unsigned long flags;
+	struct mmc_context_info *cntx;
 
 	if (!mq) {
 		while ((req = blk_fetch_request(q)) != NULL) {
@@ -130,10 +129,64 @@
 		return;
 	}
 
-	if (!mq->mqrq_cur->req && !mq->mqrq_prev->req)
+	cntx = &mq->card->host->context_info;
+	if (!mq->mqrq_cur->req && mq->mqrq_prev->req) {
+		/*
+		 * New MMC request arrived when MMC thread may be
+		 * blocked on the previous request to be complete
+		 * with no current request fetched
+		 */
+		spin_lock_irqsave(&cntx->lock, flags);
+		if (cntx->is_waiting_last_req) {
+			cntx->is_new_req = true;
+			wake_up_interruptible(&cntx->wait);
+		}
+		spin_unlock_irqrestore(&cntx->lock, flags);
+	} else if (!mq->mqrq_cur->req && !mq->mqrq_prev->req)
 		wake_up_process(mq->thread);
 }
 
+/*
+ * mmc_urgent_request() - Urgent MMC request handler.
+ * @q: request queue.
+ *
+ * This is called when block layer has urgent request for delivery.  When mmc
+ * context is waiting for the current request to complete, it will be awaken,
+ * current request may be interrupted and re-inserted back to block device
+ * request queue.  The next fetched request should be urgent request, this
+ * will be ensured by block i/o scheduler.
+ */
+static void mmc_urgent_request(struct request_queue *q)
+{
+	unsigned long flags;
+	struct mmc_queue *mq = q->queuedata;
+	struct mmc_context_info *cntx;
+
+	if (!mq) {
+		mmc_request(q);
+		return;
+	}
+	cntx = &mq->card->host->context_info;
+
+	/* critical section with mmc_wait_data_done() */
+	spin_lock_irqsave(&cntx->lock, flags);
+
+	/* do stop flow only when mmc thread is waiting for done */
+	if (cntx->is_waiting) {
+		/*
+		 * Urgent request must be executed alone
+		 * so disable the write packing
+		 */
+		mmc_blk_disable_wr_packing(mq);
+		cntx->is_urgent = true;
+		spin_unlock_irqrestore(&cntx->lock, flags);
+		wake_up_interruptible(&cntx->wait);
+	} else {
+		spin_unlock_irqrestore(&cntx->lock, flags);
+		mmc_request(q);
+	}
+}
+
 static struct scatterlist *mmc_alloc_sg(int sg_len, int *err)
 {
 	struct scatterlist *sg;
@@ -201,6 +254,11 @@
 	if (!mq->queue)
 		return -ENOMEM;
 
+	if ((host->caps2 & MMC_CAP2_STOP_REQUEST) &&
+			host->ops->stop_request &&
+			mq->card->ext_csd.hpi)
+		blk_urgent_request(mq->queue, mmc_urgent_request);
+
 	memset(&mq->mqrq_cur, 0, sizeof(mq->mqrq_cur));
 	memset(&mq->mqrq_prev, 0, sizeof(mq->mqrq_prev));
 
diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h
index a8c104e..99c3c60 100644
--- a/drivers/mmc/card/queue.h
+++ b/drivers/mmc/card/queue.h
@@ -12,17 +12,6 @@
 	struct mmc_data		data;
 };
 
-enum mmc_blk_status {
-	MMC_BLK_SUCCESS = 0,
-	MMC_BLK_PARTIAL,
-	MMC_BLK_CMD_ERR,
-	MMC_BLK_RETRY,
-	MMC_BLK_ABORT,
-	MMC_BLK_DATA_ERR,
-	MMC_BLK_ECC_ERR,
-	MMC_BLK_NOMEDIUM,
-};
-
 enum mmc_packed_cmd {
 	MMC_PACKED_NONE = 0,
 	MMC_PACKED_WRITE,
@@ -50,6 +39,10 @@
 	struct task_struct	*thread;
 	struct semaphore	thread_sem;
 	unsigned int		flags;
+#define MMC_QUEUE_SUSPENDED		(1 << 0)
+#define MMC_QUEUE_NEW_REQUEST		(1 << 1)
+#define MMC_QUEUE_URGENT_REQUEST	(1 << 2)
+
 	int			(*issue_fn)(struct mmc_queue *, struct request *);
 	void			*data;
 	struct request_queue	*queue;
@@ -59,6 +52,7 @@
 	bool			wr_packing_enabled;
 	int			num_of_potential_packed_wr_reqs;
 	int			num_wr_reqs_to_start_packing;
+	bool			no_pack_for_random;
 	int (*err_check_fn) (struct mmc_card *, struct mmc_async_req *);
 	void (*packed_test_fn) (struct request_queue *, struct mmc_queue_req *);
 };
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index b24620b..2f27407 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -328,6 +328,7 @@
 #ifdef CONFIG_DEBUG_FS
 	mmc_add_card_debugfs(card);
 #endif
+	mmc_init_context_info(card->host);
 
 	ret = device_add(&card->dev);
 	if (ret)
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 89f834a..be4315e 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -47,11 +47,14 @@
 
 static void mmc_clk_scaling(struct mmc_host *host, bool from_wq);
 
+/* If the device is not responding */
+#define MMC_CORE_TIMEOUT_MS	(10 * 60 * 1000) /* 10 minute timeout */
+
 /*
  * Background operations can take a long time, depending on the housekeeping
  * operations the card has to perform.
  */
-#define MMC_BKOPS_MAX_TIMEOUT	(4 * 60 * 1000) /* max time to wait in ms */
+#define MMC_BKOPS_MAX_TIMEOUT	(30 * 1000) /* max time to wait in ms */
 
 static struct workqueue_struct *workqueue;
 
@@ -159,6 +162,13 @@
 
 #endif /* CONFIG_FAIL_MMC_REQUEST */
 
+static inline void mmc_update_clk_scaling(struct mmc_host *host)
+{
+	if (host->clk_scaling.enable)
+		host->clk_scaling.busy_time_us +=
+			ktime_to_us(ktime_sub(ktime_get(),
+					host->clk_scaling.start_busy));
+}
 /**
  *	mmc_request_done - finish processing an MMC request
  *	@host: MMC host which completed request
@@ -174,10 +184,8 @@
 #ifdef CONFIG_MMC_PERF_PROFILING
 	ktime_t diff;
 #endif
-	if (host->card && host->clk_scaling.enable)
-		host->clk_scaling.busy_time_us +=
-			ktime_to_us(ktime_sub(ktime_get(),
-					host->clk_scaling.start_busy));
+	if (host->card)
+		mmc_update_clk_scaling(host);
 
 	if (err && cmd->retries && mmc_host_is_spi(host)) {
 		if (cmd->resp[0] & R1_SPI_ILLEGAL_COMMAND)
@@ -364,15 +372,12 @@
 	pr_debug("%s: %s: queueing delayed_bkops_work\n",
 		 mmc_hostname(card->host), __func__);
 
-	card->bkops_info.sectors_changed = 0;
-
 	/*
 	 * cancel_delayed_bkops_work will prevent a race condition between
 	 * fetching a request by the mmcqd and the delayed work, in case
 	 * it was removed from the queue work but not started yet
 	 */
 	card->bkops_info.cancel_delayed_work = false;
-	card->bkops_info.started_delayed_bkops = true;
 	queue_delayed_work(system_nrt_wq, &card->bkops_info.dw,
 			   msecs_to_jiffies(
 				   card->bkops_info.delay_ms));
@@ -392,15 +397,26 @@
 void mmc_start_bkops(struct mmc_card *card, bool from_exception)
 {
 	int err;
-	int timeout;
-	bool use_busy_signal;
 
 	BUG_ON(!card);
 	if (!card->ext_csd.bkops_en)
 		return;
 
-	mmc_claim_host(card->host);
+	if ((card->bkops_info.cancel_delayed_work) && !from_exception) {
+		pr_debug("%s: %s: cancel_delayed_work was set, exit\n",
+			 mmc_hostname(card->host), __func__);
+		card->bkops_info.cancel_delayed_work = false;
+		return;
+	}
 
+	/* In case of delayed bkops we might be in race with suspend. */
+	if (!mmc_try_claim_host(card->host))
+		return;
+
+	/*
+	 * Since the cancel_delayed_work can be changed while we are waiting
+	 * for the lock we will to re-check it
+	 */
 	if ((card->bkops_info.cancel_delayed_work) && !from_exception) {
 		pr_debug("%s: %s: cancel_delayed_work was set, exit\n",
 			 mmc_hostname(card->host), __func__);
@@ -414,42 +430,45 @@
 		goto out;
 	}
 
-	err = mmc_read_bkops_status(card);
-	if (err) {
-		pr_err("%s: %s: Failed to read bkops status: %d\n",
-		       mmc_hostname(card->host), __func__, err);
+	if (from_exception && mmc_card_need_bkops(card))
 		goto out;
-	}
-
-	if (!card->ext_csd.raw_bkops_status)
-		goto out;
-
-	pr_info("%s: %s: card->ext_csd.raw_bkops_status = 0x%x\n",
-		mmc_hostname(card->host), __func__,
-		card->ext_csd.raw_bkops_status);
 
 	/*
-	 * If the function was called due to exception but there is no need
-	 * for urgent BKOPS, BKOPs will be performed by the delayed BKOPs
-	 * work, before going to suspend
+	 * If the need BKOPS flag is set, there is no need to check if BKOPS
+	 * is needed since we already know that it does
 	 */
-	if (card->ext_csd.raw_bkops_status < EXT_CSD_BKOPS_LEVEL_2 &&
-	    from_exception) {
-		pr_debug("%s: %s: Level 1 from exception, exit",
-			 mmc_hostname(card->host), __func__);
+	if (!mmc_card_need_bkops(card)) {
+		err = mmc_read_bkops_status(card);
+		if (err) {
+			pr_err("%s: %s: Failed to read bkops status: %d\n",
+			       mmc_hostname(card->host), __func__, err);
+			goto out;
+		}
+
+		if (!card->ext_csd.raw_bkops_status)
+			goto out;
+
+		pr_info("%s: %s: raw_bkops_status=0x%x, from_exception=%d\n",
+			mmc_hostname(card->host), __func__,
+			card->ext_csd.raw_bkops_status,
+			from_exception);
+	}
+
+	/*
+	 * If the function was called due to exception, BKOPS will be performed
+	 * after handling the last pending request
+	 */
+	if (from_exception) {
+		pr_debug("%s: %s: Level %d from exception, exit",
+			 mmc_hostname(card->host), __func__,
+			 card->ext_csd.raw_bkops_status);
+		mmc_card_set_need_bkops(card);
 		goto out;
 	}
-
-	if (card->ext_csd.raw_bkops_status >= EXT_CSD_BKOPS_LEVEL_2) {
-		timeout = MMC_BKOPS_MAX_TIMEOUT;
-		use_busy_signal = true;
-	} else {
-		timeout = 0;
-		use_busy_signal = false;
-	}
+	pr_info("%s: %s: Starting bkops\n", mmc_hostname(card->host), __func__);
 
 	err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-			EXT_CSD_BKOPS_START, 1, timeout, use_busy_signal);
+			EXT_CSD_BKOPS_START, 1, 0, false, false);
 	if (err) {
 		pr_warn("%s: %s: Error %d when starting bkops\n",
 			mmc_hostname(card->host), __func__, err);
@@ -457,19 +476,13 @@
 	}
 	MMC_UPDATE_STATS_BKOPS_SEVERITY_LEVEL(card->bkops_info.bkops_stats,
 					card->ext_csd.raw_bkops_status);
+	mmc_card_clr_need_bkops(card);
 
-	/*
-	 * For urgent bkops status (LEVEL_2 and more)
-	 * bkops executed synchronously, otherwise
-	 * the operation is in progress
-	 */
-	if (!use_busy_signal) {
-		mmc_card_set_doing_bkops(card);
-		pr_debug("%s: %s: starting the polling thread\n",
-			 mmc_hostname(card->host), __func__);
-		queue_work(system_nrt_wq,
-			   &card->bkops_info.poll_for_completion);
-	}
+	mmc_card_set_doing_bkops(card);
+	pr_debug("%s: %s: starting the polling thread\n",
+		 mmc_hostname(card->host), __func__);
+	queue_work(system_nrt_wq,
+		   &card->bkops_info.poll_for_completion);
 
 out:
 	mmc_release_host(card->host);
@@ -523,7 +536,7 @@
 			pr_debug("%s: %s: completed BKOPs, exit polling\n",
 				 mmc_hostname(card->host), __func__);
 			mmc_card_clr_doing_bkops(card);
-			card->bkops_info.started_delayed_bkops = false;
+			card->bkops_info.sectors_changed = 0;
 			goto out;
 		}
 
@@ -536,8 +549,12 @@
 		msleep(BKOPS_COMPLETION_POLLING_INTERVAL_MS);
 	} while (time_before(jiffies, timeout_jiffies));
 
-	pr_err("%s: %s: exit polling due to timeout\n",
+	pr_err("%s: %s: exit polling due to timeout, stop bkops\n",
 	       mmc_hostname(card->host), __func__);
+	err = mmc_stop_bkops(card);
+	if (err)
+		pr_err("%s: %s: mmc_stop_bkops failed, err=%d\n",
+			       mmc_hostname(card->host), __func__, err);
 
 	return;
 out:
@@ -565,11 +582,45 @@
 }
 EXPORT_SYMBOL(mmc_start_idle_time_bkops);
 
+/*
+ * mmc_wait_data_done() - done callback for data request
+ * @mrq: done data request
+ *
+ * Wakes up mmc context, passed as a callback to host controller driver
+ */
+static void mmc_wait_data_done(struct mmc_request *mrq)
+{
+	mrq->host->context_info.is_done_rcv = true;
+	wake_up_interruptible(&mrq->host->context_info.wait);
+}
+
 static void mmc_wait_done(struct mmc_request *mrq)
 {
 	complete(&mrq->completion);
 }
 
+/*
+ *__mmc_start_data_req() - starts data request
+ * @host: MMC host to start the request
+ * @mrq: data request to start
+ *
+ * Sets the done callback to be called when request is completed by the card.
+ * Starts data mmc request execution
+ */
+static int __mmc_start_data_req(struct mmc_host *host, struct mmc_request *mrq)
+{
+	mrq->done = mmc_wait_data_done;
+	mrq->host = host;
+	if (mmc_card_removed(host->card)) {
+		mrq->cmd->error = -ENOMEDIUM;
+		mmc_wait_data_done(mrq);
+		return -ENOMEDIUM;
+	}
+	mmc_start_request(host, mrq);
+
+	return 0;
+}
+
 static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
 {
 	init_completion(&mrq->completion);
@@ -583,6 +634,202 @@
 	return 0;
 }
 
+/*
+ * mmc_should_stop_curr_req() - check for stop flow rationality
+ * @host: MMC host running request.
+ *
+ * Check possibility to interrupt current running request
+ * Returns true in case it is worth to stop transfer,
+ *          false otherwise
+ */
+static bool mmc_should_stop_curr_req(struct mmc_host *host)
+{
+	int remainder;
+
+	remainder = (host->ops->get_xfer_remain) ?
+		host->ops->get_xfer_remain(host) : -1;
+	return (remainder > 0);
+}
+
+/*
+ * mmc_stop_request() - Stops current running request
+ * @host: MMC host to prepare the command.
+ *
+ * Triggers stop flow in the host driver and sends CMD12 (stop command) to the
+ * card. Sends HPI to get the card out of R1_STATE_PRG immediately
+ *
+ * Returns 0 when success, error propagated otherwise
+ */
+static int mmc_stop_request(struct mmc_host *host)
+{
+	struct mmc_command cmd = {0};
+	struct mmc_card *card = host->card;
+	int err = 0;
+	u32 status;
+
+	if (!host->ops->stop_request || !card->ext_csd.hpi) {
+		pr_warn("%s: host ops stop_request() or HPI not supported\n",
+				mmc_hostname(host));
+		return -ENOTSUPP;
+	}
+	err = host->ops->stop_request(host);
+	if (err) {
+		pr_err("%s: Call to host->ops->stop_request() failed (%d)\n",
+				mmc_hostname(host), err);
+		goto out;
+	}
+
+	cmd.opcode = MMC_STOP_TRANSMISSION;
+	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
+	err = mmc_wait_for_cmd(host, &cmd, 0);
+	if (err) {
+		err = mmc_send_status(card, &status);
+		if (err) {
+			pr_err("%s: Get card status fail\n",
+					mmc_hostname(card->host));
+			goto out;
+		}
+		switch (R1_CURRENT_STATE(status)) {
+		case R1_STATE_DATA:
+		case R1_STATE_RCV:
+			pr_err("%s: CMD12 fails with error (%d)\n",
+					mmc_hostname(host), err);
+			goto out;
+		default:
+			break;
+		}
+	}
+	err = mmc_interrupt_hpi(card);
+	if (err) {
+		pr_err("%s: mmc_interrupt_hpi() failed (%d)\n",
+				mmc_hostname(host), err);
+		goto out;
+	}
+out:
+	return err;
+}
+
+/*
+ * mmc_wait_for_data_req_done() - wait for request completed
+ * @host: MMC host to prepare the command.
+ * @mrq: MMC request to wait for
+ *
+ * Blocks MMC context till host controller will ack end of data request
+ * execution or new request notification arrives from the block layer.
+ * Handles command retries.
+ *
+ * Returns enum mmc_blk_status after checking errors.
+ */
+static int mmc_wait_for_data_req_done(struct mmc_host *host,
+				      struct mmc_request *mrq,
+				      struct mmc_async_req *next_req)
+{
+	struct mmc_command *cmd;
+	struct mmc_context_info *context_info = &host->context_info;
+	bool pending_is_urgent = false;
+	bool is_urgent = false;
+	int err;
+	unsigned long flags;
+
+	while (1) {
+		context_info->is_waiting = true;
+		wait_io_event_interruptible(context_info->wait,
+				(context_info->is_done_rcv ||
+				 context_info->is_new_req  ||
+				 context_info->is_urgent));
+		spin_lock_irqsave(&context_info->lock, flags);
+		is_urgent = context_info->is_urgent;
+		context_info->is_waiting = false;
+		context_info->is_waiting_last_req = false;
+		spin_unlock_irqrestore(&context_info->lock, flags);
+		if (context_info->is_done_rcv) {
+			context_info->is_done_rcv = false;
+			context_info->is_new_req = false;
+			cmd = mrq->cmd;
+			if (!cmd->error || !cmd->retries ||
+					mmc_card_removed(host->card)) {
+				err = host->areq->err_check(host->card,
+						host->areq);
+				if (pending_is_urgent || is_urgent) {
+					/*
+					 * all the success/partial operations
+					 * are done in an addition to handling
+					 * the urgent request
+					 */
+					if ((err == MMC_BLK_PARTIAL) ||
+						(err == MMC_BLK_SUCCESS))
+						err = MMC_BLK_URGENT;
+					/* reset is_urgent for next request */
+					context_info->is_urgent = false;
+				}
+				break; /* return err */
+			} else {
+				pr_info("%s: req failed (CMD%u): %d, retrying...\n",
+						mmc_hostname(host),
+						cmd->opcode, cmd->error);
+				cmd->retries--;
+				cmd->error = 0;
+				host->ops->request(host, mrq);
+				/*
+				 * ignore urgent flow, request retry has greater
+				 * priority than urgent flow
+				 */
+				context_info->is_urgent = false;
+				/* wait for done/new/urgent event again */
+				continue;
+			}
+		} else if (context_info->is_new_req && !is_urgent) {
+			context_info->is_new_req = false;
+			if (!next_req) {
+				err = MMC_BLK_NEW_REQUEST;
+				break; /* return err */
+			}
+		} else {
+			/*
+			 * The case when block layer sent next urgent
+			 * notification before it receives end_io on
+			 * the current
+			 */
+			BUG_ON(pending_is_urgent == true);
+
+			context_info->is_urgent = false;
+			context_info->is_new_req = false;
+			if (mmc_should_stop_curr_req(host)) {
+				err = mmc_stop_request(host);
+				if (err && !context_info->is_done_rcv) {
+					err = MMC_BLK_ABORT;
+					break;
+				}
+				/* running request has finished at this point */
+				if (context_info->is_done_rcv) {
+					err = host->areq->err_check(host->card,
+							host->areq);
+					context_info->is_done_rcv = false;
+					break; /* return err */
+				} else {
+					mmc_update_clk_scaling(host);
+				}
+				err = host->areq->update_interrupted_req(
+						host->card, host->areq);
+				if (!err)
+					err = MMC_BLK_URGENT;
+				break; /* return err */
+			} else {
+				/*
+				 *  The flow will back to wait for is_done_rcv,
+				 *  but in this case original is_urgent cleared.
+				 *  Mark pending_is_urgent to differentiate the
+				 *  case, when is_done_rcv and is_urgent really
+				 *  concurrent.
+				 */
+				pending_is_urgent = true;
+				continue; /* wait for done/new/urgent event */
+			}
+		}
+	} /* while */
+	return err;
+}
+
 static void mmc_wait_for_req_done(struct mmc_host *host,
 				  struct mmc_request *mrq)
 {
@@ -592,6 +839,24 @@
 		wait_for_completion_io(&mrq->completion);
 
 		cmd = mrq->cmd;
+
+		/*
+		 * If host has timed out waiting for the blocking BKOPs
+		 * to complete, card might be still in programming state
+		 * so let's try to bring the card out of programming state.
+		 */
+		if (cmd->bkops_busy && cmd->error == -ETIMEDOUT) {
+			if (!mmc_interrupt_hpi(host->card)) {
+				pr_warning("%s: %s: Interrupted blocking bkops\n",
+					   mmc_hostname(host), __func__);
+				cmd->error = 0;
+				break;
+			} else {
+				pr_err("%s: %s: Failed to interrupt blocking bkops\n",
+				       mmc_hostname(host), __func__);
+			}
+		}
+
 		if (!cmd->error || !cmd->retries ||
 		    mmc_card_removed(host->card))
 			break;
@@ -668,12 +933,35 @@
 	struct mmc_async_req *data = host->areq;
 
 	/* Prepare a new request */
-	if (areq)
+	if (areq) {
+		/*
+		 * start waiting here for possible interrupt
+		 * because mmc_pre_req() taking long time
+		 */
+		host->context_info.is_waiting = true;
 		mmc_pre_req(host, areq->mrq, !host->areq);
+	}
 
 	if (host->areq) {
-		mmc_wait_for_req_done(host, host->areq->mrq);
-		err = host->areq->err_check(host->card, host->areq);
+		err = mmc_wait_for_data_req_done(host, host->areq->mrq,
+				areq);
+		if (err == MMC_BLK_URGENT) {
+			mmc_post_req(host, host->areq->mrq, 0);
+			if (areq) { /* reinsert ready request */
+				areq->reinsert_req(areq);
+				mmc_post_req(host, areq->mrq, 0);
+			}
+			host->areq = NULL;
+			goto exit;
+		} else if (err == MMC_BLK_NEW_REQUEST) {
+			if (error)
+				*error = err;
+			/*
+			 * The previous request was not completed,
+			 * nothing to return
+			 */
+			return NULL;
+		}
 		/*
 		 * Check BKOPS urgency for each R1 response
 		 */
@@ -688,7 +976,7 @@
 	}
 
 	if (!err && areq)
-		start_err = __mmc_start_req(host, areq->mrq);
+		start_err = __mmc_start_data_req(host, areq->mrq);
 
 	if (host->areq)
 		mmc_post_req(host, host->areq->mrq, 0);
@@ -702,6 +990,7 @@
 	else
 		host->areq = areq;
 
+exit:
 	if (error)
 		*error = err;
 	return data;
@@ -735,6 +1024,7 @@
 {
 	int err;
 	u32 status;
+	unsigned long prg_wait;
 
 	BUG_ON(!card);
 
@@ -750,30 +1040,39 @@
 		goto out;
 	}
 
-	/*
-	 * If the card status is in PRG-state, we can send the HPI command.
-	 */
-	if (R1_CURRENT_STATE(status) == R1_STATE_PRG) {
-		do {
-			/*
-			 * We don't know when the HPI command will finish
-			 * processing, so we need to resend HPI until out
-			 * of prg-state, and keep checking the card status
-			 * with SEND_STATUS.  If a timeout error occurs when
-			 * sending the HPI command, we are already out of
-			 * prg-state.
-			 */
-			err = mmc_send_hpi_cmd(card, &status);
-			if (err)
-				pr_debug("%s: abort HPI (%d error)\n",
-					 mmc_hostname(card->host), err);
+	switch (R1_CURRENT_STATE(status)) {
+	case R1_STATE_IDLE:
+	case R1_STATE_READY:
+	case R1_STATE_STBY:
+	case R1_STATE_TRAN:
+		/*
+		 * In idle and transfer states, HPI is not needed and the caller
+		 * can issue the next intended command immediately
+		 */
+		goto out;
+	case R1_STATE_PRG:
+		break;
+	default:
+		/* In all other states, it's illegal to issue HPI */
+		pr_debug("%s: HPI cannot be sent. Card state=%d\n",
+			mmc_hostname(card->host), R1_CURRENT_STATE(status));
+		err = -EINVAL;
+		goto out;
+	}
 
-			err = mmc_send_status(card, &status);
-			if (err)
-				break;
-		} while (R1_CURRENT_STATE(status) == R1_STATE_PRG);
-	} else
-		pr_debug("%s: Left prg-state\n", mmc_hostname(card->host));
+	err = mmc_send_hpi_cmd(card, &status);
+	if (err)
+		goto out;
+
+	prg_wait = jiffies + msecs_to_jiffies(card->ext_csd.out_of_int_time);
+	do {
+		err = mmc_send_status(card, &status);
+
+		if (!err && R1_CURRENT_STATE(status) == R1_STATE_TRAN)
+			break;
+		if (time_after(jiffies, prg_wait))
+			err = -ETIMEDOUT;
+	} while (!err);
 
 out:
 	mmc_release_host(card->host);
@@ -817,7 +1116,9 @@
  *	Send HPI command to stop ongoing background operations to
  *	allow rapid servicing of foreground operations, e.g. read/
  *	writes. Wait until the card comes out of the programming state
- *	to avoid errors in servicing read/write requests.
+ *      to avoid errors in servicing read/write requests.
+ *
+ *      The function should be called with host claimed.
  */
 int mmc_stop_bkops(struct mmc_card *card)
 {
@@ -825,8 +1126,6 @@
 
 	BUG_ON(!card);
 
-	mmc_claim_host(card->host);
-
 	/*
 	 * Notify the delayed work to be cancelled, in case it was already
 	 * removed from the queue, but was not started yet
@@ -851,7 +1150,6 @@
 	MMC_UPDATE_BKOPS_STATS_HPI(card->bkops_info.bkops_stats);
 
 out:
-	mmc_release_host(card->host);
 	return err;
 }
 EXPORT_SYMBOL(mmc_stop_bkops);
@@ -1744,7 +2042,6 @@
 #endif
 	host->detect_change = 1;
 
-	wake_lock(&host->detect_wake_lock);
 	mmc_schedule_delayed_work(&host->detect, delay);
 }
 
@@ -1903,6 +2200,7 @@
 {
 	struct mmc_command cmd = {0};
 	unsigned int qty = 0;
+	unsigned long timeout;
 	int err;
 
 	/*
@@ -1980,6 +2278,7 @@
 	if (mmc_host_is_spi(card->host))
 		goto out;
 
+	timeout = jiffies + msecs_to_jiffies(MMC_CORE_TIMEOUT_MS);
 	do {
 		memset(&cmd, 0, sizeof(struct mmc_command));
 		cmd.opcode = MMC_SEND_STATUS;
@@ -1993,8 +2292,19 @@
 			err = -EIO;
 			goto out;
 		}
+
+		/* Timeout if the device never becomes ready for data and
+		 * never leaves the program state.
+		 */
+		if (time_after(jiffies, timeout)) {
+			pr_err("%s: Card stuck in programming state! %s\n",
+				mmc_hostname(card->host), __func__);
+			err =  -EIO;
+			goto out;
+		}
+
 	} while (!(cmd.resp[0] & R1_READY_FOR_DATA) ||
-		 R1_CURRENT_STATE(cmd.resp[0]) == R1_STATE_PRG);
+		 (R1_CURRENT_STATE(cmd.resp[0]) == R1_STATE_PRG));
 out:
 	return err;
 }
@@ -2444,6 +2754,30 @@
 	return;
 }
 
+static bool mmc_is_vaild_state_for_clk_scaling(struct mmc_host *host)
+{
+	struct mmc_card *card = host->card;
+	u32 status;
+	bool ret = false;
+
+	if (!card)
+		goto out;
+
+	if (mmc_send_status(card, &status)) {
+		pr_err("%s: Get card status fail\n", mmc_hostname(card->host));
+		goto out;
+	}
+
+	switch (R1_CURRENT_STATE(status)) {
+	case R1_STATE_TRAN:
+		ret = true;
+		break;
+	default:
+		break;
+	}
+out:
+	return ret;
+}
 
 /**
  * mmc_clk_scaling() - clock scaling decision algorithm
@@ -2516,6 +2850,10 @@
 			if (!from_wq)
 				cancel_delayed_work_sync(
 						&host->clk_scaling.work);
+
+			if (!mmc_is_vaild_state_for_clk_scaling(host))
+				goto bypass_scaling;
+
 			err = host->bus_ops->change_bus_speed(host, &freq);
 			if (!err)
 				host->clk_scaling.curr_freq = freq;
@@ -2537,6 +2875,7 @@
 	}
 
 	mmc_reset_clk_scale_stats(host);
+bypass_scaling:
 	host->clk_scaling.in_progress = false;
 out:
 	return;
@@ -2770,12 +3109,9 @@
  out:
 	if (extend_wakelock)
 		wake_lock_timeout(&host->detect_wake_lock, HZ / 2);
-	else
-		wake_unlock(&host->detect_wake_lock);
-	if (host->caps & MMC_CAP_NEEDS_POLL) {
-		wake_lock(&host->detect_wake_lock);
+
+	if (host->caps & MMC_CAP_NEEDS_POLL)
 		mmc_schedule_delayed_work(&host->detect, HZ);
-	}
 }
 
 void mmc_start_host(struct mmc_host *host)
@@ -2793,8 +3129,8 @@
 	spin_unlock_irqrestore(&host->lock, flags);
 #endif
 
-	if (cancel_delayed_work_sync(&host->detect))
-		wake_unlock(&host->detect_wake_lock);
+	cancel_delayed_work_sync(&host->detect);
+
 	mmc_flush_scheduled_work();
 
 	/* clear pm flags now and let card drivers set them as needed */
@@ -2945,6 +3281,7 @@
  * Turn the cache ON/OFF.
  * Turning the cache OFF shall trigger flushing of the data
  * to the non-volatile storage.
+ * This function should be called with host claimed
  */
 int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
 {
@@ -2956,9 +3293,6 @@
 			mmc_card_is_removable(host))
 		return err;
 
-	if (!mmc_try_claim_host(host))
-		return -EBUSY;
-
 	if (card && mmc_card_mmc(card) &&
 			(card->ext_csd.cache_size > 0)) {
 		enable = !!enable;
@@ -2976,7 +3310,6 @@
 				card->ext_csd.cache_ctrl = enable;
 		}
 	}
-	mmc_release_host(host);
 
 	return err;
 }
@@ -2995,12 +3328,8 @@
 	if (mmc_bus_needs_resume(host))
 		return 0;
 
-	if (cancel_delayed_work(&host->detect))
-		wake_unlock(&host->detect_wake_lock);
+	cancel_delayed_work(&host->detect);
 	mmc_flush_scheduled_work();
-	err = mmc_cache_ctrl(host, 0);
-	if (err)
-		goto out;
 
 	mmc_bus_get(host);
 	if (host->bus_ops && !host->bus_dead) {
@@ -3022,11 +3351,9 @@
 
 		if (!err) {
 			if (host->bus_ops->suspend) {
-				if (mmc_card_doing_bkops(host->card)) {
-					err = mmc_stop_bkops(host->card);
-					if (err)
-						goto stop_bkops_err;
-				}
+				err = mmc_stop_bkops(host->card);
+				if (err)
+					goto stop_bkops_err;
 				err = host->bus_ops->suspend(host);
 				MMC_UPDATE_BKOPS_STATS_SUSPEND(host->
 						card->bkops_info.bkops_stats);
@@ -3058,7 +3385,6 @@
 	if (!err && !mmc_card_keep_power(host))
 		mmc_power_off(host);
 
-out:
 	return err;
 stop_bkops_err:
 	if (!(host->card && mmc_card_sdio(host->card)))
@@ -3132,7 +3458,9 @@
 	case PM_HIBERNATION_PREPARE:
 	case PM_SUSPEND_PREPARE:
 		if (host->card && mmc_card_mmc(host->card)) {
+			mmc_claim_host(host);
 			err = mmc_stop_bkops(host->card);
+			mmc_release_host(host);
 			if (err) {
 				pr_err("%s: didn't stop bkops\n",
 					mmc_hostname(host));
@@ -3145,10 +3473,22 @@
 			spin_unlock_irqrestore(&host->lock, flags);
 			break;
 		}
+		spin_unlock_irqrestore(&host->lock, flags);
+
+		/* Wait for pending detect work to be completed */
+		if (!(host->caps & MMC_CAP_NEEDS_POLL))
+			flush_work(&host->detect.work);
+
+		spin_lock_irqsave(&host->lock, flags);
 		host->rescan_disable = 1;
 		spin_unlock_irqrestore(&host->lock, flags);
-		if (cancel_delayed_work_sync(&host->detect))
-			wake_unlock(&host->detect_wake_lock);
+
+		/*
+		 * In some cases, the detect work might be scheduled
+		 * just before rescan_disable is set to true.
+		 * Cancel such the scheduled works.
+		 */
+		cancel_delayed_work_sync(&host->detect);
 
 		if (!host->bus_ops || host->bus_ops->suspend)
 			break;
@@ -3176,7 +3516,10 @@
 		host->rescan_disable = 0;
 		spin_unlock_irqrestore(&host->lock, flags);
 		mmc_detect_change(host, 0);
+		break;
 
+	default:
+		return -EINVAL;
 	}
 
 	return 0;
@@ -3199,6 +3542,23 @@
 EXPORT_SYMBOL(mmc_set_embedded_sdio_data);
 #endif
 
+/**
+ * mmc_init_context_info() - init synchronization context
+ * @host: mmc host
+ *
+ * Init struct context_info needed to implement asynchronous
+ * request mechanism, used by mmc core, host driver and mmc requests
+ * supplier.
+ */
+void mmc_init_context_info(struct mmc_host *host)
+{
+	spin_lock_init(&host->context_info.lock);
+	host->context_info.is_new_req = false;
+	host->context_info.is_done_rcv = false;
+	host->context_info.is_waiting_last_req = false;
+	init_waitqueue_head(&host->context_info.wait);
+}
+
 static int __init mmc_init(void)
 {
 	int ret;
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index c85f5aa..6fa51e0 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -87,5 +87,5 @@
 extern void mmc_exit_clk_scaling(struct mmc_host *host);
 extern void mmc_reset_clk_scale_stats(struct mmc_host *host);
 extern unsigned long mmc_get_max_frequency(struct mmc_host *host);
+void mmc_init_context_info(struct mmc_host *host);
 #endif
-
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
index 84a26a1..8b7e0bd 100644
--- a/drivers/mmc/core/debugfs.c
+++ b/drivers/mmc/core/debugfs.c
@@ -484,6 +484,20 @@
 			pack_stats->pack_stop_reason[LARGE_SEC_ALIGN]);
 		strlcat(ubuf, temp_buf, cnt);
 	}
+	if (pack_stats->pack_stop_reason[RANDOM]) {
+		snprintf(temp_buf, TEMP_BUF_SIZE,
+			 "%s: %d times: random request\n",
+			mmc_hostname(card->host),
+			pack_stats->pack_stop_reason[RANDOM]);
+		strlcat(ubuf, temp_buf, cnt);
+	}
+	if (pack_stats->pack_stop_reason[FUA]) {
+		snprintf(temp_buf, TEMP_BUF_SIZE,
+			 "%s: %d times: fua request\n",
+			mmc_hostname(card->host),
+			pack_stats->pack_stop_reason[FUA]);
+		strlcat(ubuf, temp_buf, cnt);
+	}
 
 	spin_unlock(&pack_stats->lock);
 
@@ -673,7 +687,7 @@
 					 &mmc_dbg_wr_pack_stats_fops))
 			goto err;
 
-	if (mmc_card_mmc(card) && (card->ext_csd.rev >= 6) &&
+	if (mmc_card_mmc(card) && (card->ext_csd.rev >= 5) &&
 	    card->ext_csd.bkops_en)
 		if (!debugfs_create_file("bkops_stats", S_IRUSR, root, card,
 					 &mmc_dbg_bkops_stats_fops))
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 751ba75..0cfddc4 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -33,6 +33,7 @@
 static void mmc_host_classdev_release(struct device *dev)
 {
 	struct mmc_host *host = cls_dev_to_mmc_host(dev);
+	kfree(host->wlock_name);
 	kfree(host);
 }
 
@@ -337,8 +338,10 @@
 
 	spin_lock_init(&host->lock);
 	init_waitqueue_head(&host->wq);
+	host->wlock_name = kasprintf(GFP_KERNEL,
+			"%s_detect", mmc_hostname(host));
 	wake_lock_init(&host->detect_wake_lock, WAKE_LOCK_SUSPEND,
-		kasprintf(GFP_KERNEL, "%s_detect", mmc_hostname(host)));
+			host->wlock_name);
 	INIT_DELAYED_WORK(&host->detect, mmc_rescan);
 #ifdef CONFIG_PM
 	host->pm_notify.notifier_call = mmc_pm_notify;
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index c1a6b28..0e6956f 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -292,7 +292,7 @@
 	}
 
 	card->ext_csd.rev = ext_csd[EXT_CSD_REV];
-	if (card->ext_csd.rev > 6) {
+	if (card->ext_csd.rev > 7) {
 		printk(KERN_ERR "%s: unrecognised EXT_CSD revision %d\n",
 			mmc_hostname(card->host), card->ext_csd.rev);
 		err = -EINVAL;
@@ -1086,6 +1086,8 @@
 				 card->ext_csd.part_time);
 		if (err && err != -EBADMSG)
 			goto free_card;
+		card->part_curr = card->ext_csd.part_config &
+				  EXT_CSD_PART_CONFIG_ACC_MASK;
 	}
 
 	/*
@@ -1402,20 +1404,16 @@
 
 			/*
 			 * Calculate the time to start the BKOPs checking.
-			 * The idle time of the host controller should be taken
-			 * into account in order to prevent a race condition
-			 * before starting BKOPs and going into suspend.
-			 * If the host controller didn't set its idle time,
+			 * The host controller can set this time in order to
+			 * prevent a race condition before starting BKOPs
+			 * and going into suspend.
+			 * If the host controller didn't set this time,
 			 * a default value is used.
 			 */
 			card->bkops_info.delay_ms = MMC_IDLE_BKOPS_TIME_MS;
-			if (card->bkops_info.host_suspend_tout_ms)
-				card->bkops_info.delay_ms = min(
-					card->bkops_info.delay_ms,
-				      card->bkops_info.host_suspend_tout_ms/2);
-
-			card->bkops_info.min_sectors_to_queue_delayed_work =
-				BKOPS_MIN_SECTORS_TO_QUEUE_DELAYED_WORK;
+			if (card->bkops_info.host_delay_ms)
+				card->bkops_info.delay_ms =
+					card->bkops_info.host_delay_ms;
 		}
 	}
 
@@ -1533,6 +1531,11 @@
 	mmc_disable_clk_scaling(host);
 
 	mmc_claim_host(host);
+
+	err = mmc_cache_ctrl(host, 0);
+	if (err)
+		goto out;
+
 	if (mmc_can_poweroff_notify(host->card))
 		err = mmc_poweroff_notify(host->card, EXT_CSD_POWER_OFF_SHORT);
 	else if (mmc_card_can_sleep(host))
@@ -1540,8 +1543,9 @@
 	else if (!mmc_host_is_spi(host))
 		mmc_deselect_cards(host);
 	host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
-	mmc_release_host(host);
 
+out:
+	mmc_release_host(host);
 	return err;
 }
 
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index 4f46ed1..8087ea6 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -21,6 +21,8 @@
 #include "core.h"
 #include "mmc_ops.h"
 
+#define MMC_OPS_TIMEOUT_MS	(10 * 60 * 1000) /* 10 minute timeout */
+
 static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card)
 {
 	int err;
@@ -376,14 +378,17 @@
  *	@timeout_ms: timeout (ms) for operation performed by register write,
  *                   timeout of zero implies maximum possible timeout
  *	@use_busy_signal: use the busy signal as response type
+ *	@bkops_busy: set this to indicate that we are starting blocking bkops
  *
  *	Modifies the EXT_CSD register for selected card.
  */
 int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
-	       unsigned int timeout_ms, bool use_busy_signal)
+		 unsigned int timeout_ms, bool use_busy_signal,
+		 bool bkops_busy)
 {
 	int err;
 	struct mmc_command cmd = {0};
+	unsigned long timeout;
 	u32 status;
 
 	BUG_ON(!card);
@@ -402,6 +407,7 @@
 
 
 	cmd.cmd_timeout_ms = timeout_ms;
+	cmd.bkops_busy = bkops_busy;
 
 	err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
 	if (err)
@@ -412,6 +418,7 @@
 		return 0;
 
 	/* Must check status to be sure of no errors */
+	timeout = jiffies + msecs_to_jiffies(MMC_OPS_TIMEOUT_MS);
 	do {
 		err = mmc_send_status(card, &status);
 		if (err)
@@ -420,6 +427,13 @@
 			break;
 		if (mmc_host_is_spi(card->host))
 			break;
+
+		/* Timeout if the device never leaves the program state. */
+		if (time_after(jiffies, timeout)) {
+			pr_err("%s: Card stuck in programming state! %s\n",
+				mmc_hostname(card->host), __func__);
+			return -ETIMEDOUT;
+		}
 	} while (R1_CURRENT_STATE(status) == R1_STATE_PRG);
 
 	if (mmc_host_is_spi(card->host)) {
@@ -440,7 +454,7 @@
 int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
 		unsigned int timeout_ms)
 {
-	return __mmc_switch(card, set, index, value, timeout_ms, true);
+	return __mmc_switch(card, set, index, value, timeout_ms, true, false);
 }
 EXPORT_SYMBOL_GPL(mmc_switch);
 
@@ -591,7 +605,6 @@
 
 	cmd.opcode = opcode;
 	cmd.arg = card->rca << 16 | 1;
-	cmd.cmd_timeout_ms = card->ext_csd.out_of_int_time;
 
 	err = mmc_wait_for_cmd(card->host, &cmd, 0);
 	if (err) {
diff --git a/drivers/mmc/core/sdio_cis.c b/drivers/mmc/core/sdio_cis.c
index 2ca585d..b81af11 100644
--- a/drivers/mmc/core/sdio_cis.c
+++ b/drivers/mmc/core/sdio_cis.c
@@ -55,7 +55,7 @@
 
 	for (i = 0; i < nr_strings; i++) {
 		buffer[i] = string;
-		strlcpy(string, buf, sizeof(string));
+		strlcpy(string, buf, strlen(buf));
 		string += strlen(string) + 1;
 		buf += strlen(buf) + 1;
 	}
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index e8f3d38..7669ea3 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 2007 Google Inc,
  *  Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved.
- *  Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
+ *  Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
  *
  *
  * This program is free software; you can redistribute it and/or modify
@@ -125,6 +125,9 @@
 	0xFFFFBBBB, 0xFFFF77FF, 0xFF7777FF, 0xEEDDBB77
 };
 
+static int disable_slots;
+module_param(disable_slots, int, 0);
+
 #if IRQ_DEBUG == 1
 static char *irq_status_bits[] = { "cmdcrcfail", "datcrcfail", "cmdtimeout",
 				   "dattimeout", "txunderrun", "rxoverrun",
@@ -163,6 +166,10 @@
 static int msmsdcc_dt_get_array(struct device *dev, const char *prop_name,
 		u32 **out_array, int *len, int size);
 static int msmsdcc_execute_tuning(struct mmc_host *mmc, u32 opcode);
+static bool msmsdcc_is_wait_for_auto_prog_done(struct msmsdcc_host *host,
+					       struct mmc_request *mrq);
+static bool msmsdcc_is_wait_for_prog_done(struct msmsdcc_host *host,
+					  struct mmc_request *mrq);
 
 static inline unsigned short msmsdcc_get_nr_sg(struct msmsdcc_host *host)
 {
@@ -232,14 +239,6 @@
 {
 	int rc;
 
-	/* Reset and init DML */
-	rc = msmsdcc_dml_init(host);
-	if (rc) {
-		pr_err("%s: msmsdcc_dml_init error=%d\n",
-				mmc_hostname(host->mmc), rc);
-		goto out;
-	}
-
 	/* Reset all SDCC BAM pipes */
 	rc = msmsdcc_sps_reset_ep(host, &host->sps.prod);
 	if (rc) {
@@ -263,6 +262,11 @@
 		goto out;
 	}
 
+	memset(host->sps.prod.config.desc.base, 0x00,
+			host->sps.prod.config.desc.size);
+	memset(host->sps.cons.config.desc.base, 0x00,
+			host->sps.cons.config.desc.size);
+
 	/* Restore all BAM pipes connections */
 	rc = msmsdcc_sps_restore_ep(host, &host->sps.prod);
 	if (rc) {
@@ -272,13 +276,21 @@
 	}
 
 	rc = msmsdcc_sps_restore_ep(host, &host->sps.cons);
-	if (rc)
+	if (rc) {
 		pr_err("%s: msmsdcc_sps_restore_ep(cons) error=%d\n",
 				mmc_hostname(host->mmc), rc);
-	else
-		host->sps.reset_bam = false;
+		goto out;
+	}
+
+	/* Reset and init DML */
+	rc = msmsdcc_dml_init(host);
+	if (rc)
+		pr_err("%s: msmsdcc_dml_init error=%d\n",
+				mmc_hostname(host->mmc), rc);
 
 out:
+	if (!rc)
+		host->sps.reset_bam = false;
 	return rc;
 }
 
@@ -390,37 +402,26 @@
 static void msmsdcc_reset_and_restore(struct msmsdcc_host *host)
 {
 	if (is_soft_reset(host)) {
-		if (is_sps_mode(host))
-			/*
-			 * delay the SPS BAM reset in thread context as
-			 * sps_connect/sps_disconnect APIs can be called
-			 * only from non-atomic context.
-			 */
-			host->sps.reset_bam = true;
-
 		msmsdcc_soft_reset(host);
 
 		pr_debug("%s: Applied soft reset to Controller\n",
 				mmc_hostname(host->mmc));
 	} else {
-		/*
-		 * When there is a requirement to use this hard reset,
-		 * BAM needs to be reconfigured as well by calling
-		 * msmsdcc_sps_exit and msmsdcc_sps_init.
-		 */
-
 		/* Give Clock reset (hard reset) to controller */
 		u32	mci_clk = 0;
 		u32	mci_mask0 = 0;
+		u32	dll_config = 0;
 
 		/* Save the controller state */
 		mci_clk = readl_relaxed(host->base + MMCICLOCK);
 		mci_mask0 = readl_relaxed(host->base + MMCIMASK0);
 		host->pwr = readl_relaxed(host->base + MMCIPOWER);
+		if (host->tuning_needed)
+			dll_config = readl_relaxed(host->base + MCI_DLL_CONFIG);
 		mb();
 
 		msmsdcc_hard_reset(host);
-		pr_debug("%s: Controller has been reinitialized\n",
+		pr_debug("%s: Applied hard reset to controller\n",
 				mmc_hostname(host->mmc));
 
 		/* Restore the contoller state */
@@ -429,9 +430,19 @@
 		writel_relaxed(mci_clk, host->base + MMCICLOCK);
 		msmsdcc_sync_reg_wr(host);
 		writel_relaxed(mci_mask0, host->base + MMCIMASK0);
+		if (host->tuning_needed)
+			writel_relaxed(dll_config, host->base + MCI_DLL_CONFIG);
 		mb(); /* no delay required after writing to MASK0 register */
 	}
 
+	if (is_sps_mode(host))
+		/*
+		 * delay the SPS BAM reset in thread context as
+		 * sps_connect/sps_disconnect APIs can be called
+		 * only from non-atomic context.
+		 */
+		host->sps.reset_bam = true;
+
 	if (host->dummy_52_needed)
 		host->dummy_52_needed = 0;
 }
@@ -440,18 +451,23 @@
 {
 	struct mmc_request *mrq = host->curr.mrq;
 
-	if (!mrq || !mrq->cmd || (!mrq->data && !host->pending_dpsm_reset))
-			goto out;
+	if (!mrq || !mrq->cmd || !mrq->data)
+		goto out;
 
 	/*
-	 * For CMD24, if auto prog done is not supported defer
-	 * dpsm reset until prog done is received. Otherwise,
-	 * we poll here unnecessarily as TXACTIVE will not be
-	 * deasserted until DAT0 goes high.
+	 * If we have not waited for the prog done for write transfer then
+	 * perform the DPSM reset without polling for TXACTIVE.
+	 * Otherwise, we poll here unnecessarily as TXACTIVE will not be
+	 * deasserted until DAT0 (Busy line) goes high.
 	 */
-	if ((mrq->cmd->opcode == MMC_WRITE_BLOCK) && !is_auto_prog_done(host)) {
-		host->pending_dpsm_reset = true;
-		goto out;
+	if (mrq->data->flags & MMC_DATA_WRITE) {
+		if (!msmsdcc_is_wait_for_prog_done(host, mrq)) {
+			if (is_wait_for_tx_rx_active(host) &&
+			    !is_auto_prog_done(host))
+				pr_warning("%s: %s: AUTO_PROG_DONE capability is must\n",
+					   mmc_hostname(host->mmc), __func__);
+			goto no_polling;
+		}
 	}
 
 	/* Make sure h/w (TX/RX) is inactive before resetting DPSM */
@@ -473,15 +489,14 @@
 					& MCI_TXACTIVE ? "TX" : "RX");
 				msmsdcc_dump_sdcc_state(host);
 				msmsdcc_reset_and_restore(host);
-				host->pending_dpsm_reset = false;
 				goto out;
 			}
 		}
 	}
 
+no_polling:
 	writel_relaxed(0, host->base + MMCIDATACTRL);
 	msmsdcc_sync_reg_wr(host); /* Allow the DPSM to be reset */
-	host->pending_dpsm_reset = false;
 out:
 	return;
 }
@@ -1240,13 +1255,10 @@
 				MCI_DLL_CONFIG) & ~MCI_CDR_EN),
 				host->base + MCI_DLL_CONFIG);
 
-	if (((cmd->flags & MMC_RSP_R1B) == MMC_RSP_R1B) ||
-			(cmd->opcode == MMC_SEND_STATUS &&
-			 !(cmd->flags & MMC_CMD_ADTC))) {
+	if ((cmd->flags & MMC_RSP_R1B) == MMC_RSP_R1B) {
 		*c |= MCI_CPSM_PROGENA;
 		host->prog_enable = 1;
 	}
-
 	if (cmd == cmd->mrq->stop)
 		*c |= MCI_CSPM_MCIABORT;
 
@@ -1313,7 +1325,12 @@
 	else if (host->curr.use_wr_data_pend)
 		datactrl |= MCI_DATA_PEND;
 
-	clks = (unsigned long long)data->timeout_ns * host->clk_rate;
+	if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50)
+		clks = (unsigned long long)data->timeout_ns *
+					   (host->clk_rate / 2);
+	else
+		clks = (unsigned long long)data->timeout_ns * host->clk_rate;
+
 	do_div(clks, 1000000000UL);
 	timeout = data->timeout_clks + (unsigned int)clks*2 ;
 	WARN(!timeout,
@@ -1871,7 +1888,9 @@
 			 * will take care of signaling sdio irq during
 			 * mmc_sdio_resume().
 			 */
-			if (host->sdcc_suspended) {
+			if (host->sdcc_suspended &&
+					(host->plat->mpm_sdiowakeup_int ||
+					 host->plat->sdiowakeup_irq)) {
 				/*
 				 * This is a wakeup interrupt so hold wakelock
 				 * until SDCC resume is handled.
@@ -1960,7 +1979,7 @@
 			msmsdcc_do_cmdirq(host, status);
 		}
 
-		if (host->curr.data) {
+		if (data) {
 			/* Check for data errors */
 			if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|
 				      MCI_TXUNDERRUN|MCI_RXOVERRUN)) {
@@ -2139,11 +2158,49 @@
 	}
 }
 
+/*
+ * This function returns true if AUTO_PROG_DONE feature of host is
+ * applicable for current request, returns "false" otherwise.
+ *
+ * NOTE: Caller should call this function only for data write operations.
+ */
+static bool msmsdcc_is_wait_for_auto_prog_done(struct msmsdcc_host *host,
+					       struct mmc_request *mrq)
+{
+	/*
+	 * Auto-prog done will be enabled for following cases:
+	 * mrq->sbc	|	mrq->stop
+	 * _____________|________________
+	 *	True	|	Don't care
+	 *	False	|	False (CMD24, ACMD25 use case)
+	 */
+	if (is_auto_prog_done(host) && (mrq->sbc || !mrq->stop))
+		return true;
+
+	return false;
+}
+
+/*
+ * This function returns true if controller can wait for prog done
+ * for current request, returns "false" otherwise.
+ *
+ * NOTE: Caller should call this function only for data write operations.
+ */
+static bool msmsdcc_is_wait_for_prog_done(struct msmsdcc_host *host,
+					  struct mmc_request *mrq)
+{
+	if (msmsdcc_is_wait_for_auto_prog_done(host, mrq) || mrq->stop)
+		return true;
+
+	return false;
+}
+
 static void
 msmsdcc_request(struct mmc_host *mmc, struct mmc_request *mrq)
 {
 	struct msmsdcc_host *host = mmc_priv(mmc);
 	unsigned long		flags;
+	unsigned int error = 0;
 	int retries = 5;
 
 	/*
@@ -2153,6 +2210,18 @@
 	if (host->plat->is_sdio_al_client)
 		msmsdcc_sdio_al_lpm(mmc, false);
 
+	/*
+	 * Don't start the request if SDCC is not in proper state to handle it
+	 * BAM state is checked below if applicable
+	 */
+	if (!host->pwr || !atomic_read(&host->clks_on) ||
+			host->sdcc_irq_disabled) {
+		WARN(1, "%s: %s: SDCC is in bad state. don't process new request (CMD%d)\n",
+			mmc_hostname(host->mmc), __func__, mrq->cmd->opcode);
+		error = EIO;
+		goto bad_state;
+	}
+
 	/* check if sps bam needs to be reset */
 	if (is_sps_mode(host) && host->sps.reset_bam) {
 		while (retries) {
@@ -2161,6 +2230,14 @@
 			pr_err("%s: msmsdcc_bam_dml_reset_and_restore returned error. %d attempts left.\n",
 					mmc_hostname(host->mmc), --retries);
 		}
+
+		/* check if BAM reset succeeded or not */
+		if (host->sps.reset_bam) {
+			pr_err("%s: bam reset failed. Not processing the new request (CMD%d)\n",
+				mmc_hostname(host->mmc), mrq->cmd->opcode);
+			error = EAGAIN;
+			goto bad_state;
+		}
 	}
 
 	/*
@@ -2179,33 +2256,9 @@
 					       MMC_SEND_TUNING_BLOCK_HS200);
 	}
 
-	spin_lock_irqsave(&host->lock, flags);
-
 	if (host->eject) {
-		mrq->cmd->error = -ENOMEDIUM;
-		spin_unlock_irqrestore(&host->lock, flags);
-		mmc_request_done(mmc, mrq);
-		return;
-	}
-
-	/*
-	 * Don't start the request if SDCC is not in proper state to handle it
-	 */
-	if (!host->pwr || !atomic_read(&host->clks_on) ||
-			host->sdcc_irq_disabled ||
-			host->sps.reset_bam) {
-		WARN(1, "%s: %s: SDCC is in bad state. don't process"
-		     " new request (CMD%d)\n", mmc_hostname(host->mmc),
-		     __func__, mrq->cmd->opcode);
-		msmsdcc_dump_sdcc_state(host);
-		mrq->cmd->error = -EIO;
-		if (mrq->data) {
-			mrq->data->error = -EIO;
-			mrq->data->bytes_xfered = 0;
-		}
-		spin_unlock_irqrestore(&host->lock, flags);
-		mmc_request_done(mmc, mrq);
-		return;
+		error = ENOMEDIUM;
+		goto card_ejected;
 	}
 
 	WARN(host->curr.mrq, "%s: %s: New request (CMD%d) received while"
@@ -2213,6 +2266,8 @@
 	     mmc_hostname(host->mmc), __func__,
 	     mrq->cmd->opcode, host->curr.mrq->cmd->opcode);
 
+	spin_lock_irqsave(&host->lock, flags);
+
 	/*
 	 * Set timeout value to 10 secs (or more in case of buggy cards)
 	 */
@@ -2235,16 +2290,8 @@
 	}
 
 	if (mrq->data && (mrq->data->flags & MMC_DATA_WRITE)) {
-		if (is_auto_prog_done(host)) {
-			/*
-			 * Auto-prog done will be enabled for following cases:
-			 * mrq->sbc	|	mrq->stop
-			 * _____________|________________
-			 *	True	|	Don't care
-			 *	False	|	False (CMD24, ACMD25 use case)
-			 */
-			if (mrq->sbc || !mrq->stop)
-				host->curr.wait_for_auto_prog_done = true;
+		if (msmsdcc_is_wait_for_auto_prog_done(host, mrq)) {
+			host->curr.wait_for_auto_prog_done = true;
 		} else {
 			if ((mrq->cmd->opcode == SD_IO_RW_EXTENDED) ||
 			    (mrq->cmd->opcode == 54))
@@ -2259,8 +2306,18 @@
 	}
 
 	msmsdcc_request_start(host, mrq);
-
 	spin_unlock_irqrestore(&host->lock, flags);
+	return;
+
+bad_state:
+	msmsdcc_dump_sdcc_state(host);
+card_ejected:
+	mrq->cmd->error = -error;
+	if (mrq->data) {
+		mrq->data->error = -error;
+		mrq->data->bytes_xfered = 0;
+	}
+	mmc_request_done(mmc, mrq);
 }
 
 static inline int msmsdcc_vreg_set_voltage(struct msm_mmc_reg_data *vreg,
@@ -3309,20 +3366,7 @@
 			writel_relaxed(clk, host->base + MMCICLOCK);
 			msmsdcc_sync_reg_wr(host);
 
-			/*
-			 * Make sure that we don't double the clock if
-			 * doubled clock rate is already set
-			 */
-			if (!host->ddr_doubled_clk_rate ||
-				(host->ddr_doubled_clk_rate &&
-				(host->ddr_doubled_clk_rate != ios->clock))) {
-				host->ddr_doubled_clk_rate =
-					msmsdcc_get_sup_clk_rate(
-						host, (ios->clock * 2));
-				clock = host->ddr_doubled_clk_rate;
-			}
-		} else {
-			host->ddr_doubled_clk_rate = 0;
+			clock = msmsdcc_get_sup_clk_rate(host, ios->clock * 2);
 		}
 
 		if (clock != host->clk_rate) {
@@ -4243,35 +4287,103 @@
 	if (!card || !mmc_card_sd(card))
 		return;
 
-	/*
-	 * Continuing on failing to disable regulator would lead to a panic
-	 * anyway, since the commands would fail and console would be flooded
-	 * with prints, eventually leading to a watchdog bark
-	 */
-	rc = msmsdcc_setup_vreg(host, false, false);
-	if (rc) {
-		pr_err("%s: %s disable regulator: failed: %d\n",
-		       mmc_hostname(mmc), __func__, rc);
-		BUG_ON(rc);
+	pr_debug("%s: Starting h/w reset\n", mmc_hostname(host->mmc));
+
+	if (host->plat->translate_vdd || host->plat->vreg_data) {
+
+		/* Disable the regulators */
+		if (host->plat->translate_vdd)
+			rc = host->plat->translate_vdd(mmc_dev(mmc), 0);
+		else if (host->plat->vreg_data)
+			rc = msmsdcc_setup_vreg(host, false, false);
+
+		if (rc) {
+			pr_err("%s: Failed to disable voltage regulator\n",
+				mmc_hostname(host->mmc));
+			BUG_ON(rc);
+		}
+
+		/* 10ms delay for supply to reach the desired voltage level */
+		usleep_range(10000, 12000);
+
+		/* Enable the regulators */
+		if (host->plat->translate_vdd)
+			rc = host->plat->translate_vdd(mmc_dev(mmc), 1);
+		else if (host->plat->vreg_data)
+			rc = msmsdcc_setup_vreg(host, true, false);
+
+		if (rc) {
+			pr_err("%s: Failed to enable voltage regulator\n",
+				mmc_hostname(host->mmc));
+			BUG_ON(rc);
+		}
+
+		/* 10ms delay for supply to reach the desired voltage level */
+		usleep_range(10000, 12000);
 	}
+}
 
-	/* 10ms delay for the supply to reach the desired voltage level */
-	usleep_range(10000, 12000);
+/**
+ *	msmsdcc_stop_request - stops ongoing request
+ *	@mmc: MMC host, running the request
+ *
+ *	Stops currently running request synchronously. All relevant request
+ *	information is cleared.
+ */
+int msmsdcc_stop_request(struct mmc_host *mmc)
+{
+	struct msmsdcc_host *host = mmc_priv(mmc);
+	struct mmc_request *mrq;
+	unsigned long flags;
+	int rc = 0;
 
-	/*
-	 * Continuing on failing to enable regulator would lead to a panic
-	 * anyway, since the commands would fail and console would be flooded
-	 * with prints, eventually leading to a watchdog bark
-	 */
-	rc = msmsdcc_setup_vreg(host, true, false);
-	if (rc) {
-		pr_err("%s: %s enable regulator: failed: %d\n",
-		       mmc_hostname(mmc), __func__, rc);
-		BUG_ON(rc);
+	spin_lock_irqsave(&host->lock, flags);
+	mrq = host->curr.mrq;
+	if (mrq) {
+		msmsdcc_reset_and_restore(host);
+		/*
+		 * Note: We are just taking care of SPS. We may also
+		 * need to think about ADM (and PIO?) later if required.
+		 */
+		if (host->sps.sg && is_sps_mode(host)) {
+			if (!mrq->data->host_cookie)
+				dma_unmap_sg(mmc_dev(host->mmc), host->sps.sg,
+					host->sps.num_ents, host->sps.dir);
+			host->sps.sg = NULL;
+			host->sps.busy = 0;
+		}
+
+		/*
+		 * Clear current request information as current
+		 * request has ended
+		 */
+		memset(&host->curr, 0, sizeof(struct msmsdcc_curr_req));
+		del_timer(&host->req_tout_timer);
+	} else {
+		rc = -EINVAL;
 	}
+	spin_unlock_irqrestore(&host->lock, flags);
 
-	/* 10ms delay for the supply to reach the desired voltage level */
-	usleep_range(10000, 12000);
+	return rc;
+}
+
+/**
+ *	msmsdcc_get_xfer_remain - returns number of bytes passed on bus
+ *	@mmc: MMC host, running the request
+ *
+ *	Returns the number of bytes passed for SPS transfer. 0 - for non-SPS
+ *	transfer.
+ */
+unsigned int msmsdcc_get_xfer_remain(struct mmc_host *mmc)
+{
+	struct msmsdcc_host *host = mmc_priv(mmc);
+	u32 data_cnt = 0;
+
+	/* Currently, we don't support to stop the non-SPS transfer */
+	if (host->sps.busy && atomic_read(&host->clks_on))
+		data_cnt = readl_relaxed(host->base + MMCIDATACNT);
+
+	return data_cnt;
 }
 
 static const struct mmc_host_ops msmsdcc_ops = {
@@ -4286,6 +4398,8 @@
 	.start_signal_voltage_switch = msmsdcc_switch_io_voltage,
 	.execute_tuning = msmsdcc_execute_tuning,
 	.hw_reset = msmsdcc_hw_reset,
+	.stop_request = msmsdcc_stop_request,
+	.get_xfer_remain = msmsdcc_get_xfer_remain,
 };
 
 static void msmsdcc_enable_status_gpio(struct msmsdcc_host *host)
@@ -4935,9 +5049,6 @@
 	} else {
 		mmc->caps &= ~MMC_CAP_NEEDS_POLL;
 	}
-#ifdef CONFIG_HAS_EARLYSUSPEND
-	host->polling_enabled = mmc->caps & MMC_CAP_NEEDS_POLL;
-#endif
 	spin_unlock_irqrestore(&host->lock, flags);
 	return count;
 }
@@ -5057,33 +5168,6 @@
 	return count;
 }
 
-#ifdef CONFIG_HAS_EARLYSUSPEND
-static void msmsdcc_early_suspend(struct early_suspend *h)
-{
-	struct msmsdcc_host *host =
-		container_of(h, struct msmsdcc_host, early_suspend);
-	unsigned long flags;
-
-	spin_lock_irqsave(&host->lock, flags);
-	host->polling_enabled = host->mmc->caps & MMC_CAP_NEEDS_POLL;
-	host->mmc->caps &= ~MMC_CAP_NEEDS_POLL;
-	spin_unlock_irqrestore(&host->lock, flags);
-};
-static void msmsdcc_late_resume(struct early_suspend *h)
-{
-	struct msmsdcc_host *host =
-		container_of(h, struct msmsdcc_host, early_suspend);
-	unsigned long flags;
-
-	if (host->polling_enabled) {
-		spin_lock_irqsave(&host->lock, flags);
-		host->mmc->caps |= MMC_CAP_NEEDS_POLL;
-		mmc_detect_change(host->mmc, 0);
-		spin_unlock_irqrestore(&host->lock, flags);
-	}
-};
-#endif
-
 static void msmsdcc_print_regs(const char *name, void __iomem *base,
 			       u32 phys_base, unsigned int no_of_regs)
 {
@@ -5200,9 +5284,11 @@
 	mrq = host->curr.mrq;
 
 	if (mrq && mrq->cmd) {
-		pr_info("%s: CMD%d: Request timeout\n", mmc_hostname(host->mmc),
-				mrq->cmd->opcode);
-		msmsdcc_dump_sdcc_state(host);
+		if (!mrq->cmd->bkops_busy) {
+			pr_info("%s: CMD%d: Request timeout\n",
+				mmc_hostname(host->mmc), mrq->cmd->opcode);
+			msmsdcc_dump_sdcc_state(host);
+		}
 
 		if (!mrq->cmd->error)
 			mrq->cmd->error = -ETIMEDOUT;
@@ -5766,6 +5852,11 @@
 		goto out;
 	}
 
+	if (disable_slots & (1 << (pdev->id - 1))) {
+		pr_info("%s: Slot %d disabled\n", __func__, pdev->id);
+		return -ENODEV;
+	}
+
 	if (pdev->id < 1 || pdev->id > 5)
 		return -EINVAL;
 
@@ -6012,7 +6103,6 @@
 	mmc->caps2 |= (MMC_CAP2_BOOTPART_NOACC | MMC_CAP2_DETECT_ON_ERR);
 	mmc->caps2 |= MMC_CAP2_SANITIZE;
 	mmc->caps2 |= MMC_CAP2_CACHE_CTRL;
-	mmc->caps2 |= MMC_CAP2_INIT_BKOPS;
 	mmc->caps2 |= MMC_CAP2_POWEROFF_NOTIFY;
 
 	if (plat->nonremovable)
@@ -6067,8 +6157,6 @@
 	}
 
 	if (plat->sdiowakeup_irq) {
-		wake_lock_init(&host->sdio_wlock, WAKE_LOCK_SUSPEND,
-				mmc_hostname(mmc));
 		ret = request_irq(plat->sdiowakeup_irq,
 			msmsdcc_platform_sdiowakeup_irq,
 			IRQF_SHARED | IRQF_TRIGGER_LOW,
@@ -6087,7 +6175,7 @@
 		}
 	}
 
-	if (host->plat->mpm_sdiowakeup_int) {
+	if (plat->sdiowakeup_irq || plat->mpm_sdiowakeup_int) {
 		wake_lock_init(&host->sdio_wlock, WAKE_LOCK_SUSPEND,
 				mmc_hostname(mmc));
 	}
@@ -6170,12 +6258,10 @@
 
 	mmc_add_host(mmc);
 
-#ifdef CONFIG_HAS_EARLYSUSPEND
-	host->early_suspend.suspend = msmsdcc_early_suspend;
-	host->early_suspend.resume  = msmsdcc_late_resume;
-	host->early_suspend.level   = EARLY_SUSPEND_LEVEL_DISABLE_FB;
-	register_early_suspend(&host->early_suspend);
-#endif
+	mmc->clk_scaling.up_threshold = 35;
+	mmc->clk_scaling.down_threshold = 5;
+	mmc->clk_scaling.polling_delay_ms = 100;
+	mmc->caps2 |= MMC_CAP2_CLK_SCALE;
 
 	pr_info("%s: Qualcomm MSM SDCC-core at 0x%016llx irq %d,%d dma %d"
 		" dmacrcri %d\n", mmc_hostname(mmc),
@@ -6294,12 +6380,12 @@
 		free_irq(plat->status_irq, host);
 	msmsdcc_disable_status_gpio(host);
  sdiowakeup_irq_free:
+	if (plat->sdiowakeup_irq || plat->mpm_sdiowakeup_int)
+		wake_lock_destroy(&host->sdio_wlock);
 	wake_lock_destroy(&host->sdio_suspend_wlock);
 	if (plat->sdiowakeup_irq)
 		free_irq(plat->sdiowakeup_irq, host);
  pio_irq_free:
-	if (plat->sdiowakeup_irq)
-		wake_lock_destroy(&host->sdio_wlock);
 	free_irq(core_irqres->start, host);
  irq_free:
 	free_irq(core_irqres->start, host);
@@ -6393,11 +6479,13 @@
 
 	wake_lock_destroy(&host->sdio_suspend_wlock);
 	if (plat->sdiowakeup_irq) {
-		wake_lock_destroy(&host->sdio_wlock);
 		irq_set_irq_wake(plat->sdiowakeup_irq, 0);
 		free_irq(plat->sdiowakeup_irq, host);
 	}
 
+	if (plat->sdiowakeup_irq || plat->mpm_sdiowakeup_int)
+		wake_lock_destroy(&host->sdio_wlock);
+
 	free_irq(host->core_irqres->start, host);
 	free_irq(host->core_irqres->start, host);
 
@@ -6432,9 +6520,6 @@
 	iounmap(host->base);
 	mmc_free_host(mmc);
 
-#ifdef CONFIG_HAS_EARLYSUSPEND
-	unregister_early_suspend(&host->early_suspend);
-#endif
 	pm_runtime_disable(&(pdev)->dev);
 	pm_runtime_set_suspended(&(pdev)->dev);
 
@@ -6723,9 +6808,21 @@
 		msmsdcc_disable_status_gpio(host);
 	}
 
-	if (!pm_runtime_suspended(dev))
+	/*
+	 * If system comes out of suspend, msmsdcc_pm_resume() sets the
+	 * host->pending_resume flag if the SDCC wasn't runtime suspended.
+	 * Now if the system again goes to suspend without any SDCC activity
+	 * then host->pending_resume flag will remain set which may cause
+	 * the SDCC resume to happen first and then suspend.
+	 * To avoid this unnecessary resume/suspend, make sure that
+	 * pending_resume flag is cleared before calling the
+	 * msmsdcc_runtime_suspend().
+	 */
+	if (!pm_runtime_suspended(dev) && !host->pending_resume)
 		rc = msmsdcc_runtime_suspend(dev);
  out:
+	/* This flag must not be set if system is entering into suspend */
+	host->pending_resume = false;
 	msmsdcc_print_pm_stats(host, start, __func__, rc);
 	return rc;
 }
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index 7469c8e..4ed2d96 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -2,7 +2,7 @@
  *  linux/drivers/mmc/host/msmsdcc.h - QCT MSM7K SDC Controller
  *
  *  Copyright (C) 2008 Google, All Rights Reserved.
- *  Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
+ *  Copyright (c) 2009-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 as
@@ -25,7 +25,6 @@
 #include <linux/scatterlist.h>
 #include <linux/dma-mapping.h>
 #include <linux/wakelock.h>
-#include <linux/earlysuspend.h>
 #include <linux/pm_qos.h>
 #include <mach/sps.h>
 
@@ -369,7 +368,6 @@
 
 	unsigned int		clk_rate;	/* Current clock rate */
 	unsigned int		pclk_rate;
-	unsigned int		ddr_doubled_clk_rate;
 
 	u32			pwr;
 	struct mmc_platform_data *plat;
@@ -381,11 +379,6 @@
 	struct msmsdcc_sps_data sps;
 	struct msmsdcc_pio_data	pio;
 
-#ifdef CONFIG_HAS_EARLYSUSPEND
-	struct early_suspend early_suspend;
-	int polling_enabled;
-#endif
-
 	struct tasklet_struct 	dma_tlet;
 
 	unsigned int prog_enable;
@@ -422,7 +415,6 @@
 	struct mutex clk_mutex;
 	bool pending_resume;
 	unsigned int idle_tout;			/* Timeout in msecs */
-	bool pending_dpsm_reset;
 	bool enforce_pio_mode;
 	bool print_pm_stats;
 	struct msmsdcc_msm_bus_vote msm_bus_vote;
@@ -501,17 +493,18 @@
 			| MSMSDCC_WAIT_FOR_TX_RX | MSMSDCC_IO_PAD_PWR_SWITCH
 			| MSMSDCC_AUTO_CMD19;
 
-	if ((step == 0x18) && (minor >= 3))
+	if ((step == 0x18) && (minor >= 3)) {
 		host->hw_caps |= MSMSDCC_AUTO_CMD21;
+		/* Version 0x06000018 need hard reset on errors */
+		host->hw_caps &= ~MSMSDCC_SOFT_RESET;
+	}
 
 	if (step >= 0x2b) /* SDCC v4 2.1.0 and greater */
 		host->hw_caps |= MSMSDCC_SW_RST | MSMSDCC_SW_RST_CFG |
 				 MSMSDCC_AUTO_CMD21 |
 				 MSMSDCC_DATA_PEND_FOR_CMD53 |
-				 MSMSDCC_TESTBUS_DEBUG;
-
-	if (step == 0x2b)
-		host->hw_caps |= MSMSDCC_SW_RST_CFG_BROKEN;
+				 MSMSDCC_TESTBUS_DEBUG |
+				 MSMSDCC_SW_RST_CFG_BROKEN;
 }
 
 int msmsdcc_set_pwrsave(struct mmc_host *mmc, int pwrsave);
diff --git a/drivers/mmc/host/msm_sdcc_dml.c b/drivers/mmc/host/msm_sdcc_dml.c
index 320f52e..91ab7e3 100644
--- a/drivers/mmc/host/msm_sdcc_dml.c
+++ b/drivers/mmc/host/msm_sdcc_dml.c
@@ -1,7 +1,7 @@
 /*
  * linux/drivers/mmc/host/msm_sdcc_dml.c - Qualcomm MSM SDCC DML Driver
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/drivers/mmc/host/msm_sdcc_dml.h b/drivers/mmc/host/msm_sdcc_dml.h
index f0e1b78..bee58d1 100644
--- a/drivers/mmc/host/msm_sdcc_dml.h
+++ b/drivers/mmc/host/msm_sdcc_dml.h
@@ -2,7 +2,7 @@
  *  linux/drivers/mmc/host/msm_sdcc_dml.h - Qualcomm SDCC DML driver
  *					    header file
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 6451d62..8c2bea09 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -68,51 +68,51 @@
 
 static void sdhci_dumpregs(struct sdhci_host *host)
 {
-	printk(KERN_DEBUG DRIVER_NAME ": =========== REGISTER DUMP (%s)===========\n",
+	pr_debug(DRIVER_NAME ": =========== REGISTER DUMP (%s)===========\n",
 		mmc_hostname(host->mmc));
 
-	printk(KERN_DEBUG DRIVER_NAME ": Sys addr: 0x%08x | Version:  0x%08x\n",
+	pr_debug(DRIVER_NAME ": Sys addr: 0x%08x | Version:  0x%08x\n",
 		sdhci_readl(host, SDHCI_DMA_ADDRESS),
 		sdhci_readw(host, SDHCI_HOST_VERSION));
-	printk(KERN_DEBUG DRIVER_NAME ": Blk size: 0x%08x | Blk cnt:  0x%08x\n",
+	pr_debug(DRIVER_NAME ": Blk size: 0x%08x | Blk cnt:  0x%08x\n",
 		sdhci_readw(host, SDHCI_BLOCK_SIZE),
 		sdhci_readw(host, SDHCI_BLOCK_COUNT));
-	printk(KERN_DEBUG DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n",
+	pr_debug(DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n",
 		sdhci_readl(host, SDHCI_ARGUMENT),
 		sdhci_readw(host, SDHCI_TRANSFER_MODE));
-	printk(KERN_DEBUG DRIVER_NAME ": Present:  0x%08x | Host ctl: 0x%08x\n",
+	pr_debug(DRIVER_NAME ": Present:  0x%08x | Host ctl: 0x%08x\n",
 		sdhci_readl(host, SDHCI_PRESENT_STATE),
 		sdhci_readb(host, SDHCI_HOST_CONTROL));
-	printk(KERN_DEBUG DRIVER_NAME ": Power:    0x%08x | Blk gap:  0x%08x\n",
+	pr_debug(DRIVER_NAME ": Power:    0x%08x | Blk gap:  0x%08x\n",
 		sdhci_readb(host, SDHCI_POWER_CONTROL),
 		sdhci_readb(host, SDHCI_BLOCK_GAP_CONTROL));
-	printk(KERN_DEBUG DRIVER_NAME ": Wake-up:  0x%08x | Clock:    0x%08x\n",
+	pr_debug(DRIVER_NAME ": Wake-up:  0x%08x | Clock:    0x%08x\n",
 		sdhci_readb(host, SDHCI_WAKE_UP_CONTROL),
 		sdhci_readw(host, SDHCI_CLOCK_CONTROL));
-	printk(KERN_DEBUG DRIVER_NAME ": Timeout:  0x%08x | Int stat: 0x%08x\n",
+	pr_debug(DRIVER_NAME ": Timeout:  0x%08x | Int stat: 0x%08x\n",
 		sdhci_readb(host, SDHCI_TIMEOUT_CONTROL),
 		sdhci_readl(host, SDHCI_INT_STATUS));
-	printk(KERN_DEBUG DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n",
+	pr_debug(DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n",
 		sdhci_readl(host, SDHCI_INT_ENABLE),
 		sdhci_readl(host, SDHCI_SIGNAL_ENABLE));
-	printk(KERN_DEBUG DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n",
+	pr_debug(DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n",
 		sdhci_readw(host, SDHCI_ACMD12_ERR),
 		sdhci_readw(host, SDHCI_SLOT_INT_STATUS));
-	printk(KERN_DEBUG DRIVER_NAME ": Caps:     0x%08x | Caps_1:   0x%08x\n",
+	pr_debug(DRIVER_NAME ": Caps:     0x%08x | Caps_1:   0x%08x\n",
 		sdhci_readl(host, SDHCI_CAPABILITIES),
 		sdhci_readl(host, SDHCI_CAPABILITIES_1));
-	printk(KERN_DEBUG DRIVER_NAME ": Cmd:      0x%08x | Max curr: 0x%08x\n",
+	pr_debug(DRIVER_NAME ": Cmd:      0x%08x | Max curr: 0x%08x\n",
 		sdhci_readw(host, SDHCI_COMMAND),
 		sdhci_readl(host, SDHCI_MAX_CURRENT));
-	printk(KERN_DEBUG DRIVER_NAME ": Host ctl2: 0x%08x\n",
+	pr_debug(DRIVER_NAME ": Host ctl2: 0x%08x\n",
 		sdhci_readw(host, SDHCI_HOST_CONTROL2));
 
 	if (host->flags & SDHCI_USE_ADMA)
-		printk(KERN_DEBUG DRIVER_NAME ": ADMA Err: 0x%08x | ADMA Ptr: 0x%08x\n",
+		pr_debug(DRIVER_NAME ": ADMA Err: 0x%08x | ADMA Ptr: 0x%08x\n",
 		       readl(host->ioaddr + SDHCI_ADMA_ERROR),
 		       readl(host->ioaddr + SDHCI_ADMA_ADDRESS));
 
-	printk(KERN_DEBUG DRIVER_NAME ": ===========================================\n");
+	pr_debug(DRIVER_NAME ": ===========================================\n");
 }
 
 /*****************************************************************************\
@@ -144,14 +144,15 @@
 
 static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
 {
-	u32 irqs = SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT;
+	u32 present, irqs;
 
 	if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) ||
 	    (host->mmc->caps & MMC_CAP_NONREMOVABLE))
 		return;
 
-	if (host->quirks2 & SDHCI_QUIRK2_OWN_CARD_DETECTION)
-		return;
+	present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
+			      SDHCI_CARD_PRESENT;
+	irqs = present ? SDHCI_INT_CARD_REMOVE : SDHCI_INT_CARD_INSERT;
 
 	if (enable)
 		sdhci_unmask_irqs(host, irqs);
@@ -194,10 +195,14 @@
 	/* Wait max 100 ms */
 	timeout = 100;
 
+	if (host->ops->check_power_status && host->pwr &&
+	    (mask & SDHCI_RESET_ALL))
+		host->ops->check_power_status(host);
+
 	/* hw clears the bit when it's done */
 	while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) {
 		if (timeout == 0) {
-			printk(KERN_ERR "%s: Reset 0x%x never completed.\n",
+			pr_err("%s: Reset 0x%x never completed.\n",
 				mmc_hostname(host->mmc), (int)mask);
 			sdhci_dumpregs(host);
 			return;
@@ -211,6 +216,11 @@
 
 	if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
 		sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier);
+
+	if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
+		if ((host->ops->enable_dma) && (mask & SDHCI_RESET_ALL))
+			host->ops->enable_dma(host);
+	}
 }
 
 static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios);
@@ -648,12 +658,11 @@
 	/* timeout in us */
 	if (!data)
 		target_timeout = cmd->cmd_timeout_ms * 1000;
-	else
-		target_timeout = data->timeout_ns / 1000 +
-			data->timeout_clks / host->clock;
-
-	if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)
-		host->timeout_clk = host->clock / 1000;
+	else {
+		target_timeout = data->timeout_ns / 1000;
+		if (host->clock)
+			target_timeout += data->timeout_clks / host->clock;
+	}
 
 	/*
 	 * Figure out needed cycles.
@@ -665,7 +674,6 @@
 	 *     =>
 	 *     (1) / (2) > 2^6
 	 */
-	BUG_ON(!host->timeout_clk);
 	count = 0;
 	current_timeout = (1 << 13) * 1000 / host->timeout_clk;
 	while (current_timeout < target_timeout) {
@@ -675,8 +683,11 @@
 			break;
 	}
 
-	if (count >= 0xF)
+	if (count >= 0xF) {
+		DBG("%s: Too large timeout 0x%x requested for CMD%d!\n",
+		    mmc_hostname(host->mmc), count, cmd->opcode);
 		count = 0xE;
+	}
 
 	return count;
 }
@@ -884,8 +895,13 @@
 		}
 	}
 
-	if (data->flags & MMC_DATA_READ)
+	if (data->flags & MMC_DATA_READ) {
 		mode |= SDHCI_TRNS_READ;
+		if (host->ops->toggle_cdr)
+			host->ops->toggle_cdr(host, true);
+	}
+	if (host->ops->toggle_cdr && (data->flags & MMC_DATA_WRITE))
+		host->ops->toggle_cdr(host, false);
 	if (host->flags & SDHCI_REQ_USE_DMA)
 		mode |= SDHCI_TRNS_DMA;
 
@@ -968,7 +984,7 @@
 
 	while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
 		if (timeout == 0) {
-			printk(KERN_ERR "%s: Controller never released "
+			pr_err("%s: Controller never released "
 				"inhibit bit(s).\n", mmc_hostname(host->mmc));
 			sdhci_dumpregs(host);
 			cmd->error = -EIO;
@@ -990,7 +1006,7 @@
 	sdhci_set_transfer_mode(host, cmd);
 
 	if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) {
-		printk(KERN_ERR "%s: Unsupported response type!\n",
+		pr_err("%s: Unsupported response type!\n",
 			mmc_hostname(host->mmc));
 		cmd->error = -EINVAL;
 		tasklet_schedule(&host->finish_tasklet);
@@ -1063,12 +1079,15 @@
 static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 {
 	int div = 0; /* Initialized for compiler warning */
+	int real_div = div, clk_mul = 1;
 	u16 clk = 0;
 	unsigned long timeout;
 
 	if (clock && clock == host->clock)
 		return;
 
+	host->mmc->actual_clock = 0;
+
 	if (host->ops->set_clock) {
 		host->ops->set_clock(host, clock);
 		if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK)
@@ -1106,6 +1125,8 @@
 				 * Control register.
 				 */
 				clk = SDHCI_PROG_CLOCK_MODE;
+				real_div = div;
+				clk_mul = host->clk_mul;
 				div--;
 			}
 		} else {
@@ -1119,6 +1140,7 @@
 						break;
 				}
 			}
+			real_div = div;
 			div >>= 1;
 		}
 	} else {
@@ -1127,9 +1149,13 @@
 			if ((host->max_clk / div) <= clock)
 				break;
 		}
+		real_div = div;
 		div >>= 1;
 	}
 
+	if (real_div)
+		host->mmc->actual_clock = (host->max_clk * clk_mul) / real_div;
+
 	clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT;
 	clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN)
 		<< SDHCI_DIVIDER_HI_SHIFT;
@@ -1141,7 +1167,7 @@
 	while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
 		& SDHCI_CLOCK_INT_STABLE)) {
 		if (timeout == 0) {
-			printk(KERN_ERR "%s: Internal clock never "
+			pr_err("%s: Internal clock never "
 				"stabilised.\n", mmc_hostname(host->mmc));
 			sdhci_dumpregs(host);
 			return;
@@ -1157,7 +1183,7 @@
 	host->clock = clock;
 }
 
-static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
+static int sdhci_set_power(struct sdhci_host *host, unsigned short power)
 {
 	u8 pwr = 0;
 
@@ -1180,32 +1206,42 @@
 	}
 
 	if (host->pwr == pwr)
-		return;
+		return -1;
 
 	host->pwr = pwr;
 
 	if (pwr == 0) {
 		sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
-		return;
+		if (host->ops->check_power_status)
+			host->ops->check_power_status(host);
+		return 0;
 	}
 
 	/*
 	 * Spec says that we should clear the power reg before setting
 	 * a new value. Some controllers don't seem to like this though.
 	 */
-	if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
+	if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE)) {
 		sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
+		if (host->ops->check_power_status)
+			host->ops->check_power_status(host);
+	}
 
 	/*
 	 * At least the Marvell CaFe chip gets confused if we set the voltage
 	 * and set turn on power at the same time, so set the voltage first.
 	 */
-	if (host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER)
+	if (host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER) {
 		sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
+		if (host->ops->check_power_status)
+			host->ops->check_power_status(host);
+	}
 
 	pwr |= SDHCI_POWER_ON;
 
 	sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
+	if (host->ops->check_power_status)
+		host->ops->check_power_status(host);
 
 	/*
 	 * Some controllers need an extra 10ms delay of 10ms before they
@@ -1213,6 +1249,8 @@
 	 */
 	if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER)
 		mdelay(10);
+
+	return power;
 }
 
 /*****************************************************************************\
@@ -1294,12 +1332,14 @@
 static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 {
 	unsigned long flags;
+	int vdd_bit = -1;
 	u8 ctrl;
 
-	spin_lock_irqsave(&host->lock, flags);
-
-	if (host->flags & SDHCI_DEVICE_DEAD)
-		goto out;
+	if (host->flags & SDHCI_DEVICE_DEAD) {
+		if (host->vmmc && ios->power_mode == MMC_POWER_OFF)
+			mmc_regulator_set_ocr(host->mmc, host->vmmc, 0);
+		return;
+	}
 
 	/*
 	 * Reset the chip on each power off.
@@ -1313,9 +1353,14 @@
 	sdhci_set_clock(host, ios->clock);
 
 	if (ios->power_mode == MMC_POWER_OFF)
-		sdhci_set_power(host, -1);
+		vdd_bit = sdhci_set_power(host, -1);
 	else
-		sdhci_set_power(host, ios->vdd);
+		vdd_bit = sdhci_set_power(host, ios->vdd);
+
+	if (host->vmmc && vdd_bit != -1)
+		mmc_regulator_set_ocr(host->mmc, host->vmmc, vdd_bit);
+
+	spin_lock_irqsave(&host->lock, flags);
 
 	if (host->ops->platform_send_init_74_clocks)
 		host->ops->platform_send_init_74_clocks(host, ios->power_mode);
@@ -1442,7 +1487,6 @@
 	if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS)
 		sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
 
-out:
 	mmiowb();
 	spin_unlock_irqrestore(&host->lock, flags);
 }
@@ -1572,6 +1616,8 @@
 		/* Set 1.8V Signal Enable in the Host Control2 register to 0 */
 		ctrl &= ~SDHCI_CTRL_VDD_180;
 		sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
+		if (host->ops->check_power_status)
+			host->ops->check_power_status(host);
 
 		/* Wait for 5ms */
 		usleep_range(5000, 5500);
@@ -1581,7 +1627,7 @@
 		if (!(ctrl & SDHCI_CTRL_VDD_180))
 			return 0;
 		else {
-			printk(KERN_INFO DRIVER_NAME ": Switching to 3.3V "
+			pr_info(DRIVER_NAME ": Switching to 3.3V "
 				"signalling voltage failed\n");
 			return -EIO;
 		}
@@ -1602,6 +1648,8 @@
 			 */
 			ctrl |= SDHCI_CTRL_VDD_180;
 			sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
+			if (host->ops->check_power_status)
+				host->ops->check_power_status(host);
 
 			/* Wait for 5ms */
 			usleep_range(5000, 5500);
@@ -1634,13 +1682,17 @@
 		pwr = sdhci_readb(host, SDHCI_POWER_CONTROL);
 		pwr &= ~SDHCI_POWER_ON;
 		sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
+		if (host->ops->check_power_status)
+			host->ops->check_power_status(host);
 
 		/* Wait for 1ms as per the spec */
 		usleep_range(1000, 1500);
 		pwr |= SDHCI_POWER_ON;
 		sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
+		if (host->ops->check_power_status)
+			host->ops->check_power_status(host);
 
-		printk(KERN_INFO DRIVER_NAME ": Switching to 1.8V signalling "
+		pr_info(DRIVER_NAME ": Switching to 1.8V signalling "
 			"voltage failed, retrying with S18R set to 0\n");
 		return -EAGAIN;
 	} else
@@ -1666,7 +1718,7 @@
 {
 	struct sdhci_host *host;
 	u16 ctrl;
-	u32 ier;
+	u32 ier = 0;
 	int tuning_loop_counter = MAX_TUNING_LOOP;
 	unsigned long timeout;
 	int err = 0;
@@ -1687,9 +1739,9 @@
 	 * If the Host Controller supports the HS200 mode then the
 	 * tuning function has to be executed.
 	 */
-	if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR50) &&
-	    (host->flags & SDHCI_SDR50_NEEDS_TUNING ||
-	     host->flags & SDHCI_HS200_NEEDS_TUNING))
+	if ((((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR50) &&
+	    (host->flags & SDHCI_SDR50_NEEDS_TUNING)) ||
+	     (host->flags & SDHCI_HS200_NEEDS_TUNING))
 		requires_tuning_nonuhs = true;
 
 	if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR104) ||
@@ -1702,6 +1754,14 @@
 		return 0;
 	}
 
+	if (host->ops->execute_tuning) {
+		spin_unlock(&host->lock);
+		enable_irq(host->irq);
+		host->ops->execute_tuning(host, opcode);
+		disable_irq(host->irq);
+		spin_lock(&host->lock);
+		goto out;
+	}
 	sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
 
 	/*
@@ -1780,7 +1840,7 @@
 		spin_lock(&host->lock);
 
 		if (!host->tuning_done) {
-			printk(KERN_INFO DRIVER_NAME ": Timeout waiting for "
+			pr_info(DRIVER_NAME ": Timeout waiting for "
 				"Buffer Read Ready interrupt during tuning "
 				"procedure, falling back to fixed sampling "
 				"clock\n");
@@ -1810,7 +1870,7 @@
 		sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
 	} else {
 		if (!(ctrl & SDHCI_CTRL_TUNED_CLK)) {
-			printk(KERN_INFO DRIVER_NAME ": Tuning procedure"
+			pr_info(DRIVER_NAME ": Tuning procedure"
 				" failed, falling back to fixed sampling"
 				" clock\n");
 			err = -EIO;
@@ -1925,9 +1985,9 @@
 	/* Check host->mrq first in case we are runtime suspended */
 	if (host->mrq &&
 	    !(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
-		printk(KERN_ERR "%s: Card removed during transfer!\n",
+		pr_err("%s: Card removed during transfer!\n",
 			mmc_hostname(host->mmc));
-		printk(KERN_ERR "%s: Resetting controller.\n",
+		pr_err("%s: Resetting controller.\n",
 			mmc_hostname(host->mmc));
 
 		sdhci_reset(host, SDHCI_RESET_CMD);
@@ -2016,7 +2076,7 @@
 	spin_lock_irqsave(&host->lock, flags);
 
 	if (host->mrq) {
-		printk(KERN_ERR "%s: Timeout waiting for hardware "
+		pr_err("%s: Timeout waiting for hardware "
 			"interrupt.\n", mmc_hostname(host->mmc));
 		sdhci_dumpregs(host);
 
@@ -2062,7 +2122,7 @@
 	BUG_ON(intmask == 0);
 
 	if (!host->cmd) {
-		printk(KERN_ERR "%s: Got command interrupt 0x%08x even "
+		pr_err("%s: Got command interrupt 0x%08x even "
 			"though no command operation was in progress.\n",
 			mmc_hostname(host->mmc), (unsigned)intmask);
 		sdhci_dumpregs(host);
@@ -2164,7 +2224,7 @@
 			}
 		}
 
-		printk(KERN_ERR "%s: Got data interrupt 0x%08x even "
+		pr_err("%s: Got data interrupt 0x%08x even "
 			"though no data operation was in progress.\n",
 			mmc_hostname(host->mmc), (unsigned)intmask);
 		sdhci_dumpregs(host);
@@ -2181,7 +2241,7 @@
 			!= MMC_BUS_TEST_R)
 		host->data->error = -EILSEQ;
 	else if (intmask & SDHCI_INT_ADMA_ERROR) {
-		printk(KERN_ERR "%s: ADMA error\n", mmc_hostname(host->mmc));
+		pr_err("%s: ADMA error\n", mmc_hostname(host->mmc));
 		sdhci_show_adma_error(host);
 		host->data->error = -EIO;
 	}
@@ -2245,7 +2305,7 @@
 
 	if (host->runtime_suspended) {
 		spin_unlock(&host->lock);
-		printk(KERN_WARNING "%s: got irq while runtime suspended\n",
+		pr_warning("%s: got irq while runtime suspended\n",
 		       mmc_hostname(host->mmc));
 		return IRQ_HANDLED;
 	}
@@ -2262,13 +2322,30 @@
 		mmc_hostname(host->mmc), intmask);
 
 	if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
+		u32 present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
+			      SDHCI_CARD_PRESENT;
+
+		/*
+		 * There is a observation on i.mx esdhc.  INSERT bit will be
+		 * immediately set again when it gets cleared, if a card is
+		 * inserted.  We have to mask the irq to prevent interrupt
+		 * storm which will freeze the system.  And the REMOVE gets
+		 * the same situation.
+		 *
+		 * More testing are needed here to ensure it works for other
+		 * platforms though.
+		 */
+		sdhci_mask_irqs(host, present ? SDHCI_INT_CARD_INSERT :
+						SDHCI_INT_CARD_REMOVE);
+		sdhci_unmask_irqs(host, present ? SDHCI_INT_CARD_REMOVE :
+						  SDHCI_INT_CARD_INSERT);
+
 		sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
-			SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
+			     SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
+		intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE);
 		tasklet_schedule(&host->card_tasklet);
 	}
 
-	intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE);
-
 	if (intmask & SDHCI_INT_CMD_MASK) {
 		sdhci_writel(host, intmask & SDHCI_INT_CMD_MASK,
 			SDHCI_INT_STATUS);
@@ -2286,7 +2363,7 @@
 	intmask &= ~SDHCI_INT_ERROR;
 
 	if (intmask & SDHCI_INT_BUS_POWER) {
-		printk(KERN_ERR "%s: Card is consuming too much power!\n",
+		pr_err("%s: Card is consuming too much power!\n",
 			mmc_hostname(host->mmc));
 		sdhci_writel(host, SDHCI_INT_BUS_POWER, SDHCI_INT_STATUS);
 	}
@@ -2299,9 +2376,6 @@
 	intmask &= ~SDHCI_INT_CARD_INT;
 
 	if (intmask) {
-		printk(KERN_ERR "%s: Unexpected interrupt 0x%08x.\n",
-			mmc_hostname(host->mmc), intmask);
-		sdhci_dumpregs(host);
 		unexpected |= intmask;
 		sdhci_writel(host, intmask, SDHCI_INT_STATUS);
 	}
@@ -2339,6 +2413,7 @@
 int sdhci_suspend_host(struct sdhci_host *host)
 {
 	int ret;
+	bool has_tuning_timer;
 
 	if (host->ops->platform_suspend)
 		host->ops->platform_suspend(host);
@@ -2346,21 +2421,28 @@
 	sdhci_disable_card_detection(host);
 
 	/* Disable tuning since we are suspending */
-	if (host->version >= SDHCI_SPEC_300 && host->tuning_count &&
-	    host->tuning_mode == SDHCI_TUNING_MODE_1) {
+	has_tuning_timer = host->version >= SDHCI_SPEC_300 &&
+		host->tuning_count && host->tuning_mode == SDHCI_TUNING_MODE_1;
+	if (has_tuning_timer) {
 		del_timer_sync(&host->tuning_timer);
 		host->flags &= ~SDHCI_NEEDS_RETUNING;
 	}
 
 	ret = mmc_suspend_host(host->mmc);
-	if (ret)
+	if (ret) {
+		if (has_tuning_timer) {
+			host->flags |= SDHCI_NEEDS_RETUNING;
+			mod_timer(&host->tuning_timer, jiffies +
+					host->tuning_count * HZ);
+		}
+
+		sdhci_enable_card_detection(host);
+
 		return ret;
+	}
 
 	free_irq(host->irq, host);
 
-	if (host->vmmc)
-		ret = regulator_disable(host->vmmc);
-
 	return ret;
 }
 
@@ -2370,12 +2452,6 @@
 {
 	int ret;
 
-	if (host->vmmc) {
-		int ret = regulator_enable(host->vmmc);
-		if (ret)
-			return ret;
-	}
-
 	if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
 		if (host->ops->enable_dma)
 			host->ops->enable_dma(host);
@@ -2561,7 +2637,7 @@
 	host->version = (host->version & SDHCI_SPEC_VER_MASK)
 				>> SDHCI_SPEC_VER_SHIFT;
 	if (host->version > SDHCI_SPEC_300) {
-		printk(KERN_ERR "%s: Unknown controller version (%d). "
+		pr_err("%s: Unknown controller version (%d). "
 			"You may experience problems.\n", mmc_hostname(mmc),
 			host->version);
 	}
@@ -2598,7 +2674,7 @@
 	if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
 		if (host->ops->enable_dma) {
 			if (host->ops->enable_dma(host)) {
-				printk(KERN_WARNING "%s: No suitable DMA "
+				pr_warning("%s: No suitable DMA "
 					"available. Falling back to PIO.\n",
 					mmc_hostname(mmc));
 				host->flags &=
@@ -2618,7 +2694,7 @@
 		if (!host->adma_desc || !host->align_buffer) {
 			kfree(host->adma_desc);
 			kfree(host->align_buffer);
-			printk(KERN_WARNING "%s: Unable to allocate ADMA "
+			pr_warning("%s: Unable to allocate ADMA "
 				"buffers. Falling back to standard DMA.\n",
 				mmc_hostname(mmc));
 			host->flags &= ~SDHCI_USE_ADMA;
@@ -2646,46 +2722,13 @@
 	if (host->max_clk == 0 || host->quirks &
 			SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN) {
 		if (!host->ops->get_max_clock) {
-			printk(KERN_ERR
-			       "%s: Hardware doesn't specify base clock "
+			pr_err("%s: Hardware doesn't specify base clock "
 			       "frequency.\n", mmc_hostname(mmc));
 			return -ENODEV;
 		}
 		host->max_clk = host->ops->get_max_clock(host);
 	}
 
-	host->timeout_clk =
-		(caps[0] & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT;
-	if (host->timeout_clk == 0) {
-		if (host->ops->get_timeout_clock) {
-			host->timeout_clk = host->ops->get_timeout_clock(host);
-		} else if (!(host->quirks &
-				SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)) {
-			printk(KERN_ERR
-			       "%s: Hardware doesn't specify timeout clock "
-			       "frequency.\n", mmc_hostname(mmc));
-			return -ENODEV;
-		}
-	}
-	if (caps[0] & SDHCI_TIMEOUT_CLK_UNIT)
-		host->timeout_clk *= 1000;
-
- 	/*
-	 * In case of Host Controller v3.00, find out whether clock
-	 * multiplier is supported.
-	 */
-	host->clk_mul = (caps[1] & SDHCI_CLOCK_MUL_MASK) >>
-		SDHCI_CLOCK_MUL_SHIFT;
-
-	/*
-	 * In case the value in Clock Multiplier is 0, then programmable
-	 * clock mode is not supported, otherwise the actual clock
-	 * multiplier is one more than the value of Clock Multiplier
-	 * in the Capabilities Register.
-	 */
-	if (host->clk_mul)
-		host->clk_mul += 1;
-
 	/*
 	 * In case of Host Controller v3.00, find out whether clock
 	 * multiplier is supported.
@@ -2718,6 +2761,26 @@
 	} else
 		mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200;
 
+	host->timeout_clk =
+		(caps[0] & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT;
+	if (host->timeout_clk == 0) {
+		if (host->ops->get_timeout_clock) {
+			host->timeout_clk = host->ops->get_timeout_clock(host);
+		} else if (!(host->quirks &
+				SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)) {
+			pr_err("%s: Hardware doesn't specify timeout clock "
+			       "frequency.\n", mmc_hostname(mmc));
+			return -ENODEV;
+		}
+	}
+	if (caps[0] & SDHCI_TIMEOUT_CLK_UNIT)
+		host->timeout_clk *= 1000;
+
+	if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)
+		host->timeout_clk = mmc->f_max / 1000;
+
+	mmc->max_discard_to = (1 << 27) / host->timeout_clk;
+
 	mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23;
 
 	if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12)
@@ -2869,7 +2932,7 @@
 		mmc->ocr_avail_mmc &= host->ocr_avail_mmc;
 
 	if (mmc->ocr_avail == 0) {
-		printk(KERN_ERR "%s: Hardware doesn't report any "
+		pr_err("%s: Hardware doesn't report any "
 			"support voltages.\n", mmc_hostname(mmc));
 		return -ENODEV;
 	}
@@ -2917,7 +2980,7 @@
 		mmc->max_blk_size = (caps[0] & SDHCI_MAX_BLOCK_MASK) >>
 				SDHCI_MAX_BLOCK_SHIFT;
 		if (mmc->max_blk_size >= 3) {
-			printk(KERN_WARNING "%s: Invalid maximum block size, "
+			pr_warning("%s: Invalid maximum block size, "
 				"assuming 512 bytes\n", mmc_hostname(mmc));
 			mmc->max_blk_size = 0;
 		}
@@ -2956,10 +3019,8 @@
 
 	host->vmmc = regulator_get(mmc_dev(mmc), "vmmc");
 	if (IS_ERR(host->vmmc)) {
-		printk(KERN_INFO "%s: no vmmc regulator found\n", mmc_hostname(mmc));
+		pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc));
 		host->vmmc = NULL;
-	} else {
-		regulator_enable(host->vmmc);
 	}
 
 	sdhci_init(host, 0);
@@ -2985,7 +3046,7 @@
 
 	mmc_add_host(mmc);
 
-	printk(KERN_INFO "%s: SDHCI controller on %s [%s] using %s\n",
+	pr_info("%s: SDHCI controller on %s [%s] using %s\n",
 		mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)),
 		(host->flags & SDHCI_USE_ADMA) ? "ADMA" :
 		(host->flags & SDHCI_USE_SDMA) ? "DMA" : "PIO");
@@ -3018,7 +3079,7 @@
 		host->flags |= SDHCI_DEVICE_DEAD;
 
 		if (host->mrq) {
-			printk(KERN_ERR "%s: Controller removed during "
+			pr_err("%s: Controller removed during "
 				" transfer!\n", mmc_hostname(host->mmc));
 
 			host->mrq->cmd->error = -ENOMEDIUM;
@@ -3048,10 +3109,8 @@
 	tasklet_kill(&host->card_tasklet);
 	tasklet_kill(&host->finish_tasklet);
 
-	if (host->vmmc) {
-		regulator_disable(host->vmmc);
+	if (host->vmmc)
 		regulator_put(host->vmmc);
-	}
 
 	kfree(host->adma_desc);
 	kfree(host->align_buffer);
@@ -3077,9 +3136,9 @@
 
 static int __init sdhci_drv_init(void)
 {
-	printk(KERN_INFO DRIVER_NAME
+	pr_info(DRIVER_NAME
 		": Secure Digital Host Controller Interface driver\n");
-	printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n");
+	pr_info(DRIVER_NAME ": Copyright(c) Pierre Ossman\n");
 
 	return 0;
 }
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index f761f23..4f8d01d 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -277,6 +277,9 @@
 	void	(*hw_reset)(struct sdhci_host *host);
 	void	(*platform_suspend)(struct sdhci_host *host);
 	void	(*platform_resume)(struct sdhci_host *host);
+	void	(*check_power_status)(struct sdhci_host *host);
+	int	(*execute_tuning)(struct sdhci_host *host, u32 opcode);
+	void	(*toggle_cdr)(struct sdhci_host *host, bool enable);
 };
 
 #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
diff --git a/drivers/mtd/devices/msm_nand.c b/drivers/mtd/devices/msm_nand.c
index 5cace6b..3bd4c37 100644
--- a/drivers/mtd/devices/msm_nand.c
+++ b/drivers/mtd/devices/msm_nand.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/mtd/devices/msm_nand.h b/drivers/mtd/devices/msm_nand.h
index 8156b92..8ad2116 100644
--- a/drivers/mtd/devices/msm_nand.h
+++ b/drivers/mtd/devices/msm_nand.h
@@ -1,6 +1,6 @@
 /* drivers/mtd/devices/msm_nand.h
  *
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2011, The Linux Foundation. All rights reserved.
  * Copyright (C) 2007 Google, Inc.
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/drivers/mtd/devices/msm_qpic_nand.c b/drivers/mtd/devices/msm_qpic_nand.c
index 9a6cc80..f7e8c9f 100644
--- a/drivers/mtd/devices/msm_qpic_nand.c
+++ b/drivers/mtd/devices/msm_qpic_nand.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/mtd/tests/mtd_erasepart.c b/drivers/mtd/tests/mtd_erasepart.c
index 67f0f84..0e44df4 100644
--- a/drivers/mtd/tests/mtd_erasepart.c
+++ b/drivers/mtd/tests/mtd_erasepart.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, The Linux Foundation. All rights reserved.
  * Copyright (C) 2006-2008 Nokia Corporation
  *
  * This program is free software; you can redistribute it and/or modify it
diff --git a/drivers/net/ethernet/msm/Kconfig b/drivers/net/ethernet/msm/Kconfig
index 3fced2d..4e95614 100644
--- a/drivers/net/ethernet/msm/Kconfig
+++ b/drivers/net/ethernet/msm/Kconfig
@@ -42,6 +42,16 @@
 	help
 	  Debug stats on wakeup counts.
 
+config MSM_RMNET_WWAN
+	tristate "MSM RMNET WWAN Network Device"
+	depends on IPA
+	default n
+	help
+	  WWAN Network Driver
+	  Provides an API to embedded
+	  applications to send and receive
+	  the data to/from A2
+
 config QFEC
 	tristate "QFEC ethernet driver"
 	select MII
@@ -50,3 +60,9 @@
 	  This driver supports Ethernet in the FSM9xxx.
 	  To compile this driver as a module, choose M here: the
 	  module will be called qfec.
+
+config ECM_IPA
+	tristate "STD ECM LAN Driver support"
+	depends on IPA
+	help
+	  Allows LAN between Apps and tethered HOST on STD ECM
diff --git a/drivers/net/ethernet/msm/Makefile b/drivers/net/ethernet/msm/Makefile
index 7d9d4c6..0afa00f 100644
--- a/drivers/net/ethernet/msm/Makefile
+++ b/drivers/net/ethernet/msm/Makefile
@@ -3,7 +3,9 @@
 #
 
 obj-$(CONFIG_MSM_RMNET) += msm_rmnet.o
+obj-$(CONFIG_MSM_RMNET_WWAN) += msm_rmnet_wwan.o
 obj-$(CONFIG_MSM_RMNET_SDIO) += msm_rmnet_sdio.o
 obj-$(CONFIG_MSM_RMNET_BAM) += msm_rmnet_bam.o
 obj-$(CONFIG_MSM_RMNET_SMUX) += msm_rmnet_smux.o
 obj-$(CONFIG_QFEC) += qfec.o
+obj-$(CONFIG_ECM_IPA) += ecm_ipa.o
diff --git a/drivers/net/ethernet/msm/ecm_ipa.c b/drivers/net/ethernet/msm/ecm_ipa.c
new file mode 100644
index 0000000..605fd84
--- /dev/null
+++ b/drivers/net/ethernet/msm/ecm_ipa.c
@@ -0,0 +1,1105 @@
+/* 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/debugfs.h>
+#include <linux/errno.h>
+#include <linux/etherdevice.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <mach/ecm_ipa.h>
+
+#define DRIVER_NAME "ecm_ipa"
+#define DRIVER_VERSION "19-Feb-2013"
+#define ECM_IPA_IPV4_HDR_NAME "ecm_eth_ipv4"
+#define ECM_IPA_IPV6_HDR_NAME "ecm_eth_ipv6"
+#define IPA_TO_USB_CLIENT	IPA_CLIENT_USB_CONS
+#define INACTIVITY_MSEC_DELAY 100
+#define ECM_IPA_ERROR(fmt, args...) \
+	pr_err(DRIVER_NAME "@%s@%d@ctx:%s: "\
+			fmt, __func__, __LINE__, current->comm, ## args)
+#ifdef ECM_IPA_DEBUG_ON
+#define ECM_IPA_DEBUG(fmt, args...) \
+	pr_err(DRIVER_NAME "@%s@%d@ctx:%s: "\
+			fmt, __func__, __LINE__, current->comm, ## args)
+#else /* ECM_IPA_DEBUG_ON */
+#define ECM_IPA_DEBUG(fmt, args...)
+#endif /* ECM_IPA_DEBUG_ON */
+
+#define NULL_CHECK(ptr) \
+	do { \
+		if (!(ptr)) { \
+			ECM_IPA_ERROR("null pointer #ptr\n"); \
+			return -EINVAL; \
+		} \
+	} \
+	while (0)
+
+#define ECM_IPA_LOG_ENTRY() ECM_IPA_DEBUG("begin\n")
+#define ECM_IPA_LOG_EXIT() ECM_IPA_DEBUG("end\n")
+
+/**
+ * struct ecm_ipa_dev - main driver context parameters
+ * @ack_spinlock: protect last sent skb
+ * @last_out_skb: last sent skb saved until Tx notify is received from IPA
+ * @net: network interface struct implemented by this driver
+ * @folder: debugfs folder for various debuging switches
+ * @tx_enable: flag that enable/disable Tx path to continue to IPA
+ * @rx_enable: flag that enable/disable Rx path to continue to IPA
+ * @rm_enable: flag that enable/disable Resource manager request prior to Tx
+ * @dma_enable: flag that allow on-the-fly DMA mode for IPA
+ * @tx_file: saved debugfs entry to allow cleanup
+ * @rx_file: saved debugfs entry to allow cleanup
+ * @rm_file: saved debugfs entry to allow cleanup
+ * @dma_file: saved debugfs entry to allow cleanup
+ * @eth_ipv4_hdr_hdl: saved handle for ipv4 header-insertion table
+ * @eth_ipv6_hdr_hdl: saved handle for ipv6 header-insertion table
+ * @usb_to_ipa_hdl: save handle for IPA pipe operations
+ * @ipa_to_usb_hdl: save handle for IPA pipe operations
+ */
+struct ecm_ipa_dev {
+	spinlock_t ack_spinlock;
+	struct sk_buff *last_out_skb;
+	struct net_device *net;
+	bool tx_enable;
+	bool rx_enable;
+	bool rm_enable;
+	bool dma_enable;
+	struct dentry *folder;
+	struct dentry *tx_file;
+	struct dentry *rx_file;
+	struct dentry *rm_file;
+	struct dentry *dma_file;
+	uint32_t eth_ipv4_hdr_hdl;
+	uint32_t eth_ipv6_hdr_hdl;
+	u32 usb_to_ipa_hdl;
+	u32 ipa_to_usb_hdl;
+};
+
+/**
+ * struct ecm_ipa_ctx - saved pointer for the std ecm network device
+ *                which allow ecm_ipa to be a singleton
+ */
+static struct ecm_ipa_dev *ecm_ipa_ctx;
+
+static int ecm_ipa_ep_registers_cfg(u32 usb_to_ipa_hdl, u32 ipa_to_usb_hdl);
+static void sk_buff_print(struct sk_buff *skb);
+static int ecm_ipa_set_device_ethernet_addr(
+	u8 *dev_ethaddr, u8 device_ethaddr[]);
+static void ecm_ipa_packet_receive_notify(void *priv,
+		enum ipa_dp_evt_type evt,
+		unsigned long data);
+static void ecm_ipa_tx_complete_notify(void *priv,
+		enum ipa_dp_evt_type evt,
+		unsigned long data);
+static int ecm_ipa_ep_registers_dma_cfg(u32 usb_to_ipa_hdl);
+static int ecm_ipa_open(struct net_device *net);
+static int ecm_ipa_stop(struct net_device *net);
+static netdev_tx_t ecm_ipa_start_xmit(struct sk_buff *skb,
+					struct net_device *net);
+static void ecm_ipa_rm_notify(void *user_data, enum ipa_rm_event event,
+		unsigned long data);
+static int ecm_ipa_create_rm_resource(struct ecm_ipa_dev *dev);
+static void ecm_ipa_destory_rm_resource(void);
+static bool rx_filter(struct sk_buff *skb);
+static bool tx_filter(struct sk_buff *skb);
+static bool rm_enabled(struct ecm_ipa_dev *dev);
+
+static int ecm_ipa_rules_cfg(struct ecm_ipa_dev *dev,
+		const void *dst_mac, const void *src_mac);
+static int ecm_ipa_register_tx(struct ecm_ipa_dev *dev);
+static void ecm_ipa_deregister_tx(struct ecm_ipa_dev *dev);
+static int ecm_ipa_debugfs_init(struct ecm_ipa_dev *dev);
+static void ecm_ipa_debugfs_destroy(struct ecm_ipa_dev *dev);
+static int ecm_ipa_debugfs_tx_open(struct inode *inode, struct file *file);
+static int ecm_ipa_debugfs_rx_open(struct inode *inode, struct file *file);
+static int ecm_ipa_debugfs_rm_open(struct inode *inode, struct file *file);
+static int ecm_ipa_debugfs_dma_open(struct inode *inode, struct file *file);
+static ssize_t ecm_ipa_debugfs_enable_read(struct file *file,
+		char __user *ubuf, size_t count, loff_t *ppos);
+static ssize_t ecm_ipa_debugfs_enable_write(struct file *file,
+		const char __user *buf, size_t count, loff_t *ppos);
+static ssize_t ecm_ipa_debugfs_enable_write_dma(struct file *file,
+		const char __user *buf, size_t count, loff_t *ppos);
+static void eth_get_drvinfo(struct net_device *net,
+		struct ethtool_drvinfo *drv_info);
+
+static const struct net_device_ops ecm_ipa_netdev_ops = {
+	.ndo_open		= ecm_ipa_open,
+	.ndo_stop		= ecm_ipa_stop,
+	.ndo_start_xmit = ecm_ipa_start_xmit,
+	.ndo_set_mac_address = eth_mac_addr,
+};
+static const struct ethtool_ops ops = {
+	.get_drvinfo = eth_get_drvinfo,
+	.get_link = ethtool_op_get_link,
+};
+const struct file_operations ecm_ipa_debugfs_tx_ops = {
+	.open = ecm_ipa_debugfs_tx_open,
+	.read = ecm_ipa_debugfs_enable_read,
+	.write = ecm_ipa_debugfs_enable_write,
+};
+const struct file_operations ecm_ipa_debugfs_rx_ops = {
+	.open = ecm_ipa_debugfs_rx_open,
+	.read = ecm_ipa_debugfs_enable_read,
+	.write = ecm_ipa_debugfs_enable_write,
+};
+const struct file_operations ecm_ipa_debugfs_rm_ops = {
+	.open = ecm_ipa_debugfs_rm_open,
+	.read = ecm_ipa_debugfs_enable_read,
+	.write = ecm_ipa_debugfs_enable_write,
+};
+const struct file_operations ecm_ipa_debugfs_dma_ops = {
+	.open = ecm_ipa_debugfs_dma_open,
+	.read = ecm_ipa_debugfs_enable_read,
+	.write = ecm_ipa_debugfs_enable_write_dma,
+};
+
+/**
+ * ecm_ipa_init() - initializes internal data structures
+ * @ecm_ipa_rx_dp_notify: supplied callback to be called by the IPA
+ * driver upon data packets received from USB pipe into IPA core.
+ * @ecm_ipa_rt_dp_notify: supplied callback to be called by the IPA
+ * driver upon exception packets sent from IPA pipe into USB core.
+ * @priv: should be passed later on to ecm_ipa_configure, hold the network
+ * structure allocated for STD ECM interface.
+ *
+ * Shall be called prior to pipe connection.
+ * The out parameters (the callbacks) shall be supplied to ipa_connect.
+ * Detailed description:
+ *  - set the callbacks to be used by the caller upon ipa_connect
+ *  - allocate the network device
+ *  - set the priv argument with a reference to the network device
+ *
+ * Returns negative errno, or zero on success
+ */
+int ecm_ipa_init(ecm_ipa_callback *ecm_ipa_rx_dp_notify,
+		ecm_ipa_callback *ecm_ipa_tx_dp_notify,
+		void **priv)
+{
+	int ret = 0;
+	struct net_device *net;
+	struct ecm_ipa_dev *dev;
+	ECM_IPA_LOG_ENTRY();
+	ECM_IPA_DEBUG("%s version %s\n", DRIVER_NAME, DRIVER_VERSION);
+	NULL_CHECK(ecm_ipa_rx_dp_notify);
+	NULL_CHECK(ecm_ipa_tx_dp_notify);
+	NULL_CHECK(priv);
+	net = alloc_etherdev(sizeof(struct ecm_ipa_dev));
+	if (!net) {
+		ret = -ENOMEM;
+		ECM_IPA_ERROR("fail to allocate etherdev\n");
+		goto fail_alloc_etherdev;
+	}
+	ECM_IPA_DEBUG("etherdev was successfully allocated\n");
+	dev = netdev_priv(net);
+	memset(dev, 0, sizeof(*dev));
+	dev->tx_enable = true;
+	dev->rx_enable = true;
+	spin_lock_init(&dev->ack_spinlock);
+	dev->net = net;
+	ecm_ipa_ctx = dev;
+	*priv = (void *)dev;
+	snprintf(net->name, sizeof(net->name), "%s%%d", "ecm");
+	net->netdev_ops = &ecm_ipa_netdev_ops;
+	ECM_IPA_DEBUG("internal data structures were intialized\n");
+	ret = ecm_ipa_debugfs_init(dev);
+	if (ret)
+		goto fail_debugfs;
+	ECM_IPA_DEBUG("debugfs entries were created\n");
+	*ecm_ipa_rx_dp_notify = ecm_ipa_packet_receive_notify;
+	*ecm_ipa_tx_dp_notify = ecm_ipa_tx_complete_notify;
+	ECM_IPA_LOG_EXIT();
+	return 0;
+fail_debugfs:
+	free_netdev(net);
+fail_alloc_etherdev:
+	return ret;
+}
+EXPORT_SYMBOL(ecm_ipa_init);
+
+/**
+ * ecm_ipa_rules_cfg() - set header insertion and register Tx/Rx properties
+ *				Headers will be commited to HW
+ * @dev: main driver context parameters
+ * @dst_mac: destination MAC address
+ * @src_mac: source MAC address
+ *
+ * Returns negative errno, or zero on success
+ */
+static int ecm_ipa_rules_cfg(struct ecm_ipa_dev *dev,
+		const void *dst_mac, const void *src_mac)
+{
+	struct ipa_ioc_add_hdr *hdrs;
+	struct ipa_hdr_add *ipv4_hdr;
+	struct ipa_hdr_add *ipv6_hdr;
+	struct ethhdr *eth_ipv4;
+	struct ethhdr *eth_ipv6;
+	int result = 0;
+
+	ECM_IPA_LOG_ENTRY();
+	hdrs = kzalloc(sizeof(*hdrs) + sizeof(*ipv4_hdr) + sizeof(*ipv6_hdr),
+			GFP_KERNEL);
+	if (!hdrs) {
+		result = -ENOMEM;
+		goto out;
+	}
+	ipv4_hdr = &hdrs->hdr[0];
+	eth_ipv4 = (struct ethhdr *)ipv4_hdr->hdr;
+	ipv6_hdr = &hdrs->hdr[1];
+	eth_ipv6 = (struct ethhdr *)ipv6_hdr->hdr;
+	strlcpy(ipv4_hdr->name, ECM_IPA_IPV4_HDR_NAME, IPA_RESOURCE_NAME_MAX);
+	memcpy(eth_ipv4->h_dest, dst_mac, ETH_ALEN);
+	memcpy(eth_ipv4->h_source, src_mac, ETH_ALEN);
+	eth_ipv4->h_proto = ETH_P_IP;
+	ipv4_hdr->hdr_len = ETH_HLEN;
+	ipv4_hdr->is_partial = 0;
+	strlcpy(ipv6_hdr->name, ECM_IPA_IPV6_HDR_NAME, IPA_RESOURCE_NAME_MAX);
+	memcpy(eth_ipv6->h_dest, dst_mac, ETH_ALEN);
+	memcpy(eth_ipv6->h_source, src_mac, ETH_ALEN);
+	eth_ipv6->h_proto = ETH_P_IPV6;
+	ipv6_hdr->hdr_len = ETH_HLEN;
+	ipv6_hdr->is_partial = 0;
+	hdrs->commit = 1;
+	hdrs->num_hdrs = 2;
+	result = ipa_add_hdr(hdrs);
+	if (result) {
+		ECM_IPA_ERROR("Fail on Header-Insertion(%d)\n", result);
+		goto out_free_mem;
+	}
+	if (ipv4_hdr->status) {
+		ECM_IPA_ERROR("Fail on Header-Insertion ipv4(%d)\n",
+				ipv4_hdr->status);
+		result = ipv4_hdr->status;
+		goto out_free_mem;
+	}
+	if (ipv6_hdr->status) {
+		ECM_IPA_ERROR("Fail on Header-Insertion ipv6(%d)\n",
+				ipv6_hdr->status);
+		result = ipv6_hdr->status;
+		goto out_free_mem;
+	}
+	dev->eth_ipv4_hdr_hdl = ipv4_hdr->hdr_hdl;
+	dev->eth_ipv6_hdr_hdl = ipv6_hdr->hdr_hdl;
+	ECM_IPA_LOG_EXIT();
+out_free_mem:
+	kfree(hdrs);
+out:
+	return result;
+}
+
+static void ecm_ipa_rules_destroy(struct ecm_ipa_dev *dev)
+{
+	struct ipa_ioc_del_hdr *del_hdr;
+	struct ipa_hdr_del *ipv4;
+	struct ipa_hdr_del *ipv6;
+	int result;
+	del_hdr = kzalloc(sizeof(*del_hdr) + sizeof(*ipv4) +
+			sizeof(*ipv6), GFP_KERNEL);
+	if (!del_hdr)
+		return;
+	del_hdr->commit = 1;
+	del_hdr->num_hdls = 2;
+	ipv4 = &del_hdr->hdl[0];
+	ipv4->hdl = dev->eth_ipv4_hdr_hdl;
+	ipv6 = &del_hdr->hdl[1];
+	ipv6->hdl = dev->eth_ipv6_hdr_hdl;
+	result = ipa_del_hdr(del_hdr);
+	if (result || ipv4->status || ipv6->status)
+		ECM_IPA_ERROR("ipa_del_hdr failed");
+}
+
+static int ecm_ipa_register_tx(struct ecm_ipa_dev *dev)
+{
+	struct ipa_tx_intf tx_properties = {0};
+	struct ipa_ioc_tx_intf_prop properties[2] = { {0}, {0} };
+	struct ipa_ioc_tx_intf_prop *ipv4_property;
+	struct ipa_ioc_tx_intf_prop *ipv6_property;
+	int result = 0;
+	ECM_IPA_LOG_ENTRY();
+	tx_properties.prop = properties;
+	ipv4_property = &tx_properties.prop[0];
+	ipv4_property->ip = IPA_IP_v4;
+	ipv4_property->dst_pipe = IPA_TO_USB_CLIENT;
+	strlcpy(ipv4_property->hdr_name, ECM_IPA_IPV4_HDR_NAME,
+			IPA_RESOURCE_NAME_MAX);
+	ipv6_property = &tx_properties.prop[1];
+	ipv6_property->ip = IPA_IP_v6;
+	ipv6_property->dst_pipe = IPA_TO_USB_CLIENT;
+	strlcpy(ipv6_property->hdr_name, ECM_IPA_IPV6_HDR_NAME,
+			IPA_RESOURCE_NAME_MAX);
+	tx_properties.num_props = 2;
+	result = ipa_register_intf(dev->net->name, &tx_properties, NULL);
+	if (result)
+		ECM_IPA_ERROR("fail on Tx_prop registration\n");
+	ECM_IPA_LOG_EXIT();
+	return result;
+}
+
+static void ecm_ipa_deregister_tx(struct ecm_ipa_dev *dev)
+{
+	int result;
+	ECM_IPA_LOG_ENTRY();
+	result = ipa_deregister_intf(dev->net->name);
+	if (result)
+		ECM_IPA_DEBUG("Fail on Tx prop deregister\n");
+	ECM_IPA_LOG_EXIT();
+	return;
+}
+
+/**
+ * ecm_ipa_configure() - make IPA core end-point specific configuration
+ * @usb_to_ipa_hdl: handle of usb_to_ipa end-point for IPA driver
+ * @ipa_to_usb_hdl: handle of ipa_to_usb end-point for IPA driver
+ * @host_ethaddr: host Ethernet address in network order
+ * @device_ethaddr: device Ethernet address in network order
+ *
+ * Configure the usb_to_ipa and ipa_to_usb end-point registers
+ * - USB->IPA end-point: disable de-aggregation, enable link layer
+ *   header removal (Ethernet removal), source NATing and default routing.
+ * - IPA->USB end-point: disable aggregation, add link layer header (Ethernet)
+ * - allocate Ethernet device
+ * - register to Linux network stack
+ *
+ * Returns negative errno, or zero on success
+ */
+int ecm_ipa_configure(u8 host_ethaddr[], u8 device_ethaddr[],
+		void *priv)
+{
+	struct ecm_ipa_dev *dev = priv;
+	struct net_device *net;
+	int result;
+	ECM_IPA_LOG_ENTRY();
+	NULL_CHECK(host_ethaddr);
+	NULL_CHECK(host_ethaddr);
+	NULL_CHECK(dev);
+	net = dev->net;
+	NULL_CHECK(net);
+	ECM_IPA_DEBUG("host_ethaddr=%pM device_ethaddr=%pM\n",
+					host_ethaddr, device_ethaddr);
+	result = ecm_ipa_create_rm_resource(dev);
+	if (result) {
+		ECM_IPA_ERROR("fail on RM create\n");
+		return -EINVAL;
+	}
+	ECM_IPA_DEBUG("RM resource was created\n");
+	netif_carrier_off(dev->net);
+	result = ecm_ipa_set_device_ethernet_addr(net->dev_addr,
+			device_ethaddr);
+	if (result) {
+		ECM_IPA_ERROR("set device MAC failed\n");
+		goto fail_set_device_ethernet;
+	}
+	result = ecm_ipa_rules_cfg(dev, host_ethaddr, device_ethaddr);
+	if (result) {
+		ECM_IPA_ERROR("fail on ipa rules set\n");
+		goto fail_set_device_ethernet;
+	}
+	ECM_IPA_DEBUG("Ethernet header insertion was set\n");
+	result = ecm_ipa_register_tx(dev);
+	if (result) {
+		ECM_IPA_ERROR("fail on properties set\n");
+		goto fail_register_tx;
+	}
+	ECM_IPA_DEBUG("ECM Tx properties were registered\n");
+	result = register_netdev(net);
+	if (result) {
+		ECM_IPA_ERROR("register_netdev failed: %d\n", result);
+		goto fail_register_netdev;
+	}
+	ECM_IPA_DEBUG("register_netdev succeeded\n");
+	ECM_IPA_LOG_EXIT();
+	return 0;
+fail_register_netdev:
+	ecm_ipa_deregister_tx(dev);
+fail_register_tx:
+fail_set_device_ethernet:
+	ecm_ipa_rules_destroy(dev);
+	ecm_ipa_destory_rm_resource();
+	free_netdev(net);
+	return result;
+}
+EXPORT_SYMBOL(ecm_ipa_configure);
+
+int ecm_ipa_connect(u32 usb_to_ipa_hdl, u32 ipa_to_usb_hdl,
+		void *priv)
+{
+	struct ecm_ipa_dev *dev = priv;
+	ECM_IPA_LOG_ENTRY();
+	NULL_CHECK(priv);
+	ECM_IPA_DEBUG("usb_to_ipa_hdl = %d, ipa_to_usb_hdl = %d\n",
+					usb_to_ipa_hdl, ipa_to_usb_hdl);
+	if (!usb_to_ipa_hdl || usb_to_ipa_hdl >= IPA_CLIENT_MAX) {
+		ECM_IPA_ERROR("usb_to_ipa_hdl(%d) is not a valid ipa handle\n",
+				usb_to_ipa_hdl);
+		return -EINVAL;
+	}
+	if (!ipa_to_usb_hdl || ipa_to_usb_hdl >= IPA_CLIENT_MAX) {
+		ECM_IPA_ERROR("ipa_to_usb_hdl(%d) is not a valid ipa handle\n",
+				ipa_to_usb_hdl);
+		return -EINVAL;
+	}
+	dev->ipa_to_usb_hdl = ipa_to_usb_hdl;
+	dev->usb_to_ipa_hdl = usb_to_ipa_hdl;
+	ecm_ipa_ep_registers_cfg(usb_to_ipa_hdl, ipa_to_usb_hdl);
+	netif_carrier_on(dev->net);
+	if (!netif_carrier_ok(dev->net)) {
+		ECM_IPA_ERROR("netif_carrier_ok error\n");
+		return -EBUSY;
+	}
+	ECM_IPA_LOG_EXIT();
+	return 0;
+}
+EXPORT_SYMBOL(ecm_ipa_connect);
+
+int ecm_ipa_disconnect(void *priv)
+{
+	struct ecm_ipa_dev *dev = priv;
+	ECM_IPA_LOG_ENTRY();
+	NULL_CHECK(dev);
+	netif_carrier_off(dev->net);
+	ECM_IPA_LOG_EXIT();
+	return 0;
+}
+EXPORT_SYMBOL(ecm_ipa_disconnect);
+
+
+static void ecm_ipa_rm_notify(void *user_data, enum ipa_rm_event event,
+		unsigned long data)
+{
+	struct ecm_ipa_dev *dev = user_data;
+	ECM_IPA_LOG_ENTRY();
+	if (event == IPA_RM_RESOURCE_GRANTED &&
+			netif_queue_stopped(dev->net)) {
+		ECM_IPA_DEBUG("Resource Granted - waking queue\n");
+		netif_wake_queue(dev->net);
+	} else {
+		ECM_IPA_DEBUG("Resource released\n");
+	}
+	ECM_IPA_LOG_EXIT();
+}
+
+static int ecm_ipa_create_rm_resource(struct ecm_ipa_dev *dev)
+{
+	struct ipa_rm_create_params create_params = {0};
+	int result;
+	ECM_IPA_LOG_ENTRY();
+	create_params.name = IPA_RM_RESOURCE_STD_ECM_PROD;
+	create_params.reg_params.user_data = dev;
+	create_params.reg_params.notify_cb = ecm_ipa_rm_notify;
+	result = ipa_rm_create_resource(&create_params);
+	if (result) {
+		ECM_IPA_ERROR("Fail on ipa_rm_create_resource\n");
+		goto fail_rm_create;
+	}
+	ECM_IPA_DEBUG("rm client was created");
+
+	result = ipa_rm_inactivity_timer_init(IPA_RM_RESOURCE_STD_ECM_PROD,
+			INACTIVITY_MSEC_DELAY);
+	if (result) {
+		ECM_IPA_ERROR("Fail on ipa_rm_inactivity_timer_init\n");
+		goto fail_it;
+	}
+	ECM_IPA_DEBUG("rm_it client was created");
+	ECM_IPA_LOG_EXIT();
+	return 0;
+fail_it:
+fail_rm_create:
+	return result;
+}
+
+static void ecm_ipa_destory_rm_resource(void)
+{
+	ECM_IPA_LOG_ENTRY();
+	ipa_rm_inactivity_timer_destroy(IPA_RM_RESOURCE_STD_ECM_PROD);
+	ECM_IPA_LOG_EXIT();
+}
+
+static bool rx_filter(struct sk_buff *skb)
+{
+	struct ecm_ipa_dev *dev = netdev_priv(skb->dev);
+	return !dev->rx_enable;
+}
+
+static bool tx_filter(struct sk_buff *skb)
+{
+	struct ecm_ipa_dev *dev = netdev_priv(skb->dev);
+	return !dev->tx_enable;
+}
+
+static bool rm_enabled(struct ecm_ipa_dev *dev)
+{
+	return dev->rm_enable;
+}
+
+static int ecm_ipa_open(struct net_device *net)
+{
+	ECM_IPA_LOG_ENTRY();
+	netif_start_queue(net);
+	ECM_IPA_LOG_EXIT();
+	return 0;
+}
+
+static int ecm_ipa_stop(struct net_device *net)
+{
+	ECM_IPA_LOG_ENTRY();
+	ECM_IPA_DEBUG("stopping net device\n");
+	netif_stop_queue(net);
+	ECM_IPA_LOG_EXIT();
+	return 0;
+}
+
+/**
+ * ecm_ipa_cleanup() - destroys all
+ * ecm information
+ * @priv: main driver context parameters
+ *
+ */
+void ecm_ipa_cleanup(void *priv)
+{
+	struct ecm_ipa_dev *dev = priv;
+	ECM_IPA_LOG_ENTRY();
+	if (!dev) {
+		ECM_IPA_ERROR("dev NULL pointer\n");
+		return;
+	}
+	if (rm_enabled(dev)) {
+		ecm_ipa_destory_rm_resource();
+		ecm_ipa_debugfs_destroy(dev);
+	}
+	if (!dev->net) {
+		unregister_netdev(dev->net);
+		free_netdev(dev->net);
+	}
+	ECM_IPA_DEBUG("cleanup done\n");
+	ecm_ipa_ctx = NULL;
+	ECM_IPA_LOG_EXIT();
+	return ;
+}
+EXPORT_SYMBOL(ecm_ipa_cleanup);
+
+static int resource_request(struct ecm_ipa_dev *dev)
+{
+	int result = 0;
+	ECM_IPA_LOG_ENTRY();
+	if (!rm_enabled(dev))
+		goto out;
+	result = ipa_rm_inactivity_timer_request_resource(
+			IPA_RM_RESOURCE_STD_ECM_PROD);
+out:
+	ECM_IPA_LOG_EXIT();
+	return result;
+}
+
+static void resource_release(struct ecm_ipa_dev *dev)
+{
+	ECM_IPA_LOG_ENTRY();
+	if (!rm_enabled(dev))
+		goto out;
+	ipa_rm_inactivity_timer_release_resource(IPA_RM_RESOURCE_STD_ECM_PROD);
+out:
+	ECM_IPA_LOG_EXIT();
+}
+
+/**
+ * ecm_ipa_start_xmit() - send data from APPs to USB core via IPA core
+ * @skb: packet received from Linux stack
+ * @net: the network device being used to send this packet
+ *
+ * Several conditions needed in order to send the packet to IPA:
+ * - we are in a valid state were the queue is not stopped
+ * - Filter Tx switch is turned off
+ * - The resources required for actual Tx are all up
+ *
+ */
+static netdev_tx_t ecm_ipa_start_xmit(struct sk_buff *skb,
+					struct net_device *net)
+{
+	int ret;
+	netdev_tx_t status = NETDEV_TX_BUSY;
+	struct ecm_ipa_dev *dev = netdev_priv(net);
+	unsigned long flags;
+	ECM_IPA_LOG_ENTRY();
+	if (unlikely(netif_queue_stopped(net))) {
+		ECM_IPA_ERROR("interface queue is stopped\n");
+		goto out;
+	}
+	ECM_IPA_DEBUG("send (proto=0x%04x)\n", ntohs(skb->protocol));
+	if (unlikely(tx_filter(skb))) {
+		dev_kfree_skb_any(skb);
+		ECM_IPA_ERROR("packet got filtered out on Tx path\n");
+		status = NETDEV_TX_OK;
+		goto out;
+	}
+	ret = resource_request(dev);
+	if (ret) {
+		ECM_IPA_DEBUG("Waiting to resource\n");
+		netif_stop_queue(net);
+		goto resource_busy;
+	}
+	ECM_IPA_DEBUG("taking ack_lock\n");
+	spin_lock_irqsave(&dev->ack_spinlock, flags);
+	ECM_IPA_DEBUG("ack_lock taken\n");
+	if (dev->last_out_skb) {
+		ECM_IPA_DEBUG("No Tx-ack received for previous packet\n");
+		ECM_IPA_DEBUG("releasing ack_lock\n");
+		spin_unlock_irqrestore(&dev->ack_spinlock, flags);
+		ECM_IPA_DEBUG("ack_lock released\n");
+		netif_stop_queue(net);
+		status = -NETDEV_TX_BUSY;
+		goto out;
+	} else {
+		dev->last_out_skb = skb;
+	}
+	ECM_IPA_DEBUG("releasing ack_lock\n");
+	spin_unlock_irqrestore(&dev->ack_spinlock, flags);
+	ECM_IPA_DEBUG("ack_lock released\n");
+	sk_buff_print(skb);
+	ECM_IPA_DEBUG("ipa_tx_dp is called (dst_client=%d)\n",
+			IPA_TO_USB_CLIENT);
+	ret = ipa_tx_dp(IPA_TO_USB_CLIENT, skb, NULL);
+	if (ret) {
+		ECM_IPA_ERROR("ipa transmit failed (%d)\n", ret);
+		goto fail_tx_packet;
+	}
+	net->stats.tx_packets++;
+	net->stats.tx_bytes += skb->len;
+	ECM_IPA_LOG_EXIT();
+	status = NETDEV_TX_OK;
+	goto out;
+fail_tx_packet:
+out:
+	resource_release(dev);
+resource_busy:
+	ECM_IPA_LOG_EXIT();
+	return status;
+}
+
+/**
+ * ecm_ipa_packet_receive_notify() - Rx notify
+ *
+ * @priv: ecm driver context
+ * @evt: event type
+ * @data: data provided with event
+ *
+ * IPA will pass a packet with skb->data pointing to Ethernet packet frame
+ */
+void ecm_ipa_packet_receive_notify(void *priv,
+		enum ipa_dp_evt_type evt,
+		unsigned long data)
+{
+	struct sk_buff *skb = (struct sk_buff *)data;
+	struct ecm_ipa_dev *dev = priv;
+	int result;
+	ECM_IPA_LOG_ENTRY();
+	if (evt != IPA_RECEIVE)	{
+		ECM_IPA_ERROR("A none IPA_RECEIVE event in ecm_ipa_receive\n");
+		return;
+	}
+	ECM_IPA_DEBUG("receive\n");
+	sk_buff_print(skb);
+	skb->dev = dev->net;
+	skb->protocol = eth_type_trans(skb, dev->net);
+	if (rx_filter(skb)) {
+		ECM_IPA_ERROR("packet got filtered out on Rx path\n");
+		dev_kfree_skb_any(skb);
+		return;
+	}
+	ECM_IPA_DEBUG("kernel stack Rx is called\n");
+	result = netif_rx(skb);
+	if (result)
+		ECM_IPA_ERROR("fail on netif_rx\n");
+	dev->net->stats.rx_packets++;
+	dev->net->stats.rx_bytes += skb->len;
+	ECM_IPA_LOG_EXIT();
+	return;
+}
+
+/**
+ * ecm_ipa_tx_complete_notify() - Rx notify
+ *
+ * @priv: ecm driver context
+ * @evt: event type
+ * @data: data provided with event
+ *
+ * Check that the packet is the one we sent and release it
+ * This function will be called in defered context in IPA wq.
+ */
+void ecm_ipa_tx_complete_notify(void *priv,
+		enum ipa_dp_evt_type evt,
+		unsigned long data)
+{
+	struct sk_buff *skb = (struct sk_buff *)data;
+	struct ecm_ipa_dev *dev = priv;
+	unsigned long flags;
+	ECM_IPA_LOG_ENTRY();
+
+	if (!dev) {
+		ECM_IPA_ERROR("dev is NULL pointer\n");
+		return;
+	}
+	if (evt != IPA_WRITE_DONE) {
+		ECM_IPA_ERROR("unsupported event on Tx callback\n");
+		return;
+	}
+	ECM_IPA_DEBUG("taking ack_lock\n");
+	spin_lock_irqsave(&dev->ack_spinlock, flags);
+	ECM_IPA_DEBUG("ack_lock taken\n");
+	if (skb != dev->last_out_skb)
+		ECM_IPA_ERROR("ACKed/Sent not the same(FIFO expected)\n");
+	dev->last_out_skb = NULL;
+	ECM_IPA_DEBUG("releasing ack_lock\n");
+	spin_unlock_irqrestore(&dev->ack_spinlock, flags);
+	ECM_IPA_DEBUG("ack_lock released\n");
+	if (netif_queue_stopped(dev->net)) {
+		ECM_IPA_DEBUG("waking up queue\n");
+		netif_wake_queue(dev->net);
+	}
+	dev_kfree_skb_any(skb);
+	ECM_IPA_LOG_EXIT();
+	return;
+}
+
+static int ecm_ipa_debugfs_tx_open(struct inode *inode, struct file *file)
+{
+	struct ecm_ipa_dev *dev = inode->i_private;
+	ECM_IPA_LOG_ENTRY();
+	file->private_data = &(dev->tx_enable);
+	ECM_IPA_LOG_ENTRY();
+	return 0;
+}
+
+static int ecm_ipa_debugfs_rx_open(struct inode *inode, struct file *file)
+{
+	struct ecm_ipa_dev *dev = inode->i_private;
+	ECM_IPA_LOG_ENTRY();
+	file->private_data = &(dev->rx_enable);
+	ECM_IPA_LOG_EXIT();
+	return 0;
+}
+
+static int ecm_ipa_debugfs_rm_open(struct inode *inode, struct file *file)
+{
+	struct ecm_ipa_dev *dev = inode->i_private;
+	ECM_IPA_LOG_ENTRY();
+	file->private_data = &(dev->rm_enable);
+	ECM_IPA_LOG_EXIT();
+	return 0;
+}
+
+static ssize_t ecm_ipa_debugfs_enable_write_dma(struct file *file,
+		const char __user *buf, size_t count, loff_t *ppos)
+{
+	struct ecm_ipa_dev *dev = file->private_data;
+	int result;
+	ECM_IPA_LOG_ENTRY();
+	file->private_data = &dev->dma_enable;
+	result = ecm_ipa_debugfs_enable_write(file, buf, count, ppos);
+	if (dev->dma_enable)
+		ecm_ipa_ep_registers_dma_cfg(dev->usb_to_ipa_hdl);
+	else
+		ecm_ipa_ep_registers_cfg(dev->usb_to_ipa_hdl,
+				dev->usb_to_ipa_hdl);
+	ECM_IPA_LOG_EXIT();
+	return result;
+}
+
+static int ecm_ipa_debugfs_dma_open(struct inode *inode, struct file *file)
+{
+	struct ecm_ipa_dev *dev = inode->i_private;
+	ECM_IPA_LOG_ENTRY();
+	file->private_data = dev;
+	ECM_IPA_LOG_EXIT();
+	return 0;
+}
+
+static ssize_t ecm_ipa_debugfs_enable_write(struct file *file,
+		const char __user *buf, size_t count, loff_t *ppos)
+{
+	unsigned long missing;
+	char input;
+	bool *enable = file->private_data;
+	if (count != sizeof(input) + 1) {
+		ECM_IPA_ERROR("wrong input length(%zd)\n", count);
+		return -EINVAL;
+	}
+	if (!buf) {
+		ECM_IPA_ERROR("Bad argument\n");
+		return -EINVAL;
+	}
+	missing = copy_from_user(&input, buf, 1);
+	if (missing)
+		return -EFAULT;
+	ECM_IPA_DEBUG("input received %c\n", input);
+	*enable = input - '0';
+	ECM_IPA_DEBUG("value was set to %d\n", *enable);
+	return count;
+}
+
+static ssize_t ecm_ipa_debugfs_enable_read(struct file *file,
+		char __user *ubuf, size_t count, loff_t *ppos)
+{
+	int nbytes;
+	int size = 0;
+	int ret;
+	loff_t pos;
+	u8 enable_str[sizeof(char)*3] = {0};
+	bool *enable = file->private_data;
+	pos = *ppos;
+	nbytes = scnprintf(enable_str, sizeof(enable_str), "%d\n", *enable);
+	ret = simple_read_from_buffer(ubuf, count, ppos, enable_str, nbytes);
+	if (ret < 0) {
+		ECM_IPA_ERROR("simple_read_from_buffer problem");
+		return ret;
+	}
+	size += ret;
+	count -= nbytes;
+	*ppos = pos + size;
+	return size;
+}
+
+static int ecm_ipa_debugfs_init(struct ecm_ipa_dev *dev)
+{
+	const mode_t flags = S_IRUSR | S_IRGRP | S_IROTH |
+			S_IWUSR | S_IWGRP | S_IWOTH;
+	int ret = -EINVAL;
+	ECM_IPA_LOG_ENTRY();
+	if (!dev)
+		return -EINVAL;
+	dev->folder = debugfs_create_dir("ecm_ipa", NULL);
+	if (!dev->folder) {
+		ECM_IPA_ERROR("could not create debugfs folder entry\n");
+		ret = -EFAULT;
+		goto fail_folder;
+	}
+	dev->tx_file = debugfs_create_file("tx_enable", flags, dev->folder, dev,
+		   &ecm_ipa_debugfs_tx_ops);
+	if (!dev->tx_file) {
+		ECM_IPA_ERROR("could not create debugfs tx file\n");
+		ret = -EFAULT;
+		goto fail_file;
+	}
+	dev->rx_file = debugfs_create_file("rx_enable", flags, dev->folder, dev,
+			&ecm_ipa_debugfs_rx_ops);
+	if (!dev->rx_file) {
+		ECM_IPA_ERROR("could not create debugfs rx file\n");
+		ret = -EFAULT;
+		goto fail_file;
+	}
+	dev->rm_file = debugfs_create_file("rm_enable", flags, dev->folder, dev,
+			&ecm_ipa_debugfs_rm_ops);
+	if (!dev->rm_file) {
+		ECM_IPA_ERROR("could not create debugfs rm file\n");
+		ret = -EFAULT;
+		goto fail_file;
+	}
+	dev->dma_file = debugfs_create_file("dma_enable", flags, dev->folder,
+			dev, &ecm_ipa_debugfs_dma_ops);
+	if (!dev->dma_file) {
+		ECM_IPA_ERROR("could not create debugfs dma file\n");
+		ret = -EFAULT;
+		goto fail_file;
+	}
+	ECM_IPA_LOG_EXIT();
+	return 0;
+fail_file:
+	debugfs_remove_recursive(dev->folder);
+fail_folder:
+	return ret;
+}
+
+static void ecm_ipa_debugfs_destroy(struct ecm_ipa_dev *dev)
+{
+	debugfs_remove_recursive(dev->folder);
+}
+
+static void eth_get_drvinfo(struct net_device *net,
+		struct ethtool_drvinfo *drv_info)
+{
+	ECM_IPA_LOG_ENTRY();
+	strlcpy(drv_info->driver, DRIVER_NAME, sizeof(drv_info->driver));
+	strlcpy(drv_info->version, DRIVER_VERSION, sizeof(drv_info->version));
+	ECM_IPA_LOG_EXIT();
+}
+
+
+/**
+ * ecm_ipa_ep_cfg() - configure the USB endpoints for ECM
+ *
+ *usb_to_ipa_hdl: handle received from ipa_connect
+ *ipa_to_usb_hdl: handle received from ipa_connect
+ *
+ * USB to IPA pipe:
+ *  - No de-aggregation
+ *  - Remove Ethernet header
+ *  - SRC NAT
+ *  - Default routing(0)
+ * IPA to USB Pipe:
+ *  - No aggregation
+ *  - Add Ethernet header
+ */
+int ecm_ipa_ep_registers_cfg(u32 usb_to_ipa_hdl, u32 ipa_to_usb_hdl)
+{
+	int result = 0;
+	struct ipa_ep_cfg usb_to_ipa_ep_cfg;
+	struct ipa_ep_cfg ipa_to_usb_ep_cfg;
+	ECM_IPA_LOG_ENTRY();
+	memset(&usb_to_ipa_ep_cfg, 0 , sizeof(struct ipa_ep_cfg));
+	usb_to_ipa_ep_cfg.aggr.aggr_en = IPA_BYPASS_AGGR;
+	usb_to_ipa_ep_cfg.hdr.hdr_len = ETH_HLEN;
+	usb_to_ipa_ep_cfg.nat.nat_en = IPA_SRC_NAT;
+	usb_to_ipa_ep_cfg.route.rt_tbl_hdl = 0;
+	usb_to_ipa_ep_cfg.mode.dst = IPA_CLIENT_A5_LAN_WAN_CONS;
+	usb_to_ipa_ep_cfg.mode.mode = IPA_BASIC;
+	result = ipa_cfg_ep(usb_to_ipa_hdl, &usb_to_ipa_ep_cfg);
+	if (result) {
+		ECM_IPA_ERROR("failed to configure USB to IPA point\n");
+		goto out;
+	}
+	memset(&ipa_to_usb_ep_cfg, 0 , sizeof(struct ipa_ep_cfg));
+	ipa_to_usb_ep_cfg.aggr.aggr_en = IPA_BYPASS_AGGR;
+	ipa_to_usb_ep_cfg.hdr.hdr_len = ETH_HLEN;
+	ipa_to_usb_ep_cfg.nat.nat_en = IPA_BYPASS_NAT;
+	result = ipa_cfg_ep(ipa_to_usb_hdl, &ipa_to_usb_ep_cfg);
+	if (result) {
+		ECM_IPA_ERROR("failed to configure IPA to USB end-point\n");
+		goto out;
+	}
+	ECM_IPA_DEBUG("end-point registers successfully configured\n");
+out:
+	ECM_IPA_LOG_EXIT();
+	return result;
+}
+
+/**
+ * ecm_ipa_ep_registers_dma_cfg() - configure the USB endpoints for ECM
+ *	DMA
+ * @usb_to_ipa_hdl: handle received from ipa_connect
+ *
+ * This function will override the previous configuration
+ * which is needed for cores that does not support blocks logic
+ * Note that client handles are the actual pipe index
+ */
+int ecm_ipa_ep_registers_dma_cfg(u32 usb_to_ipa_hdl)
+{
+	int result = 0;
+	struct ipa_ep_cfg_mode cfg_mode;
+	u32 apps_to_ipa_hdl = 2;
+	ECM_IPA_LOG_ENTRY();
+	/* Apps to IPA - override the configuration made by IPA driver
+	 * in order to allow data path on older platforms*/
+	memset(&cfg_mode, 0 , sizeof(cfg_mode));
+	cfg_mode.mode = IPA_DMA;
+	cfg_mode.dst = IPA_CLIENT_USB_CONS;
+	result = ipa_cfg_ep_mode(apps_to_ipa_hdl, &cfg_mode);
+	if (result) {
+		ECM_IPA_ERROR("failed to configure Apps to IPA\n");
+		goto out;
+	}
+	memset(&cfg_mode, 0 , sizeof(cfg_mode));
+	cfg_mode.mode = IPA_DMA;
+	cfg_mode.dst = IPA_CLIENT_A5_LAN_WAN_CONS;
+	result = ipa_cfg_ep_mode(usb_to_ipa_hdl, &cfg_mode);
+	if (result) {
+		ECM_IPA_ERROR("failed to configure USB to IPA\n");
+		goto out;
+	}
+	ECM_IPA_DEBUG("end-point registers successfully configured\n");
+out:
+	ECM_IPA_LOG_EXIT();
+	return result;
+}
+
+static void ecm_ipa_dump_buff(u8 *buff, u32 byte_size)
+{
+	int i;
+	ECM_IPA_DEBUG("ofst(hex), addr(hex), data(hex), value(char):\n");
+	for (i = 0 ; i < byte_size; i += 4) {
+		ECM_IPA_DEBUG("%2x  %p   %02x %02x %02x %02x | %c %c %c %c\n",
+				i, &buff[i],
+				buff[i], buff[i+1], buff[i+2], buff[i+3],
+				buff[i], buff[i+1], buff[i+2], buff[i+3]);
+	}
+}
+
+/**
+ * sk_buff_print() - detailed sk_buff printouts
+ * @skb: the socket buff
+ */
+void sk_buff_print(struct sk_buff *skb)
+{
+	ECM_IPA_DEBUG("called by: %s\n", current->comm);
+	ECM_IPA_DEBUG("skb->next=0x%p, skb->prev=0x%p, skb->sk=0x%p\n",
+			skb->next, skb->prev, skb->sk);
+	ECM_IPA_DEBUG("skb->len=0x%x, skb->data_len=0x%x protocol=0x%04x\n",
+				skb->len, skb->data_len, skb->protocol);
+	ECM_IPA_DEBUG("skb->mac_len=0x%x, skb->hdr_len=0x%x, skb->csum=%x\n",
+			skb->mac_len, skb->hdr_len, skb->csum);
+
+	ECM_IPA_DEBUG("mac_header = 0x%p\n", skb_mac_header(skb));
+	ECM_IPA_DEBUG("network_header = 0x%p\n", skb_network_header(skb));
+	ECM_IPA_DEBUG("transport_header=0x%p\n", skb_transport_header(skb));
+
+	ECM_IPA_DEBUG("skb->head=0x%p\n", skb->head);
+	ECM_IPA_DEBUG("skb->data=0x%p\n", skb->data);
+	ECM_IPA_DEBUG("tail=0x%p\n", skb_tail_pointer(skb));
+	ECM_IPA_DEBUG("end =0x%p\n", skb_end_pointer(skb));
+	ECM_IPA_DEBUG("skb->truesize=0x%x (buffer size)\n",
+				skb->truesize);
+	ecm_ipa_dump_buff(skb->data, skb->len);
+}
+
+/**
+ * ecm_ipa_set_device_ethernet_addr() - set device etherenet address
+ * @dev_ethaddr: device etherenet address
+ *
+ * Returns 0 for success, negative otherwise
+ */
+int ecm_ipa_set_device_ethernet_addr(u8 *dev_ethaddr, u8 device_ethaddr[])
+{
+	if (!is_valid_ether_addr(device_ethaddr))
+		return -EINVAL;
+	memcpy(dev_ethaddr, device_ethaddr, ETH_ALEN);
+	ECM_IPA_DEBUG("device ethernet address: %pM\n", dev_ethaddr);
+	return 0;
+}
+
+/**
+ * ecm_ipa_init_module() - module initialization
+ *
+ */
+static int ecm_ipa_init_module(void)
+{
+	ECM_IPA_LOG_ENTRY();
+	ECM_IPA_LOG_EXIT();
+	return 0;
+}
+
+/**
+ * ecm_ipa_cleanup_module() - module cleanup
+ *
+ */
+static void ecm_ipa_cleanup_module(void)
+{
+	ECM_IPA_LOG_ENTRY();
+	ECM_IPA_LOG_EXIT();
+	return;
+}
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("ECM IPA network interface");
+
+late_initcall(ecm_ipa_init_module);
+module_exit(ecm_ipa_cleanup_module);
diff --git a/drivers/net/ethernet/msm/msm_rmnet.c b/drivers/net/ethernet/msm/msm_rmnet.c
index cc9ed74..06f8cd4 100644
--- a/drivers/net/ethernet/msm/msm_rmnet.c
+++ b/drivers/net/ethernet/msm/msm_rmnet.c
@@ -3,7 +3,7 @@
  * Virtual Ethernet Interface for MSM7K Networking
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/drivers/net/ethernet/msm/msm_rmnet_bam.c b/drivers/net/ethernet/msm/msm_rmnet_bam.c
index 295c55c..83f486c 100644
--- a/drivers/net/ethernet/msm/msm_rmnet_bam.c
+++ b/drivers/net/ethernet/msm/msm_rmnet_bam.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -746,6 +746,112 @@
 	return 0;
 }
 
+/* support for 9 new rmnet ports */
+#define RMNET_REV_DEVICE_COUNT (9)
+static struct net_device *netdevs_rev[RMNET_REV_DEVICE_COUNT];
+static struct platform_driver bam_rmnet_rev_drivers[RMNET_REV_DEVICE_COUNT];
+
+static int bam_rmnet_rev_probe(struct platform_device *pdev)
+{
+	int i;
+	char name[BAM_DMUX_CH_NAME_MAX_LEN];
+	struct rmnet_private *p;
+
+	for (i = 0; i < RMNET_REV_DEVICE_COUNT; ++i) {
+		scnprintf(name, BAM_DMUX_CH_NAME_MAX_LEN, "bam_dmux_ch_%d",
+					(i+BAM_DMUX_DATA_REV_RMNET_0));
+		if (!strncmp(pdev->name, name, BAM_DMUX_CH_NAME_MAX_LEN))
+			break;
+	}
+
+	if (i >= RMNET_REV_DEVICE_COUNT) {
+		pr_err("%s: wrong netdev %s\n", __func__, pdev->name);
+		return 0;
+	}
+
+	p = netdev_priv(netdevs_rev[i]);
+	if (p->in_reset) {
+		p->in_reset = 0;
+		msm_bam_dmux_open(p->ch_id, netdevs_rev[i], bam_notify);
+		netif_carrier_on(netdevs_rev[i]);
+		netif_start_queue(netdevs_rev[i]);
+	}
+
+	return 0;
+}
+
+static int bam_rmnet_rev_remove(struct platform_device *pdev)
+{
+	int i;
+	char name[BAM_DMUX_CH_NAME_MAX_LEN];
+	struct rmnet_private *p;
+
+	for (i = 0; i < RMNET_REV_DEVICE_COUNT; ++i) {
+		scnprintf(name, BAM_DMUX_CH_NAME_MAX_LEN, "bam_dmux_ch_%d",
+				(i+BAM_DMUX_DATA_REV_RMNET_0));
+		if (!strncmp(pdev->name, name, BAM_DMUX_CH_NAME_MAX_LEN))
+			break;
+	}
+
+	if (i >= RMNET_REV_DEVICE_COUNT) {
+		pr_err("%s: wrong netdev %s\n", __func__, pdev->name);
+		return 0;
+	}
+
+	p = netdev_priv(netdevs_rev[i]);
+	p->in_reset = 1;
+	if (p->waiting_for_ul_skb != NULL) {
+		dev_kfree_skb_any(p->waiting_for_ul_skb);
+		p->waiting_for_ul_skb = NULL;
+	}
+	msm_bam_dmux_close(p->ch_id);
+	netif_carrier_off(netdevs_rev[i]);
+	netif_stop_queue(netdevs_rev[i]);
+	return 0;
+}
+
+#ifdef CONFIG_MSM_RMNET_DEBUG
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static int rmnet_debug_init_timeout_suspend(struct net_device *dev)
+{
+	struct device *d;
+	d = &(dev->dev);
+	return device_create_file(d, &dev_attr_timeout_suspend);
+}
+#else
+static int rmnet_debug_init_timeout_suspend(struct net_device *dev)
+{
+	return 0;
+}
+#endif
+static int rmnet_debug_init(struct net_device *dev)
+{
+
+	struct device *d;
+	struct rmnet_private *p;
+	int err = 0;
+	d = &(dev->dev);
+	p = netdev_priv(dev);
+	p->timeout_us = 0;
+	p->wakeups_xmit = p->wakeups_rcv = 0;
+	err = device_create_file(d, &dev_attr_timeout);
+	if (err)
+		return err;
+	err = device_create_file(d, &dev_attr_wakeups_xmit);
+	if (err)
+		return err;
+	err = device_create_file(d, &dev_attr_wakeups_rcv);
+	if (err)
+		return err;
+	err = rmnet_debug_init_timeout_suspend(dev);
+	return err;
+}
+#else
+static int rmnet_debug_init(struct net_device *dev)
+{
+	return 0;
+}
+#endif
 static int __init rmnet_init(void)
 {
 	int ret;
@@ -828,6 +934,53 @@
 			return ret;
 		}
 	}
+	/*Support for new rmnet ports */
+	for (n = 0; n < RMNET_REV_DEVICE_COUNT; n++) {
+		dev = alloc_netdev(sizeof(struct rmnet_private),
+				   "rev_rmnet%d", rmnet_setup);
+
+		if (!dev) {
+			pr_err("%s: no memory for rev netdev %d\n",
+							__func__, n);
+			return -ENOMEM;
+		}
+
+		netdevs_rev[n] = dev;
+		d = &(dev->dev);
+		p = netdev_priv(dev);
+		/* Initial config uses Ethernet */
+		p->operation_mode = RMNET_MODE_LLP_ETH;
+		p->ch_id = n+BAM_DMUX_DATA_REV_RMNET_0;
+		p->waiting_for_ul_skb = NULL;
+		p->in_reset = 0;
+		spin_lock_init(&p->lock);
+		spin_lock_init(&p->tx_queue_lock);
+
+		ret = register_netdev(dev);
+		if (ret) {
+			pr_err("%s: unable to register rev netdev %d rc=%d\n",
+							__func__, n, ret);
+			free_netdev(dev);
+			return ret;
+		}
+		if (rmnet_debug_init(dev))
+			continue;
+		bam_rmnet_rev_drivers[n].probe = bam_rmnet_rev_probe;
+		bam_rmnet_rev_drivers[n].remove = bam_rmnet_rev_remove;
+		tempname = kmalloc(BAM_DMUX_CH_NAME_MAX_LEN, GFP_KERNEL);
+		if (tempname == NULL)
+			return -ENOMEM;
+		scnprintf(tempname, BAM_DMUX_CH_NAME_MAX_LEN, "bam_dmux_ch_%d",
+					(n+BAM_DMUX_DATA_REV_RMNET_0));
+		bam_rmnet_rev_drivers[n].driver.name = tempname;
+		bam_rmnet_rev_drivers[n].driver.owner = THIS_MODULE;
+		ret = platform_driver_register(&bam_rmnet_rev_drivers[n]);
+		if (ret) {
+			pr_err("%s: new rev driver registration failed n=%d rc=%d\n",
+					__func__, n, ret);
+			return ret;
+		}
+	}
 	return 0;
 }
 
diff --git a/drivers/net/ethernet/msm/msm_rmnet_sdio.c b/drivers/net/ethernet/msm/msm_rmnet_sdio.c
index 14fb612..754cb83 100644
--- a/drivers/net/ethernet/msm/msm_rmnet_sdio.c
+++ b/drivers/net/ethernet/msm/msm_rmnet_sdio.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/net/ethernet/msm/msm_rmnet_smux.c b/drivers/net/ethernet/msm/msm_rmnet_smux.c
index e56a64e..7b27b73 100644
--- a/drivers/net/ethernet/msm/msm_rmnet_smux.c
+++ b/drivers/net/ethernet/msm/msm_rmnet_smux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/net/ethernet/msm/msm_rmnet_wwan.c b/drivers/net/ethernet/msm/msm_rmnet_wwan.c
new file mode 100644
index 0000000..fe1ac46
--- /dev/null
+++ b/drivers/net/ethernet/msm/msm_rmnet_wwan.c
@@ -0,0 +1,736 @@
+/* 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.
+ */
+
+/*
+ * WWAN Network Interface.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/wakelock.h>
+#include <linux/msm_rmnet.h>
+#include <linux/if_arp.h>
+#include <linux/platform_device.h>
+#include <net/pkt_sched.h>
+#include <linux/workqueue.h>
+#include <linux/completion.h>
+#include <mach/ipa.h>
+
+#define WWAN_DEV_NAME "rmnet%d"
+#define WWAN_METADATA_MASK 0x00FF0000
+#define IPA_RM_INACTIVITY_TIMER 1000
+#define WWAN_DEVICE_COUNT (8)
+#define WWAN_DATA_LEN 2000
+#define HEADROOM_FOR_A2_MUX   8 /* for mux header */
+#define TAILROOM              8 /* for padding by mux layer */
+
+enum wwan_device_status {
+	WWAN_DEVICE_INACTIVE = 0,
+	WWAN_DEVICE_ACTIVE   = 1
+};
+static enum ipa_rm_resource_name
+	ipa_rm_resource_by_ch_id[WWAN_DEVICE_COUNT] = {
+	IPA_RM_RESOURCE_WWAN_0_PROD,
+	IPA_RM_RESOURCE_WWAN_1_PROD,
+	IPA_RM_RESOURCE_WWAN_2_PROD,
+	IPA_RM_RESOURCE_WWAN_3_PROD,
+	IPA_RM_RESOURCE_WWAN_4_PROD,
+	IPA_RM_RESOURCE_WWAN_5_PROD,
+	IPA_RM_RESOURCE_WWAN_6_PROD,
+	IPA_RM_RESOURCE_WWAN_7_PROD
+};
+static enum a2_mux_logical_channel_id
+	a2_mux_lcid_by_ch_id[WWAN_DEVICE_COUNT] = {
+	A2_MUX_WWAN_0,
+	A2_MUX_WWAN_1,
+	A2_MUX_WWAN_2,
+	A2_MUX_WWAN_3,
+	A2_MUX_WWAN_4,
+	A2_MUX_WWAN_5,
+	A2_MUX_WWAN_6,
+	A2_MUX_WWAN_7
+};
+
+/**
+ * struct wwan_private - WWAN private data
+ * @stats: iface statistics
+ * @ch_id: channel id
+ * @lock: spinlock for mutual exclusion
+ * @device_status: holds device status
+ *
+ * WWAN private - holds all relevant info about WWAN driver
+ */
+struct wwan_private {
+	struct net_device_stats stats;
+	uint32_t ch_id;
+	spinlock_t lock;
+	struct completion resource_granted_completion;
+	enum wwan_device_status device_status;
+};
+
+static struct net_device *netdevs[WWAN_DEVICE_COUNT];
+
+static __be16 wwan_ip_type_trans(struct sk_buff *skb)
+{
+	__be16 protocol = 0;
+	/* Determine L3 protocol */
+	switch (skb->data[0] & 0xf0) {
+	case 0x40:
+		protocol = htons(ETH_P_IP);
+		break;
+	case 0x60:
+		protocol = htons(ETH_P_IPV6);
+		break;
+	default:
+		pr_err("[%s] %s() L3 protocol decode error: 0x%02x",
+		       skb->dev->name, __func__, skb->data[0] & 0xf0);
+		/* skb will be dropped in upper layer for unknown protocol */
+		break;
+	}
+	return protocol;
+}
+
+/**
+ * a2_mux_recv_notify() - Deliver an RX packet to network stack
+ *
+ * @skb: skb to be delivered
+ * @dev: network device
+ *
+ * Return codes:
+ * None
+ */
+static void a2_mux_recv_notify(void *dev, struct sk_buff *skb)
+{
+	struct wwan_private *wwan_ptr = netdev_priv(dev);
+
+	skb->dev = dev;
+	skb->protocol = wwan_ip_type_trans(skb);
+	wwan_ptr->stats.rx_packets++;
+	wwan_ptr->stats.rx_bytes += skb->len;
+	pr_debug("[%s] Rx packet #%lu len=%d\n",
+		skb->dev->name,
+		wwan_ptr->stats.rx_packets, skb->len);
+	netif_rx(skb);
+}
+
+/**
+ * wwan_send_packet() - Deliver a TX packet to A2 MUX driver.
+ *
+ * @skb: skb to be delivered
+ * @dev: network device
+ *
+ * Return codes:
+ * 0: success
+ * -EAGAIN: A2 MUX is not ready to send the skb. try later
+ * -EFAULT: A2 MUX rejected the skb
+ * -EPREM: Unknown error
+ */
+static int wwan_send_packet(struct sk_buff *skb, struct net_device *dev)
+{
+	struct wwan_private *wwan_ptr = netdev_priv(dev);
+	int ret;
+
+	dev->trans_start = jiffies;
+	ret = a2_mux_write(a2_mux_lcid_by_ch_id[wwan_ptr->ch_id], skb);
+	if (ret != 0 && ret != -EAGAIN && ret != -EFAULT) {
+		pr_err("[%s] %s: write returned error %d",
+			dev->name, __func__, ret);
+		return -EPERM;
+	}
+	return ret;
+}
+
+/**
+ * a2_mux_write_done() - Update device statistics and start
+ * network stack queue is was stop and A2 MUX queue is below low
+ * watermark.
+ *
+ * @dev: network device
+ * @skb: skb to be delivered
+ *
+ * Return codes:
+ * None
+ */
+static void a2_mux_write_done(void *dev, struct sk_buff *skb)
+{
+	struct wwan_private *wwan_ptr = netdev_priv(dev);
+	unsigned long flags;
+
+	pr_debug("%s: write complete\n", __func__);
+	wwan_ptr->stats.tx_packets++;
+	wwan_ptr->stats.tx_bytes += skb->len;
+	pr_debug("[%s] Tx packet #%lu len=%d mark=0x%x\n",
+	    ((struct net_device *)(dev))->name, wwan_ptr->stats.tx_packets,
+	    skb->len, skb->mark);
+	dev_kfree_skb_any(skb);
+	spin_lock_irqsave(&wwan_ptr->lock, flags);
+	if (netif_queue_stopped(dev) &&
+	    a2_mux_is_ch_low(a2_mux_lcid_by_ch_id[wwan_ptr->ch_id])) {
+		pr_debug("%s: Low WM hit, waking queue=%p\n",
+		      __func__, skb);
+		netif_wake_queue(dev);
+	}
+	spin_unlock_irqrestore(&wwan_ptr->lock, flags);
+}
+
+/**
+ * a2_mux_notify() - Callback function for A2 MUX events Handles
+ * A2_MUX_RECEIVE and A2_MUX_WRITE_DONE events.
+ *
+ * @dev: network device
+ * @event: A2 MUX event
+ * @data: Additional data provided by A2 MUX
+ *
+ * Return codes:
+ * None
+ */
+static void a2_mux_notify(void *dev, enum a2_mux_event_type event,
+			  unsigned long data)
+{
+	struct sk_buff *skb = (struct sk_buff *)data;
+
+	switch (event) {
+	case A2_MUX_RECEIVE:
+		if (!skb) {
+			pr_err("[%s] %s: No skb received",
+			   ((struct net_device *)dev)->name, __func__);
+			return;
+		}
+		a2_mux_recv_notify(dev, skb);
+		break;
+	case A2_MUX_WRITE_DONE:
+		a2_mux_write_done(dev, skb);
+		break;
+	default:
+		pr_err("%s: unknown event %d\n", __func__, event);
+		break;
+	}
+}
+
+/**
+ * ipa_rm_resource_granted() - Called upon
+ * IPA_RM_RESOURCE_GRANTED event. Wakes up queue is was stopped.
+ *
+ * @work: work object supplied ny workqueue
+ *
+ * Return codes:
+ * None
+ */
+static void ipa_rm_resource_granted(void *dev)
+{
+	netif_wake_queue(dev);
+}
+/**
+ * ipa_rm_notify() - Callback function for RM events. Handles
+ * IPA_RM_RESOURCE_GRANTED and IPA_RM_RESOURCE_RELEASED events.
+ * IPA_RM_RESOURCE_GRANTED is handled in the context of shared
+ * workqueue.
+ *
+ * @dev: network device
+ * @event: IPA RM event
+ * @data: Additional data provided by IPA RM
+ *
+ * Return codes:
+ * None
+ */
+static void ipa_rm_notify(void *dev, enum ipa_rm_event event,
+			  unsigned long data)
+{
+	struct wwan_private *wwan_ptr = netdev_priv(dev);
+
+	pr_debug("%s: event %d\n", __func__, event);
+	switch (event) {
+	case IPA_RM_RESOURCE_GRANTED:
+		if (wwan_ptr->device_status == WWAN_DEVICE_INACTIVE) {
+			complete_all(&wwan_ptr->resource_granted_completion);
+			break;
+		}
+		ipa_rm_resource_granted(dev);
+		break;
+	case IPA_RM_RESOURCE_RELEASED:
+		break;
+	default:
+		pr_err("%s: unknown event %d\n", __func__, event);
+		break;
+	}
+}
+
+static int wwan_register_to_ipa(struct net_device *dev)
+{
+	struct wwan_private *wwan_ptr = netdev_priv(dev);
+	struct ipa_tx_intf tx_properties = {0};
+	struct ipa_ioc_tx_intf_prop tx_ioc_properties[2] = { {0}, {0} };
+	struct ipa_ioc_tx_intf_prop *tx_ipv4_property;
+	struct ipa_ioc_tx_intf_prop *tx_ipv6_property;
+	struct ipa_rx_intf rx_properties = {0};
+	struct ipa_ioc_rx_intf_prop rx_ioc_properties[2] = { {0}, {0} };
+	struct ipa_ioc_rx_intf_prop *rx_ipv4_property;
+	struct ipa_ioc_rx_intf_prop *rx_ipv6_property;
+	int ret = 0;
+
+	pr_debug("[%s] %s:\n", dev->name, __func__);
+	tx_properties.prop = tx_ioc_properties;
+	tx_ipv4_property = &tx_properties.prop[0];
+	tx_ipv4_property->ip = IPA_IP_v4;
+	tx_ipv4_property->dst_pipe = IPA_CLIENT_A2_EMBEDDED_CONS;
+	snprintf(tx_ipv4_property->hdr_name, IPA_RESOURCE_NAME_MAX, "%s%d",
+		 A2_MUX_HDR_NAME_V4_PREF,
+		 a2_mux_lcid_by_ch_id[wwan_ptr->ch_id]);
+	tx_ipv6_property = &tx_properties.prop[1];
+	tx_ipv6_property->ip = IPA_IP_v6;
+	tx_ipv6_property->dst_pipe = IPA_CLIENT_A2_EMBEDDED_CONS;
+	snprintf(tx_ipv6_property->hdr_name, IPA_RESOURCE_NAME_MAX, "%s%d",
+		 A2_MUX_HDR_NAME_V6_PREF,
+		 a2_mux_lcid_by_ch_id[wwan_ptr->ch_id]);
+	tx_properties.num_props = 2;
+	rx_properties.prop = rx_ioc_properties;
+	rx_ipv4_property = &rx_properties.prop[0];
+	rx_ipv4_property->ip = IPA_IP_v4;
+	rx_ipv4_property->attrib.attrib_mask |= IPA_FLT_META_DATA;
+	rx_ipv4_property->attrib.meta_data = wwan_ptr->ch_id;
+	rx_ipv4_property->attrib.meta_data_mask = WWAN_METADATA_MASK;
+	rx_ipv4_property->src_pipe = IPA_CLIENT_A2_EMBEDDED_PROD;
+	rx_ipv6_property = &rx_properties.prop[1];
+	rx_ipv6_property->ip = IPA_IP_v6;
+	rx_ipv6_property->attrib.attrib_mask |= IPA_FLT_META_DATA;
+	rx_ipv6_property->attrib.meta_data = wwan_ptr->ch_id;
+	rx_ipv6_property->attrib.meta_data_mask = WWAN_METADATA_MASK;
+	rx_ipv6_property->src_pipe = IPA_CLIENT_A2_EMBEDDED_PROD;
+	rx_properties.num_props = 2;
+	ret = ipa_register_intf(dev->name, &tx_properties, &rx_properties);
+	if (ret) {
+		pr_err("[%s] %s: ipa_register_intf failed %d\n", dev->name,
+		       __func__, ret);
+		return ret;
+	}
+	return 0;
+}
+
+static int __wwan_open(struct net_device *dev)
+{
+	int r;
+	struct wwan_private *wwan_ptr = netdev_priv(dev);
+
+	pr_debug("[%s] __wwan_open()\n", dev->name);
+	if (wwan_ptr->device_status != WWAN_DEVICE_ACTIVE) {
+		INIT_COMPLETION(wwan_ptr->resource_granted_completion);
+		r = ipa_rm_inactivity_timer_request_resource(
+			ipa_rm_resource_by_ch_id[wwan_ptr->ch_id]);
+		if (r < 0 && r != -EINPROGRESS) {
+			pr_err("%s: ipa rm timer request resource failed %d\n",
+					__func__, r);
+			return -ENODEV;
+		}
+		if (r == -EINPROGRESS) {
+			wait_for_completion(
+				&wwan_ptr->resource_granted_completion);
+		}
+		r = a2_mux_open_channel(a2_mux_lcid_by_ch_id[wwan_ptr->ch_id],
+					dev, a2_mux_notify);
+		if (r < 0) {
+			pr_err("%s: ch=%d failed with rc %d\n",
+					__func__, wwan_ptr->ch_id, r);
+			ipa_rm_inactivity_timer_release_resource(
+				ipa_rm_resource_by_ch_id[wwan_ptr->ch_id]);
+			return -ENODEV;
+		}
+		ipa_rm_inactivity_timer_release_resource(
+			ipa_rm_resource_by_ch_id[wwan_ptr->ch_id]);
+		r = wwan_register_to_ipa(dev);
+		if (r < 0) {
+			pr_err("%s: ch=%d failed to register to IPA rc %d\n",
+					__func__, wwan_ptr->ch_id, r);
+			return -ENODEV;
+		}
+	}
+	wwan_ptr->device_status = WWAN_DEVICE_ACTIVE;
+	return 0;
+}
+
+/**
+ * wwan_open() - Opens the wwan network interface. Opens logical
+ * channel on A2 MUX driver and starts the network stack queue
+ *
+ * @dev: network device
+ *
+ * Return codes:
+ * 0: success
+ * -ENODEV: Error while opening logical channel on A2 MUX driver
+ */
+static int wwan_open(struct net_device *dev)
+{
+	int rc = 0;
+
+	pr_debug("[%s] wwan_open()\n", dev->name);
+	rc = __wwan_open(dev);
+	if (rc == 0)
+		netif_start_queue(dev);
+	return rc;
+}
+
+
+static int __wwan_close(struct net_device *dev)
+{
+	struct wwan_private *wwan_ptr = netdev_priv(dev);
+	int rc = 0;
+
+	if (wwan_ptr->device_status == WWAN_DEVICE_ACTIVE) {
+		wwan_ptr->device_status = WWAN_DEVICE_INACTIVE;
+		/* do not close wwan port once up,  this causes
+			remote side to hang if tried to open again */
+		INIT_COMPLETION(wwan_ptr->resource_granted_completion);
+		rc = ipa_rm_inactivity_timer_request_resource(
+			ipa_rm_resource_by_ch_id[wwan_ptr->ch_id]);
+		if (rc < 0 && rc != -EINPROGRESS) {
+			pr_err("%s: ipa rm timer request resource failed %d\n",
+					__func__, rc);
+			return -ENODEV;
+		}
+		if (rc == -EINPROGRESS) {
+			wait_for_completion(
+				&wwan_ptr->resource_granted_completion);
+		}
+		rc = a2_mux_close_channel(
+			a2_mux_lcid_by_ch_id[wwan_ptr->ch_id]);
+		if (rc) {
+			pr_err("[%s] %s: a2_mux_close_channel failed %d\n",
+			       dev->name, __func__, rc);
+			ipa_rm_inactivity_timer_release_resource(
+				ipa_rm_resource_by_ch_id[wwan_ptr->ch_id]);
+			return rc;
+		}
+		ipa_rm_inactivity_timer_release_resource(
+			ipa_rm_resource_by_ch_id[wwan_ptr->ch_id]);
+		rc = ipa_deregister_intf(dev->name);
+		if (rc) {
+			pr_err("[%s] %s: ipa_deregister_intf failed %d\n",
+			       dev->name, __func__, rc);
+			return rc;
+		}
+		return rc;
+	} else
+		return -EBADF;
+}
+
+/**
+ * wwan_stop() - Stops the wwan network interface. Closes
+ * logical channel on A2 MUX driver and stops the network stack
+ * queue
+ *
+ * @dev: network device
+ *
+ * Return codes:
+ * 0: success
+ * -ENODEV: Error while opening logical channel on A2 MUX driver
+ */
+static int wwan_stop(struct net_device *dev)
+{
+	pr_debug("[%s] wwan_stop()\n", dev->name);
+	__wwan_close(dev);
+	netif_stop_queue(dev);
+	return 0;
+}
+
+static int wwan_change_mtu(struct net_device *dev, int new_mtu)
+{
+	if (0 > new_mtu || WWAN_DATA_LEN < new_mtu)
+		return -EINVAL;
+	pr_debug("[%s] MTU change: old=%d new=%d\n",
+		dev->name, dev->mtu, new_mtu);
+	dev->mtu = new_mtu;
+	return 0;
+}
+
+/**
+ * wwan_xmit() - Transmits an skb. In charge of asking IPA
+ * RM needed resources. In case that IPA RM is not ready, then
+ * the skb is saved for tranmitting as soon as IPA RM resources
+ * are granted.
+ *
+ * @skb: skb to be transmitted
+ * @dev: network device
+ *
+ * Return codes:
+ * 0: success
+ * NETDEV_TX_BUSY: Error while transmitting the skb. Try again
+ * later
+ * -EFAULT: Error while transmitting the skb
+ */
+static int wwan_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct wwan_private *wwan_ptr = netdev_priv(dev);
+	unsigned long flags;
+	int ret = 0;
+
+	if (netif_queue_stopped(dev)) {
+		pr_err("[%s]fatal: wwan_xmit called when netif_queue stopped\n",
+		       dev->name);
+		return 0;
+	}
+	ret = ipa_rm_inactivity_timer_request_resource(
+		ipa_rm_resource_by_ch_id[wwan_ptr->ch_id]);
+	if (ret == -EINPROGRESS) {
+		netif_stop_queue(dev);
+		return NETDEV_TX_BUSY;
+	}
+	if (ret) {
+		pr_err("[%s] fatal: ipa rm timer request resource failed %d\n",
+		       dev->name, ret);
+		return -EFAULT;
+	}
+	ret = wwan_send_packet(skb, dev);
+	if (ret == -EPERM) {
+		ret = NETDEV_TX_BUSY;
+		goto exit;
+	}
+	/*
+	 * detected SSR a bit early.  shut some things down now, and leave
+	 * the rest to the main ssr handling code when that happens later
+	 */
+	if (ret == -EFAULT) {
+		netif_carrier_off(dev);
+		dev_kfree_skb_any(skb);
+		ret = 0;
+		goto exit;
+	}
+	if (ret == -EAGAIN) {
+		/*
+		 * This should not happen
+		 * EAGAIN means we attempted to overflow the high watermark
+		 * Clearly the queue is not stopped like it should be, so
+		 * stop it and return BUSY to the TCP/IP framework.  It will
+		 * retry this packet with the queue is restarted which happens
+		 * in the write_done callback when the low watermark is hit.
+		 */
+		netif_stop_queue(dev);
+		ret = NETDEV_TX_BUSY;
+		goto exit;
+	}
+	spin_lock_irqsave(&wwan_ptr->lock, flags);
+	if (a2_mux_is_ch_full(a2_mux_lcid_by_ch_id[wwan_ptr->ch_id])) {
+		netif_stop_queue(dev);
+		pr_debug("%s: High WM hit, stopping queue=%p\n",
+		       __func__, skb);
+	}
+	spin_unlock_irqrestore(&wwan_ptr->lock, flags);
+exit:
+	ipa_rm_inactivity_timer_release_resource(
+		ipa_rm_resource_by_ch_id[wwan_ptr->ch_id]);
+	return ret;
+}
+
+static struct net_device_stats *wwan_get_stats(struct net_device *dev)
+{
+	struct wwan_private *wwan_ptr = netdev_priv(dev);
+	return &wwan_ptr->stats;
+}
+
+static void wwan_tx_timeout(struct net_device *dev)
+{
+	pr_warning("[%s] wwan_tx_timeout()\n", dev->name);
+}
+
+/**
+ * wwan_ioctl() - I/O control for wwan network driver.
+ *
+ * @dev: network device
+ * @ifr: ignored
+ * @cmd: cmd to be excecuded. can be one of the following:
+ * WWAN_IOCTL_OPEN - Open the network interface
+ * WWAN_IOCTL_CLOSE - Close the network interface
+ *
+ * Return codes:
+ * 0: success
+ * NETDEV_TX_BUSY: Error while transmitting the skb. Try again
+ * later
+ * -EFAULT: Error while transmitting the skb
+ */
+static int wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	int rc = 0;
+
+	switch (cmd) {
+	case RMNET_IOCTL_SET_LLP_IP:        /* Set RAWIP protocol */
+		break;
+	case RMNET_IOCTL_GET_LLP:           /* Get link protocol state */
+		ifr->ifr_ifru.ifru_data = (void *) RMNET_MODE_LLP_IP;
+		break;
+	case RMNET_IOCTL_SET_QOS_DISABLE:   /* Set QoS header disabled */
+		break;
+	case RMNET_IOCTL_FLOW_ENABLE:
+		tc_qdisc_flow_control(dev, (u32)ifr->ifr_data, 1);
+		pr_debug("[%s] %s: enabled flow", dev->name, __func__);
+		break;
+	case RMNET_IOCTL_FLOW_DISABLE:
+		tc_qdisc_flow_control(dev, (u32)ifr->ifr_data, 0);
+		pr_debug("[%s] %s: disabled flow", dev->name, __func__);
+		break;
+	case RMNET_IOCTL_GET_QOS:           /* Get QoS header state    */
+		/* QoS disabled */
+		ifr->ifr_ifru.ifru_data = (void *) 0;
+		break;
+	case RMNET_IOCTL_GET_OPMODE:        /* Get operation mode      */
+		ifr->ifr_ifru.ifru_data = (void *) RMNET_MODE_LLP_IP;
+		break;
+	case RMNET_IOCTL_OPEN:  /* Open transport port */
+		rc = __wwan_open(dev);
+		pr_debug("[%s] wwan_ioctl(): open transport port\n",
+		     dev->name);
+		break;
+	case RMNET_IOCTL_CLOSE:  /* Close transport port */
+		rc = __wwan_close(dev);
+		pr_debug("[%s] wwan_ioctl(): close transport port\n",
+		     dev->name);
+		break;
+	default:
+		pr_err("[%s] error: wwan_ioct called for unsupported cmd[%d]",
+		       dev->name, cmd);
+		return -EINVAL;
+	}
+	return rc;
+}
+
+static const struct net_device_ops wwan_ops_ip = {
+	.ndo_open = wwan_open,
+	.ndo_stop = wwan_stop,
+	.ndo_start_xmit = wwan_xmit,
+	.ndo_get_stats = wwan_get_stats,
+	.ndo_tx_timeout = wwan_tx_timeout,
+	.ndo_do_ioctl = wwan_ioctl,
+	.ndo_change_mtu = wwan_change_mtu,
+	.ndo_set_mac_address = 0,
+	.ndo_validate_addr = 0,
+};
+
+/**
+ * wwan_setup() - Setups the wwan network driver.
+ *
+ * @dev: network device
+ *
+ * Return codes:
+ * None
+ */
+static void wwan_setup(struct net_device *dev)
+{
+	dev->netdev_ops = &wwan_ops_ip;
+	ether_setup(dev);
+	/* set this after calling ether_setup */
+	dev->header_ops = 0;  /* No header */
+	dev->type = ARPHRD_RAWIP;
+	dev->hard_header_len = 0;
+	dev->mtu = WWAN_DATA_LEN;
+	dev->addr_len = 0;
+	dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST);
+	dev->needed_headroom = HEADROOM_FOR_A2_MUX;
+	dev->needed_tailroom = TAILROOM;
+	dev->watchdog_timeo = 1000;
+}
+
+/**
+ * wwan_init() - Initialized the module and registers as a
+ * network interface to the network stack
+ *
+ * Return codes:
+ * 0: success
+ * -ENOMEM: No memory available
+ * -EFAULT: Internal error
+ */
+static int __init wwan_init(void)
+{
+	int ret;
+	struct net_device *dev;
+	struct wwan_private *wwan_ptr;
+	unsigned n;
+	struct ipa_rm_create_params ipa_rm_params;
+
+	pr_info("%s: WWAN devices[%d]\n", __func__, WWAN_DEVICE_COUNT);
+	for (n = 0; n < WWAN_DEVICE_COUNT; n++) {
+		dev = alloc_netdev(sizeof(struct wwan_private),
+				   WWAN_DEV_NAME, wwan_setup);
+		if (!dev) {
+			pr_err("%s: no memory for netdev %d\n", __func__, n);
+			ret = -ENOMEM;
+			goto fail;
+		}
+		netdevs[n] = dev;
+		wwan_ptr = netdev_priv(dev);
+		wwan_ptr->ch_id = n;
+		spin_lock_init(&wwan_ptr->lock);
+		init_completion(&wwan_ptr->resource_granted_completion);
+		memset(&ipa_rm_params, 0, sizeof(struct ipa_rm_create_params));
+		ipa_rm_params.name = ipa_rm_resource_by_ch_id[n];
+		ipa_rm_params.reg_params.user_data = dev;
+		ipa_rm_params.reg_params.notify_cb = ipa_rm_notify;
+		ret = ipa_rm_create_resource(&ipa_rm_params);
+		if (ret) {
+			pr_err("%s: unable to create resourse %d in IPA RM\n",
+			       __func__, ipa_rm_resource_by_ch_id[n]);
+			goto fail;
+		}
+		ret = ipa_rm_inactivity_timer_init(ipa_rm_resource_by_ch_id[n],
+						   IPA_RM_INACTIVITY_TIMER);
+		if (ret) {
+			pr_err("%s: ipa rm timer init failed %d on ins %d\n",
+			       __func__, ret, n);
+			goto fail;
+		}
+		ret = ipa_rm_add_dependency(ipa_rm_resource_by_ch_id[n],
+					    IPA_RM_RESOURCE_A2_CONS);
+		if (ret) {
+			pr_err("%s: unable to add dependency %d rc=%d\n",
+			       __func__, n, ret);
+			goto fail;
+		}
+		ret = register_netdev(dev);
+		if (ret) {
+			pr_err("%s: unable to register netdev %d rc=%d\n",
+			       __func__, n, ret);
+			goto fail;
+		}
+	}
+	return 0;
+fail:
+	for (n = 0; n < WWAN_DEVICE_COUNT; n++) {
+		if (!netdevs[n])
+			break;
+		unregister_netdev(netdevs[n]);
+		ipa_rm_inactivity_timer_destroy(ipa_rm_resource_by_ch_id[n]);
+		free_netdev(netdevs[n]);
+		netdevs[n] = NULL;
+	}
+	return ret;
+}
+late_initcall(wwan_init);
+
+void wwan_cleanup(void)
+{
+	unsigned n;
+
+	pr_info("%s: WWAN devices[%d]\n", __func__, WWAN_DEVICE_COUNT);
+	for (n = 0; n < WWAN_DEVICE_COUNT; n++) {
+		unregister_netdev(netdevs[n]);
+		ipa_rm_inactivity_timer_destroy(ipa_rm_resource_by_ch_id[n]);
+		free_netdev(netdevs[n]);
+		netdevs[n] = NULL;
+	}
+}
+
+MODULE_DESCRIPTION("WWAN Network Interface");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/ethernet/msm/qfec.c b/drivers/net/ethernet/msm/qfec.c
index 112e16a..a1ba0dc 100644
--- a/drivers/net/ethernet/msm/qfec.c
+++ b/drivers/net/ethernet/msm/qfec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/net/ethernet/msm/qfec.h b/drivers/net/ethernet/msm/qfec.h
index 310406a..525fd9c 100644
--- a/drivers/net/ethernet/msm/qfec.h
+++ b/drivers/net/ethernet/msm/qfec.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/net/usb/rmnet_usb_ctrl.c b/drivers/net/usb/rmnet_usb_ctrl.c
index 1476bb3..283c6b0 100644
--- a/drivers/net/usb/rmnet_usb_ctrl.c
+++ b/drivers/net/usb/rmnet_usb_ctrl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
@@ -338,15 +338,6 @@
 	return retval;
 }
 
-int rmnet_usb_ctrl_suspend(struct rmnet_ctrl_dev *dev)
-{
-	if (work_busy(&dev->get_encap_work))
-		return -EBUSY;
-
-	usb_kill_anchored_urbs(&dev->rx_submitted);
-
-	return 0;
-}
 static int rmnet_usb_ctrl_alloc_rx(struct rmnet_ctrl_dev *dev)
 {
 	int	retval = -ENOMEM;
diff --git a/drivers/net/usb/rmnet_usb_ctrl.h b/drivers/net/usb/rmnet_usb_ctrl.h
index a8f8079..f0c169f 100644
--- a/drivers/net/usb/rmnet_usb_ctrl.h
+++ b/drivers/net/usb/rmnet_usb_ctrl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/drivers/net/usb/rmnet_usb_data.c b/drivers/net/usb/rmnet_usb_data.c
index fdfe468..2a57b36 100644
--- a/drivers/net/usb/rmnet_usb_data.c
+++ b/drivers/net/usb/rmnet_usb_data.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
@@ -87,65 +87,35 @@
 {
 	struct usbnet		*unet;
 	struct rmnet_ctrl_dev	*dev;
-	int			retval = 0;
 
 	unet = usb_get_intfdata(iface);
-	if (!unet) {
-		pr_err("%s:data device not found\n", __func__);
-		retval = -ENODEV;
-		goto fail;
-	}
 
 	dev = (struct rmnet_ctrl_dev *)unet->data[1];
-	if (!dev) {
-		dev_err(&iface->dev, "%s: ctrl device not found\n",
-				__func__);
-		retval = -ENODEV;
-		goto fail;
-	}
 
-	retval = usbnet_suspend(iface, message);
-	if (!retval) {
-		retval = rmnet_usb_ctrl_suspend(dev);
-		iface->dev.power.power_state.event = message.event;
-	} else {
-		dev_dbg(&iface->dev,
-			"%s: device is busy can not suspend\n", __func__);
-	}
+	if (work_busy(&dev->get_encap_work))
+		return -EBUSY;
 
-fail:
-	return retval;
+	if (usbnet_suspend(iface, message))
+		return -EBUSY;
+
+	usb_kill_anchored_urbs(&dev->rx_submitted);
+
+	return 0;
 }
 
 static int rmnet_usb_resume(struct usb_interface *iface)
 {
 	int			retval = 0;
-	int			oldstate;
 	struct usbnet		*unet;
 	struct rmnet_ctrl_dev	*dev;
 
 	unet = usb_get_intfdata(iface);
-	if (!unet) {
-		pr_err("%s:data device not found\n", __func__);
-		retval = -ENODEV;
-		goto fail;
-	}
 
 	dev = (struct rmnet_ctrl_dev *)unet->data[1];
-	if (!dev) {
-		dev_err(&iface->dev, "%s: ctrl device not found\n", __func__);
-		retval = -ENODEV;
-		goto fail;
-	}
-	oldstate = iface->dev.power.power_state.event;
-	iface->dev.power.power_state.event = PM_EVENT_ON;
 
-	retval = usbnet_resume(iface);
-	if (!retval) {
-		if (oldstate & PM_EVENT_SUSPEND)
-			retval = rmnet_usb_ctrl_start_rx(dev);
-	}
-fail:
+	usbnet_resume(iface);
+	retval = rmnet_usb_ctrl_start_rx(dev);
+
 	return retval;
 }
 
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 740c717..e9130f6 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -333,10 +333,12 @@
 void usbnet_defer_kevent (struct usbnet *dev, int work)
 {
 	set_bit (work, &dev->flags);
-	if (!schedule_work (&dev->kevent))
-		netdev_err(dev->net, "kevent %d may have been dropped\n", work);
-	else
+	if (!schedule_work (&dev->kevent)) {
+		if (net_ratelimit())
+			netdev_err(dev->net, "kevent %d may have been dropped\n", work);
+	} else {
 		netdev_dbg(dev->net, "kevent %d scheduled\n", work);
+	}
 }
 EXPORT_SYMBOL_GPL(usbnet_defer_kevent);
 
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 5278324..5ccdd2a 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -295,7 +295,6 @@
 
 config WCNSS_CORE
 	tristate "Qualcomm WCNSS CORE driver"
-	depends on (ARCH_MSM8960 || ARCH_MSM8974)
 	select WIRELESS_EXT
 	select WEXT_PRIV
 	select WEXT_CORE
diff --git a/drivers/net/wireless/libra/libra_sdioif.c b/drivers/net/wireless/libra/libra_sdioif.c
index 1d72a16..9938559 100644
--- a/drivers/net/wireless/libra/libra_sdioif.c
+++ b/drivers/net/wireless/libra/libra_sdioif.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/drivers/net/wireless/libra/qcomwlan7x27a_pwrif.c b/drivers/net/wireless/libra/qcomwlan7x27a_pwrif.c
index ef0111a..7fa6cfc 100644
--- a/drivers/net/wireless/libra/qcomwlan7x27a_pwrif.c
+++ b/drivers/net/wireless/libra/qcomwlan7x27a_pwrif.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/net/wireless/libra/qcomwlan_pwrif.c b/drivers/net/wireless/libra/qcomwlan_pwrif.c
index 52b1a51..1d01d65 100644
--- a/drivers/net/wireless/libra/qcomwlan_pwrif.c
+++ b/drivers/net/wireless/libra/qcomwlan_pwrif.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/net/wireless/wcnss/qcomwlan_secif.c b/drivers/net/wireless/wcnss/qcomwlan_secif.c
index e2be75c..c16e48f 100644
--- a/drivers/net/wireless/wcnss/qcomwlan_secif.c
+++ b/drivers/net/wireless/wcnss/qcomwlan_secif.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/net/wireless/wcnss/wcnss_vreg.c b/drivers/net/wireless/wcnss/wcnss_vreg.c
index 75c75a8..6a315d2 100644
--- a/drivers/net/wireless/wcnss/wcnss_vreg.c
+++ b/drivers/net/wireless/wcnss/wcnss_vreg.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -40,6 +40,10 @@
 #define RIVA_PMU_OFFSET         0x28
 #define PRONTO_PMU_OFFSET       0x1004
 
+#define RIVA_SPARE_OFFSET       0x0b4
+#define PRONTO_SPARE_OFFSET     0x1088
+#define NVBIN_DLND_BIT          BIT(25)
+
 #define WCNSS_PMU_CFG_IRIS_XO_CFG          BIT(3)
 #define WCNSS_PMU_CFG_IRIS_XO_EN           BIT(4)
 #define WCNSS_PMU_CFG_GC_BUS_MUX_SEL_TOP   BIT(5)
@@ -115,13 +119,16 @@
 	int rc = 0;
 	int size = 0;
 	int pmu_offset = 0;
+	int spare_offset = 0;
 	unsigned long wcnss_phys_addr;
 	void __iomem *pmu_conf_reg;
+	void __iomem *spare_reg;
 	struct clk *clk;
 
 	if (wcnss_hardware_type() == WCNSS_PRONTO_HW) {
 		wcnss_phys_addr = MSM_PRONTO_PHYS;
 		pmu_offset = PRONTO_PMU_OFFSET;
+		spare_offset = PRONTO_SPARE_OFFSET;
 		size = 0x3000;
 
 		clk = clk_get(dev, "xo");
@@ -132,6 +139,7 @@
 	} else {
 		wcnss_phys_addr = MSM_RIVA_PHYS;
 		pmu_offset = RIVA_PMU_OFFSET;
+		spare_offset = RIVA_SPARE_OFFSET;
 		size = SZ_256;
 
 		clk = clk_get(dev, "cxo");
@@ -147,6 +155,18 @@
 			pr_err("ioremap wcnss physical failed\n");
 			goto fail;
 		}
+
+		/* power on thru SSR should not set NV bit,
+		 * during SSR, NV bin is downloaded by WLAN driver
+		 */
+		if (!wcnss_cold_boot_done()) {
+			pr_debug("wcnss: Indicate NV bin download\n");
+			spare_reg = msm_wcnss_base + spare_offset;
+			reg = readl_relaxed(spare_reg);
+			reg |= NVBIN_DLND_BIT;
+			writel_relaxed(reg, spare_reg);
+		}
+
 		pmu_conf_reg = msm_wcnss_base + pmu_offset;
 
 		/* Enable IRIS XO */
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index 71a9860..ed4e246 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -11,6 +11,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/firmware.h>
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
@@ -26,6 +27,7 @@
 #include <linux/of.h>
 #include <linux/of_gpio.h>
 #include <linux/clk.h>
+#include <linux/ratelimit.h>
 
 #include <mach/msm_smd.h>
 #include <mach/msm_iomap.h>
@@ -61,6 +63,11 @@
 #define CCU_LAST_ADDR1_OFFSET		0x108
 #define CCU_LAST_ADDR2_OFFSET		0x10c
 
+#define MSM_PRONTO_A2XB_BASE		0xfb100400
+#define A2XB_CFG_OFFSET		        0x00
+#define A2XB_INT_SRC_OFFSET		0x0c
+#define A2XB_ERR_INFO_OFFSET		0x1c
+
 #define WCNSS_CTRL_CHANNEL			"WCNSS_CTRL"
 #define WCNSS_MAX_FRAME_SIZE		500
 #define WCNSS_VERSION_LEN			30
@@ -69,13 +76,16 @@
 #define WCNSS_CTRL_MSG_START	0x01000000
 #define	WCNSS_VERSION_REQ		(WCNSS_CTRL_MSG_START + 0)
 #define	WCNSS_VERSION_RSP		(WCNSS_CTRL_MSG_START + 1)
+#define	WCNSS_NVBIN_DNLD_REQ		(WCNSS_CTRL_MSG_START + 2)
+#define	WCNSS_NVBIN_DNLD_RSP		(WCNSS_CTRL_MSG_START + 3)
+
 
 #define VALID_VERSION(version) \
 	((strncmp(version, "INVALID", WCNSS_VERSION_LEN)) ? 1 : 0)
 
 struct smd_msg_hdr {
-	unsigned int type;
-	unsigned int len;
+	unsigned int msg_type;
+	unsigned int msg_len;
 };
 
 struct wcnss_version {
@@ -86,6 +96,57 @@
 	unsigned char  revision;
 };
 
+#define NVBIN_FILE "wlan/prima/WCNSS_qcom_wlan_nv.bin"
+
+/*
+ * On SMD channel 4K of maximum data can be transferred, including message
+ * header, so NV fragment size as next multiple of 1Kb is 3Kb.
+ */
+#define NV_FRAGMENT_SIZE  3072
+
+/* Macro to find the total number fragments of the NV bin Image */
+#define TOTALFRAGMENTS(x) (((x % NV_FRAGMENT_SIZE) == 0) ? \
+	(x / NV_FRAGMENT_SIZE) : ((x / NV_FRAGMENT_SIZE) + 1))
+
+struct nvbin_dnld_req_params {
+	/*
+	 * Fragment sequence number of the NV bin Image. NV Bin Image
+	 * might not fit into one message due to size limitation of
+	 * the SMD channel FIFO so entire NV blob is chopped into
+	 * multiple fragments starting with seqeunce number 0. The
+	 * last fragment is indicated by marking is_last_fragment field
+	 * to 1. At receiving side, NV blobs would be concatenated
+	 * together without any padding bytes in between.
+	 */
+	unsigned short frag_number;
+
+	/*
+	 * When set to 1 it indicates that no more fragments will
+	 * be sent. Receiver shall send back response message after
+	 * the last fragment.
+	 */
+	unsigned short is_last_fragment;
+
+	/* NV Image size (number of bytes) */
+	unsigned int nvbin_buffer_size;
+
+	/*
+	 * Following the 'nvbin_buffer_size', there should be
+	 * nvbin_buffer_size bytes of NV bin Image i.e.
+	 * uint8[nvbin_buffer_size].
+	 */
+};
+
+struct nvbin_dnld_req_msg {
+	/*
+	 * Note: The length specified in nvbin_dnld_req_msg messages
+	 * should be hdr.msg_len = sizeof(nvbin_dnld_req_msg) +
+	 * nvbin_buffer_size.
+	 */
+	struct smd_msg_hdr hdr;
+	struct nvbin_dnld_req_params dnld_req_params;
+};
+
 static struct {
 	struct platform_device *pdev;
 	void		*pil;
@@ -96,6 +157,7 @@
 	const struct dev_pm_ops *pm_ops;
 	int		triggered;
 	int		smd_channel_ready;
+	int		cold_boot_done;
 	smd_channel_t	*smd_ch;
 	unsigned char	wcnss_version[WCNSS_VERSION_LEN];
 	unsigned int	serial_number;
@@ -105,9 +167,12 @@
 	struct wcnss_wlan_config wlan_config;
 	struct delayed_work wcnss_work;
 	struct work_struct wcnssctrl_version_work;
+	struct work_struct wcnssctrl_nvbin_dnld_work;
 	struct work_struct wcnssctrl_rx_work;
 	struct wake_lock wcnss_wake_lock;
 	void __iomem *msm_wcnss_base;
+	void __iomem *riva_ccu_base;
+	void __iomem *pronto_a2xb_base;
 } *penv = NULL;
 
 static ssize_t wcnss_serial_number_show(struct device *dev,
@@ -181,46 +246,62 @@
 
 /* wcnss_reset_intr() is invoked when host drivers fails to
  * communicate with WCNSS over SMD; so logging these registers
- * helps to know WCNSS failure reason */
-static void wcnss_log_ccpu_regs(void)
+ * helps to know WCNSS failure reason
+ */
+void wcnss_riva_log_debug_regs(void)
 {
-	void __iomem *ccu_base;
 	void __iomem *ccu_reg;
 	u32 reg = 0;
 
-	ccu_base = ioremap(MSM_RIVA_CCU_BASE, SZ_512);
-	if (!ccu_base) {
-		pr_err("%s: ioremap WCNSS CCU reg failed\n", __func__);
-		return;
-	}
-
-	ccu_reg = ccu_base + CCU_INVALID_ADDR_OFFSET;
+	ccu_reg = penv->riva_ccu_base + CCU_INVALID_ADDR_OFFSET;
 	reg = readl_relaxed(ccu_reg);
-	pr_info("%s: CCU_CCPU_INVALID_ADDR %08x\n", __func__, reg);
+	pr_info_ratelimited("%s: CCU_CCPU_INVALID_ADDR %08x\n", __func__, reg);
 
-	ccu_reg = ccu_base + CCU_LAST_ADDR0_OFFSET;
+	ccu_reg = penv->riva_ccu_base + CCU_LAST_ADDR0_OFFSET;
 	reg = readl_relaxed(ccu_reg);
-	pr_info("%s: CCU_CCPU_LAST_ADDR0 %08x\n", __func__, reg);
+	pr_info_ratelimited("%s: CCU_CCPU_LAST_ADDR0 %08x\n", __func__, reg);
 
-	ccu_reg = ccu_base + CCU_LAST_ADDR1_OFFSET;
+	ccu_reg = penv->riva_ccu_base + CCU_LAST_ADDR1_OFFSET;
 	reg = readl_relaxed(ccu_reg);
-	pr_info("%s: CCU_CCPU_LAST_ADDR1 %08x\n", __func__, reg);
+	pr_info_ratelimited("%s: CCU_CCPU_LAST_ADDR1 %08x\n", __func__, reg);
 
-	ccu_reg = ccu_base + CCU_LAST_ADDR2_OFFSET;
+	ccu_reg = penv->riva_ccu_base + CCU_LAST_ADDR2_OFFSET;
 	reg = readl_relaxed(ccu_reg);
-	pr_info("%s: CCU_CCPU_LAST_ADDR2 %08x\n", __func__, reg);
+	pr_info_ratelimited("%s: CCU_CCPU_LAST_ADDR2 %08x\n", __func__, reg);
 
-	iounmap(ccu_base);
 }
+EXPORT_SYMBOL(wcnss_riva_log_debug_regs);
 
-/* interface to reset Riva by sending the reset interrupt */
+/* Log pronto debug registers before sending reset interrupt */
+void wcnss_pronto_log_debug_regs(void)
+{
+	void __iomem *reg_addr;
+	u32 reg = 0;
+
+	reg_addr = penv->pronto_a2xb_base + A2XB_CFG_OFFSET;
+	reg = readl_relaxed(reg_addr);
+	pr_info_ratelimited("%s: A2XB_CFG_OFFSET %08x\n", __func__, reg);
+
+	reg_addr = penv->pronto_a2xb_base + A2XB_INT_SRC_OFFSET;
+	reg = readl_relaxed(reg_addr);
+	pr_info_ratelimited("%s: A2XB_INT_SRC_OFFSET %08x\n", __func__, reg);
+
+	reg_addr = penv->pronto_a2xb_base + A2XB_ERR_INFO_OFFSET;
+	reg = readl_relaxed(reg_addr);
+	pr_info_ratelimited("%s: A2XB_ERR_INFO_OFFSET %08x\n", __func__, reg);
+
+}
+EXPORT_SYMBOL(wcnss_pronto_log_debug_regs);
+
+/* interface to reset wcnss by sending the reset interrupt */
 void wcnss_reset_intr(void)
 {
-	if (wcnss_hardware_type() != WCNSS_RIVA_HW) {
+	if (wcnss_hardware_type() == WCNSS_PRONTO_HW) {
+		wcnss_pronto_log_debug_regs();
 		pr_err("%s: reset interrupt not supported\n", __func__);
 		return;
 	}
-	wcnss_log_ccpu_regs();
+	wcnss_riva_log_debug_regs();
 	wmb();
 	__raw_writel(1 << 24, MSM_APCS_GCC_BASE + 0x8);
 }
@@ -380,7 +461,7 @@
 
 void wcnss_flush_delayed_boot_votes()
 {
-	flush_delayed_work_sync(&penv->wcnss_work);
+	flush_delayed_work(&penv->wcnss_work);
 }
 EXPORT_SYMBOL(wcnss_flush_delayed_boot_votes);
 
@@ -647,6 +728,16 @@
 }
 EXPORT_SYMBOL(wcnss_hardware_type);
 
+int wcnss_cold_boot_done(void)
+{
+	if (penv)
+		return penv->cold_boot_done;
+	else
+		return -ENODEV;
+}
+EXPORT_SYMBOL(wcnss_cold_boot_done);
+
+
 static int wcnss_smd_tx(void *data, int len)
 {
 	int ret = 0;
@@ -654,7 +745,7 @@
 	ret = smd_write_avail(penv->smd_ch);
 	if (ret < len) {
 		pr_err("wcnss: no space available for smd frame\n");
-		ret =  -ENOSPC;
+		return -ENOSPC;
 	}
 	ret = smd_write(penv->smd_ch, data, len);
 	if (ret < len) {
@@ -671,6 +762,7 @@
 	unsigned char buf[WCNSS_MAX_FRAME_SIZE];
 	struct smd_msg_hdr *phdr;
 	struct wcnss_version *pversion;
+	int hw_type;
 
 	len = smd_read_avail(penv->smd_ch);
 	if (len > WCNSS_MAX_FRAME_SIZE) {
@@ -689,7 +781,7 @@
 
 	phdr = (struct smd_msg_hdr *)buf;
 
-	switch (phdr->type) {
+	switch (phdr->msg_type) {
 
 	case WCNSS_VERSION_RSP:
 		pversion = (struct wcnss_version *)buf;
@@ -702,10 +794,38 @@
 			"%02x%02x%02x%02x", pversion->major, pversion->minor,
 					pversion->version, pversion->revision);
 		pr_info("wcnss: version %s\n", penv->wcnss_version);
+		/* schedule work to download nvbin to ccpu */
+		hw_type = wcnss_hardware_type();
+		switch (hw_type) {
+		case WCNSS_RIVA_HW:
+			/* supported only if riva major >= 1 and minor >= 4 */
+			if ((pversion->major >= 1) && (pversion->minor >= 4)) {
+				pr_info("wcnss: schedule dnld work for riva\n");
+				schedule_work(&penv->wcnssctrl_nvbin_dnld_work);
+			}
+			break;
+
+		case WCNSS_PRONTO_HW:
+			/* supported only if pronto major >= 1 and minor >= 4 */
+			if ((pversion->major >= 1) && (pversion->minor >= 4)) {
+				pr_info("wcnss: schedule dnld work for pronto\n");
+				schedule_work(&penv->wcnssctrl_nvbin_dnld_work);
+			}
+			break;
+
+		default:
+			pr_info("wcnss: unknown hw type (%d), will not schedule dnld work\n",
+				hw_type);
+			break;
+		}
+		break;
+
+	case WCNSS_NVBIN_DNLD_RSP:
+		pr_info("wcnss: received WCNSS_NVBIN_DNLD_RSP from ccpu\n");
 		break;
 
 	default:
-		pr_err("wcnss: invalid message type %d\n", phdr->type);
+		pr_err("wcnss: invalid message type %d\n", phdr->msg_type);
 	}
 	return;
 }
@@ -715,15 +835,126 @@
 	struct smd_msg_hdr smd_msg;
 	int ret = 0;
 
-	smd_msg.type = WCNSS_VERSION_REQ;
-	smd_msg.len = sizeof(smd_msg);
-	ret = wcnss_smd_tx(&smd_msg, smd_msg.len);
+	smd_msg.msg_type = WCNSS_VERSION_REQ;
+	smd_msg.msg_len = sizeof(smd_msg);
+	ret = wcnss_smd_tx(&smd_msg, smd_msg.msg_len);
 	if (ret < 0)
 		pr_err("wcnss: smd tx failed\n");
 
 	return;
 }
 
+static void wcnss_nvbin_dnld_req(struct work_struct *worker)
+{
+	int ret = 0;
+	struct nvbin_dnld_req_msg *dnld_req_msg;
+	unsigned short total_fragments = 0;
+	unsigned short count = 0;
+	unsigned short retry_count = 0;
+	unsigned short cur_frag_size = 0;
+	unsigned char *outbuffer = NULL;
+	const void *nv_blob_addr = NULL;
+	unsigned int nv_blob_size = 0;
+	const struct firmware *nv = NULL;
+	struct device *dev = NULL;
+
+	dev = wcnss_wlan_get_device();
+
+	ret = request_firmware(&nv, NVBIN_FILE, dev);
+
+	if (ret || !nv || !nv->data || !nv->size) {
+		pr_err("wcnss: wcnss_nvbin_dnld_req: request_firmware failed for %s\n",
+			NVBIN_FILE);
+		return;
+	}
+
+	/*
+	 * First 4 bytes in nv blob is validity bitmap.
+	 * We cannot validate nv, so skip those 4 bytes.
+	 */
+	nv_blob_addr = nv->data + 4;
+	nv_blob_size = nv->size - 4;
+
+	total_fragments = TOTALFRAGMENTS(nv_blob_size);
+
+	pr_info("wcnss: NV bin size: %d, total_fragments: %d\n",
+		nv_blob_size, total_fragments);
+
+	/* get buffer for nv bin dnld req message */
+	outbuffer = kmalloc((sizeof(struct nvbin_dnld_req_msg) +
+		NV_FRAGMENT_SIZE), GFP_KERNEL);
+
+	if (NULL == outbuffer) {
+		pr_err("wcnss: wcnss_nvbin_dnld_req: failed to get buffer\n");
+		goto err_free_nv;
+	}
+
+	dnld_req_msg = (struct nvbin_dnld_req_msg *)outbuffer;
+
+	dnld_req_msg->hdr.msg_type = WCNSS_NVBIN_DNLD_REQ;
+
+	for (count = 0; count < total_fragments; count++) {
+		dnld_req_msg->dnld_req_params.frag_number = count;
+
+		if (count == (total_fragments - 1)) {
+			/* last fragment, take care of boundry condition */
+			cur_frag_size = nv_blob_size % NV_FRAGMENT_SIZE;
+			if (!cur_frag_size)
+				cur_frag_size = NV_FRAGMENT_SIZE;
+
+			dnld_req_msg->dnld_req_params.is_last_fragment = 1;
+		} else {
+			cur_frag_size = NV_FRAGMENT_SIZE;
+			dnld_req_msg->dnld_req_params.is_last_fragment = 0;
+		}
+
+		dnld_req_msg->dnld_req_params.nvbin_buffer_size =
+			cur_frag_size;
+
+		dnld_req_msg->hdr.msg_len =
+			sizeof(struct nvbin_dnld_req_msg) + cur_frag_size;
+
+		/* copy NV fragment */
+		memcpy((outbuffer + sizeof(struct nvbin_dnld_req_msg)),
+			(nv_blob_addr + count * NV_FRAGMENT_SIZE),
+			cur_frag_size);
+
+		ret = wcnss_smd_tx(outbuffer, dnld_req_msg->hdr.msg_len);
+
+		retry_count = 0;
+		while ((ret == -ENOSPC) && (retry_count <= 3)) {
+			pr_debug("wcnss: wcnss_nvbin_dnld_req: smd tx failed, ENOSPC\n");
+			pr_debug("fragment: %d, len: %d, TotFragments: %d, retry_count: %d\n",
+				count, dnld_req_msg->hdr.msg_len,
+				total_fragments, retry_count);
+
+			/* wait and try again */
+			msleep(20);
+			retry_count++;
+			ret = wcnss_smd_tx(outbuffer,
+				dnld_req_msg->hdr.msg_len);
+		}
+
+		if (ret < 0) {
+			pr_err("wcnss: wcnss_nvbin_dnld_req: smd tx failed\n");
+			pr_err("fragment %d, len: %d, TotFragments: %d, retry_count: %d\n",
+				count, dnld_req_msg->hdr.msg_len,
+				total_fragments, retry_count);
+			goto err_dnld;
+		}
+	}
+
+err_dnld:
+	/* free buffer */
+	kfree(outbuffer);
+
+err_free_nv:
+	/* release firmware */
+	release_firmware(nv);
+
+	return;
+}
+
 static int
 wcnss_trigger_config(struct platform_device *pdev)
 {
@@ -745,12 +976,11 @@
 		if (has_pronto_hw) {
 			has_48mhz_xo = of_property_read_bool(pdev->dev.of_node,
 										"qcom,has_48mhz_xo");
-			penv->wcnss_hw_type = WCNSS_PRONTO_HW;
 		} else {
-			penv->wcnss_hw_type = WCNSS_RIVA_HW;
 			has_48mhz_xo = pdata->has_48mhz_xo;
 		}
 	}
+	penv->wcnss_hw_type = (has_pronto_hw) ? WCNSS_PRONTO_HW : WCNSS_RIVA_HW;
 	penv->wlan_config.use_48mhz_xo = has_48mhz_xo;
 
 	penv->thermal_mitigation = 0;
@@ -808,6 +1038,7 @@
 	}
 	INIT_WORK(&penv->wcnssctrl_rx_work, wcnssctrl_rx_handler);
 	INIT_WORK(&penv->wcnssctrl_version_work, wcnss_send_version_req);
+	INIT_WORK(&penv->wcnssctrl_nvbin_dnld_work, wcnss_nvbin_dnld_req);
 
 	wake_lock_init(&penv->wcnss_wake_lock, WAKE_LOCK_SUSPEND, "wcnss");
 
@@ -826,8 +1057,27 @@
 		goto fail_wake;
 	}
 
+	if (wcnss_hardware_type() == WCNSS_RIVA_HW) {
+		penv->riva_ccu_base =  ioremap(MSM_RIVA_CCU_BASE, SZ_512);
+		if (!penv->riva_ccu_base) {
+			ret = -ENOMEM;
+			pr_err("%s: ioremap wcnss physical failed\n", __func__);
+			goto fail_ioremap;
+		}
+	} else {
+		penv->pronto_a2xb_base =  ioremap(MSM_PRONTO_A2XB_BASE, SZ_512);
+		if (!penv->pronto_a2xb_base) {
+			ret = -ENOMEM;
+			pr_err("%s: ioremap wcnss physical failed\n", __func__);
+			goto fail_ioremap;
+		}
+	}
+	penv->cold_boot_done = 1;
+
 	return 0;
 
+fail_ioremap:
+	iounmap(penv->msm_wcnss_base);
 fail_wake:
 	wake_lock_destroy(&penv->wcnss_wake_lock);
 fail_res:
@@ -899,8 +1149,7 @@
 
 #ifdef MODULE
 
-	/*
-	 * Since we were built as a module, we are running because
+	/* Since we were built as a module, we are running because
 	 * the module was loaded, therefore we assume userspace
 	 * applications are available to service PIL, so we can
 	 * trigger the WCNSS configuration now
@@ -910,8 +1159,7 @@
 
 #else
 
-	/*
-	 * Since we were built into the kernel we'll be called as part
+	/* Since we were built into the kernel we'll be called as part
 	 * of kernel initialization.  We don't know if userspace
 	 * applications are available to service PIL at this time
 	 * (they probably are not), so we simply create a device node
diff --git a/drivers/of/of_slimbus.c b/drivers/of/of_slimbus.c
index 8aaef25..9692185 100644
--- a/drivers/of/of_slimbus.c
+++ b/drivers/of/of_slimbus.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/of/of_spmi.c b/drivers/of/of_spmi.c
index 0c23db5..3c51297 100644
--- a/drivers/of/of_spmi.c
+++ b/drivers/of/of_spmi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/platform/msm/Kconfig b/drivers/platform/msm/Kconfig
index 9394986..76e3175 100644
--- a/drivers/platform/msm/Kconfig
+++ b/drivers/platform/msm/Kconfig
@@ -73,6 +73,15 @@
 	  PMIC. These clocks are typically wired through alternate functions
 	  on gpio pins.
 
+config QPNP_VIBRATOR
+	tristate "Vibrator support for QPNP PMIC"
+	depends on OF_SPMI
+	help
+	  This option enables device driver support for the vibrator
+	  on the Qualcomm's QPNP PMICs. The vibrator is connected on the
+	  VIB_DRV_N line and can be controlled manually or by the DTEST lines.
+	  It uses the android timed-output framework.
+
 config IPA
 	tristate "IPA support"
 	depends on SPS
@@ -92,4 +101,14 @@
 		This driver gets the Q6 out of power collapsed state and
 		exposes ioctl control to read avtimer tick.
 
+config SSM
+	tristate "Qualcomm Secure Service Module"
+	depends on QSEECOM
+	depends on MSM_SMD
+	help
+	  Provides an interface for OEM driver to communicate with Trustzone
+	  and modem for key exchange and mode change.
+	  This driver uses Secure Channel Manager interface for trustzone
+	  communication and communicates with modem over SMD channel.
+
 endmenu
diff --git a/drivers/platform/msm/Makefile b/drivers/platform/msm/Makefile
index 919c07f..289ece9 100644
--- a/drivers/platform/msm/Makefile
+++ b/drivers/platform/msm/Makefile
@@ -7,5 +7,7 @@
 obj-$(CONFIG_SPS) += sps/
 obj-$(CONFIG_QPNP_PWM) += qpnp-pwm.o
 obj-$(CONFIG_QPNP_POWER_ON) += qpnp-power-on.o
+obj-$(CONFIG_QPNP_VIBRATOR) += qpnp-vibrator.o
 obj-$(CONFIG_QPNP_CLKDIV) += qpnp-clkdiv.o
 obj-$(CONFIG_MSM_AVTIMER) += avtimer.o
+obj-$(CONFIG_SSM) += ssm.o
diff --git a/drivers/platform/msm/ipa/Makefile b/drivers/platform/msm/ipa/Makefile
index ded5b50..b7eca61 100644
--- a/drivers/platform/msm/ipa/Makefile
+++ b/drivers/platform/msm/ipa/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_IPA) += ipat.o
 ipat-y := ipa.o ipa_debugfs.o ipa_hdr.o ipa_flt.o ipa_rt.o ipa_dp.o ipa_client.o \
-	ipa_utils.o ipa_nat.o rmnet_bridge.o a2_service.o ipa_bridge.o
+	ipa_utils.o ipa_nat.o rmnet_bridge.o a2_service.o ipa_bridge.o ipa_intf.o teth_bridge.o \
+	ipa_rm.o ipa_rm_dependency_graph.o ipa_rm_peers_list.o ipa_rm_resource.o ipa_rm_inactivity_timer.o
diff --git a/drivers/platform/msm/ipa/a2_service.c b/drivers/platform/msm/ipa/a2_service.c
index 0ae2552..4b5f0a2 100644
--- a/drivers/platform/msm/ipa/a2_service.c
+++ b/drivers/platform/msm/ipa/a2_service.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
@@ -10,267 +10,1568 @@
  * GNU General Public License for more details.
  */
 
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <mach/bam_dmux.h>
-#include <mach/ipa.h>
+/*
+ *  A2 service component
+ */
+
+#include <net/ip.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/sched.h>
+#include <linux/skbuff.h>
+#include <linux/clk.h>
+#include <linux/wakelock.h>
 #include <mach/sps.h>
+#include <mach/msm_smsm.h>
+#include <mach/socinfo.h>
+#include <mach/ipa.h>
 #include "ipa_i.h"
 
-static struct a2_service_cb_type {
-	void *tx_complete_cb;
-	void *rx_cb;
-	u32 producer_handle;
-	u32 consumer_handle;
-} a2_service_cb;
+#define A2_NUM_PIPES				6
+#define A2_SUMMING_THRESHOLD			4096
+#define BUFFER_SIZE				2048
+#define NUM_BUFFERS				32
+#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
+#define BAM_MUX_HDR_CMD_OPEN_NO_A2_PC		4
+#define LOW_WATERMARK				2
+#define HIGH_WATERMARK				4
+#define A2_MUX_COMPLETION_TIMEOUT		(60*HZ)
+#define ENABLE_DISCONNECT_ACK			0x1
+#define A2_MUX_PADDING_LENGTH(len)		(4 - ((len) & 0x3))
 
-static struct sps_mem_buffer data_mem_buf[2];
-static struct sps_mem_buffer desc_mem_buf[2];
+struct bam_ch_info {
+	u32			status;
+	a2_mux_notify_cb	notify_cb;
+	void			*user_data;
+	spinlock_t		lock;
+	int			num_tx_pkts;
+	int			use_wm;
+	u32			v4_hdr_hdl;
+	u32			v6_hdr_hdl;
+};
+struct tx_pkt_info {
+	struct sk_buff		*skb;
+	char			is_cmd;
+	u32			len;
+	struct list_head	list_node;
+	unsigned		ts_sec;
+	unsigned long		ts_nsec;
+};
+struct bam_mux_hdr {
+	u16			magic_num;
+	u8			reserved;
+	u8			cmd;
+	u8			pad_len;
+	u8			ch_id;
+	u16			pkt_len;
+};
 
-static int connect_pipe_ipa(enum a2_mux_pipe_direction pipe_dir,
-			u8 *usb_pipe_idx,
-			u32 *clnt_hdl,
-			struct sps_pipe *pipe);
+struct a2_mux_context_type {
+	u32 tethered_prod;
+	u32 tethered_cons;
+	u32 embedded_prod;
+	u32 embedded_cons;
+	int a2_mux_apps_pc_enabled;
+	struct work_struct kickoff_ul_wakeup;
+	struct work_struct kickoff_ul_power_down;
+	struct work_struct kickoff_ul_request_resource;
+	struct	bam_ch_info bam_ch[A2_MUX_NUM_CHANNELS];
+	struct list_head bam_tx_pool;
+	spinlock_t bam_tx_pool_spinlock;
+	struct workqueue_struct *a2_mux_tx_workqueue;
+	int a2_mux_initialized;
+	bool bam_is_connected;
+	int a2_mux_send_power_vote_on_init_once;
+	int a2_mux_sw_bridge_is_connected;
+	u32 a2_device_handle;
+	struct mutex wakeup_lock;
+	struct completion ul_wakeup_ack_completion;
+	struct completion bam_connection_completion;
+	struct completion request_resource_completion;
+	rwlock_t ul_wakeup_lock;
+	int wait_for_ack;
+	struct wake_lock bam_wakelock;
+	int a2_pc_disabled;
+	spinlock_t wakelock_reference_lock;
+	int wakelock_reference_count;
+	int a2_pc_disabled_wakelock_skipped;
+	int disconnect_ack;
+	struct mutex smsm_cb_lock;
+	int bam_dmux_uplink_vote;
+};
+static struct a2_mux_context_type *a2_mux_ctx;
 
-static int a2_ipa_connect_pipe(struct ipa_connect_params *in_params,
-		struct ipa_sps_params *out_params, u32 *clnt_hdl);
+static void handle_bam_mux_cmd(struct sk_buff *rx_skb);
+
+static bool bam_ch_is_open(int index)
+{
+	return a2_mux_ctx->bam_ch[index].status ==
+		(BAM_CH_LOCAL_OPEN | BAM_CH_REMOTE_OPEN);
+}
+
+static bool bam_ch_is_local_open(int index)
+{
+	return a2_mux_ctx->bam_ch[index].status &
+		BAM_CH_LOCAL_OPEN;
+}
+
+static bool bam_ch_is_remote_open(int index)
+{
+	return a2_mux_ctx->bam_ch[index].status &
+		BAM_CH_REMOTE_OPEN;
+}
+
+static bool bam_ch_is_in_reset(int index)
+{
+	return a2_mux_ctx->bam_ch[index].status &
+		BAM_CH_IN_RESET;
+}
+
+static void set_tx_timestamp(struct tx_pkt_info *pkt)
+{
+	unsigned long long t_now;
+
+	t_now = sched_clock();
+	pkt->ts_nsec = do_div(t_now, 1000000000U);
+	pkt->ts_sec = (unsigned)t_now;
+}
+
+static void verify_tx_queue_is_empty(const char *func)
+{
+	unsigned long flags;
+	struct tx_pkt_info *info;
+	int reported = 0;
+
+	spin_lock_irqsave(&a2_mux_ctx->bam_tx_pool_spinlock, flags);
+	list_for_each_entry(info, &a2_mux_ctx->bam_tx_pool, list_node) {
+		if (!reported) {
+			IPADBG("%s: tx pool not empty\n", func);
+			reported = 1;
+		}
+		IPADBG("%s: node=%p ts=%u.%09lu\n", __func__,
+			&info->list_node, info->ts_sec, info->ts_nsec);
+	}
+	spin_unlock_irqrestore(&a2_mux_ctx->bam_tx_pool_spinlock, flags);
+}
+
+static void grab_wakelock(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&a2_mux_ctx->wakelock_reference_lock, flags);
+	IPADBG("%s: ref count = %d\n",
+		__func__,
+		a2_mux_ctx->wakelock_reference_count);
+	if (a2_mux_ctx->wakelock_reference_count == 0)
+		wake_lock(&a2_mux_ctx->bam_wakelock);
+	++a2_mux_ctx->wakelock_reference_count;
+	spin_unlock_irqrestore(&a2_mux_ctx->wakelock_reference_lock, flags);
+}
+
+static void release_wakelock(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&a2_mux_ctx->wakelock_reference_lock, flags);
+	if (a2_mux_ctx->wakelock_reference_count == 0) {
+		IPAERR("%s: bam_dmux wakelock not locked\n", __func__);
+		dump_stack();
+		spin_unlock_irqrestore(&a2_mux_ctx->wakelock_reference_lock,
+				       flags);
+		return;
+	}
+	IPADBG("%s: ref count = %d\n",
+		__func__,
+		a2_mux_ctx->wakelock_reference_count);
+	--a2_mux_ctx->wakelock_reference_count;
+	if (a2_mux_ctx->wakelock_reference_count == 0)
+		wake_unlock(&a2_mux_ctx->bam_wakelock);
+	spin_unlock_irqrestore(&a2_mux_ctx->wakelock_reference_lock, flags);
+}
+
+static void toggle_apps_ack(void)
+{
+	static unsigned int clear_bit; /* 0 = set the bit, else clear bit */
+
+	IPADBG("%s: apps ack %d->%d\n", __func__,
+			clear_bit & 0x1, ~clear_bit & 0x1);
+	smsm_change_state(SMSM_APPS_STATE,
+				clear_bit & SMSM_A2_POWER_CONTROL_ACK,
+				~clear_bit & SMSM_A2_POWER_CONTROL_ACK);
+	clear_bit = ~clear_bit;
+}
+
+static void power_vote(int vote)
+{
+	IPADBG("%s: curr=%d, vote=%d\n",
+		__func__,
+		a2_mux_ctx->bam_dmux_uplink_vote, vote);
+	if (a2_mux_ctx->bam_dmux_uplink_vote == vote)
+		IPADBG("%s: warning - duplicate power vote\n", __func__);
+	a2_mux_ctx->bam_dmux_uplink_vote = vote;
+	if (vote)
+		smsm_change_state(SMSM_APPS_STATE, 0, SMSM_A2_POWER_CONTROL);
+	else
+		smsm_change_state(SMSM_APPS_STATE, SMSM_A2_POWER_CONTROL, 0);
+}
+
+static inline void ul_powerdown(void)
+{
+	IPADBG("%s: powerdown\n", __func__);
+	verify_tx_queue_is_empty(__func__);
+	if (a2_mux_ctx->a2_pc_disabled)
+		release_wakelock();
+	else {
+		a2_mux_ctx->wait_for_ack = 1;
+		INIT_COMPLETION(a2_mux_ctx->ul_wakeup_ack_completion);
+		power_vote(0);
+	}
+	a2_mux_ctx->bam_is_connected = false;
+}
+
+static void ul_wakeup(void)
+{
+	int ret;
+
+	mutex_lock(&a2_mux_ctx->wakeup_lock);
+	if (a2_mux_ctx->bam_is_connected) {
+		IPADBG("%s Already awake\n", __func__);
+		mutex_unlock(&a2_mux_ctx->wakeup_lock);
+		return;
+	}
+	if (a2_mux_ctx->a2_pc_disabled) {
+		/*
+		 * don't grab the wakelock the first time because it is
+		 * already grabbed when a2 powers on
+		 */
+		if (likely(a2_mux_ctx->a2_pc_disabled_wakelock_skipped))
+			grab_wakelock();
+		else
+			a2_mux_ctx->a2_pc_disabled_wakelock_skipped = 1;
+		a2_mux_ctx->bam_is_connected = true;
+		mutex_unlock(&a2_mux_ctx->wakeup_lock);
+		return;
+	}
+	/*
+	 * must wait for the previous power down request to have been acked
+	 * chances are it already came in and this will just fall through
+	 * instead of waiting
+	 */
+	if (a2_mux_ctx->wait_for_ack) {
+		IPADBG("%s waiting for previous ack\n", __func__);
+		ret = wait_for_completion_timeout(
+					&a2_mux_ctx->ul_wakeup_ack_completion,
+					A2_MUX_COMPLETION_TIMEOUT);
+		a2_mux_ctx->wait_for_ack = 0;
+		if (unlikely(ret == 0)) {
+			IPADBG("%s timeout previous ack\n", __func__);
+			goto bail;
+		}
+	}
+	INIT_COMPLETION(a2_mux_ctx->ul_wakeup_ack_completion);
+	power_vote(1);
+	IPADBG("%s waiting for wakeup ack\n", __func__);
+	ret = wait_for_completion_timeout(&a2_mux_ctx->ul_wakeup_ack_completion,
+					A2_MUX_COMPLETION_TIMEOUT);
+	if (unlikely(ret == 0)) {
+		IPADBG("%s timeout wakeup ack\n", __func__);
+		goto bail;
+	}
+	INIT_COMPLETION(a2_mux_ctx->bam_connection_completion);
+	if (!a2_mux_ctx->a2_mux_sw_bridge_is_connected) {
+		ret = wait_for_completion_timeout(
+			&a2_mux_ctx->bam_connection_completion,
+			A2_MUX_COMPLETION_TIMEOUT);
+		if (unlikely(ret == 0)) {
+			IPADBG("%s timeout power on\n", __func__);
+			goto bail;
+		}
+	}
+	a2_mux_ctx->bam_is_connected = true;
+	IPADBG("%s complete\n", __func__);
+	mutex_unlock(&a2_mux_ctx->wakeup_lock);
+	return;
+bail:
+	mutex_unlock(&a2_mux_ctx->wakeup_lock);
+	BUG();
+	return;
+}
+
+static void bam_mux_write_done(bool is_tethered, struct sk_buff *skb)
+{
+	struct tx_pkt_info *info;
+	enum a2_mux_logical_channel_id lcid;
+	unsigned long event_data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&a2_mux_ctx->bam_tx_pool_spinlock, flags);
+	info = list_first_entry(&a2_mux_ctx->bam_tx_pool,
+			struct tx_pkt_info, list_node);
+	if (unlikely(info->skb != skb)) {
+		struct tx_pkt_info *errant_pkt;
+
+		IPAERR("tx_pool mismatch next=%p list_node=%p, ts=%u.%09lu\n",
+				a2_mux_ctx->bam_tx_pool.next,
+				&info->list_node,
+				info->ts_sec, info->ts_nsec
+				);
+
+		list_for_each_entry(errant_pkt,
+				    &a2_mux_ctx->bam_tx_pool, list_node) {
+			IPAERR("%s: node=%p ts=%u.%09lu\n", __func__,
+			&errant_pkt->list_node, errant_pkt->ts_sec,
+			errant_pkt->ts_nsec);
+			if (errant_pkt->skb == skb)
+				info = errant_pkt;
+
+		}
+		spin_unlock_irqrestore(&a2_mux_ctx->bam_tx_pool_spinlock,
+				       flags);
+		BUG();
+	}
+	list_del(&info->list_node);
+	spin_unlock_irqrestore(&a2_mux_ctx->bam_tx_pool_spinlock, flags);
+	if (info->is_cmd) {
+		dev_kfree_skb_any(info->skb);
+		kfree(info);
+		return;
+	}
+	skb = info->skb;
+	kfree(info);
+	event_data = (unsigned long)(skb);
+	if (is_tethered)
+		lcid = A2_MUX_TETHERED_0;
+	else {
+		struct bam_mux_hdr *hdr = (struct bam_mux_hdr *)skb->data;
+		lcid = (enum a2_mux_logical_channel_id) hdr->ch_id;
+	}
+	spin_lock_irqsave(&a2_mux_ctx->bam_ch[lcid].lock, flags);
+	a2_mux_ctx->bam_ch[lcid].num_tx_pkts--;
+	spin_unlock_irqrestore(&a2_mux_ctx->bam_ch[lcid].lock, flags);
+	if (a2_mux_ctx->bam_ch[lcid].notify_cb)
+		a2_mux_ctx->bam_ch[lcid].notify_cb(
+			a2_mux_ctx->bam_ch[lcid].user_data, A2_MUX_WRITE_DONE,
+							event_data);
+	else
+		dev_kfree_skb_any(skb);
+}
+
+static void kickoff_ul_power_down_func(struct work_struct *work)
+{
+	unsigned long flags;
+
+	write_lock_irqsave(&a2_mux_ctx->ul_wakeup_lock, flags);
+	if (a2_mux_ctx->bam_is_connected) {
+		IPADBG("%s: UL active - forcing powerdown\n", __func__);
+		ul_powerdown();
+	}
+	write_unlock_irqrestore(&a2_mux_ctx->ul_wakeup_lock, flags);
+	ipa_rm_notify_completion(IPA_RM_RESOURCE_RELEASED,
+			IPA_RM_RESOURCE_A2_CONS);
+}
+
+static void kickoff_ul_wakeup_func(struct work_struct *work)
+{
+	if (!a2_mux_ctx->bam_is_connected)
+		ul_wakeup();
+	ipa_rm_notify_completion(IPA_RM_RESOURCE_GRANTED,
+			IPA_RM_RESOURCE_A2_CONS);
+}
+
+static void kickoff_ul_request_resource_func(struct work_struct *work)
+{
+	int ret;
+
+	INIT_COMPLETION(a2_mux_ctx->request_resource_completion);
+	ret = ipa_rm_request_resource(IPA_RM_RESOURCE_A2_PROD);
+	if (ret < 0 && ret != -EINPROGRESS) {
+		IPAERR("%s: ipa_rm_request_resource failed %d\n", __func__,
+		       ret);
+		return;
+	}
+	if (ret == -EINPROGRESS) {
+		ret = wait_for_completion_timeout(
+			&a2_mux_ctx->request_resource_completion,
+			A2_MUX_COMPLETION_TIMEOUT);
+		if (unlikely(ret == 0)) {
+			IPADBG("%s timeout request A2 PROD resource\n",
+				     __func__);
+			BUG();
+			return;
+		}
+	}
+	toggle_apps_ack();
+}
+
+static bool msm_bam_dmux_kickoff_ul_wakeup(void)
+{
+	bool is_connected;
+
+	read_lock(&a2_mux_ctx->ul_wakeup_lock);
+	is_connected = a2_mux_ctx->bam_is_connected;
+	read_unlock(&a2_mux_ctx->ul_wakeup_lock);
+	if (!is_connected)
+		queue_work(a2_mux_ctx->a2_mux_tx_workqueue,
+			   &a2_mux_ctx->kickoff_ul_wakeup);
+	return is_connected;
+}
+
+static bool msm_bam_dmux_kickoff_ul_power_down(void)
+
+{
+	bool is_connected;
+
+	read_lock(&a2_mux_ctx->ul_wakeup_lock);
+	is_connected = a2_mux_ctx->bam_is_connected;
+	read_unlock(&a2_mux_ctx->ul_wakeup_lock);
+	if (is_connected)
+		queue_work(a2_mux_ctx->a2_mux_tx_workqueue,
+			   &a2_mux_ctx->kickoff_ul_power_down);
+	return is_connected;
+}
+
+static void ipa_embedded_notify(void *priv,
+				enum ipa_dp_evt_type evt,
+				unsigned long data)
+{
+	switch (evt) {
+	case IPA_RECEIVE:
+		handle_bam_mux_cmd((struct sk_buff *)data);
+		break;
+	case IPA_WRITE_DONE:
+		bam_mux_write_done(false, (struct sk_buff *)data);
+		break;
+	default:
+		IPAERR("%s: Unknown event %d\n", __func__, evt);
+		break;
+	}
+}
+
+static void ipa_tethered_notify(void *priv,
+				enum ipa_dp_evt_type evt,
+				unsigned long data)
+{
+	IPADBG("%s: event = %d\n", __func__, evt);
+	switch (evt) {
+	case IPA_RECEIVE:
+		if (a2_mux_ctx->bam_ch[A2_MUX_TETHERED_0].notify_cb)
+			a2_mux_ctx->bam_ch[A2_MUX_TETHERED_0].notify_cb(
+				a2_mux_ctx->bam_ch[A2_MUX_TETHERED_0].user_data,
+				A2_MUX_RECEIVE,
+				data);
+		break;
+	case IPA_WRITE_DONE:
+		bam_mux_write_done(true, (struct sk_buff *)data);
+		break;
+	default:
+		IPAERR("%s: Unknown event %d\n", __func__, evt);
+		break;
+	}
+}
+
+static int connect_to_bam(void)
+{
+	int ret;
+	struct ipa_sys_connect_params connect_params;
+
+	IPAERR("%s:\n", __func__);
+	if (a2_mux_ctx->a2_mux_sw_bridge_is_connected) {
+		IPAERR("%s: SW bridge is already UP\n",
+				__func__);
+		return -EFAULT;
+	}
+	ret = sps_device_reset(a2_mux_ctx->a2_device_handle);
+	if (ret)
+		IPAERR("%s: device reset failed ret = %d\n",
+		       __func__, ret);
+	memset(&connect_params, 0, sizeof(struct ipa_sys_connect_params));
+	connect_params.client = IPA_CLIENT_A2_TETHERED_CONS;
+	connect_params.notify = ipa_tethered_notify;
+	connect_params.desc_fifo_sz = 0x800;
+	ret = ipa_bridge_setup(IPA_BRIDGE_DIR_UL, IPA_BRIDGE_TYPE_TETHERED,
+			&connect_params,
+			&a2_mux_ctx->tethered_prod);
+	if (ret) {
+		IPAERR("%s: IPA bridge tethered UL failed to connect: %d\n",
+				__func__, ret);
+		goto bridge_tethered_ul_failed;
+	}
+	memset(&connect_params, 0, sizeof(struct ipa_sys_connect_params));
+	connect_params.ipa_ep_cfg.mode.mode = IPA_DMA;
+	connect_params.ipa_ep_cfg.mode.dst = IPA_CLIENT_USB_CONS;
+	connect_params.client = IPA_CLIENT_A2_TETHERED_PROD;
+	connect_params.notify = ipa_tethered_notify;
+	connect_params.desc_fifo_sz = 0x800;
+	ret = ipa_bridge_setup(IPA_BRIDGE_DIR_DL, IPA_BRIDGE_TYPE_TETHERED,
+			&connect_params,
+			&a2_mux_ctx->tethered_cons);
+	if (ret) {
+		IPAERR("%s: IPA bridge tethered DL failed to connect: %d\n",
+				__func__, ret);
+		goto bridge_tethered_dl_failed;
+	}
+	memset(&connect_params, 0, sizeof(struct ipa_sys_connect_params));
+	connect_params.ipa_ep_cfg.hdr.hdr_len = sizeof(struct bam_mux_hdr);
+	connect_params.ipa_ep_cfg.hdr.hdr_ofst_pkt_size_valid = 1;
+	connect_params.ipa_ep_cfg.hdr.hdr_ofst_pkt_size = 6;
+	connect_params.client = IPA_CLIENT_A2_EMBEDDED_CONS;
+	connect_params.notify = ipa_embedded_notify;
+	connect_params.desc_fifo_sz = 0x800;
+	ret = ipa_bridge_setup(IPA_BRIDGE_DIR_UL, IPA_BRIDGE_TYPE_EMBEDDED,
+			&connect_params,
+			&a2_mux_ctx->embedded_prod);
+	if (ret) {
+		IPAERR("%s: IPA bridge embedded UL failed to connect: %d\n",
+				__func__, ret);
+		goto bridge_embedded_ul_failed;
+	}
+	memset(&connect_params, 0, sizeof(struct ipa_sys_connect_params));
+	connect_params.ipa_ep_cfg.hdr.hdr_len = sizeof(struct bam_mux_hdr);
+	connect_params.ipa_ep_cfg.hdr.hdr_ofst_metadata_valid = 1;
+	connect_params.ipa_ep_cfg.hdr.hdr_ofst_metadata = 4;
+	connect_params.client = IPA_CLIENT_A2_EMBEDDED_PROD;
+	connect_params.notify = ipa_embedded_notify;
+	connect_params.desc_fifo_sz = 0x800;
+	ret = ipa_bridge_setup(IPA_BRIDGE_DIR_DL, IPA_BRIDGE_TYPE_EMBEDDED,
+			&connect_params,
+			&a2_mux_ctx->embedded_cons);
+	if (ret) {
+		IPAERR("%s: IPA bridge embedded DL failed to connect: %d\n",
+		       __func__, ret);
+		goto bridge_embedded_dl_failed;
+	}
+	a2_mux_ctx->a2_mux_sw_bridge_is_connected = 1;
+	complete_all(&a2_mux_ctx->bam_connection_completion);
+	return 0;
+
+bridge_embedded_dl_failed:
+	ipa_bridge_teardown(IPA_BRIDGE_DIR_UL, IPA_BRIDGE_TYPE_EMBEDDED,
+			a2_mux_ctx->embedded_prod);
+bridge_embedded_ul_failed:
+	ipa_bridge_teardown(IPA_BRIDGE_DIR_DL, IPA_BRIDGE_TYPE_TETHERED,
+			a2_mux_ctx->tethered_cons);
+bridge_tethered_dl_failed:
+	ipa_bridge_teardown(IPA_BRIDGE_DIR_UL, IPA_BRIDGE_TYPE_TETHERED,
+			a2_mux_ctx->tethered_prod);
+bridge_tethered_ul_failed:
+	return ret;
+}
+
+static int disconnect_to_bam(void)
+{
+	int ret;
+
+	IPAERR("%s\n", __func__);
+	if (!a2_mux_ctx->a2_mux_sw_bridge_is_connected) {
+		IPAERR("%s: SW bridge is already DOWN\n",
+				__func__);
+		return -EFAULT;
+	}
+	ret = ipa_bridge_teardown(IPA_BRIDGE_DIR_UL, IPA_BRIDGE_TYPE_TETHERED,
+			a2_mux_ctx->tethered_prod);
+	if (ret) {
+		IPAERR("%s: IPA bridge tethered UL failed to disconnect: %d\n",
+				__func__, ret);
+		return ret;
+	}
+	ret = ipa_bridge_teardown(IPA_BRIDGE_DIR_DL, IPA_BRIDGE_TYPE_TETHERED,
+			a2_mux_ctx->tethered_cons);
+	if (ret) {
+		IPAERR("%s: IPA bridge tethered DL failed to disconnect: %d\n",
+				__func__, ret);
+		return ret;
+	}
+	ret = ipa_bridge_teardown(IPA_BRIDGE_DIR_UL, IPA_BRIDGE_TYPE_EMBEDDED,
+			a2_mux_ctx->embedded_prod);
+	if (ret) {
+		IPAERR("%s: IPA bridge embedded UL failed to disconnect: %d\n",
+				__func__, ret);
+		return ret;
+	}
+	ret = ipa_bridge_teardown(IPA_BRIDGE_DIR_DL, IPA_BRIDGE_TYPE_EMBEDDED,
+			a2_mux_ctx->embedded_cons);
+	if (ret) {
+		IPAERR("%s: IPA bridge embedded DL failed to disconnect: %d\n",
+				__func__, ret);
+		return ret;
+	}
+	ret = sps_device_reset(a2_mux_ctx->a2_device_handle);
+	if (ret) {
+		IPAERR("%s: device reset failed ret = %d\n",
+			__func__, ret);
+		return ret;
+	}
+	verify_tx_queue_is_empty(__func__);
+	(void) ipa_rm_release_resource(IPA_RM_RESOURCE_A2_PROD);
+	if (a2_mux_ctx->disconnect_ack)
+		toggle_apps_ack();
+	a2_mux_ctx->a2_mux_sw_bridge_is_connected = 0;
+	complete_all(&a2_mux_ctx->bam_connection_completion);
+	return 0;
+}
+
+static void bam_dmux_smsm_cb(void *priv,
+		u32 old_state,
+		u32 new_state)
+{
+	static int last_processed_state;
+
+	mutex_lock(&a2_mux_ctx->smsm_cb_lock);
+	IPADBG("%s: 0x%08x -> 0x%08x\n", __func__, old_state,
+			new_state);
+	if (last_processed_state == (new_state & SMSM_A2_POWER_CONTROL)) {
+		IPADBG("%s: already processed this state\n", __func__);
+		mutex_unlock(&a2_mux_ctx->smsm_cb_lock);
+		return;
+	}
+	last_processed_state = new_state & SMSM_A2_POWER_CONTROL;
+	if (new_state & SMSM_A2_POWER_CONTROL) {
+		IPADBG("%s: MODEM PWR CTRL 1\n", __func__);
+		grab_wakelock();
+		(void) connect_to_bam();
+		queue_work(a2_mux_ctx->a2_mux_tx_workqueue,
+			   &a2_mux_ctx->kickoff_ul_request_resource);
+	} else if (!(new_state & SMSM_A2_POWER_CONTROL)) {
+		IPADBG("%s: MODEM PWR CTRL 0\n", __func__);
+		(void) disconnect_to_bam();
+		release_wakelock();
+	} else {
+		IPAERR("%s: unsupported state change\n", __func__);
+	}
+	mutex_unlock(&a2_mux_ctx->smsm_cb_lock);
+}
+
+static void bam_dmux_smsm_ack_cb(void *priv, u32 old_state,
+						u32 new_state)
+{
+	IPADBG("%s: 0x%08x -> 0x%08x\n", __func__, old_state,
+			new_state);
+	complete_all(&a2_mux_ctx->ul_wakeup_ack_completion);
+}
+
+static int a2_mux_pm_rm_request_resource(void)
+{
+	int result = 0;
+	bool is_connected;
+
+	is_connected = msm_bam_dmux_kickoff_ul_wakeup();
+	if (!is_connected)
+		result = -EINPROGRESS;
+	return result;
+}
+
+static int a2_mux_pm_rm_release_resource(void)
+{
+	int result = 0;
+	bool is_connected;
+
+	is_connected = msm_bam_dmux_kickoff_ul_power_down();
+	if (is_connected)
+		result = -EINPROGRESS;
+	return result;
+}
+
+static void a2_mux_pm_rm_notify_cb(void *user_data,
+		enum ipa_rm_event event,
+		unsigned long data)
+{
+	switch (event) {
+	case IPA_RM_RESOURCE_GRANTED:
+		IPADBG("%s: PROD GRANTED CB\n", __func__);
+		complete_all(&a2_mux_ctx->request_resource_completion);
+		break;
+	case IPA_RM_RESOURCE_RELEASED:
+		IPADBG("%s: PROD RELEASED CB\n", __func__);
+		break;
+	default:
+		return;
+	}
+}
+static int a2_mux_pm_initialize_rm(void)
+{
+	struct ipa_rm_create_params create_params;
+	int result;
+
+	memset(&create_params, 0, sizeof(create_params));
+	create_params.name = IPA_RM_RESOURCE_A2_PROD;
+	create_params.reg_params.notify_cb = &a2_mux_pm_rm_notify_cb;
+	result = ipa_rm_create_resource(&create_params);
+	if (result)
+		goto bail;
+	memset(&create_params, 0, sizeof(create_params));
+	create_params.name = IPA_RM_RESOURCE_A2_CONS;
+	create_params.release_resource = &a2_mux_pm_rm_release_resource;
+	create_params.request_resource = &a2_mux_pm_rm_request_resource;
+	result = ipa_rm_create_resource(&create_params);
+bail:
+	return result;
+}
+
+static void bam_mux_process_data(struct sk_buff *rx_skb)
+{
+	unsigned long flags;
+	struct bam_mux_hdr *rx_hdr;
+	unsigned long event_data;
+
+	rx_hdr = (struct bam_mux_hdr *)rx_skb->data;
+	rx_skb->data = (unsigned char *)(rx_hdr + 1);
+	rx_skb->tail = rx_skb->data + rx_hdr->pkt_len;
+	rx_skb->len = rx_hdr->pkt_len;
+	rx_skb->truesize = rx_hdr->pkt_len + sizeof(struct sk_buff);
+	event_data = (unsigned long)(rx_skb);
+	spin_lock_irqsave(&a2_mux_ctx->bam_ch[rx_hdr->ch_id].lock, flags);
+	if (a2_mux_ctx->bam_ch[rx_hdr->ch_id].notify_cb)
+		a2_mux_ctx->bam_ch[rx_hdr->ch_id].notify_cb(
+			a2_mux_ctx->bam_ch[rx_hdr->ch_id].user_data,
+			A2_MUX_RECEIVE,
+			event_data);
+	else
+		dev_kfree_skb_any(rx_skb);
+	spin_unlock_irqrestore(&a2_mux_ctx->bam_ch[rx_hdr->ch_id].lock,
+			       flags);
+}
+
+static void handle_bam_mux_cmd_open(struct bam_mux_hdr *rx_hdr)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&a2_mux_ctx->bam_ch[rx_hdr->ch_id].lock, flags);
+	a2_mux_ctx->bam_ch[rx_hdr->ch_id].status |= BAM_CH_REMOTE_OPEN;
+	a2_mux_ctx->bam_ch[rx_hdr->ch_id].num_tx_pkts = 0;
+	spin_unlock_irqrestore(&a2_mux_ctx->bam_ch[rx_hdr->ch_id].lock,
+			       flags);
+}
+
+static void handle_bam_mux_cmd(struct sk_buff *rx_skb)
+{
+	unsigned long flags;
+	struct bam_mux_hdr *rx_hdr;
+
+	rx_hdr = (struct bam_mux_hdr *)rx_skb->data;
+	IPADBG("%s: magic %x reserved %d cmd %d pad %d ch %d len %d\n",
+			__func__,
+			rx_hdr->magic_num, rx_hdr->reserved, rx_hdr->cmd,
+			rx_hdr->pad_len, rx_hdr->ch_id, rx_hdr->pkt_len);
+	rx_hdr->magic_num = ntohs(rx_hdr->magic_num);
+	rx_hdr->pkt_len = ntohs(rx_hdr->pkt_len);
+	IPADBG("%s: converted to host order magic_num=%d, pkt_len=%d\n",
+	    __func__, rx_hdr->magic_num, rx_hdr->pkt_len);
+	if (rx_hdr->magic_num != BAM_MUX_HDR_MAGIC_NO) {
+		IPAERR("bad hdr magic %x rvd %d cmd %d pad %d ch %d len %d\n",
+		       rx_hdr->magic_num, rx_hdr->reserved, rx_hdr->cmd,
+			rx_hdr->pad_len, rx_hdr->ch_id, rx_hdr->pkt_len);
+		dev_kfree_skb_any(rx_skb);
+		return;
+	}
+	if (rx_hdr->ch_id >= A2_MUX_NUM_CHANNELS) {
+		IPAERR("bad LCID %d rsvd %d cmd %d pad %d ch %d len %d\n",
+			rx_hdr->ch_id, rx_hdr->reserved, rx_hdr->cmd,
+			rx_hdr->pad_len, rx_hdr->ch_id, rx_hdr->pkt_len);
+		dev_kfree_skb_any(rx_skb);
+		return;
+	}
+	switch (rx_hdr->cmd) {
+	case BAM_MUX_HDR_CMD_DATA:
+		bam_mux_process_data(rx_skb);
+		break;
+	case BAM_MUX_HDR_CMD_OPEN:
+		IPADBG("%s: opening cid %d PC enabled\n", __func__,
+				rx_hdr->ch_id);
+		handle_bam_mux_cmd_open(rx_hdr);
+		if (!(rx_hdr->reserved & ENABLE_DISCONNECT_ACK)) {
+			IPADBG("%s: deactivating disconnect ack\n",
+								__func__);
+			a2_mux_ctx->disconnect_ack = 0;
+		}
+		dev_kfree_skb_any(rx_skb);
+		if (a2_mux_ctx->a2_mux_send_power_vote_on_init_once) {
+			kickoff_ul_wakeup_func(NULL);
+			a2_mux_ctx->a2_mux_send_power_vote_on_init_once = 0;
+		}
+		break;
+	case BAM_MUX_HDR_CMD_OPEN_NO_A2_PC:
+		IPADBG("%s: opening cid %d PC disabled\n", __func__,
+				rx_hdr->ch_id);
+		if (!a2_mux_ctx->a2_pc_disabled) {
+			a2_mux_ctx->a2_pc_disabled = 1;
+			ul_wakeup();
+		}
+		handle_bam_mux_cmd_open(rx_hdr);
+		dev_kfree_skb_any(rx_skb);
+		break;
+	case BAM_MUX_HDR_CMD_CLOSE:
+		/* probably should drop pending write */
+		IPADBG("%s: closing cid %d\n", __func__,
+				rx_hdr->ch_id);
+		spin_lock_irqsave(&a2_mux_ctx->bam_ch[rx_hdr->ch_id].lock,
+				  flags);
+		a2_mux_ctx->bam_ch[rx_hdr->ch_id].status &=
+			~BAM_CH_REMOTE_OPEN;
+		spin_unlock_irqrestore(
+			&a2_mux_ctx->bam_ch[rx_hdr->ch_id].lock, flags);
+		dev_kfree_skb_any(rx_skb);
+		break;
+	default:
+		IPAERR("bad hdr.magic %x rvd %d cmd %d pad %d ch %d len %d\n",
+			rx_hdr->magic_num, rx_hdr->reserved,
+			rx_hdr->cmd, rx_hdr->pad_len, rx_hdr->ch_id,
+			rx_hdr->pkt_len);
+		dev_kfree_skb_any(rx_skb);
+		return;
+	}
+}
+
+static int bam_mux_write_cmd(void *data, u32 len)
+{
+	int rc;
+	struct tx_pkt_info *pkt;
+	unsigned long flags;
+
+	pkt = kmalloc(sizeof(struct tx_pkt_info), GFP_ATOMIC);
+	if (pkt == NULL) {
+		IPAERR("%s: mem alloc for tx_pkt_info failed\n", __func__);
+		return -ENOMEM;
+	}
+	pkt->skb = __dev_alloc_skb(len, GFP_NOWAIT | __GFP_NOWARN);
+	if (pkt->skb == NULL) {
+		IPAERR("%s: unable to alloc skb\n\n", __func__);
+		kfree(pkt);
+		return -ENOMEM;
+	}
+	memcpy(skb_put(pkt->skb, len), data, len);
+	kfree(data);
+	pkt->len = len;
+	pkt->is_cmd = 1;
+	set_tx_timestamp(pkt);
+	spin_lock_irqsave(&a2_mux_ctx->bam_tx_pool_spinlock, flags);
+	list_add_tail(&pkt->list_node, &a2_mux_ctx->bam_tx_pool);
+	rc = ipa_tx_dp(IPA_CLIENT_A2_EMBEDDED_CONS, pkt->skb, NULL);
+	if (rc) {
+		IPAERR("%s ipa_tx_dp failed rc=%d\n",
+			__func__, rc);
+		list_del(&pkt->list_node);
+		spin_unlock_irqrestore(&a2_mux_ctx->bam_tx_pool_spinlock,
+				       flags);
+		dev_kfree_skb_any(pkt->skb);
+		kfree(pkt);
+	} else {
+		spin_unlock_irqrestore(&a2_mux_ctx->bam_tx_pool_spinlock,
+				       flags);
+	}
+	return rc;
+}
 
 /**
- * a2_mux_initialize() - initialize A2 MUX module
+ * a2_mux_get_tethered_client_handles() - provide the tethred
+ *		pipe handles for post setup configuration
+ * @lcid: logical channel ID
+ * @clnt_cons_handle: [out] consumer pipe handle
+ * @clnt_prod_handle: [out] producer pipe handle
  *
- * Return codes:
- * 0: success
+ * Returns: 0 on success, negative on failure
  */
-int a2_mux_initialize(void)
+int a2_mux_get_tethered_client_handles(enum a2_mux_logical_channel_id lcid,
+		unsigned int *clnt_cons_handle,
+		unsigned int *clnt_prod_handle)
 {
-	(void) msm_bam_dmux_ul_power_vote();
-
+	if (!a2_mux_ctx->a2_mux_initialized || lcid != A2_MUX_TETHERED_0)
+		return -ENODEV;
+	if (!clnt_cons_handle || !clnt_prod_handle)
+		return -EINVAL;
+	*clnt_prod_handle = a2_mux_ctx->tethered_prod;
+	*clnt_cons_handle = a2_mux_ctx->tethered_cons;
 	return 0;
 }
 
 /**
- * a2_mux_close() - close A2 MUX module
+ * a2_mux_write() - send the packet to A2,
+ *		add MUX header acc to lcid provided
+ * @id: logical channel ID
+ * @skb: SKB to write
  *
- * Return codes:
- * 0: success
- * -EINVAL: invalid parameters
+ * Returns: 0 on success, negative on failure
  */
-int a2_mux_close(void)
+int a2_mux_write(enum a2_mux_logical_channel_id id, struct sk_buff *skb)
 {
-	int ret = 0;
+	int rc = 0;
+	struct bam_mux_hdr *hdr;
+	unsigned long flags;
+	struct sk_buff *new_skb = NULL;
+	struct tx_pkt_info *pkt;
+	bool is_connected;
 
-	(void) msm_bam_dmux_ul_power_unvote();
+	if (id >= A2_MUX_NUM_CHANNELS)
+		return -EINVAL;
+	if (!skb)
+		return -EINVAL;
+	if (!a2_mux_ctx->a2_mux_initialized)
+		return -ENODEV;
+	spin_lock_irqsave(&a2_mux_ctx->bam_ch[id].lock, flags);
+	if (!bam_ch_is_open(id)) {
+		spin_unlock_irqrestore(&a2_mux_ctx->bam_ch[id].lock, flags);
+		IPAERR("%s: port not open: %d\n",
+		       __func__,
+		       a2_mux_ctx->bam_ch[id].status);
+		return -ENODEV;
+	}
+	if (a2_mux_ctx->bam_ch[id].use_wm &&
+	    (a2_mux_ctx->bam_ch[id].num_tx_pkts >= HIGH_WATERMARK)) {
+		spin_unlock_irqrestore(&a2_mux_ctx->bam_ch[id].lock, flags);
+		IPAERR("%s: watermark exceeded: %d\n", __func__, id);
+		return -EAGAIN;
+	}
+	spin_unlock_irqrestore(&a2_mux_ctx->bam_ch[id].lock, flags);
+	read_lock(&a2_mux_ctx->ul_wakeup_lock);
+	is_connected = a2_mux_ctx->bam_is_connected;
+	read_unlock(&a2_mux_ctx->ul_wakeup_lock);
+	if (!is_connected)
+		return -ENODEV;
+	if (id != A2_MUX_TETHERED_0) {
+		/*
+		 * if skb do not have any tailroom for padding
+		 * copy the skb into a new expanded skb
+		 */
+		if ((skb->len & 0x3) &&
+		    (skb_tailroom(skb) < A2_MUX_PADDING_LENGTH(skb->len))) {
+			new_skb = skb_copy_expand(skb, skb_headroom(skb),
+					A2_MUX_PADDING_LENGTH(skb->len),
+					GFP_ATOMIC);
+			if (new_skb == NULL) {
+				IPAERR("%s: cannot allocate skb\n", __func__);
+				rc = -ENOMEM;
+				goto write_fail;
+			}
+			dev_kfree_skb_any(skb);
+			skb = new_skb;
+		}
+		hdr = (struct bam_mux_hdr *)skb_push(
+					skb, sizeof(struct bam_mux_hdr));
+		/*
+		 * caller should allocate for hdr and padding
+		 * hdr is fine, padding is tricky
+		 */
+		hdr->magic_num = BAM_MUX_HDR_MAGIC_NO;
+		hdr->cmd = BAM_MUX_HDR_CMD_DATA;
+		hdr->reserved = 0;
+		hdr->ch_id = id;
+		hdr->pkt_len = skb->len - sizeof(struct bam_mux_hdr);
+		if (skb->len & 0x3)
+			skb_put(skb, A2_MUX_PADDING_LENGTH(skb->len));
+		hdr->pad_len = skb->len - (sizeof(struct bam_mux_hdr) +
+					   hdr->pkt_len);
+		IPADBG("data %p, tail %p skb len %d pkt len %d pad len %d\n",
+		    skb->data, skb->tail, skb->len,
+		    hdr->pkt_len, hdr->pad_len);
+		hdr->magic_num = htons(hdr->magic_num);
+		hdr->pkt_len = htons(hdr->pkt_len);
+		IPADBG("convert to network order magic_num=%d, pkt_len=%d\n",
+		    hdr->magic_num, hdr->pkt_len);
+	}
+	pkt = kmalloc(sizeof(struct tx_pkt_info), GFP_ATOMIC);
+	if (pkt == NULL) {
+		IPAERR("%s: mem alloc for tx_pkt_info failed\n", __func__);
+		rc = -ENOMEM;
+		goto write_fail2;
+	}
+	pkt->skb = skb;
+	pkt->is_cmd = 0;
+	set_tx_timestamp(pkt);
+	spin_lock_irqsave(&a2_mux_ctx->bam_tx_pool_spinlock, flags);
+	list_add_tail(&pkt->list_node, &a2_mux_ctx->bam_tx_pool);
+	if (id == A2_MUX_TETHERED_0)
+		rc = ipa_tx_dp(IPA_CLIENT_A2_TETHERED_CONS, skb, NULL);
+	else
+		rc = ipa_tx_dp(IPA_CLIENT_A2_EMBEDDED_CONS, skb, NULL);
+	if (rc) {
+		IPAERR("%s ipa_tx_dp failed rc=%d\n",
+			__func__, rc);
+		list_del(&pkt->list_node);
+		spin_unlock_irqrestore(&a2_mux_ctx->bam_tx_pool_spinlock,
+				       flags);
+		goto write_fail3;
+	} else {
+		spin_unlock_irqrestore(&a2_mux_ctx->bam_tx_pool_spinlock,
+				       flags);
+		spin_lock_irqsave(&a2_mux_ctx->bam_ch[id].lock, flags);
+		a2_mux_ctx->bam_ch[id].num_tx_pkts++;
+		spin_unlock_irqrestore(&a2_mux_ctx->bam_ch[id].lock, flags);
+	}
+	return 0;
 
-	ret = ipa_disconnect(a2_service_cb.consumer_handle);
-	if (0 != ret) {
-		pr_err("%s: ipa_disconnect failure\n", __func__);
+write_fail3:
+	kfree(pkt);
+write_fail2:
+	if (new_skb)
+		dev_kfree_skb_any(new_skb);
+write_fail:
+	return rc;
+}
+
+/**
+ * a2_mux_add_hdr() - called when MUX header should
+ *		be added
+ * @lcid: logical channel ID
+ *
+ * Returns: 0 on success, negative on failure
+ */
+static int a2_mux_add_hdr(enum a2_mux_logical_channel_id lcid)
+{
+	struct ipa_ioc_add_hdr *hdrs;
+	struct ipa_hdr_add *ipv4_hdr;
+	struct ipa_hdr_add *ipv6_hdr;
+	struct bam_mux_hdr *dmux_hdr;
+	int rc;
+
+	IPADBG("%s: ch %d\n", __func__, lcid);
+
+	if (lcid < A2_MUX_WWAN_0 || lcid > A2_MUX_WWAN_7) {
+		IPAERR("%s: non valid lcid passed: %d\n", __func__, lcid);
+		return -EINVAL;
+	}
+
+
+	hdrs = kzalloc(sizeof(struct ipa_ioc_add_hdr) +
+		       2 * sizeof(struct ipa_hdr_add), GFP_KERNEL);
+	if (!hdrs) {
+		IPAERR("%s: hdr allocation fail for ch %d\n", __func__, lcid);
+		return -ENOMEM;
+	}
+
+	ipv4_hdr = &hdrs->hdr[0];
+	ipv6_hdr = &hdrs->hdr[1];
+
+	dmux_hdr = (struct bam_mux_hdr *)ipv4_hdr->hdr;
+	snprintf(ipv4_hdr->name, IPA_RESOURCE_NAME_MAX, "%s%d",
+		 A2_MUX_HDR_NAME_V4_PREF, lcid);
+	dmux_hdr->magic_num = BAM_MUX_HDR_MAGIC_NO;
+	dmux_hdr->cmd = BAM_MUX_HDR_CMD_DATA;
+	dmux_hdr->reserved = 0;
+	dmux_hdr->ch_id = lcid;
+
+	/* Packet lenght is added by IPA */
+	dmux_hdr->pkt_len = 0;
+	dmux_hdr->pad_len = 0;
+
+	dmux_hdr->magic_num = htons(dmux_hdr->magic_num);
+	IPADBG("converted to network order magic_num=%d\n",
+		    dmux_hdr->magic_num);
+
+	ipv4_hdr->hdr_len = sizeof(struct bam_mux_hdr);
+	ipv4_hdr->is_partial = 0;
+
+	dmux_hdr = (struct bam_mux_hdr *)ipv6_hdr->hdr;
+	snprintf(ipv6_hdr->name, IPA_RESOURCE_NAME_MAX, "%s%d",
+		 A2_MUX_HDR_NAME_V6_PREF, lcid);
+	dmux_hdr->magic_num = BAM_MUX_HDR_MAGIC_NO;
+	dmux_hdr->cmd = BAM_MUX_HDR_CMD_DATA;
+	dmux_hdr->reserved = 0;
+	dmux_hdr->ch_id = lcid;
+
+	/* Packet lenght is added by IPA */
+	dmux_hdr->pkt_len = 0;
+	dmux_hdr->pad_len = 0;
+
+	dmux_hdr->magic_num = htons(dmux_hdr->magic_num);
+	IPADBG("converted to network order magic_num=%d\n",
+		    dmux_hdr->magic_num);
+
+	ipv6_hdr->hdr_len = sizeof(struct bam_mux_hdr);
+	ipv6_hdr->is_partial = 0;
+
+	hdrs->commit = 1;
+	hdrs->num_hdrs = 2;
+
+	rc = ipa_add_hdr(hdrs);
+	if (rc) {
+		IPAERR("Fail on Header-Insertion(%d)\n", rc);
 		goto bail;
 	}
 
-	ret = ipa_disconnect(a2_service_cb.producer_handle);
-	if (0 != ret) {
-		pr_err("%s: ipa_disconnect failure\n", __func__);
+	if (ipv4_hdr->status) {
+		IPAERR("Fail on Header-Insertion ipv4(%d)\n",
+				ipv4_hdr->status);
+		rc = ipv4_hdr->status;
 		goto bail;
 	}
 
-	ret = 0;
+	if (ipv6_hdr->status) {
+		IPAERR("%s: Fail on Header-Insertion ipv4(%d)\n", __func__,
+				ipv6_hdr->status);
+		rc = ipv6_hdr->status;
+		goto bail;
+	}
 
+	a2_mux_ctx->bam_ch[lcid].v4_hdr_hdl = ipv4_hdr->hdr_hdl;
+	a2_mux_ctx->bam_ch[lcid].v6_hdr_hdl = ipv6_hdr->hdr_hdl;
+
+	rc = 0;
 bail:
+	kfree(hdrs);
+	return rc;
+}
 
+/**
+ * a2_mux_del_hdr() - called when MUX header should
+ *		be removed
+ * @lcid: logical channel ID
+ *
+ * Returns: 0 on success, negative on failure
+ */
+static int a2_mux_del_hdr(enum a2_mux_logical_channel_id lcid)
+{
+	struct ipa_ioc_del_hdr *hdrs;
+	struct ipa_hdr_del *ipv4_hdl;
+	struct ipa_hdr_del *ipv6_hdl;
+	int rc;
+
+	IPADBG("%s: ch %d\n", __func__, lcid);
+
+	if (lcid < A2_MUX_WWAN_0 || lcid > A2_MUX_WWAN_7) {
+		IPAERR("invalid lcid passed: %d\n", lcid);
+		return -EINVAL;
+	}
+
+
+	hdrs = kzalloc(sizeof(struct ipa_ioc_del_hdr) +
+		       2 * sizeof(struct ipa_hdr_del), GFP_KERNEL);
+	if (!hdrs) {
+		IPAERR("hdr alloc fail for ch %d\n", lcid);
+		return -ENOMEM;
+	}
+
+	ipv4_hdl = &hdrs->hdl[0];
+	ipv6_hdl = &hdrs->hdl[1];
+
+	ipv4_hdl->hdl = a2_mux_ctx->bam_ch[lcid].v4_hdr_hdl;
+	ipv6_hdl->hdl = a2_mux_ctx->bam_ch[lcid].v6_hdr_hdl;
+
+	hdrs->commit = 1;
+	hdrs->num_hdls = 2;
+
+	rc = ipa_del_hdr(hdrs);
+	if (rc) {
+		IPAERR("Fail on Del Header-Insertion(%d)\n", rc);
+		goto bail;
+	}
+
+	if (ipv4_hdl->status) {
+		IPAERR("Fail on Del Header-Insertion ipv4(%d)\n",
+				ipv4_hdl->status);
+		rc = ipv4_hdl->status;
+		goto bail;
+	}
+	a2_mux_ctx->bam_ch[lcid].v4_hdr_hdl = 0;
+
+	if (ipv6_hdl->status) {
+		IPAERR("Fail on Del Header-Insertion ipv4(%d)\n",
+				ipv6_hdl->status);
+		rc = ipv6_hdl->status;
+		goto bail;
+	}
+	a2_mux_ctx->bam_ch[lcid].v6_hdr_hdl = 0;
+
+	rc = 0;
+bail:
+	kfree(hdrs);
+	return rc;
+
+}
+
+/**
+ * a2_mux_open_channel() - opens logical channel
+ *		to A2
+ * @lcid: logical channel ID
+ * @user_data: user provided data for below CB
+ * @notify_cb: user provided notification CB
+ *
+ * Returns: 0 on success, negative on failure
+ */
+int a2_mux_open_channel(enum a2_mux_logical_channel_id lcid,
+			void *user_data,
+			a2_mux_notify_cb notify_cb)
+{
+	struct bam_mux_hdr *hdr;
+	unsigned long flags;
+	int rc = 0;
+	bool is_connected;
+
+	IPADBG("%s: opening ch %d\n", __func__, lcid);
+	if (!a2_mux_ctx->a2_mux_initialized) {
+		IPAERR("%s: not inititialized\n", __func__);
+		return -ENODEV;
+	}
+	if (lcid >= A2_MUX_NUM_CHANNELS || lcid < 0) {
+		IPAERR("%s: invalid channel id %d\n", __func__, lcid);
+		return -EINVAL;
+	}
+	if (notify_cb == NULL) {
+		IPAERR("%s: notify function is NULL\n", __func__);
+		return -EINVAL;
+	}
+	spin_lock_irqsave(&a2_mux_ctx->bam_ch[lcid].lock, flags);
+	if (bam_ch_is_open(lcid)) {
+		IPAERR("%s: Already opened %d\n", __func__, lcid);
+		spin_unlock_irqrestore(&a2_mux_ctx->bam_ch[lcid].lock, flags);
+		goto open_done;
+	}
+	if (!bam_ch_is_remote_open(lcid)) {
+		IPAERR("%s: Remote not open; ch: %d\n", __func__, lcid);
+		spin_unlock_irqrestore(&a2_mux_ctx->bam_ch[lcid].lock, flags);
+		return -ENODEV;
+	}
+	a2_mux_ctx->bam_ch[lcid].notify_cb = notify_cb;
+	a2_mux_ctx->bam_ch[lcid].user_data = user_data;
+	a2_mux_ctx->bam_ch[lcid].status |= BAM_CH_LOCAL_OPEN;
+	a2_mux_ctx->bam_ch[lcid].num_tx_pkts = 0;
+	a2_mux_ctx->bam_ch[lcid].use_wm = 0;
+	spin_unlock_irqrestore(&a2_mux_ctx->bam_ch[lcid].lock, flags);
+	read_lock(&a2_mux_ctx->ul_wakeup_lock);
+	is_connected = a2_mux_ctx->bam_is_connected;
+	read_unlock(&a2_mux_ctx->ul_wakeup_lock);
+	if (!is_connected)
+		return -ENODEV;
+	if (lcid != A2_MUX_TETHERED_0) {
+		hdr = kmalloc(sizeof(struct bam_mux_hdr), GFP_KERNEL);
+		if (hdr == NULL) {
+			IPAERR("%s: hdr kmalloc failed. ch: %d\n",
+			       __func__, lcid);
+			return -ENOMEM;
+		}
+		hdr->magic_num = BAM_MUX_HDR_MAGIC_NO;
+		if (a2_mux_ctx->a2_mux_apps_pc_enabled) {
+			hdr->cmd = BAM_MUX_HDR_CMD_OPEN;
+		} else {
+			IPAERR("%s: PC DISABLED BY A5 SW BY INTENTION\n",
+					__func__);
+			a2_mux_ctx->a2_pc_disabled = 1;
+			hdr->cmd = BAM_MUX_HDR_CMD_OPEN_NO_A2_PC;
+		}
+		hdr->reserved = 0;
+		hdr->ch_id = lcid;
+		hdr->pkt_len = 0;
+		hdr->pad_len = 0;
+		hdr->magic_num = htons(hdr->magic_num);
+		hdr->pkt_len = htons(hdr->pkt_len);
+		IPADBG("convert to network order magic_num=%d, pkt_len=%d\n",
+		    hdr->magic_num, hdr->pkt_len);
+		rc = bam_mux_write_cmd((void *)hdr,
+				       sizeof(struct bam_mux_hdr));
+		if (rc) {
+			IPAERR("%s: bam_mux_write_cmd failed %d; ch: %d\n",
+			       __func__, rc, lcid);
+			kfree(hdr);
+			return rc;
+		}
+		rc = a2_mux_add_hdr(lcid);
+		if (rc) {
+			IPAERR("a2_mux_add_hdr failed %d; ch: %d\n",
+			       rc, lcid);
+			return rc;
+		}
+	}
+
+open_done:
+	IPADBG("%s: opened ch %d\n", __func__, lcid);
+	return rc;
+}
+
+/**
+ * a2_mux_close_channel() - closes logical channel
+ *		to A2
+ * @lcid: logical channel ID
+ *
+ * Returns: 0 on success, negative on failure
+ */
+int a2_mux_close_channel(enum a2_mux_logical_channel_id lcid)
+{
+	struct bam_mux_hdr *hdr;
+	unsigned long flags;
+	int rc = 0;
+	bool is_connected;
+
+	if (lcid >= A2_MUX_NUM_CHANNELS || lcid < 0)
+		return -EINVAL;
+	IPADBG("%s: closing ch %d\n", __func__, lcid);
+	if (!a2_mux_ctx->a2_mux_initialized)
+		return -ENODEV;
+	read_lock(&a2_mux_ctx->ul_wakeup_lock);
+	is_connected = a2_mux_ctx->bam_is_connected;
+	read_unlock(&a2_mux_ctx->ul_wakeup_lock);
+	if (!is_connected && !bam_ch_is_in_reset(lcid))
+		return -ENODEV;
+	spin_lock_irqsave(&a2_mux_ctx->bam_ch[lcid].lock, flags);
+	a2_mux_ctx->bam_ch[lcid].notify_cb = NULL;
+	a2_mux_ctx->bam_ch[lcid].user_data = NULL;
+	a2_mux_ctx->bam_ch[lcid].status &= ~BAM_CH_LOCAL_OPEN;
+	spin_unlock_irqrestore(&a2_mux_ctx->bam_ch[lcid].lock, flags);
+	if (bam_ch_is_in_reset(lcid)) {
+		a2_mux_ctx->bam_ch[lcid].status &= ~BAM_CH_IN_RESET;
+		return 0;
+	}
+	if (lcid != A2_MUX_TETHERED_0) {
+		hdr = kmalloc(sizeof(struct bam_mux_hdr), GFP_ATOMIC);
+		if (hdr == NULL) {
+			IPAERR("%s: hdr kmalloc failed. ch: %d\n",
+			       __func__, lcid);
+			return -ENOMEM;
+		}
+		hdr->magic_num = BAM_MUX_HDR_MAGIC_NO;
+		hdr->cmd = BAM_MUX_HDR_CMD_CLOSE;
+		hdr->reserved = 0;
+		hdr->ch_id = lcid;
+		hdr->pkt_len = 0;
+		hdr->pad_len = 0;
+		hdr->magic_num = htons(hdr->magic_num);
+		hdr->pkt_len = htons(hdr->pkt_len);
+		IPADBG("convert to network order magic_num=%d, pkt_len=%d\n",
+		    hdr->magic_num, hdr->pkt_len);
+		rc = bam_mux_write_cmd((void *)hdr, sizeof(struct bam_mux_hdr));
+		if (rc) {
+			IPAERR("%s: bam_mux_write_cmd failed %d; ch: %d\n",
+			       __func__, rc, lcid);
+			kfree(hdr);
+			return rc;
+		}
+
+		rc = a2_mux_del_hdr(lcid);
+		if (rc) {
+			IPAERR("a2_mux_del_hdr failed %d; ch: %d\n",
+			       rc, lcid);
+			return rc;
+		}
+	}
+	IPADBG("%s: closed ch %d\n", __func__, lcid);
+	return 0;
+}
+
+/**
+ * a2_mux_is_ch_full() - checks if channel is above predefined WM,
+ *		used for flow control implementation
+ * @lcid: logical channel ID
+ *
+ * Returns: true if the channel is above predefined WM,
+ *		false otherwise
+ */
+int a2_mux_is_ch_full(enum a2_mux_logical_channel_id lcid)
+{
+	unsigned long flags;
+	int ret;
+
+	if (lcid >= A2_MUX_NUM_CHANNELS ||
+			lcid < 0)
+		return -EINVAL;
+	if (!a2_mux_ctx->a2_mux_initialized)
+		return -ENODEV;
+	spin_lock_irqsave(&a2_mux_ctx->bam_ch[lcid].lock, flags);
+	a2_mux_ctx->bam_ch[lcid].use_wm = 1;
+	ret = a2_mux_ctx->bam_ch[lcid].num_tx_pkts >= HIGH_WATERMARK;
+	IPADBG("%s: ch %d num tx pkts=%d, HWM=%d\n", __func__,
+	     lcid, a2_mux_ctx->bam_ch[lcid].num_tx_pkts, ret);
+	if (!bam_ch_is_local_open(lcid)) {
+		ret = -ENODEV;
+		IPAERR("%s: port not open: %d\n", __func__,
+		       a2_mux_ctx->bam_ch[lcid].status);
+	}
+	spin_unlock_irqrestore(&a2_mux_ctx->bam_ch[lcid].lock, flags);
 	return ret;
 }
 
 /**
- * a2_mux_open_port() - open connection to A2
- * @wwan_logical_channel_id:	 WWAN logical channel ID
- * @rx_cb:	Rx callback
- * @tx_complete_cb:	Tx completed callback
+ * a2_mux_is_ch_low() - checks if channel is below predefined WM,
+ *		used for flow control implementation
+ * @lcid: logical channel ID
  *
- * Return codes:
- * 0: success
- * -EINVAL: invalid parameters
+ * Returns: true if the channel is below predefined WM,
+ *		false otherwise
  */
-int a2_mux_open_port(int wwan_logical_channel_id, void *rx_cb,
-		void *tx_complete_cb)
+int a2_mux_is_ch_low(enum a2_mux_logical_channel_id lcid)
 {
-	int ret = 0;
-	u8 src_pipe = 0;
-	u8 dst_pipe = 0;
-	struct sps_pipe *a2_to_ipa_pipe = NULL;
-	struct sps_pipe *ipa_to_a2_pipe = NULL;
-
-	(void) wwan_logical_channel_id;
-
-	a2_service_cb.rx_cb = rx_cb;
-	a2_service_cb.tx_complete_cb = tx_complete_cb;
-
-	ret = connect_pipe_ipa(A2_TO_IPA,
-			&src_pipe,
-			&(a2_service_cb.consumer_handle),
-			a2_to_ipa_pipe);
-	if (ret) {
-		pr_err("%s: A2 to IPA pipe connection failure\n", __func__);
-		goto bail;
-	}
-
-	ret = connect_pipe_ipa(IPA_TO_A2,
-			&dst_pipe,
-			&(a2_service_cb.producer_handle),
-			ipa_to_a2_pipe);
-	if (ret) {
-		pr_err("%s: IPA to A2 pipe connection failure\n", __func__);
-		sps_disconnect(a2_to_ipa_pipe);
-		sps_free_endpoint(a2_to_ipa_pipe);
-		(void) ipa_disconnect(a2_service_cb.consumer_handle);
-		goto bail;
-	}
-
-	ret = 0;
-
-bail:
-
-	return ret;
-}
-
-static int connect_pipe_ipa(enum a2_mux_pipe_direction pipe_dir,
-			u8 *usb_pipe_idx,
-			u32 *clnt_hdl,
-			struct sps_pipe *pipe)
-{
+	unsigned long flags;
 	int ret;
-	struct sps_connect connection = {0, };
-	u32 a2_handle = 0;
-	u32 a2_phy_addr = 0;
-	struct a2_mux_pipe_connection pipe_connection = { 0, };
-	struct ipa_connect_params ipa_in_params;
-	struct ipa_sps_params sps_out_params;
 
-	memset(&ipa_in_params, 0, sizeof(ipa_in_params));
-	memset(&sps_out_params, 0, sizeof(sps_out_params));
-
-	if (!usb_pipe_idx || !clnt_hdl) {
-		pr_err("connect_pipe_ipa :: null arguments\n");
-		ret = -EINVAL;
-		goto bail;
+	if (lcid >= A2_MUX_NUM_CHANNELS ||
+			lcid < 0)
+		return -EINVAL;
+	if (!a2_mux_ctx->a2_mux_initialized)
+		return -ENODEV;
+	spin_lock_irqsave(&a2_mux_ctx->bam_ch[lcid].lock, flags);
+	a2_mux_ctx->bam_ch[lcid].use_wm = 1;
+	ret = a2_mux_ctx->bam_ch[lcid].num_tx_pkts <= LOW_WATERMARK;
+	IPADBG("%s: ch %d num tx pkts=%d, LWM=%d\n", __func__,
+	     lcid, a2_mux_ctx->bam_ch[lcid].num_tx_pkts, ret);
+	if (!bam_ch_is_local_open(lcid)) {
+		ret = -ENODEV;
+		IPAERR("%s: port not open: %d\n", __func__,
+		       a2_mux_ctx->bam_ch[lcid].status);
 	}
-
-	ret = ipa_get_a2_mux_pipe_info(pipe_dir, &pipe_connection);
-	if (ret) {
-		pr_err("ipa_get_a2_mux_pipe_info failed\n");
-		goto bail;
-	}
-
-	if (pipe_dir == A2_TO_IPA) {
-		a2_phy_addr = pipe_connection.src_phy_addr;
-		ipa_in_params.client = IPA_CLIENT_A2_TETHERED_PROD;
-		ipa_in_params.ipa_ep_cfg.mode.mode = IPA_DMA;
-		ipa_in_params.ipa_ep_cfg.mode.dst = IPA_CLIENT_USB_CONS;
-		pr_err("-*&- pipe_connection->src_pipe_index = %d\n",
-				pipe_connection.src_pipe_index);
-		ipa_in_params.client_ep_idx = pipe_connection.src_pipe_index;
-	} else {
-		a2_phy_addr = pipe_connection.dst_phy_addr;
-		ipa_in_params.client = IPA_CLIENT_A2_TETHERED_CONS;
-		ipa_in_params.client_ep_idx = pipe_connection.dst_pipe_index;
-	}
-
-	ret = sps_phy2h(a2_phy_addr, &a2_handle);
-	if (ret) {
-		pr_err("%s: sps_phy2h failed (A2 BAM) %d\n", __func__, ret);
-		goto bail;
-	}
-
-	ipa_in_params.client_bam_hdl = a2_handle;
-	ipa_in_params.desc_fifo_sz = pipe_connection.desc_fifo_size;
-	ipa_in_params.data_fifo_sz = pipe_connection.data_fifo_size;
-
-	if (pipe_connection.mem_type == IPA_SPS_PIPE_MEM) {
-		pr_debug("%s: A2 BAM using SPS pipe memory\n", __func__);
-		ret = sps_setup_bam2bam_fifo(&data_mem_buf[pipe_dir],
-				pipe_connection.data_fifo_base_offset,
-				pipe_connection.data_fifo_size, 1);
-		if (ret) {
-			pr_err("%s: data fifo setup failure %d\n",
-					__func__, ret);
-			goto bail;
-		}
-
-		ret = sps_setup_bam2bam_fifo(&desc_mem_buf[pipe_dir],
-				pipe_connection.desc_fifo_base_offset,
-				pipe_connection.desc_fifo_size, 1);
-		if (ret) {
-			pr_err("%s: desc. fifo setup failure %d\n",
-					__func__, ret);
-			goto bail;
-		}
-
-		ipa_in_params.data = data_mem_buf[pipe_dir];
-		ipa_in_params.desc = desc_mem_buf[pipe_dir];
-	}
-
-	ret = a2_ipa_connect_pipe(&ipa_in_params,
-			&sps_out_params,
-			clnt_hdl);
-	if (ret) {
-		pr_err("-**- USB-IPA info: ipa_connect failed\n");
-		pr_err("%s: usb_ipa_connect_pipe failed\n", __func__);
-		goto bail;
-	}
-
-	pipe = sps_alloc_endpoint();
-	if (pipe == NULL) {
-		pr_err("%s: sps_alloc_endpoint failed\n", __func__);
-		ret = -ENOMEM;
-		goto a2_ipa_connect_pipe_failed;
-	}
-
-	ret = sps_get_config(pipe, &connection);
-	if (ret) {
-		pr_err("%s: tx get config failed %d\n", __func__, ret);
-		goto get_config_failed;
-	}
-
-	if (pipe_dir == A2_TO_IPA) {
-		connection.mode = SPS_MODE_SRC;
-		*usb_pipe_idx = connection.src_pipe_index;
-		connection.source = a2_handle;
-		connection.destination = sps_out_params.ipa_bam_hdl;
-		connection.src_pipe_index = pipe_connection.src_pipe_index;
-		connection.dest_pipe_index = sps_out_params.ipa_ep_idx;
-	} else {
-		connection.mode = SPS_MODE_DEST;
-		*usb_pipe_idx = connection.dest_pipe_index;
-		connection.source = sps_out_params.ipa_bam_hdl;
-		connection.destination = a2_handle;
-		connection.src_pipe_index = sps_out_params.ipa_ep_idx;
-		connection.dest_pipe_index = pipe_connection.dst_pipe_index;
-	}
-
-	connection.event_thresh = 16;
-	connection.data = sps_out_params.data;
-	connection.desc = sps_out_params.desc;
-
-	ret = sps_connect(pipe, &connection);
-	if (ret < 0) {
-		pr_err("%s: tx connect error %d\n", __func__, ret);
-		goto error;
-	}
-
-	ret = 0;
-	goto bail;
-error:
-	sps_disconnect(pipe);
-get_config_failed:
-	sps_free_endpoint(pipe);
-a2_ipa_connect_pipe_failed:
-	(void) ipa_disconnect(*clnt_hdl);
-bail:
+	spin_unlock_irqrestore(&a2_mux_ctx->bam_ch[lcid].lock, flags);
 	return ret;
 }
 
-static int a2_ipa_connect_pipe(struct ipa_connect_params *in_params,
-		struct ipa_sps_params *out_params, u32 *clnt_hdl)
+static int a2_mux_initialize_context(int handle)
 {
-	return ipa_connect(in_params, out_params, clnt_hdl);
+	int i;
+
+	a2_mux_ctx->a2_mux_apps_pc_enabled = 1;
+	a2_mux_ctx->a2_device_handle = handle;
+	INIT_WORK(&a2_mux_ctx->kickoff_ul_wakeup, kickoff_ul_wakeup_func);
+	INIT_WORK(&a2_mux_ctx->kickoff_ul_power_down,
+		  kickoff_ul_power_down_func);
+	INIT_WORK(&a2_mux_ctx->kickoff_ul_request_resource,
+		  kickoff_ul_request_resource_func);
+	INIT_LIST_HEAD(&a2_mux_ctx->bam_tx_pool);
+	spin_lock_init(&a2_mux_ctx->bam_tx_pool_spinlock);
+	mutex_init(&a2_mux_ctx->wakeup_lock);
+	rwlock_init(&a2_mux_ctx->ul_wakeup_lock);
+	spin_lock_init(&a2_mux_ctx->wakelock_reference_lock);
+	a2_mux_ctx->disconnect_ack = 1;
+	mutex_init(&a2_mux_ctx->smsm_cb_lock);
+	for (i = 0; i < A2_MUX_NUM_CHANNELS; ++i)
+		spin_lock_init(&a2_mux_ctx->bam_ch[i].lock);
+	init_completion(&a2_mux_ctx->ul_wakeup_ack_completion);
+	init_completion(&a2_mux_ctx->bam_connection_completion);
+	init_completion(&a2_mux_ctx->request_resource_completion);
+	wake_lock_init(&a2_mux_ctx->bam_wakelock,
+		       WAKE_LOCK_SUSPEND, "a2_mux_wakelock");
+	a2_mux_ctx->a2_mux_initialized = 1;
+	a2_mux_ctx->a2_mux_send_power_vote_on_init_once = 1;
+	a2_mux_ctx->a2_mux_tx_workqueue =
+		create_singlethread_workqueue("a2_mux_tx");
+	if (!a2_mux_ctx->a2_mux_tx_workqueue) {
+		IPAERR("%s: a2_mux_tx_workqueue alloc failed\n",
+		       __func__);
+		return -ENOMEM;
+	}
+	return 0;
 }
 
+/**
+ * a2_mux_init() - initialize A2 MUX component
+ *
+ * Returns: 0 on success, negative otherwise
+ */
+int a2_mux_init(void)
+{
+	int rc;
+	u32 h;
+	void *a2_virt_addr;
+	u32 a2_bam_mem_base;
+	u32 a2_bam_mem_size;
+	u32 a2_bam_irq;
+	struct sps_bam_props a2_props;
+
+
+	IPADBG("%s A2 MUX\n", __func__);
+	rc = ipa_get_a2_mux_bam_info(&a2_bam_mem_base,
+				     &a2_bam_mem_size,
+				     &a2_bam_irq);
+	if (rc) {
+		IPAERR("%s: ipa_get_a2_mux_bam_info failed\n", __func__);
+		rc = -EFAULT;
+		goto bail;
+	}
+	a2_virt_addr = ioremap_nocache((unsigned long)(a2_bam_mem_base),
+							a2_bam_mem_size);
+	if (!a2_virt_addr) {
+		IPAERR("%s: ioremap failed\n", __func__);
+		rc = -ENOMEM;
+		goto bail;
+	}
+	memset(&a2_props, 0, sizeof(a2_props));
+	a2_props.phys_addr		= a2_bam_mem_base;
+	a2_props.virt_addr		= a2_virt_addr;
+	a2_props.virt_size		= a2_bam_mem_size;
+	a2_props.irq			= a2_bam_irq;
+	a2_props.options		= SPS_BAM_OPT_IRQ_WAKEUP;
+	a2_props.num_pipes		= A2_NUM_PIPES;
+	a2_props.summing_threshold	= A2_SUMMING_THRESHOLD;
+	/* need to free on tear down */
+	rc = sps_register_bam_device(&a2_props, &h);
+	if (rc < 0) {
+		IPAERR("%s: register bam error %d\n", __func__, rc);
+		goto register_bam_failed;
+	}
+	a2_mux_ctx = kzalloc(sizeof(*a2_mux_ctx), GFP_KERNEL);
+	if (!a2_mux_ctx) {
+		IPAERR("%s: a2_mux_ctx alloc failed, rc: %d\n", __func__, rc);
+		rc = -ENOMEM;
+		goto register_bam_failed;
+	}
+	rc = a2_mux_initialize_context(h);
+	if (rc) {
+		IPAERR("%s: a2_mux_initialize_context failed, rc: %d\n",
+		       __func__, rc);
+		goto ctx_alloc_failed;
+	}
+	rc = a2_mux_pm_initialize_rm();
+	if (rc) {
+		IPAERR("%s: a2_mux_pm_initialize_rm failed, rc: %d\n",
+		       __func__, rc);
+		goto ctx_alloc_failed;
+	}
+	rc = smsm_state_cb_register(SMSM_MODEM_STATE, SMSM_A2_POWER_CONTROL,
+					bam_dmux_smsm_cb, NULL);
+	if (rc) {
+		IPAERR("%s: smsm cb register failed, rc: %d\n", __func__, rc);
+		rc = -ENOMEM;
+		goto ctx_alloc_failed;
+	}
+	rc = smsm_state_cb_register(SMSM_MODEM_STATE,
+				    SMSM_A2_POWER_CONTROL_ACK,
+				    bam_dmux_smsm_ack_cb, NULL);
+	if (rc) {
+		IPAERR("%s: smsm ack cb register failed, rc: %d\n",
+		       __func__, rc);
+		rc = -ENOMEM;
+		goto smsm_ack_cb_reg_failed;
+	}
+	if (smsm_get_state(SMSM_MODEM_STATE) & SMSM_A2_POWER_CONTROL)
+		bam_dmux_smsm_cb(NULL, 0, smsm_get_state(SMSM_MODEM_STATE));
+
+	/*
+	 * Set remote channel open for tethered channel since there is
+	 *  no actual remote tethered channel
+	 */
+	a2_mux_ctx->bam_ch[A2_MUX_TETHERED_0].status |= BAM_CH_REMOTE_OPEN;
+
+	rc = 0;
+	goto bail;
+
+smsm_ack_cb_reg_failed:
+	smsm_state_cb_deregister(SMSM_MODEM_STATE,
+				SMSM_A2_POWER_CONTROL,
+				bam_dmux_smsm_cb, NULL);
+ctx_alloc_failed:
+	kfree(a2_mux_ctx);
+register_bam_failed:
+	iounmap(a2_virt_addr);
+bail:
+	return rc;
+}
+
+/**
+ * a2_mux_exit() - destroy A2 MUX component
+ *
+ * Returns: 0 on success, negative otherwise
+ */
+int a2_mux_exit(void)
+{
+	smsm_state_cb_deregister(SMSM_MODEM_STATE,
+			SMSM_A2_POWER_CONTROL_ACK,
+			bam_dmux_smsm_ack_cb,
+			NULL);
+	smsm_state_cb_deregister(SMSM_MODEM_STATE,
+				SMSM_A2_POWER_CONTROL,
+				bam_dmux_smsm_cb,
+				NULL);
+	if (a2_mux_ctx->a2_mux_tx_workqueue)
+		destroy_workqueue(a2_mux_ctx->a2_mux_tx_workqueue);
+	return 0;
+}
diff --git a/drivers/platform/msm/ipa/a2_service.h b/drivers/platform/msm/ipa/a2_service.h
deleted file mode 100644
index 80885da..0000000
--- a/drivers/platform/msm/ipa/a2_service.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#ifndef _A2_SERVICE_H_
-#define _A2_SERVICE_H_
-
-int a2_mux_initialize(void);
-
-int a2_mux_close(void);
-
-int a2_mux_open_port(int wwan_logical_channel_id, void *rx_cb,
-		void *tx_complete_cb);
-
-#endif /* _A2_SERVICE_H_ */
-
diff --git a/drivers/platform/msm/ipa/ipa.c b/drivers/platform/msm/ipa/ipa.c
index 7973cfe..edf3a60 100644
--- a/drivers/platform/msm/ipa/ipa.c
+++ b/drivers/platform/msm/ipa/ipa.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
@@ -23,21 +23,24 @@
 #include <linux/platform_device.h>
 #include <linux/rbtree.h>
 #include <linux/uaccess.h>
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
 #include "ipa_i.h"
+#include "ipa_rm_i.h"
 
 #define IPA_SUMMING_THRESHOLD (0x10)
 #define IPA_PIPE_MEM_START_OFST (0x0)
 #define IPA_PIPE_MEM_SIZE (0x0)
-#define IPA_READ_MAX (16)
 #define IPA_MOBILE_AP_MODE(x) (x == IPA_MODE_MOBILE_AP_ETH || \
 			       x == IPA_MODE_MOBILE_AP_WAN || \
 			       x == IPA_MODE_MOBILE_AP_WLAN)
 #define IPA_CNOC_CLK_RATE (75 * 1000 * 1000UL)
 #define IPA_V1_CLK_RATE (92.31 * 1000 * 1000UL)
+#define IPA_V1_1_CLK_RATE (100 * 1000 * 1000UL)
+#define IPA_DEFAULT_HEADER_LENGTH (8)
 #define IPA_DMA_POOL_SIZE (512)
 #define IPA_DMA_POOL_ALIGNMENT (4)
 #define IPA_DMA_POOL_BOUNDARY (1024)
-#define WLAN_AMPDU_TX_EP (15)
 #define IPA_ROUTING_RULE_BYTE_SIZE (4)
 #define IPA_BAM_CNFG_BITS_VAL (0x7FFFE004)
 
@@ -46,19 +49,6 @@
 #define IPA_AGGR_STR_IN_BYTES(str) \
 	(strnlen((str), IPA_AGGR_MAX_STR_LENGTH - 1) + 1)
 
-struct ipa_plat_drv_res {
-	u32 ipa_mem_base;
-	u32 ipa_mem_size;
-	u32 bam_mem_base;
-	u32 bam_mem_size;
-	u32 ipa_irq;
-	u32 bam_irq;
-	u32 ipa_pipe_mem_start_ofst;
-	u32 ipa_pipe_mem_size;
-	struct a2_mux_pipe_connection a2_to_ipa_pipe;
-	struct a2_mux_pipe_connection ipa_to_a2_pipe;
-};
-
 static struct ipa_plat_drv_res ipa_res = {0, };
 static struct of_device_id ipa_plat_drv_match[] = {
 	{
@@ -73,8 +63,46 @@
 static struct clk *ipa_clk;
 static struct clk *sys_noc_ipa_axi_clk;
 static struct clk *ipa_cnoc_clk;
-static struct device *ipa_dev;
+static struct clk *ipa_inactivity_clk;
 
+static struct msm_bus_vectors ipa_init_vectors[]  = {
+	{
+		.src = MSM_BUS_MASTER_IPA,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = 0,
+	},
+};
+
+static struct msm_bus_vectors ipa_max_perf_vectors[]  = {
+	{
+		.src = MSM_BUS_MASTER_IPA,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 50000000,
+		.ib = 960000000,
+	},
+};
+
+static struct msm_bus_paths ipa_usecases[]  = {
+	{
+		ARRAY_SIZE(ipa_init_vectors),
+		ipa_init_vectors,
+	},
+	{
+		ARRAY_SIZE(ipa_max_perf_vectors),
+		ipa_max_perf_vectors,
+	},
+};
+
+static struct msm_bus_scale_pdata ipa_bus_client_pdata = {
+	ipa_usecases,
+	ARRAY_SIZE(ipa_usecases),
+	.name = "ipa",
+};
+
+static uint32_t ipa_bus_hdl;
+
+static struct device *ipa_dev;
 struct ipa_context *ipa_ctx;
 
 static bool polling_mode;
@@ -113,28 +141,6 @@
 
 static void ipa_set_aggregation_params(void);
 
-static ssize_t ipa_read(struct file *filp, char __user *buf, size_t count,
-		loff_t *f_pos)
-{
-	u32 reg_val = 0xfeedface;
-	char str[IPA_READ_MAX];
-	int result;
-	static int read_cnt;
-
-	if (read_cnt) {
-		IPAERR("only supports one call to read\n");
-		return 0;
-	}
-
-	reg_val = ipa_read_reg(ipa_ctx->mmio, IPA_COMP_HW_VERSION_OFST);
-	result = scnprintf(str, IPA_READ_MAX, "%x\n", reg_val);
-	if (copy_to_user(buf, str, result))
-		return -EFAULT;
-	read_cnt = 1;
-
-	return result;
-}
-
 static int ipa_open(struct inode *inode, struct file *filp)
 {
 	struct ipa_context *ctx = NULL;
@@ -155,6 +161,7 @@
 	struct ipa_ioc_nat_alloc_mem nat_mem;
 	struct ipa_ioc_v4_nat_init nat_init;
 	struct ipa_ioc_v4_nat_del nat_del;
+	size_t sz;
 
 	IPADBG("cmd=%x nr=%d\n", cmd, _IOC_NR(cmd));
 
@@ -485,6 +492,107 @@
 			break;
 		}
 		break;
+	case IPA_IOC_QUERY_INTF:
+		if (copy_from_user(header, (u8 *)arg,
+					sizeof(struct ipa_ioc_query_intf))) {
+			retval = -EFAULT;
+			break;
+		}
+		if (ipa_query_intf((struct ipa_ioc_query_intf *)header)) {
+			retval = -1;
+			break;
+		}
+		if (copy_to_user((u8 *)arg, header,
+					sizeof(struct ipa_ioc_query_intf))) {
+			retval = -EFAULT;
+			break;
+		}
+		break;
+	case IPA_IOC_QUERY_INTF_TX_PROPS:
+		sz = sizeof(struct ipa_ioc_query_intf_tx_props);
+		if (copy_from_user(header, (u8 *)arg, sz)) {
+			retval = -EFAULT;
+			break;
+		}
+		pyld_sz = sz + ((struct ipa_ioc_query_intf_tx_props *)
+				header)->num_tx_props *
+			sizeof(struct ipa_ioc_tx_intf_prop);
+		param = kzalloc(pyld_sz, GFP_KERNEL);
+		if (!param) {
+			retval = -ENOMEM;
+			break;
+		}
+		if (copy_from_user(param, (u8 *)arg, pyld_sz)) {
+			retval = -EFAULT;
+			break;
+		}
+		if (ipa_query_intf_tx_props(
+				(struct ipa_ioc_query_intf_tx_props *)param)) {
+			retval = -1;
+			break;
+		}
+		if (copy_to_user((u8 *)arg, param, pyld_sz)) {
+			retval = -EFAULT;
+			break;
+		}
+		break;
+	case IPA_IOC_QUERY_INTF_RX_PROPS:
+		sz = sizeof(struct ipa_ioc_query_intf_rx_props);
+		if (copy_from_user(header, (u8 *)arg, sz)) {
+			retval = -EFAULT;
+			break;
+		}
+		pyld_sz = sz + ((struct ipa_ioc_query_intf_rx_props *)
+				header)->num_rx_props *
+			sizeof(struct ipa_ioc_rx_intf_prop);
+		param = kzalloc(pyld_sz, GFP_KERNEL);
+		if (!param) {
+			retval = -ENOMEM;
+			break;
+		}
+		if (copy_from_user(param, (u8 *)arg, pyld_sz)) {
+			retval = -EFAULT;
+			break;
+		}
+		if (ipa_query_intf_rx_props(
+				(struct ipa_ioc_query_intf_rx_props *)param)) {
+			retval = -1;
+			break;
+		}
+		if (copy_to_user((u8 *)arg, param, pyld_sz)) {
+			retval = -EFAULT;
+			break;
+		}
+		break;
+	case IPA_IOC_PULL_MSG:
+		if (copy_from_user(header, (u8 *)arg,
+					sizeof(struct ipa_msg_meta))) {
+			retval = -EFAULT;
+			break;
+		}
+		pyld_sz = sizeof(struct ipa_msg_meta) +
+		   ((struct ipa_msg_meta *)header)->msg_len;
+		param = kzalloc(pyld_sz, GFP_KERNEL);
+		if (!param) {
+			retval = -ENOMEM;
+			break;
+		}
+		if (copy_from_user(param, (u8 *)arg, pyld_sz)) {
+			retval = -EFAULT;
+			break;
+		}
+		if (ipa_pull_msg((struct ipa_msg_meta *)param,
+				 (char *)param + sizeof(struct ipa_msg_meta),
+				 ((struct ipa_msg_meta *)param)->msg_len) !=
+		       ((struct ipa_msg_meta *)param)->msg_len) {
+			retval = -1;
+			break;
+		}
+		if (copy_to_user((u8 *)arg, param, pyld_sz)) {
+			retval = -EFAULT;
+			break;
+		}
+		break;
 	default:        /* redundant, as cmd was checked against MAXNR */
 		return -ENOTTY;
 	}
@@ -576,9 +684,14 @@
 	/*
 	 * only single stream for MBIM supported and no exception packets
 	 * expected so set default header to zero
+	 * for IPA HW 1.1 and up the default header length is 8 (exception)
 	 */
-	hdr_entry->hdr_len = 1;
-	hdr_entry->hdr[0] = 0;
+	if (ipa_ctx->ipa_hw_type == IPA_HW_v1_0) {
+		hdr_entry->hdr_len = 1;
+		hdr_entry->hdr[0] = 0;
+	} else {
+		hdr_entry->hdr_len = IPA_DEFAULT_HEADER_LENGTH;
+	}
 
 	/*
 	 * SW does not know anything about default exception header so
@@ -614,14 +727,16 @@
 	return ret;
 }
 
-static void ipa_handle_tx_poll_for_pipe(struct ipa_sys_context *sys)
+static int ipa_handle_tx_poll_for_pipe(struct ipa_sys_context *sys,
+		bool process_all)
 {
 	struct ipa_tx_pkt_wrapper *tx_pkt, *t;
 	struct sps_iovec iov;
 	unsigned long irq_flags;
 	int ret;
+	int cnt = 0;
 
-	while (1) {
+	do {
 		iov.addr = 0;
 		ret = sps_get_iovec(sys->ep->ep_hdl, &iov);
 		if (ret) {
@@ -638,6 +753,7 @@
 		switch (tx_pkt->cnt) {
 		case 1:
 			ipa_wq_write_done(&tx_pkt->work);
+			++cnt;
 			break;
 		case 0xFFFF:
 			/* reached end of set */
@@ -652,6 +768,7 @@
 					    struct ipa_tx_pkt_wrapper, link);
 			spin_unlock_irqrestore(&sys->spinlock, irq_flags);
 			ipa_wq_write_done(&tx_pkt->work);
+			++cnt;
 			break;
 		default:
 			/* keep looping till reach the end of the set */
@@ -662,9 +779,12 @@
 				      &sys->wait_desc_list);
 			spin_unlock_irqrestore(&sys->spinlock,
 					       irq_flags);
+			++cnt;
 			break;
 		}
-	}
+	} while (process_all);
+
+	return cnt;
 }
 
 static void ipa_poll_function(struct work_struct *work)
@@ -674,19 +794,26 @@
 		IPA_A5_WLAN_AMPDU_OUT };
 	int i;
 	int num_tx_pipes;
-
-	/* check all the system pipes for tx completions and rx available */
-	if (ipa_ctx->sys[IPA_A5_LAN_WAN_IN].ep->valid)
-		ipa_handle_rx_core();
+	int cnt;
 
 	num_tx_pipes = sizeof(tx_pipes) / sizeof(tx_pipes[0]);
 
 	if (!IPA_MOBILE_AP_MODE(ipa_ctx->mode))
 		num_tx_pipes--;
 
-	for (i = 0; i < num_tx_pipes; i++)
-		if (ipa_ctx->sys[tx_pipes[i]].ep->valid)
-			ipa_handle_tx_poll_for_pipe(&ipa_ctx->sys[tx_pipes[i]]);
+	do {
+		cnt = 0;
+
+		/* check all the system pipes for tx comp and rx avail */
+		if (ipa_ctx->sys[IPA_A5_LAN_WAN_IN].ep->valid)
+			cnt |= ipa_handle_rx_core(false, true);
+
+		for (i = 0; i < num_tx_pipes; i++)
+			if (ipa_ctx->sys[tx_pipes[i]].ep->valid)
+				cnt |= ipa_handle_tx_poll_for_pipe(
+						&ipa_ctx->sys[tx_pipes[i]],
+						false);
+	} while (cnt);
 
 	/* re-post the poll work */
 	INIT_DELAYED_WORK(&ipa_ctx->poll_work, ipa_poll_function);
@@ -710,37 +837,10 @@
 	if (ipa_setup_sys_pipe(&sys_in, &ipa_ctx->clnt_hdl_cmd)) {
 		IPAERR(":setup sys pipe failed.\n");
 		result = -EPERM;
-		goto fail;
-	}
-
-	if (ipa_setup_exception_path()) {
-		IPAERR(":fail to setup excp path\n");
-		result = -EPERM;
 		goto fail_cmd;
 	}
 
-	/* LAN-WAN IN (IPA->A5) */
-	memset(&sys_in, 0, sizeof(struct ipa_sys_connect_params));
-	sys_in.client = IPA_CLIENT_A5_LAN_WAN_CONS;
-	sys_in.desc_fifo_sz = IPA_SYS_DESC_FIFO_SZ;
-	sys_in.ipa_ep_cfg.hdr.hdr_a5_mux = 1;
-	sys_in.ipa_ep_cfg.hdr.hdr_len = 8;  /* size of A5 exception hdr */
-	if (ipa_setup_sys_pipe(&sys_in, &ipa_ctx->clnt_hdl_data_in)) {
-		IPAERR(":setup sys pipe failed.\n");
-		result = -EPERM;
-		goto fail_cmd;
-	}
-	/* LAN-WAN OUT (A5->IPA) */
-	memset(&sys_in, 0, sizeof(struct ipa_sys_connect_params));
-	sys_in.client = IPA_CLIENT_A5_LAN_WAN_PROD;
-	sys_in.desc_fifo_sz = IPA_SYS_DESC_FIFO_SZ;
-	sys_in.ipa_ep_cfg.mode.mode = IPA_BASIC;
-	sys_in.ipa_ep_cfg.mode.dst = IPA_CLIENT_A5_LAN_WAN_CONS;
-	if (ipa_setup_sys_pipe(&sys_in, &ipa_ctx->clnt_hdl_data_out)) {
-		IPAERR(":setup sys pipe failed.\n");
-		result = -EPERM;
-		goto fail_data_out;
-	}
+	/* Start polling, only if needed */
 	if (ipa_ctx->polling_mode) {
 		INIT_DELAYED_WORK(&ipa_ctx->poll_work, ipa_poll_function);
 		result =
@@ -753,15 +853,56 @@
 		}
 	}
 
+	if (ipa_setup_exception_path()) {
+		IPAERR(":fail to setup excp path\n");
+		result = -EPERM;
+		goto fail_schedule_delayed_work;
+	}
+
+	if (ipa_ctx->ipa_hw_type != IPA_HW_v1_0) {
+		if (ipa_setup_dflt_rt_tables()) {
+			IPAERR(":fail to setup dflt routes\n");
+			result = -EPERM;
+			goto fail_schedule_delayed_work;
+		}
+	}
+
+	/* LAN-WAN IN (IPA->A5) */
+	memset(&sys_in, 0, sizeof(struct ipa_sys_connect_params));
+	sys_in.client = IPA_CLIENT_A5_LAN_WAN_CONS;
+	sys_in.desc_fifo_sz = IPA_SYS_DESC_FIFO_SZ;
+	sys_in.ipa_ep_cfg.hdr.hdr_a5_mux = 1;
+	sys_in.ipa_ep_cfg.hdr.hdr_len = 8;  /* size of A5 exception hdr */
+	if (ipa_setup_sys_pipe(&sys_in, &ipa_ctx->clnt_hdl_data_in)) {
+		IPAERR(":setup sys pipe failed.\n");
+		result = -EPERM;
+		goto fail_schedule_delayed_work;
+	}
+	/* LAN-WAN OUT (A5->IPA) */
+	memset(&sys_in, 0, sizeof(struct ipa_sys_connect_params));
+	sys_in.client = IPA_CLIENT_A5_LAN_WAN_PROD;
+	sys_in.desc_fifo_sz = IPA_SYS_DESC_FIFO_SZ;
+	sys_in.ipa_ep_cfg.mode.mode = IPA_BASIC;
+	sys_in.ipa_ep_cfg.mode.dst = IPA_CLIENT_A5_LAN_WAN_CONS;
+	if (ipa_setup_sys_pipe(&sys_in, &ipa_ctx->clnt_hdl_data_out)) {
+		IPAERR(":setup sys pipe failed.\n");
+		result = -EPERM;
+		goto fail_data_out;
+	}
+
 	return 0;
 
-fail_schedule_delayed_work:
-	ipa_teardown_sys_pipe(ipa_ctx->clnt_hdl_data_out);
 fail_data_out:
 	ipa_teardown_sys_pipe(ipa_ctx->clnt_hdl_data_in);
-fail_cmd:
+fail_schedule_delayed_work:
+	if (ipa_ctx->dflt_v6_rt_rule_hdl)
+		__ipa_del_rt_rule(ipa_ctx->dflt_v6_rt_rule_hdl);
+	if (ipa_ctx->dflt_v4_rt_rule_hdl)
+		__ipa_del_rt_rule(ipa_ctx->dflt_v4_rt_rule_hdl);
+	if (ipa_ctx->excp_hdr_hdl)
+		__ipa_del_hdr(ipa_ctx->excp_hdr_hdl);
 	ipa_teardown_sys_pipe(ipa_ctx->clnt_hdl_cmd);
-fail:
+fail_cmd:
 	return result;
 }
 
@@ -770,6 +911,9 @@
 	cancel_delayed_work(&ipa_ctx->poll_work);
 	ipa_teardown_sys_pipe(ipa_ctx->clnt_hdl_data_out);
 	ipa_teardown_sys_pipe(ipa_ctx->clnt_hdl_data_in);
+	__ipa_del_rt_rule(ipa_ctx->dflt_v6_rt_rule_hdl);
+	__ipa_del_rt_rule(ipa_ctx->dflt_v4_rt_rule_hdl);
+	__ipa_del_hdr(ipa_ctx->excp_hdr_hdl);
 	ipa_teardown_sys_pipe(ipa_ctx->clnt_hdl_cmd);
 }
 
@@ -925,26 +1069,62 @@
 	return 0;
 }
 
+/**
+* ipa_get_a2_mux_bam_info() - Exposes A2 parameters fetched from
+* DTS
+*
+* @a2_bam_mem_base: A2 BAM Memory base
+* @a2_bam_mem_size: A2 BAM Memory size
+* @a2_bam_irq: A2 BAM IRQ
+*
+* Return codes:
+* 0: success
+* -EFAULT: invalid parameters
+*/
+int ipa_get_a2_mux_bam_info(u32 *a2_bam_mem_base, u32 *a2_bam_mem_size,
+			    u32 *a2_bam_irq)
+{
+	if (!a2_bam_mem_base || !a2_bam_mem_size || !a2_bam_irq) {
+		IPAERR("ipa_get_a2_mux_bam_info null args\n");
+		return -EFAULT;
+	}
+
+	*a2_bam_mem_base = ipa_res.a2_bam_mem_base;
+	*a2_bam_mem_size = ipa_res.a2_bam_mem_size;
+	*a2_bam_irq = ipa_res.a2_bam_irq;
+
+	return 0;
+}
+
 static void ipa_set_aggregation_params(void)
 {
 	struct ipa_ep_cfg_aggr agg_params;
+	struct ipa_ep_cfg_hdr hdr_params;
 	u32 producer_hdl = 0;
 	u32 consumer_hdl = 0;
 
 	rmnet_bridge_get_client_handles(&producer_hdl, &consumer_hdl);
 
+	/* configure aggregation on producer */
+	memset(&agg_params, 0, sizeof(struct ipa_ep_cfg_aggr));
+	agg_params.aggr_en = IPA_ENABLE_AGGR;
 	agg_params.aggr = ipa_ctx->aggregation_type;
 	agg_params.aggr_byte_limit = ipa_ctx->aggregation_byte_limit;
 	agg_params.aggr_time_limit = ipa_ctx->aggregation_time_limit;
-
-	/* configure aggregation on producer */
-	agg_params.aggr_en = IPA_ENABLE_AGGR;
 	ipa_cfg_ep_aggr(producer_hdl, &agg_params);
 
-	/* configure deaggregation on consumer */
-	agg_params.aggr_en = IPA_ENABLE_DEAGGR;
-	ipa_cfg_ep_aggr(consumer_hdl, &agg_params);
+	if (ipa_ctx->ipa_hw_type == IPA_HW_v1_0) {
+		/* configure header on producer */
+		memset(&hdr_params, 0, sizeof(struct ipa_ep_cfg_hdr));
+		hdr_params.hdr_len = 1;
+		ipa_cfg_ep_hdr(producer_hdl, &hdr_params);
+	}
 
+	/* configure deaggregation on consumer */
+	memset(&agg_params, 0, sizeof(struct ipa_ep_cfg_aggr));
+	agg_params.aggr_en = IPA_ENABLE_DEAGGR;
+	agg_params.aggr = ipa_ctx->aggregation_type;
+	ipa_cfg_ep_aggr(consumer_hdl, &agg_params);
 }
 
 /*
@@ -1158,6 +1338,13 @@
 		return -ENODEV;
 	}
 
+	ipa_inactivity_clk = clk_get(dev, "inactivity_clk");
+	if (IS_ERR(ipa_inactivity_clk)) {
+		ipa_inactivity_clk = NULL;
+		IPAERR("fail to get inactivity clk\n");
+		return -ENODEV;
+	}
+
 	return 0;
 }
 
@@ -1178,7 +1365,12 @@
 	}
 
 	if (ipa_clk_src)
-		clk_set_rate(ipa_clk_src, IPA_V1_CLK_RATE);
+		if (ipa_res.ipa_hw_type == IPA_HW_v1_0)
+			clk_set_rate(ipa_clk_src, IPA_V1_CLK_RATE);
+		else if (ipa_res.ipa_hw_type == IPA_HW_v1_1)
+			clk_set_rate(ipa_clk_src, IPA_V1_1_CLK_RATE);
+		else
+			WARN_ON(1);
 	else
 		WARN_ON(1);
 
@@ -1192,6 +1384,11 @@
 	else
 		WARN_ON(1);
 
+	if (ipa_inactivity_clk)
+		clk_prepare(ipa_inactivity_clk);
+	else
+		WARN_ON(1);
+
 	if (ipa_clk)
 		clk_enable(ipa_clk);
 	else
@@ -1201,6 +1398,14 @@
 		clk_enable(sys_noc_ipa_axi_clk);
 	else
 		WARN_ON(1);
+
+	if (ipa_inactivity_clk)
+		clk_enable(ipa_inactivity_clk);
+	else
+		WARN_ON(1);
+
+	if (msm_bus_scale_client_update_request(ipa_bus_hdl, 1))
+		WARN_ON(1);
 }
 
 /**
@@ -1211,6 +1416,11 @@
 */
 void ipa_disable_clks(void)
 {
+	if (ipa_inactivity_clk)
+		clk_disable_unprepare(ipa_inactivity_clk);
+	else
+		WARN_ON(1);
+
 	if (sys_noc_ipa_axi_clk)
 		clk_disable_unprepare(sys_noc_ipa_axi_clk);
 	else
@@ -1225,22 +1435,98 @@
 		clk_disable_unprepare(ipa_cnoc_clk);
 	else
 		WARN_ON(1);
+
+	if (msm_bus_scale_client_update_request(ipa_bus_hdl, 0))
+		WARN_ON(1);
 }
 
 static int ipa_setup_bam_cfg(const struct ipa_plat_drv_res *res)
 {
 	void *bam_cnfg_bits;
 
-	bam_cnfg_bits = ioremap(res->ipa_mem_base + IPA_BAM_REG_BASE_OFST,
-				IPA_BAM_REMAP_SIZE);
-	if (!bam_cnfg_bits)
-		return -ENOMEM;
-	ipa_write_reg(bam_cnfg_bits, IPA_BAM_CNFG_BITS_OFST,
-		      IPA_BAM_CNFG_BITS_VAL);
-	iounmap(bam_cnfg_bits);
-
+	if ((ipa_ctx->ipa_hw_type == IPA_HW_v1_0) ||
+	    (ipa_ctx->ipa_hw_type == IPA_HW_v1_1)) {
+		bam_cnfg_bits = ioremap(res->ipa_mem_base +
+						IPA_BAM_REG_BASE_OFST,
+					IPA_BAM_REMAP_SIZE);
+		if (!bam_cnfg_bits)
+			return -ENOMEM;
+		ipa_write_reg(bam_cnfg_bits, IPA_BAM_CNFG_BITS_OFST,
+				IPA_BAM_CNFG_BITS_VAL);
+		iounmap(bam_cnfg_bits);
+	}
 	return 0;
 }
+
+static int ipa_init_flt_block(void)
+{
+	int result = 0;
+
+	/*
+	 * SW workaround for Improper Filter Behaviour when neiher Global nor
+	 * Pipe Rules are present => configure dummy global filter rule
+	 * always which results in a miss
+	 */
+	struct ipa_ioc_add_flt_rule *rules;
+	struct ipa_flt_rule_add *rule;
+	struct ipa_ioc_get_rt_tbl rt_lookup;
+	enum ipa_ip_type ip;
+
+	if (ipa_ctx->ipa_hw_type == IPA_HW_v1_1) {
+		size_t sz = sizeof(struct ipa_ioc_add_flt_rule) +
+		   sizeof(struct ipa_flt_rule_add);
+
+		rules = kmalloc(sz, GFP_KERNEL);
+		if (rules == NULL) {
+			IPAERR("fail to alloc mem for dummy filter rule\n");
+			return -ENOMEM;
+		}
+
+		for (ip = IPA_IP_v4; ip < IPA_IP_MAX; ip++) {
+			memset(&rt_lookup, 0,
+					sizeof(struct ipa_ioc_get_rt_tbl));
+			rt_lookup.ip = ip;
+			strlcpy(rt_lookup.name, IPA_DFLT_RT_TBL_NAME,
+					IPA_RESOURCE_NAME_MAX);
+			ipa_get_rt_tbl(&rt_lookup);
+			ipa_put_rt_tbl(rt_lookup.hdl);
+
+			memset(rules, 0, sz);
+			rule = &rules->rules[0];
+			rules->commit = 1;
+			rules->ip = ip;
+			rules->global = 1;
+			rules->num_rules = 1;
+			rule->at_rear = 1;
+			if (ip == IPA_IP_v4) {
+				rule->rule.attrib.attrib_mask =
+					IPA_FLT_PROTOCOL;
+				rule->rule.attrib.u.v4.protocol =
+				   IPA_INVALID_L4_PROTOCOL;
+			} else if (ip == IPA_IP_v6) {
+				rule->rule.attrib.attrib_mask =
+					IPA_FLT_NEXT_HDR;
+				rule->rule.attrib.u.v6.next_hdr =
+				   IPA_INVALID_L4_PROTOCOL;
+			} else {
+				result = -EINVAL;
+				WARN_ON(1);
+				break;
+			}
+			rule->rule.action = IPA_PASS_TO_ROUTING;
+			rule->rule.rt_tbl_hdl = rt_lookup.hdl;
+
+			if (ipa_add_flt_rule(rules) || rules->rules[0].status) {
+				result = -EINVAL;
+				WARN_ON(1);
+				break;
+			}
+		}
+		kfree(rules);
+	}
+	return result;
+}
+
 /**
 * ipa_init() - Initialize the IPA Driver
 *@resource_p:	contain platform specific values from DST file
@@ -1271,6 +1557,7 @@
 * - Create empty routing table in system memory(no committing)
 * - Initialize pipes memory pool with ipa_pipe_mem_init for supported platforms
 * - Create a char-device for IPA
+* - Initialize IPA RM (resource manager)
 */
 static int ipa_init(const struct ipa_plat_drv_res *resource_p)
 {
@@ -1291,6 +1578,10 @@
 
 	IPADBG("polling_mode=%u delay_ms=%u\n", polling_mode, polling_delay_ms);
 	ipa_ctx->polling_mode = polling_mode;
+	if (ipa_ctx->polling_mode)
+		atomic_set(&ipa_ctx->curr_polling_state, 1);
+	else
+		atomic_set(&ipa_ctx->curr_polling_state, 0);
 	IPADBG("hdr_lcl=%u ip4_rt=%u ip6_rt=%u ip4_flt=%u ip6_flt=%u\n",
 	       hdr_tbl_lcl, ip4_rt_tbl_lcl, ip6_rt_tbl_lcl, ip4_flt_tbl_lcl,
 	       ip6_flt_tbl_lcl);
@@ -1301,6 +1592,8 @@
 	ipa_ctx->ip6_flt_tbl_lcl = ip6_flt_tbl_lcl;
 
 	ipa_ctx->ipa_wrapper_base = resource_p->ipa_mem_base;
+	ipa_ctx->ipa_hw_type = resource_p->ipa_hw_type;
+	ipa_ctx->ipa_hw_mode = resource_p->ipa_hw_mode;
 
 	/* setup IPA register access */
 	ipa_ctx->mmio = ioremap(resource_p->ipa_mem_base + IPA_REG_BASE_OFST,
@@ -1317,9 +1610,32 @@
 		result = -ENODEV;
 		goto fail_init_hw;
 	}
+
+	if (ipa_ctx->ipa_hw_type == IPA_HW_v1_0) {
+		/* setup chicken bits */
+		result = ipa_set_single_ndp_per_mbim(true);
+		if (result) {
+			IPAERR(":failed to set single ndp per mbim.\n");
+			result = -EFAULT;
+			goto fail_init_hw;
+		}
+
+		result = ipa_set_hw_timer_fix_for_mbim_aggr(true);
+		if (result) {
+			IPAERR(":failed to set HW timer fix for MBIM agg.\n");
+			result = -EFAULT;
+			goto fail_init_hw;
+		}
+	}
+
+
 	/* read how much SRAM is available for SW use */
-	ipa_ctx->smem_sz = ipa_read_reg(ipa_ctx->mmio,
-			IPA_SHARED_MEM_SIZE_OFST);
+	if (ipa_ctx->ipa_hw_type == IPA_HW_v1_0)
+		ipa_ctx->smem_sz = ipa_read_reg(ipa_ctx->mmio,
+				IPA_SHARED_MEM_SIZE_OFST_v1);
+	else
+		ipa_ctx->smem_sz = ipa_read_reg(ipa_ctx->mmio,
+				IPA_SHARED_MEM_SIZE_OFST_v2);
 
 	if (IPA_RAM_END_OFST > ipa_ctx->smem_sz) {
 		IPAERR("SW expect more core memory, needed %d, avail %d\n",
@@ -1356,7 +1672,7 @@
 	}
 
 	/* set up the default op mode */
-	ipa_ctx->mode = IPA_MODE_USB_DONGLE;
+	ipa_ctx->mode = IPA_MODE_MOBILE_AP_WAN;
 
 	/* init the lookaside cache */
 	ipa_ctx->flt_rule_cache = kmem_cache_create("IPA FLT",
@@ -1423,14 +1739,18 @@
 	/*
 	 * setup DMA pool 4 byte aligned, don't cross 1k boundaries, nominal
 	 * size 512 bytes
+	 * This is an issue with IPA HW v1.0 only.
 	 */
-	ipa_ctx->one_kb_no_straddle_pool = dma_pool_create("ipa_1k", NULL,
-			IPA_DMA_POOL_SIZE, IPA_DMA_POOL_ALIGNMENT,
-			IPA_DMA_POOL_BOUNDARY);
-	if (!ipa_ctx->one_kb_no_straddle_pool) {
-		IPAERR("cannot setup 1kb alloc DMA pool.\n");
-		result = -ENOMEM;
-		goto fail_dma_pool;
+	if (ipa_ctx->ipa_hw_type == IPA_HW_v1_0) {
+		ipa_ctx->one_kb_no_straddle_pool = dma_pool_create("ipa_1k",
+				NULL,
+				IPA_DMA_POOL_SIZE, IPA_DMA_POOL_ALIGNMENT,
+				IPA_DMA_POOL_BOUNDARY);
+		if (!ipa_ctx->one_kb_no_straddle_pool) {
+			IPAERR("cannot setup 1kb alloc DMA pool.\n");
+			result = -ENOMEM;
+			goto fail_dma_pool;
+		}
 	}
 
 	ipa_ctx->glob_flt_tbl[IPA_IP_v4].in_sys = !ipa_ctx->ip4_flt_tbl_lcl;
@@ -1461,6 +1781,12 @@
 	rset = &ipa_ctx->reap_rt_tbl_set[IPA_IP_v6];
 	INIT_LIST_HEAD(&rset->head_rt_tbl_list);
 
+	INIT_LIST_HEAD(&ipa_ctx->intf_list);
+	INIT_LIST_HEAD(&ipa_ctx->msg_list);
+	INIT_LIST_HEAD(&ipa_ctx->pull_msg_list);
+	init_waitqueue_head(&ipa_ctx->msg_waitq);
+	mutex_init(&ipa_ctx->msg_lock);
+
 	mutex_init(&ipa_ctx->lock);
 	mutex_init(&ipa_ctx->nat_mem.lock);
 
@@ -1492,6 +1818,7 @@
 	ipa_ctx->rt_rule_hdl_tree = RB_ROOT;
 	ipa_ctx->rt_tbl_hdl_tree = RB_ROOT;
 	ipa_ctx->flt_rule_hdl_tree = RB_ROOT;
+	ipa_ctx->tag_tree = RB_ROOT;
 
 	atomic_set(&ipa_ctx->ipa_active_clients, 0);
 
@@ -1511,9 +1838,11 @@
 
 	ipa_replenish_rx_cache();
 
-	/* init the filtering block */
-	ipa_commit_flt(IPA_IP_v4);
-	ipa_commit_flt(IPA_IP_v6);
+	if (ipa_init_flt_block()) {
+		IPAERR("fail to setup dummy filter rules\n");
+		result = -ENODEV;
+		goto fail_empty_rt_tbl;
+	}
 
 	/*
 	 * setup an empty routing table in system memory, this will be used
@@ -1570,13 +1899,35 @@
 	ipa_ctx->aggregation_type = IPA_MBIM_16;
 	ipa_ctx->aggregation_byte_limit = 1;
 	ipa_ctx->aggregation_time_limit = 0;
-	IPADBG(":IPA driver init OK.\n");
+
+	/* Initialize IPA RM (resource manager) */
+	result = ipa_rm_initialize();
+	if (result) {
+		IPAERR(":cdev_add err=%d\n", -result);
+		result = -ENODEV;
+		goto fail_ipa_rm_init;
+	}
+
+	a2_mux_init();
+
+	/* Initialize the tethering bridge driver */
+	result = teth_bridge_driver_init();
+	if (result) {
+		IPAERR(":teth_bridge_driver_init() failed\n");
+		result = -ENODEV;
+		goto fail_cdev_add;
+	}
 
 	/* gate IPA clocks */
-	ipa_disable_clks();
+	if (ipa_ctx->ipa_hw_mode == IPA_HW_MODE_NORMAL)
+		ipa_disable_clks();
+
+	IPADBG(":IPA driver init OK.\n");
 
 	return 0;
 
+fail_ipa_rm_init:
+	cdev_del(&ipa_ctx->cdev);
 fail_cdev_add:
 	device_destroy(ipa_ctx->class, ipa_ctx->dev_num);
 fail_device_create:
@@ -1598,7 +1949,11 @@
 fail_tx_wq:
 	destroy_workqueue(ipa_ctx->rx_wq);
 fail_rx_wq:
-	dma_pool_destroy(ipa_ctx->one_kb_no_straddle_pool);
+	/*
+	 * DMA pool need to be released only for IPA HW v1.0 only.
+	 */
+	if (ipa_ctx->ipa_hw_type == IPA_HW_v1_0)
+		dma_pool_destroy(ipa_ctx->one_kb_no_straddle_pool);
 fail_dma_pool:
 	kmem_cache_destroy(ipa_ctx->tree_node_cache);
 fail_tree_node_cache:
@@ -1627,7 +1982,8 @@
 	ipa_ctx = NULL;
 fail_mem:
 	/* gate IPA clocks */
-	ipa_disable_clks();
+	if (ipa_ctx->ipa_hw_mode == IPA_HW_MODE_NORMAL)
+		ipa_disable_clks();
 	return result;
 }
 
@@ -1635,11 +1991,14 @@
 {
 	int result = 0;
 	struct resource *resource_p;
+
 	IPADBG("IPA plat drv probe\n");
 
 	/* initialize ipa_res */
 	ipa_res.ipa_pipe_mem_start_ofst = IPA_PIPE_MEM_START_OFST;
 	ipa_res.ipa_pipe_mem_size = IPA_PIPE_MEM_SIZE;
+	ipa_res.ipa_hw_type = 0;
+	ipa_res.ipa_hw_mode = 0;
 
 	result = ipa_load_pipe_connection(pdev_p,
 					A2_TO_IPA,
@@ -1676,6 +2035,18 @@
 		ipa_res.bam_mem_size = resource_size(resource_p);
 	}
 
+	/* Get IPA A2 BAM address */
+	resource_p = platform_get_resource_byname(pdev_p, IORESOURCE_MEM,
+			"a2-bam-base");
+
+	if (!resource_p) {
+		IPAERR(":get resource failed for a2-bam-base!\n");
+		return -ENODEV;
+	} else {
+		ipa_res.a2_bam_mem_base = resource_p->start;
+		ipa_res.a2_bam_mem_size = resource_size(resource_p);
+	}
+
 	/* Get IPA pipe mem start ofst */
 	resource_p = platform_get_resource_byname(pdev_p, IORESOURCE_MEM,
 			"ipa-pipe-mem");
@@ -1709,6 +2080,36 @@
 		ipa_res.bam_irq = resource_p->start;
 	}
 
+	/* Get IPA A2 BAM IRQ number */
+	resource_p = platform_get_resource_byname(pdev_p, IORESOURCE_IRQ,
+			"a2-bam-irq");
+
+	if (!resource_p) {
+		IPAERR(":get resource failed for a2-bam-irq!\n");
+		return -ENODEV;
+	} else {
+		ipa_res.a2_bam_irq = resource_p->start;
+	}
+
+	/* Get IPA HW Version */
+	result = of_property_read_u32(pdev_p->dev.of_node, "qcom,ipa-hw-ver",
+					&ipa_res.ipa_hw_type);
+
+	if ((result) || (ipa_res.ipa_hw_type == 0)) {
+		IPAERR(":get resource failed for ipa-hw-ver!\n");
+		return -ENODEV;
+	}
+	IPADBG(": found ipa_res.ipa_hw_type = %d", ipa_res.ipa_hw_type);
+
+	/* Get IPA HW mode */
+	result = of_property_read_u32(pdev_p->dev.of_node, "ipa-hw-mode",
+			&ipa_res.ipa_hw_mode);
+
+	if (result)
+		IPADBG("using default (IPA_MODE_NORMAL) for ipa-hw-mode\n");
+	else
+		IPADBG(": found ipa_res.ipa_hw_mode = %d", ipa_res.ipa_hw_mode);
+
 	IPADBG(":ipa_mem_base = 0x%x, ipa_mem_size = 0x%x\n",
 	       ipa_res.ipa_mem_base, ipa_res.ipa_mem_size);
 	IPADBG(":bam_mem_base = 0x%x, bam_mem_size = 0x%x\n",
@@ -1722,12 +2123,24 @@
 	/* stash the IPA dev ptr */
 	ipa_dev = &pdev_p->dev;
 
-	/* get IPA clocks */
-	if (ipa_get_clks(ipa_dev) != 0)
-		return -ENODEV;
+	if (ipa_res.ipa_hw_mode == IPA_HW_MODE_NORMAL) {
+		/* get IPA clocks */
+		if (ipa_get_clks(ipa_dev) != 0) {
+			IPAERR(":fail to get clk handle's!\n");
+			return -ENODEV;
+		}
 
-	/* enable IPA clocks */
-	ipa_enable_clks();
+		/* get BUS handle */
+		ipa_bus_hdl =
+			msm_bus_scale_register_client(&ipa_bus_client_pdata);
+		if (!ipa_bus_hdl) {
+			IPAERR(":fail to register with bus mgr!\n");
+			return -ENODEV;
+		}
+
+		/* enable IPA clocks */
+		ipa_enable_clks();
+	}
 
 	/* Proceed to real initialization */
 	result = ipa_init(&ipa_res);
@@ -1761,11 +2174,6 @@
 	},
 };
 
-static int ipa_plat_drv_init(void)
-{
-	return platform_driver_register(&ipa_plat_drv);
-}
-
 struct ipa_context *ipa_get_ctx(void)
 {
 	return ipa_ctx;
@@ -1776,14 +2184,15 @@
 	int result = 0;
 
 	IPADBG("IPA module init\n");
-	ipa_debugfs_init();
+
 	/* Register as a platform device driver */
-	result = ipa_plat_drv_init();
+	platform_driver_register(&ipa_plat_drv);
+
+	ipa_debugfs_init();
 
 	return result;
 }
-
-late_initcall(ipa_module_init);
+subsys_initcall(ipa_module_init);
 
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("IPA HW device driver");
diff --git a/drivers/platform/msm/ipa/ipa_bridge.c b/drivers/platform/msm/ipa/ipa_bridge.c
index a6221b8..0227ee4 100644
--- a/drivers/platform/msm/ipa/ipa_bridge.c
+++ b/drivers/platform/msm/ipa/ipa_bridge.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
@@ -14,23 +14,26 @@
 #include <linux/ratelimit.h>
 #include "ipa_i.h"
 
-enum ipa_bridge_id {
+#define A2_EMBEDDED_PIPE_TX 4
+#define A2_EMBEDDED_PIPE_RX 5
+
+enum ipa_pipe_type {
 	IPA_DL_FROM_A2,
 	IPA_DL_TO_IPA,
 	IPA_UL_FROM_IPA,
 	IPA_UL_TO_A2,
-	IPA_BRIDGE_ID_MAX
+	IPA_PIPE_TYPE_MAX
 };
 
-static int polling_min_sleep[IPA_DIR_MAX] = { 950, 950 };
-static int polling_max_sleep[IPA_DIR_MAX] = { 1050, 1050 };
-static int polling_inactivity[IPA_DIR_MAX] = { 4, 4 };
+static int polling_min_sleep[IPA_BRIDGE_DIR_MAX] = { 950, 950 };
+static int polling_max_sleep[IPA_BRIDGE_DIR_MAX] = { 1050, 1050 };
+static int polling_inactivity[IPA_BRIDGE_DIR_MAX] = { 4, 4 };
 
 struct ipa_pkt_info {
 	void *buffer;
 	dma_addr_t dma_address;
 	uint32_t len;
-	struct list_head list_node;
+	struct list_head link;
 };
 
 struct ipa_bridge_pipe_context {
@@ -39,54 +42,62 @@
 	struct sps_connect connection;
 	struct sps_mem_buffer desc_mem_buf;
 	struct sps_register_event register_event;
-	spinlock_t spinlock;
-	u32 len;
-	u32 free_len;
 	struct list_head free_desc_list;
 };
 
-static struct ipa_bridge_pipe_context bridge[IPA_BRIDGE_ID_MAX];
+struct ipa_bridge_context {
+	struct ipa_bridge_pipe_context pipe[IPA_PIPE_TYPE_MAX];
+	struct workqueue_struct *ul_wq;
+	struct workqueue_struct *dl_wq;
+	struct work_struct ul_work;
+	struct work_struct dl_work;
+	enum ipa_bridge_type type;
+};
 
-static struct workqueue_struct *ipa_ul_workqueue;
-static struct workqueue_struct *ipa_dl_workqueue;
-static void ipa_do_bridge_work(enum ipa_bridge_dir dir);
+static struct ipa_bridge_context bridge[IPA_BRIDGE_TYPE_MAX];
 
-static u32 alloc_cnt[IPA_DIR_MAX];
+static void ipa_do_bridge_work(enum ipa_bridge_dir dir,
+		struct ipa_bridge_context *ctx);
 
 static void ul_work_func(struct work_struct *work)
 {
-	ipa_do_bridge_work(IPA_UL);
+	struct ipa_bridge_context *ctx = container_of(work,
+			struct ipa_bridge_context, ul_work);
+	ipa_do_bridge_work(IPA_BRIDGE_DIR_UL, ctx);
 }
 
 static void dl_work_func(struct work_struct *work)
 {
-	ipa_do_bridge_work(IPA_DL);
+	struct ipa_bridge_context *ctx = container_of(work,
+			struct ipa_bridge_context, dl_work);
+	ipa_do_bridge_work(IPA_BRIDGE_DIR_DL, ctx);
 }
 
-static DECLARE_WORK(ul_work, ul_work_func);
-static DECLARE_WORK(dl_work, dl_work_func);
-
-static int ipa_switch_to_intr_mode(enum ipa_bridge_dir dir)
+static int ipa_switch_to_intr_mode(enum ipa_bridge_dir dir,
+				    struct ipa_bridge_context *ctx)
 {
 	int ret;
-	struct ipa_bridge_pipe_context *sys = &bridge[2 * dir];
+	struct ipa_bridge_pipe_context *sys = &ctx->pipe[2 * dir];
 
 	ret = sps_get_config(sys->pipe, &sys->connection);
 	if (ret) {
-		IPAERR("sps_get_config() failed %d\n", ret);
+		IPAERR("sps_get_config() failed %d type=%d dir=%d\n",
+				ret, ctx->type, dir);
 		goto fail;
 	}
 	sys->register_event.options = SPS_O_EOT;
 	ret = sps_register_event(sys->pipe, &sys->register_event);
 	if (ret) {
-		IPAERR("sps_register_event() failed %d\n", ret);
+		IPAERR("sps_register_event() failed %d type=%d dir=%d\n",
+				ret, ctx->type, dir);
 		goto fail;
 	}
 	sys->connection.options =
 	   SPS_O_AUTO_ENABLE | SPS_O_ACK_TRANSFERS | SPS_O_EOT;
 	ret = sps_set_config(sys->pipe, &sys->connection);
 	if (ret) {
-		IPAERR("sps_set_config() failed %d\n", ret);
+		IPAERR("sps_set_config() failed %d type=%d dir=%d\n",
+				ret, ctx->type, dir);
 		goto fail;
 	}
 	ret = 0;
@@ -94,21 +105,24 @@
 	return ret;
 }
 
-static int ipa_switch_to_poll_mode(enum ipa_bridge_dir dir)
+static int ipa_switch_to_poll_mode(enum ipa_bridge_dir dir,
+				    enum ipa_bridge_type type)
 {
 	int ret;
-	struct ipa_bridge_pipe_context *sys = &bridge[2 * dir];
+	struct ipa_bridge_pipe_context *sys = &bridge[type].pipe[2 * dir];
 
 	ret = sps_get_config(sys->pipe, &sys->connection);
 	if (ret) {
-		IPAERR("sps_get_config() failed %d\n", ret);
+		IPAERR("sps_get_config() failed %d type=%d dir=%d\n",
+				ret, type, dir);
 		goto fail;
 	}
 	sys->connection.options =
 	   SPS_O_AUTO_ENABLE | SPS_O_ACK_TRANSFERS | SPS_O_POLL;
 	ret = sps_set_config(sys->pipe, &sys->connection);
 	if (ret) {
-		IPAERR("sps_set_config() failed %d\n", ret);
+		IPAERR("sps_set_config() failed %d type=%d dir=%d\n",
+				ret, type, dir);
 		goto fail;
 	}
 	ret = 0;
@@ -116,46 +130,47 @@
 	return ret;
 }
 
-static int queue_rx_single(enum ipa_bridge_dir dir)
+static int queue_rx_single(enum ipa_bridge_dir dir, enum ipa_bridge_type type)
 {
-	struct ipa_bridge_pipe_context *sys_rx = &bridge[2 * dir];
+	struct ipa_bridge_pipe_context *sys_rx = &bridge[type].pipe[2 * dir];
 	struct ipa_pkt_info *info;
 	int ret;
 
 	info = kmalloc(sizeof(struct ipa_pkt_info), GFP_KERNEL);
 	if (!info) {
-		IPAERR("unable to alloc rx_pkt_info\n");
+		IPAERR("unable to alloc rx_pkt_info type=%d dir=%d\n",
+				type, dir);
 		goto fail_pkt;
 	}
 
 	info->buffer = kmalloc(IPA_RX_SKB_SIZE, GFP_KERNEL | GFP_DMA);
 	if (!info->buffer) {
-		IPAERR("unable to alloc rx_pkt_buffer\n");
+		IPAERR("unable to alloc rx_pkt_buffer type=%d dir=%d\n",
+				type, dir);
 		goto fail_buffer;
 	}
 
 	info->dma_address = dma_map_single(NULL, info->buffer, IPA_RX_SKB_SIZE,
 					   DMA_BIDIRECTIONAL);
 	if (info->dma_address == 0 || info->dma_address == ~0) {
-		IPAERR("dma_map_single failure %p for %p\n",
-				(void *)info->dma_address, info->buffer);
+		IPAERR("dma_map_single failure %p for %p type=%d dir=%d\n",
+				(void *)info->dma_address, info->buffer,
+				type, dir);
 		goto fail_dma;
 	}
 
-	info->len = ~0;
-
-	list_add_tail(&info->list_node, &sys_rx->head_desc_list);
+	list_add_tail(&info->link, &sys_rx->head_desc_list);
 	ret = sps_transfer_one(sys_rx->pipe, info->dma_address,
 			       IPA_RX_SKB_SIZE, info,
-			       SPS_IOVEC_FLAG_INT | SPS_IOVEC_FLAG_EOT);
+			       SPS_IOVEC_FLAG_INT);
 	if (ret) {
-		list_del(&info->list_node);
+		list_del(&info->link);
 		dma_unmap_single(NULL, info->dma_address, IPA_RX_SKB_SIZE,
 				 DMA_BIDIRECTIONAL);
-		IPAERR("sps_transfer_one failed %d\n", ret);
+		IPAERR("sps_transfer_one failed %d type=%d dir=%d\n", ret,
+				type, dir);
 		goto fail_dma;
 	}
-	sys_rx->len++;
 	return 0;
 
 fail_dma:
@@ -163,7 +178,7 @@
 fail_buffer:
 	kfree(info);
 fail_pkt:
-	IPAERR("failed\n");
+	IPAERR("failed type=%d dir=%d\n", type, dir);
 	return -ENOMEM;
 }
 
@@ -182,12 +197,9 @@
 		} else {
 			tx_pkt = list_first_entry(&sys_tx->head_desc_list,
 						  struct ipa_pkt_info,
-						  list_node);
-			list_move_tail(&tx_pkt->list_node,
+						  link);
+			list_move_tail(&tx_pkt->link,
 					&sys_tx->free_desc_list);
-			sys_tx->len--;
-			sys_tx->free_len++;
-			tx_pkt->len = ~0;
 			cnt++;
 		}
 	} while (all);
@@ -195,10 +207,11 @@
 	return cnt;
 }
 
-static void ipa_do_bridge_work(enum ipa_bridge_dir dir)
+static void ipa_do_bridge_work(enum ipa_bridge_dir dir,
+			       struct ipa_bridge_context *ctx)
 {
-	struct ipa_bridge_pipe_context *sys_rx = &bridge[2 * dir];
-	struct ipa_bridge_pipe_context *sys_tx = &bridge[2 * dir + 1];
+	struct ipa_bridge_pipe_context *sys_rx = &ctx->pipe[2 * dir];
+	struct ipa_bridge_pipe_context *sys_tx = &ctx->pipe[2 * dir + 1];
 	struct ipa_pkt_info *tx_pkt;
 	struct ipa_pkt_info *rx_pkt;
 	struct ipa_pkt_info *tmp_pkt;
@@ -221,9 +234,8 @@
 
 			rx_pkt = list_first_entry(&sys_rx->head_desc_list,
 						  struct ipa_pkt_info,
-						  list_node);
-			list_del(&rx_pkt->list_node);
-			sys_rx->len--;
+						  link);
+			list_del(&rx_pkt->link);
 			rx_pkt->len = iov.size;
 
 retry_alloc_tx:
@@ -231,8 +243,8 @@
 				tmp_pkt = kmalloc(sizeof(struct ipa_pkt_info),
 						GFP_KERNEL);
 				if (!tmp_pkt) {
-					pr_debug_ratelimited("%s: unable to alloc tx_pkt_info\n",
-					       __func__);
+					pr_debug_ratelimited("%s: unable to alloc tx_pkt_info type=%d dir=%d\n",
+					       __func__, ctx->type, dir);
 					usleep_range(polling_min_sleep[dir],
 							polling_max_sleep[dir]);
 					goto retry_alloc_tx;
@@ -241,8 +253,8 @@
 				tmp_pkt->buffer = kmalloc(IPA_RX_SKB_SIZE,
 						GFP_KERNEL | GFP_DMA);
 				if (!tmp_pkt->buffer) {
-					pr_debug_ratelimited("%s: unable to alloc tx_pkt_buffer\n",
-					       __func__);
+					pr_debug_ratelimited("%s: unable to alloc tx_pkt_buffer type=%d dir=%d\n",
+					       __func__, ctx->type, dir);
 					kfree(tmp_pkt);
 					usleep_range(polling_min_sleep[dir],
 							polling_max_sleep[dir]);
@@ -255,47 +267,40 @@
 						DMA_BIDIRECTIONAL);
 				if (tmp_pkt->dma_address == 0 ||
 						tmp_pkt->dma_address == ~0) {
-					pr_debug_ratelimited("%s: dma_map_single failure %p for %p\n",
+					pr_debug_ratelimited("%s: dma_map_single failure %p for %p type=%d dir=%d\n",
 					       __func__,
 					       (void *)tmp_pkt->dma_address,
-					       tmp_pkt->buffer);
+					       tmp_pkt->buffer, ctx->type, dir);
 				}
 
-				list_add_tail(&tmp_pkt->list_node,
+				list_add_tail(&tmp_pkt->link,
 						&sys_tx->free_desc_list);
-				sys_tx->free_len++;
-				alloc_cnt[dir]++;
-
-				tmp_pkt->len = ~0;
 			}
 
 			tx_pkt = list_first_entry(&sys_tx->free_desc_list,
 						  struct ipa_pkt_info,
-						  list_node);
-			list_del(&tx_pkt->list_node);
-			sys_tx->free_len--;
+						  link);
+			list_del(&tx_pkt->link);
 
 retry_add_rx:
-			list_add_tail(&tx_pkt->list_node,
+			list_add_tail(&tx_pkt->link,
 					&sys_rx->head_desc_list);
 			ret = sps_transfer_one(sys_rx->pipe,
 					tx_pkt->dma_address,
 					IPA_RX_SKB_SIZE,
 					tx_pkt,
-					SPS_IOVEC_FLAG_INT |
-					SPS_IOVEC_FLAG_EOT);
+					SPS_IOVEC_FLAG_INT);
 			if (ret) {
-				list_del(&tx_pkt->list_node);
-				pr_debug_ratelimited("%s: sps_transfer_one failed %d\n",
-						__func__, ret);
+				list_del(&tx_pkt->link);
+				pr_debug_ratelimited("%s: sps_transfer_one failed %d type=%d dir=%d\n",
+						__func__, ret, ctx->type, dir);
 				usleep_range(polling_min_sleep[dir],
 						polling_max_sleep[dir]);
 				goto retry_add_rx;
 			}
-			sys_rx->len++;
 
 retry_add_tx:
-			list_add_tail(&rx_pkt->list_node,
+			list_add_tail(&rx_pkt->link,
 					&sys_tx->head_desc_list);
 			ret = sps_transfer_one(sys_tx->pipe,
 					       rx_pkt->dma_address,
@@ -304,19 +309,20 @@
 					       SPS_IOVEC_FLAG_INT |
 					       SPS_IOVEC_FLAG_EOT);
 			if (ret) {
-				pr_debug_ratelimited("%s: fail to add to TX dir=%d\n",
-						__func__, dir);
-				list_del(&rx_pkt->list_node);
+				pr_debug_ratelimited("%s: fail to add to TX type=%d dir=%d\n",
+						__func__, ctx->type, dir);
+				list_del(&rx_pkt->link);
 				ipa_reclaim_tx(sys_tx, true);
 				usleep_range(polling_min_sleep[dir],
 						polling_max_sleep[dir]);
 				goto retry_add_tx;
 			}
-			sys_tx->len++;
+			IPA_STATS_INC_BRIDGE_CNT(ctx->type, dir,
+					ipa_ctx->stats.bridged_pkts);
 		}
 
 		if (inactive_cycles >= polling_inactivity[dir]) {
-			ipa_switch_to_intr_mode(dir);
+			ipa_switch_to_intr_mode(dir, ctx);
 			break;
 		}
 	}
@@ -324,47 +330,64 @@
 
 static void ipa_sps_irq_rx_notify(struct sps_event_notify *notify)
 {
+	enum ipa_bridge_type type = (enum ipa_bridge_type) notify->user;
+
 	switch (notify->event_id) {
 	case SPS_EVENT_EOT:
-		ipa_switch_to_poll_mode(IPA_UL);
-		queue_work(ipa_ul_workqueue, &ul_work);
+		ipa_switch_to_poll_mode(IPA_BRIDGE_DIR_UL, type);
+		queue_work(bridge[type].ul_wq, &bridge[type].ul_work);
 		break;
 	default:
-		IPAERR("recieved unexpected event id %d\n", notify->event_id);
+		IPAERR("recieved unexpected event id %d type %d\n",
+				notify->event_id, type);
 	}
 }
 
-static int setup_bridge_to_ipa(enum ipa_bridge_dir dir)
+static int setup_bridge_to_ipa(enum ipa_bridge_dir dir,
+			       enum ipa_bridge_type type,
+			       struct ipa_sys_connect_params *props,
+			       u32 *clnt_hdl)
 {
 	struct ipa_bridge_pipe_context *sys;
-	struct ipa_ep_cfg_mode mode;
 	dma_addr_t dma_addr;
+	enum ipa_pipe_type pipe_type;
 	int ipa_ep_idx;
 	int ret;
 	int i;
 
-	if (dir == IPA_DL) {
-		ipa_ep_idx = ipa_get_ep_mapping(ipa_ctx->mode,
-				IPA_CLIENT_A2_TETHERED_PROD);
-		if (ipa_ep_idx == -1) {
-			IPAERR("Invalid client.\n");
-			ret = -EINVAL;
-			goto tx_alloc_endpoint_failed;
-		}
+	ipa_ep_idx = ipa_get_ep_mapping(ipa_ctx->mode, props->client);
+	if (ipa_ep_idx == -1) {
+		IPAERR("Invalid client=%d mode=%d type=%d dir=%d\n",
+				props->client, ipa_ctx->mode, type, dir);
+		ret = -EINVAL;
+		goto alloc_endpoint_failed;
+	}
 
-		sys = &bridge[IPA_DL_TO_IPA];
-		sys->pipe = sps_alloc_endpoint();
-		if (sys->pipe == NULL) {
-			IPAERR("tx alloc endpoint failed\n");
-			ret = -ENOMEM;
-			goto tx_alloc_endpoint_failed;
-		}
-		ret = sps_get_config(sys->pipe, &sys->connection);
-		if (ret) {
-			IPAERR("tx get config failed %d\n", ret);
-			goto tx_get_config_failed;
-		}
+	if (ipa_ctx->ep[ipa_ep_idx].valid) {
+		IPAERR("EP %d already allocated type=%d dir=%d\n", ipa_ep_idx,
+				type, dir);
+		ret = -EINVAL;
+		goto alloc_endpoint_failed;
+	}
 
+	pipe_type = (dir == IPA_BRIDGE_DIR_DL) ? IPA_DL_TO_IPA :
+						 IPA_UL_FROM_IPA;
+
+	sys = &bridge[type].pipe[pipe_type];
+	sys->pipe = sps_alloc_endpoint();
+	if (sys->pipe == NULL) {
+		IPAERR("alloc endpoint failed type=%d dir=%d\n", type, dir);
+		ret = -ENOMEM;
+		goto alloc_endpoint_failed;
+	}
+	ret = sps_get_config(sys->pipe, &sys->connection);
+	if (ret) {
+		IPAERR("get config failed %d type=%d dir=%d\n", ret, type, dir);
+		ret = -EINVAL;
+		goto get_config_failed;
+	}
+
+	if (dir == IPA_BRIDGE_DIR_DL) {
 		sys->connection.source = SPS_DEV_HANDLE_MEM;
 		sys->connection.src_pipe_index = ipa_ctx->a5_pipe_index++;
 		sys->connection.destination = ipa_ctx->bam_handle;
@@ -372,434 +395,451 @@
 		sys->connection.mode = SPS_MODE_DEST;
 		sys->connection.options =
 		   SPS_O_AUTO_ENABLE | SPS_O_ACK_TRANSFERS | SPS_O_POLL;
-		sys->desc_mem_buf.size = IPA_SYS_DESC_FIFO_SZ; /* 2k */
-		sys->desc_mem_buf.base = dma_alloc_coherent(NULL,
-				sys->desc_mem_buf.size,
-				&dma_addr,
-				0);
-		if (sys->desc_mem_buf.base == NULL) {
-			IPAERR("tx memory alloc failed\n");
-			ret = -ENOMEM;
-			goto tx_get_config_failed;
-		}
-		sys->desc_mem_buf.phys_base = dma_addr;
-		memset(sys->desc_mem_buf.base, 0x0, sys->desc_mem_buf.size);
-		sys->connection.desc = sys->desc_mem_buf;
-		sys->connection.event_thresh = IPA_EVENT_THRESHOLD;
-
-		ret = sps_connect(sys->pipe, &sys->connection);
-		if (ret < 0) {
-			IPAERR("tx connect error %d\n", ret);
-			goto tx_connect_failed;
-		}
-
-		INIT_LIST_HEAD(&sys->head_desc_list);
-		INIT_LIST_HEAD(&sys->free_desc_list);
-		spin_lock_init(&sys->spinlock);
-
-		ipa_ctx->ep[ipa_ep_idx].valid = 1;
-
-		mode.mode = IPA_DMA;
-		mode.dst = IPA_CLIENT_USB_CONS;
-		ret = ipa_cfg_ep_mode(ipa_ep_idx, &mode);
-		if (ret < 0) {
-			IPAERR("DMA mode set error %d\n", ret);
-			goto tx_mode_set_failed;
-		}
-
-		return 0;
-
-tx_mode_set_failed:
-		sps_disconnect(sys->pipe);
-tx_connect_failed:
-		dma_free_coherent(NULL, sys->desc_mem_buf.size,
-				sys->desc_mem_buf.base,
-				sys->desc_mem_buf.phys_base);
-tx_get_config_failed:
-		sps_free_endpoint(sys->pipe);
-tx_alloc_endpoint_failed:
-		return ret;
 	} else {
-
-		ipa_ep_idx = ipa_get_ep_mapping(ipa_ctx->mode,
-				IPA_CLIENT_A2_TETHERED_CONS);
-		if (ipa_ep_idx == -1) {
-			IPAERR("Invalid client.\n");
-			ret = -EINVAL;
-			goto rx_alloc_endpoint_failed;
-		}
-
-		sys = &bridge[IPA_UL_FROM_IPA];
-		sys->pipe = sps_alloc_endpoint();
-		if (sys->pipe == NULL) {
-			IPAERR("rx alloc endpoint failed\n");
-			ret = -ENOMEM;
-			goto rx_alloc_endpoint_failed;
-		}
-		ret = sps_get_config(sys->pipe, &sys->connection);
-		if (ret) {
-			IPAERR("rx get config failed %d\n", ret);
-			goto rx_get_config_failed;
-		}
-
 		sys->connection.source = ipa_ctx->bam_handle;
-		sys->connection.src_pipe_index = 7;
+		sys->connection.src_pipe_index = ipa_ep_idx;
 		sys->connection.destination = SPS_DEV_HANDLE_MEM;
 		sys->connection.dest_pipe_index = ipa_ctx->a5_pipe_index++;
 		sys->connection.mode = SPS_MODE_SRC;
 		sys->connection.options = SPS_O_AUTO_ENABLE | SPS_O_EOT |
 		      SPS_O_ACK_TRANSFERS;
-		sys->desc_mem_buf.size = IPA_SYS_DESC_FIFO_SZ; /* 2k */
-		sys->desc_mem_buf.base = dma_alloc_coherent(NULL,
-				sys->desc_mem_buf.size,
-				&dma_addr,
-				0);
-		if (sys->desc_mem_buf.base == NULL) {
-			IPAERR("rx memory alloc failed\n");
-			ret = -ENOMEM;
-			goto rx_get_config_failed;
-		}
-		sys->desc_mem_buf.phys_base = dma_addr;
-		memset(sys->desc_mem_buf.base, 0x0, sys->desc_mem_buf.size);
-		sys->connection.desc = sys->desc_mem_buf;
-		sys->connection.event_thresh = IPA_EVENT_THRESHOLD;
+	}
 
-		ret = sps_connect(sys->pipe, &sys->connection);
-		if (ret < 0) {
-			IPAERR("rx connect error %d\n", ret);
-			goto rx_connect_failed;
-		}
+	sys->desc_mem_buf.size = props->desc_fifo_sz;
+	sys->desc_mem_buf.base = dma_alloc_coherent(NULL,
+						    sys->desc_mem_buf.size,
+						    &dma_addr,
+						    0);
+	if (sys->desc_mem_buf.base == NULL) {
+		IPAERR("memory alloc failed type=%d dir=%d\n", type, dir);
+		ret = -ENOMEM;
+		goto get_config_failed;
+	}
+	sys->desc_mem_buf.phys_base = dma_addr;
+	memset(sys->desc_mem_buf.base, 0x0, sys->desc_mem_buf.size);
+	sys->connection.desc = sys->desc_mem_buf;
+	sys->connection.event_thresh = IPA_EVENT_THRESHOLD;
 
+	ret = sps_connect(sys->pipe, &sys->connection);
+	if (ret < 0) {
+		IPAERR("connect error %d type=%d dir=%d\n", ret, type, dir);
+		goto connect_failed;
+	}
+
+	INIT_LIST_HEAD(&sys->head_desc_list);
+	INIT_LIST_HEAD(&sys->free_desc_list);
+
+	memset(&ipa_ctx->ep[ipa_ep_idx], 0,
+	       sizeof(struct ipa_ep_context));
+
+	ipa_ctx->ep[ipa_ep_idx].valid = 1;
+	ipa_ctx->ep[ipa_ep_idx].client_notify = props->notify;
+	ipa_ctx->ep[ipa_ep_idx].priv = props->priv;
+
+	ret = ipa_cfg_ep(ipa_ep_idx, &props->ipa_ep_cfg);
+	if (ret < 0) {
+		IPAERR("ep cfg set error %d type=%d dir=%d\n", ret, type, dir);
+		ipa_ctx->ep[ipa_ep_idx].valid = 0;
+		goto event_reg_failed;
+	}
+
+	if (dir == IPA_BRIDGE_DIR_UL) {
 		sys->register_event.options = SPS_O_EOT;
 		sys->register_event.mode = SPS_TRIGGER_CALLBACK;
 		sys->register_event.xfer_done = NULL;
 		sys->register_event.callback = ipa_sps_irq_rx_notify;
-		sys->register_event.user = NULL;
+		sys->register_event.user = (void *)type;
 		ret = sps_register_event(sys->pipe, &sys->register_event);
 		if (ret < 0) {
-			IPAERR("tx register event error %d\n", ret);
-			goto rx_event_reg_failed;
+			IPAERR("register event error %d type=%d dir=%d\n", ret,
+					type, dir);
+			goto event_reg_failed;
 		}
 
-		INIT_LIST_HEAD(&sys->head_desc_list);
-		INIT_LIST_HEAD(&sys->free_desc_list);
-		spin_lock_init(&sys->spinlock);
-
 		for (i = 0; i < IPA_RX_POOL_CEIL; i++) {
-			ret = queue_rx_single(dir);
+			ret = queue_rx_single(dir, type);
 			if (ret < 0)
-				IPAERR("queue fail %d %d\n", dir, i);
+				IPAERR("queue fail dir=%d type=%d iter=%d\n",
+				       dir, type, i);
 		}
-
-		return 0;
-
-rx_event_reg_failed:
-		sps_disconnect(sys->pipe);
-rx_connect_failed:
-		dma_free_coherent(NULL,
-				sys->desc_mem_buf.size,
-				sys->desc_mem_buf.base,
-				sys->desc_mem_buf.phys_base);
-rx_get_config_failed:
-		sps_free_endpoint(sys->pipe);
-rx_alloc_endpoint_failed:
-		return ret;
 	}
+
+	*clnt_hdl = ipa_ep_idx;
+
+	return 0;
+
+event_reg_failed:
+	sps_disconnect(sys->pipe);
+connect_failed:
+	dma_free_coherent(NULL,
+			  sys->desc_mem_buf.size,
+			  sys->desc_mem_buf.base,
+			  sys->desc_mem_buf.phys_base);
+get_config_failed:
+	sps_free_endpoint(sys->pipe);
+alloc_endpoint_failed:
+	return ret;
 }
 
 static void bam_mux_rx_notify(struct sps_event_notify *notify)
 {
+	enum ipa_bridge_type type = (enum ipa_bridge_type) notify->user;
+
 	switch (notify->event_id) {
 	case SPS_EVENT_EOT:
-		ipa_switch_to_poll_mode(IPA_DL);
-		queue_work(ipa_dl_workqueue, &dl_work);
+		ipa_switch_to_poll_mode(IPA_BRIDGE_DIR_DL, type);
+		queue_work(bridge[type].dl_wq, &bridge[type].dl_work);
 		break;
 	default:
-		IPAERR("recieved unexpected event id %d\n", notify->event_id);
+		IPAERR("recieved unexpected event id %d type %d\n",
+				notify->event_id, type);
 	}
 }
 
-static int setup_bridge_to_a2(enum ipa_bridge_dir dir)
+static int setup_bridge_to_a2(enum ipa_bridge_dir dir,
+			      enum ipa_bridge_type type,
+			      u32 desc_fifo_sz)
 {
 	struct ipa_bridge_pipe_context *sys;
-	struct a2_mux_pipe_connection pipe_conn = { 0, };
+	struct a2_mux_pipe_connection pipe_conn = { 0 };
 	dma_addr_t dma_addr;
 	u32 a2_handle;
+	enum a2_mux_pipe_direction pipe_dir;
+	enum ipa_pipe_type pipe_type;
+	u32 pa;
 	int ret;
 	int i;
 
-	if (dir == IPA_UL) {
-		ret = ipa_get_a2_mux_pipe_info(IPA_TO_A2, &pipe_conn);
-		if (ret) {
-			IPAERR("ipa_get_a2_mux_pipe_info failed IPA_TO_A2\n");
-			goto tx_alloc_endpoint_failed;
-		}
+	pipe_dir = (dir == IPA_BRIDGE_DIR_UL) ? IPA_TO_A2 : A2_TO_IPA;
 
-		ret = sps_phy2h(pipe_conn.dst_phy_addr, &a2_handle);
-		if (ret) {
-			IPAERR("sps_phy2h failed (A2 BAM) %d\n", ret);
-			goto tx_alloc_endpoint_failed;
-		}
+	ret = ipa_get_a2_mux_pipe_info(pipe_dir, &pipe_conn);
+	if (ret) {
+		IPAERR("ipa_get_a2_mux_pipe_info failed type=%d dir=%d\n",
+				type, dir);
+		ret = -EINVAL;
+		goto alloc_endpoint_failed;
+	}
 
-		sys = &bridge[IPA_UL_TO_A2];
-		sys->pipe = sps_alloc_endpoint();
-		if (sys->pipe == NULL) {
-			IPAERR("tx alloc endpoint failed\n");
-			ret = -ENOMEM;
-			goto tx_alloc_endpoint_failed;
-		}
-		ret = sps_get_config(sys->pipe, &sys->connection);
-		if (ret) {
-			IPAERR("tx get config failed %d\n", ret);
-			goto tx_get_config_failed;
-		}
+	pa = (dir == IPA_BRIDGE_DIR_UL) ? pipe_conn.dst_phy_addr :
+					  pipe_conn.src_phy_addr;
 
+	ret = sps_phy2h(pa, &a2_handle);
+	if (ret) {
+		IPAERR("sps_phy2h failed (A2 BAM) %d type=%d dir=%d\n",
+				ret, type, dir);
+		ret = -EINVAL;
+		goto alloc_endpoint_failed;
+	}
+
+	pipe_type = (dir == IPA_BRIDGE_DIR_UL) ? IPA_UL_TO_A2 : IPA_DL_FROM_A2;
+
+	sys = &bridge[type].pipe[pipe_type];
+	sys->pipe = sps_alloc_endpoint();
+	if (sys->pipe == NULL) {
+		IPAERR("alloc endpoint failed type=%d dir=%d\n", type, dir);
+		ret = -ENOMEM;
+		goto alloc_endpoint_failed;
+	}
+	ret = sps_get_config(sys->pipe, &sys->connection);
+	if (ret) {
+		IPAERR("get config failed %d type=%d dir=%d\n", ret, type, dir);
+		ret = -EINVAL;
+		goto get_config_failed;
+	}
+
+	if (dir == IPA_BRIDGE_DIR_UL) {
 		sys->connection.source = SPS_DEV_HANDLE_MEM;
 		sys->connection.src_pipe_index = ipa_ctx->a5_pipe_index++;
 		sys->connection.destination = a2_handle;
-		sys->connection.dest_pipe_index = pipe_conn.dst_pipe_index;
+		if (type == IPA_BRIDGE_TYPE_TETHERED)
+			sys->connection.dest_pipe_index =
+			   pipe_conn.dst_pipe_index;
+		else
+			sys->connection.dest_pipe_index = A2_EMBEDDED_PIPE_TX;
 		sys->connection.mode = SPS_MODE_DEST;
 		sys->connection.options =
 		   SPS_O_AUTO_ENABLE | SPS_O_ACK_TRANSFERS | SPS_O_POLL;
-		sys->desc_mem_buf.size = IPA_SYS_DESC_FIFO_SZ; /* 2k */
-		sys->desc_mem_buf.base = dma_alloc_coherent(NULL,
-				sys->desc_mem_buf.size,
-				&dma_addr,
-				0);
-		if (sys->desc_mem_buf.base == NULL) {
-			IPAERR("tx memory alloc failed\n");
-			ret = -ENOMEM;
-			goto tx_get_config_failed;
-		}
-		sys->desc_mem_buf.phys_base = dma_addr;
-		memset(sys->desc_mem_buf.base, 0x0, sys->desc_mem_buf.size);
-		sys->connection.desc = sys->desc_mem_buf;
-		sys->connection.event_thresh = IPA_EVENT_THRESHOLD;
-
-		ret = sps_connect(sys->pipe, &sys->connection);
-		if (ret < 0) {
-			IPAERR("tx connect error %d\n", ret);
-			goto tx_connect_failed;
-		}
-
-		INIT_LIST_HEAD(&sys->head_desc_list);
-		INIT_LIST_HEAD(&sys->free_desc_list);
-		spin_lock_init(&sys->spinlock);
-
-		return 0;
-
-tx_connect_failed:
-		dma_free_coherent(NULL,
-				sys->desc_mem_buf.size,
-				sys->desc_mem_buf.base,
-				sys->desc_mem_buf.phys_base);
-tx_get_config_failed:
-		sps_free_endpoint(sys->pipe);
-tx_alloc_endpoint_failed:
-		return ret;
-	} else { /* dir == IPA_UL */
-
-		ret = ipa_get_a2_mux_pipe_info(A2_TO_IPA, &pipe_conn);
-		if (ret) {
-			IPAERR("ipa_get_a2_mux_pipe_info failed A2_TO_IPA\n");
-			goto rx_alloc_endpoint_failed;
-		}
-
-		ret = sps_phy2h(pipe_conn.src_phy_addr, &a2_handle);
-		if (ret) {
-			IPAERR("sps_phy2h failed (A2 BAM) %d\n", ret);
-			goto rx_alloc_endpoint_failed;
-		}
-
-		sys = &bridge[IPA_DL_FROM_A2];
-		sys->pipe = sps_alloc_endpoint();
-		if (sys->pipe == NULL) {
-			IPAERR("rx alloc endpoint failed\n");
-			ret = -ENOMEM;
-			goto rx_alloc_endpoint_failed;
-		}
-		ret = sps_get_config(sys->pipe, &sys->connection);
-		if (ret) {
-			IPAERR("rx get config failed %d\n", ret);
-			goto rx_get_config_failed;
-		}
-
+	} else {
 		sys->connection.source = a2_handle;
-		sys->connection.src_pipe_index = pipe_conn.src_pipe_index;
+		if (type == IPA_BRIDGE_TYPE_TETHERED)
+			sys->connection.src_pipe_index =
+			   pipe_conn.src_pipe_index;
+		else
+			sys->connection.src_pipe_index = A2_EMBEDDED_PIPE_RX;
 		sys->connection.destination = SPS_DEV_HANDLE_MEM;
 		sys->connection.dest_pipe_index = ipa_ctx->a5_pipe_index++;
 		sys->connection.mode = SPS_MODE_SRC;
 		sys->connection.options = SPS_O_AUTO_ENABLE | SPS_O_EOT |
 		      SPS_O_ACK_TRANSFERS;
-		sys->desc_mem_buf.size = IPA_SYS_DESC_FIFO_SZ; /* 2k */
-		sys->desc_mem_buf.base = dma_alloc_coherent(NULL,
-				sys->desc_mem_buf.size,
-				&dma_addr,
-				0);
-		if (sys->desc_mem_buf.base == NULL) {
-			IPAERR("rx memory alloc failed\n");
-			ret = -ENOMEM;
-			goto rx_get_config_failed;
-		}
-		sys->desc_mem_buf.phys_base = dma_addr;
-		memset(sys->desc_mem_buf.base, 0x0, sys->desc_mem_buf.size);
-		sys->connection.desc = sys->desc_mem_buf;
-		sys->connection.event_thresh = IPA_EVENT_THRESHOLD;
+	}
 
-		ret = sps_connect(sys->pipe, &sys->connection);
-		if (ret < 0) {
-			IPAERR("rx connect error %d\n", ret);
-			goto rx_connect_failed;
-		}
+	sys->desc_mem_buf.size = desc_fifo_sz;
+	sys->desc_mem_buf.base = dma_alloc_coherent(NULL,
+						    sys->desc_mem_buf.size,
+						    &dma_addr,
+						    0);
+	if (sys->desc_mem_buf.base == NULL) {
+		IPAERR("memory alloc failed type=%d dir=%d\n", type, dir);
+		ret = -ENOMEM;
+		goto get_config_failed;
+	}
+	sys->desc_mem_buf.phys_base = dma_addr;
+	memset(sys->desc_mem_buf.base, 0x0, sys->desc_mem_buf.size);
+	sys->connection.desc = sys->desc_mem_buf;
+	sys->connection.event_thresh = IPA_EVENT_THRESHOLD;
 
+	ret = sps_connect(sys->pipe, &sys->connection);
+	if (ret < 0) {
+		IPAERR("connect error %d type=%d dir=%d\n", ret, type, dir);
+		ret = -EINVAL;
+		goto connect_failed;
+	}
+
+	INIT_LIST_HEAD(&sys->head_desc_list);
+	INIT_LIST_HEAD(&sys->free_desc_list);
+
+	if (dir == IPA_BRIDGE_DIR_DL) {
 		sys->register_event.options = SPS_O_EOT;
 		sys->register_event.mode = SPS_TRIGGER_CALLBACK;
 		sys->register_event.xfer_done = NULL;
 		sys->register_event.callback = bam_mux_rx_notify;
-		sys->register_event.user = NULL;
+		sys->register_event.user = (void *)type;
 		ret = sps_register_event(sys->pipe, &sys->register_event);
 		if (ret < 0) {
-			IPAERR("tx register event error %d\n", ret);
-			goto rx_event_reg_failed;
+			IPAERR("register event error %d type=%d dir=%d\n",
+					ret, type, dir);
+			ret = -EINVAL;
+			goto event_reg_failed;
 		}
 
-		INIT_LIST_HEAD(&sys->head_desc_list);
-		INIT_LIST_HEAD(&sys->free_desc_list);
-		spin_lock_init(&sys->spinlock);
-
-
 		for (i = 0; i < IPA_RX_POOL_CEIL; i++) {
-			ret = queue_rx_single(dir);
+			ret = queue_rx_single(dir, type);
 			if (ret < 0)
-				IPAERR("queue fail %d %d\n", dir, i);
+				IPAERR("queue fail dir=%d type=%d iter=%d\n",
+				       dir, type, i);
 		}
-
-		return 0;
-
-rx_event_reg_failed:
-		sps_disconnect(sys->pipe);
-rx_connect_failed:
-		dma_free_coherent(NULL,
-				sys->desc_mem_buf.size,
-				sys->desc_mem_buf.base,
-				sys->desc_mem_buf.phys_base);
-rx_get_config_failed:
-		sps_free_endpoint(sys->pipe);
-rx_alloc_endpoint_failed:
-		return ret;
 	}
+
+	return 0;
+
+event_reg_failed:
+	sps_disconnect(sys->pipe);
+connect_failed:
+	dma_free_coherent(NULL,
+			  sys->desc_mem_buf.size,
+			  sys->desc_mem_buf.base,
+			  sys->desc_mem_buf.phys_base);
+get_config_failed:
+	sps_free_endpoint(sys->pipe);
+alloc_endpoint_failed:
+	return ret;
 }
 
 /**
- * ipa_bridge_init() - initialize the tethered bridge, allocate UL and DL
- * workqueues
+ * ipa_bridge_init() - create workqueues and work items serving SW bridges
  *
  * Return codes: 0: success, -ENOMEM: failure
  */
 int ipa_bridge_init(void)
 {
 	int ret;
+	int i;
 
-	ipa_ul_workqueue = alloc_workqueue("ipa_ul",
-			WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, 1);
-	if (!ipa_ul_workqueue) {
-		IPAERR("ipa ul wq alloc failed\n");
+	bridge[IPA_BRIDGE_TYPE_TETHERED].ul_wq =
+		create_singlethread_workqueue("ipa_ul_teth");
+	if (!bridge[IPA_BRIDGE_TYPE_TETHERED].ul_wq) {
+		IPAERR("ipa ul teth wq alloc failed\n");
 		ret = -ENOMEM;
-		goto fail_ul;
+		goto fail_ul_teth;
 	}
 
-	ipa_dl_workqueue = alloc_workqueue("ipa_dl",
-			WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, 1);
-	if (!ipa_dl_workqueue) {
-		IPAERR("ipa dl wq alloc failed\n");
+	bridge[IPA_BRIDGE_TYPE_TETHERED].dl_wq =
+		create_singlethread_workqueue("ipa_dl_teth");
+	if (!bridge[IPA_BRIDGE_TYPE_TETHERED].dl_wq) {
+		IPAERR("ipa dl teth wq alloc failed\n");
 		ret = -ENOMEM;
-		goto fail_dl;
+		goto fail_dl_teth;
+	}
+
+	bridge[IPA_BRIDGE_TYPE_EMBEDDED].ul_wq =
+		create_singlethread_workqueue("ipa_ul_emb");
+	if (!bridge[IPA_BRIDGE_TYPE_EMBEDDED].ul_wq) {
+		IPAERR("ipa ul emb wq alloc failed\n");
+		ret = -ENOMEM;
+		goto fail_ul_emb;
+	}
+
+	bridge[IPA_BRIDGE_TYPE_EMBEDDED].dl_wq =
+		create_singlethread_workqueue("ipa_dl_emb");
+	if (!bridge[IPA_BRIDGE_TYPE_EMBEDDED].dl_wq) {
+		IPAERR("ipa dl emb wq alloc failed\n");
+		ret = -ENOMEM;
+		goto fail_dl_emb;
+	}
+
+	for (i = 0; i < IPA_BRIDGE_TYPE_MAX; i++) {
+		INIT_WORK(&bridge[i].ul_work, ul_work_func);
+		INIT_WORK(&bridge[i].dl_work, dl_work_func);
+		bridge[i].type = i;
 	}
 
 	return 0;
-fail_dl:
-	destroy_workqueue(ipa_ul_workqueue);
-fail_ul:
+
+fail_dl_emb:
+	destroy_workqueue(bridge[IPA_BRIDGE_TYPE_EMBEDDED].ul_wq);
+fail_ul_emb:
+	destroy_workqueue(bridge[IPA_BRIDGE_TYPE_TETHERED].dl_wq);
+fail_dl_teth:
+	destroy_workqueue(bridge[IPA_BRIDGE_TYPE_TETHERED].ul_wq);
+fail_ul_teth:
 	return ret;
 }
 
 /**
- * ipa_bridge_setup() - setup tethered SW bridge in specified direction
+ * ipa_bridge_setup() - setup SW bridge leg
  * @dir: downlink or uplink (from air interface perspective)
+ * @type: tethered or embedded bridge
+ * @props: bridge leg properties (EP config, callbacks, etc)
+ * @clnt_hdl: [out] handle of IPA EP belonging to bridge leg
+ *
+ * NOTE: IT IS CALLER'S RESPONSIBILITY TO ENSURE BAMs ARE
+ * OPERATIONAL AS LONG AS BRIDGE REMAINS UP
  *
  * Return codes:
  * 0: success
  * various negative error codes on errors
  */
-int ipa_bridge_setup(enum ipa_bridge_dir dir)
+int ipa_bridge_setup(enum ipa_bridge_dir dir, enum ipa_bridge_type type,
+		     struct ipa_sys_connect_params *props, u32 *clnt_hdl)
 {
 	int ret;
 
-	if (atomic_inc_return(&ipa_ctx->ipa_active_clients) == 1)
-		ipa_enable_clks();
-
-	if (setup_bridge_to_a2(dir)) {
-		IPAERR("fail to setup SYS pipe to A2 %d\n", dir);
-		ret = -EINVAL;
-		goto bail_a2;
+	if (props == NULL || clnt_hdl == NULL ||
+	    type >= IPA_BRIDGE_TYPE_MAX || dir >= IPA_BRIDGE_DIR_MAX ||
+	    props->client >= IPA_CLIENT_MAX || props->desc_fifo_sz == 0) {
+		IPAERR("Bad param props=%p clnt_hdl=%p type=%d dir=%d\n",
+		       props, clnt_hdl, type, dir);
+		return -EINVAL;
 	}
 
-	if (setup_bridge_to_ipa(dir)) {
-		IPAERR("fail to setup SYS pipe to IPA %d\n", dir);
+	if (atomic_inc_return(&ipa_ctx->ipa_active_clients) == 1) {
+		if (ipa_ctx->ipa_hw_mode == IPA_HW_MODE_NORMAL)
+			ipa_enable_clks();
+	}
+
+	if (setup_bridge_to_ipa(dir, type, props, clnt_hdl)) {
+		IPAERR("fail to setup SYS pipe to IPA dir=%d type=%d\n",
+		       dir, type);
 		ret = -EINVAL;
 		goto bail_ipa;
 	}
 
-	return 0;
-
-bail_ipa:
-	if (dir == IPA_UL)
-		sps_disconnect(bridge[IPA_UL_TO_A2].pipe);
-	else
-		sps_disconnect(bridge[IPA_DL_FROM_A2].pipe);
-bail_a2:
-	if (atomic_dec_return(&ipa_ctx->ipa_active_clients) == 0)
-		ipa_disable_clks();
-	return ret;
-}
-
-/**
- * ipa_bridge_teardown() - teardown the tethered bridge in the specified dir
- * @dir: downlink or uplink (from air interface perspective)
- *
- * Return codes:
- * 0: always
- */
-int ipa_bridge_teardown(enum ipa_bridge_dir dir)
-{
-	struct ipa_bridge_pipe_context *sys;
-
-	if (dir == IPA_UL) {
-		sys = &bridge[IPA_UL_TO_A2];
-		sps_disconnect(sys->pipe);
-		sys = &bridge[IPA_UL_FROM_IPA];
-		sps_disconnect(sys->pipe);
-	} else {
-		sys = &bridge[IPA_DL_FROM_A2];
-		sps_disconnect(sys->pipe);
-		sys = &bridge[IPA_DL_TO_IPA];
-		sps_disconnect(sys->pipe);
+	if (setup_bridge_to_a2(dir, type, props->desc_fifo_sz)) {
+		IPAERR("fail to setup SYS pipe to A2 dir=%d type=%d\n",
+		       dir, type);
+		ret = -EINVAL;
+		goto bail_a2;
 	}
 
-	if (atomic_dec_return(&ipa_ctx->ipa_active_clients) == 0)
-		ipa_disable_clks();
 
 	return 0;
+
+bail_a2:
+	ipa_bridge_teardown(dir, type, *clnt_hdl);
+bail_ipa:
+	if (atomic_dec_return(&ipa_ctx->ipa_active_clients) == 0) {
+		if (ipa_ctx->ipa_hw_mode == IPA_HW_MODE_NORMAL)
+			ipa_disable_clks();
+	}
+	return ret;
+}
+EXPORT_SYMBOL(ipa_bridge_setup);
+
+static void ipa_bridge_free_pkt(struct ipa_pkt_info *pkt)
+{
+	list_del(&pkt->link);
+	dma_unmap_single(NULL, pkt->dma_address, IPA_RX_SKB_SIZE,
+			 DMA_BIDIRECTIONAL);
+	kfree(pkt->buffer);
+	kfree(pkt);
+}
+
+static void ipa_bridge_free_resources(struct ipa_bridge_pipe_context *pipe)
+{
+	struct ipa_pkt_info *pkt;
+	struct ipa_pkt_info *n;
+
+	list_for_each_entry_safe(pkt, n, &pipe->head_desc_list, link)
+		ipa_bridge_free_pkt(pkt);
+
+	list_for_each_entry_safe(pkt, n, &pipe->free_desc_list, link)
+		ipa_bridge_free_pkt(pkt);
 }
 
 /**
- * ipa_bridge_cleanup() - de-initialize the tethered bridge
+ * ipa_bridge_teardown() - teardown SW bridge leg
+ * @dir: downlink or uplink (from air interface perspective)
+ * @type: tethered or embedded bridge
+ * @clnt_hdl: handle of IPA EP
+ *
+ * Return codes:
+ * 0: success
+ * various negative error codes on errors
+ */
+int ipa_bridge_teardown(enum ipa_bridge_dir dir, enum ipa_bridge_type type,
+			u32 clnt_hdl)
+{
+	struct ipa_bridge_pipe_context *sys;
+	int lo;
+	int hi;
+
+	if (dir >= IPA_BRIDGE_DIR_MAX || type >= IPA_BRIDGE_TYPE_MAX ||
+	    clnt_hdl >= IPA_NUM_PIPES || ipa_ctx->ep[clnt_hdl].valid == 0) {
+		IPAERR("Bad param dir=%d type=%d\n", dir, type);
+		return -EINVAL;
+	}
+
+	if (dir == IPA_BRIDGE_DIR_UL) {
+		lo = IPA_UL_FROM_IPA;
+		hi = IPA_UL_TO_A2;
+	} else {
+		lo = IPA_DL_FROM_A2;
+		hi = IPA_DL_TO_IPA;
+	}
+
+	for (; lo <= hi; lo++) {
+		sys = &bridge[type].pipe[lo];
+		sps_disconnect(sys->pipe);
+		dma_free_coherent(NULL, sys->desc_mem_buf.size,
+				  sys->desc_mem_buf.base,
+				  sys->desc_mem_buf.phys_base);
+		sps_free_endpoint(sys->pipe);
+		ipa_bridge_free_resources(sys);
+	}
+
+	memset(&ipa_ctx->ep[clnt_hdl], 0, sizeof(struct ipa_ep_context));
+
+	if (atomic_dec_return(&ipa_ctx->ipa_active_clients) == 0) {
+		if (ipa_ctx->ipa_hw_mode == IPA_HW_MODE_NORMAL)
+			ipa_disable_clks();
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(ipa_bridge_teardown);
+
+/**
+ * ipa_bridge_cleanup() - destroy workqueues serving the SW bridges
  *
  * Return codes:
  * None
  */
 void ipa_bridge_cleanup(void)
 {
-	destroy_workqueue(ipa_dl_workqueue);
-	destroy_workqueue(ipa_ul_workqueue);
+	int i;
+
+	for (i = 0; i < IPA_BRIDGE_TYPE_MAX; i++) {
+		destroy_workqueue(bridge[i].dl_wq);
+		destroy_workqueue(bridge[i].ul_wq);
+	}
 }
diff --git a/drivers/platform/msm/ipa/ipa_client.c b/drivers/platform/msm/ipa/ipa_client.c
index dc9da7d..4b9a0fd 100644
--- a/drivers/platform/msm/ipa/ipa_client.c
+++ b/drivers/platform/msm/ipa/ipa_client.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
@@ -10,8 +10,94 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/delay.h>
 #include "ipa_i.h"
 
+static void ipa_enable_data_path(u32 clnt_hdl)
+{
+	struct ipa_ep_context *ep = &ipa_ctx->ep[clnt_hdl];
+
+	if (ipa_ctx->ipa_hw_mode == IPA_HW_MODE_VIRTUAL) {
+		/* IPA_HW_MODE_VIRTUAL lacks support for TAG IC & EP suspend */
+		return;
+	}
+
+	if (ipa_ctx->ipa_hw_type == IPA_HW_v1_1 && ep->suspended) {
+		ipa_write_reg(ipa_ctx->mmio,
+				IPA_ENDP_INIT_CTRL_n_OFST(clnt_hdl), 0);
+		ep->suspended = false;
+	}
+}
+
+static int ipa_disable_data_path(u32 clnt_hdl)
+{
+	DECLARE_COMPLETION_ONSTACK(tag_rsp);
+	struct ipa_desc desc = {0};
+	struct ipa_ip_packet_tag cmd;
+	struct ipa_ep_context *ep = &ipa_ctx->ep[clnt_hdl];
+	struct ipa_tree_node *node;
+	int result = 0;
+
+	if (ipa_ctx->ipa_hw_mode == IPA_HW_MODE_VIRTUAL) {
+		/* IPA_HW_MODE_VIRTUAL lacks support for TAG IC & EP suspend */
+		return 0;
+	}
+
+	node = kmem_cache_zalloc(ipa_ctx->tree_node_cache, GFP_KERNEL);
+	if (!node) {
+		IPAERR("failed to alloc tree node object\n");
+		result = -ENOMEM;
+		goto fail_alloc;
+	}
+
+	if (ipa_ctx->ipa_hw_type == IPA_HW_v1_1 && !ep->suspended) {
+		ipa_write_reg(ipa_ctx->mmio,
+				IPA_ENDP_INIT_CTRL_n_OFST(clnt_hdl), 1);
+
+		cmd.tag = (u32) &tag_rsp;
+
+		desc.pyld = &cmd;
+		desc.len = sizeof(struct ipa_ip_packet_tag);
+		desc.type = IPA_IMM_CMD_DESC;
+		desc.opcode = IPA_IP_PACKET_TAG;
+
+		IPADBG("Wait on TAG %p clnt=%d\n", &tag_rsp, clnt_hdl);
+
+		node->hdl = cmd.tag;
+		mutex_lock(&ipa_ctx->lock);
+		if (ipa_insert(&ipa_ctx->tag_tree, node)) {
+			IPAERR("failed to add to tree\n");
+			result = -EINVAL;
+			mutex_unlock(&ipa_ctx->lock);
+			goto fail_insert;
+		}
+		mutex_unlock(&ipa_ctx->lock);
+
+		if (ipa_send_cmd(1, &desc)) {
+			ipa_write_reg(ipa_ctx->mmio,
+				IPA_ENDP_INIT_CTRL_n_OFST(clnt_hdl), 0);
+			IPAERR("fail to send TAG command\n");
+			result = -EPERM;
+			goto fail_send;
+		}
+		wait_for_completion(&tag_rsp);
+		if (IPA_CLIENT_IS_CONS(ep->client) &&
+				ep->cfg.aggr.aggr_en == IPA_ENABLE_AGGR &&
+				ep->cfg.aggr.aggr_time_limit)
+			msleep(ep->cfg.aggr.aggr_time_limit);
+		ep->suspended = true;
+	}
+
+	return 0;
+
+fail_send:
+	rb_erase(&node->node, &ipa_ctx->tag_tree);
+fail_insert:
+	kmem_cache_free(ipa_ctx->tree_node_cache, node);
+fail_alloc:
+	return result;
+}
+
 static int ipa_connect_configure_sps(const struct ipa_connect_params *in,
 				     struct ipa_ep_context *ep, int ipa_ep_idx)
 {
@@ -94,7 +180,6 @@
 	return 0;
 }
 
-
 /**
  * ipa_connect() - low-level IPA client connect
  * @in:	[in] input parameters from client
@@ -114,16 +199,15 @@
 		u32 *clnt_hdl)
 {
 	int ipa_ep_idx;
-	int ipa_ep_idx_dst;
 	int result = -EFAULT;
 	struct ipa_ep_context *ep;
 
 	if (atomic_inc_return(&ipa_ctx->ipa_active_clients) == 1)
-		ipa_enable_clks();
+		if (ipa_ctx->ipa_hw_mode == IPA_HW_MODE_NORMAL)
+			ipa_enable_clks();
 
 	if (in == NULL || sps == NULL || clnt_hdl == NULL ||
 	    in->client >= IPA_CLIENT_MAX ||
-	    in->ipa_ep_cfg.mode.dst >= IPA_CLIENT_MAX ||
 	    in->desc_fifo_sz == 0 || in->data_fifo_sz == 0) {
 		IPAERR("bad parm.\n");
 		result = -EINVAL;
@@ -143,16 +227,6 @@
 		goto fail;
 	}
 
-	if (IPA_CLIENT_IS_PROD(in->client) &&
-			(in->ipa_ep_cfg.mode.mode == IPA_DMA)) {
-		ipa_ep_idx_dst = ipa_get_ep_mapping(ipa_ctx->mode,
-				in->ipa_ep_cfg.mode.dst);
-		if ((ipa_ep_idx_dst == -1) ||
-				(ipa_ctx->ep[ipa_ep_idx_dst].valid)) {
-			IPADBG("dst EP for IPA input pipe doesn't yet exist\n");
-		}
-	}
-
 	memset(&ipa_ctx->ep[ipa_ep_idx], 0, sizeof(struct ipa_ep_context));
 
 	ep->valid = 1;
@@ -247,13 +321,14 @@
 ipa_cfg_ep_fail:
 	memset(&ipa_ctx->ep[ipa_ep_idx], 0, sizeof(struct ipa_ep_context));
 fail:
-	if (atomic_dec_return(&ipa_ctx->ipa_active_clients) == 0)
-		ipa_disable_clks();
+	if (atomic_dec_return(&ipa_ctx->ipa_active_clients) == 0) {
+		if (ipa_ctx->ipa_hw_mode == IPA_HW_MODE_NORMAL)
+			ipa_disable_clks();
+	}
 
 	return result;
 }
 EXPORT_SYMBOL(ipa_connect);
-
 /**
  * ipa_disconnect() - low-level IPA client disconnect
  * @clnt_hdl:	[in] opaque client handle assigned by IPA to client
@@ -278,6 +353,13 @@
 
 	ep = &ipa_ctx->ep[clnt_hdl];
 
+	result = ipa_disable_data_path(clnt_hdl);
+	if (result) {
+		IPAERR("disable data path failed res=%d clnt=%d.\n", result,
+				clnt_hdl);
+		return -EPERM;
+	}
+
 	result = sps_disconnect(ep->ep_hdl);
 	if (result) {
 		IPAERR("SPS disconnect failed.\n");
@@ -314,12 +396,68 @@
 		return -EPERM;
 	}
 
+	ipa_enable_data_path(clnt_hdl);
 	memset(&ipa_ctx->ep[clnt_hdl], 0, sizeof(struct ipa_ep_context));
 
-	if (atomic_dec_return(&ipa_ctx->ipa_active_clients) == 0)
-		ipa_disable_clks();
+	if (atomic_dec_return(&ipa_ctx->ipa_active_clients) == 0) {
+		if (ipa_ctx->ipa_hw_mode == IPA_HW_MODE_NORMAL)
+			ipa_disable_clks();
+	}
 
 	return 0;
 }
 EXPORT_SYMBOL(ipa_disconnect);
 
+/**
+ * ipa_connection_suspend() - suspend B2B connection to/from IPA
+ * @clnt_hdl:	[in] opaque client handle assigned by IPA to client
+ *
+ * Should be called by the driver of the peripheral that wants to suspend
+ * its BAM-BAM connection to/from IPA in BAM-BAM mode. The pipe is not
+ * disconnected and must later be resumed before data transfer can begin
+ *
+ * Returns:	0 on success, negative on failure
+ *
+ * Note:	Should not be called from atomic context
+ */
+int ipa_connection_suspend(u32 clnt_hdl)
+{
+	int result;
+
+	if (clnt_hdl >= IPA_NUM_PIPES || ipa_ctx->ep[clnt_hdl].valid == 0) {
+		IPAERR("bad parm.\n");
+		return -EINVAL;
+	}
+	result = ipa_disable_data_path(clnt_hdl);
+	if (result)
+		IPAERR("disable data path failed res=%d clnt=%d.\n", result,
+				clnt_hdl);
+
+	return result;
+}
+EXPORT_SYMBOL(ipa_connection_suspend);
+
+/**
+ * ipa_connection_resume() - resume B2B connection to/from IPA
+ * @clnt_hdl:	[in] opaque client handle assigned by IPA to client
+ *
+ * Should be called by the driver of the peripheral that wants to resume
+ * its previously suspended BAM-BAM connection to/from IPA in BAM-BAM mode.
+ *
+ * Returns:	0 on success, negative on failure
+ *
+ * Note:	Should not be called from atomic context
+ */
+int ipa_connection_resume(u32 clnt_hdl)
+{
+	if (clnt_hdl >= IPA_NUM_PIPES || ipa_ctx->ep[clnt_hdl].valid == 0) {
+		IPAERR("bad parm.\n");
+		return -EINVAL;
+	}
+
+	ipa_enable_data_path(clnt_hdl);
+
+	return 0;
+}
+EXPORT_SYMBOL(ipa_connection_resume);
+
diff --git a/drivers/platform/msm/ipa/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_debugfs.c
index 43b0178d..1605ed2 100644
--- a/drivers/platform/msm/ipa/ipa_debugfs.c
+++ b/drivers/platform/msm/ipa/ipa_debugfs.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
@@ -13,10 +13,69 @@
 #ifdef CONFIG_DEBUG_FS
 
 #include <linux/debugfs.h>
+#include <linux/stringify.h>
 #include "ipa_i.h"
 
 
-#define IPA_MAX_MSG_LEN 1024
+#define IPA_MAX_MSG_LEN 4096
+
+const char *ipa_client_name[] = {
+	__stringify(IPA_CLIENT_HSIC1_PROD),
+	__stringify(IPA_CLIENT_HSIC2_PROD),
+	__stringify(IPA_CLIENT_HSIC3_PROD),
+	__stringify(IPA_CLIENT_HSIC4_PROD),
+	__stringify(IPA_CLIENT_HSIC5_PROD),
+	__stringify(IPA_CLIENT_USB_PROD),
+	__stringify(IPA_CLIENT_A5_WLAN_AMPDU_PROD),
+	__stringify(IPA_CLIENT_A2_EMBEDDED_PROD),
+	__stringify(IPA_CLIENT_A2_TETHERED_PROD),
+	__stringify(IPA_CLIENT_A5_LAN_WAN_PROD),
+	__stringify(IPA_CLIENT_A5_CMD_PROD),
+	__stringify(IPA_CLIENT_Q6_LAN_PROD),
+	__stringify(IPA_CLIENT_HSIC1_CONS),
+	__stringify(IPA_CLIENT_HSIC2_CONS),
+	__stringify(IPA_CLIENT_HSIC3_CONS),
+	__stringify(IPA_CLIENT_HSIC4_CONS),
+	__stringify(IPA_CLIENT_HSIC5_CONS),
+	__stringify(IPA_CLIENT_USB_CONS),
+	__stringify(IPA_CLIENT_A2_EMBEDDED_CONS),
+	__stringify(IPA_CLIENT_A2_TETHERED_CONS),
+	__stringify(IPA_CLIENT_A5_LAN_WAN_CONS),
+	__stringify(IPA_CLIENT_Q6_LAN_CONS),
+	__stringify(IPA_CLIENT_MAX),
+};
+
+const char *ipa_ic_name[] = {
+	__stringify_1(IPA_IP_CMD_INVALID),
+	__stringify_1(IPA_DECIPH_INIT),
+	__stringify_1(IPA_PPP_FRM_INIT),
+	__stringify_1(IPA_IP_V4_FILTER_INIT),
+	__stringify_1(IPA_IP_V6_FILTER_INIT),
+	__stringify_1(IPA_IP_V4_NAT_INIT),
+	__stringify_1(IPA_IP_V6_NAT_INIT),
+	__stringify_1(IPA_IP_V4_ROUTING_INIT),
+	__stringify_1(IPA_IP_V6_ROUTING_INIT),
+	__stringify_1(IPA_HDR_INIT_LOCAL),
+	__stringify_1(IPA_HDR_INIT_SYSTEM),
+	__stringify_1(IPA_DECIPH_SETUP),
+	__stringify_1(IPA_INSERT_NAT_RULE),
+	__stringify_1(IPA_DELETE_NAT_RULE),
+	__stringify_1(IPA_NAT_DMA),
+	__stringify_1(IPA_IP_PACKET_TAG),
+	__stringify_1(IPA_IP_PACKET_INIT),
+};
+
+const char *ipa_excp_name[] = {
+	__stringify_1(IPA_A5_MUX_HDR_EXCP_RSVD0),
+	__stringify_1(IPA_A5_MUX_HDR_EXCP_RSVD1),
+	__stringify_1(IPA_A5_MUX_HDR_EXCP_FLAG_IHL),
+	__stringify_1(IPA_A5_MUX_HDR_EXCP_FLAG_REPLICATED),
+	__stringify_1(IPA_A5_MUX_HDR_EXCP_FLAG_TAG),
+	__stringify_1(IPA_A5_MUX_HDR_EXCP_FLAG_SW_FLT),
+	__stringify_1(IPA_A5_MUX_HDR_EXCP_FLAG_NAT),
+	__stringify_1(IPA_A5_MUX_HDR_EXCP_FLAG_IP),
+};
+
 static struct dentry *dent;
 static struct dentry *dfile_gen_reg;
 static struct dentry *dfile_ep_reg;
@@ -25,6 +84,7 @@
 static struct dentry *dfile_ip6_rt;
 static struct dentry *dfile_ip4_flt;
 static struct dentry *dfile_ip6_flt;
+static struct dentry *dfile_stats;
 static char dbg_buff[IPA_MAX_MSG_LEN];
 static s8 ep_reg_idx;
 
@@ -33,7 +93,8 @@
 {
 	int nbytes;
 
-	nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
+	if (ipa_ctx->ipa_hw_type == IPA_HW_v1_0)
+		nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
 			"IPA_VERSION=0x%x\n"
 			"IPA_COMP_HW_VERSION=0x%x\n"
 			"IPA_ROUTE=0x%x\n"
@@ -42,11 +103,26 @@
 			"IPA_HEAD_OF_LINE_BLOCK_EN=0x%x\n",
 			ipa_read_reg(ipa_ctx->mmio, IPA_VERSION_OFST),
 			ipa_read_reg(ipa_ctx->mmio, IPA_COMP_HW_VERSION_OFST),
-			ipa_read_reg(ipa_ctx->mmio, IPA_ROUTE_OFST),
-			ipa_read_reg(ipa_ctx->mmio, IPA_FILTER_OFST),
-			ipa_read_reg(ipa_ctx->mmio, IPA_SHARED_MEM_SIZE_OFST),
+			ipa_read_reg(ipa_ctx->mmio, IPA_ROUTE_OFST_v1),
+			ipa_read_reg(ipa_ctx->mmio, IPA_FILTER_OFST_v1),
 			ipa_read_reg(ipa_ctx->mmio,
-				IPA_HEAD_OF_LINE_BLOCK_EN_OFST));
+				IPA_SHARED_MEM_SIZE_OFST_v1),
+			ipa_read_reg(ipa_ctx->mmio,
+				IPA_HEAD_OF_LINE_BLOCK_EN_OFST)
+				);
+	 else
+		nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
+			"IPA_VERSION=0x%x\n"
+			"IPA_COMP_HW_VERSION=0x%x\n"
+			"IPA_ROUTE=0x%x\n"
+			"IPA_FILTER=0x%x\n"
+			"IPA_SHARED_MEM_SIZE=0x%x\n",
+			ipa_read_reg(ipa_ctx->mmio, IPA_VERSION_OFST),
+			ipa_read_reg(ipa_ctx->mmio, IPA_COMP_HW_VERSION_OFST),
+			ipa_read_reg(ipa_ctx->mmio, IPA_ROUTE_OFST_v2),
+			ipa_read_reg(ipa_ctx->mmio, IPA_FILTER_OFST_v2),
+			ipa_read_reg(ipa_ctx->mmio, IPA_SHARED_MEM_SIZE_OFST_v2)
+				);
 
 	return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, nbytes);
 }
@@ -100,22 +176,42 @@
 	pos = *ppos;
 	for (i = start_idx; i < end_idx; i++) {
 
-		nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
+		if (ipa_ctx->ipa_hw_type == IPA_HW_v1_0) {
+			nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
 				"IPA_ENDP_INIT_NAT_%u=0x%x\n"
 				"IPA_ENDP_INIT_HDR_%u=0x%x\n"
 				"IPA_ENDP_INIT_MODE_%u=0x%x\n"
 				"IPA_ENDP_INIT_AGGR_%u=0x%x\n"
 				"IPA_ENDP_INIT_ROUTE_%u=0x%x\n",
 				i, ipa_read_reg(ipa_ctx->mmio,
-					IPA_ENDP_INIT_NAT_n_OFST(i)),
+					IPA_ENDP_INIT_NAT_n_OFST_v1(i)),
 				i, ipa_read_reg(ipa_ctx->mmio,
-					IPA_ENDP_INIT_HDR_n_OFST(i)),
+					IPA_ENDP_INIT_HDR_n_OFST_v1(i)),
 				i, ipa_read_reg(ipa_ctx->mmio,
-					IPA_ENDP_INIT_MODE_n_OFST(i)),
+					IPA_ENDP_INIT_MODE_n_OFST_v1(i)),
 				i, ipa_read_reg(ipa_ctx->mmio,
-					IPA_ENDP_INIT_AGGR_n_OFST(i)),
+					IPA_ENDP_INIT_AGGR_n_OFST_v1(i)),
 				i, ipa_read_reg(ipa_ctx->mmio,
-					IPA_ENDP_INIT_ROUTE_n_OFST(i)));
+					IPA_ENDP_INIT_ROUTE_n_OFST_v1(i)));
+		} else {
+			nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
+				"IPA_ENDP_INIT_NAT_%u=0x%x\n"
+				"IPA_ENDP_INIT_HDR_%u=0x%x\n"
+				"IPA_ENDP_INIT_MODE_%u=0x%x\n"
+				"IPA_ENDP_INIT_AGGR_%u=0x%x\n"
+				"IPA_ENDP_INIT_ROUTE_%u=0x%x\n",
+				i, ipa_read_reg(ipa_ctx->mmio,
+					IPA_ENDP_INIT_NAT_n_OFST_v2(i)),
+				i, ipa_read_reg(ipa_ctx->mmio,
+					IPA_ENDP_INIT_HDR_n_OFST_v2(i)),
+				i, ipa_read_reg(ipa_ctx->mmio,
+					IPA_ENDP_INIT_MODE_n_OFST_v2(i)),
+				i, ipa_read_reg(ipa_ctx->mmio,
+					IPA_ENDP_INIT_AGGR_n_OFST_v2(i)),
+				i, ipa_read_reg(ipa_ctx->mmio,
+					IPA_ENDP_INIT_ROUTE_n_OFST_v2(i)));
+		}
+
 		*ppos = pos;
 		ret = simple_read_from_buffer(ubuf, count, ppos, dbg_buff,
 					      nbytes);
@@ -329,9 +425,10 @@
 				hdr_ofst = 0;
 			nbytes = scnprintf(dbg_buff + cnt,
 					IPA_MAX_MSG_LEN - cnt,
-					"tbl_idx:%d tbl_name:%s tbl_ref:%u rule_idx:%d dst:%d ep:%d S:%u hdr_ofst[words]:%u attrib_mask:%08x ",
+					"tbl_idx:%d tbl_name:%s tbl_ref:%u rule_idx:%d dst:%d name:%s ep:%d S:%u hdr_ofst[words]:%u attrib_mask:%08x ",
 					entry->tbl->idx, entry->tbl->name,
 					entry->tbl->ref_cnt, i, entry->rule.dst,
+					ipa_client_name[entry->rule.dst],
 					ipa_get_ep_mapping(ipa_ctx->mode,
 						entry->rule.dst),
 					   !ipa_ctx->hdr_tbl_lcl,
@@ -357,19 +454,25 @@
 	int cnt = 0;
 	int i;
 	int j;
+	int k;
 	struct ipa_flt_tbl *tbl;
 	struct ipa_flt_entry *entry;
 	enum ipa_ip_type ip = (enum ipa_ip_type)file->private_data;
 	struct ipa_rt_tbl *rt_tbl;
+	u32 rt_tbl_idx;
 
 	tbl = &ipa_ctx->glob_flt_tbl[ip];
 	mutex_lock(&ipa_ctx->lock);
 	i = 0;
 	list_for_each_entry(entry, &tbl->head_flt_rule_list, link) {
 		rt_tbl = (struct ipa_rt_tbl *)entry->rule.rt_tbl_hdl;
+		if (rt_tbl == NULL)
+			rt_tbl_idx = ~0;
+		else
+			rt_tbl_idx = rt_tbl->idx;
 		nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
 				   "ep_idx:global rule_idx:%d act:%d rt_tbl_idx:%d attrib_mask:%08x ",
-				   i, entry->rule.action, rt_tbl->idx,
+				   i, entry->rule.action, rt_tbl_idx,
 				   entry->rule.attrib.attrib_mask);
 		cnt += nbytes;
 		cnt += ipa_attrib_dump(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
@@ -382,10 +485,16 @@
 		i = 0;
 		list_for_each_entry(entry, &tbl->head_flt_rule_list, link) {
 			rt_tbl = (struct ipa_rt_tbl *)entry->rule.rt_tbl_hdl;
+			if (rt_tbl == NULL)
+				rt_tbl_idx = ~0;
+			else
+				rt_tbl_idx = rt_tbl->idx;
+			k = ipa_get_client_mapping(ipa_ctx->mode, j);
 			nbytes = scnprintf(dbg_buff + cnt,
 					IPA_MAX_MSG_LEN - cnt,
-					"ep_idx:%d rule_idx:%d act:%d rt_tbl_idx:%d attrib_mask:%08x ",
-					j, i, entry->rule.action, rt_tbl->idx,
+					"ep_idx:%d name:%s rule_idx:%d act:%d rt_tbl_idx:%d attrib_mask:%08x ",
+					j, ipa_client_name[k], i,
+					entry->rule.action, rt_tbl_idx,
 					entry->rule.attrib.attrib_mask);
 			cnt += nbytes;
 			cnt +=
@@ -401,6 +510,57 @@
 	return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
 }
 
+static ssize_t ipa_read_stats(struct file *file, char __user *ubuf,
+		size_t count, loff_t *ppos)
+{
+	int nbytes;
+	int i;
+	int cnt = 0;
+
+	nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
+			"sw_tx=%u\n"
+			"hw_tx=%u\n"
+			"rx=%u\n"
+			"rx_repl_repost=%u\n"
+			"x_intr_repost=%u\n"
+			"rx_q_len=%u\n",
+			ipa_ctx->stats.tx_sw_pkts,
+			ipa_ctx->stats.tx_hw_pkts,
+			ipa_ctx->stats.rx_pkts,
+			ipa_ctx->stats.rx_repl_repost,
+			ipa_ctx->stats.x_intr_repost,
+			ipa_ctx->stats.rx_q_len);
+	cnt += nbytes;
+
+	for (i = 0; i < MAX_NUM_EXCP; i++) {
+		nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
+				"rx_excp[%u:%35s]=%u\n", i, ipa_excp_name[i],
+				ipa_ctx->stats.rx_excp_pkts[i]);
+		cnt += nbytes;
+	}
+
+	for (i = 0; i < IPA_BRIDGE_TYPE_MAX; i++) {
+		nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
+				"brg_pkt[%u:%s][dl]=%u\n"
+				"brg_pkt[%u:%s][ul]=%u\n",
+				i, (i == 0) ? "teth" : "embd",
+				ipa_ctx->stats.bridged_pkts[i][0],
+				i, (i == 0) ? "teth" : "embd",
+				ipa_ctx->stats.bridged_pkts[i][1]);
+		cnt += nbytes;
+	}
+
+	for (i = 0; i < MAX_NUM_IMM_CMD; i++) {
+		nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
+				"IC[%2u:%22s]=%u\n", i, ipa_ic_name[i],
+				ipa_ctx->stats.imm_cmds[i]);
+		cnt += nbytes;
+	}
+
+	return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
+}
+
+
 const struct file_operations ipa_gen_reg_ops = {
 	.read = ipa_read_gen_reg,
 };
@@ -424,6 +584,10 @@
 	.open = ipa_open_dbg,
 };
 
+const struct file_operations ipa_stats_ops = {
+	.read = ipa_read_stats,
+};
+
 void ipa_debugfs_init(void)
 {
 	const mode_t read_only_mode = S_IRUSR | S_IRGRP | S_IROTH;
@@ -485,6 +649,13 @@
 		goto fail;
 	}
 
+	dfile_stats = debugfs_create_file("stats", read_only_mode, dent, 0,
+			&ipa_stats_ops);
+	if (!dfile_stats || IS_ERR(dfile_stats)) {
+		IPAERR("fail to create file for debug_fs stats\n");
+		goto fail;
+	}
+
 	return;
 
 fail:
diff --git a/drivers/platform/msm/ipa/ipa_dp.c b/drivers/platform/msm/ipa/ipa_dp.c
index 4de19d2..38690e9 100644
--- a/drivers/platform/msm/ipa/ipa_dp.c
+++ b/drivers/platform/msm/ipa/ipa_dp.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
@@ -10,6 +10,7 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/dmapool.h>
 #include <linux/list.h>
@@ -18,7 +19,18 @@
 
 #define list_next_entry(pos, member) \
 	list_entry(pos->member.next, typeof(*pos), member)
-#define IPA_LAST_DESC_COOKIE 0xFFFF
+#define IPA_LAST_DESC_CNT 0xFFFF
+#define POLLING_INACTIVITY 40
+#define POLLING_MIN_SLEEP 950
+#define POLLING_MAX_SLEEP 1050
+
+static void replenish_rx_work_func(struct work_struct *work);
+static struct delayed_work replenish_rx_work;
+static void switch_to_intr_work_func(struct work_struct *work);
+static struct delayed_work switch_to_intr_work;
+static void ipa_wq_handle_rx(struct work_struct *work);
+static DECLARE_WORK(rx_work, ipa_wq_handle_rx);
+
 /**
  * ipa_write_done() - this function will be (eventually) called when a Tx
  * operation is complete
@@ -40,7 +52,7 @@
 	unsigned long irq_flags;
 	struct ipa_mem_buffer mult = { 0 };
 	int i;
-	u16 cnt;
+	u32 cnt;
 
 	tx_pkt = container_of(work, struct ipa_tx_pkt_wrapper, work);
 	cnt = tx_pkt->cnt;
@@ -49,7 +61,7 @@
 	if (unlikely(cnt == 0))
 		WARN_ON(1);
 
-	if (cnt > 1 && cnt != IPA_LAST_DESC_COOKIE)
+	if (cnt > 1 && cnt != IPA_LAST_DESC_CNT)
 		mult = tx_pkt->mult;
 
 	for (i = 0; i < cnt; i++) {
@@ -66,10 +78,17 @@
 		}
 		next_pkt = list_next_entry(tx_pkt, link);
 		list_del(&tx_pkt->link);
-		tx_pkt->sys->len--;
 		spin_unlock_irqrestore(&tx_pkt->sys->spinlock, irq_flags);
-		dma_pool_free(ipa_ctx->one_kb_no_straddle_pool, tx_pkt->bounce,
-				tx_pkt->mem.phys_base);
+		if (unlikely(ipa_ctx->ipa_hw_type == IPA_HW_v1_0)) {
+			dma_pool_free(ipa_ctx->one_kb_no_straddle_pool,
+					tx_pkt->bounce,
+					tx_pkt->mem.phys_base);
+		} else {
+			dma_unmap_single(NULL, tx_pkt->mem.phys_base,
+					tx_pkt->mem.size,
+					DMA_TO_DEVICE);
+		}
+
 		if (tx_pkt->callback)
 			tx_pkt->callback(tx_pkt->user1, tx_pkt->user2);
 
@@ -85,6 +104,7 @@
  * ipa_send_one() - Send a single descriptor
  * @sys:	system pipe context
  * @desc:	descriptor to send
+ * @in_atomic:  whether caller is in atomic context
  *
  * - Allocate tx_packet wrapper
  * - Allocate a bounce buffer due to HW constrains
@@ -96,7 +116,8 @@
  *
  * Return codes: 0: success, -EFAULT: failure
  */
-int ipa_send_one(struct ipa_sys_context *sys, struct ipa_desc *desc)
+int ipa_send_one(struct ipa_sys_context *sys, struct ipa_desc *desc,
+		bool in_atomic)
 {
 	struct ipa_tx_pkt_wrapper *tx_pkt;
 	unsigned long irq_flags;
@@ -104,30 +125,40 @@
 	u16 sps_flags = SPS_IOVEC_FLAG_EOT | SPS_IOVEC_FLAG_INT;
 	dma_addr_t dma_address;
 	u16 len;
+	u32 mem_flag = GFP_ATOMIC;
 
-	tx_pkt = kmem_cache_zalloc(ipa_ctx->tx_pkt_wrapper_cache, GFP_KERNEL);
+	if (unlikely(!in_atomic))
+		mem_flag = GFP_KERNEL;
+
+	tx_pkt = kmem_cache_zalloc(ipa_ctx->tx_pkt_wrapper_cache, mem_flag);
 	if (!tx_pkt) {
 		IPAERR("failed to alloc tx wrapper\n");
 		goto fail_mem_alloc;
 	}
 
-	WARN_ON(desc->len > 512);
+	if (unlikely(ipa_ctx->ipa_hw_type == IPA_HW_v1_0)) {
+		WARN_ON(desc->len > 512);
 
-	/*
-	 * Due to a HW limitation, we need to make sure that the packet does not
-	 * cross a 1KB boundary
-	 */
-	tx_pkt->bounce = dma_pool_alloc(ipa_ctx->one_kb_no_straddle_pool,
-			GFP_KERNEL, &dma_address);
-	if (!tx_pkt->bounce) {
-		dma_address = 0;
+		/*
+		 * Due to a HW limitation, we need to make sure that the packet
+		 * does not cross a 1KB boundary
+		 */
+		tx_pkt->bounce = dma_pool_alloc(
+					ipa_ctx->one_kb_no_straddle_pool,
+					mem_flag, &dma_address);
+		if (!tx_pkt->bounce) {
+			dma_address = 0;
+		} else {
+			WARN_ON(!ipa_straddle_boundary
+		       ((u32)dma_address,
+				(u32)dma_address + desc->len - 1,
+				1024));
+			memcpy(tx_pkt->bounce, desc->pyld, desc->len);
+		}
 	} else {
-		WARN_ON(!ipa_straddle_boundary
-		       ((u32)dma_address, (u32)dma_address + desc->len - 1,
-			1024));
-		memcpy(tx_pkt->bounce, desc->pyld, desc->len);
+		dma_address = dma_map_single(NULL, desc->pyld, desc->len,
+				DMA_TO_DEVICE);
 	}
-
 	if (!dma_address) {
 		IPAERR("failed to DMA wrap\n");
 		goto fail_dma_map;
@@ -153,19 +184,15 @@
 	if (desc->type == IPA_IMM_CMD_DESC) {
 		sps_flags |= SPS_IOVEC_FLAG_IMME;
 		len = desc->opcode;
+		IPADBG("sending cmd=%d pyld_len=%d sps_flags=%x\n",
+				desc->opcode, desc->len, sps_flags);
+		IPA_DUMP_BUFF(desc->pyld, dma_address, desc->len);
 	} else {
 		len = desc->len;
 	}
 
-	if (desc->type == IPA_IMM_CMD_DESC) {
-		IPADBG("sending cmd=%d pyld_len=%d sps_flags=%x\n",
-				desc->opcode, desc->len, sps_flags);
-		IPA_DUMP_BUFF(desc->pyld, dma_address, desc->len);
-	}
-
 	spin_lock_irqsave(&sys->spinlock, irq_flags);
 	list_add_tail(&tx_pkt->link, &sys->head_desc_list);
-	sys->len++;
 	result = sps_transfer_one(sys->ep->ep_hdl, dma_address, len, tx_pkt,
 			sps_flags);
 	if (result) {
@@ -180,8 +207,11 @@
 fail_sps_send:
 	list_del(&tx_pkt->link);
 	spin_unlock_irqrestore(&sys->spinlock, irq_flags);
-	dma_pool_free(ipa_ctx->one_kb_no_straddle_pool, tx_pkt->bounce,
-			dma_address);
+	if (unlikely(ipa_ctx->ipa_hw_type == IPA_HW_v1_0))
+		dma_pool_free(ipa_ctx->one_kb_no_straddle_pool, tx_pkt->bounce,
+				dma_address);
+	else
+		dma_unmap_single(NULL, dma_address, desc->len, DMA_TO_DEVICE);
 fail_dma_map:
 	kmem_cache_free(ipa_ctx->tx_pkt_wrapper_cache, tx_pkt);
 fail_mem_alloc:
@@ -193,6 +223,7 @@
  * @sys: system pipe context
  * @num_desc: number of packets
  * @desc: packets to send (may be immediate command or data)
+ * @in_atomic:  whether caller is in atomic context
  *
  * This function is used for system-to-bam connection.
  * - SPS driver expect struct sps_transfer which will contain all the data
@@ -209,7 +240,8 @@
  *
  * Return codes: 0: success, -EFAULT: failure
  */
-int ipa_send(struct ipa_sys_context *sys, u16 num_desc, struct ipa_desc *desc)
+int ipa_send(struct ipa_sys_context *sys, u32 num_desc, struct ipa_desc *desc,
+		bool in_atomic)
 {
 	struct ipa_tx_pkt_wrapper *tx_pkt;
 	struct ipa_tx_pkt_wrapper *next_pkt;
@@ -222,19 +254,24 @@
 	int result;
 	int fail_dma_wrap = 0;
 	uint size = num_desc * sizeof(struct sps_iovec);
+	u32 mem_flag = GFP_ATOMIC;
+
+	if (unlikely(!in_atomic))
+		mem_flag = GFP_KERNEL;
 
 	transfer.iovec = dma_alloc_coherent(NULL, size, &dma_addr, 0);
 	transfer.iovec_phys = dma_addr;
 	transfer.iovec_count = num_desc;
+	spin_lock_irqsave(&sys->spinlock, irq_flags);
 	if (!transfer.iovec) {
 		IPAERR("fail to alloc DMA mem for sps xfr buff\n");
-		goto failure;
+		goto failure_coherent;
 	}
 
 	for (i = 0; i < num_desc; i++) {
 		fail_dma_wrap = 0;
 		tx_pkt = kmem_cache_zalloc(ipa_ctx->tx_pkt_wrapper_cache,
-					   GFP_KERNEL);
+					   mem_flag);
 		if (!tx_pkt) {
 			IPAERR("failed to alloc tx wrapper\n");
 			goto failure;
@@ -245,43 +282,49 @@
 		 */
 		if (i == 0) {
 			transfer.user = tx_pkt;
-
 			tx_pkt->mult.phys_base = dma_addr;
 			tx_pkt->mult.base = transfer.iovec;
 			tx_pkt->mult.size = size;
 			tx_pkt->cnt = num_desc;
+			INIT_WORK(&tx_pkt->work, ipa_wq_write_done);
 		}
 
 		iovec = &transfer.iovec[i];
 		iovec->flags = 0;
 
 		INIT_LIST_HEAD(&tx_pkt->link);
-		INIT_WORK(&tx_pkt->work, ipa_wq_write_done);
 		tx_pkt->type = desc[i].type;
 
 		tx_pkt->mem.base = desc[i].pyld;
 		tx_pkt->mem.size = desc[i].len;
 
-		WARN_ON(tx_pkt->mem.size > 512);
+		if (unlikely(ipa_ctx->ipa_hw_type == IPA_HW_v1_0)) {
+			WARN_ON(tx_pkt->mem.size > 512);
 
-		/*
-		 * Due to a HW limitation, we need to make sure that the
-		 * packet does not cross a 1KB boundary
-		 */
-		tx_pkt->bounce =
-		   dma_pool_alloc(ipa_ctx->one_kb_no_straddle_pool, GFP_KERNEL,
-				   &tx_pkt->mem.phys_base);
-		if (!tx_pkt->bounce) {
-			tx_pkt->mem.phys_base = 0;
-		} else {
-			WARN_ON(!ipa_straddle_boundary(
+			/*
+			 * Due to a HW limitation, we need to make sure that the
+			 * packet does not cross a 1KB boundary
+			 */
+			tx_pkt->bounce =
+			   dma_pool_alloc(ipa_ctx->one_kb_no_straddle_pool,
+					   mem_flag,
+					   &tx_pkt->mem.phys_base);
+			if (!tx_pkt->bounce) {
+				tx_pkt->mem.phys_base = 0;
+			} else {
+				WARN_ON(!ipa_straddle_boundary(
 						(u32)tx_pkt->mem.phys_base,
 						(u32)tx_pkt->mem.phys_base +
 						tx_pkt->mem.size - 1, 1024));
-			memcpy(tx_pkt->bounce, tx_pkt->mem.base,
-					tx_pkt->mem.size);
+				memcpy(tx_pkt->bounce, tx_pkt->mem.base,
+						tx_pkt->mem.size);
+			}
+		} else {
+			tx_pkt->mem.phys_base =
+			   dma_map_single(NULL, tx_pkt->mem.base,
+					   tx_pkt->mem.size,
+					   DMA_TO_DEVICE);
 		}
-
 		if (!tx_pkt->mem.phys_base) {
 			IPAERR("failed to alloc tx wrapper\n");
 			fail_dma_wrap = 1;
@@ -298,10 +341,7 @@
 		 * add this packet to system pipe context.
 		 */
 		iovec->addr = tx_pkt->mem.phys_base;
-		spin_lock_irqsave(&sys->spinlock, irq_flags);
 		list_add_tail(&tx_pkt->link, &sys->head_desc_list);
-		sys->len++;
-		spin_unlock_irqrestore(&sys->spinlock, irq_flags);
 
 		/*
 		 * Special treatment for immediate commands, where the structure
@@ -318,7 +358,7 @@
 			iovec->flags |= (SPS_IOVEC_FLAG_EOT |
 					SPS_IOVEC_FLAG_INT);
 			/* "mark" the last desc */
-			tx_pkt->cnt = IPA_LAST_DESC_COOKIE;
+			tx_pkt->cnt = IPA_LAST_DESC_CNT;
 		}
 	}
 
@@ -328,17 +368,22 @@
 		goto failure;
 	}
 
+	spin_unlock_irqrestore(&sys->spinlock, irq_flags);
 	return 0;
 
 failure:
 	tx_pkt = transfer.user;
 	for (j = 0; j < i; j++) {
-		spin_lock_irqsave(&sys->spinlock, irq_flags);
 		next_pkt = list_next_entry(tx_pkt, link);
 		list_del(&tx_pkt->link);
-		spin_unlock_irqrestore(&sys->spinlock, irq_flags);
-		dma_pool_free(ipa_ctx->one_kb_no_straddle_pool, tx_pkt->bounce,
-				tx_pkt->mem.phys_base);
+		if (unlikely(ipa_ctx->ipa_hw_type == IPA_HW_v1_0))
+			dma_pool_free(ipa_ctx->one_kb_no_straddle_pool,
+					tx_pkt->bounce,
+					tx_pkt->mem.phys_base);
+		else
+			dma_unmap_single(NULL, tx_pkt->mem.phys_base,
+					tx_pkt->mem.size,
+					DMA_TO_DEVICE);
 		kmem_cache_free(ipa_ctx->tx_pkt_wrapper_cache, tx_pkt);
 		tx_pkt = next_pkt;
 	}
@@ -349,7 +394,8 @@
 	if (transfer.iovec_phys)
 		dma_free_coherent(NULL, size, transfer.iovec,
 				  transfer.iovec_phys);
-
+failure_coherent:
+	spin_unlock_irqrestore(&sys->spinlock, irq_flags);
 	return -EFAULT;
 }
 
@@ -385,6 +431,11 @@
 int ipa_send_cmd(u16 num_desc, struct ipa_desc *descr)
 {
 	struct ipa_desc *desc;
+	int result = 0;
+
+	if (atomic_inc_return(&ipa_ctx->ipa_active_clients) == 1)
+		if (ipa_ctx->ipa_hw_mode == IPA_HW_MODE_NORMAL)
+			ipa_enable_clks();
 
 	if (num_desc == 1) {
 		init_completion(&descr->xfer_done);
@@ -394,9 +445,10 @@
 
 		descr->callback = ipa_sps_irq_cmd_ack;
 		descr->user1 = descr;
-		if (ipa_send_one(&ipa_ctx->sys[IPA_A5_CMD], descr)) {
+		if (ipa_send_one(&ipa_ctx->sys[IPA_A5_CMD], descr, false)) {
 			IPAERR("fail to send immediate command\n");
-			return -EFAULT;
+			result = -EFAULT;
+			goto bail;
 		}
 		wait_for_completion(&descr->xfer_done);
 	} else {
@@ -408,14 +460,21 @@
 
 		desc->callback = ipa_sps_irq_cmd_ack;
 		desc->user1 = desc;
-		if (ipa_send(&ipa_ctx->sys[IPA_A5_CMD], num_desc, descr)) {
+		if (ipa_send(&ipa_ctx->sys[IPA_A5_CMD], num_desc,
+					descr, false)) {
 			IPAERR("fail to send multiple immediate command set\n");
-			return -EFAULT;
+			result = -EFAULT;
+			goto bail;
 		}
 		wait_for_completion(&desc->xfer_done);
 	}
 
-	return 0;
+	IPA_STATS_INC_IC_CNT(num_desc, descr, ipa_ctx->stats.imm_cmds);
+bail:
+	if (atomic_dec_return(&ipa_ctx->ipa_active_clients) == 0)
+		if (ipa_ctx->ipa_hw_mode == IPA_HW_MODE_NORMAL)
+			ipa_disable_clks();
+	return result;
 }
 
 /**
@@ -457,48 +516,50 @@
  *  - Call the endpoints notify function, passing the skb in the parameters
  *  - Replenish the rx cache
  */
-void ipa_handle_rx_core(void)
+int ipa_handle_rx_core(bool process_all, bool in_poll_state)
 {
 	struct ipa_a5_mux_hdr *mux_hdr;
 	struct ipa_rx_pkt_wrapper *rx_pkt;
 	struct sk_buff *rx_skb;
 	struct sps_iovec iov;
-	unsigned long irq_flags;
-	u16 pull_len;
-	u16 padding;
+	unsigned int pull_len;
+	unsigned int padding;
 	int ret;
 	struct ipa_sys_context *sys = &ipa_ctx->sys[IPA_A5_LAN_WAN_IN];
 	struct ipa_ep_context *ep;
+	int cnt = 0;
+	struct completion *compl;
+	struct ipa_tree_node *node;
 
-	do {
+	while ((in_poll_state ? atomic_read(&ipa_ctx->curr_polling_state) :
+				!atomic_read(&ipa_ctx->curr_polling_state))) {
+		if (cnt && !process_all)
+			break;
+
 		ret = sps_get_iovec(sys->ep->ep_hdl, &iov);
 		if (ret) {
 			IPAERR("sps_get_iovec failed %d\n", ret);
 			break;
 		}
 
-		/* Break the loop when there are no more packets to receive */
 		if (iov.addr == 0)
 			break;
 
-		spin_lock_irqsave(&sys->spinlock, irq_flags);
-		if (list_empty(&sys->head_desc_list))
-			WARN_ON(1);
+		if (unlikely(list_empty(&sys->head_desc_list)))
+			continue;
+
 		rx_pkt = list_first_entry(&sys->head_desc_list,
 					  struct ipa_rx_pkt_wrapper, link);
-		if (!rx_pkt)
-			WARN_ON(1);
+
 		rx_pkt->len = iov.size;
 		sys->len--;
 		list_del(&rx_pkt->link);
-		spin_unlock_irqrestore(&sys->spinlock, irq_flags);
 
 		IPADBG("--curr_cnt=%d\n", sys->len);
 
 		rx_skb = rx_pkt->skb;
 		dma_unmap_single(NULL, rx_pkt->dma_address, IPA_RX_SKB_SIZE,
 				 DMA_FROM_DEVICE);
-		kmem_cache_free(ipa_ctx->rx_pkt_wrapper_cache, rx_pkt);
 
 		/*
 		 * make it look like a real skb, "data" was already set at
@@ -507,6 +568,7 @@
 		rx_skb->tail = rx_skb->data + rx_pkt->len;
 		rx_skb->len = rx_pkt->len;
 		rx_skb->truesize = rx_pkt->len + sizeof(struct sk_buff);
+		kmem_cache_free(ipa_ctx->rx_pkt_wrapper_cache, rx_pkt);
 
 		mux_hdr = (struct ipa_a5_mux_hdr *)rx_skb->data;
 
@@ -517,15 +579,48 @@
 
 		IPA_DUMP_BUFF(rx_skb->data, 0, rx_skb->len);
 
-		if (mux_hdr->src_pipe_index >= IPA_NUM_PIPES ||
+		IPA_STATS_INC_CNT(ipa_ctx->stats.rx_pkts);
+		IPA_STATS_EXCP_CNT(mux_hdr->flags, ipa_ctx->stats.rx_excp_pkts);
+
+		if (unlikely(mux_hdr->flags & IPA_A5_MUX_HDR_EXCP_FLAG_TAG)) {
+			if (ipa_ctx->ipa_hw_mode != IPA_HW_MODE_VIRTUAL) {
+				/* retrieve the compl object from tag value */
+				mux_hdr++;
+				compl = (struct completion *)
+					ntohl(*((u32 *)mux_hdr));
+				IPADBG("%x %x %p\n", *(u32 *)mux_hdr,
+						*((u32 *)mux_hdr + 1), compl);
+
+				mutex_lock(&ipa_ctx->lock);
+				node = ipa_search(&ipa_ctx->tag_tree,
+						(u32)compl);
+				if (node) {
+					complete_all(compl);
+					rb_erase(&node->node,
+							&ipa_ctx->tag_tree);
+					kmem_cache_free(
+						ipa_ctx->tree_node_cache, node);
+				} else {
+					WARN_ON(1);
+				}
+				mutex_unlock(&ipa_ctx->lock);
+			}
+			dev_kfree_skb(rx_skb);
+			ipa_replenish_rx_cache();
+			++cnt;
+			continue;
+		}
+
+		if (unlikely(mux_hdr->src_pipe_index >= IPA_NUM_PIPES ||
 			!ipa_ctx->ep[mux_hdr->src_pipe_index].valid ||
-			!ipa_ctx->ep[mux_hdr->src_pipe_index].client_notify) {
+			!ipa_ctx->ep[mux_hdr->src_pipe_index].client_notify)) {
 			IPAERR("drop pipe=%d ep_valid=%d client_notify=%p\n",
 			  mux_hdr->src_pipe_index,
 			  ipa_ctx->ep[mux_hdr->src_pipe_index].valid,
 			  ipa_ctx->ep[mux_hdr->src_pipe_index].client_notify);
-			dev_kfree_skb_any(rx_skb);
+			dev_kfree_skb(rx_skb);
 			ipa_replenish_rx_cache();
+			++cnt;
 			continue;
 		}
 
@@ -543,10 +638,13 @@
 
 		IPADBG("pulling %d bytes from skb\n", pull_len);
 		skb_pull(rx_skb, pull_len);
+		ipa_replenish_rx_cache();
 		ep->client_notify(ep->priv, IPA_RECEIVE,
 				(unsigned long)(rx_skb));
-		ipa_replenish_rx_cache();
-	} while (1);
+		cnt++;
+	};
+
+	return cnt;
 }
 
 /**
@@ -558,9 +656,9 @@
 	struct ipa_sys_context *sys;
 
 	IPADBG("Enter");
-	if (!ipa_ctx->curr_polling_state) {
+	if (!atomic_read(&ipa_ctx->curr_polling_state)) {
 		IPAERR("already in intr mode\n");
-		return;
+		goto fail;
 	}
 
 	sys = &ipa_ctx->sys[IPA_A5_LAN_WAN_IN];
@@ -568,49 +666,28 @@
 	ret = sps_get_config(sys->ep->ep_hdl, &sys->ep->connect);
 	if (ret) {
 		IPAERR("sps_get_config() failed %d\n", ret);
-		return;
+		goto fail;
 	}
 	sys->event.options = SPS_O_EOT;
 	ret = sps_register_event(sys->ep->ep_hdl, &sys->event);
 	if (ret) {
 		IPAERR("sps_register_event() failed %d\n", ret);
-		return;
+		goto fail;
 	}
 	sys->ep->connect.options =
 		SPS_O_AUTO_ENABLE | SPS_O_ACK_TRANSFERS | SPS_O_EOT;
 	ret = sps_set_config(sys->ep->ep_hdl, &sys->ep->connect);
 	if (ret) {
 		IPAERR("sps_set_config() failed %d\n", ret);
-		return;
+		goto fail;
 	}
-	ipa_handle_rx_core();
-	ipa_ctx->curr_polling_state = 0;
-}
+	atomic_set(&ipa_ctx->curr_polling_state, 0);
+	ipa_handle_rx_core(true, false);
+	return;
 
-/**
- * ipa_rx_switch_to_poll_mode() - Operate the Rx data path in polling mode
- */
-static void ipa_rx_switch_to_poll_mode(void)
-{
-	int ret;
-	struct ipa_ep_context *ep;
-
-	IPADBG("Enter");
-	ep = ipa_ctx->sys[IPA_A5_LAN_WAN_IN].ep;
-
-	ret = sps_get_config(ep->ep_hdl, &ep->connect);
-	if (ret) {
-		IPAERR("sps_get_config() failed %d\n", ret);
-		return;
-	}
-	ep->connect.options =
-		SPS_O_AUTO_ENABLE | SPS_O_ACK_TRANSFERS | SPS_O_POLL;
-	ret = sps_set_config(ep->ep_hdl, &ep->connect);
-	if (ret) {
-		IPAERR("sps_set_config() failed %d\n", ret);
-		return;
-	}
-	ipa_ctx->curr_polling_state = 1;
+fail:
+	IPA_STATS_INC_CNT(ipa_ctx->stats.x_intr_repost);
+	schedule_delayed_work(&switch_to_intr_work, msecs_to_jiffies(1));
 }
 
 /**
@@ -628,16 +705,30 @@
  */
 static void ipa_sps_irq_rx_notify(struct sps_event_notify *notify)
 {
-	struct ipa_rx_pkt_wrapper *rx_pkt;
+	struct ipa_ep_context *ep;
+	int ret;
 
 	IPADBG("event %d notified\n", notify->event_id);
 
 	switch (notify->event_id) {
 	case SPS_EVENT_EOT:
-		if (!ipa_ctx->curr_polling_state) {
-			ipa_rx_switch_to_poll_mode();
-			rx_pkt = notify->data.transfer.user;
-			queue_work(ipa_ctx->rx_wq, &rx_pkt->work);
+		if (!atomic_read(&ipa_ctx->curr_polling_state)) {
+			ep = ipa_ctx->sys[IPA_A5_LAN_WAN_IN].ep;
+
+			ret = sps_get_config(ep->ep_hdl, &ep->connect);
+			if (ret) {
+				IPAERR("sps_get_config() failed %d\n", ret);
+				break;
+			}
+			ep->connect.options = SPS_O_AUTO_ENABLE |
+				SPS_O_ACK_TRANSFERS | SPS_O_POLL;
+			ret = sps_set_config(ep->ep_hdl, &ep->connect);
+			if (ret) {
+				IPAERR("sps_set_config() failed %d\n", ret);
+				break;
+			}
+			atomic_set(&ipa_ctx->curr_polling_state, 1);
+			queue_work(ipa_ctx->rx_wq, &rx_work);
 		}
 		break;
 	default:
@@ -690,6 +781,8 @@
 
 	ipa_ctx->ep[ipa_ep_idx].valid = 1;
 	ipa_ctx->ep[ipa_ep_idx].client = sys_in->client;
+	ipa_ctx->ep[ipa_ep_idx].client_notify = sys_in->notify;
+	ipa_ctx->ep[ipa_ep_idx].priv = sys_in->priv;
 
 	if (ipa_cfg_ep(ipa_ep_idx, &sys_in->ipa_ep_cfg)) {
 		IPAERR("fail to configure EP.\n");
@@ -765,8 +858,11 @@
 		/* fall through */
 	case 3:
 		sys_idx = ipa_ep_idx;
+		INIT_DELAYED_WORK(&replenish_rx_work, replenish_rx_work_func);
+		INIT_DELAYED_WORK(&switch_to_intr_work,
+				switch_to_intr_work_func);
 		break;
-	case 15:
+	case WLAN_AMPDU_TX_EP:
 		sys_idx = IPA_A5_WLAN_AMPDU_OUT;
 		break;
 	default:
@@ -841,8 +937,7 @@
  * @user1
  * @user2
  *
- * This notified callback (client_notify) is for
- * the destination client.
+ * This notified callback is for the destination client.
  * This function is supplied in ipa_connect.
  */
 static void ipa_tx_comp_usr_notify_release(void *user1, void *user2)
@@ -852,11 +947,20 @@
 
 	IPADBG("skb=%p ep=%d\n", skb, ep_idx);
 
+	IPA_STATS_INC_TX_CNT(ep_idx, ipa_ctx->stats.tx_sw_pkts,
+			ipa_ctx->stats.tx_hw_pkts);
+
 	if (ipa_ctx->ep[ep_idx].client_notify)
 		ipa_ctx->ep[ep_idx].client_notify(ipa_ctx->ep[ep_idx].priv,
 				IPA_WRITE_DONE, (unsigned long)skb);
 	else
-		dev_kfree_skb_any(skb);
+		dev_kfree_skb(skb);
+}
+
+static void ipa_tx_cmd_comp(void *user1, void *user2)
+{
+	IPA_STATS_INC_CNT(ipa_ctx->stats.imm_cmds[IPA_IP_PACKET_INIT]);
+	kfree(user1);
 }
 
 /**
@@ -882,7 +986,7 @@
  * get notified by the supplied callback - ipa_sps_irq_tx_comp()
  *
  * ipa_sps_irq_tx_comp will call to the user supplied
- * callback (supplied in ipa_connect())
+ * callback (from ipa_connect)
  *
  * Returns:	0 on success, negative on failure
  */
@@ -896,23 +1000,22 @@
 	memset(&desc, 0, 2 * sizeof(struct ipa_desc));
 
 	ipa_ep_idx = ipa_get_ep_mapping(ipa_ctx->mode, dst);
-	if (ipa_ep_idx == -1) {
+	if (unlikely(ipa_ep_idx == -1)) {
 		IPAERR("dest EP does not exist.\n");
 		goto fail_gen;
 	}
 
-	if (ipa_ctx->ep[ipa_ep_idx].valid == 0) {
+	if (unlikely(ipa_ctx->ep[ipa_ep_idx].valid == 0)) {
 		IPAERR("dest EP not valid.\n");
 		goto fail_gen;
 	}
 
 	if (IPA_CLIENT_IS_CONS(dst)) {
-		cmd = kzalloc(sizeof(struct ipa_ip_packet_init), GFP_KERNEL);
+		cmd = kzalloc(sizeof(struct ipa_ip_packet_init), GFP_ATOMIC);
 		if (!cmd) {
 			IPAERR("failed to alloc immediate command object\n");
 			goto fail_mem_alloc;
 		}
-		memset(cmd, 0x00, sizeof(*cmd));
 
 		cmd->destination_pipe_index = ipa_ep_idx;
 		if (meta && meta->mbim_stream_id_valid)
@@ -921,6 +1024,8 @@
 		desc[0].pyld = cmd;
 		desc[0].len = sizeof(struct ipa_ip_packet_init);
 		desc[0].type = IPA_IMM_CMD_DESC;
+		desc[0].callback = ipa_tx_cmd_comp;
+		desc[0].user1 = cmd;
 		desc[1].pyld = skb->data;
 		desc[1].len = skb->len;
 		desc[1].type = IPA_DATA_DESC_SKB;
@@ -928,7 +1033,8 @@
 		desc[1].user1 = skb;
 		desc[1].user2 = (void *)ipa_ep_idx;
 
-		if (ipa_send(&ipa_ctx->sys[IPA_A5_LAN_WAN_OUT], 2, desc)) {
+		if (ipa_send(&ipa_ctx->sys[IPA_A5_LAN_WAN_OUT], 2, desc,
+					true)) {
 			IPAERR("fail to send immediate command\n");
 			goto fail_send;
 		}
@@ -941,7 +1047,7 @@
 		desc[0].user2 = (void *)ipa_ep_idx;
 
 		if (ipa_send_one(&ipa_ctx->sys[IPA_A5_WLAN_AMPDU_OUT],
-					&desc[0])) {
+					&desc[0], true)) {
 			IPAERR("fail to send skb\n");
 			goto fail_gen;
 		}
@@ -960,6 +1066,24 @@
 }
 EXPORT_SYMBOL(ipa_tx_dp);
 
+static void ipa_handle_rx(void)
+{
+	int inactive_cycles = 0;
+	int cnt;
+
+	do {
+		cnt = ipa_handle_rx_core(true, true);
+		if (cnt == 0) {
+			inactive_cycles++;
+			usleep_range(POLLING_MIN_SLEEP, POLLING_MAX_SLEEP);
+		} else {
+			inactive_cycles = 0;
+		}
+	} while (inactive_cycles <= POLLING_INACTIVITY);
+
+	ipa_rx_switch_to_intr_mode();
+}
+
 /**
  * ipa_handle_rx() - handle packet reception. This function is executed in the
  * context of a work queue.
@@ -968,10 +1092,9 @@
  * ipa_handle_rx_core() is run in polling mode. After all packets has been
  * received, the driver switches back to interrupt mode.
  */
-void ipa_wq_handle_rx(struct work_struct *work)
+static void ipa_wq_handle_rx(struct work_struct *work)
 {
-	ipa_handle_rx_core();
-	ipa_rx_switch_to_intr_mode();
+	ipa_handle_rx();
 }
 
 /**
@@ -993,27 +1116,23 @@
 	void *ptr;
 	struct ipa_rx_pkt_wrapper *rx_pkt;
 	int ret;
-	int rx_len_cached;
-	unsigned long irq_flags;
+	int rx_len_cached = 0;
 	struct ipa_sys_context *sys = &ipa_ctx->sys[IPA_A5_LAN_WAN_IN];
+	gfp_t flag = GFP_NOWAIT | __GFP_NOWARN;
 
-	spin_lock_irqsave(&sys->spinlock, irq_flags);
 	rx_len_cached = sys->len;
-	spin_unlock_irqrestore(&sys->spinlock, irq_flags);
 
-	/* true RX data path is not currently exercised so drop the ceil */
-	while (rx_len_cached < (IPA_RX_POOL_CEIL >> 3)) {
+	while (rx_len_cached < IPA_RX_POOL_CEIL) {
 		rx_pkt = kmem_cache_zalloc(ipa_ctx->rx_pkt_wrapper_cache,
-					   GFP_KERNEL);
+					   flag);
 		if (!rx_pkt) {
 			IPAERR("failed to alloc rx wrapper\n");
-			return;
+			goto fail_kmem_cache_alloc;
 		}
 
 		INIT_LIST_HEAD(&rx_pkt->link);
-		INIT_WORK(&rx_pkt->work, ipa_wq_handle_rx);
 
-		rx_pkt->skb = __dev_alloc_skb(IPA_RX_SKB_SIZE, GFP_KERNEL);
+		rx_pkt->skb = __dev_alloc_skb(IPA_RX_SKB_SIZE, flag);
 		if (rx_pkt->skb == NULL) {
 			IPAERR("failed to alloc skb\n");
 			goto fail_skb_alloc;
@@ -1028,10 +1147,8 @@
 			goto fail_dma_mapping;
 		}
 
-		spin_lock_irqsave(&sys->spinlock, irq_flags);
 		list_add_tail(&rx_pkt->link, &sys->head_desc_list);
 		rx_len_cached = ++sys->len;
-		spin_unlock_irqrestore(&sys->spinlock, irq_flags);
 
 		ret = sps_transfer_one(sys->ep->ep_hdl, rx_pkt->dma_address,
 				       IPA_RX_SKB_SIZE, rx_pkt,
@@ -1041,27 +1158,41 @@
 			IPAERR("sps_transfer_one failed %d\n", ret);
 			goto fail_sps_transfer;
 		}
-
-		IPADBG("++curr_cnt=%d\n", sys->len);
 	}
 
+	ipa_ctx->stats.rx_q_len = sys->len;
+
 	return;
 
 fail_sps_transfer:
-	spin_lock_irqsave(&sys->spinlock, irq_flags);
 	list_del(&rx_pkt->link);
-	--sys->len;
-	spin_unlock_irqrestore(&sys->spinlock, irq_flags);
+	rx_len_cached = --sys->len;
 	dma_unmap_single(NULL, rx_pkt->dma_address, IPA_RX_SKB_SIZE,
 			 DMA_FROM_DEVICE);
 fail_dma_mapping:
-	dev_kfree_skb_any(rx_pkt->skb);
+	dev_kfree_skb(rx_pkt->skb);
 fail_skb_alloc:
 	kmem_cache_free(ipa_ctx->rx_pkt_wrapper_cache, rx_pkt);
-
+fail_kmem_cache_alloc:
+	if (rx_len_cached == 0) {
+		IPA_STATS_INC_CNT(ipa_ctx->stats.rx_repl_repost);
+		schedule_delayed_work(&replenish_rx_work,
+				msecs_to_jiffies(100));
+	}
+	ipa_ctx->stats.rx_q_len = sys->len;
 	return;
 }
 
+static void replenish_rx_work_func(struct work_struct *work)
+{
+	ipa_replenish_rx_cache();
+}
+
+static void switch_to_intr_work_func(struct work_struct *work)
+{
+	ipa_handle_rx();
+}
+
 /**
  * ipa_cleanup_rx() - release RX queue resources
  *
@@ -1070,18 +1201,15 @@
 {
 	struct ipa_rx_pkt_wrapper *rx_pkt;
 	struct ipa_rx_pkt_wrapper *r;
-	unsigned long irq_flags;
 	struct ipa_sys_context *sys = &ipa_ctx->sys[IPA_A5_LAN_WAN_IN];
 
-	spin_lock_irqsave(&sys->spinlock, irq_flags);
 	list_for_each_entry_safe(rx_pkt, r,
 				 &sys->head_desc_list, link) {
 		list_del(&rx_pkt->link);
 		dma_unmap_single(NULL, rx_pkt->dma_address, IPA_RX_SKB_SIZE,
 				 DMA_FROM_DEVICE);
-		dev_kfree_skb_any(rx_pkt->skb);
+		dev_kfree_skb(rx_pkt->skb);
 		kmem_cache_free(ipa_ctx->rx_pkt_wrapper_cache, rx_pkt);
 	}
-	spin_unlock_irqrestore(&sys->spinlock, irq_flags);
 }
 
diff --git a/drivers/platform/msm/ipa/ipa_flt.c b/drivers/platform/msm/ipa/ipa_flt.c
index 81f3a80..b63b939 100644
--- a/drivers/platform/msm/ipa/ipa_flt.c
+++ b/drivers/platform/msm/ipa/ipa_flt.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
@@ -44,17 +44,22 @@
 	const struct ipa_flt_rule *rule =
 		(const struct ipa_flt_rule *)&entry->rule;
 	u16 en_rule = 0;
-	u8 tmp[IPA_RT_FLT_HW_RULE_BUF_SIZE];
+	u32 tmp[IPA_RT_FLT_HW_RULE_BUF_SIZE/4];
 	u8 *start;
 
-	memset(tmp, 0, IPA_RT_FLT_HW_RULE_BUF_SIZE);
-	if (buf == NULL)
-		buf = tmp;
+	if (buf == NULL) {
+		memset(tmp, 0, IPA_RT_FLT_HW_RULE_BUF_SIZE);
+		buf = (u8 *)tmp;
+	}
 
 	start = buf;
 	hdr = (struct ipa_flt_rule_hw_hdr *)buf;
 	hdr->u.hdr.action = entry->rule.action;
-	hdr->u.hdr.rt_tbl_idx = entry->rt_tbl->idx;
+	if (entry->rt_tbl)
+		hdr->u.hdr.rt_tbl_idx = entry->rt_tbl->idx;
+	else
+		/* for excp action flt rules, rt tbl index is meaningless */
+		hdr->u.hdr.rt_tbl_idx = 0;
 	hdr->u.hdr.rsvd = 0;
 	buf += sizeof(struct ipa_flt_rule_hw_hdr);
 
@@ -504,19 +509,23 @@
 	struct ipa_flt_entry *entry;
 	struct ipa_tree_node *node;
 
-	if (!rule->rt_tbl_hdl) {
-		IPAERR("flt rule does not point to valid RT tbl\n");
-		goto error;
-	}
+	if (rule->action != IPA_PASS_TO_EXCEPTION) {
+		if (!rule->rt_tbl_hdl) {
+			IPAERR("flt rule does not point to valid RT tbl\n");
+			goto error;
+		}
 
-	if (ipa_search(&ipa_ctx->rt_tbl_hdl_tree, rule->rt_tbl_hdl) == NULL) {
-		IPAERR("RT tbl not found\n");
-		goto error;
-	}
+		if (ipa_search(&ipa_ctx->rt_tbl_hdl_tree,
+					rule->rt_tbl_hdl) == NULL) {
+			IPAERR("RT tbl not found\n");
+			goto error;
+		}
 
-	if (((struct ipa_rt_tbl *)rule->rt_tbl_hdl)->cookie != IPA_COOKIE) {
-		IPAERR("flt rule cookie is invalid\n");
-		goto error;
+		if (((struct ipa_rt_tbl *)rule->rt_tbl_hdl)->cookie !=
+				IPA_COOKIE) {
+			IPAERR("RT table cookie is invalid\n");
+			goto error;
+		}
 	}
 
 	node = kmem_cache_zalloc(ipa_ctx->tree_node_cache, GFP_KERNEL);
@@ -540,7 +549,8 @@
 	else
 		list_add(&entry->link, &tbl->head_flt_rule_list);
 	tbl->rule_cnt++;
-	entry->rt_tbl->ref_cnt++;
+	if (entry->rt_tbl)
+		entry->rt_tbl->ref_cnt++;
 	*rule_hdl = (u32)entry;
 	IPADBG("add flt rule rule_cnt=%d\n", tbl->rule_cnt);
 
@@ -564,20 +574,23 @@
 	struct ipa_flt_entry *entry = (struct ipa_flt_entry *)rule_hdl;
 	struct ipa_tree_node *node;
 
+	node = ipa_search(&ipa_ctx->flt_rule_hdl_tree, rule_hdl);
+	if (node == NULL) {
+		IPAERR("lookup failed\n");
+
+		return -EINVAL;
+	}
+
 	if (entry == NULL || (entry->cookie != IPA_COOKIE)) {
 		IPAERR("bad params\n");
 
 		return -EINVAL;
 	}
-	node = ipa_search(&ipa_ctx->flt_rule_hdl_tree, rule_hdl);
-	if (node == NULL) {
-		IPAERR("lookup failed\n");
 
-		return -EPERM;
-	}
 	list_del(&entry->link);
 	entry->tbl->rule_cnt--;
-	entry->rt_tbl->ref_cnt--;
+	if (entry->rt_tbl)
+		entry->rt_tbl->ref_cnt--;
 	IPADBG("del flt rule rule_cnt=%d\n", entry->tbl->rule_cnt);
 	entry->cookie = 0;
 	kmem_cache_free(ipa_ctx->flt_rule_cache, entry);
@@ -594,6 +607,12 @@
 {
 	struct ipa_flt_tbl *tbl;
 
+	if (rule == NULL || rule_hdl == NULL) {
+		IPAERR("bad parms rule=%p rule_hdl=%p\n", rule, rule_hdl);
+
+		return -EINVAL;
+	}
+
 	tbl = &ipa_ctx->glob_flt_tbl[ip];
 	IPADBG("add global flt rule ip=%d\n", ip);
 
@@ -607,16 +626,16 @@
 	struct ipa_flt_tbl *tbl;
 	int ipa_ep_idx;
 
-	if (ip >= IPA_IP_MAX || rule == NULL || rule_hdl == NULL ||
-			ep >= IPA_CLIENT_MAX) {
-		IPAERR("bad parms\n");
+	if (rule == NULL || rule_hdl == NULL || ep >= IPA_CLIENT_MAX) {
+		IPAERR("bad parms rule=%p rule_hdl=%p ep=%d\n", rule,
+				rule_hdl, ep);
 
 		return -EINVAL;
 	}
 	ipa_ep_idx = ipa_get_ep_mapping(ipa_ctx->mode, ep);
 	if (ipa_ep_idx == IPA_FLT_TABLE_INDEX_NOT_FOUND ||
 				ipa_ctx->ep[ipa_ep_idx].valid == 0) {
-		IPAERR("bad parms\n");
+		IPAERR("ep not valid and/or connected ep_idx=%d\n", ipa_ep_idx);
 
 		return -EINVAL;
 	}
@@ -694,7 +713,6 @@
 
 	if (hdls == NULL || hdls->num_hdls == 0 || hdls->ip >= IPA_IP_MAX) {
 		IPAERR("bad parm\n");
-
 		return -EINVAL;
 	}
 
@@ -735,6 +753,11 @@
 {
 	int result;
 
+	if (ip >= IPA_IP_MAX) {
+		IPAERR("bad parm\n");
+		return -EINVAL;
+	}
+
 	mutex_lock(&ipa_ctx->lock);
 
 	if (__ipa_commit_flt(ip)) {
@@ -767,6 +790,11 @@
 	struct ipa_tree_node *node;
 	int i;
 
+	if (ip >= IPA_IP_MAX) {
+		IPAERR("bad parm\n");
+		return -EINVAL;
+	}
+
 	tbl = &ipa_ctx->glob_flt_tbl[ip];
 	mutex_lock(&ipa_ctx->lock);
 	IPADBG("reset flt ip=%d\n", ip);
@@ -774,9 +802,21 @@
 		node = ipa_search(&ipa_ctx->flt_rule_hdl_tree, (u32)entry);
 		if (node == NULL)
 			WARN_ON(1);
+
+		if ((ip == IPA_IP_v4 &&
+		     entry->rule.attrib.attrib_mask == IPA_FLT_PROTOCOL &&
+		     entry->rule.attrib.u.v4.protocol ==
+		      IPA_INVALID_L4_PROTOCOL) ||
+		    (ip == IPA_IP_v6 &&
+		     entry->rule.attrib.attrib_mask == IPA_FLT_NEXT_HDR &&
+		     entry->rule.attrib.u.v6.next_hdr ==
+		      IPA_INVALID_L4_PROTOCOL))
+			continue;
+
 		list_del(&entry->link);
 		entry->tbl->rule_cnt--;
-		entry->rt_tbl->ref_cnt--;
+		if (entry->rt_tbl)
+			entry->rt_tbl->ref_cnt--;
 		entry->cookie = 0;
 		kmem_cache_free(ipa_ctx->flt_rule_cache, entry);
 
@@ -795,7 +835,8 @@
 				WARN_ON(1);
 			list_del(&entry->link);
 			entry->tbl->rule_cnt--;
-			entry->rt_tbl->ref_cnt--;
+			if (entry->rt_tbl)
+				entry->rt_tbl->ref_cnt--;
 			entry->cookie = 0;
 			kmem_cache_free(ipa_ctx->flt_rule_cache, entry);
 
diff --git a/drivers/platform/msm/ipa/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_hdr.c
index 4b9a500..0439a69 100644
--- a/drivers/platform/msm/ipa/ipa_hdr.c
+++ b/drivers/platform/msm/ipa/ipa_hdr.c
@@ -12,7 +12,7 @@
 
 #include "ipa_i.h"
 
-static const u32 ipa_hdr_bin_sz[IPA_HDR_BIN_MAX] = { 8, 16, 32, 64 };
+static const u32 ipa_hdr_bin_sz[IPA_HDR_BIN_MAX] = { 8, 16, 24, 36 };
 
 /**
  * ipa_generate_hdr_hw_tbl() - generates the headers table
@@ -234,20 +234,21 @@
 	return -EPERM;
 }
 
-static int __ipa_del_hdr(u32 hdr_hdl)
+int __ipa_del_hdr(u32 hdr_hdl)
 {
 	struct ipa_hdr_entry *entry = (struct ipa_hdr_entry *)hdr_hdl;
 	struct ipa_tree_node *node;
 	struct ipa_hdr_tbl *htbl = &ipa_ctx->hdr_tbl;
 
-	if (!entry || (entry->cookie != IPA_COOKIE) || (entry->ref_cnt != 0)) {
-		IPAERR("bad parm\n");
-		return -EINVAL;
-	}
 	node = ipa_search(&ipa_ctx->hdr_hdl_tree, hdr_hdl);
 	if (node == NULL) {
 		IPAERR("lookup failed\n");
-		return -EPERM;
+		return -EINVAL;
+	}
+
+	if (!entry || (entry->cookie != IPA_COOKIE) || (entry->ref_cnt != 0)) {
+		IPAERR("bad parm\n");
+		return -EINVAL;
 	}
 
 	IPADBG("del hdr of sz=%d hdr_cnt=%d ofst=%d\n", entry->hdr_len,
@@ -545,17 +546,21 @@
 	struct ipa_tree_node *node;
 	int result = -EFAULT;
 
-	if (entry == NULL || entry->cookie != IPA_COOKIE ||
-			entry->ref_cnt == 0) {
-		IPAERR("bad params\n");
-		return -EINVAL;
-	}
+	mutex_lock(&ipa_ctx->lock);
 	node = ipa_search(&ipa_ctx->hdr_hdl_tree, hdr_hdl);
 	if (node == NULL) {
 		IPAERR("lookup failed\n");
-		return -EPERM;
+		result = -EINVAL;
+		goto bail;
 	}
-	mutex_lock(&ipa_ctx->lock);
+
+	if (entry == NULL || entry->cookie != IPA_COOKIE ||
+			entry->ref_cnt == 0) {
+		IPAERR("bad params\n");
+		result = -EINVAL;
+		goto bail;
+	}
+
 	entry->ref_cnt--;
 	if (entry->ref_cnt == 0) {
 		if (__ipa_del_hdr(hdr_hdl)) {
diff --git a/drivers/platform/msm/ipa/ipa_hw_defs.h b/drivers/platform/msm/ipa/ipa_hw_defs.h
index 3131a84..3b9ce3d 100644
--- a/drivers/platform/msm/ipa/ipa_hw_defs.h
+++ b/drivers/platform/msm/ipa/ipa_hw_defs.h
@@ -164,12 +164,12 @@
 	u64 rsvd:32;
 };
 
-#define IPA_A5_MUX_HDR_EXCP_FLAG_IP		BIT(0)
-#define IPA_A5_MUX_HDR_EXCP_FLAG_NAT		BIT(1)
-#define IPA_A5_MUX_HDR_EXCP_FLAG_SW_FLT	BIT(2)
-#define IPA_A5_MUX_HDR_EXCP_FLAG_TAG		BIT(3)
-#define IPA_A5_MUX_HDR_EXCP_FLAG_REPLICATED	BIT(4)
-#define IPA_A5_MUX_HDR_EXCP_FLAG_IHL		BIT(5)
+#define IPA_A5_MUX_HDR_EXCP_FLAG_IP		BIT(7)
+#define IPA_A5_MUX_HDR_EXCP_FLAG_NAT		BIT(6)
+#define IPA_A5_MUX_HDR_EXCP_FLAG_SW_FLT	BIT(5)
+#define IPA_A5_MUX_HDR_EXCP_FLAG_TAG		BIT(4)
+#define IPA_A5_MUX_HDR_EXCP_FLAG_REPLICATED	BIT(3)
+#define IPA_A5_MUX_HDR_EXCP_FLAG_IHL		BIT(2)
 
 /**
  * struct ipa_a5_mux_hdr - A5 MUX header definition
@@ -255,4 +255,12 @@
 	u64 public_ip_addr:32;
 };
 
+/**
+ * struct ipa_ip_packet_tag - IPA_IP_PACKET_TAG command payload
+ * @tag: tag value returned with response
+ */
+struct ipa_ip_packet_tag {
+	u32 tag;
+};
+
 #endif /* _IPA_HW_DEFS_H */
diff --git a/drivers/platform/msm/ipa/ipa_i.h b/drivers/platform/msm/ipa/ipa_i.h
index 3be2369..cb8c0f5 100644
--- a/drivers/platform/msm/ipa/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_i.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
@@ -34,11 +34,54 @@
 
 #ifdef IPA_DEBUG
 #define IPADBG(fmt, args...) \
-	pr_debug(DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)
+	pr_err(DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)
+/*	pr_debug(DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args) */
 #else
 #define IPADBG(fmt, args...)
 #endif
 
+#define WLAN_AMPDU_TX_EP (15)
+#define MAX_NUM_EXCP	 (8)
+#define MAX_NUM_IMM_CMD	 (17)
+
+#define IPA_STATS
+
+#ifdef IPA_STATS
+#define IPA_STATS_INC_CNT(val) do {			\
+				++val;			\
+			} while (0)
+#define IPA_STATS_INC_CNT_SAFE(val) do {		\
+				atomic_inc(&val);	\
+			} while (0)
+#define IPA_STATS_EXCP_CNT(flags, base) do {			\
+			int i;					\
+			for (i = 0; i < MAX_NUM_EXCP; i++)	\
+				if (flags & BIT(i))		\
+					++base[i];		\
+			} while (0)
+#define IPA_STATS_INC_TX_CNT(ep, sw, hw) do {		\
+			if (ep == WLAN_AMPDU_TX_EP)	\
+				++hw;			\
+			else				\
+				++sw;			\
+			} while (0)
+#define IPA_STATS_INC_IC_CNT(num, base, stat_base) do {			\
+			int i;						\
+			for (i = 0; i < num; i++)			\
+				++stat_base[base[i].opcode];		\
+			} while (0)
+#define IPA_STATS_INC_BRIDGE_CNT(type, dir, base) do {		\
+			++base[type][dir];			\
+			} while (0)
+#else
+#define IPA_STATS_INC_CNT(x) do { } while (0)
+#define IPA_STATS_INC_CNT_SAFE(x) do { } while (0)
+#define IPA_STATS_EXCP_CNT(flags, base) do { } while (0)
+#define IPA_STATS_INC_TX_CNT(ep, sw, hw) do { } while (0)
+#define IPA_STATS_INC_IC_CNT(num, base, stat_base) do { } while (0)
+#define IPA_STATS_INC_BRIDGE_CNT(type, dir, base) do { } while (0)
+#endif
+
 #define IPAERR(fmt, args...) \
 	pr_err(DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)
 
@@ -67,10 +110,12 @@
 
 #define IPA_EVENT_THRESHOLD 0x10
 
-#define IPA_RX_POOL_CEIL 24
+#define IPA_RX_POOL_CEIL 32
 #define IPA_RX_SKB_SIZE 2048
 
 #define IPA_DFLT_HDR_NAME "ipa_excp_hdr"
+#define IPA_INVALID_L4_PROTOCOL 0xFF
+
 
 #define IPA_CLIENT_IS_PROD(x) (x >= IPA_CLIENT_PROD && x < IPA_CLIENT_CONS)
 #define IPA_CLIENT_IS_CONS(x) (x >= IPA_CLIENT_CONS && x < IPA_CLIENT_MAX)
@@ -110,17 +155,6 @@
 };
 
 /**
- * enum ipa_bridge_dir - direction of the bridge from air interface perspective
- *
- * IPA bridge direction
- */
-enum ipa_bridge_dir {
-	IPA_DL,
-	IPA_UL,
-	IPA_DIR_MAX
-};
-
-/**
  * struct ipa_mem_buffer - IPA memory buffer
  * @base: base
  * @phys_base: physical base address
@@ -298,13 +332,15 @@
  * @connect: SPS connect
  * @priv: user provided information which will forwarded once the user is
  *        notified for new data avail
- * @client_notify: user provided CB for EP events notification
+ * @client_notify: user provided CB for EP events notification, the event is
+ *                 data revived.
  * @desc_fifo_in_pipe_mem: flag indicating if descriptors FIFO uses pipe memory
  * @data_fifo_in_pipe_mem: flag indicating if data FIFO uses pipe memory
  * @desc_fifo_pipe_mem_ofst: descriptors FIFO pipe memory offset
  * @data_fifo_pipe_mem_ofst: data FIFO pipe memory offset
  * @desc_fifo_client_allocated: if descriptors FIFO was allocated by a client
  * @data_fifo_client_allocated: if data FIFO was allocated by a client
+ * @suspended: valid for B2B pipes, whether IPA EP is suspended
  */
 struct ipa_ep_context {
 	int valid;
@@ -323,6 +359,7 @@
 	u32 data_fifo_pipe_mem_ofst;
 	bool desc_fifo_client_allocated;
 	bool data_fifo_client_allocated;
+	bool suspended;
 };
 
 /**
@@ -358,8 +395,7 @@
 
 /**
  * struct ipa_tx_pkt_wrapper - IPA Tx packet wrapper
- * @type: specify if this packet is a data packet (skb) or
- * an immediate command
+ * @type: specify if this packet is for the skb or immediate command
  * @mem: memory buffer used by this Tx packet
  * @work: work struct for current Tx packet
  * @link: linked to the wrappers on that pipe
@@ -386,7 +422,7 @@
 	void *user2;
 	struct ipa_sys_context *sys;
 	struct ipa_mem_buffer mult;
-	u16 cnt;
+	u32 cnt;
 	void *bounce;
 };
 
@@ -417,16 +453,14 @@
  * struct ipa_rx_pkt_wrapper - IPA Rx packet wrapper
  * @skb: skb
  * @dma_address: DMA address of this Rx packet
- * @work: work struct for current Rx packet
  * @link: linked to the Rx packets on that pipe
  * @len: how many bytes are copied into skb's flat buffer
  */
 struct ipa_rx_pkt_wrapper {
 	struct sk_buff *skb;
 	dma_addr_t dma_address;
-	struct work_struct work;
 	struct list_head link;
-	u16 len;
+	u32 len;
 };
 
 /**
@@ -458,6 +492,45 @@
 };
 
 /**
+ * enum ipa_hw_type - IPA hardware version type
+ * @IPA_HW_None: IPA hardware version not defined
+ * @IPA_HW_v1_0: IPA hardware version 1.0, corresponding to ELAN 1.0
+ * @IPA_HW_v1_1: IPA hardware version 1.1, corresponding to ELAN 2.0
+ * @IPA_HW_v2_0: IPA hardware version 2.0
+ */
+enum ipa_hw_type {
+	IPA_HW_None = 0,
+	IPA_HW_v1_0 = 1,
+	IPA_HW_v1_1 = 2,
+	IPA_HW_v2_0 = 3
+};
+
+/**
+ * enum ipa_hw_mode - IPA hardware mode
+ * @IPA_HW_Normal: Regular IPA hardware
+ * @IPA_HW_Virtual: IPA hardware supporting virtual memory allocation
+ * @IPA_HW_PCIE: IPA hardware supporting memory allocation over PCIE Bridge
+ */
+enum ipa_hw_mode {
+	IPA_HW_MODE_NORMAL  = 0,
+	IPA_HW_MODE_VIRTUAL = 1,
+	IPA_HW_MODE_PCIE    = 2
+};
+
+
+struct ipa_stats {
+	u32 imm_cmds[MAX_NUM_IMM_CMD];
+	u32 tx_sw_pkts;
+	u32 tx_hw_pkts;
+	u32 rx_pkts;
+	u32 rx_excp_pkts[MAX_NUM_EXCP];
+	u32 bridged_pkts[IPA_BRIDGE_TYPE_MAX][IPA_BRIDGE_DIR_MAX];
+	u32 rx_repl_repost;
+	u32 x_intr_repost;
+	u32 rx_q_len;
+};
+
+/**
  * struct ipa_context - IPA context
  * @class: pointer to the struct class
  * @dev_num: device number
@@ -510,6 +583,8 @@
  * @empty_rt_tbl_mem: empty routing tables memory
  * @pipe_mem_pool: pipe memory pool
  * @one_kb_no_straddle_pool: one kb no straddle pool
+ * @ipa_hw_type: type of IPA HW type (e.g. IPA 1.0, IPA 1.1 etc')
+ * @ipa_hw_mode: mode of IPA HW mode (e.g. Normal, Virtual or over PCIe)
  *
  * IPA context - holds all relevant info about IPA driver and its state
  */
@@ -546,6 +621,7 @@
 	struct rb_root rt_rule_hdl_tree;
 	struct rb_root rt_tbl_hdl_tree;
 	struct rb_root flt_rule_hdl_tree;
+	struct rb_root tag_tree;
 	struct ipa_nat_mem nat_mem;
 	u32 excp_hdr_hdl;
 	u32 dflt_v4_rt_rule_hdl;
@@ -554,7 +630,7 @@
 	uint aggregation_type;
 	uint aggregation_byte_limit;
 	uint aggregation_time_limit;
-	uint curr_polling_state;
+	atomic_t curr_polling_state;
 	struct delayed_work poll_work;
 	bool hdr_tbl_lcl;
 	struct ipa_mem_buffer hdr_mem;
@@ -570,6 +646,15 @@
 	u32 clnt_hdl_data_in;
 	u32 clnt_hdl_data_out;
 	u8 a5_pipe_index;
+	struct list_head intf_list;
+	struct list_head msg_list;
+	struct list_head pull_msg_list;
+	struct mutex msg_lock;
+	wait_queue_head_t msg_waitq;
+	enum ipa_hw_type ipa_hw_type;
+	enum ipa_hw_mode ipa_hw_mode;
+	/* featurize if memory footprint becomes a concern */
+	struct ipa_stats stats;
 };
 
 /**
@@ -630,16 +715,39 @@
 	int			desc_fifo_size;
 };
 
+struct ipa_plat_drv_res {
+	u32 ipa_mem_base;
+	u32 ipa_mem_size;
+	u32 bam_mem_base;
+	u32 bam_mem_size;
+	u32 a2_bam_mem_base;
+	u32 a2_bam_mem_size;
+	u32 ipa_irq;
+	u32 bam_irq;
+	u32 a2_bam_irq;
+	u32 ipa_pipe_mem_start_ofst;
+	u32 ipa_pipe_mem_size;
+	enum ipa_hw_type ipa_hw_type;
+	enum ipa_hw_mode ipa_hw_mode;
+	struct a2_mux_pipe_connection a2_to_ipa_pipe;
+	struct a2_mux_pipe_connection ipa_to_a2_pipe;
+};
+
 extern struct ipa_context *ipa_ctx;
 
 int ipa_get_a2_mux_pipe_info(enum a2_mux_pipe_direction pipe_dir,
 				struct a2_mux_pipe_connection *pipe_connect);
+int ipa_get_a2_mux_bam_info(u32 *a2_bam_mem_base, u32 *a2_bam_mem_size,
+			    u32 *a2_bam_irq);
 void rmnet_bridge_get_client_handles(u32 *producer_handle,
 		u32 *consumer_handle);
-int ipa_send_one(struct ipa_sys_context *sys, struct ipa_desc *desc);
-int ipa_send(struct ipa_sys_context *sys, u16 num_desc, struct ipa_desc *desc);
+int ipa_send_one(struct ipa_sys_context *sys, struct ipa_desc *desc,
+		bool in_atomic);
+int ipa_send(struct ipa_sys_context *sys, u32 num_desc, struct ipa_desc *desc,
+		bool in_atomic);
 int ipa_get_ep_mapping(enum ipa_operating_mode mode,
 		       enum ipa_client_type client);
+int ipa_get_client_mapping(enum ipa_operating_mode mode, int pipe_idx);
 int ipa_generate_hw_rule(enum ipa_ip_type ip,
 			 const struct ipa_rule_attrib *attrib,
 			 u8 **buf,
@@ -654,33 +762,11 @@
 int ipa_generate_hdr_hw_tbl(struct ipa_mem_buffer *mem);
 int ipa_generate_rt_hw_tbl(enum ipa_ip_type ip, struct ipa_mem_buffer *mem);
 int ipa_generate_flt_hw_tbl(enum ipa_ip_type ip, struct ipa_mem_buffer *mem);
+int ipa_set_single_ndp_per_mbim(bool);
+int ipa_set_hw_timer_fix_for_mbim_aggr(bool);
 void ipa_debugfs_init(void);
 void ipa_debugfs_remove(void);
 
-/*
- * below functions read from/write to IPA local memory a.k.a. device memory.
- * the order of the arguments is deliberately different from the ipa_write*
- * functions which operate on system memory
- */
-void ipa_write_dev_8(u8 val, u16 ofst_ipa_sram);
-void ipa_write_dev_16(u16 val, u16 ofst_ipa_sram);
-void ipa_write_dev_32(u32 val, u16 ofst_ipa_sram);
-unsigned int ipa_read_dev_8(u16 ofst_ipa_sram);
-unsigned int ipa_read_dev_16(u16 ofst_ipa_sram);
-unsigned int ipa_read_dev_32(u16 ofst_ipa_sram);
-void ipa_write_dev_8rep(u16 ofst_ipa_sram, const void *buf,
-		unsigned long count);
-void ipa_write_dev_16rep(u16 ofst_ipa_sram, const void *buf,
-		unsigned long count);
-void ipa_write_dev_32rep(u16 ofst_ipa_sram, const void *buf,
-		unsigned long count);
-void ipa_read_dev_8rep(u16 ofst_ipa_sram, void *buf, unsigned long count);
-void ipa_read_dev_16rep(u16 ofst_ipa_sram, void *buf, unsigned long count);
-void ipa_read_dev_32rep(u16 ofst_ipa_sram, void *buf, unsigned long count);
-void ipa_memset_dev(u16 ofst_ipa_sram, u8 value, unsigned int count);
-void ipa_memcpy_from_dev(void *dest, u16 ofst_ipa_sram, unsigned int count);
-void ipa_memcpy_to_dev(u16 ofst_ipa_sram, void *source, unsigned int count);
-
 int ipa_insert(struct rb_root *root, struct ipa_tree_node *data);
 struct ipa_tree_node *ipa_search(struct rb_root *root, u32 hdl);
 void ipa_dump_buff_internal(void *base, dma_addr_t phy_base, u32 size);
@@ -698,8 +784,7 @@
 void ipa_cleanup_rx(void);
 int ipa_cfg_filter(u32 disable);
 void ipa_wq_write_done(struct work_struct *work);
-void ipa_wq_handle_rx(struct work_struct *work);
-void ipa_handle_rx_core(void);
+int ipa_handle_rx_core(bool process_all, bool in_poll_state);
 int ipa_pipe_mem_init(u32 start_ofst, u32 size);
 int ipa_pipe_mem_alloc(u32 *ofst, u32 size);
 int ipa_pipe_mem_free(u32 ofst, u32 size);
@@ -707,6 +792,8 @@
 struct ipa_context *ipa_get_ctx(void);
 void ipa_enable_clks(void);
 void ipa_disable_clks(void);
+int __ipa_del_rt_rule(u32 rule_hdl);
+int __ipa_del_hdr(u32 hdr_hdl);
 
 static inline u32 ipa_read_reg(void *base, u32 offset)
 {
@@ -725,7 +812,19 @@
 
 int ipa_bridge_init(void);
 void ipa_bridge_cleanup(void);
-int ipa_bridge_setup(enum ipa_bridge_dir dir);
-int ipa_bridge_teardown(enum ipa_bridge_dir dir);
+
+ssize_t ipa_read(struct file *filp, char __user *buf, size_t count,
+		 loff_t *f_pos);
+int ipa_pull_msg(struct ipa_msg_meta *meta, char *buff, size_t count);
+int ipa_query_intf(struct ipa_ioc_query_intf *lookup);
+int ipa_query_intf_tx_props(struct ipa_ioc_query_intf_tx_props *tx);
+int ipa_query_intf_rx_props(struct ipa_ioc_query_intf_rx_props *rx);
+
+int a2_mux_init(void);
+int a2_mux_exit(void);
+
+void wwan_cleanup(void);
+
+int teth_bridge_driver_init(void);
 
 #endif /* _IPA_I_H_ */
diff --git a/drivers/platform/msm/ipa/ipa_intf.c b/drivers/platform/msm/ipa/ipa_intf.c
new file mode 100644
index 0000000..9876650
--- /dev/null
+++ b/drivers/platform/msm/ipa/ipa_intf.c
@@ -0,0 +1,490 @@
+/* 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/fs.h>
+#include <linux/sched.h>
+#include "ipa_i.h"
+
+struct ipa_intf {
+	char name[IPA_RESOURCE_NAME_MAX];
+	struct list_head link;
+	u32 num_tx_props;
+	u32 num_rx_props;
+	struct ipa_ioc_tx_intf_prop *tx;
+	struct ipa_ioc_rx_intf_prop *rx;
+};
+
+struct ipa_push_msg {
+	struct ipa_msg_meta meta;
+	ipa_msg_free_fn callback;
+	void *buff;
+	struct list_head link;
+};
+
+struct ipa_pull_msg {
+	struct ipa_msg_meta meta;
+	ipa_msg_pull_fn callback;
+	struct list_head link;
+};
+
+/**
+ * ipa_register_intf() - register "logical" interface
+ * @name: [in] interface name
+ * @tx:	[in] TX properties of the interface
+ * @rx:	[in] RX properties of the interface
+ *
+ * Register an interface and its tx and rx properties, this allows
+ * configuration of rules from user-space
+ *
+ * Returns:	0 on success, negative on failure
+ *
+ * Note:	Should not be called from atomic context
+ */
+int ipa_register_intf(const char *name, const struct ipa_tx_intf *tx,
+		       const struct ipa_rx_intf *rx)
+{
+	struct ipa_intf *intf;
+	u32 len;
+
+	if (name == NULL || (tx == NULL && rx == NULL)) {
+		IPAERR("invalid params name=%p tx=%p rx=%p\n", name, tx, rx);
+		return -EINVAL;
+	}
+
+	len = sizeof(struct ipa_intf);
+	intf = kzalloc(len, GFP_KERNEL);
+	if (intf == NULL) {
+		IPAERR("fail to alloc 0x%x bytes\n", len);
+		return -ENOMEM;
+	}
+
+	strlcpy(intf->name, name, IPA_RESOURCE_NAME_MAX);
+
+	if (tx) {
+		intf->num_tx_props = tx->num_props;
+		len = tx->num_props * sizeof(struct ipa_ioc_tx_intf_prop);
+		intf->tx = kzalloc(len, GFP_KERNEL);
+		if (intf->tx == NULL) {
+			IPAERR("fail to alloc 0x%x bytes\n", len);
+			kfree(intf);
+			return -ENOMEM;
+		}
+		memcpy(intf->tx, tx->prop, len);
+	}
+
+	if (rx) {
+		intf->num_rx_props = rx->num_props;
+		len = rx->num_props * sizeof(struct ipa_ioc_rx_intf_prop);
+		intf->rx = kzalloc(len, GFP_KERNEL);
+		if (intf->rx == NULL) {
+			IPAERR("fail to alloc 0x%x bytes\n", len);
+			kfree(intf->tx);
+			kfree(intf);
+			return -ENOMEM;
+		}
+		memcpy(intf->rx, rx->prop, len);
+	}
+
+	mutex_lock(&ipa_ctx->lock);
+	list_add_tail(&intf->link, &ipa_ctx->intf_list);
+	mutex_unlock(&ipa_ctx->lock);
+
+	return 0;
+}
+EXPORT_SYMBOL(ipa_register_intf);
+
+/**
+ * ipa_deregister_intf() - de-register previously registered logical interface
+ * @name: [in] interface name
+ *
+ * De-register a previously registered interface
+ *
+ * Returns:	0 on success, negative on failure
+ *
+ * Note:	Should not be called from atomic context
+ */
+int ipa_deregister_intf(const char *name)
+{
+	struct ipa_intf *entry;
+	struct ipa_intf *next;
+	int result = -EINVAL;
+
+	if (name == NULL) {
+		IPAERR("invalid param name=%p\n", name);
+		return result;
+	}
+
+	mutex_lock(&ipa_ctx->lock);
+	list_for_each_entry_safe(entry, next, &ipa_ctx->intf_list, link) {
+		if (!strncmp(entry->name, name, IPA_RESOURCE_NAME_MAX)) {
+			list_del(&entry->link);
+			kfree(entry->rx);
+			kfree(entry->tx);
+			kfree(entry);
+			result = 0;
+			break;
+		}
+	}
+	mutex_unlock(&ipa_ctx->lock);
+	return result;
+}
+EXPORT_SYMBOL(ipa_deregister_intf);
+
+/**
+ * ipa_query_intf() - query logical interface properties
+ * @lookup:	[inout] interface name and number of properties
+ *
+ * Obtain the handle and number of tx and rx properties for the named
+ * interface, used as part of querying the tx and rx properties for
+ * configuration of various rules from user-space
+ *
+ * Returns:	0 on success, negative on failure
+ *
+ * Note:	Should not be called from atomic context
+ */
+int ipa_query_intf(struct ipa_ioc_query_intf *lookup)
+{
+	struct ipa_intf *entry;
+	int result = -EINVAL;
+
+	if (lookup == NULL) {
+		IPAERR("invalid param lookup=%p\n", lookup);
+		return result;
+	}
+
+	mutex_lock(&ipa_ctx->lock);
+	list_for_each_entry(entry, &ipa_ctx->intf_list, link) {
+		if (!strncmp(entry->name, lookup->name,
+					IPA_RESOURCE_NAME_MAX)) {
+			lookup->num_tx_props = entry->num_tx_props;
+			lookup->num_rx_props = entry->num_rx_props;
+			result = 0;
+			break;
+		}
+	}
+	mutex_unlock(&ipa_ctx->lock);
+	return result;
+}
+
+/**
+ * ipa_query_intf_tx_props() - qeury TX props of an interface
+ * @tx:  [inout] interface tx attributes
+ *
+ * Obtain the tx properties for the specifed interface
+ *
+ * Returns:	0 on success, negative on failure
+ *
+ * Note:	Should not be called from atomic context
+ */
+int ipa_query_intf_tx_props(struct ipa_ioc_query_intf_tx_props *tx)
+{
+	struct ipa_intf *entry;
+	int result = -EINVAL;
+
+	if (tx == NULL) {
+		IPAERR("invalid param tx=%p\n", tx);
+		return result;
+	}
+
+	mutex_lock(&ipa_ctx->lock);
+	list_for_each_entry(entry, &ipa_ctx->intf_list, link) {
+		if (!strncmp(entry->name, tx->name, IPA_RESOURCE_NAME_MAX)) {
+			memcpy(tx->tx, entry->tx, entry->num_tx_props *
+			       sizeof(struct ipa_ioc_tx_intf_prop));
+			result = 0;
+			break;
+		}
+	}
+	mutex_unlock(&ipa_ctx->lock);
+	return result;
+}
+
+/**
+ * ipa_query_intf_rx_props() - qeury RX props of an interface
+ * @rx:  [inout] interface rx attributes
+ *
+ * Obtain the rx properties for the specifed interface
+ *
+ * Returns:	0 on success, negative on failure
+ *
+ * Note:	Should not be called from atomic context
+ */
+int ipa_query_intf_rx_props(struct ipa_ioc_query_intf_rx_props *rx)
+{
+	struct ipa_intf *entry;
+	int result = -EINVAL;
+
+	if (rx == NULL) {
+		IPAERR("invalid param rx=%p\n", rx);
+		return result;
+	}
+
+	mutex_lock(&ipa_ctx->lock);
+	list_for_each_entry(entry, &ipa_ctx->intf_list, link) {
+		if (!strncmp(entry->name, rx->name, IPA_RESOURCE_NAME_MAX)) {
+			memcpy(rx->rx, entry->rx, entry->num_rx_props *
+					sizeof(struct ipa_ioc_rx_intf_prop));
+			result = 0;
+			break;
+		}
+	}
+	mutex_unlock(&ipa_ctx->lock);
+	return result;
+}
+
+/**
+ * ipa_send_msg() - Send "message" from kernel client to IPA driver
+ * @meta: [in] message meta-data
+ * @buff: [in] the payload for message
+ * @callback: [in] free callback
+ *
+ * Client supplies the message meta-data and payload which IPA driver buffers
+ * till read by user-space. After read from user space IPA driver invokes the
+ * callback supplied to free the message payload. Client must not touch/free
+ * the message payload after calling this API.
+ *
+ * Returns:	0 on success, negative on failure
+ *
+ * Note:	Should not be called from atomic context
+ */
+int ipa_send_msg(struct ipa_msg_meta *meta, void *buff,
+		  ipa_msg_free_fn callback)
+{
+	struct ipa_push_msg *msg;
+
+	if (meta == NULL || (buff == NULL && callback != NULL) ||
+	    (buff != NULL && callback == NULL)) {
+		IPAERR("invalid param meta=%p buff=%p, callback=%p\n",
+		       meta, buff, callback);
+		return -EINVAL;
+	}
+
+	msg = kzalloc(sizeof(struct ipa_push_msg), GFP_KERNEL);
+	if (msg == NULL) {
+		IPAERR("fail to alloc ipa_msg container\n");
+		return -ENOMEM;
+	}
+
+	msg->meta = *meta;
+	msg->buff = buff;
+	msg->callback = callback;
+
+	mutex_lock(&ipa_ctx->msg_lock);
+	list_add_tail(&msg->link, &ipa_ctx->msg_list);
+	mutex_unlock(&ipa_ctx->msg_lock);
+
+	wake_up(&ipa_ctx->msg_waitq);
+
+	return 0;
+}
+EXPORT_SYMBOL(ipa_send_msg);
+
+/**
+ * ipa_register_pull_msg() - register pull message type
+ * @meta: [in] message meta-data
+ * @callback: [in] pull callback
+ *
+ * Register message callback by kernel client with IPA driver for IPA driver to
+ * pull message on-demand.
+ *
+ * Returns:	0 on success, negative on failure
+ *
+ * Note:	Should not be called from atomic context
+ */
+int ipa_register_pull_msg(struct ipa_msg_meta *meta, ipa_msg_pull_fn callback)
+{
+	struct ipa_pull_msg *msg;
+
+	if (meta == NULL || callback == NULL) {
+		IPAERR("invalid param meta=%p callback=%p\n", meta, callback);
+		return -EINVAL;
+	}
+
+	msg = kzalloc(sizeof(struct ipa_pull_msg), GFP_KERNEL);
+	if (msg == NULL) {
+		IPAERR("fail to alloc ipa_msg container\n");
+		return -ENOMEM;
+	}
+
+	msg->meta = *meta;
+	msg->callback = callback;
+
+	mutex_lock(&ipa_ctx->msg_lock);
+	list_add_tail(&msg->link, &ipa_ctx->pull_msg_list);
+	mutex_unlock(&ipa_ctx->msg_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL(ipa_register_pull_msg);
+
+/**
+ * ipa_deregister_pull_msg() - De-register pull message type
+ * @meta: [in] message meta-data
+ *
+ * De-register "message" by kernel client from IPA driver
+ *
+ * Returns:	0 on success, negative on failure
+ *
+ * Note:	Should not be called from atomic context
+ */
+int ipa_deregister_pull_msg(struct ipa_msg_meta *meta)
+{
+	struct ipa_pull_msg *entry;
+	struct ipa_pull_msg *next;
+	int result = -EINVAL;
+
+	if (meta == NULL) {
+		IPAERR("invalid param name=%p\n", meta);
+		return result;
+	}
+
+	mutex_lock(&ipa_ctx->msg_lock);
+	list_for_each_entry_safe(entry, next, &ipa_ctx->pull_msg_list, link) {
+		if (entry->meta.msg_len == meta->msg_len &&
+		    entry->meta.msg_type == meta->msg_type) {
+			list_del(&entry->link);
+			kfree(entry);
+			result = 0;
+			break;
+		}
+	}
+	mutex_unlock(&ipa_ctx->msg_lock);
+	return result;
+}
+EXPORT_SYMBOL(ipa_deregister_pull_msg);
+
+/**
+ * ipa_read() - read message from IPA device
+ * @filp:	[in] file pointer
+ * @buf:	[out] buffer to read into
+ * @count:	[in] size of above buffer
+ * @f_pos:	[inout] file position
+ *
+ * Uer-space should continually read from /dev/ipa, read wll block when there
+ * are no messages to read. Upon return, user-space should read the ipa_msg_meta
+ * from the start of the buffer to know what type of message was read and its
+ * length in the remainder of the buffer. Buffer supplied must be big enough to
+ * hold the message meta-data and the largest defined message type
+ *
+ * Returns:	how many bytes copied to buffer
+ *
+ * Note:	Should not be called from atomic context
+ */
+ssize_t ipa_read(struct file *filp, char __user *buf, size_t count,
+		  loff_t *f_pos)
+{
+	char __user *start;
+	struct ipa_push_msg *msg = NULL;
+	int ret;
+	DEFINE_WAIT(wait);
+	int locked;
+
+	start = buf;
+
+	while (1) {
+		prepare_to_wait(&ipa_ctx->msg_waitq, &wait, TASK_INTERRUPTIBLE);
+
+		mutex_lock(&ipa_ctx->msg_lock);
+		locked = 1;
+		if (!list_empty(&ipa_ctx->msg_list)) {
+			msg = list_first_entry(&ipa_ctx->msg_list,
+					struct ipa_push_msg, link);
+			list_del(&msg->link);
+		}
+
+		IPADBG("msg=%p\n", msg);
+
+		if (msg) {
+			locked = 0;
+			mutex_unlock(&ipa_ctx->msg_lock);
+			if (copy_to_user(buf, &msg->meta,
+					  sizeof(struct ipa_msg_meta))) {
+				ret = -EFAULT;
+				break;
+			}
+			buf += sizeof(struct ipa_msg_meta);
+			count -= sizeof(struct ipa_msg_meta);
+			if (msg->buff) {
+				if (copy_to_user(buf, msg->buff,
+						  msg->meta.msg_len)) {
+					ret = -EFAULT;
+					break;
+				}
+				buf += msg->meta.msg_len;
+				count -= msg->meta.msg_len;
+				msg->callback(msg->buff, msg->meta.msg_len,
+					       msg->meta.msg_type);
+			}
+		}
+
+		ret = -EAGAIN;
+		if (filp->f_flags & O_NONBLOCK)
+			break;
+
+		ret = -EINTR;
+		if (signal_pending(current))
+			break;
+
+		if (start != buf)
+			break;
+
+		locked = 0;
+		mutex_unlock(&ipa_ctx->msg_lock);
+		schedule();
+	}
+
+	finish_wait(&ipa_ctx->msg_waitq, &wait);
+	if (start != buf && ret != -EFAULT)
+		ret = buf - start;
+
+	if (locked)
+		mutex_unlock(&ipa_ctx->msg_lock);
+
+	return ret;
+}
+
+/**
+ * ipa_pull_msg() - pull the specified message from client
+ * @meta: [in] message meta-data
+ * @buf:  [out] buffer to read into
+ * @count: [in] size of above buffer
+ *
+ * Populate the supplied buffer with the pull message which is fetched
+ * from client, the message must have previously been registered with
+ * the IPA driver
+ *
+ * Returns:	how many bytes copied to buffer
+ *
+ * Note:	Should not be called from atomic context
+ */
+int ipa_pull_msg(struct ipa_msg_meta *meta, char *buff, size_t count)
+{
+	struct ipa_pull_msg *entry;
+	int result = -EINVAL;
+
+	if (meta == NULL || buff == NULL || !count) {
+		IPAERR("invalid param name=%p buff=%p count=%zu\n",
+				meta, buff, count);
+		return result;
+	}
+
+	mutex_lock(&ipa_ctx->msg_lock);
+	list_for_each_entry(entry, &ipa_ctx->pull_msg_list, link) {
+		if (entry->meta.msg_len == meta->msg_len &&
+		    entry->meta.msg_type == meta->msg_type) {
+			result = entry->callback(buff, count, meta->msg_type);
+			break;
+		}
+	}
+	mutex_unlock(&ipa_ctx->msg_lock);
+	return result;
+}
diff --git a/drivers/platform/msm/ipa/ipa_nat.c b/drivers/platform/msm/ipa/ipa_nat.c
index c13c53a..befa2cf 100644
--- a/drivers/platform/msm/ipa/ipa_nat.c
+++ b/drivers/platform/msm/ipa/ipa_nat.c
@@ -356,11 +356,11 @@
 
 		desc[cnt].len = sizeof(struct ipa_nat_dma);
 		desc[cnt].pyld = (void *)&cmd[cnt];
+
+		ret = ipa_send_cmd(1, &desc[cnt]);
+		if (ret == -EPERM)
+			IPAERR("Fail to send immediate command %d\n", cnt);
 	}
-	IPADBG("posting dma command with entries %d\n", dma->entries);
-	ret = ipa_send_cmd(dma->entries, desc);
-	if (ret == -EPERM)
-		IPAERR("Fail to send immediate command\n");
 
 bail:
 	kfree(cmd);
diff --git a/drivers/platform/msm/ipa/ipa_ram_mmap.h b/drivers/platform/msm/ipa/ipa_ram_mmap.h
index 000718b..7e12b6a 100644
--- a/drivers/platform/msm/ipa/ipa_ram_mmap.h
+++ b/drivers/platform/msm/ipa/ipa_ram_mmap.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
@@ -21,7 +21,7 @@
 #define IPA_RAM_NAT_OFST    0
 #define IPA_RAM_NAT_SIZE    2048
 #define IPA_RAM_HDR_OFST    2048
-#define IPA_RAM_HDR_SIZE    256
+#define IPA_RAM_HDR_SIZE    440
 #define IPA_RAM_V4_FLT_OFST (IPA_RAM_HDR_OFST + IPA_RAM_HDR_SIZE)
 #define IPA_RAM_V4_FLT_SIZE 1024
 #define IPA_RAM_V4_RT_OFST  (IPA_RAM_V4_FLT_OFST + IPA_RAM_V4_FLT_SIZE)
diff --git a/drivers/platform/msm/ipa/ipa_reg.h b/drivers/platform/msm/ipa/ipa_reg.h
index 61913b6..4a2acac 100644
--- a/drivers/platform/msm/ipa/ipa_reg.h
+++ b/drivers/platform/msm/ipa/ipa_reg.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
@@ -15,171 +15,102 @@
 
 /*
  * IPA's BAM specific registers
+ * Used for IPA HW 1.0 only
  */
 
 #define IPA_BAM_REG_BASE_OFST 0x00004000
-
 #define IPA_BAM_CNFG_BITS_OFST 0x7c
 #define IPA_BAM_REMAP_SIZE (0x1000)
 
-/*
- * IPA's core specific regtisters
- */
+#define IPA_FILTER_FILTER_EN_BMSK 0x1
+#define IPA_FILTER_FILTER_EN_SHFT 0x0
+#define IPA_AGGREGATION_SPARE_REG_2_OFST 0x00002094
+#define IPA_AGGREGATION_QCNCM_SIG0_SHFT 16
+#define IPA_AGGREGATION_QCNCM_SIG1_SHFT 8
 
-#define IPA_REG_BASE_OFST 0x00020000
+#define IPA_AGGREGATION_SPARE_REG_1_OFST 0x00002090
+#define IPA_AGGREGATION_SPARE_REG_2_OFST 0x00002094
 
-#define IPA_COMP_HW_VERSION_OFST 0x00000030
-#define IPA_COMP_HW_VERSION_RMSK 0xffffffff
-#define IPA_COMP_HW_VERSION_MAJOR_BMSK 0xff000000
-#define IPA_COMP_HW_VERSION_MAJOR_SHFT 0x18
-#define IPA_COMP_HW_VERSION_MINOR_BMSK 0xff0000
-#define IPA_COMP_HW_VERSION_MINOR_SHFT 0x10
-#define IPA_COMP_HW_VERSION_STEP_BMSK 0xffff
-#define IPA_COMP_HW_VERSION_STEP_SHFT 0x0
+#define IPA_AGGREGATION_SINGLE_NDP_MSK 0x1
+#define IPA_AGGREGATION_SINGLE_NDP_BMSK 0xfffffffe
 
-#define IPA_VERSION_OFST 0x00000034
-#define IPA_VERSION_RMSK 0xffffffff
-#define IPA_VERSION_IPA_R_REV_BMSK 0xff000000
-#define IPA_VERSION_IPA_R_REV_SHFT 0x18
-#define IPA_VERSION_IPA_Q_REV_BMSK 0xff0000
-#define IPA_VERSION_IPA_Q_REV_SHFT 0x10
-#define IPA_VERSION_IPA_P_REV_BMSK 0xff00
-#define IPA_VERSION_IPA_P_REV_SHFT 0x8
-#define IPA_VERSION_IPA_ECO_REV_BMSK 0xff
-#define IPA_VERSION_IPA_ECO_REV_SHFT 0x0
+#define IPA_AGGREGATION_MODE_MSK 0x1
+#define IPA_AGGREGATION_MODE_SHFT 31
+#define IPA_AGGREGATION_MODE_BMSK 0x7fffffff
 
-#define IPA_COMP_CFG_OFST 0x00000038
-#define IPA_COMP_CFG_RMSK 0x1
-#define IPA_COMP_CFG_ENABLE_BMSK 0x1
-#define IPA_COMP_CFG_ENABLE_SHFT 0x0
+#define IPA_AGGREGATION_QCNCM_SIG_BMSK 0xff000000
 
-#define IPA_COMP_SW_RESET_OFST 0x0000003c
-#define IPA_COMP_SW_RESET_RMSK 0x1
-#define IPA_COMP_SW_RESET_SW_RESET_BMSK 0x1
-#define IPA_COMP_SW_RESET_SW_RESET_SHFT 0x0
-
-#define IPA_CLKON_CFG_OFST 0x00000040
-#define IPA_CLKON_CFG_RMSK 0xf
-#define IPA_CLKON_CFG_CGC_OPEN_MISC_BMSK 0x8
-#define IPA_CLKON_CFG_CGC_OPEN_MISC_SHFT 0x3
-#define IPA_CLKON_CFG_CGC_OPEN_TX_BMSK 0x4
-#define IPA_CLKON_CFG_CGC_OPEN_TX_SHFT 0x2
-#define IPA_CLKON_CFG_CGC_OPEN_PROC_BMSK 0x2
-#define IPA_CLKON_CFG_CGC_OPEN_PROC_SHFT 0x1
-#define IPA_CLKON_CFG_CGC_OPEN_RX_BMSK 0x1
-#define IPA_CLKON_CFG_CGC_OPEN_RX_SHFT 0x0
-
-#define IPA_HEAD_OF_LINE_BLOCK_EN_OFST 0x00000044
-#define IPA_HEAD_OF_LINE_BLOCK_EN_RMSK 0x1
-#define IPA_HEAD_OF_LINE_BLOCK_EN_EN_BMSK 0x1
-#define IPA_HEAD_OF_LINE_BLOCK_EN_EN_SHFT 0x0
-
-#define IPA_HEAD_OF_LINE_BLOCK_TIMER_OFST 0x00000048
-#define IPA_HEAD_OF_LINE_BLOCK_TIMER_RMSK 0x1ff
-#define IPA_HEAD_OF_LINE_BLOCK_TIMER_TIMER_BMSK 0x1ff
-#define IPA_HEAD_OF_LINE_BLOCK_TIMER_TIMER_SHFT 0x0
-
-#define IPA_ROUTE_OFST 0x0000004c
-#define IPA_ROUTE_RMSK 0x1ffff
-#define IPA_ROUTE_ROUTE_DEF_HDR_OFST_BMSK 0x1ff80
-#define IPA_ROUTE_ROUTE_DEF_HDR_OFST_SHFT 0x7
-#define IPA_ROUTE_ROUTE_DEF_HDR_TABLE_BMSK 0x40
-#define IPA_ROUTE_ROUTE_DEF_HDR_TABLE_SHFT 0x6
-#define IPA_ROUTE_ROUTE_DEF_PIPE_BMSK 0x3e
-#define IPA_ROUTE_ROUTE_DEF_PIPE_SHFT 0x1
-#define IPA_ROUTE_ROUTE_DIS_BMSK 0x1
-#define IPA_ROUTE_ROUTE_DIS_SHFT 0x0
-
-#define IPA_FILTER_OFST 0x00000050
-#define IPA_FILTER_RMSK 0x1
 #define IPA_FILTER_FILTER_EN_BMSK 0x1
 #define IPA_FILTER_FILTER_EN_SHFT 0x0
 
-#define IPA_MASTER_PRIORITY_OFST 0x00000054
-#define IPA_MASTER_PRIORITY_RMSK 0xffffffff
-#define IPA_MASTER_PRIORITY_MASTER_7_WR_BMSK 0xc0000000
-#define IPA_MASTER_PRIORITY_MASTER_7_WR_SHFT 0x1e
-#define IPA_MASTER_PRIORITY_MASTER_7_RD_BMSK 0x30000000
-#define IPA_MASTER_PRIORITY_MASTER_7_RD_SHFT 0x1c
-#define IPA_MASTER_PRIORITY_MASTER_6_WR_BMSK 0xc000000
-#define IPA_MASTER_PRIORITY_MASTER_6_WR_SHFT 0x1a
-#define IPA_MASTER_PRIORITY_MASTER_6_RD_BMSK 0x3000000
-#define IPA_MASTER_PRIORITY_MASTER_6_RD_SHFT 0x18
-#define IPA_MASTER_PRIORITY_MASTER_5_WR_BMSK 0xc00000
-#define IPA_MASTER_PRIORITY_MASTER_5_WR_SHFT 0x16
-#define IPA_MASTER_PRIORITY_MASTER_5_RD_BMSK 0x300000
-#define IPA_MASTER_PRIORITY_MASTER_5_RD_SHFT 0x14
-#define IPA_MASTER_PRIORITY_MASTER_4_WR_BMSK 0xc0000
-#define IPA_MASTER_PRIORITY_MASTER_4_WR_SHFT 0x12
-#define IPA_MASTER_PRIORITY_MASTER_4_RD_BMSK 0x30000
-#define IPA_MASTER_PRIORITY_MASTER_4_RD_SHFT 0x10
-#define IPA_MASTER_PRIORITY_MASTER_3_WR_BMSK 0xc000
-#define IPA_MASTER_PRIORITY_MASTER_3_WR_SHFT 0xe
-#define IPA_MASTER_PRIORITY_MASTER_3_RD_BMSK 0x3000
-#define IPA_MASTER_PRIORITY_MASTER_3_RD_SHFT 0xc
-#define IPA_MASTER_PRIORITY_MASTER_2_WR_BMSK 0xc00
-#define IPA_MASTER_PRIORITY_MASTER_2_WR_SHFT 0xa
-#define IPA_MASTER_PRIORITY_MASTER_2_RD_BMSK 0x300
-#define IPA_MASTER_PRIORITY_MASTER_2_RD_SHFT 0x8
-#define IPA_MASTER_PRIORITY_MASTER_1_WR_BMSK 0xc0
-#define IPA_MASTER_PRIORITY_MASTER_1_WR_SHFT 0x6
-#define IPA_MASTER_PRIORITY_MASTER_1_RD_BMSK 0x30
-#define IPA_MASTER_PRIORITY_MASTER_1_RD_SHFT 0x4
-#define IPA_MASTER_PRIORITY_MASTER_0_WR_BMSK 0xc
-#define IPA_MASTER_PRIORITY_MASTER_0_WR_SHFT 0x2
-#define IPA_MASTER_PRIORITY_MASTER_0_RD_BMSK 0x3
-#define IPA_MASTER_PRIORITY_MASTER_0_RD_SHFT 0x0
+#define IPA_AGGREGATION_HW_TIMER_FIX_MBIM_AGGR_SHFT 2
+#define IPA_AGGREGATION_HW_TIMER_FIX_MBIM_AGGR_BMSK 0x4
 
-#define IPA_SHARED_MEM_SIZE_OFST 0x00000058
-#define IPA_SHARED_MEM_SIZE_RMSK 0x1fff
-#define IPA_SHARED_MEM_SIZE_SHARED_MEM_SIZE_BMSK 0x1fff
-#define IPA_SHARED_MEM_SIZE_SHARED_MEM_SIZE_SHFT 0x0
+#define IPA_HEAD_OF_LINE_BLOCK_EN_OFST 0x00000044
 
-#define IPA_NAT_TIMER_OFST 0x0000005c
-#define IPA_NAT_TIMER_RMSK 0xffffff
-#define IPA_NAT_TIMER_NAT_TIMER_BMSK 0xffffff
-#define IPA_NAT_TIMER_NAT_TIMER_SHFT 0x0
+/*
+ * End of IPA 1.0 Registers
+ */
 
-#define IPA_NAT_TIMER_RESET_OFST 0x00000060
-#define IPA_NAT_TIMER_RESET_RMSK 0x1
-#define IPA_NAT_TIMER_RESET_NAT_TIMER_RESET_BMSK 0x1
-#define IPA_NAT_TIMER_RESET_NAT_TIMER_RESET_SHFT 0x0
 
-#define IPA_ENDP_INIT_NAT_n_OFST(n) (0x00000080 + 0x4 * (n))
-#define IPA_ENDP_INIT_NAT_n_RMSK 0x3
-#define IPA_ENDP_INIT_NAT_n_MAXn 19
-#define IPA_ENDP_INIT_NAT_n_NAT_EN_BMSK 0x3
+/*
+Common Registers
+*/
+#define IPA_REG_BASE_OFST 0x00020000
+#define IPA_COMP_SW_RESET_OFST 0x0000003c
+
+#define IPA_SHARED_MEM_SIZE_OFST_v1 0x00000058
+#define IPA_SHARED_MEM_SIZE_OFST_v2 0x00000050
+
+#define IPA_VERSION_OFST 0x00000034
+#define IPA_COMP_HW_VERSION_OFST 0x00000030
+
+#define IPA_ROUTE_OFST_v1 0x0000004c
+#define IPA_ROUTE_OFST_v2 0x00000044
+
+#define IPA_FILTER_OFST_v1 0x00000050
+#define IPA_FILTER_OFST_v2 0x00000048
+
+#define IPA_SHARED_MEM_SIZE_OFST_v1 0x00000058
+#define IPA_SHARED_MEM_SIZE_OFST_v2 0x00000050
+
+#define IPA_ENDP_INIT_NAT_n_OFST_v1(n) (0x00000080 + 0x4 * (n))
+#define IPA_ENDP_INIT_NAT_n_OFST_v2(n) (0x000000c0 + 0x4 * (n))
+
+#define IPA_ENDP_INIT_HDR_n_OFST_v1(n) (0x000000e0 + 0x4 * (n))
+#define IPA_ENDP_INIT_HDR_n_OFST_v2(n) (0x00000120 + 0x4 * (n))
+
+#define IPA_ENDP_INIT_MODE_n_OFST_v1(n) (0x00000140 + 0x4 * (n))
+#define IPA_ENDP_INIT_MODE_n_OFST_v2(n) (0x00000170 + 0x4 * (n))
+
+#define IPA_ENDP_INIT_AGGR_n_OFST_v1(n) (0x000001a0 + 0x4 * (n))
+#define IPA_ENDP_INIT_AGGR_n_OFST_v2(n) (0x000001c0 + 0x4 * (n))
+
+#define IPA_ENDP_INIT_ROUTE_n_OFST_v1(n) (0x00000200 + 0x4 * (n))
+#define IPA_ENDP_INIT_ROUTE_n_OFST_v2(n) (0x00000220 + 0x4 * (n))
+#define IPA_ENDP_INIT_ROUTE_n_ROUTE_TABLE_INDEX_BMSK 0x1f
+#define IPA_ENDP_INIT_ROUTE_n_ROUTE_TABLE_INDEX_SHFT 0x0
+
+#define IPA_ROUTE_OFST_v1 0x0000004c
+#define IPA_ROUTE_OFST_v2 0x00000044
+
+#define IPA_ROUTE_ROUTE_DIS_SHFT 0x0
+#define IPA_ROUTE_ROUTE_DIS_BMSK 0x1
+#define IPA_ROUTE_ROUTE_DEF_PIPE_SHFT 0x1
+#define IPA_ROUTE_ROUTE_DEF_PIPE_BMSK 0x3e
+#define IPA_ROUTE_ROUTE_DEF_HDR_TABLE_SHFT 0x6
+#define IPA_ROUTE_ROUTE_DEF_HDR_OFST_SHFT 0x7
+#define IPA_ROUTE_ROUTE_DEF_HDR_OFST_BMSK 0x1ff80
+
+
+#define IPA_FILTER_OFST_v1 0x00000050
+#define IPA_FILTER_OFST_v2 0x00000048
+
+#define IPA_SRAM_DIRECT_ACCESS_n_OFST(n) (0x00004000 + 0x4 * (n))
+#define IPA_ROUTE_ROUTE_DEF_HDR_TABLE_BMSK 0x40
 #define IPA_ENDP_INIT_NAT_n_NAT_EN_SHFT 0x0
+#define IPA_COMP_CFG_OFST 0x00000038
 
-#define IPA_ENDP_INIT_HDR_n_OFST(n) (0x000000e0 + 0x4 * (n))
-#define IPA_ENDP_INIT_HDR_n_RMSK 0x7ffffff
-#define IPA_ENDP_INIT_HDR_n_MAXn 19
-#define IPA_ENDP_INIT_HDR_n_HDR_A5_MUX_BMSK 0x4000000
-#define IPA_ENDP_INIT_HDR_n_HDR_A5_MUX_SHFT 0x1a
-#define IPA_ENDP_INIT_HDR_n_HDR_OFST_PKT_SIZE_BMSK 0x3f00000
-#define IPA_ENDP_INIT_HDR_n_HDR_OFST_PKT_SIZE_SHFT 0x14
-#define IPA_ENDP_INIT_HDR_n_HDR_OFST_PKT_SIZE_VALID_BMSK 0x80000
-#define IPA_ENDP_INIT_HDR_n_HDR_OFST_PKT_SIZE_VALID_SHFT 0x13
-#define IPA_ENDP_INIT_HDR_n_HDR_ADDITIONAL_CONST_LEN_BMSK 0x7e000
-#define IPA_ENDP_INIT_HDR_n_HDR_ADDITIONAL_CONST_LEN_SHFT 0xd
-#define IPA_ENDP_INIT_HDR_n_HDR_OFST_METADATA_BMSK 0x1f80
-#define IPA_ENDP_INIT_HDR_n_HDR_OFST_METADATA_SHFT 0x7
-#define IPA_ENDP_INIT_HDR_n_HDR_OFST_METADATA_VALID_BMSK 0x40
-#define IPA_ENDP_INIT_HDR_n_HDR_OFST_METADATA_VALID_SHFT 0x6
-#define IPA_ENDP_INIT_HDR_n_HDR_LEN_BMSK 0x3f
-#define IPA_ENDP_INIT_HDR_n_HDR_LEN_SHFT 0x0
-
-#define IPA_ENDP_INIT_MODE_n_OFST(n) (0x00000140 + 0x4 * (n))
-#define IPA_ENDP_INIT_MODE_n_RMSK 0x7f
-#define IPA_ENDP_INIT_MODE_n_MAXn 19
-#define IPA_ENDP_INIT_MODE_n_DEST_PIPE_INDEX_BMSK 0x7c
-#define IPA_ENDP_INIT_MODE_n_DEST_PIPE_INDEX_SHFT 0x2
-#define IPA_ENDP_INIT_MODE_n_MODE_BMSK 0x3
-#define IPA_ENDP_INIT_MODE_n_MODE_SHFT 0x0
-
-#define IPA_ENDP_INIT_AGGR_n_OFST(n) (0x000001a0 + 0x4 * (n))
-#define IPA_ENDP_INIT_AGGR_n_RMSK 0x7fff
-#define IPA_ENDP_INIT_AGGR_n_MAXn 19
 #define IPA_ENDP_INIT_AGGR_n_AGGR_TIME_LIMIT_BMSK 0x7c00
 #define IPA_ENDP_INIT_AGGR_n_AGGR_TIME_LIMIT_SHFT 0xa
 #define IPA_ENDP_INIT_AGGR_n_AGGR_BYTE_LIMIT_BMSK 0x3e0
@@ -189,35 +120,57 @@
 #define IPA_ENDP_INIT_AGGR_n_AGGR_EN_BMSK 0x3
 #define IPA_ENDP_INIT_AGGR_n_AGGR_EN_SHFT 0x0
 
-#define IPA_ENDP_INIT_ROUTE_n_OFST(n) (0x00000200 + 0x4 * (n))
-#define IPA_ENDP_INIT_ROUTE_n_RMSK 0x1f
-#define IPA_ENDP_INIT_ROUTE_n_MAXn 19
-#define IPA_ENDP_INIT_ROUTE_n_ROUTE_TABLE_INDEX_BMSK 0x1f
-#define IPA_ENDP_INIT_ROUTE_n_ROUTE_TABLE_INDEX_SHFT 0x0
+#define IPA_ENDP_INIT_MODE_n_OFST_v1(n) (0x00000140 + 0x4 * (n))
+#define IPA_ENDP_INIT_MODE_n_OFST_v2(n) (0x00000170 + 0x4 * (n))
+#define IPA_ENDP_INIT_MODE_n_RMSK 0x7f
+#define IPA_ENDP_INIT_MODE_n_MAXn 19
+#define IPA_ENDP_INIT_MODE_n_DEST_PIPE_INDEX_BMSK 0x7c
+#define IPA_ENDP_INIT_MODE_n_DEST_PIPE_INDEX_SHFT 0x2
+#define IPA_ENDP_INIT_MODE_n_MODE_BMSK 0x3
+#define IPA_ENDP_INIT_MODE_n_MODE_SHFT 0x0
 
-#define IPA_AGGREGATION_SPARE_REG_1_OFST 0x00002090
-#define IPA_AGGREGATION_SPARE_REG_1_RMSK 0xffffffff
-#define IPA_AGGREGATION_SPARE_REG_1_GENERAL_CONFIG_BMSK 0xffffffff
-#define IPA_AGGREGATION_SPARE_REG_1_GENERAL_CONFIG_SHFT 0x0
+#define IPA_ENDP_INIT_HDR_n_OFST_v1(n) (0x000000e0 + 0x4 * (n))
+#define IPA_ENDP_INIT_HDR_n_OFST_v2(n) (0x00000120 + 0x4 * (n))
+#define IPA_ENDP_INIT_HDR_n_HDR_LEN_BMSK 0x3f
+#define IPA_ENDP_INIT_HDR_n_HDR_LEN_SHFT 0x0
+#define IPA_ENDP_INIT_HDR_n_HDR_ADDITIONAL_CONST_LEN_BMSK 0x7e000
+#define IPA_ENDP_INIT_HDR_n_HDR_ADDITIONAL_CONST_LEN_SHFT 0xd
+#define IPA_ENDP_INIT_HDR_n_HDR_OFST_PKT_SIZE_BMSK 0x3f00000
+#define IPA_ENDP_INIT_HDR_n_HDR_OFST_PKT_SIZE_SHFT 0x14
+#define IPA_ENDP_INIT_HDR_n_HDR_OFST_PKT_SIZE_VALID_BMSK 0x80000
+#define IPA_ENDP_INIT_HDR_n_HDR_OFST_PKT_SIZE_VALID_SHFT 0x13
+#define IPA_ENDP_INIT_HDR_n_HDR_A5_MUX_BMSK 0x4000000
+#define IPA_ENDP_INIT_HDR_n_HDR_A5_MUX_SHFT 0x1a
 
-#define IPA_AGGREGATION_SPARE_REG_2_OFST 0x00002094
-#define IPA_AGGREGATION_SPARE_REG_2_RMSK 0xffffffff
-#define IPA_AGGREGATION_SPARE_REG_2_GENERAL_CONFIG_BMSK 0xffffffff
-#define IPA_AGGREGATION_SPARE_REG_2_GENERAL_CONFIG_SHFT 0x0
+#define IPA_ENDP_INIT_HDR_n_HDR_OFST_METADATA_VALID_BMSK 0x40
+#define IPA_ENDP_INIT_HDR_n_HDR_OFST_METADATA_VALID_SHFT 0x6
+#define IPA_ENDP_INIT_HDR_n_HDR_OFST_METADATA_BMSK 0x1f80
+#define IPA_ENDP_INIT_HDR_n_HDR_OFST_METADATA_SHFT 0x7
 
-#define IPA_AGGREGATION_MODE_MSK 0x1
-#define IPA_AGGREGATION_MODE_SHFT 31
-#define IPA_AGGREGATION_MODE_BMSK 0x7fffffff
-#define IPA_AGGREGATION_QCNCM_SIG0_SHFT 16
-#define IPA_AGGREGATION_QCNCM_SIG1_SHFT 8
-#define IPA_AGGREGATION_QCNCM_SIG_BMSK 0xff000000
-#define IPA_AGGREGATION_SINGLE_NDP_MSK 0x1
-#define IPA_AGGREGATION_SINGLE_NDP_BMSK 0xfffffffe
+#define IPA_ENDP_INIT_NAT_n_OFST_v1(n) (0x00000080 + 0x4 * (n))
+#define IPA_ENDP_INIT_NAT_n_OFST_v2(n) (0x000000c0 + 0x4 * (n))
+#define IPA_ENDP_INIT_NAT_n_NAT_EN_BMSK 0x3
+#define IPA_ENDP_INIT_NAT_n_NAT_EN_SHFT 0x0
 
-#define IPA_SRAM_DIRECT_ACCESS_n_OFST(n) (0x00004000 + 0x4 * (n))
-#define IPA_SRAM_DIRECT_ACCESS_n_RMSK 0xffffffff
-#define IPA_SRAM_DIRECT_ACCESS_n_MAXn 2047
-#define IPA_SRAM_DIRECT_ACCESS_n_DATA_WORD_BMSK 0xffffffff
-#define IPA_SRAM_DIRECT_ACCESS_n_DATA_WORD_SHFT 0x0
 
-#endif /* __IPA_REG_H__ */
+
+/*
+ IPA HW 1.1 specific Registers
+*/
+
+#define IPA_FILTER_FILTER_DIS_BMSK 0x1
+#define IPA_FILTER_FILTER_DIS_SHFT 0x0
+#define IPA_SINGLE_NDP_MODE_OFST 0x00000064
+#define IPA_QCNCM_OFST 0x00000060
+
+#define IPA_SPARE_REG_1_OFST 0x00002090
+
+#define IPA_ENDP_INIT_CTRL_n_OFST(n) (0x00000070 + 0x4 * (n))
+#define IPA_ENDP_INIT_CTRL_n_RMSK 0x1
+#define IPA_ENDP_INIT_CTRL_n_MAXn 19
+#define IPA_ENDP_INIT_CTRL_n_ENDP_SUSPEND_BMSK 0x1
+#define IPA_ENDP_INIT_CTRL_n_ENDP_SUSPEND_SHFT 0x0
+
+#endif
+
+
diff --git a/drivers/platform/msm/ipa/ipa_rm.c b/drivers/platform/msm/ipa/ipa_rm.c
new file mode 100644
index 0000000..99b19cc
--- /dev/null
+++ b/drivers/platform/msm/ipa/ipa_rm.c
@@ -0,0 +1,374 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <mach/ipa.h>
+#include "ipa_i.h"
+#include "ipa_rm_dependency_graph.h"
+#include "ipa_rm_i.h"
+#include "ipa_rm_resource.h"
+
+struct ipa_rm_context_type {
+	struct ipa_rm_dep_graph *dep_graph;
+	struct workqueue_struct *ipa_rm_wq;
+};
+static struct ipa_rm_context_type *ipa_rm_ctx;
+
+/**
+ * ipa_rm_create_resource() - create resource
+ * @create_params: [in] parameters needed
+ *                  for resource initialization
+ *
+ * Returns: 0 on success, negative on failure
+ *
+ * This function is called by IPA RM client to initialize client's resources.
+ * This API should be called before any other IPA RM API
+ * on given resource name.
+ *
+ */
+int ipa_rm_create_resource(struct ipa_rm_create_params *create_params)
+{
+	struct ipa_rm_resource *resource;
+	int result;
+
+	if (!create_params) {
+		result = -EINVAL;
+		goto bail;
+	}
+	if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph,
+					  create_params->name,
+					  &resource) == 0) {
+		result = -EPERM;
+		goto bail;
+	}
+	result = ipa_rm_resource_create(create_params,
+			&resource);
+	if (result)
+		goto bail;
+	result = ipa_rm_dep_graph_add(ipa_rm_ctx->dep_graph, resource);
+	if (result)
+		ipa_rm_resource_delete(resource);
+bail:
+	return result;
+}
+EXPORT_SYMBOL(ipa_rm_create_resource);
+
+/**
+ * ipa_rm_add_dependency() - create dependency
+ *					between 2 resources
+ * @resource_name: name of dependent resource
+ * @depends_on_name: name of its dependency
+ *
+ * Returns: 0 on success, negative on failure
+ *
+ * Side effects: IPA_RM_RESORCE_GRANTED could be generated
+ * in case client registered with IPA RM
+ */
+int ipa_rm_add_dependency(enum ipa_rm_resource_name resource_name,
+			enum ipa_rm_resource_name depends_on_name)
+{
+	return ipa_rm_dep_graph_add_dependency(
+			ipa_rm_ctx->dep_graph,
+			resource_name,
+			depends_on_name);
+}
+EXPORT_SYMBOL(ipa_rm_add_dependency);
+
+/**
+ * ipa_rm_delete_dependency() - create dependency
+ *					between 2 resources
+ * @resource_name: name of dependent resource
+ * @depends_on_name: name of its dependency
+ *
+ * Returns: 0 on success, negative on failure
+ *
+ * Side effects: IPA_RM_RESORCE_GRANTED could be generated
+ * in case client registered with IPA RM
+ */
+int ipa_rm_delete_dependency(enum ipa_rm_resource_name resource_name,
+			enum ipa_rm_resource_name depends_on_name)
+{
+	return ipa_rm_dep_graph_delete_dependency(
+			ipa_rm_ctx->dep_graph,
+			resource_name,
+			depends_on_name);
+}
+EXPORT_SYMBOL(ipa_rm_delete_dependency);
+
+/**
+ * ipa_rm_request_resource() - request resource
+ * @resource_name: [in] name of the requested resource
+ *
+ * Returns: 0 on success, negative on failure
+ *
+ * All registered callbacks are called with IPA_RM_RESOURCE_GRANTED
+ * on successful completion of this operation.
+ */
+int ipa_rm_request_resource(enum ipa_rm_resource_name resource_name)
+{
+	struct ipa_rm_resource *resource;
+	int result;
+	IPADBG("IPA RM ::ipa_rm_request_resource ENTER\n");
+
+	if (!IPA_RM_RESORCE_IS_PROD(resource_name)) {
+			result = -EINVAL;
+			goto bail;
+	}
+	if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph,
+			resource_name,
+			&resource) != 0) {
+		result = -EPERM;
+		goto bail;
+	}
+	result = ipa_rm_resource_producer_request(
+			(struct ipa_rm_resource_prod *)resource);
+
+bail:
+	IPADBG("IPA RM ::ipa_rm_request_resource EXIT [%d]\n", result);
+
+	return result;
+}
+EXPORT_SYMBOL(ipa_rm_request_resource);
+
+/**
+ * ipa_rm_release_resource() - release resource
+ * @resource_name: [in] name of the requested resource
+ *
+ * Returns: 0 on success, negative on failure
+ *
+ * All registered callbacks are called with IPA_RM_RESOURCE_RELEASED
+ * on successful completion of this operation.
+ */
+int ipa_rm_release_resource(enum ipa_rm_resource_name resource_name)
+{
+	struct ipa_rm_resource *resource;
+	int result;
+	IPADBG("IPA RM ::ipa_rm_release_resource ENTER\n");
+
+	if (!IPA_RM_RESORCE_IS_PROD(resource_name)) {
+		result = -EINVAL;
+		goto bail;
+	}
+	if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph,
+					  resource_name,
+					  &resource) != 0) {
+		result = -EPERM;
+		goto bail;
+	}
+	result = ipa_rm_resource_producer_release(
+		    (struct ipa_rm_resource_prod *)resource);
+
+bail:
+	IPADBG("IPA RM ::ipa_rm_release_resource EXIT [%d]\n", result);
+	return result;
+}
+EXPORT_SYMBOL(ipa_rm_release_resource);
+
+/**
+ * ipa_rm_register() - register for event
+ * @resource_name: resource name
+ * @reg_params: [in] registration parameters
+ *
+ * Returns: 0 on success, negative on failure
+ *
+ * Registration parameters provided here should be the same
+ * as provided later in  ipa_rm_deregister() call.
+ */
+int ipa_rm_register(enum ipa_rm_resource_name resource_name,
+			struct ipa_rm_register_params *reg_params)
+{
+	int result;
+	struct ipa_rm_resource *resource;
+	if (!IPA_RM_RESORCE_IS_PROD(resource_name)) {
+		result = -EINVAL;
+		goto bail;
+	}
+	if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph,
+				resource_name,
+				&resource) != 0) {
+		result = -EPERM;
+		goto bail;
+	}
+	result = ipa_rm_resource_producer_register(
+			(struct ipa_rm_resource_prod *)resource,
+			reg_params);
+bail:
+	return result;
+}
+EXPORT_SYMBOL(ipa_rm_register);
+
+/**
+ * ipa_rm_deregister() - cancel the registration
+ * @resource_name: resource name
+ * @reg_params: [in] registration parameters
+ *
+ * Returns: 0 on success, negative on failure
+ *
+ * Registration parameters provided here should be the same
+ * as provided in  ipa_rm_register() call.
+ */
+int ipa_rm_deregister(enum ipa_rm_resource_name resource_name,
+			struct ipa_rm_register_params *reg_params)
+{
+	int result;
+	struct ipa_rm_resource *resource;
+	if (!IPA_RM_RESORCE_IS_PROD(resource_name)) {
+		result = -EINVAL;
+		goto bail;
+	}
+	if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph,
+			resource_name,
+			&resource) != 0) {
+		result = -EPERM;
+		goto bail;
+	}
+	result = ipa_rm_resource_producer_deregister(
+			(struct ipa_rm_resource_prod *)resource,
+			reg_params);
+bail:
+	return result;
+}
+EXPORT_SYMBOL(ipa_rm_deregister);
+
+/**
+ * ipa_rm_notify_completion() -
+ *	consumer driver notification for
+ *	request_resource / release_resource operations
+ *	completion
+ * @event: notified event
+ * @resource_name: resource name
+ *
+ * Returns: 0 on success, negative on failure
+ */
+int ipa_rm_notify_completion(enum ipa_rm_event event,
+		enum ipa_rm_resource_name resource_name)
+{
+	int result;
+	if (!IPA_RM_RESORCE_IS_CONS(resource_name)) {
+		result = -EINVAL;
+		goto bail;
+	}
+	ipa_rm_wq_send_cmd(IPA_RM_WQ_RESOURCE_CB,
+			resource_name,
+			event);
+	result = 0;
+bail:
+	return result;
+}
+EXPORT_SYMBOL(ipa_rm_notify_completion);
+
+static void ipa_rm_wq_handler(struct work_struct *work)
+{
+	struct ipa_rm_resource *resource;
+	struct ipa_rm_wq_work_type *ipa_rm_work =
+			container_of(work,
+					struct ipa_rm_wq_work_type,
+					work);
+	switch (ipa_rm_work->wq_cmd) {
+	case IPA_RM_WQ_NOTIFY_PROD:
+		if (!IPA_RM_RESORCE_IS_PROD(ipa_rm_work->resource_name))
+			return;
+		if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph,
+						ipa_rm_work->resource_name,
+						&resource) != 0)
+			return;
+		ipa_rm_resource_producer_notify_clients(
+				(struct ipa_rm_resource_prod *)resource,
+				ipa_rm_work->event);
+
+		break;
+	case IPA_RM_WQ_NOTIFY_CONS:
+		break;
+	case IPA_RM_WQ_RESOURCE_CB:
+		if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph,
+						ipa_rm_work->resource_name,
+						&resource) != 0)
+			return;
+		ipa_rm_resource_consumer_handle_cb(
+				(struct ipa_rm_resource_cons *)resource,
+				ipa_rm_work->event);
+		break;
+	default:
+		break;
+	}
+
+	kfree((void *) work);
+}
+
+/**
+ * ipa_rm_wq_send_cmd() - send a command for deferred work
+ * @wq_cmd: command that should be executed
+ * @resource_name: resource on which command should be executed
+ *
+ * Returns: 0 on success, negative otherwise
+ */
+int ipa_rm_wq_send_cmd(enum ipa_rm_wq_cmd wq_cmd,
+		enum ipa_rm_resource_name resource_name,
+		enum ipa_rm_event event)
+{
+	int result = -ENOMEM;
+	struct ipa_rm_wq_work_type *work = kzalloc(sizeof(*work), GFP_KERNEL);
+	if (work) {
+		INIT_WORK((struct work_struct *)work, ipa_rm_wq_handler);
+		work->wq_cmd = wq_cmd;
+		work->resource_name = resource_name;
+		work->event = event;
+		result = queue_work(ipa_rm_ctx->ipa_rm_wq,
+				(struct work_struct *)work);
+	}
+	return result;
+}
+
+/**
+ * ipa_rm_initialize() - initialize IPA RM component
+ *
+ * Returns: 0 on success, negative otherwise
+ */
+int ipa_rm_initialize(void)
+{
+	int result;
+
+	ipa_rm_ctx = kzalloc(sizeof(*ipa_rm_ctx), GFP_KERNEL);
+	if (!ipa_rm_ctx) {
+		result = -ENOMEM;
+		goto bail;
+	}
+	ipa_rm_ctx->ipa_rm_wq = create_singlethread_workqueue("ipa_rm_wq");
+	if (!ipa_rm_ctx->ipa_rm_wq) {
+		result = -ENOMEM;
+		goto create_wq_fail;
+	}
+	result = ipa_rm_dep_graph_create(&(ipa_rm_ctx->dep_graph));
+	if (result)
+		goto graph_alloc_fail;
+	IPADBG("IPA RM ipa_rm_initialize SUCCESS\n");
+	return 0;
+
+graph_alloc_fail:
+	destroy_workqueue(ipa_rm_ctx->ipa_rm_wq);
+create_wq_fail:
+	kfree(ipa_rm_ctx);
+bail:
+	return result;
+}
+
+/**
+ * ipa_rm_exit() - free all IPA RM resources
+ */
+void ipa_rm_exit(void)
+{
+	ipa_rm_dep_graph_delete(ipa_rm_ctx->dep_graph);
+	destroy_workqueue(ipa_rm_ctx->ipa_rm_wq);
+	kfree(ipa_rm_ctx);
+	ipa_rm_ctx = NULL;
+}
diff --git a/drivers/platform/msm/ipa/ipa_rm_dependency_graph.c b/drivers/platform/msm/ipa/ipa_rm_dependency_graph.c
new file mode 100644
index 0000000..6afab42
--- /dev/null
+++ b/drivers/platform/msm/ipa/ipa_rm_dependency_graph.c
@@ -0,0 +1,208 @@
+/* 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/slab.h>
+#include "ipa_rm_dependency_graph.h"
+#include "ipa_rm_i.h"
+
+static int ipa_rm_dep_get_index(enum ipa_rm_resource_name resource_name)
+{
+	int resource_index = IPA_RM_INDEX_INVALID;
+	if (IPA_RM_RESORCE_IS_PROD(resource_name))
+		resource_index = ipa_rm_prod_index(resource_name);
+	else if (IPA_RM_RESORCE_IS_CONS(resource_name))
+		resource_index = ipa_rm_cons_index(resource_name);
+
+	return resource_index;
+}
+
+/**
+ * ipa_rm_dep_graph_create() - creates graph
+ * @dep_graph: [out] created dependency graph
+ *
+ * Returns: dependency graph on success, NULL on failure
+ */
+int  ipa_rm_dep_graph_create(struct ipa_rm_dep_graph **dep_graph)
+{
+	int result = 0;
+	*dep_graph = kzalloc(sizeof(**dep_graph), GFP_KERNEL);
+	if (!*dep_graph) {
+		result = -ENOMEM;
+		goto bail;
+	}
+	rwlock_init(&((*dep_graph)->lock));
+bail:
+	return result;
+}
+
+/**
+ * ipa_rm_dep_graph_delete() - destroyes the graph
+ * @graph: [in] dependency graph
+ *
+ * Frees all resources.
+ */
+void ipa_rm_dep_graph_delete(struct ipa_rm_dep_graph *graph)
+{
+	int resource_index;
+	if (!graph)
+		return;
+	write_lock(&graph->lock);
+	for (resource_index = 0;
+			resource_index < IPA_RM_RESOURCE_MAX;
+			resource_index++)
+		kfree(graph->resource_table[resource_index]);
+	write_unlock(&graph->lock);
+	memset(graph->resource_table, 0, sizeof(graph->resource_table));
+}
+
+/**
+ * ipa_rm_dep_graph_get_resource() - provides a resource by name
+ * @graph: [in] dependency graph
+ * @name: [in] name of the resource
+ * @resource: [out] resource in case of success
+ *
+ * Returns: 0 on success, negative on failure
+ */
+int ipa_rm_dep_graph_get_resource(
+				struct ipa_rm_dep_graph *graph,
+				enum ipa_rm_resource_name resource_name,
+				struct ipa_rm_resource **resource)
+{
+	int result;
+	int resource_index;
+	if (!graph) {
+		result = -EINVAL;
+		goto bail;
+	}
+	resource_index = ipa_rm_dep_get_index(resource_name);
+	if (resource_index == IPA_RM_INDEX_INVALID) {
+		result = -EINVAL;
+		goto bail;
+	}
+	read_lock(&graph->lock);
+	*resource = graph->resource_table[resource_index];
+	read_unlock(&graph->lock);
+	if (!*resource) {
+		result = -EINVAL;
+		goto bail;
+	}
+	result = 0;
+bail:
+	return result;
+}
+
+/**
+ * ipa_rm_dep_graph_add() - adds resource to graph
+ * @graph: [in] dependency graph
+ * @resource: [in] resource to add
+ *
+ * Returns: 0 on success, negative on failure
+ */
+int ipa_rm_dep_graph_add(struct ipa_rm_dep_graph *graph,
+			 struct ipa_rm_resource *resource)
+{
+	int result = 0;
+	int resource_index;
+	if (!graph || !resource) {
+		result = -EINVAL;
+		goto bail;
+	}
+	resource_index = ipa_rm_dep_get_index(resource->name);
+	if (resource_index == IPA_RM_INDEX_INVALID) {
+		result = -EINVAL;
+		goto bail;
+	}
+	write_lock(&graph->lock);
+	graph->resource_table[resource_index] = resource;
+	write_unlock(&graph->lock);
+bail:
+	return result;
+}
+
+/**
+ * ipa_rm_dep_graph_add_dependency() - adds dependency between
+ *				two nodes in graph
+ * @graph: [in] dependency graph
+ * @resource_name: [in] resource to add
+ * @depends_on_name: [in] resource to add
+ *
+ * Returns: 0 on success, negative on failure
+ */
+int ipa_rm_dep_graph_add_dependency(struct ipa_rm_dep_graph *graph,
+				    enum ipa_rm_resource_name resource_name,
+				    enum ipa_rm_resource_name depends_on_name)
+{
+	struct ipa_rm_resource *dependant = NULL;
+	struct ipa_rm_resource *dependency = NULL;
+	int result;
+	if (!graph ||
+		!IPA_RM_RESORCE_IS_PROD(resource_name) ||
+		!IPA_RM_RESORCE_IS_CONS(depends_on_name)) {
+		result = -EINVAL;
+		goto bail;
+	}
+	if (ipa_rm_dep_graph_get_resource(graph,
+					  resource_name,
+					  &dependant)) {
+		result = -EINVAL;
+		goto bail;
+	}
+	if (ipa_rm_dep_graph_get_resource(graph,
+					depends_on_name,
+					  &dependency)) {
+		result = -EINVAL;
+		goto bail;
+	}
+	result = ipa_rm_resource_add_dependency(dependant, dependency);
+bail:
+	return result;
+}
+
+/**
+ * ipa_rm_dep_graph_delete_dependency() - deleted dependency between
+ *				two nodes in graph
+ * @graph: [in] dependency graph
+ * @resource_name: [in] resource to delete
+ * @depends_on_name: [in] resource to delete
+ *
+ * Returns: 0 on success, negative on failure
+ *
+ */
+int ipa_rm_dep_graph_delete_dependency(struct ipa_rm_dep_graph *graph,
+				enum ipa_rm_resource_name resource_name,
+				enum ipa_rm_resource_name depends_on_name)
+{
+	struct ipa_rm_resource *dependant = NULL;
+	struct ipa_rm_resource *dependency = NULL;
+	int result;
+	if (!graph ||
+		!IPA_RM_RESORCE_IS_PROD(resource_name) ||
+		!IPA_RM_RESORCE_IS_CONS(depends_on_name)) {
+		result = -EINVAL;
+		goto bail;
+	}
+	if (ipa_rm_dep_graph_get_resource(graph,
+					  resource_name,
+					  &dependant)) {
+		result = -EINVAL;
+		goto bail;
+	}
+	if (ipa_rm_dep_graph_get_resource(graph,
+					  depends_on_name,
+					  &dependency)) {
+		result = -EINVAL;
+		goto bail;
+	}
+	result = ipa_rm_resource_delete_dependency(dependant, dependency);
+bail:
+	return result;
+}
diff --git a/drivers/platform/msm/ipa/ipa_rm_dependency_graph.h b/drivers/platform/msm/ipa/ipa_rm_dependency_graph.h
new file mode 100644
index 0000000..19d9461
--- /dev/null
+++ b/drivers/platform/msm/ipa/ipa_rm_dependency_graph.h
@@ -0,0 +1,45 @@
+/* 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 _IPA_RM_DEPENDENCY_GRAPH_H_
+#define _IPA_RM_DEPENDENCY_GRAPH_H_
+
+#include <linux/list.h>
+#include <mach/ipa.h>
+#include "ipa_rm_resource.h"
+
+struct ipa_rm_dep_graph {
+	struct ipa_rm_resource *resource_table[IPA_RM_RESOURCE_MAX];
+	rwlock_t lock;
+};
+
+int ipa_rm_dep_graph_get_resource(
+				struct ipa_rm_dep_graph *graph,
+				enum ipa_rm_resource_name name,
+				struct ipa_rm_resource **resource);
+
+int ipa_rm_dep_graph_create(struct ipa_rm_dep_graph **dep_graph);
+
+void ipa_rm_dep_graph_delete(struct ipa_rm_dep_graph *graph);
+
+int ipa_rm_dep_graph_add(struct ipa_rm_dep_graph *graph,
+			 struct ipa_rm_resource *resource);
+
+int ipa_rm_dep_graph_add_dependency(struct ipa_rm_dep_graph *graph,
+				enum ipa_rm_resource_name resource_name,
+				enum ipa_rm_resource_name depends_on_name);
+
+int ipa_rm_dep_graph_delete_dependency(struct ipa_rm_dep_graph *graph,
+				enum ipa_rm_resource_name resource_name,
+				enum ipa_rm_resource_name depends_on_name);
+
+#endif /* _IPA_RM_DEPENDENCY_GRAPH_H_ */
diff --git a/drivers/platform/msm/ipa/ipa_rm_i.h b/drivers/platform/msm/ipa/ipa_rm_i.h
new file mode 100644
index 0000000..141a442
--- /dev/null
+++ b/drivers/platform/msm/ipa/ipa_rm_i.h
@@ -0,0 +1,64 @@
+/* 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 _IPA_RM_I_H_
+#define _IPA_RM_I_H_
+
+#include <linux/workqueue.h>
+#include <mach/ipa.h>
+
+#define IPA_RM_RESOURCE_CONS_MAX \
+	(IPA_RM_RESOURCE_MAX - IPA_RM_RESOURCE_PROD_MAX)
+#define IPA_RM_RESORCE_IS_PROD(x) \
+	(x >= IPA_RM_RESOURCE_PROD && x < IPA_RM_RESOURCE_PROD_MAX)
+#define IPA_RM_RESORCE_IS_CONS(x) \
+	(x >= IPA_RM_RESOURCE_PROD_MAX && x < IPA_RM_RESOURCE_MAX)
+#define IPA_RM_INDEX_INVALID	(-1)
+
+int ipa_rm_prod_index(enum ipa_rm_resource_name resource_name);
+int ipa_rm_cons_index(enum ipa_rm_resource_name resource_name);
+
+/**
+ * enum ipa_rm_wq_cmd - workqueue commands
+ */
+enum ipa_rm_wq_cmd {
+	IPA_RM_WQ_NOTIFY_PROD,
+	IPA_RM_WQ_NOTIFY_CONS,
+	IPA_RM_WQ_RESOURCE_CB
+};
+
+/**
+ * struct ipa_rm_wq_work_type - IPA RM worqueue specific
+ *				work type
+ * @work: work struct
+ * @wq_cmd: command that should be processed in workqueue context
+ * @resource_name: name of the resource on which this work
+ *			should be done
+ * @dep_graph: data structure to search for resource if exists
+ * @event: event to notify
+ */
+struct ipa_rm_wq_work_type {
+	struct work_struct		work;
+	enum ipa_rm_wq_cmd		wq_cmd;
+	enum ipa_rm_resource_name	resource_name;
+	enum ipa_rm_event		event;
+};
+
+int ipa_rm_wq_send_cmd(enum ipa_rm_wq_cmd wq_cmd,
+		enum ipa_rm_resource_name resource_name,
+		enum ipa_rm_event event);
+
+int ipa_rm_initialize(void);
+
+void ipa_rm_exit(void);
+
+#endif /* _IPA_RM_I_H_ */
diff --git a/drivers/platform/msm/ipa/ipa_rm_inactivity_timer.c b/drivers/platform/msm/ipa/ipa_rm_inactivity_timer.c
new file mode 100644
index 0000000..2a3b8d3
--- /dev/null
+++ b/drivers/platform/msm/ipa/ipa_rm_inactivity_timer.c
@@ -0,0 +1,249 @@
+/* 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/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/timer.h>
+#include <linux/unistd.h>
+#include <linux/workqueue.h>
+#include <mach/ipa.h>
+#include "ipa_i.h"
+
+/**
+ * struct ipa_rm_it_private - IPA RM Inactivity Timer private
+ *	data
+ * @initied: indicates if instance was initialized
+ * @lock - spinlock for mutual exclusion
+ * @resource_name - resource name
+ * @work: delayed work object for running delayed releas
+ *	function
+ * @release_in_prog: boolean flag indicates if release resource
+ *			is scheduled for happen in the future.
+ * @jiffies: number of jiffies for timeout
+ *
+ * WWAN private - holds all relevant info about WWAN driver
+ */
+struct ipa_rm_it_private {
+	bool initied;
+	enum ipa_rm_resource_name resource_name;
+	spinlock_t lock;
+	struct delayed_work work;
+	bool release_in_prog;
+	unsigned long jiffies;
+};
+
+static struct ipa_rm_it_private ipa_rm_it_handles[IPA_RM_RESOURCE_MAX];
+
+/**
+ * ipa_rm_inactivity_timer_func() - called when timer expired in
+ * the context of the shared workqueue. Checks internally is
+ * release_in_prog flag is set and calls to
+ * ipa_rm_release_resource(). release_in_prog is cleared when
+ * calling to ipa_rm_inactivity_timer_request_resource(). In
+ * this situation this function shall not call to
+ * ipa_rm_release_resource() since the resource needs to remain
+ * up
+ *
+ * @work: work object provided by the work queue
+ *
+ * Return codes:
+ * None
+ */
+static void ipa_rm_inactivity_timer_func(struct work_struct *work)
+{
+
+	struct ipa_rm_it_private *me = container_of(to_delayed_work(work),
+						    struct ipa_rm_it_private,
+						    work);
+	unsigned long flags;
+
+	IPADBG("%s: timer expired for resource %d!\n", __func__,
+	    me->resource_name);
+
+	/* check that release still need to be performed */
+	spin_lock_irqsave(
+		&ipa_rm_it_handles[me->resource_name].lock, flags);
+	if (ipa_rm_it_handles[me->resource_name].release_in_prog) {
+		IPADBG("%s: calling release_resource on resource %d!\n",
+		     __func__, me->resource_name);
+		ipa_rm_release_resource(me->resource_name);
+		ipa_rm_it_handles[me->resource_name].release_in_prog = false;
+	}
+	spin_unlock_irqrestore(
+		&ipa_rm_it_handles[me->resource_name].lock, flags);
+}
+
+/**
+* ipa_rm_inactivity_timer_init() - Init function for IPA RM
+* inactivity timer. This function shall be called prior calling
+* any other API of IPA RM inactivity timer.
+*
+* @resource_name: Resource name. @see ipa_rm.h
+* @msecs: time in miliseccond, that IPA RM inactivity timer
+* shall wait prior calling to ipa_rm_release_resource().
+*
+* Return codes:
+* 0: success
+* -EINVAL: invalid parameters
+*/
+int ipa_rm_inactivity_timer_init(enum ipa_rm_resource_name resource_name,
+				 unsigned long msecs)
+{
+	IPADBG("%s: resource %d\n", __func__, resource_name);
+
+	if (resource_name < 0 ||
+	    resource_name >= IPA_RM_RESOURCE_MAX) {
+		IPAERR("%s: Invalid parameter\n", __func__);
+		return -EINVAL;
+	}
+
+	if (ipa_rm_it_handles[resource_name].initied) {
+		IPAERR("%s: resource %d already inited\n",
+		    __func__, resource_name);
+		return -EINVAL;
+	}
+
+	spin_lock_init(&ipa_rm_it_handles[resource_name].lock);
+	ipa_rm_it_handles[resource_name].resource_name = resource_name;
+	ipa_rm_it_handles[resource_name].jiffies = msecs_to_jiffies(msecs);
+	ipa_rm_it_handles[resource_name].release_in_prog = false;
+
+	INIT_DELAYED_WORK(&ipa_rm_it_handles[resource_name].work,
+			  ipa_rm_inactivity_timer_func);
+	ipa_rm_it_handles[resource_name].initied = 1;
+
+	return 0;
+}
+
+/**
+* ipa_rm_inactivity_timer_destroy() - De-Init function for IPA
+* RM inactivity timer.
+*
+* @resource_name: Resource name. @see ipa_rm.h
+*
+* Return codes:
+* 0: success
+* -EINVAL: invalid parameters
+*/
+int ipa_rm_inactivity_timer_destroy(enum ipa_rm_resource_name resource_name)
+{
+	IPADBG("%s: resource %d\n", __func__, resource_name);
+
+	if (resource_name < 0 ||
+	    resource_name >= IPA_RM_RESOURCE_MAX) {
+		IPAERR("%s: Invalid parameter\n", __func__);
+		return -EINVAL;
+	}
+
+	if (!ipa_rm_it_handles[resource_name].initied) {
+		IPAERR("%s: resource %d already inited\n",
+		    __func__, resource_name);
+		return -EINVAL;
+	}
+
+	memset(&ipa_rm_it_handles[resource_name], 0,
+	       sizeof(struct ipa_rm_it_private));
+
+	return 0;
+}
+
+/**
+* ipa_rm_inactivity_timer_request_resource() - Same as
+* ipa_rm_request_resource(), with a difference that calling to
+* this function will also cancel the inactivity timer, if
+* ipa_rm_inactivity_timer_release_resource() was called earlier.
+*
+* @resource_name: Resource name. @see ipa_rm.h
+*
+* Return codes:
+* 0: success
+* -EINVAL: invalid parameters
+*/
+int ipa_rm_inactivity_timer_request_resource(
+				enum ipa_rm_resource_name resource_name)
+{
+	int ret;
+	unsigned long flags;
+	IPADBG("%s: resource %d\n", __func__, resource_name);
+
+	if (resource_name < 0 ||
+	    resource_name >= IPA_RM_RESOURCE_MAX) {
+		IPAERR("%s: Invalid parameter\n", __func__);
+		return -EINVAL;
+	}
+
+	if (!ipa_rm_it_handles[resource_name].initied) {
+		IPAERR("%s: Not initialized\n", __func__);
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&ipa_rm_it_handles[resource_name].lock, flags);
+	cancel_delayed_work(&ipa_rm_it_handles[resource_name].work);
+	ipa_rm_it_handles[resource_name].release_in_prog = false;
+	spin_unlock_irqrestore(&ipa_rm_it_handles[resource_name].lock, flags);
+	ret = ipa_rm_request_resource(resource_name);
+	IPADBG("%s: resource %d: returning %d\n", __func__, resource_name, ret);
+	return ret;
+}
+
+/**
+* ipa_rm_inactivity_timer_release_resource() - Sets the
+* inactivity timer to the timeout set by
+* ipa_rm_inactivity_timer_init(). When the timeout expires, IPA
+* RM inactivity timer will call to ipa_rm_release_resource().
+* If a call to ipa_rm_inactivity_timer_request_resource() was
+* made BEFORE the timout has expired, rge timer will be
+* cancelled.
+*
+* @resource_name: Resource name. @see ipa_rm.h
+*
+* Return codes:
+* 0: success
+* -EINVAL: invalid parameters
+*/
+int ipa_rm_inactivity_timer_release_resource(
+				enum ipa_rm_resource_name resource_name)
+{
+	unsigned long flags;
+	IPADBG("%s: resource %d\n", __func__, resource_name);
+
+	if (resource_name < 0 ||
+	    resource_name >= IPA_RM_RESOURCE_MAX) {
+		IPAERR("%s: Invalid parameter\n", __func__);
+		return -EINVAL;
+	}
+
+	if (!ipa_rm_it_handles[resource_name].initied) {
+		IPAERR("%s: Not initialized\n", __func__);
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&ipa_rm_it_handles[resource_name].lock, flags);
+	if (ipa_rm_it_handles[resource_name].release_in_prog) {
+		IPADBG("%s: Timer already set, not scheduling again %d\n",
+		    __func__, resource_name);
+		spin_unlock_irqrestore(
+			&ipa_rm_it_handles[resource_name].lock, flags);
+		return 0;
+	}
+	ipa_rm_it_handles[resource_name].release_in_prog = true;
+	spin_unlock_irqrestore(&ipa_rm_it_handles[resource_name].lock, flags);
+
+	IPADBG("%s: setting delayed work\n", __func__);
+	schedule_delayed_work(&ipa_rm_it_handles[resource_name].work,
+			      ipa_rm_it_handles[resource_name].jiffies);
+
+	return 0;
+}
+
diff --git a/drivers/platform/msm/ipa/ipa_rm_peers_list.c b/drivers/platform/msm/ipa/ipa_rm_peers_list.c
new file mode 100644
index 0000000..55f8239
--- /dev/null
+++ b/drivers/platform/msm/ipa/ipa_rm_peers_list.c
@@ -0,0 +1,247 @@
+/* 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/slab.h>
+#include "ipa_i.h"
+#include "ipa_rm_i.h"
+#include "ipa_rm_resource.h"
+
+/**
+ * ipa_rm_peers_list_get_resource_index() - resource name to index
+ *	of this resource in corresponding peers list
+ * @resource_name: [in] resource name
+ *
+ * Returns: resource index mapping, IPA_RM_INDEX_INVALID
+ * in case provided resource name isn't contained in enum
+ * ipa_rm_resource_name.
+ *
+ */
+static int ipa_rm_peers_list_get_resource_index(
+		enum ipa_rm_resource_name resource_name)
+{
+	int resource_index = IPA_RM_INDEX_INVALID;
+	if (IPA_RM_RESORCE_IS_PROD(resource_name))
+		resource_index = ipa_rm_prod_index(resource_name);
+	else if (IPA_RM_RESORCE_IS_CONS(resource_name)) {
+		resource_index = ipa_rm_cons_index(resource_name);
+		if (resource_index != IPA_RM_INDEX_INVALID)
+			resource_index =
+				resource_index - IPA_RM_RESOURCE_PROD_MAX;
+	}
+
+	return resource_index;
+}
+
+static bool ipa_rm_peers_list_check_index(int index,
+		struct ipa_rm_peers_list *peers_list)
+{
+	return !(index > peers_list->max_peers || index < 0);
+}
+
+/**
+ * ipa_rm_peers_list_create() - creates the peers list
+ *
+ * @max_peers: maximum number of peers in new list
+ * @peers_list: [out] newly created peers list
+ *
+ * Returns: 0 in case of SUCCESS, negative otherwise
+ */
+int ipa_rm_peers_list_create(int max_peers,
+		struct ipa_rm_peers_list **peers_list)
+{
+	int result;
+	*peers_list = kzalloc(sizeof(**peers_list), GFP_KERNEL);
+	if (!*peers_list) {
+		result = -ENOMEM;
+		goto bail;
+	}
+	rwlock_init(&(*peers_list)->peers_lock);
+	(*peers_list)->max_peers = max_peers;
+	(*peers_list)->peers = kzalloc((*peers_list)->max_peers *
+				sizeof(struct ipa_rm_resource *), GFP_KERNEL);
+	if (!((*peers_list)->peers)) {
+		result = -ENOMEM;
+		goto list_alloc_fail;
+	}
+	return 0;
+
+list_alloc_fail:
+	kfree(*peers_list);
+bail:
+	return result;
+}
+
+/**
+ * ipa_rm_peers_list_delete() - deletes the peers list
+ *
+ * @peers_list: peers list
+ *
+ */
+void ipa_rm_peers_list_delete(struct ipa_rm_peers_list *peers_list)
+{
+	if (peers_list) {
+		kfree(peers_list->peers);
+		kfree(peers_list);
+	}
+}
+
+/**
+ * ipa_rm_peers_list_remove_peer() - removes peer from the list
+ *
+ * @peers_list: peers list
+ * @resource_name: name of the resource to remove
+ *
+ */
+void ipa_rm_peers_list_remove_peer(
+		struct ipa_rm_peers_list *peers_list,
+		enum ipa_rm_resource_name resource_name)
+{
+	if (!peers_list)
+		return;
+	write_lock(&peers_list->peers_lock);
+	peers_list->peers[ipa_rm_peers_list_get_resource_index(
+			resource_name)] = NULL;
+	peers_list->peers_count--;
+	write_unlock(&peers_list->peers_lock);
+}
+
+/**
+ * ipa_rm_peers_list_add_peer() - adds peer to the list
+ *
+ * @peers_list: peers list
+ * @resource: resource to add
+ *
+ */
+void ipa_rm_peers_list_add_peer(
+		struct ipa_rm_peers_list *peers_list,
+		struct ipa_rm_resource *resource)
+{
+	if (!peers_list || !resource)
+		return;
+	read_lock(&peers_list->peers_lock);
+	peers_list->peers[ipa_rm_peers_list_get_resource_index(
+			resource->name)] =
+			resource;
+	peers_list->peers_count++;
+	read_unlock(&peers_list->peers_lock);
+}
+
+/**
+ * ipa_rm_peers_list_is_empty() - checks
+ *	if resource peers list is empty
+ *
+ * @peers_list: peers list
+ *
+ * Returns: true if the list is empty, false otherwise
+ */
+bool ipa_rm_peers_list_is_empty(struct ipa_rm_peers_list *peers_list)
+{
+	bool result = true;
+	if (!peers_list)
+		goto bail;
+	read_lock(&peers_list->peers_lock);
+	if (peers_list->peers_count > 0)
+		result = false;
+	read_unlock(&peers_list->peers_lock);
+bail:
+	return result;
+}
+
+/**
+ * ipa_rm_peers_list_has_last_peer() - checks
+ *	if resource peers list has exactly one peer
+ *
+ * @peers_list: peers list
+ *
+ * Returns: true if the list has exactly one peer, false otherwise
+ */
+bool ipa_rm_peers_list_has_last_peer(
+		struct ipa_rm_peers_list *peers_list)
+{
+	bool result = true;
+	if (!peers_list)
+		goto bail;
+	read_lock(&peers_list->peers_lock);
+	if (peers_list->peers_count == 1)
+		result = false;
+	read_unlock(&peers_list->peers_lock);
+bail:
+	return result;
+}
+
+/**
+ * ipa_rm_peers_list_check_dependency() - check dependency
+ *	between 2 peer lists
+ * @resource_peers: first peers list
+ * @resource_name: first peers list resource name
+ * @depends_on_peers: second peers list
+ * @depends_on_name: second peers list resource name
+ *
+ * Returns: true if there is dependency, false otherwise
+ *
+ */
+bool ipa_rm_peers_list_check_dependency(
+		struct ipa_rm_peers_list *resource_peers,
+		enum ipa_rm_resource_name resource_name,
+		struct ipa_rm_peers_list *depends_on_peers,
+		enum ipa_rm_resource_name depends_on_name)
+{
+	bool result = false;
+	if (!resource_peers || !depends_on_peers)
+		return result;
+	read_lock(&resource_peers->peers_lock);
+	if (resource_peers->peers[ipa_rm_peers_list_get_resource_index(
+			depends_on_name)] != NULL)
+		result = true;
+	read_unlock(&resource_peers->peers_lock);
+
+	read_lock(&depends_on_peers->peers_lock);
+	if (depends_on_peers->peers[ipa_rm_peers_list_get_resource_index(
+						resource_name)] != NULL)
+		result = true;
+	read_unlock(&depends_on_peers->peers_lock);
+
+	return result;
+}
+
+/**
+ * ipa_rm_peers_list_get_resource() - get resource by
+ *	resource index
+ * @resource_index: resource index
+ * @resource_peers: peers list
+ *
+ * Returns: the resource if found, NULL otherwise
+ */
+struct ipa_rm_resource *ipa_rm_peers_list_get_resource(int resource_index,
+		struct ipa_rm_peers_list *resource_peers)
+{
+	struct ipa_rm_resource *result = NULL;
+	if (!ipa_rm_peers_list_check_index(resource_index, resource_peers))
+		goto bail;
+	read_lock(&resource_peers->peers_lock);
+	result = resource_peers->peers[resource_index];
+	read_unlock(&resource_peers->peers_lock);
+bail:
+	return result;
+}
+
+/**
+ * ipa_rm_peers_list_get_size() - get peers list sise
+ *
+ * @peers_list: peers list
+ *
+ * Returns: the size of the peers list
+ */
+int ipa_rm_peers_list_get_size(struct ipa_rm_peers_list *peers_list)
+{
+	return peers_list->max_peers;
+}
diff --git a/drivers/platform/msm/ipa/ipa_rm_peers_list.h b/drivers/platform/msm/ipa/ipa_rm_peers_list.h
new file mode 100644
index 0000000..f8fd1ca
--- /dev/null
+++ b/drivers/platform/msm/ipa/ipa_rm_peers_list.h
@@ -0,0 +1,55 @@
+/* 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 _IPA_RM_PEERS_LIST_H_
+#define _IPA_RM_PEERS_LIST_H_
+
+#include "ipa_rm_resource.h"
+
+/**
+ * struct ipa_rm_peers_list - IPA RM resource peers list
+ * @peers: the list of references to resources dependent on this resource
+ *          in case of producer or list of dependencies in case of consumer
+ * @max_peers: maximum number of peers for this resource
+ * @peers_count: actual number of peers for this resource
+ * @peers_lock: RW lock for peers container
+ */
+struct ipa_rm_peers_list {
+	struct ipa_rm_resource		**peers;
+	int				max_peers;
+	int				peers_count;
+	rwlock_t			peers_lock;
+};
+
+int ipa_rm_peers_list_create(int max_peers,
+		struct ipa_rm_peers_list **peers_list);
+void ipa_rm_peers_list_delete(struct ipa_rm_peers_list *peers_list);
+void ipa_rm_peers_list_remove_peer(
+		struct ipa_rm_peers_list *peers_list,
+		enum ipa_rm_resource_name resource_name);
+void ipa_rm_peers_list_add_peer(
+		struct ipa_rm_peers_list *peers_list,
+		struct ipa_rm_resource *resource);
+bool ipa_rm_peers_list_check_dependency(
+		struct ipa_rm_peers_list *resource_peers,
+		enum ipa_rm_resource_name resource_name,
+		struct ipa_rm_peers_list *depends_on_peers,
+		enum ipa_rm_resource_name depends_on_name);
+struct ipa_rm_resource *ipa_rm_peers_list_get_resource(int resource_index,
+		struct ipa_rm_peers_list *peers_list);
+int ipa_rm_peers_list_get_size(struct ipa_rm_peers_list *peers_list);
+bool ipa_rm_peers_list_is_empty(struct ipa_rm_peers_list *peers_list);
+bool ipa_rm_peers_list_has_last_peer(
+		struct ipa_rm_peers_list *peers_list);
+
+
+#endif /* _IPA_RM_PEERS_LIST_H_ */
diff --git a/drivers/platform/msm/ipa/ipa_rm_resource.c b/drivers/platform/msm/ipa/ipa_rm_resource.c
new file mode 100644
index 0000000..3ba8e84
--- /dev/null
+++ b/drivers/platform/msm/ipa/ipa_rm_resource.c
@@ -0,0 +1,809 @@
+/* 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/slab.h>
+#include "ipa_i.h"
+#include "ipa_rm_resource.h"
+#include "ipa_rm_i.h"
+
+/**
+ * ipa_rm_dep_prod_index() - producer name to producer index mapping
+ * @resource_name: [in] resource name (should be of producer)
+ *
+ * Returns: resource index mapping, IPA_RM_INDEX_INVALID
+ *	in case provided resource name isn't contained
+ *	in enum ipa_rm_resource_name or is not of producers.
+ *
+ */
+int ipa_rm_prod_index(enum ipa_rm_resource_name resource_name)
+{
+	int result = resource_name;
+	switch (resource_name) {
+	case IPA_RM_RESOURCE_BRIDGE_PROD:
+	case IPA_RM_RESOURCE_A2_PROD:
+	case IPA_RM_RESOURCE_USB_PROD:
+	case IPA_RM_RESOURCE_HSIC_PROD:
+	case IPA_RM_RESOURCE_STD_ECM_PROD:
+	case IPA_RM_RESOURCE_WWAN_0_PROD:
+	case IPA_RM_RESOURCE_WWAN_1_PROD:
+	case IPA_RM_RESOURCE_WWAN_2_PROD:
+	case IPA_RM_RESOURCE_WWAN_3_PROD:
+	case IPA_RM_RESOURCE_WWAN_4_PROD:
+	case IPA_RM_RESOURCE_WWAN_5_PROD:
+	case IPA_RM_RESOURCE_WWAN_6_PROD:
+	case IPA_RM_RESOURCE_WWAN_7_PROD:
+	case IPA_RM_RESOURCE_WLAN_PROD:
+		break;
+	default:
+		result = IPA_RM_INDEX_INVALID;
+		break;
+	}
+	return result;
+}
+
+/**
+ * ipa_rm_cons_index() - consumer name to consumer index mapping
+ * @resource_name: [in] resource name (should be of consumer)
+ *
+ * Returns: resource index mapping, IPA_RM_INDEX_INVALID
+ *	in case provided resource name isn't contained
+ *	in enum ipa_rm_resource_name or is not of consumers.
+ *
+ */
+int ipa_rm_cons_index(enum ipa_rm_resource_name resource_name)
+{
+	int result = resource_name;
+	switch (resource_name) {
+	case IPA_RM_RESOURCE_A2_CONS:
+	case IPA_RM_RESOURCE_USB_CONS:
+	case IPA_RM_RESOURCE_HSIC_CONS:
+		break;
+	default:
+		result = IPA_RM_INDEX_INVALID;
+		break;
+	}
+	return result;
+}
+
+static int ipa_rm_resource_consumer_request(
+		struct ipa_rm_resource_cons *consumer)
+{
+	int result = 0;
+	int driver_result;
+	unsigned long flags;
+	IPADBG("IPA RM ::ipa_rm_resource_consumer_request ENTER\n");
+	spin_lock_irqsave(&consumer->resource.state_lock, flags);
+	switch (consumer->resource.state) {
+	case IPA_RM_RELEASED:
+	case IPA_RM_RELEASE_IN_PROGRESS:
+	{
+		enum ipa_rm_resource_state prev_state =
+						consumer->resource.state;
+		consumer->resource.state = IPA_RM_REQUEST_IN_PROGRESS;
+		spin_unlock_irqrestore(&consumer->resource.state_lock, flags);
+		driver_result = consumer->request_resource();
+		spin_lock_irqsave(&consumer->resource.state_lock, flags);
+		if (driver_result == 0)
+			consumer->resource.state = IPA_RM_GRANTED;
+		else if (driver_result != -EINPROGRESS) {
+			consumer->resource.state = prev_state;
+			result = driver_result;
+			goto bail;
+		}
+		result = driver_result;
+		break;
+	}
+	case IPA_RM_GRANTED:
+		break;
+	case IPA_RM_REQUEST_IN_PROGRESS:
+		result = -EINPROGRESS;
+		break;
+	default:
+		result = -EPERM;
+		goto bail;
+	}
+	consumer->usage_count++;
+bail:
+	spin_unlock_irqrestore(&consumer->resource.state_lock, flags);
+	IPADBG("IPA RM ::ipa_rm_resource_consumer_request EXIT [%d]\n", result);
+	return result;
+}
+
+static int ipa_rm_resource_consumer_release(
+		struct ipa_rm_resource_cons *consumer)
+{
+	int result = 0;
+	int driver_result;
+	unsigned long flags;
+	enum ipa_rm_resource_state save_state;
+	IPADBG("IPA RM ::ipa_rm_resource_consumer_release ENTER\n");
+	spin_lock_irqsave(&consumer->resource.state_lock, flags);
+	switch (consumer->resource.state) {
+	case IPA_RM_RELEASED:
+		break;
+	case IPA_RM_GRANTED:
+	case IPA_RM_REQUEST_IN_PROGRESS:
+		if (consumer->usage_count > 0)
+			consumer->usage_count--;
+		if (consumer->usage_count == 0) {
+			save_state = consumer->resource.state;
+			consumer->resource.state = IPA_RM_RELEASE_IN_PROGRESS;
+			spin_unlock_irqrestore(&consumer->resource.state_lock,
+					flags);
+			driver_result = consumer->release_resource();
+			spin_lock_irqsave(&consumer->resource.state_lock,
+					flags);
+			if (driver_result == 0)
+				consumer->resource.state = IPA_RM_RELEASED;
+			else if (driver_result != -EINPROGRESS)
+				consumer->resource.state = save_state;
+			result = driver_result;
+		}
+		break;
+	case IPA_RM_RELEASE_IN_PROGRESS:
+		if (consumer->usage_count > 0)
+			consumer->usage_count--;
+		result = -EINPROGRESS;
+		break;
+	default:
+		result = -EPERM;
+		goto bail;
+	}
+bail:
+	spin_unlock_irqrestore(&consumer->resource.state_lock, flags);
+	IPADBG("IPA RM ::ipa_rm_resource_consumer_release EXIT [%d]\n", result);
+	return result;
+}
+
+/**
+ * ipa_rm_resource_producer_notify_clients() - notify
+ *	all registered clients of given producer
+ * @producer: producer
+ * @event: event to notify
+ */
+void ipa_rm_resource_producer_notify_clients(
+				struct ipa_rm_resource_prod *producer,
+				enum ipa_rm_event event)
+{
+	struct ipa_rm_notification_info *reg_info, *reg_info_cloned;
+	struct list_head *pos, *q;
+	LIST_HEAD(cloned_list);
+	read_lock(&producer->event_listeners_lock);
+	list_for_each(pos, &(producer->event_listeners)) {
+		reg_info = list_entry(pos,
+					struct ipa_rm_notification_info,
+					link);
+		reg_info_cloned = kzalloc(sizeof(*reg_info_cloned), GFP_ATOMIC);
+		if (!reg_info_cloned)
+			goto clone_list_failed;
+		reg_info_cloned->reg_params.notify_cb =
+				reg_info->reg_params.notify_cb;
+		reg_info_cloned->reg_params.user_data =
+				reg_info->reg_params.user_data;
+		list_add(&reg_info_cloned->link, &cloned_list);
+	}
+	read_unlock(&producer->event_listeners_lock);
+	list_for_each_safe(pos, q, &cloned_list) {
+		reg_info = list_entry(pos,
+					struct ipa_rm_notification_info,
+					link);
+		reg_info->reg_params.notify_cb(
+				reg_info->reg_params.user_data,
+				event,
+				0);
+		list_del(pos);
+		kfree(reg_info);
+	}
+	return;
+clone_list_failed:
+	read_unlock(&producer->event_listeners_lock);
+}
+
+static int ipa_rm_resource_producer_create(struct ipa_rm_resource **resource,
+		struct ipa_rm_resource_prod **producer,
+		struct ipa_rm_create_params *create_params,
+		int *max_peers)
+{
+	int result = 0;
+	*producer = kzalloc(sizeof(**producer), GFP_KERNEL);
+	if (*producer == NULL) {
+		result = -ENOMEM;
+		goto bail;
+	}
+	rwlock_init(&(*producer)->event_listeners_lock);
+	INIT_LIST_HEAD(&((*producer)->event_listeners));
+	result = ipa_rm_resource_producer_register(*producer,
+			&(create_params->reg_params));
+	if (result)
+		goto register_fail;
+	(*resource) = (struct ipa_rm_resource *) (*producer);
+	(*resource)->type = IPA_RM_PRODUCER;
+	*max_peers = IPA_RM_RESOURCE_CONS_MAX;
+	goto bail;
+register_fail:
+	kfree(*producer);
+bail:
+	return result;
+}
+
+static void ipa_rm_resource_producer_delete(
+				struct ipa_rm_resource_prod *producer)
+{
+	struct ipa_rm_notification_info *reg_info;
+	struct list_head *pos, *q;
+	write_lock(&producer->event_listeners_lock);
+	list_for_each_safe(pos, q, &(producer->event_listeners)) {
+		reg_info = list_entry(pos,
+				struct ipa_rm_notification_info,
+				link);
+		list_del(pos);
+		kfree(reg_info);
+	}
+	write_unlock(&producer->event_listeners_lock);
+}
+
+static int ipa_rm_resource_consumer_create(struct ipa_rm_resource **resource,
+		struct ipa_rm_resource_cons **consumer,
+		struct ipa_rm_create_params *create_params,
+		int *max_peers)
+{
+	int result = 0;
+	*consumer = kzalloc(sizeof(**consumer), GFP_KERNEL);
+	if (*consumer == NULL) {
+		result = -ENOMEM;
+		goto bail;
+	}
+	(*consumer)->request_resource = create_params->request_resource;
+	(*consumer)->release_resource = create_params->release_resource;
+	(*resource) = (struct ipa_rm_resource *) (*consumer);
+	(*resource)->type = IPA_RM_CONSUMER;
+	*max_peers = IPA_RM_RESOURCE_PROD_MAX;
+bail:
+	return result;
+}
+
+/**
+ * ipa_rm_resource_create() - creates resource
+ * @create_params: [in] parameters needed
+ *			for resource initialization with IPA RM
+ * @resource: [out] created resource
+ *
+ * Returns: 0 on success, negative on failure
+ */
+int ipa_rm_resource_create(
+		struct ipa_rm_create_params *create_params,
+		struct ipa_rm_resource **resource)
+{
+	struct ipa_rm_resource_cons *consumer;
+	struct ipa_rm_resource_prod *producer;
+	int max_peers;
+	int result = 0;
+
+	if (!create_params) {
+		result = -EINVAL;
+		goto bail;
+	}
+	if (IPA_RM_RESORCE_IS_PROD(create_params->name)) {
+		result = ipa_rm_resource_producer_create(resource,
+				&producer,
+				create_params,
+				&max_peers);
+		if (result)
+			goto bail;
+	} else if (IPA_RM_RESORCE_IS_CONS(create_params->name)) {
+		result = ipa_rm_resource_consumer_create(resource,
+				&consumer,
+				create_params,
+				&max_peers);
+		if (result)
+			goto bail;
+	} else {
+		result = -EPERM;
+		goto bail;
+	}
+	result = ipa_rm_peers_list_create(max_peers,
+			&((*resource)->peers_list));
+	if (result)
+		goto peers_alloc_fail;
+	(*resource)->name = create_params->name;
+	(*resource)->state = IPA_RM_RELEASED;
+	spin_lock_init(&((*resource)->state_lock));
+	goto bail;
+peers_alloc_fail:
+	ipa_rm_resource_delete(*resource);
+bail:
+	return result;
+}
+
+/**
+ * ipa_rm_resource_delete() - deletes resource
+ * @resource: [in] resource
+ *			for resource initialization with IPA RM
+ */
+void ipa_rm_resource_delete(struct ipa_rm_resource *resource)
+{
+	if (!resource)
+		return;
+	if (resource->peers_list)
+		ipa_rm_peers_list_delete(resource->peers_list);
+	if (resource->type == IPA_RM_PRODUCER) {
+		ipa_rm_resource_producer_delete(
+				(struct ipa_rm_resource_prod *) resource);
+		kfree((struct ipa_rm_resource_prod *) resource);
+	} else
+		kfree((struct ipa_rm_resource_cons *) resource);
+}
+
+/**
+ * ipa_rm_resource_register() - register resource
+ * @resource: [in] resource
+ * @reg_params: [in] registration parameters
+ *
+ * Returns: 0 on success, negative on failure
+ *
+ * Producer resource is expected for this call.
+ *
+ */
+int ipa_rm_resource_producer_register(struct ipa_rm_resource_prod *producer,
+		struct ipa_rm_register_params *reg_params)
+{
+	int result = 0;
+	struct ipa_rm_notification_info *reg_info;
+	struct list_head *pos;
+	if (!producer || !reg_params) {
+		result = -EPERM;
+		goto bail;
+	}
+	read_lock(&producer->event_listeners_lock);
+	list_for_each(pos, &(producer->event_listeners)) {
+		reg_info = list_entry(pos,
+					struct ipa_rm_notification_info,
+					link);
+		if (reg_info->reg_params.notify_cb ==
+						reg_params->notify_cb) {
+			result = -EPERM;
+			read_unlock(&producer->event_listeners_lock);
+			goto bail;
+		}
+
+	}
+	read_unlock(&producer->event_listeners_lock);
+	reg_info = kzalloc(sizeof(*reg_info), GFP_KERNEL);
+	if (reg_info == NULL) {
+		result = -ENOMEM;
+		goto bail;
+	}
+	reg_info->reg_params.user_data = reg_params->user_data;
+	reg_info->reg_params.notify_cb = reg_params->notify_cb;
+	INIT_LIST_HEAD(&reg_info->link);
+	write_lock(&producer->event_listeners_lock);
+	list_add(&reg_info->link, &producer->event_listeners);
+	write_unlock(&producer->event_listeners_lock);
+bail:
+	return result;
+}
+
+/**
+ * ipa_rm_resource_deregister() - register resource
+ * @resource: [in] resource
+ * @reg_params: [in] registration parameters
+ *
+ * Returns: 0 on success, negative on failure
+ *
+ * Producer resource is expected for this call.
+ * This function deleted only single instance of
+ * registration info.
+ *
+ */
+int ipa_rm_resource_producer_deregister(struct ipa_rm_resource_prod *producer,
+		struct ipa_rm_register_params *reg_params)
+{
+	int result = -EINVAL;
+	struct ipa_rm_notification_info *reg_info;
+	struct list_head *pos, *q;
+	if (!producer || !reg_params)
+		return -EINVAL;
+	write_lock(&producer->event_listeners_lock);
+	list_for_each_safe(pos, q, &(producer->event_listeners)) {
+		reg_info = list_entry(pos,
+				struct ipa_rm_notification_info,
+				link);
+		if (reg_info->reg_params.notify_cb ==
+						reg_params->notify_cb) {
+			list_del(pos);
+			kfree(reg_info);
+			result = 0;
+			goto bail;
+		}
+
+	}
+bail:
+	write_unlock(&producer->event_listeners_lock);
+	return result;
+}
+
+/**
+ * ipa_rm_resource_add_dependency() - add dependency between two
+ *				given resources
+ * @resource: [in] resource resource
+ * @depends_on: [in] depends_on resource
+ *
+ * Returns: 0 on success, negative on failure
+ */
+int ipa_rm_resource_add_dependency(struct ipa_rm_resource *resource,
+				   struct ipa_rm_resource *depends_on)
+{
+	int result = 0;
+	unsigned long flags;
+	int consumer_result;
+	if (!resource || !depends_on)
+		return -EINVAL;
+	if (ipa_rm_peers_list_check_dependency(resource->peers_list,
+			resource->name,
+			depends_on->peers_list,
+			depends_on->name))
+		return -EINVAL;
+	ipa_rm_peers_list_add_peer(resource->peers_list, depends_on);
+	ipa_rm_peers_list_add_peer(depends_on->peers_list, resource);
+	spin_lock_irqsave(&resource->state_lock, flags);
+	switch (resource->state) {
+	case IPA_RM_RELEASED:
+	case IPA_RM_RELEASE_IN_PROGRESS:
+		break;
+	case IPA_RM_GRANTED:
+	case IPA_RM_REQUEST_IN_PROGRESS:
+	{
+		enum ipa_rm_resource_state prev_state = resource->state;
+		resource->state = IPA_RM_REQUEST_IN_PROGRESS;
+		((struct ipa_rm_resource_prod *)
+					resource)->pending_request++;
+		spin_unlock_irqrestore(&resource->state_lock, flags);
+		consumer_result = ipa_rm_resource_consumer_request(
+				(struct ipa_rm_resource_cons *)depends_on);
+		spin_lock_irqsave(&resource->state_lock, flags);
+		if (consumer_result != -EINPROGRESS)
+			resource->state = prev_state;
+			((struct ipa_rm_resource_prod *)
+					resource)->pending_request--;
+		result = consumer_result;
+		break;
+	}
+	default:
+		result = -EPERM;
+		goto bail;
+	}
+bail:
+	spin_unlock_irqrestore(&resource->state_lock, flags);
+	IPADBG("IPA RM ipa_rm_resource_add_dependency name[%d]count[%d]EXIT\n",
+			resource->name, resource->peers_list->peers_count);
+	IPADBG("IPA RM ipa_rm_resource_add_dependency name[%d]count[%d]EXIT\n",
+			depends_on->name, depends_on->peers_list->peers_count);
+	return result;
+}
+
+/**
+ * ipa_rm_resource_delete_dependency() - add dependency between two
+ *				given resources
+ * @resource: [in] resource resource
+ * @depends_on: [in] depends_on resource
+ *
+ * Returns: 0 on success, negative on failure
+ * EINPROGRESS is returned in case this is the last dependency
+ * of given resource and IPA RM client should receive the RELEASED cb
+ */
+int ipa_rm_resource_delete_dependency(struct ipa_rm_resource *resource,
+				   struct ipa_rm_resource *depends_on)
+{
+	int result = 0;
+	unsigned long flags;
+	if (!resource || !depends_on)
+		return -EINVAL;
+	if (ipa_rm_peers_list_check_dependency(resource->peers_list,
+			resource->name,
+			depends_on->peers_list,
+			depends_on->name))
+		return -EINVAL;
+	spin_lock_irqsave(&resource->state_lock, flags);
+	switch (resource->state) {
+	case IPA_RM_RELEASED:
+	case IPA_RM_GRANTED:
+		break;
+	case IPA_RM_RELEASE_IN_PROGRESS:
+		if (((struct ipa_rm_resource_prod *)
+				resource)->pending_release > 0)
+			((struct ipa_rm_resource_prod *)
+					resource)->pending_release--;
+		break;
+	case IPA_RM_REQUEST_IN_PROGRESS:
+		if (((struct ipa_rm_resource_prod *)
+				resource)->pending_request > 0)
+			((struct ipa_rm_resource_prod *)
+					resource)->pending_request--;
+		break;
+	default:
+		result = -EINVAL;
+		spin_unlock_irqrestore(&resource->state_lock, flags);
+		goto bail;
+	}
+	spin_unlock_irqrestore(&resource->state_lock, flags);
+	(void) ipa_rm_resource_consumer_release(
+			(struct ipa_rm_resource_cons *)depends_on);
+	if (ipa_rm_peers_list_has_last_peer(resource->peers_list)) {
+		(void) ipa_rm_wq_send_cmd(IPA_RM_WQ_NOTIFY_PROD,
+				resource->name,
+				IPA_RM_RESOURCE_RELEASED);
+		result = -EINPROGRESS;
+	}
+	ipa_rm_peers_list_remove_peer(resource->peers_list,
+			depends_on->name);
+	ipa_rm_peers_list_remove_peer(depends_on->peers_list,
+			resource->name);
+bail:
+	return result;
+}
+
+/**
+ * ipa_rm_resource_producer_request() - producer resource request
+ * @producer: [in] producer
+ *
+ * Returns: 0 on success, negative on failure
+ */
+int ipa_rm_resource_producer_request(struct ipa_rm_resource_prod *producer)
+{
+	int peers_index;
+	int result = 0;
+	unsigned long flags;
+	struct ipa_rm_resource *consumer;
+	int consumer_result;
+	IPADBG("IPA RM ::ipa_rm_resource_producer_request [%d] ENTER\n",
+			producer->resource.name);
+	if (ipa_rm_peers_list_is_empty(producer->resource.peers_list)) {
+		spin_lock_irqsave(&producer->resource.state_lock, flags);
+		producer->resource.state = IPA_RM_GRANTED;
+		spin_unlock_irqrestore(&producer->resource.state_lock, flags);
+		return 0;
+	}
+	spin_lock_irqsave(&producer->resource.state_lock, flags);
+	IPADBG("IPA RM ::ipa_rm_resource_producer_request state [%d]\n",
+			producer->resource.state);
+	switch (producer->resource.state) {
+	case IPA_RM_RELEASED:
+	case IPA_RM_RELEASE_IN_PROGRESS:
+		producer->resource.state = IPA_RM_REQUEST_IN_PROGRESS;
+		break;
+	case IPA_RM_GRANTED:
+		goto unlock_and_bail;
+	case IPA_RM_REQUEST_IN_PROGRESS:
+		result = -EINPROGRESS;
+		goto unlock_and_bail;
+	default:
+		result = -EINVAL;
+		goto unlock_and_bail;
+	}
+	producer->pending_request = 0;
+	spin_unlock_irqrestore(&producer->resource.state_lock, flags);
+	for (peers_index = 0;
+		peers_index < ipa_rm_peers_list_get_size(
+				producer->resource.peers_list);
+		peers_index++) {
+		consumer = ipa_rm_peers_list_get_resource(peers_index,
+				producer->resource.peers_list);
+		if (consumer) {
+			spin_lock_irqsave(
+				&producer->resource.state_lock, flags);
+			producer->pending_request++;
+			spin_unlock_irqrestore(
+				&producer->resource.state_lock, flags);
+			consumer_result = ipa_rm_resource_consumer_request(
+				(struct ipa_rm_resource_cons *)consumer);
+			if (consumer_result == -EINPROGRESS) {
+				result = -EINPROGRESS;
+			} else {
+				spin_lock_irqsave(
+					&producer->resource.state_lock, flags);
+				producer->pending_request--;
+				spin_unlock_irqrestore(
+					&producer->resource.state_lock, flags);
+				if (consumer_result != 0) {
+					result = consumer_result;
+					goto bail;
+				}
+			}
+		}
+	}
+	spin_lock_irqsave(&producer->resource.state_lock, flags);
+	if (producer->pending_request == 0)
+		producer->resource.state = IPA_RM_GRANTED;
+	spin_unlock_irqrestore(&producer->resource.state_lock, flags);
+	return result;
+unlock_and_bail:
+	spin_unlock_irqrestore(&producer->resource.state_lock, flags);
+bail:
+	IPADBG("IPA RM ::ipa_rm_resource_producer_request EXIT[%d]\n", result);
+	return result;
+}
+
+/**
+ * ipa_rm_resource_producer_release() - producer resource release
+ * producer: [in] producer resource
+ *
+ * Returns: 0 on success, negative on failure
+ *
+ */
+int ipa_rm_resource_producer_release(struct ipa_rm_resource_prod *producer)
+{
+	int peers_index;
+	int result = 0;
+	unsigned long flags;
+	struct ipa_rm_resource *consumer;
+	int consumer_result;
+	IPADBG("IPA RM ::ipa_rm_resource_producer_release ENTER\n");
+	if (ipa_rm_peers_list_is_empty(producer->resource.peers_list)) {
+		spin_lock_irqsave(&producer->resource.state_lock, flags);
+		producer->resource.state = IPA_RM_RELEASED;
+		spin_unlock_irqrestore(&producer->resource.state_lock, flags);
+		return 0;
+	}
+	spin_lock_irqsave(&producer->resource.state_lock, flags);
+	switch (producer->resource.state) {
+	case IPA_RM_RELEASED:
+		goto bail;
+	case IPA_RM_GRANTED:
+	case IPA_RM_REQUEST_IN_PROGRESS:
+		producer->resource.state = IPA_RM_RELEASE_IN_PROGRESS;
+		break;
+	case IPA_RM_RELEASE_IN_PROGRESS:
+		result = -EINPROGRESS;
+		goto bail;
+	default:
+		result = -EPERM;
+		goto bail;
+	}
+	producer->pending_release = 0;
+	spin_unlock_irqrestore(&producer->resource.state_lock, flags);
+	for (peers_index = 0;
+		peers_index < ipa_rm_peers_list_get_size(
+				producer->resource.peers_list);
+		peers_index++) {
+		consumer = ipa_rm_peers_list_get_resource(peers_index,
+				producer->resource.peers_list);
+		if (consumer) {
+			spin_lock_irqsave(
+				&producer->resource.state_lock, flags);
+			producer->pending_release++;
+			spin_unlock_irqrestore(
+				&producer->resource.state_lock, flags);
+			consumer_result = ipa_rm_resource_consumer_release(
+				(struct ipa_rm_resource_cons *)consumer);
+			if (consumer_result == -EINPROGRESS) {
+				result = -EINPROGRESS;
+			} else {
+				spin_lock_irqsave(
+					&producer->resource.state_lock, flags);
+				producer->pending_release--;
+				spin_unlock_irqrestore(
+					&producer->resource.state_lock, flags);
+			}
+		}
+	}
+	spin_lock_irqsave(&producer->resource.state_lock, flags);
+	if (producer->pending_release == 0)
+		producer->resource.state = IPA_RM_RELEASED;
+	spin_unlock_irqrestore(&producer->resource.state_lock, flags);
+	return result;
+bail:
+	spin_unlock_irqrestore(&producer->resource.state_lock, flags);
+	IPADBG("IPA RM ::ipa_rm_resource_producer_release EXIT[%d]\n", result);
+	return result;
+}
+
+static void ipa_rm_resource_producer_handle_cb(
+		struct ipa_rm_resource_prod *producer,
+		enum ipa_rm_event event)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&producer->resource.state_lock, flags);
+	switch (producer->resource.state) {
+	case IPA_RM_REQUEST_IN_PROGRESS:
+		if (event != IPA_RM_RESOURCE_GRANTED)
+			goto unlock_and_bail;
+		if (producer->pending_request > 0) {
+			producer->pending_request--;
+			if (producer->pending_request == 0) {
+				producer->resource.state =
+						IPA_RM_GRANTED;
+				spin_unlock_irqrestore(
+					&producer->resource.state_lock, flags);
+				ipa_rm_resource_producer_notify_clients(
+						producer,
+						IPA_RM_RESOURCE_GRANTED);
+				goto bail;
+			}
+		}
+		break;
+	case IPA_RM_RELEASE_IN_PROGRESS:
+		if (event != IPA_RM_RESOURCE_RELEASED)
+			goto unlock_and_bail;
+		if (producer->pending_release > 0) {
+			producer->pending_release--;
+			if (producer->pending_release == 0) {
+				producer->resource.state =
+						IPA_RM_RELEASED;
+				spin_unlock_irqrestore(
+					&producer->resource.state_lock, flags);
+				ipa_rm_resource_producer_notify_clients(
+						producer,
+						IPA_RM_RESOURCE_RELEASED);
+				goto bail;
+			}
+		}
+		break;
+	case IPA_RM_GRANTED:
+	case IPA_RM_RELEASED:
+	default:
+		goto unlock_and_bail;
+	}
+unlock_and_bail:
+	spin_unlock_irqrestore(&producer->resource.state_lock, flags);
+bail:
+	return;
+}
+
+/**
+ * ipa_rm_resource_consumer_handle_cb() - propagates resource
+ *	notification to all dependent producers
+ * @consumer: [in] notifying resource
+ *
+ */
+void ipa_rm_resource_consumer_handle_cb(struct ipa_rm_resource_cons *consumer,
+				enum ipa_rm_event event)
+{
+	int peers_index;
+	struct ipa_rm_resource *producer;
+	unsigned long flags;
+	if (!consumer)
+		return;
+	spin_lock_irqsave(&consumer->resource.state_lock, flags);
+	switch (consumer->resource.state) {
+	case IPA_RM_REQUEST_IN_PROGRESS:
+		if (event == IPA_RM_RESOURCE_RELEASED)
+			goto bail;
+		consumer->resource.state = IPA_RM_GRANTED;
+		break;
+	case IPA_RM_RELEASE_IN_PROGRESS:
+		if (event == IPA_RM_RESOURCE_GRANTED)
+			goto bail;
+		consumer->resource.state = IPA_RM_RELEASED;
+		break;
+	case IPA_RM_GRANTED:
+	case IPA_RM_RELEASED:
+	default:
+		goto bail;
+	}
+	spin_unlock_irqrestore(&consumer->resource.state_lock, flags);
+	for (peers_index = 0;
+		peers_index < ipa_rm_peers_list_get_size(
+				consumer->resource.peers_list);
+		peers_index++) {
+		producer = ipa_rm_peers_list_get_resource(peers_index,
+				consumer->resource.peers_list);
+		if (producer)
+			ipa_rm_resource_producer_handle_cb(
+					(struct ipa_rm_resource_prod *)
+						producer,
+						event);
+	}
+	return;
+bail:
+	spin_unlock_irqrestore(&consumer->resource.state_lock, flags);
+	return;
+}
diff --git a/drivers/platform/msm/ipa/ipa_rm_resource.h b/drivers/platform/msm/ipa/ipa_rm_resource.h
new file mode 100644
index 0000000..b9c2e91
--- /dev/null
+++ b/drivers/platform/msm/ipa/ipa_rm_resource.h
@@ -0,0 +1,127 @@
+/* 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 _IPA_RM_RESOURCE_H_
+#define _IPA_RM_RESOURCE_H_
+
+#include <linux/list.h>
+#include <mach/ipa.h>
+#include "ipa_rm_peers_list.h"
+
+/**
+ * enum ipa_rm_resource_state - resource state
+ */
+enum ipa_rm_resource_state {
+	IPA_RM_RELEASED,
+	IPA_RM_REQUEST_IN_PROGRESS,
+	IPA_RM_GRANTED,
+	IPA_RM_RELEASE_IN_PROGRESS
+};
+
+/**
+ * enum ipa_rm_resource_type - IPA resource manager resource type
+ */
+enum ipa_rm_resource_type {
+	IPA_RM_PRODUCER,
+	IPA_RM_CONSUMER
+};
+
+/**
+ * struct ipa_rm_notification_info - notification information
+ *				of IPA RM client
+ * @reg_params: registration parameters
+ * @link: link to the list of all registered clients information
+ */
+struct ipa_rm_notification_info {
+	struct ipa_rm_register_params	reg_params;
+	struct list_head		link;
+};
+
+/**
+ * struct ipa_rm_resource - IPA RM resource
+ * @name: name identifying resource
+ * @state: state of the resource
+ * @state_lock: lock for all resource state related variables
+ * @peers_list: list of the peers of the resource
+ */
+struct ipa_rm_resource {
+	enum ipa_rm_resource_name	name;
+	enum ipa_rm_resource_type	type;
+	enum ipa_rm_resource_state	state;
+	spinlock_t			state_lock;
+	struct ipa_rm_peers_list	*peers_list;
+};
+
+/**
+ * struct ipa_rm_resource_cons - IPA RM consumer
+ * @resource: resource
+ * @usage_count: number of producers in GRANTED / REQUESTED state
+ *		using this consumer
+ * @request_resource: function which should be called to request resource
+ *			from resource manager
+ * @release_resource: function which should be called to release resource
+ *			from resource manager
+ * Add new fields after @resource only.
+ */
+struct ipa_rm_resource_cons {
+	struct ipa_rm_resource resource;
+	int usage_count;
+	int (*request_resource)(void);
+	int (*release_resource)(void);
+};
+
+/**
+ * struct ipa_rm_resource_prod - IPA RM producer
+ * @resource: resource
+ * @event_listeners: clients registered with this producer
+ *		for notifications in resource state
+ * @event_listeners_lock: RW lock protecting the event listeners list
+ * Add new fields after @resource only.
+ */
+struct ipa_rm_resource_prod {
+	struct ipa_rm_resource	resource;
+	struct list_head	event_listeners;
+	rwlock_t		event_listeners_lock;
+	int			pending_request;
+	int			pending_release;
+};
+
+int ipa_rm_resource_create(
+		struct ipa_rm_create_params *create_params,
+		struct ipa_rm_resource **resource);
+
+void ipa_rm_resource_delete(struct ipa_rm_resource *resource);
+
+int ipa_rm_resource_producer_register(struct ipa_rm_resource_prod *producer,
+				struct ipa_rm_register_params *reg_params);
+
+int ipa_rm_resource_producer_deregister(struct ipa_rm_resource_prod *producer,
+				struct ipa_rm_register_params *reg_params);
+
+int ipa_rm_resource_add_dependency(struct ipa_rm_resource *resource,
+				   struct ipa_rm_resource *depends_on);
+
+int ipa_rm_resource_delete_dependency(struct ipa_rm_resource *resource,
+				      struct ipa_rm_resource *depends_on);
+
+int ipa_rm_resource_producer_request(struct ipa_rm_resource_prod *producer);
+
+int ipa_rm_resource_producer_release(struct ipa_rm_resource_prod *producer);
+
+void ipa_rm_resource_consumer_handle_cb(struct ipa_rm_resource_cons *consumer,
+				enum ipa_rm_event event);
+
+void ipa_rm_resource_producer_notify_clients(
+				struct ipa_rm_resource_prod *producer,
+				enum ipa_rm_event event);
+
+#endif /* _IPA_RM_RESOURCE_H_ */
diff --git a/drivers/platform/msm/ipa/ipa_rt.c b/drivers/platform/msm/ipa/ipa_rt.c
index c69e1fb..7d509c6 100644
--- a/drivers/platform/msm/ipa/ipa_rt.c
+++ b/drivers/platform/msm/ipa/ipa_rt.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
@@ -47,13 +47,14 @@
 	const struct ipa_rt_rule *rule =
 		(const struct ipa_rt_rule *)&entry->rule;
 	u16 en_rule = 0;
-	u8 tmp[IPA_RT_FLT_HW_RULE_BUF_SIZE];
+	u32 tmp[IPA_RT_FLT_HW_RULE_BUF_SIZE/4];
 	u8 *start;
 	int pipe_idx;
 
-	memset(tmp, 0, IPA_RT_FLT_HW_RULE_BUF_SIZE);
-	if (buf == NULL)
-		buf = tmp;
+	if (buf == NULL) {
+		memset(tmp, 0, IPA_RT_FLT_HW_RULE_BUF_SIZE);
+		buf = (u8 *)tmp;
+	}
 
 	start = buf;
 	rule_hdr = (struct ipa_rt_rule_hw_hdr *)buf;
@@ -680,19 +681,20 @@
 }
 EXPORT_SYMBOL(ipa_add_rt_rule);
 
-static int __ipa_del_rt_rule(u32 rule_hdl)
+int __ipa_del_rt_rule(u32 rule_hdl)
 {
 	struct ipa_rt_entry *entry = (struct ipa_rt_entry *)rule_hdl;
 	struct ipa_tree_node *node;
 
-	if (entry == NULL || (entry->cookie != IPA_COOKIE)) {
-		IPAERR("bad params\n");
-		return -EINVAL;
-	}
 	node = ipa_search(&ipa_ctx->rt_rule_hdl_tree, rule_hdl);
 	if (node == NULL) {
 		IPAERR("lookup failed\n");
-		return -EPERM;
+		return -EINVAL;
+	}
+
+	if (entry == NULL || (entry->cookie != IPA_COOKIE)) {
+		IPAERR("bad params\n");
+		return -EINVAL;
 	}
 
 	if (entry->hdr)
@@ -769,6 +771,12 @@
 int ipa_commit_rt(enum ipa_ip_type ip)
 {
 	int ret;
+
+	if (ip >= IPA_IP_MAX) {
+		IPAERR("bad parm\n");
+		return -EINVAL;
+	}
+
 	/*
 	 * issue a commit on the filtering module of same IP type since
 	 * filtering rules point to routing tables
@@ -808,6 +816,11 @@
 	struct ipa_tree_node *node;
 	struct ipa_rt_tbl_set *rset;
 
+	if (ip >= IPA_IP_MAX) {
+		IPAERR("bad parm\n");
+		return -EINVAL;
+	}
+
 	/*
 	 * issue a reset on the filtering module of same IP type since
 	 * filtering rules point to routing tables
@@ -929,16 +942,21 @@
 	struct ipa_rt_tbl *entry = (struct ipa_rt_tbl *)rt_tbl_hdl;
 	struct ipa_tree_node *node;
 	enum ipa_ip_type ip = IPA_IP_MAX;
+	int result;
+
+	mutex_lock(&ipa_ctx->lock);
+	node = ipa_search(&ipa_ctx->rt_tbl_hdl_tree, rt_tbl_hdl);
+	if (node == NULL) {
+		IPAERR("lookup failed\n");
+		result = -EINVAL;
+		goto ret;
+	}
 
 	if (entry == NULL || (entry->cookie != IPA_COOKIE) ||
 			entry->ref_cnt == 0) {
 		IPAERR("bad parms\n");
-		return -EINVAL;
-	}
-	node = ipa_search(&ipa_ctx->rt_tbl_hdl_tree, rt_tbl_hdl);
-	if (node == NULL) {
-		IPAERR("lookup failed\n");
-		return -EPERM;
+		result = -EINVAL;
+		goto ret;
 	}
 
 	if (entry->set == &ipa_ctx->rt_tbl_set[IPA_IP_v4])
@@ -948,7 +966,6 @@
 	else
 		WARN_ON(1);
 
-	mutex_lock(&ipa_ctx->lock);
 	entry->ref_cnt--;
 	if (entry->ref_cnt == 0 && entry->rule_cnt == 0) {
 		if (__ipa_del_rt_tbl(entry))
@@ -957,8 +974,12 @@
 		if (__ipa_commit_rt(ip))
 			IPAERR("fail to commit RT tbl\n");
 	}
+
+	result = 0;
+
+ret:
 	mutex_unlock(&ipa_ctx->lock);
 
-	return 0;
+	return result;
 }
 EXPORT_SYMBOL(ipa_put_rt_tbl);
diff --git a/drivers/platform/msm/ipa/ipa_utils.c b/drivers/platform/msm/ipa/ipa_utils.c
index d5d5566..264de0d 100644
--- a/drivers/platform/msm/ipa/ipa_utils.c
+++ b/drivers/platform/msm/ipa/ipa_utils.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
@@ -14,7 +14,6 @@
 #include <linux/genalloc.h>	/* gen_pool_alloc() */
 #include <linux/io.h>
 #include "ipa_i.h"
-
 static const int ipa_ofst_meq32[] = { IPA_OFFSET_MEQ32_0,
 					IPA_OFFSET_MEQ32_1, -1 };
 static const int ipa_ofst_meq128[] = { IPA_OFFSET_MEQ128_0,
@@ -42,7 +41,12 @@
  */
 int ipa_cfg_route(struct ipa_route *route)
 {
-	ipa_write_reg(ipa_ctx->mmio, IPA_ROUTE_OFST,
+	u32 ipa_route_offset = IPA_ROUTE_OFST_v1;
+
+	if (ipa_ctx->ipa_hw_type != IPA_HW_v1_0)
+		ipa_route_offset = IPA_ROUTE_OFST_v2;
+
+	ipa_write_reg(ipa_ctx->mmio, ipa_route_offset,
 		     IPA_SETFIELD(route->route_dis,
 				  IPA_ROUTE_ROUTE_DIS_SHFT,
 				  IPA_ROUTE_ROUTE_DIS_BMSK) |
@@ -67,10 +71,15 @@
  */
 int ipa_cfg_filter(u32 disable)
 {
-	ipa_write_reg(ipa_ctx->mmio, IPA_FILTER_OFST,
-		     IPA_SETFIELD(!disable,
-				  IPA_FILTER_FILTER_EN_SHFT,
-				  IPA_FILTER_FILTER_EN_BMSK));
+	u32 ipa_filter_ofst = IPA_FILTER_OFST_v1;
+
+	if (ipa_ctx->ipa_hw_type != IPA_HW_v1_0)
+		ipa_filter_ofst = IPA_FILTER_OFST_v2;
+	ipa_write_reg(ipa_ctx->mmio, ipa_filter_ofst,
+			IPA_SETFIELD(!disable,
+					IPA_FILTER_FILTER_EN_SHFT,
+					IPA_FILTER_FILTER_EN_BMSK));
+
 	return 0;
 }
 
@@ -113,6 +122,23 @@
 }
 
 /**
+ * ipa_get_client_mapping() - provide client mapping
+ * @mode: IPA operating mode
+ * @pipe_idx: IPA end-point number
+ *
+ * Return value: client mapping
+ */
+int ipa_get_client_mapping(enum ipa_operating_mode mode, int pipe_idx)
+{
+	int i;
+
+	for (i = 0; i < IPA_CLIENT_MAX; i++)
+		if (ep_mapping[mode][i] == pipe_idx)
+			break;
+	return i;
+}
+
+/**
  * ipa_write_32() - convert 32 bit value to byte array
  * @w: 32 bit integer
  * @dest: byte array
@@ -654,10 +680,19 @@
 	/* copy over EP cfg */
 	ipa_ctx->ep[clnt_hdl].cfg.nat = *ipa_ep_cfg;
 	/* clnt_hdl is used as pipe_index */
-	ipa_write_reg(ipa_ctx->mmio, IPA_ENDP_INIT_NAT_n_OFST(clnt_hdl),
-		      IPA_SETFIELD(ipa_ctx->ep[clnt_hdl].cfg.nat.nat_en,
-				   IPA_ENDP_INIT_NAT_n_NAT_EN_SHFT,
-				   IPA_ENDP_INIT_NAT_n_NAT_EN_BMSK));
+	if (ipa_ctx->ipa_hw_type == IPA_HW_v1_0)
+		ipa_write_reg(ipa_ctx->mmio,
+			      IPA_ENDP_INIT_NAT_n_OFST_v1(clnt_hdl),
+			      IPA_SETFIELD(ipa_ctx->ep[clnt_hdl].cfg.nat.nat_en,
+					   IPA_ENDP_INIT_NAT_n_NAT_EN_SHFT,
+					   IPA_ENDP_INIT_NAT_n_NAT_EN_BMSK));
+	else
+		ipa_write_reg(ipa_ctx->mmio,
+			      IPA_ENDP_INIT_NAT_n_OFST_v2(clnt_hdl),
+			      IPA_SETFIELD(ipa_ctx->ep[clnt_hdl].cfg.nat.nat_en,
+					   IPA_ENDP_INIT_NAT_n_NAT_EN_SHFT,
+					   IPA_ENDP_INIT_NAT_n_NAT_EN_BMSK));
+
 	return 0;
 }
 EXPORT_SYMBOL(ipa_cfg_ep_nat);
@@ -709,7 +744,12 @@
 		   IPA_ENDP_INIT_HDR_n_HDR_A5_MUX_SHFT,
 		   IPA_ENDP_INIT_HDR_n_HDR_A5_MUX_BMSK);
 
-	ipa_write_reg(ipa_ctx->mmio, IPA_ENDP_INIT_HDR_n_OFST(clnt_hdl), val);
+	if (ipa_ctx->ipa_hw_type == IPA_HW_v1_0)
+		ipa_write_reg(ipa_ctx->mmio,
+			IPA_ENDP_INIT_HDR_n_OFST_v1(clnt_hdl), val);
+	else
+		ipa_write_reg(ipa_ctx->mmio,
+			IPA_ENDP_INIT_HDR_n_OFST_v2(clnt_hdl), val);
 
 	return 0;
 }
@@ -727,6 +767,7 @@
 int ipa_cfg_ep_mode(u32 clnt_hdl, const struct ipa_ep_cfg_mode *ipa_ep_cfg)
 {
 	u32 val;
+	int ep;
 
 	if (clnt_hdl >= IPA_NUM_PIPES || ipa_ctx->ep[clnt_hdl].valid == 0 ||
 			ipa_ep_cfg == NULL) {
@@ -739,10 +780,16 @@
 		return -EINVAL;
 	}
 
+	ep = ipa_get_ep_mapping(ipa_ctx->mode, ipa_ep_cfg->dst);
+	if (ep == -1 && ipa_ep_cfg->mode == IPA_DMA) {
+		IPAERR("dst %d does not exist in mode %d\n", ipa_ep_cfg->dst,
+		       ipa_ctx->mode);
+		return -EINVAL;
+	}
+
 	/* copy over EP cfg */
 	ipa_ctx->ep[clnt_hdl].cfg.mode = *ipa_ep_cfg;
-	ipa_ctx->ep[clnt_hdl].dst_pipe_index = ipa_get_ep_mapping(ipa_ctx->mode,
-			ipa_ep_cfg->dst);
+	ipa_ctx->ep[clnt_hdl].dst_pipe_index = ep;
 
 	val = IPA_SETFIELD(ipa_ctx->ep[clnt_hdl].cfg.mode.mode,
 			   IPA_ENDP_INIT_MODE_n_MODE_SHFT,
@@ -751,7 +798,12 @@
 			   IPA_ENDP_INIT_MODE_n_DEST_PIPE_INDEX_SHFT,
 			   IPA_ENDP_INIT_MODE_n_DEST_PIPE_INDEX_BMSK);
 
-	ipa_write_reg(ipa_ctx->mmio, IPA_ENDP_INIT_MODE_n_OFST(clnt_hdl), val);
+	if (ipa_ctx->ipa_hw_type == IPA_HW_v1_0)
+		ipa_write_reg(ipa_ctx->mmio,
+			IPA_ENDP_INIT_MODE_n_OFST_v1(clnt_hdl), val);
+	else
+		ipa_write_reg(ipa_ctx->mmio,
+			IPA_ENDP_INIT_MODE_n_OFST_v2(clnt_hdl), val);
 
 	return 0;
 }
@@ -791,7 +843,12 @@
 			   IPA_ENDP_INIT_AGGR_n_AGGR_TIME_LIMIT_SHFT,
 			   IPA_ENDP_INIT_AGGR_n_AGGR_TIME_LIMIT_BMSK);
 
-	ipa_write_reg(ipa_ctx->mmio, IPA_ENDP_INIT_AGGR_n_OFST(clnt_hdl), val);
+	if (ipa_ctx->ipa_hw_type == IPA_HW_v1_0)
+		ipa_write_reg(ipa_ctx->mmio,
+			IPA_ENDP_INIT_AGGR_n_OFST_v1(clnt_hdl), val);
+	else
+		ipa_write_reg(ipa_ctx->mmio,
+			IPA_ENDP_INIT_AGGR_n_OFST_v2(clnt_hdl), val);
 
 	return 0;
 }
@@ -834,10 +891,19 @@
 	/* always use the "default" routing tables whose indices are 0 */
 	ipa_ctx->ep[clnt_hdl].rt_tbl_idx = 0;
 
-	ipa_write_reg(ipa_ctx->mmio, IPA_ENDP_INIT_ROUTE_n_OFST(clnt_hdl),
-		      IPA_SETFIELD(ipa_ctx->ep[clnt_hdl].rt_tbl_idx,
+	if (ipa_ctx->ipa_hw_type == IPA_HW_v1_0) {
+		ipa_write_reg(ipa_ctx->mmio,
+			IPA_ENDP_INIT_ROUTE_n_OFST_v1(clnt_hdl),
+			IPA_SETFIELD(ipa_ctx->ep[clnt_hdl].rt_tbl_idx,
 			   IPA_ENDP_INIT_ROUTE_n_ROUTE_TABLE_INDEX_SHFT,
 			   IPA_ENDP_INIT_ROUTE_n_ROUTE_TABLE_INDEX_BMSK));
+	} else {
+		ipa_write_reg(ipa_ctx->mmio,
+			IPA_ENDP_INIT_ROUTE_n_OFST_v2(clnt_hdl),
+			IPA_SETFIELD(ipa_ctx->ep[clnt_hdl].rt_tbl_idx,
+			   IPA_ENDP_INIT_ROUTE_n_ROUTE_TABLE_INDEX_SHFT,
+			   IPA_ENDP_INIT_ROUTE_n_ROUTE_TABLE_INDEX_BMSK));
+	}
 
 	return 0;
 }
@@ -901,206 +967,6 @@
 	mutex_unlock(&ipa_ctx->lock);
 }
 
-/*
- * TODO: add swap if needed, for now assume LE is ok for device memory
- * even though IPA registers are assumed to be BE
- */
-/**
- * ipa_write_dev_8() - writes 8 bit value
- * @val: value
- * @ofst_ipa_sram: address to write to
- */
-void ipa_write_dev_8(u8 val, u16 ofst_ipa_sram)
-{
-	iowrite8(val, (u32)ipa_ctx->mmio + 0x4000 + ofst_ipa_sram);
-}
-
-/**
- * ipa_write_dev_16() - writes 16 bit value
- * @val: value
- * @ofst_ipa_sram: address to write to
- *
- */
-void ipa_write_dev_16(u16 val, u16 ofst_ipa_sram)
-{
-	iowrite16(val, (u32)ipa_ctx->mmio + 0x4000 + ofst_ipa_sram);
-}
-
-/**
- * ipa_write_dev_32() - writes 32 bit value
- * @val: value
- * @ofst_ipa_sram: address to write to
- */
-void ipa_write_dev_32(u32 val, u16 ofst_ipa_sram)
-{
-	iowrite32(val, (u32)ipa_ctx->mmio + 0x4000 + ofst_ipa_sram);
-}
-
-/**
- * ipa_read_dev_8() - reads 8 bit value
- * @ofst_ipa_sram: address to read from
- *
- * Return value: value read
- */
-unsigned int ipa_read_dev_8(u16 ofst_ipa_sram)
-{
-	return ioread8((u32)ipa_ctx->mmio + 0x4000 + ofst_ipa_sram);
-}
-
-/**
- * ipa_read_dev_16() - reads 16 bit value
- * @ofst_ipa_sram: address to read from
- *
- * Return value: value read
- */
-unsigned int ipa_read_dev_16(u16 ofst_ipa_sram)
-{
-	return ioread16((u32)ipa_ctx->mmio + 0x4000 + ofst_ipa_sram);
-}
-
-/**
- * ipa_read_dev_32() - reads 32 bit value
- * @ofst_ipa_sram: address to read from
- *
- * Return value: value read
- */
-unsigned int ipa_read_dev_32(u16 ofst_ipa_sram)
-{
-	return ioread32((u32)ipa_ctx->mmio + 0x4000 + ofst_ipa_sram);
-}
-
-/**
- * ipa_write_dev_8rep() - writes 8 bit value
- * @val: value
- * @ofst_ipa_sram: address to write to
- * @count: num of bytes to write
- */
-void ipa_write_dev_8rep(u16 ofst_ipa_sram, const void *buf, unsigned long count)
-{
-	iowrite8_rep((void *)((u32)ipa_ctx->mmio + 0x4000 + ofst_ipa_sram), buf,
-			count);
-}
-
-/**
- * ipa_write_dev_16rep() - writes 16 bit value
- * @val: value
- * @ofst_ipa_sram: address to write to
- * @count: num of bytes to write
- */
-void ipa_write_dev_16rep(u16 ofst_ipa_sram, const void *buf,
-		unsigned long count)
-{
-	iowrite16_rep((void *)((u32)ipa_ctx->mmio + 0x4000 + ofst_ipa_sram),
-			buf, count);
-}
-
-/**
- * ipa_write_dev_32rep() - writes 32 bit value
- * @val: value
- * @ofst_ipa_sram: address to write to
- * @count: num of bytes to write
- */
-void ipa_write_dev_32rep(u16 ofst_ipa_sram, const void *buf,
-		unsigned long count)
-{
-	iowrite32_rep((void *)((u32)ipa_ctx->mmio + 0x4000 + ofst_ipa_sram),
-			buf, count);
-}
-
-/**
- * ipa_read_dev_8rep() - reads 8 bit value
- * @ofst_ipa_sram: address to read from
- * @buf: buffer to read to
- * @count: number of bytes to read
- */
-void ipa_read_dev_8rep(u16 ofst_ipa_sram, void *buf, unsigned long count)
-{
-	ioread8_rep((void *)((u32)ipa_ctx->mmio + 0x4000 + ofst_ipa_sram), buf,
-			count);
-}
-
-/**
- * ipa_read_dev_16rep() - reads 16 bit value
- * @ofst_ipa_sram: address to read from
- * @buf: buffer to read to
- * @count: number of bytes to read
- */
-void ipa_read_dev_16rep(u16 ofst_ipa_sram, void *buf, unsigned long count)
-{
-	ioread16_rep((void *)((u32)ipa_ctx->mmio + 0x4000 + ofst_ipa_sram), buf,
-			count);
-}
-
-/**
- * ipa_read_dev_32rep() - reads 32 bit value
- * @ofst_ipa_sram: address to read from
- * @buf: buffer to read to
- * @count: number of bytes to read
- */
-void ipa_read_dev_32rep(u16 ofst_ipa_sram, void *buf, unsigned long count)
-{
-	ioread32_rep((void *)((u32)ipa_ctx->mmio + 0x4000 + ofst_ipa_sram), buf,
-			count);
-}
-
-/**
- * ipa_memset_dev() - memset IO
- * @ofst_ipa_sram: address to set
- * @value: value
- * @count: number of bytes to set
- */
-void ipa_memset_dev(u16 ofst_ipa_sram, u8 value, unsigned int count)
-{
-	memset_io((void *)((u32)ipa_ctx->mmio + 0x4000 + ofst_ipa_sram), value,
-			count);
-}
-
-/**
- * ipa_memcpy_from_dev() - copy memory from device
- * @dest: buffer to copy to
- * @ofst_ipa_sram: address
- * @count: number of bytes to copy
- */
-void ipa_memcpy_from_dev(void *dest, u16 ofst_ipa_sram, unsigned int count)
-{
-	memcpy_fromio(dest, (void *)((u32)ipa_ctx->mmio + 0x4000 +
-				ofst_ipa_sram), count);
-}
-
-/**
- * ipa_memcpy_to_dev() - copy memory to device
- * @ofst_ipa_sram: address
- * @source: buffer to copy from
- * @count: number of bytes to copy
- */
-void ipa_memcpy_to_dev(u16 ofst_ipa_sram, void *source, unsigned int count)
-{
-	memcpy_toio((void *)((u32)ipa_ctx->mmio + 0x4000 + ofst_ipa_sram),
-			source, count);
-}
-
-/**
- * ipa_defrag() - handle de-frag for bridging type of cases
- * @skb: skb
- *
- * Return value:
- * 0: success
- */
-int ipa_defrag(struct sk_buff *skb)
-{
-	/*
-	 * Reassemble IP fragments. TODO: need to setup network_header to
-	 * point to start of IP header
-	 */
-	if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
-		if (ip_defrag(skb, IP_DEFRAG_CONNTRACK_IN))
-			return -EINPROGRESS;
-	}
-
-	/* skb is not fully assembled, send it back out */
-	return 0;
-}
-
 /**
  * ipa_search() - search for handle in RB tree
  * @root: tree root
@@ -1267,11 +1133,21 @@
 int ipa_set_aggr_mode(enum ipa_aggr_mode mode)
 {
 	u32 reg_val;
-	reg_val = ipa_read_reg(ipa_ctx->mmio, IPA_AGGREGATION_SPARE_REG_2_OFST);
-	ipa_write_reg(ipa_ctx->mmio, IPA_AGGREGATION_SPARE_REG_2_OFST,
-			((mode & IPA_AGGREGATION_MODE_MSK) <<
-				IPA_AGGREGATION_MODE_SHFT) |
-			(reg_val & IPA_AGGREGATION_MODE_BMSK));
+
+	if (ipa_ctx->ipa_hw_type == IPA_HW_v1_0) {
+		reg_val = ipa_read_reg(ipa_ctx->mmio,
+				IPA_AGGREGATION_SPARE_REG_2_OFST);
+		ipa_write_reg(ipa_ctx->mmio,
+				IPA_AGGREGATION_SPARE_REG_2_OFST,
+				((mode & IPA_AGGREGATION_MODE_MSK) <<
+					IPA_AGGREGATION_MODE_SHFT) |
+					(reg_val & IPA_AGGREGATION_MODE_BMSK));
+	} else {
+		reg_val = ipa_read_reg(ipa_ctx->mmio, IPA_QCNCM_OFST);
+		ipa_write_reg(ipa_ctx->mmio, IPA_QCNCM_OFST, (mode & 0x1) |
+				(reg_val & 0xfffffffe));
+
+	}
 	return 0;
 }
 EXPORT_SYMBOL(ipa_set_aggr_mode);
@@ -1291,15 +1167,25 @@
 {
 	u32 reg_val;
 
-	if (sig == NULL) {
-		IPAERR("bad argument for ipa_set_qcncm_ndp_sig/n");
-		return -EINVAL;
+	if (ipa_ctx->ipa_hw_type == IPA_HW_v1_0) {
+		if (sig == NULL) {
+			IPAERR("bad argument for ipa_set_qcncm_ndp_sig/n");
+			return -EINVAL;
+		}
+		reg_val = ipa_read_reg(ipa_ctx->mmio,
+				IPA_AGGREGATION_SPARE_REG_2_OFST);
+		ipa_write_reg(ipa_ctx->mmio,
+				IPA_AGGREGATION_SPARE_REG_2_OFST, sig[0] <<
+				IPA_AGGREGATION_QCNCM_SIG0_SHFT |
+				(sig[1] << IPA_AGGREGATION_QCNCM_SIG1_SHFT) |
+				sig[2] |
+				(reg_val & IPA_AGGREGATION_QCNCM_SIG_BMSK));
+	} else {
+		reg_val = ipa_read_reg(ipa_ctx->mmio, IPA_QCNCM_OFST);
+		ipa_write_reg(ipa_ctx->mmio, IPA_QCNCM_OFST, sig[0] << 20 |
+				(sig[1] << 12) | (sig[2] << 4) |
+				(reg_val & 0xf000000f));
 	}
-	reg_val = ipa_read_reg(ipa_ctx->mmio, IPA_AGGREGATION_SPARE_REG_2_OFST);
-	ipa_write_reg(ipa_ctx->mmio, IPA_AGGREGATION_SPARE_REG_2_OFST, sig[0] <<
-			IPA_AGGREGATION_QCNCM_SIG0_SHFT |
-			(sig[1] << IPA_AGGREGATION_QCNCM_SIG1_SHFT) |
-			sig[2] | (reg_val & IPA_AGGREGATION_QCNCM_SIG_BMSK));
 	return 0;
 }
 EXPORT_SYMBOL(ipa_set_qcncm_ndp_sig);
@@ -1314,15 +1200,42 @@
 int ipa_set_single_ndp_per_mbim(bool enable)
 {
 	u32 reg_val;
-	reg_val = ipa_read_reg(ipa_ctx->mmio, IPA_AGGREGATION_SPARE_REG_1_OFST);
-	ipa_write_reg(ipa_ctx->mmio, IPA_AGGREGATION_SPARE_REG_1_OFST, (enable &
-			IPA_AGGREGATION_SINGLE_NDP_MSK) |
-			(reg_val & IPA_AGGREGATION_SINGLE_NDP_BMSK));
+
+	if (ipa_ctx->ipa_hw_type == IPA_HW_v1_0) {
+		reg_val = ipa_read_reg(ipa_ctx->mmio,
+				IPA_AGGREGATION_SPARE_REG_1_OFST);
+		ipa_write_reg(ipa_ctx->mmio,
+				IPA_AGGREGATION_SPARE_REG_1_OFST, (enable &
+				IPA_AGGREGATION_SINGLE_NDP_MSK) |
+				(reg_val & IPA_AGGREGATION_SINGLE_NDP_BMSK));
+	} else {
+		reg_val = ipa_read_reg(ipa_ctx->mmio, IPA_SINGLE_NDP_MODE_OFST);
+		ipa_write_reg(ipa_ctx->mmio, IPA_SINGLE_NDP_MODE_OFST,
+				(enable & 0x1) | (reg_val & 0xfffffffe));
+	}
 	return 0;
 }
 EXPORT_SYMBOL(ipa_set_single_ndp_per_mbim);
 
 /**
+ * ipa_set_hw_timer_fix_for_mbim_aggr() - Enable/disable HW timer fix
+ * for MBIM aggregation.
+ * @enable:	[in] true for enable HW fix; false otherwise
+ *
+ * Returns:	0 on success
+ */
+int ipa_set_hw_timer_fix_for_mbim_aggr(bool enable)
+{
+	u32 reg_val;
+	reg_val = ipa_read_reg(ipa_ctx->mmio, IPA_AGGREGATION_SPARE_REG_1_OFST);
+	ipa_write_reg(ipa_ctx->mmio, IPA_AGGREGATION_SPARE_REG_1_OFST,
+		(enable << IPA_AGGREGATION_HW_TIMER_FIX_MBIM_AGGR_SHFT) |
+		(reg_val & ~IPA_AGGREGATION_HW_TIMER_FIX_MBIM_AGGR_BMSK));
+	return 0;
+}
+EXPORT_SYMBOL(ipa_set_hw_timer_fix_for_mbim_aggr);
+
+/**
  * ipa_straddle_boundary() - Checks whether a memory buffer straddles a boundary
  * @start: start address of the memory buffer
  * @end: end address of the memory buffer
diff --git a/drivers/platform/msm/ipa/rmnet_bridge.c b/drivers/platform/msm/ipa/rmnet_bridge.c
index 3c7f5ca..696b363 100644
--- a/drivers/platform/msm/ipa/rmnet_bridge.c
+++ b/drivers/platform/msm/ipa/rmnet_bridge.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
@@ -16,12 +16,12 @@
 #include <mach/bam_dmux.h>
 #include <mach/ipa.h>
 #include <mach/sps.h>
-#include "a2_service.h"
-#include "ipa_i.h"
 
 static struct rmnet_bridge_cb_type {
 	u32 producer_handle;
 	u32 consumer_handle;
+	u32 ipa_producer_handle;
+	u32 ipa_consumer_handle;
 	bool is_connected;
 } rmnet_bridge_cb;
 
@@ -57,8 +57,10 @@
 
 	rmnet_bridge_cb.is_connected = false;
 
-	ret = ipa_bridge_teardown(IPA_DL);
-	ret = ipa_bridge_teardown(IPA_UL);
+	ret = ipa_bridge_teardown(IPA_BRIDGE_DIR_DL, IPA_BRIDGE_TYPE_TETHERED,
+				  rmnet_bridge_cb.ipa_consumer_handle);
+	ret = ipa_bridge_teardown(IPA_BRIDGE_DIR_UL, IPA_BRIDGE_TYPE_TETHERED,
+				  rmnet_bridge_cb.ipa_producer_handle);
 bail:
 	return ret;
 }
@@ -78,6 +80,7 @@
 			 u32 consumer_hdl,
 			 int wwan_logical_channel_id)
 {
+	struct ipa_sys_connect_params props;
 	int ret = 0;
 
 	if (true == rmnet_bridge_cb.is_connected) {
@@ -91,19 +94,35 @@
 	rmnet_bridge_cb.producer_handle = producer_hdl;
 	rmnet_bridge_cb.is_connected = true;
 
-	ret = ipa_bridge_setup(IPA_DL);
+	memset(&props, 0, sizeof(props));
+	props.ipa_ep_cfg.mode.mode = IPA_DMA;
+	props.ipa_ep_cfg.mode.dst = IPA_CLIENT_USB_CONS;
+	props.client = IPA_CLIENT_A2_TETHERED_PROD;
+	props.desc_fifo_sz = 0x800;
+	/* setup notification callback if needed */
+
+	ret = ipa_bridge_setup(IPA_BRIDGE_DIR_DL, IPA_BRIDGE_TYPE_TETHERED,
+			&props, &rmnet_bridge_cb.ipa_consumer_handle);
 	if (ret) {
 		pr_err("%s: IPA DL bridge setup failure\n", __func__);
 		goto bail_dl;
 	}
-	ret = ipa_bridge_setup(IPA_UL);
+
+	memset(&props, 0, sizeof(props));
+	props.client = IPA_CLIENT_A2_TETHERED_CONS;
+	props.desc_fifo_sz = 0x800;
+	/* setup notification callback if needed */
+
+	ret = ipa_bridge_setup(IPA_BRIDGE_DIR_UL, IPA_BRIDGE_TYPE_TETHERED,
+			&props, &rmnet_bridge_cb.ipa_producer_handle);
 	if (ret) {
 		pr_err("%s: IPA UL bridge setup failure\n", __func__);
 		goto bail_ul;
 	}
 	return 0;
 bail_ul:
-	ipa_bridge_teardown(IPA_DL);
+	ipa_bridge_teardown(IPA_BRIDGE_DIR_DL, IPA_BRIDGE_TYPE_TETHERED,
+			    rmnet_bridge_cb.ipa_consumer_handle);
 bail_dl:
 	rmnet_bridge_cb.is_connected = false;
 bail:
diff --git a/drivers/platform/msm/ipa/teth_bridge.c b/drivers/platform/msm/ipa/teth_bridge.c
new file mode 100644
index 0000000..76e2eee
--- /dev/null
+++ b/drivers/platform/msm/ipa/teth_bridge.c
@@ -0,0 +1,1483 @@
+/* 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/completion.h>
+#include <linux/debugfs.h>
+#include <linux/export.h>
+#include <linux/fs.h>
+#include <linux/if_ether.h>
+#include <linux/ioctl.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/msm_ipa.h>
+#include <linux/mutex.h>
+#include <linux/skbuff.h>
+#include <linux/types.h>
+#include <mach/bam_dmux.h>
+#include <mach/ipa.h>
+#include <mach/sps.h>
+#include "ipa_i.h"
+
+#define TETH_BRIDGE_DRV_NAME "ipa_tethering_bridge"
+
+#ifdef TETH_DEBUG
+#define TETH_DBG(fmt, args...) \
+	pr_debug(TETH_BRIDGE_DRV_NAME " %s:%d " fmt, \
+		 __func__, __LINE__, ## args)
+#define TETH_DBG_FUNC_ENTRY() \
+	pr_debug(TETH_BRIDGE_DRV_NAME " %s:%d ENTRY\n", __func__, __LINE__)
+#define TETH_DBG_FUNC_EXIT() \
+	pr_debug(TETH_BRIDGE_DRV_NAME " %s:%d EXIT\n", __func__, __LINE__)
+#else
+#define TETH_DBG(fmt, args...)
+#define TETH_DBG_FUNC_ENTRY()
+#define TETH_DBG_FUNC_EXIT()
+#endif
+
+#define TETH_ERR(fmt, args...) \
+	pr_err(TETH_BRIDGE_DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)
+
+#define USB_ETH_HDR_NAME_IPV4 "usb_bridge_ipv4"
+#define USB_ETH_HDR_NAME_IPV6 "usb_bridge_ipv6"
+#define A2_ETH_HDR_NAME_IPV4  "a2_bridge_ipv4"
+#define A2_ETH_HDR_NAME_IPV6  "a2_bridge_ipv6"
+
+#define USB_TO_A2_RT_TBL_NAME_IPV4 "usb_a2_rt_tbl_ipv4"
+#define A2_TO_USB_RT_TBL_NAME_IPV4 "a2_usb_rt_tbl_ipv4"
+#define USB_TO_A2_RT_TBL_NAME_IPV6 "usb_a2_rt_tbl_ipv6"
+#define A2_TO_USB_RT_TBL_NAME_IPV6 "a2_usb_rt_tbl_ipv6"
+
+#define MBIM_HEADER_NAME "mbim_header"
+#define TETH_DEFAULT_AGGR_TIME_LIMIT 1
+
+#define ETHERTYPE_IPV4 0x0800
+#define ETHERTYPE_IPV6 0x86DD
+
+struct mac_addresses_type {
+	u8 host_pc_mac_addr[ETH_ALEN];
+	bool host_pc_mac_addr_known;
+	u8 device_mac_addr[ETH_ALEN];
+	bool device_mac_addr_known;
+};
+
+struct teth_bridge_ctx {
+	struct class *class;
+	dev_t dev_num;
+	struct device *dev;
+	struct cdev cdev;
+	u32 usb_ipa_pipe_hdl;
+	u32 ipa_usb_pipe_hdl;
+	u32 a2_ipa_pipe_hdl;
+	u32 ipa_a2_pipe_hdl;
+	bool is_connected;
+	enum teth_link_protocol_type link_protocol;
+	struct mac_addresses_type mac_addresses;
+	bool is_hw_bridge_complete;
+	struct teth_aggr_params aggr_params;
+	bool aggr_params_known;
+	enum teth_tethering_mode tethering_mode;
+	struct completion is_bridge_prod_up;
+	struct completion is_bridge_prod_down;
+	struct work_struct comp_hw_bridge_work;
+	bool comp_hw_bridge_in_progress;
+	struct teth_aggr_capabilities *aggr_caps;
+};
+
+static struct teth_bridge_ctx *teth_ctx;
+
+#ifdef CONFIG_DEBUG_FS
+#define TETH_MAX_MSG_LEN 512
+static char dbg_buff[TETH_MAX_MSG_LEN];
+#endif
+
+static int add_eth_hdrs(char *hdr_name_ipv4, char *hdr_name_ipv6,
+			u8 *src_mac_addr, u8 *dst_mac_addr)
+{
+	int res;
+	struct ipa_ioc_add_hdr *hdrs;
+	struct ethhdr hdr_ipv4;
+	struct ethhdr hdr_ipv6;
+
+	TETH_DBG_FUNC_ENTRY();
+	memcpy(hdr_ipv4.h_source, src_mac_addr, ETH_ALEN);
+	memcpy(hdr_ipv4.h_dest, dst_mac_addr, ETH_ALEN);
+	hdr_ipv4.h_proto = htons(ETHERTYPE_IPV4);
+
+	memcpy(hdr_ipv6.h_source, src_mac_addr, ETH_ALEN);
+	memcpy(hdr_ipv6.h_dest, dst_mac_addr, ETH_ALEN);
+	hdr_ipv6.h_proto = htons(ETHERTYPE_IPV6);
+
+	/* Add headers to the header insertion tables */
+	hdrs = kzalloc(sizeof(struct ipa_ioc_add_hdr) +
+		       2 * sizeof(struct ipa_hdr_add), GFP_KERNEL);
+	if (hdrs == NULL) {
+		TETH_ERR("Failed allocating memory for headers !\n");
+		return -ENOMEM;
+	}
+
+	hdrs->commit = 0;
+	hdrs->num_hdrs = 2;
+
+	/* Ethernet IPv4 header */
+	strlcpy(hdrs->hdr[0].name, hdr_name_ipv4, IPA_RESOURCE_NAME_MAX);
+	hdrs->hdr[0].hdr_len = ETH_HLEN;
+	memcpy(hdrs->hdr[0].hdr, &hdr_ipv4, ETH_HLEN);
+
+	/* Ethernet IPv6 header */
+	strlcpy(hdrs->hdr[1].name, hdr_name_ipv6, IPA_RESOURCE_NAME_MAX);
+	hdrs->hdr[1].hdr_len = ETH_HLEN;
+	memcpy(hdrs->hdr[1].hdr, &hdr_ipv6, ETH_HLEN);
+
+	res = ipa_add_hdr(hdrs);
+	if (res || hdrs->hdr[0].status || hdrs->hdr[1].status)
+		TETH_ERR("Header insertion failed\n");
+	kfree(hdrs);
+	TETH_DBG_FUNC_EXIT();
+
+	return res;
+}
+
+static int configure_ipa_header_block_internal(u32 usb_ipa_hdr_len,
+					       u32 a2_ipa_hdr_len,
+					       u32 ipa_usb_hdr_len,
+					       u32 ipa_a2_hdr_len)
+{
+	struct ipa_ep_cfg_hdr hdr_cfg;
+	int res;
+
+	TETH_DBG_FUNC_ENTRY();
+	/* Configure header removal for the USB->IPA pipe and A2->IPA pipe */
+	memset(&hdr_cfg, 0, sizeof(hdr_cfg));
+	hdr_cfg.hdr_len = usb_ipa_hdr_len;
+	res = ipa_cfg_ep_hdr(teth_ctx->usb_ipa_pipe_hdl, &hdr_cfg);
+	if (res) {
+		TETH_ERR("Header removal config for USB->IPA pipe failed\n");
+		goto bail;
+	}
+
+	hdr_cfg.hdr_len = a2_ipa_hdr_len;
+	res = ipa_cfg_ep_hdr(teth_ctx->a2_ipa_pipe_hdl, &hdr_cfg);
+	if (res) {
+		TETH_ERR("Header removal config for A2->IPA pipe failed\n");
+		goto bail;
+	}
+
+	/* Configure header insertion for the IPA->USB pipe and IPA->A2 pipe */
+	hdr_cfg.hdr_len = ipa_usb_hdr_len;
+	res = ipa_cfg_ep_hdr(teth_ctx->ipa_usb_pipe_hdl, &hdr_cfg);
+	if (res) {
+		TETH_ERR("Header insertion config for IPA->USB pipe failed\n");
+		goto bail;
+	}
+
+	hdr_cfg.hdr_len = ipa_a2_hdr_len;
+	res = ipa_cfg_ep_hdr(teth_ctx->ipa_a2_pipe_hdl, &hdr_cfg);
+	if (res) {
+		TETH_ERR("Header insertion config for IPA->A2 pipe failed\n");
+		goto bail;
+	}
+	TETH_DBG_FUNC_EXIT();
+
+bail:
+	return res;
+}
+
+static int add_mbim_hdr(void)
+{
+	int res;
+	struct ipa_ioc_add_hdr *mbim_hdr;
+	u8 mbim_stream_id = 0;
+
+	TETH_DBG_FUNC_ENTRY();
+	mbim_hdr = kzalloc(sizeof(struct ipa_ioc_add_hdr) +
+			   sizeof(struct ipa_hdr_add),
+			   GFP_KERNEL);
+	if (!mbim_hdr) {
+		TETH_ERR("Failed allocating memory for MBIM header\n");
+		return -ENOMEM;
+	}
+
+	mbim_hdr->commit = 0;
+	mbim_hdr->num_hdrs = 1;
+	strlcpy(mbim_hdr->hdr[0].name, MBIM_HEADER_NAME, IPA_RESOURCE_NAME_MAX);
+	memcpy(mbim_hdr->hdr[0].hdr, &mbim_stream_id, sizeof(u8));
+	mbim_hdr->hdr[0].hdr_len = sizeof(u8);
+	mbim_hdr->hdr[0].is_partial = false;
+	res = ipa_add_hdr(mbim_hdr);
+	if (res || mbim_hdr->hdr[0].status) {
+		TETH_ERR("Failed adding MBIM header\n");
+		res = -EFAULT;
+	} else {
+		TETH_DBG("Added MBIM stream ID header\n");
+	}
+	kfree(mbim_hdr);
+	TETH_DBG_FUNC_EXIT();
+
+	return res;
+}
+
+static int configure_ipa_header_block(void)
+{
+	int res;
+	u32 hdr_len = 0;
+	u32 ipa_usb_hdr_len = 0;
+
+	TETH_DBG_FUNC_ENTRY();
+	if (teth_ctx->link_protocol == TETH_LINK_PROTOCOL_IP) {
+		/*
+		 * Create a new header for MBIM stream ID and associate it with
+		 * the IPA->USB routing table
+		 */
+		if (teth_ctx->aggr_params.dl.aggr_prot ==
+					TETH_AGGR_PROTOCOL_MBIM) {
+			ipa_usb_hdr_len = 1;
+			res = add_mbim_hdr();
+			if (res) {
+				TETH_ERR("Failed adding MBIM header\n");
+				goto bail;
+			}
+		}
+	} else if (teth_ctx->link_protocol == TETH_LINK_PROTOCOL_ETHERNET) {
+		/* Add a header entry for USB */
+		res = add_eth_hdrs(USB_ETH_HDR_NAME_IPV4,
+				   USB_ETH_HDR_NAME_IPV6,
+				   teth_ctx->mac_addresses.host_pc_mac_addr,
+				   teth_ctx->mac_addresses.device_mac_addr);
+		if (res) {
+			TETH_ERR("Failed adding USB Ethernet header\n");
+			goto bail;
+		}
+		TETH_DBG("Added USB Ethernet headers (IPv4 / IPv6)\n");
+
+		/* Add a header entry for A2 */
+		res = add_eth_hdrs(A2_ETH_HDR_NAME_IPV4,
+				   A2_ETH_HDR_NAME_IPV6,
+				   teth_ctx->mac_addresses.device_mac_addr,
+				   teth_ctx->mac_addresses.host_pc_mac_addr);
+		if (res) {
+			TETH_ERR("Failed adding A2 Ethernet header\n");
+			goto bail;
+		}
+		TETH_DBG("Added A2 Ethernet headers (IPv4 / IPv6\n");
+
+		hdr_len = ETH_HLEN;
+		ipa_usb_hdr_len = ETH_HLEN;
+	}
+
+	res = configure_ipa_header_block_internal(hdr_len,
+						  hdr_len,
+						  ipa_usb_hdr_len,
+						  hdr_len);
+	if (res) {
+		TETH_ERR("Configuration of header removal/insertion failed\n");
+		goto bail;
+	}
+
+	res = ipa_commit_hdr();
+	if (res) {
+		TETH_ERR("Failed committing headers\n");
+		goto bail;
+	}
+	TETH_DBG_FUNC_EXIT();
+
+bail:
+	return res;
+}
+
+static int configure_routing_by_ip(char *hdr_name,
+			    char *rt_tbl_name,
+			    enum ipa_client_type dst,
+			    enum ipa_ip_type ip_address_family)
+{
+
+	struct ipa_ioc_add_rt_rule *rt_rule;
+	struct ipa_ioc_get_hdr hdr_info;
+	int res;
+
+	TETH_DBG_FUNC_ENTRY();
+	/* Get the header handle */
+	memset(&hdr_info, 0, sizeof(hdr_info));
+	strlcpy(hdr_info.name, hdr_name, IPA_RESOURCE_NAME_MAX);
+	ipa_get_hdr(&hdr_info);
+
+	rt_rule = kzalloc(sizeof(struct ipa_ioc_add_rt_rule) +
+			  1 * sizeof(struct ipa_rt_rule_add),
+			  GFP_KERNEL);
+	if (!rt_rule) {
+		TETH_ERR("Memory allocation failure");
+		return -ENOMEM;
+	}
+
+	/* Match all, do not commit to HW*/
+	rt_rule->commit = 0;
+	rt_rule->num_rules = 1;
+	rt_rule->ip = ip_address_family;
+	strlcpy(rt_rule->rt_tbl_name, rt_tbl_name, IPA_RESOURCE_NAME_MAX);
+	rt_rule->rules[0].rule.dst = dst;
+	rt_rule->rules[0].rule.hdr_hdl = hdr_info.hdl;
+	rt_rule->rules[0].rule.attrib.attrib_mask = 0; /* Match all */
+	res = ipa_add_rt_rule(rt_rule);
+	if (res || rt_rule->rules[0].status)
+		TETH_ERR("Failed adding routing rule\n");
+	kfree(rt_rule);
+	TETH_DBG_FUNC_EXIT();
+
+	return res;
+}
+
+static int configure_routing(char *hdr_name_ipv4,
+			     char *rt_tbl_name_ipv4,
+			     char *hdr_name_ipv6,
+			     char *rt_tbl_name_ipv6,
+			     enum ipa_client_type dst)
+{
+	int res;
+
+	TETH_DBG_FUNC_ENTRY();
+	/* Configure IPv4 routing table */
+	res = configure_routing_by_ip(hdr_name_ipv4,
+				      rt_tbl_name_ipv4,
+				      dst,
+				      IPA_IP_v4);
+	if (res) {
+		TETH_ERR("Failed adding IPv4 routing table\n");
+		goto bail;
+	}
+
+	/* Configure IPv6 routing table */
+	res = configure_routing_by_ip(hdr_name_ipv6,
+				      rt_tbl_name_ipv6,
+				      dst,
+				      IPA_IP_v6);
+	if (res) {
+		TETH_ERR("Failed adding IPv6 routing table\n");
+		goto bail;
+	}
+	TETH_DBG_FUNC_EXIT();
+
+bail:
+	return res;
+}
+
+static int configure_ipa_routing_block(void)
+{
+	int res;
+	char hdr_name_ipv4[IPA_RESOURCE_NAME_MAX];
+	char hdr_name_ipv6[IPA_RESOURCE_NAME_MAX];
+
+	TETH_DBG_FUNC_ENTRY();
+	hdr_name_ipv4[0] = '\0';
+	hdr_name_ipv6[0] = '\0';
+
+	/* Configure USB -> A2 routing table */
+	if (teth_ctx->link_protocol == TETH_LINK_PROTOCOL_ETHERNET) {
+		strlcpy(hdr_name_ipv4,
+			A2_ETH_HDR_NAME_IPV4,
+			IPA_RESOURCE_NAME_MAX);
+		strlcpy(hdr_name_ipv6,
+			A2_ETH_HDR_NAME_IPV6,
+			IPA_RESOURCE_NAME_MAX);
+	}
+	res = configure_routing(hdr_name_ipv4,
+				USB_TO_A2_RT_TBL_NAME_IPV4,
+				hdr_name_ipv6,
+				USB_TO_A2_RT_TBL_NAME_IPV6,
+				IPA_CLIENT_A2_TETHERED_CONS);
+	if (res) {
+		TETH_ERR("USB to A2 routing block configuration failed\n");
+		goto bail;
+	}
+
+	/* Configure A2 -> USB routing table */
+	if (teth_ctx->link_protocol == TETH_LINK_PROTOCOL_ETHERNET) {
+		strlcpy(hdr_name_ipv4,
+			USB_ETH_HDR_NAME_IPV4,
+			IPA_RESOURCE_NAME_MAX);
+		strlcpy(hdr_name_ipv6,
+			USB_ETH_HDR_NAME_IPV6,
+			IPA_RESOURCE_NAME_MAX);
+	} else if (teth_ctx->aggr_params.dl.aggr_prot ==
+						TETH_AGGR_PROTOCOL_MBIM) {
+		strlcpy(hdr_name_ipv4,
+			MBIM_HEADER_NAME,
+			IPA_RESOURCE_NAME_MAX);
+		strlcpy(hdr_name_ipv6,
+			MBIM_HEADER_NAME,
+			IPA_RESOURCE_NAME_MAX);
+	}
+	res = configure_routing(hdr_name_ipv4,
+				A2_TO_USB_RT_TBL_NAME_IPV4,
+				hdr_name_ipv6,
+				A2_TO_USB_RT_TBL_NAME_IPV6,
+				IPA_CLIENT_USB_CONS);
+	if (res) {
+		TETH_ERR("A2 to USB routing block configuration failed\n");
+		goto bail;
+	}
+
+	/* Commit all the changes to HW in one shot */
+	res = ipa_commit_rt(IPA_IP_v4);
+	if (res) {
+		TETH_ERR("Failed commiting IPv4 routing tables\n");
+		goto bail;
+	}
+	res = ipa_commit_rt(IPA_IP_v6);
+	if (res) {
+		TETH_ERR("Failed commiting IPv6 routing tables\n");
+		goto bail;
+	}
+	TETH_DBG_FUNC_EXIT();
+
+bail:
+	return res;
+}
+
+static int configure_filtering_by_ip(char *rt_tbl_name,
+			      enum ipa_client_type src,
+			      enum ipa_ip_type ip_address_family)
+{
+	struct ipa_ioc_add_flt_rule *flt_tbl;
+	struct ipa_ioc_get_rt_tbl rt_tbl_info;
+	int res;
+
+	TETH_DBG_FUNC_ENTRY();
+	/* Get the needed routing table handle */
+	rt_tbl_info.ip = ip_address_family;
+	strlcpy(rt_tbl_info.name, rt_tbl_name, IPA_RESOURCE_NAME_MAX);
+	res = ipa_get_rt_tbl(&rt_tbl_info);
+	if (res) {
+		TETH_ERR("Failed getting routing table handle\n");
+		goto bail;
+	}
+
+	flt_tbl = kzalloc(sizeof(struct ipa_ioc_add_flt_rule) +
+			  1 * sizeof(struct ipa_flt_rule_add), GFP_KERNEL);
+	if (!flt_tbl) {
+		TETH_ERR("Filtering table memory allocation failure\n");
+		return -ENOMEM;
+	}
+
+	flt_tbl->commit = 0;
+	flt_tbl->ep = src;
+	flt_tbl->global = 0;
+	flt_tbl->ip = ip_address_family;
+	flt_tbl->num_rules = 1;
+	flt_tbl->rules[0].rule.action = IPA_PASS_TO_ROUTING;
+	flt_tbl->rules[0].rule.rt_tbl_hdl = rt_tbl_info.hdl;
+	flt_tbl->rules[0].rule.attrib.attrib_mask = 0; /* Match all */
+
+	res = ipa_add_flt_rule(flt_tbl);
+	if (res || flt_tbl->rules[0].status)
+		TETH_ERR("Failed adding filtering table\n");
+	kfree(flt_tbl);
+	TETH_DBG_FUNC_EXIT();
+
+bail:
+	return res;
+}
+
+static int configure_filtering(char *rt_tbl_name_ipv4,
+			char *rt_tbl_name_ipv6,
+			enum ipa_client_type src)
+{
+	int res;
+
+	TETH_DBG_FUNC_ENTRY();
+	res = configure_filtering_by_ip(rt_tbl_name_ipv4, src, IPA_IP_v4);
+	if (res) {
+		TETH_ERR("Failed adding IPv4 filtering table\n");
+		goto bail;
+	}
+
+	res = configure_filtering_by_ip(rt_tbl_name_ipv6, src, IPA_IP_v6);
+	if (res) {
+		TETH_ERR("Failed adding IPv4 filtering table\n");
+		goto bail;
+	}
+	TETH_DBG_FUNC_EXIT();
+
+bail:
+	return res;
+}
+
+static int configure_ipa_filtering_block(void)
+{
+	int res;
+
+	TETH_DBG_FUNC_ENTRY();
+	/* Filter all traffic coming from USB to A2 */
+	res = configure_filtering(USB_TO_A2_RT_TBL_NAME_IPV4,
+				  USB_TO_A2_RT_TBL_NAME_IPV6,
+				  IPA_CLIENT_USB_PROD);
+	if (res) {
+		TETH_ERR("USB_PROD ep filtering configuration failed\n");
+		goto bail;
+	}
+
+	/* Filter all traffic coming from A2 to USB */
+	res = configure_filtering(A2_TO_USB_RT_TBL_NAME_IPV4,
+				  A2_TO_USB_RT_TBL_NAME_IPV6,
+				  IPA_CLIENT_A2_TETHERED_PROD);
+	if (res) {
+		TETH_ERR("A2_PROD filtering configuration failed\n");
+		goto bail;
+	}
+
+	/* Commit all the changes to HW in one shot */
+	res = ipa_commit_flt(IPA_IP_v4);
+	if (res) {
+		TETH_ERR("Failed commiting IPv4 filtering tables\n");
+		goto bail;
+	}
+	res = ipa_commit_flt(IPA_IP_v6);
+	if (res) {
+		TETH_ERR("Failed commiting IPv6 filtering tables\n");
+		goto bail;
+	}
+	TETH_DBG_FUNC_EXIT();
+
+bail:
+	return res;
+}
+
+static int prepare_ipa_aggr_struct(
+	const struct teth_aggr_params_link *teth_aggr_params,
+	struct ipa_ep_cfg_aggr *ipa_aggr_params,
+	bool client_is_prod)
+{
+	TETH_DBG_FUNC_ENTRY();
+	memset(ipa_aggr_params, 0, sizeof(*ipa_aggr_params));
+
+	switch (teth_aggr_params->aggr_prot) {
+	case TETH_AGGR_PROTOCOL_NONE:
+		ipa_aggr_params->aggr_en = IPA_BYPASS_AGGR;
+		break;
+	case TETH_AGGR_PROTOCOL_MBIM:
+		 ipa_aggr_params->aggr = IPA_MBIM_16;
+		 ipa_aggr_params->aggr_en = (client_is_prod) ?
+			 IPA_ENABLE_DEAGGR : IPA_ENABLE_AGGR;
+		 break;
+	case TETH_AGGR_PROTOCOL_TLP:
+		ipa_aggr_params->aggr = IPA_TLP;
+		ipa_aggr_params->aggr_en = (client_is_prod) ?
+			IPA_ENABLE_DEAGGR : IPA_ENABLE_AGGR;
+		break;
+	default:
+		TETH_ERR("Unsupported aggregation protocol\n");
+		return -EFAULT;
+	}
+
+	ipa_aggr_params->aggr_byte_limit =
+		teth_aggr_params->max_transfer_size_byte / 1024;
+	ipa_aggr_params->aggr_time_limit = TETH_DEFAULT_AGGR_TIME_LIMIT;
+	TETH_DBG_FUNC_EXIT();
+
+	return 0;
+}
+
+static int teth_set_aggr_per_ep(
+	const struct teth_aggr_params_link *teth_aggr_params,
+	bool client_is_prod,
+	u32 pipe_hdl)
+{
+	struct ipa_ep_cfg_aggr agg_params;
+	struct ipa_ep_cfg_hdr hdr_params;
+	int res;
+
+	TETH_DBG_FUNC_ENTRY();
+	res = prepare_ipa_aggr_struct(teth_aggr_params,
+				      &agg_params,
+				      client_is_prod);
+	if (res) {
+		TETH_ERR("prepare_ipa_aggregation_struct() failed\n");
+		goto bail;
+	}
+
+	res = ipa_cfg_ep_aggr(pipe_hdl, &agg_params);
+	if (res) {
+		TETH_ERR("ipa_cfg_ep_aggr() failed\n");
+		goto bail;
+	}
+
+	if (!client_is_prod) {
+		memset(&hdr_params, 0, sizeof(hdr_params));
+		hdr_params.hdr_len = 1;
+		res = ipa_cfg_ep_hdr(pipe_hdl, &hdr_params);
+		if (res) {
+			TETH_ERR("ipa_cfg_ep_hdr() failed\n");
+			goto bail;
+		}
+	}
+	TETH_DBG_FUNC_EXIT();
+
+bail:
+	return res;
+}
+
+static void aggr_prot_to_str(enum teth_aggr_protocol_type aggr_prot,
+			     char *buff,
+			     uint buff_size)
+{
+	switch (aggr_prot) {
+	case TETH_AGGR_PROTOCOL_NONE:
+		strlcpy(buff, "NONE", buff_size);
+		break;
+	case TETH_AGGR_PROTOCOL_MBIM:
+		strlcpy(buff, "MBIM", buff_size);
+		break;
+	case TETH_AGGR_PROTOCOL_TLP:
+		strlcpy(buff, "TLP", buff_size);
+		break;
+	default:
+		strlcpy(buff, "ERROR", buff_size);
+		break;
+	}
+}
+
+static int teth_set_aggregation(void)
+{
+	int res;
+	char aggr_prot_str[20];
+
+	TETH_DBG_FUNC_ENTRY();
+	if (teth_ctx->aggr_params.ul.aggr_prot == TETH_AGGR_PROTOCOL_MBIM ||
+	    teth_ctx->aggr_params.dl.aggr_prot == TETH_AGGR_PROTOCOL_MBIM) {
+		res = ipa_set_aggr_mode(IPA_MBIM);
+		if (res) {
+			TETH_ERR("ipa_set_aggr_mode() failed\n");
+			goto bail;
+		}
+		res = ipa_set_single_ndp_per_mbim(false);
+		if (res) {
+			TETH_ERR("ipa_set_single_ndp_per_mbim() failed\n");
+			goto bail;
+		}
+	}
+
+	aggr_prot_to_str(teth_ctx->aggr_params.ul.aggr_prot,
+			 aggr_prot_str,
+			 sizeof(aggr_prot_str)-1);
+	TETH_DBG("Setting %s aggregation on UL\n", aggr_prot_str);
+	aggr_prot_to_str(teth_ctx->aggr_params.dl.aggr_prot,
+			 aggr_prot_str,
+			 sizeof(aggr_prot_str)-1);
+	TETH_DBG("Setting %s aggregation on DL\n", aggr_prot_str);
+
+	/* Configure aggregation on UL producer (USB->IPA) */
+	res = teth_set_aggr_per_ep(&teth_ctx->aggr_params.ul,
+				   true,
+				   teth_ctx->usb_ipa_pipe_hdl);
+	if (res) {
+		TETH_ERR("teth_set_aggregation_per_ep() failed\n");
+		goto bail;
+	}
+
+	/* Configure aggregation on DL consumer (IPA->USB) */
+	res = teth_set_aggr_per_ep(&teth_ctx->aggr_params.dl,
+				   false,
+				   teth_ctx->ipa_usb_pipe_hdl);
+	if (res) {
+		TETH_ERR("teth_set_aggregation_per_ep() failed\n");
+		goto bail;
+	}
+	TETH_DBG_FUNC_EXIT();
+bail:
+	return res;
+}
+
+static void complete_hw_bridge(struct work_struct *work)
+{
+	int res;
+	static DEFINE_MUTEX(f_lock);
+
+	mutex_lock(&f_lock);
+
+	TETH_DBG_FUNC_ENTRY();
+	TETH_DBG("Completing HW bridge in %s mode\n",
+		 (teth_ctx->link_protocol == TETH_LINK_PROTOCOL_ETHERNET) ?
+		 "ETHERNET" :
+		 "IP");
+
+	res = teth_set_aggregation();
+	if (res) {
+		TETH_ERR("Failed setting aggregation params\n");
+		goto bail;
+	}
+
+	/*
+	 * Reset the Header, Routing and Filtering blocks.
+	 * Resetting the Header block will also reset the other blocks.
+	 * This reset is not comitted to HW.
+	 */
+	res = ipa_reset_hdr();
+	if (res) {
+		TETH_ERR("Failed resetting IPA\n");
+		goto bail;
+	}
+
+	res = configure_ipa_header_block();
+	if (res) {
+		TETH_ERR("Configuration of IPA header block Failed\n");
+		goto bail;
+	}
+
+	res = configure_ipa_routing_block();
+	if (res) {
+		TETH_ERR("Configuration of IPA routing block Failed\n");
+		goto bail;
+	}
+
+	res = configure_ipa_filtering_block();
+	if (res) {
+		TETH_ERR("Configuration of IPA filtering block Failed\n");
+		goto bail;
+	}
+
+	teth_ctx->is_hw_bridge_complete = true;
+	teth_ctx->comp_hw_bridge_in_progress = false;
+bail:
+	mutex_unlock(&f_lock);
+	TETH_DBG_FUNC_EXIT();
+
+	return;
+}
+
+static void mac_addr_to_str(u8 mac_addr[ETH_ALEN],
+		     char *buff,
+		     uint buff_size)
+{
+	scnprintf(buff, buff_size, "%02x-%02x-%02x-%02x-%02x-%02x",
+		  mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3],
+		  mac_addr[4], mac_addr[5]);
+}
+
+static void check_to_complete_hw_bridge(struct sk_buff *skb,
+					u8 *my_mac_addr,
+					bool *my_mac_addr_known,
+					bool *peer_mac_addr_known)
+{
+	bool both_mac_addresses_known;
+	char mac_addr_str[20];
+
+	if ((teth_ctx->link_protocol == TETH_LINK_PROTOCOL_ETHERNET) &&
+	    (!(*my_mac_addr_known))) {
+		memcpy(my_mac_addr, &skb->data[ETH_ALEN], ETH_ALEN);
+		mac_addr_to_str(my_mac_addr,
+				mac_addr_str,
+				sizeof(mac_addr_str)-1);
+		TETH_DBG("Extracted MAC addr: %s\n", mac_addr_str);
+		*my_mac_addr_known = true;
+	}
+
+	both_mac_addresses_known = *my_mac_addr_known && *peer_mac_addr_known;
+	if ((both_mac_addresses_known ||
+	    (teth_ctx->link_protocol == TETH_LINK_PROTOCOL_IP)) &&
+	    (!teth_ctx->comp_hw_bridge_in_progress) &&
+	    (teth_ctx->aggr_params_known)) {
+		INIT_WORK(&teth_ctx->comp_hw_bridge_work, complete_hw_bridge);
+		teth_ctx->comp_hw_bridge_in_progress = true;
+		schedule_work(&teth_ctx->comp_hw_bridge_work);
+	}
+}
+
+static void usb_notify_cb(void *priv,
+			  enum ipa_dp_evt_type evt,
+			  unsigned long data)
+{
+	struct sk_buff *skb = (struct sk_buff *)data;
+	int res;
+
+	switch (evt) {
+	case IPA_RECEIVE:
+		if (!teth_ctx->is_hw_bridge_complete)
+			check_to_complete_hw_bridge(
+				skb,
+				teth_ctx->mac_addresses.host_pc_mac_addr,
+				&teth_ctx->mac_addresses.host_pc_mac_addr_known,
+				&teth_ctx->mac_addresses.device_mac_addr_known);
+
+		/* Send the packet to A2, using a2_service driver API */
+		res = a2_mux_write(A2_MUX_TETHERED_0, skb);
+		if (res) {
+			TETH_ERR("Packet send failure, dropping packet !\n");
+			dev_kfree_skb(skb);
+		}
+		break;
+
+	case IPA_WRITE_DONE:
+		dev_kfree_skb(skb);
+		break;
+
+	default:
+		TETH_ERR("Unsupported IPA event !\n");
+		WARN_ON(1);
+	}
+
+	return;
+}
+
+static void a2_notify_cb(void *user_data,
+			 enum a2_mux_event_type event,
+			 unsigned long data)
+{
+	struct sk_buff *skb = (struct sk_buff *)data;
+	int res;
+
+	switch (event) {
+	case A2_MUX_RECEIVE:
+		if (!teth_ctx->is_hw_bridge_complete)
+			check_to_complete_hw_bridge(
+				skb,
+				teth_ctx->mac_addresses.device_mac_addr,
+				&teth_ctx->mac_addresses.device_mac_addr_known,
+				&teth_ctx->
+				mac_addresses.host_pc_mac_addr_known);
+
+		/* Send the packet to USB */
+		res = ipa_tx_dp(IPA_CLIENT_USB_CONS, skb, NULL);
+		if (res) {
+			TETH_ERR("Packet send failure, dropping packet !\n");
+			dev_kfree_skb(skb);
+		}
+		break;
+
+	case A2_MUX_WRITE_DONE:
+		dev_kfree_skb(skb);
+		break;
+
+	default:
+		TETH_ERR("Unsupported IPA event !\n");
+		WARN_ON(1);
+	}
+
+	return;
+}
+
+static void bridge_prod_notify_cb(void *notify_cb_data,
+				  enum ipa_rm_event event,
+				  unsigned long data)
+{
+	switch (event) {
+	case IPA_RM_RESOURCE_GRANTED:
+		complete(&teth_ctx->is_bridge_prod_up);
+		break;
+
+	case IPA_RM_RESOURCE_RELEASED:
+		complete(&teth_ctx->is_bridge_prod_down);
+		break;
+
+	default:
+		TETH_ERR("Unsupported notification!\n");
+		WARN_ON(1);
+		break;
+	}
+
+	return;
+}
+
+/**
+* teth_bridge_init() - Initialize the Tethering bridge driver
+* @usb_notify_cb_ptr:	Callback function which should be used
+*			by the caller. Output parameter.
+* @private_data_ptr:	Data for the callback function. Should
+*			be used by the caller. Output parameter.
+* Return codes: 0: success,
+*		-EINVAL - Bad parameter
+*		Other negative value - Failure
+*/
+int teth_bridge_init(ipa_notify_cb *usb_notify_cb_ptr, void **private_data_ptr)
+{
+	int res = 0;
+	struct ipa_rm_create_params bridge_prod_params;
+
+	TETH_DBG_FUNC_ENTRY();
+	if (usb_notify_cb_ptr == NULL) {
+		TETH_ERR("Bad parameter\n");
+		res = -EINVAL;
+		goto bail;
+	}
+
+	*usb_notify_cb_ptr = usb_notify_cb;
+	*private_data_ptr = NULL;
+
+	/* Build IPA Resource manager dependency graph */
+	bridge_prod_params.name = IPA_RM_RESOURCE_BRIDGE_PROD;
+	bridge_prod_params.reg_params.user_data = NULL;
+	bridge_prod_params.reg_params.notify_cb = bridge_prod_notify_cb;
+	res = ipa_rm_create_resource(&bridge_prod_params);
+	if (res) {
+		TETH_ERR("ipa_rm_create_resource() failed\n");
+		goto bail;
+	}
+
+	res = ipa_rm_add_dependency(IPA_RM_RESOURCE_BRIDGE_PROD,
+				    IPA_RM_RESOURCE_USB_CONS);
+	if (res) {
+		TETH_ERR("ipa_rm_add_dependency() failed\n");
+		goto bail;
+	}
+
+	res = ipa_rm_add_dependency(IPA_RM_RESOURCE_BRIDGE_PROD,
+				    IPA_RM_RESOURCE_A2_CONS);
+	if (res) {
+		TETH_ERR("ipa_rm_add_dependency() failed\n");
+		goto fail_add_dependency_1;
+	}
+
+	res = ipa_rm_add_dependency(IPA_RM_RESOURCE_USB_PROD,
+				    IPA_RM_RESOURCE_A2_CONS);
+	if (res) {
+		TETH_ERR("ipa_rm_add_dependency() failed\n");
+		goto fail_add_dependency_2;
+	}
+
+	res = ipa_rm_add_dependency(IPA_RM_RESOURCE_A2_PROD,
+				    IPA_RM_RESOURCE_USB_CONS);
+	if (res) {
+		TETH_ERR("ipa_rm_add_dependency() failed\n");
+		goto fail_add_dependency_3;
+	}
+
+	init_completion(&teth_ctx->is_bridge_prod_up);
+	init_completion(&teth_ctx->is_bridge_prod_down);
+
+	/* The default link protocol is Ethernet */
+	teth_ctx->link_protocol = TETH_LINK_PROTOCOL_ETHERNET;
+	goto bail;
+
+fail_add_dependency_3:
+	ipa_rm_delete_dependency(IPA_RM_RESOURCE_USB_PROD,
+				 IPA_RM_RESOURCE_A2_CONS);
+fail_add_dependency_2:
+	ipa_rm_delete_dependency(IPA_RM_RESOURCE_BRIDGE_PROD,
+				 IPA_RM_RESOURCE_A2_CONS);
+fail_add_dependency_1:
+	ipa_rm_delete_dependency(IPA_RM_RESOURCE_BRIDGE_PROD,
+				 IPA_RM_RESOURCE_USB_CONS);
+bail:
+	TETH_DBG_FUNC_EXIT();
+	return res;
+}
+EXPORT_SYMBOL(teth_bridge_init);
+
+/**
+* teth_bridge_disconnect() - Disconnect tethering bridge module
+*
+* Return codes:	0: success
+*		-EPERM: Operation not permitted as the bridge is already
+*		disconnected
+*/
+int teth_bridge_disconnect(void)
+{
+	int res = -EPERM;
+
+	TETH_DBG_FUNC_ENTRY();
+	if (!teth_ctx->is_connected) {
+		TETH_ERR(
+		"Trying to disconnect an already disconnected bridge\n");
+		goto bail;
+	}
+
+	teth_ctx->is_connected = false;
+
+	res = ipa_rm_release_resource(IPA_RM_RESOURCE_BRIDGE_PROD);
+	if (res == -EINPROGRESS)
+		wait_for_completion(&teth_ctx->is_bridge_prod_down);
+
+bail:
+	TETH_DBG_FUNC_EXIT();
+	return res;
+}
+EXPORT_SYMBOL(teth_bridge_disconnect);
+
+/**
+* teth_bridge_connect() - Connect bridge for a tethered Rmnet / MBIM call
+* @connect_params:	Connection info
+*
+* Return codes: 0: success
+*		-EINVAL: invalid parameters
+*		-EPERM: Operation not permitted as the bridge is already
+*		connected
+*/
+int teth_bridge_connect(struct teth_bridge_connect_params *connect_params)
+{
+	int res;
+	struct ipa_ep_cfg ipa_ep_cfg;
+
+	TETH_DBG_FUNC_ENTRY();
+	if (teth_ctx->is_connected) {
+		TETH_ERR("Trying to connect an already connected bridge !\n");
+		return -EPERM;
+	}
+	if (connect_params == NULL ||
+	    connect_params->ipa_usb_pipe_hdl <= 0 ||
+	    connect_params->usb_ipa_pipe_hdl <= 0 ||
+	    connect_params->tethering_mode >= TETH_TETHERING_MODE_MAX ||
+	    connect_params->tethering_mode < 0)
+		return -EINVAL;
+
+	teth_ctx->ipa_usb_pipe_hdl = connect_params->ipa_usb_pipe_hdl;
+	teth_ctx->usb_ipa_pipe_hdl = connect_params->usb_ipa_pipe_hdl;
+	teth_ctx->tethering_mode = connect_params->tethering_mode;
+
+	res = ipa_rm_request_resource(IPA_RM_RESOURCE_BRIDGE_PROD);
+	if (res < 0) {
+		if (res == -EINPROGRESS)
+			wait_for_completion(&teth_ctx->is_bridge_prod_up);
+		else
+			goto bail;
+	}
+
+	res = a2_mux_open_channel(A2_MUX_TETHERED_0,
+				  NULL,
+				  a2_notify_cb);
+	if (res) {
+		TETH_ERR("a2_mux_open_channel() failed\n");
+		goto bail;
+	}
+
+	res = a2_mux_get_tethered_client_handles(A2_MUX_TETHERED_0,
+						 &teth_ctx->ipa_a2_pipe_hdl,
+						 &teth_ctx->a2_ipa_pipe_hdl);
+	if (res) {
+		TETH_ERR(
+		"a2_mux_get_tethered_client_handles() failed, res = %d\n", res);
+		goto bail;
+	}
+
+	/* Reset the various endpoints configuration */
+	memset(&ipa_ep_cfg, 0, sizeof(ipa_ep_cfg));
+	ipa_cfg_ep(teth_ctx->ipa_usb_pipe_hdl, &ipa_ep_cfg);
+	ipa_cfg_ep(teth_ctx->usb_ipa_pipe_hdl, &ipa_ep_cfg);
+	ipa_cfg_ep(teth_ctx->ipa_a2_pipe_hdl, &ipa_ep_cfg);
+	ipa_cfg_ep(teth_ctx->a2_ipa_pipe_hdl, &ipa_ep_cfg);
+
+	teth_ctx->is_connected = true;
+
+	if (teth_ctx->tethering_mode == TETH_TETHERING_MODE_MBIM)
+		teth_ctx->link_protocol = TETH_LINK_PROTOCOL_IP;
+	TETH_DBG_FUNC_EXIT();
+bail:
+	if (res)
+		ipa_rm_release_resource(IPA_RM_RESOURCE_BRIDGE_PROD);
+	return res;
+}
+EXPORT_SYMBOL(teth_bridge_connect);
+
+static void set_aggr_default_params(struct teth_aggr_params_link *params)
+{
+	if (params->max_datagrams == 0)
+		params->max_datagrams = 16;
+	if (params->max_transfer_size_byte == 0)
+		params->max_transfer_size_byte = 16*1024;
+}
+
+static void teth_set_bridge_mode(enum teth_link_protocol_type link_protocol)
+{
+	teth_ctx->link_protocol = link_protocol;
+	teth_ctx->is_hw_bridge_complete = false;
+	memset(&teth_ctx->mac_addresses, 0, sizeof(teth_ctx->mac_addresses));
+}
+
+static long teth_bridge_ioctl(struct file *filp,
+			      unsigned int cmd,
+			      unsigned long arg)
+{
+	int res = 0;
+
+	TETH_DBG("cmd=%x nr=%d\n", cmd, _IOC_NR(cmd));
+
+	if ((_IOC_TYPE(cmd) != TETH_BRIDGE_IOC_MAGIC) ||
+	    (_IOC_NR(cmd) >= TETH_BRIDGE_IOCTL_MAX)) {
+		TETH_ERR("Invalid ioctl\n");
+		return -ENOIOCTLCMD;
+	}
+
+	switch (cmd) {
+	case TETH_BRIDGE_IOC_SET_BRIDGE_MODE:
+		TETH_DBG("TETH_BRIDGE_IOC_SET_BRIDGE_MODE ioctl called\n");
+		if (teth_ctx->link_protocol != arg)
+			teth_set_bridge_mode(arg);
+		break;
+
+	case TETH_BRIDGE_IOC_SET_AGGR_PARAMS:
+		TETH_DBG("TETH_BRIDGE_IOC_SET_AGGR_PARAMS ioctl called\n");
+		res = copy_from_user(&teth_ctx->aggr_params,
+				   (struct teth_aggr_params *)arg,
+				   sizeof(struct teth_aggr_params));
+		if (res) {
+			TETH_ERR("Error, res = %d\n", res);
+			res = -EFAULT;
+			break;
+		}
+		set_aggr_default_params(&teth_ctx->aggr_params.dl);
+		set_aggr_default_params(&teth_ctx->aggr_params.ul);
+		teth_ctx->aggr_params_known = true;
+		break;
+
+	case TETH_BRIDGE_IOC_GET_AGGR_PARAMS:
+		TETH_DBG("TETH_BRIDGE_IOC_GET_AGGR_PARAMS ioctl called\n");
+		if (copy_to_user((u8 *)arg, (u8 *)&teth_ctx->aggr_params,
+				   sizeof(struct teth_aggr_params))) {
+			res = -EFAULT;
+			break;
+		}
+		break;
+
+	case TETH_BRIDGE_IOC_GET_AGGR_CAPABILITIES:
+	{
+		u16 sz;
+		u16 pyld_sz;
+		struct teth_aggr_capabilities caps;
+
+		TETH_DBG("GET_AGGR_CAPABILITIES ioctl called\n");
+		sz = sizeof(struct teth_aggr_capabilities);
+		if (copy_from_user(&caps,
+				   (struct teth_aggr_capabilities *)arg,
+				   sz)) {
+			res = -EFAULT;
+			break;
+		}
+
+		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,
+					 sz)) {
+				res = -EFAULT;
+				break;
+			}
+			TETH_DBG("Not enough space allocated.\n");
+			res = -EAGAIN;
+			break;
+		}
+
+		pyld_sz = sz + caps.num_protocols *
+			sizeof(struct teth_aggr_params_link);
+
+		if (copy_to_user((u8 *)arg,
+				 (u8 *)(teth_ctx->aggr_caps),
+				 pyld_sz)) {
+			res = -EFAULT;
+			break;
+		}
+	}
+	break;
+	}
+
+	return res;
+}
+
+static void set_aggr_capabilities(void)
+{
+	u16 NUM_PROTOCOLS = 2;
+
+	teth_ctx->aggr_caps = kzalloc(sizeof(struct teth_aggr_capabilities) +
+				      NUM_PROTOCOLS *
+				      sizeof(struct teth_aggr_params_link),
+				      GFP_KERNEL);
+	if (teth_ctx->aggr_caps == NULL) {
+		TETH_ERR("Memory alloc failed for aggregation capabilities.\n");
+		return;
+	}
+
+	teth_ctx->aggr_caps->num_protocols = NUM_PROTOCOLS;
+
+	teth_ctx->aggr_caps->prot_caps[0].aggr_prot = TETH_AGGR_PROTOCOL_MBIM;
+	teth_ctx->aggr_caps->prot_caps[0].max_datagrams = 16;
+	teth_ctx->aggr_caps->prot_caps[0].max_transfer_size_byte = 16*1024;
+
+	teth_ctx->aggr_caps->prot_caps[1].aggr_prot = TETH_AGGR_PROTOCOL_TLP;
+	teth_ctx->aggr_caps->prot_caps[1].max_datagrams = 16;
+	teth_ctx->aggr_caps->prot_caps[1].max_transfer_size_byte = 16*1024;
+}
+
+void teth_bridge_get_client_handles(u32 *producer_handle,
+		u32 *consumer_handle)
+{
+	if (producer_handle == NULL || consumer_handle == NULL)
+		return;
+
+	*producer_handle = teth_ctx->usb_ipa_pipe_hdl;
+	*consumer_handle = teth_ctx->ipa_usb_pipe_hdl;
+}
+
+#ifdef CONFIG_DEBUG_FS
+static struct dentry *dent;
+static struct dentry *dfile_link_protocol;
+static struct dentry *dfile_get_aggr_params;
+static struct dentry *dfile_set_aggr_protocol;
+
+static ssize_t teth_debugfs_read_link_protocol(struct file *file,
+					       char __user *ubuf,
+					       size_t count,
+					       loff_t *ppos)
+{
+	int nbytes;
+
+	nbytes = scnprintf(dbg_buff, TETH_MAX_MSG_LEN, "Link protocol = %s\n",
+			   (teth_ctx->link_protocol ==
+				TETH_LINK_PROTOCOL_ETHERNET) ?
+			   "ETHERNET" :
+			   "IP");
+
+	return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, nbytes);
+}
+
+static ssize_t teth_debugfs_write_link_protocol(struct file *file,
+					const char __user *ubuf,
+					size_t count,
+					loff_t *ppos)
+{
+	unsigned long missing;
+	enum teth_link_protocol_type link_protocol;
+
+	if (sizeof(dbg_buff) < count + 1)
+		return -EFAULT;
+
+	missing = copy_from_user(dbg_buff, ubuf, count);
+	if (missing)
+		return -EFAULT;
+
+	if (count > 0)
+		dbg_buff[count-1] = '\0';
+
+	if (strcmp(dbg_buff, "ETHERNET") == 0) {
+		link_protocol = TETH_LINK_PROTOCOL_ETHERNET;
+	} else if (strcmp(dbg_buff, "IP") == 0) {
+		link_protocol = TETH_LINK_PROTOCOL_IP;
+	} else {
+		TETH_ERR("Bad link protocol, got %s,\n"
+			 "Use <ETHERNET> or <IP>.\n", dbg_buff);
+		return count;
+	}
+
+	teth_set_bridge_mode(link_protocol);
+
+	return count;
+}
+
+static ssize_t teth_debugfs_read_aggr_params(struct file *file,
+					     char __user *ubuf,
+					     size_t count,
+					     loff_t *ppos)
+{
+	int nbytes = 0;
+	char aggr_str[20];
+
+	aggr_prot_to_str(teth_ctx->aggr_params.ul.aggr_prot,
+			 aggr_str,
+			 sizeof(aggr_str)-1);
+	nbytes += scnprintf(&dbg_buff[nbytes], TETH_MAX_MSG_LEN,
+			   "Aggregation parameters for uplink:\n");
+	nbytes += scnprintf(&dbg_buff[nbytes], TETH_MAX_MSG_LEN - nbytes,
+			    "  Aggregation protocol: %s\n",
+			    aggr_str);
+	nbytes += scnprintf(&dbg_buff[nbytes], TETH_MAX_MSG_LEN - nbytes,
+			    "  Max transfer size [byte]: %d\n",
+			    teth_ctx->aggr_params.ul.max_transfer_size_byte);
+	nbytes += scnprintf(&dbg_buff[nbytes], TETH_MAX_MSG_LEN - nbytes,
+			    "  Max datagrams: %d\n",
+			    teth_ctx->aggr_params.ul.max_datagrams);
+
+	aggr_prot_to_str(teth_ctx->aggr_params.dl.aggr_prot,
+			 aggr_str,
+			 sizeof(aggr_str)-1);
+	nbytes += scnprintf(&dbg_buff[nbytes], TETH_MAX_MSG_LEN,
+			   "Aggregation parameters for downlink:\n");
+	nbytes += scnprintf(&dbg_buff[nbytes], TETH_MAX_MSG_LEN - nbytes,
+			    "  Aggregation protocol: %s\n",
+			    aggr_str);
+	nbytes += scnprintf(&dbg_buff[nbytes], TETH_MAX_MSG_LEN - nbytes,
+			    "  Max transfer size [byte]: %d\n",
+			    teth_ctx->aggr_params.dl.max_transfer_size_byte);
+	nbytes += scnprintf(&dbg_buff[nbytes], TETH_MAX_MSG_LEN - nbytes,
+			    "  Max datagrams: %d\n",
+			    teth_ctx->aggr_params.dl.max_datagrams);
+
+	return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, nbytes);
+}
+
+static ssize_t teth_debugfs_set_aggr_protocol(struct file *file,
+				      const char __user *ubuf,
+				      size_t count, loff_t *ppos)
+{
+	unsigned long missing;
+	enum teth_aggr_protocol_type aggr_prot;
+	int res;
+
+	if (sizeof(dbg_buff) < count + 1)
+		return -EFAULT;
+
+	missing = copy_from_user(dbg_buff, ubuf, count);
+	if (missing)
+		return -EFAULT;
+
+	if (count > 0)
+		dbg_buff[count-1] = '\0';
+
+	set_aggr_default_params(&teth_ctx->aggr_params.dl);
+	set_aggr_default_params(&teth_ctx->aggr_params.ul);
+
+	if (strcmp(dbg_buff, "NONE") == 0) {
+		aggr_prot = TETH_AGGR_PROTOCOL_NONE;
+	} else if (strcmp(dbg_buff, "MBIM") == 0) {
+		aggr_prot = TETH_AGGR_PROTOCOL_MBIM;
+	} else if (strcmp(dbg_buff, "TLP") == 0) {
+		aggr_prot = TETH_AGGR_PROTOCOL_TLP;
+	} else {
+		TETH_ERR("Bad aggregation protocol, got %s,\n"
+			 "Use <NONE>, <MBIM> or <TLP>.\n", dbg_buff);
+		return count;
+	}
+
+	teth_ctx->aggr_params.dl.aggr_prot = aggr_prot;
+	teth_ctx->aggr_params.ul.aggr_prot = aggr_prot;
+	teth_ctx->aggr_params_known = true;
+
+	res = teth_set_aggregation();
+	if (res)
+		TETH_ERR("Failed setting aggregation params\n");
+
+	return count;
+}
+
+const struct file_operations teth_link_protocol_ops = {
+	.read = teth_debugfs_read_link_protocol,
+	.write = teth_debugfs_write_link_protocol,
+};
+
+const struct file_operations teth_get_aggr_params_ops = {
+	.read = teth_debugfs_read_aggr_params,
+};
+
+const struct file_operations teth_set_aggr_protocol_ops = {
+	.write = teth_debugfs_set_aggr_protocol,
+};
+
+void teth_debugfs_init(void)
+{
+	const mode_t read_only_mode = S_IRUSR | S_IRGRP | S_IROTH;
+	const mode_t read_write_mode = S_IRUSR | S_IRGRP | S_IROTH |
+			S_IWUSR | S_IWGRP | S_IWOTH;
+
+	dent = debugfs_create_dir("ipa_teth", 0);
+	if (IS_ERR(dent)) {
+		IPAERR("fail to create folder ipa_teth debug_fs.\n");
+		return;
+	}
+
+	dfile_link_protocol =
+		debugfs_create_file("link_protocol", read_write_mode, dent, 0,
+				    &teth_link_protocol_ops);
+	if (!dfile_link_protocol || IS_ERR(dfile_link_protocol)) {
+		IPAERR("fail to create file link_protocol\n");
+		goto fail;
+	}
+
+	dfile_get_aggr_params =
+		debugfs_create_file("get_aggr_params", read_only_mode, dent, 0,
+				    &teth_get_aggr_params_ops);
+	if (!dfile_get_aggr_params || IS_ERR(dfile_get_aggr_params)) {
+		IPAERR("fail to create file get_aggr_params\n");
+		goto fail;
+	}
+
+	dfile_set_aggr_protocol =
+		debugfs_create_file("set_aggr_protocol", read_only_mode, dent,
+				    0, &teth_set_aggr_protocol_ops);
+	if (!dfile_set_aggr_protocol || IS_ERR(dfile_set_aggr_protocol)) {
+		IPAERR("fail to create file set_aggr_protocol\n");
+		goto fail;
+	}
+
+	return;
+fail:
+	debugfs_remove_recursive(dent);
+}
+#else
+void teth_debugfs_init(void) {}
+#endif /* CONFIG_DEBUG_FS */
+
+
+static const struct file_operations teth_bridge_drv_fops = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = teth_bridge_ioctl,
+};
+
+/**
+* teth_bridge_driver_init() - Initialize tethering bridge driver
+*
+*/
+int teth_bridge_driver_init(void)
+{
+	int res;
+
+	TETH_DBG("Tethering bridge driver init\n");
+	teth_ctx = kzalloc(sizeof(*teth_ctx), GFP_KERNEL);
+	if (!teth_ctx) {
+		TETH_ERR("kzalloc err.\n");
+		return -ENOMEM;
+	}
+
+	set_aggr_capabilities();
+
+	teth_ctx->class = class_create(THIS_MODULE, TETH_BRIDGE_DRV_NAME);
+
+	res = alloc_chrdev_region(&teth_ctx->dev_num, 0, 1,
+				  TETH_BRIDGE_DRV_NAME);
+	if (res) {
+		TETH_ERR("alloc_chrdev_region err.\n");
+		res = -ENODEV;
+		goto fail_alloc_chrdev_region;
+	}
+
+	teth_ctx->dev = device_create(teth_ctx->class, NULL, teth_ctx->dev_num,
+				      teth_ctx, TETH_BRIDGE_DRV_NAME);
+	if (IS_ERR(teth_ctx->dev)) {
+		TETH_ERR(":device_create err.\n");
+		res = -ENODEV;
+		goto fail_device_create;
+	}
+
+	cdev_init(&teth_ctx->cdev, &teth_bridge_drv_fops);
+	teth_ctx->cdev.owner = THIS_MODULE;
+	teth_ctx->cdev.ops = &teth_bridge_drv_fops;
+
+	res = cdev_add(&teth_ctx->cdev, teth_ctx->dev_num, 1);
+	if (res) {
+		TETH_ERR(":cdev_add err=%d\n", -res);
+		res = -ENODEV;
+		goto fail_cdev_add;
+	}
+
+	teth_ctx->comp_hw_bridge_in_progress = false;
+
+	teth_debugfs_init();
+	TETH_DBG("Tethering bridge driver init OK\n");
+
+	return 0;
+fail_cdev_add:
+	device_destroy(teth_ctx->class, teth_ctx->dev_num);
+fail_device_create:
+	unregister_chrdev_region(teth_ctx->dev_num, 1);
+fail_alloc_chrdev_region:
+	kfree(teth_ctx->aggr_caps);
+	kfree(teth_ctx);
+	teth_ctx = NULL;
+
+	return res;
+}
+EXPORT_SYMBOL(teth_bridge_driver_init);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Tethering bridge driver");
diff --git a/drivers/platform/msm/qpnp-clkdiv.c b/drivers/platform/msm/qpnp-clkdiv.c
index 2a9ba90..c55ed09 100644
--- a/drivers/platform/msm/qpnp-clkdiv.c
+++ b/drivers/platform/msm/qpnp-clkdiv.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/platform/msm/qpnp-vibrator.c b/drivers/platform/msm/qpnp-vibrator.c
new file mode 100644
index 0000000..ca3832d
--- /dev/null
+++ b/drivers/platform/msm/qpnp-vibrator.c
@@ -0,0 +1,343 @@
+/* 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/init.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/hrtimer.h>
+#include <linux/of_device.h>
+#include <linux/spmi.h>
+
+#include <linux/qpnp/vibrator.h>
+#include "../../staging/android/timed_output.h"
+
+#define QPNP_VIB_VTG_CTL(base)		(base + 0x41)
+#define QPNP_VIB_EN_CTL(base)		(base + 0x46)
+
+#define QPNP_VIB_MAX_LEVEL		31
+#define QPNP_VIB_MIN_LEVEL		12
+
+#define QPNP_VIB_DEFAULT_TIMEOUT	15000
+#define QPNP_VIB_DEFAULT_VTG_LVL	3100
+
+#define QPNP_VIB_EN			BIT(7)
+#define QPNP_VIB_VTG_SET_MASK		0x1F
+#define QPNP_VIB_LOGIC_SHIFT		4
+
+struct qpnp_vib {
+	struct spmi_device *spmi;
+	struct hrtimer vib_timer;
+	struct timed_output_dev timed_dev;
+	struct work_struct work;
+
+	u8  reg_vtg_ctl;
+	u8  reg_en_ctl;
+	u16 base;
+	int state;
+	int vtg_level;
+	int timeout;
+	struct mutex lock;
+};
+
+static struct qpnp_vib *vib_dev;
+
+static int qpnp_vib_read_u8(struct qpnp_vib *vib, u8 *data, u16 reg)
+{
+	int rc;
+
+	rc = spmi_ext_register_readl(vib->spmi->ctrl, vib->spmi->sid,
+							reg, data, 1);
+	if (rc < 0)
+		dev_err(&vib->spmi->dev,
+			"Error reading address: %X - ret %X\n", reg, rc);
+
+	return rc;
+}
+
+static int qpnp_vib_write_u8(struct qpnp_vib *vib, u8 *data, u16 reg)
+{
+	int rc;
+
+	rc = spmi_ext_register_writel(vib->spmi->ctrl, vib->spmi->sid,
+							reg, data, 1);
+	if (rc < 0)
+		dev_err(&vib->spmi->dev,
+			"Error writing address: %X - ret %X\n", reg, rc);
+
+	return rc;
+}
+
+int qpnp_vibrator_config(struct qpnp_vib_config *vib_cfg)
+{
+	u8 reg = 0;
+	int rc = -EINVAL, level;
+
+	if (vib_dev == NULL) {
+		pr_err("%s: vib_dev is NULL\n", __func__);
+		return -ENODEV;
+	}
+
+	level = vib_cfg->drive_mV / 100;
+	if (level) {
+		if ((level < QPNP_VIB_MIN_LEVEL) ||
+				(level > QPNP_VIB_MAX_LEVEL)) {
+			dev_err(&vib_dev->spmi->dev, "Invalid voltage level\n");
+			return -EINVAL;
+		}
+	} else {
+		dev_err(&vib_dev->spmi->dev, "Voltage level not specified\n");
+		return -EINVAL;
+	}
+
+	/* Configure the VTG CTL regiser */
+	reg = vib_dev->reg_vtg_ctl;
+	reg &= ~QPNP_VIB_VTG_SET_MASK;
+	reg |= (level & QPNP_VIB_VTG_SET_MASK);
+	rc = qpnp_vib_write_u8(vib_dev, &reg, QPNP_VIB_VTG_CTL(vib_dev->base));
+	if (rc)
+		return rc;
+	vib_dev->reg_vtg_ctl = reg;
+
+	/* Configure the VIB ENABLE regiser */
+	reg = vib_dev->reg_en_ctl;
+	reg |= (!!vib_cfg->active_low) << QPNP_VIB_LOGIC_SHIFT;
+	if (vib_cfg->enable_mode == QPNP_VIB_MANUAL)
+		reg |= QPNP_VIB_EN;
+	else
+		reg |= BIT(vib_cfg->enable_mode - 1);
+	rc = qpnp_vib_write_u8(vib_dev, &reg, QPNP_VIB_EN_CTL(vib_dev->base));
+	if (rc < 0)
+		return rc;
+	vib_dev->reg_en_ctl = reg;
+
+	return rc;
+}
+EXPORT_SYMBOL(qpnp_vibrator_config);
+
+static int qpnp_vib_set(struct qpnp_vib *vib, int on)
+{
+	int rc;
+	u8 val;
+
+	if (on) {
+		val = vib->reg_vtg_ctl;
+		val &= ~QPNP_VIB_VTG_SET_MASK;
+		val |= (vib->vtg_level & QPNP_VIB_VTG_SET_MASK);
+		rc = qpnp_vib_write_u8(vib, &val, QPNP_VIB_VTG_CTL(vib->base));
+		if (rc < 0)
+			return rc;
+		vib->reg_vtg_ctl = val;
+		val = vib->reg_en_ctl;
+		val |= QPNP_VIB_EN;
+		rc = qpnp_vib_write_u8(vib, &val, QPNP_VIB_EN_CTL(vib->base));
+		if (rc < 0)
+			return rc;
+		vib->reg_en_ctl = val;
+	} else {
+		val = vib->reg_en_ctl;
+		val &= ~QPNP_VIB_EN;
+		rc = qpnp_vib_write_u8(vib, &val, QPNP_VIB_EN_CTL(vib->base));
+		if (rc < 0)
+			return rc;
+		vib->reg_en_ctl = val;
+	}
+
+	return rc;
+}
+
+static void qpnp_vib_enable(struct timed_output_dev *dev, int value)
+{
+	struct qpnp_vib *vib = container_of(dev, struct qpnp_vib,
+					 timed_dev);
+
+	mutex_lock(&vib->lock);
+	hrtimer_cancel(&vib->vib_timer);
+
+	if (value == 0)
+		vib->state = 0;
+	else {
+		value = (value > vib->timeout ?
+				 vib->timeout : value);
+		vib->state = 1;
+		hrtimer_start(&vib->vib_timer,
+			      ktime_set(value / 1000, (value % 1000) * 1000000),
+			      HRTIMER_MODE_REL);
+	}
+	mutex_unlock(&vib->lock);
+	schedule_work(&vib->work);
+}
+
+static void qpnp_vib_update(struct work_struct *work)
+{
+	struct qpnp_vib *vib = container_of(work, struct qpnp_vib,
+					 work);
+	qpnp_vib_set(vib, vib->state);
+}
+
+static int qpnp_vib_get_time(struct timed_output_dev *dev)
+{
+	struct qpnp_vib *vib = container_of(dev, struct qpnp_vib,
+							 timed_dev);
+
+	if (hrtimer_active(&vib->vib_timer)) {
+		ktime_t r = hrtimer_get_remaining(&vib->vib_timer);
+		return (int)ktime_to_us(r);
+	} else
+		return 0;
+}
+
+static enum hrtimer_restart qpnp_vib_timer_func(struct hrtimer *timer)
+{
+	struct qpnp_vib *vib = container_of(timer, struct qpnp_vib,
+							 vib_timer);
+
+	vib->state = 0;
+	schedule_work(&vib->work);
+
+	return HRTIMER_NORESTART;
+}
+
+#ifdef CONFIG_PM
+static int qpnp_vibrator_suspend(struct device *dev)
+{
+	struct qpnp_vib *vib = dev_get_drvdata(dev);
+
+	hrtimer_cancel(&vib->vib_timer);
+	cancel_work_sync(&vib->work);
+	/* turn-off vibrator */
+	qpnp_vib_set(vib, 0);
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(qpnp_vibrator_pm_ops, qpnp_vibrator_suspend, NULL);
+
+static int __devinit qpnp_vibrator_probe(struct spmi_device *spmi)
+{
+	struct qpnp_vib *vib;
+	struct resource *vib_resource;
+	int rc;
+	u8 val;
+	u32 temp_val;
+
+	vib = devm_kzalloc(&spmi->dev, sizeof(*vib), GFP_KERNEL);
+	if (!vib)
+		return -ENOMEM;
+
+	vib->spmi = spmi;
+
+	vib->timeout = QPNP_VIB_DEFAULT_TIMEOUT;
+	rc = of_property_read_u32(spmi->dev.of_node,
+			"qcom,vib-timeout-ms", &temp_val);
+	if (!rc) {
+		vib->timeout = temp_val;
+	} else if (rc != EINVAL) {
+		dev_err(&spmi->dev, "Unable to read vib timeout\n");
+		return rc;
+	}
+
+	vib->vtg_level = QPNP_VIB_DEFAULT_VTG_LVL;
+	rc = of_property_read_u32(spmi->dev.of_node,
+			"qcom,vib-vtg-level-mV", &temp_val);
+	if (!rc) {
+		vib->vtg_level = temp_val;
+	} else if (rc != -EINVAL) {
+		dev_err(&spmi->dev, "Unable to read vtg level\n");
+		return rc;
+	}
+
+	vib->vtg_level /= 100;
+
+	vib_resource = spmi_get_resource(spmi, 0, IORESOURCE_MEM, 0);
+	if (!vib_resource) {
+		dev_err(&spmi->dev, "Unable to get vibrator base address\n");
+		return -EINVAL;
+	}
+	vib->base = vib_resource->start;
+
+	/* save the control registers values */
+	rc = qpnp_vib_read_u8(vib, &val, QPNP_VIB_VTG_CTL(vib->base));
+	if (rc < 0)
+		return rc;
+	vib->reg_vtg_ctl = val;
+
+	rc = qpnp_vib_read_u8(vib, &val, QPNP_VIB_EN_CTL(vib->base));
+	if (rc < 0)
+		return rc;
+	vib->reg_en_ctl = val;
+
+	mutex_init(&vib->lock);
+	INIT_WORK(&vib->work, qpnp_vib_update);
+
+	hrtimer_init(&vib->vib_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+	vib->vib_timer.function = qpnp_vib_timer_func;
+
+	vib->timed_dev.name = "vibrator";
+	vib->timed_dev.get_time = qpnp_vib_get_time;
+	vib->timed_dev.enable = qpnp_vib_enable;
+
+	dev_set_drvdata(&spmi->dev, vib);
+
+	rc = timed_output_dev_register(&vib->timed_dev);
+	if (rc < 0)
+		return rc;
+
+	vib_dev = vib;
+
+	return rc;
+}
+
+static int  __devexit qpnp_vibrator_remove(struct spmi_device *spmi)
+{
+	struct qpnp_vib *vib = dev_get_drvdata(&spmi->dev);
+
+	cancel_work_sync(&vib->work);
+	hrtimer_cancel(&vib->vib_timer);
+	timed_output_dev_unregister(&vib->timed_dev);
+	mutex_destroy(&vib->lock);
+
+	return 0;
+}
+
+static struct of_device_id spmi_match_table[] = {
+	{	.compatible = "qcom,qpnp-vibrator",
+	},
+	{}
+};
+
+static struct spmi_driver qpnp_vibrator_driver = {
+	.driver		= {
+		.name	= "qcom,qpnp-vibrator",
+		.of_match_table = spmi_match_table,
+		.pm	= &qpnp_vibrator_pm_ops,
+	},
+	.probe		= qpnp_vibrator_probe,
+	.remove		= __devexit_p(qpnp_vibrator_remove),
+};
+
+static int __init qpnp_vibrator_init(void)
+{
+	return spmi_driver_register(&qpnp_vibrator_driver);
+}
+module_init(qpnp_vibrator_init);
+
+static void __exit qpnp_vibrator_exit(void)
+{
+	return spmi_driver_unregister(&qpnp_vibrator_driver);
+}
+module_exit(qpnp_vibrator_exit);
+
+MODULE_DESCRIPTION("qpnp vibrator driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/platform/msm/sps/bam.c b/drivers/platform/msm/sps/bam.c
index bcb4cdb..0f81285 100644
--- a/drivers/platform/msm/sps/bam.c
+++ b/drivers/platform/msm/sps/bam.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -644,7 +644,7 @@
 int bam_init(void *base, u32 ee,
 		u16 summing_threshold,
 		u32 irq_mask, u32 *version,
-		u32 *num_pipes, u32 p_rst)
+		u32 *num_pipes, u32 options)
 {
 	u32 cfg_bits;
 	u32 ver = 0;
@@ -667,7 +667,7 @@
 				"use default 4.\n", (u32) base);
 	}
 
-	if (p_rst)
+	if (options & SPS_BAM_NO_EXT_P_RST)
 		cfg_bits = 0xffffffff & ~(3 << 11);
 	else
 		cfg_bits = 0xffffffff & ~(1 << 11);
@@ -681,7 +681,10 @@
 #ifdef CONFIG_SPS_SUPPORT_NDP_BAM
 	bam_write_reg_field(base, CTRL, CACHE_MISS_ERR_RESP_EN, 0);
 
-	bam_write_reg_field(base, CTRL, LOCAL_CLK_GATING, 1);
+	if (options & SPS_BAM_NO_LOCAL_CLK_GATING)
+		bam_write_reg_field(base, CTRL, LOCAL_CLK_GATING, 0);
+	else
+		bam_write_reg_field(base, CTRL, LOCAL_CLK_GATING, 1);
 #endif
 
 	bam_write_reg(base, DESC_CNT_TRSHLD, summing_threshold);
@@ -805,7 +808,7 @@
 	 *  Discover the hardware version number and the number of pipes
 	 *  supported by this BAM
 	 */
-	*num_pipes = bam_read_reg(base, NUM_PIPES);
+	*num_pipes = bam_read_reg_field(base, NUM_PIPES, BAM_NUM_PIPES);
 	*version = ver;
 
 	/* Check BAM version */
@@ -842,21 +845,9 @@
 static void bam_output_register_content(void *base)
 {
 	u32 num_pipes;
-	u32 test_bus_selection[] = {0x1, 0x2, 0x3, 0x4, 0xD, 0x10,
-			0x41, 0x42, 0x43, 0x44, 0x45, 0x46};
 	u32 i;
-	u32 size = sizeof(test_bus_selection) / sizeof(u32);
 
-	for (i = 0; i < size; i++) {
-		bam_write_reg_field(base, TEST_BUS_SEL, BAM_TESTBUS_SEL,
-					test_bus_selection[i]);
-
-		SPS_INFO("sps:bam 0x%x(va);BAM_TEST_BUS_REG is"
-			"0x%x when BAM_TEST_BUS_SEL is 0x%x.",
-			(u32) base, bam_read_reg(base, TEST_BUS_REG),
-			bam_read_reg_field(base, TEST_BUS_SEL,
-					BAM_TESTBUS_SEL));
-	}
+	print_bam_test_bus_reg(base, 0);
 
 	print_bam_reg(base);
 
@@ -1001,7 +992,11 @@
 {
 	SPS_DBG2("sps:%s:bam=0x%x(va).pipe=%d.", __func__, (u32) base, pipe);
 
-	bam_write_reg_field(base, P_CTRL(pipe), P_EN, 1);
+	if (bam_read_reg_field(base, P_CTRL(pipe), P_EN))
+		SPS_DBG2("sps:bam=0x%x(va).pipe=%d is already enabled.\n",
+			(u32) base, pipe);
+	else
+		bam_write_reg_field(base, P_CTRL(pipe), P_EN, 1);
 }
 
 /**
@@ -1359,7 +1354,7 @@
 }
 
 /* output descriptor FIFO of a pipe */
-void print_bam_pipe_desc_fifo(void *virt_addr, u32 pipe_index)
+void print_bam_pipe_desc_fifo(void *virt_addr, u32 pipe_index, u32 option)
 {
 	void *base = virt_addr;
 	u32 pipe = pipe_index;
@@ -1393,33 +1388,93 @@
 
 	desc_fifo = (u32 *) phys_to_virt(desc_fifo_addr);
 
-	SPS_INFO("-------------------- begin of FIFO --------------------\n");
+	if (option == 100) {
+		SPS_INFO("----- start of data blocks -----\n");
+		for (i = 0; i < desc_fifo_size; i += 8) {
+			u32 *data_block_vir;
+			u32 data_block_phy = desc_fifo[i / 4];
 
-	for (i = 0; i < desc_fifo_size; i += 0x10)
-		SPS_INFO("addr 0x%x: 0x%x, 0x%x, 0x%x, 0x%x.\n",
-			desc_fifo_addr + i,
-			desc_fifo[i / 4], desc_fifo[(i / 4) + 1],
-			desc_fifo[(i / 4) + 2], desc_fifo[(i / 4) + 3]);
+			if (data_block_phy) {
+				data_block_vir =
+					(u32 *) phys_to_virt(data_block_phy);
 
-	SPS_INFO("--------------------  end of FIFO  --------------------\n");
+				SPS_INFO("desc addr:0x%x; data addr:0x%x:\n",
+					desc_fifo_addr + i, data_block_phy);
+				SPS_INFO("0x%x, 0x%x, 0x%x, 0x%x\n",
+					data_block_vir[0], data_block_vir[1],
+					data_block_vir[2], data_block_vir[3]);
+				SPS_INFO("0x%x, 0x%x, 0x%x, 0x%x\n",
+					data_block_vir[4], data_block_vir[5],
+					data_block_vir[6], data_block_vir[7]);
+				SPS_INFO("0x%x, 0x%x, 0x%x, 0x%x\n",
+					data_block_vir[8], data_block_vir[9],
+					data_block_vir[10], data_block_vir[11]);
+				SPS_INFO("0x%x, 0x%x, 0x%x, 0x%x\n\n",
+					data_block_vir[12], data_block_vir[13],
+					data_block_vir[14], data_block_vir[15]);
+			}
+		}
+		SPS_INFO("----- end of data blocks -----\n");
+	} else if (option) {
+		u32 size = option * 128;
+		u32 current_desc = bam_pipe_get_desc_read_offset(base,
+								pipe_index);
+		u32 begin = 0;
+		u32 end = desc_fifo_size;
+
+		if (current_desc > size / 2)
+			begin = current_desc - size / 2;
+
+		if (desc_fifo_size > current_desc + size / 2)
+			end = current_desc + size / 2;
+
+		SPS_INFO("------------- begin of partial FIFO -------------\n");
+
+		for (i = begin; i < end; i += 0x10)
+			SPS_INFO("addr 0x%x: 0x%x, 0x%x, 0x%x, 0x%x.\n",
+				desc_fifo_addr + i,
+				desc_fifo[i / 4], desc_fifo[(i / 4) + 1],
+				desc_fifo[(i / 4) + 2], desc_fifo[(i / 4) + 3]);
+
+		SPS_INFO("-------------  end of partial FIFO  -------------\n");
+	} else {
+		SPS_INFO("----------------- begin of FIFO -----------------\n");
+
+		for (i = 0; i < desc_fifo_size; i += 0x10)
+			SPS_INFO("addr 0x%x: 0x%x, 0x%x, 0x%x, 0x%x.\n",
+				desc_fifo_addr + i,
+				desc_fifo[i / 4], desc_fifo[(i / 4) + 1],
+				desc_fifo[(i / 4) + 2], desc_fifo[(i / 4) + 3]);
+
+		SPS_INFO("-----------------  end of FIFO  -----------------\n");
+	}
 }
 
 /* output BAM_TEST_BUS_REG with specified TEST_BUS_SEL */
 void print_bam_test_bus_reg(void *base, u32 tb_sel)
 {
 	u32 i;
-	u32 test_bus_selection[] = {0x1, 0x2, 0x3, 0x4, 0xD, 0x10,
+	u32 test_bus_selection[] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
+			0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
+			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+			0x20, 0x21, 0x22, 0x23,
 			0x41, 0x42, 0x43, 0x44, 0x45, 0x46};
 	u32 size = sizeof(test_bus_selection) / sizeof(u32);
 
-	if ((base == NULL) || (tb_sel == 0))
+	if (base == NULL) {
+		SPS_ERR("sps:%s:BAM is NULL.\n", __func__);
 		return;
+	}
 
-	SPS_INFO("\nsps:Specified TEST_BUS_SEL value: 0x%x\n", tb_sel);
-	bam_write_reg_field(base, TEST_BUS_SEL, BAM_TESTBUS_SEL, tb_sel);
-	SPS_INFO("sps:BAM_TEST_BUS_REG: 0x%x when TEST_BUS_SEL: 0x%x\n\n",
-		bam_read_reg(base, TEST_BUS_REG),
-		bam_read_reg_field(base, TEST_BUS_SEL, BAM_TESTBUS_SEL));
+	if (tb_sel) {
+		SPS_INFO("\nsps:Specified TEST_BUS_SEL value: 0x%x\n", tb_sel);
+		bam_write_reg_field(base, TEST_BUS_SEL, BAM_TESTBUS_SEL,
+					tb_sel);
+		SPS_INFO("sps:BAM_TEST_BUS_REG:0x%x for TEST_BUS_SEL:0x%x\n\n",
+			bam_read_reg(base, TEST_BUS_REG),
+			bam_read_reg_field(base, TEST_BUS_SEL,
+						BAM_TESTBUS_SEL));
+	}
 
 	/* output other selections */
 	for (i = 0; i < size; i++) {
diff --git a/drivers/platform/msm/sps/bam.h b/drivers/platform/msm/sps/bam.h
index c183fcd..2a7f05b 100644
--- a/drivers/platform/msm/sps/bam.h
+++ b/drivers/platform/msm/sps/bam.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
@@ -102,7 +102,7 @@
  *
  * @num_pipes - return number of pipes
  *
- * @p_rst - ignore external block pipe reset
+ * @options - BAM configuration options
  *
  * @return 0 on success, negative value on error
  *
@@ -111,7 +111,7 @@
 		u32 ee,
 		u16 summing_threshold,
 		u32 irq_mask, u32 *version,
-		u32 *num_pipes, u32 p_rst);
+		u32 *num_pipes, u32 options);
 
 /**
  * Initialize BAM device security execution environment
diff --git a/drivers/platform/msm/sps/sps.c b/drivers/platform/msm/sps/sps.c
index e9c3371..37dfc1b 100644
--- a/drivers/platform/msm/sps/sps.c
+++ b/drivers/platform/msm/sps/sps.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
@@ -91,7 +91,7 @@
 u8 reg_dump_option;
 u32 testbus_sel;
 u32 bam_pipe_sel;
-
+u32 desc_option;
 
 static char *debugfs_buf;
 static u32 debugfs_buf_size;
@@ -106,6 +106,7 @@
 struct dentry *dfile_reg_dump_option;
 struct dentry *dfile_testbus_sel;
 struct dentry *dfile_bam_pipe_sel;
+struct dentry *dfile_desc_option;
 struct dentry *dfile_bam_addr;
 
 static struct sps_bam *phy2bam(u32 phys_addr);
@@ -341,41 +342,187 @@
 		break;
 	case 7: /* output desc FIFO of all pipes */
 		for (i = 0; i < num_pipes; i++)
-			print_bam_pipe_desc_fifo(vir_addr, i);
+			print_bam_pipe_desc_fifo(vir_addr, i, 0);
 		break;
 	case 8: /* output desc FIFO of selected pipes */
 		for (i = 0; i < num_pipes; i++)
 			if (bam_pipe_sel & (1UL << i))
-				print_bam_pipe_desc_fifo(vir_addr, i);
+				print_bam_pipe_desc_fifo(vir_addr, i, 0);
 		break;
 	case 9: /* output desc FIFO of typical pipes */
-		print_bam_pipe_desc_fifo(vir_addr, 4);
-		print_bam_pipe_desc_fifo(vir_addr, 5);
+		print_bam_pipe_desc_fifo(vir_addr, 4, 0);
+		print_bam_pipe_desc_fifo(vir_addr, 5, 0);
 		break;
 	case 10: /* output selected registers and desc FIFO of all pipes */
 		for (i = 0; i < num_pipes; i++) {
 			print_bam_pipe_selected_reg(vir_addr, i);
-			print_bam_pipe_desc_fifo(vir_addr, i);
+			print_bam_pipe_desc_fifo(vir_addr, i, 0);
 		}
 		break;
 	case 11: /* output selected registers and desc FIFO of selected pipes */
 		for (i = 0; i < num_pipes; i++)
 			if (bam_pipe_sel & (1UL << i)) {
 				print_bam_pipe_selected_reg(vir_addr, i);
-				print_bam_pipe_desc_fifo(vir_addr, i);
+				print_bam_pipe_desc_fifo(vir_addr, i, 0);
 			}
 		break;
 	case 12: /* output selected registers and desc FIFO of typical pipes */
 		print_bam_pipe_selected_reg(vir_addr, 4);
-		print_bam_pipe_desc_fifo(vir_addr, 4);
+		print_bam_pipe_desc_fifo(vir_addr, 4, 0);
 		print_bam_pipe_selected_reg(vir_addr, 5);
-		print_bam_pipe_desc_fifo(vir_addr, 5);
+		print_bam_pipe_desc_fifo(vir_addr, 5, 0);
 		break;
 	case 13: /* output BAM_TEST_BUS_REG */
 		if (testbus_sel)
 			print_bam_test_bus_reg(vir_addr, testbus_sel);
-		else
-			pr_info("sps:TEST_BUS_SEL should NOT be zero.");
+		else {
+			pr_info("sps:output TEST_BUS_REG for all TEST_BUS_SEL");
+			print_bam_test_bus_reg(vir_addr, testbus_sel);
+		}
+		break;
+	case 14: /* output partial desc FIFO of selected pipes */
+		if (desc_option == 0)
+			desc_option = 1;
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_desc_fifo(vir_addr, i,
+							desc_option);
+		break;
+	case 15: /* output partial data blocks of descriptors */
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_desc_fifo(vir_addr, i, 100);
+		break;
+	case 16: /* output all registers of selected pipes */
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_reg(vir_addr, i);
+		break;
+	case 91: /* output testbus register, BAM global regisers
+			and registers of all pipes */
+		print_bam_test_bus_reg(vir_addr, testbus_sel);
+		print_bam_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			print_bam_pipe_reg(vir_addr, i);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			print_bam_pipe_selected_reg(vir_addr, i);
+		break;
+	case 92: /* output testbus register, BAM global regisers
+			and registers of selected pipes */
+		print_bam_test_bus_reg(vir_addr, testbus_sel);
+		print_bam_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_reg(vir_addr, i);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_selected_reg(vir_addr, i);
+		break;
+	case 93: /* output registers and partial desc FIFOs
+			of selected pipes: format 1 */
+		if (desc_option == 0)
+			desc_option = 1;
+		print_bam_test_bus_reg(vir_addr, testbus_sel);
+		print_bam_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_reg(vir_addr, i);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_selected_reg(vir_addr, i);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_desc_fifo(vir_addr, i,
+							desc_option);
+		break;
+	case 94: /* output registers and partial desc FIFOs
+			of selected pipes: format 2 */
+		if (desc_option == 0)
+			desc_option = 1;
+		print_bam_test_bus_reg(vir_addr, testbus_sel);
+		print_bam_reg(vir_addr);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i)) {
+				print_bam_pipe_reg(vir_addr, i);
+				print_bam_pipe_selected_reg(vir_addr, i);
+				print_bam_pipe_desc_fifo(vir_addr, i,
+							desc_option);
+			}
+		break;
+	case 95: /* output registers and desc FIFOs
+			of selected pipes: format 1 */
+		print_bam_test_bus_reg(vir_addr, testbus_sel);
+		print_bam_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_reg(vir_addr, i);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_selected_reg(vir_addr, i);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_desc_fifo(vir_addr, i, 0);
+		break;
+	case 96: /* output registers and desc FIFOs
+			of selected pipes: format 2 */
+		print_bam_test_bus_reg(vir_addr, testbus_sel);
+		print_bam_reg(vir_addr);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i)) {
+				print_bam_pipe_reg(vir_addr, i);
+				print_bam_pipe_selected_reg(vir_addr, i);
+				print_bam_pipe_desc_fifo(vir_addr, i, 0);
+			}
+		break;
+	case 97: /* output registers, desc FIFOs and partial data blocks
+			of selected pipes: format 1 */
+		print_bam_test_bus_reg(vir_addr, testbus_sel);
+		print_bam_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_reg(vir_addr, i);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_selected_reg(vir_addr, i);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_desc_fifo(vir_addr, i, 0);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_desc_fifo(vir_addr, i, 100);
+		break;
+	case 98: /* output registers, desc FIFOs and partial data blocks
+			of selected pipes: format 2 */
+		print_bam_test_bus_reg(vir_addr, testbus_sel);
+		print_bam_reg(vir_addr);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i)) {
+				print_bam_pipe_reg(vir_addr, i);
+				print_bam_pipe_selected_reg(vir_addr, i);
+				print_bam_pipe_desc_fifo(vir_addr, i, 0);
+				print_bam_pipe_desc_fifo(vir_addr, i, 100);
+			}
+		break;
+	case 99: /* output all registers, desc FIFOs and partial data blocks */
+		print_bam_test_bus_reg(vir_addr, testbus_sel);
+		print_bam_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			print_bam_pipe_reg(vir_addr, i);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			print_bam_pipe_selected_reg(vir_addr, i);
+		for (i = 0; i < num_pipes; i++)
+			print_bam_pipe_desc_fifo(vir_addr, i, 0);
+		for (i = 0; i < num_pipes; i++)
+			print_bam_pipe_desc_fifo(vir_addr, i, 100);
 		break;
 	default:
 		pr_info("sps:no dump option is chosen yet.");
@@ -397,6 +544,7 @@
 	reg_dump_option = 0;
 	testbus_sel = 0;
 	bam_pipe_sel = 0;
+	desc_option = 0;
 	debugfs_buf_size = 0;
 	debugfs_buf_used = 0;
 	wraparound = false;
@@ -460,6 +608,13 @@
 		goto bam_pipe_sel_err;
 	}
 
+	dfile_desc_option = debugfs_create_u32("desc_option", 0666,
+						dent, &desc_option);
+	if (!dfile_desc_option || IS_ERR(dfile_desc_option)) {
+		pr_err("sps:fail to create debug_fs file for desc_option.\n");
+		goto desc_option_err;
+	}
+
 	dfile_bam_addr = debugfs_create_file("bam_addr", 0666,
 			dent, 0, &sps_bam_addr_ops);
 	if (!dfile_bam_addr || IS_ERR(dfile_bam_addr)) {
@@ -471,6 +626,8 @@
 	return;
 
 bam_addr_err:
+	debugfs_remove(dfile_desc_option);
+desc_option_err:
 	debugfs_remove(dfile_bam_pipe_sel);
 bam_pipe_sel_err:
 	debugfs_remove(dfile_testbus_sel);
@@ -504,6 +661,8 @@
 		debugfs_remove(dfile_testbus_sel);
 	if (dfile_bam_pipe_sel)
 		debugfs_remove(dfile_bam_pipe_sel);
+	if (dfile_desc_option)
+		debugfs_remove(dfile_desc_option);
 	if (dfile_bam_addr)
 		debugfs_remove(dfile_bam_addr);
 	if (dent)
@@ -515,7 +674,7 @@
 
 /* Get the debug info of BAM registers and descriptor FIFOs */
 int sps_get_bam_debug_info(u32 dev, u32 option, u32 para,
-		u32 tb_sel, u8 pre_level)
+		u32 tb_sel, u8 desc_sel)
 {
 	int res = 0;
 	struct sps_bam *bam;
@@ -568,35 +727,35 @@
 		break;
 	case 7: /* output desc FIFO of all pipes */
 		for (i = 0; i < num_pipes; i++)
-			print_bam_pipe_desc_fifo(vir_addr, i);
+			print_bam_pipe_desc_fifo(vir_addr, i, 0);
 		break;
 	case 8: /* output desc FIFO of selected pipes */
 		for (i = 0; i < num_pipes; i++)
 			if (para & (1UL << i))
-				print_bam_pipe_desc_fifo(vir_addr, i);
+				print_bam_pipe_desc_fifo(vir_addr, i, 0);
 		break;
 	case 9: /* output desc FIFO of typical pipes */
-		print_bam_pipe_desc_fifo(vir_addr, 4);
-		print_bam_pipe_desc_fifo(vir_addr, 5);
+		print_bam_pipe_desc_fifo(vir_addr, 4, 0);
+		print_bam_pipe_desc_fifo(vir_addr, 5, 0);
 		break;
 	case 10: /* output selected registers and desc FIFO of all pipes */
 		for (i = 0; i < num_pipes; i++) {
 			print_bam_pipe_selected_reg(vir_addr, i);
-			print_bam_pipe_desc_fifo(vir_addr, i);
+			print_bam_pipe_desc_fifo(vir_addr, i, 0);
 		}
 		break;
 	case 11: /* output selected registers and desc FIFO of selected pipes */
 		for (i = 0; i < num_pipes; i++)
 			if (para & (1UL << i)) {
 				print_bam_pipe_selected_reg(vir_addr, i);
-				print_bam_pipe_desc_fifo(vir_addr, i);
+				print_bam_pipe_desc_fifo(vir_addr, i, 0);
 			}
 		break;
 	case 12: /* output selected registers and desc FIFO of typical pipes */
 		print_bam_pipe_selected_reg(vir_addr, 4);
-		print_bam_pipe_desc_fifo(vir_addr, 4);
+		print_bam_pipe_desc_fifo(vir_addr, 4, 0);
 		print_bam_pipe_selected_reg(vir_addr, 5);
-		print_bam_pipe_desc_fifo(vir_addr, 5);
+		print_bam_pipe_desc_fifo(vir_addr, 5, 0);
 		break;
 	case 13: /* output BAM_TEST_BUS_REG */
 		if (tb_sel)
@@ -604,6 +763,150 @@
 		else
 			pr_info("sps:TEST_BUS_SEL should NOT be zero.");
 		break;
+	case 14: /* output partial desc FIFO of selected pipes */
+		if (desc_sel == 0)
+			desc_sel = 1;
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_desc_fifo(vir_addr, i,
+							desc_sel);
+		break;
+	case 15: /* output partial data blocks of descriptors */
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_desc_fifo(vir_addr, i, 100);
+		break;
+	case 16: /* output all registers of selected pipes */
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_reg(vir_addr, i);
+		break;
+	case 91: /* output testbus register, BAM global regisers
+			and registers of all pipes */
+		print_bam_test_bus_reg(vir_addr, tb_sel);
+		print_bam_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			print_bam_pipe_reg(vir_addr, i);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			print_bam_pipe_selected_reg(vir_addr, i);
+		break;
+	case 92: /* output testbus register, BAM global regisers
+			and registers of selected pipes */
+		print_bam_test_bus_reg(vir_addr, tb_sel);
+		print_bam_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_reg(vir_addr, i);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_selected_reg(vir_addr, i);
+		break;
+	case 93: /* output registers and partial desc FIFOs
+			of selected pipes: format 1 */
+		if (desc_sel == 0)
+			desc_sel = 1;
+		print_bam_test_bus_reg(vir_addr, tb_sel);
+		print_bam_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_reg(vir_addr, i);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_selected_reg(vir_addr, i);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_desc_fifo(vir_addr, i,
+							desc_sel);
+		break;
+	case 94: /* output registers and partial desc FIFOs
+			of selected pipes: format 2 */
+		if (desc_sel == 0)
+			desc_sel = 1;
+		print_bam_test_bus_reg(vir_addr, tb_sel);
+		print_bam_reg(vir_addr);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i)) {
+				print_bam_pipe_reg(vir_addr, i);
+				print_bam_pipe_selected_reg(vir_addr, i);
+				print_bam_pipe_desc_fifo(vir_addr, i,
+							desc_sel);
+			}
+		break;
+	case 95: /* output registers and desc FIFOs
+			of selected pipes: format 1 */
+		print_bam_test_bus_reg(vir_addr, tb_sel);
+		print_bam_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_reg(vir_addr, i);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_selected_reg(vir_addr, i);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_desc_fifo(vir_addr, i, 0);
+		break;
+	case 96: /* output registers and desc FIFOs
+			of selected pipes: format 2 */
+		print_bam_test_bus_reg(vir_addr, tb_sel);
+		print_bam_reg(vir_addr);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i)) {
+				print_bam_pipe_reg(vir_addr, i);
+				print_bam_pipe_selected_reg(vir_addr, i);
+				print_bam_pipe_desc_fifo(vir_addr, i, 0);
+			}
+		break;
+	case 97: /* output registers, desc FIFOs and partial data blocks
+			of selected pipes: format 1 */
+		print_bam_test_bus_reg(vir_addr, tb_sel);
+		print_bam_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_reg(vir_addr, i);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_selected_reg(vir_addr, i);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_desc_fifo(vir_addr, i, 0);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_desc_fifo(vir_addr, i, 100);
+		break;
+	case 98: /* output registers, desc FIFOs and partial data blocks
+			of selected pipes: format 2 */
+		print_bam_test_bus_reg(vir_addr, tb_sel);
+		print_bam_reg(vir_addr);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i)) {
+				print_bam_pipe_reg(vir_addr, i);
+				print_bam_pipe_selected_reg(vir_addr, i);
+				print_bam_pipe_desc_fifo(vir_addr, i, 0);
+				print_bam_pipe_desc_fifo(vir_addr, i, 100);
+			}
+		break;
+	case 99: /* output all registers, desc FIFOs and partial data blocks */
+		print_bam_test_bus_reg(vir_addr, tb_sel);
+		print_bam_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			print_bam_pipe_reg(vir_addr, i);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			print_bam_pipe_selected_reg(vir_addr, i);
+		for (i = 0; i < num_pipes; i++)
+			print_bam_pipe_desc_fifo(vir_addr, i, 0);
+		for (i = 0; i < num_pipes; i++)
+			print_bam_pipe_desc_fifo(vir_addr, i, 100);
+		break;
 	default:
 		pr_info("sps:no option is chosen yet.");
 	}
diff --git a/drivers/platform/msm/sps/sps_bam.c b/drivers/platform/msm/sps/sps_bam.c
index af421ac..5ad281d 100644
--- a/drivers/platform/msm/sps/sps_bam.c
+++ b/drivers/platform/msm/sps/sps_bam.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -165,7 +165,8 @@
 
 	list_for_each_entry(pipe, &dev->pipes_q, list) {
 		/* Check this pipe's bit in the source mask */
-		if ((source & pipe->pipe_index_mask)) {
+		if (BAM_PIPE_IS_ASSIGNED(pipe)
+				&& (source & pipe->pipe_index_mask)) {
 			/* This pipe has an interrupt pending */
 			pipe_handler(dev, pipe);
 			source &= ~pipe->pipe_index_mask;
@@ -255,7 +256,7 @@
 				  (u16) dev->props.summing_threshold,
 				  irq_mask,
 				  &dev->version, &num_pipes,
-				  dev->props.options & SPS_BAM_NO_EXT_P_RST);
+				  dev->props.options);
 	else
 		/* No, so just verify that it is enabled */
 		rc = bam_check(dev->base, &dev->version, &num_pipes);
@@ -1049,6 +1050,13 @@
 		else {
 			pipe->sys.desc_cache =
 				vmalloc(pipe->desc_size + size);
+
+			if (pipe->sys.desc_cache == NULL) {
+				SPS_ERR("sps:No memory for pipe %d of BAM 0x%x",
+					pipe_index, BAM_ID(dev));
+				return -ENOMEM;
+			}
+
 			memset(pipe->sys.desc_cache, 0, pipe->desc_size + size);
 		}
 
diff --git a/drivers/platform/msm/sps/sps_bam.h b/drivers/platform/msm/sps/sps_bam.h
index 84d2b97..bbc0373 100644
--- a/drivers/platform/msm/sps/sps_bam.h
+++ b/drivers/platform/msm/sps/sps_bam.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/drivers/platform/msm/sps/sps_core.h b/drivers/platform/msm/sps/sps_core.h
index 5bd7c65..9bd079e 100644
--- a/drivers/platform/msm/sps/sps_core.h
+++ b/drivers/platform/msm/sps/sps_core.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/platform/msm/sps/sps_dma.c b/drivers/platform/msm/sps/sps_dma.c
index 335de9a..14d5c49 100644
--- a/drivers/platform/msm/sps/sps_dma.c
+++ b/drivers/platform/msm/sps/sps_dma.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/drivers/platform/msm/sps/sps_map.c b/drivers/platform/msm/sps/sps_map.c
index d98a8b1..d007b31 100644
--- a/drivers/platform/msm/sps/sps_map.c
+++ b/drivers/platform/msm/sps/sps_map.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/drivers/platform/msm/sps/sps_map.h b/drivers/platform/msm/sps/sps_map.h
index 692e47c..7db8043 100644
--- a/drivers/platform/msm/sps/sps_map.h
+++ b/drivers/platform/msm/sps/sps_map.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/platform/msm/sps/sps_mem.c b/drivers/platform/msm/sps/sps_mem.c
index fa22f1c..b44e3c4 100644
--- a/drivers/platform/msm/sps/sps_mem.c
+++ b/drivers/platform/msm/sps/sps_mem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/drivers/platform/msm/sps/sps_rm.c b/drivers/platform/msm/sps/sps_rm.c
index c980eb0..2b46203 100644
--- a/drivers/platform/msm/sps/sps_rm.c
+++ b/drivers/platform/msm/sps/sps_rm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -18,6 +18,7 @@
 #include <linux/list.h>		/* list_head */
 #include <linux/slab.h>		/* kzalloc() */
 #include <linux/memory.h>	/* memset */
+#include <linux/interrupt.h>
 
 #include "spsi.h"
 #include "sps_core.h"
@@ -555,8 +556,11 @@
 {
 	struct sps_connection *map = (void *)pipe->map;
 	struct sps_connect *cfg = &pipe->connect;
+	struct sps_bam *bam = pipe->bam;
+	unsigned long flags;
 
 	mutex_lock(&sps_rm->lock);
+	spin_lock_irqsave(&bam->isr_lock, flags);
 
 	/* Free this connection */
 	if (cfg->mode == SPS_MODE_SRC)
@@ -570,6 +574,7 @@
 
 	sps_rm_remove_ref(map);
 
+	spin_unlock_irqrestore(&bam->isr_lock, flags);
 	mutex_unlock(&sps_rm->lock);
 
 	return 0;
@@ -782,6 +787,8 @@
 	if (pipe->client_state == SPS_STATE_CONNECT &&
 	    state == SPS_STATE_DISCONNECT) {
 		struct sps_connection *map;
+		struct sps_bam *bam = pipe->bam;
+		unsigned long flags;
 		u32 pipe_index;
 
 		if (pipe->connect.mode == SPS_MODE_SRC)
@@ -789,8 +796,12 @@
 		else
 			pipe_index = pipe->map->dest.pipe_index;
 
+		if (bam->props.irq > 0)
+			synchronize_irq(bam->props.irq);
 
+		spin_lock_irqsave(&bam->isr_lock, flags);
 		result = sps_bam_pipe_disconnect(pipe->bam, pipe_index);
+		spin_unlock_irqrestore(&bam->isr_lock, flags);
 		if (result) {
 			SPS_ERR("sps:Failed to disconnect BAM 0x%x pipe %d",
 				pipe->bam->props.phys_addr,
diff --git a/drivers/platform/msm/sps/spsi.h b/drivers/platform/msm/sps/spsi.h
index 8a5deff..5b70fb0 100644
--- a/drivers/platform/msm/sps/spsi.h
+++ b/drivers/platform/msm/sps/spsi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
@@ -198,7 +198,7 @@
 void print_bam_pipe_selected_reg(void *, u32);
 
 /* output descriptor FIFO of a pipe */
-void print_bam_pipe_desc_fifo(void *, u32);
+void print_bam_pipe_desc_fifo(void *, u32, u32);
 
 /* output BAM_TEST_BUS_REG */
 void print_bam_test_bus_reg(void *, u32);
diff --git a/drivers/platform/msm/ssbi.c b/drivers/platform/msm/ssbi.c
index 265d56f..e0bbdd1 100644
--- a/drivers/platform/msm/ssbi.c
+++ b/drivers/platform/msm/ssbi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
  * Copyright (c) 2010, Google Inc.
  *
  * Original authors: Code Aurora Forum
@@ -362,7 +362,7 @@
 
 	ssbi->base = ioremap(mem_res->start, resource_size(mem_res));
 	if (!ssbi->base) {
-		pr_err("ioremap of 0x%p failed\n", (void *)mem_res->start);
+		pr_err("ioremap failed: %pr\n", mem_res);
 		ret = -EINVAL;
 		goto err_ioremap;
 	}
diff --git a/drivers/platform/msm/ssm.c b/drivers/platform/msm/ssm.c
new file mode 100644
index 0000000..c57bb91
--- /dev/null
+++ b/drivers/platform/msm/ssm.c
@@ -0,0 +1,931 @@
+/* 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.
+ */
+/*
+ * Qualcomm Secure Service Module(SSM) driver
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/of.h>
+#include <linux/cdev.h>
+#include <linux/uaccess.h>
+#include <linux/mutex.h>
+#include <linux/ion.h>
+#include <linux/types.h>
+#include <linux/firmware.h>
+#include <linux/elf.h>
+#include <linux/platform_device.h>
+#include <linux/msm_ion.h>
+#include <linux/platform_data/qcom_ssm.h>
+#include <mach/scm.h>
+#include <mach/msm_smd.h>
+
+#include "ssm.h"
+
+/* Macros */
+#define SSM_DEV_NAME			"ssm"
+#define MPSS_SUBSYS			0
+#define SSM_INFO_CMD_ID			1
+#define QSEOS_CHECK_VERSION_CMD		0x00001803
+
+#define MAX_APP_NAME_SIZE		32
+#define SSM_MSG_LEN			(104  + 4) /* bytes + pad */
+#define SSM_MSG_FIELD_LEN		11
+#define SSM_HEADER_LEN			(SSM_MSG_FIELD_LEN * 4)
+#define ATOM_MSG_LEN			(SSM_HEADER_LEN + SSM_MSG_LEN)
+#define FIRMWARE_NAME			"ssmapp"
+#define TZAPP_NAME			"SsmApp"
+#define CHANNEL_NAME			"SSM_RTR"
+
+#define ALIGN_BUFFER(size)		((size + 4095) & ~4095)
+
+/* SSM driver structure.*/
+struct ssm_driver {
+	int32_t app_id;
+	int32_t app_status;
+	int32_t update_status;
+	int32_t atom_replay;
+	int32_t mtoa_replay;
+	uint32_t buff_len;
+	unsigned char *channel_name;
+	unsigned char *smd_buffer;
+	struct ion_client *ssm_ion_client;
+	struct ion_handle *ssm_ion_handle;
+	struct tzapp_get_mode_info_rsp *resp;
+	struct device *dev;
+	smd_channel_t *ch;
+	ion_phys_addr_t buff_phys;
+	ion_virt_addr_t buff_virt;
+	dev_t ssm_device_no;
+	struct work_struct ipc_work;
+	struct mutex mutex;
+	bool key_status;
+	bool ready;
+};
+
+static struct ssm_driver *ssm_drv;
+
+static unsigned int getint(char *buff, unsigned long *res)
+{
+	char value[SSM_MSG_FIELD_LEN];
+
+	memcpy(value, buff, SSM_MSG_FIELD_LEN);
+	value[SSM_MSG_FIELD_LEN - 1] = '\0';
+
+	return kstrtoul(skip_spaces(value), 10, res);
+}
+
+/*
+ * Send packet to modem over SMD channel.
+ */
+static int update_modem(enum ssm_ipc_req ipc_req, struct ssm_driver *ssm,
+		int length, char *data)
+{
+	unsigned int packet_len = SSM_HEADER_LEN + length + 1;
+	int rc = 0;
+
+	ssm->atom_replay += 1;
+	snprintf(ssm->smd_buffer, SSM_HEADER_LEN + 1, "%10u|%10u|%10u|%10u|"
+			, packet_len, ssm->atom_replay, ipc_req, length);
+	memcpy(ssm->smd_buffer + SSM_HEADER_LEN, data, length);
+
+	ssm->smd_buffer[packet_len - 1] = '|';
+
+	if (smd_write_avail(ssm->ch) < packet_len) {
+		dev_err(ssm->dev, "Not enough space dropping request\n");
+		rc = -ENOSPC;
+	}
+
+	rc = smd_write(ssm->ch, ssm->smd_buffer, packet_len);
+	if (rc < packet_len) {
+		dev_err(ssm->dev, "smd_write failed for %d\n", ipc_req);
+		rc = -EIO;
+	}
+
+	return rc;
+}
+
+/*
+ * Header Format
+ * Each member of header is of 10 byte (ASCII).
+ * Each entry is separated by '|' delimiter.
+ * |<-10 bytes->|<-10 bytes->|<-10 bytes->|<-10 bytes->|<-10 bytes->|
+ * |-----------------------------------------------------------------
+ * | length     | replay no. | request    | msg_len    | message    |
+ * |-----------------------------------------------------------------
+ *
+ */
+static int  decode_header(char *buffer, int length,
+		struct ssm_common_msg *pkt)
+{
+	int rc;
+
+	rc =  getint(buffer, &pkt->pktlen);
+	if (rc < 0)
+		return -EINVAL;
+
+	buffer += SSM_MSG_FIELD_LEN;
+	rc =  getint(buffer, &pkt->replaynum);
+	if (rc < 0)
+		return -EINVAL;
+
+	buffer += SSM_MSG_FIELD_LEN;
+	rc =  getint(buffer, (unsigned long *)&pkt->ipc_req);
+	if (rc < 0)
+		return -EINVAL;
+
+	buffer += SSM_MSG_FIELD_LEN;
+	rc =  getint(buffer, &pkt->msg_len);
+	if ((rc < 0) || (pkt->msg_len > SSM_MSG_LEN))
+		return -EINVAL;
+
+	pkt->msg = buffer + SSM_MSG_FIELD_LEN;
+
+	dev_dbg(ssm_drv->dev, "len %lu rep %lu req %d msg_len %lu\n",
+			pkt->pktlen, pkt->replaynum, pkt->ipc_req,
+			pkt->msg_len);
+	return 0;
+}
+
+/*
+ * Decode address for storing the decryption key.
+ * Only for Key Exchange
+ * Message Format
+ * |Length@Address|
+ */
+static int decode_message(char *msg, unsigned int len, unsigned long *length,
+		unsigned long *address)
+{
+	int i = 0, rc = 0;
+	char *buff;
+
+	buff = kzalloc(len, GFP_KERNEL);
+	if (!buff)
+		return -ENOMEM;
+	while (i < len) {
+		if (msg[i] == '@')
+			break;
+		i++;
+	}
+	if ((i < len) && (msg[i] == '@')) {
+		memcpy(buff, msg, i);
+		buff[i] = '\0';
+		rc = kstrtoul(skip_spaces(buff), 10, length);
+		if (rc || (length <= 0)) {
+			rc = -EINVAL;
+			goto exit;
+		}
+		memcpy(buff, &msg[i + 1], len - (i + 1));
+		buff[len - i] = '\0';
+		rc = kstrtoul(skip_spaces(buff), 10, address);
+	} else
+		rc = -EINVAL;
+
+exit:
+	kfree(buff);
+	return rc;
+}
+
+static void process_message(int cmd, char *msg, int len,
+		struct ssm_driver *ssm)
+{
+	int rc;
+	unsigned long key_len = 0, key_add = 0, val;
+	struct ssm_keyexchg_req req;
+
+	switch (cmd) {
+	case SSM_MTOA_KEY_EXCHANGE:
+		if (len < 3) {
+			dev_err(ssm->dev, "Invalid message\n");
+			break;
+		}
+
+		if (ssm->key_status) {
+			dev_err(ssm->dev, "Key exchange already done\n");
+			break;
+		}
+
+		rc = decode_message(msg, len, &key_len, &key_add);
+		if (rc) {
+			rc = update_modem(SSM_ATOM_KEY_STATUS, ssm,
+					1, "1");
+			break;
+		}
+
+		/*
+		 * We are doing key-exchange part here as it is very
+		 * specific for this case. For all other tz
+		 * communication we have generic function.
+		 */
+		req.ssid = MPSS_SUBSYS;
+		req.address = (void *)key_add;
+		req.length = key_len;
+		req.status = (uint32_t *)ssm->buff_phys;
+
+		*(unsigned int *)ssm->buff_virt = -1;
+		rc = scm_call(KEY_EXCHANGE, 0x1, &req,
+				sizeof(struct ssm_keyexchg_req), NULL, 0);
+		if (rc) {
+			dev_err(ssm->dev, "Call for key exchg failed %d", rc);
+			rc = update_modem(SSM_ATOM_KEY_STATUS, ssm,
+								1, "1");
+		} else {
+			/* Success encode packet and update modem */
+			rc = update_modem(SSM_ATOM_KEY_STATUS, ssm,
+					1, "0");
+			ssm->key_status = true;
+		}
+		break;
+
+	case SSM_MTOA_MODE_UPDATE_STATUS:
+		msg[len] = '\0';
+		rc = kstrtoul(skip_spaces(msg), 10, &val);
+		if (val) {
+			dev_err(ssm->dev, "Modem mode update failed\n");
+			ssm->update_status = FAILED;
+		} else
+			ssm->update_status = SUCCESS;
+
+		dev_dbg(ssm->dev, "Modem mode update status %lu\n", val);
+		break;
+
+	default:
+		dev_dbg(ssm->dev, "Invalid message\n");
+		break;
+	};
+}
+
+/*
+ * Work function to handle and process packets coming from modem.
+ */
+static void ssm_app_modem_work_fn(struct work_struct *work)
+{
+	int sz, rc;
+	struct ssm_common_msg pkt;
+	struct ssm_driver *ssm;
+
+	ssm = container_of(work, struct ssm_driver, ipc_work);
+
+	mutex_lock(&ssm->mutex);
+	sz = smd_cur_packet_size(ssm->ch);
+	if ((sz <= 0) || (sz > ATOM_MSG_LEN)) {
+		dev_dbg(ssm_drv->dev, "Garbled message size\n");
+		goto unlock;
+	}
+
+	if (smd_read_avail(ssm->ch) < sz) {
+		dev_err(ssm_drv->dev, "SMD error data in channel\n");
+		goto unlock;
+	}
+
+	if (sz < SSM_HEADER_LEN) {
+		dev_err(ssm_drv->dev, "Invalid packet\n");
+		goto unlock;
+	}
+
+	if (smd_read(ssm->ch, ssm->smd_buffer, sz) != sz) {
+		dev_err(ssm_drv->dev, "Incomplete data\n");
+		goto unlock;
+	}
+
+	rc = decode_header(ssm->smd_buffer, sz, &pkt);
+	if (rc < 0) {
+		dev_err(ssm_drv->dev, "Corrupted header\n");
+		goto unlock;
+	}
+
+	/* Check validity of message */
+	if (ssm->mtoa_replay >= (int)pkt.replaynum) {
+		dev_err(ssm_drv->dev, "Replay attack...\n");
+		goto unlock;
+	}
+
+	if (pkt.msg[pkt.msg_len] != '|') {
+		dev_err(ssm_drv->dev, "Garbled message\n");
+		goto unlock;
+	}
+
+	ssm->mtoa_replay = pkt.replaynum;
+	process_message(pkt.ipc_req, pkt.msg, pkt.msg_len, ssm);
+
+unlock:
+	mutex_unlock(&ssm->mutex);
+}
+
+/*
+ * MODEM-APPS smd channel callback function.
+ */
+static void modem_request(void *ctxt, unsigned event)
+{
+	struct ssm_driver *ssm;
+
+	ssm = (struct ssm_driver *)ctxt;
+
+	switch (event) {
+	case SMD_EVENT_OPEN:
+	case SMD_EVENT_CLOSE:
+		dev_info(ssm->dev, "Port %s\n",
+			(event == SMD_EVENT_OPEN) ? "opened" : "closed");
+		break;
+	case SMD_EVENT_DATA:
+		if (smd_read_avail(ssm->ch) > 0)
+			schedule_work(&ssm->ipc_work);
+		break;
+	};
+}
+
+/*
+ * Communication interface between ssm driver and TZ.
+ */
+static int tz_scm_call(struct ssm_driver *ssm, void *tz_req, int tz_req_len,
+			void **tz_resp, int tz_resp_len)
+{
+	int rc;
+	struct common_req req;
+	struct common_resp resp;
+
+	memcpy((void *)ssm->buff_virt, tz_req, tz_req_len);
+
+	req.cmd_id = CLIENT_SEND_DATA_COMMAND;
+	req.app_id = ssm->app_id;
+	req.req_ptr = (void *)ssm->buff_phys;
+	req.req_len = tz_req_len;
+	req.resp_ptr = (void *)(ssm->buff_phys + tz_req_len);
+	req.resp_len = tz_resp_len;
+
+	rc = scm_call(SCM_SVC_TZSCHEDULER, 1, (const void *) &req,
+			sizeof(req), (void *)&resp, sizeof(resp));
+	if (rc) {
+		dev_err(ssm->dev, "SCM call failed for data command\n");
+		return rc;
+	}
+
+	if (resp.result != RESULT_SUCCESS) {
+		dev_err(ssm->dev, "Data command response failure %d\n",
+				resp.result);
+		return -EINVAL;
+	}
+
+	*tz_resp = (void *)(ssm->buff_virt + tz_req_len);
+
+	return rc;
+}
+
+/*
+ * Load SSM application in TZ and start application:
+ * 1. Check if SSM application is already loaded.
+ * 2. Load SSM application firmware.
+ * 3. Start SSM application in TZ.
+ */
+static int ssm_load_app(struct ssm_driver *ssm)
+{
+	unsigned char name[MAX_APP_NAME_SIZE], *pos;
+	int rc, i, fw_count;
+	uint32_t buff_len, size = 0, ion_len;
+	struct check_app_req app_req;
+	struct scm_resp app_resp;
+	struct load_app app_img_info;
+	const struct firmware **fw, *fw_mdt;
+	const struct elf32_hdr *ehdr;
+	const struct elf32_phdr *phdr;
+	struct ion_handle *ion_handle;
+	ion_phys_addr_t buff_phys;
+	ion_virt_addr_t buff_virt;
+
+	/* Check if TZ app already loaded */
+	app_req.cmd_id = APP_LOOKUP_COMMAND;
+	memcpy(app_req.app_name, TZAPP_NAME, MAX_APP_NAME_SIZE);
+
+	rc = scm_call(SCM_SVC_TZSCHEDULER, 1, &app_req,
+				sizeof(struct check_app_req),
+				&app_resp, sizeof(app_resp));
+	if (rc) {
+		dev_err(ssm->dev, "SCM call failed for LOOKUP COMMAND\n");
+		return -EINVAL;
+	}
+
+	if (app_resp.result == RESULT_FAILURE)
+		ssm->app_id = 0;
+	else
+		ssm->app_id = app_resp.data;
+
+	if (ssm->app_id) {
+		rc = 0;
+		dev_info(ssm->dev, "TZAPP already loaded...\n");
+		goto out;
+	}
+
+	/* APP not loaded get the firmware */
+	/* Get .mdt first */
+	rc =  request_firmware(&fw_mdt, FIRMWARE_NAME".mdt", ssm->dev);
+	if (rc) {
+		dev_err(ssm->dev, "Unable to get mdt file %s\n",
+						FIRMWARE_NAME".mdt");
+		rc = -EIO;
+		goto out;
+	}
+
+	if (fw_mdt->size < sizeof(*ehdr)) {
+		dev_err(ssm->dev, "Not big enough to be an elf header\n");
+		rc = -EIO;
+		goto release_mdt;
+	}
+
+	ehdr = (struct elf32_hdr *)fw_mdt->data;
+	if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) {
+		dev_err(ssm->dev, "Not an elf header\n");
+		rc = -EIO;
+		goto release_mdt;
+	}
+
+	if (ehdr->e_phnum == 0) {
+		dev_err(ssm->dev, "No loadable segments\n");
+		rc = -EIO;
+		goto release_mdt;
+	}
+
+	phdr = (const struct elf32_phdr *)(fw_mdt->data +
+					sizeof(struct elf32_hdr));
+
+	fw = kzalloc((sizeof(struct firmware *) * ehdr->e_phnum), GFP_KERNEL);
+	if (!fw) {
+		rc = -ENOMEM;
+		goto release_mdt;
+	}
+
+	/* Valid .mdt now we need to load other parts .b0* */
+	for (fw_count = 0; fw_count < ehdr->e_phnum ; fw_count++) {
+		snprintf(name, MAX_APP_NAME_SIZE, FIRMWARE_NAME".b%02d",
+								fw_count);
+		rc = request_firmware(&fw[fw_count], name, ssm->dev);
+		if (rc < 0) {
+			rc = -EIO;
+			dev_err(ssm->dev, "Unable to get blob file\n");
+			goto release_blob;
+		}
+
+		if (fw[fw_count]->size != phdr->p_filesz) {
+			dev_err(ssm->dev, "Blob size %u doesn't match %u\n",
+					fw[fw_count]->size, phdr->p_filesz);
+			rc = -EIO;
+			goto release_blob;
+		}
+
+		phdr++;
+		size += fw[fw_count]->size;
+	}
+
+	/* Ion allocation for loading tzapp */
+	/* ION buffer size 4k aligned */
+	ion_len = ALIGN_BUFFER(size);
+	ion_handle = ion_alloc(ssm_drv->ssm_ion_client,
+			ion_len, SZ_4K, ION_HEAP(ION_QSECOM_HEAP_ID), 0);
+	if (IS_ERR_OR_NULL(ion_handle)) {
+		rc = PTR_ERR(ion_handle);
+		dev_err(ssm->dev, "Unable to get ion handle\n");
+		goto release_blob;
+	}
+
+	rc = ion_phys(ssm_drv->ssm_ion_client, ion_handle,
+			&buff_phys, &buff_len);
+	if (rc < 0) {
+		dev_err(ssm->dev, "Unable to get ion physical address\n");
+		goto ion_free;
+	}
+
+	if (buff_len < size) {
+		rc = -ENOMEM;
+		goto ion_free;
+	}
+
+	buff_virt =
+		(ion_virt_addr_t)ion_map_kernel(ssm_drv->ssm_ion_client,
+				ion_handle);
+	if (IS_ERR_OR_NULL((void *)buff_virt)) {
+		rc = PTR_ERR((void *)buff_virt);
+		dev_err(ssm->dev, "Unable to get ion virtual address\n");
+		goto ion_free;
+	}
+
+	/* Copy firmware to ION memory */
+	memcpy((unsigned char *)buff_virt, fw_mdt->data, fw_mdt->size);
+	pos = (unsigned char *)buff_virt + fw_mdt->size;
+	for (i = 0; i < ehdr->e_phnum; i++) {
+		memcpy(pos, fw[i]->data, fw[i]->size);
+		pos += fw[i]->size;
+	}
+
+	/* Loading app */
+	app_img_info.cmd_id = APP_START_COMMAND;
+	app_img_info.mdt_len = fw_mdt->size;
+	app_img_info.img_len = size;
+	app_img_info.phy_addr = buff_phys;
+
+	/* SCM call to load the TZ APP */
+	rc = scm_call(SCM_SVC_TZSCHEDULER, 1, &app_img_info,
+		sizeof(struct load_app), &app_resp, sizeof(app_resp));
+	if (rc) {
+		rc = -EIO;
+		dev_err(ssm->dev, "SCM call to load APP failed\n");
+		goto ion_unmap;
+	}
+
+	if (app_resp.result == RESULT_FAILURE) {
+		rc = -EIO;
+		dev_err(ssm->dev, "SCM command to load TzAPP failed\n");
+		goto ion_unmap;
+	}
+
+	ssm->app_id = app_resp.data;
+	ssm->app_status = SUCCESS;
+
+ion_unmap:
+	ion_unmap_kernel(ssm_drv->ssm_ion_client, ion_handle);
+ion_free:
+	ion_free(ssm_drv->ssm_ion_client, ion_handle);
+release_blob:
+	while (--fw_count >= 0)
+		release_firmware(fw[fw_count]);
+	kfree(fw);
+release_mdt:
+	release_firmware(fw_mdt);
+out:
+	return rc;
+}
+
+/*
+ * Allocate buffer for transactions.
+ */
+static int ssm_setup_ion(struct ssm_driver *ssm)
+{
+	int rc = 0;
+	unsigned int size;
+
+	size = ALIGN_BUFFER(ATOM_MSG_LEN);
+
+	/* ION client for communicating with TZ */
+	ssm->ssm_ion_client = msm_ion_client_create(UINT_MAX,
+							"ssm-kernel");
+	if (IS_ERR_OR_NULL(ssm->ssm_ion_client)) {
+		rc = PTR_ERR(ssm->ssm_ion_client);
+		dev_err(ssm->dev, "Ion client not created\n");
+		return rc;
+	}
+
+	/* Setup a small ION buffer for tz communication */
+	ssm->ssm_ion_handle = ion_alloc(ssm->ssm_ion_client,
+				size, SZ_4K, ION_HEAP(ION_QSECOM_HEAP_ID), 0);
+	if (IS_ERR_OR_NULL(ssm->ssm_ion_handle)) {
+		rc = PTR_ERR(ssm->ssm_ion_handle);
+		dev_err(ssm->dev, "Unable to get ion handle\n");
+		goto out;
+	}
+
+	rc = ion_phys(ssm->ssm_ion_client, ssm->ssm_ion_handle,
+			&ssm->buff_phys, &ssm->buff_len);
+	if (rc < 0) {
+		dev_err(ssm->dev,
+			"Unable to get ion buffer physical address\n");
+		goto ion_free;
+	}
+
+	if (ssm->buff_len < size) {
+		rc = -ENOMEM;
+		goto ion_free;
+	}
+
+	ssm->buff_virt =
+		(ion_virt_addr_t)ion_map_kernel(ssm->ssm_ion_client,
+				ssm->ssm_ion_handle);
+	if (IS_ERR_OR_NULL((void *)ssm->buff_virt)) {
+		rc = PTR_ERR((void *)ssm->buff_virt);
+		dev_err(ssm->dev,
+			"Unable to get ion buffer virtual address\n");
+		goto ion_free;
+	}
+
+	return rc;
+
+ion_free:
+	ion_free(ssm->ssm_ion_client, ssm->ssm_ion_handle);
+out:
+	ion_client_destroy(ssm_drv->ssm_ion_client);
+	return rc;
+}
+
+static struct ssm_platform_data *populate_ssm_pdata(struct device *dev)
+{
+	struct ssm_platform_data *pdata;
+	int rc;
+
+	pdata = devm_kzalloc(dev, sizeof(struct ssm_platform_data),
+								GFP_KERNEL);
+	if (!pdata)
+		return NULL;
+
+	pdata->need_key_exchg =
+		of_property_read_bool(dev->of_node, "qcom,need-keyexhg");
+
+	rc = of_property_read_string(dev->of_node, "qcom,channel-name",
+							&pdata->channel_name);
+	if (rc && rc != -EINVAL) {
+		dev_err(dev, "Error reading channel_name property %d\n", rc);
+		return NULL;
+	} else if (rc == -EINVAL)
+		pdata->channel_name = CHANNEL_NAME;
+
+	return pdata;
+}
+
+static int __devinit ssm_probe(struct platform_device *pdev)
+{
+	int rc;
+	uint32_t system_call_id;
+	char legacy = '\0';
+	struct ssm_platform_data *pdata;
+	struct ssm_driver *drv;
+
+	if (pdev->dev.of_node)
+		pdata = populate_ssm_pdata(&pdev->dev);
+	else
+		pdata = pdev->dev.platform_data;
+
+	if (!pdata) {
+		dev_err(&pdev->dev, "Empty platform data\n");
+		return -ENOMEM;
+	}
+
+	drv = devm_kzalloc(&pdev->dev, sizeof(struct ssm_driver),
+								GFP_KERNEL);
+	if (!drv) {
+		dev_err(&pdev->dev, "Unable to allocate memory\n");
+		return -ENOMEM;
+	}
+
+	/* Initialize the driver structure */
+	drv->atom_replay = -1;
+	drv->mtoa_replay = -1;
+	drv->app_id = -1;
+	drv->app_status = RETRY;
+	drv->ready = false;
+	drv->update_status = FAILED;
+	mutex_init(&drv->mutex);
+	drv->key_status = !pdata->need_key_exchg;
+	drv->channel_name = (char *)pdata->channel_name;
+	INIT_WORK(&drv->ipc_work, ssm_app_modem_work_fn);
+
+	/* Allocate memory for smd buffer */
+	drv->smd_buffer = devm_kzalloc(&pdev->dev,
+			(sizeof(char) * ATOM_MSG_LEN), GFP_KERNEL);
+	if (!drv->smd_buffer) {
+		rc = -ENOMEM;
+		goto exit;
+	}
+
+	/* Allocate response buffer */
+	drv->resp = devm_kzalloc(&pdev->dev,
+				sizeof(struct tzapp_get_mode_info_rsp),
+				GFP_KERNEL);
+	if (!drv->resp) {
+		rc = -ENOMEM;
+		goto exit;
+	}
+
+
+	/* Check for TZ version */
+	system_call_id = QSEOS_CHECK_VERSION_CMD;
+	rc = scm_call(SCM_SVC_INFO, SSM_INFO_CMD_ID, &system_call_id,
+			sizeof(system_call_id), &legacy, sizeof(legacy));
+	if (rc) {
+		dev_err(&pdev->dev, "Get version failed %d\n", rc);
+		rc = -EINVAL;
+		goto exit;
+	}
+
+	/* This driver only support 1.4 TZ and QSEOS */
+	if (!legacy) {
+		dev_err(&pdev->dev,
+				"Driver doesn't support legacy version\n");
+		rc = -EINVAL;
+		goto exit;
+
+	}
+
+	/* Setup the ion buffer for transaction */
+	rc = ssm_setup_ion(drv);
+	if (rc < 0)
+		goto exit;
+
+	drv->dev = &pdev->dev;
+	ssm_drv = drv;
+	platform_set_drvdata(pdev, ssm_drv);
+
+	dev_dbg(&pdev->dev, "probe success\n");
+	return 0;
+
+exit:
+	mutex_destroy(&drv->mutex);
+	platform_set_drvdata(pdev, NULL);
+	return rc;
+
+}
+
+static int __devexit ssm_remove(struct platform_device *pdev)
+{
+	int rc;
+
+	struct scm_shutdown_req req;
+	struct scm_resp resp;
+
+	if (!ssm_drv)
+		return 0;
+	/*
+	 * Step to exit
+	 * 1. set ready to 0 (oem access closed).
+	 * 2. Close SMD modem connection closed.
+	 * 3. cleanup ion.
+	 */
+	ssm_drv->ready = false;
+	smd_close(ssm_drv->ch);
+	flush_work_sync(&ssm_drv->ipc_work);
+
+	/* ION clean up*/
+	ion_unmap_kernel(ssm_drv->ssm_ion_client, ssm_drv->ssm_ion_handle);
+	ion_free(ssm_drv->ssm_ion_client, ssm_drv->ssm_ion_handle);
+	ion_client_destroy(ssm_drv->ssm_ion_client);
+
+	/* Shutdown tzapp */
+	req.app_id = ssm_drv->app_id;
+	req.cmd_id = APP_SHUTDOWN_COMMAND;
+	rc = scm_call(SCM_SVC_TZSCHEDULER, 1, &req, sizeof(req),
+			&resp, sizeof(resp));
+	if (rc)
+		dev_err(&pdev->dev, "TZ_app Unload failed\n");
+
+	return rc;
+}
+
+static struct of_device_id ssm_match_table[] = {
+	{
+		.compatible = "qcom,ssm",
+	},
+	{}
+};
+
+static struct platform_driver ssm_pdriver = {
+	.probe          = ssm_probe,
+	.remove         = __devexit_p(ssm_remove),
+	.driver = {
+		.name   = SSM_DEV_NAME,
+		.owner  = THIS_MODULE,
+		.of_match_table = ssm_match_table,
+	},
+};
+module_platform_driver(ssm_pdriver);
+
+/*
+ * Interface for external OEM driver.
+ * This interface supports following functionalities:
+ * 1. Get TZAPP ID.
+ * 2. Set default mode.
+ * 3. Set mode (encrypted mode and it's length is passed as parameter).
+ * 4. Set mode from TZ.
+ * 5. Get status of mode update.
+ *
+ */
+int ssm_oem_driver_intf(int cmd, char *mode, int len)
+{
+	int rc, req_len, resp_len;
+	struct tzapp_get_mode_info_req get_mode_req;
+	struct tzapp_get_mode_info_rsp *get_mode_resp;
+
+	/* If ssm_drv is NULL, probe failed */
+	if (!ssm_drv)
+		return -ENODEV;
+
+	mutex_lock(&ssm_drv->mutex);
+
+	if (ssm_drv->app_status == RETRY) {
+		/* Load TZAPP */
+		rc = ssm_load_app(ssm_drv);
+		if (rc) {
+			rc = -ENODEV;
+			ssm_drv->app_status = FAILED;
+			goto unlock;
+		}
+	} else if (ssm_drv->app_status == FAILED) {
+		rc = -ENODEV;
+		goto unlock;
+	}
+
+	/* Open modem SMD interface */
+	if (!ssm_drv->ready) {
+		rc = smd_open(ssm_drv->channel_name, &ssm_drv->ch, ssm_drv,
+							modem_request);
+		if (rc) {
+			rc = -EAGAIN;
+			goto unlock;
+		} else
+			ssm_drv->ready = true;
+	}
+
+	/* Try again modem key-exchange not yet done.*/
+	if (!ssm_drv->key_status) {
+		rc = -EAGAIN;
+		goto unlock;
+	}
+
+	/* Set return status to success */
+	rc = 0;
+
+	switch (cmd) {
+	case SSM_READY:
+		break;
+
+	case SSM_GET_APP_ID:
+		rc = ssm_drv->app_id;
+		break;
+
+	case SSM_MODE_INFO_READY:
+		ssm_drv->update_status = RETRY;
+		/* Fill command structure */
+		req_len = sizeof(struct tzapp_get_mode_info_req);
+		resp_len = sizeof(struct tzapp_get_mode_info_rsp);
+		get_mode_req.tzapp_ssm_cmd = GET_ENC_MODE;
+		rc = tz_scm_call(ssm_drv, (void *)&get_mode_req,
+				req_len, (void **)&get_mode_resp, resp_len);
+		if (rc) {
+			ssm_drv->update_status = FAILED;
+			break;
+		}
+
+		/* Send mode_info to modem */
+		rc = update_modem(SSM_ATOM_MODE_UPDATE, ssm_drv,
+				get_mode_resp->enc_mode_len,
+				get_mode_resp->enc_mode_info);
+		if (rc)
+			ssm_drv->update_status = FAILED;
+		break;
+
+	case SSM_SET_MODE:
+		ssm_drv->update_status = RETRY;
+
+		if (len > ENC_MODE_MAX_SIZE) {
+			ssm_drv->update_status = FAILED;
+			rc = -EINVAL;
+			break;
+		}
+		memcpy(ssm_drv->resp->enc_mode_info, mode, len);
+		ssm_drv->resp->enc_mode_len = len;
+
+		/* Send mode_info to modem */
+		rc = update_modem(SSM_ATOM_MODE_UPDATE, ssm_drv,
+				ssm_drv->resp->enc_mode_len,
+				ssm_drv->resp->enc_mode_info);
+		if (rc)
+			ssm_drv->update_status = FAILED;
+		break;
+
+	case SSM_GET_MODE_STATUS:
+		rc = ssm_drv->update_status;
+		break;
+
+	case SSM_SET_DEFAULT_MODE:
+		/* Modem does not send response for this */
+		ssm_drv->update_status = RETRY;
+		rc = update_modem(SSM_ATOM_SET_DEFAULT_MODE, ssm_drv,
+				1, "0");
+		if (rc)
+			ssm_drv->update_status = FAILED;
+		else
+			/* For default mode we don't get any resp
+			 * from modem.
+			 */
+			ssm_drv->update_status = SUCCESS;
+		break;
+	default:
+		rc = -EINVAL;
+		dev_err(ssm_drv->dev, "Invalid command\n");
+		break;
+	};
+
+unlock:
+	mutex_unlock(&ssm_drv->mutex);
+	return rc;
+}
+EXPORT_SYMBOL_GPL(ssm_oem_driver_intf);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Qualcomm Secure Service Module");
+
diff --git a/drivers/platform/msm/ssm.h b/drivers/platform/msm/ssm.h
new file mode 100644
index 0000000..97add11
--- /dev/null
+++ b/drivers/platform/msm/ssm.h
@@ -0,0 +1,160 @@
+/* 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 __SSM_H_
+#define __SSM_H_
+
+#define MAX_APP_NAME_SIZE	32
+#define MODE_INFO_MAX_SIZE	4
+#define ENC_MODE_MAX_SIZE	(100 + MODE_INFO_MAX_SIZE)
+
+/* tzapp response.*/
+enum tz_response {
+	RESULT_SUCCESS = 0,
+	RESULT_FAILURE  = 0xFFFFFFFF,
+};
+
+/* tzapp command list.*/
+enum tz_commands {
+	ENC_MODE,
+	GET_ENC_MODE,
+	KEY_EXCHANGE = 11,
+};
+
+/* Command list for QSEOS.*/
+enum qceos_cmd_id {
+	APP_START_COMMAND = 0x01,
+	APP_SHUTDOWN_COMMAND,
+	APP_LOOKUP_COMMAND,
+	CLIENT_SEND_DATA_COMMAND = 0x6,
+	QSEOS_CMD_MAX = 0xEFFFFFFF,
+};
+
+/* MODEM/SSM command list.*/
+enum ssm_ipc_req {
+	SSM_MTOA_KEY_EXCHANGE = 0x0000AAAA,
+	SSM_ATOM_KEY_STATUS,
+	SSM_ATOM_MODE_UPDATE,
+	SSM_MTOA_MODE_UPDATE_STATUS,
+	SSM_MTOA_PREV_INVALID,
+	SSM_ATOM_PREV_INVALID,
+	SSM_ATOM_SET_DEFAULT_MODE,
+	SSM_INVALID_REQ,
+};
+
+/* OEM reuest commands list.*/
+enum oem_req {
+	SSM_READY,
+	SSM_GET_APP_ID,
+	SSM_MODE_INFO_READY,
+	SSM_SET_MODE,
+	SSM_GET_MODE_STATUS,
+	SSM_SET_DEFAULT_MODE,
+	SSM_INVALID,
+};
+
+/* Modem mode update status.*/
+enum modem_mode_status {
+	SUCCESS,
+	RETRY,
+	FAILED = -1,
+};
+
+__packed struct load_app {
+	uint32_t cmd_id;
+	uint32_t mdt_len;
+	uint32_t img_len;
+	uint32_t phy_addr;
+	char     app_name[MAX_APP_NAME_SIZE];
+};
+
+/* Stop tzapp reuest.*/
+__packed struct scm_shutdown_req {
+	uint32_t cmd_id;
+	uint32_t app_id;
+};
+
+/* Common tzos response.*/
+__packed struct scm_resp {
+	uint32_t result;
+	enum tz_response resp_type;
+	unsigned int data;
+};
+
+/* tzos request.*/
+__packed struct check_app_req {
+	uint32_t cmd_id;
+	char     app_name[MAX_APP_NAME_SIZE];
+};
+
+/* tzapp encode mode reuest.*/
+__packed struct tzapp_mode_enc_req {
+	uint32_t tzapp_ssm_cmd;
+	uint8_t  mode_info[4];
+};
+
+/* tzapp encode mode response.*/
+__packed struct tzapp_mode_enc_rsp {
+	uint32_t tzapp_ssm_cmd;
+	uint8_t enc_mode_info[ENC_MODE_MAX_SIZE];
+	uint32_t enc_mode_len;
+	long status;
+};
+
+/* tzapp get mode request.*/
+__packed struct tzapp_get_mode_info_req {
+	uint32_t tzapp_ssm_cmd;
+};
+
+/* tzapp get mode response.*/
+__packed struct tzapp_get_mode_info_rsp {
+	uint32_t tzapp_ssm_cmd;
+	uint8_t  enc_mode_info[ENC_MODE_MAX_SIZE];
+	uint32_t enc_mode_len;
+	long status;
+};
+
+/* tzos key exchange request.*/
+__packed struct ssm_keyexchg_req {
+	uint32_t ssid;
+	void *address;
+	uint32_t length;
+	uint32_t *status;
+};
+
+/* tzos common request.*/
+__packed struct common_req {
+	uint32_t cmd_id;
+	uint32_t app_id;
+	void *req_ptr;
+	uint32_t req_len;
+	void *resp_ptr;
+	uint32_t resp_len;
+};
+
+/* tzos common response.*/
+__packed struct common_resp {
+	uint32_t result;
+	uint32_t type;
+	uint32_t data;
+};
+
+/* Modem/SSM packet format.*/
+struct ssm_common_msg {
+	unsigned long pktlen;
+	unsigned long replaynum;
+	enum ssm_ipc_req ipc_req;
+	unsigned long msg_len;
+	char *msg;
+};
+
+#endif
diff --git a/drivers/platform/msm/usb_bam.c b/drivers/platform/msm/usb_bam.c
index 6b067e7..c841575 100644
--- a/drivers/platform/msm/usb_bam.c
+++ b/drivers/platform/msm/usb_bam.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -26,6 +26,7 @@
 #include <mach/ipa.h>
 #include <linux/workqueue.h>
 #include <linux/dma-mapping.h>
+#include <mach/msm_smsm.h>
 
 #define USB_SUMMING_THRESHOLD 512
 #define CONNECTIONS_NUM	8
@@ -37,29 +38,47 @@
 static struct sps_mem_buffer desc_mem_buf[CONNECTIONS_NUM][2];
 static struct platform_device *usb_bam_pdev;
 static struct workqueue_struct *usb_bam_wq;
+static u32 h_bam;
+static spinlock_t usb_bam_lock;
 
-struct usb_bam_wake_event_info {
+struct usb_bam_event_info {
 	struct sps_register_event event;
 	int (*callback)(void *);
 	void *param;
-	struct work_struct wake_w;
+	struct work_struct event_w;
 };
 
 struct usb_bam_connect_info {
 	u8 idx;
 	u32 *src_pipe;
 	u32 *dst_pipe;
-	struct usb_bam_wake_event_info peer_event;
+	struct usb_bam_event_info wake_event;
 	bool src_enabled;
 	bool dst_enabled;
 };
 
+enum usb_bam_sm {
+	USB_BAM_SM_INIT = 0,
+	USB_BAM_SM_PLUG_NOTIFIED,
+	USB_BAM_SM_PLUG_ACKED,
+	USB_BAM_SM_UNPLUG_NOTIFIED,
+};
+
+struct usb_bam_peer_handhskae_info {
+	enum usb_bam_sm state;
+	bool client_ready;
+	bool ack_received;
+	int pending_work;
+	struct usb_bam_event_info reset_event;
+};
+
 static struct usb_bam_connect_info usb_bam_connections[CONNECTIONS_NUM];
 static struct usb_bam_pipe_connect ***msm_usb_bam_connections_info;
 static struct usb_bam_pipe_connect *bam_connection_arr;
 void __iomem *qscratch_ram1_reg;
 struct clk *mem_clk;
 struct clk *mem_iface_clk;
+struct usb_bam_peer_handhskae_info peer_handhskae_info;
 
 static int connect_pipe(u8 conn_idx, enum usb_bam_pipe_dir pipe_dir,
 						u32 *usb_pipe_idx)
@@ -254,8 +273,8 @@
 	ret = sps_phy2h(usb_phy_addr, &usb_handle);
 	if (ret) {
 		pr_err("%s: sps_phy2h failed (HSUSB/HSIC BAM) %d\n",
-			   __func__, ret);
-		goto get_config_failed;
+			__func__, ret);
+		return ret;
 	}
 
 	/* IPA input parameters */
@@ -265,8 +284,39 @@
 	ipa_in_params.notify = connection_params->notify;
 	ipa_in_params.priv = connection_params->priv;
 	ipa_in_params.client = connection_params->client;
-	if (pipe_connection->mem_type != SYSTEM_MEM)
-		ipa_in_params.pipe_mem_preferred = true;
+
+	/* If BAM is using dedicated SPS pipe memory, get it */
+
+	if (pipe_connection->mem_type == SPS_PIPE_MEM) {
+		pr_debug("%s: USB BAM using SPS pipe memory\n", __func__);
+		ret = sps_setup_bam2bam_fifo(
+			&data_mem_buf[conn_idx][pipe_dir],
+			pipe_connection->data_fifo_base_offset,
+			pipe_connection->data_fifo_size, 1);
+		if (ret) {
+			pr_err("%s: data fifo setup failure %d\n", __func__,
+				ret);
+			return ret;
+		}
+
+		ret = sps_setup_bam2bam_fifo(
+			&desc_mem_buf[conn_idx][pipe_dir],
+			pipe_connection->desc_fifo_base_offset,
+			pipe_connection->desc_fifo_size, 1);
+		if (ret) {
+			pr_err("%s: desc. fifo setup failure %d\n", __func__,
+				ret);
+			return ret;
+		}
+
+	} else {
+		pr_err("%s: unsupported memory type(%d)\n",
+			__func__, pipe_connection->mem_type);
+		return -EINVAL;
+	}
+
+	ipa_in_params.desc = desc_mem_buf[conn_idx][pipe_dir];
+	ipa_in_params.data = data_mem_buf[conn_idx][pipe_dir];
 
 	memcpy(&ipa_in_params.ipa_ep_cfg, &connection_params->ipa_ep_cfg,
 		   sizeof(struct ipa_ep_cfg));
@@ -287,7 +337,7 @@
 	ret = sps_get_config(*pipe, connection);
 	if (ret) {
 		pr_err("%s: tx get config failed %d\n", __func__, ret);
-		goto get_config_failed;
+		goto free_sps_endpoints;
 	}
 
 	if (pipe_dir == USB_TO_PEER_PERIPHERAL) {
@@ -325,7 +375,7 @@
 
 error:
 	sps_disconnect(*pipe);
-get_config_failed:
+free_sps_endpoints:
 	sps_free_endpoint(*pipe);
 disconnect_ipa:
 	ipa_disconnect(clnt_hdl);
@@ -368,6 +418,9 @@
 int usb_bam_connect(u8 idx, u32 *src_pipe_idx, u32 *dst_pipe_idx)
 {
 	struct usb_bam_connect_info *connection = &usb_bam_connections[idx];
+	struct msm_usb_bam_platform_data *pdata =
+				usb_bam_pdev->dev.platform_data;
+	int usb_active_bam = pdata->usb_active_bam;
 	int ret;
 
 	if (!usb_bam_pdev) {
@@ -390,6 +443,10 @@
 	connection->dst_pipe = dst_pipe_idx;
 	connection->idx = idx;
 
+	/* Check if BAM requires RESET before connect */
+	if (pdata->reset_on_connect[usb_active_bam] == true)
+		sps_device_reset(h_bam);
+
 	if (src_pipe_idx) {
 		/* open USB -> Peripheral pipe */
 		ret = connect_pipe(connection->idx, USB_TO_PEER_PERIPHERAL,
@@ -457,20 +514,122 @@
 	return 0;
 }
 
-static void usb_bam_wake_work(struct work_struct *w)
+int usb_bam_client_ready(bool ready)
 {
-	struct usb_bam_wake_event_info *wake_event_info =
-		container_of(w, struct usb_bam_wake_event_info, wake_w);
+	spin_lock(&usb_bam_lock);
+	if (peer_handhskae_info.client_ready == ready) {
+		pr_debug("%s: client state is already %d\n",
+			__func__, ready);
+		spin_unlock(&usb_bam_lock);
+		return 0;
+	}
 
-	wake_event_info->callback(wake_event_info->param);
+	peer_handhskae_info.client_ready = ready;
+
+	spin_unlock(&usb_bam_lock);
+	if (!queue_work(usb_bam_wq, &peer_handhskae_info.reset_event.event_w)) {
+		spin_lock(&usb_bam_lock);
+		peer_handhskae_info.pending_work++;
+		spin_unlock(&usb_bam_lock);
+	}
+
+	return 0;
+}
+
+static void usb_bam_work(struct work_struct *w)
+{
+	struct usb_bam_event_info *event_info =
+		container_of(w, struct usb_bam_event_info, event_w);
+
+	event_info->callback(event_info->param);
 }
 
 static void usb_bam_wake_cb(struct sps_event_notify *notify)
 {
-	struct usb_bam_wake_event_info *wake_event_info =
-		(struct usb_bam_wake_event_info *)notify->user;
+	struct usb_bam_event_info *wake_event_info =
+		(struct usb_bam_event_info *)notify->user;
 
-	queue_work(usb_bam_wq, &wake_event_info->wake_w);
+	queue_work(usb_bam_wq, &wake_event_info->event_w);
+}
+
+static void usb_bam_sm_work(struct work_struct *w)
+{
+	pr_debug("%s: current state: %d\n", __func__,
+		peer_handhskae_info.state);
+
+	spin_lock(&usb_bam_lock);
+
+	switch (peer_handhskae_info.state) {
+	case USB_BAM_SM_INIT:
+		if (peer_handhskae_info.client_ready) {
+			spin_unlock(&usb_bam_lock);
+			smsm_change_state(SMSM_APPS_STATE, 0,
+				SMSM_USB_PLUG_UNPLUG);
+			spin_lock(&usb_bam_lock);
+			peer_handhskae_info.state = USB_BAM_SM_PLUG_NOTIFIED;
+		}
+		break;
+	case USB_BAM_SM_PLUG_NOTIFIED:
+		if (peer_handhskae_info.ack_received) {
+			peer_handhskae_info.state = USB_BAM_SM_PLUG_ACKED;
+			peer_handhskae_info.ack_received = 0;
+		}
+		break;
+	case USB_BAM_SM_PLUG_ACKED:
+		if (!peer_handhskae_info.client_ready) {
+			spin_unlock(&usb_bam_lock);
+			smsm_change_state(SMSM_APPS_STATE,
+				SMSM_USB_PLUG_UNPLUG, 0);
+			spin_lock(&usb_bam_lock);
+			peer_handhskae_info.state = USB_BAM_SM_UNPLUG_NOTIFIED;
+		}
+		break;
+	case USB_BAM_SM_UNPLUG_NOTIFIED:
+		if (peer_handhskae_info.ack_received) {
+			spin_unlock(&usb_bam_lock);
+			peer_handhskae_info.reset_event.
+				callback(peer_handhskae_info.reset_event.param);
+			spin_lock(&usb_bam_lock);
+			peer_handhskae_info.state = USB_BAM_SM_INIT;
+			peer_handhskae_info.ack_received = 0;
+		}
+		break;
+	}
+
+	if (peer_handhskae_info.pending_work) {
+		peer_handhskae_info.pending_work--;
+		spin_unlock(&usb_bam_lock);
+		queue_work(usb_bam_wq,
+			&peer_handhskae_info.reset_event.event_w);
+		spin_lock(&usb_bam_lock);
+	}
+	spin_unlock(&usb_bam_lock);
+}
+
+static void usb_bam_ack_toggle_cb(void *priv, uint32_t old_state,
+	uint32_t new_state)
+{
+	static int last_processed_state;
+	int current_state;
+
+	spin_lock(&usb_bam_lock);
+
+	current_state = new_state & SMSM_USB_PLUG_UNPLUG;
+
+	if (current_state == last_processed_state) {
+		spin_unlock(&usb_bam_lock);
+		return;
+	}
+
+	last_processed_state = current_state;
+	peer_handhskae_info.ack_received = true;
+
+	spin_unlock(&usb_bam_lock);
+	if (!queue_work(usb_bam_wq, &peer_handhskae_info.reset_event.event_w)) {
+		spin_lock(&usb_bam_lock);
+		peer_handhskae_info.pending_work++;
+		spin_unlock(&usb_bam_lock);
+	}
 }
 
 int usb_bam_register_wake_cb(u8 idx,
@@ -480,8 +639,8 @@
 	struct sps_connect *sps_connection =
 		&sps_connections[idx][PEER_PERIPHERAL_TO_USB];
 	struct usb_bam_connect_info *connection = &usb_bam_connections[idx];
-	struct usb_bam_wake_event_info *wake_event_info =
-		&connection->peer_event;
+	struct usb_bam_event_info *wake_event_info =
+		&connection->wake_event;
 	int ret;
 
 	wake_event_info->param = param;
@@ -509,6 +668,36 @@
 	return 0;
 }
 
+int usb_bam_register_peer_reset_cb(u8 idx,
+	 int (*callback)(void *), void *param)
+{
+	u32 ret = 0;
+
+	if (callback) {
+		peer_handhskae_info.reset_event.param = param;
+		peer_handhskae_info.reset_event.callback = callback;
+
+		ret = smsm_state_cb_register(SMSM_MODEM_STATE,
+			SMSM_USB_PLUG_UNPLUG, usb_bam_ack_toggle_cb, NULL);
+		if (ret) {
+			pr_err("%s: failed to register SMSM callback\n",
+				__func__);
+		} else {
+			if (smsm_get_state(SMSM_MODEM_STATE) &
+				SMSM_USB_PLUG_UNPLUG)
+				usb_bam_ack_toggle_cb(NULL, 0,
+					SMSM_USB_PLUG_UNPLUG);
+		}
+	} else {
+		peer_handhskae_info.reset_event.param = NULL;
+		peer_handhskae_info.reset_event.callback = NULL;
+		smsm_state_cb_deregister(SMSM_MODEM_STATE,
+			SMSM_USB_PLUG_UNPLUG, usb_bam_ack_toggle_cb, NULL);
+	}
+
+	return ret;
+}
+
 int usb_bam_disconnect_pipe(u8 idx)
 {
 	struct usb_bam_connect_info *connection = &usb_bam_connections[idx];
@@ -550,6 +739,7 @@
 
 	return 0;
 }
+
 int usb_bam_disconnect_ipa(u8 idx,
 		struct usb_bam_connect_ipa_params *ipa_params)
 {
@@ -592,6 +782,55 @@
 	return 0;
 
 }
+
+int usb_bam_reset(void)
+{
+	struct usb_bam_connect_info *connection;
+	int i;
+	int ret = 0, ret_int;
+	bool reconnect[CONNECTIONS_NUM];
+	u32 *reconnect_src_pipe[CONNECTIONS_NUM];
+	u32 *reconnect_dst_pipe[CONNECTIONS_NUM];
+
+	/* Disconnect all pipes */
+	for (i = 0; i < CONNECTIONS_NUM; i++) {
+		connection = &usb_bam_connections[i];
+		reconnect[i] = connection->src_enabled ||
+			connection->dst_enabled;
+		reconnect_src_pipe[i] = connection->src_pipe;
+		reconnect_dst_pipe[i] = connection->dst_pipe;
+
+		ret_int = usb_bam_disconnect_pipe(i);
+		if (ret_int) {
+			pr_err("%s: failure to connect pipe %d\n",
+				__func__, i);
+			ret = ret_int;
+			continue;
+		}
+	}
+
+	/* Reset USB/HSIC BAM */
+	if (sps_device_reset(h_bam))
+		pr_err("%s: BAM reset failed\n", __func__);
+
+	/* Reconnect all pipes */
+	for (i = 0; i < CONNECTIONS_NUM; i++) {
+		connection = &usb_bam_connections[i];
+		if (reconnect[i]) {
+			ret_int = usb_bam_connect(i, reconnect_src_pipe[i],
+				reconnect_dst_pipe[i]);
+			if (ret_int) {
+				pr_err("%s: failure to reconnect pipe %d\n",
+					__func__, i);
+				ret = ret_int;
+				continue;
+			}
+		}
+	}
+
+	return ret;
+}
+
 static int update_connections_info(struct device_node *node, int bam,
 	int conn_num, int dir, enum usb_pipe_mem_type mem_type)
 {
@@ -686,6 +925,14 @@
 	return 0;
 }
 
+static u8 qdss_conn_num;
+
+u8 usb_bam_get_qdss_num(void)
+{
+	return qdss_conn_num;
+}
+EXPORT_SYMBOL(usb_bam_get_qdss_num);
+
 static struct msm_usb_bam_platform_data *usb_bam_dt_to_pdata(
 	struct platform_device *pdev)
 {
@@ -698,6 +945,7 @@
 	u32 pipe_entry = 0;
 	char *key = NULL;
 	enum usb_pipe_mem_type mem_type;
+	bool reset_bam;
 
 	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
 	if (!pdata) {
@@ -734,6 +982,9 @@
 	pdata->ignore_core_reset_ack = of_property_read_bool(node,
 					"qcom,ignore-core-reset-ack");
 
+	pdata->disable_clk_gating = of_property_read_bool(node,
+					"qcom,disable-clk-gating");
+
 	for_each_child_of_node(pdev->dev.of_node, node)
 		pipe_entry++;
 
@@ -784,6 +1035,10 @@
 			pr_err("Cannot read string\n");
 			goto err;
 		}
+		reset_bam = of_property_read_bool(node,
+					"qcom,reset-bam-on-connect");
+		if (reset_bam)
+			pdata->reset_on_connect[bam] = true;
 
 		if (strnstr(str, "usb-to", 30))
 			dir = USB_TO_PEER_PERIPHERAL;
@@ -800,6 +1055,11 @@
 			!strcmp(str, "usb-to-peri-qdss-hsusb") ||
 			!strcmp(str, "peri-to-usb-qdss-hsusb"))
 				conn_num = 0;
+		else if (!strcmp(str, "usb-to-qdss-hsusb") ||
+			!strcmp(str, "qdss-to-usb-hsusb")) {
+				conn_num = 1;
+				qdss_conn_num = 1;
+		}
 		else
 			goto err;
 
@@ -825,7 +1085,6 @@
 
 static int usb_bam_init(void)
 {
-	u32 h_usb;
 	int ret;
 	void *usb_virt_addr;
 	struct msm_usb_bam_platform_data *pdata =
@@ -835,6 +1094,8 @@
 	struct resource *res, *ram_resource;
 	int irq;
 
+	qdss_conn_num = 0;
+
 	res = platform_get_resource_byname(usb_bam_pdev, IORESOURCE_MEM,
 				bam_enable_strings[pdata->usb_active_bam]);
 	if (!res) {
@@ -891,8 +1152,10 @@
 	 */
 	if (pdata->ignore_core_reset_ack && pdata->usb_active_bam != SSUSB_BAM)
 		usb_props.options = SPS_BAM_NO_EXT_P_RST;
+	if (pdata->disable_clk_gating)
+		usb_props.options |= SPS_BAM_NO_LOCAL_CLK_GATING;
 
-	ret = sps_register_bam_device(&usb_props, &h_usb);
+	ret = sps_register_bam_device(&usb_props, &h_bam);
 	if (ret < 0) {
 		pr_err("%s: register bam error %d\n", __func__, ret);
 		ret = -EFAULT;
@@ -967,10 +1230,13 @@
 	for (i = 0; i < CONNECTIONS_NUM; i++) {
 		usb_bam_connections[i].src_enabled = 0;
 		usb_bam_connections[i].dst_enabled = 0;
-		INIT_WORK(&usb_bam_connections[i].peer_event.wake_w,
-			usb_bam_wake_work);
+		INIT_WORK(&usb_bam_connections[i].wake_event.event_w,
+			usb_bam_work);
 	}
 
+	spin_lock_init(&usb_bam_lock);
+	INIT_WORK(&peer_handhskae_info.reset_event.event_w, usb_bam_sm_work);
+
 	mem_clk = devm_clk_get(&pdev->dev, "mem_clk");
 	if (IS_ERR(mem_clk))
 		dev_dbg(&pdev->dev, "failed to get mem_clock\n");
diff --git a/drivers/power/battery_current_limit.c b/drivers/power/battery_current_limit.c
index d1750ec..ecda153 100644
--- a/drivers/power/battery_current_limit.c
+++ b/drivers/power/battery_current_limit.c
@@ -507,12 +507,18 @@
 	return 0;
 }
 
+static struct of_device_id bcl_match_table[] = {
+	{.compatible = "qcom,bcl"},
+	{},
+};
+
 static struct platform_driver bcl_driver = {
 	.probe	= bcl_probe,
 	.remove	= __devexit_p(bcl_remove),
 	.driver	= {
 		.name	= BCL_DEV_NAME,
 		.owner	= THIS_MODULE,
+		.of_match_table = bcl_match_table,
 	},
 };
 
diff --git a/drivers/power/bq27520_fuelgauger.c b/drivers/power/bq27520_fuelgauger.c
index 3c191cd..c5e87c5 100644
--- a/drivers/power/bq27520_fuelgauger.c
+++ b/drivers/power/bq27520_fuelgauger.c
@@ -2,7 +2,7 @@
  * Copyright (C) 2008 Eurotech S.p.A. <info@eurotech.it>
  * Based on a previous work by Copyright (C) 2008 Texas Instruments, Inc.
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/drivers/power/bq27541_fuelgauger.c b/drivers/power/bq27541_fuelgauger.c
index 516a861..2101c5f 100644
--- a/drivers/power/bq27541_fuelgauger.c
+++ b/drivers/power/bq27541_fuelgauger.c
@@ -2,7 +2,7 @@
  * Copyright (C) 2008 Eurotech S.p.A. <info@eurotech.it>
  * Based on a previous work by Copyright (C) 2008 Texas Instruments, Inc.
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/drivers/power/bq28400_battery.c b/drivers/power/bq28400_battery.c
index 1852687..beab4e2 100644
--- a/drivers/power/bq28400_battery.c
+++ b/drivers/power/bq28400_battery.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
@@ -136,6 +136,8 @@
 	struct power_supply	batt_psy;
 	struct power_supply	*dc_psy;
 	bool			is_charging_enabled;
+	u32			temp_cold;	/* in degree celsius */
+	u32			temp_hot;	/* in degree celsius */
 };
 
 static struct bq28400_device *bq28400_dev;
@@ -486,10 +488,14 @@
 	int rsoc;
 	s16 current_ma = 0;
 	u16 battery_status;
+	int temperature;
+	struct bq28400_device *dev = i2c_get_clientdata(client);
 
 	battery_status = bq28400_read_reg(client, SBS_BATTERY_STATUS);
 	rsoc = bq28400_read_rsoc(client);
 	current_ma = bq28400_read_current(client);
+	temperature = bq28400_read_temperature(client);
+	temperature = temperature / 10; /* in degree celsius */
 
 	if (battery_status & BAT_STATUS_EMPTY)
 		pr_debug("Battery report Empty.\n");
@@ -513,8 +519,11 @@
 		return POWER_SUPPLY_STATUS_FULL;
 	}
 
-	/* Enable charging when battery is not full */
-	bq28400_enable_charging(bq28400_dev, true);
+	/* Enable charging when battery is not full and temperature is ok */
+	if ((temperature > dev->temp_cold) && (temperature < dev->temp_hot))
+		bq28400_enable_charging(bq28400_dev, true);
+	else
+		bq28400_enable_charging(bq28400_dev, false);
 
 	/*
 	* Positive current indicates charging
@@ -825,6 +834,12 @@
 				   const struct i2c_device_id *id)
 {
 	int ret = 0;
+	struct device_node *dev_node = client->dev.of_node;
+
+	if (dev_node == NULL) {
+		pr_err("Device Tree node doesn't exist.\n");
+		return -ENODEV;
+	}
 
 	if (!i2c_check_functionality(client->adapter,
 				I2C_FUNC_SMBUS_BYTE_DATA)) {
@@ -843,6 +858,23 @@
 		return -ENOMEM;
 	}
 
+	/* Note: Lithium-ion battery normal temperature range 0..40 C */
+	ret = of_property_read_u32(dev_node, "ti,temp-cold",
+				   &(bq28400_dev->temp_cold));
+	if (ret) {
+		pr_err("Unable to read cold temperature. ret=%d.\n", ret);
+		goto err_dev_node;
+	}
+	pr_debug("cold temperature limit = %d C.\n", bq28400_dev->temp_cold);
+
+	ret = of_property_read_u32(dev_node, "ti,temp-hot",
+				   &(bq28400_dev->temp_hot));
+	if (ret) {
+		pr_err("Unable to read hot temperature. ret=%d.\n", ret);
+		goto err_dev_node;
+	}
+	pr_debug("hot temperature limit = %d C.\n", bq28400_dev->temp_hot);
+
 	bq28400_dev->client = client;
 	i2c_set_clientdata(client, bq28400_dev);
 
@@ -864,7 +896,7 @@
 	schedule_delayed_work(&bq28400_dev->periodic_user_space_update_work,
 			      msecs_to_jiffies(1000));
 
-	pr_info("Device is ready.\n");
+	pr_debug("Device is ready.\n");
 
 	return 0;
 
@@ -873,6 +905,7 @@
 		debugfs_remove_recursive(bq28400_dev->dent);
 	power_supply_unregister(&bq28400_dev->batt_psy);
 err_register_psy:
+err_dev_node:
 	kfree(bq28400_dev);
 	bq28400_dev = NULL;
 
diff --git a/drivers/power/isl9519q.c b/drivers/power/isl9519q.c
index 7ebbf46..da5a0bd 100644
--- a/drivers/power/isl9519q.c
+++ b/drivers/power/isl9519q.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/power/ltc4088-charger.c b/drivers/power/ltc4088-charger.c
index 58503cf..719cfec 100644
--- a/drivers/power/ltc4088-charger.c
+++ b/drivers/power/ltc4088-charger.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/drivers/power/msm_battery.c b/drivers/power/msm_battery.c
index f8186b1..a220962 100644
--- a/drivers/power/msm_battery.c
+++ b/drivers/power/msm_battery.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
@@ -503,13 +503,13 @@
 	}
 
 	if (msm_batt_info.charger_type != charger_type) {
-		if (charger_type == CHARGER_TYPE_USB_WALL ||
-		    charger_type == CHARGER_TYPE_USB_PC ||
+		if (charger_type == CHARGER_TYPE_USB_PC ||
 		    charger_type == CHARGER_TYPE_USB_CARKIT) {
 			DBG_LIMIT("BATT: USB charger plugged in\n");
 			msm_batt_info.current_chg_source = USB_CHG;
 			supp = &msm_psy_usb;
-		} else if (charger_type == CHARGER_TYPE_WALL) {
+		} else if (charger_type == CHARGER_TYPE_WALL ||
+			charger_type == CHARGER_TYPE_USB_WALL) {
 			DBG_LIMIT("BATT: AC Wall changer plugged in\n");
 			msm_batt_info.current_chg_source = AC_CHG;
 			supp = &msm_psy_ac;
diff --git a/drivers/power/msm_charger.c b/drivers/power/msm_charger.c
index 8594ec2..29dc726 100644
--- a/drivers/power/msm_charger.c
+++ b/drivers/power/msm_charger.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/power/pm8058_usb_fix.c b/drivers/power/pm8058_usb_fix.c
index 80b1f87..1287547 100644
--- a/drivers/power/pm8058_usb_fix.c
+++ b/drivers/power/pm8058_usb_fix.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index a8d52b5..c5b1db4 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -23,6 +23,7 @@
 #include <linux/mfd/pm8xxx/pm8921-charger.h>
 #include <linux/mfd/pm8xxx/ccadc.h>
 #include <linux/mfd/pm8xxx/batterydata-lib.h>
+#include <linux/mfd/pm8xxx/batt-alarm.h>
 #include <linux/interrupt.h>
 #include <linux/bitops.h>
 #include <linux/debugfs.h>
@@ -100,7 +101,8 @@
 	struct sf_lut		*rbatt_sf_lut;
 	int			delta_rbatt_mohm;
 	struct work_struct	calib_hkadc_work;
-	struct delayed_work	calib_hkadc_delayed_work;
+	unsigned long		last_calib_time;
+	int			last_calib_temp;
 	struct mutex		calib_mutex;
 	unsigned int		revision;
 	unsigned int		xoadc_v0625_usb_present;
@@ -119,11 +121,13 @@
 	unsigned int		charging_began;
 	unsigned int		start_percent;
 	unsigned int		end_percent;
+	unsigned int		alarm_low_mv;
+	unsigned int		alarm_high_mv;
+
 	int			charge_time_us;
 	int			catch_up_time_us;
 	enum battery_type	batt_type;
 	uint16_t		ocv_reading_at_100;
-	int			cc_reading_at_100;
 	int			max_voltage_uv;
 
 	int			chg_term_ua;
@@ -131,8 +135,10 @@
 	int			amux_2_trim_delta;
 	uint16_t		prev_last_good_ocv_raw;
 	int			rconn_mohm;
+	int			rbatt_capacitive_mohm;
 	struct mutex		last_ocv_uv_mutex;
 	int			last_ocv_uv;
+	int			last_ocv_temp_decidegc;
 	int			pon_ocv_uv;
 	int			last_cc_uah;
 	unsigned long		tm_sec;
@@ -141,6 +147,7 @@
 	int			shutdown_iavg_ua;
 	struct delayed_work	calculate_soc_delayed_work;
 	struct timespec		t_soc_queried;
+	unsigned long		last_recalc_time;
 	int			shutdown_soc_valid_limit;
 	int			ignore_shutdown_soc;
 	int			prev_iavg_ua;
@@ -157,6 +164,11 @@
 	int			soc_calc_period;
 	int			normal_voltage_calc_ms;
 	int			low_voltage_calc_ms;
+	int			imax_ua;
+	struct wake_lock	soc_wake_lock;
+	int			disable_flat_portion_ocv;
+	int			ocv_dis_high_soc;
+	int			ocv_dis_low_soc;
 };
 
 /*
@@ -184,6 +196,13 @@
 static int last_real_fcc_mah = -EINVAL;
 static int last_real_fcc_batt_temp = -EINVAL;
 
+static int pm8921_battery_gauge_alarm_notify(struct notifier_block *nb,
+				unsigned long status, void *unused);
+
+static struct notifier_block alarm_notifier = {
+	.notifier_call = pm8921_battery_gauge_alarm_notify,
+};
+
 static int bms_ops_set(const char *val, const struct kernel_param *kp)
 {
 	if (*(int *)kp->arg == -EINVAL)
@@ -371,6 +390,124 @@
 	return val;
 }
 
+static int pm8921_bms_enable_batt_alarm(struct pm8921_bms_chip *chip)
+{
+	int rc = 0;
+
+	rc = pm8xxx_batt_alarm_enable(PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
+	if (!rc)
+		rc = pm8xxx_batt_alarm_disable(
+				PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
+	if (rc) {
+		pr_err("unable to set batt alarm state rc=%d\n", rc);
+		return rc;
+	}
+
+	return rc;
+}
+
+static int pm8921_bms_configure_batt_alarm(struct pm8921_bms_chip *chip)
+{
+	int rc = 0;
+
+	rc = pm8xxx_batt_alarm_disable(PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
+	if (!rc)
+		rc = pm8xxx_batt_alarm_disable(
+			PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
+	if (rc) {
+		pr_err("unable to set batt alarm state rc=%d\n", rc);
+		return rc;
+	}
+
+	/*
+	* The batt-alarm driver requires sane values for both min / max,
+	* regardless of whether they're both activated.
+	*/
+	rc = pm8xxx_batt_alarm_threshold_set(
+			PM8XXX_BATT_ALARM_LOWER_COMPARATOR,
+					chip->alarm_low_mv);
+	if (!rc)
+		rc = pm8xxx_batt_alarm_threshold_set(
+			PM8XXX_BATT_ALARM_UPPER_COMPARATOR,
+					chip->alarm_high_mv);
+	if (rc) {
+		pr_err("unable to set batt alarm threshold rc=%d\n", rc);
+		return rc;
+	}
+
+	rc = pm8xxx_batt_alarm_hold_time_set(
+			PM8XXX_BATT_ALARM_HOLD_TIME_16_MS);
+	if (rc) {
+		pr_err("unable to set batt alarm hold time rc=%d\n", rc);
+		return rc;
+	}
+
+	/* PWM enabled at 2Hz */
+	rc = pm8xxx_batt_alarm_pwm_rate_set(1, 7, 4);
+	if (rc) {
+		pr_err("unable to set batt alarm pwm rate rc=%d\n", rc);
+		return rc;
+	}
+
+	rc = pm8xxx_batt_alarm_register_notifier(&alarm_notifier);
+	if (rc) {
+		pr_err("unable to register alarm notifier rc=%d\n", rc);
+		return rc;
+	}
+
+	return rc;
+}
+
+static int pm8921_battery_gauge_alarm_notify(struct notifier_block *nb,
+		unsigned long status, void *unused)
+{
+	int rc;
+
+	if (!the_chip) {
+		pr_err("not initialized\n");
+		return -EINVAL;
+	}
+
+	switch (status) {
+	case 0:
+		pr_debug("spurious interrupt\n");
+		break;
+	case 1:
+		pr_debug("Low voltage alarm triggered\n");
+		/*
+		 * hold the low voltage wakelock until the soc
+		 * work finds it appropriate to release it.
+		 */
+		wake_lock(&the_chip->low_voltage_wake_lock);
+		the_chip->low_voltage_wake_lock_held = 1;
+
+		rc = pm8xxx_batt_alarm_disable(
+				PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
+		if (!rc)
+			rc = pm8xxx_batt_alarm_enable(
+				PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
+		if (rc)
+			pr_err("unable to set alarm state rc=%d\n", rc);
+		break;
+	case 2:
+		rc = pm8xxx_batt_alarm_disable(
+			PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
+		if (!rc)
+			rc = pm8xxx_batt_alarm_enable(
+				PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
+		if (rc)
+			pr_err("unable to set alarm state rc=%d\n", rc);
+
+		break;
+	default:
+		pr_err("error received\n");
+		break;
+	}
+
+	return 0;
+};
+
+
 #define HOLD_OREG_DATA		BIT(1)
 static int pm_bms_lock_output_data(struct pm8921_bms_chip *chip)
 {
@@ -506,15 +643,15 @@
 #define SLEEP_CLK_HZ		32764
 #define SECONDS_PER_HOUR	3600
 /**
- * ccmicrovolt_to_uvh -
+ * ccmicrovolt_to_pvh -
  * @cc_uv:  coulumb counter converted to uV
  *
- * RETURNS:	coulumb counter based charge in uVh
- *		(micro Volt Hour)
+ * RETURNS:	coulumb counter based charge in pVh
+ *		(pico Volt Hour)
  */
-static s64 ccmicrovolt_to_uvh(s64 cc_uv)
+static s64 ccmicrovolt_to_pvh(s64 cc_uv)
 {
-	return div_s64(cc_uv * CC_READING_TICKS,
+	return div_s64(cc_uv * CC_READING_TICKS * 1000000L,
 			SLEEP_CLK_HZ * SECONDS_PER_HOUR);
 }
 
@@ -524,6 +661,7 @@
 	int rc;
 	uint16_t msw, lsw;
 
+	*result = 0;
 	rc = pm_bms_read_output_data(chip, CC_LSB, &lsw);
 	if (rc) {
 		pr_err("fail to read CC_LSB rc = %d\n", rc);
@@ -590,6 +728,23 @@
 	return 0;
 }
 
+static int get_batt_temp(struct pm8921_bms_chip *chip, int *batt_temp)
+{
+	int rc;
+	struct pm8xxx_adc_chan_result result;
+
+	rc = pm8xxx_adc_read(chip->batt_temp_channel, &result);
+	if (rc) {
+		pr_err("error reading batt_temp_channel = %d, rc = %d\n",
+					chip->batt_temp_channel, rc);
+		return rc;
+	}
+	*batt_temp = result.physical;
+	pr_debug("batt_temp phy = %lld meas = 0x%llx\n", result.physical,
+						result.measurement);
+	return 0;
+}
+
 #define BMS_MODE_BIT	BIT(6)
 #define EN_VBAT_BIT	BIT(5)
 #define OVERRIDE_MODE_DELAY_MS	20
@@ -600,6 +755,7 @@
 	int16_t vbat_raw;
 	int vsense_uv;
 	int usb_chg;
+	int batt_temp;
 
 	mutex_lock(&the_chip->bms_output_lock);
 
@@ -614,12 +770,13 @@
 	pm_bms_read_output_data(the_chip, VBATT_AVG, &vbat_raw);
 	pm_bms_unlock_output_data(the_chip);
 	pm_bms_masked_write(the_chip, BMS_CONTROL,
-			BMS_MODE_BIT | EN_VBAT_BIT, 0);
+		BMS_MODE_BIT | EN_VBAT_BIT, 0);
 
 	pm8xxx_writeb(the_chip->dev->parent, BMS_S1_DELAY, 0x0B);
 
 	mutex_unlock(&the_chip->bms_output_lock);
 
+	get_batt_temp(the_chip, &batt_temp);
 	usb_chg = usb_chg_plugged_in(the_chip);
 
 	convert_vbatt_raw_to_uv(the_chip, usb_chg, vbat_raw, vbat_uv);
@@ -690,8 +847,8 @@
 {
 	int ibat_ua, vbat_uv, ocv_est_uv;
 	int rc;
-
-	int rbatt_mohm = chip->default_rbatt_mohm + chip->rconn_mohm;
+	int rbatt_mohm = chip->default_rbatt_mohm + chip->rconn_mohm
+				+ chip->rbatt_capacitive_mohm;
 
 	rc = pm8921_bms_get_simultaneous_battery_voltage_and_current(
 							&ibat_ua,
@@ -718,16 +875,105 @@
 	}
 	return reg & WD_BIT;
 }
+
+#define IBAT_TOL_MASK		0x0F
+#define OCV_TOL_MASK			0xF0
+#define IBAT_TOL_DEFAULT	0x03
+#define IBAT_TOL_NOCHG		0x0F
+#define OCV_TOL_DEFAULT		0x20
+#define OCV_TOL_NO_OCV		0x00
+static int pm8921_bms_stop_ocv_updates(void)
+{
+	if (!the_chip) {
+		pr_err("BMS driver has not been initialized yet!\n");
+		return -EINVAL;
+	}
+	pr_debug("stopping ocv updates\n");
+	return pm_bms_masked_write(the_chip, BMS_TOLERANCES,
+			OCV_TOL_MASK, OCV_TOL_NO_OCV);
+}
+
+static int pm8921_bms_start_ocv_updates(void)
+{
+	if (!the_chip) {
+		pr_err("BMS driver has not been initialized yet!\n");
+		return -EINVAL;
+	}
+	pr_debug("starting ocv updates\n");
+	return pm_bms_masked_write(the_chip, BMS_TOLERANCES,
+			OCV_TOL_MASK, OCV_TOL_DEFAULT);
+}
+
+static int reset_bms_for_test(void)
+{
+	int ibat_ua, vbat_uv, rc;
+	int ocv_est_uv;
+
+	if (!the_chip) {
+		pr_err("BMS driver has not been initialized yet!\n");
+		return -EINVAL;
+	}
+
+	rc = pm8921_bms_get_simultaneous_battery_voltage_and_current(
+							&ibat_ua,
+							&vbat_uv);
+	/*
+	 * don't include rbatt and rbatt_capacitve since we expect this to
+	 * be used with a fake battery which does not have internal resistnaces
+	 */
+	ocv_est_uv = vbat_uv + (ibat_ua * the_chip->rconn_mohm) / 1000;
+	pr_debug("forcing ocv to be %d due to bms reset mode\n", ocv_est_uv);
+	the_chip->last_ocv_uv = ocv_est_uv;
+	last_soc = -EINVAL;
+	reset_cc(the_chip);
+	the_chip->last_cc_uah = 0;
+	pm8921_bms_stop_ocv_updates();
+
+	pr_debug("bms reset to ocv = %duv vbat_ua = %d ibat_ua = %d\n",
+			the_chip->last_ocv_uv, vbat_uv, ibat_ua);
+
+	return rc;
+}
+
+static int bms_reset_set(const char *val, const struct kernel_param *kp)
+{
+	int rc;
+
+	rc = param_set_bool(val, kp);
+	if (rc) {
+		pr_err("Unable to set bms_reset: %d\n", rc);
+		return rc;
+	}
+
+	if (*val == 'Y') {
+		rc = reset_bms_for_test();
+		if (rc) {
+			pr_err("Unable to modify bms_reset: %d\n", rc);
+			return rc;
+		}
+	}
+	return 0;
+}
+
+static struct kernel_param_ops bms_reset_ops = {
+	.set = bms_reset_set,
+	.get = param_get_bool,
+};
+
+static bool bms_reset;
+module_param_cb(bms_reset, &bms_reset_ops, &bms_reset, 0644);
 /*
  * This reflects what should the CC readings should be for
  * a 5mAh discharge. This value is dependent on
  * CC_RESOLUTION_N, CC_RESOLUTION_D, CC_READING_TICKS
  * and rsense
  */
-#define CC_RAW_5MAH	0x00110000
-#define MIN_OCV_UV	2000000
+#define CC_RAW_5MAH		0x00110000
+#define MIN_OCV_UV		2000000
+#define OCV_RAW_UNINITIALIZED	0xFFFF
 static int read_soc_params_raw(struct pm8921_bms_chip *chip,
-				struct pm8921_soc_params *raw)
+				struct pm8921_soc_params *raw,
+				int batt_temp_decidegc)
 {
 	int usb_chg;
 	int est_ocv_uv;
@@ -744,7 +990,7 @@
 
 	usb_chg =  usb_chg_plugged_in(chip);
 
-	if (chip->prev_last_good_ocv_raw == 0) {
+	if (chip->prev_last_good_ocv_raw == OCV_RAW_UNINITIALIZED) {
 		chip->prev_last_good_ocv_raw = raw->last_good_ocv_raw;
 
 		convert_vbatt_raw_to_uv(chip, usb_chg,
@@ -780,30 +1026,23 @@
 				raw->cc = 0;
 			}
 		}
+		chip->last_ocv_temp_decidegc = batt_temp_decidegc;
 		pr_debug("PON_OCV_UV = %d\n", chip->last_ocv_uv);
 	} else if (chip->prev_last_good_ocv_raw != raw->last_good_ocv_raw) {
 		chip->prev_last_good_ocv_raw = raw->last_good_ocv_raw;
 		convert_vbatt_raw_to_uv(chip, usb_chg,
 			raw->last_good_ocv_raw, &raw->last_good_ocv_uv);
 		chip->last_ocv_uv = raw->last_good_ocv_uv;
+		chip->last_ocv_temp_decidegc = batt_temp_decidegc;
 		/* forget the old cc value upon ocv */
 		chip->last_cc_uah = 0;
 	} else {
 		raw->last_good_ocv_uv = chip->last_ocv_uv;
 	}
 
-	/* fake a high OCV if we are just done charging */
-	if (chip->ocv_reading_at_100 != raw->last_good_ocv_raw) {
-		chip->ocv_reading_at_100 = 0;
-		chip->cc_reading_at_100 = 0;
-	} else {
-		/*
-		 * force 100% ocv by selecting the highest voltage the
-		 * battery could ever reach
-		 */
-		raw->last_good_ocv_uv = chip->max_voltage_uv;
-		chip->last_ocv_uv = chip->max_voltage_uv;
-	}
+	/* stop faking 100% after an OCV event */
+	if (chip->ocv_reading_at_100 != raw->last_good_ocv_raw)
+		chip->ocv_reading_at_100 = OCV_RAW_UNINITIALIZED;
 	pr_debug("0p625 = %duV\n", chip->xoadc_v0625);
 	pr_debug("1p25 = %duV\n", chip->xoadc_v125);
 	pr_debug("last_good_ocv_raw= 0x%x, last_good_ocv_uv= %duV\n",
@@ -834,6 +1073,10 @@
 	pr_debug("adding rconn_mohm = %d rbatt = %d\n",
 				the_chip->rconn_mohm, rbatt);
 
+	rbatt += the_chip->rbatt_capacitive_mohm;
+	pr_debug("adding rbatt_capacitive_mohm = %d rbatt = %d\n",
+				the_chip->rbatt_capacitive_mohm, rbatt);
+
 	if (is_between(20, 10, soc_rbatt))
 		rbatt = rbatt
 			+ ((20 - soc_rbatt) * chip->delta_rbatt_mohm) / 10;
@@ -905,18 +1148,19 @@
 }
 
 static int calculate_pc(struct pm8921_bms_chip *chip, int ocv_uv,
-					int batt_temp, int chargecycles)
+				int batt_temp_decidegc, int chargecycles)
 {
 	int pc, scalefactor;
 
 	pc = interpolate_pc(chip->pc_temp_ocv_lut,
-			batt_temp / 10, ocv_uv / 1000);
+			batt_temp_decidegc / 10, ocv_uv / 1000);
 	pr_debug("pc = %u for ocv = %dmicroVolts batt_temp = %d\n",
-					pc, ocv_uv, batt_temp);
+					pc, ocv_uv, batt_temp_decidegc);
 
 	scalefactor = interpolate_scalingfactor(chip->pc_sf_lut,
 			chargecycles, pc);
-	pr_debug("scalefactor = %u batt_temp = %d\n", scalefactor, batt_temp);
+	pr_debug("scalefactor = %u batt_temp = %d\n",
+					scalefactor, batt_temp_decidegc);
 
 	/* Multiply the initial FCC value by the scale factor. */
 	pc = (pc * scalefactor) / 100;
@@ -935,19 +1179,16 @@
  */
 static void calculate_cc_uah(struct pm8921_bms_chip *chip, int cc, int *val)
 {
-	int64_t cc_voltage_uv, cc_uvh, cc_uah;
+	int64_t cc_voltage_uv, cc_pvh, cc_uah;
 
 	cc_voltage_uv = cc;
-	cc_voltage_uv -= chip->cc_reading_at_100;
-	pr_debug("cc = %d. after subtracting 0x%x cc = %lld\n",
-					cc, chip->cc_reading_at_100,
-					cc_voltage_uv);
+	pr_debug("cc = %d\n", cc);
 	cc_voltage_uv = cc_to_microvolt(chip, cc_voltage_uv);
 	cc_voltage_uv = pm8xxx_cc_adjust_for_gain(cc_voltage_uv);
 	pr_debug("cc_voltage_uv = %lld microvolts\n", cc_voltage_uv);
-	cc_uvh = ccmicrovolt_to_uvh(cc_voltage_uv);
-	pr_debug("cc_uvh = %lld micro_volt_hour\n", cc_uvh);
-	cc_uah = div_s64(cc_uvh * 1000000LL, chip->r_sense_uohm);
+	cc_pvh = ccmicrovolt_to_pvh(cc_voltage_uv);
+	pr_debug("cc_pvh = %lld pico_volt_hour\n", cc_pvh);
+	cc_uah = div_s64(cc_pvh, chip->r_sense_uohm);
 	*val = cc_uah;
 }
 
@@ -1016,28 +1257,34 @@
 	return uuc;
 }
 
+#define TIME_PER_PERCENT_UUC			60
 static int adjust_uuc(struct pm8921_bms_chip *chip, int fcc_uah,
 			int new_pc_unusable,
 			int new_uuc,
 			int batt_temp,
 			int rbatt,
-			int *iavg_ma)
+			int *iavg_ma,
+			int delta_time_s)
 {
 	int new_unusable_mv;
 	int batt_temp_degc = batt_temp / 10;
+	int max_percent_change;
+
+	max_percent_change = max(delta_time_s / TIME_PER_PERCENT_UUC, 1);
 
 	if (chip->prev_pc_unusable == -EINVAL
-		|| abs(chip->prev_pc_unusable - new_pc_unusable) <= 1) {
+		|| abs(chip->prev_pc_unusable - new_pc_unusable)
+			<= max_percent_change) {
 		chip->prev_pc_unusable = new_pc_unusable;
 		return new_uuc;
 	}
 
 	/* the uuc is trying to change more than 1% restrict it */
 	if (new_pc_unusable > chip->prev_pc_unusable)
-		chip->prev_pc_unusable++;
+		chip->prev_pc_unusable += max_percent_change;
 	else
-		chip->prev_pc_unusable--;
-
+		chip->prev_pc_unusable -= max_percent_change;
+	chip->prev_pc_unusable = clamp(chip->prev_pc_unusable, 0, 100);
 	new_uuc = (fcc_uah * chip->prev_pc_unusable) / 100;
 
 	/* also find update the iavg_ma accordingly */
@@ -1056,75 +1303,89 @@
 	return new_uuc;
 }
 
-static void calculate_iavg_ua(struct pm8921_bms_chip *chip, int cc_uah,
-				int *iavg_ua, int *delta_time_s)
+static int get_current_time(unsigned long *now_tm_sec)
 {
-	int delta_cc_uah;
 	struct rtc_time tm;
 	struct rtc_device *rtc;
-	unsigned long now_tm_sec = 0;
-	int rc = 0;
-
-	/* if anything fails report the previous iavg_ua */
-	*iavg_ua = chip->prev_iavg_ua;
+	int rc;
 
 	rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
 	if (rtc == NULL) {
 		pr_err("%s: unable to open rtc device (%s)\n",
 			__FILE__, CONFIG_RTC_HCTOSYS_DEVICE);
-		goto out;
+		return -EINVAL;
 	}
 
 	rc = rtc_read_time(rtc, &tm);
 	if (rc) {
 		pr_err("Error reading rtc device (%s) : %d\n",
 			CONFIG_RTC_HCTOSYS_DEVICE, rc);
-		goto out;
+		return rc;
 	}
 
 	rc = rtc_valid_tm(&tm);
 	if (rc) {
 		pr_err("Invalid RTC time (%s): %d\n",
 			CONFIG_RTC_HCTOSYS_DEVICE, rc);
-		goto out;
+		return rc;
 	}
-	rtc_tm_to_time(&tm, &now_tm_sec);
+	rtc_tm_to_time(&tm, now_tm_sec);
 
-	if (chip->tm_sec == 0) {
-		*delta_time_s = 0;
+	return 0;
+}
+
+static int calculate_delta_time(struct pm8921_bms_chip *chip, int *delta_time_s)
+{
+	unsigned long now_tm_sec = 0;
+
+	/* default to delta time = 0 if anything fails */
+	*delta_time_s = 0;
+
+	get_current_time(&now_tm_sec);
+
+	*delta_time_s = (now_tm_sec - chip->tm_sec);
+	pr_debug("tm_sec = %ld, now_tm_sec = %ld delta_s = %d\n",
+		chip->tm_sec, now_tm_sec, *delta_time_s);
+
+	/* remember this time */
+	chip->tm_sec = now_tm_sec;
+	return 0;
+}
+
+static void calculate_iavg_ua(struct pm8921_bms_chip *chip, int cc_uah,
+				int *iavg_ua, int delta_time_s)
+{
+	int delta_cc_uah = 0;
+
+	/* if anything fails report the previous iavg_ua */
+	*iavg_ua = chip->prev_iavg_ua;
+
+	if (chip->last_cc_uah == INT_MIN) {
 		pm8921_bms_get_battery_current(iavg_ua);
 		goto out;
 	}
 
-	*delta_time_s = (now_tm_sec - chip->tm_sec);
-
 	/* use the previous iavg if called within 15 seconds */
-	if (*delta_time_s < 15) {
+	if (delta_time_s < 15) {
 		*iavg_ua = chip->prev_iavg_ua;
 		goto out;
 	}
 
 	delta_cc_uah = cc_uah - chip->last_cc_uah;
 
-	*iavg_ua = div_s64((s64)delta_cc_uah * 3600, *delta_time_s);
-
-	pr_debug("tm_sec = %ld, now_tm_sec = %ld delta_s = %d delta_cc = %d iavg_ua = %d\n",
-				chip->tm_sec, now_tm_sec,
-				*delta_time_s, delta_cc_uah, (int)*iavg_ua);
+	*iavg_ua = div_s64((s64)delta_cc_uah * 3600, delta_time_s);
 
 out:
+	pr_debug("delta_cc = %d iavg_ua = %d\n", delta_cc_uah, (int)*iavg_ua);
 	/* remember the iavg */
 	chip->prev_iavg_ua = *iavg_ua;
 
 	/* remember cc_uah */
 	chip->last_cc_uah = cc_uah;
-
-	/* remember this time */
-	chip->tm_sec = now_tm_sec;
 }
 
 #define IAVG_SAMPLES 16
-#define CHARGING_IAVG_MA 250
+#define MIN_IAVG_MA 250
 #define MIN_SECONDS_FOR_VALID_SAMPLE	20
 static int calculate_unusable_charge_uah(struct pm8921_bms_chip *chip,
 				int rbatt, int fcc_uah, int cc_uah,
@@ -1158,8 +1419,8 @@
 	 * if we are charging use a nominal avg current so that we keep
 	 * a reasonable UUC while charging
 	 */
-	if (iavg_ma < 0)
-		iavg_ma = CHARGING_IAVG_MA;
+	if (iavg_ma < MIN_IAVG_MA)
+		iavg_ma = MIN_IAVG_MA;
 	iavg_samples[iavg_index] = iavg_ma;
 	iavg_index = (iavg_index + 1) % IAVG_SAMPLES;
 	iavg_num_samples++;
@@ -1177,15 +1438,21 @@
 		iavg_ma = DIV_ROUND_CLOSEST(iavg_ma, iavg_num_samples);
 	}
 
+	/*
+	 * if we're in bms reset mode, force uuc to be 3% of fcc
+	 */
+	if (bms_reset)
+		return (fcc_uah * 3) / 100;
+
 	uuc_uah_iavg = calculate_termination_uuc(chip,
 					batt_temp, chargecycles,
 					fcc_uah, iavg_ma,
 					&pc_unusable);
 	pr_debug("iavg = %d uuc_iavg = %d\n", iavg_ma, uuc_uah_iavg);
 
-	/* restrict the uuc such that it can increase only by one percent */
+	/* restrict the uuc change to one percent per 60 seconds */
 	uuc_uah_iavg = adjust_uuc(chip, fcc_uah, pc_unusable, uuc_uah_iavg,
-					batt_temp, rbatt, &iavg_ma);
+				batt_temp, rbatt, &iavg_ma, delta_time_s);
 
 	/* find out what the avg current should be for this uuc */
 	chip->prev_uuc_iavg_ma = iavg_ma;
@@ -1200,10 +1467,11 @@
 						int fcc_uah, int batt_temp,
 						int chargecycles)
 {
-	int  ocv, pc;
+	int  ocv, pc, batt_temp_decidegc;
 
 	ocv = raw->last_good_ocv_uv;
-	pc = calculate_pc(chip, ocv, batt_temp, chargecycles);
+	batt_temp_decidegc = chip->last_ocv_temp_decidegc;
+	pc = calculate_pc(chip, ocv, batt_temp_decidegc, chargecycles);
 	pr_debug("ocv = %d pc = %d\n", ocv, pc);
 	return (fcc_uah * pc) / 100;
 }
@@ -1216,11 +1484,17 @@
 						int *remaining_charge_uah,
 						int *cc_uah,
 						int *rbatt,
-						int *iavg_ua,
-						int *delta_time_s)
+						int *iavg_ua)
 {
 	int soc_rbatt;
+	int delta_time_s;
+	int rc;
 
+	rc = calculate_delta_time(chip, &delta_time_s);
+	if (rc) {
+		pr_err("Failed to get delta time from RTC: %d\n", rc);
+		delta_time_s = 0;
+	}
 	*fcc_uah = calculate_fcc_uah(chip, batt_temp, chargecycles);
 	pr_debug("FCC = %uuAh batt_temp = %d, cycles = %d\n",
 					*fcc_uah, batt_temp, chargecycles);
@@ -1233,10 +1507,7 @@
 
 	/* calculate cc micro_volt_hour */
 	calculate_cc_uah(chip, raw->cc, cc_uah);
-	pr_debug("cc_uah = %duAh raw->cc = %x cc = %lld after subtracting %x\n",
-				*cc_uah, raw->cc,
-				(int64_t)raw->cc - chip->cc_reading_at_100,
-				chip->cc_reading_at_100);
+	pr_debug("cc_uah = %duAh raw->cc = %x\n", *cc_uah, raw->cc);
 
 	soc_rbatt = ((*remaining_charge_uah - *cc_uah) * 100) / *fcc_uah;
 	if (soc_rbatt < 0)
@@ -1248,7 +1519,7 @@
 	*unusable_charge_uah = calculate_unusable_charge_uah(chip, *rbatt,
 					*fcc_uah, *cc_uah, soc_rbatt,
 					batt_temp, chargecycles, *iavg_ua,
-					*delta_time_s);
+					delta_time_s);
 	pr_debug("UUC = %uuAh\n", *unusable_charge_uah);
 }
 
@@ -1263,7 +1534,6 @@
 	int real_fcc_uah;
 	int rbatt;
 	int iavg_ua;
-	int delta_time_s;
 
 	calculate_soc_params(chip, raw, batt_temp, chargecycles,
 						&fcc_uah,
@@ -1271,8 +1541,7 @@
 						&remaining_charge_uah,
 						&cc_uah,
 						&rbatt,
-						&iavg_ua,
-						&delta_time_s);
+						&iavg_ua);
 
 	real_fcc_uah = remaining_charge_uah - cc_uah;
 	*ret_fcc_uah = fcc_uah;
@@ -1313,6 +1582,8 @@
 }
 EXPORT_SYMBOL(pm8921_bms_get_simultaneous_battery_voltage_and_current);
 
+#define SIGN(x) ((x) < 0 ? -1 : 1)
+
 static void find_ocv_for_soc(struct pm8921_bms_chip *chip,
 			int batt_temp,
 			int chargecycles,
@@ -1340,16 +1611,55 @@
 	new_pc = interpolate_pc(chip->pc_temp_ocv_lut, batt_temp_degc, ocv);
 	pr_debug("test revlookup pc = %d for ocv = %d\n", new_pc, ocv);
 
-	while (abs(new_pc - pc) > 1) {
+	if (abs(new_pc - pc) > 0) {
+		/* Maximum spins to make in while-loop when searching in
+		 * full resolution.
+		 */
+		const unsigned int max_spin_count =
+			chip->max_voltage_uv / 1000 - chip->v_cutoff + 1;
+		unsigned int count = 0;
 		int delta_mv = 5;
+		int diff = abs(new_pc - pc);
+		char sign = SIGN(new_pc - pc);
+		char old_sign;
+		int old_diff;
+		int old_ocv;
 
-		if (new_pc > pc)
-			delta_mv = -1 * delta_mv;
+		do {
+			count++;
+			old_ocv = ocv;
+			old_diff = diff;
+			old_sign = sign;
 
-		ocv = ocv + delta_mv;
-		new_pc = interpolate_pc(chip->pc_temp_ocv_lut,
-				batt_temp_degc, ocv);
-		pr_debug("test revlookup pc = %d for ocv = %d\n", new_pc, ocv);
+			if (new_pc > pc)
+				ocv -= delta_mv;
+			else
+				ocv += delta_mv;
+
+			new_pc = interpolate_pc(chip->pc_temp_ocv_lut,
+							batt_temp_degc, ocv);
+			pr_debug("test revlookup pc = %d for ocv = %d\n",
+				new_pc, ocv);
+			diff = abs(new_pc - pc);
+			sign = SIGN(new_pc - pc);
+
+			if (sign != old_sign) {
+				if (delta_mv == 5) {
+					/*
+					 * we crossed our desired PC probably
+					 * becuase we were overcorrecting
+					 */
+					delta_mv = 1;
+				} else {
+					/* we crossed our desired PC even with
+					 * 1mV steps, choose the best of two */
+					if (diff > old_diff)
+						ocv = old_ocv;
+
+					break;
+				}
+			}
+		} while (count <= max_spin_count && diff > 0);
 	}
 
 	*ocv_uv = ocv * 1000;
@@ -1383,6 +1693,13 @@
 	*ret_rc = rc_uah;
 	*ret_uuc = uuc_uah;
 }
+
+static void calc_current_max(struct pm8921_bms_chip *chip, int ocv_uv,
+		int rbatt_mohm)
+{
+	chip->imax_ua = 1000 * (ocv_uv - chip->v_cutoff * 1000) / rbatt_mohm;
+}
+
 static int bound_soc(int soc)
 {
 	soc = max(0, soc);
@@ -1434,6 +1751,7 @@
 	chg_soc = linear_interpolate(chip->soc_at_cv, chip->ibat_at_cv_ua,
 					100, -1 * chip->chg_term_ua,
 					ibat_ua);
+	chg_soc = bound_soc(chg_soc);
 
 	/* always report a higher soc */
 	if (chg_soc > chip->prev_chg_soc) {
@@ -1459,6 +1777,7 @@
 static void very_low_voltage_check(struct pm8921_bms_chip *chip,
 					int ibat_ua, int vbat_uv)
 {
+	int rc;
 	/*
 	 * if battery is very low (v_cutoff voltage + 20mv) hold
 	 * a wakelock untill soc = 0%
@@ -1477,6 +1796,9 @@
 		chip->low_voltage_wake_lock_held = 0;
 		wake_unlock(&chip->low_voltage_wake_lock);
 		chip->soc_calc_period = chip->normal_voltage_calc_ms;
+		rc = pm8921_bms_enable_batt_alarm(chip);
+		if (rc)
+			pr_err("Unable to enable batt alarm\n");
 	}
 }
 
@@ -1509,11 +1831,18 @@
 	delta_ocv_uv_limit = DIV_ROUND_CLOSEST(ibat_ua, 1000);
 
 	ocv_est_uv = vbat_uv + (ibat_ua * rbatt)/1000;
+	calc_current_max(chip, ocv_est_uv, rbatt);
 	pc_est = calculate_pc(chip, ocv_est_uv, batt_temp, last_chargecycles);
 	soc_est = div_s64((s64)fcc_uah * pc_est - uuc_uah*100,
 						(s64)fcc_uah - uuc_uah);
 	soc_est = bound_soc(soc_est);
 
+	/* never adjust during bms reset mode */
+	if (bms_reset) {
+		pr_debug("bms reset mode, SOC adjustment skipped\n");
+		goto out;
+	}
+
 	if (ibat_ua < 0 && pm8921_is_batfet_closed()) {
 		soc = charging_adjustments(chip, soc, vbat_uv, ibat_ua,
 				batt_temp, chargecycles,
@@ -1545,16 +1874,18 @@
 	last_soc_est = soc_est;
 
 	pc = calculate_pc(chip, chip->last_ocv_uv,
-				batt_temp, last_chargecycles);
+			chip->last_ocv_temp_decidegc, last_chargecycles);
 	if (pc > 0) {
 		pc_new = calculate_pc(chip, chip->last_ocv_uv - (++m * 1000),
-						batt_temp, last_chargecycles);
+					chip->last_ocv_temp_decidegc,
+					last_chargecycles);
 		while (pc_new == pc) {
 			/* start taking 10mV steps */
 			m = m + 10;
 			pc_new = calculate_pc(chip,
 						chip->last_ocv_uv - (m * 1000),
-						batt_temp, last_chargecycles);
+						chip->last_ocv_temp_decidegc,
+						last_chargecycles);
 		}
 	} else {
 		/*
@@ -1587,7 +1918,7 @@
 
 	/* calculate the soc based on this new ocv */
 	pc_new = calculate_pc(chip, chip->last_ocv_uv,
-						batt_temp, last_chargecycles);
+			chip->last_ocv_temp_decidegc, last_chargecycles);
 	rc_new_uah = (fcc_uah * pc_new) / 100;
 	soc_new = (rc_new_uah - cc_uah - uuc_uah)*100 / (fcc_uah - uuc_uah);
 	soc_new = bound_soc(soc_new);
@@ -1714,6 +2045,8 @@
 
 	chg_time_sec = DIV_ROUND_UP(the_chip->charge_time_us, USEC_PER_SEC);
 	catch_up_sec = DIV_ROUND_UP(the_chip->catch_up_time_us, USEC_PER_SEC);
+	if (catch_up_sec == 0)
+		return new_soc;
 	pr_debug("cts= %d catch_up_sec = %d\n", chg_time_sec, catch_up_sec);
 
 	/*
@@ -1760,6 +2093,89 @@
 		power_supply_changed(chip->batt_psy);
 }
 
+#define MIN_DELTA_625_UV	1000
+static void calib_hkadc(struct pm8921_bms_chip *chip)
+{
+	int voltage, rc;
+	struct pm8xxx_adc_chan_result result;
+	int usb_chg;
+	int this_delta;
+
+	mutex_lock(&chip->calib_mutex);
+	rc = pm8xxx_adc_read(the_chip->ref1p25v_channel, &result);
+	if (rc) {
+		pr_err("ADC failed for 1.25volts rc = %d\n", rc);
+		goto out;
+	}
+	voltage = xoadc_reading_to_microvolt(result.adc_code);
+
+	pr_debug("result 1.25v = 0x%x, voltage = %duV adc_meas = %lld\n",
+				result.adc_code, voltage, result.measurement);
+
+	chip->xoadc_v125 = voltage;
+
+	rc = pm8xxx_adc_read(the_chip->ref625mv_channel, &result);
+	if (rc) {
+		pr_err("ADC failed for 1.25volts rc = %d\n", rc);
+		goto out;
+	}
+	voltage = xoadc_reading_to_microvolt(result.adc_code);
+
+	usb_chg = usb_chg_plugged_in(chip);
+	pr_debug("result 0.625V = 0x%x, voltage = %duV adc_meas = %lld usb_chg = %d\n",
+				result.adc_code, voltage, result.measurement,
+				usb_chg);
+
+	if (usb_chg)
+		chip->xoadc_v0625_usb_present = voltage;
+	else
+		chip->xoadc_v0625_usb_absent = voltage;
+
+	chip->xoadc_v0625 = voltage;
+	if (chip->xoadc_v0625_usb_present && chip->xoadc_v0625_usb_absent) {
+		this_delta = chip->xoadc_v0625_usb_present
+						- chip->xoadc_v0625_usb_absent;
+		pr_debug("this_delta= %duV\n", this_delta);
+		if (this_delta > MIN_DELTA_625_UV)
+			last_usb_cal_delta_uv = this_delta;
+		pr_debug("625V_present= %d, 625V_absent= %d, delta = %duV\n",
+			chip->xoadc_v0625_usb_present,
+			chip->xoadc_v0625_usb_absent,
+			last_usb_cal_delta_uv);
+	}
+	pr_debug("calibration batt_temp = %d\n", chip->last_calib_temp);
+out:
+	mutex_unlock(&chip->calib_mutex);
+}
+
+#define HKADC_CALIB_DELAY_S	600
+#define HKADC_CALIB_DELTA_TEMP	20
+static void calib_hkadc_check(struct pm8921_bms_chip *chip, int batt_temp)
+{
+	unsigned long time_since_last_calib;
+	unsigned long tm_now_sec;
+	int delta_temp;
+	int rc;
+
+	rc = get_current_time(&tm_now_sec);
+	if (rc) {
+		pr_err("Could not read current time: %d\n", rc);
+		return;
+	}
+	if (tm_now_sec > chip->last_calib_time) {
+		time_since_last_calib = tm_now_sec - chip->last_calib_time;
+		delta_temp = abs(chip->last_calib_temp - batt_temp);
+		pr_debug("time since last calib: %lu, temp diff = %d\n",
+				time_since_last_calib, delta_temp);
+		if (time_since_last_calib >= HKADC_CALIB_DELAY_S
+			|| delta_temp > HKADC_CALIB_DELTA_TEMP) {
+			chip->last_calib_temp = batt_temp;
+			chip->last_calib_time = tm_now_sec;
+			calib_hkadc(chip);
+		}
+	}
+}
+
 /*
  * Remaining Usable Charge = remaining_charge (charge at ocv instance)
  *				- coloumb counter charge
@@ -1775,7 +2191,6 @@
 	int cc_uah;
 	int rbatt;
 	int iavg_ua;
-	int delta_time_s;
 	int new_ocv;
 	int new_rc_uah;
 	int new_ucc_uah;
@@ -1784,14 +2199,14 @@
 	int new_calculated_soc;
 	static int firsttime = 1;
 
+	calib_hkadc_check(chip, batt_temp);
 	calculate_soc_params(chip, raw, batt_temp, chargecycles,
 						&fcc_uah,
 						&unusable_charge_uah,
 						&remaining_charge_uah,
 						&cc_uah,
 						&rbatt,
-						&iavg_ua,
-						&delta_time_s);
+						&iavg_ua);
 
 	/* calculate remaining usable charge */
 	remaining_usable_charge_uah = remaining_charge_uah
@@ -1908,36 +2323,46 @@
 
 	calculated_soc = new_calculated_soc;
 	firsttime = 0;
+	get_current_time(&chip->last_recalc_time);
+
+	if (chip->disable_flat_portion_ocv) {
+		if (is_between(chip->ocv_dis_high_soc, chip->ocv_dis_low_soc,
+					calculated_soc)) {
+			pm8921_bms_stop_ocv_updates();
+		} else {
+			pm8921_bms_start_ocv_updates();
+		}
+	}
 	return calculated_soc;
 }
 
-static void calculate_soc_work(struct work_struct *work)
+static int recalculate_soc(struct pm8921_bms_chip *chip)
 {
-	struct pm8921_bms_chip *chip = container_of(work,
-				struct pm8921_bms_chip,
-				calculate_soc_delayed_work.work);
-	int batt_temp, rc;
-	struct pm8xxx_adc_chan_result result;
+	int batt_temp;
 	struct pm8921_soc_params raw;
 	int soc;
 
-	rc = pm8xxx_adc_read(chip->batt_temp_channel, &result);
-	if (rc) {
-		pr_err("error reading adc channel = %d, rc = %d\n",
-					chip->batt_temp_channel, rc);
-		return;
-	}
-	pr_debug("batt_temp phy = %lld meas = 0x%llx\n", result.physical,
-						result.measurement);
-	batt_temp = (int)result.physical;
+	wake_lock(&the_chip->soc_wake_lock);
+	get_batt_temp(chip, &batt_temp);
 
 	mutex_lock(&chip->last_ocv_uv_mutex);
-	read_soc_params_raw(chip, &raw);
+	read_soc_params_raw(chip, &raw, batt_temp);
 
 	soc = calculate_state_of_charge(chip, &raw,
 					batt_temp, last_chargecycles);
 	mutex_unlock(&chip->last_ocv_uv_mutex);
+	wake_unlock(&the_chip->soc_wake_lock);
+	return soc;
+}
 
+static void calculate_soc_work(struct work_struct *work)
+{
+	struct delayed_work *dwork = to_delayed_work(work);
+	struct pm8921_bms_chip *chip = container_of(dwork,
+				struct pm8921_bms_chip,
+				calculate_soc_delayed_work);
+
+	recalculate_soc(chip);
 	schedule_delayed_work(&chip->calculate_soc_delayed_work,
 			round_jiffies_relative(msecs_to_jiffies
 			(chip->soc_calc_period)));
@@ -1948,24 +2373,14 @@
 	int soc = calculated_soc;
 	int delta_time_us;
 	struct timespec now;
-	struct pm8xxx_adc_chan_result result;
 	int batt_temp;
-	int rc;
 
 	if (bms_fake_battery != -EINVAL) {
 		pr_debug("Returning Fake SOC = %d%%\n", bms_fake_battery);
 		return bms_fake_battery;
 	}
 
-	rc = pm8xxx_adc_read(the_chip->batt_temp_channel, &result);
-	if (rc) {
-		pr_err("error reading adc channel = %d, rc = %d\n",
-					the_chip->batt_temp_channel, rc);
-		return rc;
-	}
-	pr_debug("batt_temp phy = %lld meas = 0x%llx\n", result.physical,
-						result.measurement);
-	batt_temp = (int)result.physical;
+	get_batt_temp(chip, &batt_temp);
 
 	do_posix_clock_monotonic_gettime(&now);
 	if (chip->t_soc_queried.tv_sec != 0) {
@@ -2010,8 +2425,7 @@
 	}
 
 	/* last_soc < soc  ... scale and catch up */
-	if (last_soc != -EINVAL && last_soc < soc && soc != 100
-				&& chip->catch_up_time_us != 0)
+	if (last_soc != -EINVAL && last_soc < soc && soc != 100)
 		soc = scale_soc_while_chg(chip, delta_time_us, soc, last_soc);
 
 	last_soc = soc;
@@ -2026,10 +2440,6 @@
 {
 	int calculate_soc = 0;
 	struct pm8921_bms_chip *chip = the_chip;
-	int batt_temp, rc;
-	struct pm8xxx_adc_chan_result result;
-	struct pm8921_soc_params raw;
-	int soc;
 
 	pr_debug("Invalidating shutdown soc - the battery was removed\n");
 	if (shutdown_soc_invalid)
@@ -2050,81 +2460,10 @@
 	mutex_unlock(&soc_invalidation_mutex);
 	if (!calculate_soc)
 		return;
-
-	rc = pm8xxx_adc_read(chip->batt_temp_channel, &result);
-	if (rc) {
-		pr_err("error reading adc channel = %d, rc = %d\n",
-					chip->batt_temp_channel, rc);
-		return;
-	}
-	pr_debug("batt_temp phy = %lld meas = 0x%llx\n", result.physical,
-						result.measurement);
-	batt_temp = (int)result.physical;
-
-	mutex_lock(&chip->last_ocv_uv_mutex);
-	read_soc_params_raw(chip, &raw);
-
-	soc = calculate_state_of_charge(chip, &raw,
-					batt_temp, last_chargecycles);
-	mutex_unlock(&chip->last_ocv_uv_mutex);
+	recalculate_soc(chip);
 }
 EXPORT_SYMBOL(pm8921_bms_invalidate_shutdown_soc);
 
-#define MIN_DELTA_625_UV	1000
-static void calib_hkadc(struct pm8921_bms_chip *chip)
-{
-	int voltage, rc;
-	struct pm8xxx_adc_chan_result result;
-	int usb_chg;
-	int this_delta;
-
-	mutex_lock(&chip->calib_mutex);
-	rc = pm8xxx_adc_read(the_chip->ref1p25v_channel, &result);
-	if (rc) {
-		pr_err("ADC failed for 1.25volts rc = %d\n", rc);
-		goto out;
-	}
-	voltage = xoadc_reading_to_microvolt(result.adc_code);
-
-	pr_debug("result 1.25v = 0x%x, voltage = %duV adc_meas = %lld\n",
-				result.adc_code, voltage, result.measurement);
-
-	chip->xoadc_v125 = voltage;
-
-	rc = pm8xxx_adc_read(the_chip->ref625mv_channel, &result);
-	if (rc) {
-		pr_err("ADC failed for 1.25volts rc = %d\n", rc);
-		goto out;
-	}
-	voltage = xoadc_reading_to_microvolt(result.adc_code);
-
-	usb_chg = usb_chg_plugged_in(chip);
-	pr_debug("result 0.625V = 0x%x, voltage = %duV adc_meas = %lld "
-				"usb_chg = %d\n",
-				result.adc_code, voltage, result.measurement,
-				usb_chg);
-
-	if (usb_chg)
-		chip->xoadc_v0625_usb_present = voltage;
-	else
-		chip->xoadc_v0625_usb_absent = voltage;
-
-	chip->xoadc_v0625 = voltage;
-	if (chip->xoadc_v0625_usb_present && chip->xoadc_v0625_usb_absent) {
-		this_delta = chip->xoadc_v0625_usb_present
-						- chip->xoadc_v0625_usb_absent;
-		pr_debug("this_delta= %duV\n", this_delta);
-		if (this_delta > MIN_DELTA_625_UV)
-			last_usb_cal_delta_uv = this_delta;
-		pr_debug("625V_present= %d, 625V_absent= %d, delta = %duV\n",
-			chip->xoadc_v0625_usb_present,
-			chip->xoadc_v0625_usb_absent,
-			last_usb_cal_delta_uv);
-	}
-out:
-	mutex_unlock(&chip->calib_mutex);
-}
-
 static void calibrate_hkadc_work(struct work_struct *work)
 {
 	struct pm8921_bms_chip *chip = container_of(work,
@@ -2138,19 +2477,6 @@
 	schedule_work(&the_chip->calib_hkadc_work);
 }
 
-#define HKADC_CALIB_DELAY_MS	600000
-static void calibrate_hkadc_delayed_work(struct work_struct *work)
-{
-	struct pm8921_bms_chip *chip = container_of(work,
-				struct pm8921_bms_chip,
-				calib_hkadc_delayed_work.work);
-
-	calib_hkadc(chip);
-	schedule_delayed_work(&chip->calib_hkadc_delayed_work,
-			round_jiffies_relative(msecs_to_jiffies
-			(HKADC_CALIB_DELAY_MS)));
-}
-
 int pm8921_bms_get_vsense_avg(int *result)
 {
 	int rc = -EINVAL;
@@ -2171,7 +2497,9 @@
 int pm8921_bms_get_battery_current(int *result_ua)
 {
 	int vsense_uv;
+	int rc = 0;
 
+	*result_ua = 0;
 	if (!the_chip) {
 		pr_err("called before initialization\n");
 		return -EINVAL;
@@ -2183,14 +2511,20 @@
 
 	mutex_lock(&the_chip->bms_output_lock);
 	pm_bms_lock_output_data(the_chip);
-	read_vsense_avg(the_chip, &vsense_uv);
+	rc = read_vsense_avg(the_chip, &vsense_uv);
 	pm_bms_unlock_output_data(the_chip);
 	mutex_unlock(&the_chip->bms_output_lock);
+	if (rc) {
+		pr_err("Unable to read vsense average\n");
+		goto error_vsense;
+	}
 	pr_debug("vsense=%duV\n", vsense_uv);
 	/* cast for signed division */
 	*result_ua = div_s64(vsense_uv * 1000000LL, the_chip->r_sense_uohm);
 	pr_debug("ibat=%duA\n", *result_ua);
-	return 0;
+
+error_vsense:
+	return rc;
 }
 EXPORT_SYMBOL(pm8921_bms_get_battery_current);
 
@@ -2205,87 +2539,38 @@
 }
 EXPORT_SYMBOL_GPL(pm8921_bms_get_percent_charge);
 
-int pm8921_bms_get_rbatt(void)
+int pm8921_bms_get_current_max(void)
 {
-	int batt_temp, rc;
-	struct pm8xxx_adc_chan_result result;
-	struct pm8921_soc_params raw;
-	int fcc_uah;
-	int unusable_charge_uah;
-	int remaining_charge_uah;
-	int cc_uah;
-	int rbatt;
-	int iavg_ua;
-	int delta_time_s;
-
 	if (!the_chip) {
 		pr_err("called before initialization\n");
 		return -EINVAL;
 	}
-
-	rc = pm8xxx_adc_read(the_chip->batt_temp_channel, &result);
-	if (rc) {
-		pr_err("error reading adc channel = %d, rc = %d\n",
-					the_chip->batt_temp_channel, rc);
-		return rc;
-	}
-	pr_debug("batt_temp phy = %lld meas = 0x%llx\n", result.physical,
-						result.measurement);
-	batt_temp = (int)result.physical;
-
-	mutex_lock(&the_chip->last_ocv_uv_mutex);
-
-	read_soc_params_raw(the_chip, &raw);
-
-	calculate_soc_params(the_chip, &raw, batt_temp, last_chargecycles,
-						&fcc_uah,
-						&unusable_charge_uah,
-						&remaining_charge_uah,
-						&cc_uah,
-						&rbatt,
-						&iavg_ua,
-						&delta_time_s);
-	mutex_unlock(&the_chip->last_ocv_uv_mutex);
-
-	return rbatt;
+	return the_chip->imax_ua;
 }
-EXPORT_SYMBOL_GPL(pm8921_bms_get_rbatt);
+EXPORT_SYMBOL_GPL(pm8921_bms_get_current_max);
 
 int pm8921_bms_get_fcc(void)
 {
-	int batt_temp, rc;
-	struct pm8xxx_adc_chan_result result;
+	int batt_temp;
 
 	if (!the_chip) {
 		pr_err("called before initialization\n");
 		return -EINVAL;
 	}
 
-	rc = pm8xxx_adc_read(the_chip->batt_temp_channel, &result);
-	if (rc) {
-		pr_err("error reading adc channel = %d, rc = %d\n",
-					the_chip->batt_temp_channel, rc);
-		return rc;
-	}
-	pr_debug("batt_temp phy = %lld meas = 0x%llx", result.physical,
-						result.measurement);
-	batt_temp = (int)result.physical;
+	get_batt_temp(the_chip, &batt_temp);
 	return calculate_fcc_uah(the_chip, batt_temp, last_chargecycles);
 }
 EXPORT_SYMBOL_GPL(pm8921_bms_get_fcc);
-
-#define IBAT_TOL_MASK		0x0F
-#define OCV_TOL_MASK			0xF0
-#define IBAT_TOL_DEFAULT	0x03
-#define IBAT_TOL_NOCHG		0x0F
-#define OCV_TOL_DEFAULT		0x20
-#define OCV_TOL_NO_OCV		0x00
 void pm8921_bms_charging_began(void)
 {
 	struct pm8921_soc_params raw;
+	int batt_temp;
+
+	get_batt_temp(the_chip, &batt_temp);
 
 	mutex_lock(&the_chip->last_ocv_uv_mutex);
-	read_soc_params_raw(the_chip, &raw);
+	read_soc_params_raw(the_chip, &raw, batt_temp);
 	mutex_unlock(&the_chip->last_ocv_uv_mutex);
 
 	the_chip->start_percent = report_state_of_charge(the_chip);
@@ -2308,26 +2593,17 @@
 #define MIN_START_PERCENT_FOR_LEARNING	30
 void pm8921_bms_charging_end(int is_battery_full)
 {
-	int batt_temp, rc;
-	struct pm8xxx_adc_chan_result result;
+	int batt_temp;
 	struct pm8921_soc_params raw;
 
 	if (the_chip == NULL)
 		return;
 
-	rc = pm8xxx_adc_read(the_chip->batt_temp_channel, &result);
-	if (rc) {
-		pr_err("error reading adc channel = %d, rc = %d\n",
-				the_chip->batt_temp_channel, rc);
-		return;
-	}
-	pr_debug("batt_temp phy = %lld meas = 0x%llx\n", result.physical,
-						result.measurement);
-	batt_temp = (int)result.physical;
+	get_batt_temp(the_chip, &batt_temp);
 
 	mutex_lock(&the_chip->last_ocv_uv_mutex);
 
-	read_soc_params_raw(the_chip, &raw);
+	read_soc_params_raw(the_chip, &raw, batt_temp);
 
 	calculate_cc_uah(the_chip, raw.cc, &bms_end_cc_uah);
 
@@ -2368,18 +2644,20 @@
 
 	if (is_battery_full) {
 		the_chip->ocv_reading_at_100 = raw.last_good_ocv_raw;
-		the_chip->cc_reading_at_100 = raw.cc;
 
 		the_chip->last_ocv_uv = the_chip->max_voltage_uv;
 		raw.last_good_ocv_uv = the_chip->max_voltage_uv;
+		raw.cc = 0;
+		/* reset the cc in h/w */
+		reset_cc(the_chip);
+		the_chip->last_ocv_temp_decidegc = batt_temp;
 		/*
 		 * since we are treating this as an ocv event
 		 * forget the old cc value
 		 */
 		the_chip->last_cc_uah = 0;
-		pr_debug("EOC BATT_FULL ocv_reading = 0x%x cc = 0x%x\n",
-				the_chip->ocv_reading_at_100,
-				the_chip->cc_reading_at_100);
+		pr_debug("EOC BATT_FULL ocv_reading = 0x%x\n",
+				the_chip->ocv_reading_at_100);
 	}
 
 	the_chip->end_percent = calculate_state_of_charge(the_chip, &raw,
@@ -2412,22 +2690,6 @@
 }
 EXPORT_SYMBOL_GPL(pm8921_bms_charging_end);
 
-int pm8921_bms_stop_ocv_updates(struct pm8921_bms_chip *chip)
-{
-	pr_debug("stopping ocv updates\n");
-	return pm_bms_masked_write(chip, BMS_TOLERANCES,
-			OCV_TOL_MASK, OCV_TOL_NO_OCV);
-}
-EXPORT_SYMBOL_GPL(pm8921_bms_stop_ocv_updates);
-
-int pm8921_bms_start_ocv_updates(struct pm8921_bms_chip *chip)
-{
-	pr_debug("stopping ocv updates\n");
-	return pm_bms_masked_write(chip, BMS_TOLERANCES,
-			OCV_TOL_MASK, OCV_TOL_DEFAULT);
-}
-EXPORT_SYMBOL_GPL(pm8921_bms_start_ocv_updates);
-
 static irqreturn_t pm8921_bms_sbi_write_ok_handler(int irq, void *data)
 {
 	pr_debug("irq = %d triggered", irq);
@@ -2646,6 +2908,8 @@
 		chip->default_rbatt_mohm
 				= palladium_1500_data.default_rbatt_mohm;
 		chip->delta_rbatt_mohm = palladium_1500_data.delta_rbatt_mohm;
+		chip->rbatt_capacitive_mohm
+			= palladium_1500_data.rbatt_capacitive_mohm;
 		return 0;
 desay:
 		chip->fcc = desay_5200_data.fcc;
@@ -2655,6 +2919,8 @@
 		chip->rbatt_sf_lut = desay_5200_data.rbatt_sf_lut;
 		chip->default_rbatt_mohm = desay_5200_data.default_rbatt_mohm;
 		chip->delta_rbatt_mohm = desay_5200_data.delta_rbatt_mohm;
+		chip->rbatt_capacitive_mohm
+			= desay_5200_data.rbatt_capacitive_mohm;
 		return 0;
 }
 
@@ -2720,7 +2986,7 @@
 	int ibat_ua, vbat_uv;
 	struct pm8921_soc_params raw;
 
-	read_soc_params_raw(the_chip, &raw);
+	read_soc_params_raw(the_chip, &raw, 300);
 
 	*val = 0;
 
@@ -2767,10 +3033,10 @@
 
 	switch (param) {
 	case STOP_OCV:
-		pm8921_bms_stop_ocv_updates(the_chip);
+		pm8921_bms_stop_ocv_updates();
 		break;
 	case START_OCV:
-		pm8921_bms_start_ocv_updates(the_chip);
+		pm8921_bms_start_ocv_updates();
 		break;
 	default:
 		ret = -EINVAL;
@@ -2785,9 +3051,9 @@
 	int ret = 0;
 	struct pm8921_soc_params raw;
 
-	mutex_lock(&the_chip->bms_output_lock);
-	read_soc_params_raw(the_chip, &raw);
-	mutex_unlock(&the_chip->bms_output_lock);
+	mutex_lock(&the_chip->last_ocv_uv_mutex);
+	read_soc_params_raw(the_chip, &raw, 300);
+	mutex_lock(&the_chip->last_ocv_uv_mutex);
 
 	*val = 0;
 
@@ -3006,6 +3272,9 @@
 	chip->rconn_mohm = pdata->rconn_mohm;
 	chip->start_percent = -EINVAL;
 	chip->end_percent = -EINVAL;
+	chip->last_cc_uah = INT_MIN;
+	chip->ocv_reading_at_100 = OCV_RAW_UNINITIALIZED;
+	chip->prev_last_good_ocv_raw = OCV_RAW_UNINITIALIZED;
 	chip->shutdown_soc_valid_limit = pdata->shutdown_soc_valid_limit;
 	chip->adjust_soc_low_threshold = pdata->adjust_soc_low_threshold;
 
@@ -3019,6 +3288,7 @@
 
 	chip->prev_pc_unusable = -EINVAL;
 	chip->soc_at_cv = -EINVAL;
+	chip->imax_ua = -EINVAL;
 
 	chip->ignore_shutdown_soc = pdata->ignore_shutdown_soc;
 	rc = set_battery_data(chip);
@@ -3045,18 +3315,25 @@
 	chip->revision = pm8xxx_get_revision(chip->dev->parent);
 	chip->enable_fcc_learning = pdata->enable_fcc_learning;
 
+	chip->disable_flat_portion_ocv = pdata->disable_flat_portion_ocv;
+	chip->ocv_dis_high_soc = pdata->ocv_dis_high_soc;
+	chip->ocv_dis_low_soc = pdata->ocv_dis_low_soc;
+
+	chip->alarm_low_mv = pdata->alarm_low_mv;
+	chip->alarm_high_mv = pdata->alarm_high_mv;
+
 	mutex_init(&chip->calib_mutex);
 	INIT_WORK(&chip->calib_hkadc_work, calibrate_hkadc_work);
-	INIT_DELAYED_WORK(&chip->calib_hkadc_delayed_work,
-				calibrate_hkadc_delayed_work);
 
 	INIT_DELAYED_WORK(&chip->calculate_soc_delayed_work,
 			calculate_soc_work);
 
+	wake_lock_init(&chip->soc_wake_lock,
+			WAKE_LOCK_SUSPEND, "pm8921_soc_lock");
 	rc = request_irqs(chip, pdev);
 	if (rc) {
 		pr_err("couldn't register interrupts rc = %d\n", rc);
-		goto free_chip;
+		goto destroy_soc_wl;
 	}
 
 	wake_lock_init(&chip->low_voltage_wake_lock,
@@ -3081,27 +3358,39 @@
 	}
 	check_initial_ocv(chip);
 
-	/* start periodic hkadc calibration */
-	calib_hkadc(chip);
-	schedule_delayed_work(&chip->calib_hkadc_delayed_work,
-			round_jiffies_relative(msecs_to_jiffies
-			(HKADC_CALIB_DELAY_MS)));
-
 	/* enable the vbatt reading interrupts for scheduling hkadc calib */
 	pm8921_bms_enable_irq(chip, PM8921_BMS_GOOD_OCV);
 	pm8921_bms_enable_irq(chip, PM8921_BMS_OCV_FOR_R);
 
+	rc = pm8921_bms_configure_batt_alarm(chip);
+	if (rc) {
+		pr_err("Couldn't configure battery alarm! rc=%d\n", rc);
+		goto free_irqs;
+	}
+
+	rc = pm8921_bms_enable_batt_alarm(chip);
+	if (rc) {
+		pr_err("Couldn't enable battery alarm! rc=%d\n", rc);
+		goto free_irqs;
+	}
+
 	calculate_soc_work(&(chip->calculate_soc_delayed_work.work));
 
-	get_battery_uvolts(chip, &vbatt);
-	pr_info("OK battery_capacity_at_boot=%d volt = %d ocv = %d\n",
+	rc = get_battery_uvolts(chip, &vbatt);
+	if (!rc)
+		pr_info("OK battery_capacity_at_boot=%d volt = %d ocv = %d\n",
 				pm8921_bms_get_percent_charge(),
 				vbatt, chip->last_ocv_uv);
+	else
+		pr_info("Unable to read battery voltage at boot\n");
 
 	return 0;
 
 free_irqs:
+	wake_lock_destroy(&chip->low_voltage_wake_lock);
 	free_irqs(chip);
+destroy_soc_wl:
+	wake_lock_destroy(&chip->soc_wake_lock);
 free_chip:
 	kfree(chip);
 	return rc;
@@ -3121,17 +3410,26 @@
 
 static int pm8921_bms_resume(struct device *dev)
 {
-	int rc, ibat_ua, vbat_uv;
+	int rc;
+	unsigned long time_since_last_recalc;
+	unsigned long tm_now_sec;
 
-	rc = pm8921_bms_get_simultaneous_battery_voltage_and_current(
-							&ibat_ua,
-							&vbat_uv);
-	if (rc < 0) {
-		pr_err("simultaneous vbat ibat failed err = %d\n", rc);
+	rc = get_current_time(&tm_now_sec);
+	if (rc) {
+		pr_err("Could not read current time: %d\n", rc);
 		return 0;
 	}
+	if (tm_now_sec > the_chip->last_recalc_time) {
+		time_since_last_recalc = tm_now_sec -
+				the_chip->last_recalc_time;
+		pr_debug("Time since last recalc: %lu\n",
+				time_since_last_recalc);
+		if (time_since_last_recalc >= the_chip->soc_calc_period) {
+			the_chip->last_recalc_time = tm_now_sec;
+			recalculate_soc(the_chip);
+		}
+	}
 
-	very_low_voltage_check(the_chip, ibat_ua, vbat_uv);
 	return 0;
 }
 
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index bd62cf1..03b3e0d 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -255,12 +255,9 @@
 	struct dentry			*dent;
 	struct bms_notify		bms_notify;
 	int				*usb_trim_table;
-	struct regulator		*vreg_xoadc;
 	bool				ext_charging;
 	bool				ext_charge_done;
 	bool				iusb_fine_res;
-	bool				final_kickstart;
-	bool				lockup_lpm_wrkarnd;
 	DECLARE_BITMAP(enabled_irqs, PM_CHG_MAX_INTS);
 	struct work_struct		battery_id_valid_work;
 	int64_t				batt_id_min;
@@ -293,6 +290,10 @@
 	int				btc_override_hot_decidegc;
 	int				btc_delay_ms;
 	bool				btc_panic_if_cant_stop_chg;
+	int				stop_chg_upon_expiry;
+	bool				disable_aicl;
+	int				usb_type;
+	bool				disable_chg_rmvl_wrkarnd;
 };
 
 /* user space parameter to limit usb current */
@@ -308,7 +309,6 @@
 
 static struct pm8921_chg_chip *the_chip;
 
-static DEFINE_SPINLOCK(lpm_lock);
 #define LPM_ENABLE_BIT	BIT(2)
 static int pm8921_chg_set_lpm(struct pm8921_chg_chip *chip, int enable)
 {
@@ -337,38 +337,10 @@
 static int pm_chg_write(struct pm8921_chg_chip *chip, u16 addr, u8 reg)
 {
 	int rc;
-	unsigned long flags = 0;
-
-	/* Disable LPM */
-	if (chip->lockup_lpm_wrkarnd) {
-		spin_lock_irqsave(&lpm_lock, flags);
-
-		/*
-		 * This write could have initiated right after a previous write.
-		 * Allow time to settle to go in to lpm from the previous write
-		 */
-		udelay(200);
-		rc = pm8921_chg_set_lpm(chip, 0);
-		if (rc)
-			goto lpm_err;
-
-		/* Wait to come out of LPM */
-		udelay(200);
-	}
 
 	rc = pm8xxx_writeb(chip->dev->parent, addr, reg);
-	if (rc) {
-		pr_err("pm_chg_write failed: addr=%03X, rc=%d\n", addr, rc);
-		goto lpm_err;
-	}
-
-	/* Enable LPM */
-	if (chip->lockup_lpm_wrkarnd)
-		rc = pm8921_chg_set_lpm(chip, 1);
-
-lpm_err:
-	if (chip->lockup_lpm_wrkarnd)
-		spin_unlock_irqrestore(&lpm_lock, flags);
+	if (rc)
+		pr_err("failed: addr=%03X, rc=%d\n", addr, rc);
 
 	return rc;
 }
@@ -400,23 +372,6 @@
 					chip->pmic_chg_irq[irq_id]);
 }
 
-static int is_chg_on_bat(struct pm8921_chg_chip *chip)
-{
-	return !(pm_chg_get_rt_status(chip, DCIN_VALID_IRQ)
-			|| pm_chg_get_rt_status(chip, USBIN_VALID_IRQ));
-}
-
-static void pm8921_chg_bypass_bat_gone_debounce(struct pm8921_chg_chip *chip,
-		int bypass)
-{
-	int rc;
-
-	rc = pm_chg_write(chip, COMPARATOR_OVERRIDE, bypass ? 0x89 : 0x88);
-	if (rc) {
-		pr_err("Failed to set bypass bit to %d rc=%d\n", bypass, rc);
-	}
-}
-
 /* Treat OverVoltage/UnderVoltage as source missing */
 static int is_usb_chg_plugged_in(struct pm8921_chg_chip *chip)
 {
@@ -439,68 +394,77 @@
 static int pm_chg_get_fsm_state(struct pm8921_chg_chip *chip)
 {
 	u8 temp;
-	int err, ret = 0;
+	int err = 0, ret = 0;
 
 	temp = CAPTURE_FSM_STATE_CMD;
-	err = pm_chg_write(chip, CHG_TEST, temp);
+	err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
 	if (err) {
 		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
-		return err;
+		goto err_out;
 	}
 
 	temp = READ_BANK_7;
-	err = pm_chg_write(chip, CHG_TEST, temp);
+	err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
 	if (err) {
 		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
-		return err;
+		goto err_out;
 	}
 
 	err = pm8xxx_readb(chip->dev->parent, CHG_TEST, &temp);
 	if (err) {
 		pr_err("pm8xxx_readb fail: addr=%03X, rc=%d\n", CHG_TEST, err);
-		return err;
+		goto err_out;
 	}
 	/* get the lower 4 bits */
 	ret = temp & 0xF;
 
 	temp = READ_BANK_4;
-	err = pm_chg_write(chip, CHG_TEST, temp);
+	err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
 	if (err) {
 		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
-		return err;
+		goto err_out;
 	}
 
 	err = pm8xxx_readb(chip->dev->parent, CHG_TEST, &temp);
 	if (err) {
 		pr_err("pm8xxx_readb fail: addr=%03X, rc=%d\n", CHG_TEST, err);
-		return err;
+		goto err_out;
 	}
 	/* get the upper 1 bit */
 	ret |= (temp & 0x1) << 4;
+
+err_out:
+	if (err)
+		return err;
+
 	return  ret;
 }
 
 #define READ_BANK_6		0x60
 static int pm_chg_get_regulation_loop(struct pm8921_chg_chip *chip)
 {
-	u8 temp;
-	int err;
+	u8 temp, data;
+	int err = 0;
 
 	temp = READ_BANK_6;
-	err = pm_chg_write(chip, CHG_TEST, temp);
+	err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
 	if (err) {
 		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
-		return err;
+		goto err_out;
 	}
 
-	err = pm8xxx_readb(chip->dev->parent, CHG_TEST, &temp);
+	err = pm8xxx_readb(chip->dev->parent, CHG_TEST, &data);
 	if (err) {
 		pr_err("pm8xxx_readb fail: addr=%03X, rc=%d\n", CHG_TEST, err);
-		return err;
+		goto err_out;
 	}
 
+err_out:
+	if (err)
+		return err;
+
 	/* return the lower 4 bits */
-	return temp & CHG_ALL_LOOPS;
+	return data & CHG_ALL_LOOPS;
 }
 
 #define CHG_USB_SUSPEND_BIT  BIT(2)
@@ -927,7 +891,7 @@
 	if (trim < 0)
 		trim = 0;
 
-	pr_err("trim_orig %d write 0x%x index=%d value 0x%x to USB_OVP_TRIM\n",
+	pr_debug("trim_orig %d write 0x%x index=%d value 0x%x to USB_OVP_TRIM\n",
 		usb_trim_reg_orig, trim, index, chip->usb_trim_table[index]);
 
 	rc = pm8xxx_readb(chip->dev->parent, REG_SBI_CONFIG, &sbi_config);
@@ -1387,6 +1351,7 @@
 	POWER_SUPPLY_PROP_ONLINE,
 	POWER_SUPPLY_PROP_CURRENT_MAX,
 	POWER_SUPPLY_PROP_SCOPE,
+	POWER_SUPPLY_PROP_HEALTH,
 };
 
 static enum power_supply_property pm_power_props_mains[] = {
@@ -1403,6 +1368,8 @@
 				  enum power_supply_property psp,
 				  union power_supply_propval *val)
 {
+	int type;
+
 	/* Check if called before init */
 	if (!the_chip)
 		return -EINVAL;
@@ -1422,10 +1389,11 @@
 			return 0;
 		}
 
-		/* USB with max current greater than 500 mA connected */
-		if (usb_target_ma > USB_WALL_THRESHOLD_MA)
+		type = the_chip->usb_type;
+		if (type == POWER_SUPPLY_TYPE_USB_DCP ||
+			type == POWER_SUPPLY_TYPE_USB_ACA ||
+			type == POWER_SUPPLY_TYPE_USB_CDP)
 			val->intval = is_usb_chg_plugged_in(the_chip);
-			return 0;
 
 		break;
 	default:
@@ -1434,6 +1402,24 @@
 	return 0;
 }
 
+static int disable_aicl(int disable)
+{
+	if (disable != POWER_SUPPLY_HEALTH_UNKNOWN
+		&& disable != POWER_SUPPLY_HEALTH_GOOD) {
+		pr_err("called with invalid param :%d\n", disable);
+		return -EINVAL;
+	}
+
+	if (!the_chip) {
+		pr_err("%s called before init\n", __func__);
+		return -EINVAL;
+	}
+
+	pr_debug("Disable AICL = %d\n", disable);
+	the_chip->disable_aicl = disable;
+	return 0;
+}
+
 static int switch_usb_to_charge_mode(struct pm8921_chg_chip *chip)
 {
 	int rc;
@@ -1491,12 +1477,28 @@
 		break;
 	case POWER_SUPPLY_PROP_TYPE:
 		return pm8921_set_usb_power_supply_type(val->intval);
+	case POWER_SUPPLY_PROP_HEALTH:
+		/* UNKNOWN(0) means enable aicl, GOOD(1) means disable aicl */
+		return disable_aicl(val->intval);
 	default:
 		return -EINVAL;
 	}
 	return 0;
 }
 
+static int usb_property_is_writeable(struct power_supply *psy,
+						enum power_supply_property psp)
+{
+	switch (psp) {
+	case POWER_SUPPLY_PROP_HEALTH:
+		return 1;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
 static int pm_power_get_property_usb(struct power_supply *psy,
 				  enum power_supply_property psp,
 				  union power_supply_propval *val)
@@ -1520,11 +1522,9 @@
 	case POWER_SUPPLY_PROP_ONLINE:
 		val->intval = 0;
 
-		/* USB charging */
-		if (usb_target_ma < USB_WALL_THRESHOLD_MA)
+		if (the_chip->usb_type == POWER_SUPPLY_TYPE_USB)
 			val->intval = is_usb_chg_plugged_in(the_chip);
-		else
-		    return 0;
+
 		break;
 
 	case POWER_SUPPLY_PROP_SCOPE:
@@ -1533,6 +1533,10 @@
 		else
 			val->intval = POWER_SUPPLY_SCOPE_DEVICE;
 		break;
+	case POWER_SUPPLY_PROP_HEALTH:
+		/* UNKNOWN(0) means enable aicl, GOOD(1) means disable aicl */
+		val->intval = the_chip->disable_aicl;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -1662,32 +1666,7 @@
 
 static int get_prop_batt_current_max(struct pm8921_chg_chip *chip)
 {
-	int rbatt, ibatt_ua, vbatt_uv, ocv_uv;
-	int imax_ma;
-	int rc;
-
-	rbatt = pm8921_bms_get_rbatt();
-
-	if (rbatt < 0) {
-		rc = -ENXIO;
-		return rc;
-	}
-
-	rc =  pm8921_bms_get_simultaneous_battery_voltage_and_current
-			(&ibatt_ua, &vbatt_uv);
-
-	if (rc)
-		return rc;
-
-	ocv_uv = vbatt_uv + ibatt_ua*rbatt/1000;
-
-	imax_ma = (ocv_uv - chip->min_voltage_mv*1000)/rbatt;
-
-	if (imax_ma < 0)
-		imax_ma = 0;
-
-	return imax_ma*1000;
-
+	return pm8921_bms_get_current_max();
 }
 
 static int get_prop_batt_current(struct pm8921_chg_chip *chip)
@@ -1853,7 +1832,6 @@
 
 static void (*notify_vbus_state_func_ptr)(int);
 static int usb_chg_current;
-static DEFINE_SPINLOCK(vbus_lock);
 
 int pm8921_charger_register_vbus_sn(void (*callback)(int))
 {
@@ -1882,7 +1860,6 @@
 	}
 }
 
-/* assumes vbus_lock is held */
 static void __pm8921_charger_vbus_draw(unsigned int mA)
 {
 	int i, rc;
@@ -1936,15 +1913,10 @@
 /* USB calls these to tell us how much max usb current the system can draw */
 void pm8921_charger_vbus_draw(unsigned int mA)
 {
-	unsigned long flags;
+	int set_usb_now_ma;
 
 	pr_debug("Enter charge=%d\n", mA);
 
-	if (!the_chip) {
-		pr_err("chip not yet initalized\n");
-		return;
-	}
-
 	/*
 	 * Reject VBUS requests if USB connection is the only available
 	 * power source. This makes sure that if booting without
@@ -1954,10 +1926,10 @@
 	 * This would also apply when the battery has been
 	 * removed from the running system.
 	 */
-	if (!get_prop_batt_present(the_chip)
+	if (mA == 0 && the_chip && !get_prop_batt_present(the_chip)
 		&& !is_dc_chg_plugged_in(the_chip)) {
 		if (!the_chip->has_dc_supply) {
-			pr_err("rejected: no other power source connected\n");
+			pr_err("rejected: no other power source mA = %d\n", mA);
 			return;
 		}
 	}
@@ -1970,23 +1942,26 @@
 	if (usb_target_ma == 0 && mA > USB_WALL_THRESHOLD_MA)
 		usb_target_ma = mA;
 
-	spin_lock_irqsave(&vbus_lock, flags);
-	if (the_chip) {
-		if (mA > USB_WALL_THRESHOLD_MA)
-			__pm8921_charger_vbus_draw(USB_WALL_THRESHOLD_MA);
-		else
-			__pm8921_charger_vbus_draw(mA);
-	} else {
+	if (usb_target_ma)
+		usb_target_ma = mA;
+
+
+	if (mA > USB_WALL_THRESHOLD_MA)
+		set_usb_now_ma = USB_WALL_THRESHOLD_MA;
+	else
+		set_usb_now_ma = mA;
+
+	if (the_chip && the_chip->disable_aicl)
+		set_usb_now_ma = mA;
+
+	if (the_chip)
+		__pm8921_charger_vbus_draw(set_usb_now_ma);
+	else
 		/*
 		 * called before pmic initialized,
 		 * save this value and use it at probe
 		 */
-		if (mA > USB_WALL_THRESHOLD_MA)
-			usb_chg_current = USB_WALL_THRESHOLD_MA;
-		else
-			usb_chg_current = mA;
-	}
-	spin_unlock_irqrestore(&vbus_lock, flags);
+		usb_chg_current = set_usb_now_ma;
 }
 EXPORT_SYMBOL_GPL(pm8921_charger_vbus_draw);
 
@@ -2210,10 +2185,10 @@
 		return -EINVAL;
 	}
 
-	if (type < POWER_SUPPLY_TYPE_USB)
+	if (type < POWER_SUPPLY_TYPE_USB && type > POWER_SUPPLY_TYPE_BATTERY)
 		return -EINVAL;
 
-	the_chip->usb_psy.type = type;
+	the_chip->usb_type = type;
 	power_supply_changed(&the_chip->usb_psy);
 	power_supply_changed(&the_chip->dc_psy);
 	return 0;
@@ -2229,86 +2204,9 @@
 	return get_prop_batt_temp(the_chip);
 }
 
-static int pm8921_apply_19p2mhz_kickstart(struct pm8921_chg_chip *chip)
-{
-	int err;
-	u8 temp;
-	unsigned long flags = 0;
-
-	spin_lock_irqsave(&lpm_lock, flags);
-	err = pm8921_chg_set_lpm(chip, 0);
-	if (err) {
-		pr_err("Error settig LPM rc=%d\n", err);
-		goto kick_err;
-	}
-
-	temp  = 0xD1;
-	err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
-	if (err) {
-		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
-		goto kick_err;
-	}
-
-	temp  = 0xD3;
-	err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
-	if (err) {
-		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
-		goto kick_err;
-	}
-
-	temp  = 0xD1;
-	err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
-	if (err) {
-		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
-		goto kick_err;
-	}
-
-	temp  = 0xD5;
-	err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
-	if (err) {
-		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
-		goto kick_err;
-	}
-
-	/* Wait a few clock cycles before re-enabling hw clock switching */
-	udelay(183);
-
-	temp  = 0xD1;
-	err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
-	if (err) {
-		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
-		goto kick_err;
-	}
-
-	temp  = 0xD0;
-	err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
-	if (err) {
-		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
-		goto kick_err;
-	}
-
-	/* Wait for few clock cycles before re-enabling LPM */
-	udelay(32);
-
-kick_err:
-	err = pm8921_chg_set_lpm(chip, 1);
-	if (err)
-		pr_err("Error settig LPM rc=%d\n", err);
-
-	spin_unlock_irqrestore(&lpm_lock, flags);
-
-	return err;
-}
-
 static void handle_usb_insertion_removal(struct pm8921_chg_chip *chip)
 {
-	int usb_present, rc = 0;
-
-	if (chip->lockup_lpm_wrkarnd) {
-		rc = pm8921_apply_19p2mhz_kickstart(chip);
-		if (rc)
-			pr_err("Failed to apply kickstart rc=%d\n", rc);
-	}
+	int usb_present;
 
 	pm_chg_failed_clear(chip, 1);
 	usb_present = is_usb_chg_plugged_in(chip);
@@ -2318,11 +2216,6 @@
 		power_supply_changed(&chip->usb_psy);
 		power_supply_changed(&chip->batt_psy);
 		pm8921_bms_calibrate_hkadc();
-
-		/* Enable/disable bypass if charger is on battery */
-		if (chip->lockup_lpm_wrkarnd)
-			pm8921_chg_bypass_bat_gone_debounce(chip,
-				is_chg_on_bat(chip));
 	}
 	if (usb_present) {
 		schedule_delayed_work(&chip->unplug_check_work,
@@ -2338,10 +2231,6 @@
 
 static void handle_stop_ext_chg(struct pm8921_chg_chip *chip)
 {
-	if (chip->lockup_lpm_wrkarnd)
-		/* Enable bypass if charger is on battery */
-		pm8921_chg_bypass_bat_gone_debounce(chip, is_chg_on_bat(chip));
-
 	if (!chip->ext_psy) {
 		pr_debug("external charger not registered.\n");
 		return;
@@ -2371,10 +2260,6 @@
 	unsigned long delay =
 		round_jiffies_relative(msecs_to_jiffies(EOC_CHECK_PERIOD_MS));
 
-	/* Disable bypass if charger connected and not running on bat */
-	if (chip->lockup_lpm_wrkarnd)
-		pm8921_chg_bypass_bat_gone_debounce(chip, is_chg_on_bat(chip));
-
 	if (!chip->ext_psy) {
 		pr_debug("external charger not registered.\n");
 		return;
@@ -2538,7 +2423,11 @@
 			break;
 		}
 	}
-	pm_chg_masked_write(chip, ovpreg, OVP_DEBOUNCE_TIME, 0x2);
+	if (pm8xxx_get_version(chip->dev->parent) == PM8XXX_VERSION_8917)
+		pm_chg_masked_write(chip, ovpreg, OVP_DEBOUNCE_TIME, 0x6);
+	else
+		pm_chg_masked_write(chip, ovpreg, OVP_DEBOUNCE_TIME, 0x2);
+
 	pr_debug("Exit count=%d chg_gone=%d, active_valid=%d\n",
 		count, chg_gone, active_chg_plugged_in);
 	return;
@@ -2611,7 +2500,8 @@
 	 * The AICL algorithm will step up the current from 500mA to target
 	 */
 	if (is_usb_chg_plugged_in(chip)
-		&& usb_target_ma > USB_WALL_THRESHOLD_MA) {
+		&& usb_target_ma > USB_WALL_THRESHOLD_MA
+		&& !chip->disable_aicl) {
 		/* decrease usb_target_ma */
 		decrease_usb_ma_value(&usb_target_ma);
 		/* reset here, increase in unplug_check_worker */
@@ -2729,9 +2619,11 @@
 	struct pm8921_chg_chip *chip = data;
 	int ret;
 
-	ret = pm_chg_failed_clear(chip, 1);
-	if (ret)
-		pr_err("Failed to write CHG_FAILED_CLEAR bit\n");
+	if (!chip->stop_chg_upon_expiry) {
+		ret = pm_chg_failed_clear(chip, 1);
+		if (ret)
+			pr_err("Failed to write CHG_FAILED_CLEAR bit\n");
+	}
 
 	pr_err("batt_present = %d, batt_temp_ok = %d, state_changed_to=%d\n",
 			get_prop_batt_present(chip),
@@ -2849,30 +2741,15 @@
 				pm_chg_get_fsm_state(chip),
 				get_prop_batt_current(chip)
 				);
-			if (chip->lockup_lpm_wrkarnd) {
-				rc = pm8921_apply_19p2mhz_kickstart(chip);
-				if (rc)
-					pr_err("Failed kickstart rc=%d\n", rc);
-
-				/*
-				 * Make sure kickstart happens at least 200 ms
-				 * after charger has been removed.
-				 */
-				if (chip->final_kickstart) {
-					chip->final_kickstart = false;
-					goto check_again_later;
-				}
-			}
 			return;
 		} else {
 			goto check_again_later;
 		}
 	}
 
-	chip->final_kickstart = true;
-
 	/* AICL only for usb wall charger */
-	if ((active_path & USB_ACTIVE_BIT) && usb_target_ma > 0) {
+	if ((active_path & USB_ACTIVE_BIT) && usb_target_ma > 0 &&
+		!chip->disable_aicl) {
 		reg_loop = pm_chg_get_regulation_loop(chip);
 		pr_debug("reg_loop=0x%x usb_ma = %d\n", reg_loop, usb_ma);
 		if ((reg_loop & VIN_ACTIVE_BIT) &&
@@ -2891,7 +2768,7 @@
 	pr_debug("reg_loop=0x%x usb_ma = %d\n", reg_loop, usb_ma);
 
 	ibat = get_prop_batt_current(chip);
-	if (reg_loop & VIN_ACTIVE_BIT) {
+	if ((reg_loop & VIN_ACTIVE_BIT) && !chip->disable_chg_rmvl_wrkarnd) {
 		if (ibat > 0) {
 			pr_debug("revboost ibat = %d fsm = %d loop = 0x%x\n",
 				ibat, pm_chg_get_fsm_state(chip), reg_loop);
@@ -2911,7 +2788,8 @@
 			active_path, active_chg_plugged_in);
 	chg_gone = pm_chg_get_rt_status(chip, CHG_GONE_IRQ);
 
-	if (chg_gone == 1  && active_chg_plugged_in == 1) {
+	if (chg_gone == 1  && active_chg_plugged_in == 1 &&
+					!chip->disable_chg_rmvl_wrkarnd) {
 		pr_debug("chg_gone=%d, active_chg_plugged_in = %d\n",
 					chg_gone, active_chg_plugged_in);
 		unplug_ovp_fet_open(chip);
@@ -2920,10 +2798,13 @@
 	/* AICL only for usb wall charger */
 	if (!(reg_loop & VIN_ACTIVE_BIT) && (active_path & USB_ACTIVE_BIT)
 		&& usb_target_ma > 0
-		&& !charging_disabled) {
+		&& !charging_disabled
+		&& !chip->disable_aicl) {
 		/* only increase iusb_max if vin loop not active */
 		if (usb_ma < usb_target_ma) {
 			increase_usb_ma_value(&usb_ma);
+			if (usb_ma > usb_target_ma)
+				usb_ma = usb_target_ma;
 			__pm8921_charger_vbus_draw(usb_ma);
 			pr_debug("usb_now=%d, usb_target = %d\n",
 					usb_ma, usb_target_ma);
@@ -2970,8 +2851,8 @@
 {
 	int i = 0;
 
-	for (i = ARRAY_SIZE(ibatmax_adj_table) - 1; i >= 0; i--) {
-		if (ibat_target_ma <= ibatmax_adj_table[i].ibat_max_ma)
+	for (i = ARRAY_SIZE(ibatmax_adj_table); i > 0; i--) {
+		if (ibat_target_ma >= ibatmax_adj_table[i - 1].ibat_max_ma)
 			break;
 	}
 
@@ -3159,11 +3040,6 @@
 		else
 			handle_stop_ext_chg(chip);
 	} else {
-		if (chip->lockup_lpm_wrkarnd)
-			/* if no external supply call bypass debounce here */
-			pm8921_chg_bypass_bat_gone_debounce(chip,
-				is_chg_on_bat(chip));
-
 		if (dc_present)
 			schedule_delayed_work(&chip->unplug_check_work,
 				msecs_to_jiffies(UNPLUG_CHECK_WAIT_PERIOD_MS));
@@ -3233,7 +3109,6 @@
 	struct pm8921_chg_chip *chip = container_of(dwork,
 				struct pm8921_chg_chip, update_heartbeat_work);
 
-	pm_chg_failed_clear(chip, 1);
 	power_supply_changed(&chip->batt_psy);
 	if (chip->recent_reported_soc <= 20)
 		schedule_delayed_work(&chip->update_heartbeat_work,
@@ -3666,8 +3541,6 @@
 	int ichg_meas_ua, ichg_meas_ma;
 	int vbat_batt_terminal_uv;
 
-	pm_chg_failed_clear(chip, 1);
-
 	pm8921_bms_get_simultaneous_battery_voltage_and_current(
 					&ichg_meas_ua,	&vbat_meas_uv);
 	vbat_meas_mv = vbat_meas_uv / 1000;
@@ -3841,7 +3714,6 @@
 /* determines the initial present states */
 static void __devinit determine_initial_state(struct pm8921_chg_chip *chip)
 {
-	unsigned long flags;
 	int fsm_state;
 	int is_fast_chg;
 
@@ -3866,12 +3738,16 @@
 	pm8921_chg_enable_irq(chip, VBATDET_LOW_IRQ);
 	pm8921_chg_enable_irq(chip, BAT_TEMP_OK_IRQ);
 
-	spin_lock_irqsave(&vbus_lock, flags);
-	if (usb_chg_current) {
-		/* reissue a vbus draw call */
-		__pm8921_charger_vbus_draw(usb_chg_current);
-	}
-	spin_unlock_irqrestore(&vbus_lock, flags);
+	if (get_prop_batt_present(the_chip) || is_dc_chg_plugged_in(the_chip))
+		if (usb_chg_current)
+			/*
+			 * Reissue a vbus draw call only if a battery
+			 * or DC is present. We don't want to brown out the
+			 * device if usb is its only source
+			 */
+			__pm8921_charger_vbus_draw(usb_chg_current);
+	usb_chg_current = 0;
+
 	/*
 	 * The bootloader could have started charging, a fastchg interrupt
 	 * might not happen. Check the real time status and if it is fast
@@ -3995,6 +3871,91 @@
 	return -EINVAL;
 }
 
+static void pm8921_chg_force_19p2mhz_clk(struct pm8921_chg_chip *chip)
+{
+	int err;
+	u8 temp;
+
+	temp  = 0xD1;
+	err = pm_chg_write(chip, CHG_TEST, temp);
+	if (err) {
+		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
+		return;
+	}
+
+	temp  = 0xD3;
+	err = pm_chg_write(chip, CHG_TEST, temp);
+	if (err) {
+		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
+		return;
+	}
+
+	temp  = 0xD1;
+	err = pm_chg_write(chip, CHG_TEST, temp);
+	if (err) {
+		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
+		return;
+	}
+
+	temp  = 0xD5;
+	err = pm_chg_write(chip, CHG_TEST, temp);
+	if (err) {
+		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
+		return;
+	}
+
+	udelay(183);
+
+	temp  = 0xD1;
+	err = pm_chg_write(chip, CHG_TEST, temp);
+	if (err) {
+		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
+		return;
+	}
+
+	temp  = 0xD0;
+	err = pm_chg_write(chip, CHG_TEST, temp);
+	if (err) {
+		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
+		return;
+	}
+	udelay(32);
+
+	temp  = 0xD1;
+	err = pm_chg_write(chip, CHG_TEST, temp);
+	if (err) {
+		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
+		return;
+	}
+
+	temp  = 0xD3;
+	err = pm_chg_write(chip, CHG_TEST, temp);
+	if (err) {
+		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
+		return;
+	}
+}
+
+static void pm8921_chg_set_hw_clk_switching(struct pm8921_chg_chip *chip)
+{
+	int err;
+	u8 temp;
+
+	temp  = 0xD1;
+	err = pm_chg_write(chip, CHG_TEST, temp);
+	if (err) {
+		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
+		return;
+	}
+
+	temp  = 0xD0;
+	err = pm_chg_write(chip, CHG_TEST, temp);
+	if (err) {
+		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
+		return;
+	}
+}
+
 #define VREF_BATT_THERM_FORCE_ON	BIT(7)
 static void detect_battery_removal(struct pm8921_chg_chip *chip)
 {
@@ -4014,8 +3975,6 @@
 
 #define ENUM_TIMER_STOP_BIT	BIT(1)
 #define BOOT_DONE_BIT		BIT(6)
-#define BOOT_TIMER_EN_BIT	BIT(1)
-#define BOOT_DONE_MASK		(BOOT_DONE_BIT | BOOT_TIMER_EN_BIT)
 #define CHG_BATFET_ON_BIT	BIT(3)
 #define CHG_VCP_EN		BIT(0)
 #define CHG_BAT_TEMP_DIS_BIT	BIT(2)
@@ -4028,17 +3987,13 @@
 	u8 subrev;
 	int rc, vdd_safe, fcc_uah, safety_time = DEFAULT_SAFETY_MINUTES;
 
-	spin_lock_init(&lpm_lock);
-	rc = pm8921_apply_19p2mhz_kickstart(chip);
-	if (rc) {
-		pr_err("Failed to apply kickstart rc=%d\n", rc);
-		return rc;
-	}
+	/* forcing 19p2mhz before accessing any charger registers */
+	pm8921_chg_force_19p2mhz_clk(chip);
 
 	detect_battery_removal(chip);
 
 	rc = pm_chg_masked_write(chip, SYS_CONFIG_2,
-					BOOT_DONE_MASK, BOOT_DONE_MASK);
+					BOOT_DONE_BIT, BOOT_DONE_BIT);
 	if (rc) {
 		pr_err("Failed to set BOOT_DONE_BIT rc=%d\n", rc);
 		return rc;
@@ -4231,14 +4186,22 @@
 			return rc;
 		}
 		/* Check if die 3.0.1 is present */
-		if (subrev == 0x1)
+		if (subrev & 0x1)
 			pm_chg_write(chip, CHG_BUCK_CTRL_TEST3, 0xA4);
 		else
 			pm_chg_write(chip, CHG_BUCK_CTRL_TEST3, 0xAC);
 	}
 
-	/* Enable isub_fine resolution AICL for PM8917 */
 	if (pm8xxx_get_version(chip->dev->parent) == PM8XXX_VERSION_8917) {
+		/* Set PM8917 USB_OVP debounce time to 15 ms */
+		rc = pm_chg_masked_write(chip, USB_OVP_CONTROL,
+			OVP_DEBOUNCE_TIME, 0x6);
+		if (rc) {
+			pr_err("Failed to set USB OVP db rc=%d\n", rc);
+			return rc;
+		}
+
+		/* Enable isub_fine resolution AICL for PM8917 */
 		chip->iusb_fine_res = true;
 		if (chip->uvd_voltage_mv) {
 			rc = pm_chg_uvd_threshold_set(chip,
@@ -4273,45 +4236,6 @@
 		return rc;
 	}
 
-	if (pm8xxx_get_version(chip->dev->parent) == PM8XXX_VERSION_8921) {
-		/* Clear kickstart */
-		rc = pm8xxx_writeb(chip->dev->parent, CHG_TEST, 0xD0);
-		if (rc) {
-			pr_err("Failed to clear kickstart rc=%d\n", rc);
-			return rc;
-		}
-
-		/* From here the lpm_workaround will be active */
-		chip->lockup_lpm_wrkarnd = true;
-
-		/* Enable LPM */
-		pm8921_chg_set_lpm(chip, 1);
-	}
-
-	if (chip->lockup_lpm_wrkarnd) {
-		chip->vreg_xoadc = regulator_get(chip->dev, "vreg_xoadc");
-		if (IS_ERR(chip->vreg_xoadc))
-			return -ENODEV;
-
-		rc = regulator_set_optimum_mode(chip->vreg_xoadc, 10000);
-		if (rc < 0) {
-			pr_err("Failed to set configure HPM rc=%d\n", rc);
-			return rc;
-		}
-
-		rc = regulator_set_voltage(chip->vreg_xoadc, 1800000, 1800000);
-		if (rc) {
-			pr_err("Failed to set L14 voltage rc=%d\n", rc);
-			return rc;
-		}
-
-		rc = regulator_enable(chip->vreg_xoadc);
-		if (rc) {
-			pr_err("Failed to enable L14 rc=%d\n", rc);
-			return rc;
-		}
-	}
-
 	return 0;
 }
 
@@ -4562,19 +4486,16 @@
 	int rc;
 	struct pm8921_chg_chip *chip = dev_get_drvdata(dev);
 
-	if (chip->lockup_lpm_wrkarnd) {
-		rc = regulator_disable(chip->vreg_xoadc);
-		if (rc)
-			pr_err("Failed to disable L14 rc=%d\n", rc);
-
-		rc = pm8921_apply_19p2mhz_kickstart(chip);
-		if (rc)
-			pr_err("Failed to apply kickstart rc=%d\n", rc);
-	}
-
 	rc = pm_chg_masked_write(chip, CHG_CNTRL, VREF_BATT_THERM_FORCE_ON, 0);
 	if (rc)
 		pr_err("Failed to Force Vref therm off rc=%d\n", rc);
+
+	rc = pm8921_chg_set_lpm(chip, 1);
+	if (rc)
+		pr_err("Failed to set lpm rc=%d\n", rc);
+
+	pm8921_chg_set_hw_clk_switching(chip);
+
 	return 0;
 }
 
@@ -4583,15 +4504,11 @@
 	int rc;
 	struct pm8921_chg_chip *chip = dev_get_drvdata(dev);
 
-	if (chip->lockup_lpm_wrkarnd) {
-		rc = regulator_enable(chip->vreg_xoadc);
-		if (rc)
-			pr_err("Failed to enable L14 rc=%d\n", rc);
+	pm8921_chg_force_19p2mhz_clk(chip);
 
-		rc = pm8921_apply_19p2mhz_kickstart(chip);
-		if (rc)
-			pr_err("Failed to apply kickstart rc=%d\n", rc);
-	}
+	rc = pm8921_chg_set_lpm(chip, 0);
+	if (rc)
+		pr_err("Failed to set lpm rc=%d\n", rc);
 
 	rc = pm_chg_masked_write(chip, CHG_CNTRL, VREF_BATT_THERM_FORCE_ON,
 						VREF_BATT_THERM_FORCE_ON);
@@ -4608,6 +4525,11 @@
 		disable_irq_wake(chip->pmic_chg_irq[LOOP_CHANGE_IRQ]);
 		pm8921_chg_disable_irq(chip, LOOP_CHANGE_IRQ);
 	}
+
+	if (chip->btc_override && (is_dc_chg_plugged_in(the_chip) ||
+					is_usb_chg_plugged_in(the_chip)))
+		schedule_delayed_work(&chip->btc_override_work, 0);
+
 	return 0;
 }
 
@@ -4615,6 +4537,9 @@
 {
 	struct pm8921_chg_chip *chip = dev_get_drvdata(dev);
 
+	if (chip->btc_override)
+		cancel_delayed_work_sync(&chip->btc_override_work);
+
 	if (is_usb_chg_plugged_in(chip)) {
 		pm8921_chg_enable_irq(chip, LOOP_CHANGE_IRQ);
 		enable_irq_wake(chip->pmic_chg_irq[LOOP_CHANGE_IRQ]);
@@ -4683,6 +4608,7 @@
 	chip->vin_min = pdata->vin_min;
 	chip->thermal_mitigation = pdata->thermal_mitigation;
 	chip->thermal_levels = pdata->thermal_levels;
+	chip->disable_chg_rmvl_wrkarnd = pdata->disable_chg_rmvl_wrkarnd;
 
 	chip->cold_thr = pdata->cold_thr;
 	chip->hot_thr = pdata->hot_thr;
@@ -4716,29 +4642,33 @@
 	if (chip->btc_override)
 		pm8921_chg_btc_override_init(chip);
 
-	chip->usb_psy.name = "usb",
-	chip->usb_psy.type = POWER_SUPPLY_TYPE_USB,
-	chip->usb_psy.supplied_to = pm_power_supplied_to,
-	chip->usb_psy.num_supplicants = ARRAY_SIZE(pm_power_supplied_to),
-	chip->usb_psy.properties = pm_power_props_usb,
-	chip->usb_psy.num_properties = ARRAY_SIZE(pm_power_props_usb),
-	chip->usb_psy.get_property = pm_power_get_property_usb,
-	chip->usb_psy.set_property = pm_power_set_property_usb,
+	chip->stop_chg_upon_expiry = pdata->stop_chg_upon_expiry;
+	chip->usb_type = POWER_SUPPLY_TYPE_UNKNOWN;
 
-	chip->dc_psy.name = "pm8921-dc",
-	chip->dc_psy.type = POWER_SUPPLY_TYPE_MAINS,
-	chip->dc_psy.supplied_to = pm_power_supplied_to,
-	chip->dc_psy.num_supplicants = ARRAY_SIZE(pm_power_supplied_to),
-	chip->dc_psy.properties = pm_power_props_mains,
-	chip->dc_psy.num_properties = ARRAY_SIZE(pm_power_props_mains),
-	chip->dc_psy.get_property = pm_power_get_property_mains,
+	chip->usb_psy.name = "usb";
+	chip->usb_psy.type = POWER_SUPPLY_TYPE_USB;
+	chip->usb_psy.supplied_to = pm_power_supplied_to;
+	chip->usb_psy.num_supplicants = ARRAY_SIZE(pm_power_supplied_to);
+	chip->usb_psy.properties = pm_power_props_usb;
+	chip->usb_psy.num_properties = ARRAY_SIZE(pm_power_props_usb);
+	chip->usb_psy.get_property = pm_power_get_property_usb;
+	chip->usb_psy.set_property = pm_power_set_property_usb;
+	chip->usb_psy.property_is_writeable = usb_property_is_writeable;
 
-	chip->batt_psy.name = "battery",
-	chip->batt_psy.type = POWER_SUPPLY_TYPE_BATTERY,
-	chip->batt_psy.properties = msm_batt_power_props,
-	chip->batt_psy.num_properties = ARRAY_SIZE(msm_batt_power_props),
-	chip->batt_psy.get_property = pm_batt_power_get_property,
-	chip->batt_psy.external_power_changed = pm_batt_external_power_changed,
+	chip->dc_psy.name = "pm8921-dc";
+	chip->dc_psy.type = POWER_SUPPLY_TYPE_MAINS;
+	chip->dc_psy.supplied_to = pm_power_supplied_to;
+	chip->dc_psy.num_supplicants = ARRAY_SIZE(pm_power_supplied_to);
+	chip->dc_psy.properties = pm_power_props_mains;
+	chip->dc_psy.num_properties = ARRAY_SIZE(pm_power_props_mains);
+	chip->dc_psy.get_property = pm_power_get_property_mains;
+
+	chip->batt_psy.name = "battery";
+	chip->batt_psy.type = POWER_SUPPLY_TYPE_BATTERY;
+	chip->batt_psy.properties = msm_batt_power_props;
+	chip->batt_psy.num_properties = ARRAY_SIZE(msm_batt_power_props);
+	chip->batt_psy.get_property = pm_batt_power_get_property;
+	chip->batt_psy.external_power_changed = pm_batt_external_power_changed;
 	rc = power_supply_register(chip->dev, &chip->usb_psy);
 	if (rc < 0) {
 		pr_err("power_supply_register usb failed rc = %d\n", rc);
@@ -4810,7 +4740,6 @@
 {
 	struct pm8921_chg_chip *chip = platform_get_drvdata(pdev);
 
-	regulator_put(chip->vreg_xoadc);
 	free_irqs(chip);
 	platform_set_drvdata(pdev, NULL);
 	the_chip = NULL;
diff --git a/drivers/power/pm8xxx-ccadc.c b/drivers/power/pm8xxx-ccadc.c
index a586f3d8..7e37daa 100644
--- a/drivers/power/pm8xxx-ccadc.c
+++ b/drivers/power/pm8xxx-ccadc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -17,12 +17,15 @@
 #include <linux/platform_device.h>
 #include <linux/errno.h>
 #include <linux/mfd/pm8xxx/core.h>
+#include <linux/mfd/pm8xxx/pm8xxx-adc.h>
 #include <linux/mfd/pm8xxx/ccadc.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 #include <linux/ioport.h>
 #include <linux/debugfs.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/rtc.h>
 
 #define CCADC_ANA_PARAM		0x240
 #define CCADC_DIG_PARAM		0x241
@@ -67,13 +70,17 @@
 struct pm8xxx_ccadc_chip {
 	struct device		*dev;
 	struct dentry		*dent;
+	unsigned int		batt_temp_channel;
 	u16			ccadc_offset;
 	int			ccadc_gain_uv;
 	unsigned int		revision;
 	unsigned int		calib_delay_ms;
+	unsigned long		last_calib_time;
+	int			last_calib_temp;
 	int			eoc_irq;
 	int			r_sense_uohm;
 	struct delayed_work	calib_ccadc_work;
+	struct mutex		calib_mutex;
 };
 
 static struct pm8xxx_ccadc_chip *the_chip;
@@ -312,6 +319,54 @@
 	return 0;
 }
 
+static int get_batt_temp(struct pm8xxx_ccadc_chip *chip, int *batt_temp)
+{
+	int rc;
+	struct pm8xxx_adc_chan_result result;
+
+	rc = pm8xxx_adc_read(chip->batt_temp_channel, &result);
+	if (rc) {
+		pr_err("error reading batt_temp_channel = %d, rc = %d\n",
+					chip->batt_temp_channel, rc);
+		return rc;
+	}
+	*batt_temp = result.physical;
+	pr_debug("batt_temp phy = %lld meas = 0x%llx\n", result.physical,
+						result.measurement);
+	return 0;
+}
+
+static int get_current_time(unsigned long *now_tm_sec)
+{
+	struct rtc_time tm;
+	struct rtc_device *rtc;
+	int rc;
+
+	rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
+	if (rtc == NULL) {
+		pr_err("%s: unable to open rtc device (%s)\n",
+			__FILE__, CONFIG_RTC_HCTOSYS_DEVICE);
+		return -EINVAL;
+	}
+
+	rc = rtc_read_time(rtc, &tm);
+	if (rc) {
+		pr_err("Error reading rtc device (%s) : %d\n",
+			CONFIG_RTC_HCTOSYS_DEVICE, rc);
+		return rc;
+	}
+
+	rc = rtc_valid_tm(&tm);
+	if (rc) {
+		pr_err("Invalid RTC time (%s): %d\n",
+			CONFIG_RTC_HCTOSYS_DEVICE, rc);
+		return rc;
+	}
+	rtc_tm_to_time(&tm, now_tm_sec);
+
+	return 0;
+}
+
 void pm8xxx_calib_ccadc(void)
 {
 	u8 data_msb, data_lsb, sec_cntrl;
@@ -324,11 +379,12 @@
 		return;
 	}
 
+	mutex_lock(&the_chip->calib_mutex);
 	rc = pm8xxx_readb(the_chip->dev->parent,
 					ADC_ARB_SECP_CNTRL, &sec_cntrl);
 	if (rc < 0) {
 		pr_err("error = %d reading ADC_ARB_SECP_CNTRL\n", rc);
-		return;
+		goto calibration_unlock;
 	}
 
 	rc = calib_ccadc_enable_arbiter(the_chip);
@@ -460,6 +516,8 @@
 		pr_debug("error = %d programming gain trim\n", rc);
 bail:
 	pm8xxx_writeb(the_chip->dev->parent, ADC_ARB_SECP_CNTRL, sec_cntrl);
+calibration_unlock:
+	mutex_unlock(&the_chip->calib_mutex);
 }
 EXPORT_SYMBOL(pm8xxx_calib_ccadc);
 
@@ -678,10 +736,13 @@
 	chip->eoc_irq = res->start;
 	chip->r_sense_uohm = pdata->r_sense_uohm;
 	chip->calib_delay_ms = pdata->calib_delay_ms;
+	chip->batt_temp_channel = pdata->ccadc_cdata.batt_temp_channel;
+	mutex_init(&chip->calib_mutex);
 
 	calib_ccadc_read_offset_and_gain(chip,
 					&chip->ccadc_gain_uv,
 					&chip->ccadc_offset);
+	irq_set_status_flags(chip->eoc_irq, IRQ_NOAUTOEN);
 	rc = request_irq(chip->eoc_irq,
 			pm8921_bms_ccadc_eoc_handler, IRQF_TRIGGER_RISING,
 			"bms_eoc_ccadc", chip);
@@ -690,8 +751,6 @@
 		goto free_chip;
 	}
 
-	disable_irq_nosync(chip->eoc_irq);
-
 	platform_set_drvdata(pdev, chip);
 	the_chip = chip;
 	INIT_DELAYED_WORK(&chip->calib_ccadc_work, calibrate_ccadc_work);
@@ -702,6 +761,7 @@
 	return 0;
 
 free_chip:
+	mutex_destroy(&chip->calib_mutex);
 	kfree(chip);
 	return rc;
 }
@@ -716,12 +776,50 @@
 	return 0;
 }
 
+#define CCADC_CALIB_TEMP_THRESH 20
+static int pm8xxx_ccadc_resume(struct device *dev)
+{
+	int rc, batt_temp, delta_temp;
+	unsigned long current_time_sec;
+	unsigned long time_since_last_calib;
+
+	rc = get_batt_temp(the_chip, &batt_temp);
+	if (rc) {
+		pr_err("unable to get batt_temp: %d\n", rc);
+		return 0;
+	}
+	rc = get_current_time(&current_time_sec);
+	if (rc) {
+		pr_err("unable to get current time: %d\n", rc);
+		return 0;
+	}
+	if (current_time_sec > the_chip->last_calib_time) {
+		time_since_last_calib = current_time_sec -
+					the_chip->last_calib_time;
+		delta_temp = abs(batt_temp - the_chip->last_calib_temp);
+		pr_debug("time since last calib: %lu, delta_temp = %d\n",
+					time_since_last_calib, delta_temp);
+		if (time_since_last_calib >= the_chip->calib_delay_ms/1000
+				|| delta_temp > CCADC_CALIB_TEMP_THRESH) {
+			the_chip->last_calib_time = current_time_sec;
+			the_chip->last_calib_temp = batt_temp;
+			pm8xxx_calib_ccadc();
+		}
+	}
+	return 0;
+}
+
+static const struct dev_pm_ops pm8xxx_ccadc_pm_ops = {
+	.resume		= pm8xxx_ccadc_resume,
+};
+
 static struct platform_driver pm8xxx_ccadc_driver = {
 	.probe	= pm8xxx_ccadc_probe,
 	.remove	= __devexit_p(pm8xxx_ccadc_remove),
 	.driver	= {
 		.name	= PM8XXX_CCADC_DEV_NAME,
 		.owner	= THIS_MODULE,
+		.pm	= &pm8xxx_ccadc_pm_ops,
 	},
 };
 
diff --git a/drivers/power/pmic8058-charger.c b/drivers/power/pmic8058-charger.c
index 70b5d59..36270cf 100644
--- a/drivers/power/pmic8058-charger.c
+++ b/drivers/power/pmic8058-charger.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
index 7eb285b..63fb0a5 100644
--- a/drivers/power/power_supply_sysfs.c
+++ b/drivers/power/power_supply_sysfs.c
@@ -175,6 +175,7 @@
 	POWER_SUPPLY_ATTR(time_to_full_avg),
 	POWER_SUPPLY_ATTR(type),
 	POWER_SUPPLY_ATTR(scope),
+	POWER_SUPPLY_ATTR(system_temp_level),
 	/* Properties of type `const char *' */
 	POWER_SUPPLY_ATTR(model_name),
 	POWER_SUPPLY_ATTR(manufacturer),
diff --git a/drivers/power/qpnp-bms.c b/drivers/power/qpnp-bms.c
index 51e4465..ec0b0e7 100644
--- a/drivers/power/qpnp-bms.c
+++ b/drivers/power/qpnp-bms.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -34,6 +34,8 @@
 /* Coulomb counter clear registers */
 #define BMS1_CC_DATA_CTL		0x42
 #define BMS1_CC_CLEAR_CTL		0x43
+/* BMS Tolerances */
+#define BMS1_TOL_CTL			0X44
 /* OCV limit registers */
 #define BMS1_OCV_USE_LOW_LIMIT_THR0	0x48
 #define BMS1_OCV_USE_LOW_LIMIT_THR1	0x49
@@ -89,10 +91,11 @@
 struct soc_params {
 	int		fcc_uah;
 	int		cc_uah;
-	int		rbatt;
+	int		rbatt_mohm;
 	int		iavg_ua;
 	int		uuc_uah;
 	int		ocv_charge_uah;
+	int		delta_time_s;
 };
 
 struct raw_soc_params {
@@ -114,10 +117,10 @@
 	int				charger_status;
 	bool				online;
 	/* platform data */
-	unsigned int			r_sense_mohm;
+	int				r_sense_uohm;
 	unsigned int			v_cutoff_uv;
-	unsigned int			max_voltage_uv;
-	unsigned int			r_conn_mohm;
+	int				max_voltage_uv;
+	int				r_conn_mohm;
 	int				shutdown_soc_valid_limit;
 	int				adjust_soc_low_threshold;
 	int				adjust_soc_high_threshold;
@@ -138,9 +141,8 @@
 	struct mutex			soc_invalidation_mutex;
 
 	bool				use_external_rsense;
+	bool				use_ocv_thresholds;
 
-	unsigned int			start_percent;
-	unsigned int			end_percent;
 	bool				ignore_shutdown_soc;
 	int				shutdown_soc_invalid;
 	int				shutdown_soc;
@@ -149,11 +151,13 @@
 	int				low_soc_calc_threshold;
 	int				low_soc_calculate_soc_ms;
 	int				calculate_soc_ms;
+	struct wake_lock		soc_wake_lock;
 
 	uint16_t			ocv_reading_at_100;
 	int64_t				cc_reading_at_100;
 	uint16_t			prev_last_good_ocv_raw;
 	int				last_ocv_uv;
+	int				last_ocv_temp;
 	int				last_cc_uah;
 	unsigned long			tm_sec;
 	bool				first_time_calc_soc;
@@ -174,6 +178,7 @@
 	unsigned int			vadc_v0625;
 	unsigned int			vadc_v1250;
 
+	int				ibat_max_ua;
 	int				prev_iavg_ua;
 	int				prev_uuc_iavg_ma;
 	int				prev_pc_unusable;
@@ -183,6 +188,10 @@
 	int				calculated_soc;
 	int				prev_voltage_based_soc;
 	bool				use_voltage_soc;
+
+	int				ocv_high_threshold_uv;
+	int				ocv_low_threshold_uv;
+	unsigned long			last_recalc_time;
 };
 
 static struct of_device_id qpnp_bms_match_table[] = {
@@ -199,9 +208,11 @@
 	POWER_SUPPLY_PROP_ONLINE,
 	POWER_SUPPLY_PROP_CAPACITY,
 	POWER_SUPPLY_PROP_CURRENT_NOW,
+	POWER_SUPPLY_PROP_CURRENT_MAX,
 	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
 };
 
+static bool bms_reset;
 
 static int qpnp_read_wrapper(struct qpnp_bms_chip *chip, u8 *val,
 			u16 base, int count)
@@ -295,7 +306,7 @@
 #define V_PER_BIT_DIV_FACTOR	1000
 #define VADC_INTRINSIC_OFFSET	0x6000
 
-static int vadc_reading_to_uv(unsigned int reading)
+static int vadc_reading_to_uv(int reading)
 {
 	if (reading <= VADC_INTRINSIC_OFFSET)
 		return 0;
@@ -307,8 +318,7 @@
 #define VADC_CALIB_UV		625000
 #define VBATT_MUL_FACTOR	3
 
-static int adjust_vbatt_reading(struct qpnp_bms_chip *chip,
-						unsigned int reading_uv)
+static int adjust_vbatt_reading(struct qpnp_bms_chip *chip, int reading_uv)
 {
 	s64 numerator, denominator;
 
@@ -330,6 +340,17 @@
 						* VBATT_MUL_FACTOR;
 }
 
+static int convert_vbatt_uv_to_raw(struct qpnp_bms_chip *chip,
+					int unadjusted_vbatt)
+{
+	int scaled_vbatt = unadjusted_vbatt / VBATT_MUL_FACTOR;
+
+	if (scaled_vbatt <= 0)
+		return VADC_INTRINSIC_OFFSET;
+	return ((scaled_vbatt * V_PER_BIT_DIV_FACTOR) / V_PER_BIT_MUL_FACTOR)
+						+ VADC_INTRINSIC_OFFSET;
+}
+
 static inline int convert_vbatt_raw_to_uv(struct qpnp_bms_chip *chip,
 					uint16_t reading)
 {
@@ -350,7 +371,7 @@
 					CC_READING_RESOLUTION_D);
 }
 
-#define QPNP_ADC_GAIN_NV				17857LL
+#define QPNP_ADC_GAIN_IDEAL				3291LL
 static s64 cc_adjust_for_gain(s64 uv, uint16_t gain)
 {
 	s64 result_uv;
@@ -361,10 +382,10 @@
 		return uv;
 	}
 	pr_debug("adjusting by factor: %lld/%hu = %lld%%\n",
-			QPNP_ADC_GAIN_NV, gain,
-			div_s64(QPNP_ADC_GAIN_NV * 100LL, (s64)gain));
+			QPNP_ADC_GAIN_IDEAL, gain,
+			div_s64(QPNP_ADC_GAIN_IDEAL * 100LL, (s64)gain));
 
-	result_uv = div_s64(uv * QPNP_ADC_GAIN_NV, (s64)gain);
+	result_uv = div_s64(uv * QPNP_ADC_GAIN_IDEAL, (s64)gain);
 	pr_debug("result_uv = %lld\n", result_uv);
 	return result_uv;
 }
@@ -376,7 +397,7 @@
 
 	qpnp_iadc_get_gain_and_offset(&calibration);
 	return cc_adjust_for_gain(cc_reading_to_uv(reading),
-			calibration.gain_raw);
+			calibration.gain_raw - calibration.offset_raw);
 }
 
 static int read_vsense_avg(struct qpnp_bms_chip *chip, int *result_uv)
@@ -400,7 +421,7 @@
 {
 	int vsense_uv = 0;
 
-	if (chip->r_sense_mohm == 0) {
+	if (chip->r_sense_uohm == 0) {
 		pr_err("r_sense is zero\n");
 		return -EINVAL;
 	}
@@ -413,7 +434,7 @@
 
 	pr_debug("vsense_uv=%duV\n", vsense_uv);
 	/* cast for signed division */
-	*result_ua = vsense_uv * 1000 / (int)chip->r_sense_mohm;
+	*result_ua = div_s64((vsense_uv * 1000000LL), (int)chip->r_sense_uohm);
 	pr_debug("ibat=%duA\n", *result_ua);
 	return 0;
 }
@@ -483,7 +504,8 @@
 }
 
 static void convert_and_store_ocv(struct qpnp_bms_chip *chip,
-				struct raw_soc_params *raw)
+				struct raw_soc_params *raw,
+				int batt_temp)
 {
 	int rc;
 
@@ -497,6 +519,7 @@
 	raw->last_good_ocv_uv = convert_vbatt_raw_to_uv(chip,
 					raw->last_good_ocv_raw);
 	chip->last_ocv_uv = raw->last_good_ocv_uv;
+	chip->last_ocv_temp = batt_temp;
 	pr_debug("last_good_ocv_uv = %d\n", raw->last_good_ocv_uv);
 }
 
@@ -528,14 +551,16 @@
 		pr_err("cc reenable failed: %d\n", rc);
 }
 
+#define OCV_RAW_UNINITIALIZED	0xFFFF
 static int read_soc_params_raw(struct qpnp_bms_chip *chip,
-				struct raw_soc_params *raw)
+				struct raw_soc_params *raw,
+				int batt_temp)
 {
 	int rc;
 
 	mutex_lock(&chip->bms_output_lock);
 
-	if (chip->prev_last_good_ocv_raw == 0) {
+	if (chip->prev_last_good_ocv_raw == OCV_RAW_UNINITIALIZED) {
 		/* software workaround for BMS 1.0
 		 * The coulomb counter does not reset upon PON, so reset it
 		 * manually upon probe. */
@@ -561,20 +586,20 @@
 	unlock_output_data(chip);
 	mutex_unlock(&chip->bms_output_lock);
 
-	if (chip->prev_last_good_ocv_raw == 0) {
-		convert_and_store_ocv(chip, raw);
+	if (chip->prev_last_good_ocv_raw == OCV_RAW_UNINITIALIZED) {
+		convert_and_store_ocv(chip, raw, batt_temp);
 		pr_debug("PON_OCV_UV = %d\n", chip->last_ocv_uv);
 	} else if (chip->prev_last_good_ocv_raw != raw->last_good_ocv_raw) {
-		convert_and_store_ocv(chip, raw);
+		convert_and_store_ocv(chip, raw, batt_temp);
 		/* forget the old cc value upon ocv */
-		chip->last_cc_uah = 0;
+		chip->last_cc_uah = INT_MIN;
 	} else {
 		raw->last_good_ocv_uv = chip->last_ocv_uv;
 	}
 
 	/* fake a high OCV if done charging */
 	if (chip->ocv_reading_at_100 != raw->last_good_ocv_raw) {
-		chip->ocv_reading_at_100 = 0;
+		chip->ocv_reading_at_100 = OCV_RAW_UNINITIALIZED;
 		chip->cc_reading_at_100 = 0;
 	} else {
 		/*
@@ -583,6 +608,7 @@
 		 */
 		raw->last_good_ocv_uv = chip->max_voltage_uv;
 		chip->last_ocv_uv = chip->max_voltage_uv;
+		chip->last_ocv_temp = batt_temp;
 	}
 	pr_debug("last_good_ocv_raw= 0x%x, last_good_ocv_uv= %duV\n",
 			raw->last_good_ocv_raw, raw->last_good_ocv_uv);
@@ -622,13 +648,12 @@
 /* calculate remaining charge at the time of ocv */
 static int calculate_ocv_charge(struct qpnp_bms_chip *chip,
 						struct raw_soc_params *raw,
-						int fcc_uah,
-						int batt_temp)
+						int fcc_uah)
 {
 	int  ocv_uv, pc;
 
 	ocv_uv = raw->last_good_ocv_uv;
-	pc = calculate_pc(chip, ocv_uv, batt_temp);
+	pc = calculate_pc(chip, ocv_uv, chip->last_ocv_temp);
 	pr_debug("ocv_uv = %d pc = %d\n", ocv_uv, pc);
 	return (fcc_uah * pc) / 100;
 }
@@ -645,10 +670,18 @@
 #define SLEEP_CLK_HZ		32764
 #define SECONDS_PER_HOUR	3600
 
-static s64 cc_uv_to_nvh(s64 cc_uv)
+static s64 cc_uv_to_pvh(s64 cc_uv)
 {
-	return div_s64(cc_uv * CC_READING_TICKS * 1000,
-			SLEEP_CLK_HZ * SECONDS_PER_HOUR);
+	/* Note that it is necessary need to multiply by 1000000 to convert
+	 * from uvh to pvh here.
+	 * However, the maximum Coulomb Counter value is 2^35, which can cause
+	 * an over flow.
+	 * Multiply by 100000 first to perserve as much precision as possible
+	 * then multiply by 10 after doing the division in order to avoid
+	 * overflow on the maximum Coulomb Counter value.
+	 */
+	return div_s64(cc_uv * CC_READING_TICKS * 100000,
+			SLEEP_CLK_HZ * SECONDS_PER_HOUR) * 10;
 }
 
 /**
@@ -663,7 +696,7 @@
  */
 static int calculate_cc(struct qpnp_bms_chip *chip, int64_t cc)
 {
-	int64_t cc_voltage_uv, cc_nvh, cc_uah;
+	int64_t cc_voltage_uv, cc_pvh, cc_uah;
 	struct qpnp_iadc_calib calibration;
 
 	qpnp_iadc_get_gain_and_offset(&calibration);
@@ -673,11 +706,13 @@
 					cc, chip->cc_reading_at_100,
 					cc_voltage_uv);
 	cc_voltage_uv = cc_to_uv(cc_voltage_uv);
-	cc_voltage_uv = cc_adjust_for_gain(cc_voltage_uv, calibration.gain_raw);
+	cc_voltage_uv = cc_adjust_for_gain(cc_voltage_uv,
+					calibration.gain_raw
+					- calibration.offset_raw);
 	pr_debug("cc_voltage_uv = %lld uv\n", cc_voltage_uv);
-	cc_nvh = cc_uv_to_nvh(cc_voltage_uv);
-	pr_debug("cc_nvh = %lld nano_volt_hour\n", cc_nvh);
-	cc_uah = div_s64(cc_nvh, chip->r_sense_mohm);
+	cc_pvh = cc_uv_to_pvh(cc_voltage_uv);
+	pr_debug("cc_pvh = %lld pvh\n", cc_pvh);
+	cc_uah = div_s64(cc_pvh, chip->r_sense_uohm);
 	/* cc_raw had 4 bits of extra precision.
 	   By now it should be within 32 bit range */
 	return (int)cc_uah;
@@ -711,46 +746,18 @@
 }
 
 static void calculate_iavg(struct qpnp_bms_chip *chip, int cc_uah,
-				int *iavg_ua)
+				int *iavg_ua, int delta_time_s)
 {
-	int delta_cc_uah, delta_time_s, rc;
-	struct rtc_time tm;
-	struct rtc_device *rtc;
-	unsigned long now_tm_sec = 0;
+	int delta_cc_uah = 0;
 
-	rc = 0;
 	/* if anything fails report the previous iavg_ua */
 	*iavg_ua = chip->prev_iavg_ua;
 
-	rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
-	if (rtc == NULL) {
-		pr_err("%s: unable to open rtc device (%s)\n",
-			__FILE__, CONFIG_RTC_HCTOSYS_DEVICE);
-		goto out;
-	}
-
-	rc = rtc_read_time(rtc, &tm);
-	if (rc) {
-		pr_err("Error reading rtc device (%s) : %d\n",
-			CONFIG_RTC_HCTOSYS_DEVICE, rc);
-		goto out;
-	}
-
-	rc = rtc_valid_tm(&tm);
-	if (rc) {
-		pr_err("Invalid RTC time (%s): %d\n",
-			CONFIG_RTC_HCTOSYS_DEVICE, rc);
-		goto out;
-	}
-	rtc_tm_to_time(&tm, &now_tm_sec);
-
-	if (chip->tm_sec == 0) {
+	if (chip->last_cc_uah == INT_MIN) {
 		get_battery_current(chip, iavg_ua);
 		goto out;
 	}
 
-	delta_time_s = (now_tm_sec - chip->tm_sec);
-
 	/* use the previous iavg if called within 15 seconds */
 	if (delta_time_s < 15) {
 		*iavg_ua = chip->prev_iavg_ua;
@@ -761,19 +768,13 @@
 
 	*iavg_ua = div_s64((s64)delta_cc_uah * 3600, delta_time_s);
 
-	pr_debug("tm_sec = %ld, now_tm_sec = %ld delta_s = %d delta_cc = %d iavg_ua = %d\n",
-				chip->tm_sec, now_tm_sec,
-				delta_time_s, delta_cc_uah, (int)*iavg_ua);
-
 out:
+	pr_debug("delta_cc = %d iavg_ua = %d\n", delta_cc_uah, (int)*iavg_ua);
 	/* remember the iavg */
 	chip->prev_iavg_ua = *iavg_ua;
 
 	/* remember cc_uah */
 	chip->last_cc_uah = cc_uah;
-
-	/* remember this time */
-	chip->tm_sec = now_tm_sec;
 }
 
 static int calculate_termination_uuc(struct qpnp_bms_chip *chip,
@@ -825,6 +826,7 @@
 	return uuc_uah;
 }
 
+#define TIME_PER_PERCENT_UUC			60
 static int adjust_uuc(struct qpnp_bms_chip *chip,
 			struct soc_params *params,
 			int new_pc_unusable,
@@ -833,18 +835,23 @@
 {
 	int new_unusable_mv, new_iavg_ma;
 	int batt_temp_degc = batt_temp / 10;
+	int max_percent_change;
+
+	max_percent_change = max(params->delta_time_s
+				/ TIME_PER_PERCENT_UUC, 1);
 
 	if (chip->prev_pc_unusable == -EINVAL
-		|| abs(chip->prev_pc_unusable - new_pc_unusable) <= 1) {
+		|| abs(chip->prev_pc_unusable - new_pc_unusable)
+			<= max_percent_change) {
 		chip->prev_pc_unusable = new_pc_unusable;
 		return new_uuc_uah;
 	}
 
 	/* the uuc is trying to change more than 1% restrict it */
 	if (new_pc_unusable > chip->prev_pc_unusable)
-		chip->prev_pc_unusable++;
+		chip->prev_pc_unusable += max_percent_change;
 	else
-		chip->prev_pc_unusable--;
+		chip->prev_pc_unusable -= max_percent_change;
 
 	new_uuc_uah = (params->fcc_uah * chip->prev_pc_unusable) / 100;
 
@@ -855,7 +862,7 @@
 		new_unusable_mv = chip->v_cutoff_uv/1000;
 
 	new_iavg_ma = (new_unusable_mv * 1000 - chip->v_cutoff_uv)
-						/ params->rbatt;
+						/ params->rbatt_mohm;
 	if (new_iavg_ma == 0)
 		new_iavg_ma = 1;
 	chip->prev_uuc_iavg_ma = new_iavg_ma;
@@ -866,7 +873,7 @@
 	return new_uuc_uah;
 }
 
-#define CHARGING_IAVG_MA 250
+#define MIN_IAVG_MA 250
 #define MIN_SECONDS_FOR_VALID_SAMPLE	20
 static int calculate_unusable_charge_uah(struct qpnp_bms_chip *chip,
 					struct soc_params *params,
@@ -895,8 +902,8 @@
 	 * if charging use a nominal avg current to keep
 	 * a reasonable UUC while charging
 	 */
-	if (uuc_iavg_ma < 0)
-		uuc_iavg_ma = CHARGING_IAVG_MA;
+	if (uuc_iavg_ma < MIN_IAVG_MA)
+		uuc_iavg_ma = MIN_IAVG_MA;
 	chip->iavg_samples_ma[chip->iavg_index] = uuc_iavg_ma;
 	chip->iavg_index = (chip->iavg_index + 1) % IAVG_SAMPLES;
 	chip->iavg_num_samples++;
@@ -916,8 +923,14 @@
 						chip->iavg_num_samples);
 	}
 
-	uuc_uah_iavg = calculate_termination_uuc(chip, params, uuc_iavg_ma,
-						batt_temp, &pc_unusable);
+	/*
+	 * if we're in bms reset mode, force uuc to be 3% of fcc
+	 */
+	if (bms_reset)
+		return (params->fcc_uah * 3) / 100;
+
+	uuc_uah_iavg = calculate_termination_uuc(chip, params, batt_temp,
+						uuc_iavg_ma, &pc_unusable);
 	pr_debug("uuc_iavg_ma = %d uuc with iavg = %d\n",
 						uuc_iavg_ma, uuc_uah_iavg);
 
@@ -974,6 +987,58 @@
 	params->ocv_charge_uah = (int)ocv_charge_uah;
 }
 
+static int get_current_time(unsigned long *now_tm_sec)
+{
+	struct rtc_time tm;
+	struct rtc_device *rtc;
+	int rc;
+
+	rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
+	if (rtc == NULL) {
+		pr_err("%s: unable to open rtc device (%s)\n",
+			__FILE__, CONFIG_RTC_HCTOSYS_DEVICE);
+		rc = -EINVAL;
+		goto close_time;
+	}
+
+	rc = rtc_read_time(rtc, &tm);
+	if (rc) {
+		pr_err("Error reading rtc device (%s) : %d\n",
+			CONFIG_RTC_HCTOSYS_DEVICE, rc);
+		goto close_time;
+	}
+
+	rc = rtc_valid_tm(&tm);
+	if (rc) {
+		pr_err("Invalid RTC time (%s): %d\n",
+			CONFIG_RTC_HCTOSYS_DEVICE, rc);
+		goto close_time;
+	}
+	rtc_tm_to_time(&tm, now_tm_sec);
+
+close_time:
+	rtc_class_close(rtc);
+	return rc;
+}
+
+static int calculate_delta_time(struct qpnp_bms_chip *chip, int *delta_time_s)
+{
+	unsigned long now_tm_sec = 0;
+
+	/* default to delta time = 0 if anything fails */
+	*delta_time_s = 0;
+
+	get_current_time(&now_tm_sec);
+
+	*delta_time_s = (now_tm_sec - chip->tm_sec);
+	pr_debug("tm_sec = %ld, now_tm_sec = %ld delta_s = %d\n",
+		chip->tm_sec, now_tm_sec, *delta_time_s);
+
+	/* remember this time */
+	chip->tm_sec = now_tm_sec;
+	return 0;
+}
+
 static void calculate_soc_params(struct qpnp_bms_chip *chip,
 						struct raw_soc_params *raw,
 						struct soc_params *params,
@@ -981,14 +1046,14 @@
 {
 	int soc_rbatt;
 
+	calculate_delta_time(chip, &params->delta_time_s);
 	params->fcc_uah = calculate_fcc(chip, batt_temp);
 	pr_debug("FCC = %uuAh batt_temp = %d\n", params->fcc_uah, batt_temp);
 
 	/* calculate remainging charge */
 	params->ocv_charge_uah = calculate_ocv_charge(
 						chip, raw,
-						params->fcc_uah,
-						batt_temp);
+						params->fcc_uah);
 	pr_debug("ocv_charge_uah = %uuAh\n", params->ocv_charge_uah);
 
 	/* calculate cc micro_volt_hour */
@@ -1002,9 +1067,10 @@
 							/ params->fcc_uah;
 	if (soc_rbatt < 0)
 		soc_rbatt = 0;
-	params->rbatt = get_rbatt(chip, soc_rbatt, batt_temp);
+	params->rbatt_mohm = get_rbatt(chip, soc_rbatt, batt_temp);
 
-	calculate_iavg(chip, params->cc_uah, &params->iavg_ua);
+	calculate_iavg(chip, params->cc_uah, &params->iavg_ua,
+						params->delta_time_s);
 
 	params->uuc_uah = calculate_unusable_charge_uah(chip, params,
 							batt_temp);
@@ -1029,58 +1095,22 @@
 	return 1;
 }
 
-#define BMS_OVERRIDE_MODE_EN_BIT	BIT(7)
-#define EN_VBAT_BIT			BIT(0)
-#define OVERRIDE_MODE_DELAY_MS		20
-static int override_mode_batt_v_and_i(
-		struct qpnp_bms_chip *chip, int *ibat_ua, int *vbat_uv)
+static bool is_battery_charging(struct qpnp_bms_chip *chip)
 {
-	int16_t vsense_raw, vbat_raw;
-	int vsense_uv, rc;
-	u8 delay;
+	union power_supply_propval ret = {0,};
 
-	mutex_lock(&chip->bms_output_lock);
+	if (chip->batt_psy == NULL)
+		chip->batt_psy = power_supply_get_by_name("battery");
+	if (chip->batt_psy) {
+		/* if battery has been registered, use the status property */
+		chip->batt_psy->get_property(chip->batt_psy,
+					POWER_SUPPLY_PROP_STATUS, &ret);
+		return ret.intval == POWER_SUPPLY_STATUS_CHARGING;
+	}
 
-	delay = 0x00;
-	rc = qpnp_write_wrapper(chip, &delay,
-			chip->base + BMS1_S1_DELAY_CTL, 1);
-	if (rc)
-		pr_err("unable to write into BMS1_S1_DELAY, rc: %d\n", rc);
-
-	rc = qpnp_masked_write(chip, BMS1_MODE_CTL,
-			BMS_OVERRIDE_MODE_EN_BIT | EN_VBAT_BIT,
-			BMS_OVERRIDE_MODE_EN_BIT | EN_VBAT_BIT);
-	if (rc)
-		pr_err("unable to write into BMS1_MODE_CTL, rc: %d\n", rc);
-
-	msleep(OVERRIDE_MODE_DELAY_MS);
-
-	lock_output_data(chip);
-	qpnp_read_wrapper(chip, (u8 *)&vsense_raw,
-			chip->base + BMS1_VSENSE_AVG_DATA0, 2);
-	qpnp_read_wrapper(chip, (u8 *)&vbat_raw,
-			chip->base + BMS1_VBAT_AVG_DATA0, 2);
-	unlock_output_data(chip);
-
-	rc = qpnp_masked_write(chip, BMS1_MODE_CTL,
-			BMS_OVERRIDE_MODE_EN_BIT | EN_VBAT_BIT, 0);
-
-	delay = 0x0B;
-	rc = qpnp_write_wrapper(chip, &delay,
-			chip->base + BMS1_S1_DELAY_CTL, 1);
-	if (rc)
-		pr_err("unable to write into BMS1_S1_DELAY, rc: %d\n", rc);
-
-	mutex_unlock(&chip->bms_output_lock);
-
-	*vbat_uv = convert_vbatt_raw_to_uv(chip, vbat_raw);
-	vsense_uv = convert_vsense_to_uv(chip, vsense_raw);
-	*ibat_ua = vsense_uv * 1000 / (int)chip->r_sense_mohm;
-
-	pr_debug("vsense_raw = 0x%x vbat_raw = 0x%x ibat_ua = %d vbat_uv = %d\n",
-			(uint16_t)vsense_raw, (uint16_t)vbat_raw,
-			*ibat_ua, *vbat_uv);
-	return 0;
+	/* Default to false if the battery power supply is not registered. */
+	pr_debug("battery power supply is not registered\n");
+	return false;
 }
 
 static bool is_batfet_open(struct qpnp_bms_chip *chip)
@@ -1104,23 +1134,21 @@
 static int get_simultaneous_batt_v_and_i(struct qpnp_bms_chip *chip,
 					int *ibat_ua, int *vbat_uv)
 {
+	struct qpnp_iadc_result i_result;
+	struct qpnp_vadc_result v_result;
+	enum qpnp_iadc_channels iadc_channel;
 	int rc;
 
-	if (is_batfet_open(chip)) {
-		pr_debug("batfet is open using separate vbat and ibat meas\n");
-		rc = get_battery_voltage(vbat_uv);
-		if (rc < 0) {
-			pr_err("adc vbat failed err = %d\n", rc);
-			return rc;
-		}
-		rc = get_battery_current(chip, ibat_ua);
-		if (rc < 0) {
-			pr_err("bms ibat failed err = %d\n", rc);
-			return rc;
-		}
-	} else {
-		return override_mode_batt_v_and_i(chip, ibat_ua, vbat_uv);
+	iadc_channel = chip->use_external_rsense ?
+				EXTERNAL_RSENSE : INTERNAL_RSENSE;
+	rc = qpnp_iadc_vadc_sync_read(iadc_channel, &i_result,
+				VBAT_SNS, &v_result);
+	if (rc) {
+		pr_err("vadc read failed with rc: %d\n", rc);
+		return rc;
 	}
+	*ibat_ua = (int)i_result.result_ua;
+	*vbat_uv = (int)v_result.physical;
 
 	return 0;
 }
@@ -1132,19 +1160,90 @@
 	return soc;
 }
 
+#define IBAT_TOL_MASK		0x0F
+#define OCV_TOL_MASK		0xF0
+#define IBAT_TOL_DEFAULT	0x03
+#define IBAT_TOL_NOCHG		0x0F
+#define OCV_TOL_DEFAULT		0x20
+#define OCV_TOL_NO_OCV		0x00
+static int stop_ocv_updates(struct qpnp_bms_chip *chip)
+{
+	pr_debug("stopping ocv updates\n");
+	return qpnp_masked_write(chip, BMS1_TOL_CTL,
+			OCV_TOL_MASK, OCV_TOL_NO_OCV);
+}
+
+static int reset_bms_for_test(struct qpnp_bms_chip *chip)
+{
+	int ibat_ua = 0, vbat_uv = 0, rc;
+	int ocv_est_uv;
+
+	if (!chip) {
+		pr_err("BMS driver has not been initialized yet!\n");
+		return -EINVAL;
+	}
+
+	rc = get_simultaneous_batt_v_and_i(chip, &ibat_ua, &vbat_uv);
+
+	ocv_est_uv = vbat_uv + (ibat_ua * chip->r_conn_mohm) / 1000;
+	pr_debug("forcing ocv to be %d due to bms reset mode\n", ocv_est_uv);
+	chip->last_ocv_uv = ocv_est_uv;
+	chip->last_soc = -EINVAL;
+	reset_cc(chip);
+	chip->last_cc_uah = INT_MIN;
+	stop_ocv_updates(chip);
+
+	pr_debug("bms reset to ocv = %duv vbat_ua = %d ibat_ua = %d\n",
+			chip->last_ocv_uv, vbat_uv, ibat_ua);
+
+	return rc;
+}
+
+static int bms_reset_set(const char *val, const struct kernel_param *kp)
+{
+	int rc;
+
+	rc = param_set_bool(val, kp);
+	if (rc) {
+		pr_err("Unable to set bms_reset: %d\n", rc);
+		return rc;
+	}
+
+	if (*(bool *)kp->arg) {
+		struct power_supply *bms_psy = power_supply_get_by_name("bms");
+		struct qpnp_bms_chip *chip = container_of(bms_psy,
+					struct qpnp_bms_chip, bms_psy);
+
+		rc = reset_bms_for_test(chip);
+		if (rc) {
+			pr_err("Unable to modify bms_reset: %d\n", rc);
+			return rc;
+		}
+	}
+	return 0;
+}
+
+static struct kernel_param_ops bms_reset_ops = {
+	.set = bms_reset_set,
+	.get = param_get_bool,
+};
+
+module_param_cb(bms_reset, &bms_reset_ops, &bms_reset, 0644);
+
 static int charging_adjustments(struct qpnp_bms_chip *chip,
 				struct soc_params *params, int soc,
 				int vbat_uv, int ibat_ua, int batt_temp)
 {
 	int chg_soc;
+	int batt_terminal_uv = vbat_uv + (ibat_ua * chip->r_conn_mohm) / 1000;
 
 	if (chip->soc_at_cv == -EINVAL) {
 		/* In constant current charging return the calc soc */
-		if (vbat_uv <= chip->max_voltage_uv)
+		if (batt_terminal_uv <= chip->max_voltage_uv)
 			pr_debug("CC CHG SOC %d\n", soc);
 
 		/* Note the CC to CV point */
-		if (vbat_uv >= chip->max_voltage_uv) {
+		if (batt_terminal_uv >= chip->max_voltage_uv) {
 			chip->soc_at_cv = soc;
 			chip->prev_chg_soc = soc;
 			chip->ibat_at_cv_ua = ibat_ua;
@@ -1163,15 +1262,17 @@
 	 * if voltage lessened (possibly because of a system load)
 	 * keep reporting the prev chg soc
 	 */
-	if (vbat_uv <= chip->max_voltage_uv) {
-		pr_debug("vbat %d < max = %d CC CHG SOC %d\n",
-			vbat_uv, chip->max_voltage_uv, chip->prev_chg_soc);
+	if (batt_terminal_uv <= chip->max_voltage_uv - 10000) {
+		pr_debug("batt_terminal_uv %d < (max = %d - 10000); CC CHG SOC %d\n",
+			batt_terminal_uv,
+			chip->max_voltage_uv, chip->prev_chg_soc);
 		return chip->prev_chg_soc;
 	}
 
 	chg_soc = linear_interpolate(chip->soc_at_cv, chip->ibat_at_cv_ua,
-					100, -100000,
+					100, -1 * chip->chg_term_ua,
 					ibat_ua);
+	chg_soc = bound_soc(chg_soc);
 
 	/* always report a higher soc */
 	if (chg_soc > chip->prev_chg_soc) {
@@ -1212,12 +1313,22 @@
 
 	delta_ocv_uv_limit = DIV_ROUND_CLOSEST(ibat_ua, 1000);
 
-	ocv_est_uv = vbat_uv + (ibat_ua * params->rbatt)/1000;
+	ocv_est_uv = vbat_uv + (ibat_ua * params->rbatt_mohm)/1000;
+
+	chip->ibat_max_ua = (ocv_est_uv - chip->v_cutoff_uv) * 1000
+					/ (params->rbatt_mohm);
+
 	pc_est = calculate_pc(chip, ocv_est_uv, batt_temp);
 	soc_est = div_s64((s64)params->fcc_uah * pc_est - params->uuc_uah*100,
 				(s64)params->fcc_uah - params->uuc_uah);
 	soc_est = bound_soc(soc_est);
 
+	/* never adjust during bms reset mode */
+	if (bms_reset) {
+		pr_debug("bms reset mode, SOC adjustment skipped\n");
+		goto out;
+	}
+
 	if (ibat_ua < 0 && !is_batfet_open(chip)) {
 		soc = charging_adjustments(chip, params, soc, vbat_uv, ibat_ua,
 				batt_temp);
@@ -1246,17 +1357,17 @@
 	n = min(200, max(1 , soc + soc_est + chip->last_soc_est));
 	chip->last_soc_est = soc_est;
 
-	pc = calculate_pc(chip, chip->last_ocv_uv, batt_temp);
+	pc = calculate_pc(chip, chip->last_ocv_uv, chip->last_ocv_temp);
 	if (pc > 0) {
 		pc_new = calculate_pc(chip,
 				chip->last_ocv_uv - (++slope * 1000),
-				batt_temp);
+				chip->last_ocv_temp);
 		while (pc_new == pc) {
 			/* start taking 10mV steps */
 			slope = slope + 10;
 			pc_new = calculate_pc(chip,
 				chip->last_ocv_uv - (slope * 1000),
-				batt_temp);
+				chip->last_ocv_temp);
 		}
 	} else {
 		/*
@@ -1288,7 +1399,7 @@
 		chip->last_ocv_uv = chip->max_voltage_uv;
 
 	/* calculate the soc based on this new ocv */
-	pc_new = calculate_pc(chip, chip->last_ocv_uv, batt_temp);
+	pc_new = calculate_pc(chip, chip->last_ocv_uv, chip->last_ocv_temp);
 	rc_new_uah = (params->fcc_uah * pc_new) / 100;
 	soc_new = (rc_new_uah - params->cc_uah - params->uuc_uah)*100
 					/ (params->fcc_uah - params->uuc_uah);
@@ -1307,7 +1418,7 @@
 	pr_debug("ibat_ua = %d, vbat_uv = %d, ocv_est_uv = %d, pc_est = %d, soc_est = %d, n = %d, delta_ocv_uv = %d, last_ocv_uv = %d, pc_new = %d, soc_new = %d, rbatt = %d, slope = %d\n",
 		ibat_ua, vbat_uv, ocv_est_uv, pc_est,
 		soc_est, n, delta_ocv_uv, chip->last_ocv_uv,
-		pc_new, soc_new, params->rbatt, slope);
+		pc_new, soc_new, params->rbatt_mohm, slope);
 
 	return soc;
 }
@@ -1315,16 +1426,12 @@
 static int clamp_soc_based_on_voltage(struct qpnp_bms_chip *chip, int soc)
 {
 	int rc, vbat_uv;
-	struct qpnp_vadc_result result;
 
-	rc = qpnp_vadc_read(VBAT_SNS, &result);
-	if (rc) {
-		pr_err("error reading vbat_sns adc channel = %d, rc = %d\n",
-						VBAT_SNS, rc);
-		return rc;
+	rc = get_battery_voltage(&vbat_uv);
+	if (rc < 0) {
+		pr_err("adc vbat failed err = %d\n", rc);
+		return soc;
 	}
-
-	vbat_uv = (int)result.physical;
 	if (soc == 0 && vbat_uv > chip->v_cutoff_uv) {
 		pr_debug("clamping soc to 1, vbat (%d) > cutoff (%d)\n",
 						vbat_uv, chip->v_cutoff_uv);
@@ -1359,13 +1466,13 @@
 		pr_debug("FCC = %duAh, UUC = %duAh forcing soc = 0\n",
 						params.fcc_uah,
 						params.uuc_uah);
-		soc = 0;
-	} else {
-		soc = DIV_ROUND_CLOSEST((remaining_usable_charge_uah * 100),
-					(params.fcc_uah
-						- params.uuc_uah));
+		new_calculated_soc = 0;
+		goto done_calculating;
 	}
 
+	soc = DIV_ROUND_CLOSEST((remaining_usable_charge_uah * 100),
+				(params.fcc_uah - params.uuc_uah));
+
 	if (chip->first_time_calc_soc && soc < 0) {
 		/*
 		 * first time calcualtion and the pon ocv  is too low resulting
@@ -1439,6 +1546,7 @@
 		new_calculated_soc = clamp_soc_based_on_voltage(chip,
 						new_calculated_soc);
 
+done_calculating:
 	if (new_calculated_soc != chip->calculated_soc
 			&& chip->bms_psy.name != NULL) {
 		power_supply_changed(&chip->bms_psy);
@@ -1448,31 +1556,20 @@
 	chip->calculated_soc = new_calculated_soc;
 	pr_debug("CC based calculated SOC = %d\n", chip->calculated_soc);
 	chip->first_time_calc_soc = 0;
+	get_current_time(&chip->last_recalc_time);
 	return chip->calculated_soc;
 }
 
-static int read_vbat(struct qpnp_bms_chip *chip)
-{
-	int rc;
-	struct qpnp_vadc_result result;
-
-	rc = qpnp_vadc_read(VBAT_SNS, &result);
-	if (rc) {
-		pr_err("error reading vadc VBAT_SNS = %d, rc = %d\n",
-					VBAT_SNS, rc);
-		return rc;
-	}
-	pr_debug("read %duv from vadc\n", (int)result.physical);
-	return (int)result.physical;
-}
-
 static int calculate_soc_from_voltage(struct qpnp_bms_chip *chip)
 {
 	int voltage_range_uv, voltage_remaining_uv, voltage_based_soc;
-	int vbat_uv;
+	int rc, vbat_uv;
 
-	vbat_uv = read_vbat(chip);
-
+	rc = get_battery_voltage(&vbat_uv);
+	if (rc < 0) {
+		pr_err("adc vbat failed err = %d\n", rc);
+		return rc;
+	}
 	voltage_range_uv = chip->max_voltage_uv - chip->v_cutoff_uv;
 	voltage_remaining_uv = vbat_uv - chip->v_cutoff_uv;
 	voltage_based_soc = voltage_remaining_uv * 100 / voltage_range_uv;
@@ -1491,15 +1588,13 @@
 	return voltage_based_soc;
 }
 
-static void calculate_soc_work(struct work_struct *work)
+static int recalculate_soc(struct qpnp_bms_chip *chip)
 {
-	struct qpnp_bms_chip *chip = container_of(work,
-				struct qpnp_bms_chip,
-				calculate_soc_delayed_work.work);
 	int batt_temp, rc, soc;
 	struct qpnp_vadc_result result;
 	struct raw_soc_params raw;
 
+	wake_lock(&chip->soc_wake_lock);
 	if (chip->use_voltage_soc) {
 		soc = calculate_soc_from_voltage(chip);
 	} else {
@@ -1507,18 +1602,29 @@
 		if (rc) {
 			pr_err("error reading vadc LR_MUX1_BATT_THERM = %d, rc = %d\n",
 						LR_MUX1_BATT_THERM, rc);
-			return;
-		}
-		pr_debug("batt_temp phy = %lld meas = 0x%llx\n",
-						result.physical,
-						result.measurement);
-		batt_temp = (int)result.physical;
+			soc = chip->calculated_soc;
+		} else {
+			pr_debug("batt_temp phy = %lld meas = 0x%llx\n",
+							result.physical,
+							result.measurement);
+			batt_temp = (int)result.physical;
 
-		mutex_lock(&chip->last_ocv_uv_mutex);
-		read_soc_params_raw(chip, &raw);
-		soc = calculate_state_of_charge(chip, &raw, batt_temp);
-		mutex_unlock(&chip->last_ocv_uv_mutex);
+			mutex_lock(&chip->last_ocv_uv_mutex);
+			read_soc_params_raw(chip, &raw, batt_temp);
+			soc = calculate_state_of_charge(chip, &raw, batt_temp);
+			mutex_unlock(&chip->last_ocv_uv_mutex);
+		}
 	}
+	wake_unlock(&chip->soc_wake_lock);
+	return soc;
+}
+
+static void calculate_soc_work(struct work_struct *work)
+{
+	struct qpnp_bms_chip *chip = container_of(work,
+				struct qpnp_bms_chip,
+				calculate_soc_delayed_work.work);
+	int soc = recalculate_soc(chip);
 
 	if (soc < chip->low_soc_calc_threshold)
 		schedule_delayed_work(&chip->calculate_soc_delayed_work,
@@ -1576,11 +1682,13 @@
 	 */
 
 	/* if not charging, return last soc */
-	if (chip->start_percent == -EINVAL)
+	if (!is_battery_charging(chip))
 		return prev_soc;
 
 	chg_time_sec = DIV_ROUND_UP(chip->charge_time_us, USEC_PER_SEC);
 	catch_up_sec = DIV_ROUND_UP(chip->catch_up_time_us, USEC_PER_SEC);
+	if (catch_up_sec == 0)
+		return new_soc;
 	pr_debug("cts= %d catch_up_sec = %d\n", chg_time_sec, catch_up_sec);
 
 	/*
@@ -1651,7 +1759,7 @@
 	 * account for charge time - limit it to SOC_CATCHUP_SEC to
 	 * avoid overflows when charging continues for extended periods
 	 */
-	if (chip->start_percent != -EINVAL) {
+	if (is_battery_charging(chip)) {
 		if (chip->charge_time_us == 0) {
 			/*
 			 * calculating soc for the first time
@@ -1680,8 +1788,7 @@
 	}
 
 	/* last_soc < soc  ... scale and catch up */
-	if (chip->last_soc != -EINVAL && chip->last_soc < soc
-			&& soc != 100 && chip->catch_up_time_us != 0)
+	if (chip->last_soc != -EINVAL && chip->last_soc < soc && soc != 100)
 		soc = scale_soc_while_chg(chip, delta_time_us,
 						soc, chip->last_soc);
 
@@ -1712,10 +1819,15 @@
 	return report_state_of_charge(chip);
 }
 
+/* Returns estimated max current that the battery can supply in uA */
+static int get_prop_bms_current_max(struct qpnp_bms_chip *chip)
+{
+	return chip->ibat_max_ua;
+}
+
 /* Returns instantaneous current in uA */
 static int get_prop_bms_current_now(struct qpnp_bms_chip *chip)
 {
-	/* temporarily return 0 until a real algorithm is put in */
 	int rc, result_ua;
 
 	rc = get_battery_current(chip, &result_ua);
@@ -1770,6 +1882,9 @@
 	case POWER_SUPPLY_PROP_CURRENT_NOW:
 		val->intval = get_prop_bms_current_now(chip);
 		break;
+	case POWER_SUPPLY_PROP_CURRENT_MAX:
+		val->intval = get_prop_bms_current_max(chip);
+		break;
 	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
 		val->intval = get_prop_bms_charge_full_design(chip);
 		break;
@@ -1805,6 +1920,43 @@
 	return 0;
 }
 
+#define OCV_USE_LIMIT_EN		BIT(7)
+static int set_ocv_voltage_thresholds(struct qpnp_bms_chip *chip,
+					int low_voltage_threshold,
+					int high_voltage_threshold)
+{
+	uint16_t low_voltage_raw, high_voltage_raw;
+	int rc;
+
+	low_voltage_raw = convert_vbatt_uv_to_raw(chip,
+				low_voltage_threshold);
+	high_voltage_raw = convert_vbatt_uv_to_raw(chip,
+				high_voltage_threshold);
+	rc = qpnp_write_wrapper(chip, (u8 *)&low_voltage_raw,
+			chip->base + BMS1_OCV_USE_LOW_LIMIT_THR0, 2);
+	if (rc) {
+		pr_err("Failed to set ocv low voltage threshold: %d\n", rc);
+		return rc;
+	}
+	rc = qpnp_write_wrapper(chip, (u8 *)&high_voltage_raw,
+			chip->base + BMS1_OCV_USE_HIGH_LIMIT_THR0, 2);
+	if (rc) {
+		pr_err("Failed to set ocv high voltage threshold: %d\n", rc);
+		return rc;
+	}
+	rc = qpnp_masked_write(chip, BMS1_OCV_USE_LIMIT_CTL,
+				OCV_USE_LIMIT_EN, OCV_USE_LIMIT_EN);
+	if (rc) {
+		pr_err("Failed to enabled ocv voltage thresholds: %d\n", rc);
+		return rc;
+	}
+	pr_debug("ocv low threshold set to %d uv or 0x%x raw\n",
+				low_voltage_threshold, low_voltage_raw);
+	pr_debug("ocv high threshold set to %d uv or 0x%x raw\n",
+				high_voltage_threshold, high_voltage_raw);
+	return 0;
+}
+
 static void read_shutdown_soc_and_iavg(struct qpnp_bms_chip *chip)
 {
 	int rc;
@@ -1879,59 +2031,54 @@
 static int set_battery_data(struct qpnp_bms_chip *chip)
 {
 	int64_t battery_id;
+	struct bms_battery_data *batt_data;
 
-	if (chip->batt_type == BATT_DESAY)
-		goto desay;
-	else if (chip->batt_type == BATT_PALLADIUM)
-		goto palladium;
-
-	battery_id = read_battery_id(chip);
-	if (battery_id < 0) {
-		pr_err("cannot read battery id err = %lld\n", battery_id);
-		return battery_id;
-	}
-
-	if (is_between(PALLADIUM_ID_MIN, PALLADIUM_ID_MAX, battery_id)) {
-		goto palladium;
-	} else if (is_between(DESAY_5200_ID_MIN, DESAY_5200_ID_MAX,
-				battery_id)) {
-		goto desay;
+	if (chip->batt_type == BATT_DESAY) {
+		batt_data = &desay_5200_data;
+	} else if (chip->batt_type == BATT_PALLADIUM) {
+		batt_data = &palladium_1500_data;
+	} else if (chip->batt_type == BATT_OEM) {
+		batt_data = &oem_batt_data;
 	} else {
-		pr_warn("invalid battid, palladium 1500 assumed batt_id %llx\n",
-				battery_id);
-		goto palladium;
+		battery_id = read_battery_id(chip);
+		if (battery_id < 0) {
+			pr_err("cannot read battery id err = %lld\n",
+							battery_id);
+			return battery_id;
+		}
+
+		if (is_between(PALLADIUM_ID_MIN, PALLADIUM_ID_MAX,
+							battery_id)) {
+			batt_data = &palladium_1500_data;
+		} else if (is_between(DESAY_5200_ID_MIN, DESAY_5200_ID_MAX,
+					battery_id)) {
+			batt_data = &desay_5200_data;
+		} else {
+			pr_warn("invalid battid, palladium 1500 assumed batt_id %llx\n",
+					battery_id);
+			batt_data = &palladium_1500_data;
+		}
 	}
 
-palladium:
-		chip->fcc = palladium_1500_data.fcc;
-		chip->fcc_temp_lut = palladium_1500_data.fcc_temp_lut;
-		chip->fcc_sf_lut = palladium_1500_data.fcc_sf_lut;
-		chip->pc_temp_ocv_lut = palladium_1500_data.pc_temp_ocv_lut;
-		chip->pc_sf_lut = palladium_1500_data.pc_sf_lut;
-		chip->rbatt_sf_lut = palladium_1500_data.rbatt_sf_lut;
-		chip->default_rbatt_mohm
-				= palladium_1500_data.default_rbatt_mohm;
-		goto check_lut;
-desay:
-		chip->fcc = desay_5200_data.fcc;
-		chip->fcc_temp_lut = desay_5200_data.fcc_temp_lut;
-		chip->pc_temp_ocv_lut = desay_5200_data.pc_temp_ocv_lut;
-		chip->pc_sf_lut = desay_5200_data.pc_sf_lut;
-		chip->rbatt_sf_lut = desay_5200_data.rbatt_sf_lut;
-		chip->default_rbatt_mohm = desay_5200_data.default_rbatt_mohm;
-		goto check_lut;
-check_lut:
-		if (chip->pc_temp_ocv_lut == NULL) {
-			pr_err("temp ocv lut table is NULL\n");
-			return -EINVAL;
-		}
-		return 0;
+	chip->fcc = batt_data->fcc;
+	chip->fcc_temp_lut = batt_data->fcc_temp_lut;
+	chip->fcc_sf_lut = batt_data->fcc_sf_lut;
+	chip->pc_temp_ocv_lut = batt_data->pc_temp_ocv_lut;
+	chip->pc_sf_lut = batt_data->pc_sf_lut;
+	chip->rbatt_sf_lut = batt_data->rbatt_sf_lut;
+	chip->default_rbatt_mohm = batt_data->default_rbatt_mohm;
+
+	if (chip->pc_temp_ocv_lut == NULL) {
+		pr_err("temp ocv lut table is NULL\n");
+		return -EINVAL;
+	}
+	return 0;
 }
 
 #define SPMI_PROP_READ(chip_prop, qpnp_spmi_property, retval)		\
 do {									\
 	retval = of_property_read_u32(chip->spmi->dev.of_node,		\
-				"qcom,bms-" qpnp_spmi_property,		\
+				"qcom," qpnp_spmi_property,		\
 					&chip->chip_prop);		\
 	if (retval) {							\
 		pr_err("Error reading " #qpnp_spmi_property		\
@@ -1944,7 +2091,7 @@
 {
 	int rc;
 
-	SPMI_PROP_READ(r_sense_mohm, "r-sense-mohm", rc);
+	SPMI_PROP_READ(r_sense_uohm, "r-sense-uohm", rc);
 	SPMI_PROP_READ(v_cutoff_uv, "v-cutoff-uv", rc);
 	SPMI_PROP_READ(max_voltage_uv, "max-voltage-uv", rc);
 	SPMI_PROP_READ(r_conn_mohm, "r-conn-mohm", rc);
@@ -1963,18 +2110,25 @@
 	SPMI_PROP_READ(calculate_soc_ms, "calculate-soc-ms", rc);
 	chip->use_external_rsense = of_property_read_bool(
 			chip->spmi->dev.of_node,
-			"qcom,bms-use-external-rsense");
+			"qcom,use-external-rsense");
 	chip->ignore_shutdown_soc = of_property_read_bool(
 			chip->spmi->dev.of_node,
-			"qcom,bms-ignore-shutdown-soc");
+			"qcom,ignore-shutdown-soc");
 	chip->use_voltage_soc = of_property_read_bool(chip->spmi->dev.of_node,
-			"qcom,bms-use-voltage-soc");
+			"qcom,use-voltage-soc");
+	chip->use_ocv_thresholds = of_property_read_bool(
+			chip->spmi->dev.of_node,
+			"qcom,use-ocv-thresholds");
+	SPMI_PROP_READ(ocv_high_threshold_uv,
+			"ocv-voltage-high-threshold-uv", rc);
+	SPMI_PROP_READ(ocv_low_threshold_uv,
+			"ocv-voltage-low-threshold-uv", rc);
 
 	if (chip->adjust_soc_low_threshold >= 45)
 		chip->adjust_soc_low_threshold = 45;
 
-	pr_debug("dts data: r_sense_mohm:%d, v_cutoff_uv:%d, max_v:%d\n",
-			chip->r_sense_mohm, chip->v_cutoff_uv,
+	pr_debug("dts data: r_sense_uohm:%d, v_cutoff_uv:%d, max_v:%d\n",
+			chip->r_sense_uohm, chip->v_cutoff_uv,
 			chip->max_voltage_uv);
 	pr_debug("r_conn:%d, shutdown_soc: %d, adjust_soc_low:%d\n",
 			chip->r_conn_mohm, chip->shutdown_soc_valid_limit,
@@ -1990,13 +2144,14 @@
 
 static inline void bms_initialize_constants(struct qpnp_bms_chip *chip)
 {
-	chip->start_percent = -EINVAL;
-	chip->end_percent = -EINVAL;
 	chip->prev_pc_unusable = -EINVAL;
 	chip->soc_at_cv = -EINVAL;
 	chip->calculated_soc = -EINVAL;
 	chip->last_soc = -EINVAL;
 	chip->last_soc_est = -EINVAL;
+	chip->last_cc_uah = INT_MIN;
+	chip->ocv_reading_at_100 = OCV_RAW_UNINITIALIZED;
+	chip->prev_last_good_ocv_raw = OCV_RAW_UNINITIALIZED;
 	chip->first_time_calc_soc = 1;
 	chip->first_time_calc_uuc = 1;
 }
@@ -2072,6 +2227,7 @@
 static int read_iadc_channel_select(struct qpnp_bms_chip *chip)
 {
 	u8 iadc_channel_select;
+	int32_t rds_rsense_nohm;
 	int rc;
 
 	rc = qpnp_read_wrapper(chip, &iadc_channel_select,
@@ -2082,10 +2238,17 @@
 	}
 
 	iadc_channel_select &= ADC_CH_SEL_MASK;
-	if (iadc_channel_select == INTERNAL_RSENSE) {
-		pr_debug("Internal rsense used\n");
-		if (chip->use_external_rsense) {
-			pr_debug("Changing rsense to external\n");
+	if (iadc_channel_select != EXTERNAL_RSENSE
+			&& iadc_channel_select != INTERNAL_RSENSE) {
+		pr_err("IADC1_BMS_IADC configured incorrectly. Selected channel = %d\n",
+						iadc_channel_select);
+		return -EINVAL;
+	}
+
+	if (chip->use_external_rsense) {
+		pr_debug("External rsense selected\n");
+		if (iadc_channel_select == INTERNAL_RSENSE) {
+			pr_debug("Internal rsense detected; Changing rsense to external\n");
 			rc = qpnp_masked_write_iadc(chip,
 					IADC1_BMS_ADC_CH_SEL_CTL,
 					ADC_CH_SEL_MASK,
@@ -2098,10 +2261,10 @@
 			}
 			reset_cc(chip);
 		}
-	} else if (iadc_channel_select == EXTERNAL_RSENSE) {
-		pr_debug("External rsense used\n");
-		if (!chip->use_external_rsense) {
-			pr_debug("Changing rsense to internal\n");
+	} else {
+		pr_debug("Internal rsense selected\n");
+		if (iadc_channel_select == EXTERNAL_RSENSE) {
+			pr_debug("External rsense detected; Changing rsense to internal\n");
 			rc = qpnp_masked_write_iadc(chip,
 					IADC1_BMS_ADC_CH_SEL_CTL,
 					ADC_CH_SEL_MASK,
@@ -2114,10 +2277,16 @@
 			}
 			reset_cc(chip);
 		}
-	} else {
-		pr_err("IADC1_BMS_IADC configured incorrectly. Selected channel = %d\n",
-							iadc_channel_select);
-		return -EINVAL;
+
+		rc = qpnp_iadc_get_rsense(&rds_rsense_nohm);
+		if (rc) {
+			pr_err("Unable to read RDS resistance value from IADC; rc = %d\n",
+								rc);
+			return rc;
+		}
+		chip->r_sense_uohm = rds_rsense_nohm/1000;
+		pr_debug("rds_rsense = %d nOhm, saved as %d uOhm\n",
+					rds_rsense_nohm, chip->r_sense_uohm);
 	}
 	return 0;
 }
@@ -2179,6 +2348,17 @@
 		goto error_read;
 	}
 
+	if (chip->use_ocv_thresholds) {
+		rc = set_ocv_voltage_thresholds(chip,
+				chip->ocv_low_threshold_uv,
+				chip->ocv_high_threshold_uv);
+		if (rc) {
+			pr_err("Could not set ocv voltage thresholds: %d\n",
+					rc);
+			goto error_read;
+		}
+	}
+
 	rc = set_battery_data(chip);
 	if (rc) {
 		pr_err("Bad battery data %d\n", rc);
@@ -2191,6 +2371,8 @@
 	mutex_init(&chip->last_ocv_uv_mutex);
 	mutex_init(&chip->soc_invalidation_mutex);
 
+	wake_lock_init(&chip->soc_wake_lock, WAKE_LOCK_SUSPEND,
+			"qpnp_soc_lock");
 	INIT_DELAYED_WORK(&chip->calculate_soc_delayed_work,
 			calculate_soc_work);
 
@@ -2221,15 +2403,20 @@
 	}
 
 	vbatt = 0;
-	get_battery_voltage(&vbatt);
+	rc = get_battery_voltage(&vbatt);
+	if (rc) {
+		pr_err("error reading vbat_sns adc channel = %d, rc = %d\n",
+						VBAT_SNS, rc);
+		goto unregister_dc;
+	}
 
-	pr_debug("OK battery_capacity_at_boot=%d vbatt = %d\n",
+	pr_info("probe success: soc =%d vbatt = %d ocv = %d r_sense_uohm = %u\n",
 				get_prop_bms_capacity(chip),
-				vbatt);
-	pr_info("probe success\n");
+				vbatt, chip->last_ocv_uv, chip->r_sense_uohm);
 	return 0;
 
 unregister_dc:
+	wake_lock_destroy(&chip->soc_wake_lock);
 	power_supply_unregister(&chip->bms_psy);
 	dev_set_drvdata(&spmi->dev, NULL);
 error_resource:
@@ -2248,6 +2435,38 @@
 	return 0;
 }
 
+static int bms_resume(struct device *dev)
+{
+	int rc;
+	unsigned long soc_calc_period;
+	unsigned long time_since_last_recalc;
+	unsigned long tm_now_sec;
+	struct qpnp_bms_chip *chip = dev_get_drvdata(dev);
+
+	rc = get_current_time(&tm_now_sec);
+	if (rc) {
+		pr_err("Could not read current time: %d\n", rc);
+	} else if (tm_now_sec > chip->last_recalc_time) {
+		time_since_last_recalc = tm_now_sec - chip->last_recalc_time;
+		pr_debug("Time since last recalc: %lu\n",
+				time_since_last_recalc);
+		if (chip->calculated_soc < chip->low_soc_calc_threshold)
+			soc_calc_period = chip->low_soc_calculate_soc_ms;
+		else
+			soc_calc_period = chip->calculate_soc_ms;
+
+		if (time_since_last_recalc >= soc_calc_period) {
+			chip->last_recalc_time = tm_now_sec;
+			recalculate_soc(chip);
+		}
+	}
+	return 0;
+}
+
+static const struct dev_pm_ops qpnp_bms_pm_ops = {
+	.resume		= bms_resume,
+};
+
 static struct spmi_driver qpnp_bms_driver = {
 	.probe		= qpnp_bms_probe,
 	.remove		= __devexit_p(qpnp_bms_remove),
@@ -2255,6 +2474,7 @@
 		.name		= QPNP_BMS_DEV_NAME,
 		.owner		= THIS_MODULE,
 		.of_match_table	= qpnp_bms_match_table,
+		.pm		= &qpnp_bms_pm_ops,
 	},
 };
 
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index 005f789..7833afa 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.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
@@ -69,7 +69,8 @@
 #define CHGR_CHG_WDOG_DLY			0x63
 #define CHGR_CHG_WDOG_PET			0x64
 #define CHGR_CHG_WDOG_EN			0x65
-#define CHGR_USB_IUSB_MAX			0x44
+#define CHGR_IR_DROP_COMPEN			0x67
+#define CHGR_I_MAX_REG			0x44
 #define CHGR_USB_USB_SUSP			0x47
 #define CHGR_USB_USB_OTG_CTL			0x48
 #define CHGR_USB_ENUM_T_STOP			0x4E
@@ -80,11 +81,13 @@
 #define CHGR_BAT_IF_BATFET_CTRL1		0x90
 #define CHGR_MISC_BOOT_DONE			0x42
 #define CHGR_BUCK_COMPARATOR_OVRIDE_3		0xED
+#define CHGR_BUCK_BCK_VBAT_REG_MODE		0x74
 #define MISC_REVISION2				0x01
+#define USB_OVP_CTL				0x42
 #define SEC_ACCESS				0xD0
 
-/* SMBB peripheral subtype values */
 #define REG_OFFSET_PERP_SUBTYPE			0x05
+/* SMBB peripheral subtype values */
 #define SMBB_CHGR_SUBTYPE			0x01
 #define SMBB_BUCK_SUBTYPE			0x02
 #define SMBB_BAT_IF_SUBTYPE			0x03
@@ -93,12 +96,22 @@
 #define SMBB_BOOST_SUBTYPE			0x06
 #define SMBB_MISC_SUBTYPE			0x07
 
+/* SMBB peripheral subtype values */
+#define SMBBP_CHGR_SUBTYPE			0x31
+#define SMBBP_BUCK_SUBTYPE			0x32
+#define SMBBP_BAT_IF_SUBTYPE			0x33
+#define SMBBP_USB_CHGPTH_SUBTYPE		0x34
+#define SMBBP_BOOST_SUBTYPE			0x36
+#define SMBBP_MISC_SUBTYPE			0x37
+
 #define QPNP_CHARGER_DEV_NAME	"qcom,qpnp-charger"
 
 /* Status bits and masks */
 #define CHGR_BOOT_DONE			BIT(7)
 #define CHGR_CHG_EN			BIT(7)
 #define CHGR_ON_BAT_FORCE_BIT		BIT(0)
+#define USB_VALID_DEB_20MS		0x03
+#define BUCK_VBAT_REG_NODE_SEL_BIT	BIT(0)
 
 /* Interrupt definitions */
 /* smbb_chg_interrupts */
@@ -167,7 +180,12 @@
  * @resume_voltage_mv:		voltage at which the battery resumes charging
  * @term_current:		the charging based term current
  * @safe_current:		battery safety current setting
+ * @maxinput_usb_ma:		Maximum Input current USB
+ * @maxinput_dc_ma:		Maximum Input current DC
  * @revision:			PMIC revision
+ * @thermal_levels		amount of thermal mitigation levels
+ * @thermal_mitigation		thermal mitigation level values
+ * @therm_lvl_sel		thermal mitigation level selection
  * @dc_psy			power supply to export information to userspace
  * @usb_psy			power supply to export information to userspace
  * @bms_psy			power supply to export information to userspace
@@ -188,6 +206,7 @@
 	u16				misc_base;
 	u16				freq_base;
 	unsigned int			usbin_valid_irq;
+	unsigned int			dcin_valid_irq;
 	unsigned int			chg_done_irq;
 	unsigned int			chg_failed_irq;
 	bool				chg_done;
@@ -201,8 +220,13 @@
 	unsigned int			min_voltage_mv;
 	unsigned int			resume_voltage_mv;
 	unsigned int			term_current;
+	unsigned int			maxinput_usb_ma;
+	unsigned int			maxinput_dc_ma;
 	unsigned int			safe_current;
 	unsigned int			revision;
+	unsigned int			thermal_levels;
+	unsigned int			therm_lvl_sel;
+	unsigned int			*thermal_mitigation;
 	struct power_supply		dc_psy;
 	struct power_supply		*usb_psy;
 	struct power_supply		*bms_psy;
@@ -325,6 +349,9 @@
 	u8 dcin_valid_rt_sts;
 	int rc;
 
+	if (!chip->dc_chgpth_base)
+		return 0;
+
 	rc = qpnp_chg_read(chip, &dcin_valid_rt_sts,
 				 INT_RT_STS(chip->dc_chgpth_base), 1);
 	if (rc) {
@@ -336,36 +363,73 @@
 	return (dcin_valid_rt_sts & DCIN_VALID_IRQ) ? 1 : 0;
 }
 
-#define QPNP_CHG_IUSB_MAX_MIN_100		100
-#define QPNP_CHG_IUSB_MAX_MIN_150		150
-#define QPNP_CHG_IUSB_MAX_MIN_MA		200
-#define QPNP_CHG_IUSB_MAX_MAX_MA		2500
-#define QPNP_CHG_IUSB_MAX_STEP_MA		100
+#define QPNP_CHG_I_MAX_MIN_100		100
+#define QPNP_CHG_I_MAX_MIN_150		150
+#define QPNP_CHG_I_MAX_MIN_MA		200
+#define QPNP_CHG_I_MAX_MAX_MA		2500
+#define QPNP_CHG_I_MAXSTEP_MA		100
+static int
+qpnp_chg_idcmax_set(struct qpnp_chg_chip *chip, int mA)
+{
+	int rc = 0;
+	u8 dc = 0;
+
+	if (mA < QPNP_CHG_I_MAX_MIN_100
+			|| 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) {
+		dc = 0x00;
+		pr_debug("current=%d setting %02x\n", mA, dc);
+		return qpnp_chg_write(chip, &dc,
+			chip->dc_chgpth_base + CHGR_I_MAX_REG, 1);
+	} else if (mA == QPNP_CHG_I_MAX_MIN_150) {
+		dc = 0x01;
+		pr_debug("current=%d setting %02x\n", mA, dc);
+		return qpnp_chg_write(chip, &dc,
+			chip->dc_chgpth_base + CHGR_I_MAX_REG, 1);
+	}
+
+	dc = mA / QPNP_CHG_I_MAXSTEP_MA;
+
+	pr_debug("current=%d setting 0x%x\n", mA, dc);
+	rc = qpnp_chg_write(chip, &dc,
+		chip->dc_chgpth_base + CHGR_I_MAX_REG, 1);
+
+	return rc;
+}
+
 static int
 qpnp_chg_iusbmax_set(struct qpnp_chg_chip *chip, int mA)
 {
 	int rc = 0;
 	u8 usb_reg = 0, temp = 8;
 
-	if (mA == QPNP_CHG_IUSB_MAX_MIN_100) {
-		usb_reg = 0x00;
-		pr_debug("current=%d setting %02x\n", mA, usb_reg);
-		return qpnp_chg_write(chip, &usb_reg,
-		chip->usb_chgpth_base + CHGR_USB_IUSB_MAX, 1);
-	} else if (mA == QPNP_CHG_IUSB_MAX_MIN_150) {
-		usb_reg = 0x01;
-		pr_debug("current=%d setting %02x\n", mA, usb_reg);
-		return qpnp_chg_write(chip, &usb_reg,
-		chip->usb_chgpth_base + CHGR_USB_IUSB_MAX, 1);
-	}
-
-	if (mA < QPNP_CHG_IUSB_MAX_MIN_MA
-			|| mA > QPNP_CHG_IUSB_MAX_MAX_MA) {
+	if (mA < QPNP_CHG_I_MAX_MIN_100
+			|| mA > QPNP_CHG_I_MAX_MAX_MA) {
 		pr_err("bad mA=%d asked to set\n", mA);
 		return -EINVAL;
 	}
 
-	usb_reg = mA / QPNP_CHG_IUSB_MAX_STEP_MA;
+	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,
+		chip->usb_chgpth_base + CHGR_I_MAX_REG, 1);
+	} else if (mA == QPNP_CHG_I_MAX_MIN_150) {
+		usb_reg = 0x01;
+		pr_debug("current=%d setting %02x\n", mA, usb_reg);
+		return qpnp_chg_write(chip, &usb_reg,
+		chip->usb_chgpth_base + CHGR_I_MAX_REG, 1);
+	}
+
+	/* Impose input current limit */
+	if (chip->maxinput_usb_ma)
+		mA = (chip->maxinput_usb_ma) <= mA ? chip->maxinput_usb_ma : mA;
+
+	usb_reg = mA / QPNP_CHG_I_MAXSTEP_MA;
 
 	if (chip->flags & CHG_FLAGS_VCP_WA) {
 		temp = 0xA5;
@@ -378,7 +442,7 @@
 
 	pr_debug("current=%d setting 0x%x\n", mA, usb_reg);
 	rc = qpnp_chg_write(chip, &usb_reg,
-		chip->usb_chgpth_base + CHGR_USB_IUSB_MAX, 1);
+		chip->usb_chgpth_base + CHGR_I_MAX_REG, 1);
 
 	if (chip->flags & CHG_FLAGS_VCP_WA) {
 		temp = 0xA5;
@@ -428,6 +492,23 @@
 	return IRQ_HANDLED;
 }
 
+static irqreturn_t
+qpnp_chg_dc_dcin_valid_irq_handler(int irq, void *_chip)
+{
+	struct qpnp_chg_chip *chip = _chip;
+	int dc_present;
+
+	dc_present = qpnp_chg_is_dc_chg_plugged_in(chip);
+	pr_debug("dcin-valid triggered: %d\n", dc_present);
+
+	if (chip->dc_present ^ dc_present) {
+		chip->dc_present = dc_present;
+		power_supply_changed(&chip->dc_psy);
+	}
+
+	return IRQ_HANDLED;
+}
+
 #define CHGR_CHG_FAILED_BIT	BIT(7)
 static irqreturn_t
 qpnp_chg_chgr_chg_failed_irq_handler(int irq, void *_chip)
@@ -462,6 +543,7 @@
 {
 	switch (psp) {
 	case POWER_SUPPLY_PROP_CHARGING_ENABLED:
+	case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL:
 		return 1;
 	default:
 		break;
@@ -481,6 +563,10 @@
 static int
 qpnp_chg_force_run_on_batt(struct qpnp_chg_chip *chip, int disable)
 {
+	/* Don't run on battery for batteryless hardware */
+	if (chip->use_default_batt_values)
+		return 0;
+
 	/* This bit forces the charger to run off of the battery rather
 	 * than a connected charger */
 	return qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_CHG_CTRL,
@@ -488,6 +574,29 @@
 			disable ? CHGR_ON_BAT_FORCE_BIT : 0, 1);
 }
 
+static int
+qpnp_chg_buck_control(struct qpnp_chg_chip *chip, int enable)
+{
+	int rc;
+
+	if (chip->charging_disabled && enable) {
+		pr_debug("Charging disabled\n");
+		return 0;
+	}
+
+	rc = qpnp_chg_charge_en(chip, enable);
+	if (rc) {
+		pr_err("Failed to control charging %d\n", rc);
+		return rc;
+	}
+
+	rc = qpnp_chg_force_run_on_batt(chip, !enable);
+	if (rc)
+		pr_err("Failed to control charging %d\n", rc);
+
+	return rc;
+}
+
 static
 int switch_usb_to_charge_mode(struct qpnp_chg_chip *chip)
 {
@@ -563,6 +672,7 @@
 	POWER_SUPPLY_PROP_CURRENT_NOW,
 	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
 	POWER_SUPPLY_PROP_TEMP,
+	POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL,
 };
 
 static char *pm_power_supplied_to[] = {
@@ -817,12 +927,12 @@
 		chip->usb_psy->get_property(chip->usb_psy,
 			  POWER_SUPPLY_PROP_CURRENT_MAX, &ret);
 		qpnp_chg_iusbmax_set(chip, ret.intval / 1000);
-		if ((ret.intval / 1000) <= QPNP_CHG_IUSB_MAX_MIN_MA)
+		if ((ret.intval / 1000) <= QPNP_CHG_I_MAX_MIN_MA)
 			qpnp_chg_usb_suspend_enable(chip, 1);
 		else
 			qpnp_chg_usb_suspend_enable(chip, 0);
 	} else {
-		qpnp_chg_iusbmax_set(chip, QPNP_CHG_IUSB_MAX_MIN_100);
+		qpnp_chg_iusbmax_set(chip, QPNP_CHG_I_MAX_MIN_100);
 		qpnp_chg_usb_suspend_enable(chip, 0);
 	}
 
@@ -878,32 +988,13 @@
 	case POWER_SUPPLY_PROP_CHARGING_ENABLED:
 		val->intval = !(chip->charging_disabled);
 		break;
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int
-qpnp_batt_power_set_property(struct power_supply *psy,
-				  enum power_supply_property psp,
-				  const union power_supply_propval *val)
-{
-	struct qpnp_chg_chip *chip = container_of(psy, struct qpnp_chg_chip,
-								batt_psy);
-
-	switch (psp) {
-	case POWER_SUPPLY_PROP_CHARGING_ENABLED:
-		chip->charging_disabled = !(val->intval);
-		qpnp_chg_charge_en(chip, !chip->charging_disabled);
-		qpnp_chg_force_run_on_batt(chip, chip->charging_disabled);
+	case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL:
+		val->intval = chip->therm_lvl_sel;
 		break;
 	default:
 		return -EINVAL;
 	}
 
-	power_supply_changed(&chip->batt_psy);
 	return 0;
 }
 
@@ -1060,6 +1151,60 @@
 		chip->chgr_base + CHGR_VDD_MAX, 1);
 }
 
+static void
+qpnp_chg_set_appropriate_battery_current(struct qpnp_chg_chip *chip)
+{
+	unsigned int chg_current = chip->max_bat_chg_current;
+
+	if (chip->therm_lvl_sel != 0 && chip->thermal_mitigation)
+		chg_current = min(chg_current,
+			chip->thermal_mitigation[chip->therm_lvl_sel]);
+
+	pr_debug("setting %d mA\n", chg_current);
+	qpnp_chg_ibatmax_set(chip, chg_current);
+}
+
+static void
+qpnp_batt_system_temp_level_set(struct qpnp_chg_chip *chip, int lvl_sel)
+{
+	if (lvl_sel >= 0 && lvl_sel < chip->thermal_levels) {
+		chip->therm_lvl_sel = lvl_sel;
+		if (lvl_sel == (chip->thermal_levels - 1)) {
+			/* disable charging if highest value selected */
+			qpnp_chg_buck_control(chip, 0);
+		} else {
+			qpnp_chg_buck_control(chip, 1);
+			qpnp_chg_set_appropriate_battery_current(chip);
+		}
+	} else {
+		pr_err("Unsupported level selected %d\n", lvl_sel);
+	}
+}
+
+static int
+qpnp_batt_power_set_property(struct power_supply *psy,
+				  enum power_supply_property psp,
+				  const union power_supply_propval *val)
+{
+	struct qpnp_chg_chip *chip = container_of(psy, struct qpnp_chg_chip,
+								batt_psy);
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_CHARGING_ENABLED:
+		chip->charging_disabled = !(val->intval);
+		qpnp_chg_charge_en(chip, !chip->charging_disabled);
+		qpnp_chg_force_run_on_batt(chip, chip->charging_disabled);
+		break;
+	case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL:
+		qpnp_batt_system_temp_level_set(chip, val->intval);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	power_supply_changed(&chip->batt_psy);
+	return 0;
+}
 
 static void
 qpnp_chg_setup_flags(struct qpnp_chg_chip *chip)
@@ -1078,6 +1223,7 @@
 
 	switch (subtype) {
 	case SMBB_CHGR_SUBTYPE:
+	case SMBBP_CHGR_SUBTYPE:
 		chip->chg_done_irq = spmi_get_irq_byname(chip->spmi,
 						spmi_resource, "chg-done");
 		if (chip->chg_done_irq < 0) {
@@ -1155,18 +1301,21 @@
 		enable_irq_wake(chip->chg_done_irq);
 		break;
 	case SMBB_BUCK_SUBTYPE:
+	case SMBBP_BUCK_SUBTYPE:
+		rc = qpnp_chg_masked_write(chip,
+			chip->chgr_base + CHGR_BUCK_BCK_VBAT_REG_MODE,
+			BUCK_VBAT_REG_NODE_SEL_BIT,
+			BUCK_VBAT_REG_NODE_SEL_BIT, 1);
+		if (rc) {
+			pr_debug("failed to enable IR drop comp rc=%d\n", rc);
+			return rc;
+		}
 		break;
 	case SMBB_BAT_IF_SUBTYPE:
-		/* HACK: Unlock secure access to override temp comparator */
-		rc = qpnp_chg_masked_write(chip,
-				chip->bat_if_base + SEC_ACCESS,
-				0xA5, 0xA5, 1);
-		pr_debug("override hot cold\n");
-		rc = qpnp_chg_masked_write(chip,
-				chip->bat_if_base + 0xE5,
-				0xFF, 0x28, 1);
+	case SMBBP_BAT_IF_SUBTYPE:
 		break;
 	case SMBB_USB_CHGPTH_SUBTYPE:
+	case SMBBP_USB_CHGPTH_SUBTYPE:
 		chip->usbin_valid_irq = spmi_get_irq_byname(chip->spmi,
 						spmi_resource, "usbin-valid");
 		if (chip->usbin_valid_irq < 0) {
@@ -1197,16 +1346,40 @@
 		}
 
 		rc = qpnp_chg_masked_write(chip,
+			chip->usb_chgpth_base + USB_OVP_CTL,
+			USB_VALID_DEB_20MS,
+			USB_VALID_DEB_20MS, 1);
+
+		rc = qpnp_chg_masked_write(chip,
 			chip->usb_chgpth_base + CHGR_USB_ENUM_T_STOP,
 			ENUM_T_STOP_BIT,
 			ENUM_T_STOP_BIT, 1);
 
 		break;
 	case SMBB_DC_CHGPTH_SUBTYPE:
+		chip->dcin_valid_irq = spmi_get_irq_byname(chip->spmi,
+						spmi_resource, "dcin-valid");
+		if (chip->dcin_valid_irq < 0) {
+			pr_err("Unable to get dcin irq\n");
+			return -ENXIO;
+		}
+		rc = devm_request_irq(chip->dev, chip->dcin_valid_irq,
+				qpnp_chg_dc_dcin_valid_irq_handler,
+				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+				"chg_dcin_valid", chip);
+		if (rc < 0) {
+			pr_err("Can't request %d dcinvalid  for chg: %d\n",
+						chip->dcin_valid_irq, rc);
+			return -ENXIO;
+		}
+
+		enable_irq_wake(chip->dcin_valid_irq);
 		break;
 	case SMBB_BOOST_SUBTYPE:
+	case SMBBP_BOOST_SUBTYPE:
 		break;
 	case SMBB_MISC_SUBTYPE:
+	case SMBBP_MISC_SUBTYPE:
 		pr_debug("Setting BOOT_DONE\n");
 		rc = qpnp_chg_masked_write(chip,
 			chip->misc_base + CHGR_MISC_BOOT_DONE,
@@ -1241,10 +1414,6 @@
 		return -ENOMEM;
 	}
 
-	rc = qpnp_vadc_is_ready();
-	if (rc)
-		goto fail_chg_enable;
-
 	chip->dev = &(spmi->dev);
 	chip->spmi = spmi;
 
@@ -1314,6 +1483,33 @@
 		goto fail_chg_enable;
 	}
 
+	/* Get the ibatsafe property */
+	rc = of_property_read_u32(spmi->dev.of_node,
+				"qcom,chg-vbatdet-mv",
+				&chip->resume_voltage_mv);
+	if (rc) {
+		pr_err("Error reading vbatdet property %d\n", rc);
+		goto fail_chg_enable;
+	}
+
+	/* Get the maxinput-dc-ma property */
+	rc = of_property_read_u32(spmi->dev.of_node,
+				"qcom,chg-maxinput-dc-ma",
+				&chip->maxinput_dc_ma);
+	if (rc && rc != -EINVAL) {
+		pr_err("Error reading maxinput-dc-ma property %d\n", rc);
+		goto fail_chg_enable;
+	}
+
+	/* Get the maxinput-usb-ma property */
+	rc = of_property_read_u32(spmi->dev.of_node,
+				"qcom,chg-maxinput-usb-ma",
+				&chip->maxinput_usb_ma);
+	if (rc && rc != -EINVAL) {
+		pr_err("Error reading maxinput-usb-ma property %d\n", rc);
+		goto fail_chg_enable;
+	}
+
 	/* Get the charging-disabled property */
 	chip->charging_disabled = of_property_read_bool(spmi->dev.of_node,
 					"qcom,chg-charging-disabled");
@@ -1322,6 +1518,29 @@
 	chip->use_default_batt_values = of_property_read_bool(spmi->dev.of_node,
 					"qcom,chg-use-default-batt-values");
 
+	of_get_property(spmi->dev.of_node, "qcom,chg-thermal-mitigation",
+		&(chip->thermal_levels));
+
+	if (chip->thermal_levels > sizeof(int)) {
+		chip->thermal_mitigation = kzalloc(
+			chip->thermal_levels,
+			GFP_KERNEL);
+
+		if (chip->thermal_mitigation == NULL) {
+			pr_err("thermal mitigation kzalloc() failed.\n");
+			goto fail_chg_enable;
+		}
+
+		chip->thermal_levels /= sizeof(int);
+		rc = of_property_read_u32_array(spmi->dev.of_node,
+				"qcom,chg-thermal-mitigation",
+				chip->thermal_mitigation, chip->thermal_levels);
+		if (rc) {
+			pr_err("qcom,chg-thermal-mitigation missing in dt\n");
+			goto fail_chg_enable;
+		}
+	}
+
 	/* Disable charging when faking battery values */
 	if (chip->use_default_batt_values)
 		chip->charging_disabled = true;
@@ -1351,6 +1570,7 @@
 
 		switch (subtype) {
 		case SMBB_CHGR_SUBTYPE:
+		case SMBBP_CHGR_SUBTYPE:
 			chip->chgr_base = resource->start;
 			rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
 			if (rc) {
@@ -1360,6 +1580,7 @@
 			}
 			break;
 		case SMBB_BUCK_SUBTYPE:
+		case SMBBP_BUCK_SUBTYPE:
 			chip->buck_base = resource->start;
 			rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
 			if (rc) {
@@ -1369,6 +1590,7 @@
 			}
 			break;
 		case SMBB_BAT_IF_SUBTYPE:
+		case SMBBP_BAT_IF_SUBTYPE:
 			chip->bat_if_base = resource->start;
 			rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
 			if (rc) {
@@ -1378,6 +1600,7 @@
 			}
 			break;
 		case SMBB_USB_CHGPTH_SUBTYPE:
+		case SMBBP_USB_CHGPTH_SUBTYPE:
 			chip->usb_chgpth_base = resource->start;
 			rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
 			if (rc) {
@@ -1396,6 +1619,7 @@
 			}
 			break;
 		case SMBB_BOOST_SUBTYPE:
+		case SMBBP_BOOST_SUBTYPE:
 			chip->boost_base = resource->start;
 			rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
 			if (rc) {
@@ -1405,6 +1629,7 @@
 			}
 			break;
 		case SMBB_MISC_SUBTYPE:
+		case SMBBP_MISC_SUBTYPE:
 			chip->misc_base = resource->start;
 			rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
 			if (rc) {
@@ -1422,34 +1647,44 @@
 	dev_set_drvdata(&spmi->dev, chip);
 	device_init_wakeup(&spmi->dev, 1);
 
-	chip->dc_psy.name = "qpnp-dc";
-	chip->dc_psy.type = POWER_SUPPLY_TYPE_MAINS;
-	chip->dc_psy.supplied_to = pm_power_supplied_to;
-	chip->dc_psy.num_supplicants = ARRAY_SIZE(pm_power_supplied_to);
-	chip->dc_psy.properties = pm_power_props_mains;
-	chip->dc_psy.num_properties = ARRAY_SIZE(pm_power_props_mains);
-	chip->dc_psy.get_property = qpnp_power_get_property_mains;
+	if (chip->bat_if_base) {
+		rc = qpnp_vadc_is_ready();
+		if (rc)
+			goto fail_chg_enable;
 
-	chip->batt_psy.name = "battery";
-	chip->batt_psy.type = POWER_SUPPLY_TYPE_BATTERY;
-	chip->batt_psy.properties = msm_batt_power_props;
-	chip->batt_psy.num_properties = ARRAY_SIZE(msm_batt_power_props);
-	chip->batt_psy.get_property = qpnp_batt_power_get_property;
-	chip->batt_psy.set_property = qpnp_batt_power_set_property;
-	chip->batt_psy.property_is_writeable = qpnp_batt_property_is_writeable;
-	chip->batt_psy.external_power_changed =
+		chip->batt_psy.name = "battery";
+		chip->batt_psy.type = POWER_SUPPLY_TYPE_BATTERY;
+		chip->batt_psy.properties = msm_batt_power_props;
+		chip->batt_psy.num_properties =
+			ARRAY_SIZE(msm_batt_power_props);
+		chip->batt_psy.get_property = qpnp_batt_power_get_property;
+		chip->batt_psy.set_property = qpnp_batt_power_set_property;
+		chip->batt_psy.property_is_writeable =
+				qpnp_batt_property_is_writeable;
+		chip->batt_psy.external_power_changed =
 				qpnp_batt_external_power_changed;
 
-	rc = power_supply_register(chip->dev, &chip->dc_psy);
-	if (rc < 0) {
-		pr_err("power_supply_register usb failed rc = %d\n", rc);
-		goto fail_chg_enable;
+		rc = power_supply_register(chip->dev, &chip->batt_psy);
+		if (rc < 0) {
+			pr_err("batt failed to register rc = %d\n", rc);
+			goto fail_chg_enable;
+		}
 	}
 
-	rc = power_supply_register(chip->dev, &chip->batt_psy);
-	if (rc < 0) {
-		pr_err("power_supply_register batt failed rc = %d\n", rc);
-		goto unregister_dc;
+	if (chip->dc_chgpth_base) {
+		chip->dc_psy.name = "qpnp-dc";
+		chip->dc_psy.type = POWER_SUPPLY_TYPE_MAINS;
+		chip->dc_psy.supplied_to = pm_power_supplied_to;
+		chip->dc_psy.num_supplicants = ARRAY_SIZE(pm_power_supplied_to);
+		chip->dc_psy.properties = pm_power_props_mains;
+		chip->dc_psy.num_properties = ARRAY_SIZE(pm_power_props_mains);
+		chip->dc_psy.get_property = qpnp_power_get_property_mains;
+
+		rc = power_supply_register(chip->dev, &chip->dc_psy);
+		if (rc < 0) {
+			pr_err("power_supply_register dc failed rc=%d\n", rc);
+			goto unregister_batt;
+		}
 	}
 
 	/* Turn on appropriate workaround flags */
@@ -1458,15 +1693,30 @@
 	power_supply_set_present(chip->usb_psy,
 			qpnp_chg_is_usb_chg_plugged_in(chip));
 
+	if (chip->maxinput_dc_ma && chip->dc_chgpth_base) {
+		rc = qpnp_chg_idcmax_set(chip, chip->maxinput_dc_ma);
+		if (rc) {
+			pr_err("Error setting idcmax property %d\n", rc);
+			goto unregister_batt;
+		}
+	}
+
 	qpnp_chg_charge_en(chip, !chip->charging_disabled);
 	qpnp_chg_force_run_on_batt(chip, chip->charging_disabled);
 
-	pr_info("Probe success !\n");
+	pr_info("success chg_dis = %d, usb = %d, dc = %d b_health = %d batt_present = %d\n",
+			chip->charging_disabled,
+			qpnp_chg_is_usb_chg_plugged_in(chip),
+			qpnp_chg_is_dc_chg_plugged_in(chip),
+			get_prop_batt_present(chip),
+			get_prop_batt_health(chip));
 	return 0;
 
-unregister_dc:
-	power_supply_unregister(&chip->dc_psy);
+unregister_batt:
+	if (chip->bat_if_base)
+		power_supply_unregister(&chip->batt_psy);
 fail_chg_enable:
+	kfree(chip->thermal_mitigation);
 	kfree(chip);
 	dev_set_drvdata(&spmi->dev, NULL);
 	return rc;
diff --git a/drivers/power/smb137b.c b/drivers/power/smb137b.c
index 7ff8e28..c1728e0 100644
--- a/drivers/power/smb137b.c
+++ b/drivers/power/smb137b.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011 Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/power/smb349.c b/drivers/power/smb349.c
index f9ca81c..29d8c18 100644
--- a/drivers/power/smb349.c
+++ b/drivers/power/smb349.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012 The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c
index 7e74eca..d0410a4 100644
--- a/drivers/regulator/fixed.c
+++ b/drivers/regulator/fixed.c
@@ -104,6 +104,9 @@
 	if (of_find_property(np, "enable-active-high", NULL))
 		config->enable_high = true;
 
+	if (of_find_property(np, "parent-supply", NULL))
+		init_data->supply_regulator = "parent";
+
 	return config;
 }
 
diff --git a/drivers/regulator/msm-gpio-regulator.c b/drivers/regulator/msm-gpio-regulator.c
index 15e5b53..f8fdc14 100644
--- a/drivers/regulator/msm-gpio-regulator.c
+++ b/drivers/regulator/msm-gpio-regulator.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/drivers/regulator/onsemi-ncp6335d.c b/drivers/regulator/onsemi-ncp6335d.c
index 4574862..329ac46 100644
--- a/drivers/regulator/onsemi-ncp6335d.c
+++ b/drivers/regulator/onsemi-ncp6335d.c
@@ -39,6 +39,7 @@
 #define NCP6335D_PWM_MODE1		BIT(6)
 #define NCP6335D_PWM_MODE0		BIT(7)
 #define NCP6335D_PGOOD_DISCHG		BIT(4)
+#define NCP6335D_SLEEP_MODE		BIT(4)
 
 #define NCP6335D_VOUT_SEL_MASK		0x7F
 #define NCP6335D_SLEW_MASK		0x18
@@ -280,6 +281,14 @@
 	if (rc)
 		dev_err(dd->dev, "Unable to set slew rate rc(%d)\n", rc);
 
+	/* Set Sleep mode bit */
+	rc = regmap_update_bits(dd->regmap, REG_NCP6335D_COMMAND,
+				NCP6335D_SLEEP_MODE, pdata->sleep_enable ?
+						NCP6335D_SLEEP_MODE : 0);
+	if (rc)
+		dev_err(dd->dev, "Unable to set sleep mode (%d)\n", rc);
+
+	dump_registers(dd, REG_NCP6335D_COMMAND, __func__);
 	dump_registers(dd, REG_NCP6335D_PROGVSEL0, __func__);
 	dump_registers(dd, REG_NCP6335D_TIMING, __func__);
 	dump_registers(dd, REG_NCP6335D_PGOOD, __func__);
diff --git a/drivers/regulator/pm8058-xo.c b/drivers/regulator/pm8058-xo.c
index 0d57c02..119cbb2 100644
--- a/drivers/regulator/pm8058-xo.c
+++ b/drivers/regulator/pm8058-xo.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/regulator/pm8xxx-regulator.c b/drivers/regulator/pm8xxx-regulator.c
index dfdbb44..1b67c47 100644
--- a/drivers/regulator/pm8xxx-regulator.c
+++ b/drivers/regulator/pm8xxx-regulator.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/drivers/regulator/pmic8058-regulator.c b/drivers/regulator/pmic8058-regulator.c
index f9b0319..24c7902 100644
--- a/drivers/regulator/pmic8058-regulator.c
+++ b/drivers/regulator/pmic8058-regulator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/regulator/pmic8901-regulator.c b/drivers/regulator/pmic8901-regulator.c
index 02c9549..c1d0281 100644
--- a/drivers/regulator/pmic8901-regulator.c
+++ b/drivers/regulator/pmic8901-regulator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/regulator/qpnp-regulator.c b/drivers/regulator/qpnp-regulator.c
index a330f1b..4cdfaeb 100644
--- a/drivers/regulator/qpnp-regulator.c
+++ b/drivers/regulator/qpnp-regulator.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/rtc/qpnp-rtc.c b/drivers/rtc/qpnp-rtc.c
index 5650e74..6d8985e 100644
--- a/drivers/rtc/qpnp-rtc.c
+++ b/drivers/rtc/qpnp-rtc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/rtc/rtc-msm.c b/drivers/rtc/rtc-msm.c
index c17e461..99eb41c 100644
--- a/drivers/rtc/rtc-msm.c
+++ b/drivers/rtc/rtc-msm.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2009-2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2011 The Linux Foundation. All rights reserved.
  * Author: San Mehat <san@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c
index e53374e..aea91ef 100644
--- a/drivers/rtc/rtc-pm8xxx.c
+++ b/drivers/rtc/rtc-pm8xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 5ba5c2a..508c2bb 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -467,7 +467,7 @@
 	return sdkp;
 }
 
-static struct scsi_disk *scsi_disk_get_from_dev(struct device *dev)
+struct scsi_disk *scsi_disk_get_from_dev(struct device *dev)
 {
 	struct scsi_disk *sdkp;
 
diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig
index 8f27f9d..1756897 100644
--- a/drivers/scsi/ufs/Kconfig
+++ b/drivers/scsi/ufs/Kconfig
@@ -47,3 +47,12 @@
 	depends on PCI && SCSI
 	---help---
 	This is a generic driver which supports PCIe UFS Host controllers.
+
+config SCSI_UFS_TEST
+	tristate "Universal Flash Storage host controller driver unit-tests"
+	depends on SCSI_UFSHCD && IOSCHED_TEST
+	---help---
+	This adds UFS Host controller unit-test framework.
+	The UFS unit-tests register as a block device test utility to
+	the test-iosched and will be initiated when the test-iosched will
+	be chosen to be the active I/O scheduler.
diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile
index adf7895..489058d 100644
--- a/drivers/scsi/ufs/Makefile
+++ b/drivers/scsi/ufs/Makefile
@@ -1,2 +1,3 @@
 # UFSHCD makefile
 obj-$(CONFIG_SCSI_UFSHCD) += ufshcd.o
+obj-$(CONFIG_SCSI_UFS_TEST) += ufs_test.o
diff --git a/drivers/scsi/ufs/ufs_test.c b/drivers/scsi/ufs/ufs_test.c
new file mode 100644
index 0000000..03c58a4
--- /dev/null
+++ b/drivers/scsi/ufs/ufs_test.c
@@ -0,0 +1,348 @@
+/* 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/blkdev.h>
+#include <linux/debugfs.h>
+#include <linux/test-iosched.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_cmnd.h>
+#include <../sd.h>
+
+#define MODULE_NAME "ufs_test"
+
+#define TEST_MAX_BIOS_PER_REQ		120
+#define LARGE_PRIME_1	1103515367
+#define LARGE_PRIME_2	35757
+#define DEFAULT_NUM_OF_BIOS	2
+
+#define test_pr_debug(fmt, args...) pr_debug("%s: "fmt"\n", MODULE_NAME, args)
+#define test_pr_info(fmt, args...) pr_info("%s: "fmt"\n", MODULE_NAME, args)
+#define test_pr_err(fmt, args...) pr_err("%s: "fmt"\n", MODULE_NAME, args)
+
+enum ufs_test_testcases {
+	UFS_TEST_WRITE_READ_TEST,
+};
+
+struct ufs_test_debug {
+	struct dentry *write_read_test; /* basic test */
+	struct dentry *random_test_seed; /* parameters in utils */
+};
+
+struct ufs_test_data {
+	/* Data structure for debugfs dentrys */
+	struct ufs_test_debug debug;
+	/*
+	 * Data structure containing individual test information, including
+	 * self-defined specific data
+	 */
+	struct test_info test_info;
+	/* device test */
+	struct blk_dev_test_type bdt;
+	/* A wait queue for OPs to complete */
+	wait_queue_head_t wait_q;
+	/* a flag for read compleation */
+	bool read_completed;
+	/* a flag for write compleation */
+	bool write_completed;
+	/*
+	 * To determine the number of r/w bios. When seed = 0, random is
+	 * disabled and 2 BIOs are written.
+	 */
+	unsigned int random_test_seed;
+};
+
+static struct ufs_test_data *utd;
+
+static bool message_repeat;
+
+static char *ufs_test_get_test_case_str(struct test_data *td)
+{
+	if (!td) {
+		test_pr_err("%s: NULL td", __func__);
+		return NULL;
+	}
+
+	switch (td->test_info.testcase) {
+	case UFS_TEST_WRITE_READ_TEST:
+		return "UFS write read test";
+		break;
+	default:
+		return "Unknown test";
+	}
+}
+
+static unsigned int ufs_test_pseudo_random_seed(unsigned int *seed_number,
+		unsigned int min_val, unsigned int max_val)
+{
+	int ret = 0;
+
+	if (!seed_number)
+		return 0;
+
+	*seed_number = ((unsigned int) (((unsigned long) *seed_number
+			* (unsigned long) LARGE_PRIME_1) + LARGE_PRIME_2));
+	ret = (unsigned int) ((*seed_number) % max_val);
+
+	return (ret > min_val ? ret : min_val);
+}
+
+static void ufs_test_pseudo_rnd_size(unsigned int *seed,
+				unsigned int *num_of_bios)
+{
+	*num_of_bios = ufs_test_pseudo_random_seed(seed, 1,
+						TEST_MAX_BIOS_PER_REQ);
+	if (!(*num_of_bios))
+		*num_of_bios = DEFAULT_NUM_OF_BIOS;
+}
+
+static void ufs_test_write_read_test_end_io_fn(struct request *rq, int err)
+{
+	struct test_request *test_rq = (struct test_request *)rq->elv.priv[0];
+	BUG_ON(!test_rq);
+
+	test_rq->req_completed = 1;
+	test_rq->req_result = err;
+
+	test_pr_info("%s: request %d completed, err=%d",
+			__func__, test_rq->req_id, err);
+
+	utd->write_completed = true;
+	wake_up(&utd->wait_q);
+}
+
+static struct gendisk *ufs_test_get_rq_disk(void)
+{
+	struct request_queue *req_q = test_iosched_get_req_queue();
+	struct scsi_device *sd;
+	struct device *dev;
+	struct scsi_disk *sdkp;
+	struct gendisk *gd;
+
+	if (!req_q) {
+		test_pr_info("%s: Could not fetch request_queue", __func__);
+		gd = NULL;
+		goto exit;
+	}
+
+	sd = (struct scsi_device *)req_q->queuedata;
+
+	dev = &sd->sdev_gendev;
+	sdkp = scsi_disk_get_from_dev(dev);
+	if (!sdkp) {
+		test_pr_info("%s: Could not fatch scsi disk", __func__);
+		gd = NULL;
+		goto exit;
+	}
+
+	gd = sdkp->disk;
+exit:
+	return gd;
+}
+
+static int ufs_test_run_write_read_test(struct test_data *td)
+{
+	int ret = 0;
+	unsigned int start_sec;
+	unsigned int num_bios;
+	struct request_queue *q = td->req_q;
+
+
+	start_sec = td->start_sector + sizeof(int) * BIO_U32_SIZE
+			* td->num_of_write_bios;
+	if (utd->random_test_seed != 0)
+		ufs_test_pseudo_rnd_size(&utd->random_test_seed, &num_bios);
+	else
+		num_bios = DEFAULT_NUM_OF_BIOS;
+
+	/* Adding a write request */
+	test_pr_info("%s: Adding a write requests to Q, first req_id=%d",
+			__func__, td->wr_rd_next_req_id);
+
+	utd->write_completed = false;
+	ret = test_iosched_add_wr_rd_test_req(0, WRITE, start_sec,
+					num_bios, TEST_PATTERN_5A,
+					ufs_test_write_read_test_end_io_fn);
+
+	if (ret) {
+		test_pr_err("%s: failed to add a write request", __func__);
+		return ret;
+	}
+
+	/* waiting for the write request to finish */
+	blk_run_queue(q);
+	wait_event(utd->wait_q, utd->write_completed);
+
+	/* Adding a read request*/
+	test_pr_info("%s: Adding a read request to Q", __func__);
+
+	ret = test_iosched_add_wr_rd_test_req(0, READ, start_sec,
+			num_bios, TEST_PATTERN_5A, NULL);
+
+	if (ret) {
+		test_pr_err("%s: failed to add a read request", __func__);
+		return ret;
+	}
+
+	blk_run_queue(q);
+	return ret;
+}
+
+static
+int ufs_test_write_read_test_open_cb(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	message_repeat = 1;
+	test_pr_info("%s:UFS test initialized", __func__);
+	return 0;
+}
+
+static ssize_t ufs_test_write_read_test_write_cb(struct file *file,
+					const char __user *buf,
+					size_t count, loff_t *ppos)
+{
+	int ret = 0;
+	int i;
+	int number;
+
+	sscanf(buf, "%d", &number);
+
+	if (number <= 0)
+		number = 1;
+
+	test_pr_info("%s:the test will run for %d iterations.",
+			__func__, number);
+	memset(&utd->test_info, 0, sizeof(struct test_info));
+
+	/* Initializing test */
+	utd->test_info.data = utd;
+	utd->test_info.get_test_case_str_fn = ufs_test_get_test_case_str;
+	utd->test_info.testcase = UFS_TEST_WRITE_READ_TEST;
+	utd->test_info.get_rq_disk_fn = ufs_test_get_rq_disk;
+	utd->test_info.run_test_fn = ufs_test_run_write_read_test;
+
+	/* Running the test multiple times */
+	for (i = 0; i < number; ++i) {
+		ret = test_iosched_start_test(&utd->test_info);
+		if (ret) {
+			test_pr_err("%s: Test failed.", __func__);
+			return ret;
+		}
+	}
+
+	test_pr_info("%s: Completed all the ufs test iterations.", __func__);
+
+	return count;
+}
+
+static ssize_t ufs_test_write_read_test_read_cb(struct file *file,
+		char __user *buffer, size_t count, loff_t *offset)
+{
+	memset((void *) buffer, 0, count);
+
+	snprintf(buffer, count, "\nThis is a UFS write-read test for debug.\n");
+
+	if (message_repeat == 1) {
+		message_repeat = 0;
+		return strnlen(buffer, count);
+	} else
+		return 0;
+}
+
+const struct file_operations write_read_test_ops = {
+		.open = ufs_test_write_read_test_open_cb,
+		.write = ufs_test_write_read_test_write_cb,
+		.read = ufs_test_write_read_test_read_cb,
+};
+
+static void ufs_test_debugfs_cleanup(void)
+{
+	debugfs_remove(utd->debug.write_read_test);
+}
+
+static int ufs_test_debugfs_init(void)
+{
+	struct dentry *utils_root, *tests_root;
+
+	utils_root = test_iosched_get_debugfs_utils_root();
+	tests_root = test_iosched_get_debugfs_tests_root();
+
+	if (!utils_root || !tests_root) {
+		test_pr_err("%s: Failed to create debugfs root.", __func__);
+		return -EINVAL;
+	}
+
+	utd->debug.random_test_seed = debugfs_create_u32("random_test_seed",
+			S_IRUGO | S_IWUGO, utils_root, &utd->random_test_seed);
+
+	if (!utd->debug.random_test_seed) {
+		test_pr_err("%s: Could not create debugfs random_test_seed.",
+				__func__);
+		return -ENOMEM;
+	}
+
+	utd->debug.write_read_test = debugfs_create_file("write_read_test",
+					S_IRUGO | S_IWUGO, tests_root,
+					NULL, &write_read_test_ops);
+
+	if (!utd->debug.write_read_test) {
+		debugfs_remove(utd->debug.random_test_seed);
+		test_pr_err("%s: Could not create debugfs write_read_test.",
+				__func__);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void ufs_test_probe(void)
+{
+	ufs_test_debugfs_init();
+}
+
+static void ufs_test_remove(void)
+{
+	ufs_test_debugfs_cleanup();
+}
+
+int __init ufs_test_init(void)
+{
+	utd = kzalloc(sizeof(struct ufs_test_data), GFP_KERNEL);
+	if (!utd) {
+		test_pr_err("%s: failed to allocate ufs_test_data", __func__);
+		return -ENODEV;
+	}
+
+	init_waitqueue_head(&utd->wait_q);
+	utd->bdt.init_fn = ufs_test_probe;
+	utd->bdt.exit_fn = ufs_test_remove;
+	INIT_LIST_HEAD(&utd->bdt.list);
+	test_iosched_register(&utd->bdt);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(ufs_test_init);
+
+static void __exit ufs_test_exit(void)
+{
+	test_iosched_unregister(&utd->bdt);
+	kfree(utd);
+}
+module_init(ufs_test_init)
+;
+module_exit(ufs_test_exit)
+;
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("UFC test");
+
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 52b96e8..58f4ba6 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -232,11 +232,11 @@
  *			      the host controller
  * @reg_hcs - host controller status register value
  *
- * Returns 0 if device present, non-zero if no device detected
+ * Returns 1 if device present, 0 if no device detected
  */
 static inline int ufshcd_is_device_present(u32 reg_hcs)
 {
-	return (DEVICE_PRESENT & reg_hcs) ? 0 : -1;
+	return (DEVICE_PRESENT & reg_hcs) ? 1 : 0;
 }
 
 /**
@@ -911,7 +911,7 @@
 
 	/* check if device present */
 	reg = readl((hba->mmio_base + REG_CONTROLLER_STATUS));
-	if (ufshcd_is_device_present(reg)) {
+	if (!ufshcd_is_device_present(reg)) {
 		dev_err(&hba->pdev->dev, "cc: Device not present\n");
 		err = -ENXIO;
 		goto out;
@@ -1032,11 +1032,11 @@
 		return -EIO;
 
 	/* Configure UTRL and UTMRL base address registers */
-	writel(hba->utrdl_dma_addr,
-	       (hba->mmio_base + REG_UTP_TRANSFER_REQ_LIST_BASE_L));
 	writel(lower_32_bits(hba->utrdl_dma_addr),
+	       (hba->mmio_base + REG_UTP_TRANSFER_REQ_LIST_BASE_L));
+	writel(upper_32_bits(hba->utrdl_dma_addr),
 	       (hba->mmio_base + REG_UTP_TRANSFER_REQ_LIST_BASE_H));
-	writel(hba->utmrdl_dma_addr,
+	writel(lower_32_bits(hba->utmrdl_dma_addr),
 	       (hba->mmio_base + REG_UTP_TASK_REQ_LIST_BASE_L));
 	writel(upper_32_bits(hba->utmrdl_dma_addr),
 	       (hba->mmio_base + REG_UTP_TASK_REQ_LIST_BASE_H));
@@ -1160,9 +1160,11 @@
 		task_result = be32_to_cpu(task_rsp_upiup->header.dword_1);
 		task_result = ((task_result & MASK_TASK_RESPONSE) >> 8);
 
-		if (task_result != UPIU_TASK_MANAGEMENT_FUNC_COMPL ||
+		if (task_result != UPIU_TASK_MANAGEMENT_FUNC_COMPL &&
 		    task_result != UPIU_TASK_MANAGEMENT_FUNC_SUCCEEDED)
 			task_result = FAILED;
+		else
+			task_result = SUCCESS;
 	} else {
 		task_result = FAILED;
 		dev_err(&hba->pdev->dev,
@@ -1556,7 +1558,7 @@
 		goto out;
 	}
 	clear_bit(free_slot, &hba->tm_condition);
-	return ufshcd_task_req_compl(hba, free_slot);
+	err = ufshcd_task_req_compl(hba, free_slot);
 out:
 	return err;
 }
@@ -1580,7 +1582,7 @@
 	tag = cmd->request->tag;
 
 	err = ufshcd_issue_tm_cmd(hba, &hba->lrb[tag], UFS_LOGICAL_RESET);
-	if (err)
+	if (err == FAILED)
 		goto out;
 
 	for (pos = 0; pos < hba->nutrs; pos++) {
@@ -1620,7 +1622,7 @@
 	if (hba->ufshcd_state == UFSHCD_STATE_RESET)
 		return SUCCESS;
 
-	return (ufshcd_do_reset(hba) == SUCCESS) ? SUCCESS : FAILED;
+	return ufshcd_do_reset(hba);
 }
 
 /**
@@ -1652,7 +1654,7 @@
 	spin_unlock_irqrestore(host->host_lock, flags);
 
 	err = ufshcd_issue_tm_cmd(hba, &hba->lrb[tag], UFS_ABORT_TASK);
-	if (err)
+	if (err == FAILED)
 		goto out;
 
 	scsi_dma_unmap(cmd);
@@ -1836,7 +1838,7 @@
 	err = pci_request_regions(pdev, UFSHCD);
 	if (err < 0) {
 		dev_err(&pdev->dev, "request regions failed\n");
-		goto out_disable;
+		goto out_host_put;
 	}
 
 	hba->mmio_base = pci_ioremap_bar(pdev, 0);
@@ -1925,8 +1927,9 @@
 	iounmap(hba->mmio_base);
 out_release_regions:
 	pci_release_regions(pdev);
-out_disable:
+out_host_put:
 	scsi_host_put(host);
+out_disable:
 	pci_clear_master(pdev);
 	pci_disable_device(pdev);
 out_error:
@@ -1952,24 +1955,7 @@
 #endif
 };
 
-/**
- * ufshcd_init - Driver registration routine
- */
-static int __init ufshcd_init(void)
-{
-	return pci_register_driver(&ufshcd_pci_driver);
-}
-module_init(ufshcd_init);
-
-/**
- * ufshcd_exit - Driver exit clean-up routine
- */
-static void __exit ufshcd_exit(void)
-{
-	pci_unregister_driver(&ufshcd_pci_driver);
-}
-module_exit(ufshcd_exit);
-
+module_pci_driver(ufshcd_pci_driver);
 
 MODULE_AUTHOR("Santosh Yaragnavi <santosh.sy@samsung.com>, "
 	      "Vinayak Holikatti <h.vinayak@samsung.com>");
diff --git a/drivers/slimbus/slim-msm-ctrl.c b/drivers/slimbus/slim-msm-ctrl.c
index 9c69f47..9b0b8b4 100644
--- a/drivers/slimbus/slim-msm-ctrl.c
+++ b/drivers/slimbus/slim-msm-ctrl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -1061,7 +1061,7 @@
 			dev_err(dev->dev, "rx thread wait error:%d", ret);
 
 		/* 1 irq notification per message */
-		if (!dev->use_rx_msgqs) {
+		if (dev->use_rx_msgqs != MSM_MSGQ_ENABLED) {
 			msm_slim_rxwq(dev);
 			continue;
 		}
@@ -1255,9 +1255,9 @@
 	spin_lock_init(&dev->rx_lock);
 	dev->ee = 1;
 	if (rxreg_access)
-		dev->use_rx_msgqs = 0;
+		dev->use_rx_msgqs = MSM_MSGQ_DISABLED;
 	else
-		dev->use_rx_msgqs = 1;
+		dev->use_rx_msgqs = MSM_MSGQ_RESET;
 
 	dev->irq = irq->start;
 	dev->bam.irq = bam_irq->start;
@@ -1328,7 +1328,7 @@
 	 * Manager register initialization
 	 * If RX msg Q is used, disable RX_MSG_RCVD interrupt
 	 */
-	if (dev->use_rx_msgqs)
+	if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED)
 		writel_relaxed((MGR_INT_RECFG_DONE | MGR_INT_TX_NACKED_2 |
 			MGR_INT_MSG_BUF_CONTE | /* MGR_INT_RX_MSG_RCVD | */
 			MGR_INT_TX_MSG_SENT), dev->base + MGR_INT_EN);
@@ -1357,7 +1357,7 @@
 	mb();
 
 	/* Enable RX msg Q */
-	if (dev->use_rx_msgqs)
+	if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED)
 		writel_relaxed(MGR_CFG_ENABLE | MGR_CFG_RX_MSGQ_EN,
 					dev->base + MGR_CFG);
 	else
@@ -1409,7 +1409,7 @@
 err_request_irq_failed:
 	kthread_stop(dev->rx_msgq_thread);
 err_thread_create_failed:
-	msm_slim_sps_exit(dev);
+	msm_slim_sps_exit(dev, true);
 err_sps_init_failed:
 	if (dev->hclk) {
 		clk_disable_unprepare(dev->hclk);
@@ -1453,7 +1453,7 @@
 	clk_put(dev->rclk);
 	if (dev->hclk)
 		clk_put(dev->hclk);
-	msm_slim_sps_exit(dev);
+	msm_slim_sps_exit(dev, true);
 	kthread_stop(dev->rx_msgq_thread);
 	iounmap(dev->bam.base);
 	iounmap(dev->base);
diff --git a/drivers/slimbus/slim-msm-ngd.c b/drivers/slimbus/slim-msm-ngd.c
index 78e8a6f..10c69c3 100644
--- a/drivers/slimbus/slim-msm-ngd.c
+++ b/drivers/slimbus/slim-msm-ngd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -33,6 +33,7 @@
 #define NGD_SLIM_NAME	"ngd_msm_ctrl"
 #define SLIM_LA_MGR	0xFF
 #define SLIM_ROOT_FREQ	24576000
+#define LADDR_RETRY	5
 
 #define NGD_BASE_V1(r)	(((r) % 2) ? 0x800 : 0xA00)
 #define NGD_BASE_V2(r)	(((r) % 2) ? 0x1000 : 0x2000)
@@ -78,6 +79,12 @@
 	NGD_TX_BUSY		= 0x0,
 };
 
+enum ngd_status {
+	NGD_LADDR		= 1 << 1,
+};
+
+static int ngd_slim_runtime_resume(struct device *device);
+
 static irqreturn_t ngd_slim_interrupt(int irq, void *d)
 {
 	struct msm_slim_ctrl *dev = (struct msm_slim_ctrl *)d;
@@ -122,7 +129,7 @@
 		 * queuing work
 		 */
 		mb();
-		if (dev->use_rx_msgqs)
+		if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED)
 			dev_err(dev->dev,
 				"direct message received even with RX MSGQs");
 		else
@@ -144,23 +151,24 @@
 	return IRQ_HANDLED;
 }
 
-static int ngd_clk_pause_wakeup(struct slim_controller *ctrl)
-{
-	struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl);
-	return msm_slim_qmi_power_request(dev, true);
-}
-
 static int ngd_qmi_available(struct notifier_block *n, unsigned long code,
 				void *_cmd)
 {
 	struct msm_slim_qmi *qmi = container_of(n, struct msm_slim_qmi, nb);
+	struct msm_slim_ctrl *dev =
+		container_of(qmi, struct msm_slim_ctrl, qmi);
 	pr_info("Slimbus QMI NGD CB received event:%ld", code);
 	switch (code) {
 	case QMI_SERVER_ARRIVE:
-		complete(&qmi->qmi_comp);
+		schedule_work(&qmi->ssr_up);
 		break;
 	case QMI_SERVER_EXIT:
-		/* SSR implementation */
+		dev->state = MSM_CTRL_DOWN;
+		/* make sure autosuspend is not called until ADSP comes up*/
+		pm_runtime_get_noresume(dev->dev);
+		/* Reset ctrl_up completion */
+		init_completion(&dev->ctrl_up);
+		schedule_work(&qmi->ssr_down);
 		break;
 	default:
 		break;
@@ -216,9 +224,29 @@
 	u8 la = txn->la;
 	u8 wbuf[SLIM_RX_MSGQ_BUF_LEN];
 
+	if (!pm_runtime_enabled(dev->dev) && dev->state == MSM_CTRL_ASLEEP &&
+			txn->mc != SLIM_USR_MC_REPORT_SATELLITE) {
+		/*
+		 * Counter-part of system-suspend when runtime-pm is not enabled
+		 * This way, resume can be left empty and device will be put in
+		 * active mode only if client requests anything on the bus
+		 * If the state was DOWN, SSR UP notification will take
+		 * care of putting the device in active state.
+		 */
+		ngd_slim_runtime_resume(dev->dev);
+	}
 	if (txn->mc == (SLIM_MSG_CLK_PAUSE_SEQ_FLG |
-			SLIM_MSG_MC_RECONFIGURE_NOW))
-		return msm_slim_qmi_power_request(dev, false);
+			SLIM_MSG_MC_RECONFIGURE_NOW)) {
+		if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED) {
+			ret = sps_disconnect(dev->rx_msgq.sps);
+			dev->use_rx_msgqs = MSM_MSGQ_RESET;
+		}
+		if (!ret)
+			ret = msm_slim_qmi_power_request(dev, false);
+		else
+			pr_err("SPS pipe disconnect error:%d", ret);
+		return ret;
+	}
 	else if (txn->mc & SLIM_MSG_CLK_PAUSE_SEQ_FLG)
 		return 0;
 
@@ -227,22 +255,43 @@
 		 txn->mc <= SLIM_MSG_MC_RECONFIGURE_NOW)) {
 		return 0;
 	}
-	msm_slim_get_ctrl(dev);
+	/* If txn is tried when controller is down, wait for ADSP to boot */
+	if (txn->mc != SLIM_USR_MC_REPORT_SATELLITE) {
+		if (dev->state == MSM_CTRL_DOWN) {
+			u8 mc = (u8)txn->mc;
+			int timeout;
+			dev_err(dev->dev, "ADSP slimbus not up yet");
+			/*
+			 * Messages related to data channel management can't
+			 * wait since they are holding reconfiguration lock.
+			 * clk_pause in resume (which can change state back to
+			 * MSM_CTRL_AWAKE), will need that lock
+			 */
+			if ((txn->mt == SLIM_MSG_MT_CORE) &&
+				((mc >= SLIM_MSG_MC_CONNECT_SOURCE &&
+				mc <= SLIM_MSG_MC_CHANGE_CONTENT) ||
+				(mc >= SLIM_MSG_MC_BEGIN_RECONFIGURATION &&
+				mc <= SLIM_MSG_MC_RECONFIGURE_NOW)))
+				return -EREMOTEIO;
+			if ((txn->mt == SLIM_MSG_MT_DEST_REFERRED_USER) &&
+				((mc >= SLIM_USR_MC_DEFINE_CHAN &&
+				mc <= SLIM_USR_MC_DISCONNECT_PORT)))
+				return -EREMOTEIO;
+			timeout = wait_for_completion_timeout(&dev->ctrl_up,
+							HZ);
+			if (!timeout)
+				return -ETIMEDOUT;
+		}
+		msm_slim_get_ctrl(dev);
+	}
 	mutex_lock(&dev->tx_lock);
+
 	if (txn->mc != SLIM_USR_MC_REPORT_SATELLITE &&
-		(dev->state == MSM_CTRL_ASLEEP ||
-		dev->state == MSM_CTRL_SLEEPING)) {
-		int timeout;
+		(dev->state != MSM_CTRL_AWAKE)) {
 		dev_err(dev->dev, "controller not ready");
 		mutex_unlock(&dev->tx_lock);
-		/* Reconf is signalled when master responds */
-		timeout = wait_for_completion_timeout(&dev->reconf, HZ);
-		if (timeout) {
-			mutex_lock(&dev->tx_lock);
-		} else {
-			msm_slim_put_ctrl(dev);
-			return -EBUSY;
-		}
+		msm_slim_put_ctrl(dev);
+		return -EREMOTEIO;
 	}
 	if (txn->mt == SLIM_MSG_MT_CORE &&
 		(txn->mc == SLIM_MSG_MC_CONNECT_SOURCE ||
@@ -370,24 +419,23 @@
 		mutex_unlock(&dev->tx_lock);
 		msm_slim_put_ctrl(dev);
 		timeout = wait_for_completion_timeout(txn->comp, HZ);
-		if (!timeout) {
-			pr_err("connect/disc :0x%x, tid:%d timed out", txn->mc,
-					txn->tid);
+		if (!timeout)
 			ret = -ETIMEDOUT;
+		else
+			ret = txn->ec;
+		if (ret) {
+			pr_err("connect/disconnect:0x%x,tid:%d err:%d", txn->mc,
+					txn->tid, ret);
 			mutex_lock(&ctrl->m_ctrl);
 			ctrl->txnt[txn->tid] = NULL;
 			mutex_unlock(&ctrl->m_ctrl);
-		} else {
-			ret = txn->ec;
 		}
-		if (ret)
-			pr_err("connect/disconnect:0x%x,tid:%d err:%d", txn->mc,
-					txn->tid, ret);
 		return ret ? ret : dev->err;
 	}
 ngd_xfer_err:
 	mutex_unlock(&dev->tx_lock);
-	msm_slim_put_ctrl(dev);
+	if (txn->mc != SLIM_USR_MC_REPORT_SATELLITE)
+		msm_slim_put_ctrl(dev);
 	return ret ? ret : dev->err;
 }
 
@@ -398,20 +446,18 @@
 	if (!ret) {
 		int timeout;
 		timeout = wait_for_completion_timeout(txn->comp, HZ);
-		if (!timeout) {
-			pr_err("master req:0x%x, tid:%d timed out", txn->mc,
-					txn->tid);
+		if (!timeout)
 			ret = -ETIMEDOUT;
-			mutex_lock(&ctrl->m_ctrl);
-			ctrl->txnt[txn->tid] = NULL;
-			mutex_unlock(&ctrl->m_ctrl);
-		} else {
+		else
 			ret = txn->ec;
-		}
 	}
-	if (ret)
+	if (ret) {
 		pr_err("master msg:0x%x,tid:%d ret:%d", txn->mc,
 				txn->tid, ret);
+		mutex_lock(&ctrl->m_ctrl);
+		ctrl->txnt[txn->tid] = NULL;
+		mutex_unlock(&ctrl->m_ctrl);
+	}
 
 	return ret;
 }
@@ -517,7 +563,7 @@
 			return ret;
 		txn.len = 0;
 	}
-	return ret;
+	return 0;
 }
 
 static int ngd_set_laddr(struct slim_controller *ctrl, const u8 *ea,
@@ -555,6 +601,24 @@
 	return ret;
 }
 
+static void ngd_slim_setup_rx_path(struct msm_slim_ctrl *dev)
+{
+	int ret;
+	if (dev->state == MSM_CTRL_DOWN) {
+		msm_slim_sps_init(dev, dev->bam_mem,
+			NGD_BASE(dev->ctrl.nr,
+			dev->ver) + NGD_STATUS, true);
+	} else {
+		if (dev->use_rx_msgqs == MSM_MSGQ_DISABLED)
+			return;
+		ret = msm_slim_connect_endp(dev, &dev->rx_msgq,
+				&dev->rx_msgq_notify);
+		if (!ret)
+			dev->use_rx_msgqs = MSM_MSGQ_ENABLED;
+		else
+			pr_err("RX msgq not being used:%d", ret);
+	}
+}
 static void ngd_slim_rx(struct msm_slim_ctrl *dev, u8 *buf)
 {
 	u8 mc, mt, len;
@@ -582,26 +646,28 @@
 		txn.wbuf = wbuf;
 		txn.len = 4;
 		pr_info("SLIM SAT: Received master capability");
-		dev->use_rx_msgqs = 1;
-		msm_slim_sps_init(dev, dev->bam_mem,
-			NGD_BASE(dev->ctrl.nr, dev->ver) + NGD_STATUS, true);
-		if (dev->use_rx_msgqs)
-			msgq_en |= NGD_CFG_RX_MSGQ_EN;
-		writel_relaxed(msgq_en, dev->base +
-				NGD_BASE(dev->ctrl.nr, dev->ver));
-		/* make sure NGD MSG-Q config goes through */
-		mb();
+		if (dev->state >= MSM_CTRL_ASLEEP) {
+			ngd_slim_setup_rx_path(dev);
+			if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED)
+				msgq_en |= NGD_CFG_RX_MSGQ_EN;
+			writel_relaxed(msgq_en, dev->base +
+					NGD_BASE(dev->ctrl.nr, dev->ver));
+			/* make sure NGD MSG-Q config goes through */
+			mb();
+		}
 
 		ret = ngd_xfer_msg(&dev->ctrl, &txn);
 		if (!ret) {
+			enum msm_ctrl_state prev_state = dev->state;
 			dev->state = MSM_CTRL_AWAKE;
-
-			pm_runtime_use_autosuspend(dev->dev);
-			pm_runtime_set_autosuspend_delay(dev->dev,
-							MSM_SLIM_AUTOSUSPEND);
-			pm_runtime_set_active(dev->dev);
-			pm_runtime_enable(dev->dev);
-			complete(&dev->reconf);
+			if (prev_state >= MSM_CTRL_ASLEEP)
+				complete(&dev->reconf);
+			else
+				pr_err("SLIM: unexpected capability, state:%d",
+					prev_state);
+			/* ADSP SSR, send device_up notifications */
+			if (prev_state == MSM_CTRL_DOWN)
+				schedule_work(&dev->slave_notify);
 		}
 	}
 	if (mc == SLIM_MSG_MC_REPLY_INFORMATION ||
@@ -654,38 +720,114 @@
 	}
 }
 
-static int ngd_slim_enable(struct msm_slim_ctrl *dev, bool enable)
+static int ngd_slim_power_up(struct msm_slim_ctrl *dev)
 {
-	u32 ngd_int = (NGD_INT_RECFG_DONE | NGD_INT_TX_NACKED_2 |
+	void __iomem *ngd;
+	int timeout, ret;
+	enum msm_ctrl_state cur_state = dev->state;
+	u32 laddr;
+	u32 ngd_int = (NGD_INT_TX_NACKED_2 |
 			NGD_INT_MSG_BUF_CONTE | NGD_INT_MSG_TX_INVAL |
 			NGD_INT_IE_VE_CHG | NGD_INT_DEV_ERR |
 			NGD_INT_TX_MSG_SENT | NGD_INT_RX_MSG_RCVD);
-	if (enable) {
-		int ret = msm_slim_qmi_init(dev, false);
-		if (ret)
-			return ret;
-		ret = msm_slim_qmi_power_request(dev, true);
-		if (ret)
-			return ret;
-		writel_relaxed(ngd_int, dev->base + NGD_INT_EN +
-					NGD_BASE(dev->ctrl.nr, dev->ver));
+
+	if (cur_state == MSM_CTRL_DOWN) {
+		int timeout = wait_for_completion_timeout(&dev->qmi.qmi_comp,
+						HZ);
+		if (!timeout)
+			pr_err("slimbus QMI init timed out");
+	}
+
+	ret = msm_slim_qmi_power_request(dev, true);
+	if (ret) {
+		pr_err("SLIM QMI power request failed:%d", ret);
+		return ret;
+	}
+	if (!dev->ver) {
+		dev->ver = readl_relaxed(dev->base);
+		/* Version info in 16 MSbits */
+		dev->ver >>= 16;
+	}
+	ngd = dev->base + NGD_BASE(dev->ctrl.nr, dev->ver);
+	laddr = readl_relaxed(ngd + NGD_STATUS);
+	if (laddr & NGD_LADDR) {
 		/*
-		 * Enable NGD. Configure NGD in register acc. mode until master
-		 * announcement is received
+		 * ADSP power collapse case, where HW wasn't reset.
+		 * Reconnect BAM pipes if disconnected
 		 */
-		writel_relaxed(1, dev->base + NGD_BASE(dev->ctrl.nr, dev->ver));
-		/* make sure NGD enabling goes through */
-		mb();
-	} else {
-		writel_relaxed(0, dev->base + NGD_BASE(dev->ctrl.nr, dev->ver));
-		writel_relaxed(0, dev->base + NGD_INT_EN +
+		ngd_slim_setup_rx_path(dev);
+		return 0;
+	} else if (cur_state != MSM_CTRL_DOWN) {
+		pr_info("ADSP P.C. CTRL state:%d NGD not enumerated:0x%x",
+					dev->state, laddr);
+	}
+
+	/*
+	 * ADSP power collapse case (OR SSR), where HW was reset
+	 * BAM programming will happen when capability message is received
+	 */
+	writel_relaxed(ngd_int, dev->base + NGD_INT_EN +
 				NGD_BASE(dev->ctrl.nr, dev->ver));
-		/* make sure NGD disabling goes through */
-		mb();
+	/*
+	 * Enable NGD. Configure NGD in register acc. mode until master
+	 * announcement is received
+	 */
+	writel_relaxed(1, dev->base + NGD_BASE(dev->ctrl.nr, dev->ver));
+	/* make sure NGD enabling goes through */
+	mb();
+
+	timeout = wait_for_completion_timeout(&dev->reconf, HZ);
+	if (!timeout) {
+		pr_err("failed to received master capability");
+		return -ETIMEDOUT;
+	}
+	if (cur_state == MSM_CTRL_DOWN)
+		complete(&dev->ctrl_up);
+	return 0;
+}
+
+static int ngd_slim_enable(struct msm_slim_ctrl *dev, bool enable)
+{
+	int ret = 0;
+	if (enable) {
+		ret = msm_slim_qmi_init(dev, false);
+		/* controller state should be in sync with framework state */
+		if (!ret) {
+			ret = slim_ctrl_clk_pause(&dev->ctrl, false,
+						SLIM_CLK_UNSPECIFIED);
+			complete(&dev->qmi.qmi_comp);
+			/*
+			 * Power-up won't be called if clock pause failed.
+			 * This can happen if ADSP SSR happened when audio
+			 * session is in progress. Framework will think that
+			 * clock pause failed so no need to wakeup controller.
+			 * Call power-up explicitly in that case, since slimbus
+			 * HW needs to be powered-on to be in sync with
+			 * framework state
+			 */
+			if (ret)
+				ngd_slim_power_up(dev);
+			if (!pm_runtime_enabled(dev->dev) ||
+					!pm_runtime_suspended(dev->dev))
+				ngd_slim_runtime_resume(dev->dev);
+			else
+				pm_runtime_resume(dev->dev);
+			pm_runtime_mark_last_busy(dev->dev);
+			pm_runtime_put(dev->dev);
+		} else
+			dev_err(dev->dev, "qmi init fail, ret:%d, state:%d",
+					ret, dev->state);
+	} else {
 		msm_slim_qmi_exit(dev);
 	}
 
-	return 0;
+	return ret;
+}
+
+static int ngd_clk_pause_wakeup(struct slim_controller *ctrl)
+{
+	struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl);
+	return ngd_slim_power_up(dev);
 }
 
 static int ngd_slim_rx_msgq_thread(void *data)
@@ -698,14 +840,6 @@
 	u32 buffer[10];
 	u8 msg_len = 0;
 
-	wait_for_completion_interruptible(&dev->qmi.qmi_comp);
-	ret = ngd_slim_enable(dev, true);
-	/* Exit the thread if component can't be enabled */
-	if (ret) {
-		pr_err("Enabling NGD failed:%d", ret);
-		return 0;
-	}
-
 	while (!kthread_should_stop()) {
 		set_current_state(TASK_INTERRUPTIBLE);
 		ret = wait_for_completion_interruptible(notify);
@@ -714,7 +848,7 @@
 			continue;
 		}
 		/* 1 irq notification per message */
-		if (!dev->use_rx_msgqs) {
+		if (dev->use_rx_msgqs != MSM_MSGQ_ENABLED) {
 			msm_slim_rx_dequeue(dev, (u8 *)buffer);
 			ngd_slim_rx(dev, (u8 *)buffer);
 			continue;
@@ -741,6 +875,63 @@
 	return 0;
 }
 
+static void ngd_laddr_lookup(struct work_struct *work)
+{
+	struct msm_slim_ctrl *dev =
+		container_of(work, struct msm_slim_ctrl, slave_notify);
+	struct slim_controller *ctrl = &dev->ctrl;
+	struct slim_device *sbdev;
+	int i;
+	mutex_lock(&ctrl->m_ctrl);
+	list_for_each_entry(sbdev, &ctrl->devs, dev_list) {
+		int ret = 0;
+		mutex_unlock(&ctrl->m_ctrl);
+		for (i = 0; i < LADDR_RETRY; i++) {
+			ret = slim_get_logical_addr(sbdev, sbdev->e_addr,
+					6, &sbdev->laddr);
+			if (!ret)
+				break;
+			else /* time for ADSP to assign LA */
+				msleep(20);
+		}
+		mutex_lock(&ctrl->m_ctrl);
+	}
+	mutex_unlock(&ctrl->m_ctrl);
+}
+
+static void ngd_adsp_down(struct work_struct *work)
+{
+	struct msm_slim_qmi *qmi =
+		container_of(work, struct msm_slim_qmi, ssr_down);
+	struct msm_slim_ctrl *dev =
+		container_of(qmi, struct msm_slim_ctrl, qmi);
+	struct slim_controller *ctrl = &dev->ctrl;
+	struct slim_device *sbdev;
+	int i;
+
+	ngd_slim_enable(dev, false);
+	/* disconnect BAM pipes */
+	msm_slim_sps_exit(dev, false);
+	mutex_lock(&ctrl->m_ctrl);
+	/* device up should be called again after SSR */
+	list_for_each_entry(sbdev, &ctrl->devs, dev_list)
+		sbdev->notified = false;
+	/* invalidate logical addresses */
+	for (i = 0; i < ctrl->num_dev; i++)
+		ctrl->addrt[i].valid = false;
+	mutex_unlock(&ctrl->m_ctrl);
+	pr_info("SLIM ADSP SSR (DOWN) done");
+}
+
+static void ngd_adsp_up(struct work_struct *work)
+{
+	struct msm_slim_qmi *qmi =
+		container_of(work, struct msm_slim_qmi, ssr_up);
+	struct msm_slim_ctrl *dev =
+		container_of(qmi, struct msm_slim_ctrl, qmi);
+	ngd_slim_enable(dev, true);
+}
+
 static int __devinit ngd_slim_probe(struct platform_device *pdev)
 {
 	struct msm_slim_ctrl *dev;
@@ -749,6 +940,7 @@
 	struct resource		*slim_mem;
 	struct resource		*irq, *bam_irq;
 	enum apr_subsys_state q6_state;
+	bool			rxreg_access = false;
 
 	q6_state = apr_get_q6_state();
 	if (q6_state == APR_SUBSYS_DOWN) {
@@ -811,6 +1003,8 @@
 			dev_err(&pdev->dev, "Cell index not specified:%d", ret);
 			goto err_ctrl_failed;
 		}
+		rxreg_access = of_property_read_bool(pdev->dev.of_node,
+					"qcom,rxreg-access");
 	} else {
 		dev->ctrl.nr = pdev->id;
 	}
@@ -834,15 +1028,17 @@
 	dev->bam_mem = bam_mem;
 
 	init_completion(&dev->reconf);
+	init_completion(&dev->ctrl_up);
 	mutex_init(&dev->tx_lock);
 	spin_lock_init(&dev->rx_lock);
 	dev->ee = 1;
 	dev->irq = irq->start;
 	dev->bam.irq = bam_irq->start;
 
-	dev->ver = readl_relaxed(dev->base);
-	/* Version info in 16 MSbits */
-	dev->ver >>= 16;
+	if (rxreg_access)
+		dev->use_rx_msgqs = MSM_MSGQ_DISABLED;
+	else
+		dev->use_rx_msgqs = MSM_MSGQ_RESET;
 	init_completion(&dev->rx_msgq_notify);
 
 	/* Register with framework */
@@ -854,7 +1050,7 @@
 
 	dev->ctrl.dev.parent = &pdev->dev;
 	dev->ctrl.dev.of_node = pdev->dev.of_node;
-	dev->state = MSM_CTRL_ASLEEP;
+	dev->state = MSM_CTRL_DOWN;
 
 	ret = request_irq(dev->irq, ngd_slim_interrupt,
 			IRQF_TRIGGER_HIGH, "ngd_slim_irq", dev);
@@ -865,7 +1061,16 @@
 	}
 
 	init_completion(&dev->qmi.qmi_comp);
+	pm_runtime_use_autosuspend(dev->dev);
+	pm_runtime_set_autosuspend_delay(dev->dev, MSM_SLIM_AUTOSUSPEND);
+	pm_runtime_set_suspended(dev->dev);
+	pm_runtime_enable(dev->dev);
+
+	INIT_WORK(&dev->slave_notify, ngd_laddr_lookup);
+	INIT_WORK(&dev->qmi.ssr_down, ngd_adsp_down);
+	INIT_WORK(&dev->qmi.ssr_up, ngd_adsp_up);
 	dev->qmi.nb.notifier_call = ngd_qmi_available;
+	pm_runtime_get_noresume(dev->dev);
 	ret = qmi_svc_event_notifier_register(SLIMBUS_QMI_SVC_ID,
 				SLIMBUS_QMI_INS_ID, &dev->qmi.nb);
 	if (ret) {
@@ -873,6 +1078,7 @@
 		goto qmi_register_failed;
 	}
 
+
 	/* Fire up the Rx message queue thread */
 	dev->rx_msgq_thread = kthread_run(ngd_slim_rx_msgq_thread, dev,
 					NGD_SLIM_NAME "_ngd_msgq_thread");
@@ -914,7 +1120,6 @@
 	qmi_svc_event_notifier_unregister(SLIMBUS_QMI_SVC_ID,
 				SLIMBUS_QMI_INS_ID, &dev->qmi.nb);
 	pm_runtime_disable(&pdev->dev);
-	pm_runtime_set_suspended(&pdev->dev);
 	free_irq(dev->irq, dev);
 	slim_del_controller(&dev->ctrl);
 	kthread_stop(dev->rx_msgq_thread);
@@ -938,31 +1143,12 @@
  * functions to be called from system suspend/resume. So they are not
  * inside ifdef CONFIG_PM_RUNTIME
  */
-#ifdef CONFIG_PM_SLEEP
-static int ngd_slim_runtime_suspend(struct device *device)
-{
-	struct platform_device *pdev = to_platform_device(device);
-	struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
-	int ret;
-	dev_dbg(device, "pm_runtime: suspending...\n");
-	dev->state = MSM_CTRL_SLEEPING;
-	ret = slim_ctrl_clk_pause(&dev->ctrl, false, SLIM_CLK_UNSPECIFIED);
-	if (ret) {
-		dev_err(device, "clk pause not entered:%d", ret);
-		dev->state = MSM_CTRL_AWAKE;
-	} else {
-		dev->state = MSM_CTRL_ASLEEP;
-	}
-	return ret;
-}
-
 static int ngd_slim_runtime_resume(struct device *device)
 {
 	struct platform_device *pdev = to_platform_device(device);
 	struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
 	int ret = 0;
-	dev_dbg(device, "pm_runtime: resuming...\n");
-	if (dev->state == MSM_CTRL_ASLEEP)
+	if (dev->state >= MSM_CTRL_ASLEEP)
 		ret = slim_ctrl_clk_pause(&dev->ctrl, true, 0);
 	if (ret) {
 		dev_err(device, "clk pause not exited:%d", ret);
@@ -973,12 +1159,43 @@
 	return ret;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int ngd_slim_runtime_suspend(struct device *device)
+{
+	struct platform_device *pdev = to_platform_device(device);
+	struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
+	int ret = 0;
+	dev->state = MSM_CTRL_SLEEPING;
+	ret = slim_ctrl_clk_pause(&dev->ctrl, false, SLIM_CLK_UNSPECIFIED);
+	if (ret) {
+		if (ret != -EBUSY)
+			dev_err(device, "clk pause not entered:%d", ret);
+		dev->state = MSM_CTRL_AWAKE;
+	} else {
+		dev->state = MSM_CTRL_ASLEEP;
+	}
+	return ret;
+}
+
 static int ngd_slim_suspend(struct device *dev)
 {
 	int ret = -EBUSY;
 	if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) {
 		dev_dbg(dev, "system suspend");
 		ret = ngd_slim_runtime_suspend(dev);
+		/*
+		 * If runtime-PM still thinks it's active, then make sure its
+		 * status is in sync with HW status.
+		 * Since this suspend calls QMI api, it results in holding a
+		 * wakelock. That results in failure of first suspend.
+		 * Subsequent suspend should not call low-power transition
+		 * again since the HW is already in suspended state.
+		 */
+		if (!ret) {
+			pm_runtime_disable(dev);
+			pm_runtime_set_suspended(dev);
+			pm_runtime_enable(dev);
+		}
 	}
 	if (ret == -EBUSY) {
 		/*
@@ -996,18 +1213,11 @@
 
 static int ngd_slim_resume(struct device *dev)
 {
-	/* If runtime_pm is enabled, this resume shouldn't do anything */
-	if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) {
-		int ret;
-		dev_dbg(dev, "system resume");
-		ret = ngd_slim_runtime_resume(dev);
-		if (!ret) {
-			pm_runtime_mark_last_busy(dev);
-			pm_request_autosuspend(dev);
-		}
-		return ret;
-
-	}
+	/*
+	 * Rely on runtime-PM to call resume in case it is enabled.
+	 * Even if it's not enabled, rely on 1st client transaction to do
+	 * clock/power on
+	 */
 	return 0;
 }
 #endif /* CONFIG_PM_SLEEP */
diff --git a/drivers/slimbus/slim-msm.c b/drivers/slimbus/slim-msm.c
index c62ac27..3e19f9b 100644
--- a/drivers/slimbus/slim-msm.c
+++ b/drivers/slimbus/slim-msm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -9,7 +9,6 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
-
 #include <linux/pm_runtime.h>
 #include <linux/dma-mapping.h>
 #include <linux/slimbus/slimbus.h>
@@ -378,53 +377,19 @@
 	return ret;
 }
 
-static int msm_slim_init_rx_msgq(struct msm_slim_ctrl *dev, u32 pipe_reg)
+int msm_slim_connect_endp(struct msm_slim_ctrl *dev,
+				struct msm_slim_endp *endpoint,
+				struct completion *notify)
 {
 	int i, ret;
-	u32 pipe_offset;
-	struct msm_slim_endp *endpoint = &dev->rx_msgq;
-	struct sps_connect *config = &endpoint->config;
-	struct sps_mem_buffer *descr = &config->desc;
-	struct sps_mem_buffer *mem = &endpoint->buf;
-	struct completion *notify = &dev->rx_msgq_notify;
-
 	struct sps_register_event sps_error_event; /* SPS_ERROR */
 	struct sps_register_event sps_descr_event; /* DESCR_DONE */
-
-	init_completion(notify);
-	if (!dev->use_rx_msgqs)
-		return 0;
-
-	/* Allocate the endpoint */
-	ret = msm_slim_init_endpoint(dev, endpoint);
-	if (ret) {
-		dev_err(dev->dev, "init_endpoint failed 0x%x\n", ret);
-		goto sps_init_endpoint_failed;
-	}
-
-	/* Get the pipe indices for the message queues */
-	pipe_offset = (readl_relaxed(dev->base + pipe_reg) & 0xfc) >> 2;
-	dev_dbg(dev->dev, "Message queue pipe offset %d\n", pipe_offset);
-
-	config->mode = SPS_MODE_SRC;
-	config->source = dev->bam.hdl;
-	config->destination = SPS_DEV_HANDLE_MEM;
-	config->src_pipe_index = pipe_offset;
-	config->options = SPS_O_DESC_DONE | SPS_O_ERROR |
-				SPS_O_ACK_TRANSFERS | SPS_O_AUTO_ENABLE;
-
-	/* Allocate memory for the FIFO descriptors */
-	ret = msm_slim_sps_mem_alloc(dev, descr,
-				MSM_SLIM_DESC_NUM * sizeof(struct sps_iovec));
-	if (ret) {
-		dev_err(dev->dev, "unable to allocate SPS descriptors\n");
-		goto alloc_descr_failed;
-	}
+	struct sps_connect *config = &endpoint->config;
 
 	ret = sps_connect(endpoint->sps, config);
 	if (ret) {
 		dev_err(dev->dev, "sps_connect failed 0x%x\n", ret);
-		goto sps_connect_failed;
+		return ret;
 	}
 
 	memset(&sps_descr_event, 0x00, sizeof(sps_descr_event));
@@ -453,13 +418,6 @@
 		goto sps_reg_event_failed;
 	}
 
-	/* Allocate memory for the message buffer(s), N descrs, 4-byte mesg */
-	ret = msm_slim_sps_mem_alloc(dev, mem, MSM_SLIM_DESC_NUM * 4);
-	if (ret) {
-		dev_err(dev->dev, "dma_alloc_coherent failed\n");
-		goto alloc_buffer_failed;
-	}
-
 	/*
 	 * Call transfer_one for each 4-byte buffer
 	 * Use (buf->size/4) - 1 for the number of buffer to post
@@ -475,20 +433,74 @@
 	}
 
 	return 0;
-
 sps_transfer_failed:
-	msm_slim_sps_mem_free(dev, mem);
-alloc_buffer_failed:
 	memset(&sps_error_event, 0x00, sizeof(sps_error_event));
 	sps_register_event(endpoint->sps, &sps_error_event);
 sps_reg_event_failed:
 	sps_disconnect(endpoint->sps);
-sps_connect_failed:
+	return ret;
+}
+static int msm_slim_init_rx_msgq(struct msm_slim_ctrl *dev, u32 pipe_reg)
+{
+	int ret;
+	u32 pipe_offset;
+	struct msm_slim_endp *endpoint = &dev->rx_msgq;
+	struct sps_connect *config = &endpoint->config;
+	struct sps_mem_buffer *descr = &config->desc;
+	struct sps_mem_buffer *mem = &endpoint->buf;
+	struct completion *notify = &dev->rx_msgq_notify;
+
+	init_completion(notify);
+	if (dev->use_rx_msgqs == MSM_MSGQ_DISABLED)
+		return 0;
+
+	/* Allocate the endpoint */
+	ret = msm_slim_init_endpoint(dev, endpoint);
+	if (ret) {
+		dev_err(dev->dev, "init_endpoint failed 0x%x\n", ret);
+		goto sps_init_endpoint_failed;
+	}
+
+	/* Get the pipe indices for the message queues */
+	pipe_offset = (readl_relaxed(dev->base + pipe_reg) & 0xfc) >> 2;
+	dev_dbg(dev->dev, "Message queue pipe offset %d\n", pipe_offset);
+
+	config->mode = SPS_MODE_SRC;
+	config->source = dev->bam.hdl;
+	config->destination = SPS_DEV_HANDLE_MEM;
+	config->src_pipe_index = pipe_offset;
+	config->options = SPS_O_DESC_DONE | SPS_O_ERROR |
+				SPS_O_ACK_TRANSFERS | SPS_O_AUTO_ENABLE;
+
+	/* Allocate memory for the FIFO descriptors */
+	ret = msm_slim_sps_mem_alloc(dev, descr,
+				MSM_SLIM_DESC_NUM * sizeof(struct sps_iovec));
+	if (ret) {
+		dev_err(dev->dev, "unable to allocate SPS descriptors\n");
+		goto alloc_descr_failed;
+	}
+
+	/* Allocate memory for the message buffer(s), N descrs, 4-byte mesg */
+	ret = msm_slim_sps_mem_alloc(dev, mem, MSM_SLIM_DESC_NUM * 4);
+	if (ret) {
+		dev_err(dev->dev, "dma_alloc_coherent failed\n");
+		goto alloc_buffer_failed;
+	}
+
+	ret = msm_slim_connect_endp(dev, endpoint, notify);
+
+	if (!ret) {
+		dev->use_rx_msgqs = MSM_MSGQ_ENABLED;
+		return 0;
+	}
+
+	msm_slim_sps_mem_free(dev, mem);
+alloc_buffer_failed:
 	msm_slim_sps_mem_free(dev, descr);
 alloc_descr_failed:
 	msm_slim_free_endpoint(endpoint);
 sps_init_endpoint_failed:
-	dev->use_rx_msgqs = 0;
+	dev->use_rx_msgqs = MSM_MSGQ_DISABLED;
 	return ret;
 }
 
@@ -517,6 +529,8 @@
 		},
 	};
 
+	if (dev->bam.hdl)
+		goto init_rx_msgq;
 	bam_props.ee = dev->ee;
 	bam_props.virt_addr = dev->bam.base;
 	bam_props.phys_addr = bam_mem->start;
@@ -548,7 +562,7 @@
 	ret = sps_register_bam_device(&bam_props, &bam_handle);
 	if (ret) {
 		dev_err(dev->dev, "disabling BAM: reg-bam failed 0x%x\n", ret);
-		dev->use_rx_msgqs = 0;
+		dev->use_rx_msgqs = MSM_MSGQ_DISABLED;
 		goto init_rx_msgq;
 	}
 	dev->bam.hdl = bam_handle;
@@ -565,9 +579,9 @@
 	return ret;
 }
 
-void msm_slim_sps_exit(struct msm_slim_ctrl *dev)
+void msm_slim_sps_exit(struct msm_slim_ctrl *dev, bool dereg)
 {
-	if (dev->use_rx_msgqs) {
+	if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED) {
 		struct msm_slim_endp *endpoint = &dev->rx_msgq;
 		struct sps_connect *config = &endpoint->config;
 		struct sps_mem_buffer *descr = &config->desc;
@@ -579,7 +593,11 @@
 		sps_disconnect(endpoint->sps);
 		msm_slim_sps_mem_free(dev, descr);
 		msm_slim_free_endpoint(endpoint);
+		dev->use_rx_msgqs = MSM_MSGQ_RESET;
+	}
+	if (dereg) {
 		sps_deregister_bam_device(dev->bam.hdl);
+		dev->bam.hdl = 0L;
 	}
 }
 
@@ -589,6 +607,11 @@
 #define SLIMBUS_QMI_POWER_REQ_V01 0x0021
 #define SLIMBUS_QMI_POWER_RESP_V01 0x0021
 
+#define SLIMBUS_QMI_POWER_REQ_MAX_MSG_LEN 7
+#define SLIMBUS_QMI_POWER_RESP_MAX_MSG_LEN 7
+#define SLIMBUS_QMI_SELECT_INSTANCE_REQ_MAX_MSG_LEN 14
+#define SLIMBUS_QMI_SELECT_INSTANCE_RESP_MAX_MSG_LEN 7
+
 enum slimbus_mode_enum_type_v01 {
 	/* To force a 32 bit signed enum. Do not change or use*/
 	SLIMBUS_MODE_ENUM_TYPE_MIN_ENUM_VAL_V01 = INT_MIN,
@@ -791,11 +814,11 @@
 	int rc;
 
 	req_desc.msg_id = SLIMBUS_QMI_SELECT_INSTANCE_REQ_V01;
-	req_desc.max_msg_len = sizeof(*req);
+	req_desc.max_msg_len = SLIMBUS_QMI_SELECT_INSTANCE_REQ_MAX_MSG_LEN;
 	req_desc.ei_array = slimbus_select_inst_req_msg_v01_ei;
 
 	resp_desc.msg_id = SLIMBUS_QMI_SELECT_INSTANCE_RESP_V01;
-	resp_desc.max_msg_len = sizeof(resp);
+	resp_desc.max_msg_len = SLIMBUS_QMI_SELECT_INSTANCE_RESP_MAX_MSG_LEN;
 	resp_desc.ei_array = slimbus_select_inst_resp_msg_v01_ei;
 
 	rc = qmi_send_req_wait(dev->qmi.handle, &req_desc, req, sizeof(*req),
@@ -823,11 +846,11 @@
 	int rc;
 
 	req_desc.msg_id = SLIMBUS_QMI_POWER_REQ_V01;
-	req_desc.max_msg_len = sizeof(*req);
+	req_desc.max_msg_len = SLIMBUS_QMI_POWER_REQ_MAX_MSG_LEN;
 	req_desc.ei_array = slimbus_power_req_msg_v01_ei;
 
 	resp_desc.msg_id = SLIMBUS_QMI_POWER_RESP_V01;
-	resp_desc.max_msg_len = sizeof(resp);
+	resp_desc.max_msg_len = SLIMBUS_QMI_POWER_RESP_MAX_MSG_LEN;
 	resp_desc.ei_array = slimbus_power_resp_msg_v01_ei;
 
 	rc = qmi_send_req_wait(dev->qmi.handle, &req_desc, req, sizeof(*req),
diff --git a/drivers/slimbus/slim-msm.h b/drivers/slimbus/slim-msm.h
index 3daf7ee..6e329b3 100644
--- a/drivers/slimbus/slim-msm.h
+++ b/drivers/slimbus/slim-msm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -152,6 +152,13 @@
 	MSM_CTRL_AWAKE,
 	MSM_CTRL_SLEEPING,
 	MSM_CTRL_ASLEEP,
+	MSM_CTRL_DOWN,
+};
+
+enum msm_slim_msgq {
+	MSM_MSGQ_DISABLED,
+	MSM_MSGQ_RESET,
+	MSM_MSGQ_ENABLED,
 };
 
 struct msm_slim_sps_bam {
@@ -176,6 +183,8 @@
 	struct kthread_worker		kworker;
 	struct completion		qmi_comp;
 	struct notifier_block		nb;
+	struct work_struct		ssr_down;
+	struct work_struct		ssr_up;
 };
 
 struct msm_slim_ctrl {
@@ -206,14 +215,16 @@
 	struct clk		*hclk;
 	struct mutex		tx_lock;
 	u8			pgdla;
-	bool			use_rx_msgqs;
+	enum msm_slim_msgq	use_rx_msgqs;
 	int			pipe_b;
 	struct completion	reconf;
 	bool			reconf_busy;
 	bool			chan_active;
 	enum msm_ctrl_state	state;
+	struct completion	ctrl_up;
 	int			nsats;
 	u32			ver;
+	struct work_struct	slave_notify;
 	struct msm_slim_qmi	qmi;
 };
 
@@ -266,8 +277,11 @@
 int msm_slim_rx_msgq_get(struct msm_slim_ctrl *dev, u32 *data, int offset);
 int msm_slim_sps_init(struct msm_slim_ctrl *dev, struct resource *bam_mem,
 			u32 pipe_reg, bool remote);
-void msm_slim_sps_exit(struct msm_slim_ctrl *dev);
+void msm_slim_sps_exit(struct msm_slim_ctrl *dev, bool dereg);
 
+int msm_slim_connect_endp(struct msm_slim_ctrl *dev,
+				struct msm_slim_endp *endpoint,
+				struct completion *notify);
 void msm_slim_qmi_exit(struct msm_slim_ctrl *dev);
 int msm_slim_qmi_init(struct msm_slim_ctrl *dev, bool apps_is_master);
 int msm_slim_qmi_power_request(struct msm_slim_ctrl *dev, bool active);
diff --git a/drivers/slimbus/slimbus.c b/drivers/slimbus/slimbus.c
index c320e46..bec0399 100644
--- a/drivers/slimbus/slimbus.c
+++ b/drivers/slimbus/slimbus.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -233,6 +233,17 @@
 }
 EXPORT_SYMBOL_GPL(slim_driver_register);
 
+/*
+ * slim_driver_unregister: Undo effects of slim_driver_register
+ * @drv: Client driver to be unregistered
+ */
+void slim_driver_unregister(struct slim_driver *drv)
+{
+	if (drv)
+		driver_unregister(&drv->driver);
+}
+EXPORT_SYMBOL_GPL(slim_driver_unregister);
+
 #define slim_ctrl_attr_gr NULL
 
 static void slim_ctrl_release(struct device *dev)
@@ -3047,6 +3058,7 @@
 	for (i = 0; i < ctrl->last_tid; i++) {
 		if (ctrl->txnt[i]) {
 			ret = -EBUSY;
+			pr_info("slim_clk_pause: txn-rsp for %d pending", i);
 			mutex_unlock(&ctrl->m_ctrl);
 			return -EBUSY;
 		}
@@ -3057,6 +3069,7 @@
 	mutex_lock(&ctrl->sched.m_reconf);
 	/* Data channels active */
 	if (ctrl->sched.usedslots) {
+		pr_info("slim_clk_pause: data channel active");
 		ret = -EBUSY;
 		goto clk_pause_ret;
 	}
diff --git a/drivers/spi/spi_qsd.c b/drivers/spi/spi_qsd.c
index 6135e71..7f60128 100644
--- a/drivers/spi/spi_qsd.c
+++ b/drivers/spi/spi_qsd.c
@@ -2375,7 +2375,7 @@
 
 	of_property_read_u32(node, "spi-max-frequency",
 			&pdata->max_clock_speed);
-	of_property_read_u32(node, "infinite_mode",
+	of_property_read_u32(node, "qcom,infinite-mode",
 			&pdata->infinite_mode);
 
 	pdata->ver_reg_exists = of_property_read_bool(node
@@ -2485,13 +2485,12 @@
 			goto err_probe_exit;
 		}
 
-		rc = of_property_read_u32(pdev->dev.of_node,
-				"cell-index", &pdev->id);
-		if (rc)
+		rc = of_alias_get_id(pdev->dev.of_node, "spi");
+		if (rc < 0)
 			dev_warn(&pdev->dev,
 				"using default bus_num %d\n", pdev->id);
 		else
-			master->bus_num = pdev->id;
+			master->bus_num = pdev->id = rc;
 
 		for (i = 0; i < ARRAY_SIZE(spi_rsrcs); ++i) {
 			dd->spi_gpios[i] = of_get_gpio_flags(pdev->dev.of_node,
diff --git a/drivers/spi/spi_qsd.h b/drivers/spi/spi_qsd.h
index 62f1830..7f5b726 100644
--- a/drivers/spi/spi_qsd.h
+++ b/drivers/spi/spi_qsd.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/drivers/spmi/qpnp-int.c b/drivers/spmi/qpnp-int.c
index 24e35e4..082c9ff 100644
--- a/drivers/spmi/qpnp-int.c
+++ b/drivers/spmi/qpnp-int.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -26,13 +26,16 @@
 #include <linux/radix-tree.h>
 #include <linux/slab.h>
 #include <linux/printk.h>
+#include <linux/ratelimit.h>
 
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
 #include <mach/qpnp-int.h>
 
 /* 16 slave_ids, 256 per_ids per slave, and 8 ints per per_id */
-#define QPNPINT_NR_IRQS (16 * 256 * 8)
+#define QPNPINT_NR_IRQS		(16 * 256 * 8)
+/* This value is guaranteed not to be valid for private data */
+#define QPNPINT_INVALID_DATA	0x80000000
 
 enum qpnpint_regs {
 	QPNPINT_REG_RT_STS		= 0x10,
@@ -65,7 +68,7 @@
 struct q_chip_data {
 	int bus_nr;
 	struct irq_domain *domain;
-	struct qpnp_local_int cb;
+	struct qpnp_local_int *cb;
 	struct spmi_controller *spmi_ctrl;
 	struct radix_tree_root per_tree;
 	struct list_head list;
@@ -114,6 +117,18 @@
 	return 0;
 }
 
+static int qpnpint_spmi_read(struct q_irq_data *irq_d, uint8_t reg,
+			     void *buf, uint32_t len)
+{
+	struct q_chip_data *chip_d = irq_d->chip_d;
+
+	if (!chip_d->spmi_ctrl)
+		return -ENODEV;
+
+	return spmi_ext_register_readl(chip_d->spmi_ctrl, irq_d->spmi_slave,
+				       irq_d->spmi_offset + reg, buf, len);
+}
+
 static int qpnpint_spmi_write(struct q_irq_data *irq_d, uint8_t reg,
 			      void *buf, uint32_t len)
 {
@@ -128,31 +143,76 @@
 	return rc;
 }
 
+static int qpnpint_arbiter_op(struct irq_data *d,
+			      struct q_irq_data *irq_d,
+			      int (*arb_op)(struct spmi_controller *,
+					    struct qpnp_irq_spec *,
+					    uint32_t))
+
+{
+	struct q_chip_data *chip_d = irq_d->chip_d;
+	struct qpnp_irq_spec q_spec;
+	int rc;
+
+	if (!arb_op)
+		return 0;
+
+	if (!chip_d->cb->register_priv_data) {
+		pr_warn_ratelimited("No ability to register arbiter registration data\n");
+		return -ENODEV;
+	}
+
+	rc = qpnpint_decode_hwirq(d->hwirq, &q_spec);
+	if (rc) {
+		pr_err_ratelimited("%s: decode failed on hwirq %lu\n",
+							__func__, d->hwirq);
+		return rc;
+	} else {
+		if (irq_d->priv_d == QPNPINT_INVALID_DATA) {
+			rc = chip_d->cb->register_priv_data(chip_d->spmi_ctrl,
+						&q_spec, &irq_d->priv_d);
+			if (rc) {
+				pr_err_ratelimited(
+					"%s: decode failed on hwirq %lu\n",
+					__func__, d->hwirq);
+				return rc;
+			}
+
+		}
+		arb_op(chip_d->spmi_ctrl, &q_spec, irq_d->priv_d);
+	}
+
+	return 0;
+}
+
 static void qpnpint_irq_mask(struct irq_data *d)
 {
 	struct q_irq_data *irq_d = irq_data_get_irq_chip_data(d);
 	struct q_chip_data *chip_d = irq_d->chip_d;
 	struct q_perip_data *per_d = irq_d->per_d;
-	struct qpnp_irq_spec q_spec;
 	int rc;
 
 	pr_debug("hwirq %lu irq: %d\n", d->hwirq, d->irq);
 
-	if (chip_d->cb.mask) {
-		rc = qpnpint_decode_hwirq(d->hwirq, &q_spec);
-		if (rc)
-			pr_err("decode failed on hwirq %lu\n", d->hwirq);
-		else
-			chip_d->cb.mask(chip_d->spmi_ctrl, &q_spec,
-								irq_d->priv_d);
+	if (!chip_d->cb) {
+		pr_warn_ratelimited("No arbiter on bus=%u slave=%u offset=%u\n",
+				chip_d->bus_nr, irq_d->spmi_slave,
+				irq_d->spmi_offset);
+		return;
 	}
 
+	qpnpint_arbiter_op(d, irq_d, chip_d->cb->mask);
+
 	per_d->int_en &= ~irq_d->mask_shift;
 
 	rc = qpnpint_spmi_write(irq_d, QPNPINT_REG_EN_CLR,
 					(u8 *)&irq_d->mask_shift, 1);
-	if (rc)
-		pr_err("spmi failure on irq %d\n", d->irq);
+	if (rc) {
+		pr_err_ratelimited("spmi failure on irq %d\n", d->irq);
+		return;
+	}
+
+	pr_debug("done hwirq %lu irq: %d\n", d->hwirq, d->irq);
 }
 
 static void qpnpint_irq_mask_ack(struct irq_data *d)
@@ -160,32 +220,34 @@
 	struct q_irq_data *irq_d = irq_data_get_irq_chip_data(d);
 	struct q_chip_data *chip_d = irq_d->chip_d;
 	struct q_perip_data *per_d = irq_d->per_d;
-	struct qpnp_irq_spec q_spec;
 	int rc;
 
-	pr_debug("hwirq %lu irq: %d mask: 0x%x\n", d->hwirq, d->irq,
-							irq_d->mask_shift);
+	pr_debug("hwirq %lu irq: %d\n", d->hwirq, d->irq);
 
-	if (chip_d->cb.mask) {
-		rc = qpnpint_decode_hwirq(d->hwirq, &q_spec);
-		if (rc)
-			pr_err("decode failed on hwirq %lu\n", d->hwirq);
-		else
-			chip_d->cb.mask(chip_d->spmi_ctrl, &q_spec,
-								irq_d->priv_d);
+	if (!chip_d->cb) {
+		pr_warn_ratelimited("No arbiter on bus=%u slave=%u offset=%u\n",
+				chip_d->bus_nr, irq_d->spmi_slave,
+				irq_d->spmi_offset);
+		return;
 	}
 
+	qpnpint_arbiter_op(d, irq_d, chip_d->cb->mask);
+
 	per_d->int_en &= ~irq_d->mask_shift;
 
 	rc = qpnpint_spmi_write(irq_d, QPNPINT_REG_EN_CLR,
 							&irq_d->mask_shift, 1);
-	if (rc)
+	if (rc) {
 		pr_err("spmi failure on irq %d\n", d->irq);
+		return;
+	}
 
 	rc = qpnpint_spmi_write(irq_d, QPNPINT_REG_LATCHED_CLR,
 							&irq_d->mask_shift, 1);
-	if (rc)
+	if (rc) {
 		pr_err("spmi failure on irq %d\n", d->irq);
+		return;
+	}
 }
 
 static void qpnpint_irq_unmask(struct irq_data *d)
@@ -193,25 +255,26 @@
 	struct q_irq_data *irq_d = irq_data_get_irq_chip_data(d);
 	struct q_chip_data *chip_d = irq_d->chip_d;
 	struct q_perip_data *per_d = irq_d->per_d;
-	struct qpnp_irq_spec q_spec;
 	int rc;
 
 	pr_debug("hwirq %lu irq: %d\n", d->hwirq, d->irq);
 
-	if (chip_d->cb.unmask) {
-		rc = qpnpint_decode_hwirq(d->hwirq, &q_spec);
-		if (rc)
-			pr_err("decode failed on hwirq %lu\n", d->hwirq);
-		else
-			chip_d->cb.unmask(chip_d->spmi_ctrl, &q_spec,
-								irq_d->priv_d);
+	if (!chip_d->cb) {
+		pr_warn_ratelimited("No arbiter on bus=%u slave=%u offset=%u\n",
+				chip_d->bus_nr, irq_d->spmi_slave,
+				irq_d->spmi_offset);
+		return;
 	}
 
+	qpnpint_arbiter_op(d, irq_d, chip_d->cb->unmask);
+
 	per_d->int_en |= irq_d->mask_shift;
 	rc = qpnpint_spmi_write(irq_d, QPNPINT_REG_EN_SET,
 					&irq_d->mask_shift, 1);
-	if (rc)
+	if (rc) {
 		pr_err("spmi failure on irq %d\n", d->irq);
+		return;
+	}
 }
 
 static int qpnpint_irq_set_type(struct irq_data *d, unsigned int flow_type)
@@ -248,9 +311,29 @@
 	buf[2] = per_d->pol_low;
 
 	rc = qpnpint_spmi_write(irq_d, QPNPINT_REG_SET_TYPE, &buf, 3);
-	if (rc)
+	if (rc) {
 		pr_err("spmi failure on irq %d\n", d->irq);
-	return rc;
+		return rc;
+	}
+
+	return 0;
+}
+
+static int qpnpint_irq_read_line(struct irq_data *d)
+{
+	struct q_irq_data *irq_d = irq_data_get_irq_chip_data(d);
+	int rc;
+	u8 buf;
+
+	pr_debug("hwirq %lu irq: %d\n", d->hwirq, d->irq);
+
+	rc = qpnpint_spmi_read(irq_d, QPNPINT_REG_RT_STS, &buf, 1);
+	if (rc) {
+		pr_err("spmi failure on irq %d\n", d->irq);
+		return rc;
+	}
+
+	return (buf & irq_d->mask_shift) ? 1 : 0;
 }
 
 static int qpnpint_irq_set_wake(struct irq_data *d, unsigned int on)
@@ -264,6 +347,7 @@
 	.irq_mask_ack	= qpnpint_irq_mask_ack,
 	.irq_unmask	= qpnpint_irq_unmask,
 	.irq_set_type	= qpnpint_irq_set_type,
+	.irq_read_line	= qpnpint_irq_read_line,
 	.irq_set_wake	= qpnpint_irq_set_wake,
 	.flags		= IRQCHIP_MASK_ON_SUSPEND,
 };
@@ -283,11 +367,14 @@
 	irq_d->spmi_offset = q_spec.per << 8;
 	irq_d->chip_d = chip_d;
 
-	if (chip_d->cb.register_priv_data)
-		rc = chip_d->cb.register_priv_data(chip_d->spmi_ctrl, &q_spec,
+	irq_d->priv_d = QPNPINT_INVALID_DATA;
+
+	if (chip_d->cb && chip_d->cb->register_priv_data) {
+		rc = chip_d->cb->register_priv_data(chip_d->spmi_ctrl, &q_spec,
 							&irq_d->priv_d);
 		if (rc)
 			return rc;
+	}
 
 	irq_d->per_d->use_count++;
 	return 0;
@@ -299,6 +386,7 @@
 {
 	struct q_irq_data *irq_d;
 	struct q_perip_data *per_d;
+	int rc;
 
 	irq_d = kzalloc(sizeof(struct q_irq_data), GFP_KERNEL);
 	if (!irq_d)
@@ -313,15 +401,26 @@
 	if (!per_d) {
 		per_d = kzalloc(sizeof(struct q_perip_data), GFP_KERNEL);
 		if (!per_d) {
-			kfree(irq_d);
-			return ERR_PTR(-ENOMEM);
+			rc = -ENOMEM;
+			goto alloc_fail;
 		}
-		radix_tree_insert(&chip_d->per_tree,
+		rc = radix_tree_preload(GFP_KERNEL);
+		if (rc)
+			goto alloc_fail;
+		rc = radix_tree_insert(&chip_d->per_tree,
 				  (hwirq & ~0x7), per_d);
+		if (rc)
+			goto alloc_fail;
+		radix_tree_preload_end();
 	}
 	irq_d->per_d = per_d;
 
 	return irq_d;
+
+alloc_fail:
+	kfree(per_d);
+	kfree(irq_d);
+	return ERR_PTR(rc);
 }
 
 static int qpnpint_irq_domain_dt_translate(struct irq_domain *d,
@@ -353,6 +452,8 @@
 	*out_hwirq = ret;
 	*out_type = IRQ_TYPE_NONE;
 
+	pr_debug("out_hwirq = %lu\n", *out_hwirq);
+
 	return 0;
 }
 
@@ -374,7 +475,7 @@
 
 	pr_debug("hwirq = %lu\n", hwirq);
 
-	if (hwirq < 0 || hwirq >= 32768) {
+	if (hwirq < 0 || hwirq >= QPNPINT_NR_IRQS) {
 		pr_err("hwirq %lu out of bounds\n", hwirq);
 		return -EINVAL;
 	}
@@ -436,7 +537,10 @@
 
 	list_for_each_entry(chip_d, &qpnpint_chips, list)
 		if (node == chip_d->domain->of_node) {
-			chip_d->cb = *li_cb;
+			chip_d->cb = kmemdup(li_cb,
+						sizeof(*li_cb), GFP_ATOMIC);
+			if (!chip_d->cb)
+				return -ENOMEM;
 			chip_d->spmi_ctrl = ctrl;
 			chip_lookup[ctrl->nr] = chip_d;
 			return 0;
@@ -446,6 +550,27 @@
 }
 EXPORT_SYMBOL(qpnpint_register_controller);
 
+int qpnpint_unregister_controller(struct device_node *node)
+{
+	struct q_chip_data *chip_d;
+
+	if (!node)
+		return -EINVAL;
+
+	list_for_each_entry(chip_d, &qpnpint_chips, list)
+		if (node == chip_d->domain->of_node) {
+			kfree(chip_d->cb);
+			chip_d->cb = NULL;
+			if (chip_d->spmi_ctrl)
+				chip_lookup[chip_d->spmi_ctrl->nr] = NULL;
+			chip_d->spmi_ctrl = NULL;
+			return 0;
+		}
+
+	return -ENOENT;
+}
+EXPORT_SYMBOL(qpnpint_unregister_controller);
+
 int qpnpint_handle_irq(struct spmi_controller *spmi_ctrl,
 		       struct qpnp_irq_spec *spec)
 {
diff --git a/drivers/spmi/spmi-dbgfs.c b/drivers/spmi/spmi-dbgfs.c
index a23f945..b825ade 100644
--- a/drivers/spmi/spmi-dbgfs.c
+++ b/drivers/spmi/spmi-dbgfs.c
@@ -36,6 +36,7 @@
 #include <linux/debugfs.h>
 #include <linux/spmi.h>
 #include <linux/ctype.h>
+#include "spmi-dbgfs.h"
 
 #define ADDR_LEN	 6	/* 5 byte address + 1 space character */
 #define CHARS_PER_ITEM   3	/* Format is 'XX ' */
@@ -58,6 +59,7 @@
 struct spmi_ctrl_data {
 	u32 cnt;
 	u32 addr;
+	struct dentry *dir;
 	struct list_head node;
 	struct spmi_controller *ctrl;
 };
@@ -655,6 +657,7 @@
 	}
 
 	ctrl_data->cnt  = 1;
+	ctrl_data->dir  = dir;
 	ctrl_data->ctrl = ctrl;
 
 	file = debugfs_create_u32("count", DFS_MODE, dir, &ctrl_data->cnt);
@@ -693,6 +696,25 @@
 	return -ENOMEM;
 }
 
+/*
+ * spmi_dfs_create_file: creates a new file in the SPMI debugfs
+ * @returns valid dentry pointer on success or NULL
+ */
+struct dentry *spmi_dfs_create_file(struct spmi_controller *ctrl,
+					const char *name, void *data,
+					const struct file_operations *fops)
+{
+	struct spmi_ctrl_data *ctrl_data;
+
+	list_for_each_entry(ctrl_data, &dbgfs_data.ctrl, node) {
+		if (ctrl_data->ctrl == ctrl)
+			return debugfs_create_file(name,
+					DFS_MODE, ctrl_data->dir, data, fops);
+	}
+
+	return NULL;
+}
+
 static void __exit spmi_dfs_delete_all_ctrl(struct list_head *head)
 {
 	struct list_head *pos, *tmp;
diff --git a/drivers/spmi/spmi-dbgfs.h b/drivers/spmi/spmi-dbgfs.h
index 0baa4db..2a0d815 100644
--- a/drivers/spmi/spmi-dbgfs.h
+++ b/drivers/spmi/spmi-dbgfs.h
@@ -12,10 +12,16 @@
 #ifndef _SPMI_DBGFS_H
 #define _SPMI_DBGFS_H
 
+#include <linux/debugfs.h>
+
 #ifdef CONFIG_DEBUG_FS
 int spmi_dfs_add_controller(struct spmi_controller *ctrl);
 #else
-int spmi_dfs_add_controller(struct spmi_controller *ctrl) { return 0; }
+static int spmi_dfs_add_controller(struct spmi_controller *ctrl) { return 0; }
 #endif
 
+struct dentry *spmi_dfs_create_file(struct spmi_controller *ctrl,
+					const char *name, void *data,
+					const struct file_operations *fops);
+
 #endif /* _SPMI_DBGFS_H */
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index d099074..05a4806 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -23,7 +23,9 @@
 #include <linux/interrupt.h>
 #include <linux/of_spmi.h>
 #include <linux/module.h>
+#include <linux/seq_file.h>
 #include <mach/qpnp-int.h>
+#include "spmi-dbgfs.h"
 
 #define SPMI_PMIC_ARB_NAME		"spmi_pmic_arb"
 
@@ -46,6 +48,21 @@
 #define SPMI_PIC_IRQ_STATUS(N)		(0x0600 + (4 * (N)))
 #define SPMI_PIC_IRQ_CLEAR(N)		(0x0A00 + (4 * (N)))
 
+/* Mapping Table */
+#define SPMI_MAPPING_TABLE_REG(N)	(0x0B00 + (4 * (N)))
+#define SPMI_MAPPING_BIT_INDEX(X)	(((X) >> 18) & 0xF)
+#define SPMI_MAPPING_BIT_IS_0_FLAG(X)	(((X) >> 17) & 0x1)
+#define SPMI_MAPPING_BIT_IS_0_RESULT(X)	(((X) >> 9) & 0xFF)
+#define SPMI_MAPPING_BIT_IS_1_FLAG(X)	(((X) >> 8) & 0x1)
+#define SPMI_MAPPING_BIT_IS_1_RESULT(X)	(((X) >> 0) & 0xFF)
+
+#define SPMI_MAPPING_TABLE_LEN		255
+#define SPMI_MAPPING_TABLE_TREE_DEPTH	16	/* Maximum of 16-bits */
+
+/* Ownership Table */
+#define SPMI_OWNERSHIP_TABLE_REG(N)	(0x0700 + (4 * (N)))
+#define SPMI_OWNERSHIP_PERIPH2OWNER(X)	((X) & 0x7)
+
 /* Channel Status fields */
 enum pmic_arb_chnl_status {
 	PMIC_ARB_STATUS_DONE	= (1 << 0),
@@ -81,13 +98,8 @@
 #define PMIC_ARB_TIMEOUT_US		100
 #define PMIC_ARB_MAX_TRANS_BYTES	(8)
 
-#define PMIC_ARB_APID_MASK				0xFF
-#define PMIC_ARB_PPID_MASK				0xFFF
-/* extract PPID and APID from interrupt map in .dts config file format */
-#define PMIC_ARB_DEV_TRE_2_PPID(MAP_COMPRS_VAL)		\
-			((MAP_COMPRS_VAL) >> (20))
-#define PMIC_ARB_DEV_TRE_2_APID(MAP_COMPRS_VAL)		\
-			((MAP_COMPRS_VAL) &  PMIC_ARB_APID_MASK)
+#define PMIC_ARB_APID_MASK		0xFF
+#define PMIC_ARB_PPID_MASK		0xFFF
 
 /**
  * base - base address of the PMIC Arbiter core registers.
@@ -99,6 +111,7 @@
 	struct device		*slave;
 	void __iomem		*base;
 	void __iomem		*intr;
+	void __iomem		*cnfg;
 	int			pic_irq;
 	bool			allow_wakeup;
 	spinlock_t		lock;
@@ -107,6 +120,7 @@
 	u8			min_apid;
 	u8			max_apid;
 	u16			periph_id_map[PMIC_ARB_MAX_PERIPHS];
+	u32			mapping_table[SPMI_MAPPING_TABLE_LEN];
 };
 
 static u32 pmic_arb_read(struct spmi_pmic_arb_dev *dev, u32 offset)
@@ -317,17 +331,79 @@
 	return pmic_arb->periph_id_map[apid] & PMIC_ARB_PERIPH_ID_VALID;
 }
 
+static u32 search_mapping_table(struct spmi_pmic_arb_dev *pmic_arb, u16 ppid)
+{
+	u32 *mapping_table = pmic_arb->mapping_table;
+	u32 apid = PMIC_ARB_MAX_PERIPHS;
+	int index = 0;
+	u32 data;
+	int i;
+
+	for (i = 0; i < SPMI_MAPPING_TABLE_TREE_DEPTH; ++i) {
+		data = mapping_table[index];
+
+		if (ppid & (1 << SPMI_MAPPING_BIT_INDEX(data))) {
+			if (SPMI_MAPPING_BIT_IS_1_FLAG(data)) {
+				index = SPMI_MAPPING_BIT_IS_1_RESULT(data);
+			} else {
+				apid = SPMI_MAPPING_BIT_IS_1_RESULT(data);
+				break;
+			}
+		} else {
+			if (SPMI_MAPPING_BIT_IS_0_FLAG(data)) {
+				index = SPMI_MAPPING_BIT_IS_0_RESULT(data);
+			} else {
+				apid = SPMI_MAPPING_BIT_IS_0_RESULT(data);
+				break;
+			}
+		}
+	}
+
+	return apid;
+}
+
 /* PPID to APID */
 static uint32_t map_peripheral_id(struct spmi_pmic_arb_dev *pmic_arb, u16 ppid)
 {
-	int first = pmic_arb->min_apid;
-	int last = pmic_arb->max_apid;
-	int i;
+	u32 apid = search_mapping_table(pmic_arb, ppid);
+	u32 old_ppid;
+	u32 owner;
 
-	/* Search table for a matching PPID */
-	for (i = first; i <= last; ++i) {
-		if ((pmic_arb->periph_id_map[i] & PMIC_ARB_PPID_MASK) == ppid)
-			return i;
+	/* If the apid was found, add it to the lookup table */
+	if (apid < PMIC_ARB_MAX_PERIPHS) {
+		old_ppid = get_peripheral_id(pmic_arb, apid);
+
+		owner = SPMI_OWNERSHIP_PERIPH2OWNER(
+				readl_relaxed(pmic_arb->cnfg +
+					SPMI_OWNERSHIP_TABLE_REG(apid)));
+
+		/* Check ownership */
+		if (owner != pmic_arb->owner) {
+			dev_err(pmic_arb->dev, "PPID 0x%x incorrect owner %d\n",
+				ppid, owner);
+			return PMIC_ARB_MAX_PERIPHS;
+		}
+
+		/* Check if already mapped */
+		if (pmic_arb->periph_id_map[apid] & PMIC_ARB_PERIPH_ID_VALID) {
+			if (ppid != old_ppid) {
+				dev_err(pmic_arb->dev,
+					"PPID 0x%x: APID 0x%x already mapped\n",
+					ppid, apid);
+				return PMIC_ARB_MAX_PERIPHS;
+			}
+			return apid;
+		}
+
+		pmic_arb->periph_id_map[apid] = ppid | PMIC_ARB_PERIPH_ID_VALID;
+
+		if (apid > pmic_arb->max_apid)
+			pmic_arb->max_apid = apid;
+
+		if (apid < pmic_arb->min_apid)
+			pmic_arb->min_apid = apid;
+
+		return apid;
 	}
 
 	dev_err(pmic_arb->dev, "Unknown ppid 0x%x\n", ppid);
@@ -481,6 +557,37 @@
 	return 0;
 }
 
+static int pmic_arb_mapping_data_show(struct seq_file *file, void *unused)
+{
+	struct spmi_pmic_arb_dev *pmic_arb = file->private;
+	int first = pmic_arb->min_apid;
+	int last = pmic_arb->max_apid;
+	int i;
+
+	for (i = first; i <= last; ++i) {
+		if (!is_apid_valid(pmic_arb, i))
+			continue;
+
+		seq_printf(file, "APID 0x%.2x = PPID 0x%.3x. Enabled:%d\n",
+			i, get_peripheral_id(pmic_arb, i),
+			readl_relaxed(pmic_arb->intr + SPMI_PIC_ACC_ENABLE(i)));
+	}
+
+	return 0;
+}
+
+static int pmic_arb_mapping_data_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, pmic_arb_mapping_data_show, inode->i_private);
+}
+
+static const struct file_operations pmic_arb_dfs_fops = {
+	.open		= pmic_arb_mapping_data_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release,
+};
+
 static int __devinit
 spmi_pmic_arb_get_property(struct platform_device *pdev, char *pname, u32 *prop)
 {
@@ -494,70 +601,6 @@
 	return ret;
 }
 
-static int __devinit spmi_pmic_arb_get_map_data(struct platform_device *pdev,
-					struct spmi_pmic_arb_dev *pmic_arb)
-{
-	int i;
-	int ret;
-	int map_size;
-	u32 *map_data;
-	const int map_width = sizeof(*map_data);
-	const struct device_node *of_node = pdev->dev.of_node;
-
-	/* Get size of the mapping table (in bytes) */
-	if (!of_get_property(of_node, "qcom,pmic-arb-ppid-map", &map_size)) {
-		dev_err(&pdev->dev, "missing ppid mapping table\n");
-		return -ENODEV;
-	}
-
-	/* Map size can't exceed the maximum number of peripherals */
-	if (map_size == 0 || map_size > map_width * PMIC_ARB_MAX_PERIPHS) {
-		dev_err(&pdev->dev, "map size of %d is not valid\n", map_size);
-		return -ENODEV;
-	}
-
-	map_data = kzalloc(map_size, GFP_KERNEL);
-	if (!map_data) {
-		dev_err(&pdev->dev, "can not allocate map data\n");
-		return -ENOMEM;
-	}
-
-	ret = of_property_read_u32_array(of_node,
-		"qcom,pmic-arb-ppid-map", map_data, map_size/sizeof(u32));
-	if (ret) {
-		dev_err(&pdev->dev, "invalid or missing property: ppid-map\n");
-		goto err;
-	};
-
-	pmic_arb->max_apid = 0;
-	pmic_arb->min_apid = PMIC_ARB_MAX_PERIPHS - 1;
-
-	/* Build the mapping table from the data */
-	for (i = 0; i < map_size/sizeof(u32);) {
-		u32 map_compressed_val = map_data[i++];
-		u32 ppid = PMIC_ARB_DEV_TRE_2_PPID(map_compressed_val) ;
-		u32 apid = PMIC_ARB_DEV_TRE_2_APID(map_compressed_val) ;
-
-		if (pmic_arb->periph_id_map[apid] & PMIC_ARB_PERIPH_ID_VALID)
-			dev_warn(&pdev->dev, "duplicate APID 0x%x\n", apid);
-
-		pmic_arb->periph_id_map[apid] = ppid | PMIC_ARB_PERIPH_ID_VALID;
-
-		if (apid > pmic_arb->max_apid)
-			pmic_arb->max_apid = apid;
-
-		if (apid < pmic_arb->min_apid)
-			pmic_arb->min_apid = apid;
-	}
-
-	pr_debug("%d value(s) mapped, min:%d, max:%d\n",
-		map_size/map_width, pmic_arb->min_apid, pmic_arb->max_apid);
-
-err:
-	kfree(map_data);
-	return ret;
-}
-
 static struct qpnp_local_int spmi_pmic_arb_intr_cb = {
 	.mask = pmic_arb_pic_disable,
 	.unmask = pmic_arb_pic_enable,
@@ -571,6 +614,7 @@
 	u32 cell_index;
 	u32 prop;
 	int ret = 0;
+	int i;
 
 	pr_debug("SPMI PMIC Arbiter\n");
 
@@ -581,7 +625,7 @@
 		return -ENOMEM;
 	}
 
-	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mem_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core");
 	if (!mem_res) {
 		dev_err(&pdev->dev, "missing base memory resource\n");
 		return -ENODEV;
@@ -594,7 +638,7 @@
 		return -ENOMEM;
 	}
 
-	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	mem_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr");
 	if (!mem_res) {
 		dev_err(&pdev->dev, "missing mem resource (interrupts)\n");
 		return -ENODEV;
@@ -607,6 +651,23 @@
 		return -ENOMEM;
 	}
 
+	mem_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cnfg");
+	if (!mem_res) {
+		dev_err(&pdev->dev, "missing mem resource (configuration)\n");
+		return -ENODEV;
+	}
+
+	pmic_arb->cnfg = devm_ioremap(&pdev->dev,
+					mem_res->start, resource_size(mem_res));
+	if (!pmic_arb->cnfg) {
+		dev_err(&pdev->dev, "ioremap of 'cnfg' failed\n");
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(pmic_arb->mapping_table); ++i)
+		pmic_arb->mapping_table[i] = readl_relaxed(
+				pmic_arb->cnfg + SPMI_MAPPING_TABLE_REG(i));
+
 	pmic_arb->pic_irq = platform_get_irq(pdev, 0);
 	if (!pmic_arb->pic_irq) {
 		dev_err(&pdev->dev, "missing IRQ resource\n");
@@ -625,10 +686,6 @@
 	if (ret)
 		return -ENODEV;
 
-	ret = spmi_pmic_arb_get_map_data(pdev, pmic_arb);
-	if (ret)
-		return ret;
-
 	ret = spmi_pmic_arb_get_property(pdev, "qcom,pmic-arb-ee", &prop);
 	if (ret)
 		return -ENODEV;
@@ -649,6 +706,9 @@
 		}
 	}
 
+	pmic_arb->max_apid = 0;
+	pmic_arb->min_apid = PMIC_ARB_MAX_PERIPHS - 1;
+
 	pmic_arb->dev = &pdev->dev;
 	platform_set_drvdata(pdev, pmic_arb);
 	spmi_set_ctrldata(&pmic_arb->controller, pmic_arb);
@@ -681,6 +741,11 @@
 	/* Register device(s) from the device tree */
 	of_spmi_register_devices(&pmic_arb->controller);
 
+	/* Add debugfs file for mapping data */
+	if (spmi_dfs_create_file(&pmic_arb->controller, "mapping",
+					pmic_arb, &pmic_arb_dfs_fops) == NULL)
+		dev_err(&pdev->dev, "error creating 'mapping' debugfs file\n");
+
 	pr_debug("PMIC Arb Version 0x%x\n",
 			pmic_arb_read(pmic_arb, PMIC_ARB_VERSION));
 
@@ -698,12 +763,18 @@
 static int __devexit spmi_pmic_arb_remove(struct platform_device *pdev)
 {
 	struct spmi_pmic_arb_dev *pmic_arb = platform_get_drvdata(pdev);
+	int ret;
+
+	ret = qpnpint_unregister_controller(pmic_arb->controller.dev.of_node);
+	if (ret)
+		dev_err(&pdev->dev, "Unable to unregister controller %d\n",
+					pmic_arb->controller.nr);
 
 	if (pmic_arb->allow_wakeup)
 		irq_set_irq_wake(pmic_arb->pic_irq, 0);
 	platform_set_drvdata(pdev, NULL);
 	spmi_del_controller(&pmic_arb->controller);
-	return 0;
+	return ret;
 }
 
 static struct of_device_id spmi_pmic_arb_match_table[] = {
diff --git a/drivers/spmi/spmi-resources.c b/drivers/spmi/spmi-resources.c
index 97f15ae..d2e06fd 100644
--- a/drivers/spmi/spmi-resources.c
+++ b/drivers/spmi/spmi-resources.c
@@ -1,6 +1,6 @@
 /* Copyright (c) 2002-3 Patrick Mochel
  * Copyright (c) 2002-3 Open Source Development Labs
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c
index ad58240..49a27c7 100644
--- a/drivers/spmi/spmi.c
+++ b/drivers/spmi/spmi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
index 7b8788d..71554ed 100644
--- a/drivers/staging/android/lowmemorykiller.c
+++ b/drivers/staging/android/lowmemorykiller.c
@@ -37,8 +37,10 @@
 #include <linux/sched.h>
 #include <linux/rcupdate.h>
 #include <linux/notifier.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
 
-static uint32_t lowmem_debug_level = 2;
+static uint32_t lowmem_debug_level = 1;
 static int lowmem_adj[6] = {
 	0,
 	1,
@@ -62,6 +64,60 @@
 			printk(x);			\
 	} while (0)
 
+
+static int can_use_cma_pages(struct zone *zone, gfp_t gfp_mask)
+{
+	int can_use = 0;
+	int mtype = allocflags_to_migratetype(gfp_mask);
+	int i = 0;
+	int *mtype_fallbacks = get_migratetype_fallbacks(mtype);
+
+	if (is_migrate_cma(mtype)) {
+		can_use = 1;
+	} else {
+		for (i = 0;; i++) {
+			int fallbacktype = mtype_fallbacks[i];
+
+			if (is_migrate_cma(fallbacktype)) {
+				can_use = 1;
+				break;
+			}
+
+			if (fallbacktype == MIGRATE_RESERVE)
+				break;
+		}
+	}
+	return can_use;
+}
+
+
+static int nr_free_zone_pages(struct zone *zone, gfp_t gfp_mask)
+{
+	int sum = zone_page_state(zone, NR_FREE_PAGES);
+
+	if (!can_use_cma_pages(zone, gfp_mask))
+		sum -= zone_page_state(zone, NR_FREE_CMA_PAGES);
+
+	return sum;
+}
+
+
+static int nr_free_pages(gfp_t gfp_mask)
+{
+	struct zoneref *z;
+	struct zone *zone;
+	int sum = 0;
+
+	struct zonelist *zonelist = node_zonelist(numa_node_id(), gfp_mask);
+
+	for_each_zone_zonelist(zone, z, zonelist, gfp_zone(gfp_mask)) {
+		sum += nr_free_zone_pages(zone, gfp_mask);
+	}
+
+	return sum;
+}
+
+
 static int test_task_flag(struct task_struct *p, int flag)
 {
 	struct task_struct *t = p;
@@ -78,6 +134,8 @@
 	return 0;
 }
 
+static DEFINE_MUTEX(scan_mutex);
+
 static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
 {
 	struct task_struct *tsk;
@@ -89,10 +147,28 @@
 	int selected_tasksize = 0;
 	int selected_oom_score_adj;
 	int array_size = ARRAY_SIZE(lowmem_adj);
-	int other_free = global_page_state(NR_FREE_PAGES);
-	int other_file = global_page_state(NR_FILE_PAGES) -
+	int other_free;
+	int other_file;
+	unsigned long nr_to_scan = sc->nr_to_scan;
+
+	if (nr_to_scan > 0) {
+		if (mutex_lock_interruptible(&scan_mutex) < 0)
+			return 0;
+	}
+
+	other_free = global_page_state(NR_FREE_PAGES);
+	other_file = global_page_state(NR_FILE_PAGES) -
 						global_page_state(NR_SHMEM);
 
+	if (nr_to_scan > 0 && other_free > other_file) {
+		/*
+		 * If the number of free pages is going to affect the decision
+		 * of which process is selected then ensure only free pages
+		 * which can satisfy the request are considered.
+		 */
+		other_free = nr_free_pages(sc->gfp_mask);
+	}
+
 	if (lowmem_adj_size < array_size)
 		array_size = lowmem_adj_size;
 	if (lowmem_minfree_size < array_size)
@@ -104,17 +180,21 @@
 			break;
 		}
 	}
-	if (sc->nr_to_scan > 0)
+	if (nr_to_scan > 0)
 		lowmem_print(3, "lowmem_shrink %lu, %x, ofree %d %d, ma %d\n",
-				sc->nr_to_scan, sc->gfp_mask, other_free,
+				nr_to_scan, sc->gfp_mask, other_free,
 				other_file, min_score_adj);
 	rem = global_page_state(NR_ACTIVE_ANON) +
 		global_page_state(NR_ACTIVE_FILE) +
 		global_page_state(NR_INACTIVE_ANON) +
 		global_page_state(NR_INACTIVE_FILE);
-	if (sc->nr_to_scan <= 0 || min_score_adj == OOM_SCORE_ADJ_MAX + 1) {
+	if (nr_to_scan <= 0 || min_score_adj == OOM_SCORE_ADJ_MAX + 1) {
 		lowmem_print(5, "lowmem_shrink %lu, %x, return %d\n",
-			     sc->nr_to_scan, sc->gfp_mask, rem);
+			     nr_to_scan, sc->gfp_mask, rem);
+
+		if (nr_to_scan > 0)
+			mutex_unlock(&scan_mutex);
+
 		return rem;
 	}
 	selected_oom_score_adj = min_score_adj;
@@ -127,9 +207,16 @@
 		if (tsk->flags & PF_KTHREAD)
 			continue;
 
+		/* if task no longer has any memory ignore it */
+		if (test_task_flag(tsk, TIF_MM_RELEASED))
+			continue;
+
 		if (time_before_eq(jiffies, lowmem_deathpending_timeout)) {
 			if (test_task_flag(tsk, TIF_MEMDIE)) {
 				rcu_read_unlock();
+				/* give the system time to free up the memory */
+				msleep_interruptible(20);
+				mutex_unlock(&scan_mutex);
 				return 0;
 			}
 		}
@@ -168,10 +255,15 @@
 		send_sig(SIGKILL, selected, 0);
 		set_tsk_thread_flag(selected, TIF_MEMDIE);
 		rem -= selected_tasksize;
-	}
+		rcu_read_unlock();
+		/* give the system time to free up the memory */
+		msleep_interruptible(20);
+	} else
+		rcu_read_unlock();
+
 	lowmem_print(4, "lowmem_shrink %lu, %x, return %d\n",
-		     sc->nr_to_scan, sc->gfp_mask, rem);
-	rcu_read_unlock();
+		     nr_to_scan, sc->gfp_mask, rem);
+	mutex_unlock(&scan_mutex);
 	return rem;
 }
 
diff --git a/drivers/staging/gobi/QCUSBNet2k/QCUSBNet.c b/drivers/staging/gobi/QCUSBNet2k/QCUSBNet.c
index e7f72e7..d4b4663 100644
--- a/drivers/staging/gobi/QCUSBNet2k/QCUSBNet.c
+++ b/drivers/staging/gobi/QCUSBNet2k/QCUSBNet.c
@@ -20,7 +20,7 @@
    QCUSBNetModInit
    QCUSBNetModExit
 
-Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+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
diff --git a/drivers/staging/gobi/QCUSBNet2k/QMI.c b/drivers/staging/gobi/QCUSBNet2k/QMI.c
index fe7eebe..fb88092 100644
--- a/drivers/staging/gobi/QCUSBNet2k/QMI.c
+++ b/drivers/staging/gobi/QCUSBNet2k/QMI.c
@@ -29,7 +29,7 @@
       QMIWDSEventResp
       QMIDMSGetMEIDResp
 
-Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+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
diff --git a/drivers/staging/gobi/QCUSBNet2k/QMI.h b/drivers/staging/gobi/QCUSBNet2k/QMI.h
index 4da1285..633d298 100644
--- a/drivers/staging/gobi/QCUSBNet2k/QMI.h
+++ b/drivers/staging/gobi/QCUSBNet2k/QMI.h
@@ -38,7 +38,7 @@
       QMIWDSEventResp
       QMIDMSGetMEIDResp
 
-Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+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
diff --git a/drivers/staging/gobi/QCUSBNet2k/QMIDevice.c b/drivers/staging/gobi/QCUSBNet2k/QMIDevice.c
index 668328c..dbe4bb2 100644
--- a/drivers/staging/gobi/QCUSBNet2k/QMIDevice.c
+++ b/drivers/staging/gobi/QCUSBNet2k/QMIDevice.c
@@ -54,7 +54,7 @@
       SetupQMIWDSCallback
       QMIDMSGetMEID
 
-Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+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
diff --git a/drivers/staging/gobi/QCUSBNet2k/QMIDevice.h b/drivers/staging/gobi/QCUSBNet2k/QMIDevice.h
index 6fb9c47..29cc269 100644
--- a/drivers/staging/gobi/QCUSBNet2k/QMIDevice.h
+++ b/drivers/staging/gobi/QCUSBNet2k/QMIDevice.h
@@ -54,7 +54,7 @@
       SetupQMIWDSCallback
       QMIDMSGetMEID
 
-Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+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
diff --git a/drivers/staging/gobi/QCUSBNet2k/Structs.h b/drivers/staging/gobi/QCUSBNet2k/Structs.h
index 07e3193..7c93503 100644
--- a/drivers/staging/gobi/QCUSBNet2k/Structs.h
+++ b/drivers/staging/gobi/QCUSBNet2k/Structs.h
@@ -8,7 +8,7 @@
 FUNCTIONS:
    none
 
-Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+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
diff --git a/drivers/staging/qcache/fmem.c b/drivers/staging/qcache/fmem.c
index 8f9e0ef..0609f4a 100644
--- a/drivers/staging/qcache/fmem.c
+++ b/drivers/staging/qcache/fmem.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/drivers/staging/qcache/qcache-main.c b/drivers/staging/qcache/qcache-main.c
index 063c6fc..f416cfc 100644
--- a/drivers/staging/qcache/qcache-main.c
+++ b/drivers/staging/qcache/qcache-main.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2010,2011, Dan Magenheimer, Oracle Corp.
  * Copyright (c) 2010,2011, Nitin Gupta
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * Qcache provides an in-kernel "host implementation" for transcendent memory
  * and, thus indirectly, for cleancache and frontswap.  Qcache includes a
diff --git a/drivers/staging/qcache/tmem.c b/drivers/staging/qcache/tmem.c
index e5c3f30..40f2246 100644
--- a/drivers/staging/qcache/tmem.c
+++ b/drivers/staging/qcache/tmem.c
@@ -2,7 +2,7 @@
  * In-kernel transcendent memory (generic implementation)
  *
  * Copyright (c) 2009-2011, Dan Magenheimer, Oracle Corp.
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. All rights reserved.
  *
  * The primary purpose of Transcedent Memory ("tmem") is to map object-oriented
  * "handles" (triples containing a pool id, and object id, and an index), to
diff --git a/drivers/staging/qcache/tmem.h b/drivers/staging/qcache/tmem.h
index dd8a6ea..359c201 100644
--- a/drivers/staging/qcache/tmem.h
+++ b/drivers/staging/qcache/tmem.h
@@ -4,7 +4,7 @@
  * Transcendent memory
  *
  * Copyright (c) 2009-2011, Dan Magenheimer, Oracle Corp.
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _TMEM_H_
diff --git a/drivers/switch/switch_class.c b/drivers/switch/switch_class.c
index e05fc25..f9cf2b4 100644
--- a/drivers/switch/switch_class.c
+++ b/drivers/switch/switch_class.c
@@ -151,8 +151,8 @@
 {
 	device_remove_file(sdev->dev, &dev_attr_name);
 	device_remove_file(sdev->dev, &dev_attr_state);
-	device_destroy(switch_class, MKDEV(0, sdev->index));
 	dev_set_drvdata(sdev->dev, NULL);
+	device_destroy(switch_class, MKDEV(0, sdev->index));
 }
 EXPORT_SYMBOL_GPL(switch_dev_unregister);
 
diff --git a/drivers/thermal/msm8960_tsens.c b/drivers/thermal/msm8960_tsens.c
index a932f6b..67e0181 100644
--- a/drivers/thermal/msm8960_tsens.c
+++ b/drivers/thermal/msm8960_tsens.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/drivers/thermal/msm8974-tsens.c b/drivers/thermal/msm8974-tsens.c
index 4cb93b8..482d383 100644
--- a/drivers/thermal/msm8974-tsens.c
+++ b/drivers/thermal/msm8974-tsens.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -63,12 +63,16 @@
 #define TSENS_SN_REMOTE_CONFIG(n)	((n) + 0x3c)
 
 #define TSENS_EEPROM(n)			((n) + 0xd0)
-#define TSENS_EEPROM_REDUNDANCY_SEL(n)	((n) + 0x1cc)
+#define TSENS_EEPROM_REDUNDANCY_SEL(n)	((n) + 0x444)
 #define TSENS_EEPROM_BACKUP_REGION(n)	((n) + 0x440)
 
 #define TSENS_MAIN_CALIB_ADDR_RANGE	6
 #define TSENS_BACKUP_CALIB_ADDR_RANGE	4
 
+#define TSENS_EEPROM_8X26_1(n)		((n) + 0x1c0)
+#define TSENS_EEPROM_8X26_2(n)		((n) + 0x444)
+#define TSENS_8X26_MAIN_CALIB_ADDR_RANGE	4
+
 /* TSENS calibration Mask data */
 #define TSENS_BASE1_MASK		0xff
 #define TSENS0_POINT1_MASK		0x3f00
@@ -83,7 +87,7 @@
 #define TSENS8_POINT1_MASK_BACKUP	0x3f
 #define TSENS9_POINT1_MASK		0x3f
 #define TSENS9_POINT1_MASK_BACKUP	0xfc0
-#define TSENS10_POINT1_MASK		0xfc00
+#define TSENS10_POINT1_MASK		0xfc0
 #define TSENS10_POINT1_MASK_BACKUP	0x3f000
 #define TSENS_CAL_SEL_0_1		0xc0000000
 #define TSENS_CAL_SEL_2			0x40000000
@@ -134,7 +138,7 @@
 #define TSENS1_POINT2_BACKUP_MASK	0x3f
 #define TSENS2_POINT2_MASK		0x3f
 #define TSENS2_POINT2_BACKUP_MASK	0xfc0
-#define TSENS3_POINT2_MASK		0xfc00
+#define TSENS3_POINT2_MASK		0xfc0
 #define TSENS3_POINT2_BACKUP_MASK	0x3f000
 #define TSENS4_POINT2_MASK		0x3f000
 #define TSENS4_POINT2_BACKUP_MASK	0xfc0000
@@ -143,14 +147,49 @@
 #define TSENS6_POINT2_MASK		0x3f000000
 #define TSENS6_POINT2_BACKUP_MASK	0x3f
 #define TSENS7_POINT2_MASK		0x3f
-#define TSENS7_POINT2_BACKUP_MASK	0xfc00
-#define TSENS8_POINT2_MASK		0xfc00
+#define TSENS7_POINT2_BACKUP_MASK	0xfc0
+#define TSENS8_POINT2_MASK		0xfc0
 #define TSENS8_POINT2_BACKUP_MASK	0x3f000
 #define TSENS9_POINT2_MASK		0x3f000
 #define TSENS9_POINT2_BACKUP_MASK	0xfc0000
 #define TSENS10_POINT2_MASK		0xfc0000
 #define TSENS10_POINT2_BACKUP_MASK	0x3f000000
 
+#define TSENS_8X26_BASE0_MASK		0x1fe000
+#define TSENS0_8X26_POINT1_MASK		0x7f00000
+#define TSENS1_8X26_POINT1_MASK		0x3f
+#define TSENS2_8X26_POINT1_MASK		0xfc0
+#define TSENS3_8X26_POINT1_MASK		0x3f000
+#define TSENS4_8X26_POINT1_MASK		0xfc0000
+#define TSENS5_8X26_POINT1_MASK		0x3f000000
+#define TSENS6_8X26_POINT1_MASK		0x3f00000
+#define TSENS_8X26_TSENS_CAL_SEL	0xe0000000
+#define TSENS_8X26_BASE1_MASK		0xff
+#define TSENS0_8X26_POINT2_MASK		0x3f00
+#define TSENS1_8X26_POINT2_MASK		0xfc00
+#define TSENS2_8X26_POINT2_MASK		0x3f00000
+#define TSENS3_8X26_POINT2_MASK		0xfc000000
+#define TSENS4_8X26_POINT2_MASK		0xfc000000
+#define TSENS5_8X26_POINT2_MASK		0x3f00000
+#define TSENS6_8X26_POINT2_MASK		0x7e0000
+
+#define TSENS_8X26_CAL_SEL_SHIFT	29
+#define TSENS_8X26_BASE0_SHIFT		13
+#define TSENS0_8X26_POINT1_SHIFT	21
+#define TSENS2_8X26_POINT1_SHIFT	6
+#define TSENS3_8X26_POINT1_SHIFT	12
+#define TSENS4_8X26_POINT1_SHIFT	18
+#define TSENS5_8X26_POINT1_SHIFT	24
+#define TSENS6_8X26_POINT1_SHIFT	20
+
+#define TSENS0_8X26_POINT2_SHIFT	8
+#define TSENS1_8X26_POINT2_SHIFT	14
+#define TSENS2_8X26_POINT2_SHIFT	20
+#define TSENS3_8X26_POINT2_SHIFT	26
+#define TSENS4_8X26_POINT2_SHIFT	20
+#define TSENS5_8X26_POINT2_SHIFT	26
+#define TSENS6_8X26_POINT2_SHIFT	17
+
 #define TSENS_BIT_APPEND		0x3
 #define TSENS_CAL_DEGC_POINT1		30
 #define TSENS_CAL_DEGC_POINT2		120
@@ -171,6 +210,13 @@
 #define TSENS_QFPROM_BACKUP_REDUN_SEL	0xe0000000
 #define TSENS_QFPROM_BACKUP_REDUN_SHIFT	29
 
+enum tsens_calib_fuse_map_type {
+	TSENS_CALIB_FUSE_MAP_8974 = 0,
+	TSENS_CALIB_FUSE_MAP_8X26,
+	TSENS_CALIB_FUSE_MAP_8X10,
+	TSENS_CALIB_FUSE_MAP_NUM,
+};
+
 /* Trips: warm and cool */
 enum tsens_trip_type {
 	TSENS_TRIP_WARM = 0,
@@ -203,6 +249,7 @@
 	struct resource			*res_tsens_mem;
 	struct resource			*res_calib_mem;
 	struct work_struct		tsens_work;
+	uint32_t			calib_mode;
 	struct tsens_tm_device_sensor	sensor[0];
 };
 
@@ -546,7 +593,162 @@
 		TSENS_UPPER_LOWER_INTERRUPT_CTRL(tmdev->tsens_addr));
 }
 
-static int tsens_calib_sensors(void)
+static int tsens_calib_8x26_sensors(void)
+{
+	int i, tsens_base0_data = 0, tsens0_point1 = 0, tsens1_point1 = 0;
+	int tsens2_point1 = 0, tsens3_point1 = 0, tsens4_point1 = 0;
+	int tsens5_point1 = 0, tsens6_point1 = 0, tsens6_point2 = 0;
+	int tsens0_point2 = 0, tsens1_point2 = 0, tsens2_point2 = 0;
+	int tsens3_point2 = 0, tsens4_point2 = 0, tsens5_point2 = 0;
+	int tsens_base1_data = 0, tsens_calibration_mode = 0;
+	uint32_t calib_data[6];
+	uint32_t calib_tsens_point1_data[7], calib_tsens_point2_data[7];
+
+	if (tmdev->calibration_less_mode)
+		goto calibration_less_mode;
+
+	for (i = 0; i < TSENS_8X26_MAIN_CALIB_ADDR_RANGE; i++)
+		calib_data[i] = readl_relaxed(
+			(TSENS_EEPROM_8X26_1(tmdev->tsens_calib_addr))
+					+ (i * TSENS_SN_ADDR_OFFSET));
+	calib_data[4] = readl_relaxed(
+			(TSENS_EEPROM_8X26_2(tmdev->tsens_calib_addr)));
+	calib_data[5] = readl_relaxed(
+			(TSENS_EEPROM_8X26_2(tmdev->tsens_calib_addr)) + 0x8);
+
+	tsens_calibration_mode = calib_data[5] & TSENS_8X26_TSENS_CAL_SEL;
+
+	if ((tsens_calibration_mode == TSENS_TWO_POINT_CALIB) ||
+		(tsens_calibration_mode == TSENS_ONE_POINT_CALIB_OPTION_2)) {
+		pr_debug("backup one point calibrationless mode\n");
+		tsens_base0_data = (calib_data[0] & TSENS_8X26_BASE0_MASK)
+				>> TSENS_8X26_BASE0_SHIFT;
+		tsens0_point1 = (calib_data[0] & TSENS0_8X26_POINT1_MASK) >>
+				TSENS0_8X26_POINT1_SHIFT;
+		tsens1_point1 = calib_data[1] & TSENS1_8X26_POINT1_MASK;
+		tsens2_point1 = (calib_data[1] & TSENS2_8X26_POINT1_MASK) >>
+				TSENS2_8X26_POINT1_SHIFT;
+		tsens3_point1 = (calib_data[1] & TSENS3_8X26_POINT1_MASK) >>
+				TSENS3_8X26_POINT1_SHIFT;
+		tsens4_point1 = (calib_data[1] & TSENS4_8X26_POINT1_MASK) >>
+				TSENS4_8X26_POINT1_SHIFT;
+		tsens5_point1 = (calib_data[1] & TSENS5_8X26_POINT1_MASK) >>
+				TSENS5_8X26_POINT1_SHIFT;
+		tsens6_point1 = (calib_data[2] & TSENS6_8X26_POINT1_MASK) >>
+				TSENS6_8X26_POINT1_SHIFT;
+	} else
+		goto calibration_less_mode;
+
+	if (tsens_calibration_mode == TSENS_TWO_POINT_CALIB) {
+		pr_debug("backup two point calibrationless mode\n");
+		tsens_base1_data = (calib_data[3] & TSENS_8X26_BASE1_MASK);
+		tsens0_point2 = (calib_data[3] & TSENS0_8X26_POINT2_MASK) >>
+				TSENS0_8X26_POINT2_SHIFT;
+		tsens1_point2 = (calib_data[3] & TSENS1_8X26_POINT2_MASK) >>
+				TSENS1_8X26_POINT2_SHIFT;
+		tsens2_point2 = (calib_data[3] & TSENS2_8X26_POINT2_MASK) >>
+				TSENS2_8X26_POINT2_SHIFT;
+		tsens3_point2 = (calib_data[3] & TSENS3_8X26_POINT2_MASK) >>
+				TSENS3_8X26_POINT2_SHIFT;
+		tsens4_point2 = (calib_data[4] & TSENS4_8X26_POINT2_MASK) >>
+				TSENS4_8X26_POINT2_SHIFT;
+		tsens5_point2 = (calib_data[4] & TSENS5_8X26_POINT2_MASK) >>
+				TSENS5_8X26_POINT2_SHIFT;
+		tsens6_point2 = (calib_data[5] & TSENS6_8X26_POINT2_MASK) >>
+				TSENS6_8X26_POINT2_SHIFT;
+	}
+
+	if (tsens_calibration_mode == 0) {
+calibration_less_mode:
+		pr_debug("TSENS is calibrationless mode\n");
+		for (i = 0; i < tmdev->tsens_num_sensor; i++)
+			calib_tsens_point2_data[i] = 780;
+		calib_tsens_point1_data[0] = 502;
+		calib_tsens_point1_data[1] = 509;
+		calib_tsens_point1_data[2] = 503;
+		calib_tsens_point1_data[3] = 509;
+		calib_tsens_point1_data[4] = 505;
+		calib_tsens_point1_data[5] = 509;
+		calib_tsens_point1_data[6] = 507;
+		goto compute_intercept_slope;
+	}
+
+	if ((tsens_calibration_mode == TSENS_ONE_POINT_CALIB_OPTION_2) ||
+			(tsens_calibration_mode == TSENS_TWO_POINT_CALIB)) {
+		pr_debug("one and two point calibration calculation\n");
+		calib_tsens_point1_data[0] =
+			((((tsens_base0_data) + tsens0_point1) << 2) |
+						TSENS_BIT_APPEND);
+		calib_tsens_point1_data[1] =
+			((((tsens_base0_data) + tsens1_point1) << 2) |
+						TSENS_BIT_APPEND);
+		calib_tsens_point1_data[2] =
+			((((tsens_base0_data) + tsens2_point1) << 2) |
+						TSENS_BIT_APPEND);
+		calib_tsens_point1_data[3] =
+			((((tsens_base0_data) + tsens3_point1) << 2) |
+						TSENS_BIT_APPEND);
+		calib_tsens_point1_data[4] =
+			((((tsens_base0_data) + tsens4_point1) << 2) |
+						TSENS_BIT_APPEND);
+		calib_tsens_point1_data[5] =
+			((((tsens_base0_data) + tsens5_point1) << 2) |
+						TSENS_BIT_APPEND);
+		calib_tsens_point1_data[6] =
+			((((tsens_base0_data) + tsens6_point1) << 2) |
+						TSENS_BIT_APPEND);
+	}
+
+	if (tsens_calibration_mode == TSENS_TWO_POINT_CALIB) {
+		pr_debug("two point calibration calculation\n");
+		calib_tsens_point2_data[0] =
+			(((tsens_base1_data + tsens0_point2) << 2) |
+					TSENS_BIT_APPEND);
+		calib_tsens_point2_data[1] =
+			(((tsens_base1_data + tsens1_point2) << 2) |
+					TSENS_BIT_APPEND);
+		calib_tsens_point2_data[2] =
+			(((tsens_base1_data + tsens2_point2) << 2) |
+					TSENS_BIT_APPEND);
+		calib_tsens_point2_data[3] =
+			(((tsens_base1_data + tsens3_point2) << 2) |
+					TSENS_BIT_APPEND);
+		calib_tsens_point2_data[4] =
+			(((tsens_base1_data + tsens4_point2) << 2) |
+					TSENS_BIT_APPEND);
+		calib_tsens_point2_data[5] =
+			(((tsens_base1_data + tsens5_point2) << 2) |
+					TSENS_BIT_APPEND);
+		calib_tsens_point2_data[6] =
+			(((tsens_base1_data + tsens6_point2) << 2) |
+					TSENS_BIT_APPEND);
+	}
+
+compute_intercept_slope:
+	for (i = 0; i < tmdev->tsens_num_sensor; i++) {
+		int32_t num = 0, den = 0;
+		tmdev->sensor[i].calib_data_point2 = calib_tsens_point2_data[i];
+		tmdev->sensor[i].calib_data_point1 = calib_tsens_point1_data[i];
+		if (tsens_calibration_mode == TSENS_TWO_POINT_CALIB) {
+			/* slope (m) = adc_code2 - adc_code1 (y2 - y1)/
+				temp_120_degc - temp_30_degc (x2 - x1) */
+			num = tmdev->sensor[i].calib_data_point2 -
+					tmdev->sensor[i].calib_data_point1;
+			num *= tmdev->tsens_factor;
+			den = TSENS_CAL_DEGC_POINT2 - TSENS_CAL_DEGC_POINT1;
+			tmdev->sensor[i].slope_mul_tsens_factor = num/den;
+		}
+		tmdev->sensor[i].offset = (tmdev->sensor[i].calib_data_point1 *
+			tmdev->tsens_factor) - (TSENS_CAL_DEGC_POINT1 *
+				tmdev->sensor[i].slope_mul_tsens_factor);
+		INIT_WORK(&tmdev->sensor[i].work, notify_uspace_tsens_fn);
+		tmdev->prev_reading_avail = false;
+	}
+
+	return 0;
+}
+
+static int tsens_calib_8974_sensors(void)
 {
 	int i, tsens_base1_data = 0, tsens0_point1 = 0, tsens1_point1 = 0;
 	int tsens2_point1 = 0, tsens3_point1 = 0, tsens4_point1 = 0;
@@ -859,10 +1061,12 @@
 		tmdev->sensor[i].calib_data_point2 = calib_tsens_point2_data[i];
 		tmdev->sensor[i].calib_data_point1 = calib_tsens_point1_data[i];
 		if (tsens_calibration_mode == TSENS_TWO_POINT_CALIB) {
-			num = TSENS_CAL_DEGC_POINT2 - TSENS_CAL_DEGC_POINT2;
-			den = tmdev->sensor[i].calib_data_point2 -
+			/* slope (m) = adc_code2 - adc_code1 (y2 - y1)/
+				temp_120_degc - temp_30_degc (x2 - x1) */
+			num = tmdev->sensor[i].calib_data_point2 -
 					tmdev->sensor[i].calib_data_point1;
 			num *= tmdev->tsens_factor;
+			den = TSENS_CAL_DEGC_POINT2 - TSENS_CAL_DEGC_POINT1;
 			tmdev->sensor[i].slope_mul_tsens_factor = num/den;
 		}
 		tmdev->sensor[i].offset = (tmdev->sensor[i].calib_data_point1 *
@@ -875,12 +1079,30 @@
 	return 0;
 }
 
+static int tsens_calib_sensors(void)
+{
+	int rc = 0;
+
+	if (!tmdev)
+		return -ENODEV;
+
+	if (tmdev->calib_mode == TSENS_CALIB_FUSE_MAP_8974)
+		rc = tsens_calib_8974_sensors();
+	else if (tmdev->calib_mode == TSENS_CALIB_FUSE_MAP_8X26)
+		rc = tsens_calib_8x26_sensors();
+	else
+		rc = -ENODEV;
+
+	return rc;
+}
+
 static int get_device_tree_data(struct platform_device *pdev)
 {
 	const struct device_node *of_node = pdev->dev.of_node;
 	struct resource *res_mem = NULL;
 	u32 *tsens_slope_data;
-	u32 rc = 0, i, tsens_num_sensors;
+	u32 rc = 0, i, tsens_num_sensors, calib_type;
+	const char *tsens_calib_mode;
 
 	rc = of_property_read_u32(of_node,
 			"qcom,sensors", &tsens_num_sensors);
@@ -903,6 +1125,19 @@
 		return rc;
 	};
 
+	tsens_calib_mode = of_get_property(of_node,
+			"qcom,calib-mode", NULL);
+	if (!strncmp(tsens_calib_mode, "fuse_map1", 9))
+		calib_type = TSENS_CALIB_FUSE_MAP_8974;
+	else if (!strncmp(tsens_calib_mode, "fuse_map2", 9))
+		calib_type = TSENS_CALIB_FUSE_MAP_8X26;
+	else if (!strncmp(tsens_calib_mode, "fuse_map3", 9))
+		calib_type = TSENS_CALIB_FUSE_MAP_8X10;
+	else {
+		pr_err("%s: Invalid calibration property\n", __func__);
+		return -EINVAL;
+	}
+
 	tmdev = devm_kzalloc(&pdev->dev,
 			sizeof(struct tsens_tm_device) +
 			tsens_num_sensors *
@@ -919,6 +1154,7 @@
 	tmdev->tsens_num_sensor = tsens_num_sensors;
 	tmdev->calibration_less_mode = of_property_read_bool(of_node,
 				"qcom,calibration-less-mode");
+	tmdev->calib_mode = calib_type;
 
 	tmdev->tsens_irq = platform_get_irq(pdev, 0);
 	if (tmdev->tsens_irq < 0) {
@@ -1083,6 +1319,8 @@
 		for (i = 0; i < tmdev->tsens_num_sensor; i++)
 			thermal_zone_device_unregister(tmdev->sensor[i].tz_dev);
 		goto fail;
+	} else {
+		enable_irq_wake(tmdev->tsens_irq);
 	}
 	platform_set_drvdata(pdev, tmdev);
 
diff --git a/drivers/thermal/msm_popmem-tm.c b/drivers/thermal/msm_popmem-tm.c
index 583b2db..26ac048 100644
--- a/drivers/thermal/msm_popmem-tm.c
+++ b/drivers/thermal/msm_popmem-tm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c
index 2dd2592..5aca48d 100644
--- a/drivers/thermal/msm_thermal.c
+++ b/drivers/thermal/msm_thermal.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -81,7 +81,7 @@
 {
 	static int limit_init;
 	struct tsens_device tsens_dev;
-	unsigned long temp = 0;
+	long temp = 0;
 	uint32_t max_freq = limited_max_freq;
 	int cpu = 0;
 	int ret = 0;
diff --git a/drivers/thermal/msm_tsens.c b/drivers/thermal/msm_tsens.c
index 401ad88..86bae06 100644
--- a/drivers/thermal/msm_tsens.c
+++ b/drivers/thermal/msm_tsens.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/thermal/qpnp-adc-tm.c b/drivers/thermal/qpnp-adc-tm.c
index bcc85f3..17ae34f 100644
--- a/drivers/thermal/qpnp-adc-tm.c
+++ b/drivers/thermal/qpnp-adc-tm.c
@@ -867,10 +867,10 @@
 
 		if (status_low & QPNP_ADC_TM_LOW_THR_INT_EN_M1)
 			adc_tm->battery_param->threshold_notification(
-							ADC_TM_LOW_STATE);
+			ADC_TM_LOW_STATE, adc_tm->battery_param->btm_ctx);
 		else if (status_high & QPNP_ADC_TM_HIGH_THR_INT_EN_M1)
 			adc_tm->battery_param->threshold_notification(
-							ADC_TM_HIGH_STATE);
+			ADC_TM_HIGH_STATE, adc_tm->battery_param->btm_ctx);
 	}
 
 	return;
@@ -944,6 +944,9 @@
 	u8 thr_int_disable = 0;
 	int rc = 0, sensor_notify_num = 0;
 
+	if (!adc_tm || !adc_tm->adc_tm_initialized)
+		return -ENODEV;
+
 	rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_STATUS_LOW, &status_low);
 	if (rc) {
 		pr_err("adc-tm-tm read status low failed with %d\n", rc);
@@ -1364,7 +1367,8 @@
 			GFP_KERNEL);
 	if (!adc_qpnp) {
 		dev_err(&spmi->dev, "Unable to allocate memory\n");
-		return -ENOMEM;
+		rc = -ENOMEM;
+		goto fail;
 	}
 
 	adc_tm->adc = adc_qpnp;
@@ -1372,7 +1376,7 @@
 	rc = qpnp_adc_get_devicetree_data(spmi, adc_tm->adc);
 	if (rc) {
 		dev_err(&spmi->dev, "failed to read device tree\n");
-		return rc;
+		goto fail;
 	}
 
 	/* Register the ADC peripheral interrupt */
@@ -1380,14 +1384,16 @@
 						NULL, "high-thr-en-set");
 	if (adc_tm->adc->adc_high_thr_irq < 0) {
 		pr_err("Invalid irq\n");
-		return -ENXIO;
+		rc = -ENXIO;
+		goto fail;
 	}
 
 	adc_tm->adc->adc_low_thr_irq = spmi_get_irq_byname(spmi,
 						NULL, "low-thr-en-set");
 	if (adc_tm->adc->adc_low_thr_irq < 0) {
 		pr_err("Invalid irq\n");
-		return -ENXIO;
+		rc = -ENXIO;
+		goto fail;
 	}
 
 	rc = devm_request_irq(&spmi->dev, adc_tm->adc->adc_irq_eoc,
@@ -1396,7 +1402,7 @@
 	if (rc) {
 		dev_err(&spmi->dev,
 			"failed to request adc irq with error %d\n", rc);
-		return rc;
+		goto fail;
 	} else {
 		enable_irq_wake(adc_tm->adc->adc_irq_eoc);
 	}
@@ -1406,7 +1412,7 @@
 		IRQF_TRIGGER_RISING, "qpnp_adc_tm_high_interrupt", adc_tm);
 	if (rc) {
 		dev_err(&spmi->dev, "failed to request adc irq\n");
-		return rc;
+		goto fail;
 	} else {
 		enable_irq_wake(adc_tm->adc->adc_high_thr_irq);
 	}
@@ -1416,7 +1422,7 @@
 		IRQF_TRIGGER_RISING, "qpnp_adc_tm_low_interrupt", adc_tm);
 	if (rc) {
 		dev_err(&spmi->dev, "failed to request adc irq\n");
-		return rc;
+		goto fail;
 	} else {
 		enable_irq_wake(adc_tm->adc->adc_low_thr_irq);
 	}
@@ -1428,7 +1434,7 @@
 				"qcom,btm-channel-number", &btm_channel_num);
 		if (rc) {
 			pr_err("Invalid btm channel number\n");
-			return -EINVAL;
+			goto fail;
 		}
 
 		if ((btm_channel_num != QPNP_ADC_TM_M0_ADC_CH_SEL_CTL) &&
@@ -1463,24 +1469,27 @@
 	rc = qpnp_adc_tm_write_reg(QPNP_ADC_TM_HIGH_THR_INT_EN, thr_init);
 	if (rc < 0) {
 		pr_err("high thr init failed\n");
-		return rc;
+		goto fail;
 	}
 
 	rc = qpnp_adc_tm_write_reg(QPNP_ADC_TM_LOW_THR_INT_EN, thr_init);
 	if (rc < 0) {
 		pr_err("low thr init failed\n");
-		return rc;
+		goto fail;
 	}
 
 	rc = qpnp_adc_tm_write_reg(QPNP_ADC_TM_MULTI_MEAS_EN, thr_init);
 	if (rc < 0) {
 		pr_err("multi meas en failed\n");
-		return rc;
+		goto fail;
 	}
 
 	adc_tm->adc_tm_initialized = true;
 
 	return 0;
+fail:
+	qpnp_adc_tm = NULL;
+	return rc;
 }
 
 static int __devexit qpnp_adc_tm_remove(struct spmi_device *spmi)
diff --git a/drivers/tty/hvc/hvc_dcc.c b/drivers/tty/hvc/hvc_dcc.c
index 81429c2..02a64be 100644
--- a/drivers/tty/hvc/hvc_dcc.c
+++ b/drivers/tty/hvc/hvc_dcc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/tty/n_smux.c b/drivers/tty/n_smux.c
index 14b8ca2..0348145 100644
--- a/drivers/tty/n_smux.c
+++ b/drivers/tty/n_smux.c
@@ -1,6 +1,6 @@
 /* drivers/tty/n_smux.c
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -1287,8 +1287,9 @@
 			goto out;
 		}
 		ack_pkt->hdr.cmd = SMUX_CMD_OPEN_LCH;
-		ack_pkt->hdr.flags = SMUX_CMD_OPEN_ACK
-			| SMUX_CMD_OPEN_POWER_COLLAPSE;
+		ack_pkt->hdr.flags = SMUX_CMD_OPEN_ACK;
+		if (enable_powerdown)
+			ack_pkt->hdr.flags |= SMUX_CMD_OPEN_POWER_COLLAPSE;
 		ack_pkt->hdr.lcid = lcid;
 		ack_pkt->hdr.payload_len = 0;
 		ack_pkt->hdr.pad_len = 0;
@@ -1308,8 +1309,9 @@
 			if (ack_pkt) {
 				ack_pkt->hdr.lcid = lcid;
 				ack_pkt->hdr.cmd = SMUX_CMD_OPEN_LCH;
-				ack_pkt->hdr.flags =
-					SMUX_CMD_OPEN_POWER_COLLAPSE;
+				if (enable_powerdown)
+					ack_pkt->hdr.flags |=
+						SMUX_CMD_OPEN_POWER_COLLAPSE;
 				ack_pkt->hdr.payload_len = 0;
 				ack_pkt->hdr.pad_len = 0;
 				smux_tx_queue(ack_pkt, ch, 0);
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index 5e7ab9f..4f22d72 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -2,7 +2,7 @@
  * drivers/serial/msm_serial.c - driver for msm7k serial device and console
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
  * Author: Robert Love <rlove@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -557,10 +557,6 @@
 	if (unlikely(ret))
 		return ret;
 
-	if (unlikely(irq_set_irq_wake(port->irq, 1))) {
-		free_irq(port->irq, port);
-		return -ENXIO;
-	}
 
 #ifndef CONFIG_PM_RUNTIME
 	msm_init_clock(port);
diff --git a/drivers/tty/serial/msm_serial.h b/drivers/tty/serial/msm_serial.h
index 34228ec..1f17ba4 100644
--- a/drivers/tty/serial/msm_serial.h
+++ b/drivers/tty/serial/msm_serial.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2007 Google, Inc.
  * Author: Robert Love <rlove@google.com>
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index 7a0e32b..c982587 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -3,7 +3,7 @@
  * MSM 7k High speed uart driver
  *
  * Copyright (c) 2008 Google Inc.
- * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2013, The Linux Foundation. All rights reserved.
  * Modified: Nick Pelly <npelly@google.com>
  *
  * All source code in this file is licensed under the following license
@@ -40,6 +40,7 @@
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/ioport.h>
+#include <linux/atomic.h>
 #include <linux/kernel.h>
 #include <linux/timer.h>
 #include <linux/clk.h>
@@ -54,18 +55,36 @@
 #include <linux/device.h>
 #include <linux/wakelock.h>
 #include <linux/debugfs.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/gpio.h>
 #include <asm/atomic.h>
 #include <asm/irq.h>
 
 #include <mach/hardware.h>
 #include <mach/dma.h>
+#include <mach/sps.h>
 #include <mach/msm_serial_hs.h>
+#include <mach/msm_bus.h>
 
 #include "msm_serial_hs_hwreg.h"
+#define UART_SPS_CONS_PERIPHERAL 0
+#define UART_SPS_PROD_PERIPHERAL 1
 
 static int hs_serial_debug_mask = 1;
 module_param_named(debug_mask, hs_serial_debug_mask,
 		   int, S_IRUGO | S_IWUSR | S_IWGRP);
+/*
+ * There are 3 different kind of UART Core available on MSM.
+ * High Speed UART (i.e. Legacy HSUART), GSBI based HSUART
+ * and BSLP based HSUART.
+ */
+enum uart_core_type {
+	LEGACY_HSUART,
+	GSBI_HSUART,
+	BLSP_HSUART,
+};
 
 enum flush_reason {
 	FLUSH_NONE,
@@ -92,6 +111,17 @@
 	CLK_REQ_OFF_RXSTALE_FLUSHED,
 };
 
+/* SPS data structures to support HSUART with BAM
+ * @sps_pipe - This struct defines BAM pipe descriptor
+ * @sps_connect - This struct defines a connection's end point
+ * @sps_register - This struct defines a event registration parameters
+ */
+struct msm_hs_sps_ep_conn_data {
+	struct sps_pipe *pipe_handle;
+	struct sps_connect config;
+	struct sps_register_event event;
+};
+
 struct msm_hs_tx {
 	unsigned int tx_ready_int_en;  /* ok to dma more tx */
 	unsigned int dma_in_flight;    /* tx dma in progress */
@@ -105,6 +135,7 @@
 	int tx_count;
 	dma_addr_t dma_base;
 	struct tasklet_struct tlet;
+	struct msm_hs_sps_ep_conn_data cons;
 };
 
 struct msm_hs_rx {
@@ -122,6 +153,7 @@
 	struct wake_lock wake_lock;
 	struct delayed_work flip_insert_work;
 	struct tasklet_struct tlet;
+	struct msm_hs_sps_ep_conn_data prod;
 };
 
 enum buffer_states {
@@ -168,7 +200,24 @@
 	struct work_struct clock_off_w; /* work for actual clock off */
 	struct workqueue_struct *hsuart_wq; /* hsuart workqueue */
 	struct mutex clk_mutex; /* mutex to guard against clock off/clock on */
+	struct work_struct reset_bam_rx; /* work for reset bam rx endpoint */
+	struct work_struct disconnect_rx_endpoint; /* disconnect rx_endpoint */
 	bool tty_flush_receive;
+	enum uart_core_type uart_type;
+	u32 bam_handle;
+	resource_size_t bam_mem;
+	int bam_irq;
+	unsigned char __iomem *bam_base;
+	unsigned int bam_tx_ep_pipe_index;
+	unsigned int bam_rx_ep_pipe_index;
+	/* struct sps_event_notify is an argument passed when triggering a
+	 * callback event object registered for an SPS connection end point.
+	 */
+	struct sps_event_notify notify;
+	/* bus client handler */
+	u32 bus_perf_client;
+	/* BLSP UART required BUS Scaling data */
+	struct msm_bus_scale_pdata *bus_scale_table;
 };
 
 #define MSM_UARTDM_BURST_SIZE 16   /* DM burst size (in bytes) */
@@ -176,12 +225,19 @@
 #define UARTDM_RX_BUF_SIZE 512
 #define RETRY_TIMEOUT 5
 #define UARTDM_NR 256
+#define BAM_PIPE_MIN 0
+#define BAM_PIPE_MAX 11
+#define BUS_SCALING 1
+#define BUS_RESET 0
 
 static struct dentry *debug_base;
 static struct msm_hs_port q_uart_port[UARTDM_NR];
 static struct platform_driver msm_serial_hs_platform_driver;
 static struct uart_driver msm_hs_driver;
 static struct uart_ops msm_hs_ops;
+static void msm_hs_start_rx_locked(struct uart_port *uport);
+static void msm_serial_hs_rx_tlet(unsigned long tlet_ptr);
+static void flip_insert_work(struct work_struct *work);
 
 #define UARTDM_TO_MSM(uart_port) \
 	container_of((uart_port), struct msm_hs_port, uport)
@@ -244,6 +300,24 @@
 	/* assume gsbi uart if gsbi resource found in pdata */
 	return ((msm_uport->mapped_gsbi != NULL));
 }
+static unsigned int is_blsp_uart(struct msm_hs_port *msm_uport)
+{
+	return (msm_uport->uart_type == BLSP_HSUART);
+}
+
+static void msm_hs_bus_voting(struct msm_hs_port *msm_uport, unsigned int vote)
+{
+	int ret;
+
+	if (is_blsp_uart(msm_uport) && msm_uport->bus_perf_client) {
+		pr_debug("Bus voting:%d\n", vote);
+		ret = msm_bus_scale_client_update_request(
+				msm_uport->bus_perf_client, vote);
+		if (ret)
+			pr_err("%s(): Failed for Bus voting: %d\n",
+							__func__, vote);
+	}
+}
 
 static inline unsigned int msm_hs_read(struct uart_port *uport,
 				       unsigned int offset)
@@ -313,6 +387,8 @@
 	unsigned long flags;
 	int ret = 0;
 
+	msm_hs_bus_voting(msm_uport, BUS_SCALING);
+
 	clk_prepare_enable(msm_uport->clk);
 	if (msm_uport->pclk)
 		clk_prepare_enable(msm_uport->pclk);
@@ -320,13 +396,21 @@
 	if (val) {
 		spin_lock_irqsave(&uport->lock, flags);
 		ret = msm_hs_read(uport, UARTDM_MR2_ADDR);
-		ret |= UARTDM_MR2_LOOP_MODE_BMSK;
+		if (is_blsp_uart(msm_uport))
+			ret |= (UARTDM_MR2_LOOP_MODE_BMSK |
+				UARTDM_MR2_RFR_CTS_LOOP_MODE_BMSK);
+		else
+			ret |= UARTDM_MR2_LOOP_MODE_BMSK;
 		msm_hs_write(uport, UARTDM_MR2_ADDR, ret);
 		spin_unlock_irqrestore(&uport->lock, flags);
 	} else {
 		spin_lock_irqsave(&uport->lock, flags);
 		ret = msm_hs_read(uport, UARTDM_MR2_ADDR);
-		ret &= ~UARTDM_MR2_LOOP_MODE_BMSK;
+		if (is_blsp_uart(msm_uport))
+			ret &= ~(UARTDM_MR2_LOOP_MODE_BMSK |
+				UARTDM_MR2_RFR_CTS_LOOP_MODE_BMSK);
+		else
+			ret &= ~UARTDM_MR2_LOOP_MODE_BMSK;
 		msm_hs_write(uport, UARTDM_MR2_ADDR, ret);
 		spin_unlock_irqrestore(&uport->lock, flags);
 	}
@@ -336,6 +420,7 @@
 	if (msm_uport->pclk)
 		clk_disable_unprepare(msm_uport->pclk);
 
+	msm_hs_bus_voting(msm_uport, BUS_RESET);
 	return 0;
 }
 
@@ -346,6 +431,8 @@
 	unsigned long flags;
 	int ret = 0;
 
+	msm_hs_bus_voting(msm_uport, BUS_SCALING);
+
 	clk_prepare_enable(msm_uport->clk);
 	if (msm_uport->pclk)
 		clk_prepare_enable(msm_uport->pclk);
@@ -359,6 +446,8 @@
 		clk_disable_unprepare(msm_uport->pclk);
 
 	*val = (ret & UARTDM_MR2_LOOP_MODE_BMSK) ? 1 : 0;
+
+	msm_hs_bus_voting(msm_uport, BUS_RESET);
 	return 0;
 }
 DEFINE_SIMPLE_ATTRIBUTE(loopback_enable_fops, msm_serial_loopback_enable_get,
@@ -470,6 +559,89 @@
 	return 0;
 }
 
+
+/* Connect a UART peripheral's SPS endpoint(consumer endpoint)
+ *
+ * Also registers a SPS callback function for the consumer
+ * process with the SPS driver
+ *
+ * @uport - Pointer to uart uport structure
+ *
+ * @return - 0 if successful else negative value.
+ *
+ */
+
+static int msm_hs_spsconnect_tx(struct uart_port *uport)
+{
+	int ret;
+	struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
+	struct msm_hs_tx *tx = &msm_uport->tx;
+	struct sps_pipe *sps_pipe_handle = tx->cons.pipe_handle;
+	struct sps_connect *sps_config = &tx->cons.config;
+	struct sps_register_event *sps_event = &tx->cons.event;
+
+	/* Establish connection between peripheral and memory endpoint */
+	ret = sps_connect(sps_pipe_handle, sps_config);
+	if (ret) {
+		pr_err("msm_serial_hs: sps_connect() failed for tx!!\n"
+		"pipe_handle=0x%x ret=%d", (u32)sps_pipe_handle, ret);
+		return ret;
+	}
+	/* Register callback event for EOT (End of transfer) event. */
+	ret = sps_register_event(sps_pipe_handle, sps_event);
+	if (ret) {
+		pr_err("msm_serial_hs: sps_connect() failed for tx!!\n"
+		"pipe_handle=0x%x ret=%d", (u32)sps_pipe_handle, ret);
+		goto reg_event_err;
+	}
+	return 0;
+
+reg_event_err:
+	sps_disconnect(sps_pipe_handle);
+	return ret;
+}
+
+/* Connect a UART peripheral's SPS endpoint(producer endpoint)
+ *
+ * Also registers a SPS callback function for the producer
+ * process with the SPS driver
+ *
+ * @uport - Pointer to uart uport structure
+ *
+ * @return - 0 if successful else negative value.
+ *
+ */
+
+static int msm_hs_spsconnect_rx(struct uart_port *uport)
+{
+	int ret;
+	struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
+	struct msm_hs_rx *rx = &msm_uport->rx;
+	struct sps_pipe *sps_pipe_handle = rx->prod.pipe_handle;
+	struct sps_connect *sps_config = &rx->prod.config;
+	struct sps_register_event *sps_event = &rx->prod.event;
+
+	/* Establish connection between peripheral and memory endpoint */
+	ret = sps_connect(sps_pipe_handle, sps_config);
+	if (ret) {
+		pr_err("msm_serial_hs: sps_connect() failed for rx!!\n"
+		"pipe_handle=0x%x ret=%d", (u32)sps_pipe_handle, ret);
+		return ret;
+	}
+	/* Register callback event for EOT (End of transfer) event. */
+	ret = sps_register_event(sps_pipe_handle, sps_event);
+	if (ret) {
+		pr_err("msm_serial_hs: sps_connect() failed for rx!!\n"
+		"pipe_handle=0x%x ret=%d", (u32)sps_pipe_handle, ret);
+		goto reg_event_err;
+	}
+	return 0;
+
+reg_event_err:
+	sps_disconnect(sps_pipe_handle);
+	return ret;
+}
+
 /*
  * programs the UARTDM_CSR register with correct bit rates
  *
@@ -479,9 +651,8 @@
  * Goal is to have around 8 ms before indicate stale.
  * roundup (((Bit Rate * .008) / 10) + 1
  */
-static unsigned long msm_hs_set_bps_locked(struct uart_port *uport,
-			       unsigned int bps,
-				unsigned long flags)
+static void msm_hs_set_bps_locked(struct uart_port *uport,
+			       unsigned int bps)
 {
 	unsigned long rxstale;
 	unsigned long data;
@@ -581,15 +752,11 @@
 		uport->uartclk = 7372800;
 	}
 
-	spin_unlock_irqrestore(&uport->lock, flags);
 	if (clk_set_rate(msm_uport->clk, uport->uartclk)) {
 		printk(KERN_WARNING "Error setting clock rate on UART\n");
 		WARN_ON(1);
-		spin_lock_irqsave(&uport->lock, flags);
-		return flags;
 	}
 
-	spin_lock_irqsave(&uport->lock, flags);
 	data = rxstale & UARTDM_IPR_STALE_LSB_BMSK;
 	data |= UARTDM_IPR_STALE_TIMEOUT_MSB_BMSK & (rxstale << 2);
 
@@ -601,7 +768,6 @@
 	 */
 	msm_hs_write(uport, UARTDM_CR_ADDR, RESET_TX);
 	msm_hs_write(uport, UARTDM_CR_ADDR, RESET_RX);
-	return flags;
 }
 
 
@@ -654,6 +820,23 @@
 	msm_hs_write(uport, UARTDM_IPR_ADDR, data);
 }
 
+
+/* Reset BAM RX Endpoint Pipe Index from workqueue context*/
+
+static void hsuart_reset_bam_rx_work(struct work_struct *w)
+{
+	struct msm_hs_port *msm_uport = container_of(w, struct msm_hs_port,
+							reset_bam_rx);
+	struct uart_port *uport = &msm_uport->uport;
+	struct msm_hs_rx *rx = &msm_uport->rx;
+	struct sps_pipe *sps_pipe_handle = rx->prod.pipe_handle;
+
+	sps_disconnect(sps_pipe_handle);
+	msm_hs_spsconnect_rx(uport);
+
+	msm_serial_hs_rx_tlet((unsigned long) &rx->tlet);
+}
+
 /*
  * termios :  new ktermios
  * oldtermios:  old ktermios previous setting
@@ -666,12 +849,13 @@
 {
 	unsigned int bps;
 	unsigned long data;
-	unsigned long flags;
 	unsigned int c_cflag = termios->c_cflag;
 	struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
+	struct msm_hs_rx *rx = &msm_uport->rx;
+	struct sps_pipe *sps_pipe_handle = rx->prod.pipe_handle;
 
 	mutex_lock(&msm_uport->clk_mutex);
-	spin_lock_irqsave(&uport->lock, flags);
+	msm_hs_write(uport, UARTDM_IMR_ADDR, 0);
 
 	/*
 	 * Disable Rx channel of UARTDM
@@ -683,7 +867,13 @@
 	 * suggested to do disable/reset or reset/disable at the same time.
 	 */
 	data = msm_hs_read(uport, UARTDM_DMEN_ADDR);
-	data &= ~UARTDM_RX_DM_EN_BMSK;
+	if (is_blsp_uart(msm_uport)) {
+		/* Disable UARTDM RX BAM Interface */
+		data &= ~UARTDM_RX_BAM_ENABLE_BMSK;
+	} else {
+		data &= ~UARTDM_RX_DM_EN_BMSK;
+	}
+
 	msm_hs_write(uport, UARTDM_DMEN_ADDR, data);
 
 	/* 300 is the minimum baud support by the driver  */
@@ -697,7 +887,7 @@
 	if (!uport->uartclk)
 		msm_hs_set_std_bps_locked(uport, bps);
 	else
-		flags = msm_hs_set_bps_locked(uport, bps, flags);
+		msm_hs_set_bps_locked(uport, bps);
 
 	data = msm_hs_read(uport, UARTDM_MR2_ADDR);
 	data &= ~UARTDM_MR2_PARITY_MODE_BMSK;
@@ -754,9 +944,10 @@
 
 	uport->ignore_status_mask = termios->c_iflag & INPCK;
 	uport->ignore_status_mask |= termios->c_iflag & IGNPAR;
+	uport->ignore_status_mask |= termios->c_iflag & IGNBRK;
+
 	uport->read_status_mask = (termios->c_cflag & CREAD);
 
-	msm_hs_write(uport, UARTDM_IMR_ADDR, 0);
 
 	/* Set Transmit software time out */
 	uart_update_timeout(uport, c_cflag, bps);
@@ -773,13 +964,18 @@
 		 * dsb requires here.
 		 */
 		mb();
-		/* do discard flush */
-		msm_dmov_flush(msm_uport->dma_rx_channel, 0);
+		if (is_blsp_uart(msm_uport)) {
+			sps_disconnect(sps_pipe_handle);
+			msm_hs_spsconnect_rx(uport);
+			msm_serial_hs_rx_tlet((unsigned long) &rx->tlet);
+		} else {
+			/* do discard flush */
+			msm_dmov_flush(msm_uport->dma_rx_channel, 0);
+		}
 	}
 
 	msm_hs_write(uport, UARTDM_IMR_ADDR, msm_uport->imr_reg);
 	mb();
-	spin_unlock_irqrestore(&uport->lock, flags);
 	mutex_unlock(&msm_uport->clk_mutex);
 }
 
@@ -812,6 +1008,20 @@
 	msm_uport->tx.tx_ready_int_en = 0;
 }
 
+/* Disconnect BAM RX Endpoint Pipe Index from workqueue context*/
+static void hsuart_disconnect_rx_endpoint_work(struct work_struct *w)
+{
+	struct msm_hs_port *msm_uport = container_of(w, struct msm_hs_port,
+						disconnect_rx_endpoint);
+	struct msm_hs_rx *rx = &msm_uport->rx;
+	struct sps_pipe *sps_pipe_handle = rx->prod.pipe_handle;
+
+	sps_disconnect(sps_pipe_handle);
+	wake_lock_timeout(&msm_uport->rx.wake_lock, HZ / 2);
+	msm_uport->rx.flush = FLUSH_SHUTDOWN;
+	wake_up(&msm_uport->rx.wait);
+}
+
 /*
  *  Standard API, Stop receiver as soon as possible.
  *
@@ -827,7 +1037,10 @@
 
 	/* disable dlink */
 	data = msm_hs_read(uport, UARTDM_DMEN_ADDR);
-	data &= ~UARTDM_RX_DM_EN_BMSK;
+	if (is_blsp_uart(msm_uport))
+		data &= ~UARTDM_RX_BAM_ENABLE_BMSK;
+	else
+		data &= ~UARTDM_RX_DM_EN_BMSK;
 	msm_hs_write(uport, UARTDM_DMEN_ADDR, data);
 
 	/* calling DMOV or CLOCK API. Hence mb() */
@@ -835,11 +1048,26 @@
 	/* Disable the receiver */
 	if (msm_uport->rx.flush == FLUSH_NONE) {
 		wake_lock(&msm_uport->rx.wake_lock);
-		/* do discard flush */
-		msm_dmov_flush(msm_uport->dma_rx_channel, 0);
+		if (is_blsp_uart(msm_uport)) {
+			msm_uport->rx.flush = FLUSH_STOP;
+			/* workqueue for BAM rx endpoint disconnect */
+			queue_work(msm_uport->hsuart_wq,
+				&msm_uport->disconnect_rx_endpoint);
+		} else {
+			/* do discard flush */
+			msm_dmov_flush(msm_uport->dma_rx_channel, 0);
+		}
 	}
-	if (msm_uport->rx.flush != FLUSH_SHUTDOWN)
+	if (!is_blsp_uart(msm_uport) && msm_uport->rx.flush != FLUSH_SHUTDOWN)
 		msm_uport->rx.flush = FLUSH_STOP;
+
+	/* During uart port close, due to spurious rx stale interrupt,
+	 * the rx state machine is causing BUG_ON to be hit in
+	 * msm_hs_shutdown causing kernel panic.
+	 * Hence fixing the same by handling the rx state machine.
+	 */
+	if (is_blsp_uart(msm_uport) && msm_uport->rx.flush == FLUSH_DATA_READY)
+		msm_uport->rx.flush = FLUSH_SHUTDOWN;
 }
 
 /*  Transmit the next chunk of data */
@@ -850,9 +1078,11 @@
 	int aligned_tx_count;
 	dma_addr_t src_addr;
 	dma_addr_t aligned_src_addr;
+	u32 flags = SPS_IOVEC_FLAG_EOT;
 	struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
 	struct msm_hs_tx *tx = &msm_uport->tx;
 	struct circ_buf *tx_buf = &msm_uport->uport.state->xmit;
+	struct sps_pipe *sps_pipe_handle;
 
 	if (uart_circ_empty(tx_buf) || uport->state->port.tty->stopped) {
 		msm_hs_stop_tx_locked(uport);
@@ -880,14 +1110,21 @@
 	dma_sync_single_for_device(uport->dev, aligned_src_addr,
 			aligned_tx_count, DMA_TO_DEVICE);
 
-	tx->command_ptr->num_rows = (((tx_count + 15) >> 4) << 16) |
-				     ((tx_count + 15) >> 4);
-	tx->command_ptr->src_row_addr = src_addr;
+	if (is_blsp_uart(msm_uport)) {
+		/* Issue TX BAM Start IFC command */
+		msm_hs_write(uport, UARTDM_CR_ADDR, START_TX_BAM_IFC);
+	} else {
+		tx->command_ptr->num_rows =
+				(((tx_count + 15) >> 4) << 16) |
+				((tx_count + 15) >> 4);
+		tx->command_ptr->src_row_addr = src_addr;
 
-	dma_sync_single_for_device(uport->dev, tx->mapped_cmd_ptr,
-				   sizeof(dmov_box), DMA_TO_DEVICE);
+		dma_sync_single_for_device(uport->dev, tx->mapped_cmd_ptr,
+				sizeof(dmov_box), DMA_TO_DEVICE);
 
-	*tx->command_ptr_ptr = CMD_PTR_LP | DMOV_CMD_ADDR(tx->mapped_cmd_ptr);
+		*tx->command_ptr_ptr = CMD_PTR_LP |
+				DMOV_CMD_ADDR(tx->mapped_cmd_ptr);
+	}
 
 	/* Save tx_count to use in Callback */
 	tx->tx_count = tx_count;
@@ -899,16 +1136,28 @@
 	/* Calling next DMOV API. Hence mb() here. */
 	mb();
 
-	dma_sync_single_for_device(uport->dev, tx->mapped_cmd_ptr_ptr,
-				   sizeof(u32), DMA_TO_DEVICE);
 	msm_uport->tx.flush = FLUSH_NONE;
-	msm_dmov_enqueue_cmd(msm_uport->dma_tx_channel, &tx->xfer);
+
+	if (is_blsp_uart(msm_uport)) {
+		sps_pipe_handle = tx->cons.pipe_handle;
+		/* Queue transfer request to SPS */
+		sps_transfer_one(sps_pipe_handle, src_addr, tx_count,
+					msm_uport, flags);
+	} else {
+		dma_sync_single_for_device(uport->dev, tx->mapped_cmd_ptr_ptr,
+			sizeof(u32), DMA_TO_DEVICE);
+
+		msm_dmov_enqueue_cmd(msm_uport->dma_tx_channel, &tx->xfer);
+	}
 }
 
 /* Start to receive the next chunk of data */
 static void msm_hs_start_rx_locked(struct uart_port *uport)
 {
 	struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
+	struct msm_hs_rx *rx = &msm_uport->rx;
+	struct sps_pipe *sps_pipe_handle;
+	u32 flags = SPS_IOVEC_FLAG_EOT;
 	unsigned int buffer_pending = msm_uport->rx.buffer_pending;
 	unsigned int data;
 
@@ -917,6 +1166,10 @@
 		printk(KERN_ERR "Error: rx started in buffer state = %x",
 		       buffer_pending);
 
+	if (is_blsp_uart(msm_uport)) {
+		/* Issue RX BAM Start IFC command */
+		msm_hs_write(uport, UARTDM_CR_ADDR, START_RX_BAM_IFC);
+	}
 	msm_hs_write(uport, UARTDM_CR_ADDR, RESET_STALE_INT);
 	msm_hs_write(uport, UARTDM_DMRX_ADDR, UARTDM_RX_BUF_SIZE);
 	msm_hs_write(uport, UARTDM_CR_ADDR, STALE_EVENT_ENABLE);
@@ -927,15 +1180,29 @@
 	 * disable in set_termios before configuring baud rate.
 	 */
 	data = msm_hs_read(uport, UARTDM_DMEN_ADDR);
-	data |= UARTDM_RX_DM_EN_BMSK;
+	if (is_blsp_uart(msm_uport)) {
+		/* Enable UARTDM Rx BAM Interface */
+		data |= UARTDM_RX_BAM_ENABLE_BMSK;
+	} else {
+		data |= UARTDM_RX_DM_EN_BMSK;
+	}
+
 	msm_hs_write(uport, UARTDM_DMEN_ADDR, data);
 	msm_hs_write(uport, UARTDM_IMR_ADDR, msm_uport->imr_reg);
 	/* Calling next DMOV API. Hence mb() here. */
 	mb();
 
 	msm_uport->rx.flush = FLUSH_NONE;
-	msm_dmov_enqueue_cmd(msm_uport->dma_rx_channel, &msm_uport->rx.xfer);
 
+	if (is_blsp_uart(msm_uport)) {
+		sps_pipe_handle = rx->prod.pipe_handle;
+		/* Queue transfer request to SPS */
+		sps_transfer_one(sps_pipe_handle, rx->rbuffer,
+			UARTDM_RX_BUF_SIZE, msm_uport, flags);
+	} else {
+		msm_dmov_enqueue_cmd(msm_uport->dma_rx_channel,
+				&msm_uport->rx.xfer);
+	}
 }
 
 static void flip_insert_work(struct work_struct *work)
@@ -997,6 +1264,7 @@
 {
 	int retval;
 	int rx_count;
+	static int remaining_rx_count, bytes_pending;
 	unsigned long status;
 	unsigned long flags;
 	unsigned int error_f = 0;
@@ -1031,15 +1299,29 @@
 
 	if (unlikely(status & UARTDM_SR_PAR_FRAME_BMSK)) {
 		/* Can not tell difference between parity & frame error */
+		if (hs_serial_debug_mask)
+			printk(KERN_WARNING "msm_serial_hs: parity error\n");
 		uport->icount.parity++;
 		error_f = 1;
-		if (uport->ignore_status_mask & IGNPAR) {
+		if (!(uport->ignore_status_mask & IGNPAR)) {
 			retval = tty_insert_flip_char(tty, 0, TTY_PARITY);
 			if (!retval)
 				msm_uport->rx.buffer_pending |= TTY_PARITY;
 		}
 	}
 
+	if (unlikely(status & UARTDM_SR_RX_BREAK_BMSK)) {
+		if (hs_serial_debug_mask)
+			printk(KERN_WARNING "msm_serial_hs: Rx break\n");
+		uport->icount.brk++;
+		error_f = 1;
+		if (!(uport->ignore_status_mask & IGNBRK)) {
+			retval = tty_insert_flip_char(tty, 0, TTY_BREAK);
+			if (!retval)
+				msm_uport->rx.buffer_pending |= TTY_BREAK;
+		}
+	}
+
 	if (error_f)
 		msm_hs_write(uport, UARTDM_CR_ADDR, RESET_ERROR_STATUS);
 
@@ -1059,6 +1341,20 @@
 
 	rx_count = msm_hs_read(uport, UARTDM_RX_TOTAL_SNAP_ADDR);
 
+	if (is_blsp_uart(msm_uport)) {
+		if (rx_count > UARTDM_RX_BUF_SIZE) {
+			if (bytes_pending) {
+				rx_count = remaining_rx_count;
+				bytes_pending = 0;
+			} else {
+				remaining_rx_count = rx_count -
+						UARTDM_RX_BUF_SIZE;
+				if (remaining_rx_count)
+					bytes_pending = 1;
+				rx_count = UARTDM_RX_BUF_SIZE;
+			}
+		}
+	}
 	/* order the read of rx.buffer */
 	rmb();
 
@@ -1108,6 +1404,31 @@
 	}
 }
 
+/**
+ * Callback notification from SPS driver
+ *
+ * This callback function gets triggered called from
+ * SPS driver when requested SPS data transfer is
+ * completed.
+ *
+ */
+
+static void msm_hs_sps_tx_callback(struct sps_event_notify *notify)
+{
+	struct msm_hs_port *msm_uport =
+		(struct msm_hs_port *)
+		((struct sps_event_notify *)notify)->user;
+
+	msm_uport->notify = *notify;
+	pr_debug("%s: sps ev_id=%d, addr=0x%x, size=0x%x, flags=0x%x\n",
+		__func__, notify->event_id,
+		notify->data.transfer.iovec.addr,
+		notify->data.transfer.iovec.size,
+		notify->data.transfer.iovec.flags);
+
+	tasklet_schedule(&msm_uport->tx.tlet);
+}
+
 /*
  *  This routine is called when we are done with a DMA transfer
  *
@@ -1154,6 +1475,33 @@
 	spin_unlock_irqrestore(&(msm_uport->uport.lock), flags);
 }
 
+/**
+ * Callback notification from SPS driver
+ *
+ * This callback function gets triggered called from
+ * SPS driver when requested SPS data transfer is
+ * completed.
+ *
+ */
+
+static void msm_hs_sps_rx_callback(struct sps_event_notify *notify)
+{
+
+	struct msm_hs_port *msm_uport =
+		(struct msm_hs_port *)
+		((struct sps_event_notify *)notify)->user;
+
+	msm_uport->notify = *notify;
+	pr_debug("%s: sps ev_id=%d, addr=0x%x, size=0x%x, flags=0x%x\n",
+		__func__, notify->event_id,
+		notify->data.transfer.iovec.addr,
+		notify->data.transfer.iovec.size,
+		notify->data.transfer.iovec.flags);
+
+	if (msm_uport->rx.flush == FLUSH_NONE)
+		tasklet_schedule(&msm_uport->rx.tlet);
+}
+
 /*
  * This routine is called when we are done with a DMA transfer or the
  * a flush has been sent to the data mover driver.
@@ -1249,7 +1597,8 @@
 {
 	struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
 
-	msm_uport->tty_flush_receive = true;
+	if (msm_uport->tx.dma_in_flight)
+		msm_uport->tty_flush_receive = true;
 }
 
 /*
@@ -1340,6 +1689,14 @@
 	switch (msm_uport->clk_req_off_state) {
 	case CLK_REQ_OFF_START:
 		msm_uport->clk_req_off_state = CLK_REQ_OFF_RXSTALE_ISSUED;
+		if (is_blsp_uart(msm_uport)) {
+			/* Stale interrupt when RX-FIFO is empty
+			 * will fire if STALE_IRQ_EMPTY bit is set
+			 * for UART Core v1.4
+			 */
+			msm_hs_write(uport, UARTDM_BCR_ADDR,
+					UARTDM_BCR_STALE_IRQ_EMPTY);
+		}
 		msm_hs_write(uport, UARTDM_CR_ADDR, FORCE_STALE_EVENT);
 		/*
 		 * Before returning make sure that device writel completed.
@@ -1384,7 +1741,11 @@
 	wake_unlock(&msm_uport->dma_wake_lock);
 
 	spin_unlock_irqrestore(&uport->lock, flags);
+
+	/* Reset PNOC Bus Scaling */
+	msm_hs_bus_voting(msm_uport, BUS_RESET);
 	mutex_unlock(&msm_uport->clk_mutex);
+
 	return 1;
 }
 
@@ -1442,13 +1803,25 @@
 		 */
 		mb();
 
-		if (msm_uport->clk_req_off_state == CLK_REQ_OFF_RXSTALE_ISSUED)
+		if (msm_uport->clk_req_off_state ==
+					CLK_REQ_OFF_RXSTALE_ISSUED) {
 			msm_uport->clk_req_off_state =
 				CLK_REQ_OFF_FLUSH_ISSUED;
 
+			if (is_blsp_uart(msm_uport)) {
+				/* Reset BCR Register for UARTDM Core v14*/
+				msm_hs_write(uport, UARTDM_BCR_ADDR, 0x0);
+			}
+		}
+
 		if (rx->flush == FLUSH_NONE) {
 			rx->flush = FLUSH_DATA_READY;
-			msm_dmov_flush(msm_uport->dma_rx_channel, 1);
+			if (is_blsp_uart(msm_uport)) {
+				queue_work(msm_uport->hsuart_wq,
+					&msm_uport->reset_bam_rx);
+			} else {
+				msm_dmov_flush(msm_uport->dma_rx_channel, 1);
+			}
 		}
 	}
 	/* tx ready interrupt */
@@ -1542,6 +1915,10 @@
 		wake_lock(&msm_uport->dma_wake_lock);
 		disable_irq_nosync(msm_uport->wakeup.irq);
 		spin_unlock_irqrestore(&uport->lock, flags);
+
+		/* Vote for PNOC BUS Scaling */
+		msm_hs_bus_voting(msm_uport, BUS_SCALING);
+
 		ret = clk_prepare_enable(msm_uport->clk);
 		if (ret) {
 			dev_err(uport->dev, "Clock ON Failure"
@@ -1565,7 +1942,10 @@
 		    msm_uport->rx.flush == FLUSH_SHUTDOWN) {
 			msm_hs_write(uport, UARTDM_CR_ADDR, RESET_RX);
 			data = msm_hs_read(uport, UARTDM_DMEN_ADDR);
-			data |= UARTDM_RX_DM_EN_BMSK;
+			if (is_blsp_uart(msm_uport))
+				data |= UARTDM_RX_BAM_ENABLE_BMSK;
+			else
+				data |= UARTDM_RX_DM_EN_BMSK;
 			msm_hs_write(uport, UARTDM_DMEN_ADDR, data);
 			/* Complete above device write. Hence mb() here. */
 			mb();
@@ -1632,6 +2012,100 @@
 	return ("MSM HS UART");
 }
 
+/**
+ * msm_hs_unconfig_uart_gpios: Unconfigures UART GPIOs
+ * @uport: uart port
+ */
+static void msm_hs_unconfig_uart_gpios(struct uart_port *uport)
+{
+	struct platform_device *pdev = to_platform_device(uport->dev);
+	const struct msm_serial_hs_platform_data *pdata =
+					pdev->dev.platform_data;
+
+	if (pdata) {
+		if (gpio_is_valid(pdata->uart_tx_gpio))
+			gpio_free(pdata->uart_tx_gpio);
+		if (gpio_is_valid(pdata->uart_rx_gpio))
+			gpio_free(pdata->uart_rx_gpio);
+		if (gpio_is_valid(pdata->uart_cts_gpio))
+			gpio_free(pdata->uart_cts_gpio);
+		if (gpio_is_valid(pdata->uart_rfr_gpio))
+			gpio_free(pdata->uart_rfr_gpio);
+	} else {
+		pr_err("Error:Pdata is NULL.\n");
+	}
+}
+
+/**
+ * msm_hs_config_uart_gpios - Configures UART GPIOs
+ * @uport: uart port
+ */
+static int msm_hs_config_uart_gpios(struct uart_port *uport)
+{
+	struct platform_device *pdev = to_platform_device(uport->dev);
+	const struct msm_serial_hs_platform_data *pdata =
+					pdev->dev.platform_data;
+	int ret = 0;
+
+	if (pdata) {
+		if (gpio_is_valid(pdata->uart_tx_gpio)) {
+			ret = gpio_request(pdata->uart_tx_gpio,
+							"UART_TX_GPIO");
+			if (unlikely(ret)) {
+				pr_err("gpio request failed for:%d\n",
+					pdata->uart_tx_gpio);
+				goto exit_uart_config;
+			}
+		}
+
+		if (gpio_is_valid(pdata->uart_rx_gpio)) {
+			ret = gpio_request(pdata->uart_rx_gpio,
+							"UART_RX_GPIO");
+			if (unlikely(ret)) {
+				pr_err("gpio request failed for:%d\n",
+					pdata->uart_rx_gpio);
+				goto uart_tx_unconfig;
+			}
+		}
+
+		if (gpio_is_valid(pdata->uart_cts_gpio)) {
+			ret = gpio_request(pdata->uart_cts_gpio,
+							"UART_CTS_GPIO");
+			if (unlikely(ret)) {
+				pr_err("gpio request failed for:%d\n",
+					pdata->uart_cts_gpio);
+				goto uart_rx_unconfig;
+			}
+		}
+
+		if (gpio_is_valid(pdata->uart_rfr_gpio)) {
+			ret = gpio_request(pdata->uart_rfr_gpio,
+							"UART_RFR_GPIO");
+			if (unlikely(ret)) {
+				pr_err("gpio request failed for:%d\n",
+					pdata->uart_rfr_gpio);
+				goto uart_cts_unconfig;
+			}
+		}
+	} else {
+		pr_err("Pdata is NULL.\n");
+		ret = -EINVAL;
+	}
+	return ret;
+
+uart_cts_unconfig:
+	if (gpio_is_valid(pdata->uart_cts_gpio))
+		gpio_free(pdata->uart_cts_gpio);
+uart_rx_unconfig:
+	if (gpio_is_valid(pdata->uart_rx_gpio))
+		gpio_free(pdata->uart_rx_gpio);
+uart_tx_unconfig:
+	if (gpio_is_valid(pdata->uart_tx_gpio))
+		gpio_free(pdata->uart_tx_gpio);
+exit_uart_config:
+	return ret;
+}
+
 /* Called when port is opened */
 static int msm_hs_startup(struct uart_port *uport)
 {
@@ -1645,6 +2119,9 @@
 					pdev->dev.platform_data;
 	struct circ_buf *tx_buf = &uport->state->xmit;
 	struct msm_hs_tx *tx = &msm_uport->tx;
+	struct msm_hs_rx *rx = &msm_uport->rx;
+	struct sps_pipe *sps_pipe_handle_tx = tx->cons.pipe_handle;
+	struct sps_pipe *sps_pipe_handle_rx = rx->prod.pipe_handle;
 
 	rfr_level = uport->fifosize;
 	if (rfr_level > 16)
@@ -1662,9 +2139,34 @@
 		return ret;
 	}
 
-	if (pdata && pdata->gpio_config)
-		if (unlikely(pdata->gpio_config(1)))
-			dev_err(uport->dev, "Cannot configure gpios\n");
+	if (is_blsp_uart(msm_uport)) {
+		ret = msm_hs_config_uart_gpios(uport);
+		if (ret) {
+			pr_err("Uart GPIO request failed\n");
+			goto deinit_uart_clk;
+		}
+	} else {
+		if (pdata && pdata->gpio_config)
+			if (unlikely(pdata->gpio_config(1)))
+				dev_err(uport->dev, "Cannot configure gpios\n");
+	}
+
+	/* SPS Connect for BAM endpoints */
+	if (is_blsp_uart(msm_uport)) {
+		/* SPS connect for TX */
+		ret = msm_hs_spsconnect_tx(uport);
+		if (ret) {
+			pr_err("msm_serial_hs: SPS connect failed for TX");
+			goto unconfig_uart_gpios;
+		}
+
+		/* SPS connect for RX */
+		ret = msm_hs_spsconnect_rx(uport);
+		if (ret) {
+			pr_err("msm_serial_hs: SPS connect failed for RX");
+			goto sps_disconnect_tx;
+		}
+	}
 
 	/* Set auto RFR Level */
 	data = msm_hs_read(uport, UARTDM_MR1_ADDR);
@@ -1681,8 +2183,13 @@
 		msm_hs_write(uport, UARTDM_IPR_ADDR, data);
 	}
 
-	/* Enable Data Mover Mode */
-	data = UARTDM_TX_DM_EN_BMSK | UARTDM_RX_DM_EN_BMSK;
+	if (is_blsp_uart(msm_uport)) {
+		/* Enable BAM mode */
+		data  = UARTDM_TX_BAM_ENABLE_BMSK | UARTDM_RX_BAM_ENABLE_BMSK;
+	} else {
+		/* Enable Data Mover Mode */
+		data = UARTDM_TX_DM_EN_BMSK | UARTDM_RX_DM_EN_BMSK;
+	}
 	msm_hs_write(uport, UARTDM_DMEN_ADDR, data);
 
 	/* Reset TX */
@@ -1703,18 +2210,20 @@
 	tx->tx_ready_int_en = 0;
 	tx->dma_in_flight = 0;
 
-	tx->xfer.complete_func = msm_hs_dmov_tx_callback;
+	if (!is_blsp_uart(msm_uport)) {
+		tx->xfer.complete_func = msm_hs_dmov_tx_callback;
 
-	tx->command_ptr->cmd = CMD_LC |
-	    CMD_DST_CRCI(msm_uport->dma_tx_crci) | CMD_MODE_BOX;
+		tx->command_ptr->cmd = CMD_LC |
+			CMD_DST_CRCI(msm_uport->dma_tx_crci) | CMD_MODE_BOX;
 
-	tx->command_ptr->src_dst_len = (MSM_UARTDM_BURST_SIZE << 16)
+		tx->command_ptr->src_dst_len = (MSM_UARTDM_BURST_SIZE << 16)
 					   | (MSM_UARTDM_BURST_SIZE);
 
-	tx->command_ptr->row_offset = (MSM_UARTDM_BURST_SIZE << 16);
+		tx->command_ptr->row_offset = (MSM_UARTDM_BURST_SIZE << 16);
 
-	tx->command_ptr->dst_row_addr =
-	    msm_uport->uport.mapbase + UARTDM_TF_ADDR;
+		tx->command_ptr->dst_row_addr =
+			msm_uport->uport.mapbase + UARTDM_TF_ADDR;
+	}
 
 	msm_uport->imr_reg |= UARTDM_ISR_RXSTALE_BMSK;
 	/* Enable reading the current CTS, no harm even if CTS is ignored */
@@ -1731,7 +2240,7 @@
 		ret = irq_set_irq_wake(msm_uport->wakeup.irq, 1);
 		if (unlikely(ret)) {
 			pr_err("%s():Err setting wakeup irq\n", __func__);
-			goto deinit_uart_clk;
+			goto sps_disconnect_rx;
 		}
 	}
 
@@ -1755,6 +2264,9 @@
 		disable_irq(msm_uport->wakeup.irq);
 	}
 
+	/* Vote for PNOC BUS Scaling */
+	msm_hs_bus_voting(msm_uport, BUS_SCALING);
+
 	spin_lock_irqsave(&uport->lock, flags);
 
 	msm_hs_start_rx_locked(uport);
@@ -1771,6 +2283,15 @@
 	free_irq(uport->irq, msm_uport);
 free_wake_irq:
 	irq_set_irq_wake(msm_uport->wakeup.irq, 0);
+sps_disconnect_rx:
+	if (is_blsp_uart(msm_uport))
+		sps_disconnect(sps_pipe_handle_rx);
+sps_disconnect_tx:
+	if (is_blsp_uart(msm_uport))
+		sps_disconnect(sps_pipe_handle_tx);
+unconfig_uart_gpios:
+	if (is_blsp_uart(msm_uport))
+		msm_hs_unconfig_uart_gpios(uport);
 deinit_uart_clk:
 	clk_disable_unprepare(msm_uport->clk);
 	if (msm_uport->pclk)
@@ -1788,24 +2309,6 @@
 	struct msm_hs_tx *tx = &msm_uport->tx;
 	struct msm_hs_rx *rx = &msm_uport->rx;
 
-	/* Allocate the command pointer. Needs to be 64 bit aligned */
-	tx->command_ptr = kmalloc(sizeof(dmov_box), GFP_KERNEL | __GFP_DMA);
-	if (!tx->command_ptr)
-		return -ENOMEM;
-
-	tx->command_ptr_ptr = kmalloc(sizeof(u32), GFP_KERNEL | __GFP_DMA);
-	if (!tx->command_ptr_ptr) {
-		ret = -ENOMEM;
-		goto free_tx_command_ptr;
-	}
-
-	tx->mapped_cmd_ptr = dma_map_single(uport->dev, tx->command_ptr,
-					    sizeof(dmov_box), DMA_TO_DEVICE);
-	tx->mapped_cmd_ptr_ptr = dma_map_single(uport->dev,
-						tx->command_ptr_ptr,
-						sizeof(u32), DMA_TO_DEVICE);
-	tx->xfer.cmdptr = DMOV_CMD_ADDR(tx->mapped_cmd_ptr_ptr);
-
 	init_waitqueue_head(&rx->wait);
 	init_waitqueue_head(&tx->wait);
 	wake_lock_init(&rx->wake_lock, WAKE_LOCK_SUSPEND, "msm_serial_hs_rx");
@@ -1832,12 +2335,40 @@
 		goto free_pool;
 	}
 
+	/* Set up Uart Receive */
+	msm_hs_write(uport, UARTDM_RFWR_ADDR, 0);
+
+	INIT_DELAYED_WORK(&rx->flip_insert_work, flip_insert_work);
+
+	if (is_blsp_uart(msm_uport))
+		return ret;
+
+	/* Allocate the command pointer. Needs to be 64 bit aligned */
+	tx->command_ptr = kmalloc(sizeof(dmov_box), GFP_KERNEL | __GFP_DMA);
+	if (!tx->command_ptr) {
+		return -ENOMEM;
+		goto free_rx_buffer;
+	}
+
+	tx->command_ptr_ptr = kmalloc(sizeof(u32), GFP_KERNEL | __GFP_DMA);
+	if (!tx->command_ptr_ptr) {
+		ret = -ENOMEM;
+		goto free_tx_command_ptr;
+	}
+
+	tx->mapped_cmd_ptr = dma_map_single(uport->dev, tx->command_ptr,
+					sizeof(dmov_box), DMA_TO_DEVICE);
+	tx->mapped_cmd_ptr_ptr = dma_map_single(uport->dev,
+						tx->command_ptr_ptr,
+						sizeof(u32), DMA_TO_DEVICE);
+	tx->xfer.cmdptr = DMOV_CMD_ADDR(tx->mapped_cmd_ptr_ptr);
+
 	/* Allocate the command pointer. Needs to be 64 bit aligned */
 	rx->command_ptr = kmalloc(sizeof(dmov_box), GFP_KERNEL | __GFP_DMA);
 	if (!rx->command_ptr) {
 		pr_err("%s(): cannot allocate rx->command_ptr", __func__);
 		ret = -ENOMEM;
-		goto free_rx_buffer;
+		goto free_tx_command_ptr_ptr;
 	}
 
 	rx->command_ptr_ptr = kmalloc(sizeof(u32), GFP_KERNEL | __GFP_DMA);
@@ -1852,9 +2383,6 @@
 
 	rx->command_ptr->dst_row_addr = rx->rbuffer;
 
-	/* Set up Uart Receive */
-	msm_hs_write(uport, UARTDM_RFWR_ADDR, 0);
-
 	rx->xfer.complete_func = msm_hs_dmov_rx_callback;
 
 	rx->command_ptr->cmd = CMD_LC |
@@ -1874,13 +2402,21 @@
 					    sizeof(u32), DMA_TO_DEVICE);
 	rx->xfer.cmdptr = DMOV_CMD_ADDR(rx->cmdptr_dmaaddr);
 
-	INIT_DELAYED_WORK(&rx->flip_insert_work, flip_insert_work);
-
 	return ret;
 
 free_rx_command_ptr:
 	kfree(rx->command_ptr);
 
+free_tx_command_ptr_ptr:
+	kfree(msm_uport->tx.command_ptr_ptr);
+	dma_unmap_single(uport->dev, msm_uport->tx.mapped_cmd_ptr_ptr,
+			sizeof(u32), DMA_TO_DEVICE);
+	dma_unmap_single(uport->dev, msm_uport->tx.mapped_cmd_ptr,
+			sizeof(dmov_box), DMA_TO_DEVICE);
+
+free_tx_command_ptr:
+	kfree(msm_uport->tx.command_ptr);
+
 free_rx_buffer:
 	dma_pool_free(msm_uport->rx.pool, msm_uport->rx.buffer,
 			msm_uport->rx.rbuffer);
@@ -1893,47 +2429,427 @@
 	wake_lock_destroy(&msm_uport->dma_wake_lock);
 	tasklet_kill(&msm_uport->tx.tlet);
 	tasklet_kill(&msm_uport->rx.tlet);
-	dma_unmap_single(uport->dev, msm_uport->tx.mapped_cmd_ptr_ptr,
-			sizeof(u32), DMA_TO_DEVICE);
-	dma_unmap_single(uport->dev, msm_uport->tx.mapped_cmd_ptr,
-			sizeof(dmov_box), DMA_TO_DEVICE);
-	kfree(msm_uport->tx.command_ptr_ptr);
-
-free_tx_command_ptr:
-	kfree(msm_uport->tx.command_ptr);
 	return ret;
 }
 
+struct msm_serial_hs_platform_data
+	*msm_hs_dt_to_pdata(struct platform_device *pdev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	struct msm_serial_hs_platform_data *pdata;
+	int rx_to_inject, ret;
+
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		pr_err("unable to allocate memory for platform data\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	/* UART TX GPIO */
+	pdata->uart_tx_gpio = of_get_named_gpio(node,
+					"qcom,tx-gpio", 0);
+	if (pdata->uart_tx_gpio < 0)
+		pr_debug("uart_tx_gpio is not available\n");
+
+	/* UART RX GPIO */
+	pdata->uart_rx_gpio = of_get_named_gpio(node,
+					"qcom,rx-gpio", 0);
+	if (pdata->uart_rx_gpio < 0)
+		pr_debug("uart_rx_gpio is not available\n");
+
+	/* UART CTS GPIO */
+	pdata->uart_cts_gpio = of_get_named_gpio(node,
+					"qcom,cts-gpio", 0);
+	if (pdata->uart_cts_gpio < 0)
+		pr_debug("uart_cts_gpio is not available\n");
+
+	/* UART RFR GPIO */
+	pdata->uart_rfr_gpio = of_get_named_gpio(node,
+					"qcom,rfr-gpio", 0);
+	if (pdata->uart_rfr_gpio < 0)
+		pr_debug("uart_rfr_gpio is not available\n");
+
+	pdata->inject_rx_on_wakeup = of_property_read_bool(node,
+				"qcom,inject-rx-on-wakeup");
+
+	if (pdata->inject_rx_on_wakeup) {
+		ret = of_property_read_u32(node, "qcom,rx-char-to-inject",
+						&rx_to_inject);
+		if (ret < 0) {
+			pr_err("Error: Rx_char_to_inject not specified.\n");
+			return ERR_PTR(ret);
+		}
+		pdata->rx_to_inject = (char)rx_to_inject;
+	}
+
+	ret = of_property_read_u32(node, "qcom,bam-tx-ep-pipe-index",
+				&pdata->bam_tx_ep_pipe_index);
+	if (ret < 0) {
+		pr_err("Error: Getting UART BAM TX EP Pipe Index.\n");
+		return ERR_PTR(ret);
+	}
+
+	if (!(pdata->bam_tx_ep_pipe_index >= BAM_PIPE_MIN &&
+		pdata->bam_tx_ep_pipe_index <= BAM_PIPE_MAX)) {
+		pr_err("Error: Invalid UART BAM TX EP Pipe Index.\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	ret = of_property_read_u32(node, "qcom,bam-rx-ep-pipe-index",
+					&pdata->bam_rx_ep_pipe_index);
+	if (ret < 0) {
+		pr_err("Error: Getting UART BAM RX EP Pipe Index.\n");
+		return ERR_PTR(ret);
+	}
+
+	if (!(pdata->bam_rx_ep_pipe_index >= BAM_PIPE_MIN &&
+		pdata->bam_rx_ep_pipe_index <= BAM_PIPE_MAX)) {
+		pr_err("Error: Invalid UART BAM RX EP Pipe Index.\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	pr_debug("tx_ep_pipe_index:%d rx_ep_pipe_index:%d\n"
+		"tx_gpio:%d rx_gpio:%d rfr_gpio:%d cts_gpio:%d",
+		pdata->bam_tx_ep_pipe_index, pdata->bam_rx_ep_pipe_index,
+		pdata->uart_tx_gpio, pdata->uart_rx_gpio, pdata->uart_cts_gpio,
+		pdata->uart_rfr_gpio);
+
+	return pdata;
+}
+
+
+/**
+ * Deallocate UART peripheral's SPS endpoint
+ * @msm_uport - Pointer to msm_hs_port structure
+ * @ep - Pointer to sps endpoint data structure
+ */
+
+static void msm_hs_exit_ep_conn(struct msm_hs_port *msm_uport,
+				struct msm_hs_sps_ep_conn_data *ep)
+{
+	struct sps_pipe *sps_pipe_handle = ep->pipe_handle;
+	struct sps_connect *sps_config = &ep->config;
+
+	dma_free_coherent(msm_uport->uport.dev,
+			sps_config->desc.size,
+			&sps_config->desc.phys_base,
+			GFP_KERNEL);
+	sps_free_endpoint(sps_pipe_handle);
+}
+
+
+/**
+ * Allocate UART peripheral's SPS endpoint
+ *
+ * This function allocates endpoint context
+ * by calling appropriate SPS driver APIs.
+ *
+ * @msm_uport - Pointer to msm_hs_port structure
+ * @ep - Pointer to sps endpoint data structure
+ * @is_produce - 1 means Producer endpoint
+ *             - 0 means Consumer endpoint
+ *
+ * @return - 0 if successful else negative value
+ */
+
+static int msm_hs_sps_init_ep_conn(struct msm_hs_port *msm_uport,
+				struct msm_hs_sps_ep_conn_data *ep,
+				bool is_producer)
+{
+	int rc = 0;
+	struct sps_pipe *sps_pipe_handle;
+	struct sps_connect *sps_config = &ep->config;
+	struct sps_register_event *sps_event = &ep->event;
+
+	/* Allocate endpoint context */
+	sps_pipe_handle = sps_alloc_endpoint();
+	if (!sps_pipe_handle) {
+		pr_err("msm_serial_hs: sps_alloc_endpoint() failed!!\n"
+			"is_producer=%d", is_producer);
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	/* Get default connection configuration for an endpoint */
+	rc = sps_get_config(sps_pipe_handle, sps_config);
+	if (rc) {
+		pr_err("msm_serial_hs: sps_get_config() failed!!\n"
+		"pipe_handle=0x%x rc=%d", (u32)sps_pipe_handle, rc);
+		goto get_config_err;
+	}
+
+	/* Modify the default connection configuration */
+	if (is_producer) {
+		/* For UART producer transfer, source is UART peripheral
+		where as destination is system memory */
+		sps_config->source = msm_uport->bam_handle;
+		sps_config->destination = SPS_DEV_HANDLE_MEM;
+		sps_config->mode = SPS_MODE_SRC;
+		sps_config->src_pipe_index = msm_uport->bam_rx_ep_pipe_index;
+		sps_config->dest_pipe_index = 0;
+		sps_config->options = SPS_O_EOT;
+	} else {
+		/* For UART consumer transfer, source is system memory
+		where as destination is UART peripheral */
+		sps_config->source = SPS_DEV_HANDLE_MEM;
+		sps_config->destination = msm_uport->bam_handle;
+		sps_config->mode = SPS_MODE_DEST;
+		sps_config->src_pipe_index = 0;
+		sps_config->dest_pipe_index = msm_uport->bam_tx_ep_pipe_index;
+		sps_config->options = SPS_O_EOT;
+	}
+
+	sps_config->event_thresh = 0x10;
+
+	/* Allocate maximum descriptor fifo size */
+	sps_config->desc.size = 65532;
+	sps_config->desc.base = dma_alloc_coherent(msm_uport->uport.dev,
+						sps_config->desc.size,
+						&sps_config->desc.phys_base,
+						GFP_KERNEL);
+	if (!sps_config->desc.base) {
+		rc = -ENOMEM;
+		pr_err("msm_serial_hs: dma_alloc_coherent() failed!!\n");
+		goto get_config_err;
+	}
+	memset(sps_config->desc.base, 0x00, sps_config->desc.size);
+
+	sps_event->mode = SPS_TRIGGER_CALLBACK;
+	sps_event->options = SPS_O_EOT;
+	if (is_producer)
+		sps_event->callback = msm_hs_sps_rx_callback;
+	else
+		sps_event->callback = msm_hs_sps_tx_callback;
+
+	sps_event->user = (void *)msm_uport;
+
+	/* Now save the sps pipe handle */
+	ep->pipe_handle = sps_pipe_handle;
+	pr_debug("msm_serial_hs: success !! %s: pipe_handle=0x%x\n"
+		"desc_fifo.phys_base=0x%x\n",
+		is_producer ? "READ" : "WRITE",
+		(u32)sps_pipe_handle, sps_config->desc.phys_base);
+	return 0;
+
+get_config_err:
+	sps_free_endpoint(sps_pipe_handle);
+out:
+	return rc;
+}
+
+/**
+ * Initialize SPS HW connected with UART core
+ *
+ * This function register BAM HW resources with
+ * SPS driver and then initialize 2 SPS endpoints
+ *
+ * msm_uport - Pointer to msm_hs_port structure
+ *
+ * @return - 0 if successful else negative value
+ */
+
+static int msm_hs_sps_init(struct msm_hs_port *msm_uport)
+{
+	int rc = 0;
+	struct sps_bam_props bam = {0};
+	u32 bam_handle;
+
+	rc = sps_phy2h(msm_uport->bam_mem, &bam_handle);
+	if (rc || !bam_handle) {
+		bam.phys_addr = msm_uport->bam_mem;
+		bam.virt_addr = msm_uport->bam_base;
+		/*
+		 * This event thresold value is only significant for BAM-to-BAM
+		 * transfer. It's ignored for BAM-to-System mode transfer.
+		 */
+		bam.event_threshold = 0x10;	/* Pipe event threshold */
+		bam.summing_threshold = 1;	/* BAM event threshold */
+
+		/* SPS driver wll handle the UART BAM IRQ */
+		bam.irq = (u32)msm_uport->bam_irq;
+		bam.manage = SPS_BAM_MGR_LOCAL;
+
+		pr_debug("msm_serial_hs: bam physical base=0x%x\n",
+							(u32)bam.phys_addr);
+		pr_debug("msm_serial_hs: bam virtual base=0x%x\n",
+							(u32)bam.virt_addr);
+
+		/* Register UART Peripheral BAM device to SPS driver */
+		rc = sps_register_bam_device(&bam, &bam_handle);
+		if (rc) {
+			pr_err("msm_serial_hs: BAM device register failed\n");
+			return rc;
+		}
+		pr_info("msm_serial_hs: BAM device registered. bam_handle=0x%x",
+							msm_uport->bam_handle);
+	}
+	msm_uport->bam_handle = bam_handle;
+
+	rc = msm_hs_sps_init_ep_conn(msm_uport, &msm_uport->rx.prod,
+				UART_SPS_PROD_PERIPHERAL);
+	if (rc) {
+		pr_err("%s: Failed to Init Producer BAM-pipe", __func__);
+		goto deregister_bam;
+	}
+
+	rc = msm_hs_sps_init_ep_conn(msm_uport, &msm_uport->tx.cons,
+				UART_SPS_CONS_PERIPHERAL);
+	if (rc) {
+		pr_err("%s: Failed to Init Consumer BAM-pipe", __func__);
+		goto deinit_ep_conn_prod;
+	}
+	return 0;
+
+deinit_ep_conn_prod:
+	msm_hs_exit_ep_conn(msm_uport, &msm_uport->rx.prod);
+deregister_bam:
+	sps_deregister_bam_device(msm_uport->bam_handle);
+	return rc;
+}
+
+#define BLSP_UART_NR	12
+static int deviceid[BLSP_UART_NR] = {0};
+static atomic_t msm_serial_hs_next_id = ATOMIC_INIT(0);
+
 static int __devinit msm_hs_probe(struct platform_device *pdev)
 {
-	int ret;
+	int ret = 0, alias_num = -1;
 	struct uart_port *uport;
 	struct msm_hs_port *msm_uport;
+	struct resource *core_resource;
+	struct resource *bam_resource;
 	struct resource *resource;
+	int core_irqres, bam_irqres;
 	struct msm_serial_hs_platform_data *pdata = pdev->dev.platform_data;
 
+	if (pdev->dev.of_node) {
+		dev_dbg(&pdev->dev, "device tree enabled\n");
+		pdata = msm_hs_dt_to_pdata(pdev);
+		if (IS_ERR(pdata))
+			return PTR_ERR(pdata);
+
+		if (pdev->id == -1) {
+			pdev->id = atomic_inc_return(&msm_serial_hs_next_id)-1;
+			deviceid[pdev->id] = 1;
+		}
+
+		/* Use alias from device tree if present
+		 * Alias is used as an optional property
+		 */
+		alias_num = of_alias_get_id(pdev->dev.of_node, "uart");
+		if (alias_num >= 0) {
+			/* If alias_num is between 0 and 11, check that it not
+			 * equal to previous incremented pdev-ids. If it is
+			 * equal to previous pdev.ids , fail deviceprobe.
+			 */
+			if (alias_num < BLSP_UART_NR) {
+				if (deviceid[alias_num] == 0) {
+					pdev->id = alias_num;
+				} else {
+					pr_err("alias_num=%d already used\n",
+								alias_num);
+					return -EINVAL;
+				}
+			} else {
+				pdev->id = alias_num;
+			}
+		}
+
+		pdev->dev.platform_data = pdata;
+	}
+
 	if (pdev->id < 0 || pdev->id >= UARTDM_NR) {
-		printk(KERN_ERR "Invalid plaform device ID = %d\n", pdev->id);
+		pr_err("Invalid plaform device ID = %d\n", pdev->id);
 		return -EINVAL;
 	}
 
 	msm_uport = &q_uart_port[pdev->id];
 	uport = &msm_uport->uport;
-
 	uport->dev = &pdev->dev;
 
-	resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (unlikely(!resource))
-		return -ENXIO;
-	uport->mapbase = resource->start;  /* virtual address */
+	if (pdev->dev.of_node)
+		msm_uport->uart_type = BLSP_HSUART;
 
-	uport->membase = ioremap(uport->mapbase, PAGE_SIZE);
-	if (unlikely(!uport->membase))
-		return -ENOMEM;
+	/* Get required resources for BAM HSUART */
+	if (is_blsp_uart(msm_uport)) {
+		core_resource = platform_get_resource_byname(pdev,
+					IORESOURCE_MEM, "core_mem");
+		bam_resource = platform_get_resource_byname(pdev,
+					IORESOURCE_MEM, "bam_mem");
+		core_irqres = platform_get_irq_byname(pdev, "core_irq");
+		bam_irqres = platform_get_irq_byname(pdev, "bam_irq");
 
-	uport->irq = platform_get_irq(pdev, 0);
-	if (unlikely((int)uport->irq < 0))
-		return -ENXIO;
+		if (!core_resource) {
+			pr_err("Invalid core HSUART Resources.\n");
+			return -ENXIO;
+		}
+
+		if (!bam_resource) {
+			pr_err("Invalid BAM HSUART Resources.\n");
+			return -ENXIO;
+		}
+
+		if (!core_irqres) {
+			pr_err("Invalid core irqres Resources.\n");
+			return -ENXIO;
+		}
+		if (!bam_irqres) {
+			pr_err("Invalid bam irqres Resources.\n");
+			return -ENXIO;
+		}
+
+		uport->mapbase = core_resource->start;
+
+		uport->membase = ioremap(uport->mapbase,
+					resource_size(core_resource));
+		if (unlikely(!uport->membase)) {
+			pr_err("UART Resource ioremap Failed.\n");
+			return -ENOMEM;
+		}
+		msm_uport->bam_mem = bam_resource->start;
+		msm_uport->bam_base = ioremap(msm_uport->bam_mem,
+					resource_size(bam_resource));
+		if (unlikely(!msm_uport->bam_base)) {
+			pr_err("UART BAM Resource ioremap Failed.\n");
+			iounmap(uport->membase);
+			return -ENOMEM;
+		}
+
+		uport->irq = core_irqres;
+		msm_uport->bam_irq = bam_irqres;
+
+		msm_uport->bus_scale_table = msm_bus_cl_get_pdata(pdev);
+		if (!msm_uport->bus_scale_table) {
+			pr_err("BLSP UART: Bus scaling is disabled.\n");
+		} else {
+			msm_uport->bus_perf_client =
+				msm_bus_scale_register_client
+					(msm_uport->bus_scale_table);
+			if (IS_ERR(&msm_uport->bus_perf_client)) {
+				pr_err("%s(): Bus client register failed.\n",
+								__func__);
+				ret = -EINVAL;
+				goto unmap_memory;
+			}
+		}
+	} else {
+
+		resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+		if (unlikely(!resource))
+			return -ENXIO;
+		uport->mapbase = resource->start;
+		uport->membase = ioremap(uport->mapbase,
+					resource_size(resource));
+		if (unlikely(!uport->membase))
+			return -ENOMEM;
+
+		uport->irq = platform_get_irq(pdev, 0);
+		if (unlikely((int)uport->irq < 0)) {
+			pr_err("UART IRQ Failed.\n");
+			iounmap(uport->membase);
+			return -ENXIO;
+		}
+	}
 
 	if (pdata == NULL)
 		msm_uport->wakeup.irq = -1;
@@ -1943,24 +2859,41 @@
 		msm_uport->wakeup.inject_rx = pdata->inject_rx_on_wakeup;
 		msm_uport->wakeup.rx_to_inject = pdata->rx_to_inject;
 
-		if (unlikely(msm_uport->wakeup.irq < 0))
-			return -ENXIO;
+		if (unlikely(msm_uport->wakeup.irq < 0)) {
+			ret = -ENXIO;
+			goto deregister_bus_client;
+		}
 
+		if (is_blsp_uart(msm_uport)) {
+			msm_uport->bam_tx_ep_pipe_index =
+					pdata->bam_tx_ep_pipe_index;
+			msm_uport->bam_rx_ep_pipe_index =
+					pdata->bam_rx_ep_pipe_index;
+		}
 	}
 
-	resource = platform_get_resource_byname(pdev, IORESOURCE_DMA,
-						"uartdm_channels");
-	if (unlikely(!resource))
-		return -ENXIO;
-	msm_uport->dma_tx_channel = resource->start;
-	msm_uport->dma_rx_channel = resource->end;
+	if (!is_blsp_uart(msm_uport)) {
 
-	resource = platform_get_resource_byname(pdev, IORESOURCE_DMA,
-						"uartdm_crci");
-	if (unlikely(!resource))
-		return -ENXIO;
-	msm_uport->dma_tx_crci = resource->start;
-	msm_uport->dma_rx_crci = resource->end;
+		resource = platform_get_resource_byname(pdev,
+					IORESOURCE_DMA, "uartdm_channels");
+		if (unlikely(!resource)) {
+			ret =  -ENXIO;
+			goto deregister_bus_client;
+		}
+
+		msm_uport->dma_tx_channel = resource->start;
+		msm_uport->dma_rx_channel = resource->end;
+
+		resource = platform_get_resource_byname(pdev,
+					IORESOURCE_DMA, "uartdm_crci");
+		if (unlikely(!resource)) {
+			ret = -ENXIO;
+			goto deregister_bus_client;
+		}
+
+		msm_uport->dma_tx_crci = resource->start;
+		msm_uport->dma_rx_crci = resource->end;
+	}
 
 	uport->iotype = UPIO_MEM;
 	uport->fifosize = 64;
@@ -1970,8 +2903,10 @@
 	msm_uport->imr_reg = 0x0;
 
 	msm_uport->clk = clk_get(&pdev->dev, "core_clk");
-	if (IS_ERR(msm_uport->clk))
-		return PTR_ERR(msm_uport->clk);
+	if (IS_ERR(msm_uport->clk)) {
+		ret = PTR_ERR(msm_uport->clk);
+		goto deregister_bus_client;
+	}
 
 	msm_uport->pclk = clk_get(&pdev->dev, "iface_clk");
 	/*
@@ -1984,7 +2919,7 @@
 	ret = clk_set_rate(msm_uport->clk, uport->uartclk);
 	if (ret) {
 		printk(KERN_WARNING "Error setting clock rate on UART\n");
-		return ret;
+		goto put_clk;
 	}
 
 	msm_uport->hsuart_wq = alloc_workqueue("k_hsuart",
@@ -1992,30 +2927,43 @@
 	if (!msm_uport->hsuart_wq) {
 		pr_err("%s(): Unable to create workqueue hsuart_wq\n",
 								__func__);
-		return -ENOMEM;
+		ret =  -ENOMEM;
+		goto put_clk;
 	}
 
 	INIT_WORK(&msm_uport->clock_off_w, hsuart_clock_off_work);
+
+	/* Init work for Reset Rx bam endpoints */
+	INIT_WORK(&msm_uport->reset_bam_rx, hsuart_reset_bam_rx_work);
+
+	/* Init work for sps_disconnect in stop_rx_locked */
+	INIT_WORK(&msm_uport->disconnect_rx_endpoint,
+				hsuart_disconnect_rx_endpoint_work);
 	mutex_init(&msm_uport->clk_mutex);
 
+	/* Initialize SPS HW connected with UART core */
+	if (is_blsp_uart(msm_uport)) {
+		ret = msm_hs_sps_init(msm_uport);
+		if (unlikely(ret)) {
+			pr_err("SPS Initialization failed ! err=%d", ret);
+			goto destroy_mutex;
+		}
+	}
+
+	msm_hs_bus_voting(msm_uport, BUS_SCALING);
+
 	clk_prepare_enable(msm_uport->clk);
 	if (msm_uport->pclk)
 		clk_prepare_enable(msm_uport->pclk);
 
 	ret = uartdm_init_port(uport);
 	if (unlikely(ret)) {
-		clk_disable_unprepare(msm_uport->clk);
-		if (msm_uport->pclk)
-			clk_disable_unprepare(msm_uport->pclk);
-		return ret;
+		goto err_clock;
 	}
 
 	/* configure the CR Protection to Enable */
 	msm_hs_write(uport, UARTDM_CR_ADDR, CR_PROTECTION_EN);
 
-	clk_disable_unprepare(msm_uport->clk);
-	if (msm_uport->pclk)
-		clk_disable_unprepare(msm_uport->pclk);
 
 	/*
 	 * Enable Command register protection before going ahead as this hw
@@ -2032,14 +2980,49 @@
 
 	ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_clock.attr);
 	if (unlikely(ret))
-		return ret;
+		goto err_clock;
 
 	msm_serial_debugfs_init(msm_uport, pdev->id);
 
 	uport->line = pdev->id;
 	if (pdata != NULL && pdata->userid && pdata->userid <= UARTDM_NR)
 		uport->line = pdata->userid;
-	return uart_add_one_port(&msm_hs_driver, uport);
+	ret = uart_add_one_port(&msm_hs_driver, uport);
+	if (!ret) {
+		msm_hs_bus_voting(msm_uport, BUS_RESET);
+		clk_disable_unprepare(msm_uport->clk);
+		if (msm_uport->pclk)
+			clk_disable_unprepare(msm_uport->pclk);
+		return ret;
+	}
+
+err_clock:
+
+	msm_hs_bus_voting(msm_uport, BUS_RESET);
+	clk_disable_unprepare(msm_uport->clk);
+	if (msm_uport->pclk)
+		clk_disable_unprepare(msm_uport->pclk);
+
+destroy_mutex:
+	mutex_destroy(&msm_uport->clk_mutex);
+	destroy_workqueue(msm_uport->hsuart_wq);
+
+put_clk:
+	if (msm_uport->pclk)
+		clk_put(msm_uport->pclk);
+
+	if (msm_uport->clk)
+		clk_put(msm_uport->clk);
+
+deregister_bus_client:
+	if (is_blsp_uart(msm_uport))
+		msm_bus_scale_unregister_client(msm_uport->bus_perf_client);
+unmap_memory:
+	iounmap(uport->membase);
+	if (is_blsp_uart(msm_uport))
+		iounmap(msm_uport->bam_base);
+
+	return ret;
 }
 
 static int __init msm_serial_hs_init(void)
@@ -2086,27 +3069,35 @@
 	struct platform_device *pdev = to_platform_device(uport->dev);
 	const struct msm_serial_hs_platform_data *pdata =
 				pdev->dev.platform_data;
+	struct msm_hs_tx *tx = &msm_uport->tx;
+	struct sps_pipe *sps_pipe_handle = tx->cons.pipe_handle;
 
 	if (msm_uport->tx.dma_in_flight) {
-		spin_lock_irqsave(&uport->lock, flags);
-		/* disable UART TX interface to DM */
-		data = msm_hs_read(uport, UARTDM_DMEN_ADDR);
-		data &= ~UARTDM_TX_DM_EN_BMSK;
-		msm_hs_write(uport, UARTDM_DMEN_ADDR, data);
-		/* turn OFF UART Transmitter */
-		msm_hs_write(uport, UARTDM_CR_ADDR, UARTDM_CR_TX_DISABLE_BMSK);
-		/* reset UART TX */
-		msm_hs_write(uport, UARTDM_CR_ADDR, RESET_TX);
-		/* reset UART TX Error */
-		msm_hs_write(uport, UARTDM_CR_ADDR, RESET_TX_ERROR);
-		msm_uport->tx.flush = FLUSH_STOP;
-		spin_unlock_irqrestore(&uport->lock, flags);
-		/* discard flush */
-		msm_dmov_flush(msm_uport->dma_tx_channel, 0);
-		ret = wait_event_timeout(msm_uport->tx.wait,
-			msm_uport->tx.flush == FLUSH_SHUTDOWN, 100);
-		if (!ret)
-			pr_err("%s():HSUART TX Stalls.\n", __func__);
+		if (!is_blsp_uart(msm_uport)) {
+			spin_lock_irqsave(&uport->lock, flags);
+			/* disable UART TX interface to DM */
+			data = msm_hs_read(uport, UARTDM_DMEN_ADDR);
+			data &= ~UARTDM_TX_DM_EN_BMSK;
+			msm_hs_write(uport, UARTDM_DMEN_ADDR, data);
+			/* turn OFF UART Transmitter */
+			msm_hs_write(uport, UARTDM_CR_ADDR,
+					UARTDM_CR_TX_DISABLE_BMSK);
+			/* reset UART TX */
+			msm_hs_write(uport, UARTDM_CR_ADDR, RESET_TX);
+			/* reset UART TX Error */
+			msm_hs_write(uport, UARTDM_CR_ADDR, RESET_TX_ERROR);
+			msm_uport->tx.flush = FLUSH_STOP;
+			spin_unlock_irqrestore(&uport->lock, flags);
+			/* discard flush */
+			msm_dmov_flush(msm_uport->dma_tx_channel, 0);
+			ret = wait_event_timeout(msm_uport->tx.wait,
+				msm_uport->tx.flush == FLUSH_SHUTDOWN, 100);
+			if (!ret)
+				pr_err("%s():HSUART TX Stalls.\n", __func__);
+		} else {
+			/* BAM Disconnect for TX */
+			sps_disconnect(sps_pipe_handle);
+		}
 	}
 	tasklet_kill(&msm_uport->tx.tlet);
 	BUG_ON(msm_uport->rx.flush < FLUSH_STOP);
@@ -2129,6 +3120,10 @@
 	 * Hence mb() requires here.
 	 */
 	mb();
+
+	/* Reset PNOC Bus Scaling */
+	msm_hs_bus_voting(msm_uport, BUS_RESET);
+
 	if (msm_uport->clk_state != MSM_HS_CLK_OFF) {
 		/* to balance clk_state */
 		clk_disable_unprepare(msm_uport->clk);
@@ -2149,9 +3144,13 @@
 	if (use_low_power_wakeup(msm_uport))
 		free_irq(msm_uport->wakeup.irq, msm_uport);
 
-	if (pdata && pdata->gpio_config)
-		if (pdata->gpio_config(0))
-			dev_err(uport->dev, "GPIO config error\n");
+	if (is_blsp_uart(msm_uport)) {
+		msm_hs_unconfig_uart_gpios(uport);
+	} else {
+		if (pdata && pdata->gpio_config)
+			if (pdata->gpio_config(0))
+				dev_err(uport->dev, "GPIO config error\n");
+	}
 }
 
 static void __exit msm_serial_hs_exit(void)
@@ -2195,12 +3194,18 @@
 	.runtime_idle    = msm_hs_runtime_idle,
 };
 
+static struct of_device_id msm_hs_match_table[] = {
+	{ .compatible = "qcom,msm-hsuart-v14" },
+	{}
+};
+
 static struct platform_driver msm_serial_hs_platform_driver = {
 	.probe	= msm_hs_probe,
 	.remove = __devexit_p(msm_hs_remove),
 	.driver = {
 		.name = "msm_serial_hs",
 		.pm   = &msm_hs_dev_pm_ops,
+		.of_match_table = msm_hs_match_table,
 	},
 };
 
diff --git a/drivers/tty/serial/msm_serial_hs_hwreg.h b/drivers/tty/serial/msm_serial_hs_hwreg.h
index 8debc36..9fa4f55 100644
--- a/drivers/tty/serial/msm_serial_hs_hwreg.h
+++ b/drivers/tty/serial/msm_serial_hs_hwreg.h
@@ -1,6 +1,6 @@
 /* drivers/serial/msm_serial_hs_hwreg.h
  *
- * Copyright (c) 2007-2009, 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2009, 2012-2013,The Linux Foundation. All rights reserved.
  * 
  * All source code in this file is licensed under the following license
  * except where indicated.
@@ -59,8 +59,16 @@
 #define UARTDM_MR1_ADDR 0x0
 #define UARTDM_MR2_ADDR 0x4
 
+/* Backward Compatability Register for UARTDM Core v1.4 */
+#define UARTDM_BCR_ADDR	0xc8
+
+/*
+ * UARTDM Core v1.4 STALE_IRQ_EMPTY bit defination
+ * Stale interrupt will fire if bit is set when RX-FIFO is empty
+ */
+#define UARTDM_BCR_STALE_IRQ_EMPTY	0x2
+
 /* write only register */
-#define UARTDM_CSR_ADDR    0x8
 #define UARTDM_CSR_115200 0xFF
 #define UARTDM_CSR_57600  0xEE
 #define UARTDM_CSR_38400  0xDD
@@ -79,22 +87,11 @@
 #define UARTDM_CSR_75     0x00
 
 /* write only register */
-#define UARTDM_TF_ADDR 0x70
-#define UARTDM_TF2_ADDR 0x74
-#define UARTDM_TF3_ADDR 0x78
-#define UARTDM_TF4_ADDR 0x7C
-
-/* write only register */
-#define UARTDM_CR_ADDR 0x10
-/* write only register */
-#define UARTDM_IMR_ADDR 0x14
-
 #define UARTDM_IPR_ADDR 0x18
 #define UARTDM_TFWR_ADDR 0x1c
 #define UARTDM_RFWR_ADDR 0x20
 #define UARTDM_HCR_ADDR 0x24
 #define UARTDM_DMRX_ADDR 0x34
-#define UARTDM_IRDA_ADDR 0x38
 #define UARTDM_DMEN_ADDR 0x3c
 
 /* UART_DM_NO_CHARS_FOR_TX */
@@ -105,21 +102,6 @@
 #define UARTDM_SIM_CFG_ADDR 0x80
 
 /* Read Only register */
-#define UARTDM_SR_ADDR 0x8
-
-/* Read Only register */
-#define UARTDM_RF_ADDR  0x70
-#define UARTDM_RF2_ADDR 0x74
-#define UARTDM_RF3_ADDR 0x78
-#define UARTDM_RF4_ADDR 0x7C
-
-/* Read Only register */
-#define UARTDM_MISR_ADDR 0x10
-
-/* Read Only register */
-#define UARTDM_ISR_ADDR 0x14
-#define UARTDM_RX_TOTAL_SNAP_ADDR 0x38
-
 #define UARTDM_TXFS_ADDR 0x4C
 #define UARTDM_RXFS_ADDR 0x50
 
@@ -155,11 +137,25 @@
 #define RESET_TX_ERROR		0x800
 #define RESET_TX_DONE		0x810
 
+/*
+ * UARTDM_CR BAM IFC comman bit value
+ * for UARTDM Core v1.4
+ */
+#define START_RX_BAM_IFC	0x850
+#define START_TX_BAM_IFC	0x860
+
 #define UARTDM_MR1_AUTO_RFR_LEVEL1_BMSK 0xffffff00
 #define UARTDM_MR1_AUTO_RFR_LEVEL0_BMSK 0x3f
 #define UARTDM_MR1_CTS_CTL_BMSK 0x40
 #define UARTDM_MR1_RX_RDY_CTL_BMSK 0x80
 
+/*
+ * UARTDM Core v1.4 MR2_RFR_CTS_LOOP bitmask
+ * Enables internal loopback between RFR_N of
+ * RX channel and CTS_N of TX channel.
+ */
+#define UARTDM_MR2_RFR_CTS_LOOP_MODE_BMSK	0x400
+
 #define UARTDM_MR2_LOOP_MODE_BMSK		0x80
 #define UARTDM_MR2_ERROR_MODE_BMSK		0x40
 #define UARTDM_MR2_BITS_PER_CHAR_BMSK		0x30
@@ -204,4 +200,110 @@
 #define UARTDM_TX_DM_EN_BMSK 0x1
 #define UARTDM_RX_DM_EN_BMSK 0x2
 
+/*
+ * UARTDM Core v1.4 bitmask
+ * Bitmasks for enabling Rx and Tx BAM Interface
+ */
+#define UARTDM_TX_BAM_ENABLE_BMSK 0x4
+#define UARTDM_RX_BAM_ENABLE_BMSK 0x8
+
+/*
+ * Some of the BLSP Based UART Core(v14) existing register offsets
+ * are different compare to GSBI based UART Core(v13)
+ * Hence add the changed register offsets for UART Core v14
+ */
+#ifdef CONFIG_MSM_UARTDM_Core_v14
+
+/* write only register */
+#define UARTDM_CSR_ADDR    0xa0
+
+/* write only register */
+#define UARTDM_TF_ADDR   0x100
+#define UARTDM_TF2_ADDR  0x104
+#define UARTDM_TF3_ADDR  0x108
+#define UARTDM_TF4_ADDR  0x10c
+#define UARTDM_TF5_ADDR  0x110
+#define UARTDM_TF6_ADDR  0x114
+#define UARTDM_TF7_ADDR  0x118
+#define UARTDM_TF8_ADDR  0x11c
+#define UARTDM_TF9_ADDR  0x120
+#define UARTDM_TF10_ADDR 0x124
+#define UARTDM_TF11_ADDR 0x128
+#define UARTDM_TF12_ADDR 0x12c
+#define UARTDM_TF13_ADDR 0x130
+#define UARTDM_TF14_ADDR 0x134
+#define UARTDM_TF15_ADDR 0x138
+#define UARTDM_TF16_ADDR 0x13c
+
+/* write only register */
+#define UARTDM_CR_ADDR 0xa8
+/* write only register */
+#define UARTDM_IMR_ADDR 0xb0
+#define UARTDM_IRDA_ADDR 0xb8
+
+/* Read Only register */
+#define UARTDM_SR_ADDR 0xa4
+
+/* Read Only register */
+#define UARTDM_RF_ADDR   0x140
+#define UARTDM_RF2_ADDR  0x144
+#define UARTDM_RF3_ADDR  0x148
+#define UARTDM_RF4_ADDR  0x14c
+#define UARTDM_RF5_ADDR  0x150
+#define UARTDM_RF6_ADDR  0x154
+#define UARTDM_RF7_ADDR  0x158
+#define UARTDM_RF8_ADDR  0x15c
+#define UARTDM_RF9_ADDR  0x160
+#define UARTDM_RF10_ADDR 0x164
+#define UARTDM_RF11_ADDR 0x168
+#define UARTDM_RF12_ADDR 0x16c
+#define UARTDM_RF13_ADDR 0x170
+#define UARTDM_RF14_ADDR 0x174
+#define UARTDM_RF15_ADDR 0x178
+#define UARTDM_RF16_ADDR 0x17c
+
+/* Read Only register */
+#define UARTDM_MISR_ADDR 0xac
+
+/* Read Only register */
+#define UARTDM_ISR_ADDR 0xb4
+#define UARTDM_RX_TOTAL_SNAP_ADDR 0xbc
+
+#else
+
+/* Register offsets for UART Core v13 */
+
+/* write only register */
+#define UARTDM_CSR_ADDR    0x8
+
+/* write only register */
+#define UARTDM_TF_ADDR   0x70
+#define UARTDM_TF2_ADDR  0x74
+#define UARTDM_TF3_ADDR  0x78
+#define UARTDM_TF4_ADDR  0x7c
+
+/* write only register */
+#define UARTDM_CR_ADDR 0x10
+/* write only register */
+#define UARTDM_IMR_ADDR 0x14
+#define UARTDM_IRDA_ADDR 0x38
+
+/* Read Only register */
+#define UARTDM_SR_ADDR 0x8
+
+/* Read Only register */
+#define UARTDM_RF_ADDR   0x70
+#define UARTDM_RF2_ADDR  0x74
+#define UARTDM_RF3_ADDR  0x78
+#define UARTDM_RF4_ADDR  0x7c
+
+/* Read Only register */
+#define UARTDM_MISR_ADDR 0x10
+
+/* Read Only register */
+#define UARTDM_ISR_ADDR 0x14
+#define UARTDM_RX_TOTAL_SNAP_ADDR 0x38
+
+#endif
+
 #endif /* MSM_SERIAL_HS_HWREG_H */
diff --git a/drivers/tty/serial/msm_serial_hs_lite.c b/drivers/tty/serial/msm_serial_hs_lite.c
index 72a12d1..8069b35 100644
--- a/drivers/tty/serial/msm_serial_hs_lite.c
+++ b/drivers/tty/serial/msm_serial_hs_lite.c
@@ -2,7 +2,7 @@
  * drivers/serial/msm_serial.c - driver for msm7k serial device and console
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -45,11 +45,34 @@
 #include <linux/debugfs.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/wakelock.h>
 #include <mach/board.h>
 #include <mach/msm_serial_hs_lite.h>
+#include <mach/msm_bus.h>
 #include <asm/mach-types.h>
 #include "msm_serial_hs_hwreg.h"
 
+/*
+ * There are 3 different kind of UART Core available on MSM.
+ * High Speed UART (i.e. Legacy HSUART), GSBI based HSUART
+ * and BSLP based HSUART.
+ */
+enum uart_core_type {
+	LEGACY_HSUART,
+	GSBI_HSUART,
+	BLSP_HSUART,
+};
+
+/*
+ * UART can be used in 2-wire or 4-wire mode.
+ * Use uart_func_mode to set 2-wire or 4-wire mode.
+ */
+enum uart_func_mode {
+	UART_TWO_WIRE, /* can't support HW Flow control. */
+	UART_FOUR_WIRE,/* can support HW Flow control. */
+};
+
 struct msm_hsl_port {
 	struct uart_port	uart;
 	char			name[16];
@@ -60,11 +83,17 @@
 	unsigned int		*uart_csr_code;
 	unsigned int            *gsbi_mapbase;
 	unsigned int            *mapped_gsbi;
-	int			is_uartdm;
 	unsigned int            old_snap_state;
 	unsigned int		ver_id;
 	int			tx_timeout;
 	struct mutex		clk_mutex;
+	enum uart_core_type	uart_type;
+	enum uart_func_mode	func_mode;
+	struct wake_lock	port_open_wake_lock;
+	int			clk_enable_count;
+	u32			bus_perf_client;
+	/* BLSP UART required BUS Scaling data */
+	struct msm_bus_scale_pdata *bus_scale_table;
 };
 
 #define UARTDM_VERSION_11_13	0
@@ -147,13 +176,191 @@
 
 static unsigned int msm_serial_hsl_has_gsbi(struct uart_port *port)
 {
-	return UART_TO_MSM(port)->is_uartdm;
+	return (UART_TO_MSM(port)->uart_type == GSBI_HSUART);
 }
 
+/**
+ * set_gsbi_uart_func_mode: Check the currently used GSBI UART mode
+ * and set the new required GSBI UART Mode if it is different.
+ * @port: uart port
+ */
+static void set_gsbi_uart_func_mode(struct uart_port *port)
+{
+	struct msm_hsl_port *msm_hsl_port = UART_TO_MSM(port);
+	unsigned int set_gsbi_uart_mode = GSBI_PROTOCOL_I2C_UART;
+	unsigned int cur_gsbi_uart_mode;
+
+	if (msm_hsl_port->func_mode == UART_FOUR_WIRE)
+		set_gsbi_uart_mode = GSBI_PROTOCOL_UART;
+
+	if (msm_hsl_port->pclk)
+		clk_prepare_enable(msm_hsl_port->pclk);
+
+	/* Read current used GSBI UART Mode and set only if it is different. */
+	cur_gsbi_uart_mode = ioread32(msm_hsl_port->mapped_gsbi +
+					GSBI_CONTROL_ADDR);
+	if ((cur_gsbi_uart_mode & set_gsbi_uart_mode) != set_gsbi_uart_mode)
+		/*
+		 * Programmed GSBI based UART protocol mode i.e. I2C/UART
+		 * Shared Mode or UART Mode.
+		 */
+		iowrite32(set_gsbi_uart_mode,
+			msm_hsl_port->mapped_gsbi + GSBI_CONTROL_ADDR);
+
+	if (msm_hsl_port->pclk)
+		clk_disable_unprepare(msm_hsl_port->pclk);
+}
+
+/**
+ * msm_hsl_config_uart_tx_rx_gpios - Configures UART Tx and RX GPIOs
+ * @port: uart port
+ */
+static int msm_hsl_config_uart_tx_rx_gpios(struct uart_port *port)
+{
+	struct platform_device *pdev = to_platform_device(port->dev);
+	const struct msm_serial_hslite_platform_data *pdata =
+					pdev->dev.platform_data;
+	int ret;
+
+	if (pdata) {
+		ret = gpio_request(pdata->uart_tx_gpio,
+				"UART_TX_GPIO");
+		if (unlikely(ret)) {
+			pr_err("gpio request failed for:%d\n",
+					pdata->uart_tx_gpio);
+			goto exit_uart_config;
+		}
+
+		ret = gpio_request(pdata->uart_rx_gpio, "UART_RX_GPIO");
+		if (unlikely(ret)) {
+			pr_err("gpio request failed for:%d\n",
+					pdata->uart_rx_gpio);
+			gpio_free(pdata->uart_tx_gpio);
+			goto exit_uart_config;
+		}
+	} else {
+		pr_err("Pdata is NULL.\n");
+		ret = -EINVAL;
+	}
+
+exit_uart_config:
+	return ret;
+}
+
+/**
+ * msm_hsl_unconfig_uart_tx_rx_gpios: Unconfigures UART Tx and RX GPIOs
+ * @port: uart port
+ */
+static void msm_hsl_unconfig_uart_tx_rx_gpios(struct uart_port *port)
+{
+	struct platform_device *pdev = to_platform_device(port->dev);
+	const struct msm_serial_hslite_platform_data *pdata =
+					pdev->dev.platform_data;
+
+	if (pdata) {
+		gpio_free(pdata->uart_tx_gpio);
+		gpio_free(pdata->uart_rx_gpio);
+	} else {
+		pr_err("Error:Pdata is NULL.\n");
+	}
+}
+
+/**
+ * msm_hsl_config_uart_hwflow_gpios: Configures UART HWFlow GPIOs
+ * @port: uart port
+ */
+static int msm_hsl_config_uart_hwflow_gpios(struct uart_port *port)
+{
+	struct platform_device *pdev = to_platform_device(port->dev);
+	const struct msm_serial_hslite_platform_data *pdata =
+				pdev->dev.platform_data;
+	int ret = -EINVAL;
+
+	if (pdata) {
+		ret = gpio_request(pdata->uart_cts_gpio,
+					"UART_CTS_GPIO");
+		if (unlikely(ret)) {
+			pr_err("gpio request failed for:%d\n",
+					pdata->uart_cts_gpio);
+			goto exit_config_uart;
+		}
+
+		ret = gpio_request(pdata->uart_rfr_gpio,
+					"UART_RFR_GPIO");
+		if (unlikely(ret)) {
+			pr_err("gpio request failed for:%d\n",
+				pdata->uart_rfr_gpio);
+			gpio_free(pdata->uart_cts_gpio);
+			goto exit_config_uart;
+		}
+	} else {
+		pr_err("Error: Pdata is NULL.\n");
+	}
+
+exit_config_uart:
+	return ret;
+}
+
+/**
+ * msm_hsl_unconfig_uart_hwflow_gpios: Unonfigures UART HWFlow GPIOs
+ * @port: uart port
+ */
+static void msm_hsl_unconfig_uart_hwflow_gpios(struct uart_port *port)
+{
+	struct platform_device *pdev = to_platform_device(port->dev);
+	const struct msm_serial_hslite_platform_data *pdata =
+					pdev->dev.platform_data;
+
+	if (pdata) {
+		gpio_free(pdata->uart_cts_gpio);
+		gpio_free(pdata->uart_rfr_gpio);
+	} else {
+		pr_err("Error: Pdata is NULL.\n");
+	}
+
+}
+
+/**
+ * msm_hsl_config_uart_gpios: Configures UART GPIOs and returns success or
+ * Failure
+ * @port: uart port
+ */
+static int msm_hsl_config_uart_gpios(struct uart_port *port)
+{
+	struct msm_hsl_port *msm_hsl_port = UART_TO_MSM(port);
+	int ret;
+
+	/* Configure UART Tx and Rx GPIOs */
+	ret = msm_hsl_config_uart_tx_rx_gpios(port);
+	if (!ret) {
+		if (msm_hsl_port->func_mode == UART_FOUR_WIRE) {
+			/*if 4-wire uart, configure CTS and RFR GPIOs */
+			ret = msm_hsl_config_uart_hwflow_gpios(port);
+			if (ret)
+				msm_hsl_unconfig_uart_tx_rx_gpios(port);
+		}
+	} else {
+		msm_hsl_unconfig_uart_tx_rx_gpios(port);
+	}
+
+	return ret;
+}
+
+/**
+ * msm_hsl_unconfig_uart_gpios: Unconfigures UART GPIOs
+ * @port: uart port
+ */
+static void msm_hsl_unconfig_uart_gpios(struct uart_port *port)
+{
+	struct msm_hsl_port *msm_hsl_port = UART_TO_MSM(port);
+
+	msm_hsl_unconfig_uart_tx_rx_gpios(port);
+	if (msm_hsl_port->func_mode == UART_FOUR_WIRE)
+		msm_hsl_unconfig_uart_hwflow_gpios(port);
+}
 static int get_line(struct platform_device *pdev)
 {
 	struct msm_hsl_port *msm_hsl_port = platform_get_drvdata(pdev);
-
 	return msm_hsl_port->uart.line;
 }
 
@@ -164,23 +371,40 @@
 
 	if (enable) {
 
+		msm_hsl_port->clk_enable_count++;
 		ret = clk_prepare_enable(msm_hsl_port->clk);
 		if (ret)
 			goto err;
 		if (msm_hsl_port->pclk) {
 			ret = clk_prepare_enable(msm_hsl_port->pclk);
-			if (ret) {
-				clk_disable_unprepare(msm_hsl_port->clk);
-				goto err;
-			}
+			if (ret)
+				goto err_clk_disable;
 		}
 	} else {
 
+		msm_hsl_port->clk_enable_count--;
 		clk_disable_unprepare(msm_hsl_port->clk);
 		if (msm_hsl_port->pclk)
 			clk_disable_unprepare(msm_hsl_port->pclk);
 	}
+
+	if (msm_hsl_port->bus_perf_client) {
+			pr_debug("Voting for bus scaling:%d\n",
+					!!msm_hsl_port->clk_enable_count);
+			ret = msm_bus_scale_client_update_request(
+				msm_hsl_port->bus_perf_client,
+				!!msm_hsl_port->clk_enable_count);
+			if (ret)
+				pr_err("Failed to request bus bw vector %d\n",
+					!!msm_hsl_port->clk_enable_count);
+	}
+
+	return ret;
+
+err_clk_disable:
+	clk_disable_unprepare(msm_hsl_port->clk);
 err:
+	msm_hsl_port->clk_enable_count--;
 	return ret;
 }
 static int msm_hsl_loopback_enable_set(void *data, u64 val)
@@ -745,28 +969,16 @@
 		(port->cons && (!(port->cons->flags & CON_ENABLED)))) {
 
 		if (msm_serial_hsl_has_gsbi(port))
-			if ((ioread32(msm_hsl_port->mapped_gsbi +
-				GSBI_CONTROL_ADDR) & GSBI_PROTOCOL_I2C_UART)
-					!= GSBI_PROTOCOL_I2C_UART)
-				iowrite32(GSBI_PROTOCOL_I2C_UART,
-					msm_hsl_port->mapped_gsbi +
-						GSBI_CONTROL_ADDR);
+			set_gsbi_uart_func_mode(port);
+
+		if (pdata && pdata->use_pm)
+			wake_lock(&msm_hsl_port->port_open_wake_lock);
 
 		if (pdata && pdata->config_gpio) {
-			ret = gpio_request(pdata->uart_tx_gpio,
-						"UART_TX_GPIO");
-			if (unlikely(ret)) {
-				pr_err("gpio request failed for:%d\n",
-							pdata->uart_tx_gpio);
-				return ret;
-			}
-
-			ret = gpio_request(pdata->uart_rx_gpio, "UART_RX_GPIO");
-			if (unlikely(ret)) {
-				pr_err("gpio request failed for:%d\n",
-							pdata->uart_rx_gpio);
-				gpio_free(pdata->uart_tx_gpio);
-				return ret;
+			ret = msm_hsl_config_uart_gpios(port);
+			if (ret) {
+				msm_hsl_unconfig_uart_gpios(port);
+				goto release_wakelock;
 			}
 		}
 	}
@@ -800,9 +1012,17 @@
 			  msm_hsl_port->name, port);
 	if (unlikely(ret)) {
 		pr_err("failed to request_irq\n");
-		return ret;
+		msm_hsl_unconfig_uart_gpios(port);
+		goto release_wakelock;
 	}
-	return 0;
+
+	return ret;
+
+release_wakelock:
+	if (pdata && pdata->use_pm)
+		wake_unlock(&msm_hsl_port->port_open_wake_lock);
+
+	return ret;
 }
 
 static void msm_hsl_shutdown(struct uart_port *port)
@@ -824,10 +1044,12 @@
 	pm_runtime_put_sync(port->dev);
 	if (!(is_console(port)) || (!port->cons) ||
 		(port->cons && (!(port->cons->flags & CON_ENABLED)))) {
-		if (pdata && pdata->config_gpio) {
-			gpio_free(pdata->uart_tx_gpio);
-			gpio_free(pdata->uart_rx_gpio);
-		}
+		/* Free UART GPIOs */
+		if (pdata && pdata->config_gpio)
+			msm_hsl_unconfig_uart_gpios(port);
+
+		if (pdata && pdata->use_pm)
+			wake_unlock(&msm_hsl_port->port_open_wake_lock);
 	}
 }
 
@@ -1009,22 +1231,15 @@
 
 static void msm_hsl_config_port(struct uart_port *port, int flags)
 {
-	struct msm_hsl_port *msm_hsl_port = UART_TO_MSM(port);
 	if (flags & UART_CONFIG_TYPE) {
 		port->type = PORT_MSM;
 		if (msm_hsl_request_port(port))
 			return;
 	}
-	if (msm_serial_hsl_has_gsbi(port)) {
-		if (msm_hsl_port->pclk)
-			clk_prepare_enable(msm_hsl_port->pclk);
-		if ((ioread32(msm_hsl_port->mapped_gsbi + GSBI_CONTROL_ADDR) &
-			GSBI_PROTOCOL_I2C_UART) != GSBI_PROTOCOL_I2C_UART)
-			iowrite32(GSBI_PROTOCOL_I2C_UART,
-				msm_hsl_port->mapped_gsbi + GSBI_CONTROL_ADDR);
-		if (msm_hsl_port->pclk)
-			clk_disable_unprepare(msm_hsl_port->pclk);
-	}
+
+	/* Configure required GSBI based UART protocol. */
+	if (msm_serial_hsl_has_gsbi(port))
+		set_gsbi_uart_func_mode(port);
 }
 
 static int msm_hsl_verify_port(struct uart_port *port,
@@ -1042,6 +1257,9 @@
 {
 	int ret;
 	struct msm_hsl_port *msm_hsl_port = UART_TO_MSM(port);
+	struct platform_device *pdev = to_platform_device(port->dev);
+	const struct msm_serial_hslite_platform_data *pdata =
+					pdev->dev.platform_data;
 
 	switch (state) {
 	case 0:
@@ -1053,9 +1271,11 @@
 		break;
 	case 3:
 		clk_en(port, 0);
-		ret = clk_set_rate(msm_hsl_port->clk, 0);
-		if (ret)
-			pr_err("Error setting UART clock rate to zero.\n");
+		if (pdata && pdata->set_uart_clk_zero) {
+			ret = clk_set_rate(msm_hsl_port->clk, 0);
+			if (ret)
+				pr_err("Error setting UART clock rate to zero.\n");
+		}
 		break;
 	default:
 		pr_err("Unknown PM state %d\n", state);
@@ -1397,6 +1617,56 @@
 	.cons = MSM_HSL_CONSOLE,
 };
 
+static struct msm_serial_hslite_platform_data
+		*msm_hsl_dt_to_pdata(struct platform_device *pdev)
+{
+	int ret;
+	struct device_node *node = pdev->dev.of_node;
+	struct msm_serial_hslite_platform_data *pdata;
+
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		pr_err("unable to allocate memory for platform data\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	ret = of_property_read_u32(node, "qcom,config-gpio",
+				&pdata->config_gpio);
+	if (ret && ret != -EINVAL) {
+		pr_err("Error with config_gpio property.\n");
+		return ERR_PTR(ret);
+	}
+
+	if (pdata->config_gpio) {
+		pdata->uart_tx_gpio = of_get_named_gpio(node,
+					"qcom,tx-gpio", 0);
+		if (pdata->uart_tx_gpio < 0)
+				return ERR_PTR(pdata->uart_tx_gpio);
+
+		pdata->uart_rx_gpio = of_get_named_gpio(node,
+					"qcom,rx-gpio", 0);
+		if (pdata->uart_rx_gpio < 0)
+				return ERR_PTR(pdata->uart_rx_gpio);
+
+		/* check if 4-wire UART, then get cts/rfr GPIOs. */
+		if (pdata->config_gpio == 4) {
+			pdata->uart_cts_gpio = of_get_named_gpio(node,
+						"qcom,cts-gpio", 0);
+			if (pdata->uart_cts_gpio < 0)
+				return ERR_PTR(pdata->uart_cts_gpio);
+
+			pdata->uart_rfr_gpio = of_get_named_gpio(node,
+						"qcom,rfr-gpio", 0);
+			if (pdata->uart_rfr_gpio < 0)
+				return ERR_PTR(pdata->uart_rfr_gpio);
+		}
+	}
+
+	pdata->use_pm = of_property_read_bool(node, "qcom,use-pm");
+
+	return pdata;
+}
+
 static atomic_t msm_serial_hsl_next_id = ATOMIC_INIT(0);
 
 static int __devinit msm_serial_hsl_probe(struct platform_device *pdev)
@@ -1405,7 +1675,7 @@
 	struct resource *uart_resource;
 	struct resource *gsbi_resource;
 	struct uart_port *port;
-	const struct msm_serial_hslite_platform_data *pdata;
+	struct msm_serial_hslite_platform_data *pdata;
 	const struct of_device_id *match;
 	u32 line;
 	int ret;
@@ -1422,9 +1692,16 @@
 
 	/* Use line number from device tree alias if present */
 	if (pdev->dev.of_node) {
+		dev_dbg(&pdev->dev, "device tree enabled\n");
 		ret = of_alias_get_id(pdev->dev.of_node, "serial");
 		if (ret >= 0)
 			line = ret;
+
+		pdata = msm_hsl_dt_to_pdata(pdev);
+		if (IS_ERR(pdata))
+			return PTR_ERR(pdata);
+
+		pdev->dev.platform_data = pdata;
 	}
 
 	if (unlikely(line < 0 || line >= UART_NR))
@@ -1437,11 +1714,37 @@
 	port->uartclk = 7372800;
 	msm_hsl_port = UART_TO_MSM(port);
 
-	match = of_match_device(msm_hsl_match_table, &pdev->dev);
-	if (!match)
-		msm_hsl_port->ver_id = UARTDM_VERSION_11_13;
+	/* Identify UART functional mode as 2-wire or 4-wire. */
+	if (pdata && pdata->config_gpio == 4)
+		msm_hsl_port->func_mode = UART_FOUR_WIRE;
 	else
+		msm_hsl_port->func_mode = UART_TWO_WIRE;
+
+	match = of_match_device(msm_hsl_match_table, &pdev->dev);
+	if (!match) {
+		msm_hsl_port->ver_id = UARTDM_VERSION_11_13;
+	} else {
 		msm_hsl_port->ver_id = (unsigned int)match->data;
+		/*
+		 * BLSP based UART configuration is available with
+		 * UARTDM v14 Revision. Hence set uart_type as UART_BLSP.
+		 */
+		msm_hsl_port->uart_type = BLSP_HSUART;
+
+		msm_hsl_port->bus_scale_table = msm_bus_cl_get_pdata(pdev);
+		if (!msm_hsl_port->bus_scale_table) {
+			pr_err("Bus scaling is disabled\n");
+		} else {
+			msm_hsl_port->bus_perf_client =
+				msm_bus_scale_register_client(
+					msm_hsl_port->bus_scale_table);
+			if (IS_ERR(&msm_hsl_port->bus_perf_client)) {
+				pr_err("Bus client register failed.\n");
+				ret = -EINVAL;
+				goto err;
+			}
+		}
+	}
 
 	gsbi_resource =	platform_get_resource_byname(pdev,
 						     IORESOURCE_MEM,
@@ -1452,9 +1755,9 @@
 	msm_hsl_port->pclk = clk_get(&pdev->dev, "iface_clk");
 
 	if (gsbi_resource)
-		msm_hsl_port->is_uartdm = 1;
+		msm_hsl_port->uart_type = GSBI_HSUART;
 	else
-		msm_hsl_port->is_uartdm = 0;
+		msm_hsl_port->uart_type = LEGACY_HSUART;
 
 	if (unlikely(IS_ERR(msm_hsl_port->clk))) {
 		pr_err("Error getting clk\n");
@@ -1492,6 +1795,10 @@
 #endif
 	msm_hsl_debugfs_init(msm_hsl_port, get_line(pdev));
 	mutex_init(&msm_hsl_port->clk_mutex);
+	if (pdata && pdata->use_pm)
+		wake_lock_init(&msm_hsl_port->port_open_wake_lock,
+				WAKE_LOCK_SUSPEND,
+				"msm_serial_hslite_port_open");
 
 	/* Temporarily increase the refcount on the GSBI clock to avoid a race
 	 * condition with the earlyprintk handover mechanism.
@@ -1501,12 +1808,16 @@
 	ret = uart_add_one_port(&msm_hsl_uart_driver, port);
 	if (msm_hsl_port->pclk)
 		clk_disable_unprepare(msm_hsl_port->pclk);
+
+err:
 	return ret;
 }
 
 static int __devexit msm_serial_hsl_remove(struct platform_device *pdev)
 {
 	struct msm_hsl_port *msm_hsl_port = platform_get_drvdata(pdev);
+	const struct msm_serial_hslite_platform_data *pdata =
+					pdev->dev.platform_data;
 	struct uart_port *port;
 
 	port = get_port_from_line(get_line(pdev));
@@ -1516,6 +1827,9 @@
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
+	if (pdata && pdata->use_pm)
+		wake_lock_destroy(&msm_hsl_port->port_open_wake_lock);
+
 	device_set_wakeup_capable(&pdev->dev, 0);
 	platform_set_drvdata(pdev, NULL);
 	mutex_destroy(&msm_hsl_port->clk_mutex);
diff --git a/drivers/tty/serial/msm_smd_tty.c b/drivers/tty/serial/msm_smd_tty.c
index b25e6ee..a0e8af4 100644
--- a/drivers/tty/serial/msm_smd_tty.c
+++ b/drivers/tty/serial/msm_smd_tty.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/drivers/tty/smux_ctl.c b/drivers/tty/smux_ctl.c
index c17495b..2e091cc 100644
--- a/drivers/tty/smux_ctl.c
+++ b/drivers/tty/smux_ctl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/tty/smux_debug.c b/drivers/tty/smux_debug.c
index 86377d6..d467523 100644
--- a/drivers/tty/smux_debug.c
+++ b/drivers/tty/smux_debug.c
@@ -1,6 +1,6 @@
 /* drivers/tty/smux_debug.c
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/tty/smux_loopback.c b/drivers/tty/smux_loopback.c
index c4374bb..c78b453 100644
--- a/drivers/tty/smux_loopback.c
+++ b/drivers/tty/smux_loopback.c
@@ -1,6 +1,6 @@
 /* drivers/tty/smux_loopback.c
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/tty/smux_loopback.h b/drivers/tty/smux_loopback.h
index 85c6c23..02bff80 100644
--- a/drivers/tty/smux_loopback.h
+++ b/drivers/tty/smux_loopback.h
@@ -1,6 +1,6 @@
 /* drivers/tty/smux_loopback.h
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/tty/smux_private.h b/drivers/tty/smux_private.h
index 195ee0f..8fdec86 100644
--- a/drivers/tty/smux_private.h
+++ b/drivers/tty/smux_private.h
@@ -1,6 +1,6 @@
 /* drivers/tty/smux_private.h
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/tty/smux_test.c b/drivers/tty/smux_test.c
index 81ac04b..e1d9975 100644
--- a/drivers/tty/smux_test.c
+++ b/drivers/tty/smux_test.c
@@ -1,6 +1,6 @@
 /* drivers/tty/smux_test.c
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 55ff980..2382640 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -546,14 +546,15 @@
 	if (!usb_match_device(dev, id))
 		return 0;
 
-	/* The interface class, subclass, and protocol should never be
+	/* The interface class, subclass, protocol and number should never be
 	 * checked for a match if the device class is Vendor Specific,
 	 * unless the match record specifies the Vendor ID. */
 	if (dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC &&
 			!(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
 			(id->match_flags & (USB_DEVICE_ID_MATCH_INT_CLASS |
 				USB_DEVICE_ID_MATCH_INT_SUBCLASS |
-				USB_DEVICE_ID_MATCH_INT_PROTOCOL)))
+				USB_DEVICE_ID_MATCH_INT_PROTOCOL |
+				USB_DEVICE_ID_MATCH_INT_NUMBER)))
 		return 0;
 
 	if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
@@ -568,6 +569,10 @@
 	    (id->bInterfaceProtocol != intf->desc.bInterfaceProtocol))
 		return 0;
 
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_NUMBER) &&
+	    (id->bInterfaceNumber != intf->desc.bInterfaceNumber))
+		return 0;
+
 	return 1;
 }
 EXPORT_SYMBOL_GPL(usb_match_one_id);
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index b2da64c..3aa16b1 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1535,7 +1535,7 @@
 
 	if (add_uevent_var(env,
 		   "MODALIAS=usb:"
-		   "v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X",
+		   "v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02Xin%02X",
 		   le16_to_cpu(usb_dev->descriptor.idVendor),
 		   le16_to_cpu(usb_dev->descriptor.idProduct),
 		   le16_to_cpu(usb_dev->descriptor.bcdDevice),
@@ -1544,7 +1544,8 @@
 		   usb_dev->descriptor.bDeviceProtocol,
 		   alt->desc.bInterfaceClass,
 		   alt->desc.bInterfaceSubClass,
-		   alt->desc.bInterfaceProtocol))
+		   alt->desc.bInterfaceProtocol,
+		   alt->desc.bInterfaceNumber))
 		return -ENOMEM;
 
 	return 0;
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 566d9f9..87678c5 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -840,7 +840,7 @@
 	alt = intf->cur_altsetting;
 
 	return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02X"
-			"ic%02Xisc%02Xip%02X\n",
+			"ic%02Xisc%02Xip%02Xin%02X\n",
 			le16_to_cpu(udev->descriptor.idVendor),
 			le16_to_cpu(udev->descriptor.idProduct),
 			le16_to_cpu(udev->descriptor.bcdDevice),
@@ -849,7 +849,8 @@
 			udev->descriptor.bDeviceProtocol,
 			alt->desc.bInterfaceClass,
 			alt->desc.bInterfaceSubClass,
-			alt->desc.bInterfaceProtocol);
+			alt->desc.bInterfaceProtocol,
+			alt->desc.bInterfaceNumber);
 }
 static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL);
 
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
index 0b46082..6875b74 100644
--- a/drivers/usb/dwc3/Makefile
+++ b/drivers/usb/dwc3/Makefile
@@ -1,6 +1,7 @@
 ccflags-$(CONFIG_USB_DWC3_DEBUG)	:= -DDEBUG
 ccflags-$(CONFIG_USB_DWC3_VERBOSE)	+= -DVERBOSE_DEBUG
 ccflags-y += -Idrivers/usb/host
+ccflags-y += -Idrivers/base/power
 
 obj-$(CONFIG_USB_DWC3)			+= dwc3.o
 
diff --git a/drivers/usb/dwc3/debug.h b/drivers/usb/dwc3/debug.h
index 5894ee8..b156c5f 100644
--- a/drivers/usb/dwc3/debug.h
+++ b/drivers/usb/dwc3/debug.h
@@ -39,9 +39,24 @@
 #include "core.h"
 
 #ifdef CONFIG_DEBUG_FS
+extern void dbg_event(u8, const char*, int);
+extern void dbg_print(u8, const char*, int, const char*);
+extern void dbg_done(u8, const u32, int);
+extern void dbg_queue(u8, const struct usb_request*, int);
+extern void dbg_setup(u8, const struct usb_ctrlrequest*);
 extern int dwc3_debugfs_init(struct dwc3 *);
 extern void dwc3_debugfs_exit(struct dwc3 *);
 #else
+static inline void dbg_event(u8, const char*, int)
+{  }
+static inline void dbg_print(u8, const char*, int, const char*)
+{  }
+static inline void dbg_done(u8, const u32, int)
+{  }
+static inline void dbg_queue(u8, const struct usb_request*, int)
+{  }
+static inline void dbg_setup(u8, const struct usb_ctrlrequest*)
+{  }
 static inline int dwc3_debugfs_init(struct dwc3 *d)
 {  return 0;  }
 static inline void dwc3_debugfs_exit(struct dwc3 *d)
diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c
index be4eff7..93504eb 100644
--- a/drivers/usb/dwc3/debugfs.c
+++ b/drivers/usb/dwc3/debugfs.c
@@ -36,6 +36,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/ptrace.h>
@@ -652,6 +653,382 @@
 	.release		= single_release,
 };
 
+static int ep_num;
+static ssize_t dwc3_store_ep_num(struct file *file, const char __user *ubuf,
+				 size_t count, loff_t *ppos)
+{
+	struct seq_file		*s = file->private_data;
+	struct dwc3		*dwc = s->private;
+	char			kbuf[10];
+	unsigned int		num, dir;
+	unsigned long		flags;
+
+	memset(kbuf, 0, 10);
+
+	if (copy_from_user(kbuf, ubuf, count > 10 ? 10 : count))
+		return -EFAULT;
+
+	if (sscanf(kbuf, "%u %u", &num, &dir) != 2)
+		return -EINVAL;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	ep_num = (num << 1) + dir;
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	return count;
+}
+
+static int dwc3_ep_req_list_show(struct seq_file *s, void *unused)
+{
+	struct dwc3		*dwc = s->private;
+	struct dwc3_ep		*dep;
+	struct dwc3_request	*req = NULL;
+	struct list_head	*ptr = NULL;
+	unsigned long		flags;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	dep = dwc->eps[ep_num];
+
+	seq_printf(s, "%s request list: flags: 0x%x\n", dep->name, dep->flags);
+	list_for_each(ptr, &dep->request_list) {
+		req = list_entry(ptr, struct dwc3_request, list);
+
+		seq_printf(s, "req:0x%p len: %d sts: %d dma:0x%x num_sgs: %d\n",
+			req, req->request.length, req->request.status,
+			req->request.dma, req->request.num_sgs);
+	}
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	return 0;
+}
+
+static int dwc3_ep_req_list_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, dwc3_ep_req_list_show, inode->i_private);
+}
+
+static const struct file_operations dwc3_ep_req_list_fops = {
+	.open			= dwc3_ep_req_list_open,
+	.write			= dwc3_store_ep_num,
+	.read			= seq_read,
+	.llseek			= seq_lseek,
+	.release		= single_release,
+};
+
+static int dwc3_ep_queued_req_show(struct seq_file *s, void *unused)
+{
+	struct dwc3		*dwc = s->private;
+	struct dwc3_ep		*dep;
+	struct dwc3_request	*req = NULL;
+	struct list_head	*ptr = NULL;
+	unsigned long		flags;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	dep = dwc->eps[ep_num];
+
+	seq_printf(s, "%s queued reqs to HW: flags:0x%x\n", dep->name,
+								dep->flags);
+	list_for_each(ptr, &dep->req_queued) {
+		req = list_entry(ptr, struct dwc3_request, list);
+
+		seq_printf(s, "req:0x%p len:%d sts:%d dma:%x nsg:%d trb:0x%p\n",
+			req, req->request.length, req->request.status,
+			req->request.dma, req->request.num_sgs, req->trb);
+	}
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	return 0;
+}
+
+static int dwc3_ep_queued_req_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, dwc3_ep_queued_req_show, inode->i_private);
+}
+
+const struct file_operations dwc3_ep_req_queued_fops = {
+	.open			= dwc3_ep_queued_req_open,
+	.write			= dwc3_store_ep_num,
+	.read			= seq_read,
+	.llseek			= seq_lseek,
+	.release		= single_release,
+};
+
+static int dwc3_ep_trbs_show(struct seq_file *s, void *unused)
+{
+	struct dwc3		*dwc = s->private;
+	struct dwc3_ep		*dep;
+	struct dwc3_trb		*trb;
+	unsigned long		flags;
+	int			j;
+
+	if (!ep_num)
+		return 0;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	dep = dwc->eps[ep_num];
+
+	seq_printf(s, "%s trb pool: flags:0x%x freeslot:%d busyslot:%d\n",
+		dep->name, dep->flags, dep->free_slot, dep->busy_slot);
+	for (j = 0; j < DWC3_TRB_NUM; j++) {
+		trb = &dep->trb_pool[j];
+		seq_printf(s, "trb:0x%p bph:0x%x bpl:0x%x size:0x%x ctrl: %x\n",
+			trb, trb->bph, trb->bpl, trb->size, trb->ctrl);
+	}
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	return 0;
+}
+
+static int dwc3_ep_trbs_list_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, dwc3_ep_trbs_show, inode->i_private);
+}
+
+const struct file_operations dwc3_ep_trb_list_fops = {
+	.open			= dwc3_ep_trbs_list_open,
+	.write			= dwc3_store_ep_num,
+	.read			= seq_read,
+	.llseek			= seq_lseek,
+	.release		= single_release,
+};
+
+static unsigned int ep_addr_rxdbg_mask;
+module_param(ep_addr_rxdbg_mask, uint, S_IRUGO | S_IWUSR);
+static unsigned int ep_addr_txdbg_mask;
+module_param(ep_addr_txdbg_mask, uint, S_IRUGO | S_IWUSR);
+
+/* Maximum debug message length */
+#define DBG_DATA_MSG   64UL
+
+/* Maximum number of messages */
+#define DBG_DATA_MAX   128UL
+
+static struct {
+	char     (buf[DBG_DATA_MAX])[DBG_DATA_MSG];   /* buffer */
+	unsigned idx;   /* index */
+	unsigned tty;   /* print to console? */
+	rwlock_t lck;   /* lock */
+} dbg_dwc3_data = {
+	.idx = 0,
+	.tty = 0,
+	.lck = __RW_LOCK_UNLOCKED(lck)
+};
+
+/**
+ * dbg_dec: decrements debug event index
+ * @idx: buffer index
+ */
+static inline void __maybe_unused dbg_dec(unsigned *idx)
+{
+	*idx = (*idx - 1) % DBG_DATA_MAX;
+}
+
+/**
+ * dbg_inc: increments debug event index
+ * @idx: buffer index
+ */
+static inline void dbg_inc(unsigned *idx)
+{
+	*idx = (*idx + 1) % DBG_DATA_MAX;
+}
+
+#define TIME_BUF_LEN  20
+/*get_timestamp - returns time of day in us */
+static char *get_timestamp(char *tbuf)
+{
+	unsigned long long t;
+	unsigned long nanosec_rem;
+
+	t = cpu_clock(smp_processor_id());
+	nanosec_rem = do_div(t, 1000000000)/1000;
+	scnprintf(tbuf, TIME_BUF_LEN, "[%5lu.%06lu] ", (unsigned long)t,
+		nanosec_rem);
+	return tbuf;
+}
+
+static int allow_dbg_print(u8 ep_num)
+{
+	int dir, num;
+
+	/* allow bus wide events */
+	if (ep_num == 0xff)
+		return 1;
+
+	dir = ep_num & 0x1;
+	num = ep_num >> 1;
+	num = 1 << num;
+
+	if (dir && (num & ep_addr_txdbg_mask))
+		return 1;
+	if (!dir && (num & ep_addr_rxdbg_mask))
+		return 1;
+
+	return 0;
+}
+
+/**
+ * dbg_print:  prints the common part of the event
+ * @addr:   endpoint address
+ * @name:   event name
+ * @status: status
+ * @extra:  extra information
+ */
+void dbg_print(u8 ep_num, const char *name, int status, const char *extra)
+{
+	unsigned long flags;
+	char tbuf[TIME_BUF_LEN];
+
+	if (!allow_dbg_print(ep_num))
+		return;
+
+	write_lock_irqsave(&dbg_dwc3_data.lck, flags);
+
+	scnprintf(dbg_dwc3_data.buf[dbg_dwc3_data.idx], DBG_DATA_MSG,
+		  "%s\t? %02X %-7.7s %4i ?\t%s\n",
+		  get_timestamp(tbuf), ep_num, name, status, extra);
+
+	dbg_inc(&dbg_dwc3_data.idx);
+
+	write_unlock_irqrestore(&dbg_dwc3_data.lck, flags);
+
+	if (dbg_dwc3_data.tty != 0)
+		pr_notice("%s\t? %02X %-7.7s %4i ?\t%s\n",
+			  get_timestamp(tbuf), ep_num, name, status, extra);
+}
+
+/**
+ * dbg_done: prints a DONE event
+ * @addr:   endpoint address
+ * @td:     transfer descriptor
+ * @status: status
+ */
+void dbg_done(u8 ep_num, const u32 count, int status)
+{
+	char msg[DBG_DATA_MSG];
+
+	if (!allow_dbg_print(ep_num))
+		return;
+
+	scnprintf(msg, sizeof(msg), "%d", count);
+	dbg_print(ep_num, "DONE", status, msg);
+}
+
+/**
+ * dbg_event: prints a generic event
+ * @addr:   endpoint address
+ * @name:   event name
+ * @status: status
+ */
+void dbg_event(u8 ep_num, const char *name, int status)
+{
+	if (!allow_dbg_print(ep_num))
+		return;
+
+	if (name != NULL)
+		dbg_print(ep_num, name, status, "");
+}
+
+/*
+ * dbg_queue: prints a QUEUE event
+ * @addr:   endpoint address
+ * @req:    USB request
+ * @status: status
+ */
+void dbg_queue(u8 ep_num, const struct usb_request *req, int status)
+{
+	char msg[DBG_DATA_MSG];
+
+	if (!allow_dbg_print(ep_num))
+		return;
+
+	if (req != NULL) {
+		scnprintf(msg, sizeof(msg),
+			  "%d %d", !req->no_interrupt, req->length);
+		dbg_print(ep_num, "QUEUE", status, msg);
+	}
+}
+
+/**
+ * dbg_setup: prints a SETUP event
+ * @addr: endpoint address
+ * @req:  setup request
+ */
+void dbg_setup(u8 ep_num, const struct usb_ctrlrequest *req)
+{
+	char msg[DBG_DATA_MSG];
+
+	if (!allow_dbg_print(ep_num))
+		return;
+
+	if (req != NULL) {
+		scnprintf(msg, sizeof(msg),
+			  "%02X %02X %04X %04X %d", req->bRequestType,
+			  req->bRequest, le16_to_cpu(req->wValue),
+			  le16_to_cpu(req->wIndex), le16_to_cpu(req->wLength));
+		dbg_print(ep_num, "SETUP", 0, msg);
+	}
+}
+
+/**
+ * store_events: configure if events are going to be also printed to console
+ *
+ */
+static ssize_t dwc3_store_events(struct file *file,
+			    const char __user *buf, size_t count, loff_t *ppos)
+{
+	unsigned tty;
+
+	if (buf == NULL) {
+		pr_err("[%s] EINVAL\n", __func__);
+		goto done;
+	}
+
+	if (sscanf(buf, "%u", &tty) != 1 || tty > 1) {
+		pr_err("<1|0>: enable|disable console log\n");
+		goto done;
+	}
+
+	dbg_dwc3_data.tty = tty;
+	pr_info("tty = %u", dbg_dwc3_data.tty);
+
+ done:
+	return count;
+}
+
+static int dwc3_gadget_data_events_show(struct seq_file *s, void *unused)
+{
+	unsigned long	flags;
+	unsigned	i;
+
+	read_lock_irqsave(&dbg_dwc3_data.lck, flags);
+
+	i = dbg_dwc3_data.idx;
+	if (strnlen(dbg_dwc3_data.buf[i], DBG_DATA_MSG))
+		seq_printf(s, "%s\n", dbg_dwc3_data.buf[i]);
+	for (dbg_inc(&i); i != dbg_dwc3_data.idx; dbg_inc(&i)) {
+		if (!strnlen(dbg_dwc3_data.buf[i], DBG_DATA_MSG))
+			continue;
+		seq_printf(s, "%s\n", dbg_dwc3_data.buf[i]);
+	}
+
+	read_unlock_irqrestore(&dbg_dwc3_data.lck, flags);
+
+	return 0;
+}
+
+static int dwc3_gadget_data_events_open(struct inode *inode, struct file *f)
+{
+	return single_open(f, dwc3_gadget_data_events_show, inode->i_private);
+}
+
+const struct file_operations dwc3_gadget_dbg_data_fops = {
+	.open			= dwc3_gadget_data_events_open,
+	.read			= seq_read,
+	.write			= dwc3_store_events,
+	.llseek			= seq_lseek,
+	.release		= single_release,
+};
+
 int __devinit dwc3_debugfs_init(struct dwc3 *dwc)
 {
 	struct dentry		*root;
@@ -694,6 +1071,33 @@
 		goto err1;
 	}
 
+	file = debugfs_create_file("trbs", S_IRUGO | S_IWUSR, root,
+			dwc, &dwc3_ep_trb_list_fops);
+	if (!file) {
+		ret = -ENOMEM;
+		goto err1;
+	}
+
+	file = debugfs_create_file("requests", S_IRUGO | S_IWUSR, root,
+			dwc, &dwc3_ep_req_list_fops);
+	if (!file) {
+		ret = -ENOMEM;
+		goto err1;
+	}
+
+	file = debugfs_create_file("queued_reqs", S_IRUGO | S_IWUSR, root,
+			dwc, &dwc3_ep_req_queued_fops);
+	if (!file) {
+		ret = -ENOMEM;
+		goto err1;
+	}
+
+	file = debugfs_create_file("events", S_IRUGO | S_IWUSR, root,
+			dwc, &dwc3_gadget_dbg_data_fops);
+	if (!file) {
+		ret = -ENOMEM;
+		goto err1;
+	}
 	return 0;
 
 err1:
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index bcacf7a..f38de0c 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.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
@@ -38,7 +38,6 @@
 
 #include <mach/rpm-regulator.h>
 #include <mach/rpm-regulator-smd.h>
-#include <mach/msm_xo.h>
 #include <mach/msm_bus.h>
 #include <mach/clk.h>
 
@@ -59,6 +58,10 @@
 module_param(adc_meas_interval, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(adc_meas_interval, "ADC ID polling period");
 
+static int override_phy_init;
+module_param(override_phy_init, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(override_phy_init, "Override HSPHY Init Seq");
+
 /**
  *  USB DBM Hardware registers.
  *
@@ -124,11 +127,15 @@
 #define QSCRATCH_REG_OFFSET	(0x000F8800)
 #define QSCRATCH_GENERAL_CFG	(QSCRATCH_REG_OFFSET + 0x08)
 #define HS_PHY_CTRL_REG		(QSCRATCH_REG_OFFSET + 0x10)
+#define PARAMETER_OVERRIDE_X_REG (QSCRATCH_REG_OFFSET + 0x14)
 #define CHARGING_DET_CTRL_REG	(QSCRATCH_REG_OFFSET + 0x18)
 #define CHARGING_DET_OUTPUT_REG	(QSCRATCH_REG_OFFSET + 0x1C)
 #define ALT_INTERRUPT_EN_REG	(QSCRATCH_REG_OFFSET + 0x20)
 #define HS_PHY_IRQ_STAT_REG	(QSCRATCH_REG_OFFSET + 0x24)
+#define CGCTL_REG		(QSCRATCH_REG_OFFSET + 0x28)
 #define SS_PHY_CTRL_REG		(QSCRATCH_REG_OFFSET + 0x30)
+#define SS_PHY_PARAM_CTRL_1	(QSCRATCH_REG_OFFSET + 0x34)
+#define SS_PHY_PARAM_CTRL_2	(QSCRATCH_REG_OFFSET + 0x38)
 #define SS_CR_PROTOCOL_DATA_IN_REG  (QSCRATCH_REG_OFFSET + 0x3C)
 #define SS_CR_PROTOCOL_DATA_OUT_REG (QSCRATCH_REG_OFFSET + 0x40)
 #define SS_CR_PROTOCOL_CAP_ADDR_REG (QSCRATCH_REG_OFFSET + 0x44)
@@ -152,12 +159,13 @@
 	u8 ep_num_mapping[DBM_MAX_EPS];
 	const struct usb_ep_ops *original_ep_ops[DWC3_ENDPOINTS_NUM];
 	struct list_head req_complete_list;
-	struct msm_xo_voter	*xo_handle;
+	struct clk		*xo_clk;
 	struct clk		*ref_clk;
 	struct clk		*core_clk;
 	struct clk		*iface_clk;
 	struct clk		*sleep_clk;
 	struct clk		*hsphy_sleep_clk;
+	struct clk		*utmi_clk;
 	struct regulator	*hsusb_3p3;
 	struct regulator	*hsusb_1p8;
 	struct regulator	*hsusb_vddcx;
@@ -168,8 +176,10 @@
 	atomic_t                pm_suspended;
 	atomic_t		in_lpm;
 	int			hs_phy_irq;
+	int			hsphy_init_seq;
 	bool			lpm_irq_seen;
 	struct delayed_work	resume_work;
+	struct work_struct	restart_usb_work;
 	struct wake_lock	wlock;
 	struct dwc3_charger	charger;
 	struct usb_phy		*otg_xceiv;
@@ -182,6 +192,7 @@
 	u32			bus_perf_client;
 	struct msm_bus_scale_pdata	*bus_scale_table;
 	struct power_supply	usb_psy;
+	struct power_supply	*ext_vbus_psy;
 	unsigned int		online;
 	unsigned int		host_mode;
 	unsigned int		current_max;
@@ -190,6 +201,7 @@
 	unsigned int		vdd_high_vol_level;
 	bool			vbus_active;
 	bool			ext_inuse;
+	enum dwc3_id_state	id_state;
 };
 
 #define USB_HSPHY_3P3_VOL_MIN		3050000 /* uV */
@@ -583,7 +595,6 @@
 static void dwc3_msm_req_complete_func(struct usb_ep *ep,
 				       struct usb_request *request)
 {
-	struct dwc3_request *req = to_dwc3_request(request);
 	struct dwc3_ep *dep = to_dwc3_ep(ep);
 	struct dwc3_msm_req_complete *req_complete = NULL;
 
@@ -606,8 +617,7 @@
 	 * (normal and link), and the dwc3/gadget.c :: dwc3_gadget_giveback
 	 * released only one.
 	 */
-	if (req->queued)
-		dep->busy_slot++;
+	dep->busy_slot++;
 
 	/* Unconfigure dbm ep */
 	dwc3_msm_dbm_ep_unconfig(dep->number);
@@ -853,6 +863,10 @@
 	struct dwc3_ep *dep = to_dwc3_ep(ep);
 	struct usb_ep_ops *new_ep_ops;
 
+	dwc3_msm_event_buffer_config(dwc3_msm_read_reg(context->base,
+			DWC3_GEVNTADRLO(0)),
+			dwc3_msm_read_reg(context->base, DWC3_GEVNTSIZ(0)));
+
 	/* Save original ep ops for future restore*/
 	if (context->original_ep_ops[dep->number]) {
 		dev_err(context->dev,
@@ -918,6 +932,50 @@
 }
 EXPORT_SYMBOL(msm_ep_unconfig);
 
+static void dwc3_restart_usb_work(struct work_struct *w)
+{
+	struct dwc3_msm *mdwc = container_of(w, struct dwc3_msm,
+						restart_usb_work);
+
+	dev_dbg(mdwc->dev, "%s\n", __func__);
+
+	if (atomic_read(&mdwc->in_lpm) || !mdwc->otg_xceiv) {
+		dev_err(mdwc->dev, "%s failed!!!\n", __func__);
+		return;
+	}
+
+	if (!mdwc->ext_xceiv.bsv) {
+		dev_dbg(mdwc->dev, "%s bailing out in disconnect\n", __func__);
+		return;
+	}
+
+	/* Reset active USB connection */
+	mdwc->ext_xceiv.bsv = false;
+	queue_delayed_work(system_nrt_wq, &mdwc->resume_work, 0);
+	/* Make sure disconnect is processed before sending connect */
+	flush_delayed_work(&mdwc->resume_work);
+
+	mdwc->ext_xceiv.bsv = true;
+	queue_delayed_work(system_nrt_wq, &mdwc->resume_work, 0);
+}
+
+/**
+ * Reset USB peripheral connection
+ * Inform OTG for Vbus LOW followed by Vbus HIGH notification.
+ * This performs full hardware reset and re-initialization which
+ * might be required by some DBM client driver during uninit/cleanup.
+ */
+void msm_dwc3_restart_usb_session(void)
+{
+	struct dwc3_msm *mdwc = context;
+
+	dev_dbg(mdwc->dev, "%s\n", __func__);
+	queue_work(system_nrt_wq, &mdwc->restart_usb_work);
+
+	return;
+}
+EXPORT_SYMBOL(msm_dwc3_restart_usb_session);
+
 /**
  * msm_register_usb_ext_notification: register for event notification
  * @info: pointer to client usb_ext_notification structure. May be NULL.
@@ -1203,6 +1261,24 @@
 	usleep_range(2000, 2200);
 	/* Disable (bypass) VBUS and ID filters */
 	dwc3_msm_write_reg(msm->base, QSCRATCH_GENERAL_CFG, 0x78);
+	/*
+	 * write HSPHY init value to QSCRATCH reg to set HSPHY parameters like
+	 * VBUS valid threshold, disconnect valid threshold, DC voltage level,
+	 * preempasis and rise/fall time.
+	 */
+	if (override_phy_init)
+		msm->hsphy_init_seq = override_phy_init;
+	if (msm->hsphy_init_seq)
+		dwc3_msm_write_readback(msm->base,
+					PARAMETER_OVERRIDE_X_REG, 0x03FFFFFF,
+					msm->hsphy_init_seq & 0x03FFFFFF);
+
+	/* Enable master clock for RAMs to allow BAM to access RAMs when
+	 * RAM clock gating is enabled via DWC3's GCTL. Otherwise, issues
+	 * are seen where RAM clocks get turned OFF in SS mode
+	 */
+	dwc3_msm_write_reg(msm->base, CGCTL_REG,
+		dwc3_msm_read_reg(msm->base, CGCTL_REG) | 0x18);
 
 	/*
 	 * WORKAROUND: There is SSPHY suspend bug due to which USB enumerates
@@ -1215,8 +1291,39 @@
 
 	data = dwc3_msm_ssusb_read_phycreg(msm->base, 0x1010);
 	data &= ~0xFF0;
-	data |= 0x40;
+	data |= 0x20;
 	dwc3_msm_ssusb_write_phycreg(msm->base, 0x1010, data);
+
+	/*
+	 * Fix RX Equalization setting as follows
+	 * LANE0.RX_OVRD_IN_HI. RX_EQ_EN set to 0
+	 * LANE0.RX_OVRD_IN_HI.RX_EQ_EN_OVRD set to 1
+	 * LANE0.RX_OVRD_IN_HI.RX_EQ set to 3
+	 * LANE0.RX_OVRD_IN_HI.RX_EQ_OVRD set to 1
+	 */
+	data = dwc3_msm_ssusb_read_phycreg(msm->base, 0x1006);
+	data &= ~(1 << 6);
+	data |= (1 << 7);
+	data &= ~(0x7 << 8);
+	data |= (0x3 << 8);
+	data |= (0x1 << 11);
+	dwc3_msm_ssusb_write_phycreg(msm->base, 0x1006, data);
+
+	/*
+	 * Set EQ and TX launch amplitudes as follows
+	 * LANE0.TX_OVRD_DRV_LO.PREEMPH set to 22
+	 * LANE0.TX_OVRD_DRV_LO.AMPLITUDE set to 127
+	 * LANE0.TX_OVRD_DRV_LO.EN set to 1.
+	 */
+	data = dwc3_msm_ssusb_read_phycreg(msm->base, 0x1002);
+	data &= ~0x3F80;
+	data |= (0x16 << 7);
+	data &= ~0x7F;
+	data |= (0x7F | (1 << 14));
+	dwc3_msm_ssusb_write_phycreg(msm->base, 0x1002, data);
+
+	/* Set LOS_BIAS to 0x5 */
+	dwc3_msm_write_readback(msm->base, SS_PHY_PARAM_CTRL_1, 0x07, 0x5);
 }
 
 static void dwc3_msm_block_reset(void)
@@ -1237,6 +1344,11 @@
 
 	/* Reinitialize QSCRATCH registers after block reset */
 	dwc3_msm_qscratch_reg_init(mdwc);
+
+	/* Reset the DBM */
+	dwc3_msm_dbm_soft_reset(1);
+	usleep_range(1000, 1200);
+	dwc3_msm_dbm_soft_reset(0);
 }
 
 static void dwc3_chg_enable_secondary_det(struct dwc3_msm *mdwc)
@@ -1259,6 +1371,17 @@
 	dwc3_msm_write_readback(mdwc->base, CHARGING_DET_CTRL_REG, 0x3F, 0x34);
 }
 
+static bool dwc3_chg_det_check_linestate(struct dwc3_msm *mdwc)
+{
+	u32 chg_det;
+	bool ret = false;
+
+	chg_det = dwc3_msm_read_reg(mdwc->base, CHARGING_DET_OUTPUT_REG);
+	ret = chg_det & (3 << 8);
+
+	return ret;
+}
+
 static bool dwc3_chg_det_check_output(struct dwc3_msm *mdwc)
 {
 	u32 chg_det;
@@ -1324,9 +1447,10 @@
 static const char *chg_to_string(enum dwc3_chg_type chg_type)
 {
 	switch (chg_type) {
-	case USB_SDP_CHARGER:		return "USB_SDP_CHARGER";
-	case USB_DCP_CHARGER:		return "USB_DCP_CHARGER";
-	case USB_CDP_CHARGER:		return "USB_CDP_CHARGER";
+	case DWC3_SDP_CHARGER:		return "USB_SDP_CHARGER";
+	case DWC3_DCP_CHARGER:		return "USB_DCP_CHARGER";
+	case DWC3_CDP_CHARGER:		return "USB_CDP_CHARGER";
+	case DWC3_PROPRIETARY_CHARGER:	return "USB_PROPRIETARY_CHARGER";
 	default:			return "INVALID_CHARGER";
 	}
 }
@@ -1356,6 +1480,14 @@
 		tmout = ++mdwc->dcd_retries == DWC3_CHG_DCD_MAX_RETRIES;
 		if (is_dcd || tmout) {
 			dwc3_chg_disable_dcd(mdwc);
+			if (dwc3_chg_det_check_linestate(mdwc)) {
+				dev_dbg(mdwc->dev, "proprietary charger\n");
+				mdwc->charger.chg_type =
+						DWC3_PROPRIETARY_CHARGER;
+				mdwc->chg_state = USB_CHG_STATE_DETECTED;
+				delay = 0;
+				break;
+			}
 			dwc3_chg_enable_primary_det(mdwc);
 			delay = DWC3_CHG_PRIMARY_DET_TIME;
 			mdwc->chg_state = USB_CHG_STATE_DCD_DONE;
@@ -1370,7 +1502,7 @@
 			delay = DWC3_CHG_SECONDARY_DET_TIME;
 			mdwc->chg_state = USB_CHG_STATE_PRIMARY_DONE;
 		} else {
-			mdwc->charger.chg_type = USB_SDP_CHARGER;
+			mdwc->charger.chg_type = DWC3_SDP_CHARGER;
 			mdwc->chg_state = USB_CHG_STATE_DETECTED;
 			delay = 0;
 		}
@@ -1378,9 +1510,9 @@
 	case USB_CHG_STATE_PRIMARY_DONE:
 		vout = dwc3_chg_det_check_output(mdwc);
 		if (vout)
-			mdwc->charger.chg_type = USB_DCP_CHARGER;
+			mdwc->charger.chg_type = DWC3_DCP_CHARGER;
 		else
-			mdwc->charger.chg_type = USB_CDP_CHARGER;
+			mdwc->charger.chg_type = DWC3_CDP_CHARGER;
 		mdwc->chg_state = USB_CHG_STATE_SECONDARY_DONE;
 		/* fall through */
 	case USB_CHG_STATE_SECONDARY_DONE:
@@ -1409,6 +1541,7 @@
 	struct dwc3_msm *mdwc = context;
 
 	if (start == false) {
+		dev_dbg(mdwc->dev, "canceling charging detection work\n");
 		cancel_delayed_work_sync(&mdwc->chg_work);
 		mdwc->chg_state = USB_CHG_STATE_UNDEFINED;
 		charger->chg_type = DWC3_INVALID_CHARGER;
@@ -1424,6 +1557,7 @@
 {
 	int ret;
 	bool dcp;
+	bool host_bus_suspend;
 
 	dev_dbg(mdwc->dev, "%s: entering lpm\n", __func__);
 
@@ -1446,17 +1580,7 @@
 	}
 
 	dcp = mdwc->charger.chg_type == DWC3_DCP_CHARGER;
-
-	/* Sequence to put hardware in low power state:
-	 * 1. Set OTGDISABLE to disable OTG block in HSPHY (saves power)
-	 * 2. Clear charger detection control fields (performed above)
-	 * 3. SUSPEND PHY and turn OFF core clock after some delay
-	 * 4. Clear interrupt latch register and enable BSV, ID HV interrupts
-	 * 5. Enable PHY retention
-	 */
-	dwc3_msm_write_readback(mdwc->base, HS_PHY_CTRL_REG, 0x1000, 0x1000);
-	dwc3_msm_write_readback(mdwc->base, HS_PHY_CTRL_REG,
-						0xC00000, 0x800000);
+	host_bus_suspend = mdwc->host_mode == 1;
 
 	/* Sequence to put SSPHY in low power state:
 	 * 1. Clear REF_SS_PHY_EN in SS_PHY_CTRL_REG
@@ -1472,21 +1596,53 @@
 	usleep_range(1000, 1200);
 	clk_disable_unprepare(mdwc->ref_clk);
 
-	dwc3_msm_write_reg(mdwc->base, HS_PHY_IRQ_STAT_REG, 0xFFF);
-	dwc3_msm_write_readback(mdwc->base, HS_PHY_CTRL_REG, 0x18000, 0x18000);
-	if (!dcp)
-		dwc3_msm_write_readback(mdwc->base, HS_PHY_CTRL_REG, 0x2, 0x0);
+	if (host_bus_suspend) {
+		/* Sequence for host bus suspend case:
+		 * 1. Set suspend and sleep bits in GUSB2PHYCONFIG reg
+		 * 2. Clear interrupt latch register and enable BSV, ID HV intr
+		 * 3. Enable DP and DM HV interrupts in ALT_INTERRUPT_EN_REG
+		 */
+		dwc3_msm_write_reg(mdwc->base, DWC3_GUSB2PHYCFG(0),
+			dwc3_msm_read_reg(mdwc->base, DWC3_GUSB2PHYCFG(0)) |
+								0x00000140);
+		dwc3_msm_write_reg(mdwc->base, HS_PHY_IRQ_STAT_REG, 0xFFF);
+		if (mdwc->otg_xceiv && (!mdwc->ext_xceiv.otg_capability))
+			dwc3_msm_write_readback(mdwc->base, HS_PHY_CTRL_REG,
+							 0x18000, 0x18000);
+		dwc3_msm_write_reg(mdwc->base, ALT_INTERRUPT_EN_REG, 0xFC0);
+		udelay(5);
+	} else {
+		/* Sequence to put hardware in low power state:
+		 * 1. Set OTGDISABLE to disable OTG block in HSPHY (saves power)
+		 * 2. Clear charger detection control fields (performed above)
+		 * 3. SUSPEND PHY and turn OFF core clock after some delay
+		 * 4. Clear interrupt latch register and enable BSV, ID HV intr
+		 * 5. Enable PHY retention
+		 */
+		dwc3_msm_write_readback(mdwc->base, HS_PHY_CTRL_REG, 0x1000,
+									0x1000);
+		dwc3_msm_write_readback(mdwc->base, HS_PHY_CTRL_REG,
+							0xC00000, 0x800000);
+		dwc3_msm_write_reg(mdwc->base, HS_PHY_IRQ_STAT_REG, 0xFFF);
+		if (mdwc->otg_xceiv && (!mdwc->ext_xceiv.otg_capability))
+			dwc3_msm_write_readback(mdwc->base, HS_PHY_CTRL_REG,
+							0x18000, 0x18000);
+		if (!dcp)
+			dwc3_msm_write_readback(mdwc->base, HS_PHY_CTRL_REG,
+								0x2, 0x0);
+	}
 
 	/* make sure above writes are completed before turning off clocks */
 	wmb();
 	clk_disable_unprepare(mdwc->core_clk);
 	clk_disable_unprepare(mdwc->iface_clk);
 
-	/* USB PHY no more requires TCXO */
-	ret = msm_xo_mode_vote(mdwc->xo_handle, MSM_XO_MODE_OFF);
-	if (ret)
-		dev_err(mdwc->dev, "%s failed to devote for TCXO buffer%d\n",
-						__func__, ret);
+	if (!host_bus_suspend) {
+		clk_disable_unprepare(mdwc->utmi_clk);
+
+		/* USB PHY no more requires TCXO */
+		clk_disable_unprepare(mdwc->xo_clk);
+	}
 
 	if (mdwc->bus_perf_client) {
 		ret = msm_bus_scale_client_update_request(
@@ -1495,12 +1651,14 @@
 			dev_err(mdwc->dev, "Failed to reset bus bw vote\n");
 	}
 
-	if (mdwc->otg_xceiv && mdwc->ext_xceiv.otg_capability && !dcp)
+	if (mdwc->otg_xceiv && mdwc->ext_xceiv.otg_capability && !dcp &&
+							!host_bus_suspend)
 		dwc3_hsusb_ldo_enable(0);
 
 	dwc3_ssusb_ldo_enable(0);
 	dwc3_ssusb_config_vddcx(0);
-	dwc3_hsusb_config_vddcx(0);
+	if (!host_bus_suspend)
+		dwc3_hsusb_config_vddcx(0);
 	wake_unlock(&mdwc->wlock);
 	atomic_set(&mdwc->in_lpm, 1);
 
@@ -1516,6 +1674,7 @@
 {
 	int ret;
 	bool dcp;
+	bool host_bus_suspend;
 
 	dev_dbg(mdwc->dev, "%s: exiting lpm\n", __func__);
 
@@ -1533,39 +1692,71 @@
 			dev_err(mdwc->dev, "Failed to vote for bus scaling\n");
 	}
 
-	/* Vote for TCXO while waking up USB HSPHY */
-	ret = msm_xo_mode_vote(mdwc->xo_handle, MSM_XO_MODE_ON);
-	if (ret)
-		dev_err(mdwc->dev, "%s failed to vote for TCXO buffer%d\n",
-						__func__, ret);
-
 	dcp = mdwc->charger.chg_type == DWC3_DCP_CHARGER;
-	if (mdwc->otg_xceiv && mdwc->ext_xceiv.otg_capability && !dcp)
+	host_bus_suspend = mdwc->host_mode == 1;
+
+	if (!host_bus_suspend) {
+		/* Vote for TCXO while waking up USB HSPHY */
+		ret = clk_prepare_enable(mdwc->xo_clk);
+		if (ret)
+			dev_err(mdwc->dev, "%s failed to vote TCXO buffer%d\n",
+						__func__, ret);
+	}
+
+	if (mdwc->otg_xceiv && mdwc->ext_xceiv.otg_capability && !dcp &&
+							!host_bus_suspend)
 		dwc3_hsusb_ldo_enable(1);
 
 	dwc3_ssusb_ldo_enable(1);
 	dwc3_ssusb_config_vddcx(1);
-	dwc3_hsusb_config_vddcx(1);
+
+	if (!host_bus_suspend) {
+		dwc3_hsusb_config_vddcx(1);
+		clk_prepare_enable(mdwc->utmi_clk);
+	}
+
 	clk_prepare_enable(mdwc->ref_clk);
 	usleep_range(1000, 1200);
 
 	clk_prepare_enable(mdwc->iface_clk);
 	clk_prepare_enable(mdwc->core_clk);
 
-	/* Disable HV interrupt */
-	dwc3_msm_write_readback(mdwc->base, HS_PHY_CTRL_REG, 0x18000, 0x0);
-	/* Disable Retention */
-	dwc3_msm_write_readback(mdwc->base, HS_PHY_CTRL_REG, 0x2, 0x2);
+	if (host_bus_suspend) {
+		/* Disable HV interrupt */
+		if (mdwc->otg_xceiv && (!mdwc->ext_xceiv.otg_capability))
+			dwc3_msm_write_readback(mdwc->base, HS_PHY_CTRL_REG,
+							0x18000, 0x0);
+		/* Clear interrupt latch register */
+		dwc3_msm_write_reg(mdwc->base, HS_PHY_IRQ_STAT_REG, 0x000);
 
-	dwc3_msm_write_reg(mdwc->base, DWC3_GUSB2PHYCFG(0),
-	      dwc3_msm_read_reg(mdwc->base, DWC3_GUSB2PHYCFG(0)) | 0xF0000000);
-	/* 10usec delay required before de-asserting PHY RESET */
-	udelay(10);
-	dwc3_msm_write_reg(mdwc->base, DWC3_GUSB2PHYCFG(0),
-	      dwc3_msm_read_reg(mdwc->base, DWC3_GUSB2PHYCFG(0)) & 0x7FFFFFFF);
+		/* Disable DP and DM HV interrupt */
+		dwc3_msm_write_reg(mdwc->base, ALT_INTERRUPT_EN_REG, 0x000);
 
-	/* Bring PHY out of suspend */
-	dwc3_msm_write_readback(mdwc->base, HS_PHY_CTRL_REG, 0xC00000, 0x0);
+		/* Clear suspend bit in GUSB2PHYCONFIG register */
+		dwc3_msm_write_readback(mdwc->base, DWC3_GUSB2PHYCFG(0),
+								0x40, 0x0);
+	} else {
+		/* Disable HV interrupt */
+		if (mdwc->otg_xceiv && (!mdwc->ext_xceiv.otg_capability))
+			dwc3_msm_write_readback(mdwc->base, HS_PHY_CTRL_REG,
+								0x18000, 0x0);
+		/* Disable Retention */
+		dwc3_msm_write_readback(mdwc->base, HS_PHY_CTRL_REG, 0x2, 0x2);
+
+		dwc3_msm_write_reg(mdwc->base, DWC3_GUSB2PHYCFG(0),
+			dwc3_msm_read_reg(mdwc->base, DWC3_GUSB2PHYCFG(0)) |
+								 0xF0000000);
+		/* 10usec delay required before de-asserting PHY RESET */
+		udelay(10);
+		dwc3_msm_write_reg(mdwc->base, DWC3_GUSB2PHYCFG(0),
+		      dwc3_msm_read_reg(mdwc->base, DWC3_GUSB2PHYCFG(0)) &
+								0x7FFFFFFF);
+
+		/* Bring PHY out of suspend */
+		dwc3_msm_write_readback(mdwc->base, HS_PHY_CTRL_REG, 0xC00000,
+									0x0);
+
+	}
 
 	/* Assert SS PHY RESET */
 	dwc3_msm_write_readback(mdwc->base, SS_PHY_CTRL_REG, (1 << 7),
@@ -1744,6 +1935,9 @@
 	case POWER_SUPPLY_PROP_ONLINE:
 		val->intval = mdwc->online;
 		break;
+	case POWER_SUPPLY_PROP_TYPE:
+		val->intval = psy->type;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -1765,22 +1959,15 @@
 	/* Process PMIC notification in PRESENT prop */
 	case POWER_SUPPLY_PROP_PRESENT:
 		dev_dbg(mdwc->dev, "%s: notify xceiv event\n", __func__);
-		if (mdwc->otg_xceiv && (mdwc->ext_xceiv.otg_capability ||
-							!init)) {
+		if (mdwc->otg_xceiv && !mdwc->ext_inuse &&
+		    (mdwc->ext_xceiv.otg_capability || !init)) {
 			mdwc->ext_xceiv.bsv = val->intval;
-			if (atomic_read(&mdwc->in_lpm)) {
-				dev_dbg(mdwc->dev,
-					"%s received in LPM\n", __func__);
-				queue_delayed_work(system_nrt_wq,
+			queue_delayed_work(system_nrt_wq,
 							&mdwc->resume_work, 0);
-			} else {
-				mdwc->ext_xceiv.notify_ext_events(
-							mdwc->otg_xceiv->otg,
-							DWC3_EVENT_XCEIV_STATE);
-			}
+
+			if (!init)
+				init = true;
 		}
-		if (!init)
-			init = true;
 		mdwc->vbus_active = val->intval;
 		break;
 	case POWER_SUPPLY_PROP_ONLINE:
@@ -1789,6 +1976,9 @@
 	case POWER_SUPPLY_PROP_CURRENT_MAX:
 		mdwc->current_max = val->intval;
 		break;
+	case POWER_SUPPLY_PROP_TYPE:
+		psy->type = val->intval;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -1797,6 +1987,33 @@
 	return 0;
 }
 
+static void dwc3_msm_external_power_changed(struct power_supply *psy)
+{
+	struct dwc3_msm *mdwc = container_of(psy, struct dwc3_msm, usb_psy);
+	union power_supply_propval ret = {0,};
+
+	if (!mdwc->ext_vbus_psy)
+		mdwc->ext_vbus_psy = power_supply_get_by_name("ext-vbus");
+
+	if (!mdwc->ext_vbus_psy) {
+		pr_err("%s: Unable to get ext_vbus power_supply\n", __func__);
+		return;
+	}
+
+	mdwc->ext_vbus_psy->get_property(mdwc->ext_vbus_psy,
+					POWER_SUPPLY_PROP_ONLINE, &ret);
+	if (ret.intval) {
+		dwc3_start_chg_det(&mdwc->charger, false);
+		mdwc->ext_vbus_psy->get_property(mdwc->ext_vbus_psy,
+					POWER_SUPPLY_PROP_CURRENT_MAX, &ret);
+		power_supply_set_current_limit(&mdwc->usb_psy, ret.intval);
+	}
+
+	power_supply_set_online(&mdwc->usb_psy, ret.intval);
+	power_supply_changed(&mdwc->usb_psy);
+}
+
+
 static char *dwc3_msm_pm_power_supplied_to[] = {
 	"battery",
 };
@@ -1813,6 +2030,7 @@
 static void dwc3_ext_notify_online(int on)
 {
 	struct dwc3_msm *mdwc = context;
+	bool notify_otg = false;
 
 	if (!mdwc) {
 		pr_err("%s: DWC3 driver already removed\n", __func__);
@@ -1821,11 +2039,31 @@
 
 	dev_dbg(mdwc->dev, "notify %s%s\n", on ? "" : "dis", "connected");
 
-	if (!on) {
-		/* external client offline; revert back to USB */
-		mdwc->ext_inuse = false;
-		queue_delayed_work(system_nrt_wq, &mdwc->resume_work, 0);
+	if (!mdwc->ext_vbus_psy)
+		mdwc->ext_vbus_psy = power_supply_get_by_name("ext-vbus");
+
+	mdwc->ext_inuse = on;
+	if (on) {
+		/* force OTG to exit B-peripheral state */
+		mdwc->ext_xceiv.bsv = false;
+		notify_otg = true;
+		dwc3_start_chg_det(&mdwc->charger, false);
+	} else {
+		/* external client offline; tell OTG about cached ID/BSV */
+		if (mdwc->ext_xceiv.id != mdwc->id_state) {
+			mdwc->ext_xceiv.id = mdwc->id_state;
+			notify_otg = true;
+		}
+
+		mdwc->ext_xceiv.bsv = mdwc->vbus_active;
+		notify_otg |= mdwc->vbus_active;
 	}
+
+	if (mdwc->ext_vbus_psy)
+		power_supply_set_present(mdwc->ext_vbus_psy, on);
+
+	if (notify_otg)
+		queue_delayed_work(system_nrt_wq, &mdwc->resume_work, 0);
 }
 
 static bool dwc3_ext_trigger_handled(struct dwc3_msm *mdwc,
@@ -1855,21 +2093,26 @@
 	dev_dbg(mdwc->dev, "%s: state = %s\n", __func__,
 			state == ADC_TM_HIGH_STATE ? "high" : "low");
 
+	/* Give external client a chance to handle */
+	if (!mdwc->ext_inuse)
+		dwc3_ext_trigger_handled(mdwc, (state == ADC_TM_HIGH_STATE));
+
+	/* save ID state, but don't necessarily notify OTG */
 	if (state == ADC_TM_HIGH_STATE) {
-		mdwc->ext_xceiv.id = DWC3_ID_FLOAT;
+		mdwc->id_state = DWC3_ID_FLOAT;
 		mdwc->adc_param.state_request = ADC_TM_LOW_THR_ENABLE;
 	} else {
-		mdwc->ext_xceiv.id = DWC3_ID_GROUND;
+		mdwc->id_state = DWC3_ID_GROUND;
 		mdwc->adc_param.state_request = ADC_TM_HIGH_THR_ENABLE;
 	}
 
-	/* Give external client a chance to handle, otherwise notify OTG */
-	if (!mdwc->ext_inuse &&
-			!dwc3_ext_trigger_handled(mdwc, mdwc->ext_xceiv.id))
-		queue_delayed_work(system_nrt_wq, &mdwc->resume_work, 0);
-
 	/* re-arm ADC interrupt */
 	qpnp_adc_tm_usbid_configure(&mdwc->adc_param);
+
+	if (!mdwc->ext_inuse) { /* notify OTG */
+		mdwc->ext_xceiv.id = mdwc->id_state;
+		queue_delayed_work(system_nrt_wq, &mdwc->resume_work, 0);
+	}
 }
 
 static void dwc3_init_adc_work(struct work_struct *w)
@@ -1952,20 +2195,21 @@
 	INIT_LIST_HEAD(&msm->req_complete_list);
 	INIT_DELAYED_WORK(&msm->chg_work, dwc3_chg_detect_work);
 	INIT_DELAYED_WORK(&msm->resume_work, dwc3_resume_work);
+	INIT_WORK(&msm->restart_usb_work, dwc3_restart_usb_work);
 	INIT_DELAYED_WORK(&msm->init_adc_work, dwc3_init_adc_work);
 
-	msm->xo_handle = msm_xo_get(MSM_XO_TCXO_D0, "usb");
-	if (IS_ERR(msm->xo_handle)) {
+	msm->xo_clk = clk_get(&pdev->dev, "xo");
+	if (IS_ERR(msm->xo_clk)) {
 		dev_err(&pdev->dev, "%s unable to get TCXO buffer handle\n",
 								__func__);
-		return PTR_ERR(msm->xo_handle);
+		return PTR_ERR(msm->xo_clk);
 	}
 
-	ret = msm_xo_mode_vote(msm->xo_handle, MSM_XO_MODE_ON);
+	ret = clk_prepare_enable(msm->xo_clk);
 	if (ret) {
 		dev_err(&pdev->dev, "%s failed to vote for TCXO buffer%d\n",
 						__func__, ret);
-		goto free_xo_handle;
+		goto put_xo;
 	}
 
 	/*
@@ -1976,7 +2220,7 @@
 	if (IS_ERR(msm->core_clk)) {
 		dev_err(&pdev->dev, "failed to get core_clk\n");
 		ret = PTR_ERR(msm->core_clk);
-		goto free_xo_handle;
+		goto disable_xo;
 	}
 	clk_set_rate(msm->core_clk, 125000000);
 	clk_prepare_enable(msm->core_clk);
@@ -2005,15 +2249,22 @@
 	}
 	clk_prepare_enable(msm->hsphy_sleep_clk);
 
+	msm->utmi_clk = devm_clk_get(&pdev->dev, "utmi_clk");
+	if (IS_ERR(msm->utmi_clk)) {
+		dev_err(&pdev->dev, "failed to get utmi_clk\n");
+		ret = PTR_ERR(msm->utmi_clk);
+		goto disable_sleep_a_clk;
+	}
+	clk_prepare_enable(msm->utmi_clk);
+
 	msm->ref_clk = devm_clk_get(&pdev->dev, "ref_clk");
 	if (IS_ERR(msm->ref_clk)) {
 		dev_err(&pdev->dev, "failed to get ref_clk\n");
 		ret = PTR_ERR(msm->ref_clk);
-		goto disable_sleep_a_clk;
+		goto disable_utmi_clk;
 	}
 	clk_prepare_enable(msm->ref_clk);
 
-
 	of_get_property(node, "qcom,vdd-voltage-level", &len);
 	if (len == sizeof(tmp)) {
 		of_property_read_u32_array(node, "qcom,vdd-voltage-level",
@@ -2097,22 +2348,24 @@
 	msm->charger.charging_disabled = of_property_read_bool(node,
 				"qcom,charging-disabled");
 
-	if (!msm->ext_xceiv.otg_capability) {
-		/* DWC3 has separate IRQ line for OTG events (ID/BSV etc.) */
-		msm->hs_phy_irq = platform_get_irq_byname(pdev, "hs_phy_irq");
-		if (msm->hs_phy_irq < 0) {
-			dev_dbg(&pdev->dev, "pget_irq for hs_phy_irq failed\n");
-			msm->hs_phy_irq = 0;
-		} else {
-			ret = request_irq(msm->hs_phy_irq, msm_dwc3_irq,
-					IRQF_TRIGGER_RISING, "msm_dwc3", msm);
-			if (ret) {
-				dev_err(&pdev->dev, "irqreq HSPHYINT failed\n");
-				goto disable_hs_ldo;
-			}
-			enable_irq_wake(msm->hs_phy_irq);
-		}
+	/*
+	 * DWC3 has separate IRQ line for OTG events (ID/BSV) and for
+	 * DP and DM linestate transitions during low power mode.
+	 */
+	msm->hs_phy_irq = platform_get_irq_byname(pdev, "hs_phy_irq");
+	if (msm->hs_phy_irq < 0) {
+		dev_dbg(&pdev->dev, "pget_irq for hs_phy_irq failed\n");
+		msm->hs_phy_irq = 0;
 	} else {
+		ret = request_irq(msm->hs_phy_irq, msm_dwc3_irq,
+				IRQF_TRIGGER_RISING, "msm_dwc3", msm);
+		if (ret) {
+			dev_err(&pdev->dev, "irqreq HSPHYINT failed\n");
+			goto disable_hs_ldo;
+		}
+		enable_irq_wake(msm->hs_phy_irq);
+	}
+	if (msm->ext_xceiv.otg_capability) {
 		/* Use ADC for ID pin detection */
 		queue_delayed_work(system_nrt_wq, &msm->init_adc_work, 0);
 		device_create_file(&pdev->dev, &dev_attr_adc_enable);
@@ -2166,6 +2419,12 @@
 	msm->resource_size = resource_size(res);
 	msm->dwc3 = dwc3;
 
+	if (of_property_read_u32(node, "qcom,dwc-hsphy-init",
+						&msm->hsphy_init_seq))
+		dev_dbg(&pdev->dev, "unable to read hsphy init seq\n");
+	else if (!msm->hsphy_init_seq)
+		dev_warn(&pdev->dev, "incorrect hsphyinitseq.Using PORvalue\n");
+
 	dwc3_msm_qscratch_reg_init(msm);
 
 	pm_runtime_set_active(msm->dev);
@@ -2196,6 +2455,8 @@
 	msm->usb_psy.num_properties = ARRAY_SIZE(dwc3_msm_pm_power_props_usb);
 	msm->usb_psy.get_property = dwc3_msm_power_get_property_usb;
 	msm->usb_psy.set_property = dwc3_msm_power_set_property_usb;
+	msm->usb_psy.external_power_changed =
+				dwc3_msm_external_power_changed;
 
 	ret = power_supply_register(&pdev->dev, &msm->usb_psy);
 	if (ret < 0) {
@@ -2230,15 +2491,6 @@
 			dev_err(&pdev->dev, "Failed to vote for bus scaling\n");
 	}
 
-	/* Reset the DBM */
-	dwc3_msm_dbm_soft_reset(1);
-	usleep_range(1000, 1200);
-	dwc3_msm_dbm_soft_reset(0);
-
-	dwc3_msm_event_buffer_config(dwc3_msm_read_reg(msm->base,
-							DWC3_GEVNTADRLO(0)),
-				dwc3_msm_read_reg(msm->base, DWC3_GEVNTSIZ(0)));
-
 	msm->otg_xceiv = usb_get_transceiver();
 	if (msm->otg_xceiv) {
 		msm->charger.start_detection = dwc3_start_chg_det;
@@ -2295,6 +2547,8 @@
 	dwc3_ssusb_config_vddcx(0);
 disable_ref_clk:
 	clk_disable_unprepare(msm->ref_clk);
+disable_utmi_clk:
+	clk_disable_unprepare(msm->utmi_clk);
 disable_sleep_a_clk:
 	clk_disable_unprepare(msm->hsphy_sleep_clk);
 disable_sleep_clk:
@@ -2303,8 +2557,10 @@
 	clk_disable_unprepare(msm->iface_clk);
 disable_core_clk:
 	clk_disable_unprepare(msm->core_clk);
-free_xo_handle:
-	msm_xo_put(msm->xo_handle);
+disable_xo:
+	clk_disable_unprepare(msm->xo_clk);
+put_xo:
+	clk_put(msm->xo_clk);
 
 	return ret;
 }
@@ -2339,7 +2595,8 @@
 	clk_disable_unprepare(msm->sleep_clk);
 	clk_disable_unprepare(msm->hsphy_sleep_clk);
 	clk_disable_unprepare(msm->ref_clk);
-	msm_xo_put(msm->xo_handle);
+	clk_disable_unprepare(msm->xo_clk);
+	clk_put(msm->xo_clk);
 
 	return 0;
 }
@@ -2351,6 +2608,12 @@
 
 	dev_dbg(dev, "dwc3-msm PM suspend\n");
 
+	flush_delayed_work_sync(&mdwc->resume_work);
+	if (!atomic_read(&mdwc->in_lpm)) {
+		dev_err(mdwc->dev, "Abort PM suspend!! (USB is outside LPM)\n");
+		return -EBUSY;
+	}
+
 	ret = dwc3_msm_suspend(mdwc);
 	if (!ret)
 		atomic_set(&mdwc->pm_suspended, 1);
diff --git a/drivers/usb/dwc3/dwc3_otg.c b/drivers/usb/dwc3/dwc3_otg.c
index 136cc5d..01fad76 100644
--- a/drivers/usb/dwc3/dwc3_otg.c
+++ b/drivers/usb/dwc3/dwc3_otg.c
@@ -1,7 +1,7 @@
 /**
  * dwc3_otg.c - DesignWare USB3 DRD Controller OTG
  *
- * 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
@@ -55,6 +55,25 @@
 	}
 }
 
+static int dwc3_otg_set_suspend(struct usb_phy *phy, int suspend)
+{
+	struct usb_otg *otg = phy->otg;
+	struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
+
+	if (dotg->host_bus_suspend == suspend)
+		return 0;
+
+	dotg->host_bus_suspend = suspend;
+	if (suspend) {
+		pm_runtime_put_sync(phy->dev);
+	} else {
+		pm_runtime_get_noresume(phy->dev);
+		pm_runtime_resume(phy->dev);
+	}
+
+	return 0;
+}
+
 /**
  * dwc3_otg_set_host_power - Enable port power control for host operation
  *
@@ -149,6 +168,14 @@
 		 * anymore.
 		 */
 		dwc3_otg_set_host_regs(dotg);
+		/*
+		 * FIXME If micro A cable is disconnected during system suspend,
+		 * xhci platform device will be removed before runtime pm is
+		 * enabled for xhci device. Due to this, disable_depth becomes
+		 * greater than one and runtimepm is not enabled for next microA
+		 * connect. Fix this by calling pm_runtime_init for xhci device.
+		 */
+		pm_runtime_init(&dwc->xhci->dev);
 		ret = platform_device_add(dwc->xhci);
 		if (ret) {
 			dev_err(otg->phy->dev,
@@ -179,16 +206,6 @@
 			return ret;
 		}
 		dwc3_otg_notify_host_mode(otg, on);
-
-		/* Do block reset for Host <-> peripheral switching to work */
-		if (ext_xceiv && ext_xceiv->otg_capability &&
-						ext_xceiv->ext_block_reset)
-			ext_xceiv->ext_block_reset();
-
-		/* re-init core and OTG register as XHCI reset clears it */
-		dwc3_post_host_reset_core_init(dwc);
-		if (ext_xceiv && !ext_xceiv->otg_capability)
-			dwc3_otg_reset(dotg);
 	}
 
 	return 0;
@@ -235,6 +252,8 @@
 static int dwc3_otg_start_peripheral(struct usb_otg *otg, int on)
 {
 	struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
+	struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
+	struct dwc3 *dwc = dotg->dwc;
 
 	if (!otg->gadget)
 		return -EINVAL;
@@ -242,6 +261,22 @@
 	if (on) {
 		dev_dbg(otg->phy->dev, "%s: turn on gadget %s\n",
 					__func__, otg->gadget->name);
+
+		/*
+		 * Hardware reset is required to support below scenarios:
+		 * 1. Host <-> peripheral switching
+		 * 2. Once an endpoint is configured in DBM (BAM) mode, it
+		 * can be unconfigured only after RESET
+		 */
+		if (ext_xceiv && ext_xceiv->otg_capability &&
+						ext_xceiv->ext_block_reset)
+			ext_xceiv->ext_block_reset();
+
+		/* re-init core and OTG registers as block reset clears these */
+		dwc3_post_host_reset_core_init(dwc);
+		if (ext_xceiv && !ext_xceiv->otg_capability)
+			dwc3_otg_reset(dotg);
+
 		dwc3_otg_set_peripheral_regs(dotg);
 		usb_gadget_vbus_connect(otg->gadget);
 	} else {
@@ -337,7 +372,10 @@
 	struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
 	struct usb_phy *phy = dotg->otg.phy;
 	int ret = 0;
-	int work = 0;
+
+	/* Flush processing any pending events before handling new ones */
+	if (init)
+		flush_work(&dotg->sm_work);
 
 	if (event == DWC3_EVENT_PHY_RESUME) {
 		if (!pm_runtime_status_suspended(phy->dev)) {
@@ -346,6 +384,9 @@
 			dev_dbg(phy->dev, "ext PHY_RESUME event received\n");
 			/* ext_xceiver would have taken h/w out of LPM by now */
 			ret = pm_runtime_get(phy->dev);
+			if ((phy->state == OTG_STATE_A_HOST) &&
+							dotg->host_bus_suspend)
+				dotg->host_bus_suspend = 0;
 			if (ret == -EACCES) {
 				/* pm_runtime_get may fail during system
 				   resume with -EACCES error */
@@ -357,28 +398,26 @@
 			}
 		}
 	} else if (event == DWC3_EVENT_XCEIV_STATE) {
+		if (pm_runtime_status_suspended(phy->dev)) {
+			dev_warn(phy->dev, "PHY_STATE event in LPM!!!!\n");
+			ret = pm_runtime_get(phy->dev);
+			if (ret < 0)
+				dev_warn(phy->dev, "pm_runtime_get failed!!\n");
+		}
 		if (ext_xceiv->id == DWC3_ID_FLOAT) {
-			if (!test_and_set_bit(ID, &dotg->inputs)) {
-				dev_dbg(phy->dev, "XCVR: ID set\n");
-				work = 1;
-			}
+			dev_dbg(phy->dev, "XCVR: ID set\n");
+			set_bit(ID, &dotg->inputs);
 		} else {
-			if (test_and_clear_bit(ID, &dotg->inputs)) {
-				dev_dbg(phy->dev, "XCVR: ID clear\n");
-				work = 1;
-			}
+			dev_dbg(phy->dev, "XCVR: ID clear\n");
+			clear_bit(ID, &dotg->inputs);
 		}
 
 		if (ext_xceiv->bsv) {
-			if (!test_and_set_bit(B_SESS_VLD, &dotg->inputs)) {
-				dev_dbg(phy->dev, "XCVR: BSV set\n");
-				work = 1;
-			}
+			dev_dbg(phy->dev, "XCVR: BSV set\n");
+			set_bit(B_SESS_VLD, &dotg->inputs);
 		} else {
-			if (test_and_clear_bit(B_SESS_VLD, &dotg->inputs)) {
-				dev_dbg(phy->dev, "XCVR: BSV clear\n");
-				work = 1;
-			}
+			dev_dbg(phy->dev, "XCVR: BSV clear\n");
+			clear_bit(B_SESS_VLD, &dotg->inputs);
 		}
 
 		if (!init) {
@@ -387,8 +426,8 @@
 			dev_dbg(phy->dev, "XCVR: BSV init complete\n");
 			return;
 		}
-		if (work)
-			schedule_work(&dotg->sm_work);
+
+		schedule_work(&dotg->sm_work);
 	}
 }
 
@@ -443,7 +482,8 @@
 		power_supply_type = POWER_SUPPLY_TYPE_USB;
 	else if (dotg->charger->chg_type == DWC3_CDP_CHARGER)
 		power_supply_type = POWER_SUPPLY_TYPE_USB_CDP;
-	else if (dotg->charger->chg_type == DWC3_DCP_CHARGER)
+	else if (dotg->charger->chg_type == DWC3_DCP_CHARGER ||
+			dotg->charger->chg_type == DWC3_PROPRIETARY_CHARGER)
 		power_supply_type = POWER_SUPPLY_TYPE_USB_DCP;
 	else
 		power_supply_type = POWER_SUPPLY_TYPE_BATTERY;
@@ -646,6 +686,7 @@
 				/* Has charger been detected? If no detect it */
 				switch (charger->chg_type) {
 				case DWC3_DCP_CHARGER:
+				case DWC3_PROPRIETARY_CHARGER:
 					dev_dbg(phy->dev, "lpm, DCP charger\n");
 					dwc3_otg_set_power(phy,
 							DWC3_IDEV_CHG_MAX);
@@ -714,7 +755,8 @@
 			phy->state = OTG_STATE_B_IDLE;
 			work = 1;
 		} else {
-			 if (dwc3_otg_start_host(&dotg->otg, 1)) {
+			phy->state = OTG_STATE_A_HOST;
+			if (dwc3_otg_start_host(&dotg->otg, 1)) {
 				/*
 				 * Probably set_host was not called yet.
 				 * We will re-try as soon as it will be called
@@ -725,7 +767,6 @@
 				pm_runtime_put_sync(phy->dev);
 				return;
 			}
-			phy->state = OTG_STATE_A_HOST;
 		}
 		break;
 
@@ -853,6 +894,7 @@
 	dotg->otg.phy->otg = &dotg->otg;
 	dotg->otg.phy->dev = dwc->dev;
 	dotg->otg.phy->set_power = dwc3_otg_set_power;
+	dotg->otg.phy->set_suspend = dwc3_otg_set_suspend;
 
 	ret = usb_set_transceiver(dotg->otg.phy);
 	if (ret) {
diff --git a/drivers/usb/dwc3/dwc3_otg.h b/drivers/usb/dwc3/dwc3_otg.h
index 5a36a4f..d3b1b4a 100644
--- a/drivers/usb/dwc3/dwc3_otg.h
+++ b/drivers/usb/dwc3/dwc3_otg.h
@@ -1,7 +1,7 @@
 /**
  * dwc3_otg.h - DesignWare USB3 DRD Controller OTG
  *
- * Copyright (c) 2012, Code Aurora Forum. 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
@@ -20,6 +20,7 @@
 #include <linux/power_supply.h>
 
 #include <linux/usb/otg.h>
+#include "power.h"
 
 #define DWC3_IDEV_CHG_MAX 1500
 
@@ -48,6 +49,7 @@
 	unsigned long inputs;
 	struct power_supply	*psy;
 	struct completion	dwc3_xcvr_vbus_init;
+	int			host_bus_suspend;
 };
 
 /**
@@ -59,12 +61,15 @@
  * DWC3_DCP_CHARGER	Dedicated charger port (AC charger/ Wall charger).
  * DWC3_CDP_CHARGER	Charging downstream port. Enumeration can happen and
  *                      IDEV_CHG_MAX can be drawn irrespective of USB state.
+ * DWC3_PROPRIETARY_CHARGER A proprietary charger pull DP and DM to specific
+ *                     voltages between 2.0-3.3v for identification.
  */
 enum dwc3_chg_type {
 	DWC3_INVALID_CHARGER = 0,
 	DWC3_SDP_CHARGER,
 	DWC3_DCP_CHARGER,
 	DWC3_CDP_CHARGER,
+	DWC3_PROPRIETARY_CHARGER,
 };
 
 struct dwc3_charger {
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 1512513..a1d7a87 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -53,6 +53,7 @@
 #include "core.h"
 #include "gadget.h"
 #include "io.h"
+#include "debug.h"
 
 static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep);
 static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
@@ -741,6 +742,7 @@
 		dwc->ep0_next_event = DWC3_EP0_NRDY_DATA;
 	}
 
+	dbg_setup(0x00, ctrl);
 	if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
 		ret = dwc3_ep0_std_request(dwc, ctrl);
 	else
@@ -849,6 +851,7 @@
 	if (status == DWC3_TRBSTS_SETUP_PENDING)
 		dev_dbg(dwc->dev, "Setup Pending received\n");
 
+	dbg_print(dep->number, "DONE", status, "STATUS");
 	dwc->ep0state = EP0_SETUP_PHASE;
 	dwc3_ep0_out_start(dwc);
 }
@@ -931,6 +934,7 @@
 				req->request.length, DWC3_TRBCTL_CONTROL_DATA);
 	}
 
+	dbg_queue(dep->number, &req->request, ret);
 	WARN_ON(ret < 0);
 }
 
@@ -948,13 +952,16 @@
 
 static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep)
 {
+	int ret;
 	if (dwc->resize_fifos) {
 		dev_dbg(dwc->dev, "starting to resize fifos\n");
 		dwc3_gadget_resize_tx_fifos(dwc);
 		dwc->resize_fifos = 0;
 	}
 
-	WARN_ON(dwc3_ep0_start_control_status(dep));
+	ret = dwc3_ep0_start_control_status(dep);
+	dbg_print(dep->number, "QUEUE", ret, "STATUS");
+	WARN_ON(ret);
 }
 
 static void dwc3_ep0_do_control_status(struct dwc3 *dwc,
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index c2bc3f3..5694999 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -53,6 +53,7 @@
 
 #include "core.h"
 #include "gadget.h"
+#include "debug.h"
 #include "io.h"
 
 /**
@@ -190,7 +191,8 @@
 	 * FIXME For now we will only allocate 1 wMaxPacketSize space
 	 * for each enabled endpoint, later patches will come to
 	 * improve this algorithm so that we better use the internal
-	 * FIFO space
+	 * FIFO space. Also consider the case where TxFIFO RAM space
+	 * may change dynamically based on the USB configuration.
 	 */
 	for (num = 0; num < DWC3_ENDPOINTS_NUM; num++) {
 		struct dwc3_ep	*dep = dwc->eps[num];
@@ -204,7 +206,8 @@
 		if (!(dep->flags & DWC3_EP_ENABLED))
 			continue;
 
-		if (usb_endpoint_xfer_bulk(dep->endpoint.desc)
+		if (((dep->endpoint.maxburst > 1) &&
+				usb_endpoint_xfer_bulk(dep->endpoint.desc))
 				|| usb_endpoint_xfer_isoc(dep->endpoint.desc))
 			mult = 3;
 
@@ -214,8 +217,8 @@
 		 * Make sure that's true somehow and change FIFO allocation
 		 * accordingly.
 		 *
-		 * If we have Bulk or Isochronous endpoints, we want
-		 * them to be able to be very, very fast. So we're giving
+		 * If we have Bulk (burst only) or Isochronous endpoints, we
+		 * want them to be able to be very, very fast. So we're giving
 		 * those endpoints a fifo_size which is enough for 3 full
 		 * packets
 		 */
@@ -244,6 +247,8 @@
 	struct dwc3			*dwc = dep->dwc;
 
 	if (req->queued) {
+		req->queued = false;
+
 		if (req->request.num_mapped_sgs)
 			dep->busy_slot += req->request.num_mapped_sgs;
 		else
@@ -274,6 +279,7 @@
 			req, dep->name, req->request.actual,
 			req->request.length, status);
 
+	dbg_done(dep->number, req->request.actual, req->request.status);
 	spin_unlock(&dwc->lock);
 	req->request.complete(&dep->endpoint, &req->request);
 	spin_lock(&dwc->lock);
@@ -354,7 +360,16 @@
 		if (!(reg & DWC3_DEPCMD_CMDACT)) {
 			dev_vdbg(dwc->dev, "Command Complete --> %d\n",
 					DWC3_DEPCMD_STATUS(reg));
-			return 0;
+			/* SW issues START TRANSFER command to isochronous ep
+			 * with future frame interval. If future interval time
+			 * has already passed when core recieves command, core
+			 * will respond with an error(bit13 in Command complete
+			 * event. Hence return error in this case.
+			 */
+			if (reg & 0x2000)
+				return -EAGAIN;
+			else
+				return 0;
 		}
 
 		/*
@@ -679,6 +694,7 @@
 
 	spin_lock_irqsave(&dwc->lock, flags);
 	ret = __dwc3_gadget_ep_enable(dep, desc, ep->comp_desc, false);
+	dbg_event(dep->number, "ENABLE", ret);
 	spin_unlock_irqrestore(&dwc->lock, flags);
 
 	return ret;
@@ -711,6 +727,7 @@
 
 	spin_lock_irqsave(&dwc->lock, flags);
 	ret = __dwc3_gadget_ep_disable(dep);
+	dbg_event(dep->number, "DISABLE", ret);
 	spin_unlock_irqrestore(&dwc->lock, flags);
 
 	return ret;
@@ -767,9 +784,9 @@
 	dep->free_slot++;
 
 	/* Skip the LINK-TRB on ISOC */
-	if (((cur_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) &&
+	if (((dep->free_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) &&
 			usb_endpoint_xfer_isoc(dep->endpoint.desc))
-		return;
+		dep->free_slot++;
 
 	if (!req->trb) {
 		dwc3_gadget_move_request_queued(req);
@@ -918,6 +935,7 @@
 				if (last_one)
 					break;
 			}
+			dbg_queue(dep->number, &req->request, 0);
 		} else {
 			dma = req->request.dma;
 			length = req->request.length;
@@ -933,6 +951,7 @@
 			dwc3_prepare_one_trb(dep, req, dma, length,
 					last_one, false);
 
+			dbg_queue(dep->number, &req->request, 0);
 			if (last_one)
 				break;
 		}
@@ -943,7 +962,7 @@
 		int start_new)
 {
 	struct dwc3_gadget_ep_cmd_params params;
-	struct dwc3_request		*req;
+	struct dwc3_request		*req, *req1, *n;
 	struct dwc3			*dwc = dep->dwc;
 	int				ret;
 	u32				cmd;
@@ -974,6 +993,7 @@
 	}
 	if (!req) {
 		dep->flags |= DWC3_EP_PENDING_REQUEST;
+		dbg_event(dep->number, "NO REQ", 0);
 		return 0;
 	}
 
@@ -991,15 +1011,44 @@
 	if (ret < 0) {
 		dev_dbg(dwc->dev, "failed to send STARTTRANSFER command\n");
 
-		/*
-		 * FIXME we need to iterate over the list of requests
-		 * here and stop, unmap, free and del each of the linked
-		 * requests instead of what we do now.
-		 */
-		usb_gadget_unmap_request(&dwc->gadget, &req->request,
+		if ((ret == -EAGAIN) && start_new &&
+				usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
+			/* If bit13 in Command complete event is set, software
+			 * must issue ENDTRANDFER command and wait for
+			 * Xfernotready event to queue the requests again.
+			 */
+			if (!dep->resource_index) {
+				dep->resource_index =
+					 dwc3_gadget_ep_get_transfer_index(dwc,
+								dep->number);
+				WARN_ON_ONCE(!dep->resource_index);
+			}
+			dwc3_stop_active_transfer(dwc, dep->number);
+			list_for_each_entry_safe_reverse(req1, n,
+						 &dep->req_queued, list) {
+				req1->trb = NULL;
+				dwc3_gadget_move_request_list_front(req1);
+				if (req->request.num_mapped_sgs)
+					dep->busy_slot +=
+						 req->request.num_mapped_sgs;
+				else
+					dep->busy_slot++;
+				if ((dep->busy_slot & DWC3_TRB_MASK) ==
+							DWC3_TRB_NUM - 1)
+					dep->busy_slot++;
+			}
+			return ret;
+		} else {
+			/*
+			 * FIXME we need to iterate over the list of requests
+			 * here and stop, unmap, free and del each of the linked
+			 * requests instead of what we do now.
+			 */
+			usb_gadget_unmap_request(&dwc->gadget, &req->request,
 				req->direction);
-		list_del(&req->list);
-		return ret;
+			list_del(&req->list);
+			return ret;
+		}
 	}
 
 	dep->flags |= DWC3_EP_BUSY;
@@ -1017,6 +1066,9 @@
 		struct dwc3_ep *dep, u32 cur_uf)
 {
 	u32 uf;
+	int ret;
+
+	dep->current_uf = cur_uf;
 
 	if (list_empty(&dep->request_list)) {
 		dev_vdbg(dwc->dev, "ISOC ep %s run out for requests.\n",
@@ -1028,7 +1080,9 @@
 	/* 4 micro frames in the future */
 	uf = cur_uf + dep->interval * 4;
 
-	__dwc3_gadget_kick_transfer(dep, uf, 1);
+	ret = __dwc3_gadget_kick_transfer(dep, uf, 1);
+	if (ret < 0)
+		dbg_event(dep->number, "QUEUE", ret);
 }
 
 static void dwc3_gadget_start_isoc(struct dwc3 *dwc,
@@ -1047,6 +1101,13 @@
 	struct dwc3		*dwc = dep->dwc;
 	int			ret;
 
+	if (req->request.status == -EINPROGRESS) {
+		ret = -EBUSY;
+		dev_err(dwc->dev, "%s: %p request already in queue",
+					dep->name, req);
+		return ret;
+	}
+
 	req->request.actual	= 0;
 	req->request.status	= -EINPROGRESS;
 	req->direction		= dep->direction;
@@ -1092,14 +1153,26 @@
 		 * notion of current microframe.
 		 */
 		if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
-			dwc3_stop_active_transfer(dwc, dep->number);
+			/* If xfernotready event is recieved before issuing
+			 * START TRANSFER command, don't issue END TRANSFER.
+			 * Rather start queueing the requests by issuing START
+			 * TRANSFER command.
+			 */
+			if (list_empty(&dep->req_queued) && dep->resource_index)
+				dwc3_stop_active_transfer(dwc, dep->number);
+			else
+				__dwc3_gadget_start_isoc(dwc, dep,
+							dep->current_uf);
+			dep->flags &= ~DWC3_EP_PENDING_REQUEST;
 			return 0;
 		}
 
 		ret = __dwc3_gadget_kick_transfer(dep, 0, true);
-		if (ret && ret != -EBUSY)
+		if (ret && ret != -EBUSY) {
+			dbg_event(dep->number, "QUEUE", ret);
 			dev_dbg(dwc->dev, "%s: failed to kick transfers\n",
 					dep->name);
+		}
 	}
 
 	/*
@@ -1113,19 +1186,11 @@
 		WARN_ON_ONCE(!dep->resource_index);
 		ret = __dwc3_gadget_kick_transfer(dep, dep->resource_index,
 				false);
-		if (ret && ret != -EBUSY)
+		if (ret && ret != -EBUSY) {
+			dbg_event(dep->number, "QUEUE", ret);
 			dev_dbg(dwc->dev, "%s: failed to kick transfers\n",
 					dep->name);
-	}
-
-	/*
-	 * 3. Missed ISOC Handling. We need to start isoc transfer on the saved
-	 * uframe number.
-	 */
-	if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
-		(dep->flags & DWC3_EP_MISSED_ISOC)) {
-			__dwc3_gadget_start_isoc(dwc, dep, dep->current_uf);
-			dep->flags &= ~DWC3_EP_MISSED_ISOC;
+		}
 	}
 
 	return 0;
@@ -1142,7 +1207,10 @@
 
 	int				ret;
 
+	spin_lock_irqsave(&dwc->lock, flags);
+
 	if (!dep->endpoint.desc) {
+		spin_unlock_irqrestore(&dwc->lock, flags);
 		dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n",
 				request, ep->name);
 		return -ESHUTDOWN;
@@ -1154,7 +1222,6 @@
 	WARN(!dep->direction && (request->length % ep->desc->wMaxPacketSize),
 		"trying to queue unaligned request (%d)\n", request->length);
 
-	spin_lock_irqsave(&dwc->lock, flags);
 	ret = __dwc3_gadget_ep_queue(dep, req);
 	spin_unlock_irqrestore(&dwc->lock, flags);
 
@@ -1197,6 +1264,7 @@
 	}
 
 out1:
+	dbg_event(dep->number, "DEQUEUE", 0);
 	/* giveback the request */
 	dwc3_gadget_giveback(dep, req, -ECONNRESET);
 
@@ -1254,6 +1322,7 @@
 		goto out;
 	}
 
+	dbg_event(dep->number, "HALT", value);
 	ret = __dwc3_gadget_ep_set_halt(dep, value);
 out:
 	spin_unlock_irqrestore(&dwc->lock, flags);
@@ -1268,6 +1337,7 @@
 	unsigned long			flags;
 
 	spin_lock_irqsave(&dwc->lock, flags);
+	dbg_event(dep->number, "WEDGE", 0);
 	dep->flags |= DWC3_EP_WEDGE;
 	spin_unlock_irqrestore(&dwc->lock, flags);
 
@@ -1845,14 +1915,31 @@
 				if (trb_status == DWC3_TRBSTS_MISSED_ISOC) {
 					dev_dbg(dwc->dev, "incomplete IN transfer %s\n",
 							dep->name);
-					dep->current_uf = event->parameters &
-						~(dep->interval - 1);
+					/*
+					 * If missed isoc occurred and there is
+					 * no request queued then issue END
+					 * TRANSFER, so that core generates
+					 * next xfernotready and we will issue
+					 * a fresh START TRANSFER.
+					 * If there are still queued request
+					 * then wait, do not issue either END
+					 * or UPDATE TRANSFER, just attach next
+					 * request in request_list during
+					 * giveback.If any future queued request
+					 * is successfully transferred then we
+					 * will issue UPDATE TRANSFER for all
+					 * request in the request_list.
+					 */
 					dep->flags |= DWC3_EP_MISSED_ISOC;
+					dbg_event(dep->number, "MISSED ISOC",
+									status);
 				} else {
 					dev_err(dwc->dev, "incomplete IN transfer %s\n",
 							dep->name);
 					status = -ECONNRESET;
 				}
+			} else {
+				dep->flags &= ~DWC3_EP_MISSED_ISOC;
 			}
 		} else {
 			if (count && (event->status & DEPEVT_STATUS_SHORT))
@@ -1879,6 +1966,22 @@
 			break;
 	} while (1);
 
+	if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
+			list_empty(&dep->req_queued)) {
+		if (list_empty(&dep->request_list))
+			/*
+			 * If there is no entry in request list then do
+			 * not issue END TRANSFER now. Just set PENDING
+			 * flag, so that END TRANSFER is issued when an
+			 * entry is added into request list.
+			 */
+			dep->flags |= DWC3_EP_PENDING_REQUEST;
+		else
+			dwc3_stop_active_transfer(dwc, dep->number);
+		dep->flags &= ~DWC3_EP_MISSED_ISOC;
+		return 1;
+	}
+
 	if ((event->status & DEPEVT_STATUS_IOC) &&
 			(trb->ctrl & DWC3_TRB_CTRL_IOC))
 		return 0;
@@ -1980,6 +2083,8 @@
 			ret = __dwc3_gadget_kick_transfer(dep, 0, 1);
 			if (!ret || ret == -EBUSY)
 				return;
+			else
+				dbg_event(dep->number, "QUEUE", ret);
 
 			dev_dbg(dwc->dev, "%s: failed to kick transfers\n",
 					dep->name);
@@ -2116,6 +2221,7 @@
 	reg &= ~DWC3_DCTL_INITU2ENA;
 	dwc3_writel(dwc->regs, DWC3_DCTL, reg);
 
+	dbg_event(0xFF, "DISCONNECT", 0);
 	dwc3_disconnect_gadget(dwc);
 	dwc->start_config_issued = false;
 
@@ -2189,6 +2295,7 @@
 			dwc3_gadget_disconnect_interrupt(dwc);
 	}
 
+	dbg_event(0xFF, "BUS RST", 0);
 	/* after reset -> Default State */
 	dwc->dev_state = DWC3_DEFAULT_STATE;
 
@@ -2355,6 +2462,7 @@
 	 * implemented.
 	 */
 
+	dbg_event(0xFF, "WAKEUP", 0);
 	dwc->gadget_driver->resume(&dwc->gadget);
 }
 
@@ -2410,9 +2518,12 @@
 	}
 
 	if (next == DWC3_LINK_STATE_U0) {
-		if (dwc->link_state == DWC3_LINK_STATE_U3)
+		if (dwc->link_state == DWC3_LINK_STATE_U3) {
+			dbg_event(0xFF, "RESUME", 0);
 			dwc->gadget_driver->resume(&dwc->gadget);
+		}
 	} else if (next == DWC3_LINK_STATE_U3) {
+		dbg_event(0xFF, "SUSPEND", 0);
 		dwc->gadget_driver->suspend(&dwc->gadget);
 	}
 
@@ -2447,12 +2558,14 @@
 		dev_vdbg(dwc->dev, "Start of Periodic Frame\n");
 		break;
 	case DWC3_DEVICE_EVENT_ERRATIC_ERROR:
+		dbg_event(0xFF, "ERROR", 0);
 		dev_vdbg(dwc->dev, "Erratic Error\n");
 		break;
 	case DWC3_DEVICE_EVENT_CMD_CMPL:
 		dev_vdbg(dwc->dev, "Command Complete\n");
 		break;
 	case DWC3_DEVICE_EVENT_OVERFLOW:
+		dbg_event(0xFF, "OVERFL", 0);
 		dev_vdbg(dwc->dev, "Overflow\n");
 		/*
 		 * Controllers prior to 2.30a revision has a bug where
@@ -2479,6 +2592,7 @@
 		 * Add a warning message to indicate that this event is received
 		 * which means that event buffer might have corrupted.
 		 */
+		dbg_event(0xFF, "TSTLMP", 0);
 		if (dwc->revision < DWC3_REVISION_230A)
 			dev_warn(dwc->dev, "Vendor Device Test LMP Received\n");
 		break;
diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h
index dc7a3c1..cd5492f 100644
--- a/drivers/usb/dwc3/gadget.h
+++ b/drivers/usb/dwc3/gadget.h
@@ -94,6 +94,14 @@
 	return list_first_entry(list, struct dwc3_request, list);
 }
 
+static inline void dwc3_gadget_move_request_list_front(struct dwc3_request *req)
+{
+	struct dwc3_ep		*dep = req->dep;
+
+	req->queued = false;
+	list_move(&req->list, &dep->request_list);
+}
+
 static inline void dwc3_gadget_move_request_queued(struct dwc3_request *req)
 {
 	struct dwc3_ep		*dep = req->dep;
diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
index 644a779..d6d8a76 100644
--- a/drivers/usb/dwc3/host.c
+++ b/drivers/usb/dwc3/host.c
@@ -55,7 +55,6 @@
 
 	dma_set_coherent_mask(&xhci->dev, dwc->dev->coherent_dma_mask);
 
-	xhci->dev.parent	= dwc->dev;
 	xhci->dev.dma_mask	= dwc->dev->dma_mask;
 	xhci->dev.dma_parms	= dwc->dev->dma_parms;
 
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index fe59036..9dd9c40 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -53,13 +53,16 @@
 #include "f_rmnet_sdio.c"
 #include "f_rmnet_smd_sdio.c"
 #include "f_rmnet.c"
+#ifdef CONFIG_SND_PCM
 #include "f_audio_source.c"
+#endif
 #include "f_mass_storage.c"
 #include "u_serial.c"
 #include "u_sdio.c"
 #include "u_smd.c"
 #include "u_bam.c"
 #include "u_rmnet_ctrl_smd.c"
+#include "u_rmnet_ctrl_qti.c"
 #include "u_ctrl_hsic.c"
 #include "u_data_hsic.c"
 #include "u_ctrl_hsuart.c"
@@ -73,10 +76,10 @@
 #define USB_ETH_RNDIS y
 #include "f_rndis.c"
 #include "rndis.c"
+#include "f_qc_ecm.c"
 #include "u_bam_data.c"
 #include "f_mbim.c"
 #include "f_ecm.c"
-#include "f_qc_ecm.c"
 #include "f_qc_rndis.c"
 #include "u_ether.c"
 #include "u_qc_ether.c"
@@ -141,6 +144,46 @@
 	struct list_head enabled_list;
 };
 
+/**
+* struct android_dev - represents android USB gadget device
+* @name: device name.
+* @functions: an array of all the supported USB function
+*    drivers that this gadget support but not necessarily
+*    added to one of the gadget configurations.
+* @cdev: The internal composite device. Android gadget device
+*    is a composite device, such that it can support configurations
+*    with more than one function driver.
+* @dev: The kernel device that represents this android device.
+* @enabled: True if the android gadget is enabled, means all
+*    the configurations were set and all function drivers were
+*    bind and ready for USB enumeration.
+* @disable_depth: Number of times the device was disabled, after
+*    symmetrical number of enables the device willl be enabled.
+*    Used for controlling ADB userspace disable/enable requests.
+* @mutex: Internal mutex for protecting device member fields.
+* @pdata: Platform data fetched from the kernel device platfrom data.
+* @connected: True if got connect notification from the gadget UDC.
+*    False if got disconnect notification from the gadget UDC.
+* @sw_connected: Equal to 'connected' only after the connect
+*    notification was handled by the android gadget work function.
+* @suspended: True if got suspend notification from the gadget UDC.
+*    False if got resume notification from the gadget UDC.
+* @sw_suspended: Equal to 'suspended' only after the susped
+*    notification was handled by the android gadget work function.
+* @pm_qos: An attribute string that can be set by user space in order to
+*    determine pm_qos policy. Set to 'high' for always demand pm_qos
+*    when USB bus is connected and resumed. Set to 'low' for disable
+*    any setting of pm_qos by this driver. Default = 'high'.
+* @work: workqueue used for handling notifications from the gadget UDC.
+* @configs: List of configurations currently configured into the device.
+*    The android gadget supports more than one configuration. The host
+*    may choose one configuration from the suggested.
+* @configs_num: Number of configurations currently configured and existing
+*    in the configs list.
+* @list_item: This driver supports more than one android gadget device (for
+*    example in order to support multiple USB cores), therefore this is
+*    a item in a linked list of android devices.
+*/
 struct android_dev {
 	const char *name;
 	struct android_usb_function **functions;
@@ -154,6 +197,8 @@
 
 	bool connected;
 	bool sw_connected;
+	bool suspended;
+	bool sw_suspended;
 	char pm_qos[5];
 	struct pm_qos_request pm_qos_req_dma;
 	struct work_struct work;
@@ -164,7 +209,6 @@
 
 	/* A list node inside the android_dev_list */
 	struct list_head list_item;
-
 };
 
 struct android_configuration {
@@ -244,6 +288,8 @@
 	USB_DISCONNECTED,
 	USB_CONNECTED,
 	USB_CONFIGURED,
+	USB_SUSPENDED,
+	USB_RESUMED
 };
 
 static void android_pm_qos_update_latency(struct android_dev *dev, int vote)
@@ -273,13 +319,20 @@
 	char *disconnected[2] = { "USB_STATE=DISCONNECTED", NULL };
 	char *connected[2]    = { "USB_STATE=CONNECTED", NULL };
 	char *configured[2]   = { "USB_STATE=CONFIGURED", NULL };
+	char *suspended[2]   = { "USB_STATE=SUSPENDED", NULL };
+	char *resumed[2]   = { "USB_STATE=RESUMED", NULL };
 	char **uevent_envp = NULL;
 	static enum android_device_state last_uevent, next_state;
 	unsigned long flags;
 	int pm_qos_vote = -1;
 
 	spin_lock_irqsave(&cdev->lock, flags);
-	if (cdev->config) {
+	if (dev->suspended != dev->sw_suspended && cdev->config) {
+		if (strncmp(dev->pm_qos, "low", 3))
+			pm_qos_vote = dev->suspended ? 0 : 1;
+		next_state = dev->suspended ? USB_SUSPENDED : USB_RESUMED;
+		uevent_envp = dev->suspended ? suspended : resumed;
+	} else if (cdev->config) {
 		uevent_envp = configured;
 		next_state = USB_CONFIGURED;
 	} else if (dev->connected != dev->sw_connected) {
@@ -291,6 +344,7 @@
 			pm_qos_vote = 0;
 	}
 	dev->sw_connected = dev->connected;
+	dev->sw_suspended = dev->suspended;
 	spin_unlock_irqrestore(&cdev->lock, flags);
 
 	if (pm_qos_vote != -1)
@@ -319,8 +373,12 @@
 		if (uevent_envp == configured)
 			msleep(50);
 
-		kobject_uevent_env(&dev->dev->kobj, KOBJ_CHANGE, uevent_envp);
-		last_uevent = next_state;
+		/* Do not notify on suspend / resume */
+		if (next_state != USB_SUSPENDED && next_state != USB_RESUMED) {
+			kobject_uevent_env(&dev->dev->kobj, KOBJ_CHANGE,
+					   uevent_envp);
+			last_uevent = next_state;
+		}
 		pr_info("%s: sent uevent %s\n", __func__, uevent_envp[0]);
 	} else {
 		pr_info("%s: did not send uevent (%d %d %p)\n", __func__,
@@ -597,6 +655,9 @@
 	.attributes	= rmnet_function_attributes,
 };
 
+/* ecm transport string */
+static char ecm_transports[MAX_XPORT_STR_LEN];
+
 struct ecm_function_config {
 	u8      ethaddr[ETH_ALEN];
 };
@@ -620,6 +681,7 @@
 					struct usb_configuration *c)
 {
 	int ret;
+	char *trans;
 	struct ecm_function_config *ecm = f->config;
 
 	if (!ecm) {
@@ -631,19 +693,28 @@
 		ecm->ethaddr[0], ecm->ethaddr[1], ecm->ethaddr[2],
 		ecm->ethaddr[3], ecm->ethaddr[4], ecm->ethaddr[5]);
 
-	ret = gether_qc_setup_name(c->cdev->gadget, ecm->ethaddr, "ecm");
-	if (ret) {
-		pr_err("%s: gether_setup failed\n", __func__);
-		return ret;
+	pr_debug("%s: ecm_transport is %s", __func__, ecm_transports);
+
+	trans = strim(ecm_transports);
+	if (strcmp("BAM2BAM_IPA", trans)) {
+		ret = gether_qc_setup_name(c->cdev->gadget,
+						ecm->ethaddr, "ecm");
+		if (ret) {
+			pr_err("%s: gether_setup failed\n", __func__);
+			return ret;
+		}
 	}
 
-	return ecm_qc_bind_config(c, ecm->ethaddr);
+	return ecm_qc_bind_config(c, ecm->ethaddr, trans);
 }
 
 static void ecm_qc_function_unbind_config(struct android_usb_function *f,
 						struct usb_configuration *c)
 {
-	gether_qc_cleanup_name("ecm0");
+	char *trans = strim(ecm_transports);
+
+	if (strcmp("BAM2BAM_IPA", trans))
+		gether_qc_cleanup_name("ecm0");
 }
 
 static ssize_t ecm_ethaddr_show(struct device *dev,
@@ -673,7 +744,24 @@
 static DEVICE_ATTR(ecm_ethaddr, S_IRUGO | S_IWUSR, ecm_ethaddr_show,
 					       ecm_ethaddr_store);
 
+static ssize_t ecm_transports_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%s\n", ecm_transports);
+}
+
+static ssize_t ecm_transports_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	strlcpy(ecm_transports, buf, sizeof(ecm_transports));
+	return size;
+}
+
+static DEVICE_ATTR(ecm_transports, S_IRUGO | S_IWUSR, ecm_transports_show,
+					       ecm_transports_store);
+
 static struct device_attribute *ecm_function_attributes[] = {
+	&dev_attr_ecm_transports,
 	&dev_attr_ecm_ethaddr,
 	NULL
 };
@@ -1535,6 +1623,7 @@
 	.ctrlrequest	= accessory_function_ctrlrequest,
 };
 
+#ifdef CONFIG_SND_PCM
 static int audio_source_function_init(struct android_usb_function *f,
 			struct usb_composite_dev *cdev)
 {
@@ -1596,6 +1685,7 @@
 	.unbind_config	= audio_source_function_unbind_config,
 	.attributes	= audio_source_function_attributes,
 };
+#endif
 
 static int android_uasp_connect_cb(bool connect)
 {
@@ -1666,7 +1756,9 @@
 	&ecm_function,
 	&mass_storage_function,
 	&accessory_function,
+#ifdef CONFIG_SND_PCM
 	&audio_source_function,
+#endif
 	&uasp_function,
 	NULL
 };
@@ -1988,6 +2080,8 @@
 	struct android_usb_function_holder *f_holder;
 	struct android_configuration *conf;
 	int enabled = 0;
+	bool audio_enabled = false;
+	static DEFINE_RATELIMIT_STATE(rl, 10*HZ, 1);
 
 	if (!cdev)
 		return -ENODEV;
@@ -2006,12 +2100,22 @@
 		cdev->desc.bDeviceClass = device_desc.bDeviceClass;
 		cdev->desc.bDeviceSubClass = device_desc.bDeviceSubClass;
 		cdev->desc.bDeviceProtocol = device_desc.bDeviceProtocol;
+
+		/* Audio dock accessory is unable to enumerate device if
+		 * pull-up is enabled immediately. The enumeration is
+		 * reliable with 100 msec delay.
+		 */
 		list_for_each_entry(conf, &dev->configs, list_item)
 			list_for_each_entry(f_holder, &conf->enabled_functions,
 						enabled_list) {
 				if (f_holder->f->enable)
 					f_holder->f->enable(f_holder->f);
+				if (!strncmp(f_holder->f->name,
+						"audio_source", 12))
+					audio_enabled = true;
 			}
+		if (audio_enabled)
+			msleep(100);
 		android_enable(dev);
 		dev->enabled = true;
 	} else if (!enabled && dev->enabled) {
@@ -2023,7 +2127,7 @@
 					f_holder->f->disable(f_holder->f);
 			}
 		dev->enabled = false;
-	} else {
+	} else if (__ratelimit(&rl)) {
 		pr_err("android_usb: already %s\n",
 				dev->enabled ? "enabled" : "disabled");
 	}
@@ -2331,6 +2435,35 @@
 	spin_unlock_irqrestore(&cdev->lock, flags);
 }
 
+static void android_suspend(struct usb_gadget *gadget)
+{
+	struct usb_composite_dev *cdev = get_gadget_data(gadget);
+	struct android_dev *dev = cdev_to_android_dev(cdev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&cdev->lock, flags);
+	dev->suspended = 1;
+	schedule_work(&dev->work);
+	spin_unlock_irqrestore(&cdev->lock, flags);
+
+	composite_suspend(gadget);
+}
+
+static void android_resume(struct usb_gadget *gadget)
+{
+	struct usb_composite_dev *cdev = get_gadget_data(gadget);
+	struct android_dev *dev = cdev_to_android_dev(cdev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&cdev->lock, flags);
+	dev->suspended = 0;
+	schedule_work(&dev->work);
+	spin_unlock_irqrestore(&cdev->lock, flags);
+
+	composite_resume(gadget);
+}
+
+
 static int android_create_device(struct android_dev *dev, u8 usb_core_id)
 {
 	struct device_attribute **attrs = android_usb_attributes;
@@ -2622,6 +2755,8 @@
 	/* Override composite driver functions */
 	composite_driver.setup = android_setup;
 	composite_driver.disconnect = android_disconnect;
+	composite_driver.suspend = android_suspend;
+	composite_driver.resume = android_resume;
 
 	INIT_LIST_HEAD(&android_dev_list);
 	android_dev_count = 0;
diff --git a/drivers/usb/gadget/ci13xxx_msm.c b/drivers/usb/gadget/ci13xxx_msm.c
index e3c1216..a4742a5 100644
--- a/drivers/usb/gadget/ci13xxx_msm.c
+++ b/drivers/usb/gadget/ci13xxx_msm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -233,6 +233,19 @@
 	return 0;
 }
 
+void msm_hw_bam_disable(bool bam_disable)
+{
+	u32 val;
+	struct ci13xxx *udc = _udc;
+
+	if (bam_disable)
+		val = readl_relaxed(USB_GENCONFIG) | GENCONFIG_BAM_DISABLE;
+	else
+		val = readl_relaxed(USB_GENCONFIG) & ~GENCONFIG_BAM_DISABLE;
+
+	writel_relaxed(val, USB_GENCONFIG);
+}
+
 static struct platform_driver ci13xxx_msm_driver = {
 	.probe = ci13xxx_msm_probe,
 	.driver = { .name = "msm_hsusb", },
diff --git a/drivers/usb/gadget/ci13xxx_msm_hsic.c b/drivers/usb/gadget/ci13xxx_msm_hsic.c
index b0b9468..0ed08be 100644
--- a/drivers/usb/gadget/ci13xxx_msm_hsic.c
+++ b/drivers/usb/gadget/ci13xxx_msm_hsic.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 9c7b1ec..4254c3a 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -69,6 +69,9 @@
 
 #include "ci13xxx_udc.h"
 
+/* Turns on streaming. overrides CI13XXX_DISABLE_STREAMING */
+static unsigned int streaming;
+module_param(streaming, uint, S_IRUGO | S_IWUSR);
 
 /******************************************************************************
  * DEFINE
@@ -332,9 +335,6 @@
 		udc->udc_driver->notify_event(udc,
 			CI13XXX_CONTROLLER_RESET_EVENT);
 
-	if (udc->udc_driver->flags & CI13XXX_DISABLE_STREAMING)
-		hw_cwrite(CAP_USBMODE, USBMODE_SDIS, USBMODE_SDIS);
-
 	/* USBMODE should be configured step by step */
 	hw_cwrite(CAP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE);
 	hw_cwrite(CAP_USBMODE, USBMODE_CM, USBMODE_CM_DEVICE);
@@ -369,7 +369,15 @@
  */
 static int hw_device_state(u32 dma)
 {
+	struct ci13xxx *udc = _udc;
+
 	if (dma) {
+		if (streaming || !(udc->udc_driver->flags &
+				CI13XXX_DISABLE_STREAMING))
+			hw_cwrite(CAP_USBMODE, USBMODE_SDIS, 0);
+		else
+			hw_cwrite(CAP_USBMODE, USBMODE_SDIS, USBMODE_SDIS);
+
 		hw_cwrite(CAP_ENDPTLISTADDR, ~0, dma);
 		/* interrupt, error, port change, reset, sleep/suspend */
 		hw_cwrite(CAP_USBINTR, ~0,
@@ -414,6 +422,10 @@
 {
 	ktime_t start, diff;
 	int n = hw_ep_bit(num, dir);
+	struct ci13xxx_ep *mEp = &_udc->ci13xxx_ep[n];
+
+	if (_udc->skip_flush || list_empty(&mEp->qh.queue))
+		return 0;
 
 	start = ktime_get();
 	do {
@@ -428,6 +440,7 @@
 					__func__, num,
 					dir ? "IN" : "OUT");
 				debug_ept_flush_info(num, dir);
+				_udc->skip_flush = true;
 				return 0;
 			}
 		}
@@ -445,7 +458,6 @@
  */
 static int hw_ep_disable(int num, int dir)
 {
-	hw_ep_flush(num, dir);
 	hw_cwrite(CAP_ENDPTCTRL + num * sizeof(u32),
 		  dir ? ENDPTCTRL_TXE : ENDPTCTRL_RXE, 0);
 	return 0;
@@ -1873,8 +1885,8 @@
 
 	mReq->ptr->page[0]  = mReq->req.dma;
 	for (i = 1; i < 5; i++)
-		mReq->ptr->page[i] =
-			(mReq->req.dma + i * CI13XXX_PAGE_SIZE) & ~TD_RESERVED_MASK;
+		mReq->ptr->page[i] = (mReq->req.dma + i * CI13XXX_PAGE_SIZE) &
+							~TD_RESERVED_MASK;
 
 	/* Remote Wakeup */
 	if (udc->suspended) {
@@ -2041,6 +2053,25 @@
 }
 
 /**
+ * restore_original_req: Restore original req's attributes
+ * @mReq: Request
+ *
+ * This function restores original req's attributes.  Call
+ * this function before completing the large req (>16K).
+ */
+static void restore_original_req(struct ci13xxx_req *mReq)
+{
+	mReq->req.buf = mReq->multi.buf;
+	mReq->req.length = mReq->multi.len;
+	if (!mReq->req.status)
+		mReq->req.actual = mReq->multi.actual;
+
+	mReq->multi.len = 0;
+	mReq->multi.actual = 0;
+	mReq->multi.buf = NULL;
+}
+
+/**
  * _ep_nuke: dequeues all endpoint requests
  * @mEp: endpoint
  *
@@ -2093,6 +2124,11 @@
 			mReq->map     = 0;
 		}
 
+		if (mEp->multi_req) {
+			restore_original_req(mReq);
+			mEp->multi_req = false;
+		}
+
 		if (mReq->req.complete != NULL) {
 			spin_unlock(mEp->lock);
 			if ((mEp->type == USB_ENDPOINT_XFER_CONTROL) &&
@@ -2115,7 +2151,6 @@
  */
 static int _gadget_stop_activity(struct usb_gadget *gadget)
 {
-	struct usb_ep *ep;
 	struct ci13xxx    *udc = container_of(gadget, struct ci13xxx, gadget);
 	unsigned long flags;
 
@@ -2136,20 +2171,10 @@
 	gadget->host_request = 0;
 	gadget->otg_srp_reqd = 0;
 
-	/* flush all endpoints */
-	gadget_for_each_ep(ep, gadget) {
-		usb_ep_fifo_flush(ep);
-	}
+	udc->driver->disconnect(gadget);
 	usb_ep_fifo_flush(&udc->ep0out.ep);
 	usb_ep_fifo_flush(&udc->ep0in.ep);
 
-	udc->driver->disconnect(gadget);
-
-	/* make sure to disable all endpoints */
-	gadget_for_each_ep(ep, gadget) {
-		usb_ep_disable(ep);
-	}
-
 	if (udc->status != NULL) {
 		usb_ep_free_request(&udc->ep0in.ep, udc->status);
 		udc->status = NULL;
@@ -2202,6 +2227,7 @@
 	if (retval)
 		goto done;
 
+	_udc->skip_flush = false;
 	retval = hw_usb_reset();
 	if (retval)
 		goto done;
@@ -2452,8 +2478,44 @@
 			break;
 		}
 		req_dequeue = 0;
+
+		if (mEp->multi_req) { /* Large request in progress */
+			unsigned remain_len;
+
+			mReq->multi.actual += mReq->req.actual;
+			remain_len = mReq->multi.len - mReq->multi.actual;
+			if (mReq->req.status || !remain_len ||
+				(mReq->req.actual != mReq->req.length)) {
+				restore_original_req(mReq);
+				mEp->multi_req = false;
+			} else {
+				mReq->req.buf = mReq->multi.buf +
+						mReq->multi.actual;
+				mReq->req.length = min_t(unsigned, remain_len,
+						(4 * CI13XXX_PAGE_SIZE));
+
+				mReq->req.status = -EINPROGRESS;
+				mReq->req.actual = 0;
+				list_del_init(&mReq->queue);
+				retval = _hardware_enqueue(mEp, mReq);
+				if (retval) {
+					err("Large req failed in middle");
+					mReq->req.status = retval;
+					restore_original_req(mReq);
+					mEp->multi_req = false;
+					goto done;
+				} else {
+					list_add_tail(&mReq->queue,
+						&mEp->qh.queue);
+					return 0;
+				}
+			}
+		}
 		list_del_init(&mReq->queue);
+done:
+
 		dbg_done(_usb_addr(mEp), mReq->ptr->token, retval);
+
 		if (mReq->req.complete != NULL) {
 			spin_unlock(mEp->lock);
 			if ((mEp->type == USB_ENDPOINT_XFER_CONTROL) &&
@@ -2889,6 +2951,9 @@
 	if (ep == NULL || req == NULL || mEp->desc == NULL)
 		return -EINVAL;
 
+	if (!udc->softconnect)
+		return -ENODEV;
+
 	spin_lock_irqsave(mEp->lock, flags);
 
 	if (!udc->configured && mEp->type !=
@@ -2917,11 +2982,28 @@
 		err("request already in queue");
 		goto done;
 	}
+	if (mEp->multi_req) {
+		retval = -EAGAIN;
+		err("Large request is in progress. come again");
+		goto done;
+	}
 
 	if (req->length > (4 * CI13XXX_PAGE_SIZE)) {
+		if (!list_empty(&mEp->qh.queue)) {
+			retval = -EAGAIN;
+			err("Queue is busy. Large req is not allowed");
+			goto done;
+		}
+		if ((mEp->type != USB_ENDPOINT_XFER_BULK) ||
+				(mEp->dir != RX)) {
+			retval = -EINVAL;
+			err("Larger req is supported only for Bulk OUT");
+			goto done;
+		}
+		mEp->multi_req = true;
+		mReq->multi.len = req->length;
+		mReq->multi.buf = req->buf;
 		req->length = (4 * CI13XXX_PAGE_SIZE);
-		retval = -EMSGSIZE;
-		warn("request length truncated");
 	}
 
 	dbg_queue(_usb_addr(mEp), req, retval);
@@ -2938,6 +3020,8 @@
 	}
 	if (!retval)
 		list_add_tail(&mReq->queue, &mEp->qh.queue);
+	else if (mEp->multi_req)
+		mEp->multi_req = false;
 
  done:
 	spin_unlock_irqrestore(mEp->lock, flags);
@@ -2983,6 +3067,10 @@
 		mReq->map     = 0;
 	}
 	req->status = -ECONNRESET;
+	if (mEp->multi_req) {
+		restore_original_req(mReq);
+		mEp->multi_req = false;
+	}
 
 	if (mReq->req.complete != NULL) {
 		spin_unlock(mEp->lock);
@@ -3513,8 +3601,7 @@
 		void __iomem *regs)
 {
 	struct ci13xxx *udc;
-	struct ci13xxx_platform_data *pdata =
-		(struct ci13xxx_platform_data *)(dev->platform_data);
+	struct ci13xxx_platform_data *pdata;
 	int retval = 0, i;
 
 	trace("%p, %p, %p", dev, regs, driver->name);
@@ -3543,6 +3630,7 @@
 	INIT_LIST_HEAD(&udc->gadget.ep_list);
 	udc->gadget.ep0 = NULL;
 
+	pdata = dev->platform_data;
 	if (pdata)
 		udc->gadget.usb_core_id = pdata->usb_core_id;
 
diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h
index 6b3cad8..76028b2 100644
--- a/drivers/usb/gadget/ci13xxx_udc.h
+++ b/drivers/usb/gadget/ci13xxx_udc.h
@@ -77,6 +77,13 @@
 	struct usb_ctrlrequest   setup;
 } __attribute__ ((packed));
 
+/* cache of larger request's original attributes */
+struct ci13xxx_multi_req {
+	unsigned             len;
+	unsigned             actual;
+	void                *buf;
+};
+
 /* Extension of usb_request */
 struct ci13xxx_req {
 	struct usb_request   req;
@@ -86,6 +93,7 @@
 	dma_addr_t           dma;
 	struct ci13xxx_td   *zptr;
 	dma_addr_t           zdma;
+	struct ci13xxx_multi_req multi;
 };
 
 /* Extension of usb_ep */
@@ -111,6 +119,8 @@
 	unsigned long			      prime_fail_count;
 	int				      prime_timer_count;
 	struct timer_list		      prime_timer;
+
+	bool                                  multi_req;
 };
 
 struct ci13xxx;
@@ -162,6 +172,9 @@
 	int                        softconnect; /* is pull-up enable allowed */
 	unsigned long dTD_update_fail_count;
 	struct usb_phy            *transceiver; /* Transceiver struct */
+	bool                      skip_flush; /* skip flushing remaining EP
+						upon flush timeout for the
+						first EP. */
 };
 
 struct ci13xxx_platform_data {
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c
index cc151cb..0752188 100644
--- a/drivers/usb/gadget/f_acm.c
+++ b/drivers/usb/gadget/f_acm.c
@@ -5,7 +5,7 @@
  * Copyright (C) 2008 by David Brownell
  * Copyright (C) 2008 by Nokia Corporation
  * Copyright (C) 2009 by Samsung Electronics
- * Copyright (c) 2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011 The Linux Foundation. All rights reserved.
  * Author: Michal Nazarewicz (mina86@mina86.com)
  *
  * This software is distributed under the terms of the GNU General
diff --git a/drivers/usb/gadget/f_adb.c b/drivers/usb/gadget/f_adb.c
index 68c99a3..ff2287e 100644
--- a/drivers/usb/gadget/f_adb.c
+++ b/drivers/usb/gadget/f_adb.c
@@ -359,7 +359,8 @@
 	}
 
 	/* wait for a request to complete */
-	ret = wait_event_interruptible(dev->read_wq, dev->rx_done);
+	ret = wait_event_interruptible(dev->read_wq, dev->rx_done ||
+				atomic_read(&dev->error));
 	if (ret < 0) {
 		if (ret != -ERESTARTSYS)
 		atomic_set(&dev->error, 1);
@@ -381,6 +382,9 @@
 		r = -EIO;
 
 done:
+	if (atomic_read(&dev->error))
+		wake_up(&dev->write_wq);
+
 	adb_unlock(&dev->read_excl);
 	pr_debug("adb_read returning %d\n", r);
 	return r;
@@ -449,6 +453,9 @@
 	if (req)
 		adb_req_put(dev, &dev->tx_idle, req);
 
+	if (atomic_read(&dev->error))
+		wake_up(&dev->read_wq);
+
 	adb_unlock(&dev->write_excl);
 	pr_debug("adb_write returning %d\n", r);
 	return r;
@@ -456,7 +463,10 @@
 
 static int adb_open(struct inode *ip, struct file *fp)
 {
-	pr_info("adb_open\n");
+	static DEFINE_RATELIMIT_STATE(rl, 10*HZ, 1);
+
+	if (__ratelimit(&rl))
+		pr_info("adb_open\n");
 	if (!_adb_dev)
 		return -ENODEV;
 
@@ -479,7 +489,10 @@
 
 static int adb_release(struct inode *ip, struct file *fp)
 {
-	pr_info("adb_release\n");
+	static DEFINE_RATELIMIT_STATE(rl, 10*HZ, 1);
+
+	if (__ratelimit(&rl))
+		pr_info("adb_release\n");
 
 	/*
 	 * ADB daemon closes the device file after I/O error.  The
diff --git a/drivers/usb/gadget/f_audio_source.c b/drivers/usb/gadget/f_audio_source.c
index aae941e..f0d5c52 100644
--- a/drivers/usb/gadget/f_audio_source.c
+++ b/drivers/usb/gadget/f_audio_source.c
@@ -256,6 +256,8 @@
 	ktime_t				start_time;
 	/* number of frames sent since start_time */
 	s64				frames_sent;
+
+	bool				audio_ep_enabled;
 };
 
 static inline struct audio_dev *func_to_audio_source(struct usb_function *f)
@@ -525,18 +527,26 @@
 
 	pr_debug("audio_set_alt intf %d, alt %d\n", intf, alt);
 
-	ret = config_ep_by_speed(cdev->gadget, f, audio->in_ep);
-	if (ret) {
-		audio->in_ep->desc = NULL;
-		ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
-				audio->in_ep->name, ret);
-			return ret;
-	}
-	ret = usb_ep_enable(audio->in_ep);
-	if (ret) {
-		ERROR(cdev, "failed to enable ep %s, result %d\n",
-			audio->in_ep->name, ret);
-		return ret;
+	if (intf == as_interface_alt_1_desc.bInterfaceNumber) {
+		if (alt && !audio->audio_ep_enabled) {
+			ret = config_ep_by_speed(cdev->gadget, f, audio->in_ep);
+			if (ret) {
+				audio->in_ep->desc = NULL;
+				ERROR(cdev, "config_ep fail ep %s, result %d\n",
+						audio->in_ep->name, ret);
+				return ret;
+			}
+			ret = usb_ep_enable(audio->in_ep);
+			if (ret) {
+				ERROR(cdev, "failedto enable ep%s, result %d\n",
+					audio->in_ep->name, ret);
+				return ret;
+			}
+			audio->audio_ep_enabled = true;
+		} else if (!alt && audio->audio_ep_enabled) {
+			usb_ep_disable(audio->in_ep);
+			audio->audio_ep_enabled = false;
+		}
 	}
 	return 0;
 }
@@ -546,7 +556,10 @@
 	struct audio_dev *audio = func_to_audio_source(f);
 
 	pr_debug("audio_disable\n");
-	usb_ep_disable(audio->in_ep);
+	if (audio->audio_ep_enabled) {
+		usb_ep_disable(audio->in_ep);
+		audio->audio_ep_enabled = false;
+	}
 }
 
 /*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/gadget/f_ccid.c b/drivers/usb/gadget/f_ccid.c
index c8f144a..4e28d34 100644
--- a/drivers/usb/gadget/f_ccid.c
+++ b/drivers/usb/gadget/f_ccid.c
@@ -1,7 +1,7 @@
 /*
  * f_ccid.c -- CCID function Driver
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/drivers/usb/gadget/f_ccid.h b/drivers/usb/gadget/f_ccid.h
index 4d6a0ea..d899044 100644
--- a/drivers/usb/gadget/f_ccid.h
+++ b/drivers/usb/gadget/f_ccid.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/drivers/usb/gadget/f_diag.c b/drivers/usb/gadget/f_diag.c
index aca2af3..3b1843b 100644
--- a/drivers/usb/gadget/f_diag.c
+++ b/drivers/usb/gadget/f_diag.c
@@ -2,7 +2,7 @@
  * Diag Function Device - Route ARM9 and ARM11 DIAG messages
  * between HOST and DEVICE.
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2013, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -158,14 +158,19 @@
 	unsigned configured;
 	struct usb_composite_dev *cdev;
 	int (*update_pid_and_serial_num)(uint32_t, const char *);
-	struct usb_diag_ch ch;
+	struct usb_diag_ch *ch;
 
 	/* pkt counters */
 	unsigned long dpkts_tolaptop;
 	unsigned long dpkts_tomodem;
 	unsigned dpkts_tolaptop_pending;
+
+	/* A list node inside the diag_dev_list */
+	struct list_head list_item;
 };
 
+static struct list_head diag_dev_list;
+
 static inline struct diag_context *func_to_diag(struct usb_function *f)
 {
 	return container_of(f, struct diag_context, function);
@@ -179,8 +184,11 @@
 	struct usb_gadget_strings *table;
 	struct usb_string *s;
 
-	if (ctxt->ch.notify)
-		ctxt->ch.notify(ctxt->ch.priv, USB_DIAG_CONNECT, NULL);
+	if (!ctxt->ch)
+		return;
+
+	if (ctxt->ch->notify)
+		ctxt->ch->notify(ctxt->ch->priv, USB_DIAG_CONNECT, NULL);
 
 	if (!ctxt->update_pid_and_serial_num)
 		return;
@@ -236,8 +244,8 @@
 	}
 	spin_unlock_irqrestore(&ctxt->lock, flags);
 
-	if (ctxt->ch.notify)
-		ctxt->ch.notify(ctxt->ch.priv, USB_DIAG_WRITE_DONE, d_req);
+	if (ctxt->ch && ctxt->ch->notify)
+		ctxt->ch->notify(ctxt->ch->priv, USB_DIAG_WRITE_DONE, d_req);
 }
 
 static void diag_read_complete(struct usb_ep *ep,
@@ -256,8 +264,8 @@
 
 	ctxt->dpkts_tomodem++;
 
-	if (ctxt->ch.notify)
-		ctxt->ch.notify(ctxt->ch.priv, USB_DIAG_READ_DONE, d_req);
+	if (ctxt->ch && ctxt->ch->notify)
+		ctxt->ch->notify(ctxt->ch->priv, USB_DIAG_READ_DONE, d_req);
 }
 
 /**
@@ -275,7 +283,6 @@
 		void (*notify)(void *, unsigned, struct diag_request *))
 {
 	struct usb_diag_ch *ch;
-	struct diag_context *ctxt;
 	unsigned long flags;
 	int found = 0;
 
@@ -290,11 +297,9 @@
 	spin_unlock_irqrestore(&ch_lock, flags);
 
 	if (!found) {
-		ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL);
-		if (!ctxt)
+		ch = kzalloc(sizeof(*ch), GFP_KERNEL);
+		if (!ch)
 			return ERR_PTR(-ENOMEM);
-
-		ch = &ctxt->ch;
 	}
 
 	ch->name = name;
@@ -318,38 +323,27 @@
  */
 void usb_diag_close(struct usb_diag_ch *ch)
 {
-	struct diag_context *dev = container_of(ch, struct diag_context, ch);
+	struct diag_context *dev = NULL;
 	unsigned long flags;
 
 	spin_lock_irqsave(&ch_lock, flags);
 	ch->priv = NULL;
 	ch->notify = NULL;
 	/* Free-up the resources if channel is no more active */
-	if (!ch->priv_usb) {
-		list_del(&ch->list);
-		kfree(dev);
-	}
+	list_del(&ch->list);
+	list_for_each_entry(dev, &diag_dev_list, list_item)
+		if (dev->ch == ch)
+			dev->ch = NULL;
+	kfree(ch);
 
 	spin_unlock_irqrestore(&ch_lock, flags);
 }
 EXPORT_SYMBOL(usb_diag_close);
 
-/**
- * usb_diag_free_req() - Free USB requests
- * @ch: Channel handler
- *
- * This function free read and write USB requests for the interface
- * associated with this channel.
- *
- */
-void usb_diag_free_req(struct usb_diag_ch *ch)
+static void free_reqs(struct diag_context *ctxt)
 {
-	struct diag_context *ctxt = ch->priv_usb;
-	struct usb_request *req;
 	struct list_head *act, *tmp;
-
-	if (!ctxt)
-		return;
+	struct usb_request *req;
 
 	list_for_each_safe(act, tmp, &ctxt->write_pool) {
 		req = list_entry(act, struct usb_request, list);
@@ -363,6 +357,27 @@
 		usb_ep_free_request(ctxt->out, req);
 	}
 }
+
+/**
+ * usb_diag_free_req() - Free USB requests
+ * @ch: Channel handler
+ *
+ * This function free read and write USB requests for the interface
+ * associated with this channel.
+ *
+ */
+void usb_diag_free_req(struct usb_diag_ch *ch)
+{
+	struct diag_context *ctxt = ch->priv_usb;
+	unsigned long flags;
+
+	if (ctxt) {
+		spin_lock_irqsave(&ctxt->lock, flags);
+		free_reqs(ctxt);
+		spin_unlock_irqrestore(&ctxt->lock, flags);
+	}
+
+}
 EXPORT_SYMBOL(usb_diag_free_req);
 
 /**
@@ -381,10 +396,14 @@
 	struct diag_context *ctxt = ch->priv_usb;
 	struct usb_request *req;
 	int i;
+	unsigned long flags;
 
 	if (!ctxt)
 		return -ENODEV;
 
+	spin_lock_irqsave(&ctxt->lock, flags);
+	/* Free previous session's stale requests */
+	free_reqs(ctxt);
 	for (i = 0; i < n_write; i++) {
 		req = usb_ep_alloc_request(ctxt->in, GFP_ATOMIC);
 		if (!req)
@@ -400,11 +419,11 @@
 		req->complete = diag_read_complete;
 		list_add_tail(&req->list, &ctxt->read_pool);
 	}
-
+	spin_unlock_irqrestore(&ctxt->lock, flags);
 	return 0;
-
 fail:
-	usb_diag_free_req(ch);
+	free_reqs(ctxt);
+	spin_unlock_irqrestore(&ctxt->lock, flags);
 	return -ENOMEM;
 
 }
@@ -542,15 +561,16 @@
 	dev->configured = 0;
 	spin_unlock_irqrestore(&dev->lock, flags);
 
-	if (dev->ch.notify)
-		dev->ch.notify(dev->ch.priv, USB_DIAG_DISCONNECT, NULL);
+	if (dev->ch && dev->ch->notify)
+		dev->ch->notify(dev->ch->priv, USB_DIAG_DISCONNECT, NULL);
 
 	usb_ep_disable(dev->in);
 	dev->in->driver_data = NULL;
 
 	usb_ep_disable(dev->out);
 	dev->out->driver_data = NULL;
-
+	if (dev->ch)
+		dev->ch->priv_usb = NULL;
 }
 
 static int diag_function_set_alt(struct usb_function *f,
@@ -568,6 +588,15 @@
 		return -EINVAL;
 	}
 
+	if (!dev->ch)
+		return -ENODEV;
+
+	/*
+	 * Indicate to the diag channel that the active diag device is dev.
+	 * Since a few diag devices can point to the same channel.
+	 */
+	dev->ch->priv_usb = dev;
+
 	dev->in->driver_data = dev;
 	rc = usb_ep_enable(dev->in);
 	if (rc) {
@@ -607,7 +636,16 @@
 		usb_free_descriptors(f->hs_descriptors);
 
 	usb_free_descriptors(f->descriptors);
-	ctxt->ch.priv_usb = NULL;
+
+	/*
+	 * Channel priv_usb may point to other diag function.
+	 * Clear the priv_usb only if the channel is used by the
+	 * diag dev we unbind here.
+	 */
+	if (ctxt->ch && ctxt->ch->priv_usb == ctxt)
+		ctxt->ch->priv_usb = NULL;
+	list_del(&ctxt->list_item);
+	kfree(ctxt);
 }
 
 static int diag_function_bind(struct usb_configuration *c,
@@ -697,9 +735,19 @@
 		return -ENODEV;
 	}
 
-	dev = container_of(_ch, struct diag_context, ch);
-	/* claim the channel for this USB interface */
-	_ch->priv_usb = dev;
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return -ENOMEM;
+
+	list_add_tail(&dev->list_item, &diag_dev_list);
+
+	/*
+	 * A few diag devices can point to the same channel, in case that
+	 * the diag devices belong to different configurations, however
+	 * only the active diag device will claim the channel by setting
+	 * the ch->priv_usb (see diag_function_set_alt).
+	 */
+	dev->ch = _ch;
 
 	dev->update_pid_and_serial_num = update_pid;
 	dev->cdev = c->cdev;
@@ -718,13 +766,13 @@
 	ret = usb_add_function(c, &dev->function);
 	if (ret) {
 		INFO(c->cdev, "usb_add_function failed\n");
-		_ch->priv_usb = NULL;
+		list_del(&dev->list_item);
+		kfree(dev);
 	}
 
 	return ret;
 }
 
-
 #if defined(CONFIG_DEBUG_FS)
 static char debug_buffer[PAGE_SIZE];
 
@@ -802,7 +850,6 @@
 
 static void diag_cleanup(void)
 {
-	struct diag_context *dev;
 	struct list_head *act, *tmp;
 	struct usb_diag_ch *_ch;
 	unsigned long flags;
@@ -811,13 +858,12 @@
 
 	list_for_each_safe(act, tmp, &usb_diag_ch_list) {
 		_ch = list_entry(act, struct usb_diag_ch, list);
-		dev = container_of(_ch, struct diag_context, ch);
 
 		spin_lock_irqsave(&ch_lock, flags);
 		/* Free if diagchar is not using the channel anymore */
 		if (!_ch->priv) {
 			list_del(&_ch->list);
-			kfree(dev);
+			kfree(_ch);
 		}
 		spin_unlock_irqrestore(&ch_lock, flags);
 	}
@@ -825,6 +871,8 @@
 
 static int diag_setup(void)
 {
+	INIT_LIST_HEAD(&diag_dev_list);
+
 	fdiag_debugfs_init();
 
 	return 0;
diff --git a/drivers/usb/gadget/f_diag.h b/drivers/usb/gadget/f_diag.h
index 82d9a25..90497b6 100644
--- a/drivers/usb/gadget/f_diag.h
+++ b/drivers/usb/gadget/f_diag.h
@@ -3,7 +3,7 @@
  * Diag Function Device - Route DIAG frames between SMD and USB
  *
  * Copyright (C) 2008-2009 Google, Inc.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 0514aa8..245a972 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -2512,6 +2512,8 @@
 	fsg->bulk_out_enabled = 1;
 	common->bulk_out_maxpacket = le16_to_cpu(fsg->bulk_in->desc->wMaxPacketSize);
 	clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
+	csw_hack_sent = 0;
+	write_error_after_csw_sent = 0;
 	fsg->common->new_fsg = fsg;
 	raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
 	return USB_GADGET_DELAYED_STATUS;
diff --git a/drivers/usb/gadget/f_mbim.c b/drivers/usb/gadget/f_mbim.c
index 65b4890..a32dd15 100644
--- a/drivers/usb/gadget/f_mbim.c
+++ b/drivers/usb/gadget/f_mbim.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -66,6 +66,7 @@
 	NCM_NOTIFY_NONE,
 	NCM_NOTIFY_CONNECT,
 	NCM_NOTIFY_SPEED,
+	NCM_NOTIFY_RESPONSE_AVAILABLE,
 };
 
 struct f_mbim {
@@ -91,6 +92,7 @@
 	struct mbim_ep_descs		hs;
 
 	u8				ctrl_id, data_id;
+	u8				data_alt_int;
 
 	struct ndp_parser_opts		*parser_opts;
 
@@ -222,6 +224,16 @@
 	.bmNetworkCapabilities = 0x20,
 };
 
+static struct usb_cdc_ext_mbb_desc ext_mbb_desc = {
+	.bLength =	sizeof ext_mbb_desc,
+	.bDescriptorType =	USB_DT_CS_INTERFACE,
+	.bDescriptorSubType =	USB_CDC_EXT_MBB_TYPE,
+
+	.bcdMbbExtendedVersion =	cpu_to_le16(0x0100),
+	.bMaxOutstandingCmdMsges =	64,
+	.wMTU =	1500,
+};
+
 /* the default data interface has no endpoints ... */
 static struct usb_interface_descriptor mbim_data_nop_intf = {
 	.bLength =		sizeof mbim_data_nop_intf,
@@ -283,7 +295,9 @@
 	/* MBIM control descriptors */
 	(struct usb_descriptor_header *) &mbim_control_intf,
 	(struct usb_descriptor_header *) &mbim_header_desc,
+	(struct usb_descriptor_header *) &mbim_union_desc,
 	(struct usb_descriptor_header *) &mbb_desc,
+	(struct usb_descriptor_header *) &ext_mbb_desc,
 	(struct usb_descriptor_header *) &fs_mbim_notify_desc,
 	/* data interface, altsettings 0 and 1 */
 	(struct usb_descriptor_header *) &mbim_data_nop_intf,
@@ -328,6 +342,7 @@
 	(struct usb_descriptor_header *) &mbim_control_intf,
 	(struct usb_descriptor_header *) &mbim_header_desc,
 	(struct usb_descriptor_header *) &mbb_desc,
+	(struct usb_descriptor_header *) &ext_mbb_desc,
 	(struct usb_descriptor_header *) &hs_mbim_notify_desc,
 	/* data interface, altsettings 0 and 1 */
 	(struct usb_descriptor_header *) &mbim_data_nop_intf,
@@ -570,6 +585,7 @@
 		return;
 	}
 
+	req->length = sizeof *event;
 	event = req->buf;
 	event->bmRequestType = USB_DIR_IN | USB_TYPE_CLASS
 			| USB_RECIP_INTERFACE;
@@ -580,7 +596,7 @@
 	spin_unlock_irqrestore(&dev->lock, flags);
 
 	ret = usb_ep_queue(dev->not_port.notify,
-			   dev->not_port.notify_req, GFP_ATOMIC);
+			   req, GFP_ATOMIC);
 	if (ret) {
 		atomic_dec(&dev->not_port.notify_count);
 		pr_err("ep enqueue error %d\n", ret);
@@ -609,6 +625,13 @@
 		return 0;
 	}
 
+	if (dev->not_port.notify_state != NCM_NOTIFY_RESPONSE_AVAILABLE) {
+		pr_err("dev:%p state=%d, recover!!\n", dev,
+			dev->not_port.notify_state);
+		mbim_free_ctrl_pkt(cpkt);
+		return 0;
+	}
+
 	spin_lock_irqsave(&dev->lock, flags);
 	list_add_tail(&cpkt->list, &dev->cpkt_resp_q);
 	spin_unlock_irqrestore(&dev->lock, flags);
@@ -642,7 +665,8 @@
 
 	pr_info("dev:%p portno:%d\n", dev, dev->port_num);
 
-	ret = bam_data_connect(&dev->bam_port, dev->port_num, dev->port_num);
+	ret = bam_data_connect(&dev->bam_port, dev->port_num,
+		USB_GADGET_XPORT_BAM2BAM, dev->port_num, USB_FUNC_MBIM);
 	if (ret) {
 		pr_err("bam_data_setup failed: err:%d\n",
 				ret);
@@ -659,7 +683,7 @@
 	pr_info("dev:%p port:%d. Do nothing.\n",
 			dev, dev->port_num);
 
-	/* bam_data_disconnect(&dev->bam_port, dev->port_num); */
+	bam_data_disconnect(&dev->bam_port, dev->port_num);
 
 	return 0;
 }
@@ -749,10 +773,18 @@
 	switch (mbim->not_port.notify_state) {
 
 	case NCM_NOTIFY_NONE:
+		if (atomic_read(&mbim->not_port.notify_count) > 0)
+			pr_err("Pending notifications in NCM_NOTIFY_NONE\n");
+		else
+			pr_debug("No pending notifications\n");
+
+		return;
+
+	case NCM_NOTIFY_RESPONSE_AVAILABLE:
 		pr_debug("Notification %02x sent\n", event->bNotificationType);
 
 		if (atomic_read(&mbim->not_port.notify_count) <= 0) {
-			pr_debug("notify_none: done");
+			pr_debug("notify_response_avaliable: done");
 			return;
 		}
 
@@ -777,7 +809,7 @@
 
 		pr_info("notify connect %s\n",
 			mbim->is_open ? "true" : "false");
-		mbim->not_port.notify_state = NCM_NOTIFY_NONE;
+		mbim->not_port.notify_state = NCM_NOTIFY_RESPONSE_AVAILABLE;
 		break;
 
 	case NCM_NOTIFY_SPEED:
@@ -829,7 +861,7 @@
 	 */
 	pr_debug("dev:%p\n", mbim);
 
-	mbim->not_port.notify_state = NCM_NOTIFY_SPEED;
+	mbim->not_port.notify_state = NCM_NOTIFY_RESPONSE_AVAILABLE;
 	mbim_do_notify(mbim);
 }
 
@@ -1273,7 +1305,6 @@
 		if (mbim->bam_port.in->driver_data) {
 			pr_info("reset mbim\n");
 			mbim_reset_values(mbim);
-			mbim_bam_disconnect(mbim);
 		}
 
 		/*
@@ -1319,6 +1350,7 @@
 			}
 		}
 
+		mbim->data_alt_int = alt;
 		spin_lock(&mbim->lock);
 		mbim_notify(mbim);
 		spin_unlock(&mbim->lock);
@@ -1351,7 +1383,10 @@
 
 	if (intf == mbim->ctrl_id)
 		return 0;
-	return mbim->bam_port.in->driver_data ? 1 : 0;
+	else if (intf == mbim->data_id)
+		return mbim->data_alt_int;
+
+	return -EINVAL;
 }
 
 static void mbim_disable(struct usb_function *f)
@@ -1361,6 +1396,8 @@
 	pr_info("SET DEVICE OFFLINE");
 	atomic_set(&mbim->online, 0);
 
+	mbim->not_port.notify_state = NCM_NOTIFY_NONE;
+
 	mbim_clear_queues(mbim);
 	mbim_reset_function_queue(mbim);
 
@@ -1418,6 +1455,7 @@
 	if (status < 0)
 		goto fail;
 	mbim->data_id = status;
+	mbim->data_alt_int = 0;
 
 	mbim_data_nop_intf.bInterfaceNumber = status;
 	mbim_data_intf.bInterfaceNumber = status;
@@ -1659,7 +1697,7 @@
 			atomic_read(&dev->error)));
 		if (ret < 0) {
 			mbim_unlock(&dev->read_excl);
-			return 0;
+			return -ERESTARTSYS;
 		}
 	}
 
@@ -1669,13 +1707,13 @@
 	}
 
 	while (list_empty(&dev->cpkt_req_q)) {
-		pr_err("Requests list is empty. Wait.\n");
+		pr_debug("Requests list is empty. Wait.\n");
 		ret = wait_event_interruptible(dev->read_wq,
 			!list_empty(&dev->cpkt_req_q));
 		if (ret < 0) {
 			pr_err("Waiting failed\n");
 			mbim_unlock(&dev->read_excl);
-			return 0;
+			return -ERESTARTSYS;
 		}
 		pr_debug("Received request packet\n");
 	}
@@ -1697,7 +1735,7 @@
 	ret = copy_to_user(buf, cpkt->buf, cpkt->len);
 	if (ret) {
 		pr_err("copy_to_user failed: err %d\n", ret);
-		ret = 0;
+		ret = -ENOMEM;
 	} else {
 		pr_debug("copied %d bytes to user\n", cpkt->len);
 		ret = cpkt->len;
diff --git a/drivers/usb/gadget/f_mtp.c b/drivers/usb/gadget/f_mtp.c
index 82ffbba..0c0d58a 100644
--- a/drivers/usb/gadget/f_mtp.c
+++ b/drivers/usb/gadget/f_mtp.c
@@ -67,6 +67,9 @@
 #define MTP_RESPONSE_OK             0x2001
 #define MTP_RESPONSE_DEVICE_BUSY    0x2019
 
+unsigned int mtp_rx_req_len = MTP_BULK_BUFFER_SIZE;
+module_param(mtp_rx_req_len, uint, S_IRUGO | S_IWUSR);
+
 static const char mtp_shortname[] = "mtp_usb";
 
 struct mtp_dev {
@@ -493,10 +496,27 @@
 		req->complete = mtp_complete_in;
 		mtp_req_put(dev, &dev->tx_idle, req);
 	}
+
+	/*
+	 * The RX buffer should be aligned to EP max packet for
+	 * some controllers.  At bind time, we don't know the
+	 * operational speed.  Hence assuming super speed max
+	 * packet size.
+	 */
+	if (mtp_rx_req_len % 1024)
+		mtp_rx_req_len = MTP_BULK_BUFFER_SIZE;
+
+retry_rx_alloc:
 	for (i = 0; i < RX_REQ_MAX; i++) {
-		req = mtp_request_new(dev->ep_out, MTP_BULK_BUFFER_SIZE);
-		if (!req)
-			goto fail;
+		req = mtp_request_new(dev->ep_out, mtp_rx_req_len);
+		if (!req) {
+			if (mtp_rx_req_len <= MTP_BULK_BUFFER_SIZE)
+				goto fail;
+			for (; i > 0; i--)
+				mtp_request_free(dev->rx_req[i], dev->ep_out);
+			mtp_rx_req_len = MTP_BULK_BUFFER_SIZE;
+			goto retry_rx_alloc;
+		}
 		req->complete = mtp_complete_out;
 		dev->rx_req[i] = req;
 	}
@@ -526,7 +546,7 @@
 
 	DBG(cdev, "mtp_read(%d)\n", count);
 
-	if (count > MTP_BULK_BUFFER_SIZE)
+	if (count > mtp_rx_req_len)
 		return -EINVAL;
 
 	if (!IS_ALIGNED(count, dev->ep_out->maxpacket))
@@ -554,7 +574,7 @@
 requeue_req:
 	/* queue a request */
 	req = dev->rx_req[0];
-	req->length = MTP_BULK_BUFFER_SIZE;
+	req->length = mtp_rx_req_len;
 	dev->rx_done = 0;
 	ret = usb_ep_queue(dev->ep_out, req, GFP_KERNEL);
 	if (ret < 0) {
@@ -832,7 +852,7 @@
 			cur_buf = (cur_buf + 1) % RX_REQ_MAX;
 
 			/* some h/w expects size to be aligned to ep's MTU */
-			read_req->length = MTP_BULK_BUFFER_SIZE;
+			read_req->length = mtp_rx_req_len;
 
 			dev->rx_done = 0;
 			ret = usb_ep_queue(dev->ep_out, read_req, GFP_KERNEL);
diff --git a/drivers/usb/gadget/f_qc_ecm.c b/drivers/usb/gadget/f_qc_ecm.c
index 0b41197..559fd04 100644
--- a/drivers/usb/gadget/f_qc_ecm.c
+++ b/drivers/usb/gadget/f_qc_ecm.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2003-2005,2008 David Brownell
  * Copyright (C) 2008 Nokia Corporation
- * Copyright (c) 2012, Code Aurora Forum. 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
@@ -21,6 +21,11 @@
 
 /* #define VERBOSE_DEBUG */
 
+#ifdef pr_fmt
+#undef pr_fmt
+#endif
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
 #include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
@@ -29,6 +34,9 @@
 #include "u_ether.h"
 #include "u_qc_ether.h"
 
+#include "u_bam_data.h"
+#include <mach/ecm_ipa.h>
+
 
 /*
  * This function is a "CDC Ethernet Networking Control Model" (CDC ECM)
@@ -58,9 +66,9 @@
 };
 
 struct f_ecm_qc {
-	struct qc_gether			port;
+	struct qc_gether		port;
 	u8				ctrl_id, data_id;
-
+	enum transport_type		xport;
 	char				ethaddr[14];
 
 	struct usb_ep			*notify;
@@ -69,6 +77,16 @@
 	bool				is_open;
 };
 
+struct f_ecm_qc_ipa_params {
+	u8			dev_mac[ETH_ALEN];
+	u8			host_mac[ETH_ALEN];
+	ecm_ipa_callback	ipa_rx_cb;
+	ecm_ipa_callback	ipa_tx_cb;
+	void			*ipa_priv;
+};
+
+static struct f_ecm_qc_ipa_params ipa_params;
+
 static inline struct f_ecm_qc *func_to_ecm_qc(struct usb_function *f)
 {
 	return container_of(f, struct f_ecm_qc, port.func);
@@ -288,50 +306,6 @@
 
 static struct data_port ecm_qc_bam_port;
 
-static int ecm_qc_bam_setup(void)
-{
-	int ret;
-
-	ret = bam_data_setup(ECM_QC_NO_PORTS);
-	if (ret) {
-		pr_err("bam_data_setup failed err: %d\n", ret);
-		return ret;
-	}
-
-	return 0;
-}
-
-static int ecm_qc_bam_connect(struct f_ecm_qc *dev)
-{
-	int ret;
-
-	ecm_qc_bam_port.cdev = dev->port.func.config->cdev;
-	ecm_qc_bam_port.in = dev->port.in_ep;
-	ecm_qc_bam_port.out = dev->port.out_ep;
-
-	/* currently we use the first connection */
-	ret = bam_data_connect(&ecm_qc_bam_port, 0, 0);
-	if (ret) {
-		pr_err("bam_data_connect failed: err:%d\n",
-				ret);
-		return ret;
-	} else {
-		pr_info("ecm bam connected\n");
-	}
-
-	return 0;
-}
-
-static int ecm_qc_bam_disconnect(struct f_ecm_qc *dev)
-{
-	pr_debug("dev:%p. %s Do nothing.\n",
-			 dev, __func__);
-
-	return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
 static void ecm_qc_do_notify(struct f_ecm_qc *ecm)
 {
 	struct usb_request		*req = ecm->notify_req;
@@ -400,6 +374,73 @@
 	ecm_qc_do_notify(ecm);
 }
 
+static int ecm_qc_bam_setup(void)
+{
+	int ret;
+
+	ret = bam_data_setup(ECM_QC_NO_PORTS);
+	if (ret) {
+		pr_err("bam_data_setup failed err: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int ecm_qc_bam_connect(struct f_ecm_qc *dev)
+{
+	int ret;
+
+	ecm_qc_bam_port.cdev = dev->port.func.config->cdev;
+	ecm_qc_bam_port.in = dev->port.in_ep;
+	ecm_qc_bam_port.out = dev->port.out_ep;
+
+	/* currently we use the first connection */
+	ret = bam_data_connect(&ecm_qc_bam_port, 0, dev->xport,
+					0, USB_FUNC_ECM);
+	if (ret) {
+		pr_err("bam_data_connect failed: err:%d\n", ret);
+		return ret;
+	} else {
+		pr_debug("ecm bam connected\n");
+	}
+
+	dev->is_open = true;
+	ecm_qc_notify(dev);
+
+	return 0;
+}
+
+static int ecm_qc_bam_disconnect(struct f_ecm_qc *dev)
+{
+	pr_debug("dev:%p. Disconnect BAM.\n", dev);
+
+	bam_data_disconnect(&ecm_qc_bam_port, 0);
+
+	ecm_ipa_cleanup(ipa_params.ipa_priv);
+
+	return 0;
+}
+
+void *ecm_qc_get_ipa_rx_cb(void)
+{
+	return ipa_params.ipa_rx_cb;
+}
+
+void *ecm_qc_get_ipa_tx_cb(void)
+{
+	return ipa_params.ipa_tx_cb;
+}
+
+void *ecm_qc_get_ipa_priv(void)
+{
+	return ipa_params.ipa_priv;
+}
+
+/*-------------------------------------------------------------------------*/
+
+
+
 static void ecm_qc_notify_complete(struct usb_ep *ep, struct usb_request *req)
 {
 	struct f_ecm_qc			*ecm = req->context;
@@ -518,8 +559,13 @@
 
 		if (ecm->port.in_ep->driver_data) {
 			DBG(cdev, "reset ecm\n");
-			gether_qc_disconnect_name(&ecm->port, "ecm0");
+			/* ecm->port is needed for disconnecting the BAM data
+			 * path. Only after the BAM data path is disconnected,
+			 * we can disconnect the port from the network layer.
+			 */
 			ecm_qc_bam_disconnect(ecm);
+			if (ecm->xport != USB_GADGET_XPORT_BAM2BAM_IPA)
+				gether_qc_disconnect_name(&ecm->port, "ecm0");
 		}
 
 		if (!ecm->port.in_ep->desc ||
@@ -548,9 +594,12 @@
 				);
 			ecm->port.cdc_filter = DEFAULT_FILTER;
 			DBG(cdev, "activate ecm\n");
-			net = gether_qc_connect_name(&ecm->port, "ecm0");
-			if (IS_ERR(net))
-				return PTR_ERR(net);
+			if (ecm->xport != USB_GADGET_XPORT_BAM2BAM_IPA) {
+				net = gether_qc_connect_name(&ecm->port,
+								"ecm0");
+				if (IS_ERR(net))
+					return PTR_ERR(net);
+			}
 
 			if (ecm_qc_bam_connect(ecm))
 				goto fail;
@@ -591,8 +640,9 @@
 	DBG(cdev, "ecm deactivated\n");
 
 	if (ecm->port.in_ep->driver_data) {
-		gether_qc_disconnect_name(&ecm->port, "ecm0");
 		ecm_qc_bam_disconnect(ecm);
+		if (ecm->xport != USB_GADGET_XPORT_BAM2BAM_IPA)
+			gether_qc_disconnect_name(&ecm->port, "ecm0");
 	}
 
 	if (ecm->notify->driver_data) {
@@ -657,6 +707,7 @@
 	status = usb_interface_id(c, f);
 	if (status < 0)
 		goto fail;
+
 	ecm->ctrl_id = status;
 
 	ecm_qc_control_intf.bInterfaceNumber = status;
@@ -665,6 +716,7 @@
 	status = usb_interface_id(c, f);
 	if (status < 0)
 		goto fail;
+
 	ecm->data_id = status;
 
 	ecm_qc_data_nop_intf.bInterfaceNumber = status;
@@ -792,6 +844,7 @@
  * @c: the configuration to support the network link
  * @ethaddr: a buffer in which the ethernet address of the host side
  *	side of the link was recorded
+ * @xport_name: data path transport type name ("BAM2BAM" or "BAM2BAM_IPA")
  * Context: single threaded during gadget setup
  *
  * Returns zero on success, else negative errno.
@@ -800,7 +853,8 @@
  * for calling @gether_cleanup() before module unload.
  */
 int
-ecm_qc_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
+ecm_qc_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+	char *xport_name)
 {
 	struct f_ecm_qc		*ecm;
 	int		status;
@@ -814,6 +868,8 @@
 		return status;
 	}
 
+	pr_debug("data transport type is %s", xport_name);
+
 	/* maybe allocate device-global string IDs */
 	if (ecm_qc_string_defs[0].id == 0) {
 
@@ -844,11 +900,23 @@
 	if (!ecm)
 		return -ENOMEM;
 
+	ecm->xport = str_to_xport(xport_name);
+	pr_debug("set xport = %d", ecm->xport);
+
 	/* export host's Ethernet address in CDC format */
-	snprintf(ecm->ethaddr, sizeof ecm->ethaddr,
+	if (ecm->xport == USB_GADGET_XPORT_BAM2BAM_IPA) {
+		gether_qc_get_macs(ipa_params.dev_mac, ipa_params.host_mac);
+		snprintf(ecm->ethaddr, sizeof ecm->ethaddr,
+		"%02X%02X%02X%02X%02X%02X",
+		ipa_params.host_mac[0], ipa_params.host_mac[1],
+		ipa_params.host_mac[2], ipa_params.host_mac[3],
+		ipa_params.host_mac[4], ipa_params.host_mac[5]);
+	} else
+		snprintf(ecm->ethaddr, sizeof ecm->ethaddr,
 		"%02X%02X%02X%02X%02X%02X",
 		ethaddr[0], ethaddr[1], ethaddr[2],
 		ethaddr[3], ethaddr[4], ethaddr[5]);
+
 	ecm_qc_string_defs[1].s = ecm->ethaddr;
 
 	ecm->port.cdc_filter = DEFAULT_FILTER;
@@ -865,8 +933,31 @@
 
 	status = usb_add_function(c, &ecm->port.func);
 	if (status) {
+		pr_err("failed to add function");
+		ecm_qc_string_defs[1].s = NULL;
+		kfree(ecm);
+		return status;
+	}
+
+	if (ecm->xport != USB_GADGET_XPORT_BAM2BAM_IPA)
+		return status;
+
+	status = ecm_ipa_init(&ipa_params.ipa_rx_cb, &ipa_params.ipa_tx_cb,
+			&ipa_params.ipa_priv);
+	if (status) {
+		pr_err("failed to initialize ECM IPA Driver");
+		ecm_qc_string_defs[1].s = NULL;
+		kfree(ecm);
+		return status;
+	}
+
+	status = ecm_ipa_configure(ipa_params.host_mac, ipa_params.dev_mac,
+			ipa_params.ipa_priv);
+	if (status) {
+		pr_err("failed to configure ECM IPA Driver");
 		ecm_qc_string_defs[1].s = NULL;
 		kfree(ecm);
 	}
+
 	return status;
 }
diff --git a/drivers/usb/gadget/f_qc_rndis.c b/drivers/usb/gadget/f_qc_rndis.c
index 82ef2a8..51d7bc1 100644
--- a/drivers/usb/gadget/f_qc_rndis.c
+++ b/drivers/usb/gadget/f_qc_rndis.c
@@ -6,7 +6,7 @@
  * Copyright (C) 2008 Nokia Corporation
  * Copyright (C) 2009 Samsung Electronics
  *			Author: Michal Nazarewicz (mina86@mina86.com)
- * Copyright (c) 2012, Code Aurora Forum. 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
@@ -94,6 +94,7 @@
 	struct usb_ep			*notify;
 	struct usb_request		*notify_req;
 	atomic_t			notify_count;
+	struct data_port		bam_port;
 };
 
 static inline struct f_rndis_qc *func_to_rndis_qc(struct usb_function *f)
@@ -117,8 +118,11 @@
 #define RNDIS_QC_LOG2_STATUS_INTERVAL_MSEC	5	/* 1 << 5 == 32 msec */
 #define RNDIS_QC_STATUS_BYTECOUNT		8	/* 8 bytes data */
 
-/* currently only one rndis instance is supported */
-#define RNDIS_QC_NO_PORTS					1
+/* currently only one rndis instance is supported - port
+ * index 0.
+ */
+#define RNDIS_QC_NO_PORTS				1
+#define RNDIS_QC_ACTIVE_PORT				0
 
 /* default max packets per tarnsfer value */
 #define DEFAULT_MAX_PKT_PER_XFER			15
@@ -400,7 +404,6 @@
 }
 
 /* MSM bam support */
-static struct data_port rndis_qc_bam_port;
 
 static int rndis_qc_bam_setup(void)
 {
@@ -419,12 +422,13 @@
 {
 	int ret;
 
-	rndis_qc_bam_port.cdev = dev->port.func.config->cdev;
-	rndis_qc_bam_port.in = dev->port.in_ep;
-	rndis_qc_bam_port.out = dev->port.out_ep;
+	dev->bam_port.cdev = dev->port.func.config->cdev;
+	dev->bam_port.in = dev->port.in_ep;
+	dev->bam_port.out = dev->port.out_ep;
 
 	/* currently we use the first connection */
-	ret = bam_data_connect(&rndis_qc_bam_port, 0, 0);
+	ret = bam_data_connect(&dev->bam_port, 0, USB_GADGET_XPORT_BAM2BAM,
+			0, USB_FUNC_RNDIS);
 	if (ret) {
 		pr_err("bam_data_connect failed: err:%d\n",
 				ret);
@@ -438,8 +442,9 @@
 
 static int rndis_qc_bam_disconnect(struct f_rndis_qc *dev)
 {
-	pr_info("dev:%p. %s Do nothing.\n",
-			dev, __func__);
+	pr_debug("dev:%p. %s Disconnect BAM.\n", dev, __func__);
+
+	bam_data_disconnect(&dev->bam_port, 0);
 
 	return 0;
 }
@@ -671,8 +676,12 @@
 
 		if (rndis->port.in_ep->driver_data) {
 			DBG(cdev, "reset rndis\n");
-			gether_qc_disconnect_name(&rndis->port, "rndis0");
+			/* rndis->port is needed for disconnecting the BAM data
+			 * path. Only after the BAM data path is disconnected,
+			 * we can disconnect the port from the network layer.
+			 */
 			rndis_qc_bam_disconnect(rndis);
+			gether_qc_disconnect_name(&rndis->port, "rndis0");
 		}
 
 		if (!rndis->port.in_ep->desc || !rndis->port.out_ep->desc) {
@@ -732,13 +741,27 @@
 	pr_info("rndis deactivated\n");
 
 	rndis_uninit(rndis->config);
-	gether_qc_disconnect_name(&rndis->port, "rndis0");
 	rndis_qc_bam_disconnect(rndis);
+	gether_qc_disconnect_name(&rndis->port, "rndis0");
 
 	usb_ep_disable(rndis->notify);
 	rndis->notify->driver_data = NULL;
 }
 
+static void rndis_qc_suspend(struct usb_function *f)
+{
+	pr_debug("%s: rndis suspended\n", __func__);
+
+	bam_data_suspend(RNDIS_QC_ACTIVE_PORT);
+}
+
+static void rndis_qc_resume(struct usb_function *f)
+{
+	pr_debug("%s: rndis resumed\n", __func__);
+
+	bam_data_resume(RNDIS_QC_ACTIVE_PORT);
+}
+
 /*-------------------------------------------------------------------------*/
 
 /*
@@ -1056,6 +1079,8 @@
 	rndis->port.func.set_alt = rndis_qc_set_alt;
 	rndis->port.func.setup = rndis_qc_setup;
 	rndis->port.func.disable = rndis_qc_disable;
+	rndis->port.func.suspend = rndis_qc_suspend;
+	rndis->port.func.resume = rndis_qc_resume;
 
 	_rndis_qc = rndis;
 
diff --git a/drivers/usb/gadget/f_qdss.c b/drivers/usb/gadget/f_qdss.c
index c3eddcc..3069bcb 100644
--- a/drivers/usb/gadget/f_qdss.c
+++ b/drivers/usb/gadget/f_qdss.c
@@ -1,7 +1,7 @@
 /*
  * f_qdss.c -- QDSS function Driver
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
 
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -408,7 +408,9 @@
 {
 	pr_debug("qdss_unbind\n");
 
+	clear_eps(f);
 	clear_desc(c->cdev->gadget, f);
+	msm_dwc3_restart_usb_session();
 }
 
 static void qdss_eps_disable(struct usb_function *f)
@@ -420,19 +422,16 @@
 	if (qdss->ctrl_in_enabled) {
 		usb_ep_disable(qdss->ctrl_in);
 		qdss->ctrl_in_enabled = 0;
-		qdss->ctrl_in->driver_data = NULL;
 	}
 
 	if (qdss->ctrl_out_enabled) {
 		usb_ep_disable(qdss->ctrl_out);
 		qdss->ctrl_out_enabled = 0;
-		qdss->ctrl_out->driver_data = NULL;
 	}
 
 	if (qdss->data_enabled) {
 		usb_ep_disable(qdss->data);
 		qdss->data_enabled = 0;
-		qdss->data->driver_data = NULL;
 	}
 }
 
@@ -797,11 +796,13 @@
 	pr_debug("usb_qdss_close\n");
 
 	spin_lock_irqsave(&d_lock, flags);
-	/*free not used reqests*/
-	usb_qdss_free_req(ch);
 	usb_ep_dequeue(qdss->data, qdss->endless_req);
+	usb_ep_free_request(qdss->data, qdss->endless_req);
 	qdss->endless_req = NULL;
+	ch->app_conn = 0;
 	spin_unlock_irqrestore(&d_lock, flags);
+
+	msm_dwc3_restart_usb_session();
 }
 EXPORT_SYMBOL(usb_qdss_close);
 
diff --git a/drivers/usb/gadget/f_qdss.h b/drivers/usb/gadget/f_qdss.h
index d6be8b7..93b5b1f 100644
--- a/drivers/usb/gadget/f_qdss.h
+++ b/drivers/usb/gadget/f_qdss.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
 
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/usb/gadget/f_rmnet.c b/drivers/usb/gadget/f_rmnet.c
index 32fc79e..0d8fa0f 100644
--- a/drivers/usb/gadget/f_rmnet.c
+++ b/drivers/usb/gadget/f_rmnet.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -55,6 +55,7 @@
 #define NR_RMNET_PORTS	3
 static unsigned int nr_rmnet_ports;
 static unsigned int no_ctrl_smd_ports;
+static unsigned int no_ctrl_qti_ports;
 static unsigned int no_ctrl_hsic_ports;
 static unsigned int no_ctrl_hsuart_ports;
 static unsigned int no_data_bam_ports;
@@ -402,6 +403,14 @@
 			return ret;
 		}
 		break;
+	case USB_GADGET_XPORT_QTI:
+		ret = gqti_ctrl_connect(&dev->port);
+		if (ret) {
+			pr_err("%s: gqti_ctrl_connect failed: err:%d\n",
+					__func__, ret);
+			return ret;
+		}
+		break;
 	case USB_GADGET_XPORT_HSIC:
 		ret = ghsic_ctrl_connect(&dev->port, port_num);
 		if (ret) {
@@ -436,7 +445,10 @@
 		if (ret) {
 			pr_err("%s: gbam_connect failed: err:%d\n",
 					__func__, ret);
-			gsmd_ctrl_disconnect(&dev->port, port_num);
+			if (cxport == USB_GADGET_XPORT_QTI)
+				gqti_ctrl_disconnect(&dev->port);
+			else
+				gsmd_ctrl_disconnect(&dev->port, port_num);
 			return ret;
 		}
 		break;
@@ -484,6 +496,9 @@
 	case USB_GADGET_XPORT_SMD:
 		gsmd_ctrl_disconnect(&dev->port, port_num);
 		break;
+	case USB_GADGET_XPORT_QTI:
+		gqti_ctrl_disconnect(&dev->port);
+		break;
 	case USB_GADGET_XPORT_HSIC:
 		ghsic_ctrl_disconnect(&dev->port, port_num);
 		break;
@@ -539,6 +554,25 @@
 	kfree(f->name);
 }
 
+static void frmnet_purge_responses(struct f_rmnet *dev)
+{
+	unsigned long flags;
+	struct rmnet_ctrl_pkt *cpkt;
+
+	pr_debug("%s: port#%d\n", __func__, dev->port_num);
+
+	spin_lock_irqsave(&dev->lock, flags);
+	while (!list_empty(&dev->cpkt_resp_q)) {
+		cpkt = list_first_entry(&dev->cpkt_resp_q,
+				struct rmnet_ctrl_pkt, list);
+
+		list_del(&cpkt->list);
+		rmnet_free_ctrl_pkt(cpkt);
+	}
+	atomic_set(&dev->notify_count, 0);
+	spin_unlock_irqrestore(&dev->lock, flags);
+}
+
 static void frmnet_suspend(struct usb_function *f)
 {
 	struct f_rmnet *dev = func_to_rmnet(f);
@@ -549,6 +583,8 @@
 		__func__, xport_to_str(dxport),
 		dev, dev->port_num);
 
+	frmnet_purge_responses(dev);
+
 	port_num = rmnet_ports[dev->port_num].data_xport_num;
 	switch (dxport) {
 	case USB_GADGET_XPORT_BAM:
@@ -602,8 +638,6 @@
 static void frmnet_disable(struct usb_function *f)
 {
 	struct f_rmnet *dev = func_to_rmnet(f);
-	unsigned long flags;
-	struct rmnet_ctrl_pkt *cpkt;
 
 	pr_debug("%s: port#%d\n", __func__, dev->port_num);
 
@@ -612,16 +646,7 @@
 
 	atomic_set(&dev->online, 0);
 
-	spin_lock_irqsave(&dev->lock, flags);
-	while (!list_empty(&dev->cpkt_resp_q)) {
-		cpkt = list_first_entry(&dev->cpkt_resp_q,
-				struct rmnet_ctrl_pkt, list);
-
-		list_del(&cpkt->list);
-		rmnet_free_ctrl_pkt(cpkt);
-	}
-	atomic_set(&dev->notify_count, 0);
-	spin_unlock_irqrestore(&dev->lock, flags);
+	frmnet_purge_responses(dev);
 
 	gport_rmnet_disconnect(dev);
 }
@@ -709,11 +734,11 @@
 
 	ret = usb_ep_queue(dev->notify, dev->notify_req, GFP_ATOMIC);
 	if (ret) {
-		atomic_dec(&dev->notify_count);
 		spin_lock_irqsave(&dev->lock, flags);
-		cpkt = list_first_entry(&dev->cpkt_resp_q,
+		if (!list_empty(&dev->cpkt_resp_q)) {
+			atomic_dec(&dev->notify_count);
+			cpkt = list_first_entry(&dev->cpkt_resp_q,
 					struct rmnet_ctrl_pkt, list);
-		if (cpkt) {
 			list_del(&cpkt->list);
 			rmnet_free_ctrl_pkt(cpkt);
 		}
@@ -739,10 +764,8 @@
 static void frmnet_disconnect(struct grmnet *gr)
 {
 	struct f_rmnet			*dev;
-	unsigned long			flags;
 	struct usb_cdc_notification	*event;
 	int				status;
-	struct rmnet_ctrl_pkt		*cpkt;
 
 	if (!gr) {
 		pr_err("%s: Invalid grmnet:%p\n", __func__, gr);
@@ -776,17 +799,7 @@
 				__func__, status);
 	}
 
-	spin_lock_irqsave(&dev->lock, flags);
-	while (!list_empty(&dev->cpkt_resp_q)) {
-		cpkt = list_first_entry(&dev->cpkt_resp_q,
-				struct rmnet_ctrl_pkt, list);
-
-		list_del(&cpkt->list);
-		rmnet_free_ctrl_pkt(cpkt);
-	}
-	atomic_set(&dev->notify_count, 0);
-	spin_unlock_irqrestore(&dev->lock, flags);
-
+	frmnet_purge_responses(dev);
 }
 
 static int
@@ -876,11 +889,11 @@
 
 		status = usb_ep_queue(dev->notify, req, GFP_ATOMIC);
 		if (status) {
-			atomic_dec(&dev->notify_count);
 			spin_lock_irqsave(&dev->lock, flags);
-			cpkt = list_first_entry(&dev->cpkt_resp_q,
+			if (!list_empty(&dev->cpkt_resp_q)) {
+				atomic_dec(&dev->notify_count);
+				cpkt = list_first_entry(&dev->cpkt_resp_q,
 						struct rmnet_ctrl_pkt, list);
-			if (cpkt) {
 				list_del(&cpkt->list);
 				rmnet_free_ctrl_pkt(cpkt);
 			}
@@ -1172,6 +1185,7 @@
 
 	nr_rmnet_ports = 0;
 	no_ctrl_smd_ports = 0;
+	no_ctrl_qti_ports = 0;
 	no_data_bam_ports = 0;
 	no_data_bam2bam_ports = 0;
 	no_ctrl_hsic_ports = 0;
@@ -1217,6 +1231,10 @@
 		rmnet_port->ctrl_xport_num = no_ctrl_smd_ports;
 		no_ctrl_smd_ports++;
 		break;
+	case USB_GADGET_XPORT_QTI:
+		rmnet_port->ctrl_xport_num = no_ctrl_qti_ports;
+		no_ctrl_qti_ports++;
+		break;
 	case USB_GADGET_XPORT_HSIC:
 		rmnet_port->ctrl_xport_num = no_ctrl_hsic_ports;
 		no_ctrl_hsic_ports++;
@@ -1270,6 +1288,7 @@
 
 	nr_rmnet_ports = 0;
 	no_ctrl_smd_ports = 0;
+	no_ctrl_qti_ports = 0;
 	no_data_bam_ports = 0;
 	no_ctrl_hsic_ports = 0;
 	no_data_hsic_ports = 0;
diff --git a/drivers/usb/gadget/f_rmnet.h b/drivers/usb/gadget/f_rmnet.h
index 2d816c6..f4375ba 100644
--- a/drivers/usb/gadget/f_rmnet.h
+++ b/drivers/usb/gadget/f_rmnet.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/usb/gadget/f_rmnet_sdio.c b/drivers/usb/gadget/f_rmnet_sdio.c
index 8019356..46e6b12 100644
--- a/drivers/usb/gadget/f_rmnet_sdio.c
+++ b/drivers/usb/gadget/f_rmnet_sdio.c
@@ -5,7 +5,7 @@
  * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
  * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
  * Copyright (C) 2008 Nokia Corporation
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * 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 as published by
diff --git a/drivers/usb/gadget/f_rmnet_smd.c b/drivers/usb/gadget/f_rmnet_smd.c
index e8c1f2a..8aec34f 100644
--- a/drivers/usb/gadget/f_rmnet_smd.c
+++ b/drivers/usb/gadget/f_rmnet_smd.c
@@ -5,7 +5,7 @@
  * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
  * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
  * Copyright (C) 2008 Nokia Corporation
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * 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 as published by
diff --git a/drivers/usb/gadget/f_rmnet_smd_sdio.c b/drivers/usb/gadget/f_rmnet_smd_sdio.c
index 175afe3..aa6c99a 100644
--- a/drivers/usb/gadget/f_rmnet_smd_sdio.c
+++ b/drivers/usb/gadget/f_rmnet_smd_sdio.c
@@ -5,7 +5,7 @@
  * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
  * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
  * Copyright (C) 2008 Nokia Corporation
- * Copyright (c) 2011 Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
index 288611d..f3c6481 100644
--- a/drivers/usb/gadget/f_rndis.c
+++ b/drivers/usb/gadget/f_rndis.c
@@ -412,9 +412,14 @@
 static void rndis_response_complete(struct usb_ep *ep, struct usb_request *req)
 {
 	struct f_rndis			*rndis = req->context;
-	struct usb_composite_dev	*cdev = rndis->port.func.config->cdev;
+	struct usb_composite_dev	*cdev;
 	int				status = req->status;
 
+	if (!rndis->port.func.config || !rndis->port.func.config->cdev)
+		return;
+	else
+		cdev = rndis->port.func.config->cdev;
+
 	/* after TX:
 	 *  - USB_CDC_GET_ENCAPSULATED_RESPONSE (ep0/control)
 	 *  - RNDIS_RESPONSE_AVAILABLE (status/irq)
@@ -451,10 +456,15 @@
 static void rndis_command_complete(struct usb_ep *ep, struct usb_request *req)
 {
 	struct f_rndis			*rndis = req->context;
-	struct usb_composite_dev	*cdev = rndis->port.func.config->cdev;
+	struct usb_composite_dev	*cdev;
 	int				status;
 	rndis_init_msg_type		*buf;
 
+	if (!rndis->port.func.config || !rndis->port.func.config->cdev)
+		return;
+	else
+		cdev = rndis->port.func.config->cdev;
+
 	/* received RNDIS command from USB_CDC_SEND_ENCAPSULATED_COMMAND */
 //	spin_lock(&dev->lock);
 	status = rndis_msg_parser(rndis->config, (u8 *) req->buf);
diff --git a/drivers/usb/gadget/msm72k_udc.c b/drivers/usb/gadget/msm72k_udc.c
index b408bfd..e35a60e 100644
--- a/drivers/usb/gadget/msm72k_udc.c
+++ b/drivers/usb/gadget/msm72k_udc.c
@@ -2,7 +2,7 @@
  * Driver for HighSpeed USB Client Controller in MSM7K
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
  * Author: Mike Lockwood <lockwood@android.com>
  *         Brian Swetland <swetland@google.com>
  *
@@ -1259,6 +1259,9 @@
 	struct msm_request *req, *next_req = NULL;
 	unsigned long flags;
 
+	if (!ept->req)
+		return;
+
 	/* inactive endpoints have nothing to do here */
 	if (ept->ep.maxpacket == 0)
 		return;
@@ -1303,9 +1306,13 @@
 static irqreturn_t usb_interrupt(int irq, void *data)
 {
 	struct usb_info *ui = data;
+	struct msm_otg *dev = to_msm_otg(ui->xceiv);
 	unsigned n;
 	unsigned long flags;
 
+	if (atomic_read(&dev->in_lpm))
+		return IRQ_NONE;
+
 	n = readl(USB_USBSTS);
 	writel(n, USB_USBSTS);
 
@@ -1649,6 +1656,20 @@
 				usb_phy_set_power(ui->xceiv, 0);
 
 				if (ui->irq) {
+					/* Disable and acknowledge all
+					 * USB interrupts before freeing
+					 * irq, so that no USB spurious
+					 * interrupt occurs during USB cable
+					 * disconnect which may lead to
+					 * IRQ nobody cared error.
+					 */
+					writel_relaxed(0, USB_USBINTR);
+					writel_relaxed(readl_relaxed(USB_USBSTS)
+								, USB_USBSTS);
+					/* Ensure that above STOREs are
+					 * completed before enabling
+					 * interrupts */
+					wmb();
 					free_irq(ui->irq, ui);
 					ui->irq = 0;
 				}
@@ -2188,6 +2209,9 @@
 	struct msm_endpoint *ep = to_msm_endpoint(_ep);
 	struct usb_info *ui = ep->ui;
 
+	if (!atomic_read(&ui->softconnect))
+		return -ENODEV;
+
 	if (ep == &ui->ep0in) {
 		struct msm_request *r = to_msm_request(req);
 		if (!req->length)
@@ -2215,6 +2239,13 @@
 	struct msm_request *temp_req;
 	unsigned long flags;
 
+	if (ep->num == 0) {
+		/* Flush both out and in control endpoints */
+		flush_endpoint(&ui->ep0out);
+		flush_endpoint(&ui->ep0in);
+		return 0;
+	}
+
 	if (!(ui && req && ep->req))
 		return -EINVAL;
 
diff --git a/drivers/usb/gadget/qcom_maemo.c b/drivers/usb/gadget/qcom_maemo.c
index 39686c4..2fb8be0 100644
--- a/drivers/usb/gadget/qcom_maemo.c
+++ b/drivers/usb/gadget/qcom_maemo.c
@@ -4,9 +4,9 @@
  * Copyright (C) 2008 David Brownell
  * Copyright (C) 2008 Nokia Corporation
  * Copyright (C) 2009 Samsung Electronics
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, The Linux Foundation. All rights reserved.
  *
- * This program from the Code Aurora Forum is free software; you can
+ * This program from The Linux Foundation is free software; you can
  * redistribute it and/or modify it under the GNU General Public License
  * version 2 and only version 2 as published by the Free Software Foundation.
  * The original work available from [git.kernel.org ] is subject to the
diff --git a/drivers/usb/gadget/u_bam.c b/drivers/usb/gadget/u_bam.c
index aa93a7d..a2997e9 100644
--- a/drivers/usb/gadget/u_bam.c
+++ b/drivers/usb/gadget/u_bam.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, 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
@@ -137,6 +137,7 @@
 static void gbam_start_rx(struct gbam_port *port);
 static void gbam_start_endless_rx(struct gbam_port *port);
 static void gbam_start_endless_tx(struct gbam_port *port);
+static int gbam_peer_reset_cb(void *param);
 
 /*---------------misc functions---------------- */
 static void gbam_free_requests(struct usb_ep *ep, struct list_head *head)
@@ -219,7 +220,7 @@
 		ret = usb_ep_queue(ep, req, GFP_ATOMIC);
 		spin_lock(&port->port_lock_dl);
 		if (ret) {
-			pr_err("%s: usb epIn failed\n", __func__);
+			pr_err("%s: usb epIn failed with %d\n", __func__, ret);
 			list_add(&req->list, &d->tx_idle);
 			dev_kfree_skb_any(skb);
 			break;
@@ -516,7 +517,8 @@
 			dev_kfree_skb_any(skb);
 
 			if (printk_ratelimit())
-				pr_err("%s: rx queue failed\n", __func__);
+				pr_err("%s: rx queue failed %d\n",
+							__func__, ret);
 
 			if (port->port_usb)
 				list_add(&req->list, &d->rx_idle);
@@ -533,6 +535,9 @@
 	struct bam_ch_info *d = &port->data_ch;
 	int status;
 
+	if (!port->port_usb)
+		return;
+
 	status = usb_ep_queue(port->port_usb->out, d->rx_req, GFP_ATOMIC);
 	if (status)
 		pr_err("%s: error enqueuing transfer, %d\n", __func__, status);
@@ -543,6 +548,9 @@
 	struct bam_ch_info *d = &port->data_ch;
 	int status;
 
+	if (!port->port_usb)
+		return;
+
 	status = usb_ep_queue(port->port_usb->in, d->tx_req, GFP_ATOMIC);
 	if (status)
 		pr_err("%s: error enqueuing transfer, %d\n", __func__, status);
@@ -574,6 +582,11 @@
 
 	spin_unlock_irqrestore(&port->port_lock_ul, flags);
 	spin_lock_irqsave(&port->port_lock_dl, flags);
+	if (!port->port_usb) {
+		gbam_free_requests(ep, &d->rx_idle);
+		spin_unlock_irqrestore(&port->port_lock_dl, flags);
+		return;
+	}
 	ep = port->port_usb->in;
 	ret = gbam_alloc_requests(ep, &d->tx_idle, bam_mux_tx_q_size,
 			gbam_epin_complete, GFP_ATOMIC);
@@ -644,7 +657,8 @@
 
 static void gbam2bam_disconnect_work(struct work_struct *w)
 {
-	struct gbam_port *port = container_of(w, struct gbam_port, connect_w);
+	struct gbam_port *port =
+			container_of(w, struct gbam_port, disconnect_w);
 	struct bam_ch_info *d = &port->data_ch;
 	int ret;
 
@@ -756,9 +770,93 @@
 	gbam_start_endless_rx(port);
 	gbam_start_endless_tx(port);
 
+	if (d->trans == USB_GADGET_XPORT_BAM2BAM && port->port_num == 0) {
+		/* Register for peer reset callback */
+		usb_bam_register_peer_reset_cb(d->connection_idx,
+			gbam_peer_reset_cb, port);
+
+		ret = usb_bam_client_ready(true);
+		if (ret) {
+			pr_err("%s: usb_bam_client_ready failed: err:%d\n",
+				__func__, ret);
+			return;
+		}
+	}
+
 	pr_debug("%s: done\n", __func__);
 }
 
+static int gbam_peer_reset_cb(void *param)
+{
+	struct gbam_port	*port = (struct gbam_port *)param;
+	struct bam_ch_info *d;
+	struct f_rmnet		*dev;
+	struct usb_gadget *gadget;
+	int ret;
+	bool reenable_eps = false;
+
+	dev = port_to_rmnet(port->gr);
+	d = &port->data_ch;
+
+	gadget = dev->cdev->gadget;
+
+	pr_debug("%s: reset by peer\n", __func__);
+
+	/* Disable the relevant EPs if currently EPs are enabled */
+	if (port->port_usb && port->port_usb->in &&
+	  port->port_usb->in->driver_data) {
+		usb_ep_disable(port->port_usb->out);
+		usb_ep_disable(port->port_usb->in);
+
+		port->port_usb->in->driver_data = NULL;
+		port->port_usb->out->driver_data = NULL;
+		reenable_eps = true;
+	}
+
+	/* Disable BAM */
+	msm_hw_bam_disable(1);
+
+	/* Reset BAM */
+	ret = usb_bam_reset();
+	if (ret) {
+		pr_err("%s: BAM reset failed %d\n", __func__, ret);
+		goto reenable_eps;
+	}
+
+	/* Enable BAM */
+	msm_hw_bam_disable(0);
+
+reenable_eps:
+	/* Re-Enable the relevant EPs, if EPs were originally enabled */
+	if (reenable_eps) {
+		ret = usb_ep_enable(port->port_usb->in);
+		if (ret) {
+			pr_err("%s: usb_ep_enable failed eptype:IN ep:%p",
+				__func__, port->port_usb->in);
+			return ret;
+		}
+		port->port_usb->in->driver_data = port;
+
+		ret = usb_ep_enable(port->port_usb->out);
+		if (ret) {
+			pr_err("%s: usb_ep_enable failed eptype:OUT ep:%p",
+				__func__, port->port_usb->out);
+			port->port_usb->in->driver_data = 0;
+			return ret;
+		}
+		port->port_usb->out->driver_data = port;
+
+		gbam_start_endless_rx(port);
+		gbam_start_endless_tx(port);
+	}
+
+	/* Unregister the peer reset callback */
+	if (d->trans == USB_GADGET_XPORT_BAM2BAM && port->port_num == 0)
+		usb_bam_register_peer_reset_cb(d->connection_idx, NULL, NULL);
+
+	return 0;
+}
+
 /* BAM data channel ready, allow attempt to open */
 static int gbam_data_ch_probe(struct platform_device *pdev)
 {
@@ -1092,6 +1190,14 @@
 	if (trans == USB_GADGET_XPORT_BAM ||
 		trans == USB_GADGET_XPORT_BAM2BAM_IPA)
 		queue_work(gbam_wq, &port->disconnect_w);
+	else if (trans == USB_GADGET_XPORT_BAM2BAM) {
+		if (port_num == 0) {
+			if (usb_bam_client_ready(false)) {
+				pr_err("%s: usb_bam_client_ready failed\n",
+					__func__);
+			}
+		}
+	}
 }
 
 int gbam_connect(struct grmnet *gr, u8 port_num,
diff --git a/drivers/usb/gadget/u_bam_data.c b/drivers/usb/gadget/u_bam_data.c
index 32f683e..8df06a4 100644
--- a/drivers/usb/gadget/u_bam_data.c
+++ b/drivers/usb/gadget/u_bam_data.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -22,9 +22,10 @@
 #include <linux/usb/gadget.h>
 
 #include <mach/bam_dmux.h>
-#include <mach/usb_gadget_xport.h>
 #include <mach/usb_bam.h>
 
+#include "u_bam_data.h"
+
 #define BAM2BAM_DATA_N_PORTS	1
 
 static struct workqueue_struct *bam_data_wq;
@@ -34,12 +35,6 @@
 #define SPS_PARAMS_TBE		        BIT(6)
 #define MSM_VENDOR_ID			BIT(16)
 
-struct data_port {
-	struct usb_composite_dev	*cdev;
-	struct usb_ep			*in;
-	struct usb_ep			*out;
-};
-
 struct bam_data_ch_info {
 	unsigned long		flags;
 	unsigned		id;
@@ -53,6 +48,10 @@
 	u32			src_pipe_idx;
 	u32			dst_pipe_idx;
 	u8			connection_idx;
+
+	enum function_type			func_type;
+	enum transport_type			trans;
+	struct usb_bam_connect_ipa_params	ipa_params;
 };
 
 struct bam_data_port {
@@ -73,7 +72,7 @@
 {
 	int status = req->status;
 
-	pr_info("status: %d\n", status);
+	pr_debug("%s: status: %d\n", __func__, status);
 }
 
 static void bam_data_endless_tx_complete(struct usb_ep *ep,
@@ -81,7 +80,7 @@
 {
 	int status = req->status;
 
-	pr_info("status: %d\n", status);
+	pr_debug("%s: status: %d\n", __func__, status);
 }
 
 static void bam_data_start_endless_rx(struct bam_data_port *port)
@@ -89,6 +88,9 @@
 	struct bam_data_ch_info *d = &port->data_ch;
 	int status;
 
+	if (!port->port_usb)
+		return;
+
 	status = usb_ep_queue(port->port_usb->out, d->rx_req, GFP_ATOMIC);
 	if (status)
 		pr_err("error enqueuing transfer, %d\n", status);
@@ -99,32 +101,93 @@
 	struct bam_data_ch_info *d = &port->data_ch;
 	int status;
 
+	if (!port->port_usb)
+		return;
+
 	status = usb_ep_queue(port->port_usb->in, d->tx_req, GFP_ATOMIC);
 	if (status)
 		pr_err("error enqueuing transfer, %d\n", status);
 }
 
+static int bam_data_peer_reset_cb(void *param)
+{
+	struct bam_data_port	*port = (struct bam_data_port *)param;
+	struct bam_data_ch_info *d;
+	int ret;
+	bool reenable_eps = false;
+
+	d = &port->data_ch;
+
+	pr_debug("%s: reset by peer\n", __func__);
+
+	/* Disable the relevant EPs if currently EPs are enabled */
+	if (port->port_usb && port->port_usb->in &&
+	  port->port_usb->in->driver_data) {
+		usb_ep_disable(port->port_usb->out);
+		usb_ep_disable(port->port_usb->in);
+
+		port->port_usb->in->driver_data = NULL;
+		port->port_usb->out->driver_data = NULL;
+		reenable_eps = true;
+	}
+
+	/* Disable BAM */
+	msm_hw_bam_disable(1);
+
+	/* Reset BAM */
+	ret = usb_bam_reset();
+	if (ret) {
+		pr_err("%s: BAM reset failed %d\n", __func__, ret);
+		goto reenable_eps;
+	}
+
+	/* Enable BAM */
+	msm_hw_bam_disable(0);
+
+reenable_eps:
+	/* Re-Enable the relevant EPs, if EPs were originally enabled */
+	if (reenable_eps) {
+		ret = usb_ep_enable(port->port_usb->in);
+		if (ret) {
+			pr_err("%s: usb_ep_enable failed eptype:IN ep:%p",
+				__func__, port->port_usb->in);
+			return ret;
+		}
+		port->port_usb->in->driver_data = port;
+
+		ret = usb_ep_enable(port->port_usb->out);
+		if (ret) {
+			pr_err("%s: usb_ep_enable failed eptype:OUT ep:%p",
+				__func__, port->port_usb->out);
+			port->port_usb->in->driver_data = 0;
+			return ret;
+		}
+		port->port_usb->out->driver_data = port;
+
+		bam_data_start_endless_rx(port);
+		bam_data_start_endless_tx(port);
+	}
+
+	/* Unregister the peer reset callback */
+	usb_bam_register_peer_reset_cb(d->connection_idx, NULL, NULL);
+
+	return 0;
+}
+
 static void bam2bam_data_disconnect_work(struct work_struct *w)
 {
 	struct bam_data_port *port =
 			container_of(w, struct bam_data_port, disconnect_w);
+	struct bam_data_ch_info *d = &port->data_ch;
+	int ret;
 
-	pr_info("Enter");
-
-	/* disable endpoints */
-	if (!port->port_usb || !port->port_usb->out || !port->port_usb->in) {
-		pr_err("port_usb->out/in == NULL. Exit");
-		return;
+	if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
+		if (d->func_type == USB_FUNC_ECM)
+			ecm_ipa_disconnect(d->ipa_params.priv);
+		ret = usb_bam_disconnect_ipa(d->connection_idx, &d->ipa_params);
+		if (ret)
+			pr_err("usb_bam_disconnect_ipa failed: err:%d\n", ret);
 	}
-	usb_ep_disable(port->port_usb->out);
-	usb_ep_disable(port->port_usb->in);
-
-	port->port_usb->in->driver_data = NULL;
-	port->port_usb->out->driver_data = NULL;
-
-	port->port_usb = 0;
-
-	pr_info("Exit");
 }
 
 static void bam2bam_data_connect_work(struct work_struct *w)
@@ -135,16 +198,51 @@
 	u32 sps_params;
 	int ret;
 
-	pr_info("Enter");
+	pr_debug("%s: Connect workqueue started", __func__);
 
-	ret = usb_bam_connect(d->connection_idx, &d->src_pipe_idx,
+	if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
+		d->ipa_params.client = IPA_CLIENT_USB_CONS;
+		d->ipa_params.dir = PEER_PERIPHERAL_TO_USB;
+		if (d->func_type == USB_FUNC_ECM) {
+			d->ipa_params.notify = ecm_qc_get_ipa_tx_cb();
+			d->ipa_params.priv = ecm_qc_get_ipa_priv();
+		}
+		ret = usb_bam_connect_ipa(&d->ipa_params);
+		if (ret) {
+			pr_err("%s: usb_bam_connect_ipa failed: err:%d\n",
+				__func__, ret);
+			return;
+		}
+
+		d->ipa_params.client = IPA_CLIENT_USB_PROD;
+		d->ipa_params.dir = USB_TO_PEER_PERIPHERAL;
+		if (d->func_type == USB_FUNC_ECM) {
+			d->ipa_params.notify = ecm_qc_get_ipa_rx_cb();
+			d->ipa_params.priv = ecm_qc_get_ipa_priv();
+		}
+		ret = usb_bam_connect_ipa(&d->ipa_params);
+		if (ret) {
+			pr_err("%s: usb_bam_connect_ipa failed: err:%d\n",
+				__func__, ret);
+			return;
+		}
+		if (d->func_type == USB_FUNC_ECM) {
+			ret = ecm_ipa_connect(d->ipa_params.cons_clnt_hdl,
+				d->ipa_params.prod_clnt_hdl,
+				d->ipa_params.priv);
+			if (ret) {
+				pr_err("%s: failed to connect IPA: err:%d\n",
+					__func__, ret);
+				return;
+			}
+		}
+	} else { /* transport type is USB_GADGET_XPORT_BAM2BAM */
+		ret = usb_bam_connect(d->connection_idx, &d->src_pipe_idx,
 						  &d->dst_pipe_idx);
-	d->src_pipe_idx = 11;
-	d->dst_pipe_idx = 10;
-
-	if (ret) {
-		pr_err("usb_bam_connect failed: err:%d\n", ret);
-		return;
+		if (ret) {
+			pr_err("usb_bam_connect failed: err:%d\n", ret);
+			return;
+		}
 	}
 
 	if (!port->port_usb) {
@@ -182,7 +280,20 @@
 	bam_data_start_endless_rx(port);
 	bam_data_start_endless_tx(port);
 
-	pr_info("Done\n");
+	/* Register for peer reset callback if USB_GADGET_XPORT_BAM2BAM */
+	if (d->trans != USB_GADGET_XPORT_BAM2BAM_IPA) {
+		usb_bam_register_peer_reset_cb(d->connection_idx,
+			bam_data_peer_reset_cb, port);
+
+		ret = usb_bam_client_ready(true);
+		if (ret) {
+			pr_err("%s: usb_bam_client_ready failed: err:%d\n",
+			__func__, ret);
+			return;
+		}
+	}
+
+	pr_debug("%s: Connect workqueue done", __func__);
 }
 
 static void bam2bam_data_port_free(int portno)
@@ -210,7 +321,7 @@
 	d->port = port;
 	bam2bam_data_ports[portno] = port;
 
-	pr_info("port:%p portno:%d\n", port, portno);
+	pr_debug("port:%p portno:%d\n", port, portno);
 
 	return 0;
 }
@@ -220,7 +331,7 @@
 	struct bam_data_port	*port;
 	struct bam_data_ch_info	*d;
 
-	pr_info("dev:%p port#%d\n", gr, port_num);
+	pr_debug("dev:%p port#%d\n", gr, port_num);
 
 	if (port_num >= n_bam2bam_data_ports) {
 		pr_err("invalid bam2bam portno#%d\n", port_num);
@@ -228,26 +339,43 @@
 	}
 
 	if (!gr) {
-		pr_err("mbim data port is null\n");
+		pr_err("data port is null\n");
 		return;
 	}
 
 	port = bam2bam_data_ports[port_num];
 
-	d = &port->data_ch;
-	port->port_usb = gr;
+	if (port->port_usb && port->port_usb->in &&
+	  port->port_usb->in->driver_data) {
+		/* disable endpoints */
+		usb_ep_disable(port->port_usb->out);
+		usb_ep_disable(port->port_usb->in);
 
-	queue_work(bam_data_wq, &port->disconnect_w);
+		port->port_usb->in->driver_data = NULL;
+		port->port_usb->out->driver_data = NULL;
+
+		port->port_usb = 0;
+	}
+
+	d = &port->data_ch;
+	if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA)
+		queue_work(gbam_wq, &port->disconnect_w);
+	else {
+		if (usb_bam_client_ready(false)) {
+			pr_err("%s: usb_bam_client_ready failed\n",
+				__func__);
+		}
+	}
 }
 
 int bam_data_connect(struct data_port *gr, u8 port_num,
-				 u8 connection_idx)
+	enum transport_type trans, u8 connection_idx, enum function_type func)
 {
 	struct bam_data_port	*port;
 	struct bam_data_ch_info	*d;
 	int			ret;
 
-	pr_info("dev:%p port#%d\n", gr, port_num);
+	pr_debug("dev:%p port#%d\n", gr, port_num);
 
 	if (port_num >= n_bam2bam_data_ports) {
 		pr_err("invalid portno#%d\n", port_num);
@@ -255,7 +383,7 @@
 	}
 
 	if (!gr) {
-		pr_err("mbim data port is null\n");
+		pr_err("data port is null\n");
 		return -ENODEV;
 	}
 
@@ -282,6 +410,16 @@
 
 	d->connection_idx = connection_idx;
 
+	d->trans = trans;
+
+	if (trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
+		d->ipa_params.src_pipe = &(d->src_pipe_idx);
+		d->ipa_params.dst_pipe = &(d->dst_pipe_idx);
+		d->ipa_params.idx = connection_idx;
+	}
+
+	d->func_type = func;
+
 	queue_work(bam_data_wq, &port->connect_w);
 
 	return 0;
@@ -292,7 +430,7 @@
 	int	i;
 	int	ret;
 
-	pr_info("requested %d BAM2BAM ports", no_bam2bam_port);
+	pr_debug("requested %d BAM2BAM ports", no_bam2bam_port);
 
 	if (!no_bam2bam_port || no_bam2bam_port > BAM2BAM_DATA_N_PORTS) {
 		pr_err("Invalid num of ports count:%d\n", no_bam2bam_port);
@@ -331,7 +469,7 @@
 	struct bam_data_port *port = (struct bam_data_port *)param;
 	struct data_port *d_port = port->port_usb;
 
-	pr_info("%s: woken up by peer\n", __func__);
+	pr_debug("%s: woken up by peer\n", __func__);
 
 	if (!d_port) {
 		pr_err("FAILED: d_port == NULL");
@@ -360,7 +498,7 @@
 	port = bam2bam_data_ports[port_num];
 	d = &port->data_ch;
 
-	pr_info("%s: suspended port %d\n", __func__, port_num);
+	pr_debug("%s: suspended port %d\n", __func__, port_num);
 	usb_bam_register_wake_cb(d->connection_idx, bam_data_wake_cb, port);
 }
 
@@ -373,7 +511,7 @@
 	port = bam2bam_data_ports[port_num];
 	d = &port->data_ch;
 
-	pr_info("%s: resumed port %d\n", __func__, port_num);
+	pr_debug("%s: resumed port %d\n", __func__, port_num);
 	usb_bam_register_wake_cb(d->connection_idx, NULL, NULL);
 }
 
diff --git a/drivers/usb/gadget/u_bam_data.h b/drivers/usb/gadget/u_bam_data.h
new file mode 100644
index 0000000..71a01b9
--- /dev/null
+++ b/drivers/usb/gadget/u_bam_data.h
@@ -0,0 +1,41 @@
+/* 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 __U_BAM_DATA_H
+#define __U_BAM_DATA_H
+
+#include <mach/usb_gadget_xport.h>
+
+enum function_type {
+	USB_FUNC_ECM,
+	USB_FUNC_MBIM,
+	USB_FUNC_RNDIS,
+};
+
+struct data_port {
+	struct usb_composite_dev	*cdev;
+	struct usb_ep			*in;
+	struct usb_ep			*out;
+};
+
+void bam_data_disconnect(struct data_port *gr, u8 port_num);
+
+int bam_data_connect(struct data_port *gr, u8 port_num,
+	enum transport_type trans, u8 connection_idx, enum function_type func);
+
+int bam_data_setup(unsigned int no_bam2bam_port);
+
+void bam_data_suspend(u8 port_num);
+
+void bam_data_resume(u8 port_num);
+
+#endif /* __U_BAM_DATA_H */
diff --git a/drivers/usb/gadget/u_ctrl_hsic.c b/drivers/usb/gadget/u_ctrl_hsic.c
index fdfab96..0f93ad4 100644
--- a/drivers/usb/gadget/u_ctrl_hsic.c
+++ b/drivers/usb/gadget/u_ctrl_hsic.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/usb/gadget/u_ctrl_hsuart.c b/drivers/usb/gadget/u_ctrl_hsuart.c
index a55960e..a9bd53e 100644
--- a/drivers/usb/gadget/u_ctrl_hsuart.c
+++ b/drivers/usb/gadget/u_ctrl_hsuart.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/usb/gadget/u_data_hsic.c b/drivers/usb/gadget/u_data_hsic.c
index 746c041..3932bbc 100644
--- a/drivers/usb/gadget/u_data_hsic.c
+++ b/drivers/usb/gadget/u_data_hsic.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, 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
@@ -634,10 +634,10 @@
 
 	ghsic_data_free_buffers(port);
 
-	data_bridge_close(port->brdg.ch_id);
-
+	cancel_work_sync(&port->connect_w);
+	if (test_and_clear_bit(CH_OPENED, &port->bridge_sts))
+		data_bridge_close(port->brdg.ch_id);
 	clear_bit(CH_READY, &port->bridge_sts);
-	clear_bit(CH_OPENED, &port->bridge_sts);
 
 	return 0;
 }
@@ -729,11 +729,15 @@
 	ghsic_data_free_buffers(port);
 
 	/* disable endpoints */
-	if (port->in)
-		usb_ep_disable(port->out);
-
-	if (port->out)
+	if (port->in) {
 		usb_ep_disable(port->in);
+		port->in->driver_data = NULL;
+	}
+
+	if (port->out) {
+		usb_ep_disable(port->out);
+		port->out->driver_data = NULL;
+	}
 
 	atomic_set(&port->connected, 0);
 
diff --git a/drivers/usb/gadget/u_data_hsuart.c b/drivers/usb/gadget/u_data_hsuart.c
index 4d88ea5..8005a4a 100644
--- a/drivers/usb/gadget/u_data_hsuart.c
+++ b/drivers/usb/gadget/u_data_hsuart.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
index f7b908b..2d974ab 100644
--- a/drivers/usb/gadget/u_ether.c
+++ b/drivers/usb/gadget/u_ether.c
@@ -474,13 +474,26 @@
 static void tx_complete(struct usb_ep *ep, struct usb_request *req)
 {
 	struct sk_buff	*skb = req->context;
-	struct eth_dev	*dev = ep->driver_data;
-	struct net_device *net = dev->net;
+	struct eth_dev	*dev;
+	struct net_device *net;
 	struct usb_request *new_req;
 	struct usb_ep *in;
 	int length;
 	int retval;
 
+	if (!ep->driver_data) {
+		usb_ep_free_request(ep, req);
+		return;
+	}
+
+	dev = ep->driver_data;
+	net = dev->net;
+
+	if (!dev->port_usb) {
+		usb_ep_free_request(ep, req);
+		return;
+	}
+
 	switch (req->status) {
 	default:
 		dev->net->stats.tx_errors++;
@@ -597,11 +610,13 @@
 	unsigned long		flags;
 	struct usb_ep		*in;
 	u16			cdc_filter;
+	bool			multi_pkt_xfer = false;
 
 	spin_lock_irqsave(&dev->lock, flags);
 	if (dev->port_usb) {
 		in = dev->port_usb->in_ep;
 		cdc_filter = dev->port_usb->cdc_filter;
+		multi_pkt_xfer = dev->port_usb->multi_pkt_xfer;
 	} else {
 		in = NULL;
 		cdc_filter = 0;
@@ -614,7 +629,7 @@
 	}
 
 	/* Allocate memory for tx_reqs to support multi packet transfer */
-	if (dev->port_usb->multi_pkt_xfer && !dev->tx_req_bufsize)
+	if (multi_pkt_xfer && !dev->tx_req_bufsize)
 		alloc_tx_buffer(dev);
 
 	/* apply outgoing CDC or RNDIS filters */
@@ -677,7 +692,7 @@
 	dev->tx_skb_hold_count++;
 	spin_unlock_irqrestore(&dev->req_lock, flags);
 
-	if (dev->port_usb->multi_pkt_xfer) {
+	if (multi_pkt_xfer) {
 		memcpy(req->buf + req->length, skb->data, skb->len);
 		req->length = req->length + skb->len;
 		length = req->length;
@@ -749,7 +764,7 @@
 	}
 
 	if (retval) {
-		if (!dev->port_usb->multi_pkt_xfer)
+		if (!multi_pkt_xfer)
 			dev_kfree_skb_any(skb);
 drop:
 		dev->net->stats.tx_dropped++;
diff --git a/drivers/usb/gadget/u_qc_ether.c b/drivers/usb/gadget/u_qc_ether.c
index bba2ca6..e10ec25 100644
--- a/drivers/usb/gadget/u_qc_ether.c
+++ b/drivers/usb/gadget/u_qc_ether.c
@@ -4,7 +4,7 @@
  * Copyright (C) 2003-2005,2008 David Brownell
  * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
  * Copyright (C) 2008 Nokia Corporation
- * Copyright (c) 2012, Code Aurora Forum. 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
@@ -62,7 +62,7 @@
 	 * or updating its backlink port_usb->ioport
 	 */
 	spinlock_t		lock;
-	struct qc_gether		*port_usb;
+	struct qc_gether	*port_usb;
 
 	struct net_device	*net;
 	struct usb_gadget	*gadget;
@@ -235,6 +235,14 @@
 	.name	= "gadget",
 };
 
+void gether_qc_get_macs(u8 dev_mac[ETH_ALEN], u8 host_mac[ETH_ALEN])
+{
+	if (get_qc_ether_addr(qc_dev_addr, dev_mac))
+		pr_debug("using random dev_mac ethernet address\n");
+	if (get_qc_ether_addr(qc_host_addr, host_mac))
+		pr_debug("using random host_mac ethernet address\n");
+}
+
 /**
  * gether_qc_setup - initialize one ethernet-over-usb link
  * @g: gadget to associated with these links
@@ -320,6 +328,7 @@
 
 /**
  * gether_qc_cleanup_name - remove Ethernet-over-USB device
+ * @netname: name for network device (for example, "usb")
  * Context: may sleep
  *
  * This is called to free all resources allocated by @gether_qc_setup().
@@ -343,6 +352,7 @@
  * is active
  * @link: the USB link, set up with endpoints, descriptors matching
  *	current device speed, and any framing wrapper(s) set up.
+ * @netname: name for network device (for example, "usb")
  * Context: irqs blocked
  *
  * This is called to let the network layer know the connection
@@ -391,6 +401,7 @@
  * gether_qc_disconnect_name - notify network layer that USB
  * link is inactive
  * @link: the USB link, on which gether_connect() was called
+ * @netname: name for network device (for example, "usb")
  * Context: irqs blocked
  *
  * This is called to let the network layer know the connection
diff --git a/drivers/usb/gadget/u_qc_ether.h b/drivers/usb/gadget/u_qc_ether.h
index d91e805..25562da 100644
--- a/drivers/usb/gadget/u_qc_ether.h
+++ b/drivers/usb/gadget/u_qc_ether.h
@@ -4,7 +4,7 @@
  * Copyright (C) 2003-2005,2008 David Brownell
  * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
  * Copyright (C) 2008 Nokia Corporation
- * Copyright (c) 2012, Code Aurora Forum. 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
@@ -49,7 +49,7 @@
 	struct usb_function		func;
 
 	/* updated by gether_{connect,disconnect} */
-	struct eth_qc_dev			*ioport;
+	struct eth_qc_dev		*ioport;
 
 	/* endpoints handle full and/or high speeds */
 	struct usb_ep			*in_ep;
@@ -61,10 +61,7 @@
 
 	/* hooks for added framing, as needed for RNDIS and EEM. */
 	u32				header_len;
-	/* NCM requires fixed size bundles */
-	bool				is_fixed;
-	u32				fixed_out_len;
-	u32				fixed_in_len;
+
 	struct sk_buff			*(*wrap)(struct qc_gether *port,
 						struct sk_buff *skb);
 	int				(*unwrap)(struct qc_gether *port,
@@ -89,10 +86,14 @@
 void gether_qc_disconnect_name(struct qc_gether *link, const char *netname);
 
 /* each configuration may bind one instance of an ethernet link */
-int ecm_qc_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]);
+int ecm_qc_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+				char *xport_name);
 
 int
 rndis_qc_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
 					 u32 vendorID, const char *manufacturer,
 					 u8 maxPktPerXfer);
+
+void gether_qc_get_macs(u8 dev_mac[ETH_ALEN], u8 host_mac[ETH_ALEN]);
+
 #endif /* __U_QC_ETHER_H */
diff --git a/drivers/usb/gadget/u_qdss.c b/drivers/usb/gadget/u_qdss.c
index 028d5e6..2931ace 100644
--- a/drivers/usb/gadget/u_qdss.c
+++ b/drivers/usb/gadget/u_qdss.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -15,8 +15,6 @@
 #include <linux/usb/msm_hsusb.h>
 #include <mach/usb_bam.h>
 
-#define BAM_CONNC_IDX 0 /* USB bam connection index */
-
 struct  usb_qdss_bam_connect_info {
 	u32 usb_bam_pipe_idx;
 	u32 peer_pipe_idx;
@@ -57,17 +55,18 @@
 		pr_err("send_sps_req: usb_ep_queue error\n");
 		return -EIO;
 	}
+
 	return 0;
 }
 
 int set_qdss_data_connection(struct usb_ep *data_ep, u8 data_addr, int enable)
 {
 	int res = 0;
-
+	u8 conn_num = usb_bam_get_qdss_num();
 	pr_debug("set_qdss_data_connection\n");
 
 	if (enable) {
-		res = usb_bam_connect(BAM_CONNC_IDX, NULL,
+		res = usb_bam_connect(conn_num, NULL,
 			&(bam_info.usb_bam_pipe_idx));
 		if (res) {
 			pr_err("usb_bam_connection error\n");
@@ -80,7 +79,7 @@
 			pr_err("qdss_data_connection: memory alloc failed\n");
 			return -ENOMEM;
 		}
-		get_bam2bam_connection_info(BAM_CONNC_IDX,
+		get_bam2bam_connection_info(conn_num,
 			PEER_PERIPHERAL_TO_USB, &bam_info.usb_bam_handle,
 			&bam_info.usb_bam_pipe_idx, &bam_info.peer_pipe_idx,
 			NULL, bam_info.data_fifo);
@@ -89,7 +88,7 @@
 			bam_info.data_fifo->size, bam_info.usb_bam_pipe_idx);
 	} else {
 		kfree(bam_info.data_fifo);
-		res = usb_bam_disconnect_pipe(BAM_CONNC_IDX);
+		res = usb_bam_disconnect_pipe(conn_num);
 		if (res) {
 			pr_err("usb_bam_disconnection error\n");
 			return res;
diff --git a/drivers/usb/gadget/u_rmnet.h b/drivers/usb/gadget/u_rmnet.h
index 0f7c4fb..cea9369 100644
--- a/drivers/usb/gadget/u_rmnet.h
+++ b/drivers/usb/gadget/u_rmnet.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -55,5 +55,7 @@
 int gsmd_ctrl_connect(struct grmnet *gr, int port_num);
 void gsmd_ctrl_disconnect(struct grmnet *gr, u8 port_num);
 int gsmd_ctrl_setup(unsigned int count);
+int gqti_ctrl_connect(struct grmnet *gr);
+void gqti_ctrl_disconnect(struct grmnet *gr);
 
 #endif /* __U_RMNET_H*/
diff --git a/drivers/usb/gadget/u_rmnet_ctrl_qti.c b/drivers/usb/gadget/u_rmnet_ctrl_qti.c
new file mode 100644
index 0000000..e92978f
--- /dev/null
+++ b/drivers/usb/gadget/u_rmnet_ctrl_qti.c
@@ -0,0 +1,519 @@
+/*
+ * 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/wait.h>
+#include <linux/poll.h>
+#include <linux/usb/rmnet_ctrl_qti.h>
+
+#include "u_rmnet.h"
+
+struct rmnet_ctrl_qti_port {
+	struct grmnet		*port_usb;
+
+	bool		is_open;
+
+	atomic_t	connected;
+	atomic_t	line_state;
+
+	atomic_t	open_excl;
+	atomic_t	read_excl;
+	atomic_t	write_excl;
+	atomic_t	ioctl_excl;
+
+	wait_queue_head_t read_wq;
+
+	struct list_head	cpkt_req_q;
+
+	spinlock_t			lock;
+};
+static struct rmnet_ctrl_qti_port *ctrl_port;
+
+static inline int rmnet_ctrl_lock(atomic_t *excl)
+{
+	if (atomic_inc_return(excl) == 1) {
+		return 0;
+	} else {
+		atomic_dec(excl);
+		return -EBUSY;
+	}
+}
+
+static inline void rmnet_ctrl_unlock(atomic_t *excl)
+{
+	atomic_dec(excl);
+}
+
+static void rmnet_ctrl_queue_notify(struct rmnet_ctrl_qti_port *port)
+{
+	unsigned long		flags;
+	struct rmnet_ctrl_pkt	*cpkt = NULL;
+
+	pr_debug("%s: Queue empty packet for QTI", __func__);
+
+	spin_lock_irqsave(&port->lock, flags);
+	if (!port->is_open) {
+		pr_err("%s: rmnet ctrl file handler %p is not open",
+			   __func__, port);
+		spin_unlock_irqrestore(&port->lock, flags);
+		return;
+	}
+
+	cpkt = alloc_rmnet_ctrl_pkt(0, GFP_ATOMIC);
+	if (!cpkt) {
+		pr_err("%s: Unable to allocate reset function pkt\n", __func__);
+		spin_unlock_irqrestore(&port->lock, flags);
+		return;
+	}
+
+	list_add_tail(&cpkt->list, &port->cpkt_req_q);
+	spin_unlock_irqrestore(&port->lock, flags);
+
+	pr_debug("%s: Wake up read queue", __func__);
+	wake_up(&port->read_wq);
+}
+
+static int grmnet_ctrl_qti_send_cpkt_tomodem(u8 portno,
+	void *buf, size_t len)
+{
+	unsigned long		flags;
+	struct rmnet_ctrl_qti_port	*port = ctrl_port;
+	struct rmnet_ctrl_pkt *cpkt;
+
+	if (len > MAX_QTI_PKT_SIZE) {
+		pr_err("given pkt size too big:%d > max_pkt_size:%d\n",
+				len, MAX_QTI_PKT_SIZE);
+		return -EINVAL;
+	}
+
+	cpkt = alloc_rmnet_ctrl_pkt(len, GFP_ATOMIC);
+	if (IS_ERR(cpkt)) {
+		pr_err("%s: Unable to allocate ctrl pkt\n", __func__);
+		return -ENOMEM;
+	}
+
+	memcpy(cpkt->buf, buf, len);
+	cpkt->len = len;
+
+	pr_debug("%s: Add to cpkt_req_q packet with len = %d\n", __func__, len);
+	spin_lock_irqsave(&port->lock, flags);
+
+	/* drop cpkt if port is not open */
+	if (!port->is_open) {
+		pr_err("rmnet file handler %p is not open", port);
+		spin_unlock_irqrestore(&port->lock, flags);
+		free_rmnet_ctrl_pkt(cpkt);
+		return 0;
+	}
+
+	list_add_tail(&cpkt->list, &port->cpkt_req_q);
+	spin_unlock_irqrestore(&port->lock, flags);
+
+	/* wakeup read thread */
+	pr_debug("%s: Wake up read queue", __func__);
+	wake_up(&port->read_wq);
+
+	return 0;
+}
+
+static void
+gqti_ctrl_notify_modem(void *gptr, u8 portno, int val)
+{
+	struct rmnet_ctrl_qti_port	*port = ctrl_port;
+
+	atomic_set(&port->line_state, val);
+
+	/* send 0 len pkt to qti to notify state change */
+	rmnet_ctrl_queue_notify(port);
+}
+
+int gqti_ctrl_connect(struct grmnet *gr)
+{
+	struct rmnet_ctrl_qti_port	*port;
+	unsigned long		flags;
+
+	pr_debug("%s: grmnet:%p\n", __func__, gr);
+
+	if (!gr) {
+		pr_err("%s: grmnet port is null\n", __func__);
+		return -ENODEV;
+	}
+
+	port = ctrl_port;
+
+	spin_lock_irqsave(&port->lock, flags);
+	port->port_usb = gr;
+	gr->send_encap_cmd = grmnet_ctrl_qti_send_cpkt_tomodem;
+	gr->notify_modem = gqti_ctrl_notify_modem;
+	spin_unlock_irqrestore(&port->lock, flags);
+
+	atomic_set(&port->connected, 1);
+	wake_up(&port->read_wq);
+
+	if (port && port->port_usb && port->port_usb->connect)
+		port->port_usb->connect(port->port_usb);
+
+	return 0;
+}
+
+void gqti_ctrl_disconnect(struct grmnet *gr)
+{
+	struct rmnet_ctrl_qti_port	*port = ctrl_port;
+	unsigned long		flags;
+	struct rmnet_ctrl_pkt	*cpkt;
+
+	pr_debug("%s: grmnet:%p\n", __func__, gr);
+
+	if (!gr) {
+		pr_err("%s: grmnet port is null\n", __func__);
+		return;
+	}
+
+	if (port && port->port_usb && port->port_usb->disconnect)
+		port->port_usb->disconnect(port->port_usb);
+
+	atomic_set(&port->connected, 0);
+	atomic_set(&port->line_state, 0);
+	spin_lock_irqsave(&port->lock, flags);
+	port->port_usb = 0;
+	gr->send_encap_cmd = 0;
+	gr->notify_modem = 0;
+
+	while (!list_empty(&port->cpkt_req_q)) {
+		cpkt = list_first_entry(&port->cpkt_req_q,
+					struct rmnet_ctrl_pkt, list);
+
+		list_del(&cpkt->list);
+		free_rmnet_ctrl_pkt(cpkt);
+	}
+
+	spin_unlock_irqrestore(&port->lock, flags);
+
+	/* send 0 len pkt to qti to notify state change */
+	rmnet_ctrl_queue_notify(port);
+}
+
+static int rmnet_ctrl_open(struct inode *ip, struct file *fp)
+{
+	unsigned long		flags;
+
+	pr_debug("Open rmnet_ctrl_qti device file\n");
+
+	if (rmnet_ctrl_lock(&ctrl_port->open_excl)) {
+		pr_debug("Already opened\n");
+		return -EBUSY;
+	}
+
+	fp->private_data = ctrl_port;
+
+	spin_lock_irqsave(&ctrl_port->lock, flags);
+	ctrl_port->is_open = true;
+	spin_unlock_irqrestore(&ctrl_port->lock, flags);
+
+	return 0;
+}
+
+static int rmnet_ctrl_release(struct inode *ip, struct file *fp)
+{
+	unsigned long		flags;
+	struct rmnet_ctrl_qti_port *port = fp->private_data;
+
+	pr_debug("Close rmnet control file");
+
+	spin_lock_irqsave(&port->lock, flags);
+	port->is_open = false;
+	spin_unlock_irqrestore(&port->lock, flags);
+
+	rmnet_ctrl_unlock(&port->open_excl);
+
+	return 0;
+}
+
+static ssize_t
+rmnet_ctrl_read(struct file *fp, char __user *buf, size_t count, loff_t *pos)
+{
+	struct rmnet_ctrl_qti_port *port = fp->private_data;
+	struct rmnet_ctrl_pkt *cpkt = NULL;
+	unsigned long flags;
+	int ret = 0;
+
+	pr_debug("%s: Enter(%d)\n", __func__, count);
+
+	if (count > MAX_QTI_PKT_SIZE) {
+		pr_err("Buffer size is too big %d, should be at most %d\n",
+			count, MAX_QTI_PKT_SIZE);
+		return -EINVAL;
+	}
+
+	if (rmnet_ctrl_lock(&port->read_excl)) {
+		pr_err("Previous reading is not finished yet\n");
+		return -EBUSY;
+	}
+
+	/* block until online */
+	while (!(atomic_read(&port->connected))) {
+		pr_debug("Not connected. Wait.\n");
+		ret = wait_event_interruptible(port->read_wq,
+			atomic_read(&port->connected));
+		if (ret < 0) {
+			rmnet_ctrl_unlock(&port->read_excl);
+			if (ret == -ERESTARTSYS)
+				return -ERESTARTSYS;
+			else
+				return -EINTR;
+		}
+	}
+
+	/* block until a new packet is available */
+	do {
+		spin_lock_irqsave(&port->lock, flags);
+		if (!list_empty(&port->cpkt_req_q))
+			break;
+		spin_unlock_irqrestore(&port->lock, flags);
+
+		pr_debug("%s: Requests list is empty. Wait.\n", __func__);
+		ret = wait_event_interruptible(port->read_wq,
+					!list_empty(&port->cpkt_req_q));
+		if (ret < 0) {
+			pr_debug("Waiting failed\n");
+			rmnet_ctrl_unlock(&port->read_excl);
+			return -ERESTARTSYS;
+		}
+	} while (1);
+
+	cpkt = list_first_entry(&port->cpkt_req_q, struct rmnet_ctrl_pkt,
+							list);
+	list_del(&cpkt->list);
+	spin_unlock_irqrestore(&port->lock, flags);
+
+	if (cpkt->len > count) {
+		pr_err("cpkt size too big:%d > buf size:%d\n",
+				cpkt->len, count);
+		rmnet_ctrl_unlock(&port->read_excl);
+		free_rmnet_ctrl_pkt(cpkt);
+		return -ENOMEM;
+	}
+
+	pr_debug("%s: cpkt size:%d\n", __func__, cpkt->len);
+
+
+	rmnet_ctrl_unlock(&port->read_excl);
+
+	ret = copy_to_user(buf, cpkt->buf, cpkt->len);
+	if (ret) {
+		pr_err("copy_to_user failed: err %d\n", ret);
+		ret = -EFAULT;
+	} else {
+		pr_debug("%s: copied %d bytes to user\n", __func__, cpkt->len);
+		ret = cpkt->len;
+	}
+
+	free_rmnet_ctrl_pkt(cpkt);
+
+	return ret;
+}
+
+static ssize_t
+rmnet_ctrl_write(struct file *fp, const char __user *buf, size_t count,
+		   loff_t *pos)
+{
+	struct rmnet_ctrl_qti_port *port = fp->private_data;
+	void *kbuf;
+	unsigned long flags;
+	int ret = 0;
+
+	pr_debug("%s: Enter(%d)", __func__, count);
+
+	if (!count) {
+		pr_debug("zero length ctrl pkt\n");
+		return -EINVAL;
+	}
+
+	if (count > MAX_QTI_PKT_SIZE) {
+		pr_debug("given pkt size too big:%d > max_pkt_size:%d\n",
+				count, MAX_QTI_PKT_SIZE);
+		return -EINVAL;
+	}
+
+	if (rmnet_ctrl_lock(&port->write_excl)) {
+		pr_err("Previous writing not finished yet\n");
+		return -EBUSY;
+	}
+
+	if (!atomic_read(&port->connected)) {
+		pr_debug("USB cable not connected\n");
+		rmnet_ctrl_unlock(&port->write_excl);
+		return -EPIPE;
+	}
+
+	kbuf = kmalloc(count, GFP_KERNEL);
+	if (!kbuf) {
+		pr_err("failed to allocate ctrl pkt\n");
+		rmnet_ctrl_unlock(&port->write_excl);
+		return -ENOMEM;
+	}
+	ret = copy_from_user(kbuf, buf, count);
+	if (ret) {
+		pr_err("copy_from_user failed err:%d\n", ret);
+		kfree(kbuf);
+		rmnet_ctrl_unlock(&port->write_excl);
+		return -EFAULT;
+	}
+
+	spin_lock_irqsave(&port->lock, flags);
+	if (port->port_usb && port->port_usb->send_cpkt_response) {
+		ret = port->port_usb->send_cpkt_response(port->port_usb,
+							kbuf, count);
+		if (ret) {
+			pr_err("failed to send ctrl packet. error=%d\n", ret);
+			spin_unlock_irqrestore(&port->lock, flags);
+			kfree(kbuf);
+			rmnet_ctrl_unlock(&port->write_excl);
+			return ret;
+		}
+	} else {
+		pr_err("send_cpkt_response callback is NULL\n");
+		spin_unlock_irqrestore(&port->lock, flags);
+		kfree(kbuf);
+		rmnet_ctrl_unlock(&port->write_excl);
+		return -EINVAL;
+	}
+	spin_unlock_irqrestore(&port->lock, flags);
+
+	kfree(kbuf);
+	rmnet_ctrl_unlock(&port->write_excl);
+
+	pr_debug("%s: Exit(%d)", __func__, count);
+
+	return count;
+
+}
+
+static long rmnet_ctrl_ioctl(struct file *fp, unsigned cmd, unsigned long arg)
+{
+	struct rmnet_ctrl_qti_port *port = fp->private_data;
+	int val, ret = 0;
+
+	pr_debug("%s: Received command %d", __func__, cmd);
+
+	if (rmnet_ctrl_lock(&port->ioctl_excl))
+		return -EBUSY;
+
+	switch (cmd) {
+	case FRMNET_CTRL_GET_LINE_STATE:
+		val = atomic_read(&port->line_state);
+		ret = copy_to_user((void __user *)arg, &val, sizeof(val));
+		if (ret) {
+			pr_err("copying to user space failed");
+			ret = -EFAULT;
+		}
+		pr_debug("%s: Sent line_state: %d", __func__,
+				 atomic_read(&port->line_state));
+		break;
+	default:
+		pr_err("wrong parameter");
+		ret = -EINVAL;
+	}
+
+	rmnet_ctrl_unlock(&port->ioctl_excl);
+
+	return ret;
+}
+
+static unsigned int rmnet_ctrl_poll(struct file *file, poll_table *wait)
+{
+	struct rmnet_ctrl_qti_port *port = file->private_data;
+	unsigned long flags;
+	unsigned int mask = 0;
+
+	if (!port) {
+		pr_err("%s on a NULL device\n", __func__);
+		return POLLERR;
+	}
+
+	poll_wait(file, &port->read_wq, wait);
+
+	spin_lock_irqsave(&port->lock, flags);
+	if (!list_empty(&port->cpkt_req_q)) {
+		mask |= POLLIN | POLLRDNORM;
+		pr_debug("%s sets POLLIN for rmnet_ctrl_qti_port\n", __func__);
+	}
+	spin_unlock_irqrestore(&port->lock, flags);
+
+	return mask;
+}
+
+/* file operations for rmnet device /dev/rmnet_ctrl */
+static const struct file_operations rmnet_ctrl_fops = {
+	.owner = THIS_MODULE,
+	.open = rmnet_ctrl_open,
+	.release = rmnet_ctrl_release,
+	.read = rmnet_ctrl_read,
+	.write = rmnet_ctrl_write,
+	.unlocked_ioctl = rmnet_ctrl_ioctl,
+	.poll = rmnet_ctrl_poll,
+};
+
+static struct miscdevice rmnet_device = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = "rmnet_ctrl",
+	.fops = &rmnet_ctrl_fops,
+};
+
+static int __init gqti_ctrl_init(void)
+{
+	int ret;
+	struct rmnet_ctrl_qti_port *port = NULL;
+
+	port = kzalloc(sizeof(struct rmnet_ctrl_qti_port), GFP_KERNEL);
+	if (!port) {
+		pr_err("Failed to allocate rmnet control device\n");
+		return -ENOMEM;
+	}
+
+	INIT_LIST_HEAD(&port->cpkt_req_q);
+	spin_lock_init(&port->lock);
+
+	atomic_set(&port->open_excl, 0);
+	atomic_set(&port->read_excl, 0);
+	atomic_set(&port->write_excl, 0);
+	atomic_set(&port->ioctl_excl, 0);
+	atomic_set(&port->connected, 0);
+	atomic_set(&port->line_state, 0);
+
+	init_waitqueue_head(&port->read_wq);
+
+	ctrl_port = port;
+
+	ret = misc_register(&rmnet_device);
+	if (ret) {
+		pr_err("rmnet control driver failed to register");
+		goto fail_init;
+	}
+
+	return ret;
+
+fail_init:
+	kfree(port);
+	ctrl_port = NULL;
+	return ret;
+}
+module_init(gqti_ctrl_init);
+
+static void __exit gqti_ctrl_cleanup(void)
+{
+	misc_deregister(&rmnet_device);
+
+	kfree(ctrl_port);
+	ctrl_port = NULL;
+}
+module_exit(gqti_ctrl_cleanup);
diff --git a/drivers/usb/gadget/u_rmnet_ctrl_smd.c b/drivers/usb/gadget/u_rmnet_ctrl_smd.c
index 169008b..5817779 100644
--- a/drivers/usb/gadget/u_rmnet_ctrl_smd.c
+++ b/drivers/usb/gadget/u_rmnet_ctrl_smd.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -32,6 +32,8 @@
 #define SMD_CH_MAX_LEN	20
 #define CH_OPENED	0
 #define CH_READY	1
+#define CH_PREPARE_READY 2
+
 struct smd_ch_info {
 	struct smd_channel	*ch;
 	char			*name;
@@ -60,6 +62,7 @@
 
 	spinlock_t		port_lock;
 	struct delayed_work	connect_w;
+	struct delayed_work	disconnect_w;
 };
 
 static struct rmnet_ctrl_ports {
@@ -324,6 +327,7 @@
 {
 	struct rmnet_ctrl_port *port =
 			container_of(w, struct rmnet_ctrl_port, connect_w.work);
+	struct rmnet_ctrl_ports *port_entry = &ctrl_smd_ports[port->port_num];
 	struct smd_ch_info *c = &port->ctrl_ch;
 	unsigned long flags;
 	int	set_bits = 0;
@@ -332,8 +336,13 @@
 
 	pr_debug("%s:\n", __func__);
 
-	if (!test_bit(CH_READY, &c->flags))
+	if (!test_bit(CH_READY, &c->flags)) {
+		if (!test_bit(CH_PREPARE_READY, &c->flags)) {
+			set_bit(CH_PREPARE_READY, &c->flags);
+			platform_driver_register(&(port_entry->pdrv));
+		}
 		return;
+	}
 
 	ret = smd_open(c->name, &c->ch, port, grmnet_ctrl_smd_notify);
 	if (ret) {
@@ -390,6 +399,23 @@
 	return 0;
 }
 
+static void grmnet_ctrl_smd_disconnect_w(struct work_struct *w)
+{
+	struct rmnet_ctrl_port *port =
+			container_of(w, struct rmnet_ctrl_port,
+					disconnect_w.work);
+	struct smd_ch_info *c;
+	struct platform_driver *pdrv;
+
+	c = &port->ctrl_ch;
+	if (test_bit(CH_READY, &c->flags) ||
+	    test_bit(CH_PREPARE_READY, &c->flags)) {
+		clear_bit(CH_PREPARE_READY, &c->flags);
+		pdrv = &ctrl_smd_ports[port->port_num].pdrv;
+		platform_driver_unregister(pdrv);
+	}
+}
+
 void gsmd_ctrl_disconnect(struct grmnet *gr, u8 port_num)
 {
 	struct rmnet_ctrl_port	*port;
@@ -435,6 +461,8 @@
 		smd_close(c->ch);
 		c->ch = NULL;
 	}
+
+	queue_delayed_work(grmnet_ctrl_wq, &port->disconnect_w, 0);
 }
 
 #define SMD_CH_MAX_LEN	20
@@ -452,6 +480,7 @@
 		c = &port->ctrl_ch;
 
 		if (!strncmp(c->name, pdev->name, SMD_CH_MAX_LEN)) {
+			clear_bit(CH_PREPARE_READY, &c->flags);
 			set_bit(CH_READY, &c->flags);
 
 			/* if usb is online, try opening smd_ch */
@@ -520,6 +549,7 @@
 
 	spin_lock_init(&port->port_lock);
 	INIT_DELAYED_WORK(&port->connect_w, grmnet_ctrl_smd_connect_w);
+	INIT_DELAYED_WORK(&port->disconnect_w, grmnet_ctrl_smd_disconnect_w);
 
 	c = &port->ctrl_ch;
 	c->name = rmnet_ctrl_names[portno];
@@ -537,8 +567,6 @@
 	pdrv->driver.name = c->name;
 	pdrv->driver.owner = THIS_MODULE;
 
-	platform_driver_register(pdrv);
-
 	pr_debug("%s: port:%p portno:%d\n", __func__, port, portno);
 
 	return 0;
diff --git a/drivers/usb/gadget/u_sdio.c b/drivers/usb/gadget/u_sdio.c
index a604e1e..a0cdde2 100644
--- a/drivers/usb/gadget/u_sdio.c
+++ b/drivers/usb/gadget/u_sdio.c
@@ -5,9 +5,9 @@
  * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
  * Copyright (C) 2008 David Brownell
  * Copyright (C) 2008 by Nokia Corporation
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. All rights reserved.
  *
- * This program from the Code Aurora Forum is free software; you can
+ * This program from The Linux Foundation is free software; you can
  * redistribute it and/or modify it under the GNU General Public License
  * version 2 and only version 2 as published by the Free Software Foundation.
  * The original work available from [kernel.org] is subject to the notice below.
diff --git a/drivers/usb/gadget/u_smd.c b/drivers/usb/gadget/u_smd.c
index effe418..4b02665 100644
--- a/drivers/usb/gadget/u_smd.c
+++ b/drivers/usb/gadget/u_smd.c
@@ -1,7 +1,7 @@
 /*
  * u_smd.c - utilities for USB gadget serial over smd
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. All rights reserved.
  *
  * This code also borrows from drivers/usb/gadget/u_serial.c, which is
  * Copyright (C) 2000 - 2003 Al Borchers (alborchers@steinerpoint.com)
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index adbf217..4b14934 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -976,9 +976,10 @@
 	/* PCI errors [4.15.2.4] */
 	if (unlikely ((status & STS_FATAL) != 0)) {
 		ehci_err(ehci, "fatal error\n");
-		if (hcd->driver->dump_regs)
+		if (hcd->driver->dump_regs) {
 			hcd->driver->dump_regs(hcd);
-		panic("System error\n");
+			panic("System error\n");
+		}
 		dbg_cmd(ehci, "fatal", cmd);
 		dbg_status(ehci, "fatal", status);
 		ehci_halt(ehci);
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 1a75bd7..a09b1ab 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -256,8 +256,11 @@
 		else if ((t1 & PORT_PE) && !(t1 & PORT_SUSPEND)) {
 			/*clear RS bit before setting SUSP bit
 			* and wait for HCH to get set*/
-			if (ehci->susp_sof_bug)
+			if (ehci->susp_sof_bug) {
+				spin_unlock_irq(&ehci->lock);
 				ehci_halt(ehci);
+				spin_lock_irq(&ehci->lock);
+			}
 
 			t2 |= PORT_SUSPEND;
 			set_bit(port, &ehci->bus_suspended);
@@ -839,7 +842,7 @@
 	u32 __iomem	*status_reg = &ehci->regs->port_status[
 				(wIndex & 0xff) - 1];
 	u32 __iomem	*hostpc_reg = NULL;
-	u32		temp, temp1, status, cmd = 0;
+	u32		temp, temp1, status;
 	unsigned long	flags;
 	int		retval = 0;
 	unsigned	selector;
@@ -1218,31 +1221,13 @@
 				ehci->reset_done [wIndex] = jiffies
 						+ msecs_to_jiffies (50);
 			}
-
-			if (ehci->reset_sof_bug && (temp & PORT_RESET)) {
-				cmd = ehci_readl(ehci, &ehci->regs->command);
-				cmd &= ~CMD_RUN;
-				ehci_writel(ehci, cmd, &ehci->regs->command);
-				if (handshake(ehci, &ehci->regs->status,
-						STS_HALT, STS_HALT, 16 * 125))
-					ehci_info(ehci,
-						"controller halt failed\n");
-			}
-			ehci_writel(ehci, temp, status_reg);
-			if (ehci->reset_sof_bug && (temp & PORT_RESET)
-				&& hcd->driver->enable_ulpi_control) {
-				hcd->driver->enable_ulpi_control(hcd,
-						PORT_RESET);
+			if (ehci->reset_sof_bug && (temp & PORT_RESET) &&
+					hcd->driver->reset_sof_bug_handler) {
 				spin_unlock_irqrestore(&ehci->lock, flags);
-				usleep_range(50000, 55000);
-				if (handshake(ehci, status_reg,
-						PORT_RESET, 0, 10 * 1000))
-					ehci_info(ehci,
-						"failed to clear reset\n");
+				hcd->driver->reset_sof_bug_handler(hcd, temp);
 				spin_lock_irqsave(&ehci->lock, flags);
-				hcd->driver->disable_ulpi_control(hcd);
-				cmd |= CMD_RUN;
-				ehci_writel(ehci, cmd, &ehci->regs->command);
+			} else {
+				ehci_writel(ehci, temp, status_reg);
 			}
 			break;
 
@@ -1268,7 +1253,9 @@
 							temp | PORT_SUSPEND,
 							sreg);
 				}
+				spin_unlock_irq(&ehci->lock);
 				ehci_halt(ehci);
+				spin_lock_irq(&ehci->lock);
 				temp = ehci_readl(ehci, status_reg);
 				temp |= selector << 16;
 				ehci_writel(ehci, temp, status_reg);
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index 57598c8..8e32aa9 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-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * Partly derived from ehci-fsl.c and ehci-hcd.c
  * Copyright (c) 2000-2004 by David Brownell
@@ -79,12 +79,14 @@
 	struct clk		*cal_clk;
 	struct regulator	*hsic_vddcx;
 	struct regulator	*hsic_gdsc;
-	bool			async_int;
+	atomic_t		async_int;
 	atomic_t                in_lpm;
 	struct wake_lock	wlock;
 	int			peripheral_status_irq;
 	int			wakeup_irq;
 	bool			wakeup_irq_enabled;
+	int			async_irq;
+	uint32_t		async_int_cnt;
 	atomic_t		pm_usage_cnt;
 	uint32_t		bus_perf_client;
 	uint32_t		wakeup_int_cnt;
@@ -99,6 +101,8 @@
 	struct completion	rt_completion;
 	int			resume_status;
 	int			resume_again;
+	int			bus_reset;
+	int			reset_again;
 
 	struct pm_qos_request pm_qos_req_dma;
 };
@@ -428,7 +432,7 @@
 
 }
 
-static int ulpi_read(struct msm_hsic_hcd *mehci, u32 reg)
+static int __maybe_unused ulpi_read(struct msm_hsic_hcd *mehci, u32 reg)
 {
 	struct usb_hcd *hcd = hsic_to_hcd(mehci);
 	int cnt = 0;
@@ -499,37 +503,6 @@
 	return 0;
 }
 
-#define HSIC_DBG1		0X38
-#define ULPI_MANUAL_ENABLE	BIT(4)
-#define ULPI_LINESTATE_DATA	BIT(5)
-#define ULPI_LINESTATE_STROBE	BIT(6)
-static void ehci_msm_enable_ulpi_control(struct usb_hcd *hcd, u32 linestate)
-{
-	struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
-	int val;
-
-	switch (linestate) {
-	case PORT_RESET:
-		val = ulpi_read(mehci, HSIC_DBG1);
-		val |= ULPI_MANUAL_ENABLE;
-		val &= ~(ULPI_LINESTATE_DATA | ULPI_LINESTATE_STROBE);
-		ulpi_write(mehci, val, HSIC_DBG1);
-		break;
-	default:
-		pr_info("%s: Unknown linestate:%0x\n", __func__, linestate);
-	}
-}
-
-static void ehci_msm_disable_ulpi_control(struct usb_hcd *hcd)
-{
-	struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
-	int val;
-
-	val = ulpi_read(mehci, HSIC_DBG1);
-	val &= ~ULPI_MANUAL_ENABLE;
-	ulpi_write(mehci, val, HSIC_DBG1);
-}
-
 static int msm_hsic_config_gpios(struct msm_hsic_hcd *mehci, int gpio_en)
 {
 	int rc = 0;
@@ -575,20 +548,53 @@
 {
 	int ret;
 
-	ret = clk_reset(mehci->core_clk, CLK_RESET_ASSERT);
-	if (ret) {
-		dev_err(mehci->dev, "hsic clk assert failed:%d\n", ret);
-		return;
+	/* alt_core_clk exists in targets that do not use asynchronous reset */
+	if (!IS_ERR(mehci->alt_core_clk)) {
+		ret = clk_reset(mehci->core_clk, CLK_RESET_ASSERT);
+		if (ret) {
+			dev_err(mehci->dev, "hsic clk assert failed:%d\n", ret);
+			return;
+		}
+
+		/* Since a hw bug, turn off the clock before complete reset */
+		clk_disable(mehci->core_clk);
+
+		ret = clk_reset(mehci->core_clk, CLK_RESET_DEASSERT);
+		if (ret)
+			dev_err(mehci->dev, "hsic clk deassert failed:%d\n",
+					ret);
+
+		usleep_range(10000, 12000);
+
+		clk_enable(mehci->core_clk);
+	} else {
+		/* Using asynchronous block reset to the hardware */
+		clk_disable_unprepare(mehci->core_clk);
+		clk_disable_unprepare(mehci->phy_clk);
+		clk_disable_unprepare(mehci->cal_clk);
+		clk_disable_unprepare(mehci->ahb_clk);
+
+		ret = clk_reset(mehci->core_clk, CLK_RESET_ASSERT);
+		if (ret) {
+			dev_err(mehci->dev, "hsic clk assert failed:%d\n", ret);
+			return;
+		}
+		usleep_range(10000, 12000);
+
+		ret = clk_reset(mehci->core_clk, CLK_RESET_DEASSERT);
+		if (ret)
+			dev_err(mehci->dev, "hsic clk deassert failed:%d\n",
+					ret);
+		/*
+		 * Required delay between the deassertion and
+		 *  clock enablement.
+		*/
+		ndelay(200);
+		clk_prepare_enable(mehci->core_clk);
+		clk_prepare_enable(mehci->phy_clk);
+		clk_prepare_enable(mehci->cal_clk);
+		clk_prepare_enable(mehci->ahb_clk);
 	}
-	clk_disable(mehci->core_clk);
-
-	ret = clk_reset(mehci->core_clk, CLK_RESET_DEASSERT);
-	if (ret)
-		dev_err(mehci->dev, "hsic clk deassert failed:%d\n", ret);
-
-	usleep_range(10000, 12000);
-
-	clk_enable(mehci->core_clk);
 }
 
 #define HSIC_STROBE_GPIO_PAD_CTL	(MSM_TLMM_BASE+0x20C0)
@@ -751,9 +757,14 @@
 	 * power mode (LPM). This interrupt is level triggered. So USB IRQ
 	 * line must be disabled till async interrupt enable bit is cleared
 	 * in USBCMD register. Assert STP (ULPI interface STOP signal) to
-	 * block data communication from PHY.
+	 * block data communication from PHY.  Enable asynchronous interrupt
+	 * only when wakeup gpio IRQ is not present.
 	 */
-	writel_relaxed(readl_relaxed(USB_USBCMD) | ASYNC_INTR_CTRL |
+	if (mehci->wakeup_irq)
+		writel_relaxed(readl_relaxed(USB_USBCMD) |
+				ULPI_STP_CTRL, USB_USBCMD);
+	else
+		writel_relaxed(readl_relaxed(USB_USBCMD) | ASYNC_INTR_CTRL |
 				ULPI_STP_CTRL, USB_USBCMD);
 
 	/*
@@ -782,9 +793,11 @@
 	atomic_set(&mehci->in_lpm, 1);
 	enable_irq(hcd->irq);
 
-	mehci->wakeup_irq_enabled = 1;
-	enable_irq_wake(mehci->wakeup_irq);
-	enable_irq(mehci->wakeup_irq);
+	if (mehci->wakeup_irq) {
+		mehci->wakeup_irq_enabled = 1;
+		enable_irq_wake(mehci->wakeup_irq);
+		enable_irq(mehci->wakeup_irq);
+	}
 
 	if (pdata && pdata->standalone_latency)
 		pm_qos_update_request(&mehci->pm_qos_req_dma,
@@ -792,7 +805,7 @@
 
 	wake_unlock(&mehci->wlock);
 
-	dev_info(mehci->dev, "HSIC-USB in low power mode\n");
+	dev_dbg(mehci->dev, "HSIC-USB in low power mode\n");
 
 	return 0;
 }
@@ -811,17 +824,22 @@
 		return 0;
 	}
 
+	/* Handles race with Async interrupt */
+	disable_irq(hcd->irq);
+
 	if (pdata && pdata->standalone_latency)
 		pm_qos_update_request(&mehci->pm_qos_req_dma,
 			pdata->standalone_latency + 1);
 
-	spin_lock_irqsave(&mehci->wakeup_lock, flags);
-	if (mehci->wakeup_irq_enabled) {
-		disable_irq_wake(mehci->wakeup_irq);
-		disable_irq_nosync(mehci->wakeup_irq);
-		mehci->wakeup_irq_enabled = 0;
+	if (mehci->wakeup_irq) {
+		spin_lock_irqsave(&mehci->wakeup_lock, flags);
+		if (mehci->wakeup_irq_enabled) {
+			disable_irq_wake(mehci->wakeup_irq);
+			disable_irq_nosync(mehci->wakeup_irq);
+			mehci->wakeup_irq_enabled = 0;
+		}
+		spin_unlock_irqrestore(&mehci->wakeup_lock, flags);
 	}
-	spin_unlock_irqrestore(&mehci->wakeup_lock, flags);
 
 	wake_lock(&mehci->wlock);
 
@@ -877,8 +895,8 @@
 
 	atomic_set(&mehci->in_lpm, 0);
 
-	if (mehci->async_int) {
-		mehci->async_int = false;
+	if (atomic_read(&mehci->async_int)) {
+		atomic_set(&mehci->async_int, 0);
 		pm_runtime_put_noidle(mehci->dev);
 		enable_irq(hcd->irq);
 	}
@@ -888,7 +906,8 @@
 		pm_runtime_put_noidle(mehci->dev);
 	}
 
-	dev_info(mehci->dev, "HSIC-USB exited from low power mode\n");
+	enable_irq(hcd->irq);
+	dev_dbg(mehci->dev, "HSIC-USB exited from low power mode\n");
 
 	return 0;
 }
@@ -907,18 +926,45 @@
 				__func__, ret);
 }
 
+static int msm_hsic_reset_done(struct usb_hcd *hcd)
+{
+	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+	u32 __iomem *status_reg = &ehci->regs->port_status[0];
+	int ret;
+
+	ehci_writel(ehci, ehci_readl(ehci, status_reg) & ~(PORT_RWC_BITS |
+					PORT_RESET), status_reg);
+
+	ret = handshake(ehci, status_reg, PORT_RESET, 0, 1 * 1000);
+
+	if (ret)
+		pr_err("reset handshake failed in %s\n", __func__);
+	else
+		ehci_writel(ehci, ehci_readl(ehci, &ehci->regs->command) |
+				CMD_RUN, &ehci->regs->command);
+
+	return ret;
+}
+
 #define STS_GPTIMER0_INTERRUPT	BIT(24)
 static irqreturn_t msm_hsic_irq(struct usb_hcd *hcd)
 {
 	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
 	struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
 	u32			status;
+	int			ret;
 
 	if (atomic_read(&mehci->in_lpm)) {
-		disable_irq_nosync(hcd->irq);
 		dev_dbg(mehci->dev, "phy async intr\n");
-		mehci->async_int = true;
-		pm_runtime_get(mehci->dev);
+		dbg_log_event(NULL, "Async IRQ", 0);
+		ret = pm_runtime_get(mehci->dev);
+		if ((ret == 1) || (ret == -EINPROGRESS)) {
+			pm_runtime_put_noidle(mehci->dev);
+		} else {
+			disable_irq_nosync(hcd->irq);
+			atomic_set(&mehci->async_int, 1);
+		}
+
 		return IRQ_HANDLED;
 	}
 
@@ -927,16 +973,28 @@
 	if (status & STS_GPTIMER0_INTERRUPT) {
 		int timeleft;
 
-		dbg_log_event(NULL, "FPR: gpt0_isr", 0);
+		dbg_log_event(NULL, "FPR: gpt0_isr", mehci->bus_reset);
 
 		timeleft = GPT_CNT(ehci_readl(ehci,
 						 &mehci->timer->gptimer1_ctrl));
 		if (timeleft) {
-			ehci_writel(ehci, ehci_readl(ehci,
-				&ehci->regs->command) | CMD_RUN,
-				&ehci->regs->command);
-		} else
-			mehci->resume_again = 1;
+			if (mehci->bus_reset) {
+				ret = msm_hsic_reset_done(hcd);
+				if (ret) {
+					mehci->reset_again = 1;
+					dbg_log_event(NULL, "RESET: fail", 0);
+				}
+			} else {
+				ehci_writel(ehci, ehci_readl(ehci,
+					&ehci->regs->command) | CMD_RUN,
+					&ehci->regs->command);
+			}
+		} else {
+			if (mehci->bus_reset)
+				mehci->reset_again = 1;
+			else
+				mehci->resume_again = 1;
+		}
 
 		dbg_log_event(NULL, "FPR: timeleft", timeleft);
 
@@ -992,6 +1050,83 @@
 
 #ifdef CONFIG_PM
 
+#define RESET_RETRY_LIMIT 3
+#define RESET_SIGNAL_TIME_SOF_USEC (50 * 1000)
+#define RESET_SIGNAL_TIME_USEC (20 * 1000)
+static void ehci_hsic_reset_sof_bug_handler(struct usb_hcd *hcd, u32 val)
+{
+	struct ehci_hcd	*ehci = hcd_to_ehci(hcd);
+	struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
+	struct msm_hsic_host_platform_data *pdata = mehci->dev->platform_data;
+	u32 __iomem *status_reg = &ehci->regs->port_status[0];
+	unsigned long flags;
+	int retries = 0, ret, cnt = RESET_SIGNAL_TIME_USEC;
+
+	if (pdata && pdata->swfi_latency)
+		pm_qos_update_request(&mehci->pm_qos_req_dma,
+			pdata->swfi_latency + 1);
+
+	mehci->bus_reset = 1;
+retry:
+	retries++;
+	dbg_log_event(NULL, "RESET: start", retries);
+	pr_debug("reset begin %d\n", retries);
+	mehci->reset_again = 0;
+	spin_lock_irqsave(&ehci->lock, flags);
+	ehci_writel(ehci, val, status_reg);
+	ehci_writel(ehci, GPT_LD(RESET_SIGNAL_TIME_USEC - 1),
+					&mehci->timer->gptimer0_ld);
+	ehci_writel(ehci, GPT_RESET | GPT_RUN,
+			&mehci->timer->gptimer0_ctrl);
+	ehci_writel(ehci, INTR_MASK | STS_GPTIMER0_INTERRUPT,
+			&ehci->regs->intr_enable);
+
+	ehci_writel(ehci, GPT_LD(RESET_SIGNAL_TIME_SOF_USEC - 1),
+			&mehci->timer->gptimer1_ld);
+	ehci_writel(ehci, GPT_RESET | GPT_RUN,
+		&mehci->timer->gptimer1_ctrl);
+
+	spin_unlock_irqrestore(&ehci->lock, flags);
+	wait_for_completion(&mehci->gpt0_completion);
+
+	if (!mehci->reset_again)
+		goto done;
+
+	if (handshake(ehci, status_reg, PORT_RESET, 0, 10 * 1000)) {
+		pr_err("reset handshake fatal error\n");
+		dbg_log_event(NULL, "RESET: fatal", retries);
+		goto fail;
+	}
+
+	if (retries < RESET_RETRY_LIMIT)
+		goto retry;
+
+	/* complete reset in tight loop */
+	pr_info("RESET in tight loop\n");
+	dbg_log_event(NULL, "RESET: tight", 0);
+
+	spin_lock_irqsave(&ehci->lock, flags);
+	ehci_writel(ehci, val, status_reg);
+	while (cnt--)
+		udelay(1);
+	ret = msm_hsic_reset_done(hcd);
+	spin_unlock_irqrestore(&ehci->lock, flags);
+	if (ret) {
+		pr_err("RESET in tight loop failed\n");
+		dbg_log_event(NULL, "RESET: tight failed", 0);
+		goto fail;
+	}
+
+done:
+	dbg_log_event(NULL, "RESET: done", retries);
+	pr_debug("reset completed\n");
+fail:
+	mehci->bus_reset = 0;
+	if (pdata && pdata->swfi_latency)
+		pm_qos_update_request(&mehci->pm_qos_req_dma,
+			PM_QOS_DEFAULT_VALUE);
+}
+
 static int ehci_hsic_bus_suspend(struct usb_hcd *hcd)
 {
 	struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
@@ -1008,8 +1143,8 @@
 }
 
 #define RESUME_RETRY_LIMIT		3
-#define RESUME_SIGNAL_TIME_MS		(21 * 999)
-#define RESUME_SIGNAL_TIME_SOF_MS	(23 * 999)
+#define RESUME_SIGNAL_TIME_USEC		(21 * 1000)
+#define RESUME_SIGNAL_TIME_SOF_USEC	(23 * 1000)
 static int msm_hsic_resume_thread(void *data)
 {
 	struct msm_hsic_hcd *mehci = data;
@@ -1090,14 +1225,15 @@
 	if (ehci->resume_sof_bug && resume_needed) {
 		if (!tight_resume) {
 			mehci->resume_again = 0;
-			ehci_writel(ehci, GPT_LD(RESUME_SIGNAL_TIME_MS),
+			ehci_writel(ehci, GPT_LD(RESUME_SIGNAL_TIME_USEC - 1),
 					&mehci->timer->gptimer0_ld);
 			ehci_writel(ehci, GPT_RESET | GPT_RUN,
 					&mehci->timer->gptimer0_ctrl);
 			ehci_writel(ehci, INTR_MASK | STS_GPTIMER0_INTERRUPT,
 					&ehci->regs->intr_enable);
 
-			ehci_writel(ehci, GPT_LD(RESUME_SIGNAL_TIME_SOF_MS),
+			ehci_writel(ehci, GPT_LD(
+					RESUME_SIGNAL_TIME_SOF_USEC - 1),
 					&mehci->timer->gptimer1_ld);
 			ehci_writel(ehci, GPT_RESET | GPT_RUN,
 				&mehci->timer->gptimer1_ctrl);
@@ -1192,6 +1328,7 @@
 	ehci->next_statechange = jiffies + msecs_to_jiffies(5);
 	hcd->state = HC_STATE_RUNNING;
 	ehci->rh_state = EHCI_RH_RUNNING;
+	ehci->command |= CMD_RUN;
 
 	/* Now we can safely re-enable irqs */
 	ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable);
@@ -1264,10 +1401,8 @@
 	.log_urb		= dbg_log_event,
 	.dump_regs		= dump_hsic_regs,
 
-	.enable_ulpi_control	= ehci_msm_enable_ulpi_control,
-	.disable_ulpi_control	= ehci_msm_disable_ulpi_control,
-
 	.set_autosuspend_delay = ehci_msm_set_autosuspend_delay,
+	.reset_sof_bug_handler	= ehci_hsic_reset_sof_bug_handler,
 };
 
 static int msm_hsic_init_clocks(struct msm_hsic_hcd *mehci, u32 init)
@@ -1286,7 +1421,8 @@
 		return ret;
 	}
 
-	/* alt_core_clk is for LINK to be used during PHY RESET
+	/* alt_core_clk is for LINK to be used during PHY RESET in
+	 * targets on which link does NOT use asynchronous reset methodology.
 	 * clock rate appropriately set by target specific clock driver */
 	mehci->alt_core_clk = clk_get(mehci->dev, "alt_core_clk");
 	if (IS_ERR(mehci->alt_core_clk))
@@ -1360,20 +1496,28 @@
 	struct msm_hsic_hcd *mehci = data;
 	int ret;
 
-	mehci->wakeup_int_cnt++;
-	dbg_log_event(NULL, "Remote Wakeup IRQ", mehci->wakeup_int_cnt);
-	dev_dbg(mehci->dev, "%s: hsic remote wakeup interrupt cnt: %u\n",
-			__func__, mehci->wakeup_int_cnt);
+	if (irq == mehci->async_irq) {
+		mehci->async_int_cnt++;
+		dbg_log_event(NULL, "Remote Wakeup (ASYNC) IRQ",
+							 mehci->async_int_cnt);
+	} else {
+		mehci->wakeup_int_cnt++;
+		dbg_log_event(NULL, "Remote Wakeup IRQ", mehci->wakeup_int_cnt);
+	}
+	dev_dbg(mehci->dev, "%s: hsic remote wakeup interrupt %d cnt: %u, %u\n",
+		    __func__, irq, mehci->wakeup_int_cnt, mehci->async_int_cnt);
 
 	wake_lock(&mehci->wlock);
 
-	spin_lock(&mehci->wakeup_lock);
-	if (mehci->wakeup_irq_enabled) {
-		mehci->wakeup_irq_enabled = 0;
-		disable_irq_wake(irq);
-		disable_irq_nosync(irq);
+	if (mehci->wakeup_irq) {
+		spin_lock(&mehci->wakeup_lock);
+		if (mehci->wakeup_irq_enabled) {
+			mehci->wakeup_irq_enabled = 0;
+			disable_irq_wake(irq);
+			disable_irq_nosync(irq);
+		}
+		spin_unlock(&mehci->wakeup_lock);
 	}
-	spin_unlock(&mehci->wakeup_lock);
 
 	if (!atomic_read(&mehci->pm_usage_cnt)) {
 		ret = pm_runtime_get(mehci->dev);
@@ -1591,19 +1735,23 @@
 {
 	struct device_node *node = pdev->dev.of_node;
 	struct msm_hsic_host_platform_data *pdata;
+	int res_gpio;
 
 	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
 	if (!pdata) {
 		dev_err(&pdev->dev, "unable to allocate platform data\n");
 		return NULL;
 	}
-	pdata->strobe = of_get_named_gpio(node, "hsic,strobe-gpio", 0);
-	if (pdata->strobe < 0)
-		pdata->strobe = 0;
 
-	pdata->data = of_get_named_gpio(node, "hsic,data-gpio", 0);
-	if (pdata->data < 0)
-		pdata->data = 0;
+	res_gpio = of_get_named_gpio(node, "hsic,strobe-gpio", 0);
+	if (res_gpio < 0)
+		res_gpio = 0;
+	pdata->strobe = res_gpio;
+
+	res_gpio = of_get_named_gpio(node, "hsic,data-gpio", 0);
+	if (res_gpio < 0)
+		res_gpio = 0;
+	pdata->data = res_gpio;
 
 	pdata->ignore_cal_pad_config = of_property_read_bool(node,
 					"hsic,ignore-cal-pad-config");
@@ -1612,6 +1760,8 @@
 	of_property_read_u32(node, "hsic,data-pad-offset",
 					&pdata->data_pad_offset);
 
+	pdata->bus_scale_table = msm_bus_cl_get_pdata(pdev);
+
 	return pdata;
 }
 
@@ -1785,6 +1935,21 @@
 		}
 	}
 
+	mehci->async_irq = platform_get_irq_byname(pdev, "async_irq");
+	if (mehci->async_irq < 0) {
+		dev_dbg(&pdev->dev, "platform_get_irq for async_int failed\n");
+		mehci->async_irq = 0;
+	} else {
+		ret = request_irq(mehci->async_irq, msm_hsic_wakeup_irq,
+				IRQF_TRIGGER_RISING, "msm_hsic_async", mehci);
+		if (ret) {
+			dev_err(&pdev->dev, "request irq failed (ASYNC INT)\n");
+			mehci->async_irq = 0;
+		} else {
+			enable_irq_wake(mehci->async_irq);
+		}
+	}
+
 	ret = ehci_hsic_msm_debugfs_init(mehci);
 	if (ret)
 		dev_dbg(&pdev->dev, "mode debugfs file is"
@@ -1846,6 +2011,15 @@
 	struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
 	struct msm_hsic_host_platform_data *pdata = mehci->dev->platform_data;
 
+	/* If the device was removed no need to call pm_runtime_disable */
+	if (pdev->dev.power.power_state.event != PM_EVENT_INVALID)
+		pm_runtime_disable(&pdev->dev);
+
+	pm_runtime_set_suspended(&pdev->dev);
+
+	/* Remove the HCD prior to releasing our resources. */
+	usb_remove_hcd(hcd);
+
 	if (pdata && pdata->standalone_latency)
 		pm_qos_remove_request(&mehci->pm_qos_req_dma);
 
@@ -1858,6 +2032,10 @@
 		free_irq(mehci->wakeup_irq, mehci);
 	}
 
+	if (mehci->async_irq) {
+		disable_irq_wake(mehci->async_irq);
+		free_irq(mehci->async_irq, mehci);
+	}
 	/*
 	 * If the update request is called after unregister, the request will
 	 * fail. Results are undefined if unregister is called in the middle of
@@ -1871,11 +2049,9 @@
 
 	ehci_hsic_msm_debugfs_cleanup();
 	device_init_wakeup(&pdev->dev, 0);
-	pm_runtime_set_suspended(&pdev->dev);
 
 	destroy_workqueue(ehci_wq);
 
-	usb_remove_hcd(hcd);
 	msm_hsic_config_gpios(mehci, 0);
 	msm_hsic_init_vddcx(mehci, 0);
 	msm_hsic_init_gdsc(mehci, 0);
@@ -1915,7 +2091,7 @@
 	struct usb_hcd *hcd = dev_get_drvdata(dev);
 	struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
 
-	if (mehci->async_int) {
+	if (atomic_read(&mehci->async_int)) {
 		dev_dbg(dev, "suspend_noirq: Aborting due to pending interrupt\n");
 		return -EBUSY;
 	}
@@ -1942,6 +2118,7 @@
 	 * start I/O.
 	 */
 	if (!atomic_read(&mehci->pm_usage_cnt) &&
+			!atomic_read(&mehci->async_int) &&
 			pm_runtime_suspended(dev))
 		return 0;
 
diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c
index e8e4e10..66363eb 100644
--- a/drivers/usb/host/ehci-msm.c
+++ b/drivers/usb/host/ehci-msm.c
@@ -1,6 +1,6 @@
 /* ehci-msm.c - HSUSB Host Controller Driver Implementation
  *
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * Partly derived from ehci-fsl.c and ehci-hcd.c
  * Copyright (c) 2000-2004 by David Brownell
diff --git a/drivers/usb/host/ehci-msm2.c b/drivers/usb/host/ehci-msm2.c
index 34d90fb..faa5625 100644
--- a/drivers/usb/host/ehci-msm2.c
+++ b/drivers/usb/host/ehci-msm2.c
@@ -1,6 +1,6 @@
 /* ehci-msm2.c - HSUSB Host Controller Driver Implementation
  *
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2013, The Linux Foundation. All rights reserved.
  *
  * Partly derived from ehci-fsl.c and ehci-hcd.c
  * Copyright (c) 2000-2004 by David Brownell
@@ -32,6 +32,7 @@
 #include <linux/usb/ulpi.h>
 #include <linux/usb/msm_hsusb_hw.h>
 #include <linux/usb/msm_hsusb.h>
+#include <linux/of.h>
 #include <mach/clk.h>
 #include <mach/msm_xo.h>
 #include <mach/msm_iomap.h>
@@ -42,10 +43,13 @@
 
 struct msm_hcd {
 	struct ehci_hcd				ehci;
+	spinlock_t				wakeup_lock;
 	struct device				*dev;
+	struct clk				*xo_clk;
 	struct clk				*iface_clk;
 	struct clk				*core_clk;
 	struct clk				*alt_core_clk;
+	struct clk				*phy_sleep_clk;
 	struct regulator			*hsusb_vddcx;
 	struct regulator			*hsusb_3p3;
 	struct regulator			*hsusb_1p8;
@@ -60,6 +64,9 @@
 	atomic_t				pm_usage_cnt;
 	struct wake_lock			wlock;
 	struct work_struct			phy_susp_fail_work;
+	int					async_irq;
+	bool					async_irq_enabled;
+	uint32_t				async_int_cnt;
 };
 
 static inline struct msm_hcd *hcd_to_mhcd(struct usb_hcd *hcd)
@@ -272,6 +279,7 @@
 	int rc = 0;
 	struct usb_hcd *hcd = mhcd_to_hcd(mhcd);
 	const struct msm_usb_host_platform_data *pdata;
+	int ret = 0;
 
 	pdata = mhcd->dev->platform_data;
 
@@ -282,7 +290,11 @@
 	}
 
 	mhcd->vbus = devm_regulator_get(mhcd->dev, "vbus");
-	if (IS_ERR(mhcd->vbus)) {
+	ret = PTR_ERR(mhcd->vbus);
+	if (ret == -EPROBE_DEFER) {
+		pr_debug("failed to get vbus handle, defer probe\n");
+		return ret;
+	} else if (IS_ERR(mhcd->vbus)) {
 		pr_err("Unable to get vbus\n");
 		return -ENODEV;
 	}
@@ -435,18 +447,38 @@
 	return 0;
 }
 
+/**
+ * Do hard reset to USB hardware block using one of reset methodology based
+ * on availablity of alt_core_clk. There are two kinds of hardware resets.
+ * 1. Conventional synchronous reset where clocks to blocks to be ON while
+ * issuing the reset. 2. Asynchronous reset which requires clocks to be OFF.
+ */
 static int msm_ehci_link_clk_reset(struct msm_hcd *mhcd, bool assert)
 {
 	int ret;
 
 	if (assert) {
-		ret = clk_reset(mhcd->alt_core_clk, CLK_RESET_ASSERT);
+		if (!IS_ERR(mhcd->alt_core_clk)) {
+			ret = clk_reset(mhcd->alt_core_clk, CLK_RESET_ASSERT);
+		} else {
+			/* Using asynchronous block reset to the hardware */
+			clk_disable(mhcd->iface_clk);
+			clk_disable(mhcd->core_clk);
+			ret = clk_reset(mhcd->core_clk, CLK_RESET_ASSERT);
+		}
 		if (ret)
-			dev_err(mhcd->dev, "usb alt_core_clk assert failed\n");
+			dev_err(mhcd->dev, "usb clk assert failed\n");
 	} else {
-		ret = clk_reset(mhcd->alt_core_clk, CLK_RESET_DEASSERT);
+		if (!IS_ERR(mhcd->alt_core_clk)) {
+			ret = clk_reset(mhcd->alt_core_clk, CLK_RESET_DEASSERT);
+		} else {
+			ret = clk_reset(mhcd->core_clk, CLK_RESET_DEASSERT);
+			ndelay(200);
+			clk_enable(mhcd->core_clk);
+			clk_enable(mhcd->iface_clk);
+		}
 		if (ret)
-			dev_err(mhcd->dev, "usb alt_core_clk deassert failed\n");
+			dev_err(mhcd->dev, "usb clk deassert failed\n");
 	}
 
 	return ret;
@@ -455,6 +487,7 @@
 static int msm_ehci_phy_reset(struct msm_hcd *mhcd)
 {
 	struct usb_hcd *hcd = mhcd_to_hcd(mhcd);
+	struct msm_usb_host_platform_data *pdata;
 	u32 val;
 	int ret;
 	int retries;
@@ -463,12 +496,17 @@
 	if (ret)
 		return ret;
 
-	udelay(1);
+	usleep_range(10, 12);
 
 	ret = msm_ehci_link_clk_reset(mhcd, 0);
 	if (ret)
 		return ret;
 
+	pdata = mhcd->dev->platform_data;
+	if (pdata && pdata->use_sec_phy)
+		/* select secondary phy if offset is set for USB operation */
+		writel_relaxed(readl_relaxed(USB_PHY_CTRL2) | (1<<16),
+								USB_PHY_CTRL2);
 	val = readl_relaxed(USB_PORTSC) & ~PORTSC_PTS_MASK;
 	writel_relaxed(val | PORTSC_PTS_ULPI, USB_PORTSC);
 
@@ -499,10 +537,13 @@
 static int msm_hsusb_reset(struct msm_hcd *mhcd)
 {
 	struct usb_hcd *hcd = mhcd_to_hcd(mhcd);
+	struct msm_usb_host_platform_data *pdata;
 	unsigned long timeout;
 	int ret;
 
-	clk_prepare_enable(mhcd->alt_core_clk);
+	if (!IS_ERR(mhcd->alt_core_clk))
+		clk_prepare_enable(mhcd->alt_core_clk);
+
 	ret = msm_ehci_phy_reset(mhcd);
 	if (ret) {
 		dev_err(mhcd->dev, "phy_reset failed\n");
@@ -521,6 +562,11 @@
 	/* select ULPI phy */
 	writel_relaxed(0x80000000, USB_PORTSC);
 
+	pdata = mhcd->dev->platform_data;
+	if (pdata && pdata->use_sec_phy)
+		writel_relaxed(readl_relaxed(USB_PHY_CTRL2) | (1<<16),
+								USB_PHY_CTRL2);
+
 	msleep(100);
 
 	writel_relaxed(0x0, USB_AHBBURST);
@@ -528,7 +574,9 @@
 
 	/* Ensure that RESET operation is completed before turning off clock */
 	mb();
-	clk_disable_unprepare(mhcd->alt_core_clk);
+
+	if (!IS_ERR(mhcd->alt_core_clk))
+		clk_disable_unprepare(mhcd->alt_core_clk);
 
 	/*rising edge interrupts with Dp rise and fall enabled*/
 	msm_ulpi_write(mhcd, ULPI_INT_DP, ULPI_USB_INT_EN_RISE);
@@ -612,10 +660,14 @@
 	clk_disable_unprepare(mhcd->core_clk);
 
 	/* usb phy does not require TCXO clock, hence vote for TCXO disable */
-	ret = msm_xo_mode_vote(mhcd->xo_handle, MSM_XO_MODE_OFF);
-	if (ret)
-		dev_err(mhcd->dev, "%s failed to devote for "
-			"TCXO D0 buffer%d\n", __func__, ret);
+	if (!IS_ERR(mhcd->xo_clk)) {
+		clk_disable_unprepare(mhcd->xo_clk);
+	} else {
+		ret = msm_xo_mode_vote(mhcd->xo_handle, MSM_XO_MODE_OFF);
+		if (ret)
+			dev_err(mhcd->dev, "%s failed to devote for TCXO %d\n",
+								__func__, ret);
+	}
 
 	msm_ehci_config_vddcx(mhcd, 0);
 
@@ -626,6 +678,11 @@
 		enable_irq_wake(mhcd->pmic_gpio_dp_irq);
 		enable_irq(mhcd->pmic_gpio_dp_irq);
 	}
+	if (mhcd->async_irq) {
+		mhcd->async_irq_enabled = 1;
+		enable_irq_wake(mhcd->async_irq);
+		enable_irq(mhcd->async_irq);
+	}
 	wake_unlock(&mhcd->wlock);
 
 	dev_info(mhcd->dev, "EHCI USB in low power mode\n");
@@ -639,6 +696,7 @@
 	unsigned long timeout;
 	unsigned temp;
 	int ret;
+	unsigned long flags;
 
 	if (!atomic_read(&mhcd->in_lpm)) {
 		dev_dbg(mhcd->dev, "%s called in !in_lpm\n", __func__);
@@ -650,13 +708,25 @@
 		disable_irq_nosync(mhcd->pmic_gpio_dp_irq);
 		mhcd->pmic_gpio_dp_irq_enabled = 0;
 	}
+	spin_lock_irqsave(&mhcd->wakeup_lock, flags);
+	if (mhcd->async_irq_enabled) {
+		disable_irq_wake(mhcd->async_irq);
+		disable_irq_nosync(mhcd->async_irq);
+		mhcd->async_irq_enabled = 0;
+	}
+	spin_unlock_irqrestore(&mhcd->wakeup_lock, flags);
+
 	wake_lock(&mhcd->wlock);
 
 	/* Vote for TCXO when waking up the phy */
-	ret = msm_xo_mode_vote(mhcd->xo_handle, MSM_XO_MODE_ON);
-	if (ret)
-		dev_err(mhcd->dev, "%s failed to vote for "
-			"TCXO D0 buffer%d\n", __func__, ret);
+	if (!IS_ERR(mhcd->xo_clk)) {
+		clk_prepare_enable(mhcd->xo_clk);
+	} else {
+		ret = msm_xo_mode_vote(mhcd->xo_handle, MSM_XO_MODE_ON);
+		if (ret)
+			dev_err(mhcd->dev, "%s failed to vote for TCXO D0 %d\n",
+								__func__, ret);
+	}
 
 	clk_prepare_enable(mhcd->core_clk);
 	clk_prepare_enable(mhcd->iface_clk);
@@ -722,6 +792,36 @@
 	return ehci_irq(hcd);
 }
 
+static irqreturn_t msm_async_irq(int irq, void *data)
+{
+	struct msm_hcd *mhcd = data;
+	int ret;
+
+	mhcd->async_int_cnt++;
+	dev_dbg(mhcd->dev, "%s: hsusb host remote wakeup interrupt cnt: %u\n",
+			__func__, mhcd->async_int_cnt);
+
+	wake_lock(&mhcd->wlock);
+
+	spin_lock(&mhcd->wakeup_lock);
+	if (mhcd->async_irq_enabled) {
+		mhcd->async_irq_enabled = 0;
+		disable_irq_wake(irq);
+		disable_irq_nosync(irq);
+	}
+	spin_unlock(&mhcd->wakeup_lock);
+
+	if (!atomic_read(&mhcd->pm_usage_cnt)) {
+		ret = pm_runtime_get(mhcd->dev);
+		if ((ret == 1) || (ret == -EINPROGRESS))
+			pm_runtime_put_noidle(mhcd->dev);
+		else
+			atomic_set(&mhcd->pm_usage_cnt, 1);
+	}
+
+	return IRQ_HANDLED;
+}
+
 static irqreturn_t msm_ehci_host_wakeup_irq(int irq, void *data)
 {
 
@@ -751,6 +851,8 @@
 static int msm_ehci_reset(struct usb_hcd *hcd)
 {
 	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+	struct msm_hcd *mhcd = hcd_to_mhcd(hcd);
+	struct msm_usb_host_platform_data *pdata;
 	int retval;
 
 	ehci->caps = USB_CAPLENGTH;
@@ -785,6 +887,11 @@
 	/* Disable streaming mode and select host mode */
 	writel_relaxed(0x13, USB_USBMODE);
 
+	pdata = mhcd->dev->platform_data;
+	if (pdata && pdata->use_sec_phy)
+		writel_relaxed(readl_relaxed(USB_PHY_CTRL2) | (1<<16),
+								USB_PHY_CTRL2);
+
 	ehci_port_power(ehci, 1);
 	return 0;
 }
@@ -844,12 +951,10 @@
 
 	/* 60MHz alt_core_clk is for LINK to be used during PHY RESET  */
 	mhcd->alt_core_clk = clk_get(mhcd->dev, "alt_core_clk");
-	if (IS_ERR(mhcd->alt_core_clk)) {
-		dev_err(mhcd->dev, "failed to get alt_core_clk\n");
-		ret = PTR_ERR(mhcd->alt_core_clk);
-		return ret;
-	}
-	clk_set_rate(mhcd->alt_core_clk, 60000000);
+	if (IS_ERR(mhcd->alt_core_clk))
+		dev_dbg(mhcd->dev, "failed to get alt_core_clk\n");
+	else
+		clk_set_rate(mhcd->alt_core_clk, 60000000);
 
 	/* iface_clk is required for data transfers */
 	mhcd->iface_clk = clk_get(mhcd->dev, "iface_clk");
@@ -871,23 +976,56 @@
 	}
 	clk_set_rate(mhcd->core_clk, INT_MAX);
 
+	mhcd->phy_sleep_clk = clk_get(mhcd->dev, "sleep_clk");
+	if (IS_ERR(mhcd->phy_sleep_clk))
+		dev_dbg(mhcd->dev, "failed to get sleep_clk\n");
+	else
+		clk_prepare_enable(mhcd->phy_sleep_clk);
+
 	clk_prepare_enable(mhcd->core_clk);
 	clk_prepare_enable(mhcd->iface_clk);
 
 	return 0;
 
 put_clocks:
-	clk_disable_unprepare(mhcd->iface_clk);
-	clk_disable_unprepare(mhcd->core_clk);
+	if (!atomic_read(&mhcd->in_lpm)) {
+		clk_disable_unprepare(mhcd->iface_clk);
+		clk_disable_unprepare(mhcd->core_clk);
+	}
 	clk_put(mhcd->core_clk);
+	if (!IS_ERR(mhcd->phy_sleep_clk)) {
+		clk_disable_unprepare(mhcd->phy_sleep_clk);
+		clk_put(mhcd->phy_sleep_clk);
+	}
 put_iface_clk:
 	clk_put(mhcd->iface_clk);
 put_alt_core_clk:
-	clk_put(mhcd->alt_core_clk);
+	if (!IS_ERR(mhcd->alt_core_clk))
+		clk_put(mhcd->alt_core_clk);
 
 	return ret;
 }
 
+struct msm_usb_host_platform_data *ehci_msm2_dt_to_pdata(
+				struct platform_device *pdev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	struct msm_usb_host_platform_data *pdata;
+
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		dev_err(&pdev->dev, "unable to allocate platform data\n");
+		return NULL;
+	}
+
+	pdata->use_sec_phy = of_property_read_bool(node,
+					"qcom,usb2-enable-hsphy2");
+	of_property_read_u32(node, "qcom,usb2-power-budget",
+					&pdata->power_budget);
+	return pdata;
+}
+
+static u64 ehci_msm_dma_mask = DMA_BIT_MASK(64);
 static int __devinit ehci_msm2_probe(struct platform_device *pdev)
 {
 	struct usb_hcd *hcd;
@@ -899,6 +1037,19 @@
 
 	dev_dbg(&pdev->dev, "ehci_msm2 probe\n");
 
+	if (pdev->dev.of_node) {
+		dev_dbg(&pdev->dev, "device tree enabled\n");
+		pdev->dev.platform_data = ehci_msm2_dt_to_pdata(pdev);
+	}
+
+	if (!pdev->dev.platform_data)
+		dev_dbg(&pdev->dev, "No platform data given\n");
+
+	if (!pdev->dev.dma_mask)
+		pdev->dev.dma_mask = &ehci_msm_dma_mask;
+	if (!pdev->dev.coherent_dma_mask)
+		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+
 	hcd = usb_create_hcd(&msm_hc2_driver, &pdev->dev,
 				dev_name(&pdev->dev));
 	if (!hcd) {
@@ -932,19 +1083,40 @@
 	mhcd = hcd_to_mhcd(hcd);
 	mhcd->dev = &pdev->dev;
 
-	snprintf(pdev_name, PDEV_NAME_LEN, "%s.%d", pdev->name, pdev->id);
-	mhcd->xo_handle = msm_xo_get(MSM_XO_TCXO_D0, pdev_name);
-	if (IS_ERR(mhcd->xo_handle)) {
-		dev_err(&pdev->dev, "%s not able to get the handle "
-			"to vote for TCXO D0 buffer\n", __func__);
-		ret = PTR_ERR(mhcd->xo_handle);
-		goto unmap;
+	spin_lock_init(&mhcd->wakeup_lock);
+
+	mhcd->async_irq = platform_get_irq_byname(pdev, "async_irq");
+	if (mhcd->async_irq < 0) {
+		dev_dbg(&pdev->dev, "platform_get_irq for async_int failed\n");
+		mhcd->async_irq = 0;
+	} else {
+		ret = request_irq(mhcd->async_irq, msm_async_irq,
+				IRQF_TRIGGER_RISING, "msm_ehci_host", mhcd);
+		if (ret) {
+			dev_err(&pdev->dev, "request irq failed (ASYNC INT)\n");
+			goto unmap;
+		}
+		disable_irq(mhcd->async_irq);
 	}
 
-	ret = msm_xo_mode_vote(mhcd->xo_handle, MSM_XO_MODE_ON);
+	snprintf(pdev_name, PDEV_NAME_LEN, "%s.%d", pdev->name, pdev->id);
+	mhcd->xo_clk = clk_get(&pdev->dev, "xo");
+	if (!IS_ERR(mhcd->xo_clk)) {
+		ret = clk_prepare_enable(mhcd->xo_clk);
+	} else {
+		mhcd->xo_handle = msm_xo_get(MSM_XO_TCXO_D0, pdev_name);
+		if (IS_ERR(mhcd->xo_handle)) {
+			dev_err(&pdev->dev, "%s fail to get handle for X0 D0\n",
+								__func__);
+			ret = PTR_ERR(mhcd->xo_handle);
+			goto free_async_irq;
+		} else {
+			ret = msm_xo_mode_vote(mhcd->xo_handle, MSM_XO_MODE_ON);
+		}
+	}
 	if (ret) {
-		dev_err(&pdev->dev, "%s failed to vote for TCXO "
-			"D0 buffer%d\n", __func__, ret);
+		dev_err(&pdev->dev, "%s failed to vote for TCXO %d\n",
+								__func__, ret);
 		goto free_xo_handle;
 	}
 
@@ -1044,9 +1216,18 @@
 deinit_clocks:
 	msm_ehci_init_clocks(mhcd, 0);
 devote_xo_handle:
-	msm_xo_mode_vote(mhcd->xo_handle, MSM_XO_MODE_OFF);
+	if (!IS_ERR(mhcd->xo_clk))
+		clk_disable_unprepare(mhcd->xo_clk);
+	else
+		msm_xo_mode_vote(mhcd->xo_handle, MSM_XO_MODE_OFF);
 free_xo_handle:
-	msm_xo_put(mhcd->xo_handle);
+	if (!IS_ERR(mhcd->xo_clk))
+		clk_put(mhcd->xo_clk);
+	else
+		msm_xo_put(mhcd->xo_handle);
+free_async_irq:
+	if (mhcd->async_irq)
+		free_irq(mhcd->async_irq, mhcd);
 unmap:
 	iounmap(hcd->regs);
 put_hcd:
@@ -1065,13 +1246,22 @@
 			disable_irq_wake(mhcd->pmic_gpio_dp_irq);
 		free_irq(mhcd->pmic_gpio_dp_irq, mhcd);
 	}
+	if (mhcd->async_irq) {
+		if (mhcd->async_irq_enabled)
+			disable_irq_wake(mhcd->async_irq);
+		free_irq(mhcd->async_irq, mhcd);
+	}
 	device_init_wakeup(&pdev->dev, 0);
-	pm_runtime_disable(&pdev->dev);
 	pm_runtime_set_suspended(&pdev->dev);
 
 	usb_remove_hcd(hcd);
 
-	msm_xo_put(mhcd->xo_handle);
+	if (!IS_ERR(mhcd->xo_clk)) {
+		clk_disable_unprepare(mhcd->xo_clk);
+		clk_put(mhcd->xo_clk);
+	} else {
+		msm_xo_put(mhcd->xo_handle);
+	}
 	msm_ehci_vbus_power(mhcd, 0);
 	msm_ehci_init_vbus(mhcd, 0);
 	msm_ehci_ldo_enable(mhcd, 0);
@@ -1160,6 +1350,12 @@
 };
 #endif
 
+static const struct of_device_id ehci_msm2_dt_match[] = {
+	{ .compatible = "qcom,ehci-host",
+	},
+	{}
+};
+
 static struct platform_driver ehci_msm2_driver = {
 	.probe	= ehci_msm2_probe,
 	.remove	= __devexit_p(ehci_msm2_remove),
@@ -1168,5 +1364,6 @@
 #ifdef CONFIG_PM
 		.pm = &ehci_msm2_dev_pm_ops,
 #endif
+		.of_match_table = ehci_msm2_dt_match,
 	},
 };
diff --git a/drivers/usb/host/ehci-msm72k.c b/drivers/usb/host/ehci-msm72k.c
index 3e53c14..76cd977 100644
--- a/drivers/usb/host/ehci-msm72k.c
+++ b/drivers/usb/host/ehci-msm72k.c
@@ -1,6 +1,6 @@
 /* ehci-msm.c - HSUSB Host Controller Driver Implementation
  *
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * Partly derived from ehci-fsl.c and ehci-hcd.c
  * Copyright (c) 2000-2004 by David Brownell
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 78ece8d..717103d 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -485,6 +485,7 @@
 	struct xhci_bus_state *bus_state;
 	u16 link_state = 0;
 	u16 wake_mask = 0;
+	u16 test_mode = 0;
 
 	max_ports = xhci_get_ports(hcd, &port_array);
 	bus_state = &xhci->bus_state[hcd_index(hcd)];
@@ -628,6 +629,8 @@
 		put_unaligned(cpu_to_le32(status), (__le32 *) buf);
 		break;
 	case SetPortFeature:
+		/* The MSB of wIndex is the TEST Mode */
+		test_mode = (wIndex & 0xff00) >> 8;
 		if (wValue == USB_PORT_FEAT_LINK_STATE)
 			link_state = (wIndex & 0xff00) >> 3;
 		if (wValue == USB_PORT_FEAT_REMOTE_WAKE_MASK)
@@ -762,6 +765,23 @@
 
 			temp = xhci_readl(xhci, port_array[wIndex]);
 			break;
+		case USB_PORT_FEAT_TEST:
+			slot_id = xhci_find_slot_id_by_port(hcd, xhci,
+					wIndex + 1);
+			if (test_mode && test_mode <= 5) {
+				/* unlock to execute stop endpoint commands */
+				spin_unlock_irqrestore(&xhci->lock, flags);
+				xhci_stop_device(xhci, slot_id, 1);
+				spin_lock_irqsave(&xhci->lock, flags);
+				xhci_halt(xhci);
+
+				temp = xhci_readl(xhci, port_array[wIndex] + 1);
+				temp |= test_mode << 28;
+				xhci_writel(xhci, temp, port_array[wIndex] + 1);
+			} else {
+				goto error;
+			}
+			break;
 		default:
 			goto error;
 		}
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index e55fed7..79dcf2f 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -122,6 +122,7 @@
 	if (!hcd)
 		return -ENOMEM;
 
+	hcd_to_bus(hcd)->skip_resume = true;
 	hcd->rsrc_start = res->start;
 	hcd->rsrc_len = resource_size(res);
 
@@ -153,6 +154,7 @@
 		goto dealloc_usb2_hcd;
 	}
 
+	hcd_to_bus(xhci->shared_hcd)->skip_resume = true;
 	/*
 	 * Set the xHCI pointer before xhci_plat_setup() (aka hcd_driver.reset)
 	 * is called by usb_add_hcd().
@@ -173,6 +175,8 @@
 			usb_put_transceiver(phy);
 			goto put_usb3_hcd;
 		}
+		pm_runtime_set_active(&pdev->dev);
+		pm_runtime_enable(&pdev->dev);
 	} else {
 		pm_runtime_no_callbacks(&pdev->dev);
 		pm_runtime_set_active(&pdev->dev);
@@ -205,6 +209,7 @@
 	struct usb_hcd	*hcd = platform_get_drvdata(dev);
 	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
 
+
 	usb_remove_hcd(xhci->shared_hcd);
 	usb_put_hcd(xhci->shared_hcd);
 
@@ -225,11 +230,74 @@
 	return 0;
 }
 
+#ifdef CONFIG_PM_RUNTIME
+static int xhci_msm_runtime_idle(struct device *dev)
+{
+	dev_dbg(dev, "xhci msm runtime idle\n");
+	return 0;
+}
+
+static int xhci_msm_runtime_suspend(struct device *dev)
+{
+	dev_dbg(dev, "xhci msm runtime suspend\n");
+	/*
+	 * Notify OTG about suspend.  It takes care of
+	 * putting the hardware in LPM.
+	 */
+	if (phy)
+		return usb_phy_set_suspend(phy, 1);
+
+	return 0;
+}
+
+static int xhci_msm_runtime_resume(struct device *dev)
+{
+	dev_dbg(dev, "xhci msm runtime resume\n");
+
+	if (phy)
+		return usb_phy_set_suspend(phy, 0);
+
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+static int xhci_msm_pm_suspend(struct device *dev)
+{
+	dev_dbg(dev, "xhci-msm PM suspend\n");
+
+	if (phy)
+		return usb_phy_set_suspend(phy, 1);
+
+	return 0;
+}
+
+static int xhci_msm_pm_resume(struct device *dev)
+{
+	dev_dbg(dev, "xhci-msm PM resume\n");
+
+	if (pm_runtime_suspended(dev))
+		return 0;
+
+	if (phy)
+		return usb_phy_set_suspend(phy, 0);
+
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops xhci_msm_dev_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(xhci_msm_pm_suspend, xhci_msm_pm_resume)
+	SET_RUNTIME_PM_OPS(xhci_msm_runtime_suspend, xhci_msm_runtime_resume,
+				xhci_msm_runtime_idle)
+};
+
 static struct platform_driver usb_xhci_driver = {
 	.probe	= xhci_plat_probe,
 	.remove	= xhci_plat_remove,
 	.driver	= {
 		.name = "xhci-hcd",
+		.pm = &xhci_msm_dev_pm_ops,
 	},
 };
 MODULE_ALIAS("platform:xhci-hcd");
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 38a3c15..323b481 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -145,29 +145,37 @@
  */
 static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring)
 {
-	union xhci_trb *next;
 	unsigned long long addr;
 
 	ring->deq_updates++;
 
-	/* If this is not event ring, there is one more usable TRB */
+	/*
+	 * If this is not event ring, and the dequeue pointer
+	 * is not on a link TRB, there is one more usable TRB
+	 */
 	if (ring->type != TYPE_EVENT &&
 			!last_trb(xhci, ring, ring->deq_seg, ring->dequeue))
 		ring->num_trbs_free++;
-	next = ++(ring->dequeue);
 
-	/* Update the dequeue pointer further if that was a link TRB or we're at
-	 * the end of an event ring segment (which doesn't have link TRBS)
-	 */
-	while (last_trb(xhci, ring, ring->deq_seg, next)) {
-		if (ring->type == TYPE_EVENT &&	last_trb_on_last_seg(xhci,
-				ring, ring->deq_seg, next)) {
-			ring->cycle_state = (ring->cycle_state ? 0 : 1);
+	do {
+		/*
+		 * Update the dequeue pointer further if that was a link TRB or
+		 * we're at the end of an event ring segment (which doesn't have
+		 * link TRBS)
+		 */
+		if (last_trb(xhci, ring, ring->deq_seg, ring->dequeue)) {
+			if (ring->type == TYPE_EVENT &&
+					last_trb_on_last_seg(xhci, ring,
+						ring->deq_seg, ring->dequeue)) {
+				ring->cycle_state = (ring->cycle_state ? 0 : 1);
+			}
+			ring->deq_seg = ring->deq_seg->next;
+			ring->dequeue = ring->deq_seg->trbs;
+		} else {
+			ring->dequeue++;
 		}
-		ring->deq_seg = ring->deq_seg->next;
-		ring->dequeue = ring->deq_seg->trbs;
-		next = ring->dequeue;
-	}
+	} while (last_trb(xhci, ring, ring->deq_seg, ring->dequeue));
+
 	addr = (unsigned long long) xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue);
 }
 
@@ -885,6 +893,17 @@
 	num_trbs_free_temp = ep_ring->num_trbs_free;
 	dequeue_temp = ep_ring->dequeue;
 
+	/* If we get two back-to-back stalls, and the first stalled transfer
+	 * ends just before a link TRB, the dequeue pointer will be left on
+	 * the link TRB by the code in the while loop.  So we have to update
+	 * the dequeue pointer one segment further, or we'll jump off
+	 * the segment into la-la-land.
+	 */
+	if (last_trb(xhci, ep_ring, ep_ring->deq_seg, ep_ring->dequeue)) {
+		ep_ring->deq_seg = ep_ring->deq_seg->next;
+		ep_ring->dequeue = ep_ring->deq_seg->trbs;
+	}
+
 	while (ep_ring->dequeue != dev->eps[ep_index].queued_deq_ptr) {
 		/* We have more usable TRBs */
 		ep_ring->num_trbs_free++;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 2c26998..df41b4f 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -2464,7 +2464,7 @@
 	/* Wait for the configure endpoint command to complete */
 	timeleft = wait_for_completion_interruptible_timeout(
 			cmd_completion,
-			USB_CTRL_SET_TIMEOUT);
+			XHCI_CMD_DEFAULT_TIMEOUT);
 	if (timeleft <= 0) {
 		xhci_warn(xhci, "%s while waiting for %s command\n",
 				timeleft == 0 ? "Timeout" : "Signal",
@@ -3433,7 +3433,7 @@
 
 	/* XXX: how much time for xHC slot assignment? */
 	timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev,
-			USB_CTRL_SET_TIMEOUT);
+			XHCI_CMD_DEFAULT_TIMEOUT);
 	if (timeleft <= 0) {
 		xhci_warn(xhci, "%s while waiting for a slot\n",
 				timeleft == 0 ? "Timeout" : "Signal");
@@ -3549,7 +3549,7 @@
 
 	/* ctrl tx can take up to 5 sec; XXX: need more time for xHC? */
 	timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev,
-			USB_CTRL_SET_TIMEOUT);
+			XHCI_CMD_DEFAULT_TIMEOUT);
 	/* FIXME: From section 4.3.4: "Software shall be responsible for timing
 	 * the SetAddress() "recovery interval" required by USB and aborting the
 	 * command on a timeout.
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 127b0e9..8f3651b 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1248,6 +1248,9 @@
 	union xhci_trb		*last_trb;
 };
 
+/* xHCI command default timeout value */
+#define XHCI_CMD_DEFAULT_TIMEOUT	(5 * HZ)
+
 struct xhci_dequeue_state {
 	struct xhci_segment *new_deq_seg;
 	union xhci_trb *new_deq_ptr;
diff --git a/drivers/usb/misc/diag_bridge.c b/drivers/usb/misc/diag_bridge.c
index ae7e1b6..1ee1c8e 100644
--- a/drivers/usb/misc/diag_bridge.c
+++ b/drivers/usb/misc/diag_bridge.c
@@ -1,5 +1,4 @@
-/*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -31,6 +30,7 @@
 #define DRIVER_DESC	"USB host diag bridge driver"
 #define DRIVER_VERSION	"1.0"
 
+#define MAX_DIAG_BRIDGE_DEVS	2
 #define AUTOSUSP_DELAY_WITH_USB 1000
 
 struct diag_bridge {
@@ -52,12 +52,18 @@
 	unsigned		pending_reads;
 	unsigned		pending_writes;
 };
-struct diag_bridge *__dev;
+struct diag_bridge *__dev[MAX_DIAG_BRIDGE_DEVS];
 
-int diag_bridge_open(struct diag_bridge_ops *ops)
+int diag_bridge_open(int id, struct diag_bridge_ops *ops)
 {
-	struct diag_bridge	*dev = __dev;
+	struct diag_bridge	*dev;
 
+	if (id < 0 || id >= MAX_DIAG_BRIDGE_DEVS) {
+		pr_err("Invalid device ID");
+		return -ENODEV;
+	}
+
+	dev = __dev[id];
 	if (!dev) {
 		pr_err("dev is null");
 		return -ENODEV;
@@ -86,16 +92,23 @@
 static void diag_bridge_delete(struct kref *kref)
 {
 	struct diag_bridge *dev = container_of(kref, struct diag_bridge, kref);
+	int id = dev->pdev->id;
 
 	usb_put_dev(dev->udev);
-	__dev = 0;
+	__dev[id] = 0;
 	kfree(dev);
 }
 
-void diag_bridge_close(void)
+void diag_bridge_close(int id)
 {
-	struct diag_bridge	*dev = __dev;
+	struct diag_bridge	*dev;
 
+	if (id < 0 || id >= MAX_DIAG_BRIDGE_DEVS) {
+		pr_err("Invalid device ID");
+		return;
+	}
+
+	dev = __dev[id];
 	if (!dev) {
 		pr_err("dev is null");
 		return;
@@ -141,15 +154,21 @@
 	kref_put(&dev->kref, diag_bridge_delete);
 }
 
-int diag_bridge_read(char *data, int size)
+int diag_bridge_read(int id, char *data, int size)
 {
 	struct urb		*urb = NULL;
 	unsigned int		pipe;
-	struct diag_bridge	*dev = __dev;
+	struct diag_bridge	*dev;
 	int			ret;
 
+	if (id < 0 || id >= MAX_DIAG_BRIDGE_DEVS) {
+		pr_err("Invalid device ID");
+		return -ENODEV;
+	}
+
 	pr_debug("reading %d bytes", size);
 
+	dev = __dev[id];
 	if (!dev) {
 		pr_err("device is disconnected");
 		return -ENODEV;
@@ -243,15 +262,21 @@
 	kref_put(&dev->kref, diag_bridge_delete);
 }
 
-int diag_bridge_write(char *data, int size)
+int diag_bridge_write(int id, char *data, int size)
 {
 	struct urb		*urb = NULL;
 	unsigned int		pipe;
-	struct diag_bridge	*dev = __dev;
+	struct diag_bridge	*dev;
 	int			ret;
 
+	if (id < 0 || id >= MAX_DIAG_BRIDGE_DEVS) {
+		pr_err("Invalid device ID");
+		return -ENODEV;
+	}
+
 	pr_debug("writing %d bytes", size);
 
+	dev = __dev[id];
 	if (!dev) {
 		pr_err("device is disconnected");
 		return -ENODEV;
@@ -328,28 +353,30 @@
 static ssize_t diag_read_stats(struct file *file, char __user *ubuf,
 				size_t count, loff_t *ppos)
 {
-	struct diag_bridge	*dev = __dev;
 	char			*buf;
-	int			ret;
-
-	if (!dev)
-		return -ENODEV;
+	int			i, ret = 0;
 
 	buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
 
-	ret = scnprintf(buf, DEBUG_BUF_SIZE,
-			"epin:%d, epout:%d\n"
-			"bytes to host: %lu\n"
-			"bytes to mdm: %lu\n"
-			"pending reads: %u\n"
-			"pending writes: %u\n"
-			"last error: %d\n",
-			dev->in_epAddr, dev->out_epAddr,
-			dev->bytes_to_host, dev->bytes_to_mdm,
-			dev->pending_reads, dev->pending_writes,
-			dev->err);
+	for (i = 0; i < MAX_DIAG_BRIDGE_DEVS; i++) {
+		struct diag_bridge *dev = __dev[i];
+		if (!dev)
+			continue;
+
+		ret += scnprintf(buf, DEBUG_BUF_SIZE,
+				"epin:%d, epout:%d\n"
+				"bytes to host: %lu\n"
+				"bytes to mdm: %lu\n"
+				"pending reads: %u\n"
+				"pending writes: %u\n"
+				"last error: %d\n",
+				dev->in_epAddr, dev->out_epAddr,
+				dev->bytes_to_host, dev->bytes_to_mdm,
+				dev->pending_reads, dev->pending_writes,
+				dev->err);
+	}
 
 	ret = simple_read_from_buffer(ubuf, count, ppos, buf, ret);
 	kfree(buf);
@@ -359,11 +386,14 @@
 static ssize_t diag_reset_stats(struct file *file, const char __user *buf,
 				 size_t count, loff_t *ppos)
 {
-	struct diag_bridge	*dev = __dev;
+	int i;
 
-	if (dev) {
-		dev->bytes_to_host = dev->bytes_to_mdm = 0;
-		dev->pending_reads = dev->pending_writes = 0;
+	for (i = 0; i < MAX_DIAG_BRIDGE_DEVS; i++) {
+		struct diag_bridge *dev = __dev[i];
+		if (dev) {
+			dev->bytes_to_host = dev->bytes_to_mdm = 0;
+			dev->pending_reads = dev->pending_writes = 0;
+		}
 	}
 
 	return count;
@@ -407,8 +437,7 @@
 	struct diag_bridge		*dev;
 	struct usb_host_interface	*ifc_desc;
 	struct usb_endpoint_descriptor	*ep_desc;
-	int				i;
-	int				ret = -ENOMEM;
+	int				i, devid, ret = -ENOMEM;
 	__u8				ifc_num;
 
 	pr_debug("id:%lu", id->driver_info);
@@ -416,21 +445,31 @@
 	ifc_num = ifc->cur_altsetting->desc.bInterfaceNumber;
 
 	/* is this interface supported ? */
-	if (ifc_num != id->driver_info)
+	if (ifc_num != (id->driver_info & 0xFF))
 		return -ENODEV;
 
+	devid = (id->driver_info >> 8) & 0xFF;
+	if (devid < 0 || devid >= MAX_DIAG_BRIDGE_DEVS)
+		return -ENODEV;
+
+	/* already probed? */
+	if (__dev[devid]) {
+		pr_err("Diag device already probed");
+		return -ENODEV;
+	}
+
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	if (!dev) {
 		pr_err("unable to allocate dev");
 		return -ENOMEM;
 	}
-	dev->pdev = platform_device_alloc("diag_bridge", -1);
+	dev->pdev = platform_device_alloc("diag_bridge", devid);
 	if (!dev->pdev) {
 		pr_err("unable to allocate platform device");
 		kfree(dev);
 		return -ENOMEM;
 	}
-	__dev = dev;
+	__dev[devid] = dev;
 
 	dev->udev = usb_get_dev(interface_to_usbdev(ifc));
 	dev->ifc = ifc;
@@ -518,17 +557,21 @@
 }
 
 #define VALID_INTERFACE_NUM	0
+#define DEV_ID(n)		((n)<<8)
+
 static const struct usb_device_id diag_bridge_ids[] = {
 	{ USB_DEVICE(0x5c6, 0x9001),
-	.driver_info = VALID_INTERFACE_NUM, },
+	.driver_info = VALID_INTERFACE_NUM | DEV_ID(0), },
 	{ USB_DEVICE(0x5c6, 0x9034),
-	.driver_info = VALID_INTERFACE_NUM, },
+	.driver_info = VALID_INTERFACE_NUM | DEV_ID(0), },
 	{ USB_DEVICE(0x5c6, 0x9048),
-	.driver_info = VALID_INTERFACE_NUM, },
+	.driver_info = VALID_INTERFACE_NUM | DEV_ID(0), },
 	{ USB_DEVICE(0x5c6, 0x904C),
-	.driver_info = VALID_INTERFACE_NUM, },
+	.driver_info = VALID_INTERFACE_NUM | DEV_ID(0), },
 	{ USB_DEVICE(0x5c6, 0x9075),
-	.driver_info = VALID_INTERFACE_NUM, },
+	.driver_info = VALID_INTERFACE_NUM | DEV_ID(0), },
+	{ USB_DEVICE(0x5c6, 0x9079),
+	.driver_info = VALID_INTERFACE_NUM | DEV_ID(1), },
 
 	{} /* terminating entry */
 };
diff --git a/drivers/usb/misc/diag_bridge_test.c b/drivers/usb/misc/diag_bridge_test.c
index 5bc0828..18d8a51 100644
--- a/drivers/usb/misc/diag_bridge_test.c
+++ b/drivers/usb/misc/diag_bridge_test.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/drivers/usb/misc/ehset.c b/drivers/usb/misc/ehset.c
index 30879e0..ebaf567 100644
--- a/drivers/usb/misc/ehset.c
+++ b/drivers/usb/misc/ehset.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/usb/misc/ks_bridge.c b/drivers/usb/misc/ks_bridge.c
index 86c59e7..b0785f6 100644
--- a/drivers/usb/misc/ks_bridge.c
+++ b/drivers/usb/misc/ks_bridge.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012-2013, 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
@@ -33,6 +33,24 @@
 #define DRIVER_DESC	"USB host ks bridge driver"
 #define DRIVER_VERSION	"1.0"
 
+enum bus_id {
+	BUS_HSIC,
+	BUS_USB,
+	BUS_UNDEF,
+};
+
+#define BUSNAME_LEN	20
+
+static enum bus_id str_to_busid(const char *name)
+{
+	if (!strncasecmp("msm_hsic_host", name, BUSNAME_LEN))
+		return BUS_HSIC;
+	if (!strncasecmp("msm_ehci_host.0", name, BUSNAME_LEN))
+		return BUS_USB;
+
+	return BUS_UNDEF;
+}
+
 struct data_pkt {
 	int			n_read;
 	char			*buf;
@@ -44,9 +62,9 @@
 #define FILE_OPENED		BIT(0)
 #define USB_DEV_CONNECTED	BIT(1)
 #define NO_RX_REQS		10
-#define NO_BRIDGE_INSTANCES	2
-#define BOOT_BRIDGE_INDEX	0
-#define EFS_BRIDGE_INDEX	1
+#define NO_BRIDGE_INSTANCES	4
+#define EFS_HSIC_BRIDGE_INDEX	2
+#define EFS_USB_BRIDGE_INDEX	3
 #define MAX_DATA_PKT_SIZE	16384
 #define PENDING_URB_TIMEOUT	10
 
@@ -60,7 +78,7 @@
 	struct list_head	to_ks_list;
 	wait_queue_head_t	ks_wait_q;
 	wait_queue_head_t	pending_urb_wait;
-	struct miscdevice	*fs_dev;
+	struct miscdevice	fs_dev;
 	atomic_t		tx_pending_cnt;
 	atomic_t		rx_pending_cnt;
 
@@ -74,7 +92,6 @@
 	struct usb_anchor	submitted;
 
 	unsigned long		flags;
-	unsigned int		alloced_read_pkts;
 
 #define DBG_MSG_LEN   40
 #define DBG_MAX_MSG   500
@@ -141,13 +158,15 @@
 }
 
 
+static void
+submit_one_urb(struct ks_bridge *ksb, gfp_t flags, struct data_pkt *pkt);
 static ssize_t ksb_fs_read(struct file *fp, char __user *buf,
 				size_t count, loff_t *pos)
 {
 	int ret;
 	unsigned long flags;
 	struct ks_bridge *ksb = fp->private_data;
-	struct data_pkt *pkt;
+	struct data_pkt *pkt = NULL;
 	size_t space, copied;
 
 read_start:
@@ -168,37 +187,53 @@
 
 	space = count;
 	copied = 0;
-	while (!list_empty(&ksb->to_ks_list) && space) {
+	while (!list_empty(&ksb->to_ks_list) && space &&
+			test_bit(USB_DEV_CONNECTED, &ksb->flags)) {
 		size_t len;
 
 		pkt = list_first_entry(&ksb->to_ks_list, struct data_pkt, list);
+		list_del_init(&pkt->list);
 		len = min_t(size_t, space, pkt->len - pkt->n_read);
 		spin_unlock_irqrestore(&ksb->lock, flags);
 
 		ret = copy_to_user(buf + copied, pkt->buf + pkt->n_read, len);
 		if (ret) {
-			pr_err("copy_to_user failed err:%d\n", ret);
+			dev_err(ksb->fs_dev.this_device,
+					"copy_to_user failed err:%d\n", ret);
 			ksb_free_data_pkt(pkt);
-			ksb->alloced_read_pkts--;
-			return ret;
+			return -EFAULT;
 		}
 
 		pkt->n_read += len;
 		space -= len;
 		copied += len;
 
-		spin_lock_irqsave(&ksb->lock, flags);
 		if (pkt->n_read == pkt->len) {
-			list_del_init(&pkt->list);
-			ksb_free_data_pkt(pkt);
-			ksb->alloced_read_pkts--;
+			/*
+			 * re-init the packet and queue it
+			 * for more data.
+			 */
+			pkt->n_read = 0;
+			pkt->len = MAX_DATA_PKT_SIZE;
+			submit_one_urb(ksb, GFP_KERNEL, pkt);
+			pkt = NULL;
 		}
+		spin_lock_irqsave(&ksb->lock, flags);
+	}
+
+	/* put the partial packet back in the list */
+	if (!space && pkt && pkt->n_read != pkt->len) {
+		if (test_bit(USB_DEV_CONNECTED, &ksb->flags))
+			list_add(&pkt->list, &ksb->to_ks_list);
+		else
+			ksb_free_data_pkt(pkt);
 	}
 	spin_unlock_irqrestore(&ksb->lock, flags);
 
 	dbg_log_event(ksb, "KS_READ", copied, 0);
 
-	pr_debug("count:%d space:%d copied:%d", count, space, copied);
+	dev_dbg(ksb->fs_dev.this_device, "count:%d space:%d copied:%d", count,
+			space, copied);
 
 	return copied;
 }
@@ -209,13 +244,14 @@
 	struct ks_bridge *ksb = pkt->ctxt;
 
 	dbg_log_event(ksb, "C TX_URB", urb->status, 0);
-	pr_debug("status:%d", urb->status);
+	dev_dbg(&ksb->udev->dev, "status:%d", urb->status);
 
 	if (test_bit(USB_DEV_CONNECTED, &ksb->flags))
 		usb_autopm_put_interface_async(ksb->ifc);
 
 	if (urb->status < 0)
-		pr_err_ratelimited("urb failed with err:%d", urb->status);
+		pr_err_ratelimited("%s: urb failed with err:%d",
+				ksb->fs_dev.name, urb->status);
 
 	ksb_free_data_pkt(pkt);
 
@@ -241,14 +277,16 @@
 
 		urb = usb_alloc_urb(0, GFP_KERNEL);
 		if (!urb) {
-			pr_err_ratelimited("unable to allocate urb");
+			pr_err_ratelimited("%s: unable to allocate urb",
+					ksb->fs_dev.name);
 			ksb_free_data_pkt(pkt);
 			return;
 		}
 
 		ret = usb_autopm_get_interface(ksb->ifc);
 		if (ret < 0 && ret != -EAGAIN && ret != -EACCES) {
-			pr_err_ratelimited("autopm_get failed:%d", ret);
+			pr_err_ratelimited("%s: autopm_get failed:%d",
+					ksb->fs_dev.name, ret);
 			usb_free_urb(urb);
 			ksb_free_data_pkt(pkt);
 			return;
@@ -262,7 +300,7 @@
 		atomic_inc(&ksb->tx_pending_cnt);
 		ret = usb_submit_urb(urb, GFP_KERNEL);
 		if (ret) {
-			pr_err("out urb submission failed");
+			dev_err(&ksb->udev->dev, "out urb submission failed");
 			usb_unanchor_urb(urb);
 			usb_free_urb(urb);
 			ksb_free_data_pkt(pkt);
@@ -290,15 +328,20 @@
 	if (!test_bit(USB_DEV_CONNECTED, &ksb->flags))
 		return -ENODEV;
 
+	if (count > MAX_DATA_PKT_SIZE)
+		count = MAX_DATA_PKT_SIZE;
+
 	pkt = ksb_alloc_data_pkt(count, GFP_KERNEL, ksb);
 	if (IS_ERR(pkt)) {
-		pr_err("unable to allocate data packet");
+		dev_err(ksb->fs_dev.this_device,
+				"unable to allocate data packet");
 		return PTR_ERR(pkt);
 	}
 
 	ret = copy_from_user(pkt->buf, buf, count);
 	if (ret) {
-		pr_err("copy_from_user failed: err:%d", ret);
+		dev_err(ksb->fs_dev.this_device,
+				"copy_from_user failed: err:%d", ret);
 		ksb_free_data_pkt(pkt);
 		return ret;
 	}
@@ -312,39 +355,19 @@
 	return count;
 }
 
-static int efs_fs_open(struct inode *ip, struct file *fp)
-{
-	struct ks_bridge *ksb = __ksb[EFS_BRIDGE_INDEX];
-
-	pr_debug(":%s", ksb->name);
-	dbg_log_event(ksb, "EFS-FS-OPEN", 0, 0);
-
-	if (!ksb) {
-		pr_err("ksb is being removed");
-		return -ENODEV;
-	}
-
-	fp->private_data = ksb;
-	set_bit(FILE_OPENED, &ksb->flags);
-
-	if (test_bit(USB_DEV_CONNECTED, &ksb->flags))
-		queue_work(ksb->wq, &ksb->start_rx_work);
-
-	return 0;
-}
-
 static int ksb_fs_open(struct inode *ip, struct file *fp)
 {
-	struct ks_bridge *ksb = __ksb[BOOT_BRIDGE_INDEX];
+	struct miscdevice *mdev = fp->private_data;
+	struct ks_bridge *ksb = container_of(mdev, struct ks_bridge, fs_dev);
 
-	pr_debug(":%s", ksb->name);
-	dbg_log_event(ksb, "KS-FS-OPEN", 0, 0);
-
-	if (!ksb) {
-		pr_err("ksb is being removed");
+	if (IS_ERR(ksb)) {
+		pr_err("ksb device not found");
 		return -ENODEV;
 	}
 
+	dev_dbg(ksb->fs_dev.this_device, ":%s", ksb->fs_dev.name);
+	dbg_log_event(ksb, "FS-OPEN", 0, 0);
+
 	fp->private_data = ksb;
 	set_bit(FILE_OPENED, &ksb->flags);
 
@@ -358,7 +381,7 @@
 {
 	struct ks_bridge	*ksb = fp->private_data;
 
-	pr_debug(":%s", ksb->name);
+	dev_dbg(ksb->fs_dev.this_device, ":%s", ksb->fs_dev.name);
 	dbg_log_event(ksb, "FS-RELEASE", 0, 0);
 
 	clear_bit(FILE_OPENED, &ksb->flags);
@@ -375,60 +398,67 @@
 	.release = ksb_fs_release,
 };
 
-static struct miscdevice ksb_fboot_dev = {
-	.minor = MISC_DYNAMIC_MINOR,
-	.name = "ks_bridge",
-	.fops = &ksb_fops,
+static struct miscdevice ksb_fboot_dev[] = {
+	{
+		.minor = MISC_DYNAMIC_MINOR,
+		.name = "ks_hsic_bridge",
+		.fops = &ksb_fops,
+	},
+	{
+		.minor = MISC_DYNAMIC_MINOR,
+		.name = "ks_usb_bridge",
+		.fops = &ksb_fops,
+	},
 };
 
 static const struct file_operations efs_fops = {
 	.owner = THIS_MODULE,
 	.read = ksb_fs_read,
 	.write = ksb_fs_write,
-	.open = efs_fs_open,
+	.open = ksb_fs_open,
 	.release = ksb_fs_release,
 };
 
-static struct miscdevice ksb_efs_dev = {
+static struct miscdevice ksb_efs_hsic_dev = {
 	.minor = MISC_DYNAMIC_MINOR,
-	.name = "efs_bridge",
+	.name = "efs_hsic_bridge",
 	.fops = &efs_fops,
 };
 
+static struct miscdevice ksb_efs_usb_dev = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = "efs_usb_bridge",
+	.fops = &efs_fops,
+};
 static const struct usb_device_id ksb_usb_ids[] = {
 	{ USB_DEVICE(0x5c6, 0x9008),
 	.driver_info = (unsigned long)&ksb_fboot_dev, },
 	{ USB_DEVICE(0x5c6, 0x9048),
-	.driver_info = (unsigned long)&ksb_efs_dev, },
+	.driver_info = (unsigned long)&ksb_efs_hsic_dev, },
 	{ USB_DEVICE(0x5c6, 0x904C),
-	.driver_info = (unsigned long)&ksb_efs_dev, },
+	.driver_info = (unsigned long)&ksb_efs_hsic_dev, },
 	{ USB_DEVICE(0x5c6, 0x9075),
-	.driver_info = (unsigned long)&ksb_efs_dev, },
+	.driver_info = (unsigned long)&ksb_efs_hsic_dev, },
+	{ USB_DEVICE(0x5c6, 0x9079),
+	.driver_info = (unsigned long)&ksb_efs_usb_dev, },
 
 	{} /* terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, ksb_usb_ids);
 
 static void ksb_rx_cb(struct urb *urb);
-static void submit_one_urb(struct ks_bridge *ksb)
+static void
+submit_one_urb(struct ks_bridge *ksb, gfp_t flags, struct data_pkt *pkt)
 {
-	struct data_pkt	*pkt;
 	struct urb *urb;
 	int ret;
 
-	pkt = ksb_alloc_data_pkt(MAX_DATA_PKT_SIZE, GFP_ATOMIC, ksb);
-	if (IS_ERR(pkt)) {
-		pr_err("unable to allocate data pkt");
-		return;
-	}
-
-	urb = usb_alloc_urb(0, GFP_ATOMIC);
+	urb = usb_alloc_urb(0, flags);
 	if (!urb) {
-		pr_err("unable to allocate urb");
+		dev_err(&ksb->udev->dev, "unable to allocate urb");
 		ksb_free_data_pkt(pkt);
 		return;
 	}
-	ksb->alloced_read_pkts++;
 
 	usb_fill_bulk_urb(urb, ksb->udev, ksb->in_pipe,
 			pkt->buf, pkt->len,
@@ -439,18 +469,16 @@
 		usb_unanchor_urb(urb);
 		usb_free_urb(urb);
 		ksb_free_data_pkt(pkt);
-		ksb->alloced_read_pkts--;
 		return;
 	}
 
 	atomic_inc(&ksb->rx_pending_cnt);
-	ret = usb_submit_urb(urb, GFP_ATOMIC);
+	ret = usb_submit_urb(urb, flags);
 	if (ret) {
-		pr_err("in urb submission failed");
+		dev_err(&ksb->udev->dev, "in urb submission failed");
 		usb_unanchor_urb(urb);
 		usb_free_urb(urb);
 		ksb_free_data_pkt(pkt);
-		ksb->alloced_read_pkts--;
 		atomic_dec(&ksb->rx_pending_cnt);
 		wake_up(&ksb->pending_urb_wait);
 		return;
@@ -464,29 +492,36 @@
 {
 	struct data_pkt *pkt = urb->context;
 	struct ks_bridge *ksb = pkt->ctxt;
+	bool wakeup = true;
 
 	dbg_log_event(ksb, "C RX_URB", urb->status, urb->actual_length);
 
-	pr_debug("status:%d actual:%d", urb->status, urb->actual_length);
+	dev_dbg(&ksb->udev->dev, "status:%d actual:%d", urb->status,
+			urb->actual_length);
 
 	/*non zero len of data received while unlinking urb*/
-	if (urb->status == -ENOENT && urb->actual_length > 0)
+	if (urb->status == -ENOENT && (urb->actual_length > 0)) {
+		/*
+		 * If we wakeup the reader process now, it may
+		 * queue the URB before its reject flag gets
+		 * cleared.
+		 */
+		wakeup = false;
 		goto add_to_list;
+	}
 
 	if (urb->status < 0) {
 		if (urb->status != -ESHUTDOWN && urb->status != -ENOENT
 				&& urb->status != -EPROTO)
-			pr_err_ratelimited("urb failed with err:%d",
-					urb->status);
+			pr_err_ratelimited("%s: urb failed with err:%d",
+					ksb->fs_dev.name, urb->status);
 		ksb_free_data_pkt(pkt);
-		ksb->alloced_read_pkts--;
 		goto done;
 	}
 
 	if (urb->actual_length == 0) {
-		ksb_free_data_pkt(pkt);
-		ksb->alloced_read_pkts--;
-		goto resubmit_urb;
+		submit_one_urb(ksb, GFP_ATOMIC, pkt);
+		goto done;
 	}
 
 add_to_list:
@@ -494,12 +529,9 @@
 	pkt->len = urb->actual_length;
 	list_add_tail(&pkt->list, &ksb->to_ks_list);
 	spin_unlock(&ksb->lock);
-
 	/* wake up read thread */
-	wake_up(&ksb->ks_wait_q);
-
-resubmit_urb:
-	submit_one_urb(ksb);
+	if (wakeup)
+		wake_up(&ksb->ks_wait_q);
 done:
 	atomic_dec(&ksb->rx_pending_cnt);
 	wake_up(&ksb->pending_urb_wait);
@@ -513,34 +545,35 @@
 	struct urb *urb;
 	int i = 0;
 	int ret;
+	bool put = true;
 
+	ret = usb_autopm_get_interface(ksb->ifc);
+	if (ret < 0) {
+		if (ret != -EAGAIN && ret != -EACCES) {
+			pr_err_ratelimited("%s: autopm_get failed:%d",
+					ksb->fs_dev.name, ret);
+			return;
+		}
+		put = false;
+	}
 	for (i = 0; i < NO_RX_REQS; i++) {
 
 		if (!test_bit(USB_DEV_CONNECTED, &ksb->flags))
-			return;
+			break;
 
 		pkt = ksb_alloc_data_pkt(MAX_DATA_PKT_SIZE, GFP_KERNEL, ksb);
 		if (IS_ERR(pkt)) {
-			pr_err("unable to allocate data pkt");
-			return;
+			dev_err(&ksb->udev->dev, "unable to allocate data pkt");
+			break;
 		}
 
 		urb = usb_alloc_urb(0, GFP_KERNEL);
 		if (!urb) {
-			pr_err("unable to allocate urb");
+			dev_err(&ksb->udev->dev, "unable to allocate urb");
 			ksb_free_data_pkt(pkt);
-			return;
+			break;
 		}
 
-		ret = usb_autopm_get_interface(ksb->ifc);
-		if (ret < 0 && ret != -EAGAIN && ret != -EACCES) {
-			pr_err_ratelimited("autopm_get failed:%d", ret);
-			usb_free_urb(urb);
-			ksb_free_data_pkt(pkt);
-			return;
-		}
-		ksb->alloced_read_pkts++;
-
 		usb_fill_bulk_urb(urb, ksb->udev, ksb->in_pipe,
 				pkt->buf, pkt->len,
 				ksb_rx_cb, pkt);
@@ -551,20 +584,19 @@
 		atomic_inc(&ksb->rx_pending_cnt);
 		ret = usb_submit_urb(urb, GFP_KERNEL);
 		if (ret) {
-			pr_err("in urb submission failed");
+			dev_err(&ksb->udev->dev, "in urb submission failed");
 			usb_unanchor_urb(urb);
 			usb_free_urb(urb);
 			ksb_free_data_pkt(pkt);
-			ksb->alloced_read_pkts--;
-			usb_autopm_put_interface(ksb->ifc);
 			atomic_dec(&ksb->rx_pending_cnt);
 			wake_up(&ksb->pending_urb_wait);
-			return;
+			break;
 		}
 
-		usb_autopm_put_interface_async(ksb->ifc);
 		usb_free_urb(urb);
 	}
+	if (put)
+		usb_autopm_put_interface_async(ksb->ifc);
 }
 
 static int
@@ -577,20 +609,40 @@
 	struct ks_bridge		*ksb;
 	unsigned long			flags;
 	struct data_pkt			*pkt;
+	struct miscdevice		*mdev, *fbdev;
+	struct usb_device		*udev;
+	unsigned int			bus_id;
 
 	ifc_num = ifc->cur_altsetting->desc.bInterfaceNumber;
 
+	udev = interface_to_usbdev(ifc);
+	fbdev = mdev = (struct miscdevice *)id->driver_info;
+
+	bus_id = str_to_busid(udev->bus->bus_name);
+	if (bus_id == BUS_UNDEF) {
+		dev_err(&udev->dev, "unknown usb bus %s, probe failed\n",
+				udev->bus->bus_name);
+		return -ENODEV;
+	}
+
 	switch (id->idProduct) {
 	case 0x9008:
 		if (ifc_num != 0)
 			return -ENODEV;
-		ksb = __ksb[BOOT_BRIDGE_INDEX];
+		ksb = __ksb[bus_id];
+		mdev = &fbdev[bus_id];
 		break;
 	case 0x9048:
 	case 0x904C:
+	case 0x9075:
 		if (ifc_num != 2)
 			return -ENODEV;
-		ksb = __ksb[EFS_BRIDGE_INDEX];
+		ksb = __ksb[EFS_HSIC_BRIDGE_INDEX];
+		break;
+	case 0x9079:
+		if (ifc_num != 2)
+			return -ENODEV;
+		ksb = __ksb[EFS_USB_BRIDGE_INDEX];
 		break;
 	default:
 		return -ENODEV;
@@ -616,7 +668,8 @@
 	}
 
 	if (!(ksb->in_epAddr && ksb->out_epAddr)) {
-		pr_err("could not find bulk in and bulk out endpoints");
+		dev_err(&udev->dev,
+			"could not find bulk in and bulk out endpoints");
 		usb_put_dev(ksb->udev);
 		ksb->ifc = NULL;
 		return -ENODEV;
@@ -639,7 +692,6 @@
 				struct data_pkt, list);
 		list_del_init(&pkt->list);
 		ksb_free_data_pkt(pkt);
-		ksb->alloced_read_pkts--;
 	}
 	while (!list_empty(&ksb->to_mdm_list)) {
 		pkt = list_first_entry(&ksb->to_mdm_list,
@@ -649,13 +701,15 @@
 	}
 	spin_unlock_irqrestore(&ksb->lock, flags);
 
-	ksb->fs_dev = (struct miscdevice *)id->driver_info;
-	misc_register(ksb->fs_dev);
+	ksb->fs_dev = *mdev;
+	misc_register(&ksb->fs_dev);
 
-	ifc->needs_remote_wakeup = 1;
-	usb_enable_autosuspend(ksb->udev);
+	if (device_can_wakeup(&ksb->udev->dev)) {
+		ifc->needs_remote_wakeup = 1;
+		usb_enable_autosuspend(ksb->udev);
+	}
 
-	pr_debug("usb dev connected");
+	dev_dbg(&udev->dev, "usb dev connected");
 
 	return 0;
 }
@@ -663,13 +717,26 @@
 static int ksb_usb_suspend(struct usb_interface *ifc, pm_message_t message)
 {
 	struct ks_bridge *ksb = usb_get_intfdata(ifc);
+	unsigned long flags;
 
 	dbg_log_event(ksb, "SUSPEND", 0, 0);
 
-	pr_debug("read cnt: %d", ksb->alloced_read_pkts);
-
 	usb_kill_anchored_urbs(&ksb->submitted);
 
+	spin_lock_irqsave(&ksb->lock, flags);
+	if (!list_empty(&ksb->to_ks_list)) {
+		spin_unlock_irqrestore(&ksb->lock, flags);
+		dbg_log_event(ksb, "SUSPEND ABORT", 0, 0);
+		/*
+		 * Now wakeup the reader process and queue
+		 * Rx URBs for more data.
+		 */
+		wake_up(&ksb->ks_wait_q);
+		queue_work(ksb->wq, &ksb->start_rx_work);
+		return -EBUSY;
+	}
+	spin_unlock_irqrestore(&ksb->lock, flags);
+
 	return 0;
 }
 
@@ -698,7 +765,7 @@
 	cancel_work_sync(&ksb->to_mdm_work);
 	cancel_work_sync(&ksb->start_rx_work);
 
-	misc_deregister(ksb->fs_dev);
+	misc_deregister(&ksb->fs_dev);
 
 	usb_kill_anchored_urbs(&ksb->submitted);
 
@@ -714,7 +781,6 @@
 				struct data_pkt, list);
 		list_del_init(&pkt->list);
 		ksb_free_data_pkt(pkt);
-		ksb->alloced_read_pkts--;
 	}
 	while (!list_empty(&ksb->to_mdm_list)) {
 		pkt = list_first_entry(&ksb->to_mdm_list,
diff --git a/drivers/usb/misc/mdm_ctrl_bridge.c b/drivers/usb/misc/mdm_ctrl_bridge.c
index abc7b86..2a61501 100644
--- a/drivers/usb/misc/mdm_ctrl_bridge.c
+++ b/drivers/usb/misc/mdm_ctrl_bridge.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/drivers/usb/misc/mdm_data_bridge.c b/drivers/usb/misc/mdm_data_bridge.c
index 655e2f6..fcbf0e1 100644
--- a/drivers/usb/misc/mdm_data_bridge.c
+++ b/drivers/usb/misc/mdm_data_bridge.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, 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
@@ -343,6 +343,9 @@
 
 	dev_dbg(&dev->intf->dev, "%s:\n", __func__);
 
+	cancel_work_sync(&dev->kevent);
+	cancel_work_sync(&dev->process_rx_w);
+
 	usb_unlink_anchored_urbs(&dev->tx_active);
 	usb_unlink_anchored_urbs(&dev->rx_active);
 	usb_unlink_anchored_urbs(&dev->delayed);
@@ -995,9 +998,6 @@
 	usb_set_intfdata(intf, NULL);
 	__dev[dev->id] = NULL;
 
-	cancel_work_sync(&dev->process_rx_w);
-	cancel_work_sync(&dev->kevent);
-
 	/*free rx urbs*/
 	head = &dev->rx_idle;
 	spin_lock_irqsave(&dev->rx_done.lock, flags);
diff --git a/drivers/usb/otg/msm72k_otg.c b/drivers/usb/otg/msm72k_otg.c
index 36a91f1..c3b3b3d 100644
--- a/drivers/usb/otg/msm72k_otg.c
+++ b/drivers/usb/otg/msm72k_otg.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 3ad05b06..c03ca69 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2013, 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
@@ -95,7 +95,7 @@
 
 static struct regulator *hsusb_3p3;
 static struct regulator *hsusb_1p8;
-static struct regulator *hsusb_vddcx;
+static struct regulator *hsusb_vdd;
 static struct regulator *vbus_otg;
 static struct regulator *mhl_usb_hs_switch;
 static struct power_supply *psy;
@@ -111,7 +111,7 @@
 #endif
 }
 
-static const int vdd_val[VDD_TYPE_MAX][VDD_VAL_MAX] = {
+static int vdd_val[VDD_TYPE_MAX][VDD_VAL_MAX] = {
 		{  /* VDD_CX CORNER Voting */
 			[VDD_NONE]	= RPM_VREG_CORNER_NONE,
 			[VDD_MIN]	= RPM_VREG_CORNER_NOMINAL,
@@ -175,7 +175,7 @@
 	int ret;
 
 	min_vol = vdd_val[vdd_type][!!high];
-	ret = regulator_set_voltage(hsusb_vddcx, min_vol, max_vol);
+	ret = regulator_set_voltage(hsusb_vdd, min_vol, max_vol);
 	if (ret) {
 		pr_err("%s: unable to set the voltage for regulator "
 			"HSUSB_VDDCX\n", __func__);
@@ -485,9 +485,13 @@
 	ret = msm_otg_phy_clk_reset(motg);
 	if (ret)
 		return ret;
-	/* 10 usec delay is required according to spec */
+
+	/*
+	 * 10 usec delay is required according to spec. Using larger value
+	 * since the exact value proved to not work 100% of the time.
+	 */
 	if (IS_ERR(motg->phy_reset_clk))
-		usleep_range(10, 12);
+		usleep_range(100, 120);
 	ret = msm_otg_link_clk_reset(motg, 0);
 	if (ret)
 		return ret;
@@ -980,12 +984,18 @@
 
 	/* usb phy no more require TCXO clock, hence vote for TCXO disable */
 	if (!host_bus_suspend) {
-		ret = msm_xo_mode_vote(motg->xo_handle, MSM_XO_MODE_OFF);
-		if (ret)
-			dev_err(phy->dev, "%s failed to devote for "
-				"TCXO D0 buffer%d\n", __func__, ret);
-		else
+		if (!IS_ERR(motg->xo_clk)) {
+			clk_disable_unprepare(motg->xo_clk);
 			motg->lpm_flags |= XO_SHUTDOWN;
+		} else {
+			ret = msm_xo_mode_vote(motg->xo_handle,
+							MSM_XO_MODE_OFF);
+			if (ret)
+				dev_err(phy->dev, "%s fail to devote XO %d\n",
+								 __func__, ret);
+			else
+				motg->lpm_flags |= XO_SHUTDOWN;
+		}
 	}
 
 	if (motg->caps & ALLOW_PHY_POWER_COLLAPSE &&
@@ -1004,9 +1014,11 @@
 	}
 
 	if (device_may_wakeup(phy->dev)) {
-		enable_irq_wake(motg->irq);
 		if (motg->async_irq)
 			enable_irq_wake(motg->async_irq);
+		else
+			enable_irq_wake(motg->irq);
+
 		if (motg->pdata->pmic_id_irq)
 			enable_irq_wake(motg->pdata->pmic_id_irq);
 		if (pdata->otg_control == OTG_PHY_CONTROL &&
@@ -1046,10 +1058,14 @@
 
 	/* Vote for TCXO when waking up the phy */
 	if (motg->lpm_flags & XO_SHUTDOWN) {
-		ret = msm_xo_mode_vote(motg->xo_handle, MSM_XO_MODE_ON);
-		if (ret)
-			dev_err(phy->dev, "%s failed to vote for "
-				"TCXO D0 buffer%d\n", __func__, ret);
+		if (!IS_ERR(motg->xo_clk)) {
+			clk_prepare_enable(motg->xo_clk);
+		} else {
+			ret = msm_xo_mode_vote(motg->xo_handle, MSM_XO_MODE_ON);
+			if (ret)
+				dev_err(phy->dev, "%s fail to vote for XO %d\n",
+								__func__, ret);
+		}
 		motg->lpm_flags &= ~XO_SHUTDOWN;
 	}
 
@@ -1113,9 +1129,11 @@
 
 skip_phy_resume:
 	if (device_may_wakeup(phy->dev)) {
-		disable_irq_wake(motg->irq);
 		if (motg->async_irq)
 			disable_irq_wake(motg->async_irq);
+		else
+			disable_irq_wake(motg->irq);
+
 		if (motg->pdata->pmic_id_irq)
 			disable_irq_wake(motg->pdata->pmic_id_irq);
 		if (pdata->otg_control == OTG_PHY_CONTROL &&
@@ -1197,7 +1215,7 @@
 		motg->chg_type == USB_ACA_C_CHARGER))
 		charger_type = POWER_SUPPLY_TYPE_USB_ACA;
 	else
-		charger_type = POWER_SUPPLY_TYPE_BATTERY;
+		charger_type = POWER_SUPPLY_TYPE_UNKNOWN;
 
 	if (!psy) {
 		pr_err("No USB power supply registered!\n");
@@ -2167,8 +2185,8 @@
 	}
 }
 
-#define MSM_CHG_DCD_POLL_TIME		(100 * HZ/1000) /* 100 msec */
-#define MSM_CHG_DCD_MAX_RETRIES		6 /* Tdcd_tmout = 6 * 100 msec */
+#define MSM_CHG_DCD_TIMEOUT		(750 * HZ/1000) /* 750 msec */
+#define MSM_CHG_DCD_POLL_TIME		(50 * HZ/1000) /* 50 msec */
 #define MSM_CHG_PRIMARY_DET_TIME	(50 * HZ/1000) /* TVDPSRC_ON */
 #define MSM_CHG_SECONDARY_DET_TIME	(50 * HZ/1000) /* TVDMSRC_ON */
 static void msm_chg_detect_work(struct work_struct *w)
@@ -2192,7 +2210,7 @@
 		msm_chg_enable_dcd(motg);
 		msm_chg_enable_aca_det(motg);
 		motg->chg_state = USB_CHG_STATE_WAIT_FOR_DCD;
-		motg->dcd_retries = 0;
+		motg->dcd_time = 0;
 		delay = MSM_CHG_DCD_POLL_TIME;
 		break;
 	case USB_CHG_STATE_WAIT_FOR_DCD:
@@ -2217,7 +2235,8 @@
 			}
 		}
 		is_dcd = msm_chg_check_dcd(motg);
-		tmout = ++motg->dcd_retries == MSM_CHG_DCD_MAX_RETRIES;
+		motg->dcd_time += MSM_CHG_DCD_POLL_TIME;
+		tmout = motg->dcd_time >= MSM_CHG_DCD_TIMEOUT;
 		if (is_dcd || tmout) {
 			msm_chg_disable_dcd(motg);
 			msm_chg_enable_primary_det(motg);
@@ -2275,6 +2294,11 @@
 	case USB_CHG_STATE_SECONDARY_DONE:
 		motg->chg_state = USB_CHG_STATE_DETECTED;
 	case USB_CHG_STATE_DETECTED:
+		/*
+		 * Notify the charger type to power supply
+		 * owner as soon as we determine the charger.
+		 */
+		msm_otg_notify_chg_type(motg);
 		msm_chg_block_off(motg);
 		msm_chg_enable_aca_det(motg);
 		/*
@@ -2478,6 +2502,7 @@
 			pr_debug("chg_work cancel");
 			del_timer_sync(&motg->chg_check_timer);
 			clear_bit(B_FALSE_SDP, &motg->inputs);
+			clear_bit(A_BUS_REQ, &motg->inputs);
 			cancel_delayed_work_sync(&motg->chg_work);
 			motg->chg_state = USB_CHG_STATE_UNDEFINED;
 			motg->chg_type = USB_INVALID_CHARGER;
@@ -3766,6 +3791,10 @@
 				"qcom,hsusb-otg-disable-reset");
 	pdata->pnoc_errata_fix = of_property_read_bool(node,
 				"qcom,hsusb-otg-pnoc-errata-fix");
+	pdata->enable_lpm_on_dev_suspend = of_property_read_bool(node,
+				"qcom,hsusb-otg-lpm-on-dev-suspend");
+	pdata->core_clk_always_on_workaround = of_property_read_bool(node,
+				"qcom,hsusb-otg-clk-always-on-workaround");
 
 	return pdata;
 }
@@ -3773,6 +3802,8 @@
 static int __init msm_otg_probe(struct platform_device *pdev)
 {
 	int ret = 0;
+	int len = 0;
+	u32 tmp[3];
 	struct resource *res;
 	struct msm_otg *motg;
 	struct usb_phy *phy;
@@ -3900,42 +3931,69 @@
 		motg->async_irq = 0;
 	}
 
-	motg->xo_handle = msm_xo_get(MSM_XO_TCXO_D0, "usb");
-	if (IS_ERR(motg->xo_handle)) {
-		dev_err(&pdev->dev, "%s not able to get the handle "
-			"to vote for TCXO D0 buffer\n", __func__);
-		ret = PTR_ERR(motg->xo_handle);
-		goto free_regs;
+	motg->xo_clk = clk_get(&pdev->dev, "xo");
+	if (IS_ERR(motg->xo_clk)) {
+		motg->xo_handle = msm_xo_get(MSM_XO_TCXO_D0, "usb");
+		if (IS_ERR(motg->xo_handle)) {
+			dev_err(&pdev->dev, "%s fail to get handle for TCXO\n",
+								__func__);
+			ret = PTR_ERR(motg->xo_handle);
+			goto free_regs;
+		} else {
+			ret = msm_xo_mode_vote(motg->xo_handle, MSM_XO_MODE_ON);
+			if (ret) {
+				dev_err(&pdev->dev, "%s XO voting failed %d\n",
+								__func__, ret);
+				goto free_xo_handle;
+			}
+		}
+	} else {
+		ret = clk_prepare_enable(motg->xo_clk);
+		if (ret) {
+			dev_err(&pdev->dev, "%s failed to vote for TCXO %d\n",
+							__func__, ret);
+			goto free_xo_handle;
+		}
 	}
 
-	ret = msm_xo_mode_vote(motg->xo_handle, MSM_XO_MODE_ON);
-	if (ret) {
-		dev_err(&pdev->dev, "%s failed to vote for TCXO "
-			"D0 buffer%d\n", __func__, ret);
-		goto free_xo_handle;
-	}
 
 	clk_prepare_enable(motg->pclk);
 
 	motg->vdd_type = VDDCX_CORNER;
-	hsusb_vddcx = devm_regulator_get(motg->phy.dev, "hsusb_vdd_dig");
-	if (IS_ERR(hsusb_vddcx)) {
-		hsusb_vddcx = devm_regulator_get(motg->phy.dev, "HSUSB_VDDCX");
-		if (IS_ERR(hsusb_vddcx)) {
+	hsusb_vdd = devm_regulator_get(motg->phy.dev, "hsusb_vdd_dig");
+	if (IS_ERR(hsusb_vdd)) {
+		hsusb_vdd = devm_regulator_get(motg->phy.dev, "HSUSB_VDDCX");
+		if (IS_ERR(hsusb_vdd)) {
 			dev_err(motg->phy.dev, "unable to get hsusb vddcx\n");
-			ret = PTR_ERR(hsusb_vddcx);
+			ret = PTR_ERR(hsusb_vdd);
 			goto devote_xo_handle;
 		}
 		motg->vdd_type = VDDCX;
 	}
 
+	if (pdev->dev.of_node) {
+		of_get_property(pdev->dev.of_node,
+				"qcom,vdd-voltage-level",
+				&len);
+		if (len == sizeof(tmp)) {
+			of_property_read_u32_array(pdev->dev.of_node,
+					"qcom,vdd-voltage-level",
+					tmp, len/sizeof(*tmp));
+			vdd_val[motg->vdd_type][0] = tmp[0];
+			vdd_val[motg->vdd_type][1] = tmp[1];
+			vdd_val[motg->vdd_type][2] = tmp[2];
+		} else {
+			dev_dbg(&pdev->dev, "Using default hsusb vdd config.\n");
+		}
+	}
+
 	ret = msm_hsusb_config_vddcx(1);
 	if (ret) {
 		dev_err(&pdev->dev, "hsusb vddcx configuration failed\n");
 		goto devote_xo_handle;
 	}
 
-	ret = regulator_enable(hsusb_vddcx);
+	ret = regulator_enable(hsusb_vdd);
 	if (ret) {
 		dev_err(&pdev->dev, "unable to enable the hsusb vddcx\n");
 		goto free_config_vddcx;
@@ -3944,7 +4002,7 @@
 	ret = msm_hsusb_ldo_init(motg, 1);
 	if (ret) {
 		dev_err(&pdev->dev, "hsusb vreg configuration failed\n");
-		goto free_hsusb_vddcx;
+		goto free_hsusb_vdd;
 	}
 
 	if (pdata->mhl_enable) {
@@ -4127,17 +4185,23 @@
 	msm_hsusb_ldo_enable(motg, USB_PHY_REG_OFF);
 free_ldo_init:
 	msm_hsusb_ldo_init(motg, 0);
-free_hsusb_vddcx:
-	regulator_disable(hsusb_vddcx);
+free_hsusb_vdd:
+	regulator_disable(hsusb_vdd);
 free_config_vddcx:
-	regulator_set_voltage(hsusb_vddcx,
+	regulator_set_voltage(hsusb_vdd,
 		vdd_val[motg->vdd_type][VDD_NONE],
 		vdd_val[motg->vdd_type][VDD_MAX]);
 devote_xo_handle:
 	clk_disable_unprepare(motg->pclk);
-	msm_xo_mode_vote(motg->xo_handle, MSM_XO_MODE_OFF);
+	if (!IS_ERR(motg->xo_clk))
+		clk_disable_unprepare(motg->xo_clk);
+	else
+		msm_xo_mode_vote(motg->xo_handle, MSM_XO_MODE_OFF);
 free_xo_handle:
-	msm_xo_put(motg->xo_handle);
+	if (!IS_ERR(motg->xo_clk))
+		clk_put(motg->xo_clk);
+	else
+		msm_xo_put(motg->xo_handle);
 free_regs:
 	iounmap(motg->regs);
 put_pclk:
@@ -4210,11 +4274,16 @@
 
 	clk_disable_unprepare(motg->pclk);
 	clk_disable_unprepare(motg->core_clk);
-	msm_xo_put(motg->xo_handle);
+	if (!IS_ERR(motg->xo_clk)) {
+		clk_disable_unprepare(motg->xo_clk);
+		clk_put(motg->xo_clk);
+	} else {
+		msm_xo_put(motg->xo_handle);
+	}
 	msm_hsusb_ldo_enable(motg, USB_PHY_REG_OFF);
 	msm_hsusb_ldo_init(motg, 0);
-	regulator_disable(hsusb_vddcx);
-	regulator_set_voltage(hsusb_vddcx,
+	regulator_disable(hsusb_vdd);
+	regulator_set_voltage(hsusb_vdd,
 		vdd_val[motg->vdd_type][VDD_NONE],
 		vdd_val[motg->vdd_type][VDD_MAX]);
 
diff --git a/drivers/usb/serial/csvt.c b/drivers/usb/serial/csvt.c
index 6835ddc..66922da 100644
--- a/drivers/usb/serial/csvt.c
+++ b/drivers/usb/serial/csvt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index a749a6d..fd6c48d 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -1,7 +1,7 @@
 /*
  * Qualcomm Serial USB driver
  *
- *	Copyright (c) 2008, 2012 Code Aurora Forum. All rights reserved.
+ *	Copyright (c) 2008, 2012 The Linux Foundation. All rights reserved.
  *	Copyright (c) 2009 Greg Kroah-Hartman <gregkh@suse.de>
  *	Copyright (c) 2009 Novell Inc.
  *
diff --git a/drivers/video/msm/adv7520.c b/drivers/video/msm/adv7520.c
index c2f1c0c..0e83d0f 100644
--- a/drivers/video/msm/adv7520.c
+++ b/drivers/video/msm/adv7520.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010,2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/ebi2_epson_s1d_qvga.c b/drivers/video/msm/ebi2_epson_s1d_qvga.c
index 8821eab..8db3cf9 100644
--- a/drivers/video/msm/ebi2_epson_s1d_qvga.c
+++ b/drivers/video/msm/ebi2_epson_s1d_qvga.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/video/msm/ebi2_host.c b/drivers/video/msm/ebi2_host.c
index 8ba5506..bebc36e 100644
--- a/drivers/video/msm/ebi2_host.c
+++ b/drivers/video/msm/ebi2_host.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/video/msm/ebi2_l2f.c b/drivers/video/msm/ebi2_l2f.c
index 767b802..2e944be 100644
--- a/drivers/video/msm/ebi2_l2f.c
+++ b/drivers/video/msm/ebi2_l2f.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/drivers/video/msm/ebi2_lcd.c b/drivers/video/msm/ebi2_lcd.c
index 966f974..a19763c 100644
--- a/drivers/video/msm/ebi2_lcd.c
+++ b/drivers/video/msm/ebi2_lcd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/drivers/video/msm/ebi2_tmd20.c b/drivers/video/msm/ebi2_tmd20.c
index 280373f..7c7b0ef 100644
--- a/drivers/video/msm/ebi2_tmd20.c
+++ b/drivers/video/msm/ebi2_tmd20.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/drivers/video/msm/external_common.c b/drivers/video/msm/external_common.c
index 0411baa..7aeca6e 100644
--- a/drivers/video/msm/external_common.c
+++ b/drivers/video/msm/external_common.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -244,6 +244,7 @@
 	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p240_16_9),
 	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i240_4_3),
 	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i240_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1280x1024p60_5_4)
 };
 EXPORT_SYMBOL(hdmi_common_supported_video_mode_lut);
 
@@ -308,6 +309,7 @@
 	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p240_16_9),
 	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i240_4_3),
 	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i240_16_9),
+	HDMI_SETTINGS_1280x1024p60_5_4
 };
 EXPORT_SYMBOL(hdmi_mhl_supported_video_mode_lut);
 
@@ -829,6 +831,74 @@
 	return ret;
 }
 
+static ssize_t hdmi_common_rda_audio_data_block(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	int adb_size	= 0;
+	int adb_count	= 0;
+	ssize_t ret	= 0;
+	char *data	= buf;
+
+	if (!external_common_state)
+		return 0;
+
+	adb_count = 1;
+	adb_size  = external_common_state->adb_size;
+	ret       = sizeof(adb_count) + sizeof(adb_size) + adb_size;
+
+	if (ret > PAGE_SIZE) {
+		DEV_DBG("%s: Insufficient buffer size\n", __func__);
+		return 0;
+	}
+
+	/* Currently only extracting one audio data block */
+	memcpy(data, &adb_count, sizeof(adb_count));
+	data += sizeof(adb_count);
+	memcpy(data, &adb_size, sizeof(adb_size));
+	data += sizeof(adb_size);
+	memcpy(data, external_common_state->audio_data_block,
+			external_common_state->adb_size);
+
+	print_hex_dump(KERN_DEBUG, "AUDIO DATA BLOCK: ", DUMP_PREFIX_NONE,
+			32, 8, buf, ret, false);
+
+	return ret;
+}
+
+static ssize_t hdmi_common_rda_spkr_alloc_data_block(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	int sadb_size	= 0;
+	int sadb_count	= 0;
+	ssize_t ret	= 0;
+	char *data	= buf;
+
+	if (!external_common_state)
+		return 0;
+
+	sadb_count = 1;
+	sadb_size  = external_common_state->sadb_size;
+	ret        = sizeof(sadb_count) + sizeof(sadb_size) + sadb_size;
+
+	if (ret > PAGE_SIZE) {
+		DEV_DBG("%s: Insufficient buffer size\n", __func__);
+		return 0;
+	}
+
+	/* Currently only extracting one speaker allocation data block */
+	memcpy(data, &sadb_count, sizeof(sadb_count));
+	data += sizeof(sadb_count);
+	memcpy(data, &sadb_size, sizeof(sadb_size));
+	data += sizeof(sadb_size);
+	memcpy(data, external_common_state->spkr_alloc_data_block,
+			external_common_state->sadb_size);
+
+	print_hex_dump(KERN_DEBUG, "SPKR ALLOC DATA BLOCK: ", DUMP_PREFIX_NONE,
+			32, 8, buf, ret, false);
+
+	return ret;
+}
+
 static DEVICE_ATTR(video_mode, S_IRUGO | S_IWUGO,
 	external_common_rda_video_mode, external_common_wta_video_mode);
 static DEVICE_ATTR(video_mode_str, S_IRUGO, external_common_rda_video_mode_str,
@@ -859,6 +929,10 @@
 	hdmi_3d_wta_format_3d);
 #endif
 static DEVICE_ATTR(hdmi_primary, S_IRUGO, hdmi_common_rda_hdmi_primary, NULL);
+static DEVICE_ATTR(audio_data_block, S_IRUGO, hdmi_common_rda_audio_data_block,
+	NULL);
+static DEVICE_ATTR(spkr_alloc_data_block, S_IRUGO,
+	hdmi_common_rda_spkr_alloc_data_block, NULL);
 
 static struct attribute *external_common_fs_attrs[] = {
 	&dev_attr_video_mode.attr,
@@ -887,6 +961,8 @@
 	&dev_attr_cec_wr_frame.attr,
 #endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT */
 	&dev_attr_hdmi_primary.attr,
+	&dev_attr_audio_data_block.attr,
+	&dev_attr_spkr_alloc_data_block.attr,
 	NULL,
 };
 static struct attribute_group external_common_fs_attr_group = {
@@ -1001,6 +1077,8 @@
 	 89909, 119880, 148352, 119880, FALSE},
 	{HDMI_VFRMT_1280x720p120_16_9, 1280, 720, FALSE, 1650, 370, 750, 30,
 	 90000, 120000, 148500, 120000, FALSE},
+	{HDMI_VFRMT_1280x1024p60_5_4, 1280, 1024, FALSE, 1688, 408, 1066, 42,
+	 63981, 60020, 108000, 60000, FALSE},
 
 	/* All 1440 H Active */
 	{HDMI_VFRMT_1440x576i50_4_3, 1440, 576, TRUE,  1728, 288, 625, 24,
@@ -1205,45 +1283,33 @@
 static void hdmi_edid_extract_speaker_allocation_data(const uint8 *in_buf)
 {
 	uint8 len;
-	const uint8 *sad = hdmi_edid_find_block(in_buf, DBC_START_OFFSET, 4,
+	const uint8 *sadb = hdmi_edid_find_block(in_buf, DBC_START_OFFSET, 4,
 			&len);
 
-	if (sad == NULL)
+	if (sadb == NULL)
 		return;
 
-	external_common_state->speaker_allocation_block = sad[1];
-	DEV_DBG("EDID: speaker allocation data SP byte = %08x %s%s%s%s%s%s%s\n",
-		sad[1],
-		(sad[1] & BIT(0)) ? "FL/FR," : "",
-		(sad[1] & BIT(1)) ? "LFE," : "",
-		(sad[1] & BIT(2)) ? "FC," : "",
-		(sad[1] & BIT(3)) ? "RL/RR," : "",
-		(sad[1] & BIT(4)) ? "RC," : "",
-		(sad[1] & BIT(5)) ? "FLC/FRC," : "",
-		(sad[1] & BIT(6)) ? "RLC/RRC," : "");
+	if (len != MAX_SPKR_ALLOC_DATA_BLOCK_SIZE)
+		return;
+
+	memcpy(external_common_state->spkr_alloc_data_block, sadb + 1, len);
+	external_common_state->sadb_size = len;
 }
 
 static void hdmi_edid_extract_audio_data_blocks(const uint8 *in_buf)
 {
 	uint8 len;
-	const uint8 *sad = hdmi_edid_find_block(in_buf, DBC_START_OFFSET, 1,
+	const uint8 *adb = hdmi_edid_find_block(in_buf, DBC_START_OFFSET, 1,
 			&len);
-	uint32 *adb = external_common_state->audio_data_blocks;
 
-	if (sad == NULL)
+	if (external_common_state->audio_data_block == NULL)
 		return;
 
-	external_common_state->audio_data_block_cnt = 0;
-	while (len >= 3 && external_common_state->audio_data_block_cnt < 16) {
-		DEV_DBG("EDID: Audio Data Block=<ch=%d, format=%d "
-			"sampling=0x%02x bit-depth=0x%02x>\n",
-			(sad[1] & 0x7)+1, sad[1] >> 3, sad[2], sad[3]);
-		*adb++ = (uint32)sad[1] + ((uint32)sad[2] << 8)
-			+ ((uint32)sad[2] << 16);
-		++external_common_state->audio_data_block_cnt;
-		len -= 3;
-		sad += 3;
-	}
+	if (len > MAX_AUDIO_DATA_BLOCK_SIZE)
+		return;
+
+	memcpy(external_common_state->audio_data_block, adb + 1, len);
+	external_common_state->adb_size = len;
 }
 
 static void hdmi_edid_extract_extended_data_blocks(const uint8 *in_buf)
@@ -1507,7 +1573,8 @@
 	struct hdmi_disp_mode_list_type *disp_mode_list,
 	uint32 num_og_cea_blocks)
 {
-	uint8 len, offset, present_multi_3d, hdmi_vic_len, hdmi_3d_len;
+	uint8 len, offset, present_multi_3d, hdmi_vic_len;
+	int hdmi_3d_len;
 	uint16 structure_all, structure_mask;
 	const uint8 *vsd = num_og_cea_blocks ?
 		hdmi_edid_find_block(data_buf+0x80, DBC_START_OFFSET,
@@ -1631,7 +1698,7 @@
 	struct hdmi_disp_mode_list_type *disp_mode_list,
 	uint32 num_og_cea_blocks)
 {
-	uint8 i			= 0;
+	uint8 i			= 0, offset = 0, std_blk = 0;
 	uint32 video_format	= HDMI_VFRMT_640x480p60_4_3;
 	boolean has480p		= FALSE;
 	uint8 len;
@@ -1762,6 +1829,66 @@
 		}
 	}
 
+
+	/*
+	 * Check SD Timings if it contains 1280x1024@60Hz.
+	 * SD Timing can be max 8 with 2 byte in size.
+	 */
+	std_blk = 0;
+	offset  = 0;
+	while (std_blk < 8) {
+		if ((edid_blk0[0x26 + offset] == 0x81) &&
+			(edid_blk0[0x26 + offset + 1] == 0x80)) {
+			add_supported_video_format(disp_mode_list,
+					HDMI_VFRMT_1280x1024p60_5_4);
+			break;
+		} else {
+			offset += 2;
+		}
+		std_blk++;
+	}
+
+	/* check if the EDID revision is 4 (version 1.4) */
+	if (edid_blk0[0x13] == 4) {
+		uint8  start = 0x36;
+
+		i = 0;
+
+		/* Check each of 4 - 18 bytes descriptors */
+		while (i < 4) {
+			uint8  itrate   = start;
+			uint32 header_1 = 0;
+			uint8  header_2 = 0;
+
+			/*
+			 * First 5 bytes are header.
+			 * If they match 0x000000F700, it means its an
+			 * established Timing III descriptor.
+			 */
+			header_1 = edid_blk0[itrate++];
+			header_1 = header_1 << 8 | edid_blk0[itrate++];
+			header_1 = header_1 << 8 | edid_blk0[itrate++];
+			header_1 = header_1 << 8 | edid_blk0[itrate++];
+			header_2 = edid_blk0[itrate];
+
+			if (header_1 == 0x000000F7 &&
+			    header_2 == 0x00) {
+				itrate++; /* VESA DMT Standard Version (0x0A)*/
+				itrate++; /* First set of supported formats */
+				itrate++; /* Second set of supported formats */
+				/* BIT(1) indicates 1280x1024@60Hz */
+				if (edid_blk0[itrate] & 0x02) {
+					add_supported_video_format(
+						disp_mode_list,
+						HDMI_VFRMT_1280x1024p60_5_4);
+					break;
+				}
+			}
+			i++;
+			start += 0x12;
+		}
+	}
+
 	/* mandaroty 3d format */
 	if (external_common_state->present_3d) {
 		if (has60hz_mode) {
@@ -1874,6 +2001,12 @@
 		sizeof(external_common_state->disp_mode_list));
 	memset(edid_buf, 0, sizeof(edid_buf));
 	external_common_state->default_res_supported = false;
+	memset(external_common_state->audio_data_block, 0,
+		sizeof(external_common_state->audio_data_block));
+	memset(external_common_state->spkr_alloc_data_block, 0,
+		sizeof(external_common_state->spkr_alloc_data_block));
+	external_common_state->adb_size = 0;
+	external_common_state->sadb_size = 0;
 
 	status = hdmi_common_read_edid_block(0, edid_buf);
 	if (status || !check_edid_header(edid_buf)) {
@@ -1985,7 +2118,7 @@
 
 bool hdmi_common_get_video_format_from_drv_data(struct msm_fb_data_type *mfd)
 {
-	uint32 format = HDMI_VFRMT_1920x1080p60_16_9;
+	uint32 format =  external_common_state->video_resolution;
 	struct fb_var_screeninfo *var = &mfd->fbi->var;
 	bool changed = TRUE;
 
@@ -2008,7 +2141,9 @@
 				: HDMI_VFRMT_720x576p50_16_9;
 			break;
 		case 1280:
-			if (mfd->var_frame_rate == 50000)
+			if (mfd->var_yres == 1024)
+				format = HDMI_VFRMT_1280x1024p60_5_4;
+			else if (mfd->var_frame_rate == 50000)
 				format = HDMI_VFRMT_1280x720p50_16_9;
 			else
 				format = HDMI_VFRMT_1280x720p60_16_9;
diff --git a/drivers/video/msm/external_common.h b/drivers/video/msm/external_common.h
index 70a99ee..d117898 100644
--- a/drivers/video/msm/external_common.h
+++ b/drivers/video/msm/external_common.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -109,9 +109,19 @@
 #define HDMI_VFRMT_1440x480i240_4_3	HDMI_VFRMT_720x480i240_4_3
 #define HDMI_VFRMT_720x480i240_16_9	58
 #define HDMI_VFRMT_1440x480i240_16_9	HDMI_VFRMT_720x480i240_16_9
-#define HDMI_VFRMT_MAX			59
 #define HDMI_VFRMT_FORCE_32BIT		0x7FFFFFFF
 
+/* Video Identification Codes from 65-127 are reserved for the future */
+#define HDMI_VFRMT_END			127
+
+/* VESA DMT TIMINGS */
+/* DMT ID: 23h, STD code: (81h, 80h), also a part of Established Timing III */
+#define HDMI_VFRMT_1280x1024p60_5_4	(HDMI_VFRMT_END + 1)
+#define DMT_VFRMT_END                   HDMI_VFRMT_1280x1024p60_5_4
+
+#define HDMI_VFRMT_MAX	                (DMT_VFRMT_END + 1)
+
+
 extern int ext_resolution;
 
 struct hdmi_disp_mode_timing_type {
@@ -185,6 +195,9 @@
 #define HDMI_SETTINGS_1920x1080p30_16_9					\
 	{HDMI_VFRMT_1920x1080p30_16_9,   1920,  88,   44,  148,  FALSE,	\
 	 1080, 4, 5, 36, FALSE, 74250, 30000, FALSE, TRUE}
+#define HDMI_SETTINGS_1280x1024p60_5_4					\
+	{HDMI_VFRMT_1280x1024p60_5_4,   1280,  48,  112,  248,  FALSE, \
+	 1024, 1, 3, 38, FALSE, 108000, 60000, FALSE, TRUE}
 
 /* A lookup table for all the supported display modes by the HDMI
  * hardware and driver.  Use HDMI_SETUP_LUT in the module init to
@@ -206,6 +219,14 @@
 };
 #endif
 
+/*
+ * As per the CEA-861E spec, there can be a total of 10 short audio
+ * descriptors with each SAD being 3 bytes long.
+ * Thus, the maximum length of the audio data block would be 30 bytes
+ */
+#define MAX_AUDIO_DATA_BLOCK_SIZE	30
+#define MAX_SPKR_ALLOC_DATA_BLOCK_SIZE	3
+
 struct external_common_state_type {
 	boolean hpd_state;
 	struct kobject *uevent_kobj;
@@ -223,9 +244,7 @@
 	boolean hpd_feature_on;
 	boolean hdmi_sink;
 	struct hdmi_disp_mode_list_type disp_mode_list;
-	uint8 speaker_allocation_block;
 	uint16 video_latency, audio_latency;
-	uint8 audio_data_block_cnt;
 	uint16 physical_address;
 	uint32 preferred_video_format;
 	uint8 pt_scan_info;
@@ -235,7 +254,10 @@
 	uint8 spd_product_description[16];
 	boolean present_3d;
 	boolean present_hdcp;
-	uint32 audio_data_blocks[16];
+	uint8 audio_data_block[MAX_AUDIO_DATA_BLOCK_SIZE];
+	int adb_size;
+	uint8 spkr_alloc_data_block[MAX_SPKR_ALLOC_DATA_BLOCK_SIZE];
+	int sadb_size;
 	int (*read_edid_block)(int block, uint8 *edid_buf);
 	int (*hpd_feature)(int on);
 #endif
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index bd32b6d..fa57992 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -647,6 +647,7 @@
 	HDMI_SETUP_LUT(1920x1080p24_16_9);
 	HDMI_SETUP_LUT(1920x1080p25_16_9);
 	HDMI_SETUP_LUT(1920x1080p30_16_9);
+	HDMI_SETUP_LUT(1280x1024p60_5_4);
 }
 
 #ifdef PORT_DEBUG
@@ -3618,36 +3619,35 @@
 	return 0;
 }
 
-
-static uint8 hdmi_msm_avi_iframe_lut[][16] = {
+static uint8 hdmi_msm_avi_iframe_lut[][17] = {
 /*	480p60	480i60	576p50	576i50	720p60	 720p50	1080p60	1080i60	1080p50
 	1080i50	1080p24	1080p30	1080p25	640x480p 480p60_16_9 576p50_4_3 */
 	{0x10,	0x10,	0x10,	0x10,	0x10,	 0x10,	0x10,	0x10,	0x10,
-	 0x10,	0x10,	0x10,	0x10,	0x10, 0x10, 0x10}, /*00*/
+	 0x10,	0x10,	0x10,	0x10,	0x10, 0x10, 0x10, 0x10}, /*00*/
 	{0x18,	0x18,	0x28,	0x28,	0x28,	 0x28,	0x28,	0x28,	0x28,
-	 0x28,	0x28,	0x28,	0x28,	0x18, 0x28, 0x18}, /*01*/
+	 0x28,	0x28,	0x28,	0x28,	0x18, 0x28, 0x18, 0x08}, /*01*/
 	{0x00,	0x04,	0x04,	0x04,	0x04,	 0x04,	0x04,	0x04,	0x04,
-	 0x04,	0x04,	0x04,	0x04,	0x88, 0x00, 0x04}, /*02*/
+	 0x04,	0x04,	0x04,	0x04,	0x88, 0x00, 0x04, 0x04}, /*02*/
 	{0x02,	0x06,	0x11,	0x15,	0x04,	 0x13,	0x10,	0x05,	0x1F,
-	 0x14,	0x20,	0x22,	0x21,	0x01, 0x03, 0x11}, /*03*/
+	 0x14,	0x20,	0x22,	0x21,	0x01, 0x03, 0x11, 0x00}, /*03*/
 	{0x00,	0x01,	0x00,	0x01,	0x00,	 0x00,	0x00,	0x00,	0x00,
-	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00, 0x00}, /*04*/
+	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00, 0x00, 0x00}, /*04*/
 	{0x00,	0x00,	0x00,	0x00,	0x00,	 0x00,	0x00,	0x00,	0x00,
-	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00, 0x00}, /*05*/
+	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00, 0x00, 0x00}, /*05*/
 	{0x00,	0x00,	0x00,	0x00,	0x00,	 0x00,	0x00,	0x00,	0x00,
-	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00, 0x00}, /*06*/
+	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00, 0x00, 0x00}, /*06*/
 	{0xE1,	0xE1,	0x41,	0x41,	0xD1,	 0xd1,	0x39,	0x39,	0x39,
-	 0x39,	0x39,	0x39,	0x39,	0xe1, 0xE1, 0x41}, /*07*/
+	 0x39,	0x39,	0x39,	0x39,	0xe1, 0xE1, 0x41, 0x01}, /*07*/
 	{0x01,	0x01,	0x02,	0x02,	0x02,	 0x02,	0x04,	0x04,	0x04,
-	 0x04,	0x04,	0x04,	0x04,	0x01, 0x01, 0x02}, /*08*/
+	 0x04,	0x04,	0x04,	0x04,	0x01, 0x01, 0x02, 0x04}, /*08*/
 	{0x00,	0x00,	0x00,	0x00,	0x00,	 0x00,	0x00,	0x00,	0x00,
-	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00, 0x00}, /*09*/
+	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00, 0x00, 0x00}, /*09*/
 	{0x00,	0x00,	0x00,	0x00,	0x00,	 0x00,	0x00,	0x00,	0x00,
-	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00, 0x00}, /*10*/
+	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00, 0x00, 0x00}, /*10*/
 	{0xD1,	0xD1,	0xD1,	0xD1,	0x01,	 0x01,	0x81,	0x81,	0x81,
-	 0x81,	0x81,	0x81,	0x81,	0x81, 0xD1, 0xD1}, /*11*/
+	 0x81,	0x81,	0x81,	0x81,	0x81, 0xD1, 0xD1, 0x01}, /*11*/
 	{0x02,	0x02,	0x02,	0x02,	0x05,	 0x05,	0x07,	0x07,	0x07,
-	 0x07,	0x07,	0x07,	0x07,	0x02, 0x02, 0x02}  /*12*/
+	 0x07,	0x07,	0x07,	0x07,	0x02, 0x02, 0x02, 0x05}  /*12*/
 };
 
 static void hdmi_msm_avi_info_frame(void)
@@ -3710,6 +3710,9 @@
 	case HDMI_VFRMT_720x576p50_4_3:
 		mode = 15;
 		break;
+	case HDMI_VFRMT_1280x1024p60_5_4:
+		mode = 16;
+		break;
 	default:
 		DEV_INFO("%s: mode %d not supported\n", __func__,
 			external_common_state->video_resolution);
@@ -4489,6 +4492,7 @@
 		cancel_work_sync(&hdmi_msm_state->hdcp_reauth_work);
 		cancel_work_sync(&hdmi_msm_state->hdcp_work);
 		del_timer_sync(&hdmi_msm_state->hdcp_timer);
+		hdmi_msm_state->reauth = FALSE;
 
 		hdcp_deauthenticate();
 	}
@@ -4539,10 +4543,26 @@
 			hdmi_msm_state->hdcp_enable ? "Enabled" : "Disabled");
 }
 
+static void hdmi_msm_update_panel_info(struct msm_fb_data_type *mfd)
+{
+	if (!mfd)
+		return;
+
+	if (hdmi_common_get_video_format_from_drv_data(mfd))
+		hdmi_common_init_panel_info(&mfd->panel_info);
+}
+
+static bool hdmi_msm_cable_connected(void)
+{
+	return hdmi_msm_state->hpd_initialized &&
+			external_common_state->hpd_state;
+}
+
 static int __devinit hdmi_msm_probe(struct platform_device *pdev)
 {
 	int rc;
 	struct platform_device *fb_dev;
+	struct msm_fb_data_type *mfd = NULL;
 
 	if (!hdmi_msm_state) {
 		pr_err("%s: hdmi_msm_state is NULL\n", __func__);
@@ -4664,6 +4684,10 @@
 	} else
 		DEV_ERR("Init FAILED: failed to add fb device\n");
 
+	mfd = platform_get_drvdata(fb_dev);
+	mfd->update_panel_info = hdmi_msm_update_panel_info;
+	mfd->is_panel_ready = hdmi_msm_cable_connected;
+
 	if (hdmi_prim_display) {
 		rc = hdmi_msm_hpd_on();
 		if (rc)
diff --git a/drivers/video/msm/hdmi_msm.h b/drivers/video/msm/hdmi_msm.h
index aded4e0..ce01830 100644
--- a/drivers/video/msm/hdmi_msm.h
+++ b/drivers/video/msm/hdmi_msm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/hdmi_sii9022.c b/drivers/video/msm/hdmi_sii9022.c
index 3d27488..c1b5e03 100644
--- a/drivers/video/msm/hdmi_sii9022.c
+++ b/drivers/video/msm/hdmi_sii9022.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/drivers/video/msm/lcdc.c b/drivers/video/msm/lcdc.c
index 1bd4302..24c4ec9 100644
--- a/drivers/video/msm/lcdc.c
+++ b/drivers/video/msm/lcdc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/drivers/video/msm/lcdc_auo_wvga.c b/drivers/video/msm/lcdc_auo_wvga.c
index 6b0733f..70a28d2 100644
--- a/drivers/video/msm/lcdc_auo_wvga.c
+++ b/drivers/video/msm/lcdc_auo_wvga.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/lcdc_chimei_wxga.c b/drivers/video/msm/lcdc_chimei_wxga.c
index 7453ecb..cab7bb3 100644
--- a/drivers/video/msm/lcdc_chimei_wxga.c
+++ b/drivers/video/msm/lcdc_chimei_wxga.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/lcdc_external.c b/drivers/video/msm/lcdc_external.c
index ca82def..b699610 100644
--- a/drivers/video/msm/lcdc_external.c
+++ b/drivers/video/msm/lcdc_external.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/drivers/video/msm/lcdc_gordon.c b/drivers/video/msm/lcdc_gordon.c
index b675787..ecb23f0 100644
--- a/drivers/video/msm/lcdc_gordon.c
+++ b/drivers/video/msm/lcdc_gordon.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/drivers/video/msm/lcdc_nt35582_wvga.c b/drivers/video/msm/lcdc_nt35582_wvga.c
index 9ecf4b9..2152b1a 100644
--- a/drivers/video/msm/lcdc_nt35582_wvga.c
+++ b/drivers/video/msm/lcdc_nt35582_wvga.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/lcdc_panel.c b/drivers/video/msm/lcdc_panel.c
index 5705325..5de2557 100644
--- a/drivers/video/msm/lcdc_panel.c
+++ b/drivers/video/msm/lcdc_panel.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/drivers/video/msm/lcdc_prism.c b/drivers/video/msm/lcdc_prism.c
index d127f63..fb040ca 100644
--- a/drivers/video/msm/lcdc_prism.c
+++ b/drivers/video/msm/lcdc_prism.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/drivers/video/msm/lcdc_samsung_oled_pt.c b/drivers/video/msm/lcdc_samsung_oled_pt.c
index 16790f3..409496e 100644
--- a/drivers/video/msm/lcdc_samsung_oled_pt.c
+++ b/drivers/video/msm/lcdc_samsung_oled_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/drivers/video/msm/lcdc_samsung_wsvga.c b/drivers/video/msm/lcdc_samsung_wsvga.c
index 6b35e52..ced8344 100644
--- a/drivers/video/msm/lcdc_samsung_wsvga.c
+++ b/drivers/video/msm/lcdc_samsung_wsvga.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/drivers/video/msm/lcdc_sharp_wvga_pt.c b/drivers/video/msm/lcdc_sharp_wvga_pt.c
index 2ba2618..ee125e2 100644
--- a/drivers/video/msm/lcdc_sharp_wvga_pt.c
+++ b/drivers/video/msm/lcdc_sharp_wvga_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/drivers/video/msm/lcdc_st15.c b/drivers/video/msm/lcdc_st15.c
index cdae358..3effac9 100644
--- a/drivers/video/msm/lcdc_st15.c
+++ b/drivers/video/msm/lcdc_st15.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/lcdc_toshiba_fwvga_pt.c b/drivers/video/msm/lcdc_toshiba_fwvga_pt.c
index 77606cf..65c6415 100644
--- a/drivers/video/msm/lcdc_toshiba_fwvga_pt.c
+++ b/drivers/video/msm/lcdc_toshiba_fwvga_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/drivers/video/msm/lcdc_toshiba_wvga_pt.c b/drivers/video/msm/lcdc_toshiba_wvga_pt.c
index f0aa8f5..30248ff 100644
--- a/drivers/video/msm/lcdc_toshiba_wvga_pt.c
+++ b/drivers/video/msm/lcdc_toshiba_wvga_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/drivers/video/msm/lcdc_truly_ips3p2335.c b/drivers/video/msm/lcdc_truly_ips3p2335.c
index b2f4ab8..89ede49 100644
--- a/drivers/video/msm/lcdc_truly_ips3p2335.c
+++ b/drivers/video/msm/lcdc_truly_ips3p2335.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/video/msm/lcdc_wxga.c b/drivers/video/msm/lcdc_wxga.c
index 3204704..dca57de 100644
--- a/drivers/video/msm/lcdc_wxga.c
+++ b/drivers/video/msm/lcdc_wxga.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/drivers/video/msm/lvds.c b/drivers/video/msm/lvds.c
index e9bbceb..4e31d6a 100644
--- a/drivers/video/msm/lvds.c
+++ b/drivers/video/msm/lvds.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/video/msm/lvds_chimei_wxga.c b/drivers/video/msm/lvds_chimei_wxga.c
index 39aa852..181ec6a 100644
--- a/drivers/video/msm/lvds_chimei_wxga.c
+++ b/drivers/video/msm/lvds_chimei_wxga.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/video/msm/lvds_frc_fhd.c b/drivers/video/msm/lvds_frc_fhd.c
index 7739588..36d26c5 100644
--- a/drivers/video/msm/lvds_frc_fhd.c
+++ b/drivers/video/msm/lvds_frc_fhd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c
index b4c1e76..796f67f 100644
--- a/drivers/video/msm/mddi.c
+++ b/drivers/video/msm/mddi.c
@@ -2,7 +2,7 @@
  * MSM MDDI Transport
  *
  * Copyright (C) 2007 Google Incorporated
- * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/video/msm/mddi_ext.c b/drivers/video/msm/mddi_ext.c
index dc79fed..83831b0 100644
--- a/drivers/video/msm/mddi_ext.c
+++ b/drivers/video/msm/mddi_ext.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/drivers/video/msm/mddi_ext_lcd.c b/drivers/video/msm/mddi_ext_lcd.c
index da79513..aa4d484 100644
--- a/drivers/video/msm/mddi_ext_lcd.c
+++ b/drivers/video/msm/mddi_ext_lcd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/drivers/video/msm/mddi_orise.c b/drivers/video/msm/mddi_orise.c
index fa48c75..bf9f1fa 100644
--- a/drivers/video/msm/mddi_orise.c
+++ b/drivers/video/msm/mddi_orise.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 2012 Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/mddi_prism.c b/drivers/video/msm/mddi_prism.c
index ec2bf57..c2fa8b9 100644
--- a/drivers/video/msm/mddi_prism.c
+++ b/drivers/video/msm/mddi_prism.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/drivers/video/msm/mddi_quickvx.c b/drivers/video/msm/mddi_quickvx.c
index 37c147d..a5d9ea3 100644
--- a/drivers/video/msm/mddi_quickvx.c
+++ b/drivers/video/msm/mddi_quickvx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 2012 Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/mddi_sharp.c b/drivers/video/msm/mddi_sharp.c
index 6a9008f..c10d01a 100644
--- a/drivers/video/msm/mddi_sharp.c
+++ b/drivers/video/msm/mddi_sharp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/drivers/video/msm/mddi_toshiba.c b/drivers/video/msm/mddi_toshiba.c
index 9727453..f06a2fd 100644
--- a/drivers/video/msm/mddi_toshiba.c
+++ b/drivers/video/msm/mddi_toshiba.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/drivers/video/msm/mddi_toshiba.h b/drivers/video/msm/mddi_toshiba.h
index 646f5e9..854817f 100644
--- a/drivers/video/msm/mddi_toshiba.h
+++ b/drivers/video/msm/mddi_toshiba.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/drivers/video/msm/mddi_toshiba_vga.c b/drivers/video/msm/mddi_toshiba_vga.c
index 73749f9..3b4a85d 100644
--- a/drivers/video/msm/mddi_toshiba_vga.c
+++ b/drivers/video/msm/mddi_toshiba_vga.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/drivers/video/msm/mddi_toshiba_wvga.c b/drivers/video/msm/mddi_toshiba_wvga.c
index c1925e1..7e7b036 100644
--- a/drivers/video/msm/mddi_toshiba_wvga.c
+++ b/drivers/video/msm/mddi_toshiba_wvga.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/drivers/video/msm/mddi_toshiba_wvga_pt.c b/drivers/video/msm/mddi_toshiba_wvga_pt.c
index 8da1485..bdb04ff 100644
--- a/drivers/video/msm/mddi_toshiba_wvga_pt.c
+++ b/drivers/video/msm/mddi_toshiba_wvga_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/drivers/video/msm/mddihost.c b/drivers/video/msm/mddihost.c
index c6acf9f..c2a7af3 100644
--- a/drivers/video/msm/mddihost.c
+++ b/drivers/video/msm/mddihost.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/drivers/video/msm/mddihost.h b/drivers/video/msm/mddihost.h
index 52bc67c..db2df38 100644
--- a/drivers/video/msm/mddihost.h
+++ b/drivers/video/msm/mddihost.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/drivers/video/msm/mddihost_e.c b/drivers/video/msm/mddihost_e.c
index d53aa6f..275e4ee 100644
--- a/drivers/video/msm/mddihost_e.c
+++ b/drivers/video/msm/mddihost_e.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/drivers/video/msm/mddihosti.c b/drivers/video/msm/mddihosti.c
index 1a5a3fd..b4429f6 100644
--- a/drivers/video/msm/mddihosti.c
+++ b/drivers/video/msm/mddihosti.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/drivers/video/msm/mddihosti.h b/drivers/video/msm/mddihosti.h
index 166d15c..96675a0 100644
--- a/drivers/video/msm/mddihosti.h
+++ b/drivers/video/msm/mddihosti.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index e41017d..77eb9c2 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -2,7 +2,7 @@
  *
  * MSM MDP Interface (used by framebuffer core)
  *
- * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
  * Copyright (C) 2007 Google Incorporated
  *
  * This software is licensed under the terms of the GNU General Public
@@ -2298,7 +2298,8 @@
 	if (mdp_rev == MDP_REV_303 && mfd->panel.type == MIPI_CMD_PANEL) {
 
 		vsync_cntrl.dev = mfd->fbi->dev;
-		atomic_set(&vsync_cntrl.suspend, 1);
+		atomic_set(&vsync_cntrl.suspend, 0);
+		atomic_set(&vsync_cntrl.vsync_resume, 1);
 	}
 
 	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
@@ -2307,6 +2308,10 @@
 	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 
 	mdp_histogram_ctrl_all(TRUE);
+
+	if (ret == 0)
+		ret = panel_next_late_init(pdev);
+
 	pr_debug("%s:-\n", __func__);
 
 	return ret;
@@ -2743,6 +2748,7 @@
 	pdata = msm_fb_dev->dev.platform_data;
 	pdata->on = mdp_on;
 	pdata->off = mdp_off;
+	pdata->late_init = NULL;
 	pdata->next = pdev;
 
 	mdp_clk_ctrl(1);
@@ -3054,9 +3060,13 @@
 
 	pdev_list[pdev_list_cnt++] = pdev;
 	mdp4_extn_disp = 0;
-
-	if (mfd->vsync_init != NULL) {
-		mfd->vsync_init(0);
+	/*
+	 * vsync_init call not required for mdp3.
+	 * vsync_init call required for mdp4 targets.
+	 */
+	if ((mfd->vsync_init != NULL) || (mdp_rev < MDP_REV_40)) {
+		if (mdp_rev >= MDP_REV_40)
+			mfd->vsync_init(0);
 
 		if (!mfd->vsync_sysfs_created) {
 			mfd->dev_attr.attr.name = "vsync_event";
diff --git a/drivers/video/msm/mdp.h b/drivers/video/msm/mdp.h
index eab4dbe..631ce38 100644
--- a/drivers/video/msm/mdp.h
+++ b/drivers/video/msm/mdp.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
@@ -73,6 +73,7 @@
 #define MDPOP_SHARPENING	BIT(11) /* enable sharpening */
 #define MDPOP_BLUR		BIT(12) /* enable blur */
 #define MDPOP_FG_PM_ALPHA       BIT(13)
+#define MDPOP_LAYER_IS_FG       BIT(14)
 #define MDP_ALLOC(x)  kmalloc(x, GFP_KERNEL)
 
 struct mdp_buf_type {
@@ -927,7 +928,7 @@
 
 int mdp_ppp_v4l2_overlay_set(struct fb_info *info, struct mdp_overlay *req);
 int mdp_ppp_v4l2_overlay_clear(void);
-int mdp_ppp_v4l2_overlay_play(struct fb_info *info,
+int mdp_ppp_v4l2_overlay_play(struct fb_info *info, bool bUserPtr,
 	unsigned long srcp0_addr, unsigned long srcp0_size,
 	unsigned long srcp1_addr, unsigned long srcp1_size);
 void mdp_update_pm(struct msm_fb_data_type *mfd, ktime_t pre_vsync);
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index 02cdd71..a3d8d7e 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
@@ -276,6 +276,7 @@
 	struct mdp4_overlay_pipe *solidfill_pipe;
 };
 
+
 struct mdp4_overlay_pipe {
 	uint32 pipe_used;
 	uint32 pipe_type;		/* rgb, video/graphic */
@@ -955,6 +956,7 @@
 int mdp4_pcc_cfg(struct mdp_pcc_cfg_data *cfg_ptr);
 int mdp4_argc_cfg(struct mdp_pgc_lut_data *pgc_ptr);
 int mdp4_qseed_cfg(struct mdp_qseed_cfg_data *cfg);
+int mdp4_calib_config(struct mdp_calib_config_data *cfg);
 int mdp4_qseed_access_cfg(struct mdp_qseed_cfg *cfg, uint32_t base);
 u32  mdp4_allocate_writeback_buf(struct msm_fb_data_type *mfd, u32 mix_num);
 void mdp4_init_writeback_buf(struct msm_fb_data_type *mfd, u32 mix_num);
@@ -982,6 +984,8 @@
 void mdp4_overlay_mdp_perf_upd(struct msm_fb_data_type *mfd, int flag);
 int mdp4_update_base_blend(struct msm_fb_data_type *mfd,
 				struct mdp_blend_cfg *mdp_blend_cfg);
+int mdp4_update_writeback_format(struct msm_fb_data_type *mfd,
+			struct mdp_mixer_cfg *mdp_mixer_cfg);
 u32 mdp4_get_mixer_num(u32 panel_type);
 
 #ifndef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
diff --git a/drivers/video/msm/mdp4_dtv.c b/drivers/video/msm/mdp4_dtv.c
index 4b83224..ba810a9 100644
--- a/drivers/video/msm/mdp4_dtv.c
+++ b/drivers/video/msm/mdp4_dtv.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index 43fcb7c..bfd8238 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
@@ -49,6 +49,7 @@
 	struct mdp4_overlay_pipe *baselayer[MDP4_MIXER_MAX];
 	struct blend_cfg blend[MDP4_MIXER_MAX][MDP4_MIXER_STAGE_MAX];
 	struct mdp4_overlay_pipe sf_plist[MDP4_MIXER_MAX][OVERLAY_PIPE_MAX];
+	struct mdp_mixer_cfg mdp_mixer_cfg[MDP4_MIXER_MAX];
 	uint32 mixer_cfg[MDP4_MIXER_MAX];
 	uint32 flush[MDP4_MIXER_MAX];
 	struct iommu_free_list iommu_free[MDP4_MIXER_MAX];
@@ -780,6 +781,7 @@
 		case MDP_ARGB_8888:
 		case MDP_RGBA_8888:
 		case MDP_BGRA_8888:
+		case MDP_BGRX_8888:
 		case MDP_RGBX_8888:
 		case MDP_RGB_565:
 		case MDP_BGR_565:
@@ -967,6 +969,7 @@
 	case MDP_ARGB_8888:
 	case MDP_RGBA_8888:
 	case MDP_BGRA_8888:
+	case MDP_BGRX_8888:
 	case MDP_RGBX_8888:
 		return OVERLAY_TYPE_RGB;
 	case MDP_YCRYCB_H2V1:
@@ -1137,6 +1140,23 @@
 		pipe->element0 = C1_B_Cb;	/* B */
 		pipe->bpp = 4;		/* 4 bpp */
 		break;
+	case MDP_BGRX_8888:
+		pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
+		pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
+		pipe->a_bit = 3;        /* alpha, 4 bits */
+		pipe->r_bit = 3;        /* R, 8 bits */
+		pipe->b_bit = 3;        /* B, 8 bits */
+		pipe->g_bit = 3;        /* G, 8 bits */
+		pipe->alpha_enable = 0;
+		pipe->unpack_tight = 1;
+		pipe->unpack_align_msb = 0;
+		pipe->unpack_count = 3;
+		pipe->element3 = C3_ALPHA;      /* alpha */
+		pipe->element2 = C2_R_Cr;       /* R */
+		pipe->element1 = C0_G_Y;        /* G */
+		pipe->element0 = C1_B_Cb;       /* B */
+		pipe->bpp = 4;          /* 4 bpp */
+		break;
 	case MDP_YCRYCB_H2V1:
 		pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
 		pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
@@ -1324,6 +1344,7 @@
 	case MDP_XRGB_8888:
 	case MDP_ARGB_8888:
 	case MDP_BGRA_8888:
+	case MDP_BGRX_8888:
 		b_start = 0;
 		g_start = 8;
 		r_start = 16;
@@ -1436,6 +1457,87 @@
 			(pipe->element1 << 8) | pipe->element0;
 }
 
+static uint32 mdp4_overlayproc_cfg_wb_panel(struct mdp4_overlay_pipe *pipe,
+					char *overlay_base, uint32 curr)
+{
+	int off, bpp;
+	uint32 flag;
+	bool is_rgb = false;
+	struct mdp_mixer_cfg *mixer_cfg;
+
+	off = 0;
+	mixer_cfg = &ctrl->mdp_mixer_cfg[MDP4_MIXER2];
+
+	switch (mixer_cfg->writeback_format) {
+	case WB_FORMAT_RGB_888:
+		bpp = 3; /* RGB888 */
+		flag = 0x0;
+		is_rgb = true;
+		break;
+	case WB_FORMAT_RGB_565:
+		bpp = 2; /* RGB565 */
+		flag = 0x1;
+		is_rgb = true;
+		break;
+	case WB_FORMAT_xRGB_8888:
+		bpp = 4; /* xRGB8888 */
+		flag = 0x3;
+		is_rgb = true;
+		break;
+	case WB_FORMAT_ARGB_8888:
+		bpp = 4; /* ARGB8888 */
+		flag = 0x80000003;
+		is_rgb = true;
+		break;
+	case WB_FORMAT_ARGB_8888_INPUT_ALPHA:
+		pr_warn("currently not supported ARGB_8888_INPUT_ALPHA\n");
+	default:
+		bpp = 1; /* NV12 */
+		is_rgb = false;
+		break;
+	}
+
+	if (is_rgb == true) {
+		if (pipe->ov_cnt & 0x01)
+			off = pipe->src_height * pipe->src_width * bpp;
+
+		outpdw(overlay_base + 0x000c, pipe->ov_blt_addr + off);
+		/* overlay ouput is RGB888 */
+		outpdw(overlay_base + 0x0010, pipe->src_width * bpp);
+		outpdw(overlay_base + 0x001c, pipe->ov_blt_addr + off);
+		/* MDDI - BLT + on demand */
+		outpdw(overlay_base + 0x0004, 0x08);
+
+		curr = inpdw(overlay_base + 0x0014);
+		curr &= 0x4;
+
+		outpdw(overlay_base + 0x0014, curr | flag);
+	} else {
+		if (pipe->ov_cnt & 0x01)
+			off = pipe->src_height * pipe->src_width * bpp;
+
+		outpdw(overlay_base + 0x000c, pipe->ov_blt_addr + off);
+		/* overlay ouput is RGB888 */
+		outpdw(overlay_base + 0x0010, ((pipe->src_width << 16) |
+				pipe->src_width));
+		outpdw(overlay_base + 0x001c, pipe->ov_blt_addr + off);
+		off = pipe->src_height * pipe->src_width;
+		/* align chroma to 2k address */
+		off = (off + 2047) & ~2047;
+		/* UV plane adress */
+		outpdw(overlay_base + 0x0020, pipe->ov_blt_addr + off);
+		/* MDDI - BLT + on demand */
+		outpdw(overlay_base + 0x0004, 0x08);
+		/* pseudo planar + writeback */
+		curr = inpdw(overlay_base + 0x0014);
+		curr &= 0x4;
+		outpdw(overlay_base + 0x0014, curr | 0x012);
+		/* rgb->yuv */
+		outpdw(overlay_base + 0x0200, 0x05);
+	}
+	return curr;
+}
+
 /*
  * mdp4_overlayproc_cfg: only be called from base layer
  */
@@ -1495,34 +1597,8 @@
 #endif
 		} else if (pipe->mixer_num == MDP4_MIXER2) {
 			if (ctrl->panel_mode & MDP4_PANEL_WRITEBACK) {
-				off = 0;
-				bpp = 1;
-				if (pipe->ov_cnt & 0x01)
-					off = pipe->src_height *
-							pipe->src_width * bpp;
-
-				outpdw(overlay_base + 0x000c,
-						pipe->ov_blt_addr + off);
-				/* overlay ouput is RGB888 */
-				outpdw(overlay_base + 0x0010,
-					((pipe->src_width << 16) |
-					 pipe->src_width));
-				outpdw(overlay_base + 0x001c,
-						pipe->ov_blt_addr + off);
-				off = pipe->src_height * pipe->src_width;
-				/* align chroma to 2k address */
-				off = (off + 2047) & ~2047;
-				/* UV plane adress */
-				outpdw(overlay_base + 0x0020,
-						pipe->ov_blt_addr + off);
-				/* MDDI - BLT + on demand */
-				outpdw(overlay_base + 0x0004, 0x08);
-				/* pseudo planar + writeback */
-				curr = inpdw(overlay_base + 0x0014);
-				curr &= 0x4;
-				outpdw(overlay_base + 0x0014, curr | 0x012);
-				/* rgb->yuv */
-				outpdw(overlay_base + 0x0200, 0x05);
+				curr = mdp4_overlayproc_cfg_wb_panel(pipe,
+							overlay_base, curr);
 			}
 		}
 	} else {
@@ -3845,6 +3921,42 @@
 	mutex_unlock(&mfd->dma->ov_mutex);
 	return err;
 }
+
+int mdp4_update_writeback_format(struct msm_fb_data_type *mfd,
+				struct mdp_mixer_cfg *mdp_mixer_cfg)
+{
+	int ret = 0;
+	u32 mixer_num;
+	struct mdp_mixer_cfg *mixer;
+
+	mixer_num = mdp4_get_mixer_num(mfd->panel_info.type);
+	if (!ctrl) {
+		pr_warn("mdp4_overlay_ctrl is NULL\n");
+		return -EPERM;
+	}
+	mixer = &ctrl->mdp_mixer_cfg[mixer_num];
+
+	switch (mdp_mixer_cfg->writeback_format) {
+	case WB_FORMAT_RGB_888:
+	case WB_FORMAT_RGB_565:
+	case WB_FORMAT_NV12:
+	case WB_FORMAT_xRGB_8888:
+	case WB_FORMAT_ARGB_8888:
+		mixer->writeback_format = mdp_mixer_cfg->writeback_format;
+		break;
+	case WB_FORMAT_ARGB_8888_INPUT_ALPHA:
+		mixer->writeback_format = mdp_mixer_cfg->writeback_format;
+		mixer->alpha = mdp_mixer_cfg->alpha;
+		break;
+	default:
+		mixer->writeback_format = WB_FORMAT_NV12;
+		pr_warn("Unsupported format request, setting to NV12\n");
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
 int mdp4_update_base_blend(struct msm_fb_data_type *mfd,
 			struct mdp_blend_cfg *mdp_blend_cfg)
 {
diff --git a/drivers/video/msm/mdp4_overlay_atv.c b/drivers/video/msm/mdp4_overlay_atv.c
index 90c3da9..4cbac09 100644
--- a/drivers/video/msm/mdp4_overlay_atv.c
+++ b/drivers/video/msm/mdp4_overlay_atv.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 2012 Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/mdp4_overlay_dsi_cmd.c b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
index 9cb2b34..5554d88 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_cmd.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -687,7 +687,10 @@
 		msecs_to_jiffies(VSYNC_PERIOD * 4));
 	if (ret <= 0) {
 		vctrl->wait_vsync_cnt = 0;
-		return -EBUSY;
+		vsync_tick = ktime_to_ns(ktime_get());
+		ret = snprintf(buf, PAGE_SIZE, "VSYNC=%llu", vsync_tick);
+		buf[strlen(buf) + 1] = '\0';
+		return ret;
 	}
 
 	spin_lock_irqsave(&vctrl->spin_lock, flags);
@@ -867,6 +870,9 @@
 		pipe = vctrl->base_pipe;
 	}
 
+	/* TE enabled */
+	mdp4_mipi_vsync_enable(mfd, pipe, 0);
+
 	MDP_OUTP(MDP_BASE + 0x021c, 10); /* read pointer */
 
 	/*
diff --git a/drivers/video/msm/mdp4_overlay_dsi_video.c b/drivers/video/msm/mdp4_overlay_dsi_video.c
index a4d2b77..72a53fc 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_video.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_video.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -390,7 +390,10 @@
 		msecs_to_jiffies(VSYNC_PERIOD * 4));
 	if (ret <= 0) {
 		vctrl->wait_vsync_cnt = 0;
-		return -EBUSY;
+		vsync_tick = ktime_to_ns(ktime_get());
+		ret = snprintf(buf, PAGE_SIZE, "VSYNC=%llu", vsync_tick);
+		buf[strlen(buf) + 1] = '\0';
+		return ret;
 	}
 
 	spin_lock_irqsave(&vctrl->spin_lock, flags);
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
index 85fb305..8539c00 100644
--- a/drivers/video/msm/mdp4_overlay_dtv.c
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
@@ -376,7 +376,10 @@
 		msecs_to_jiffies(VSYNC_PERIOD * 4));
 	if (ret <= 0) {
 		vctrl->wait_vsync_cnt = 0;
-		return -EBUSY;
+		vsync_tick = ktime_to_ns(ktime_get());
+		ret = snprintf(buf, PAGE_SIZE, "VSYNC=%llu", vsync_tick);
+		buf[strlen(buf) + 1] = '\0';
+		return ret;
 	}
 
 	spin_lock_irqsave(&vctrl->spin_lock, flags);
@@ -701,10 +704,10 @@
 	atomic_set(&vctrl->suspend, 1);
 	atomic_set(&vctrl->vsync_resume, 0);
 
-	if (vctrl->vsync_irq_enabled) {
-		while (vctrl->wait_vsync_cnt)
-			msleep(20);     /* >= 17 ms */
-	}
+	/* wait for one vsycn time to make sure
+	 * previous stage_commit had been kicked in
+	 */
+	msleep(20);     /* >= 17 ms */
 
 	complete_all(&vctrl->vsync_comp);
 
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index 4a46d72..3702b59 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
@@ -386,7 +386,10 @@
 		msecs_to_jiffies(VSYNC_PERIOD * 4));
 	if (ret <= 0) {
 		vctrl->wait_vsync_cnt = 0;
-		return -EBUSY;
+		vsync_tick = ktime_to_ns(ktime_get());
+		ret = snprintf(buf, PAGE_SIZE, "VSYNC=%llu", vsync_tick);
+		buf[strlen(buf) + 1] = '\0';
+		return ret;
 	}
 
 	spin_lock_irqsave(&vctrl->spin_lock, flags);
diff --git a/drivers/video/msm/mdp4_overlay_writeback.c b/drivers/video/msm/mdp4_overlay_writeback.c
index bd20e82..7caf0ad 100644
--- a/drivers/video/msm/mdp4_overlay_writeback.c
+++ b/drivers/video/msm/mdp4_overlay_writeback.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/drivers/video/msm/mdp4_util.c b/drivers/video/msm/mdp4_util.c
index 01ec10e..2423de5 100644
--- a/drivers/video/msm/mdp4_util.c
+++ b/drivers/video/msm/mdp4_util.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
@@ -634,6 +634,7 @@
 #if defined(CONFIG_FB_MSM_WRITEBACK_MSM_PANEL)
 	if (isr & INTR_OVERLAY2_DONE) {
 		mdp4_stat.intr_overlay2++;
+		mdp_pipe_ctrl(MDP_OVERLAY2_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 		/* disable DTV interrupt */
 		if (panel & MDP4_PANEL_WRITEBACK)
 			mdp4_overlay2_done_wfd(&dma_wb_data);
@@ -3080,6 +3081,106 @@
 error:
 	return ret;
 }
+
+static int is_valid_calib_addr(void *addr)
+{
+	int ret = 0;
+	unsigned int ptr;
+
+	ptr = (unsigned int) addr;
+
+	if (mdp_rev >= MDP_REV_30 && mdp_rev < MDP_REV_40) {
+		/* if request is outside the MDP reg-map or is not aligned 4 */
+		if (ptr == 0x0 || ptr > 0xF0600 || ptr % 0x4)
+			goto end;
+
+		if (ptr >= 0x90000 && ptr < 0x94000) {
+			if (ptr == 0x90000 || ptr == 0x90070)
+				ret = 1;
+			else if (ptr >= 0x93400 && ptr <= 0x93420)
+				ret = 1;
+			else if (ptr >= 0x93500 && ptr <= 0x93508)
+				ret = 1;
+			else if (ptr >= 0x93580 && ptr <= 0x93588)
+				ret = 1;
+			else if (ptr >= 0x93600 && ptr <= 0x93614)
+				ret = 1;
+			else if (ptr >= 0x93680 && ptr <= 0x93694)
+				ret = 1;
+			else if (ptr >= 0x93800 && ptr <= 0x93BFC)
+				ret = 1;
+		}
+	} else if (mdp_rev >= MDP_REV_40 && mdp_rev <= MDP_REV_44) {
+		/* if request is outside the MDP reg-map or is not aligned 4 */
+		if (ptr > 0xF0600 || ptr % 0x4)
+			goto end;
+
+		if (ptr < 0x90000) {
+			if (ptr == 0x0 || ptr == 0x4 || ptr == 0x28200 ||
+								ptr == 0x28204)
+				ret = 1;
+		} else if (ptr < 0x95000) {
+			if (ptr == 0x90000 || ptr == 0x90070)
+				ret = 1;
+			else if (ptr >= 0x93400 && ptr <= 0x93420)
+				ret = 1;
+			else if (ptr >= 0x93500 && ptr <= 0x93508)
+				ret = 1;
+			else if (ptr >= 0x93580 && ptr <= 0x93588)
+				ret = 1;
+			else if (ptr >= 0x93600 && ptr <= 0x93614)
+				ret = 1;
+			else if (ptr >= 0x93680 && ptr <= 0x93694)
+				ret = 1;
+			else if (ptr >= 0x94800 && ptr <= 0x94BFC)
+				ret = 1;
+		} else if (ptr < 0x9A000) {
+			if (ptr >= 0x98800 && ptr <= 0x9883C)
+				ret = 1;
+			else if (ptr >= 0x98880 && ptr <= 0x988AC)
+				ret = 1;
+			else if (ptr >= 0x98900 && ptr <= 0x9893C)
+				ret = 1;
+			else if (ptr >= 0x98980 && ptr <= 0x989BC)
+				ret = 1;
+			else if (ptr >= 0x98A00 && ptr <= 0x98A3C)
+				ret = 1;
+			else if (ptr >= 0x98A80 && ptr <= 0x98ABC)
+				ret = 1;
+			else if (ptr >= 0x99000 && ptr <= 0x993FC)
+				ret = 1;
+			else if (ptr >= 0x99800 && ptr <= 0x99BFC)
+				ret = 1;
+		} else if (ptr >= 0x9A000 && ptr <= 0x9a08c) {
+			ret = 1;
+		}
+	}
+end:
+	return ret;
+}
+
+int mdp4_calib_config(struct mdp_calib_config_data *cfg)
+{
+	int ret = -1;
+	void *ptr = (void *) cfg->addr;
+
+	if (is_valid_calib_addr(ptr))
+		ret = 0;
+	else
+		return ret;
+
+	ptr = (void *)(((unsigned int) ptr) + MDP_BASE);
+	mdp_clk_ctrl(1);
+	if (cfg->ops & MDP_PP_OPS_READ) {
+		cfg->data = inpdw(ptr);
+		ret = 1;
+	} else if (cfg->ops & MDP_PP_OPS_WRITE) {
+		outpdw(ptr, cfg->data);
+	}
+	mdp_clk_ctrl(0);
+	return ret;
+}
+
 u32 mdp4_get_mixer_num(u32 panel_type)
 {
 	u32 mixer_num;
diff --git a/drivers/video/msm/mdp4_wfd_writeback.c b/drivers/video/msm/mdp4_wfd_writeback.c
index a8fdcc0..d96fc7d 100644
--- a/drivers/video/msm/mdp4_wfd_writeback.c
+++ b/drivers/video/msm/mdp4_wfd_writeback.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/mdp4_wfd_writeback_panel.c b/drivers/video/msm/mdp4_wfd_writeback_panel.c
index 40ffb65..c3d0431 100644
--- a/drivers/video/msm/mdp4_wfd_writeback_panel.c
+++ b/drivers/video/msm/mdp4_wfd_writeback_panel.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/mdp4_wfd_writeback_util.h b/drivers/video/msm/mdp4_wfd_writeback_util.h
index 2d62713..582d198 100644
--- a/drivers/video/msm/mdp4_wfd_writeback_util.h
+++ b/drivers/video/msm/mdp4_wfd_writeback_util.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/mdp_cursor.c b/drivers/video/msm/mdp_cursor.c
index b5930a1..a3920af 100644
--- a/drivers/video/msm/mdp_cursor.c
+++ b/drivers/video/msm/mdp_cursor.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/drivers/video/msm/mdp_debugfs.c b/drivers/video/msm/mdp_debugfs.c
index 767375d..d3e0c8d 100644
--- a/drivers/video/msm/mdp_debugfs.c
+++ b/drivers/video/msm/mdp_debugfs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/drivers/video/msm/mdp_dma.c b/drivers/video/msm/mdp_dma.c
index 4d4b05f..842f96b 100644
--- a/drivers/video/msm/mdp_dma.c
+++ b/drivers/video/msm/mdp_dma.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/drivers/video/msm/mdp_dma_dsi_video.c b/drivers/video/msm/mdp_dma_dsi_video.c
index cfbff9a..b349213 100644
--- a/drivers/video/msm/mdp_dma_dsi_video.c
+++ b/drivers/video/msm/mdp_dma_dsi_video.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/drivers/video/msm/mdp_dma_lcdc.c b/drivers/video/msm/mdp_dma_lcdc.c
index c51a99a..04d8b01 100644
--- a/drivers/video/msm/mdp_dma_lcdc.c
+++ b/drivers/video/msm/mdp_dma_lcdc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/drivers/video/msm/mdp_dma_s.c b/drivers/video/msm/mdp_dma_s.c
index 22d79be..c5a2402 100644
--- a/drivers/video/msm/mdp_dma_s.c
+++ b/drivers/video/msm/mdp_dma_s.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/drivers/video/msm/mdp_dma_tv.c b/drivers/video/msm/mdp_dma_tv.c
index b578ba2..ee2e323 100644
--- a/drivers/video/msm/mdp_dma_tv.c
+++ b/drivers/video/msm/mdp_dma_tv.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/drivers/video/msm/mdp_hw_init.c b/drivers/video/msm/mdp_hw_init.c
index fc8435c..ad2789b 100644
--- a/drivers/video/msm/mdp_hw_init.c
+++ b/drivers/video/msm/mdp_hw_init.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/drivers/video/msm/mdp_lcdc.c b/drivers/video/msm/mdp_lcdc.c
index 62b0975..22bab96 100644
--- a/drivers/video/msm/mdp_lcdc.c
+++ b/drivers/video/msm/mdp_lcdc.c
@@ -1,7 +1,7 @@
 /* drivers/video/msm/mdp_lcdc.c
  *
  * Copyright (c) 2009 Google Inc.
- * Copyright (c) 2009 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/video/msm/mdp_ppp.c b/drivers/video/msm/mdp_ppp.c
index 8999395..415b575 100644
--- a/drivers/video/msm/mdp_ppp.c
+++ b/drivers/video/msm/mdp_ppp.c
@@ -1,7 +1,7 @@
 /* drivers/video/msm/src/drv/mdp/mdp_ppp.c
  *
  * Copyright (C) 2007 Google Incorporated
- * Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2012 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -1401,6 +1401,9 @@
 
 	iBuf.mdpImg.mdpOp = MDPOP_NOP;
 
+	if (req->flags & MDP_IS_FG)
+		iBuf.mdpImg.mdpOp |= MDPOP_LAYER_IS_FG;
+
 	/* blending check */
 	if (req->transp_mask != MDP_TRANSP_NOP) {
 		iBuf.mdpImg.mdpOp |= MDPOP_TRANSP;
@@ -1698,12 +1701,19 @@
 	return 0;
 }
 
-int mdp_ppp_v4l2_overlay_play(struct fb_info *info,
+int mdp_ppp_v4l2_overlay_play(struct fb_info *info, bool bUserPtr,
 	unsigned long srcp0_addr, unsigned long srcp0_size,
 	unsigned long srcp1_addr, unsigned long srcp1_size)
 {
 	int ret;
+	unsigned long srcp0_start = 0, srcp1_start = 0;
+	unsigned long srcp0_len = 0, srcp1_len = 0;
 
+	struct ion_handle *srcp0_ihdl = NULL;
+	struct ion_handle *srcp1_ihdl = NULL;
+	struct msm_fb_data_type *mfd = info->par;
+
+	ppp_display_iclient = mfd->iclient;
 	if (!mdp_overlay_req_set) {
 		pr_err("mdp_ppp:v4l2:No overlay set, ignore play req\n");
 		return -EINVAL;
@@ -1712,6 +1722,31 @@
 	overlay_req.dst.width = info->var.xres;
 	overlay_req.dst.height = info->var.yres;
 
+	if (bUserPtr) {
+		overlay_req.src.memory_id = srcp0_addr;
+		get_img(&overlay_req.src, &overlay_req, info, &srcp0_start,
+					&srcp0_len, NULL, &srcp0_ihdl);
+		if (srcp0_len == 0) {
+			pr_err("%s: could not retrieve source image0"
+						, __func__);
+			return -EINVAL;
+		}
+		srcp0_addr = srcp0_start + srcp0_size;
+		srcp0_size = srcp0_len;
+
+		if (srcp1_addr) {
+			overlay_req.src.memory_id = srcp1_addr;
+			get_img(&overlay_req.src, &overlay_req, info,
+				&srcp1_start, &srcp1_len, NULL, &srcp1_ihdl);
+			if (srcp1_len == 0) {
+				pr_err("%s: could not retrieve source image1"
+					, __func__);
+				return -EINVAL;
+			}
+			srcp1_addr = srcp1_start + srcp1_size;
+			srcp1_size = srcp1_len;
+		}
+	}
 	ret = mdp_ppp_blit_addr(info, &overlay_req,
 		srcp0_addr, srcp0_size, srcp1_addr, srcp1_size,
 		info->fix.smem_start, info->fix.smem_len, NULL, NULL,
diff --git a/drivers/video/msm/mdp_ppp22.c b/drivers/video/msm/mdp_ppp22.c
index 9016f0a..799ce52 100644
--- a/drivers/video/msm/mdp_ppp22.c
+++ b/drivers/video/msm/mdp_ppp22.c
@@ -1,6 +1,6 @@
 /* drivers/video/msm/mdp_ppp22.c
  *
- * Copyright (C) 2007 Code Aurora Forum. All rights reserved.
+ * Copyright (C) 2007 The Linux Foundation. All rights reserved.
  * Copyright (C) 2007 Google Incorporated
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/drivers/video/msm/mdp_ppp31.c b/drivers/video/msm/mdp_ppp31.c
index 91764fe..2d28358 100644
--- a/drivers/video/msm/mdp_ppp31.c
+++ b/drivers/video/msm/mdp_ppp31.c
@@ -1,6 +1,6 @@
 /* drivers/video/msm/mdp_ppp31.c
  *
- * Copyright (C) 2009 Code Aurora Forum. All rights reserved.
+ * Copyright (C) 2009 The Linux Foundation. All rights reserved.
  * Copyright (C) 2009 Google Incorporated
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/drivers/video/msm/mdp_ppp_v20.c b/drivers/video/msm/mdp_ppp_v20.c
index 418528e..50164fd 100644
--- a/drivers/video/msm/mdp_ppp_v20.c
+++ b/drivers/video/msm/mdp_ppp_v20.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
@@ -2467,7 +2467,8 @@
 			bg_alpha = PPP_BLEND_BG_USE_ALPHA_SEL |
 				PPP_BLEND_BG_ALPHA_REVERSE;
 
-			if (perPixelAlpha) {
+			if ((perPixelAlpha) && !(iBuf->mdpImg.mdpOp &
+							MDPOP_LAYER_IS_FG)) {
 				bg_alpha |= PPP_BLEND_BG_SRCPIXEL_ALPHA;
 			} else {
 				bg_alpha |= PPP_BLEND_BG_CONSTANT_ALPHA;
@@ -2478,7 +2479,12 @@
 			if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)
 				*pppop_reg_ptr |= PPP_BLEND_CALPHA_TRNASP;
 		} else if (perPixelAlpha) {
-				*pppop_reg_ptr |= PPP_OP_ROT_ON |
+				if (iBuf->mdpImg.mdpOp & MDPOP_LAYER_IS_FG)
+					*pppop_reg_ptr |= PPP_OP_ROT_ON |
+						  PPP_OP_BLEND_ON |
+						  PPP_OP_BLEND_CONSTANT_ALPHA;
+				else
+					*pppop_reg_ptr |= PPP_OP_ROT_ON |
 						  PPP_OP_BLEND_ON |
 						  PPP_OP_BLEND_SRCPIXEL_ALPHA;
 				outpdw(MDP_BASE + 0x70010, 0);
diff --git a/drivers/video/msm/mdp_ppp_v31.c b/drivers/video/msm/mdp_ppp_v31.c
index ee6af53..3c149b1 100644
--- a/drivers/video/msm/mdp_ppp_v31.c
+++ b/drivers/video/msm/mdp_ppp_v31.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/drivers/video/msm/mdp_vsync.c b/drivers/video/msm/mdp_vsync.c
index cc350d3..b574a5a 100644
--- a/drivers/video/msm/mdp_vsync.c
+++ b/drivers/video/msm/mdp_vsync.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/drivers/video/msm/mdss/Kconfig b/drivers/video/msm/mdss/Kconfig
index 56eb90c..7682a49 100644
--- a/drivers/video/msm/mdss/Kconfig
+++ b/drivers/video/msm/mdss/Kconfig
@@ -12,7 +12,7 @@
 	The MDSS HDMI Panel provides support for transmitting TMDS signals of
 	MDSS frame buffer data to connected hdmi compliant TVs, monitors etc.
 
-config FB_MSM_MDSS_HDMI_MHL_8334
+config FB_MSM_MDSS_HDMI_MHL_SII8334
 	depends on FB_MSM_MDSS_HDMI_PANEL
 	bool 'MHL SII8334 support '
 	default n
diff --git a/drivers/video/msm/mdss/Makefile b/drivers/video/msm/mdss/Makefile
index 4deaa8c..17987d4 100644
--- a/drivers/video/msm/mdss/Makefile
+++ b/drivers/video/msm/mdss/Makefile
@@ -19,7 +19,7 @@
 obj-$(CONFIG_FB_MSM_MDSS_HDMI_PANEL) += mdss_hdmi_tx.o
 obj-$(CONFIG_FB_MSM_MDSS_HDMI_PANEL) += mdss_hdmi_util.o
 obj-$(CONFIG_FB_MSM_MDSS_HDMI_PANEL) += mdss_hdmi_edid.o
-obj-$(CONFIG_FB_MSM_MDSS_HDMI_MHL_8334) += mhl_sii8334.o
+obj-$(CONFIG_FB_MSM_MDSS_HDMI_MHL_SII8334) += mhl_sii8334.o mhl_msc.o
 obj-$(CONFIG_FB_MSM_MDSS_HDMI_PANEL) += mdss_hdmi_hdcp.o
 
 obj-$(CONFIG_FB_MSM_MDSS_WRITEBACK) += mdss_wb.o
diff --git a/drivers/video/msm/mdss/mdss.h b/drivers/video/msm/mdss/mdss.h
index 9e13418..8ceb62e 100644
--- a/drivers/video/msm/mdss/mdss.h
+++ b/drivers/video/msm/mdss/mdss.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -51,14 +51,18 @@
 	int domain_idx;
 };
 
+struct mdss_hw_settings {
+	char __iomem *reg;
+	u32 val;
+};
+
 struct mdss_data_type {
-	u32 rev;
 	u32 mdp_rev;
 	struct clk *mdp_clk[MDSS_MAX_CLK];
 	struct regulator *fs;
 
 	struct workqueue_struct *clk_ctrl_wq;
-	struct delayed_work clk_ctrl_worker;
+	struct work_struct clk_ctrl_worker;
 	struct platform_device *pdev;
 	char __iomem *mdp_base;
 	size_t mdp_reg_size;
@@ -72,22 +76,36 @@
 	u32 mdp_irq_mask;
 	u32 mdp_hist_irq_mask;
 
-	u32 suspend;
-	u32 timeout;
-
+	int suspend_fs_ena;
+	atomic_t clk_ref;
 	u8 clk_ena;
 	u8 fs_ena;
 	u8 vsync_ena;
-	u8 eintf_ena;
 
-	u32 prim_ptype;
 	u32 res_init;
 	u32 bus_hdl;
 
 	u32 smp_mb_cnt;
 	u32 smp_mb_size;
-	u32 *pipe_type_map;
-	u32 *mixer_type_map;
+
+	struct mdss_hw_settings *hw_settings;
+
+	struct mdss_mdp_pipe *vig_pipes;
+	struct mdss_mdp_pipe *rgb_pipes;
+	struct mdss_mdp_pipe *dma_pipes;
+	u32 nvig_pipes;
+	u32 nrgb_pipes;
+	u32 ndma_pipes;
+	struct mdss_mdp_mixer *mixer_intf;
+	struct mdss_mdp_mixer *mixer_wb;
+	u32 nmixers_intf;
+	u32 nmixers_wb;
+	struct mdss_mdp_ctl *ctl_off;
+	u32 nctl;
+	struct mdss_mdp_dp_intf *dp_off;
+	u32 ndp;
+	void *video_intf;
+	u32 nintf;
 
 	struct ion_client *iclient;
 	int iommu_attached;
diff --git a/drivers/video/msm/mdss/mdss_dsi.c b/drivers/video/msm/mdss/mdss_dsi.c
index 980ed46..99eea82 100644
--- a/drivers/video/msm/mdss/mdss_dsi.c
+++ b/drivers/video/msm/mdss/mdss_dsi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -17,6 +17,8 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/gpio.h>
 #include <linux/err.h>
 #include <linux/regulator/consumer.h>
 
@@ -24,47 +26,47 @@
 #include "mdss_panel.h"
 #include "mdss_dsi.h"
 
-static struct mdss_dsi_drv_pdata dsi_drv;
-
 static unsigned char *mdss_dsi_base;
 
-static int mdss_dsi_regulator_init(struct platform_device *pdev)
+static int mdss_dsi_regulator_init(struct platform_device *pdev,
+				   struct dsi_drv_cm_data *dsi_drv)
 {
 	int ret;
-	dsi_drv.vdd_vreg = devm_regulator_get(&pdev->dev, "vdd");
-	if (IS_ERR(dsi_drv.vdd_vreg)) {
+
+	dsi_drv->vdd_vreg = devm_regulator_get(&pdev->dev, "vdd");
+	if (IS_ERR(dsi_drv->vdd_vreg)) {
 		pr_err("could not get 8941_l22, rc = %ld\n",
-				PTR_ERR(dsi_drv.vdd_vreg));
+				PTR_ERR(dsi_drv->vdd_vreg));
 		return -ENODEV;
 	}
 
-	ret = regulator_set_voltage(dsi_drv.vdd_vreg, 3000000, 3000000);
+	ret = regulator_set_voltage(dsi_drv->vdd_vreg, 3000000, 3000000);
 	if (ret) {
 		pr_err("vdd_vreg->set_voltage failed, rc=%d\n", ret);
 		return -EINVAL;
 	}
 
-	dsi_drv.vdd_io_vreg = devm_regulator_get(&pdev->dev, "vdd_io");
-	if (IS_ERR(dsi_drv.vdd_io_vreg)) {
+	dsi_drv->vdd_io_vreg = devm_regulator_get(&pdev->dev, "vdd_io");
+	if (IS_ERR(dsi_drv->vdd_io_vreg)) {
 		pr_err("could not get 8941_l12, rc = %ld\n",
-				PTR_ERR(dsi_drv.vdd_io_vreg));
+				PTR_ERR(dsi_drv->vdd_io_vreg));
 		return -ENODEV;
 	}
 
-	ret = regulator_set_voltage(dsi_drv.vdd_io_vreg, 1800000, 1800000);
+	ret = regulator_set_voltage(dsi_drv->vdd_io_vreg, 1800000, 1800000);
 	if (ret) {
 		pr_err("vdd_io_vreg->set_voltage failed, rc=%d\n", ret);
 		return -EINVAL;
 	}
 
-	dsi_drv.dsi_vreg = devm_regulator_get(&pdev->dev, "vreg");
-	if (IS_ERR(dsi_drv.dsi_vreg)) {
+	dsi_drv->dsi_vreg = devm_regulator_get(&pdev->dev, "vreg");
+	if (IS_ERR(dsi_drv->dsi_vreg)) {
 		pr_err("could not get 8941_l2, rc = %ld\n",
-				PTR_ERR(dsi_drv.dsi_vreg));
+				PTR_ERR(dsi_drv->dsi_vreg));
 		return -ENODEV;
 	}
 
-	ret = regulator_set_voltage(dsi_drv.dsi_vreg, 1200000, 1200000);
+	ret = regulator_set_voltage(dsi_drv->dsi_vreg, 1200000, 1200000);
 	if (ret) {
 		pr_err("dsi_vreg->set_voltage failed, rc=%d\n", ret);
 		return -EINVAL;
@@ -73,34 +75,46 @@
 	return 0;
 }
 
-static int mdss_dsi_panel_power_on(int enable)
+static int mdss_dsi_panel_power_on(struct mdss_panel_data *pdata, int enable)
 {
 	int ret;
+	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
+
+	if (pdata == NULL) {
+		pr_err("%s: Invalid input data\n", __func__);
+		return -EINVAL;
+	}
+
+	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+				panel_data);
 	pr_debug("%s: enable=%d\n", __func__, enable);
 
 	if (enable) {
-		ret = regulator_set_optimum_mode(dsi_drv.vdd_vreg, 100000);
+		ret = regulator_set_optimum_mode
+		  ((ctrl_pdata->shared_pdata).vdd_vreg, 100000);
 		if (ret < 0) {
 			pr_err("%s: vdd_vreg set regulator mode failed.\n",
 						       __func__);
 			return ret;
 		}
 
-		ret = regulator_set_optimum_mode(dsi_drv.vdd_io_vreg, 100000);
+		ret = regulator_set_optimum_mode
+		  ((ctrl_pdata->shared_pdata).vdd_io_vreg, 100000);
 		if (ret < 0) {
 			pr_err("%s: vdd_io_vreg set regulator mode failed.\n",
 						       __func__);
 			return ret;
 		}
 
-		ret = regulator_set_optimum_mode(dsi_drv.dsi_vreg, 100000);
+		ret = regulator_set_optimum_mode
+		  ((ctrl_pdata->shared_pdata).dsi_vreg, 100000);
 		if (ret < 0) {
 			pr_err("%s: dsi_vreg set regulator mode failed.\n",
 						       __func__);
 			return ret;
 		}
 
-		ret = regulator_enable(dsi_drv.vdd_io_vreg);
+		ret = regulator_enable((ctrl_pdata->shared_pdata).vdd_io_vreg);
 		if (ret) {
 			pr_err("%s: Failed to enable regulator.\n", __func__);
 			return ret;
@@ -108,7 +122,7 @@
 		msleep(20);
 		wmb();
 
-		ret = regulator_enable(dsi_drv.vdd_vreg);
+		ret = regulator_enable((ctrl_pdata->shared_pdata).vdd_vreg);
 		if (ret) {
 			pr_err("%s: Failed to enable regulator.\n", __func__);
 			return ret;
@@ -116,50 +130,53 @@
 		msleep(20);
 		wmb();
 
-		ret = regulator_enable(dsi_drv.dsi_vreg);
+		ret = regulator_enable((ctrl_pdata->shared_pdata).dsi_vreg);
 		if (ret) {
 			pr_err("%s: Failed to enable regulator.\n", __func__);
 			return ret;
 		}
-
-		mdss_dsi_panel_reset(1);
+		if (pdata->panel_info.panel_power_on == 0)
+			mdss_dsi_panel_reset(pdata, 1);
 
 	} else {
 
-		mdss_dsi_panel_reset(0);
+		mdss_dsi_panel_reset(pdata, 0);
 
-		ret = regulator_disable(dsi_drv.vdd_vreg);
+		ret = regulator_disable((ctrl_pdata->shared_pdata).vdd_vreg);
 		if (ret) {
 			pr_err("%s: Failed to disable regulator.\n", __func__);
 			return ret;
 		}
 
-		ret = regulator_disable(dsi_drv.dsi_vreg);
+		ret = regulator_disable((ctrl_pdata->shared_pdata).dsi_vreg);
 		if (ret) {
 			pr_err("%s: Failed to disable regulator.\n", __func__);
 			return ret;
 		}
 
-		ret = regulator_disable(dsi_drv.vdd_io_vreg);
+		ret = regulator_disable((ctrl_pdata->shared_pdata).vdd_io_vreg);
 		if (ret) {
 			pr_err("%s: Failed to disable regulator.\n", __func__);
 			return ret;
 		}
 
-		ret = regulator_set_optimum_mode(dsi_drv.vdd_vreg, 100);
+		ret = regulator_set_optimum_mode
+		  ((ctrl_pdata->shared_pdata).vdd_vreg, 100);
 		if (ret < 0) {
 			pr_err("%s: vdd_vreg set regulator mode failed.\n",
 						       __func__);
 			return ret;
 		}
 
-		ret = regulator_set_optimum_mode(dsi_drv.vdd_io_vreg, 100);
+		ret = regulator_set_optimum_mode
+		  ((ctrl_pdata->shared_pdata).vdd_io_vreg, 100);
 		if (ret < 0) {
 			pr_err("%s: vdd_io_vreg set regulator mode failed.\n",
 						       __func__);
 			return ret;
 		}
-		ret = regulator_set_optimum_mode(dsi_drv.dsi_vreg, 100);
+		ret = regulator_set_optimum_mode
+		  ((ctrl_pdata->shared_pdata).dsi_vreg, 100);
 		if (ret < 0) {
 			pr_err("%s: dsi_vreg set regulator mode failed.\n",
 						       __func__);
@@ -175,13 +192,13 @@
 	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
 	int ret = 0;
 
-	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
-				panel_data);
-	if (!ctrl_pdata) {
+	if (pdata == NULL) {
 		pr_err("%s: Invalid input data\n", __func__);
 		return -EINVAL;
 	}
 
+	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+				panel_data);
 	pinfo = &pdata->panel_info;
 
 	mdss_dsi_op_mode_config(DSI_CMD_MODE, pdata);
@@ -198,14 +215,29 @@
 static int mdss_dsi_off(struct mdss_panel_data *pdata)
 {
 	int ret = 0;
+	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
 
+	if (pdata == NULL) {
+		pr_err("%s: Invalid input data\n", __func__);
+		return -EINVAL;
+	}
+
+	if (!pdata->panel_info.panel_power_on) {
+		pr_warn("%s:%d Panel already off.\n", __func__, __LINE__);
+		return -EPERM;
+	}
+
+	pdata->panel_info.panel_power_on = 0;
+
+	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+				panel_data);
 	mdss_dsi_clk_disable(pdata);
-	mdss_dsi_unprepare_clocks();
+	mdss_dsi_unprepare_clocks(ctrl_pdata);
 
 	/* disable DSI controller */
 	mdss_dsi_controller_cfg(0, pdata);
 
-	ret = mdss_dsi_panel_power_on(0);
+	ret = mdss_dsi_panel_power_on(pdata, 0);
 	if (ret) {
 		pr_err("%s: Panel power off failed\n", __func__);
 		return ret;
@@ -216,7 +248,38 @@
 	return ret;
 }
 
-static int mdss_dsi_on(struct mdss_panel_data *pdata)
+int mdss_dsi_cont_splash_on(struct mdss_panel_data *pdata)
+{
+	int ret = 0;
+	struct mipi_panel_info *mipi;
+
+	pr_info("%s:%d DSI on for continuous splash.\n", __func__, __LINE__);
+
+	if (pdata == NULL) {
+		pr_err("%s: Invalid input data\n", __func__);
+		return -EINVAL;
+	}
+
+	mipi  = &pdata->panel_info.mipi;
+
+	ret = mdss_dsi_panel_power_on(pdata, 1);
+	if (ret) {
+		pr_err("%s: Panel power on failed\n", __func__);
+		return ret;
+	}
+	mdss_dsi_sw_reset(pdata);
+	mdss_dsi_host_init(mipi, pdata);
+
+	pdata->panel_info.panel_power_on = 1;
+
+	mdss_dsi_op_mode_config(mipi->mode, pdata);
+
+	pr_debug("%s-:End\n", __func__);
+	return ret;
+}
+
+
+int mdss_dsi_on(struct mdss_panel_data *pdata)
 {
 	int ret = 0;
 	u32 clk_rate;
@@ -227,25 +290,32 @@
 	u32 dummy_xres, dummy_yres;
 	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
 
-	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
-				panel_data);
-	if (!ctrl_pdata) {
+	if (pdata == NULL) {
 		pr_err("%s: Invalid input data\n", __func__);
 		return -EINVAL;
 	}
 
+	if (pdata->panel_info.panel_power_on) {
+		pr_warn("%s:%d Panel already on.\n", __func__, __LINE__);
+		return 0;
+	}
+
+	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+				panel_data);
 	pinfo = &pdata->panel_info;
 
-	ret = mdss_dsi_panel_power_on(1);
+	ret = mdss_dsi_panel_power_on(pdata, 1);
 	if (ret) {
 		pr_err("%s: Panel power on failed\n", __func__);
 		return ret;
 	}
 
+	pdata->panel_info.panel_power_on = 1;
+
 	mdss_dsi_phy_sw_reset((ctrl_pdata->ctrl_base));
 	mdss_dsi_phy_init(pdata);
 
-	mdss_dsi_prepare_clocks();
+	mdss_dsi_prepare_clocks(ctrl_pdata);
 	mdss_dsi_clk_enable(pdata);
 
 	clk_rate = pdata->panel_info.clk_rate;
@@ -323,7 +393,7 @@
 
 	mdss_dsi_op_mode_config(mipi->mode, pdata);
 
-	pr_debug("%s-:\n", __func__);
+	pr_debug("%s-:End\n", __func__);
 	return ret;
 }
 
@@ -331,32 +401,94 @@
 				  int event, void *arg)
 {
 	int rc = 0;
+	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
 
-	pr_debug("%s: event=%d\n", __func__, event);
+	if (pdata == NULL) {
+		pr_err("%s: Invalid input data\n", __func__);
+		return -EINVAL;
+	}
+	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+				panel_data);
 	switch (event) {
 	case MDSS_EVENT_UNBLANK:
-		rc = mdss_dsi_on(pdata);
+		if (ctrl_pdata->on_cmds->ctrl_state == DSI_LP_MODE) {
+			rc = mdss_dsi_on(pdata);
+		} else {
+			pr_debug("%s:event=%d, Dsi On not called: ctrl_state: %d\n",
+				 __func__, event,
+				 ctrl_pdata->on_cmds->ctrl_state);
+			rc = -EINVAL;
+		}
 		break;
 	case MDSS_EVENT_BLANK:
-		rc = mdss_dsi_ctrl_unprepare(pdata);
+		if (ctrl_pdata->off_cmds->ctrl_state == DSI_HS_MODE) {
+			rc = mdss_dsi_ctrl_unprepare(pdata);
+		} else {
+			pr_debug("%s:event=%d,Unprepare not called.Ctrl_state: %d\n",
+				 __func__, event,
+				 ctrl_pdata->on_cmds->ctrl_state);
+			rc = -EINVAL;
+		}
 		break;
 	case MDSS_EVENT_TIMEGEN_OFF:
+		if (ctrl_pdata->off_cmds->ctrl_state == DSI_LP_MODE) {
+			pr_debug("%s:event=%d, calling unprepare: ctrl_state: %d\n",
+				 __func__, event,
+				 ctrl_pdata->on_cmds->ctrl_state);
+			rc = mdss_dsi_ctrl_unprepare(pdata);
+		}
 		rc = mdss_dsi_off(pdata);
 		break;
+	case MDSS_EVENT_CONT_SPLASH_FINISH:
+		if (ctrl_pdata->on_cmds->ctrl_state == DSI_LP_MODE) {
+			rc = mdss_dsi_cont_splash_on(pdata);
+		} else {
+			pr_debug("%s:event=%d, Dsi On not called: ctrl_state: %d\n",
+				 __func__, event,
+				 ctrl_pdata->on_cmds->ctrl_state);
+			rc = -EINVAL;
+		}
+		break;
+	default:
+		pr_debug("%s: unhandled event=%d\n", __func__, event);
+		break;
 	}
 	return rc;
 }
 
-static int mdss_dsi_resource_initialized;
-
-static int __devinit mdss_dsi_probe(struct platform_device *pdev)
+static int __devinit mdss_dsi_ctrl_probe(struct platform_device *pdev)
 {
 	int rc = 0;
+	u32 index;
+
 	pr_debug("%s\n", __func__);
 
-	if (pdev->dev.of_node && !mdss_dsi_resource_initialized) {
+	if (pdev->dev.of_node) {
 		struct resource *mdss_dsi_mres;
-		pdev->id = 1;
+		const char *ctrl_name;
+
+		ctrl_name = of_get_property(pdev->dev.of_node, "label", NULL);
+		if (!ctrl_name)
+			pr_info("%s:%d, DSI Ctrl name not specified\n",
+						__func__, __LINE__);
+		else
+			pr_info("%s: DSI Ctrl name = %s\n",
+				__func__, ctrl_name);
+
+		rc = of_property_read_u32(pdev->dev.of_node,
+					  "cell-index", &index);
+		if (rc) {
+			dev_err(&pdev->dev,
+				"%s: Cell-index not specified, rc=%d\n",
+							__func__, rc);
+			return rc;
+		}
+
+		if (index == 0)
+			pdev->id = 1;
+		else
+			pdev->id = 2;
+
 		mdss_dsi_mres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 		if (!mdss_dsi_mres) {
 			pr_err("%s:%d unable to get the MDSS resources",
@@ -373,20 +505,6 @@
 			}
 		}
 
-		rc = mdss_dsi_regulator_init(pdev);
-		if (rc) {
-			dev_err(&pdev->dev,
-				"%s: failed to init regulator, rc=%d\n",
-							__func__, rc);
-			iounmap(mdss_dsi_base);
-			return rc;
-		}
-
-		if (mdss_dsi_clk_init(pdev)) {
-			iounmap(mdss_dsi_base);
-			return -EPERM;
-		}
-
 		rc = of_platform_populate(pdev->dev.of_node,
 					NULL, NULL, &pdev->dev);
 		if (rc) {
@@ -397,16 +515,13 @@
 			return rc;
 		}
 
-		mdss_dsi_resource_initialized = 1;
+		pr_debug("%s: Dsi Ctrl->%d initialized\n", __func__, index);
 	}
 
-	if (!mdss_dsi_resource_initialized)
-		return -EPERM;
-
 	return 0;
 }
 
-static int __devexit mdss_dsi_remove(struct platform_device *pdev)
+static int __devexit mdss_dsi_ctrl_remove(struct platform_device *pdev)
 {
 	struct msm_fb_data_type *mfd;
 
@@ -417,6 +532,58 @@
 
 struct device dsi_dev;
 
+int mdss_dsi_retrieve_ctrl_resources(struct platform_device *pdev, int mode,
+			    unsigned char **ctrl_base)
+{
+	int rc = 0;
+	u32 index;
+	struct resource *mdss_dsi_mres;
+
+	rc = of_property_read_u32(pdev->dev.of_node, "cell-index", &index);
+	if (rc) {
+		dev_err(&pdev->dev,
+			"%s: Cell-index not specified, rc=%d\n",
+						__func__, rc);
+		return rc;
+	}
+
+	if (index == 0) {
+		if (mode != DISPLAY_1) {
+			pr_err("%s:%d Panel->Ctrl mapping is wrong",
+				       __func__, __LINE__);
+			return -EPERM;
+		}
+	} else if (index == 1) {
+		if (mode != DISPLAY_2) {
+			pr_err("%s:%d Panel->Ctrl mapping is wrong",
+				       __func__, __LINE__);
+			return -EPERM;
+		}
+	} else {
+		pr_err("%s:%d Unknown Ctrl mapped to panel",
+			       __func__, __LINE__);
+		return -EPERM;
+	}
+
+	mdss_dsi_mres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!mdss_dsi_mres) {
+		pr_err("%s:%d unable to get the DSI ctrl resources",
+			       __func__, __LINE__);
+		return -ENOMEM;
+	}
+
+	*ctrl_base = ioremap(mdss_dsi_mres->start,
+		resource_size(mdss_dsi_mres));
+	if (!(*ctrl_base)) {
+		pr_err("%s:%d unable to remap dsi resources",
+			       __func__, __LINE__);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+
 int dsi_panel_device_register(struct platform_device *pdev,
 			      struct mdss_panel_common_pdata *panel_data,
 			      char backlight_ctrl)
@@ -426,6 +593,11 @@
 	u8 lanes = 0, bpp;
 	u32 h_period, v_period, dsi_pclk_rate;
 	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
+	struct device_node *dsi_ctrl_np = NULL;
+	struct platform_device *ctrl_pdev = NULL;
+	unsigned char *ctrl_addr;
+	bool broadcast;
+	bool cont_splash_enabled = false;
 
 	h_period = ((panel_data->panel_info.lcdc.h_pulse_width)
 			+ (panel_data->panel_info.lcdc.h_back_porch)
@@ -496,22 +668,122 @@
 	if (!ctrl_pdata)
 		return -ENOMEM;
 
+	dsi_ctrl_np = of_parse_phandle(pdev->dev.of_node,
+				       "qcom,dsi-ctrl-phandle", 0);
+	if (!dsi_ctrl_np) {
+		pr_err("%s: Dsi controller node not initialized\n", __func__);
+		devm_kfree(&pdev->dev, ctrl_pdata);
+		return -EPROBE_DEFER;
+	}
+
+	ctrl_pdev = of_find_device_by_node(dsi_ctrl_np);
+
+	rc = mdss_dsi_regulator_init(ctrl_pdev, &(ctrl_pdata->shared_pdata));
+	if (rc) {
+		dev_err(&pdev->dev,
+			"%s: failed to init regulator, rc=%d\n",
+						__func__, rc);
+		devm_kfree(&pdev->dev, ctrl_pdata);
+		return rc;
+	}
+
+	broadcast = of_property_read_bool(pdev->dev.of_node,
+					  "qcom,mdss-pan-broadcast-mode");
+	if (broadcast)
+		ctrl_pdata->shared_pdata.broadcast_enable = 1;
+
+	ctrl_pdata->disp_en_gpio = of_get_named_gpio(pdev->dev.of_node,
+						     "qcom,enable-gpio", 0);
+	if (!gpio_is_valid(ctrl_pdata->disp_en_gpio)) {
+		pr_err("%s:%d, Disp_en gpio not specified\n",
+						__func__, __LINE__);
+	} else {
+		rc = gpio_request(ctrl_pdata->disp_en_gpio, "disp_enable");
+		if (rc) {
+			pr_err("request reset gpio failed, rc=%d\n",
+			       rc);
+			gpio_free(ctrl_pdata->disp_en_gpio);
+			return -ENODEV;
+		}
+	}
+
+	ctrl_pdata->rst_gpio = of_get_named_gpio(pdev->dev.of_node,
+						 "qcom,rst-gpio", 0);
+	if (!gpio_is_valid(ctrl_pdata->rst_gpio)) {
+		pr_err("%s:%d, reset gpio not specified\n",
+						__func__, __LINE__);
+	} else {
+		rc = gpio_request(ctrl_pdata->rst_gpio, "disp_rst_n");
+		if (rc) {
+			pr_err("request reset gpio failed, rc=%d\n",
+				rc);
+			gpio_free(ctrl_pdata->rst_gpio);
+			gpio_free(ctrl_pdata->disp_en_gpio);
+			return -ENODEV;
+		}
+	}
+
+	if (mdss_dsi_clk_init(ctrl_pdev, ctrl_pdata)) {
+		pr_err("%s: unable to initialize Dsi ctrl clks\n", __func__);
+		devm_kfree(&pdev->dev, ctrl_pdata);
+		return -EPERM;
+	}
+
+	if (mdss_dsi_retrieve_ctrl_resources(ctrl_pdev,
+					     panel_data->panel_info.pdest,
+					     &ctrl_addr)) {
+		pr_err("%s: unable to get Dsi controller res\n", __func__);
+		devm_kfree(&pdev->dev, ctrl_pdata);
+		return -EPERM;
+	}
+
+	pr_debug("%s: ctrl base address: 0x%x\n", __func__, (int)ctrl_addr);
 	ctrl_pdata->panel_data.event_handler = mdss_dsi_event_handler;
+
+	ctrl_pdata->on_cmds = panel_data->dsi_panel_on_cmds;
+	ctrl_pdata->off_cmds = panel_data->dsi_panel_off_cmds;
+
 	memcpy(&((ctrl_pdata->panel_data).panel_info),
 				&(panel_data->panel_info),
 				       sizeof(struct mdss_panel_info));
 
 	mdss_dsi_irq_handler_config(ctrl_pdata);
 	(ctrl_pdata->panel_data).set_backlight = panel_data->bl_fnc;
-	(ctrl_pdata->ctrl_base) = mdss_dsi_base;
+	(ctrl_pdata->ctrl_base) = ctrl_addr;
 	(ctrl_pdata->bl_ctrl) = backlight_ctrl;
 	/*
 	 * register in mdp driver
 	 */
-	rc = mdss_register_panel(&(ctrl_pdata->panel_data));
+
+	cont_splash_enabled = of_property_read_bool(pdev->dev.of_node,
+			"qcom,cont-splash-enabled");
+	if (!cont_splash_enabled) {
+		pr_info("%s:%d Continous splash flag not found.\n",
+				__func__, __LINE__);
+		ctrl_pdata->panel_data.panel_info.cont_splash_enabled = 0;
+		ctrl_pdata->panel_data.panel_info.panel_power_on = 0;
+	} else {
+		pr_info("%s:%d Continous splash flag enabled.\n",
+				__func__, __LINE__);
+
+		ctrl_pdata->panel_data.panel_info.cont_splash_enabled = 1;
+		ctrl_pdata->panel_data.panel_info.panel_power_on = 1;
+	}
+
+
+	if (ctrl_pdata->panel_data.panel_info.cont_splash_enabled) {
+		mdss_dsi_prepare_clocks(ctrl_pdata);
+		mdss_dsi_clk_enable(&(ctrl_pdata->panel_data));
+	}
+
+	rc = mdss_register_panel(ctrl_pdev, &(ctrl_pdata->panel_data));
 	if (rc) {
 		dev_err(&pdev->dev, "unable to register MIPI DSI panel\n");
 		devm_kfree(&pdev->dev, ctrl_pdata);
+		if (ctrl_pdata->rst_gpio)
+			gpio_free(ctrl_pdata->rst_gpio);
+		if (ctrl_pdata->disp_en_gpio)
+			gpio_free(ctrl_pdata->disp_en_gpio);
 		return rc;
 	}
 
@@ -522,25 +794,25 @@
 	return 0;
 }
 
-static const struct of_device_id msm_mdss_dsi_dt_match[] = {
-	{.compatible = "qcom,msm-mdss-dsi"},
+static const struct of_device_id mdss_dsi_ctrl_dt_match[] = {
+	{.compatible = "qcom,mdss-dsi-ctrl"},
 	{}
 };
-MODULE_DEVICE_TABLE(of, msm_mdss_dsi_dt_match);
+MODULE_DEVICE_TABLE(of, mdss_dsi_ctrl_dt_match);
 
-static struct platform_driver mdss_dsi_driver = {
-	.probe = mdss_dsi_probe,
-	.remove = __devexit_p(mdss_dsi_remove),
+static struct platform_driver mdss_dsi_ctrl_driver = {
+	.probe = mdss_dsi_ctrl_probe,
+	.remove = __devexit_p(mdss_dsi_ctrl_remove),
 	.shutdown = NULL,
 	.driver = {
-		.name = "mdss_dsi",
-		.of_match_table = msm_mdss_dsi_dt_match,
+		.name = "mdss_dsi_ctrl",
+		.of_match_table = mdss_dsi_ctrl_dt_match,
 	},
 };
 
 static int mdss_dsi_register_driver(void)
 {
-	return platform_driver_register(&mdss_dsi_driver);
+	return platform_driver_register(&mdss_dsi_ctrl_driver);
 }
 
 static int __init mdss_dsi_driver_init(void)
@@ -562,7 +834,7 @@
 static void __exit mdss_dsi_driver_cleanup(void)
 {
 	iounmap(mdss_dsi_base);
-	platform_driver_unregister(&mdss_dsi_driver);
+	platform_driver_unregister(&mdss_dsi_ctrl_driver);
 }
 module_exit(mdss_dsi_driver_cleanup);
 
diff --git a/drivers/video/msm/mdss/mdss_dsi.h b/drivers/video/msm/mdss/mdss_dsi.h
index e6fd910..06c2952 100644
--- a/drivers/video/msm/mdss/mdss_dsi.h
+++ b/drivers/video/msm/mdss/mdss_dsi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -83,6 +83,11 @@
 	UNKNOWN_CTRL,
 };
 
+enum dsi_ctrl_state {
+	DSI_LP_MODE,
+	DSI_HS_MODE,
+};
+
 #define DSI_NON_BURST_SYNCH_PULSE	0
 #define DSI_NON_BURST_SYNCH_EVENT	1
 #define DSI_BURST_MODE			2
@@ -244,17 +249,26 @@
 	void *data;
 };
 
+struct dsi_panel_cmds_list {
+	struct dsi_cmd_desc *buf;
+	char size;
+	char ctrl_state;
+};
+
 struct mdss_panel_common_pdata {
 	struct mdss_panel_info panel_info;
 	int (*on) (struct mdss_panel_data *pdata);
 	int (*off) (struct mdss_panel_data *pdata);
 	void (*bl_fnc) (struct mdss_panel_data *pdata, u32 bl_level);
+	struct dsi_panel_cmds_list *dsi_panel_on_cmds;
+	struct dsi_panel_cmds_list *dsi_panel_off_cmds;
 };
 
-struct mdss_dsi_drv_pdata {
+struct dsi_drv_cm_data {
 	struct regulator *vdd_vreg;
 	struct regulator *vdd_io_vreg;
 	struct regulator *dsi_vreg;
+	int broadcast_enable;
 };
 
 struct mdss_dsi_ctrl_pdata {
@@ -263,6 +277,15 @@
 	struct mdss_panel_data panel_data;
 	unsigned char *ctrl_base;
 	char bl_ctrl;
+	struct clk *byte_clk;
+	struct clk *esc_clk;
+	struct clk *pixel_clk;
+	int mdss_dsi_clk_on;
+	int rst_gpio;
+	int disp_en_gpio;
+	struct dsi_panel_cmds_list *on_cmds;
+	struct dsi_panel_cmds_list *off_cmds;
+	struct dsi_drv_cm_data shared_pdata;
 };
 
 int dsi_panel_device_register(struct platform_device *pdev,
@@ -292,7 +315,7 @@
 				struct mdss_panel_data *pdata);
 void mdss_dsi_cmd_mode_ctrl(int enable);
 void mdp4_dsi_cmd_trigger(void);
-void mdss_dsi_cmd_mdp_start(void);
+void mdss_dsi_cmd_mdp_start(struct mdss_panel_data *pdata);
 void mdss_dsi_cmd_bta_sw_trigger(struct mdss_panel_data *pdata);
 void mdss_dsi_ack_err_status(unsigned char *dsi_base);
 void mdss_dsi_clk_enable(struct mdss_panel_data *pdata);
@@ -307,11 +330,12 @@
 void mipi_set_tx_power_mode(int mode, struct mdss_panel_data *pdata);
 int mdss_dsi_clk_div_config(u8 bpp, u8 lanes,
 			    u32 *expected_dsi_pclk);
-int mdss_dsi_clk_init(struct platform_device *pdev);
-void mdss_dsi_clk_deinit(struct device *dev);
-void mdss_dsi_prepare_clocks(void);
-void mdss_dsi_unprepare_clocks(void);
-void mdss_dsi_panel_reset(int enable);
+int mdss_dsi_clk_init(struct platform_device *pdev,
+		      struct mdss_dsi_ctrl_pdata *ctrl_pdata);
+void mdss_dsi_clk_deinit(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
+void mdss_dsi_prepare_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
+void mdss_dsi_unprepare_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
+void mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable);
 void mdss_dsi_phy_enable(unsigned char *ctrl_base, int on);
 void mdss_dsi_phy_init(struct mdss_panel_data *pdata);
 void mdss_dsi_phy_sw_reset(unsigned char *ctrl_base);
diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c
index 8c3b1a8..6f7023c 100644
--- a/drivers/video/msm/mdss/mdss_dsi_host.c
+++ b/drivers/video/msm/mdss/mdss_dsi_host.c
@@ -1,5 +1,4 @@
-
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -31,13 +30,20 @@
 static spinlock_t dsi_irq_lock;
 static spinlock_t dsi_mdp_lock;
 static int dsi_mdp_busy;
+static struct mdss_dsi_ctrl_pdata *left_ctrl_pdata;
 
-struct mdss_hw mdss_dsi_hw = {
+struct mdss_hw mdss_dsi0_hw = {
 	.hw_ndx = MDSS_HW_DSI0,
 	.ptr = NULL,
 	.irq_handler = mdss_dsi_isr,
 };
 
+struct mdss_hw mdss_dsi1_hw = {
+	.hw_ndx = MDSS_HW_DSI1,
+	.ptr = NULL,
+	.irq_handler = mdss_dsi_isr,
+};
+
 void mdss_dsi_init(void)
 {
 	init_completion(&dsi_dma_comp);
@@ -47,12 +53,24 @@
 
 void mdss_dsi_irq_handler_config(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
 {
-	mdss_dsi_hw.ptr = (void *)(ctrl_pdata);
+	if (ctrl_pdata->panel_data.panel_info.pdest == DISPLAY_1)
+		mdss_dsi0_hw.ptr = (void *)(ctrl_pdata);
+	else
+		mdss_dsi1_hw.ptr = (void *)(ctrl_pdata);
 }
 
-void mdss_dsi_enable_irq(void)
+void mdss_dsi_enable_irq(struct mdss_panel_data *pdata)
 {
 	unsigned long flags;
+	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
+
+	if (pdata == NULL) {
+		pr_err("%s: Invalid input data\n", __func__);
+		return;
+	}
+
+	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+				panel_data);
 
 	spin_lock_irqsave(&dsi_irq_lock, flags);
 	if (dsi_irq_enabled) {
@@ -61,15 +79,28 @@
 		return;
 	}
 
-	mdss_enable_irq(&mdss_dsi_hw);
+	if ((ctrl_pdata->panel_data).panel_info.pdest == DISPLAY_1)
+		mdss_enable_irq(&mdss_dsi0_hw);
+	else
+		mdss_enable_irq(&mdss_dsi1_hw);
+
 	dsi_irq_enabled = 1;
 	/* TO DO: Check whether MDSS IRQ is enabled */
 	spin_unlock_irqrestore(&dsi_irq_lock, flags);
 }
 
-void mdss_dsi_disable_irq(void)
+void mdss_dsi_disable_irq(struct mdss_panel_data *pdata)
 {
 	unsigned long flags;
+	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
+
+	if (pdata == NULL) {
+		pr_err("%s: Invalid input data\n", __func__);
+		return;
+	}
+
+	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+				panel_data);
 
 	spin_lock_irqsave(&dsi_irq_lock, flags);
 	if (dsi_irq_enabled == 0) {
@@ -77,7 +108,11 @@
 		spin_unlock_irqrestore(&dsi_irq_lock, flags);
 		return;
 	}
-	mdss_disable_irq(&mdss_dsi_hw);
+	if (ctrl_pdata->panel_data.panel_info.pdest == DISPLAY_1)
+		mdss_disable_irq(&mdss_dsi0_hw);
+	else
+		mdss_disable_irq(&mdss_dsi1_hw);
+
 	dsi_irq_enabled = 0;
 	/* TO DO: Check whether MDSS IRQ is Disabled */
 	spin_unlock_irqrestore(&dsi_irq_lock, flags);
@@ -661,13 +696,14 @@
 	u32 data;
 	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
 
-	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
-				panel_data);
-	if (!ctrl_pdata) {
+	if (pdata == NULL) {
 		pr_err("%s: Invalid input data\n", __func__);
 		return;
 	}
 
+	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+				panel_data);
+
 	pinfo->rgb_swap = DSI_RGB_SWAP_RGB;
 
 	if (pinfo->mode == DSI_VIDEO_MODE) {
@@ -740,7 +776,17 @@
 
 	/* from frame buffer, low power mode */
 	/* DSI_COMMAND_MODE_DMA_CTRL */
-	MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x3C, 0x14000000);
+	if (ctrl_pdata->shared_pdata.broadcast_enable)
+		MIPI_OUTP(ctrl_pdata->ctrl_base + 0x3C, 0x94000000);
+	else
+		MIPI_OUTP(ctrl_pdata->ctrl_base + 0x3C, 0x14000000);
+
+	if (ctrl_pdata->shared_pdata.broadcast_enable)
+		if (pdata->panel_info.pdest == DISPLAY_1) {
+			pr_debug("%s: Broadcast mode enabled.\n",
+				 __func__);
+			left_ctrl_pdata = ctrl_pdata;
+		}
 
 	data = 0;
 	if (pinfo->te_sel)
@@ -793,13 +839,14 @@
 	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
 	u32 data;
 
-	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
-				panel_data);
-	if (!ctrl_pdata) {
+	if (pdata == NULL) {
 		pr_err("%s: Invalid input data\n", __func__);
 		return;
 	}
 
+	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+				panel_data);
+
 	data = MIPI_INP((ctrl_pdata->ctrl_base) + 0x3c);
 
 	if (mode == 0)
@@ -815,13 +862,13 @@
 	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
 	u32 dsi_ctrl;
 
-	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
-				panel_data);
-	if (!ctrl_pdata) {
+	if (pdata == NULL) {
 		pr_err("%s: Invalid input data\n", __func__);
 		return;
 	}
 
+	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+				panel_data);
 	dsi_ctrl = MIPI_INP((ctrl_pdata->ctrl_base) + 0x0004);
 	dsi_ctrl &= ~0x01;
 	MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0004, dsi_ctrl);
@@ -848,13 +895,14 @@
 	u32 timeout_us = 16000;
 	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
 
-	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
-				panel_data);
-	if (!ctrl_pdata) {
+	if (pdata == NULL) {
 		pr_err("%s: Invalid input data\n", __func__);
 		return;
 	}
 
+	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+				panel_data);
+
 	/* Check for CMD_MODE_DMA_BUSY */
 	if (readl_poll_timeout(((ctrl_pdata->ctrl_base) + 0x0008),
 			   status,
@@ -895,13 +943,21 @@
 	u32 dsi_ctrl, intr_ctrl;
 	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
 
-	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
-				panel_data);
-	if (!ctrl_pdata) {
+	if (pdata == NULL) {
 		pr_err("%s: Invalid input data\n", __func__);
 		return;
 	}
 
+	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+				panel_data);
+
+	if (ctrl_pdata->shared_pdata.broadcast_enable)
+		if (pdata->panel_info.pdest == DISPLAY_1) {
+			pr_debug("%s: Broadcast mode. 1st ctrl\n",
+				 __func__);
+			return;
+		}
+
 	dsi_ctrl = MIPI_INP((ctrl_pdata->ctrl_base) + 0x0004);
 	/*If Video enabled, Keep Video and Cmd mode ON */
 	if (dsi_ctrl & 0x02)
@@ -923,18 +979,27 @@
 
 	pr_debug("%s: dsi_ctrl=%x intr=%x\n", __func__, dsi_ctrl, intr_ctrl);
 
+	if (ctrl_pdata->shared_pdata.broadcast_enable)
+		if ((pdata->panel_info.pdest == DISPLAY_2)
+		  && (left_ctrl_pdata != NULL)) {
+			MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x0110,
+				  intr_ctrl); /* DSI_INTL_CTRL */
+			MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x0004,
+					dsi_ctrl);
+		}
+
 	MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0110,
 				intr_ctrl); /* DSI_INTL_CTRL */
 	MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0004, dsi_ctrl);
 	wmb();
 }
 
-void mdss_dsi_cmd_mdp_start(void)
+void mdss_dsi_cmd_mdp_start(struct mdss_panel_data *pdata)
 {
 	unsigned long flag;
 
 	spin_lock_irqsave(&dsi_mdp_lock, flag);
-	mdss_dsi_enable_irq();
+	mdss_dsi_enable_irq(pdata);
 	dsi_mdp_busy = true;
 	spin_unlock_irqrestore(&dsi_mdp_lock, flag);
 }
@@ -946,13 +1011,14 @@
 	int timeout_us = 10000;
 	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
 
-	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
-				panel_data);
-	if (!ctrl_pdata) {
+	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) + 0x098, 0x01);	/* trigger */
 	wmb();
 
@@ -1008,18 +1074,40 @@
 	unsigned long flag;
 	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
 
-	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
-				panel_data);
-	if (!ctrl_pdata) {
+	if (pdata == NULL) {
 		pr_err("%s: Invalid input data\n", __func__);
 		return -EINVAL;
 	}
 
+	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+				panel_data);
+
+	if (ctrl_pdata->shared_pdata.broadcast_enable)
+		if (pdata->panel_info.pdest == DISPLAY_1) {
+			pr_debug("%s: Broadcast mode. 1st ctrl\n",
+				 __func__);
+			return 0;
+		}
+
 	/* turn on cmd mode
 	* for video mode, do not send cmds more than
 	* one pixel line, since it only transmit it
 	* during BLLP.
 	*/
+
+	if (ctrl_pdata->shared_pdata.broadcast_enable)
+		if ((pdata->panel_info.pdest == DISPLAY_2)
+		  && (left_ctrl_pdata != NULL)) {
+			dsi_ctrl = MIPI_INP(left_ctrl_pdata->ctrl_base
+								+ 0x0004);
+			video_mode = dsi_ctrl & 0x02; /* VIDEO_MODE_EN */
+			if (video_mode) {
+				ctrl = dsi_ctrl | 0x04; /* CMD_MODE_EN */
+				MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x0004,
+						ctrl);
+			}
+		}
+
 	dsi_ctrl = MIPI_INP((ctrl_pdata->ctrl_base) + 0x0004);
 	video_mode = dsi_ctrl & 0x02; /* VIDEO_MODE_EN */
 	if (video_mode) {
@@ -1028,7 +1116,8 @@
 	}
 
 	spin_lock_irqsave(&dsi_mdp_lock, flag);
-	mdss_dsi_enable_irq();
+	mdss_dsi_enable_irq(pdata);
+
 	dsi_mdp_busy = true;
 	spin_unlock_irqrestore(&dsi_mdp_lock, flag);
 
@@ -1045,7 +1134,7 @@
 
 	spin_lock_irqsave(&dsi_mdp_lock, flag);
 	dsi_mdp_busy = false;
-	mdss_dsi_disable_irq();
+	mdss_dsi_disable_irq(pdata);
 	spin_unlock_irqrestore(&dsi_mdp_lock, flag);
 
 	if (video_mode)
@@ -1083,13 +1172,14 @@
 	char cmd;
 	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
 
-	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
-				panel_data);
-	if (!ctrl_pdata) {
+	if (pdata == NULL) {
 		pr_err("%s: Invalid input data\n", __func__);
 		return -EINVAL;
 	}
 
+	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+				panel_data);
+
 	if (pdata->panel_info.mipi.no_max_pkt_size)
 		rlen = ALIGN(rlen, 4); /* Only support rlen = 4*n */
 
@@ -1116,7 +1206,7 @@
 	}
 
 	spin_lock_irqsave(&dsi_mdp_lock, flag);
-	mdss_dsi_enable_irq();
+	mdss_dsi_enable_irq(pdata);
 	dsi_mdp_busy = true;
 	spin_unlock_irqrestore(&dsi_mdp_lock, flag);
 
@@ -1153,7 +1243,7 @@
 
 	spin_lock_irqsave(&dsi_mdp_lock, flag);
 	dsi_mdp_busy = false;
-	mdss_dsi_disable_irq();
+	mdss_dsi_disable_irq(pdata);
 	spin_unlock_irqrestore(&dsi_mdp_lock, flag);
 
 	if (pdata->panel_info.mipi.no_max_pkt_size) {
@@ -1204,13 +1294,13 @@
 	unsigned long size, addr;
 	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
 
-	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
-				panel_data);
-	if (!ctrl_pdata) {
+	if (pdata == NULL) {
 		pr_err("%s: Invalid input data\n", __func__);
 		return -EINVAL;
 	}
 
+	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+				panel_data);
 	bp = tp->data;
 
 	pr_debug("%s: ", __func__);
@@ -1242,10 +1332,23 @@
 
 	INIT_COMPLETION(dsi_dma_comp);
 
+	if (ctrl_pdata->shared_pdata.broadcast_enable)
+		if ((pdata->panel_info.pdest == DISPLAY_2)
+		  && (left_ctrl_pdata != NULL)) {
+			MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x048, addr);
+			MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x04c, len);
+		}
+
 	MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x048, addr);
 	MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x04c, len);
 	wmb();
 
+	if (ctrl_pdata->shared_pdata.broadcast_enable)
+		if ((pdata->panel_info.pdest == DISPLAY_2)
+		  && (left_ctrl_pdata != NULL)) {
+			MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x090, 0x01);
+		}
+
 	MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x090, 0x01);	/* trigger */
 	wmb();
 
@@ -1267,13 +1370,13 @@
 	int i, off, cnt;
 	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
 
-	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
-				panel_data);
-	if (!ctrl_pdata) {
+	if (pdata == NULL) {
 		pr_err("%s: Invalid input data\n", __func__);
 		return -EINVAL;
 	}
 
+	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+				panel_data);
 	lp = (u32 *)rp->data;
 	cnt = rlen;
 	cnt += 3;
@@ -1383,6 +1486,15 @@
 	isr = MIPI_INP(dsi_base + 0x0110);/* DSI_INTR_CTRL */
 	MIPI_OUTP(dsi_base + 0x0110, isr);
 
+	if (ctrl_pdata->shared_pdata.broadcast_enable)
+		if ((ctrl_pdata->panel_data.panel_info.pdest == DISPLAY_2)
+		    && (left_ctrl_pdata != NULL)) {
+			u32 isr0;
+			isr0 = MIPI_INP(left_ctrl_pdata->ctrl_base
+						+ 0x0110);/* DSI_INTR_CTRL */
+			MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x0110, isr0);
+		}
+
 	if (isr & DSI_INTR_ERROR)
 		mdss_dsi_error(dsi_base);
 
diff --git a/drivers/video/msm/mdss/mdss_dsi_panel.c b/drivers/video/msm/mdss/mdss_dsi_panel.c
index fd52e1c..4c30d18 100644
--- a/drivers/video/msm/mdss/mdss_dsi_panel.c
+++ b/drivers/video/msm/mdss/mdss_dsi_panel.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -13,9 +13,8 @@
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/of.h>
-#include <linux/of_gpio.h>
-#include <linux/gpio.h>
 #include <linux/qpnp/pin.h>
+#include <linux/gpio.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/leds.h>
@@ -27,46 +26,51 @@
 static struct dsi_buf dsi_panel_tx_buf;
 static struct dsi_buf dsi_panel_rx_buf;
 
-static struct dsi_cmd_desc *dsi_panel_on_cmds;
-static struct dsi_cmd_desc *dsi_panel_off_cmds;
-static int num_of_on_cmds;
-static int num_of_off_cmds;
-static char *on_cmds, *off_cmds;
-
 DEFINE_LED_TRIGGER(bl_led_trigger);
 
 static struct mdss_dsi_phy_ctrl phy_params;
 
-static int rst_gpio;
-static int disp_en;
-
-void mdss_dsi_panel_reset(int enable)
+void mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable)
 {
-	if (!disp_en)
-		pr_debug("%s:%d, reset line not configured\n",
-			   __func__, __LINE__);
+	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
 
-	if (!rst_gpio)
+	if (pdata == NULL) {
+		pr_err("%s: Invalid input data\n", __func__);
+		return;
+	}
+
+	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+				panel_data);
+
+	if (!gpio_is_valid(ctrl_pdata->disp_en_gpio)) {
 		pr_debug("%s:%d, reset line not configured\n",
 			   __func__, __LINE__);
+		return;
+	}
+
+	if (!gpio_is_valid(ctrl_pdata->rst_gpio)) {
+		pr_debug("%s:%d, reset line not configured\n",
+			   __func__, __LINE__);
+		return;
+	}
 
 	pr_debug("%s: enable = %d\n", __func__, enable);
 
 	if (enable) {
-		gpio_set_value(rst_gpio, 1);
+		gpio_set_value((ctrl_pdata->rst_gpio), 1);
 		msleep(20);
 		wmb();
-		gpio_set_value(rst_gpio, 0);
+		gpio_set_value((ctrl_pdata->rst_gpio), 0);
 		udelay(200);
 		wmb();
-		gpio_set_value(rst_gpio, 1);
+		gpio_set_value((ctrl_pdata->rst_gpio), 1);
 		msleep(20);
 		wmb();
-		gpio_set_value(disp_en, 1);
+		gpio_set_value((ctrl_pdata->disp_en_gpio), 1);
 		wmb();
 	} else {
-		gpio_set_value(rst_gpio, 0);
-		gpio_set_value(disp_en, 0);
+		gpio_set_value((ctrl_pdata->rst_gpio), 0);
+		gpio_set_value((ctrl_pdata->disp_en_gpio), 0);
 	}
 }
 
@@ -75,13 +79,14 @@
 {
 	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
 
-	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
-				panel_data);
-	if (!ctrl_pdata) {
+	if (pdata == NULL) {
 		pr_err("%s: Invalid input data\n", __func__);
 		return;
 	}
 
+	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+				panel_data);
+
 	if (ctrl_pdata->bl_ctrl) {
 		switch (ctrl_pdata->bl_ctrl) {
 		case BL_WLED:
@@ -100,15 +105,24 @@
 static int mdss_dsi_panel_on(struct mdss_panel_data *pdata)
 {
 	struct mipi_panel_info *mipi;
+	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
 
+	if (pdata == NULL) {
+		pr_err("%s: Invalid input data\n", __func__);
+		return -EINVAL;
+	}
+
+	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+				panel_data);
 	mipi  = &pdata->panel_info.mipi;
 
 	pr_debug("%s:%d, debug info (mode) : %d\n", __func__, __LINE__,
 		 mipi->mode);
 
 	if (mipi->mode == DSI_VIDEO_MODE) {
-		mdss_dsi_cmds_tx(pdata, &dsi_panel_tx_buf, dsi_panel_on_cmds,
-			num_of_on_cmds);
+		mdss_dsi_cmds_tx(pdata, &dsi_panel_tx_buf,
+				 ctrl_pdata->on_cmds->buf,
+				 ctrl_pdata->on_cmds->size);
 	} else {
 		pr_err("%s:%d, CMD MODE NOT SUPPORTED", __func__, __LINE__);
 		return -EINVAL;
@@ -120,14 +134,23 @@
 static int mdss_dsi_panel_off(struct mdss_panel_data *pdata)
 {
 	struct mipi_panel_info *mipi;
+	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
 
+	if (pdata == NULL) {
+		pr_err("%s: Invalid input data\n", __func__);
+		return -EINVAL;
+	}
+
+	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+				panel_data);
 	mipi  = &pdata->panel_info.mipi;
 
 	pr_debug("%s:%d, debug info\n", __func__, __LINE__);
 
 	if (mipi->mode == DSI_VIDEO_MODE) {
-		mdss_dsi_cmds_tx(pdata, &dsi_panel_tx_buf, dsi_panel_off_cmds,
-			num_of_off_cmds);
+		mdss_dsi_cmds_tx(pdata, &dsi_panel_tx_buf,
+				 ctrl_pdata->off_cmds->buf,
+				 ctrl_pdata->off_cmds->size);
 	} else {
 		pr_debug("%s:%d, CMD mode not supported", __func__, __LINE__);
 		return -EINVAL;
@@ -145,7 +168,10 @@
 	int rc, i, len;
 	int cmd_plen, data_offset;
 	const char *data;
-	static const char *bl_ctrl_type;
+	static const char *bl_ctrl_type, *pdest;
+	static const char *on_cmds_state, *off_cmds_state;
+	char *on_cmds = NULL, *off_cmds = NULL;
+	int num_of_on_cmds = 0, num_of_off_cmds = 0;
 
 	rc = of_property_read_u32_array(np, "qcom,mdss-pan-res", res, 2);
 	if (rc) {
@@ -164,43 +190,6 @@
 			panel_data->panel_info.yres - res[1];
 	}
 
-	disp_en = of_get_named_gpio(np, "qcom,enable-gpio", 0);
-	if (!gpio_is_valid(disp_en)) {
-		pr_err("%s:%d, Disp_en gpio not specified\n",
-						__func__, __LINE__);
-		return -ENODEV;
-	}
-
-	rc = gpio_request(disp_en, "disp_enable");
-	if (rc) {
-		pr_err("request reset gpio failed, rc=%d\n",
-			rc);
-		gpio_free(disp_en);
-		return -ENODEV;
-	}
-	rc = gpio_direction_output(disp_en, 1);
-	if (rc) {
-		pr_err("set_direction for disp_en gpio failed, rc=%d\n",
-			rc);
-		gpio_free(disp_en);
-		return -ENODEV;
-	}
-
-	rst_gpio = of_get_named_gpio(np, "qcom,rst-gpio", 0);
-	if (!gpio_is_valid(rst_gpio)) {
-		pr_err("%s:%d, reset gpio not specified\n",
-						__func__, __LINE__);
-	} else {
-		rc = gpio_request(rst_gpio, "disp_rst_n");
-		if (rc) {
-			pr_err("request reset gpio failed, rc=%d\n",
-				rc);
-			gpio_free(rst_gpio);
-			gpio_free(disp_en);
-			return -ENODEV;
-		}
-	}
-
 	rc = of_property_read_u32(np, "qcom,mdss-pan-bpp", &tmp);
 	if (rc) {
 		pr_err("%s:%d, panel bpp not specified\n",
@@ -209,6 +198,22 @@
 	}
 	panel_data->panel_info.bpp = (!rc ? tmp : 24);
 
+	pdest = of_get_property(pdev->dev.of_node,
+				"qcom,mdss-pan-dest", NULL);
+	if (strlen(pdest) != 9) {
+		pr_err("%s: Unknown pdest specified\n", __func__);
+		return -EINVAL;
+	}
+	if (!strncmp(pdest, "display_1", 9))
+		panel_data->panel_info.pdest = DISPLAY_1;
+	else if (!strncmp(pdest, "display_2", 9))
+		panel_data->panel_info.pdest = DISPLAY_2;
+	else {
+		pr_debug("%s: pdest not specified. Set Default\n",
+							__func__);
+		panel_data->panel_info.pdest = DISPLAY_1;
+	}
+
 	rc = of_property_read_u32_array(np,
 		"qcom,mdss-pan-porch-values", res, 6);
 	panel_data->panel_info.lcdc.h_back_porch = (!rc ? res[0] : 6);
@@ -224,7 +229,7 @@
 
 	bl_ctrl_type = of_get_property(pdev->dev.of_node,
 				  "qcom,mdss-pan-bl-ctrl", NULL);
-	if (!strncmp(bl_ctrl_type, "bl_ctrl_wled", 12)) {
+	if ((bl_ctrl_type) && (!strncmp(bl_ctrl_type, "bl_ctrl_wled", 12))) {
 		led_trigger_register_simple("bkl-trigger", &bl_led_trigger);
 		pr_debug("%s: SUCCESS-> WLED TRIGGER register\n", __func__);
 		*bl_ctrl = BL_WLED;
@@ -278,6 +283,9 @@
 	panel_data->panel_info.mipi.data_lane2 = (!rc ? res[2] : false);
 	panel_data->panel_info.mipi.data_lane3 = (!rc ? res[3] : false);
 
+	rc = of_property_read_u32(np, "qcom,mdss-pan-dsi-dlane-swap", &tmp);
+	panel_data->panel_info.mipi.dlane_swap = (!rc ? tmp : 0);
+
 	rc = of_property_read_u32_array(np, "qcom,mdss-pan-dsi-t-clk", res, 2);
 	panel_data->panel_info.mipi.t_clk_pre = (!rc ? res[0] : 0x24);
 	panel_data->panel_info.mipi.t_clk_post = (!rc ? res[1] : 0x03);
@@ -380,22 +388,34 @@
 		goto error;
 	}
 
-	dsi_panel_on_cmds =
+	panel_data->dsi_panel_on_cmds =
+		kzalloc(sizeof(struct dsi_panel_cmds_list), GFP_KERNEL);
+	if (!panel_data->dsi_panel_on_cmds)
+		return -ENOMEM;
+
+	(panel_data->dsi_panel_on_cmds)->buf =
 		kzalloc((num_of_on_cmds * sizeof(struct dsi_cmd_desc)),
 						GFP_KERNEL);
-	if (!dsi_panel_on_cmds)
+	if (!(panel_data->dsi_panel_on_cmds)->buf)
 		return -ENOMEM;
 
 	data_offset = 0;
 	for (i = 0; i < num_of_on_cmds; i++) {
-		dsi_panel_on_cmds[i].dtype = on_cmds[data_offset++];
-		dsi_panel_on_cmds[i].last = on_cmds[data_offset++];
-		dsi_panel_on_cmds[i].vc = on_cmds[data_offset++];
-		dsi_panel_on_cmds[i].ack = on_cmds[data_offset++];
-		dsi_panel_on_cmds[i].wait = on_cmds[data_offset++];
-		dsi_panel_on_cmds[i].dlen = on_cmds[data_offset++];
-		dsi_panel_on_cmds[i].payload = &on_cmds[data_offset];
-		data_offset += (dsi_panel_on_cmds[i].dlen);
+		panel_data->dsi_panel_on_cmds->buf[i].dtype =
+						on_cmds[data_offset++];
+		panel_data->dsi_panel_on_cmds->buf[i].last =
+						on_cmds[data_offset++];
+		panel_data->dsi_panel_on_cmds->buf[i].vc =
+						on_cmds[data_offset++];
+		panel_data->dsi_panel_on_cmds->buf[i].ack =
+						on_cmds[data_offset++];
+		panel_data->dsi_panel_on_cmds->buf[i].wait =
+						on_cmds[data_offset++];
+		panel_data->dsi_panel_on_cmds->buf[i].dlen =
+						on_cmds[data_offset++];
+		panel_data->dsi_panel_on_cmds->buf[i].payload =
+						&on_cmds[data_offset];
+		data_offset += (panel_data->dsi_panel_on_cmds->buf[i].dlen);
 	}
 
 	if (data_offset != len) {
@@ -404,6 +424,23 @@
 		goto error;
 	}
 
+	(panel_data->dsi_panel_on_cmds)->size = num_of_on_cmds;
+
+	on_cmds_state = of_get_property(pdev->dev.of_node,
+				"qcom,on-cmds-dsi-state", NULL);
+	if (!strncmp(on_cmds_state, "DSI_LP_MODE", 11)) {
+		(panel_data->dsi_panel_on_cmds)->ctrl_state =
+						DSI_LP_MODE;
+	} else if (!strncmp(on_cmds_state, "DSI_HS_MODE", 11)) {
+		(panel_data->dsi_panel_on_cmds)->ctrl_state =
+						DSI_HS_MODE;
+	} else {
+		pr_debug("%s: ON cmds state not specified. Set Default\n",
+							__func__);
+		(panel_data->dsi_panel_on_cmds)->ctrl_state =
+						DSI_LP_MODE;
+	}
+
 	data = of_get_property(np, "qcom,panel-off-cmds", &len);
 	if (!data) {
 		pr_err("%s:%d, Unable to read OFF cmds", __func__, __LINE__);
@@ -429,22 +466,34 @@
 		goto error;
 	}
 
-	dsi_panel_off_cmds = kzalloc(num_of_off_cmds
+	panel_data->dsi_panel_off_cmds =
+		kzalloc(sizeof(struct dsi_panel_cmds_list), GFP_KERNEL);
+	if (!panel_data->dsi_panel_off_cmds)
+		return -ENOMEM;
+
+	(panel_data->dsi_panel_off_cmds)->buf = kzalloc(num_of_off_cmds
 				* sizeof(struct dsi_cmd_desc),
 					GFP_KERNEL);
-	if (!dsi_panel_off_cmds)
+	if (!(panel_data->dsi_panel_off_cmds)->buf)
 		return -ENOMEM;
 
 	data_offset = 0;
 	for (i = 0; i < num_of_off_cmds; i++) {
-		dsi_panel_off_cmds[i].dtype = off_cmds[data_offset++];
-		dsi_panel_off_cmds[i].last = off_cmds[data_offset++];
-		dsi_panel_off_cmds[i].vc = off_cmds[data_offset++];
-		dsi_panel_off_cmds[i].ack = off_cmds[data_offset++];
-		dsi_panel_off_cmds[i].wait = off_cmds[data_offset++];
-		dsi_panel_off_cmds[i].dlen = off_cmds[data_offset++];
-		dsi_panel_off_cmds[i].payload = &off_cmds[data_offset];
-		data_offset += (dsi_panel_off_cmds[i].dlen);
+		panel_data->dsi_panel_off_cmds->buf[i].dtype =
+						off_cmds[data_offset++];
+		panel_data->dsi_panel_off_cmds->buf[i].last =
+						off_cmds[data_offset++];
+		panel_data->dsi_panel_off_cmds->buf[i].vc =
+						off_cmds[data_offset++];
+		panel_data->dsi_panel_off_cmds->buf[i].ack =
+						off_cmds[data_offset++];
+		panel_data->dsi_panel_off_cmds->buf[i].wait =
+						off_cmds[data_offset++];
+		panel_data->dsi_panel_off_cmds->buf[i].dlen =
+						off_cmds[data_offset++];
+		panel_data->dsi_panel_off_cmds->buf[i].payload =
+						&off_cmds[data_offset];
+		data_offset += (panel_data->dsi_panel_off_cmds->buf[i].dlen);
 	}
 
 	if (data_offset != len) {
@@ -453,16 +502,31 @@
 		goto error;
 	}
 
+	(panel_data->dsi_panel_off_cmds)->size = num_of_off_cmds;
+
+	off_cmds_state = of_get_property(pdev->dev.of_node,
+				"qcom,off-cmds-dsi-state", NULL);
+	if (!strncmp(off_cmds_state, "DSI_LP_MODE", 11)) {
+		(panel_data->dsi_panel_off_cmds)->ctrl_state =
+						DSI_LP_MODE;
+	} else if (!strncmp(off_cmds_state, "DSI_HS_MODE", 11)) {
+		(panel_data->dsi_panel_off_cmds)->ctrl_state =
+						DSI_HS_MODE;
+	} else {
+		pr_debug("%s: ON cmds state not specified. Set Default\n",
+							__func__);
+		(panel_data->dsi_panel_off_cmds)->ctrl_state =
+						DSI_LP_MODE;
+	}
+
 	return 0;
 error:
-	kfree(dsi_panel_on_cmds);
-	kfree(dsi_panel_off_cmds);
+	kfree((panel_data->dsi_panel_on_cmds)->buf);
+	kfree((panel_data->dsi_panel_off_cmds)->buf);
+	kfree(panel_data->dsi_panel_on_cmds);
+	kfree(panel_data->dsi_panel_off_cmds);
 	kfree(on_cmds);
 	kfree(off_cmds);
-	if (rst_gpio)
-		gpio_free(rst_gpio);
-	if (disp_en)
-		gpio_free(disp_en);
 
 	return -EINVAL;
 }
@@ -474,11 +538,6 @@
 	static const char *panel_name;
 	char bl_ctrl = UNKNOWN_CTRL;
 
-	if (pdev->dev.parent == NULL) {
-		pr_err("%s: parent device missing\n", __func__);
-		return -ENODEV;
-	}
-
 	pr_debug("%s:%d, debug info id=%d", __func__, __LINE__, pdev->id);
 	if (!pdev->dev.of_node)
 		return -ENODEV;
diff --git a/drivers/video/msm/mdss/mdss_edp.c b/drivers/video/msm/mdss/mdss_edp.c
index 227619f..6986117 100644
--- a/drivers/video/msm/mdss/mdss_edp.c
+++ b/drivers/video/msm/mdss/mdss_edp.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
@@ -433,7 +433,7 @@
 	edp_drv->panel_data.event_handler = mdss_edp_event_handler;
 	edp_drv->panel_data.set_backlight = mdss_edp_set_backlight;
 
-	ret = mdss_register_panel(&edp_drv->panel_data);
+	ret = mdss_register_panel(edp_drv->pdev, &edp_drv->panel_data);
 	if (ret) {
 		dev_err(&(edp_drv->pdev->dev), "unable to register eDP\n");
 		return ret;
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index 2e8a654..ea0eb7b 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -2,7 +2,7 @@
  * Core MDSS framebuffer driver.
  *
  * Copyright (C) 2007 Google Incorporated
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -40,6 +40,9 @@
 #include <linux/uaccess.h>
 #include <linux/version.h>
 #include <linux/vmalloc.h>
+#include <linux/sync.h>
+#include <linux/sw_sync.h>
+#include <linux/file.h>
 
 #include <mach/board.h>
 #include <mach/memory.h>
@@ -80,7 +83,12 @@
 static int mdss_fb_ioctl(struct fb_info *info, unsigned int cmd,
 			 unsigned long arg);
 static int mdss_fb_mmap(struct fb_info *info, struct vm_area_struct *vma);
+static void mdss_fb_release_fences(struct msm_fb_data_type *mfd);
 
+static void mdss_fb_commit_wq_handler(struct work_struct *work);
+static void mdss_fb_pan_idle(struct msm_fb_data_type *mfd);
+static int mdss_fb_send_panel_event(struct msm_fb_data_type *mfd,
+					int event, void *arg);
 void mdss_fb_no_update_notify_timer_cb(unsigned long data)
 {
 	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)data;
@@ -225,7 +233,7 @@
 
 	pdata = dev_get_platdata(&pdev->dev);
 	if (!pdata)
-		return -ENODEV;
+		return -EPROBE_DEFER;
 
 	/*
 	 * alloc framebuffer info + par data
@@ -252,6 +260,8 @@
 	mfd->fb_imgType = MDP_RGBA_8888;
 
 	mfd->pdev = pdev;
+	if (pdata->next)
+		mfd->split_display = true;
 
 	mutex_init(&mfd->lock);
 
@@ -277,6 +287,24 @@
 	}
 
 	mdss_fb_create_sysfs(mfd);
+	mdss_fb_send_panel_event(mfd, MDSS_EVENT_FB_REGISTERED, fbi);
+
+	if (mfd->timeline == NULL) {
+		char timeline_name[16];
+		snprintf(timeline_name, sizeof(timeline_name),
+			"mdss_fb_%d", mfd->index);
+		mfd->timeline = sw_sync_timeline_create(timeline_name);
+		if (mfd->timeline == NULL) {
+			pr_err("%s: cannot create time line", __func__);
+			return -ENOMEM;
+		} else {
+			mfd->timeline_value = 0;
+		}
+	}
+
+	rc = mdss_mdp_overlay_init(mfd);
+	if (rc)
+		pr_err("unable to init overlay\n");
 
 	return 0;
 }
@@ -301,11 +329,6 @@
 		pr_err("msm_fb_remove: can't stop the device %d\n",
 			    mfd->index);
 
-	if (mfd->no_update.timer.function)
-		del_timer(&mfd->no_update.timer);
-	complete(&mfd->no_update.comp);
-	complete(&mfd->update.comp);
-
 	/* remove /dev/fb* */
 	unregister_framebuffer(mfd->fbi);
 
@@ -317,8 +340,8 @@
 	return 0;
 }
 
-static inline int mdss_fb_send_panel_event(
-	struct msm_fb_data_type *mfd, int e, void *arg)
+static int mdss_fb_send_panel_event(struct msm_fb_data_type *mfd,
+					int event, void *arg)
 {
 	struct mdss_panel_data *pdata;
 
@@ -328,10 +351,10 @@
 		return -ENODEV;
 	}
 
-	pr_debug("sending event=%d for fb%d\n", e, mfd->index);
+	pr_debug("sending event=%d for fb%d\n", event, mfd->index);
 
 	if (pdata->event_handler)
-		return pdata->event_handler(pdata, e, arg);
+		return pdata->event_handler(pdata, event, arg);
 
 	return 0;
 }
@@ -345,6 +368,7 @@
 
 	pr_debug("mdss_fb suspend index=%d\n", mfd->index);
 
+	mdss_fb_pan_idle(mfd);
 	ret = mdss_fb_send_panel_event(mfd, MDSS_EVENT_SUSPEND, NULL);
 	if (ret) {
 		pr_warn("unable to suspend fb%d (%d)\n", mfd->index, ret);
@@ -362,6 +386,7 @@
 			return ret;
 		}
 		mfd->op_enable = false;
+		fb_set_suspend(mfd->fbi, FBINFO_STATE_SUSPENDED);
 	}
 
 	return 0;
@@ -374,8 +399,11 @@
 	if ((!mfd) || (mfd->key != MFD_KEY))
 		return 0;
 
+	INIT_COMPLETION(mfd->power_set_comp);
+	mfd->is_power_setting = true;
 	pr_debug("mdss_fb resume index=%d\n", mfd->index);
 
+	mdss_fb_pan_idle(mfd);
 	ret = mdss_fb_send_panel_event(mfd, MDSS_EVENT_RESUME, NULL);
 	if (ret) {
 		pr_warn("unable to resume fb%d (%d)\n", mfd->index, ret);
@@ -390,53 +418,86 @@
 					mfd->op_enable);
 		if (ret)
 			pr_warn("can't turn on display!\n");
-
-		if (mfd->vsync_pending)
-			mdss_mdp_overlay_vsync_ctrl(mfd, mfd->vsync_pending);
+		else
+			fb_set_suspend(mfd->fbi, FBINFO_STATE_RUNNING);
 	}
+	mfd->is_power_setting = false;
+	complete_all(&mfd->power_set_comp);
 
 	return ret;
 }
 
-int mdss_fb_suspend_all(void)
+#if defined(CONFIG_PM) && !defined(CONFIG_PM_SLEEP)
+static int mdss_fb_suspend(struct platform_device *pdev, pm_message_t state)
 {
-	struct fb_info *fbi;
-	int ret, i;
-	int result = 0;
-	for (i = 0; i < fbi_list_index; i++) {
-		fbi = fbi_list[i];
-		fb_set_suspend(fbi, FBINFO_STATE_SUSPENDED);
+	struct msm_fb_data_type *mfd = platform_get_drvdata(pdev);
+	if (!mfd)
+		return -ENODEV;
 
-		ret = mdss_fb_suspend_sub(fbi->par);
-		if (ret != 0) {
-			fb_set_suspend(fbi, FBINFO_STATE_RUNNING);
-			result = ret;
-		}
-	}
-	return result;
+	dev_dbg(&pdev->dev, "display suspend\n");
+
+	return mdss_fb_suspend_sub(mfd);
 }
 
-int mdss_fb_resume_all(void)
+static int mdss_fb_resume(struct platform_device *pdev)
 {
-	struct fb_info *fbi;
-	int ret, i;
-	int result = 0;
+	struct msm_fb_data_type *mfd = platform_get_drvdata(pdev);
+	if (!mfd)
+		return -ENODEV;
 
-	for (i = 0; i < fbi_list_index; i++) {
-		fbi = fbi_list[i];
+	dev_dbg(&pdev->dev, "display resume\n");
 
-		ret = mdss_fb_resume_sub(fbi->par);
-		if (ret == 0)
-			fb_set_suspend(fbi, FBINFO_STATE_RUNNING);
-	}
-	return result;
+	return mdss_fb_resume_sub(mfd);
 }
+#else
+#define mdss_fb_suspend NULL
+#define mdss_fb_resume NULL
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+static int mdss_fb_pm_suspend(struct device *dev)
+{
+	struct msm_fb_data_type *mfd = dev_get_drvdata(dev);
+
+	if (!mfd)
+		return -ENODEV;
+
+	dev_dbg(dev, "display pm suspend\n");
+
+	return mdss_fb_suspend_sub(mfd);
+}
+
+static int mdss_fb_pm_resume(struct device *dev)
+{
+	struct msm_fb_data_type *mfd = dev_get_drvdata(dev);
+	if (!mfd)
+		return -ENODEV;
+
+	dev_dbg(dev, "display pm resume\n");
+
+	return mdss_fb_resume_sub(mfd);
+}
+#endif
+
+static const struct dev_pm_ops mdss_fb_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(mdss_fb_pm_suspend, mdss_fb_pm_resume)
+};
+
+static const struct of_device_id mdss_fb_dt_match[] = {
+	{ .compatible = "qcom,mdss-fb",},
+	{}
+};
+EXPORT_COMPAT("qcom,mdss-fb");
 
 static struct platform_driver mdss_fb_driver = {
 	.probe = mdss_fb_probe,
 	.remove = mdss_fb_remove,
+	.suspend = mdss_fb_suspend,
+	.resume = mdss_fb_resume,
 	.driver = {
 		.name = "mdss_fb",
+		.of_match_table = mdss_fb_dt_match,
+		.pm = &mdss_fb_pm_ops,
 	},
 };
 
@@ -557,6 +618,9 @@
 		if (mfd->panel_power_on) {
 			int curr_pwr_state;
 
+			del_timer(&mfd->no_update.timer);
+			complete(&mfd->no_update.comp);
+
 			mfd->op_enable = false;
 			curr_pwr_state = mfd->panel_power_on;
 			mfd->panel_power_on = false;
@@ -566,7 +630,8 @@
 			ret = mfd->off_fnc(mfd);
 			if (ret)
 				mfd->panel_power_on = curr_pwr_state;
-
+			else
+				mdss_fb_release_fences(mfd);
 			mfd->op_enable = true;
 		}
 		break;
@@ -578,6 +643,20 @@
 static int mdss_fb_blank(int blank_mode, struct fb_info *info)
 {
 	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	if (blank_mode == FB_BLANK_POWERDOWN) {
+		struct fb_event event;
+		event.info = info;
+		event.data = &blank_mode;
+		fb_notifier_call_chain(FB_EVENT_BLANK, &event);
+	}
+	mdss_fb_pan_idle(mfd);
+	if (mfd->op_enable == 0) {
+		if (blank_mode == FB_BLANK_UNBLANK)
+			mfd->suspend.panel_power_on = true;
+		else
+			mfd->suspend.panel_power_on = false;
+		return 0;
+	}
 	return mdss_fb_blank_sub(blank_mode, info, mfd->op_enable);
 }
 
@@ -594,6 +673,7 @@
 	unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
 	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
 
+	mdss_fb_pan_idle(mfd);
 	if (off >= len) {
 		/* memory mapped io */
 		off -= len;
@@ -680,11 +760,9 @@
 			return -ENOMEM;
 		}
 		phys = memory_pool_node_paddr(virt);
-		if (is_mdss_iommu_attached()) {
-			dom = mdss_get_iommu_domain(MDSS_IOMMU_DOMAIN_UNSECURE);
-			msm_iommu_map_contig_buffer(phys, dom, 0, size, SZ_4K,
-						    0, &(mfd->iova));
-		}
+		dom = mdss_get_iommu_domain(MDSS_IOMMU_DOMAIN_UNSECURE);
+		msm_iommu_map_contig_buffer(phys, dom, 0, size, SZ_4K,
+					    0, &(mfd->iova));
 		pr_info("allocating %u bytes at %p (%lx phys) for fb %d\n",
 			size, virt, phys, mfd->index);
 	} else {
@@ -838,13 +916,15 @@
 		return ret;
 	}
 
-	fix->type = panel_info->is_3d_panel;
-	fix->line_length = mdss_fb_line_length(mfd->index, panel_info->xres,
-					       bpp);
-
 	var->xres = panel_info->xres;
+	if (mfd->split_display)
+		var->xres *= 2;
+
+	fix->type = panel_info->is_3d_panel;
+	fix->line_length = mdss_fb_line_length(mfd->index, var->xres, bpp);
+
 	var->yres = panel_info->yres;
-	var->xres_virtual = panel_info->xres;
+	var->xres_virtual = var->xres;
 	var->yres_virtual = panel_info->yres * mfd->fb_page;
 	var->bits_per_pixel = bpp * 8;	/* FrameBuffer color depth */
 	var->upper_margin = panel_info->lcdc.v_back_porch;
@@ -855,20 +935,6 @@
 	var->hsync_len = panel_info->lcdc.h_pulse_width;
 	var->pixclock = panel_info->clk_rate / 1000;
 
-	if (panel_info->type == MIPI_VIDEO_PANEL) {
-		var->reserved[4] = panel_info->mipi.frame_rate;
-	} else {
-		var->reserved[4] = panel_info->clk_rate /
-			((panel_info->lcdc.h_back_porch +
-			  panel_info->lcdc.h_front_porch +
-			  panel_info->lcdc.h_pulse_width +
-			  panel_info->xres) *
-			 (panel_info->lcdc.v_back_porch +
-			  panel_info->lcdc.v_front_porch +
-			  panel_info->lcdc.v_pulse_width +
-			  panel_info->yres));
-	}
-
 	/* id field for fb app  */
 
 	id = (int *)&mfd->panel;
@@ -879,7 +945,6 @@
 	fbi->flags = FBINFO_FLAG_DEFAULT;
 	fbi->pseudo_palette = mdss_fb_pseudo_palette;
 
-	panel_info->fbi = fbi;
 	mfd->ref_cnt = 0;
 	mfd->panel_power_on = false;
 
@@ -891,12 +956,21 @@
 	mfd->op_enable = true;
 
 	mutex_init(&mfd->no_update.lock);
+	mutex_init(&mfd->sync_mutex);
 	init_timer(&mfd->no_update.timer);
 	mfd->no_update.timer.function = mdss_fb_no_update_notify_timer_cb;
 	mfd->no_update.timer.data = (unsigned long)mfd;
 	init_completion(&mfd->update.comp);
 	init_completion(&mfd->no_update.comp);
-
+	init_completion(&mfd->commit_comp);
+	init_completion(&mfd->power_set_comp);
+	INIT_WORK(&mfd->commit_work, mdss_fb_commit_wq_handler);
+	mfd->msm_fb_backup = kzalloc(sizeof(struct msm_fb_backup_type),
+		GFP_KERNEL);
+	if (mfd->msm_fb_backup == 0) {
+		pr_err("error: not enough memory!\n");
+		return -ENOMEM;
+	}
 	if (mfd->lut_update) {
 		ret = fb_alloc_cmap(&fbi->cmap, 256, 0);
 		if (ret)
@@ -954,6 +1028,7 @@
 		return -EINVAL;
 	}
 
+	mdss_fb_pan_idle(mfd);
 	mfd->ref_cnt--;
 
 	if (!mfd->ref_cnt) {
@@ -969,7 +1044,154 @@
 	return ret;
 }
 
+static void mdss_fb_power_setting_idle(struct msm_fb_data_type *mfd)
+{
+	int ret;
+
+	if (mfd->is_power_setting) {
+		ret = wait_for_completion_timeout(
+				&mfd->power_set_comp,
+			msecs_to_jiffies(WAIT_DISP_OP_TIMEOUT));
+		if (ret < 0)
+			ret = -ERESTARTSYS;
+		else if (!ret)
+			pr_err("%s wait for power_set_comp timeout %d %d",
+				__func__, ret, mfd->is_power_setting);
+		if (ret <= 0) {
+			mfd->is_power_setting = false;
+			complete_all(&mfd->power_set_comp);
+		}
+	}
+}
+
+void mdss_fb_wait_for_fence(struct msm_fb_data_type *mfd)
+{
+	int i, ret = 0;
+	/* buf sync */
+	for (i = 0; i < mfd->acq_fen_cnt; i++) {
+		ret = sync_fence_wait(mfd->acq_fen[i], WAIT_FENCE_TIMEOUT);
+		if (ret < 0) {
+			pr_err("%s: sync_fence_wait failed! ret = %x\n",
+				__func__, ret);
+			break;
+		}
+		sync_fence_put(mfd->acq_fen[i]);
+	}
+
+	if (ret < 0) {
+		while (i < mfd->acq_fen_cnt) {
+			sync_fence_put(mfd->acq_fen[i]);
+			i++;
+		}
+	}
+	mfd->acq_fen_cnt = 0;
+}
+
+static void mdss_fb_signal_timeline_locked(struct msm_fb_data_type *mfd)
+{
+	if (mfd->timeline && !list_empty((const struct list_head *)
+				(&(mfd->timeline->obj.active_list_head)))) {
+		sw_sync_timeline_inc(mfd->timeline, 1);
+		mfd->timeline_value++;
+	}
+	mfd->last_rel_fence = mfd->cur_rel_fence;
+	mfd->cur_rel_fence = 0;
+}
+
+void mdss_fb_signal_timeline(struct msm_fb_data_type *mfd)
+{
+	mutex_lock(&mfd->sync_mutex);
+	mdss_fb_signal_timeline_locked(mfd);
+	mutex_unlock(&mfd->sync_mutex);
+}
+
+static void mdss_fb_release_fences(struct msm_fb_data_type *mfd)
+{
+	mutex_lock(&mfd->sync_mutex);
+	if (mfd->timeline) {
+		sw_sync_timeline_inc(mfd->timeline, 2);
+		mfd->timeline_value += 2;
+	}
+	mfd->last_rel_fence = 0;
+	mfd->cur_rel_fence = 0;
+	mutex_unlock(&mfd->sync_mutex);
+}
+
+static void mdss_fb_pan_idle(struct msm_fb_data_type *mfd)
+{
+	int ret;
+
+	if (mfd->is_committing) {
+		ret = wait_for_completion_timeout(
+				&mfd->commit_comp,
+			msecs_to_jiffies(WAIT_DISP_OP_TIMEOUT));
+		if (ret < 0)
+			ret = -ERESTARTSYS;
+		else if (!ret)
+			pr_err("%s wait for commit_comp timeout %d %d",
+				__func__, ret, mfd->is_committing);
+		if (ret <= 0) {
+			mutex_lock(&mfd->sync_mutex);
+			mdss_fb_signal_timeline_locked(mfd);
+			mfd->is_committing = 0;
+			complete_all(&mfd->commit_comp);
+			mutex_unlock(&mfd->sync_mutex);
+		}
+	}
+}
+
+static int mdss_fb_pan_display_ex(struct fb_info *info,
+		struct mdp_display_commit *disp_commit)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	struct msm_fb_backup_type *fb_backup;
+	struct fb_var_screeninfo *var = &disp_commit->var;
+	u32 wait_for_finish = disp_commit->wait_for_finish;
+	int ret = 0;
+
+	if ((!mfd->op_enable) || (!mfd->panel_power_on))
+		return -EPERM;
+
+	if (var->xoffset > (info->var.xres_virtual - info->var.xres))
+		return -EINVAL;
+
+	if (var->yoffset > (info->var.yres_virtual - info->var.yres))
+		return -EINVAL;
+
+	mdss_fb_pan_idle(mfd);
+
+	mutex_lock(&mfd->sync_mutex);
+	if (info->fix.xpanstep)
+		info->var.xoffset =
+		(var->xoffset / info->fix.xpanstep) * info->fix.xpanstep;
+
+	if (info->fix.ypanstep)
+		info->var.yoffset =
+		(var->yoffset / info->fix.ypanstep) * info->fix.ypanstep;
+
+	fb_backup = (struct msm_fb_backup_type *)mfd->msm_fb_backup;
+	memcpy(&fb_backup->info, info, sizeof(struct fb_info));
+	memcpy(&fb_backup->disp_commit, disp_commit,
+		sizeof(struct mdp_display_commit));
+	INIT_COMPLETION(mfd->commit_comp);
+	mfd->is_committing = 1;
+	schedule_work(&mfd->commit_work);
+	mutex_unlock(&mfd->sync_mutex);
+	if (wait_for_finish)
+		mdss_fb_pan_idle(mfd);
+	return ret;
+}
+
 static int mdss_fb_pan_display(struct fb_var_screeninfo *var,
+		struct fb_info *info)
+{
+	struct mdp_display_commit disp_commit;
+	memset(&disp_commit, 0, sizeof(disp_commit));
+	disp_commit.wait_for_finish = true;
+	return mdss_fb_pan_display_ex(info, &disp_commit);
+}
+
+static int mdss_fb_pan_display_sub(struct fb_var_screeninfo *var,
 			       struct fb_info *info)
 {
 	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
@@ -991,12 +1213,13 @@
 		info->var.yoffset =
 		(var->yoffset / info->fix.ypanstep) * info->fix.ypanstep;
 
+	mdss_fb_wait_for_fence(mfd);
 	if (mfd->dma_fnc)
 		mfd->dma_fnc(mfd);
 	else
 		pr_warn("dma function not set for panel type=%d\n",
 				mfd->panel.type);
-
+	mdss_fb_signal_timeline(mfd);
 	mdss_fb_update_backlight(mfd);
 	return 0;
 }
@@ -1013,8 +1236,34 @@
 	pinfo->lcdc.h_back_porch = var->left_margin;
 	pinfo->lcdc.h_pulse_width = var->hsync_len;
 	pinfo->clk_rate = var->pixclock;
-	/* todo: find how to pass CEA vic through framebuffer APIs */
-	pinfo->vic = var->reserved[3];
+}
+
+static void mdss_fb_commit_wq_handler(struct work_struct *work)
+{
+	struct msm_fb_data_type *mfd;
+	struct fb_var_screeninfo *var;
+	struct fb_info *info;
+	struct msm_fb_backup_type *fb_backup;
+	int ret;
+
+	mfd = container_of(work, struct msm_fb_data_type, commit_work);
+	fb_backup = (struct msm_fb_backup_type *)mfd->msm_fb_backup;
+	info = &fb_backup->info;
+	if (fb_backup->disp_commit.flags &
+		MDP_DISPLAY_COMMIT_OVERLAY) {
+		mdss_fb_wait_for_fence(mfd);
+		mdss_mdp_overlay_kickoff(mfd->ctl);
+		mdss_fb_signal_timeline(mfd);
+	} else {
+		var = &fb_backup->disp_commit.var;
+		ret = mdss_fb_pan_display_sub(var, info);
+		if (ret)
+			pr_err("%s fails: ret = %x", __func__, ret);
+	}
+	mutex_lock(&mfd->sync_mutex);
+	mfd->is_committing = 0;
+	complete_all(&mfd->commit_comp);
+	mutex_unlock(&mfd->sync_mutex);
 }
 
 static int mdss_fb_check_var(struct fb_var_screeninfo *var,
@@ -1137,6 +1386,7 @@
 	struct fb_var_screeninfo *var = &info->var;
 	int old_imgType;
 
+	mdss_fb_pan_idle(mfd);
 	old_imgType = mfd->fb_imgType;
 	switch (var->bits_per_pixel) {
 	case 16:
@@ -1226,32 +1476,32 @@
 
 	switch (mdp_pp.op) {
 	case mdp_op_pa_cfg:
-		ret = mdss_mdp_pa_config(&mdp_pp.data.pa_cfg_data,
+		ret = mdss_mdp_pa_config(mfd->ctl, &mdp_pp.data.pa_cfg_data,
 				&copyback);
 		break;
 
 	case mdp_op_pcc_cfg:
-		ret = mdss_mdp_pcc_config(&mdp_pp.data.pcc_cfg_data,
+		ret = mdss_mdp_pcc_config(mfd->ctl, &mdp_pp.data.pcc_cfg_data,
 			   &copyback);
 		break;
 
 	case mdp_op_lut_cfg:
 		switch (mdp_pp.data.lut_cfg_data.lut_type) {
 		case mdp_lut_igc:
-			ret = mdss_mdp_igc_lut_config(
+			ret = mdss_mdp_igc_lut_config(mfd->ctl,
 					(struct mdp_igc_lut_data *)
 					&mdp_pp.data.lut_cfg_data.data,
 					&copyback);
 			break;
 
 		case mdp_lut_pgc:
-			ret = mdss_mdp_argc_config(
+			ret = mdss_mdp_argc_config(mfd->ctl,
 				&mdp_pp.data.lut_cfg_data.data.pgc_lut_data,
 				&copyback);
 			break;
 
 		case mdp_lut_hist:
-			ret = mdss_mdp_hist_lut_config(
+			ret = mdss_mdp_hist_lut_config(mfd->ctl,
 				(struct mdp_hist_lut_data *)
 				&mdp_pp.data.lut_cfg_data.data, &copyback);
 			break;
@@ -1262,12 +1512,12 @@
 		}
 		break;
 	case mdp_op_dither_cfg:
-		ret = mdss_mdp_dither_config(&mdp_pp.data.dither_cfg_data,
-				&copyback);
+		ret = mdss_mdp_dither_config(mfd->ctl,
+				&mdp_pp.data.dither_cfg_data, &copyback);
 		break;
 	case mdp_op_gamut_cfg:
-		ret = mdss_mdp_gamut_config(&mdp_pp.data.gamut_cfg_data,
-				&copyback);
+		ret = mdss_mdp_gamut_config(mfd->ctl,
+					&mdp_pp.data.gamut_cfg_data, &copyback);
 		break;
 	case mdp_bl_scale_cfg:
 		ret = mdss_bl_scale_config(mfd, (struct mdp_bl_scale_data *)
@@ -1282,6 +1532,142 @@
 		ret = copy_to_user(argp, &mdp_pp, sizeof(struct msmfb_mdp_pp));
 	return ret;
 }
+static int mdss_fb_handle_buf_sync_ioctl(struct msm_fb_data_type *mfd,
+						struct mdp_buf_sync *buf_sync)
+{
+	int i, fence_cnt = 0, ret = 0;
+	int acq_fen_fd[MDP_MAX_FENCE_FD];
+	struct sync_fence *fence;
+
+	if ((buf_sync->acq_fen_fd_cnt > MDP_MAX_FENCE_FD) ||
+		(mfd->timeline == NULL))
+		return -EINVAL;
+
+	if ((!mfd->op_enable) || (!mfd->panel_power_on))
+		return -EPERM;
+
+	if (buf_sync->acq_fen_fd_cnt)
+		ret = copy_from_user(acq_fen_fd, buf_sync->acq_fen_fd,
+				buf_sync->acq_fen_fd_cnt * sizeof(int));
+	if (ret) {
+		pr_err("%s:copy_from_user failed", __func__);
+		return ret;
+	}
+	mutex_lock(&mfd->sync_mutex);
+	for (i = 0; i < buf_sync->acq_fen_fd_cnt; i++) {
+		fence = sync_fence_fdget(acq_fen_fd[i]);
+		if (fence == NULL) {
+			pr_info("%s: null fence! i=%d fd=%d\n", __func__, i,
+				acq_fen_fd[i]);
+			ret = -EINVAL;
+			break;
+		}
+		mfd->acq_fen[i] = fence;
+	}
+	fence_cnt = i;
+	if (ret)
+		goto buf_sync_err_1;
+	mfd->acq_fen_cnt = fence_cnt;
+	if (buf_sync->flags & MDP_BUF_SYNC_FLAG_WAIT)
+		mdss_fb_wait_for_fence(mfd);
+
+	mfd->cur_rel_sync_pt = sw_sync_pt_create(mfd->timeline,
+			mfd->timeline_value + 2);
+	if (mfd->cur_rel_sync_pt == NULL) {
+		pr_err("%s: cannot create sync point", __func__);
+		ret = -ENOMEM;
+		goto buf_sync_err_1;
+	}
+	/* create fence */
+	mfd->cur_rel_fence = sync_fence_create("mdp-fence",
+			mfd->cur_rel_sync_pt);
+	if (mfd->cur_rel_fence == NULL) {
+		sync_pt_free(mfd->cur_rel_sync_pt);
+		mfd->cur_rel_sync_pt = NULL;
+		pr_err("%s: cannot create fence", __func__);
+		ret = -ENOMEM;
+		goto buf_sync_err_1;
+	}
+	/* create fd */
+	mfd->cur_rel_fen_fd = get_unused_fd_flags(0);
+	if (mfd->cur_rel_fen_fd < 0) {
+		pr_err("%s: get_unused_fd_flags failed", __func__);
+		ret  = -EIO;
+		goto buf_sync_err_2;
+	}
+	sync_fence_install(mfd->cur_rel_fence, mfd->cur_rel_fen_fd);
+	ret = copy_to_user(buf_sync->rel_fen_fd,
+		&mfd->cur_rel_fen_fd, sizeof(int));
+	if (ret) {
+		pr_err("%s:copy_to_user failed", __func__);
+		goto buf_sync_err_3;
+	}
+	mutex_unlock(&mfd->sync_mutex);
+	return ret;
+buf_sync_err_3:
+	put_unused_fd(mfd->cur_rel_fen_fd);
+buf_sync_err_2:
+	sync_fence_put(mfd->cur_rel_fence);
+	mfd->cur_rel_fence = NULL;
+	mfd->cur_rel_fen_fd = 0;
+buf_sync_err_1:
+	for (i = 0; i < fence_cnt; i++)
+		sync_fence_put(mfd->acq_fen[i]);
+	mfd->acq_fen_cnt = 0;
+	mutex_unlock(&mfd->sync_mutex);
+	return ret;
+}
+static int mdss_fb_display_commit(struct fb_info *info,
+						unsigned long *argp)
+{
+	int ret;
+	struct mdp_display_commit disp_commit;
+	ret = copy_from_user(&disp_commit, argp,
+			sizeof(disp_commit));
+	if (ret) {
+		pr_err("%s:copy_from_user failed", __func__);
+		return ret;
+	}
+	ret = mdss_fb_pan_display_ex(info, &disp_commit);
+	return ret;
+}
+
+static int mdss_fb_set_metadata(struct msm_fb_data_type *mfd,
+				struct msmfb_metadata *metadata)
+{
+	int ret = 0;
+	switch (metadata->op) {
+	case metadata_op_vic:
+		if (mfd->panel_info)
+			mfd->panel_info->vic =
+				metadata->data.video_info_code;
+		else
+			ret = -EINVAL;
+		break;
+	default:
+		pr_warn("unsupported request to MDP META IOCTL\n");
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+static int mdss_fb_get_metadata(struct msm_fb_data_type *mfd,
+				struct msmfb_metadata *metadata)
+{
+	int ret = 0;
+	switch (metadata->op) {
+	case metadata_op_frame_rate:
+		metadata->data.panel_frame_rate =
+			mdss_get_panel_framerate(mfd);
+		break;
+	default:
+		pr_warn("Unsupported request to MDP META IOCTL.\n");
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
 
 static int mdss_fb_ioctl(struct fb_info *info, unsigned int cmd,
 			 unsigned long arg)
@@ -1293,6 +1679,12 @@
 	u32 block, hist_data_addr = 0;
 	struct mdp_page_protection fb_page_protection;
 	int ret = -ENOSYS;
+	struct mdp_buf_sync buf_sync;
+	struct msmfb_metadata metadata;
+
+	mdss_fb_power_setting_idle(mfd);
+
+	mdss_fb_pan_idle(mfd);
 
 	switch (cmd) {
 	case MSMFB_CURSOR:
@@ -1311,7 +1703,7 @@
 		if (ret)
 			return ret;
 
-		ret = mdss_mdp_hist_collect(info, &hist, &hist_data_addr);
+		ret = mdss_mdp_hist_collect(mfd->ctl, &hist, &hist_data_addr);
 		if ((ret == 0) && hist_data_addr) {
 			ret = copy_to_user(hist.c0, (u32 *)hist_data_addr,
 				sizeof(u32) * hist.bin_cnt);
@@ -1329,7 +1721,7 @@
 		if (ret)
 			return ret;
 
-		ret = mdss_mdp_histogram_start(&hist_req);
+		ret = mdss_mdp_histogram_start(mfd->ctl, &hist_req);
 		break;
 
 	case MSMFB_HISTOGRAM_STOP:
@@ -1337,7 +1729,7 @@
 		if (ret)
 			return ret;
 
-		ret = mdss_mdp_histogram_stop(block);
+		ret = mdss_mdp_histogram_stop(mfd->ctl, block);
 		break;
 
 	case MSMFB_GET_PAGE_PROTECTION:
@@ -1353,10 +1745,41 @@
 		ret = mdss_fb_handle_pp_ioctl(mfd, argp);
 		break;
 
+	case MSMFB_BUFFER_SYNC:
+		ret = copy_from_user(&buf_sync, argp, sizeof(buf_sync));
+		if (ret)
+			return ret;
+
+		ret = mdss_fb_handle_buf_sync_ioctl(mfd, &buf_sync);
+
+		if (!ret)
+			ret = copy_to_user(argp, &buf_sync, sizeof(buf_sync));
+		break;
+
 	case MSMFB_NOTIFY_UPDATE:
 		ret = mdss_fb_notify_update(mfd, argp);
 		break;
 
+	case MSMFB_DISPLAY_COMMIT:
+		ret = mdss_fb_display_commit(info, argp);
+		break;
+
+	case MSMFB_METADATA_SET:
+		ret = copy_from_user(&metadata, argp, sizeof(metadata));
+		if (ret)
+			return ret;
+		ret = mdss_fb_set_metadata(mfd, &metadata);
+		break;
+
+	case MSMFB_METADATA_GET:
+		ret = copy_from_user(&metadata, argp, sizeof(metadata));
+		if (ret)
+			return ret;
+		ret = mdss_fb_get_metadata(mfd, &metadata);
+		if (!ret)
+			ret = copy_to_user(argp, &metadata, sizeof(metadata));
+		break;
+
 	default:
 		if (mfd->ioctl_handler)
 			ret = mfd->ioctl_handler(mfd, cmd, argp);
@@ -1383,44 +1806,83 @@
 }
 EXPORT_SYMBOL(msm_fb_get_writeback_fb);
 
-int mdss_register_panel(struct mdss_panel_data *pdata)
+static int mdss_fb_register_extra_panel(struct platform_device *pdev,
+	struct mdss_panel_data *pdata)
 {
-	struct platform_device *mdss_fb_dev = NULL;
-	struct msm_fb_data_type *mfd;
-	int rc;
+	struct mdss_panel_data *fb_pdata;
 
-	if (!mdss_res) {
-		pr_err("mdss mdp resources not initialized yet\n");
-		return -ENODEV;
-	}
-
-	mdss_fb_dev = platform_device_alloc("mdss_fb", pdata->panel_info.pdest);
-	if (!mdss_fb_dev) {
-		pr_err("unable to allocate mdss_fb device\n");
-		return -ENOMEM;
-	}
-
-	mdss_fb_dev->dev.platform_data = pdata;
-
-	rc = platform_device_add(mdss_fb_dev);
-	if (rc) {
-		platform_device_put(mdss_fb_dev);
-		pr_err("unable to probe mdss_fb device (%d)\n", rc);
-		return rc;
-	}
-
-	mfd = platform_get_drvdata(mdss_fb_dev);
-	if (!mfd)
-		return -ENODEV;
-	if (mfd->key != MFD_KEY)
+	fb_pdata = dev_get_platdata(&pdev->dev);
+	if (!fb_pdata) {
+		pr_err("framebuffer device %s contains invalid panel data\n",
+				dev_name(&pdev->dev));
 		return -EINVAL;
+	}
 
-	mfd->on_fnc = mdss_mdp_ctl_on;
-	mfd->off_fnc = mdss_mdp_ctl_off;
+	if (fb_pdata->next) {
+		pr_err("split panel already setup for framebuffer device %s\n",
+				dev_name(&pdev->dev));
+		return -EEXIST;
+	}
 
-	rc = mdss_mdp_overlay_init(mfd);
-	if (rc)
-		pr_err("unable to init overlay\n");
+	if ((fb_pdata->panel_info.type != MIPI_VIDEO_PANEL) ||
+			(pdata->panel_info.type != MIPI_VIDEO_PANEL)) {
+		pr_err("Split panel not supported for panel type %d\n",
+				pdata->panel_info.type);
+		return -EINVAL;
+	}
+
+	fb_pdata->next = pdata;
+
+	return 0;
+}
+
+int mdss_register_panel(struct platform_device *pdev,
+	struct mdss_panel_data *pdata)
+{
+	struct platform_device *fb_pdev, *mdss_pdev;
+	struct device_node *node;
+	int rc = 0;
+
+	if (!pdev || !pdev->dev.of_node) {
+		pr_err("Invalid device node\n");
+		return -ENODEV;
+	}
+
+	node = of_parse_phandle(pdev->dev.of_node, "qcom,mdss-fb-map", 0);
+	if (!node) {
+		pr_err("Unable to find fb node for device: %s\n",
+				pdev->name);
+		return -ENODEV;
+	}
+	mdss_pdev = of_find_device_by_node(node->parent);
+	if (!mdss_pdev) {
+		pr_err("Unable to find mdss for node: %s\n", node->full_name);
+		rc = -ENODEV;
+		goto mdss_notfound;
+	}
+
+	fb_pdev = of_find_device_by_node(node);
+	if (fb_pdev) {
+		rc = mdss_fb_register_extra_panel(fb_pdev, pdata);
+	} else {
+		pr_info("adding framebuffer device %s\n", dev_name(&pdev->dev));
+		fb_pdev = of_platform_device_create(node, NULL,
+				&mdss_pdev->dev);
+		fb_pdev->dev.platform_data = pdata;
+	}
+
+	/*
+	 * Clocks are already on if continuous splash is enabled,
+	 * increasing ref_cnt to help balance clocks once done.
+	 */
+	if (pdata->panel_info.cont_splash_enabled) {
+		mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
+		mdss_mdp_footswitch_ctrl_splash(1);
+		mdss_mdp_copy_splash_screen(pdata);
+	}
+
+mdss_notfound:
+	of_node_put(node);
 
 	return rc;
 }
@@ -1462,4 +1924,4 @@
 	return 0;
 }
 
-module_init(mdss_fb_init);
+device_initcall_sync(mdss_fb_init);
diff --git a/drivers/video/msm/mdss/mdss_fb.h b/drivers/video/msm/mdss/mdss_fb.h
index 11bb859..c4e837e 100644
--- a/drivers/video/msm/mdss/mdss_fb.h
+++ b/drivers/video/msm/mdss/mdss_fb.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
@@ -27,6 +27,10 @@
 #define MSM_FB_MAX_DEV_LIST 32
 
 #define MSM_FB_ENABLE_DBGFS
+/* 900 ms for fence time out */
+#define WAIT_FENCE_TIMEOUT 900
+/* 950 ms for display operation time out */
+#define WAIT_DISP_OP_TIMEOUT 950
 
 #ifndef MAX
 #define  MAX(x, y) (((x) > (y)) ? (x) : (y))
@@ -56,6 +60,7 @@
 
 	struct panel_id panel;
 	struct mdss_panel_info *panel_info;
+	int split_display;
 
 	u32 dest;
 	struct fb_info *fbi;
@@ -69,6 +74,7 @@
 	ktime_t vsync_time;
 	struct completion vsync_comp;
 	spinlock_t vsync_lock;
+	int borderfill_enable;
 
 	int hw_refresh;
 
@@ -104,6 +110,7 @@
 
 	u32 mdp_fb_page_protection;
 
+	struct mdss_data_type *mdata;
 	struct mdss_mdp_ctl *ctl;
 	struct mdss_mdp_wb *wb;
 	struct list_head overlay_list;
@@ -111,11 +118,36 @@
 	struct list_head pipes_cleanup;
 	struct disp_info_notify update;
 	struct disp_info_notify no_update;
+
+	u32 acq_fen_cnt;
+	struct sync_fence *acq_fen[MDP_MAX_FENCE_FD];
+	int cur_rel_fen_fd;
+	struct sync_pt *cur_rel_sync_pt;
+	struct sync_fence *cur_rel_fence;
+	struct sync_fence *last_rel_fence;
+	struct sw_sync_timeline *timeline;
+	int timeline_value;
+	u32 last_acq_fen_cnt;
+	struct sync_fence *last_acq_fen[MDP_MAX_FENCE_FD];
+	struct mutex sync_mutex;
+	/* for non-blocking */
+	struct completion commit_comp;
+	u32 is_committing;
+	struct work_struct commit_work;
+	void *msm_fb_backup;
+	struct completion power_set_comp;
+	u32 is_power_setting;
+};
+
+struct msm_fb_backup_type {
+	struct fb_info info;
+	struct mdp_display_commit disp_commit;
 };
 
 int mdss_fb_get_phys_info(unsigned long *start, unsigned long *len, int fb_num);
 void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl);
 void mdss_fb_update_backlight(struct msm_fb_data_type *mfd);
-int mdss_fb_suspend_all(void);
-int mdss_fb_resume_all(void);
+void mdss_fb_wait_for_fence(struct msm_fb_data_type *mfd);
+void mdss_fb_signal_timeline(struct msm_fb_data_type *mfd);
+
 #endif /* MDSS_FB_H */
diff --git a/drivers/video/msm/mdss/mdss_hdmi_edid.c b/drivers/video/msm/mdss/mdss_hdmi_edid.c
index 6c76348..08be337 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_edid.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_edid.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -240,6 +240,8 @@
 	if (edid_ctrl->sink_data.num_of_elements) {
 		u32 *video_mode = edid_ctrl->sink_data.disp_mode_list;
 		for (i = 0; i < edid_ctrl->sink_data.num_of_elements; ++i) {
+			if (!hdmi_get_supported_mode(*video_mode))
+				continue;
 			if (ret > 0)
 				ret += snprintf(buf+ret, PAGE_SIZE-ret, ",%d",
 					*video_mode++ + 1);
diff --git a/drivers/video/msm/mdss/mdss_hdmi_edid.h b/drivers/video/msm/mdss/mdss_hdmi_edid.h
index bb56a24..e8d1b7c 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_edid.h
+++ b/drivers/video/msm/mdss/mdss_hdmi_edid.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/mdss/mdss_hdmi_mhl.h b/drivers/video/msm/mdss/mdss_hdmi_mhl.h
new file mode 100644
index 0000000..8fef63e
--- /dev/null
+++ b/drivers/video/msm/mdss/mdss_hdmi_mhl.h
@@ -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.
+ *
+ */
+
+#ifndef __MDSS_HDMI_MHL_H__
+#define __MDSS_HDMI_MHL_H__
+
+#include <linux/platform_device.h>
+
+struct msm_hdmi_mhl_ops {
+	u8 (*tmds_enabled)(struct platform_device *pdev);
+	int (*set_mhl_max_pclk)(struct platform_device *pdev, u32 max_val);
+};
+
+int msm_hdmi_register_mhl(struct platform_device *pdev,
+			  struct msm_hdmi_mhl_ops *ops);
+
+#endif /* __MDSS_HDMI_MHL_H__ */
diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.c b/drivers/video/msm/mdss/mdss_hdmi_tx.c
index edc3634..5404000 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -30,11 +30,12 @@
 #include "mdss_hdmi_hdcp.h"
 #include "mdss.h"
 #include "mdss_panel.h"
+#include "mdss_hdmi_mhl.h"
 
 #define DRV_NAME "hdmi-tx"
 #define COMPATIBLE_NAME "qcom,hdmi-tx"
 
-#define DEFAULT_VIDEO_RESOLUTION HDMI_VFRMT_1920x1080p60_16_9
+#define DEFAULT_VIDEO_RESOLUTION HDMI_VFRMT_640x480p60_4_3
 
 /* HDMI PHY/PLL bit field macros */
 #define SW_RESET BIT(2)
@@ -406,24 +407,23 @@
 	.attrs = hdmi_tx_fs_attrs,
 };
 
-static int hdmi_tx_sysfs_create(struct hdmi_tx_ctrl *hdmi_ctrl)
+static int hdmi_tx_sysfs_create(struct hdmi_tx_ctrl *hdmi_ctrl,
+	struct fb_info *fbi)
 {
 	int rc;
-	struct mdss_panel_info *pinfo = NULL;
 
-	if (!hdmi_ctrl) {
+	if (!hdmi_ctrl || !fbi) {
 		DEV_ERR("%s: invalid input\n", __func__);
 		return -ENODEV;
 	}
-	pinfo = &hdmi_ctrl->panel_data.panel_info;
 
-	rc = sysfs_create_group(&pinfo->fbi->dev->kobj,
+	rc = sysfs_create_group(&fbi->dev->kobj,
 		&hdmi_tx_fs_attrs_group);
 	if (rc) {
 		DEV_ERR("%s: failed, rc=%d\n", __func__, rc);
 		return rc;
 	}
-	hdmi_ctrl->kobj = &pinfo->fbi->dev->kobj;
+	hdmi_ctrl->kobj = &fbi->dev->kobj;
 	DEV_DBG("%s: sysfs group %p\n", __func__, hdmi_ctrl->kobj);
 
 	kobject_uevent(hdmi_ctrl->kobj, KOBJ_ADD);
@@ -630,6 +630,30 @@
 	hdmi_set_supported_mode(HDMI_VFRMT_4096x2160p24_16_9);
 } /* hdmi_tx_setup_video_mode_lut */
 
+/* Table tuned to indicate video formats supported by the MHL Tx */
+/* Valid pclk rates (Mhz): 25.2, 27, 27.03, 74.25 */
+static void hdmi_tx_setup_mhl_video_mode_lut(struct hdmi_tx_ctrl *hdmi_ctrl)
+{
+	u32 i;
+	struct hdmi_disp_mode_timing_type *temp_timing;
+
+	if (!hdmi_ctrl->mhl_max_pclk) {
+		DEV_WARN("%s: mhl max pclk not set!\n", __func__);
+		return;
+	}
+	DEV_DBG("%s: max mode set to [%u]\n",
+		__func__, hdmi_ctrl->mhl_max_pclk);
+	for (i = 0; i < HDMI_VFRMT_MAX; i++) {
+		temp_timing =
+		(struct hdmi_disp_mode_timing_type *)hdmi_get_supported_mode(i);
+		if (!temp_timing)
+			continue;
+		/* formats that exceed max mhl line clk bw */
+		if (temp_timing->pixel_freq > hdmi_ctrl->mhl_max_pclk)
+			hdmi_del_supported_mode(i);
+	}
+} /* hdmi_tx_setup_mhl_video_mode_lut */
+
 static int hdmi_tx_read_sink_info(struct hdmi_tx_ctrl *hdmi_ctrl)
 {
 	int status;
@@ -1742,7 +1766,7 @@
 		rc = -EPERM;
 	}
 
-	return 0;
+	return rc;
 } /* hdmi_tx_audio_info_setup */
 
 static int hdmi_tx_get_audio_edid_blk(struct platform_device *pdev,
@@ -1759,12 +1783,65 @@
 		hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID], blk);
 } /* hdmi_tx_get_audio_edid_blk */
 
+static u8 hdmi_tx_tmds_enabled(struct platform_device *pdev)
+{
+	struct hdmi_tx_ctrl *hdmi_ctrl = platform_get_drvdata(pdev);
+
+	if (!hdmi_ctrl) {
+		DEV_ERR("%s: invalid input\n", __func__);
+		return -ENODEV;
+	}
+
+	/* status of tmds */
+	return (hdmi_ctrl->timing_gen_on == true);
+}
+
+static int hdmi_tx_set_mhl_max_pclk(struct platform_device *pdev, u32 max_val)
+{
+	struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
+
+	hdmi_ctrl = platform_get_drvdata(pdev);
+
+	if (!hdmi_ctrl) {
+		DEV_ERR("%s: invalid input\n", __func__);
+		return -ENODEV;
+	}
+	if (max_val) {
+		hdmi_ctrl->mhl_max_pclk = max_val;
+		hdmi_tx_setup_mhl_video_mode_lut(hdmi_ctrl);
+	} else {
+		DEV_ERR("%s: invalid max pclk val\n", __func__);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+int msm_hdmi_register_mhl(struct platform_device *pdev,
+		struct msm_hdmi_mhl_ops *ops)
+{
+	struct hdmi_tx_ctrl *hdmi_ctrl = platform_get_drvdata(pdev);
+
+	if (!hdmi_ctrl) {
+		DEV_ERR("%s: invalid pdev\n", __func__);
+		return -ENODEV;
+	}
+
+	if (!ops) {
+		DEV_ERR("%s: invalid ops\n", __func__);
+		return -EINVAL;
+	}
+
+	ops->tmds_enabled = hdmi_tx_tmds_enabled;
+	ops->set_mhl_max_pclk = hdmi_tx_set_mhl_max_pclk;
+	return 0;
+}
+
 int msm_hdmi_register_audio_codec(struct platform_device *pdev,
 	struct msm_hdmi_audio_codec_ops *ops)
 {
 	struct hdmi_tx_ctrl *hdmi_ctrl = platform_get_drvdata(pdev);
 
-	if (!hdmi_ctrl) {
+	if (!hdmi_ctrl || !ops) {
 		DEV_ERR("%s: invalid input\n", __func__);
 		return -ENODEV;
 	}
@@ -1983,15 +2060,15 @@
 
 	hdmi_tx_core_off(hdmi_ctrl);
 
-	mutex_lock(&hdmi_ctrl->mutex);
-	hdmi_ctrl->panel_power_on = false;
-	mutex_unlock(&hdmi_ctrl->mutex);
-
 	if (hdmi_ctrl->hpd_off_pending) {
 		hdmi_tx_hpd_off(hdmi_ctrl);
 		hdmi_ctrl->hpd_off_pending = false;
 	}
 
+	mutex_lock(&hdmi_ctrl->mutex);
+	hdmi_ctrl->panel_power_on = false;
+	mutex_unlock(&hdmi_ctrl->mutex);
+
 	DEV_INFO("%s: HDMI Core: OFF\n", __func__);
 } /* hdmi_tx_power_off_work */
 
@@ -2349,6 +2426,22 @@
 		event, hdmi_ctrl->panel_suspend, hdmi_ctrl->hpd_feature_on);
 
 	switch (event) {
+	case MDSS_EVENT_FB_REGISTERED:
+		rc = hdmi_tx_sysfs_create(hdmi_ctrl, arg);
+		if (rc) {
+			DEV_ERR("%s: hdmi_tx_sysfs_create failed.rc=%d\n",
+					__func__, rc);
+			return rc;
+		}
+		rc = hdmi_tx_init_features(hdmi_ctrl);
+		if (rc) {
+			DEV_ERR("%s: init_features failed.rc=%d\n",
+					__func__, rc);
+			hdmi_tx_sysfs_remove(hdmi_ctrl);
+			return rc;
+		}
+		break;
+
 	case MDSS_EVENT_CHECK_PARAMS:
 		new_vic = hdmi_tx_get_vic_from_panel_info(hdmi_ctrl,
 			(struct mdss_panel_info *)arg);
@@ -2369,6 +2462,10 @@
 		break;
 
 	case MDSS_EVENT_RESUME:
+		/* If a suspend is already underway, wait for it to finish */
+		if (hdmi_ctrl->panel_suspend && hdmi_ctrl->panel_power_on)
+			flush_work(&hdmi_ctrl->power_off_work);
+
 		if (hdmi_ctrl->hpd_feature_on) {
 			INIT_COMPLETION(hdmi_ctrl->hpd_done);
 
@@ -2417,6 +2514,7 @@
 				DEV_ERR("%s: hdcp auth failed. rc=%d\n",
 					__func__, rc);
 		}
+		hdmi_ctrl->timing_gen_on = true;
 		break;
 
 	case MDSS_EVENT_SUSPEND:
@@ -2444,6 +2542,7 @@
 		break;
 
 	case MDSS_EVENT_TIMEGEN_OFF:
+		hdmi_ctrl->timing_gen_on = false;
 		break;
 
 	case MDSS_EVENT_CLOSE:
@@ -2475,7 +2574,7 @@
 		return rc;
 	}
 
-	rc = mdss_register_panel(&hdmi_ctrl->panel_data);
+	rc = mdss_register_panel(hdmi_ctrl->pdev, &hdmi_ctrl->panel_data);
 	if (rc) {
 		DEV_ERR("%s: FAILED: to register HDMI panel\n", __func__);
 		return rc;
@@ -3074,26 +3173,13 @@
 		goto failed_reg_panel;
 	}
 
-	rc = hdmi_tx_sysfs_create(hdmi_ctrl);
-	if (rc) {
-		DEV_ERR("%s: hdmi_tx_sysfs_create failed.rc=%d\n",
-			__func__, rc);
-		goto failed_reg_panel;
-	}
-
-	rc = hdmi_tx_init_features(hdmi_ctrl);
-	if (rc) {
-		DEV_ERR("%s: init_features failed.rc=%d\n", __func__, rc);
-		goto failed_init_features;
-	}
-
 	rc = of_platform_populate(of_node, NULL, NULL, &pdev->dev);
 	if (rc) {
-		DEV_ERR("%s: failed to add child devices, rc=%d\n",
+		DEV_ERR("%s: Failed to add child devices. rc=%d\n",
 			__func__, rc);
 		goto failed_init_features;
 	} else {
-		DEV_DBG("%s: added child devices.\n", __func__);
+		DEV_DBG("%s: Add child devices.\n", __func__);
 	}
 
 	return rc;
diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.h b/drivers/video/msm/mdss/mdss_hdmi_tx.h
index f78ce9f..06ae427 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.h
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -58,6 +58,8 @@
 	u32 hpd_off_pending;
 	u32 hpd_feature_on;
 	u32 hpd_initialized;
+	u8  timing_gen_on;
+	u32 mhl_max_pclk;
 	struct completion hpd_done;
 	struct work_struct hpd_int_work;
 
diff --git a/drivers/video/msm/mdss/mdss_hdmi_util.c b/drivers/video/msm/mdss/mdss_hdmi_util.c
index ad63605..07c2336 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_util.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_util.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -34,6 +34,16 @@
 	}
 } /* hdmi_init_supported_video_timings */
 
+void hdmi_del_supported_mode(u32 mode)
+{
+	struct hdmi_disp_mode_timing_type *ret = NULL;
+	DEV_DBG("%s: removing %s\n", __func__,
+		 hdmi_get_video_fmt_2string(mode));
+	ret = &hdmi_supported_video_mode_lut[mode];
+	if (ret != NULL && ret->supported)
+		ret->supported = false;
+}
+
 const struct hdmi_disp_mode_timing_type *hdmi_get_supported_mode(u32 mode)
 {
 	const struct hdmi_disp_mode_timing_type *ret = NULL;
diff --git a/drivers/video/msm/mdss/mdss_hdmi_util.h b/drivers/video/msm/mdss/mdss_hdmi_util.h
index d79b6e7..914aac1 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_util.h
+++ b/drivers/video/msm/mdss/mdss_hdmi_util.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -430,6 +430,7 @@
 int hdmi_get_video_id_code(struct hdmi_disp_mode_timing_type *timing_in);
 const struct hdmi_disp_mode_timing_type *hdmi_get_supported_mode(u32 mode);
 void hdmi_set_supported_mode(u32 mode);
+void hdmi_del_supported_mode(u32 mode);
 const char *hdmi_get_video_fmt_2string(u32 format);
 ssize_t hdmi_get_video_3d_fmt_2string(u32 format, char *buf);
 
diff --git a/drivers/video/msm/mdss/mdss_io_util.c b/drivers/video/msm/mdss/mdss_io_util.c
index 2bf2d74..c38eaa4 100644
--- a/drivers/video/msm/mdss/mdss_io_util.c
+++ b/drivers/video/msm/mdss/mdss_io_util.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/video/msm/mdss/mdss_io_util.h b/drivers/video/msm/mdss/mdss_io_util.h
index 85826f7..0ae62a3 100644
--- a/drivers/video/msm/mdss/mdss_io_util.h
+++ b/drivers/video/msm/mdss/mdss_io_util.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index 7ca06ff..e4099ad 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -1,7 +1,7 @@
 /*
  * MDSS MDP Interface (used by framebuffer core)
  *
- * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2013, The Linux Foundation. All rights reserved.
  * Copyright (C) 2007 Google Incorporated
  *
  * This software is licensed under the terms of the GNU General Public
@@ -27,6 +27,7 @@
 #include <linux/iommu.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/pm.h>
 #include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
 #include <linux/memory_alloc.h>
@@ -53,28 +54,11 @@
 
 struct mdss_data_type *mdss_res;
 
+#define IB_QUOTA 800000000
+#define AB_QUOTA 800000000
+
 static DEFINE_SPINLOCK(mdp_lock);
 static DEFINE_MUTEX(mdp_clk_lock);
-static DEFINE_MUTEX(mdp_suspend_mutex);
-
-u32 mdss_mdp_pipe_type_map[MDSS_MDP_MAX_SSPP] = {
-	MDSS_MDP_PIPE_TYPE_VIG,
-	MDSS_MDP_PIPE_TYPE_VIG,
-	MDSS_MDP_PIPE_TYPE_VIG,
-	MDSS_MDP_PIPE_TYPE_RGB,
-	MDSS_MDP_PIPE_TYPE_RGB,
-	MDSS_MDP_PIPE_TYPE_RGB,
-	MDSS_MDP_PIPE_TYPE_DMA,
-	MDSS_MDP_PIPE_TYPE_DMA,
-};
-
-u32 mdss_mdp_mixer_type_map[MDSS_MDP_MAX_LAYERMIXER] = {
-	MDSS_MDP_MIXER_TYPE_INTF,
-	MDSS_MDP_MIXER_TYPE_INTF,
-	MDSS_MDP_MIXER_TYPE_INTF,
-	MDSS_MDP_MIXER_TYPE_WRITEBACK,
-	MDSS_MDP_MIXER_TYPE_WRITEBACK,
-};
 
 #define MDP_BUS_VECTOR_ENTRY(ab_val, ib_val)		\
 	{						\
@@ -130,7 +114,16 @@
 static DEFINE_SPINLOCK(mdss_lock);
 struct mdss_hw *mdss_irq_handlers[MDSS_MAX_HW_BLK];
 
-static int mdss_mdp_register_early_suspend(struct mdss_data_type *mdata);
+static void mdss_mdp_footswitch_ctrl(struct mdss_data_type *mdata, int on);
+static int mdss_mdp_parse_dt(struct platform_device *pdev);
+static int mdss_mdp_parse_dt_pipe(struct platform_device *pdev);
+static int mdss_mdp_parse_dt_mixer(struct platform_device *pdev);
+static int mdss_mdp_parse_dt_ctl(struct platform_device *pdev);
+static int mdss_mdp_parse_dt_video_intf(struct platform_device *pdev);
+static int mdss_mdp_parse_dt_handler(struct platform_device *pdev,
+				      char *prop_name, u32 *offsets, int len);
+static int mdss_mdp_parse_dt_prop_len(struct platform_device *pdev,
+				       char *prop_name);
 
 static inline int mdss_irq_dispatch(u32 hw_ndx, int irq, void *ptr)
 {
@@ -524,15 +517,19 @@
 	return clk_rate;
 }
 
-static void mdss_mdp_clk_ctrl_update(int enable)
+static void mdss_mdp_clk_ctrl_update(struct mdss_data_type *mdata)
 {
-	if (mdss_res->clk_ena == enable)
-		return;
-
-	pr_debug("MDP CLKS %s\n", (enable ? "Enable" : "Disable"));
+	int enable;
 
 	mutex_lock(&mdp_clk_lock);
-	mdss_res->clk_ena = enable;
+	enable = atomic_read(&mdata->clk_ref) > 0;
+	if (mdata->clk_ena == enable) {
+		mutex_unlock(&mdp_clk_lock);
+		return;
+	}
+	mdata->clk_ena = enable;
+
+	pr_debug("MDP CLKS %s\n", (enable ? "Enable" : "Disable"));
 	mb();
 
 	mdss_mdp_clk_update(MDSS_CLK_AHB, enable);
@@ -540,7 +537,7 @@
 
 	mdss_mdp_clk_update(MDSS_CLK_MDP_CORE, enable);
 	mdss_mdp_clk_update(MDSS_CLK_MDP_LUT, enable);
-	if (mdss_res->vsync_ena)
+	if (mdata->vsync_ena)
 		mdss_mdp_clk_update(MDSS_CLK_MDP_VSYNC, enable);
 
 	mutex_unlock(&mdp_clk_lock);
@@ -548,65 +545,37 @@
 
 static void mdss_mdp_clk_ctrl_workqueue_handler(struct work_struct *work)
 {
-	mdss_mdp_clk_ctrl(MDP_BLOCK_MASTER_OFF, false);
+	struct mdss_data_type *mdata;
+
+	mdata = container_of(work, struct mdss_data_type, clk_ctrl_worker);
+	mdss_mdp_clk_ctrl_update(mdata);
 }
 
 void mdss_mdp_clk_ctrl(int enable, int isr)
 {
-	static atomic_t clk_ref = ATOMIC_INIT(0);
-	static DEFINE_MUTEX(clk_ctrl_lock);
-	int force_off = 0;
+	struct mdss_data_type *mdata = mdss_res;
 
-	pr_debug("clk enable=%d isr=%d clk_ref=%d\n", enable, isr,
-			atomic_read(&clk_ref));
-	/*
-	 * It is assumed that if isr = TRUE then start = OFF
-	 * if start = ON when isr = TRUE it could happen that the usercontext
-	 * could turn off the clocks while the interrupt is updating the
-	 * power to ON
-	 */
-	WARN_ON(isr == true && enable);
+	pr_debug("clk enable=%d isr=%d ref= %d\n", enable, isr,
+			atomic_read(&mdata->clk_ref));
 
 	if (enable == MDP_BLOCK_POWER_ON) {
-		atomic_inc(&clk_ref);
-	} else if (!atomic_add_unless(&clk_ref, -1, 0)) {
-		if (enable == MDP_BLOCK_MASTER_OFF) {
-			pr_debug("master power-off req\n");
-			force_off = 1;
-		} else {
-			WARN(1, "too many mdp clock off call\n");
-		}
-	}
+		BUG_ON(isr);
 
-	WARN_ON(enable == MDP_BLOCK_MASTER_OFF && !force_off);
-
-	if (isr) {
-		/* if it's power off send workqueue to turn off clocks */
-		if (mdss_res->clk_ena && !atomic_read(&clk_ref))
-			queue_delayed_work(mdss_res->clk_ctrl_wq,
-					   &mdss_res->clk_ctrl_worker,
-					   mdss_res->timeout);
+		if (atomic_inc_return(&mdata->clk_ref) == 1)
+			mdss_mdp_clk_ctrl_update(mdata);
 	} else {
-		mutex_lock(&clk_ctrl_lock);
-		if (delayed_work_pending(&mdss_res->clk_ctrl_worker))
-			cancel_delayed_work(&mdss_res->clk_ctrl_worker);
+		BUG_ON(atomic_read(&mdata->clk_ref) == 0);
 
-		if (atomic_read(&clk_ref)) {
-			mdss_mdp_clk_ctrl_update(true);
-		} else if (mdss_res->clk_ena) {
-			mutex_lock(&mdp_suspend_mutex);
-			if (force_off || mdss_res->suspend) {
-				mdss_mdp_clk_ctrl_update(false);
-			} else {
-				/* send workqueue to turn off mdp power */
-				queue_delayed_work(mdss_res->clk_ctrl_wq,
-						   &mdss_res->clk_ctrl_worker,
-						   mdss_res->timeout);
-			}
-			mutex_unlock(&mdp_suspend_mutex);
+		if (atomic_dec_and_test(&mdata->clk_ref)) {
+			if (isr)
+				queue_work(mdata->clk_ctrl_wq,
+						&mdata->clk_ctrl_worker);
+			else
+				mdss_mdp_clk_ctrl_update(mdata);
 		}
-		mutex_unlock(&clk_ctrl_lock);
 	}
+
+
 }
 
 static inline int mdss_mdp_irq_clk_register(struct mdss_data_type *mdata,
@@ -646,8 +615,7 @@
 		pr_err("unable to get gdsc regulator\n");
 		return -EINVAL;
 	}
-	regulator_enable(mdata->fs);
-	mdata->fs_ena = true;
+	mdata->fs_ena = false;
 
 	if (mdss_mdp_irq_clk_register(mdata, "bus_clk", MDSS_CLK_AXI) ||
 	    mdss_mdp_irq_clk_register(mdata, "iface_clk", MDSS_CLK_AHB) ||
@@ -679,7 +647,7 @@
 	int i;
 
 	if (mdata->iommu_attached) {
-		pr_warn("mdp iommu already attached\n");
+		pr_debug("mdp iommu already attached\n");
 		return 0;
 	}
 
@@ -707,7 +675,7 @@
 	int i;
 
 	if (!mdata->iommu_attached) {
-		pr_warn("mdp iommu already dettached\n");
+		pr_debug("mdp iommu already dettached\n");
 		return 0;
 	}
 
@@ -786,22 +754,33 @@
 	return 0;
 }
 
-static int mdss_hw_init(struct mdss_data_type *mdata)
+int mdss_hw_init(struct mdss_data_type *mdata)
 {
-	char *base = mdata->vbif_base;
+	int i, j;
+	char *offset;
 
 	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
-	/* Setup VBIF QoS settings*/
-	MDSS_MDP_REG_WRITE(0x2E0, 0x000000AA);
-	MDSS_MDP_REG_WRITE(0x2E4, 0x00000055);
-	writel_relaxed(0x00000001, base + 0x004);
-	writel_relaxed(0x00000707, base + 0x0D8);
-	writel_relaxed(0x00000030, base + 0x0F0);
-	writel_relaxed(0x00000001, base + 0x124);
-	writel_relaxed(0x00000FFF, base + 0x178);
-	writel_relaxed(0x0FFF0FFF, base + 0x17C);
-	writel_relaxed(0x22222222, base + 0x160);
-	writel_relaxed(0x00002222, base + 0x164);
+	mdata->mdp_rev = MDSS_MDP_REG_READ(MDSS_MDP_REG_HW_VERSION);
+	pr_info_once("MDP Rev=%x\n", mdata->mdp_rev);
+
+	if (mdata->hw_settings) {
+		struct mdss_hw_settings *hws = mdata->hw_settings;
+
+		while (hws->reg) {
+			writel_relaxed(hws->val, hws->reg);
+			hws++;
+		}
+	}
+
+	for (i = 0; i < mdata->nmixers_intf; i++) {
+		offset = mdata->mixer_intf[i].dspp_base +
+				MDSS_MDP_REG_DSPP_HIST_LUT_BASE;
+		for (j = 0; j < ENHIST_LUT_ENTRIES; j++)
+			writel_relaxed(j, offset);
+
+		/* swap */
+		writel_relaxed(i, offset + 4);
+	}
 	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
 	pr_debug("MDP hw init done\n");
 
@@ -812,34 +791,26 @@
 {
 	u32 rc = 0;
 
+	if (mdata->res_init) {
+		pr_err("mdss resources already initialized\n");
+		return -EPERM;
+	}
+
+	mdata->res_init = true;
+	mdata->clk_ena = false;
+	mdata->irq_mask = MDSS_MDP_DEFAULT_INTR_MASK;
+	mdata->irq_ena = false;
+
 	rc = mdss_mdp_irq_clk_setup(mdata);
 	if (rc)
 		return rc;
 
 	mdata->clk_ctrl_wq = create_singlethread_workqueue("mdp_clk_wq");
-	INIT_DELAYED_WORK(&mdata->clk_ctrl_worker,
-			  mdss_mdp_clk_ctrl_workqueue_handler);
-
-	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
-	mdata->rev = MDSS_MDP_REG_READ(MDSS_REG_HW_VERSION);
-	mdata->mdp_rev = MDSS_MDP_REG_READ(MDSS_MDP_REG_HW_VERSION);
-	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+	INIT_WORK(&mdata->clk_ctrl_worker, mdss_mdp_clk_ctrl_workqueue_handler);
 
 	mdata->smp_mb_cnt = MDSS_MDP_SMP_MMB_BLOCKS;
 	mdata->smp_mb_size = MDSS_MDP_SMP_MMB_SIZE;
-	mdata->pipe_type_map = mdss_mdp_pipe_type_map;
-	mdata->mixer_type_map = mdss_mdp_mixer_type_map;
 
-	pr_info("mdss_revision=%x\n", mdata->rev);
-	pr_info("mdp_hw_revision=%x\n", mdata->mdp_rev);
-
-	mdata->res_init = true;
-	mdata->timeout = HZ/20;
-	mdata->clk_ena = false;
-	mdata->irq_mask = MDSS_MDP_DEFAULT_INTR_MASK;
-	mdata->suspend = false;
-	mdata->prim_ptype = NO_PANEL;
-	mdata->irq_ena = false;
 
 	mdata->iclient = msm_ion_client_create(-1, mdata->pdev->name);
 	if (IS_ERR_OR_NULL(mdata->iclient)) {
@@ -849,14 +820,25 @@
 	}
 
 	rc = mdss_iommu_init(mdata);
-	if (!IS_ERR_VALUE(rc))
-		mdss_iommu_attach(mdata);
-
-	rc = mdss_hw_init(mdata);
 
 	return rc;
 }
 
+void mdss_mdp_footswitch_ctrl_splash(int on)
+{
+	if (mdss_res != NULL) {
+		if (on) {
+			pr_debug("Enable MDP FS for splash.\n");
+			regulator_enable(mdss_res->fs);
+		} else {
+			pr_debug("Disable MDP FS for splash.\n");
+			regulator_disable(mdss_res->fs);
+		}
+	} else {
+		pr_warn("mdss mdata not initialized\n");
+	}
+}
+
 static int mdss_mdp_probe(struct platform_device *pdev)
 {
 	struct resource *res;
@@ -927,6 +909,13 @@
 	}
 	mdata->irq = res->start;
 
+	/*populate hw iomem base info from device tree*/
+	rc = mdss_mdp_parse_dt(pdev);
+	if (rc) {
+		pr_err("unable to parse device tree\n");
+		goto probe_done;
+	}
+
 	rc = mdss_mdp_res_init(mdata);
 	if (rc) {
 		pr_err("unable to initialize mdss mdp resources\n");
@@ -942,16 +931,18 @@
 		pr_err("unable to register bus scaling\n");
 		goto probe_done;
 	}
+	mdss_mdp_bus_scale_set_quota(AB_QUOTA, IB_QUOTA);
 
-	rc = mdss_mdp_register_early_suspend(mdata);
+	rc = mdss_mdp_debug_init(mdata);
 	if (rc) {
-		pr_err("unable to register early suspend\n");
+		pr_err("unable to initialize mdp debugging\n");
 		goto probe_done;
 	}
 
-	rc = mdss_mdp_debug_init(mdata);
-	if (rc)
-		pr_err("unable to initialize mdp debugging\n");
+	pm_runtime_set_suspended(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+	if (!pm_runtime_enabled(&pdev->dev))
+		mdss_mdp_footswitch_ctrl(mdata, true);
 
 probe_done:
 	if (IS_ERR_VALUE(rc)) {
@@ -962,78 +953,465 @@
 	return rc;
 }
 
-static void mdss_mdp_footswitch_ctrl(struct mdss_data_type *mdata, int on)
+static void mdss_mdp_parse_dt_regs_array(const u32 *arr, char __iomem *hw_base,
+	struct mdss_hw_settings *hws, int count)
 {
-	mutex_lock(&mdp_suspend_mutex);
-	if (!mdata->suspend || mdata->eintf_ena || !mdata->fs) {
-		mutex_unlock(&mdp_suspend_mutex);
+	u32 len, reg;
+	int i;
+
+	if (!arr)
 		return;
+
+	for (i = 0, len = count * 2; i < len; i += 2) {
+		reg = be32_to_cpu(arr[i]);
+		hws->reg = hw_base + reg;
+		hws->val = be32_to_cpu(arr[i + 1]);
+		pr_debug("reg: 0x%04x=0x%08x\n", reg, hws->val);
+		hws++;
+	}
+}
+
+int mdss_mdp_parse_dt_hw_settings(struct platform_device *pdev)
+{
+	struct mdss_data_type *mdata = platform_get_drvdata(pdev);
+	struct mdss_hw_settings *hws;
+	const u32 *vbif_arr, *mdp_arr;
+	int vbif_len, mdp_len;
+
+	vbif_arr = of_get_property(pdev->dev.of_node, "qcom,vbif-settings",
+			&vbif_len);
+	if (!vbif_arr || (mdp_len & 1)) {
+		pr_warn("MDSS VBIF settings not found\n");
+		vbif_len = 0;
+	}
+	vbif_len /= 2 * sizeof(u32);
+
+	mdp_arr = of_get_property(pdev->dev.of_node, "qcom,mdp-settings",
+			&mdp_len);
+	if (!mdp_arr || (mdp_len & 1)) {
+		pr_warn("MDSS MDP settings not found\n");
+		mdp_len = 0;
+	}
+	mdp_len /= 2 * sizeof(u32);
+
+	if ((mdp_len + vbif_len) == 0)
+		return 0;
+
+	hws = devm_kzalloc(&pdev->dev, sizeof(*hws) * (vbif_len + mdp_len + 1),
+			GFP_KERNEL);
+	if (!hws)
+		return -ENOMEM;
+
+	mdss_mdp_parse_dt_regs_array(vbif_arr, mdata->vbif_base, hws, vbif_len);
+	mdss_mdp_parse_dt_regs_array(mdp_arr, mdata->mdp_base,
+		hws + vbif_len, mdp_len);
+
+	mdata->hw_settings = hws;
+
+	return 0;
+}
+
+static int mdss_mdp_parse_dt(struct platform_device *pdev)
+{
+	int rc;
+
+	rc = mdss_mdp_parse_dt_hw_settings(pdev);
+	if (rc) {
+		pr_err("Error in device tree : hw settings\n");
+		return rc;
 	}
 
-	if (on && !mdata->fs_ena) {
+	rc = mdss_mdp_parse_dt_pipe(pdev);
+	if (rc) {
+		pr_err("Error in device tree : pipes\n");
+		return rc;
+	}
+
+	rc = mdss_mdp_parse_dt_mixer(pdev);
+	if (rc) {
+		pr_err("Error in device tree : mixers\n");
+		return rc;
+	}
+
+	rc = mdss_mdp_parse_dt_ctl(pdev);
+	if (rc) {
+		pr_err("Error in device tree : ctl\n");
+		return rc;
+	}
+
+	rc = mdss_mdp_parse_dt_video_intf(pdev);
+	if (rc) {
+		pr_err("Error in device tree : ctl\n");
+		return rc;
+	}
+
+	return 0;
+}
+
+
+static int mdss_mdp_parse_dt_pipe(struct platform_device *pdev)
+{
+	u32 npipes, off;
+	int rc = 0;
+	u32 nids = 0;
+	u32 *offsets = NULL, *ftch_id = NULL;
+
+	struct mdss_data_type *mdata = platform_get_drvdata(pdev);
+
+	mdata->nvig_pipes = mdss_mdp_parse_dt_prop_len(pdev,
+				"qcom,mdss-pipe-vig-off");
+	mdata->nrgb_pipes = mdss_mdp_parse_dt_prop_len(pdev,
+				"qcom,mdss-pipe-rgb-off");
+	mdata->ndma_pipes = mdss_mdp_parse_dt_prop_len(pdev,
+				"qcom,mdss-pipe-dma-off");
+
+	nids  += mdss_mdp_parse_dt_prop_len(pdev,
+			"qcom,mdss-pipe-vig-fetch-id");
+	nids  += mdss_mdp_parse_dt_prop_len(pdev,
+			"qcom,mdss-pipe-rgb-fetch-id");
+	nids  += mdss_mdp_parse_dt_prop_len(pdev,
+			"qcom,mdss-pipe-dma-fetch-id");
+
+	npipes = mdata->nvig_pipes + mdata->nrgb_pipes + mdata->ndma_pipes;
+
+	if (npipes != nids) {
+		pr_err("device tree err: unequal number of pipes and smp ids");
+		return -EINVAL;
+	}
+
+	offsets = kzalloc(sizeof(u32) * npipes, GFP_KERNEL);
+	if (!offsets) {
+		pr_err("no mem assigned: kzalloc fail\n");
+		return -ENOMEM;
+	}
+
+	ftch_id = kzalloc(sizeof(u32) * nids, GFP_KERNEL);
+	if (!ftch_id) {
+		pr_err("no mem assigned: kzalloc fail\n");
+		rc = -ENOMEM;
+		goto ftch_alloc_fail;
+	}
+
+	rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-vig-fetch-id",
+		ftch_id, mdata->nvig_pipes);
+	if (rc)
+		goto parse_done;
+
+	rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-vig-off",
+		offsets, mdata->nvig_pipes);
+	if (rc)
+		goto parse_done;
+
+	rc = mdss_mdp_pipe_addr_setup(mdata, offsets, ftch_id,
+		MDSS_MDP_PIPE_TYPE_VIG, MDSS_MDP_SSPP_VIG0, mdata->nvig_pipes);
+	if (rc)
+		goto parse_done;
+
+	rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-rgb-fetch-id",
+		ftch_id + mdata->nvig_pipes, mdata->nrgb_pipes);
+	if (rc)
+		goto parse_done;
+
+	rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-rgb-off",
+		offsets + mdata->nvig_pipes, mdata->nrgb_pipes);
+	if (rc)
+		goto parse_done;
+
+	rc = mdss_mdp_pipe_addr_setup(mdata, offsets + mdata->nvig_pipes,
+		ftch_id + mdata->nvig_pipes, MDSS_MDP_PIPE_TYPE_RGB,
+		MDSS_MDP_SSPP_RGB0, mdata->nrgb_pipes);
+	if (rc)
+		goto parse_done;
+
+	off = mdata->nvig_pipes + mdata->nrgb_pipes;
+
+	rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-dma-fetch-id",
+		ftch_id + off, mdata->ndma_pipes);
+	if (rc)
+		goto parse_done;
+
+	rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-dma-off",
+		offsets + off, mdata->ndma_pipes);
+	if (rc)
+		goto parse_done;
+
+	rc = mdss_mdp_pipe_addr_setup(mdata, offsets + off, ftch_id + off,
+		MDSS_MDP_PIPE_TYPE_DMA, MDSS_MDP_SSPP_DMA0, mdata->ndma_pipes);
+	if (rc)
+		goto parse_done;
+
+parse_done:
+	kfree(ftch_id);
+ftch_alloc_fail:
+	kfree(offsets);
+	return rc;
+}
+
+static int mdss_mdp_parse_dt_mixer(struct platform_device *pdev)
+{
+
+	u32 nmixers, ndspp;
+	int rc = 0;
+	u32 *mixer_offsets = NULL, *dspp_offsets = NULL;
+
+	struct mdss_data_type *mdata = platform_get_drvdata(pdev);
+
+	mdata->nmixers_intf = mdss_mdp_parse_dt_prop_len(pdev,
+				"qcom,mdss-mixer-intf-off");
+	mdata->nmixers_wb = mdss_mdp_parse_dt_prop_len(pdev,
+				"qcom,mdss-mixer-wb-off");
+	ndspp = mdss_mdp_parse_dt_prop_len(pdev,
+				"qcom,mdss-dspp-off");
+	nmixers = mdata->nmixers_intf + mdata->nmixers_wb;
+
+	if (mdata->nmixers_intf != ndspp) {
+		pr_err("device tree err: unequal no of dspp and intf mixers\n");
+		return -EINVAL;
+	}
+
+	mixer_offsets = kzalloc(sizeof(u32) * nmixers, GFP_KERNEL);
+	if (!mixer_offsets) {
+		pr_err("no mem assigned: kzalloc fail\n");
+		return -ENOMEM;
+	}
+
+	dspp_offsets = kzalloc(sizeof(u32) * ndspp, GFP_KERNEL);
+	if (!dspp_offsets) {
+		pr_err("no mem assigned: kzalloc fail\n");
+		rc = -ENOMEM;
+		goto dspp_alloc_fail;
+	}
+
+	rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-mixer-intf-off",
+		mixer_offsets, mdata->nmixers_intf);
+	if (rc)
+		goto parse_done;
+
+	rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-mixer-wb-off",
+		mixer_offsets + mdata->nmixers_intf, mdata->nmixers_wb);
+	if (rc)
+		goto parse_done;
+
+	rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-dspp-off",
+		dspp_offsets, ndspp);
+	if (rc)
+		goto parse_done;
+
+	rc = mdss_mdp_mixer_addr_setup(mdata, mixer_offsets,
+			dspp_offsets, MDSS_MDP_MIXER_TYPE_INTF,
+			mdata->nmixers_intf);
+	if (rc)
+		goto parse_done;
+
+	rc = mdss_mdp_mixer_addr_setup(mdata, mixer_offsets +
+			mdata->nmixers_intf, NULL,
+			MDSS_MDP_MIXER_TYPE_WRITEBACK, mdata->nmixers_wb);
+	if (rc)
+		goto parse_done;
+
+parse_done:
+	kfree(dspp_offsets);
+dspp_alloc_fail:
+	kfree(mixer_offsets);
+
+	return rc;
+}
+
+static int mdss_mdp_parse_dt_ctl(struct platform_device *pdev)
+{
+	u32 nwb;
+	int rc = 0;
+	u32 *ctl_offsets = NULL, *wb_offsets = NULL;
+
+	struct mdss_data_type *mdata = platform_get_drvdata(pdev);
+
+	mdata->nctl = mdss_mdp_parse_dt_prop_len(pdev,
+			"qcom,mdss-ctl-off");
+	nwb =  mdss_mdp_parse_dt_prop_len(pdev,
+			"qcom,mdss-wb-off");
+
+	if (mdata->nctl != nwb) {
+		pr_err("device tree err: unequal number of ctl and wb\n");
+		rc = -EINVAL;
+		goto parse_done;
+	}
+
+	ctl_offsets = kzalloc(sizeof(u32) * mdata->nctl, GFP_KERNEL);
+	if (!ctl_offsets) {
+		pr_err("no more mem for ctl offsets\n");
+		return -ENOMEM;
+	}
+
+	wb_offsets = kzalloc(sizeof(u32) * nwb, GFP_KERNEL);
+	if (!wb_offsets) {
+		pr_err("no more mem for writeback offsets\n");
+		rc = -ENOMEM;
+		goto wb_alloc_fail;
+	}
+
+	rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-ctl-off",
+		ctl_offsets, mdata->nctl);
+	if (rc)
+		goto parse_done;
+
+	rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-wb-off",
+		wb_offsets, nwb);
+	if (rc)
+		goto parse_done;
+
+	rc = mdss_mdp_ctl_addr_setup(mdata, ctl_offsets, wb_offsets,
+						 mdata->nctl);
+	if (rc)
+		goto parse_done;
+
+parse_done:
+	kfree(wb_offsets);
+wb_alloc_fail:
+	kfree(ctl_offsets);
+
+	return rc;
+}
+
+static int mdss_mdp_parse_dt_video_intf(struct platform_device *pdev)
+{
+	struct mdss_data_type *mdata = platform_get_drvdata(pdev);
+	u32 count;
+	u32 *offsets;
+	int rc;
+
+
+	count = mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-intf-off");
+	if (count == 0)
+		return -EINVAL;
+
+	offsets = kzalloc(sizeof(u32) * count, GFP_KERNEL);
+	if (!offsets) {
+		pr_err("no mem assigned for video intf\n");
+		return -ENOMEM;
+	}
+
+	rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-intf-off",
+			offsets, count);
+	if (rc)
+		goto parse_fail;
+
+	rc = mdss_mdp_video_addr_setup(mdata, offsets, count);
+	if (rc)
+		pr_err("unable to setup video interfaces\n");
+
+parse_fail:
+	kfree(offsets);
+
+	return rc;
+}
+
+static int mdss_mdp_parse_dt_handler(struct platform_device *pdev,
+		char *prop_name, u32 *offsets, int len)
+{
+	int rc;
+	rc = of_property_read_u32_array(pdev->dev.of_node, prop_name,
+					offsets, len);
+	if (rc) {
+		pr_err("Error from prop %s : u32 array read\n", prop_name);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int mdss_mdp_parse_dt_prop_len(struct platform_device *pdev,
+				      char *prop_name)
+{
+	int len = 0;
+
+	of_find_property(pdev->dev.of_node, prop_name, &len);
+
+	if (len < 1) {
+		pr_err("Error from prop %s : spec error in device tree\n",
+		       prop_name);
+		return 0;
+	}
+
+	len = len/sizeof(u32);
+
+	return len;
+}
+
+struct mdss_data_type *mdss_mdp_get_mdata()
+{
+	return mdss_res;
+}
+
+static void mdss_mdp_footswitch_ctrl(struct mdss_data_type *mdata, int on)
+{
+	if (!mdata->fs)
+		return;
+
+	if (on) {
 		pr_debug("Enable MDP FS\n");
-		regulator_enable(mdata->fs);
-		mdss_iommu_attach(mdata);
+		if (!mdata->fs_ena)
+			regulator_enable(mdata->fs);
 		mdata->fs_ena = true;
-	} else if (!on && mdata->fs_ena) {
+	} else {
 		pr_debug("Disable MDP FS\n");
 		mdss_iommu_dettach(mdata);
-		regulator_disable(mdata->fs);
+		if (mdata->fs_ena)
+			regulator_disable(mdata->fs);
 		mdata->fs_ena = false;
 	}
-	mutex_unlock(&mdp_suspend_mutex);
 }
 
 static inline int mdss_mdp_suspend_sub(struct mdss_data_type *mdata)
 {
-	int ret;
-
-	ret = mdss_fb_suspend_all();
-	if (IS_ERR_VALUE(ret)) {
-		pr_err("Unable to suspend all fb panels (%d)\n", ret);
-		return ret;
-	}
-
-	cancel_delayed_work(&mdata->clk_ctrl_worker);
-
 	flush_workqueue(mdata->clk_ctrl_wq);
 
-	mdss_mdp_clk_ctrl(MDP_BLOCK_MASTER_OFF, false);
-
-	mutex_lock(&mdp_suspend_mutex);
-	mdata->suspend = true;
-	mutex_unlock(&mdp_suspend_mutex);
-
-	if (mdata->clk_ena) {
-		pr_err("MDP suspend failed\n");
-		return -EBUSY;
-	}
+	mdata->suspend_fs_ena = mdata->fs_ena;
 	mdss_mdp_footswitch_ctrl(mdata, false);
 
-	pr_debug("suspend done\n");
+	pr_debug("suspend done fs=%d\n", mdata->suspend_fs_ena);
 
 	return 0;
 }
 
 static inline int mdss_mdp_resume_sub(struct mdss_data_type *mdata)
 {
-	int ret = 0;
+	if (mdata->suspend_fs_ena)
+		mdss_mdp_footswitch_ctrl(mdata, true);
 
-	mdss_mdp_footswitch_ctrl(mdata, true);
-	mutex_lock(&mdp_suspend_mutex);
-	mdata->suspend = false;
-	mutex_unlock(&mdp_suspend_mutex);
-	mdss_hw_init(mdata);
-	ret = mdss_fb_resume_all();
-	if (IS_ERR_VALUE(ret))
-		pr_err("Unable to resume all fb panels (%d)\n", ret);
+	pr_debug("resume done fs=%d\n", mdata->suspend_fs_ena);
 
-	pr_debug("resume done\n");
-
-	return ret;
+	return 0;
 }
 
-#if defined(CONFIG_PM) && !defined(CONFIG_HAS_EARLYSUSPEND)
+#ifdef CONFIG_PM_SLEEP
+static int mdss_mdp_pm_suspend(struct device *dev)
+{
+	struct mdss_data_type *mdata;
+
+	mdata = dev_get_drvdata(dev);
+	if (!mdata)
+		return -ENODEV;
+
+	dev_dbg(dev, "display pm suspend\n");
+
+	return mdss_mdp_suspend_sub(mdata);
+}
+
+static int mdss_mdp_pm_resume(struct device *dev)
+{
+	struct mdss_data_type *mdata;
+
+	mdata = dev_get_drvdata(dev);
+	if (!mdata)
+		return -ENODEV;
+
+	dev_dbg(dev, "display pm resume\n");
+
+	return mdss_mdp_resume_sub(mdata);
+}
+#endif
+
+#if defined(CONFIG_PM) && !defined(CONFIG_PM_SLEEP)
 static int mdss_mdp_suspend(struct platform_device *pdev, pm_message_t state)
 {
 	struct mdss_data_type *mdata = platform_get_drvdata(pdev);
@@ -1041,7 +1419,7 @@
 	if (!mdata)
 		return -ENODEV;
 
-	pr_debug("display suspend\n");
+	dev_dbg(&pdev->dev, "display suspend\n");
 
 	return mdss_mdp_suspend_sub(mdata);
 }
@@ -1053,7 +1431,7 @@
 	if (!mdata)
 		return -ENODEV;
 
-	pr_debug("display resume\n");
+	dev_dbg(&pdev->dev, "display resume\n");
 
 	return mdss_mdp_resume_sub(mdata);
 }
@@ -1062,54 +1440,57 @@
 #define mdss_mdp_resume NULL
 #endif
 
-#ifdef CONFIG_HAS_EARLYSUSPEND
-static void mdss_mdp_early_suspend(struct early_suspend *h)
+#ifdef CONFIG_PM_RUNTIME
+static int mdss_mdp_runtime_resume(struct device *dev)
 {
-	struct mdss_data_type *mdata;
-	mdata = container_of(h, struct mdss_data_type, early_suspend);
+	struct mdss_data_type *mdata = dev_get_drvdata(dev);
+	if (!mdata)
+		return -ENODEV;
 
-	pr_debug("display early suspend\n");
+	dev_dbg(dev, "pm_runtime: resuming...\n");
 
-	mdss_mdp_suspend_sub(mdata);
-}
-
-static void mdss_mdp_late_resume(struct early_suspend *h)
-{
-	struct mdss_data_type *mdata;
-	mdata = container_of(h, struct mdss_data_type, early_suspend);
-
-	pr_debug("display early resume\n");
-
-	mdss_mdp_resume_sub(mdata);
-}
-
-static int mdss_mdp_register_early_suspend(struct mdss_data_type *mdata)
-{
-	mdata->early_suspend.suspend = mdss_mdp_early_suspend;
-	mdata->early_suspend.resume = mdss_mdp_late_resume;
-	mdata->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
-	register_early_suspend(&mdata->early_suspend);
+	mdss_mdp_footswitch_ctrl(mdata, true);
 
 	return 0;
 }
 
-static int mdss_mdp_remove_early_suspend(struct mdss_data_type *mdata)
+static int mdss_mdp_runtime_idle(struct device *dev)
 {
-	unregister_early_suspend(&mdata->early_suspend);
+	struct mdss_data_type *mdata = dev_get_drvdata(dev);
+	if (!mdata)
+		return -ENODEV;
+
+	dev_dbg(dev, "pm_runtime: idling...\n");
+
+	flush_workqueue(mdata->clk_ctrl_wq);
 
 	return 0;
 }
-#else
-static int mdss_mdp_register_early_suspend(struct mdss_data_type *mdata)
+
+static int mdss_mdp_runtime_suspend(struct device *dev)
 {
-	return 0;
-}
-static int mdss_mdp_remove_early_suspend(struct mdss_data_type *mdata)
-{
+	struct mdss_data_type *mdata = dev_get_drvdata(dev);
+	if (!mdata)
+		return -ENODEV;
+	dev_dbg(dev, "pm_runtime: suspending...\n");
+
+	if (mdata->clk_ena) {
+		pr_err("MDP suspend failed\n");
+		return -EBUSY;
+	}
+	mdss_mdp_footswitch_ctrl(mdata, false);
+
 	return 0;
 }
 #endif
 
+static const struct dev_pm_ops mdss_mdp_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(mdss_mdp_pm_suspend, mdss_mdp_pm_resume)
+	SET_RUNTIME_PM_OPS(mdss_mdp_runtime_suspend,
+			mdss_mdp_runtime_resume,
+			mdss_mdp_runtime_idle)
+};
+
 static int mdss_mdp_remove(struct platform_device *pdev)
 {
 	struct mdss_data_type *mdata = platform_get_drvdata(pdev);
@@ -1118,7 +1499,6 @@
 	pm_runtime_disable(&pdev->dev);
 	mdss_mdp_pp_term(&pdev->dev);
 	mdss_mdp_bus_scale_unregister(mdata);
-	mdss_mdp_remove_early_suspend(mdata);
 	mdss_debugfs_remove(mdata);
 	return 0;
 }
@@ -1128,7 +1508,6 @@
 	{}
 };
 MODULE_DEVICE_TABLE(of, mdss_mdp_dt_match);
-EXPORT_COMPAT("qcom,mdss_mdp");
 
 static struct platform_driver mdss_mdp_driver = {
 	.probe = mdss_mdp_probe,
@@ -1143,6 +1522,7 @@
 		 */
 		.name = "mdp",
 		.of_match_table = mdss_mdp_dt_match,
+		.pm = &mdss_mdp_pm_ops,
 	},
 };
 
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index d273201..e4f78ad 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -26,14 +27,12 @@
 #define MDSS_MDP_CURSOR_HEIGHT 64
 #define MDSS_MDP_CURSOR_SIZE (MDSS_MDP_CURSOR_WIDTH*MDSS_MDP_CURSOR_WIDTH*4)
 
-#define MDP_CLK_DEFAULT_RATE	37500000
+#define MDP_CLK_DEFAULT_RATE	200000000
 #define PHASE_STEP_SHIFT	21
 #define MAX_MIXER_WIDTH		2048
 #define MAX_MIXER_HEIGHT	2400
 #define MAX_IMG_WIDTH		0x3FFF
 #define MAX_IMG_HEIGHT		0x3FFF
-#define MIN_DST_W		10
-#define MIN_DST_H		10
 #define MAX_DST_W		MAX_MIXER_WIDTH
 #define MAX_DST_H		MAX_MIXER_HEIGHT
 #define MAX_PLANES		4
@@ -66,7 +65,6 @@
 #endif
 
 enum mdss_mdp_block_power_state {
-	MDP_BLOCK_MASTER_OFF = -1,
 	MDP_BLOCK_POWER_OFF = 0,
 	MDP_BLOCK_POWER_ON = 1,
 };
@@ -112,6 +110,8 @@
 
 struct mdss_mdp_ctl {
 	u32 num;
+	char __iomem *base;
+	char __iomem *wb_base;
 	u32 ref_cnt;
 	int power_on;
 
@@ -129,9 +129,10 @@
 
 	u32 bus_ab_quota;
 	u32 bus_ib_quota;
-	u32 bus_quota;
 	u32 clk_rate;
+	u32 perf_changed;
 
+	struct mdss_data_type *mdata;
 	struct msm_fb_data_type *mfd;
 	struct mdss_mdp_mixer *mixer_left;
 	struct mdss_mdp_mixer *mixer_right;
@@ -143,6 +144,7 @@
 	int (*stop_fnc) (struct mdss_mdp_ctl *ctl);
 	int (*prepare_fnc) (struct mdss_mdp_ctl *ctl, void *arg);
 	int (*display_fnc) (struct mdss_mdp_ctl *ctl, void *arg);
+	int (*wait_fnc) (struct mdss_mdp_ctl *ctl, void *arg);
 	int (*set_vsync_handler) (struct mdss_mdp_ctl *, mdp_vsync_handler_t);
 
 	void *priv_data;
@@ -151,9 +153,10 @@
 struct mdss_mdp_mixer {
 	u32 num;
 	u32 ref_cnt;
+	char __iomem *base;
+	char __iomem *dspp_base;
 	u8 type;
 	u8 params_changed;
-
 	u16 width;
 	u16 height;
 	u8 cursor_enabled;
@@ -210,10 +213,31 @@
 	struct mdss_mdp_img_data p[MAX_PLANES];
 };
 
+struct pp_sts_type {
+	u32 pa_sts;
+	u32 pcc_sts;
+	u32 igc_sts;
+	u32 igc_tbl_idx;
+	u32 argc_sts;
+	u32 enhist_sts;
+	u32 dither_sts;
+	u32 gamut_sts;
+	u32 pgc_sts;
+	u32 sharp_sts;
+};
+
+struct mdss_pipe_pp_res {
+	u32 igc_c0_c1[IGC_LUT_ENTRIES];
+	u32 igc_c2[IGC_LUT_ENTRIES];
+	struct pp_sts_type pp_sts;
+};
+
 struct mdss_mdp_pipe {
 	u32 num;
 	u32 type;
 	u32 ndx;
+	char __iomem *base;
+	u32 ftch_id;
 	atomic_t ref_cnt;
 	u32 play_cnt;
 
@@ -236,7 +260,6 @@
 
 	struct msm_fb_data_type *mfd;
 	struct mdss_mdp_mixer *mixer;
-	struct mutex lock;
 
 	struct mdp_overlay req_data;
 	u32 params_changed;
@@ -250,6 +273,7 @@
 	struct list_head cleanup_list;
 
 	struct mdp_overlay_pp_params pp_cfg;
+	struct mdss_pipe_pp_res pp_res;
 };
 
 struct mdss_mdp_writeback_arg {
@@ -262,17 +286,17 @@
 static inline void mdss_mdp_ctl_write(struct mdss_mdp_ctl *ctl,
 				      u32 reg, u32 val)
 {
-	int offset = MDSS_MDP_REG_CTL_OFFSET(ctl->num);
-	MDSS_MDP_REG_WRITE(offset + reg, val);
+	writel_relaxed(val, ctl->base + reg);
 }
 
 static inline u32 mdss_mdp_ctl_read(struct mdss_mdp_ctl *ctl, u32 reg)
 {
-	int offset = MDSS_MDP_REG_CTL_OFFSET(ctl->num);
-	return MDSS_MDP_REG_READ(offset + reg);
+	return readl_relaxed(ctl->base + reg);
 }
 
 irqreturn_t mdss_mdp_isr(int irq, void *ptr);
+int mdss_iommu_attach(struct mdss_data_type *mdata);
+int mdss_mdp_copy_splash_screen(struct mdss_panel_data *pdata);
 int mdss_mdp_irq_enable(u32 intr_type, u32 intf_num);
 void mdss_mdp_irq_disable(u32 intr_type, u32 intf_num);
 int mdss_mdp_hist_irq_enable(u32 irq);
@@ -281,19 +305,30 @@
 int mdss_mdp_set_intr_callback(u32 intr_type, u32 intf_num,
 			       void (*fnc_ptr)(void *), void *arg);
 
+void mdss_mdp_footswitch_ctrl_splash(int on);
 int mdss_mdp_bus_scale_set_quota(u64 ab_quota, u64 ib_quota);
 void mdss_mdp_set_clk_rate(unsigned long min_clk_rate);
 unsigned long mdss_mdp_get_clk_rate(u32 clk_idx);
 int mdss_mdp_vsync_clk_enable(int enable);
 void mdss_mdp_clk_ctrl(int enable, int isr);
+struct mdss_data_type *mdss_mdp_get_mdata(void);
 
 int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd);
 int mdss_mdp_overlay_vsync_ctrl(struct msm_fb_data_type *mfd, int en);
+int mdss_mdp_video_addr_setup(struct mdss_data_type *mdata,
+		u32 *offsets,  u32 count);
 int mdss_mdp_video_start(struct mdss_mdp_ctl *ctl);
 int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl);
+int mdss_mdp_overlay_kickoff(struct mdss_mdp_ctl *ctl);
 
-int mdss_mdp_ctl_on(struct msm_fb_data_type *mfd);
-int mdss_mdp_ctl_off(struct msm_fb_data_type *mfd);
+struct mdss_mdp_ctl *mdss_mdp_ctl_init(struct mdss_panel_data *pdata,
+				       struct msm_fb_data_type *mfd);
+int mdss_mdp_ctl_setup(struct mdss_mdp_ctl *ctl);
+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_stop(struct mdss_mdp_ctl *ctl);
 int mdss_mdp_ctl_intf_event(struct mdss_mdp_ctl *ctl, int event, void *arg);
 
 struct mdss_mdp_mixer *mdss_mdp_wb_mixer_alloc(int rotator);
@@ -304,32 +339,68 @@
 int mdss_mdp_mixer_pipe_update(struct mdss_mdp_pipe *pipe, int params_changed);
 int mdss_mdp_mixer_pipe_unstage(struct mdss_mdp_pipe *pipe);
 int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg);
+int mdss_mdp_display_wait4comp(struct mdss_mdp_ctl *ctl);
 
 int mdss_mdp_csc_setup(u32 block, u32 blk_idx, u32 tbl_idx, u32 csc_type);
 int mdss_mdp_csc_setup_data(u32 block, u32 blk_idx, u32 tbl_idx,
 				   struct mdp_csc_cfg *data);
 
+int mdss_mdp_pp_init(struct device *dev);
+void mdss_mdp_pp_term(struct device *dev);
+
+int mdss_mdp_pp_resume(u32 mixer_num);
+
 int mdss_mdp_pp_setup(struct mdss_mdp_ctl *ctl);
-int mdss_mdp_pcc_config(struct mdp_pcc_cfg_data *cfg_ptr, u32 *copyback);
+int mdss_mdp_pp_setup_locked(struct mdss_mdp_ctl *ctl);
+int mdss_mdp_pipe_pp_setup(struct mdss_mdp_pipe *pipe, u32 *op);
+int mdss_mdp_pipe_sspp_setup(struct mdss_mdp_pipe *pipe, u32 *op);
+void mdss_mdp_pipe_sspp_term(struct mdss_mdp_pipe *pipe);
 
-int mdss_mdp_igc_lut_config(struct mdp_igc_lut_data *config, u32 *copyback);
-int mdss_mdp_argc_config(struct mdp_pgc_lut_data *config, u32 *copyback);
-int mdss_mdp_hist_lut_config(struct mdp_hist_lut_data *config, u32 *copyback);
-int mdss_mdp_dither_config(struct mdp_dither_cfg_data *config, u32 *copyback);
-int mdss_mdp_gamut_config(struct mdp_gamut_cfg_data *config, u32 *copyback);
+int mdss_hw_init(struct mdss_data_type *mdata);
 
-int mdss_mdp_histogram_start(struct mdp_histogram_start_req *req);
-int mdss_mdp_histogram_stop(u32 block);
-int mdss_mdp_hist_collect(struct fb_info *info,
-		   struct mdp_histogram_data *hist, u32 *hist_data_addr);
+int mdss_mdp_pa_config(struct mdss_mdp_ctl *ctl,
+				struct mdp_pa_cfg_data *config,
+				u32 *copyback);
+int mdss_mdp_pcc_config(struct mdss_mdp_ctl *ctl,
+				struct mdp_pcc_cfg_data *cfg_ptr,
+				u32 *copyback);
+int mdss_mdp_igc_lut_config(struct mdss_mdp_ctl *ctl,
+				struct mdp_igc_lut_data *config,
+				u32 *copyback);
+int mdss_mdp_argc_config(struct mdss_mdp_ctl *ctl,
+				struct mdp_pgc_lut_data *config,
+				u32 *copyback);
+int mdss_mdp_hist_lut_config(struct mdss_mdp_ctl *ctl,
+				struct mdp_hist_lut_data *config,
+				u32 *copyback);
+int mdss_mdp_dither_config(struct mdss_mdp_ctl *ctl,
+				struct mdp_dither_cfg_data *config,
+				u32 *copyback);
+int mdss_mdp_gamut_config(struct mdss_mdp_ctl *ctl,
+				struct mdp_gamut_cfg_data *config,
+				u32 *copyback);
+
+int mdss_mdp_histogram_start(struct mdss_mdp_ctl *ctl,
+				struct mdp_histogram_start_req *req);
+int mdss_mdp_histogram_stop(struct mdss_mdp_ctl *ctl, u32 block);
+int mdss_mdp_hist_collect(struct mdss_mdp_ctl *ctl,
+				struct mdp_histogram_data *hist,
+				u32 *hist_data_addr);
 void mdss_mdp_hist_intr_done(u32 isr);
 
+struct mdss_mdp_pipe *mdss_mdp_pipe_alloc(struct mdss_mdp_mixer *mixer,
+					  u32 type);
+struct mdss_mdp_pipe *mdss_mdp_pipe_get(struct mdss_data_type *mdata, u32 ndx);
+int mdss_mdp_pipe_map(struct mdss_mdp_pipe *pipe);
+void mdss_mdp_pipe_unmap(struct mdss_mdp_pipe *pipe);
+struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_dma(struct mdss_mdp_mixer *mixer);
 
-struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_pnum(u32 pnum);
-struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_locked(u32 type);
-struct mdss_mdp_pipe *mdss_mdp_pipe_get_locked(u32 ndx);
-int mdss_mdp_pipe_lock(struct mdss_mdp_pipe *pipe);
-void mdss_mdp_pipe_unlock(struct mdss_mdp_pipe *pipe);
+int mdss_mdp_pipe_addr_setup(struct mdss_data_type *mdata, u32 *offsets,
+		u32 *ftch_y_id, u32 type, u32 num_base, u32 len);
+int mdss_mdp_mixer_addr_setup(struct mdss_data_type *mdata, u32 *mixer_offsets,
+		u32 *dspp_offsets, u32 type, u32 len);
+int mdss_mdp_ctl_addr_setup(struct mdss_data_type *mdata, u32 *ctl_offsets,
+		u32 *wb_offsets, u32 len);
 
 int mdss_mdp_pipe_destroy(struct mdss_mdp_pipe *pipe);
 int mdss_mdp_pipe_queue_data(struct mdss_mdp_pipe *pipe,
@@ -342,13 +413,10 @@
 struct mdss_mdp_format_params *mdss_mdp_get_format_params(u32 format);
 int mdss_mdp_put_img(struct mdss_mdp_img_data *data);
 int mdss_mdp_get_img(struct msmfb_data *img, struct mdss_mdp_img_data *data);
+u32 mdss_get_panel_framerate(struct msm_fb_data_type *mfd);
 
 int mdss_mdp_wb_kickoff(struct mdss_mdp_ctl *ctl);
 int mdss_mdp_wb_ioctl_handler(struct msm_fb_data_type *mfd, u32 cmd, void *arg);
 
-int mdss_mdp_pp_init(struct device *dev);
-void mdss_mdp_pp_term(struct device *dev);
-int mdss_mdp_pa_config(struct mdp_pa_cfg_data *config, u32 *copyback);
-
 int mdss_mdp_get_ctl_mixers(u32 fb_num, u32 *mixer_id);
 #endif /* MDSS_MDP_H */
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index bd0f6c9..cabb183 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.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
@@ -38,10 +38,14 @@
 #define MDSS_MDP_PERF_UPDATE_ALL -1
 
 static DEFINE_MUTEX(mdss_mdp_ctl_lock);
-static struct mdss_mdp_ctl mdss_mdp_ctl_list[MDSS_MDP_MAX_CTL];
-static struct mdss_mdp_mixer mdss_mdp_mixer_list[MDSS_MDP_MAX_LAYERMIXER];
 
-static int mdss_mdp_ctl_perf_commit(u32 flags)
+static inline void mdp_mixer_write(struct mdss_mdp_mixer *mixer,
+				   u32 reg, u32 val)
+{
+	writel_relaxed(val, mixer->base + reg);
+}
+
+static int mdss_mdp_ctl_perf_commit(struct mdss_data_type *mdata, u32 flags)
 {
 	struct mdss_mdp_ctl *ctl;
 	int cnum;
@@ -54,8 +58,8 @@
 	}
 
 	mutex_lock(&mdss_mdp_ctl_lock);
-	for (cnum = 0; cnum < MDSS_MDP_MAX_CTL; cnum++) {
-		ctl = &mdss_mdp_ctl_list[cnum];
+	for (cnum = 0; cnum < mdata->nctl; cnum++) {
+		ctl = mdata->ctl_off + cnum;
 		if (ctl->power_on) {
 			bus_ab_quota += ctl->bus_ab_quota;
 			bus_ib_quota += ctl->bus_ib_quota;
@@ -69,10 +73,6 @@
 		bus_ib_quota = MDSS_MDP_BUS_FUDGE_FACTOR(bus_ib_quota);
 		bus_ib_quota <<= MDSS_MDP_BUS_FACTOR_SHIFT;
 
-		if ((bus_ib_quota == 0) && (clk_rate > 0)) {
-			/* allocate min bw for panel cmds if mdp is active */
-			bus_ib_quota = SZ_16M;
-		}
 		mdss_mdp_bus_scale_set_quota(bus_ab_quota, bus_ib_quota);
 	}
 	if (flags & MDSS_MDP_PERF_UPDATE_CLK) {
@@ -92,7 +92,7 @@
 	struct mdss_mdp_pipe *pipe;
 	const int fps = 60;
 	u32 quota, rate;
-	u32 v_total, v_active;
+	u32 v_total;
 	int i;
 	u32 max_clk_rate = 0, ab_total = 0, ib_total = 0;
 
@@ -103,7 +103,6 @@
 	if (mixer->rotator_mode) {
 		pipe = mixer->stage_pipe[0]; /* rotator pipe */
 		v_total = pipe->flags & MDP_ROT_90 ? pipe->dst.w : pipe->dst.h;
-		v_active = v_total;
 	} else {
 		int is_writeback = false;
 		if (mixer->type == MDSS_MDP_MIXER_TYPE_INTF) {
@@ -112,13 +111,11 @@
 			v_total = (pinfo->yres + pinfo->lcdc.v_back_porch +
 				   pinfo->lcdc.v_front_porch +
 				   pinfo->lcdc.v_pulse_width);
-			v_active = pinfo->yres;
 
 			if (pinfo->type == WRITEBACK_PANEL)
 				is_writeback = true;
 		} else {
 			v_total = mixer->height;
-			v_active = v_total;
 
 			is_writeback = true;
 		}
@@ -148,21 +145,19 @@
 		else
 			quota *= pipe->src_fmt->bpp;
 
-		if (mixer->type == MDSS_MDP_MIXER_TYPE_INTF)
-			quota = (quota / v_active) * v_total;
-		else if (mixer->rotator_mode)
-			quota *= 2; /* bus read + write */
-
 		rate = pipe->dst.w;
-		if (pipe->src.h > pipe->dst.h) {
+		if (pipe->src.h > pipe->dst.h)
 			rate = (rate * pipe->src.h) / pipe->dst.h;
-			ib_quota = (quota / pipe->dst.h) * pipe->src.h;
-		} else {
-			ib_quota = quota;
-		}
+
 		rate *= v_total * fps;
-		if (mixer->rotator_mode)
+		if (mixer->rotator_mode) {
 			rate /= 4; /* block mode fetch at 4 pix/clk */
+			quota *= 2; /* bus read + write */
+			ib_quota = quota;
+		} else {
+			ib_quota = (quota / pipe->dst.h) * v_total;
+		}
+
 
 		pr_debug("mixer=%d pnum=%d clk_rate=%u bus ab=%u ib=%u\n",
 			 mixer->num, pipe->num, rate, quota, ib_quota);
@@ -182,7 +177,7 @@
 		 *clk_rate, *bus_ab_quota, *bus_ib_quota);
 }
 
-static int mdss_mdp_ctl_perf_update(struct mdss_mdp_ctl *ctl, u32 *flags)
+static int mdss_mdp_ctl_perf_update(struct mdss_mdp_ctl *ctl)
 {
 	int ret = MDSS_MDP_PERF_UPDATE_SKIP;
 	u32 clk_rate, ab_quota, ib_quota;
@@ -205,7 +200,9 @@
 			max_clk_rate = clk_rate;
 	}
 
-	*flags = 0;
+	/* request minimum bandwidth to have bus clock on when display is on */
+	if (total_ib_quota == 0)
+		total_ib_quota = SZ_16M >> MDSS_MDP_BUS_FACTOR_SHIFT;
 
 	if (max_clk_rate != ctl->clk_rate) {
 		if (max_clk_rate > ctl->clk_rate)
@@ -213,41 +210,41 @@
 		else
 			ret = MDSS_MDP_PERF_UPDATE_LATE;
 		ctl->clk_rate = max_clk_rate;
-		*flags |= MDSS_MDP_PERF_UPDATE_CLK;
+		ctl->perf_changed |= MDSS_MDP_PERF_UPDATE_CLK;
 	}
 
 	if ((total_ab_quota != ctl->bus_ab_quota) ||
 			(total_ib_quota != ctl->bus_ib_quota)) {
 		if (ret == MDSS_MDP_PERF_UPDATE_SKIP) {
-			if (total_ib_quota > ctl->bus_ib_quota)
+			if (total_ib_quota >= ctl->bus_ib_quota)
 				ret = MDSS_MDP_PERF_UPDATE_EARLY;
 			else
 				ret = MDSS_MDP_PERF_UPDATE_LATE;
 		}
 		ctl->bus_ab_quota = total_ab_quota;
 		ctl->bus_ib_quota = total_ib_quota;
-		*flags |= MDSS_MDP_PERF_UPDATE_BUS;
+		ctl->perf_changed |= MDSS_MDP_PERF_UPDATE_BUS;
 	}
 
 	return ret;
 }
 
-static struct mdss_mdp_ctl *mdss_mdp_ctl_alloc(void)
+static struct mdss_mdp_ctl *mdss_mdp_ctl_alloc(struct mdss_data_type *mdata)
 {
 	struct mdss_mdp_ctl *ctl = NULL;
 	int cnum;
 
 	mutex_lock(&mdss_mdp_ctl_lock);
-	for (cnum = 0; cnum < MDSS_MDP_MAX_CTL; cnum++) {
-		if (mdss_mdp_ctl_list[cnum].ref_cnt == 0) {
-			ctl = &mdss_mdp_ctl_list[cnum];
-			ctl->num = cnum;
+	for (cnum = 0; cnum < mdata->nctl; cnum++) {
+		ctl = mdata->ctl_off + cnum;
+		if (ctl->ref_cnt == 0) {
 			ctl->ref_cnt++;
+			ctl->mdata = mdata;
 			mutex_init(&ctl->lock);
-
 			pr_debug("alloc ctl_num=%d\n", ctl->num);
 			break;
 		}
+		ctl = NULL;
 	}
 	mutex_unlock(&mdss_mdp_ctl_lock);
 
@@ -267,31 +264,72 @@
 	}
 
 	mutex_lock(&mdss_mdp_ctl_lock);
-	if (--ctl->ref_cnt == 0)
-		memset(ctl, 0, sizeof(*ctl));
+	ctl->ref_cnt--;
+	ctl->mixer_left = NULL;
+	ctl->mixer_right = NULL;
+	ctl->power_on = false;
+	ctl->start_fnc = NULL;
+	ctl->stop_fnc = NULL;
+	ctl->prepare_fnc = NULL;
+	ctl->display_fnc = NULL;
 	mutex_unlock(&mdss_mdp_ctl_lock);
 
 	return 0;
 }
 
-static struct mdss_mdp_mixer *mdss_mdp_mixer_alloc(u32 type)
+static struct mdss_mdp_mixer *mdss_mdp_mixer_alloc(
+		struct mdss_mdp_ctl *ctl, u32 type, int mux)
 {
 	struct mdss_mdp_mixer *mixer = NULL;
-	int mnum;
+	u32 nmixers_intf;
+	u32 nmixers_wb;
+	u32 i;
+	u32 nmixers;
+	struct mdss_mdp_mixer *mixer_pool = NULL;
+
+	if (!ctl || !ctl->mdata)
+		return NULL;
 
 	mutex_lock(&mdss_mdp_ctl_lock);
-	for (mnum = 0; mnum < MDSS_MDP_MAX_LAYERMIXER; mnum++) {
-		if (type == mdss_res->mixer_type_map[mnum] &&
-		    mdss_mdp_mixer_list[mnum].ref_cnt == 0) {
-			mixer = &mdss_mdp_mixer_list[mnum];
-			mixer->num = mnum;
+	nmixers_intf = ctl->mdata->nmixers_intf;
+	nmixers_wb = ctl->mdata->nmixers_wb;
+
+	switch (type) {
+	case MDSS_MDP_MIXER_TYPE_INTF:
+		mixer_pool = ctl->mdata->mixer_intf;
+		nmixers = nmixers_intf;
+		break;
+
+	case MDSS_MDP_MIXER_TYPE_WRITEBACK:
+		mixer_pool = ctl->mdata->mixer_wb;
+		nmixers = nmixers_wb;
+		break;
+
+	default:
+		nmixers = 0;
+		pr_err("invalid pipe type %d\n", type);
+		break;
+	}
+
+	/* early mdp revision only supports mux of dual pipe on mixers 0 and 1,
+	 * need to ensure that these pipes are readily available by using
+	 * mixer 2 if available and mux is not required */
+	if (!mux && (ctl->mdata->mdp_rev == MDSS_MDP_HW_REV_100) &&
+			(type == MDSS_MDP_MIXER_TYPE_INTF) &&
+			(nmixers >= MDSS_MDP_INTF_LAYERMIXER2) &&
+			(mixer_pool[MDSS_MDP_INTF_LAYERMIXER2].ref_cnt == 0))
+		mixer_pool += MDSS_MDP_INTF_LAYERMIXER2;
+
+	for (i = 0; i < nmixers; i++) {
+		mixer = mixer_pool + i;
+		if (mixer->ref_cnt == 0) {
 			mixer->ref_cnt++;
 			mixer->params_changed++;
-			mixer->type = type;
-
-			pr_debug("mixer_num=%d\n", mixer->num);
+			mixer->ctl = ctl;
+			pr_debug("alloc mixer num%d\n", mixer->num);
 			break;
 		}
+		mixer = NULL;
 	}
 	mutex_unlock(&mdss_mdp_ctl_lock);
 
@@ -311,8 +349,7 @@
 	}
 
 	mutex_lock(&mdss_mdp_ctl_lock);
-	if (--mixer->ref_cnt == 0)
-		memset(mixer, 0, sizeof(*mixer));
+	mixer->ref_cnt--;
 	mutex_unlock(&mdss_mdp_ctl_lock);
 
 	return 0;
@@ -323,23 +360,22 @@
 	struct mdss_mdp_ctl *ctl = NULL;
 	struct mdss_mdp_mixer *mixer = NULL;
 
-	ctl = mdss_mdp_ctl_alloc();
-
+	ctl = mdss_mdp_ctl_alloc(mdss_res);
 	if (!ctl)
 		return NULL;
 
-	mixer = mdss_mdp_mixer_alloc(MDSS_MDP_MIXER_TYPE_WRITEBACK);
+	mixer = mdss_mdp_mixer_alloc(ctl, MDSS_MDP_MIXER_TYPE_WRITEBACK, false);
 	if (!mixer)
 		goto error;
 
 	mixer->rotator_mode = rotator;
 
 	switch (mixer->num) {
-	case MDSS_MDP_LAYERMIXER3:
+	case MDSS_MDP_WB_LAYERMIXER0:
 		ctl->opmode = (rotator ? MDSS_MDP_CTL_OP_ROT0_MODE :
 			       MDSS_MDP_CTL_OP_WB0_MODE);
 		break;
-	case MDSS_MDP_LAYERMIXER4:
+	case MDSS_MDP_WB_LAYERMIXER1:
 		ctl->opmode = (rotator ? MDSS_MDP_CTL_OP_ROT1_MODE :
 			       MDSS_MDP_CTL_OP_WB1_MODE);
 		break;
@@ -349,7 +385,6 @@
 	}
 
 	ctl->mixer_left = mixer;
-	mixer->ctl = ctl;
 
 	ctl->start_fnc = mdss_mdp_writeback_start;
 	ctl->power_on = true;
@@ -381,46 +416,52 @@
 	mdss_mdp_mixer_free(mixer);
 	mdss_mdp_ctl_free(ctl);
 
-	mdss_mdp_ctl_perf_commit(MDSS_MDP_PERF_UPDATE_ALL);
+	mdss_mdp_ctl_perf_commit(ctl->mdata, MDSS_MDP_PERF_UPDATE_ALL);
 
 	return 0;
 }
 
-static int mdss_mdp_ctl_init(struct msm_fb_data_type *mfd)
+static inline int mdss_mdp_set_split_ctl(struct mdss_mdp_ctl *ctl,
+		struct mdss_mdp_ctl *split_ctl)
 {
-	struct mdss_mdp_ctl *ctl;
-	struct mdss_panel_data *pdata;
+	if (!ctl || !split_ctl)
+		return -ENODEV;
+
+	/* setup split ctl mixer as right mixer of original ctl so that
+	 * original ctl can work the same way as dual pipe solution */
+	ctl->mixer_right = split_ctl->mixer_left;
+
+	return 0;
+}
+
+static inline struct mdss_mdp_ctl *mdss_mdp_get_split_ctl(
+		struct mdss_mdp_ctl *ctl)
+{
+	if (ctl && ctl->mixer_right && (ctl->mixer_right->ctl != ctl))
+		return ctl->mixer_right->ctl;
+
+	return NULL;
+}
+
+int mdss_mdp_ctl_setup(struct mdss_mdp_ctl *ctl)
+{
+	struct mdss_mdp_ctl *split_ctl;
 	u32 width, height;
-	int ret = 0;
 
-	if (!mfd)
-		return -ENODEV;
-
-	pdata = dev_get_platdata(&mfd->pdev->dev);
-	if (!pdata) {
-		pr_err("no panel connected for fb%d\n", mfd->index);
+	if (!ctl || !ctl->panel_data) {
+		pr_err("invalid ctl handle\n");
 		return -ENODEV;
 	}
 
-	width = pdata->panel_info.xres;
-	height = pdata->panel_info.yres;
+	split_ctl = mdss_mdp_get_split_ctl(ctl);
 
-	if (width > (2 * MAX_MIXER_WIDTH)) {
-		pr_err("unsupported resolution\n");
-		return -EINVAL;
-	}
+	width = ctl->panel_data->panel_info.xres;
+	height = ctl->panel_data->panel_info.yres;
 
-	if (!mfd->ctl) {
-		ctl = mdss_mdp_ctl_alloc();
-		if (!ctl) {
-			pr_err("unable to allocate ctl\n");
-			return -ENOMEM;
-		}
-		ctl->mfd = mfd;
-		mfd->ctl = ctl;
-		ctl->panel_data = pdata;
-	} else {
-		ctl = mfd->ctl;
+	if ((split_ctl && (width > MAX_MIXER_WIDTH)) ||
+			(width > (2 * MAX_MIXER_WIDTH))) {
+		pr_err("Unsupported panel resolution: %dx%d\n", width, height);
+		return -ENOTSUPP;
 	}
 
 	ctl->width = width;
@@ -428,11 +469,11 @@
 
 	if (!ctl->mixer_left) {
 		ctl->mixer_left =
-			mdss_mdp_mixer_alloc(MDSS_MDP_MIXER_TYPE_INTF);
+			mdss_mdp_mixer_alloc(ctl, MDSS_MDP_MIXER_TYPE_INTF,
+					(width > MAX_MIXER_WIDTH));
 		if (!ctl->mixer_left) {
 			pr_err("unable to allocate layer mixer\n");
-			ret = -ENOMEM;
-			goto ctl_init_fail;
+			return -ENOMEM;
 		}
 	}
 
@@ -441,25 +482,55 @@
 
 	ctl->mixer_left->width = width;
 	ctl->mixer_left->height = height;
-	ctl->mixer_left->ctl = ctl;
+
+	if (split_ctl) {
+		pr_debug("split display detected\n");
+		return 0;
+	}
 
 	if (width < ctl->width) {
 		if (ctl->mixer_right == NULL) {
-			ctl->mixer_right =
-				mdss_mdp_mixer_alloc(MDSS_MDP_MIXER_TYPE_INTF);
+			ctl->mixer_right = mdss_mdp_mixer_alloc(ctl,
+					MDSS_MDP_MIXER_TYPE_INTF, true);
 			if (!ctl->mixer_right) {
 				pr_err("unable to allocate right mixer\n");
-				ret = -ENOMEM;
-				goto ctl_init_fail;
+				if (ctl->mixer_left)
+					mdss_mdp_mixer_free(ctl->mixer_left);
+				return -ENOMEM;
 			}
 		}
 		ctl->mixer_right->width = width;
 		ctl->mixer_right->height = height;
-		ctl->mixer_right->ctl = ctl;
 	} else if (ctl->mixer_right) {
 		mdss_mdp_mixer_free(ctl->mixer_right);
+		ctl->mixer_right = NULL;
 	}
 
+	if (ctl->mixer_right) {
+		ctl->opmode |= MDSS_MDP_CTL_OP_PACK_3D_ENABLE |
+			       MDSS_MDP_CTL_OP_PACK_3D_H_ROW_INT;
+	} else {
+		ctl->opmode &= ~(MDSS_MDP_CTL_OP_PACK_3D_ENABLE |
+				  MDSS_MDP_CTL_OP_PACK_3D_H_ROW_INT);
+	}
+
+	return 0;
+}
+
+struct mdss_mdp_ctl *mdss_mdp_ctl_init(struct mdss_panel_data *pdata,
+				       struct msm_fb_data_type *mfd)
+{
+	struct mdss_mdp_ctl *ctl;
+	int ret = 0;
+
+	ctl = mdss_mdp_ctl_alloc(mfd->mdata);
+	if (!ctl) {
+		pr_err("unable to allocate ctl\n");
+		return ERR_PTR(-ENOMEM);
+	}
+	ctl->mfd = mfd;
+	ctl->panel_data = pdata;
+
 	switch (pdata->panel_info.type) {
 	case EDP_PANEL:
 		ctl->intf_num = MDSS_MDP_INTF0;
@@ -516,40 +587,121 @@
 			ctl->dst_format = MDSS_MDP_PANEL_FORMAT_RGB888;
 			break;
 		}
-		mdss_mdp_dither_config(&dither, NULL);
+		mdss_mdp_dither_config(ctl, &dither, NULL);
+	}
+
+	return ctl;
+ctl_init_fail:
+	mdss_mdp_ctl_free(ctl);
+
+	return ERR_PTR(ret);
+}
+
+int mdss_mdp_ctl_split_display_setup(struct mdss_mdp_ctl *ctl,
+		struct mdss_panel_data *pdata)
+{
+	struct mdss_mdp_ctl *sctl;
+	struct mdss_mdp_mixer *mixer;
+
+	if (!ctl || !pdata)
+		return -ENODEV;
+
+	if (pdata->panel_info.xres > MAX_MIXER_WIDTH) {
+		pr_err("Unsupported second panel resolution: %dx%d\n",
+				pdata->panel_info.xres, pdata->panel_info.yres);
+		return -ENOTSUPP;
 	}
 
 	if (ctl->mixer_right) {
-		ctl->opmode |= MDSS_MDP_CTL_OP_PACK_3D_ENABLE |
-			       MDSS_MDP_CTL_OP_PACK_3D_H_ROW_INT;
+		pr_err("right mixer already setup for ctl=%d\n", ctl->num);
+		return -EPERM;
 	}
 
-ctl_init_fail:
-	if (IS_ERR_VALUE(ret)) {
-		if (ctl->mixer_left)
-			mdss_mdp_mixer_free(ctl->mixer_left);
-		if (ctl->mixer_right)
-			mdss_mdp_mixer_free(ctl->mixer_right);
-		mdss_mdp_ctl_free(ctl);
-		mfd->ctl = NULL;
+	sctl = mdss_mdp_ctl_init(pdata, ctl->mfd);
+	if (!sctl) {
+		pr_err("unable to setup split display\n");
+		return -ENODEV;
 	}
 
-	return ret;
+	sctl->width = pdata->panel_info.xres;
+	sctl->height = pdata->panel_info.yres;
+
+	ctl->mixer_left = mdss_mdp_mixer_alloc(ctl, MDSS_MDP_MIXER_TYPE_INTF,
+			false);
+	if (!ctl->mixer_left) {
+		pr_err("unable to allocate layer mixer\n");
+		mdss_mdp_ctl_destroy(sctl);
+		return -ENOMEM;
+	}
+
+	mixer = mdss_mdp_mixer_alloc(sctl, MDSS_MDP_MIXER_TYPE_INTF, false);
+	if (!mixer) {
+		pr_err("unable to allocate layer mixer\n");
+		mdss_mdp_ctl_destroy(sctl);
+		return -ENOMEM;
+	}
+
+	mixer->width = sctl->width;
+	mixer->height = sctl->height;
+	sctl->mixer_left = mixer;
+
+	return mdss_mdp_set_split_ctl(ctl, sctl);
 }
 
-static int mdss_mdp_ctl_destroy(struct msm_fb_data_type *mfd)
+static void mdss_mdp_ctl_split_display_enable(int enable,
+	struct mdss_mdp_ctl *main_ctl, struct mdss_mdp_ctl *slave_ctl)
 {
-	struct mdss_mdp_ctl *ctl;
-	if (!mfd || !mfd->ctl)
-		return -ENODEV;
+	u32 upper = 0, lower = 0;
 
-	ctl = mfd->ctl;
-	mfd->ctl = NULL;
+	pr_debug("split main ctl=%d intf=%d slave ctl=%d intf=%d\n",
+			main_ctl->num, main_ctl->intf_num,
+			slave_ctl->num, slave_ctl->intf_num);
+	if (enable) {
+		if (main_ctl->opmode & MDSS_MDP_CTL_OP_CMD_MODE) {
+			upper |= BIT(1);
+			lower |= BIT(1);
 
-	if (ctl->mixer_left)
-		mdss_mdp_mixer_free(ctl->mixer_left);
-	if (ctl->mixer_right)
+			/* interface controlling sw trigger */
+			if (main_ctl->intf_num == MDSS_MDP_INTF2)
+				upper |= BIT(4);
+			else
+				upper |= BIT(8);
+		} else { /* video mode */
+			if (main_ctl->intf_num == MDSS_MDP_INTF2)
+				lower |= BIT(4);
+			else
+				lower |= BIT(8);
+		}
+	}
+	MDSS_MDP_REG_WRITE(MDSS_MDP_REG_SPLIT_DISPLAY_UPPER_PIPE_CTRL, upper);
+	MDSS_MDP_REG_WRITE(MDSS_MDP_REG_SPLIT_DISPLAY_LOWER_PIPE_CTRL, lower);
+	MDSS_MDP_REG_WRITE(MDSS_MDP_REG_SPLIT_DISPLAY_EN, enable);
+}
+
+
+int mdss_mdp_ctl_destroy(struct mdss_mdp_ctl *ctl)
+{
+	struct mdss_mdp_ctl *sctl;
+	int rc;
+
+	rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_CLOSE, NULL);
+	WARN(rc, "unable to close panel for intf=%d\n", ctl->intf_num);
+
+	sctl = mdss_mdp_get_split_ctl(ctl);
+	if (sctl) {
+		pr_debug("destroying split display ctl=%d\n", sctl->num);
+		if (sctl->mixer_left)
+			mdss_mdp_mixer_free(sctl->mixer_left);
+		mdss_mdp_ctl_free(sctl);
+	} else if (ctl->mixer_right) {
 		mdss_mdp_mixer_free(ctl->mixer_right);
+		ctl->mixer_right = NULL;
+	}
+
+	if (ctl->mixer_left) {
+		mdss_mdp_mixer_free(ctl->mixer_left);
+		ctl->mixer_left = NULL;
+	}
 	mdss_mdp_ctl_free(ctl);
 
 	return 0;
@@ -558,6 +710,8 @@
 int mdss_mdp_ctl_intf_event(struct mdss_mdp_ctl *ctl, int event, void *arg)
 {
 	struct mdss_panel_data *pdata;
+	int rc = 0;
+
 	if (!ctl || !ctl->panel_data)
 		return -ENODEV;
 
@@ -565,48 +719,21 @@
 
 	pr_debug("sending ctl=%d event=%d\n", ctl->num, event);
 
-	if (pdata->event_handler)
-		return pdata->event_handler(pdata, event, arg);
+	do {
+		if (pdata->event_handler)
+			rc = pdata->event_handler(pdata, event, arg);
+		pdata = pdata->next;
+	} while (rc == 0 && pdata);
 
-	return 0;
+	return rc;
 }
 
-int mdss_mdp_ctl_on(struct msm_fb_data_type *mfd)
+static int mdss_mdp_ctl_start_sub(struct mdss_mdp_ctl *ctl)
 {
-	struct mdss_mdp_ctl *ctl;
 	struct mdss_mdp_mixer *mixer;
-	u32 outsize, temp, off;
+	u32 outsize, temp;
 	int ret = 0;
 
-	if (!mfd)
-		return -ENODEV;
-
-	if (mfd->key != MFD_KEY)
-		return -EINVAL;
-
-	if (mdss_mdp_ctl_init(mfd)) {
-		pr_err("unable to initialize ctl\n");
-		return -ENODEV;
-	}
-
-	ctl = mfd->ctl;
-
-	if (ctl->power_on) {
-		WARN(1, "already on!\n");
-		return 0;
-	}
-
-	mutex_lock(&ctl->lock);
-
-	ctl->power_on = true;
-
-	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
-	ret = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_RESET, NULL);
-	if (ret) {
-		pr_err("panel power on failed ctl=%d\n", ctl->num);
-		goto start_fail;
-	}
-
 	if (ctl->start_fnc)
 		ret = ctl->start_fnc(ctl);
 	else
@@ -615,70 +742,95 @@
 
 	if (ret) {
 		pr_err("unable to start intf\n");
-		goto start_fail;
+		return ret;
 	}
 
 	pr_debug("ctl_num=%d\n", ctl->num);
 
 	mixer = ctl->mixer_left;
+	mdss_mdp_pp_resume(mixer->num);
 	mixer->params_changed++;
 
 	temp = MDSS_MDP_REG_READ(MDSS_MDP_REG_DISP_INTF_SEL);
 	temp |= (ctl->intf_type << ((ctl->intf_num - MDSS_MDP_INTF0) * 8));
 	MDSS_MDP_REG_WRITE(MDSS_MDP_REG_DISP_INTF_SEL, temp);
 
-	if (ctl->intf_num != MDSS_MDP_NO_INTF) {
-		off = MDSS_MDP_REG_INTF_OFFSET(ctl->intf_num);
-		MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_PANEL_FORMAT,
-				   ctl->dst_format);
-	}
-
 	outsize = (mixer->height << 16) | mixer->width;
-	off = MDSS_MDP_REG_LM_OFFSET(mixer->num);
-	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_LM_OUT_SIZE, outsize);
-
-	if (ctl->mixer_right) {
-		mixer = ctl->mixer_right;
-		mixer->params_changed++;
-		outsize = (mixer->height << 16) | mixer->width;
-		off = MDSS_MDP_REG_LM_OFFSET(mixer->num);
-		MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_LM_OUT_SIZE, outsize);
-		mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_PACK_3D, 0);
-	}
-
-start_fail:
-	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
-	mutex_unlock(&ctl->lock);
-	if (ret)
-		mdss_mdp_ctl_destroy(mfd);
+	mdp_mixer_write(mixer, MDSS_MDP_REG_LM_OUT_SIZE, outsize);
 
 	return ret;
 }
 
-int mdss_mdp_ctl_off(struct msm_fb_data_type *mfd)
+int mdss_mdp_ctl_start(struct mdss_mdp_ctl *ctl)
 {
-	struct mdss_mdp_ctl *ctl;
+	struct mdss_mdp_ctl *sctl;
 	int ret = 0;
 
-	if (!mfd)
-		return -ENODEV;
-
-	if (mfd->key != MFD_KEY)
-		return -EINVAL;
-
-	if (!mfd->ctl) {
-		pr_err("ctl not initialized\n");
-		return -ENODEV;
-	}
-
-	ctl = mfd->ctl;
-
-	if (!ctl->power_on) {
-		WARN(1, "already off!\n");
+	if (ctl->power_on) {
+		pr_debug("%s:%d already on!\n", __func__, __LINE__);
 		return 0;
 	}
 
-	pr_debug("ctl_num=%d\n", mfd->ctl->num);
+	ret = mdss_mdp_ctl_setup(ctl);
+	if (ret)
+		return ret;
+
+
+	sctl = mdss_mdp_get_split_ctl(ctl);
+
+	mutex_lock(&ctl->lock);
+
+	ctl->power_on = true;
+	ctl->bus_ab_quota = 0;
+	ctl->bus_ib_quota = 0;
+	ctl->clk_rate = 0;
+
+	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
+
+	ret = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_RESET, NULL);
+	if (ret) {
+		pr_err("panel power on failed ctl=%d\n", ctl->num);
+		return ret;
+	}
+
+	ret = mdss_mdp_ctl_start_sub(ctl);
+	if (ret == 0) {
+		if (sctl) { /* split display is available */
+			ret = mdss_mdp_ctl_start_sub(sctl);
+			if (!ret)
+				mdss_mdp_ctl_split_display_enable(1, ctl, sctl);
+		} else if (ctl->mixer_right) {
+			struct mdss_mdp_mixer *mixer = ctl->mixer_right;
+			u32 out, off;
+
+			mdss_mdp_pp_resume(mixer->num);
+			mixer->params_changed++;
+			out = (mixer->height << 16) | mixer->width;
+			off = MDSS_MDP_REG_LM_OFFSET(mixer->num);
+			MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_LM_OUT_SIZE, out);
+			mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_PACK_3D, 0);
+		}
+	}
+
+	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+	mutex_unlock(&ctl->lock);
+
+	return ret;
+}
+
+int mdss_mdp_ctl_stop(struct mdss_mdp_ctl *ctl)
+{
+	struct mdss_mdp_ctl *sctl;
+	int ret = 0;
+
+	if (!ctl->power_on) {
+		pr_debug("%s %d already off!\n", __func__, __LINE__);
+		return 0;
+	}
+
+	sctl = mdss_mdp_get_split_ctl(ctl);
+
+	pr_debug("ctl_num=%d\n", ctl->num);
 
 	mutex_lock(&ctl->lock);
 
@@ -689,25 +841,33 @@
 	else
 		pr_warn("no stop func for ctl=%d\n", ctl->num);
 
+	if (sctl && sctl->stop_fnc) {
+		ret = sctl->stop_fnc(sctl);
+
+		mdss_mdp_ctl_split_display_enable(0, ctl, sctl);
+	}
+
 	if (ret) {
 		pr_warn("error powering off intf ctl=%d\n", ctl->num);
 	} else {
 		ctl->power_on = false;
 		ctl->play_cnt = 0;
 		ctl->clk_rate = 0;
-		mdss_mdp_ctl_perf_commit(MDSS_MDP_PERF_UPDATE_ALL);
+		if (ctl->mixer_left) {
+			mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_LAYER(
+					ctl->mixer_left->num), 0);
+		}
+		if (ctl->mixer_right) {
+			mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_LAYER(
+					ctl->mixer_right->num), 0);
+		}
+		mdss_mdp_ctl_perf_commit(ctl->mdata, MDSS_MDP_PERF_UPDATE_ALL);
 	}
 
 	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
 
 	mutex_unlock(&ctl->lock);
 
-	if (!ret && !mfd->ref_cnt) {
-		ret = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_CLOSE, NULL);
-		WARN(ret, "unable to close intf %d\n", ctl->intf_num);
-		mdss_mdp_ctl_destroy(mfd);
-	}
-
 	return ret;
 }
 
@@ -717,7 +877,7 @@
 	struct mdss_mdp_pipe *pipe;
 	u32 off, blend_op, blend_stage;
 	u32 mixercfg = 0, blend_color_out = 0, bgalpha = 0;
-	int stage;
+	int stage, secure = 0;
 
 	if (!mixer)
 		return -ENODEV;
@@ -731,6 +891,7 @@
 		mixercfg = 1 << (3 * pipe->num);
 		if (pipe->src_fmt->alpha_enable)
 			bgalpha = 1;
+		secure = pipe->flags & MDP_SECURE_OVERLAY_SESSION;
 	}
 
 	for (stage = MDSS_MDP_STAGE_0; stage < MDSS_MDP_MAX_STAGE; stage++) {
@@ -744,12 +905,12 @@
 		}
 
 		blend_stage = stage - MDSS_MDP_STAGE_0;
-		off = MDSS_MDP_REG_LM_OFFSET(mixer->num) +
-		      MDSS_MDP_REG_LM_BLEND_OFFSET(blend_stage);
+		off = MDSS_MDP_REG_LM_BLEND_OFFSET(blend_stage);
 
 		if (pipe->is_fg) {
 			bgalpha = 0;
-			mixercfg = MDSS_MDP_LM_BORDER_COLOR;
+			if (!secure)
+				mixercfg = MDSS_MDP_LM_BORDER_COLOR;
 
 			blend_op = (MDSS_MDP_BLEND_FG_ALPHA_FG_CONST |
 				    MDSS_MDP_BLEND_BG_ALPHA_BG_CONST);
@@ -781,12 +942,20 @@
 					stage);
 		}
 
+		if (mixercfg == MDSS_MDP_LM_BORDER_COLOR &&
+				pipe->src_fmt->alpha_enable &&
+				pipe->dst.w == mixer->width &&
+				pipe->dst.h == mixer->height) {
+			pr_debug("setting pipe=%d as BG_PIPE\n", pipe->num);
+			bgalpha = 1;
+		}
+
 		mixercfg |= stage << (3 * pipe->num);
 
-		MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_LM_OP_MODE, blend_op);
-		MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_LM_BLEND_FG_ALPHA,
+		mdp_mixer_write(mixer, off + MDSS_MDP_REG_LM_OP_MODE, blend_op);
+		mdp_mixer_write(mixer, off + MDSS_MDP_REG_LM_BLEND_FG_ALPHA,
 				   pipe->alpha);
-		MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_LM_BLEND_BG_ALPHA,
+		mdp_mixer_write(mixer, off + MDSS_MDP_REG_LM_BLEND_BG_ALPHA,
 				   0xFF - pipe->alpha);
 	}
 
@@ -798,12 +967,82 @@
 	ctl->flush_bits |= BIT(6) << mixer->num;	/* LAYER_MIXER */
 
 	off = MDSS_MDP_REG_LM_OFFSET(mixer->num);
-	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_LM_OP_MODE, blend_color_out);
+	mdp_mixer_write(mixer, MDSS_MDP_REG_LM_OP_MODE, blend_color_out);
 	mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_LAYER(mixer->num), mixercfg);
 
 	return 0;
 }
 
+int mdss_mdp_mixer_addr_setup(struct mdss_data_type *mdata,
+	 u32 *mixer_offsets, u32 *dspp_offsets, u32 type, u32 len)
+{
+	struct mdss_mdp_mixer *head;
+	u32 i;
+	int rc = 0;
+
+	head = devm_kzalloc(&mdata->pdev->dev, sizeof(struct mdss_mdp_mixer) *
+			len, GFP_KERNEL);
+
+	if (!head) {
+		pr_err("unable to setup mixer type=%d :kzalloc fail\n",
+			type);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < len; i++) {
+		head[i].type = type;
+		head[i].base = mdata->mdp_base + mixer_offsets[i];
+		head[i].ref_cnt = 0;
+		head[i].num = i;
+		if (type == MDSS_MDP_MIXER_TYPE_INTF)
+			head[i].dspp_base = mdata->mdp_base + dspp_offsets[i];
+	}
+
+	switch (type) {
+
+	case MDSS_MDP_MIXER_TYPE_INTF:
+		mdata->mixer_intf = head;
+		break;
+
+	case MDSS_MDP_MIXER_TYPE_WRITEBACK:
+		mdata->mixer_wb = head;
+		break;
+
+	default:
+		pr_err("Invalid mixer type=%d\n", type);
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
+int mdss_mdp_ctl_addr_setup(struct mdss_data_type *mdata,
+	u32 *ctl_offsets, u32 *wb_offsets, u32 len)
+{
+	struct mdss_mdp_ctl *head;
+	u32 i;
+
+	head = devm_kzalloc(&mdata->pdev->dev, sizeof(struct mdss_mdp_ctl) *
+			len, GFP_KERNEL);
+
+	if (!head) {
+		pr_err("unable to setup ctl and wb: kzalloc fail\n");
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < len; i++) {
+		head[i].num = i;
+		head[i].base = (mdata->mdp_base) + ctl_offsets[i];
+		head[i].wb_base = (mdata->mdp_base) + wb_offsets[i];
+		head[i].ref_cnt = 0;
+	}
+
+	mdata->ctl_off = head;
+
+	return 0;
+}
+
 struct mdss_mdp_mixer *mdss_mdp_mixer_get(struct mdss_mdp_ctl *ctl, int mux)
 {
 	struct mdss_mdp_mixer *mixer = NULL;
@@ -921,12 +1160,38 @@
 	return 0;
 }
 
+int mdss_mdp_display_wait4comp(struct mdss_mdp_ctl *ctl)
+{
+	int ret;
+
+	ret = mutex_lock_interruptible(&ctl->lock);
+	if (ret)
+		return ret;
+
+	if (!ctl->power_on) {
+		mutex_unlock(&ctl->lock);
+		return 0;
+	}
+
+	if (ctl->wait_fnc)
+		ret = ctl->wait_fnc(ctl, NULL);
+
+	if (ctl->perf_changed) {
+		mdss_mdp_ctl_perf_commit(ctl->mdata, ctl->perf_changed);
+		ctl->perf_changed = 0;
+	}
+
+	mutex_unlock(&ctl->lock);
+
+	return ret;
+}
+
 int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg)
 {
+	struct mdss_mdp_ctl *sctl = NULL;
 	int mixer1_changed, mixer2_changed;
 	int ret = 0;
 	int perf_update = MDSS_MDP_PERF_UPDATE_SKIP;
-	u32 update_flags = 0;
 
 	if (!ctl) {
 		pr_err("display function not set\n");
@@ -944,12 +1209,14 @@
 		return 0;
 	}
 
+	sctl = mdss_mdp_get_split_ctl(ctl);
+
 	mixer1_changed = (ctl->mixer_left && ctl->mixer_left->params_changed);
 	mixer2_changed = (ctl->mixer_right && ctl->mixer_right->params_changed);
 
 	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
 	if (mixer1_changed || mixer2_changed) {
-		perf_update = mdss_mdp_ctl_perf_update(ctl, &update_flags);
+		perf_update = mdss_mdp_ctl_perf_update(ctl);
 
 		if (ctl->prepare_fnc)
 			ret = ctl->prepare_fnc(ctl, arg);
@@ -958,8 +1225,10 @@
 			goto done;
 		}
 
-		if (perf_update == MDSS_MDP_PERF_UPDATE_EARLY)
-			mdss_mdp_ctl_perf_commit(update_flags);
+		if (perf_update == MDSS_MDP_PERF_UPDATE_EARLY) {
+			mdss_mdp_ctl_perf_commit(ctl->mdata, ctl->perf_changed);
+			ctl->perf_changed = 0;
+		}
 
 		if (mixer1_changed)
 			mdss_mdp_mixer_update(ctl->mixer_left);
@@ -968,11 +1237,22 @@
 
 		mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_TOP, ctl->opmode);
 		ctl->flush_bits |= BIT(17);	/* CTL */
+
+		if (sctl) {
+			mdss_mdp_ctl_write(sctl, MDSS_MDP_REG_CTL_TOP,
+					sctl->opmode);
+			sctl->flush_bits |= BIT(17);
+		}
 	}
 
 	/* postprocessing setup, including dspp */
-	mdss_mdp_pp_setup(ctl);
+	mdss_mdp_pp_setup_locked(ctl);
 	mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_FLUSH, ctl->flush_bits);
+	if (sctl) {
+		mdss_mdp_pp_setup_locked(sctl);
+		mdss_mdp_ctl_write(sctl, MDSS_MDP_REG_CTL_FLUSH,
+			sctl->flush_bits);
+	}
 	wmb();
 	ctl->flush_bits = 0;
 
@@ -983,9 +1263,6 @@
 
 	ctl->play_cnt++;
 
-	if (perf_update == MDSS_MDP_PERF_UPDATE_LATE)
-		mdss_mdp_ctl_perf_commit(update_flags);
-
 done:
 	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
 
@@ -998,10 +1275,12 @@
 {
 	int i;
 	struct mdss_mdp_ctl *ctl;
+	struct mdss_data_type *mdata;
 	u32 mixer_cnt = 0;
 	mutex_lock(&mdss_mdp_ctl_lock);
-	for (i = 0; i < MDSS_MDP_MAX_CTL; i++) {
-		ctl = &mdss_mdp_ctl_list[i];
+	mdata = mdss_mdp_get_mdata();
+	for (i = 0; i < mdata->nctl; i++) {
+		ctl = mdata->ctl_off + i;
 		if ((ctl->power_on) && (ctl->mfd) &&
 			(ctl->mfd->index == fb_num)) {
 			if (ctl->mixer_left) {
diff --git a/drivers/video/msm/mdss/mdss_mdp_formats.h b/drivers/video/msm/mdss/mdss_mdp_formats.h
index ee3b8e6..c6d5fb9 100644
--- a/drivers/video/msm/mdss/mdss_mdp_formats.h
+++ b/drivers/video/msm/mdss/mdss_mdp_formats.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/video/msm/mdss/mdss_mdp_hwio.h b/drivers/video/msm/mdss/mdss_mdp_hwio.h
index b6ac126..d4ffaff 100644
--- a/drivers/video/msm/mdss/mdss_mdp_hwio.h
+++ b/drivers/video/msm/mdss/mdss_mdp_hwio.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -16,6 +16,14 @@
 
 #include <linux/bitops.h>
 
+#define IGC_LUT_ENTRIES	256
+#define GC_LUT_SEGMENTS	16
+#define ENHIST_LUT_ENTRIES 256
+#define HIST_V_SIZE	256
+
+#define MDSS_MDP_HW_REV_100		0x10000000
+#define MDSS_MDP_HW_REV_102		0x10020000
+
 #define MDSS_REG_HW_VERSION				0x0
 #define MDSS_REG_HW_INTR_STATUS				0x10
 
@@ -34,6 +42,10 @@
 #define MDSS_MDP_REG_HIST_INTR_STATUS			0x00120
 #define MDSS_MDP_REG_HIST_INTR_CLEAR			0x00124
 
+#define MDSS_MDP_REG_SPLIT_DISPLAY_EN			0x003F4
+#define MDSS_MDP_REG_SPLIT_DISPLAY_UPPER_PIPE_CTRL	0x003F8
+#define MDSS_MDP_REG_SPLIT_DISPLAY_LOWER_PIPE_CTRL	0x004F0
+
 #define MDSS_INTF_DSI	0x1
 #define MDSS_INTF_HDMI	0x3
 #define MDSS_INTF_LCDC	0x5
@@ -156,6 +168,9 @@
 #define MDSS_MDP_REG_SSPP_SRC_OP_MODE			0x038
 #define MDSS_MDP_OP_DEINTERLACE			BIT(22)
 #define MDSS_MDP_OP_DEINTERLACE_ODD		BIT(23)
+#define MDSS_MDP_OP_IGC_ROM_1			BIT(18)
+#define MDSS_MDP_OP_IGC_ROM_0			BIT(17)
+#define MDSS_MDP_OP_IGC_EN			BIT(16)
 #define MDSS_MDP_OP_FLIP_UD			BIT(14)
 #define MDSS_MDP_OP_FLIP_LR			BIT(13)
 #define MDSS_MDP_OP_BWC_EN			BIT(0)
@@ -185,6 +200,8 @@
 #define MDSS_MDP_REG_VIG_QSEED2_C03_INIT_PHASEY		0x224
 #define MDSS_MDP_REG_VIG_QSEED2_C12_INIT_PHASEX		0x228
 #define MDSS_MDP_REG_VIG_QSEED2_C12_INIT_PHASEY		0x22C
+#define MDSS_MDP_REG_VIG_QSEED2_SHARP			0x230
+#define MDSS_MDP_REG_VIG_PA_BASE			0x310
 
 #define MDSS_MDP_REG_SCALE_CONFIG			0x204
 #define MDSS_MDP_REG_SCALE_PHASE_STEP_X			0x210
@@ -204,17 +221,22 @@
 #define MDSS_MDP_SCALE_FILTER_CA		0x3
 #define MDSS_MDP_SCALEY_EN			BIT(1)
 #define MDSS_MDP_SCALEX_EN			BIT(0)
+#define MDSS_MDP_FMT_SOLID_FILL			0x4037FF
 
 #define MDSS_MDP_NUM_REG_MIXERS 3
 #define MDSS_MDP_NUM_WB_MIXERS 2
 
-enum mdss_mdp_mixer_index {
-	MDSS_MDP_LAYERMIXER0,
-	MDSS_MDP_LAYERMIXER1,
-	MDSS_MDP_LAYERMIXER2,
-	MDSS_MDP_LAYERMIXER3,
-	MDSS_MDP_LAYERMIXER4,
-	MDSS_MDP_MAX_LAYERMIXER
+enum mdss_mdp_mixer_intf_index {
+	MDSS_MDP_INTF_LAYERMIXER0,
+	MDSS_MDP_INTF_LAYERMIXER1,
+	MDSS_MDP_INTF_LAYERMIXER2,
+	MDSS_MDP_INTF_MAX_LAYERMIXER,
+};
+
+enum mdss_mdp_mixer_wb_index {
+	MDSS_MDP_WB_LAYERMIXER0,
+	MDSS_MDP_WB_LAYERMIXER1,
+	MDSS_MDP_WB_MAX_LAYERMIXER,
 };
 
 enum mdss_mdp_stage_index {
@@ -340,6 +362,7 @@
 #define MDSS_MDP_REG_DSPP_HIST_LUT_BASE			0x230
 #define MDSS_MDP_REG_DSPP_PA_BASE			0x238
 #define MDSS_MDP_REG_DSPP_GAMUT_BASE			0x2DC
+#define MDSS_MDP_REG_DSPP_GC_BASE			0x2B0
 
 enum mdss_mpd_intf_index {
 	MDSS_MDP_NO_INTF,
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_video.c b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
index a6a6d59..e2c3b23 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_video.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_video.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
@@ -38,22 +38,52 @@
 	u32 hsync_skew;
 };
 
-#define MAX_SESSIONS 3
 struct mdss_mdp_video_ctx {
-	u32 pp_num;
+	u32 intf_num;
+	char __iomem *base;
+	u32 intf_type;
 	u8 ref_cnt;
 
 	u8 timegen_en;
 	struct completion vsync_comp;
+	int wait_pending;
 
 	atomic_t vsync_ref;
 	spinlock_t vsync_lock;
 	mdp_vsync_handler_t vsync_handler;
 };
 
-struct mdss_mdp_video_ctx mdss_mdp_video_ctx_list[MAX_SESSIONS];
+static inline void mdp_video_write(struct mdss_mdp_video_ctx *ctx,
+				   u32 reg, u32 val)
+{
+	writel_relaxed(val, ctx->base + reg);
+}
 
-static int mdss_mdp_video_timegen_setup(struct mdss_mdp_ctl *ctl,
+int mdss_mdp_video_addr_setup(struct mdss_data_type *mdata,
+				u32 *offsets,  u32 count)
+{
+	struct mdss_mdp_video_ctx *head;
+	u32 i;
+
+	head = devm_kzalloc(&mdata->pdev->dev,
+			sizeof(struct mdss_mdp_video_ctx) * count, GFP_KERNEL);
+	if (!head)
+		return -ENOMEM;
+
+	for (i = 0; i < count; i++) {
+		head[i].base = mdata->mdp_base + offsets[i];
+		pr_debug("adding Video Intf #%d offset=0x%x virt=%p\n", i,
+				offsets[i], head[i].base);
+		head[i].ref_cnt = 0;
+		head[i].intf_num = i + MDSS_MDP_INTF0;
+	}
+
+	mdata->video_intf = head;
+	mdata->nintf = count;
+	return 0;
+}
+
+static int mdss_mdp_video_timegen_setup(struct mdss_mdp_video_ctx *ctx,
 					struct intf_timing_params *p)
 {
 	u32 hsync_period, vsync_period;
@@ -61,9 +91,6 @@
 	u32 active_h_start, active_h_end, active_v_start, active_v_end;
 	u32 den_polarity, hsync_polarity, vsync_polarity;
 	u32 display_hctl, active_hctl, hsync_ctl, polarity_ctl;
-	int off;
-
-	off = MDSS_MDP_REG_INTF_OFFSET(ctl->intf_num);
 
 	hsync_period = p->hsync_pulse_width + p->h_back_porch +
 			p->width + p->h_front_porch;
@@ -75,7 +102,7 @@
 	display_v_end = ((vsync_period - p->v_front_porch) * hsync_period) +
 			p->hsync_skew - 1;
 
-	if (ctl->intf_type == MDSS_INTF_EDP) {
+	if (ctx->intf_type == MDSS_INTF_EDP) {
 		display_v_start += p->hsync_pulse_width + p->h_back_porch;
 		display_v_end -= p->h_front_porch;
 	}
@@ -114,7 +141,7 @@
 	display_hctl = (hsync_end_x << 16) | hsync_start_x;
 
 	den_polarity = 0;
-	if (MDSS_INTF_HDMI ==  ctl->intf_type) {
+	if (MDSS_INTF_HDMI == ctx->intf_type) {
 		hsync_polarity = p->yres >= 720 ? 0 : 1;
 		vsync_polarity = p->yres >= 720 ? 0 : 1;
 	} else {
@@ -125,31 +152,25 @@
 		       (vsync_polarity << 1) | /* VSYNC Polarity */
 		       (hsync_polarity << 0);  /* HSYNC Polarity */
 
-	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_HSYNC_CTL, hsync_ctl);
-	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_VSYNC_PERIOD_F0,
+	mdp_video_write(ctx, MDSS_MDP_REG_INTF_HSYNC_CTL, hsync_ctl);
+	mdp_video_write(ctx, MDSS_MDP_REG_INTF_VSYNC_PERIOD_F0,
 			   vsync_period * hsync_period);
-	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_VSYNC_PULSE_WIDTH_F0,
+	mdp_video_write(ctx, MDSS_MDP_REG_INTF_VSYNC_PULSE_WIDTH_F0,
 			   p->vsync_pulse_width * hsync_period);
-	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_DISPLAY_HCTL,
-			   display_hctl);
-	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_DISPLAY_V_START_F0,
+	mdp_video_write(ctx, MDSS_MDP_REG_INTF_DISPLAY_HCTL, display_hctl);
+	mdp_video_write(ctx, MDSS_MDP_REG_INTF_DISPLAY_V_START_F0,
 			   display_v_start);
-	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_DISPLAY_V_END_F0,
-			   display_v_end);
-	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_ACTIVE_HCTL, active_hctl);
-	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_ACTIVE_V_START_F0,
+	mdp_video_write(ctx, MDSS_MDP_REG_INTF_DISPLAY_V_END_F0, display_v_end);
+	mdp_video_write(ctx, MDSS_MDP_REG_INTF_ACTIVE_HCTL, active_hctl);
+	mdp_video_write(ctx, MDSS_MDP_REG_INTF_ACTIVE_V_START_F0,
 			   active_v_start);
-	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_ACTIVE_V_END_F0,
-			   active_v_end);
+	mdp_video_write(ctx, MDSS_MDP_REG_INTF_ACTIVE_V_END_F0, active_v_end);
 
-	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_BORDER_COLOR,
-			   p->border_clr);
-	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_UNDERFLOW_COLOR,
+	mdp_video_write(ctx, MDSS_MDP_REG_INTF_BORDER_COLOR, p->border_clr);
+	mdp_video_write(ctx, MDSS_MDP_REG_INTF_UNDERFLOW_COLOR,
 			   p->underflow_clr);
-	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_HSYNC_SKEW,
-			   p->hsync_skew);
-	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_POLARITY_CTL,
-			   polarity_ctl);
+	mdp_video_write(ctx, MDSS_MDP_REG_INTF_HSYNC_SKEW, p->hsync_skew);
+	mdp_video_write(ctx, MDSS_MDP_REG_INTF_POLARITY_CTL, polarity_ctl);
 
 	return 0;
 }
@@ -198,7 +219,7 @@
 static int mdss_mdp_video_stop(struct mdss_mdp_ctl *ctl)
 {
 	struct mdss_mdp_video_ctx *ctx;
-	int rc, off;
+	int rc;
 
 	pr_debug("stop ctl=%d\n", ctl->num);
 
@@ -217,8 +238,7 @@
 		}
 		WARN(rc, "intf %d blank error (%d)\n", ctl->intf_num, rc);
 
-		off = MDSS_MDP_REG_INTF_OFFSET(ctl->intf_num);
-		MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_TIMING_ENGINE_EN, 0);
+		mdp_video_write(ctx, MDSS_MDP_REG_INTF_TIMING_ENGINE_EN, 0);
 		mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
 		ctx->timegen_en = false;
 
@@ -230,10 +250,9 @@
 
 	mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num,
 				   NULL, NULL);
-	mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_COMP, ctx->pp_num,
-				   NULL, NULL);
 
-	memset(ctx, 0, sizeof(*ctx));
+	ctx->ref_cnt--;
+	ctl->priv_data = NULL;
 
 	return 0;
 }
@@ -253,13 +272,38 @@
 
 	pr_debug("intr ctl=%d\n", ctl->num);
 
-	complete(&ctx->vsync_comp);
+	complete_all(&ctx->vsync_comp);
 	spin_lock(&ctx->vsync_lock);
 	if (ctx->vsync_handler)
 		ctx->vsync_handler(ctl, vsync_time);
 	spin_unlock(&ctx->vsync_lock);
 }
 
+static int mdss_mdp_video_wait4comp(struct mdss_mdp_ctl *ctl, void *arg)
+{
+	struct mdss_mdp_video_ctx *ctx;
+	int rc;
+
+	ctx = (struct mdss_mdp_video_ctx *) ctl->priv_data;
+	if (!ctx) {
+		pr_err("invalid ctx\n");
+		return -ENODEV;
+	}
+
+	WARN(!ctx->wait_pending, "waiting without commit! ctl=%d", ctl->num);
+
+	rc = wait_for_completion_interruptible_timeout(&ctx->vsync_comp,
+			VSYNC_TIMEOUT);
+	WARN(rc <= 0, "vsync timed out (%d) ctl=%d\n", rc, ctl->num);
+
+	if (ctx->wait_pending) {
+		ctx->wait_pending = 0;
+		video_vsync_irq_disable(ctl);
+	}
+
+	return rc;
+}
+
 static int mdss_mdp_video_display(struct mdss_mdp_ctl *ctl, void *arg)
 {
 	struct mdss_mdp_video_ctx *ctx;
@@ -272,45 +316,48 @@
 		pr_err("invalid ctx\n");
 		return -ENODEV;
 	}
-	INIT_COMPLETION(ctx->vsync_comp);
-	video_vsync_irq_enable(ctl);
+
+	if (!ctx->wait_pending) {
+		ctx->wait_pending++;
+		INIT_COMPLETION(ctx->vsync_comp);
+		video_vsync_irq_enable(ctl);
+	} else {
+		WARN(1, "commit without wait! ctl=%d", ctl->num);
+	}
 
 	if (!ctx->timegen_en) {
-		int off = MDSS_MDP_REG_INTF_OFFSET(ctl->intf_num);
-
 		rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_UNBLANK, NULL);
 		WARN(rc, "intf %d unblank error (%d)\n", ctl->intf_num, rc);
 
 		pr_debug("enabling timing gen for intf=%d\n", ctl->intf_num);
 
 		mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
-		MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_TIMING_ENGINE_EN, 1);
+		mdp_video_write(ctx, MDSS_MDP_REG_INTF_TIMING_ENGINE_EN, 1);
 		wmb();
-	}
 
-	rc = wait_for_completion_interruptible_timeout(&ctx->vsync_comp,
-			VSYNC_TIMEOUT);
-	WARN(rc <= 0, "vsync timed out (%d) ctl=%d\n", rc, ctl->num);
+		rc = wait_for_completion_interruptible_timeout(&ctx->vsync_comp,
+				VSYNC_TIMEOUT);
+		WARN(rc <= 0, "timeout (%d) enabling timegen on ctl=%d\n",
+				rc, ctl->num);
 
-	if (!ctx->timegen_en) {
 		ctx->timegen_en = true;
 		rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_TIMEGEN_ON, NULL);
 		WARN(rc, "intf %d timegen on error (%d)\n", ctl->intf_num, rc);
 	}
 
-	video_vsync_irq_disable(ctl);
-
 	return 0;
 }
 
 int mdss_mdp_video_start(struct mdss_mdp_ctl *ctl)
 {
+	struct mdss_data_type *mdata;
 	struct mdss_panel_info *pinfo;
 	struct mdss_mdp_video_ctx *ctx;
 	struct mdss_mdp_mixer *mixer;
 	struct intf_timing_params itp = {0};
 	int i;
 
+	mdata = ctl->mdata;
 	pinfo = &ctl->panel_data->panel_info;
 	mixer = mdss_mdp_mixer_get(ctl, MDSS_MDP_MIXER_MUX_LEFT);
 
@@ -319,21 +366,24 @@
 		return -ENODEV;
 	}
 
+	i = ctl->intf_num - MDSS_MDP_INTF0;
+	if (i < mdata->nintf) {
+		ctx = ((struct mdss_mdp_video_ctx *) mdata->video_intf) + i;
+		if (ctx->ref_cnt) {
+			pr_err("Intf %d already in use\n", ctl->intf_num);
+			return -EBUSY;
+		}
+		pr_debug("video Intf #%d base=%p", ctx->intf_num, ctx->base);
+		ctx->ref_cnt++;
+	} else {
+		pr_err("Invalid intf number: %d\n", ctl->intf_num);
+		return -EINVAL;
+	}
+
 	pr_debug("start ctl=%u\n", ctl->num);
 
-	for (i = 0; i < MAX_SESSIONS; i++) {
-		ctx = &mdss_mdp_video_ctx_list[i];
-		if (ctx->ref_cnt == 0) {
-			ctx->ref_cnt++;
-			break;
-		}
-	}
-	if (i == MAX_SESSIONS) {
-		pr_err("too many sessions\n");
-		return -ENOMEM;
-	}
 	ctl->priv_data = ctx;
-	ctx->pp_num = mixer->num;
+	ctx->intf_type = ctl->intf_type;
 	init_completion(&ctx->vsync_comp);
 	spin_lock_init(&ctx->vsync_lock);
 	atomic_set(&ctx->vsync_ref, 0);
@@ -356,13 +406,15 @@
 	itp.hsync_pulse_width = pinfo->lcdc.h_pulse_width;
 	itp.vsync_pulse_width = pinfo->lcdc.v_pulse_width;
 
-	if (mdss_mdp_video_timegen_setup(ctl, &itp)) {
+	if (mdss_mdp_video_timegen_setup(ctx, &itp)) {
 		pr_err("unable to get timing parameters\n");
 		return -EINVAL;
 	}
+	mdp_video_write(ctx, MDSS_MDP_REG_INTF_PANEL_FORMAT, ctl->dst_format);
 
 	ctl->stop_fnc = mdss_mdp_video_stop;
 	ctl->display_fnc = mdss_mdp_video_display;
+	ctl->wait_fnc = mdss_mdp_video_wait4comp;
 	ctl->set_vsync_handler = mdss_mdp_video_set_vsync_handler;
 
 	return 0;
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
index a1f1bcc..97428cd 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -27,6 +27,7 @@
 
 struct mdss_mdp_writeback_ctx {
 	u32 wb_num;
+	char __iomem *base;
 	u8 ref_cnt;
 	u8 type;
 
@@ -75,10 +76,16 @@
 	},
 };
 
+static inline void mdp_wb_write(struct mdss_mdp_writeback_ctx *ctx,
+				u32 reg, u32 val)
+{
+	writel_relaxed(val, ctx->base + reg);
+}
+
 static int mdss_mdp_writeback_addr_setup(struct mdss_mdp_writeback_ctx *ctx,
 					 struct mdss_mdp_data *data)
 {
-	int off, ret;
+	int ret;
 
 	if (!data)
 		return -EINVAL;
@@ -89,11 +96,10 @@
 	if (ret)
 		return ret;
 
-	off = MDSS_MDP_REG_WB_OFFSET(ctx->wb_num);
-	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_WB_DST0_ADDR, data->p[0].addr);
-	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_WB_DST1_ADDR, data->p[1].addr);
-	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_WB_DST2_ADDR, data->p[2].addr);
-	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_WB_DST3_ADDR, data->p[3].addr);
+	mdp_wb_write(ctx, MDSS_MDP_REG_WB_DST0_ADDR, data->p[0].addr);
+	mdp_wb_write(ctx, MDSS_MDP_REG_WB_DST1_ADDR, data->p[1].addr);
+	mdp_wb_write(ctx, MDSS_MDP_REG_WB_DST2_ADDR, data->p[2].addr);
+	mdp_wb_write(ctx, MDSS_MDP_REG_WB_DST3_ADDR, data->p[3].addr);
 
 	return 0;
 }
@@ -102,8 +108,8 @@
 {
 	struct mdss_mdp_format_params *fmt;
 	u32 dst_format, pattern, ystride0, ystride1, outsize, chroma_samp;
-	int off;
 	u32 opmode = ctx->opmode;
+	struct mdss_data_type *mdata;
 
 	pr_debug("wb_num=%d format=%d\n", ctx->wb_num, ctx->format);
 
@@ -157,8 +163,19 @@
 	}
 
 	if (fmt->fetch_planes != MDSS_MDP_PLANE_PLANAR) {
-		pattern = (fmt->element[3] << 24) | (fmt->element[2] << 15) |
-			(fmt->element[1] << 8) | (fmt->element[0] << 0);
+		mdata = mdss_mdp_get_mdata();
+		if (mdata && mdata->mdp_rev >= MDSS_MDP_HW_REV_102) {
+			pattern = (fmt->element[3] << 24) |
+				  (fmt->element[2] << 16) |
+				  (fmt->element[1] << 8)  |
+				  (fmt->element[0] << 0);
+		} else {
+			pattern = (fmt->element[3] << 24) |
+				  (fmt->element[2] << 15) |
+				  (fmt->element[1] << 8)  |
+				  (fmt->element[0] << 0);
+		}
+
 		dst_format |= (fmt->unpack_align_msb << 18) |
 			      (fmt->unpack_tight << 17) |
 			      ((fmt->unpack_count - 1) << 12) |
@@ -173,13 +190,12 @@
 		   (ctx->dst_planes.ystride[3] << 16);
 	outsize = (ctx->height << 16) | ctx->width;
 
-	off = MDSS_MDP_REG_WB_OFFSET(ctx->wb_num);
-	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_WB_DST_FORMAT, dst_format);
-	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_WB_DST_OP_MODE, opmode);
-	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_WB_DST_PACK_PATTERN, pattern);
-	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_WB_DST_YSTRIDE0, ystride0);
-	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_WB_DST_YSTRIDE1, ystride1);
-	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_WB_OUT_SIZE, outsize);
+	mdp_wb_write(ctx, MDSS_MDP_REG_WB_DST_FORMAT, dst_format);
+	mdp_wb_write(ctx, MDSS_MDP_REG_WB_DST_OP_MODE, opmode);
+	mdp_wb_write(ctx, MDSS_MDP_REG_WB_DST_PACK_PATTERN, pattern);
+	mdp_wb_write(ctx, MDSS_MDP_REG_WB_DST_YSTRIDE0, ystride0);
+	mdp_wb_write(ctx, MDSS_MDP_REG_WB_DST_YSTRIDE1, ystride1);
+	mdp_wb_write(ctx, MDSS_MDP_REG_WB_OUT_SIZE, outsize);
 
 	return 0;
 }
@@ -265,6 +281,9 @@
 
 	ctx = (struct mdss_mdp_writeback_ctx *) ctl->priv_data;
 	if (ctx) {
+		mdss_mdp_set_intr_callback(ctx->intr_type, ctx->intf_num,
+				   NULL, NULL);
+
 		ctl->priv_data = NULL;
 		ctx->ref_cnt--;
 	}
@@ -318,8 +337,6 @@
 	flush_bits = BIT(16); /* WB */
 	mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_FLUSH, flush_bits);
 
-	mdss_mdp_set_intr_callback(ctx->intr_type, ctx->intf_num,
-				   mdss_mdp_writeback_intr_done, ctx);
 	mdss_mdp_irq_enable(ctx->intr_type, ctx->intf_num);
 
 	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
@@ -351,8 +368,12 @@
 	}
 	ctl->priv_data = ctx;
 	ctx->wb_num = ctl->num;	/* wb num should match ctl num */
+	ctx->base = ctl->wb_base;
 	ctx->initialized = false;
 
+	mdss_mdp_set_intr_callback(ctx->intr_type, ctx->intf_num,
+				   mdss_mdp_writeback_intr_done, ctx);
+
 	if (ctx->type == MDSS_MDP_WRITEBACK_TYPE_ROTATOR)
 		ctl->prepare_fnc = mdss_mdp_writeback_prepare_rot;
 	else /* wfd or line mode */
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index 5b6d009..daa2499 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.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
@@ -18,33 +18,38 @@
 #include <linux/kernel.h>
 #include <linux/major.h>
 #include <linux/module.h>
+#include <linux/pm_runtime.h>
 #include <linux/uaccess.h>
+#include <linux/delay.h>
 
 #include <mach/iommu_domains.h>
 
+#include "mdss.h"
 #include "mdss_fb.h"
 #include "mdss_mdp.h"
 #include "mdss_mdp_rotator.h"
 
 #define VSYNC_PERIOD 16
+#define BORDERFILL_NDX	0x0BF000BF
 #define CHECK_BOUNDS(offset, size, max_size) \
 	(((size) > (max_size)) || ((offset) > ((max_size) - (size))))
 
 static atomic_t ov_active_panels = ATOMIC_INIT(0);
+static int mdss_mdp_overlay_free_fb_pipe(struct msm_fb_data_type *mfd);
 
 static int mdss_mdp_overlay_get(struct msm_fb_data_type *mfd,
 				struct mdp_overlay *req)
 {
 	struct mdss_mdp_pipe *pipe;
 
-	pipe = mdss_mdp_pipe_get_locked(req->id);
-	if (pipe == NULL) {
+	pipe = mdss_mdp_pipe_get(mfd->mdata, req->id);
+	if (IS_ERR_OR_NULL(pipe)) {
 		pr_err("invalid pipe ndx=%x\n", req->id);
-		return -ENODEV;
+		return pipe ? PTR_ERR(pipe) : -ENODEV;
 	}
 
 	*req = pipe->req_data;
-	mdss_mdp_pipe_unlock(pipe);
+	mdss_mdp_pipe_unmap(pipe);
 
 	return 0;
 }
@@ -54,10 +59,19 @@
 				      struct mdss_mdp_format_params *fmt)
 {
 	u32 xres, yres;
+	u32 min_src_size, min_dst_size;
 
 	xres = mfd->fbi->var.xres;
 	yres = mfd->fbi->var.yres;
 
+	if (mfd->mdata->mdp_rev >= MDSS_MDP_HW_REV_102) {
+		min_src_size = fmt->is_yuv ? 2 : 1;
+		min_dst_size = 1;
+	} else {
+		min_src_size = fmt->is_yuv ? 10 : 5;
+		min_dst_size = 2;
+	}
+
 	if (req->z_order >= MDSS_MDP_MAX_STAGE) {
 		pr_err("zorder %d out of range\n", req->z_order);
 		return -ERANGE;
@@ -65,7 +79,7 @@
 
 	if (req->src.width > MAX_IMG_WIDTH ||
 	    req->src.height > MAX_IMG_HEIGHT ||
-	    req->src_rect.w == 0 || req->src_rect.h == 0 ||
+	    req->src_rect.w < min_src_size || req->src_rect.h < min_src_size ||
 	    CHECK_BOUNDS(req->src_rect.x, req->src_rect.w, req->src.width) ||
 	    CHECK_BOUNDS(req->src_rect.y, req->src_rect.h, req->src.height)) {
 		pr_err("invalid source image img wh=%dx%d rect=%d,%d,%d,%d\n",
@@ -75,18 +89,14 @@
 		return -EOVERFLOW;
 	}
 
-	if (req->dst_rect.w < MIN_DST_W || req->dst_rect.h < MIN_DST_H ||
+	if (req->dst_rect.w < min_dst_size || req->dst_rect.h < min_dst_size ||
 	    req->dst_rect.w > MAX_DST_W || req->dst_rect.h > MAX_DST_H) {
 		pr_err("invalid destination resolution (%dx%d)",
 		       req->dst_rect.w, req->dst_rect.h);
 		return -EOVERFLOW;
 	}
 
-	if (req->flags & MDSS_MDP_ROT_ONLY) {
-		/* dst res should match src res in rotation only mode*/
-		req->dst_rect.w = req->src_rect.w;
-		req->dst_rect.h = req->src_rect.h;
-	} else {
+	if (!(req->flags & MDSS_MDP_ROT_ONLY)) {
 		u32 dst_w, dst_h;
 
 		if ((CHECK_BOUNDS(req->dst_rect.x, req->dst_rect.w, xres) ||
@@ -152,10 +162,6 @@
 			pr_err("invalid odd src resolution or coordinates\n");
 			return -EINVAL;
 		}
-		if ((req->dst_rect.w & 0x1) || (req->dst_rect.h & 0x1)) {
-			pr_err("invalid odd dst resolution\n");
-			return -EINVAL;
-		}
 	}
 
 	return 0;
@@ -230,7 +236,7 @@
 	struct mdss_mdp_format_params *fmt;
 	struct mdss_mdp_pipe *pipe;
 	struct mdss_mdp_mixer *mixer = NULL;
-	u32 pipe_type, mixer_mux;
+	u32 pipe_type, mixer_mux, len;
 	int ret;
 
 	if (mfd == NULL || mfd->ctl == NULL)
@@ -261,29 +267,31 @@
 
 	pipe = mdss_mdp_mixer_stage_pipe(mfd->ctl, mixer_mux, req->z_order);
 	if (pipe && pipe->ndx != req->id) {
-		pr_err("stage %d taken by pnum=%d\n", req->z_order, pipe->num);
-		return -EBUSY;
+		pr_debug("replacing pnum=%d at stage=%d mux=%d\n",
+				pipe->num, req->z_order, mixer_mux);
+		pipe->params_changed = true;
 	}
 
+	mixer = mdss_mdp_mixer_get(mfd->ctl, mixer_mux);
+	if (!mixer) {
+		pr_err("unable to get mixer\n");
+		return -ENODEV;
+	}
 
 	if (req->id == MSMFB_NEW_REQUEST) {
-		mixer = mdss_mdp_mixer_get(mfd->ctl, mixer_mux);
-		if (!mixer) {
-			pr_err("unable to get mixer\n");
-			return -ENODEV;
-		}
-
-		if (fmt->is_yuv || (req->flags & MDP_OV_PIPE_SHARE))
+		if (req->flags & MDP_OV_PIPE_FORCE_DMA)
+			pipe_type = MDSS_MDP_PIPE_TYPE_DMA;
+		else if (fmt->is_yuv || (req->flags & MDP_OV_PIPE_SHARE))
 			pipe_type = MDSS_MDP_PIPE_TYPE_VIG;
 		else
 			pipe_type = MDSS_MDP_PIPE_TYPE_RGB;
 
-		pipe = mdss_mdp_pipe_alloc_locked(pipe_type);
+		pipe = mdss_mdp_pipe_alloc(mixer, pipe_type);
 
 		/* VIG pipes can also support RGB format */
 		if (!pipe && pipe_type == MDSS_MDP_PIPE_TYPE_RGB) {
 			pipe_type = MDSS_MDP_PIPE_TYPE_VIG;
-			pipe = mdss_mdp_pipe_alloc_locked(pipe_type);
+			pipe = mdss_mdp_pipe_alloc(mixer, pipe_type);
 		}
 
 		if (pipe == NULL) {
@@ -291,16 +299,38 @@
 			return -ENOMEM;
 		}
 
+		ret = mdss_mdp_pipe_map(pipe);
+		if (ret) {
+			pr_err("unable to map pipe=%d\n", pipe->num);
+			return ret;
+		}
+
 		mutex_lock(&mfd->lock);
 		list_add(&pipe->used_list, &mfd->pipes_used);
 		mutex_unlock(&mfd->lock);
 		pipe->mixer = mixer;
 		pipe->mfd = mfd;
+		pipe->play_cnt = 0;
 	} else {
-		pipe = mdss_mdp_pipe_get_locked(req->id);
-		if (pipe == NULL) {
+		pipe = mdss_mdp_pipe_get(mfd->mdata, req->id);
+		if (IS_ERR_OR_NULL(pipe)) {
 			pr_err("invalid pipe ndx=%x\n", req->id);
-			return -ENODEV;
+			return pipe ? PTR_ERR(pipe) : -ENODEV;
+		}
+
+		if (pipe->mixer != mixer) {
+			if (!mixer->ctl || (mixer->ctl->mfd != mfd)) {
+				pr_err("Can't switch mixer %d->%d pnum %d!\n",
+						pipe->mixer->num, mixer->num,
+						pipe->num);
+				mdss_mdp_pipe_unmap(pipe);
+				return -EINVAL;
+			}
+			pr_debug("switching pipe mixer %d->%d pnum %d\n",
+					pipe->mixer->num, mixer->num,
+					pipe->num);
+			mdss_mdp_mixer_pipe_unstage(pipe);
+			pipe->mixer = mixer;
 		}
 	}
 
@@ -328,12 +358,25 @@
 	pipe->req_data = *req;
 
 	if (pipe->flags & MDP_OVERLAY_PP_CFG_EN) {
-		if (pipe->num <= MDSS_MDP_SSPP_VIG2)
-			memcpy(&pipe->pp_cfg, &req->overlay_pp_cfg,
+		memcpy(&pipe->pp_cfg, &req->overlay_pp_cfg,
 					sizeof(struct mdp_overlay_pp_params));
-		else
-			pr_debug("%s: RGB Pipes don't support CSC/QSEED\n",
-								__func__);
+		len = pipe->pp_cfg.igc_cfg.len;
+		if ((pipe->pp_cfg.config_ops & MDP_OVERLAY_PP_IGC_CFG) &&
+						(len == IGC_LUT_ENTRIES)) {
+			ret = copy_from_user(pipe->pp_res.igc_c0_c1,
+					pipe->pp_cfg.igc_cfg.c0_c1_data,
+					sizeof(uint32_t) * len);
+			if (ret)
+				return -ENOMEM;
+			ret = copy_from_user(pipe->pp_res.igc_c2,
+					pipe->pp_cfg.igc_cfg.c2_data,
+					sizeof(uint32_t) * len);
+			if (ret)
+				return -ENOMEM;
+			pipe->pp_cfg.igc_cfg.c0_c1_data =
+							pipe->pp_res.igc_c0_c1;
+			pipe->pp_cfg.igc_cfg.c2_data = pipe->pp_res.igc_c2;
+		}
 	}
 
 	if (pipe->flags & MDP_DEINTERLACE) {
@@ -351,7 +394,7 @@
 
 	*ppipe = pipe;
 
-	mdss_mdp_pipe_unlock(pipe);
+	mdss_mdp_pipe_unmap(pipe);
 
 	return ret;
 }
@@ -359,7 +402,7 @@
 static int mdss_mdp_overlay_set(struct msm_fb_data_type *mfd,
 				struct mdp_overlay *req)
 {
-	int ret;
+	int ret = 0;
 
 	ret = mutex_lock_interruptible(&mfd->ov_lock);
 	if (ret)
@@ -372,6 +415,8 @@
 
 	if (req->flags & MDSS_MDP_ROT_ONLY) {
 		ret = mdss_mdp_overlay_rotator_setup(mfd, req);
+	} else if (req->src.format == MDP_RGB_BORDERFILL) {
+		req->id = BORDERFILL_NDX;
 	} else {
 		struct mdss_mdp_pipe *pipe;
 
@@ -394,25 +439,28 @@
 					   int num_planes,
 					   u32 flags)
 {
-	int i;
+	int i, rc = 0;
+
+	if ((num_planes <= 0) || (num_planes > MAX_PLANES))
+		return -EINVAL;
 
 	memset(data, 0, sizeof(*data));
 	for (i = 0; i < num_planes; i++) {
 		data->p[i].flags = flags;
-		mdss_mdp_get_img(&planes[i], &data->p[i]);
-		if (data->p[0].len == 0)
+		rc = mdss_mdp_get_img(&planes[i], &data->p[i]);
+		if (rc) {
+			pr_err("failed to map buf p=%d flags=%x\n", i, flags);
+			while (i > 0) {
+				i--;
+				mdss_mdp_put_img(&data->p[i]);
+			}
 			break;
+		}
 	}
 
-	if (i != num_planes) {
-		for (; i >= 0; i--)
-			mdss_mdp_put_img(&data->p[i]);
-		return -ENOMEM;
-	}
+	data->num_planes = i;
 
-	data->num_planes = num_planes;
-
-	return 0;
+	return rc;
 }
 
 static inline int mdss_mdp_overlay_free_buf(struct mdss_mdp_data *data)
@@ -452,22 +500,167 @@
 	return 0;
 }
 
-static int mdss_mdp_overlay_kickoff(struct mdss_mdp_ctl *ctl)
+int mdss_mdp_copy_splash_screen(struct mdss_panel_data *pdata)
+{
+	void *virt = NULL;
+	unsigned long bl_fb_addr = 0;
+	unsigned long *bl_fb_addr_va;
+	unsigned long  pipe_addr, pipe_src_size;
+	u32 height, width, rgb_size, bpp;
+	size_t size;
+	static struct ion_handle *ihdl;
+	struct ion_client *iclient = mdss_get_ionclient();
+	static ion_phys_addr_t phys;
+
+	pipe_addr = MDSS_MDP_REG_SSPP_OFFSET(3) +
+		MDSS_MDP_REG_SSPP_SRC0_ADDR;
+	pipe_src_size =
+		MDSS_MDP_REG_SSPP_OFFSET(3) + MDSS_MDP_REG_SSPP_SRC_SIZE;
+
+	bpp        = 3;
+	rgb_size   = MDSS_MDP_REG_READ(pipe_src_size);
+	bl_fb_addr = MDSS_MDP_REG_READ(pipe_addr);
+
+	height = (rgb_size >> 16) & 0xffff;
+	width  = rgb_size & 0xffff;
+	size = PAGE_ALIGN(height * width * bpp);
+	pr_debug("%s:%d splash_height=%d splash_width=%d Buffer size=%d\n",
+			__func__, __LINE__, height, width, size);
+
+	ihdl = ion_alloc(iclient, size, SZ_1M,
+			ION_HEAP(ION_QSECOM_HEAP_ID), 0);
+	if (IS_ERR_OR_NULL(ihdl)) {
+		pr_err("unable to alloc fbmem from ion (%p)\n", ihdl);
+		return -ENOMEM;
+	}
+
+	pdata->panel_info.splash_ihdl = ihdl;
+
+	virt = ion_map_kernel(iclient, ihdl);
+	ion_phys(iclient, ihdl, &phys, &size);
+
+	pr_debug("%s %d Allocating %u bytes at 0x%lx (%lx phys)\n",
+			__func__, __LINE__, size,
+			(unsigned long int)virt, phys);
+
+	bl_fb_addr_va = (unsigned long *)ioremap(bl_fb_addr, size);
+
+	memcpy(virt, bl_fb_addr_va, size);
+
+	MDSS_MDP_REG_WRITE(pipe_addr, phys);
+	MDSS_MDP_REG_WRITE(MDSS_MDP_REG_CTL_FLUSH + MDSS_MDP_REG_CTL_OFFSET(0),
+			0x48);
+
+	return 0;
+
+}
+
+int mdss_mdp_reconfigure_splash_done(struct mdss_mdp_ctl *ctl)
+{
+	struct ion_client *iclient = mdss_get_ionclient();
+	struct mdss_panel_data *pdata;
+	int ret = 0, off;
+
+	off = 0;
+
+	pdata = ctl->panel_data;
+
+	pdata->panel_info.cont_splash_enabled = 0;
+
+	ion_free(iclient, pdata->panel_info.splash_ihdl);
+
+	mdss_mdp_ctl_write(ctl, 0, MDSS_MDP_LM_BORDER_COLOR);
+	off = MDSS_MDP_REG_INTF_OFFSET(ctl->intf_num);
+
+	/* wait for 1 VSYNC for the pipe to be unstaged */
+	msleep(20);
+	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_TIMING_ENGINE_EN, 0);
+	ret = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_CONT_SPLASH_FINISH,
+			NULL);
+	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+	mdss_mdp_footswitch_ctrl_splash(0);
+	return ret;
+}
+
+static int mdss_mdp_overlay_start(struct msm_fb_data_type *mfd)
+{
+	int rc;
+
+	if (mfd->ctl->power_on)
+		return 0;
+
+	pr_debug("starting fb%d overlay\n", mfd->index);
+
+	rc = pm_runtime_get_sync(&mfd->pdev->dev);
+	if (IS_ERR_VALUE(rc)) {
+		pr_err("unable to resume with pm_runtime_get_sync rc=%d\n", rc);
+		return rc;
+	}
+
+	if (mfd->panel_info->cont_splash_enabled)
+		mdss_mdp_reconfigure_splash_done(mfd->ctl);
+
+	if (!is_mdss_iommu_attached()) {
+		mdss_iommu_attach(mdss_res);
+		mdss_hw_init(mdss_res);
+	}
+
+	rc = mdss_mdp_ctl_start(mfd->ctl);
+	if (rc == 0) {
+		atomic_inc(&ov_active_panels);
+	} else {
+		pr_err("overlay start failed.\n");
+		mdss_mdp_ctl_destroy(mfd->ctl);
+		mfd->ctl = NULL;
+
+		pm_runtime_put(&mfd->pdev->dev);
+	}
+
+	return rc;
+}
+
+int mdss_mdp_overlay_kickoff(struct mdss_mdp_ctl *ctl)
 {
 	struct msm_fb_data_type *mfd = ctl->mfd;
+	struct mdss_mdp_pipe *pipe;
 	int ret;
 
 	mutex_lock(&mfd->ov_lock);
+	mutex_lock(&mfd->lock);
+	list_for_each_entry(pipe, &mfd->pipes_used, used_list) {
+		struct mdss_mdp_data *buf;
+		if (pipe->back_buf.num_planes) {
+			buf = &pipe->back_buf;
+		} else if (!pipe->params_changed) {
+			continue;
+		} else if (pipe->front_buf.num_planes) {
+			buf = &pipe->front_buf;
+		} else {
+			pr_warn("pipe queue without buffer\n");
+			buf = NULL;
+		}
+
+		ret = mdss_mdp_pipe_queue_data(pipe, buf);
+		if (IS_ERR_VALUE(ret)) {
+			pr_warn("Unable to queue data for pnum=%d\n",
+					pipe->num);
+			mdss_mdp_overlay_free_buf(buf);
+		}
+	}
 
 	if (mfd->kickoff_fnc)
 		ret = mfd->kickoff_fnc(ctl);
 	else
 		ret = mdss_mdp_display_commit(ctl, NULL);
+	mutex_unlock(&mfd->lock);
+
 	if (IS_ERR_VALUE(ret)) {
 		mutex_unlock(&mfd->ov_lock);
 		return ret;
 	}
 
+	ret = mdss_mdp_display_wait4comp(ctl);
+
 	complete(&mfd->update.comp);
 	mutex_lock(&mfd->no_update.lock);
 	if (mfd->no_update.timer.function)
@@ -494,8 +687,8 @@
 		pipe_ndx = BIT(i);
 		if (pipe_ndx & ndx) {
 			unset_ndx |= pipe_ndx;
-			pipe = mdss_mdp_pipe_get_locked(pipe_ndx);
-			if (!pipe) {
+			pipe = mdss_mdp_pipe_get(mfd->mdata, pipe_ndx);
+			if (IS_ERR_OR_NULL(pipe)) {
 				pr_warn("unknown pipe ndx=%x\n", pipe_ndx);
 				continue;
 			}
@@ -504,6 +697,7 @@
 			list_add(&pipe->cleanup_list, &mfd->pipes_cleanup);
 			mutex_unlock(&mfd->lock);
 			mdss_mdp_mixer_pipe_unstage(pipe);
+			mdss_mdp_pipe_unmap(pipe);
 		}
 	}
 	return 0;
@@ -520,6 +714,12 @@
 	if (ret)
 		return ret;
 
+	if (ndx == BORDERFILL_NDX) {
+		pr_debug("borderfill disable\n");
+		mfd->borderfill_enable = false;
+		return 0;
+	}
+
 	if (!mfd->panel_power_on) {
 		mutex_unlock(&mfd->ov_lock);
 		return -EPERM;
@@ -549,6 +749,13 @@
 		unset_ndx |= pipe->ndx;
 		cnt++;
 	}
+
+	if (cnt == 0 && !list_empty(&mfd->pipes_cleanup)) {
+		pr_warn("overlay release on fb%d called without commit!",
+			mfd->index);
+		cnt++;
+	}
+
 	mutex_unlock(&mfd->lock);
 
 	if (unset_ndx) {
@@ -597,41 +804,38 @@
 	ret = mdss_mdp_overlay_get_buf(mfd, &src_data, &req->data, 1, flgs);
 	if (ret) {
 		pr_err("src_data pmem error\n");
-		goto rotate_done;
+		return ret;
 	}
 
 	ret = mdss_mdp_overlay_get_buf(mfd, &dst_data, &req->dst_data, 1, flgs);
 	if (ret) {
 		pr_err("dst_data pmem error\n");
-		goto rotate_done;
+		goto dst_buf_fail;
 	}
 
 	ret = mdss_mdp_rotator_queue(rot, &src_data, &dst_data);
-	if (ret) {
+	if (ret)
 		pr_err("rotator queue error session id=%x\n", req->id);
-		goto rotate_done;
-	}
 
-rotate_done:
 	mdss_mdp_overlay_free_buf(&dst_data);
+dst_buf_fail:
 	mdss_mdp_overlay_free_buf(&src_data);
 
-	return 0;
+	return ret;
 }
 
 static int mdss_mdp_overlay_queue(struct msm_fb_data_type *mfd,
 				  struct msmfb_overlay_data *req)
 {
-	struct mdss_mdp_ctl *ctl;
 	struct mdss_mdp_pipe *pipe;
 	struct mdss_mdp_data *src_data;
 	int ret;
 	u32 flags;
 
-	pipe = mdss_mdp_pipe_get_locked(req->id);
-	if (pipe == NULL) {
+	pipe = mdss_mdp_pipe_get(mfd->mdata, req->id);
+	if (IS_ERR_OR_NULL(pipe)) {
 		pr_err("pipe ndx=%x doesn't exist\n", req->id);
-		return -ENODEV;
+		return pipe ? PTR_ERR(pipe) : -ENODEV;
 	}
 
 	pr_debug("ov queue pnum=%d\n", pipe->num);
@@ -648,13 +852,8 @@
 	ret = mdss_mdp_overlay_get_buf(mfd, src_data, &req->data, 1, flags);
 	if (IS_ERR_VALUE(ret)) {
 		pr_err("src_data pmem error\n");
-	} else {
-		ret = mdss_mdp_pipe_queue_data(pipe, src_data);
-		if (IS_ERR_VALUE(ret))
-			mdss_mdp_overlay_free_buf(src_data);
 	}
-	ctl = pipe->mixer->ctl;
-	mdss_mdp_pipe_unlock(pipe);
+	mdss_mdp_pipe_unmap(pipe);
 
 	return ret;
 }
@@ -675,16 +874,20 @@
 		return -EPERM;
 	}
 
+	ret = mdss_mdp_overlay_start(mfd);
+	if (ret) {
+		pr_err("unable to start overlay %d (%d)\n", mfd->index, ret);
+		return ret;
+	}
+
 	if (req->id & MDSS_MDP_ROT_SESSION_MASK) {
 		ret = mdss_mdp_overlay_rotate(mfd, req);
+	} else if (req->id == BORDERFILL_NDX) {
+		pr_debug("borderfill enable\n");
+		mfd->borderfill_enable = true;
+		ret = mdss_mdp_overlay_free_fb_pipe(mfd);
 	} else {
 		ret = mdss_mdp_overlay_queue(mfd, req);
-
-		if ((ret == 0) && (mfd->panel.type == WRITEBACK_PANEL)) {
-			mutex_unlock(&mfd->ov_lock);
-			ret = mdss_mdp_overlay_kickoff(mfd->ctl);
-			return ret;
-		}
 	}
 
 	mutex_unlock(&mfd->ov_lock);
@@ -692,6 +895,28 @@
 	return ret;
 }
 
+static int mdss_mdp_overlay_free_fb_pipe(struct msm_fb_data_type *mfd)
+{
+	struct mdss_mdp_pipe *pipe;
+	u32 fb_ndx = 0;
+
+	pipe = mdss_mdp_mixer_stage_pipe(mfd->ctl, MDSS_MDP_MIXER_MUX_LEFT,
+					 MDSS_MDP_STAGE_BASE);
+	if (pipe)
+		fb_ndx |= pipe->ndx;
+
+	pipe = mdss_mdp_mixer_stage_pipe(mfd->ctl, MDSS_MDP_MIXER_MUX_RIGHT,
+					 MDSS_MDP_STAGE_BASE);
+	if (pipe)
+		fb_ndx |= pipe->ndx;
+
+	if (fb_ndx) {
+		pr_debug("unstaging framebuffer pipes %x\n", fb_ndx);
+		mdss_mdp_overlay_release(mfd, fb_ndx);
+	}
+	return 0;
+}
+
 static int mdss_mdp_overlay_get_fb_pipe(struct msm_fb_data_type *mfd,
 					struct mdss_mdp_pipe **ppipe,
 					int mixer_mux)
@@ -767,7 +992,7 @@
 
 	fbi = mfd->fbi;
 
-	if (fbi->fix.smem_len == 0) {
+	if (fbi->fix.smem_len == 0 || mfd->borderfill_enable) {
 		mdss_mdp_overlay_kickoff(mfd->ctl);
 		return;
 	}
@@ -792,6 +1017,12 @@
 		return;
 	}
 
+	ret = mdss_mdp_overlay_start(mfd);
+	if (ret) {
+		pr_err("unable to start overlay %d (%d)\n", mfd->index, ret);
+		return;
+	}
+
 	if (is_mdss_iommu_attached())
 		data.p[0].addr = mfd->iova;
 	else
@@ -807,24 +1038,30 @@
 		return;
 	}
 
-	mdss_mdp_pipe_lock(pipe);
+	if (mdss_mdp_pipe_map(pipe)) {
+		pr_err("unable to map base pipe\n");
+		return;
+	}
 	ret = mdss_mdp_pipe_queue_data(pipe, &data);
-	mdss_mdp_pipe_unlock(pipe);
+	mdss_mdp_pipe_unmap(pipe);
 	if (ret) {
 		pr_err("unable to queue data\n");
 		return;
 	}
 
-	if (fbi->var.xres > MAX_MIXER_WIDTH) {
+	if (fbi->var.xres > MAX_MIXER_WIDTH || mfd->split_display) {
 		ret = mdss_mdp_overlay_get_fb_pipe(mfd, &pipe,
 						   MDSS_MDP_MIXER_MUX_RIGHT);
 		if (ret) {
 			pr_err("unable to allocate right base pipe\n");
 			return;
 		}
-		mdss_mdp_pipe_lock(pipe);
+		if (mdss_mdp_pipe_map(pipe)) {
+			pr_err("unable to map right base pipe\n");
+			return;
+		}
 		ret = mdss_mdp_pipe_queue_data(pipe, &data);
-		mdss_mdp_pipe_unlock(pipe);
+		mdss_mdp_pipe_unmap(pipe);
 		if (ret) {
 			pr_err("unable to queue right data\n");
 			return;
@@ -832,7 +1069,8 @@
 	}
 	mutex_unlock(&mfd->ov_lock);
 
-	if (fbi->var.activate & FB_ACTIVATE_VBL)
+	if ((fbi->var.activate & FB_ACTIVATE_VBL) ||
+	    (fbi->var.activate & FB_ACTIVATE_FORCE))
 		mdss_mdp_overlay_kickoff(mfd->ctl);
 }
 
@@ -864,10 +1102,15 @@
 	if (!ctl->set_vsync_handler)
 		return -ENOTSUPP;
 
+	rc = mutex_lock_interruptible(&ctl->lock);
+	if (rc)
+		return rc;
+
 	if (!ctl->power_on) {
 		pr_debug("fb%d vsync pending first update en=%d\n",
 				mfd->index, en);
 		mfd->vsync_pending = en;
+		mutex_unlock(&ctl->lock);
 		return 0;
 	}
 
@@ -875,10 +1118,6 @@
 
 	spin_lock_irqsave(&mfd->vsync_lock, flags);
 	INIT_COMPLETION(mfd->vsync_comp);
-	if (en && ctl->play_cnt == 0) {
-		mfd->vsync_time = ktime_get();
-		complete(&mfd->vsync_comp);
-	}
 	spin_unlock_irqrestore(&mfd->vsync_lock, flags);
 
 	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
@@ -888,6 +1127,8 @@
 		rc = ctl->set_vsync_handler(ctl, NULL);
 	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
 
+	mutex_unlock(&ctl->lock);
+
 	return rc;
 }
 
@@ -898,17 +1139,19 @@
 	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
 	unsigned long flags;
 	u64 vsync_ticks;
+	unsigned long timeout;
 	int ret;
 
 	if (!mfd->ctl || !mfd->ctl->power_on)
 		return 0;
 
+	timeout = msecs_to_jiffies(VSYNC_PERIOD * 5);
 	ret = wait_for_completion_interruptible_timeout(&mfd->vsync_comp,
-			msecs_to_jiffies(VSYNC_PERIOD * 5));
+			timeout);
 	if (ret <= 0) {
-		pr_warn("vsync wait on fb%d interrupted (%d)\n",
-			mfd->index, ret);
-		return -EBUSY;
+		pr_warn("Sending current time as vsync timestamp for fb%d\n",
+				mfd->index);
+		mfd->vsync_time = ktime_get();
 	}
 
 	spin_lock_irqsave(&mfd->vsync_lock, flags);
@@ -1162,7 +1405,9 @@
 		}
 		break;
 	case MSMFB_OVERLAY_COMMIT:
+		mdss_fb_wait_for_fence(mfd);
 		ret = mdss_mdp_overlay_kickoff(mfd->ctl);
+		mdss_fb_signal_timeline(mfd);
 		break;
 	default:
 		if (mfd->panel.type == WRITEBACK_PANEL)
@@ -1175,11 +1420,56 @@
 
 static int mdss_mdp_overlay_on(struct msm_fb_data_type *mfd)
 {
-	int rc;
+	int rc = 0;
 
-	rc = mdss_mdp_ctl_on(mfd);
-	if (rc == 0)
-		atomic_inc(&ov_active_panels);
+	if (!mfd)
+		return -ENODEV;
+
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	if (!mfd->ctl) {
+		struct mdss_mdp_ctl *ctl;
+		struct mdss_panel_data *pdata;
+
+		pdata = dev_get_platdata(&mfd->pdev->dev);
+		if (!pdata) {
+			pr_err("no panel connected for fb%d\n", mfd->index);
+			return -ENODEV;
+		}
+
+		ctl = mdss_mdp_ctl_init(pdata, mfd);
+		if (IS_ERR_OR_NULL(ctl)) {
+			pr_err("Unable to initialize ctl for fb%d\n",
+				mfd->index);
+			return PTR_ERR(ctl);
+		}
+
+		if (mfd->split_display && pdata->next) {
+			/* enable split display */
+			rc = mdss_mdp_ctl_split_display_setup(ctl, pdata->next);
+			if (rc) {
+				mdss_mdp_ctl_destroy(ctl);
+				return rc;
+			}
+		}
+		mfd->ctl = ctl;
+	}
+
+	if (!mfd->panel_info->cont_splash_enabled) {
+		rc = mdss_mdp_overlay_start(mfd);
+		if (!IS_ERR_VALUE(rc))
+			rc = mdss_mdp_overlay_kickoff(mfd->ctl);
+	} else {
+		rc = mdss_mdp_ctl_setup(mfd->ctl);
+		if (rc)
+			return rc;
+	}
+
+	if (!IS_ERR_VALUE(rc) && mfd->vsync_pending) {
+		mfd->vsync_pending = 0;
+		mdss_mdp_overlay_vsync_ctrl(mfd, mfd->vsync_pending);
+	}
 
 	return rc;
 }
@@ -1188,12 +1478,36 @@
 {
 	int rc;
 
+	if (!mfd)
+		return -ENODEV;
+
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	if (!mfd->ctl) {
+		pr_err("ctl not initialized\n");
+		return -ENODEV;
+	}
+
+	if (!mfd->ctl->power_on)
+		return 0;
+
 	mdss_mdp_overlay_release_all(mfd);
 
-	rc = mdss_mdp_ctl_off(mfd);
+	rc = mdss_mdp_ctl_stop(mfd->ctl);
 	if (rc == 0) {
+		if (!mfd->ref_cnt) {
+			mfd->borderfill_enable = false;
+			mdss_mdp_ctl_destroy(mfd->ctl);
+			mfd->ctl = NULL;
+		}
+
 		if (atomic_dec_return(&ov_active_panels) == 0)
 			mdss_mdp_rotator_release_all();
+
+		rc = pm_runtime_put(&mfd->pdev->dev);
+		if (rc)
+			pr_err("unable to suspend w/pm_runtime_put (%d)\n", rc);
 	}
 
 	return rc;
@@ -1204,6 +1518,12 @@
 	struct device *dev = mfd->fbi->dev;
 	int rc;
 
+	mfd->mdata = dev_get_drvdata(mfd->pdev->dev.parent);
+	if (!mfd->mdata) {
+		pr_err("unable to initialize overlay for fb%d\n", mfd->index);
+		return -ENODEV;
+	}
+
 	mfd->on_fnc = mdss_mdp_overlay_on;
 	mfd->off_fnc = mdss_mdp_overlay_off;
 	mfd->hw_refresh = true;
@@ -1228,6 +1548,9 @@
 		return rc;
 	}
 
+	pm_runtime_set_suspended(&mfd->pdev->dev);
+	pm_runtime_enable(&mfd->pdev->dev);
+
 	kobject_uevent(&dev->kobj, KOBJ_ADD);
 	pr_debug("vsync kobject_uevent(KOBJ_ADD)\n");
 
diff --git a/drivers/video/msm/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c
index ade7cb4..8c88646 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pipe.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -25,7 +25,9 @@
 static DEFINE_MUTEX(mdss_mdp_smp_lock);
 static DECLARE_BITMAP(mdss_mdp_smp_mmb_pool, MDSS_MDP_SMP_MMB_BLOCKS);
 
-static struct mdss_mdp_pipe mdss_mdp_pipe_list[MDSS_MDP_MAX_SSPP];
+static struct mdss_mdp_pipe *mdss_mdp_pipe_search(struct mdss_data_type *mdata,
+						  u32 ndx);
+static int mdss_mdp_pipe_free(struct mdss_mdp_pipe *pipe);
 
 static u32 mdss_mdp_smp_mmb_reserve(unsigned long *smp, size_t n)
 {
@@ -96,6 +98,9 @@
 		num_blks = DIV_ROUND_UP(2 * ps.ystride[i],
 			mdss_res->smp_mb_size);
 
+		if (mdss_res->mdp_rev == MDSS_MDP_HW_REV_100)
+			num_blks = roundup_pow_of_two(num_blks);
+
 		pr_debug("reserving %d mmb for pnum=%d plane=%d\n",
 				num_blks, pipe->num, i);
 		reserved = mdss_mdp_smp_mmb_reserve(&pipe->smp[i], num_blks);
@@ -117,179 +122,201 @@
 
 static int mdss_mdp_smp_alloc(struct mdss_mdp_pipe *pipe)
 {
-	u32 client_id;
 	int i;
-
-	switch (pipe->num) {
-	case MDSS_MDP_SSPP_VIG0:
-		client_id = MDSS_MDP_SMP_CLIENT_VIG0_FETCH_Y;
-		break;
-	case MDSS_MDP_SSPP_VIG1:
-		client_id = MDSS_MDP_SMP_CLIENT_VIG1_FETCH_Y;
-		break;
-	case MDSS_MDP_SSPP_VIG2:
-		client_id = MDSS_MDP_SMP_CLIENT_VIG2_FETCH_Y;
-		break;
-	case MDSS_MDP_SSPP_RGB0:
-		client_id = MDSS_MDP_SMP_CLIENT_RGB0_FETCH;
-		break;
-	case MDSS_MDP_SSPP_RGB1:
-		client_id = MDSS_MDP_SMP_CLIENT_RGB1_FETCH;
-		break;
-	case MDSS_MDP_SSPP_RGB2:
-		client_id = MDSS_MDP_SMP_CLIENT_RGB2_FETCH;
-		break;
-	case MDSS_MDP_SSPP_DMA0:
-		client_id = MDSS_MDP_SMP_CLIENT_DMA0_FETCH_Y;
-		break;
-	case MDSS_MDP_SSPP_DMA1:
-		client_id = MDSS_MDP_SMP_CLIENT_DMA1_FETCH_Y;
-		break;
-	default:
-		pr_err("no valid smp client for pnum=%d\n", pipe->num);
-		return -EINVAL;
-	}
-
 	mutex_lock(&mdss_mdp_smp_lock);
 	for (i = 0; i < pipe->src_planes.num_planes; i++)
-		mdss_mdp_smp_mmb_set(client_id + i, &pipe->smp[i]);
+		mdss_mdp_smp_mmb_set(pipe->ftch_id + i, &pipe->smp[i]);
 	mutex_unlock(&mdss_mdp_smp_lock);
 	return 0;
 }
 
-void mdss_mdp_pipe_unlock(struct mdss_mdp_pipe *pipe)
+void mdss_mdp_pipe_unmap(struct mdss_mdp_pipe *pipe)
 {
-	atomic_dec(&pipe->ref_cnt);
-	mutex_unlock(&pipe->lock);
+	int tmp;
+
+	tmp = atomic_dec_return(&pipe->ref_cnt);
+
+	WARN(tmp < 0, "Invalid unmap with ref_cnt=%d", tmp);
+	if (tmp == 0)
+		mdss_mdp_pipe_free(pipe);
 }
 
-int mdss_mdp_pipe_lock(struct mdss_mdp_pipe *pipe)
+int mdss_mdp_pipe_map(struct mdss_mdp_pipe *pipe)
 {
-	if (atomic_inc_not_zero(&pipe->ref_cnt)) {
-		if (mutex_lock_interruptible(&pipe->lock)) {
-			atomic_dec(&pipe->ref_cnt);
-			return -EINTR;
-		}
-		return 0;
+	if (!atomic_inc_not_zero(&pipe->ref_cnt)) {
+		pr_err("attempting to map unallocated pipe (%d)", pipe->num);
+		return -EINVAL;
 	}
-	return -EINVAL;
+	return 0;
 }
 
-static struct mdss_mdp_pipe *mdss_mdp_pipe_init(u32 pnum)
+static struct mdss_mdp_pipe *mdss_mdp_pipe_init(struct mdss_mdp_mixer *mixer,
+						u32 type)
 {
-	struct mdss_mdp_pipe *pipe = NULL;
+	struct mdss_mdp_pipe *pipe;
+	struct mdss_data_type *mdata;
+	struct mdss_mdp_pipe *pipe_pool = NULL;
+	u32 npipes;
+	u32 i;
 
-	if (atomic_read(&mdss_mdp_pipe_list[pnum].ref_cnt) == 0) {
-		pipe = &mdss_mdp_pipe_list[pnum];
-		memset(pipe, 0, sizeof(*pipe));
-
-		mutex_init(&pipe->lock);
-		atomic_set(&pipe->ref_cnt, 1);
-
-		if (mdss_mdp_pipe_lock(pipe) == 0) {
-			pipe->num = pnum;
-			pipe->type = mdss_res->pipe_type_map[pnum];
-			pipe->ndx = BIT(pnum);
-
-			pr_debug("ndx=%x pnum=%d\n", pipe->ndx, pipe->num);
-		} else {
-			atomic_set(&pipe->ref_cnt, 0);
-			pipe = NULL;
-		}
-	}
-	return pipe;
-}
-
-struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_pnum(u32 pnum)
-{
-	struct mdss_mdp_pipe *pipe = NULL;
-	mutex_lock(&mdss_mdp_sspp_lock);
-	if (mdss_res->pipe_type_map[pnum] != MDSS_MDP_PIPE_TYPE_UNUSED)
-		pipe = mdss_mdp_pipe_init(pnum);
-	mutex_unlock(&mdss_mdp_sspp_lock);
-	return pipe;
-}
-
-struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_locked(u32 type)
-{
-	struct mdss_mdp_pipe *pipe = NULL;
-	int pnum;
-
-	mutex_lock(&mdss_mdp_sspp_lock);
-	for (pnum = 0; pnum < MDSS_MDP_MAX_SSPP; pnum++) {
-		if (type == mdss_res->pipe_type_map[pnum]) {
-			pipe = mdss_mdp_pipe_init(pnum);
-			if (pipe)
-				break;
-		}
-	}
-	mutex_unlock(&mdss_mdp_sspp_lock);
-
-	return pipe;
-}
-
-struct mdss_mdp_pipe *mdss_mdp_pipe_get_locked(u32 ndx)
-{
-	struct mdss_mdp_pipe *pipe = NULL;
-	int i;
-
-	if (!ndx)
+	if (!mixer || !mixer->ctl || !mixer->ctl->mdata)
 		return NULL;
 
-	mutex_lock(&mdss_mdp_sspp_lock);
-	for (i = 0; i < MDSS_MDP_MAX_SSPP; i++) {
-		pipe = &mdss_mdp_pipe_list[i];
-		if (ndx == pipe->ndx)
+	mdata = mixer->ctl->mdata;
+
+	switch (type) {
+	case MDSS_MDP_PIPE_TYPE_VIG:
+		pipe_pool = mdata->vig_pipes;
+		npipes = mdata->nvig_pipes;
+		break;
+
+	case MDSS_MDP_PIPE_TYPE_RGB:
+		pipe_pool = mdata->rgb_pipes;
+		npipes = mdata->nrgb_pipes;
+		break;
+
+	case MDSS_MDP_PIPE_TYPE_DMA:
+		pipe_pool = mdata->dma_pipes;
+		npipes = mdata->ndma_pipes;
+		break;
+
+	default:
+		npipes = 0;
+		pr_err("invalid pipe type %d\n", type);
+		break;
+	}
+
+	for (i = 0; i < npipes; i++) {
+		pipe = pipe_pool + i;
+		if (atomic_cmpxchg(&pipe->ref_cnt, 0, 1) == 0) {
+			pipe->mixer = mixer;
 			break;
-	}
-	mutex_unlock(&mdss_mdp_sspp_lock);
-
-	if (i == MDSS_MDP_MAX_SSPP)
-		return NULL;
-
-	if (mdss_mdp_pipe_lock(pipe))
-		return NULL;
-
-	if (pipe->ndx != ndx) {
-		mdss_mdp_pipe_unlock(pipe);
+		}
 		pipe = NULL;
 	}
 
+	if (pipe)
+		pr_debug("type=%x   pnum=%d\n", pipe->type, pipe->num);
+	else
+		pr_err("no %d type pipes available\n", type);
+
 	return pipe;
 }
 
-
-static void mdss_mdp_pipe_free(struct mdss_mdp_pipe *pipe)
+struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_dma(struct mdss_mdp_mixer *mixer)
 {
-	mdss_mdp_smp_free(pipe);
-	pipe->ndx = 0;
-	atomic_dec(&pipe->ref_cnt);
-	mdss_mdp_pipe_unlock(pipe);
+	struct mdss_mdp_pipe *pipe = NULL;
+	struct mdss_data_type *mdata;
+	u32 pnum;
+
+	mutex_lock(&mdss_mdp_sspp_lock);
+	mdata = mixer->ctl->mdata;
+	pnum = mixer->num;
+
+	if (atomic_cmpxchg(&((mdata->dma_pipes[pnum]).ref_cnt), 0, 1) == 0) {
+		pipe = &mdata->dma_pipes[pnum];
+		pipe->mixer = mixer;
+
+	} else {
+		pr_err("DMA pnum%d\t not available\n", pnum);
+	}
+
+	mutex_unlock(&mdss_mdp_sspp_lock);
+	return pipe;
 }
 
-int mdss_mdp_pipe_destroy(struct mdss_mdp_pipe *pipe)
+struct mdss_mdp_pipe *mdss_mdp_pipe_alloc(struct mdss_mdp_mixer *mixer,
+						 u32 type)
+{
+	struct mdss_mdp_pipe *pipe;
+	mutex_lock(&mdss_mdp_sspp_lock);
+	pipe = mdss_mdp_pipe_init(mixer, type);
+	mutex_unlock(&mdss_mdp_sspp_lock);
+	return pipe;
+}
+
+struct mdss_mdp_pipe *mdss_mdp_pipe_get(struct mdss_data_type *mdata, u32 ndx)
+{
+	struct mdss_mdp_pipe *pipe = NULL;
+
+	if (!ndx)
+		return ERR_PTR(-EINVAL);
+
+	mutex_lock(&mdss_mdp_sspp_lock);
+
+	pipe = mdss_mdp_pipe_search(mdata, ndx);
+	if (!pipe)
+		return ERR_PTR(-EINVAL);
+
+	if (mdss_mdp_pipe_map(pipe))
+		return ERR_PTR(-EACCES);
+
+	mutex_unlock(&mdss_mdp_sspp_lock);
+
+	return pipe;
+}
+
+static struct mdss_mdp_pipe *mdss_mdp_pipe_search(struct mdss_data_type *mdata,
+						  u32 ndx)
+{
+	u32 i;
+	for (i = 0; i < mdata->nvig_pipes; i++) {
+		if (mdata->vig_pipes[i].ndx == ndx)
+			return &mdata->vig_pipes[i];
+	}
+
+	for (i = 0; i < mdata->nrgb_pipes; i++) {
+		if (mdata->rgb_pipes[i].ndx == ndx)
+			return &mdata->rgb_pipes[i];
+	}
+
+	for (i = 0; i < mdata->ndma_pipes; i++) {
+		if (mdata->dma_pipes[i].ndx == ndx)
+			return &mdata->dma_pipes[i];
+	}
+
+	return NULL;
+}
+
+static int mdss_mdp_pipe_free(struct mdss_mdp_pipe *pipe)
 {
 	pr_debug("ndx=%x pnum=%d ref_cnt=%d\n", pipe->ndx, pipe->num,
 			atomic_read(&pipe->ref_cnt));
 
 	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
-	mdss_mdp_pipe_free(pipe);
+	mdss_mdp_pipe_sspp_term(pipe);
+	mdss_mdp_smp_free(pipe);
 	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
 
 	return 0;
 }
 
+int mdss_mdp_pipe_destroy(struct mdss_mdp_pipe *pipe)
+{
+	int tmp;
+
+	tmp = atomic_dec_return(&pipe->ref_cnt);
+
+	if (tmp != 0) {
+		pr_err("unable to free pipe %d while still in use (%d)\n",
+				pipe->num, tmp);
+		return -EBUSY;
+	}
+	mdss_mdp_pipe_free(pipe);
+
+	return 0;
+
+}
+
 static inline void mdss_mdp_pipe_write(struct mdss_mdp_pipe *pipe,
 				       u32 reg, u32 val)
 {
-	int offset = MDSS_MDP_REG_SSPP_OFFSET(pipe->num);
-	MDSS_MDP_REG_WRITE(offset + reg, val);
+	writel_relaxed(val, pipe->base + reg);
 }
 
 static inline u32 mdss_mdp_pipe_read(struct mdss_mdp_pipe *pipe, u32 reg)
 {
-	int offset = MDSS_MDP_REG_SSPP_OFFSET(pipe->num);
-	return MDSS_MDP_REG_READ(offset + reg);
+	return readl_relaxed(pipe->base + reg);
 }
 
 static int mdss_mdp_leading_zero(u32 num)
@@ -575,6 +602,8 @@
 		unpack = 0;
 	}
 
+	mdss_mdp_pipe_sspp_setup(pipe, &opmode);
+
 	mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC_FORMAT, src_format);
 	mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC_UNPACK_PATTERN, unpack);
 	mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC_OP_MODE, opmode);
@@ -583,43 +612,6 @@
 	return 0;
 }
 
-static int mdss_mdp_vig_setup(struct mdss_mdp_pipe *pipe)
-{
-	u32 opmode = 0;
-
-	pr_debug("pnum=%x\n", pipe->num);
-
-	/* CSC Post Processing enabled? */
-	if (pipe->flags & MDP_OVERLAY_PP_CFG_EN) {
-		if (pipe->pp_cfg.config_ops & MDP_OVERLAY_PP_CSC_CFG) {
-			if (pipe->pp_cfg.csc_cfg.flags & MDP_CSC_FLAG_ENABLE)
-				opmode |= 1 << 17;	/* CSC_1_EN */
-			if (pipe->pp_cfg.csc_cfg.flags & MDP_CSC_FLAG_YUV_IN)
-				opmode |= 1 << 18;	/* SRC_DATA=YCBCR */
-			if (pipe->pp_cfg.csc_cfg.flags & MDP_CSC_FLAG_YUV_OUT)
-				opmode |= 1 << 19;	/* DST_DATA=YCBCR */
-			/* only need to program once */
-			if (pipe->play_cnt == 0)
-				mdss_mdp_csc_setup_data(MDSS_MDP_BLOCK_SSPP,
-				  pipe->num, 1, &pipe->pp_cfg.csc_cfg);
-		}
-	} else {
-		if (pipe->src_fmt->is_yuv)
-			opmode |= (0 << 19) |	/* DST_DATA=RGB */
-				  (1 << 18) |	/* SRC_DATA=YCBCR */
-				  (1 << 17);	/* CSC_1_EN */
-		/* only need to program once */
-		if (pipe->play_cnt == 0) {
-			mdss_mdp_csc_setup(MDSS_MDP_BLOCK_SSPP, pipe->num, 1,
-					   MDSS_MDP_CSC_YUV2RGB);
-		}
-	}
-
-	mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_VIG_OP_MODE, opmode);
-
-	return 0;
-}
-
 static void mdss_mdp_addr_add_offset(struct mdss_mdp_pipe *pipe,
 				    struct mdss_mdp_data *data)
 {
@@ -642,6 +634,53 @@
 	}
 }
 
+int mdss_mdp_pipe_addr_setup(struct mdss_data_type *mdata, u32 *offsets,
+				u32 *ftch_id, u32 type, u32 num_base, u32 len)
+{
+	struct mdss_mdp_pipe *head;
+	u32 i;
+	int rc = 0;
+
+	head = devm_kzalloc(&mdata->pdev->dev, sizeof(struct mdss_mdp_pipe) *
+			len, GFP_KERNEL);
+
+	if (!head) {
+		pr_err("unable to setup pipe type=%d :devm_kzalloc fail\n",
+			type);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < len; i++) {
+		head[i].type = type;
+		head[i].ftch_id  = ftch_id[i];
+		head[i].num = i + num_base;
+		head[i].ndx = BIT(i + num_base);
+		head[i].base = mdata->mdp_base + offsets[i];
+	}
+
+	switch (type) {
+
+	case MDSS_MDP_PIPE_TYPE_VIG:
+		mdata->vig_pipes = head;
+		break;
+
+	case MDSS_MDP_PIPE_TYPE_RGB:
+		mdata->rgb_pipes = head;
+		break;
+
+	case MDSS_MDP_PIPE_TYPE_DMA:
+		mdata->dma_pipes = head;
+		break;
+
+	default:
+		pr_err("Invalid pipe type=%d\n", type);
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
 static int mdss_mdp_src_addr_setup(struct mdss_mdp_pipe *pipe,
 				   struct mdss_mdp_data *data)
 {
@@ -673,11 +712,33 @@
 	return 0;
 }
 
+static int mdss_mdp_pipe_solidfill_setup(struct mdss_mdp_pipe *pipe)
+{
+	int ret;
+	u32 secure, format;
+
+	pr_debug("solid fill setup on pnum=%d\n", pipe->num);
+
+	ret = mdss_mdp_image_setup(pipe);
+	if (ret) {
+		pr_err("image setup error for pnum=%d\n", pipe->num);
+		return ret;
+	}
+
+	format = MDSS_MDP_FMT_SOLID_FILL;
+	secure = (pipe->flags & MDP_SECURE_OVERLAY_SESSION ? 0xF : 0x0);
+
+	mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC_FORMAT, format);
+	mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC_ADDR_SW_STATUS, secure);
+
+	return 0;
+}
+
 int mdss_mdp_pipe_queue_data(struct mdss_mdp_pipe *pipe,
 			     struct mdss_mdp_data *src_data)
 {
 	int ret = 0;
-	u32 params_changed;
+	u32 params_changed, opmode;
 
 	if (!pipe) {
 		pr_err("pipe not setup properly for queue\n");
@@ -695,6 +756,11 @@
 	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
 
 	params_changed = pipe->params_changed;
+	if (src_data == NULL) {
+		mdss_mdp_pipe_solidfill_setup(pipe);
+		goto update_nobuf;
+	}
+
 	if (params_changed) {
 		pipe->params_changed = 0;
 
@@ -711,8 +777,10 @@
 			goto done;
 		}
 
+		mdss_mdp_pipe_pp_setup(pipe, &opmode);
 		if (pipe->type == MDSS_MDP_PIPE_TYPE_VIG)
-			mdss_mdp_vig_setup(pipe);
+			mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_VIG_OP_MODE,
+			opmode);
 
 		ret = mdss_mdp_smp_reserve(pipe);
 		if (ret) {
@@ -730,6 +798,7 @@
 		goto done;
 	}
 
+update_nobuf:
 	mdss_mdp_mixer_pipe_update(pipe, params_changed);
 
 	pipe->play_cnt++;
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index e4be407..59d760b 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -77,12 +78,7 @@
 
 #define MDSS_BLOCK_DISP_NUM	(MDP_BLOCK_MAX - MDP_LOGICAL_BLOCK_DISP_0)
 
-#define IGC_LUT_ENTRIES	256
-#define GC_LUT_SEGMENTS	16
-#define ENHIST_LUT_ENTRIES 256
-#define HIST_V_SIZE	256
-
-#define HIST_WAIT_TIMEOUT	1000
+#define HIST_WAIT_TIMEOUT(frame) ((60 * HZ * (frame)) / 1000)
 /* hist collect state */
 enum {
 	HIST_UNKNOWN,
@@ -121,17 +117,6 @@
 	GAMUT_T2_SIZE + GAMUT_T3_SIZE + GAMUT_T4_SIZE + \
 	GAMUT_T5_SIZE + GAMUT_T6_SIZE + GAMUT_T7_SIZE)
 
-struct pp_sts_type {
-	u32 pa_sts;
-	u32 pcc_sts;
-	u32 igc_sts;
-	u32 igc_tbl_idx;
-	u32 argc_sts;
-	u32 enhist_sts;
-	u32 dither_sts;
-	u32 gamut_sts;
-};
-
 #define PP_FLAGS_DIRTY_PA	0x1
 #define PP_FLAGS_DIRTY_PCC	0x2
 #define PP_FLAGS_DIRTY_IGC	0x4
@@ -140,6 +125,8 @@
 #define PP_FLAGS_DIRTY_DITHER	0x20
 #define PP_FLAGS_DIRTY_GAMUT	0x40
 #define PP_FLAGS_DIRTY_HIST_COL	0x80
+#define PP_FLAGS_DIRTY_PGC	0x100
+#define PP_FLAGS_DIRTY_SHARP	0x200
 
 #define PP_STS_ENABLE	0x1
 #define PP_STS_GAMUT_FIRST	0x2
@@ -156,9 +143,10 @@
 	struct mdp_ar_gc_lut_data
 		gc_lut_b[MDSS_BLOCK_DISP_NUM][GC_LUT_SEGMENTS];
 	u32 enhist_lut[MDSS_BLOCK_DISP_NUM][ENHIST_LUT_ENTRIES];
-	struct mdp_pa_cfg_data pa_disp_cfg[MDSS_BLOCK_DISP_NUM];
+	struct mdp_pa_cfg pa_disp_cfg[MDSS_BLOCK_DISP_NUM];
 	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];
 	struct mdp_pgc_lut_data pgc_disp_cfg[MDSS_BLOCK_DISP_NUM];
 	struct mdp_hist_lut_data enhist_disp_cfg[MDSS_BLOCK_DISP_NUM];
 	struct mdp_dither_cfg_data dither_disp_cfg[MDSS_BLOCK_DISP_NUM];
@@ -177,17 +165,29 @@
 static DEFINE_MUTEX(mdss_mdp_hist_mutex);
 static struct mdss_pp_res_type *mdss_pp_res;
 
-
 static void pp_hist_read(u32 v_base, struct pp_hist_col_info *hist_info);
-
 static void pp_update_pcc_regs(u32 offset,
 				struct mdp_pcc_cfg_data *cfg_ptr);
 static void pp_update_igc_lut(struct mdp_igc_lut_data *cfg,
 				u32 offset, u32 blk_idx);
 static void pp_update_gc_one_lut(u32 offset,
-		struct mdp_ar_gc_lut_data *lut_data);
+				struct mdp_ar_gc_lut_data *lut_data);
 static void pp_update_argc_lut(u32 offset,
-		struct mdp_pgc_lut_data *config);
+				struct mdp_pgc_lut_data *config);
+static void pp_update_hist_lut(u32 offset, struct mdp_hist_lut_data *cfg);
+static void pp_pa_config(unsigned long flags, u32 base,
+				struct pp_sts_type *pp_sts,
+				struct mdp_pa_cfg *pa_config);
+static void pp_pcc_config(unsigned long flags, u32 base,
+				struct pp_sts_type *pp_sts,
+				struct mdp_pcc_cfg_data *pcc_config);
+static void pp_igc_config(unsigned long flags, u32 base,
+				struct pp_sts_type *pp_sts,
+				struct mdp_igc_lut_data *igc_config,
+				u32 pipe_num);
+static void pp_enhist_config(unsigned long flags, u32 base,
+				struct pp_sts_type *pp_sts,
+				struct mdp_hist_lut_data *enhist_cfg);
 
 int mdss_mdp_csc_setup_data(u32 block, u32 blk_idx, u32 tbl_idx,
 				   struct mdp_csc_cfg *data)
@@ -277,51 +277,9 @@
 	data = &mdp_csc_convert[csc_type];
 	return mdss_mdp_csc_setup_data(block, blk_idx, tbl_idx, data);
 }
-static int pp_mixer_setup(u32 disp_num, struct mdss_mdp_ctl *ctl,
-		struct mdss_mdp_mixer *mixer)
-{
-	u32 flags, offset, dspp_num, opmode = 0;
-	struct mdp_pgc_lut_data *pgc_config;
-	struct pp_sts_type *pp_sts;
-	dspp_num = mixer->num;
-	/* no corresponding dspp */
-	if ((mixer->type != MDSS_MDP_MIXER_TYPE_INTF) ||
-		(dspp_num >= MDSS_MDP_MAX_DSPP))
-		return 0;
-	if (disp_num < MDSS_BLOCK_DISP_NUM)
-		flags = mdss_pp_res->pp_disp_flags[disp_num];
-	else
-		flags = 0;
 
-	pp_sts = &mdss_pp_res->pp_dspp_sts[dspp_num];
-	/* GC_LUT is in layer mixer */
-	if (flags & PP_FLAGS_DIRTY_ARGC) {
-		pgc_config = &mdss_pp_res->pgc_disp_cfg[disp_num];
-		if (pgc_config->flags & MDP_PP_OPS_WRITE) {
-			offset = MDSS_MDP_REG_LM_OFFSET(disp_num) +
-				MDSS_MDP_REG_LM_GC_LUT_BASE;
-			pp_update_argc_lut(offset, pgc_config);
-		}
-		if (pgc_config->flags & MDP_PP_OPS_DISABLE)
-			pp_sts->argc_sts &= ~PP_STS_ENABLE;
-		else if (pgc_config->flags & MDP_PP_OPS_ENABLE)
-			pp_sts->argc_sts |= PP_STS_ENABLE;
-		ctl->flush_bits |= BIT(6) << dspp_num; /* LAYER_MIXER */
-	}
-	/* update LM opmode if LM needs flush */
-	if ((pp_sts->argc_sts & PP_STS_ENABLE) &&
-		(ctl->flush_bits & (BIT(6) << dspp_num))) {
-		offset = MDSS_MDP_REG_LM_OFFSET(dspp_num) +
-			MDSS_MDP_REG_LM_OP_MODE;
-		opmode = MDSS_MDP_REG_READ(offset);
-		opmode |= (1 << 0); /* GC_LUT_EN */
-		MDSS_MDP_REG_WRITE(offset, opmode);
-	}
-	return 0;
-}
 static void pp_gamut_config(struct mdp_gamut_cfg_data *gamut_cfg,
-							u32 base,
-							u32 *gamut_sts)
+				u32 base, struct pp_sts_type *pp_sts)
 {
 	u32 offset;
 	int i, j;
@@ -346,103 +304,61 @@
 			offset += 4;
 		}
 		if (gamut_cfg->gamut_first)
-			*gamut_sts |= PP_STS_GAMUT_FIRST;
+			pp_sts->gamut_sts |= PP_STS_GAMUT_FIRST;
 	}
 
 	if (gamut_cfg->flags & MDP_PP_OPS_DISABLE)
-		*gamut_sts &= ~PP_STS_ENABLE;
+		pp_sts->gamut_sts &= ~PP_STS_ENABLE;
 	else if (gamut_cfg->flags & MDP_PP_OPS_ENABLE)
-		*gamut_sts |= PP_STS_ENABLE;
+		pp_sts->gamut_sts |= PP_STS_ENABLE;
 }
-static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_ctl *ctl,
-		struct mdss_mdp_mixer *mixer)
+
+static void pp_pa_config(unsigned long flags, u32 base,
+				struct pp_sts_type *pp_sts,
+				struct mdp_pa_cfg *pa_config)
 {
-	u32 flags, base, offset, dspp_num, opmode = 0;
-	struct mdp_pa_cfg_data *pa_config;
-	struct mdp_pcc_cfg_data *pcc_config;
-	struct mdp_igc_lut_data *igc_config;
-	struct mdp_hist_lut_data *enhist_cfg;
-	struct mdp_dither_cfg_data *dither_cfg;
-	struct pp_hist_col_info *hist_info;
-	struct pp_sts_type *pp_sts;
-	u32 data, tbl_idx, col_state;
-	unsigned long flag;
-	int i;
-	dspp_num = mixer->num;
-	/* no corresponding dspp */
-	if ((mixer->type != MDSS_MDP_MIXER_TYPE_INTF) ||
-		(dspp_num >= MDSS_MDP_MAX_DSPP))
-		return 0;
-	base = MDSS_MDP_REG_DSPP_OFFSET(dspp_num);
-	hist_info = &mdss_pp_res->dspp_hist[dspp_num];
-	if (hist_info->col_en) {
-		/* HIST_EN & AUTO_CLEAR */
-		opmode |= (1 << 16) | (1 << 17);
-		mutex_lock(&mdss_mdp_hist_mutex);
-		spin_lock_irqsave(&mdss_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))) {
-			/* Kick off collection */
-			MDSS_MDP_REG_WRITE(base +
-				MDSS_MDP_REG_DSPP_HIST_CTL_BASE, 1);
-			hist_info->col_state = HIST_START;
-		}
-		hist_info->is_kick_ready = true;
-		spin_unlock_irqrestore(&mdss_hist_lock, flag);
-		mutex_unlock(&mdss_mdp_hist_mutex);
-	}
-
-	if (disp_num < MDSS_BLOCK_DISP_NUM)
-		flags = mdss_pp_res->pp_disp_flags[disp_num];
-	else
-		flags = 0;
-
-	/* nothing to update */
-	if ((!flags) && (!(hist_info->col_en)))
-		return 0;
-	pp_sts = &mdss_pp_res->pp_dspp_sts[dspp_num];
 	if (flags & PP_FLAGS_DIRTY_PA) {
-		pa_config = &mdss_pp_res->pa_disp_cfg[disp_num];
 		if (pa_config->flags & MDP_PP_OPS_WRITE) {
-			offset = base + MDSS_MDP_REG_DSPP_PA_BASE;
-			MDSS_MDP_REG_WRITE(offset, pa_config->hue_adj);
-			offset += 4;
-			MDSS_MDP_REG_WRITE(offset, pa_config->sat_adj);
-			offset += 4;
-			MDSS_MDP_REG_WRITE(offset, pa_config->val_adj);
-			offset += 4;
-			MDSS_MDP_REG_WRITE(offset, pa_config->cont_adj);
+			MDSS_MDP_REG_WRITE(base, pa_config->hue_adj);
+			base += 4;
+			MDSS_MDP_REG_WRITE(base, pa_config->sat_adj);
+			base += 4;
+			MDSS_MDP_REG_WRITE(base, pa_config->val_adj);
+			base += 4;
+			MDSS_MDP_REG_WRITE(base, pa_config->cont_adj);
 		}
 		if (pa_config->flags & MDP_PP_OPS_DISABLE)
 			pp_sts->pa_sts &= ~PP_STS_ENABLE;
 		else if (pa_config->flags & MDP_PP_OPS_ENABLE)
 			pp_sts->pa_sts |= PP_STS_ENABLE;
 	}
-	if (pp_sts->pa_sts & PP_STS_ENABLE)
-		opmode |= (1 << 20); /* PA_EN */
+}
+
+static void pp_pcc_config(unsigned long flags, u32 base,
+				struct pp_sts_type *pp_sts,
+				struct mdp_pcc_cfg_data *pcc_config)
+{
 	if (flags & PP_FLAGS_DIRTY_PCC) {
-		pcc_config = &mdss_pp_res->pcc_disp_cfg[disp_num];
-		if (pcc_config->ops & MDP_PP_OPS_WRITE) {
-			offset = base + MDSS_MDP_REG_DSPP_PCC_BASE;
-			pp_update_pcc_regs(offset, pcc_config);
-		}
+		if (pcc_config->ops & MDP_PP_OPS_WRITE)
+			pp_update_pcc_regs(base, pcc_config);
+
 		if (pcc_config->ops & MDP_PP_OPS_DISABLE)
 			pp_sts->pcc_sts &= ~PP_STS_ENABLE;
 		else if (pcc_config->ops & MDP_PP_OPS_ENABLE)
 			pp_sts->pcc_sts |= PP_STS_ENABLE;
 	}
-	if (pp_sts->pcc_sts & PP_STS_ENABLE)
-		opmode |= (1 << 4); /* PCC_EN */
+}
 
+static void pp_igc_config(unsigned long flags, u32 base,
+				struct pp_sts_type *pp_sts,
+				struct mdp_igc_lut_data *igc_config,
+				u32 pipe_num)
+{
+	u32 tbl_idx;
 	if (flags & PP_FLAGS_DIRTY_IGC) {
-		igc_config = &mdss_pp_res->igc_disp_cfg[disp_num];
-		if (igc_config->ops & MDP_PP_OPS_WRITE) {
-			offset = MDSS_MDP_REG_IGC_DSPP_BASE;
-			pp_update_igc_lut(igc_config, offset, dspp_num);
-		}
+		if (igc_config->ops & MDP_PP_OPS_WRITE)
+			pp_update_igc_lut(igc_config, base, pipe_num);
+
 		if (igc_config->ops & MDP_PP_IGC_FLAG_ROM0) {
 			pp_sts->pcc_sts |= PP_STS_ENABLE;
 			tbl_idx = 1;
@@ -458,24 +374,310 @@
 		else if (igc_config->ops & MDP_PP_OPS_ENABLE)
 			pp_sts->igc_sts |= PP_STS_ENABLE;
 	}
-	if (pp_sts->igc_sts & PP_STS_ENABLE) {
-		opmode |= (1 << 0) | /* IGC_LUT_EN */
-			      (pp_sts->igc_tbl_idx << 1);
-	}
+}
+
+static void pp_enhist_config(unsigned long flags, u32 base,
+				struct pp_sts_type *pp_sts,
+				struct mdp_hist_lut_data *enhist_cfg)
+{
 	if (flags & PP_FLAGS_DIRTY_ENHIST) {
-		enhist_cfg = &mdss_pp_res->enhist_disp_cfg[disp_num];
-		if (enhist_cfg->ops & MDP_PP_OPS_WRITE) {
-			offset = base + MDSS_MDP_REG_DSPP_HIST_LUT_BASE;
-			for (i = 0; i < ENHIST_LUT_ENTRIES; i++)
-				MDSS_MDP_REG_WRITE(offset, enhist_cfg->data[i]);
-			/* swap */
-			MDSS_MDP_REG_WRITE(offset + 4, 1);
-		}
+		if (enhist_cfg->ops & MDP_PP_OPS_WRITE)
+			pp_update_hist_lut(base, enhist_cfg);
+
 		if (enhist_cfg->ops & MDP_PP_OPS_DISABLE)
 			pp_sts->enhist_sts &= ~PP_STS_ENABLE;
 		else if (enhist_cfg->ops & MDP_PP_OPS_ENABLE)
 			pp_sts->enhist_sts |= PP_STS_ENABLE;
 	}
+}
+
+static void pp_sharp_config(unsigned long flags, u32 base,
+				struct pp_sts_type *pp_sts,
+				struct mdp_sharp_cfg *sharp_config)
+{
+	if (flags & PP_FLAGS_DIRTY_SHARP) {
+		if (sharp_config->flags & MDP_PP_OPS_WRITE) {
+			MDSS_MDP_REG_WRITE(base, sharp_config->strength);
+			base += 4;
+			MDSS_MDP_REG_WRITE(base, sharp_config->edge_thr);
+			base += 4;
+			MDSS_MDP_REG_WRITE(base, sharp_config->smooth_thr);
+			base += 4;
+			MDSS_MDP_REG_WRITE(base, sharp_config->noise_thr);
+		}
+		if (sharp_config->flags & MDP_PP_OPS_DISABLE)
+			pp_sts->sharp_sts &= ~PP_STS_ENABLE;
+		else if (sharp_config->flags & MDP_PP_OPS_ENABLE)
+			pp_sts->sharp_sts |= PP_STS_ENABLE;
+	}
+}
+
+
+static int pp_vig_pipe_setup(struct mdss_mdp_pipe *pipe, u32 *op)
+{
+	u32 opmode = 0, base = 0;
+	unsigned long flags = 0;
+	u32 upscaling = 1;
+
+	pr_debug("pnum=%x\n", pipe->num);
+
+	if ((pipe->flags & MDP_OVERLAY_PP_CFG_EN) &&
+		(pipe->pp_cfg.config_ops & MDP_OVERLAY_PP_CSC_CFG)) {
+			opmode |= !!(pipe->pp_cfg.csc_cfg.flags &
+						MDP_CSC_FLAG_ENABLE) << 17;
+			opmode |= !!(pipe->pp_cfg.csc_cfg.flags &
+						MDP_CSC_FLAG_YUV_IN) << 18;
+			opmode |= !!(pipe->pp_cfg.csc_cfg.flags &
+						MDP_CSC_FLAG_YUV_OUT) << 19;
+			/*
+			 * TODO: Allow pipe to be programmed whenever new CSC is
+			 * applied (i.e. dirty bit)
+			 */
+			if (pipe->play_cnt == 0)
+				mdss_mdp_csc_setup_data(MDSS_MDP_BLOCK_SSPP,
+				  pipe->num, 1, &pipe->pp_cfg.csc_cfg);
+	} else {
+		if (pipe->src_fmt->is_yuv)
+			opmode |= (0 << 19) |	/* DST_DATA=RGB */
+				  (1 << 18) |	/* SRC_DATA=YCBCR */
+				  (1 << 17);	/* CSC_1_EN */
+		/*
+		 * TODO: Needs to be part of dirty bit logic: if there is a
+		 * previously configured pipe need to re-configure CSC matrix
+		 */
+		if (pipe->play_cnt == 0) {
+			mdss_mdp_csc_setup(MDSS_MDP_BLOCK_SSPP, pipe->num, 1,
+					   MDSS_MDP_CSC_YUV2RGB);
+		}
+	}
+
+	if (pipe->flags & MDP_OVERLAY_PP_CFG_EN) {
+		if (pipe->pp_cfg.config_ops & MDP_OVERLAY_PP_PA_CFG) {
+			flags = PP_FLAGS_DIRTY_PA;
+			base = MDSS_MDP_REG_SSPP_OFFSET(pipe->num) +
+				MDSS_MDP_REG_VIG_PA_BASE;
+			pp_pa_config(flags, base, &pipe->pp_res.pp_sts,
+					&pipe->pp_cfg.pa_cfg);
+
+			if (pipe->pp_res.pp_sts.pa_sts & PP_STS_ENABLE)
+				opmode |= (1 << 4); /* PA_EN */
+		}
+
+		if (pipe->pp_cfg.config_ops & MDP_OVERLAY_PP_SHARP_CFG) {
+			if ((pipe->dst.w < pipe->src.w) ||
+				(pipe->dst.h < pipe->src.h))
+				upscaling = 0;
+			if ((pipe->src_fmt->is_yuv) && upscaling) {
+				flags = PP_FLAGS_DIRTY_SHARP;
+				base = MDSS_MDP_REG_SSPP_OFFSET(pipe->num) +
+					MDSS_MDP_REG_VIG_QSEED2_SHARP;
+				pp_sharp_config(flags, base,
+					&pipe->pp_res.pp_sts,
+					&pipe->pp_cfg.sharp_cfg);
+
+				if (pipe->pp_res.pp_sts.sharp_sts &
+					PP_STS_ENABLE)
+					MDSS_MDP_REG_WRITE(
+					   MDSS_MDP_REG_SSPP_OFFSET(pipe->num) +
+					   MDSS_MDP_REG_VIG_QSEED2_CONFIG,
+					   1 << 0 | 1 << 1);
+			}
+		}
+	}
+
+	*op = opmode;
+
+	return 0;
+}
+
+int mdss_mdp_pipe_pp_setup(struct mdss_mdp_pipe *pipe, u32 *op)
+{
+	int ret = 0;
+	if (!pipe)
+		return -ENODEV;
+
+	if (pipe->type == MDSS_MDP_PIPE_TYPE_VIG)
+		ret = pp_vig_pipe_setup(pipe, op);
+	else if (pipe->type == MDSS_MDP_PIPE_TYPE_RGB)
+		ret = -EINVAL;
+	else if (pipe->type == MDSS_MDP_PIPE_TYPE_DMA)
+		ret = -EINVAL;
+
+	return ret;
+}
+
+void mdss_mdp_pipe_sspp_term(struct mdss_mdp_pipe *pipe)
+{
+	memset(&pipe->pp_cfg, 0, sizeof(struct mdp_overlay_pp_params));
+	memset(&pipe->pp_res, 0, sizeof(struct mdss_pipe_pp_res));
+}
+
+int mdss_mdp_pipe_sspp_setup(struct mdss_mdp_pipe *pipe, u32 *op)
+{
+	int ret = 0;
+	unsigned long flags = 0;
+	u32 pipe_base;
+	u32 pipe_num;
+
+	if (pipe == NULL)
+		return -EINVAL;
+
+	/*
+	 * TODO: should this function be responsible for masking multiple
+	 * pipes to be written in dual pipe case?
+	 * if so, requires rework of update_igc_lut
+	 */
+	switch (pipe->type) {
+	case MDSS_MDP_PIPE_TYPE_VIG:
+		pipe_base = MDSS_MDP_REG_IGC_VIG_BASE;
+		pipe_num = pipe->num - MDSS_MDP_SSPP_VIG0;
+		break;
+	case MDSS_MDP_PIPE_TYPE_RGB:
+		pipe_base = MDSS_MDP_REG_IGC_RGB_BASE;
+		pipe_num = pipe->num - MDSS_MDP_SSPP_RGB0;
+		break;
+	case MDSS_MDP_PIPE_TYPE_DMA:
+		pipe_base = MDSS_MDP_REG_IGC_DMA_BASE;
+		pipe_num = pipe->num - MDSS_MDP_SSPP_DMA0;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (pipe->pp_cfg.config_ops & MDP_OVERLAY_PP_IGC_CFG) {
+		flags |= PP_FLAGS_DIRTY_IGC;
+		pp_igc_config(flags, pipe_base, &pipe->pp_res.pp_sts,
+					&pipe->pp_cfg.igc_cfg, pipe_num);
+	}
+
+	if (pipe->pp_res.pp_sts.igc_sts & PP_STS_ENABLE)
+		*op |= (1 << 16); /* IGC_LUT_EN */
+
+	return ret;
+}
+
+static int pp_mixer_setup(u32 disp_num, struct mdss_mdp_ctl *ctl,
+		struct mdss_mdp_mixer *mixer)
+{
+	u32 flags, offset, dspp_num, opmode = 0;
+	struct mdp_pgc_lut_data *pgc_config;
+	struct pp_sts_type *pp_sts;
+	dspp_num = mixer->num;
+
+	/* no corresponding dspp */
+	if ((mixer->type != MDSS_MDP_MIXER_TYPE_INTF) ||
+		(dspp_num >= MDSS_MDP_MAX_DSPP))
+		return 0;
+	if (disp_num < MDSS_BLOCK_DISP_NUM)
+		flags = mdss_pp_res->pp_disp_flags[disp_num];
+	else
+		flags = 0;
+
+	pp_sts = &mdss_pp_res->pp_dspp_sts[dspp_num];
+	/* GC_LUT is in layer mixer */
+	if (flags & PP_FLAGS_DIRTY_ARGC) {
+		pgc_config = &mdss_pp_res->argc_disp_cfg[disp_num];
+		if (pgc_config->flags & MDP_PP_OPS_WRITE) {
+			offset = MDSS_MDP_REG_LM_OFFSET(disp_num) +
+				MDSS_MDP_REG_LM_GC_LUT_BASE;
+			pp_update_argc_lut(offset, pgc_config);
+		}
+		if (pgc_config->flags & MDP_PP_OPS_DISABLE)
+			pp_sts->argc_sts &= ~PP_STS_ENABLE;
+		else if (pgc_config->flags & MDP_PP_OPS_ENABLE)
+			pp_sts->argc_sts |= PP_STS_ENABLE;
+		ctl->flush_bits |= BIT(6) << dspp_num; /* LAYER_MIXER */
+	}
+	/* update LM opmode if LM needs flush */
+	if ((pp_sts->argc_sts & PP_STS_ENABLE) &&
+		(ctl->flush_bits & (BIT(6) << dspp_num))) {
+		offset = MDSS_MDP_REG_LM_OFFSET(dspp_num) +
+			MDSS_MDP_REG_LM_OP_MODE;
+		opmode = MDSS_MDP_REG_READ(offset);
+		opmode |= (1 << 0); /* GC_LUT_EN */
+		MDSS_MDP_REG_WRITE(offset, opmode);
+	}
+	return 0;
+}
+
+static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_ctl *ctl,
+				struct mdss_mdp_mixer *mixer)
+{
+	u32 flags, base, offset, dspp_num, opmode = 0;
+	struct mdp_dither_cfg_data *dither_cfg;
+	struct pp_hist_col_info *hist_info;
+	struct mdp_pgc_lut_data *pgc_config;
+	struct pp_sts_type *pp_sts;
+	u32 data, col_state;
+	unsigned long flag;
+	int i, ret = 0;
+
+	if (!mixer || !ctl)
+		return -EINVAL;
+
+	dspp_num = mixer->num;
+	/* no corresponding dspp */
+	if ((mixer->type != MDSS_MDP_MIXER_TYPE_INTF) ||
+		(dspp_num >= MDSS_MDP_MAX_DSPP))
+		return -EINVAL;
+	base = MDSS_MDP_REG_DSPP_OFFSET(dspp_num);
+	hist_info = &mdss_pp_res->dspp_hist[dspp_num];
+
+	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
+
+	if (hist_info->col_en) {
+		/* HIST_EN & AUTO_CLEAR */
+		opmode |= (1 << 16) | (1 << 17);
+		mutex_lock(&mdss_mdp_hist_mutex);
+		spin_lock_irqsave(&mdss_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))) {
+			/* Kick off collection */
+			MDSS_MDP_REG_WRITE(base +
+				MDSS_MDP_REG_DSPP_HIST_CTL_BASE, 1);
+			hist_info->col_state = HIST_START;
+		}
+		spin_unlock_irqrestore(&mdss_hist_lock, flag);
+		mutex_unlock(&mdss_mdp_hist_mutex);
+	}
+
+	if (disp_num < MDSS_BLOCK_DISP_NUM)
+		flags = mdss_pp_res->pp_disp_flags[disp_num];
+	else
+		flags = 0;
+
+	/* nothing to update */
+	if ((!flags) && (!(hist_info->col_en)))
+		goto dspp_exit;
+
+	pp_sts = &mdss_pp_res->pp_dspp_sts[dspp_num];
+
+	pp_pa_config(flags, base + MDSS_MDP_REG_DSPP_PA_BASE, pp_sts,
+					&mdss_pp_res->pa_disp_cfg[disp_num]);
+
+	pp_pcc_config(flags, base + MDSS_MDP_REG_DSPP_PCC_BASE, pp_sts,
+					&mdss_pp_res->pcc_disp_cfg[disp_num]);
+
+	pp_igc_config(flags, MDSS_MDP_REG_IGC_DSPP_BASE, pp_sts,
+				&mdss_pp_res->igc_disp_cfg[disp_num], dspp_num);
+
+	pp_enhist_config(flags, base + MDSS_MDP_REG_DSPP_HIST_LUT_BASE,
+			pp_sts, &mdss_pp_res->enhist_disp_cfg[disp_num]);
+
+	if (pp_sts->pa_sts & PP_STS_ENABLE)
+		opmode |= (1 << 20); /* PA_EN */
+
+	if (pp_sts->pcc_sts & PP_STS_ENABLE)
+		opmode |= (1 << 4); /* PCC_EN */
+
+	if (pp_sts->igc_sts & PP_STS_ENABLE) {
+		opmode |= (1 << 0) | /* IGC_LUT_EN */
+			      (pp_sts->igc_tbl_idx << 1);
+	}
+
 	if (pp_sts->enhist_sts & PP_STS_ENABLE) {
 		opmode |= (1 << 19) | /* HIST_LUT_EN */
 				  (1 << 20); /* PA_EN */
@@ -514,20 +716,59 @@
 	if (pp_sts->dither_sts & PP_STS_ENABLE)
 		opmode |= (1 << 8); /* DITHER_EN */
 	if (flags & PP_FLAGS_DIRTY_GAMUT)
-		pp_gamut_config(&mdss_pp_res->gamut_disp_cfg[disp_num],
-					base, &pp_sts->gamut_sts);
+		pp_gamut_config(&mdss_pp_res->gamut_disp_cfg[disp_num], base,
+				pp_sts);
 	if (pp_sts->gamut_sts & PP_STS_ENABLE) {
 		opmode |= (1 << 23); /* GAMUT_EN */
 		if (pp_sts->gamut_sts & PP_STS_GAMUT_FIRST)
 			opmode |= (1 << 24); /* GAMUT_ORDER */
 	}
 
+	if (flags & PP_FLAGS_DIRTY_PGC) {
+		pgc_config = &mdss_pp_res->pgc_disp_cfg[disp_num];
+		if (pgc_config->flags & MDP_PP_OPS_WRITE) {
+			offset = base + MDSS_MDP_REG_DSPP_GC_BASE;
+			pp_update_argc_lut(offset, pgc_config);
+		}
+		if (pgc_config->flags & MDP_PP_OPS_DISABLE)
+			pp_sts->pgc_sts &= ~PP_STS_ENABLE;
+		else if (pgc_config->flags & MDP_PP_OPS_ENABLE)
+			pp_sts->pgc_sts |= PP_STS_ENABLE;
+	}
+	if (pp_sts->pgc_sts & PP_STS_ENABLE)
+		opmode |= (1 << 22);
+
 	MDSS_MDP_REG_WRITE(base + MDSS_MDP_REG_DSPP_OP_MODE, opmode);
-	ctl->flush_bits |= BIT(13 + dspp_num); /* DSPP */
-	return 0;
+	mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_FLUSH, BIT(13 + dspp_num));
+	wmb();
+dspp_exit:
+	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+	return ret;
 }
+
 int mdss_mdp_pp_setup(struct mdss_mdp_ctl *ctl)
 {
+	int ret = 0;
+
+	if ((!ctl->mfd) || (!mdss_pp_res))
+		return -EINVAL;
+
+	/* TODO: have some sort of reader/writer lock to prevent unclocked
+	 * access while display power is toggled */
+	if (!ctl->mfd->panel_power_on) {
+		ret = -EPERM;
+		goto error;
+	}
+	mutex_lock(&ctl->mfd->lock);
+	ret = mdss_mdp_pp_setup_locked(ctl);
+	mutex_unlock(&ctl->mfd->lock);
+error:
+	return ret;
+}
+
+/* call only when holding and mfd->lock */
+int mdss_mdp_pp_setup_locked(struct mdss_mdp_ctl *ctl)
+{
 	u32 disp_num;
 	if ((!ctl->mfd) || (!mdss_pp_res))
 		return -EINVAL;
@@ -552,9 +793,87 @@
 	return 0;
 }
 
+/*
+ * Set dirty and write bits on features that were enabled so they will be
+ * reconfigured
+ */
+int mdss_mdp_pp_resume(u32 mixer_num)
+{
+	u32 flags = 0;
+	struct pp_sts_type pp_sts;
+
+	if (mixer_num >= MDSS_MDP_MAX_DSPP) {
+		pr_warn("invalid mixer_num");
+		return -EINVAL;
+	}
+
+	pp_sts = mdss_pp_res->pp_dspp_sts[mixer_num];
+
+	if (pp_sts.pa_sts & PP_STS_ENABLE) {
+		flags |= PP_FLAGS_DIRTY_PA;
+		if (!(mdss_pp_res->pa_disp_cfg[mixer_num].flags
+					& MDP_PP_OPS_DISABLE))
+			mdss_pp_res->pa_disp_cfg[mixer_num].flags |=
+				MDP_PP_OPS_WRITE;
+	}
+	if (pp_sts.pcc_sts & PP_STS_ENABLE) {
+		flags |= PP_FLAGS_DIRTY_PCC;
+		if (!(mdss_pp_res->pcc_disp_cfg[mixer_num].ops
+					& MDP_PP_OPS_DISABLE))
+			mdss_pp_res->pcc_disp_cfg[mixer_num].ops |=
+				MDP_PP_OPS_WRITE;
+	}
+	if (pp_sts.igc_sts & PP_STS_ENABLE) {
+		flags |= PP_FLAGS_DIRTY_IGC;
+		if (!(mdss_pp_res->igc_disp_cfg[mixer_num].ops
+					& MDP_PP_OPS_DISABLE))
+			mdss_pp_res->igc_disp_cfg[mixer_num].ops |=
+				MDP_PP_OPS_WRITE;
+	}
+	if (pp_sts.argc_sts & PP_STS_ENABLE) {
+		flags |= PP_FLAGS_DIRTY_ARGC;
+		if (!(mdss_pp_res->argc_disp_cfg[mixer_num].flags
+					& MDP_PP_OPS_DISABLE))
+			mdss_pp_res->argc_disp_cfg[mixer_num].flags |=
+				MDP_PP_OPS_WRITE;
+	}
+	if (pp_sts.enhist_sts & PP_STS_ENABLE) {
+		flags |= PP_FLAGS_DIRTY_ENHIST;
+		if (!(mdss_pp_res->enhist_disp_cfg[mixer_num].ops
+					& MDP_PP_OPS_DISABLE))
+			mdss_pp_res->enhist_disp_cfg[mixer_num].ops |=
+				MDP_PP_OPS_WRITE;
+	}
+	if (pp_sts.dither_sts & PP_STS_ENABLE) {
+		flags |= PP_FLAGS_DIRTY_DITHER;
+		if (!(mdss_pp_res->dither_disp_cfg[mixer_num].flags
+					& MDP_PP_OPS_DISABLE))
+			mdss_pp_res->dither_disp_cfg[mixer_num].flags |=
+				MDP_PP_OPS_WRITE;
+	}
+	if (pp_sts.gamut_sts & PP_STS_ENABLE) {
+		flags |= PP_FLAGS_DIRTY_GAMUT;
+		if (!(mdss_pp_res->gamut_disp_cfg[mixer_num].flags
+					& MDP_PP_OPS_DISABLE))
+			mdss_pp_res->gamut_disp_cfg[mixer_num].flags |=
+				MDP_PP_OPS_WRITE;
+	}
+	if (pp_sts.pgc_sts & PP_STS_ENABLE) {
+		flags |= PP_FLAGS_DIRTY_PGC;
+		if (!(mdss_pp_res->pgc_disp_cfg[mixer_num].flags
+					& MDP_PP_OPS_DISABLE))
+			mdss_pp_res->pgc_disp_cfg[mixer_num].flags |=
+				MDP_PP_OPS_WRITE;
+	}
+
+	mdss_pp_res->pp_disp_flags[mixer_num] = flags;
+	return 0;
+}
+
 int mdss_mdp_pp_init(struct device *dev)
 {
 	int ret = 0;
+
 	mutex_lock(&mdss_pp_mutex);
 	if (!mdss_pp_res) {
 		mdss_pp_res = devm_kzalloc(dev, sizeof(*mdss_pp_res),
@@ -580,7 +899,7 @@
 {
 	int i;
 	u32 mixer_cnt;
-	u32 mixer_id[MDSS_MDP_MAX_LAYERMIXER];
+	u32 mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER];
 	mixer_cnt = mdss_mdp_get_ctl_mixers(disp_num, mixer_id);
 
 	if (!mixer_cnt)
@@ -597,11 +916,15 @@
 	return 0;
 }
 
-int mdss_mdp_pa_config(struct mdp_pa_cfg_data *config, u32 *copyback)
+int mdss_mdp_pa_config(struct mdss_mdp_ctl *ctl, struct mdp_pa_cfg_data *config,
+			u32 *copyback)
 {
 	int ret = 0;
 	u32 pa_offset, disp_num, dspp_num = 0;
 
+	if (!ctl)
+		return -EINVAL;
+
 	if ((config->block < MDP_LOGICAL_BLOCK_DISP_0) ||
 		(config->block >= MDP_BLOCK_MAX))
 		return -EINVAL;
@@ -609,7 +932,7 @@
 	mutex_lock(&mdss_pp_mutex);
 	disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0;
 
-	if (config->flags & MDP_PP_OPS_READ) {
+	if (config->pa_data.flags & MDP_PP_OPS_READ) {
 		ret = pp_get_dspp_num(disp_num, &dspp_num);
 		if (ret) {
 			pr_err("%s, no dspp connects to disp %d",
@@ -619,22 +942,24 @@
 		mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
 		pa_offset = MDSS_MDP_REG_DSPP_OFFSET(dspp_num) +
 			  MDSS_MDP_REG_DSPP_PA_BASE;
-		config->hue_adj = MDSS_MDP_REG_READ(pa_offset);
+		config->pa_data.hue_adj = MDSS_MDP_REG_READ(pa_offset);
 		pa_offset += 4;
-		config->sat_adj = MDSS_MDP_REG_READ(pa_offset);
+		config->pa_data.sat_adj = MDSS_MDP_REG_READ(pa_offset);
 		pa_offset += 4;
-		config->val_adj = MDSS_MDP_REG_READ(pa_offset);
+		config->pa_data.val_adj = MDSS_MDP_REG_READ(pa_offset);
 		pa_offset += 4;
-		config->cont_adj = MDSS_MDP_REG_READ(pa_offset);
+		config->pa_data.cont_adj = MDSS_MDP_REG_READ(pa_offset);
 		*copyback = 1;
 		mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
 	} else {
-		mdss_pp_res->pa_disp_cfg[disp_num] = *config;
+		mdss_pp_res->pa_disp_cfg[disp_num] = config->pa_data;
 		mdss_pp_res->pp_disp_flags[disp_num] |= PP_FLAGS_DIRTY_PA;
 	}
 
 pa_config_exit:
 	mutex_unlock(&mdss_pp_mutex);
+	if (!ret)
+		mdss_mdp_pp_setup(ctl);
 	return ret;
 }
 
@@ -764,11 +1089,16 @@
 	MDSS_MDP_REG_WRITE(offset + 8, cfg_ptr->b.rgb_1);
 }
 
-int mdss_mdp_pcc_config(struct mdp_pcc_cfg_data *config, u32 *copyback)
+int mdss_mdp_pcc_config(struct mdss_mdp_ctl *ctl,
+					struct mdp_pcc_cfg_data *config,
+					u32 *copyback)
 {
 	int ret = 0;
 	u32 base, disp_num, dspp_num = 0;
 
+	if (!ctl)
+		return -EINVAL;
+
 	if ((config->block < MDP_LOGICAL_BLOCK_DISP_0) ||
 		(config->block >= MDP_BLOCK_MAX))
 		return -EINVAL;
@@ -798,8 +1128,9 @@
 
 pcc_config_exit:
 	mutex_unlock(&mdss_pp_mutex);
+	if (!ret)
+		mdss_mdp_pp_setup(ctl);
 	return ret;
-
 }
 
 static void pp_read_igc_lut(struct mdp_igc_lut_data *cfg,
@@ -856,12 +1187,17 @@
 		MDSS_MDP_REG_WRITE(offset, (cfg->c2_data[i] & 0xFFF) | data);
 }
 
-int mdss_mdp_igc_lut_config(struct mdp_igc_lut_data *config, u32 *copyback)
+int mdss_mdp_igc_lut_config(struct mdss_mdp_ctl *ctl,
+					struct mdp_igc_lut_data *config,
+					u32 *copyback)
 {
 	int ret = 0;
 	u32 tbl_idx, igc_offset, disp_num, dspp_num = 0;
 	struct mdp_igc_lut_data local_cfg;
 
+	if (!ctl)
+		return -EINVAL;
+
 	if ((config->block < MDP_LOGICAL_BLOCK_DISP_0) ||
 		(config->block >= MDP_BLOCK_MAX))
 		return -EINVAL;
@@ -923,6 +1259,8 @@
 
 igc_config_exit:
 	mutex_unlock(&mdss_pp_mutex);
+	if (!ret)
+		mdss_mdp_pp_setup(ctl);
 	return ret;
 }
 static void pp_update_gc_one_lut(u32 offset,
@@ -1009,21 +1347,59 @@
 	pp_read_gc_one_lut(offset, config->b_data);
 	return ret;
 }
-int mdss_mdp_argc_config(struct mdp_pgc_lut_data *config, u32 *copyback)
+
+/* Note: Assumes that its inputs have been checked by calling function */
+static void pp_update_hist_lut(u32 offset, struct mdp_hist_lut_data *cfg)
+{
+	int i;
+	for (i = 0; i < ENHIST_LUT_ENTRIES; i++)
+		MDSS_MDP_REG_WRITE(offset, cfg->data[i]);
+	/* swap */
+	MDSS_MDP_REG_WRITE(offset + 4, 1);
+}
+
+int mdss_mdp_argc_config(struct mdss_mdp_ctl *ctl,
+				struct mdp_pgc_lut_data *config,
+				u32 *copyback)
 {
 	int ret = 0;
-	u32 argc_offset, disp_num, dspp_num = 0;
+	u32 argc_offset = 0, disp_num, dspp_num = 0;
 	struct mdp_pgc_lut_data local_cfg;
+	struct mdp_pgc_lut_data *pgc_ptr;
 	u32 tbl_size;
 
-	if ((config->block < MDP_LOGICAL_BLOCK_DISP_0) ||
-		(config->block >= MDP_BLOCK_MAX))
+	if (!ctl)
+		return -EINVAL;
+
+	if ((PP_BLOCK(config->block) < MDP_LOGICAL_BLOCK_DISP_0) ||
+		(PP_BLOCK(config->block) >= MDP_BLOCK_MAX))
 		return -EINVAL;
 
 	mutex_lock(&mdss_pp_mutex);
-	disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0;
+
+	disp_num = PP_BLOCK(config->block) - MDP_LOGICAL_BLOCK_DISP_0;
+	switch (config->block & MDSS_PP_LOCATION_MASK) {
+	case MDSS_PP_LM_CFG:
+		argc_offset = MDSS_MDP_REG_LM_OFFSET(dspp_num) +
+			MDSS_MDP_REG_LM_GC_LUT_BASE;
+		pgc_ptr = &mdss_pp_res->argc_disp_cfg[disp_num];
+		mdss_pp_res->pp_disp_flags[disp_num] |=
+			PP_FLAGS_DIRTY_ARGC;
+		break;
+	case MDSS_PP_DSPP_CFG:
+		argc_offset = MDSS_MDP_REG_DSPP_OFFSET(dspp_num) +
+					MDSS_MDP_REG_DSPP_GC_BASE;
+		pgc_ptr = &mdss_pp_res->pgc_disp_cfg[disp_num];
+		mdss_pp_res->pp_disp_flags[disp_num] |=
+			PP_FLAGS_DIRTY_PGC;
+		break;
+	default:
+		goto argc_config_exit;
+		break;
+	}
 
 	tbl_size = GC_LUT_SEGMENTS * sizeof(struct mdp_ar_gc_lut_data);
+
 	if (config->flags & MDP_PP_OPS_READ) {
 		ret = pp_get_dspp_num(disp_num, &dspp_num);
 		if (ret) {
@@ -1032,10 +1408,6 @@
 			goto argc_config_exit;
 		}
 		mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
-
-		argc_offset = MDSS_MDP_REG_LM_OFFSET(dspp_num) +
-				MDSS_MDP_REG_LM_GC_LUT_BASE;
-		mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
 		local_cfg = *config;
 		local_cfg.r_data =
 			&mdss_pp_res->gc_lut_r[disp_num][0];
@@ -1077,24 +1449,31 @@
 			ret = -EFAULT;
 			goto argc_config_exit;
 		}
-		mdss_pp_res->pgc_disp_cfg[disp_num] = *config;
-		mdss_pp_res->pgc_disp_cfg[disp_num].r_data =
+
+		*pgc_ptr = *config;
+		pgc_ptr->r_data =
 			&mdss_pp_res->gc_lut_r[disp_num][0];
-		mdss_pp_res->pgc_disp_cfg[disp_num].g_data =
+		pgc_ptr->g_data =
 			&mdss_pp_res->gc_lut_g[disp_num][0];
-		mdss_pp_res->pgc_disp_cfg[disp_num].b_data =
+		pgc_ptr->b_data =
 			&mdss_pp_res->gc_lut_b[disp_num][0];
-		mdss_pp_res->pp_disp_flags[disp_num] |= PP_FLAGS_DIRTY_ARGC;
 	}
 argc_config_exit:
 	mutex_unlock(&mdss_pp_mutex);
+	if (!ret)
+		mdss_mdp_pp_setup(ctl);
 	return ret;
 }
-int mdss_mdp_hist_lut_config(struct mdp_hist_lut_data *config, u32 *copyback)
+int mdss_mdp_hist_lut_config(struct mdss_mdp_ctl *ctl,
+					struct mdp_hist_lut_data *config,
+					u32 *copyback)
 {
 	int i, ret = 0;
 	u32 hist_offset, disp_num, dspp_num = 0;
 
+	if (!ctl)
+		return -EINVAL;
+
 	if ((config->block < MDP_LOGICAL_BLOCK_DISP_0) ||
 		(config->block >= MDP_BLOCK_MAX))
 		return -EINVAL;
@@ -1137,12 +1516,19 @@
 	}
 enhist_config_exit:
 	mutex_unlock(&mdss_pp_mutex);
+	if (!ret)
+		mdss_mdp_pp_setup(ctl);
 	return ret;
 }
 
-int mdss_mdp_dither_config(struct mdp_dither_cfg_data *config, u32 *copyback)
+int mdss_mdp_dither_config(struct mdss_mdp_ctl *ctl,
+					struct mdp_dither_cfg_data *config,
+					u32 *copyback)
 {
 	u32 disp_num;
+	if (!ctl)
+		return -EINVAL;
+
 	if ((config->block < MDP_LOGICAL_BLOCK_DISP_0) ||
 		(config->block >= MDP_BLOCK_MAX))
 		return -EINVAL;
@@ -1154,16 +1540,22 @@
 	mdss_pp_res->dither_disp_cfg[disp_num] = *config;
 	mdss_pp_res->pp_disp_flags[disp_num] |= PP_FLAGS_DIRTY_DITHER;
 	mutex_unlock(&mdss_pp_mutex);
+	mdss_mdp_pp_setup(ctl);
 	return 0;
 }
 
-int mdss_mdp_gamut_config(struct mdp_gamut_cfg_data *config, u32 *copyback)
+int mdss_mdp_gamut_config(struct mdss_mdp_ctl *ctl,
+					struct mdp_gamut_cfg_data *config,
+					u32 *copyback)
 {
 	int i, j, size_total = 0, ret = 0;
 	u32 offset, disp_num, dspp_num = 0;
 	uint16_t *tbl_off;
 	struct mdp_gamut_cfg_data local_cfg;
 
+	if (!ctl)
+		return -EINVAL;
+
 	if ((config->block < MDP_LOGICAL_BLOCK_DISP_0) ||
 		(config->block >= MDP_BLOCK_MAX))
 		return -EINVAL;
@@ -1241,6 +1633,8 @@
 	}
 gamut_config_exit:
 	mutex_unlock(&mdss_pp_mutex);
+	if (!ret)
+		mdss_mdp_pp_setup(ctl);
 	return ret;
 }
 static void pp_hist_read(u32 v_base, struct pp_hist_col_info *hist_info)
@@ -1257,15 +1651,19 @@
 	hist_info->hist_cnt_read++;
 }
 
-int mdss_mdp_histogram_start(struct mdp_histogram_start_req *req)
+int mdss_mdp_histogram_start(struct mdss_mdp_ctl *ctl,
+					struct mdp_histogram_start_req *req)
 {
 	u32 ctl_base, done_shift_bit;
 	struct pp_hist_col_info *hist_info;
 	int i, ret = 0;
 	u32 disp_num, dspp_num = 0;
-	u32 mixer_cnt, mixer_id[MDSS_MDP_MAX_LAYERMIXER];
+	u32 mixer_cnt, mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER];
 	unsigned long flag;
 
+	if (!ctl)
+		return -EINVAL;
+
 	if ((req->block < MDP_LOGICAL_BLOCK_DISP_0) ||
 		(req->block >= MDP_BLOCK_MAX))
 		return -EINVAL;
@@ -1323,17 +1721,34 @@
 	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
 hist_start_exit:
 	mutex_unlock(&mdss_mdp_hist_mutex);
+	if (!ret) {
+		mdss_mdp_pp_setup(ctl);
+		/* wait for a frame to let histrogram enable itself */
+		usleep(41666);
+		for (i = 0; i < mixer_cnt; i++) {
+			dspp_num = mixer_id[i];
+			hist_info = &mdss_pp_res->dspp_hist[dspp_num];
+			mutex_lock(&mdss_mdp_hist_mutex);
+			spin_lock_irqsave(&mdss_hist_lock, flag);
+			hist_info->is_kick_ready = true;
+			spin_unlock_irqrestore(&mdss_hist_lock, flag);
+			mutex_unlock(&mdss_mdp_hist_mutex);
+		}
+	}
 	return ret;
 }
 
-int mdss_mdp_histogram_stop(u32 block)
+int mdss_mdp_histogram_stop(struct mdss_mdp_ctl *ctl, u32 block)
 {
 	int i, ret = 0;
 	u32 dspp_num, disp_num, ctl_base, done_bit;
 	struct pp_hist_col_info *hist_info;
-	u32 mixer_cnt, mixer_id[MDSS_MDP_MAX_LAYERMIXER];
+	u32 mixer_cnt, mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER];
 	unsigned long flag;
 
+	if (!ctl)
+		return -EINVAL;
+
 	if ((block < MDP_LOGICAL_BLOCK_DISP_0) ||
 		(block >= MDP_BLOCK_MAX))
 		return -EINVAL;
@@ -1380,19 +1795,25 @@
 	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
 hist_stop_exit:
 	mutex_unlock(&mdss_mdp_hist_mutex);
+	if (!ret)
+		mdss_mdp_pp_setup(ctl);
 	return ret;
 }
 
-int mdss_mdp_hist_collect(struct fb_info *info,
-		  struct mdp_histogram_data *hist, u32 *hist_data_addr)
+int mdss_mdp_hist_collect(struct mdss_mdp_ctl *ctl,
+					struct mdp_histogram_data *hist,
+					u32 *hist_data_addr)
 {
 	int i, j, wait_ret, ret = 0;
 	u32 timeout, v_base;
 	struct pp_hist_col_info *hist_info;
 	u32 dspp_num, disp_num, ctl_base;
-	u32 mixer_cnt, mixer_id[MDSS_MDP_MAX_LAYERMIXER];
+	u32 mixer_cnt, mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER];
 	unsigned long flag;
 
+	if (!ctl)
+		return -EINVAL;
+
 	if ((hist->block < MDP_LOGICAL_BLOCK_DISP_0) ||
 		(hist->block >= MDP_BLOCK_MAX))
 		return -EINVAL;
@@ -1429,18 +1850,31 @@
 		if (hist_info->col_state != HIST_READY) {
 			hist_info->read_request = true;
 			spin_unlock_irqrestore(&mdss_hist_lock, flag);
-			timeout = HIST_WAIT_TIMEOUT *
-				hist_info->frame_cnt;
+			timeout = HIST_WAIT_TIMEOUT(hist_info->frame_cnt);
 			mutex_unlock(&mdss_mdp_hist_mutex);
+			/* flush updates before wait*/
+			mdss_mdp_pp_setup(ctl);
 			wait_ret = wait_for_completion_killable_timeout(
 					&(hist_info->comp), timeout);
 
 			mutex_lock(&mdss_mdp_hist_mutex);
 			if (wait_ret == 0) {
 				ret = -ETIMEDOUT;
-				pr_debug("%s: bin collection timedout",
-						__func__);
-				goto hist_collect_exit;
+				spin_lock_irqsave(&mdss_hist_lock, flag);
+				pr_debug("bin collection timedout, state %d",
+							hist_info->col_state);
+				/*
+				 * When the histogram has timed out (usually
+				 * underrun) change the SW state back to idle
+				 * since histogram hardware will have done the
+				 * same. Histogram data also needs to be
+				 * cleared in this case, which is done by the
+				 * histogram being read (triggered by READY
+				 * state, which also moves the histogram SW back
+				 * to IDLE).
+				 */
+				hist_info->col_state = HIST_READY;
+				spin_unlock_irqrestore(&mdss_hist_lock, flag);
 			} else if (wait_ret < 0) {
 				ret = -EINTR;
 				pr_debug("%s: bin collection interrupted",
@@ -1449,8 +1883,8 @@
 			}
 			if (hist_info->col_state != HIST_READY) {
 				ret = -ENODATA;
-				pr_debug("%s: collection state is not ready: %d",
-						__func__, hist_info->col_state);
+				pr_debug("%s: state is not ready: %d",
+					__func__, hist_info->col_state);
 				goto hist_collect_exit;
 			}
 		} else {
diff --git a/drivers/video/msm/mdss/mdss_mdp_rotator.c b/drivers/video/msm/mdss/mdss_mdp_rotator.c
index 1e58269..8bff5cb 100644
--- a/drivers/video/msm/mdss/mdss_mdp_rotator.c
+++ b/drivers/video/msm/mdss/mdss_mdp_rotator.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
@@ -70,28 +70,13 @@
 {
 	struct mdss_mdp_mixer *mixer;
 	struct mdss_mdp_pipe *pipe = NULL;
-	int pnum;
 
 	mixer = mdss_mdp_wb_mixer_alloc(1);
 	if (!mixer)
 		return NULL;
 
-	switch (mixer->num) {
-	case MDSS_MDP_LAYERMIXER3:
-		pnum = MDSS_MDP_SSPP_DMA0;
-		break;
-	case MDSS_MDP_LAYERMIXER4:
-		pnum = MDSS_MDP_SSPP_DMA1;
-		break;
-	default:
-		goto done;
-	}
+	pipe = mdss_mdp_pipe_alloc_dma(mixer);
 
-	pipe = mdss_mdp_pipe_alloc_pnum(pnum);
-
-	if (pipe)
-		pipe->mixer = mixer;
-done:
 	if (!pipe)
 		mdss_mdp_wb_mixer_destroy(mixer);
 
@@ -185,7 +170,7 @@
 			   struct mdss_mdp_data *src_data,
 			   struct mdss_mdp_data *dst_data)
 {
-	struct mdss_mdp_pipe *rot_pipe;
+	struct mdss_mdp_pipe *rot_pipe = NULL;
 	struct mdss_mdp_ctl *ctl;
 	int ret, need_wait = false;
 
@@ -238,6 +223,9 @@
 	if (need_wait)
 		mdss_mdp_rotator_busy_wait(rot);
 
+	if (rot_pipe)
+		pr_debug("end of rotator pnum=%d enqueue\n", rot_pipe->num);
+
 	return ret;
 }
 
diff --git a/drivers/video/msm/mdss/mdss_mdp_util.c b/drivers/video/msm/mdss/mdss_mdp_util.c
index 9f2df85..911e29f 100644
--- a/drivers/video/msm/mdss/mdss_mdp_util.c
+++ b/drivers/video/msm/mdss/mdss_mdp_util.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
@@ -29,6 +29,8 @@
 #include "mdss_mdp.h"
 #include "mdss_mdp_formats.h"
 
+#define DEFAULT_FRAME_RATE	60
+
 enum {
 	MDP_INTR_VSYNC_INTF_0,
 	MDP_INTR_VSYNC_INTF_1,
@@ -76,7 +78,7 @@
 			       void (*fnc_ptr)(void *), void *arg)
 {
 	unsigned long flags;
-	int index, ret;
+	int index;
 
 	index = mdss_mdp_intr2index(intr_type, intf_num);
 	if (index < 0) {
@@ -86,16 +88,13 @@
 	}
 
 	spin_lock_irqsave(&mdss_mdp_intr_lock, flags);
-	if (!mdp_intr_cb[index].func) {
-		mdp_intr_cb[index].func = fnc_ptr;
-		mdp_intr_cb[index].arg = arg;
-		ret = 0;
-	} else {
-		ret = -EBUSY;
-	}
+	WARN(mdp_intr_cb[index].func && fnc_ptr,
+		"replacing current intr callback for ndx=%d\n", index);
+	mdp_intr_cb[index].func = fnc_ptr;
+	mdp_intr_cb[index].arg = arg;
 	spin_unlock_irqrestore(&mdss_mdp_intr_lock, flags);
 
-	return ret;
+	return 0;
 }
 
 static inline void mdss_mdp_intr_done(int index)
@@ -433,3 +432,26 @@
 
 	return ret;
 }
+
+u32 mdss_get_panel_framerate(struct msm_fb_data_type *mfd)
+{
+	u32 frame_rate = DEFAULT_FRAME_RATE;
+	u32 pixel_total;
+	struct mdss_panel_info *panel_info = mfd->panel_info;
+
+	if (panel_info->type == MIPI_VIDEO_PANEL) {
+		frame_rate = panel_info->mipi.frame_rate;
+	} else {
+		pixel_total = (panel_info->lcdc.h_back_porch +
+			  panel_info->lcdc.h_front_porch +
+			  panel_info->lcdc.h_pulse_width +
+			  panel_info->xres) *
+			 (panel_info->lcdc.v_back_porch +
+			  panel_info->lcdc.v_front_porch +
+			  panel_info->lcdc.v_pulse_width +
+			  panel_info->yres);
+		if (pixel_total)
+			frame_rate = panel_info->clk_rate / pixel_total;
+	}
+	return frame_rate;
+}
diff --git a/drivers/video/msm/mdss/mdss_mdp_wb.c b/drivers/video/msm/mdss/mdss_mdp_wb.c
index b74523b..d24a7c9 100644
--- a/drivers/video/msm/mdss/mdss_mdp_wb.c
+++ b/drivers/video/msm/mdss/mdss_mdp_wb.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -26,7 +26,6 @@
 #include "mdss_mdp.h"
 #include "mdss_fb.h"
 
-#define DEBUG_WRITEBACK
 
 enum mdss_mdp_wb_state {
 	WB_OPEN,
@@ -43,6 +42,8 @@
 	struct list_head register_queue;
 	wait_queue_head_t wait_q;
 	u32 state;
+	int is_secure;
+	struct mdss_mdp_pipe *secure_pipe;
 };
 
 enum mdss_mdp_wb_node_state {
@@ -121,6 +122,72 @@
 }
 #endif
 
+int mdss_mdp_wb_set_secure(struct msm_fb_data_type *mfd, int enable)
+{
+	struct mdss_mdp_wb *wb;
+	struct mdss_mdp_pipe *pipe;
+	struct mdss_mdp_mixer *mixer;
+
+	pr_debug("setting secure=%d\n", enable);
+
+	wb = mfd->wb;
+	if (wb == NULL) {
+		pr_err("Invalid writeback session\n");
+		return -ENODEV;
+	}
+
+	wb->is_secure = enable;
+	pipe = wb->secure_pipe;
+
+	if (!enable) {
+		if (pipe) {
+			/* unset pipe */
+			mdss_mdp_mixer_pipe_unstage(pipe);
+			mdss_mdp_pipe_destroy(pipe);
+			wb->secure_pipe = NULL;
+		}
+		return 0;
+	}
+
+	mixer = mdss_mdp_mixer_get(mfd->ctl, MDSS_MDP_MIXER_MUX_DEFAULT);
+	if (!mixer) {
+		pr_err("Unable to find mixer for wb\n");
+		return -ENOENT;
+	}
+
+	if (!pipe) {
+		pipe = mdss_mdp_pipe_alloc(mixer, MDSS_MDP_PIPE_TYPE_RGB);
+		if (!pipe)
+			pipe = mdss_mdp_pipe_alloc(mixer,
+					MDSS_MDP_PIPE_TYPE_VIG);
+		if (!pipe) {
+			pr_err("Unable to get pipe to set secure session\n");
+			return -ENOMEM;
+		}
+
+		pipe->src_fmt = mdss_mdp_get_format_params(MDP_RGBA_8888);
+
+		pipe->mfd = mfd;
+		pipe->mixer_stage = MDSS_MDP_STAGE_BASE;
+		wb->secure_pipe = pipe;
+	}
+
+	pipe->img_height = mixer->height;
+	pipe->img_width = mixer->width;
+	pipe->src.x = 0;
+	pipe->src.y = 0;
+	pipe->src.w = pipe->img_width;
+	pipe->src.h = pipe->img_height;
+	pipe->dst = pipe->src;
+
+	pipe->flags = (enable ? MDP_SECURE_OVERLAY_SESSION : 0);
+	pipe->params_changed++;
+
+	pr_debug("setting secure pipe=%d flags=%x\n", pipe->num, pipe->flags);
+
+	return mdss_mdp_pipe_queue_data(pipe, NULL);
+}
+
 static int mdss_mdp_wb_init(struct msm_fb_data_type *mfd)
 {
 	struct mdss_mdp_wb *wb;
@@ -173,6 +240,10 @@
 			kfree(node);
 		}
 	}
+
+	wb->is_secure = false;
+	if (wb->secure_pipe)
+		mdss_mdp_pipe_destroy(wb->secure_pipe);
 	mutex_unlock(&wb->lock);
 
 	mfd->wb = NULL;
@@ -257,6 +328,8 @@
 	buf = &node->buf_data.p[0];
 	buf->addr = (u32) (data->iova + data->offset);
 	buf->len = UINT_MAX; /* trusted source */
+	if (wb->is_secure)
+		buf->flags |= MDP_SECURE_OVERLAY_SESSION;
 	ret = mdss_mdp_wb_register_node(wb, node);
 	if (IS_ERR_VALUE(ret)) {
 		pr_err("error registering wb node\n");
@@ -284,6 +357,8 @@
 
 	node->buf_data.num_planes = 1;
 	buf = &node->buf_data.p[0];
+	if (wb->is_secure)
+		buf->flags |= MDP_SECURE_OVERLAY_SESSION;
 	ret = mdss_mdp_get_img(data, buf);
 	if (IS_ERR_VALUE(ret)) {
 		pr_err("error getting buffer info\n");
@@ -419,6 +494,9 @@
 	wb = ctl->mfd->wb;
 	if (wb) {
 		mutex_lock(&wb->lock);
+		/* in case of reinit of control path need to reset secure */
+		if (ctl->play_cnt == 0)
+			mdss_mdp_wb_set_secure(ctl->mfd, wb->is_secure);
 		if (!list_empty(&wb->free_queue) && wb->state != WB_STOPING &&
 		    wb->state != WB_STOP) {
 			node = list_first_entry(&wb->free_queue,
@@ -438,7 +516,8 @@
 
 	if (wb_args.data == NULL) {
 		pr_err("unable to get writeback buf ctl=%d\n", ctl->num);
-		ret = -ENOMEM;
+		/* drop buffer but don't return error */
+		ret = 0;
 		goto kickoff_fail;
 	}
 
@@ -568,8 +647,31 @@
 }
 EXPORT_SYMBOL(msm_fb_writeback_terminate);
 
-int msm_fb_get_iommu_domain(void)
+int msm_fb_get_iommu_domain(struct fb_info *info, int domain)
 {
-	return mdss_get_iommu_domain(MDSS_IOMMU_DOMAIN_UNSECURE);
+	int mdss_domain;
+	switch (domain) {
+	case MDP_IOMMU_DOMAIN_CP:
+		mdss_domain = MDSS_IOMMU_DOMAIN_SECURE;
+		break;
+	case MDP_IOMMU_DOMAIN_NS:
+		mdss_domain = MDSS_IOMMU_DOMAIN_UNSECURE;
+		break;
+	default:
+		pr_err("Invalid mdp iommu domain (%d)\n", domain);
+		return -EINVAL;
+	}
+	return mdss_get_iommu_domain(mdss_domain);
 }
 EXPORT_SYMBOL(msm_fb_get_iommu_domain);
+
+int msm_fb_writeback_set_secure(struct fb_info *info, int enable)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *) info->par;
+
+	if (!mfd)
+		return -ENODEV;
+
+	return mdss_mdp_wb_set_secure(mfd, enable);
+}
+EXPORT_SYMBOL(msm_fb_writeback_set_secure);
diff --git a/drivers/video/msm/mdss/mdss_panel.h b/drivers/video/msm/mdss/mdss_panel.h
index d807493..31fb2e7 100644
--- a/drivers/video/msm/mdss/mdss_panel.h
+++ b/drivers/video/msm/mdss/mdss_panel.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
@@ -65,6 +65,8 @@
 	MDSS_EVENT_SUSPEND,
 	MDSS_EVENT_RESUME,
 	MDSS_EVENT_CHECK_PARAMS,
+	MDSS_EVENT_CONT_SPLASH_FINISH,
+	MDSS_EVENT_FB_REGISTERED,
 };
 
 /* panel info type */
@@ -182,11 +184,14 @@
 	u32 out_format;
 	u32 vic; /* video identification code */
 
+	u32 cont_splash_enabled;
+	struct ion_handle *splash_ihdl;
+	u32 panel_power_on;
+
 	struct lcd_panel_info lcd;
 	struct lcdc_panel_info lcdc;
 	struct mipi_panel_info mipi;
 	struct lvds_panel_info lvds;
-	struct fb_info *fbi;
 };
 
 struct mdss_panel_data {
@@ -196,7 +201,10 @@
 
 	/* function entry chain */
 	int (*event_handler) (struct mdss_panel_data *pdata, int e, void *arg);
+
+	struct mdss_panel_data *next;
 };
 
-int mdss_register_panel(struct mdss_panel_data *pdata);
+int mdss_register_panel(struct platform_device *pdev,
+	struct mdss_panel_data *pdata);
 #endif /* MDSS_PANEL_H */
diff --git a/drivers/video/msm/mdss/mdss_wb.c b/drivers/video/msm/mdss/mdss_wb.c
index 47dc2c8..1b398d3 100644
--- a/drivers/video/msm/mdss/mdss_wb.c
+++ b/drivers/video/msm/mdss/mdss_wb.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -111,7 +111,7 @@
 	pdata->event_handler = mdss_wb_event_handler;
 	pdev->dev.platform_data = pdata;
 
-	rc = mdss_register_panel(pdata);
+	rc = mdss_register_panel(pdev, pdata);
 	if (rc) {
 		dev_err(&pdev->dev, "unable to register writeback panel\n");
 		return rc;
diff --git a/drivers/video/msm/mdss/mhl_msc.c b/drivers/video/msm/mdss/mhl_msc.c
new file mode 100644
index 0000000..add65ac
--- /dev/null
+++ b/drivers/video/msm/mdss/mhl_msc.c
@@ -0,0 +1,646 @@
+/* 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/types.h>
+#include <linux/mhl_8334.h>
+#include <linux/vmalloc.h>
+#include <linux/input.h>
+#include "mhl_msc.h"
+#include "mdss_hdmi_mhl.h"
+
+static struct mhl_tx_ctrl *mhl_ctrl;
+static DEFINE_MUTEX(msc_send_workqueue_mutex);
+
+const char *devcap_reg_name[] = {
+	"DEV_STATE       ",
+	"MHL_VERSION     ",
+	"DEV_CAT         ",
+	"ADOPTER_ID_H    ",
+	"ADOPTER_ID_L    ",
+	"VID_LINK_MODE   ",
+	"AUD_LINK_MODE   ",
+	"VIDEO_TYPE      ",
+	"LOG_DEV_MAP     ",
+	"BANDWIDTH       ",
+	"FEATURE_FLAG    ",
+	"DEVICE_ID_H     ",
+	"DEVICE_ID_L     ",
+	"SCRATCHPAD_SIZE ",
+	"INT_STAT_SIZE   ",
+	"Reserved        ",
+};
+
+static bool mhl_check_tmds_enabled(struct mhl_tx_ctrl *mhl_ctrl)
+{
+	if (mhl_ctrl && mhl_ctrl->hdmi_mhl_ops) {
+		struct msm_hdmi_mhl_ops *ops = mhl_ctrl->hdmi_mhl_ops;
+		struct platform_device *pdev = mhl_ctrl->pdata->hdmi_pdev;
+		return (ops->tmds_enabled(pdev) == true);
+	} else {
+		pr_err("%s: invalid input\n", __func__);
+		return false;
+	}
+}
+
+static void mhl_print_devcap(u8 offset, u8 devcap)
+{
+	switch (offset) {
+	case DEVCAP_OFFSET_DEV_CAT:
+		pr_debug("DCAP: %02X %s: %02X DEV_TYPE=%X POW=%s\n",
+			offset, devcap_reg_name[offset], devcap,
+			devcap & 0x0F, (devcap & 0x10) ? "y" : "n");
+		break;
+	case DEVCAP_OFFSET_FEATURE_FLAG:
+		pr_debug("DCAP: %02X %s: %02X RCP=%s RAP=%s SP=%s\n",
+			offset, devcap_reg_name[offset], devcap,
+			(devcap & 0x01) ? "y" : "n",
+			(devcap & 0x02) ? "y" : "n",
+			(devcap & 0x04) ? "y" : "n");
+		break;
+	default:
+		pr_debug("DCAP: %02X %s: %02X\n",
+			offset, devcap_reg_name[offset], devcap);
+		break;
+	}
+}
+
+void mhl_register_msc(struct mhl_tx_ctrl *ctrl)
+{
+	if (ctrl)
+		mhl_ctrl = ctrl;
+}
+
+static int mhl_flag_scrpd_burst_req(struct mhl_tx_ctrl *mhl_ctrl,
+		struct msc_command_struct *req)
+{
+	int postpone_send = 0;
+
+	if ((req->command == MHL_SET_INT) &&
+	    (req->offset == MHL_RCHANGE_INT)) {
+		if (mhl_ctrl->scrpd_busy) {
+			/* reduce priority */
+			if (req->payload.data[0] == MHL_INT_REQ_WRT)
+				postpone_send = 1;
+		} else {
+			if (req->payload.data[0] == MHL_INT_REQ_WRT) {
+				mhl_ctrl->scrpd_busy = true;
+				mhl_ctrl->wr_burst_pending = true;
+			} else if (req->payload.data[0] == MHL_INT_GRT_WRT) {
+					mhl_ctrl->scrpd_busy = true;
+			}
+		}
+	}
+	return postpone_send;
+}
+
+
+
+void mhl_msc_send_work(struct work_struct *work)
+{
+	struct mhl_tx_ctrl *mhl_ctrl =
+		container_of(work, struct mhl_tx_ctrl, mhl_msc_send_work);
+	struct msc_cmd_envelope *cmd_env;
+	int ret, postpone_send;
+	/*
+	 * Remove item from the queue
+	 * and schedule it
+	 */
+	mutex_lock(&msc_send_workqueue_mutex);
+	while (!list_empty(&mhl_ctrl->list_cmd)) {
+		cmd_env = list_first_entry(&mhl_ctrl->list_cmd,
+					   struct msc_cmd_envelope,
+					   msc_queue_envelope);
+		list_del(&cmd_env->msc_queue_envelope);
+		mutex_unlock(&msc_send_workqueue_mutex);
+
+		postpone_send = mhl_flag_scrpd_burst_req(
+			mhl_ctrl,
+			&cmd_env->msc_cmd_msg);
+		if (postpone_send) {
+			if (cmd_env->msc_cmd_msg.retry-- > 0) {
+				mutex_lock(&msc_send_workqueue_mutex);
+				list_add_tail(
+					&cmd_env->msc_queue_envelope,
+					&mhl_ctrl->list_cmd);
+				mutex_unlock(&msc_send_workqueue_mutex);
+			} else {
+				pr_err("%s: max scrpd retry out\n",
+				       __func__);
+			}
+		} else {
+			ret = mhl_send_msc_command(mhl_ctrl,
+						   &cmd_env->msc_cmd_msg);
+			if (ret == -EAGAIN) {
+				int retry = 2;
+				while (retry--) {
+					ret = mhl_send_msc_command(
+						mhl_ctrl,
+						&cmd_env->msc_cmd_msg);
+					if (ret != -EAGAIN)
+						break;
+				}
+			}
+			if (ret == -EAGAIN)
+				pr_err("%s: send_msc_command retry out!\n",
+				       __func__);
+			vfree(cmd_env);
+		}
+
+		mutex_lock(&msc_send_workqueue_mutex);
+	}
+	mutex_unlock(&msc_send_workqueue_mutex);
+}
+
+int mhl_queue_msc_command(struct mhl_tx_ctrl *mhl_ctrl,
+			  struct msc_command_struct *req,
+			  int priority_send)
+{
+	struct msc_cmd_envelope *cmd_env;
+
+	mutex_lock(&msc_send_workqueue_mutex);
+	cmd_env = vmalloc(sizeof(struct msc_cmd_envelope));
+	if (!cmd_env) {
+		pr_err("%s: out of memory!\n", __func__);
+		return -ENOMEM;
+	}
+
+	memcpy(&cmd_env->msc_cmd_msg, req,
+	       sizeof(struct msc_command_struct));
+
+	if (priority_send)
+		list_add(&cmd_env->msc_queue_envelope,
+			 &mhl_ctrl->list_cmd);
+	else
+		list_add_tail(&cmd_env->msc_queue_envelope,
+			      &mhl_ctrl->list_cmd);
+	mutex_unlock(&msc_send_workqueue_mutex);
+	queue_work(mhl_ctrl->msc_send_workqueue, &mhl_ctrl->mhl_msc_send_work);
+
+	return 0;
+}
+
+static int mhl_update_devcap(struct mhl_tx_ctrl *mhl_ctrl,
+	int offset, u8 devcap)
+{
+	if (!mhl_ctrl)
+		return -EFAULT;
+	if (offset < 0 || offset > 15)
+		return -EFAULT;
+	mhl_ctrl->devcap[offset] = devcap;
+	mhl_print_devcap(offset, mhl_ctrl->devcap[offset]);
+
+	return 0;
+}
+
+
+int mhl_msc_command_done(struct mhl_tx_ctrl *mhl_ctrl,
+			 struct msc_command_struct *req)
+{
+	switch (req->command) {
+	case MHL_WRITE_STAT:
+		if (req->offset == MHL_STATUS_REG_LINK_MODE) {
+			if (req->payload.data[0]
+			    & MHL_STATUS_PATH_ENABLED)
+				/* Enable TMDS output */
+				mhl_tmds_ctrl(mhl_ctrl, TMDS_ENABLE);
+			else
+				/* Disable TMDS output */
+				mhl_tmds_ctrl(mhl_ctrl, TMDS_DISABLE);
+		}
+		break;
+	case MHL_READ_DEVCAP:
+		mhl_update_devcap(mhl_ctrl,
+			req->offset, req->retval);
+		mhl_ctrl->devcap_state |= BIT(req->offset);
+		switch (req->offset) {
+		case MHL_DEV_CATEGORY_OFFSET:
+			if (req->retval & MHL_DEV_CATEGORY_POW_BIT)
+				pr_debug("%s: devcap pow bit set\n",
+					 __func__);
+			else
+				pr_debug("%s: devcap pow bit unset\n",
+					 __func__);
+			break;
+		case DEVCAP_OFFSET_MHL_VERSION:
+		case DEVCAP_OFFSET_INT_STAT_SIZE:
+			break;
+		}
+		break;
+	case MHL_WRITE_BURST:
+		mhl_msc_send_set_int(
+			mhl_ctrl,
+			MHL_RCHANGE_INT,
+			MHL_INT_DSCR_CHG,
+			MSC_PRIORITY_SEND);
+		break;
+	}
+	return 0;
+}
+
+int mhl_msc_send_set_int(struct mhl_tx_ctrl *mhl_ctrl,
+			 u8 offset, u8 mask, u8 prior)
+{
+	struct msc_command_struct req;
+	req.command = MHL_SET_INT;
+	req.offset = offset;
+	req.payload.data[0] = mask;
+	return mhl_queue_msc_command(mhl_ctrl, &req, prior);
+}
+
+int mhl_msc_send_write_stat(struct mhl_tx_ctrl *mhl_ctrl,
+			    u8 offset, u8 value)
+{
+	struct msc_command_struct req;
+	req.command = MHL_WRITE_STAT;
+	req.offset = offset;
+	req.payload.data[0] = value;
+	return mhl_queue_msc_command(mhl_ctrl, &req, MSC_NORMAL_SEND);
+}
+
+static int mhl_msc_write_burst(struct mhl_tx_ctrl *mhl_ctrl,
+	u8 offset, u8 *data, u8 length)
+{
+	struct msc_command_struct req;
+	if (!mhl_ctrl)
+		return -EFAULT;
+
+	if (!mhl_ctrl->wr_burst_pending)
+		return -EFAULT;
+
+	req.command = MHL_WRITE_BURST;
+	req.offset = offset;
+	req.length = length;
+	req.payload.burst_data = data;
+	mhl_queue_msc_command(mhl_ctrl, &req, MSC_PRIORITY_SEND);
+	mhl_ctrl->wr_burst_pending = false;
+	return 0;
+}
+
+
+
+int mhl_msc_send_msc_msg(struct mhl_tx_ctrl *mhl_ctrl,
+			 u8 sub_cmd, u8 cmd_data)
+{
+	struct msc_command_struct req;
+	req.command = MHL_MSC_MSG;
+	req.payload.data[0] = sub_cmd;
+	req.payload.data[1] = cmd_data;
+	return mhl_queue_msc_command(mhl_ctrl, &req, MSC_NORMAL_SEND);
+}
+
+/*
+ * Certain MSC msgs such as RCPK, RCPE and RAPK
+ * should be transmitted as a high priority
+ * because these msgs should be sent within
+ * 1000ms of a receipt of RCP/RAP. So such msgs can
+ * be added to the head of msc cmd queue.
+ */
+static int mhl_msc_send_prior_msc_msg(struct mhl_tx_ctrl *mhl_ctrl,
+				      u8 sub_cmd, u8 cmd_data)
+{
+	struct msc_command_struct req;
+	req.command = MHL_MSC_MSG;
+	req.payload.data[0] = sub_cmd;
+	req.payload.data[1] = cmd_data;
+	return mhl_queue_msc_command(mhl_ctrl, &req, MSC_PRIORITY_SEND);
+}
+
+
+int mhl_msc_read_devcap(struct mhl_tx_ctrl *mhl_ctrl, u8 offset)
+{
+	struct msc_command_struct req;
+	if (offset < 0 || offset > 15)
+		return -EFAULT;
+	req.command = MHL_READ_DEVCAP;
+	req.offset = offset;
+	req.payload.data[0] = 0;
+	return mhl_queue_msc_command(mhl_ctrl, &req, MSC_NORMAL_SEND);
+}
+
+int mhl_msc_read_devcap_all(struct mhl_tx_ctrl *mhl_ctrl)
+{
+	int offset;
+	int ret;
+
+	for (offset = 0; offset < DEVCAP_SIZE; offset++) {
+		ret = mhl_msc_read_devcap(mhl_ctrl, offset);
+		if (ret == -EBUSY)
+			pr_err("%s: queue busy!\n", __func__);
+	}
+	return ret;
+}
+
+
+static void mhl_handle_input(struct mhl_tx_ctrl *mhl_ctrl,
+			     u8 key_code, u16 input_key_code)
+{
+	int key_press = (key_code & 0x80) == 0;
+
+	pr_debug("%s: send key events[%x][%d]\n",
+		 __func__, key_code, key_press);
+	input_report_key(mhl_ctrl->input, input_key_code, key_press);
+	input_sync(mhl_ctrl->input);
+}
+
+
+
+int mhl_rcp_recv(struct mhl_tx_ctrl *mhl_ctrl, u8 key_code)
+{
+	u8 index = key_code & 0x7f;
+	u16 input_key_code;
+
+	if (!mhl_ctrl->rcp_key_code_tbl) {
+		pr_err("%s: RCP Key Code Table not initialized\n", __func__);
+		return -EINVAL;
+	}
+
+	input_key_code = mhl_ctrl->rcp_key_code_tbl[index];
+
+	if ((index < mhl_ctrl->rcp_key_code_tbl_len) &&
+	    (input_key_code > 0)) {
+		/* prior send rcpk */
+		mhl_msc_send_prior_msc_msg(
+			mhl_ctrl,
+			MHL_MSC_MSG_RCPK,
+			key_code);
+
+		if (mhl_ctrl->input)
+			mhl_handle_input(mhl_ctrl, key_code, input_key_code);
+	} else {
+		/* prior send rcpe */
+		mhl_msc_send_prior_msc_msg(
+			mhl_ctrl,
+			MHL_MSC_MSG_RCPE,
+			MHL_RCPE_INEFFECTIVE_KEY_CODE);
+
+		/* send rcpk after rcpe send */
+		mhl_msc_send_prior_msc_msg(
+			mhl_ctrl,
+			MHL_MSC_MSG_RCPK,
+			key_code);
+	}
+	return 0;
+}
+
+
+static int mhl_rap_action(struct mhl_tx_ctrl *mhl_ctrl, u8 action_code)
+{
+	switch (action_code) {
+	case MHL_RAP_CONTENT_ON:
+		mhl_tmds_ctrl(mhl_ctrl, TMDS_ENABLE);
+		break;
+	case MHL_RAP_CONTENT_OFF:
+		mhl_tmds_ctrl(mhl_ctrl, TMDS_DISABLE);
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+static int mhl_rap_recv(struct mhl_tx_ctrl *mhl_ctrl, u8 action_code)
+{
+	u8 error_code;
+	bool tmds_en;
+
+	switch (action_code) {
+	case MHL_RAP_POLL:
+		tmds_en = mhl_check_tmds_enabled(mhl_ctrl);
+		if (tmds_en)
+			error_code = MHL_RAPK_NO_ERROR;
+		else
+			error_code = MHL_RAPK_UNSUPPORTED_ACTION_CODE;
+		break;
+	case MHL_RAP_CONTENT_ON:
+	case MHL_RAP_CONTENT_OFF:
+		mhl_rap_action(mhl_ctrl, action_code);
+		error_code = MHL_RAPK_NO_ERROR;
+		break;
+	default:
+		error_code = MHL_RAPK_UNRECOGNIZED_ACTION_CODE;
+		break;
+	}
+	/* prior send rapk */
+	return mhl_msc_send_prior_msc_msg(
+		mhl_ctrl,
+		MHL_MSC_MSG_RAPK,
+		error_code);
+}
+
+
+int mhl_msc_recv_msc_msg(struct mhl_tx_ctrl *mhl_ctrl,
+			 u8 sub_cmd, u8 cmd_data)
+{
+	int rc = 0;
+	switch (sub_cmd) {
+	case MHL_MSC_MSG_RCP:
+		pr_debug("MHL: receive RCP(0x%02x)\n", cmd_data);
+		rc = mhl_rcp_recv(mhl_ctrl, cmd_data);
+		break;
+	case MHL_MSC_MSG_RCPK:
+		pr_debug("MHL: receive RCPK(0x%02x)\n", cmd_data);
+		break;
+	case MHL_MSC_MSG_RCPE:
+		pr_debug("MHL: receive RCPE(0x%02x)\n", cmd_data);
+		break;
+	case MHL_MSC_MSG_RAP:
+		pr_debug("MHL: receive RAP(0x%02x)\n", cmd_data);
+		rc = mhl_rap_recv(mhl_ctrl, cmd_data);
+		break;
+	case MHL_MSC_MSG_RAPK:
+		pr_debug("MHL: receive RAPK(0x%02x)\n", cmd_data);
+		break;
+	default:
+		break;
+	}
+	return rc;
+}
+
+int mhl_msc_recv_set_int(struct mhl_tx_ctrl *mhl_ctrl,
+			 u8 offset, u8 set_int)
+{
+	int prior;
+	if (offset >= 2)
+		return -EFAULT;
+
+	switch (offset) {
+	case 0:
+		if (set_int & MHL_INT_DCAP_CHG) {
+			/* peer dcap has changed */
+			mhl_ctrl->devcap_state = 0;
+			mhl_msc_read_devcap_all(mhl_ctrl);
+		}
+		if (set_int & MHL_INT_DSCR_CHG) {
+			/* peer's scratchpad reg changed */
+			pr_debug("%s: dscr chg\n", __func__);
+			mhl_read_scratchpad(mhl_ctrl);
+			mhl_ctrl->scrpd_busy = false;
+		}
+		if (set_int & MHL_INT_REQ_WRT) {
+			/* SET_INT: REQ_WRT */
+			if (mhl_ctrl->scrpd_busy) {
+				prior = MSC_NORMAL_SEND;
+			} else {
+				prior = MSC_PRIORITY_SEND;
+				mhl_ctrl->scrpd_busy = true;
+			}
+			mhl_msc_send_set_int(
+				mhl_ctrl,
+				MHL_RCHANGE_INT,
+				MHL_INT_GRT_WRT,
+				prior);
+		}
+		if (set_int & MHL_INT_GRT_WRT) {
+			/* SET_INT: GRT_WRT */
+			pr_debug("%s: recvd req to permit/grant write",
+				 __func__);
+			mhl_msc_write_burst(
+				mhl_ctrl,
+				MHL_SCRATCHPAD_OFFSET,
+				mhl_ctrl->scrpd.data,
+				mhl_ctrl->scrpd.length);
+		}
+		break;
+	case 1:
+		if (set_int & MHL_INT_EDID_CHG) {
+			/* peer EDID has changed
+			 * toggle HPD to read EDID
+			 */
+			pr_debug("%s: EDID CHG\n", __func__);
+			mhl_drive_hpd(mhl_ctrl, HPD_DOWN);
+			msleep(110);
+			mhl_drive_hpd(mhl_ctrl, HPD_UP);
+		}
+	}
+	return 0;
+}
+
+int mhl_msc_recv_write_stat(struct mhl_tx_ctrl *mhl_ctrl,
+			    u8 offset, u8 value)
+{
+	bool tmds_en;
+
+	if (offset >= 2)
+		return -EFAULT;
+
+	switch (offset) {
+	case 0:
+		/*
+		 * connected device bits
+		 * changed and DEVCAP READY
+		 */
+		if (((value ^ mhl_ctrl->devcap_state) &
+		     MHL_STATUS_DCAP_RDY)) {
+			if (value & MHL_STATUS_DCAP_RDY) {
+				mhl_ctrl->devcap_state = 0;
+				mhl_msc_read_devcap_all(mhl_ctrl);
+			} else {
+				/*
+				 * peer dcap turned not ready
+				 * use old devap state
+				 */
+				pr_debug("%s: DCAP RDY bit cleared\n",
+					 __func__);
+			}
+		}
+		break;
+	case 1:
+		/*
+		 * connected device bits
+		 * changed and PATH ENABLED
+		 * bit set
+		 */
+		tmds_en = mhl_check_tmds_enabled(mhl_ctrl);
+		if ((value ^ mhl_ctrl->path_en_state)
+		    & MHL_STATUS_PATH_ENABLED) {
+			if (value & MHL_STATUS_PATH_ENABLED) {
+				if (tmds_en &&
+				    (mhl_ctrl->devcap[offset] &
+				     MHL_FEATURE_RAP_SUPPORT)) {
+					mhl_msc_send_msc_msg(
+						mhl_ctrl,
+						MHL_MSC_MSG_RAP,
+						MHL_RAP_CONTENT_ON);
+				}
+				mhl_ctrl->path_en_state
+					|= (MHL_STATUS_PATH_ENABLED |
+					    MHL_STATUS_CLK_MODE_NORMAL);
+				mhl_msc_send_write_stat(
+					mhl_ctrl,
+					MHL_STATUS_REG_LINK_MODE,
+					mhl_ctrl->path_en_state);
+			} else {
+				mhl_ctrl->path_en_state
+					&= ~(MHL_STATUS_PATH_ENABLED |
+					     MHL_STATUS_CLK_MODE_NORMAL);
+				mhl_msc_send_write_stat(
+					mhl_ctrl,
+					MHL_STATUS_REG_LINK_MODE,
+					mhl_ctrl->path_en_state);
+			}
+		}
+		break;
+	}
+	mhl_ctrl->path_en_state = value;
+	return 0;
+}
+
+static int mhl_request_write_burst(struct mhl_tx_ctrl *mhl_ctrl,
+				   u8 start_reg,
+				   u8 length, u8 *data)
+{
+	int rc = 0;
+
+	if (!(mhl_ctrl->devcap[DEVCAP_OFFSET_FEATURE_FLAG] &
+	      MHL_FEATURE_SP_SUPPORT)) {
+		pr_debug("MHL: SCRATCHPAD_NOT_SUPPORTED\n");
+		rc = -EFAULT;
+	} else {
+		if (mhl_ctrl->scrpd_busy) {
+			pr_debug("MHL: scratchpad_busy\n");
+			rc = -EBUSY;
+		} else {
+			int i, reg;
+			for (i = 0, reg = start_reg; (i < length) &&
+				     (reg < MHL_SCRATCHPAD_SIZE); i++, reg++)
+				mhl_ctrl->scrpd.data[reg] = data[i];
+			mhl_ctrl->scrpd.length = length;
+			mhl_ctrl->scrpd.offset = start_reg;
+			mhl_msc_send_set_int(
+				mhl_ctrl,
+				MHL_RCHANGE_INT,
+				MHL_INT_REQ_WRT,
+				MSC_PRIORITY_SEND);
+		}
+	}
+	return rc;
+}
+
+/* write scratchpad entry */
+int mhl_write_scratchpad(struct mhl_tx_ctrl *mhl_ctrl,
+			  u8 offset, u8 length, u8 *data)
+{
+	int rc;
+
+	if ((length < ADOPTER_ID_SIZE) ||
+	    (length > MAX_SCRATCHPAD_TRANSFER_SIZE) ||
+	    (offset > (MAX_SCRATCHPAD_TRANSFER_SIZE - ADOPTER_ID_SIZE)) ||
+	    ((offset + length) > MAX_SCRATCHPAD_TRANSFER_SIZE)) {
+		pr_debug("MHL: write_burst (0x%02x)\n", -EINVAL);
+		return  -EINVAL;
+	}
+
+	rc = mhl_request_write_burst(mhl_ctrl, offset, length, data);
+
+	return rc;
+}
diff --git a/drivers/video/msm/mdss/mhl_msc.h b/drivers/video/msm/mdss/mhl_msc.h
new file mode 100644
index 0000000..8a1fd39
--- /dev/null
+++ b/drivers/video/msm/mdss/mhl_msc.h
@@ -0,0 +1,59 @@
+/* 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 __MHL_MSC_H__
+#define __MHL_MSC_H__
+#include <linux/mhl_8334.h>
+
+#define MAX_RCP_KEYS_SUPPORTED 256
+
+#define MSC_NORMAL_SEND 0
+#define MSC_PRIORITY_SEND 1
+
+#define TMDS_ENABLE 1
+#define TMDS_DISABLE 0
+
+/******************************************************************/
+/* the below APIs are implemented by the MSC functionality */
+int mhl_msc_command_done(struct mhl_tx_ctrl *mhl_ctrl,
+			 struct msc_command_struct *req);
+
+int mhl_msc_send_set_int(struct mhl_tx_ctrl *mhl_ctrl,
+			 u8 offset, u8 mask, u8 priority);
+
+int mhl_msc_send_write_stat(struct mhl_tx_ctrl *mhl_ctrl,
+			    u8 offset, u8 value);
+int mhl_msc_send_msc_msg(struct mhl_tx_ctrl *mhl_ctrl,
+			 u8 sub_cmd, u8 cmd_data);
+
+int mhl_msc_recv_set_int(struct mhl_tx_ctrl *mhl_ctrl,
+			 u8 offset, u8 set_int);
+
+int mhl_msc_recv_write_stat(struct mhl_tx_ctrl *mhl_ctrl,
+			    u8 offset, u8 value);
+int mhl_msc_recv_msc_msg(struct mhl_tx_ctrl *mhl_ctrl,
+			 u8 sub_cmd, u8 cmd_data);
+void mhl_msc_send_work(struct work_struct *work);
+
+/******************************************************************/
+/* Tx should implement these APIs */
+int mhl_send_msc_command(struct mhl_tx_ctrl *mhl_ctrl,
+			 struct msc_command_struct *req);
+void mhl_read_scratchpad(struct mhl_tx_ctrl *mhl_ctrl);
+void mhl_drive_hpd(struct mhl_tx_ctrl *mhl_ctrl, uint8_t to_state);
+void mhl_tmds_ctrl(struct mhl_tx_ctrl *ctrl, uint8_t on);
+/******************************************************************/
+/* MHL driver registers ctrl with MSC */
+void mhl_register_msc(struct mhl_tx_ctrl *ctrl);
+
+#endif /* __MHL_MSC_H__ */
diff --git a/drivers/video/msm/mdss/mhl_sii8334.c b/drivers/video/msm/mdss/mhl_sii8334.c
index 6a63964..30dd471 100644
--- a/drivers/video/msm/mdss/mhl_sii8334.c
+++ b/drivers/video/msm/mdss/mhl_sii8334.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
@@ -18,6 +18,9 @@
 #include <linux/of_address.h>
 #include <linux/of_gpio.h>
 #include <linux/types.h>
+#include <linux/vmalloc.h>
+#include <linux/input.h>
+#include <linux/usb/msm_hsusb.h>
 #include <linux/mhl_8334.h>
 
 #include "mdss_fb.h"
@@ -26,38 +29,151 @@
 #include "mdss.h"
 #include "mdss_panel.h"
 #include "mdss_io_util.h"
+#include "mhl_msc.h"
+#include "mdss_hdmi_mhl.h"
 
 #define MHL_DRIVER_NAME "sii8334"
 #define COMPATIBLE_NAME "qcom,mhl-sii8334"
+#define MAX_CURRENT 700000
 
 #define pr_debug_intr(...) pr_debug("\n")
 
-enum mhl_gpio_type {
-	MHL_TX_RESET_GPIO,
-	MHL_TX_INTR_GPIO,
-	MHL_TX_PMIC_PWR_GPIO,
-	MHL_TX_MAX_GPIO,
-};
+#define MSC_START_BIT_MSC_CMD        (0x01 << 0)
+#define MSC_START_BIT_VS_CMD        (0x01 << 1)
+#define MSC_START_BIT_READ_REG        (0x01 << 2)
+#define MSC_START_BIT_WRITE_REG        (0x01 << 3)
+#define MSC_START_BIT_WRITE_BURST        (0x01 << 4)
 
-enum mhl_vreg_type {
-	MHL_TX_3V_VREG,
-	MHL_TX_MAX_VREG,
-};
-
-struct mhl_tx_platform_data {
-	/* Data filled from device tree nodes */
-	struct dss_gpio *gpios[MHL_TX_MAX_GPIO];
-	struct dss_vreg *vregs[MHL_TX_MAX_VREG];
-	int irq;
-};
-
-struct mhl_tx_ctrl {
-	struct platform_device *pdev;
-	struct mhl_tx_platform_data *pdata;
-	struct i2c_client *i2c_handle;
-	uint8_t cur_state;
-	uint8_t chip_rev_id;
-	int mhl_mode;
+/* supported RCP key code */
+u16 support_rcp_key_code_tbl[] = {
+	KEY_ENTER,		/* 0x00 Select */
+	KEY_UP,			/* 0x01 Up */
+	KEY_DOWN,		/* 0x02 Down */
+	KEY_LEFT,		/* 0x03 Left */
+	KEY_RIGHT,		/* 0x04 Right */
+	KEY_UNKNOWN,		/* 0x05 Right-up */
+	KEY_UNKNOWN,		/* 0x06 Right-down */
+	KEY_UNKNOWN,		/* 0x07 Left-up */
+	KEY_UNKNOWN,		/* 0x08 Left-down */
+	KEY_MENU,		/* 0x09 Root Menu */
+	KEY_OPTION,		/* 0x0A Setup Menu */
+	KEY_UNKNOWN,		/* 0x0B Contents Menu */
+	KEY_UNKNOWN,		/* 0x0C Favorite Menu */
+	KEY_EXIT,		/* 0x0D Exit */
+	KEY_RESERVED,		/* 0x0E */
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,		/* 0x1F */
+	KEY_NUMERIC_0,		/* 0x20 NUMERIC_0 */
+	KEY_NUMERIC_1,		/* 0x21 NUMERIC_1 */
+	KEY_NUMERIC_2,		/* 0x22 NUMERIC_2 */
+	KEY_NUMERIC_3,		/* 0x23 NUMERIC_3 */
+	KEY_NUMERIC_4,		/* 0x24 NUMERIC_4 */
+	KEY_NUMERIC_5,		/* 0x25 NUMERIC_5 */
+	KEY_NUMERIC_6,		/* 0x26 NUMERIC_6 */
+	KEY_NUMERIC_7,		/* 0x27 NUMERIC_7 */
+	KEY_NUMERIC_8,		/* 0x28 NUMERIC_8 */
+	KEY_NUMERIC_9,		/* 0x29 NUMERIC_9 */
+	KEY_DOT,		/* 0x2A Dot */
+	KEY_ENTER,		/* 0x2B Enter */
+	KEY_ESC,		/* 0x2C Clear */
+	KEY_RESERVED,		/* 0x2D */
+	KEY_RESERVED,		/* 0x2E */
+	KEY_RESERVED,		/* 0x2F */
+	KEY_UNKNOWN,		/* 0x30 Channel Up */
+	KEY_UNKNOWN,		/* 0x31 Channel Down */
+	KEY_UNKNOWN,		/* 0x32 Previous Channel */
+	KEY_UNKNOWN,		/* 0x33 Sound Select */
+	KEY_UNKNOWN,		/* 0x34 Input Select */
+	KEY_UNKNOWN,		/* 0x35 Show Information */
+	KEY_UNKNOWN,		/* 0x36 Help */
+	KEY_UNKNOWN,		/* 0x37 Page Up */
+	KEY_UNKNOWN,		/* 0x38 Page Down */
+	KEY_RESERVED,		/* 0x39 */
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,		/* 0x3F */
+	KEY_RESERVED,		/* 0x40 */
+	KEY_VOLUMEUP,		/* 0x41 Volume Up */
+	KEY_VOLUMEDOWN,		/* 0x42 Volume Down */
+	KEY_MUTE,		/* 0x43 Mute */
+	KEY_PLAY,		/* 0x44 Play */
+	KEY_STOP,		/* 0x45 Stop */
+	KEY_PAUSE,		/* 0x46 Pause */
+	KEY_UNKNOWN,		/* 0x47 Record */
+	KEY_REWIND,		/* 0x48 Rewind */
+	KEY_FASTFORWARD,	/* 0x49 Fast Forward */
+	KEY_UNKNOWN,		/* 0x4A Eject */
+	KEY_FORWARD,		/* 0x4B Forward */
+	KEY_BACK,		/* 0x4C Backward */
+	KEY_RESERVED,		/* 0x4D */
+	KEY_RESERVED,
+	KEY_RESERVED,		/* 0x4F */
+	KEY_UNKNOWN,		/* 0x50 Angle */
+	KEY_UNKNOWN,		/* 0x51 Subtitle */
+	KEY_RESERVED,		/* 0x52 */
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,		/* 0x5F */
+	KEY_PLAYPAUSE,		/* 0x60 Play Function */
+	KEY_PLAYPAUSE,		/* 0x61 Pause_Play Function */
+	KEY_UNKNOWN,		/* 0x62 Record Function */
+	KEY_PAUSE,		/* 0x63 Pause Record Function */
+	KEY_STOP,		/* 0x64 Stop Function  */
+	KEY_MUTE,		/* 0x65 Mute Function */
+	KEY_UNKNOWN,		/* 0x66 Restore Volume Function */
+	KEY_UNKNOWN,		/* 0x67 Tune Function */
+	KEY_UNKNOWN,		/* 0x68 Select Media Function */
+	KEY_RESERVED,		/* 0x69 */
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,		/* 0x70 */
+	KEY_BLUE,			/* 0x71 F1 */
+	KEY_RED,			/* 0x72 F2 */
+	KEY_GREEN,			/* 0x73 F3 */
+	KEY_YELLOW,			/* 0x74 F4 */
+	KEY_UNKNOWN,		/* 0x75 F5 */
+	KEY_RESERVED,		/* 0x76 */
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,		/* 0x7D */
+	KEY_VENDOR,		/* Vendor Specific */
+	KEY_RESERVED,		/* 0x7F */
 };
 
 
@@ -75,10 +191,10 @@
 static irqreturn_t mhl_tx_isr(int irq, void *dev_id);
 static void switch_mode(struct mhl_tx_ctrl *mhl_ctrl,
 			enum mhl_st_type to_mode);
-static void mhl_drive_hpd(struct mhl_tx_ctrl *mhl_ctrl,
-			  uint8_t to_state);
+static void mhl_init_reg_settings(struct mhl_tx_ctrl *mhl_ctrl,
+				  bool mhl_disc_en);
 
-static int mhl_i2c_reg_read(struct i2c_client *client,
+int mhl_i2c_reg_read(struct i2c_client *client,
 			    uint8_t slave_addr_index, uint8_t reg_offset)
 {
 	int rc = -1;
@@ -95,7 +211,7 @@
 }
 
 
-static int mhl_i2c_reg_write(struct i2c_client *client,
+int mhl_i2c_reg_write(struct i2c_client *client,
 			     uint8_t slave_addr_index, uint8_t reg_offset,
 			     uint8_t value)
 {
@@ -103,7 +219,7 @@
 				 reg_offset, &value);
 }
 
-static void mhl_i2c_reg_modify(struct i2c_client *client,
+void mhl_i2c_reg_modify(struct i2c_client *client,
 			       uint8_t slave_addr_index, uint8_t reg_offset,
 			       uint8_t mask, uint8_t val)
 {
@@ -122,6 +238,9 @@
 	int i, rc = 0;
 	struct device_node *of_node = NULL;
 	struct dss_gpio *temp_gpio = NULL;
+	struct platform_device *hdmi_pdev = NULL;
+	struct device_node *hdmi_tx_node = NULL;
+	int dt_gpio;
 	i = 0;
 
 	if (!dev || !pdata) {
@@ -146,7 +265,13 @@
 		goto error;
 	}
 	/* RESET */
-	temp_gpio->gpio = of_get_named_gpio(of_node, "mhl-rst-gpio", 0);
+	dt_gpio = of_get_named_gpio(of_node, "mhl-rst-gpio", 0);
+	if (dt_gpio < 0) {
+		pr_err("%s: Can't get mhl-rst-gpio\n", __func__);
+		goto error;
+	}
+
+	temp_gpio->gpio = dt_gpio;
 	snprintf(temp_gpio->gpio_name, 32, "%s", "mhl-rst-gpio");
 	pr_debug("%s: rst gpio=[%d]\n", __func__,
 		 temp_gpio->gpio);
@@ -160,7 +285,13 @@
 		pr_err("%s: can't alloc %d gpio mem\n", __func__, i);
 		goto error;
 	}
-	temp_gpio->gpio = of_get_named_gpio(of_node, "mhl-pwr-gpio", 0);
+	dt_gpio = of_get_named_gpio(of_node, "mhl-pwr-gpio", 0);
+	if (dt_gpio < 0) {
+		pr_err("%s: Can't get mhl-pwr-gpio\n", __func__);
+		goto error;
+	}
+
+	temp_gpio->gpio = dt_gpio;
 	snprintf(temp_gpio->gpio_name, 32, "%s", "mhl-pwr-gpio");
 	pr_debug("%s: pmic gpio=[%d]\n", __func__,
 		 temp_gpio->gpio);
@@ -174,12 +305,35 @@
 		pr_err("%s: can't alloc %d gpio mem\n", __func__, i);
 		goto error;
 	}
-	temp_gpio->gpio = of_get_named_gpio(of_node, "mhl-intr-gpio", 0);
+	dt_gpio = of_get_named_gpio(of_node, "mhl-intr-gpio", 0);
+	if (dt_gpio < 0) {
+		pr_err("%s: Can't get mhl-intr-gpio\n", __func__);
+		goto error;
+	}
+
+	temp_gpio->gpio = dt_gpio;
 	snprintf(temp_gpio->gpio_name, 32, "%s", "mhl-intr-gpio");
 	pr_debug("%s: intr gpio=[%d]\n", __func__,
 		 temp_gpio->gpio);
 	pdata->gpios[MHL_TX_INTR_GPIO] = temp_gpio;
 
+	/* parse phandle for hdmi tx */
+	hdmi_tx_node = of_parse_phandle(of_node, "qcom,hdmi-tx-map", 0);
+	if (!hdmi_tx_node) {
+		pr_err("%s: can't find hdmi phandle\n", __func__);
+		goto error;
+	}
+
+	hdmi_pdev = of_find_device_by_node(hdmi_tx_node);
+	if (!hdmi_pdev) {
+		pr_err("%s: can't find the device by node\n", __func__);
+		goto error;
+	}
+	pr_debug("%s: hdmi_pdev [0X%x] to pdata->pdev\n",
+	       __func__, (unsigned int)hdmi_pdev);
+
+	pdata->hdmi_pdev = hdmi_pdev;
+
 	return 0;
 error:
 	pr_err("%s: ret due to err\n", __func__);
@@ -191,11 +345,136 @@
 
 static int mhl_sii_reset_pin(struct mhl_tx_ctrl *mhl_ctrl, int on)
 {
-	gpio_set_value(mhl_ctrl->pdata->gpios[MHL_TX_RESET_GPIO]->gpio,
-		       on);
+	if (mhl_ctrl->pdata->gpios[MHL_TX_RESET_GPIO]) {
+		gpio_set_value(
+			mhl_ctrl->pdata->gpios[MHL_TX_RESET_GPIO]->gpio,
+			on);
+	}
 	return 0;
 }
 
+
+static int mhl_sii_wait_for_rgnd(struct mhl_tx_ctrl *mhl_ctrl)
+{
+	int timeout;
+	/* let isr handle RGND interrupt */
+	pr_debug("%s:%u\n", __func__, __LINE__);
+	INIT_COMPLETION(mhl_ctrl->rgnd_done);
+	timeout = wait_for_completion_interruptible_timeout
+		(&mhl_ctrl->rgnd_done, HZ/2);
+	if (!timeout) {
+		/* most likely nothing plugged in USB */
+		/* USB HOST connected or already in USB mode */
+		pr_warn("%s:%u timedout\n", __func__, __LINE__);
+		return -ENODEV;
+	}
+	return mhl_ctrl->mhl_mode ? 0 : 1;
+}
+
+/*  USB_HANDSHAKING FUNCTIONS */
+static int mhl_sii_device_discovery(void *data, int id,
+			     void (*usb_notify_cb)(int online))
+{
+	int rc;
+	struct mhl_tx_ctrl *mhl_ctrl = data;
+
+	if (id) {
+		/* When MHL cable is disconnected we get a sii8334
+		 * mhl_disconnect interrupt which is handled separately.
+		 */
+		pr_debug("%s: USB ID pin high\n", __func__);
+		return id;
+	}
+
+	if (!mhl_ctrl || !usb_notify_cb) {
+		pr_warn("%s: cb || ctrl is NULL\n", __func__);
+		/* return "USB" so caller can proceed */
+		return -EINVAL;
+	}
+
+	if (!mhl_ctrl->notify_usb_online)
+		mhl_ctrl->notify_usb_online = usb_notify_cb;
+
+	if (!mhl_ctrl->disc_enabled) {
+		mhl_sii_reset_pin(mhl_ctrl, 0);
+		msleep(50);
+		mhl_sii_reset_pin(mhl_ctrl, 1);
+		/* TX PR-guide requires a 100 ms wait here */
+		msleep(100);
+		mhl_init_reg_settings(mhl_ctrl, true);
+		rc = mhl_sii_wait_for_rgnd(mhl_ctrl);
+	} else {
+		if (mhl_ctrl->cur_state == POWER_STATE_D3) {
+			rc = mhl_sii_wait_for_rgnd(mhl_ctrl);
+		} else {
+			/* in MHL mode */
+			pr_debug("%s:%u\n", __func__, __LINE__);
+			rc = 0;
+		}
+	}
+	pr_debug("%s: ret result: %s\n", __func__, rc ? "usb" : " mhl");
+	return rc;
+}
+
+static int mhl_power_get_property(struct power_supply *psy,
+				  enum power_supply_property psp,
+				  union power_supply_propval *val)
+{
+	struct mhl_tx_ctrl *mhl_ctrl =
+		container_of(psy, struct mhl_tx_ctrl, mhl_psy);
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_CURRENT_MAX:
+		val->intval = mhl_ctrl->current_val;
+		break;
+	case POWER_SUPPLY_PROP_PRESENT:
+		val->intval = mhl_ctrl->vbus_active;
+		break;
+	case POWER_SUPPLY_PROP_ONLINE:
+		val->intval = mhl_ctrl->vbus_active && mhl_ctrl->mhl_mode;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int mhl_power_set_property(struct power_supply *psy,
+				  enum power_supply_property psp,
+				  const union power_supply_propval *val)
+{
+	struct mhl_tx_ctrl *mhl_ctrl =
+		container_of(psy, struct mhl_tx_ctrl, mhl_psy);
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_PRESENT:
+		mhl_ctrl->vbus_active = val->intval;
+		if (mhl_ctrl->vbus_active)
+			mhl_ctrl->current_val = MAX_CURRENT;
+		else
+			mhl_ctrl->current_val = 0;
+		power_supply_changed(psy);
+		break;
+	case POWER_SUPPLY_PROP_ONLINE:
+	case POWER_SUPPLY_PROP_CURRENT_MAX:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static char *mhl_pm_power_supplied_to[] = {
+	"usb",
+};
+
+static enum power_supply_property mhl_pm_power_props[] = {
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_ONLINE,
+	POWER_SUPPLY_PROP_CURRENT_MAX,
+};
+
 static void cbus_reset(struct i2c_client *client)
 {
 	uint8_t i;
@@ -216,11 +495,11 @@
 	MHL_SII_REG_NAME_WR(REG_INTR5_MASK, 0x00);
 
 	/* Unmask CBUS1 Intrs */
-	MHL_SII_CBUS_WR(0x0009,
+	MHL_SII_REG_NAME_WR(REG_CBUS_INTR_ENABLE,
 		BIT2 | BIT3 | BIT4 | BIT5 | BIT6);
 
 	/* Unmask CBUS2 Intrs */
-	MHL_SII_CBUS_WR(0x001F, BIT2 | BIT3);
+	MHL_SII_REG_NAME_WR(REG_CBUS_MSC_INT2_ENABLE, BIT2 | BIT3);
 
 	for (i = 0; i < 4; i++) {
 		/*
@@ -235,7 +514,6 @@
 		 */
 		MHL_SII_CBUS_WR((0xF0 + i), 0xFF);
 	}
-	return;
 }
 
 static void init_cbus_regs(struct i2c_client *client)
@@ -309,13 +587,15 @@
 /*
  * Configure the initial reg settings
  */
-static void mhl_init_reg_settings(struct i2c_client *client, bool mhl_disc_en)
+static void mhl_init_reg_settings(struct mhl_tx_ctrl *mhl_ctrl,
+	bool mhl_disc_en)
 {
 	/*
 	 * ============================================
 	 * POWER UP
 	 * ============================================
 	 */
+	struct i2c_client *client = mhl_ctrl->i2c_handle;
 
 	/* Power up 1.2V core */
 	MHL_SII_PAGE1_WR(0x003D, 0x3F);
@@ -390,7 +670,7 @@
 		/* Enable MHL Discovery */
 		MHL_SII_REG_NAME_WR(REG_DISC_CTRL1, 0x27);
 		/* Pull-up resistance off for IDLE state */
-		MHL_SII_REG_NAME_WR(REG_DISC_CTRL4, 0xA4);
+		MHL_SII_REG_NAME_WR(REG_DISC_CTRL4, 0x8C);
 	} else {
 		/* Disable MHL Discovery */
 		MHL_SII_REG_NAME_WR(REG_DISC_CTRL1, 0x26);
@@ -401,7 +681,10 @@
 	/* MHL CBUS Discovery - immediate comm.  */
 	MHL_SII_REG_NAME_WR(REG_DISC_CTRL3, 0x86);
 
-	MHL_SII_REG_NAME_MOD(REG_INT_CTRL, BIT5 | BIT4, BIT4);
+	MHL_SII_PAGE3_WR(0x3C, 0x80);
+
+	if (mhl_ctrl->cur_state != POWER_STATE_D3)
+		MHL_SII_REG_NAME_MOD(REG_INT_CTRL, BIT5 | BIT4, BIT4);
 
 	/* Enable Auto Soft RESET */
 	MHL_SII_REG_NAME_WR(REG_SRST, 0x084);
@@ -419,9 +702,8 @@
 
 	switch (to_mode) {
 	case POWER_STATE_D0_NO_MHL:
-		break;
-	case POWER_STATE_D0_MHL:
-		mhl_init_reg_settings(client, true);
+		mhl_ctrl->cur_state = to_mode;
+		mhl_init_reg_settings(mhl_ctrl, true);
 		/* REG_DISC_CTRL1 */
 		MHL_SII_REG_NAME_MOD(REG_DISC_CTRL1, BIT1 | BIT0, BIT0);
 
@@ -429,21 +711,25 @@
 		mhl_i2c_reg_modify(client, TX_PAGE_TPI, 0x001E, BIT1 | BIT0,
 			0x00);
 		break;
+	case POWER_STATE_D0_MHL:
+		mhl_ctrl->cur_state = to_mode;
+		break;
 	case POWER_STATE_D3:
 		if (mhl_ctrl->cur_state == POWER_STATE_D3)
 			break;
 
 		/* Force HPD to 0 when not in MHL mode.  */
 		mhl_drive_hpd(mhl_ctrl, HPD_DOWN);
+		mhl_tmds_ctrl(mhl_ctrl, TMDS_DISABLE);
 		/*
 		 * Change TMDS termination to high impedance
 		 * on disconnection.
 		 */
 		MHL_SII_REG_NAME_WR(REG_MHLTX_CTL1, 0xD0);
 		msleep(50);
-		MHL_SII_REG_NAME_MOD(REG_DISC_CTRL1, BIT1 | BIT0, 0x00);
-		MHL_SII_PAGE3_MOD(0x003D, BIT0,
-				   0x00);
+		if (!mhl_ctrl->disc_enabled)
+			MHL_SII_REG_NAME_MOD(REG_DISC_CTRL1, BIT1 | BIT0, 0x00);
+		MHL_SII_PAGE3_MOD(0x003D, BIT0, 0x00);
 		mhl_ctrl->cur_state = POWER_STATE_D3;
 		break;
 	default:
@@ -451,7 +737,19 @@
 	}
 }
 
-static void mhl_drive_hpd(struct mhl_tx_ctrl *mhl_ctrl, uint8_t to_state)
+
+void mhl_tmds_ctrl(struct mhl_tx_ctrl *mhl_ctrl, uint8_t on)
+{
+	struct i2c_client *client = mhl_ctrl->i2c_handle;
+	if (on) {
+		MHL_SII_REG_NAME_MOD(REG_TMDS_CCTRL, BIT4, BIT4);
+		mhl_drive_hpd(mhl_ctrl, HPD_UP);
+	} else {
+		MHL_SII_REG_NAME_MOD(REG_TMDS_CCTRL, BIT4, 0x00);
+	}
+}
+
+void mhl_drive_hpd(struct mhl_tx_ctrl *mhl_ctrl, uint8_t to_state)
 {
 	struct i2c_client *client = mhl_ctrl->i2c_handle;
 
@@ -459,15 +757,6 @@
 	if (to_state == HPD_UP) {
 		/*
 		 * Drive HPD to UP state
-		 *
-		 * The below two reg configs combined
-		 * enable TMDS output.
-		 */
-
-		/* Enable TMDS on TMDS_CCTRL */
-		MHL_SII_REG_NAME_MOD(REG_TMDS_CCTRL, BIT4, BIT4);
-
-		/*
 		 * Set HPD_OUT_OVR_EN = HPD State
 		 * EDID read and Un-force HPD (from low)
 		 * propogate to src let HPD float by clearing
@@ -475,15 +764,9 @@
 		 */
 		MHL_SII_REG_NAME_MOD(REG_INT_CTRL, BIT4, 0x00);
 	} else {
-		/*
-		 * Drive HPD to DOWN state
-		 * Disable TMDS Output on REG_TMDS_CCTRL
-		 * Enable/Disable TMDS output (MHL TMDS output only)
-		 */
+		/* Drive HPD to DOWN state */
 		MHL_SII_REG_NAME_MOD(REG_INT_CTRL, BIT4, BIT4);
-		MHL_SII_REG_NAME_MOD(REG_TMDS_CCTRL, BIT4, 0x00);
 	}
-	return;
 }
 
 static void mhl_msm_connection(struct mhl_tx_ctrl *mhl_ctrl)
@@ -500,7 +783,7 @@
 		return;
 	}
 	/* spin_lock_irqsave(&mhl_state_lock, flags); */
-	mhl_ctrl->cur_state = POWER_STATE_D0_MHL;
+	switch_mode(mhl_ctrl, POWER_STATE_D0_MHL);
 	/* spin_unlock_irqrestore(&mhl_state_lock, flags); */
 
 	MHL_SII_REG_NAME_WR(REG_MHLTX_CTL1, 0x10);
@@ -514,7 +797,20 @@
 	val = MHL_SII_PAGE3_RD(0x10);
 	MHL_SII_PAGE3_WR(0x10, val | BIT0);
 
-	return;
+	/*
+	 * indicate DCAP_RDY and DCAP_CHG
+	 * to the peer only after
+	 * msm conn has been established
+	 */
+	mhl_msc_send_write_stat(mhl_ctrl,
+				MHL_STATUS_REG_CONNECTED_RDY,
+				MHL_STATUS_DCAP_RDY);
+
+	mhl_msc_send_set_int(mhl_ctrl,
+			     MHL_RCHANGE_INT,
+			     MHL_INT_DCAP_CHG,
+			     MSC_PRIORITY_SEND);
+
 }
 
 static void mhl_msm_disconnection(struct mhl_tx_ctrl *mhl_ctrl)
@@ -527,11 +823,6 @@
 	MHL_SII_PAGE3_WR(0x30, 0xD0);
 
 	switch_mode(mhl_ctrl, POWER_STATE_D3);
-	/*
-	 * Only if MHL-USB handshake is not implemented
-	 */
-	mhl_init_reg_settings(client, true);
-	return;
 }
 
 static int  mhl_msm_read_rgnd_int(struct mhl_tx_ctrl *mhl_ctrl)
@@ -539,20 +830,22 @@
 	uint8_t rgnd_imp;
 	struct i2c_client *client = mhl_ctrl->i2c_handle;
 	/* DISC STATUS REG 2 */
-	rgnd_imp = (mhl_i2c_reg_read(client,
-				     TX_PAGE_3, 0x001C) & (BIT1 | BIT0));
+	rgnd_imp = (mhl_i2c_reg_read(client, TX_PAGE_3, 0x001C) &
+		    (BIT1 | BIT0));
 	pr_debug("imp range read=%02X\n", (int)rgnd_imp);
 
 	if (0x02 == rgnd_imp) {
 		pr_debug("%s: mhl sink\n", __func__);
-		MHL_SII_REG_NAME_MOD(REG_DISC_CTRL9, BIT0, BIT0);
 		mhl_ctrl->mhl_mode = 1;
+		power_supply_changed(&mhl_ctrl->mhl_psy);
+		if (mhl_ctrl->notify_usb_online)
+			mhl_ctrl->notify_usb_online(1);
 	} else {
 		pr_debug("%s: non-mhl sink\n", __func__);
 		mhl_ctrl->mhl_mode = 0;
-		MHL_SII_REG_NAME_MOD(REG_DISC_CTRL9, BIT3, BIT3);
 		switch_mode(mhl_ctrl, POWER_STATE_D3);
 	}
+	complete(&mhl_ctrl->rgnd_done);
 	return mhl_ctrl->mhl_mode ?
 		MHL_DISCOVERY_RESULT_MHL : MHL_DISCOVERY_RESULT_USB;
 }
@@ -640,8 +933,12 @@
 		mhl_msm_connection(mhl_ctrl);
 	} else if (status & BIT3) {
 		pr_debug("%s: uUSB-a type dev detct\n", __func__);
-		MHL_SII_REG_NAME_WR(REG_DISC_STAT2, 0x80);
-		switch_mode(mhl_ctrl, POWER_STATE_D3);
+		/* Short RGND */
+		MHL_SII_REG_NAME_MOD(REG_DISC_STAT2, BIT0 | BIT1, 0x00);
+		mhl_msm_disconnection(mhl_ctrl);
+		power_supply_changed(&mhl_ctrl->mhl_psy);
+		if (mhl_ctrl->notify_usb_online)
+			mhl_ctrl->notify_usb_online(0);
 	}
 
 	if (status & BIT5) {
@@ -651,13 +948,16 @@
 		reg = MHL_SII_REG_NAME_RD(REG_INTR4);
 		MHL_SII_REG_NAME_WR(REG_INTR4, reg);
 		mhl_msm_disconnection(mhl_ctrl);
+		power_supply_changed(&mhl_ctrl->mhl_psy);
+		if (mhl_ctrl->notify_usb_online)
+			mhl_ctrl->notify_usb_online(0);
 	}
 
-	if ((mhl_ctrl->cur_state != POWER_STATE_D0_MHL) &&\
+	if ((mhl_ctrl->cur_state != POWER_STATE_D0_NO_MHL) &&\
 	    (status & BIT6)) {
 		/* rgnd rdy Intr */
 		pr_debug("%s: rgnd ready intr\n", __func__);
-		switch_mode(mhl_ctrl, POWER_STATE_D0_MHL);
+		switch_mode(mhl_ctrl, POWER_STATE_D0_NO_MHL);
 		mhl_msm_read_rgnd_int(mhl_ctrl);
 	}
 
@@ -674,8 +974,6 @@
 		release_usb_switch_open(mhl_ctrl);
 	}
 	MHL_SII_REG_NAME_WR(REG_INTR4, status);
-
-	return;
 }
 
 static void mhl_misc_isr(struct mhl_tx_ctrl *mhl_ctrl)
@@ -716,8 +1014,240 @@
 		cbus_stat = MHL_SII_CBUS_RD(0x0D);
 		if (BIT6 & cbus_stat)
 			mhl_drive_hpd(mhl_ctrl, HPD_UP);
+		else
+			mhl_drive_hpd(mhl_ctrl, HPD_DOWN);
+
 	}
-	return;
+}
+
+static void mhl_sii_cbus_process_errors(struct i2c_client *client,
+					u8 int_status)
+{
+	u8 abort_reason = 0;
+
+	if (int_status & BIT2) {
+		abort_reason = MHL_SII_REG_NAME_RD(REG_DDC_ABORT_REASON);
+		pr_debug("%s: CBUS DDC Abort Reason(0x%02x)\n",
+			 __func__, abort_reason);
+	}
+	if (int_status & BIT5) {
+		abort_reason = MHL_SII_REG_NAME_RD(REG_PRI_XFR_ABORT_REASON);
+		pr_debug("%s: CBUS MSC Requestor Abort Reason(0x%02x)\n",
+			 __func__, abort_reason);
+		MHL_SII_REG_NAME_WR(REG_PRI_XFR_ABORT_REASON, 0xFF);
+	}
+	if (int_status & BIT6) {
+		abort_reason = MHL_SII_REG_NAME_RD(
+			REG_CBUS_PRI_FWR_ABORT_REASON);
+		pr_debug("%s: CBUS MSC Responder Abort Reason(0x%02x)\n",
+			 __func__, abort_reason);
+		MHL_SII_REG_NAME_WR(REG_CBUS_PRI_FWR_ABORT_REASON, 0xFF);
+	}
+}
+
+int mhl_send_msc_command(struct mhl_tx_ctrl *mhl_ctrl,
+			 struct msc_command_struct *req)
+{
+	int timeout;
+	u8 start_bit = 0x00;
+	u8 *burst_data;
+	int i;
+	struct i2c_client *client = mhl_ctrl->i2c_handle;
+
+	if (mhl_ctrl->cur_state != POWER_STATE_D0_MHL) {
+		pr_debug("%s: power_state:%02x CBUS(0x0A):%02x\n",
+			 __func__,
+			 mhl_ctrl->cur_state,
+			 MHL_SII_REG_NAME_RD(REG_CBUS_BUS_STATUS));
+		return -EFAULT;
+	}
+
+	if (!req)
+		return -EFAULT;
+
+	pr_debug("%s: command=0x%02x offset=0x%02x %02x %02x",
+		 __func__,
+		 req->command,
+		 req->offset,
+		 req->payload.data[0],
+		 req->payload.data[1]);
+
+	/* REG_CBUS_PRI_ADDR_CMD = REQ CBUS CMD or OFFSET */
+	MHL_SII_REG_NAME_WR(REG_CBUS_PRI_ADDR_CMD, req->offset);
+	MHL_SII_REG_NAME_WR(REG_CBUS_PRI_WR_DATA_1ST,
+			    req->payload.data[0]);
+
+	switch (req->command) {
+	case MHL_SET_INT:
+	case MHL_WRITE_STAT:
+		start_bit = MSC_START_BIT_WRITE_REG;
+		break;
+	case MHL_READ_DEVCAP:
+		start_bit = MSC_START_BIT_READ_REG;
+		break;
+	case MHL_GET_STATE:
+	case MHL_GET_VENDOR_ID:
+	case MHL_SET_HPD:
+	case MHL_CLR_HPD:
+	case MHL_GET_SC1_ERRORCODE:
+	case MHL_GET_DDC_ERRORCODE:
+	case MHL_GET_MSC_ERRORCODE:
+	case MHL_GET_SC3_ERRORCODE:
+		start_bit = MSC_START_BIT_MSC_CMD;
+		MHL_SII_REG_NAME_WR(REG_CBUS_PRI_ADDR_CMD, req->command);
+		break;
+	case MHL_MSC_MSG:
+		start_bit = MSC_START_BIT_VS_CMD;
+		MHL_SII_REG_NAME_WR(REG_CBUS_PRI_WR_DATA_2ND,
+				    req->payload.data[1]);
+		MHL_SII_REG_NAME_WR(REG_CBUS_PRI_ADDR_CMD, req->command);
+		break;
+	case MHL_WRITE_BURST:
+		start_bit = MSC_START_BIT_WRITE_BURST;
+		MHL_SII_REG_NAME_WR(REG_MSC_WRITE_BURST_LEN, req->length - 1);
+		if (!(req->payload.burst_data)) {
+			pr_err("%s: burst data is null!\n", __func__);
+			goto cbus_send_fail;
+		}
+		burst_data = req->payload.burst_data;
+		for (i = 0; i < req->length; i++, burst_data++)
+			MHL_SII_REG_NAME_WR(REG_CBUS_SCRATCHPAD_0 + i,
+				*burst_data);
+		break;
+	default:
+		pr_err("%s: unknown command! (%02x)\n",
+		       __func__, req->command);
+		goto cbus_send_fail;
+	}
+
+	INIT_COMPLETION(mhl_ctrl->msc_cmd_done);
+	MHL_SII_REG_NAME_WR(REG_CBUS_PRI_START, start_bit);
+	timeout = wait_for_completion_interruptible_timeout
+		(&mhl_ctrl->msc_cmd_done, msecs_to_jiffies(T_ABORT_NEXT));
+	if (!timeout) {
+		pr_err("%s: cbus_command_send timed out!\n", __func__);
+		goto cbus_send_fail;
+	}
+
+	switch (req->command) {
+	case MHL_READ_DEVCAP:
+		req->retval = MHL_SII_REG_NAME_RD(REG_CBUS_PRI_RD_DATA_1ST);
+		break;
+	case MHL_MSC_MSG:
+		/* check if MSC_MSG NACKed */
+		if (MHL_SII_REG_NAME_RD(REG_MSC_WRITE_BURST_LEN) & BIT6)
+			return -EAGAIN;
+	default:
+		req->retval = 0;
+		break;
+	}
+	mhl_msc_command_done(mhl_ctrl, req);
+	pr_debug("%s: msc cmd done\n", __func__);
+	return 0;
+
+cbus_send_fail:
+	return -EFAULT;
+}
+
+/* read scratchpad */
+void mhl_read_scratchpad(struct mhl_tx_ctrl *mhl_ctrl)
+{
+	struct i2c_client *client = mhl_ctrl->i2c_handle;
+	int i;
+
+	for (i = 0; i < MHL_SCRATCHPAD_SIZE; i++) {
+		mhl_ctrl->scrpd.data[i] = MHL_SII_REG_NAME_RD(
+			REG_CBUS_SCRATCHPAD_0 + i);
+	}
+}
+
+static void mhl_cbus_isr(struct mhl_tx_ctrl *mhl_ctrl)
+{
+	uint8_t regval;
+	int req_done = 0;
+	uint8_t sub_cmd = 0x0;
+	uint8_t cmd_data = 0x0;
+	int msc_msg_recved = 0;
+	int rc = -1;
+	struct i2c_client *client = mhl_ctrl->i2c_handle;
+
+	regval = MHL_SII_REG_NAME_RD(REG_CBUS_INTR_STATUS);
+	if (regval == 0xff)
+		return;
+
+	if (regval)
+		MHL_SII_REG_NAME_WR(REG_CBUS_INTR_STATUS, regval);
+
+	pr_debug("%s: CBUS_INT = %02x\n", __func__, regval);
+
+	/* MSC_MSG (RCP/RAP) */
+	if (regval & BIT3) {
+		sub_cmd = MHL_SII_REG_NAME_RD(REG_CBUS_PRI_VS_CMD);
+		cmd_data = MHL_SII_REG_NAME_RD(REG_CBUS_PRI_VS_DATA);
+		msc_msg_recved = 1;
+	}
+	/* MSC_MT_ABRT/MSC_MR_ABRT/DDC_ABORT */
+	if (regval & (BIT6 | BIT5 | BIT2))
+		mhl_sii_cbus_process_errors(client, regval);
+
+	/* MSC_REQ_DONE */
+	if (regval & BIT4)
+		req_done = 1;
+
+	/* look for interrupts on CBUS_MSC_INT2 */
+	regval  = MHL_SII_REG_NAME_RD(REG_CBUS_MSC_INT2_STATUS);
+
+	/* clear all interrupts */
+	if (regval)
+		MHL_SII_REG_NAME_WR(REG_CBUS_MSC_INT2_STATUS, regval);
+
+	pr_debug("%s: CBUS_MSC_INT2 = %02x\n", __func__, regval);
+
+	/* received SET_INT */
+	if (regval & BIT2) {
+		uint8_t intr;
+		intr = MHL_SII_REG_NAME_RD(REG_CBUS_SET_INT_0);
+		MHL_SII_REG_NAME_WR(REG_CBUS_SET_INT_0, intr);
+		mhl_msc_recv_set_int(mhl_ctrl, 0, intr);
+
+		pr_debug("%s: MHL_INT_0 = %02x\n", __func__, intr);
+		intr = MHL_SII_REG_NAME_RD(REG_CBUS_SET_INT_1);
+		MHL_SII_REG_NAME_WR(REG_CBUS_SET_INT_1, intr);
+		mhl_msc_recv_set_int(mhl_ctrl, 1, intr);
+
+		pr_debug("%s: MHL_INT_1 = %02x\n", __func__, intr);
+		MHL_SII_REG_NAME_WR(REG_CBUS_SET_INT_2, 0xFF);
+		MHL_SII_REG_NAME_WR(REG_CBUS_SET_INT_3, 0xFF);
+	}
+
+	/* received WRITE_STAT */
+	if (regval & BIT3) {
+		uint8_t stat;
+		stat = MHL_SII_REG_NAME_RD(REG_CBUS_WRITE_STAT_0);
+		mhl_msc_recv_write_stat(mhl_ctrl, 0, stat);
+
+		pr_debug("%s: MHL_STATUS_0 = %02x\n", __func__, stat);
+		stat = MHL_SII_REG_NAME_RD(REG_CBUS_WRITE_STAT_1);
+		mhl_msc_recv_write_stat(mhl_ctrl, 1, stat);
+		pr_debug("%s: MHL_STATUS_1 = %02x\n", __func__, stat);
+
+		MHL_SII_REG_NAME_WR(REG_CBUS_WRITE_STAT_0, 0xFF);
+		MHL_SII_REG_NAME_WR(REG_CBUS_WRITE_STAT_1, 0xFF);
+		MHL_SII_REG_NAME_WR(REG_CBUS_WRITE_STAT_2, 0xFF);
+		MHL_SII_REG_NAME_WR(REG_CBUS_WRITE_STAT_3, 0xFF);
+	}
+
+	/* received MSC_MSG */
+	if (msc_msg_recved) {
+		/*mhl msc recv msc msg*/
+		rc = mhl_msc_recv_msc_msg(mhl_ctrl, sub_cmd, cmd_data);
+		if (rc)
+			pr_err("MHL: mhl msc recv msc msg failed(%d)!\n", rc);
+	}
+	/* complete last command */
+	if (req_done)
+		complete_all(&mhl_ctrl->msc_cmd_done);
+
 }
 
 static void clear_all_intrs(struct i2c_client *client)
@@ -856,11 +1386,11 @@
 		mhl_misc_isr(mhl_ctrl);
 
 		/*
-		 * Check for any peer messages for DCAP_CHG etc
+		 * Check for any peer messages for DCAP_CHG, MSC etc
 		 * Dispatch to have the CBUS module working only
 		 * once connected.
-		mhl_cbus_isr(mhl_ctrl);
 		 */
+		mhl_cbus_isr(mhl_ctrl);
 		mhl_hpd_stat_isr(mhl_ctrl);
 	}
 
@@ -884,12 +1414,14 @@
 	/* Read the chip rev ID */
 	chip_rev_id = MHL_SII_PAGE0_RD(0x04);
 	pr_debug("MHL: chip rev ID read=[%x]\n", chip_rev_id);
+	mhl_ctrl->chip_rev_id = chip_rev_id;
 
 	/*
 	 * Need to disable MHL discovery if
 	 * MHL-USB handshake is implemented
 	 */
-	mhl_init_reg_settings(client, true);
+	mhl_init_reg_settings(mhl_ctrl, true);
+	switch_mode(mhl_ctrl, POWER_STATE_D3);
 	return 0;
 }
 
@@ -897,14 +1429,16 @@
 {
 	static struct regulator *reg_8941_l24;
 	static struct regulator *reg_8941_l02;
+	static struct regulator *reg_8941_smps3a;
+	static struct regulator *reg_8941_vdda;
 	int rc;
 
-	pr_debug("Inside %s\n", __func__);
+	pr_debug("%s\n", __func__);
 	if (!reg_8941_l24) {
 		reg_8941_l24 = regulator_get(&client->dev,
 			"avcc_18");
 		if (IS_ERR(reg_8941_l24)) {
-			pr_err("could not get reg_8038_l20, rc = %ld\n",
+			pr_err("could not get 8941 l24, rc = %ld\n",
 				PTR_ERR(reg_8941_l24));
 			return -ENODEV;
 		}
@@ -915,7 +1449,7 @@
 		if (rc) {
 			pr_err("'%s' regulator config[%u] failed, rc=%d\n",
 			       "avcc_1.8V", enable, rc);
-			return rc;
+			goto l24_fail;
 		} else {
 			pr_debug("%s: vreg L24 %s\n",
 				 __func__, (enable ? "enabled" : "disabled"));
@@ -928,7 +1462,7 @@
 		if (IS_ERR(reg_8941_l02)) {
 			pr_err("could not get reg_8941_l02, rc = %ld\n",
 				PTR_ERR(reg_8941_l02));
-			return -ENODEV;
+			goto l24_fail;
 		}
 		if (enable)
 			rc = regulator_enable(reg_8941_l02);
@@ -937,14 +1471,73 @@
 		if (rc) {
 			pr_debug("'%s' regulator configure[%u] failed, rc=%d\n",
 				 "avcc_1.2V", enable, rc);
-			return rc;
+			goto l02_fail;
 		} else {
 			pr_debug("%s: vreg L02 %s\n",
 				 __func__, (enable ? "enabled" : "disabled"));
 		}
 	}
 
+	if (!reg_8941_smps3a) {
+		reg_8941_smps3a = regulator_get(&client->dev,
+			"smps3a");
+		if (IS_ERR(reg_8941_smps3a)) {
+			pr_err("could not get vreg smps3a, rc = %ld\n",
+				PTR_ERR(reg_8941_smps3a));
+			goto l02_fail;
+		}
+		if (enable)
+			rc = regulator_enable(reg_8941_smps3a);
+		else
+			rc = regulator_disable(reg_8941_smps3a);
+		if (rc) {
+			pr_err("'%s' regulator config[%u] failed, rc=%d\n",
+			       "SMPS3A", enable, rc);
+			goto smps3a_fail;
+		} else {
+			pr_debug("%s: vreg SMPS3A %s\n",
+				 __func__, (enable ? "enabled" : "disabled"));
+		}
+	}
+
+	if (!reg_8941_vdda) {
+		reg_8941_vdda = regulator_get(&client->dev,
+			"vdda");
+		if (IS_ERR(reg_8941_vdda)) {
+			pr_err("could not get vreg vdda, rc = %ld\n",
+				PTR_ERR(reg_8941_vdda));
+			goto smps3a_fail;
+		}
+		if (enable)
+			rc = regulator_enable(reg_8941_vdda);
+		else
+			rc = regulator_disable(reg_8941_vdda);
+		if (rc) {
+			pr_err("'%s' regulator config[%u] failed, rc=%d\n",
+			       "VDDA", enable, rc);
+			goto vdda_fail;
+		} else {
+			pr_debug("%s: vreg VDDA %s\n",
+				 __func__, (enable ? "enabled" : "disabled"));
+		}
+	}
+
 	return rc;
+
+vdda_fail:
+	regulator_disable(reg_8941_vdda);
+	regulator_put(reg_8941_vdda);
+smps3a_fail:
+	regulator_disable(reg_8941_smps3a);
+	regulator_put(reg_8941_smps3a);
+l02_fail:
+	regulator_disable(reg_8941_l02);
+	regulator_put(reg_8941_l02);
+l24_fail:
+	regulator_disable(reg_8941_l24);
+	regulator_put(reg_8941_l24);
+
+	return -EINVAL;
 }
 
 
@@ -967,13 +1560,13 @@
 		if (ret < 0) {
 			pr_err("%s: set gpio MHL_PWR_EN dircn failed: %d\n",
 			       __func__, ret);
-			return ret;
+			goto vreg_config_failed;
 		}
 
 		ret = mhl_sii_reg_config(client, true);
 		if (ret) {
 			pr_err("%s: regulator enable failed\n", __func__);
-			return -EINVAL;
+			goto vreg_config_failed;
 		}
 		pr_debug("%s: mhl sii power on successful\n", __func__);
 	} else {
@@ -983,6 +1576,9 @@
 	}
 	pr_debug("%s: successful\n", __func__);
 	return 0;
+vreg_config_failed:
+	gpio_free(pwr_gpio);
+	return -EINVAL;
 }
 
 /*
@@ -1048,6 +1644,8 @@
 	int rc = 0;
 	struct mhl_tx_platform_data *pdata = NULL;
 	struct mhl_tx_ctrl *mhl_ctrl;
+	struct usb_ext_notification *mhl_info = NULL;
+	struct msm_hdmi_mhl_ops *hdmi_mhl_ops = NULL;
 
 	mhl_ctrl = devm_kzalloc(&client->dev, sizeof(*mhl_ctrl), GFP_KERNEL);
 	if (!mhl_ctrl) {
@@ -1100,6 +1698,60 @@
 	 * Other initializations
 	 * such tx specific
 	 */
+	mhl_ctrl->disc_enabled = false;
+	INIT_WORK(&mhl_ctrl->mhl_msc_send_work, mhl_msc_send_work);
+	mhl_ctrl->cur_state = POWER_STATE_D0_MHL;
+	INIT_LIST_HEAD(&mhl_ctrl->list_cmd);
+	init_completion(&mhl_ctrl->msc_cmd_done);
+	mhl_ctrl->msc_send_workqueue = create_singlethread_workqueue
+		("mhl_msc_cmd_queue");
+
+	mhl_ctrl->input = input_allocate_device();
+	if (mhl_ctrl->input) {
+		int i;
+		struct input_dev *input = mhl_ctrl->input;
+
+		mhl_ctrl->rcp_key_code_tbl = vmalloc(
+			ARRAY_SIZE(support_rcp_key_code_tbl));
+		if (!mhl_ctrl->rcp_key_code_tbl) {
+			pr_err("%s: no alloc mem for rcp keycode tbl\n",
+			       __func__);
+			return -ENOMEM;
+		}
+
+		memcpy(mhl_ctrl->rcp_key_code_tbl,
+		       &support_rcp_key_code_tbl[0],
+		       ARRAY_SIZE(support_rcp_key_code_tbl));
+		mhl_ctrl->rcp_key_code_tbl_len = ARRAY_SIZE(
+			support_rcp_key_code_tbl);
+
+		input->phys = "cbus/input0";
+		input->id.bustype = BUS_VIRTUAL;
+		input->id.vendor  = 0x1095;
+		input->id.product = 0x8334;
+		input->id.version = 0xA;
+
+		input->name = "mhl-rcp";
+
+		input->keycode = support_rcp_key_code_tbl;
+		input->keycodesize = sizeof(u16);
+		input->keycodemax = ARRAY_SIZE(support_rcp_key_code_tbl);
+
+		input->evbit[0] = EV_KEY;
+		for (i = 0; i < ARRAY_SIZE(support_rcp_key_code_tbl); i++) {
+			if (support_rcp_key_code_tbl[i] > 1)
+				input_set_capability(input, EV_KEY,
+					support_rcp_key_code_tbl[i]);
+		}
+
+		if (input_register_device(input) < 0) {
+			pr_warn("%s: failed to register input device\n",
+				__func__);
+			input_free_device(input);
+			mhl_ctrl->input = NULL;
+		}
+	}
+
 	rc = mhl_tx_chip_init(mhl_ctrl);
 	if (rc) {
 		pr_err("%s: tx chip init failed [%d]\n",
@@ -1107,6 +1759,8 @@
 		goto failed_probe;
 	}
 
+	init_completion(&mhl_ctrl->rgnd_done);
+
 	pr_debug("%s: IRQ from GPIO INTR = %d\n",
 		__func__, mhl_ctrl->i2c_handle->irq);
 	pr_debug("%s: Driver name = [%s]\n", __func__,
@@ -1117,20 +1771,100 @@
 				 client->dev.driver->name, mhl_ctrl);
 	if (rc) {
 		pr_err("request_threaded_irq failed, status: %d\n",
-			rc);
+		       rc);
 		goto failed_probe;
 	} else {
 		pr_debug("request_threaded_irq succeeded\n");
 	}
+
+	mhl_ctrl->mhl_psy.name = "ext-vbus";
+	mhl_ctrl->mhl_psy.type = POWER_SUPPLY_TYPE_USB_DCP;
+	mhl_ctrl->mhl_psy.supplied_to = mhl_pm_power_supplied_to;
+	mhl_ctrl->mhl_psy.num_supplicants = ARRAY_SIZE(
+					mhl_pm_power_supplied_to);
+	mhl_ctrl->mhl_psy.properties = mhl_pm_power_props;
+	mhl_ctrl->mhl_psy.num_properties = ARRAY_SIZE(mhl_pm_power_props);
+	mhl_ctrl->mhl_psy.get_property = mhl_power_get_property;
+	mhl_ctrl->mhl_psy.set_property = mhl_power_set_property;
+
+	rc = power_supply_register(&client->dev, &mhl_ctrl->mhl_psy);
+	if (rc < 0) {
+		dev_err(&client->dev, "%s:power_supply_register ext_vbus_psy failed\n",
+			__func__);
+		goto failed_probe;
+	}
+
+	hdmi_mhl_ops = devm_kzalloc(&client->dev,
+				    sizeof(struct msm_hdmi_mhl_ops),
+				    GFP_KERNEL);
+	if (!hdmi_mhl_ops) {
+		pr_err("%s: alloc hdmi mhl ops failed\n", __func__);
+		rc = -ENOMEM;
+		goto failed_probe_pwr;
+	}
+
 	pr_debug("%s: i2c client addr is [%x]\n", __func__, client->addr);
+	if (mhl_ctrl->pdata->hdmi_pdev) {
+		rc = msm_hdmi_register_mhl(mhl_ctrl->pdata->hdmi_pdev,
+					   hdmi_mhl_ops);
+		if (rc) {
+			pr_err("%s: register with hdmi failed\n", __func__);
+			rc = -EPROBE_DEFER;
+			goto failed_probe_pwr;
+		}
+	}
+
+	if (!hdmi_mhl_ops || !hdmi_mhl_ops->tmds_enabled ||
+	    !hdmi_mhl_ops->set_mhl_max_pclk) {
+		pr_err("%s: func ptr is NULL\n", __func__);
+		rc = -EINVAL;
+		goto failed_probe_pwr;
+	}
+	mhl_ctrl->hdmi_mhl_ops = hdmi_mhl_ops;
+
+	rc = hdmi_mhl_ops->set_mhl_max_pclk(
+		mhl_ctrl->pdata->hdmi_pdev, MAX_MHL_PCLK);
+	if (rc) {
+		pr_err("%s: can't set max mhl pclk\n", __func__);
+		goto failed_probe_pwr;
+	}
+
+	mhl_info = devm_kzalloc(&client->dev, sizeof(*mhl_info), GFP_KERNEL);
+	if (!mhl_info) {
+		pr_err("%s: alloc mhl info failed\n", __func__);
+		rc = -ENOMEM;
+		goto failed_probe_pwr;
+	}
+
+	mhl_info->ctxt = mhl_ctrl;
+	mhl_info->notify = mhl_sii_device_discovery;
+	if (msm_register_usb_ext_notification(mhl_info)) {
+		pr_err("%s: register for usb notifcn failed\n", __func__);
+		rc = -EPROBE_DEFER;
+		goto failed_probe_pwr;
+	}
+	mhl_ctrl->mhl_info = mhl_info;
+	mhl_register_msc(mhl_ctrl);
 	return 0;
+
+failed_probe_pwr:
+	power_supply_unregister(&mhl_ctrl->mhl_psy);
 failed_probe:
+	free_irq(mhl_ctrl->i2c_handle->irq, mhl_ctrl);
+	mhl_gpio_config(mhl_ctrl, 0);
+	mhl_vreg_config(mhl_ctrl, 0);
+	/* do not deep-free */
+	if (mhl_info)
+		devm_kfree(&client->dev, mhl_info);
 failed_dt_data:
 	if (pdata)
 		devm_kfree(&client->dev, pdata);
 failed_no_mem:
 	if (mhl_ctrl)
 		devm_kfree(&client->dev, mhl_ctrl);
+	mhl_info = NULL;
+	pdata = NULL;
+	mhl_ctrl = NULL;
 	pr_err("%s: PROBE FAILED, rc=%d\n", __func__, rc);
 	return rc;
 }
@@ -1148,6 +1882,8 @@
 	free_irq(mhl_ctrl->i2c_handle->irq, mhl_ctrl);
 	mhl_gpio_config(mhl_ctrl, 0);
 	mhl_vreg_config(mhl_ctrl, 0);
+	if (mhl_ctrl->mhl_info)
+		devm_kfree(&client->dev, mhl_ctrl->mhl_info);
 	if (mhl_ctrl->pdata)
 		devm_kfree(&client->dev, mhl_ctrl->pdata);
 	devm_kfree(&client->dev, mhl_ctrl);
diff --git a/drivers/video/msm/mdss/msm_mdss_io_8974.c b/drivers/video/msm/mdss/msm_mdss_io_8974.c
index f594b17..3b6fc38 100644
--- a/drivers/video/msm/mdss/msm_mdss_io_8974.c
+++ b/drivers/video/msm/mdss/msm_mdss_io_8974.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -28,52 +28,53 @@
 
 static struct dsi_clk_desc dsi_pclk;
 
-static struct clk *dsi_byte_clk;
-static struct clk *dsi_esc_clk;
-static struct clk *dsi_pixel_clk;
-
-int mdss_dsi_clk_on;
-
-int mdss_dsi_clk_init(struct platform_device *pdev)
+int mdss_dsi_clk_init(struct platform_device *pdev,
+	struct mdss_dsi_ctrl_pdata *ctrl_pdata)
 {
-	struct device *dev = &pdev->dev;
+	struct device *dev = NULL;
 
-	dsi_byte_clk = clk_get(dev, "byte_clk");
-	if (IS_ERR(dsi_byte_clk)) {
+	if (!pdev) {
+		pr_err("%s: Invalid pdev\n", __func__);
+		goto mdss_dsi_clk_err;
+	}
+
+	dev = &pdev->dev;
+	ctrl_pdata->byte_clk = clk_get(dev, "byte_clk");
+	if (IS_ERR(ctrl_pdata->byte_clk)) {
 		pr_err("can't find dsi_byte_clk\n");
-		dsi_byte_clk = NULL;
+		ctrl_pdata->byte_clk = NULL;
 		goto mdss_dsi_clk_err;
 	}
 
-	dsi_pixel_clk = clk_get(dev, "pixel_clk");
-	if (IS_ERR(dsi_pixel_clk)) {
+	ctrl_pdata->pixel_clk = clk_get(dev, "pixel_clk");
+	if (IS_ERR(ctrl_pdata->pixel_clk)) {
 		pr_err("can't find dsi_pixel_clk\n");
-		dsi_pixel_clk = NULL;
+		ctrl_pdata->pixel_clk = NULL;
 		goto mdss_dsi_clk_err;
 	}
 
-	dsi_esc_clk = clk_get(dev, "core_clk");
-	if (IS_ERR(dsi_esc_clk)) {
+	ctrl_pdata->esc_clk = clk_get(dev, "core_clk");
+	if (IS_ERR(ctrl_pdata->esc_clk)) {
 		pr_err("can't find dsi_esc_clk\n");
-		dsi_esc_clk = NULL;
+		ctrl_pdata->esc_clk = NULL;
 		goto mdss_dsi_clk_err;
 	}
 
 	return 0;
 
 mdss_dsi_clk_err:
-	mdss_dsi_clk_deinit(dev);
+	mdss_dsi_clk_deinit(ctrl_pdata);
 	return -EPERM;
 }
 
-void mdss_dsi_clk_deinit(struct device *dev)
+void mdss_dsi_clk_deinit(struct mdss_dsi_ctrl_pdata  *ctrl_pdata)
 {
-	if (dsi_byte_clk)
-		clk_put(dsi_byte_clk);
-	if (dsi_esc_clk)
-		clk_put(dsi_esc_clk);
-	if (dsi_pixel_clk)
-		clk_put(dsi_pixel_clk);
+	if (ctrl_pdata->byte_clk)
+		clk_put(ctrl_pdata->byte_clk);
+	if (ctrl_pdata->esc_clk)
+		clk_put(ctrl_pdata->esc_clk);
+	if (ctrl_pdata->pixel_clk)
+		clk_put(ctrl_pdata->pixel_clk);
 }
 
 #define PREF_DIV_RATIO 27
@@ -155,58 +156,76 @@
 	return 0;
 }
 
-void mdss_dsi_prepare_clocks(void)
+void mdss_dsi_prepare_clocks(struct mdss_dsi_ctrl_pdata  *ctrl_pdata)
 {
-	clk_prepare(dsi_byte_clk);
-	clk_prepare(dsi_esc_clk);
-	clk_prepare(dsi_pixel_clk);
+	clk_prepare(ctrl_pdata->byte_clk);
+	clk_prepare(ctrl_pdata->esc_clk);
+	clk_prepare(ctrl_pdata->pixel_clk);
 }
 
-void mdss_dsi_unprepare_clocks(void)
+void mdss_dsi_unprepare_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
 {
-	clk_unprepare(dsi_esc_clk);
-	clk_unprepare(dsi_pixel_clk);
-	clk_unprepare(dsi_byte_clk);
+	clk_unprepare(ctrl_pdata->esc_clk);
+	clk_unprepare(ctrl_pdata->pixel_clk);
+	clk_unprepare(ctrl_pdata->byte_clk);
 }
 
 void mdss_dsi_clk_enable(struct mdss_panel_data *pdata)
 {
-	if (mdss_dsi_clk_on) {
+	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
+
+	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+				panel_data);
+	if (!ctrl_pdata) {
+		pr_err("%s: Invalid input data\n", __func__);
+		return;
+	}
+
+	if (ctrl_pdata->mdss_dsi_clk_on) {
 		pr_info("%s: mdss_dsi_clks already ON\n", __func__);
 		return;
 	}
 
-	if (clk_set_rate(dsi_esc_clk, 19200000) < 0)
+	if (clk_set_rate(ctrl_pdata->esc_clk, 19200000) < 0)
 		pr_err("%s: dsi_esc_clk - clk_set_rate failed\n",
 					__func__);
 
-	if (clk_set_rate(dsi_byte_clk, 53000000) < 0)
+	if (clk_set_rate(ctrl_pdata->byte_clk, 53000000) < 0)
 		pr_err("%s: dsi_byte_clk - clk_set_rate failed\n",
 					__func__);
 
-	if (clk_set_rate(dsi_pixel_clk, 70000000) < 0)
+	if (clk_set_rate(ctrl_pdata->pixel_clk, 70000000) < 0)
 		pr_err("%s: dsi_pixel_clk - clk_set_rate failed\n",
 					__func__);
 
-	clk_enable(dsi_esc_clk);
-	clk_enable(dsi_byte_clk);
-	clk_enable(dsi_pixel_clk);
+	clk_enable(ctrl_pdata->esc_clk);
+	clk_enable(ctrl_pdata->byte_clk);
+	clk_enable(ctrl_pdata->pixel_clk);
 
-	mdss_dsi_clk_on = 1;
+	ctrl_pdata->mdss_dsi_clk_on = 1;
 }
 
 void mdss_dsi_clk_disable(struct mdss_panel_data *pdata)
 {
-	if (mdss_dsi_clk_on == 0) {
+	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
+
+	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+				panel_data);
+	if (!ctrl_pdata) {
+		pr_err("%s: Invalid input data\n", __func__);
+		return;
+	}
+
+	if (ctrl_pdata->mdss_dsi_clk_on == 0) {
 		pr_info("%s: mdss_dsi_clks already OFF\n", __func__);
 		return;
 	}
 
-	clk_disable(dsi_pixel_clk);
-	clk_disable(dsi_byte_clk);
-	clk_disable(dsi_esc_clk);
+	clk_disable(ctrl_pdata->pixel_clk);
+	clk_disable(ctrl_pdata->byte_clk);
+	clk_disable(ctrl_pdata->esc_clk);
 
-	mdss_dsi_clk_on = 0;
+	ctrl_pdata->mdss_dsi_clk_on = 0;
 }
 
 void mdss_dsi_phy_sw_reset(unsigned char *ctrl_base)
@@ -277,12 +296,20 @@
 	pd = ((ctrl_pdata->panel_data).panel_info.mipi).dsi_phy_db;
 
 	/* Strength ctrl 0 */
-	MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0484, 0x07);
 	MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0484, pd->strength[0]);
 
-	off = 0x0580;	/* phy regulator ctrl settings */
-	/* Regulator ctrl - CAL_PWD_CFG */
+	/* phy regulator ctrl settings. Both the DSI controller
+	   have one regulator */
+	if ((ctrl_pdata->panel_data).panel_info.pdest == DISPLAY_1)
+		off = 0x0580;
+	else
+		off = 0x0580 - 0x600;
+
+	/* Regulator ctrl 0 */
+	MIPI_OUTP((ctrl_pdata->ctrl_base) + off + (4 * 0), 0x0);
+	/* Regulator ctrl - CAL_PWR_CFG */
 	MIPI_OUTP((ctrl_pdata->ctrl_base) + off + (4 * 6), pd->regulator[6]);
+
 	/* Regulator ctrl - TEST */
 	MIPI_OUTP((ctrl_pdata->ctrl_base) + off + (4 * 5), pd->regulator[5]);
 	/* Regulator ctrl 3 */
@@ -296,6 +323,12 @@
 	/* Regulator ctrl 4 */
 	MIPI_OUTP((ctrl_pdata->ctrl_base) + off + (4 * 4), pd->regulator[4]);
 
+	/* LDO ctrl 0 */
+	if ((ctrl_pdata->panel_data).panel_info.pdest == DISPLAY_1)
+		MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x4dc, 0x00);
+	else
+		MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x4dc, 0x00);
+
 	off = 0x0440;	/* phy timing ctrl 0 - 11 */
 	for (i = 0; i < 12; i++) {
 		MIPI_OUTP((ctrl_pdata->ctrl_base) + off, pd->timing[i]);
@@ -327,11 +360,14 @@
 	}
 
 	/* MMSS_DSI_0_PHY_DSIPHY_CTRL_0 */
-	MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0470, 0x7f);
+	MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0470, 0x5f);
 	wmb();
 
 	/* DSI_0_PHY_DSIPHY_GLBL_TEST_CTRL */
-	MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x04d4, 0x01);
+	if ((ctrl_pdata->panel_data).panel_info.pdest == DISPLAY_1)
+		MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x04d4, 0x01);
+	else
+		MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x04d4, 0x00);
 	wmb();
 
 	off = 0x04b4;	/* phy BIST ctrl 0 - 5 */
diff --git a/drivers/video/msm/mhl/mhl_8334.c b/drivers/video/msm/mhl/mhl_8334.c
index 6c0778f..2acf6f4 100644
--- a/drivers/video/msm/mhl/mhl_8334.c
+++ b/drivers/video/msm/mhl/mhl_8334.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/video/msm/mhl/mhl_i2c_utils.c b/drivers/video/msm/mhl/mhl_i2c_utils.c
index ee069bb..d3eec74 100644
--- a/drivers/video/msm/mhl/mhl_i2c_utils.c
+++ b/drivers/video/msm/mhl/mhl_i2c_utils.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/video/msm/mhl/mhl_i2c_utils.h b/drivers/video/msm/mhl/mhl_i2c_utils.h
index 5a2d199..9e4a4fa 100644
--- a/drivers/video/msm/mhl/mhl_i2c_utils.h
+++ b/drivers/video/msm/mhl/mhl_i2c_utils.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/video/msm/mhl_api.h b/drivers/video/msm/mhl_api.h
index 7fdbaa9..691771a 100644
--- a/drivers/video/msm/mhl_api.h
+++ b/drivers/video/msm/mhl_api.h
@@ -1,5 +1,5 @@
 
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/mipi_NT35510.c b/drivers/video/msm/mipi_NT35510.c
index 6d0bf7c..9763c88 100644
--- a/drivers/video/msm/mipi_NT35510.c
+++ b/drivers/video/msm/mipi_NT35510.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/video/msm/mipi_NT35510.h b/drivers/video/msm/mipi_NT35510.h
index 5c81875..58ac05a 100644
--- a/drivers/video/msm/mipi_NT35510.h
+++ b/drivers/video/msm/mipi_NT35510.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/video/msm/mipi_NT35510_cmd_wvga_pt.c b/drivers/video/msm/mipi_NT35510_cmd_wvga_pt.c
index 1524ce6..0f9fece 100644
--- a/drivers/video/msm/mipi_NT35510_cmd_wvga_pt.c
+++ b/drivers/video/msm/mipi_NT35510_cmd_wvga_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/video/msm/mipi_NT35510_video_wvga_pt.c b/drivers/video/msm/mipi_NT35510_video_wvga_pt.c
index 8a364ba..6f2a372 100644
--- a/drivers/video/msm/mipi_NT35510_video_wvga_pt.c
+++ b/drivers/video/msm/mipi_NT35510_video_wvga_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/video/msm/mipi_chimei_wuxga.c b/drivers/video/msm/mipi_chimei_wuxga.c
index e9e291e..3645d61 100644
--- a/drivers/video/msm/mipi_chimei_wuxga.c
+++ b/drivers/video/msm/mipi_chimei_wuxga.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/video/msm/mipi_chimei_wxga_pt.c b/drivers/video/msm/mipi_chimei_wxga_pt.c
index 88a5193..8b1b828 100644
--- a/drivers/video/msm/mipi_chimei_wxga_pt.c
+++ b/drivers/video/msm/mipi_chimei_wxga_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/mipi_dsi.c b/drivers/video/msm/mipi_dsi.c
index 35b6ae6..1528d65 100644
--- a/drivers/video/msm/mipi_dsi.c
+++ b/drivers/video/msm/mipi_dsi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
@@ -319,6 +319,11 @@
 	return ret;
 }
 
+static int mipi_dsi_late_init(struct platform_device *pdev)
+{
+	return panel_next_late_init(pdev);
+}
+
 
 static int mipi_dsi_resource_initialized;
 
@@ -463,6 +468,7 @@
 	pdata = mdp_dev->dev.platform_data;
 	pdata->on = mipi_dsi_on;
 	pdata->off = mipi_dsi_off;
+	pdata->late_init = mipi_dsi_late_init;
 	pdata->next = pdev;
 
 	/*
diff --git a/drivers/video/msm/mipi_dsi.h b/drivers/video/msm/mipi_dsi.h
index 02b42bc..7338a5a 100644
--- a/drivers/video/msm/mipi_dsi.h
+++ b/drivers/video/msm/mipi_dsi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/drivers/video/msm/mipi_dsi_host.c b/drivers/video/msm/mipi_dsi_host.c
index 559c7a1..31883dd 100644
--- a/drivers/video/msm/mipi_dsi_host.c
+++ b/drivers/video/msm/mipi_dsi_host.c
@@ -1,5 +1,5 @@
 
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/drivers/video/msm/mipi_novatek.c b/drivers/video/msm/mipi_novatek.c
index 7e0a46e..60d0944 100644
--- a/drivers/video/msm/mipi_novatek.c
+++ b/drivers/video/msm/mipi_novatek.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -451,6 +451,11 @@
 	return 0;
 }
 
+static int mipi_novatek_lcd_late_init(struct platform_device *pdev)
+{
+	return 0;
+}
+
 DEFINE_LED_TRIGGER(bkl_led_trigger);
 
 static char led_pwm1[2] = {0x51, 0x0};	/* DTYPE_DCS_WRITE1 */
@@ -555,6 +560,7 @@
 static struct msm_fb_panel_data novatek_panel_data = {
 	.on		= mipi_novatek_lcd_on,
 	.off		= mipi_novatek_lcd_off,
+	.late_init	= mipi_novatek_lcd_late_init,
 	.set_backlight = mipi_novatek_set_backlight,
 };
 
diff --git a/drivers/video/msm/mipi_novatek.h b/drivers/video/msm/mipi_novatek.h
index f84de9a..7abe863 100644
--- a/drivers/video/msm/mipi_novatek.h
+++ b/drivers/video/msm/mipi_novatek.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/mipi_novatek_cmd_qhd_pt.c b/drivers/video/msm/mipi_novatek_cmd_qhd_pt.c
index 4c1aa63..d2820a8 100644
--- a/drivers/video/msm/mipi_novatek_cmd_qhd_pt.c
+++ b/drivers/video/msm/mipi_novatek_cmd_qhd_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/mipi_novatek_video_qhd_pt.c b/drivers/video/msm/mipi_novatek_video_qhd_pt.c
index 7a9d556..8881b60 100644
--- a/drivers/video/msm/mipi_novatek_video_qhd_pt.c
+++ b/drivers/video/msm/mipi_novatek_video_qhd_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/mipi_orise.c b/drivers/video/msm/mipi_orise.c
index ea37def..ef3f17d 100644
--- a/drivers/video/msm/mipi_orise.c
+++ b/drivers/video/msm/mipi_orise.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/video/msm/mipi_orise.h b/drivers/video/msm/mipi_orise.h
index 1659479..da4b59f 100644
--- a/drivers/video/msm/mipi_orise.h
+++ b/drivers/video/msm/mipi_orise.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/video/msm/mipi_orise_cmd_720p_pt.c b/drivers/video/msm/mipi_orise_cmd_720p_pt.c
index c2a158d..9b7020a 100644
--- a/drivers/video/msm/mipi_orise_cmd_720p_pt.c
+++ b/drivers/video/msm/mipi_orise_cmd_720p_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/video/msm/mipi_orise_video_720p_pt.c b/drivers/video/msm/mipi_orise_video_720p_pt.c
index da8b5e5..1484576 100644
--- a/drivers/video/msm/mipi_orise_video_720p_pt.c
+++ b/drivers/video/msm/mipi_orise_video_720p_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/video/msm/mipi_renesas.c b/drivers/video/msm/mipi_renesas.c
index 0d6b4be..e2ab01f 100644
--- a/drivers/video/msm/mipi_renesas.c
+++ b/drivers/video/msm/mipi_renesas.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/drivers/video/msm/mipi_renesas.h b/drivers/video/msm/mipi_renesas.h
index 59ccfd0..67f777f 100644
--- a/drivers/video/msm/mipi_renesas.h
+++ b/drivers/video/msm/mipi_renesas.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/mipi_renesas_cmd_fwvga_pt.c b/drivers/video/msm/mipi_renesas_cmd_fwvga_pt.c
index 2ebfad4..1bf86a7 100644
--- a/drivers/video/msm/mipi_renesas_cmd_fwvga_pt.c
+++ b/drivers/video/msm/mipi_renesas_cmd_fwvga_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/drivers/video/msm/mipi_renesas_video_fwvga_pt.c b/drivers/video/msm/mipi_renesas_video_fwvga_pt.c
index 144d9ff..b7f7704 100644
--- a/drivers/video/msm/mipi_renesas_video_fwvga_pt.c
+++ b/drivers/video/msm/mipi_renesas_video_fwvga_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/drivers/video/msm/mipi_simulator.c b/drivers/video/msm/mipi_simulator.c
index cac927b..532b97d 100644
--- a/drivers/video/msm/mipi_simulator.c
+++ b/drivers/video/msm/mipi_simulator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/drivers/video/msm/mipi_simulator.h b/drivers/video/msm/mipi_simulator.h
index 274ce8f..6c0a60c 100644
--- a/drivers/video/msm/mipi_simulator.h
+++ b/drivers/video/msm/mipi_simulator.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/mipi_simulator_video.c b/drivers/video/msm/mipi_simulator_video.c
index 845df75..258a7ec 100644
--- a/drivers/video/msm/mipi_simulator_video.c
+++ b/drivers/video/msm/mipi_simulator_video.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/mipi_tc358764_dsi2lvds.c b/drivers/video/msm/mipi_tc358764_dsi2lvds.c
index 5db4fd2..8c02d14 100644
--- a/drivers/video/msm/mipi_tc358764_dsi2lvds.c
+++ b/drivers/video/msm/mipi_tc358764_dsi2lvds.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/drivers/video/msm/mipi_tc358764_dsi2lvds.h b/drivers/video/msm/mipi_tc358764_dsi2lvds.h
index 1b949f0..671c191 100644
--- a/drivers/video/msm/mipi_tc358764_dsi2lvds.h
+++ b/drivers/video/msm/mipi_tc358764_dsi2lvds.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/mipi_toshiba.c b/drivers/video/msm/mipi_toshiba.c
index 63504c9..bba2807 100644
--- a/drivers/video/msm/mipi_toshiba.c
+++ b/drivers/video/msm/mipi_toshiba.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
@@ -238,6 +238,11 @@
 	return 0;
 }
 
+static int mipi_toshiba_lcd_late_init(struct platform_device *pdev)
+{
+	return 0;
+}
+
 void mipi_bklight_pwm_cfg(void)
 {
 	if (mipi_toshiba_pdata && mipi_toshiba_pdata->dsi_pwm_cfg)
@@ -310,6 +315,7 @@
 static struct msm_fb_panel_data toshiba_panel_data = {
 	.on		= mipi_toshiba_lcd_on,
 	.off		= mipi_toshiba_lcd_off,
+	.late_init	= mipi_toshiba_lcd_late_init,
 	.set_backlight  = mipi_toshiba_set_backlight,
 };
 
diff --git a/drivers/video/msm/mipi_toshiba.h b/drivers/video/msm/mipi_toshiba.h
index dd446b9..faff16d 100644
--- a/drivers/video/msm/mipi_toshiba.h
+++ b/drivers/video/msm/mipi_toshiba.h
@@ -1,5 +1,5 @@
 
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/drivers/video/msm/mipi_toshiba_video_wsvga_pt.c b/drivers/video/msm/mipi_toshiba_video_wsvga_pt.c
index eb2946b..f604f0c 100644
--- a/drivers/video/msm/mipi_toshiba_video_wsvga_pt.c
+++ b/drivers/video/msm/mipi_toshiba_video_wsvga_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/drivers/video/msm/mipi_toshiba_video_wuxga.c b/drivers/video/msm/mipi_toshiba_video_wuxga.c
index 8eddce4..ed7895e 100644
--- a/drivers/video/msm/mipi_toshiba_video_wuxga.c
+++ b/drivers/video/msm/mipi_toshiba_video_wuxga.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/video/msm/mipi_toshiba_video_wvga_pt.c b/drivers/video/msm/mipi_toshiba_video_wvga_pt.c
index d6cabfc..fdd4d1c 100644
--- a/drivers/video/msm/mipi_toshiba_video_wvga_pt.c
+++ b/drivers/video/msm/mipi_toshiba_video_wvga_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/drivers/video/msm/mipi_truly.c b/drivers/video/msm/mipi_truly.c
index ea9c047..016c815 100644
--- a/drivers/video/msm/mipi_truly.c
+++ b/drivers/video/msm/mipi_truly.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/drivers/video/msm/mipi_truly.h b/drivers/video/msm/mipi_truly.h
index 900e6f6..4c12ff9 100644
--- a/drivers/video/msm/mipi_truly.h
+++ b/drivers/video/msm/mipi_truly.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/mipi_truly_tft540960_1_e.c b/drivers/video/msm/mipi_truly_tft540960_1_e.c
index 7f001eb..3b3bcbc 100644
--- a/drivers/video/msm/mipi_truly_tft540960_1_e.c
+++ b/drivers/video/msm/mipi_truly_tft540960_1_e.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/video/msm/mipi_truly_tft540960_1_e.h b/drivers/video/msm/mipi_truly_tft540960_1_e.h
index 8cbfb80..d7329d6 100644
--- a/drivers/video/msm/mipi_truly_tft540960_1_e.h
+++ b/drivers/video/msm/mipi_truly_tft540960_1_e.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/video/msm/mipi_truly_tft540960_1_e_cmd_qhd_pt.c b/drivers/video/msm/mipi_truly_tft540960_1_e_cmd_qhd_pt.c
index 3423241..ad7ebe9 100644
--- a/drivers/video/msm/mipi_truly_tft540960_1_e_cmd_qhd_pt.c
+++ b/drivers/video/msm/mipi_truly_tft540960_1_e_cmd_qhd_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/video/msm/mipi_truly_tft540960_1_e_video_qhd_pt.c b/drivers/video/msm/mipi_truly_tft540960_1_e_video_qhd_pt.c
index 3c0c0b7..d62cfc9 100644
--- a/drivers/video/msm/mipi_truly_tft540960_1_e_video_qhd_pt.c
+++ b/drivers/video/msm/mipi_truly_tft540960_1_e_video_qhd_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/video/msm/mipi_truly_video_wvga_pt.c b/drivers/video/msm/mipi_truly_video_wvga_pt.c
index 03ef32b..3fc14d2 100644
--- a/drivers/video/msm/mipi_truly_video_wvga_pt.c
+++ b/drivers/video/msm/mipi_truly_video_wvga_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/msm_dss_io_7x27a.c b/drivers/video/msm/msm_dss_io_7x27a.c
index 18e8ac5..8610a21 100644
--- a/drivers/video/msm/msm_dss_io_7x27a.c
+++ b/drivers/video/msm/msm_dss_io_7x27a.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/drivers/video/msm/msm_dss_io_8960.c b/drivers/video/msm/msm_dss_io_8960.c
index 682a45a..b1f2b34 100644
--- a/drivers/video/msm/msm_dss_io_8960.c
+++ b/drivers/video/msm/msm_dss_io_8960.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/drivers/video/msm/msm_dss_io_8x60.c b/drivers/video/msm/msm_dss_io_8x60.c
index c79c4c7..d60bfad 100644
--- a/drivers/video/msm/msm_dss_io_8x60.c
+++ b/drivers/video/msm/msm_dss_io_8x60.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index b7e0bbf..b96e093 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -3,7 +3,7 @@
  * Core MSM framebuffer driver.
  *
  * Copyright (C) 2007 Google Incorporated
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -726,36 +726,11 @@
 		   },
 };
 
-#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CONFIG_FB_MSM_MDP303)
-static void memset32_io(u32 __iomem *_ptr, u32 val, size_t count)
-{
-	count >>= 2;
-	while (count--)
-		writel(val, _ptr++);
-}
-#endif
-
 #ifdef CONFIG_HAS_EARLYSUSPEND
 static void msmfb_early_suspend(struct early_suspend *h)
 {
 	struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type,
 						    early_suspend);
-#if defined(CONFIG_FB_MSM_MDP303)
-	/*
-	* For MDP with overlay, set framebuffer with black pixels
-	* to show black screen on HDMI.
-	*/
-	struct fb_info *fbi = mfd->fbi;
-	switch (mfd->fbi->var.bits_per_pixel) {
-	case 32:
-		memset32_io((void *)fbi->screen_base, 0xFF000000,
-							fbi->fix.smem_len);
-		break;
-	default:
-		memset32_io((void *)fbi->screen_base, 0x00, fbi->fix.smem_len);
-		break;
-	}
-#endif
 	msm_fb_suspend_sub(mfd);
 }
 
@@ -1206,6 +1181,26 @@
 		bpp = 4;
 		break;
 
+	case MDP_BGRA_8888:
+		fix->type = FB_TYPE_PACKED_PIXELS;
+		fix->xpanstep = 1;
+		fix->ypanstep = 1;
+		var->vmode = FB_VMODE_NONINTERLACED;
+		var->blue.offset = 0;
+		var->green.offset = 8;
+		var->red.offset = 16;
+		var->blue.length = 8;
+		var->green.length = 8;
+		var->red.length = 8;
+		var->blue.msb_right = 0;
+		var->green.msb_right = 0;
+		var->red.msb_right = 0;
+		var->transp.offset = 24;
+		var->transp.length = 8;
+		bpp = 4;
+		break;
+
+
 	case MDP_YCRYCB_H2V1:
 		/* ToDo: need to check TV-Out YUV422i framebuffer format */
 		/*       we might need to create new type define */
@@ -1287,8 +1282,6 @@
 		((PAGE_SIZE - remainder)/fix->line_length) * mfd->fb_page;
 	var->bits_per_pixel = bpp * 8;	/* FrameBuffer color depth */
 
-	var->reserved[4] = mdp_get_panel_framerate(mfd);
-
 		/*
 		 * id field for fb app
 		 */
@@ -1595,6 +1588,7 @@
 static int msm_fb_open(struct fb_info *info, int user)
 {
 	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	bool unblank = true;
 	int result;
 
 	result = pm_runtime_get_sync(info->dev);
@@ -1616,9 +1610,16 @@
 			pr_debug("%s:%d no mdp_set_dma_pan_info %d\n",
 				__func__, __LINE__, info->node);
 
-		if (msm_fb_blank_sub(FB_BLANK_UNBLANK, info, mfd->op_enable)) {
-			printk(KERN_ERR "msm_fb_open: can't turn on display!\n");
-			return -1;
+		if (mfd->is_panel_ready && !mfd->is_panel_ready())
+			unblank = false;
+
+		if (unblank) {
+			if (msm_fb_blank_sub(FB_BLANK_UNBLANK,
+				info, mfd->op_enable)) {
+				MSM_FB_ERR("%s: can't turn on display!\n",
+					__func__);
+				return -EPERM;
+			}
 		}
 	}
 
@@ -1757,7 +1758,7 @@
 	}
 
 	mdp_set_dma_pan_info(info, dirtyPtr,
-			     (var->activate == FB_ACTIVATE_VBL));
+			     (var->activate & FB_ACTIVATE_VBL));
 	mdp_dma_pan_update(info);
 	up(&msm_fb_pan_sem);
 
@@ -1774,8 +1775,6 @@
 
 static int msm_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
-	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
-
 	if (var->rotate != FB_ROTATE_UR)
 		return -EINVAL;
 	if (var->grayscale != info->var.grayscale)
@@ -1864,12 +1863,6 @@
 	if ((var->xres == 0) || (var->yres == 0))
 		return -EINVAL;
 
-	if ((var->xres > MAX(mfd->panel_info.xres,
-			     mfd->panel_info.mode2_xres)) ||
-		(var->yres > MAX(mfd->panel_info.yres,
-				 mfd->panel_info.mode2_yres)))
-		return -EINVAL;
-
 	if (var->xoffset > (var->xres_virtual - var->xres))
 		return -EINVAL;
 
@@ -1927,7 +1920,9 @@
 		break;
 
 	case 32:
-		if (var->transp.offset == 24)
+		if ((var->transp.offset == 24) && (var->blue.offset == 0))
+			mfd->fb_imgType = MDP_BGRA_8888;
+		else if (var->transp.offset == 24)
 			mfd->fb_imgType = MDP_ARGB_8888;
 		else
 			mfd->fb_imgType = MDP_RGBA_8888;
@@ -1953,6 +1948,10 @@
 
 	if (blank) {
 		msm_fb_blank_sub(FB_BLANK_POWERDOWN, info, mfd->op_enable);
+
+		if (mfd->update_panel_info)
+			mfd->update_panel_info(mfd);
+
 		msm_fb_blank_sub(FB_BLANK_UNBLANK, info, mfd->op_enable);
 	}
 
@@ -3144,6 +3143,7 @@
 #endif
 
 DEFINE_SEMAPHORE(msm_fb_ioctl_ppp_sem);
+DEFINE_SEMAPHORE(msm_fb_ioctl_vsync_sem);
 DEFINE_MUTEX(msm_fb_ioctl_lut_sem);
 
 /* Set color conversion matrix from user space */
@@ -3273,6 +3273,10 @@
 		ret = mdp4_qseed_cfg((struct mdp_qseed_cfg_data *)
 						&pp_ptr->data.qseed_cfg_data);
 		break;
+	case mdp_op_calib_cfg:
+		ret = mdp4_calib_config((struct mdp_calib_config_data *)
+						&pp_ptr->data.calib_cfg);
+		break;
 #endif
 	case mdp_bl_scale_cfg:
 		ret = mdp_bl_scale_config(mfd, (struct mdp_bl_scale_data *)
@@ -3297,6 +3301,10 @@
 		ret = mdp4_update_base_blend(mfd,
 						&metadata_ptr->data.blend_cfg);
 		break;
+	case metadata_op_wb_format:
+		ret = mdp4_update_writeback_format(mfd,
+					&metadata_ptr->data.mixer_cfg);
+		break;
 #endif
 	default:
 		pr_warn("Unsupported request to MDP META IOCTL.\n");
@@ -3305,6 +3313,24 @@
 	}
 	return ret;
 }
+
+static int msmfb_get_metadata(struct msm_fb_data_type *mfd,
+				struct msmfb_metadata *metadata_ptr)
+{
+	int ret = 0;
+	switch (metadata_ptr->op) {
+	case metadata_op_frame_rate:
+		metadata_ptr->data.panel_frame_rate =
+			mdp_get_panel_framerate(mfd);
+		break;
+	default:
+		pr_warn("Unsupported request to MDP META IOCTL.\n");
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
 static int msm_fb_ioctl(struct fb_info *info, unsigned int cmd,
 			unsigned long arg)
 {
@@ -3384,12 +3410,12 @@
 #endif
 	case MSMFB_VSYNC_CTRL:
 	case MSMFB_OVERLAY_VSYNC_CTRL:
-		down(&msm_fb_ioctl_ppp_sem);
+		down(&msm_fb_ioctl_vsync_sem);
 		if (mdp_rev >= MDP_REV_40)
 			ret = msmfb_overlay_vsync_ctrl(info, argp);
 		else
 			ret = msmfb_vsync_ctrl(info, argp);
-		up(&msm_fb_ioctl_ppp_sem);
+		up(&msm_fb_ioctl_vsync_sem);
 		break;
 	case MSMFB_BLIT:
 		down(&msm_fb_ioctl_ppp_sem);
@@ -3607,6 +3633,8 @@
 			return ret;
 
 		ret = msmfb_handle_pp_ioctl(mfd, &mdp_pp);
+		if (ret == 1)
+			ret = copy_to_user(argp, &mdp_pp, sizeof(mdp_pp));
 		break;
 
 	case MSMFB_METADATA_SET:
@@ -3616,6 +3644,16 @@
 		ret = msmfb_handle_metadata_ioctl(mfd, &mdp_metadata);
 		break;
 
+	case MSMFB_METADATA_GET:
+		ret = copy_from_user(&mdp_metadata, argp, sizeof(mdp_metadata));
+		if (ret)
+			return ret;
+		ret = msmfb_get_metadata(mfd, &mdp_metadata);
+		if (!ret)
+			ret = copy_to_user(argp, &mdp_metadata,
+				sizeof(mdp_metadata));
+		break;
+
 	default:
 		MSM_FB_INFO("MDP: unknown ioctl (cmd=%x) received!\n", cmd);
 		ret = -EINVAL;
@@ -3877,7 +3915,7 @@
 EXPORT_SYMBOL(msm_fb_v4l2_enable);
 
 /* Called by v4l2 driver to provide a frame for display */
-int msm_fb_v4l2_update(void *par,
+int msm_fb_v4l2_update(void *par, bool bUserPtr,
 	unsigned long srcp0_addr, unsigned long srcp0_size,
 	unsigned long srcp1_addr, unsigned long srcp1_size,
 	unsigned long srcp2_addr, unsigned long srcp2_size)
@@ -3889,9 +3927,14 @@
 		srcp2_addr);
 #else
 #ifdef CONFIG_FB_MSM_MDP30
-	return mdp_ppp_v4l2_overlay_play(fbi_list[0],
-		srcp0_addr, srcp0_size,
-		srcp1_addr, srcp1_size);
+	if (bUserPtr)
+		return mdp_ppp_v4l2_overlay_play(fbi_list[0], true,
+				srcp0_addr, srcp0_size,
+				srcp1_addr, srcp1_size);
+	else
+		return mdp_ppp_v4l2_overlay_play(fbi_list[0], false,
+			srcp0_addr, srcp0_size,
+			srcp1_addr, srcp1_size);
 #else
 	return -EINVAL;
 #endif
diff --git a/drivers/video/msm/msm_fb.h b/drivers/video/msm/msm_fb.h
index 9c4f3d3..34cb1fc 100644
--- a/drivers/video/msm/msm_fb.h
+++ b/drivers/video/msm/msm_fb.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
@@ -138,6 +138,8 @@
 	int (*stop_histogram) (struct fb_info *info, uint32_t block);
 	void (*vsync_ctrl) (int enable);
 	void (*vsync_init) (int cndx);
+	void (*update_panel_info)(struct msm_fb_data_type *mfd);
+	bool (*is_panel_ready)(void);
 	void *vsync_show;
 	void *cursor_buf;
 	void *cursor_buf_phys;
diff --git a/drivers/video/msm/msm_fb_bl.c b/drivers/video/msm/msm_fb_bl.c
index b21adee..cdedc6f 100644
--- a/drivers/video/msm/msm_fb_bl.c
+++ b/drivers/video/msm/msm_fb_bl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
diff --git a/drivers/video/msm/msm_fb_def.h b/drivers/video/msm/msm_fb_def.h
index 1c1f392..dcd648b 100644
--- a/drivers/video/msm/msm_fb_def.h
+++ b/drivers/video/msm/msm_fb_def.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/drivers/video/msm/msm_fb_panel.c b/drivers/video/msm/msm_fb_panel.c
index 8640116..28698c1 100644
--- a/drivers/video/msm/msm_fb_panel.c
+++ b/drivers/video/msm/msm_fb_panel.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
@@ -78,6 +78,28 @@
 	return ret;
 }
 
+int panel_next_late_init(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct msm_fb_panel_data *pdata;
+	struct msm_fb_panel_data *next_pdata;
+	struct platform_device *next_pdev;
+
+	pdata = (struct msm_fb_panel_data *)pdev->dev.platform_data;
+
+	if (pdata) {
+		next_pdev = pdata->next;
+		if (next_pdev) {
+			next_pdata = (struct msm_fb_panel_data *)
+					next_pdev->dev.platform_data;
+			if ((next_pdata) && (next_pdata->late_init))
+				ret = next_pdata->late_init(next_pdev);
+		}
+	}
+
+	return ret;
+}
+
 struct platform_device *msm_fb_device_alloc(struct msm_fb_panel_data *pdata,
 						u32 type, u32 id)
 {
diff --git a/drivers/video/msm/msm_fb_panel.h b/drivers/video/msm/msm_fb_panel.h
index 505928e..26b88b1 100644
--- a/drivers/video/msm/msm_fb_panel.h
+++ b/drivers/video/msm/msm_fb_panel.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
@@ -200,6 +200,7 @@
 	/* function entry chain */
 	int (*on) (struct platform_device *pdev);
 	int (*off) (struct platform_device *pdev);
+	int (*late_init) (struct platform_device *pdev);
 	int (*power_ctrl) (boolean enable);
 	struct platform_device *next;
 	int (*clk_func) (int enable);
@@ -224,6 +225,7 @@
 						u32 type, u32 id);
 int panel_next_on(struct platform_device *pdev);
 int panel_next_off(struct platform_device *pdev);
+int panel_next_late_init(struct platform_device *pdev);
 
 int lcdc_device_register(struct msm_panel_info *pinfo);
 
diff --git a/drivers/video/msm/tvenc.c b/drivers/video/msm/tvenc.c
index 30dc854..2f3ee97 100644
--- a/drivers/video/msm/tvenc.c
+++ b/drivers/video/msm/tvenc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/drivers/video/msm/tvenc.h b/drivers/video/msm/tvenc.h
index c64c160..0368cb8 100644
--- a/drivers/video/msm/tvenc.h
+++ b/drivers/video/msm/tvenc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/drivers/video/msm/tvout_msm.c b/drivers/video/msm/tvout_msm.c
index 9ee55cc..bc2b8ad 100644
--- a/drivers/video/msm/tvout_msm.c
+++ b/drivers/video/msm/tvout_msm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c
index a82feb9..582744c 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. 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
@@ -88,7 +88,7 @@
 			ddl_context->dram_base_a.align_virtual_addr;
 	}
 	if (!status) {
-		ddl_context->metadata_shared_input.mem_type = DDL_FW_MEM;
+		ddl_context->metadata_shared_input.mem_type = DDL_CMD_MEM;
 		ptr = ddl_pmem_alloc(&ddl_context->metadata_shared_input,
 			DDL_METADATA_TOTAL_INPUTBUFSIZE,
 			DDL_LINEAR_BUFFER_ALIGN_BYTES);
@@ -280,6 +280,25 @@
 		return VCD_ERR_ILLEGAL_OP;
 	}
 	encoder = &ddl->codec_data.encoder;
+	if (DDL_IS_LTR_ENABLED(encoder)) {
+		DDL_MSG_HIGH("LTR enabled, mode %u count %u",
+			(u32)encoder->ltr_control.ltrmode.ltr_mode,
+			(u32)encoder->ltr_control.ltr_count);
+		status = ddl_allocate_ltr_list(&encoder->ltr_control);
+		if (status) {
+			DDL_MSG_ERROR("%s: allocate ltr list failed",
+				__func__);
+			return status;
+		} else {
+			ddl_clear_ltr_list(&encoder->ltr_control, false);
+		}
+		encoder->num_references_for_p_frame = 2;
+		encoder->ltr_control.callback_reqd = false;
+		encoder->ltr_control.curr_ltr_id = (u32)DDL_LTR_FRAME_START_ID;
+		DDL_MSG_HIGH("num_ref_for_p_frames %u, curr_ltr_id = %u",
+			(u32)encoder->num_references_for_p_frame,
+			(u32)encoder->ltr_control.curr_ltr_id);
+	}
 	status = ddl_allocate_enc_hw_buffers(ddl);
 	if (status)
 		return status;
@@ -393,7 +412,7 @@
 		(struct ddl_client_context *) ddl_handle;
 	struct ddl_context *ddl_context;
 	struct ddl_decoder_data *decoder;
-	DDL_MSG_HIGH("ddl_decode_frame");
+	DDL_MSG_MED("ddl_decode_frame");
 	ddl_context = ddl_get_context();
 	if (!DDL_IS_INITIALIZED(ddl_context)) {
 		DDL_MSG_ERROR("ddl_dec_frame:Not_inited");
@@ -472,9 +491,6 @@
 	struct ddl_encoder_data *encoder =
 		&ddl->codec_data.encoder;
 	u32 vcd_status = VCD_S_SUCCESS;
-	struct vcd_transc *transc;
-	transc = (struct vcd_transc *)(ddl->client_data);
-	DDL_MSG_LOW("%s: transc = 0x%x", __func__, (u32)ddl->client_data);
 	if (encoder->slice_delivery_info.enable) {
 		return ddl_encode_frame_batch(ddl_handle,
 					input_frame,
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
index 8836b33..69120e8 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -52,6 +52,19 @@
 #define DDLCLIENT_STATE_IS(ddl, state) \
 	(state == (ddl)->client_state)
 
+#define DDL_IS_LTR_ENABLED(encoder) \
+	((encoder->ltr_control.ltrmode.ltr_mode == \
+		VCD_LTR_MODE_AUTO || \
+	encoder->ltr_control.ltrmode.ltr_mode == \
+		VCD_LTR_MODE_MANUAL) && \
+	(encoder->ltr_control.ltr_count > 0))
+
+#define DDL_IS_LTR_IN_AUTO_MODE(encoder) \
+	((encoder->ltr_control.ltrmode.ltr_mode == \
+		VCD_LTR_MODE_AUTO) && \
+	(encoder->ltr_control.ltr_count > 0) && \
+	(encoder->ltr_control.ltr_period > 0))
+
 #define DDL_DPB_OP_INIT       1
 #define DDL_DPB_OP_MARK_FREE  2
 #define DDL_DPB_OP_MARK_BUSY  3
@@ -72,6 +85,7 @@
 #define DDL_ENC_CHANGE_BITRATE    0x04
 #define DDL_ENC_CHANGE_FRAMERATE  0x08
 #define DDL_ENC_CHANGE_CIR        0x10
+#define DDL_ENC_LTR_USE_FRAME     0x20
 
 #define DDL_DEC_REQ_OUTPUT_FLUSH  0x1
 
@@ -86,6 +100,9 @@
 
 #define MDP_MIN_TILE_HEIGHT			96
 
+#define DDL_MAX_NUM_LTR_FRAMES                  2
+#define DDL_LTR_FRAME_START_ID                  1
+
 enum ddl_mem_area {
 	DDL_FW_MEM	= 0x0,
 	DDL_MM_MEM	= 0x1,
@@ -188,6 +205,7 @@
 	struct ddl_buf_addr h264_nb_ip;
 	struct ddl_buf_addr context;
 	struct ddl_buf_addr extnuserdata;
+	struct ddl_buf_addr meta_hdr[DDL_MAX_BUFFER_COUNT];
 };
 struct ddl_enc_buffer_size{
 	u32  sz_cur_y;
@@ -242,6 +260,43 @@
 	u32 seqdisp_extdump_enable;
 	u32 seq_extdump_enable;
 };
+
+
+struct ddl_ltrlist {
+	bool ltr_in_use;
+	u32 ltr_id;
+};
+
+struct ddl_ltr_encoding_type {
+	struct vcd_property_ltrmode_type  ltrmode;
+	struct vcd_property_ltruse_type  failed_use_cmd;
+	struct ddl_ltrlist *ltr_list;
+	u32 ltr_count;
+	u32 ltr_period;
+	u32 ltr_use_frames;
+	u32 curr_ltr_id;
+	u32 storing_idx;
+	u32 out_frame_cnt_to_use_this_ltr;
+	u32 out_frame_cnt_before_next_idr;
+	bool storing;
+	bool callback_reqd;
+	bool meta_data_reqd;
+	bool using;
+	bool first_ltr_use_arvd;
+	bool use_ltr_reqd;
+	bool store_for_intraframe_insertion;
+	bool pending_chg_ltr_useframes; /* True if
+		 * corresponding driver context of
+		 * out_frame_cnt_to_use_this_ltr
+		 * is pending to be changed with
+		 * client settings
+		 */
+	bool store_ltr0;
+	bool store_ltr1;
+	bool use_ltr0;
+	bool use_ltr1;
+};
+
 struct ddl_encoder_data{
 	struct ddl_codec_data_hdr   hdr;
 	struct vcd_property_codec   codec;
@@ -275,6 +330,7 @@
 	struct ddl_enc_buffers  hw_bufs;
 	struct ddl_yuv_buffer_size  input_buf_size;
 	struct vidc_1080p_enc_frame_info enc_frame_info;
+	struct ddl_ltr_encoding_type  ltr_control;
 	u32  plusptype_enable;
 	u32  meta_data_enable_flag;
 	u32  suffix;
@@ -291,6 +347,7 @@
 	u32  num_references_for_p_frame;
 	u32  closed_gop;
 	u32  num_slices_comp;
+	bool  intra_period_changed;
 	struct vcd_property_slice_delivery_info slice_delivery_info;
 	struct ddl_batch_frame_data batch_frame;
 	u32 avc_delimiter_enable;
@@ -496,7 +553,7 @@
 #ifdef DDL_BUF_LOG
 void ddl_list_buffers(struct ddl_client_context *ddl);
 #endif
-#ifdef DDL_MSG_LOG
+#if DDL_MSG_LOG
 s8 *ddl_get_state_string(enum ddl_client_state client_state);
 #endif
 extern unsigned char *vidc_video_codec_fw;
@@ -510,4 +567,21 @@
 void ddl_vidc_decode_reset_avg_time(struct ddl_client_context *ddl);
 void ddl_calc_core_proc_time(const char *func_name, u32 index,
 		struct ddl_client_context *ddl);
+s32 ddl_encoder_ltr_control(struct ddl_client_context *ddl);
+void ddl_encoder_use_ltr_fail_callback(
+	struct ddl_client_context *ddl);
+void ddl_handle_ltr_in_framedone(struct ddl_client_context *ddl);
+s32 ddl_clear_ltr_list(struct ddl_ltr_encoding_type *ltr_control,
+	bool only_use_flag);
+s32 ddl_find_oldest_ltr_not_in_use(
+	struct ddl_ltr_encoding_type *ltr_control);
+s32 ddl_find_ltr_in_use(struct ddl_ltr_encoding_type *ltr_control);
+s32 ddl_find_ltr_from_list(struct ddl_ltr_encoding_type *ltr_control,
+	u32 ltr_id);
+s32 ddl_use_ltr_from_list(struct ddl_ltr_encoding_type *ltr_control,
+	u32 ltr_idx);
+s32 ddl_allocate_ltr_list(struct ddl_ltr_encoding_type *ltr_control);
+s32 ddl_free_ltr_list(struct ddl_ltr_encoding_type *ltr_control);
+void ddl_print_ltr_list(struct ddl_ltr_encoding_type *ltr_control);
+
 #endif
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_api.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_api.h
index 5c1ee21..3a7e443 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_api.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_api.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h
index db8a777..176699e 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -154,4 +154,10 @@
 #define VIDC_SM_ERR_CONCEALMENT_INTER_SLICE_MB_COPY		2
 #define VIDC_SM_ERR_CONCEALMENT_INTRA_SLICE_COLOR_CONCEALMENT	1
 
+#define DDL_MAX_P_FRAMES_IN_INTRA_INTERVAL      0xffff
+
+#define DDL_SATURATE_P_FRAMES_IN_INTRA_INTERVAL(p_rames) \
+	(((p_rames) > (DDL_MAX_P_FRAMES_IN_INTRA_INTERVAL - 1)) ? \
+	(DDL_MAX_P_FRAMES_IN_INTRA_INTERVAL) : (p_rames))
+
 #endif
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c
index 3646e8c..daafe44 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
index 1782fd2..77faee3 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -22,7 +22,7 @@
 	return &ddl_context;
 }
 
-#ifdef DDL_MSG_LOG
+#if DDL_MSG_LOG
 s8 *ddl_get_state_string(enum ddl_client_state client_state)
 {
 	s8 *ptr;
@@ -265,7 +265,7 @@
 	luma_size = ddl_get_yuv_buf_size(decoder->frame_size.width,
 			decoder->frame_size.height, DDL_YUV_BUF_TYPE_TILE);
 	dpb = decoder->dp_buf.no_of_dec_pic_buf;
-	DDL_MSG_LOW("%s Decoder num DPB buffers = %u Luma Size = %u"
+	DDL_MSG_LOW("%s Decoder num DPB buffers = %u Luma Size = %u",
 				 __func__, dpb, luma_size);
 	if (dpb > DDL_MAX_BUFFER_COUNT)
 		dpb = DDL_MAX_BUFFER_COUNT;
@@ -298,7 +298,7 @@
 		luma[i] = DDL_OFFSET(ddl_context->dram_base_a.
 			align_physical_addr, frame[i].vcd_frm.physical);
 		chroma[i] = luma[i] + luma_size;
-		DDL_MSG_LOW("%s Decoder Luma address = %x Chroma address = %x"
+		DDL_MSG_LOW("%s Decoder Luma address = %x Chroma address = %x",
 					__func__, luma[i], chroma[i]);
 	}
 	switch (decoder->codec.codec) {
@@ -403,6 +403,7 @@
 		ddl_vidc_encode_dynamic_property(ddl, false);
 		encoder->dynamic_prop_change = 0;
 		ddl_free_enc_hw_buffers(ddl);
+		ddl_free_ltr_list(&encoder->ltr_control);
 	}
 	ddl_pmem_free(&ddl->shared_mem[0]);
 	ddl_pmem_free(&ddl->shared_mem[1]);
@@ -505,6 +506,8 @@
 
 	width_round_up  = width;
 	height_round_up = height;
+	align = SZ_4K;
+
 	if (format == DDL_YUV_BUF_TYPE_TILE) {
 		width_round_up  = DDL_ALIGN(width, DDL_TILE_ALIGN_WIDTH);
 		height_round_up = DDL_ALIGN(height, DDL_TILE_ALIGN_HEIGHT);
@@ -780,7 +783,7 @@
 		}
 	}
 	if (buf_size.sz_extnuserdata > 0) {
-		dec_bufs->extnuserdata.mem_type = DDL_FW_MEM;
+		dec_bufs->extnuserdata.mem_type = DDL_CMD_MEM;
 		ptr = ddl_pmem_alloc(&dec_bufs->extnuserdata,
 				buf_size.sz_extnuserdata, DDL_KILO_BYTE(2));
 		if (!ptr)
@@ -999,7 +1002,7 @@
 	u32 luma_size, i, dpb;
 	luma_size = decoder->dpb_buf_size.size_y;
 	dpb = decoder->dp_buf.no_of_dec_pic_buf;
-	DDL_MSG_HIGH("%s Decoder num DPB buffers = %u Luma Size = %u"
+	DDL_MSG_HIGH("%s Decoder num DPB buffers = %u Luma Size = %u",
 			 __func__, dpb, luma_size);
 	if (dpb > DDL_MAX_BUFFER_COUNT)
 		dpb = DDL_MAX_BUFFER_COUNT;
@@ -1137,8 +1140,295 @@
 				vidc_time_out = temp;
 		}
 	}
-	DDL_MSG_HIGH("%s Video core time out value = 0x%x",
+	DDL_MSG_LOW("%s Video core time out value = 0x%x",
 		 __func__, vidc_time_out);
 	vidc_sm_set_video_core_timeout_value(
 		&ddl->shared_mem[ddl->command_channel], vidc_time_out);
 }
+
+void ddl_handle_ltr_in_framedone(struct ddl_client_context *ddl)
+{
+	struct ddl_ltr_encoding_type *ltr_control =
+		&ddl->codec_data.encoder.ltr_control;
+	DDL_MSG_LOW("%s:", __func__);
+	if (ltr_control->storing) {
+		ltr_control->ltr_list[ltr_control->storing_idx].ltr_id =
+			ltr_control->curr_ltr_id;
+		DDL_MSG_MED("Encoder output stores LTR ID %d into entry %d",
+			ltr_control->curr_ltr_id, ltr_control->storing_idx);
+		ltr_control->meta_data_reqd = true;
+		ltr_control->storing = false;
+	}
+	ltr_control->out_frame_cnt_before_next_idr++;
+	if (ltr_control->out_frame_cnt_to_use_this_ltr) {
+		ltr_control->out_frame_cnt_to_use_this_ltr--;
+		if (!ltr_control->out_frame_cnt_to_use_this_ltr)
+			ddl_clear_ltr_list(ltr_control, true);
+	}
+}
+
+s32 ddl_encoder_ltr_control(struct ddl_client_context *ddl)
+{
+	s32 vcd_status = VCD_S_SUCCESS;
+	struct ddl_encoder_data *encoder = &ddl->codec_data.encoder;
+	struct ddl_ltr_encoding_type *ltr_ctrl = &encoder->ltr_control;
+	bool intra_period_reached = false;
+
+	DDL_MSG_LOW("%s:", __func__);
+	ddl_print_ltr_list(ltr_ctrl);
+
+	if (DDL_IS_LTR_IN_AUTO_MODE(encoder)) {
+		bool finite_i_period, infinite_i_period;
+		DDL_MSG_LOW("%s: before LTR encoding: output "\
+			"count before next IDR %d", __func__,
+			ltr_ctrl->out_frame_cnt_before_next_idr);
+		finite_i_period =
+			(DDL_MAX_P_FRAMES_IN_INTRA_INTERVAL !=
+			encoder->i_period.p_frames) &&
+			(!(ltr_ctrl->out_frame_cnt_before_next_idr %
+			(encoder->i_period.p_frames + 1)));
+		infinite_i_period =
+			((DDL_MAX_P_FRAMES_IN_INTRA_INTERVAL ==
+			encoder->i_period.p_frames) &&
+			(!ltr_ctrl->out_frame_cnt_before_next_idr));
+		if (finite_i_period || infinite_i_period) {
+			DDL_MSG_HIGH("%s: Intra period reached. "\
+			"finite_i_period (%u), infinite_i_period (%u)",
+			__func__, (u32)finite_i_period,
+			(u32)infinite_i_period);
+			intra_period_reached = true;
+		}
+		if (intra_period_reached ||
+			ltr_ctrl->store_for_intraframe_insertion ||
+			encoder->intra_period_changed) {
+			ddl_clear_ltr_list(ltr_ctrl, false);
+			ltr_ctrl->out_frame_cnt_before_next_idr = 0;
+			ltr_ctrl->first_ltr_use_arvd = false;
+			ltr_ctrl->store_for_intraframe_insertion = false;
+		} else {
+			if (ltr_ctrl->first_ltr_use_arvd == false) {
+				ddl_use_ltr_from_list(ltr_ctrl, 0);
+				ltr_ctrl->out_frame_cnt_to_use_this_ltr =
+					0xFFFFFFFF;
+				ltr_ctrl->use_ltr_reqd = true;
+			}
+		}
+		if (!(ltr_ctrl->out_frame_cnt_before_next_idr %
+			ltr_ctrl->ltr_period)) {
+			s32 idx;
+			DDL_MSG_HIGH("%s: reached LTR period "\
+				"out_frame_cnt_before_next_idr %d",
+				__func__, ltr_ctrl->\
+				out_frame_cnt_before_next_idr);
+			idx = ddl_find_oldest_ltr_not_in_use(
+					ltr_ctrl);
+			if (idx >= 0) {
+				ltr_ctrl->storing = true;
+				ltr_ctrl->storing_idx = idx;
+				if (idx == 0)
+					ltr_ctrl->store_ltr0 = true;
+				else if (idx == 1)
+					ltr_ctrl->store_ltr1 = true;
+			}
+		}
+	}
+	if (encoder->intra_frame_insertion) {
+		DDL_MSG_HIGH("%s: I-frame insertion requested, "\
+			"delay LTR store for one frame", __func__);
+		ltr_ctrl->store_for_intraframe_insertion = true;
+	}
+	if (ltr_ctrl->pending_chg_ltr_useframes) {
+		ltr_ctrl->out_frame_cnt_to_use_this_ltr =
+			ltr_ctrl->ltr_use_frames;
+		ltr_ctrl->pending_chg_ltr_useframes = false;
+	}
+	if (ltr_ctrl->out_frame_cnt_to_use_this_ltr)
+		ltr_ctrl->use_ltr_reqd = true;
+	if (ltr_ctrl->use_ltr_reqd) {
+		s32 idx;
+		idx = ddl_find_ltr_in_use(ltr_ctrl);
+		if (idx == 0)
+			ltr_ctrl->use_ltr0 = true;
+		else if (idx == 1)
+			ltr_ctrl->use_ltr1 = true;
+		ltr_ctrl->using = true;
+		ltr_ctrl->use_ltr_reqd = false;
+	} else {
+		DDL_MSG_HIGH("%s: use_ltr_reqd skipped", __func__);
+	}
+
+	return vcd_status;
+}
+
+
+s32 ddl_allocate_ltr_list(struct ddl_ltr_encoding_type *ltr_control)
+{
+	s32 vcd_status = VCD_S_SUCCESS;
+
+	DDL_MSG_LOW("%s: lrr_cout = %u", __func__, ltr_control->ltr_count);
+	if (!ltr_control->ltr_list) {
+		if (ltr_control->ltr_count) {
+			ltr_control->ltr_list = (struct ddl_ltrlist *)
+				kmalloc(sizeof(struct ddl_ltrlist)*
+					ltr_control->ltr_count, GFP_KERNEL);
+			if (!ltr_control->ltr_list) {
+				DDL_MSG_ERROR("ddl_allocate_ltr_list failed");
+				vcd_status = VCD_ERR_ALLOC_FAIL;
+			}
+		} else {
+			DDL_MSG_ERROR("%s: failed, zero LTR count", __func__);
+			vcd_status = VCD_ERR_FAIL;
+		}
+	} else {
+		DDL_MSG_HIGH("WARN: ltr_list already allocated");
+	}
+
+	return vcd_status;
+}
+
+s32 ddl_free_ltr_list(struct ddl_ltr_encoding_type *ltr_control)
+{
+	s32 vcd_status = VCD_S_SUCCESS;
+
+	DDL_MSG_LOW("%s:", __func__);
+	kfree(ltr_control->ltr_list);
+	ltr_control->ltr_list = NULL;
+
+	return vcd_status;
+}
+
+s32 ddl_clear_ltr_list(struct ddl_ltr_encoding_type *ltr_control,
+	bool only_use_flag)
+{
+	s32 vcd_status = VCD_S_SUCCESS;
+	u32 i;
+
+	DDL_MSG_LOW("%s:", __func__);
+	for (i = 0; i < ltr_control->ltr_count; i++) {
+		ltr_control->ltr_list[i].ltr_in_use = false;
+		if (!only_use_flag)
+			ltr_control->ltr_list[i].ltr_id = 0;
+	}
+
+	return vcd_status;
+}
+
+s32 ddl_find_oldest_ltr_not_in_use(struct ddl_ltr_encoding_type *ltr_control)
+{
+	s32 found_idx = -1;
+	u32 i;
+
+	if (ltr_control->ltr_list) {
+		if (ltr_control->ltr_count == 1)
+			found_idx = 0;
+		else {
+			for (i = 0; i < ltr_control->ltr_count; i++) {
+				if ((ltr_control->ltr_list[i].ltr_in_use ==
+					false) && (found_idx < 0)) {
+					found_idx = i;
+				}
+				if ((found_idx >= 0) &&
+					(ltr_control->ltr_list[i].\
+					ltr_in_use == false) &&
+					(ltr_control->ltr_list[i].ltr_id <
+					ltr_control->ltr_list[found_idx].\
+					ltr_id)) {
+					found_idx = i;
+				}
+			}
+		}
+	}
+
+	DDL_MSG_LOW("%s: found_idx = %d", __func__, found_idx);
+	return found_idx;
+}
+
+s32 ddl_find_ltr_in_use(struct ddl_ltr_encoding_type *ltr_control)
+{
+	s32 found_idx = -1;
+	u32 i;
+
+	if (ltr_control->ltr_list) {
+		for (i = 0; i < ltr_control->ltr_count; i++) {
+			if (ltr_control->ltr_list[i].ltr_in_use == true)
+				found_idx = i;
+		}
+	}
+
+	DDL_MSG_LOW("%s: found_idx = %d", __func__, found_idx);
+	return found_idx;
+}
+
+s32 ddl_find_ltr_from_list(struct ddl_ltr_encoding_type *ltr_control,
+	u32 ltr_id)
+{
+	s32 found_idx = -1;
+	u32 i;
+
+	if (ltr_control->ltr_list) {
+		for (i = 0; i < ltr_control->ltr_count; i++) {
+			if (ltr_control->ltr_list[i].ltr_id == ltr_id) {
+				found_idx = i;
+				break;
+			}
+		}
+	} else {
+		DDL_MSG_ERROR("%s: ltr_list is NULL", __func__);
+	}
+
+	DDL_MSG_LOW("%s: found_idx = %d", __func__, found_idx);
+	return found_idx;
+}
+
+s32 ddl_use_ltr_from_list(struct ddl_ltr_encoding_type *ltr_control,
+	u32 ltr_idx)
+{
+	s32 vcd_status = VCD_S_SUCCESS;
+	u32 i;
+
+	DDL_MSG_LOW("%s: ltr_idx = %u", __func__, ltr_idx);
+	if (ltr_idx > ltr_control->ltr_count) {
+		DDL_MSG_ERROR("%s: fail, idx %d larger than "\
+			"the list array count %d", __func__,
+			ltr_idx, ltr_control->ltr_count);
+		vcd_status = VCD_ERR_FAIL;
+	} else {
+		for (i = 0; i < ltr_control->ltr_count; i++) {
+			if (i == ltr_idx)
+				ltr_control->ltr_list[ltr_idx].ltr_in_use =
+					true;
+			else
+				ltr_control->ltr_list[i].ltr_in_use = false;
+		}
+	}
+
+	return vcd_status;
+}
+
+void ddl_encoder_use_ltr_fail_callback(struct ddl_client_context *ddl)
+{
+	struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder);
+	struct ddl_context *ddl_context = ddl->ddl_context;
+
+	DDL_MSG_ERROR("%s: LTR use failed, callback "\
+		"requested with LTR ID %d", __func__,
+		encoder->ltr_control.failed_use_cmd.ltr_id);
+
+	ddl_context->ddl_callback(VCD_EVT_IND_INFO_LTRUSE_FAILED,
+			VCD_ERR_ILLEGAL_PARM,
+			&(encoder->ltr_control.failed_use_cmd),
+			sizeof(struct vcd_property_ltruse_type),
+			(u32 *)ddl,
+			ddl->client_data);
+}
+
+void ddl_print_ltr_list(struct ddl_ltr_encoding_type *ltr_control)
+{
+	u32 i;
+
+	for (i = 0; i < ltr_control->ltr_count; i++) {
+		DDL_MSG_MED("%s: ltr_id: %d, ltr_in_use: %d",
+			__func__, ltr_control->ltr_list[i].ltr_id,
+			ltr_control->ltr_list[i].ltr_in_use);
+	}
+}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
index d189408..64cc570 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -822,13 +822,13 @@
 			pixel_cache_stats;
 			vidc_pix_cache_get_statistics(&pixel_cache_stats);
 
-			DDL_MSG_HIGH(" pixel cache hits = %d,"
+			DDL_MSG_LOW(" pixel cache hits = %d,"
 				"miss = %d", pixel_cache_stats.access_hit,
 				pixel_cache_stats.access_miss);
-			DDL_MSG_HIGH(" pixel cache core reqs = %d,"
+			DDL_MSG_LOW(" pixel cache core reqs = %d,"
 				"axi reqs = %d", pixel_cache_stats.core_req,
 				pixel_cache_stats.axi_req);
-			DDL_MSG_HIGH(" pixel cache core bus stats = %d,"
+			DDL_MSG_LOW(" pixel cache core bus stats = %d,"
 			"axi bus stats = %d", pixel_cache_stats.core_bus,
 				pixel_cache_stats.axi_bus);
 		}
@@ -1313,7 +1313,7 @@
 			DDL_MSG_LOW("%s y_cb_cr_size = %u "
 				"actual_output_buf_req.sz = %u"
 				"min_output_buf_req.sz = %u\n",
-				decoder->y_cb_cr_size,
+				__func__, decoder->y_cb_cr_size,
 				decoder->actual_output_buf_req.sz,
 				decoder->min_output_buf_req.sz);
 			vidc_sm_set_chroma_addr_change(
@@ -1474,7 +1474,7 @@
 		}
 	} else
 		status = false;
-	DDL_MSG_HIGH("Enc Frame Type %u", (u32)frame->frame);
+	DDL_MSG_LOW("Enc Frame Type %u", (u32)frame->frame);
 	return status;
 }
 
@@ -1764,7 +1764,17 @@
 			(unsigned long) output_frame->alloc_len,
 			ION_IOC_INV_CACHES);
 	}
-	ddl_process_encoder_metadata(ddl);
+
+	if ((VIDC_1080P_ENCODE_FRAMETYPE_SKIPPED !=
+		encoder->enc_frame_info.enc_frame) &&
+		(VIDC_1080P_ENCODE_FRAMETYPE_NOT_CODED !=
+		encoder->enc_frame_info.enc_frame)) {
+		if (DDL_IS_LTR_ENABLED(encoder))
+			ddl_handle_ltr_in_framedone(ddl);
+		ddl_process_encoder_metadata(ddl);
+		encoder->ltr_control.meta_data_reqd = false;
+	}
+	encoder->ltr_control.using = false;
 	ddl_vidc_encode_dynamic_property(ddl, false);
 	ddl->input_frame.frm_trans_end = false;
 	input_buffer_address = ddl_context->dram_base_a.align_physical_addr +
@@ -1801,8 +1811,10 @@
 	slice_output = (struct vidc_1080p_enc_slice_batch_out_param *)
 		(encoder->batch_frame.slice_batch_out.align_virtual_addr);
 	DDL_MSG_LOW(" after get no of slices = %d\n", num_slices_comp);
-	if (slice_output == NULL)
+	if (slice_output == NULL) {
 		DDL_MSG_ERROR(" slice_output is NULL\n");
+		return; /* Bail out */
+	}
 	encoder->slice_delivery_info.num_slices_enc += num_slices_comp;
 	if (vidc_msg_timing) {
 		ddl_calc_core_proc_time_cnt(__func__, ENC_SLICE_OP_TIME,
@@ -1828,9 +1840,9 @@
 			encoder->batch_frame.output_frame[actual_idx].vcd_frm);
 		DDL_MSG_LOW("OutBfr: vcd_frm 0x%x frmbfr(virtual) 0x%x"
 			"frmbfr(physical) 0x%x\n",
-			&output_frame,
-			output_frame.virtual_base_addr,
-			output_frame.physical_base_addr);
+			(u32)output_frame,
+			(u32)output_frame->virtual,
+			(u32)output_frame->physical);
 		vidc_1080p_get_encode_frame_info(&encoder->enc_frame_info);
 		vidc_sm_get_frame_tags(&ddl->shared_mem
 			[ddl->command_channel],
@@ -1908,17 +1920,17 @@
 		actual_idx =
 			slice_output->slice_info[start_bfr_idx+index]. \
 			stream_buffer_idx;
-		DDL_MSG_LOW("Slice Info: OutBfrIndex %d SliceSize %d",
+		DDL_MSG_LOW("Slice Info: OutBfrIndex %u SliceSize %u",
 			actual_idx,
 			slice_output->slice_info[start_bfr_idx+index]. \
-			stream_buffer_size, 0);
+			stream_buffer_size);
 		output_frame =
 		&(encoder->batch_frame.output_frame[actual_idx].vcd_frm);
 		DDL_MSG_LOW("OutBfr: vcd_frm 0x%x frmbfr(virtual) 0x%x"
 				"frmbfr(physical) 0x%x",
-				&output_frame,
-				output_frame.virtual_base_addr,
-				output_frame.physical_base_addr);
+				(u32)output_frame,
+				(u32)output_frame->virtual,
+				(u32)output_frame->physical);
 		vidc_1080p_get_encode_frame_info(
 			&encoder->enc_frame_info);
 		vidc_sm_get_frame_tags(&ddl->shared_mem
@@ -1936,8 +1948,8 @@
 			slice_output->slice_info[actual_idx].stream_buffer_size;
 		ddl->output_frame =
 			encoder->batch_frame.output_frame[actual_idx];
-		DDL_MSG_LOW(" %s actual_idx = %d"
-		"encoder->batch_frame.num_output_frames = %d\n", __func__,
+		DDL_MSG_LOW("%s: actual_idx = %u "\
+		"encoder->batch_frame.num_output_frames = %u\n", __func__,
 		actual_idx, encoder->batch_frame.num_output_frames);
 		if (encoder->batch_frame.num_output_frames == (actual_idx+1)) {
 			output_frame->flags |= VCD_FRAME_FLAG_ENDOFFRAME;
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c
index f70c47c..2b8eddd 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -75,6 +75,9 @@
 		case VCD_METADATA_QCOMFILLER:
 			skip_words = 6;
 		break;
+		case VCD_METADATA_LTR_INFO:
+			skip_words = 9;
+		break;
 		}
 	}
 	buffer += skip_words;
@@ -146,19 +149,24 @@
 		hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101;
 		hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1;
 		hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_ENC_SLICE;
+
+		hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_LTR_INFO);
+		hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101;
+		hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1;
+		hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_LTR_INFO;
 	}
 }
 
 static u32 ddl_supported_metadata_flag(struct ddl_client_context *ddl)
 {
 	u32 flag = 0;
+	enum vcd_codec codec =
+		ddl->codec_data.decoder.codec.codec;
 
 	if (ddl->decoding) {
-		enum vcd_codec codec =
-			ddl->codec_data.decoder.codec.codec;
-
 		flag |= (VCD_METADATA_CONCEALMB | VCD_METADATA_PASSTHROUGH |
-				VCD_METADATA_QPARRAY);
+				VCD_METADATA_QPARRAY |
+				VCD_METADATA_SEPARATE_BUF);
 		if (codec == VCD_CODEC_H264)
 			flag |= (VCD_METADATA_SEI | VCD_METADATA_VUI);
 		else if (codec == VCD_CODEC_VC1 ||
@@ -167,8 +175,12 @@
 		else if (codec == VCD_CODEC_MPEG2)
 			flag |= (VCD_METADATA_USER_DATA |
 				VCD_METADATA_EXT_DATA);
-	} else
-		flag |= VCD_METADATA_ENC_SLICE;
+	} else {
+		if (codec == VCD_CODEC_H264)
+			flag |= VCD_METADATA_ENC_SLICE | VCD_METADATA_LTR_INFO;
+		else
+			flag |= VCD_METADATA_ENC_SLICE;
+	}
 	return flag;
 }
 
@@ -249,6 +261,9 @@
 	DDL_METADATA_ALIGNSIZE(suffix);
 	decoder->suffix = suffix;
 	output_buf_req->sz += suffix;
+	output_buf_req->meta_buffer_size = suffix;
+	output_buf_req->meta_buffer_size =
+		(output_buf_req->meta_buffer_size + 8191) & (~8191);
 	decoder->meta_data_offset = 0;
 	DDL_MSG_LOW("metadata output buf size : %d", suffix);
 }
@@ -272,6 +287,12 @@
 		DDL_METADATA_ALIGNSIZE(size);
 		suffix += size;
 	}
+	if (flag & VCD_METADATA_LTR_INFO) {
+		size = DDL_METADATA_HDR_SIZE;
+		size += DDL_METADATA_LTR_INFO_PAYLOAD_SIZE;
+		DDL_METADATA_ALIGNSIZE(size);
+		suffix += size;
+	}
 	size = DDL_METADATA_EXTRADATANONE_SIZE;
 	DDL_METADATA_ALIGNSIZE(size);
 	suffix += (size);
@@ -464,13 +485,14 @@
 void ddl_vidc_decode_set_metadata_output(struct ddl_decoder_data *decoder)
 {
 	struct ddl_context *ddl_context;
-	u32 loopc, yuv_size;
+	u32 loopc, yuv_size, dpb;
 	u32 *buffer;
-
+	struct ddl_dec_buffers *dec_buffers = &decoder->hw_bufs;
 	if (!decoder->meta_data_enable_flag) {
 		decoder->meta_data_offset = 0;
 		return;
 	}
+	dpb = decoder->dp_buf.no_of_dec_pic_buf;
 	ddl_context = ddl_get_context();
 	yuv_size = ddl_get_yuv_buffer_size(&decoder->client_frame_size,
 		&decoder->buf_format, !decoder->progressive_only,
@@ -478,15 +500,22 @@
 	decoder->meta_data_offset = DDL_ALIGN_SIZE(yuv_size,
 		DDL_LINEAR_BUF_ALIGN_GUARD_BYTES, DDL_LINEAR_BUF_ALIGN_MASK);
 	buffer = (u32 *) decoder->meta_data_input.align_virtual_addr;
-	*buffer++ = decoder->suffix;
 	DDL_MSG_LOW("Metadata offset & size : %d/%d",
 		decoder->meta_data_offset, decoder->suffix);
-	for (loopc = 0; loopc < decoder->dp_buf.no_of_dec_pic_buf;
-		++loopc) {
-		*buffer++ = (u32)(decoder->meta_data_offset + (u8 *)
+	if (!(decoder->meta_data_enable_flag & VCD_METADATA_SEPARATE_BUF)) {
+		*buffer++ = decoder->suffix;
+		for (loopc = 0; loopc < dpb; ++loopc) {
+			*buffer++ = (u32)(decoder->meta_data_offset + (u8 *)
 			DDL_OFFSET(ddl_context->dram_base_a.
 			align_physical_addr, decoder->dp_buf.
 			dec_pic_buffers[loopc].vcd_frm.physical));
+		}
+	} else {
+		*buffer++ = decoder->actual_output_buf_req.meta_buffer_size;
+		for (loopc = 0; loopc < dpb; ++loopc) {
+			*buffer++ = DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+					dec_buffers->meta_hdr[loopc]);
+		}
 	}
 }
 
@@ -497,27 +526,92 @@
 		&(ddl->output_frame.vcd_frm);
 	u32 *qfiller_hdr, *qfiller, start_addr;
 	u32 qfiller_size;
+	u8 *extradata_addr;
+	u32 metadata_available = false;
+
+	out_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA);
 	if (!encoder->meta_data_enable_flag) {
-		out_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA);
-		return;
+		DDL_MSG_HIGH("meta_data is not enabled");
+		goto exit;
 	}
-	if (!encoder->enc_frame_info.meta_data_exists) {
-		out_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA);
-		return;
-	}
-	out_frame->flags |= VCD_FRAME_FLAG_EXTRADATA;
-	DDL_MSG_LOW("processing metadata for encoder");
 	start_addr = (u32) ((u8 *)out_frame->virtual + out_frame->offset);
-	qfiller = (u32 *)((out_frame->data_len +
+	extradata_addr = (u8 *)((out_frame->data_len +
 				start_addr + 3) & ~3);
+	qfiller = (u32 *)extradata_addr;
 	qfiller_size = (u32)((encoder->meta_data_offset +
 		(u8 *) out_frame->virtual) - (u8 *) qfiller);
+	if (qfiller_size & 3) {
+		DDL_MSG_ERROR("qfiller_size is not 4 bytes aligned");
+		goto exit;
+	}
 	qfiller_hdr = ddl_metadata_hdr_entry(ddl, VCD_METADATA_QCOMFILLER);
 	*qfiller++ = qfiller_size;
 	*qfiller++ = qfiller_hdr[DDL_METADATA_HDR_VERSION_INDEX];
 	*qfiller++ = qfiller_hdr[DDL_METADATA_HDR_PORT_INDEX];
 	*qfiller++ = qfiller_hdr[DDL_METADATA_HDR_TYPE_INDEX];
 	*qfiller = (u32)(qfiller_size - DDL_METADATA_HDR_SIZE);
+	extradata_addr += qfiller_size;
+	if ((u32)extradata_addr !=
+		(u32)((u8 *)start_addr + encoder->meta_data_offset)) {
+		DDL_MSG_ERROR("wrong qfiller size");
+		goto exit;
+	}
+	if (encoder->meta_data_enable_flag & VCD_METADATA_ENC_SLICE) {
+		u32 *sliceinfo = (u32 *)extradata_addr;
+		if (sliceinfo[3] != VCD_METADATA_ENC_SLICE) {
+			DDL_MSG_ERROR("wrong slice info extradata. " \
+				"data: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x",
+				sliceinfo[0], sliceinfo[1],	sliceinfo[2],
+				sliceinfo[3], sliceinfo[4],	sliceinfo[5]);
+			goto metadata_end;
+		}
+		extradata_addr += sliceinfo[0];
+		metadata_available = true;
+		DDL_MSG_HIGH("%s: Send %u slices info in metadata",
+			__func__, sliceinfo[5]);
+	}
+	if ((encoder->meta_data_enable_flag & VCD_METADATA_LTR_INFO) &&
+		(encoder->ltr_control.meta_data_reqd == true)) {
+		u32 *ltrinfo_hdr = ddl_metadata_hdr_entry(ddl,
+				VCD_METADATA_LTR_INFO);
+		u32 *ltrinfo = (u32 *)extradata_addr;
+		if ((u32)extradata_addr > (u32)((u8 *)out_frame->virtual +
+			out_frame->alloc_len)) {
+			metadata_available = false;
+			DDL_MSG_ERROR("Error: extradata_addr = 0x%p, "\
+				"buffer_start = 0x%p, size = %u",
+				extradata_addr, out_frame->virtual,
+				out_frame->alloc_len);
+			goto metadata_end;
+		}
+		ltrinfo[0] = DDL_METADATA_LTR_INFO_PAYLOAD_SIZE +
+				DDL_METADATA_HDR_SIZE;
+		ltrinfo[1] = ltrinfo_hdr[DDL_METADATA_HDR_VERSION_INDEX];
+		ltrinfo[2] = ltrinfo_hdr[DDL_METADATA_HDR_PORT_INDEX];
+		ltrinfo[3] = ltrinfo_hdr[DDL_METADATA_HDR_TYPE_INDEX];
+		ltrinfo[4] = DDL_METADATA_LTR_INFO_PAYLOAD_SIZE;
+		ltrinfo[5] = encoder->ltr_control.curr_ltr_id;
+		extradata_addr += ltrinfo[0];
+		encoder->ltr_control.curr_ltr_id++;
+		metadata_available = true;
+		DDL_MSG_HIGH("%s: Send curr_ltr_id = %u in metadata",
+			__func__, (u32)encoder->ltr_control.curr_ltr_id);
+	}
+metadata_end:
+	if (metadata_available == true) {
+		u32 *data_none_hdr = ddl_metadata_hdr_entry(ddl,
+				VCD_METADATA_DATANONE);
+		u32 *data_none = (u32 *)extradata_addr;
+		DDL_MSG_LOW("prepare metadata_none header");
+		data_none[0] = DDL_METADATA_EXTRADATANONE_SIZE;
+		data_none[1] = data_none_hdr[DDL_METADATA_HDR_VERSION_INDEX];
+		data_none[2] = data_none_hdr[DDL_METADATA_HDR_PORT_INDEX];
+		data_none[3] = data_none_hdr[DDL_METADATA_HDR_TYPE_INDEX];
+		data_none[4] = 0;
+		out_frame->flags |= VCD_FRAME_FLAG_EXTRADATA;
+	}
+exit:
+	return;
 }
 
 void ddl_process_decoder_metadata(struct ddl_client_context *ddl)
@@ -545,7 +639,8 @@
 	DDL_MSG_LOW("data_len/metadata_offset : %d/%d",
 		output_frame->data_len, decoder->meta_data_offset);
 	output_frame->flags |= VCD_FRAME_FLAG_EXTRADATA;
-	if (output_frame->data_len != decoder->meta_data_offset) {
+	if (!(decoder->meta_data_enable_flag & VCD_METADATA_SEPARATE_BUF)
+		&& (output_frame->data_len != decoder->meta_data_offset)) {
 		qfiller = (u32 *)((u32)((output_frame->data_len +
 			output_frame->offset  +
 				(u8 *) output_frame->virtual) + 3) & ~3);
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.h
index e03a9b7..5be38d0 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
@@ -26,6 +26,7 @@
 #define DDL_METADATA_SEI_PAYLOAD_SIZE          100
 #define DDL_METADATA_SEI_MAX                     5
 #define DDL_METADATA_VUI_PAYLOAD_SIZE          256
+#define DDL_METADATA_LTR_INFO_PAYLOAD_SIZE     (4)
 #define DDL_METADATA_PASSTHROUGH_PAYLOAD_SIZE   68
 #define DDL_METADATA_EXT_PAYLOAD_SIZE         (640)
 #define DDL_METADATA_USER_PAYLOAD_SIZE        (2048)
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
index 2b65d7e..5cf2f9c 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -163,6 +163,28 @@
 		DDL_MSG_ERROR("H264BaseLineCABAC!!");
 		return false;
 	}
+	if (DDL_IS_LTR_ENABLED(encoder)) {
+		if ((encoder->codec.codec != VCD_CODEC_H264) ||
+			(encoder->i_period.b_frames)) {
+			DDL_MSG_ERROR("%s: Only support LTR encoding "\
+				"for H264 without B frame. Current "\
+				"codec %d, B-frame %d", __func__,
+				encoder->codec.codec,
+				encoder->i_period.b_frames);
+			return false;
+		}
+		if (encoder->ltr_control.ltrmode.ltr_mode ==
+				VCD_LTR_MODE_MANUAL) {
+			DDL_MSG_ERROR("%s: Manual LTR mode not supported!",
+				__func__);
+			return false;
+		}
+		DDL_MSG_HIGH("%s: LTR: mode = %u, count = %u, period = %u",
+			__func__, (u32)encoder->ltr_control.ltrmode.ltr_mode,
+			encoder->ltr_control.ltr_count,
+			encoder->ltr_control.ltr_period);
+	}
+
 	return true;
 }
 
@@ -319,6 +341,61 @@
 		}
 	}
 	break;
+	case VCD_I_SET_EXT_METABUFFER:
+	{
+		int index, buffer_size;
+		u8 *phys_addr;
+		u8 *virt_addr;
+		struct vcd_property_meta_buffer *meta_buffer =
+			(struct vcd_property_meta_buffer *) property_value;
+		DDL_MSG_LOW("Entered VCD_I_SET_EXT_METABUFFER Virt: %p,"\
+					"Phys %p, fd: %d size: %d count: %d",
+					meta_buffer->kernel_virtual_addr,
+					meta_buffer->physical_addr,
+					meta_buffer->pmem_fd,
+					meta_buffer->size, meta_buffer->count);
+		if ((property_hdr->sz == sizeof(struct
+			vcd_property_meta_buffer)) &&
+			(DDLCLIENT_STATE_IS(ddl,
+			DDL_CLIENT_WAIT_FOR_INITCODEC) ||
+			DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB) ||
+			DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN))) {
+			phys_addr = meta_buffer->dev_addr;
+			virt_addr = meta_buffer->kernel_virtual_addr;
+			buffer_size = meta_buffer->size/meta_buffer->count;
+
+			for (index = 0; index < meta_buffer->count; index++) {
+				ddl->codec_data.decoder.hw_bufs.
+					meta_hdr[index].align_physical_addr
+					= phys_addr;
+				ddl->codec_data.decoder.hw_bufs.
+					meta_hdr[index].align_virtual_addr
+					= virt_addr;
+				ddl->codec_data.decoder.hw_bufs.
+					meta_hdr[index].buffer_size
+					= buffer_size;
+				ddl->codec_data.decoder.hw_bufs.
+					meta_hdr[index].physical_base_addr
+					= phys_addr;
+				ddl->codec_data.decoder.hw_bufs.
+					meta_hdr[index].virtual_base_addr
+					= virt_addr;
+
+				DDL_MSG_LOW("Meta Buffer: "\
+							"Assigned %d buffer for "
+							"virt: %p, phys %p for "
+							"meta_buffers "
+							"of size: %d\n",
+							index, virt_addr,
+							phys_addr, buffer_size);
+
+				phys_addr += buffer_size;
+				virt_addr += buffer_size;
+			}
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
 	case VCD_I_H264_MV_BUFFER:
 	{
 		int index, buffer_size;
@@ -379,6 +456,13 @@
 			vcd_status = VCD_S_SUCCESS;
 		}
 		break;
+	case VCD_I_FREE_EXT_METABUFFER:
+		{
+			memset(&decoder->hw_bufs.meta_hdr, 0, sizeof(struct
+					ddl_buf_addr) * DDL_MAX_BUFFER_COUNT);
+			vcd_status = VCD_S_SUCCESS;
+		}
+		break;
 	case VCD_I_OUTPUT_ORDER:
 		{
 			if (sizeof(u32) == property_hdr->sz &&
@@ -617,8 +701,9 @@
 		struct vcd_property_multi_slice *multi_slice =
 			(struct vcd_property_multi_slice *)
 				property_value;
-		DDL_MSG_HIGH("VCD_I_MULTI_SLICE eMSliceSel %d  nMSliceSize %d"
-				"Tot#of MB %d encoder->frame_size.width = %d"
+		DDL_MSG_HIGH("VCD_I_MULTI_SLICE eMSliceSel %d  "\
+				"nMSliceSize %d Tot#of MB %d "\
+				"encoder->frame_size.width = %d "\
 				"encoder->frame_size.height = %d",
 				(int)multi_slice->m_slice_sel,
 				multi_slice->m_slice_size,
@@ -1030,20 +1115,62 @@
 				encoder->client_output_buf_req.sz/num_slices;
 				encoder->client_output_buf_req.sz =
 				DDL_ALIGN(output_buf_size, DDL_KILO_BYTE(4));
+				if (encoder->client_output_buf_req. \
+					actual_count < encoder-> \
+					client_output_buf_req.min_count) {
+					encoder->client_output_buf_req. \
+					actual_count = encoder-> \
+					client_output_buf_req.min_count;
+				}
 				encoder->output_buf_req =
 				encoder->client_output_buf_req;
-				DDL_MSG_HIGH("%s num_mb = %u num_slices = %u "
-				"output_buf_count = %u "
-				"output_buf_size = %u aligned size = %u\n",
+				DDL_MSG_HIGH("%s num_mb = %u num_slices = %u" \
+				" min_count = %u act_count = %u" \
+				" aligned size = %u\n",
 				__func__, num_mb, num_slices,
 				encoder->client_output_buf_req.min_count,
-				output_buf_size,
+				encoder->client_output_buf_req.actual_count,
 				encoder->client_output_buf_req.sz);
 				vcd_status = VCD_S_SUCCESS;
 			}
 		}
 		break;
 	}
+	case VCD_I_LTR_MODE:
+		if (sizeof(struct vcd_property_ltrmode_type) ==
+			property_hdr->sz && encoder->codec.codec ==
+			VCD_CODEC_H264) {
+			struct vcd_property_ltrmode_type *ltrmode =
+				(struct vcd_property_ltrmode_type *)
+				property_value;
+			encoder->ltr_control.ltrmode.ltr_mode =
+				ltrmode->ltr_mode;
+			DDL_MSG_HIGH("%s: set LTR mode = %u", __func__,
+				(u32)encoder->ltr_control.ltrmode.ltr_mode);
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_LTR_COUNT:
+		if (sizeof(struct vcd_property_ltrcount_type) ==
+			property_hdr->sz && encoder->codec.codec ==
+			VCD_CODEC_H264) {
+			struct vcd_property_ltrcount_type *ltrcount =
+				(struct vcd_property_ltrcount_type *)
+				property_value;
+			if (ltrcount->ltr_count > DDL_MAX_NUM_LTR_FRAMES) {
+				DDL_MSG_ERROR("%s: set LTR count failed. "\
+					"LTR count %u beyond maximum of %u",
+					__func__, ltrcount->ltr_count,
+					(u32)DDL_MAX_NUM_LTR_FRAMES);
+			} else {
+				encoder->ltr_control.ltr_count =
+					ltrcount->ltr_count;
+				DDL_MSG_HIGH("%s: set LTR count = %u", __func__,
+					encoder->ltr_control.ltr_count);
+				vcd_status = VCD_S_SUCCESS;
+			}
+		}
+	break;
 	case VCD_REQ_PERF_LEVEL:
 		vcd_status = VCD_S_SUCCESS;
 		break;
@@ -1091,7 +1218,8 @@
 		break;
 	}
 	default:
-		DDL_MSG_ERROR("INVALID ID %d\n", (int)property_hdr->prop_id);
+		DDL_MSG_ERROR("%s: unknown prop_id = 0x%x", __func__,
+			property_hdr->prop_id);
 		vcd_status = VCD_ERR_ILLEGAL_OP;
 	break;
 	}
@@ -1552,7 +1680,7 @@
 	break;
 	case VCD_I_METADATA_ENABLE:
 	case VCD_I_METADATA_HEADER:
-		DDL_MSG_ERROR("Meta Data Interface is Requested");
+		DDL_MSG_HIGH("Meta Data Interface is Requested");
 		vcd_status = ddl_get_metadata_params(ddl, property_hdr,
 			property_value);
 		vcd_status = VCD_S_SUCCESS;
@@ -1591,7 +1719,67 @@
 			vcd_status = VCD_S_SUCCESS;
 		}
 		break;
+	case VCD_I_CAPABILITY_LTR_COUNT:
+		if (sizeof(struct vcd_property_range_type) ==
+			property_hdr->sz) {
+			struct vcd_property_range_type capability_ltr_range;
+			capability_ltr_range.max = DDL_MAX_NUM_LTR_FRAMES;
+			capability_ltr_range.min = 1;
+			capability_ltr_range.step_size = 1;
+			*(struct vcd_property_range_type *)property_value =
+				capability_ltr_range;
+			DDL_MSG_HIGH("%s: capability_ltr_count = %u",
+				__func__, ((struct vcd_property_range_type *)
+				property_value)->max);
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_LTR_MODE:
+		if (sizeof(struct vcd_property_ltrmode_type) ==
+			property_hdr->sz) {
+			((struct vcd_property_ltrmode_type *)
+			property_value)->ltr_mode =
+				encoder->ltr_control.ltrmode.ltr_mode;
+			DDL_MSG_HIGH("%s: ltr_mode = %u", __func__,
+				(u32)(((struct vcd_property_ltrmode_type *)
+				property_value)->ltr_mode));
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_LTR_COUNT:
+		if (sizeof(struct vcd_property_ltrcount_type) ==
+			property_hdr->sz) {
+			struct vcd_property_ltrcount_type ltr_count;
+			ltr_count.ltr_count =
+				encoder->ltr_control.ltr_count;
+			*(struct vcd_property_ltrcount_type *)property_value =
+				ltr_count;
+			DDL_MSG_HIGH("%s: ltr_count = %u", __func__,
+				((struct vcd_property_ltrcount_type *)
+				property_value)->ltr_count);
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_LTR_PERIOD:
+		if (sizeof(struct vcd_property_ltrperiod_type) ==
+			property_hdr->sz) {
+			struct vcd_property_ltrperiod_type ltr_period;
+			if (!encoder->ltr_control.ltr_period)
+				ltr_period.ltr_period = 0;
+			else
+				ltr_period.ltr_period =
+					encoder->ltr_control.ltr_period - 1;
+			*(struct vcd_property_ltrperiod_type *)property_value =
+				ltr_period;
+			DDL_MSG_HIGH("%s: ltr_period = %u", __func__,
+				((struct vcd_property_ltrperiod_type *)
+				property_value)->ltr_period);
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
 	default:
+		DDL_MSG_ERROR("%s: unknown prop_id = 0x%x", __func__,
+			property_hdr->prop_id);
 		vcd_status = VCD_ERR_ILLEGAL_OP;
 		break;
 	}
@@ -1680,6 +1868,77 @@
 		}
 	}
 	break;
+	case VCD_I_LTR_PERIOD:
+	{
+		if (sizeof(struct vcd_property_ltrperiod_type) ==
+			property_hdr->sz) {
+			struct vcd_property_ltrperiod_type *ltrperiod =
+				(struct vcd_property_ltrperiod_type *)
+				property_value;
+			encoder->ltr_control.ltr_period =
+				(ltrperiod->ltr_period == 0xFFFFFFFF) ?
+				0xFFFFFFFF : (ltrperiod->ltr_period + 1);
+			DDL_MSG_HIGH("%s: set ltr_period = %u", __func__,
+				encoder->ltr_control.ltr_period);
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	case VCD_I_LTR_USE:
+	{
+		if (sizeof(struct vcd_property_ltruse_type) ==
+			property_hdr->sz) {
+			struct vcd_property_ltruse_type *ltruse =
+				(struct vcd_property_ltruse_type *)
+				property_value;
+			if (ltruse->ltr_id >= DDL_LTR_FRAME_START_ID) {
+				struct ddl_ltr_encoding_type *ltr_ctrl =
+					&encoder->ltr_control;
+				s32 idx;
+				idx = ddl_find_ltr_from_list(ltr_ctrl,
+					ltruse->ltr_id);
+				if (idx < 0) {
+					ltr_ctrl->callback_reqd = true;
+					ltr_ctrl->failed_use_cmd.ltr_id =
+						ltruse->ltr_id;
+					ltr_ctrl->failed_use_cmd.ltr_frames =
+						ltruse->ltr_frames;
+					DDL_MSG_ERROR("%s: index (%d) "\
+					"not found. Callback requested. "\
+					"ltr_id = %u, ltr_frames = %u",
+					__func__, idx, ltruse->ltr_id,
+					ltruse->ltr_frames);
+				} else {
+					ddl_use_ltr_from_list(ltr_ctrl, idx);
+					ltr_ctrl->ltr_use_frames =
+						ltruse->ltr_frames;
+					if (ltr_ctrl->using == false)
+						ltr_ctrl->\
+						out_frame_cnt_to_use_this_ltr =
+							ltruse->ltr_frames;
+					else
+						ltr_ctrl->\
+						pending_chg_ltr_useframes =
+							true;
+					ltr_ctrl->first_ltr_use_arvd = true;
+					ltr_ctrl->use_ltr_reqd = true;
+					DDL_MSG_HIGH("%s: index (%d) found. "\
+					"num frames to use this ltr_id (%u) "\
+					"is %u", __func__, idx,
+					ltruse->ltr_id, ltruse->ltr_frames);
+				}
+				dynamic_prop_change = DDL_ENC_LTR_USE_FRAME;
+				vcd_status = VCD_S_SUCCESS;
+			} else {
+				DDL_MSG_ERROR("%s: LTRUse ID %d failed. "\
+					"LTR ID starts from %d", __func__,
+					ltruse->ltr_id,
+					(u32)DDL_LTR_FRAME_START_ID);
+				vcd_status = VCD_ERR_ILLEGAL_OP;
+			}
+		}
+	}
+	break;
 	default:
 		vcd_status = VCD_ERR_ILLEGAL_OP;
 		break;
@@ -1747,6 +2006,9 @@
 	encoder->num_references_for_p_frame = DDL_MIN_NUM_REF_FOR_P_FRAME;
 	if (encoder->codec.codec == VCD_CODEC_MPEG4)
 		encoder->closed_gop = true;
+	encoder->intra_period_changed = false;
+	memset(&encoder->ltr_control, 0,
+		sizeof(struct ddl_ltr_encoding_type));
 	ddl_set_default_metadata_flag(ddl);
 	ddl_set_default_encoder_buffer_req(encoder);
 	encoder->slice_delivery_info.enable = 0;
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
index de3fc4f..f5e81e1 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -87,6 +87,8 @@
 #define VIDC_SM_ENC_EXT_CTRL_TIMING_INFO_EN_SHFT     14
 #define VIDC_SM_ENC_EXT_CTRL_AU_DELIMITER_EN_BMSK    0x00000800
 #define VIDC_SM_ENC_EXT_CTRL_AU_DELIMITER_EN_SHFT    11
+#define VIDC_SM_ENC_EXT_CTRL_LONG_TERM_REF_ENABLE_BMSK      0x00000400
+#define VIDC_SM_ENC_EXT_CTRL_LONG_TERM_REF_ENABLE_SHFT      10
 #define VIDC_SM_ENC_EXT_CTRL_H263_CPCFC_ENABLE_BMSK  0x80
 #define VIDC_SM_ENC_EXT_CTRL_H263_CPCFC_ENABLE_SHFT  7
 #define VIDC_SM_ENC_EXT_CTRL_SPS_PPS_CONTROL_BMSK    0X100
@@ -458,8 +460,8 @@
 	enum VIDC_SM_frame_skip frame_skip_mode,
 	u32 seq_hdr_in_band, u32 vbv_buffer_size, u32 cpcfc_enable,
 	u32 sps_pps_control, u32 closed_gop_enable,
-	u32 au_delim_enable,
-	u32 vui_timing_info_enable)
+	u32 au_delim_enable, u32 vui_timing_info_enable,
+	u32 ltr_enable)
 {
 	u32 enc_ctrl;
 	enc_ctrl = VIDC_SETFIELD((hec_enable) ? 1 : 0,
@@ -488,8 +490,10 @@
 			VIDC_SM_ENC_EXT_CTRL_AU_DELIMITER_EN_BMSK) |
 			VIDC_SETFIELD((vui_timing_info_enable) ? 1 : 0,
 			VIDC_SM_ENC_EXT_CTRL_TIMING_INFO_EN_SHFT,
-			VIDC_SM_ENC_EXT_CTRL_TIMING_INFO_EN_BMSK);
-
+			VIDC_SM_ENC_EXT_CTRL_TIMING_INFO_EN_BMSK) |
+			VIDC_SETFIELD((ltr_enable) ? 1 : 0,
+			VIDC_SM_ENC_EXT_CTRL_LONG_TERM_REF_ENABLE_SHFT,
+			VIDC_SM_ENC_EXT_CTRL_LONG_TERM_REF_ENABLE_BMSK);
 	DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ENC_EXT_CTRL_ADDR, enc_ctrl);
 }
 
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
index 2eef99d..b7325a8 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -106,7 +106,8 @@
 	struct ddl_buf_addr *shared_mem, u32 hec_enable,
 	enum VIDC_SM_frame_skip  frame_skip_mode, u32 seq_hdr_in_band,
 	u32 vbv_buffer_size, u32 cpcfc_enable, u32 sps_pps_control,
-	u32 closed_gop_enable, u32 au_delim_enable, u32 vui_timing_info_enable);
+	u32 closed_gop_enable, u32 au_delim_enable, u32 vui_timing_info_enable,
+	u32 ltr_enable);
 void vidc_sm_set_encoder_param_change(struct ddl_buf_addr *shared_mem,
 	u32 bit_rate_chg, u32 frame_rate_chg, u32 i_period_chg);
 void vidc_sm_set_encoder_vop_time(struct ddl_buf_addr *shared_mem,
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
index 4b5fbf5..61099b0 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h
index 4963874..1792510 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -34,7 +34,7 @@
 		printk(KERN_DEBUG x); \
 } while (0)
 
-#ifdef DDL_MSG_LOG
+#if DDL_MSG_LOG
 #define DDL_MSG_LOW(x...)    printk(KERN_INFO x)
 #define DDL_MSG_MED(x...)    printk(KERN_INFO x)
 #define DDL_MSG_HIGH(x...)   printk(KERN_INFO x)
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
index 1bf242d..52ad4aa 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -331,7 +331,7 @@
 {
 	struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder);
 	u32 frame_rate_change = false, bit_rate_change = false;
-	u32 i_period_change = false, reset_req = false;
+	u32 reset_req = false;
 
 	if (!enable) {
 		if (encoder->dynmic_prop_change_req) {
@@ -344,6 +344,17 @@
 			encoder->dynamic_prop_change &=
 				~(DDL_ENC_REQ_IFRAME);
 		}
+		if (encoder->dynamic_prop_change & DDL_ENC_LTR_USE_FRAME) {
+			if (encoder->ltr_control.callback_reqd) {
+				DDL_MSG_ERROR("%s: LTR use failed", __func__);
+				ddl_encoder_use_ltr_fail_callback(ddl);
+				encoder->ltr_control.callback_reqd = false;
+			} else {
+				encoder->ltr_control.use_ltr_reqd = true;
+			}
+			encoder->dynamic_prop_change &=
+				~(DDL_ENC_LTR_USE_FRAME);
+		}
 		if ((encoder->dynamic_prop_change &
 			DDL_ENC_CHANGE_BITRATE)) {
 			bit_rate_change = true;
@@ -355,7 +366,7 @@
 		}
 		if ((encoder->dynamic_prop_change
 			& DDL_ENC_CHANGE_IPERIOD)) {
-			i_period_change = true;
+			encoder->intra_period_changed = true;
 			vidc_sm_set_encoder_new_i_period(
 				&ddl->shared_mem[ddl->command_channel],
 				encoder->i_period.p_frames);
@@ -387,7 +398,7 @@
 		vidc_sm_set_encoder_param_change(
 			&ddl->shared_mem[ddl->command_channel],
 			bit_rate_change, frame_rate_change,
-			i_period_change);
+			encoder->intra_period_changed);
 	}
 }
 
@@ -580,7 +591,7 @@
 	u32 index, luma[4], chroma[4], hdr_ext_control = false;
 	const u32 recon_bufs = 4;
 	u32 h263_cpfc_enable = false;
-	u32 scaled_frame_rate;
+	u32 scaled_frame_rate, ltr_enable;
 
 	ddl_vidc_encode_set_profile_level(ddl);
 	vidc_1080p_set_encode_frame_size(encoder->frame_size.width,
@@ -601,12 +612,14 @@
 		(DDL_FRAMERATE_SCALE(DDL_INITIAL_FRAME_RATE)
 		 != scaled_frame_rate) && encoder->plusptype_enable)
 		h263_cpfc_enable = true;
+	ltr_enable = DDL_IS_LTR_ENABLED(encoder);
+	DDL_MSG_HIGH("ltr_enable = %u", ltr_enable);
 	vidc_sm_set_extended_encoder_control(&ddl->shared_mem
 		[ddl->command_channel], hdr_ext_control,
 		r_cframe_skip, false, 0,
 		h263_cpfc_enable, encoder->sps_pps.sps_pps_for_idr_enable_flag,
 		encoder->closed_gop, encoder->avc_delimiter_enable,
-		encoder->vui_timinginfo_enable);
+		encoder->vui_timinginfo_enable, ltr_enable);
 	if (encoder->vui_timinginfo_enable) {
 		vidc_sm_set_h264_encoder_timing_info(
 			&ddl->shared_mem[ddl->command_channel],
@@ -809,7 +822,8 @@
 		encoder->dynmic_prop_change_req = true;
 		ddl_vidc_encode_dynamic_property(ddl, true);
 	}
-
+	if (DDL_IS_LTR_ENABLED(encoder))
+		ddl_encoder_ltr_control(ddl);
 	vidc_1080p_set_encode_circular_intra_refresh(
 		encoder->intra_refresh.cir_mb_number);
 	ddl_vidc_encode_set_multi_slice_info(encoder);
@@ -824,13 +838,21 @@
 	ddl_context->dram_base_a.align_physical_addr, stream->physical);
 	enc_param.stream_buffer_size =
 		encoder->client_output_buf_req.sz;
-
 	enc_param.intra_frame = encoder->intra_frame_insertion;
-	if (encoder->intra_frame_insertion)
-		encoder->intra_frame_insertion = false;
 	enc_param.input_flush = false;
 	enc_param.slice_enable = false;
-		vidc_sm_set_encoder_vop_time(
+	enc_param.store_ltr0 = encoder->ltr_control.store_ltr0;
+	enc_param.store_ltr1 = encoder->ltr_control.store_ltr1;
+	enc_param.use_ltr0 = encoder->ltr_control.use_ltr0;
+	enc_param.use_ltr1 = encoder->ltr_control.use_ltr1;
+
+	encoder->intra_frame_insertion = false;
+	encoder->intra_period_changed = false;
+	encoder->ltr_control.store_ltr0 = false;
+	encoder->ltr_control.store_ltr1 = false;
+	encoder->ltr_control.use_ltr0 = false;
+	encoder->ltr_control.use_ltr1 = false;
+	vidc_sm_set_encoder_vop_time(
 			&ddl->shared_mem[ddl->command_channel], true,
 			encoder->vop_timing.vop_time_resolution,
 			ddl->input_frame.frm_delta);
diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc.c b/drivers/video/msm/vidc/1080p/ddl/vidc.c
index 3c445bc..c60175a 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vidc.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vidc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -83,6 +83,17 @@
 #define VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_SHFT      31
 #define VIDC_1080P_MAX_INTRA_PERIOD 0xffff
 
+#define VIDC_1080P_COMMON_CHX_RG6_I_FRAME_BMASK              0x00000001
+#define VIDC_1080P_COMMON_CHX_RG6_I_FRAME_SHIFT              0
+#define VIDC_1080P_COMMON_CHX_RG6_STORE_LTR0_BMASK           0x00000008
+#define VIDC_1080P_COMMON_CHX_RG6_STORE_LTR0_SHIFT           3
+#define VIDC_1080P_COMMON_CHX_RG6_STORE_LTR1_BMASK           0x00000010
+#define VIDC_1080P_COMMON_CHX_RG6_STORE_LTR1_SHIFT           4
+#define VIDC_1080P_COMMON_CHX_RG6_USE_LTR0_BMASK             0x00000020
+#define VIDC_1080P_COMMON_CHX_RG6_USE_LTR0_SHIFT             5
+#define VIDC_1080P_COMMON_CHX_RG6_USE_LTR1_BMASK             0x00000040
+#define VIDC_1080P_COMMON_CHX_RG6_USE_LTR1_SHIFT             6
+
 u8 *VIDC_BASE_PTR;
 
 void vidc_1080p_do_sw_reset(enum vidc_1080p_reset init_flag)
@@ -787,7 +798,9 @@
 void vidc_1080p_encode_frame_start_ch0(
 	struct vidc_1080p_enc_frame_start_param *param)
 {
-	u32 input_flush;
+	u32 input_flush = 0;
+	u32 frame_insertion = 0;
+
 	VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY);
 	VIDC_HWIO_OUT(REG_666957, VIDC_1080P_INIT_CH_INST_ID);
 	VIDC_HWIO_OUT(REG_117192,
@@ -798,7 +811,22 @@
 		VIDC_1080P_BASE_OFFSET_SHIFT);
 	VIDC_HWIO_OUT(REG_175608, param->current_c_addr_offset >>
 		VIDC_1080P_BASE_OFFSET_SHIFT);
-	VIDC_HWIO_OUT(REG_190381, param->intra_frame);
+	frame_insertion = VIDC_SETFIELD(param->intra_frame,
+			VIDC_1080P_COMMON_CHX_RG6_I_FRAME_SHIFT,
+			VIDC_1080P_COMMON_CHX_RG6_I_FRAME_BMASK);
+	frame_insertion |= VIDC_SETFIELD(param->store_ltr0,
+			VIDC_1080P_COMMON_CHX_RG6_STORE_LTR0_SHIFT,
+			VIDC_1080P_COMMON_CHX_RG6_STORE_LTR0_BMASK);
+	frame_insertion |= VIDC_SETFIELD(param->store_ltr1,
+			VIDC_1080P_COMMON_CHX_RG6_STORE_LTR1_SHIFT,
+			VIDC_1080P_COMMON_CHX_RG6_STORE_LTR1_BMASK);
+	frame_insertion |= VIDC_SETFIELD(param->use_ltr0,
+			VIDC_1080P_COMMON_CHX_RG6_USE_LTR0_SHIFT,
+			VIDC_1080P_COMMON_CHX_RG6_USE_LTR0_BMASK);
+	frame_insertion |= VIDC_SETFIELD(param->use_ltr1,
+			VIDC_1080P_COMMON_CHX_RG6_USE_LTR1_SHIFT,
+			VIDC_1080P_COMMON_CHX_RG6_USE_LTR1_BMASK);
+	VIDC_HWIO_OUT(REG_190381, frame_insertion);
 	VIDC_HWIO_OUT(REG_889944, param->shared_mem_addr_offset);
 	input_flush = VIDC_SETFIELD(param->input_flush,
 			VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_SHFT,
@@ -816,7 +844,9 @@
 void vidc_1080p_encode_frame_start_ch1(
 	struct vidc_1080p_enc_frame_start_param *param)
 {
-	u32 input_flush;
+	u32 input_flush = 0;
+	u32 frame_insertion = 0;
+
 	VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY);
 	VIDC_HWIO_OUT(REG_313350, VIDC_1080P_INIT_CH_INST_ID);
 	VIDC_HWIO_OUT(REG_980194,
@@ -827,7 +857,22 @@
 		VIDC_1080P_BASE_OFFSET_SHIFT);
 	VIDC_HWIO_OUT(REG_548308,  param->current_c_addr_offset >>
 		VIDC_1080P_BASE_OFFSET_SHIFT);
-	VIDC_HWIO_OUT(REG_887095, param->intra_frame);
+	frame_insertion = VIDC_SETFIELD(param->intra_frame,
+			VIDC_1080P_COMMON_CHX_RG6_I_FRAME_SHIFT,
+			VIDC_1080P_COMMON_CHX_RG6_I_FRAME_BMASK);
+	frame_insertion |= VIDC_SETFIELD(param->store_ltr0,
+			VIDC_1080P_COMMON_CHX_RG6_STORE_LTR0_SHIFT,
+			VIDC_1080P_COMMON_CHX_RG6_STORE_LTR0_BMASK);
+	frame_insertion |= VIDC_SETFIELD(param->store_ltr1,
+			VIDC_1080P_COMMON_CHX_RG6_STORE_LTR1_SHIFT,
+			VIDC_1080P_COMMON_CHX_RG6_STORE_LTR1_BMASK);
+	frame_insertion |= VIDC_SETFIELD(param->use_ltr0,
+			VIDC_1080P_COMMON_CHX_RG6_USE_LTR0_SHIFT,
+			VIDC_1080P_COMMON_CHX_RG6_USE_LTR0_BMASK);
+	frame_insertion |= VIDC_SETFIELD(param->use_ltr1,
+			VIDC_1080P_COMMON_CHX_RG6_USE_LTR1_SHIFT,
+			VIDC_1080P_COMMON_CHX_RG6_USE_LTR1_BMASK);
+	VIDC_HWIO_OUT(REG_887095, frame_insertion);
 	VIDC_HWIO_OUT(REG_652528, param->shared_mem_addr_offset);
 	input_flush = VIDC_SETFIELD(param->input_flush,
 			VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_SHFT,
diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc.h b/drivers/video/msm/vidc/1080p/ddl/vidc.h
index 117612b..0d83dd9 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vidc.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vidc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -400,6 +400,10 @@
 	u32 intra_frame;
 	u32 input_flush;
 	u32 slice_enable;
+	u32 store_ltr0;
+	u32 store_ltr1;
+	u32 use_ltr0;
+	u32 use_ltr1;
 	enum vidc_1080p_encode encode;
 };
 struct vidc_1080p_enc_frame_info{
diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc_hwio.h b/drivers/video/msm/vidc/1080p/ddl/vidc_hwio.h
index a5a8e57..d63a45b 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vidc_hwio.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vidc_hwio.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc_hwio_reg.h b/drivers/video/msm/vidc/1080p/ddl/vidc_hwio_reg.h
index 819cd6c..0de06bf 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vidc_hwio_reg.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vidc_hwio_reg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.c b/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.c
index 6870525..de294fd 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.h b/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.h
index e8a93a1..c70b113 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
index d9cadef..c15218d 100644
--- a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -160,9 +160,13 @@
 static void res_trk_pmem_free(struct ddl_buf_addr *addr)
 {
 	struct ddl_context *ddl_context;
+
+	if (!addr)
+		return;
+
 	ddl_context = ddl_get_context();
 	if (ddl_context->video_ion_client) {
-		if (addr && addr->alloc_handle) {
+		if (addr->alloc_handle) {
 			ion_free(ddl_context->video_ion_client,
 			 addr->alloc_handle);
 			addr->alloc_handle = NULL;
diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h
index a980230..6cb9fe7 100644
--- a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h
index ee876f4..2c47921 100644
--- a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.c
index a144e06..9b27abd 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h
index e6d3527..7a79a40 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012 Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_api.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_api.h
index 53cc93e..3796e8f 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_api.h
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_api.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_core.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_core.h
index 9fdb668..78b05ec 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_core.h
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_core.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c
index 91136f3..6e43a7c 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.c
index 965c3aa..23948d4 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.h
index a136de8..ba8dbcb 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.h
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c
index 6a69955..4cbd984 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c
index 15adf21..b97fae6 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_internal_property.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_internal_property.h
index 7e201cf..32a4047 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_internal_property.h
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_internal_property.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_interrupt_handler.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_interrupt_handler.c
index fe71dc1..817a98e 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_interrupt_handler.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_interrupt_handler.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.c
index 2a74da8..5d87533 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.h
index ed43861..7c9ac95 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.h
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c
index 3aebdaf..cdb6313 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c
index 9fb8162..672c049 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.h
index 59bb620..633292b 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.h
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/720p/ddl/vidc.c b/drivers/video/msm/vidc/720p/ddl/vidc.c
index de6cbbb..da969ef 100644
--- a/drivers/video/msm/vidc/720p/ddl/vidc.c
+++ b/drivers/video/msm/vidc/720p/ddl/vidc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/720p/ddl/vidc.h b/drivers/video/msm/vidc/720p/ddl/vidc.h
index 509482b..a09034f 100644
--- a/drivers/video/msm/vidc/720p/ddl/vidc.h
+++ b/drivers/video/msm/vidc/720p/ddl/vidc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c
index c83faa6..a67dc1c 100644
--- a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c
+++ b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h
index 5f126fd..e1781b6 100644
--- a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h
+++ b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h
index a20d9f2..537f3c8 100644
--- a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h
+++ b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
index 59e19b7..afc5130 100644
--- a/drivers/video/msm/vidc/common/dec/vdec.c
+++ b/drivers/video/msm/vidc/common/dec/vdec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -271,6 +271,38 @@
 				      &phy_addr, &pmem_fd, &file,
 				      &buffer_index) ||
 		(vcd_frame_data->flags & VCD_FRAME_FLAG_EOS)) {
+
+		if (res_trk_check_for_sec_session() &&
+				event == VCD_EVT_RESP_OUTPUT_DONE) {
+			DBG("Buffer Index = %d", buffer_index);
+			if (buffer_index != -1) {
+				if (client_ctx->meta_addr_table[buffer_index].
+					kernel_vir_addr_iommu &&
+					client_ctx->
+					meta_addr_table[buffer_index].
+					kernel_vir_addr) {
+
+					memcpy(client_ctx->
+						meta_addr_table[buffer_index].
+						kernel_vir_addr_iommu,
+						client_ctx->
+						meta_addr_table[buffer_index].
+						kernel_vir_addr,
+						client_ctx->meta_buf_size);
+					DBG("Copying Meta Buffer from "\
+						"secure memory"
+						"kernel_virt_iommu = %p "
+						"kernel_virt = %p",
+						client_ctx->
+						meta_addr_table[buffer_index].
+						kernel_vir_addr_iommu,
+						client_ctx->
+						meta_addr_table[buffer_index].
+						kernel_vir_addr);
+				}
+			}
+		}
+
 		/* Buffer address in user space */
 		vdec_msg->vdec_msg_info.msgdata.output_frame.bufferaddr =
 		    (u8 *) user_vaddr;
@@ -838,7 +870,263 @@
 		return false;
 	return true;
 }
+static u32 vid_dec_set_meta_buffers(struct video_client_ctx *client_ctx,
+					struct vdec_meta_buffers *meta_buffers)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_meta_buffer *vcd_meta_buffer = NULL;
+	struct msm_mapped_buffer *mapped_buffer = NULL;
+	struct msm_mapped_buffer *mapped_buffer_iommu = NULL;
+	u32 vcd_status = VCD_ERR_FAIL;
+	u32 len = 0, flags = 0, len_iommu = 0, flags_iommu = 0, buf_size = 0;
+	struct file *file, *file_iommu;
+	int rc = 0;
+	unsigned long ionflag = 0, ionflag_iommu = 0;
+	unsigned long buffer_size = 0, buffer_size_iommu = 0;
+	unsigned long iova = 0, iova_iommu = 0;
+	int index = -1, num_buffers = 0;
+	u8 *ker_vir_addr = NULL, *ker_vir_addr_iommu = NULL;
 
+	if (!client_ctx || !meta_buffers)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_SET_EXT_METABUFFER;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_meta_buffer);
+	vcd_meta_buffer = &client_ctx->vcd_meta_buffer;
+
+	memset(&client_ctx->vcd_meta_buffer, 0,
+		   sizeof(struct vcd_property_meta_buffer));
+	vcd_meta_buffer->size = meta_buffers->size;
+	vcd_meta_buffer->count = meta_buffers->count;
+	vcd_meta_buffer->pmem_fd = meta_buffers->pmem_fd;
+	vcd_meta_buffer->offset = meta_buffers->offset;
+	vcd_meta_buffer->pmem_fd_iommu = meta_buffers->pmem_fd_iommu;
+
+	if (!vcd_get_ion_status()) {
+		if (get_pmem_file(vcd_meta_buffer->pmem_fd,
+				(unsigned long *) (&(vcd_meta_buffer->
+				physical_addr)),
+				(unsigned long *) (&vcd_meta_buffer->
+							kernel_virtual_addr),
+				(unsigned long *) (&len), &file)) {
+				ERR("%s(): get_pmem_file failed\n", __func__);
+				return false;
+			}
+		put_pmem_file(file);
+		flags = MSM_SUBSYSTEM_MAP_IOVA;
+		mapped_buffer = msm_subsystem_map_buffer(
+			(unsigned long)vcd_meta_buffer->physical_addr,
+				len, flags, vidc_mmu_subsystem,
+				sizeof(vidc_mmu_subsystem)/
+				sizeof(unsigned int));
+		if (IS_ERR(mapped_buffer)) {
+			pr_err("buffer map failed");
+			return false;
+		}
+		vcd_meta_buffer->client_data = (void *) mapped_buffer;
+		vcd_meta_buffer->dev_addr =
+			(u8 *)mapped_buffer->iova[0];
+
+		if (get_pmem_file(vcd_meta_buffer->pmem_fd_iommu,
+				(unsigned long *) (&(vcd_meta_buffer->
+				physical_addr_iommu)),
+				(unsigned long *) (&vcd_meta_buffer->
+				kernel_virt_addr_iommu),
+				(unsigned long *) (&len_iommu), &file_iommu)) {
+				ERR("%s(): get_pmem_file failed\n", __func__);
+				return false;
+			}
+		put_pmem_file(file_iommu);
+		flags_iommu = MSM_SUBSYSTEM_MAP_IOVA;
+		mapped_buffer_iommu = msm_subsystem_map_buffer(
+			(unsigned long)vcd_meta_buffer->physical_addr_iommu,
+				len_iommu, flags_iommu, vidc_mmu_subsystem,
+				sizeof(vidc_mmu_subsystem)/
+				sizeof(unsigned int));
+		if (IS_ERR(mapped_buffer_iommu)) {
+			pr_err("buffer map failed");
+			return false;
+		}
+		vcd_meta_buffer->client_data_iommu =
+					(void *) mapped_buffer_iommu;
+		vcd_meta_buffer->dev_addr_iommu =
+					(u8 *)mapped_buffer_iommu->iova[0];
+	} else {
+		client_ctx->meta_buffer_ion_handle = ion_import_dma_buf(
+					client_ctx->user_ion_client,
+					vcd_meta_buffer->pmem_fd);
+		if (IS_ERR_OR_NULL(client_ctx->meta_buffer_ion_handle)) {
+			ERR("%s(): get_ION_handle failed\n", __func__);
+			goto import_ion_error;
+		}
+		rc = ion_handle_get_flags(client_ctx->user_ion_client,
+					client_ctx->meta_buffer_ion_handle,
+					&ionflag);
+		if (rc) {
+			ERR("%s():get_ION_flags fail\n",
+					 __func__);
+			goto import_ion_error;
+		}
+		vcd_meta_buffer->kernel_virtual_addr =
+			(u8 *) ion_map_kernel(
+			client_ctx->user_ion_client,
+			client_ctx->meta_buffer_ion_handle);
+		if (!vcd_meta_buffer->kernel_virtual_addr) {
+			ERR("%s(): get_ION_kernel virtual addr failed\n",
+				 __func__);
+			goto import_ion_error;
+		}
+		if (res_trk_check_for_sec_session() ||
+		   (res_trk_get_core_type() == (u32)VCD_CORE_720P)) {
+			rc = ion_phys(client_ctx->user_ion_client,
+				client_ctx->meta_buffer_ion_handle,
+				(unsigned long *) (&(vcd_meta_buffer->
+				physical_addr)), &len);
+			if (rc) {
+				ERR("%s():get_ION_kernel physical addr fail\n",
+					__func__);
+				goto ion_map_error;
+			}
+			vcd_meta_buffer->client_data = NULL;
+			vcd_meta_buffer->dev_addr = (u8 *)
+				vcd_meta_buffer->physical_addr;
+		} else {
+			rc = ion_map_iommu(client_ctx->user_ion_client,
+				client_ctx->meta_buffer_ion_handle,
+				VIDEO_DOMAIN, VIDEO_MAIN_POOL,
+				SZ_4K, 0, (unsigned long *)&iova,
+				(unsigned long *)&buffer_size,
+				0, 0);
+			if (rc || !iova) {
+				ERR("%s():get_ION_kernel physical addr fail,"\
+					" rc = %d iova = 0x%lx\n",
+					__func__, rc, iova);
+				goto ion_map_error;
+			}
+			vcd_meta_buffer->physical_addr = (u8 *) iova;
+			vcd_meta_buffer->client_data = NULL;
+			vcd_meta_buffer->dev_addr = (u8 *) iova;
+		}
+
+		client_ctx->meta_buffer_iommu_ion_handle = ion_import_dma_buf(
+					client_ctx->user_ion_client,
+					vcd_meta_buffer->pmem_fd_iommu);
+		if (IS_ERR_OR_NULL(client_ctx->meta_buffer_iommu_ion_handle)) {
+			ERR("%s(): get_ION_handle failed\n", __func__);
+			goto import_ion_error;
+		}
+		rc = ion_handle_get_flags(client_ctx->user_ion_client,
+					client_ctx->
+					meta_buffer_iommu_ion_handle,
+					&ionflag_iommu);
+		if (rc) {
+			ERR("%s():get_ION_flags fail\n",
+					 __func__);
+			goto import_ion_error;
+		}
+		vcd_meta_buffer->kernel_virt_addr_iommu =
+			(u8 *) ion_map_kernel(
+			client_ctx->user_ion_client,
+			client_ctx->meta_buffer_iommu_ion_handle);
+		if (!vcd_meta_buffer->kernel_virt_addr_iommu) {
+			ERR("%s(): get_ION_kernel virtual addr failed\n",
+				 __func__);
+			goto import_ion_error;
+		}
+		if (res_trk_get_core_type() == (u32)VCD_CORE_720P) {
+			rc = ion_phys(client_ctx->user_ion_client,
+				client_ctx->meta_buffer_iommu_ion_handle,
+				(unsigned long *) (&(vcd_meta_buffer->
+				physical_addr_iommu)), &len_iommu);
+			if (rc) {
+				ERR("%s():get_ION_kernel physical addr fail\n",
+					__func__);
+				goto ion_map_error_iommu;
+			}
+			vcd_meta_buffer->client_data_iommu = NULL;
+			vcd_meta_buffer->dev_addr_iommu = (u8 *)
+				vcd_meta_buffer->physical_addr_iommu;
+		} else {
+			rc = ion_map_iommu(client_ctx->user_ion_client,
+				client_ctx->meta_buffer_iommu_ion_handle,
+				VIDEO_DOMAIN, VIDEO_MAIN_POOL,
+				SZ_4K, 0, (unsigned long *)&iova_iommu,
+				(unsigned long *)&buffer_size_iommu,
+				0, 0);
+			if (rc || !iova_iommu) {
+				ERR("%s():get_ION_kernel physical addr fail, "\
+					"rc = %d iova = 0x%lx\n",
+					__func__, rc, iova);
+				goto ion_map_error_iommu;
+			}
+			vcd_meta_buffer->physical_addr_iommu =
+						(u8 *) iova_iommu;
+			vcd_meta_buffer->client_data_iommu = NULL;
+			vcd_meta_buffer->dev_addr_iommu = (u8 *) iova_iommu;
+		}
+	}
+
+	/*fill the meta addr table*/
+	num_buffers = vcd_meta_buffer->count;
+	buf_size = vcd_meta_buffer->size/num_buffers;
+	ker_vir_addr = vcd_meta_buffer->kernel_virtual_addr;
+	ker_vir_addr_iommu = vcd_meta_buffer->kernel_virt_addr_iommu;
+	client_ctx->meta_buf_size = buf_size;
+	for (index = 0; index < num_buffers; index++) {
+		client_ctx->meta_addr_table[index].kernel_vir_addr =
+			ker_vir_addr;
+		client_ctx->meta_addr_table[index].kernel_vir_addr_iommu =
+			ker_vir_addr_iommu;
+		DBG("[%d] kernel_virtual = %p kernel_vir_iommu = %p",
+			index, ker_vir_addr, ker_vir_addr_iommu);
+		ker_vir_addr += buf_size;
+		ker_vir_addr_iommu += buf_size;
+	}
+
+	DBG("Meta Buffer: Virt: %p, Phys %p, fd: %d",
+			vcd_meta_buffer->kernel_virtual_addr,
+			vcd_meta_buffer->physical_addr,
+			vcd_meta_buffer->pmem_fd);
+	DBG("IOMMU Meta Buffer: Virt: %p, Phys %p, fd: %d",
+			vcd_meta_buffer->kernel_virt_addr_iommu,
+			vcd_meta_buffer->physical_addr_iommu,
+			vcd_meta_buffer->pmem_fd_iommu);
+	DBG("Meta_buffer: Dev addr %p", vcd_meta_buffer->dev_addr);
+	DBG("IOMMU Meta_buffer: Dev addr %p",
+			vcd_meta_buffer->dev_addr_iommu);
+	vcd_status = vcd_set_property(client_ctx->vcd_handle,
+					  &vcd_property_hdr,
+					  vcd_meta_buffer);
+
+	if (vcd_status)
+		return false;
+	else
+		return true;
+ion_map_error_iommu:
+	if (vcd_meta_buffer->kernel_virt_addr_iommu) {
+		ion_unmap_kernel(client_ctx->user_ion_client,
+				client_ctx->meta_buffer_iommu_ion_handle);
+		vcd_meta_buffer->kernel_virt_addr_iommu = NULL;
+	}
+	if (!IS_ERR_OR_NULL(client_ctx->meta_buffer_iommu_ion_handle)) {
+		ion_free(client_ctx->user_ion_client,
+			client_ctx->meta_buffer_iommu_ion_handle);
+		 client_ctx->meta_buffer_iommu_ion_handle = NULL;
+	}
+ion_map_error:
+	if (vcd_meta_buffer->kernel_virtual_addr) {
+		ion_unmap_kernel(client_ctx->user_ion_client,
+				client_ctx->meta_buffer_ion_handle);
+		vcd_meta_buffer->kernel_virtual_addr = NULL;
+	}
+	if (!IS_ERR_OR_NULL(client_ctx->meta_buffer_ion_handle)) {
+		ion_free(client_ctx->user_ion_client,
+			client_ctx->meta_buffer_ion_handle);
+		 client_ctx->meta_buffer_ion_handle = NULL;
+	}
+import_ion_error:
+	return false;
+}
 static u32 vid_dec_set_h264_mv_buffers(struct video_client_ctx *client_ctx,
 					struct vdec_h264_mv *mv_data)
 {
@@ -1018,6 +1306,65 @@
 		return true;
 }
 
+static u32 vid_dec_free_meta_buffers(struct video_client_ctx *client_ctx)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_buffer_size meta_buffer_size;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx)
+		return false;
+	if (client_ctx->vcd_meta_buffer.client_data)
+		msm_subsystem_unmap_buffer((struct msm_mapped_buffer *)
+		client_ctx->vcd_meta_buffer.client_data);
+
+	if (client_ctx->vcd_meta_buffer.client_data_iommu)
+		msm_subsystem_unmap_buffer((struct msm_mapped_buffer *)
+		client_ctx->vcd_meta_buffer.client_data_iommu);
+
+	vcd_property_hdr.prop_id = VCD_I_FREE_EXT_METABUFFER;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size);
+
+	vcd_status = vcd_set_property(client_ctx->vcd_handle,
+				      &vcd_property_hdr, &meta_buffer_size);
+
+	if (!IS_ERR_OR_NULL(client_ctx->meta_buffer_ion_handle)) {
+		ion_unmap_kernel(client_ctx->user_ion_client,
+					client_ctx->meta_buffer_ion_handle);
+		if (!res_trk_check_for_sec_session() &&
+		   (res_trk_get_core_type() != (u32)VCD_CORE_720P)) {
+			ion_unmap_iommu(client_ctx->user_ion_client,
+				client_ctx->meta_buffer_ion_handle,
+				VIDEO_DOMAIN,
+				VIDEO_MAIN_POOL);
+		}
+		ion_free(client_ctx->user_ion_client,
+					client_ctx->meta_buffer_ion_handle);
+		client_ctx->meta_buffer_ion_handle = NULL;
+	}
+
+	if (!IS_ERR_OR_NULL(client_ctx->meta_buffer_iommu_ion_handle)) {
+		ion_unmap_kernel(client_ctx->user_ion_client,
+			client_ctx->meta_buffer_iommu_ion_handle);
+		if (res_trk_check_for_sec_session() &&
+		   (res_trk_get_core_type() != (u32)VCD_CORE_720P)) {
+			ion_unmap_iommu(client_ctx->user_ion_client,
+				client_ctx->meta_buffer_iommu_ion_handle,
+				VIDEO_DOMAIN,
+				VIDEO_MAIN_POOL);
+		}
+		ion_free(client_ctx->user_ion_client,
+				client_ctx->meta_buffer_iommu_ion_handle);
+		client_ctx->meta_buffer_iommu_ion_handle = NULL;
+	}
+
+	if (vcd_status)
+		return false;
+	else
+		return true;
+}
+
+
 static u32 vid_dec_free_h264_mv_buffers(struct video_client_ctx *client_ctx)
 {
 	struct vcd_property_hdr vcd_property_hdr;
@@ -1085,6 +1432,7 @@
 		vdec_buf_req->buffer_size = vcd_buf_req.sz;
 		vdec_buf_req->alignment = vcd_buf_req.align;
 		vdec_buf_req->buf_poolid = vcd_buf_req.buf_pool_id;
+		vdec_buf_req->meta_buffer_size = vcd_buf_req.meta_buffer_size;
 
 		return true;
 	}
@@ -1977,6 +2325,29 @@
 			return -EIO;
 		break;
 	}
+	case VDEC_IOCTL_SET_META_BUFFERS:
+	{
+		struct vdec_meta_buffers meta_buffers;
+		DBG("VDEC_IOCTL_SET_META_BUFFERS\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&meta_buffers, vdec_msg.in,
+						   sizeof(meta_buffers)))
+			return -EFAULT;
+		result = vid_dec_set_meta_buffers(client_ctx, &meta_buffers);
+
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_FREE_META_BUFFERS:
+	{
+		DBG("VDEC_IOCTL_FREE_META_BUFFERS\n");
+		result = vid_dec_free_meta_buffers(client_ctx);
+		if (!result)
+			return -EIO;
+		break;
+	}
 	case VDEC_IOCTL_SET_H264_MV_BUFFER:
 	{
 		struct vdec_h264_mv mv_data;
@@ -2114,7 +2485,7 @@
 	}
 
 	client_index = vid_dec_get_empty_client_index();
-	if (client_index == -1) {
+	if (client_index < 0) {
 		ERR("%s() : No free clients client_index == -1\n", __func__);
 		rc = -ENOMEM;
 		goto client_failure;
diff --git a/drivers/video/msm/vidc/common/dec/vdec_internal.h b/drivers/video/msm/vidc/common/dec/vdec_internal.h
index 89da9a2..a7a32a5 100644
--- a/drivers/video/msm/vidc/common/dec/vdec_internal.h
+++ b/drivers/video/msm/vidc/common/dec/vdec_internal.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c
index 763fbda..aa17f84 100644
--- a/drivers/video/msm/vidc/common/enc/venc.c
+++ b/drivers/video/msm/vidc/common/enc/venc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. 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
@@ -35,6 +35,7 @@
 #include "vcd_res_tracker_api.h"
 
 #define VID_ENC_NAME	"msm_vidc_enc"
+static char *node_name[2] = {"", "_sec"};
 
 #if DEBUG
 #define DBG(x...) printk(KERN_DEBUG x)
@@ -50,7 +51,6 @@
 static struct class *vid_enc_class;
 static long vid_enc_ioctl(struct file *file,
 	unsigned cmd, unsigned long arg);
-static int stop_cmd;
 
 static s32 vid_enc_get_empty_client_index(void)
 {
@@ -218,15 +218,15 @@
 
 	switch (event) {
 	case VCD_EVT_RESP_OUTPUT_DONE:
-	   DBG("Send INPUT_DON message to client = %p\n",
+	   DBG("Send OUTPUT_DON message to client = %p\n",
 			client_ctx);
 	   break;
 	case VCD_EVT_RESP_OUTPUT_FLUSHED:
-	   DBG("Send INPUT_FLUSHED message to client = %p\n",
+	   DBG("Send OUTPUT_FLUSHED message to client = %p\n",
 		   client_ctx);
 	   break;
 	default:
-	   ERR("QVD: vid_enc_output_frame_done invalid cmd type: %d\n", event);
+	   ERR("vid_enc_output_frame_done: invalid cmd type: %d\n", event);
 	   venc_msg->venc_msg_info.statuscode = VEN_S_EFATAL;
 	   break;
 	}
@@ -336,6 +336,12 @@
 		venc_msg->venc_msg_info.msgcode =
 			VEN_MSG_PAUSE;
 		break;
+	case VCD_EVT_IND_INFO_LTRUSE_FAILED:
+		INFO("\n msm_vidc_enc: Sending VEN_MSG_LTRUSE_FAILED"\
+			 " to client");
+		venc_msg->venc_msg_info.msgcode =
+			VEN_MSG_LTRUSE_FAILED;
+		break;
 
 	default:
 		ERR("%s() : unknown event type %u\n",
@@ -394,6 +400,7 @@
 	case VCD_EVT_IND_OUTPUT_RECONFIG:
 	case VCD_EVT_IND_HWERRFATAL:
 	case VCD_EVT_IND_RESOURCES_LOST:
+	case VCD_EVT_IND_INFO_LTRUSE_FAILED:
 		vid_enc_lean_event(client_ctx, event, status);
 		break;
 
@@ -476,7 +483,7 @@
 
 	mutex_lock(&vid_enc_device_p->lock);
 
-	if (!stop_cmd) {
+	if (!client_ctx->stop_called) {
 		vcd_status = vcd_stop(client_ctx->vcd_handle);
 		DBG("Waiting for VCD_STOP: Before Timeout\n");
 		if (!vcd_status) {
@@ -513,13 +520,13 @@
 		sizeof(struct video_client_ctx));
 
 	vid_enc_device_p->num_clients--;
-	stop_cmd = 0;
+	client_ctx->stop_called = 0;
 	mutex_unlock(&vid_enc_device_p->lock);
 	return true;
 }
 
-
-static int vid_enc_open(struct inode *inode, struct file *file)
+static int vid_enc_open_client(struct video_client_ctx **vid_clnt_ctx,
+							   int flags)
 {
 	s32 client_index;
 	struct video_client_ctx *client_ctx;
@@ -527,30 +534,34 @@
 	u8 client_count = 0;
 
 	INFO("\n msm_vidc_enc: Inside %s()", __func__);
-
-	mutex_lock(&vid_enc_device_p->lock);
-
-	stop_cmd = 0;
+	if (!vid_clnt_ctx) {
+		ERR("Invalid input\n");
+		rc = -EINVAL;
+		goto client_failure;
+	}
+	*vid_clnt_ctx = NULL;
 	client_count = vcd_get_num_of_clients();
 	if (client_count == VIDC_MAX_NUM_CLIENTS) {
-		ERR("ERROR : vid_enc_open() max number of clients"
-		    "limit reached\n");
-		mutex_unlock(&vid_enc_device_p->lock);
-		return -ENODEV;
+		ERR("ERROR : vid_enc_open() max number of clients\n");
+		rc = -ENODEV;
+		goto client_failure;
 	}
 
 	DBG(" Virtual Address of ioremap is %p\n", vid_enc_device_p->virt_base);
 	if (!vid_enc_device_p->num_clients) {
-		if (!vidc_load_firmware())
-			return -ENODEV;
+		if (!vidc_load_firmware()) {
+			rc = -ENODEV;
+			goto client_failure;
+		}
 	}
 
 	client_index = vid_enc_get_empty_client_index();
 
-	if (client_index == -1) {
+	if (client_index < 0) {
 		ERR("%s() : No free clients client_index == -1\n",
 			__func__);
-		return -ENODEV;
+		rc = -ENODEV;
+		goto client_failure;
 	}
 
 	client_ctx =
@@ -566,27 +577,46 @@
 		client_ctx->user_ion_client = vcd_get_ion_client();
 		if (!client_ctx->user_ion_client) {
 			ERR("vcd_open ion get client failed");
-			return -EFAULT;
+			rc = -EFAULT;
+			goto client_failure;
 		}
 	}
 	rc = vcd_open(vid_enc_device_p->device_handle, false,
-		vid_enc_vcd_cb, client_ctx, 0);
+		vid_enc_vcd_cb, client_ctx, flags);
 	client_ctx->stop_msg = 0;
+	client_ctx->stop_called = 1;
 
 	if (!rc) {
 		wait_for_completion(&client_ctx->event);
 		if (client_ctx->event_status) {
 			ERR("callback for vcd_open returned error: %u",
 				client_ctx->event_status);
-			mutex_unlock(&vid_enc_device_p->lock);
-			return -EFAULT;
+			rc =  -EFAULT;
+			goto client_failure;
 		}
 	} else {
 		ERR("vcd_open returned error: %u", rc);
-		mutex_unlock(&vid_enc_device_p->lock);
-		return rc;
+		goto client_failure;
 	}
-	file->private_data = client_ctx;
+	*vid_clnt_ctx = client_ctx;
+client_failure:
+	return rc;
+}
+static int vid_enc_open(struct inode *inode, struct file *file)
+{
+	int rc = 0;
+	struct video_client_ctx *client_ctx = NULL;
+	INFO("msm_vidc_venc: Inside %s()", __func__);
+	mutex_lock(&vid_enc_device_p->lock);
+	rc = vid_enc_open_client(&client_ctx, 0);
+	if (rc)
+		pr_err("%s() open failed rc=%d\n", __func__, rc);
+	else if (!client_ctx) {
+		pr_err("%s() client_ctx is NULL\n", __func__);
+		rc = -ENOMEM;
+	}
+	if (!rc)
+		file->private_data = client_ctx;
 	mutex_unlock(&vid_enc_device_p->lock);
 	return rc;
 }
@@ -603,12 +633,62 @@
 	INFO("\n msm_vidc_enc: Return from %s()", __func__);
 	return 0;
 }
+static int vid_enc_open_secure(struct inode *inode, struct file *file)
+{
+	int rc = 0, vcd_status = 0;
+	struct video_client_ctx *client_ctx = NULL;
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_sps_pps_for_idr_enable idr_enable;
 
-static const struct file_operations vid_enc_fops = {
-	.owner = THIS_MODULE,
-	.open = vid_enc_open,
-	.release = vid_enc_release,
-	.unlocked_ioctl = vid_enc_ioctl,
+	INFO("msm_vidc_enc: Inside %s()", __func__);
+	mutex_lock(&vid_enc_device_p->lock);
+	rc = vid_enc_open_client(&client_ctx, VCD_CP_SESSION);
+	if (rc || !client_ctx) {
+		pr_err("%s() open failed rc=%d\n", __func__, rc);
+		if (!client_ctx)
+			rc = -ENOMEM;
+		goto error;
+	}
+	file->private_data = client_ctx;
+	vcd_property_hdr.prop_id = VCD_I_ENABLE_SPS_PPS_FOR_IDR;
+	vcd_property_hdr.sz =
+		sizeof(struct vcd_property_sps_pps_for_idr_enable);
+	idr_enable.sps_pps_for_idr_enable_flag = 1;
+	vcd_status = vcd_set_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &idr_enable);
+	if (vcd_status) {
+		ERR("Setting SPS with IDR failed\n");
+		rc = -EACCES;
+		goto close_client;
+	}
+
+	if (res_trk_open_secure_session()) {
+		rc = -EACCES;
+		goto close_client;
+	}
+	mutex_unlock(&vid_enc_device_p->lock);
+	return rc;
+
+close_client:
+	vid_enc_close_client(client_ctx);
+	ERR("Secure session operation failure\n");
+error:
+	mutex_unlock(&vid_enc_device_p->lock);
+	return rc;
+}
+static const struct file_operations vid_enc_fops[NUM_OF_DRIVER_NODES] = {
+	{
+		.owner = THIS_MODULE,
+		.open = vid_enc_open,
+		.release = vid_enc_release,
+		.unlocked_ioctl = vid_enc_ioctl,
+	},
+	{
+		.owner = THIS_MODULE,
+		.open = vid_enc_open_secure,
+		.release = vid_enc_release,
+		.unlocked_ioctl = vid_enc_ioctl,
+	},
 };
 
 void vid_enc_interrupt_deregister(void)
@@ -673,7 +753,7 @@
 
 static int __init vid_enc_init(void)
 {
-	int rc = 0;
+	int rc = 0, i = 0, j = 0;
 	struct device *class_devp;
 
 	INFO("\n msm_vidc_enc: Inside %s()", __func__);
@@ -684,14 +764,13 @@
 			__func__);
 		return -ENOMEM;
 	}
-
-	rc = alloc_chrdev_region(&vid_enc_dev_num, 0, 1, VID_ENC_NAME);
+	rc = alloc_chrdev_region(&vid_enc_dev_num, 0, NUM_OF_DRIVER_NODES,
+			VID_ENC_NAME);
 	if (rc < 0) {
 		ERR("%s: alloc_chrdev_region Failed rc = %d\n",
 			__func__, rc);
 		goto error_vid_enc_alloc_chrdev_region;
 	}
-
 	vid_enc_class = class_create(THIS_MODULE, VID_ENC_NAME);
 	if (IS_ERR(vid_enc_class)) {
 		rc = PTR_ERR(vid_enc_class);
@@ -699,32 +778,40 @@
 			__func__, rc);
 		goto error_vid_enc_class_create;
 	}
+	for (i = 0; i < NUM_OF_DRIVER_NODES; i++) {
+		class_devp = device_create(vid_enc_class, NULL,
+					(vid_enc_dev_num + i), NULL,
+					VID_ENC_NAME "%s", node_name[i]);
 
-	class_devp = device_create(vid_enc_class, NULL,
-				vid_enc_dev_num, NULL, VID_ENC_NAME);
+		if (IS_ERR(class_devp)) {
+			rc = PTR_ERR(class_devp);
+			ERR("%s: class device_create failed %d\n",
+			__func__, rc);
+			if (!i)
+				goto error_vid_enc_class_device_create;
+			else
+				goto error_vid_enc_cdev_add;
+		}
 
-	if (IS_ERR(class_devp)) {
-		rc = PTR_ERR(class_devp);
-		ERR("%s: class device_create failed %d\n",
-		__func__, rc);
-		goto error_vid_enc_class_device_create;
-	}
+		vid_enc_device_p->device[i] = class_devp;
 
-	vid_enc_device_p->device = class_devp;
+		cdev_init(&vid_enc_device_p->cdev[i], &vid_enc_fops[i]);
+		vid_enc_device_p->cdev[i].owner = THIS_MODULE;
+		rc = cdev_add(&(vid_enc_device_p->cdev[i]),
+					 (vid_enc_dev_num + i), 1);
 
-	cdev_init(&vid_enc_device_p->cdev, &vid_enc_fops);
-	vid_enc_device_p->cdev.owner = THIS_MODULE;
-	rc = cdev_add(&(vid_enc_device_p->cdev), vid_enc_dev_num, 1);
-
-	if (rc < 0) {
-		ERR("%s: cdev_add failed %d\n",
-		__func__, rc);
-		goto error_vid_enc_cdev_add;
+		if (rc < 0) {
+			ERR("%s: cdev_add failed %d\n",
+			__func__, rc);
+			goto error_vid_enc_cdev_add;
+		}
 	}
 	vid_enc_vcd_init();
 	return 0;
 
 error_vid_enc_cdev_add:
+	for (j = i-1; j >= 0; j--)
+		cdev_del(&(vid_enc_device_p->cdev[j]));
 	device_destroy(vid_enc_class, vid_enc_dev_num);
 error_vid_enc_class_device_create:
 	class_destroy(vid_enc_class);
@@ -738,8 +825,10 @@
 
 static void __exit vid_enc_exit(void)
 {
+	int i = 0;
 	INFO("\n msm_vidc_enc: Inside %s()", __func__);
-	cdev_del(&(vid_enc_device_p->cdev));
+	for (i = 0; i < NUM_OF_DRIVER_NODES; i++)
+		cdev_del(&(vid_enc_device_p->cdev[i]));
 	device_destroy(vid_enc_class, vid_enc_dev_num);
 	class_destroy(vid_enc_class);
 	unregister_chrdev_region(vid_enc_dev_num, 1);
@@ -790,17 +879,18 @@
 		struct venc_buffer enc_buffer;
 		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
 			return -EFAULT;
-		DBG("VEN_IOCTL_CMD_ENCODE_FRAME"
-			"/VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER\n");
 		if (copy_from_user(&enc_buffer, venc_msg.in,
 						   sizeof(enc_buffer)))
 			return -EFAULT;
-		if (cmd == VEN_IOCTL_CMD_ENCODE_FRAME)
+		if (cmd == VEN_IOCTL_CMD_ENCODE_FRAME) {
+			DBG("VEN_IOCTL_CMD_ENCODE_FRAME\n");
 			result = vid_enc_encode_frame(client_ctx,
 					&enc_buffer);
-		else
+		} else {
+			DBG("VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER\n");
 			result = vid_enc_fill_output_buffer(client_ctx,
 					&enc_buffer);
+		}
 		if (!result) {
 			DBG("\n VEN_IOCTL_CMD_ENCODE_FRAME/"
 				"VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER failed");
@@ -866,19 +956,19 @@
 		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
 			return -EFAULT;
 
-		DBG("VEN_IOCTL_SET_INPUT_BUFFER_REQ"
-			"/VEN_IOCTL_SET_OUTPUT_BUFFER_REQ\n");
-
 		if (copy_from_user(&allocatorproperty, venc_msg.in,
 			sizeof(allocatorproperty)))
 			return -EFAULT;
 
-		if (cmd == VEN_IOCTL_SET_OUTPUT_BUFFER_REQ)
-				result = vid_enc_set_buffer_req(client_ctx,
-						&allocatorproperty, false);
-		else
+		if (cmd == VEN_IOCTL_SET_OUTPUT_BUFFER_REQ) {
+			DBG("VEN_IOCTL_SET_OUTPUT_BUFFER_REQ\n");
+			result = vid_enc_set_buffer_req(client_ctx,
+					&allocatorproperty, false);
+		} else {
+			DBG("VEN_IOCTL_SET_INPUT_BUFFER_REQ\n");
 			result = vid_enc_set_buffer_req(client_ctx,
 					&allocatorproperty, true);
+		}
 		if (!result) {
 			DBG("setting VEN_IOCTL_SET_OUTPUT_BUFFER_REQ/"
 			"VEN_IOCTL_SET_INPUT_BUFFER_REQ failed\n");
@@ -893,15 +983,15 @@
 		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
 			return -EFAULT;
 
-		DBG("VEN_IOCTL_GET_INPUT_BUFFER_REQ/"
-			"VEN_IOCTL_GET_OUTPUT_BUFFER_REQ\n");
-
-		if (cmd == VEN_IOCTL_GET_OUTPUT_BUFFER_REQ)
+		if (cmd == VEN_IOCTL_GET_OUTPUT_BUFFER_REQ) {
+			DBG("VEN_IOCTL_GET_OUTPUT_BUFFER_REQ\n");
 			result = vid_enc_get_buffer_req(client_ctx,
 					&allocatorproperty, false);
-		else
+		} else {
+			DBG("VEN_IOCTL_GET_INPUT_BUFFER_REQ\n");
 			result = vid_enc_get_buffer_req(client_ctx,
 					&allocatorproperty, true);
+		}
 		if (!result)
 			return -EIO;
 		if (copy_to_user(venc_msg.out, &allocatorproperty,
@@ -936,7 +1026,8 @@
 		if (!result) {
 			ERR("setting VEN_IOCTL_CMD_START failed\n");
 			return -EIO;
-		}
+		} else
+			client_ctx->stop_called = 0;
 		break;
 	}
 	case VEN_IOCTL_CMD_STOP:
@@ -947,7 +1038,7 @@
 			ERR("setting VEN_IOCTL_CMD_STOP failed\n");
 			return -EIO;
 		}
-		stop_cmd = 1;
+		client_ctx->stop_called = 1;
 		break;
 	}
 	case VEN_IOCTL_CMD_PAUSE:
@@ -1342,6 +1433,7 @@
 	}
 	case VEN_IOCTL_CMD_REQUEST_IFRAME:
 	{
+		DBG("VEN_IOCTL_CMD_REQUEST_IFRAME\n");
 		result = vid_enc_request_iframe(client_ctx);
 		if (!result) {
 			ERR("setting VEN_IOCTL_CMD_REQUEST_IFRAME failed\n");
@@ -1565,6 +1657,7 @@
 		struct vcd_property_hdr vcd_property_hdr;
 		struct vcd_property_live live_mode;
 
+		DBG("VEN_IOCTL_SET_METABUFFER_MODE\n");
 		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
 			return -EFAULT;
 		if (copy_from_user(&metabuffer_mode, venc_msg.in,
@@ -1614,6 +1707,7 @@
 		struct vcd_property_hdr vcd_property_hdr;
 		u32 vcd_status = VCD_ERR_FAIL;
 		u32 enable = true;
+		DBG("VEN_IOCTL_SET_SLICE_DELIVERY_MODE\n");
 		vcd_property_hdr.prop_id = VCD_I_SLICE_DELIVERY_MODE;
 		vcd_property_hdr.sz = sizeof(u32);
 		vcd_status = vcd_set_property(client_ctx->vcd_handle,
@@ -1647,6 +1741,168 @@
 		}
 		break;
 	}
+	case VEN_IOCTL_SET_LTRMODE:
+	case VEN_IOCTL_GET_LTRMODE:
+	{
+		struct venc_ltrmode encoder_ltrmode;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		if (cmd == VEN_IOCTL_SET_LTRMODE) {
+			DBG("VEN_IOCTL_SET_LTRMODE\n");
+			if (copy_from_user(&encoder_ltrmode, venc_msg.in,
+					sizeof(encoder_ltrmode)))
+				return -EFAULT;
+			result = vid_enc_set_get_ltrmode(client_ctx,
+					&encoder_ltrmode, true);
+		} else {
+			DBG("VEN_IOCTL_GET_LTRMODE\n");
+			result = vid_enc_set_get_ltrmode(client_ctx,
+					&encoder_ltrmode, false);
+			if (result) {
+				if (copy_to_user(venc_msg.out, &encoder_ltrmode,
+						sizeof(encoder_ltrmode)))
+					return -EFAULT;
+			}
+		}
+		if (!result) {
+			ERR("VEN_IOCTL_(G)SET_LTRMODE failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_SET_LTRCOUNT:
+	case VEN_IOCTL_GET_LTRCOUNT:
+	{
+		struct venc_ltrcount encoder_ltrcount;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		if (cmd == VEN_IOCTL_SET_LTRCOUNT) {
+			DBG("VEN_IOCTL_SET_LTRCOUNT\n");
+			if (copy_from_user(&encoder_ltrcount, venc_msg.in,
+					sizeof(encoder_ltrcount)))
+				return -EFAULT;
+			result = vid_enc_set_get_ltrcount(client_ctx,
+					&encoder_ltrcount, true);
+		} else {
+			DBG("VEN_IOCTL_GET_LTRCOUNT\n");
+			result = vid_enc_set_get_ltrcount(client_ctx,
+					&encoder_ltrcount, false);
+			if (result) {
+				if (copy_to_user(venc_msg.out,
+					&encoder_ltrcount,
+					sizeof(encoder_ltrcount)))
+					return -EFAULT;
+			}
+		}
+		if (!result) {
+			ERR("VEN_IOCTL_(G)SET_LTRCOUNT failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_SET_LTRPERIOD:
+	case VEN_IOCTL_GET_LTRPERIOD:
+	{
+		struct venc_ltrperiod encoder_ltrperiod;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		if (cmd == VEN_IOCTL_SET_LTRPERIOD) {
+			DBG("VEN_IOCTL_SET_LTRPERIOD\n");
+			if (copy_from_user(&encoder_ltrperiod, venc_msg.in,
+					sizeof(encoder_ltrperiod)))
+				return -EFAULT;
+			result = vid_enc_set_get_ltrperiod(client_ctx,
+					&encoder_ltrperiod, true);
+		} else {
+			DBG("VEN_IOCTL_GET_LTRPERIOD\n");
+			result = vid_enc_set_get_ltrperiod(client_ctx,
+					&encoder_ltrperiod, false);
+			if (result) {
+				if (copy_to_user(venc_msg.out,
+					&encoder_ltrperiod,
+					sizeof(encoder_ltrperiod)))
+					return -EFAULT;
+			}
+		}
+		if (!result) {
+			ERR("VEN_IOCTL_(G)SET_LTRPERIOD failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_GET_CAPABILITY_LTRCOUNT:
+	{
+		struct venc_range venc_capltrcount;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		DBG("VEN_IOCTL_GET_CAPABILITY_LTRCOUNT\n");
+		result = vid_enc_get_capability_ltrcount(client_ctx,
+					&venc_capltrcount);
+		if (result) {
+			if (copy_to_user(venc_msg.out, &venc_capltrcount,
+					sizeof(venc_capltrcount)))
+				return -EFAULT;
+		} else {
+			ERR("VEN_IOCTL_GET_CAPABILITY_LTRCOUNT failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_SET_LTRUSE:
+	case VEN_IOCTL_GET_LTRUSE:
+	{
+		struct venc_ltruse encoder_ltruse;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		if (cmd == VEN_IOCTL_SET_LTRUSE) {
+			DBG("VEN_IOCTL_SET_LTRUSE\n");
+			if (copy_from_user(&encoder_ltruse, venc_msg.in,
+					sizeof(encoder_ltruse)))
+				return -EFAULT;
+			result = vid_enc_set_get_ltruse(client_ctx,
+						&encoder_ltruse, true);
+		} else {
+			DBG("VEN_IOCTL_GET_LTRUSE\n");
+			result = vid_enc_set_get_ltruse(client_ctx,
+						&encoder_ltruse, false);
+			if (result) {
+				if (copy_to_user(venc_msg.out,
+					&encoder_ltruse,
+					sizeof(encoder_ltruse)))
+					return -EFAULT;
+			}
+		}
+		if (!result) {
+			ERR("VEN_IOCTL_(G)SET_LTRUSE failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_SET_SPS_PPS_FOR_IDR:
+	{
+		struct vcd_property_hdr vcd_property_hdr;
+		struct vcd_property_sps_pps_for_idr_enable idr_enable;
+		u32 vcd_status = VCD_ERR_FAIL;
+		u32 enabled = 1;
+
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+
+		vcd_property_hdr.prop_id = VCD_I_ENABLE_SPS_PPS_FOR_IDR;
+		vcd_property_hdr.sz = sizeof(idr_enable);
+
+		if (copy_from_user(&enabled, venc_msg.in, sizeof(u32)))
+			return -EFAULT;
+
+		idr_enable.sps_pps_for_idr_enable_flag = enabled;
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &idr_enable);
+		if (vcd_status) {
+			pr_err("Setting sps/pps per IDR failed");
+			return -EIO;
+		}
+		break;
+	}
 	case VEN_IOCTL_SET_AC_PREDICTION:
 	case VEN_IOCTL_GET_AC_PREDICTION:
 	case VEN_IOCTL_SET_RVLC:
diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.c b/drivers/video/msm/vidc/common/enc/venc_internal.c
index 8779432..14d8bfc 100644
--- a/drivers/video/msm/vidc/common/enc/venc_internal.c
+++ b/drivers/video/msm/vidc/common/enc/venc_internal.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -328,6 +328,42 @@
 	vcd_property_hdr.prop_id = VCD_I_METADATA_ENABLE;
 	vcd_property_hdr.sz = sizeof(struct vcd_property_meta_data_enable);
 	if (set_flag) {
+		DBG("vcd_set_property: VCD_I_METADATA_ENABLE = %x\n",
+				(u32)*extradata_flag);
+		vcd_meta_data.meta_data_enable_flag = *extradata_flag;
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &vcd_meta_data);
+		if (vcd_status) {
+			ERR("%s(): Set VCD_I_METADATA_ENABLE Failed\n",
+				__func__);
+			return false;
+		}
+	} else {
+		vcd_status = vcd_get_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &vcd_meta_data);
+		if (vcd_status) {
+			ERR("%s(): Get VCD_I_METADATA_ENABLE Failed\n",
+				__func__);
+			return false;
+		}
+		*extradata_flag = vcd_meta_data.meta_data_enable_flag;
+		DBG("vcd_get_property: VCD_I_METADATA_ENABLE = 0x%x\n",
+				(u32)*extradata_flag);
+	}
+	return true;
+}
+
+u32 vid_enc_set_get_extradata_cfg(struct video_client_ctx *client_ctx,
+		u32 *extradata_flag, u32 set_flag)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_meta_data_enable vcd_meta_data;
+	u32 vcd_status = VCD_ERR_FAIL;
+	if (!client_ctx || !extradata_flag)
+		return false;
+	vcd_property_hdr.prop_id = VCD_I_METADATA_ENABLE;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_meta_data_enable);
+	if (set_flag) {
 		DBG("vcd_set_property: VCD_I_METADATA_ENABLE = %d\n",
 				*extradata_flag);
 		vcd_meta_data.meta_data_enable_flag = *extradata_flag;
@@ -1995,3 +2031,215 @@
 			return false;
 		}
 }
+
+u32 vid_enc_set_get_ltrmode(struct video_client_ctx *client_ctx,
+		struct venc_ltrmode *venc_ltrmode, u32 set_flag)
+{
+	struct vcd_property_ltrmode_type vcd_property_ltrmode;
+	struct vcd_property_hdr vcd_property_hdr;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx || !venc_ltrmode)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_LTR_MODE;
+	vcd_property_hdr.sz =
+		sizeof(struct vcd_property_ltrmode_type);
+
+	if (set_flag) {
+		vcd_property_ltrmode.ltr_mode = (enum vcd_property_ltrmode)
+			venc_ltrmode->ltr_mode;
+		DBG("%s: Set ltr_mode = %u", __func__,
+			(u32)vcd_property_ltrmode.ltr_mode);
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_property_ltrmode);
+		if (vcd_status) {
+			ERR("%s(): Set VCD_I_LTR_MODE Failed\n",
+					__func__);
+			return false;
+		}
+	} else {
+		vcd_status = vcd_get_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_property_ltrmode);
+		if (vcd_status) {
+			ERR("%s(): Get VCD_I_LTR_MODE Failed\n",
+					__func__);
+			return false;
+		} else {
+			venc_ltrmode->ltr_mode = (unsigned long)
+				vcd_property_ltrmode.ltr_mode;
+			DBG("%s: Got ltr_mode = %u", __func__,
+				(u32)vcd_property_ltrmode.ltr_mode);
+		}
+	}
+
+	return true;
+}
+
+u32 vid_enc_set_get_ltrcount(struct video_client_ctx *client_ctx,
+		struct venc_ltrcount *venc_ltrcount, u32 set_flag)
+{
+	struct vcd_property_ltrcount_type vcd_property_ltrcount;
+	struct vcd_property_hdr vcd_property_hdr;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx || !venc_ltrcount)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_LTR_COUNT;
+	vcd_property_hdr.sz =
+		sizeof(struct vcd_property_ltrcount_type);
+
+	if (set_flag) {
+		vcd_property_ltrcount.ltr_count = (u32)
+			venc_ltrcount->ltr_count;
+		DBG("%s: Set ltr_count = %u", __func__,
+			(u32)vcd_property_ltrcount.ltr_count);
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_property_ltrcount);
+		if (vcd_status) {
+			ERR("%s(): Set VCD_I_LTR_COUNT Failed\n",
+					__func__);
+			return false;
+		}
+	} else {
+		vcd_status = vcd_get_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_property_ltrcount);
+		if (vcd_status) {
+			ERR("%s(): Get VCD_I_LTR_COUNT Failed\n",
+					__func__);
+			return false;
+		} else {
+			venc_ltrcount->ltr_count = (unsigned long)
+				vcd_property_ltrcount.ltr_count;
+			DBG("%s: Got ltr_count = %u", __func__,
+				(u32)vcd_property_ltrcount.ltr_count);
+		}
+	}
+
+	return true;
+}
+
+u32 vid_enc_set_get_ltrperiod(struct video_client_ctx *client_ctx,
+		struct venc_ltrperiod *venc_ltrperiod, u32 set_flag)
+{
+	struct vcd_property_ltrperiod_type vcd_property_ltrperiod;
+	struct vcd_property_hdr vcd_property_hdr;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx || !venc_ltrperiod)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_LTR_PERIOD;
+	vcd_property_hdr.sz =
+		sizeof(struct vcd_property_ltrperiod_type);
+
+	if (set_flag) {
+		vcd_property_ltrperiod.ltr_period = (u32)
+			venc_ltrperiod->ltr_period;
+		DBG("%s: Set ltr_period = %u", __func__,
+			(u32)vcd_property_ltrperiod.ltr_period);
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_property_ltrperiod);
+		if (vcd_status) {
+			ERR("%s(): Set VCD_I_LTR_PERIOD Failed\n",
+					__func__);
+			return false;
+		}
+	} else {
+		vcd_status = vcd_get_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_property_ltrperiod);
+		if (vcd_status) {
+			ERR("%s(): Get VCD_I_LTR_PERIOD Failed\n",
+					__func__);
+			return false;
+		} else {
+			venc_ltrperiod->ltr_period = (unsigned long)
+				vcd_property_ltrperiod.ltr_period;
+			DBG("%s: Got ltr_period = %u", __func__,
+				(u32)vcd_property_ltrperiod.ltr_period);
+		}
+	}
+
+	return true;
+}
+
+u32 vid_enc_set_get_ltruse(struct video_client_ctx *client_ctx,
+		struct venc_ltruse *venc_ltruse, u32 set_flag)
+{
+	struct vcd_property_ltruse_type vcd_property_ltruse;
+	struct vcd_property_hdr vcd_property_hdr;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx || !venc_ltruse)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_LTR_USE;
+	vcd_property_hdr.sz =
+		sizeof(struct vcd_property_ltruse_type);
+
+	if (set_flag) {
+		vcd_property_ltruse.ltr_id = (u32)
+			venc_ltruse->ltr_id;
+		vcd_property_ltruse.ltr_frames = (u32)
+			venc_ltruse->ltr_frames;
+		DBG("%s: Set ltr_id = %u, ltr_frames = %u",
+			__func__, vcd_property_ltruse.ltr_id,
+			vcd_property_ltruse.ltr_frames);
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_property_ltruse);
+		if (vcd_status) {
+			ERR("%s(): Set VCD_I_LTR_USE Failed\n",
+					__func__);
+			return false;
+		}
+	} else {
+		vcd_status = vcd_get_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_property_ltruse);
+		if (vcd_status) {
+			ERR("%s(): Get VCD_I_LTR_USE Failed\n",
+					__func__);
+			return false;
+		} else {
+			venc_ltruse->ltr_id = (unsigned long)
+				vcd_property_ltruse.ltr_id;
+			venc_ltruse->ltr_frames = (unsigned long)
+				vcd_property_ltruse.ltr_frames;
+			DBG("%s: Got ltr_id = %u, ltr_frames = %u",
+				__func__, vcd_property_ltruse.ltr_id,
+				vcd_property_ltruse.ltr_frames);
+		}
+	}
+
+	return true;
+}
+
+u32 vid_enc_get_capability_ltrcount(struct video_client_ctx *client_ctx,
+		struct venc_range *venc_capltrcount)
+{
+	struct vcd_property_range_type vcd_property_range;
+	struct vcd_property_hdr vcd_property_hdr;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx || !venc_capltrcount)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_CAPABILITY_LTR_COUNT;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_range_type);
+	vcd_status = vcd_get_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &vcd_property_range);
+	if (vcd_status) {
+		ERR("%s(): Get VCD_I_CAPABILITY_LTR_COUNT Failed\n",
+			__func__);
+		return false;
+	} else {
+		venc_capltrcount->min = vcd_property_range.min;
+		venc_capltrcount->max = vcd_property_range.max;
+		venc_capltrcount->step_size = vcd_property_range.step_size;
+		DBG("%s: Got min: %lu, max: %lu, step_size: %lu", __func__,
+			venc_capltrcount->min, venc_capltrcount->max,
+			venc_capltrcount->step_size);
+	}
+
+	return true;
+}
diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.h b/drivers/video/msm/vidc/common/enc/venc_internal.h
index 8a07fdb..b7b8c98 100644
--- a/drivers/video/msm/vidc/common/enc/venc_internal.h
+++ b/drivers/video/msm/vidc/common/enc/venc_internal.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. 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
@@ -18,6 +18,7 @@
 #include <linux/cdev.h>
 #include <media/msm/vidc_init.h>
 
+#define NUM_OF_DRIVER_NODES 2
 #define VID_ENC_MAX_NUM_OF_BUFF 100
 
 enum venc_buffer_dir{
@@ -32,8 +33,8 @@
 
 struct vid_enc_dev {
 
-	struct cdev cdev;
-	struct device *device;
+	struct cdev cdev[NUM_OF_DRIVER_NODES];
+	struct device *device[NUM_OF_DRIVER_NODES];
 	resource_size_t phys_base;
 	void __iomem *virt_base;
 	unsigned int irq;
@@ -151,4 +152,19 @@
 u32 vid_enc_get_recon_buffer_size(struct video_client_ctx *client_ctx,
 		struct venc_recon_buff_size *venc_recon_size);
 
+u32 vid_enc_set_get_ltrmode(struct video_client_ctx *client_ctx,
+		struct venc_ltrmode *encoder_ltrmode, u32 set_flag);
+
+u32 vid_enc_set_get_ltrcount(struct video_client_ctx *client_ctx,
+		struct venc_ltrcount *encoder_ltrcount, u32 set_flag);
+
+u32 vid_enc_set_get_ltrperiod(struct video_client_ctx *client_ctx,
+		struct venc_ltrperiod *encoder_ltrperiod, u32 set_flag);
+
+u32 vid_enc_get_capability_ltrcount(struct video_client_ctx *client_ctx,
+		struct venc_range *venc_capltrcount);
+
+u32 vid_enc_set_get_ltruse(struct video_client_ctx *client_ctx,
+		struct venc_ltruse *encoder_ltruse, u32 set_flag);
+
 #endif
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.c b/drivers/video/msm/vidc/common/init/vidc_init.c
index 65dde68..9007145 100644
--- a/drivers/video/msm/vidc/common/init/vidc_init.c
+++ b/drivers/video/msm/vidc/common/init/vidc_init.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/common/init/vidc_init_internal.h b/drivers/video/msm/vidc/common/init/vidc_init_internal.h
index 1d903ad..b62280f 100644
--- a/drivers/video/msm/vidc/common/init/vidc_init_internal.h
+++ b/drivers/video/msm/vidc/common/init/vidc_init_internal.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/common/vcd/vcd.h b/drivers/video/msm/vidc/common/vcd/vcd.h
index a22adeb..90f7d0e 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -402,4 +402,7 @@
 struct vcd_transc *vcd_get_first_in_use_trans_for_clnt(
 	struct vcd_clnt_ctxt *cctxt);
 
+u32 vcd_handle_ltr_use_failed(struct vcd_clnt_ctxt *cctxt,
+	void *payload, size_t sz, u32 status);
+
 #endif
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_api.c b/drivers/video/msm/vidc/common/vcd/vcd_api.c
index 0dbbf57..3d7474f 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_api.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_api.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. 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
@@ -117,36 +117,20 @@
 	int is_secure;
 	struct client_security_info sec_info;
 	int client_count = 0;
-	int secure_session_running = 0;
+	int secure_session_running = 0, non_secure_runnung = 0;
 	is_secure = (flags & VCD_CP_SESSION) ? 1 : 0;
 	client_count = vcd_get_clients_security_info(&sec_info);
 	secure_session_running = (sec_info.secure_enc > 0) ||
 			(sec_info.secure_dec > 0);
-	if (!decoding && is_secure) {
-		if ((sec_info.secure_dec == 1))
-			VCD_MSG_LOW("SE-SD: SUCCESS\n");
-		else {
-			VCD_MSG_LOW("SE is permitted only with SD: FAILURE\n");
-			return -EACCES;
-		}
-	} else if (!decoding && !is_secure) {
+	non_secure_runnung = sec_info.non_secure_dec + sec_info.non_secure_enc;
+	if (!is_secure) {
 		if (secure_session_running) {
-			VCD_MSG_LOW("SD-NSE: FAILURE\n");
-			VCD_MSG_LOW("SE-NSE: FAILURE\n");
-			return -EACCES;
-		}
-	} else if (decoding && is_secure) {
-		if (client_count > 0) {
-			VCD_MSG_LOW("S/NS-SD: FAILURE\n");
-			if (sec_info.secure_enc > 0 ||
-				sec_info.non_secure_enc > 0) {
-				return -EAGAIN;
-			}
+			pr_err("non secure session failed secure running\n");
 			return -EACCES;
 		}
 	} else {
-		if (sec_info.secure_dec > 0) {
-			VCD_MSG_LOW("SD-NSD: FAILURE\n");
+		if (non_secure_runnung) {
+			pr_err("Secure session failed non secure running\n");
 			return -EACCES;
 		}
 	}
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c
index 8f52f83..14c8030 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -964,6 +964,12 @@
 			vcd_handle_ind_info_output_reconfig(cctxt, status);
 			break;
 		}
+	case VCD_EVT_IND_INFO_LTRUSE_FAILED:
+		{
+			rc = vcd_handle_ltr_use_failed(cctxt,
+					payload, sz, status);
+			break;
+		}
 	default:
 		{
 			VCD_MSG_ERROR
@@ -1622,6 +1628,7 @@
 	if (!cctxt || to_state >= VCD_CLIENT_STATE_MAX) {
 		VCD_MSG_ERROR("Bad parameters. cctxt=%p, to_state=%d",
 			      cctxt, to_state);
+		return;
 	}
 
 	state_ctxt = &cctxt->clnt_state;
@@ -1744,7 +1751,7 @@
 	 vcd_get_buffer_requirements_cmn,
 	 NULL,
 	 NULL,
-	 NULL,
+	 vcd_free_buffer_cmn,
 	 vcd_fill_output_buffer_cmn,
 	 vcd_clnt_cb_in_flushing,
 	 },
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_client_sm.h b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.h
index 9f2d63d..ba1884d 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_client_sm.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_core.h b/drivers/video/msm/vidc/common/vcd/vcd_core.h
index aba8119..0eaff74 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_core.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd_core.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c
index f670a4a..9074358 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -36,6 +36,7 @@
 	if (!drv_ctxt || to_state >= VCD_DEVICE_STATE_MAX) {
 		VCD_MSG_ERROR("Bad parameters. drv_ctxt=%p, to_state=%d",
 				  drv_ctxt, to_state);
+		return;
 	}
 
 	state_ctxt = &drv_ctxt->dev_state;
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_device_sm.h b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.h
index 2443c33..898f284 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_device_sm.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_power_sm.c b/drivers/video/msm/vidc/common/vcd/vcd_power_sm.c
index 44d270a..4b70eed 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_power_sm.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_power_sm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_power_sm.h b/drivers/video/msm/vidc/common/vcd/vcd_power_sm.h
index 26ce019..aecbc8d 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_power_sm.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd_power_sm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_scheduler.c b/drivers/video/msm/vidc/common/vcd/vcd_scheduler.c
index ab21bac..fe0e131 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_scheduler.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_scheduler.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -88,8 +88,13 @@
 			prop_hdr.sz = sizeof(cctxt->frm_p_units);
 			rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr,
 						  &cctxt->frm_p_units);
-			VCD_FAILED_RETURN(rc,
-				"Failed: Get DDL_I_FRAME_PROC_UNITS");
+			if (VCD_FAILED(rc)) {
+				kfree(sched_cctxt);
+				VCD_MSG_ERROR(
+					"Failed: Get DDL_I_FRAME_PROC_UNITS");
+				return rc;
+			}
+
 			if (cctxt->decoding) {
 				cctxt->frm_rate.fps_numerator =
 					VCD_DEC_INITIAL_FRAME_RATE;
@@ -99,8 +104,12 @@
 				prop_hdr.sz = sizeof(cctxt->frm_rate);
 				rc = ddl_get_property(cctxt->ddl_handle,
 						&prop_hdr, &cctxt->frm_rate);
-				VCD_FAILED_RETURN(rc,
-					"Failed: Get VCD_I_FRAME_RATE");
+				if (VCD_FAILED(rc)) {
+					kfree(sched_cctxt);
+					VCD_MSG_ERROR(
+						"Failed: Get VCD_I_FRAME_RATE");
+					return rc;
+				}
 			}
 			if (!cctxt->perf_set_by_client)
 				cctxt->reqd_perf_lvl = cctxt->frm_p_units *
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_sub.c b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
index a4c44f3..09cd91d 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_sub.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -2022,6 +2022,11 @@
 	orig_frame = vcd_find_buffer_pool_entry(&cctxt->in_buf_pool,
 					 transc->ip_buf_entry->virtual);
 
+	if (!orig_frame) {
+		rc = VCD_ERR_ILLEGAL_PARM;
+		VCD_FAILED_RETURN(rc, "Couldn't find buffer");
+	}
+
 	if ((transc->ip_buf_entry->frame.virtual !=
 		 frame->vcd_frm.virtual)
 		|| !transc->ip_buf_entry->in_use) {
@@ -3516,3 +3521,14 @@
 	}
 	return rc;
 }
+
+u32 vcd_handle_ltr_use_failed(struct vcd_clnt_ctxt *cctxt,
+	void *payload, size_t sz, u32 status)
+{
+	u32 rc = VCD_S_SUCCESS;
+	if (payload && cctxt) {
+		cctxt->callback(VCD_EVT_IND_INFO_LTRUSE_FAILED,
+			status, payload, sz, cctxt, cctxt->client_data);
+	}
+	return rc;
+}
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_util.c b/drivers/video/msm/vidc/common/vcd/vcd_util.c
index ba991f1..98bc7f5 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_util.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_util.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_util.h b/drivers/video/msm/vidc/common/vcd/vcd_util.h
index ed7fc1a..f374ebb 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_util.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd_util.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 6e0f58b..6b83222 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -664,7 +664,7 @@
 		}
 	}
 
-#ifdef CONFIG_DMA_CMA
+#ifdef CONFIG_CMA
 	if (is_cma_pageblock(page)) {
 		struct page *oldpage = page, *newpage;
 		int err;
diff --git a/include/asm-generic/dma-contiguous.h b/include/asm-generic/dma-contiguous.h
index c544356..9071ef1 100644
--- a/include/asm-generic/dma-contiguous.h
+++ b/include/asm-generic/dma-contiguous.h
@@ -11,15 +11,13 @@
 {
 	if (dev && dev->cma_area)
 		return dev->cma_area;
-	return dma_contiguous_default_area;
+	return dma_contiguous_def_area;
 }
 
 static inline void dev_set_cma_area(struct device *dev, struct cma *cma)
 {
 	if (dev)
 		dev->cma_area = cma;
-	if (!dev || !dma_contiguous_default_area)
-		dma_contiguous_default_area = cma;
 }
 
 #endif
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index dd73104..3bf1490 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -9,7 +9,7 @@
 /*
  * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
  * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * Copyright (c) 2009-2010, Code Aurora Forum.
+ * Copyright (c) 2009-2010, The Linux Foundation.
  * All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
diff --git a/include/drm/kgsl_drm.h b/include/drm/kgsl_drm.h
index 7ffae9d..41f7c29 100644
--- a/include/drm/kgsl_drm.h
+++ b/include/drm/kgsl_drm.h
@@ -20,6 +20,7 @@
 #define DRM_KGSL_GEM_UNLOCK_ON_TS 0x0D
 #define DRM_KGSL_GEM_CREATE_FD 0x0E
 #define DRM_KGSL_GEM_GET_ION_FD 0x0F
+#define DRM_KGSL_GEM_CREATE_FROM_ION 0x10
 
 #define DRM_IOCTL_KGSL_GEM_CREATE \
 DRM_IOWR(DRM_COMMAND_BASE + DRM_KGSL_GEM_CREATE, struct drm_kgsl_gem_create)
@@ -80,6 +81,10 @@
 DRM_IOWR(DRM_COMMAND_BASE + DRM_KGSL_GEM_GET_ION_FD, \
 struct drm_kgsl_gem_get_ion_fd)
 
+#define DRM_IOCTL_KGSL_GEM_CREATE_FROM_ION \
+DRM_IOWR(DRM_COMMAND_BASE + DRM_KGSL_GEM_CREATE_FROM_ION, \
+struct drm_kgsl_gem_create_from_ion)
+
 /* Maximum number of sub buffers per GEM object */
 #define DRM_KGSL_GEM_MAX_BUFFERS 2
 
@@ -199,4 +204,9 @@
 	uint32_t handle;
 };
 
+struct drm_kgsl_gem_create_from_ion {
+	uint32_t ion_fd;
+	uint32_t handle;
+};
+
 #endif
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 46ae59f..f6ca334 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -207,6 +207,7 @@
 header-y += input.h
 header-y += ioctl.h
 header-y += ion.h
+header-y += ioprio.h
 header-y += ip.h
 header-y += ip6_tunnel.h
 header-y += ip_vs.h
@@ -384,6 +385,7 @@
 header-y += types.h
 header-y += udf_fs_i.h
 header-y += udp.h
+header-y += uhid.h
 header-y += uinput.h
 header-y += uio.h
 header-y += ultrasound.h
@@ -439,6 +441,7 @@
 header-y += msm_audio_sbc.h
 header-y += msm_ipc.h
 header-y += msm_charm.h
+header-y += msm_rmnet.h
 header-y += qseecom.h
 header-y += qcedev.h
 header-y += idle_stats_device.h
@@ -448,3 +451,4 @@
 header-y += ci-bridge-spi.h
 header-y += msm_audio_amrwbplus.h
 header-y += avtimer.h
+header-y += msm_ipa.h
diff --git a/include/linux/adv7520.h b/include/linux/adv7520.h
index 96db7b7..f64dbdf 100644
--- a/include/linux/adv7520.h
+++ b/include/linux/adv7520.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/bif/consumer.h b/include/linux/bif/consumer.h
new file mode 100644
index 0000000..e4c190e
--- /dev/null
+++ b/include/linux/bif/consumer.h
@@ -0,0 +1,613 @@
+/* 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 _LINUX_BIF_CONSUMER_H_
+#define _LINUX_BIF_CONSUMER_H_
+
+#include <linux/bitops.h>
+#include <linux/kernel.h>
+#include <linux/notifier.h>
+
+#define BIF_DEVICE_ID_BYTE_LENGTH	8
+#define BIF_UNIQUE_ID_BYTE_LENGTH	10
+#define BIF_UNIQUE_ID_BIT_LENGTH	80
+
+#define BIF_PRIMARY_SLAVE_DEV_ADR	0x01
+
+/**
+ * enum bif_transaction - BIF master bus transaction types
+ * %BIF_TRANS_WD:	Write data
+ * %BIF_TRANS_ERA:	Extended register address
+ * %BIF_TRANS_WRA:	Write register address
+ * %BIF_TRANS_RRA:	Read register address
+ * %BIF_TRANS_BC:	Bus command
+ * %BIF_TRANS_EDA:	Extended device address
+ * %BIF_TRANS_SDA:	Slave device address
+ *
+ * These values correspond to BIF word bits: BCF, bit 9, bit 8.
+ * BCF_n bit is inserted automatically.
+ */
+enum bif_transaction {
+	BIF_TRANS_WD	= 0x00,
+	BIF_TRANS_ERA	= 0x01,
+	BIF_TRANS_WRA	= 0x02,
+	BIF_TRANS_RRA	= 0x03,
+	BIF_TRANS_BC	= 0x04,
+	BIF_TRANS_EDA	= 0x05,
+	BIF_TRANS_SDA	= 0x06,
+};
+
+/* BIF slave response components */
+#define BIF_SLAVE_RD_ACK		0x200
+#define BIF_SLAVE_RD_EOT		0x100
+#define BIF_SLAVE_RD_DATA		0x0FF
+#define BIF_SLAVE_RD_ERR		0x0FF
+#define BIF_SLAVE_TACK_ACK		0x200
+#define BIF_SLAVE_TACK_WCNT		0x0FF
+#define BIF_SLAVE_TACK_ERR		0x0FF
+
+/**
+ * enum bif_bus_command - MIPI defined bus commands to use in BC transaction
+ * %BIF_CMD_BRES:	Bus reset of all slaves
+ * %BIF_CMD_PDWN:	Put all slaves into power down mode
+ * %BIF_CMD_STBY:	Put all slaves into standby mode
+ * %BIF_CMD_EINT:	Enable interrupts for all slaves
+ * %BIF_CMD_ISTS:	Poll interrupt status for all slaves.  Expects BQ
+ *			response if any slave has a pending interrupt.
+ * %BIF_CMD_RBL:	Specify the burst read length for the next read
+ *			transaction.  Bits 3 to 0 should also be ORed on in
+ *			order to specify the number of bytes to read.
+ * %BIF_CMD_RBE:	Specify the extended burst read length for the next read
+ *			transaction.  Bits 3 to 0 should also be ORed on in
+ *			order to specify the number of bytes to read.  The burst
+ *			read length for RBEy and RBLx = 16 * y + x.
+ * %BIF_CMD_DASM:	Device activation stick mode.  This keeps a slave
+ *			selected if it would otherwise become unselected by the
+ *			next transaction.
+ * %BIF_CMD_DISS:	UID search start
+ * %BIF_CMD_DILC:	UID length check.  Expects BQ response if all 80 UID
+ *			bits for a given slave have been entered.
+ * %BIF_CMD_DIE0:	UID search enter 0
+ * %BIF_CMD_DIE1:	UID search enter 1
+ * %BIF_CMD_DIP0:	UID search probe 0
+ * %BIF_CMD_DIP1:	UID search probe 1
+ * %BIF_CMD_DRES:	Device reset of selected slaves
+ * %BIF_CMD_TQ:		Transaction query; expects TACK response
+ * %BIF_CMD_AIO:	Address increment off for the next transaction
+ *
+ * These values correspond to BIF word bits 7 to 0.
+ */
+enum bif_bus_command {
+	BIF_CMD_BRES	= 0x00,
+	BIF_CMD_PDWN	= 0x02,
+	BIF_CMD_STBY	= 0x03,
+	BIF_CMD_EINT	= 0x10,
+	BIF_CMD_ISTS	= 0x11,
+	BIF_CMD_RBL	= 0x20,
+	BIF_CMD_RBE	= 0x30,
+	BIF_CMD_DASM	= 0x40,
+	BIF_CMD_DISS	= 0x80,
+	BIF_CMD_DILC	= 0x81,
+	BIF_CMD_DIE0	= 0x84,
+	BIF_CMD_DIE1	= 0x85,
+	BIF_CMD_DIP0	= 0x86,
+	BIF_CMD_DIP1	= 0x87,
+	BIF_CMD_DRES	= 0xC0,
+	BIF_CMD_TQ	= 0xC2,
+	BIF_CMD_AIO	= 0xC4,
+};
+
+/**
+ * struct bif_ddb_l1_data - MIPI defined L1 DDB data structure
+ * @revision:		DDB version; should be 0x10 for DDB v1.0
+ * @level:		DDB level support; should be 0x03 for DDB L1 and L2
+ * @device_class:	MIPI device class; should be 0x0800
+ * @manufacturer_id:	Manufacturer ID number allocated by MIPI
+ * @product_id:		Manufacturer specified product ID number
+ * @length:		Size of L2 function directory in bytes
+ */
+struct bif_ddb_l1_data {
+	u8	revision;
+	u8	level;
+	u16	device_class;
+	u16	manufacturer_id;
+	u16	product_id;
+	u16	length;
+};
+
+/**
+ * struct bif_ddb_l2_data - MIPI defined L2 DDB function data structure
+ * @function_type:	Defines the type of the function.  The type may be
+ *			either MIPI or manufacturer defined.
+ * @function_version:	Defines the version of the function.  The version may
+ *			be either MIPI or manufacturer defined.
+ * @function_pointer:	Address in BIF slave memory where the register map for
+ *			the function begins.
+ */
+struct bif_ddb_l2_data {
+	u8	function_type;
+	u8	function_version;
+	u16	function_pointer;
+};
+
+/**
+ * enum bif_mipi_function_type - MIPI defined DDB L2 function types
+ * %BIF_FUNC_PROTOCOL:		Protocol function which provides access to core
+ *				BIF communication features.
+ * %BIF_FUNC_SLAVE_CONTROL:	Slave control function which provides control
+ *				for BIF slave interrupts and tasks.
+ * %BIF_FUNC_TEMPERATURE:	Temperature sensor function which provides a
+ *				means to accurately read the battery temperature
+ *				in a single-shot or periodic fashion.
+ * %BIF_FUNC_NVM:		Non-volatile memory function which provides a
+ *				means to store data onto a BIF slave that is
+ *				non-volatile.  Secondary slave objects are also
+ *				found through the NVM function.
+ * %BIF_FUNC_AUTHENTICATION:	Authentication function which provides a means
+ *				to authenticate batteries.  This function does
+ *				not have a MIPI defined implimentation.  Instead
+ *				all aspects of the authentication function are
+ *				left to the discretion of the manufacturer.
+ */
+enum bif_mipi_function_type {
+	BIF_FUNC_PROTOCOL	= 0x01,
+	BIF_FUNC_SLAVE_CONTROL	= 0x02,
+	BIF_FUNC_TEMPERATURE	= 0x03,
+	BIF_FUNC_NVM		= 0x04,
+	BIF_FUNC_AUTHENTICATION	= 0x05,
+};
+
+#define BIF_DDB_L1_BASE_ADDR	0x0000
+#define BIF_DDB_L2_BASE_ADDR	0x000A
+
+/**
+ * enum bif_slave_error_code - MIPI defined BIF slave error codes
+ * %BIF_ERR_NONE:		No error occurred
+ * %BIF_ERR_GENERAL:		An unenumerated error occurred
+ * %BIF_ERR_PARITY:		A Hamming-15 parity check failed for a word
+ *				sent on the bus
+ * %BIF_ERR_INVERSION:		More than 8 bits in a word were 1
+ * %BIF_ERR_BAD_LENGTH:		Word had more or less than 17 bits
+ * %BIF_ERR_TIMING:		Bit timing was violated in a word
+ * %BIF_ERR_UNKNOWN_CMD:	Bus command was unknown to the slave
+ * %BIF_ERR_CMD_SEQ:		Commands with ordering dependency were not
+ *				sent in the right order
+ * %BIF_ERR_BUS_COLLISION:	BCL was already low at the beginning of a new
+ *				transaction
+ * %BIF_ERR_SLAVE_BUSY:		Slave is busy and cannot respond
+ * %BIF_ERR_FATAL:		Slave is in an unrecoverable error state and
+ *				must be reset
+ *
+ * These values are present in the ERR portion of an RD or TACK slave response
+ * word.  These values can also be found in the ERR_CODE register of the
+ * protocol function.
+ */
+enum bif_slave_error_code {
+	BIF_ERR_NONE		= 0x00,
+	BIF_ERR_GENERAL		= 0x10,
+	BIF_ERR_PARITY		= 0x11,
+	BIF_ERR_INVERSION	= 0x12,
+	BIF_ERR_BAD_LENGTH	= 0x13,
+	BIF_ERR_TIMING		= 0x14,
+	BIF_ERR_UNKNOWN_CMD	= 0x15,
+	BIF_ERR_CMD_SEQ		= 0x16,
+	BIF_ERR_BUS_COLLISION	= 0x1F,
+	BIF_ERR_SLAVE_BUSY	= 0x20,
+	BIF_ERR_FATAL		= 0x7F,
+};
+
+/**
+ * struct bif_protocol_function - constant data present in protocol function
+ * @l2_entry:		Pointer to protocol function L2 DDB data struct
+ * @protocol_pointer:	BIF slave address where protocol registers begin
+ * @device_id_pointer:	BIF slave address where device ID begins
+ * @device_id:		The 8-byte unique device ID in MSB to LSB order
+ */
+struct bif_protocol_function {
+	struct bif_ddb_l2_data *l2_entry;
+	u16	protocol_pointer;
+	u16	device_id_pointer;
+	u8	device_id[BIF_DEVICE_ID_BYTE_LENGTH]; /* Unique ID */
+};
+
+#define PROTOCOL_FUNC_DEV_ADR_ADDR(protocol_pointer)	((protocol_pointer) + 0)
+#define PROTOCOL_FUNC_ERR_CODE_ADDR(protocol_pointer)	((protocol_pointer) + 2)
+#define PROTOCOL_FUNC_ERR_CNT_ADDR(protocol_pointer)	((protocol_pointer) + 3)
+#define PROTOCOL_FUNC_WORD_CNT_ADDR(protocol_pointer)	((protocol_pointer) + 4)
+
+/**
+ * struct bif_slave_control_function - constant data present in slave control
+ *			function as well internal software state parameters
+ * @l2_entry:		Pointer to slave control function L2 DDB data struct
+ * @slave_ctrl_pointer:	BIF slave address where slave control registers begin
+ * @task_count:		Number of tasks supported by the slave
+ * @irq_notifier_list:	List of notifiers for consumers drivers that wish to be
+ *			notified when any given interrupt triggers.  This list
+ *			is dynamically allocated with length task_count.
+ */
+struct bif_slave_control_function {
+	struct bif_ddb_l2_data		*l2_entry;
+	u16				slave_ctrl_pointer;
+	unsigned int			task_count;
+	struct blocking_notifier_head	*irq_notifier_list;
+};
+
+#define SLAVE_CTRL_TASKS_PER_SET	8
+
+/**
+ * bif_slave_control_task_is_valid() - returns true if the specified task
+ *		is supported by the slave or false if it isn't
+ * @func:	Pointer to slave's slave control function structure
+ * @task:	Slave task number to check
+ */
+static inline bool
+bif_slave_control_task_is_valid(struct bif_slave_control_function *func,
+				unsigned int task)
+{
+	return func ? task < func->task_count : false;
+}
+
+#define SLAVE_CTRL_FUNC_IRQ_EN_ADDR(slave_ctrl_pointer, task) \
+	((slave_ctrl_pointer) + 4 * ((task) / SLAVE_CTRL_TASKS_PER_SET) + 0)
+
+#define SLAVE_CTRL_FUNC_IRQ_STATUS_ADDR(slave_ctrl_pointer, task) \
+	((slave_ctrl_pointer) + 4 * ((task) / SLAVE_CTRL_TASKS_PER_SET) + 1)
+#define SLAVE_CTRL_FUNC_IRQ_CLEAR_ADDR(slave_ctrl_pointer, task) \
+	SLAVE_CTRL_FUNC_IRQ_STATUS_ADDR(slave_ctrl_pointer, task)
+
+#define SLAVE_CTRL_FUNC_TASK_TRIGGER_ADDR(slave_ctrl_pointer, task) \
+	((slave_ctrl_pointer) + 4 * ((task) / SLAVE_CTRL_TASKS_PER_SET) + 2)
+#define SLAVE_CTRL_FUNC_TASK_BUSY_ADDR(slave_ctrl_pointer, task) \
+	SLAVE_CTRL_FUNC_TASK_TRIGGER_ADDR(slave_ctrl_pointer, task)
+
+#define SLAVE_CTRL_FUNC_TASK_AUTO_TRIGGER_ADDR(slave_ctrl_pointer, task) \
+	((slave_ctrl_pointer) + 4 * ((task) / SLAVE_CTRL_TASKS_PER_SET) + 3)
+
+/**
+ * struct bif_temperature_function - constant data present in temperature
+ *				sensor function
+ * @temperatuer_pointer:	BIF slave address where temperature sensor
+ *				control registers begin
+ * @slave_control_channel:	Slave control channel associated with the
+ *				temperature sensor function.  This channel is
+ *				also the task number.
+ * @accuracy_pointer:		BIF slave address where temperature accuracy
+ *				registers begin
+ */
+struct bif_temperature_function {
+	u16	temperature_pointer;
+	u8	slave_control_channel;
+	u16	accuracy_pointer;
+};
+
+/**
+ * enum bif_mipi_object_type - MIPI defined BIF object types
+ * %BIF_OBJ_END_OF_LIST:	Indicates that the end of the object list in
+ *				NVM has been reached
+ * %BIF_OBJ_SEC_SLAVE:		Specifies the UIDs of secondary slaves found
+ *				inside of the battery pack
+ * %BIF_OBJ_BATT_PARAM:		Specifies some variety of battery parameter.
+ *				There is no MIPI defined format for this object
+ *				type so parsing is manufacturer specific.
+ */
+enum bif_mipi_object_type {
+	BIF_OBJ_END_OF_LIST	= 0x00,
+	BIF_OBJ_SEC_SLAVE	= 0x01,
+	BIF_OBJ_BATT_PARAM	= 0x02,
+};
+
+/**
+ * struct bif_object - contains all header and data information for a slave
+ *			data object
+ * @type:		Object type
+ * @version:		Object version
+ * @manufacturer_id:	Manufacturer ID number allocated by MIPI
+ * @length:		Length of the entire object including header and CRC
+ * @data:		Raw byte data found in the object
+ * @crc:		CRC of the object calculated using CRC-CCITT
+ * @list:		Linked-list connection parameter
+ * @addr:		BIF slave address correspond to the start of the object
+ *
+ * manufacturer_id == 0x0000 if MIPI type and version.
+ */
+struct bif_object {
+	u8			type;
+	u8			version;
+	u16			manufacturer_id;
+	u16			length;
+	u8			*data;
+	u16			crc;
+	struct list_head	list;
+	u16			addr;
+};
+
+/**
+ * struct bif_nvm_function - constant data present in non-volatile memory
+ *				function as well internal software state
+ *				parameters
+ * @nvm_pointer:		BIF slave address where NVM registers begin
+ * @slave_control_channel:	Slave control channel associated with the
+ *				NVM function.  This channel is also the task
+ *				number.
+ * @write_buffer_size:		Size in bytes of the NVM write buffer.  0x00
+ *				is used to denote a 256 byte buffer.
+ * @nvm_base_address:		BIF slave address where NVM begins
+ * @nvm_size:			NVM size in bytes
+ * @object_count:		Number of BIF objects read from NVM
+ * @object_list:		List of BIF objects read from NVM
+ */
+struct bif_nvm_function {
+	u16			nvm_pointer;
+	u8			slave_control_channel;
+	u8			write_buffer_size;
+	u16			nvm_base_address;
+	u16			nvm_size;
+	int			object_count;
+	struct list_head	object_list;
+};
+
+/**
+ * struct bif_ctrl - Opaque handle for a BIF controller to be used in bus
+ *			oriented BIF function calls.
+ */
+struct bif_ctrl;
+
+/**
+ * struct bif_slave - Opaque handle for a BIF slave to be used in slave oriented
+ *			BIF function calls.
+ */
+struct bif_slave;
+
+/**
+ * enum bif_bus_state - indicates the current or desired state of the BIF bus
+ * %BIF_BUS_STATE_MASTER_DISABLED:	BIF host hardware is disabled
+ * %BIF_BUS_STATE_POWER_DOWN:		BIF bus is in power down state and
+ *					BCL is not being pulled high
+ * %BIF_BUS_STATE_STANDBY:		BIF slaves are in standby state in which
+ *					less power is drawn
+ * %BIF_BUS_STATE_ACTIVE:		BIF slaves are ready for immediate
+ *					communications
+ * %BIF_BUS_STATE_INTERRUPT:		BIF bus is active, but no communication
+ *					is possible.  Instead, either one of the
+ *					slaves or the master must transition to
+ *					active state by pulling BCL low for 1
+ *					tau bif period.
+ */
+enum bif_bus_state {
+	BIF_BUS_STATE_MASTER_DISABLED,
+	BIF_BUS_STATE_POWER_DOWN,
+	BIF_BUS_STATE_STANDBY,
+	BIF_BUS_STATE_ACTIVE,
+	BIF_BUS_STATE_INTERRUPT,
+};
+
+/**
+ * enum bif_bus_event - events that the BIF framework may send to BIF consumers
+ * %BIF_BUS_EVENT_BATTERY_INSERTED:	Indicates that a battery was just
+ *					inserted physically or that the BIF
+ *					host controller for the battery just
+ *					probed and a battery was already
+ *					present.
+ * %BIF_BUS_EVENT_BATTERY_REMOVED:	Indicates that a battery was just
+ *					removed and thus its slaves are no
+ *					longer accessible.
+ */
+enum bif_bus_event {
+	BIF_BUS_EVENT_BATTERY_INSERTED,
+	BIF_BUS_EVENT_BATTERY_REMOVED,
+};
+
+/* Mask values to be ORed together for use in bif_match_criteria.match_mask. */
+#define BIF_MATCH_MANUFACTURER_ID	BIT(0)
+#define BIF_MATCH_PRODUCT_ID		BIT(1)
+#define BIF_MATCH_FUNCTION_TYPE		BIT(2)
+#define BIF_MATCH_FUNCTION_VERSION	BIT(3)
+#define BIF_MATCH_IGNORE_PRESENCE	BIT(4)
+
+/**
+ * struct bif_match_criteria - specifies the matching criteria that a BIF
+ *			consumer uses to find an appropriate BIF slave
+ * @match_mask:		Mask value specifying which parameters to match upon.
+ *			This value should be some ORed combination of
+ *			BIF_MATCH_* specified above.
+ * @manufacturer_id:	Manufacturer ID number allocated by MIPI
+ * @product_id:		Manufacturer specified product ID number
+ * @function_type:	Defines the type of the function.  The type may be
+ *			either MIPI or manufacturer defined.
+ * @function_version:	Defines the version of the function.  The version may
+ *			be either MIPI or manufacturer defined.
+ * @ignore_presence:	If true, then slaves that are currently not present
+ *			will be successfully matched against.  By default, only
+ *			present slaves can be matched.
+ */
+struct bif_match_criteria {
+	u32	match_mask;
+	u16	manufacturer_id;
+	u16	product_id;
+	u8	function_type;
+	u8	function_version;
+	bool	ignore_presence;
+};
+
+/**
+ * bif_battery_rid_ranges - MIPI-BIF defined Rid battery pack resistance ranges
+ * %BIF_BATT_RID_SPECIAL1_MIN:	Minimum Rid for special case 1
+ * %BIF_BATT_RID_SPECIAL1_MAX:	Maximum Rid for special case 1
+ * %BIF_BATT_RID_SPECIAL2_MIN:	Minimum Rid for special case 2
+ * %BIF_BATT_RID_SPECIAL2_MAX:	Maximum Rid for special case 2
+ * %BIF_BATT_RID_SPECIAL3_MIN:	Minimum Rid for special case 3
+ * %BIF_BATT_RID_SPECIAL3_MAX:	Maximum Rid for special case 3
+ * %BIF_BATT_RID_LOW_COST_MIN:	Minimum Rid for a low cost battery pack
+ * %BIF_BATT_RID_LOW_COST_MAX:	Maximum Rid for a low cost battery pack
+ * %BIF_BATT_RID_SMART_MIN:	Minimum Rid for a smart battery pack
+ * %BIF_BATT_RID_SMART_MAX:	Maximum Rid for a smart battery pack
+ */
+enum bif_battery_rid_ranges {
+	BIF_BATT_RID_SPECIAL1_MIN	= 0,
+	BIF_BATT_RID_SPECIAL1_MAX	= 1,
+	BIF_BATT_RID_SPECIAL2_MIN	= 7350,
+	BIF_BATT_RID_SPECIAL2_MAX	= 7650,
+	BIF_BATT_RID_SPECIAL3_MIN	= 12740,
+	BIF_BATT_RID_SPECIAL3_MAX	= 13260,
+	BIF_BATT_RID_LOW_COST_MIN	= 19600,
+	BIF_BATT_RID_LOW_COST_MAX	= 140000,
+	BIF_BATT_RID_SMART_MIN		= 240000,
+	BIF_BATT_RID_SMART_MAX		= 450000,
+};
+
+#ifdef CONFIG_BIF
+
+int bif_request_irq(struct bif_slave *slave, unsigned int task,
+			struct notifier_block *nb);
+int bif_free_irq(struct bif_slave *slave, unsigned int task,
+			struct notifier_block *nb);
+
+int bif_trigger_task(struct bif_slave *slave, unsigned int task);
+int bif_task_is_busy(struct bif_slave *slave, unsigned int task);
+
+int bif_ctrl_count(void);
+struct bif_ctrl *bif_ctrl_get_by_id(unsigned int id);
+struct bif_ctrl *bif_ctrl_get(struct device *consumer_dev);
+void bif_ctrl_put(struct bif_ctrl *ctrl);
+
+int bif_ctrl_signal_battery_changed(struct bif_ctrl *ctrl);
+
+int bif_slave_match_count(const struct bif_ctrl *ctrl,
+			const struct bif_match_criteria *match_criteria);
+
+struct bif_slave *bif_slave_match_get(const struct bif_ctrl *ctrl,
+	unsigned int id, const struct bif_match_criteria *match_criteria);
+
+void bif_slave_put(struct bif_slave *slave);
+
+int bif_ctrl_notifier_register(struct bif_ctrl *ctrl,
+				struct notifier_block *nb);
+
+int bif_ctrl_notifier_unregister(struct bif_ctrl *ctrl,
+				struct notifier_block *nb);
+
+struct bif_ctrl *bif_get_ctrl_handle(struct bif_slave *slave);
+
+int bif_slave_find_function(struct bif_slave *slave, u8 function, u8 *version,
+				u16 *function_pointer);
+
+int bif_slave_read(struct bif_slave *slave, u16 addr, u8 *buf, int len);
+int bif_slave_write(struct bif_slave *slave, u16 addr, u8 *buf, int len);
+
+int bif_slave_is_present(struct bif_slave *slave);
+
+int bif_slave_is_selected(struct bif_slave *slave);
+int bif_slave_select(struct bif_slave *slave);
+
+int bif_ctrl_raw_transaction(struct bif_ctrl *ctrl, int transaction, u8 data);
+int bif_ctrl_raw_transaction_read(struct bif_ctrl *ctrl, int transaction,
+					u8 data, int *response);
+int bif_ctrl_raw_transaction_query(struct bif_ctrl *ctrl, int transaction,
+		u8 data, bool *query_response);
+
+void bif_ctrl_bus_lock(struct bif_ctrl *ctrl);
+void bif_ctrl_bus_unlock(struct bif_ctrl *ctrl);
+
+u16 bif_crc_ccitt(const u8 *buffer, unsigned int len);
+
+int bif_ctrl_measure_rid(struct bif_ctrl *ctrl);
+int bif_ctrl_get_bus_period(struct bif_ctrl *ctrl);
+int bif_ctrl_set_bus_period(struct bif_ctrl *ctrl, int period_ns);
+int bif_ctrl_get_bus_state(struct bif_ctrl *ctrl);
+int bif_ctrl_set_bus_state(struct bif_ctrl *ctrl, enum bif_bus_state state);
+
+#else
+
+static inline int bif_request_irq(struct bif_slave *slave, unsigned int task,
+			struct notifier_block *nb) { return -EPERM; }
+static inline int bif_free_irq(struct bif_slave *slave, unsigned int task,
+			struct notifier_block *nb) { return -EPERM; }
+
+static inline int bif_trigger_task(struct bif_slave *slave, unsigned int task)
+{ return -EPERM; }
+static inline int bif_task_is_busy(struct bif_slave *slave, unsigned int task)
+{ return -EPERM; }
+
+static inline int bif_ctrl_count(void) { return -EPERM; }
+static inline struct bif_ctrl *bif_ctrl_get_by_id(unsigned int id)
+{ return ERR_PTR(-EPERM); }
+struct bif_ctrl *bif_ctrl_get(struct device *consumer_dev)
+{ return ERR_PTR(-EPERM); }
+static inline void bif_ctrl_put(struct bif_ctrl *ctrl) { return; }
+
+int bif_ctrl_signal_battery_changed(struct bif_ctrl *ctrl) { return -EPERM; }
+
+static inline int bif_slave_match_count(const struct bif_ctrl *ctrl,
+			const struct bif_match_criteria *match_criteria)
+{ return -EPERM; }
+
+static inline struct bif_slave *bif_slave_match_get(const struct bif_ctrl *ctrl,
+	unsigned int id, const struct bif_match_criteria *match_criteria)
+{ return ERR_PTR(-EPERM); }
+
+static inline void bif_slave_put(struct bif_slave *slave) { return; }
+
+static inline int bif_ctrl_notifier_register(struct bif_ctrl *ctrl,
+				struct notifier_block *nb)
+{ return -EPERM; }
+
+static inline int bif_ctrl_notifier_unregister(struct bif_ctrl *ctrl,
+				struct notifier_block *nb)
+{ return -EPERM; }
+
+static inline struct bif_ctrl *bif_get_ctrl_handle(struct bif_slave *slave)
+{ return ERR_PTR(-EPERM); }
+
+static inline int bif_slave_find_function(struct bif_slave *slave, u8 function,
+				u8 *version, u16 *function_pointer)
+{ return -EPERM; }
+
+static inline int bif_slave_read(struct bif_slave *slave, u16 addr, u8 *buf,
+				int len)
+{ return -EPERM; }
+static inline int bif_slave_write(struct bif_slave *slave, u16 addr, u8 *buf,
+				int len)
+{ return -EPERM; }
+
+int bif_slave_is_present(struct bif_slave *slave) { return -EPERM; }
+
+int bif_slave_is_selected(struct bif_slave *slave) { return -EPERM; }
+int bif_slave_select(struct bif_slave *slave) { return -EPERM; }
+
+int bif_ctrl_raw_transaction(struct bif_ctrl *ctrl, int transaction, u8 data)
+{ return -EPERM; }
+int bif_ctrl_raw_transaction_read(struct bif_ctrl *ctrl, int transaction,
+					u8 data, int *response)
+{ return -EPERM; }
+int bif_ctrl_raw_transaction_query(struct bif_ctrl *ctrl, int transaction,
+		u8 data, bool *query_response)
+{ return -EPERM; }
+
+static inline void bif_ctrl_bus_lock(struct bif_ctrl *ctrl)
+{ return -EPERM; }
+static inline void bif_ctrl_bus_unlock(struct bif_ctrl *ctrl)
+{ return -EPERM; }
+
+static inline u16 bif_crc_ccitt(const u8 *buffer, unsigned int len)
+{ return 0; }
+
+static inline int bif_ctrl_measure_rid(struct bif_ctrl *ctrl) { return -EPERM; }
+int bif_ctrl_get_bus_period(struct bif_ctrl *ctrl) { return -EPERM; }
+int bif_ctrl_set_bus_period(struct bif_ctrl *ctrl, int period_ns)
+{ return -EPERM; }
+int bif_ctrl_get_bus_state(struct bif_ctrl *ctrl) { return -EPERM; }
+int bif_ctrl_set_bus_state(struct bif_ctrl *ctrl, enum bif_bus_state state)
+{ return -EPERM; }
+
+#endif
+
+#endif
diff --git a/include/linux/bif/driver.h b/include/linux/bif/driver.h
new file mode 100644
index 0000000..184d46f
--- /dev/null
+++ b/include/linux/bif/driver.h
@@ -0,0 +1,161 @@
+/* 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 _LINUX_BIF_DRIVER_H_
+#define _LINUX_BIF_DRIVER_H_
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/types.h>
+#include <linux/bif/consumer.h>
+
+/**
+ * struct bif_ctrl_dev - opaque handle used to identify a given BIF controller
+ *			device
+ */
+struct bif_ctrl_dev;
+
+/**
+ * struct bif_ctrl_ops - BIF operations which may be implemented by BIF
+ *				controller drivers
+ * @bus_transaction:		Perform the specified BIF transaction which does
+ *				not result in any slave response.
+ * @bus_transaction_query:	Perform the specified BIF transaction which
+ *				expects a BQ response in the case of slave
+ *				positive acknowledgement.
+ * @bus_transaction_read:	Perform the specified BIF transaction which
+ *				expects an RD or TACK response from the selected
+ *				slave.
+ * @read_slave_registers:	Perform all BIF transactions necessary to read
+ *				the specified set of contiguous registers from
+ *				the previously selected slave.  This operation
+ *				is used to optimize the common case of slave
+ *				register reads since the a BIF controller driver
+ *				can take advantage of BIF burst reads while the
+ *				BIF core driver cannot due to the inherient
+ *				tight timing requirements.
+ * @write_slave_registers:	Perform all BIF transactions necessary to write
+ *				the specified set of contiguous registers to
+ *				the previously selected slave.  This operation
+ *				is used to optimize the common case of slave
+ *				register writes since the a BIF controller
+ *				driver can remove redundant steps when
+ *				performing several WD commands in a row.
+ * @get_bus_period:		Return the tau_bif BIF bus clock period in
+ *				nanoseconds.
+ * @set_bus_period:		Set the tau_bif BIF bus clock period in
+ *				nanoseconds.  If the exact period is not
+ *				supported by the BIF controller hardware, then
+ *				the next larger supported period should be used.
+ * @get_battery_presence:	Return the current state of the battery pack.
+ *				If a battery pack is present, then return >= 1.
+ *				If a battery pack is not present, then return 0.
+ *				If an error occurs during presence detection,
+ *				then return errno.
+ * @get_battery_rid:		Return the measured value of the Rid battery
+ *				pack pull-down resistor in ohms.
+ * @get_bus_state:		Return the current bus state as defined by one
+ *				of the enum bif_bus_state values.
+ * @set_bus_state:		Set the BIF bus state to the specified enum
+ *				bif_bus_state value.
+ *
+ * The following operations must be defined by every BIF controller driver in
+ * order to ensure baseline functionality:
+ * bus_transaction, bus_transaction_query, get_bus_state, and set_bus_state.
+ *
+ * The BIF core driver is unaware of BIF transaction timing constraints.  A
+ * given BIF controller driver must ensure that all timing constraints in the
+ * MIPI-BIF specification are met as transactions are carried out.
+ *
+ * Conversion between 11-bit and 17-bit BIF words (i.e. the insertion of BCF_n,
+ * parity bits, and the inversion bit) must be handled inside of the BIF
+ * controller driver (either in software or hardware).  This guarantees maximum
+ * performance if hardware support is available.
+ *
+ * The bus_transaction_read operation must return -ETIMEDOUT in the case of no
+ * RD or TACK word received.  This allows the transaction query, TQ, command
+ * to be used for slave selection verification.
+ *
+ * It is acceptable for the BIF bus state to be changed autonomously by a BIF
+ * controller driver in response to low level bus actions without a call to
+ * set_bus_state.  One example is the case of receiving a slave interrupt
+ * while in interrupt state as this intrinsically causes the bus to enter the
+ * active communication state.
+ */
+struct bif_ctrl_ops {
+	int (*bus_transaction) (struct bif_ctrl_dev *bdev, int transaction,
+					u8 data);
+	int (*bus_transaction_query) (struct bif_ctrl_dev *bdev,
+					int transaction, u8 data,
+					bool *query_response);
+	int (*bus_transaction_read) (struct bif_ctrl_dev *bdev,
+					int transaction, u8 data,
+					int *response);
+	int (*read_slave_registers) (struct bif_ctrl_dev *bdev, u16 addr,
+					u8 *data, int len);
+	int (*write_slave_registers) (struct bif_ctrl_dev *bdev, u16 addr,
+					const u8 *data, int len);
+	int (*get_bus_period) (struct bif_ctrl_dev *bdev);
+	int (*set_bus_period) (struct bif_ctrl_dev *bdev, int period_ns);
+	int (*get_battery_presence) (struct bif_ctrl_dev *bdev);
+	int (*get_battery_rid) (struct bif_ctrl_dev *bdev);
+	int (*get_bus_state) (struct bif_ctrl_dev *bdev);
+	int (*set_bus_state) (struct bif_ctrl_dev *bdev, int state);
+};
+
+/**
+ * struct bif_ctrl_desc - BIF bus controller descriptor
+ * @name:		Name used to identify the BIF controller
+ * @ops:		BIF operations supported by the BIF controller
+ * @bus_clock_min_ns:	Minimum tau_bif BIF bus clock period supported by the
+ *			BIF controller
+ * @bus_clock_max_ns:	Maximum tau_bif BIF bus clock period supported by the
+ *			BIF controller
+ *
+ * Each BIF controller registered with the BIF core is described with a
+ * structure of this type.
+ */
+struct bif_ctrl_desc {
+	const char *name;
+	struct bif_ctrl_ops *ops;
+	int bus_clock_min_ns;
+	int bus_clock_max_ns;
+};
+
+#ifdef CONFIG_BIF
+
+struct bif_ctrl_dev *bif_ctrl_register(struct bif_ctrl_desc *bif_desc,
+	struct device *dev, void *driver_data, struct device_node *of_node);
+
+void bif_ctrl_unregister(struct bif_ctrl_dev *bdev);
+
+void *bdev_get_drvdata(struct bif_ctrl_dev *bdev);
+
+int bif_ctrl_notify_battery_changed(struct bif_ctrl_dev *bdev);
+int bif_ctrl_notify_slave_irq(struct bif_ctrl_dev *bdev);
+
+#else
+
+static inline struct bif_ctrl_dev *bif_ctrl_register(
+	struct bif_ctrl_desc *bif_desc, struct device *dev, void *driver_data,
+	struct device_node *of_node)
+{ return ERR_PTR(-EINVAL); }
+
+static inline void bif_ctrl_unregister(struct bif_ctrl_dev *bdev) { }
+
+static inline void *bdev_get_drvdata(struct bif_ctrl_dev *bdev) { return NULL; }
+
+int bif_ctrl_notify_slave_irq(struct bif_ctrl_dev *bdev) { return -EINVAL; }
+
+#endif
+
+#endif
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 9c49d17..2b4542a 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -135,7 +135,7 @@
 				 * throttling rules. Don't do it again. */
 
 	/* request only flags */
-	__REQ_SORTED,		/* elevator knows about this request */
+	__REQ_SORTED = __REQ_RAHEAD, /* elevator knows about this request */
 	__REQ_SOFTBARRIER,	/* may not be passed by ioscheduler */
 	__REQ_NOMERGE,		/* don't touch this for merging */
 	__REQ_STARTED,		/* drive already may have started this one */
@@ -151,6 +151,7 @@
 	__REQ_IO_STAT,		/* account I/O stat */
 	__REQ_MIXED_MERGE,	/* merge of different types, fail separately */
 	__REQ_SANITIZE,		/* sanitize */
+	__REQ_URGENT,		/* urgent request */
 	__REQ_NR_BITS,		/* stops here */
 };
 
@@ -163,6 +164,7 @@
 #define REQ_PRIO		(1 << __REQ_PRIO)
 #define REQ_DISCARD		(1 << __REQ_DISCARD)
 #define REQ_SANITIZE		(1 << __REQ_SANITIZE)
+#define REQ_URGENT		(1 << __REQ_URGENT)
 #define REQ_NOIDLE		(1 << __REQ_NOIDLE)
 
 #define REQ_FAILFAST_MASK \
diff --git a/include/linux/bma150.h b/include/linux/bma150.h
index a3d1c4f..d62a4d9 100644
--- a/include/linux/bma150.h
+++ b/include/linux/bma150.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/include/linux/coresight-cti.h b/include/linux/coresight-cti.h
new file mode 100644
index 0000000..7f2da3f
--- /dev/null
+++ b/include/linux/coresight-cti.h
@@ -0,0 +1,59 @@
+/* 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 _LINUX_CORESIGHT_CTI_H
+#define _LINUX_CORESIGHT_CTI_H
+
+struct coresight_cti_data {
+	int nr_ctis;
+	const char **names;
+};
+
+struct coresight_cti {
+	const char *name;
+	struct list_head link;
+};
+
+#ifdef CONFIG_CORESIGHT_CTI
+extern struct coresight_cti *coresight_cti_get(const char *name);
+extern void coresight_cti_put(struct coresight_cti *cti);
+extern int coresight_cti_map_trigin(
+			struct coresight_cti *cti, int trig, int ch);
+extern int coresight_cti_map_trigout(
+			struct coresight_cti *cti, int trig, int ch);
+extern void coresight_cti_unmap_trigin(
+			struct coresight_cti *cti, int trig, int ch);
+extern void coresight_cti_unmap_trigout(
+			struct coresight_cti *cti, int trig, int ch);
+#else
+static inline struct coresight_cti *coresight_cti_get(const char *name)
+{
+	return NULL;
+}
+static inline void coresight_cti_put(struct coresight_cti *cti) {}
+static inline int coresight_cti_map_trigin(
+			struct coresight_cti *cti, int trig, int ch)
+{
+	return -ENOSYS;
+}
+static inline int coresight_cti_map_trigout(
+			struct coresight_cti *cti, int trig, int ch)
+{
+	return -ENOSYS;
+}
+static inline void coresight_cti_unmap_trigin(
+			struct coresight_cti *cti, int trig, int ch) {}
+static inline void coresight_cti_unmap_trigout(
+			struct coresight_cti *cti, int trig, int ch) {}
+#endif
+
+#endif
diff --git a/include/linux/coresight-stm.h b/include/linux/coresight-stm.h
index b156eba..3f35dd9 100644
--- a/include/linux/coresight-stm.h
+++ b/include/linux/coresight-stm.h
@@ -36,7 +36,7 @@
 #define stm_log(entity_id, data, size)					\
 	stm_log_inv_ts(entity_id, 0, data, size)
 
-#ifdef CONFIG_MSM_QDSS
+#ifdef CONFIG_CORESIGHT_STM
 extern int stm_trace(uint32_t options, uint8_t entity_id, uint8_t proto_id,
 		     const void *data, uint32_t size);
 #else
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 0bdacffa..cfc690e 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.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
@@ -30,7 +30,11 @@
 #define CORESIGHT_COMPIDR2	(0xFF8)
 #define CORESIGHT_COMPIDR3	(0xFFC)
 
+#define ETM_ARCH_V1_0		(0x00)
+#define ETM_ARCH_V1_2		(0x02)
 #define ETM_ARCH_V3_3		(0x23)
+#define ETM_ARCH_V3_5		(0x25)
+#define PFT_ARCH_MAJOR		(0x30)
 #define PFT_ARCH_V1_1		(0x31)
 
 enum coresight_clk_rate {
@@ -147,7 +151,7 @@
 	const struct coresight_ops_source *source_ops;
 };
 
-#ifdef CONFIG_MSM_QDSS
+#ifdef CONFIG_CORESIGHT
 extern struct coresight_device *
 coresight_register(struct coresight_desc *desc);
 extern void coresight_unregister(struct coresight_device *csdev);
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index 6c26a3d..5ab7183 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -57,6 +57,7 @@
 
 /* Idle State Flags */
 #define CPUIDLE_FLAG_TIME_VALID	(0x01) /* is residency time measurable? */
+#define CPUIDLE_FLAG_COUPLED	(0x02) /* state applies to multiple cpus */
 
 #define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000)
 
@@ -100,6 +101,12 @@
 	struct list_head 	device_list;
 	struct kobject		kobj;
 	struct completion	kobj_unregister;
+
+#ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
+	int			safe_state_index;
+	cpumask_t		coupled_cpus;
+	struct cpuidle_coupled	*coupled;
+#endif
 };
 
 DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
@@ -176,6 +183,10 @@
 
 #endif
 
+#ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
+void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev, atomic_t *a);
+#endif
+
 /******************************
  * CPUIDLE GOVERNOR INTERFACE *
  ******************************/
diff --git a/include/linux/diagchar.h b/include/linux/diagchar.h
index 43daaf2..7a5ab0d 100644
--- a/include/linux/diagchar.h
+++ b/include/linux/diagchar.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
@@ -112,10 +112,10 @@
 /* This needs to be modified manually now, when we add
  a new RANGE of SSIDs to the msg_mask_tbl */
 #define MSG_MASK_TBL_CNT		24
-#define EVENT_LAST_ID			0x08C5
+#define EVENT_LAST_ID			0x09AB
 
 #define MSG_SSID_0			0
-#define MSG_SSID_0_LAST			93
+#define MSG_SSID_0_LAST			94
 #define MSG_SSID_1			500
 #define MSG_SSID_1_LAST			506
 #define MSG_SSID_2			1000
@@ -135,7 +135,7 @@
 #define MSG_SSID_9			5500
 #define MSG_SSID_9_LAST			5516
 #define MSG_SSID_10			6000
-#define MSG_SSID_10_LAST		6072
+#define MSG_SSID_10_LAST		6080
 #define MSG_SSID_11			6500
 #define MSG_SSID_11_LAST		6521
 #define MSG_SSID_12			7000
@@ -159,7 +159,7 @@
 #define MSG_SSID_21			10300
 #define MSG_SSID_21_LAST		10300
 #define MSG_SSID_22			10350
-#define MSG_SSID_22_LAST		10361
+#define MSG_SSID_22_LAST		10374
 #define MSG_SSID_23			0xC000
 #define MSG_SSID_23_LAST		0xC063
 
@@ -278,6 +278,9 @@
 	MSG_LVL_LOW,
 	MSG_LVL_MED,
 	MSG_LVL_LOW,
+	MSG_LVL_LOW,
+	MSG_LVL_LOW,
+	MSG_LVL_HIGH,
 	MSG_LVL_LOW
 };
 
@@ -525,6 +528,14 @@
 	MSG_LVL_MED,
 	MSG_LVL_MED,
 	MSG_LVL_MED,
+	MSG_LVL_LOW,
+	MSG_LVL_LOW,
+	MSG_LVL_LOW,
+	MSG_LVL_LOW,
+	MSG_LVL_LOW,
+	MSG_LVL_LOW,
+	MSG_LVL_LOW,
+	MSG_LVL_LOW,
 	MSG_LVL_LOW
 };
 
@@ -686,13 +697,26 @@
 	MSG_LVL_LOW,
 	MSG_LVL_LOW,
 	MSG_LVL_LOW,
+	MSG_LVL_LOW,
+	MSG_LVL_LOW,
+	MSG_LVL_LOW,
+	MSG_LVL_LOW,
+	MSG_LVL_LOW,
+	MSG_LVL_LOW,
+	MSG_LVL_LOW,
+	MSG_LVL_LOW,
+	MSG_LVL_LOW,
+	MSG_LVL_LOW,
+	MSG_LVL_LOW,
+	MSG_LVL_LOW,
+	MSG_LVL_LOW,
 	MSG_LVL_LOW
 };
 
 /* LOG CODES */
 
 #define LOG_0	0x0
-#define LOG_1	0x1636
+#define LOG_1	0x1755
 #define LOG_2	0x0
 #define LOG_3	0x0
 #define LOG_4	0x4910
diff --git a/include/linux/dma-contiguous.h b/include/linux/dma-contiguous.h
index 2f303e4..8a1b3a1 100644
--- a/include/linux/dma-contiguous.h
+++ b/include/linux/dma-contiguous.h
@@ -65,11 +65,37 @@
  */
 #define MAX_CMA_AREAS	(1 + CONFIG_CMA_AREAS)
 
-extern struct cma *dma_contiguous_default_area;
+extern struct cma *dma_contiguous_def_area;
 
 void dma_contiguous_reserve(phys_addr_t addr_limit);
-int dma_declare_contiguous(struct device *dev, unsigned long size,
-			   phys_addr_t base, phys_addr_t limit);
+
+int dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t *res_base,
+				  phys_addr_t limit, const char *name);
+
+int dma_contiguous_add_device(struct device *dev, phys_addr_t base);
+
+/**
+ * dma_declare_contiguous() - reserve area for contiguous memory handling
+ *			      for particular device
+ * @dev:   Pointer to device structure.
+ * @size:  Size of the reserved memory.
+ * @base:  Start address of the reserved memory (optional, 0 for any).
+ * @limit: End address of the reserved memory (optional, 0 for any).
+ *
+ * This function reserves memory for specified device. It should be
+ * called by board specific code when early allocator (memblock or bootmem)
+ * is still activate.
+ */
+
+static inline int dma_declare_contiguous(struct device *dev, phys_addr_t size,
+					 phys_addr_t base, phys_addr_t limit)
+{
+	int ret;
+	ret = dma_contiguous_reserve_area(size, &base, limit, NULL);
+	if (ret == 0)
+		ret = dma_contiguous_add_device(dev, base);
+	return ret;
+}
 
 struct page *dma_alloc_from_contiguous(struct device *dev, int count,
 				       unsigned int order);
@@ -83,7 +109,7 @@
 static inline void dma_contiguous_reserve(phys_addr_t limit) { }
 
 static inline
-int dma_declare_contiguous(struct device *dev, unsigned long size,
+int dma_declare_contiguous(struct device *dev, phys_addr_t size,
 			   phys_addr_t base, phys_addr_t limit)
 {
 	return -ENOSYS;
diff --git a/include/linux/dvb/dmx.h b/include/linux/dvb/dmx.h
index 257e069..2cea256 100644
--- a/include/linux/dvb/dmx.h
+++ b/include/linux/dvb/dmx.h
@@ -5,7 +5,7 @@
  *                  & Ralph  Metzler <ralph@convergence.de>
  *                    for convergence integrated media GmbH
  *
- * Copyright (c) 2012, Code Aurora Forum. 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 Lesser General Public License
@@ -39,6 +39,8 @@
 /* Min recording chunk upon which event is generated */
 #define DMX_REC_BUFF_CHUNK_MIN_SIZE		(100*188)
 
+#define DMX_MAX_DECODER_BUFFER_NUM		(32)
+
 typedef enum
 {
 	DMX_OUT_DECODER, /* Streaming directly to decoder. */
@@ -205,7 +207,10 @@
 	DMX_EVENT_SECTION_CRC_ERROR,
 
 	/* End-of-stream, no more data from this filter */
-	DMX_EVENT_EOS
+	DMX_EVENT_EOS,
+
+	/* New Elementary Stream data is ready */
+	DMX_EVENT_NEW_ES_DATA
 };
 
 /* Flags passed in filter events */
@@ -214,7 +219,7 @@
 #define DMX_FILTER_CC_ERROR			0x01
 
 /* Discontinuity indicator was set */
-#define DMX_FILTER_DISCONTINUITY_INDEICATOR	0x02
+#define DMX_FILTER_DISCONTINUITY_INDICATOR	0x02
 
 /* PES legnth in PES header is not correct */
 #define DMX_FILTER_PES_LENGTH_ERROR		0x04
@@ -244,6 +249,18 @@
 
 	/* Flags passed in filter events */
 	__u32 flags;
+
+	/*
+	 * Number of TS packets with Transport Error Indicator (TEI)
+	 * found while constructing the PES.
+	 */
+	__u32 transport_error_indicator_counter;
+
+	/* Number of continuity errors found while constructing the PES */
+	__u32 continuity_error_counter;
+
+	/* Total number of TS packets holding the PES */
+	__u32 ts_packets_num;
 };
 
 /* Section info associated with DMX_EVENT_NEW_SECTION event */
@@ -293,6 +310,57 @@
 };
 
 /*
+ * Elementary stream data information associated
+ * with DMX_EVENT_NEW_ES_DATA event
+ */
+struct dmx_es_data_event_info {
+	/* Buffer user-space handle */
+	int buf_handle;
+
+	/*
+	 * Cookie to provide when releasing the buffer
+	 * using the DMX_RELEASE_DECODER_BUFFER ioctl command
+	 */
+	int cookie;
+
+	/* Offset of data from the beginning of the buffer */
+	__u32 offset;
+
+	/* Length of data in buffer (in bytes) */
+	__u32 data_len;
+
+	/* Indication whether PTS value is valid */
+	int pts_valid;
+
+	/* PTS value associated with the buffer */
+	__u64 pts;
+
+	/* Indication whether DTS value is valid */
+	int dts_valid;
+
+	/* DTS value associated with the buffer */
+	__u64 dts;
+
+	/*
+	 * Number of TS packets with Transport Error Indicator (TEI) set
+	 * in the TS packet header since last reported event
+	 */
+	__u32 transport_error_indicator_counter;
+
+	/* Number of continuity errors since last reported event */
+	__u32 continuity_error_counter;
+
+	/* Total number of TS packets processed since last reported event */
+	__u32 ts_packets_num;
+
+	/*
+	 * Number of dropped bytes due to insufficient buffer space,
+	 * since last reported event
+	 */
+	__u32 ts_dropped_bytes;
+};
+
+/*
  * Filter's event returned through DMX_GET_EVENT.
  * poll with POLLPRI would block until events are available.
  */
@@ -304,6 +372,7 @@
 		struct dmx_section_event_info section;
 		struct dmx_rec_chunk_event_info recording_chunk;
 		struct dmx_pcr_event_info pcr;
+		struct dmx_es_data_event_info es_data;
 	} params;
 };
 
@@ -314,13 +383,27 @@
 
 	/* Maximum buffer size allowed */
 	__u32 max_size;
+
+	/* Maximum number of linear buffers handled by demux */
+	__u32 max_buffer_num;
+
+	/* Feature support bitmap as detailed below */
 	__u32 flags;
 
-/* Buffer allocated as physically contiguous memory */
-#define DMX_BUFFER_CONTIGEOUS_MEM			0x1
+/* Buffer must be allocated as physically contiguous memory */
+#define DMX_BUFFER_CONTIGUOUS_MEM		0x1
 
 /* If the filter's data is decrypted, the buffer should be secured one */
 #define DMX_BUFFER_SECURED_IF_DECRYPTED		0x2
+
+/* Buffer can be allocated externally */
+#define DMX_BUFFER_EXTERNAL_SUPPORT		0x4
+
+/* Buffer can be allocated internally */
+#define DMX_BUFFER_INTERNAL_SUPPORT		0x8
+
+/* Filter output can be output to a linear buffer group */
+#define DMX_BUFFER_LINEAR_GROUP_SUPPORT		0x10
 };
 
 typedef struct dmx_caps {
@@ -385,6 +468,9 @@
 	/* For PES not sent to decoder */
 	struct dmx_buffer_requirement pes;
 
+	/* For PES sent to decoder */
+	struct dmx_buffer_requirement decoder;
+
 	/* Recording buffer for recording of 188 bytes packets */
 	struct dmx_buffer_requirement recording_188_tsp;
 
@@ -438,9 +524,9 @@
 };
 
 struct dmx_stc {
-	unsigned int num;	/* input : which STC? 0..N */
-	unsigned int base;	/* output: divisor for stc to get 90 kHz clock */
-	__u64 stc;		/* output: stc in 'base'*90 kHz units */
+	unsigned int num; /* input : which STC? 0..N */
+	unsigned int base; /* output: divisor for stc to get 90 kHz clock */
+	__u64 stc; /* output: stc in 'base'*90 kHz units */
 };
 
 enum dmx_buffer_mode {
@@ -466,6 +552,41 @@
 	int handle;
 };
 
+
+struct dmx_decoder_buffers {
+	/*
+	 * Specify if linear buffer support is requested. If set, buffers_num
+	 * must be greater than 1
+	 */
+	int is_linear;
+
+	/*
+	 * Specify number of external buffers allocated by user.
+	 * If set to 0 means internal buffer allocation is requested
+	 */
+	__u32 buffers_num;
+
+	/* Specify buffer size, either external or internal */
+	__u32 buffers_size;
+
+	/* Array of externally allocated buffer handles */
+	int handles[DMX_MAX_DECODER_BUFFER_NUM];
+};
+
+struct dmx_secure_mode {
+	/*
+	 * Specifies whether secure mode should be set or not for the filter's
+	 * pid. Note that DMX_OUT_TSDEMUX_TAP filters can have more than 1 pid
+	 */
+	int is_secured;
+
+	/* PID to associate with key ladder id */
+	__u16 pid;
+
+	/* key ladder information to associate with the specified pid */
+	__u32 key_ladder_id;
+};
+
 #define DMX_START                _IO('o', 41)
 #define DMX_STOP                 _IO('o', 42)
 #define DMX_SET_FILTER           _IOW('o', 43, struct dmx_sct_filter_params)
@@ -484,8 +605,12 @@
 #define DMX_RELEASE_DATA		 _IO('o', 57)
 #define DMX_FEED_DATA			 _IO('o', 58)
 #define DMX_SET_PLAYBACK_MODE	 _IOW('o', 59, enum dmx_playback_mode_t)
-#define DMX_GET_EVENT			 _IOR('o', 60, struct dmx_filter_event)
-#define DMX_SET_BUFFER_MODE		 _IOW('o', 61, enum dmx_buffer_mode)
-#define DMX_SET_BUFFER			 _IOW('o', 62, struct dmx_buffer)
+#define DMX_GET_EVENT		 _IOR('o', 60, struct dmx_filter_event)
+#define DMX_SET_BUFFER_MODE	 _IOW('o', 61, enum dmx_buffer_mode)
+#define DMX_SET_BUFFER		 _IOW('o', 62, struct dmx_buffer)
+#define DMX_SET_DECODER_BUFFER	 _IOW('o', 63, struct dmx_decoder_buffers)
+#define DMX_REUSE_DECODER_BUFFER _IO('o', 64)
+#define DMX_SET_SECURE_MODE	_IOW('o', 65, struct dmx_secure_mode)
+
 
 #endif /*_DVBDMX_H_*/
diff --git a/include/linux/fb.h b/include/linux/fb.h
index f6a2923..d31cb68 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -279,7 +279,7 @@
 	__u32 vmode;			/* see FB_VMODE_*		*/
 	__u32 rotate;			/* angle we rotate counter clockwise */
 	__u32 colorspace;		/* colorspace for FOURCC-based modes */
-	__u32 reserved[5];		/* Reserved for future compatibility */
+	__u32 reserved[4];		/* Reserved for future compatibility */
 };
 
 struct fb_cmap {
diff --git a/include/linux/fmem.h b/include/linux/fmem.h
index e4fa82c..cda4a0f 100644
--- a/include/linux/fmem.h
+++ b/include/linux/fmem.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/include/linux/fsm_dfe_hh.h b/include/linux/fsm_dfe_hh.h
index 7938518..db96794 100644
--- a/include/linux/fsm_dfe_hh.h
+++ b/include/linux/fsm_dfe_hh.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/include/linux/fsm_rfic_ftr.h b/include/linux/fsm_rfic_ftr.h
index 18b7947..6288a33 100644
--- a/include/linux/fsm_rfic_ftr.h
+++ b/include/linux/fsm_rfic_ftr.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 1e49be4..7b3823e 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -23,6 +23,7 @@
 #define ___GFP_REPEAT		0x400u
 #define ___GFP_NOFAIL		0x800u
 #define ___GFP_NORETRY		0x1000u
+#define ___GFP_CMA		0x2000u
 #define ___GFP_COMP		0x4000u
 #define ___GFP_ZERO		0x8000u
 #define ___GFP_NOMEMALLOC	0x10000u
@@ -51,7 +52,9 @@
 #define __GFP_HIGHMEM	((__force gfp_t)___GFP_HIGHMEM)
 #define __GFP_DMA32	((__force gfp_t)___GFP_DMA32)
 #define __GFP_MOVABLE	((__force gfp_t)___GFP_MOVABLE)  /* Page is movable */
-#define GFP_ZONEMASK	(__GFP_DMA|__GFP_HIGHMEM|__GFP_DMA32|__GFP_MOVABLE)
+#define __GFP_CMA	((__force gfp_t)___GFP_CMA)
+#define GFP_ZONEMASK	(__GFP_DMA|__GFP_HIGHMEM|__GFP_DMA32|__GFP_MOVABLE| \
+			__GFP_CMA)
 /*
  * Action modifiers - doesn't change the zoning
  *
@@ -124,7 +127,7 @@
 #endif
 
 /* This mask makes up all the page movable related flags */
-#define GFP_MOVABLE_MASK (__GFP_RECLAIMABLE|__GFP_MOVABLE)
+#define GFP_MOVABLE_MASK (__GFP_RECLAIMABLE|__GFP_MOVABLE|__GFP_CMA)
 
 /* Control page allocator reclaim behavior */
 #define GFP_RECLAIM_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS|\
@@ -157,8 +160,14 @@
 		return MIGRATE_UNMOVABLE;
 
 	/* Group based on mobility */
+#ifndef CONFIG_CMA
 	return (((gfp_flags & __GFP_MOVABLE) != 0) << 1) |
 		((gfp_flags & __GFP_RECLAIMABLE) != 0);
+#else
+	return (((gfp_flags & __GFP_MOVABLE) != 0) << 1) |
+		(((gfp_flags & __GFP_CMA) != 0) << 1) |
+		((gfp_flags & __GFP_RECLAIMABLE) != 0);
+#endif
 }
 
 #ifdef CONFIG_HIGHMEM
diff --git a/include/linux/gpio-pm8xxx-rpc.h b/include/linux/gpio-pm8xxx-rpc.h
index 5b6f097..cb8247f 100644
--- a/include/linux/gpio-pm8xxx-rpc.h
+++ b/include/linux/gpio-pm8xxx-rpc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/include/linux/highmem.h b/include/linux/highmem.h
index d3999b4..c737eb7 100644
--- a/include/linux/highmem.h
+++ b/include/linux/highmem.h
@@ -211,9 +211,24 @@
 alloc_zeroed_user_highpage_movable(struct vm_area_struct *vma,
 					unsigned long vaddr)
 {
+#ifndef CONFIG_CMA
 	return __alloc_zeroed_user_highpage(__GFP_MOVABLE, vma, vaddr);
+#else
+	return __alloc_zeroed_user_highpage(__GFP_MOVABLE|__GFP_CMA, vma,
+						vaddr);
+#endif
 }
 
+#ifdef CONFIG_CMA
+static inline struct page *
+alloc_zeroed_user_highpage_movable_cma(struct vm_area_struct *vma,
+						unsigned long vaddr)
+{
+	return __alloc_zeroed_user_highpage(__GFP_MOVABLE|__GFP_CMA, vma,
+						vaddr);
+}
+#endif
+
 static inline void clear_highpage(struct page *page)
 {
 	void *kaddr = kmap_atomic(page);
diff --git a/include/linux/i2c/atmel_mxt_ts.h b/include/linux/i2c/atmel_mxt_ts.h
index fe23993..b903dfb 100644
--- a/include/linux/i2c/atmel_mxt_ts.h
+++ b/include/linux/i2c/atmel_mxt_ts.h
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2010 Samsung Electronics Co.Ltd
  * Author: Joonyoung Shim <jy0922.shim@samsung.com>
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -32,8 +32,10 @@
 /* Bootoader IDs */
 #define MXT_BOOTLOADER_ID_224		0x0A
 #define MXT_BOOTLOADER_ID_224E		0x06
+#define MXT_BOOTLOADER_ID_336S		0x1A
 #define MXT_BOOTLOADER_ID_1386		0x01
 #define MXT_BOOTLOADER_ID_1386E		0x10
+#define MXT_BOOTLOADER_ID_1664S		0x14
 
 /* Config data for a given maXTouch controller with a specific firmware */
 struct mxt_config_info {
@@ -75,6 +77,7 @@
 	int *key_codes;
 	bool need_calibration;
 	bool no_force_update;
+	u8 bl_addr;
 
 	u8(*read_chg) (void);
 	int (*init_hw) (bool);
diff --git a/include/linux/i2c/bq27520.h b/include/linux/i2c/bq27520.h
index 70c5a4c..c1e5e06 100644
--- a/include/linux/i2c/bq27520.h
+++ b/include/linux/i2c/bq27520.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/i2c/isa1200.h b/include/linux/i2c/isa1200.h
index ffadf96..65a6bf5 100644
--- a/include/linux/i2c/isa1200.h
+++ b/include/linux/i2c/isa1200.h
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 2009 Samsung Electronics
  *  Kyungmin Park <kyungmin.park@samsung.com>
- *  Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *  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 as
diff --git a/include/linux/i2c/isl9519.h b/include/linux/i2c/isl9519.h
index 8c98bf7..3499674 100644
--- a/include/linux/i2c/isl9519.h
+++ b/include/linux/i2c/isl9519.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/i2c/smb137b.h b/include/linux/i2c/smb137b.h
index a72b895..7367ac5 100644
--- a/include/linux/i2c/smb137b.h
+++ b/include/linux/i2c/smb137b.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/i2c/smb349.h b/include/linux/i2c/smb349.h
index 2adacb3..40e1fac 100644
--- a/include/linux/i2c/smb349.h
+++ b/include/linux/i2c/smb349.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012 The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/include/linux/i2c/sx150x.h b/include/linux/i2c/sx150x.h
index e73dfd9..a2060bd 100644
--- a/include/linux/i2c/sx150x.h
+++ b/include/linux/i2c/sx150x.h
@@ -1,7 +1,7 @@
 /*
  * Driver for the Semtech SX150x I2C GPIO Expanders
  *
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/include/linux/input/cy8c_ts.h b/include/linux/input/cy8c_ts.h
index d25f31d..a451c44 100644
--- a/include/linux/input/cy8c_ts.h
+++ b/include/linux/input/cy8c_ts.h
@@ -2,7 +2,7 @@
  * Cypress CY8CTMA300 Prototype touchscreen driver.
  *
  * Copyright (C) 2009, 2010 Cypress Semiconductor, Inc.
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/include/linux/input/ft5x06_ts.h b/include/linux/input/ft5x06_ts.h
index b2fb3c4..a379d38 100644
--- a/include/linux/input/ft5x06_ts.h
+++ b/include/linux/input/ft5x06_ts.h
@@ -3,7 +3,7 @@
  * FocalTech ft5x06 TouchScreen driver header file.
  *
  * Copyright (c) 2010  Focal tech Ltd.
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/include/linux/input/gen_vkeys.h b/include/linux/input/gen_vkeys.h
new file mode 100644
index 0000000..ce29351
--- /dev/null
+++ b/include/linux/input/gen_vkeys.h
@@ -0,0 +1,23 @@
+/* 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 __GEN_VKEYS_
+struct vkeys_platform_data {
+	const char *name;
+	int disp_maxx;
+	int disp_maxy;
+	int panel_maxx;
+	int panel_maxy;
+	int *keycodes;
+	int num_keys;
+};
+#endif
diff --git a/include/linux/input/kp_flip_switch.h b/include/linux/input/kp_flip_switch.h
index 31c0cc4..68c226b 100644
--- a/include/linux/input/kp_flip_switch.h
+++ b/include/linux/input/kp_flip_switch.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/input/mpu3050.h b/include/linux/input/mpu3050.h
index 6006abb..61a2920 100644
--- a/include/linux/input/mpu3050.h
+++ b/include/linux/input/mpu3050.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/include/linux/input/pmic8xxx-keypad.h b/include/linux/input/pmic8xxx-keypad.h
index 5f1e2f9..4292328 100644
--- a/include/linux/input/pmic8xxx-keypad.h
+++ b/include/linux/input/pmic8xxx-keypad.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/input/pmic8xxx-pwrkey.h b/include/linux/input/pmic8xxx-pwrkey.h
index a32eafd..9230a75 100644
--- a/include/linux/input/pmic8xxx-pwrkey.h
+++ b/include/linux/input/pmic8xxx-pwrkey.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/input/qci_kbd.h b/include/linux/input/qci_kbd.h
index 5afda7d..20fd9e9 100644
--- a/include/linux/input/qci_kbd.h
+++ b/include/linux/input/qci_kbd.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/input/synaptics_dsx.h b/include/linux/input/synaptics_dsx.h
new file mode 100644
index 0000000..9d03787
--- /dev/null
+++ b/include/linux/input/synaptics_dsx.h
@@ -0,0 +1,61 @@
+/*
+ * Synaptics RMI4 touchscreen driver
+ *
+ * Copyright (C) 2012 Synaptics Incorporated
+ *
+ * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
+ * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SYNAPTICS_DSX_H_
+#define _SYNAPTICS_DSX_H_
+
+/*
+ * struct synaptics_rmi4_capacitance_button_map - 0d button map
+ * @nbuttons: number of buttons
+ * @map: button map
+ */
+struct synaptics_rmi4_capacitance_button_map {
+	unsigned char nbuttons;
+	unsigned char *map;
+};
+
+/*
+ * struct synaptics_rmi4_platform_data - rmi4 platform data
+ * @x_flip: x flip flag
+ * @y_flip: y flip flag
+ * @regulator_en: regulator enable flag
+ * @irq_gpio: attention interrupt gpio
+ * @irq_flags: flags used by the irq
+ * @reset_gpio: reset gpio
+ * @panel_x: panel maximum values on the x
+ * @panel_y: panel maximum values on the y
+ * @gpio_config: pointer to gpio configuration function
+ * @capacitance_button_map: pointer to 0d button map
+ */
+struct synaptics_rmi4_platform_data {
+	bool x_flip;
+	bool y_flip;
+	bool regulator_en;
+	bool i2c_pull_up;
+	unsigned irq_gpio;
+	unsigned long irq_flags;
+	unsigned reset_gpio;
+	unsigned panel_x;
+	unsigned panel_y;
+	int (*gpio_config)(unsigned gpio, bool configure);
+	struct synaptics_rmi4_capacitance_button_map *capacitance_button_map;
+};
+
+#endif
diff --git a/include/linux/input/tdisc_shinetsu.h b/include/linux/input/tdisc_shinetsu.h
index 88f84f2..973606a 100644
--- a/include/linux/input/tdisc_shinetsu.h
+++ b/include/linux/input/tdisc_shinetsu.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index d4fa3aa..97b8e0b 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -138,6 +138,7 @@
 extern int iommu_group_for_each_dev(struct iommu_group *group, void *data,
 				    int (*fn)(struct device *, void *));
 extern struct iommu_group *iommu_group_get(struct device *dev);
+extern struct iommu_group *iommu_group_find(const char *name);
 extern void iommu_group_put(struct iommu_group *group);
 extern int iommu_group_register_notifier(struct iommu_group *group,
 					 struct notifier_block *nb);
@@ -317,6 +318,11 @@
 	return NULL;
 }
 
+static inline struct iommu_group *iommu_group_find(const char *name)
+{
+	return NULL;
+}
+
 static inline void iommu_group_put(struct iommu_group *group)
 {
 }
diff --git a/include/linux/ion.h b/include/linux/ion.h
index 3a29f20..f159fe2 100644
--- a/include/linux/ion.h
+++ b/include/linux/ion.h
@@ -2,7 +2,7 @@
  * include/linux/ion.h
  *
  * Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -482,6 +482,10 @@
 	return -ENODEV;
 }
 
+static inline void ion_mark_dangling_buffers_locked(struct ion_device *dev)
+{
+}
+
 static inline int msm_ion_do_cache_op(struct ion_client *client,
 			struct ion_handle *handle, void *vaddr,
 			unsigned long len, unsigned int cmd)
diff --git a/include/linux/iopoll.h b/include/linux/iopoll.h
index f28053c..8aa758d 100644
--- a/include/linux/iopoll.h
+++ b/include/linux/iopoll.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012 The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/include/linux/ioprio.h b/include/linux/ioprio.h
index 76dad48..da6e8c5 100644
--- a/include/linux/ioprio.h
+++ b/include/linux/ioprio.h
@@ -1,14 +1,16 @@
 #ifndef IOPRIO_H
 #define IOPRIO_H
-
+#ifdef __KERNEL__
 #include <linux/sched.h>
 #include <linux/iocontext.h>
+#endif /* __KERNEL__ */
 
 /*
  * Gives us 8 prio classes with 13-bits of data for each class
  */
 #define IOPRIO_BITS		(16)
 #define IOPRIO_CLASS_SHIFT	(13)
+#ifdef __KERNEL__
 #define IOPRIO_PRIO_MASK	((1UL << IOPRIO_CLASS_SHIFT) - 1)
 
 #define IOPRIO_PRIO_CLASS(mask)	((mask) >> IOPRIO_CLASS_SHIFT)
@@ -16,6 +18,7 @@
 #define IOPRIO_PRIO_VALUE(class, data)	(((class) << IOPRIO_CLASS_SHIFT) | data)
 
 #define ioprio_valid(mask)	(IOPRIO_PRIO_CLASS((mask)) != IOPRIO_CLASS_NONE)
+#endif /* __KERNEL__ */
 
 /*
  * These are the io priority groups as implemented by CFQ. RT is the realtime
@@ -41,6 +44,7 @@
 	IOPRIO_WHO_USER,
 };
 
+#ifdef __KERNEL__
 /*
  * if process has set io priority explicitly, use that. if not, convert
  * the cpu scheduler nice value to an io priority
@@ -88,4 +92,5 @@
 
 extern int set_task_ioprio(struct task_struct *task, int ioprio);
 
-#endif
+#endif /* __KERNEL__ */
+#endif /* IOPRIO_H */
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 8260ef7..4effce6 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -172,6 +172,7 @@
 	__s32		disable_ipv6;
 	__s32		accept_dad;
 	__s32		force_tllao;
+	__s32		accept_ra_prefix_route;
 	void		*sysctl;
 };
 
@@ -213,6 +214,7 @@
 	DEVCONF_DISABLE_IPV6,
 	DEVCONF_ACCEPT_DAD,
 	DEVCONF_FORCE_TLLAO,
+	DEVCONF_ACCEPT_RA_PREFIX_ROUTE,
 	DEVCONF_MAX
 };
 
diff --git a/include/linux/ks8851.h b/include/linux/ks8851.h
index 6970f47..bfa4d3b 100644
--- a/include/linux/ks8851.h
+++ b/include/linux/ks8851.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/leds-msm-tricolor.h b/include/linux/leds-msm-tricolor.h
index 314645e..3302676 100644
--- a/include/linux/leds-msm-tricolor.h
+++ b/include/linux/leds-msm-tricolor.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/include/linux/leds-pm8xxx.h b/include/linux/leds-pm8xxx.h
index ff1a93b..e912585 100644
--- a/include/linux/leds-pm8xxx.h
+++ b/include/linux/leds-pm8xxx.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -18,6 +18,10 @@
 
 #define PM8XXX_LEDS_DEV_NAME	"pm8xxx-led"
 
+#define WLED_FIRST_STRING (1 << 2)
+#define WLED_SECOND_STRING (1 << 1)
+#define WLED_THIRD_STRING (1 << 0)
+
 /**
  * enum pm8xxx_leds - PMIC8XXX supported led ids
  * @PM8XXX_ID_LED_KB_LIGHT - keyboard backlight led
@@ -77,7 +81,7 @@
 
 /**
  *  wled_config_data - wled configuration data
- *  @num_strings - number of wled strings supported
+ *  @strings - strings supported
  *  @ovp_val - over voltage protection threshold
  *  @boost_curr_lim - boot current limit
  *  @cp_select - high pole capacitance
@@ -86,9 +90,10 @@
  *  @cs_out_en - current sink output enable
  *  @op_fdbck - selection of output as feedback for the boost
  *  @cabc_en - enable cabc for backlight pwm control
+ *
  */
 struct wled_config_data {
-	u8	num_strings;
+	u8	strings;
 	u8	ovp_val;
 	u8	boost_curr_lim;
 	u8	cp_select;
@@ -97,6 +102,11 @@
 	bool	cs_out_en;
 	bool	op_fdbck;
 	bool	cabc_en;
+	bool	sstart_en;
+	bool	max_current_ind;
+	u8 max_three;
+	u8 max_two;
+	u8 max_one;
 };
 
 /**
diff --git a/include/linux/leds-pmic8058.h b/include/linux/leds-pmic8058.h
index cbfde9f..a4bf0ea 100644
--- a/include/linux/leds-pmic8058.h
+++ b/include/linux/leds-pmic8058.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/libra_sdioif.h b/include/linux/libra_sdioif.h
index 99b7d04..d1a42cc 100644
--- a/include/linux/libra_sdioif.h
+++ b/include/linux/libra_sdioif.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/include/linux/m_adcproc.h b/include/linux/m_adcproc.h
index e36a90a..e7628b0 100644
--- a/include/linux/m_adcproc.h
+++ b/include/linux/m_adcproc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/memory_alloc.h b/include/linux/memory_alloc.h
index e7049f8..b649451 100644
--- a/include/linux/memory_alloc.h
+++ b/include/linux/memory_alloc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/mfd/marimba-codec.h b/include/linux/mfd/marimba-codec.h
index bfda146..2fbbc0e 100644
--- a/include/linux/mfd/marimba-codec.h
+++ b/include/linux/mfd/marimba-codec.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/include/linux/mfd/marimba-tsadc.h b/include/linux/mfd/marimba-tsadc.h
index 6a05b43..247fedd 100644
--- a/include/linux/mfd/marimba-tsadc.h
+++ b/include/linux/mfd/marimba-tsadc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/include/linux/mfd/marimba.h b/include/linux/mfd/marimba.h
index 32fe748..473d39b 100644
--- a/include/linux/mfd/marimba.h
+++ b/include/linux/mfd/marimba.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/include/linux/mfd/pm8xxx/batt-alarm.h b/include/linux/mfd/pm8xxx/batt-alarm.h
index f10715d..b266f3e 100644
--- a/include/linux/mfd/pm8xxx/batt-alarm.h
+++ b/include/linux/mfd/pm8xxx/batt-alarm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/mfd/pm8xxx/batterydata-lib.h b/include/linux/mfd/pm8xxx/batterydata-lib.h
index afa1843..f27ceca 100644
--- a/include/linux/mfd/pm8xxx/batterydata-lib.h
+++ b/include/linux/mfd/pm8xxx/batterydata-lib.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
@@ -73,6 +73,7 @@
 	BATT_UNKNOWN = 0,
 	BATT_PALLADIUM,
 	BATT_DESAY,
+	BATT_OEM,
 };
 
 /**
@@ -88,6 +89,8 @@
  *			readings from bms are not available.
  * @delta_rbatt_mohm:	the resistance to be added towards lower soc to
  *			compensate for battery capacitance.
+ * @rbatt_capacitve_mohm: the resistance to be added to compensate for
+ *				battery capacitance
  */
 
 struct bms_battery_data {
@@ -99,6 +102,7 @@
 	struct sf_lut		*rbatt_sf_lut;
 	int			default_rbatt_mohm;
 	int			delta_rbatt_mohm;
+	int			rbatt_capacitive_mohm;
 };
 
 #if defined(CONFIG_PM8921_BMS) || \
@@ -106,6 +110,7 @@
 	defined(CONFIG_QPNP_BMS)
 extern struct bms_battery_data  palladium_1500_data;
 extern struct bms_battery_data  desay_5200_data;
+extern struct bms_battery_data  oem_batt_data;
 
 int interpolate_fcc(struct single_row_lut *fcc_temp_lut, int batt_temp);
 int interpolate_scalingfactor(struct sf_lut *sf_lut, int row_entry, int pc);
diff --git a/include/linux/mfd/pm8xxx/ccadc.h b/include/linux/mfd/pm8xxx/ccadc.h
index fc31f89..955e286 100644
--- a/include/linux/mfd/pm8xxx/ccadc.h
+++ b/include/linux/mfd/pm8xxx/ccadc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -17,14 +17,20 @@
 
 #define PM8XXX_CCADC_DEV_NAME "pm8xxx-ccadc"
 
+struct pm8xxx_ccadc_core_data {
+	unsigned int	batt_temp_channel;
+};
+
 /**
  * struct pm8xxx_ccadc_platform_data -
+ * @ccadc_cdata:	core data for the ccadc driver containing channel info
  * @r_sense_uohm:		sense resistor value in (micro Ohms)
  * @calib_delay_ms:	how often should the adc calculate gain and offset
  */
 struct pm8xxx_ccadc_platform_data {
-	int		r_sense_uohm;
-	unsigned int	calib_delay_ms;
+	struct pm8xxx_ccadc_core_data	ccadc_cdata;
+	int				r_sense_uohm;
+	unsigned int			calib_delay_ms;
 };
 
 #define CCADC_READING_RESOLUTION_N	542535
diff --git a/include/linux/mfd/pm8xxx/core.h b/include/linux/mfd/pm8xxx/core.h
index 38c589d..282593c 100644
--- a/include/linux/mfd/pm8xxx/core.h
+++ b/include/linux/mfd/pm8xxx/core.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/include/linux/mfd/pm8xxx/gpio.h b/include/linux/mfd/pm8xxx/gpio.h
index ccd9c10..333d13f 100644
--- a/include/linux/mfd/pm8xxx/gpio.h
+++ b/include/linux/mfd/pm8xxx/gpio.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/include/linux/mfd/pm8xxx/irq.h b/include/linux/mfd/pm8xxx/irq.h
index 78fbed3..9ae6fd4 100644
--- a/include/linux/mfd/pm8xxx/irq.h
+++ b/include/linux/mfd/pm8xxx/irq.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/include/linux/mfd/pm8xxx/misc.h b/include/linux/mfd/pm8xxx/misc.h
index c4b0ea4..fa97ba9 100644
--- a/include/linux/mfd/pm8xxx/misc.h
+++ b/include/linux/mfd/pm8xxx/misc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/include/linux/mfd/pm8xxx/mpp.h b/include/linux/mfd/pm8xxx/mpp.h
index 2a934e5..90596f8 100644
--- a/include/linux/mfd/pm8xxx/mpp.h
+++ b/include/linux/mfd/pm8xxx/mpp.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/include/linux/mfd/pm8xxx/nfc.h b/include/linux/mfd/pm8xxx/nfc.h
index e58e0a9..e4a495d 100644
--- a/include/linux/mfd/pm8xxx/nfc.h
+++ b/include/linux/mfd/pm8xxx/nfc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010,2011 Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/mfd/pm8xxx/pm8018.h b/include/linux/mfd/pm8xxx/pm8018.h
index daacdd4..002623c 100644
--- a/include/linux/mfd/pm8xxx/pm8018.h
+++ b/include/linux/mfd/pm8xxx/pm8018.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/include/linux/mfd/pm8xxx/pm8038.h b/include/linux/mfd/pm8xxx/pm8038.h
index 9e25b5c..5c9219c 100644
--- a/include/linux/mfd/pm8xxx/pm8038.h
+++ b/include/linux/mfd/pm8xxx/pm8038.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/include/linux/mfd/pm8xxx/pm8821-irq.h b/include/linux/mfd/pm8xxx/pm8821-irq.h
index af985e6..4d9b8b8 100644
--- a/include/linux/mfd/pm8xxx/pm8821-irq.h
+++ b/include/linux/mfd/pm8xxx/pm8821-irq.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/include/linux/mfd/pm8xxx/pm8821.h b/include/linux/mfd/pm8xxx/pm8821.h
index f41a632..e5877ac 100644
--- a/include/linux/mfd/pm8xxx/pm8821.h
+++ b/include/linux/mfd/pm8xxx/pm8821.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/include/linux/mfd/pm8xxx/pm8921-bms.h b/include/linux/mfd/pm8xxx/pm8921-bms.h
index 6db6204..0806d31 100644
--- a/include/linux/mfd/pm8xxx/pm8921-bms.h
+++ b/include/linux/mfd/pm8xxx/pm8921-bms.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -41,6 +41,9 @@
  *				voltage higher than cutoff voltage
  * @low_voltage_calc_ms:	The period of soc calculation in ms when battery
  *				voltage is near cutoff voltage
+ * @disable_flat_portion_ocv:	feature to disable ocv updates while in sleep
+ * @ocv_dis_high_soc:		the high soc percent when ocv should be disabled
+ * @ocv_dis_low_soc:		the low soc percent when ocv should be enabled
  */
 struct pm8921_bms_platform_data {
 	struct pm8xxx_bms_core_data	bms_cdata;
@@ -50,6 +53,8 @@
 	unsigned int			v_cutoff;
 	unsigned int			max_voltage_uv;
 	unsigned int			rconn_mohm;
+	unsigned int			alarm_low_mv;
+	unsigned int			alarm_high_mv;
 	int				enable_fcc_learning;
 	int				shutdown_soc_valid_limit;
 	int				ignore_shutdown_soc;
@@ -57,6 +62,9 @@
 	int				chg_term_ua;
 	int				normal_voltage_calc_ms;
 	int				low_voltage_calc_ms;
+	int				disable_flat_portion_ocv;
+	int				ocv_dis_high_soc;
+	int				ocv_dis_low_soc;
 };
 
 #if defined(CONFIG_PM8921_BMS) || defined(CONFIG_PM8921_BMS_MODULE)
@@ -123,9 +131,11 @@
 int pm8921_bms_get_simultaneous_battery_voltage_and_current(int *ibat_ua,
 								int *vbat_uv);
 /**
- * pm8921_bms_get_rbatt - function to get the battery resistance in mOhm.
+ * pm8921_bms_get_current_max
+ *	- function to get the max current that can be drawn from
+ *	  the battery before it dips below the min allowed voltage
  */
-int pm8921_bms_get_rbatt(void);
+int pm8921_bms_get_current_max(void);
 /**
  * pm8921_bms_invalidate_shutdown_soc - function to notify the bms driver that
  *					the battery was replaced between reboot
@@ -184,6 +194,10 @@
 {
 	return -ENXIO;
 }
+static inline int pm8921_bms_get_current_max(void)
+{
+	return -ENXIO;
+}
 #endif
 
 #endif
diff --git a/include/linux/mfd/pm8xxx/pm8921-charger.h b/include/linux/mfd/pm8xxx/pm8921-charger.h
index 44f8538..1c67b1e 100644
--- a/include/linux/mfd/pm8xxx/pm8921-charger.h
+++ b/include/linux/mfd/pm8xxx/pm8921-charger.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -138,6 +138,10 @@
  *				driver couldn't stop charging when battery
  *				temperature is out of bounds. Used only if
  *				btc_override = 1
+ * stop_chg_upon_expiry:	flag to indicate that the charger driver should
+ *				stop charging the battery when the safety timer
+ *				expires. If not set the charger driver will
+ *				restart charging upon expiry.
  */
 struct pm8921_charger_platform_data {
 	struct pm8xxx_charger_core_data	charger_cdata;
@@ -183,6 +187,8 @@
 	int				btc_override_hot_degc;
 	int				btc_delay_ms;
 	int				btc_panic_if_cant_stop_chg;
+	int				stop_chg_upon_expiry;
+	bool				disable_chg_rmvl_wrkarnd;
 };
 
 enum pm8921_charger_source {
diff --git a/include/linux/mfd/pm8xxx/pm8921.h b/include/linux/mfd/pm8xxx/pm8921.h
index 92bb94b..aabbb21 100644
--- a/include/linux/mfd/pm8xxx/pm8921.h
+++ b/include/linux/mfd/pm8xxx/pm8921.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/include/linux/mfd/pm8xxx/pm8xxx-adc.h b/include/linux/mfd/pm8xxx/pm8xxx-adc.h
index 84f8e03..f40633a 100644
--- a/include/linux/mfd/pm8xxx/pm8xxx-adc.h
+++ b/include/linux/mfd/pm8xxx/pm8xxx-adc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/include/linux/mfd/pm8xxx/pwm.h b/include/linux/mfd/pm8xxx/pwm.h
index 09b165e..6d95e3a 100644
--- a/include/linux/mfd/pm8xxx/pwm.h
+++ b/include/linux/mfd/pm8xxx/pwm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/include/linux/mfd/pm8xxx/regulator.h b/include/linux/mfd/pm8xxx/regulator.h
index 83492d2..31c2684 100644
--- a/include/linux/mfd/pm8xxx/regulator.h
+++ b/include/linux/mfd/pm8xxx/regulator.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/include/linux/mfd/pm8xxx/rtc.h b/include/linux/mfd/pm8xxx/rtc.h
index bb3f98a..2ce37a0 100644
--- a/include/linux/mfd/pm8xxx/rtc.h
+++ b/include/linux/mfd/pm8xxx/rtc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/mfd/pm8xxx/spk.h b/include/linux/mfd/pm8xxx/spk.h
index 2905a1d..9835b85 100644
--- a/include/linux/mfd/pm8xxx/spk.h
+++ b/include/linux/mfd/pm8xxx/spk.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/include/linux/mfd/pm8xxx/upl.h b/include/linux/mfd/pm8xxx/upl.h
index b0e94a9..6a315ab 100644
--- a/include/linux/mfd/pm8xxx/upl.h
+++ b/include/linux/mfd/pm8xxx/upl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010,2011 Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/mfd/pm8xxx/vibrator.h b/include/linux/mfd/pm8xxx/vibrator.h
index cfea1c9..3594bb0 100644
--- a/include/linux/mfd/pm8xxx/vibrator.h
+++ b/include/linux/mfd/pm8xxx/vibrator.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/mfd/pmic8058.h b/include/linux/mfd/pmic8058.h
index ff7a329..19e783f 100644
--- a/include/linux/mfd/pmic8058.h
+++ b/include/linux/mfd/pmic8058.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/include/linux/mfd/pmic8901.h b/include/linux/mfd/pmic8901.h
index f5b34be..bf64bec 100644
--- a/include/linux/mfd/pmic8901.h
+++ b/include/linux/mfd/pmic8901.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/mfd/tps65023.h b/include/linux/mfd/tps65023.h
index 4cce091..b6ad6e5 100644
--- a/include/linux/mfd/tps65023.h
+++ b/include/linux/mfd/tps65023.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
diff --git a/include/linux/mfd/wcd9xxx/Kbuild b/include/linux/mfd/wcd9xxx/Kbuild
index acfab6e..1c4cec2 100644
--- a/include/linux/mfd/wcd9xxx/Kbuild
+++ b/include/linux/mfd/wcd9xxx/Kbuild
@@ -1,2 +1,3 @@
 header-y += wcd9xxx_registers.h
 header-y += wcd9310_registers.h
+header-y += wcd9320_registers.h
diff --git a/include/linux/mfd/wcd9xxx/core.h b/include/linux/mfd/wcd9xxx/core.h
index 2874a3b..aed549e 100644
--- a/include/linux/mfd/wcd9xxx/core.h
+++ b/include/linux/mfd/wcd9xxx/core.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -29,6 +29,8 @@
 	(((ver == TABLA_VERSION_1_0) || (ver == TABLA_VERSION_1_1)) ? 1 : 0)
 #define TABLA_IS_2_0(ver) ((ver == TABLA_VERSION_2_0) ? 1 : 0)
 
+#define WCD9XXX_SUPPLY_BUCK_NAME "cdc-vdd-buck"
+
 #define SITAR_VERSION_1P0 0
 #define SITAR_VERSION_1P1 1
 #define SITAR_IS_1P0(ver) \
@@ -36,11 +38,14 @@
 #define SITAR_IS_1P1(ver) \
 	((ver == SITAR_VERSION_1P1) ? 1 : 0)
 
-
-#define TAIKO_VERSION_1_0	0
+#define TAIKO_VERSION_1_0	1
 #define TAIKO_IS_1_0(ver) \
 	((ver == TAIKO_VERSION_1_0) ? 1 : 0)
 
+enum wcd9xxx_slim_slave_addr_type {
+	WCD9XXX_SLIM_SLAVE_ADDR_TYPE_TABLA,
+	WCD9XXX_SLIM_SLAVE_ADDR_TYPE_TAIKO,
+};
 
 enum {
 	/* INTR_REG 0 */
@@ -83,6 +88,7 @@
 	TABLA_NUM_IRQS = WCD9XXX_NUM_IRQS,
 	SITAR_NUM_IRQS = WCD9XXX_NUM_IRQS,
 	TAIKO_NUM_IRQS = WCD9XXX_NUM_IRQS,
+	TAPAN_NUM_IRQS = WCD9XXX_NUM_IRQS,
 };
 
 
@@ -147,6 +153,7 @@
 	struct mutex io_lock;
 	struct mutex xfer_lock;
 	struct mutex irq_lock;
+	struct mutex nested_irq_lock;
 	u8 version;
 
 	int reset_gpio;
@@ -155,6 +162,10 @@
 			int bytes, void *dest, bool interface_reg);
 	int (*write_dev)(struct wcd9xxx *wcd9xxx, unsigned short reg,
 			int bytes, void *src, bool interface_reg);
+	int (*post_reset)(struct wcd9xxx *wcd9xxx);
+
+	void *ssr_priv;
+	bool slim_device_bootup;
 
 	u32 num_of_supplies;
 	struct regulator_bulk_data *supplies;
@@ -180,6 +191,8 @@
 	struct wcd9xxx_ch *rx_chs;
 	struct wcd9xxx_ch *tx_chs;
 	u32 mclk_rate;
+
+	enum wcd9xxx_slim_slave_addr_type slim_slave_type;
 };
 
 int wcd9xxx_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg);
@@ -199,6 +212,8 @@
 
 bool wcd9xxx_lock_sleep(struct wcd9xxx *wcd9xxx);
 void wcd9xxx_unlock_sleep(struct wcd9xxx *wcd9xxx);
+void wcd9xxx_nested_irq_lock(struct wcd9xxx *wcd9xxx);
+void wcd9xxx_nested_irq_unlock(struct wcd9xxx *wcd9xxx);
 enum wcd9xxx_pm_state wcd9xxx_pm_cmpxchg(struct wcd9xxx *wcd9xxx,
 				enum wcd9xxx_pm_state o,
 				enum wcd9xxx_pm_state n);
@@ -212,7 +227,8 @@
 void wcd9xxx_disable_irq_sync(struct wcd9xxx *wcd9xxx, int irq);
 #if defined(CONFIG_WCD9310_CODEC) || \
 	defined(CONFIG_WCD9304_CODEC) || \
-	defined(CONFIG_WCD9320_CODEC)
+	defined(CONFIG_WCD9320_CODEC) || \
+	defined(CONFIG_WCD9306_CODEC)
 int __init wcd9xxx_irq_of_init(struct device_node *node,
 			       struct device_node *parent);
 #else
@@ -221,5 +237,5 @@
 {
 	return 0;
 }
-#endif
+#endif	/* CONFIG_OF */
 #endif
diff --git a/include/linux/mfd/wcd9xxx/pdata.h b/include/linux/mfd/wcd9xxx/pdata.h
index bfd95a6..392c0ae 100644
--- a/include/linux/mfd/wcd9xxx/pdata.h
+++ b/include/linux/mfd/wcd9xxx/pdata.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/include/linux/mfd/wcd9xxx/wcd9304_registers.h b/include/linux/mfd/wcd9xxx/wcd9304_registers.h
index 73919e0..a7f9e4a 100644
--- a/include/linux/mfd/wcd9xxx/wcd9304_registers.h
+++ b/include/linux/mfd/wcd9xxx/wcd9304_registers.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/include/linux/mfd/wcd9xxx/wcd9306_registers.h b/include/linux/mfd/wcd9xxx/wcd9306_registers.h
new file mode 100644
index 0000000..1254fac
--- /dev/null
+++ b/include/linux/mfd/wcd9xxx/wcd9306_registers.h
@@ -0,0 +1,1015 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef WCD9306_REGISTERS_H
+#define WCD9306_REGISTERS_H
+
+#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
+
+#define TAPAN_A_CHIP_CTL				WCD9XXX_A_CHIP_CTL
+#define TAPAN_A_CHIP_CTL__POR			WCD9XXX_A_CHIP_CTL__POR
+#define TAPAN_A_CHIP_STATUS				WCD9XXX_A_CHIP_STATUS
+#define TAPAN_A_CHIP_STATUS__POR		WCD9XXX_A_CHIP_STATUS__POR
+#define TAPAN_A_CHIP_ID_BYTE_0			WCD9XXX_A_CHIP_ID_BYTE_0
+#define TAPAN_A_CHIP_ID_BYTE_0__POR		WCD9XXX_A_CHIP_ID_BYTE_0__POR
+#define TAPAN_A_CHIP_ID_BYTE_1			WCD9XXX_A_CHIP_ID_BYTE_1
+#define TAPAN_A_CHIP_ID_BYTE_1__POR		WCD9XXX_A_CHIP_ID_BYTE_1__POR
+#define TAPAN_A_CHIP_ID_BYTE_2			WCD9XXX_A_CHIP_ID_BYTE_2
+#define TAPAN_A_CHIP_ID_BYTE_2__POR		WCD9XXX_A_CHIP_ID_BYTE_2__POR
+#define TAPAN_A_CHIP_ID_BYTE_3			WCD9XXX_A_CHIP_ID_BYTE_3
+#define TAPAN_A_CHIP_ID_BYTE_3__POR		WCD9XXX_A_CHIP_ID_BYTE_3__POR
+#define TAPAN_A_CHIP_VERSION			WCD9XXX_A_CHIP_VERSION
+#define TAPAN_A_CHIP_VERSION__POR		WCD9XXX_A_CHIP_VERSION__POR
+#define TAPAN_A_CHIP_DEBUG_CTL			(0x009)
+#define TAPAN_A_CHIP_DEBUG_CTL__POR				(0x00)
+#define TAPAN_A_SLAVE_ID_1			(0x00C)
+#define TAPAN_A_SLAVE_ID_1__POR				(0x77)
+#define TAPAN_A_SLAVE_ID_2			(0x00D)
+#define TAPAN_A_SLAVE_ID_2__POR				(0x66)
+#define TAPAN_A_SLAVE_ID_3			(0x00E)
+#define TAPAN_A_SLAVE_ID_3__POR				(0x55)
+#define TAPAN_A_PIN_CTL_OE0			(0x010)
+#define TAPAN_A_PIN_CTL_OE0__POR				(0x00)
+#define TAPAN_A_PIN_CTL_DATA0			(0x012)
+#define TAPAN_A_PIN_CTL_DATA0__POR				(0x00)
+#define TAPAN_A_HDRIVE_GENERIC			(0x018)
+#define TAPAN_A_HDRIVE_GENERIC__POR				(0x00)
+#define TAPAN_A_HDRIVE_OVERRIDE			(0x019)
+#define TAPAN_A_HDRIVE_OVERRIDE__POR				(0x08)
+#define TAPAN_A_ANA_CSR_WAIT_STATE			(0x020)
+#define TAPAN_A_ANA_CSR_WAIT_STATE__POR				(0x44)
+#define TAPAN_A_PROCESS_MONITOR_CTL0			(0x040)
+#define TAPAN_A_PROCESS_MONITOR_CTL0__POR				(0x80)
+#define TAPAN_A_PROCESS_MONITOR_CTL1			(0x041)
+#define TAPAN_A_PROCESS_MONITOR_CTL1__POR				(0x00)
+#define TAPAN_A_PROCESS_MONITOR_CTL2			(0x042)
+#define TAPAN_A_PROCESS_MONITOR_CTL2__POR				(0x00)
+#define TAPAN_A_PROCESS_MONITOR_CTL3			(0x043)
+#define TAPAN_A_PROCESS_MONITOR_CTL3__POR				(0x01)
+#define TAPAN_A_QFUSE_CTL			(0x048)
+#define TAPAN_A_QFUSE_CTL__POR				(0x00)
+#define TAPAN_A_QFUSE_STATUS			(0x049)
+#define TAPAN_A_QFUSE_STATUS__POR				(0x00)
+#define TAPAN_A_QFUSE_DATA_OUT0			(0x04A)
+#define TAPAN_A_QFUSE_DATA_OUT0__POR				(0x00)
+#define TAPAN_A_QFUSE_DATA_OUT1			(0x04B)
+#define TAPAN_A_QFUSE_DATA_OUT1__POR				(0x00)
+#define TAPAN_A_QFUSE_DATA_OUT2			(0x04C)
+#define TAPAN_A_QFUSE_DATA_OUT2__POR				(0x00)
+#define TAPAN_A_QFUSE_DATA_OUT3			(0x04D)
+#define TAPAN_A_QFUSE_DATA_OUT3__POR				(0x00)
+#define TAPAN_A_QFUSE_DATA_OUT4			(0x04E)
+#define TAPAN_A_QFUSE_DATA_OUT4__POR				(0x00)
+#define TAPAN_A_QFUSE_DATA_OUT5			(0x04F)
+#define TAPAN_A_QFUSE_DATA_OUT5__POR				(0x00)
+#define TAPAN_A_QFUSE_DATA_OUT6			(0x050)
+#define TAPAN_A_QFUSE_DATA_OUT6__POR				(0x00)
+#define TAPAN_A_QFUSE_DATA_OUT7			(0x051)
+#define TAPAN_A_QFUSE_DATA_OUT7__POR				(0x00)
+#define TAPAN_A_CDC_CTL			(0x080)
+#define TAPAN_A_CDC_CTL__POR				(0x00)
+#define TAPAN_A_LEAKAGE_CTL			(0x088)
+#define TAPAN_A_LEAKAGE_CTL__POR				(0x04)
+#define TAPAN_A_INTR_MODE			(0x090)
+#define TAPAN_A_INTR_MODE__POR				(0x00)
+#define TAPAN_A_INTR_MASK0			(0x094)
+#define TAPAN_A_INTR_MASK0__POR				(0xFF)
+#define TAPAN_A_INTR_MASK1			(0x095)
+#define TAPAN_A_INTR_MASK1__POR				(0xFF)
+#define TAPAN_A_INTR_MASK2			(0x096)
+#define TAPAN_A_INTR_MASK2__POR				(0x3F)
+#define TAPAN_A_INTR_MASK3			(0x097)
+#define TAPAN_A_INTR_MASK3__POR				(0x3F)
+#define TAPAN_A_INTR_STATUS0			(0x098)
+#define TAPAN_A_INTR_STATUS0__POR				(0x00)
+#define TAPAN_A_INTR_STATUS1			(0x099)
+#define TAPAN_A_INTR_STATUS1__POR				(0x00)
+#define TAPAN_A_INTR_STATUS2			(0x09A)
+#define TAPAN_A_INTR_STATUS2__POR				(0x00)
+#define TAPAN_A_INTR_STATUS3			(0x09B)
+#define TAPAN_A_INTR_STATUS3__POR				(0x00)
+#define TAPAN_A_INTR_CLEAR0			(0x09C)
+#define TAPAN_A_INTR_CLEAR0__POR				(0x00)
+#define TAPAN_A_INTR_CLEAR1			(0x09D)
+#define TAPAN_A_INTR_CLEAR1__POR				(0x00)
+#define TAPAN_A_INTR_CLEAR2			(0x09E)
+#define TAPAN_A_INTR_CLEAR2__POR				(0x00)
+#define TAPAN_A_INTR_CLEAR3			(0x09F)
+#define TAPAN_A_INTR_CLEAR3__POR				(0x00)
+#define TAPAN_A_INTR_LEVEL0			(0x0A0)
+#define TAPAN_A_INTR_LEVEL0__POR				(0x01)
+#define TAPAN_A_INTR_LEVEL1			(0x0A1)
+#define TAPAN_A_INTR_LEVEL1__POR				(0x00)
+#define TAPAN_A_INTR_LEVEL2			(0x0A2)
+#define TAPAN_A_INTR_LEVEL2__POR				(0x00)
+#define TAPAN_A_INTR_LEVEL3			(0x0A3)
+#define TAPAN_A_INTR_LEVEL3__POR				(0x00)
+#define TAPAN_A_INTR_TEST0			(0x0A4)
+#define TAPAN_A_INTR_TEST0__POR				(0x00)
+#define TAPAN_A_INTR_TEST1			(0x0A5)
+#define TAPAN_A_INTR_TEST1__POR				(0x00)
+#define TAPAN_A_INTR_TEST2			(0x0A6)
+#define TAPAN_A_INTR_TEST2__POR				(0x00)
+#define TAPAN_A_INTR_TEST3			(0x0A7)
+#define TAPAN_A_INTR_TEST3__POR				(0x00)
+#define TAPAN_A_INTR_SET0			(0x0A8)
+#define TAPAN_A_INTR_SET0__POR				(0x00)
+#define TAPAN_A_INTR_SET1			(0x0A9)
+#define TAPAN_A_INTR_SET1__POR				(0x00)
+#define TAPAN_A_INTR_SET2			(0x0AA)
+#define TAPAN_A_INTR_SET2__POR				(0x00)
+#define TAPAN_A_INTR_SET3			(0x0AB)
+#define TAPAN_A_INTR_SET3__POR				(0x00)
+#define TAPAN_A_INTR_DESTN0			(0x0AC)
+#define TAPAN_A_INTR_DESTN0__POR				(0x00)
+#define TAPAN_A_INTR_DESTN1			(0x0AD)
+#define TAPAN_A_INTR_DESTN1__POR				(0x00)
+#define TAPAN_A_INTR_DESTN2			(0x0AE)
+#define TAPAN_A_INTR_DESTN2__POR				(0x00)
+#define TAPAN_A_INTR_DESTN3			(0x0AF)
+#define TAPAN_A_INTR_DESTN3__POR				(0x00)
+#define TAPAN_A_CDC_DMIC_DATA0_MODE			(0x0C0)
+#define TAPAN_A_CDC_DMIC_DATA0_MODE__POR				(0x00)
+#define TAPAN_A_CDC_DMIC_CLK0_MODE			(0x0C1)
+#define TAPAN_A_CDC_DMIC_CLK0_MODE__POR				(0x00)
+#define TAPAN_A_CDC_DMIC_DATA1_MODE			(0x0C2)
+#define TAPAN_A_CDC_DMIC_DATA1_MODE__POR				(0x00)
+#define TAPAN_A_CDC_DMIC_CLK1_MODE			(0x0C3)
+#define TAPAN_A_CDC_DMIC_CLK1_MODE__POR				(0x00)
+#define TAPAN_A_CDC_INTR_MODE			(0x0C4)
+#define TAPAN_A_CDC_INTR_MODE__POR				(0x00)
+#define TAPAN_A_BIAS_REF_CTL			(0x100)
+#define TAPAN_A_BIAS_REF_CTL__POR				(0x1C)
+#define TAPAN_A_BIAS_CENTRAL_BG_CTL			(0x101)
+#define TAPAN_A_BIAS_CENTRAL_BG_CTL__POR				(0x50)
+#define TAPAN_A_BIAS_PRECHRG_CTL			(0x102)
+#define TAPAN_A_BIAS_PRECHRG_CTL__POR				(0x07)
+#define TAPAN_A_BIAS_CURR_CTL_1			(0x103)
+#define TAPAN_A_BIAS_CURR_CTL_1__POR				(0x52)
+#define TAPAN_A_BIAS_CURR_CTL_2			(0x104)
+#define TAPAN_A_BIAS_CURR_CTL_2__POR				(0x00)
+#define TAPAN_A_BIAS_OSC_BG_CTL			(0x105)
+#define TAPAN_A_BIAS_OSC_BG_CTL__POR				(0x16)
+#define TAPAN_A_CLK_BUFF_EN1			(0x108)
+#define TAPAN_A_CLK_BUFF_EN1__POR				(0x04)
+#define TAPAN_A_CLK_BUFF_EN2			(0x109)
+#define TAPAN_A_CLK_BUFF_EN2__POR				(0x02)
+#define TAPAN_A_LDO_H_MODE_1			(0x110)
+#define TAPAN_A_LDO_H_MODE_1__POR				(0x65)
+#define TAPAN_A_LDO_H_MODE_2			(0x111)
+#define TAPAN_A_LDO_H_MODE_2__POR				(0xA8)
+#define TAPAN_A_LDO_H_LOOP_CTL			(0x112)
+#define TAPAN_A_LDO_H_LOOP_CTL__POR				(0x6B)
+#define TAPAN_A_LDO_H_COMP_1			(0x113)
+#define TAPAN_A_LDO_H_COMP_1__POR				(0x84)
+#define TAPAN_A_LDO_H_COMP_2			(0x114)
+#define TAPAN_A_LDO_H_COMP_2__POR				(0xE0)
+#define TAPAN_A_LDO_H_BIAS_1			(0x115)
+#define TAPAN_A_LDO_H_BIAS_1__POR				(0x6D)
+#define TAPAN_A_LDO_H_BIAS_2			(0x116)
+#define TAPAN_A_LDO_H_BIAS_2__POR				(0xA5)
+#define TAPAN_A_LDO_H_BIAS_3			(0x117)
+#define TAPAN_A_LDO_H_BIAS_3__POR				(0x60)
+#define TAPAN_A_MICB_CFILT_1_CTL			(0x128)
+#define TAPAN_A_MICB_CFILT_1_CTL__POR				(0x40)
+#define TAPAN_A_MICB_CFILT_1_VAL			(0x129)
+#define TAPAN_A_MICB_CFILT_1_VAL__POR				(0x80)
+#define TAPAN_A_MICB_CFILT_1_PRECHRG			(0x12A)
+#define TAPAN_A_MICB_CFILT_1_PRECHRG__POR				(0x00)
+#define TAPAN_A_MICB_1_CTL			(0x12B)
+#define TAPAN_A_MICB_1_CTL__POR				(0x02)
+#define TAPAN_A_MICB_1_INT_RBIAS			(0x12C)
+#define TAPAN_A_MICB_1_INT_RBIAS__POR				(0x24)
+#define TAPAN_A_MICB_1_MBHC			(0x12D)
+#define TAPAN_A_MICB_1_MBHC__POR				(0x01)
+#define TAPAN_A_MICB_CFILT_2_CTL			(0x12E)
+#define TAPAN_A_MICB_CFILT_2_CTL__POR				(0x40)
+#define TAPAN_A_MICB_CFILT_2_VAL			(0x12F)
+#define TAPAN_A_MICB_CFILT_2_VAL__POR				(0x80)
+#define TAPAN_A_MICB_CFILT_2_PRECHRG			(0x130)
+#define TAPAN_A_MICB_CFILT_2_PRECHRG__POR				(0x00)
+#define TAPAN_A_MICB_2_CTL			(0x131)
+#define TAPAN_A_MICB_2_CTL__POR				(0x12)
+#define TAPAN_A_MICB_2_INT_RBIAS			(0x132)
+#define TAPAN_A_MICB_2_INT_RBIAS__POR				(0x24)
+#define TAPAN_A_MICB_2_MBHC			(0x133)
+#define TAPAN_A_MICB_2_MBHC__POR				(0x02)
+#define TAPAN_A_MICB_CFILT_3_CTL			(0x134)
+#define TAPAN_A_MICB_CFILT_3_CTL__POR				(0x40)
+#define TAPAN_A_MICB_CFILT_3_VAL			(0x135)
+#define TAPAN_A_MICB_CFILT_3_VAL__POR				(0x80)
+#define TAPAN_A_MICB_CFILT_3_PRECHRG			(0x136)
+#define TAPAN_A_MICB_CFILT_3_PRECHRG__POR				(0x00)
+#define TAPAN_A_MICB_3_CTL			(0x137)
+#define TAPAN_A_MICB_3_CTL__POR				(0x02)
+#define TAPAN_A_MICB_3_INT_RBIAS			(0x138)
+#define TAPAN_A_MICB_3_INT_RBIAS__POR				(0x24)
+#define TAPAN_A_MICB_3_MBHC			(0x139)
+#define TAPAN_A_MICB_3_MBHC__POR				(0x00)
+#define TAPAN_A_MBHC_INSERT_DETECT			(0x14A)
+#define TAPAN_A_MBHC_INSERT_DETECT__POR				(0x00)
+#define TAPAN_A_MBHC_INSERT_DET_STATUS			(0x14B)
+#define TAPAN_A_MBHC_INSERT_DET_STATUS__POR				(0x00)
+#define TAPAN_A_TX_COM_BIAS			(0x14C)
+#define TAPAN_A_TX_COM_BIAS__POR				(0xF0)
+#define TAPAN_A_MBHC_SCALING_MUX_1			(0x14E)
+#define TAPAN_A_MBHC_SCALING_MUX_1__POR				(0x00)
+#define TAPAN_A_MBHC_SCALING_MUX_2			(0x14F)
+#define TAPAN_A_MBHC_SCALING_MUX_2__POR				(0x80)
+#define TAPAN_A_RESERVED_MAD_ANA_CTRL			(0x150)
+#define TAPAN_A_RESERVED_MAD_ANA_CTRL__POR				(0xF1)
+#define TAPAN_A_TX_SUP_SWITCH_CTRL_1			(0x151)
+#define TAPAN_A_TX_SUP_SWITCH_CTRL_1__POR				(0x00)
+#define TAPAN_A_TX_SUP_SWITCH_CTRL_2			(0x152)
+#define TAPAN_A_TX_SUP_SWITCH_CTRL_2__POR				(0x80)
+#define TAPAN_A_TX_1_EN			(0x153)
+#define TAPAN_A_TX_1_EN__POR				(0x02)
+#define TAPAN_A_TX_2_EN			(0x154)
+#define TAPAN_A_TX_2_EN__POR				(0x02)
+#define TAPAN_A_TX_1_2_ADC_CH1			(0x155)
+#define TAPAN_A_TX_1_2_ADC_CH1__POR				(0x44)
+#define TAPAN_A_TX_1_2_ADC_CH2			(0x156)
+#define TAPAN_A_TX_1_2_ADC_CH2__POR				(0x44)
+#define TAPAN_A_TX_1_2_ATEST_REFCTRL			(0x157)
+#define TAPAN_A_TX_1_2_ATEST_REFCTRL__POR				(0x00)
+#define TAPAN_A_TX_1_2_TEST_CTL			(0x158)
+#define TAPAN_A_TX_1_2_TEST_CTL__POR				(0x38)
+#define TAPAN_A_TX_1_2_TEST_BLOCK_EN			(0x159)
+#define TAPAN_A_TX_1_2_TEST_BLOCK_EN__POR				(0xFC)
+#define TAPAN_A_TX_1_2_TXFE_CLKDIV			(0x15A)
+#define TAPAN_A_TX_1_2_TXFE_CLKDIV__POR				(0x55)
+#define TAPAN_A_TX_1_2_SAR_ERR_CH1			(0x15B)
+#define TAPAN_A_TX_1_2_SAR_ERR_CH1__POR				(0x00)
+#define TAPAN_A_TX_1_2_SAR_ERR_CH2			(0x15C)
+#define TAPAN_A_TX_1_2_SAR_ERR_CH2__POR				(0x00)
+#define TAPAN_A_TX_3_EN			(0x15D)
+#define TAPAN_A_TX_3_EN__POR				(0x00)
+#define TAPAN_A_TX_1_2_TEST_EN			(0x15E)
+#define TAPAN_A_TX_1_2_TEST_EN__POR				(0xCC)
+#define TAPAN_A_TX_4_5_TXFE_SC_CTL			(0x15F)
+#define TAPAN_A_TX_4_5_TXFE_SC_CTL__POR				(0x00)
+#define TAPAN_A_TX_4_5_TEST_EN			(0x160)
+#define TAPAN_A_TX_4_5_TEST_EN__POR				(0xCC)
+#define TAPAN_A_TX_4_EN			(0x167)
+#define TAPAN_A_TX_4_EN__POR				(0x02)
+#define TAPAN_A_TX_5_EN			(0x168)
+#define TAPAN_A_TX_5_EN__POR				(0x02)
+#define TAPAN_A_TX_4_5_ADC_CH4			(0x169)
+#define TAPAN_A_TX_4_5_ADC_CH4__POR				(0x44)
+#define TAPAN_A_TX_4_5_ADC_CH5			(0x16A)
+#define TAPAN_A_TX_4_5_ADC_CH5__POR				(0x44)
+#define TAPAN_A_TX_4_5_ATEST_REFCTRL			(0x16B)
+#define TAPAN_A_TX_4_5_ATEST_REFCTRL__POR				(0x00)
+#define TAPAN_A_TX_4_5_TEST_CTL			(0x16C)
+#define TAPAN_A_TX_4_5_TEST_CTL__POR				(0x38)
+#define TAPAN_A_TX_4_5_TEST_BLOCK_EN			(0x16D)
+#define TAPAN_A_TX_4_5_TEST_BLOCK_EN__POR				(0xFC)
+#define TAPAN_A_TX_4_5_TXFE_CKDIV			(0x16E)
+#define TAPAN_A_TX_4_5_TXFE_CKDIV__POR				(0x55)
+#define TAPAN_A_TX_4_5_SAR_ERR_CH4			(0x16F)
+#define TAPAN_A_TX_4_5_SAR_ERR_CH4__POR				(0x00)
+#define TAPAN_A_TX_4_5_SAR_ERR_CH5			(0x170)
+#define TAPAN_A_TX_4_5_SAR_ERR_CH5__POR				(0x00)
+#define TAPAN_A_TX_7_MBHC_EN			(0x171)
+#define TAPAN_A_TX_7_MBHC_EN__POR				(0x0C)
+#define TAPAN_A_TX_7_MBHC_ATEST_REFCTRL			(0x172)
+#define TAPAN_A_TX_7_MBHC_ATEST_REFCTRL__POR				(0x00)
+#define TAPAN_A_TX_7_MBHC_ADC			(0x173)
+#define TAPAN_A_TX_7_MBHC_ADC__POR				(0x44)
+#define TAPAN_A_TX_7_MBHC_TEST_CTL			(0x174)
+#define TAPAN_A_TX_7_MBHC_TEST_CTL__POR				(0x38)
+#define TAPAN_A_TX_7_MBHC_SAR_ERR			(0x175)
+#define TAPAN_A_TX_7_MBHC_SAR_ERR__POR				(0x00)
+#define TAPAN_A_TX_7_TXFE_CLKDIV			(0x176)
+#define TAPAN_A_TX_7_TXFE_CLKDIV__POR				(0x0B)
+#define TAPAN_A_BUCK_MODE_1			(0x181)
+#define TAPAN_A_BUCK_MODE_1__POR				(0x21)
+#define TAPAN_A_BUCK_MODE_2			(0x182)
+#define TAPAN_A_BUCK_MODE_2__POR				(0xFF)
+#define TAPAN_A_BUCK_MODE_3			(0x183)
+#define TAPAN_A_BUCK_MODE_3__POR				(0xCE)
+#define TAPAN_A_BUCK_MODE_4			(0x184)
+#define TAPAN_A_BUCK_MODE_4__POR				(0x3A)
+#define TAPAN_A_BUCK_MODE_5			(0x185)
+#define TAPAN_A_BUCK_MODE_5__POR				(0x00)
+#define TAPAN_A_BUCK_CTRL_VCL_1			(0x186)
+#define TAPAN_A_BUCK_CTRL_VCL_1__POR				(0x08)
+#define TAPAN_A_BUCK_CTRL_VCL_2			(0x187)
+#define TAPAN_A_BUCK_CTRL_VCL_2__POR				(0xA3)
+#define TAPAN_A_BUCK_CTRL_VCL_3			(0x188)
+#define TAPAN_A_BUCK_CTRL_VCL_3__POR				(0x82)
+#define TAPAN_A_BUCK_CTRL_CCL_1			(0x189)
+#define TAPAN_A_BUCK_CTRL_CCL_1__POR				(0x5B)
+#define TAPAN_A_BUCK_CTRL_CCL_2			(0x18A)
+#define TAPAN_A_BUCK_CTRL_CCL_2__POR				(0xDC)
+#define TAPAN_A_BUCK_CTRL_CCL_3			(0x18B)
+#define TAPAN_A_BUCK_CTRL_CCL_3__POR				(0x6A)
+#define TAPAN_A_BUCK_CTRL_CCL_4			(0x18C)
+#define TAPAN_A_BUCK_CTRL_CCL_4__POR				(0x50)
+#define TAPAN_A_BUCK_CTRL_PWM_DRVR_1			(0x18D)
+#define TAPAN_A_BUCK_CTRL_PWM_DRVR_1__POR				(0x50)
+#define TAPAN_A_BUCK_CTRL_PWM_DRVR_2			(0x18E)
+#define TAPAN_A_BUCK_CTRL_PWM_DRVR_2__POR				(0x64)
+#define TAPAN_A_BUCK_CTRL_PWM_DRVR_3			(0x18F)
+#define TAPAN_A_BUCK_CTRL_PWM_DRVR_3__POR				(0x77)
+#define TAPAN_A_BUCK_TMUX_A_D			(0x190)
+#define TAPAN_A_BUCK_TMUX_A_D__POR				(0x00)
+#define TAPAN_A_NCP_BUCKREF			(0x191)
+#define TAPAN_A_NCP_BUCKREF__POR				(0x00)
+#define TAPAN_A_NCP_EN			(0x192)
+#define TAPAN_A_NCP_EN__POR				(0xFE)
+#define TAPAN_A_NCP_CLK			(0x193)
+#define TAPAN_A_NCP_CLK__POR				(0x94)
+#define TAPAN_A_NCP_STATIC			(0x194)
+#define TAPAN_A_NCP_STATIC__POR				(0x28)
+#define TAPAN_A_NCP_VTH_LOW			(0x195)
+#define TAPAN_A_NCP_VTH_LOW__POR				(0x88)
+#define TAPAN_A_NCP_VTH_HIGH			(0x196)
+#define TAPAN_A_NCP_VTH_HIGH__POR				(0xA0)
+#define TAPAN_A_NCP_ATEST			(0x197)
+#define TAPAN_A_NCP_ATEST__POR				(0x00)
+#define TAPAN_A_NCP_DTEST			(0x198)
+#define TAPAN_A_NCP_DTEST__POR				(0x10)
+#define TAPAN_A_NCP_DLY1			(0x199)
+#define TAPAN_A_NCP_DLY1__POR				(0x06)
+#define TAPAN_A_NCP_DLY2			(0x19A)
+#define TAPAN_A_NCP_DLY2__POR				(0x06)
+#define TAPAN_A_RX_AUX_SW_CTL			(0x19B)
+#define TAPAN_A_RX_AUX_SW_CTL__POR				(0x00)
+#define TAPAN_A_RX_PA_AUX_IN_CONN			(0x19C)
+#define TAPAN_A_RX_PA_AUX_IN_CONN__POR				(0x00)
+#define TAPAN_A_RX_COM_TIMER_DIV			(0x19E)
+#define TAPAN_A_RX_COM_TIMER_DIV__POR				(0xE8)
+#define TAPAN_A_RX_COM_OCP_CTL			(0x19F)
+#define TAPAN_A_RX_COM_OCP_CTL__POR				(0x1F)
+#define TAPAN_A_RX_COM_OCP_COUNT			(0x1A0)
+#define TAPAN_A_RX_COM_OCP_COUNT__POR				(0x77)
+#define TAPAN_A_RX_COM_DAC_CTL			(0x1A1)
+#define TAPAN_A_RX_COM_DAC_CTL__POR				(0x00)
+#define TAPAN_A_RX_COM_BIAS			(0x1A2)
+#define TAPAN_A_RX_COM_BIAS__POR				(0x00)
+#define TAPAN_A_RX_HPH_AUTO_CHOP			(0x1A4)
+#define TAPAN_A_RX_HPH_AUTO_CHOP__POR				(0x38)
+#define TAPAN_A_RX_HPH_CHOP_CTL			(0x1A5)
+#define TAPAN_A_RX_HPH_CHOP_CTL__POR				(0xA4)
+#define TAPAN_A_RX_HPH_BIAS_PA			(0x1A6)
+#define TAPAN_A_RX_HPH_BIAS_PA__POR				(0x7A)
+#define TAPAN_A_RX_HPH_BIAS_LDO			(0x1A7)
+#define TAPAN_A_RX_HPH_BIAS_LDO__POR				(0x87)
+#define TAPAN_A_RX_HPH_BIAS_CNP			(0x1A8)
+#define TAPAN_A_RX_HPH_BIAS_CNP__POR				(0x8A)
+#define TAPAN_A_RX_HPH_BIAS_WG_OCP			(0x1A9)
+#define TAPAN_A_RX_HPH_BIAS_WG_OCP__POR				(0x2A)
+#define TAPAN_A_RX_HPH_OCP_CTL			(0x1AA)
+#define TAPAN_A_RX_HPH_OCP_CTL__POR				(0x69)
+#define TAPAN_A_RX_HPH_CNP_EN			(0x1AB)
+#define TAPAN_A_RX_HPH_CNP_EN__POR				(0x80)
+#define TAPAN_A_RX_HPH_CNP_WG_CTL			(0x1AC)
+#define TAPAN_A_RX_HPH_CNP_WG_CTL__POR				(0xDE)
+#define TAPAN_A_RX_HPH_CNP_WG_TIME			(0x1AD)
+#define TAPAN_A_RX_HPH_CNP_WG_TIME__POR				(0x15)
+#define TAPAN_A_RX_HPH_L_GAIN			(0x1AE)
+#define TAPAN_A_RX_HPH_L_GAIN__POR				(0x00)
+#define TAPAN_A_RX_HPH_L_TEST			(0x1AF)
+#define TAPAN_A_RX_HPH_L_TEST__POR				(0x00)
+#define TAPAN_A_RX_HPH_L_PA_CTL			(0x1B0)
+#define TAPAN_A_RX_HPH_L_PA_CTL__POR				(0x40)
+#define TAPAN_A_RX_HPH_L_DAC_CTL			(0x1B1)
+#define TAPAN_A_RX_HPH_L_DAC_CTL__POR				(0x00)
+#define TAPAN_A_RX_HPH_L_ATEST			(0x1B2)
+#define TAPAN_A_RX_HPH_L_ATEST__POR				(0x00)
+#define TAPAN_A_RX_HPH_L_STATUS			(0x1B3)
+#define TAPAN_A_RX_HPH_L_STATUS__POR				(0x00)
+#define TAPAN_A_RX_HPH_R_GAIN			(0x1B4)
+#define TAPAN_A_RX_HPH_R_GAIN__POR				(0x00)
+#define TAPAN_A_RX_HPH_R_TEST			(0x1B5)
+#define TAPAN_A_RX_HPH_R_TEST__POR				(0x00)
+#define TAPAN_A_RX_HPH_R_PA_CTL			(0x1B6)
+#define TAPAN_A_RX_HPH_R_PA_CTL__POR				(0x40)
+#define TAPAN_A_RX_HPH_R_DAC_CTL			(0x1B7)
+#define TAPAN_A_RX_HPH_R_DAC_CTL__POR				(0x00)
+#define TAPAN_A_RX_HPH_R_ATEST			(0x1B8)
+#define TAPAN_A_RX_HPH_R_ATEST__POR				(0x00)
+#define TAPAN_A_RX_HPH_R_STATUS			(0x1B9)
+#define TAPAN_A_RX_HPH_R_STATUS__POR				(0x00)
+#define TAPAN_A_RX_EAR_BIAS_PA			(0x1BA)
+#define TAPAN_A_RX_EAR_BIAS_PA__POR				(0x76)
+#define TAPAN_A_RX_EAR_BIAS_CMBUFF			(0x1BB)
+#define TAPAN_A_RX_EAR_BIAS_CMBUFF__POR				(0xA0)
+#define TAPAN_A_RX_EAR_EN			(0x1BC)
+#define TAPAN_A_RX_EAR_EN__POR				(0x00)
+#define TAPAN_A_RX_EAR_GAIN			(0x1BD)
+#define TAPAN_A_RX_EAR_GAIN__POR				(0x02)
+#define TAPAN_A_RX_EAR_CMBUFF			(0x1BE)
+#define TAPAN_A_RX_EAR_CMBUFF__POR				(0x05)
+#define TAPAN_A_RX_EAR_ICTL			(0x1BF)
+#define TAPAN_A_RX_EAR_ICTL__POR				(0x40)
+#define TAPAN_A_RX_EAR_CCOMP			(0x1C0)
+#define TAPAN_A_RX_EAR_CCOMP__POR				(0x08)
+#define TAPAN_A_RX_EAR_VCM			(0x1C1)
+#define TAPAN_A_RX_EAR_VCM__POR				(0x03)
+#define TAPAN_A_RX_EAR_CNP			(0x1C2)
+#define TAPAN_A_RX_EAR_CNP__POR				(0xF2)
+#define TAPAN_A_RX_EAR_DAC_CTL_ATEST			(0x1C3)
+#define TAPAN_A_RX_EAR_DAC_CTL_ATEST__POR				(0x00)
+#define TAPAN_A_RX_EAR_STATUS			(0x1C5)
+#define TAPAN_A_RX_EAR_STATUS__POR				(0x04)
+#define TAPAN_A_RX_LINE_BIAS_PA			(0x1C6)
+#define TAPAN_A_RX_LINE_BIAS_PA__POR				(0x78)
+#define TAPAN_A_RX_BUCK_BIAS1			(0x1C7)
+#define TAPAN_A_RX_BUCK_BIAS1__POR				(0x42)
+#define TAPAN_A_RX_BUCK_BIAS2			(0x1C8)
+#define TAPAN_A_RX_BUCK_BIAS2__POR				(0x84)
+#define TAPAN_A_RX_LINE_COM			(0x1C9)
+#define TAPAN_A_RX_LINE_COM__POR				(0x80)
+#define TAPAN_A_RX_LINE_CNP_EN			(0x1CA)
+#define TAPAN_A_RX_LINE_CNP_EN__POR				(0x00)
+#define TAPAN_A_RX_LINE_CNP_WG_CTL			(0x1CB)
+#define TAPAN_A_RX_LINE_CNP_WG_CTL__POR				(0x00)
+#define TAPAN_A_RX_LINE_CNP_WG_TIME			(0x1CC)
+#define TAPAN_A_RX_LINE_CNP_WG_TIME__POR				(0x04)
+#define TAPAN_A_RX_LINE_1_GAIN			(0x1CD)
+#define TAPAN_A_RX_LINE_1_GAIN__POR				(0x00)
+#define TAPAN_A_RX_LINE_1_TEST			(0x1CE)
+#define TAPAN_A_RX_LINE_1_TEST__POR				(0x00)
+#define TAPAN_A_RX_LINE_1_DAC_CTL			(0x1CF)
+#define TAPAN_A_RX_LINE_1_DAC_CTL__POR				(0x00)
+#define TAPAN_A_RX_LINE_1_STATUS			(0x1D0)
+#define TAPAN_A_RX_LINE_1_STATUS__POR				(0x00)
+#define TAPAN_A_RX_LINE_2_GAIN			(0x1D1)
+#define TAPAN_A_RX_LINE_2_GAIN__POR				(0x00)
+#define TAPAN_A_RX_LINE_2_TEST			(0x1D2)
+#define TAPAN_A_RX_LINE_2_TEST__POR				(0x00)
+#define TAPAN_A_RX_LINE_2_DAC_CTL			(0x1D3)
+#define TAPAN_A_RX_LINE_2_DAC_CTL__POR				(0x00)
+#define TAPAN_A_RX_LINE_2_STATUS			(0x1D4)
+#define TAPAN_A_RX_LINE_2_STATUS__POR				(0x00)
+#define TAPAN_A_RX_LINE_CNP_DBG			(0x1DD)
+#define TAPAN_A_RX_LINE_CNP_DBG__POR				(0x00)
+#define TAPAN_A_SPKR_DRV_EN			(0x1DF)
+#define TAPAN_A_SPKR_DRV_EN__POR				(0x6F)
+#define TAPAN_A_SPKR_DRV_GAIN			(0x1E0)
+#define TAPAN_A_SPKR_DRV_GAIN__POR				(0x00)
+#define TAPAN_A_SPKR_DRV_DAC_CTL			(0x1E1)
+#define TAPAN_A_SPKR_DRV_DAC_CTL__POR				(0x04)
+#define TAPAN_A_SPKR_DRV_OCP_CTL			(0x1E2)
+#define TAPAN_A_SPKR_DRV_OCP_CTL__POR				(0x98)
+#define TAPAN_A_SPKR_DRV_CLIP_DET			(0x1E3)
+#define TAPAN_A_SPKR_DRV_CLIP_DET__POR				(0x48)
+#define TAPAN_A_SPKR_DRV_IEC			(0x1E4)
+#define TAPAN_A_SPKR_DRV_IEC__POR				(0x28)
+#define TAPAN_A_SPKR_DRV_DBG_DAC			(0x1E5)
+#define TAPAN_A_SPKR_DRV_DBG_DAC__POR				(0x05)
+#define TAPAN_A_SPKR_DRV_DBG_PA			(0x1E6)
+#define TAPAN_A_SPKR_DRV_DBG_PA__POR				(0x18)
+#define TAPAN_A_SPKR_DRV_DBG_PWRSTG			(0x1E7)
+#define TAPAN_A_SPKR_DRV_DBG_PWRSTG__POR				(0x00)
+#define TAPAN_A_SPKR_DRV_BIAS_LDO			(0x1E8)
+#define TAPAN_A_SPKR_DRV_BIAS_LDO__POR				(0x45)
+#define TAPAN_A_SPKR_DRV_BIAS_INT			(0x1E9)
+#define TAPAN_A_SPKR_DRV_BIAS_INT__POR				(0xA5)
+#define TAPAN_A_SPKR_DRV_BIAS_PA			(0x1EA)
+#define TAPAN_A_SPKR_DRV_BIAS_PA__POR				(0x55)
+#define TAPAN_A_SPKR_DRV_STATUS_OCP			(0x1EB)
+#define TAPAN_A_SPKR_DRV_STATUS_OCP__POR				(0x00)
+#define TAPAN_A_SPKR_DRV_STATUS_PA			(0x1EC)
+#define TAPAN_A_SPKR_DRV_STATUS_PA__POR				(0x00)
+#define TAPAN_A_RC_OSC_FREQ			(0x1FA)
+#define TAPAN_A_RC_OSC_FREQ__POR				(0x46)
+#define TAPAN_A_RC_OSC_TEST			(0x1FB)
+#define TAPAN_A_RC_OSC_TEST__POR				(0x0A)
+#define TAPAN_A_RC_OSC_STATUS			(0x1FC)
+#define TAPAN_A_RC_OSC_STATUS__POR				(0x18)
+#define TAPAN_A_RC_OSC_TUNER			(0x1FD)
+#define TAPAN_A_RC_OSC_TUNER__POR				(0x00)
+#define TAPAN_A_MBHC_HPH			(0x1FE)
+#define TAPAN_A_MBHC_HPH__POR				(0x44)
+#define TAPAN_A_CDC_ANC1_B1_CTL			(0x200)
+#define TAPAN_A_CDC_ANC1_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_ANC2_B1_CTL			(0x280)
+#define TAPAN_A_CDC_ANC2_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_ANC1_SHIFT			(0x201)
+#define TAPAN_A_CDC_ANC1_SHIFT__POR				(0x00)
+#define TAPAN_A_CDC_ANC2_SHIFT			(0x281)
+#define TAPAN_A_CDC_ANC2_SHIFT__POR				(0x00)
+#define TAPAN_A_CDC_ANC1_IIR_B1_CTL			(0x202)
+#define TAPAN_A_CDC_ANC1_IIR_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_ANC2_IIR_B1_CTL			(0x282)
+#define TAPAN_A_CDC_ANC2_IIR_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_ANC1_IIR_B2_CTL			(0x203)
+#define TAPAN_A_CDC_ANC1_IIR_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_ANC2_IIR_B2_CTL			(0x283)
+#define TAPAN_A_CDC_ANC2_IIR_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_ANC1_IIR_B3_CTL			(0x204)
+#define TAPAN_A_CDC_ANC1_IIR_B3_CTL__POR				(0x00)
+#define TAPAN_A_CDC_ANC2_IIR_B3_CTL			(0x284)
+#define TAPAN_A_CDC_ANC2_IIR_B3_CTL__POR				(0x00)
+#define TAPAN_A_CDC_ANC1_LPF_B1_CTL			(0x206)
+#define TAPAN_A_CDC_ANC1_LPF_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_ANC2_LPF_B1_CTL			(0x286)
+#define TAPAN_A_CDC_ANC2_LPF_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_ANC1_LPF_B2_CTL			(0x207)
+#define TAPAN_A_CDC_ANC1_LPF_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_ANC2_LPF_B2_CTL			(0x287)
+#define TAPAN_A_CDC_ANC2_LPF_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_ANC1_SPARE			(0x209)
+#define TAPAN_A_CDC_ANC1_SPARE__POR				(0x00)
+#define TAPAN_A_CDC_ANC2_SPARE			(0x289)
+#define TAPAN_A_CDC_ANC2_SPARE__POR				(0x00)
+#define TAPAN_A_CDC_ANC1_SMLPF_CTL			(0x20A)
+#define TAPAN_A_CDC_ANC1_SMLPF_CTL__POR				(0x00)
+#define TAPAN_A_CDC_ANC2_SMLPF_CTL			(0x28A)
+#define TAPAN_A_CDC_ANC2_SMLPF_CTL__POR				(0x00)
+#define TAPAN_A_CDC_ANC1_DCFLT_CTL			(0x20B)
+#define TAPAN_A_CDC_ANC1_DCFLT_CTL__POR				(0x00)
+#define TAPAN_A_CDC_ANC2_DCFLT_CTL			(0x28B)
+#define TAPAN_A_CDC_ANC2_DCFLT_CTL__POR				(0x00)
+#define TAPAN_A_CDC_ANC1_GAIN_CTL			(0x20C)
+#define TAPAN_A_CDC_ANC1_GAIN_CTL__POR				(0x00)
+#define TAPAN_A_CDC_ANC2_GAIN_CTL			(0x28C)
+#define TAPAN_A_CDC_ANC2_GAIN_CTL__POR				(0x00)
+#define TAPAN_A_CDC_ANC1_B2_CTL			(0x20D)
+#define TAPAN_A_CDC_ANC1_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_ANC2_B2_CTL			(0x28D)
+#define TAPAN_A_CDC_ANC2_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_TX1_VOL_CTL_TIMER			(0x220)
+#define TAPAN_A_CDC_TX1_VOL_CTL_TIMER__POR				(0x00)
+#define TAPAN_A_CDC_TX2_VOL_CTL_TIMER			(0x228)
+#define TAPAN_A_CDC_TX2_VOL_CTL_TIMER__POR				(0x00)
+#define TAPAN_A_CDC_TX3_VOL_CTL_TIMER			(0x230)
+#define TAPAN_A_CDC_TX3_VOL_CTL_TIMER__POR				(0x00)
+#define TAPAN_A_CDC_TX4_VOL_CTL_TIMER			(0x238)
+#define TAPAN_A_CDC_TX4_VOL_CTL_TIMER__POR				(0x00)
+#define TAPAN_A_CDC_TX1_VOL_CTL_GAIN			(0x221)
+#define TAPAN_A_CDC_TX1_VOL_CTL_GAIN__POR				(0x00)
+#define TAPAN_A_CDC_TX2_VOL_CTL_GAIN			(0x229)
+#define TAPAN_A_CDC_TX2_VOL_CTL_GAIN__POR				(0x00)
+#define TAPAN_A_CDC_TX3_VOL_CTL_GAIN			(0x231)
+#define TAPAN_A_CDC_TX3_VOL_CTL_GAIN__POR				(0x00)
+#define TAPAN_A_CDC_TX4_VOL_CTL_GAIN			(0x239)
+#define TAPAN_A_CDC_TX4_VOL_CTL_GAIN__POR				(0x00)
+#define TAPAN_A_CDC_TX1_VOL_CTL_CFG			(0x222)
+#define TAPAN_A_CDC_TX1_VOL_CTL_CFG__POR				(0x00)
+#define TAPAN_A_CDC_TX2_VOL_CTL_CFG			(0x22A)
+#define TAPAN_A_CDC_TX2_VOL_CTL_CFG__POR				(0x00)
+#define TAPAN_A_CDC_TX3_VOL_CTL_CFG			(0x232)
+#define TAPAN_A_CDC_TX3_VOL_CTL_CFG__POR				(0x00)
+#define TAPAN_A_CDC_TX4_VOL_CTL_CFG			(0x23A)
+#define TAPAN_A_CDC_TX4_VOL_CTL_CFG__POR				(0x00)
+#define TAPAN_A_CDC_TX1_MUX_CTL			(0x223)
+#define TAPAN_A_CDC_TX1_MUX_CTL__POR				(0x00)
+#define TAPAN_A_CDC_TX2_MUX_CTL			(0x22B)
+#define TAPAN_A_CDC_TX2_MUX_CTL__POR				(0x00)
+#define TAPAN_A_CDC_TX3_MUX_CTL			(0x233)
+#define TAPAN_A_CDC_TX3_MUX_CTL__POR				(0x00)
+#define TAPAN_A_CDC_TX4_MUX_CTL			(0x23B)
+#define TAPAN_A_CDC_TX4_MUX_CTL__POR				(0x00)
+#define TAPAN_A_CDC_TX1_CLK_FS_CTL			(0x224)
+#define TAPAN_A_CDC_TX1_CLK_FS_CTL__POR				(0x00)
+#define TAPAN_A_CDC_TX2_CLK_FS_CTL			(0x22C)
+#define TAPAN_A_CDC_TX2_CLK_FS_CTL__POR				(0x00)
+#define TAPAN_A_CDC_TX3_CLK_FS_CTL			(0x234)
+#define TAPAN_A_CDC_TX3_CLK_FS_CTL__POR				(0x00)
+#define TAPAN_A_CDC_TX4_CLK_FS_CTL			(0x23C)
+#define TAPAN_A_CDC_TX4_CLK_FS_CTL__POR				(0x00)
+#define TAPAN_A_CDC_TX1_DMIC_CTL			(0x225)
+#define TAPAN_A_CDC_TX1_DMIC_CTL__POR				(0x00)
+#define TAPAN_A_CDC_TX2_DMIC_CTL			(0x22D)
+#define TAPAN_A_CDC_TX2_DMIC_CTL__POR				(0x00)
+#define TAPAN_A_CDC_TX3_DMIC_CTL			(0x235)
+#define TAPAN_A_CDC_TX3_DMIC_CTL__POR				(0x00)
+#define TAPAN_A_CDC_TX4_DMIC_CTL			(0x23D)
+#define TAPAN_A_CDC_TX4_DMIC_CTL__POR				(0x00)
+#define TAPAN_A_CDC_DEBUG_B1_CTL			(0x278)
+#define TAPAN_A_CDC_DEBUG_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_DEBUG_B2_CTL			(0x279)
+#define TAPAN_A_CDC_DEBUG_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_DEBUG_B3_CTL			(0x27A)
+#define TAPAN_A_CDC_DEBUG_B3_CTL__POR				(0x00)
+#define TAPAN_A_CDC_DEBUG_B4_CTL			(0x27B)
+#define TAPAN_A_CDC_DEBUG_B4_CTL__POR				(0x00)
+#define TAPAN_A_CDC_DEBUG_B5_CTL			(0x27C)
+#define TAPAN_A_CDC_DEBUG_B5_CTL__POR				(0x00)
+#define TAPAN_A_CDC_DEBUG_B6_CTL			(0x27D)
+#define TAPAN_A_CDC_DEBUG_B6_CTL__POR				(0x00)
+#define TAPAN_A_CDC_DEBUG_B7_CTL			(0x27E)
+#define TAPAN_A_CDC_DEBUG_B7_CTL__POR				(0x00)
+#define TAPAN_A_CDC_SRC1_PDA_CFG			(0x2A0)
+#define TAPAN_A_CDC_SRC1_PDA_CFG__POR				(0x00)
+#define TAPAN_A_CDC_SRC2_PDA_CFG			(0x2A8)
+#define TAPAN_A_CDC_SRC2_PDA_CFG__POR				(0x00)
+#define TAPAN_A_CDC_SRC1_FS_CTL			(0x2A1)
+#define TAPAN_A_CDC_SRC1_FS_CTL__POR				(0x00)
+#define TAPAN_A_CDC_SRC2_FS_CTL			(0x2A9)
+#define TAPAN_A_CDC_SRC2_FS_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX1_B1_CTL			(0x2B0)
+#define TAPAN_A_CDC_RX1_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX2_B1_CTL			(0x2B8)
+#define TAPAN_A_CDC_RX2_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX3_B1_CTL			(0x2C0)
+#define TAPAN_A_CDC_RX3_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX4_B1_CTL			(0x2C8)
+#define TAPAN_A_CDC_RX4_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX1_B2_CTL			(0x2B1)
+#define TAPAN_A_CDC_RX1_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX2_B2_CTL			(0x2B9)
+#define TAPAN_A_CDC_RX2_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX3_B2_CTL			(0x2C1)
+#define TAPAN_A_CDC_RX3_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX4_B2_CTL			(0x2C9)
+#define TAPAN_A_CDC_RX4_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX1_B3_CTL			(0x2B2)
+#define TAPAN_A_CDC_RX1_B3_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX2_B3_CTL			(0x2BA)
+#define TAPAN_A_CDC_RX2_B3_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX3_B3_CTL			(0x2C2)
+#define TAPAN_A_CDC_RX3_B3_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX4_B3_CTL			(0x2CA)
+#define TAPAN_A_CDC_RX4_B3_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX1_B4_CTL			(0x2B3)
+#define TAPAN_A_CDC_RX1_B4_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX2_B4_CTL			(0x2BB)
+#define TAPAN_A_CDC_RX2_B4_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX3_B4_CTL			(0x2C3)
+#define TAPAN_A_CDC_RX3_B4_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX4_B4_CTL			(0x2CB)
+#define TAPAN_A_CDC_RX4_B4_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX1_B5_CTL			(0x2B4)
+#define TAPAN_A_CDC_RX1_B5_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX2_B5_CTL			(0x2BC)
+#define TAPAN_A_CDC_RX2_B5_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX3_B5_CTL			(0x2C4)
+#define TAPAN_A_CDC_RX3_B5_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX4_B5_CTL			(0x2CC)
+#define TAPAN_A_CDC_RX4_B5_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX1_B6_CTL			(0x2B5)
+#define TAPAN_A_CDC_RX1_B6_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX2_B6_CTL			(0x2BD)
+#define TAPAN_A_CDC_RX2_B6_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX3_B6_CTL			(0x2C5)
+#define TAPAN_A_CDC_RX3_B6_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX4_B6_CTL			(0x2CD)
+#define TAPAN_A_CDC_RX4_B6_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX1_VOL_CTL_B1_CTL			(0x2B6)
+#define TAPAN_A_CDC_RX1_VOL_CTL_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX2_VOL_CTL_B1_CTL			(0x2BE)
+#define TAPAN_A_CDC_RX2_VOL_CTL_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX3_VOL_CTL_B1_CTL			(0x2C6)
+#define TAPAN_A_CDC_RX3_VOL_CTL_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX4_VOL_CTL_B1_CTL			(0x2CE)
+#define TAPAN_A_CDC_RX4_VOL_CTL_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX1_VOL_CTL_B2_CTL			(0x2B7)
+#define TAPAN_A_CDC_RX1_VOL_CTL_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX2_VOL_CTL_B2_CTL			(0x2BF)
+#define TAPAN_A_CDC_RX2_VOL_CTL_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX3_VOL_CTL_B2_CTL			(0x2C7)
+#define TAPAN_A_CDC_RX3_VOL_CTL_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_RX4_VOL_CTL_B2_CTL			(0x2CF)
+#define TAPAN_A_CDC_RX4_VOL_CTL_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CLK_ANC_RESET_CTL			(0x300)
+#define TAPAN_A_CDC_CLK_ANC_RESET_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CLK_RX_RESET_CTL			(0x301)
+#define TAPAN_A_CDC_CLK_RX_RESET_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CLK_TX_RESET_B1_CTL			(0x302)
+#define TAPAN_A_CDC_CLK_TX_RESET_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CLK_TX_RESET_B2_CTL			(0x303)
+#define TAPAN_A_CDC_CLK_TX_RESET_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CLK_DMIC_B1_CTL			(0x304)
+#define TAPAN_A_CDC_CLK_DMIC_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CLK_DMIC_B2_CTL			(0x305)
+#define TAPAN_A_CDC_CLK_DMIC_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CLK_I2S_CTL			(0x306)
+#define TAPAN_A_CDC_CLK_I2S_CTL__POR				(0x03)
+#define TAPAN_A_CDC_CLK_OTHR_RESET_B1_CTL			(0x308)
+#define TAPAN_A_CDC_CLK_OTHR_RESET_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CLK_OTHR_RESET_B2_CTL			(0x309)
+#define TAPAN_A_CDC_CLK_OTHR_RESET_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CLK_TX_CLK_EN_B1_CTL			(0x30A)
+#define TAPAN_A_CDC_CLK_TX_CLK_EN_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CLK_TX_CLK_EN_B2_CTL			(0x30B)
+#define TAPAN_A_CDC_CLK_TX_CLK_EN_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CLK_OTHR_CTL			(0x30C)
+#define TAPAN_A_CDC_CLK_OTHR_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CLK_RDAC_CLK_EN_CTL			(0x30D)
+#define TAPAN_A_CDC_CLK_RDAC_CLK_EN_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CLK_ANC_CLK_EN_CTL			(0x30E)
+#define TAPAN_A_CDC_CLK_ANC_CLK_EN_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CLK_RX_B1_CTL			(0x30F)
+#define TAPAN_A_CDC_CLK_RX_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CLK_RX_B2_CTL			(0x310)
+#define TAPAN_A_CDC_CLK_RX_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CLK_MCLK_CTL			(0x311)
+#define TAPAN_A_CDC_CLK_MCLK_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CLK_PDM_CTL			(0x312)
+#define TAPAN_A_CDC_CLK_PDM_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CLK_SD_CTL			(0x313)
+#define TAPAN_A_CDC_CLK_SD_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CLK_POWER_CTL			(0x314)
+#define TAPAN_A_CDC_CLK_POWER_CTL__POR				(0x03)
+#define TAPAN_A_CDC_CLSH_B1_CTL			(0x320)
+#define TAPAN_A_CDC_CLSH_B1_CTL__POR				(0x22)
+#define TAPAN_A_CDC_CLSH_B2_CTL			(0x321)
+#define TAPAN_A_CDC_CLSH_B2_CTL__POR				(0x35)
+#define TAPAN_A_CDC_CLSH_B3_CTL			(0x322)
+#define TAPAN_A_CDC_CLSH_B3_CTL__POR				(0x3B)
+#define TAPAN_A_CDC_CLSH_BUCK_NCP_VARS			(0x323)
+#define TAPAN_A_CDC_CLSH_BUCK_NCP_VARS__POR				(0x04)
+#define TAPAN_A_CDC_CLSH_IDLE_HPH_THSD			(0x324)
+#define TAPAN_A_CDC_CLSH_IDLE_HPH_THSD__POR				(0x12)
+#define TAPAN_A_CDC_CLSH_IDLE_EAR_THSD			(0x325)
+#define TAPAN_A_CDC_CLSH_IDLE_EAR_THSD__POR				(0x0C)
+#define TAPAN_A_CDC_CLSH_FCLKONLY_HPH_THSD			(0x326)
+#define TAPAN_A_CDC_CLSH_FCLKONLY_HPH_THSD__POR				(0x18)
+#define TAPAN_A_CDC_CLSH_FCLKONLY_EAR_THSD			(0x327)
+#define TAPAN_A_CDC_CLSH_FCLKONLY_EAR_THSD__POR				(0x23)
+#define TAPAN_A_CDC_CLSH_K_ADDR			(0x328)
+#define TAPAN_A_CDC_CLSH_K_ADDR__POR				(0x00)
+#define TAPAN_A_CDC_CLSH_K_DATA			(0x329)
+#define TAPAN_A_CDC_CLSH_K_DATA__POR				(0xA4)
+#define TAPAN_A_CDC_CLSH_I_PA_FACT_HPH_L			(0x32A)
+#define TAPAN_A_CDC_CLSH_I_PA_FACT_HPH_L__POR				(0xD7)
+#define TAPAN_A_CDC_CLSH_I_PA_FACT_HPH_U			(0x32B)
+#define TAPAN_A_CDC_CLSH_I_PA_FACT_HPH_U__POR				(0x05)
+#define TAPAN_A_CDC_CLSH_I_PA_FACT_EAR_L			(0x32C)
+#define TAPAN_A_CDC_CLSH_I_PA_FACT_EAR_L__POR				(0x60)
+#define TAPAN_A_CDC_CLSH_I_PA_FACT_EAR_U			(0x32D)
+#define TAPAN_A_CDC_CLSH_I_PA_FACT_EAR_U__POR				(0x09)
+#define TAPAN_A_CDC_CLSH_V_PA_HD_EAR			(0x32E)
+#define TAPAN_A_CDC_CLSH_V_PA_HD_EAR__POR				(0x0D)
+#define TAPAN_A_CDC_CLSH_V_PA_HD_HPH			(0x32F)
+#define TAPAN_A_CDC_CLSH_V_PA_HD_HPH__POR				(0x0D)
+#define TAPAN_A_CDC_CLSH_V_PA_MIN_EAR			(0x330)
+#define TAPAN_A_CDC_CLSH_V_PA_MIN_EAR__POR				(0x3A)
+#define TAPAN_A_CDC_CLSH_V_PA_MIN_HPH			(0x331)
+#define TAPAN_A_CDC_CLSH_V_PA_MIN_HPH__POR				(0x1D)
+#define TAPAN_A_CDC_IIR1_GAIN_B1_CTL			(0x340)
+#define TAPAN_A_CDC_IIR1_GAIN_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_IIR2_GAIN_B1_CTL			(0x350)
+#define TAPAN_A_CDC_IIR2_GAIN_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_IIR1_GAIN_B2_CTL			(0x341)
+#define TAPAN_A_CDC_IIR1_GAIN_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_IIR2_GAIN_B2_CTL			(0x351)
+#define TAPAN_A_CDC_IIR2_GAIN_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_IIR1_GAIN_B3_CTL			(0x342)
+#define TAPAN_A_CDC_IIR1_GAIN_B3_CTL__POR				(0x00)
+#define TAPAN_A_CDC_IIR2_GAIN_B3_CTL			(0x352)
+#define TAPAN_A_CDC_IIR2_GAIN_B3_CTL__POR				(0x00)
+#define TAPAN_A_CDC_IIR1_GAIN_B4_CTL			(0x343)
+#define TAPAN_A_CDC_IIR1_GAIN_B4_CTL__POR				(0x00)
+#define TAPAN_A_CDC_IIR2_GAIN_B4_CTL			(0x353)
+#define TAPAN_A_CDC_IIR2_GAIN_B4_CTL__POR				(0x00)
+#define TAPAN_A_CDC_IIR1_GAIN_B5_CTL			(0x344)
+#define TAPAN_A_CDC_IIR1_GAIN_B5_CTL__POR				(0x00)
+#define TAPAN_A_CDC_IIR2_GAIN_B5_CTL			(0x354)
+#define TAPAN_A_CDC_IIR2_GAIN_B5_CTL__POR				(0x00)
+#define TAPAN_A_CDC_IIR1_GAIN_B6_CTL			(0x345)
+#define TAPAN_A_CDC_IIR1_GAIN_B6_CTL__POR				(0x00)
+#define TAPAN_A_CDC_IIR2_GAIN_B6_CTL			(0x355)
+#define TAPAN_A_CDC_IIR2_GAIN_B6_CTL__POR				(0x00)
+#define TAPAN_A_CDC_IIR1_GAIN_B7_CTL			(0x346)
+#define TAPAN_A_CDC_IIR1_GAIN_B7_CTL__POR				(0x00)
+#define TAPAN_A_CDC_IIR2_GAIN_B7_CTL			(0x356)
+#define TAPAN_A_CDC_IIR2_GAIN_B7_CTL__POR				(0x00)
+#define TAPAN_A_CDC_IIR1_GAIN_B8_CTL			(0x347)
+#define TAPAN_A_CDC_IIR1_GAIN_B8_CTL__POR				(0x00)
+#define TAPAN_A_CDC_IIR2_GAIN_B8_CTL			(0x357)
+#define TAPAN_A_CDC_IIR2_GAIN_B8_CTL__POR				(0x00)
+#define TAPAN_A_CDC_IIR1_CTL			(0x348)
+#define TAPAN_A_CDC_IIR1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_IIR2_CTL			(0x358)
+#define TAPAN_A_CDC_IIR2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_IIR1_GAIN_TIMER_CTL			(0x349)
+#define TAPAN_A_CDC_IIR1_GAIN_TIMER_CTL__POR				(0x00)
+#define TAPAN_A_CDC_IIR2_GAIN_TIMER_CTL			(0x359)
+#define TAPAN_A_CDC_IIR2_GAIN_TIMER_CTL__POR				(0x00)
+#define TAPAN_A_CDC_IIR1_COEF_B1_CTL			(0x34A)
+#define TAPAN_A_CDC_IIR1_COEF_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_IIR2_COEF_B1_CTL			(0x35A)
+#define TAPAN_A_CDC_IIR2_COEF_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_IIR1_COEF_B2_CTL			(0x34B)
+#define TAPAN_A_CDC_IIR1_COEF_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_IIR2_COEF_B2_CTL			(0x35B)
+#define TAPAN_A_CDC_IIR2_COEF_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_TOP_GAIN_UPDATE			(0x360)
+#define TAPAN_A_CDC_TOP_GAIN_UPDATE__POR				(0x00)
+#define TAPAN_A_CDC_COMP0_B1_CTL			(0x368)
+#define TAPAN_A_CDC_COMP0_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_COMP1_B1_CTL			(0x370)
+#define TAPAN_A_CDC_COMP1_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_COMP2_B1_CTL			(0x378)
+#define TAPAN_A_CDC_COMP2_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_COMP0_B2_CTL			(0x369)
+#define TAPAN_A_CDC_COMP0_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_COMP1_B2_CTL			(0x371)
+#define TAPAN_A_CDC_COMP1_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_COMP2_B2_CTL			(0x379)
+#define TAPAN_A_CDC_COMP2_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_COMP0_B3_CTL			(0x36A)
+#define TAPAN_A_CDC_COMP0_B3_CTL__POR				(0x00)
+#define TAPAN_A_CDC_COMP1_B3_CTL			(0x372)
+#define TAPAN_A_CDC_COMP1_B3_CTL__POR				(0x00)
+#define TAPAN_A_CDC_COMP2_B3_CTL			(0x37A)
+#define TAPAN_A_CDC_COMP2_B3_CTL__POR				(0x00)
+#define TAPAN_A_CDC_COMP0_B4_CTL			(0x36B)
+#define TAPAN_A_CDC_COMP0_B4_CTL__POR				(0x00)
+#define TAPAN_A_CDC_COMP1_B4_CTL			(0x373)
+#define TAPAN_A_CDC_COMP1_B4_CTL__POR				(0x00)
+#define TAPAN_A_CDC_COMP2_B4_CTL			(0x37B)
+#define TAPAN_A_CDC_COMP2_B4_CTL__POR				(0x00)
+#define TAPAN_A_CDC_COMP0_B5_CTL			(0x36C)
+#define TAPAN_A_CDC_COMP0_B5_CTL__POR				(0x00)
+#define TAPAN_A_CDC_COMP1_B5_CTL			(0x374)
+#define TAPAN_A_CDC_COMP1_B5_CTL__POR				(0x00)
+#define TAPAN_A_CDC_COMP2_B5_CTL			(0x37C)
+#define TAPAN_A_CDC_COMP2_B5_CTL__POR				(0x00)
+#define TAPAN_A_CDC_COMP0_B6_CTL			(0x36D)
+#define TAPAN_A_CDC_COMP0_B6_CTL__POR				(0x00)
+#define TAPAN_A_CDC_COMP1_B6_CTL			(0x375)
+#define TAPAN_A_CDC_COMP1_B6_CTL__POR				(0x00)
+#define TAPAN_A_CDC_COMP2_B6_CTL			(0x37D)
+#define TAPAN_A_CDC_COMP2_B6_CTL__POR				(0x00)
+#define TAPAN_A_CDC_COMP0_SHUT_DOWN_STATUS			(0x36E)
+#define TAPAN_A_CDC_COMP0_SHUT_DOWN_STATUS__POR				(0x00)
+#define TAPAN_A_CDC_COMP1_SHUT_DOWN_STATUS			(0x376)
+#define TAPAN_A_CDC_COMP1_SHUT_DOWN_STATUS__POR				(0x00)
+#define TAPAN_A_CDC_COMP2_SHUT_DOWN_STATUS			(0x37E)
+#define TAPAN_A_CDC_COMP2_SHUT_DOWN_STATUS__POR				(0x00)
+#define TAPAN_A_CDC_COMP0_FS_CFG			(0x36F)
+#define TAPAN_A_CDC_COMP0_FS_CFG__POR				(0x00)
+#define TAPAN_A_CDC_COMP1_FS_CFG			(0x377)
+#define TAPAN_A_CDC_COMP1_FS_CFG__POR				(0x00)
+#define TAPAN_A_CDC_COMP2_FS_CFG			(0x37F)
+#define TAPAN_A_CDC_COMP2_FS_CFG__POR				(0x00)
+#define TAPAN_A_CDC_CONN_RX1_B1_CTL			(0x380)
+#define TAPAN_A_CDC_CONN_RX1_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_RX1_B2_CTL			(0x381)
+#define TAPAN_A_CDC_CONN_RX1_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_RX1_B3_CTL			(0x382)
+#define TAPAN_A_CDC_CONN_RX1_B3_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_RX2_B1_CTL			(0x383)
+#define TAPAN_A_CDC_CONN_RX2_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_RX2_B2_CTL			(0x384)
+#define TAPAN_A_CDC_CONN_RX2_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_RX2_B3_CTL			(0x385)
+#define TAPAN_A_CDC_CONN_RX2_B3_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_RX3_B1_CTL			(0x386)
+#define TAPAN_A_CDC_CONN_RX3_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_RX3_B2_CTL			(0x387)
+#define TAPAN_A_CDC_CONN_RX3_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_RX4_B1_CTL			(0x388)
+#define TAPAN_A_CDC_CONN_RX4_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_RX4_B2_CTL			(0x389)
+#define TAPAN_A_CDC_CONN_RX4_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_RX4_B3_CTL			(0x38A)
+#define TAPAN_A_CDC_CONN_RX4_B3_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_ANC_B1_CTL			(0x391)
+#define TAPAN_A_CDC_CONN_ANC_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_ANC_B2_CTL			(0x392)
+#define TAPAN_A_CDC_CONN_ANC_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_TX_B1_CTL			(0x393)
+#define TAPAN_A_CDC_CONN_TX_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_TX_B2_CTL			(0x394)
+#define TAPAN_A_CDC_CONN_TX_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_TX_B3_CTL			(0x395)
+#define TAPAN_A_CDC_CONN_TX_B3_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_TX_B4_CTL			(0x396)
+#define TAPAN_A_CDC_CONN_TX_B4_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_EQ1_B1_CTL			(0x397)
+#define TAPAN_A_CDC_CONN_EQ1_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_EQ1_B2_CTL			(0x398)
+#define TAPAN_A_CDC_CONN_EQ1_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_EQ1_B3_CTL			(0x399)
+#define TAPAN_A_CDC_CONN_EQ1_B3_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_EQ1_B4_CTL			(0x39A)
+#define TAPAN_A_CDC_CONN_EQ1_B4_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_EQ2_B1_CTL			(0x39B)
+#define TAPAN_A_CDC_CONN_EQ2_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_EQ2_B2_CTL			(0x39C)
+#define TAPAN_A_CDC_CONN_EQ2_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_EQ2_B3_CTL			(0x39D)
+#define TAPAN_A_CDC_CONN_EQ2_B3_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_EQ2_B4_CTL			(0x39E)
+#define TAPAN_A_CDC_CONN_EQ2_B4_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_SRC1_B1_CTL			(0x39F)
+#define TAPAN_A_CDC_CONN_SRC1_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_SRC1_B2_CTL			(0x3A0)
+#define TAPAN_A_CDC_CONN_SRC1_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_SRC2_B1_CTL			(0x3A1)
+#define TAPAN_A_CDC_CONN_SRC2_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_SRC2_B2_CTL			(0x3A2)
+#define TAPAN_A_CDC_CONN_SRC2_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_TX_SB_B1_CTL			(0x3A3)
+#define TAPAN_A_CDC_CONN_TX_SB_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_TX_SB_B2_CTL			(0x3A4)
+#define TAPAN_A_CDC_CONN_TX_SB_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_TX_SB_B3_CTL			(0x3A5)
+#define TAPAN_A_CDC_CONN_TX_SB_B3_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_TX_SB_B4_CTL			(0x3A6)
+#define TAPAN_A_CDC_CONN_TX_SB_B4_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_TX_SB_B5_CTL			(0x3A7)
+#define TAPAN_A_CDC_CONN_TX_SB_B5_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_TX_SB_B11_CTL			(0x3AD)
+#define TAPAN_A_CDC_CONN_TX_SB_B11_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_RX_SB_B1_CTL			(0x3AE)
+#define TAPAN_A_CDC_CONN_RX_SB_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_RX_SB_B2_CTL			(0x3AF)
+#define TAPAN_A_CDC_CONN_RX_SB_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_CLSH_CTL			(0x3B0)
+#define TAPAN_A_CDC_CONN_CLSH_CTL__POR				(0x00)
+#define TAPAN_A_CDC_CONN_MISC			(0x3B1)
+#define TAPAN_A_CDC_CONN_MISC__POR				(0x01)
+#define TAPAN_A_CDC_MBHC_EN_CTL			(0x3C0)
+#define TAPAN_A_CDC_MBHC_EN_CTL__POR				(0x00)
+#define TAPAN_A_CDC_MBHC_FIR_B1_CFG			(0x3C1)
+#define TAPAN_A_CDC_MBHC_FIR_B1_CFG__POR				(0x00)
+#define TAPAN_A_CDC_MBHC_FIR_B2_CFG			(0x3C2)
+#define TAPAN_A_CDC_MBHC_FIR_B2_CFG__POR				(0x06)
+#define TAPAN_A_CDC_MBHC_TIMER_B1_CTL			(0x3C3)
+#define TAPAN_A_CDC_MBHC_TIMER_B1_CTL__POR				(0x03)
+#define TAPAN_A_CDC_MBHC_TIMER_B2_CTL			(0x3C4)
+#define TAPAN_A_CDC_MBHC_TIMER_B2_CTL__POR				(0x09)
+#define TAPAN_A_CDC_MBHC_TIMER_B3_CTL			(0x3C5)
+#define TAPAN_A_CDC_MBHC_TIMER_B3_CTL__POR				(0x1E)
+#define TAPAN_A_CDC_MBHC_TIMER_B4_CTL			(0x3C6)
+#define TAPAN_A_CDC_MBHC_TIMER_B4_CTL__POR				(0x45)
+#define TAPAN_A_CDC_MBHC_TIMER_B5_CTL			(0x3C7)
+#define TAPAN_A_CDC_MBHC_TIMER_B5_CTL__POR				(0x04)
+#define TAPAN_A_CDC_MBHC_TIMER_B6_CTL			(0x3C8)
+#define TAPAN_A_CDC_MBHC_TIMER_B6_CTL__POR				(0x78)
+#define TAPAN_A_CDC_MBHC_B1_STATUS			(0x3C9)
+#define TAPAN_A_CDC_MBHC_B1_STATUS__POR				(0x00)
+#define TAPAN_A_CDC_MBHC_B2_STATUS			(0x3CA)
+#define TAPAN_A_CDC_MBHC_B2_STATUS__POR				(0x00)
+#define TAPAN_A_CDC_MBHC_B3_STATUS			(0x3CB)
+#define TAPAN_A_CDC_MBHC_B3_STATUS__POR				(0x00)
+#define TAPAN_A_CDC_MBHC_B4_STATUS			(0x3CC)
+#define TAPAN_A_CDC_MBHC_B4_STATUS__POR				(0x00)
+#define TAPAN_A_CDC_MBHC_B5_STATUS			(0x3CD)
+#define TAPAN_A_CDC_MBHC_B5_STATUS__POR				(0x00)
+#define TAPAN_A_CDC_MBHC_B1_CTL			(0x3CE)
+#define TAPAN_A_CDC_MBHC_B1_CTL__POR				(0xC0)
+#define TAPAN_A_CDC_MBHC_B2_CTL			(0x3CF)
+#define TAPAN_A_CDC_MBHC_B2_CTL__POR				(0x5D)
+#define TAPAN_A_CDC_MBHC_VOLT_B1_CTL			(0x3D0)
+#define TAPAN_A_CDC_MBHC_VOLT_B1_CTL__POR				(0x00)
+#define TAPAN_A_CDC_MBHC_VOLT_B2_CTL			(0x3D1)
+#define TAPAN_A_CDC_MBHC_VOLT_B2_CTL__POR				(0x00)
+#define TAPAN_A_CDC_MBHC_VOLT_B3_CTL			(0x3D2)
+#define TAPAN_A_CDC_MBHC_VOLT_B3_CTL__POR				(0x00)
+#define TAPAN_A_CDC_MBHC_VOLT_B4_CTL			(0x3D3)
+#define TAPAN_A_CDC_MBHC_VOLT_B4_CTL__POR				(0x00)
+#define TAPAN_A_CDC_MBHC_VOLT_B5_CTL			(0x3D4)
+#define TAPAN_A_CDC_MBHC_VOLT_B5_CTL__POR				(0x00)
+#define TAPAN_A_CDC_MBHC_VOLT_B6_CTL			(0x3D5)
+#define TAPAN_A_CDC_MBHC_VOLT_B6_CTL__POR				(0x00)
+#define TAPAN_A_CDC_MBHC_VOLT_B7_CTL			(0x3D6)
+#define TAPAN_A_CDC_MBHC_VOLT_B7_CTL__POR				(0xFF)
+#define TAPAN_A_CDC_MBHC_VOLT_B8_CTL			(0x3D7)
+#define TAPAN_A_CDC_MBHC_VOLT_B8_CTL__POR				(0x07)
+#define TAPAN_A_CDC_MBHC_VOLT_B9_CTL			(0x3D8)
+#define TAPAN_A_CDC_MBHC_VOLT_B9_CTL__POR				(0xFF)
+#define TAPAN_A_CDC_MBHC_VOLT_B10_CTL			(0x3D9)
+#define TAPAN_A_CDC_MBHC_VOLT_B10_CTL__POR				(0x7F)
+#define TAPAN_A_CDC_MBHC_VOLT_B11_CTL			(0x3DA)
+#define TAPAN_A_CDC_MBHC_VOLT_B11_CTL__POR				(0x00)
+#define TAPAN_A_CDC_MBHC_VOLT_B12_CTL			(0x3DB)
+#define TAPAN_A_CDC_MBHC_VOLT_B12_CTL__POR				(0x80)
+#define TAPAN_A_CDC_MBHC_CLK_CTL			(0x3DC)
+#define TAPAN_A_CDC_MBHC_CLK_CTL__POR				(0x00)
+#define TAPAN_A_CDC_MBHC_INT_CTL			(0x3DD)
+#define TAPAN_A_CDC_MBHC_INT_CTL__POR				(0x00)
+#define TAPAN_A_CDC_MBHC_DEBUG_CTL			(0x3DE)
+#define TAPAN_A_CDC_MBHC_DEBUG_CTL__POR				(0x00)
+#define TAPAN_A_CDC_MBHC_SPARE			(0x3DF)
+#define TAPAN_A_CDC_MBHC_SPARE__POR				(0x00)
+
+
+/* SLIMBUS Slave Registers */
+#define TAPAN_SLIM_PGD_PORT_INT_EN0 (0x30)
+#define TAPAN_SLIM_PGD_PORT_INT_STATUS0 (0x34)
+#define TAPAN_SLIM_PGD_PORT_INT_CLR0 (0x38)
+#define TAPAN_SLIM_PGD_PORT_INT_SOURCE0 (0x60)
+
+/* Macros for Packing Register Writes into a U32 */
+#define TAPAN_PACKED_REG_SIZE sizeof(u32)
+
+#define TAPAN_CODEC_PACK_ENTRY(reg, mask, val) ((val & 0xff)|\
+	((mask & 0xff) << 8)|((reg & 0xffff) << 16))
+
+#define TAPAN_CODEC_UNPACK_ENTRY(packed, reg, mask, val) \
+	do { \
+		((reg) = ((packed >> 16) & (0xffff))); \
+		((mask) = ((packed >> 8) & (0xff))); \
+		((val) = ((packed) & (0xff))); \
+	} while (0);
+
+#endif
diff --git a/include/linux/mfd/wcd9xxx/wcd9310_registers.h b/include/linux/mfd/wcd9xxx/wcd9310_registers.h
index 67c2a6b..46336e2 100644
--- a/include/linux/mfd/wcd9xxx/wcd9310_registers.h
+++ b/include/linux/mfd/wcd9xxx/wcd9310_registers.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -898,37 +898,37 @@
 #define TABLA_A_CDC_DEBUG_B6_CTL			(0x0000036D)
 #define TABLA_A_CDC_DEBUG_B6_CTL__POR			(0x00000000)
 #define TABLA_A_CDC_COMP1_B1_CTL			(0x00000370)
-#define TABLA_A_CDC_COMP1_B1_CTL__POR			(0x00000000)
+#define TABLA_A_CDC_COMP1_B1_CTL__POR			(0x00000030)
 #define TABLA_A_CDC_COMP1_B2_CTL			(0x00000371)
-#define TABLA_A_CDC_COMP1_B2_CTL__POR			(0x00000000)
+#define TABLA_A_CDC_COMP1_B2_CTL__POR			(0x000000B5)
 #define TABLA_A_CDC_COMP1_B3_CTL			(0x00000372)
-#define TABLA_A_CDC_COMP1_B3_CTL__POR			(0x00000000)
+#define TABLA_A_CDC_COMP1_B3_CTL__POR			(0x00000028)
 #define TABLA_A_CDC_COMP1_B4_CTL			(0x00000373)
-#define TABLA_A_CDC_COMP1_B4_CTL__POR			(0x00000000)
+#define TABLA_A_CDC_COMP1_B4_CTL__POR			(0x0000003C)
 #define TABLA_A_CDC_COMP1_B5_CTL			(0x00000374)
-#define TABLA_A_CDC_COMP1_B5_CTL__POR			(0x00000000)
+#define TABLA_A_CDC_COMP1_B5_CTL__POR			(0x0000001F)
 #define TABLA_A_CDC_COMP1_B6_CTL			(0x00000375)
 #define TABLA_A_CDC_COMP1_B6_CTL__POR			(0x00000000)
 #define TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS		(0x00000376)
 #define TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS__POR	(0x00000000)
 #define TABLA_A_CDC_COMP1_FS_CFG			(0x00000377)
-#define TABLA_A_CDC_COMP1_FS_CFG__POR			(0x00000000)
+#define TABLA_A_CDC_COMP1_FS_CFG__POR			(0x0000001B)
 #define TABLA_A_CDC_COMP2_B1_CTL			(0x00000378)
-#define TABLA_A_CDC_COMP2_B1_CTL__POR			(0x00000000)
+#define TABLA_A_CDC_COMP2_B1_CTL__POR			(0x00000030)
 #define TABLA_A_CDC_COMP2_B2_CTL			(0x00000379)
-#define TABLA_A_CDC_COMP2_B2_CTL__POR			(0x00000000)
+#define TABLA_A_CDC_COMP2_B2_CTL__POR			(0x000000B5)
 #define TABLA_A_CDC_COMP2_B3_CTL			(0x0000037A)
-#define TABLA_A_CDC_COMP2_B3_CTL__POR			(0x00000000)
+#define TABLA_A_CDC_COMP2_B3_CTL__POR			(0x00000028)
 #define TABLA_A_CDC_COMP2_B4_CTL			(0x0000037B)
-#define TABLA_A_CDC_COMP2_B4_CTL__POR			(0x00000000)
+#define TABLA_A_CDC_COMP2_B4_CTL__POR			(0x0000003C)
 #define TABLA_A_CDC_COMP2_B5_CTL			(0x0000037C)
-#define TABLA_A_CDC_COMP2_B5_CTL__POR			(0x00000000)
+#define TABLA_A_CDC_COMP2_B5_CTL__POR			(0x0000001F)
 #define TABLA_A_CDC_COMP2_B6_CTL			(0x0000037D)
 #define TABLA_A_CDC_COMP2_B6_CTL__POR			(0x00000000)
 #define TABLA_A_CDC_COMP2_SHUT_DOWN_STATUS		(0x0000037E)
 #define TABLA_A_CDC_COMP2_SHUT_DOWN_STATUS__POR	(0x00000000)
 #define TABLA_A_CDC_COMP2_FS_CFG			(0x0000037F)
-#define TABLA_A_CDC_COMP2_FS_CFG__POR			(0x00000000)
+#define TABLA_A_CDC_COMP2_FS_CFG__POR			(0x0000001B)
 #define TABLA_A_CDC_CONN_RX1_B1_CTL			(0x00000380)
 #define TABLA_A_CDC_CONN_RX1_B1_CTL__POR			(0x00000000)
 #define TABLA_A_CDC_CONN_RX1_B2_CTL			(0x00000381)
diff --git a/include/linux/mfd/wcd9xxx/wcd9320_registers.h b/include/linux/mfd/wcd9xxx/wcd9320_registers.h
index f9966be..63ab624 100644
--- a/include/linux/mfd/wcd9xxx/wcd9320_registers.h
+++ b/include/linux/mfd/wcd9xxx/wcd9320_registers.h
@@ -1,14 +1,3 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 WCD9320_REGISTERS_H
 #define WCD9320_REGISTERS_H
 
@@ -1331,6 +1320,55 @@
 #define TAIKO_A_CDC_MAD_BEACON_IIR_CTL_VAL			(0x3FC)
 #define TAIKO_A_CDC_MAD_BEACON_IIR_CTL_VAL__POR				(0x00)
 
+/* Taiko v2+ registers */
+#define TAIKO_A_CDC_TX_1_GAIN			(0x153)
+#define TAIKO_A_CDC_TX_1_GAIN__POR			(0x02)
+#define TAIKO_A_CDC_TX_2_GAIN			(0x155)
+#define TAIKO_A_CDC_TX_2_GAIN__POR			(0x02)
+#define TAIKO_A_CDC_TX_1_2_ADC_IB		(0x156)
+#define TAIKO_A_CDC_TX_1_2_ADC_IB__POR			(0x44)
+#define TAIKO_A_CDC_TX_3_GAIN			(0x15D)
+#define TAIKO_A_CDC_TX_3_GAIN__POR			(0x02)
+#define TAIKO_A_CDC_TX_4_GAIN			(0x15F)
+#define TAIKO_A_CDC_TX_4_GAIN__POR			(0x02)
+#define TAIKO_A_CDC_TX_3_4_ADC_IB		(0x160)
+#define TAIKO_A_CDC_TX_3_4_ADC_IB__POR			(0x44)
+#define TAIKO_A_CDC_TX_5_GAIN			(0x167)
+#define TAIKO_A_CDC_TX_5_GAIN__POR			(0x02)
+#define TAIKO_A_CDC_TX_6_GAIN			(0x169)
+#define TAIKO_A_CDC_TX_6_GAIN__POR			(0x02)
+#define TAIKO_A_CDC_TX_5_6_ADC_IB		(0x16A)
+#define TAIKO_A_CDC_TX_5_6_ADC_IB__POR			(0x44)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL0		(0x270)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL0__POR		(0x00)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL1		(0x271)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL1__POR		(0x00)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL2		(0x272)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL2__POR		(0x00)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL3		(0x273)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL3__POR		(0x00)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL4		(0x274)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL4__POR		(0x00)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL5		(0x275)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL5__POR		(0x00)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL6		(0x276)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL6__POR		(0x00)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL7		(0x277)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL7__POR		(0x00)
+#define TAIKO_A_CDC_VBAT_GAIN_UPD_MON		(0x2FA)
+#define TAIKO_A_CDC_VBAT_GAIN_UPD_MON__POR		(0x00)
+#define TAIKO_A_CDC_VBAT_GAIN_MON_VAL		(0x2FB)
+#define TAIKO_A_CDC_VBAT_GAIN_MON_VAL__POR		(0x00)
+#define TAIKO_A_CDC_PA_RAMP_B1_CTL		(0x361)
+#define TAIKO_A_CDC_PA_RAMP_B1_CTL__POR			(0x00)
+#define TAIKO_A_CDC_PA_RAMP_B2_CTL		(0x362)
+#define TAIKO_A_CDC_PA_RAMP_B2_CTL__POR			(0x00)
+#define TAIKO_A_CDC_PA_RAMP_B3_CTL		(0x363)
+#define TAIKO_A_CDC_PA_RAMP_B3_CTL__POR			(0x00)
+#define TAIKO_A_CDC_PA_RAMP_B4_CTL		(0x364)
+#define TAIKO_A_CDC_PA_RAMP_B4_CTL__POR			(0x00)
+#define TAIKO_A_CDC_SPKR_CLIPDET_B1_CTL		(0x365)
+#define TAIKO_A_CDC_SPKR_CLIPDET_B1_CTL__POR		(0x00)
 
 /* SLIMBUS Slave Registers */
 #define TAIKO_SLIM_PGD_PORT_INT_EN0                     (0x30)
diff --git a/include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h b/include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h
index aaa8fd6..066a423 100644
--- a/include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h
+++ b/include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/include/linux/mfd/wcd9xxx/wcd9xxx_registers.h b/include/linux/mfd/wcd9xxx/wcd9xxx_registers.h
index a1609b8..412341a 100644
--- a/include/linux/mfd/wcd9xxx/wcd9xxx_registers.h
+++ b/include/linux/mfd/wcd9xxx/wcd9xxx_registers.h
@@ -1,14 +1,3 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 WCD9XXX_CODEC_DIGITAL_H
 
 #define WCD9XXX_CODEC_DIGITAL_H
@@ -173,6 +162,8 @@
 #define WCD9XXX_A_MICB_4_MBHC__POR		(0x01)
 #define WCD9XXX_A_MICB_CFILT_1_VAL		(0x129)
 #define WCD9XXX_A_MICB_CFILT_1_VAL__POR		(0x80)
+#define WCD9XXX_A_RX_HPH_L_STATUS		(0x1B3)
+#define WCD9XXX_A_RX_HPH_L_STATUS__POR		(0x00)
 #define WCD9XXX_A_MBHC_HPH			(0x1FE)
 #define WCD9XXX_A_MBHC_HPH__POR			(0x44)
 #define WCD9XXX_A_RX_HPH_CNP_WG_TIME		(0x1AD)
@@ -205,4 +196,85 @@
 #define WCD9XXX_A_MAD_ANA_CTRL			(0x150)
 #define WCD9XXX_A_MAD_ANA_CTRL__POR		(0xF1)
 
+
+#define WCD9XXX_A_CDC_CLK_OTHR_CTL			(0x30C)
+#define WCD9XXX_A_CDC_CLK_OTHR_CTL__POR				(0x00)
+
+/* Class H related common registers */
+#define WCD9XXX_A_BUCK_MODE_1			(0x181)
+#define WCD9XXX_A_BUCK_MODE_1__POR				(0x21)
+#define WCD9XXX_A_BUCK_MODE_2			(0x182)
+#define WCD9XXX_A_BUCK_MODE_2__POR				(0xFF)
+#define WCD9XXX_A_BUCK_MODE_3			(0x183)
+#define WCD9XXX_A_BUCK_MODE_3__POR				(0xCC)
+#define WCD9XXX_A_BUCK_MODE_4			(0x184)
+#define WCD9XXX_A_BUCK_MODE_4__POR				(0x3A)
+#define WCD9XXX_A_BUCK_MODE_5			(0x185)
+#define WCD9XXX_A_BUCK_MODE_5__POR				(0x00)
+#define WCD9XXX_A_BUCK_CTRL_VCL_1			(0x186)
+#define WCD9XXX_A_BUCK_CTRL_VCL_1__POR				(0x48)
+#define WCD9XXX_A_BUCK_CTRL_VCL_2			(0x187)
+#define WCD9XXX_A_BUCK_CTRL_VCL_2__POR				(0xA3)
+#define WCD9XXX_A_BUCK_CTRL_VCL_3			(0x188)
+#define WCD9XXX_A_BUCK_CTRL_VCL_3__POR				(0x82)
+#define WCD9XXX_A_BUCK_CTRL_CCL_1			(0x189)
+#define WCD9XXX_A_BUCK_CTRL_CCL_1__POR				(0xAB)
+#define WCD9XXX_A_BUCK_CTRL_CCL_2			(0x18A)
+#define WCD9XXX_A_BUCK_CTRL_CCL_2__POR				(0xDC)
+#define WCD9XXX_A_BUCK_CTRL_CCL_3			(0x18B)
+#define WCD9XXX_A_BUCK_CTRL_CCL_3__POR				(0x6A)
+#define WCD9XXX_A_BUCK_CTRL_CCL_4			(0x18C)
+#define WCD9XXX_A_BUCK_CTRL_CCL_4__POR				(0x58)
+#define WCD9XXX_A_BUCK_CTRL_PWM_DRVR_1			(0x18D)
+#define WCD9XXX_A_BUCK_CTRL_PWM_DRVR_1__POR				(0x50)
+#define WCD9XXX_A_BUCK_CTRL_PWM_DRVR_2			(0x18E)
+#define WCD9XXX_A_BUCK_CTRL_PWM_DRVR_2__POR				(0x64)
+#define WCD9XXX_A_BUCK_CTRL_PWM_DRVR_3			(0x18F)
+#define WCD9XXX_A_BUCK_CTRL_PWM_DRVR_3__POR				(0x77)
+#define WCD9XXX_A_BUCK_TMUX_A_D			(0x190)
+#define WCD9XXX_A_BUCK_TMUX_A_D__POR				(0x00)
+#define WCD9XXX_A_NCP_EN			(0x192)
+#define WCD9XXX_A_NCP_EN__POR				(0xFE)
+#define WCD9XXX_A_NCP_STATIC			(0x194)
+#define WCD9XXX_A_NCP_STATIC__POR				(0x28)
+#define WCD9XXX_A_NCP_BUCKREF			(0x191)
+#define WCD9XXX_A_NCP_BUCKREF__POR				(0x00)
+#define WCD9XXX_A_CDC_CLSH_B1_CTL			(0x320)
+#define WCD9XXX_A_CDC_CLSH_B1_CTL__POR				(0xE4)
+#define WCD9XXX_A_CDC_CLSH_B2_CTL			(0x321)
+#define WCD9XXX_A_CDC_CLSH_B2_CTL__POR				(0x00)
+#define WCD9XXX_A_CDC_CLSH_B3_CTL			(0x322)
+#define WCD9XXX_A_CDC_CLSH_B3_CTL__POR				(0x00)
+#define WCD9XXX_A_CDC_CLSH_BUCK_NCP_VARS			(0x323)
+#define WCD9XXX_A_CDC_CLSH_BUCK_NCP_VARS__POR			(0x00)
+#define WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD			(0x324)
+#define WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD__POR			(0x12)
+#define WCD9XXX_A_CDC_CLSH_IDLE_EAR_THSD			(0x325)
+#define WCD9XXX_A_CDC_CLSH_IDLE_EAR_THSD__POR			(0x0C)
+#define WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD			(0x326)
+#define WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD__POR		(0x18)
+#define WCD9XXX_A_CDC_CLSH_FCLKONLY_EAR_THSD			(0x327)
+#define WCD9XXX_A_CDC_CLSH_FCLKONLY_EAR_THSD__POR		(0x23)
+#define WCD9XXX_A_CDC_CLSH_K_ADDR			(0x328)
+#define WCD9XXX_A_CDC_CLSH_K_ADDR__POR				(0x00)
+#define WCD9XXX_A_CDC_CLSH_K_DATA			(0x329)
+#define WCD9XXX_A_CDC_CLSH_K_DATA__POR				(0xA4)
+#define WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L			(0x32A)
+#define WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L__POR				(0xD7)
+#define WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U			(0x32B)
+#define WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U__POR				(0x05)
+#define WCD9XXX_A_CDC_CLSH_I_PA_FACT_EAR_L			(0x32C)
+#define WCD9XXX_A_CDC_CLSH_I_PA_FACT_EAR_L__POR				(0x60)
+#define WCD9XXX_A_CDC_CLSH_I_PA_FACT_EAR_U			(0x32D)
+#define WCD9XXX_A_CDC_CLSH_I_PA_FACT_EAR_U__POR				(0x09)
+#define WCD9XXX_A_CDC_CLSH_V_PA_HD_EAR			(0x32E)
+#define WCD9XXX_A_CDC_CLSH_V_PA_HD_EAR__POR				(0x00)
+#define WCD9XXX_A_CDC_CLSH_V_PA_HD_HPH			(0x32F)
+#define WCD9XXX_A_CDC_CLSH_V_PA_HD_HPH__POR				(0x00)
+#define WCD9XXX_A_CDC_CLSH_V_PA_MIN_EAR			(0x330)
+#define WCD9XXX_A_CDC_CLSH_V_PA_MIN_EAR__POR				(0x00)
+#define WCD9XXX_A_CDC_CLSH_V_PA_MIN_HPH			(0x331)
+#define WCD9XXX_A_CDC_CLSH_V_PA_MIN_HPH__POR				(0x00)
+
+
 #endif
diff --git a/include/linux/mhl_8334.h b/include/linux/mhl_8334.h
index c9f57c5..d6f8356 100644
--- a/include/linux/mhl_8334.h
+++ b/include/linux/mhl_8334.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -18,6 +18,7 @@
 #include <linux/platform_device.h>
 #include <mach/board.h>
 #include <linux/mhl_devcap.h>
+#include <linux/power_supply.h>
 #include <linux/mhl_defs.h>
 
 #define MHL_DEVICE_NAME "sii8334"
@@ -35,6 +36,7 @@
 	u8 command;
 	u8 offset;
 	u8 length;
+	u8 retry;
 	union {
 		u8 data[16];
 		u8 *burst_data;
@@ -42,9 +44,18 @@
 	u8 retval;
 };
 
+struct scrpd_struct {
+	u8 offset;
+	u8 length;
+	u8 data[MHL_SCRATCHPAD_SIZE];
+};
+
+/* MHL 8334 supports a max HD pixel clk of 75 MHz */
+#define MAX_MHL_PCLK 75000
+
 /* USB driver interface  */
 
-#ifdef CONFIG_FB_MSM_HDMI_MHL_8334
+#if defined(CONFIG_FB_MSM_HDMI_MHL_8334)
  /*  mhl_device_discovery */
 extern int mhl_device_discovery(const char *name, int *result);
 
@@ -70,7 +81,6 @@
 }
 #endif
 
-
 struct msc_cmd_envelope {
 	/*
 	 * this list head is for list APIs
@@ -97,6 +107,69 @@
 	struct msc_command_struct* (*msc_command_get_work) (void);
 };
 
+#ifdef CONFIG_FB_MSM_MDSS_HDMI_MHL_SII8334
+enum mhl_gpio_type {
+	MHL_TX_RESET_GPIO,
+	MHL_TX_INTR_GPIO,
+	MHL_TX_PMIC_PWR_GPIO,
+	MHL_TX_MAX_GPIO,
+};
+
+enum mhl_vreg_type {
+	MHL_TX_3V_VREG,
+	MHL_TX_MAX_VREG,
+};
+
+
+struct mhl_tx_platform_data {
+	/* Data filled from device tree nodes */
+	struct dss_gpio *gpios[MHL_TX_MAX_GPIO];
+	struct dss_vreg *vregs[MHL_TX_MAX_VREG];
+	int irq;
+	struct platform_device *hdmi_pdev;
+};
+
+struct mhl_tx_ctrl {
+	struct platform_device *pdev;
+	struct mhl_tx_platform_data *pdata;
+	struct i2c_client *i2c_handle;
+	uint8_t cur_state;
+	uint8_t chip_rev_id;
+	int mhl_mode;
+	struct completion rgnd_done;
+	void (*notify_usb_online)(int online);
+	struct usb_ext_notification *mhl_info;
+	bool disc_enabled;
+	struct power_supply mhl_psy;
+	bool vbus_active;
+	int current_val;
+	struct completion msc_cmd_done;
+	uint8_t devcap[16];
+	uint8_t devcap_state;
+	uint8_t path_en_state;
+	void *hdmi_mhl_ops;
+	struct work_struct mhl_msc_send_work;
+	struct list_head list_cmd;
+	struct input_dev *input;
+	struct workqueue_struct *msc_send_workqueue;
+	u16 *rcp_key_code_tbl;
+	size_t rcp_key_code_tbl_len;
+	struct scrpd_struct scrpd;
+	int scrpd_busy;
+	int wr_burst_pending;
+};
+
+int mhl_i2c_reg_read(struct i2c_client *client,
+		     uint8_t slave_addr_index, uint8_t reg_offset);
+int mhl_i2c_reg_write(struct i2c_client *client,
+		      uint8_t slave_addr_index, uint8_t reg_offset,
+		      uint8_t value);
+void mhl_i2c_reg_modify(struct i2c_client *client,
+			uint8_t slave_addr_index, uint8_t reg_offset,
+			uint8_t mask, uint8_t val);
+
+#endif /* CONFIG_FB_MSM_MDSS_HDMI_MHL_SII8334 */
+
 enum {
 	TX_PAGE_TPI          = 0x00,
 	TX_PAGE_L0           = 0x01,
@@ -205,6 +278,7 @@
 
 #define REG_TMDS_CSTAT	((TX_PAGE_3 << 16) | 0x0040)
 
+#define REG_CBUS_INTR_STATUS            ((TX_PAGE_CBUS << 16) | 0x0008)
 #define REG_CBUS_INTR_ENABLE            ((TX_PAGE_CBUS << 16) | 0x0009)
 
 #define REG_DDC_ABORT_REASON            ((TX_PAGE_CBUS << 16) | 0x000B)
@@ -277,8 +351,8 @@
 #define REG_CBUS_WRITE_STAT_2           ((TX_PAGE_CBUS << 16) | 0x00B2)
 #define REG_CBUS_WRITE_STAT_3           ((TX_PAGE_CBUS << 16) | 0x00B3)
 
-#define GET_PAGE(x) (x >> 16)
-#define GET_OFF(x) (x & 0xffff)
+#define GET_PAGE(x) ((x) >> 16)
+#define GET_OFF(x) ((x) & 0xffff)
 
 
 #define MHL_SII_REG_NAME_RD(arg)\
diff --git a/include/linux/mhl_defs.h b/include/linux/mhl_defs.h
index 062bdf9..f9d1ce4 100644
--- a/include/linux/mhl_defs.h
+++ b/include/linux/mhl_defs.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -128,7 +128,11 @@
 
 /* This contains one nibble each - max offset */
 #define		MHL_INT_AND_STATUS_SIZE			0x33
+#define         MHL_SCRATCHPAD_OFFSET                   0x40
 #define		MHL_SCRATCHPAD_SIZE			16
+#define		MAX_SCRATCHPAD_TRANSFER_SIZE		64
+#define		ADOPTER_ID_SIZE				2
+
 /* manually define highest number */
 #define		MHL_MAX_BUFFER_SIZE			MHL_SCRATCHPAD_SIZE
 
@@ -149,6 +153,7 @@
 
 #define MHL_RCPE_NO_ERROR			0x00
 #define MHL_RCPE_UNSUPPORTED_KEY_CODE		0x01
+#define MHL_RCPE_INEFFECTIVE_KEY_CODE		0x01
 #define MHL_RCPE_BUSY				0x02
 
 #define MHL_RAPK_NO_ERROR			0x00
@@ -156,6 +161,8 @@
 #define MHL_RAPK_UNSUPPORTED_ACTION_CODE	0x02
 #define MHL_RAPK_BUSY				0x03
 
+#define T_ABORT_NEXT                    (2050)
+
 /* MHL spec related defines*/
 enum {
 	/* Command or Data byte acknowledge */
@@ -196,6 +203,8 @@
 	MHL_GET_SC3_ERRORCODE		= 0x6D,
 };
 
+/* Polling. */
+#define MHL_RAP_POLL                    0x00
 /* Turn content streaming ON. */
 #define	MHL_RAP_CONTENT_ON		0x10
 /* Turn content streaming OFF. */
diff --git a/include/linux/mhl_devcap.h b/include/linux/mhl_devcap.h
index 6d01daf..40a87fe 100644
--- a/include/linux/mhl_devcap.h
+++ b/include/linux/mhl_devcap.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/include/linux/mmc/Kbuild b/include/linux/mmc/Kbuild
index 1fb2644..d71c0a6 100644
--- a/include/linux/mmc/Kbuild
+++ b/include/linux/mmc/Kbuild
@@ -1 +1,3 @@
+header-y += core.h
 header-y += ioctl.h
+header-y += mmc.h
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index ec1d619..dd61824 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -186,6 +186,7 @@
 struct mmc_host;
 struct sdio_func;
 struct sdio_func_tuple;
+struct mmc_queue;
 
 #define SDIO_MAX_FUNCS		7
 
@@ -198,9 +199,24 @@
 	REL_WRITE,
 	THRESHOLD,
 	LARGE_SEC_ALIGN,
+	RANDOM,
+	FUA,
 	MAX_REASONS,
 };
 
+enum mmc_blk_status {
+	MMC_BLK_SUCCESS = 0,
+	MMC_BLK_PARTIAL,
+	MMC_BLK_CMD_ERR,
+	MMC_BLK_RETRY,
+	MMC_BLK_ABORT,
+	MMC_BLK_DATA_ERR,
+	MMC_BLK_ECC_ERR,
+	MMC_BLK_NOMEDIUM,
+	MMC_BLK_NEW_REQUEST,
+	MMC_BLK_URGENT,
+};
+
 struct mmc_wr_pack_stats {
 	u32 *packing_events;
 	u32 pack_stop_reason[MAX_REASONS];
@@ -249,35 +265,39 @@
 /**
  * struct mmc_bkops_info - BKOPS data
  * @dw:	Idle time bkops delayed work
- * @host_suspend_tout_ms:	The host controller idle time,
- * before getting into suspend
+ * @host_delay_ms:	The host controller time to start bkops
  * @delay_ms:	The time to start the BKOPS
  *        delayed work once MMC thread is idle
+ * @min_sectors_to_queue_delayed_work: the changed
+ *        number of sectors that should issue check for BKOPS
+ *        need
+ * @size_percentage_to_queue_delayed_work: the changed
+ *        percentage of sectors that should issue check for
+ *        BKOPS need
+ * @bkops_stats: BKOPS statistics
  * @poll_for_completion:	Poll on BKOPS completion
  * @cancel_delayed_work: A flag to indicate if the delayed work
  *        should be cancelled
- * @started_delayed_bkops:  A flag to indicate if the delayed
- *        work was scheduled
  * @sectors_changed:  number of  sectors written or
  *       discard since the last idle BKOPS were scheduled
  */
 struct mmc_bkops_info {
 	struct delayed_work	dw;
-	unsigned int		host_suspend_tout_ms;
+	unsigned int		host_delay_ms;
 	unsigned int		delay_ms;
 	unsigned int		min_sectors_to_queue_delayed_work;
-	struct mmc_bkops_stats  bkops_stats;    /* BKOPS statistics */
+	unsigned int		size_percentage_to_queue_delayed_work;
+	struct mmc_bkops_stats  bkops_stats;
 /*
  * A default time for checking the need for non urgent BKOPS once mmcqd
  * is idle.
  */
-#define MMC_IDLE_BKOPS_TIME_MS 2000
+#define MMC_IDLE_BKOPS_TIME_MS 200
 	struct work_struct	poll_for_completion;
 /* Polling timeout and interval for waiting on non-blocking BKOPs completion */
-#define BKOPS_COMPLETION_POLLING_TIMEOUT_MS 10000 /* in ms */
+#define BKOPS_COMPLETION_POLLING_TIMEOUT_MS (4 * 60 * 1000) /* in ms */
 #define BKOPS_COMPLETION_POLLING_INTERVAL_MS 1000 /* in ms */
 	bool			cancel_delayed_work;
-	bool			started_delayed_bkops;
 	unsigned int		sectors_changed;
 /*
  * Since canceling the delayed work might have significant effect on the
@@ -285,9 +305,8 @@
  * mmcqd thread is idle.
  * The delayed work for idle BKOPS will be scheduled only after a significant
  * amount of write or discard data.
- * 100MB is chosen based on benchmark tests.
  */
-#define BKOPS_MIN_SECTORS_TO_QUEUE_DELAYED_WORK 204800 /* 100MB */
+#define BKOPS_SIZE_PERCENTAGE_TO_QUEUE_DELAYED_WORK 1 /* 1% */
 };
 
 /*
@@ -313,6 +332,7 @@
 #define MMC_CARD_REMOVED	(1<<7)		/* card has been removed */
 #define MMC_STATE_HIGHSPEED_200	(1<<8)		/* card is in HS200 mode */
 #define MMC_STATE_DOING_BKOPS	(1<<10)		/* card is doing BKOPS */
+#define MMC_STATE_NEED_BKOPS	(1<<11)		/* card needs to do BKOPS */
 	unsigned int		quirks; 	/* card quirks */
 #define MMC_QUIRK_LENIENT_FN0	(1<<0)		/* allow SDIO FN0 writes outside of the VS CCCR range */
 #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1)	/* use func->cur_blksize */
@@ -359,6 +379,7 @@
 	struct dentry		*debugfs_root;
 	struct mmc_part	part[MMC_NUM_PHY_PARTITION]; /* physical partitions */
 	unsigned int    nr_parts;
+	unsigned int	part_curr;
 
 	struct mmc_wr_pack_stats wr_pack_stats; /* packed commands stats*/
 
@@ -485,6 +506,7 @@
 #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
 #define mmc_card_removed(c)	((c) && ((c)->state & MMC_CARD_REMOVED))
 #define mmc_card_doing_bkops(c)	((c)->state & MMC_STATE_DOING_BKOPS)
+#define mmc_card_need_bkops(c)	((c)->state & MMC_STATE_NEED_BKOPS)
 
 #define mmc_card_set_present(c)	((c)->state |= MMC_STATE_PRESENT)
 #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
@@ -498,7 +520,8 @@
 #define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED)
 #define mmc_card_set_doing_bkops(c)	((c)->state |= MMC_STATE_DOING_BKOPS)
 #define mmc_card_clr_doing_bkops(c)	((c)->state &= ~MMC_STATE_DOING_BKOPS)
-
+#define mmc_card_set_need_bkops(c)	((c)->state |= MMC_STATE_NEED_BKOPS)
+#define mmc_card_clr_need_bkops(c)	((c)->state &= ~MMC_STATE_NEED_BKOPS)
 /*
  * Quirk add/remove for MMC products.
  */
@@ -591,5 +614,5 @@
 extern struct mmc_wr_pack_stats *mmc_blk_get_packed_statistics(
 			struct mmc_card *card);
 extern void mmc_blk_init_packed_statistics(struct mmc_card *card);
-
+extern void mmc_blk_disable_wr_packing(struct mmc_queue *mq);
 #endif /* LINUX_MMC_CARD_H */
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index 24b9790..5f1e2d9 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -8,6 +8,7 @@
 #ifndef LINUX_MMC_CORE_H
 #define LINUX_MMC_CORE_H
 
+#ifdef __KERNEL__
 #include <linux/interrupt.h>
 #include <linux/completion.h>
 
@@ -23,6 +24,7 @@
 #define MMC_CMD23_ARG_TAG_REQ	(1 << 29)
 	u32			resp[4];
 	unsigned int		flags;		/* expected response type */
+#endif /* __KERNEL__ */
 #define MMC_RSP_PRESENT	(1 << 0)
 #define MMC_RSP_136	(1 << 1)		/* 136 bit response */
 #define MMC_RSP_CRC	(1 << 2)		/* expect valid crc */
@@ -55,6 +57,7 @@
 #define MMC_RSP_R6	(MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
 #define MMC_RSP_R7	(MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
 
+#ifdef __KERNEL__
 #define mmc_resp_type(cmd)	((cmd)->flags & (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC|MMC_RSP_BUSY|MMC_RSP_OPCODE))
 
 /*
@@ -96,6 +99,8 @@
  */
 
 	unsigned int		cmd_timeout_ms;	/* in milliseconds */
+	/* Set this flag only for blocking bkops request */
+	bool			bkops_busy;
 
 	struct mmc_data		*data;		/* data segment associated with cmd */
 	struct mmc_request	*mrq;		/* associated request */
@@ -124,6 +129,7 @@
 	bool			fault_injected; /* fault injected */
 };
 
+struct mmc_host;
 struct mmc_request {
 	struct mmc_command	*sbc;		/* SET_BLOCK_COUNT for multiblock */
 	struct mmc_command	*cmd;
@@ -132,9 +138,9 @@
 
 	struct completion	completion;
 	void			(*done)(struct mmc_request *);/* completion function */
+	struct mmc_host		*host;
 };
 
-struct mmc_host;
 struct mmc_card;
 struct mmc_async_req;
 
@@ -152,7 +158,8 @@
 extern void mmc_start_delayed_bkops(struct mmc_card *card);
 extern void mmc_start_idle_time_bkops(struct work_struct *work);
 extern void mmc_bkops_completion_polling(struct work_struct *work);
-extern int __mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int, bool);
+extern int __mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int, bool,
+			bool);
 extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int);
 extern int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd);
 
@@ -213,4 +220,5 @@
 
 extern u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max);
 
+#endif /* __KERNEL__ */
 #endif /* LINUX_MMC_CORE_H */
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 6c43ec7..1a3c662 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -140,6 +140,8 @@
 	void	(*hw_reset)(struct mmc_host *host);
 	unsigned long (*get_max_frequency)(struct mmc_host *host);
 	unsigned long (*get_min_frequency)(struct mmc_host *host);
+	int	(*stop_request)(struct mmc_host *host);
+	unsigned int	(*get_xfer_remain)(struct mmc_host *host);
 };
 
 struct mmc_card;
@@ -153,6 +155,36 @@
 	 * Returns 0 if success otherwise non zero.
 	 */
 	int (*err_check) (struct mmc_card *, struct mmc_async_req *);
+	/* Reinserts request back to the block layer */
+	void (*reinsert_req) (struct mmc_async_req *);
+	/* update what part of request is not done (packed_fail_idx) */
+	int (*update_interrupted_req) (struct mmc_card *,
+			struct mmc_async_req *);
+};
+
+/**
+ * mmc_context_info - synchronization details for mmc context
+ * @is_done_rcv		wake up reason was done request
+ * @is_new_req		wake up reason was new request
+ * @is_waiting_last_req	is true, when 1 request running on the bus and
+ *			NULL fetched as second request. MMC_BLK_NEW_REQUEST
+ *			notification will wake up mmc thread from waiting.
+ * @is_urgent		wake up reason was urgent request
+ * @is_waiting		is true, when first request is running on the bus,
+ *			second request preparation started or mmc thread is
+ *			waiting for the completion of the current request
+ *			(latter case is like @is_waiting_last_req)
+ * @wait		wait queue
+ * @lock		lock to protect data fields
+ */
+struct mmc_context_info {
+	bool			is_done_rcv;
+	bool			is_new_req;
+	bool			is_waiting_last_req;
+	bool			is_urgent;
+	bool			is_waiting;
+	wait_queue_head_t	wait;
+	spinlock_t		lock;
 };
 
 struct mmc_hotplug {
@@ -244,15 +276,16 @@
 #define MMC_CAP2_DETECT_ON_ERR	(1 << 8)	/* On I/O err check card removal */
 #define MMC_CAP2_HC_ERASE_SZ	(1 << 9)	/* High-capacity erase size */
 
-#define MMC_CAP2_PACKED_RD	(1 << 10)	/* Allow packed read */
-#define MMC_CAP2_PACKED_WR	(1 << 11)	/* Allow packed write */
+#define MMC_CAP2_PACKED_RD	(1 << 12)	/* Allow packed read */
+#define MMC_CAP2_PACKED_WR	(1 << 13)	/* Allow packed write */
 #define MMC_CAP2_PACKED_CMD	(MMC_CAP2_PACKED_RD | \
 				 MMC_CAP2_PACKED_WR) /* Allow packed commands */
-#define MMC_CAP2_PACKED_WR_CONTROL (1 << 12) /* Allow write packing control */
+#define MMC_CAP2_PACKED_WR_CONTROL (1 << 14) /* Allow write packing control */
 
-#define MMC_CAP2_SANITIZE	(1 << 13)		/* Support Sanitize */
-#define MMC_CAP2_INIT_BKOPS	    (1 << 15)	/* Need to set BKOPS_EN */
-#define MMC_CAP2_CLK_SCALE	(1 << 16)	/* Allow dynamic clk scaling */
+#define MMC_CAP2_SANITIZE	(1 << 15)		/* Support Sanitize */
+#define MMC_CAP2_INIT_BKOPS	    (1 << 16)	/* Need to set BKOPS_EN */
+#define MMC_CAP2_CLK_SCALE	(1 << 17)	/* Allow dynamic clk scaling */
+#define MMC_CAP2_STOP_REQUEST	(1 << 18)	/* Allow stop ongoing request */
 	mmc_pm_flag_t		pm_caps;	/* supported pm features */
 
 	int			clk_requests;	/* internal reference counter */
@@ -299,6 +332,7 @@
 
 	struct delayed_work	detect;
 	struct wake_lock	detect_wake_lock;
+	const char		*wlock_name;
 	int			detect_change;	/* card detect flag */
 	struct mmc_hotplug	hotplug;
 
@@ -327,6 +361,7 @@
 	struct dentry		*debugfs_root;
 
 	struct mmc_async_req	*areq;		/* active async req */
+	struct mmc_context_info	context_info;	/* async synchronization info */
 
 #ifdef CONFIG_FAIL_MMC_REQUEST
 	struct fault_attr	fail_mmc_request;
diff --git a/include/linux/mmc/ioctl.h b/include/linux/mmc/ioctl.h
index 1f5e689..befbdc2 100644
--- a/include/linux/mmc/ioctl.h
+++ b/include/linux/mmc/ioctl.h
@@ -47,6 +47,60 @@
 
 #define MMC_IOC_CMD _IOWR(MMC_BLOCK_MAJOR, 0, struct mmc_ioc_cmd)
 
+/**
+ * There are four request types that are applicable for rpmb accesses- two
+ * under read category and two under write. They are
+ *
+ *  Reads
+ *  -------
+ *  1. Read Write Counter
+ *  2. Authenticated data read
+ *
+ *
+ *  Writes
+ *  -------
+ *  1. Provision RPMB key (though it might be done in a secure environment)
+ *  2. Authenticated data write
+ *
+ *  While its given that the rpmb data frames are going to have that
+ *  information encoded in it and the frames should be generated by a secure
+ *  piece of code, the request types can be classified as above.
+ *
+ *  So here are the set of commands that should be executed atomically in the
+ *  ioctl for rpmb read operation
+ *  1. Switch partition
+ *  2. Set block count
+ *  3. Write data frame - CMD25 to write the rpmb data frame
+ *  4. Set block count
+ *  5. Read the data - CMD18 to do the actual read
+ *
+ *  Similarly for rpmb write operation, these are the commands that should be
+ *  executed atomically in the ioctl for rpmb write operation
+ *  1. Switch partition
+ *  2. Set block count
+ *  3. Write data frame - CMD25 to write the rpmb data frame with data
+ *  4. Set block count
+ *  5. Read the data - CMD25 to write rpmb data frame indicating that rpmb
+ *     result register is about to be read
+ *  6. Set block count
+ *  7. Read rpmb result - CMD18 to read the rpmb result register
+ *
+ * Each of the above commands should be sent individually via struct mmc_ioc_cmd
+ * and fields like is_acmd that are not needed for rpmb operations will be
+ * ignored.
+ */
+#define MMC_IOC_MAX_RPMB_CMD	3
+struct mmc_ioc_rpmb {
+	struct mmc_ioc_cmd cmds[MMC_IOC_MAX_RPMB_CMD];
+};
+
+/*
+ * This ioctl is meant for use with rpmb partitions. This is needed since the
+ * access procedure for this particular partition is different from regular
+ * or normal partitions.
+ */
+#define MMC_IOC_RPMB_CMD _IOWR(MMC_BLOCK_MAJOR, 0, struct mmc_ioc_rpmb)
+
 /*
  * Since this ioctl is only meant to enhance (and not replace) normal access
  * to the mmc bus device, an upper data transfer limit of MMC_IOC_MAX_BYTES
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index 46479a7..7f316a9 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -84,6 +84,7 @@
 #define MMC_APP_CMD              55   /* ac   [31:16] RCA        R1  */
 #define MMC_GEN_CMD              56   /* adtc [0] RD/WR          R1  */
 
+#ifdef __KERNEL__
 static inline bool mmc_op_multi(u32 opcode)
 {
 	return opcode == MMC_WRITE_MULTIPLE_BLOCK ||
@@ -322,6 +323,7 @@
 #define EXT_CSD_PWR_CL_200_360		237	/* RO */
 #define EXT_CSD_PWR_CL_DDR_52_195	238	/* RO */
 #define EXT_CSD_PWR_CL_DDR_52_360	239	/* RO */
+#define EXT_CSD_CORRECTLY_PRG_SECTORS_NUM 242	/* RO, 4 bytes */
 #define EXT_CSD_BKOPS_STATUS		246	/* RO */
 #define EXT_CSD_POWER_OFF_LONG_TIME	247	/* RO */
 #define EXT_CSD_GENERIC_CMD6_TIME	248	/* RO */
@@ -429,4 +431,5 @@
 #define MMC_SWITCH_MODE_CLEAR_BITS	0x02	/* Clear bits which are 1 in value */
 #define MMC_SWITCH_MODE_WRITE_BYTE	0x03	/* Set target to value */
 
+#endif /* __KERNEL__ */
 #endif /* LINUX_MMC_MMC_H */
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index c5b492b..e9051e1 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -91,7 +91,6 @@
 	unsigned int quirks2;	/* More deviations from spec. */
 
 #define SDHCI_QUIRK2_HOST_OFF_CARD_ON			(1<<0)
-#define SDHCI_QUIRK2_OWN_CARD_DETECTION			(1<<1)
 
 	int irq;		/* Device IRQ */
 	void __iomem *ioaddr;	/* Mapped address */
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 7bdd3f2..6e12694 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -61,6 +61,14 @@
 	MIGRATE_TYPES
 };
 
+/*
+ * Returns a list which contains the migrate types on to which
+ * an allocation falls back when the free list for the migrate
+ * type mtype is depleted.
+ * The end of the list is delimited by the type MIGRATE_RESERVE.
+ */
+extern int *get_migratetype_fallbacks(int mtype);
+
 #ifdef CONFIG_CMA
 bool is_cma_pageblock(struct page *page);
 #  define is_migrate_cma(migratetype) unlikely((migratetype) == MIGRATE_CMA)
@@ -144,6 +152,7 @@
 	NUMA_OTHER,		/* allocation from other node */
 #endif
 	NR_ANON_TRANSPARENT_HUGEPAGES,
+	NR_FREE_CMA_PAGES,
 	NR_VM_ZONE_STAT_ITEMS };
 
 /*
@@ -381,6 +390,7 @@
 	 * process to make sure that the system is not starved.
 	 */
 	unsigned long		min_cma_pages;
+	bool			cma_alloc;
 #endif
 	struct free_area	free_area[MAX_ORDER];
 
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index bc124da..839767f 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -78,6 +78,9 @@
  *	of a given interface; other interfaces may support other classes.
  * @bInterfaceSubClass: Subclass of interface; associated with bInterfaceClass.
  * @bInterfaceProtocol: Protocol of interface; associated with bInterfaceClass.
+ * @bInterfaceNumber: Number of interface; composite devices may use
+ *	fixed interface numbers to differentiate between vendor-specific
+ *	interfaces.
  * @driver_info: Holds information used by the driver.  Usually it holds
  *	a pointer to a descriptor understood by the driver, or perhaps
  *	device flags.
@@ -115,6 +118,9 @@
 	__u8		bInterfaceSubClass;
 	__u8		bInterfaceProtocol;
 
+	/* Used for vendor-specific interface matches */
+	__u8		bInterfaceNumber;
+
 	/* not matched against */
 	kernel_ulong_t	driver_info;
 };
@@ -130,6 +136,7 @@
 #define USB_DEVICE_ID_MATCH_INT_CLASS		0x0080
 #define USB_DEVICE_ID_MATCH_INT_SUBCLASS	0x0100
 #define USB_DEVICE_ID_MATCH_INT_PROTOCOL	0x0200
+#define USB_DEVICE_ID_MATCH_INT_NUMBER		0x0400
 
 #define HID_ANY_ID				(~0)
 
diff --git a/include/linux/msm-charger.h b/include/linux/msm-charger.h
index 14ffae31..93ed7cf 100644
--- a/include/linux/msm-charger.h
+++ b/include/linux/msm-charger.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/msm_audio.h b/include/linux/msm_audio.h
index 4eb8a65..322a374 100644
--- a/include/linux/msm_audio.h
+++ b/include/linux/msm_audio.h
@@ -1,7 +1,7 @@
 /* include/linux/msm_audio.h
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -245,6 +245,7 @@
 #define CAD_SET_DEVICE _IOW(SND_IOCTL_MAGIC, 2, struct msm_cad_device_config *)
 
 #define SND_METHOD_VOICE 0
+#define SND_METHOD_MIDI 4
 
 struct msm_snd_volume_config {
 	uint32_t device;
diff --git a/include/linux/msm_audio_aac.h b/include/linux/msm_audio_aac.h
index ee71c3e..88024d9 100644
--- a/include/linux/msm_audio_aac.h
+++ b/include/linux/msm_audio_aac.h
@@ -14,6 +14,9 @@
 #define AUDIO_GET_AAC_ENC_CONFIG  _IOR(AUDIO_IOCTL_MAGIC, \
   (AUDIO_MAX_COMMON_IOCTL_NUM+4), struct msm_audio_aac_enc_config)
 
+#define AUDIO_SET_AAC_MIX_CONFIG  _IOR(AUDIO_IOCTL_MAGIC, \
+(AUDIO_MAX_COMMON_IOCTL_NUM+5), unsigned)
+
 #define AUDIO_AAC_FORMAT_ADTS		-1
 #define	AUDIO_AAC_FORMAT_RAW		0x0000
 #define	AUDIO_AAC_FORMAT_PSUEDO_RAW	0x0001
diff --git a/include/linux/msm_audio_acdb.h b/include/linux/msm_audio_acdb.h
index e907f4a..f0c4915 100644
--- a/include/linux/msm_audio_acdb.h
+++ b/include/linux/msm_audio_acdb.h
@@ -1,5 +1,5 @@
-#ifndef __MSM_AUDIO_ACDB_H
-#define __MSM_AUDIO_ACDB_H
+#ifndef _LINUX_MSM_AUDIO_ACDB_H
+#define _LINUX_MSM_AUDIO_ACDB_H
 
 #include <linux/msm_audio.h>
 
@@ -47,6 +47,12 @@
 			(AUDIO_MAX_COMMON_IOCTL_NUM+20), unsigned)
 #define AUDIO_SET_VOCPROC_DEV_CFG_CAL	_IOW(AUDIO_IOCTL_MAGIC, \
 			(AUDIO_MAX_COMMON_IOCTL_NUM+21), unsigned)
+#define AUDIO_SET_LSM_CAL		_IOW(AUDIO_IOCTL_MAGIC, \
+			(AUDIO_MAX_COMMON_IOCTL_NUM+22), unsigned)
+#define AUDIO_SET_ADM_CUSTOM_TOPOLOGY	_IOW(AUDIO_IOCTL_MAGIC, \
+			(AUDIO_MAX_COMMON_IOCTL_NUM+23), unsigned)
+#define AUDIO_SET_ASM_CUSTOM_TOPOLOGY	_IOW(AUDIO_IOCTL_MAGIC, \
+			(AUDIO_MAX_COMMON_IOCTL_NUM+24), unsigned)
 
 #define	AUDIO_MAX_ACDB_IOCTL	(AUDIO_MAX_COMMON_IOCTL_NUM+30)
 
@@ -85,4 +91,4 @@
 
 #define	AUDIO_MAX_RTAC_IOCTL	(AUDIO_MAX_ACDB_IOCTL+20)
 
-#endif /* __MSM_AUDIO_ACDB_H */
+#endif /* _LINUX_MSM_AUDIO_ACDB_H */
diff --git a/include/linux/msm_dsps.h b/include/linux/msm_dsps.h
index a5ac256..1f997ba 100644
--- a/include/linux/msm_dsps.h
+++ b/include/linux/msm_dsps.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/include/linux/msm_ion.h b/include/linux/msm_ion.h
index d423b26..2593154 100644
--- a/include/linux/msm_ion.h
+++ b/include/linux/msm_ion.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -22,6 +22,7 @@
 	ION_HEAP_TYPE_MSM_START = ION_HEAP_TYPE_CUSTOM + 1,
 	ION_HEAP_TYPE_IOMMU = ION_HEAP_TYPE_MSM_START,
 	ION_HEAP_TYPE_CP,
+	ION_HEAP_TYPE_SECURE_DMA,
 };
 
 /**
@@ -75,6 +76,13 @@
 #define ION_SECURE (1 << ION_HEAP_ID_RESERVED)
 
 /**
+ * Flag for clients to force contiguous memort allocation
+ *
+ * Use of this flag is carefully monitored!
+ */
+#define ION_FORCE_CONTIGUOUS (1 << 30)
+
+/**
  * Macro should be used with ion_heap_ids defined above.
  */
 #define ION_HEAP(bit) (1 << (bit))
@@ -137,7 +145,9 @@
  *			goes from 1 -> 0
  * @setup_region:	function to be called upon ion registration
  * @memory_type:Memory type used for the heap
- * @no_nonsecure_alloc: don't allow non-secure allocations from this heap
+ * @allow_nonsecure_alloc: allow non-secure allocations from this heap. For
+ *			secure heaps, this flag must be set so allow non-secure
+ *			allocations. For non-secure heaps, this flag is ignored.
  *
  */
 struct ion_cp_heap_pdata {
@@ -156,7 +166,7 @@
 	int (*release_region)(void *);
 	void *(*setup_region)(void);
 	enum ion_memory_types memory_type;
-	int no_nonsecure_alloc;
+	int allow_nonsecure_alloc;
 };
 
 /**
@@ -271,6 +281,20 @@
 {
 	return -ENODEV;
 }
+
+static inline int msm_ion_secure_buffer(struct ion_client *client,
+					struct ion_handle *handle,
+					enum cp_mem_usage usage,
+					int flags)
+{
+	return -ENODEV;
+}
+
+static inline int msm_ion_unsecure_buffer(struct ion_client *client,
+					struct ion_handle *handle)
+{
+	return -ENODEV;
+}
 #endif /* CONFIG_ION */
 
 #endif /* __KERNEL */
@@ -295,19 +319,6 @@
 	unsigned int length;
 };
 
-/* struct ion_flag_data - information about flags for this buffer
- *
- * @handle:	handle to get flags from
- * @flags:	flags of this handle
- *
- * Takes handle as an input and outputs the flags from the handle
- * in the flag field.
- */
-struct ion_flag_data {
-	struct ion_handle *handle;
-	unsigned long flags;
-};
-
 #define ION_IOC_MSM_MAGIC 'M'
 
 /**
@@ -332,13 +343,4 @@
 #define ION_IOC_CLEAN_INV_CACHES	_IOWR(ION_IOC_MSM_MAGIC, 2, \
 						struct ion_flush_data)
 
-/**
- * DOC: ION_IOC_GET_FLAGS - get the flags of the handle
- *
- * Gets the flags of the current handle which indicate cachability,
- * secure state etc.
- */
-#define ION_IOC_GET_FLAGS		_IOWR(ION_IOC_MSM_MAGIC, 3, \
-						struct ion_flag_data)
-
 #endif
diff --git a/include/linux/msm_ipa.h b/include/linux/msm_ipa.h
index 613cd9f..30bf4f2 100644
--- a/include/linux/msm_ipa.h
+++ b/include/linux/msm_ipa.h
@@ -47,7 +47,7 @@
 #define IPA_IOCTL_V4_INIT_NAT    23
 #define IPA_IOCTL_NAT_DMA        24
 #define IPA_IOCTL_V4_DEL_NAT     26
-#define IPA_IOCTL_GET_ASYNC_MSG  27
+#define IPA_IOCTL_PULL_MSG       27
 #define IPA_IOCTL_GET_NAT_OFFSET 28
 #define IPA_IOCTL_MAX            29
 
@@ -62,6 +62,11 @@
 #define IPA_RESOURCE_NAME_MAX 20
 
 /**
+ * size of the mac address
+ */
+#define IPA_MAC_ADDR_SIZE  6
+
+/**
  * the attributes of the rule (routing or filtering)
  */
 #define IPA_FLT_TOS            (1ul << 0)
@@ -142,6 +147,34 @@
 };
 
 /**
+ * enum ipa_wlan_event - Events for wlan client
+ *
+ * wlan client connect: New wlan client connected
+ * wlan client disconnect: wlan client disconnected
+ * wlan client power save: wlan client moved to power save
+ * wlan client normal: wlan client moved out of power save
+ * sw routing enable: ipa routing is disabled
+ * sw routing disable: ipa routing is enabled
+ * wlan ap connect: wlan AP(access point) is up
+ * wlan ap disconnect: wlan AP(access point) is down
+ * wlan sta connect: wlan STA(station) is up
+ * wlan sta disconnect: wlan STA(station) is down
+ */
+enum ipa_wlan_event {
+	WLAN_CLIENT_CONNECT,
+	WLAN_CLIENT_DISCONNECT,
+	WLAN_CLIENT_POWER_SAVE_MODE,
+	WLAN_CLIENT_NORMAL_MODE,
+	SW_ROUTING_ENABLE,
+	SW_ROUTING_DISABLE,
+	WLAN_AP_CONNECT,
+	WLAN_AP_DISCONNECT,
+	WLAN_STA_CONNECT,
+	WLAN_STA_DISCONNECT,
+};
+
+
+/**
  * struct ipa_rule_attrib - attributes of a routing/filtering
  * rule, all in LE
  * @attrib_mask: what attributes are valid
@@ -501,10 +534,12 @@
 /**
  * struct ipa_ioc_query_intf_tx_props - interface tx propertie
  * @name: name of interface
+ * @num_tx_props: number of TX properties
  * @tx[0]: output parameter, the tx properties go here back to back
  */
 struct ipa_ioc_query_intf_tx_props {
 	char name[IPA_RESOURCE_NAME_MAX];
+	uint32_t num_tx_props;
 	struct ipa_ioc_tx_intf_prop tx[0];
 };
 
@@ -523,10 +558,12 @@
 /**
  * struct ipa_ioc_query_intf_rx_props - interface rx propertie
  * @name: name of interface
+ * @num_rx_props: number of RX properties
  * @rx: output parameter, the rx properties go here back to back
  */
 struct ipa_ioc_query_intf_rx_props {
 	char name[IPA_RESOURCE_NAME_MAX];
+	uint32_t num_rx_props;
 	struct ipa_ioc_rx_intf_prop rx[0];
 };
 
@@ -609,24 +646,45 @@
 /**
  * struct ipa_msg_meta - Format of the message meta-data.
  * @msg_type: the type of the message
- * @msg_len: the length of the message in bytes
  * @rsvd: reserved bits for future use.
+ * @msg_len: the length of the message in bytes
  *
+ * For push model:
  * Client in user-space should issue a read on the device (/dev/ipa) with a
- * buffer of atleast this size in an continuous loop, call will block when there
- * is no pending async message.
+ * sufficiently large buffer in a continuous loop, call will block when there is
+ * no message to read. Upon return, client can read the ipa_msg_meta from start
+ * of buffer to find out type and length of message
+ * size of buffer supplied >= (size of largest message + size of metadata)
  *
- * After reading a message's meta-data using above scheme, client should issue a
- * GET_MSG IOCTL to actually read the message itself into the buffer of
- * "msg_len" immediately following the ipa_msg_meta itself in the IOCTL payload
+ * For pull model:
+ * Client in user-space can also issue a pull msg IOCTL to device (/dev/ipa)
+ * with a payload containing space for the ipa_msg_meta and the message specific
+ * payload length.
+ * size of buffer supplied == (len of specific message  + size of metadata)
  */
 struct ipa_msg_meta {
 	uint8_t msg_type;
-	uint16_t msg_len;
 	uint8_t rsvd;
+	uint16_t msg_len;
 };
 
 /**
+ * struct ipa_wlan_msg - To hold information about wlan client
+ * @name: name of the wlan interface
+ * @mac_addr: mac address of wlan client
+ *
+ * wlan drivers need to pass name of wlan iface and mac address of
+ * wlan client along with ipa_wlan_event, whenever a wlan client is
+ * connected/disconnected/moved to power save/come out of power save
+ */
+struct ipa_wlan_msg {
+	char name[IPA_RESOURCE_NAME_MAX];
+	uint8_t mac_addr[IPA_MAC_ADDR_SIZE];
+};
+
+
+
+/**
  *   actual IOCTLs supported by IPA driver
  */
 #define IPA_IOC_ADD_HDR _IOWR(IPA_IOC_MAGIC, \
@@ -707,8 +765,91 @@
 #define IPA_IOC_SET_FLT _IOW(IPA_IOC_MAGIC, \
 			IPA_IOCTL_SET_FLT, \
 			uint32_t)
-#define IPA_IOC_GET_ASYNC_MSG _IOWR(IPA_IOC_MAGIC, \
-				IPA_IOCTL_GET_ASYNC_MSG, \
+#define IPA_IOC_PULL_MSG _IOWR(IPA_IOC_MAGIC, \
+				IPA_IOCTL_PULL_MSG, \
 				struct ipa_msg_meta *)
 
+/*
+ * unique magic number of the Tethering bridge ioctls
+ */
+#define TETH_BRIDGE_IOC_MAGIC 0xCE
+
+/*
+ * Ioctls supported by Tethering bridge driver
+ */
+#define TETH_BRIDGE_IOCTL_SET_BRIDGE_MODE	0
+#define TETH_BRIDGE_IOCTL_SET_AGGR_PARAMS	1
+#define TETH_BRIDGE_IOCTL_GET_AGGR_PARAMS	2
+#define TETH_BRIDGE_IOCTL_GET_AGGR_CAPABILITIES	3
+#define TETH_BRIDGE_IOCTL_MAX			4
+
+
+/**
+ * enum teth_link_protocol_type - link protocol (IP / Ethernet)
+ */
+enum teth_link_protocol_type {
+	TETH_LINK_PROTOCOL_IP,
+	TETH_LINK_PROTOCOL_ETHERNET,
+	TETH_LINK_PROTOCOL_MAX,
+};
+
+/**
+ * enum teth_aggr_protocol_type - Aggregation protocol (MBIM / TLP)
+ */
+enum teth_aggr_protocol_type {
+	TETH_AGGR_PROTOCOL_NONE,
+	TETH_AGGR_PROTOCOL_MBIM,
+	TETH_AGGR_PROTOCOL_TLP,
+	TETH_AGGR_PROTOCOL_MAX,
+};
+
+/**
+ * struct teth_aggr_params_link - Aggregation parameters for uplink/downlink
+ * @aggr_prot:			Aggregation protocol (MBIM / TLP)
+ * @max_transfer_size_byte:	Maximal size of aggregated packet in bytes.
+ *				Default value is 16*1024.
+ * @max_datagrams:		Maximal number of IP packets in an aggregated
+ *				packet. Default value is 16
+ */
+struct teth_aggr_params_link {
+	enum teth_aggr_protocol_type aggr_prot;
+	uint32_t max_transfer_size_byte;
+	uint32_t max_datagrams;
+};
+
+
+/**
+ * struct teth_aggr_params - Aggregation parmeters
+ * @ul:	Uplink parameters
+ * @dl: Downlink parmaeters
+ */
+struct teth_aggr_params {
+	struct teth_aggr_params_link ul;
+	struct teth_aggr_params_link dl;
+};
+
+/**
+ * struct teth_aggr_capabilities - Aggregation capabilities
+ * @num_protocols:		Number of protocols described in the array
+ * @prot_caps[]:		Array of aggregation capabilities per protocol
+ */
+struct teth_aggr_capabilities {
+	uint16_t num_protocols;
+	struct teth_aggr_params_link prot_caps[0];
+};
+
+
+#define TETH_BRIDGE_IOC_SET_BRIDGE_MODE _IOW(TETH_BRIDGE_IOC_MAGIC, \
+				TETH_BRIDGE_IOCTL_SET_BRIDGE_MODE, \
+				enum teth_link_protocol_type)
+#define TETH_BRIDGE_IOC_SET_AGGR_PARAMS _IOW(TETH_BRIDGE_IOC_MAGIC, \
+				TETH_BRIDGE_IOCTL_SET_AGGR_PARAMS, \
+				struct teth_aggr_params *)
+#define TETH_BRIDGE_IOC_GET_AGGR_PARAMS _IOR(TETH_BRIDGE_IOC_MAGIC, \
+				TETH_BRIDGE_IOCTL_GET_AGGR_PARAMS, \
+				struct teth_aggr_params *)
+#define TETH_BRIDGE_IOC_GET_AGGR_CAPABILITIES _IOWR(TETH_BRIDGE_IOC_MAGIC, \
+				TETH_BRIDGE_IOCTL_GET_AGGR_CAPABILITIES, \
+				struct teth_aggr_capabilities *)
+
 #endif /* _MSM_IPA_H_ */
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index d3f6792..45bc0ea 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -1,7 +1,7 @@
 /* include/linux/msm_mdp.h
  *
  * Copyright (C) 2007 Google Incorporated
- * Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -72,6 +72,10 @@
 #define MSMFB_VSYNC_CTRL  _IOW(MSMFB_IOCTL_MAGIC, 161, unsigned int)
 #define MSMFB_METADATA_SET  _IOW(MSMFB_IOCTL_MAGIC, 162, struct msmfb_metadata)
 #define MSMFB_OVERLAY_COMMIT      _IO(MSMFB_IOCTL_MAGIC, 163)
+#define MSMFB_BUFFER_SYNC  _IOW(MSMFB_IOCTL_MAGIC, 164, struct mdp_buf_sync)
+#define MSMFB_DISPLAY_COMMIT      _IOW(MSMFB_IOCTL_MAGIC, 165, \
+						struct mdp_display_commit)
+#define MSMFB_METADATA_GET  _IOW(MSMFB_IOCTL_MAGIC, 166, struct msmfb_metadata)
 
 #define FB_TYPE_3D_PANEL 0x10101010
 #define MDP_IMGTYPE2_START 0x10000
@@ -110,6 +114,7 @@
 	MDP_BGR_565,      /* BGR 565 planer */
 	MDP_BGR_888,      /* BGR 888 */
 	MDP_Y_CBCR_H2V2_VENUS,
+	MDP_BGRX_8888,   /* BGRX 8888 */
 	MDP_IMGTYPE_LIMIT,
 	MDP_RGB_BORDERFILL,	/* border fill pipe */
 	MDP_FB_FORMAT = MDP_IMGTYPE2_START,    /* framebuffer format */
@@ -142,6 +147,7 @@
 #define MDP_DITHER 0x8
 #define MDP_BLUR 0x10
 #define MDP_BLEND_FG_PREMULT 0x20000
+#define MDP_IS_FG 0x40000
 #define MDP_DEINTERLACE 0x80000000
 #define MDP_SHARPENING  0x40000000
 #define MDP_NO_DMA_BARRIER_START	0x20000000
@@ -161,6 +167,7 @@
 #define MDP_BACKEND_COMPOSITION		0x00040000
 #define MDP_BORDERFILL_SUPPORTED	0x00010000
 #define MDP_SECURE_OVERLAY_SESSION      0x00008000
+#define MDP_OV_PIPE_FORCE_DMA		0x00004000
 #define MDP_MEMORY_ID_TYPE_FB		0x00001000
 
 #define MDP_TRANSP_NOP 0xffffffff
@@ -281,6 +288,18 @@
 #define MDP_PP_IGC_FLAG_ROM0	0x10
 #define MDP_PP_IGC_FLAG_ROM1	0x20
 
+#define MDSS_PP_DSPP_CFG	0x0000
+#define MDSS_PP_SSPP_CFG	0x4000
+#define MDSS_PP_LM_CFG	0x8000
+#define MDSS_PP_WB_CFG	0xC000
+
+#define MDSS_PP_LOCATION_MASK	0xC000
+#define MDSS_PP_LOGICAL_MASK	0x3FFF
+
+#define PP_LOCAT(var) ((var) & MDSS_PP_LOCATION_MASK)
+#define PP_BLOCK(var) ((var) & MDSS_PP_LOGICAL_MASK)
+
+
 struct mdp_qseed_cfg {
 	uint32_t table_num;
 	uint32_t ops;
@@ -288,13 +307,24 @@
 	uint32_t *data;
 };
 
+struct mdp_sharp_cfg {
+	uint32_t flags;
+	uint32_t strength;
+	uint32_t edge_thr;
+	uint32_t smooth_thr;
+	uint32_t noise_thr;
+};
+
 struct mdp_qseed_cfg_data {
 	uint32_t block;
 	struct mdp_qseed_cfg qseed_data;
 };
 
-#define MDP_OVERLAY_PP_CSC_CFG      0x1
-#define MDP_OVERLAY_PP_QSEED_CFG    0x2
+#define MDP_OVERLAY_PP_CSC_CFG         0x1
+#define MDP_OVERLAY_PP_QSEED_CFG       0x2
+#define MDP_OVERLAY_PP_PA_CFG          0x4
+#define MDP_OVERLAY_PP_IGC_CFG         0x8
+#define MDP_OVERLAY_PP_SHARP_CFG       0x10
 
 #define MDP_CSC_FLAG_ENABLE	0x1
 #define MDP_CSC_FLAG_YUV_IN	0x2
@@ -315,10 +345,28 @@
 	struct mdp_csc_cfg csc_data;
 };
 
+struct mdp_pa_cfg {
+	uint32_t flags;
+	uint32_t hue_adj;
+	uint32_t sat_adj;
+	uint32_t val_adj;
+	uint32_t cont_adj;
+};
+
+struct mdp_igc_lut_data {
+	uint32_t block;
+	uint32_t len, ops;
+	uint32_t *c0_c1_data;
+	uint32_t *c2_data;
+};
+
 struct mdp_overlay_pp_params {
 	uint32_t config_ops;
 	struct mdp_csc_cfg csc_cfg;
 	struct mdp_qseed_cfg qseed_cfg[2];
+	struct mdp_pa_cfg pa_cfg;
+	struct mdp_igc_lut_data igc_cfg;
+	struct mdp_sharp_cfg sharp_cfg;
 };
 
 struct mdp_overlay {
@@ -435,13 +483,6 @@
 	mdp_lut_max,
 };
 
-struct mdp_igc_lut_data {
-	uint32_t block;
-	uint32_t len, ops;
-	uint32_t *c0_c1_data;
-	uint32_t *c2_data;
-};
-
 struct mdp_ar_gc_lut_data {
 	uint32_t x_start;
 	uint32_t slope;
@@ -483,11 +524,7 @@
 
 struct mdp_pa_cfg_data {
 	uint32_t block;
-	uint32_t flags;
-	uint32_t hue_adj;
-	uint32_t sat_adj;
-	uint32_t val_adj;
-	uint32_t cont_adj;
+	struct mdp_pa_cfg pa_data;
 };
 
 struct mdp_dither_cfg_data {
@@ -508,6 +545,12 @@
 	uint16_t *b_tbl[MDP_GAMUT_TABLE_NUM];
 };
 
+struct mdp_calib_config_data {
+	uint32_t ops;
+	uint32_t addr;
+	uint32_t data;
+};
+
 enum {
 	mdp_op_pcc_cfg,
 	mdp_op_csc_cfg,
@@ -517,9 +560,19 @@
 	mdp_op_pa_cfg,
 	mdp_op_dither_cfg,
 	mdp_op_gamut_cfg,
+	mdp_op_calib_cfg,
 	mdp_op_max,
 };
 
+enum {
+	WB_FORMAT_NV12,
+	WB_FORMAT_RGB_565,
+	WB_FORMAT_RGB_888,
+	WB_FORMAT_xRGB_8888,
+	WB_FORMAT_ARGB_8888,
+	WB_FORMAT_ARGB_8888_INPUT_ALPHA /* Need to support */
+};
+
 struct msmfb_mdp_pp {
 	uint32_t op;
 	union {
@@ -531,12 +584,17 @@
 		struct mdp_pa_cfg_data pa_cfg_data;
 		struct mdp_dither_cfg_data dither_cfg_data;
 		struct mdp_gamut_cfg_data gamut_cfg_data;
+		struct mdp_calib_config_data calib_cfg;
 	} data;
 };
 
+#define FB_METADATA_VIDEO_INFO_CODE_SUPPORT 1
 enum {
 	metadata_op_none,
 	metadata_op_base_blend,
+	metadata_op_frame_rate,
+	metadata_op_vic,
+	metadata_op_wb_format,
 	metadata_op_max
 };
 
@@ -544,13 +602,40 @@
 	uint32_t is_premultiplied;
 };
 
+struct mdp_mixer_cfg {
+	uint32_t writeback_format;
+	uint32_t alpha;
+};
+
 struct msmfb_metadata {
 	uint32_t op;
 	uint32_t flags;
 	union {
 		struct mdp_blend_cfg blend_cfg;
+		struct mdp_mixer_cfg mixer_cfg;
+		uint32_t panel_frame_rate;
+		uint32_t video_info_code;
 	} data;
 };
+
+#define MDP_MAX_FENCE_FD	10
+#define MDP_BUF_SYNC_FLAG_WAIT	1
+
+struct mdp_buf_sync {
+	uint32_t flags;
+	uint32_t acq_fen_fd_cnt;
+	int *acq_fen_fd;
+	int *rel_fen_fd;
+};
+
+#define MDP_DISPLAY_COMMIT_OVERLAY	1
+
+struct mdp_display_commit {
+	uint32_t flags;
+	uint32_t wait_for_finish;
+	struct fb_var_screeninfo var;
+};
+
 struct mdp_page_protection {
 	uint32_t page_protection;
 };
@@ -577,8 +662,13 @@
 	ROTATOR_SUBSYSTEM_ID,
 };
 
+enum {
+	MDP_IOMMU_DOMAIN_CP,
+	MDP_IOMMU_DOMAIN_NS,
+};
+
 #ifdef __KERNEL__
-int msm_fb_get_iommu_domain(void);
+int msm_fb_get_iommu_domain(struct fb_info *info, int domain);
 /* get the framebuffer physical address information */
 int get_fb_phys_info(unsigned long *start, unsigned long *len, int fb_num,
 	int subsys_id);
@@ -591,6 +681,7 @@
 		struct msmfb_data *data);
 int msm_fb_writeback_stop(struct fb_info *info);
 int msm_fb_writeback_terminate(struct fb_info *info);
+int msm_fb_writeback_set_secure(struct fb_info *info, int enable);
 #endif
 
 #endif /*_MSM_MDP_H_*/
diff --git a/include/linux/msm_rmnet.h b/include/linux/msm_rmnet.h
index 063a8f1..d41b55c 100644
--- a/include/linux/msm_rmnet.h
+++ b/include/linux/msm_rmnet.h
@@ -1,16 +1,3 @@
-/* Copyright (c) 2010, Code Aurora Forum. 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 _MSM_RMNET_H_
 #define _MSM_RMNET_H_
 
diff --git a/include/linux/msm_rpcrouter.h b/include/linux/msm_rpcrouter.h
index 01d3809..cd304f3 100644
--- a/include/linux/msm_rpcrouter.h
+++ b/include/linux/msm_rpcrouter.h
@@ -1,6 +1,6 @@
 /* include/linux/msm_rpcrouter.h
  *
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  * Copyright (C) 2007 Google, Inc.
  * Author: San Mehat <san@android.com>
  *
diff --git a/include/linux/msm_smd_pkt.h b/include/linux/msm_smd_pkt.h
index dc7328f..cba9f6f 100644
--- a/include/linux/msm_smd_pkt.h
+++ b/include/linux/msm_smd_pkt.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/msm_ssbi.h b/include/linux/msm_ssbi.h
index 647bc06..6858d00 100644
--- a/include/linux/msm_ssbi.h
+++ b/include/linux/msm_ssbi.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2010 Google, Inc.
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  * Author: Dima Zavin <dima@android.com>
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/include/linux/msm_thermal.h b/include/linux/msm_thermal.h
index 8b7bb7c..2c9a613 100644
--- a/include/linux/msm_thermal.h
+++ b/include/linux/msm_thermal.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/include/linux/msm_tsens.h b/include/linux/msm_tsens.h
index 1b0d399..5837094 100644
--- a/include/linux/msm_tsens.h
+++ b/include/linux/msm_tsens.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/include/linux/msm_vidc_dec.h b/include/linux/msm_vidc_dec.h
index 3c99562..cc864f0 100644
--- a/include/linux/msm_vidc_dec.h
+++ b/include/linux/msm_vidc_dec.h
@@ -78,6 +78,7 @@
 
 #define VDEC_EXTRADATA_EXT_DATA          0x0800
 #define VDEC_EXTRADATA_USER_DATA         0x1000
+#define VDEC_EXTRADATA_EXT_BUFFER        0x2000
 
 #define VDEC_CMDBASE	0x800
 #define VDEC_CMD_SET_INTF_VERSION	(VDEC_CMDBASE)
@@ -213,6 +214,12 @@
 #define VDEC_IOCTL_SET_PERF_CLK \
 	_IOR(VDEC_IOCTL_MAGIC, 38, struct vdec_ioctl_msg)
 
+#define VDEC_IOCTL_SET_META_BUFFERS \
+	_IOW(VDEC_IOCTL_MAGIC, 39, struct vdec_ioctl_msg)
+
+#define VDEC_IOCTL_FREE_META_BUFFERS \
+	_IO(VDEC_IOCTL_MAGIC, 40)
+
 enum vdec_picture {
 	PICTURE_TYPE_I,
 	PICTURE_TYPE_P,
@@ -236,6 +243,7 @@
 	size_t buffer_size;
 	uint32_t alignment;
 	uint32_t buf_poolid;
+	size_t meta_buffer_size;
 };
 
 struct vdec_bufferpayload {
@@ -526,6 +534,11 @@
 	uint32_t par_height;
 };
 
+struct vdec_sep_metadatainfo {
+	void __user *metabufaddr;
+	uint32_t size;
+};
+
 struct vdec_output_frameinfo {
 	void __user *bufferaddr;
 	size_t offset;
@@ -538,6 +551,7 @@
 	struct vdec_framesize framesize;
 	enum vdec_interlaced_format interlaced_format;
 	struct vdec_aspectratioinfo aspect_ratio_info;
+	struct vdec_sep_metadatainfo metadata_info;
 };
 
 union vdec_msgdata {
@@ -571,4 +585,12 @@
 	int alignment;
 };
 
+struct vdec_meta_buffers {
+	size_t size;
+	int count;
+	int pmem_fd;
+	int pmem_fd_iommu;
+	int offset;
+};
+
 #endif /* end of macro _VDECDECODER_H_ */
diff --git a/include/linux/msm_vidc_enc.h b/include/linux/msm_vidc_enc.h
index ea7db81..dcc2353 100644
--- a/include/linux/msm_vidc_enc.h
+++ b/include/linux/msm_vidc_enc.h
@@ -44,6 +44,8 @@
 #define VEN_MSG_PAUSE	8
 #define VEN_MSG_RESUME	9
 #define VEN_MSG_STOP_READING_MSG	10
+#define VEN_MSG_LTRUSE_FAILED	    11
+
 
 /*Buffer flags bits masks*/
 #define VEN_BUFFLAG_EOS	0x00000001
@@ -56,6 +58,7 @@
 #define VEN_EXTRADATA_NONE          0x001
 #define VEN_EXTRADATA_QCOMFILLER    0x002
 #define VEN_EXTRADATA_SLICEINFO     0x100
+#define VEN_EXTRADATA_LTRINFO       0x200
 
 /*ENCODER CONFIGURATION CONSTANTS*/
 
@@ -461,6 +464,58 @@
 #define VEN_IOCTL_SET_H263_PLUSPTYPE \
 	_IOW(VEN_IOCTLBASE_ENC, 51, struct venc_ioctl_msg)
 
+/*IOCTL params:SET: InputData - venc_range, OutputData - NULL.*/
+#define VEN_IOCTL_SET_CAPABILITY_LTRCOUNT \
+	_IOW(VEN_IOCTLBASE_ENC, 52, struct venc_ioctl_msg)
+/*IOCTL params:GET: InputData - NULL, OutputData - venc_range.*/
+#define VEN_IOCTL_GET_CAPABILITY_LTRCOUNT \
+	_IOR(VEN_IOCTLBASE_ENC, 53, struct venc_ioctl_msg)
+
+/*IOCTL params:SET: InputData - venc_ltrmode, OutputData - NULL.*/
+#define VEN_IOCTL_SET_LTRMODE \
+	_IOW(VEN_IOCTLBASE_ENC, 54, struct venc_ioctl_msg)
+/*IOCTL params:GET: InputData - NULL, OutputData - venc_ltrmode.*/
+#define VEN_IOCTL_GET_LTRMODE \
+	_IOR(VEN_IOCTLBASE_ENC, 55, struct venc_ioctl_msg)
+
+/*IOCTL params:SET: InputData - venc_ltrcount, OutputData - NULL.*/
+#define VEN_IOCTL_SET_LTRCOUNT \
+	_IOW(VEN_IOCTLBASE_ENC, 56, struct venc_ioctl_msg)
+/*IOCTL params:GET: InputData - NULL, OutputData - venc_ltrcount.*/
+#define VEN_IOCTL_GET_LTRCOUNT \
+	_IOR(VEN_IOCTLBASE_ENC, 57, struct venc_ioctl_msg)
+
+/*IOCTL params:SET: InputData - venc_ltrperiod, OutputData - NULL.*/
+#define VEN_IOCTL_SET_LTRPERIOD \
+	_IOW(VEN_IOCTLBASE_ENC, 58, struct venc_ioctl_msg)
+/*IOCTL params:GET: InputData - NULL, OutputData - venc_ltrperiod.*/
+#define VEN_IOCTL_GET_LTRPERIOD \
+	_IOR(VEN_IOCTLBASE_ENC, 59, struct venc_ioctl_msg)
+
+/*IOCTL params:SET: InputData - venc_ltruse, OutputData - NULL.*/
+#define VEN_IOCTL_SET_LTRUSE \
+	_IOW(VEN_IOCTLBASE_ENC, 60, struct venc_ioctl_msg)
+/*IOCTL params:GET: InputData - NULL, OutputData - venc_ltruse.*/
+#define VEN_IOCTL_GET_LTRUSE \
+	_IOR(VEN_IOCTLBASE_ENC, 61, struct venc_ioctl_msg)
+
+/*IOCTL params:SET: InputData - venc_ltrmark, OutputData - NULL.*/
+#define VEN_IOCTL_SET_LTRMARK \
+	_IOW(VEN_IOCTLBASE_ENC, 62, struct venc_ioctl_msg)
+/*IOCTL params:GET: InputData - NULL, OutputData - venc_ltrmark.*/
+#define VEN_IOCTL_GET_LTRMARK \
+	_IOR(VEN_IOCTLBASE_ENC, 63, struct venc_ioctl_msg)
+
+/*IOCTL params:SET: InputData - unsigned int, OutputData - NULL*/
+#define VEN_IOCTL_SET_SPS_PPS_FOR_IDR \
+	_IOW(VEN_IOCTLBASE_ENC, 64, struct venc_ioctl_msg)
+
+struct venc_range {
+	unsigned long	max;
+	unsigned long	min;
+	unsigned long	step_size;
+};
+
 struct venc_switch{
 	unsigned char	status;
 };
@@ -622,4 +677,21 @@
 	int alignment;
 };
 
+struct venc_ltrmode {
+	unsigned long   ltr_mode;
+};
+
+struct venc_ltrcount {
+	unsigned long   ltr_count;
+};
+
+struct venc_ltrperiod {
+	unsigned long   ltr_period;
+};
+
+struct venc_ltruse {
+	unsigned long   ltr_id;
+	unsigned long   ltr_frames;
+};
+
 #endif /* _MSM_VIDC_ENC_H_ */
diff --git a/include/linux/netfilter_ipv4/ipt_NATTYPE.h b/include/linux/netfilter_ipv4/ipt_NATTYPE.h
index b612290..88311c9 100644
--- a/include/linux/netfilter_ipv4/ipt_NATTYPE.h
+++ b/include/linux/netfilter_ipv4/ipt_NATTYPE.h
@@ -21,5 +21,7 @@
 	u_int16_t type;
 };
 
+extern bool nattype_refresh_timer(unsigned long nattype);
+
 #endif /*_IPT_NATTYPE_H_target*/
 
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index e0d9072..0683296 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -365,8 +365,8 @@
  *	requests to connect to a specified network but without separating
  *	auth and assoc steps. For this, you need to specify the SSID in a
  *	%NL80211_ATTR_SSID attribute, and can optionally specify the association
- *	IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_MAC,
- *	%NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT,
+ *	IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_USE_MFP,
+ *	%NL80211_ATTR_MAC, %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT,
  *	%NL80211_ATTR_CONTROL_PORT_ETHERTYPE and
  *	%NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT.
  *	Background scan period can optionally be
@@ -514,6 +514,12 @@
  *	of PMKSA caching dandidates.
  *
  * @NL80211_CMD_TDLS_OPER: Perform a high-level TDLS command (e.g. link setup).
+ *	In addition, this can be used as an event to request userspace to take
+ *	actions on TDLS links (set up a new link or tear down an existing one).
+ *	In such events, %NL80211_ATTR_TDLS_OPERATION indicates the requested
+ *	operation, %NL80211_ATTR_MAC contains the peer MAC address, and
+ *	%NL80211_ATTR_REASON_CODE the reason code to be used (only with
+ *	%NL80211_TDLS_TEARDOWN).
  * @NL80211_CMD_TDLS_MGMT: Send a TDLS management frame.
  *
  * @NL80211_CMD_UNEXPECTED_FRAME: Used by an application controlling an AP
@@ -900,7 +906,7 @@
  * @NL80211_ATTR_USE_MFP: Whether management frame protection (IEEE 802.11w) is
  *	used for the association (&enum nl80211_mfp, represented as a u32);
  *	this attribute can be used
- *	with %NL80211_CMD_ASSOCIATE request
+ *	with %NL80211_CMD_ASSOCIATE and %NL80211_CMD_CONNECT requests
  *
  * @NL80211_ATTR_STA_FLAGS2: Attribute containing a
  *	&struct nl80211_sta_flag_update.
diff --git a/include/linux/of_coresight.h b/include/linux/of_coresight.h
index 47a05c9..0943dda 100644
--- a/include/linux/of_coresight.h
+++ b/include/linux/of_coresight.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -16,12 +16,19 @@
 #ifdef CONFIG_OF
 extern struct coresight_platform_data *of_get_coresight_platform_data(
 				struct device *dev, struct device_node *node);
+extern struct coresight_cti_data *of_get_coresight_cti_data(
+				struct device *dev, struct device_node *node);
 #else
 static inline struct coresight_platform_data *of_get_coresight_platform_data(
 				struct device *dev, struct device_node *node)
 {
 	return NULL;
 }
+static inline struct coresight_cti_data *of_get_coresight_cti_data(
+				struct device *dev, struct device_node *node)
+{
+	return NULL;
+}
 #endif
 
 #endif
diff --git a/include/linux/of_slimbus.h b/include/linux/of_slimbus.h
index 8e1dc65..f686cdc 100644
--- a/include/linux/of_slimbus.h
+++ b/include/linux/of_slimbus.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/include/linux/of_spmi.h b/include/linux/of_spmi.h
index fe09dec..b22696b 100644
--- a/include/linux/of_spmi.h
+++ b/include/linux/of_spmi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/include/linux/ofn_atlab.h b/include/linux/ofn_atlab.h
index 16c34d7..6e3a277 100644
--- a/include/linux/ofn_atlab.h
+++ b/include/linux/ofn_atlab.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
diff --git a/include/linux/platform_data/qcom_crypto_device.h b/include/linux/platform_data/qcom_crypto_device.h
index 08aa784..37cf3c8 100644
--- a/include/linux/platform_data/qcom_crypto_device.h
+++ b/include/linux/platform_data/qcom_crypto_device.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/platform_data/qcom_ssm.h b/include/linux/platform_data/qcom_ssm.h
new file mode 100644
index 0000000..03ac67a
--- /dev/null
+++ b/include/linux/platform_data/qcom_ssm.h
@@ -0,0 +1,21 @@
+/* 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 __QCOM_SSM_H_
+#define __QCOM_SSM_H_
+
+struct ssm_platform_data {
+	bool need_key_exchg;
+	const char *channel_name;
+};
+
+#endif /* __QCOM_SSM_H_ */
diff --git a/include/linux/platform_data/qcom_wcnss_device.h b/include/linux/platform_data/qcom_wcnss_device.h
index e904084..be9a09a 100644
--- a/include/linux/platform_data/qcom_wcnss_device.h
+++ b/include/linux/platform_data/qcom_wcnss_device.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/pmic8058-charger.h b/include/linux/pmic8058-charger.h
index 0fbc828..a11c4ed 100644
--- a/include/linux/pmic8058-charger.h
+++ b/include/linux/pmic8058-charger.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/pmic8058-othc.h b/include/linux/pmic8058-othc.h
index 4c59845..bd96c3f 100644
--- a/include/linux/pmic8058-othc.h
+++ b/include/linux/pmic8058-othc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/pmic8058-pwm.h b/include/linux/pmic8058-pwm.h
index d380170..a9fc0db 100644
--- a/include/linux/pmic8058-pwm.h
+++ b/include/linux/pmic8058-pwm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/pmic8058-xoadc.h b/include/linux/pmic8058-xoadc.h
index 5163b65..bc4772d 100644
--- a/include/linux/pmic8058-xoadc.h
+++ b/include/linux/pmic8058-xoadc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/power/ltc4088-charger.h b/include/linux/power/ltc4088-charger.h
index 7a0bacf..e7c7e63 100644
--- a/include/linux/power/ltc4088-charger.h
+++ b/include/linux/power/ltc4088-charger.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 46724eb..6e30ca2 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -126,6 +126,7 @@
 	POWER_SUPPLY_PROP_TIME_TO_FULL_AVG,
 	POWER_SUPPLY_PROP_TYPE, /* use power_supply.type instead */
 	POWER_SUPPLY_PROP_SCOPE,
+	POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL,
 	/* Properties of type `const char *' */
 	POWER_SUPPLY_PROP_MODEL_NAME,
 	POWER_SUPPLY_PROP_MANUFACTURER,
diff --git a/include/linux/qcomwlan7x27a_pwrif.h b/include/linux/qcomwlan7x27a_pwrif.h
index 16e1783..fc022ae 100644
--- a/include/linux/qcomwlan7x27a_pwrif.h
+++ b/include/linux/qcomwlan7x27a_pwrif.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/qcomwlan_pwrif.h b/include/linux/qcomwlan_pwrif.h
index 74d2a80..fc5f1e8 100644
--- a/include/linux/qcomwlan_pwrif.h
+++ b/include/linux/qcomwlan_pwrif.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/qcomwlan_secif.h b/include/linux/qcomwlan_secif.h
index 8c6e425..b0f5308 100644
--- a/include/linux/qcomwlan_secif.h
+++ b/include/linux/qcomwlan_secif.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/qcota.h b/include/linux/qcota.h
index afc6b7f..cf62f02 100644
--- a/include/linux/qcota.h
+++ b/include/linux/qcota.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/qfp_fuse.h b/include/linux/qfp_fuse.h
index 8e3fd5e..d2f8961 100644
--- a/include/linux/qfp_fuse.h
+++ b/include/linux/qfp_fuse.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/include/linux/qmi_encdec.h b/include/linux/qmi_encdec.h
index 4c5f6d3..b1fd217 100644
--- a/include/linux/qmi_encdec.h
+++ b/include/linux/qmi_encdec.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
@@ -150,6 +150,15 @@
 int qmi_kernel_decode(struct msg_desc *desc, void *out_c_struct,
 		      void *in_buf, uint32_t in_buf_len);
 
+/**
+ * qmi_verify_max_msg_len() - Verify the maximum length of a QMI message
+ * @desc: Pointer to structure descriptor.
+ *
+ * @return: true if the maximum message length embedded in structure
+ *          descriptor matches the calculated value, else false.
+ */
+bool qmi_verify_max_msg_len(struct msg_desc *desc);
+
 #else
 static inline int qmi_kernel_encode(struct msg_desc *desc,
 				    void *out_buf, uint32_t out_buf_len,
@@ -164,6 +173,11 @@
 {
 	return -EOPNOTSUPP;
 }
+
+static inline bool qmi_verify_max_msg_len(struct msg_desc *desc)
+{
+	return false;
+}
 #endif
 
 #endif
diff --git a/include/linux/qpnp/clkdiv.h b/include/linux/qpnp/clkdiv.h
index c75a922..5253711 100644
--- a/include/linux/qpnp/clkdiv.h
+++ b/include/linux/qpnp/clkdiv.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/include/linux/qpnp/pin.h b/include/linux/qpnp/pin.h
index fff29ab..4c23f09 100644
--- a/include/linux/qpnp/pin.h
+++ b/include/linux/qpnp/pin.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/include/linux/qpnp/pwm.h b/include/linux/qpnp/pwm.h
index 50c15e9..bf7908b 100644
--- a/include/linux/qpnp/pwm.h
+++ b/include/linux/qpnp/pwm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/include/linux/qpnp/qpnp-adc.h b/include/linux/qpnp/qpnp-adc.h
index 3ab7b9d..05d75ce 100644
--- a/include/linux/qpnp/qpnp-adc.h
+++ b/include/linux/qpnp/qpnp-adc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -680,6 +680,7 @@
  * @state_request: Enable/disable the corresponding high and low temperature
  *		thresholds.
  * @timer_interval: Select polling rate from qpnp_adc_meas_timer_2 type.
+ * @btmid_ctx: A context of void type.
  * @threshold_notification: Notification callback once threshold are crossed.
  */
 struct qpnp_adc_tm_btm_param {
@@ -687,7 +688,9 @@
 	int32_t					low_temp;
 	enum qpnp_state_request			state_request;
 	enum qpnp_adc_meas_timer_2		timer_interval;
-	void	(*threshold_notification) (enum qpnp_tm_state state);
+	void					*btm_ctx;
+	void	(*threshold_notification) (enum qpnp_tm_state state,
+						void *ctx);
 };
 
 /**
@@ -1146,6 +1149,23 @@
  */
 int32_t qpnp_adc_usb_scaler(struct qpnp_adc_tm_usbid_param *param,
 		uint32_t *low_threshold, uint32_t *high_threshold);
+/**
+ * qpnp_vadc_iadc_sync_request() - Performs Voltage ADC read and
+ *		locks the peripheral. When performing simultaneous
+ *		voltage and current request the VADC peripheral is
+ *		prepared for conversion and the IADC sync conversion
+ *		is done from the IADC peripheral.
+ * @channel:	Input channel to perform the voltage ADC read.
+ */
+int32_t qpnp_vadc_iadc_sync_request(enum qpnp_vadc_channels channel);
+/**
+ * qpnp_vadc_iadc_sync_complete_request() - Reads the ADC result and
+ *		unlocks the peripheral.
+ * @result:	Structure pointer of type adc_chan_result
+ *		in which the ADC read results are stored.
+ */
+int32_t qpnp_vadc_iadc_sync_complete_request(
+	enum qpnp_vadc_channels channel, struct qpnp_vadc_result *result);
 #else
 static inline int32_t qpnp_vadc_read(uint32_t channel,
 				struct qpnp_vadc_result *result)
@@ -1183,20 +1203,15 @@
 static inline int32_t qpnp_adc_scale_therm_pu1(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);
+			struct qpnp_vadc_result *chan_rslt)
 { return -ENXIO; }
 static inline int32_t qpnp_adc_scale_therm_pu2(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);
+			struct qpnp_vadc_result *chan_rslt)
 { return -ENXIO; }
 static inline int32_t qpnp_vadc_is_ready(void)
 { return -ENXIO; }
-static inline int32_t qpnp_adc_scale_default(int32_t adc_code,
-			const struct qpnp_adc_properties *adc_prop,
-			const struct qpnp_adc_chan_properties *chan_prop,
-			struct qpnp_adc_chan_result *chan_rslt)
-{ return -ENXIO; }
 static inline int32_t qpnp_get_vadc_gain_and_offset(
 			struct qpnp_vadc_linear_graph *param,
 			enum qpnp_adc_calib_type calib_type)
@@ -1215,6 +1230,13 @@
 static inline int32_t qpnp_adc_tm_scale_voltage_therm_pu2(
 				uint32_t reg, int64_t *result)
 { return -ENXIO; }
+static inline int32_t qpnp_vadc_iadc_sync_request(
+				enum qpnp_vadc_channels channel)
+{ return -ENXIO; }
+static inline int32_t qpnp_vadc_iadc_sync_complete_request(
+				enum qpnp_vadc_channels channel,
+				struct qpnp_vadc_result *result)
+{ return -ENXIO; }
 #endif
 
 /* Public API */
@@ -1223,11 +1245,17 @@
 /**
  * qpnp_iadc_read() - Performs ADC read on the current channel.
  * @channel:	Input channel to perform the ADC read.
- * @result:	Current across rsens in mV.
+ * @result:	Current across rsense in mA.
  */
 int32_t qpnp_iadc_read(enum qpnp_iadc_channels channel,
 				struct qpnp_iadc_result *result);
 /**
+ * qpnp_iadc_get_rsense() - Reads the RDS resistance value from the
+			trim registers.
+ * @rsense:	RDS resistance in nOhms.
+ */
+int32_t qpnp_iadc_get_rsense(int32_t *rsense);
+/**
  * qpnp_iadc_get_gain_and_offset() - Performs gain calibration
  *				over 17.8571mV and offset over selected
  *				channel. Channel can be internal rsense,
@@ -1236,7 +1264,6 @@
  *		type qpnp_iadc_calib.
  */
 int32_t qpnp_iadc_get_gain_and_offset(struct qpnp_iadc_calib *result);
-
 /**
  * qpnp_iadc_is_ready() - Clients can use this API to check if the
  *			  device is ready to use.
@@ -1244,15 +1271,34 @@
  *		has not occured.
  */
 int32_t qpnp_iadc_is_ready(void);
+/**
+ * qpnp_iadc_vadc_sync_read() - Performs synchronous VADC and IADC read.
+ *		The api is to be used only by the BMS to perform
+ *		simultaneous VADC and IADC measurement for battery voltage
+ *		and current.
+ * @i_channel:	Input battery current channel to perform the IADC read.
+ * @i_result:	Current across the rsense in mA.
+ * @v_channel:	Input battery voltage channel to perform VADC read.
+ * @v_result:	Voltage on the vbatt channel with units in mV.
+ */
+int32_t qpnp_iadc_vadc_sync_read(
+	enum qpnp_iadc_channels i_channel, struct qpnp_iadc_result *i_result,
+	enum qpnp_vadc_channels v_channel, struct qpnp_vadc_result *v_result);
 #else
 static inline int32_t qpnp_iadc_read(enum qpnp_iadc_channels channel,
 						struct qpnp_iadc_result *result)
 { return -ENXIO; }
+static inline int32_t qpnp_iadc_get_rsense(int32_t *rsense)
+{ return -ENXIO; }
 static inline int32_t qpnp_iadc_get_gain_and_offset(struct qpnp_iadc_calib
 									*result)
 { return -ENXIO; }
 static inline int32_t qpnp_iadc_is_ready(void)
 { return -ENXIO; }
+static inline int32_t qpnp_iadc_vadc_sync_read(
+	enum qpnp_iadc_channels i_channel, struct qpnp_iadc_result *i_result,
+	enum qpnp_vadc_channels v_channel, struct qpnp_vadc_result *v_result)
+{ return -ENXIO; }
 #endif
 
 /* Public API */
diff --git a/include/linux/qpnp/vibrator.h b/include/linux/qpnp/vibrator.h
new file mode 100644
index 0000000..aa823be
--- /dev/null
+++ b/include/linux/qpnp/vibrator.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 __QPNP_VIBRATOR_H__
+#define __QPNP_VIBRATOR_H__
+
+enum qpnp_vib_en_mode {
+	QPNP_VIB_MANUAL,
+	QPNP_VIB_DTEST1,
+	QPNP_VIB_DTEST2,
+	QPNP_VIB_DTEST3,
+};
+
+struct qpnp_vib_config {
+	u16			drive_mV;
+	u8			active_low;
+	enum qpnp_vib_en_mode	enable_mode;
+};
+#if defined(CONFIG_QPNP_VIBRATOR)
+
+int qpnp_vibrator_config(struct qpnp_vib_config *vib_config);
+#else
+
+static inline int qpnp_vibrator_config(struct qpnp_vib_config *vib_config)
+{
+	return -ENODEV;
+}
+#endif
+
+#endif /* __QPNP_VIBRATOR_H__ */
diff --git a/include/linux/regulator/krait-regulator.h b/include/linux/regulator/krait-regulator.h
index 9806225..b784531 100644
--- a/include/linux/regulator/krait-regulator.h
+++ b/include/linux/regulator/krait-regulator.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -13,7 +13,8 @@
 #ifndef __KRAIT_REGULATOR_H__
 #define __KRAIT_REGULATOR_H__
 
-#define KRAIT_REGULATOR_DRIVER_NAME "krait-power-regulator"
+#define KRAIT_REGULATOR_DRIVER_NAME	"krait-power-regulator"
+#define KRAIT_PDN_DRIVER_NAME		"krait-pdn"
 
 /**
  * krait_power_init - driver initialization function
@@ -26,6 +27,22 @@
 #ifdef CONFIG_ARCH_MSM8974
 int __init krait_power_init(void);
 void secondary_cpu_hs_init(void *base_ptr);
+
+/**
+ * krait_power_mdd_enable - function to turn on/off MDD. Turning off MDD
+ *				turns off badngap reference for LDO. If
+ *				a core is running on a LDO, requests to
+ *				turn off MDD will not be honoured
+ * @on:	boolean to indicate whether to turn MDD on/off
+ *
+ * CONTEXT: Can be called in interrupt context, only when the core
+ *		is about to go to idle, this guarantees that there are no
+ *		frequency changes on that cpu happening. Note if going from off
+ *		to on mode there will be settling delays
+ *
+ * RETURNS: -EINVAL if MDD cannot be turned off
+ */
+int krait_power_mdd_enable(int cpu_num, bool on);
 #else
 static inline int __init krait_power_init(void)
 {
@@ -33,6 +50,10 @@
 }
 
 static inline void secondary_cpu_hs_init(void *base_ptr) {}
+static inline int krait_power_mdd_enable(int cpu_num, bool on)
+{
+	return -EINVAL;
+}
 #endif
 
 #endif
diff --git a/include/linux/regulator/msm-gpio-regulator.h b/include/linux/regulator/msm-gpio-regulator.h
index 9efda85..0269aa7 100644
--- a/include/linux/regulator/msm-gpio-regulator.h
+++ b/include/linux/regulator/msm-gpio-regulator.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/include/linux/regulator/onsemi-ncp6335d.h b/include/linux/regulator/onsemi-ncp6335d.h
index a57c3b7..98a5fea 100644
--- a/include/linux/regulator/onsemi-ncp6335d.h
+++ b/include/linux/regulator/onsemi-ncp6335d.h
@@ -23,6 +23,7 @@
 	int default_vsel;
 	int slew_rate_ns;
 	int discharge_enable;
+	bool sleep_enable;
 };
 
 #endif
diff --git a/include/linux/regulator/pm8058-xo.h b/include/linux/regulator/pm8058-xo.h
index a2b8aeb..29cdd01 100644
--- a/include/linux/regulator/pm8058-xo.h
+++ b/include/linux/regulator/pm8058-xo.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/regulator/pm8xxx-regulator.h b/include/linux/regulator/pm8xxx-regulator.h
index 4ca624b..7461c6a 100644
--- a/include/linux/regulator/pm8xxx-regulator.h
+++ b/include/linux/regulator/pm8xxx-regulator.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/include/linux/regulator/pmic8058-regulator.h b/include/linux/regulator/pmic8058-regulator.h
index 3eeaa61..ee1d93d 100644
--- a/include/linux/regulator/pmic8058-regulator.h
+++ b/include/linux/regulator/pmic8058-regulator.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/regulator/pmic8901-regulator.h b/include/linux/regulator/pmic8901-regulator.h
index ec842bc..60d9353 100644
--- a/include/linux/regulator/pmic8901-regulator.h
+++ b/include/linux/regulator/pmic8901-regulator.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/regulator/qpnp-regulator.h b/include/linux/regulator/qpnp-regulator.h
index ca8ccd7..ec580ab 100644
--- a/include/linux/regulator/qpnp-regulator.h
+++ b/include/linux/regulator/qpnp-regulator.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/include/linux/remote_spinlock.h b/include/linux/remote_spinlock.h
index 8d7c7e7..e39846f 100644
--- a/include/linux/remote_spinlock.h
+++ b/include/linux/remote_spinlock.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2008-2009, 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
@@ -89,6 +90,9 @@
 #define remote_spin_release_all(pid) \
 	_remote_spin_release_all(pid)
 
+#define remote_spin_owner(lock) \
+	_remote_spin_owner(&((lock)->remote))
+
 typedef struct {
 	struct mutex local;
 	_remote_mutex_t remote;
diff --git a/include/linux/rmt_storage_client.h b/include/linux/rmt_storage_client.h
index f56819a..077a42a 100644
--- a/include/linux/rmt_storage_client.h
+++ b/include/linux/rmt_storage_client.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
diff --git a/include/linux/rq_stats.h b/include/linux/rq_stats.h
index e04063f..65d8e8f 100644
--- a/include/linux/rq_stats.h
+++ b/include/linux/rq_stats.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/rtc-msm.h b/include/linux/rtc-msm.h
index f8f6a16..324d66a 100644
--- a/include/linux/rtc-msm.h
+++ b/include/linux/rtc-msm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 0a1428e..67889bf 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -2304,7 +2304,7 @@
 }
 
 /* mmput gets rid of the mappings and all user-space */
-extern void mmput(struct mm_struct *);
+extern int mmput(struct mm_struct *);
 /* Grab a reference to a task's mm, if it is not already going away */
 extern struct mm_struct *get_task_mm(struct task_struct *task);
 /*
diff --git a/include/linux/slimbus/slimbus.h b/include/linux/slimbus/slimbus.h
index e333235..5c5b777 100644
--- a/include/linux/slimbus/slimbus.h
+++ b/include/linux/slimbus/slimbus.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -962,6 +962,12 @@
 extern int slim_driver_register(struct slim_driver *drv);
 
 /*
+ * slim_driver_unregister: Undo effects of slim_driver_register
+ * @drv: Client driver to be unregistered
+ */
+extern void slim_driver_unregister(struct slim_driver *drv);
+
+/*
  * slim_add_numbered_controller: Controller bring-up.
  * @ctrl: Controller to be registered.
  * A controller is registered with the framework using this API. ctrl->nr is the
diff --git a/include/linux/smsc3503.h b/include/linux/smsc3503.h
index 857ad1f..d5df871 100644
--- a/include/linux/smsc3503.h
+++ b/include/linux/smsc3503.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/include/linux/smux.h b/include/linux/smux.h
index 24a6371..56b18fa 100644
--- a/include/linux/smux.h
+++ b/include/linux/smux.h
@@ -1,6 +1,6 @@
 /* include/linux/smux.h
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/include/linux/spmi.h b/include/linux/spmi.h
index f94b5c5..d179eab 100644
--- a/include/linux/spmi.h
+++ b/include/linux/spmi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/include/linux/sync.h b/include/linux/sync.h
index 4c00f04..31ba6ec 100644
--- a/include/linux/sync.h
+++ b/include/linux/sync.h
@@ -16,6 +16,7 @@
 #include <linux/types.h>
 #ifdef __KERNEL__
 
+#include <linux/kref.h>
 #include <linux/ktime.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
@@ -40,14 +41,14 @@
  *			 -1 if a will signabl before b
  * @free_pt:		called before sync_pt is freed
  * @release_obj:	called before sync_timeline is freed
- * @print_obj:		print aditional debug information about sync_timeline.
- *			  should not print a newline
- * @print_pt:		print aditional debug information about sync_pt.
- *			  should not print a newline
+ * @print_obj:		deprecated
+ * @print_pt:		deprecated
  * @fill_driver_data:	write implmentation specific driver data to data.
  *			  should return an error if there is not enough room
  *			  as specified by size.  This information is returned
  *			  to userspace by SYNC_IOC_FENCE_INFO.
+ * @timeline_value_str: fill str with the value of the sync_timeline's counter
+ * @pt_value_str:	fill str with the value of the sync_pt
  */
 struct sync_timeline_ops {
 	const char *driver_name;
@@ -67,19 +68,27 @@
 	/* optional */
 	void (*release_obj)(struct sync_timeline *sync_timeline);
 
-	/* optional */
+	/* deprecated */
 	void (*print_obj)(struct seq_file *s,
 			  struct sync_timeline *sync_timeline);
 
-	/* optional */
+	/* deprecated */
 	void (*print_pt)(struct seq_file *s, struct sync_pt *sync_pt);
 
 	/* optional */
 	int (*fill_driver_data)(struct sync_pt *syncpt, void *data, int size);
+
+	/* optional */
+	void (*timeline_value_str)(struct sync_timeline *timeline, char *str,
+				   int size);
+
+	/* optional */
+	void (*pt_value_str)(struct sync_pt *pt, char *str, int size);
 };
 
 /**
  * struct sync_timeline - sync object
+ * @kref:		reference count on fence.
  * @ops:		ops that define the implementaiton of the sync_timeline
  * @name:		name of the sync_timeline. Useful for debugging
  * @destoryed:		set when sync_timeline is destroyed
@@ -90,6 +99,7 @@
  * @sync_timeline_list:	membership in global sync_timeline_list
  */
 struct sync_timeline {
+	struct kref		kref;
 	const struct sync_timeline_ops	*ops;
 	char			name[32];
 
@@ -110,6 +120,7 @@
  * @parent:		sync_timeline to which this sync_pt belongs
  * @child_list:		membership in sync_timeline.child_list_head
  * @active_list:	membership in sync_timeline.active_list_head
+ * @signaled_list:	membership in temorary signaled_list on stack
  * @fence:		sync_fence to which the sync_pt belongs
  * @pt_list:		membership in sync_fence.pt_list_head
  * @status:		1: signaled, 0:active, <0: error
@@ -121,6 +132,7 @@
 	struct list_head	child_list;
 
 	struct list_head	active_list;
+	struct list_head	signaled_list;
 
 	struct sync_fence	*fence;
 	struct list_head	pt_list;
@@ -134,6 +146,7 @@
 /**
  * struct sync_fence - sync fence
  * @file:		file representing this fence
+ * @kref:		referenace count on fence.
  * @name:		name of sync_fence.  Useful for debugging
  * @pt_list_head:	list of sync_pts in ths fence.  immutable once fence
  *			  is created
@@ -146,6 +159,7 @@
  */
 struct sync_fence {
 	struct file		*file;
+	struct kref		kref;
 	char			name[32];
 
 	/* this list is immutable once the fence is created */
@@ -323,8 +337,8 @@
  * @fence:	fence to wait on
  * @tiemout:	timeout in ms
  *
- * Wait for @fence to be signaled or have an error.  Waits indefintly
- * if @timeout = 0
+ * Wait for @fence to be signaled or have an error.  Waits indefinitely
+ * if @timeout < 0
  */
 int sync_fence_wait(struct sync_fence *fence, long timeout);
 
@@ -383,9 +397,9 @@
 /**
  * DOC: SYNC_IOC_WAIT - wait for a fence to signal
  *
- * pass timeout in milliseconds.
+ * pass timeout in milliseconds.  Waits indefinitely timeout < 0.
  */
-#define SYNC_IOC_WAIT		_IOW(SYNC_IOC_MAGIC, 0, __u32)
+#define SYNC_IOC_WAIT		_IOW(SYNC_IOC_MAGIC, 0, __s32)
 
 /**
  * DOC: SYNC_IOC_MERGE - merge two fences
diff --git a/include/linux/test-iosched.h b/include/linux/test-iosched.h
index b52762c..89d3b30 100644
--- a/include/linux/test-iosched.h
+++ b/include/linux/test-iosched.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -23,7 +23,7 @@
 /*
  * Patterns definitions for read/write requests data
  */
-#define TEST_PATTERN_SEQUENTIAL	-1
+#define TEST_PATTERN_SEQUENTIAL	0x12345678
 #define TEST_PATTERN_5A		0x5A5A5A5A
 #define TEST_PATTERN_FF		0xFFFFFFFF
 #define TEST_NO_PATTERN		0xDEADBEEF
@@ -38,6 +38,7 @@
 typedef char* (get_test_case_str_fn) (struct test_data *);
 typedef void (blk_dev_test_init_fn) (void);
 typedef void (blk_dev_test_exit_fn) (void);
+typedef struct gendisk* (get_rq_disk_fn) (void);
 
 /**
  * enum test_state - defines the state of the test
@@ -132,6 +133,8 @@
  * @test_duration:	A jiffies value saved for timing
  *			calculations
  * @data:		Test specific private data
+ * @test_byte_count:	Total number of bytes dispatched in
+ *			the test
  */
 struct test_info {
 	int testcase;
@@ -142,7 +145,9 @@
 	post_test_fn *post_test_fn;
 	get_test_case_str_fn *get_test_case_str_fn;
 	unsigned long test_duration;
+	get_rq_disk_fn *get_rq_disk_fn;
 	void *data;
+	unsigned long test_byte_count;
 };
 
 /**
@@ -161,8 +166,17 @@
  * struct test_data - global test iosched data
  * @queue:		The test IO scheduler requests list
  * @test_queue:		The test requests list
- * @next_req:		Points to the next request to be
- *			dispatched from the test requests list
+ * @dispatched_queue:   The queue contains requests dispatched
+ *			from @test_queue
+ * @reinsert_queue:     The queue contains reinserted from underlying
+ *			driver requests
+ * @urgent_queue:       The queue contains requests for urgent delivery
+ *			These requests will be delivered before @test_queue
+ *			and @reinsert_queue requests
+ * @test_count:         Number of requests in the @test_queue
+ * @dispatched_count:   Number of requests in the @dispatched_queue
+ * @reinsert_count:     Number of requests in the @reinsert_queue
+ * @urgent_count:       Number of requests in the @urgent_queue
  * @wait_q:		A wait queue for waiting for the test
  *			requests completion
  * @test_state:		Indicates if there is a running test.
@@ -195,7 +209,13 @@
 struct test_data {
 	struct list_head queue;
 	struct list_head test_queue;
-	struct test_request *next_req;
+	struct list_head dispatched_queue;
+	struct list_head reinsert_queue;
+	struct list_head urgent_queue;
+	unsigned int  test_count;
+	unsigned int  dispatched_count;
+	unsigned int  reinsert_count;
+	unsigned int  urgent_count;
 	wait_queue_head_t wait_q;
 	enum test_state test_state;
 	enum test_results test_result;
@@ -214,12 +234,16 @@
 
 extern int test_iosched_start_test(struct test_info *t_info);
 extern void test_iosched_mark_test_completion(void);
+extern void check_test_completion(void);
 extern int test_iosched_add_unique_test_req(int is_err_expcted,
 		enum req_unique_type req_unique,
 		int start_sec, int nr_sects, rq_end_io_fn *end_req_io);
 extern int test_iosched_add_wr_rd_test_req(int is_err_expcted,
 	      int direction, int start_sec,
 	      int num_bios, int pattern, rq_end_io_fn *end_req_io);
+extern struct test_request *test_iosched_create_test_req(int is_err_expcted,
+	      int direction, int start_sec,
+	      int num_bios, int pattern, rq_end_io_fn *end_req_io);
 
 extern struct dentry *test_iosched_get_debugfs_tests_root(void);
 extern struct dentry *test_iosched_get_debugfs_utils_root(void);
@@ -234,4 +258,9 @@
 
 void test_iosched_unregister(struct blk_dev_test_type *bdt);
 
+extern struct test_data *test_get_test_data(void);
+
+void test_iosched_add_urgent_req(struct test_request *test_rq);
+
+int test_is_req_urgent(struct request *rq);
 #endif /* _LINUX_TEST_IOSCHED_H */
diff --git a/include/linux/tsif_api.h b/include/linux/tsif_api.h
index 0c18228..b69ddf5 100644
--- a/include/linux/tsif_api.h
+++ b/include/linux/tsif_api.h
@@ -3,7 +3,7 @@
  *
  * Kernel API
  *
- * Copyright (c) 2009-2010, 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
@@ -256,6 +256,17 @@
 void tsif_stop(void *cookie);
 
 /**
+ * tsif_get_ref_clk_counter - return the TSIF clock reference (TCR) counter.
+ * @cookie:      TSIF cookie previously obtained with tsif_attach()
+ * @tcr_counter: the value of TCR counter
+ *
+ * Return      error code
+ *
+ * TCR increments at a rate equal to 27 MHz/256 = 105.47 kHz.
+ */
+int tsif_get_ref_clk_counter(void *cookie, u32 *tcr_counter);
+
+/**
  * tsif_reclaim_packets - inform that buffer space may be reclaimed
  * @cookie:    TSIF cookie previously obtained with tsif_attach()
  * @ri:        new value for read index
diff --git a/include/linux/tspp.h b/include/linux/tspp.h
index 551fbb0..c790c28 100644
--- a/include/linux/tspp.h
+++ b/include/linux/tspp.h
@@ -88,5 +88,7 @@
 	_IOW(TSPP_IOCTL_BASE, 5, struct tspp_system_keys)
 #define TSPP_IOCTL_BUFFER_SIZE		\
 	_IOW(TSPP_IOCTL_BASE, 6, struct tspp_buffer)
+#define TSPP_IOCTL_CLOSE_STREAM		\
+	_IO(TSPP_IOCTL_BASE, 7)
 
 #endif /* _TSPP_H_ */
diff --git a/include/linux/uhid.h b/include/linux/uhid.h
new file mode 100644
index 0000000..16b786a
--- /dev/null
+++ b/include/linux/uhid.h
@@ -0,0 +1,33 @@
+#ifndef __UHID_H_
+#define __UHID_H_
+
+/*
+ * User-space I/O driver support for HID subsystem
+ * Copyright (c) 2012 David Herrmann
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+/*
+ * Public header for user-space communication. We try to keep every structure
+ * aligned but to be safe we also use __attribute__((__packed__)). Therefore,
+ * the communication should be ABI compatible even between architectures.
+ */
+
+#include <linux/input.h>
+#include <linux/types.h>
+
+enum uhid_event_type {
+	UHID_DUMMY,
+};
+
+struct uhid_event {
+	__u32 type;
+} __attribute__((__packed__));
+
+#endif /* __UHID_H_ */
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 44c64e8..e8114f0 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -771,6 +771,22 @@
 	.bInterfaceProtocol = (pr)
 
 /**
+ * USB_DEVICE_INTERFACE_NUMBER - describe a usb device with a specific interface number
+ * @vend: the 16 bit USB Vendor ID
+ * @prod: the 16 bit USB Product ID
+ * @num: bInterfaceNumber value
+ *
+ * This macro is used to create a struct usb_device_id that matches a
+ * specific interface number of devices.
+ */
+#define USB_DEVICE_INTERFACE_NUMBER(vend, prod, num) \
+	.match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
+		       USB_DEVICE_ID_MATCH_INT_NUMBER, \
+	.idVendor = (vend), \
+	.idProduct = (prod), \
+	.bInterfaceNumber = (num)
+
+/**
  * USB_DEVICE_INFO - macro used to describe a class of usb devices
  * @cl: bDeviceClass value
  * @sc: bDeviceSubClass value
diff --git a/include/linux/usb/ccid_desc.h b/include/linux/usb/ccid_desc.h
index 2d1ae74..334a045 100644
--- a/include/linux/usb/ccid_desc.h
+++ b/include/linux/usb/ccid_desc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/include/linux/usb/cdc.h b/include/linux/usb/cdc.h
index 2b39f69..478734f 100644
--- a/include/linux/usb/cdc.h
+++ b/include/linux/usb/cdc.h
@@ -54,6 +54,7 @@
 #define USB_CDC_OBEX_TYPE		0x15
 #define USB_CDC_NCM_TYPE		0x1a
 #define USB_CDC_MBB_TYPE		0x1b	/* mbb_desc */
+#define USB_CDC_EXT_MBB_TYPE		0x1c
 
 /* "Header Functional Descriptor" from CDC spec  5.2.3.1 */
 struct usb_cdc_header_desc {
@@ -203,6 +204,17 @@
 	__u8	bmNetworkCapabilities;
 } __packed;
 
+/* "Extended MBIM Functional Descriptor" */
+struct usb_cdc_ext_mbb_desc {
+	__u8	bLength;
+	__u8	bDescriptorType;
+	__u8	bDescriptorSubType;
+
+	__le16	bcdMbbExtendedVersion;
+	__u8	bMaxOutstandingCmdMsges;
+	__le16	wMTU;
+} __packed;
+
 /*-------------------------------------------------------------------------*/
 
 /*
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index 268aa48..4fb20f6 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -349,9 +349,8 @@
 	/* to log submission/completion events*/
 	void	(*log_urb)(struct urb *urb, char *event, unsigned extra);
 	void	(*dump_regs)(struct usb_hcd *);
-	void	(*enable_ulpi_control)(struct usb_hcd *hcd, u32 linestate);
-	void	(*disable_ulpi_control)(struct usb_hcd *hcd);
 	void	(*set_autosuspend_delay)(struct usb_device *);
+	void	(*reset_sof_bug_handler)(struct usb_hcd *hcd, u32 val);
 };
 
 extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb);
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index bcbdec4..e249953 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Author: Brian Swetland <swetland@google.com>
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -304,6 +304,7 @@
 	struct msm_otg_platform_data *pdata;
 	int irq;
 	int async_irq;
+	struct clk *xo_clk;
 	struct clk *clk;
 	struct clk *pclk;
 	struct clk *phy_reset_clk;
@@ -340,7 +341,7 @@
 	struct delayed_work suspend_work;
 	enum usb_chg_state chg_state;
 	enum usb_chg_type chg_type;
-	u8 dcd_retries;
+	unsigned dcd_time;
 	struct wake_lock wlock;
 	struct notifier_block usbdev_nb;
 	unsigned mA_port;
@@ -412,6 +413,7 @@
 	unsigned int power_budget;
 	int pmic_gpio_dp_irq;
 	unsigned int dock_connect_irq;
+	bool use_sec_phy;
 };
 
 /**
@@ -456,6 +458,13 @@
 	u32 desc_fifo_size;
 };
 
+enum usb_bam {
+	SSUSB_BAM = 0,
+	HSUSB_BAM,
+	HSIC_BAM,
+	MAX_BAMS,
+};
+
 /**
  * struct msm_usb_bam_platform_data: pipe connection information
  * between USB/HSIC BAM and another BAM. USB/HSIC BAM can be
@@ -466,6 +475,7 @@
  * @active_conn_num: number of active pipe connections.
  * @usb_base_address: BAM physical address.
  * @ignore_core_reset_ack: BAM can ignore ACK from USB core during PIPE RESET
+ * @disable_clk_gating: Disable clock gating
  */
 struct msm_usb_bam_platform_data {
 	struct usb_bam_pipe_connect *connections;
@@ -474,13 +484,8 @@
 	u32 total_bam_num;
 	u32 usb_base_address;
 	bool ignore_core_reset_ack;
-};
-
-enum usb_bam {
-	SSUSB_BAM = 0,
-	HSUSB_BAM,
-	HSIC_BAM,
-	MAX_BAMS,
+	bool reset_on_connect[MAX_BAMS];
+	bool disable_clk_gating;
 };
 
 /**
@@ -504,14 +509,24 @@
 	void *ctxt;
 };
 
+#ifdef CONFIG_USB_CI13XXX_MSM
+void msm_hw_bam_disable(bool bam_disable);
+
+#else
+static inline void msm_hw_bam_disable(bool bam_disable)
+{
+}
+#endif
+
 #ifdef CONFIG_USB_DWC3_MSM
 int msm_ep_config(struct usb_ep *ep);
 int msm_ep_unconfig(struct usb_ep *ep);
 int msm_data_fifo_config(struct usb_ep *ep, u32 addr, u32 size,
 	u8 dst_pipe_idx);
 
-int msm_register_usb_ext_notification(struct usb_ext_notification *info);
+void msm_dwc3_restart_usb_session(void);
 
+int msm_register_usb_ext_notification(struct usb_ext_notification *info);
 #else
 static inline int msm_data_fifo_config(struct usb_ep *ep, u32 addr, u32 size,
 	u8 dst_pipe_idx)
@@ -529,6 +544,11 @@
 	return -ENODEV;
 }
 
+static inline void msm_dwc3_restart_usb_session(void)
+{
+	return;
+}
+
 static inline int msm_register_usb_ext_notification(
 					struct usb_ext_notification *info)
 {
diff --git a/include/linux/usb/msm_hsusb_hw.h b/include/linux/usb/msm_hsusb_hw.h
index c8c2ed1..900fc00 100644
--- a/include/linux/usb/msm_hsusb_hw.h
+++ b/include/linux/usb/msm_hsusb_hw.h
@@ -18,6 +18,7 @@
 
 #define USB_AHBBURST         (MSM_USB_BASE + 0x0090)
 #define USB_AHBMODE          (MSM_USB_BASE + 0x0098)
+#define USB_GENCONFIG        (MSM_USB_BASE + 0x009C)
 #define USB_CAPLENGTH        (MSM_USB_BASE + 0x0100) /* 8 bit */
 #define USB_HS_GPTIMER_BASE  (MSM_USB_BASE + 0x80)
 
@@ -27,6 +28,7 @@
 #define USB_OTGSC            (MSM_USB_BASE + 0x01A4)
 #define USB_USBMODE          (MSM_USB_BASE + 0x01A8)
 #define USB_PHY_CTRL         (MSM_USB_BASE + 0x0240)
+#define USB_PHY_CTRL2        (MSM_USB_BASE + 0x0278)
 
 #define USBCMD_RESET   2
 #define USB_USBINTR          (MSM_USB_BASE + 0x0148)
@@ -49,6 +51,8 @@
 #define ULPI_DATA(n)          ((n) & 255)
 #define ULPI_DATA_READ(n)     (((n) >> 8) & 255)
 
+#define GENCONFIG_BAM_DISABLE (1 << 13)
+
 /* synopsys 28nm phy registers */
 #define ULPI_PWR_CLK_MNG_REG	0x88
 #define OTG_COMP_DISABLE	BIT(0)
diff --git a/include/linux/usb/rmnet_ctrl_qti.h b/include/linux/usb/rmnet_ctrl_qti.h
new file mode 100644
index 0000000..5038396
--- /dev/null
+++ b/include/linux/usb/rmnet_ctrl_qti.h
@@ -0,0 +1,12 @@
+#ifndef __LINUX_USB_U_RMNET_CTRL_QTI_H
+#define __LINUX_USB_U_RMNET_CTRL_QTI_H
+
+#include <linux/ioctl.h>
+
+#define MAX_QTI_PKT_SIZE 2048
+
+#define FRMNET_CTRL_IOCTL_MAGIC	'r'
+#define FRMNET_CTRL_GET_LINE_STATE	_IOR(FRMNET_CTRL_IOCTL_MAGIC, 2, int)
+
+
+#endif /* __LINUX_USB_U_RMNET_CTRL_QTI_H */
diff --git a/include/linux/usb/usb_qdss.h b/include/linux/usb/usb_qdss.h
index 94a2c37..662d992 100644
--- a/include/linux/usb/usb_qdss.h
+++ b/include/linux/usb/usb_qdss.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/include/linux/vcm.h b/include/linux/vcm.h
index 776b8b2..3ea8c88 100644
--- a/include/linux/vcm.h
+++ b/include/linux/vcm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/vcm_alloc.h b/include/linux/vcm_alloc.h
index f0e4ea4..06d7ee1 100644
--- a/include/linux/vcm_alloc.h
+++ b/include/linux/vcm_alloc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/vcm_mm.h b/include/linux/vcm_mm.h
index 4cc5358..b113fc2 100644
--- a/include/linux/vcm_mm.h
+++ b/include/linux/vcm_mm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/vcm_types.h b/include/linux/vcm_types.h
index 7ec20a6..cea1de5 100644
--- a/include/linux/vcm_types.h
+++ b/include/linux/vcm_types.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index bc25e24..2972dc0 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -696,6 +696,9 @@
 #define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE	0x0800
 #define V4L2_BUF_FLAG_NO_CACHE_CLEAN		0x1000
 #define V4L2_BUF_FLAG_EOS		0x2000
+#define V4L2_QCOM_BUF_FLAG_CODECCONFIG  0x4000
+#define V4L2_QCOM_BUF_FLAG_EOSEQ  0x8000
+#define V4L2_QCOM_BUF_TIMESTAMP_INVALID 0x10000
 
 /*
  *	O V E R L A Y   P R E V I E W
@@ -1498,6 +1501,7 @@
 	V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE		= 0,
 	V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB		= 1,
 	V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES	= 2,
+	V4L2_MPEG_VIDEO_MULTI_SLICE_GOB			= 3,
 };
 #define V4L2_CID_MPEG_VIDEO_VBV_SIZE			(V4L2_CID_MPEG_BASE+222)
 #define V4L2_CID_MPEG_VIDEO_DEC_PTS			(V4L2_CID_MPEG_BASE+223)
@@ -1845,7 +1849,8 @@
 	V4L2_CID_MPEG_VIDC_PERF_LEVEL_PERFORMANCE		= 0,
 	V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO			= 1,
 };
-
+#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_GOB		\
+		(V4L2_CID_MPEG_MSM_VIDC_BASE+27)
 /*  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)
@@ -2138,9 +2143,6 @@
 	};
 };
 
-#define V4L2_QCOM_BUF_FLAG_CODECCONFIG	0x4000
-#define V4L2_QCOM_BUF_FLAG_EOSEQ  0x8000
-
 /* Decoder commands */
 #define V4L2_DEC_CMD_START       (0)
 #define V4L2_DEC_CMD_STOP        (1)
diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h
index 65efb92..1d10474 100644
--- a/include/linux/vmstat.h
+++ b/include/linux/vmstat.h
@@ -258,6 +258,13 @@
 
 #endif		/* CONFIG_SMP */
 
+static inline void __mod_zone_freepage_state(struct zone *zone, int nr_pages,
+					     int migratetype)
+{
+	__mod_zone_page_state(zone, NR_FREE_PAGES, nr_pages);
+	if (is_migrate_cma(migratetype))
+		__mod_zone_page_state(zone, NR_FREE_CMA_PAGES, nr_pages);
+}
 extern const char * const vmstat_text[];
 
 #endif /* _LINUX_VMSTAT_H */
diff --git a/include/linux/wcnss_wlan.h b/include/linux/wcnss_wlan.h
index 6d2eee4..2319c48 100644
--- a/include/linux/wcnss_wlan.h
+++ b/include/linux/wcnss_wlan.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
@@ -63,6 +63,9 @@
 void wcnss_reset_intr(void);
 void wcnss_suspend_notify(void);
 void wcnss_resume_notify(void);
+void wcnss_riva_log_debug_regs(void);
+void wcnss_pronto_log_debug_regs(void);
+int wcnss_cold_boot_done(void);
 
 #define wcnss_wlan_get_drvdata(dev) dev_get_drvdata(dev)
 #define wcnss_wlan_set_drvdata(dev, data) dev_set_drvdata((dev), (data))
diff --git a/include/media/Kbuild b/include/media/Kbuild
index fc764eb..16786a9 100644
--- a/include/media/Kbuild
+++ b/include/media/Kbuild
@@ -9,3 +9,9 @@
 header-y += msm_jpeg.h
 header-y += msm_media_info.h
 header-y += msm_vidc.h
+header-y += msmb_camera.h
+header-y += msm_cam_sensor.h
+header-y += msmb_isp.h
+header-y += msmb_ispif.h
+header-y += msmb_generic_buf_mgr.h
+header-y += msmb_pproc.h
diff --git a/include/media/gpio-ir-recv.h b/include/media/gpio-ir-recv.h
index ffdf2f0..63f40f7 100644
--- a/include/media/gpio-ir-recv.h
+++ b/include/media/gpio-ir-recv.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/include/media/msm/vcd_api.h b/include/media/msm/vcd_api.h
index 7104028..944446f 100644
--- a/include/media/msm/vcd_api.h
+++ b/include/media/msm/vcd_api.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -100,6 +100,7 @@
 	size_t sz;
 	u32 align;
 	u32 buf_pool_id;
+	size_t meta_buffer_size;
 };
 
 struct vcd_init_config {
diff --git a/include/media/msm/vcd_property.h b/include/media/msm/vcd_property.h
index 2ce1a88..5fcb049 100644
--- a/include/media/msm/vcd_property.h
+++ b/include/media/msm/vcd_property.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -58,7 +58,14 @@
 #define VCD_I_ENABLE_DELIMITER_FLAG (VCD_START_BASE + 0x2A)
 #define VCD_I_ENABLE_VUI_TIMING_INFO (VCD_START_BASE + 0x2B)
 #define VCD_I_H263_PLUSPTYPE (VCD_START_BASE + 0x2C)
-
+#define VCD_I_LTR_MODE (VCD_START_BASE + 0x2D)
+#define VCD_I_LTR_COUNT (VCD_START_BASE + 0x2E)
+#define VCD_I_LTR_PERIOD (VCD_START_BASE + 0x2F)
+#define VCD_I_LTR_USE (VCD_START_BASE + 0x30)
+#define VCD_I_CAPABILITY_LTR_COUNT (VCD_START_BASE + 0x31)
+#define VCD_I_LTR_MARK (VCD_START_BASE + 0x32)
+#define VCD_I_SET_EXT_METABUFFER (VCD_START_BASE + 0x33)
+#define VCD_I_FREE_EXT_METABUFFER (VCD_START_BASE + 0x34)
 
 #define VCD_START_REQ      (VCD_START_BASE + 0x1000)
 #define VCD_I_REQ_IFRAME   (VCD_START_REQ + 0x1)
@@ -116,9 +123,12 @@
 #define VCD_METADATA_VC1            0x040
 #define VCD_METADATA_PASSTHROUGH    0x080
 #define VCD_METADATA_ENC_SLICE      0x100
+#define VCD_METADATA_LTR_INFO       0x200
 
 #define VCD_METADATA_EXT_DATA       0x0800
 #define VCD_METADATA_USER_DATA      0x1000
+#define VCD_METADATA_SEPARATE_BUF   0x2000
+
 
 struct vcd_property_meta_data_enable {
 	u32 meta_data_enable_flag;
@@ -389,4 +399,49 @@
 	u32 vui_timing_info;
 };
 
+struct vcd_property_range_type {
+	u32 min;
+	u32 max;
+	u32 step_size;
+};
+
+enum vcd_property_ltrmode {
+	VCD_LTR_MODE_DISABLE = 0,
+	VCD_LTR_MODE_MANUAL  = 1,
+	VCD_LTR_MODE_AUTO    = 2,
+	VCD_LTR_MODE_MAX     = 0x7fffffff
+};
+
+struct vcd_property_ltrmode_type {
+	enum vcd_property_ltrmode ltr_mode;
+};
+
+struct vcd_property_ltrcount_type {
+	u32 ltr_count;
+};
+
+struct vcd_property_ltrperiod_type {
+	u32 ltr_period;
+};
+
+struct vcd_property_ltruse_type {
+	u32 ltr_id;
+	u32 ltr_frames;
+};
+
+struct vcd_property_meta_buffer {
+	u8 *kernel_virtual_addr;
+	u8 *physical_addr;
+	u32 size;
+	u32 count;
+	int pmem_fd;
+	u32 offset;
+	u8 *dev_addr;
+	void *client_data;
+	u8 *kernel_virt_addr_iommu;
+	u8 *physical_addr_iommu;
+	int pmem_fd_iommu;
+	u8 *dev_addr_iommu;
+	void *client_data_iommu;
+};
 #endif
diff --git a/include/media/msm/vcd_status.h b/include/media/msm/vcd_status.h
index 7e8ec0b..7419b23 100644
--- a/include/media/msm/vcd_status.h
+++ b/include/media/msm/vcd_status.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -33,6 +33,7 @@
 #define VCD_EVT_IND_RESOURCES_LOST        (VCD_EVT_IND_BASE + 0x4)
 #define VCD_EVT_IND_INFO_OUTPUT_RECONFIG  (VCD_EVT_IND_BASE + 0x5)
 #define VCD_EVT_IND_INFO_FIELD_DROPPED    (VCD_EVT_IND_BASE + 0x6)
+#define VCD_EVT_IND_INFO_LTRUSE_FAILED    (VCD_EVT_IND_BASE + 0x7)
 
 #define VCD_S_SUCCESS           0x0
 
diff --git a/include/media/msm/vidc_init.h b/include/media/msm/vidc_init.h
index f7d4e58..bcc0370 100644
--- a/include/media/msm/vidc_init.h
+++ b/include/media/msm/vidc_init.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -19,6 +19,7 @@
 
 #define VIDC_MAX_NUM_CLIENTS 4
 #define MAX_VIDEO_NUM_OF_BUFF 100
+#define MAX_META_BUFFERS 32
 
 enum buffer_dir {
 	BUFFER_TYPE_INPUT,
@@ -37,6 +38,11 @@
 	void *client_data;
 };
 
+struct meta_buffer_addr_table {
+	u8 *kernel_vir_addr;
+	u8 *kernel_vir_addr_iommu;
+};
+
 struct video_client_ctx {
 	void *vcd_handle;
 	u32 num_of_input_buffers;
@@ -49,17 +55,22 @@
 	wait_queue_head_t msg_wait;
 	struct completion event;
 	struct vcd_property_h264_mv_buffer vcd_h264_mv_buffer;
+	struct vcd_property_meta_buffer vcd_meta_buffer;
 	struct vcd_property_enc_recon_buffer recon_buffer[4];
 	u32 event_status;
 	u32 seq_header_set;
 	u32 stop_msg;
 	u32 stop_called;
 	u32 stop_sync_cb;
+	size_t meta_buf_size;
 	struct ion_client *user_ion_client;
 	struct ion_handle *seq_hdr_ion_handle;
 	struct ion_handle *h264_mv_ion_handle;
 	struct ion_handle *recon_buffer_ion_handle[4];
+	struct ion_handle *meta_buffer_ion_handle;
+	struct ion_handle *meta_buffer_iommu_ion_handle;
 	u32 dmx_disable;
+	struct meta_buffer_addr_table meta_addr_table[MAX_META_BUFFERS];
 };
 
 void __iomem *vidc_get_ioaddr(void);
diff --git a/include/media/msm/vidc_type.h b/include/media/msm/vidc_type.h
index d4db0a0..77bae5a 100644
--- a/include/media/msm/vidc_type.h
+++ b/include/media/msm/vidc_type.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -23,8 +23,9 @@
 #include <linux/dma-mapping.h>
 #include <linux/android_pmem.h>
 
-#define DEBUG   0
+#define DDL_MSG_LOG 0
+#define DEBUG 0
 #define VIDC_ENABLE_DBGFS
-
 #define USE_RES_TRACKER
+
 #endif
diff --git a/include/media/msm_cam_sensor.h b/include/media/msm_cam_sensor.h
new file mode 100644
index 0000000..4e1fb31
--- /dev/null
+++ b/include/media/msm_cam_sensor.h
@@ -0,0 +1,461 @@
+#ifndef __LINUX_MSM_CAM_SENSOR_H
+#define __LINUX_MSM_CAM_SENSOR_H
+
+#ifdef MSM_CAMERA_BIONIC
+#include <sys/types.h>
+#endif
+#include <linux/types.h>
+#include <linux/v4l2-mediabus.h>
+#include <linux/i2c.h>
+
+#define I2C_SEQ_REG_SETTING_MAX   5
+#define I2C_SEQ_REG_DATA_MAX      20
+#define MAX_CID                   16
+
+#define MSM_SENSOR_MCLK_8HZ   8000000
+#define MSM_SENSOR_MCLK_16HZ  16000000
+#define MSM_SENSOR_MCLK_24HZ  24000000
+
+#define GPIO_OUT_LOW          (0 << 1)
+#define GPIO_OUT_HIGH         (1 << 1)
+
+#define CSI_EMBED_DATA        0x12
+#define CSI_RESERVED_DATA_0   0x13
+#define CSI_YUV422_8          0x1E
+#define CSI_RAW8              0x2A
+#define CSI_RAW10             0x2B
+#define CSI_RAW12             0x2C
+
+#define CSI_DECODE_6BIT         0
+#define CSI_DECODE_8BIT         1
+#define CSI_DECODE_10BIT        2
+#define CSI_DECODE_DPCM_10_8_10 5
+
+#define MAX_SENSOR_NAME 32
+
+#define MAX_ACT_MOD_NAME_SIZE 32
+#define MAX_ACT_NAME_SIZE 32
+#define NUM_ACTUATOR_DIR 2
+#define MAX_ACTUATOR_SCENARIO 8
+#define MAX_ACTUATOR_REGION 5
+#define MAX_ACTUATOR_INIT_SET 12
+#define MAX_ACTUATOR_REG_TBL_SIZE 8
+
+#define MOVE_NEAR 0
+#define MOVE_FAR  1
+
+enum msm_camera_i2c_reg_addr_type {
+	MSM_CAMERA_I2C_BYTE_ADDR = 1,
+	MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+enum msm_camera_i2c_data_type {
+	MSM_CAMERA_I2C_BYTE_DATA = 1,
+	MSM_CAMERA_I2C_WORD_DATA,
+	MSM_CAMERA_I2C_SET_BYTE_MASK,
+	MSM_CAMERA_I2C_UNSET_BYTE_MASK,
+	MSM_CAMERA_I2C_SET_WORD_MASK,
+	MSM_CAMERA_I2C_UNSET_WORD_MASK,
+	MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA,
+};
+
+enum msm_sensor_power_seq_type_t {
+	SENSOR_CLK,
+	SENSOR_GPIO,
+	SENSOR_VREG,
+	SENSOR_I2C_MUX,
+};
+
+enum msm_sensor_clk_type_t {
+	SENSOR_CAM_MCLK,
+	SENSOR_CAM_CLK,
+	SENSOR_CAM_CLK_MAX,
+};
+
+enum msm_sensor_power_seq_gpio_t {
+	SENSOR_GPIO_RESET,
+	SENSOR_GPIO_STANDBY,
+	SENSOR_GPIO_MAX,
+};
+
+enum msm_camera_vreg_name_t {
+	CAM_VDIG,
+	CAM_VIO,
+	CAM_VANA,
+	CAM_VAF,
+	CAM_VREG_MAX,
+};
+
+enum msm_sensor_resolution_t {
+	MSM_SENSOR_RES_FULL,
+	MSM_SENSOR_RES_QTR,
+	MSM_SENSOR_RES_2,
+	MSM_SENSOR_RES_3,
+	MSM_SENSOR_RES_4,
+	MSM_SENSOR_RES_5,
+	MSM_SENSOR_RES_6,
+	MSM_SENSOR_RES_7,
+	MSM_SENSOR_INVALID_RES,
+};
+
+enum sensor_sub_module_t {
+	SUB_MODULE_SENSOR,
+	SUB_MODULE_CHROMATIX,
+	SUB_MODULE_ACTUATOR,
+	SUB_MODULE_EEPROM,
+	SUB_MODULE_LED_FLASH,
+	SUB_MODULE_STROBE_FLASH,
+	SUB_MODULE_CSIPHY,
+	SUB_MODULE_CSIPHY_3D,
+	SUB_MODULE_CSID,
+	SUB_MODULE_CSID_3D,
+	SUB_MODULE_MAX,
+};
+
+enum csid_cfg_type_t {
+	CSID_INIT,
+	CSID_CFG,
+	CSID_RELEASE,
+};
+
+enum csiphy_cfg_type_t {
+	CSIPHY_INIT,
+	CSIPHY_CFG,
+	CSIPHY_RELEASE,
+};
+
+enum camera_vreg_type {
+	REG_LDO,
+	REG_VS,
+	REG_GPIO,
+};
+
+struct msm_sensor_power_setting {
+	enum msm_sensor_power_seq_type_t seq_type;
+	uint16_t seq_val;
+	long config_val;
+	uint16_t delay;
+	void *data[10];
+};
+
+struct msm_sensor_power_setting_array {
+	struct msm_sensor_power_setting *power_setting;
+	uint16_t size;
+};
+
+struct msm_sensor_id_info_t {
+	uint16_t sensor_id_reg_addr;
+	uint16_t sensor_id;
+};
+
+struct msm_camera_sensor_slave_info {
+	uint16_t slave_addr;
+	enum msm_camera_i2c_reg_addr_type addr_type;
+	struct msm_sensor_id_info_t sensor_id_info;
+	struct msm_sensor_power_setting_array power_setting_array;
+};
+
+struct msm_camera_i2c_reg_array {
+	uint16_t reg_addr;
+	uint16_t reg_data;
+};
+
+struct msm_camera_i2c_reg_setting {
+	struct msm_camera_i2c_reg_array *reg_setting;
+	uint16_t size;
+	enum msm_camera_i2c_reg_addr_type addr_type;
+	enum msm_camera_i2c_data_type data_type;
+	uint16_t delay;
+};
+
+struct msm_camera_i2c_seq_reg_array {
+	uint16_t reg_addr;
+	uint8_t reg_data[I2C_SEQ_REG_DATA_MAX];
+	uint16_t reg_data_size;
+};
+
+struct msm_camera_i2c_seq_reg_setting {
+	struct msm_camera_i2c_seq_reg_array *reg_setting;
+	uint16_t size;
+	enum msm_camera_i2c_reg_addr_type addr_type;
+	uint16_t delay;
+};
+
+struct msm_camera_csid_vc_cfg {
+	uint8_t cid;
+	uint8_t dt;
+	uint8_t decode_format;
+};
+
+struct msm_camera_csid_lut_params {
+	uint8_t num_cid;
+	struct msm_camera_csid_vc_cfg *vc_cfg[MAX_CID];
+};
+
+struct msm_camera_csid_params {
+	uint8_t lane_cnt;
+	uint16_t lane_assign;
+	uint8_t phy_sel;
+	struct msm_camera_csid_lut_params lut_params;
+};
+
+struct msm_camera_csiphy_params {
+	uint8_t lane_cnt;
+	uint8_t settle_cnt;
+	uint16_t lane_mask;
+	uint8_t combo_mode;
+};
+
+struct msm_camera_csi2_params {
+	struct msm_camera_csid_params csid_params;
+	struct msm_camera_csiphy_params csiphy_params;
+};
+
+struct msm_camera_csi_lane_params {
+	uint16_t csi_lane_assign;
+	uint16_t csi_lane_mask;
+};
+
+struct csi_lane_params_t {
+	uint16_t csi_lane_assign;
+	uint8_t csi_lane_mask;
+	uint8_t csi_if;
+	uint8_t csid_core[2];
+	uint8_t csi_phy_sel;
+};
+
+struct msm_sensor_info_t {
+	char sensor_name[MAX_SENSOR_NAME];
+	int32_t    session_id;
+	int32_t     subdev_id[SUB_MODULE_MAX];
+};
+
+struct camera_vreg_t {
+	const char *reg_name;
+	enum camera_vreg_type type;
+	int min_voltage;
+	int max_voltage;
+	int op_mode;
+	uint32_t delay;
+};
+
+enum camb_position_t {
+	BACK_CAMERA_B,
+	FRONT_CAMERA_B,
+};
+
+enum camerab_mode_t {
+	CAMERA_MODE_2D_B = (1<<0),
+	CAMERA_MODE_3D_B = (1<<1)
+};
+
+struct msm_sensor_init_params {
+	/* mask of modes supported: 2D, 3D */
+	int                 modes_supported;
+	/* sensor position: front, back */
+	enum camb_position_t position;
+	/* sensor mount angle */
+	uint32_t            sensor_mount_angle;
+};
+
+struct sensorb_cfg_data {
+	int cfgtype;
+	union {
+		struct msm_sensor_info_t      sensor_info;
+		struct msm_sensor_init_params sensor_init_params;
+		void                         *setting;
+	} cfg;
+};
+
+struct csid_cfg_data {
+	enum csid_cfg_type_t cfgtype;
+	union {
+		uint32_t csid_version;
+		struct msm_camera_csid_params *csid_params;
+	} cfg;
+};
+
+struct csiphy_cfg_data {
+	enum csiphy_cfg_type_t cfgtype;
+	union {
+		struct msm_camera_csiphy_params *csiphy_params;
+		struct msm_camera_csi_lane_params *csi_lane_params;
+	} cfg;
+};
+
+enum msm_sensor_cfg_type_t {
+	CFG_SET_SLAVE_INFO,
+	CFG_WRITE_I2C_ARRAY,
+	CFG_WRITE_I2C_SEQ_ARRAY,
+	CFG_POWER_UP,
+	CFG_POWER_DOWN,
+	CFG_SET_STOP_STREAM_SETTING,
+	CFG_GET_SENSOR_INFO,
+	CFG_GET_SENSOR_INIT_PARAMS,
+	CFG_SET_INIT_SETTING,
+	CFG_SET_RESOLUTION,
+	CFG_SET_STOP_STREAM,
+	CFG_SET_START_STREAM,
+};
+
+enum msm_actuator_cfg_type_t {
+	CFG_GET_ACTUATOR_INFO,
+	CFG_SET_ACTUATOR_INFO,
+	CFG_SET_DEFAULT_FOCUS,
+	CFG_MOVE_FOCUS,
+};
+
+enum actuator_type {
+	ACTUATOR_VCM,
+	ACTUATOR_PIEZO,
+};
+
+enum msm_actuator_data_type {
+	MSM_ACTUATOR_BYTE_DATA = 1,
+	MSM_ACTUATOR_WORD_DATA,
+};
+
+enum msm_actuator_addr_type {
+	MSM_ACTUATOR_BYTE_ADDR = 1,
+	MSM_ACTUATOR_WORD_ADDR,
+};
+
+struct reg_settings_t {
+	uint16_t reg_addr;
+	uint16_t reg_data;
+};
+
+struct region_params_t {
+	/* [0] = ForwardDirection Macro boundary
+	   [1] = ReverseDirection Inf boundary
+        */
+	uint16_t step_bound[2];
+	uint16_t code_per_step;
+};
+
+struct damping_params_t {
+	uint32_t damping_step;
+	uint32_t damping_delay;
+	uint32_t hw_params;
+};
+
+struct msm_actuator_move_params_t {
+	int8_t dir;
+	int8_t sign_dir;
+	int16_t dest_step_pos;
+	int32_t num_steps;
+	struct damping_params_t *ringing_params;
+};
+
+struct msm_actuator_tuning_params_t {
+	int16_t initial_code;
+	uint16_t pwd_step;
+	uint16_t region_size;
+	uint32_t total_steps;
+	struct region_params_t *region_params;
+};
+
+struct msm_actuator_params_t {
+	enum actuator_type act_type;
+	uint8_t reg_tbl_size;
+	uint16_t data_size;
+	uint16_t init_setting_size;
+	uint32_t i2c_addr;
+	enum msm_actuator_addr_type i2c_addr_type;
+	enum msm_actuator_data_type i2c_data_type;
+	struct msm_actuator_reg_params_t *reg_tbl_params;
+	struct reg_settings_t *init_settings;
+};
+
+struct msm_actuator_set_info_t {
+	struct msm_actuator_params_t actuator_params;
+	struct msm_actuator_tuning_params_t af_tuning_params;
+};
+
+struct msm_actuator_get_info_t {
+	uint32_t focal_length_num;
+	uint32_t focal_length_den;
+	uint32_t f_number_num;
+	uint32_t f_number_den;
+	uint32_t f_pix_num;
+	uint32_t f_pix_den;
+	uint32_t total_f_dist_num;
+	uint32_t total_f_dist_den;
+	uint32_t hor_view_angle_num;
+	uint32_t hor_view_angle_den;
+	uint32_t ver_view_angle_num;
+	uint32_t ver_view_angle_den;
+};
+
+enum af_camera_name {
+	ACTUATOR_MAIN_CAM_0,
+	ACTUATOR_MAIN_CAM_1,
+	ACTUATOR_MAIN_CAM_2,
+	ACTUATOR_MAIN_CAM_3,
+	ACTUATOR_MAIN_CAM_4,
+	ACTUATOR_MAIN_CAM_5,
+	ACTUATOR_WEB_CAM_0,
+	ACTUATOR_WEB_CAM_1,
+	ACTUATOR_WEB_CAM_2,
+};
+
+struct msm_actuator_cfg_data {
+	int cfgtype;
+	uint8_t is_af_supported;
+	union {
+		struct msm_actuator_move_params_t move;
+		struct msm_actuator_set_info_t set_info;
+		struct msm_actuator_get_info_t get_info;
+		enum af_camera_name cam_name;
+	} cfg;
+};
+
+enum msm_actuator_write_type {
+	MSM_ACTUATOR_WRITE_HW_DAMP,
+	MSM_ACTUATOR_WRITE_DAC,
+};
+
+struct msm_actuator_reg_params_t {
+	enum msm_actuator_write_type reg_write_type;
+	uint32_t hw_mask;
+	uint16_t reg_addr;
+	uint16_t hw_shift;
+	uint16_t data_shift;
+};
+
+enum msm_camera_led_config_t {
+	MSM_CAMERA_LED_OFF,
+	MSM_CAMERA_LED_LOW,
+	MSM_CAMERA_LED_HIGH,
+	MSM_CAMERA_LED_INIT,
+	MSM_CAMERA_LED_RELEASE,
+};
+
+struct msm_camera_led_cfg_t {
+	enum msm_camera_led_config_t cfgtype;
+};
+
+#define VIDIOC_MSM_SENSOR_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct sensorb_cfg_data)
+
+#define VIDIOC_MSM_SENSOR_RELEASE \
+	_IO('V', BASE_VIDIOC_PRIVATE + 2)
+
+#define VIDIOC_MSM_SENSOR_GET_SUBDEV_ID \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 3, uint32_t)
+
+#define VIDIOC_MSM_CSIPHY_IO_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 4, struct csid_cfg_data)
+
+#define VIDIOC_MSM_CSID_IO_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 5, struct csiphy_cfg_data)
+
+#define VIDIOC_MSM_ACTUATOR_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 6, struct msm_actuator_cfg_data)
+
+#define VIDIOC_MSM_FLASH_LED_DATA_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 7, struct msm_camera_led_cfg_t)
+
+#define MSM_V4L2_PIX_FMT_META v4l2_fourcc('M', 'E', 'T', 'A') /* META */
+
+#endif /* __LINUX_MSM_CAM_SENSOR_H */
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 971c9b3..9c310a9 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2009-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
@@ -1595,6 +1595,19 @@
 	REG_GPIO,
 };
 
+enum msm_camera_vreg_name_t {
+	CAM_VDIG,
+	CAM_VIO,
+	CAM_VANA,
+	CAM_VAF,
+	CAM_VREG_MAX,
+};
+
+struct msm_camera_csi_lane_params {
+	uint16_t csi_lane_assign;
+	uint16_t csi_lane_mask;
+};
+
 struct camera_vreg_t {
 	const char *reg_name;
 	enum camera_vreg_type type;
diff --git a/include/media/msm_gestures.h b/include/media/msm_gestures.h
index c9af034..a6efd4f 100644
--- a/include/media/msm_gestures.h
+++ b/include/media/msm_gestures.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/include/media/msm_isp.h b/include/media/msm_isp.h
index 8b4ae19..77455ca 100644
--- a/include/media/msm_isp.h
+++ b/include/media/msm_isp.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/include/media/msm_media_info.h b/include/media/msm_media_info.h
index ab76d79..993a4ab 100644
--- a/include/media/msm_media_info.h
+++ b/include/media/msm_media_info.h
@@ -1,8 +1,8 @@
 #ifndef __MEDIA_INFO_H__
 #define __MEDIA_INFO_H__
 
-#ifndef ALIGN
-#define ALIGN(__sz, __align) (((__sz) + (__align-1)) & (~(__align-1)))
+#ifndef MSM_MEDIA_ALIGN
+#define MSM_MEDIA_ALIGN(__sz, __align) (((__sz) + (__align-1)) & (~(__align-1)))
 #endif
 
 enum color_fmts {
@@ -18,7 +18,7 @@
 	switch (color_fmt) {
 	case COLOR_FMT_NV12:
 		alignment = 128;
-		stride = ALIGN(width, alignment);
+		stride = MSM_MEDIA_ALIGN(width, alignment);
 		break;
 	default:
 		break;
@@ -36,7 +36,7 @@
 	switch (color_fmt) {
 	case COLOR_FMT_NV12:
 		alignment = 128;
-		stride = ALIGN(width, alignment);
+		stride = MSM_MEDIA_ALIGN(width, alignment);
 		break;
 	default:
 		break;
@@ -54,7 +54,7 @@
 	switch (color_fmt) {
 	case COLOR_FMT_NV12:
 		alignment = 32;
-		sclines = ALIGN(height, alignment);
+		sclines = MSM_MEDIA_ALIGN(height, alignment);
 		break;
 	default:
 		break;
@@ -72,7 +72,7 @@
 	switch (color_fmt) {
 	case COLOR_FMT_NV12:
 		alignment = 16;
-		sclines = ALIGN(((height + 1) >> 1), alignment);
+		sclines = MSM_MEDIA_ALIGN(((height + 1) >> 1), alignment);
 		break;
 	default:
 		break;
@@ -101,7 +101,7 @@
 		y_plane = y_stride * y_sclines;
 		uv_plane = uv_stride * uv_sclines + uv_alignment;
 		size = y_plane + uv_plane;
-		size = ALIGN(size, 4096);
+		size = MSM_MEDIA_ALIGN(size, 4096);
 		break;
 	default:
 		break;
diff --git a/include/media/msm_vidc.h b/include/media/msm_vidc.h
index 4261d34..fae1efa 100644
--- a/include/media/msm_vidc.h
+++ b/include/media/msm_vidc.h
@@ -67,8 +67,8 @@
 	unsigned int frame_rate;
 };
 struct msm_vidc_ts_payload {
-	unsigned int timestamp_hi;
 	unsigned int timestamp_lo;
+	unsigned int timestamp_hi;
 };
 struct msm_vidc_concealmb_payload {
 	unsigned int num_mbs;
@@ -76,6 +76,15 @@
 struct msm_vidc_recoverysei_payload {
 	unsigned int flags;
 };
+
+struct msm_vidc_aspect_ratio_payload {
+	unsigned int size;
+	unsigned int version;
+	unsigned int port_index;
+	unsigned int aspect_width;
+	unsigned int aspect_height;
+};
+
 struct msm_vidc_panscan_window {
 	unsigned int panscan_height_offset;
 	unsigned int panscan_width_offset;
@@ -100,6 +109,7 @@
 	EXTRADATA_MULTISLICE_INFO = 0x7F100000,
 	EXTRADATA_NUM_CONCEALED_MB = 0x7F100001,
 	EXTRADATA_INDEX = 0x7F100002,
+	EXTRADATA_ASPECT_RATIO = 0x7F100003,
 	EXTRADATA_METADATA_FILLER = 0x7FE00002,
 };
 enum msm_vidc_interlace_type {
diff --git a/include/media/msmb_camera.h b/include/media/msmb_camera.h
new file mode 100644
index 0000000..123c86c
--- /dev/null
+++ b/include/media/msmb_camera.h
@@ -0,0 +1,160 @@
+#ifndef __LINUX_MSMB_CAMERA_H
+#define __LINUX_MSMB_CAMERA_H
+
+#include <linux/videodev2.h>
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define MSM_CAM_V4L2_IOCTL_NOTIFY \
+	_IOW('V', BASE_VIDIOC_PRIVATE + 30, struct v4l2_event)
+
+#define MSM_CAM_V4L2_IOCTL_NOTIFY_META \
+	_IOW('V', BASE_VIDIOC_PRIVATE + 31, struct v4l2_event)
+
+#define MSM_CAM_V4L2_IOCTL_CMD_ACK \
+	_IOW('V', BASE_VIDIOC_PRIVATE + 32, struct v4l2_event)
+
+#define QCAMERA_DEVICE_GROUP_ID	1
+#define QCAMERA_VNODE_GROUP_ID	2
+#define MSM_CAMERA_NAME					"msm_camera"
+#define MSM_CONFIGURATION_NAME	"msm_config"
+
+#define MSM_CAMERA_SUBDEV_CSIPHY       0
+#define MSM_CAMERA_SUBDEV_CSID         1
+#define MSM_CAMERA_SUBDEV_ISPIF        2
+#define MSM_CAMERA_SUBDEV_VFE          3
+#define MSM_CAMERA_SUBDEV_AXI          4
+#define MSM_CAMERA_SUBDEV_VPE          5
+#define MSM_CAMERA_SUBDEV_SENSOR       6
+#define MSM_CAMERA_SUBDEV_ACTUATOR     7
+#define MSM_CAMERA_SUBDEV_EEPROM       8
+#define MSM_CAMERA_SUBDEV_CPP          9
+#define MSM_CAMERA_SUBDEV_CCI          10
+#define MSM_CAMERA_SUBDEV_LED_FLASH    11
+#define MSM_CAMERA_SUBDEV_STROBE_FLASH 12
+#define MSM_CAMERA_SUBDEV_BUF_MNGR     13
+
+#define MSM_MAX_CAMERA_SENSORS  5
+
+/* featur base */
+#define MSM_CAMERA_FEATURE_BASE     0x00010000
+#define MSM_CAMERA_FEATURE_SHUTDOWN (MSM_CAMERA_FEATURE_BASE + 1)
+
+#define MSM_CAMERA_STATUS_BASE      0x00020000
+#define MSM_CAMERA_STATUS_FAIL      (MSM_CAMERA_STATUS_BASE + 1)
+#define MSM_CAMERA_STATUS_SUCCESS   (MSM_CAMERA_STATUS_BASE + 2)
+
+/* event type */
+#define MSM_CAMERA_V4L2_EVENT_TYPE (V4L2_EVENT_PRIVATE_START + 0x00002000)
+
+/* event id */
+#define MSM_CAMERA_EVENT_MIN    0
+#define MSM_CAMERA_NEW_SESSION  (MSM_CAMERA_EVENT_MIN + 1)
+#define MSM_CAMERA_DEL_SESSION  (MSM_CAMERA_EVENT_MIN + 2)
+#define MSM_CAMERA_SET_PARM     (MSM_CAMERA_EVENT_MIN + 3)
+#define MSM_CAMERA_GET_PARM     (MSM_CAMERA_EVENT_MIN + 4)
+#define MSM_CAMERA_MAPPING_CFG  (MSM_CAMERA_EVENT_MIN + 5)
+#define MSM_CAMERA_MAPPING_SES  (MSM_CAMERA_EVENT_MIN + 6)
+#define MSM_CAMERA_MSM_NOTIFY   (MSM_CAMERA_EVENT_MIN + 7)
+#define MSM_CAMERA_EVENT_MAX    (MSM_CAMERA_EVENT_MIN + 8)
+
+/* data.command */
+#define MSM_CAMERA_PRIV_S_CROP		 (V4L2_CID_PRIVATE_BASE + 1)
+#define MSM_CAMERA_PRIV_G_CROP		 (V4L2_CID_PRIVATE_BASE + 2)
+#define MSM_CAMERA_PRIV_G_FMT			 (V4L2_CID_PRIVATE_BASE + 3)
+#define MSM_CAMERA_PRIV_S_FMT			 (V4L2_CID_PRIVATE_BASE + 4)
+#define MSM_CAMERA_PRIV_TRY_FMT		 (V4L2_CID_PRIVATE_BASE + 5)
+#define MSM_CAMERA_PRIV_METADATA	 (V4L2_CID_PRIVATE_BASE + 6)
+#define MSM_CAMERA_PRIV_QUERY_CAP  (V4L2_CID_PRIVATE_BASE + 7)
+#define MSM_CAMERA_PRIV_STREAM_ON  (V4L2_CID_PRIVATE_BASE + 8)
+#define MSM_CAMERA_PRIV_STREAM_OFF (V4L2_CID_PRIVATE_BASE + 9)
+#define MSM_CAMERA_PRIV_NEW_STREAM (V4L2_CID_PRIVATE_BASE + 10)
+#define MSM_CAMERA_PRIV_DEL_STREAM (V4L2_CID_PRIVATE_BASE + 11)
+#define MSM_CAMERA_PRIV_SHUTDOWN   (V4L2_CID_PRIVATE_BASE + 12)
+#define MSM_CAMERA_PRIV_STREAM_INFO_SYNC \
+	(V4L2_CID_PRIVATE_BASE + 13)
+
+/* data.status - success */
+#define MSM_CAMERA_CMD_SUCESS      0x00000001
+#define MSM_CAMERA_BUF_MAP_SUCESS  0x00000002
+
+/* data.status - error */
+#define MSM_CAMERA_ERR_EVT_BASE 0x00010000
+#define MSM_CAMERA_ERR_CMD_FAIL (MSM_CAMERA_ERR_EVT_BASE + 1)
+#define MSM_CAMERA_ERR_MAPPING  (MSM_CAMERA_ERR_EVT_BASE + 2)
+
+/* The msm_v4l2_event_data structure should match the
+ * v4l2_event.u.data field.
+ * should not exceed 16 elements */
+struct msm_v4l2_event_data {
+	/*word 0*/
+	unsigned int command;
+	/*word 1*/
+	unsigned int status;
+	/*word 2*/
+	unsigned int session_id;
+	/*word 3*/
+	unsigned int stream_id;
+	/*word 4*/
+	unsigned int map_op;
+	/*word 5*/
+	unsigned int map_buf_idx;
+	/*word 6*/
+	unsigned int notify;
+	/*word 7*/
+	unsigned int nop1;
+	/*word 8*/
+	unsigned int nop2;
+	/*word 9*/
+	unsigned int nop3;
+	/*word 10*/
+	unsigned int nop4;
+	/*word 11*/
+	unsigned int nop5;
+	/*word 12*/
+	unsigned int nop6;
+	/*word 13*/
+	unsigned int nop7;
+	/*word 14*/
+	unsigned int nop8;
+	/*word 15*/
+	unsigned int nop9;
+};
+
+/* map to v4l2_format.fmt.raw_data */
+struct msm_v4l2_format_data {
+	enum v4l2_buf_type type;
+	unsigned int width;
+	unsigned int height;
+	unsigned int pixelformat; /* FOURCC */
+	unsigned char num_planes;
+	unsigned int plane_sizes[VIDEO_MAX_PLANES];
+};
+
+/*  MSM Four-character-code (FOURCC) */
+#define msm_v4l2_fourcc(a, b, c, d)\
+	((__u32)(a) | ((__u32)(b) << 8) | ((__u32)(c) << 16) |\
+	((__u32)(d) << 24))
+
+/* Composite stats */
+#define MSM_V4L2_PIX_FMT_STATS_COMB v4l2_fourcc('S', 'T', 'C', 'M')
+/* AEC stats */
+#define MSM_V4L2_PIX_FMT_STATS_AE   v4l2_fourcc('S', 'T', 'A', 'E')
+/* AF stats */
+#define MSM_V4L2_PIX_FMT_STATS_AF   v4l2_fourcc('S', 'T', 'A', 'F')
+/* AWB stats */
+#define MSM_V4L2_PIX_FMT_STATS_AWB  v4l2_fourcc('S', 'T', 'W', 'B')
+/* IHIST stats */
+#define MSM_V4L2_PIX_FMT_STATS_IHST v4l2_fourcc('I', 'H', 'S', 'T')
+/* Column count stats */
+#define MSM_V4L2_PIX_FMT_STATS_CS   v4l2_fourcc('S', 'T', 'C', 'S')
+/* Row count stats */
+#define MSM_V4L2_PIX_FMT_STATS_RS   v4l2_fourcc('S', 'T', 'R', 'S')
+/* Bayer Grid stats */
+#define MSM_V4L2_PIX_FMT_STATS_BG   v4l2_fourcc('S', 'T', 'B', 'G')
+/* Bayer focus stats */
+#define MSM_V4L2_PIX_FMT_STATS_BF   v4l2_fourcc('S', 'T', 'B', 'F')
+/* Bayer hist stats */
+#define MSM_V4L2_PIX_FMT_STATS_BHST v4l2_fourcc('B', 'H', 'S', 'T')
+
+#endif /* __LINUX_MSMB_CAMERA_H */
diff --git a/include/media/msmb_generic_buf_mgr.h b/include/media/msmb_generic_buf_mgr.h
new file mode 100644
index 0000000..17cb947
--- /dev/null
+++ b/include/media/msmb_generic_buf_mgr.h
@@ -0,0 +1,22 @@
+#ifndef __MEDIA_MSMB_BUF_MNGR_H__
+#define __MEDIA_MSMB_BUF_MNGR_H__
+
+struct msm_buf_mngr_info {
+	uint32_t session_id;
+	uint32_t stream_id;
+	uint32_t frame_id;
+	struct timeval timestamp;
+	uint32_t index;
+};
+
+
+#define VIDIOC_MSM_BUF_MNGR_GET_BUF \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 33, struct msm_buf_mngr_info)
+
+#define VIDIOC_MSM_BUF_MNGR_PUT_BUF \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 34, struct msm_buf_mngr_info)
+
+#define VIDIOC_MSM_BUF_MNGR_BUF_DONE \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 35, struct msm_buf_mngr_info)
+
+#endif
diff --git a/include/media/msmb_isp.h b/include/media/msmb_isp.h
new file mode 100644
index 0000000..34b3139
--- /dev/null
+++ b/include/media/msmb_isp.h
@@ -0,0 +1,411 @@
+#ifndef __MSMB_ISP__
+#define __MSMB_ISP__
+
+#include <linux/videodev2.h>
+
+#define MAX_PLANES_PER_STREAM 3
+#define MAX_NUM_STREAM 7
+
+#define ISP_VERSION_40        40
+#define ISP_VERSION_32        32
+#define ISP_NATIVE_BUF_BIT    0x10000
+#define ISP_STATS_STREAM_BIT  0x80000000
+
+enum ISP_START_PIXEL_PATTERN {
+	ISP_BAYER_RGRGRG,
+	ISP_BAYER_GRGRGR,
+	ISP_BAYER_BGBGBG,
+	ISP_BAYER_GBGBGB,
+	ISP_YUV_YCbYCr,
+	ISP_YUV_YCrYCb,
+	ISP_YUV_CbYCrY,
+	ISP_YUV_CrYCbY,
+	ISP_PIX_PATTERN_MAX
+};
+
+enum msm_vfe_plane_fmt {
+	Y_PLANE,
+	CB_PLANE,
+	CR_PLANE,
+	CRCB_PLANE,
+	CBCR_PLANE,
+	VFE_PLANE_FMT_MAX
+};
+
+enum msm_vfe_input_src {
+	VFE_PIX_0,
+	VFE_RAW_0,
+	VFE_RAW_1,
+	VFE_RAW_2,
+	VFE_SRC_MAX,
+};
+
+enum msm_vfe_axi_stream_src {
+	PIX_ENCODER,
+	PIX_VIEWFINDER,
+	CAMIF_RAW,
+	IDEAL_RAW,
+	RDI_INTF_0,
+	RDI_INTF_1,
+	RDI_INTF_2,
+	VFE_AXI_SRC_MAX
+};
+
+enum msm_vfe_frame_skip_pattern {
+	NO_SKIP,
+	EVERY_2FRAME,
+	EVERY_3FRAME,
+	EVERY_4FRAME,
+	EVERY_5FRAME,
+	EVERY_6FRAME,
+	EVERY_7FRAME,
+	EVERY_8FRAME,
+	EVERY_16FRAME,
+	EVERY_32FRAME,
+	MAX_SKIP,
+};
+
+enum msm_vfe_camif_input {
+	CAMIF_DISABLED,
+	CAMIF_PAD_REG_INPUT,
+	CAMIF_MIDDI_INPUT,
+	CAMIF_MIPI_INPUT,
+};
+
+struct msm_vfe_camif_cfg {
+	uint32_t lines_per_frame;
+	uint32_t pixels_per_line;
+	uint32_t first_pixel;
+	uint32_t last_pixel;
+	uint32_t first_line;
+	uint32_t last_line;
+	uint32_t epoch_line0;
+	uint32_t epoch_line1;
+	enum msm_vfe_camif_input camif_input;
+};
+
+enum msm_vfe_inputmux {
+	CAMIF,
+	TESTGEN,
+	EXTERNAL_READ,
+};
+
+struct msm_vfe_pix_cfg {
+	struct msm_vfe_camif_cfg camif_cfg;
+	enum msm_vfe_inputmux input_mux;
+	enum ISP_START_PIXEL_PATTERN pixel_pattern;
+};
+
+struct msm_vfe_rdi_cfg {
+	uint8_t cid;
+	uint8_t frame_based;
+};
+
+struct msm_vfe_input_cfg {
+	union {
+		struct msm_vfe_pix_cfg pix_cfg;
+		struct msm_vfe_rdi_cfg rdi_cfg;
+	} d;
+	enum msm_vfe_input_src input_src;
+};
+
+struct msm_vfe_axi_plane_cfg {
+	uint32_t output_width; /*Include padding*/
+	uint32_t output_height;
+	uint32_t output_stride;
+	uint32_t output_scan_lines;
+	uint32_t output_plane_format; /*Y/Cb/Cr/CbCr*/
+
+	uint8_t csid_src; /*RDI 0-2*/
+	uint8_t rdi_cid;/*CID 1-16*/
+};
+
+struct msm_vfe_axi_stream_request_cmd {
+	uint32_t session_id;
+	uint32_t stream_id;
+	uint32_t output_format;/*Planar/RAW/Misc*/
+	enum msm_vfe_axi_stream_src stream_src; /*CAMIF/IDEAL/RDIs*/
+	struct msm_vfe_axi_plane_cfg plane_cfg[MAX_PLANES_PER_STREAM];
+
+	uint32_t burst_count;
+	uint32_t hfr_mode;
+	uint8_t frame_base;
+
+	uint32_t init_frame_drop; /*MAX 31 Frames*/
+	enum msm_vfe_frame_skip_pattern frame_skip_pattern;
+	uint8_t buf_divert; /* if TRUE no vb2 buf done. */
+	/*Return values*/
+	uint32_t axi_stream_handle;
+};
+
+struct msm_vfe_axi_stream_release_cmd {
+	uint32_t stream_handle;
+};
+
+enum msm_vfe_axi_stream_cmd {
+	STOP_STREAM,
+	START_STREAM,
+};
+
+struct msm_vfe_axi_stream_cfg_cmd {
+	uint8_t num_streams;
+	uint32_t stream_handle[MAX_NUM_STREAM];
+	enum msm_vfe_axi_stream_cmd cmd;
+};
+
+enum msm_vfe_axi_stream_update_type {
+	ENABLE_STREAM_BUF_DIVERT,
+	DISABLE_STREAM_BUF_DIVERT,
+	UPDATE_STREAM_FRAMEDROP_PATTERN,
+};
+
+struct msm_vfe_axi_stream_update_cmd {
+	uint32_t stream_handle;
+	enum msm_vfe_axi_stream_update_type update_type;
+	enum msm_vfe_frame_skip_pattern skip_pattern;
+};
+
+enum msm_vfe_stats_pipeline_policy {
+	STATS_COMP_ALL,
+	STATS_COMP_NONE,
+	MAX_STATS_POLICY,
+};
+
+enum msm_isp_stats_type {
+	MSM_ISP_STATS_AEC,   /* legacy based AEC */
+	MSM_ISP_STATS_AF,    /* legacy based AF */
+	MSM_ISP_STATS_AWB,   /* legacy based AWB */
+	MSM_ISP_STATS_RS,    /* legacy based RS */
+	MSM_ISP_STATS_CS,    /* legacy based CS */
+	MSM_ISP_STATS_IHIST, /* legacy based HIST */
+	MSM_ISP_STATS_SKIN,  /* legacy based SKIN */
+	MSM_ISP_STATS_BG,    /* Bayer Grids */
+	MSM_ISP_STATS_BF,    /* Bayer Focus */
+	MSM_ISP_STATS_BE,    /* Bayer Exposure*/
+	MSM_ISP_STATS_BHIST, /* Bayer Hist */
+	MSM_ISP_STATS_MAX    /* MAX */
+};
+
+struct msm_vfe_stats_stream_request_cmd {
+	uint32_t session_id;
+	uint32_t stream_id;
+	enum msm_isp_stats_type stats_type;
+	uint32_t framedrop_pattern;
+	uint32_t irq_subsample_pattern;
+	uint32_t stream_handle;
+	uint8_t comp_flag;
+};
+
+struct msm_vfe_stats_stream_release_cmd {
+	uint32_t stream_handle;
+};
+struct msm_vfe_stats_stream_cfg_cmd {
+	uint8_t num_streams;
+	uint32_t stream_handle[MSM_ISP_STATS_MAX];
+	uint8_t enable;
+};
+
+struct msm_vfe_stats_comp_policy_cfg {
+	enum msm_vfe_stats_pipeline_policy stats_pipeline_policy;
+	uint32_t comp_framedrop_pattern;
+	uint32_t comp_irq_subsample_pattern;
+};
+
+enum msm_vfe_reg_cfg_type {
+	VFE_WRITE,
+	VFE_WRITE_MB,
+	VFE_READ,
+	VFE_CFG_MASK,
+	VFE_WRITE_DMI_16BIT,
+	VFE_WRITE_DMI_32BIT,
+	VFE_WRITE_DMI_64BIT,
+	VFE_READ_DMI_16BIT,
+	VFE_READ_DMI_32BIT,
+	VFE_READ_DMI_64BIT,
+};
+
+struct msm_vfe_cfg_cmd2 {
+	uint16_t num_cfg;
+	uint16_t cmd_len;
+	void __user *cfg_data;
+	void __user *cfg_cmd;
+};
+
+struct msm_vfe_reg_rw_info {
+	uint32_t reg_offset;
+	uint32_t cmd_data_offset;
+	uint32_t len;
+};
+
+struct msm_vfe_reg_mask_info {
+	uint32_t reg_offset;
+	uint32_t mask;
+	uint32_t val;
+};
+
+struct msm_vfe_reg_dmi_info {
+	uint32_t hi_tbl_offset; /*Optional*/
+	uint32_t lo_tbl_offset; /*Required*/
+	uint32_t len;
+};
+
+struct msm_vfe_reg_cfg_cmd {
+	union {
+		struct msm_vfe_reg_rw_info rw_info;
+		struct msm_vfe_reg_mask_info mask_info;
+		struct msm_vfe_reg_dmi_info dmi_info;
+	} u;
+
+	enum msm_vfe_reg_cfg_type cmd_type;
+};
+
+struct msm_isp_buf_request {
+	uint32_t session_id;
+	uint32_t stream_id;
+	uint8_t num_buf;
+	uint32_t handle;
+};
+
+struct msm_isp_qbuf_info {
+	uint32_t handle;
+	int buf_idx;
+	/*Only used for prepare buffer*/
+	struct v4l2_buffer buffer;
+	/*Only used for diverted buffer*/
+	uint32_t dirty_buf;
+};
+
+struct msm_vfe_axi_src_state {
+	enum msm_vfe_input_src input_src;
+	uint32_t src_active;
+};
+
+enum msm_isp_event_idx {
+	ISP_REG_UPDATE      = 0,
+	ISP_START_ACK       = 1,
+	ISP_STOP_ACK        = 2,
+	ISP_IRQ_VIOLATION   = 3,
+	ISP_WM_BUS_OVERFLOW = 4,
+	ISP_STATS_OVERFLOW  = 5,
+	ISP_CAMIF_ERROR     = 6,
+	ISP_SOF             = 7,
+	ISP_EOF             = 8,
+	ISP_EVENT_MAX       = 9
+};
+
+#define ISP_EVENT_OFFSET          8
+#define ISP_EVENT_BASE            (V4L2_EVENT_PRIVATE_START)
+#define ISP_BUF_EVENT_BASE        (ISP_EVENT_BASE + (1 << ISP_EVENT_OFFSET))
+#define ISP_STATS_EVENT_BASE      (ISP_EVENT_BASE + (2 << ISP_EVENT_OFFSET))
+#define ISP_EVENT_REG_UPDATE      (ISP_EVENT_BASE + ISP_REG_UPDATE)
+#define ISP_EVENT_START_ACK       (ISP_EVENT_BASE + ISP_START_ACK)
+#define ISP_EVENT_STOP_ACK        (ISP_EVENT_BASE + ISP_STOP_ACK)
+#define ISP_EVENT_IRQ_VIOLATION   (ISP_EVENT_BASE + ISP_IRQ_VIOLATION)
+#define ISP_EVENT_WM_BUS_OVERFLOW (ISP_EVENT_BASE + ISP_WM_BUS_OVERFLOW)
+#define ISP_EVENT_STATS_OVERFLOW  (ISP_EVENT_BASE + ISP_STATS_OVERFLOW)
+#define ISP_EVENT_CAMIF_ERROR     (ISP_EVENT_BASE + ISP_CAMIF_ERROR)
+#define ISP_EVENT_SOF             (ISP_EVENT_BASE + ISP_SOF)
+#define ISP_EVENT_EOF             (ISP_EVENT_BASE + ISP_EOF)
+#define ISP_EVENT_BUF_DIVERT      (ISP_BUF_EVENT_BASE)
+#define ISP_EVENT_STATS_NOTIFY    (ISP_STATS_EVENT_BASE)
+
+/* The msm_v4l2_event_data structure should match the
+ * v4l2_event.u.data field.
+ * should not exceed 64 bytes */
+
+struct msm_isp_buf_event {
+	uint32_t session_id;
+	uint32_t stream_id;
+	uint32_t handle;
+	int8_t buf_idx;
+};
+struct msm_isp_stats_event {
+	uint32_t stats_mask;                        /* 4 bytes */
+	uint8_t stats_buf_idxs[MSM_ISP_STATS_MAX];  /* 11 bytes */
+};
+
+struct msm_isp_stream_ack {
+	uint32_t session_id;
+	uint32_t stream_id;
+	uint32_t handle;
+};
+
+struct msm_isp_event_data {
+	/*Wall clock except for buffer divert events
+	 *which use monotonic clock
+	 */
+	struct timeval timestamp;
+	/* if pix is a src frame_id is from camif */
+	uint32_t frame_id;
+	union {
+		/* START_ACK, STOP_ACK */
+		struct msm_isp_stream_ack stream_ack;
+		/* REG_UPDATE_TRIGGER, bus over flow */
+		enum msm_vfe_input_src input_src;
+		/* stats notify */
+		struct msm_isp_stats_event stats;
+		/* IRQ_VIOLATION, STATS_OVER_FLOW, WM_OVER_FLOW */
+		uint32_t irq_status_mask;
+		struct msm_isp_buf_event buf_done;
+	} u; /* union can have max 52 bytes */
+};
+
+#define V4L2_PIX_FMT_QBGGR8  v4l2_fourcc('Q', 'B', 'G', '8')
+#define V4L2_PIX_FMT_QGBRG8  v4l2_fourcc('Q', 'G', 'B', '8')
+#define V4L2_PIX_FMT_QGRBG8  v4l2_fourcc('Q', 'G', 'R', '8')
+#define V4L2_PIX_FMT_QRGGB8  v4l2_fourcc('Q', 'R', 'G', '8')
+#define V4L2_PIX_FMT_QBGGR10 v4l2_fourcc('Q', 'B', 'G', '0')
+#define V4L2_PIX_FMT_QGBRG10 v4l2_fourcc('Q', 'G', 'B', '0')
+#define V4L2_PIX_FMT_QGRBG10 v4l2_fourcc('Q', 'G', 'R', '0')
+#define V4L2_PIX_FMT_QRGGB10 v4l2_fourcc('Q', 'R', 'G', '0')
+#define V4L2_PIX_FMT_QBGGR12 v4l2_fourcc('Q', 'B', 'G', '2')
+#define V4L2_PIX_FMT_QGBRG12 v4l2_fourcc('Q', 'G', 'B', '2')
+#define V4L2_PIX_FMT_QGRBG12 v4l2_fourcc('Q', 'G', 'R', '2')
+#define V4L2_PIX_FMT_QRGGB12 v4l2_fourcc('Q', 'R', 'G', '2')
+
+#define VIDIOC_MSM_VFE_REG_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE, struct msm_vfe_cfg_cmd2)
+
+#define VIDIOC_MSM_ISP_REQUEST_BUF \
+	_IOWR('V', BASE_VIDIOC_PRIVATE+1, struct msm_isp_buf_request)
+
+#define VIDIOC_MSM_ISP_ENQUEUE_BUF \
+	_IOWR('V', BASE_VIDIOC_PRIVATE+2, struct msm_isp_qbuf_info)
+
+#define VIDIOC_MSM_ISP_RELEASE_BUF \
+	_IOWR('V', BASE_VIDIOC_PRIVATE+3, struct msm_isp_buf_request)
+
+#define VIDIOC_MSM_ISP_REQUEST_STREAM \
+	_IOWR('V', BASE_VIDIOC_PRIVATE+4, struct msm_vfe_axi_stream_request_cmd)
+
+#define VIDIOC_MSM_ISP_CFG_STREAM \
+	_IOWR('V', BASE_VIDIOC_PRIVATE+5, struct msm_vfe_axi_stream_cfg_cmd)
+
+#define VIDIOC_MSM_ISP_RELEASE_STREAM \
+	_IOWR('V', BASE_VIDIOC_PRIVATE+6, struct msm_vfe_axi_stream_release_cmd)
+
+#define VIDIOC_MSM_ISP_INPUT_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE+7, struct msm_vfe_input_cfg)
+
+#define VIDIOC_MSM_ISP_SET_SRC_STATE \
+	_IOWR('V', BASE_VIDIOC_PRIVATE+8, struct msm_vfe_axi_src_state)
+
+#define VIDIOC_MSM_ISP_REQUEST_STATS_STREAM \
+	_IOWR('V', BASE_VIDIOC_PRIVATE+9, \
+	struct msm_vfe_stats_stream_request_cmd)
+
+#define VIDIOC_MSM_ISP_CFG_STATS_STREAM \
+	_IOWR('V', BASE_VIDIOC_PRIVATE+10, struct msm_vfe_stats_stream_cfg_cmd)
+
+#define VIDIOC_MSM_ISP_RELEASE_STATS_STREAM \
+	_IOWR('V', BASE_VIDIOC_PRIVATE+11, \
+	struct msm_vfe_stats_stream_release_cmd)
+
+#define VIDIOC_MSM_ISP_CFG_STATS_COMP_POLICY \
+	_IOWR('V', BASE_VIDIOC_PRIVATE+12,   \
+	      struct msm_vfe_stats_comp_policy_cfg)
+
+#define VIDIOC_MSM_ISP_UPDATE_STREAM \
+	_IOWR('V', BASE_VIDIOC_PRIVATE+13, struct msm_vfe_axi_stream_update_cmd)
+
+#endif /* __MSMB_ISP__ */
diff --git a/include/media/msmb_ispif.h b/include/media/msmb_ispif.h
new file mode 100644
index 0000000..fc27ef6
--- /dev/null
+++ b/include/media/msmb_ispif.h
@@ -0,0 +1,103 @@
+#ifndef MSM_CAM_ISPIF_H
+#define MSM_CAM_ISPIF_H
+
+#define CSID_VERSION_V2                       0x02000011
+#define CSID_VERSION_V3                       0x30000000
+
+enum msm_ispif_vfe_intf {
+	VFE0,
+	VFE1,
+	VFE_MAX
+};
+#define VFE0_MASK    (1 << VFE0)
+#define VFE1_MASK    (1 << VFE1)
+
+enum msm_ispif_intftype {
+	PIX0,
+	RDI0,
+	PIX1,
+	RDI1,
+	RDI2,
+	INTF_MAX
+};
+#define PIX0_MASK (1 << PIX0)
+#define PIX1_MASK (1 << PIX1)
+#define RDI0_MASK (1 << RDI0)
+#define RDI1_MASK (1 << RDI1)
+#define RDI2_MASK (1 << RDI2)
+
+
+enum msm_ispif_vc {
+	VC0,
+	VC1,
+	VC2,
+	VC3,
+	VC_MAX
+};
+
+enum msm_ispif_cid {
+	CID0,
+	CID1,
+	CID2,
+	CID3,
+	CID4,
+	CID5,
+	CID6,
+	CID7,
+	CID8,
+	CID9,
+	CID10,
+	CID11,
+	CID12,
+	CID13,
+	CID14,
+	CID15,
+	CID_MAX
+};
+
+enum msm_ispif_csid {
+	CSID0,
+	CSID1,
+	CSID2,
+	CSID3,
+	CSID_MAX
+};
+
+struct msm_ispif_params_entry {
+	enum msm_ispif_intftype intftype;
+	int num_cids;
+	enum msm_ispif_cid cids[3];
+	enum msm_ispif_csid csid;
+};
+
+struct msm_ispif_param_data {
+	enum msm_ispif_vfe_intf vfe_intf;
+	uint32_t num;
+	struct msm_ispif_params_entry entries[INTF_MAX];
+};
+
+enum ispif_cfg_type_t {
+	ISPIF_CLK_ENABLE,
+	ISPIF_CLK_DISABLE,
+	ISPIF_INIT,
+	ISPIF_CFG,
+	ISPIF_START_FRAME_BOUNDARY,
+	ISPIF_STOP_FRAME_BOUNDARY,
+	ISPIF_STOP_IMMEDIATELY,
+	ISPIF_RELEASE,
+	ISPIF_ENABLE_REG_DUMP,
+};
+
+struct ispif_cfg_data {
+	enum ispif_cfg_type_t cfg_type;
+	union {
+		int reg_dump;                        /* ISPIF_ENABLE_REG_DUMP */
+		uint32_t csid_version;               /* ISPIF_INIT */
+		struct msm_ispif_param_data params;  /* CFG, START, STOP */
+	};
+};
+
+#define VIDIOC_MSM_ISPIF_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE, struct ispif_cfg_data)
+
+#endif /* MSM_CAM_ISPIF_H */
diff --git a/include/media/msmb_pproc.h b/include/media/msmb_pproc.h
new file mode 100644
index 0000000..6bac1d6
--- /dev/null
+++ b/include/media/msmb_pproc.h
@@ -0,0 +1,119 @@
+#ifndef __MSMB_PPROC_H
+#define __MSMB_PPROC_H
+
+#ifdef MSM_CAMERA_BIONIC
+#include <sys/types.h>
+#endif
+#include <linux/videodev2.h>
+#include <linux/types.h>
+
+/* Should be same as VIDEO_MAX_PLANES in videodev2.h */
+#define MAX_PLANES VIDEO_MAX_PLANES
+
+#define MAX_NUM_CPP_STRIPS 8
+
+enum msm_cpp_frame_type {
+	MSM_CPP_OFFLINE_FRAME,
+	MSM_CPP_REALTIME_FRAME,
+};
+
+struct msm_cpp_frame_strip_info {
+	int scale_v_en;
+	int scale_h_en;
+
+	int upscale_v_en;
+	int upscale_h_en;
+
+	int src_start_x;
+	int src_end_x;
+	int src_start_y;
+	int src_end_y;
+
+	/* Padding is required for upscaler because it does not
+	 * pad internally like other blocks, also needed for rotation
+	 * rotation expects all the blocks in the stripe to be the same size
+	 * Padding is done such that all the extra padded pixels
+	 * are on the right and bottom
+	 */
+	int pad_bottom;
+	int pad_top;
+	int pad_right;
+	int pad_left;
+
+	int v_init_phase;
+	int h_init_phase;
+	int h_phase_step;
+	int v_phase_step;
+
+	int prescale_crop_width_first_pixel;
+	int prescale_crop_width_last_pixel;
+	int prescale_crop_height_first_line;
+	int prescale_crop_height_last_line;
+
+	int postscale_crop_height_first_line;
+	int postscale_crop_height_last_line;
+	int postscale_crop_width_first_pixel;
+	int postscale_crop_width_last_pixel;
+
+	int dst_start_x;
+	int dst_end_x;
+	int dst_start_y;
+	int dst_end_y;
+
+	int bytes_per_pixel;
+	unsigned int source_address;
+	unsigned int destination_address;
+	unsigned int src_stride;
+	unsigned int dst_stride;
+	int rotate_270;
+	int horizontal_flip;
+	int vertical_flip;
+	int scale_output_width;
+	int scale_output_height;
+	int prescale_crop_en;
+	int postscale_crop_en;
+};
+
+struct msm_cpp_frame_info_t {
+	int32_t frame_id;
+	uint32_t inst_id;
+	uint32_t client_id;
+	enum msm_cpp_frame_type frame_type;
+	uint32_t num_strips;
+	struct msm_cpp_frame_strip_info *strip_info;
+	uint32_t msg_len;
+	uint32_t *cpp_cmd_msg;
+	int src_fd;
+	int dst_fd;
+	struct ion_handle *src_ion_handle;
+	struct ion_handle *dest_ion_handle;
+};
+
+struct msm_ver_num_info {
+	uint32_t main;
+	uint32_t minor;
+	uint32_t rev;
+};
+
+#define VIDIOC_MSM_CPP_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE, struct msm_camera_v4l2_ioctl_t)
+
+#define VIDIOC_MSM_CPP_GET_EVENTPAYLOAD \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct msm_camera_v4l2_ioctl_t)
+
+#define VIDIOC_MSM_CPP_GET_INST_INFO \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 2, struct msm_camera_v4l2_ioctl_t)
+
+#define VIDIOC_MSM_CPP_LOAD_FIRMWARE \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 3, struct msm_camera_v4l2_ioctl_t)
+
+#define V4L2_EVENT_CPP_FRAME_DONE  (V4L2_EVENT_PRIVATE_START + 0)
+
+struct msm_camera_v4l2_ioctl_t {
+	uint32_t id;
+	uint32_t len;
+	uint32_t trans_code;
+	void __user *ioctl_ptr;
+};
+
+#endif /* __MSMB_PPROC_H */
diff --git a/include/media/radio-iris.h b/include/media/radio-iris.h
index 0efeff4..e3c4567 100644
--- a/include/media/radio-iris.h
+++ b/include/media/radio-iris.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright (c) 2011-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012 The Linux Foundation. All rights reserved.
  *
  * This file is based on include/net/bluetooth/hci_core.h
  *
diff --git a/include/media/user-rc-input.h b/include/media/user-rc-input.h
index e58e40f..0eb9aec 100644
--- a/include/media/user-rc-input.h
+++ b/include/media/user-rc-input.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/include/media/vcap_fmt.h b/include/media/vcap_fmt.h
index 2787e8d..b2a8d10 100644
--- a/include/media/vcap_fmt.h
+++ b/include/media/vcap_fmt.h
@@ -1,16 +1,3 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 VCAP_FMT_H
 #define VCAP_FMT_H
 #include <linux/videodev2.h>
diff --git a/include/media/vcap_v4l2.h b/include/media/vcap_v4l2.h
index 39aa1b9..0011ee6 100644
--- a/include/media/vcap_v4l2.h
+++ b/include/media/vcap_v4l2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/include/media/videobuf-msm-mem.h b/include/media/videobuf-msm-mem.h
index 19dd93e..5e9790c 100644
--- a/include/media/videobuf-msm-mem.h
+++ b/include/media/videobuf-msm-mem.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/media/videobuf2-msm-mem.h b/include/media/videobuf2-msm-mem.h
index f80ddcd..49625c4 100644
--- a/include/media/videobuf2-msm-mem.h
+++ b/include/media/videobuf2-msm-mem.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/include/net/bluetooth/amp.h b/include/net/bluetooth/amp.h
index ec517b0..15d1817 100644
--- a/include/net/bluetooth/amp.h
+++ b/include/net/bluetooth/amp.h
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2010-2012 Code Aurora Forum.  All rights reserved.
+   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
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 660a4a9..e909195 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -1,6 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
-   Copyright (c) 2000-2001, 2010-2012 Code Aurora Forum.  All rights reserved.
+   Copyright (c) 2000-2001, 2010-2013 The Linux Foundation. All rights reserved.
 
    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
 
@@ -63,6 +63,7 @@
 #define BT_SECURITY_LOW		1
 #define BT_SECURITY_MEDIUM	2
 #define BT_SECURITY_HIGH	3
+#define BT_SECURITY_VERY_HIGH	4
 
 #define BT_DEFER_SETUP	7
 #define BT_FLUSHABLE	8
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 80f36e0..42c8823 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -1,6 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
-   Copyright (c) 2000-2001, 2010-2012 Code Aurora Forum. All rights reserved.
+   Copyright (c) 2000-2001, 2010-2012 The Linux Foundation. All rights reserved.
 
    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
 
@@ -412,6 +412,11 @@
 	__le16   handle;
 } __packed;
 
+#define HCI_OP_READ_CLOCK_OFFSET	0x041f
+struct hci_cp_read_clock_offset {
+	__le16   handle;
+} __packed;
+
 #define HCI_OP_SETUP_SYNC_CONN		0x0428
 struct hci_cp_setup_sync_conn {
 	__le16   handle;
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 544f3bf..efc11bb 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1,6 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
-   Copyright (c) 2000-2001, 2010-2012, Code Aurora Forum. All rights reserved.
+   Copyright (c) 2000-2001, 2010-2012, The Linux Foundation. All rights reserved.
 
    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
 
@@ -383,7 +383,7 @@
 
 /* ----- Inquiry cache ----- */
 #define INQUIRY_CACHE_AGE_MAX   (HZ*30)   /* 30 seconds */
-#define INQUIRY_ENTRY_AGE_MAX   (HZ*60)   /* 60 seconds */
+#define INQUIRY_ENTRY_AGE_MAX   (HZ*60*60)   /* 1 Hour */
 
 #define inquiry_cache_lock(c)		spin_lock(&c->lock)
 #define inquiry_cache_unlock(c)		spin_unlock(&c->lock)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index e312ab3..9c2b735 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -1,6 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
-   Copyright (c) 2000-2001, 2010-2012 Code Aurora Forum.  All rights reserved.
+   Copyright (c) 2000-2001, 2010-2012 The Linux Foundation.  All rights reserved.
    Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
    Copyright (C) 2010 Google Inc.
 
diff --git a/include/net/bluetooth/sco.h b/include/net/bluetooth/sco.h
index 6d94c34..8c85c98 100644
--- a/include/net/bluetooth/sco.h
+++ b/include/net/bluetooth/sco.h
@@ -1,7 +1,7 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
    Copyright (C) 2000-2001 Qualcomm Incorporated
-   Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+   Copyright (c) 2011, The Linux Foundation. All rights reserved.
 
    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
 
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 5c1daf3..6666c69 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1199,6 +1199,7 @@
  * @ie: IEs for association request
  * @ie_len: Length of assoc_ie in octets
  * @privacy: indicates whether privacy-enabled APs should be used
+ * @mfp: indicate whether management frame protection is used
  * @crypto: crypto settings
  * @key_len: length of WEP key for shared key authentication
  * @key_idx: index of WEP key for shared key authentication
@@ -1219,6 +1220,7 @@
 	u8 *ie;
 	size_t ie_len;
 	bool privacy;
+	enum nl80211_mfp mfp;
 	struct cfg80211_crypto_settings crypto;
 	const u8 *key;
 	u8 key_len, key_idx;
@@ -3358,6 +3360,25 @@
 				 enum nl80211_channel_type channel_type);
 
 /*
+ * cfg80211_tdls_oper_request - request userspace to perform TDLS operation
+ * @dev: the device on which the operation is requested
+ * @peer: the MAC address of the peer device
+ * @oper: the requested TDLS operation (NL80211_TDLS_SETUP or
+ *	NL80211_TDLS_TEARDOWN)
+ * @reason_code: the reason code for teardown request
+ * @gfp: allocation flags
+ *
+ * This function is used to request userspace to perform TDLS operation that
+ * requires knowledge of keys, i.e., link setup or teardown when the AP
+ * connection uses encryption. This is optional mechanism for the driver to use
+ * if it can automatically determine when a TDLS link could be useful (e.g.,
+ * based on traffic and signal strength for a peer).
+ */
+void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
+				enum nl80211_tdls_operation oper,
+				u16 reason_code, gfp_t gfp);
+
+/*
  * cfg80211_calculate_bitrate - calculate actual bitrate (in 100Kbps units)
  * @rate: given rate_info to calculate bitrate from
  *
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index ab86036..eeb5258 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -100,6 +100,11 @@
 #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
 #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
 
+/* Handle NATTYPE Stuff,only if NATTYPE module was defined */
+#if defined(CONFIG_IP_NF_TARGET_NATTYPE_MODULE)
+#include <linux/netfilter_ipv4/ipt_NATTYPE.h>
+#endif
+
 struct nf_conn {
 	/* Usage count in here is 1 for hash table/destruct timer, 1 per skb,
            plus 1 for any connection(s) we are `master' for */
@@ -134,6 +139,10 @@
 	struct net *ct_net;
 #endif
 
+#if defined(CONFIG_IP_NF_TARGET_NATTYPE_MODULE)
+	unsigned long nattype_entry;
+#endif
+
 	/* Storage reserved for other modules, must be the last member */
 	union nf_conntrack_proto proto;
 };
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
index f34a5a8..cc37cd8 100644
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -562,4 +562,6 @@
 	return (ptr[0]<<24) + (ptr[1]<<16) + (ptr[2]<<8) + ptr[3];
 }
 
+struct scsi_disk *scsi_disk_get_from_dev(struct device *dev);
+
 #endif /* _SCSI_SCSI_H */
diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h
index 88acdfc..93f0aa90 100644
--- a/include/sound/apr_audio-v2.h
+++ b/include/sound/apr_audio-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -82,6 +82,14 @@
 */
 #define ADM_CMD_DEVICE_OPEN_V5                          0x00010326
 
+#define ADM_BIT_SHIFT_DEVICE_PERF_MODE_FLAG                           13
+
+/* Definition for a legacy device session. */
+#define ADM_LEGACY_DEVICE_SESSION                                      0
+
+/* Definition for a low latency stream session. */
+#define ADM_LOW_LATENCY_DEVICE_SESSION                                 1
+
 /* Indicates that endpoint_id_2 is to be ignored.*/
 #define ADM_CMD_COPP_OPEN_END_POINT_ID_2_IGNORE				0xFFFF
 
@@ -3794,8 +3802,15 @@
 
 /* adsp_asm_session_command.h*/
 #define ASM_STREAM_CMD_OPEN_WRITE_V2       0x00010D8F
+#define ASM_STREAM_CMD_OPEN_WRITE_V3       0x00010DB3
 
-struct asm_stream_cmd_open_write_v2 {
+#define ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_WRITE                     28
+
+#define ASM_LEGACY_STREAM_SESSION                                      0
+
+#define ASM_LOW_LATENCY_STREAM_SESSION                                  1
+
+struct asm_stream_cmd_open_write_v3 {
 	struct apr_hdr			hdr;
 	uint32_t                    mode_flags;
 /* Mode flags that configure the stream to notify the client
@@ -3878,6 +3893,9 @@
 } __packed;
 
 #define ASM_STREAM_CMD_OPEN_READ_V2                 0x00010D8C
+
+#define ASM_STREAM_CMD_OPEN_READ_V3                 0x00010DB4
+
 /* Definition of the timestamp type flag bitmask */
 #define ASM_BIT_MASKIMESTAMPYPE_FLAG        (0x00000020UL)
 
@@ -3890,8 +3908,10 @@
 /* Absolute timestamp is identified by this value.*/
 #define ASM_ABSOLUTEIMESTAMP      1
 
+/* Bit shift for the stream_perf_mode subfield. */
+#define ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_READ              29
 
-struct asm_stream_cmd_open_read_v2 {
+struct asm_stream_cmd_open_read_v3 {
 	struct apr_hdr hdr;
 	u32                    mode_flags;
 /* Mode flags that indicate whether meta information per encoded
@@ -6215,6 +6235,22 @@
 #define VOICE_CMD_GET_PARAM				0x0001133E
 #define VOICE_EVT_GET_PARAM_ACK				0x00011008
 
+/* Set Q6 topologies */
+#define ASM_CMD_ADD_TOPOLOGIES				0x00010DBE
+#define ADM_CMD_ADD_TOPOLOGIES				0x00010335
+
+/* structure used for both ioctls */
+struct cmd_set_topologies {
+	struct apr_hdr hdr;
+	u32		payload_addr_lsw;
+	/* LSW of parameter data payload address.*/
+	u32		payload_addr_msw;
+	/* MSW of parameter data payload address.*/
+	u32		mem_map_handle;
+	/* Memory map handle returned by mem map command */
+	u32		payload_size;
+	/* Size in bytes of the variable payload in shared memory */
+} __packed;
 
 /* SRS TRUMEDIA start */
 /* topology */
@@ -6369,4 +6405,183 @@
 
 /*bharath, adsp_error_codes.h */
 
+/* LPASS clock for I2S Interface */
+
+/* Supported OSR clock values */
+#define Q6AFE_LPASS_OSR_CLK_12_P288_MHZ		0xBB8000
+#define Q6AFE_LPASS_OSR_CLK_8_P192_MHZ		0x7D0000
+#define Q6AFE_LPASS_OSR_CLK_6_P144_MHZ		0x5DC000
+#define Q6AFE_LPASS_OSR_CLK_4_P096_MHZ		0x3E8000
+#define Q6AFE_LPASS_OSR_CLK_3_P072_MHZ		0x2EE000
+#define Q6AFE_LPASS_OSR_CLK_2_P048_MHZ		0x1F4000
+#define Q6AFE_LPASS_OSR_CLK_1_P536_MHZ		0x177000
+#define Q6AFE_LPASS_OSR_CLK_1_P024_MHZ		 0xFA000
+#define Q6AFE_LPASS_OSR_CLK_768_kHZ		 0xBB800
+#define Q6AFE_LPASS_OSR_CLK_512_kHZ		 0x7D000
+#define Q6AFE_LPASS_OSR_CLK_DISABLE		     0x0
+
+/* Supported Bit clock values */
+#define Q6AFE_LPASS_IBIT_CLK_8_P192_MHZ		0x7D0000
+#define Q6AFE_LPASS_IBIT_CLK_6_P144_MHZ		0x5DC000
+#define Q6AFE_LPASS_IBIT_CLK_4_P096_MHZ		0x3E8000
+#define Q6AFE_LPASS_IBIT_CLK_3_P072_MHZ		0x2EE000
+#define Q6AFE_LPASS_IBIT_CLK_2_P048_MHZ		0x1F4000
+#define Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ		0x177000
+#define Q6AFE_LPASS_IBIT_CLK_1_P024_MHZ		 0xFA000
+#define Q6AFE_LPASS_IBIT_CLK_768_KHZ		 0xBB800
+#define Q6AFE_LPASS_IBIT_CLK_512_KHZ		 0x7D000
+#define Q6AFE_LPASS_IBIT_CLK_DISABLE		     0x0
+
+/* Supported LPASS CLK sources */
+#define Q6AFE_LPASS_CLK_SRC_EXTERNAL 0
+#define Q6AFE_LPASS_CLK_SRC_INTERNAL 1
+
+/* Supported LPASS CLK root*/
+#define Q6AFE_LPASS_CLK_ROOT_DEFAULT 0
+
+enum afe_lpass_clk_mode {
+	Q6AFE_LPASS_MODE_BOTH_INVALID,
+	Q6AFE_LPASS_MODE_CLK1_VALID,
+	Q6AFE_LPASS_MODE_CLK2_VALID,
+	Q6AFE_LPASS_MODE_BOTH_VALID,
+} __packed;
+
+struct afe_clk_cfg {
+/* Minor version used for tracking the version of the I2S
+ * configuration interface.
+ * Supported values: #AFE_API_VERSION_I2S_CONFIG
+ */
+	u32                  i2s_cfg_minor_version;
+
+/* clk value 1 in MHz. */
+	u32                  clk_val1;
+
+/* clk value 2 in MHz. */
+	u32                  clk_val2;
+
+/* clk_src
+ * #Q6AFE_LPASS_CLK_SRC_EXTERNAL
+ * #Q6AFE_LPASS_CLK_SRC_INTERNAL
+ */
+
+	u16                  clk_src;
+
+/* clk_root -0 for default */
+	u16                  clk_root;
+
+/* clk_set_mode
+ * #Q6AFE_LPASS_MODE_BOTH_INVALID
+ * #Q6AFE_LPASS_MODE_CLK1_VALID
+ * #Q6AFE_LPASS_MODE_CLK2_VALID
+ * #Q6AFE_LPASS_MODE_BOTH_VALID
+ */
+	u16                  clk_set_mode;
+
+/* This param id is used to configure I2S clk */
+	u16                  reserved;
+} __packed;
+
+/* This param id is used to configure I2S clk */
+#define AFE_PARAM_ID_LPAIF_CLK_CONFIG	0x00010238
+
+
+struct afe_lpass_clk_config_command {
+	struct apr_hdr			 hdr;
+	struct afe_port_cmd_set_param_v2 param;
+	struct afe_port_param_data_v2    pdata;
+	struct afe_clk_cfg clk_cfg;
+} __packed;
+
+enum afe_lpass_digital_clk_src {
+	Q6AFE_LPASS_DIGITAL_ROOT_INVALID,
+	Q6AFE_LPASS_DIGITAL_ROOT_PRI_MI2S_OSR,
+	Q6AFE_LPASS_DIGITAL_ROOT_SEC_MI2S_OSR,
+	Q6AFE_LPASS_DIGITAL_ROOT_TER_MI2S_OSR,
+	Q6AFE_LPASS_DIGITAL_ROOT_QUAD_MI2S_OSR,
+	Q6AFE_LPASS_DIGITAL_ROOT_CDC_ROOT_CLK,
+} __packed;
+
+/* This param id is used to configure internal clk */
+#define AFE_PARAM_ID_INTERNAL_DIGIATL_CDC_CLK_CONFIG	0x00010239
+
+struct afe_digital_clk_cfg {
+/* Minor version used for tracking the version of the I2S
+ * configuration interface.
+ * Supported values: #AFE_API_VERSION_I2S_CONFIG
+ */
+	u32                  i2s_cfg_minor_version;
+
+/* clk value in MHz. */
+	u32                  clk_val;
+
+/*	INVALID
+ *	PRI_MI2S_OSR
+ *	SEC_MI2S_OSR
+ *	TER_MI2S_OSR
+ *	QUAD_MI2S_OSR
+ *	DIGT_CDC_ROOT
+ */
+	u16                  clk_root;
+
+/* This field must be set to zero. */
+	u16                  reserved;
+} __packed;
+
+
+struct afe_lpass_digital_clk_config_command {
+	struct apr_hdr			 hdr;
+	struct afe_port_cmd_set_param_v2 param;
+	struct afe_port_param_data_v2    pdata;
+	struct afe_digital_clk_cfg clk_cfg;
+} __packed;
+
+/*
+ * Opcode for AFE to start DTMF.
+ */
+#define AFE_PORTS_CMD_DTMF_CTL	0x00010102
+
+/** DTMF payload.*/
+struct afe_dtmf_generation_command {
+	struct apr_hdr hdr;
+
+	/*
+	 * Duration of the DTMF tone in ms.
+	 * -1      -> continuous,
+	 *  0      -> disable
+	 */
+	int64_t                   duration_in_ms;
+
+	/*
+	 * The DTMF high tone frequency.
+	 */
+	uint16_t                  high_freq;
+
+	/*
+	 * The DTMF low tone frequency.
+	 */
+	uint16_t                  low_freq;
+
+	/*
+	 * The DTMF volume setting
+	 */
+	uint16_t                  gain;
+
+	/*
+	 * The number of ports to enable/disable on.
+	 */
+	uint16_t                  num_ports;
+
+	/*
+	 * The Destination ports - array  .
+	 * For DTMF on multiple ports, portIds needs to
+	 * be populated numPorts times.
+	 */
+	uint16_t                  port_ids;
+
+	/*
+	 * variable for 32 bit alignment of APR packet.
+	 */
+	uint16_t                  reserved;
+} __packed;
+
 #endif /*_APR_AUDIO_V2_H_ */
diff --git a/include/sound/apr_audio.h b/include/sound/apr_audio.h
index 5afbfad..40b0e1e 100644
--- a/include/sound/apr_audio.h
+++ b/include/sound/apr_audio.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * 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
@@ -1513,6 +1513,17 @@
 	struct asm_dual_mono channel_map;
 } __packed;
 
+#define ASM_PARAM_ID_AAC_STEREO_MIX_COEFF_SELECTION_FLAG        0x00010DD8
+
+/* Structure for AAC decoder stereo coefficient setting. */
+
+struct asm_aac_stereo_mix_coeff_selection_param {
+	struct apr_hdr				hdr;
+	u32					param_id;
+	u32					param_size;
+	u32					aac_stereo_mix_coeff_flag;
+} __packed;
+
 #define ASM_ENCDEC_DEC_CHAN_MAP				 0x00010D82
 struct asm_stream_cmd_encdec_channelmap {
 	struct apr_hdr hdr;
diff --git a/include/sound/dai.h b/include/sound/dai.h
index 4d3fb96..031fe3b 100644
--- a/include/sound/dai.h
+++ b/include/sound/dai.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/sound/msm-dai-q6-v2.h b/include/sound/msm-dai-q6-v2.h
index 4ecd435..c34a397 100644
--- a/include/sound/msm-dai-q6-v2.h
+++ b/include/sound/msm-dai-q6-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -26,8 +26,7 @@
 #define MSM_TERT_MI2S 2
 #define MSM_QUAT_MI2S  3
 
-struct msm_dai_auxpcm_pdata {
-	const char *clk;
+struct msm_dai_auxpcm_config {
 	u16 mode;
 	u16 sync;
 	u16 frame;
@@ -40,6 +39,12 @@
 	int pcm_clk_rate;
 };
 
+struct msm_dai_auxpcm_pdata {
+	void *clk_cfg;
+	struct msm_dai_auxpcm_config mode_8k;
+	struct msm_dai_auxpcm_config mode_16k;
+};
+
 struct msm_mi2s_pdata {
 	u16 rx_sd_lines;
 	u16 tx_sd_lines;
diff --git a/include/sound/msm-dai-q6.h b/include/sound/msm-dai-q6.h
index 042aa6f..a39d3dc 100644
--- a/include/sound/msm-dai-q6.h
+++ b/include/sound/msm-dai-q6.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/sound/q6adm-v2.h b/include/sound/q6adm-v2.h
index fdc3cb9..77a805c 100644
--- a/include/sound/q6adm-v2.h
+++ b/include/sound/q6adm-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -29,10 +29,11 @@
 
 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);
+int adm_open(int port, int path, int rate, int mode, int topology,
+				bool perf_mode, uint16_t bits_per_sample);
 
 int adm_multi_ch_copp_open(int port, int path, int rate, int mode,
-				int topology);
+			int topology, bool perf_mode, uint16_t bits_per_sample);
 
 int adm_memory_map_regions(int port_id, uint32_t *buf_add, uint32_t mempool_id,
 				uint32_t *bufsz, uint32_t bufcnt);
@@ -49,4 +50,8 @@
 
 int adm_get_copp_id(int port_id);
 
+void adm_set_multi_ch_map(char *channel_map);
+
+void adm_get_multi_ch_map(char *channel_map);
+
 #endif /* __Q6_ADM_V2_H__ */
diff --git a/include/sound/q6adm.h b/include/sound/q6adm.h
index 70c68a8..b819725 100644
--- a/include/sound/q6adm.h
+++ b/include/sound/q6adm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/sound/q6afe-v2.h b/include/sound/q6afe-v2.h
index 444b432..506e877 100644
--- a/include/sound/q6afe-v2.h
+++ b/include/sound/q6afe-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -73,6 +73,12 @@
 	IDX_RT_PROXY_PORT_001_TX = 31,
 	IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX = 32,
 	IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX = 33,
+	IDX_AFE_PORT_ID_SECONDARY_MI2S_RX = 34,
+	IDX_AFE_PORT_ID_SECONDARY_MI2S_TX = 35,
+	IDX_AFE_PORT_ID_TERTIARY_MI2S_RX = 36,
+	IDX_AFE_PORT_ID_TERTIARY_MI2S_TX = 37,
+	IDX_AFE_PORT_ID_PRIMARY_MI2S_RX = 38,
+	IDX_AFE_PORT_ID_PRIMARY_MI2S_TX = 39,
 	AFE_MAX_PORTS
 };
 
@@ -108,6 +114,7 @@
 	/* idx:1 out port, 0: in port*/
 	struct afe_audio_port_data port[2];
 	wait_queue_head_t      cmd_wait;
+	uint32_t               mem_map_handle;
 };
 
 int afe_open(u16 port_id, union afe_port_config *afe_config, int rate);
@@ -119,12 +126,16 @@
 int afe_get_port_index(u16 port_id);
 int afe_start_pseudo_port(u16 port_id);
 int afe_stop_pseudo_port(u16 port_id);
-uint32_t afe_req_mmap_handle(void);
+uint32_t afe_req_mmap_handle(struct afe_audio_client *ac);
+int afe_memory_map(u32 dma_addr_p, u32 dma_buf_sz, struct afe_audio_client *ac);
 int afe_cmd_memory_map(u32 dma_addr_p, u32 dma_buf_sz);
 int afe_cmd_memory_map_nowait(int port_id, u32 dma_addr_p, u32 dma_buf_sz);
 int afe_cmd_memory_unmap(u32 dma_addr_p);
 int afe_cmd_memory_unmap_nowait(u32 dma_addr_p);
-
+void afe_set_dtmf_gen_rx_portid(u16 rx_port_id, int set);
+int afe_dtmf_generate_rx(int64_t duration_in_ms,
+			 uint16_t high_freq,
+			 uint16_t low_freq, uint16_t gain);
 int afe_register_get_events(u16 port_id,
 		void (*cb) (uint32_t opcode,
 		uint32_t token, uint32_t *payload, void *priv),
@@ -153,4 +164,9 @@
 
 int afe_pseudo_port_start_nowait(u16 port_id);
 int afe_pseudo_port_stop_nowait(u16 port_id);
+int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg);
+int afe_set_lpass_internal_digital_codec_clock(u16 port_id,
+				struct afe_digital_clk_cfg *cfg);
+int q6afe_check_osr_clk_freq(u32 freq);
+
 #endif /* __Q6AFE_V2_H__ */
diff --git a/include/sound/q6afe.h b/include/sound/q6afe.h
index 1e12d48..54ba475 100644
--- a/include/sound/q6afe.h
+++ b/include/sound/q6afe.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h
index a436a6e..5744a43 100644
--- a/include/sound/q6asm-v2.h
+++ b/include/sound/q6asm-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -139,7 +139,7 @@
 	app_cb		       cb;
 	atomic_t	       cmd_state;
 	/* Relative or absolute TS */
-	uint32_t	       time_flag;
+	atomic_t	       time_flag;
 	atomic_t	       nowait_cmd_cnt;
 	void		       *priv;
 	uint32_t               io_mode;
@@ -150,6 +150,8 @@
 	/* idx:1 out port, 0: in port*/
 	struct audio_port_data port[2];
 	wait_queue_head_t      cmd_wait;
+	wait_queue_head_t      time_wait;
+	bool                   perf_mode;
 };
 
 void q6asm_audio_client_free(struct audio_client *ac);
@@ -177,6 +179,9 @@
 int q6asm_open_write(struct audio_client *ac, uint32_t format
 		/*, uint16_t bits_per_sample*/);
 
+int q6asm_open_write_v2(struct audio_client *ac, uint32_t format,
+			uint16_t bits_per_sample);
+
 int q6asm_open_read_write(struct audio_client *ac,
 			uint32_t rd_format,
 			uint32_t wr_format);
@@ -244,6 +249,8 @@
 int q6asm_cfg_dual_mono_aac(struct audio_client *ac,
 			uint16_t sce_left, uint16_t sce_right);
 
+int q6asm_cfg_aac_sel_mix_coef(struct audio_client *ac, uint32_t mix_coeff);
+
 int q6asm_enc_cfg_blk_qcelp(struct audio_client *ac, uint32_t frames_per_buf,
 		uint16_t min_rate, uint16_t max_rate,
 		uint16_t reduced_rate_level, uint16_t rate_modulation_cmd);
@@ -261,8 +268,19 @@
 int q6asm_media_format_block_pcm(struct audio_client *ac,
 			uint32_t rate, uint32_t channels);
 
+int q6asm_media_format_block_pcm_format_support(struct audio_client *ac,
+			uint32_t rate, uint32_t channels,
+			uint16_t bits_per_sample);
+
 int q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac,
-				uint32_t rate, uint32_t channels);
+			uint32_t rate, uint32_t channels,
+			bool use_default_chmap, char *channel_map);
+
+int q6asm_media_format_block_multi_ch_pcm_v2(
+			struct audio_client *ac,
+			uint32_t rate, uint32_t channels,
+			bool use_default_chmap, char *channel_map,
+			uint16_t bits_per_sample);
 
 int q6asm_media_format_block_aac(struct audio_client *ac,
 			struct asm_aac_cfg *cfg);
@@ -296,7 +314,7 @@
 /* Enable Mute/unmute flag */
 int q6asm_set_mute(struct audio_client *ac, int muteflag);
 
-uint64_t q6asm_get_session_time(struct audio_client *ac);
+int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp);
 
 /* Client can set the IO mode to either AIO/SIO mode */
 int q6asm_set_io_mode(struct audio_client *ac, uint32_t mode);
diff --git a/include/sound/q6asm.h b/include/sound/q6asm.h
index 6b4c17b..406407d 100644
--- a/include/sound/q6asm.h
+++ b/include/sound/q6asm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -74,28 +74,30 @@
 /* Enable Sample_Rate/Channel_Mode notification event from Decoder */
 #define SR_CM_NOTIFY_ENABLE	0x0004
 
-#define ASYNC_IO_MODE	0x0002
-#define SYNC_IO_MODE	0x0001
-#define NO_TIMESTAMP    0xFF00
-#define SET_TIMESTAMP   0x0000
+#define TUN_WRITE_IO_MODE 0x0008 /* tunnel read write mode */
+#define TUN_READ_IO_MODE  0x0004 /* tunnel read write mode */
+#define ASYNC_IO_MODE	  0x0002
+#define SYNC_IO_MODE	  0x0001
+#define NO_TIMESTAMP      0xFF00
+#define SET_TIMESTAMP     0x0000
 
 #define SOFT_PAUSE_ENABLE	1
 #define SOFT_PAUSE_DISABLE	0
 
 #define SESSION_MAX	0x08
 
-#define SOFT_PAUSE_PERIOD       30   /* ramp up/down for 30ms    */
+#define SOFT_PAUSE_PERIOD       30   /* ramp up/down for 30ms */
 #define SOFT_PAUSE_STEP_LINEAR  0    /* Step value 0ms or 0us */
-#define SOFT_PAUSE_STEP         2000 /* Step value 2000ms or 2000us */
+#define SOFT_PAUSE_STEP         0    /* Step value 0ms or 0us */
 enum {
 	SOFT_PAUSE_CURVE_LINEAR = 0,
 	SOFT_PAUSE_CURVE_EXP,
 	SOFT_PAUSE_CURVE_LOG,
 };
 
-#define SOFT_VOLUME_PERIOD       30   /* ramp up/down for 30ms    */
+#define SOFT_VOLUME_PERIOD       30   /* ramp up/down for 30ms */
 #define SOFT_VOLUME_STEP_LINEAR  0    /* Step value 0ms or 0us */
-#define SOFT_VOLUME_STEP         2000 /* Step value 2000ms or 2000us */
+#define SOFT_VOLUME_STEP         0    /* Step value 0ms or 0us */
 enum {
 	SOFT_VOLUME_CURVE_LINEAR = 0,
 	SOFT_VOLUME_CURVE_EXP,
@@ -153,6 +155,7 @@
 	struct mutex	       cmd_lock;
 
 	atomic_t		cmd_state;
+	atomic_t		cmd_close_state;
 	atomic_t		time_flag;
 	atomic_t		nowait_cmd_cnt;
 	wait_queue_head_t	cmd_wait;
@@ -270,6 +273,8 @@
 int q6asm_cfg_dual_mono_aac(struct audio_client *ac,
 			uint16_t sce_left, uint16_t sce_right);
 
+int q6asm_cfg_aac_sel_mix_coef(struct audio_client *ac, uint32_t mix_coeff);
+
 int q6asm_set_encdec_chan_map(struct audio_client *ac,
 			uint32_t num_channels);
 
@@ -329,7 +334,7 @@
 /* Enable Mute/unmute flag */
 int q6asm_set_mute(struct audio_client *ac, int muteflag);
 
-uint64_t q6asm_get_session_time(struct audio_client *ac);
+int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp);
 
 /* Client can set the IO mode to either AIO/SIO mode */
 int q6asm_set_io_mode(struct audio_client *ac, uint32_t mode);
diff --git a/include/sound/q6audio-v2.h b/include/sound/q6audio-v2.h
index 1a5dce1..fd6a490 100644
--- a/include/sound/q6audio-v2.h
+++ b/include/sound/q6audio-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -21,6 +21,8 @@
 
 int q6audio_validate_port(u16 port_id);
 
+int q6audio_is_digital_pcm_interface(u16 port_id);
+
 int q6audio_get_port_id(u16 port_id);
 
 #endif
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 17fef15..2b66a2e 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -2,7 +2,7 @@
  * linux/sound/soc-dai.h -- ALSA SoC Layer
  *
  * Copyright:	2005-2008 Wolfson Microelectronics. PLC.
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
diff --git a/include/trace/events/kmem.h b/include/trace/events/kmem.h
index 5f889f1..a1da44f 100644
--- a/include/trace/events/kmem.h
+++ b/include/trace/events/kmem.h
@@ -302,6 +302,199 @@
 		__entry->alloc_migratetype == __entry->fallback_migratetype)
 );
 
+
+DECLARE_EVENT_CLASS(ion_alloc,
+
+	TP_PROTO(const char *client_name,
+		 const char *heap_name,
+		 size_t len,
+		 unsigned int mask,
+		 unsigned int flags),
+
+	TP_ARGS(client_name, heap_name, len, mask, flags),
+
+	TP_STRUCT__entry(
+		__field(const char *,	client_name)
+		__field(const char *,	heap_name)
+		__field(size_t,		len)
+		__field(unsigned int,	mask)
+		__field(unsigned int,	flags)
+	),
+
+	TP_fast_assign(
+		__entry->client_name	= client_name;
+		__entry->heap_name	= heap_name;
+		__entry->len		= len;
+		__entry->mask		= mask;
+		__entry->flags		= flags;
+	),
+
+	TP_printk("client_name=%s heap_name=%s len=%zu mask=0x%x flags=0x%x",
+		__entry->client_name,
+		__entry->heap_name,
+		__entry->len,
+		__entry->mask,
+		__entry->flags)
+);
+
+DEFINE_EVENT(ion_alloc, ion_alloc_buffer_start,
+
+	TP_PROTO(const char *client_name,
+		 const char *heap_name,
+		 size_t len,
+		 unsigned int mask,
+		 unsigned int flags),
+
+	TP_ARGS(client_name, heap_name, len, mask, flags)
+);
+
+DEFINE_EVENT(ion_alloc, ion_alloc_buffer_end,
+
+	TP_PROTO(const char *client_name,
+		 const char *heap_name,
+		 size_t len,
+		 unsigned int mask,
+		 unsigned int flags),
+
+	TP_ARGS(client_name, heap_name, len, mask, flags)
+);
+
+DECLARE_EVENT_CLASS(ion_alloc_error,
+
+	TP_PROTO(const char *client_name,
+		 const char *heap_name,
+		 size_t len,
+		 unsigned int mask,
+		 unsigned int flags,
+		 long error),
+
+	TP_ARGS(client_name, heap_name, len, mask, flags, error),
+
+	TP_STRUCT__entry(
+		__field(const char *,	client_name)
+		__field(const char *,	heap_name)
+		__field(size_t,		len)
+		__field(unsigned int,	mask)
+		__field(unsigned int,	flags)
+		__field(long,		error)
+	),
+
+	TP_fast_assign(
+		__entry->client_name	= client_name;
+		__entry->heap_name	= heap_name;
+		__entry->len		= len;
+		__entry->mask		= mask;
+		__entry->flags		= flags;
+		__entry->error		= error;
+	),
+
+	TP_printk(
+	"client_name=%s heap_name=%s len=%zu mask=0x%x flags=0x%x error=%ld",
+		__entry->client_name,
+		__entry->heap_name,
+		__entry->len,
+		__entry->mask,
+		__entry->flags,
+		__entry->error)
+);
+
+
+DEFINE_EVENT(ion_alloc_error, ion_alloc_buffer_fallback,
+
+	TP_PROTO(const char *client_name,
+		 const char *heap_name,
+		 size_t len,
+		 unsigned int mask,
+		 unsigned int flags,
+		 long error),
+
+	TP_ARGS(client_name, heap_name, len, mask, flags, error)
+);
+
+DEFINE_EVENT(ion_alloc_error, ion_alloc_buffer_fail,
+
+	TP_PROTO(const char *client_name,
+		 const char *heap_name,
+		 size_t len,
+		 unsigned int mask,
+		 unsigned int flags,
+		 long error),
+
+	TP_ARGS(client_name, heap_name, len, mask, flags, error)
+);
+
+
+DECLARE_EVENT_CLASS(alloc_retry,
+
+	TP_PROTO(int tries),
+
+	TP_ARGS(tries),
+
+	TP_STRUCT__entry(
+		__field(int, tries)
+	),
+
+	TP_fast_assign(
+		__entry->tries = tries;
+	),
+
+	TP_printk("tries=%d",
+		__entry->tries)
+);
+
+DEFINE_EVENT(alloc_retry, ion_cp_alloc_retry,
+
+	TP_PROTO(int tries),
+
+	TP_ARGS(tries)
+);
+
+DEFINE_EVENT(alloc_retry, migrate_retry,
+
+	TP_PROTO(int tries),
+
+	TP_ARGS(tries)
+);
+
+DEFINE_EVENT(alloc_retry, dma_alloc_contiguous_retry,
+
+	TP_PROTO(int tries),
+
+	TP_ARGS(tries)
+);
+
+DECLARE_EVENT_CLASS(migrate_pages,
+
+	TP_PROTO(int mode),
+
+	TP_ARGS(mode),
+
+	TP_STRUCT__entry(
+		__field(int, mode)
+	),
+
+	TP_fast_assign(
+		__entry->mode = mode;
+	),
+
+	TP_printk("mode=%d",
+		__entry->mode)
+);
+
+DEFINE_EVENT(migrate_pages, migrate_pages_start,
+
+	TP_PROTO(int mode),
+
+	TP_ARGS(mode)
+);
+
+DEFINE_EVENT(migrate_pages, migrate_pages_end,
+
+	TP_PROTO(int mode),
+
+	TP_ARGS(mode)
+);
+
 #endif /* _TRACE_KMEM_H */
 
 /* This part must be outside protection */
diff --git a/include/trace/events/sync.h b/include/trace/events/sync.h
new file mode 100644
index 0000000..f31bc63
--- /dev/null
+++ b/include/trace/events/sync.h
@@ -0,0 +1,82 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM sync
+
+#if !defined(_TRACE_SYNC_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_SYNC_H
+
+#include <linux/sync.h>
+#include <linux/tracepoint.h>
+
+TRACE_EVENT(sync_timeline,
+	    TP_PROTO(struct sync_timeline *timeline),
+
+	    TP_ARGS(timeline),
+
+	    TP_STRUCT__entry(
+		    __string(name, timeline->name)
+		    __array(char, value, 32)
+		    ),
+
+	    TP_fast_assign(
+		    __assign_str(name, timeline->name);
+		    if (timeline->ops->timeline_value_str) {
+			    timeline->ops->timeline_value_str(timeline,
+							      __entry->value,
+							      sizeof(__entry->value));
+		    } else {
+			    __entry->value[0] = '\0';
+		    }
+		    ),
+
+	    TP_printk("name=%s value=%s", __get_str(name), __entry->value)
+);
+
+TRACE_EVENT(sync_wait,
+	    TP_PROTO(struct sync_fence *fence, int begin),
+
+	    TP_ARGS(fence, begin),
+
+	    TP_STRUCT__entry(
+		    __string(name, fence->name)
+		    __field(s32, status)
+		    __field(u32, begin)
+		    ),
+
+	    TP_fast_assign(
+		    __assign_str(name, fence->name);
+		    __entry->status = fence->status;
+		    __entry->begin = begin;
+		    ),
+
+	    TP_printk("%s name=%s state=%d", __entry->begin ? "begin" : "end",
+		      __get_str(name), __entry->status)
+);
+
+TRACE_EVENT(sync_pt,
+	    TP_PROTO(struct sync_pt *pt),
+
+	    TP_ARGS(pt),
+
+	    TP_STRUCT__entry(
+		    __string(timeline, pt->parent->name)
+		    __array(char, value, 32)
+		    ),
+
+	    TP_fast_assign(
+		    __assign_str(timeline, pt->parent->name);
+		    if (pt->parent->ops->pt_value_str) {
+			    pt->parent->ops->pt_value_str(pt,
+							__entry->value,
+							sizeof(__entry->value));
+		    } else {
+			    __entry->value[0] = '\0';
+		    }
+		    ),
+
+	    TP_printk("name=%s value=%s", __get_str(timeline), __entry->value)
+	);
+
+#endif /* if !defined(_TRACE_SYNC_H) || defined(TRACE_HEADER_MULTI_READ) */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/include/uapi/media/msmb_generic_buf_mgr.h b/include/uapi/media/msmb_generic_buf_mgr.h
new file mode 100644
index 0000000..8368e26
--- /dev/null
+++ b/include/uapi/media/msmb_generic_buf_mgr.h
@@ -0,0 +1,19 @@
+#ifndef __UAPI_MEDIA_MSMB_BUF_MNGR_H__
+#define __UAPI_MEDIA_MSMB_BUF_MNGR_H__
+
+#define VIDIOC_MSM_BUF_MNGR_GET_BUF \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 33, struct msm_buf_mngr_info *)
+
+#define VIDIOC_MSM_BUF_MNGR_PUT_BUF \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 34, struct msm_buf_mngr_info *)
+
+#define VIDIOC_MSM_BUF_MNGR_BUF_DONE \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 35, struct msm_buf_mngr_info *)
+
+struct msm_buf_mngr_info {
+	uint32_t session_id;
+	uint32_t stream_id;
+	uint32_t index;
+};
+
+#endif
diff --git a/kernel/exit.c b/kernel/exit.c
index d8bd3b42..6096e80 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -639,6 +639,7 @@
 {
 	struct mm_struct *mm = tsk->mm;
 	struct core_state *core_state;
+	int mm_released;
 
 	mm_release(tsk, mm);
 	if (!mm)
@@ -683,7 +684,10 @@
 	enter_lazy_tlb(mm, current);
 	task_unlock(tsk);
 	mm_update_next_owner(mm);
-	mmput(mm);
+
+	mm_released = mmput(mm);
+	if (mm_released)
+		set_tsk_thread_flag(tsk, TIF_MM_RELEASED);
 }
 
 /*
diff --git a/kernel/fork.c b/kernel/fork.c
index c0bf8c7..0de735c 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -581,8 +581,9 @@
 /*
  * Decrement the use count and release all resources for an mm.
  */
-void mmput(struct mm_struct *mm)
+int mmput(struct mm_struct *mm)
 {
+	int mm_freed = 0;
 	might_sleep();
 
 	if (atomic_dec_and_test(&mm->mm_users)) {
@@ -600,7 +601,9 @@
 		if (mm->binfmt)
 			module_put(mm->binfmt->module);
 		mmdrop(mm);
+		mm_freed = 1;
 	}
+	return mm_freed;
 }
 EXPORT_SYMBOL_GPL(mmput);
 
diff --git a/kernel/panic.c b/kernel/panic.c
index 8c6babc..4716d16 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -23,6 +23,7 @@
 #include <linux/init.h>
 #include <linux/nmi.h>
 #include <linux/dmi.h>
+#include <linux/coresight.h>
 
 #define PANIC_TIMER_STEP 100
 #define PANIC_BLINK_SPD 18
@@ -80,6 +81,7 @@
 	long i, i_next = 0;
 	int state = 0;
 
+	coresight_abort();
 	/*
 	 * Disable local interrupts. This will prevent panic_smp_self_stop
 	 * from deadlocking the first cpu that invokes the panic, since
diff --git a/kernel/sys.c b/kernel/sys.c
index e7006eb..39791be 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1179,15 +1179,16 @@
  * Work around broken programs that cannot handle "Linux 3.0".
  * Instead we map 3.x to 2.6.40+x, so e.g. 3.0 would be 2.6.40
  */
-static int override_release(char __user *release, int len)
+static int override_release(char __user *release, size_t len)
 {
 	int ret = 0;
-	char buf[65];
 
 	if (current->personality & UNAME26) {
-		char *rest = UTS_RELEASE;
+		const char *rest = UTS_RELEASE;
+		char buf[65] = { 0 };
 		int ndots = 0;
 		unsigned v;
+		size_t copy;
 
 		while (*rest) {
 			if (*rest == '.' && ++ndots >= 3)
@@ -1197,8 +1198,9 @@
 			rest++;
 		}
 		v = ((LINUX_VERSION_CODE >> 8) & 0xff) + 40;
-		snprintf(buf, len, "2.6.%u%s", v, rest);
-		ret = copy_to_user(release, buf, len);
+		copy = min(sizeof(buf), max_t(size_t, 1, len));
+		copy = scnprintf(buf, copy, "2.6.%u%s", v, rest);
+		ret = copy_to_user(release, buf, copy + 1);
 	}
 	return ret;
 }
diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c
index d42c279..acb60be 100644
--- a/kernel/sysctl_binary.c
+++ b/kernel/sysctl_binary.c
@@ -524,6 +524,7 @@
 	{ CTL_INT,	NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN,	"accept_ra_rt_info_max_plen" },
 	{ CTL_INT,	NET_IPV6_PROXY_NDP,			"proxy_ndp" },
 	{ CTL_INT,	NET_IPV6_ACCEPT_SOURCE_ROUTE,		"accept_source_route" },
+	{ CTL_INT,	NET_IPV6_ACCEPT_RA_PREFIX_ROUTE,	"accept_ra_prefix_route" },
 	{}
 };
 
diff --git a/lib/memory_alloc.c b/lib/memory_alloc.c
index d931e14..cc7424f 100644
--- a/lib/memory_alloc.c
+++ b/lib/memory_alloc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/lib/qmi_encdec.c b/lib/qmi_encdec.c
index 40273d0..3f618cb 100644
--- a/lib/qmi_encdec.c
+++ b/lib/qmi_encdec.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
@@ -82,7 +82,7 @@
 
 static int _qmi_kernel_encode(struct elem_info *ei_array,
 			      void *out_buf, void *in_c_struct,
-			      int enc_level);
+			      uint32_t out_buf_len, int enc_level);
 
 static int _qmi_kernel_decode(struct elem_info *ei_array,
 			      void *out_c_struct,
@@ -90,6 +90,71 @@
 			      int dec_level);
 
 /**
+ * qmi_calc_max_msg_len() - Calculate the maximum length of a QMI message
+ * @ei_array: Struct info array describing the structure.
+ * @level: Level to identify the depth of the nested structures.
+ *
+ * @return: expected maximum length of the QMI message or 0 on failure.
+ */
+static int qmi_calc_max_msg_len(struct elem_info *ei_array,
+				int level)
+{
+	int max_msg_len = 0;
+	struct elem_info *temp_ei;
+
+	if (!ei_array)
+		return max_msg_len;
+
+	for (temp_ei = ei_array; temp_ei->data_type != QMI_EOTI; temp_ei++) {
+		/* Flag to identify the optional element is not encoded */
+		if (temp_ei->data_type == QMI_OPT_FLAG)
+			continue;
+
+		if (temp_ei->data_type == QMI_DATA_LEN) {
+			max_msg_len += (temp_ei->elem_size == sizeof(uint8_t) ?
+					sizeof(uint8_t) : sizeof(uint16_t));
+			continue;
+		} else if (temp_ei->data_type == QMI_STRUCT) {
+			max_msg_len += qmi_calc_max_msg_len(temp_ei->ei_array,
+							    (level + 1));
+		} else {
+			max_msg_len += (temp_ei->elem_len * temp_ei->elem_size);
+		}
+
+		/*
+		 * Type & Length info. not prepended for elements in the
+		 * nested structure.
+		 */
+		if (level == 1)
+			max_msg_len += (TLV_TYPE_SIZE + TLV_LEN_SIZE);
+	}
+	return max_msg_len;
+}
+
+/**
+ * qmi_verify_max_msg_len() - Verify the maximum length of a QMI message
+ * @desc: Pointer to structure descriptor.
+ *
+ * @return: true if the maximum message length embedded in structure
+ *          descriptor matches the calculated value, else false.
+ */
+bool qmi_verify_max_msg_len(struct msg_desc *desc)
+{
+	int calc_max_msg_len;
+
+	if (!desc)
+		return false;
+
+	calc_max_msg_len = qmi_calc_max_msg_len(desc->ei_array, 1);
+	if (calc_max_msg_len != desc->max_msg_len) {
+		pr_err("%s: Calc. len %d != Passed len %d\n",
+			__func__, calc_max_msg_len, desc->max_msg_len);
+		return false;
+	}
+	return true;
+}
+
+/**
  * qmi_kernel_encode() - Encode to QMI message wire format
  * @desc: Pointer to structure descriptor.
  * @out_buf: Buffer to hold the encoded QMI message.
@@ -103,6 +168,7 @@
 		      void *in_c_struct)
 {
 	int enc_level = 1;
+	int ret, calc_max_msg_len;
 
 	if (!desc || !desc->ei_array)
 		return -EINVAL;
@@ -113,8 +179,14 @@
 	if (desc->max_msg_len < out_buf_len)
 		return -ETOOSMALL;
 
-	return _qmi_kernel_encode(desc->ei_array, out_buf,
-				  in_c_struct, enc_level);
+	ret = _qmi_kernel_encode(desc->ei_array, out_buf,
+				 in_c_struct, out_buf_len, enc_level);
+	if (ret == -ETOOSMALL) {
+		calc_max_msg_len = qmi_calc_max_msg_len(desc->ei_array, 1);
+		pr_err("%s: Calc. len %d != Out buf len %d\n",
+			__func__, calc_max_msg_len, out_buf_len);
+	}
+	return ret;
 }
 EXPORT_SYMBOL(qmi_kernel_encode);
 
@@ -152,6 +224,7 @@
  * @buf_dst: Buffer to store the encoded information.
  * @buf_src: Buffer containing the elements to be encoded.
  * @elem_len: Number of elements, in the buf_src, to be encoded.
+ * @out_buf_len: Available space in the encode buffer.
  * @enc_level: Depth of the nested structure from the main structure.
  *
  * @return: Mumber of bytes of encoded information, on success.
@@ -165,14 +238,16 @@
  */
 static int qmi_encode_struct_elem(struct elem_info *ei_array,
 				  void *buf_dst, void *buf_src,
-				  uint32_t elem_len, int enc_level)
+				  uint32_t elem_len, uint32_t out_buf_len,
+				  int enc_level)
 {
 	int i, rc, encoded_bytes = 0;
 	struct elem_info *temp_ei = ei_array;
 
 	for (i = 0; i < elem_len; i++) {
-		rc = _qmi_kernel_encode(temp_ei->ei_array,
-					buf_dst, buf_src, enc_level);
+		rc = _qmi_kernel_encode(temp_ei->ei_array, buf_dst, buf_src,
+					(out_buf_len - encoded_bytes),
+					enc_level);
 		if (rc < 0) {
 			pr_err("%s: STRUCT Encode failure\n", __func__);
 			return rc;
@@ -214,6 +289,7 @@
  * @ei_array: Struct info array describing the structure to be encoded.
  * @out_buf: Buffer to hold the encoded QMI message.
  * @in_c_struct: Pointer to the C structure to be encoded.
+ * @out_buf_len: Available space in the encode buffer.
  * @enc_level: Encode level to indicate the depth of the nested structure,
  *             within the main structure, being encoded.
  *
@@ -222,7 +298,7 @@
  */
 static int _qmi_kernel_encode(struct elem_info *ei_array,
 			      void *out_buf, void *in_c_struct,
-			      int enc_level)
+			      uint32_t out_buf_len, int enc_level)
 {
 	struct elem_info *temp_ei = ei_array;
 	uint8_t opt_flag_value = 0;
@@ -268,6 +344,13 @@
 			memcpy(&data_len_value, buf_src, temp_ei->elem_size);
 			data_len_sz = temp_ei->elem_size == sizeof(uint8_t) ?
 					sizeof(uint8_t) : sizeof(uint16_t);
+			/* Check to avoid out of range buffer access */
+			if ((data_len_sz + encoded_bytes + TLV_LEN_SIZE +
+			    TLV_TYPE_SIZE) > out_buf_len) {
+				pr_err("%s: Too Small Buffer @DATA_LEN\n",
+					__func__);
+				return -ETOOSMALL;
+			}
 			rc = qmi_encode_basic_elem(buf_dst, &data_len_value,
 						   1, data_len_sz);
 			if (data_len_value) {
@@ -285,6 +368,14 @@
 		case QMI_UNSIGNED_8_BYTE:
 		case QMI_SIGNED_2_BYTE_ENUM:
 		case QMI_SIGNED_4_BYTE_ENUM:
+			/* Check to avoid out of range buffer access */
+			if (((data_len_value * temp_ei->elem_size) +
+			    encoded_bytes + TLV_LEN_SIZE + TLV_TYPE_SIZE) >
+			    out_buf_len) {
+				pr_err("%s: Too Small Buffer @data_type:%d\n",
+					__func__, temp_ei->data_type);
+				return -ETOOSMALL;
+			}
 			rc = qmi_encode_basic_elem(buf_dst, buf_src,
 				data_len_value, temp_ei->elem_size);
 			QMI_ENCODE_LOG_ELEM(enc_level, data_len_value,
@@ -295,7 +386,8 @@
 
 		case QMI_STRUCT:
 			rc = qmi_encode_struct_elem(temp_ei, buf_dst, buf_src,
-				data_len_value, (enc_level + 1));
+				data_len_value, (out_buf_len - encoded_bytes),
+				(enc_level + 1));
 			if (rc < 0)
 				return rc;
 			UPDATE_ENCODE_VARIABLES(temp_ei, buf_dst,
diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c
index 1967297..f2aa5de 100644
--- a/lib/spinlock_debug.c
+++ b/lib/spinlock_debug.c
@@ -106,24 +106,28 @@
 static void __spin_lock_debug(raw_spinlock_t *lock)
 {
 	u64 i;
-	u64 loops = loops_per_jiffy * HZ;
-	int print_once = 1;
+	u64 loops = (loops_per_jiffy * HZ) >> 4;
 
-	for (;;) {
-		for (i = 0; i < loops; i++) {
-			if (arch_spin_trylock(&lock->raw_lock))
-				return;
-			__delay(1);
-		}
-		/* lockup suspected: */
-		if (print_once) {
-			print_once = 0;
-			spin_dump(lock, "lockup");
-#ifdef CONFIG_SMP
-			trigger_all_cpu_backtrace();
-#endif
-		}
+	for (i = 0; i < loops; i++) {
+		if (arch_spin_trylock(&lock->raw_lock))
+			return;
+		__delay(1);
 	}
+	/* lockup suspected: */
+	spin_dump(lock, "lockup");
+#ifdef CONFIG_SMP
+	trigger_all_cpu_backtrace();
+#endif
+
+	/*
+	 * The trylock above was causing a livelock.  Give the lower level arch
+	 * specific lock code a chance to acquire the lock. We have already
+	 * printed a warning/backtrace at this point. The non-debug arch
+	 * specific code might actually succeed in acquiring the lock.  If it is
+	 * not successful, the end-result is the same - there is no forward
+	 * progress.
+	 */
+	arch_spin_lock(&lock->raw_lock);
 }
 
 void do_raw_spin_lock(raw_spinlock_t *lock)
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index f5dfe0c..08b5ae7 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -857,6 +857,7 @@
  *       correctness of the format string and va_list arguments.
  * - 'K' For a kernel pointer that should be hidden from unprivileged users
  * - 'NF' For a netdev_features_t
+ * - 'a' For a phys_addr_t type and its derivative types (passed by reference)
  *
  * Note: The difference between 'S' and 'F' is that on ia64 and ppc64
  * function pointers are really function descriptors, which contain a
@@ -941,6 +942,12 @@
 			return netdev_feature_string(buf, end, ptr, spec);
 		}
 		break;
+	case 'a':
+		spec.flags |= SPECIAL | SMALL | ZEROPAD;
+		spec.field_width = sizeof(phys_addr_t) * 2 + 2;
+		spec.base = 16;
+		return number(buf, end,
+			      (unsigned long long) *((phys_addr_t *)ptr), spec);
 	}
 	spec.flags |= SMALL;
 	if (spec.field_width == -1) {
diff --git a/mm/compaction.c b/mm/compaction.c
index da7d35e..353f1c5 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -750,6 +750,7 @@
 	struct zoneref *z;
 	struct zone *zone;
 	int rc = COMPACT_SKIPPED;
+	int alloc_flags = 0;
 
 	/*
 	 * Check whether it is worth even starting compaction. The order check is
@@ -761,6 +762,10 @@
 
 	count_vm_event(COMPACTSTALL);
 
+#ifdef CONFIG_CMA
+	if (allocflags_to_migratetype(gfp_mask) == MIGRATE_MOVABLE)
+		alloc_flags |= ALLOC_CMA;
+#endif
 	/* Compact each zone in the list */
 	for_each_zone_zonelist_nodemask(zone, z, zonelist, high_zoneidx,
 								nodemask) {
@@ -770,7 +775,8 @@
 		rc = max(status, rc);
 
 		/* If a normal allocation would succeed, stop compacting */
-		if (zone_watermark_ok(zone, order, low_wmark_pages(zone), 0, 0))
+		if (zone_watermark_ok(zone, order, low_wmark_pages(zone), 0,
+				      alloc_flags))
 			break;
 	}
 
diff --git a/mm/internal.h b/mm/internal.h
index aee4761..8c6fd44 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -342,3 +342,17 @@
 extern u64 hwpoison_filter_flags_value;
 extern u64 hwpoison_filter_memcg;
 extern u32 hwpoison_filter_enable;
+
+/* The ALLOC_WMARK bits are used as an index to zone->watermark */
+#define ALLOC_WMARK_MIN		WMARK_MIN
+#define ALLOC_WMARK_LOW		WMARK_LOW
+#define ALLOC_WMARK_HIGH	WMARK_HIGH
+#define ALLOC_NO_WATERMARKS	0x04 /* don't check watermarks at all */
+
+/* Mask to get the watermark bits */
+#define ALLOC_WMARK_MASK	(ALLOC_NO_WATERMARKS-1)
+
+#define ALLOC_HARDER		0x10 /* try to alloc harder */
+#define ALLOC_HIGH		0x20 /* __GFP_HIGH set */
+#define ALLOC_CPUSET		0x40 /* check for correct cpuset */
+#define ALLOC_CMA		0x80 /* allow allocations from CMA areas */
diff --git a/mm/madvise.c b/mm/madvise.c
index 1ccbba5..55f645c 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -13,6 +13,7 @@
 #include <linux/hugetlb.h>
 #include <linux/sched.h>
 #include <linux/ksm.h>
+#include <linux/file.h>
 
 /*
  * Any behaviour which results in changes to the vma->vm_flags needs to
@@ -203,14 +204,16 @@
 	struct address_space *mapping;
 	loff_t offset, endoff;
 	int error;
+	struct file *f;
 
 	*prev = NULL;	/* tell sys_madvise we drop mmap_sem */
 
 	if (vma->vm_flags & (VM_LOCKED|VM_NONLINEAR|VM_HUGETLB))
 		return -EINVAL;
 
-	if (!vma->vm_file || !vma->vm_file->f_mapping
-		|| !vma->vm_file->f_mapping->host) {
+	f = vma->vm_file;
+
+	if (!f || !f->f_mapping || !f->f_mapping->host) {
 			return -EINVAL;
 	}
 
@@ -224,9 +227,16 @@
 	endoff = (loff_t)(end - vma->vm_start - 1)
 			+ ((loff_t)vma->vm_pgoff << PAGE_SHIFT);
 
-	/* vmtruncate_range needs to take i_mutex */
+	/*
+	 * vmtruncate_range may need to take i_mutex.  We need to
+	 * explicitly grab a reference because the vma (and hence the
+	 * vma's reference to the file) can go away as soon as we drop
+	 * mmap_sem.
+	 */
+	get_file(f);
 	up_read(&current->mm->mmap_sem);
 	error = vmtruncate_range(mapping->host, offset, endoff);
+	fput(f);
 	down_read(&current->mm->mmap_sem);
 	return error;
 }
diff --git a/mm/memory.c b/mm/memory.c
index c130853..2111354 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2913,7 +2913,7 @@
 	entry = pte_to_swp_entry(orig_pte);
 	if (unlikely(non_swap_entry(entry))) {
 		if (is_migration_entry(entry)) {
-#ifdef CONFIG_DMA_CMA
+#ifdef CONFIG_CMA
 			/*
 			 * FIXME: mszyprow: cruel, brute-force method for
 			 * letting cma/migration to finish it's job without
diff --git a/mm/migrate.c b/mm/migrate.c
index 1107238..79a791f 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -34,6 +34,7 @@
 #include <linux/syscalls.h>
 #include <linux/hugetlb.h>
 #include <linux/gfp.h>
+#include <trace/events/kmem.h>
 
 #include <asm/tlbflush.h>
 
@@ -974,6 +975,7 @@
 	int swapwrite = current->flags & PF_SWAPWRITE;
 	int rc;
 
+	trace_migrate_pages_start(mode);
 	if (!swapwrite)
 		current->flags |= PF_SWAPWRITE;
 
@@ -992,6 +994,7 @@
 				goto out;
 			case -EAGAIN:
 				retry++;
+				trace_migrate_retry(retry);
 				break;
 			case 0:
 				break;
@@ -1007,6 +1010,7 @@
 	if (!swapwrite)
 		current->flags &= ~PF_SWAPWRITE;
 
+	trace_migrate_pages_end(mode);
 	if (rc)
 		return rc;
 
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index bd3f0f3..d6dd07a 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -561,7 +561,8 @@
 		if (page_is_guard(buddy)) {
 			clear_page_guard_flag(buddy);
 			set_page_private(page, 0);
-			__mod_zone_page_state(zone, NR_FREE_PAGES, 1 << order);
+			__mod_zone_freepage_state(zone, 1 << order,
+						  migratetype);
 		} else {
 			list_del(&buddy->lru);
 			zone->free_area[order].nr_free--;
@@ -643,6 +644,7 @@
 	int migratetype = 0;
 	int batch_free = 0;
 	int to_free = count;
+	int mt = 0;
 
 	spin_lock(&zone->lock);
 	zone->all_unreclaimable = 0;
@@ -672,11 +674,15 @@
 
 		do {
 			page = list_entry(list->prev, struct page, lru);
+			mt = get_pageblock_migratetype(page);
 			/* must delete as __free_one_page list manipulates */
 			list_del(&page->lru);
 			/* MIGRATE_MOVABLE list may include MIGRATE_RESERVEs */
 			__free_one_page(page, zone, 0, page_private(page));
 			trace_mm_page_pcpu_drain(page, 0, page_private(page));
+			if (is_migrate_cma(mt))
+				__mod_zone_page_state(zone,
+				NR_FREE_CMA_PAGES, 1);
 		} while (--to_free && --batch_free && !list_empty(list));
 	}
 	__mod_zone_page_state(zone, NR_FREE_PAGES, count);
@@ -691,7 +697,8 @@
 	zone->pages_scanned = 0;
 
 	__free_one_page(page, zone, order, migratetype);
-	__mod_zone_page_state(zone, NR_FREE_PAGES, 1 << order);
+	if (unlikely(migratetype != MIGRATE_ISOLATE))
+		__mod_zone_freepage_state(zone, 1 << order, migratetype);
 	spin_unlock(&zone->lock);
 }
 
@@ -819,7 +826,8 @@
 			set_page_guard_flag(&page[size]);
 			set_page_private(&page[size], high);
 			/* Guard pages are not available for any usage */
-			__mod_zone_page_state(zone, NR_FREE_PAGES, -(1 << high));
+			__mod_zone_freepage_state(zone, -(1 << high),
+						  migratetype);
 			continue;
 		}
 #endif
@@ -918,6 +926,11 @@
 	[MIGRATE_ISOLATE]     = { MIGRATE_RESERVE }, /* Never used */
 };
 
+int *get_migratetype_fallbacks(int mtype)
+{
+	return fallbacks[mtype];
+}
+
 /*
  * Move the free pages in a range to the free lists of the requested type.
  * Note that start_page and end_pages are not aligned on a pageblock
@@ -1108,6 +1121,37 @@
 	return page;
 }
 
+static struct page *__rmqueue_cma(struct zone *zone, unsigned int order,
+							int migratetype)
+{
+	struct page *page = 0;
+#ifdef CONFIG_CMA
+	if (migratetype == MIGRATE_MOVABLE && !zone->cma_alloc)
+		page = __rmqueue_smallest(zone, order, MIGRATE_CMA);
+	else
+#endif
+retry_reserve :
+		page = __rmqueue_smallest(zone, order, migratetype);
+
+
+	if (unlikely(!page) && migratetype != MIGRATE_RESERVE) {
+		page = __rmqueue_fallback(zone, order, migratetype);
+
+		/*
+		 * Use MIGRATE_RESERVE rather than fail an allocation. goto
+		 * is used because __rmqueue_smallest is an inline function
+		 * and we want just one call site
+		 */
+		if (!page) {
+			migratetype = MIGRATE_RESERVE;
+			goto retry_reserve;
+		}
+	}
+
+	trace_mm_page_alloc_zone_locked(page, order, migratetype);
+	return page;
+}
+
 /*
  * Obtain a specified number of elements from the buddy allocator, all under
  * a single hold of the lock, for efficiency.  Add them to the supplied list.
@@ -1115,13 +1159,17 @@
  */
 static int rmqueue_bulk(struct zone *zone, unsigned int order,
 			unsigned long count, struct list_head *list,
-			int migratetype, int cold)
+			int migratetype, int cold, int cma)
 {
 	int mt = migratetype, i;
 
 	spin_lock(&zone->lock);
 	for (i = 0; i < count; ++i) {
-		struct page *page = __rmqueue(zone, order, migratetype);
+		struct page *page;
+		if (cma)
+			page = __rmqueue_cma(zone, order, migratetype);
+		else
+			page = __rmqueue(zone, order, migratetype);
 		if (unlikely(page == NULL))
 			break;
 
@@ -1145,6 +1193,9 @@
 		}
 		set_page_private(page, mt);
 		list = &page->lru;
+		if (is_migrate_cma(mt))
+			__mod_zone_page_state(zone, NR_FREE_CMA_PAGES,
+					      -(1 << order));
 	}
 	__mod_zone_page_state(zone, NR_FREE_PAGES, -(i << order));
 	spin_unlock(&zone->lock);
@@ -1322,7 +1373,8 @@
 	 * excessively into the page allocator
 	 */
 	if (migratetype >= MIGRATE_PCPTYPES) {
-		if (unlikely(migratetype == MIGRATE_ISOLATE)) {
+		if (unlikely(migratetype == MIGRATE_ISOLATE) ||
+			     is_migrate_cma(migratetype)) {
 			free_one_page(zone, page, 0, migratetype);
 			goto out;
 		}
@@ -1418,7 +1470,9 @@
 	list_del(&page->lru);
 	zone->free_area[order].nr_free--;
 	rmv_page_order(page);
-	__mod_zone_page_state(zone, NR_FREE_PAGES, -(1UL << order));
+
+	if (unlikely(mt != MIGRATE_ISOLATE))
+		__mod_zone_freepage_state(zone, -(1UL << order), mt);
 
 	/* Split into individual pages */
 	set_page_refcounted(page);
@@ -1462,7 +1516,8 @@
 		if (list_empty(list)) {
 			pcp->count += rmqueue_bulk(zone, 0,
 					pcp->batch, list,
-					migratetype, cold);
+					migratetype, cold,
+					gfp_flags & __GFP_CMA);
 			if (unlikely(list_empty(list)))
 				goto failed;
 		}
@@ -1489,11 +1544,15 @@
 			WARN_ON_ONCE(order > 1);
 		}
 		spin_lock_irqsave(&zone->lock, flags);
-		page = __rmqueue(zone, order, migratetype);
+		if (gfp_flags & __GFP_CMA)
+			page = __rmqueue_cma(zone, order, migratetype);
+		else
+			page = __rmqueue(zone, order, migratetype);
 		spin_unlock(&zone->lock);
 		if (!page)
 			goto failed;
-		__mod_zone_page_state(zone, NR_FREE_PAGES, -(1 << order));
+		__mod_zone_freepage_state(zone, -(1 << order),
+					  get_pageblock_migratetype(page));
 	}
 
 	__count_zone_vm_events(PGALLOC, zone, 1 << order);
@@ -1510,19 +1569,6 @@
 	return NULL;
 }
 
-/* The ALLOC_WMARK bits are used as an index to zone->watermark */
-#define ALLOC_WMARK_MIN		WMARK_MIN
-#define ALLOC_WMARK_LOW		WMARK_LOW
-#define ALLOC_WMARK_HIGH	WMARK_HIGH
-#define ALLOC_NO_WATERMARKS	0x04 /* don't check watermarks at all */
-
-/* Mask to get the watermark bits */
-#define ALLOC_WMARK_MASK	(ALLOC_NO_WATERMARKS-1)
-
-#define ALLOC_HARDER		0x10 /* try to alloc harder */
-#define ALLOC_HIGH		0x20 /* __GFP_HIGH set */
-#define ALLOC_CPUSET		0x40 /* check for correct cpuset */
-
 #ifdef CONFIG_FAIL_PAGE_ALLOC
 
 static struct {
@@ -1617,7 +1663,11 @@
 		min -= min / 2;
 	if (alloc_flags & ALLOC_HARDER)
 		min -= min / 4;
-
+#ifdef CONFIG_CMA
+	/* If allocation can't use CMA areas don't use free CMA pages */
+	if (!(alloc_flags & ALLOC_CMA))
+		free_pages -= zone_page_state(z, NR_FREE_CMA_PAGES);
+#endif
 	if (free_pages <= min + lowmem_reserve)
 		return false;
 	for (o = 0; o < order; o++) {
@@ -2286,7 +2336,10 @@
 		     unlikely(test_thread_flag(TIF_MEMDIE))))
 			alloc_flags |= ALLOC_NO_WATERMARKS;
 	}
-
+#ifdef CONFIG_CMA
+	if (allocflags_to_migratetype(gfp_mask) == MIGRATE_MOVABLE)
+		alloc_flags |= ALLOC_CMA;
+#endif
 	return alloc_flags;
 }
 
@@ -2495,6 +2548,7 @@
 	struct page *page = NULL;
 	int migratetype = allocflags_to_migratetype(gfp_mask);
 	unsigned int cpuset_mems_cookie;
+	int alloc_flags = ALLOC_WMARK_LOW|ALLOC_CPUSET;
 
 	gfp_mask &= gfp_allowed_mask;
 
@@ -2523,9 +2577,13 @@
 	if (!preferred_zone)
 		goto out;
 
+#ifdef CONFIG_CMA
+	if (allocflags_to_migratetype(gfp_mask) == MIGRATE_MOVABLE)
+		alloc_flags |= ALLOC_CMA;
+#endif
 	/* First allocation attempt */
 	page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, nodemask, order,
-			zonelist, high_zoneidx, ALLOC_WMARK_LOW|ALLOC_CPUSET,
+			zonelist, high_zoneidx, alloc_flags,
 			preferred_zone, migratetype);
 	if (unlikely(!page))
 		page = __alloc_pages_slowpath(gfp_mask, order,
@@ -2772,6 +2830,31 @@
 
 #define K(x) ((x) << (PAGE_SHIFT-10))
 
+static void show_migration_types(unsigned char type)
+{
+	static const char types[MIGRATE_TYPES] = {
+		[MIGRATE_UNMOVABLE]	= 'U',
+		[MIGRATE_RECLAIMABLE]	= 'E',
+		[MIGRATE_MOVABLE]	= 'M',
+		[MIGRATE_RESERVE]	= 'R',
+#ifdef CONFIG_CMA
+		[MIGRATE_CMA]		= 'C',
+#endif
+		[MIGRATE_ISOLATE]	= 'I',
+	};
+	char tmp[MIGRATE_TYPES + 1];
+	char *p = tmp;
+	int i;
+
+	for (i = 0; i < MIGRATE_TYPES; i++) {
+		if (type & (1 << i))
+			*p++ = types[i];
+	}
+
+	*p = '\0';
+	printk("(%s) ", tmp);
+}
+
 /*
  * Show free area list (used inside shift_scroll-lock stuff)
  * We also calculate the percentage fragmentation. We do this by counting the
@@ -2806,7 +2889,8 @@
 		" unevictable:%lu"
 		" dirty:%lu writeback:%lu unstable:%lu\n"
 		" free:%lu slab_reclaimable:%lu slab_unreclaimable:%lu\n"
-		" mapped:%lu shmem:%lu pagetables:%lu bounce:%lu\n",
+		" mapped:%lu shmem:%lu pagetables:%lu bounce:%lu\n"
+		" free_cma:%lu\n",
 		global_page_state(NR_ACTIVE_ANON),
 		global_page_state(NR_INACTIVE_ANON),
 		global_page_state(NR_ISOLATED_ANON),
@@ -2823,7 +2907,8 @@
 		global_page_state(NR_FILE_MAPPED),
 		global_page_state(NR_SHMEM),
 		global_page_state(NR_PAGETABLE),
-		global_page_state(NR_BOUNCE));
+		global_page_state(NR_BOUNCE),
+		global_page_state(NR_FREE_CMA_PAGES));
 
 	for_each_populated_zone(zone) {
 		int i;
@@ -2855,6 +2940,7 @@
 			" pagetables:%lukB"
 			" unstable:%lukB"
 			" bounce:%lukB"
+			" free_cma:%lukB"
 			" writeback_tmp:%lukB"
 			" pages_scanned:%lu"
 			" all_unreclaimable? %s"
@@ -2884,6 +2970,7 @@
 			K(zone_page_state(zone, NR_PAGETABLE)),
 			K(zone_page_state(zone, NR_UNSTABLE_NFS)),
 			K(zone_page_state(zone, NR_BOUNCE)),
+			K(zone_page_state(zone, NR_FREE_CMA_PAGES)),
 			K(zone_page_state(zone, NR_WRITEBACK_TEMP)),
 			zone->pages_scanned,
 			(zone->all_unreclaimable ? "yes" : "no")
@@ -2896,6 +2983,7 @@
 
 	for_each_populated_zone(zone) {
  		unsigned long nr[MAX_ORDER], flags, order, total = 0;
+		unsigned char types[MAX_ORDER];
 
 		if (skip_free_areas_node(filter, zone_to_nid(zone)))
 			continue;
@@ -2904,12 +2992,24 @@
 
 		spin_lock_irqsave(&zone->lock, flags);
 		for (order = 0; order < MAX_ORDER; order++) {
-			nr[order] = zone->free_area[order].nr_free;
+			struct free_area *area = &zone->free_area[order];
+			int type;
+
+			nr[order] = area->nr_free;
 			total += nr[order] << order;
+
+			types[order] = 0;
+			for (type = 0; type < MIGRATE_TYPES; type++) {
+				if (!list_empty(&area->free_list[type]))
+					types[order] |= 1 << type;
+			}
 		}
 		spin_unlock_irqrestore(&zone->lock, flags);
-		for (order = 0; order < MAX_ORDER; order++)
+		for (order = 0; order < MAX_ORDER; order++) {
 			printk("%lu*%lukB ", nr[order], K(1UL) << order);
+			if (nr[order])
+				show_migration_types(types[order]);
+		}
 		printk("= %lukB\n", K(total));
 	}
 
@@ -5615,8 +5715,13 @@
 
 out:
 	if (!ret) {
+		unsigned long nr_pages;
+		int migratetype = get_pageblock_migratetype(page);
+
 		set_pageblock_migratetype(page, MIGRATE_ISOLATE);
-		move_freepages_block(zone, page, MIGRATE_ISOLATE);
+		nr_pages = move_freepages_block(zone, page, MIGRATE_ISOLATE);
+
+		__mod_zone_freepage_state(zone, -nr_pages, migratetype);
 	}
 
 	spin_unlock_irqrestore(&zone->lock, flags);
@@ -5628,13 +5733,15 @@
 void unset_migratetype_isolate(struct page *page, unsigned migratetype)
 {
 	struct zone *zone;
-	unsigned long flags;
+	unsigned long flags, nr_pages;
+
 	zone = page_zone(page);
 	spin_lock_irqsave(&zone->lock, flags);
 	if (get_pageblock_migratetype(page) != MIGRATE_ISOLATE)
 		goto out;
+	nr_pages = move_freepages_block(zone, page, migratetype);
+	__mod_zone_freepage_state(zone, nr_pages, migratetype);
 	set_pageblock_migratetype(page, migratetype);
-	move_freepages_block(zone, page, migratetype);
 out:
 	spin_unlock_irqrestore(&zone->lock, flags);
 }
@@ -5817,6 +5924,8 @@
 	if (ret)
 		goto done;
 
+	zone->cma_alloc = 1;
+
 	ret = __alloc_contig_migrate_range(start, end);
 	if (ret)
 		goto done;
@@ -5881,6 +5990,7 @@
 done:
 	undo_isolate_page_range(pfn_max_align_down(start),
 				pfn_max_align_up(end), migratetype);
+	zone->cma_alloc = 0;
 	return ret;
 }
 
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 0dad31dc..8e18d6b 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -722,6 +722,7 @@
 	"numa_other",
 #endif
 	"nr_anon_transparent_hugepages",
+	"nr_free_cma",
 	"nr_dirty_threshold",
 	"nr_dirty_background_threshold",
 
diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c
index ba638d1..c19be91 100644
--- a/net/bluetooth/amp.c
+++ b/net/bluetooth/amp.c
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2010-2012 Code Aurora Forum.  All rights reserved.
+   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
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index 5ac5c52..f504921 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -56,9 +56,6 @@
 #include "bnep.h"
 
 #define VERSION "1.3"
-/* As this feature is dummy for BNEP net device
-** disabling support */
-#undef CONFIG_BT_BNEP_MC_FILTER
 
 static bool compress_src = 1;
 static bool compress_dst = 1;
diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c
index a8e5449..155ff74 100644
--- a/net/bluetooth/bnep/netdev.c
+++ b/net/bluetooth/bnep/netdev.c
@@ -44,9 +44,6 @@
 #include "bnep.h"
 
 #define BNEP_TX_QUEUE_LEN 20
-/* As this feature is dummy for BNEP net device
-** disabling support */
-#undef CONFIG_BT_BNEP_MC_FILTER
 
 static int bnep_net_open(struct net_device *dev)
 {
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 0704394..50f73be 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -1,6 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
-   Copyright (c) 2000-2001, 2010-2012 Code Aurora Forum.  All rights reserved.
+   Copyright (c) 2000-2001, 2010-2012 The Linux Foundation.  All rights reserved.
 
    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
 
@@ -1409,8 +1409,24 @@
 
 	hci_dev_lock_bh(hdev);
 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &req.bdaddr);
-	if (conn)
+	if (conn) {
 		conn->auth_type = req.type;
+		switch (conn->auth_type) {
+		case HCI_AT_NO_BONDING:
+			conn->pending_sec_level = BT_SECURITY_LOW;
+			break;
+		case HCI_AT_DEDICATED_BONDING:
+		case HCI_AT_GENERAL_BONDING:
+			conn->pending_sec_level = BT_SECURITY_MEDIUM;
+			break;
+		case HCI_AT_DEDICATED_BONDING_MITM:
+		case HCI_AT_GENERAL_BONDING_MITM:
+			conn->pending_sec_level = BT_SECURITY_HIGH;
+			break;
+		default:
+			break;
+		}
+	}
 	hci_dev_unlock_bh(hdev);
 
 	if (!conn)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 345b70f..9962c88 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1,6 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
-   Copyright (c) 2000-2001, 2010-2012 Code Aurora Forum.  All rights reserved.
+   Copyright (c) 2000-2001, 2010-2012 The Linux Foundation.  All rights reserved.
 
    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
 
@@ -1474,6 +1474,8 @@
 	hdev->sniff_max_interval = 800;
 	hdev->sniff_min_interval = 80;
 
+	set_bit(HCI_SETUP, &hdev->flags);
+
 	tasklet_init(&hdev->cmd_task, hci_cmd_task, (unsigned long) hdev);
 	tasklet_init(&hdev->rx_task, hci_rx_task, (unsigned long) hdev);
 	tasklet_init(&hdev->tx_task, hci_tx_task, (unsigned long) hdev);
@@ -1542,7 +1544,6 @@
 	}
 
 	set_bit(HCI_AUTO_OFF, &hdev->flags);
-	set_bit(HCI_SETUP, &hdev->flags);
 	queue_work(hdev->workqueue, &hdev->power_on);
 
 	hci_notify(hdev, HCI_DEV_REG);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index ea116e9..198773c 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1,6 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
-   Copyright (c) 2000-2001, 2010-2012, Code Aurora Forum. All rights reserved.
+   Copyright (c) 2000-2001, 2010-2013 The Linux Foundation. All rights reserved.
 
    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
 
@@ -1669,6 +1669,8 @@
 		if (conn->type == ACL_LINK) {
 			struct hci_cp_read_remote_version cp;
 			cp.handle = ev->handle;
+			hci_send_cmd(hdev, HCI_OP_READ_CLOCK_OFFSET,
+				sizeof(cp), &cp);
 			hci_send_cmd(hdev, HCI_OP_READ_REMOTE_VERSION,
 				sizeof(cp), &cp);
 		}
@@ -2044,7 +2046,7 @@
 							sizeof(cp), &cp);
 		goto unlock;
 	} else  if (!(lmp_ssp_capable(conn)) && conn->auth_initiator &&
-		(conn->pending_sec_level == BT_SECURITY_HIGH)) {
+		(conn->pending_sec_level == BT_SECURITY_VERY_HIGH)) {
 		conn->pending_sec_level = BT_SECURITY_MEDIUM;
 	}
 
@@ -2668,7 +2670,7 @@
 			conn->pending_sec_level, conn->ssp_mode, key->pin_len);
 	}
 	if (conn && (conn->ssp_mode == 0) &&
-		(conn->pending_sec_level == BT_SECURITY_HIGH) &&
+		(conn->pending_sec_level == BT_SECURITY_VERY_HIGH) &&
 		(key->pin_len != 16)) {
 		BT_DBG("Security is high ignoring this key");
 		goto not_found;
@@ -2857,14 +2859,14 @@
 
 		conn->ssp_mode = (ev->features[0] & 0x01);
 		/*In case if remote device ssp supported/2.0 device
-		reduce the security level to MEDIUM if it is HIGH*/
+		reduce the security level to MEDIUM if it is VERY HIGH*/
 		if (!conn->ssp_mode && conn->auth_initiator &&
-			(conn->pending_sec_level == BT_SECURITY_HIGH))
+			(conn->pending_sec_level == BT_SECURITY_VERY_HIGH))
 			conn->pending_sec_level = BT_SECURITY_MEDIUM;
 
 		if (conn->ssp_mode && conn->auth_initiator &&
 			conn->io_capability != 0x03) {
-			conn->pending_sec_level = BT_SECURITY_HIGH;
+			conn->pending_sec_level = BT_SECURITY_VERY_HIGH;
 			conn->auth_type = HCI_AT_DEDICATED_BONDING_MITM;
 		}
 	}
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 61c2ca1..550f601 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -1,6 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
-   Copyright (c) 2000-2001, 2011, Code Aurora Forum. All rights reserved.
+   Copyright (c) 2000-2001, 2011, The Linux Foundation. All rights reserved.
 
    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
 
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index 2c4ab78..2353e91 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -1,7 +1,7 @@
 /*
    HIDP implementation for Linux Bluetooth stack (BlueZ).
    Copyright (C) 2003-2004 Marcel Holtmann <marcel@holtmann.org>
-   Copyright (c) 2012 Code Aurora Forum.  All rights reserved.
+   Copyright (c) 2012 The Linux Foundation.  All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License version 2 as
@@ -101,7 +101,20 @@
 
 static void __hidp_unlink_session(struct hidp_session *session)
 {
-	if (session->conn)
+	bdaddr_t *dst = &session->bdaddr;
+	struct hci_dev *hdev;
+	struct device *dev = NULL;
+
+	hdev = hci_get_route(dst, BDADDR_ANY);
+	if (hdev) {
+		session->conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
+		if (session->conn)
+			dev = &session->conn->dev;
+
+		hci_dev_put(hdev);
+	}
+
+	if (dev)
 		hci_conn_put_device(session->conn);
 
 	list_del(&session->list);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 44e2feb..fd9088a 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1,6 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
-   Copyright (c) 2000-2001, 2010-2012 Code Aurora Forum.  All rights reserved.
+   Copyright (c) 2000-2001, 2010-2013 The Linux Foundation. All rights reserved.
    Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
    Copyright (C) 2010 Google Inc.
 
@@ -610,6 +610,7 @@
 {
 	if (sk->sk_type == SOCK_RAW) {
 		switch (l2cap_pi(sk)->sec_level) {
+		case BT_SECURITY_VERY_HIGH:
 		case BT_SECURITY_HIGH:
 			return HCI_AT_DEDICATED_BONDING_MITM;
 		case BT_SECURITY_MEDIUM:
@@ -621,12 +622,14 @@
 		if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
 			l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
 
-		if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
+		if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH ||
+			l2cap_pi(sk)->sec_level == BT_SECURITY_VERY_HIGH)
 			return HCI_AT_NO_BONDING_MITM;
 		else
 			return HCI_AT_NO_BONDING;
 	} else {
 		switch (l2cap_pi(sk)->sec_level) {
+		case BT_SECURITY_VERY_HIGH:
 		case BT_SECURITY_HIGH:
 			return HCI_AT_GENERAL_BONDING_MITM;
 		case BT_SECURITY_MEDIUM:
@@ -7533,7 +7536,8 @@
 		if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
 			l2cap_sock_clear_timer(sk);
 			l2cap_sock_set_timer(sk, HZ * 5);
-		} else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
+		} else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH ||
+			l2cap_pi(sk)->sec_level == BT_SECURITY_VERY_HIGH)
 			__l2cap_sock_close(sk, ECONNREFUSED);
 	} else {
 		if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 761f868..d778ae3 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1,6 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
-   Copyright (c) 2000-2001, 2011-2012 Code Aurora Forum.  All rights reserved.
+   Copyright (c) 2000-2001, 2011-2012 The Linux Foundation.  All rights reserved.
    Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
    Copyright (C) 2010 Google Inc.
 
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 8568dae7..8658b94 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1,7 +1,7 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
    Copyright (C) 2010  Nokia Corporation
-   Copyright (c) 2011-2012 Code Aurora Forum.  All rights reserved.
+   Copyright (c) 2011-2013 The Linux Foundation.  All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License version 2 as
@@ -383,23 +383,30 @@
 		err = cmd_status(sk, index, MGMT_OP_SET_POWERED, EBUSY);
 		goto failed;
 	}
+	/* Avoid queing power_on/off when the set up is going on via
+	 * hci_register_dev
+	 */
+	if (!test_bit(HCI_SETUP, &hdev->flags)) {
+		cmd = mgmt_pending_add(sk, MGMT_OP_SET_POWERED, index, data,
+									len);
+		if (!cmd) {
+			err = -ENOMEM;
+			goto failed;
+		}
 
-	cmd = mgmt_pending_add(sk, MGMT_OP_SET_POWERED, index, data, len);
-	if (!cmd) {
-		err = -ENOMEM;
+		hci_dev_unlock_bh(hdev);
+
+		if (cp->val)
+			queue_work(hdev->workqueue, &hdev->power_on);
+		else
+			queue_work(hdev->workqueue, &hdev->power_off);
+
+		err = 0;
+		hci_dev_put(hdev);
+	} else {
+		err = cmd_status(sk, index, MGMT_OP_SET_POWERED, ENODEV);
 		goto failed;
 	}
-
-	hci_dev_unlock_bh(hdev);
-
-	if (cp->val)
-		queue_work(hdev->workqueue, &hdev->power_on);
-	else
-		queue_work(hdev->workqueue, &hdev->power_off);
-
-	err = 0;
-	hci_dev_put(hdev);
-
 	return err;
 
 failed:
@@ -1758,7 +1765,7 @@
 		return;
 	}
 
-	if (status)
+	if (status || conn->pending_sec_level < BT_SECURITY_MEDIUM)
 		pairing_complete(cmd, status);
 
 	hci_conn_put(conn);
@@ -2238,10 +2245,11 @@
 
 		mgmt_event(MGMT_EV_DISCOVERING, index, &cp, sizeof(cp), NULL);
 
-		hdev->disco_state = SCAN_IDLE;
-
-		if (hdev)
+		if (hdev) {
+			BT_DBG("Setting state to SCAN_IDLE\n");
+			hdev->disco_state = SCAN_IDLE;
 			goto done;
+		}
 		else
 			return;
 	}
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index dc4bf2f..d1914ea 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -262,6 +262,7 @@
 	__u8 auth_type;
 
 	switch (d->sec_level) {
+	case BT_SECURITY_VERY_HIGH:
 	case BT_SECURITY_HIGH:
 		auth_type = HCI_AT_GENERAL_BONDING_MITM;
 		break;
@@ -2163,7 +2164,8 @@
 				set_bit(RFCOMM_SEC_PENDING, &d->flags);
 				rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
 				continue;
-			} else if (d->sec_level == BT_SECURITY_HIGH) {
+			} else if (d->sec_level == BT_SECURITY_HIGH ||
+				d->sec_level == BT_SECURITY_VERY_HIGH) {
 				__rfcomm_dlc_close(d, ECONNREFUSED);
 				continue;
 			}
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 66cc1f0..216068f 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -707,12 +707,13 @@
 			break;
 		}
 
-		if (sec.level > BT_SECURITY_HIGH) {
+		if (sec.level > BT_SECURITY_VERY_HIGH) {
 			err = -EINVAL;
 			break;
 		}
 
 		rfcomm_pi(sk)->sec_level = sec.level;
+		BT_DBG("set to %d", sec.level);
 		break;
 
 	case BT_DEFER_SETUP:
@@ -763,6 +764,7 @@
 			opt = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT;
 			break;
 		case BT_SECURITY_HIGH:
+		case BT_SECURITY_VERY_HIGH:
 			opt = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT |
 							RFCOMM_LM_SECURE;
 			break;
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 8cec741..3170190 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -1,7 +1,7 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
    Copyright (C) 2000-2001 Qualcomm Incorporated
-   Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+   Copyright (c) 2011, The Linux Foundation. All rights reserved.
 
    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
 
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 56b2cfa..4a83020 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -213,6 +213,7 @@
 static __u8 seclevel_to_authreq(__u8 level)
 {
 	switch (level) {
+	case BT_SECURITY_VERY_HIGH:
 	case BT_SECURITY_HIGH:
 		return SMP_AUTH_MITM | SMP_AUTH_BONDING;
 
@@ -446,6 +447,8 @@
 		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
 								&reason);
 		del_timer(&hcon->smp_timer);
+		if (hcon->disconn_cfm_cb)
+			hcon->disconn_cfm_cb(hcon, SMP_UNSPECIFIED);
 		clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
 		mgmt_auth_failed(hcon->hdev->id, conn->dst, reason);
 		hci_conn_put(hcon);
diff --git a/net/ipv4/netfilter/ipt_NATTYPE.c b/net/ipv4/netfilter/ipt_NATTYPE.c
index 6b28794..2bb18ca 100644
--- a/net/ipv4/netfilter/ipt_NATTYPE.c
+++ b/net/ipv4/netfilter/ipt_NATTYPE.c
@@ -58,6 +58,7 @@
 struct ipt_nattype {
 	struct list_head list;
 	struct timer_list timeout;
+	unsigned char is_valid;
 	unsigned short proto;		/* Protocol: TCP or UDP */
 	struct nf_nat_ipv4_range range;	/* LAN side source information */
 	unsigned short nat_port;	/* Routed NAT port */
@@ -101,14 +102,23 @@
  * nattype_refresh_timer()
  *	Refresh the timer for this object.
  */
-static bool nattype_refresh_timer(struct ipt_nattype *nte)
+bool nattype_refresh_timer(unsigned long nat_type)
 {
-
+	struct ipt_nattype *nte = (struct ipt_nattype *)nat_type;
+	if (!nte)
+		return false;
+	spin_lock_bh(&nattype_lock);
+	if (!nte->is_valid) {
+		spin_unlock_bh(&nattype_lock);
+		return false;
+	}
 	if (del_timer(&nte->timeout)) {
 		nte->timeout.expires = jiffies + NATTYPE_TIMEOUT * HZ;
 		add_timer(&nte->timeout);
+		spin_unlock_bh(&nattype_lock);
 		return true;
 	}
+	spin_unlock_bh(&nattype_lock);
 	return false;
 }
 
@@ -128,6 +138,7 @@
 	nattype_nte_debug_print(nte, "timeout");
 	spin_lock_bh(&nattype_lock);
 	list_del(&nte->list);
+	memset(nte, 0, sizeof(struct ipt_nattype));
 	spin_unlock_bh(&nattype_lock);
 	nattype_free(nte);
 }
@@ -309,6 +320,7 @@
 		 */
 		DEBUGP("Expand ingress conntrack=%p, type=%d, src[%pI4:%d]\n",
 			ct, ctinfo, &newrange.min_ip, ntohs(newrange.min.all));
+		ct->nattype_entry = (unsigned long)nte;
 		ret = nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST);
 		DEBUGP("Expand returned: %d\n", ret);
 		return ret;
@@ -348,21 +360,19 @@
 			 */
 			if (!nattype_packet_in_match(nte, skb, info))
 				continue;
-
+			spin_unlock_bh(&nattype_lock);
 			/*
 			 * Refresh the timer, if we fail, break
 			 * out and forward fail as though we never
 			 * found the entry.
 			 */
-			if (!nattype_refresh_timer(nte))
+			if (!nattype_refresh_timer((unsigned long)nte))
 				break;
-
 			/*
 			 * The entry is found and refreshed, the
 			 * entry values should not change so print
 			 * them outside the lock.
 			 */
-			spin_unlock_bh(&nattype_lock);
 			nattype_nte_debug_print(nte, "refresh");
 			DEBUGP("FORWARD_IN_ACCEPT\n");
 			return NF_ACCEPT;
@@ -431,22 +441,20 @@
 	list_for_each_entry(nte2, &nattype_list, list) {
 		if (!nattype_compare(nte, nte2))
 			continue;
-
+		spin_unlock_bh(&nattype_lock);
 		/*
 		 * If we can not refresh this entry, insert our new
 		 * entry as this one is timed out and will be removed
 		 * from the list shortly.
 		 */
-		if (!nattype_refresh_timer(nte2))
+		if (!nattype_refresh_timer((unsigned long)nte2))
 			break;
-
 		/*
 		 * Found and refreshed an existing entry.  Its values
 		 * do not change so print the values outside of the lock.
 		 *
 		 * Free up the new entry.
 		 */
-		spin_unlock_bh(&nattype_lock);
 		nattype_nte_debug_print(nte2, "refresh");
 		nattype_free(nte);
 		return XT_CONTINUE;
@@ -458,6 +466,8 @@
 	nte->timeout.expires = jiffies + (NATTYPE_TIMEOUT  * HZ);
 	add_timer(&nte->timeout);
 	list_add(&nte->list, &nattype_list);
+	ct->nattype_entry = (unsigned long)nte;
+	nte->is_valid = 1;
 	spin_unlock_bh(&nattype_lock);
 	nattype_nte_debug_print(nte, "ADD");
 	return XT_CONTINUE;
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index f897841..5bb2847 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -36,6 +36,8 @@
  *	YOSHIFUJI Hideaki @USAGI	:	improved source address
  *						selection; consider scope,
  *						status etc.
+ *	Harout S. Hedeshian		:	procfs flag to toggle automatic
+ *						addition of prefix route
  */
 
 #include <linux/errno.h>
@@ -197,6 +199,7 @@
 	.accept_source_route	= 0,	/* we do not accept RH0 by default. */
 	.disable_ipv6		= 0,
 	.accept_dad		= 1,
+	.accept_ra_prefix_route = 1,
 };
 
 static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
@@ -231,6 +234,7 @@
 	.accept_source_route	= 0,	/* we do not accept RH0 by default. */
 	.disable_ipv6		= 0,
 	.accept_dad		= 1,
+	.accept_ra_prefix_route = 1,
 };
 
 /* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */
@@ -1908,8 +1912,10 @@
 				flags |= RTF_EXPIRES;
 				expires = jiffies_to_clock_t(rt_expires);
 			}
-			addrconf_prefix_route(&pinfo->prefix, pinfo->prefix_len,
-					      dev, expires, flags);
+			if (dev->ip6_ptr->cnf.accept_ra_prefix_route) {
+				addrconf_prefix_route(&pinfo->prefix,
+					pinfo->prefix_len, dev, expires, flags);
+			}
 		}
 		if (rt)
 			dst_release(&rt->dst);
@@ -4598,6 +4604,13 @@
 			.proc_handler   = proc_dointvec
 		},
 		{
+			.procname	= "accept_ra_prefix_route",
+			.data		= &ipv6_devconf.accept_ra_prefix_route,
+			.maxlen		= sizeof(int),
+			.mode		= 0644,
+			.proc_handler	= proc_dointvec,
+		},
+		{
 			/* sentinel */
 		}
 	},
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 729f157..13925ac 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -833,6 +833,10 @@
 #ifdef CONFIG_NF_CONNTRACK_SECMARK
 		ct->secmark = exp->master->secmark;
 #endif
+/* Intialize the NAT type entry. */
+#if defined(CONFIG_IP_NF_TARGET_NATTYPE_MODULE)
+		ct->nattype_entry = 0;
+#endif
 		nf_conntrack_get(&ct->master->ct_general);
 		NF_CT_STAT_INC(net, expect_new);
 	} else {
@@ -1095,6 +1099,11 @@
 			mod_timer_pending(&ct->timeout, newtime);
 	}
 
+/* Refresh the NAT type entry. */
+#if defined(CONFIG_IP_NF_TARGET_NATTYPE_MODULE)
+	(void)nattype_refresh_timer(ct->nattype_entry);
+#endif
+
 acct:
 	if (do_acct) {
 		struct nf_conn_counter *acct;
diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c
index f6d4cfc..2b486b1 100644
--- a/net/netfilter/xt_qtaguid.c
+++ b/net/netfilter/xt_qtaguid.c
@@ -1201,7 +1201,7 @@
 static int ipx_proto(const struct sk_buff *skb,
 		     struct xt_action_param *par)
 {
-	int thoff, tproto;
+	int thoff = 0, tproto;
 
 	switch (par->family) {
 	case NFPROTO_IPV6:
@@ -1773,6 +1773,8 @@
 	}
 
 	sk = skb->sk;
+	if (sk && sk->sk_state == TCP_TIME_WAIT)
+		sk = NULL;
 	if (sk == NULL) {
 		/*
 		 * A missing sk->sk_socket happens when packets are in-flight
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 0410707..1ccc69e 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -5173,6 +5173,15 @@
 		connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
 	}
 
+	if (info->attrs[NL80211_ATTR_USE_MFP]) {
+		connect.mfp = nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
+		if (connect.mfp != NL80211_MFP_REQUIRED &&
+		    connect.mfp != NL80211_MFP_NO)
+			return -EINVAL;
+	} else {
+		connect.mfp = NL80211_MFP_NO;
+	}
+
 	if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
 		connect.channel =
 			ieee80211_get_channel(wiphy,
@@ -8082,6 +8091,50 @@
 }
 EXPORT_SYMBOL(cfg80211_report_obss_beacon);
 
+void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
+				enum nl80211_tdls_operation oper,
+				u16 reason_code, gfp_t gfp)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	struct sk_buff *msg;
+	void *hdr;
+	int err;
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
+	if (!msg)
+		return;
+
+	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_TDLS_OPER);
+	if (!hdr) {
+		nlmsg_free(msg);
+		return;
+	}
+
+	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
+	    nla_put_u8(msg, NL80211_ATTR_TDLS_OPERATION, oper) ||
+	    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer) ||
+	    (reason_code > 0 &&
+	     nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code)))
+		goto nla_put_failure;
+
+	err = genlmsg_end(msg, hdr);
+	if (err < 0) {
+		nlmsg_free(msg);
+		return;
+	}
+
+	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+				nl80211_mlme_mcgrp.id, gfp);
+	return;
+
+ nla_put_failure:
+	genlmsg_cancel(msg, hdr);
+	nlmsg_free(msg);
+}
+EXPORT_SYMBOL(cfg80211_tdls_oper_request);
+
 static int nl80211_netlink_notify(struct notifier_block * nb,
 				  unsigned long state,
 				  void *_notify)
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index bbbed73..ab91446 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -190,7 +190,8 @@
 					    prev_bssid,
 					    params->ssid, params->ssid_len,
 					    params->ie, params->ie_len,
-					    false, &params->crypto,
+					    params->mfp != NL80211_MFP_NO,
+					    &params->crypto,
 					    params->flags, &params->ht_capa,
 					    &params->ht_capa_mask);
 		if (err)
diff --git a/scripts/build-all.py b/scripts/build-all.py
index c59ffae..4789af7 100755
--- a/scripts/build-all.py
+++ b/scripts/build-all.py
@@ -1,6 +1,6 @@
 #! /usr/bin/env python
 
-# Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+# Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are met:
@@ -9,7 +9,7 @@
 #     * Redistributions in binary form must reproduce the above copyright
 #       notice, this list of conditions and the following disclaimer in the
 #       documentation and/or other materials provided with the distribution.
-#     * Neither the name of Code Aurora nor
+#     * Neither the name of The Linux Foundation nor
 #       the names of its contributors may be used to endorse or promote
 #       products derived from this software without specific prior written
 #       permission.
@@ -88,7 +88,6 @@
         r'[fm]sm[0-9]*_defconfig',
         r'apq*_defconfig',
         r'qsd*_defconfig',
-        r'omap2*_defconfig',
         )
     for p in arch_pats:
         for n in glob.glob('arch/arm/configs/' + p):
diff --git a/scripts/gcc-wrapper.py b/scripts/gcc-wrapper.py
index 583a5ce..2010c57 100755
--- a/scripts/gcc-wrapper.py
+++ b/scripts/gcc-wrapper.py
@@ -1,7 +1,7 @@
 #! /usr/bin/env python
 # -*- coding: utf-8 -*-
 
-# Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+# Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are met:
@@ -10,7 +10,7 @@
 #     * Redistributions in binary form must reproduce the above copyright
 #       notice, this list of conditions and the following disclaimer in the
 #       documentation and/or other materials provided with the distribution.
-#     * Neither the name of Code Aurora nor
+#     * Neither the name of The Linux Foundation nor
 #       the names of its contributors may be used to endorse or promote
 #       products derived from this software without specific prior written
 #       permission.
@@ -43,6 +43,7 @@
     "alignment.c:327",
     "mmu.c:602",
     "return_address.c:62",
+    "extents.c:2091",
  ])
 
 # Capture the name of the object file, can find it.
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 44ddaa5..f527f4f 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -156,7 +156,7 @@
 }
 
 /* USB is special because the bcdDevice can be matched against a numeric range */
-/* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipN" */
+/* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipNinN" */
 static void do_usb_entry(struct usb_device_id *id,
 			 unsigned int bcdDevice_initial, int bcdDevice_initial_digits,
 			 unsigned char range_lo, unsigned char range_hi,
@@ -210,6 +210,9 @@
 	ADD(alias, "ip",
 	    id->match_flags&USB_DEVICE_ID_MATCH_INT_PROTOCOL,
 	    id->bInterfaceProtocol);
+	ADD(alias, "in",
+	    id->match_flags&USB_DEVICE_ID_MATCH_INT_NUMBER,
+	    id->bInterfaceNumber);
 
 	add_wildcard(alias);
 	buf_printf(&mod->dev_table_buf,
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 1b46499..155585a 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -295,6 +295,12 @@
 config SND_SOC_WCD9320
         tristate
 
+config SND_SOC_WCD9306
+        tristate
+
+config SND_SOC_MSM8X10_WCD
+	tristate
+
 config SND_SOC_WL1273
 	tristate
 
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 42121fe..a09dab3 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -51,7 +51,9 @@
 snd-soc-wcd9304-objs := wcd9304.o wcd9304-tables.o
 snd-soc-wcd9310-objs := wcd9310.o wcd9310-tables.o
 snd-soc-cs8427-objs := cs8427.o
-snd-soc-wcd9320-objs := wcd9xxx-resmgr.o wcd9320.o wcd9320-tables.o wcd9xxx-mbhc.o
+snd-soc-wcd9320-objs := wcd9xxx-resmgr.o wcd9320.o wcd9320-tables.o wcd9xxx-mbhc.o wcd9xxx-common.o
+snd-soc-wcd9306-objs := wcd9306.o wcd9306-tables.o
+snd-soc-msm8x10-wcd-objs := msm8x10-wcd.o msm8x10-wcd-tables.o
 snd-soc-wl1273-objs := wl1273.o
 snd-soc-wm1250-ev1-objs := wm1250-ev1.o
 snd-soc-wm2000-objs := wm2000.o
@@ -162,6 +164,8 @@
 obj-$(CONFIG_SND_SOC_WCD9310)	+= snd-soc-wcd9310.o
 obj-$(CONFIG_SND_SOC_CS8427)	+= snd-soc-cs8427.o
 obj-$(CONFIG_SND_SOC_WCD9320)	+= snd-soc-wcd9320.o
+obj-$(CONFIG_SND_SOC_WCD9306)	+= snd-soc-wcd9306.o wcd9xxx-resmgr.o wcd9xxx-mbhc.o
+obj-$(CONFIG_SND_SOC_MSM8X10_WCD)	+= snd-soc-msm8x10-wcd.o wcd9xxx-resmgr.o
 obj-$(CONFIG_SND_SOC_WL1273)	+= snd-soc-wl1273.o
 obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o
 obj-$(CONFIG_SND_SOC_WM2000)	+= snd-soc-wm2000.o
diff --git a/sound/soc/codecs/cs8427.c b/sound/soc/codecs/cs8427.c
index 6e08742..67f96f9 100644
--- a/sound/soc/codecs/cs8427.c
+++ b/sound/soc/codecs/cs8427.c
@@ -2,7 +2,7 @@
  *  Routines for control of the CS8427 via i2c bus
  *  IEC958 (S/PDIF) receiver & transmitter by Cirrus Logic
  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *  Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2 and
diff --git a/sound/soc/codecs/msm8x10-wcd-tables.c b/sound/soc/codecs/msm8x10-wcd-tables.c
new file mode 100644
index 0000000..7e0263d
--- /dev/null
+++ b/sound/soc/codecs/msm8x10-wcd-tables.c
@@ -0,0 +1,794 @@
+/* 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 <msm8x10_wcd_registers.h>
+#include "msm8x10-wcd.h"
+
+const u8 msm8x10_wcd_reg_readable[MSM8X10_WCD_CACHE_SIZE] = {
+	[MSM8X10_WCD_A_CHIP_CTL] = 1,
+	[MSM8X10_WCD_A_CHIP_STATUS] = 1,
+	[MSM8X10_WCD_A_CDC_TLMM_MODE_SELECT] = 1,
+	[MSM8X10_WCD_A_MODE_LOCK] = 0,
+	[MSM8X10_WCD_A_CHIP_ID_BYTE_0] = 1,
+	[MSM8X10_WCD_A_CHIP_ID_BYTE_1] = 1,
+	[MSM8X10_WCD_A_CHIP_ID_BYTE_2] = 1,
+	[MSM8X10_WCD_A_CHIP_ID_BYTE_3] = 1,
+	[MSM8X10_WCD_A_CHIP_VERSION] = 1,
+	[MSM8X10_WCD_A_ANALOG_SLAVE_ID] = 1,
+	[MSM8X10_WCD_A_PIN_CTL_OE] = 1,
+	[MSM8X10_WCD_A_PIN_CTL_DATA] = 1,
+	[MSM8X10_WCD_A_PIN_STATUS] = 1,
+	[MSM8X10_WCD_A_HDRIVE_CTL] = 1,
+	[MSM8X10_WCD_A_HDRIVE_I2C_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RST_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_TOP_CLK_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_ANA_CLK_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_DIG_CLK_CTL] = 1,
+	[MSM8X10_WCD_A_PROCESS_MONITOR_CTL0] = 1,
+	[MSM8X10_WCD_A_PROCESS_MONITOR_CTL1] = 1,
+	[MSM8X10_WCD_A_PROCESS_MONITOR_CTL2] = 1,
+	[MSM8X10_WCD_A_PROCESS_MONITOR_CTL3] = 1,
+	[MSM8X10_WCD_A_QFUSE_CTL] = 1,
+	[MSM8X10_WCD_A_QFUSE_STATUS] = 1,
+	[MSM8X10_WCD_A_QFUSE_DATA_OUT0] = 1,
+	[MSM8X10_WCD_A_QFUSE_DATA_OUT1] = 1,
+	[MSM8X10_WCD_A_QFUSE_DATA_OUT2] = 1,
+	[MSM8X10_WCD_A_QFUSE_DATA_OUT3] = 1,
+	[MSM8X10_WCD_A_CDC_CONN_TX1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CONN_TX2_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CONN_HPHR_DAC_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CONN_LO_DAC_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CONN_RX1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CONN_RX2_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CONN_RX3_CTL] = 1,
+	[MSM8X10_WCD_A_DIGITAL_DEBUG_CTL] = 1,
+	[MSM8X10_WCD_A_ANALOG_DEBUG_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RX1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RX2_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RX3_CTL] = 1,
+	[MSM8X10_WCD_A_DEM_BYPASS_DATA0] = 1,
+	[MSM8X10_WCD_A_DEM_BYPASS_DATA1] = 1,
+	[MSM8X10_WCD_A_DEM_BYPASS_DATA2] = 1,
+	[MSM8X10_WCD_A_DEM_BYPASS_DATA3] = 1,
+	[MSM8X10_WCD_A_SPARE_0] = 1,
+	[MSM8X10_WCD_A_SPARE_1] = 1,
+	[MSM8X10_WCD_A_SPARE_2] = 1,
+	[MSM8X10_WCD_A_INTR_MODE] = 1,
+	[MSM8X10_WCD_A_INTR_MASK0] = 1,
+	[MSM8X10_WCD_A_INTR_MASK1] = 1,
+	[MSM8X10_WCD_A_INTR_MASK2] = 1,
+	[MSM8X10_WCD_A_INTR_STATUS0] = 1,
+	[MSM8X10_WCD_A_INTR_STATUS1] = 1,
+	[MSM8X10_WCD_A_INTR_STATUS2] = 1,
+	[MSM8X10_WCD_A_INTR_CLEAR0] = 0,
+	[MSM8X10_WCD_A_INTR_CLEAR1] = 0,
+	[MSM8X10_WCD_A_INTR_CLEAR2] = 0,
+	[MSM8X10_WCD_A_INTR_TEST0] = 1,
+	[MSM8X10_WCD_A_INTR_TEST1] = 1,
+	[MSM8X10_WCD_A_INTR_TEST2] = 1,
+	[MSM8X10_WCD_A_INTR_SET0] = 1,
+	[MSM8X10_WCD_A_INTR_SET1] = 1,
+	[MSM8X10_WCD_A_INTR_SET2] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_EN_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_FIR_B1_CFG] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_FIR_B2_CFG] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_TIMER_B1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_TIMER_B2_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_TIMER_B3_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_TIMER_B4_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_TIMER_B5_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_TIMER_B6_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_B1_STATUS] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_B2_STATUS] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_B3_STATUS] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_B4_STATUS] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_B5_STATUS] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_B1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_B2_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_VOLT_B1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_VOLT_B2_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_VOLT_B3_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_VOLT_B4_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_VOLT_B5_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_VOLT_B6_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_VOLT_B7_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_VOLT_B8_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_VOLT_B9_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_VOLT_B10_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_VOLT_B11_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_VOLT_B12_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_CLK_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_INT_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_DEBUG_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_MBHC_SPARE] = 1,
+	[MSM8X10_WCD_A_BIAS_REF_CTL] = 1,
+	[MSM8X10_WCD_A_BIAS_CENTRAL_BG_CTL] = 1,
+	[MSM8X10_WCD_A_BIAS_PRECHRG_CTL] = 1,
+	[MSM8X10_WCD_A_BIAS_CURR_CTL_1] = 1,
+	[MSM8X10_WCD_A_BIAS_CURR_CTL_2] = 1,
+	[MSM8X10_WCD_A_BIAS_OSC_BG_CTL] = 1,
+	[MSM8X10_WCD_A_MICB_CFILT_1_CTL] = 1,
+	[MSM8X10_WCD_A_MICB_CFILT_1_VAL] = 1,
+	[MSM8X10_WCD_A_MICB_CFILT_1_PRECHRG] = 1,
+	[MSM8X10_WCD_A_MICB_1_CTL] = 1,
+	[MSM8X10_WCD_A_MICB_1_INT_RBIAS] = 1,
+	[MSM8X10_WCD_A_MICB_1_MBHC] = 1,
+	[MSM8X10_WCD_A_MBHC_INSERT_DETECT] = 1,
+	[MSM8X10_WCD_A_MBHC_INSERT_DET_STATUS] = 1,
+	[MSM8X10_WCD_A_TX_COM_BIAS] = 1,
+	[MSM8X10_WCD_A_MBHC_SCALING_MUX_1] = 1,
+	[MSM8X10_WCD_A_MBHC_SCALING_MUX_2] = 1,
+	[MSM8X10_WCD_A_RESERVED_MAD_ANA_CTRL] = 1,
+	[MSM8X10_WCD_A_TX_SUP_SWITCH_CTRL_1] = 1,
+	[MSM8X10_WCD_A_TX_SUP_SWITCH_CTRL_2] = 1,
+	[MSM8X10_WCD_A_TX_1_EN] = 1,
+	[MSM8X10_WCD_A_TX_2_EN] = 1,
+	[MSM8X10_WCD_A_TX_1_2_ADC_CH1] = 1,
+	[MSM8X10_WCD_A_TX_1_2_ADC_CH2] = 1,
+	[MSM8X10_WCD_A_TX_1_2_ATEST_REFCTRL] = 1,
+	[MSM8X10_WCD_A_TX_1_2_TEST_CTL] = 1,
+	[MSM8X10_WCD_A_TX_1_2_TEST_BLOCK_EN] = 1,
+	[MSM8X10_WCD_A_TX_1_2_TXFE_CLKDIV] = 1,
+	[MSM8X10_WCD_A_TX_1_2_SAR_ERR_CH1] = 1,
+	[MSM8X10_WCD_A_TX_1_2_SAR_ERR_CH2] = 1,
+	[MSM8X10_WCD_A_TX_3_EN] = 1,
+	[MSM8X10_WCD_A_TX_1_2_TEST_EN] = 1,
+	[MSM8X10_WCD_A_TX_7_MBHC_EN_ATEST_CTRL] = 1,
+	[MSM8X10_WCD_A_TX_7_MBHC_SAR_ERR] = 1,
+	[MSM8X10_WCD_A_CP_EN] = 1,
+	[MSM8X10_WCD_A_CP_CLK] = 1,
+	[MSM8X10_WCD_A_CP_STATIC] = 1,
+	[MSM8X10_WCD_A_CP_DCC1] = 1,
+	[MSM8X10_WCD_A_CP_DCC3] = 1,
+	[MSM8X10_WCD_A_CP_ATEST] = 1,
+	[MSM8X10_WCD_A_CP_DTEST] = 1,
+	[MSM8X10_WCD_A_RX_AUX_SW_CTL] = 1,
+	[MSM8X10_WCD_A_RX_PA_AUX_IN_CONN] = 1,
+	[MSM8X10_WCD_A_RX_COM_TIMER_DIV] = 1,
+	[MSM8X10_WCD_A_RX_COM_OCP_CTL] = 1,
+	[MSM8X10_WCD_A_RX_COM_OCP_COUNT] = 1,
+	[MSM8X10_WCD_A_RX_COM_DAC_CTL] = 1,
+	[MSM8X10_WCD_A_RX_COM_BIAS] = 1,
+	[MSM8X10_WCD_A_RX_HPH_AUTO_CHOP] = 1,
+	[MSM8X10_WCD_A_RX_HPH_CHOP_CTL] = 1,
+	[MSM8X10_WCD_A_RX_HPH_BIAS_PA] = 1,
+	[MSM8X10_WCD_A_RX_HPH_BIAS_LDO] = 1,
+	[MSM8X10_WCD_A_RX_HPH_BIAS_CNP] = 1,
+	[MSM8X10_WCD_A_RX_HPH_BIAS_WG_OCP] = 1,
+	[MSM8X10_WCD_A_RX_HPH_OCP_CTL] = 1,
+	[MSM8X10_WCD_A_RX_HPH_CNP_EN] = 1,
+	[MSM8X10_WCD_A_RX_HPH_CNP_WG_CTL] = 1,
+	[MSM8X10_WCD_A_RX_HPH_CNP_WG_TIME] = 1,
+	[MSM8X10_WCD_A_RX_HPH_L_GAIN] = 1,
+	[MSM8X10_WCD_A_RX_HPH_L_TEST] = 1,
+	[MSM8X10_WCD_A_RX_HPH_L_PA_CTL] = 1,
+	[MSM8X10_WCD_A_RX_HPH_L_DAC_CTL] = 1,
+	[MSM8X10_WCD_A_RX_HPH_L_ATEST] = 1,
+	[MSM8X10_WCD_A_RX_HPH_L_STATUS] = 1,
+	[MSM8X10_WCD_A_RX_HPH_R_GAIN] = 1,
+	[MSM8X10_WCD_A_RX_HPH_R_TEST] = 1,
+	[MSM8X10_WCD_A_RX_HPH_R_PA_CTL] = 1,
+	[MSM8X10_WCD_A_RX_HPH_R_DAC_CTL] = 1,
+	[MSM8X10_WCD_A_RX_HPH_R_ATEST] = 1,
+	[MSM8X10_WCD_A_RX_HPH_R_STATUS] = 1,
+	[MSM8X10_WCD_A_RX_EAR_BIAS_PA] = 1,
+	[MSM8X10_WCD_A_RX_EAR_BIAS_CMBUFF] = 1,
+	[MSM8X10_WCD_A_RX_EAR_EN] = 1,
+	[MSM8X10_WCD_A_RX_EAR_GAIN] = 1,
+	[MSM8X10_WCD_A_RX_EAR_CMBUFF] = 1,
+	[MSM8X10_WCD_A_RX_EAR_ICTL] = 1,
+	[MSM8X10_WCD_A_RX_EAR_CCOMP] = 1,
+	[MSM8X10_WCD_A_RX_EAR_VCM] = 1,
+	[MSM8X10_WCD_A_RX_EAR_CNP] = 1,
+	[MSM8X10_WCD_A_RX_EAR_DAC_CTL_ATEST] = 1,
+	[MSM8X10_WCD_A_RX_EAR_STATUS] = 1,
+	[MSM8X10_WCD_A_RX_LINE_BIAS_PA] = 1,
+	[MSM8X10_WCD_A_RX_BUCK_BIAS1] = 1,
+	[MSM8X10_WCD_A_RX_BUCK_BIAS2] = 1,
+	[MSM8X10_WCD_A_RX_LINE_COM] = 1,
+	[MSM8X10_WCD_A_RX_LINE_CNP_EN] = 1,
+	[MSM8X10_WCD_A_RX_LINE_CNP_WG_CTL] = 1,
+	[MSM8X10_WCD_A_RX_LINE_CNP_WG_TIME] = 1,
+	[MSM8X10_WCD_A_RX_LINE_1_GAIN] = 1,
+	[MSM8X10_WCD_A_RX_LINE_1_TEST] = 1,
+	[MSM8X10_WCD_A_RX_LINE_1_DAC_CTL] = 1,
+	[MSM8X10_WCD_A_RX_LINE_1_STATUS] = 1,
+	[MSM8X10_WCD_A_RX_LINE_CNP_DBG] = 1,
+	[MSM8X10_WCD_A_SPKR_DRV_EN] = 1,
+	[MSM8X10_WCD_A_SPKR_DRV_GAIN] = 1,
+	[MSM8X10_WCD_A_SPKR_DRV_DAC_CTL] = 1,
+	[MSM8X10_WCD_A_SPKR_DRV_OCP_CTL] = 1,
+	[MSM8X10_WCD_A_SPKR_DRV_CLIP_DET] = 1,
+	[MSM8X10_WCD_A_SPKR_DRV_IEC] = 1,
+	[MSM8X10_WCD_A_SPKR_DRV_DBG_DAC] = 1,
+	[MSM8X10_WCD_A_SPKR_DRV_DBG_PA] = 1,
+	[MSM8X10_WCD_A_SPKR_DRV_DBG_PWRSTG] = 1,
+	[MSM8X10_WCD_A_SPKR_DRV_BIAS_LDO] = 1,
+	[MSM8X10_WCD_A_SPKR_DRV_BIAS_INT] = 1,
+	[MSM8X10_WCD_A_SPKR_DRV_BIAS_PA] = 1,
+	[MSM8X10_WCD_A_SPKR_DRV_STATUS_OCP] = 1,
+	[MSM8X10_WCD_A_SPKR_DRV_STATUS_PA] = 1,
+	[MSM8X10_WCD_A_RC_OSC_FREQ] = 1,
+	[MSM8X10_WCD_A_RC_OSC_TEST] = 1,
+	[MSM8X10_WCD_A_RC_OSC_STATUS] = 1,
+	[MSM8X10_WCD_A_RC_OSC_TUNER] = 1,
+	[MSM8X10_WCD_A_MBHC_HPH] = 1,
+	[MSM8X10_WCD_A_CDC_CLK_RX_RESET_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CLK_TX_RESET_B1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CLK_DMIC_B1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CLK_RX_I2S_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CLK_TX_I2S_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CLK_OTHR_RESET_B1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CLK_OTHR_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CLK_RX_B1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CLK_MCLK_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CLK_PDM_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CLK_SD_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RX1_B1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RX2_B1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RX3_B1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RX1_B2_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RX2_B2_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RX3_B2_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RX1_B3_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RX2_B3_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RX3_B3_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RX1_B4_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RX2_B4_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RX3_B4_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RX1_B5_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RX2_B5_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RX3_B5_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RX1_B6_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RX2_B6_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RX3_B6_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RX1_VOL_CTL_B1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RX2_VOL_CTL_B1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RX3_VOL_CTL_B1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RX1_VOL_CTL_B2_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RX2_VOL_CTL_B2_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_RX3_VOL_CTL_B2_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B2_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B3_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B4_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CLSG_GAIN_THRESH_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CLSG_TIMER_B1_CFG] = 1,
+	[MSM8X10_WCD_A_CDC_CLSG_TIMER_B2_CFG] = 1,
+	[MSM8X10_WCD_A_CDC_CLSG_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_TX1_VOL_CTL_TIMER] = 1,
+	[MSM8X10_WCD_A_CDC_TX2_VOL_CTL_TIMER] = 1,
+	[MSM8X10_WCD_A_CDC_TX1_VOL_CTL_GAIN] = 1,
+	[MSM8X10_WCD_A_CDC_TX2_VOL_CTL_GAIN] = 1,
+	[MSM8X10_WCD_A_CDC_TX1_VOL_CTL_CFG] = 1,
+	[MSM8X10_WCD_A_CDC_TX2_VOL_CTL_CFG] = 1,
+	[MSM8X10_WCD_A_CDC_TX1_MUX_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_TX2_MUX_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_TX1_CLK_FS_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_TX2_CLK_FS_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_TX1_DMIC_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_TX2_DMIC_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_IIR1_GAIN_B1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_IIR2_GAIN_B1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_IIR1_GAIN_B2_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_IIR2_GAIN_B2_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_IIR1_GAIN_B3_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_IIR2_GAIN_B3_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_IIR1_GAIN_B4_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_IIR2_GAIN_B4_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_IIR1_GAIN_B5_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_IIR2_GAIN_B5_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_IIR1_GAIN_B6_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_IIR2_GAIN_B6_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_IIR1_GAIN_B7_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_IIR2_GAIN_B7_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_IIR1_GAIN_B8_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_IIR2_GAIN_B8_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_IIR1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_IIR2_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_IIR1_GAIN_TIMER_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_IIR2_GAIN_TIMER_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_IIR1_COEF_B1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_IIR2_COEF_B1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_IIR1_COEF_B2_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_IIR2_COEF_B2_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CONN_RX1_B1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CONN_RX1_B2_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CONN_RX1_B3_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CONN_RX2_B1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CONN_RX2_B2_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CONN_RX2_B3_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CONN_RX3_B1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CONN_RX3_B2_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CONN_TX_B1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CONN_EQ1_B1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CONN_EQ1_B2_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CONN_EQ1_B3_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CONN_EQ1_B4_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CONN_EQ2_B1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CONN_EQ2_B2_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CONN_EQ2_B3_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CONN_EQ2_B4_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_CONN_TX_I2S_SD1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_TOP_GAIN_UPDATE] = 1,
+	[MSM8X10_WCD_A_CDC_TOP_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_DEBUG_DESER1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_DEBUG_DESER2_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_DEBUG_B1_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_DEBUG_B2_CTL] = 1,
+	[MSM8X10_WCD_A_CDC_DEBUG_B3_CTL] = 1,
+};
+
+const u8 msm8x10_wcd_reset_reg_defaults[MSM8X10_WCD_CACHE_SIZE] = {
+	[MSM8X10_WCD_A_CHIP_CTL] = MSM8X10_WCD_A_CHIP_CTL__POR,
+	[MSM8X10_WCD_A_CHIP_STATUS] = MSM8X10_WCD_A_CHIP_STATUS__POR,
+	[MSM8X10_WCD_A_CDC_TLMM_MODE_SELECT] =
+			MSM8X10_WCD_A_CDC_TLMM_MODE_SELECT__POR,
+	[MSM8X10_WCD_A_MODE_LOCK] = MSM8X10_WCD_A_MODE_LOCK__POR,
+	[MSM8X10_WCD_A_CHIP_ID_BYTE_0] = MSM8X10_WCD_A_CHIP_ID_BYTE_0__POR,
+	[MSM8X10_WCD_A_CHIP_ID_BYTE_1] = MSM8X10_WCD_A_CHIP_ID_BYTE_1__POR,
+	[MSM8X10_WCD_A_CHIP_ID_BYTE_2] = MSM8X10_WCD_A_CHIP_ID_BYTE_2__POR,
+	[MSM8X10_WCD_A_CHIP_ID_BYTE_3] = MSM8X10_WCD_A_CHIP_ID_BYTE_3__POR,
+	[MSM8X10_WCD_A_CHIP_VERSION] = MSM8X10_WCD_A_CHIP_VERSION__POR,
+	[MSM8X10_WCD_A_ANALOG_SLAVE_ID] = MSM8X10_WCD_A_ANALOG_SLAVE_ID__POR,
+	[MSM8X10_WCD_A_PIN_CTL_OE] = MSM8X10_WCD_A_PIN_CTL_OE__POR,
+	[MSM8X10_WCD_A_PIN_CTL_DATA] = MSM8X10_WCD_A_PIN_CTL_DATA__POR,
+	[MSM8X10_WCD_A_PIN_STATUS] = MSM8X10_WCD_A_PIN_STATUS__POR,
+	[MSM8X10_WCD_A_HDRIVE_CTL] = MSM8X10_WCD_A_HDRIVE_CTL__POR,
+	[MSM8X10_WCD_A_HDRIVE_I2C_CTL] = MSM8X10_WCD_A_HDRIVE_I2C_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RST_CTL] = MSM8X10_WCD_A_CDC_RST_CTL__POR,
+	[MSM8X10_WCD_A_CDC_TOP_CLK_CTL] = MSM8X10_WCD_A_CDC_TOP_CLK_CTL__POR,
+	[MSM8X10_WCD_A_CDC_ANA_CLK_CTL] = MSM8X10_WCD_A_CDC_ANA_CLK_CTL__POR,
+	[MSM8X10_WCD_A_CDC_DIG_CLK_CTL] = MSM8X10_WCD_A_CDC_DIG_CLK_CTL__POR,
+	[MSM8X10_WCD_A_PROCESS_MONITOR_CTL0] =
+			MSM8X10_WCD_A_PROCESS_MONITOR_CTL0__POR,
+	[MSM8X10_WCD_A_PROCESS_MONITOR_CTL1] =
+			MSM8X10_WCD_A_PROCESS_MONITOR_CTL1__POR,
+	[MSM8X10_WCD_A_PROCESS_MONITOR_CTL2] =
+			MSM8X10_WCD_A_PROCESS_MONITOR_CTL2__POR,
+	[MSM8X10_WCD_A_PROCESS_MONITOR_CTL3] =
+			MSM8X10_WCD_A_PROCESS_MONITOR_CTL3__POR,
+	[MSM8X10_WCD_A_QFUSE_CTL] = MSM8X10_WCD_A_QFUSE_CTL__POR,
+	[MSM8X10_WCD_A_QFUSE_STATUS] = MSM8X10_WCD_A_QFUSE_STATUS__POR,
+	[MSM8X10_WCD_A_QFUSE_DATA_OUT0] = MSM8X10_WCD_A_QFUSE_DATA_OUT0__POR,
+	[MSM8X10_WCD_A_QFUSE_DATA_OUT1] = MSM8X10_WCD_A_QFUSE_DATA_OUT1__POR,
+	[MSM8X10_WCD_A_QFUSE_DATA_OUT2] = MSM8X10_WCD_A_QFUSE_DATA_OUT2__POR,
+	[MSM8X10_WCD_A_QFUSE_DATA_OUT3] = MSM8X10_WCD_A_QFUSE_DATA_OUT3__POR,
+	[MSM8X10_WCD_A_CDC_CONN_TX1_CTL] = MSM8X10_WCD_A_CDC_CONN_TX1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CONN_TX2_CTL] = MSM8X10_WCD_A_CDC_CONN_TX2_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CONN_HPHR_DAC_CTL] =
+			MSM8X10_WCD_A_CDC_CONN_HPHR_DAC_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CONN_LO_DAC_CTL] =
+			MSM8X10_WCD_A_CDC_CONN_LO_DAC_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CONN_RX1_CTL] = MSM8X10_WCD_A_CDC_CONN_RX1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CONN_RX2_CTL] = MSM8X10_WCD_A_CDC_CONN_RX2_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CONN_RX3_CTL] = MSM8X10_WCD_A_CDC_CONN_RX3_CTL__POR,
+	[MSM8X10_WCD_A_DIGITAL_DEBUG_CTL] =
+			MSM8X10_WCD_A_DIGITAL_DEBUG_CTL__POR,
+	[MSM8X10_WCD_A_ANALOG_DEBUG_CTL] = MSM8X10_WCD_A_ANALOG_DEBUG_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RX1_CTL] = MSM8X10_WCD_A_CDC_RX1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RX2_CTL] = MSM8X10_WCD_A_CDC_RX2_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RX3_CTL] = MSM8X10_WCD_A_CDC_RX3_CTL__POR,
+	[MSM8X10_WCD_A_DEM_BYPASS_DATA0] = MSM8X10_WCD_A_DEM_BYPASS_DATA0__POR,
+	[MSM8X10_WCD_A_DEM_BYPASS_DATA1] = MSM8X10_WCD_A_DEM_BYPASS_DATA1__POR,
+	[MSM8X10_WCD_A_DEM_BYPASS_DATA2] = MSM8X10_WCD_A_DEM_BYPASS_DATA2__POR,
+	[MSM8X10_WCD_A_DEM_BYPASS_DATA3] = MSM8X10_WCD_A_DEM_BYPASS_DATA3__POR,
+	[MSM8X10_WCD_A_SPARE_0] = MSM8X10_WCD_A_SPARE_0__POR,
+	[MSM8X10_WCD_A_SPARE_1] = MSM8X10_WCD_A_SPARE_1__POR,
+	[MSM8X10_WCD_A_SPARE_2] = MSM8X10_WCD_A_SPARE_2__POR,
+	[MSM8X10_WCD_A_INTR_MODE] = MSM8X10_WCD_A_INTR_MODE__POR,
+	[MSM8X10_WCD_A_INTR_MASK0] = MSM8X10_WCD_A_INTR_MASK0__POR,
+	[MSM8X10_WCD_A_INTR_MASK1] = MSM8X10_WCD_A_INTR_MASK1__POR,
+	[MSM8X10_WCD_A_INTR_MASK2] = MSM8X10_WCD_A_INTR_MASK2__POR,
+	[MSM8X10_WCD_A_INTR_STATUS0] = MSM8X10_WCD_A_INTR_STATUS0__POR,
+	[MSM8X10_WCD_A_INTR_STATUS1] = MSM8X10_WCD_A_INTR_STATUS1__POR,
+	[MSM8X10_WCD_A_INTR_STATUS2] = MSM8X10_WCD_A_INTR_STATUS2__POR,
+	[MSM8X10_WCD_A_INTR_CLEAR0] = MSM8X10_WCD_A_INTR_CLEAR0__POR,
+	[MSM8X10_WCD_A_INTR_CLEAR1] = MSM8X10_WCD_A_INTR_CLEAR1__POR,
+	[MSM8X10_WCD_A_INTR_CLEAR2] = MSM8X10_WCD_A_INTR_CLEAR2__POR,
+	[MSM8X10_WCD_A_INTR_TEST0] = MSM8X10_WCD_A_INTR_TEST0__POR,
+	[MSM8X10_WCD_A_INTR_TEST1] = MSM8X10_WCD_A_INTR_TEST1__POR,
+	[MSM8X10_WCD_A_INTR_TEST2] = MSM8X10_WCD_A_INTR_TEST2__POR,
+	[MSM8X10_WCD_A_INTR_SET0] = MSM8X10_WCD_A_INTR_SET0__POR,
+	[MSM8X10_WCD_A_INTR_SET1] = MSM8X10_WCD_A_INTR_SET1__POR,
+	[MSM8X10_WCD_A_INTR_SET2] = MSM8X10_WCD_A_INTR_SET2__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_EN_CTL] = MSM8X10_WCD_A_CDC_MBHC_EN_CTL__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_FIR_B1_CFG] =
+			MSM8X10_WCD_A_CDC_MBHC_FIR_B1_CFG__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_FIR_B2_CFG] =
+			MSM8X10_WCD_A_CDC_MBHC_FIR_B2_CFG__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_TIMER_B1_CTL] =
+			MSM8X10_WCD_A_CDC_MBHC_TIMER_B1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_TIMER_B2_CTL] =
+			MSM8X10_WCD_A_CDC_MBHC_TIMER_B2_CTL__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_TIMER_B3_CTL] =
+			MSM8X10_WCD_A_CDC_MBHC_TIMER_B3_CTL__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_TIMER_B4_CTL] =
+			MSM8X10_WCD_A_CDC_MBHC_TIMER_B4_CTL__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_TIMER_B5_CTL] =
+			MSM8X10_WCD_A_CDC_MBHC_TIMER_B5_CTL__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_TIMER_B6_CTL] =
+			MSM8X10_WCD_A_CDC_MBHC_TIMER_B6_CTL__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_B1_STATUS] =
+			MSM8X10_WCD_A_CDC_MBHC_B1_STATUS__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_B2_STATUS] =
+			MSM8X10_WCD_A_CDC_MBHC_B2_STATUS__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_B3_STATUS] =
+			MSM8X10_WCD_A_CDC_MBHC_B3_STATUS__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_B4_STATUS] =
+			MSM8X10_WCD_A_CDC_MBHC_B4_STATUS__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_B5_STATUS] =
+			MSM8X10_WCD_A_CDC_MBHC_B5_STATUS__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_B1_CTL] = MSM8X10_WCD_A_CDC_MBHC_B1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_B2_CTL] = MSM8X10_WCD_A_CDC_MBHC_B2_CTL__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_VOLT_B1_CTL] =
+			MSM8X10_WCD_A_CDC_MBHC_VOLT_B1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_VOLT_B2_CTL] =
+			MSM8X10_WCD_A_CDC_MBHC_VOLT_B2_CTL__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_VOLT_B3_CTL] =
+			MSM8X10_WCD_A_CDC_MBHC_VOLT_B3_CTL__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_VOLT_B4_CTL] =
+			MSM8X10_WCD_A_CDC_MBHC_VOLT_B4_CTL__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_VOLT_B5_CTL] =
+			MSM8X10_WCD_A_CDC_MBHC_VOLT_B5_CTL__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_VOLT_B6_CTL] =
+			MSM8X10_WCD_A_CDC_MBHC_VOLT_B6_CTL__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_VOLT_B7_CTL] =
+			MSM8X10_WCD_A_CDC_MBHC_VOLT_B7_CTL__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_VOLT_B8_CTL] =
+			MSM8X10_WCD_A_CDC_MBHC_VOLT_B8_CTL__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_VOLT_B9_CTL] =
+			MSM8X10_WCD_A_CDC_MBHC_VOLT_B9_CTL__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_VOLT_B10_CTL] =
+			MSM8X10_WCD_A_CDC_MBHC_VOLT_B10_CTL__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_VOLT_B11_CTL] =
+			MSM8X10_WCD_A_CDC_MBHC_VOLT_B11_CTL__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_VOLT_B12_CTL] =
+			MSM8X10_WCD_A_CDC_MBHC_VOLT_B12_CTL__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_CLK_CTL] = MSM8X10_WCD_A_CDC_MBHC_CLK_CTL__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_INT_CTL] = MSM8X10_WCD_A_CDC_MBHC_INT_CTL__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_DEBUG_CTL] =
+			MSM8X10_WCD_A_CDC_MBHC_DEBUG_CTL__POR,
+	[MSM8X10_WCD_A_CDC_MBHC_SPARE] = MSM8X10_WCD_A_CDC_MBHC_SPARE__POR,
+	[MSM8X10_WCD_A_BIAS_REF_CTL] = MSM8X10_WCD_A_BIAS_REF_CTL__POR,
+	[MSM8X10_WCD_A_BIAS_CENTRAL_BG_CTL] =
+			MSM8X10_WCD_A_BIAS_CENTRAL_BG_CTL__POR,
+	[MSM8X10_WCD_A_BIAS_PRECHRG_CTL] = MSM8X10_WCD_A_BIAS_PRECHRG_CTL__POR,
+	[MSM8X10_WCD_A_BIAS_CURR_CTL_1] = MSM8X10_WCD_A_BIAS_CURR_CTL_1__POR,
+	[MSM8X10_WCD_A_BIAS_CURR_CTL_2] = MSM8X10_WCD_A_BIAS_CURR_CTL_2__POR,
+	[MSM8X10_WCD_A_BIAS_OSC_BG_CTL] = MSM8X10_WCD_A_BIAS_OSC_BG_CTL__POR,
+	[MSM8X10_WCD_A_MICB_CFILT_1_CTL] = MSM8X10_WCD_A_MICB_CFILT_1_CTL__POR,
+	[MSM8X10_WCD_A_MICB_CFILT_1_VAL] = MSM8X10_WCD_A_MICB_CFILT_1_VAL__POR,
+	[MSM8X10_WCD_A_MICB_CFILT_1_PRECHRG] =
+			MSM8X10_WCD_A_MICB_CFILT_1_PRECHRG__POR,
+	[MSM8X10_WCD_A_MICB_1_CTL] = MSM8X10_WCD_A_MICB_1_CTL__POR,
+	[MSM8X10_WCD_A_MICB_1_INT_RBIAS] = MSM8X10_WCD_A_MICB_1_INT_RBIAS__POR,
+	[MSM8X10_WCD_A_MICB_1_MBHC] = MSM8X10_WCD_A_MICB_1_MBHC__POR,
+	[MSM8X10_WCD_A_MBHC_INSERT_DETECT] =
+			MSM8X10_WCD_A_MBHC_INSERT_DETECT__POR,
+	[MSM8X10_WCD_A_MBHC_INSERT_DET_STATUS] =
+			MSM8X10_WCD_A_MBHC_INSERT_DET_STATUS__POR,
+	[MSM8X10_WCD_A_TX_COM_BIAS] = MSM8X10_WCD_A_TX_COM_BIAS__POR,
+	[MSM8X10_WCD_A_MBHC_SCALING_MUX_1] =
+			MSM8X10_WCD_A_MBHC_SCALING_MUX_1__POR,
+	[MSM8X10_WCD_A_MBHC_SCALING_MUX_2] =
+			MSM8X10_WCD_A_MBHC_SCALING_MUX_2__POR,
+	[MSM8X10_WCD_A_RESERVED_MAD_ANA_CTRL] =
+			MSM8X10_WCD_A_RESERVED_MAD_ANA_CTRL__POR,
+	[MSM8X10_WCD_A_TX_SUP_SWITCH_CTRL_1] =
+			MSM8X10_WCD_A_TX_SUP_SWITCH_CTRL_1__POR,
+	[MSM8X10_WCD_A_TX_SUP_SWITCH_CTRL_2] =
+			MSM8X10_WCD_A_TX_SUP_SWITCH_CTRL_2__POR,
+	[MSM8X10_WCD_A_TX_1_EN] = MSM8X10_WCD_A_TX_1_EN__POR,
+	[MSM8X10_WCD_A_TX_2_EN] = MSM8X10_WCD_A_TX_2_EN__POR,
+	[MSM8X10_WCD_A_TX_1_2_ADC_CH1] = MSM8X10_WCD_A_TX_1_2_ADC_CH1__POR,
+	[MSM8X10_WCD_A_TX_1_2_ADC_CH2] = MSM8X10_WCD_A_TX_1_2_ADC_CH2__POR,
+	[MSM8X10_WCD_A_TX_1_2_ATEST_REFCTRL] =
+			MSM8X10_WCD_A_TX_1_2_ATEST_REFCTRL__POR,
+	[MSM8X10_WCD_A_TX_1_2_TEST_CTL] =
+			MSM8X10_WCD_A_TX_1_2_TEST_CTL__POR,
+	[MSM8X10_WCD_A_TX_1_2_TEST_BLOCK_EN] =
+			MSM8X10_WCD_A_TX_1_2_TEST_BLOCK_EN__POR,
+	[MSM8X10_WCD_A_TX_1_2_TXFE_CLKDIV] =
+			MSM8X10_WCD_A_TX_1_2_TXFE_CLKDIV__POR,
+	[MSM8X10_WCD_A_TX_1_2_SAR_ERR_CH1] =
+			MSM8X10_WCD_A_TX_1_2_SAR_ERR_CH1__POR,
+	[MSM8X10_WCD_A_TX_1_2_SAR_ERR_CH2] =
+			MSM8X10_WCD_A_TX_1_2_SAR_ERR_CH2__POR,
+	[MSM8X10_WCD_A_TX_3_EN] = MSM8X10_WCD_A_TX_3_EN__POR,
+	[MSM8X10_WCD_A_TX_1_2_TEST_EN] = MSM8X10_WCD_A_TX_1_2_TEST_EN__POR,
+	[MSM8X10_WCD_A_TX_7_MBHC_EN_ATEST_CTRL] =
+			MSM8X10_WCD_A_TX_7_MBHC_EN_ATEST_CTRL__POR,
+	[MSM8X10_WCD_A_TX_7_MBHC_SAR_ERR] =
+			MSM8X10_WCD_A_TX_7_MBHC_SAR_ERR__POR,
+	[MSM8X10_WCD_A_CP_EN] = MSM8X10_WCD_A_CP_EN__POR,
+	[MSM8X10_WCD_A_CP_CLK] = MSM8X10_WCD_A_CP_CLK__POR,
+	[MSM8X10_WCD_A_CP_STATIC] = MSM8X10_WCD_A_CP_STATIC__POR,
+	[MSM8X10_WCD_A_CP_DCC1] = MSM8X10_WCD_A_CP_DCC1__POR,
+	[MSM8X10_WCD_A_CP_DCC3] = MSM8X10_WCD_A_CP_DCC3__POR,
+	[MSM8X10_WCD_A_CP_ATEST] = MSM8X10_WCD_A_CP_ATEST__POR,
+	[MSM8X10_WCD_A_CP_DTEST] = MSM8X10_WCD_A_CP_DTEST__POR,
+	[MSM8X10_WCD_A_RX_AUX_SW_CTL] = MSM8X10_WCD_A_RX_AUX_SW_CTL__POR,
+	[MSM8X10_WCD_A_RX_PA_AUX_IN_CONN] =
+			MSM8X10_WCD_A_RX_PA_AUX_IN_CONN__POR,
+	[MSM8X10_WCD_A_RX_COM_TIMER_DIV] = MSM8X10_WCD_A_RX_COM_TIMER_DIV__POR,
+	[MSM8X10_WCD_A_RX_COM_OCP_CTL] = MSM8X10_WCD_A_RX_COM_OCP_CTL__POR,
+	[MSM8X10_WCD_A_RX_COM_OCP_COUNT] = MSM8X10_WCD_A_RX_COM_OCP_COUNT__POR,
+	[MSM8X10_WCD_A_RX_COM_DAC_CTL] = MSM8X10_WCD_A_RX_COM_DAC_CTL__POR,
+	[MSM8X10_WCD_A_RX_COM_BIAS] = MSM8X10_WCD_A_RX_COM_BIAS__POR,
+	[MSM8X10_WCD_A_RX_HPH_AUTO_CHOP] = MSM8X10_WCD_A_RX_HPH_AUTO_CHOP__POR,
+	[MSM8X10_WCD_A_RX_HPH_CHOP_CTL] = MSM8X10_WCD_A_RX_HPH_CHOP_CTL__POR,
+	[MSM8X10_WCD_A_RX_HPH_BIAS_PA] = MSM8X10_WCD_A_RX_HPH_BIAS_PA__POR,
+	[MSM8X10_WCD_A_RX_HPH_BIAS_LDO] = MSM8X10_WCD_A_RX_HPH_BIAS_LDO__POR,
+	[MSM8X10_WCD_A_RX_HPH_BIAS_CNP] = MSM8X10_WCD_A_RX_HPH_BIAS_CNP__POR,
+	[MSM8X10_WCD_A_RX_HPH_BIAS_WG_OCP] =
+			MSM8X10_WCD_A_RX_HPH_BIAS_WG_OCP__POR,
+	[MSM8X10_WCD_A_RX_HPH_OCP_CTL] = MSM8X10_WCD_A_RX_HPH_OCP_CTL__POR,
+	[MSM8X10_WCD_A_RX_HPH_CNP_EN] = MSM8X10_WCD_A_RX_HPH_CNP_EN__POR,
+	[MSM8X10_WCD_A_RX_HPH_CNP_WG_CTL] =
+			MSM8X10_WCD_A_RX_HPH_CNP_WG_CTL__POR,
+	[MSM8X10_WCD_A_RX_HPH_CNP_WG_TIME] =
+			MSM8X10_WCD_A_RX_HPH_CNP_WG_TIME__POR,
+	[MSM8X10_WCD_A_RX_HPH_L_GAIN] = MSM8X10_WCD_A_RX_HPH_L_GAIN__POR,
+	[MSM8X10_WCD_A_RX_HPH_L_TEST] = MSM8X10_WCD_A_RX_HPH_L_TEST__POR,
+	[MSM8X10_WCD_A_RX_HPH_L_PA_CTL] = MSM8X10_WCD_A_RX_HPH_L_PA_CTL__POR,
+	[MSM8X10_WCD_A_RX_HPH_L_DAC_CTL] =
+			MSM8X10_WCD_A_RX_HPH_L_DAC_CTL__POR,
+	[MSM8X10_WCD_A_RX_HPH_L_ATEST] = MSM8X10_WCD_A_RX_HPH_L_ATEST__POR,
+	[MSM8X10_WCD_A_RX_HPH_L_STATUS] = MSM8X10_WCD_A_RX_HPH_L_STATUS__POR,
+	[MSM8X10_WCD_A_RX_HPH_R_GAIN] = MSM8X10_WCD_A_RX_HPH_R_GAIN__POR,
+	[MSM8X10_WCD_A_RX_HPH_R_TEST] = MSM8X10_WCD_A_RX_HPH_R_TEST__POR,
+	[MSM8X10_WCD_A_RX_HPH_R_PA_CTL] = MSM8X10_WCD_A_RX_HPH_R_PA_CTL__POR,
+	[MSM8X10_WCD_A_RX_HPH_R_DAC_CTL] = MSM8X10_WCD_A_RX_HPH_R_DAC_CTL__POR,
+	[MSM8X10_WCD_A_RX_HPH_R_ATEST] = MSM8X10_WCD_A_RX_HPH_R_ATEST__POR,
+	[MSM8X10_WCD_A_RX_HPH_R_STATUS] = MSM8X10_WCD_A_RX_HPH_R_STATUS__POR,
+	[MSM8X10_WCD_A_RX_EAR_BIAS_PA] = MSM8X10_WCD_A_RX_EAR_BIAS_PA__POR,
+	[MSM8X10_WCD_A_RX_EAR_BIAS_CMBUFF] =
+			MSM8X10_WCD_A_RX_EAR_BIAS_CMBUFF__POR,
+	[MSM8X10_WCD_A_RX_EAR_EN] = MSM8X10_WCD_A_RX_EAR_EN__POR,
+	[MSM8X10_WCD_A_RX_EAR_GAIN] = MSM8X10_WCD_A_RX_EAR_GAIN__POR,
+	[MSM8X10_WCD_A_RX_EAR_CMBUFF] = MSM8X10_WCD_A_RX_EAR_CMBUFF__POR,
+	[MSM8X10_WCD_A_RX_EAR_ICTL] = MSM8X10_WCD_A_RX_EAR_ICTL__POR,
+	[MSM8X10_WCD_A_RX_EAR_CCOMP] = MSM8X10_WCD_A_RX_EAR_CCOMP__POR,
+	[MSM8X10_WCD_A_RX_EAR_VCM] = MSM8X10_WCD_A_RX_EAR_VCM__POR,
+	[MSM8X10_WCD_A_RX_EAR_CNP] = MSM8X10_WCD_A_RX_EAR_CNP__POR,
+	[MSM8X10_WCD_A_RX_EAR_DAC_CTL_ATEST] =
+			MSM8X10_WCD_A_RX_EAR_DAC_CTL_ATEST__POR,
+	[MSM8X10_WCD_A_RX_EAR_STATUS] = MSM8X10_WCD_A_RX_EAR_STATUS__POR,
+	[MSM8X10_WCD_A_RX_LINE_BIAS_PA] =
+			MSM8X10_WCD_A_RX_LINE_BIAS_PA__POR,
+	[MSM8X10_WCD_A_RX_BUCK_BIAS1] = MSM8X10_WCD_A_RX_BUCK_BIAS1__POR,
+	[MSM8X10_WCD_A_RX_BUCK_BIAS2] = MSM8X10_WCD_A_RX_BUCK_BIAS2__POR,
+	[MSM8X10_WCD_A_RX_LINE_COM] = MSM8X10_WCD_A_RX_LINE_COM__POR,
+	[MSM8X10_WCD_A_RX_LINE_CNP_EN] = MSM8X10_WCD_A_RX_LINE_CNP_EN__POR,
+	[MSM8X10_WCD_A_RX_LINE_CNP_WG_CTL] =
+			MSM8X10_WCD_A_RX_LINE_CNP_WG_CTL__POR,
+	[MSM8X10_WCD_A_RX_LINE_CNP_WG_TIME] =
+			MSM8X10_WCD_A_RX_LINE_CNP_WG_TIME__POR,
+	[MSM8X10_WCD_A_RX_LINE_1_GAIN] = MSM8X10_WCD_A_RX_LINE_1_GAIN__POR,
+	[MSM8X10_WCD_A_RX_LINE_1_TEST] = MSM8X10_WCD_A_RX_LINE_1_TEST__POR,
+	[MSM8X10_WCD_A_RX_LINE_1_DAC_CTL] =
+			MSM8X10_WCD_A_RX_LINE_1_DAC_CTL__POR,
+	[MSM8X10_WCD_A_RX_LINE_1_STATUS] =
+			MSM8X10_WCD_A_RX_LINE_1_STATUS__POR,
+	[MSM8X10_WCD_A_RX_LINE_CNP_DBG] = MSM8X10_WCD_A_RX_LINE_CNP_DBG__POR,
+	[MSM8X10_WCD_A_SPKR_DRV_EN] = MSM8X10_WCD_A_SPKR_DRV_EN__POR,
+	[MSM8X10_WCD_A_SPKR_DRV_GAIN] = MSM8X10_WCD_A_SPKR_DRV_GAIN__POR,
+	[MSM8X10_WCD_A_SPKR_DRV_DAC_CTL] = MSM8X10_WCD_A_SPKR_DRV_DAC_CTL__POR,
+	[MSM8X10_WCD_A_SPKR_DRV_OCP_CTL] = MSM8X10_WCD_A_SPKR_DRV_OCP_CTL__POR,
+	[MSM8X10_WCD_A_SPKR_DRV_CLIP_DET] =
+			MSM8X10_WCD_A_SPKR_DRV_CLIP_DET__POR,
+	[MSM8X10_WCD_A_SPKR_DRV_IEC] = MSM8X10_WCD_A_SPKR_DRV_IEC__POR,
+	[MSM8X10_WCD_A_SPKR_DRV_DBG_DAC] = MSM8X10_WCD_A_SPKR_DRV_DBG_DAC__POR,
+	[MSM8X10_WCD_A_SPKR_DRV_DBG_PA] = MSM8X10_WCD_A_SPKR_DRV_DBG_PA__POR,
+	[MSM8X10_WCD_A_SPKR_DRV_DBG_PWRSTG] =
+			MSM8X10_WCD_A_SPKR_DRV_DBG_PWRSTG__POR,
+	[MSM8X10_WCD_A_SPKR_DRV_BIAS_LDO] =
+			MSM8X10_WCD_A_SPKR_DRV_BIAS_LDO__POR,
+	[MSM8X10_WCD_A_SPKR_DRV_BIAS_INT] =
+			MSM8X10_WCD_A_SPKR_DRV_BIAS_INT__POR,
+	[MSM8X10_WCD_A_SPKR_DRV_BIAS_PA] = MSM8X10_WCD_A_SPKR_DRV_BIAS_PA__POR,
+	[MSM8X10_WCD_A_SPKR_DRV_STATUS_OCP] =
+			MSM8X10_WCD_A_SPKR_DRV_STATUS_OCP__POR,
+	[MSM8X10_WCD_A_SPKR_DRV_STATUS_PA] =
+			MSM8X10_WCD_A_SPKR_DRV_STATUS_PA__POR,
+	[MSM8X10_WCD_A_RC_OSC_FREQ] = MSM8X10_WCD_A_RC_OSC_FREQ__POR,
+	[MSM8X10_WCD_A_RC_OSC_TEST] = MSM8X10_WCD_A_RC_OSC_TEST__POR,
+	[MSM8X10_WCD_A_RC_OSC_STATUS] = MSM8X10_WCD_A_RC_OSC_STATUS__POR,
+	[MSM8X10_WCD_A_RC_OSC_TUNER] = MSM8X10_WCD_A_RC_OSC_TUNER__POR,
+	[MSM8X10_WCD_A_MBHC_HPH] = MSM8X10_WCD_A_MBHC_HPH__POR,
+	[MSM8X10_WCD_A_CDC_CLK_RX_RESET_CTL] =
+			MSM8X10_WCD_A_CDC_CLK_RX_RESET_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CLK_TX_RESET_B1_CTL] =
+			MSM8X10_WCD_A_CDC_CLK_TX_RESET_B1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CLK_DMIC_B1_CTL] =
+			MSM8X10_WCD_A_CDC_CLK_DMIC_B1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CLK_RX_I2S_CTL] =
+			MSM8X10_WCD_A_CDC_CLK_RX_I2S_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CLK_TX_I2S_CTL] =
+			MSM8X10_WCD_A_CDC_CLK_TX_I2S_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CLK_OTHR_RESET_B1_CTL] =
+			MSM8X10_WCD_A_CDC_CLK_OTHR_RESET_B1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL] =
+			MSM8X10_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CLK_OTHR_CTL] = MSM8X10_WCD_A_CDC_CLK_OTHR_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CLK_RX_B1_CTL] =
+			MSM8X10_WCD_A_CDC_CLK_RX_B1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CLK_MCLK_CTL] = MSM8X10_WCD_A_CDC_CLK_MCLK_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CLK_PDM_CTL] = MSM8X10_WCD_A_CDC_CLK_PDM_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CLK_SD_CTL] = MSM8X10_WCD_A_CDC_CLK_SD_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RX1_B1_CTL] = MSM8X10_WCD_A_CDC_RX1_B1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RX2_B1_CTL] = MSM8X10_WCD_A_CDC_RX2_B1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RX3_B1_CTL] = MSM8X10_WCD_A_CDC_RX3_B1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RX1_B2_CTL] = MSM8X10_WCD_A_CDC_RX1_B2_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RX2_B2_CTL] = MSM8X10_WCD_A_CDC_RX2_B2_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RX3_B2_CTL] = MSM8X10_WCD_A_CDC_RX3_B2_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RX1_B3_CTL] = MSM8X10_WCD_A_CDC_RX1_B3_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RX2_B3_CTL] = MSM8X10_WCD_A_CDC_RX2_B3_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RX3_B3_CTL] = MSM8X10_WCD_A_CDC_RX3_B3_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RX1_B4_CTL] = MSM8X10_WCD_A_CDC_RX1_B4_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RX2_B4_CTL] = MSM8X10_WCD_A_CDC_RX2_B4_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RX3_B4_CTL] = MSM8X10_WCD_A_CDC_RX3_B4_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RX1_B5_CTL] = MSM8X10_WCD_A_CDC_RX1_B5_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RX2_B5_CTL] = MSM8X10_WCD_A_CDC_RX2_B5_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RX3_B5_CTL] = MSM8X10_WCD_A_CDC_RX3_B5_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RX1_B6_CTL] = MSM8X10_WCD_A_CDC_RX1_B6_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RX2_B6_CTL] = MSM8X10_WCD_A_CDC_RX2_B6_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RX3_B6_CTL] = MSM8X10_WCD_A_CDC_RX3_B6_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RX1_VOL_CTL_B1_CTL] =
+			MSM8X10_WCD_A_CDC_RX1_VOL_CTL_B1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RX2_VOL_CTL_B1_CTL] =
+			MSM8X10_WCD_A_CDC_RX2_VOL_CTL_B1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RX3_VOL_CTL_B1_CTL] =
+			MSM8X10_WCD_A_CDC_RX3_VOL_CTL_B1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RX1_VOL_CTL_B2_CTL] =
+			MSM8X10_WCD_A_CDC_RX1_VOL_CTL_B2_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RX2_VOL_CTL_B2_CTL] =
+			MSM8X10_WCD_A_CDC_RX2_VOL_CTL_B2_CTL__POR,
+	[MSM8X10_WCD_A_CDC_RX3_VOL_CTL_B2_CTL] =
+			MSM8X10_WCD_A_CDC_RX3_VOL_CTL_B2_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B1_CTL] =
+			MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B2_CTL] =
+			MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B2_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B3_CTL] =
+			MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B3_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B4_CTL] =
+			MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B4_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CLSG_GAIN_THRESH_CTL] =
+			MSM8X10_WCD_A_CDC_CLSG_GAIN_THRESH_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CLSG_TIMER_B1_CFG] =
+			MSM8X10_WCD_A_CDC_CLSG_TIMER_B1_CFG__POR,
+	[MSM8X10_WCD_A_CDC_CLSG_TIMER_B2_CFG] =
+			MSM8X10_WCD_A_CDC_CLSG_TIMER_B2_CFG__POR,
+	[MSM8X10_WCD_A_CDC_CLSG_CTL] = MSM8X10_WCD_A_CDC_CLSG_CTL__POR,
+	[MSM8X10_WCD_A_CDC_TX1_VOL_CTL_TIMER] =
+			MSM8X10_WCD_A_CDC_TX1_VOL_CTL_TIMER__POR,
+	[MSM8X10_WCD_A_CDC_TX2_VOL_CTL_TIMER] =
+			MSM8X10_WCD_A_CDC_TX2_VOL_CTL_TIMER__POR,
+	[MSM8X10_WCD_A_CDC_TX1_VOL_CTL_GAIN] =
+			MSM8X10_WCD_A_CDC_TX1_VOL_CTL_GAIN__POR,
+	[MSM8X10_WCD_A_CDC_TX2_VOL_CTL_GAIN] =
+			MSM8X10_WCD_A_CDC_TX2_VOL_CTL_GAIN__POR,
+	[MSM8X10_WCD_A_CDC_TX1_VOL_CTL_CFG] =
+			MSM8X10_WCD_A_CDC_TX1_VOL_CTL_CFG__POR,
+	[MSM8X10_WCD_A_CDC_TX2_VOL_CTL_CFG] =
+			MSM8X10_WCD_A_CDC_TX2_VOL_CTL_CFG__POR,
+	[MSM8X10_WCD_A_CDC_TX1_MUX_CTL] =
+			MSM8X10_WCD_A_CDC_TX1_MUX_CTL__POR,
+	[MSM8X10_WCD_A_CDC_TX2_MUX_CTL] =
+			MSM8X10_WCD_A_CDC_TX2_MUX_CTL__POR,
+	[MSM8X10_WCD_A_CDC_TX1_CLK_FS_CTL] =
+			MSM8X10_WCD_A_CDC_TX1_CLK_FS_CTL__POR,
+	[MSM8X10_WCD_A_CDC_TX2_CLK_FS_CTL] =
+			MSM8X10_WCD_A_CDC_TX2_CLK_FS_CTL__POR,
+	[MSM8X10_WCD_A_CDC_TX1_DMIC_CTL] =
+			MSM8X10_WCD_A_CDC_TX1_DMIC_CTL__POR,
+	[MSM8X10_WCD_A_CDC_TX2_DMIC_CTL] =
+			MSM8X10_WCD_A_CDC_TX2_DMIC_CTL__POR,
+	[MSM8X10_WCD_A_CDC_IIR1_GAIN_B1_CTL] =
+			MSM8X10_WCD_A_CDC_IIR1_GAIN_B1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_IIR2_GAIN_B1_CTL] =
+			MSM8X10_WCD_A_CDC_IIR2_GAIN_B1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_IIR1_GAIN_B2_CTL] =
+			MSM8X10_WCD_A_CDC_IIR1_GAIN_B2_CTL__POR,
+	[MSM8X10_WCD_A_CDC_IIR2_GAIN_B2_CTL] =
+			MSM8X10_WCD_A_CDC_IIR2_GAIN_B2_CTL__POR,
+	[MSM8X10_WCD_A_CDC_IIR1_GAIN_B3_CTL] =
+			MSM8X10_WCD_A_CDC_IIR1_GAIN_B3_CTL__POR,
+	[MSM8X10_WCD_A_CDC_IIR2_GAIN_B3_CTL] =
+			MSM8X10_WCD_A_CDC_IIR2_GAIN_B3_CTL__POR,
+	[MSM8X10_WCD_A_CDC_IIR1_GAIN_B4_CTL] =
+			MSM8X10_WCD_A_CDC_IIR1_GAIN_B4_CTL__POR,
+	[MSM8X10_WCD_A_CDC_IIR2_GAIN_B4_CTL] =
+			MSM8X10_WCD_A_CDC_IIR2_GAIN_B4_CTL__POR,
+	[MSM8X10_WCD_A_CDC_IIR1_GAIN_B5_CTL] =
+			MSM8X10_WCD_A_CDC_IIR1_GAIN_B5_CTL__POR,
+	[MSM8X10_WCD_A_CDC_IIR2_GAIN_B5_CTL] =
+			MSM8X10_WCD_A_CDC_IIR2_GAIN_B5_CTL__POR,
+	[MSM8X10_WCD_A_CDC_IIR1_GAIN_B6_CTL] =
+			MSM8X10_WCD_A_CDC_IIR1_GAIN_B6_CTL__POR,
+	[MSM8X10_WCD_A_CDC_IIR2_GAIN_B6_CTL] =
+			MSM8X10_WCD_A_CDC_IIR2_GAIN_B6_CTL__POR,
+	[MSM8X10_WCD_A_CDC_IIR1_GAIN_B7_CTL] =
+			MSM8X10_WCD_A_CDC_IIR1_GAIN_B7_CTL__POR,
+	[MSM8X10_WCD_A_CDC_IIR2_GAIN_B7_CTL] =
+			MSM8X10_WCD_A_CDC_IIR2_GAIN_B7_CTL__POR,
+	[MSM8X10_WCD_A_CDC_IIR1_GAIN_B8_CTL] =
+			MSM8X10_WCD_A_CDC_IIR1_GAIN_B8_CTL__POR,
+	[MSM8X10_WCD_A_CDC_IIR2_GAIN_B8_CTL] =
+			MSM8X10_WCD_A_CDC_IIR2_GAIN_B8_CTL__POR,
+	[MSM8X10_WCD_A_CDC_IIR1_CTL] = MSM8X10_WCD_A_CDC_IIR1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_IIR2_CTL] = MSM8X10_WCD_A_CDC_IIR2_CTL__POR,
+	[MSM8X10_WCD_A_CDC_IIR1_GAIN_TIMER_CTL] =
+			MSM8X10_WCD_A_CDC_IIR1_GAIN_TIMER_CTL__POR,
+	[MSM8X10_WCD_A_CDC_IIR2_GAIN_TIMER_CTL] =
+			MSM8X10_WCD_A_CDC_IIR2_GAIN_TIMER_CTL__POR,
+	[MSM8X10_WCD_A_CDC_IIR1_COEF_B1_CTL] =
+			MSM8X10_WCD_A_CDC_IIR1_COEF_B1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_IIR2_COEF_B1_CTL] =
+			MSM8X10_WCD_A_CDC_IIR2_COEF_B1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_IIR1_COEF_B2_CTL] =
+			MSM8X10_WCD_A_CDC_IIR1_COEF_B2_CTL__POR,
+	[MSM8X10_WCD_A_CDC_IIR2_COEF_B2_CTL] =
+			MSM8X10_WCD_A_CDC_IIR2_COEF_B2_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CONN_RX1_B1_CTL] =
+			MSM8X10_WCD_A_CDC_CONN_RX1_B1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CONN_RX1_B2_CTL] =
+			MSM8X10_WCD_A_CDC_CONN_RX1_B2_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CONN_RX1_B3_CTL] =
+			MSM8X10_WCD_A_CDC_CONN_RX1_B3_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CONN_RX2_B1_CTL] =
+			MSM8X10_WCD_A_CDC_CONN_RX2_B1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CONN_RX2_B2_CTL] =
+			MSM8X10_WCD_A_CDC_CONN_RX2_B2_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CONN_RX2_B3_CTL] =
+			MSM8X10_WCD_A_CDC_CONN_RX2_B3_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CONN_RX3_B1_CTL] =
+			MSM8X10_WCD_A_CDC_CONN_RX3_B1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CONN_RX3_B2_CTL] =
+			MSM8X10_WCD_A_CDC_CONN_RX3_B2_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CONN_TX_B1_CTL] =
+			MSM8X10_WCD_A_CDC_CONN_TX_B1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CONN_EQ1_B1_CTL] =
+			MSM8X10_WCD_A_CDC_CONN_EQ1_B1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CONN_EQ1_B2_CTL] =
+			MSM8X10_WCD_A_CDC_CONN_EQ1_B2_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CONN_EQ1_B3_CTL] =
+			MSM8X10_WCD_A_CDC_CONN_EQ1_B3_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CONN_EQ1_B4_CTL] =
+			MSM8X10_WCD_A_CDC_CONN_EQ1_B4_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CONN_EQ2_B1_CTL] =
+			MSM8X10_WCD_A_CDC_CONN_EQ2_B1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CONN_EQ2_B2_CTL] =
+			MSM8X10_WCD_A_CDC_CONN_EQ2_B2_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CONN_EQ2_B3_CTL] =
+			MSM8X10_WCD_A_CDC_CONN_EQ2_B3_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CONN_EQ2_B4_CTL] =
+			MSM8X10_WCD_A_CDC_CONN_EQ2_B4_CTL__POR,
+	[MSM8X10_WCD_A_CDC_CONN_TX_I2S_SD1_CTL] =
+			MSM8X10_WCD_A_CDC_CONN_TX_I2S_SD1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_TOP_GAIN_UPDATE] =
+			MSM8X10_WCD_A_CDC_TOP_GAIN_UPDATE__POR,
+	[MSM8X10_WCD_A_CDC_TOP_CTL] = MSM8X10_WCD_A_CDC_TOP_CTL__POR,
+	[MSM8X10_WCD_A_CDC_DEBUG_DESER1_CTL] =
+			MSM8X10_WCD_A_CDC_DEBUG_DESER1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_DEBUG_DESER2_CTL] =
+			MSM8X10_WCD_A_CDC_DEBUG_DESER2_CTL__POR,
+	[MSM8X10_WCD_A_CDC_DEBUG_B1_CTL] =
+			MSM8X10_WCD_A_CDC_DEBUG_B1_CTL__POR,
+	[MSM8X10_WCD_A_CDC_DEBUG_B2_CTL] =
+			MSM8X10_WCD_A_CDC_DEBUG_B2_CTL__POR,
+	[MSM8X10_WCD_A_CDC_DEBUG_B3_CTL] =
+			MSM8X10_WCD_A_CDC_DEBUG_B3_CTL__POR,
+};
diff --git a/sound/soc/codecs/msm8x10-wcd.c b/sound/soc/codecs/msm8x10-wcd.c
new file mode 100644
index 0000000..c8647fb1
--- /dev/null
+++ b/sound/soc/codecs/msm8x10-wcd.c
@@ -0,0 +1,2515 @@
+/* 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/init.h>
+#include <linux/firmware.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/printk.h>
+#include <linux/ratelimit.h>
+#include <linux/debugfs.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/pm_runtime.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/of_gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/mfd/wcd9xxx/core.h>
+#include <linux/mfd/wcd9xxx/pdata.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/tlv.h>
+#include "msm8x10-wcd.h"
+#include "wcd9xxx-resmgr.h"
+#include "msm8x10_wcd_registers.h"
+
+#define MSM8X10_WCD_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
+			SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000)
+#define MSM8X10_WCD_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
+
+#define NUM_DECIMATORS		2
+#define NUM_INTERPOLATORS	3
+#define BITS_PER_REG		8
+#define MSM8X10_WCD_TX_PORT_NUMBER	4
+
+#define MSM8X10_WCD_I2S_MASTER_MODE_MASK	0x08
+#define MSM8X10_DINO_CODEC_BASE_ADDR		0xFE043000
+
+#define MAX_MSM8X10_WCD_DEVICE	4
+#define CODEC_DT_MAX_PROP_SIZE	40
+#define MSM8X10_WCD_I2C_GSBI_SLAVE_ID "1-000d"
+
+enum {
+	MSM8X10_WCD_I2C_TOP_LEVEL = 0,
+	MSM8X10_WCD_I2C_ANALOG,
+	MSM8X10_WCD_I2C_DIGITAL_1,
+	MSM8X10_WCD_I2C_DIGITAL_2,
+};
+
+enum {
+	AIF1_PB = 0,
+	AIF1_CAP,
+	NUM_CODEC_DAIS,
+};
+
+enum {
+	RX_MIX1_INP_SEL_ZERO = 0,
+	RX_MIX1_INP_SEL_IIR1,
+	RX_MIX1_INP_SEL_IIR2,
+	RX_MIX1_INP_SEL_RX1,
+	RX_MIX1_INP_SEL_RX2,
+	RX_MIX1_INP_SEL_RX3,
+};
+
+static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
+static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1);
+static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
+static struct snd_soc_dai_driver msm8x10_wcd_i2s_dai[];
+static const DECLARE_TLV_DB_SCALE(aux_pga_gain, 0, 2, 0);
+
+/* Codec supports 2 IIR filters */
+enum {
+	IIR1 = 0,
+	IIR2,
+	IIR_MAX,
+};
+
+/* Codec supports 5 bands */
+enum {
+	BAND1 = 0,
+	BAND2,
+	BAND3,
+	BAND4,
+	BAND5,
+	BAND_MAX,
+};
+
+struct hpf_work {
+	struct msm8x10_wcd_priv *msm8x10_wcd;
+	u32 decimator;
+	u8 tx_hpf_cut_of_freq;
+	struct delayed_work dwork;
+};
+
+static struct hpf_work tx_hpf_work[NUM_DECIMATORS];
+
+struct msm8x10_wcd_priv {
+	struct snd_soc_codec *codec;
+	u32 adc_count;
+	u32 rx_bias_count;
+	s32 dmic_1_2_clk_cnt;
+
+	/* resmgr module */
+	struct wcd9xxx_resmgr resmgr;
+	/* mbhc module */
+	struct wcd9xxx_mbhc mbhc;
+};
+
+static unsigned short rx_digital_gain_reg[] = {
+	MSM8X10_WCD_A_CDC_RX1_VOL_CTL_B2_CTL,
+	MSM8X10_WCD_A_CDC_RX2_VOL_CTL_B2_CTL,
+	MSM8X10_WCD_A_CDC_RX3_VOL_CTL_B2_CTL,
+};
+
+static unsigned short tx_digital_gain_reg[] = {
+	MSM8X10_WCD_A_CDC_TX1_VOL_CTL_GAIN,
+	MSM8X10_WCD_A_CDC_TX2_VOL_CTL_GAIN,
+};
+
+struct msm8x10_wcd_i2c {
+	struct i2c_client *client;
+	struct i2c_msg xfer_msg[2];
+	struct mutex xfer_lock;
+	int mod_id;
+};
+
+static char *msm8x10_wcd_supplies[] = {
+	"cdc-vdd-mic-bias", "cdc-vdda-h", "cdc-vdd-1p2", "cdc-vdd-px",
+	"cdc-vdda-cp",
+};
+
+static int msm8x10_wcd_dt_parse_vreg_info(struct device *dev,
+	struct msm8x10_wcd_regulator *vreg, const char *vreg_name);
+static int msm8x10_wcd_dt_parse_micbias_info(struct device *dev,
+	struct msm8x10_wcd_micbias_setting *micbias);
+static struct msm8x10_wcd_pdata *msm8x10_wcd_populate_dt_pdata(
+	struct device *dev);
+
+struct msm8x10_wcd_i2c msm8x10_wcd_modules[MAX_MSM8X10_WCD_DEVICE];
+
+
+static int get_i2c_msm8x10_wcd_device_info(u16 reg,
+					   struct msm8x10_wcd_i2c **msm8x10_wcd)
+{
+	int rtn = 0;
+	int value = ((reg & 0x0f00) >> 8) & 0x000f;
+	pr_debug("%s: reg(0x%x) value(%d)\n", __func__, reg, value);
+	switch (value) {
+	case 0:
+	case 1:
+		*msm8x10_wcd = &msm8x10_wcd_modules[value];
+		break;
+	default:
+		rtn = -EINVAL;
+		break;
+	}
+	return rtn;
+}
+
+static int msm8x10_wcd_abh_write_device(u16 reg, unsigned int *value, u32 bytes)
+{
+	u32 temp = ((u32)(*value)) & 0x000000FF;
+	u32 offset = (((u32)(reg)) ^ 0x00000400) & 0x00000FFF;
+	iowrite32(temp, ioremap(MSM8X10_DINO_CODEC_BASE_ADDR + offset, 4));
+	return 0;
+}
+
+static int msm8x10_wcd_abh_read_device(u16 reg, u32 bytes, unsigned int *value)
+{
+	u32 offset = (((u32)(reg)) ^ 0x00000400) & 0x00000FFF;
+	*value = ioread32(ioremap(MSM8X10_DINO_CODEC_BASE_ADDR +
+				      offset, 4));
+	return 0;
+}
+
+static int msm8x10_wcd_i2c_write_device(u16 reg, u8 *value, u32 bytes)
+{
+
+	struct i2c_msg *msg;
+	int ret;
+	u8 reg_addr = 0;
+	u8 data[bytes + 1];
+	struct msm8x10_wcd_i2c *msm8x10_wcd = NULL;
+
+	ret = get_i2c_msm8x10_wcd_device_info(reg, &msm8x10_wcd);
+	if (ret) {
+		pr_err("%s: Invalid register address\n", __func__);
+		return ret;
+	}
+
+	if (msm8x10_wcd == NULL || msm8x10_wcd->client == NULL) {
+		pr_err("%s: Failed to get device info\n", __func__);
+		return -ENODEV;
+	}
+	reg_addr = (u8)reg;
+	msg = &msm8x10_wcd->xfer_msg[0];
+	msg->addr = msm8x10_wcd->client->addr;
+	msg->len = bytes + 1;
+	msg->flags = 0;
+	data[0] = reg;
+	data[1] = *value;
+	msg->buf = data;
+	ret = i2c_transfer(msm8x10_wcd->client->adapter,
+			   msm8x10_wcd->xfer_msg, 1);
+	/* Try again if the write fails */
+	if (ret != 1) {
+		ret = i2c_transfer(msm8x10_wcd->client->adapter,
+				   msm8x10_wcd->xfer_msg, 1);
+		if (ret != 1) {
+			pr_err("failed to write the device\n");
+			return ret;
+		}
+	}
+	pr_debug("write sucess register = %x val = %x\n", reg, data[1]);
+	return 0;
+}
+
+
+int msm8x10_wcd_i2c_read_device(u32 reg, u32 bytes, u8 *dest)
+{
+	struct i2c_msg *msg;
+	int ret = 0;
+	u8 reg_addr = 0;
+	struct msm8x10_wcd_i2c *msm8x10_wcd = NULL;
+	u8 i = 0;
+
+	ret = get_i2c_msm8x10_wcd_device_info(reg, &msm8x10_wcd);
+	if (ret) {
+		pr_err("%s: Invalid register address\n", __func__);
+		return ret;
+	}
+
+	if (msm8x10_wcd == NULL || msm8x10_wcd->client == NULL) {
+		pr_err("%s: Failed to get device info\n", __func__);
+		return -ENODEV;
+	}
+
+	for (i = 0; i < bytes; i++) {
+		reg_addr = (u8)reg++;
+		msg = &msm8x10_wcd->xfer_msg[0];
+		msg->addr = msm8x10_wcd->client->addr;
+		msg->len = 1;
+		msg->flags = 0;
+		msg->buf = &reg_addr;
+		msg = &msm8x10_wcd->xfer_msg[1];
+		msg->addr = msm8x10_wcd->client->addr;
+		msg->len = 1;
+		msg->flags = I2C_M_RD;
+		msg->buf = dest++;
+		ret = i2c_transfer(msm8x10_wcd->client->adapter,
+				msm8x10_wcd->xfer_msg, 2);
+
+		/* Try again if read fails first time */
+		if (ret != 2) {
+			ret = i2c_transfer(msm8x10_wcd->client->adapter,
+					   msm8x10_wcd->xfer_msg, 2);
+			if (ret != 2) {
+				pr_err("failed to read msm8x10_wcd register\n");
+				return ret;
+			}
+		}
+	}
+	pr_debug("%s: Reg 0x%x = 0x%x\n", __func__, reg, *dest);
+	return 0;
+}
+
+int msm8x10_wcd_i2c_read(unsigned short reg, int bytes, void *dest)
+{
+	return msm8x10_wcd_i2c_read_device(reg, bytes, dest);
+}
+
+int msm8x10_wcd_i2c_write(unsigned short reg, int bytes, void *src)
+{
+	return msm8x10_wcd_i2c_write_device(reg, src, bytes);
+}
+
+static int msm8x10_wcd_reg_read(struct msm8x10_wcd *msm8x10_wcd,
+				u16 reg, unsigned int *val)
+{
+	int ret = -EINVAL;
+
+	/* check if use I2C interface for Helicon or AHB for Dino */
+	mutex_lock(&msm8x10_wcd->io_lock);
+	if (MSM8X10_WCD_IS_HELICON_REG(reg))
+		ret = msm8x10_wcd_i2c_read(reg, 1, val);
+	else if (MSM8X10_WCD_IS_DINO_REG(reg))
+		ret = msm8x10_wcd_abh_read_device(reg, 1, val);
+	mutex_unlock(&msm8x10_wcd->io_lock);
+	return ret;
+}
+
+
+static int msm8x10_wcd_reg_write(struct msm8x10_wcd *msm8x10_wcd, u16  reg,
+				 unsigned int val)
+{
+	int ret = -EINVAL;
+
+	/* check if use I2C interface for Helicon or AHB for Dino */
+	mutex_lock(&msm8x10_wcd->io_lock);
+	if (MSM8X10_WCD_IS_HELICON_REG(reg))
+		ret = msm8x10_wcd_i2c_write(reg, 1, &val);
+	else if (MSM8X10_WCD_IS_DINO_REG(reg))
+		ret = msm8x10_wcd_abh_write_device(reg, &val, 1);
+	mutex_unlock(&msm8x10_wcd->io_lock);
+
+	return ret;
+}
+
+static bool msm8x10_wcd_is_digital_gain_register(unsigned int reg)
+{
+	bool rtn = false;
+	switch (reg) {
+	case MSM8X10_WCD_A_CDC_RX1_VOL_CTL_B2_CTL:
+	case MSM8X10_WCD_A_CDC_RX2_VOL_CTL_B2_CTL:
+	case MSM8X10_WCD_A_CDC_RX3_VOL_CTL_B2_CTL:
+	case MSM8X10_WCD_A_CDC_TX1_VOL_CTL_GAIN:
+	case MSM8X10_WCD_A_CDC_TX2_VOL_CTL_GAIN:
+		rtn = true;
+		break;
+	default:
+		break;
+	}
+	return rtn;
+}
+
+static int msm8x10_wcd_volatile(struct snd_soc_codec *codec, unsigned int reg)
+{
+	/*
+	 * Registers lower than 0x100 are top level registers which can be
+	 * written by the Taiko core driver.
+	 */
+	dev_dbg(codec->dev, "%s: reg 0x%x\n", __func__, reg);
+
+	if ((reg >= MSM8X10_WCD_A_CDC_MBHC_EN_CTL) || (reg < 0x100))
+		return 1;
+
+	/* IIR Coeff registers are not cacheable */
+	if ((reg >= MSM8X10_WCD_A_CDC_IIR1_COEF_B1_CTL) &&
+		(reg <= MSM8X10_WCD_A_CDC_IIR2_COEF_B2_CTL))
+		return 1;
+
+	/*
+	 * Digital gain register is not cacheable so we have to write
+	 * the setting even it is the same
+	 */
+	if (msm8x10_wcd_is_digital_gain_register(reg))
+		return 1;
+
+	/* HPH status registers */
+	if (reg == MSM8X10_WCD_A_RX_HPH_L_STATUS ||
+	    reg == MSM8X10_WCD_A_RX_HPH_R_STATUS)
+		return 1;
+
+	if (reg == MSM8X10_WCD_A_MBHC_INSERT_DET_STATUS)
+		return 1;
+
+	return 0;
+}
+
+static int msm8x10_wcd_readable(struct snd_soc_codec *ssc, unsigned int reg)
+{
+	return msm8x10_wcd_reg_readable[reg];
+}
+
+static int msm8x10_wcd_write(struct snd_soc_codec *codec, unsigned int reg,
+			     unsigned int value)
+{
+	int ret;
+	dev_dbg(codec->dev, "%s: Write from reg 0x%x\n", __func__, reg);
+	if (reg == SND_SOC_NOPM)
+		return 0;
+
+	BUG_ON(reg > MSM8X10_WCD_MAX_REGISTER);
+
+	if (!msm8x10_wcd_volatile(codec, reg)) {
+		ret = snd_soc_cache_write(codec, reg, value);
+		if (ret != 0)
+			dev_err(codec->dev, "Cache write to %x failed: %d\n",
+				reg, ret);
+	}
+
+	return msm8x10_wcd_reg_write(codec->control_data, reg, value);
+}
+
+static unsigned int msm8x10_wcd_read(struct snd_soc_codec *codec,
+				unsigned int reg)
+{
+	unsigned int val;
+	int ret;
+
+	dev_dbg(codec->dev, "%s: Read from reg 0x%x\n", __func__, reg);
+	if (reg == SND_SOC_NOPM)
+		return 0;
+
+	BUG_ON(reg > MSM8X10_WCD_MAX_REGISTER);
+
+	if (!msm8x10_wcd_volatile(codec, reg) &&
+	    msm8x10_wcd_readable(codec, reg) &&
+		reg < codec->driver->reg_cache_size) {
+		ret = snd_soc_cache_read(codec, reg, &val);
+		if (ret >= 0) {
+			return val;
+		} else
+			dev_err(codec->dev, "Cache read from %x failed: %d\n",
+				reg, ret);
+	}
+
+	ret = msm8x10_wcd_reg_read(codec->control_data, reg, &val);
+	return val;
+}
+
+
+static int msm8x10_wcd_dt_parse_vreg_info(struct device *dev,
+	struct msm8x10_wcd_regulator *vreg, const char *vreg_name)
+{
+	int len, ret = 0;
+	const __be32 *prop;
+	char prop_name[CODEC_DT_MAX_PROP_SIZE];
+	struct device_node *regnode = NULL;
+	u32 prop_val;
+
+	snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, "%s-supply",
+		vreg_name);
+	regnode = of_parse_phandle(dev->of_node, prop_name, 0);
+
+	if (!regnode) {
+		dev_err(dev, "Looking up %s property in node %s failed",
+			prop_name, dev->of_node->full_name);
+		return -ENODEV;
+	}
+	vreg->name = vreg_name;
+
+	snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
+		"qcom,%s-voltage", vreg_name);
+	prop = of_get_property(dev->of_node, prop_name, &len);
+
+	if (!prop || (len != (2 * sizeof(__be32)))) {
+		dev_err(dev, "%s %s property\n",
+			prop ? "invalid format" : "no", prop_name);
+		return -ENODEV;
+	} else {
+		vreg->min_uV = be32_to_cpup(&prop[0]);
+		vreg->max_uV = be32_to_cpup(&prop[1]);
+	}
+
+	snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
+		"qcom,%s-current", vreg_name);
+
+	ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
+	if (ret) {
+		dev_err(dev, "Looking up %s property in node %s failed",
+			prop_name, dev->of_node->full_name);
+		return -ENODEV;
+	}
+	vreg->optimum_uA = prop_val;
+
+	dev_info(dev, "%s: vol=[%d %d]uV, curr=[%d]uA\n", vreg->name,
+		 vreg->min_uV, vreg->max_uV, vreg->optimum_uA);
+	return 0;
+}
+
+static int msm8x10_wcd_dt_parse_micbias_info(struct device *dev,
+	struct msm8x10_wcd_micbias_setting *micbias)
+{
+	int ret = 0;
+	char prop_name[CODEC_DT_MAX_PROP_SIZE];
+	u32 prop_val;
+
+	snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
+		 "qcom,cdc-micbias-ldoh-v");
+	ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
+	if (ret) {
+		dev_err(dev, "Looking up %s property in node %s failed",
+			prop_name, dev->of_node->full_name);
+		return -ENODEV;
+	}
+	micbias->ldoh_v = (u8)prop_val;
+
+	snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
+		 "qcom,cdc-micbias-cfilt1-mv");
+	ret = of_property_read_u32(dev->of_node, prop_name,
+				   &micbias->cfilt1_mv);
+	if (ret) {
+		dev_err(dev, "Looking up %s property in node %s failed",
+			prop_name, dev->of_node->full_name);
+		return -ENODEV;
+	}
+
+	snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
+		 "qcom,cdc-micbias1-cfilt-sel");
+	ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
+	if (ret) {
+		dev_err(dev, "Looking up %s property in node %s failed",
+			prop_name, dev->of_node->full_name);
+		return -ENODEV;
+	}
+	micbias->bias1_cfilt_sel = (u8)prop_val;
+
+	/* micbias external cap */
+	micbias->bias1_cap_mode =
+	    (of_property_read_bool(dev->of_node, "qcom,cdc-micbias1-ext-cap") ?
+	     MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP);
+
+	dev_dbg(dev, "ldoh_v  %u cfilt1_mv %u\n",
+		(u32)micbias->ldoh_v, (u32)micbias->cfilt1_mv);
+	dev_dbg(dev, "bias1_cfilt_sel %u\n", (u32)micbias->bias1_cfilt_sel);
+	dev_dbg(dev, "bias1_ext_cap %d\n", micbias->bias1_cap_mode);
+
+	return 0;
+}
+
+static struct msm8x10_wcd_pdata *msm8x10_wcd_populate_dt_pdata(
+						struct device *dev)
+{
+	struct msm8x10_wcd_pdata *pdata;
+	int ret, i;
+	char **codec_supplies;
+	u32 num_of_supplies = 0;
+
+	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		dev_err(dev, "could not allocate memory for platform data\n");
+		return NULL;
+	}
+	if ((!strcmp(dev_name(dev), MSM8X10_WCD_I2C_GSBI_SLAVE_ID))) {
+		codec_supplies = msm8x10_wcd_supplies;
+		num_of_supplies = ARRAY_SIZE(msm8x10_wcd_supplies);
+	} else {
+		dev_err(dev, "%s unsupported device %s\n",
+			__func__, dev_name(dev));
+		goto err;
+	}
+
+	if (num_of_supplies > ARRAY_SIZE(pdata->regulator)) {
+		dev_err(dev, "%s: Num of supplies %u > max supported %u\n",
+			__func__, num_of_supplies,
+			ARRAY_SIZE(pdata->regulator));
+
+		goto err;
+	}
+
+	for (i = 0; i < num_of_supplies; i++) {
+		ret = msm8x10_wcd_dt_parse_vreg_info(dev, &pdata->regulator[i],
+			codec_supplies[i]);
+		if (ret)
+			goto err;
+	}
+
+	ret = msm8x10_wcd_dt_parse_micbias_info(dev, &pdata->micbias);
+	if (ret)
+		goto err;
+
+	pdata->reset_gpio = of_get_named_gpio(dev->of_node,
+				"qcom,cdc-reset-gpio", 0);
+	if (pdata->reset_gpio < 0) {
+		dev_err(dev, "Looking up %s property in node %s failed %d\n",
+			"qcom, cdc-reset-gpio", dev->of_node->full_name,
+			pdata->reset_gpio);
+		goto err;
+	}
+	dev_dbg(dev, "%s: reset gpio %d", __func__, pdata->reset_gpio);
+	return pdata;
+err:
+	devm_kfree(dev, pdata);
+	return NULL;
+}
+
+static int msm8x10_wcd_codec_enable_charge_pump(struct snd_soc_dapm_widget *w,
+		struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	dev_dbg(codec->dev, "%s: event = %d\n", __func__, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		/* Enable charge pump clock*/
+		snd_soc_update_bits(codec, MSM8X10_WCD_A_CDC_CLK_OTHR_CTL,
+				    0x01, 0x01);
+		snd_soc_update_bits(codec, MSM8X10_WCD_A_CDC_CLSG_CTL,
+				    0x08, 0x08);
+		usleep_range(200, 300);
+		snd_soc_update_bits(codec, MSM8X10_WCD_A_CP_STATIC,
+				    0x10, 0x00);
+		break;
+	case SND_SOC_DAPM_PRE_PMD:
+		snd_soc_update_bits(codec,
+				    MSM8X10_WCD_A_CDC_CLK_OTHR_RESET_B1_CTL,
+				    0x01, 0x01);
+		usleep_range(20, 100);
+		snd_soc_update_bits(codec,
+				    MSM8X10_WCD_A_CP_STATIC, 0x08, 0x08);
+		snd_soc_update_bits(codec,
+				    MSM8X10_WCD_A_CP_STATIC, 0x10, 0x10);
+		snd_soc_update_bits(codec,
+				    MSM8X10_WCD_A_CDC_CLSG_CTL, 0x08, 0x00);
+		snd_soc_update_bits(codec,
+				    MSM8X10_WCD_A_CDC_CLK_OTHR_CTL, 0x01,
+				    0x00);
+		snd_soc_update_bits(codec,
+				    MSM8X10_WCD_A_CP_STATIC, 0x08, 0x00);
+		break;
+	}
+	return 0;
+}
+
+static int msm8x10_wcd_pa_gain_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	u8 ear_pa_gain;
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+
+	ear_pa_gain = snd_soc_read(codec, MSM8X10_WCD_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  {
+		dev_err(codec->dev, "%s: ERROR: Unsupported Ear Gain = 0x%x\n",
+			__func__, ear_pa_gain);
+		return -EINVAL;
+	}
+	dev_dbg(codec->dev, "%s: ear_pa_gain = 0x%x\n", __func__, ear_pa_gain);
+	return 0;
+}
+
+static int msm8x10_wcd_pa_gain_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	u8 ear_pa_gain;
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+
+	dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
+		__func__, ucontrol->value.integer.value[0]);
+
+	switch (ucontrol->value.integer.value[0]) {
+	case 0:
+		ear_pa_gain = 0x00;
+		break;
+	case 1:
+		ear_pa_gain = 0x80;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	snd_soc_update_bits(codec, MSM8X10_WCD_A_RX_EAR_GAIN,
+			    0xE0, ear_pa_gain);
+	return 0;
+}
+
+static int msm8x10_wcd_get_iir_enable_audio_mixer(
+					struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	int iir_idx = ((struct soc_multi_mixer_control *)
+					kcontrol->private_value)->reg;
+	int band_idx = ((struct soc_multi_mixer_control *)
+					kcontrol->private_value)->shift;
+
+	ucontrol->value.integer.value[0] =
+		snd_soc_read(codec,
+			    (MSM8X10_WCD_A_CDC_IIR1_CTL + 64 * iir_idx)) &
+		(1 << band_idx);
+
+	dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__,
+		iir_idx, band_idx,
+		(uint32_t)ucontrol->value.integer.value[0]);
+	return 0;
+}
+
+static int msm8x10_wcd_put_iir_enable_audio_mixer(
+					struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	int iir_idx = ((struct soc_multi_mixer_control *)
+					kcontrol->private_value)->reg;
+	int band_idx = ((struct soc_multi_mixer_control *)
+					kcontrol->private_value)->shift;
+	int value = ucontrol->value.integer.value[0];
+
+	/* Mask first 5 bits, 6-8 are reserved */
+	snd_soc_update_bits(codec, (MSM8X10_WCD_A_CDC_IIR1_CTL + 64 * iir_idx),
+			    (1 << band_idx), (value << band_idx));
+
+	dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__,
+		iir_idx, band_idx, value);
+	return 0;
+}
+static uint32_t get_iir_band_coeff(struct snd_soc_codec *codec,
+				   int iir_idx, int band_idx,
+				   int coeff_idx)
+{
+	/* Address does not automatically update if reading */
+	snd_soc_write(codec,
+		(MSM8X10_WCD_A_CDC_IIR1_COEF_B1_CTL + 64 * iir_idx),
+		(band_idx * BAND_MAX + coeff_idx) & 0x1F);
+
+	/* Mask bits top 2 bits since they are reserved */
+	return ((snd_soc_read(codec,
+		(MSM8X10_WCD_A_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx)) << 24)) &
+		0x3FFFFFFF;
+}
+
+static int msm8x10_wcd_get_iir_band_audio_mixer(
+					struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	int iir_idx = ((struct soc_multi_mixer_control *)
+					kcontrol->private_value)->reg;
+	int band_idx = ((struct soc_multi_mixer_control *)
+					kcontrol->private_value)->shift;
+
+	ucontrol->value.integer.value[0] =
+		get_iir_band_coeff(codec, iir_idx, band_idx, 0);
+	ucontrol->value.integer.value[1] =
+		get_iir_band_coeff(codec, iir_idx, band_idx, 1);
+	ucontrol->value.integer.value[2] =
+		get_iir_band_coeff(codec, iir_idx, band_idx, 2);
+	ucontrol->value.integer.value[3] =
+		get_iir_band_coeff(codec, iir_idx, band_idx, 3);
+	ucontrol->value.integer.value[4] =
+		get_iir_band_coeff(codec, iir_idx, band_idx, 4);
+
+	dev_dbg(codec->dev, "%s: IIR #%d band #%d b0 = 0x%x\n"
+		"%s: IIR #%d band #%d b1 = 0x%x\n"
+		"%s: IIR #%d band #%d b2 = 0x%x\n"
+		"%s: IIR #%d band #%d a1 = 0x%x\n"
+		"%s: IIR #%d band #%d a2 = 0x%x\n",
+		__func__, iir_idx, band_idx,
+		(uint32_t)ucontrol->value.integer.value[0],
+		__func__, iir_idx, band_idx,
+		(uint32_t)ucontrol->value.integer.value[1],
+		__func__, iir_idx, band_idx,
+		(uint32_t)ucontrol->value.integer.value[2],
+		__func__, iir_idx, band_idx,
+		(uint32_t)ucontrol->value.integer.value[3],
+		__func__, iir_idx, band_idx,
+		(uint32_t)ucontrol->value.integer.value[4]);
+	return 0;
+}
+
+static void set_iir_band_coeff(struct snd_soc_codec *codec,
+				int iir_idx, int band_idx,
+				int coeff_idx, uint32_t value)
+{
+	/* Mask top 3 bits, 6-8 are reserved */
+	/* Update address manually each time */
+	snd_soc_write(codec,
+		(MSM8X10_WCD_A_CDC_IIR1_COEF_B1_CTL + 64 * iir_idx),
+		(band_idx * BAND_MAX + coeff_idx) & 0x1F);
+
+	/* Mask top 2 bits, 7-8 are reserved */
+	snd_soc_write(codec,
+		(MSM8X10_WCD_A_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx),
+		(value >> 24) & 0x3F);
+
+}
+
+static int msm8x10_wcd_put_iir_band_audio_mixer(
+					struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	int iir_idx = ((struct soc_multi_mixer_control *)
+					kcontrol->private_value)->reg;
+	int band_idx = ((struct soc_multi_mixer_control *)
+					kcontrol->private_value)->shift;
+
+	set_iir_band_coeff(codec, iir_idx, band_idx, 0,
+			   ucontrol->value.integer.value[0]);
+	set_iir_band_coeff(codec, iir_idx, band_idx, 1,
+			   ucontrol->value.integer.value[1]);
+	set_iir_band_coeff(codec, iir_idx, band_idx, 2,
+			   ucontrol->value.integer.value[2]);
+	set_iir_band_coeff(codec, iir_idx, band_idx, 3,
+			   ucontrol->value.integer.value[3]);
+	set_iir_band_coeff(codec, iir_idx, band_idx, 4,
+			   ucontrol->value.integer.value[4]);
+
+	dev_dbg(codec->dev, "%s: IIR #%d band #%d b0 = 0x%x\n"
+		"%s: IIR #%d band #%d b1 = 0x%x\n"
+		"%s: IIR #%d band #%d b2 = 0x%x\n"
+		"%s: IIR #%d band #%d a1 = 0x%x\n"
+		"%s: IIR #%d band #%d a2 = 0x%x\n",
+		__func__, iir_idx, band_idx,
+		get_iir_band_coeff(codec, iir_idx, band_idx, 0),
+		__func__, iir_idx, band_idx,
+		get_iir_band_coeff(codec, iir_idx, band_idx, 1),
+		__func__, iir_idx, band_idx,
+		get_iir_band_coeff(codec, iir_idx, band_idx, 2),
+		__func__, iir_idx, band_idx,
+		get_iir_band_coeff(codec, iir_idx, band_idx, 3),
+		__func__, iir_idx, band_idx,
+		get_iir_band_coeff(codec, iir_idx, band_idx, 4));
+	return 0;
+}
+
+static const char * const msm8x10_wcd_ear_pa_gain_text[] = {
+		"POS_6_DB", "POS_2_DB"};
+static const struct soc_enum msm8x10_wcd_ear_pa_gain_enum[] = {
+		SOC_ENUM_SINGLE_EXT(2, msm8x10_wcd_ear_pa_gain_text),
+};
+
+/*cut of frequency for high pass filter*/
+static const char * const cf_text[] = {
+	"MIN_3DB_4Hz", "MIN_3DB_75Hz", "MIN_3DB_150Hz"
+};
+
+static const struct soc_enum cf_dec1_enum =
+	SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_TX1_MUX_CTL, 4, 3, cf_text);
+
+static const struct soc_enum cf_dec2_enum =
+	SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_TX2_MUX_CTL, 4, 3, cf_text);
+
+static const struct soc_enum cf_rxmix1_enum =
+	SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_RX1_B4_CTL, 0, 3, cf_text);
+
+static const struct soc_enum cf_rxmix2_enum =
+	SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_RX2_B4_CTL, 0, 3, cf_text);
+
+static const struct soc_enum cf_rxmix3_enum =
+	SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_RX3_B4_CTL, 0, 3, cf_text);
+
+static const struct snd_kcontrol_new msm8x10_wcd_snd_controls[] = {
+
+	SOC_ENUM_EXT("EAR PA Gain", msm8x10_wcd_ear_pa_gain_enum[0],
+		msm8x10_wcd_pa_gain_get, msm8x10_wcd_pa_gain_put),
+
+	SOC_SINGLE_TLV("LINEOUT1 Volume", MSM8X10_WCD_A_RX_LINE_1_GAIN,
+		       0, 12, 1, line_gain),
+
+	SOC_SINGLE_TLV("HPHL Volume", MSM8X10_WCD_A_RX_HPH_L_GAIN,
+		       0, 12, 1, line_gain),
+	SOC_SINGLE_TLV("HPHR Volume", MSM8X10_WCD_A_RX_HPH_R_GAIN,
+		       0, 12, 1, line_gain),
+
+	SOC_SINGLE_S8_TLV("RX1 Digital Volume",
+			  MSM8X10_WCD_A_CDC_RX1_VOL_CTL_B2_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("RX2 Digital Volume",
+			  MSM8X10_WCD_A_CDC_RX2_VOL_CTL_B2_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("RX3 Digital Volume",
+			  MSM8X10_WCD_A_CDC_RX3_VOL_CTL_B2_CTL,
+			  -84, 40, digital_gain),
+
+	SOC_SINGLE_S8_TLV("DEC1 Volume",
+			  MSM8X10_WCD_A_CDC_TX1_VOL_CTL_GAIN,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("DEC2 Volume",
+			  MSM8X10_WCD_A_CDC_TX2_VOL_CTL_GAIN,
+			  -84, 40, digital_gain),
+
+	SOC_SINGLE_S8_TLV("IIR1 INP1 Volume",
+			  MSM8X10_WCD_A_CDC_IIR1_GAIN_B1_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("IIR1 INP2 Volume",
+			  MSM8X10_WCD_A_CDC_IIR1_GAIN_B2_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("IIR1 INP3 Volume",
+			  MSM8X10_WCD_A_CDC_IIR1_GAIN_B3_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("IIR1 INP4 Volume",
+			  MSM8X10_WCD_A_CDC_IIR1_GAIN_B4_CTL,
+			  -84,	40, digital_gain),
+
+	SOC_SINGLE("MICBIAS1 CAPLESS Switch",
+		   MSM8X10_WCD_A_MICB_1_CTL, 4, 1, 1),
+
+	SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
+	SOC_ENUM("TX2 HPF cut off", cf_dec2_enum),
+
+	SOC_SINGLE("TX1 HPF Switch", MSM8X10_WCD_A_CDC_TX1_MUX_CTL, 3, 1, 0),
+	SOC_SINGLE("TX2 HPF Switch", MSM8X10_WCD_A_CDC_TX2_MUX_CTL, 3, 1, 0),
+
+	SOC_SINGLE("RX1 HPF Switch", MSM8X10_WCD_A_CDC_RX1_B5_CTL, 2, 1, 0),
+	SOC_SINGLE("RX2 HPF Switch", MSM8X10_WCD_A_CDC_RX2_B5_CTL, 2, 1, 0),
+	SOC_SINGLE("RX3 HPF Switch", MSM8X10_WCD_A_CDC_RX3_B5_CTL, 2, 1, 0),
+
+	SOC_ENUM("RX1 HPF cut off", cf_rxmix1_enum),
+	SOC_ENUM("RX2 HPF cut off", cf_rxmix2_enum),
+	SOC_ENUM("RX3 HPF cut off", cf_rxmix3_enum),
+
+	SOC_SINGLE_EXT("IIR1 Enable Band1", IIR1, BAND1, 1, 0,
+	msm8x10_wcd_get_iir_enable_audio_mixer,
+	msm8x10_wcd_put_iir_enable_audio_mixer),
+	SOC_SINGLE_EXT("IIR1 Enable Band2", IIR1, BAND2, 1, 0,
+	msm8x10_wcd_get_iir_enable_audio_mixer,
+	msm8x10_wcd_put_iir_enable_audio_mixer),
+	SOC_SINGLE_EXT("IIR1 Enable Band3", IIR1, BAND3, 1, 0,
+	msm8x10_wcd_get_iir_enable_audio_mixer,
+	msm8x10_wcd_put_iir_enable_audio_mixer),
+	SOC_SINGLE_EXT("IIR1 Enable Band4", IIR1, BAND4, 1, 0,
+	msm8x10_wcd_get_iir_enable_audio_mixer,
+	msm8x10_wcd_put_iir_enable_audio_mixer),
+	SOC_SINGLE_EXT("IIR1 Enable Band5", IIR1, BAND5, 1, 0,
+	msm8x10_wcd_get_iir_enable_audio_mixer,
+	msm8x10_wcd_put_iir_enable_audio_mixer),
+	SOC_SINGLE_EXT("IIR2 Enable Band1", IIR2, BAND1, 1, 0,
+	msm8x10_wcd_get_iir_enable_audio_mixer,
+	msm8x10_wcd_put_iir_enable_audio_mixer),
+	SOC_SINGLE_EXT("IIR2 Enable Band2", IIR2, BAND2, 1, 0,
+	msm8x10_wcd_get_iir_enable_audio_mixer,
+	msm8x10_wcd_put_iir_enable_audio_mixer),
+	SOC_SINGLE_EXT("IIR2 Enable Band3", IIR2, BAND3, 1, 0,
+	msm8x10_wcd_get_iir_enable_audio_mixer,
+	msm8x10_wcd_put_iir_enable_audio_mixer),
+	SOC_SINGLE_EXT("IIR2 Enable Band4", IIR2, BAND4, 1, 0,
+	msm8x10_wcd_get_iir_enable_audio_mixer,
+	msm8x10_wcd_put_iir_enable_audio_mixer),
+	SOC_SINGLE_EXT("IIR2 Enable Band5", IIR2, BAND5, 1, 0,
+	msm8x10_wcd_get_iir_enable_audio_mixer,
+	msm8x10_wcd_put_iir_enable_audio_mixer),
+
+	SOC_SINGLE_MULTI_EXT("IIR1 Band1", IIR1, BAND1, 255, 0, 5,
+	msm8x10_wcd_get_iir_band_audio_mixer,
+	msm8x10_wcd_put_iir_band_audio_mixer),
+	SOC_SINGLE_MULTI_EXT("IIR1 Band2", IIR1, BAND2, 255, 0, 5,
+	msm8x10_wcd_get_iir_band_audio_mixer,
+	msm8x10_wcd_put_iir_band_audio_mixer),
+	SOC_SINGLE_MULTI_EXT("IIR1 Band3", IIR1, BAND3, 255, 0, 5,
+	msm8x10_wcd_get_iir_band_audio_mixer,
+	msm8x10_wcd_put_iir_band_audio_mixer),
+	SOC_SINGLE_MULTI_EXT("IIR1 Band4", IIR1, BAND4, 255, 0, 5,
+	msm8x10_wcd_get_iir_band_audio_mixer,
+	msm8x10_wcd_put_iir_band_audio_mixer),
+	SOC_SINGLE_MULTI_EXT("IIR1 Band5", IIR1, BAND5, 255, 0, 5,
+	msm8x10_wcd_get_iir_band_audio_mixer,
+	msm8x10_wcd_put_iir_band_audio_mixer),
+	SOC_SINGLE_MULTI_EXT("IIR2 Band1", IIR2, BAND1, 255, 0, 5,
+	msm8x10_wcd_get_iir_band_audio_mixer,
+	msm8x10_wcd_put_iir_band_audio_mixer),
+	SOC_SINGLE_MULTI_EXT("IIR2 Band2", IIR2, BAND2, 255, 0, 5,
+	msm8x10_wcd_get_iir_band_audio_mixer,
+	msm8x10_wcd_put_iir_band_audio_mixer),
+	SOC_SINGLE_MULTI_EXT("IIR2 Band3", IIR2, BAND3, 255, 0, 5,
+	msm8x10_wcd_get_iir_band_audio_mixer,
+	msm8x10_wcd_put_iir_band_audio_mixer),
+	SOC_SINGLE_MULTI_EXT("IIR2 Band4", IIR2, BAND4, 255, 0, 5,
+	msm8x10_wcd_get_iir_band_audio_mixer,
+	msm8x10_wcd_put_iir_band_audio_mixer),
+	SOC_SINGLE_MULTI_EXT("IIR2 Band5", IIR2, BAND5, 255, 0, 5,
+	msm8x10_wcd_get_iir_band_audio_mixer,
+	msm8x10_wcd_put_iir_band_audio_mixer),
+
+};
+
+static const char * const rx_mix1_text[] = {
+	"ZERO", "IIR1", "IIR2", "RX1", "RX2", "RX3"
+};
+
+static const char * const rx_mix2_text[] = {
+	"ZERO", "IIR1", "IIR2"
+};
+
+static const char * const dec_mux_text[] = {
+	"ZERO", "ADC1", "ADC2", "DMIC1", "DMIC2"
+};
+
+static const char * const anc_mux_text[] = {
+	"ZERO", "ADC1", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6", "ADC_MB",
+		"RSVD_1", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5", "DMIC6"
+};
+
+static const char * const anc1_fb_mux_text[] = {
+	"ZERO", "EAR_HPH_L", "EAR_LINE_1",
+};
+
+static const char * const iir1_inp1_text[] = {
+	"ZERO", "DEC1", "DEC2", "RX1", "RX2", "RX3"
+};
+
+static const struct soc_enum rx_mix1_inp1_chain_enum =
+	SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_CONN_RX1_B1_CTL, 0, 6, rx_mix1_text);
+
+static const struct soc_enum rx_mix1_inp2_chain_enum =
+	SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_CONN_RX1_B1_CTL, 3, 6, rx_mix1_text);
+
+static const struct soc_enum rx_mix1_inp3_chain_enum =
+	SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_CONN_RX1_B2_CTL, 0, 6, rx_mix1_text);
+
+static const struct soc_enum rx2_mix1_inp1_chain_enum =
+	SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_CONN_RX2_B1_CTL, 0, 6, rx_mix1_text);
+
+static const struct soc_enum rx2_mix1_inp2_chain_enum =
+	SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_CONN_RX2_B1_CTL, 3, 6, rx_mix1_text);
+
+static const struct soc_enum rx3_mix1_inp1_chain_enum =
+	SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_CONN_RX3_B1_CTL, 0, 6, rx_mix1_text);
+
+static const struct soc_enum rx3_mix1_inp2_chain_enum =
+	SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_CONN_RX3_B1_CTL, 3, 6, rx_mix1_text);
+
+static const struct soc_enum rx1_mix2_inp1_chain_enum =
+	SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_CONN_RX1_B3_CTL, 0, 3, rx_mix2_text);
+
+static const struct soc_enum rx2_mix2_inp1_chain_enum =
+	SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_CONN_RX2_B3_CTL, 0, 3, rx_mix2_text);
+
+static const struct soc_enum dec1_mux_enum =
+	SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_CONN_TX_B1_CTL, 0, 5, dec_mux_text);
+
+static const struct soc_enum dec2_mux_enum =
+	SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_CONN_TX_B1_CTL, 3, 5, dec_mux_text);
+
+static const struct soc_enum iir1_inp1_mux_enum =
+	SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_CONN_EQ1_B1_CTL, 0, 6,
+	iir1_inp1_text);
+
+static const struct snd_kcontrol_new rx_mix1_inp1_mux =
+	SOC_DAPM_ENUM("RX1 MIX1 INP1 Mux", rx_mix1_inp1_chain_enum);
+
+static const struct snd_kcontrol_new rx_mix1_inp2_mux =
+	SOC_DAPM_ENUM("RX1 MIX1 INP2 Mux", rx_mix1_inp2_chain_enum);
+
+static const struct snd_kcontrol_new rx_mix1_inp3_mux =
+	SOC_DAPM_ENUM("RX1 MIX1 INP3 Mux", rx_mix1_inp3_chain_enum);
+
+static const struct snd_kcontrol_new rx2_mix1_inp1_mux =
+	SOC_DAPM_ENUM("RX2 MIX1 INP1 Mux", rx2_mix1_inp1_chain_enum);
+
+static const struct snd_kcontrol_new rx2_mix1_inp2_mux =
+	SOC_DAPM_ENUM("RX2 MIX1 INP2 Mux", rx2_mix1_inp2_chain_enum);
+
+static const struct snd_kcontrol_new rx3_mix1_inp1_mux =
+	SOC_DAPM_ENUM("RX3 MIX1 INP1 Mux", rx3_mix1_inp1_chain_enum);
+
+static const struct snd_kcontrol_new rx3_mix1_inp2_mux =
+	SOC_DAPM_ENUM("RX3 MIX1 INP2 Mux", rx3_mix1_inp2_chain_enum);
+
+static const struct snd_kcontrol_new rx1_mix2_inp1_mux =
+	SOC_DAPM_ENUM("RX1 MIX2 INP1 Mux", rx1_mix2_inp1_chain_enum);
+
+static const struct snd_kcontrol_new rx2_mix2_inp1_mux =
+	SOC_DAPM_ENUM("RX2 MIX2 INP1 Mux", rx2_mix2_inp1_chain_enum);
+
+static int msm8x10_wcd_put_dec_enum(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
+	struct snd_soc_dapm_widget *w = wlist->widgets[0];
+	struct snd_soc_codec *codec = w->codec;
+	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+	unsigned int dec_mux, decimator;
+	char *dec_name = NULL;
+	char *widget_name = NULL;
+	char *temp;
+	u16 tx_mux_ctl_reg;
+	u8 adc_dmic_sel = 0x0;
+	int ret = 0;
+
+	if (ucontrol->value.enumerated.item[0] > e->max - 1)
+		return -EINVAL;
+
+	dec_mux = ucontrol->value.enumerated.item[0];
+
+	widget_name = kstrndup(w->name, 15, GFP_KERNEL);
+	if (!widget_name)
+		return -ENOMEM;
+	temp = widget_name;
+
+	dec_name = strsep(&widget_name, " ");
+	widget_name = temp;
+	if (!dec_name) {
+		dev_err(codec->dev, "%s: Invalid decimator = %s\n",
+			__func__, w->name);
+		ret =  -EINVAL;
+		goto out;
+	}
+
+	ret = kstrtouint(strpbrk(dec_name, "12"), 10, &decimator);
+	if (ret < 0) {
+		dev_err(codec->dev, "%s: Invalid decimator = %s\n",
+			__func__, dec_name);
+		ret =  -EINVAL;
+		goto out;
+	}
+
+	dev_dbg(w->dapm->dev, "%s(): widget = %s decimator = %u dec_mux = %u\n"
+		, __func__, w->name, decimator, dec_mux);
+
+	switch (decimator) {
+	case 1:
+	case 2:
+		if (dec_mux == 1)
+			adc_dmic_sel = 0x1;
+		else
+			adc_dmic_sel = 0x0;
+		break;
+	default:
+		dev_err(codec->dev, "%s: Invalid Decimator = %u\n",
+			__func__, decimator);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	tx_mux_ctl_reg = MSM8X10_WCD_A_CDC_TX1_MUX_CTL + 32 * (decimator - 1);
+
+	snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x1, adc_dmic_sel);
+
+	ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
+
+out:
+	kfree(widget_name);
+	return ret;
+}
+
+#define MSM8X10_WCD_DEC_ENUM(xname, xenum) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+	.info = snd_soc_info_enum_double, \
+	.get = snd_soc_dapm_get_enum_double, \
+	.put = msm8x10_wcd_put_dec_enum, \
+	.private_value = (unsigned long)&xenum }
+
+static const struct snd_kcontrol_new dec1_mux =
+	MSM8X10_WCD_DEC_ENUM("DEC1 MUX Mux", dec1_mux_enum);
+
+static const struct snd_kcontrol_new dec2_mux =
+	MSM8X10_WCD_DEC_ENUM("DEC2 MUX Mux", dec2_mux_enum);
+
+static const struct snd_kcontrol_new iir1_inp1_mux =
+	SOC_DAPM_ENUM("IIR1 INP1 Mux", iir1_inp1_mux_enum);
+
+static const struct snd_kcontrol_new dac1_switch[] = {
+	SOC_DAPM_SINGLE("Switch", MSM8X10_WCD_A_RX_EAR_EN, 5, 1, 0)
+};
+static const struct snd_kcontrol_new hphl_switch[] = {
+	SOC_DAPM_SINGLE("Switch", MSM8X10_WCD_A_RX_HPH_L_DAC_CTL, 6, 1, 0)
+};
+
+/* virtual port entries */
+static int slim_tx_mixer_get(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
+	struct snd_soc_dapm_widget *widget = wlist->widgets[0];
+
+	ucontrol->value.integer.value[0] = widget->value;
+	return 0;
+}
+
+static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
+{
+	return 0;
+}
+
+static int slim_rx_mux_get(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
+	struct snd_soc_dapm_widget *widget = wlist->widgets[0];
+
+	ucontrol->value.enumerated.item[0] = widget->value;
+	return 0;
+}
+
+static int slim_rx_mux_put(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol)
+{
+	return 0;
+}
+
+
+static const char *const slim_rx_mux_text[] = {
+	"ZERO", "AIF1_PB"
+};
+
+static const struct soc_enum slim_rx_mux_enum =
+	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim_rx_mux_text), slim_rx_mux_text);
+
+static const struct snd_kcontrol_new slim_rx_mux[MSM8X10_WCD_RX_MAX] = {
+	SOC_DAPM_ENUM_EXT("I2S RX1 Mux", slim_rx_mux_enum,
+			  slim_rx_mux_get, slim_rx_mux_put),
+	SOC_DAPM_ENUM_EXT("I2S RX2 Mux", slim_rx_mux_enum,
+			  slim_rx_mux_get, slim_rx_mux_put),
+	SOC_DAPM_ENUM_EXT("I2S RX3 Mux", slim_rx_mux_enum,
+			  slim_rx_mux_get, slim_rx_mux_put),
+};
+
+static const struct snd_kcontrol_new aif_cap_mixer[] = {
+	SOC_SINGLE_EXT("I2S TX1", SND_SOC_NOPM, MSM8X10_WCD_TX1, 1, 0,
+			slim_tx_mixer_get, slim_tx_mixer_put),
+	SOC_SINGLE_EXT("I2S TX2", SND_SOC_NOPM, MSM8X10_WCD_TX2, 1, 0,
+			slim_tx_mixer_get, slim_tx_mixer_put),
+	SOC_SINGLE_EXT("I2S TX3", SND_SOC_NOPM, MSM8X10_WCD_TX3, 1, 0,
+			slim_tx_mixer_get, slim_tx_mixer_put),
+	SOC_SINGLE_EXT("I2S TX4", SND_SOC_NOPM, MSM8X10_WCD_TX4, 1, 0,
+			slim_tx_mixer_get, slim_tx_mixer_put),
+};
+
+
+static void msm8x10_wcd_codec_enable_adc_block(struct snd_soc_codec *codec,
+					 int enable)
+{
+	struct msm8x10_wcd_priv *wcd8x10 = snd_soc_codec_get_drvdata(codec);
+
+	dev_dbg(codec->dev, "%s %d\n", __func__, enable);
+
+	if (enable) {
+		wcd8x10->adc_count++;
+		snd_soc_update_bits(codec,
+				    MSM8X10_WCD_A_CDC_ANA_CLK_CTL,
+				    0x20, 0x20);
+	} else {
+		wcd8x10->adc_count--;
+		if (!wcd8x10->adc_count)
+			snd_soc_update_bits(codec,
+					    MSM8X10_WCD_A_CDC_ANA_CLK_CTL,
+					    0x20, 0x0);
+	}
+}
+
+static int msm8x10_wcd_codec_enable_adc(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	u16 adc_reg;
+	u8 init_bit_shift;
+
+	dev_dbg(codec->dev, "%s %d\n", __func__, event);
+	adc_reg = MSM8X10_WCD_A_TX_1_2_TEST_CTL;
+
+	if (w->reg == MSM8X10_WCD_A_TX_1_EN)
+		init_bit_shift = 7;
+	else if (adc_reg == MSM8X10_WCD_A_TX_2_EN)
+		init_bit_shift = 6;
+	else {
+		dev_err(codec->dev, "%s: Error, invalid adc register\n",
+			__func__);
+		return -EINVAL;
+	}
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		msm8x10_wcd_codec_enable_adc_block(codec, 1);
+		snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift,
+				1 << init_bit_shift);
+		break;
+	case SND_SOC_DAPM_POST_PMU:
+		snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift, 0x00);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		msm8x10_wcd_codec_enable_adc_block(codec, 0);
+		break;
+	}
+	return 0;
+}
+
+static int msm8x10_wcd_codec_enable_lineout(struct snd_soc_dapm_widget *w,
+		struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	u16 lineout_gain_reg;
+
+	dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name);
+
+	switch (w->shift) {
+	case 0:
+		lineout_gain_reg = MSM8X10_WCD_A_RX_LINE_1_GAIN;
+		break;
+	default:
+		dev_err(codec->dev,
+			"%s: Error, incorrect lineout register value\n",
+			__func__);
+		return -EINVAL;
+	}
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		snd_soc_update_bits(codec, lineout_gain_reg, 0x40, 0x40);
+		break;
+	case SND_SOC_DAPM_POST_PMU:
+		dev_dbg(codec->dev, "%s: sleeping 16 ms after %s PA turn on\n",
+			__func__, w->name);
+		usleep_range(16000, 16100);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		snd_soc_update_bits(codec, lineout_gain_reg, 0x40, 0x00);
+		break;
+	}
+	return 0;
+}
+
+static int msm8x10_wcd_codec_enable_spk_pa(struct snd_soc_dapm_widget *w,
+				     struct snd_kcontrol *kcontrol, int event)
+{
+	dev_dbg(w->codec->dev, "%s %d %s\n", __func__, event, w->name);
+	return 0;
+}
+
+static int msm8x10_wcd_codec_enable_dmic(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	struct msm8x10_wcd_priv *msm8x10_wcd = snd_soc_codec_get_drvdata(codec);
+	u8  dmic_clk_en;
+	u16 dmic_clk_reg;
+	s32 *dmic_clk_cnt;
+	unsigned int dmic;
+	int ret;
+
+	ret = kstrtouint(strpbrk(w->name, "12"), 10, &dmic);
+	if (ret < 0) {
+		dev_err(codec->dev,
+			"%s: Invalid DMIC line on the codec\n", __func__);
+		return -EINVAL;
+	}
+
+	switch (dmic) {
+	case 1:
+	case 2:
+		dmic_clk_en = 0x01;
+		dmic_clk_cnt = &(msm8x10_wcd->dmic_1_2_clk_cnt);
+		dmic_clk_reg = MSM8X10_WCD_A_CDC_CLK_DMIC_B1_CTL;
+		dev_dbg(codec->dev,
+			"%s() event %d DMIC%d dmic_1_2_clk_cnt %d\n",
+			__func__, event,  dmic, *dmic_clk_cnt);
+		break;
+	default:
+		dev_err(codec->dev, "%s: Invalid DMIC Selection\n", __func__);
+		return -EINVAL;
+	}
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+
+		(*dmic_clk_cnt)++;
+		if (*dmic_clk_cnt == 1)
+			snd_soc_update_bits(codec, dmic_clk_reg,
+					dmic_clk_en, dmic_clk_en);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+
+		(*dmic_clk_cnt)--;
+		if (*dmic_clk_cnt  == 0)
+			snd_soc_update_bits(codec, dmic_clk_reg,
+					dmic_clk_en, 0);
+		break;
+	}
+	return 0;
+}
+
+static int msm8x10_wcd_codec_enable_micbias(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	struct msm8x10_wcd_priv *msm8x10_wcd = snd_soc_codec_get_drvdata(codec);
+	u16 micb_int_reg;
+	u8 cfilt_sel_val = 0;
+	char *internal1_text = "Internal1";
+	char *internal2_text = "Internal2";
+	char *internal3_text = "Internal3";
+	enum wcd9xxx_notify_event e_post_off, e_pre_on, e_post_on;
+
+	dev_dbg(codec->dev, "%s %d\n", __func__, event);
+	switch (w->reg) {
+	case MSM8X10_WCD_A_MICB_1_CTL:
+		micb_int_reg = MSM8X10_WCD_A_MICB_1_INT_RBIAS;
+		cfilt_sel_val =
+			msm8x10_wcd->resmgr.pdata->micbias.bias1_cfilt_sel;
+		e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_1_ON;
+		e_post_on = WCD9XXX_EVENT_POST_MICBIAS_1_ON;
+		e_post_off = WCD9XXX_EVENT_POST_MICBIAS_1_OFF;
+		break;
+	default:
+		dev_err(codec->dev,
+			"%s: Error, invalid micbias register\n", __func__);
+		return -EINVAL;
+	}
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		/* Let MBHC module know so micbias switch to be off */
+		wcd9xxx_resmgr_notifier_call(&msm8x10_wcd->resmgr, e_pre_on);
+
+		/* Get cfilt */
+		wcd9xxx_resmgr_cfilt_get(&msm8x10_wcd->resmgr, cfilt_sel_val);
+
+		if (strnstr(w->name, internal1_text, 30))
+			snd_soc_update_bits(codec, micb_int_reg, 0xE0, 0xE0);
+		else if (strnstr(w->name, internal2_text, 30))
+			snd_soc_update_bits(codec, micb_int_reg, 0x1C, 0x1C);
+		else if (strnstr(w->name, internal3_text, 30))
+			snd_soc_update_bits(codec, micb_int_reg, 0x3, 0x3);
+		break;
+	case SND_SOC_DAPM_POST_PMU:
+		usleep_range(20000, 20100);
+		/* Let MBHC module know so micbias is on */
+		wcd9xxx_resmgr_notifier_call(&msm8x10_wcd->resmgr, e_post_on);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		/* Let MBHC module know so micbias switch to be off */
+		wcd9xxx_resmgr_notifier_call(&msm8x10_wcd->resmgr, e_post_off);
+
+		if (strnstr(w->name, internal1_text, 30))
+			snd_soc_update_bits(codec, micb_int_reg, 0x80, 0x00);
+		else if (strnstr(w->name, internal2_text, 30))
+			snd_soc_update_bits(codec, micb_int_reg, 0x10, 0x00);
+		else if (strnstr(w->name, internal3_text, 30))
+			snd_soc_update_bits(codec, micb_int_reg, 0x2, 0x0);
+
+		/* Put cfilt */
+		wcd9xxx_resmgr_cfilt_put(&msm8x10_wcd->resmgr, cfilt_sel_val);
+		break;
+	}
+
+	return 0;
+}
+
+#define  TX_MUX_CTL_CUT_OFF_FREQ_MASK	0x30
+#define  CF_MIN_3DB_4HZ			0x0
+#define  CF_MIN_3DB_75HZ		0x1
+#define  CF_MIN_3DB_150HZ		0x2
+
+static int msm8x10_wcd_codec_enable_dec(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	unsigned int decimator;
+	char *dec_name = NULL;
+	char *widget_name = NULL;
+	char *temp;
+	int ret = 0;
+	u16 dec_reset_reg, tx_vol_ctl_reg, tx_mux_ctl_reg;
+	u8 dec_hpf_cut_of_freq;
+	int offset;
+
+	dev_dbg(codec->dev, "%s %d\n", __func__, event);
+
+	widget_name = kstrndup(w->name, 15, GFP_KERNEL);
+	if (!widget_name)
+		return -ENOMEM;
+	temp = widget_name;
+
+	dec_name = strsep(&widget_name, " ");
+	widget_name = temp;
+	if (!dec_name) {
+		dev_err(codec->dev,
+			"%s: Invalid decimator = %s\n", __func__, w->name);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = kstrtouint(strpbrk(dec_name, "12"), 10, &decimator);
+	if (ret < 0) {
+		dev_err(codec->dev,
+			"%s: Invalid decimator = %s\n", __func__, dec_name);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	dev_dbg(codec->dev,
+		"%s(): widget = %s dec_name = %s decimator = %u\n", __func__,
+		w->name, dec_name, decimator);
+
+	if (w->reg == MSM8X10_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL) {
+		dec_reset_reg = MSM8X10_WCD_A_CDC_CLK_TX_RESET_B1_CTL;
+		offset = 0;
+	} else {
+		dev_err(codec->dev, "%s: Error, incorrect dec\n", __func__);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	tx_vol_ctl_reg = MSM8X10_WCD_A_CDC_TX1_VOL_CTL_CFG +
+			 32 * (decimator - 1);
+	tx_mux_ctl_reg = MSM8X10_WCD_A_CDC_TX1_MUX_CTL +
+			  32 * (decimator - 1);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		/* Enableable TX digital mute */
+		snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01);
+
+		snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift,
+			1 << w->shift);
+		snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift, 0x0);
+
+		dec_hpf_cut_of_freq = snd_soc_read(codec, tx_mux_ctl_reg);
+
+		dec_hpf_cut_of_freq = (dec_hpf_cut_of_freq & 0x30) >> 4;
+
+		tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq =
+			dec_hpf_cut_of_freq;
+
+		if ((dec_hpf_cut_of_freq != CF_MIN_3DB_150HZ)) {
+
+			/* set cut of freq to CF_MIN_3DB_150HZ (0x1); */
+			snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30,
+					    CF_MIN_3DB_150HZ << 4);
+		}
+
+		/* enable HPF */
+		snd_soc_update_bits(codec, tx_mux_ctl_reg , 0x08, 0x00);
+		break;
+	case SND_SOC_DAPM_POST_PMU:
+		/* Disable TX digital mute */
+		snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00);
+
+		if (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq !=
+				CF_MIN_3DB_150HZ) {
+
+			schedule_delayed_work(&tx_hpf_work[decimator - 1].dwork,
+					msecs_to_jiffies(300));
+		}
+		/* apply the digital gain after the decimator is enabled*/
+		if ((w->shift) < ARRAY_SIZE(tx_digital_gain_reg))
+			snd_soc_write(codec,
+				  tx_digital_gain_reg[w->shift + offset],
+				  snd_soc_read(codec,
+				  tx_digital_gain_reg[w->shift + offset])
+				  );
+		break;
+	case SND_SOC_DAPM_PRE_PMD:
+		snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01);
+		cancel_delayed_work_sync(&tx_hpf_work[decimator - 1].dwork);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x08, 0x08);
+		snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30,
+			(tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq) << 4);
+		break;
+	}
+out:
+	kfree(widget_name);
+	return ret;
+}
+
+static int msm8x10_wcd_codec_enable_interpolator(struct snd_soc_dapm_widget *w,
+						 struct snd_kcontrol *kcontrol,
+						 int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+
+	dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		snd_soc_update_bits(codec, MSM8X10_WCD_A_CDC_CLK_RX_RESET_CTL,
+			1 << w->shift, 1 << w->shift);
+		snd_soc_update_bits(codec, MSM8X10_WCD_A_CDC_CLK_RX_RESET_CTL,
+			1 << w->shift, 0x0);
+		break;
+	case SND_SOC_DAPM_POST_PMU:
+		/* apply the digital gain after the interpolator is enabled*/
+		if ((w->shift) < ARRAY_SIZE(rx_digital_gain_reg))
+			snd_soc_write(codec,
+				  rx_digital_gain_reg[w->shift],
+				  snd_soc_read(codec,
+				  rx_digital_gain_reg[w->shift])
+				  );
+		break;
+	}
+	return 0;
+}
+
+
+/* The register address is the same as other codec so it can use resmgr */
+static int msm8x10_wcd_codec_enable_rx_bias(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	struct msm8x10_wcd_priv *msm8x10_wcd = snd_soc_codec_get_drvdata(codec);
+
+	dev_dbg(codec->dev, "%s %d\n", __func__, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		wcd9xxx_resmgr_enable_rx_bias(&msm8x10_wcd->resmgr, 1);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		wcd9xxx_resmgr_enable_rx_bias(&msm8x10_wcd->resmgr, 0);
+		break;
+	}
+	return 0;
+}
+
+static int msm8x10_wcd_hphr_dac_event(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+
+	dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		snd_soc_update_bits(codec, w->reg, 0x40, 0x40);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		snd_soc_update_bits(codec, w->reg, 0x40, 0x00);
+		break;
+	}
+	return 0;
+}
+
+static int msm8x10_wcd_hph_pa_event(struct snd_soc_dapm_widget *w,
+			      struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	struct msm8x10_wcd_priv *msm8x10_wcd = snd_soc_codec_get_drvdata(codec);
+	enum wcd9xxx_notify_event e_pre_on, e_post_off;
+
+	dev_dbg(codec->dev, "%s: %s event = %d\n", __func__, w->name, event);
+	if (w->shift == 5) {
+		e_pre_on = WCD9XXX_EVENT_PRE_HPHR_PA_ON;
+		e_post_off = WCD9XXX_EVENT_POST_HPHR_PA_OFF;
+	} else if (w->shift == 4) {
+		e_pre_on = WCD9XXX_EVENT_PRE_HPHL_PA_ON;
+		e_post_off = WCD9XXX_EVENT_POST_HPHL_PA_OFF;
+	} else {
+		dev_err(codec->dev,
+			"%s: Invalid w->shift %d\n", __func__, w->shift);
+		return -EINVAL;
+	}
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		/* Let MBHC module know PA is turning on */
+		wcd9xxx_resmgr_notifier_call(&msm8x10_wcd->resmgr, e_pre_on);
+		break;
+
+	case SND_SOC_DAPM_POST_PMU:
+		usleep_range(10000, 10100);
+		break;
+
+	case SND_SOC_DAPM_POST_PMD:
+		/* Let MBHC module know PA turned off */
+		wcd9xxx_resmgr_notifier_call(&msm8x10_wcd->resmgr, e_post_off);
+
+		/*
+		 * schedule work is required because at the time HPH PA DAPM
+		 * event callback is called by DAPM framework, CODEC dapm mutex
+		 * would have been locked while snd_soc_jack_report also
+		 * attempts to acquire same lock.
+		 */
+		dev_dbg(codec->dev,
+			"%s: sleep 10 ms after %s PA disable.\n", __func__,
+			w->name);
+		usleep_range(10000, 10100);
+		break;
+	}
+	return 0;
+}
+
+static int msm8x10_wcd_lineout_dac_event(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+
+	dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		snd_soc_update_bits(codec, w->reg, 0x40, 0x40);
+		break;
+
+	case SND_SOC_DAPM_POST_PMD:
+		snd_soc_update_bits(codec, w->reg, 0x40, 0x00);
+		break;
+	}
+	return 0;
+}
+
+static int msm8x10_wcd_spk_dac_event(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	dev_dbg(w->codec->dev, "%s %s %d\n", __func__, w->name, event);
+	return 0;
+}
+
+static const struct snd_soc_dapm_route audio_map[] = {
+	{"RX_I2S_CLK", NULL, "CDC_CONN"},
+	{"I2S RX1", NULL, "RX_I2S_CLK"},
+	{"I2S RX2", NULL, "RX_I2S_CLK"},
+	{"I2S RX3", NULL, "RX_I2S_CLK"},
+
+	{"I2S TX1", NULL, "TX_I2S_CLK"},
+	{"I2S TX2", NULL, "TX_I2S_CLK"},
+	{"I2S TX3", NULL, "TX_I2S_CLK"},
+	{"I2S TX4", NULL, "TX_I2S_CLK"},
+
+	{"AIF1 CAP", NULL, "AIF1_CAP Mixer"},
+
+	{"AIF1_CAP Mixer", "I2S TX1", "I2S TX1 MUX"},
+	{"AIF1_CAP Mixer", "I2S TX2", "I2S TX2 MUX"},
+	{"AIF1_CAP Mixer", "I2S TX3", "I2S TX3 MUX"},
+	{"AIF1_CAP Mixer", "I2S TX4", "I2S TX4 MUX"},
+
+	{"I2S TX1 MUX", NULL, "DEC1 MUX"},
+	{"I2S TX2 MUX", NULL, "DEC2 MUX"},
+	{"I2S TX3 MUX", NULL, "RX1 MIX1"},
+	{"I2S TX4 MUX", "RMIX2", "RX1 MIX2"},
+	{"I2S TX4 MUX", "RMIX3", "RX1 MIX3"},
+
+	/* Earpiece (RX MIX1) */
+	{"EAR", NULL, "EAR PA"},
+	{"EAR PA", NULL, "DAC1"},
+	{"DAC1", NULL, "CP"},
+
+	/* Headset (RX MIX1 and RX MIX2) */
+	{"HEADPHONE", NULL, "HPHL"},
+	{"HEADPHONE", NULL, "HPHR"},
+
+	{"HPHL", NULL, "HPHL DAC"},
+
+	{"HPHR", NULL, "HPHR DAC"},
+	{"HPHR_PA_MIXER", NULL, "HPHR DAC"},
+
+	{"HPHL DAC", NULL, "CP"},
+
+	{"HPHR DAC", NULL, "CP"},
+
+	{"DAC1", "Switch", "RX1 CHAIN"},
+	{"HPHL DAC", "Switch", "RX1 CHAIN"},
+	{"HPHR DAC", NULL, "RX2 CHAIN"},
+
+	{"LINEOUT1", NULL, "LINEOUT1 PA"},
+	{"SPK_OUT", NULL, "SPK PA"},
+
+	{"LINEOUT1 PA", NULL, "CP"},
+	{"LINEOUT1 PA", NULL, "LINEOUT1 DAC"},
+
+	{"LINEOUT1 DAC", "RX2 INPUT", "RX2 MIX1"},
+	{"LINEOUT1 DAC", "RX3 INPUT", "RX3 MIX1"},
+
+	{"SPK PA", NULL, "SPK DAC"},
+	{"SPK DAC", NULL, "RX7 MIX2"},
+
+	{"RX1 CHAIN", NULL, "RX1 MIX2"},
+	{"RX2 CHAIN", NULL, "RX2 MIX2"},
+
+	{"LINEOUT1 DAC", NULL, "RX_BIAS"},
+	{"SPK DAC", NULL, "RX_BIAS"},
+
+	{"RX1 MIX1", NULL, "RX1 MIX1 INP1"},
+	{"RX1 MIX1", NULL, "RX1 MIX1 INP2"},
+	{"RX1 MIX1", NULL, "RX1 MIX1 INP3"},
+	{"RX2 MIX1", NULL, "RX2 MIX1 INP1"},
+	{"RX2 MIX1", NULL, "RX2 MIX1 INP2"},
+	{"RX3 MIX1", NULL, "RX3 MIX1 INP1"},
+	{"RX3 MIX1", NULL, "RX3 MIX1 INP2"},
+	{"RX1 MIX2", NULL, "RX1 MIX1"},
+	{"RX1 MIX2", NULL, "RX1 MIX2 INP1"},
+	{"RX1 MIX2", NULL, "RX1 MIX2 INP2"},
+	{"RX2 MIX2", NULL, "RX2 MIX1"},
+	{"RX2 MIX2", NULL, "RX2 MIX2 INP1"},
+	{"RX2 MIX2", NULL, "RX2 MIX2 INP2"},
+
+	{"I2S RX1 MUX", "AIF1_PB", "AIF1 PB"},
+	{"I2S RX2 MUX", "AIF1_PB", "AIF1 PB"},
+	{"I2S RX3 MUX", "AIF1_PB", "AIF1 PB"},
+
+	{"I2S RX1", NULL, "I2S RX1 MUX"},
+	{"I2S RX2", NULL, "I2S RX2 MUX"},
+	{"I2S RX3", NULL, "I2S RX3 MUX"},
+
+	{"RX1 MIX1 INP1", "RX1", "I2S RX1"},
+	{"RX1 MIX1 INP1", "RX2", "I2S RX2"},
+	{"RX1 MIX1 INP1", "RX3", "I2S RX3"},
+	{"RX1 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX1 MIX1 INP2", "RX1", "I2S RX1"},
+	{"RX1 MIX1 INP2", "RX2", "I2S RX2"},
+	{"RX1 MIX1 INP2", "RX3", "I2S RX3"},
+	{"RX1 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX1 MIX1 INP3", "RX1", "I2S RX1"},
+	{"RX1 MIX1 INP3", "RX2", "I2S RX2"},
+	{"RX1 MIX1 INP3", "RX3", "I2S RX3"},
+
+	{"RX2 MIX1 INP1", "RX1", "I2S RX1"},
+	{"RX2 MIX1 INP1", "RX2", "I2S RX2"},
+	{"RX2 MIX1 INP1", "RX3", "I2S RX3"},
+	{"RX2 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX2 MIX1 INP2", "RX1", "I2S RX1"},
+	{"RX2 MIX1 INP2", "RX2", "I2S RX2"},
+	{"RX2 MIX1 INP2", "RX3", "I2S RX3"},
+	{"RX2 MIX1 INP2", "IIR1", "IIR1"},
+
+	{"RX3 MIX1 INP1", "RX1", "I2S RX1"},
+	{"RX3 MIX1 INP1", "RX2", "I2S RX2"},
+	{"RX3 MIX1 INP1", "RX3", "I2S RX3"},
+	{"RX3 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX3 MIX1 INP2", "RX1", "I2S RX1"},
+	{"RX3 MIX1 INP2", "RX2", "I2S RX2"},
+	{"RX3 MIX1 INP2", "RX3", "I2S RX3"},
+	{"RX3 MIX1 INP2", "IIR1", "IIR1"},
+
+	/* Decimator Inputs */
+	{"DEC1 MUX", "DMIC1", "DMIC1"},
+	{"DEC1 MUX", "DMIC2", "DMIC2"},
+	{"DEC1 MUX", "ADC1", "ADC1"},
+	{"DEC1 MUX", "ADC2", "ADC2"},
+	{"DEC1 MUX", NULL, "CDC_CONN"},
+
+	{"DEC2 MUX", "DMIC1", "DMIC1"},
+	{"DEC2 MUX", "DMIC2", "DMIC2"},
+	{"DEC2 MUX", "ADC1", "ADC1"},
+	{"DEC2 MUX", "ADC2", "ADC2"},
+	{"DEC2 MUX", NULL, "CDC_CONN"},
+
+	/* ADC Connections */
+	{"ADC1", NULL, "AMIC1"},
+	{"ADC2", NULL, "AMIC2"},
+
+	{"IIR1", NULL, "IIR1 INP1 MUX"},
+	{"IIR1 INP1 MUX", "DEC1", "DEC1 MUX"},
+	{"IIR1 INP1 MUX", "DEC2", "DEC2 MUX"},
+
+	/* There is no LDO_H in Helicon */
+	{"MIC BIAS1 Internal1", NULL, "LDO_H"},
+	{"MIC BIAS1 Internal2", NULL, "LDO_H"},
+	{"MIC BIAS1 External", NULL, "LDO_H"},
+};
+
+static int msm8x10_wcd_startup(struct snd_pcm_substream *substream,
+		struct snd_soc_dai *dai)
+{
+	struct msm8x10_wcd *msm8x10_wcd_core =
+		dev_get_drvdata(dai->codec->dev);
+	dev_dbg(dai->codec->dev, "%s(): substream = %s  stream = %d\n",
+		__func__,
+		substream->name, substream->stream);
+	if ((msm8x10_wcd_core != NULL) &&
+	    (msm8x10_wcd_core->dev != NULL))
+		pm_runtime_get_sync(msm8x10_wcd_core->dev);
+
+	return 0;
+}
+
+static void msm8x10_wcd_shutdown(struct snd_pcm_substream *substream,
+		struct snd_soc_dai *dai)
+{
+	struct msm8x10_wcd *msm8x10_wcd_core =
+		dev_get_drvdata(dai->codec->dev);
+	dev_dbg(dai->codec->dev,
+		"%s(): substream = %s  stream = %d\n" , __func__,
+		substream->name, substream->stream);
+	if ((msm8x10_wcd_core != NULL) &&
+	    (msm8x10_wcd_core->dev != NULL)) {
+		pm_runtime_mark_last_busy(msm8x10_wcd_core->dev);
+		pm_runtime_put(msm8x10_wcd_core->dev);
+	}
+}
+
+int msm8x10_wcd_mclk_enable(struct snd_soc_codec *codec,
+			    int mclk_enable, bool dapm)
+{
+	struct msm8x10_wcd_priv *msm8x10_wcd = snd_soc_codec_get_drvdata(codec);
+
+	dev_dbg(codec->dev,
+		"%s: mclk_enable = %u, dapm = %d\n", __func__,
+		mclk_enable, dapm);
+	WCD9XXX_BCL_LOCK(&msm8x10_wcd->resmgr);
+	if (mclk_enable) {
+		wcd9xxx_resmgr_get_bandgap(&msm8x10_wcd->resmgr,
+					   WCD9XXX_BANDGAP_AUDIO_MODE);
+		wcd9xxx_resmgr_get_clk_block(&msm8x10_wcd->resmgr,
+					     WCD9XXX_CLK_MCLK);
+	} else {
+		/* Put clock and BG */
+		wcd9xxx_resmgr_put_clk_block(&msm8x10_wcd->resmgr,
+					     WCD9XXX_CLK_MCLK);
+		wcd9xxx_resmgr_put_bandgap(&msm8x10_wcd->resmgr,
+					   WCD9XXX_BANDGAP_AUDIO_MODE);
+	}
+	WCD9XXX_BCL_UNLOCK(&msm8x10_wcd->resmgr);
+
+	return 0;
+}
+
+static int msm8x10_wcd_set_dai_sysclk(struct snd_soc_dai *dai,
+		int clk_id, unsigned int freq, int dir)
+{
+	dev_dbg(dai->codec->dev, "%s\n", __func__);
+	return 0;
+}
+
+static int msm8x10_wcd_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	dev_dbg(dai->codec->dev, "%s\n", __func__);
+	return 0;
+}
+
+static int msm8x10_wcd_set_channel_map(struct snd_soc_dai *dai,
+				unsigned int tx_num, unsigned int *tx_slot,
+				unsigned int rx_num, unsigned int *rx_slot)
+
+{
+	dev_dbg(dai->codec->dev, "%s\n", __func__);
+	return 0;
+}
+
+static int msm8x10_wcd_get_channel_map(struct snd_soc_dai *dai,
+				 unsigned int *tx_num, unsigned int *tx_slot,
+				 unsigned int *rx_num, unsigned int *rx_slot)
+
+{
+	dev_dbg(dai->codec->dev, "%s\n", __func__);
+	return 0;
+}
+
+static int msm8x10_wcd_set_interpolator_rate(struct snd_soc_dai *dai,
+	u8 rx_fs_rate_reg_val, u32 sample_rate)
+{
+	return 0;
+}
+
+static int msm8x10_wcd_set_decimator_rate(struct snd_soc_dai *dai,
+	u8 tx_fs_rate_reg_val, u32 sample_rate)
+{
+	return 0;
+}
+
+static int msm8x10_wcd_hw_params(struct snd_pcm_substream *substream,
+			    struct snd_pcm_hw_params *params,
+			    struct snd_soc_dai *dai)
+{
+	u8 tx_fs_rate, rx_fs_rate;
+	int ret;
+
+	dev_dbg(dai->codec->dev,
+		"%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
+		 dai->name, dai->id, params_rate(params),
+		 params_channels(params));
+
+	switch (params_rate(params)) {
+	case 8000:
+		tx_fs_rate = 0x00;
+		rx_fs_rate = 0x00;
+		break;
+	case 16000:
+		tx_fs_rate = 0x01;
+		rx_fs_rate = 0x20;
+		break;
+	case 32000:
+		tx_fs_rate = 0x02;
+		rx_fs_rate = 0x40;
+		break;
+	case 48000:
+		tx_fs_rate = 0x03;
+		rx_fs_rate = 0x60;
+		break;
+	case 96000:
+		tx_fs_rate = 0x04;
+		rx_fs_rate = 0x80;
+		break;
+	case 192000:
+		tx_fs_rate = 0x05;
+		rx_fs_rate = 0xA0;
+		break;
+	default:
+		dev_err(dai->codec->dev,
+			"%s: Invalid sampling rate %d\n", __func__,
+			params_rate(params));
+		return -EINVAL;
+	}
+
+	switch (substream->stream) {
+	case SNDRV_PCM_STREAM_CAPTURE:
+		ret = msm8x10_wcd_set_decimator_rate(dai, tx_fs_rate,
+					       params_rate(params));
+		if (ret < 0) {
+			dev_err(dai->codec->dev,
+				"%s: set decimator rate failed %d\n", __func__,
+				ret);
+			return ret;
+		}
+		break;
+	case SNDRV_PCM_STREAM_PLAYBACK:
+		ret = msm8x10_wcd_set_interpolator_rate(dai, rx_fs_rate,
+						  params_rate(params));
+		if (ret < 0) {
+			dev_err(dai->codec->dev,
+				"%s: set decimator rate failed %d\n", __func__,
+				ret);
+			return ret;
+		}
+		break;
+	default:
+		dev_err(dai->codec->dev,
+			"%s: Invalid stream type %d\n", __func__,
+			substream->stream);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct snd_soc_dai_ops msm8x10_wcd_dai_ops = {
+	.startup = msm8x10_wcd_startup,
+	.shutdown = msm8x10_wcd_shutdown,
+	.hw_params = msm8x10_wcd_hw_params,
+	.set_sysclk = msm8x10_wcd_set_dai_sysclk,
+	.set_fmt = msm8x10_wcd_set_dai_fmt,
+	.set_channel_map = msm8x10_wcd_set_channel_map,
+	.get_channel_map = msm8x10_wcd_get_channel_map,
+};
+
+static struct snd_soc_dai_driver msm8x10_wcd_i2s_dai[] = {
+	{
+		.name = "msm8x10_wcd_i2s_rx1",
+		.id = AIF1_PB,
+		.playback = {
+			.stream_name = "AIF1 Playback",
+			.rates = MSM8X10_WCD_RATES,
+			.formats = MSM8X10_WCD_FORMATS,
+			.rate_max = 192000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 4,
+		},
+		.ops = &msm8x10_wcd_dai_ops,
+	},
+	{
+		.name = "msm8x10_wcd_i2s_tx1",
+		.id = AIF1_CAP,
+		.capture = {
+			.stream_name = "AIF1 Capture",
+			.rates = MSM8X10_WCD_RATES,
+			.formats = MSM8X10_WCD_FORMATS,
+			.rate_max = 192000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 4,
+		},
+		.ops = &msm8x10_wcd_dai_ops,
+	},
+};
+
+static int msm8x10_wcd_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		dev_dbg(w->codec->dev,
+			"%s: Sleeping 20ms after enabling EAR PA\n",
+			__func__);
+		msleep(20);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		dev_dbg(w->codec->dev,
+			"%s: Sleeping 20ms after disabling EAR PA\n",
+			__func__);
+		msleep(20);
+		break;
+	}
+	return 0;
+}
+
+static const struct snd_soc_dapm_widget msm8x10_wcd_dapm_widgets[] = {
+	/*RX stuff */
+	SND_SOC_DAPM_OUTPUT("EAR"),
+
+	SND_SOC_DAPM_PGA_E("EAR PA", MSM8X10_WCD_A_RX_EAR_EN, 4, 0, NULL, 0,
+			msm8x10_wcd_codec_enable_ear_pa, SND_SOC_DAPM_POST_PMU),
+
+	SND_SOC_DAPM_MIXER("DAC1", MSM8X10_WCD_A_RX_EAR_EN, 6, 0, dac1_switch,
+		ARRAY_SIZE(dac1_switch)),
+
+	SND_SOC_DAPM_AIF_IN("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM,
+				AIF1_PB, 0),
+
+	SND_SOC_DAPM_MUX("I2S RX1 MUX", SND_SOC_NOPM, MSM8X10_WCD_RX1, 0,
+				&slim_rx_mux[MSM8X10_WCD_RX1]),
+	SND_SOC_DAPM_MUX("I2S RX2 MUX", SND_SOC_NOPM, MSM8X10_WCD_RX2, 0,
+				&slim_rx_mux[MSM8X10_WCD_RX2]),
+	SND_SOC_DAPM_MUX("I2S RX3 MUX", SND_SOC_NOPM, MSM8X10_WCD_RX3, 0,
+				&slim_rx_mux[MSM8X10_WCD_RX3]),
+
+	SND_SOC_DAPM_MIXER("I2S RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("I2S RX2", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("I2S RX3", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("I2S RX4", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("I2S RX5", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+	/* Headphone */
+	SND_SOC_DAPM_OUTPUT("HEADPHONE"),
+	SND_SOC_DAPM_PGA_E("HPHL", MSM8X10_WCD_A_RX_HPH_CNP_EN,
+		5, 0, NULL, 0,
+		msm8x10_wcd_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MIXER("HPHL DAC", MSM8X10_WCD_A_RX_HPH_L_DAC_CTL,
+		7, 0,
+		hphl_switch, ARRAY_SIZE(hphl_switch)),
+
+	SND_SOC_DAPM_PGA_E("HPHR", MSM8X10_WCD_A_RX_HPH_CNP_EN,
+		4, 0, NULL, 0,
+		msm8x10_wcd_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU |	SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_DAC_E("HPHR DAC", NULL, MSM8X10_WCD_A_RX_HPH_R_DAC_CTL,
+		7, 0,
+		msm8x10_wcd_hphr_dac_event,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	/* Speaker */
+	SND_SOC_DAPM_OUTPUT("LINEOUT1"),
+	SND_SOC_DAPM_OUTPUT("SPK_OUT"),
+
+	SND_SOC_DAPM_PGA_E("LINEOUT1 PA", MSM8X10_WCD_A_RX_LINE_CNP_EN,
+			0, 0, NULL, 0, msm8x10_wcd_codec_enable_lineout,
+			SND_SOC_DAPM_PRE_PMU |
+			SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_PGA_E("SPK PA", MSM8X10_WCD_A_SPKR_DRV_EN,
+			7, 0 , NULL, 0, msm8x10_wcd_codec_enable_spk_pa,
+			SND_SOC_DAPM_PRE_PMU |
+			SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_DAC_E("LINEOUT1 DAC", NULL,
+		MSM8X10_WCD_A_RX_LINE_1_DAC_CTL, 7, 0,
+		msm8x10_wcd_lineout_dac_event,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_DAC_E("SPK DAC", NULL, SND_SOC_NOPM, 0, 0,
+			   msm8x10_wcd_spk_dac_event,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MIXER("RX1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("RX2 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+	SND_SOC_DAPM_MIXER_E("RX1 MIX2",
+		MSM8X10_WCD_A_CDC_CLK_RX_B1_CTL, 0, 0, NULL,
+		0, msm8x10_wcd_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU),
+	SND_SOC_DAPM_MIXER_E("RX2 MIX2",
+		MSM8X10_WCD_A_CDC_CLK_RX_B1_CTL, 1, 0, NULL,
+		0, msm8x10_wcd_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU),
+	SND_SOC_DAPM_MIXER_E("RX3 MIX1",
+		MSM8X10_WCD_A_CDC_CLK_RX_B1_CTL, 2, 0, NULL,
+		0, msm8x10_wcd_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU),
+
+	SND_SOC_DAPM_MIXER("RX1 CHAIN", MSM8X10_WCD_A_CDC_RX1_B6_CTL,
+		5, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("RX2 CHAIN", MSM8X10_WCD_A_CDC_RX2_B6_CTL,
+		5, 0, NULL, 0),
+
+	SND_SOC_DAPM_MUX("RX1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
+		&rx_mix1_inp1_mux),
+	SND_SOC_DAPM_MUX("RX1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
+		&rx_mix1_inp2_mux),
+	SND_SOC_DAPM_MUX("RX1 MIX1 INP3", SND_SOC_NOPM, 0, 0,
+		&rx_mix1_inp3_mux),
+	SND_SOC_DAPM_MUX("RX2 MIX1 INP1", SND_SOC_NOPM, 0, 0,
+		&rx2_mix1_inp1_mux),
+	SND_SOC_DAPM_MUX("RX2 MIX1 INP2", SND_SOC_NOPM, 0, 0,
+		&rx2_mix1_inp2_mux),
+	SND_SOC_DAPM_MUX("RX3 MIX1 INP1", SND_SOC_NOPM, 0, 0,
+		&rx3_mix1_inp1_mux),
+	SND_SOC_DAPM_MUX("RX3 MIX1 INP2", SND_SOC_NOPM, 0, 0,
+		&rx3_mix1_inp2_mux),
+	SND_SOC_DAPM_MUX("RX1 MIX2 INP1", SND_SOC_NOPM, 0, 0,
+		&rx1_mix2_inp1_mux),
+	SND_SOC_DAPM_MUX("RX2 MIX2 INP1", SND_SOC_NOPM, 0, 0,
+		&rx2_mix2_inp1_mux),
+
+	SND_SOC_DAPM_SUPPLY("CP", MSM8X10_WCD_A_CP_EN, 0, 0,
+		msm8x10_wcd_codec_enable_charge_pump, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+
+	SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0,
+		msm8x10_wcd_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	/* TX */
+
+	SND_SOC_DAPM_SUPPLY("CDC_CONN", MSM8X10_WCD_A_CDC_CLK_OTHR_CTL,
+		2, 0, NULL, 0),
+
+
+	SND_SOC_DAPM_INPUT("AMIC1"),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 External",
+		MSM8X10_WCD_A_MICB_1_CTL, 7, 0,
+		msm8x10_wcd_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal1",
+		MSM8X10_WCD_A_MICB_1_CTL, 7, 0,
+		msm8x10_wcd_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal2",
+		MSM8X10_WCD_A_MICB_1_CTL, 7, 0,
+		msm8x10_wcd_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_ADC_E("ADC1", NULL, MSM8X10_WCD_A_TX_1_EN, 7, 0,
+		msm8x10_wcd_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("ADC1", NULL, MSM8X10_WCD_A_TX_2_EN, 7, 0,
+		msm8x10_wcd_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_INPUT("AMIC3"),
+
+	SND_SOC_DAPM_MUX_E("DEC1 MUX",
+		MSM8X10_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL, 0, 0,
+		&dec1_mux, msm8x10_wcd_codec_enable_dec,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+		SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("DEC2 MUX",
+		MSM8X10_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL, 1, 0,
+		&dec2_mux, msm8x10_wcd_codec_enable_dec,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+		SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_INPUT("AMIC2"),
+	SND_SOC_DAPM_AIF_OUT("AIF1 CAP", "AIF1 Capture", 0, SND_SOC_NOPM,
+		AIF1_CAP, 0),
+
+	SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0,
+		aif_cap_mixer, ARRAY_SIZE(aif_cap_mixer)),
+
+	/* Digital Mic Inputs */
+	SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
+		msm8x10_wcd_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0,
+		msm8x10_wcd_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	/* Sidetone */
+	SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux),
+	SND_SOC_DAPM_PGA("IIR1", MSM8X10_WCD_A_CDC_CLK_SD_CTL, 0, 0, NULL, 0),
+
+	SND_SOC_DAPM_SUPPLY("RX_I2S_CLK", MSM8X10_WCD_A_CDC_CLK_RX_I2S_CTL,
+		4, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("TX_I2S_CLK", MSM8X10_WCD_A_CDC_CLK_TX_I2S_CTL, 4,
+		0, NULL, 0),
+};
+
+static const struct msm8x10_wcd_reg_mask_val msm8x10_wcd_reg_defaults[] = {
+
+	/* set MCLk to 9.6 */
+	MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_CHIP_CTL, 0x0A),
+
+	/* EAR PA deafults  */
+	MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_RX_EAR_CMBUFF, 0x05),
+
+	/* RX deafults */
+	MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_CDC_RX1_B5_CTL, 0x78),
+	MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_CDC_RX2_B5_CTL, 0x78),
+	MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_CDC_RX3_B5_CTL, 0x78),
+
+	/* RX1 and RX2 defaults */
+	MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_CDC_RX1_B6_CTL, 0xA0),
+	MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_CDC_RX2_B6_CTL, 0xA0),
+
+	/* RX3 to RX7 defaults */
+	MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_CDC_RX3_B6_CTL, 0x80),
+
+	/* Reduce HPH DAC bias to 70% */
+	MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_RX_HPH_BIAS_PA, 0x7A),
+	/*Reduce EAR DAC bias to 70% */
+	MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_RX_EAR_BIAS_PA, 0x76),
+	/* Reduce LINE DAC bias to 70% */
+	MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_RX_LINE_BIAS_PA, 0x78),
+
+
+	/* Disable TX7 internal biasing path which can cause leakage */
+	MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_TX_SUP_SWITCH_CTRL_1, 0xBF),
+};
+
+static void msm8x10_wcd_update_reg_defaults(struct snd_soc_codec *codec)
+{
+	u32 i;
+
+	for (i = 0; i < ARRAY_SIZE(msm8x10_wcd_reg_defaults); i++)
+		snd_soc_write(codec, msm8x10_wcd_reg_defaults[i].reg,
+				msm8x10_wcd_reg_defaults[i].val);
+}
+
+static const struct msm8x10_wcd_reg_mask_val
+	msm8x10_wcd_codec_reg_init_val[] = {
+	/* Initialize current threshold to 350MA
+	 * number of wait and run cycles to 4096
+	 */
+	{MSM8X10_WCD_A_RX_HPH_OCP_CTL, 0xE1, 0x61},
+	{MSM8X10_WCD_A_RX_COM_OCP_COUNT, 0xFF, 0xFF},
+
+	/* Initialize gain registers to use register gain */
+	{MSM8X10_WCD_A_RX_HPH_L_GAIN, 0x20, 0x20},
+	{MSM8X10_WCD_A_RX_HPH_R_GAIN, 0x20, 0x20},
+	{MSM8X10_WCD_A_RX_LINE_1_GAIN, 0x20, 0x20},
+
+	/*enable HPF filter for TX paths */
+	{MSM8X10_WCD_A_CDC_TX1_MUX_CTL, 0x8, 0x0},
+	{MSM8X10_WCD_A_CDC_TX2_MUX_CTL, 0x8, 0x0},
+
+	/* config Decimator for DMIC CLK_MODE_1(3.2Mhz@9.6Mhz mclk) */
+	{MSM8X10_WCD_A_CDC_TX1_DMIC_CTL, 0x7, 0x1},
+	{MSM8X10_WCD_A_CDC_TX2_DMIC_CTL, 0x7, 0x1},
+
+	/* config DMIC clk to CLK_MODE_1 (3.2Mhz@9.6Mhz mclk) */
+	{MSM8X10_WCD_A_CDC_CLK_DMIC_B1_CTL, 0xEE, 0x22},
+
+};
+
+static void msm8x10_wcd_codec_init_reg(struct snd_soc_codec *codec)
+{
+	u32 i;
+
+	for (i = 0; i < ARRAY_SIZE(msm8x10_wcd_codec_reg_init_val); i++)
+		snd_soc_update_bits(codec,
+				    msm8x10_wcd_codec_reg_init_val[i].reg,
+				    msm8x10_wcd_codec_reg_init_val[i].mask,
+				    msm8x10_wcd_codec_reg_init_val[i].val);
+}
+
+int msm8x10_wcd_hs_detect(struct snd_soc_codec *codec,
+		    struct msm8x10_wcd_mbhc_config *mbhc_cfg)
+{
+	return 0;
+}
+EXPORT_SYMBOL_GPL(msm8x10_wcd_hs_detect);
+
+static int msm8x10_wcd_codec_probe(struct snd_soc_codec *codec)
+{
+	dev_dbg(codec->dev, "%s()\n", __func__);
+
+	codec->control_data = dev_get_drvdata(codec->dev);
+	msm8x10_wcd_codec_init_reg(codec);
+	msm8x10_wcd_update_reg_defaults(codec);
+
+
+	return 0;
+}
+
+static int msm8x10_wcd_codec_remove(struct snd_soc_codec *codec)
+{
+	return 0;
+}
+
+static int msm8x10_wcd_device_init(struct msm8x10_wcd *msm8x10)
+{
+
+	mutex_init(&msm8x10->io_lock);
+	mutex_init(&msm8x10->xfer_lock);
+	mutex_init(&msm8x10->pm_lock);
+	msm8x10->wlock_holders = 0;
+
+	return 0;
+}
+
+
+static struct snd_soc_codec_driver soc_codec_dev_msm8x10_wcd = {
+	.probe	= msm8x10_wcd_codec_probe,
+	.remove	= msm8x10_wcd_codec_remove,
+
+	.read = msm8x10_wcd_read,
+	.write = msm8x10_wcd_write,
+
+	.readable_register = msm8x10_wcd_readable,
+	.volatile_register = msm8x10_wcd_volatile,
+
+	.reg_cache_size = MSM8X10_WCD_CACHE_SIZE,
+	.reg_cache_default = msm8x10_wcd_reset_reg_defaults,
+	.reg_word_size = 1,
+
+	.controls = msm8x10_wcd_snd_controls,
+	.num_controls = ARRAY_SIZE(msm8x10_wcd_snd_controls),
+	.dapm_widgets = msm8x10_wcd_dapm_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(msm8x10_wcd_dapm_widgets),
+	.dapm_routes = audio_map,
+	.num_dapm_routes = ARRAY_SIZE(audio_map),
+};
+
+static int __devinit msm8x10_wcd_i2c_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	int ret = 0;
+	struct msm8x10_wcd *msm8x10 = NULL;
+	struct msm8x10_wcd_pdata *pdata;
+	static int device_id;
+	struct device *dev;
+
+	dev_dbg(&client->dev, "%s:slave addr = 0x%x device_id = %d\n",
+		__func__, client->addr, device_id);
+
+	if (device_id > 0) {
+		msm8x10_wcd_modules[device_id++].client = client;
+		return ret;
+	}
+
+	dev = &client->dev;
+	if (client->dev.of_node) {
+		dev_dbg(&client->dev, "%s:Platform data from device tree\n",
+			__func__);
+		pdata = msm8x10_wcd_populate_dt_pdata(&client->dev);
+		client->dev.platform_data = pdata;
+	} else {
+		dev_dbg(&client->dev, "%s:Platform data from board file\n",
+			__func__);
+		pdata = client->dev.platform_data;
+	}
+
+	msm8x10 = kzalloc(sizeof(struct msm8x10_wcd), GFP_KERNEL);
+	if (msm8x10 == NULL) {
+		dev_err(&client->dev,
+			"%s: error, allocation failed\n", __func__);
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	msm8x10->dev = &client->dev;
+	msm8x10_wcd_modules[device_id++].client = client;
+	msm8x10->read_dev = msm8x10_wcd_reg_read;
+	msm8x10->write_dev = msm8x10_wcd_reg_write;
+	ret = msm8x10_wcd_device_init(msm8x10);
+	if (ret) {
+		dev_err(&client->dev,
+			"%s:msm8x10_wcd_device_init failed with error %d\n",
+			__func__, ret);
+		goto fail;
+	}
+	dev_set_drvdata(&client->dev, msm8x10);
+	ret = snd_soc_register_codec(&client->dev, &soc_codec_dev_msm8x10_wcd,
+				     msm8x10_wcd_i2s_dai,
+				     ARRAY_SIZE(msm8x10_wcd_i2s_dai));
+	if (ret)
+		dev_err(&client->dev,
+			"%s:snd_soc_register_codec failed with error %d\n",
+			__func__, ret);
+fail:
+	return ret;
+}
+
+static void msm8x10_wcd_device_exit(struct msm8x10_wcd *msm8x10)
+{
+	mutex_destroy(&msm8x10->pm_lock);
+	mutex_destroy(&msm8x10->io_lock);
+	mutex_destroy(&msm8x10->xfer_lock);
+	kfree(msm8x10);
+}
+
+static int __devexit msm8x10_wcd_i2c_remove(struct i2c_client *client)
+{
+	struct msm8x10_wcd *msm8x10 = dev_get_drvdata(&client->dev);
+
+	msm8x10_wcd_device_exit(msm8x10);
+	return 0;
+}
+
+static struct i2c_device_id msm8x10_wcd_id_table[] = {
+	{"msm8x10-wcd-i2c", MSM8X10_WCD_I2C_TOP_LEVEL},
+	{"msm8x10-wcd-i2c", MSM8X10_WCD_I2C_ANALOG},
+	{"msm8x10-wcd-i2c", MSM8X10_WCD_I2C_DIGITAL_1},
+	{"msm8x10-wcd-i2c", MSM8X10_WCD_I2C_DIGITAL_2},
+	{}
+};
+
+static struct of_device_id msm8x10_wcd_of_match[] = {
+	{ .compatible = "qcom,msm8x10-wcd-i2c",},
+	{ },
+};
+
+
+static struct i2c_driver msm8x10_wcd_i2c_driver = {
+	.driver                 = {
+		.owner          = THIS_MODULE,
+		.name           = "msm8x10-wcd-i2c-core",
+		.of_match_table = msm8x10_wcd_of_match
+	},
+	.id_table               = msm8x10_wcd_id_table,
+	.probe                  = msm8x10_wcd_i2c_probe,
+	.remove                 = __devexit_p(msm8x10_wcd_i2c_remove),
+};
+
+static int __init msm8x10_wcd_codec_init(void)
+{
+	int ret;
+
+	pr_debug("%s:\n", __func__);
+	ret = i2c_add_driver(&msm8x10_wcd_i2c_driver);
+	if (ret != 0)
+		pr_err("%s: Failed to add msm8x10 wcd I2C driver - error %d\n",
+		       __func__, ret);
+	return ret;
+}
+
+static void __exit msm8x10_wcd_codec_exit(void)
+{
+	i2c_del_driver(&msm8x10_wcd_i2c_driver);
+}
+
+
+module_init(msm8x10_wcd_codec_init);
+module_exit(msm8x10_wcd_codec_exit);
+
+MODULE_DESCRIPTION("MSM8x10 Audio codec driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(i2c, msm8x10_wcd_id_table);
+
diff --git a/sound/soc/codecs/msm8x10-wcd.h b/sound/soc/codecs/msm8x10-wcd.h
new file mode 100644
index 0000000..44e8a6d
--- /dev/null
+++ b/sound/soc/codecs/msm8x10-wcd.h
@@ -0,0 +1,230 @@
+/* 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 MSM8X10_WCD_H
+#define MSM8X10_WCD_H
+
+#include <sound/soc.h>
+#include <sound/jack.h>
+#include "wcd9xxx-mbhc.h"
+#include "wcd9xxx-resmgr.h"
+
+#define MSM8X10_WCD_NUM_REGISTERS	0x600
+#define MSM8X10_WCD_MAX_REGISTER	(MSM8X10_WCD_NUM_REGISTERS-1)
+#define MSM8X10_WCD_CACHE_SIZE		MSM8X10_WCD_NUM_REGISTERS
+#define MSM8X10_WCD_NUM_IRQ_REGS	3
+#define MAX_REGULATOR				7
+#define MSM8X10_WCD_REG_VAL(reg, val)		{reg, 0, val}
+
+#define MSM8X10_WCD_IS_DINO_REG(reg) \
+	(((reg >= 0x400) && (reg <= 0x5FF)) ? 1 : 0)
+#define MSM8X10_WCD_IS_HELICON_REG(reg) \
+	(((reg >= 0x000) && (reg <= 0x1FF)) ? 1 : 0)
+extern const u8 msm8x10_wcd_reg_readable[MSM8X10_WCD_CACHE_SIZE];
+extern const u8 msm8x10_wcd_reset_reg_defaults[MSM8X10_WCD_CACHE_SIZE];
+struct msm8x10_wcd_codec_dai_data {
+	u32 rate;
+	u32 *ch_num;
+	u32 ch_act;
+	u32 ch_tot;
+};
+
+enum msm8x10_wcd_pid_current {
+	MSM8X10_WCD_PID_MIC_2P5_UA,
+	MSM8X10_WCD_PID_MIC_5_UA,
+	MSM8X10_WCD_PID_MIC_10_UA,
+	MSM8X10_WCD_PID_MIC_20_UA,
+};
+
+struct msm8x10_wcd_reg_mask_val {
+	u16	reg;
+	u8	mask;
+	u8	val;
+};
+
+enum msm8x10_wcd_mbhc_analog_pwr_cfg {
+	MSM8X10_WCD_ANALOG_PWR_COLLAPSED = 0,
+	MSM8X10_WCD_ANALOG_PWR_ON,
+	MSM8X10_WCD_NUM_ANALOG_PWR_CONFIGS,
+};
+
+/* Number of input and output Slimbus port */
+enum {
+	MSM8X10_WCD_RX1 = 0,
+	MSM8X10_WCD_RX2,
+	MSM8X10_WCD_RX3,
+	MSM8X10_WCD_RX_MAX,
+};
+
+enum {
+	MSM8X10_WCD_TX1 = 0,
+	MSM8X10_WCD_TX2,
+	MSM8X10_WCD_TX3,
+	MSM8X10_WCD_TX4,
+	MSM8X10_WCD_TX_MAX,
+};
+
+enum {
+	/* INTR_REG 0 */
+	MSM8X10_WCD_IRQ_RESERVED_0 = 0,
+	MSM8X10_WCD_IRQ_MBHC_REMOVAL,
+	MSM8X10_WCD_IRQ_MBHC_SHORT_TERM,
+	MSM8X10_WCD_IRQ_MBHC_PRESS,
+	MSM8X10_WCD_IRQ_MBHC_RELEASE,
+	MSM8X10_WCD_IRQ_MBHC_POTENTIAL,
+	MSM8X10_WCD_IRQ_MBHC_INSERTION,
+	MSM8X10_WCD_IRQ_MBHC_HS_DET,
+	/* INTR_REG 1 */
+	MSM8X10_WCD_IRQ_PA_STARTUP,
+	MSM8X10_WCD_IRQ_BG_PRECHARGE,
+	MSM8X10_WCD_IRQ_RESERVED_1,
+	MSM8X10_WCD_IRQ_EAR_PA_OCPL_FAULT,
+	MSM8X10_WCD_IRQ_EAR_PA_STARTUP,
+	MSM8X10_WCD_IRQ_SPKR_PA_OCPL_FAULT,
+	MSM8X10_WCD_IRQ_SPKR_CLIP_FAULT,
+	MSM8X10_WCD_IRQ_RESERVED_2,
+	/* INTR_REG 2 */
+	MSM8X10_WCD_IRQ_HPH_L_PA_STARTUP,
+	MSM8X10_WCD_IRQ_HPH_R_PA_STARTUP,
+	MSM8X10_WCD_IRQ_HPH_PA_OCPL_FAULT,
+	MSM8X10_WCD_IRQ_HPH_PA_OCPR_FAULT,
+	MSM8X10_WCD_IRQ_RESERVED_3,
+	MSM8X10_WCD_IRQ_RESERVED_4,
+	MSM8X10_WCD_IRQ_RESERVED_5,
+	MSM8X10_WCD_IRQ_RESERVED_6,
+	MSM8X10_WCD_NUM_IRQS,
+};
+
+/*
+ * Each micbias can be assigned to one of three cfilters
+ * Vbatt_min >= .15V + ldoh_v
+ * ldoh_v >= .15v + cfiltx_mv
+ * If ldoh_v = 1.95 160 mv < cfiltx_mv < 1800 mv
+ * If ldoh_v = 2.35 200 mv < cfiltx_mv < 2200 mv
+ * If ldoh_v = 2.75 240 mv < cfiltx_mv < 2600 mv
+ * If ldoh_v = 2.85 250 mv < cfiltx_mv < 2700 mv
+ */
+struct msm8x10_wcd_micbias_setting {
+	u8 ldoh_v;
+	u32 cfilt1_mv; /* in mv */
+	/*
+	 * Different WCD9xxx series codecs may not
+	 * have 4 mic biases. If a codec has fewer
+	 * mic biases, some of these properties will
+	 * not be used.
+	 */
+	u8 bias1_cfilt_sel;
+	u8 bias1_cap_mode;
+};
+
+struct msm8x10_wcd_ocp_setting {
+	unsigned int	use_pdata:1; /* 0 - use sys default as recommended */
+	unsigned int	num_attempts:4; /* up to 15 attempts */
+	unsigned int	run_time:4; /* in duty cycle */
+	unsigned int	wait_time:4; /* in duty cycle */
+	unsigned int	hph_ocp_limit:3; /* Headphone OCP current limit */
+};
+
+struct msm8x10_wcd_regulator {
+	const char *name;
+	int min_uV;
+	int max_uV;
+	int optimum_uA;
+	struct regulator *regulator;
+};
+
+struct msm8x10_wcd_pdata {
+	int irq;
+	int irq_base;
+	int num_irqs;
+	int reset_gpio;
+	void *msm8x10_wcd_ahb_base_vaddr;
+	struct msm8x10_wcd_micbias_setting micbias;
+	struct msm8x10_wcd_ocp_setting ocp;
+	struct msm8x10_wcd_regulator regulator[MAX_REGULATOR];
+	u32 mclk_rate;
+};
+
+enum msm8x10_wcd_micbias_num {
+	MSM8X10_WCD_MICBIAS1 = 0,
+};
+
+struct msm8x10_wcd_mbhc_config {
+	struct snd_soc_jack *headset_jack;
+	struct snd_soc_jack *button_jack;
+	bool read_fw_bin;
+	/*
+	 * void* calibration contains:
+	 *  struct msm8x10_wcd_mbhc_general_cfg generic;
+	 *  struct msm8x10_wcd_mbhc_plug_detect_cfg plug_det;
+	 *  struct msm8x10_wcd_mbhc_plug_type_cfg plug_type;
+	 *  struct msm8x10_wcd_mbhc_btn_detect_cfg btn_det;
+	 *  struct msm8x10_wcd_mbhc_imped_detect_cfg imped_det;
+	 * Note: various size depends on btn_det->num_btn
+	 */
+	void *calibration;
+	enum msm8x10_wcd_micbias_num micbias;
+	int (*mclk_cb_fn) (struct snd_soc_codec*, int, bool);
+	unsigned int mclk_rate;
+	unsigned int gpio;
+	unsigned int gpio_irq;
+	int gpio_level_insert;
+	bool detect_extn_cable;
+	/* swap_gnd_mic returns true if extern GND/MIC swap switch toggled */
+	bool (*swap_gnd_mic) (struct snd_soc_codec *);
+};
+
+enum msm8x10_wcd_pm_state {
+	MSM8X10_WCD_PM_SLEEPABLE,
+	MSM8X10_WCD_PM_AWAKE,
+	MSM8X10_WCD_PM_ASLEEP,
+};
+
+struct msm8x10_wcd {
+	struct device *dev;
+	struct mutex io_lock;
+	struct mutex xfer_lock;
+	struct mutex irq_lock;
+	u8 version;
+
+	int reset_gpio;
+	int (*read_dev)(struct msm8x10_wcd *msm8x10,
+			unsigned short reg, unsigned int *val);
+	int (*write_dev)(struct msm8x10_wcd *msm8x10,
+			 unsigned short reg, unsigned int val);
+
+	u32 num_of_supplies;
+	struct regulator_bulk_data *supplies;
+
+	enum msm8x10_wcd_pm_state pm_state;
+	struct mutex pm_lock;
+	/* pm_wq notifies change of pm_state */
+	wait_queue_head_t pm_wq;
+	struct pm_qos_request pm_qos_req;
+	int wlock_holders;
+
+	u8 idbyte[4];
+
+	unsigned int irq_base;
+	unsigned int irq;
+	u8 irq_masks_cur[MSM8X10_WCD_NUM_IRQ_REGS];
+	u8 irq_masks_cache[MSM8X10_WCD_NUM_IRQ_REGS];
+	bool irq_level_high[MSM8X10_WCD_NUM_IRQS];
+	int num_irqs;
+	u32 mclk_rate;
+};
+
+extern int msm8x10_wcd_mclk_enable(struct snd_soc_codec *codec, int mclk_enable,
+			     bool dapm);
+extern int msm8x10_wcd_hs_detect(struct snd_soc_codec *codec,
+			   struct msm8x10_wcd_mbhc_config *mbhc_cfg);
+
+#endif
diff --git a/sound/soc/codecs/msm8x10_wcd_registers.h b/sound/soc/codecs/msm8x10_wcd_registers.h
new file mode 100644
index 0000000..a10f31f
--- /dev/null
+++ b/sound/soc/codecs/msm8x10_wcd_registers.h
@@ -0,0 +1,641 @@
+ /* 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 MSM8X10_WCD_REGISTERS_H
+#define MSM8X10_WCD_REGISTERS_H
+
+#define MSM8X10_WCD_A_CHIP_CTL			(0x000)
+#define MSM8X10_WCD_A_CHIP_CTL__POR				(0x04)
+#define MSM8X10_WCD_A_CHIP_STATUS			(0x001)
+#define MSM8X10_WCD_A_CHIP_STATUS__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_TLMM_MODE_SELECT			(0x002)
+#define MSM8X10_WCD_A_CDC_TLMM_MODE_SELECT__POR				(0x00)
+#define MSM8X10_WCD_A_MODE_LOCK			(0x003)
+#define MSM8X10_WCD_A_MODE_LOCK__POR				(0x00)
+#define MSM8X10_WCD_A_CHIP_ID_BYTE_0			(0x004)
+#define MSM8X10_WCD_A_CHIP_ID_BYTE_0__POR				(0x00)
+#define MSM8X10_WCD_A_CHIP_ID_BYTE_1			(0x005)
+#define MSM8X10_WCD_A_CHIP_ID_BYTE_1__POR				(0x00)
+#define MSM8X10_WCD_A_CHIP_ID_BYTE_2			(0x006)
+#define MSM8X10_WCD_A_CHIP_ID_BYTE_2__POR				(0x04)
+#define MSM8X10_WCD_A_CHIP_ID_BYTE_3			(0x007)
+#define MSM8X10_WCD_A_CHIP_ID_BYTE_3__POR				(0x01)
+#define MSM8X10_WCD_A_CHIP_VERSION			(0x008)
+#define MSM8X10_WCD_A_CHIP_VERSION__POR				(0x00)
+#define MSM8X10_WCD_A_ANALOG_SLAVE_ID			(0x00C)
+#define MSM8X10_WCD_A_ANALOG_SLAVE_ID__POR				(0x77)
+#define MSM8X10_WCD_A_PIN_CTL_OE			(0x010)
+#define MSM8X10_WCD_A_PIN_CTL_OE__POR				(0x07)
+#define MSM8X10_WCD_A_PIN_CTL_DATA			(0x012)
+#define MSM8X10_WCD_A_PIN_CTL_DATA__POR				(0x00)
+#define MSM8X10_WCD_A_PIN_STATUS			(0x014)
+#define MSM8X10_WCD_A_PIN_STATUS__POR				(0x00)
+#define MSM8X10_WCD_A_HDRIVE_CTL			(0x018)
+#define MSM8X10_WCD_A_HDRIVE_CTL__POR				(0x01)
+#define MSM8X10_WCD_A_HDRIVE_I2C_CTL			(0x019)
+#define MSM8X10_WCD_A_HDRIVE_I2C_CTL__POR				(0x01)
+#define MSM8X10_WCD_A_CDC_RST_CTL			(0x020)
+#define MSM8X10_WCD_A_CDC_RST_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_TOP_CLK_CTL			(0x022)
+#define MSM8X10_WCD_A_CDC_TOP_CLK_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_ANA_CLK_CTL			(0x023)
+#define MSM8X10_WCD_A_CDC_ANA_CLK_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_DIG_CLK_CTL			(0x024)
+#define MSM8X10_WCD_A_CDC_DIG_CLK_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_PROCESS_MONITOR_CTL0			(0x030)
+#define MSM8X10_WCD_A_PROCESS_MONITOR_CTL0__POR				(0x80)
+#define MSM8X10_WCD_A_PROCESS_MONITOR_CTL1			(0x031)
+#define MSM8X10_WCD_A_PROCESS_MONITOR_CTL1__POR				(0x00)
+#define MSM8X10_WCD_A_PROCESS_MONITOR_CTL2			(0x032)
+#define MSM8X10_WCD_A_PROCESS_MONITOR_CTL2__POR				(0x00)
+#define MSM8X10_WCD_A_PROCESS_MONITOR_CTL3			(0x033)
+#define MSM8X10_WCD_A_PROCESS_MONITOR_CTL3__POR				(0x01)
+#define MSM8X10_WCD_A_QFUSE_CTL			(0x034)
+#define MSM8X10_WCD_A_QFUSE_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_QFUSE_STATUS			(0x035)
+#define MSM8X10_WCD_A_QFUSE_STATUS__POR				(0x00)
+#define MSM8X10_WCD_A_QFUSE_DATA_OUT0			(0x036)
+#define MSM8X10_WCD_A_QFUSE_DATA_OUT0__POR				(0x00)
+#define MSM8X10_WCD_A_QFUSE_DATA_OUT1			(0x037)
+#define MSM8X10_WCD_A_QFUSE_DATA_OUT1__POR				(0x00)
+#define MSM8X10_WCD_A_QFUSE_DATA_OUT2			(0x038)
+#define MSM8X10_WCD_A_QFUSE_DATA_OUT2__POR				(0x00)
+#define MSM8X10_WCD_A_QFUSE_DATA_OUT3			(0x039)
+#define MSM8X10_WCD_A_QFUSE_DATA_OUT3__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CONN_TX1_CTL			(0x040)
+#define MSM8X10_WCD_A_CDC_CONN_TX1_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CONN_TX2_CTL			(0x041)
+#define MSM8X10_WCD_A_CDC_CONN_TX2_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CONN_HPHR_DAC_CTL			(0x042)
+#define MSM8X10_WCD_A_CDC_CONN_HPHR_DAC_CTL__POR			(0x01)
+#define MSM8X10_WCD_A_CDC_CONN_LO_DAC_CTL			(0x043)
+#define MSM8X10_WCD_A_CDC_CONN_LO_DAC_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CONN_RX1_CTL			(0x044)
+#define MSM8X10_WCD_A_CDC_CONN_RX1_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CONN_RX2_CTL			(0x045)
+#define MSM8X10_WCD_A_CDC_CONN_RX2_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CONN_RX3_CTL			(0x046)
+#define MSM8X10_WCD_A_CDC_CONN_RX3_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_DIGITAL_DEBUG_CTL			(0x048)
+#define MSM8X10_WCD_A_DIGITAL_DEBUG_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_ANALOG_DEBUG_CTL			(0x049)
+#define MSM8X10_WCD_A_ANALOG_DEBUG_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_RX1_CTL			(0x050)
+#define MSM8X10_WCD_A_CDC_RX1_CTL__POR				(0x7C)
+#define MSM8X10_WCD_A_CDC_RX2_CTL			(0x058)
+#define MSM8X10_WCD_A_CDC_RX2_CTL__POR				(0x7C)
+#define MSM8X10_WCD_A_CDC_RX3_CTL			(0x060)
+#define MSM8X10_WCD_A_CDC_RX3_CTL__POR				(0x7C)
+#define MSM8X10_WCD_A_DEM_BYPASS_DATA0			(0x070)
+#define MSM8X10_WCD_A_DEM_BYPASS_DATA0__POR				(0x00)
+#define MSM8X10_WCD_A_DEM_BYPASS_DATA1			(0x071)
+#define MSM8X10_WCD_A_DEM_BYPASS_DATA1__POR				(0x00)
+#define MSM8X10_WCD_A_DEM_BYPASS_DATA2			(0x072)
+#define MSM8X10_WCD_A_DEM_BYPASS_DATA2__POR				(0x00)
+#define MSM8X10_WCD_A_DEM_BYPASS_DATA3			(0x073)
+#define MSM8X10_WCD_A_DEM_BYPASS_DATA3__POR				(0x00)
+#define MSM8X10_WCD_A_SPARE_0			(0x080)
+#define MSM8X10_WCD_A_SPARE_0__POR				(0x00)
+#define MSM8X10_WCD_A_SPARE_1			(0x082)
+#define MSM8X10_WCD_A_SPARE_1__POR				(0x00)
+#define MSM8X10_WCD_A_SPARE_2			(0x084)
+#define MSM8X10_WCD_A_SPARE_2__POR				(0x00)
+#define MSM8X10_WCD_A_INTR_MODE			(0x090)
+#define MSM8X10_WCD_A_INTR_MODE__POR				(0x00)
+#define MSM8X10_WCD_A_INTR_MASK0			(0x094)
+#define MSM8X10_WCD_A_INTR_MASK0__POR				(0xFF)
+#define MSM8X10_WCD_A_INTR_MASK1			(0x095)
+#define MSM8X10_WCD_A_INTR_MASK1__POR				(0xFF)
+#define MSM8X10_WCD_A_INTR_MASK2			(0x096)
+#define MSM8X10_WCD_A_INTR_MASK2__POR				(0x3F)
+#define MSM8X10_WCD_A_INTR_STATUS0			(0x098)
+#define MSM8X10_WCD_A_INTR_STATUS0__POR				(0x00)
+#define MSM8X10_WCD_A_INTR_STATUS1			(0x099)
+#define MSM8X10_WCD_A_INTR_STATUS1__POR				(0x00)
+#define MSM8X10_WCD_A_INTR_STATUS2			(0x09A)
+#define MSM8X10_WCD_A_INTR_STATUS2__POR				(0x00)
+#define MSM8X10_WCD_A_INTR_CLEAR0			(0x09C)
+#define MSM8X10_WCD_A_INTR_CLEAR0__POR				(0x00)
+#define MSM8X10_WCD_A_INTR_CLEAR1			(0x09D)
+#define MSM8X10_WCD_A_INTR_CLEAR1__POR				(0x00)
+#define MSM8X10_WCD_A_INTR_CLEAR2			(0x09E)
+#define MSM8X10_WCD_A_INTR_CLEAR2__POR				(0x00)
+#define MSM8X10_WCD_A_INTR_TEST0			(0x0A4)
+#define MSM8X10_WCD_A_INTR_TEST0__POR				(0x00)
+#define MSM8X10_WCD_A_INTR_TEST1			(0x0A5)
+#define MSM8X10_WCD_A_INTR_TEST1__POR				(0x00)
+#define MSM8X10_WCD_A_INTR_TEST2			(0x0A6)
+#define MSM8X10_WCD_A_INTR_TEST2__POR				(0x00)
+#define MSM8X10_WCD_A_INTR_SET0			(0x0A8)
+#define MSM8X10_WCD_A_INTR_SET0__POR				(0x00)
+#define MSM8X10_WCD_A_INTR_SET1			(0x0A9)
+#define MSM8X10_WCD_A_INTR_SET1__POR				(0x00)
+#define MSM8X10_WCD_A_INTR_SET2			(0x0AA)
+#define MSM8X10_WCD_A_INTR_SET2__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_EN_CTL			(0x0C0)
+#define MSM8X10_WCD_A_CDC_MBHC_EN_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_FIR_B1_CFG			(0x0C1)
+#define MSM8X10_WCD_A_CDC_MBHC_FIR_B1_CFG__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_FIR_B2_CFG			(0x0C2)
+#define MSM8X10_WCD_A_CDC_MBHC_FIR_B2_CFG__POR				(0x06)
+#define MSM8X10_WCD_A_CDC_MBHC_TIMER_B1_CTL			(0x0C3)
+#define MSM8X10_WCD_A_CDC_MBHC_TIMER_B1_CTL__POR			(0x03)
+#define MSM8X10_WCD_A_CDC_MBHC_TIMER_B2_CTL			(0x0C4)
+#define MSM8X10_WCD_A_CDC_MBHC_TIMER_B2_CTL__POR			(0x09)
+#define MSM8X10_WCD_A_CDC_MBHC_TIMER_B3_CTL			(0x0C5)
+#define MSM8X10_WCD_A_CDC_MBHC_TIMER_B3_CTL__POR			(0x1E)
+#define MSM8X10_WCD_A_CDC_MBHC_TIMER_B4_CTL			(0x0C6)
+#define MSM8X10_WCD_A_CDC_MBHC_TIMER_B4_CTL__POR			(0x45)
+#define MSM8X10_WCD_A_CDC_MBHC_TIMER_B5_CTL			(0x0C7)
+#define MSM8X10_WCD_A_CDC_MBHC_TIMER_B5_CTL__POR			(0x04)
+#define MSM8X10_WCD_A_CDC_MBHC_TIMER_B6_CTL			(0x0C8)
+#define MSM8X10_WCD_A_CDC_MBHC_TIMER_B6_CTL__POR			(0x78)
+#define MSM8X10_WCD_A_CDC_MBHC_B1_STATUS			(0x0C9)
+#define MSM8X10_WCD_A_CDC_MBHC_B1_STATUS__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_B2_STATUS			(0x0CA)
+#define MSM8X10_WCD_A_CDC_MBHC_B2_STATUS__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_B3_STATUS			(0x0CB)
+#define MSM8X10_WCD_A_CDC_MBHC_B3_STATUS__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_B4_STATUS			(0x0CC)
+#define MSM8X10_WCD_A_CDC_MBHC_B4_STATUS__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_B5_STATUS			(0x0CD)
+#define MSM8X10_WCD_A_CDC_MBHC_B5_STATUS__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_B1_CTL			(0x0CE)
+#define MSM8X10_WCD_A_CDC_MBHC_B1_CTL__POR				(0xC0)
+#define MSM8X10_WCD_A_CDC_MBHC_B2_CTL			(0x0CF)
+#define MSM8X10_WCD_A_CDC_MBHC_B2_CTL__POR				(0x5D)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B1_CTL			(0x0D0)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B1_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B2_CTL			(0x0D1)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B2_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B3_CTL			(0x0D2)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B3_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B4_CTL			(0x0D3)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B4_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B5_CTL			(0x0D4)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B5_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B6_CTL			(0x0D5)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B6_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B7_CTL			(0x0D6)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B7_CTL__POR				(0xFF)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B8_CTL			(0x0D7)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B8_CTL__POR				(0x07)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B9_CTL			(0x0D8)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B9_CTL__POR				(0xFF)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B10_CTL			(0x0D9)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B10_CTL__POR			(0x7F)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B11_CTL			(0x0DA)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B11_CTL__POR			(0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B12_CTL			(0x0DB)
+#define MSM8X10_WCD_A_CDC_MBHC_VOLT_B12_CTL__POR			(0x80)
+#define MSM8X10_WCD_A_CDC_MBHC_CLK_CTL			(0x0DC)
+#define MSM8X10_WCD_A_CDC_MBHC_CLK_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_INT_CTL			(0x0DD)
+#define MSM8X10_WCD_A_CDC_MBHC_INT_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_DEBUG_CTL			(0x0DE)
+#define MSM8X10_WCD_A_CDC_MBHC_DEBUG_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_MBHC_SPARE			(0x0DF)
+#define MSM8X10_WCD_A_CDC_MBHC_SPARE__POR				(0x00)
+#define MSM8X10_WCD_A_BIAS_REF_CTL			(0x100)
+#define MSM8X10_WCD_A_BIAS_REF_CTL__POR				(0x1C)
+#define MSM8X10_WCD_A_BIAS_CENTRAL_BG_CTL			(0x101)
+#define MSM8X10_WCD_A_BIAS_CENTRAL_BG_CTL__POR				(0x50)
+#define MSM8X10_WCD_A_BIAS_PRECHRG_CTL			(0x102)
+#define MSM8X10_WCD_A_BIAS_PRECHRG_CTL__POR				(0x07)
+#define MSM8X10_WCD_A_BIAS_CURR_CTL_1			(0x103)
+#define MSM8X10_WCD_A_BIAS_CURR_CTL_1__POR				(0x52)
+#define MSM8X10_WCD_A_BIAS_CURR_CTL_2			(0x104)
+#define MSM8X10_WCD_A_BIAS_CURR_CTL_2__POR				(0x00)
+#define MSM8X10_WCD_A_BIAS_OSC_BG_CTL			(0x105)
+#define MSM8X10_WCD_A_BIAS_OSC_BG_CTL__POR				(0x16)
+#define MSM8X10_WCD_A_MICB_CFILT_1_CTL			(0x128)
+#define MSM8X10_WCD_A_MICB_CFILT_1_CTL__POR				(0x40)
+#define MSM8X10_WCD_A_MICB_CFILT_1_VAL			(0x129)
+#define MSM8X10_WCD_A_MICB_CFILT_1_VAL__POR				(0x80)
+#define MSM8X10_WCD_A_MICB_CFILT_1_PRECHRG			(0x12A)
+#define MSM8X10_WCD_A_MICB_CFILT_1_PRECHRG__POR				(0x00)
+#define MSM8X10_WCD_A_MICB_1_CTL			(0x12B)
+#define MSM8X10_WCD_A_MICB_1_CTL__POR				(0x02)
+#define MSM8X10_WCD_A_MICB_1_INT_RBIAS			(0x12C)
+#define MSM8X10_WCD_A_MICB_1_INT_RBIAS__POR				(0x00)
+#define MSM8X10_WCD_A_MICB_1_MBHC			(0x12D)
+#define MSM8X10_WCD_A_MICB_1_MBHC__POR				(0x00)
+#define MSM8X10_WCD_A_MBHC_INSERT_DETECT			(0x14A)
+#define MSM8X10_WCD_A_MBHC_INSERT_DETECT__POR				(0x00)
+#define MSM8X10_WCD_A_MBHC_INSERT_DET_STATUS			(0x14B)
+#define MSM8X10_WCD_A_MBHC_INSERT_DET_STATUS__POR			(0x00)
+#define MSM8X10_WCD_A_TX_COM_BIAS			(0x14C)
+#define MSM8X10_WCD_A_TX_COM_BIAS__POR				(0xF0)
+#define MSM8X10_WCD_A_MBHC_SCALING_MUX_1			(0x14E)
+#define MSM8X10_WCD_A_MBHC_SCALING_MUX_1__POR				(0x00)
+#define MSM8X10_WCD_A_MBHC_SCALING_MUX_2			(0x14F)
+#define MSM8X10_WCD_A_MBHC_SCALING_MUX_2__POR				(0x80)
+#define MSM8X10_WCD_A_RESERVED_MAD_ANA_CTRL			(0x150)
+#define MSM8X10_WCD_A_RESERVED_MAD_ANA_CTRL__POR			(0xF1)
+#define MSM8X10_WCD_A_TX_SUP_SWITCH_CTRL_1			(0x151)
+#define MSM8X10_WCD_A_TX_SUP_SWITCH_CTRL_1__POR				(0x00)
+#define MSM8X10_WCD_A_TX_SUP_SWITCH_CTRL_2			(0x152)
+#define MSM8X10_WCD_A_TX_SUP_SWITCH_CTRL_2__POR				(0x80)
+#define MSM8X10_WCD_A_TX_1_EN			(0x153)
+#define MSM8X10_WCD_A_TX_1_EN__POR				(0x02)
+#define MSM8X10_WCD_A_TX_2_EN			(0x154)
+#define MSM8X10_WCD_A_TX_2_EN__POR				(0x02)
+#define MSM8X10_WCD_A_TX_1_2_ADC_CH1			(0x155)
+#define MSM8X10_WCD_A_TX_1_2_ADC_CH1__POR				(0x44)
+#define MSM8X10_WCD_A_TX_1_2_ADC_CH2			(0x156)
+#define MSM8X10_WCD_A_TX_1_2_ADC_CH2__POR				(0x44)
+#define MSM8X10_WCD_A_TX_1_2_ATEST_REFCTRL			(0x157)
+#define MSM8X10_WCD_A_TX_1_2_ATEST_REFCTRL__POR				(0x00)
+#define MSM8X10_WCD_A_TX_1_2_TEST_CTL			(0x158)
+#define MSM8X10_WCD_A_TX_1_2_TEST_CTL__POR				(0x38)
+#define MSM8X10_WCD_A_TX_1_2_TEST_BLOCK_EN			(0x159)
+#define MSM8X10_WCD_A_TX_1_2_TEST_BLOCK_EN__POR				(0xFC)
+#define MSM8X10_WCD_A_TX_1_2_TXFE_CLKDIV			(0x15A)
+#define MSM8X10_WCD_A_TX_1_2_TXFE_CLKDIV__POR				(0x55)
+#define MSM8X10_WCD_A_TX_1_2_SAR_ERR_CH1			(0x15B)
+#define MSM8X10_WCD_A_TX_1_2_SAR_ERR_CH1__POR				(0x00)
+#define MSM8X10_WCD_A_TX_1_2_SAR_ERR_CH2			(0x15C)
+#define MSM8X10_WCD_A_TX_1_2_SAR_ERR_CH2__POR				(0x00)
+#define MSM8X10_WCD_A_TX_3_EN			(0x15D)
+#define MSM8X10_WCD_A_TX_3_EN__POR				(0x00)
+#define MSM8X10_WCD_A_TX_1_2_TEST_EN			(0x15E)
+#define MSM8X10_WCD_A_TX_1_2_TEST_EN__POR				(0xCC)
+#define MSM8X10_WCD_A_TX_7_MBHC_EN_ATEST_CTRL			(0x171)
+#define MSM8X10_WCD_A_TX_7_MBHC_EN_ATEST_CTRL__POR			(0x10)
+#define MSM8X10_WCD_A_TX_7_MBHC_SAR_ERR			(0x175)
+#define MSM8X10_WCD_A_TX_7_MBHC_SAR_ERR__POR				(0x00)
+#define MSM8X10_WCD_A_CP_EN			(0x192)
+#define MSM8X10_WCD_A_CP_EN__POR				(0xE6)
+#define MSM8X10_WCD_A_CP_CLK			(0x193)
+#define MSM8X10_WCD_A_CP_CLK__POR				(0x29)
+#define MSM8X10_WCD_A_CP_STATIC			(0x194)
+#define MSM8X10_WCD_A_CP_STATIC__POR				(0x10)
+#define MSM8X10_WCD_A_CP_DCC1			(0x195)
+#define MSM8X10_WCD_A_CP_DCC1__POR				(0x52)
+#define MSM8X10_WCD_A_CP_DCC3			(0x196)
+#define MSM8X10_WCD_A_CP_DCC3__POR				(0x01)
+#define MSM8X10_WCD_A_CP_ATEST			(0x197)
+#define MSM8X10_WCD_A_CP_ATEST__POR				(0x00)
+#define MSM8X10_WCD_A_CP_DTEST			(0x198)
+#define MSM8X10_WCD_A_CP_DTEST__POR				(0x00)
+#define MSM8X10_WCD_A_RX_AUX_SW_CTL			(0x19B)
+#define MSM8X10_WCD_A_RX_AUX_SW_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_RX_PA_AUX_IN_CONN			(0x19C)
+#define MSM8X10_WCD_A_RX_PA_AUX_IN_CONN__POR				(0x00)
+#define MSM8X10_WCD_A_RX_COM_TIMER_DIV			(0x19E)
+#define MSM8X10_WCD_A_RX_COM_TIMER_DIV__POR				(0xE8)
+#define MSM8X10_WCD_A_RX_COM_OCP_CTL			(0x19F)
+#define MSM8X10_WCD_A_RX_COM_OCP_CTL__POR				(0x1F)
+#define MSM8X10_WCD_A_RX_COM_OCP_COUNT			(0x1A0)
+#define MSM8X10_WCD_A_RX_COM_OCP_COUNT__POR				(0x77)
+#define MSM8X10_WCD_A_RX_COM_DAC_CTL			(0x1A1)
+#define MSM8X10_WCD_A_RX_COM_DAC_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_RX_COM_BIAS			(0x1A2)
+#define MSM8X10_WCD_A_RX_COM_BIAS__POR				(0x00)
+#define MSM8X10_WCD_A_RX_HPH_AUTO_CHOP			(0x1A4)
+#define MSM8X10_WCD_A_RX_HPH_AUTO_CHOP__POR				(0x38)
+#define MSM8X10_WCD_A_RX_HPH_CHOP_CTL			(0x1A5)
+#define MSM8X10_WCD_A_RX_HPH_CHOP_CTL__POR				(0x34)
+#define MSM8X10_WCD_A_RX_HPH_BIAS_PA			(0x1A6)
+#define MSM8X10_WCD_A_RX_HPH_BIAS_PA__POR				(0x5A)
+#define MSM8X10_WCD_A_RX_HPH_BIAS_LDO			(0x1A7)
+#define MSM8X10_WCD_A_RX_HPH_BIAS_LDO__POR				(0x87)
+#define MSM8X10_WCD_A_RX_HPH_BIAS_CNP			(0x1A8)
+#define MSM8X10_WCD_A_RX_HPH_BIAS_CNP__POR				(0x8A)
+#define MSM8X10_WCD_A_RX_HPH_BIAS_WG_OCP			(0x1A9)
+#define MSM8X10_WCD_A_RX_HPH_BIAS_WG_OCP__POR				(0x2A)
+#define MSM8X10_WCD_A_RX_HPH_OCP_CTL			(0x1AA)
+#define MSM8X10_WCD_A_RX_HPH_OCP_CTL__POR				(0x69)
+#define MSM8X10_WCD_A_RX_HPH_CNP_EN			(0x1AB)
+#define MSM8X10_WCD_A_RX_HPH_CNP_EN__POR				(0x80)
+#define MSM8X10_WCD_A_RX_HPH_CNP_WG_CTL			(0x1AC)
+#define MSM8X10_WCD_A_RX_HPH_CNP_WG_CTL__POR				(0xDE)
+#define MSM8X10_WCD_A_RX_HPH_CNP_WG_TIME			(0x1AD)
+#define MSM8X10_WCD_A_RX_HPH_CNP_WG_TIME__POR				(0x15)
+#define MSM8X10_WCD_A_RX_HPH_L_GAIN			(0x1AE)
+#define MSM8X10_WCD_A_RX_HPH_L_GAIN__POR				(0x00)
+#define MSM8X10_WCD_A_RX_HPH_L_TEST			(0x1AF)
+#define MSM8X10_WCD_A_RX_HPH_L_TEST__POR				(0x00)
+#define MSM8X10_WCD_A_RX_HPH_L_PA_CTL			(0x1B0)
+#define MSM8X10_WCD_A_RX_HPH_L_PA_CTL__POR				(0x40)
+#define MSM8X10_WCD_A_RX_HPH_L_DAC_CTL			(0x1B1)
+#define MSM8X10_WCD_A_RX_HPH_L_DAC_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_RX_HPH_L_ATEST			(0x1B2)
+#define MSM8X10_WCD_A_RX_HPH_L_ATEST__POR				(0x00)
+#define MSM8X10_WCD_A_RX_HPH_L_STATUS			(0x1B3)
+#define MSM8X10_WCD_A_RX_HPH_L_STATUS__POR				(0x00)
+#define MSM8X10_WCD_A_RX_HPH_R_GAIN			(0x1B4)
+#define MSM8X10_WCD_A_RX_HPH_R_GAIN__POR				(0x00)
+#define MSM8X10_WCD_A_RX_HPH_R_TEST			(0x1B5)
+#define MSM8X10_WCD_A_RX_HPH_R_TEST__POR				(0x00)
+#define MSM8X10_WCD_A_RX_HPH_R_PA_CTL			(0x1B6)
+#define MSM8X10_WCD_A_RX_HPH_R_PA_CTL__POR				(0x40)
+#define MSM8X10_WCD_A_RX_HPH_R_DAC_CTL			(0x1B7)
+#define MSM8X10_WCD_A_RX_HPH_R_DAC_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_RX_HPH_R_ATEST			(0x1B8)
+#define MSM8X10_WCD_A_RX_HPH_R_ATEST__POR				(0x00)
+#define MSM8X10_WCD_A_RX_HPH_R_STATUS			(0x1B9)
+#define MSM8X10_WCD_A_RX_HPH_R_STATUS__POR				(0x00)
+#define MSM8X10_WCD_A_RX_EAR_BIAS_PA			(0x1BA)
+#define MSM8X10_WCD_A_RX_EAR_BIAS_PA__POR				(0x56)
+#define MSM8X10_WCD_A_RX_EAR_BIAS_CMBUFF			(0x1BB)
+#define MSM8X10_WCD_A_RX_EAR_BIAS_CMBUFF__POR				(0xA0)
+#define MSM8X10_WCD_A_RX_EAR_EN			(0x1BC)
+#define MSM8X10_WCD_A_RX_EAR_EN__POR				(0x00)
+#define MSM8X10_WCD_A_RX_EAR_GAIN			(0x1BD)
+#define MSM8X10_WCD_A_RX_EAR_GAIN__POR				(0x02)
+#define MSM8X10_WCD_A_RX_EAR_CMBUFF			(0x1BE)
+#define MSM8X10_WCD_A_RX_EAR_CMBUFF__POR				(0x05)
+#define MSM8X10_WCD_A_RX_EAR_ICTL			(0x1BF)
+#define MSM8X10_WCD_A_RX_EAR_ICTL__POR				(0x40)
+#define MSM8X10_WCD_A_RX_EAR_CCOMP			(0x1C0)
+#define MSM8X10_WCD_A_RX_EAR_CCOMP__POR				(0x08)
+#define MSM8X10_WCD_A_RX_EAR_VCM			(0x1C1)
+#define MSM8X10_WCD_A_RX_EAR_VCM__POR				(0x03)
+#define MSM8X10_WCD_A_RX_EAR_CNP			(0x1C2)
+#define MSM8X10_WCD_A_RX_EAR_CNP__POR				(0xF2)
+#define MSM8X10_WCD_A_RX_EAR_DAC_CTL_ATEST			(0x1C3)
+#define MSM8X10_WCD_A_RX_EAR_DAC_CTL_ATEST__POR				(0x00)
+#define MSM8X10_WCD_A_RX_EAR_STATUS			(0x1C5)
+#define MSM8X10_WCD_A_RX_EAR_STATUS__POR				(0x04)
+#define MSM8X10_WCD_A_RX_LINE_BIAS_PA			(0x1C6)
+#define MSM8X10_WCD_A_RX_LINE_BIAS_PA__POR				(0x58)
+#define MSM8X10_WCD_A_RX_BUCK_BIAS1			(0x1C7)
+#define MSM8X10_WCD_A_RX_BUCK_BIAS1__POR				(0x42)
+#define MSM8X10_WCD_A_RX_BUCK_BIAS2			(0x1C8)
+#define MSM8X10_WCD_A_RX_BUCK_BIAS2__POR				(0x84)
+#define MSM8X10_WCD_A_RX_LINE_COM			(0x1C9)
+#define MSM8X10_WCD_A_RX_LINE_COM__POR				(0x80)
+#define MSM8X10_WCD_A_RX_LINE_CNP_EN			(0x1CA)
+#define MSM8X10_WCD_A_RX_LINE_CNP_EN__POR				(0x00)
+#define MSM8X10_WCD_A_RX_LINE_CNP_WG_CTL			(0x1CB)
+#define MSM8X10_WCD_A_RX_LINE_CNP_WG_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_RX_LINE_CNP_WG_TIME			(0x1CC)
+#define MSM8X10_WCD_A_RX_LINE_CNP_WG_TIME__POR				(0x04)
+#define MSM8X10_WCD_A_RX_LINE_1_GAIN			(0x1CD)
+#define MSM8X10_WCD_A_RX_LINE_1_GAIN__POR				(0x00)
+#define MSM8X10_WCD_A_RX_LINE_1_TEST			(0x1CE)
+#define MSM8X10_WCD_A_RX_LINE_1_TEST__POR				(0x00)
+#define MSM8X10_WCD_A_RX_LINE_1_DAC_CTL			(0x1CF)
+#define MSM8X10_WCD_A_RX_LINE_1_DAC_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_RX_LINE_1_STATUS			(0x1D0)
+#define MSM8X10_WCD_A_RX_LINE_1_STATUS__POR				(0x00)
+#define MSM8X10_WCD_A_RX_LINE_CNP_DBG			(0x1DD)
+#define MSM8X10_WCD_A_RX_LINE_CNP_DBG__POR				(0x00)
+#define MSM8X10_WCD_A_SPKR_DRV_EN			(0x1DF)
+#define MSM8X10_WCD_A_SPKR_DRV_EN__POR				(0x6F)
+#define MSM8X10_WCD_A_SPKR_DRV_GAIN			(0x1E0)
+#define MSM8X10_WCD_A_SPKR_DRV_GAIN__POR				(0x00)
+#define MSM8X10_WCD_A_SPKR_DRV_DAC_CTL			(0x1E1)
+#define MSM8X10_WCD_A_SPKR_DRV_DAC_CTL__POR				(0x04)
+#define MSM8X10_WCD_A_SPKR_DRV_OCP_CTL			(0x1E2)
+#define MSM8X10_WCD_A_SPKR_DRV_OCP_CTL__POR				(0x98)
+#define MSM8X10_WCD_A_SPKR_DRV_CLIP_DET			(0x1E3)
+#define MSM8X10_WCD_A_SPKR_DRV_CLIP_DET__POR				(0x01)
+#define MSM8X10_WCD_A_SPKR_DRV_IEC			(0x1E4)
+#define MSM8X10_WCD_A_SPKR_DRV_IEC__POR				(0x00)
+#define MSM8X10_WCD_A_SPKR_DRV_DBG_DAC			(0x1E5)
+#define MSM8X10_WCD_A_SPKR_DRV_DBG_DAC__POR				(0x05)
+#define MSM8X10_WCD_A_SPKR_DRV_DBG_PA			(0x1E6)
+#define MSM8X10_WCD_A_SPKR_DRV_DBG_PA__POR				(0x18)
+#define MSM8X10_WCD_A_SPKR_DRV_DBG_PWRSTG			(0x1E7)
+#define MSM8X10_WCD_A_SPKR_DRV_DBG_PWRSTG__POR				(0x00)
+#define MSM8X10_WCD_A_SPKR_DRV_BIAS_LDO			(0x1E8)
+#define MSM8X10_WCD_A_SPKR_DRV_BIAS_LDO__POR				(0x45)
+#define MSM8X10_WCD_A_SPKR_DRV_BIAS_INT			(0x1E9)
+#define MSM8X10_WCD_A_SPKR_DRV_BIAS_INT__POR				(0xA5)
+#define MSM8X10_WCD_A_SPKR_DRV_BIAS_PA			(0x1EA)
+#define MSM8X10_WCD_A_SPKR_DRV_BIAS_PA__POR				(0x55)
+#define MSM8X10_WCD_A_SPKR_DRV_STATUS_OCP			(0x1EB)
+#define MSM8X10_WCD_A_SPKR_DRV_STATUS_OCP__POR				(0x00)
+#define MSM8X10_WCD_A_SPKR_DRV_STATUS_PA			(0x1EC)
+#define MSM8X10_WCD_A_SPKR_DRV_STATUS_PA__POR				(0x00)
+#define MSM8X10_WCD_A_RC_OSC_FREQ			(0x1FA)
+#define MSM8X10_WCD_A_RC_OSC_FREQ__POR				(0x46)
+#define MSM8X10_WCD_A_RC_OSC_TEST			(0x1FB)
+#define MSM8X10_WCD_A_RC_OSC_TEST__POR				(0x0A)
+#define MSM8X10_WCD_A_RC_OSC_STATUS			(0x1FC)
+#define MSM8X10_WCD_A_RC_OSC_STATUS__POR				(0x18)
+#define MSM8X10_WCD_A_RC_OSC_TUNER			(0x1FD)
+#define MSM8X10_WCD_A_RC_OSC_TUNER__POR				(0x00)
+#define MSM8X10_WCD_A_MBHC_HPH			(0x1FE)
+#define MSM8X10_WCD_A_MBHC_HPH__POR				(0x44)
+#define MSM8X10_WCD_A_CDC_CLK_RX_RESET_CTL			(0x400)
+#define MSM8X10_WCD_A_CDC_CLK_RX_RESET_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CLK_TX_RESET_B1_CTL			(0x404)
+#define MSM8X10_WCD_A_CDC_CLK_TX_RESET_B1_CTL__POR			(0x00)
+#define MSM8X10_WCD_A_CDC_CLK_DMIC_B1_CTL			(0x408)
+#define MSM8X10_WCD_A_CDC_CLK_DMIC_B1_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CLK_RX_I2S_CTL			(0x40C)
+#define MSM8X10_WCD_A_CDC_CLK_RX_I2S_CTL__POR				(0x10)
+#define MSM8X10_WCD_A_CDC_CLK_TX_I2S_CTL			(0x410)
+#define MSM8X10_WCD_A_CDC_CLK_TX_I2S_CTL__POR				(0x10)
+#define MSM8X10_WCD_A_CDC_CLK_OTHR_RESET_B1_CTL			(0x414)
+#define MSM8X10_WCD_A_CDC_CLK_OTHR_RESET_B1_CTL__POR			(0x00)
+#define MSM8X10_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL			(0x418)
+#define MSM8X10_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL__POR			(0x00)
+#define MSM8X10_WCD_A_CDC_CLK_OTHR_CTL			(0x41C)
+#define MSM8X10_WCD_A_CDC_CLK_OTHR_CTL__POR				(0x04)
+#define MSM8X10_WCD_A_CDC_CLK_RX_B1_CTL			(0x420)
+#define MSM8X10_WCD_A_CDC_CLK_RX_B1_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CLK_MCLK_CTL			(0x424)
+#define MSM8X10_WCD_A_CDC_CLK_MCLK_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CLK_PDM_CTL			(0x428)
+#define MSM8X10_WCD_A_CDC_CLK_PDM_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CLK_SD_CTL			(0x42C)
+#define MSM8X10_WCD_A_CDC_CLK_SD_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_RX1_B1_CTL			(0x440)
+#define MSM8X10_WCD_A_CDC_RX1_B1_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_RX2_B1_CTL			(0x460)
+#define MSM8X10_WCD_A_CDC_RX2_B1_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_RX3_B1_CTL			(0x480)
+#define MSM8X10_WCD_A_CDC_RX3_B1_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_RX1_B2_CTL			(0x444)
+#define MSM8X10_WCD_A_CDC_RX1_B2_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_RX2_B2_CTL			(0x464)
+#define MSM8X10_WCD_A_CDC_RX2_B2_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_RX3_B2_CTL			(0x484)
+#define MSM8X10_WCD_A_CDC_RX3_B2_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_RX1_B3_CTL			(0x448)
+#define MSM8X10_WCD_A_CDC_RX1_B3_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_RX2_B3_CTL			(0x468)
+#define MSM8X10_WCD_A_CDC_RX2_B3_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_RX3_B3_CTL			(0x488)
+#define MSM8X10_WCD_A_CDC_RX3_B3_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_RX1_B4_CTL			(0x44C)
+#define MSM8X10_WCD_A_CDC_RX1_B4_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_RX2_B4_CTL			(0x46C)
+#define MSM8X10_WCD_A_CDC_RX2_B4_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_RX3_B4_CTL			(0x48C)
+#define MSM8X10_WCD_A_CDC_RX3_B4_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_RX1_B5_CTL			(0x450)
+#define MSM8X10_WCD_A_CDC_RX1_B5_CTL__POR				(0x68)
+#define MSM8X10_WCD_A_CDC_RX2_B5_CTL			(0x470)
+#define MSM8X10_WCD_A_CDC_RX2_B5_CTL__POR				(0x68)
+#define MSM8X10_WCD_A_CDC_RX3_B5_CTL			(0x490)
+#define MSM8X10_WCD_A_CDC_RX3_B5_CTL__POR				(0x68)
+#define MSM8X10_WCD_A_CDC_RX1_B6_CTL			(0x454)
+#define MSM8X10_WCD_A_CDC_RX1_B6_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_RX2_B6_CTL			(0x474)
+#define MSM8X10_WCD_A_CDC_RX2_B6_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_RX3_B6_CTL			(0x494)
+#define MSM8X10_WCD_A_CDC_RX3_B6_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_RX1_VOL_CTL_B1_CTL			(0x458)
+#define MSM8X10_WCD_A_CDC_RX1_VOL_CTL_B1_CTL__POR			(0x00)
+#define MSM8X10_WCD_A_CDC_RX2_VOL_CTL_B1_CTL			(0x478)
+#define MSM8X10_WCD_A_CDC_RX2_VOL_CTL_B1_CTL__POR			(0x00)
+#define MSM8X10_WCD_A_CDC_RX3_VOL_CTL_B1_CTL			(0x498)
+#define MSM8X10_WCD_A_CDC_RX3_VOL_CTL_B1_CTL__POR			(0x00)
+#define MSM8X10_WCD_A_CDC_RX1_VOL_CTL_B2_CTL			(0x45C)
+#define MSM8X10_WCD_A_CDC_RX1_VOL_CTL_B2_CTL__POR			(0x00)
+#define MSM8X10_WCD_A_CDC_RX2_VOL_CTL_B2_CTL			(0x47C)
+#define MSM8X10_WCD_A_CDC_RX2_VOL_CTL_B2_CTL__POR			(0x00)
+#define MSM8X10_WCD_A_CDC_RX3_VOL_CTL_B2_CTL			(0x49C)
+#define MSM8X10_WCD_A_CDC_RX3_VOL_CTL_B2_CTL__POR			(0x00)
+#define MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B1_CTL			(0x4A0)
+#define MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B1_CTL__POR			(0x07)
+#define MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B2_CTL			(0x4A4)
+#define MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B2_CTL__POR			(0x13)
+#define MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B3_CTL			(0x4A8)
+#define MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B3_CTL__POR			(0x1B)
+#define MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B4_CTL			(0x4AC)
+#define MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B4_CTL__POR			(0x7F)
+#define MSM8X10_WCD_A_CDC_CLSG_GAIN_THRESH_CTL			(0x4B0)
+#define MSM8X10_WCD_A_CDC_CLSG_GAIN_THRESH_CTL__POR			(0x26)
+#define MSM8X10_WCD_A_CDC_CLSG_TIMER_B1_CFG			(0x4B4)
+#define MSM8X10_WCD_A_CDC_CLSG_TIMER_B1_CFG__POR			(0x0A)
+#define MSM8X10_WCD_A_CDC_CLSG_TIMER_B2_CFG			(0x4B8)
+#define MSM8X10_WCD_A_CDC_CLSG_TIMER_B2_CFG__POR			(0x00)
+#define MSM8X10_WCD_A_CDC_CLSG_CTL			(0x4BC)
+#define MSM8X10_WCD_A_CDC_CLSG_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_TX1_VOL_CTL_TIMER			(0x4C0)
+#define MSM8X10_WCD_A_CDC_TX1_VOL_CTL_TIMER__POR			(0x00)
+#define MSM8X10_WCD_A_CDC_TX2_VOL_CTL_TIMER			(0x4E0)
+#define MSM8X10_WCD_A_CDC_TX2_VOL_CTL_TIMER__POR			(0x00)
+#define MSM8X10_WCD_A_CDC_TX1_VOL_CTL_GAIN			(0x4C4)
+#define MSM8X10_WCD_A_CDC_TX1_VOL_CTL_GAIN__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_TX2_VOL_CTL_GAIN			(0x4E4)
+#define MSM8X10_WCD_A_CDC_TX2_VOL_CTL_GAIN__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_TX1_VOL_CTL_CFG			(0x4C8)
+#define MSM8X10_WCD_A_CDC_TX1_VOL_CTL_CFG__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_TX2_VOL_CTL_CFG			(0x4E8)
+#define MSM8X10_WCD_A_CDC_TX2_VOL_CTL_CFG__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_TX1_MUX_CTL			(0x4CC)
+#define MSM8X10_WCD_A_CDC_TX1_MUX_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_TX2_MUX_CTL			(0x4EC)
+#define MSM8X10_WCD_A_CDC_TX2_MUX_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_TX1_CLK_FS_CTL			(0x4D0)
+#define MSM8X10_WCD_A_CDC_TX1_CLK_FS_CTL__POR				(0x03)
+#define MSM8X10_WCD_A_CDC_TX2_CLK_FS_CTL			(0x4F0)
+#define MSM8X10_WCD_A_CDC_TX2_CLK_FS_CTL__POR				(0x03)
+#define MSM8X10_WCD_A_CDC_TX1_DMIC_CTL			(0x4D4)
+#define MSM8X10_WCD_A_CDC_TX1_DMIC_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_TX2_DMIC_CTL			(0x4F4)
+#define MSM8X10_WCD_A_CDC_TX2_DMIC_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B1_CTL			(0x500)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B1_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B1_CTL			(0x540)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B1_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B2_CTL			(0x504)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B2_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B2_CTL			(0x544)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B2_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B3_CTL			(0x508)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B3_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B3_CTL			(0x548)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B3_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B4_CTL			(0x50C)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B4_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B4_CTL			(0x54C)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B4_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B5_CTL			(0x510)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B5_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B5_CTL			(0x550)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B5_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B6_CTL			(0x514)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B6_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B6_CTL			(0x554)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B6_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B7_CTL			(0x518)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B7_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B7_CTL			(0x558)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B7_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B8_CTL			(0x51C)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_B8_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B8_CTL			(0x55C)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_B8_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_IIR1_CTL			(0x520)
+#define MSM8X10_WCD_A_CDC_IIR1_CTL__POR				(0x40)
+#define MSM8X10_WCD_A_CDC_IIR2_CTL			(0x560)
+#define MSM8X10_WCD_A_CDC_IIR2_CTL__POR				(0x40)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_TIMER_CTL			(0x524)
+#define MSM8X10_WCD_A_CDC_IIR1_GAIN_TIMER_CTL__POR			(0x00)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_TIMER_CTL			(0x564)
+#define MSM8X10_WCD_A_CDC_IIR2_GAIN_TIMER_CTL__POR			(0x00)
+#define MSM8X10_WCD_A_CDC_IIR1_COEF_B1_CTL			(0x528)
+#define MSM8X10_WCD_A_CDC_IIR1_COEF_B1_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_IIR2_COEF_B1_CTL			(0x568)
+#define MSM8X10_WCD_A_CDC_IIR2_COEF_B1_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_IIR1_COEF_B2_CTL			(0x52C)
+#define MSM8X10_WCD_A_CDC_IIR1_COEF_B2_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_IIR2_COEF_B2_CTL			(0x56C)
+#define MSM8X10_WCD_A_CDC_IIR2_COEF_B2_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CONN_RX1_B1_CTL			(0x580)
+#define MSM8X10_WCD_A_CDC_CONN_RX1_B1_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CONN_RX1_B2_CTL			(0x584)
+#define MSM8X10_WCD_A_CDC_CONN_RX1_B2_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CONN_RX1_B3_CTL			(0x588)
+#define MSM8X10_WCD_A_CDC_CONN_RX1_B3_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CONN_RX2_B1_CTL			(0x58C)
+#define MSM8X10_WCD_A_CDC_CONN_RX2_B1_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CONN_RX2_B2_CTL			(0x590)
+#define MSM8X10_WCD_A_CDC_CONN_RX2_B2_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CONN_RX2_B3_CTL			(0x594)
+#define MSM8X10_WCD_A_CDC_CONN_RX2_B3_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CONN_RX3_B1_CTL			(0x598)
+#define MSM8X10_WCD_A_CDC_CONN_RX3_B1_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CONN_RX3_B2_CTL			(0x59C)
+#define MSM8X10_WCD_A_CDC_CONN_RX3_B2_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CONN_TX_B1_CTL			(0x5A4)
+#define MSM8X10_WCD_A_CDC_CONN_TX_B1_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CONN_EQ1_B1_CTL			(0x5A8)
+#define MSM8X10_WCD_A_CDC_CONN_EQ1_B1_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CONN_EQ1_B2_CTL			(0x5AC)
+#define MSM8X10_WCD_A_CDC_CONN_EQ1_B2_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CONN_EQ1_B3_CTL			(0x5B0)
+#define MSM8X10_WCD_A_CDC_CONN_EQ1_B3_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CONN_EQ1_B4_CTL			(0x5B4)
+#define MSM8X10_WCD_A_CDC_CONN_EQ1_B4_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CONN_EQ2_B1_CTL			(0x5B8)
+#define MSM8X10_WCD_A_CDC_CONN_EQ2_B1_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CONN_EQ2_B2_CTL			(0x5BC)
+#define MSM8X10_WCD_A_CDC_CONN_EQ2_B2_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CONN_EQ2_B3_CTL			(0x5C0)
+#define MSM8X10_WCD_A_CDC_CONN_EQ2_B3_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CONN_EQ2_B4_CTL			(0x5C4)
+#define MSM8X10_WCD_A_CDC_CONN_EQ2_B4_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_CONN_TX_I2S_SD1_CTL			(0x5C8)
+#define MSM8X10_WCD_A_CDC_CONN_TX_I2S_SD1_CTL__POR			(0x00)
+#define MSM8X10_WCD_A_CDC_TOP_GAIN_UPDATE			(0x5D0)
+#define MSM8X10_WCD_A_CDC_TOP_GAIN_UPDATE__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_TOP_CTL			(0x5D8)
+#define MSM8X10_WCD_A_CDC_TOP_CTL__POR				(0x01)
+#define MSM8X10_WCD_A_CDC_DEBUG_DESER1_CTL			(0x5E0)
+#define MSM8X10_WCD_A_CDC_DEBUG_DESER1_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_DEBUG_DESER2_CTL			(0x5E4)
+#define MSM8X10_WCD_A_CDC_DEBUG_DESER2_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_DEBUG_B1_CTL			(0x5E8)
+#define MSM8X10_WCD_A_CDC_DEBUG_B1_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_DEBUG_B2_CTL			(0x5EC)
+#define MSM8X10_WCD_A_CDC_DEBUG_B2_CTL__POR				(0x00)
+#define MSM8X10_WCD_A_CDC_DEBUG_B3_CTL			(0x5F0)
+#define MSM8X10_WCD_A_CDC_DEBUG_B3_CTL__POR				(0x00)
+#endif
diff --git a/sound/soc/codecs/msm_hdmi_codec_rx.c b/sound/soc/codecs/msm_hdmi_codec_rx.c
index 0000a1a..46bce9e 100644
--- a/sound/soc/codecs/msm_hdmi_codec_rx.c
+++ b/sound/soc/codecs/msm_hdmi_codec_rx.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
@@ -13,6 +13,7 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/err.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
@@ -25,6 +26,60 @@
 	struct msm_hdmi_audio_codec_ops hdmi_ops;
 };
 
+static int msm_hdmi_edid_ctl_info(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_info *uinfo)
+{
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct msm_hdmi_audio_codec_rx_data *codec_data;
+	struct msm_hdmi_audio_edid_blk edid_blk;
+	int rc;
+
+	codec_data = snd_soc_codec_get_drvdata(codec);
+	rc = codec_data->hdmi_ops.get_audio_edid_blk(codec_data->hdmi_core_pdev,
+						     &edid_blk);
+	if (!IS_ERR_VALUE(rc)) {
+		uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
+		uinfo->count = edid_blk.audio_data_blk_size +
+			       edid_blk.spk_alloc_data_blk_size;
+	}
+
+	return 0;
+}
+
+static int msm_hdmi_edid_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol) {
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct msm_hdmi_audio_codec_rx_data *codec_data;
+	struct msm_hdmi_audio_edid_blk edid_blk;
+	int rc;
+
+	codec_data = snd_soc_codec_get_drvdata(codec);
+	rc = codec_data->hdmi_ops.get_audio_edid_blk(codec_data->hdmi_core_pdev,
+						     &edid_blk);
+
+	if (!IS_ERR_VALUE(rc)) {
+		memcpy(ucontrol->value.bytes.data, edid_blk.audio_data_blk,
+		       edid_blk.audio_data_blk_size);
+		memcpy((ucontrol->value.bytes.data +
+		       edid_blk.audio_data_blk_size),
+		       edid_blk.spk_alloc_data_blk,
+		       edid_blk.spk_alloc_data_blk_size);
+	}
+
+	return rc;
+}
+
+static const struct snd_kcontrol_new msm_hdmi_codec_rx_controls[] = {
+	{
+		.access = SNDRV_CTL_ELEM_ACCESS_READ |
+			  SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+		.iface	= SNDRV_CTL_ELEM_IFACE_PCM,
+		.name	= "HDMI EDID",
+		.info	= msm_hdmi_edid_ctl_info,
+		.get	= msm_hdmi_edid_get,
+	},
+};
+
 static int msm_hdmi_audio_codec_rx_dai_hw_params(
 		struct snd_pcm_substream *substream,
 		struct snd_pcm_hw_params *params,
@@ -142,6 +197,8 @@
 static struct snd_soc_codec_driver msm_hdmi_audio_codec_rx_soc_driver = {
 	.probe = msm_hdmi_audio_codec_rx_probe,
 	.remove =  msm_hdmi_audio_codec_rx_remove,
+	.controls = msm_hdmi_codec_rx_controls,
+	.num_controls = ARRAY_SIZE(msm_hdmi_codec_rx_controls),
 };
 
 static int __devinit msm_hdmi_audio_codec_rx_plat_probe(
diff --git a/sound/soc/codecs/msm_stub.c b/sound/soc/codecs/msm_stub.c
index 0143e51..0cbcaf3 100644
--- a/sound/soc/codecs/msm_stub.c
+++ b/sound/soc/codecs/msm_stub.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/sound/soc/codecs/timpani.c b/sound/soc/codecs/timpani.c
index 786b2d6..f80c0fc 100644
--- a/sound/soc/codecs/timpani.c
+++ b/sound/soc/codecs/timpani.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/sound/soc/codecs/timpani.h b/sound/soc/codecs/timpani.h
index bd14eea..bfa0b8b 100644
--- a/sound/soc/codecs/timpani.h
+++ b/sound/soc/codecs/timpani.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/sound/soc/codecs/wcd9304-tables.c b/sound/soc/codecs/wcd9304-tables.c
index ba0b6b6..83c0c1d 100644
--- a/sound/soc/codecs/wcd9304-tables.c
+++ b/sound/soc/codecs/wcd9304-tables.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/sound/soc/codecs/wcd9304.c b/sound/soc/codecs/wcd9304.c
index 3fc3f32..36d5d6b 100644
--- a/sound/soc/codecs/wcd9304.c
+++ b/sound/soc/codecs/wcd9304.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -1919,7 +1919,7 @@
 				     int mask)
 {
 	/* XXX: wake_lock_timeout()? */
-	snd_soc_jack_report(jack, status, mask);
+	snd_soc_jack_report_no_dapm(jack, status, mask);
 }
 
 static void hphocp_off_report(struct sitar_priv *sitar,
diff --git a/sound/soc/codecs/wcd9304.h b/sound/soc/codecs/wcd9304.h
index 13336ef..4c92fb8 100644
--- a/sound/soc/codecs/wcd9304.h
+++ b/sound/soc/codecs/wcd9304.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/sound/soc/codecs/wcd9306-tables.c b/sound/soc/codecs/wcd9306-tables.c
new file mode 100644
index 0000000..21c5636
--- /dev/null
+++ b/sound/soc/codecs/wcd9306-tables.c
@@ -0,0 +1,1015 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 and
+* only version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*/
+
+#include <linux/mfd/wcd9xxx/wcd9306_registers.h>
+#include "wcd9306.h"
+
+const u8 tapan_reg_readable[TAPAN_CACHE_SIZE] = {
+	[TAPAN_A_CHIP_CTL] = 1,
+	[TAPAN_A_CHIP_STATUS] = 1,
+	[TAPAN_A_CHIP_ID_BYTE_0] = 1,
+	[TAPAN_A_CHIP_ID_BYTE_1] = 1,
+	[TAPAN_A_CHIP_ID_BYTE_2] = 1,
+	[TAPAN_A_CHIP_ID_BYTE_3] = 1,
+	[TAPAN_A_CHIP_VERSION] = 1,
+	[TAPAN_A_CHIP_DEBUG_CTL] = 1,
+	[TAPAN_A_SLAVE_ID_1] = 1,
+	[TAPAN_A_SLAVE_ID_2] = 1,
+	[TAPAN_A_SLAVE_ID_3] = 1,
+	[TAPAN_A_PIN_CTL_OE0] = 1,
+	[TAPAN_A_PIN_CTL_DATA0] = 1,
+	[TAPAN_A_HDRIVE_GENERIC] = 1,
+	[TAPAN_A_HDRIVE_OVERRIDE] = 1,
+	[TAPAN_A_ANA_CSR_WAIT_STATE] = 1,
+	[TAPAN_A_PROCESS_MONITOR_CTL0] = 1,
+	[TAPAN_A_PROCESS_MONITOR_CTL1] = 1,
+	[TAPAN_A_PROCESS_MONITOR_CTL2] = 1,
+	[TAPAN_A_PROCESS_MONITOR_CTL3] = 1,
+	[TAPAN_A_QFUSE_CTL] = 1,
+	[TAPAN_A_QFUSE_STATUS] = 1,
+	[TAPAN_A_QFUSE_DATA_OUT0] = 1,
+	[TAPAN_A_QFUSE_DATA_OUT1] = 1,
+	[TAPAN_A_QFUSE_DATA_OUT2] = 1,
+	[TAPAN_A_QFUSE_DATA_OUT3] = 1,
+	[TAPAN_A_QFUSE_DATA_OUT4] = 1,
+	[TAPAN_A_QFUSE_DATA_OUT5] = 1,
+	[TAPAN_A_QFUSE_DATA_OUT6] = 1,
+	[TAPAN_A_QFUSE_DATA_OUT7] = 1,
+	[TAPAN_A_CDC_CTL] = 1,
+	[TAPAN_A_LEAKAGE_CTL] = 1,
+	[TAPAN_A_INTR_MODE] = 1,
+	[TAPAN_A_INTR_MASK0] = 1,
+	[TAPAN_A_INTR_MASK1] = 1,
+	[TAPAN_A_INTR_MASK2] = 1,
+	[TAPAN_A_INTR_MASK3] = 1,
+	[TAPAN_A_INTR_STATUS0] = 1,
+	[TAPAN_A_INTR_STATUS1] = 1,
+	[TAPAN_A_INTR_STATUS2] = 1,
+	[TAPAN_A_INTR_STATUS3] = 1,
+	[TAPAN_A_INTR_CLEAR0] = 0,
+	[TAPAN_A_INTR_CLEAR1] = 0,
+	[TAPAN_A_INTR_CLEAR2] = 0,
+	[TAPAN_A_INTR_CLEAR3] = 0,
+	[TAPAN_A_INTR_LEVEL0] = 1,
+	[TAPAN_A_INTR_LEVEL1] = 1,
+	[TAPAN_A_INTR_LEVEL2] = 1,
+	[TAPAN_A_INTR_LEVEL3] = 1,
+	[TAPAN_A_INTR_TEST0] = 1,
+	[TAPAN_A_INTR_TEST1] = 1,
+	[TAPAN_A_INTR_TEST2] = 1,
+	[TAPAN_A_INTR_TEST3] = 1,
+	[TAPAN_A_INTR_SET0] = 1,
+	[TAPAN_A_INTR_SET1] = 1,
+	[TAPAN_A_INTR_SET2] = 1,
+	[TAPAN_A_INTR_SET3] = 1,
+	[TAPAN_A_INTR_DESTN0] = 1,
+	[TAPAN_A_INTR_DESTN1] = 1,
+	[TAPAN_A_INTR_DESTN2] = 1,
+	[TAPAN_A_INTR_DESTN3] = 1,
+	[TAPAN_A_CDC_DMIC_DATA0_MODE] = 1,
+	[TAPAN_A_CDC_DMIC_CLK0_MODE] = 1,
+	[TAPAN_A_CDC_DMIC_DATA1_MODE] = 1,
+	[TAPAN_A_CDC_DMIC_CLK1_MODE] = 1,
+	[TAPAN_A_CDC_INTR_MODE] = 1,
+	[TAPAN_A_BIAS_REF_CTL] = 1,
+	[TAPAN_A_BIAS_CENTRAL_BG_CTL] = 1,
+	[TAPAN_A_BIAS_PRECHRG_CTL] = 1,
+	[TAPAN_A_BIAS_CURR_CTL_1] = 1,
+	[TAPAN_A_BIAS_CURR_CTL_2] = 1,
+	[TAPAN_A_BIAS_OSC_BG_CTL] = 1,
+	[TAPAN_A_CLK_BUFF_EN1] = 1,
+	[TAPAN_A_CLK_BUFF_EN2] = 1,
+	[TAPAN_A_LDO_H_MODE_1] = 1,
+	[TAPAN_A_LDO_H_MODE_2] = 1,
+	[TAPAN_A_LDO_H_LOOP_CTL] = 1,
+	[TAPAN_A_LDO_H_COMP_1] = 1,
+	[TAPAN_A_LDO_H_COMP_2] = 1,
+	[TAPAN_A_LDO_H_BIAS_1] = 1,
+	[TAPAN_A_LDO_H_BIAS_2] = 1,
+	[TAPAN_A_LDO_H_BIAS_3] = 1,
+	[TAPAN_A_MICB_CFILT_1_CTL] = 1,
+	[TAPAN_A_MICB_CFILT_1_VAL] = 1,
+	[TAPAN_A_MICB_CFILT_1_PRECHRG] = 1,
+	[TAPAN_A_MICB_1_CTL] = 1,
+	[TAPAN_A_MICB_1_INT_RBIAS] = 1,
+	[TAPAN_A_MICB_1_MBHC] = 1,
+	[TAPAN_A_MICB_CFILT_2_CTL] = 1,
+	[TAPAN_A_MICB_CFILT_2_VAL] = 1,
+	[TAPAN_A_MICB_CFILT_2_PRECHRG] = 1,
+	[TAPAN_A_MICB_2_CTL] = 1,
+	[TAPAN_A_MICB_2_INT_RBIAS] = 1,
+	[TAPAN_A_MICB_2_MBHC] = 1,
+	[TAPAN_A_MICB_CFILT_3_CTL] = 1,
+	[TAPAN_A_MICB_CFILT_3_VAL] = 1,
+	[TAPAN_A_MICB_CFILT_3_PRECHRG] = 1,
+	[TAPAN_A_MICB_3_CTL] = 1,
+	[TAPAN_A_MICB_3_INT_RBIAS] = 1,
+	[TAPAN_A_MICB_3_MBHC] = 1,
+	[TAPAN_A_MBHC_INSERT_DETECT] = 1,
+	[TAPAN_A_MBHC_INSERT_DET_STATUS] = 1,
+	[TAPAN_A_TX_COM_BIAS] = 1,
+	[TAPAN_A_MBHC_SCALING_MUX_1] = 1,
+	[TAPAN_A_MBHC_SCALING_MUX_2] = 1,
+	[TAPAN_A_RESERVED_MAD_ANA_CTRL] = 1,
+	[TAPAN_A_TX_SUP_SWITCH_CTRL_1] = 1,
+	[TAPAN_A_TX_SUP_SWITCH_CTRL_2] = 1,
+	[TAPAN_A_TX_1_EN] = 1,
+	[TAPAN_A_TX_2_EN] = 1,
+	[TAPAN_A_TX_1_2_ADC_CH1] = 1,
+	[TAPAN_A_TX_1_2_ADC_CH2] = 1,
+	[TAPAN_A_TX_1_2_ATEST_REFCTRL] = 1,
+	[TAPAN_A_TX_1_2_TEST_CTL] = 1,
+	[TAPAN_A_TX_1_2_TEST_BLOCK_EN] = 1,
+	[TAPAN_A_TX_1_2_TXFE_CLKDIV] = 1,
+	[TAPAN_A_TX_1_2_SAR_ERR_CH1] = 1,
+	[TAPAN_A_TX_1_2_SAR_ERR_CH2] = 1,
+	[TAPAN_A_TX_3_EN] = 1,
+	[TAPAN_A_TX_1_2_TEST_EN] = 1,
+	[TAPAN_A_TX_4_5_TXFE_SC_CTL] = 1,
+	[TAPAN_A_TX_4_5_TEST_EN] = 1,
+	[TAPAN_A_TX_4_EN] = 1,
+	[TAPAN_A_TX_5_EN] = 1,
+	[TAPAN_A_TX_4_5_ADC_CH4] = 1,
+	[TAPAN_A_TX_4_5_ADC_CH5] = 1,
+	[TAPAN_A_TX_4_5_ATEST_REFCTRL] = 1,
+	[TAPAN_A_TX_4_5_TEST_CTL] = 1,
+	[TAPAN_A_TX_4_5_TEST_BLOCK_EN] = 1,
+	[TAPAN_A_TX_4_5_TXFE_CKDIV] = 1,
+	[TAPAN_A_TX_4_5_SAR_ERR_CH4] = 1,
+	[TAPAN_A_TX_4_5_SAR_ERR_CH5] = 1,
+	[TAPAN_A_TX_7_MBHC_EN] = 1,
+	[TAPAN_A_TX_7_MBHC_ATEST_REFCTRL] = 1,
+	[TAPAN_A_TX_7_MBHC_ADC] = 1,
+	[TAPAN_A_TX_7_MBHC_TEST_CTL] = 1,
+	[TAPAN_A_TX_7_MBHC_SAR_ERR] = 1,
+	[TAPAN_A_TX_7_TXFE_CLKDIV] = 1,
+	[TAPAN_A_BUCK_MODE_1] = 1,
+	[TAPAN_A_BUCK_MODE_2] = 1,
+	[TAPAN_A_BUCK_MODE_3] = 1,
+	[TAPAN_A_BUCK_MODE_4] = 1,
+	[TAPAN_A_BUCK_MODE_5] = 1,
+	[TAPAN_A_BUCK_CTRL_VCL_1] = 1,
+	[TAPAN_A_BUCK_CTRL_VCL_2] = 1,
+	[TAPAN_A_BUCK_CTRL_VCL_3] = 1,
+	[TAPAN_A_BUCK_CTRL_CCL_1] = 1,
+	[TAPAN_A_BUCK_CTRL_CCL_2] = 1,
+	[TAPAN_A_BUCK_CTRL_CCL_3] = 1,
+	[TAPAN_A_BUCK_CTRL_CCL_4] = 1,
+	[TAPAN_A_BUCK_CTRL_PWM_DRVR_1] = 1,
+	[TAPAN_A_BUCK_CTRL_PWM_DRVR_2] = 1,
+	[TAPAN_A_BUCK_CTRL_PWM_DRVR_3] = 1,
+	[TAPAN_A_BUCK_TMUX_A_D] = 1,
+	[TAPAN_A_NCP_BUCKREF] = 1,
+	[TAPAN_A_NCP_EN] = 1,
+	[TAPAN_A_NCP_CLK] = 1,
+	[TAPAN_A_NCP_STATIC] = 1,
+	[TAPAN_A_NCP_VTH_LOW] = 1,
+	[TAPAN_A_NCP_VTH_HIGH] = 1,
+	[TAPAN_A_NCP_ATEST] = 1,
+	[TAPAN_A_NCP_DTEST] = 1,
+	[TAPAN_A_NCP_DLY1] = 1,
+	[TAPAN_A_NCP_DLY2] = 1,
+	[TAPAN_A_RX_AUX_SW_CTL] = 1,
+	[TAPAN_A_RX_PA_AUX_IN_CONN] = 1,
+	[TAPAN_A_RX_COM_TIMER_DIV] = 1,
+	[TAPAN_A_RX_COM_OCP_CTL] = 1,
+	[TAPAN_A_RX_COM_OCP_COUNT] = 1,
+	[TAPAN_A_RX_COM_DAC_CTL] = 1,
+	[TAPAN_A_RX_COM_BIAS] = 1,
+	[TAPAN_A_RX_HPH_AUTO_CHOP] = 1,
+	[TAPAN_A_RX_HPH_CHOP_CTL] = 1,
+	[TAPAN_A_RX_HPH_BIAS_PA] = 1,
+	[TAPAN_A_RX_HPH_BIAS_LDO] = 1,
+	[TAPAN_A_RX_HPH_BIAS_CNP] = 1,
+	[TAPAN_A_RX_HPH_BIAS_WG_OCP] = 1,
+	[TAPAN_A_RX_HPH_OCP_CTL] = 1,
+	[TAPAN_A_RX_HPH_CNP_EN] = 1,
+	[TAPAN_A_RX_HPH_CNP_WG_CTL] = 1,
+	[TAPAN_A_RX_HPH_CNP_WG_TIME] = 1,
+	[TAPAN_A_RX_HPH_L_GAIN] = 1,
+	[TAPAN_A_RX_HPH_L_TEST] = 1,
+	[TAPAN_A_RX_HPH_L_PA_CTL] = 1,
+	[TAPAN_A_RX_HPH_L_DAC_CTL] = 1,
+	[TAPAN_A_RX_HPH_L_ATEST] = 1,
+	[TAPAN_A_RX_HPH_L_STATUS] = 1,
+	[TAPAN_A_RX_HPH_R_GAIN] = 1,
+	[TAPAN_A_RX_HPH_R_TEST] = 1,
+	[TAPAN_A_RX_HPH_R_PA_CTL] = 1,
+	[TAPAN_A_RX_HPH_R_DAC_CTL] = 1,
+	[TAPAN_A_RX_HPH_R_ATEST] = 1,
+	[TAPAN_A_RX_HPH_R_STATUS] = 1,
+	[TAPAN_A_RX_EAR_BIAS_PA] = 1,
+	[TAPAN_A_RX_EAR_BIAS_CMBUFF] = 1,
+	[TAPAN_A_RX_EAR_EN] = 1,
+	[TAPAN_A_RX_EAR_GAIN] = 1,
+	[TAPAN_A_RX_EAR_CMBUFF] = 1,
+	[TAPAN_A_RX_EAR_ICTL] = 1,
+	[TAPAN_A_RX_EAR_CCOMP] = 1,
+	[TAPAN_A_RX_EAR_VCM] = 1,
+	[TAPAN_A_RX_EAR_CNP] = 1,
+	[TAPAN_A_RX_EAR_DAC_CTL_ATEST] = 1,
+	[TAPAN_A_RX_EAR_STATUS] = 1,
+	[TAPAN_A_RX_LINE_BIAS_PA] = 1,
+	[TAPAN_A_RX_BUCK_BIAS1] = 1,
+	[TAPAN_A_RX_BUCK_BIAS2] = 1,
+	[TAPAN_A_RX_LINE_COM] = 1,
+	[TAPAN_A_RX_LINE_CNP_EN] = 1,
+	[TAPAN_A_RX_LINE_CNP_WG_CTL] = 1,
+	[TAPAN_A_RX_LINE_CNP_WG_TIME] = 1,
+	[TAPAN_A_RX_LINE_1_GAIN] = 1,
+	[TAPAN_A_RX_LINE_1_TEST] = 1,
+	[TAPAN_A_RX_LINE_1_DAC_CTL] = 1,
+	[TAPAN_A_RX_LINE_1_STATUS] = 1,
+	[TAPAN_A_RX_LINE_2_GAIN] = 1,
+	[TAPAN_A_RX_LINE_2_TEST] = 1,
+	[TAPAN_A_RX_LINE_2_DAC_CTL] = 1,
+	[TAPAN_A_RX_LINE_2_STATUS] = 1,
+	[TAPAN_A_RX_LINE_CNP_DBG] = 1,
+	[TAPAN_A_SPKR_DRV_EN] = 1,
+	[TAPAN_A_SPKR_DRV_GAIN] = 1,
+	[TAPAN_A_SPKR_DRV_DAC_CTL] = 1,
+	[TAPAN_A_SPKR_DRV_OCP_CTL] = 1,
+	[TAPAN_A_SPKR_DRV_CLIP_DET] = 1,
+	[TAPAN_A_SPKR_DRV_IEC] = 1,
+	[TAPAN_A_SPKR_DRV_DBG_DAC] = 1,
+	[TAPAN_A_SPKR_DRV_DBG_PA] = 1,
+	[TAPAN_A_SPKR_DRV_DBG_PWRSTG] = 1,
+	[TAPAN_A_SPKR_DRV_BIAS_LDO] = 1,
+	[TAPAN_A_SPKR_DRV_BIAS_INT] = 1,
+	[TAPAN_A_SPKR_DRV_BIAS_PA] = 1,
+	[TAPAN_A_SPKR_DRV_STATUS_OCP] = 1,
+	[TAPAN_A_SPKR_DRV_STATUS_PA] = 1,
+	[TAPAN_A_RC_OSC_FREQ] = 1,
+	[TAPAN_A_RC_OSC_TEST] = 1,
+	[TAPAN_A_RC_OSC_STATUS] = 1,
+	[TAPAN_A_RC_OSC_TUNER] = 1,
+	[TAPAN_A_MBHC_HPH] = 1,
+	[TAPAN_A_CDC_ANC1_B1_CTL] = 1,
+	[TAPAN_A_CDC_ANC2_B1_CTL] = 1,
+	[TAPAN_A_CDC_ANC1_SHIFT] = 1,
+	[TAPAN_A_CDC_ANC2_SHIFT] = 1,
+	[TAPAN_A_CDC_ANC1_IIR_B1_CTL] = 1,
+	[TAPAN_A_CDC_ANC2_IIR_B1_CTL] = 1,
+	[TAPAN_A_CDC_ANC1_IIR_B2_CTL] = 1,
+	[TAPAN_A_CDC_ANC2_IIR_B2_CTL] = 1,
+	[TAPAN_A_CDC_ANC1_IIR_B3_CTL] = 1,
+	[TAPAN_A_CDC_ANC2_IIR_B3_CTL] = 1,
+	[TAPAN_A_CDC_ANC1_LPF_B1_CTL] = 1,
+	[TAPAN_A_CDC_ANC2_LPF_B1_CTL] = 1,
+	[TAPAN_A_CDC_ANC1_LPF_B2_CTL] = 1,
+	[TAPAN_A_CDC_ANC2_LPF_B2_CTL] = 1,
+	[TAPAN_A_CDC_ANC1_SPARE] = 1,
+	[TAPAN_A_CDC_ANC2_SPARE] = 1,
+	[TAPAN_A_CDC_ANC1_SMLPF_CTL] = 1,
+	[TAPAN_A_CDC_ANC2_SMLPF_CTL] = 1,
+	[TAPAN_A_CDC_ANC1_DCFLT_CTL] = 1,
+	[TAPAN_A_CDC_ANC2_DCFLT_CTL] = 1,
+	[TAPAN_A_CDC_ANC1_GAIN_CTL] = 1,
+	[TAPAN_A_CDC_ANC2_GAIN_CTL] = 1,
+	[TAPAN_A_CDC_ANC1_B2_CTL] = 1,
+	[TAPAN_A_CDC_ANC2_B2_CTL] = 1,
+	[TAPAN_A_CDC_TX1_VOL_CTL_TIMER] = 1,
+	[TAPAN_A_CDC_TX2_VOL_CTL_TIMER] = 1,
+	[TAPAN_A_CDC_TX3_VOL_CTL_TIMER] = 1,
+	[TAPAN_A_CDC_TX4_VOL_CTL_TIMER] = 1,
+	[TAPAN_A_CDC_TX1_VOL_CTL_GAIN] = 1,
+	[TAPAN_A_CDC_TX2_VOL_CTL_GAIN] = 1,
+	[TAPAN_A_CDC_TX3_VOL_CTL_GAIN] = 1,
+	[TAPAN_A_CDC_TX4_VOL_CTL_GAIN] = 1,
+	[TAPAN_A_CDC_TX1_VOL_CTL_CFG] = 1,
+	[TAPAN_A_CDC_TX2_VOL_CTL_CFG] = 1,
+	[TAPAN_A_CDC_TX3_VOL_CTL_CFG] = 1,
+	[TAPAN_A_CDC_TX4_VOL_CTL_CFG] = 1,
+	[TAPAN_A_CDC_TX1_MUX_CTL] = 1,
+	[TAPAN_A_CDC_TX2_MUX_CTL] = 1,
+	[TAPAN_A_CDC_TX3_MUX_CTL] = 1,
+	[TAPAN_A_CDC_TX4_MUX_CTL] = 1,
+	[TAPAN_A_CDC_TX1_CLK_FS_CTL] = 1,
+	[TAPAN_A_CDC_TX2_CLK_FS_CTL] = 1,
+	[TAPAN_A_CDC_TX3_CLK_FS_CTL] = 1,
+	[TAPAN_A_CDC_TX4_CLK_FS_CTL] = 1,
+	[TAPAN_A_CDC_TX1_DMIC_CTL] = 1,
+	[TAPAN_A_CDC_TX2_DMIC_CTL] = 1,
+	[TAPAN_A_CDC_TX3_DMIC_CTL] = 1,
+	[TAPAN_A_CDC_TX4_DMIC_CTL] = 1,
+	[TAPAN_A_CDC_DEBUG_B1_CTL] = 1,
+	[TAPAN_A_CDC_DEBUG_B2_CTL] = 1,
+	[TAPAN_A_CDC_DEBUG_B3_CTL] = 1,
+	[TAPAN_A_CDC_DEBUG_B4_CTL] = 1,
+	[TAPAN_A_CDC_DEBUG_B5_CTL] = 1,
+	[TAPAN_A_CDC_DEBUG_B6_CTL] = 1,
+	[TAPAN_A_CDC_DEBUG_B7_CTL] = 1,
+	[TAPAN_A_CDC_SRC1_PDA_CFG] = 1,
+	[TAPAN_A_CDC_SRC2_PDA_CFG] = 1,
+	[TAPAN_A_CDC_SRC1_FS_CTL] = 1,
+	[TAPAN_A_CDC_SRC2_FS_CTL] = 1,
+	[TAPAN_A_CDC_RX1_B1_CTL] = 1,
+	[TAPAN_A_CDC_RX2_B1_CTL] = 1,
+	[TAPAN_A_CDC_RX3_B1_CTL] = 1,
+	[TAPAN_A_CDC_RX4_B1_CTL] = 1,
+	[TAPAN_A_CDC_RX1_B2_CTL] = 1,
+	[TAPAN_A_CDC_RX2_B2_CTL] = 1,
+	[TAPAN_A_CDC_RX3_B2_CTL] = 1,
+	[TAPAN_A_CDC_RX4_B2_CTL] = 1,
+	[TAPAN_A_CDC_RX1_B3_CTL] = 1,
+	[TAPAN_A_CDC_RX2_B3_CTL] = 1,
+	[TAPAN_A_CDC_RX3_B3_CTL] = 1,
+	[TAPAN_A_CDC_RX4_B3_CTL] = 1,
+	[TAPAN_A_CDC_RX1_B4_CTL] = 1,
+	[TAPAN_A_CDC_RX2_B4_CTL] = 1,
+	[TAPAN_A_CDC_RX3_B4_CTL] = 1,
+	[TAPAN_A_CDC_RX4_B4_CTL] = 1,
+	[TAPAN_A_CDC_RX1_B5_CTL] = 1,
+	[TAPAN_A_CDC_RX2_B5_CTL] = 1,
+	[TAPAN_A_CDC_RX3_B5_CTL] = 1,
+	[TAPAN_A_CDC_RX4_B5_CTL] = 1,
+	[TAPAN_A_CDC_RX1_B6_CTL] = 1,
+	[TAPAN_A_CDC_RX2_B6_CTL] = 1,
+	[TAPAN_A_CDC_RX3_B6_CTL] = 1,
+	[TAPAN_A_CDC_RX4_B6_CTL] = 1,
+	[TAPAN_A_CDC_RX1_VOL_CTL_B1_CTL] = 1,
+	[TAPAN_A_CDC_RX2_VOL_CTL_B1_CTL] = 1,
+	[TAPAN_A_CDC_RX3_VOL_CTL_B1_CTL] = 1,
+	[TAPAN_A_CDC_RX4_VOL_CTL_B1_CTL] = 1,
+	[TAPAN_A_CDC_RX1_VOL_CTL_B2_CTL] = 1,
+	[TAPAN_A_CDC_RX2_VOL_CTL_B2_CTL] = 1,
+	[TAPAN_A_CDC_RX3_VOL_CTL_B2_CTL] = 1,
+	[TAPAN_A_CDC_RX4_VOL_CTL_B2_CTL] = 1,
+	[TAPAN_A_CDC_CLK_ANC_RESET_CTL] = 1,
+	[TAPAN_A_CDC_CLK_RX_RESET_CTL] = 1,
+	[TAPAN_A_CDC_CLK_TX_RESET_B1_CTL] = 1,
+	[TAPAN_A_CDC_CLK_TX_RESET_B2_CTL] = 1,
+	[TAPAN_A_CDC_CLK_DMIC_B1_CTL] = 1,
+	[TAPAN_A_CDC_CLK_DMIC_B2_CTL] = 1,
+	[TAPAN_A_CDC_CLK_I2S_CTL] = 1,
+	[TAPAN_A_CDC_CLK_OTHR_RESET_B1_CTL] = 1,
+	[TAPAN_A_CDC_CLK_OTHR_RESET_B2_CTL] = 1,
+	[TAPAN_A_CDC_CLK_TX_CLK_EN_B1_CTL] = 1,
+	[TAPAN_A_CDC_CLK_TX_CLK_EN_B2_CTL] = 1,
+	[TAPAN_A_CDC_CLK_OTHR_CTL] = 1,
+	[TAPAN_A_CDC_CLK_RDAC_CLK_EN_CTL] = 1,
+	[TAPAN_A_CDC_CLK_ANC_CLK_EN_CTL] = 1,
+	[TAPAN_A_CDC_CLK_RX_B1_CTL] = 1,
+	[TAPAN_A_CDC_CLK_RX_B2_CTL] = 1,
+	[TAPAN_A_CDC_CLK_MCLK_CTL] = 1,
+	[TAPAN_A_CDC_CLK_PDM_CTL] = 1,
+	[TAPAN_A_CDC_CLK_SD_CTL] = 1,
+	[TAPAN_A_CDC_CLK_POWER_CTL] = 1,
+	[TAPAN_A_CDC_CLSH_B1_CTL] = 1,
+	[TAPAN_A_CDC_CLSH_B2_CTL] = 1,
+	[TAPAN_A_CDC_CLSH_B3_CTL] = 1,
+	[TAPAN_A_CDC_CLSH_BUCK_NCP_VARS] = 1,
+	[TAPAN_A_CDC_CLSH_IDLE_HPH_THSD] = 1,
+	[TAPAN_A_CDC_CLSH_IDLE_EAR_THSD] = 1,
+	[TAPAN_A_CDC_CLSH_FCLKONLY_HPH_THSD] = 1,
+	[TAPAN_A_CDC_CLSH_FCLKONLY_EAR_THSD] = 1,
+	[TAPAN_A_CDC_CLSH_K_ADDR] = 1,
+	[TAPAN_A_CDC_CLSH_K_DATA] = 1,
+	[TAPAN_A_CDC_CLSH_I_PA_FACT_HPH_L] = 1,
+	[TAPAN_A_CDC_CLSH_I_PA_FACT_HPH_U] = 1,
+	[TAPAN_A_CDC_CLSH_I_PA_FACT_EAR_L] = 1,
+	[TAPAN_A_CDC_CLSH_I_PA_FACT_EAR_U] = 1,
+	[TAPAN_A_CDC_CLSH_V_PA_HD_EAR] = 1,
+	[TAPAN_A_CDC_CLSH_V_PA_HD_HPH] = 1,
+	[TAPAN_A_CDC_CLSH_V_PA_MIN_EAR] = 1,
+	[TAPAN_A_CDC_CLSH_V_PA_MIN_HPH] = 1,
+	[TAPAN_A_CDC_IIR1_GAIN_B1_CTL] = 1,
+	[TAPAN_A_CDC_IIR2_GAIN_B1_CTL] = 1,
+	[TAPAN_A_CDC_IIR1_GAIN_B2_CTL] = 1,
+	[TAPAN_A_CDC_IIR2_GAIN_B2_CTL] = 1,
+	[TAPAN_A_CDC_IIR1_GAIN_B3_CTL] = 1,
+	[TAPAN_A_CDC_IIR2_GAIN_B3_CTL] = 1,
+	[TAPAN_A_CDC_IIR1_GAIN_B4_CTL] = 1,
+	[TAPAN_A_CDC_IIR2_GAIN_B4_CTL] = 1,
+	[TAPAN_A_CDC_IIR1_GAIN_B5_CTL] = 1,
+	[TAPAN_A_CDC_IIR2_GAIN_B5_CTL] = 1,
+	[TAPAN_A_CDC_IIR1_GAIN_B6_CTL] = 1,
+	[TAPAN_A_CDC_IIR2_GAIN_B6_CTL] = 1,
+	[TAPAN_A_CDC_IIR1_GAIN_B7_CTL] = 1,
+	[TAPAN_A_CDC_IIR2_GAIN_B7_CTL] = 1,
+	[TAPAN_A_CDC_IIR1_GAIN_B8_CTL] = 1,
+	[TAPAN_A_CDC_IIR2_GAIN_B8_CTL] = 1,
+	[TAPAN_A_CDC_IIR1_CTL] = 1,
+	[TAPAN_A_CDC_IIR2_CTL] = 1,
+	[TAPAN_A_CDC_IIR1_GAIN_TIMER_CTL] = 1,
+	[TAPAN_A_CDC_IIR2_GAIN_TIMER_CTL] = 1,
+	[TAPAN_A_CDC_IIR1_COEF_B1_CTL] = 1,
+	[TAPAN_A_CDC_IIR2_COEF_B1_CTL] = 1,
+	[TAPAN_A_CDC_IIR1_COEF_B2_CTL] = 1,
+	[TAPAN_A_CDC_IIR2_COEF_B2_CTL] = 1,
+	[TAPAN_A_CDC_TOP_GAIN_UPDATE] = 1,
+	[TAPAN_A_CDC_COMP0_B1_CTL] = 1,
+	[TAPAN_A_CDC_COMP1_B1_CTL] = 1,
+	[TAPAN_A_CDC_COMP2_B1_CTL] = 1,
+	[TAPAN_A_CDC_COMP0_B2_CTL] = 1,
+	[TAPAN_A_CDC_COMP1_B2_CTL] = 1,
+	[TAPAN_A_CDC_COMP2_B2_CTL] = 1,
+	[TAPAN_A_CDC_COMP0_B3_CTL] = 1,
+	[TAPAN_A_CDC_COMP1_B3_CTL] = 1,
+	[TAPAN_A_CDC_COMP2_B3_CTL] = 1,
+	[TAPAN_A_CDC_COMP0_B4_CTL] = 1,
+	[TAPAN_A_CDC_COMP1_B4_CTL] = 1,
+	[TAPAN_A_CDC_COMP2_B4_CTL] = 1,
+	[TAPAN_A_CDC_COMP0_B5_CTL] = 1,
+	[TAPAN_A_CDC_COMP1_B5_CTL] = 1,
+	[TAPAN_A_CDC_COMP2_B5_CTL] = 1,
+	[TAPAN_A_CDC_COMP0_B6_CTL] = 1,
+	[TAPAN_A_CDC_COMP1_B6_CTL] = 1,
+	[TAPAN_A_CDC_COMP2_B6_CTL] = 1,
+	[TAPAN_A_CDC_COMP0_SHUT_DOWN_STATUS] = 1,
+	[TAPAN_A_CDC_COMP1_SHUT_DOWN_STATUS] = 1,
+	[TAPAN_A_CDC_COMP2_SHUT_DOWN_STATUS] = 1,
+	[TAPAN_A_CDC_COMP0_FS_CFG] = 1,
+	[TAPAN_A_CDC_COMP1_FS_CFG] = 1,
+	[TAPAN_A_CDC_COMP2_FS_CFG] = 1,
+	[TAPAN_A_CDC_CONN_RX1_B1_CTL] = 1,
+	[TAPAN_A_CDC_CONN_RX1_B2_CTL] = 1,
+	[TAPAN_A_CDC_CONN_RX1_B3_CTL] = 1,
+	[TAPAN_A_CDC_CONN_RX2_B1_CTL] = 1,
+	[TAPAN_A_CDC_CONN_RX2_B2_CTL] = 1,
+	[TAPAN_A_CDC_CONN_RX2_B3_CTL] = 1,
+	[TAPAN_A_CDC_CONN_RX3_B1_CTL] = 1,
+	[TAPAN_A_CDC_CONN_RX3_B2_CTL] = 1,
+	[TAPAN_A_CDC_CONN_RX4_B1_CTL] = 1,
+	[TAPAN_A_CDC_CONN_RX4_B2_CTL] = 1,
+	[TAPAN_A_CDC_CONN_RX4_B3_CTL] = 1,
+	[TAPAN_A_CDC_CONN_ANC_B1_CTL] = 1,
+	[TAPAN_A_CDC_CONN_ANC_B2_CTL] = 1,
+	[TAPAN_A_CDC_CONN_TX_B1_CTL] = 1,
+	[TAPAN_A_CDC_CONN_TX_B2_CTL] = 1,
+	[TAPAN_A_CDC_CONN_TX_B3_CTL] = 1,
+	[TAPAN_A_CDC_CONN_TX_B4_CTL] = 1,
+	[TAPAN_A_CDC_CONN_EQ1_B1_CTL] = 1,
+	[TAPAN_A_CDC_CONN_EQ1_B2_CTL] = 1,
+	[TAPAN_A_CDC_CONN_EQ1_B3_CTL] = 1,
+	[TAPAN_A_CDC_CONN_EQ1_B4_CTL] = 1,
+	[TAPAN_A_CDC_CONN_EQ2_B1_CTL] = 1,
+	[TAPAN_A_CDC_CONN_EQ2_B2_CTL] = 1,
+	[TAPAN_A_CDC_CONN_EQ2_B3_CTL] = 1,
+	[TAPAN_A_CDC_CONN_EQ2_B4_CTL] = 1,
+	[TAPAN_A_CDC_CONN_SRC1_B1_CTL] = 1,
+	[TAPAN_A_CDC_CONN_SRC1_B2_CTL] = 1,
+	[TAPAN_A_CDC_CONN_SRC2_B1_CTL] = 1,
+	[TAPAN_A_CDC_CONN_SRC2_B2_CTL] = 1,
+	[TAPAN_A_CDC_CONN_TX_SB_B1_CTL] = 1,
+	[TAPAN_A_CDC_CONN_TX_SB_B2_CTL] = 1,
+	[TAPAN_A_CDC_CONN_TX_SB_B3_CTL] = 1,
+	[TAPAN_A_CDC_CONN_TX_SB_B4_CTL] = 1,
+	[TAPAN_A_CDC_CONN_TX_SB_B5_CTL] = 1,
+	[TAPAN_A_CDC_CONN_TX_SB_B11_CTL] = 1,
+	[TAPAN_A_CDC_CONN_RX_SB_B1_CTL] = 1,
+	[TAPAN_A_CDC_CONN_RX_SB_B2_CTL] = 1,
+	[TAPAN_A_CDC_CONN_CLSH_CTL] = 1,
+	[TAPAN_A_CDC_CONN_MISC] = 1,
+	[TAPAN_A_CDC_MBHC_EN_CTL] = 1,
+	[TAPAN_A_CDC_MBHC_FIR_B1_CFG] = 1,
+	[TAPAN_A_CDC_MBHC_FIR_B2_CFG] = 1,
+	[TAPAN_A_CDC_MBHC_TIMER_B1_CTL] = 1,
+	[TAPAN_A_CDC_MBHC_TIMER_B2_CTL] = 1,
+	[TAPAN_A_CDC_MBHC_TIMER_B3_CTL] = 1,
+	[TAPAN_A_CDC_MBHC_TIMER_B4_CTL] = 1,
+	[TAPAN_A_CDC_MBHC_TIMER_B5_CTL] = 1,
+	[TAPAN_A_CDC_MBHC_TIMER_B6_CTL] = 1,
+	[TAPAN_A_CDC_MBHC_B1_STATUS] = 1,
+	[TAPAN_A_CDC_MBHC_B2_STATUS] = 1,
+	[TAPAN_A_CDC_MBHC_B3_STATUS] = 1,
+	[TAPAN_A_CDC_MBHC_B4_STATUS] = 1,
+	[TAPAN_A_CDC_MBHC_B5_STATUS] = 1,
+	[TAPAN_A_CDC_MBHC_B1_CTL] = 1,
+	[TAPAN_A_CDC_MBHC_B2_CTL] = 1,
+	[TAPAN_A_CDC_MBHC_VOLT_B1_CTL] = 1,
+	[TAPAN_A_CDC_MBHC_VOLT_B2_CTL] = 1,
+	[TAPAN_A_CDC_MBHC_VOLT_B3_CTL] = 1,
+	[TAPAN_A_CDC_MBHC_VOLT_B4_CTL] = 1,
+	[TAPAN_A_CDC_MBHC_VOLT_B5_CTL] = 1,
+	[TAPAN_A_CDC_MBHC_VOLT_B6_CTL] = 1,
+	[TAPAN_A_CDC_MBHC_VOLT_B7_CTL] = 1,
+	[TAPAN_A_CDC_MBHC_VOLT_B8_CTL] = 1,
+	[TAPAN_A_CDC_MBHC_VOLT_B9_CTL] = 1,
+	[TAPAN_A_CDC_MBHC_VOLT_B10_CTL] = 1,
+	[TAPAN_A_CDC_MBHC_VOLT_B11_CTL] = 1,
+	[TAPAN_A_CDC_MBHC_VOLT_B12_CTL] = 1,
+	[TAPAN_A_CDC_MBHC_CLK_CTL] = 1,
+	[TAPAN_A_CDC_MBHC_INT_CTL] = 1,
+	[TAPAN_A_CDC_MBHC_DEBUG_CTL] = 1,
+	[TAPAN_A_CDC_MBHC_SPARE] = 1,
+};
+
+const u8 tapan_reset_reg_defaults[TAPAN_CACHE_SIZE] = {
+	[TAPAN_A_CHIP_CTL] = TAPAN_A_CHIP_CTL__POR,
+	[TAPAN_A_CHIP_STATUS] = TAPAN_A_CHIP_STATUS__POR,
+	[TAPAN_A_CHIP_ID_BYTE_0] = TAPAN_A_CHIP_ID_BYTE_0__POR,
+	[TAPAN_A_CHIP_ID_BYTE_1] = TAPAN_A_CHIP_ID_BYTE_1__POR,
+	[TAPAN_A_CHIP_ID_BYTE_2] = TAPAN_A_CHIP_ID_BYTE_2__POR,
+	[TAPAN_A_CHIP_ID_BYTE_3] = TAPAN_A_CHIP_ID_BYTE_3__POR,
+	[TAPAN_A_CHIP_VERSION] = TAPAN_A_CHIP_VERSION__POR,
+	[TAPAN_A_CHIP_DEBUG_CTL] = TAPAN_A_CHIP_DEBUG_CTL__POR,
+	[TAPAN_A_SLAVE_ID_1] = TAPAN_A_SLAVE_ID_1__POR,
+	[TAPAN_A_SLAVE_ID_2] = TAPAN_A_SLAVE_ID_2__POR,
+	[TAPAN_A_SLAVE_ID_3] = TAPAN_A_SLAVE_ID_3__POR,
+	[TAPAN_A_PIN_CTL_OE0] = TAPAN_A_PIN_CTL_OE0__POR,
+	[TAPAN_A_PIN_CTL_DATA0] = TAPAN_A_PIN_CTL_DATA0__POR,
+	[TAPAN_A_HDRIVE_GENERIC] = TAPAN_A_HDRIVE_GENERIC__POR,
+	[TAPAN_A_HDRIVE_OVERRIDE] = TAPAN_A_HDRIVE_OVERRIDE__POR,
+	[TAPAN_A_ANA_CSR_WAIT_STATE] = TAPAN_A_ANA_CSR_WAIT_STATE__POR,
+	[TAPAN_A_PROCESS_MONITOR_CTL0] = TAPAN_A_PROCESS_MONITOR_CTL0__POR,
+	[TAPAN_A_PROCESS_MONITOR_CTL1] = TAPAN_A_PROCESS_MONITOR_CTL1__POR,
+	[TAPAN_A_PROCESS_MONITOR_CTL2] = TAPAN_A_PROCESS_MONITOR_CTL2__POR,
+	[TAPAN_A_PROCESS_MONITOR_CTL3] = TAPAN_A_PROCESS_MONITOR_CTL3__POR,
+	[TAPAN_A_QFUSE_CTL] = TAPAN_A_QFUSE_CTL__POR,
+	[TAPAN_A_QFUSE_STATUS] = TAPAN_A_QFUSE_STATUS__POR,
+	[TAPAN_A_QFUSE_DATA_OUT0] = TAPAN_A_QFUSE_DATA_OUT0__POR,
+	[TAPAN_A_QFUSE_DATA_OUT1] = TAPAN_A_QFUSE_DATA_OUT1__POR,
+	[TAPAN_A_QFUSE_DATA_OUT2] = TAPAN_A_QFUSE_DATA_OUT2__POR,
+	[TAPAN_A_QFUSE_DATA_OUT3] = TAPAN_A_QFUSE_DATA_OUT3__POR,
+	[TAPAN_A_QFUSE_DATA_OUT4] = TAPAN_A_QFUSE_DATA_OUT4__POR,
+	[TAPAN_A_QFUSE_DATA_OUT5] = TAPAN_A_QFUSE_DATA_OUT5__POR,
+	[TAPAN_A_QFUSE_DATA_OUT6] = TAPAN_A_QFUSE_DATA_OUT6__POR,
+	[TAPAN_A_QFUSE_DATA_OUT7] = TAPAN_A_QFUSE_DATA_OUT7__POR,
+	[TAPAN_A_CDC_CTL] = TAPAN_A_CDC_CTL__POR,
+	[TAPAN_A_LEAKAGE_CTL] = TAPAN_A_LEAKAGE_CTL__POR,
+	[TAPAN_A_INTR_MODE] = TAPAN_A_INTR_MODE__POR,
+	[TAPAN_A_INTR_MASK0] = TAPAN_A_INTR_MASK0__POR,
+	[TAPAN_A_INTR_MASK1] = TAPAN_A_INTR_MASK1__POR,
+	[TAPAN_A_INTR_MASK2] = TAPAN_A_INTR_MASK2__POR,
+	[TAPAN_A_INTR_MASK3] = TAPAN_A_INTR_MASK3__POR,
+	[TAPAN_A_INTR_STATUS0] = TAPAN_A_INTR_STATUS0__POR,
+	[TAPAN_A_INTR_STATUS1] = TAPAN_A_INTR_STATUS1__POR,
+	[TAPAN_A_INTR_STATUS2] = TAPAN_A_INTR_STATUS2__POR,
+	[TAPAN_A_INTR_STATUS3] = TAPAN_A_INTR_STATUS3__POR,
+	[TAPAN_A_INTR_CLEAR0] = TAPAN_A_INTR_CLEAR0__POR,
+	[TAPAN_A_INTR_CLEAR1] = TAPAN_A_INTR_CLEAR1__POR,
+	[TAPAN_A_INTR_CLEAR2] = TAPAN_A_INTR_CLEAR2__POR,
+	[TAPAN_A_INTR_CLEAR3] = TAPAN_A_INTR_CLEAR3__POR,
+	[TAPAN_A_INTR_LEVEL0] = TAPAN_A_INTR_LEVEL0__POR,
+	[TAPAN_A_INTR_LEVEL1] = TAPAN_A_INTR_LEVEL1__POR,
+	[TAPAN_A_INTR_LEVEL2] = TAPAN_A_INTR_LEVEL2__POR,
+	[TAPAN_A_INTR_LEVEL3] = TAPAN_A_INTR_LEVEL3__POR,
+	[TAPAN_A_INTR_TEST0] = TAPAN_A_INTR_TEST0__POR,
+	[TAPAN_A_INTR_TEST1] = TAPAN_A_INTR_TEST1__POR,
+	[TAPAN_A_INTR_TEST2] = TAPAN_A_INTR_TEST2__POR,
+	[TAPAN_A_INTR_TEST3] = TAPAN_A_INTR_TEST3__POR,
+	[TAPAN_A_INTR_SET0] = TAPAN_A_INTR_SET0__POR,
+	[TAPAN_A_INTR_SET1] = TAPAN_A_INTR_SET1__POR,
+	[TAPAN_A_INTR_SET2] = TAPAN_A_INTR_SET2__POR,
+	[TAPAN_A_INTR_SET3] = TAPAN_A_INTR_SET3__POR,
+	[TAPAN_A_INTR_DESTN0] = TAPAN_A_INTR_DESTN0__POR,
+	[TAPAN_A_INTR_DESTN1] = TAPAN_A_INTR_DESTN1__POR,
+	[TAPAN_A_INTR_DESTN2] = TAPAN_A_INTR_DESTN2__POR,
+	[TAPAN_A_INTR_DESTN3] = TAPAN_A_INTR_DESTN3__POR,
+	[TAPAN_A_CDC_DMIC_DATA0_MODE] = TAPAN_A_CDC_DMIC_DATA0_MODE__POR,
+	[TAPAN_A_CDC_DMIC_CLK0_MODE] = TAPAN_A_CDC_DMIC_CLK0_MODE__POR,
+	[TAPAN_A_CDC_DMIC_DATA1_MODE] = TAPAN_A_CDC_DMIC_DATA1_MODE__POR,
+	[TAPAN_A_CDC_DMIC_CLK1_MODE] = TAPAN_A_CDC_DMIC_CLK1_MODE__POR,
+	[TAPAN_A_CDC_INTR_MODE] = TAPAN_A_CDC_INTR_MODE__POR,
+	[TAPAN_A_BIAS_REF_CTL] = TAPAN_A_BIAS_REF_CTL__POR,
+	[TAPAN_A_BIAS_CENTRAL_BG_CTL] = TAPAN_A_BIAS_CENTRAL_BG_CTL__POR,
+	[TAPAN_A_BIAS_PRECHRG_CTL] = TAPAN_A_BIAS_PRECHRG_CTL__POR,
+	[TAPAN_A_BIAS_CURR_CTL_1] = TAPAN_A_BIAS_CURR_CTL_1__POR,
+	[TAPAN_A_BIAS_CURR_CTL_2] = TAPAN_A_BIAS_CURR_CTL_2__POR,
+	[TAPAN_A_BIAS_OSC_BG_CTL] = TAPAN_A_BIAS_OSC_BG_CTL__POR,
+	[TAPAN_A_CLK_BUFF_EN1] = TAPAN_A_CLK_BUFF_EN1__POR,
+	[TAPAN_A_CLK_BUFF_EN2] = TAPAN_A_CLK_BUFF_EN2__POR,
+	[TAPAN_A_LDO_H_MODE_1] = TAPAN_A_LDO_H_MODE_1__POR,
+	[TAPAN_A_LDO_H_MODE_2] = TAPAN_A_LDO_H_MODE_2__POR,
+	[TAPAN_A_LDO_H_LOOP_CTL] = TAPAN_A_LDO_H_LOOP_CTL__POR,
+	[TAPAN_A_LDO_H_COMP_1] = TAPAN_A_LDO_H_COMP_1__POR,
+	[TAPAN_A_LDO_H_COMP_2] = TAPAN_A_LDO_H_COMP_2__POR,
+	[TAPAN_A_LDO_H_BIAS_1] = TAPAN_A_LDO_H_BIAS_1__POR,
+	[TAPAN_A_LDO_H_BIAS_2] = TAPAN_A_LDO_H_BIAS_2__POR,
+	[TAPAN_A_LDO_H_BIAS_3] = TAPAN_A_LDO_H_BIAS_3__POR,
+	[TAPAN_A_MICB_CFILT_1_CTL] = TAPAN_A_MICB_CFILT_1_CTL__POR,
+	[TAPAN_A_MICB_CFILT_1_VAL] = TAPAN_A_MICB_CFILT_1_VAL__POR,
+	[TAPAN_A_MICB_CFILT_1_PRECHRG] = TAPAN_A_MICB_CFILT_1_PRECHRG__POR,
+	[TAPAN_A_MICB_1_CTL] = TAPAN_A_MICB_1_CTL__POR,
+	[TAPAN_A_MICB_1_INT_RBIAS] = TAPAN_A_MICB_1_INT_RBIAS__POR,
+	[TAPAN_A_MICB_1_MBHC] = TAPAN_A_MICB_1_MBHC__POR,
+	[TAPAN_A_MICB_CFILT_2_CTL] = TAPAN_A_MICB_CFILT_2_CTL__POR,
+	[TAPAN_A_MICB_CFILT_2_VAL] = TAPAN_A_MICB_CFILT_2_VAL__POR,
+	[TAPAN_A_MICB_CFILT_2_PRECHRG] = TAPAN_A_MICB_CFILT_2_PRECHRG__POR,
+	[TAPAN_A_MICB_2_CTL] = TAPAN_A_MICB_2_CTL__POR,
+	[TAPAN_A_MICB_2_INT_RBIAS] = TAPAN_A_MICB_2_INT_RBIAS__POR,
+	[TAPAN_A_MICB_2_MBHC] = TAPAN_A_MICB_2_MBHC__POR,
+	[TAPAN_A_MICB_CFILT_3_CTL] = TAPAN_A_MICB_CFILT_3_CTL__POR,
+	[TAPAN_A_MICB_CFILT_3_VAL] = TAPAN_A_MICB_CFILT_3_VAL__POR,
+	[TAPAN_A_MICB_CFILT_3_PRECHRG] = TAPAN_A_MICB_CFILT_3_PRECHRG__POR,
+	[TAPAN_A_MICB_3_CTL] = TAPAN_A_MICB_3_CTL__POR,
+	[TAPAN_A_MICB_3_INT_RBIAS] = TAPAN_A_MICB_3_INT_RBIAS__POR,
+	[TAPAN_A_MICB_3_MBHC] = TAPAN_A_MICB_3_MBHC__POR,
+	[TAPAN_A_MBHC_INSERT_DETECT] = TAPAN_A_MBHC_INSERT_DETECT__POR,
+	[TAPAN_A_MBHC_INSERT_DET_STATUS] = TAPAN_A_MBHC_INSERT_DET_STATUS__POR,
+	[TAPAN_A_TX_COM_BIAS] = TAPAN_A_TX_COM_BIAS__POR,
+	[TAPAN_A_MBHC_SCALING_MUX_1] = TAPAN_A_MBHC_SCALING_MUX_1__POR,
+	[TAPAN_A_MBHC_SCALING_MUX_2] = TAPAN_A_MBHC_SCALING_MUX_2__POR,
+	[TAPAN_A_RESERVED_MAD_ANA_CTRL] = TAPAN_A_RESERVED_MAD_ANA_CTRL__POR,
+	[TAPAN_A_TX_SUP_SWITCH_CTRL_1] = TAPAN_A_TX_SUP_SWITCH_CTRL_1__POR,
+	[TAPAN_A_TX_SUP_SWITCH_CTRL_2] = TAPAN_A_TX_SUP_SWITCH_CTRL_2__POR,
+	[TAPAN_A_TX_1_EN] = TAPAN_A_TX_1_EN__POR,
+	[TAPAN_A_TX_2_EN] = TAPAN_A_TX_2_EN__POR,
+	[TAPAN_A_TX_1_2_ADC_CH1] = TAPAN_A_TX_1_2_ADC_CH1__POR,
+	[TAPAN_A_TX_1_2_ADC_CH2] = TAPAN_A_TX_1_2_ADC_CH2__POR,
+	[TAPAN_A_TX_1_2_ATEST_REFCTRL] = TAPAN_A_TX_1_2_ATEST_REFCTRL__POR,
+	[TAPAN_A_TX_1_2_TEST_CTL] = TAPAN_A_TX_1_2_TEST_CTL__POR,
+	[TAPAN_A_TX_1_2_TEST_BLOCK_EN] = TAPAN_A_TX_1_2_TEST_BLOCK_EN__POR,
+	[TAPAN_A_TX_1_2_TXFE_CLKDIV] = TAPAN_A_TX_1_2_TXFE_CLKDIV__POR,
+	[TAPAN_A_TX_1_2_SAR_ERR_CH1] = TAPAN_A_TX_1_2_SAR_ERR_CH1__POR,
+	[TAPAN_A_TX_1_2_SAR_ERR_CH2] = TAPAN_A_TX_1_2_SAR_ERR_CH2__POR,
+	[TAPAN_A_TX_3_EN] = TAPAN_A_TX_3_EN__POR,
+	[TAPAN_A_TX_1_2_TEST_EN] = TAPAN_A_TX_1_2_TEST_EN__POR,
+	[TAPAN_A_TX_4_5_TXFE_SC_CTL] = TAPAN_A_TX_4_5_TXFE_SC_CTL__POR,
+	[TAPAN_A_TX_4_5_TEST_EN] = TAPAN_A_TX_4_5_TEST_EN__POR,
+	[TAPAN_A_TX_4_EN] = TAPAN_A_TX_4_EN__POR,
+	[TAPAN_A_TX_5_EN] = TAPAN_A_TX_5_EN__POR,
+	[TAPAN_A_TX_4_5_ADC_CH4] = TAPAN_A_TX_4_5_ADC_CH4__POR,
+	[TAPAN_A_TX_4_5_ADC_CH5] = TAPAN_A_TX_4_5_ADC_CH5__POR,
+	[TAPAN_A_TX_4_5_ATEST_REFCTRL] = TAPAN_A_TX_4_5_ATEST_REFCTRL__POR,
+	[TAPAN_A_TX_4_5_TEST_CTL] = TAPAN_A_TX_4_5_TEST_CTL__POR,
+	[TAPAN_A_TX_4_5_TEST_BLOCK_EN] = TAPAN_A_TX_4_5_TEST_BLOCK_EN__POR,
+	[TAPAN_A_TX_4_5_TXFE_CKDIV] = TAPAN_A_TX_4_5_TXFE_CKDIV__POR,
+	[TAPAN_A_TX_4_5_SAR_ERR_CH4] = TAPAN_A_TX_4_5_SAR_ERR_CH4__POR,
+	[TAPAN_A_TX_4_5_SAR_ERR_CH5] = TAPAN_A_TX_4_5_SAR_ERR_CH5__POR,
+	[TAPAN_A_TX_7_MBHC_EN] = TAPAN_A_TX_7_MBHC_EN__POR,
+	[TAPAN_A_TX_7_MBHC_ATEST_REFCTRL] =
+			TAPAN_A_TX_7_MBHC_ATEST_REFCTRL__POR,
+	[TAPAN_A_TX_7_MBHC_ADC] = TAPAN_A_TX_7_MBHC_ADC__POR,
+	[TAPAN_A_TX_7_MBHC_TEST_CTL] = TAPAN_A_TX_7_MBHC_TEST_CTL__POR,
+	[TAPAN_A_TX_7_MBHC_SAR_ERR] = TAPAN_A_TX_7_MBHC_SAR_ERR__POR,
+	[TAPAN_A_TX_7_TXFE_CLKDIV] = TAPAN_A_TX_7_TXFE_CLKDIV__POR,
+	[TAPAN_A_BUCK_MODE_1] = TAPAN_A_BUCK_MODE_1__POR,
+	[TAPAN_A_BUCK_MODE_2] = TAPAN_A_BUCK_MODE_2__POR,
+	[TAPAN_A_BUCK_MODE_3] = TAPAN_A_BUCK_MODE_3__POR,
+	[TAPAN_A_BUCK_MODE_4] = TAPAN_A_BUCK_MODE_4__POR,
+	[TAPAN_A_BUCK_MODE_5] = TAPAN_A_BUCK_MODE_5__POR,
+	[TAPAN_A_BUCK_CTRL_VCL_1] = TAPAN_A_BUCK_CTRL_VCL_1__POR,
+	[TAPAN_A_BUCK_CTRL_VCL_2] = TAPAN_A_BUCK_CTRL_VCL_2__POR,
+	[TAPAN_A_BUCK_CTRL_VCL_3] = TAPAN_A_BUCK_CTRL_VCL_3__POR,
+	[TAPAN_A_BUCK_CTRL_CCL_1] = TAPAN_A_BUCK_CTRL_CCL_1__POR,
+	[TAPAN_A_BUCK_CTRL_CCL_2] = TAPAN_A_BUCK_CTRL_CCL_2__POR,
+	[TAPAN_A_BUCK_CTRL_CCL_3] = TAPAN_A_BUCK_CTRL_CCL_3__POR,
+	[TAPAN_A_BUCK_CTRL_CCL_4] = TAPAN_A_BUCK_CTRL_CCL_4__POR,
+	[TAPAN_A_BUCK_CTRL_PWM_DRVR_1] = TAPAN_A_BUCK_CTRL_PWM_DRVR_1__POR,
+	[TAPAN_A_BUCK_CTRL_PWM_DRVR_2] = TAPAN_A_BUCK_CTRL_PWM_DRVR_2__POR,
+	[TAPAN_A_BUCK_CTRL_PWM_DRVR_3] = TAPAN_A_BUCK_CTRL_PWM_DRVR_3__POR,
+	[TAPAN_A_BUCK_TMUX_A_D] = TAPAN_A_BUCK_TMUX_A_D__POR,
+	[TAPAN_A_NCP_BUCKREF] = TAPAN_A_NCP_BUCKREF__POR,
+	[TAPAN_A_NCP_EN] = TAPAN_A_NCP_EN__POR,
+	[TAPAN_A_NCP_CLK] = TAPAN_A_NCP_CLK__POR,
+	[TAPAN_A_NCP_STATIC] = TAPAN_A_NCP_STATIC__POR,
+	[TAPAN_A_NCP_VTH_LOW] = TAPAN_A_NCP_VTH_LOW__POR,
+	[TAPAN_A_NCP_VTH_HIGH] = TAPAN_A_NCP_VTH_HIGH__POR,
+	[TAPAN_A_NCP_ATEST] = TAPAN_A_NCP_ATEST__POR,
+	[TAPAN_A_NCP_DTEST] = TAPAN_A_NCP_DTEST__POR,
+	[TAPAN_A_NCP_DLY1] = TAPAN_A_NCP_DLY1__POR,
+	[TAPAN_A_NCP_DLY2] = TAPAN_A_NCP_DLY2__POR,
+	[TAPAN_A_RX_AUX_SW_CTL] = TAPAN_A_RX_AUX_SW_CTL__POR,
+	[TAPAN_A_RX_PA_AUX_IN_CONN] = TAPAN_A_RX_PA_AUX_IN_CONN__POR,
+	[TAPAN_A_RX_COM_TIMER_DIV] = TAPAN_A_RX_COM_TIMER_DIV__POR,
+	[TAPAN_A_RX_COM_OCP_CTL] = TAPAN_A_RX_COM_OCP_CTL__POR,
+	[TAPAN_A_RX_COM_OCP_COUNT] = TAPAN_A_RX_COM_OCP_COUNT__POR,
+	[TAPAN_A_RX_COM_DAC_CTL] = TAPAN_A_RX_COM_DAC_CTL__POR,
+	[TAPAN_A_RX_COM_BIAS] = TAPAN_A_RX_COM_BIAS__POR,
+	[TAPAN_A_RX_HPH_AUTO_CHOP] = TAPAN_A_RX_HPH_AUTO_CHOP__POR,
+	[TAPAN_A_RX_HPH_CHOP_CTL] = TAPAN_A_RX_HPH_CHOP_CTL__POR,
+	[TAPAN_A_RX_HPH_BIAS_PA] = TAPAN_A_RX_HPH_BIAS_PA__POR,
+	[TAPAN_A_RX_HPH_BIAS_LDO] = TAPAN_A_RX_HPH_BIAS_LDO__POR,
+	[TAPAN_A_RX_HPH_BIAS_CNP] = TAPAN_A_RX_HPH_BIAS_CNP__POR,
+	[TAPAN_A_RX_HPH_BIAS_WG_OCP] = TAPAN_A_RX_HPH_BIAS_WG_OCP__POR,
+	[TAPAN_A_RX_HPH_OCP_CTL] = TAPAN_A_RX_HPH_OCP_CTL__POR,
+	[TAPAN_A_RX_HPH_CNP_EN] = TAPAN_A_RX_HPH_CNP_EN__POR,
+	[TAPAN_A_RX_HPH_CNP_WG_CTL] = TAPAN_A_RX_HPH_CNP_WG_CTL__POR,
+	[TAPAN_A_RX_HPH_CNP_WG_TIME] = TAPAN_A_RX_HPH_CNP_WG_TIME__POR,
+	[TAPAN_A_RX_HPH_L_GAIN] = TAPAN_A_RX_HPH_L_GAIN__POR,
+	[TAPAN_A_RX_HPH_L_TEST] = TAPAN_A_RX_HPH_L_TEST__POR,
+	[TAPAN_A_RX_HPH_L_PA_CTL] = TAPAN_A_RX_HPH_L_PA_CTL__POR,
+	[TAPAN_A_RX_HPH_L_DAC_CTL] = TAPAN_A_RX_HPH_L_DAC_CTL__POR,
+	[TAPAN_A_RX_HPH_L_ATEST] = TAPAN_A_RX_HPH_L_ATEST__POR,
+	[TAPAN_A_RX_HPH_L_STATUS] = TAPAN_A_RX_HPH_L_STATUS__POR,
+	[TAPAN_A_RX_HPH_R_GAIN] = TAPAN_A_RX_HPH_R_GAIN__POR,
+	[TAPAN_A_RX_HPH_R_TEST] = TAPAN_A_RX_HPH_R_TEST__POR,
+	[TAPAN_A_RX_HPH_R_PA_CTL] = TAPAN_A_RX_HPH_R_PA_CTL__POR,
+	[TAPAN_A_RX_HPH_R_DAC_CTL] = TAPAN_A_RX_HPH_R_DAC_CTL__POR,
+	[TAPAN_A_RX_HPH_R_ATEST] = TAPAN_A_RX_HPH_R_ATEST__POR,
+	[TAPAN_A_RX_HPH_R_STATUS] = TAPAN_A_RX_HPH_R_STATUS__POR,
+	[TAPAN_A_RX_EAR_BIAS_PA] = TAPAN_A_RX_EAR_BIAS_PA__POR,
+	[TAPAN_A_RX_EAR_BIAS_CMBUFF] = TAPAN_A_RX_EAR_BIAS_CMBUFF__POR,
+	[TAPAN_A_RX_EAR_EN] = TAPAN_A_RX_EAR_EN__POR,
+	[TAPAN_A_RX_EAR_GAIN] = TAPAN_A_RX_EAR_GAIN__POR,
+	[TAPAN_A_RX_EAR_CMBUFF] = TAPAN_A_RX_EAR_CMBUFF__POR,
+	[TAPAN_A_RX_EAR_ICTL] = TAPAN_A_RX_EAR_ICTL__POR,
+	[TAPAN_A_RX_EAR_CCOMP] = TAPAN_A_RX_EAR_CCOMP__POR,
+	[TAPAN_A_RX_EAR_VCM] = TAPAN_A_RX_EAR_VCM__POR,
+	[TAPAN_A_RX_EAR_CNP] = TAPAN_A_RX_EAR_CNP__POR,
+	[TAPAN_A_RX_EAR_DAC_CTL_ATEST] = TAPAN_A_RX_EAR_DAC_CTL_ATEST__POR,
+	[TAPAN_A_RX_EAR_STATUS] = TAPAN_A_RX_EAR_STATUS__POR,
+	[TAPAN_A_RX_LINE_BIAS_PA] = TAPAN_A_RX_LINE_BIAS_PA__POR,
+	[TAPAN_A_RX_BUCK_BIAS1] = TAPAN_A_RX_BUCK_BIAS1__POR,
+	[TAPAN_A_RX_BUCK_BIAS2] = TAPAN_A_RX_BUCK_BIAS2__POR,
+	[TAPAN_A_RX_LINE_COM] = TAPAN_A_RX_LINE_COM__POR,
+	[TAPAN_A_RX_LINE_CNP_EN] = TAPAN_A_RX_LINE_CNP_EN__POR,
+	[TAPAN_A_RX_LINE_CNP_WG_CTL] = TAPAN_A_RX_LINE_CNP_WG_CTL__POR,
+	[TAPAN_A_RX_LINE_CNP_WG_TIME] = TAPAN_A_RX_LINE_CNP_WG_TIME__POR,
+	[TAPAN_A_RX_LINE_1_GAIN] = TAPAN_A_RX_LINE_1_GAIN__POR,
+	[TAPAN_A_RX_LINE_1_TEST] = TAPAN_A_RX_LINE_1_TEST__POR,
+	[TAPAN_A_RX_LINE_1_DAC_CTL] = TAPAN_A_RX_LINE_1_DAC_CTL__POR,
+	[TAPAN_A_RX_LINE_1_STATUS] = TAPAN_A_RX_LINE_1_STATUS__POR,
+	[TAPAN_A_RX_LINE_2_GAIN] = TAPAN_A_RX_LINE_2_GAIN__POR,
+	[TAPAN_A_RX_LINE_2_TEST] = TAPAN_A_RX_LINE_2_TEST__POR,
+	[TAPAN_A_RX_LINE_2_DAC_CTL] = TAPAN_A_RX_LINE_2_DAC_CTL__POR,
+	[TAPAN_A_RX_LINE_2_STATUS] = TAPAN_A_RX_LINE_2_STATUS__POR,
+	[TAPAN_A_RX_LINE_CNP_DBG] = TAPAN_A_RX_LINE_CNP_DBG__POR,
+	[TAPAN_A_SPKR_DRV_EN] = TAPAN_A_SPKR_DRV_EN__POR,
+	[TAPAN_A_SPKR_DRV_GAIN] = TAPAN_A_SPKR_DRV_GAIN__POR,
+	[TAPAN_A_SPKR_DRV_DAC_CTL] = TAPAN_A_SPKR_DRV_DAC_CTL__POR,
+	[TAPAN_A_SPKR_DRV_OCP_CTL] = TAPAN_A_SPKR_DRV_OCP_CTL__POR,
+	[TAPAN_A_SPKR_DRV_CLIP_DET] = TAPAN_A_SPKR_DRV_CLIP_DET__POR,
+	[TAPAN_A_SPKR_DRV_IEC] = TAPAN_A_SPKR_DRV_IEC__POR,
+	[TAPAN_A_SPKR_DRV_DBG_DAC] = TAPAN_A_SPKR_DRV_DBG_DAC__POR,
+	[TAPAN_A_SPKR_DRV_DBG_PA] = TAPAN_A_SPKR_DRV_DBG_PA__POR,
+	[TAPAN_A_SPKR_DRV_DBG_PWRSTG] = TAPAN_A_SPKR_DRV_DBG_PWRSTG__POR,
+	[TAPAN_A_SPKR_DRV_BIAS_LDO] = TAPAN_A_SPKR_DRV_BIAS_LDO__POR,
+	[TAPAN_A_SPKR_DRV_BIAS_INT] = TAPAN_A_SPKR_DRV_BIAS_INT__POR,
+	[TAPAN_A_SPKR_DRV_BIAS_PA] = TAPAN_A_SPKR_DRV_BIAS_PA__POR,
+	[TAPAN_A_SPKR_DRV_STATUS_OCP] = TAPAN_A_SPKR_DRV_STATUS_OCP__POR,
+	[TAPAN_A_SPKR_DRV_STATUS_PA] = TAPAN_A_SPKR_DRV_STATUS_PA__POR,
+	[TAPAN_A_RC_OSC_FREQ] = TAPAN_A_RC_OSC_FREQ__POR,
+	[TAPAN_A_RC_OSC_TEST] = TAPAN_A_RC_OSC_TEST__POR,
+	[TAPAN_A_RC_OSC_STATUS] = TAPAN_A_RC_OSC_STATUS__POR,
+	[TAPAN_A_RC_OSC_TUNER] = TAPAN_A_RC_OSC_TUNER__POR,
+	[TAPAN_A_MBHC_HPH] = TAPAN_A_MBHC_HPH__POR,
+	[TAPAN_A_CDC_ANC1_B1_CTL] = TAPAN_A_CDC_ANC1_B1_CTL__POR,
+	[TAPAN_A_CDC_ANC2_B1_CTL] = TAPAN_A_CDC_ANC2_B1_CTL__POR,
+	[TAPAN_A_CDC_ANC1_SHIFT] = TAPAN_A_CDC_ANC1_SHIFT__POR,
+	[TAPAN_A_CDC_ANC2_SHIFT] = TAPAN_A_CDC_ANC2_SHIFT__POR,
+	[TAPAN_A_CDC_ANC1_IIR_B1_CTL] = TAPAN_A_CDC_ANC1_IIR_B1_CTL__POR,
+	[TAPAN_A_CDC_ANC2_IIR_B1_CTL] = TAPAN_A_CDC_ANC2_IIR_B1_CTL__POR,
+	[TAPAN_A_CDC_ANC1_IIR_B2_CTL] = TAPAN_A_CDC_ANC1_IIR_B2_CTL__POR,
+	[TAPAN_A_CDC_ANC2_IIR_B2_CTL] = TAPAN_A_CDC_ANC2_IIR_B2_CTL__POR,
+	[TAPAN_A_CDC_ANC1_IIR_B3_CTL] = TAPAN_A_CDC_ANC1_IIR_B3_CTL__POR,
+	[TAPAN_A_CDC_ANC2_IIR_B3_CTL] = TAPAN_A_CDC_ANC2_IIR_B3_CTL__POR,
+	[TAPAN_A_CDC_ANC1_LPF_B1_CTL] = TAPAN_A_CDC_ANC1_LPF_B1_CTL__POR,
+	[TAPAN_A_CDC_ANC2_LPF_B1_CTL] = TAPAN_A_CDC_ANC2_LPF_B1_CTL__POR,
+	[TAPAN_A_CDC_ANC1_LPF_B2_CTL] = TAPAN_A_CDC_ANC1_LPF_B2_CTL__POR,
+	[TAPAN_A_CDC_ANC2_LPF_B2_CTL] = TAPAN_A_CDC_ANC2_LPF_B2_CTL__POR,
+	[TAPAN_A_CDC_ANC1_SPARE] = TAPAN_A_CDC_ANC1_SPARE__POR,
+	[TAPAN_A_CDC_ANC2_SPARE] = TAPAN_A_CDC_ANC2_SPARE__POR,
+	[TAPAN_A_CDC_ANC1_SMLPF_CTL] = TAPAN_A_CDC_ANC1_SMLPF_CTL__POR,
+	[TAPAN_A_CDC_ANC2_SMLPF_CTL] = TAPAN_A_CDC_ANC2_SMLPF_CTL__POR,
+	[TAPAN_A_CDC_ANC1_DCFLT_CTL] = TAPAN_A_CDC_ANC1_DCFLT_CTL__POR,
+	[TAPAN_A_CDC_ANC2_DCFLT_CTL] = TAPAN_A_CDC_ANC2_DCFLT_CTL__POR,
+	[TAPAN_A_CDC_ANC1_GAIN_CTL] = TAPAN_A_CDC_ANC1_GAIN_CTL__POR,
+	[TAPAN_A_CDC_ANC2_GAIN_CTL] = TAPAN_A_CDC_ANC2_GAIN_CTL__POR,
+	[TAPAN_A_CDC_ANC1_B2_CTL] = TAPAN_A_CDC_ANC1_B2_CTL__POR,
+	[TAPAN_A_CDC_ANC2_B2_CTL] = TAPAN_A_CDC_ANC2_B2_CTL__POR,
+	[TAPAN_A_CDC_TX1_VOL_CTL_TIMER] = TAPAN_A_CDC_TX1_VOL_CTL_TIMER__POR,
+	[TAPAN_A_CDC_TX2_VOL_CTL_TIMER] = TAPAN_A_CDC_TX2_VOL_CTL_TIMER__POR,
+	[TAPAN_A_CDC_TX3_VOL_CTL_TIMER] = TAPAN_A_CDC_TX3_VOL_CTL_TIMER__POR,
+	[TAPAN_A_CDC_TX4_VOL_CTL_TIMER] = TAPAN_A_CDC_TX4_VOL_CTL_TIMER__POR,
+	[TAPAN_A_CDC_TX1_VOL_CTL_GAIN] = TAPAN_A_CDC_TX1_VOL_CTL_GAIN__POR,
+	[TAPAN_A_CDC_TX2_VOL_CTL_GAIN] = TAPAN_A_CDC_TX2_VOL_CTL_GAIN__POR,
+	[TAPAN_A_CDC_TX3_VOL_CTL_GAIN] = TAPAN_A_CDC_TX3_VOL_CTL_GAIN__POR,
+	[TAPAN_A_CDC_TX4_VOL_CTL_GAIN] = TAPAN_A_CDC_TX4_VOL_CTL_GAIN__POR,
+	[TAPAN_A_CDC_TX1_VOL_CTL_CFG] = TAPAN_A_CDC_TX1_VOL_CTL_CFG__POR,
+	[TAPAN_A_CDC_TX2_VOL_CTL_CFG] = TAPAN_A_CDC_TX2_VOL_CTL_CFG__POR,
+	[TAPAN_A_CDC_TX3_VOL_CTL_CFG] = TAPAN_A_CDC_TX3_VOL_CTL_CFG__POR,
+	[TAPAN_A_CDC_TX4_VOL_CTL_CFG] = TAPAN_A_CDC_TX4_VOL_CTL_CFG__POR,
+	[TAPAN_A_CDC_TX1_MUX_CTL] = TAPAN_A_CDC_TX1_MUX_CTL__POR,
+	[TAPAN_A_CDC_TX2_MUX_CTL] = TAPAN_A_CDC_TX2_MUX_CTL__POR,
+	[TAPAN_A_CDC_TX3_MUX_CTL] = TAPAN_A_CDC_TX3_MUX_CTL__POR,
+	[TAPAN_A_CDC_TX4_MUX_CTL] = TAPAN_A_CDC_TX4_MUX_CTL__POR,
+	[TAPAN_A_CDC_TX1_CLK_FS_CTL] = TAPAN_A_CDC_TX1_CLK_FS_CTL__POR,
+	[TAPAN_A_CDC_TX2_CLK_FS_CTL] = TAPAN_A_CDC_TX2_CLK_FS_CTL__POR,
+	[TAPAN_A_CDC_TX3_CLK_FS_CTL] = TAPAN_A_CDC_TX3_CLK_FS_CTL__POR,
+	[TAPAN_A_CDC_TX4_CLK_FS_CTL] = TAPAN_A_CDC_TX4_CLK_FS_CTL__POR,
+	[TAPAN_A_CDC_TX1_DMIC_CTL] = TAPAN_A_CDC_TX1_DMIC_CTL__POR,
+	[TAPAN_A_CDC_TX2_DMIC_CTL] = TAPAN_A_CDC_TX2_DMIC_CTL__POR,
+	[TAPAN_A_CDC_TX3_DMIC_CTL] = TAPAN_A_CDC_TX3_DMIC_CTL__POR,
+	[TAPAN_A_CDC_TX4_DMIC_CTL] = TAPAN_A_CDC_TX4_DMIC_CTL__POR,
+	[TAPAN_A_CDC_DEBUG_B1_CTL] = TAPAN_A_CDC_DEBUG_B1_CTL__POR,
+	[TAPAN_A_CDC_DEBUG_B2_CTL] = TAPAN_A_CDC_DEBUG_B2_CTL__POR,
+	[TAPAN_A_CDC_DEBUG_B3_CTL] = TAPAN_A_CDC_DEBUG_B3_CTL__POR,
+	[TAPAN_A_CDC_DEBUG_B4_CTL] = TAPAN_A_CDC_DEBUG_B4_CTL__POR,
+	[TAPAN_A_CDC_DEBUG_B5_CTL] = TAPAN_A_CDC_DEBUG_B5_CTL__POR,
+	[TAPAN_A_CDC_DEBUG_B6_CTL] = TAPAN_A_CDC_DEBUG_B6_CTL__POR,
+	[TAPAN_A_CDC_DEBUG_B7_CTL] = TAPAN_A_CDC_DEBUG_B7_CTL__POR,
+	[TAPAN_A_CDC_SRC1_PDA_CFG] = TAPAN_A_CDC_SRC1_PDA_CFG__POR,
+	[TAPAN_A_CDC_SRC2_PDA_CFG] = TAPAN_A_CDC_SRC2_PDA_CFG__POR,
+	[TAPAN_A_CDC_SRC1_FS_CTL] = TAPAN_A_CDC_SRC1_FS_CTL__POR,
+	[TAPAN_A_CDC_SRC2_FS_CTL] = TAPAN_A_CDC_SRC2_FS_CTL__POR,
+	[TAPAN_A_CDC_RX1_B1_CTL] = TAPAN_A_CDC_RX1_B1_CTL__POR,
+	[TAPAN_A_CDC_RX2_B1_CTL] = TAPAN_A_CDC_RX2_B1_CTL__POR,
+	[TAPAN_A_CDC_RX3_B1_CTL] = TAPAN_A_CDC_RX3_B1_CTL__POR,
+	[TAPAN_A_CDC_RX4_B1_CTL] = TAPAN_A_CDC_RX4_B1_CTL__POR,
+	[TAPAN_A_CDC_RX1_B2_CTL] = TAPAN_A_CDC_RX1_B2_CTL__POR,
+	[TAPAN_A_CDC_RX2_B2_CTL] = TAPAN_A_CDC_RX2_B2_CTL__POR,
+	[TAPAN_A_CDC_RX3_B2_CTL] = TAPAN_A_CDC_RX3_B2_CTL__POR,
+	[TAPAN_A_CDC_RX4_B2_CTL] = TAPAN_A_CDC_RX4_B2_CTL__POR,
+	[TAPAN_A_CDC_RX1_B3_CTL] = TAPAN_A_CDC_RX1_B3_CTL__POR,
+	[TAPAN_A_CDC_RX2_B3_CTL] = TAPAN_A_CDC_RX2_B3_CTL__POR,
+	[TAPAN_A_CDC_RX3_B3_CTL] = TAPAN_A_CDC_RX3_B3_CTL__POR,
+	[TAPAN_A_CDC_RX4_B3_CTL] = TAPAN_A_CDC_RX4_B3_CTL__POR,
+	[TAPAN_A_CDC_RX1_B4_CTL] = TAPAN_A_CDC_RX1_B4_CTL__POR,
+	[TAPAN_A_CDC_RX2_B4_CTL] = TAPAN_A_CDC_RX2_B4_CTL__POR,
+	[TAPAN_A_CDC_RX3_B4_CTL] = TAPAN_A_CDC_RX3_B4_CTL__POR,
+	[TAPAN_A_CDC_RX4_B4_CTL] = TAPAN_A_CDC_RX4_B4_CTL__POR,
+	[TAPAN_A_CDC_RX1_B5_CTL] = TAPAN_A_CDC_RX1_B5_CTL__POR,
+	[TAPAN_A_CDC_RX2_B5_CTL] = TAPAN_A_CDC_RX2_B5_CTL__POR,
+	[TAPAN_A_CDC_RX3_B5_CTL] = TAPAN_A_CDC_RX3_B5_CTL__POR,
+	[TAPAN_A_CDC_RX4_B5_CTL] = TAPAN_A_CDC_RX4_B5_CTL__POR,
+	[TAPAN_A_CDC_RX1_B6_CTL] = TAPAN_A_CDC_RX1_B6_CTL__POR,
+	[TAPAN_A_CDC_RX2_B6_CTL] = TAPAN_A_CDC_RX2_B6_CTL__POR,
+	[TAPAN_A_CDC_RX3_B6_CTL] = TAPAN_A_CDC_RX3_B6_CTL__POR,
+	[TAPAN_A_CDC_RX4_B6_CTL] = TAPAN_A_CDC_RX4_B6_CTL__POR,
+	[TAPAN_A_CDC_RX1_VOL_CTL_B1_CTL] = TAPAN_A_CDC_RX1_VOL_CTL_B1_CTL__POR,
+	[TAPAN_A_CDC_RX2_VOL_CTL_B1_CTL] = TAPAN_A_CDC_RX2_VOL_CTL_B1_CTL__POR,
+	[TAPAN_A_CDC_RX3_VOL_CTL_B1_CTL] = TAPAN_A_CDC_RX3_VOL_CTL_B1_CTL__POR,
+	[TAPAN_A_CDC_RX4_VOL_CTL_B1_CTL] = TAPAN_A_CDC_RX4_VOL_CTL_B1_CTL__POR,
+	[TAPAN_A_CDC_RX1_VOL_CTL_B2_CTL] = TAPAN_A_CDC_RX1_VOL_CTL_B2_CTL__POR,
+	[TAPAN_A_CDC_RX2_VOL_CTL_B2_CTL] = TAPAN_A_CDC_RX2_VOL_CTL_B2_CTL__POR,
+	[TAPAN_A_CDC_RX3_VOL_CTL_B2_CTL] = TAPAN_A_CDC_RX3_VOL_CTL_B2_CTL__POR,
+	[TAPAN_A_CDC_RX4_VOL_CTL_B2_CTL] = TAPAN_A_CDC_RX4_VOL_CTL_B2_CTL__POR,
+	[TAPAN_A_CDC_CLK_ANC_RESET_CTL] = TAPAN_A_CDC_CLK_ANC_RESET_CTL__POR,
+	[TAPAN_A_CDC_CLK_RX_RESET_CTL] = TAPAN_A_CDC_CLK_RX_RESET_CTL__POR,
+	[TAPAN_A_CDC_CLK_TX_RESET_B1_CTL] =
+			TAPAN_A_CDC_CLK_TX_RESET_B1_CTL__POR,
+	[TAPAN_A_CDC_CLK_TX_RESET_B2_CTL] =
+			TAPAN_A_CDC_CLK_TX_RESET_B2_CTL__POR,
+	[TAPAN_A_CDC_CLK_DMIC_B1_CTL] = TAPAN_A_CDC_CLK_DMIC_B1_CTL__POR,
+	[TAPAN_A_CDC_CLK_DMIC_B2_CTL] = TAPAN_A_CDC_CLK_DMIC_B2_CTL__POR,
+	[TAPAN_A_CDC_CLK_I2S_CTL] = TAPAN_A_CDC_CLK_I2S_CTL__POR,
+	[TAPAN_A_CDC_CLK_OTHR_RESET_B1_CTL] =
+			TAPAN_A_CDC_CLK_OTHR_RESET_B1_CTL__POR,
+	[TAPAN_A_CDC_CLK_OTHR_RESET_B2_CTL] =
+			TAPAN_A_CDC_CLK_OTHR_RESET_B2_CTL__POR,
+	[TAPAN_A_CDC_CLK_TX_CLK_EN_B1_CTL] =
+			TAPAN_A_CDC_CLK_TX_CLK_EN_B1_CTL__POR,
+	[TAPAN_A_CDC_CLK_TX_CLK_EN_B2_CTL] =
+			TAPAN_A_CDC_CLK_TX_CLK_EN_B2_CTL__POR,
+	[TAPAN_A_CDC_CLK_OTHR_CTL] = TAPAN_A_CDC_CLK_OTHR_CTL__POR,
+	[TAPAN_A_CDC_CLK_RDAC_CLK_EN_CTL] =
+			TAPAN_A_CDC_CLK_RDAC_CLK_EN_CTL__POR,
+	[TAPAN_A_CDC_CLK_ANC_CLK_EN_CTL] = TAPAN_A_CDC_CLK_ANC_CLK_EN_CTL__POR,
+	[TAPAN_A_CDC_CLK_RX_B1_CTL] = TAPAN_A_CDC_CLK_RX_B1_CTL__POR,
+	[TAPAN_A_CDC_CLK_RX_B2_CTL] = TAPAN_A_CDC_CLK_RX_B2_CTL__POR,
+	[TAPAN_A_CDC_CLK_MCLK_CTL] = TAPAN_A_CDC_CLK_MCLK_CTL__POR,
+	[TAPAN_A_CDC_CLK_PDM_CTL] = TAPAN_A_CDC_CLK_PDM_CTL__POR,
+	[TAPAN_A_CDC_CLK_SD_CTL] = TAPAN_A_CDC_CLK_SD_CTL__POR,
+	[TAPAN_A_CDC_CLK_POWER_CTL] = TAPAN_A_CDC_CLK_POWER_CTL__POR,
+	[TAPAN_A_CDC_CLSH_B1_CTL] = TAPAN_A_CDC_CLSH_B1_CTL__POR,
+	[TAPAN_A_CDC_CLSH_B2_CTL] = TAPAN_A_CDC_CLSH_B2_CTL__POR,
+	[TAPAN_A_CDC_CLSH_B3_CTL] = TAPAN_A_CDC_CLSH_B3_CTL__POR,
+	[TAPAN_A_CDC_CLSH_BUCK_NCP_VARS] = TAPAN_A_CDC_CLSH_BUCK_NCP_VARS__POR,
+	[TAPAN_A_CDC_CLSH_IDLE_HPH_THSD] = TAPAN_A_CDC_CLSH_IDLE_HPH_THSD__POR,
+	[TAPAN_A_CDC_CLSH_IDLE_EAR_THSD] = TAPAN_A_CDC_CLSH_IDLE_EAR_THSD__POR,
+	[TAPAN_A_CDC_CLSH_FCLKONLY_HPH_THSD] =
+			TAPAN_A_CDC_CLSH_FCLKONLY_HPH_THSD__POR,
+	[TAPAN_A_CDC_CLSH_FCLKONLY_EAR_THSD] =
+			TAPAN_A_CDC_CLSH_FCLKONLY_EAR_THSD__POR,
+	[TAPAN_A_CDC_CLSH_K_ADDR] = TAPAN_A_CDC_CLSH_K_ADDR__POR,
+	[TAPAN_A_CDC_CLSH_K_DATA] = TAPAN_A_CDC_CLSH_K_DATA__POR,
+	[TAPAN_A_CDC_CLSH_I_PA_FACT_HPH_L] =
+			TAPAN_A_CDC_CLSH_I_PA_FACT_HPH_L__POR,
+	[TAPAN_A_CDC_CLSH_I_PA_FACT_HPH_U] =
+			TAPAN_A_CDC_CLSH_I_PA_FACT_HPH_U__POR,
+	[TAPAN_A_CDC_CLSH_I_PA_FACT_EAR_L] =
+			TAPAN_A_CDC_CLSH_I_PA_FACT_EAR_L__POR,
+	[TAPAN_A_CDC_CLSH_I_PA_FACT_EAR_U] =
+			TAPAN_A_CDC_CLSH_I_PA_FACT_EAR_U__POR,
+	[TAPAN_A_CDC_CLSH_V_PA_HD_EAR] = TAPAN_A_CDC_CLSH_V_PA_HD_EAR__POR,
+	[TAPAN_A_CDC_CLSH_V_PA_HD_HPH] = TAPAN_A_CDC_CLSH_V_PA_HD_HPH__POR,
+	[TAPAN_A_CDC_CLSH_V_PA_MIN_EAR] = TAPAN_A_CDC_CLSH_V_PA_MIN_EAR__POR,
+	[TAPAN_A_CDC_CLSH_V_PA_MIN_HPH] = TAPAN_A_CDC_CLSH_V_PA_MIN_HPH__POR,
+	[TAPAN_A_CDC_IIR1_GAIN_B1_CTL] = TAPAN_A_CDC_IIR1_GAIN_B1_CTL__POR,
+	[TAPAN_A_CDC_IIR2_GAIN_B1_CTL] = TAPAN_A_CDC_IIR2_GAIN_B1_CTL__POR,
+	[TAPAN_A_CDC_IIR1_GAIN_B2_CTL] = TAPAN_A_CDC_IIR1_GAIN_B2_CTL__POR,
+	[TAPAN_A_CDC_IIR2_GAIN_B2_CTL] = TAPAN_A_CDC_IIR2_GAIN_B2_CTL__POR,
+	[TAPAN_A_CDC_IIR1_GAIN_B3_CTL] = TAPAN_A_CDC_IIR1_GAIN_B3_CTL__POR,
+	[TAPAN_A_CDC_IIR2_GAIN_B3_CTL] = TAPAN_A_CDC_IIR2_GAIN_B3_CTL__POR,
+	[TAPAN_A_CDC_IIR1_GAIN_B4_CTL] = TAPAN_A_CDC_IIR1_GAIN_B4_CTL__POR,
+	[TAPAN_A_CDC_IIR2_GAIN_B4_CTL] = TAPAN_A_CDC_IIR2_GAIN_B4_CTL__POR,
+	[TAPAN_A_CDC_IIR1_GAIN_B5_CTL] = TAPAN_A_CDC_IIR1_GAIN_B5_CTL__POR,
+	[TAPAN_A_CDC_IIR2_GAIN_B5_CTL] = TAPAN_A_CDC_IIR2_GAIN_B5_CTL__POR,
+	[TAPAN_A_CDC_IIR1_GAIN_B6_CTL] = TAPAN_A_CDC_IIR1_GAIN_B6_CTL__POR,
+	[TAPAN_A_CDC_IIR2_GAIN_B6_CTL] = TAPAN_A_CDC_IIR2_GAIN_B6_CTL__POR,
+	[TAPAN_A_CDC_IIR1_GAIN_B7_CTL] = TAPAN_A_CDC_IIR1_GAIN_B7_CTL__POR,
+	[TAPAN_A_CDC_IIR2_GAIN_B7_CTL] = TAPAN_A_CDC_IIR2_GAIN_B7_CTL__POR,
+	[TAPAN_A_CDC_IIR1_GAIN_B8_CTL] = TAPAN_A_CDC_IIR1_GAIN_B8_CTL__POR,
+	[TAPAN_A_CDC_IIR2_GAIN_B8_CTL] = TAPAN_A_CDC_IIR2_GAIN_B8_CTL__POR,
+	[TAPAN_A_CDC_IIR1_CTL] = TAPAN_A_CDC_IIR1_CTL__POR,
+	[TAPAN_A_CDC_IIR2_CTL] = TAPAN_A_CDC_IIR2_CTL__POR,
+	[TAPAN_A_CDC_IIR1_GAIN_TIMER_CTL] =
+			TAPAN_A_CDC_IIR1_GAIN_TIMER_CTL__POR,
+	[TAPAN_A_CDC_IIR2_GAIN_TIMER_CTL] =
+			TAPAN_A_CDC_IIR2_GAIN_TIMER_CTL__POR,
+	[TAPAN_A_CDC_IIR1_COEF_B1_CTL] = TAPAN_A_CDC_IIR1_COEF_B1_CTL__POR,
+	[TAPAN_A_CDC_IIR2_COEF_B1_CTL] = TAPAN_A_CDC_IIR2_COEF_B1_CTL__POR,
+	[TAPAN_A_CDC_IIR1_COEF_B2_CTL] = TAPAN_A_CDC_IIR1_COEF_B2_CTL__POR,
+	[TAPAN_A_CDC_IIR2_COEF_B2_CTL] = TAPAN_A_CDC_IIR2_COEF_B2_CTL__POR,
+	[TAPAN_A_CDC_TOP_GAIN_UPDATE] = TAPAN_A_CDC_TOP_GAIN_UPDATE__POR,
+	[TAPAN_A_CDC_COMP0_B1_CTL] = TAPAN_A_CDC_COMP0_B1_CTL__POR,
+	[TAPAN_A_CDC_COMP1_B1_CTL] = TAPAN_A_CDC_COMP1_B1_CTL__POR,
+	[TAPAN_A_CDC_COMP2_B1_CTL] = TAPAN_A_CDC_COMP2_B1_CTL__POR,
+	[TAPAN_A_CDC_COMP0_B2_CTL] = TAPAN_A_CDC_COMP0_B2_CTL__POR,
+	[TAPAN_A_CDC_COMP1_B2_CTL] = TAPAN_A_CDC_COMP1_B2_CTL__POR,
+	[TAPAN_A_CDC_COMP2_B2_CTL] = TAPAN_A_CDC_COMP2_B2_CTL__POR,
+	[TAPAN_A_CDC_COMP0_B3_CTL] = TAPAN_A_CDC_COMP0_B3_CTL__POR,
+	[TAPAN_A_CDC_COMP1_B3_CTL] = TAPAN_A_CDC_COMP1_B3_CTL__POR,
+	[TAPAN_A_CDC_COMP2_B3_CTL] = TAPAN_A_CDC_COMP2_B3_CTL__POR,
+	[TAPAN_A_CDC_COMP0_B4_CTL] = TAPAN_A_CDC_COMP0_B4_CTL__POR,
+	[TAPAN_A_CDC_COMP1_B4_CTL] = TAPAN_A_CDC_COMP1_B4_CTL__POR,
+	[TAPAN_A_CDC_COMP2_B4_CTL] = TAPAN_A_CDC_COMP2_B4_CTL__POR,
+	[TAPAN_A_CDC_COMP0_B5_CTL] = TAPAN_A_CDC_COMP0_B5_CTL__POR,
+	[TAPAN_A_CDC_COMP1_B5_CTL] = TAPAN_A_CDC_COMP1_B5_CTL__POR,
+	[TAPAN_A_CDC_COMP2_B5_CTL] = TAPAN_A_CDC_COMP2_B5_CTL__POR,
+	[TAPAN_A_CDC_COMP0_B6_CTL] = TAPAN_A_CDC_COMP0_B6_CTL__POR,
+	[TAPAN_A_CDC_COMP1_B6_CTL] = TAPAN_A_CDC_COMP1_B6_CTL__POR,
+	[TAPAN_A_CDC_COMP2_B6_CTL] = TAPAN_A_CDC_COMP2_B6_CTL__POR,
+	[TAPAN_A_CDC_COMP0_SHUT_DOWN_STATUS] =
+			TAPAN_A_CDC_COMP0_SHUT_DOWN_STATUS__POR,
+	[TAPAN_A_CDC_COMP1_SHUT_DOWN_STATUS] =
+			TAPAN_A_CDC_COMP1_SHUT_DOWN_STATUS__POR,
+	[TAPAN_A_CDC_COMP2_SHUT_DOWN_STATUS] =
+			TAPAN_A_CDC_COMP2_SHUT_DOWN_STATUS__POR,
+	[TAPAN_A_CDC_COMP0_FS_CFG] = TAPAN_A_CDC_COMP0_FS_CFG__POR,
+	[TAPAN_A_CDC_COMP1_FS_CFG] = TAPAN_A_CDC_COMP1_FS_CFG__POR,
+	[TAPAN_A_CDC_COMP2_FS_CFG] = TAPAN_A_CDC_COMP2_FS_CFG__POR,
+	[TAPAN_A_CDC_CONN_RX1_B1_CTL] = TAPAN_A_CDC_CONN_RX1_B1_CTL__POR,
+	[TAPAN_A_CDC_CONN_RX1_B2_CTL] = TAPAN_A_CDC_CONN_RX1_B2_CTL__POR,
+	[TAPAN_A_CDC_CONN_RX1_B3_CTL] = TAPAN_A_CDC_CONN_RX1_B3_CTL__POR,
+	[TAPAN_A_CDC_CONN_RX2_B1_CTL] = TAPAN_A_CDC_CONN_RX2_B1_CTL__POR,
+	[TAPAN_A_CDC_CONN_RX2_B2_CTL] = TAPAN_A_CDC_CONN_RX2_B2_CTL__POR,
+	[TAPAN_A_CDC_CONN_RX2_B3_CTL] = TAPAN_A_CDC_CONN_RX2_B3_CTL__POR,
+	[TAPAN_A_CDC_CONN_RX3_B1_CTL] = TAPAN_A_CDC_CONN_RX3_B1_CTL__POR,
+	[TAPAN_A_CDC_CONN_RX3_B2_CTL] = TAPAN_A_CDC_CONN_RX3_B2_CTL__POR,
+	[TAPAN_A_CDC_CONN_RX4_B1_CTL] = TAPAN_A_CDC_CONN_RX4_B1_CTL__POR,
+	[TAPAN_A_CDC_CONN_RX4_B2_CTL] = TAPAN_A_CDC_CONN_RX4_B2_CTL__POR,
+	[TAPAN_A_CDC_CONN_RX4_B3_CTL] = TAPAN_A_CDC_CONN_RX4_B3_CTL__POR,
+	[TAPAN_A_CDC_CONN_ANC_B1_CTL] = TAPAN_A_CDC_CONN_ANC_B1_CTL__POR,
+	[TAPAN_A_CDC_CONN_ANC_B2_CTL] = TAPAN_A_CDC_CONN_ANC_B2_CTL__POR,
+	[TAPAN_A_CDC_CONN_TX_B1_CTL] = TAPAN_A_CDC_CONN_TX_B1_CTL__POR,
+	[TAPAN_A_CDC_CONN_TX_B2_CTL] = TAPAN_A_CDC_CONN_TX_B2_CTL__POR,
+	[TAPAN_A_CDC_CONN_TX_B3_CTL] = TAPAN_A_CDC_CONN_TX_B3_CTL__POR,
+	[TAPAN_A_CDC_CONN_TX_B4_CTL] = TAPAN_A_CDC_CONN_TX_B4_CTL__POR,
+	[TAPAN_A_CDC_CONN_EQ1_B1_CTL] = TAPAN_A_CDC_CONN_EQ1_B1_CTL__POR,
+	[TAPAN_A_CDC_CONN_EQ1_B2_CTL] = TAPAN_A_CDC_CONN_EQ1_B2_CTL__POR,
+	[TAPAN_A_CDC_CONN_EQ1_B3_CTL] = TAPAN_A_CDC_CONN_EQ1_B3_CTL__POR,
+	[TAPAN_A_CDC_CONN_EQ1_B4_CTL] = TAPAN_A_CDC_CONN_EQ1_B4_CTL__POR,
+	[TAPAN_A_CDC_CONN_EQ2_B1_CTL] = TAPAN_A_CDC_CONN_EQ2_B1_CTL__POR,
+	[TAPAN_A_CDC_CONN_EQ2_B2_CTL] = TAPAN_A_CDC_CONN_EQ2_B2_CTL__POR,
+	[TAPAN_A_CDC_CONN_EQ2_B3_CTL] = TAPAN_A_CDC_CONN_EQ2_B3_CTL__POR,
+	[TAPAN_A_CDC_CONN_EQ2_B4_CTL] = TAPAN_A_CDC_CONN_EQ2_B4_CTL__POR,
+	[TAPAN_A_CDC_CONN_SRC1_B1_CTL] = TAPAN_A_CDC_CONN_SRC1_B1_CTL__POR,
+	[TAPAN_A_CDC_CONN_SRC1_B2_CTL] = TAPAN_A_CDC_CONN_SRC1_B2_CTL__POR,
+	[TAPAN_A_CDC_CONN_SRC2_B1_CTL] = TAPAN_A_CDC_CONN_SRC2_B1_CTL__POR,
+	[TAPAN_A_CDC_CONN_SRC2_B2_CTL] = TAPAN_A_CDC_CONN_SRC2_B2_CTL__POR,
+	[TAPAN_A_CDC_CONN_TX_SB_B1_CTL] = TAPAN_A_CDC_CONN_TX_SB_B1_CTL__POR,
+	[TAPAN_A_CDC_CONN_TX_SB_B2_CTL] = TAPAN_A_CDC_CONN_TX_SB_B2_CTL__POR,
+	[TAPAN_A_CDC_CONN_TX_SB_B3_CTL] = TAPAN_A_CDC_CONN_TX_SB_B3_CTL__POR,
+	[TAPAN_A_CDC_CONN_TX_SB_B4_CTL] = TAPAN_A_CDC_CONN_TX_SB_B4_CTL__POR,
+	[TAPAN_A_CDC_CONN_TX_SB_B5_CTL] = TAPAN_A_CDC_CONN_TX_SB_B5_CTL__POR,
+	[TAPAN_A_CDC_CONN_TX_SB_B11_CTL] = TAPAN_A_CDC_CONN_TX_SB_B11_CTL__POR,
+	[TAPAN_A_CDC_CONN_RX_SB_B1_CTL] = TAPAN_A_CDC_CONN_RX_SB_B1_CTL__POR,
+	[TAPAN_A_CDC_CONN_RX_SB_B2_CTL] = TAPAN_A_CDC_CONN_RX_SB_B2_CTL__POR,
+	[TAPAN_A_CDC_CONN_CLSH_CTL] = TAPAN_A_CDC_CONN_CLSH_CTL__POR,
+	[TAPAN_A_CDC_CONN_MISC] = TAPAN_A_CDC_CONN_MISC__POR,
+	[TAPAN_A_CDC_MBHC_EN_CTL] = TAPAN_A_CDC_MBHC_EN_CTL__POR,
+	[TAPAN_A_CDC_MBHC_FIR_B1_CFG] = TAPAN_A_CDC_MBHC_FIR_B1_CFG__POR,
+	[TAPAN_A_CDC_MBHC_FIR_B2_CFG] = TAPAN_A_CDC_MBHC_FIR_B2_CFG__POR,
+	[TAPAN_A_CDC_MBHC_TIMER_B1_CTL] = TAPAN_A_CDC_MBHC_TIMER_B1_CTL__POR,
+	[TAPAN_A_CDC_MBHC_TIMER_B2_CTL] = TAPAN_A_CDC_MBHC_TIMER_B2_CTL__POR,
+	[TAPAN_A_CDC_MBHC_TIMER_B3_CTL] = TAPAN_A_CDC_MBHC_TIMER_B3_CTL__POR,
+	[TAPAN_A_CDC_MBHC_TIMER_B4_CTL] = TAPAN_A_CDC_MBHC_TIMER_B4_CTL__POR,
+	[TAPAN_A_CDC_MBHC_TIMER_B5_CTL] = TAPAN_A_CDC_MBHC_TIMER_B5_CTL__POR,
+	[TAPAN_A_CDC_MBHC_TIMER_B6_CTL] = TAPAN_A_CDC_MBHC_TIMER_B6_CTL__POR,
+	[TAPAN_A_CDC_MBHC_B1_STATUS] = TAPAN_A_CDC_MBHC_B1_STATUS__POR,
+	[TAPAN_A_CDC_MBHC_B2_STATUS] = TAPAN_A_CDC_MBHC_B2_STATUS__POR,
+	[TAPAN_A_CDC_MBHC_B3_STATUS] = TAPAN_A_CDC_MBHC_B3_STATUS__POR,
+	[TAPAN_A_CDC_MBHC_B4_STATUS] = TAPAN_A_CDC_MBHC_B4_STATUS__POR,
+	[TAPAN_A_CDC_MBHC_B5_STATUS] = TAPAN_A_CDC_MBHC_B5_STATUS__POR,
+	[TAPAN_A_CDC_MBHC_B1_CTL] = TAPAN_A_CDC_MBHC_B1_CTL__POR,
+	[TAPAN_A_CDC_MBHC_B2_CTL] = TAPAN_A_CDC_MBHC_B2_CTL__POR,
+	[TAPAN_A_CDC_MBHC_VOLT_B1_CTL] = TAPAN_A_CDC_MBHC_VOLT_B1_CTL__POR,
+	[TAPAN_A_CDC_MBHC_VOLT_B2_CTL] = TAPAN_A_CDC_MBHC_VOLT_B2_CTL__POR,
+	[TAPAN_A_CDC_MBHC_VOLT_B3_CTL] = TAPAN_A_CDC_MBHC_VOLT_B3_CTL__POR,
+	[TAPAN_A_CDC_MBHC_VOLT_B4_CTL] = TAPAN_A_CDC_MBHC_VOLT_B4_CTL__POR,
+	[TAPAN_A_CDC_MBHC_VOLT_B5_CTL] = TAPAN_A_CDC_MBHC_VOLT_B5_CTL__POR,
+	[TAPAN_A_CDC_MBHC_VOLT_B6_CTL] = TAPAN_A_CDC_MBHC_VOLT_B6_CTL__POR,
+	[TAPAN_A_CDC_MBHC_VOLT_B7_CTL] = TAPAN_A_CDC_MBHC_VOLT_B7_CTL__POR,
+	[TAPAN_A_CDC_MBHC_VOLT_B8_CTL] = TAPAN_A_CDC_MBHC_VOLT_B8_CTL__POR,
+	[TAPAN_A_CDC_MBHC_VOLT_B9_CTL] = TAPAN_A_CDC_MBHC_VOLT_B9_CTL__POR,
+	[TAPAN_A_CDC_MBHC_VOLT_B10_CTL] = TAPAN_A_CDC_MBHC_VOLT_B10_CTL__POR,
+	[TAPAN_A_CDC_MBHC_VOLT_B11_CTL] = TAPAN_A_CDC_MBHC_VOLT_B11_CTL__POR,
+	[TAPAN_A_CDC_MBHC_VOLT_B12_CTL] = TAPAN_A_CDC_MBHC_VOLT_B12_CTL__POR,
+	[TAPAN_A_CDC_MBHC_CLK_CTL] = TAPAN_A_CDC_MBHC_CLK_CTL__POR,
+	[TAPAN_A_CDC_MBHC_INT_CTL] = TAPAN_A_CDC_MBHC_INT_CTL__POR,
+	[TAPAN_A_CDC_MBHC_DEBUG_CTL] = TAPAN_A_CDC_MBHC_DEBUG_CTL__POR,
+	[TAPAN_A_CDC_MBHC_SPARE] = TAPAN_A_CDC_MBHC_SPARE__POR,
+};
diff --git a/sound/soc/codecs/wcd9306.c b/sound/soc/codecs/wcd9306.c
new file mode 100644
index 0000000..25d3f56
--- /dev/null
+++ b/sound/soc/codecs/wcd9306.c
@@ -0,0 +1,3856 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/firmware.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/printk.h>
+#include <linux/ratelimit.h>
+#include <linux/debugfs.h>
+#include <linux/mfd/wcd9xxx/core.h>
+#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
+#include <linux/mfd/wcd9xxx/wcd9306_registers.h>
+#include <linux/mfd/wcd9xxx/pdata.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/tlv.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/pm_runtime.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include "wcd9306.h"
+#include "wcd9xxx-resmgr.h"
+
+#define WCD9306_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
+			SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
+			SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
+
+#define NUM_DECIMATORS 4
+#define NUM_INTERPOLATORS 4
+#define BITS_PER_REG 8
+#define TAPAN_TX_PORT_NUMBER	16
+
+#define TAPAN_I2S_MASTER_MODE_MASK 0x08
+
+enum {
+	AIF1_PB = 0,
+	AIF1_CAP,
+	AIF2_PB,
+	AIF2_CAP,
+	AIF3_PB,
+	AIF3_CAP,
+	NUM_CODEC_DAIS,
+};
+
+enum {
+	RX_MIX1_INP_SEL_ZERO = 0,
+	RX_MIX1_INP_SEL_SRC1,
+	RX_MIX1_INP_SEL_SRC2,
+	RX_MIX1_INP_SEL_IIR1,
+	RX_MIX1_INP_SEL_IIR2,
+	RX_MIX1_INP_SEL_RX1,
+	RX_MIX1_INP_SEL_RX2,
+	RX_MIX1_INP_SEL_RX3,
+	RX_MIX1_INP_SEL_RX4,
+	RX_MIX1_INP_SEL_RX5,
+	RX_MIX1_INP_SEL_RX6,
+	RX_MIX1_INP_SEL_RX7,
+	RX_MIX1_INP_SEL_AUXRX,
+};
+
+#define TAPAN_COMP_DIGITAL_GAIN_OFFSET 3
+
+static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
+static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1);
+static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
+static struct snd_soc_dai_driver tapan_dai[];
+static const DECLARE_TLV_DB_SCALE(aux_pga_gain, 0, 2, 0);
+
+/* Codec supports 2 IIR filters */
+enum {
+	IIR1 = 0,
+	IIR2,
+	IIR_MAX,
+};
+/* Codec supports 5 bands */
+enum {
+	BAND1 = 0,
+	BAND2,
+	BAND3,
+	BAND4,
+	BAND5,
+	BAND_MAX,
+};
+
+enum {
+	COMPANDER_1 = 0,
+	COMPANDER_2,
+	COMPANDER_MAX,
+};
+
+enum {
+	COMPANDER_FS_8KHZ = 0,
+	COMPANDER_FS_16KHZ,
+	COMPANDER_FS_32KHZ,
+	COMPANDER_FS_48KHZ,
+	COMPANDER_FS_96KHZ,
+	COMPANDER_FS_192KHZ,
+	COMPANDER_FS_MAX,
+};
+
+struct comp_sample_dependent_params {
+	u32 peak_det_timeout;
+	u32 rms_meter_div_fact;
+	u32 rms_meter_resamp_fact;
+};
+
+struct hpf_work {
+	struct tapan_priv *tapan;
+	u32 decimator;
+	u8 tx_hpf_cut_of_freq;
+	struct delayed_work dwork;
+};
+
+static struct hpf_work tx_hpf_work[NUM_DECIMATORS];
+
+static const struct wcd9xxx_ch tapan_rx_chs[TAPAN_RX_MAX] = {
+	WCD9XXX_CH(16, 0),
+	WCD9XXX_CH(17, 1),
+	WCD9XXX_CH(18, 2),
+	WCD9XXX_CH(19, 3),
+	WCD9XXX_CH(20, 4),
+};
+
+static const struct wcd9xxx_ch tapan_tx_chs[TAPAN_TX_MAX] = {
+	WCD9XXX_CH(0, 0),
+	WCD9XXX_CH(1, 1),
+	WCD9XXX_CH(2, 2),
+	WCD9XXX_CH(3, 3),
+	WCD9XXX_CH(4, 4),
+};
+
+static const u32 vport_check_table[NUM_CODEC_DAIS] = {
+	0,					/* AIF1_PB */
+	(1 << AIF2_CAP) | (1 << AIF3_CAP),	/* AIF1_CAP */
+	0,					/* AIF2_PB */
+	(1 << AIF1_CAP) | (1 << AIF3_CAP),	/* AIF2_CAP */
+	0,					/* AIF2_PB */
+	(1 << AIF1_CAP) | (1 << AIF2_CAP),	/* AIF2_CAP */
+};
+
+struct tapan_priv {
+	struct snd_soc_codec *codec;
+	u32 adc_count;
+	u32 rx_bias_count;
+	s32 dmic_1_2_clk_cnt;
+	s32 dmic_3_4_clk_cnt;
+	s32 dmic_5_6_clk_cnt;
+
+	u32 anc_slot;
+
+	/*track tapan interface type*/
+	u8 intf_type;
+
+	/* num of slim ports required */
+	struct wcd9xxx_codec_dai_data  dai[NUM_CODEC_DAIS];
+
+	/* Maintain the status of AUX PGA */
+	int aux_pga_cnt;
+	u8 aux_l_gain;
+	u8 aux_r_gain;
+
+	/* resmgr module */
+	struct wcd9xxx_resmgr resmgr;
+	/* mbhc module */
+	struct wcd9xxx_mbhc mbhc;
+};
+
+static const u32 comp_shift[] = {
+	0,
+	2,
+};
+
+static unsigned short rx_digital_gain_reg[] = {
+	TAPAN_A_CDC_RX1_VOL_CTL_B2_CTL,
+	TAPAN_A_CDC_RX2_VOL_CTL_B2_CTL,
+	TAPAN_A_CDC_RX3_VOL_CTL_B2_CTL,
+	TAPAN_A_CDC_RX4_VOL_CTL_B2_CTL,
+};
+
+static unsigned short tx_digital_gain_reg[] = {
+	TAPAN_A_CDC_TX1_VOL_CTL_GAIN,
+	TAPAN_A_CDC_TX2_VOL_CTL_GAIN,
+	TAPAN_A_CDC_TX3_VOL_CTL_GAIN,
+	TAPAN_A_CDC_TX4_VOL_CTL_GAIN,
+};
+
+static int tapan_codec_enable_class_h_clk(struct snd_soc_dapm_widget *w,
+		struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+
+	dev_dbg(codec->dev, "%s %s  %d\n", __func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		snd_soc_update_bits(codec, TAPAN_A_CDC_CLSH_B1_CTL, 0x01, 0x01);
+		break;
+	case SND_SOC_DAPM_PRE_PMD:
+		snd_soc_update_bits(codec, TAPAN_A_BUCK_MODE_1, 0x80, 0x00);
+		snd_soc_update_bits(codec, TAPAN_A_CDC_CLSH_B1_CTL, 0x01, 0x00);
+		break;
+	}
+	return 0;
+}
+
+static int tapan_codec_enable_class_h(struct snd_soc_dapm_widget *w,
+		struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+
+	dev_dbg(codec->dev, "%s %s  %d\n", __func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		snd_soc_update_bits(codec, TAPAN_A_BUCK_MODE_5, 0x02, 0x02);
+		snd_soc_update_bits(codec, TAPAN_A_BUCK_MODE_4, 0xFF, 0xFF);
+		snd_soc_update_bits(codec, TAPAN_A_BUCK_MODE_1, 0x04, 0x04);
+		snd_soc_update_bits(codec, TAPAN_A_BUCK_MODE_1, 0x04, 0x00);
+		snd_soc_update_bits(codec, TAPAN_A_BUCK_MODE_3, 0x04, 0x00);
+		snd_soc_update_bits(codec, TAPAN_A_BUCK_MODE_3, 0x08, 0x00);
+		snd_soc_update_bits(codec, TAPAN_A_BUCK_MODE_1, 0x80, 0x80);
+		usleep_range(1000, 1000);
+		break;
+	}
+	return 0;
+}
+
+static int tapan_codec_enable_charge_pump(struct snd_soc_dapm_widget *w,
+		struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+
+	dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		snd_soc_update_bits(codec, w->reg, 0x01, 0x01);
+		snd_soc_update_bits(codec, w->reg, 0x40, 0x00);
+		snd_soc_update_bits(codec, TAPAN_A_NCP_STATIC, 0x0f, 0x01);
+		break;
+
+	case SND_SOC_DAPM_POST_PMU:
+		usleep_range(1000, 1000);
+		break;
+
+	case SND_SOC_DAPM_PRE_PMD:
+	    snd_soc_update_bits(codec, w->reg, 0x01, 0x00);
+		snd_soc_update_bits(codec, w->reg, 0x40, 0x40);
+		snd_soc_update_bits(codec, TAPAN_A_NCP_STATIC, 0x0f, 0x08);
+		break;
+	}
+	return 0;
+}
+
+static int tapan_pa_gain_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	u8 ear_pa_gain;
+	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  {
+		pr_err("%s: ERROR: Unsupported Ear Gain = 0x%x\n",
+				__func__, ear_pa_gain);
+		return -EINVAL;
+	}
+
+	dev_dbg(codec->dev, "%s: ear_pa_gain = 0x%x\n", __func__, ear_pa_gain);
+
+	return 0;
+}
+
+static int tapan_pa_gain_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	u8 ear_pa_gain;
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+
+	dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0]  = %ld\n",
+			 __func__, ucontrol->value.integer.value[0]);
+
+	switch (ucontrol->value.integer.value[0]) {
+	case 0:
+		ear_pa_gain = 0x00;
+		break;
+	case 1:
+		ear_pa_gain = 0x80;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	snd_soc_update_bits(codec, TAPAN_A_RX_EAR_GAIN, 0xE0, ear_pa_gain);
+	return 0;
+}
+
+static int tapan_get_iir_enable_audio_mixer(
+					struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	int iir_idx = ((struct soc_multi_mixer_control *)
+					kcontrol->private_value)->reg;
+	int band_idx = ((struct soc_multi_mixer_control *)
+					kcontrol->private_value)->shift;
+
+	ucontrol->value.integer.value[0] =
+		snd_soc_read(codec, (TAPAN_A_CDC_IIR1_CTL + 16 * iir_idx)) &
+		(1 << band_idx);
+
+	dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__,
+		iir_idx, band_idx,
+		(uint32_t)ucontrol->value.integer.value[0]);
+	return 0;
+}
+
+static int tapan_put_iir_enable_audio_mixer(
+					struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	int iir_idx = ((struct soc_multi_mixer_control *)
+					kcontrol->private_value)->reg;
+	int band_idx = ((struct soc_multi_mixer_control *)
+					kcontrol->private_value)->shift;
+	int value = ucontrol->value.integer.value[0];
+
+	/* Mask first 5 bits, 6-8 are reserved */
+	snd_soc_update_bits(codec, (TAPAN_A_CDC_IIR1_CTL + 16 * iir_idx),
+		(1 << band_idx), (value << band_idx));
+
+	dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__,
+		iir_idx, band_idx, value);
+	return 0;
+}
+static uint32_t get_iir_band_coeff(struct snd_soc_codec *codec,
+				int iir_idx, int band_idx,
+				int coeff_idx)
+{
+	/* Address does not automatically update if reading */
+	snd_soc_write(codec,
+		(TAPAN_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
+		(band_idx * BAND_MAX + coeff_idx) & 0x1F);
+
+	/* Mask bits top 2 bits since they are reserved */
+	return ((snd_soc_read(codec,
+		(TAPAN_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx)) << 24)) &
+		0x3FFFFFFF;
+}
+
+static int tapan_get_iir_band_audio_mixer(
+					struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	int iir_idx = ((struct soc_multi_mixer_control *)
+					kcontrol->private_value)->reg;
+	int band_idx = ((struct soc_multi_mixer_control *)
+					kcontrol->private_value)->shift;
+
+	ucontrol->value.integer.value[0] =
+		get_iir_band_coeff(codec, iir_idx, band_idx, 0);
+	ucontrol->value.integer.value[1] =
+		get_iir_band_coeff(codec, iir_idx, band_idx, 1);
+	ucontrol->value.integer.value[2] =
+		get_iir_band_coeff(codec, iir_idx, band_idx, 2);
+	ucontrol->value.integer.value[3] =
+		get_iir_band_coeff(codec, iir_idx, band_idx, 3);
+	ucontrol->value.integer.value[4] =
+		get_iir_band_coeff(codec, iir_idx, band_idx, 4);
+
+	dev_dbg(codec->dev, "%s: IIR #%d band #%d b0 = 0x%x\n"
+		"%s: IIR #%d band #%d b1 = 0x%x\n"
+		"%s: IIR #%d band #%d b2 = 0x%x\n"
+		"%s: IIR #%d band #%d a1 = 0x%x\n"
+		"%s: IIR #%d band #%d a2 = 0x%x\n",
+		__func__, iir_idx, band_idx,
+		(uint32_t)ucontrol->value.integer.value[0],
+		__func__, iir_idx, band_idx,
+		(uint32_t)ucontrol->value.integer.value[1],
+		__func__, iir_idx, band_idx,
+		(uint32_t)ucontrol->value.integer.value[2],
+		__func__, iir_idx, band_idx,
+		(uint32_t)ucontrol->value.integer.value[3],
+		__func__, iir_idx, band_idx,
+		(uint32_t)ucontrol->value.integer.value[4]);
+	return 0;
+}
+
+static void set_iir_band_coeff(struct snd_soc_codec *codec,
+				int iir_idx, int band_idx,
+				int coeff_idx, uint32_t value)
+{
+	/* Mask top 3 bits, 6-8 are reserved */
+	/* Update address manually each time */
+	snd_soc_write(codec,
+		(TAPAN_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
+		(band_idx * BAND_MAX + coeff_idx) & 0x1F);
+
+	/* Mask top 2 bits, 7-8 are reserved */
+	snd_soc_write(codec,
+		(TAPAN_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx),
+		(value >> 24) & 0x3F);
+
+}
+
+static int tapan_put_iir_band_audio_mixer(
+					struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	int iir_idx = ((struct soc_multi_mixer_control *)
+					kcontrol->private_value)->reg;
+	int band_idx = ((struct soc_multi_mixer_control *)
+					kcontrol->private_value)->shift;
+
+	set_iir_band_coeff(codec, iir_idx, band_idx, 0,
+				ucontrol->value.integer.value[0]);
+	set_iir_band_coeff(codec, iir_idx, band_idx, 1,
+				ucontrol->value.integer.value[1]);
+	set_iir_band_coeff(codec, iir_idx, band_idx, 2,
+				ucontrol->value.integer.value[2]);
+	set_iir_band_coeff(codec, iir_idx, band_idx, 3,
+				ucontrol->value.integer.value[3]);
+	set_iir_band_coeff(codec, iir_idx, band_idx, 4,
+				ucontrol->value.integer.value[4]);
+
+	dev_dbg(codec->dev, "%s: IIR #%d band #%d b0 = 0x%x\n"
+		"%s: IIR #%d band #%d b1 = 0x%x\n"
+		"%s: IIR #%d band #%d b2 = 0x%x\n"
+		"%s: IIR #%d band #%d a1 = 0x%x\n"
+		"%s: IIR #%d band #%d a2 = 0x%x\n",
+		__func__, iir_idx, band_idx,
+		get_iir_band_coeff(codec, iir_idx, band_idx, 0),
+		__func__, iir_idx, band_idx,
+		get_iir_band_coeff(codec, iir_idx, band_idx, 1),
+		__func__, iir_idx, band_idx,
+		get_iir_band_coeff(codec, iir_idx, band_idx, 2),
+		__func__, iir_idx, band_idx,
+		get_iir_band_coeff(codec, iir_idx, band_idx, 3),
+		__func__, iir_idx, band_idx,
+		get_iir_band_coeff(codec, iir_idx, band_idx, 4));
+	return 0;
+}
+
+static const char * const tapan_ear_pa_gain_text[] = {"POS_6_DB", "POS_2_DB"};
+static const struct soc_enum tapan_ear_pa_gain_enum[] = {
+		SOC_ENUM_SINGLE_EXT(2, tapan_ear_pa_gain_text),
+};
+
+/*cut of frequency for high pass filter*/
+static const char * const cf_text[] = {
+	"MIN_3DB_4Hz", "MIN_3DB_75Hz", "MIN_3DB_150Hz"
+};
+
+static const struct soc_enum cf_dec1_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_TX1_MUX_CTL, 4, 3, cf_text);
+
+static const struct soc_enum cf_dec2_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_TX2_MUX_CTL, 4, 3, cf_text);
+
+static const struct soc_enum cf_dec3_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_TX3_MUX_CTL, 4, 3, cf_text);
+
+static const struct soc_enum cf_dec4_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_TX4_MUX_CTL, 4, 3, cf_text);
+
+static const struct soc_enum cf_rxmix1_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_RX1_B4_CTL, 0, 3, cf_text);
+
+static const struct soc_enum cf_rxmix2_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_RX2_B4_CTL, 0, 3, cf_text);
+
+static const struct soc_enum cf_rxmix3_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_RX3_B4_CTL, 0, 3, cf_text);
+
+static const struct soc_enum cf_rxmix4_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_RX4_B4_CTL, 0, 3, cf_text);
+
+static const struct snd_kcontrol_new tapan_snd_controls[] = {
+
+	SOC_ENUM_EXT("EAR PA Gain", tapan_ear_pa_gain_enum[0],
+		tapan_pa_gain_get, tapan_pa_gain_put),
+
+	SOC_SINGLE_TLV("LINEOUT1 Volume", TAPAN_A_RX_LINE_1_GAIN, 0, 12, 1,
+		line_gain),
+	SOC_SINGLE_TLV("LINEOUT2 Volume", TAPAN_A_RX_LINE_2_GAIN, 0, 12, 1,
+		line_gain),
+
+	SOC_SINGLE_TLV("HPHL Volume", TAPAN_A_RX_HPH_L_GAIN, 0, 12, 1,
+		line_gain),
+	SOC_SINGLE_TLV("HPHR Volume", TAPAN_A_RX_HPH_R_GAIN, 0, 12, 1,
+		line_gain),
+
+	SOC_SINGLE_S8_TLV("RX1 Digital Volume", TAPAN_A_CDC_RX1_VOL_CTL_B2_CTL,
+		-84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("RX2 Digital Volume", TAPAN_A_CDC_RX2_VOL_CTL_B2_CTL,
+		-84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("RX3 Digital Volume", TAPAN_A_CDC_RX3_VOL_CTL_B2_CTL,
+		-84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("RX4 Digital Volume", TAPAN_A_CDC_RX4_VOL_CTL_B2_CTL,
+		-84, 40, digital_gain),
+
+	SOC_SINGLE_S8_TLV("DEC1 Volume", TAPAN_A_CDC_TX1_VOL_CTL_GAIN, -84, 40,
+		digital_gain),
+	SOC_SINGLE_S8_TLV("DEC2 Volume", TAPAN_A_CDC_TX2_VOL_CTL_GAIN, -84, 40,
+		digital_gain),
+	SOC_SINGLE_S8_TLV("DEC3 Volume", TAPAN_A_CDC_TX3_VOL_CTL_GAIN, -84, 40,
+		digital_gain),
+	SOC_SINGLE_S8_TLV("DEC4 Volume", TAPAN_A_CDC_TX4_VOL_CTL_GAIN, -84, 40,
+		digital_gain),
+
+	SOC_SINGLE_S8_TLV("IIR1 INP1 Volume", TAPAN_A_CDC_IIR1_GAIN_B1_CTL, -84,
+		40, digital_gain),
+	SOC_SINGLE_S8_TLV("IIR1 INP2 Volume", TAPAN_A_CDC_IIR1_GAIN_B2_CTL, -84,
+		40, digital_gain),
+	SOC_SINGLE_S8_TLV("IIR1 INP3 Volume", TAPAN_A_CDC_IIR1_GAIN_B3_CTL, -84,
+		40, digital_gain),
+	SOC_SINGLE_S8_TLV("IIR1 INP4 Volume", TAPAN_A_CDC_IIR1_GAIN_B4_CTL, -84,
+		40, digital_gain),
+
+	SOC_SINGLE("MICBIAS1 CAPLESS Switch", TAPAN_A_MICB_1_CTL, 4, 1, 1),
+	SOC_SINGLE("MICBIAS2 CAPLESS Switch", TAPAN_A_MICB_2_CTL, 4, 1, 1),
+	SOC_SINGLE("MICBIAS3 CAPLESS Switch", TAPAN_A_MICB_3_CTL, 4, 1, 1),
+
+	SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
+	SOC_ENUM("TX2 HPF cut off", cf_dec2_enum),
+	SOC_ENUM("TX3 HPF cut off", cf_dec3_enum),
+	SOC_ENUM("TX4 HPF cut off", cf_dec4_enum),
+
+	SOC_SINGLE("TX1 HPF Switch", TAPAN_A_CDC_TX1_MUX_CTL, 3, 1, 0),
+	SOC_SINGLE("TX2 HPF Switch", TAPAN_A_CDC_TX2_MUX_CTL, 3, 1, 0),
+	SOC_SINGLE("TX3 HPF Switch", TAPAN_A_CDC_TX3_MUX_CTL, 3, 1, 0),
+	SOC_SINGLE("TX4 HPF Switch", TAPAN_A_CDC_TX4_MUX_CTL, 3, 1, 0),
+
+	SOC_SINGLE("RX1 HPF Switch", TAPAN_A_CDC_RX1_B5_CTL, 2, 1, 0),
+	SOC_SINGLE("RX2 HPF Switch", TAPAN_A_CDC_RX2_B5_CTL, 2, 1, 0),
+	SOC_SINGLE("RX3 HPF Switch", TAPAN_A_CDC_RX3_B5_CTL, 2, 1, 0),
+	SOC_SINGLE("RX4 HPF Switch", TAPAN_A_CDC_RX4_B5_CTL, 2, 1, 0),
+
+	SOC_ENUM("RX1 HPF cut off", cf_rxmix1_enum),
+	SOC_ENUM("RX2 HPF cut off", cf_rxmix2_enum),
+	SOC_ENUM("RX3 HPF cut off", cf_rxmix3_enum),
+	SOC_ENUM("RX4 HPF cut off", cf_rxmix4_enum),
+
+	SOC_SINGLE_EXT("IIR1 Enable Band1", IIR1, BAND1, 1, 0,
+	tapan_get_iir_enable_audio_mixer, tapan_put_iir_enable_audio_mixer),
+	SOC_SINGLE_EXT("IIR1 Enable Band2", IIR1, BAND2, 1, 0,
+	tapan_get_iir_enable_audio_mixer, tapan_put_iir_enable_audio_mixer),
+	SOC_SINGLE_EXT("IIR1 Enable Band3", IIR1, BAND3, 1, 0,
+	tapan_get_iir_enable_audio_mixer, tapan_put_iir_enable_audio_mixer),
+	SOC_SINGLE_EXT("IIR1 Enable Band4", IIR1, BAND4, 1, 0,
+	tapan_get_iir_enable_audio_mixer, tapan_put_iir_enable_audio_mixer),
+	SOC_SINGLE_EXT("IIR1 Enable Band5", IIR1, BAND5, 1, 0,
+	tapan_get_iir_enable_audio_mixer, tapan_put_iir_enable_audio_mixer),
+	SOC_SINGLE_EXT("IIR2 Enable Band1", IIR2, BAND1, 1, 0,
+	tapan_get_iir_enable_audio_mixer, tapan_put_iir_enable_audio_mixer),
+	SOC_SINGLE_EXT("IIR2 Enable Band2", IIR2, BAND2, 1, 0,
+	tapan_get_iir_enable_audio_mixer, tapan_put_iir_enable_audio_mixer),
+	SOC_SINGLE_EXT("IIR2 Enable Band3", IIR2, BAND3, 1, 0,
+	tapan_get_iir_enable_audio_mixer, tapan_put_iir_enable_audio_mixer),
+	SOC_SINGLE_EXT("IIR2 Enable Band4", IIR2, BAND4, 1, 0,
+	tapan_get_iir_enable_audio_mixer, tapan_put_iir_enable_audio_mixer),
+	SOC_SINGLE_EXT("IIR2 Enable Band5", IIR2, BAND5, 1, 0,
+	tapan_get_iir_enable_audio_mixer, tapan_put_iir_enable_audio_mixer),
+
+	SOC_SINGLE_MULTI_EXT("IIR1 Band1", IIR1, BAND1, 255, 0, 5,
+	tapan_get_iir_band_audio_mixer, tapan_put_iir_band_audio_mixer),
+	SOC_SINGLE_MULTI_EXT("IIR1 Band2", IIR1, BAND2, 255, 0, 5,
+	tapan_get_iir_band_audio_mixer, tapan_put_iir_band_audio_mixer),
+	SOC_SINGLE_MULTI_EXT("IIR1 Band3", IIR1, BAND3, 255, 0, 5,
+	tapan_get_iir_band_audio_mixer, tapan_put_iir_band_audio_mixer),
+	SOC_SINGLE_MULTI_EXT("IIR1 Band4", IIR1, BAND4, 255, 0, 5,
+	tapan_get_iir_band_audio_mixer, tapan_put_iir_band_audio_mixer),
+	SOC_SINGLE_MULTI_EXT("IIR1 Band5", IIR1, BAND5, 255, 0, 5,
+	tapan_get_iir_band_audio_mixer, tapan_put_iir_band_audio_mixer),
+	SOC_SINGLE_MULTI_EXT("IIR2 Band1", IIR2, BAND1, 255, 0, 5,
+	tapan_get_iir_band_audio_mixer, tapan_put_iir_band_audio_mixer),
+	SOC_SINGLE_MULTI_EXT("IIR2 Band2", IIR2, BAND2, 255, 0, 5,
+	tapan_get_iir_band_audio_mixer, tapan_put_iir_band_audio_mixer),
+	SOC_SINGLE_MULTI_EXT("IIR2 Band3", IIR2, BAND3, 255, 0, 5,
+	tapan_get_iir_band_audio_mixer, tapan_put_iir_band_audio_mixer),
+	SOC_SINGLE_MULTI_EXT("IIR2 Band4", IIR2, BAND4, 255, 0, 5,
+	tapan_get_iir_band_audio_mixer, tapan_put_iir_band_audio_mixer),
+	SOC_SINGLE_MULTI_EXT("IIR2 Band5", IIR2, BAND5, 255, 0, 5,
+	tapan_get_iir_band_audio_mixer, tapan_put_iir_band_audio_mixer),
+
+};
+
+static const char * const rx_mix1_text[] = {
+	"ZERO", "SRC1", "SRC2", "IIR1", "IIR2", "RX1", "RX2", "RX3", "RX4",
+		"RX5", "RX6", "RX7"
+};
+
+static const char * const rx_mix2_text[] = {
+	"ZERO", "SRC1", "SRC2", "IIR1", "IIR2"
+};
+
+static const char * const rx_rdac5_text[] = {
+	"DEM4", "DEM3_INV"
+};
+
+static const char * const rx_rdac7_text[] = {
+	"DEM6", "DEM5_INV"
+};
+
+static const char * const sb_tx1_mux_text[] = {
+	"ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
+		"DEC1"
+};
+
+static const char * const sb_tx2_mux_text[] = {
+	"ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
+		"DEC2"
+};
+
+static const char * const sb_tx3_mux_text[] = {
+	"ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
+		"DEC3"
+};
+
+static const char * const sb_tx4_mux_text[] = {
+	"ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
+		"DEC4"
+};
+
+static const char * const dec1_mux_text[] = {
+	"ZERO", "DMIC1", "ADC6",
+};
+
+static const char * const dec2_mux_text[] = {
+	"ZERO", "DMIC2", "ADC5",
+};
+
+static const char * const dec3_mux_text[] = {
+	"ZERO", "DMIC3", "ADC4",
+};
+
+static const char * const dec4_mux_text[] = {
+	"ZERO", "DMIC4", "ADC3",
+};
+
+static const char * const anc_mux_text[] = {
+	"ZERO", "ADC1", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6", "ADC_MB",
+		"RSVD_1", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5", "DMIC6"
+};
+
+static const char * const anc1_fb_mux_text[] = {
+	"ZERO", "EAR_HPH_L", "EAR_LINE_1",
+};
+
+static const char * const iir1_inp1_text[] = {
+	"ZERO", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6", "DEC7", "DEC8",
+	"DEC9", "DEC10", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7"
+};
+
+static const struct soc_enum rx_mix1_inp1_chain_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_RX1_B1_CTL, 0, 12, rx_mix1_text);
+
+static const struct soc_enum rx_mix1_inp2_chain_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_RX1_B1_CTL, 4, 12, rx_mix1_text);
+
+static const struct soc_enum rx_mix1_inp3_chain_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_RX1_B2_CTL, 0, 12, rx_mix1_text);
+
+static const struct soc_enum rx2_mix1_inp1_chain_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_RX2_B1_CTL, 0, 12, rx_mix1_text);
+
+static const struct soc_enum rx2_mix1_inp2_chain_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_RX2_B1_CTL, 4, 12, rx_mix1_text);
+
+static const struct soc_enum rx3_mix1_inp1_chain_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_RX3_B1_CTL, 0, 12, rx_mix1_text);
+
+static const struct soc_enum rx3_mix1_inp2_chain_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_RX3_B1_CTL, 4, 12, rx_mix1_text);
+
+static const struct soc_enum rx4_mix1_inp1_chain_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_RX4_B1_CTL, 0, 12, rx_mix1_text);
+
+static const struct soc_enum rx4_mix1_inp2_chain_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_RX4_B1_CTL, 4, 12, rx_mix1_text);
+
+static const struct soc_enum rx1_mix2_inp1_chain_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_RX1_B3_CTL, 0, 5, rx_mix2_text);
+
+static const struct soc_enum rx1_mix2_inp2_chain_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_RX1_B3_CTL, 3, 5, rx_mix2_text);
+
+static const struct soc_enum rx2_mix2_inp1_chain_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_RX2_B3_CTL, 0, 5, rx_mix2_text);
+
+static const struct soc_enum rx2_mix2_inp2_chain_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_RX2_B3_CTL, 3, 5, rx_mix2_text);
+
+static const struct soc_enum rx_rdac5_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_MISC, 2, 2, rx_rdac5_text);
+
+static const struct soc_enum rx_rdac7_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_MISC, 1, 2, rx_rdac7_text);
+
+static const struct soc_enum sb_tx1_mux_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_TX_SB_B1_CTL, 0, 9, sb_tx1_mux_text);
+
+static const struct soc_enum sb_tx2_mux_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_TX_SB_B2_CTL, 0, 9, sb_tx2_mux_text);
+
+static const struct soc_enum sb_tx3_mux_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_TX_SB_B3_CTL, 0, 9, sb_tx3_mux_text);
+
+static const struct soc_enum sb_tx4_mux_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_TX_SB_B4_CTL, 0, 9, sb_tx4_mux_text);
+
+static const struct soc_enum dec1_mux_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_TX_B1_CTL, 0, 3, dec1_mux_text);
+
+static const struct soc_enum dec2_mux_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_TX_B1_CTL, 2, 3, dec2_mux_text);
+
+static const struct soc_enum dec3_mux_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_TX_B1_CTL, 4, 3, dec3_mux_text);
+
+static const struct soc_enum dec4_mux_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_TX_B1_CTL, 6, 3, dec4_mux_text);
+
+static const struct soc_enum iir1_inp1_mux_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_EQ1_B1_CTL, 0, 18, iir1_inp1_text);
+
+static const struct snd_kcontrol_new rx_mix1_inp1_mux =
+	SOC_DAPM_ENUM("RX1 MIX1 INP1 Mux", rx_mix1_inp1_chain_enum);
+
+static const struct snd_kcontrol_new rx_mix1_inp2_mux =
+	SOC_DAPM_ENUM("RX1 MIX1 INP2 Mux", rx_mix1_inp2_chain_enum);
+
+static const struct snd_kcontrol_new rx_mix1_inp3_mux =
+	SOC_DAPM_ENUM("RX1 MIX1 INP3 Mux", rx_mix1_inp3_chain_enum);
+
+static const struct snd_kcontrol_new rx2_mix1_inp1_mux =
+	SOC_DAPM_ENUM("RX2 MIX1 INP1 Mux", rx2_mix1_inp1_chain_enum);
+
+static const struct snd_kcontrol_new rx2_mix1_inp2_mux =
+	SOC_DAPM_ENUM("RX2 MIX1 INP2 Mux", rx2_mix1_inp2_chain_enum);
+
+static const struct snd_kcontrol_new rx3_mix1_inp1_mux =
+	SOC_DAPM_ENUM("RX3 MIX1 INP1 Mux", rx3_mix1_inp1_chain_enum);
+
+static const struct snd_kcontrol_new rx3_mix1_inp2_mux =
+	SOC_DAPM_ENUM("RX3 MIX1 INP2 Mux", rx3_mix1_inp2_chain_enum);
+
+static const struct snd_kcontrol_new rx4_mix1_inp1_mux =
+	SOC_DAPM_ENUM("RX4 MIX1 INP1 Mux", rx4_mix1_inp1_chain_enum);
+
+static const struct snd_kcontrol_new rx4_mix1_inp2_mux =
+	SOC_DAPM_ENUM("RX4 MIX1 INP2 Mux", rx4_mix1_inp2_chain_enum);
+
+static const struct snd_kcontrol_new rx1_mix2_inp1_mux =
+	SOC_DAPM_ENUM("RX1 MIX2 INP1 Mux", rx1_mix2_inp1_chain_enum);
+
+static const struct snd_kcontrol_new rx1_mix2_inp2_mux =
+	SOC_DAPM_ENUM("RX1 MIX2 INP2 Mux", rx1_mix2_inp2_chain_enum);
+
+static const struct snd_kcontrol_new rx2_mix2_inp1_mux =
+	SOC_DAPM_ENUM("RX2 MIX2 INP1 Mux", rx2_mix2_inp1_chain_enum);
+
+static const struct snd_kcontrol_new rx2_mix2_inp2_mux =
+	SOC_DAPM_ENUM("RX2 MIX2 INP2 Mux", rx2_mix2_inp2_chain_enum);
+
+static const struct snd_kcontrol_new rx_dac5_mux =
+	SOC_DAPM_ENUM("RDAC5 MUX Mux", rx_rdac5_enum);
+
+static const struct snd_kcontrol_new sb_tx1_mux =
+	SOC_DAPM_ENUM("SLIM TX1 MUX Mux", sb_tx1_mux_enum);
+
+static const struct snd_kcontrol_new sb_tx2_mux =
+	SOC_DAPM_ENUM("SLIM TX2 MUX Mux", sb_tx2_mux_enum);
+
+static const struct snd_kcontrol_new sb_tx3_mux =
+	SOC_DAPM_ENUM("SLIM TX3 MUX Mux", sb_tx3_mux_enum);
+
+static const struct snd_kcontrol_new sb_tx4_mux =
+	SOC_DAPM_ENUM("SLIM TX4 MUX Mux", sb_tx4_mux_enum);
+
+/*static const struct snd_kcontrol_new sb_tx5_mux =
+	SOC_DAPM_ENUM("SLIM TX5 MUX Mux", sb_tx5_mux_enum);
+*/
+
+static int wcd9306_put_dec_enum(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
+	struct snd_soc_dapm_widget *w = wlist->widgets[0];
+	struct snd_soc_codec *codec = w->codec;
+	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+	unsigned int dec_mux, decimator;
+	char *dec_name = NULL;
+	char *widget_name = NULL;
+	char *temp;
+	u16 tx_mux_ctl_reg;
+	u8 adc_dmic_sel = 0x0;
+	int ret = 0;
+
+	if (ucontrol->value.enumerated.item[0] > e->max - 1)
+		return -EINVAL;
+
+	dec_mux = ucontrol->value.enumerated.item[0];
+
+	widget_name = kstrndup(w->name, 15, GFP_KERNEL);
+	if (!widget_name)
+		return -ENOMEM;
+	temp = widget_name;
+
+	dec_name = strsep(&widget_name, " ");
+	widget_name = temp;
+	if (!dec_name) {
+		pr_err("%s: Invalid decimator = %s\n", __func__, w->name);
+		ret =  -EINVAL;
+		goto out;
+	}
+
+	ret = kstrtouint(strpbrk(dec_name, "1234"), 10, &decimator);
+	if (ret < 0) {
+		pr_err("%s: Invalid decimator = %s\n", __func__, dec_name);
+		ret =  -EINVAL;
+		goto out;
+	}
+
+	dev_dbg(w->dapm->dev, "%s(): widget = %s decimator = %u dec_mux = %u\n"
+		, __func__, w->name, decimator, dec_mux);
+
+	switch (decimator) {
+	case 1:
+	case 2:
+	case 3:
+	case 4:
+	case 5:
+	case 6:
+		if (dec_mux == 1)
+			adc_dmic_sel = 0x1;
+		else
+			adc_dmic_sel = 0x0;
+		break;
+	case 7:
+	case 8:
+	case 9:
+	case 10:
+		if ((dec_mux == 1) || (dec_mux == 2))
+			adc_dmic_sel = 0x1;
+		else
+			adc_dmic_sel = 0x0;
+		break;
+	default:
+		pr_err("%s: Invalid Decimator = %u\n", __func__, decimator);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	tx_mux_ctl_reg = TAPAN_A_CDC_TX1_MUX_CTL + 8 * (decimator - 1);
+
+	snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x1, adc_dmic_sel);
+
+	ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
+
+out:
+	kfree(widget_name);
+	return ret;
+}
+
+#define WCD9306_DEC_ENUM(xname, xenum) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+	.info = snd_soc_info_enum_double, \
+	.get = snd_soc_dapm_get_enum_double, \
+	.put = wcd9306_put_dec_enum, \
+	.private_value = (unsigned long)&xenum }
+
+static const struct snd_kcontrol_new dec1_mux =
+	WCD9306_DEC_ENUM("DEC1 MUX Mux", dec1_mux_enum);
+
+static const struct snd_kcontrol_new dec2_mux =
+	WCD9306_DEC_ENUM("DEC2 MUX Mux", dec2_mux_enum);
+
+static const struct snd_kcontrol_new dec3_mux =
+	WCD9306_DEC_ENUM("DEC3 MUX Mux", dec3_mux_enum);
+
+static const struct snd_kcontrol_new dec4_mux =
+	WCD9306_DEC_ENUM("DEC4 MUX Mux", dec4_mux_enum);
+
+static const struct snd_kcontrol_new iir1_inp1_mux =
+	SOC_DAPM_ENUM("IIR1 INP1 Mux", iir1_inp1_mux_enum);
+
+static const struct snd_kcontrol_new dac1_switch[] = {
+	SOC_DAPM_SINGLE("Switch", TAPAN_A_RX_EAR_EN, 5, 1, 0)
+};
+static const struct snd_kcontrol_new hphl_switch[] = {
+	SOC_DAPM_SINGLE("Switch", TAPAN_A_RX_HPH_L_DAC_CTL, 6, 1, 0)
+};
+
+static const struct snd_kcontrol_new hphl_pa_mix[] = {
+	SOC_DAPM_SINGLE("AUX_PGA_L Switch", TAPAN_A_RX_PA_AUX_IN_CONN,
+					7, 1, 0),
+};
+
+static const struct snd_kcontrol_new hphr_pa_mix[] = {
+	SOC_DAPM_SINGLE("AUX_PGA_R Switch", TAPAN_A_RX_PA_AUX_IN_CONN,
+					6, 1, 0),
+};
+
+static const struct snd_kcontrol_new ear_pa_mix[] = {
+	SOC_DAPM_SINGLE("AUX_PGA_L Switch", TAPAN_A_RX_PA_AUX_IN_CONN,
+					5, 1, 0),
+};
+static const struct snd_kcontrol_new lineout1_pa_mix[] = {
+	SOC_DAPM_SINGLE("AUX_PGA_L Switch", TAPAN_A_RX_PA_AUX_IN_CONN,
+					4, 1, 0),
+};
+
+static const struct snd_kcontrol_new lineout2_pa_mix[] = {
+	SOC_DAPM_SINGLE("AUX_PGA_R Switch", TAPAN_A_RX_PA_AUX_IN_CONN,
+					3, 1, 0),
+};
+
+static const struct snd_kcontrol_new lineout3_pa_mix[] = {
+	SOC_DAPM_SINGLE("AUX_PGA_L Switch", TAPAN_A_RX_PA_AUX_IN_CONN,
+					2, 1, 0),
+};
+
+static const struct snd_kcontrol_new lineout4_pa_mix[] = {
+	SOC_DAPM_SINGLE("AUX_PGA_R Switch", TAPAN_A_RX_PA_AUX_IN_CONN,
+					1, 1, 0),
+};
+
+/* virtual port entries */
+static int slim_tx_mixer_get(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
+	struct snd_soc_dapm_widget *widget = wlist->widgets[0];
+
+	ucontrol->value.integer.value[0] = widget->value;
+	return 0;
+}
+
+static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
+	struct snd_soc_dapm_widget *widget = wlist->widgets[0];
+	struct snd_soc_codec *codec = widget->codec;
+	struct tapan_priv *tapan_p = snd_soc_codec_get_drvdata(codec);
+	struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
+	struct soc_multi_mixer_control *mixer =
+		((struct soc_multi_mixer_control *)kcontrol->private_value);
+	u32 dai_id = widget->shift;
+	u32 port_id = mixer->shift;
+	u32 enable = ucontrol->value.integer.value[0];
+
+	dev_dbg(codec->dev, "%s: wname %s cname %s\n",
+		__func__, widget->name,	ucontrol->id.name);
+	dev_dbg(codec->dev, "%s: value %u shift %d item %ld\n",
+		__func__, widget->value, widget->shift,
+		ucontrol->value.integer.value[0]);
+
+	mutex_lock(&codec->mutex);
+
+	if (tapan_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
+		if (dai_id != AIF1_CAP) {
+			dev_err(codec->dev, "%s: invalid AIF for I2C mode\n",
+				__func__);
+			mutex_unlock(&codec->mutex);
+			return -EINVAL;
+		}
+	}
+	switch (dai_id) {
+	case AIF1_CAP:
+	case AIF2_CAP:
+	case AIF3_CAP:
+		/* only add to the list if value not set
+		 */
+		if (enable && !(widget->value & 1 << port_id)) {
+			if (wcd9xxx_tx_vport_validation(
+						vport_check_table[dai_id],
+						port_id,
+						tapan_p->dai)) {
+				dev_dbg(codec->dev, "%s: TX%u is used by other virtual port\n",
+					__func__, port_id + 1);
+				mutex_unlock(&codec->mutex);
+				return -EINVAL;
+			}
+			widget->value |= 1 << port_id;
+			list_add_tail(&core->tx_chs[port_id].list,
+				      &tapan_p->dai[dai_id].wcd9xxx_ch_list
+				      );
+		} else if (!enable && (widget->value & 1 << port_id)) {
+			widget->value &= ~(1 << port_id);
+			list_del_init(&core->tx_chs[port_id].list);
+		} else {
+			if (enable)
+				dev_dbg(codec->dev, "%s: TX%u port is used by this virtual port\n",
+					__func__, port_id + 1);
+			else
+				dev_dbg(codec->dev, "%s: TX%u port is not used by this virtual port\n",
+					__func__, port_id + 1);
+			/* avoid update power function */
+			mutex_unlock(&codec->mutex);
+			return 0;
+		}
+		break;
+	default:
+		pr_err("Unknown AIF %d\n", dai_id);
+		mutex_unlock(&codec->mutex);
+		return -EINVAL;
+	}
+	dev_dbg(codec->dev, "%s: name %s sname %s updated value %u shift %d\n",
+		 __func__, widget->name, widget->sname,
+		 widget->value, widget->shift);
+
+	snd_soc_dapm_mixer_update_power(widget, kcontrol, enable);
+
+	mutex_unlock(&codec->mutex);
+	return 0;
+}
+
+static int slim_rx_mux_get(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
+	struct snd_soc_dapm_widget *widget = wlist->widgets[0];
+
+	ucontrol->value.enumerated.item[0] = widget->value;
+	return 0;
+}
+
+static const char *const slim_rx_mux_text[] = {
+	"ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB"
+};
+
+static int slim_rx_mux_put(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
+	struct snd_soc_dapm_widget *widget = wlist->widgets[0];
+	struct snd_soc_codec *codec = widget->codec;
+	struct tapan_priv *tapan_p = snd_soc_codec_get_drvdata(codec);
+	struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
+	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+	u32 port_id = widget->shift;
+
+	dev_dbg(codec->dev, "%s: wname %s cname %s value %u shift %d item %ld\n",
+		 __func__, widget->name, ucontrol->id.name, widget->value,
+		 widget->shift, ucontrol->value.integer.value[0]);
+
+	widget->value = ucontrol->value.enumerated.item[0];
+
+	mutex_lock(&codec->mutex);
+
+	if (tapan_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
+		if (widget->value > 1) {
+			dev_err(codec->dev, "%s: invalid AIF for I2C mode\n",
+				__func__);
+			goto err;
+		}
+	}
+	/* value need to match the Virtual port and AIF number
+	 */
+	switch (widget->value) {
+	case 0:
+		list_del_init(&core->rx_chs[port_id].list);
+	break;
+	case 1:
+		if (wcd9xxx_rx_vport_validation(port_id + core->num_tx_port,
+			&tapan_p->dai[AIF1_PB].wcd9xxx_ch_list))
+			goto pr_err;
+		list_add_tail(&core->rx_chs[port_id].list,
+			      &tapan_p->dai[AIF1_PB].wcd9xxx_ch_list);
+	break;
+	case 2:
+		if (wcd9xxx_rx_vport_validation(port_id + core->num_tx_port,
+			&tapan_p->dai[AIF1_PB].wcd9xxx_ch_list))
+			goto pr_err;
+		list_add_tail(&core->rx_chs[port_id].list,
+			      &tapan_p->dai[AIF2_PB].wcd9xxx_ch_list);
+	break;
+	case 3:
+		if (wcd9xxx_rx_vport_validation(port_id + core->num_tx_port,
+			&tapan_p->dai[AIF1_PB].wcd9xxx_ch_list))
+			goto pr_err;
+		list_add_tail(&core->rx_chs[port_id].list,
+			      &tapan_p->dai[AIF3_PB].wcd9xxx_ch_list);
+	break;
+	default:
+		pr_err("Unknown AIF %d\n", widget->value);
+		goto err;
+	}
+
+	snd_soc_dapm_mux_update_power(widget, kcontrol, 1, widget->value, e);
+
+	mutex_unlock(&codec->mutex);
+	return 0;
+pr_err:
+	pr_err("%s: RX%u is used by current requesting AIF_PB itself\n",
+		__func__, port_id + 1);
+err:
+	mutex_unlock(&codec->mutex);
+	return -EINVAL;
+}
+
+static const struct soc_enum slim_rx_mux_enum =
+	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim_rx_mux_text), slim_rx_mux_text);
+
+static const struct snd_kcontrol_new slim_rx_mux[TAPAN_RX_MAX] = {
+	SOC_DAPM_ENUM_EXT("SLIM RX1 Mux", slim_rx_mux_enum,
+			  slim_rx_mux_get, slim_rx_mux_put),
+	SOC_DAPM_ENUM_EXT("SLIM RX2 Mux", slim_rx_mux_enum,
+			  slim_rx_mux_get, slim_rx_mux_put),
+	SOC_DAPM_ENUM_EXT("SLIM RX3 Mux", slim_rx_mux_enum,
+			  slim_rx_mux_get, slim_rx_mux_put),
+	SOC_DAPM_ENUM_EXT("SLIM RX4 Mux", slim_rx_mux_enum,
+			  slim_rx_mux_get, slim_rx_mux_put),
+	SOC_DAPM_ENUM_EXT("SLIM RX5 Mux", slim_rx_mux_enum,
+			  slim_rx_mux_get, slim_rx_mux_put),
+};
+
+static const struct snd_kcontrol_new aif_cap_mixer[] = {
+	SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, TAPAN_TX1, 1, 0,
+			slim_tx_mixer_get, slim_tx_mixer_put),
+	SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, TAPAN_TX2, 1, 0,
+			slim_tx_mixer_get, slim_tx_mixer_put),
+	SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, TAPAN_TX3, 1, 0,
+			slim_tx_mixer_get, slim_tx_mixer_put),
+	SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, TAPAN_TX4, 1, 0,
+			slim_tx_mixer_get, slim_tx_mixer_put),
+	SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, TAPAN_TX5, 1, 0,
+			slim_tx_mixer_get, slim_tx_mixer_put),
+};
+
+static int tapan_codec_enable_aux_pga(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	struct tapan_priv *tapan = snd_soc_codec_get_drvdata(codec);
+
+	dev_dbg(codec->dev, "%s: %d\n", __func__, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		WCD9XXX_BCL_LOCK(&tapan->resmgr);
+		wcd9xxx_resmgr_get_bandgap(&tapan->resmgr,
+					   WCD9XXX_BANDGAP_AUDIO_MODE);
+		/* AUX PGA requires RCO or MCLK */
+		wcd9xxx_resmgr_get_clk_block(&tapan->resmgr, WCD9XXX_CLK_RCO);
+		wcd9xxx_resmgr_enable_rx_bias(&tapan->resmgr, 1);
+		WCD9XXX_BCL_UNLOCK(&tapan->resmgr);
+		break;
+
+	case SND_SOC_DAPM_POST_PMD:
+		WCD9XXX_BCL_LOCK(&tapan->resmgr);
+		wcd9xxx_resmgr_enable_rx_bias(&tapan->resmgr, 0);
+		wcd9xxx_resmgr_put_bandgap(&tapan->resmgr,
+					   WCD9XXX_BANDGAP_AUDIO_MODE);
+		wcd9xxx_resmgr_put_clk_block(&tapan->resmgr, WCD9XXX_CLK_RCO);
+		WCD9XXX_BCL_UNLOCK(&tapan->resmgr);
+		break;
+	}
+	return 0;
+}
+
+static int tapan_codec_enable_lineout(struct snd_soc_dapm_widget *w,
+		struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	u16 lineout_gain_reg;
+
+	dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name);
+
+	switch (w->shift) {
+	case 0:
+		lineout_gain_reg = TAPAN_A_RX_LINE_1_GAIN;
+		break;
+	case 1:
+		lineout_gain_reg = TAPAN_A_RX_LINE_2_GAIN;
+		break;
+	default:
+		pr_err("%s: Error, incorrect lineout register value\n",
+			__func__);
+		return -EINVAL;
+	}
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		snd_soc_update_bits(codec, lineout_gain_reg, 0x40, 0x40);
+		break;
+	case SND_SOC_DAPM_POST_PMU:
+		dev_dbg(codec->dev, "%s: sleeping 16 ms after %s PA turn on\n",
+				__func__, w->name);
+		usleep_range(16000, 16000);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		snd_soc_update_bits(codec, lineout_gain_reg, 0x40, 0x00);
+		break;
+	}
+	return 0;
+}
+
+static int tapan_codec_enable_spk_pa(struct snd_soc_dapm_widget *w,
+				     struct snd_kcontrol *kcontrol, int event)
+{
+	dev_dbg(w->codec->dev, "%s %d %s\n", __func__, event, w->name);
+	return 0;
+}
+
+static int tapan_codec_enable_dmic(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	struct tapan_priv *tapan = snd_soc_codec_get_drvdata(codec);
+	u8  dmic_clk_en;
+	u16 dmic_clk_reg;
+	s32 *dmic_clk_cnt;
+	unsigned int dmic;
+	int ret;
+
+	ret = kstrtouint(strpbrk(w->name, "123456"), 10, &dmic);
+	if (ret < 0) {
+		pr_err("%s: Invalid DMIC line on the codec\n", __func__);
+		return -EINVAL;
+	}
+
+	switch (dmic) {
+	case 1:
+	case 2:
+		dmic_clk_en = 0x01;
+		dmic_clk_cnt = &(tapan->dmic_1_2_clk_cnt);
+		dmic_clk_reg = TAPAN_A_CDC_CLK_DMIC_B1_CTL;
+		dev_dbg(codec->dev, "%s() event %d DMIC%d dmic_1_2_clk_cnt %d\n",
+			__func__, event,  dmic, *dmic_clk_cnt);
+
+		break;
+
+	case 3:
+	case 4:
+		dmic_clk_en = 0x10;
+		dmic_clk_cnt = &(tapan->dmic_3_4_clk_cnt);
+		dmic_clk_reg = TAPAN_A_CDC_CLK_DMIC_B1_CTL;
+
+		dev_dbg(codec->dev, "%s() event %d DMIC%d dmic_3_4_clk_cnt %d\n",
+			__func__, event,  dmic, *dmic_clk_cnt);
+		break;
+
+	case 5:
+	case 6:
+		dmic_clk_en = 0x01;
+		dmic_clk_cnt = &(tapan->dmic_5_6_clk_cnt);
+		dmic_clk_reg = TAPAN_A_CDC_CLK_DMIC_B2_CTL;
+
+		dev_dbg(codec->dev, "%s() event %d DMIC%d dmic_5_6_clk_cnt %d\n",
+			__func__, event,  dmic, *dmic_clk_cnt);
+
+		break;
+
+	default:
+		pr_err("%s: Invalid DMIC Selection\n", __func__);
+		return -EINVAL;
+	}
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+
+		(*dmic_clk_cnt)++;
+		if (*dmic_clk_cnt == 1)
+			snd_soc_update_bits(codec, dmic_clk_reg,
+					dmic_clk_en, dmic_clk_en);
+
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+
+		(*dmic_clk_cnt)--;
+		if (*dmic_clk_cnt  == 0)
+			snd_soc_update_bits(codec, dmic_clk_reg,
+					dmic_clk_en, 0);
+		break;
+	}
+	return 0;
+}
+
+static int tapan_codec_enable_anc(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	const char *filename;
+	const struct firmware *fw;
+	int i;
+	int ret;
+	int num_anc_slots;
+	struct anc_header *anc_head;
+	struct tapan_priv *tapan = snd_soc_codec_get_drvdata(codec);
+	u32 anc_writes_size = 0;
+	int anc_size_remaining;
+	u32 *anc_ptr;
+	u16 reg;
+	u8 mask, val;
+
+	dev_dbg(codec->dev, "%s %d\n", __func__, event);
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+
+		filename = "wcd9306/wcd9306_anc.bin";
+
+		ret = request_firmware(&fw, filename, codec->dev);
+		if (ret != 0) {
+			dev_err(codec->dev, "Failed to acquire ANC data: %d\n",
+				ret);
+			return -ENODEV;
+		}
+
+		if (fw->size < sizeof(struct anc_header)) {
+			dev_err(codec->dev, "Not enough data\n");
+			release_firmware(fw);
+			return -ENOMEM;
+		}
+
+		/* First number is the number of register writes */
+		anc_head = (struct anc_header *)(fw->data);
+		anc_ptr = (u32 *)((u32)fw->data + sizeof(struct anc_header));
+		anc_size_remaining = fw->size - sizeof(struct anc_header);
+		num_anc_slots = anc_head->num_anc_slots;
+
+		if (tapan->anc_slot >= num_anc_slots) {
+			dev_err(codec->dev, "Invalid ANC slot selected\n");
+			release_firmware(fw);
+			return -EINVAL;
+		}
+
+		for (i = 0; i < num_anc_slots; i++) {
+
+			if (anc_size_remaining < TAPAN_PACKED_REG_SIZE) {
+				dev_err(codec->dev, "Invalid register format\n");
+				release_firmware(fw);
+				return -EINVAL;
+			}
+			anc_writes_size = (u32)(*anc_ptr);
+			anc_size_remaining -= sizeof(u32);
+			anc_ptr += 1;
+
+			if (anc_writes_size * TAPAN_PACKED_REG_SIZE
+				> anc_size_remaining) {
+				dev_err(codec->dev, "Invalid register format\n");
+				release_firmware(fw);
+				return -ENOMEM;
+			}
+
+			if (tapan->anc_slot == i)
+				break;
+
+			anc_size_remaining -= (anc_writes_size *
+				TAPAN_PACKED_REG_SIZE);
+			anc_ptr += anc_writes_size;
+		}
+		if (i == num_anc_slots) {
+			dev_err(codec->dev, "Selected ANC slot not present\n");
+			release_firmware(fw);
+			return -ENOMEM;
+		}
+
+		for (i = 0; i < anc_writes_size; i++) {
+			TAPAN_CODEC_UNPACK_ENTRY(anc_ptr[i], reg,
+				mask, val);
+			snd_soc_write(codec, reg, val);
+		}
+		release_firmware(fw);
+
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		snd_soc_write(codec, TAPAN_A_CDC_CLK_ANC_RESET_CTL, 0xFF);
+		snd_soc_write(codec, TAPAN_A_CDC_CLK_ANC_CLK_EN_CTL, 0);
+		break;
+	}
+	return 0;
+}
+
+static int tapan_codec_enable_micbias(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	struct tapan_priv *tapan = snd_soc_codec_get_drvdata(codec);
+	u16 micb_int_reg;
+	u8 cfilt_sel_val = 0;
+	char *internal1_text = "Internal1";
+	char *internal2_text = "Internal2";
+	char *internal3_text = "Internal3";
+	enum wcd9xxx_notify_event e_post_off, e_pre_on, e_post_on;
+
+	dev_dbg(codec->dev, "%s %d\n", __func__, event);
+	switch (w->reg) {
+	case TAPAN_A_MICB_1_CTL:
+		micb_int_reg = TAPAN_A_MICB_1_INT_RBIAS;
+		cfilt_sel_val = tapan->resmgr.pdata->micbias.bias1_cfilt_sel;
+		e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_1_ON;
+		e_post_on = WCD9XXX_EVENT_POST_MICBIAS_1_ON;
+		e_post_off = WCD9XXX_EVENT_POST_MICBIAS_1_OFF;
+		break;
+	case TAPAN_A_MICB_2_CTL:
+		micb_int_reg = TAPAN_A_MICB_2_INT_RBIAS;
+		cfilt_sel_val = tapan->resmgr.pdata->micbias.bias2_cfilt_sel;
+		e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_2_ON;
+		e_post_on = WCD9XXX_EVENT_POST_MICBIAS_2_ON;
+		e_post_off = WCD9XXX_EVENT_POST_MICBIAS_2_OFF;
+		break;
+	case TAPAN_A_MICB_3_CTL:
+		micb_int_reg = TAPAN_A_MICB_3_INT_RBIAS;
+		cfilt_sel_val = tapan->resmgr.pdata->micbias.bias3_cfilt_sel;
+		e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_3_ON;
+		e_post_on = WCD9XXX_EVENT_POST_MICBIAS_3_ON;
+		e_post_off = WCD9XXX_EVENT_POST_MICBIAS_3_OFF;
+		break;
+	default:
+		pr_err("%s: Error, invalid micbias register\n", __func__);
+		return -EINVAL;
+	}
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		/* Let MBHC module know so micbias switch to be off */
+		wcd9xxx_resmgr_notifier_call(&tapan->resmgr, e_pre_on);
+
+		/* Get cfilt */
+		wcd9xxx_resmgr_cfilt_get(&tapan->resmgr, cfilt_sel_val);
+
+		if (strnstr(w->name, internal1_text, 30))
+			snd_soc_update_bits(codec, micb_int_reg, 0xE0, 0xE0);
+		else if (strnstr(w->name, internal2_text, 30))
+			snd_soc_update_bits(codec, micb_int_reg, 0x1C, 0x1C);
+		else if (strnstr(w->name, internal3_text, 30))
+			snd_soc_update_bits(codec, micb_int_reg, 0x3, 0x3);
+
+		break;
+	case SND_SOC_DAPM_POST_PMU:
+		usleep_range(20000, 20000);
+		/* Let MBHC module know so micbias is on */
+		wcd9xxx_resmgr_notifier_call(&tapan->resmgr, e_post_on);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		/* Let MBHC module know so micbias switch to be off */
+		wcd9xxx_resmgr_notifier_call(&tapan->resmgr, e_post_off);
+
+		if (strnstr(w->name, internal1_text, 30))
+			snd_soc_update_bits(codec, micb_int_reg, 0x80, 0x00);
+		else if (strnstr(w->name, internal2_text, 30))
+			snd_soc_update_bits(codec, micb_int_reg, 0x10, 0x00);
+		else if (strnstr(w->name, internal3_text, 30))
+			snd_soc_update_bits(codec, micb_int_reg, 0x2, 0x0);
+
+		/* Put cfilt */
+		wcd9xxx_resmgr_cfilt_put(&tapan->resmgr, cfilt_sel_val);
+		break;
+	}
+
+	return 0;
+}
+
+static void tx_hpf_corner_freq_callback(struct work_struct *work)
+{
+	struct delayed_work *hpf_delayed_work;
+	struct hpf_work *hpf_work;
+	struct tapan_priv *tapan;
+	struct snd_soc_codec *codec;
+	u16 tx_mux_ctl_reg;
+	u8 hpf_cut_of_freq;
+
+	hpf_delayed_work = to_delayed_work(work);
+	hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork);
+	tapan = hpf_work->tapan;
+	codec = hpf_work->tapan->codec;
+	hpf_cut_of_freq = hpf_work->tx_hpf_cut_of_freq;
+
+	tx_mux_ctl_reg = TAPAN_A_CDC_TX1_MUX_CTL +
+			(hpf_work->decimator - 1) * 8;
+
+	dev_dbg(codec->dev, "%s(): decimator %u hpf_cut_of_freq 0x%x\n",
+		 __func__, hpf_work->decimator, (unsigned int)hpf_cut_of_freq);
+
+	snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30, hpf_cut_of_freq << 4);
+}
+
+#define  TX_MUX_CTL_CUT_OFF_FREQ_MASK	0x30
+#define  CF_MIN_3DB_4HZ			0x0
+#define  CF_MIN_3DB_75HZ		0x1
+#define  CF_MIN_3DB_150HZ		0x2
+
+static int tapan_codec_enable_dec(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	unsigned int decimator;
+	char *dec_name = NULL;
+	char *widget_name = NULL;
+	char *temp;
+	int ret = 0;
+	u16 dec_reset_reg, tx_vol_ctl_reg, tx_mux_ctl_reg;
+	u8 dec_hpf_cut_of_freq;
+	int offset;
+
+	dev_dbg(codec->dev, "%s %d\n", __func__, event);
+
+	widget_name = kstrndup(w->name, 15, GFP_KERNEL);
+	if (!widget_name)
+		return -ENOMEM;
+	temp = widget_name;
+
+	dec_name = strsep(&widget_name, " ");
+	widget_name = temp;
+	if (!dec_name) {
+		pr_err("%s: Invalid decimator = %s\n", __func__, w->name);
+		ret =  -EINVAL;
+		goto out;
+	}
+
+	ret = kstrtouint(strpbrk(dec_name, "123456789"), 10, &decimator);
+	if (ret < 0) {
+		pr_err("%s: Invalid decimator = %s\n", __func__, dec_name);
+		ret =  -EINVAL;
+		goto out;
+	}
+
+	dev_dbg(codec->dev, "%s(): widget = %s dec_name = %s decimator = %u\n",
+			__func__, w->name, dec_name, decimator);
+
+	if (w->reg == TAPAN_A_CDC_CLK_TX_CLK_EN_B1_CTL) {
+		dec_reset_reg = TAPAN_A_CDC_CLK_TX_RESET_B1_CTL;
+		offset = 0;
+	} else if (w->reg == TAPAN_A_CDC_CLK_TX_CLK_EN_B2_CTL) {
+		dec_reset_reg = TAPAN_A_CDC_CLK_TX_RESET_B2_CTL;
+		offset = 8;
+	} else {
+		pr_err("%s: Error, incorrect dec\n", __func__);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	tx_vol_ctl_reg = TAPAN_A_CDC_TX1_VOL_CTL_CFG + 8 * (decimator - 1);
+	tx_mux_ctl_reg = TAPAN_A_CDC_TX1_MUX_CTL + 8 * (decimator - 1);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+
+		/* Enableable TX digital mute */
+		snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01);
+
+		snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift,
+			1 << w->shift);
+		snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift, 0x0);
+
+		dec_hpf_cut_of_freq = snd_soc_read(codec, tx_mux_ctl_reg);
+
+		dec_hpf_cut_of_freq = (dec_hpf_cut_of_freq & 0x30) >> 4;
+
+		tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq =
+			dec_hpf_cut_of_freq;
+
+		if ((dec_hpf_cut_of_freq != CF_MIN_3DB_150HZ)) {
+
+			/* set cut of freq to CF_MIN_3DB_150HZ (0x1); */
+			snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30,
+					    CF_MIN_3DB_150HZ << 4);
+		}
+
+		/* enable HPF */
+		snd_soc_update_bits(codec, tx_mux_ctl_reg , 0x08, 0x00);
+
+		break;
+
+	case SND_SOC_DAPM_POST_PMU:
+
+		/* Disable TX digital mute */
+		snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00);
+
+		if (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq !=
+				CF_MIN_3DB_150HZ) {
+
+			schedule_delayed_work(&tx_hpf_work[decimator - 1].dwork,
+					msecs_to_jiffies(300));
+		}
+		/* apply the digital gain after the decimator is enabled*/
+		if ((w->shift) < ARRAY_SIZE(tx_digital_gain_reg))
+			snd_soc_write(codec,
+				  tx_digital_gain_reg[w->shift + offset],
+				  snd_soc_read(codec,
+				  tx_digital_gain_reg[w->shift + offset])
+				  );
+
+		break;
+
+	case SND_SOC_DAPM_PRE_PMD:
+
+		snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01);
+		cancel_delayed_work_sync(&tx_hpf_work[decimator - 1].dwork);
+		break;
+
+	case SND_SOC_DAPM_POST_PMD:
+
+		snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x08, 0x08);
+		snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30,
+			(tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq) << 4);
+
+		break;
+	}
+out:
+	kfree(widget_name);
+	return ret;
+}
+
+static int tapan_codec_enable_interpolator(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+
+	dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		snd_soc_update_bits(codec, TAPAN_A_CDC_CLK_RX_RESET_CTL,
+			1 << w->shift, 1 << w->shift);
+		snd_soc_update_bits(codec, TAPAN_A_CDC_CLK_RX_RESET_CTL,
+			1 << w->shift, 0x0);
+		break;
+	case SND_SOC_DAPM_POST_PMU:
+		/* apply the digital gain after the interpolator is enabled*/
+		if ((w->shift) < ARRAY_SIZE(rx_digital_gain_reg))
+			snd_soc_write(codec,
+				  rx_digital_gain_reg[w->shift],
+				  snd_soc_read(codec,
+				  rx_digital_gain_reg[w->shift])
+				  );
+		break;
+	}
+	return 0;
+}
+
+static int tapan_codec_enable_ldo_h(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+	case SND_SOC_DAPM_POST_PMD:
+		usleep_range(1000, 1000);
+		break;
+	}
+	return 0;
+}
+
+static int tapan_codec_enable_rx_bias(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	struct tapan_priv *tapan = snd_soc_codec_get_drvdata(codec);
+
+	dev_dbg(codec->dev, "%s %d\n", __func__, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		wcd9xxx_resmgr_enable_rx_bias(&tapan->resmgr, 1);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		wcd9xxx_resmgr_enable_rx_bias(&tapan->resmgr, 0);
+		break;
+	}
+	return 0;
+}
+static int tapan_hphr_dac_event(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+
+	dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		snd_soc_update_bits(codec, w->reg, 0x40, 0x40);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		snd_soc_update_bits(codec, w->reg, 0x40, 0x00);
+		break;
+	}
+	return 0;
+}
+
+static int tapan_hph_pa_event(struct snd_soc_dapm_widget *w,
+			      struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	struct tapan_priv *tapan = snd_soc_codec_get_drvdata(codec);
+	enum wcd9xxx_notify_event e_pre_on, e_post_off;
+
+	dev_dbg(codec->dev, "%s: %s event = %d\n", __func__, w->name, event);
+	if (w->shift == 5) {
+		e_pre_on = WCD9XXX_EVENT_PRE_HPHR_PA_ON;
+		e_post_off = WCD9XXX_EVENT_POST_HPHR_PA_OFF;
+	} else if (w->shift == 4) {
+		e_pre_on = WCD9XXX_EVENT_PRE_HPHL_PA_ON;
+		e_post_off = WCD9XXX_EVENT_POST_HPHL_PA_OFF;
+	} else {
+		pr_err("%s: Invalid w->shift %d\n", __func__, w->shift);
+		return -EINVAL;
+	}
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		/* Let MBHC module know PA is turning on */
+		wcd9xxx_resmgr_notifier_call(&tapan->resmgr, e_pre_on);
+		break;
+
+	case SND_SOC_DAPM_POST_PMU:
+		usleep_range(10000, 10000);
+
+		snd_soc_update_bits(codec, TAPAN_A_BUCK_MODE_5, 0x02, 0x00);
+		snd_soc_update_bits(codec, TAPAN_A_NCP_STATIC, 0x20, 0x00);
+		snd_soc_update_bits(codec, TAPAN_A_BUCK_MODE_3, 0x04, 0x04);
+		snd_soc_update_bits(codec, TAPAN_A_BUCK_MODE_3, 0x08, 0x00);
+
+		usleep_range(10, 10);
+		break;
+
+	case SND_SOC_DAPM_POST_PMD:
+		/* Let MBHC module know PA turned off */
+		wcd9xxx_resmgr_notifier_call(&tapan->resmgr, e_post_off);
+
+		/*
+		 * schedule work is required because at the time HPH PA DAPM
+		 * event callback is called by DAPM framework, CODEC dapm mutex
+		 * would have been locked while snd_soc_jack_report also
+		 * attempts to acquire same lock.
+		 */
+		dev_dbg(codec->dev, "%s: sleep 10 ms after %s PA disable.\n",
+			 __func__, w->name);
+		usleep_range(5000, 5000);
+		break;
+	}
+	return 0;
+}
+
+static int tapan_lineout_dac_event(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+
+	dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		snd_soc_update_bits(codec, w->reg, 0x40, 0x40);
+		break;
+
+	case SND_SOC_DAPM_POST_PMD:
+		snd_soc_update_bits(codec, w->reg, 0x40, 0x00);
+		break;
+	}
+	return 0;
+}
+
+static int tapan_spk_dac_event(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+
+	dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
+	return 0;
+}
+
+static const struct snd_soc_dapm_route audio_i2s_map[] = {
+	{"RX_I2S_CLK", NULL, "CDC_CONN"},
+	{"SLIM RX1", NULL, "RX_I2S_CLK"},
+	{"SLIM RX2", NULL, "RX_I2S_CLK"},
+
+	{"SLIM TX1 MUX", NULL, "TX_I2S_CLK"},
+	{"SLIM TX2 MUX", NULL, "TX_I2S_CLK"},
+};
+
+static const struct snd_soc_dapm_route audio_map[] = {
+	/* SLIMBUS Connections */
+	{"AIF1 CAP", NULL, "AIF1_CAP Mixer"},
+	{"AIF2 CAP", NULL, "AIF2_CAP Mixer"},
+	{"AIF3 CAP", NULL, "AIF3_CAP Mixer"},
+
+	/* SLIM_MIXER("AIF1_CAP Mixer"),*/
+	{"AIF1_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
+	{"AIF1_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
+	{"AIF1_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
+	{"AIF1_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
+	{"AIF1_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
+	{"AIF1_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
+	{"AIF1_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
+	{"AIF1_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
+	{"AIF1_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
+	{"AIF1_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
+	/* SLIM_MIXER("AIF2_CAP Mixer"),*/
+	{"AIF2_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
+	{"AIF2_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
+	{"AIF2_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
+	{"AIF2_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
+	{"AIF2_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
+	{"AIF2_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
+	{"AIF2_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
+	{"AIF2_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
+	{"AIF2_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
+	{"AIF2_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
+	/* SLIM_MIXER("AIF3_CAP Mixer"),*/
+	{"AIF3_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
+	{"AIF3_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
+	{"AIF3_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
+	{"AIF3_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
+	{"AIF3_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
+	{"AIF3_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
+	{"AIF3_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
+	{"AIF3_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
+	{"AIF3_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
+	{"AIF3_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
+
+	{"SLIM TX1 MUX", "DEC1", "DEC1 MUX"},
+
+	{"SLIM TX2 MUX", "DEC2", "DEC2 MUX"},
+
+	{"SLIM TX3 MUX", "DEC3", "DEC3 MUX"},
+	{"SLIM TX3 MUX", "RMIX1", "RX1 MIX1"},
+	{"SLIM TX3 MUX", "RMIX2", "RX2 MIX1"},
+	{"SLIM TX3 MUX", "RMIX3", "RX3 MIX1"},
+	{"SLIM TX3 MUX", "RMIX4", "RX4 MIX1"},
+	{"SLIM TX3 MUX", "RMIX5", "RX5 MIX1"},
+	{"SLIM TX3 MUX", "RMIX6", "RX6 MIX1"},
+	{"SLIM TX3 MUX", "RMIX7", "RX7 MIX1"},
+
+	{"SLIM TX4 MUX", "DEC4", "DEC4 MUX"},
+
+	{"SLIM TX5 MUX", "DEC5", "DEC5 MUX"},
+	{"SLIM TX5 MUX", "RMIX1", "RX1 MIX1"},
+	{"SLIM TX5 MUX", "RMIX2", "RX2 MIX1"},
+	{"SLIM TX5 MUX", "RMIX3", "RX3 MIX1"},
+	{"SLIM TX5 MUX", "RMIX4", "RX4 MIX1"},
+	{"SLIM TX5 MUX", "RMIX5", "RX5 MIX1"},
+	{"SLIM TX5 MUX", "RMIX6", "RX6 MIX1"},
+	{"SLIM TX5 MUX", "RMIX7", "RX7 MIX1"},
+
+	{"SLIM TX6 MUX", "DEC6", "DEC6 MUX"},
+
+	{"SLIM TX7 MUX", "DEC1", "DEC1 MUX"},
+	{"SLIM TX7 MUX", "DEC2", "DEC2 MUX"},
+	{"SLIM TX7 MUX", "DEC3", "DEC3 MUX"},
+	{"SLIM TX7 MUX", "DEC4", "DEC4 MUX"},
+	{"SLIM TX7 MUX", "DEC5", "DEC5 MUX"},
+	{"SLIM TX7 MUX", "DEC6", "DEC6 MUX"},
+	{"SLIM TX7 MUX", "DEC7", "DEC7 MUX"},
+	{"SLIM TX7 MUX", "DEC8", "DEC8 MUX"},
+	{"SLIM TX7 MUX", "DEC9", "DEC9 MUX"},
+	{"SLIM TX7 MUX", "DEC10", "DEC10 MUX"},
+	{"SLIM TX7 MUX", "RMIX1", "RX1 MIX1"},
+	{"SLIM TX7 MUX", "RMIX2", "RX2 MIX1"},
+	{"SLIM TX7 MUX", "RMIX3", "RX3 MIX1"},
+	{"SLIM TX7 MUX", "RMIX4", "RX4 MIX1"},
+	{"SLIM TX7 MUX", "RMIX5", "RX5 MIX1"},
+	{"SLIM TX7 MUX", "RMIX6", "RX6 MIX1"},
+	{"SLIM TX7 MUX", "RMIX7", "RX7 MIX1"},
+
+	{"SLIM TX8 MUX", "DEC1", "DEC1 MUX"},
+	{"SLIM TX8 MUX", "DEC2", "DEC2 MUX"},
+	{"SLIM TX8 MUX", "DEC3", "DEC3 MUX"},
+	{"SLIM TX8 MUX", "DEC4", "DEC4 MUX"},
+	{"SLIM TX8 MUX", "DEC5", "DEC5 MUX"},
+	{"SLIM TX8 MUX", "DEC6", "DEC6 MUX"},
+	{"SLIM TX8 MUX", "DEC7", "DEC7 MUX"},
+	{"SLIM TX8 MUX", "DEC8", "DEC8 MUX"},
+	{"SLIM TX8 MUX", "DEC9", "DEC9 MUX"},
+	{"SLIM TX8 MUX", "DEC10", "DEC10 MUX"},
+
+	{"SLIM TX9 MUX", "DEC1", "DEC1 MUX"},
+	{"SLIM TX9 MUX", "DEC2", "DEC2 MUX"},
+	{"SLIM TX9 MUX", "DEC3", "DEC3 MUX"},
+	{"SLIM TX9 MUX", "DEC4", "DEC4 MUX"},
+	{"SLIM TX9 MUX", "DEC5", "DEC5 MUX"},
+	{"SLIM TX9 MUX", "DEC6", "DEC6 MUX"},
+	{"SLIM TX9 MUX", "DEC7", "DEC7 MUX"},
+	{"SLIM TX9 MUX", "DEC8", "DEC8 MUX"},
+	{"SLIM TX9 MUX", "DEC9", "DEC9 MUX"},
+	{"SLIM TX9 MUX", "DEC10", "DEC10 MUX"},
+
+	{"SLIM TX10 MUX", "DEC1", "DEC1 MUX"},
+	{"SLIM TX10 MUX", "DEC2", "DEC2 MUX"},
+	{"SLIM TX10 MUX", "DEC3", "DEC3 MUX"},
+	{"SLIM TX10 MUX", "DEC4", "DEC4 MUX"},
+	{"SLIM TX10 MUX", "DEC5", "DEC5 MUX"},
+	{"SLIM TX10 MUX", "DEC6", "DEC6 MUX"},
+	{"SLIM TX10 MUX", "DEC7", "DEC7 MUX"},
+	{"SLIM TX10 MUX", "DEC8", "DEC8 MUX"},
+	{"SLIM TX10 MUX", "DEC9", "DEC9 MUX"},
+	{"SLIM TX10 MUX", "DEC10", "DEC10 MUX"},
+
+	/* Earpiece (RX MIX1) */
+	{"EAR", NULL, "EAR PA"},
+	{"EAR PA", NULL, "EAR_PA_MIXER"},
+	{"EAR_PA_MIXER", NULL, "DAC1"},
+	{"DAC1", NULL, "CP"},
+	{"CP", NULL, "CLASS_H_EAR"},
+	{"CLASS_H_EAR", NULL, "CLASS_H_CLK"},
+
+	{"ANC1 FB MUX", "EAR_HPH_L", "RX1 MIX2"},
+	{"ANC1 FB MUX", "EAR_LINE_1", "RX2 MIX2"},
+	{"ANC", NULL, "ANC1 FB MUX"},
+
+	/* Headset (RX MIX1 and RX MIX2) */
+	{"HEADPHONE", NULL, "HPHL"},
+	{"HEADPHONE", NULL, "HPHR"},
+
+	{"HPHL", NULL, "HPHL_PA_MIXER"},
+	{"HPHL_PA_MIXER", NULL, "HPHL DAC"},
+
+	{"HPHR", NULL, "HPHR_PA_MIXER"},
+	{"HPHR_PA_MIXER", NULL, "HPHR DAC"},
+
+	{"HPHL DAC", NULL, "CP"},
+	{"CP", NULL, "CLASS_H_HPH_L"},
+	{"CLASS_H_HPH_L", NULL, "CLASS_H_CLK"},
+
+	{"HPHR DAC", NULL, "CP"},
+	{"CP", NULL, "CLASS_H_HPH_R"},
+	{"CLASS_H_HPH_R", NULL, "CLASS_H_CLK"},
+
+	{"ANC", NULL, "ANC1 MUX"},
+	{"ANC", NULL, "ANC2 MUX"},
+	{"ANC1 MUX", "ADC1", "ADC1"},
+	{"ANC1 MUX", "ADC2", "ADC2"},
+	{"ANC1 MUX", "ADC3", "ADC3"},
+	{"ANC1 MUX", "ADC4", "ADC4"},
+	{"ANC2 MUX", "ADC1", "ADC1"},
+	{"ANC2 MUX", "ADC2", "ADC2"},
+	{"ANC2 MUX", "ADC3", "ADC3"},
+	{"ANC2 MUX", "ADC4", "ADC4"},
+
+	{"ANC", NULL, "CDC_CONN"},
+
+	{"DAC1", "Switch", "RX1 CHAIN"},
+	{"HPHL DAC", "Switch", "RX1 CHAIN"},
+	{"HPHR DAC", NULL, "RX2 CHAIN"},
+
+	{"LINEOUT1", NULL, "LINEOUT1 PA"},
+	{"LINEOUT2", NULL, "LINEOUT2 PA"},
+	{"LINEOUT3", NULL, "LINEOUT3 PA"},
+	{"LINEOUT4", NULL, "LINEOUT4 PA"},
+	{"SPK_OUT", NULL, "SPK PA"},
+
+	{"LINEOUT1 PA", NULL, "CP"},
+	{"LINEOUT1 PA", NULL, "LINEOUT1_PA_MIXER"},
+	{"LINEOUT1_PA_MIXER", NULL, "LINEOUT1 DAC"},
+
+	{"LINEOUT2 PA", NULL, "CP"},
+	{"LINEOUT2 PA", NULL, "LINEOUT2_PA_MIXER"},
+	{"LINEOUT2_PA_MIXER", NULL, "LINEOUT2 DAC"},
+
+	{"LINEOUT3 PA", NULL, "CP"},
+	{"LINEOUT3 PA", NULL, "LINEOUT3_PA_MIXER"},
+	{"LINEOUT3_PA_MIXER", NULL, "LINEOUT3 DAC"},
+
+	{"LINEOUT4 PA", NULL, "CP"},
+	{"LINEOUT4 PA", NULL, "LINEOUT4_PA_MIXER"},
+	{"LINEOUT4_PA_MIXER", NULL, "LINEOUT4 DAC"},
+
+	{"CP", NULL, "CLASS_H_LINEOUTS_PA"},
+	{"CLASS_H_LINEOUTS_PA", NULL, "CLASS_H_CLK"},
+
+	{"LINEOUT1 DAC", NULL, "RX3 MIX1"},
+
+	{"RDAC5 MUX", "DEM3_INV", "RX3 MIX1"},
+	{"RDAC5 MUX", "DEM4", "RX4 MIX1"},
+
+	{"LINEOUT3 DAC", NULL, "RDAC5 MUX"},
+
+	{"LINEOUT2 DAC", NULL, "RX5 MIX1"},
+
+	{"RDAC7 MUX", "DEM5_INV", "RX5 MIX1"},
+	{"RDAC7 MUX", "DEM6", "RX6 MIX1"},
+
+	{"LINEOUT4 DAC", NULL, "RDAC7 MUX"},
+
+	{"SPK PA", NULL, "SPK DAC"},
+	{"SPK DAC", NULL, "RX7 MIX2"},
+
+	{"RX1 CHAIN", NULL, "RX1 MIX2"},
+	{"RX2 CHAIN", NULL, "RX2 MIX2"},
+	{"RX1 CHAIN", NULL, "ANC"},
+	{"RX2 CHAIN", NULL, "ANC"},
+
+	{"CLASS_H_CLK", NULL, "RX_BIAS"},
+	{"LINEOUT1 DAC", NULL, "RX_BIAS"},
+	{"LINEOUT2 DAC", NULL, "RX_BIAS"},
+	{"LINEOUT3 DAC", NULL, "RX_BIAS"},
+	{"LINEOUT4 DAC", NULL, "RX_BIAS"},
+	{"SPK DAC", NULL, "RX_BIAS"},
+
+	{"RX1 MIX1", NULL, "COMP1_CLK"},
+	{"RX2 MIX1", NULL, "COMP1_CLK"},
+	{"RX3 MIX1", NULL, "COMP2_CLK"},
+	{"RX5 MIX1", NULL, "COMP2_CLK"},
+
+	{"RX1 MIX1", NULL, "RX1 MIX1 INP1"},
+	{"RX1 MIX1", NULL, "RX1 MIX1 INP2"},
+	{"RX1 MIX1", NULL, "RX1 MIX1 INP3"},
+	{"RX2 MIX1", NULL, "RX2 MIX1 INP1"},
+	{"RX2 MIX1", NULL, "RX2 MIX1 INP2"},
+	{"RX3 MIX1", NULL, "RX3 MIX1 INP1"},
+	{"RX3 MIX1", NULL, "RX3 MIX1 INP2"},
+	{"RX4 MIX1", NULL, "RX4 MIX1 INP1"},
+	{"RX4 MIX1", NULL, "RX4 MIX1 INP2"},
+	{"RX5 MIX1", NULL, "RX5 MIX1 INP1"},
+	{"RX5 MIX1", NULL, "RX5 MIX1 INP2"},
+	{"RX6 MIX1", NULL, "RX6 MIX1 INP1"},
+	{"RX6 MIX1", NULL, "RX6 MIX1 INP2"},
+	{"RX7 MIX1", NULL, "RX7 MIX1 INP1"},
+	{"RX7 MIX1", NULL, "RX7 MIX1 INP2"},
+	{"RX1 MIX2", NULL, "RX1 MIX1"},
+	{"RX1 MIX2", NULL, "RX1 MIX2 INP1"},
+	{"RX1 MIX2", NULL, "RX1 MIX2 INP2"},
+	{"RX2 MIX2", NULL, "RX2 MIX1"},
+	{"RX2 MIX2", NULL, "RX2 MIX2 INP1"},
+	{"RX2 MIX2", NULL, "RX2 MIX2 INP2"},
+	{"RX7 MIX2", NULL, "RX7 MIX1"},
+	{"RX7 MIX2", NULL, "RX7 MIX2 INP1"},
+	{"RX7 MIX2", NULL, "RX7 MIX2 INP2"},
+
+	/* SLIM_MUX("AIF1_PB", "AIF1 PB"),*/
+	{"SLIM RX1 MUX", "AIF1_PB", "AIF1 PB"},
+	{"SLIM RX2 MUX", "AIF1_PB", "AIF1 PB"},
+	{"SLIM RX3 MUX", "AIF1_PB", "AIF1 PB"},
+	{"SLIM RX4 MUX", "AIF1_PB", "AIF1 PB"},
+	{"SLIM RX5 MUX", "AIF1_PB", "AIF1 PB"},
+	{"SLIM RX6 MUX", "AIF1_PB", "AIF1 PB"},
+	{"SLIM RX7 MUX", "AIF1_PB", "AIF1 PB"},
+	/* SLIM_MUX("AIF2_PB", "AIF2 PB"),*/
+	{"SLIM RX1 MUX", "AIF2_PB", "AIF2 PB"},
+	{"SLIM RX2 MUX", "AIF2_PB", "AIF2 PB"},
+	{"SLIM RX3 MUX", "AIF2_PB", "AIF2 PB"},
+	{"SLIM RX4 MUX", "AIF2_PB", "AIF2 PB"},
+	{"SLIM RX5 MUX", "AIF2_PB", "AIF2 PB"},
+	{"SLIM RX6 MUX", "AIF2_PB", "AIF2 PB"},
+	{"SLIM RX7 MUX", "AIF2_PB", "AIF2 PB"},
+	/* SLIM_MUX("AIF3_PB", "AIF3 PB"),*/
+	{"SLIM RX1 MUX", "AIF3_PB", "AIF3 PB"},
+	{"SLIM RX2 MUX", "AIF3_PB", "AIF3 PB"},
+	{"SLIM RX3 MUX", "AIF3_PB", "AIF3 PB"},
+	{"SLIM RX4 MUX", "AIF3_PB", "AIF3 PB"},
+	{"SLIM RX5 MUX", "AIF3_PB", "AIF3 PB"},
+	{"SLIM RX6 MUX", "AIF3_PB", "AIF3 PB"},
+	{"SLIM RX7 MUX", "AIF3_PB", "AIF3 PB"},
+
+	{"SLIM RX1", NULL, "SLIM RX1 MUX"},
+	{"SLIM RX2", NULL, "SLIM RX2 MUX"},
+	{"SLIM RX3", NULL, "SLIM RX3 MUX"},
+	{"SLIM RX4", NULL, "SLIM RX4 MUX"},
+	{"SLIM RX5", NULL, "SLIM RX5 MUX"},
+	{"SLIM RX6", NULL, "SLIM RX6 MUX"},
+	{"SLIM RX7", NULL, "SLIM RX7 MUX"},
+
+	{"RX1 MIX1 INP1", "RX1", "SLIM RX1"},
+	{"RX1 MIX1 INP1", "RX2", "SLIM RX2"},
+	{"RX1 MIX1 INP1", "RX3", "SLIM RX3"},
+	{"RX1 MIX1 INP1", "RX4", "SLIM RX4"},
+	{"RX1 MIX1 INP1", "RX5", "SLIM RX5"},
+	{"RX1 MIX1 INP1", "RX6", "SLIM RX6"},
+	{"RX1 MIX1 INP1", "RX7", "SLIM RX7"},
+	{"RX1 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX1 MIX1 INP2", "RX1", "SLIM RX1"},
+	{"RX1 MIX1 INP2", "RX2", "SLIM RX2"},
+	{"RX1 MIX1 INP2", "RX3", "SLIM RX3"},
+	{"RX1 MIX1 INP2", "RX4", "SLIM RX4"},
+	{"RX1 MIX1 INP2", "RX5", "SLIM RX5"},
+	{"RX1 MIX1 INP2", "RX6", "SLIM RX6"},
+	{"RX1 MIX1 INP2", "RX7", "SLIM RX7"},
+	{"RX1 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX1 MIX1 INP3", "RX1", "SLIM RX1"},
+	{"RX1 MIX1 INP3", "RX2", "SLIM RX2"},
+	{"RX1 MIX1 INP3", "RX3", "SLIM RX3"},
+	{"RX1 MIX1 INP3", "RX4", "SLIM RX4"},
+	{"RX1 MIX1 INP3", "RX5", "SLIM RX5"},
+	{"RX1 MIX1 INP3", "RX6", "SLIM RX6"},
+	{"RX1 MIX1 INP3", "RX7", "SLIM RX7"},
+	{"RX2 MIX1 INP1", "RX1", "SLIM RX1"},
+	{"RX2 MIX1 INP1", "RX2", "SLIM RX2"},
+	{"RX2 MIX1 INP1", "RX3", "SLIM RX3"},
+	{"RX2 MIX1 INP1", "RX4", "SLIM RX4"},
+	{"RX2 MIX1 INP1", "RX5", "SLIM RX5"},
+	{"RX2 MIX1 INP1", "RX6", "SLIM RX6"},
+	{"RX2 MIX1 INP1", "RX7", "SLIM RX7"},
+	{"RX2 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX2 MIX1 INP2", "RX1", "SLIM RX1"},
+	{"RX2 MIX1 INP2", "RX2", "SLIM RX2"},
+	{"RX2 MIX1 INP2", "RX3", "SLIM RX3"},
+	{"RX2 MIX1 INP2", "RX4", "SLIM RX4"},
+	{"RX2 MIX1 INP2", "RX5", "SLIM RX5"},
+	{"RX2 MIX1 INP2", "RX6", "SLIM RX6"},
+	{"RX2 MIX1 INP2", "RX7", "SLIM RX7"},
+	{"RX2 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX3 MIX1 INP1", "RX1", "SLIM RX1"},
+	{"RX3 MIX1 INP1", "RX2", "SLIM RX2"},
+	{"RX3 MIX1 INP1", "RX3", "SLIM RX3"},
+	{"RX3 MIX1 INP1", "RX4", "SLIM RX4"},
+	{"RX3 MIX1 INP1", "RX5", "SLIM RX5"},
+	{"RX3 MIX1 INP1", "RX6", "SLIM RX6"},
+	{"RX3 MIX1 INP1", "RX7", "SLIM RX7"},
+	{"RX3 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX3 MIX1 INP2", "RX1", "SLIM RX1"},
+	{"RX3 MIX1 INP2", "RX2", "SLIM RX2"},
+	{"RX3 MIX1 INP2", "RX3", "SLIM RX3"},
+	{"RX3 MIX1 INP2", "RX4", "SLIM RX4"},
+	{"RX3 MIX1 INP2", "RX5", "SLIM RX5"},
+	{"RX3 MIX1 INP2", "RX6", "SLIM RX6"},
+	{"RX3 MIX1 INP2", "RX7", "SLIM RX7"},
+	{"RX3 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX4 MIX1 INP1", "RX1", "SLIM RX1"},
+	{"RX4 MIX1 INP1", "RX2", "SLIM RX2"},
+	{"RX4 MIX1 INP1", "RX3", "SLIM RX3"},
+	{"RX4 MIX1 INP1", "RX4", "SLIM RX4"},
+	{"RX4 MIX1 INP1", "RX5", "SLIM RX5"},
+	{"RX4 MIX1 INP1", "RX6", "SLIM RX6"},
+	{"RX4 MIX1 INP1", "RX7", "SLIM RX7"},
+	{"RX4 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX4 MIX1 INP2", "RX1", "SLIM RX1"},
+	{"RX4 MIX1 INP2", "RX2", "SLIM RX2"},
+	{"RX4 MIX1 INP2", "RX3", "SLIM RX3"},
+	{"RX4 MIX1 INP2", "RX5", "SLIM RX5"},
+	{"RX4 MIX1 INP2", "RX4", "SLIM RX4"},
+	{"RX4 MIX1 INP2", "RX6", "SLIM RX6"},
+	{"RX4 MIX1 INP2", "RX7", "SLIM RX7"},
+	{"RX4 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX5 MIX1 INP1", "RX1", "SLIM RX1"},
+	{"RX5 MIX1 INP1", "RX2", "SLIM RX2"},
+	{"RX5 MIX1 INP1", "RX3", "SLIM RX3"},
+	{"RX5 MIX1 INP1", "RX4", "SLIM RX4"},
+	{"RX5 MIX1 INP1", "RX5", "SLIM RX5"},
+	{"RX5 MIX1 INP1", "RX6", "SLIM RX6"},
+	{"RX5 MIX1 INP1", "RX7", "SLIM RX7"},
+	{"RX5 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX5 MIX1 INP2", "RX1", "SLIM RX1"},
+	{"RX5 MIX1 INP2", "RX2", "SLIM RX2"},
+	{"RX5 MIX1 INP2", "RX3", "SLIM RX3"},
+	{"RX5 MIX1 INP2", "RX4", "SLIM RX4"},
+	{"RX5 MIX1 INP2", "RX5", "SLIM RX5"},
+	{"RX5 MIX1 INP2", "RX6", "SLIM RX6"},
+	{"RX5 MIX1 INP2", "RX7", "SLIM RX7"},
+	{"RX5 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX6 MIX1 INP1", "RX1", "SLIM RX1"},
+	{"RX6 MIX1 INP1", "RX2", "SLIM RX2"},
+	{"RX6 MIX1 INP1", "RX3", "SLIM RX3"},
+	{"RX6 MIX1 INP1", "RX4", "SLIM RX4"},
+	{"RX6 MIX1 INP1", "RX5", "SLIM RX5"},
+	{"RX6 MIX1 INP1", "RX6", "SLIM RX6"},
+	{"RX6 MIX1 INP1", "RX7", "SLIM RX7"},
+	{"RX6 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX6 MIX1 INP2", "RX1", "SLIM RX1"},
+	{"RX6 MIX1 INP2", "RX2", "SLIM RX2"},
+	{"RX6 MIX1 INP2", "RX3", "SLIM RX3"},
+	{"RX6 MIX1 INP2", "RX4", "SLIM RX4"},
+	{"RX6 MIX1 INP2", "RX5", "SLIM RX5"},
+	{"RX6 MIX1 INP2", "RX6", "SLIM RX6"},
+	{"RX6 MIX1 INP2", "RX7", "SLIM RX7"},
+	{"RX6 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX7 MIX1 INP1", "RX1", "SLIM RX1"},
+	{"RX7 MIX1 INP1", "RX2", "SLIM RX2"},
+	{"RX7 MIX1 INP1", "RX3", "SLIM RX3"},
+	{"RX7 MIX1 INP1", "RX4", "SLIM RX4"},
+	{"RX7 MIX1 INP1", "RX5", "SLIM RX5"},
+	{"RX7 MIX1 INP1", "RX6", "SLIM RX6"},
+	{"RX7 MIX1 INP1", "RX7", "SLIM RX7"},
+	{"RX7 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX7 MIX1 INP2", "RX1", "SLIM RX1"},
+	{"RX7 MIX1 INP2", "RX2", "SLIM RX2"},
+	{"RX7 MIX1 INP2", "RX3", "SLIM RX3"},
+	{"RX7 MIX1 INP2", "RX4", "SLIM RX4"},
+	{"RX7 MIX1 INP2", "RX5", "SLIM RX5"},
+	{"RX7 MIX1 INP2", "RX6", "SLIM RX6"},
+	{"RX7 MIX1 INP2", "RX7", "SLIM RX7"},
+	{"RX7 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX1 MIX2 INP1", "IIR1", "IIR1"},
+	{"RX1 MIX2 INP2", "IIR1", "IIR1"},
+	{"RX2 MIX2 INP1", "IIR1", "IIR1"},
+	{"RX2 MIX2 INP2", "IIR1", "IIR1"},
+	{"RX7 MIX2 INP1", "IIR1", "IIR1"},
+	{"RX7 MIX2 INP2", "IIR1", "IIR1"},
+
+	/* Decimator Inputs */
+	{"DEC1 MUX", "DMIC1", "DMIC1"},
+	{"DEC1 MUX", "ADC6", "ADC6"},
+	{"DEC1 MUX", NULL, "CDC_CONN"},
+	{"DEC2 MUX", "DMIC2", "DMIC2"},
+	{"DEC2 MUX", "ADC5", "ADC5"},
+	{"DEC2 MUX", NULL, "CDC_CONN"},
+	{"DEC3 MUX", "DMIC3", "DMIC3"},
+	{"DEC3 MUX", "ADC4", "ADC4"},
+	{"DEC3 MUX", NULL, "CDC_CONN"},
+	{"DEC4 MUX", "DMIC4", "DMIC4"},
+	{"DEC4 MUX", "ADC3", "ADC3"},
+	{"DEC4 MUX", NULL, "CDC_CONN"},
+	{"DEC5 MUX", "DMIC5", "DMIC5"},
+	{"DEC5 MUX", "ADC2", "ADC2"},
+	{"DEC5 MUX", NULL, "CDC_CONN"},
+	{"DEC6 MUX", "DMIC6", "DMIC6"},
+	{"DEC6 MUX", "ADC1", "ADC1"},
+	{"DEC6 MUX", NULL, "CDC_CONN"},
+	{"DEC7 MUX", "DMIC1", "DMIC1"},
+	{"DEC7 MUX", "DMIC6", "DMIC6"},
+	{"DEC7 MUX", "ADC1", "ADC1"},
+	{"DEC7 MUX", "ADC6", "ADC6"},
+	{"DEC7 MUX", NULL, "CDC_CONN"},
+	{"DEC8 MUX", "DMIC2", "DMIC2"},
+	{"DEC8 MUX", "DMIC5", "DMIC5"},
+	{"DEC8 MUX", "ADC2", "ADC2"},
+	{"DEC8 MUX", "ADC5", "ADC5"},
+	{"DEC8 MUX", NULL, "CDC_CONN"},
+	{"DEC9 MUX", "DMIC4", "DMIC4"},
+	{"DEC9 MUX", "DMIC5", "DMIC5"},
+	{"DEC9 MUX", "ADC2", "ADC2"},
+	{"DEC9 MUX", "ADC3", "ADC3"},
+	{"DEC9 MUX", NULL, "CDC_CONN"},
+	{"DEC10 MUX", "DMIC3", "DMIC3"},
+	{"DEC10 MUX", "DMIC6", "DMIC6"},
+	{"DEC10 MUX", "ADC1", "ADC1"},
+	{"DEC10 MUX", "ADC4", "ADC4"},
+	{"DEC10 MUX", NULL, "CDC_CONN"},
+
+	/* ADC Connections */
+	{"ADC1", NULL, "AMIC1"},
+	{"ADC2", NULL, "AMIC2"},
+	{"ADC3", NULL, "AMIC3"},
+	{"ADC4", NULL, "AMIC4"},
+	{"ADC5", NULL, "AMIC5"},
+	{"ADC6", NULL, "AMIC6"},
+
+	/* AUX PGA Connections */
+	{"EAR_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
+	{"HPHL_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
+	{"HPHR_PA_MIXER", "AUX_PGA_R Switch", "AUX_PGA_Right"},
+	{"LINEOUT1_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
+	{"LINEOUT2_PA_MIXER", "AUX_PGA_R Switch", "AUX_PGA_Right"},
+	{"LINEOUT3_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
+	{"LINEOUT4_PA_MIXER", "AUX_PGA_R Switch", "AUX_PGA_Right"},
+	{"AUX_PGA_Left", NULL, "AMIC5"},
+	{"AUX_PGA_Right", NULL, "AMIC6"},
+
+	{"IIR1", NULL, "IIR1 INP1 MUX"},
+	{"IIR1 INP1 MUX", "DEC1", "DEC1 MUX"},
+	{"IIR1 INP1 MUX", "DEC2", "DEC2 MUX"},
+	{"IIR1 INP1 MUX", "DEC3", "DEC3 MUX"},
+	{"IIR1 INP1 MUX", "DEC4", "DEC4 MUX"},
+	{"IIR1 INP1 MUX", "DEC5", "DEC5 MUX"},
+	{"IIR1 INP1 MUX", "DEC6", "DEC6 MUX"},
+	{"IIR1 INP1 MUX", "DEC7", "DEC7 MUX"},
+	{"IIR1 INP1 MUX", "DEC8", "DEC8 MUX"},
+	{"IIR1 INP1 MUX", "DEC9", "DEC9 MUX"},
+	{"IIR1 INP1 MUX", "DEC10", "DEC10 MUX"},
+
+	{"MIC BIAS1 Internal1", NULL, "LDO_H"},
+	{"MIC BIAS1 Internal2", NULL, "LDO_H"},
+	{"MIC BIAS1 External", NULL, "LDO_H"},
+	{"MIC BIAS2 Internal1", NULL, "LDO_H"},
+	{"MIC BIAS2 Internal2", NULL, "LDO_H"},
+	{"MIC BIAS2 Internal3", NULL, "LDO_H"},
+	{"MIC BIAS2 External", NULL, "LDO_H"},
+	{"MIC BIAS3 Internal1", NULL, "LDO_H"},
+	{"MIC BIAS3 Internal2", NULL, "LDO_H"},
+	{"MIC BIAS3 External", NULL, "LDO_H"},
+	{"MIC BIAS4 External", NULL, "LDO_H"},
+};
+
+static int tapan_readable(struct snd_soc_codec *ssc, unsigned int reg)
+{
+	return tapan_reg_readable[reg];
+}
+
+static bool tapan_is_digital_gain_register(unsigned int reg)
+{
+	bool rtn = false;
+	switch (reg) {
+	case TAPAN_A_CDC_RX1_VOL_CTL_B2_CTL:
+	case TAPAN_A_CDC_RX2_VOL_CTL_B2_CTL:
+	case TAPAN_A_CDC_RX3_VOL_CTL_B2_CTL:
+	case TAPAN_A_CDC_RX4_VOL_CTL_B2_CTL:
+	case TAPAN_A_CDC_TX1_VOL_CTL_GAIN:
+	case TAPAN_A_CDC_TX2_VOL_CTL_GAIN:
+	case TAPAN_A_CDC_TX3_VOL_CTL_GAIN:
+	case TAPAN_A_CDC_TX4_VOL_CTL_GAIN:
+		rtn = true;
+		break;
+	default:
+		break;
+	}
+	return rtn;
+}
+
+static int tapan_volatile(struct snd_soc_codec *ssc, unsigned int reg)
+{
+	/* Registers lower than 0x100 are top level registers which can be
+	 * written by the Taiko core driver.
+	 */
+
+	if ((reg >= TAPAN_A_CDC_MBHC_EN_CTL) || (reg < 0x100))
+		return 1;
+
+	/* IIR Coeff registers are not cacheable */
+	if ((reg >= TAPAN_A_CDC_IIR1_COEF_B1_CTL) &&
+		(reg <= TAPAN_A_CDC_IIR2_COEF_B2_CTL))
+		return 1;
+
+	/* Digital gain register is not cacheable so we have to write
+	 * the setting even it is the same
+	 */
+	if (tapan_is_digital_gain_register(reg))
+		return 1;
+
+	/* HPH status registers */
+	if (reg == TAPAN_A_RX_HPH_L_STATUS || reg == TAPAN_A_RX_HPH_R_STATUS)
+		return 1;
+
+	if (reg == TAPAN_A_MBHC_INSERT_DET_STATUS)
+		return 1;
+
+	return 0;
+}
+
+#define TAPAN_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
+static int tapan_write(struct snd_soc_codec *codec, unsigned int reg,
+	unsigned int value)
+{
+	int ret;
+
+	if (reg == SND_SOC_NOPM)
+		return 0;
+
+	BUG_ON(reg > TAPAN_MAX_REGISTER);
+
+	if (!tapan_volatile(codec, reg)) {
+		ret = snd_soc_cache_write(codec, reg, value);
+		if (ret != 0)
+			dev_err(codec->dev, "Cache write to %x failed: %d\n",
+				reg, ret);
+	}
+
+	return wcd9xxx_reg_write(codec->control_data, reg, value);
+}
+static unsigned int tapan_read(struct snd_soc_codec *codec,
+				unsigned int reg)
+{
+	unsigned int val;
+	int ret;
+
+	if (reg == SND_SOC_NOPM)
+		return 0;
+
+	BUG_ON(reg > TAPAN_MAX_REGISTER);
+
+	if (!tapan_volatile(codec, reg) && tapan_readable(codec, reg) &&
+		reg < codec->driver->reg_cache_size) {
+		ret = snd_soc_cache_read(codec, reg, &val);
+		if (ret >= 0) {
+			return val;
+		} else
+			dev_err(codec->dev, "Cache read from %x failed: %d\n",
+				reg, ret);
+	}
+
+	val = wcd9xxx_reg_read(codec->control_data, reg);
+	return val;
+}
+
+static int tapan_startup(struct snd_pcm_substream *substream,
+		struct snd_soc_dai *dai)
+{
+	struct wcd9xxx *tapan_core = dev_get_drvdata(dai->codec->dev->parent);
+	dev_dbg(dai->codec->dev, "%s(): substream = %s  stream = %d\n",
+		 __func__, substream->name, substream->stream);
+	if ((tapan_core != NULL) &&
+	    (tapan_core->dev != NULL) &&
+	    (tapan_core->dev->parent != NULL))
+		pm_runtime_get_sync(tapan_core->dev->parent);
+
+	return 0;
+}
+
+static void tapan_shutdown(struct snd_pcm_substream *substream,
+		struct snd_soc_dai *dai)
+{
+	struct wcd9xxx *tapan_core = dev_get_drvdata(dai->codec->dev->parent);
+	dev_dbg(dai->codec->dev, "%s(): substream = %s  stream = %d\n",
+		 __func__, substream->name, substream->stream);
+	if ((tapan_core != NULL) &&
+	    (tapan_core->dev != NULL) &&
+	    (tapan_core->dev->parent != NULL)) {
+		pm_runtime_mark_last_busy(tapan_core->dev->parent);
+		pm_runtime_put(tapan_core->dev->parent);
+	}
+}
+
+int tapan_mclk_enable(struct snd_soc_codec *codec, int mclk_enable, bool dapm)
+{
+	struct tapan_priv *tapan = snd_soc_codec_get_drvdata(codec);
+
+	dev_dbg(codec->dev, "%s: mclk_enable = %u, dapm = %d\n", __func__,
+		 mclk_enable, dapm);
+
+	WCD9XXX_BCL_LOCK(&tapan->resmgr);
+	if (mclk_enable) {
+		wcd9xxx_resmgr_get_bandgap(&tapan->resmgr,
+					   WCD9XXX_BANDGAP_AUDIO_MODE);
+		wcd9xxx_resmgr_get_clk_block(&tapan->resmgr, WCD9XXX_CLK_MCLK);
+	} else {
+		/* Put clock and BG */
+		wcd9xxx_resmgr_put_clk_block(&tapan->resmgr, WCD9XXX_CLK_MCLK);
+		wcd9xxx_resmgr_put_bandgap(&tapan->resmgr,
+					   WCD9XXX_BANDGAP_AUDIO_MODE);
+	}
+	WCD9XXX_BCL_UNLOCK(&tapan->resmgr);
+
+	return 0;
+}
+
+static int tapan_set_dai_sysclk(struct snd_soc_dai *dai,
+		int clk_id, unsigned int freq, int dir)
+{
+	dev_dbg(dai->codec->dev, "%s\n", __func__);
+	return 0;
+}
+
+static int tapan_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	return 0;
+}
+
+static int tapan_set_channel_map(struct snd_soc_dai *dai,
+				unsigned int tx_num, unsigned int *tx_slot,
+				unsigned int rx_num, unsigned int *rx_slot)
+
+{
+	struct tapan_priv *tapan = snd_soc_codec_get_drvdata(dai->codec);
+	struct wcd9xxx *core = dev_get_drvdata(dai->codec->dev->parent);
+	if (!tx_slot && !rx_slot) {
+		pr_err("%s: Invalid\n", __func__);
+		return -EINVAL;
+	}
+	dev_dbg(dai->codec->dev, "%s(): dai_name = %s DAI-ID %x\n",
+		 __func__, dai->name, dai->id);
+	dev_dbg(dai->codec->dev, "%s(): tx_ch %d rx_ch %d\n intf_type %d\n",
+		 __func__, tx_num, rx_num, tapan->intf_type);
+
+	if (tapan->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
+		wcd9xxx_init_slimslave(core, core->slim->laddr,
+				       tx_num, tx_slot, rx_num, rx_slot);
+	return 0;
+}
+
+static int tapan_get_channel_map(struct snd_soc_dai *dai,
+				 unsigned int *tx_num, unsigned int *tx_slot,
+				 unsigned int *rx_num, unsigned int *rx_slot)
+
+{
+	struct tapan_priv *tapan_p = snd_soc_codec_get_drvdata(dai->codec);
+	u32 i = 0;
+	struct wcd9xxx_ch *ch;
+
+	switch (dai->id) {
+	case AIF1_PB:
+	case AIF2_PB:
+	case AIF3_PB:
+		if (!rx_slot || !rx_num) {
+			pr_err("%s: Invalid rx_slot %d or rx_num %d\n",
+				 __func__, (u32) rx_slot, (u32) rx_num);
+			return -EINVAL;
+		}
+		list_for_each_entry(ch, &tapan_p->dai[dai->id].wcd9xxx_ch_list,
+				    list) {
+			dev_dbg(dai->codec->dev, "%s: rx_slot[%d] %d ch->ch_num %d\n",
+				 __func__, i, rx_slot[i], ch->ch_num);
+			rx_slot[i++] = ch->ch_num;
+		}
+		dev_dbg(dai->codec->dev, "%s: rx_num %d\n", __func__, i);
+		*rx_num = i;
+		break;
+	case AIF1_CAP:
+	case AIF2_CAP:
+	case AIF3_CAP:
+		if (!tx_slot || !tx_num) {
+			pr_err("%s: Invalid tx_slot %d or tx_num %d\n",
+				 __func__, (u32) tx_slot, (u32) tx_num);
+			return -EINVAL;
+		}
+		list_for_each_entry(ch, &tapan_p->dai[dai->id].wcd9xxx_ch_list,
+				    list) {
+			dev_dbg(dai->codec->dev, "%s: tx_slot[%d] %d, ch->ch_num %d\n",
+				 __func__, i, tx_slot[i], ch->ch_num);
+			tx_slot[i++] = ch->ch_num;
+		}
+		dev_dbg(dai->codec->dev, "%s: tx_num %d\n", __func__, i);
+		*tx_num = i;
+		break;
+
+	default:
+		pr_err("%s: Invalid DAI ID %x\n", __func__, dai->id);
+		break;
+	}
+
+	return 0;
+}
+
+static int tapan_set_interpolator_rate(struct snd_soc_dai *dai,
+	u8 rx_fs_rate_reg_val, u32 sample_rate)
+{
+	u32 j;
+	u8 rx_mix1_inp;
+	u16 rx_mix_1_reg_1, rx_mix_1_reg_2;
+	u16 rx_fs_reg;
+	u8 rx_mix_1_reg_1_val, rx_mix_1_reg_2_val;
+	struct snd_soc_codec *codec = dai->codec;
+	struct wcd9xxx_ch *ch;
+	struct tapan_priv *tapan = snd_soc_codec_get_drvdata(codec);
+
+	list_for_each_entry(ch, &tapan->dai[dai->id].wcd9xxx_ch_list, list) {
+		/* for RX port starting from 16 instead of 10 like tabla */
+		rx_mix1_inp = ch->port + RX_MIX1_INP_SEL_RX1 -
+			      TAPAN_TX_PORT_NUMBER;
+		if ((rx_mix1_inp < RX_MIX1_INP_SEL_RX1) ||
+			(rx_mix1_inp > RX_MIX1_INP_SEL_RX7)) {
+			pr_err("%s: Invalid TAPAN_RX%u port. Dai ID is %d\n",
+				__func__,  rx_mix1_inp - 5 , dai->id);
+			return -EINVAL;
+		}
+
+		rx_mix_1_reg_1 = TAPAN_A_CDC_CONN_RX1_B1_CTL;
+
+		for (j = 0; j < NUM_INTERPOLATORS; j++) {
+			rx_mix_1_reg_2 = rx_mix_1_reg_1 + 1;
+
+			rx_mix_1_reg_1_val = snd_soc_read(codec,
+							  rx_mix_1_reg_1);
+			rx_mix_1_reg_2_val = snd_soc_read(codec,
+							  rx_mix_1_reg_2);
+
+			if (((rx_mix_1_reg_1_val & 0x0F) == rx_mix1_inp) ||
+			    (((rx_mix_1_reg_1_val >> 4) & 0x0F)
+				== rx_mix1_inp) ||
+			    ((rx_mix_1_reg_2_val & 0x0F) == rx_mix1_inp)) {
+
+				rx_fs_reg = TAPAN_A_CDC_RX1_B5_CTL + 8 * j;
+
+				dev_dbg(codec->dev, "%s: AIF_PB DAI(%d) connected to RX%u\n",
+					__func__, dai->id, j + 1);
+
+				dev_dbg(codec->dev, "%s: set RX%u sample rate to %u\n",
+					__func__, j + 1, sample_rate);
+
+				snd_soc_update_bits(codec, rx_fs_reg,
+						0xE0, rx_fs_rate_reg_val);
+
+			}
+			if (j <= 2)
+				rx_mix_1_reg_1 += 3;
+			else
+				rx_mix_1_reg_1 += 2;
+		}
+	}
+	return 0;
+}
+
+static int tapan_set_decimator_rate(struct snd_soc_dai *dai,
+	u8 tx_fs_rate_reg_val, u32 sample_rate)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	struct wcd9xxx_ch *ch;
+	struct tapan_priv *tapan = snd_soc_codec_get_drvdata(codec);
+	u32 tx_port;
+	u16 tx_port_reg, tx_fs_reg;
+	u8 tx_port_reg_val;
+	s8 decimator;
+
+	list_for_each_entry(ch, &tapan->dai[dai->id].wcd9xxx_ch_list, list) {
+
+		tx_port = ch->port + 1;
+		dev_dbg(codec->dev, "%s: dai->id = %d, tx_port = %d",
+			__func__, dai->id, tx_port);
+
+		if ((tx_port < 1) || (tx_port > NUM_DECIMATORS)) {
+			pr_err("%s: Invalid SLIM TX%u port. DAI ID is %d\n",
+				__func__, tx_port, dai->id);
+			return -EINVAL;
+		}
+
+		tx_port_reg = TAPAN_A_CDC_CONN_TX_SB_B1_CTL + (tx_port - 1);
+		tx_port_reg_val =  snd_soc_read(codec, tx_port_reg);
+
+		decimator = 0;
+
+		if ((tx_port >= 1) && (tx_port <= 6)) {
+
+			tx_port_reg_val =  tx_port_reg_val & 0x0F;
+			if (tx_port_reg_val == 0x8)
+				decimator = tx_port;
+
+		} else if ((tx_port >= 7) && (tx_port <= NUM_DECIMATORS)) {
+
+			tx_port_reg_val =  tx_port_reg_val & 0x1F;
+
+			if ((tx_port_reg_val >= 0x8) &&
+			    (tx_port_reg_val <= 0x11)) {
+
+				decimator = (tx_port_reg_val - 0x8) + 1;
+			}
+		}
+
+		if (decimator) { /* SLIM_TX port has a DEC as input */
+
+			tx_fs_reg = TAPAN_A_CDC_TX1_CLK_FS_CTL +
+				    8 * (decimator - 1);
+
+			dev_dbg(codec->dev, "%s: set DEC%u (-> SLIM_TX%u) rate to %u\n",
+				__func__, decimator, tx_port, sample_rate);
+
+			snd_soc_update_bits(codec, tx_fs_reg, 0x07,
+					    tx_fs_rate_reg_val);
+
+		} else {
+			if ((tx_port_reg_val >= 0x1) &&
+			    (tx_port_reg_val <= 0x7)) {
+
+				dev_dbg(codec->dev, "%s: RMIX%u going to SLIM TX%u\n",
+					__func__, tx_port_reg_val, tx_port);
+
+			} else if  ((tx_port_reg_val >= 0x8) &&
+				    (tx_port_reg_val <= 0x11)) {
+
+				pr_err("%s: ERROR: Should not be here\n",
+				       __func__);
+				pr_err("%s: ERROR: DEC connected to SLIM TX%u\n",
+					__func__, tx_port);
+				return -EINVAL;
+
+			} else if (tx_port_reg_val == 0) {
+				dev_dbg(codec->dev, "%s: no signal to SLIM TX%u\n",
+					__func__, tx_port);
+			} else {
+				pr_err("%s: ERROR: wrong signal to SLIM TX%u\n",
+					__func__, tx_port);
+				pr_err("%s: ERROR: wrong signal = %u\n",
+					__func__, tx_port_reg_val);
+				return -EINVAL;
+			}
+		}
+	}
+	return 0;
+}
+
+static int tapan_hw_params(struct snd_pcm_substream *substream,
+			    struct snd_pcm_hw_params *params,
+			    struct snd_soc_dai *dai)
+{
+	struct tapan_priv *tapan = snd_soc_codec_get_drvdata(dai->codec);
+	u8 tx_fs_rate, rx_fs_rate;
+	int ret;
+
+	dev_dbg(dai->codec->dev, "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n",
+		 __func__, dai->name, dai->id,
+		 params_rate(params), params_channels(params));
+
+	switch (params_rate(params)) {
+	case 8000:
+		tx_fs_rate = 0x00;
+		rx_fs_rate = 0x00;
+		break;
+	case 16000:
+		tx_fs_rate = 0x01;
+		rx_fs_rate = 0x20;
+		break;
+	case 32000:
+		tx_fs_rate = 0x02;
+		rx_fs_rate = 0x40;
+		break;
+	case 48000:
+		tx_fs_rate = 0x03;
+		rx_fs_rate = 0x60;
+		break;
+	case 96000:
+		tx_fs_rate = 0x04;
+		rx_fs_rate = 0x80;
+		break;
+	case 192000:
+		tx_fs_rate = 0x05;
+		rx_fs_rate = 0xA0;
+		break;
+	default:
+		pr_err("%s: Invalid sampling rate %d\n", __func__,
+			params_rate(params));
+		return -EINVAL;
+	}
+
+	switch (substream->stream) {
+	case SNDRV_PCM_STREAM_CAPTURE:
+		ret = tapan_set_decimator_rate(dai, tx_fs_rate,
+					       params_rate(params));
+		if (ret < 0) {
+			pr_err("%s: set decimator rate failed %d\n", __func__,
+				ret);
+			return ret;
+		}
+
+		if (tapan->intf_type == WCD9XXX_INTERFACE_TYPE_I2C)
+			pr_err("%s: I2C interface not yet supported\n",
+				   __func__);
+		else
+			tapan->dai[dai->id].rate = params_rate(params);
+
+		break;
+
+	case SNDRV_PCM_STREAM_PLAYBACK:
+		ret = tapan_set_interpolator_rate(dai, rx_fs_rate,
+						  params_rate(params));
+		if (ret < 0) {
+			pr_err("%s: set decimator rate failed %d\n", __func__,
+				ret);
+			return ret;
+		}
+		if (tapan->intf_type == WCD9XXX_INTERFACE_TYPE_I2C)
+			pr_err("%s: I2C interface not yet supported\n",
+				   __func__);
+		else
+			tapan->dai[dai->id].rate   = params_rate(params);
+
+		break;
+	default:
+		pr_err("%s: Invalid stream type %d\n", __func__,
+			substream->stream);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct snd_soc_dai_ops tapan_dai_ops = {
+	.startup = tapan_startup,
+	.shutdown = tapan_shutdown,
+	.hw_params = tapan_hw_params,
+	.set_sysclk = tapan_set_dai_sysclk,
+	.set_fmt = tapan_set_dai_fmt,
+	.set_channel_map = tapan_set_channel_map,
+	.get_channel_map = tapan_get_channel_map,
+};
+
+static struct snd_soc_dai_driver tapan_dai[] = {
+	{
+		.name = "tapan_rx1",
+		.id = AIF1_PB,
+		.playback = {
+			.stream_name = "AIF1 Playback",
+			.rates = WCD9306_RATES,
+			.formats = TAPAN_FORMATS,
+			.rate_max = 192000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 2,
+		},
+		.ops = &tapan_dai_ops,
+	},
+	{
+		.name = "tapan_tx1",
+		.id = AIF1_CAP,
+		.capture = {
+			.stream_name = "AIF1 Capture",
+			.rates = WCD9306_RATES,
+			.formats = TAPAN_FORMATS,
+			.rate_max = 192000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 4,
+		},
+		.ops = &tapan_dai_ops,
+	},
+	{
+		.name = "tapan_rx2",
+		.id = AIF2_PB,
+		.playback = {
+			.stream_name = "AIF2 Playback",
+			.rates = WCD9306_RATES,
+			.formats = TAPAN_FORMATS,
+			.rate_min = 8000,
+			.rate_max = 192000,
+			.channels_min = 1,
+			.channels_max = 2,
+		},
+		.ops = &tapan_dai_ops,
+	},
+	{
+		.name = "tapan_tx2",
+		.id = AIF2_CAP,
+		.capture = {
+			.stream_name = "AIF2 Capture",
+			.rates = WCD9306_RATES,
+			.formats = TAPAN_FORMATS,
+			.rate_max = 192000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 4,
+		},
+		.ops = &tapan_dai_ops,
+	},
+	{
+		.name = "tapan_tx3",
+		.id = AIF3_CAP,
+		.capture = {
+			.stream_name = "AIF3 Capture",
+			.rates = WCD9306_RATES,
+			.formats = TAPAN_FORMATS,
+			.rate_max = 48000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 2,
+		},
+		.ops = &tapan_dai_ops,
+	},
+	{
+		.name = "tapan_rx3",
+		.id = AIF3_PB,
+		.playback = {
+			.stream_name = "AIF3 Playback",
+			.rates = WCD9306_RATES,
+			.formats = TAPAN_FORMATS,
+			.rate_min = 8000,
+			.rate_max = 192000,
+			.channels_min = 1,
+			.channels_max = 2,
+		},
+		.ops = &tapan_dai_ops,
+	},
+};
+
+static struct snd_soc_dai_driver tapan_i2s_dai[] = {
+	{
+		.name = "tapan_i2s_rx1",
+		.id = AIF1_PB,
+		.playback = {
+			.stream_name = "AIF1 Playback",
+			.rates = WCD9306_RATES,
+			.formats = TAPAN_FORMATS,
+			.rate_max = 192000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 4,
+		},
+		.ops = &tapan_dai_ops,
+	},
+	{
+		.name = "tapan_i2s_tx1",
+		.id = AIF1_CAP,
+		.capture = {
+			.stream_name = "AIF1 Capture",
+			.rates = WCD9306_RATES,
+			.formats = TAPAN_FORMATS,
+			.rate_max = 192000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 4,
+		},
+		.ops = &tapan_dai_ops,
+	},
+};
+
+static int tapan_codec_enable_slimrx(struct snd_soc_dapm_widget *w,
+				     struct snd_kcontrol *kcontrol,
+				     int event)
+{
+	struct wcd9xxx *core;
+	struct snd_soc_codec *codec = w->codec;
+	struct tapan_priv *tapan_p = snd_soc_codec_get_drvdata(codec);
+	u32  ret = 0;
+	struct wcd9xxx_codec_dai_data *dai;
+
+	core = dev_get_drvdata(codec->dev->parent);
+
+	dev_dbg(codec->dev, "%s: event called! codec name %s\n",
+		__func__, w->codec->name);
+	dev_dbg(codec->dev, "%s: num_dai %d stream name %s event %d\n",
+		__func__, w->codec->num_dai, w->sname, event);
+
+	/* Execute the callback only if interface type is slimbus */
+	if (tapan_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS)
+		return 0;
+
+	dai = &tapan_p->dai[w->shift];
+	dev_dbg(codec->dev, "%s: w->name %s w->shift %d event %d\n",
+		 __func__, w->name, w->shift, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		ret = wcd9xxx_cfg_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
+					      dai->rate, dai->bit_width,
+					      &dai->grph);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		ret = wcd9xxx_close_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
+						dai->grph);
+		usleep_range(15000, 15000);
+		break;
+	}
+	return ret;
+}
+
+static int tapan_codec_enable_slimtx(struct snd_soc_dapm_widget *w,
+				     struct snd_kcontrol *kcontrol,
+				     int event)
+{
+	struct wcd9xxx *core;
+	struct snd_soc_codec *codec = w->codec;
+	struct tapan_priv *tapan_p = snd_soc_codec_get_drvdata(codec);
+	u32  ret = 0;
+	struct wcd9xxx_codec_dai_data *dai;
+
+	core = dev_get_drvdata(codec->dev->parent);
+
+	dev_dbg(codec->dev, "%s: event called! codec name %s\n",
+		__func__, w->codec->name);
+	dev_dbg(codec->dev, "%s: num_dai %d stream name %s\n",
+		__func__, w->codec->num_dai, w->sname);
+
+	/* Execute the callback only if interface type is slimbus */
+	if (tapan_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS)
+		return 0;
+
+	dev_dbg(codec->dev, "%s(): w->name %s event %d w->shift %d\n",
+		__func__, w->name, event, w->shift);
+
+	dai = &tapan_p->dai[w->shift];
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
+					      dai->rate, dai->bit_width,
+					      &dai->grph);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
+						dai->grph);
+		break;
+	}
+	return ret;
+}
+
+static int tapan_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+
+	dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
+
+	switch (event) {
+
+	case SND_SOC_DAPM_POST_PMU:
+
+		snd_soc_update_bits(codec, TAPAN_A_BUCK_MODE_5, 0x02, 0x00);
+		snd_soc_update_bits(codec, TAPAN_A_NCP_STATIC, 0x20, 0x00);
+		snd_soc_update_bits(codec, TAPAN_A_BUCK_MODE_3, 0x04, 0x04);
+		snd_soc_update_bits(codec, TAPAN_A_BUCK_MODE_3, 0x08, 0x00);
+
+		usleep_range(5000, 5000);
+		break;
+	}
+	return 0;
+}
+
+/* Todo: Have seperate dapm widgets for I2S and Slimbus.
+ * Might Need to have callbacks registered only for slimbus
+ */
+static const struct snd_soc_dapm_widget tapan_dapm_widgets[] = {
+	/*RX stuff */
+	SND_SOC_DAPM_OUTPUT("EAR"),
+
+	SND_SOC_DAPM_PGA_E("EAR PA", TAPAN_A_RX_EAR_EN, 4, 0, NULL, 0,
+			tapan_codec_enable_ear_pa, SND_SOC_DAPM_POST_PMU),
+
+	SND_SOC_DAPM_MIXER("DAC1", TAPAN_A_RX_EAR_EN, 6, 0, dac1_switch,
+		ARRAY_SIZE(dac1_switch)),
+
+	SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM,
+				AIF1_PB, 0, tapan_codec_enable_slimrx,
+				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_AIF_IN_E("AIF2 PB", "AIF2 Playback", 0, SND_SOC_NOPM,
+				AIF2_PB, 0, tapan_codec_enable_slimrx,
+				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM,
+				AIF3_PB, 0, tapan_codec_enable_slimrx,
+				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX("SLIM RX1 MUX", SND_SOC_NOPM, TAPAN_RX1, 0,
+				&slim_rx_mux[TAPAN_RX1]),
+	SND_SOC_DAPM_MUX("SLIM RX2 MUX", SND_SOC_NOPM, TAPAN_RX2, 0,
+				&slim_rx_mux[TAPAN_RX2]),
+	SND_SOC_DAPM_MUX("SLIM RX3 MUX", SND_SOC_NOPM, TAPAN_RX3, 0,
+				&slim_rx_mux[TAPAN_RX3]),
+	SND_SOC_DAPM_MUX("SLIM RX4 MUX", SND_SOC_NOPM, TAPAN_RX4, 0,
+				&slim_rx_mux[TAPAN_RX4]),
+	SND_SOC_DAPM_MUX("SLIM RX5 MUX", SND_SOC_NOPM, TAPAN_RX5, 0,
+				&slim_rx_mux[TAPAN_RX5]),
+
+	SND_SOC_DAPM_MIXER("SLIM RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("SLIM RX2", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("SLIM RX3", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("SLIM RX4", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("SLIM RX5", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+	/* Headphone */
+	SND_SOC_DAPM_OUTPUT("HEADPHONE"),
+	SND_SOC_DAPM_PGA_E("HPHL", TAPAN_A_RX_HPH_CNP_EN, 5, 0, NULL, 0,
+		tapan_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MIXER("HPHL DAC", TAPAN_A_RX_HPH_L_DAC_CTL, 7, 0,
+		hphl_switch, ARRAY_SIZE(hphl_switch)),
+
+	SND_SOC_DAPM_PGA_E("HPHR", TAPAN_A_RX_HPH_CNP_EN, 4, 0, NULL, 0,
+		tapan_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU |	SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_DAC_E("HPHR DAC", NULL, TAPAN_A_RX_HPH_R_DAC_CTL, 7, 0,
+		tapan_hphr_dac_event,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	/* Speaker */
+	SND_SOC_DAPM_OUTPUT("LINEOUT1"),
+	SND_SOC_DAPM_OUTPUT("LINEOUT2"),
+	SND_SOC_DAPM_OUTPUT("SPK_OUT"),
+
+	SND_SOC_DAPM_PGA_E("LINEOUT1 PA", TAPAN_A_RX_LINE_CNP_EN, 0, 0, NULL,
+			0, tapan_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
+			SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_PGA_E("LINEOUT2 PA", TAPAN_A_RX_LINE_CNP_EN, 1, 0, NULL,
+			0, tapan_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
+			SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_PGA_E("SPK PA", TAPAN_A_SPKR_DRV_EN, 7, 0 , NULL,
+			   0, tapan_codec_enable_spk_pa, SND_SOC_DAPM_PRE_PMU |
+			   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_DAC_E("LINEOUT1 DAC", NULL, TAPAN_A_RX_LINE_1_DAC_CTL, 7, 0
+		, tapan_lineout_dac_event,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_DAC_E("LINEOUT2 DAC", NULL, TAPAN_A_RX_LINE_2_DAC_CTL, 7, 0
+		, tapan_lineout_dac_event,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_DAC_E("SPK DAC", NULL, SND_SOC_NOPM, 0, 0,
+			   tapan_spk_dac_event,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MIXER("RX1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("RX2 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+	SND_SOC_DAPM_MIXER_E("RX1 MIX2", TAPAN_A_CDC_CLK_RX_B1_CTL, 0, 0, NULL,
+		0, tapan_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU),
+	SND_SOC_DAPM_MIXER_E("RX2 MIX2", TAPAN_A_CDC_CLK_RX_B1_CTL, 1, 0, NULL,
+		0, tapan_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU),
+	SND_SOC_DAPM_MIXER_E("RX3 MIX1", TAPAN_A_CDC_CLK_RX_B1_CTL, 2, 0, NULL,
+		0, tapan_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU),
+	SND_SOC_DAPM_MIXER_E("RX4 MIX1", TAPAN_A_CDC_CLK_RX_B1_CTL, 3, 0, NULL,
+		0, tapan_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU),
+	SND_SOC_DAPM_MIXER_E("RX5 MIX1", TAPAN_A_CDC_CLK_RX_B1_CTL, 4, 0, NULL,
+		0, tapan_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU),
+
+	SND_SOC_DAPM_MIXER("RX1 CHAIN", TAPAN_A_CDC_RX1_B6_CTL, 5, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("RX2 CHAIN", TAPAN_A_CDC_RX2_B6_CTL, 5, 0, NULL, 0),
+
+	SND_SOC_DAPM_MUX("RX1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
+		&rx_mix1_inp1_mux),
+	SND_SOC_DAPM_MUX("RX1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
+		&rx_mix1_inp2_mux),
+	SND_SOC_DAPM_MUX("RX1 MIX1 INP3", SND_SOC_NOPM, 0, 0,
+		&rx_mix1_inp3_mux),
+	SND_SOC_DAPM_MUX("RX2 MIX1 INP1", SND_SOC_NOPM, 0, 0,
+		&rx2_mix1_inp1_mux),
+	SND_SOC_DAPM_MUX("RX2 MIX1 INP2", SND_SOC_NOPM, 0, 0,
+		&rx2_mix1_inp2_mux),
+	SND_SOC_DAPM_MUX("RX3 MIX1 INP1", SND_SOC_NOPM, 0, 0,
+		&rx3_mix1_inp1_mux),
+	SND_SOC_DAPM_MUX("RX3 MIX1 INP2", SND_SOC_NOPM, 0, 0,
+		&rx3_mix1_inp2_mux),
+	SND_SOC_DAPM_MUX("RX4 MIX1 INP1", SND_SOC_NOPM, 0, 0,
+		&rx4_mix1_inp1_mux),
+	SND_SOC_DAPM_MUX("RX4 MIX1 INP2", SND_SOC_NOPM, 0, 0,
+		&rx4_mix1_inp2_mux),
+	SND_SOC_DAPM_MUX("RX1 MIX2 INP1", SND_SOC_NOPM, 0, 0,
+		&rx1_mix2_inp1_mux),
+	SND_SOC_DAPM_MUX("RX1 MIX2 INP2", SND_SOC_NOPM, 0, 0,
+		&rx1_mix2_inp2_mux),
+	SND_SOC_DAPM_MUX("RX2 MIX2 INP1", SND_SOC_NOPM, 0, 0,
+		&rx2_mix2_inp1_mux),
+	SND_SOC_DAPM_MUX("RX2 MIX2 INP2", SND_SOC_NOPM, 0, 0,
+		&rx2_mix2_inp2_mux),
+
+	SND_SOC_DAPM_MUX("RDAC5 MUX", SND_SOC_NOPM, 0, 0,
+		&rx_dac5_mux),
+
+	SND_SOC_DAPM_SUPPLY("CLASS_H_CLK", TAPAN_A_CDC_CLK_OTHR_CTL, 0, 0,
+		tapan_codec_enable_class_h_clk, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_PRE_PMD),
+
+	SND_SOC_DAPM_SUPPLY("CLASS_H_EAR", TAPAN_A_CDC_CLSH_B1_CTL, 4, 0,
+		tapan_codec_enable_class_h, SND_SOC_DAPM_POST_PMU),
+
+	SND_SOC_DAPM_SUPPLY("CLASS_H_HPH_L", TAPAN_A_CDC_CLSH_B1_CTL, 3, 0,
+		tapan_codec_enable_class_h, SND_SOC_DAPM_POST_PMU),
+
+	SND_SOC_DAPM_SUPPLY("CLASS_H_HPH_R", TAPAN_A_CDC_CLSH_B1_CTL, 2, 0,
+		tapan_codec_enable_class_h, SND_SOC_DAPM_POST_PMU),
+
+	SND_SOC_DAPM_SUPPLY("CLASS_H_LINEOUTS_PA", SND_SOC_NOPM, 0, 0,
+		tapan_codec_enable_class_h, SND_SOC_DAPM_POST_PMU),
+
+	SND_SOC_DAPM_SUPPLY("CP", TAPAN_A_NCP_EN, 0, 0,
+		tapan_codec_enable_charge_pump, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+
+	SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0,
+		tapan_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	/* TX */
+
+	SND_SOC_DAPM_SUPPLY("CDC_CONN", TAPAN_A_CDC_CLK_OTHR_CTL, 2, 0, NULL,
+		0),
+
+	SND_SOC_DAPM_SUPPLY("LDO_H", TAPAN_A_LDO_H_MODE_1, 7, 0,
+		tapan_codec_enable_ldo_h, SND_SOC_DAPM_POST_PMU),
+
+	SND_SOC_DAPM_INPUT("AMIC1"),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 External", TAPAN_A_MICB_1_CTL, 7, 0,
+		tapan_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal1", TAPAN_A_MICB_1_CTL, 7, 0,
+		tapan_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal2", TAPAN_A_MICB_1_CTL, 7, 0,
+		tapan_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_INPUT("AMIC3"),
+
+	SND_SOC_DAPM_INPUT("AMIC4"),
+
+	SND_SOC_DAPM_INPUT("AMIC5"),
+
+	SND_SOC_DAPM_MUX_E("DEC1 MUX", TAPAN_A_CDC_CLK_TX_CLK_EN_B1_CTL, 0, 0,
+		&dec1_mux, tapan_codec_enable_dec,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+		SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("DEC2 MUX", TAPAN_A_CDC_CLK_TX_CLK_EN_B1_CTL, 1, 0,
+		&dec2_mux, tapan_codec_enable_dec,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+		SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("DEC3 MUX", TAPAN_A_CDC_CLK_TX_CLK_EN_B1_CTL, 2, 0,
+		&dec3_mux, tapan_codec_enable_dec,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+		SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("DEC4 MUX", TAPAN_A_CDC_CLK_TX_CLK_EN_B1_CTL, 3, 0,
+		&dec4_mux, tapan_codec_enable_dec,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+		SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MIXER_E("ANC", SND_SOC_NOPM, 0, 0, NULL, 0,
+		tapan_codec_enable_anc, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_INPUT("AMIC2"),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 External", TAPAN_A_MICB_2_CTL, 7, 0,
+		tapan_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU |	SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal1", TAPAN_A_MICB_2_CTL, 7, 0,
+		tapan_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal2", TAPAN_A_MICB_2_CTL, 7, 0,
+		tapan_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal3", TAPAN_A_MICB_2_CTL, 7, 0,
+		tapan_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 External", TAPAN_A_MICB_3_CTL, 7, 0,
+		tapan_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal1", TAPAN_A_MICB_3_CTL, 7, 0,
+		tapan_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal2", TAPAN_A_MICB_3_CTL, 7, 0,
+		tapan_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_AIF_OUT_E("AIF1 CAP", "AIF1 Capture", 0, SND_SOC_NOPM,
+		AIF1_CAP, 0, tapan_codec_enable_slimtx,
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_AIF_OUT_E("AIF2 CAP", "AIF2 Capture", 0, SND_SOC_NOPM,
+		AIF2_CAP, 0, tapan_codec_enable_slimtx,
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_AIF_OUT_E("AIF3 CAP", "AIF3 Capture", 0, SND_SOC_NOPM,
+		AIF3_CAP, 0, tapan_codec_enable_slimtx,
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0,
+		aif_cap_mixer, ARRAY_SIZE(aif_cap_mixer)),
+
+	SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0,
+		aif_cap_mixer, ARRAY_SIZE(aif_cap_mixer)),
+
+	SND_SOC_DAPM_MIXER("AIF3_CAP Mixer", SND_SOC_NOPM, AIF3_CAP, 0,
+		aif_cap_mixer, ARRAY_SIZE(aif_cap_mixer)),
+
+	SND_SOC_DAPM_MUX("SLIM TX1 MUX", SND_SOC_NOPM, TAPAN_TX1, 0,
+		&sb_tx1_mux),
+	SND_SOC_DAPM_MUX("SLIM TX2 MUX", SND_SOC_NOPM, TAPAN_TX2, 0,
+		&sb_tx2_mux),
+	SND_SOC_DAPM_MUX("SLIM TX3 MUX", SND_SOC_NOPM, TAPAN_TX3, 0,
+		&sb_tx3_mux),
+	SND_SOC_DAPM_MUX("SLIM TX4 MUX", SND_SOC_NOPM, TAPAN_TX4, 0,
+		&sb_tx4_mux),
+
+	/* Digital Mic Inputs */
+	SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
+		tapan_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0,
+		tapan_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0,
+		tapan_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0,
+		tapan_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	/* Sidetone */
+	SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux),
+	SND_SOC_DAPM_PGA("IIR1", TAPAN_A_CDC_CLK_SD_CTL, 0, 0, NULL, 0),
+
+	/* AUX PGA */
+	SND_SOC_DAPM_ADC_E("AUX_PGA_Left", NULL, TAPAN_A_RX_AUX_SW_CTL, 7, 0,
+		tapan_codec_enable_aux_pga, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("AUX_PGA_Right", NULL, TAPAN_A_RX_AUX_SW_CTL, 6, 0,
+		tapan_codec_enable_aux_pga, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	/* Lineout, ear and HPH PA Mixers */
+
+	SND_SOC_DAPM_MIXER("EAR_PA_MIXER", SND_SOC_NOPM, 0, 0,
+		ear_pa_mix, ARRAY_SIZE(ear_pa_mix)),
+
+	SND_SOC_DAPM_MIXER("HPHL_PA_MIXER", SND_SOC_NOPM, 0, 0,
+		hphl_pa_mix, ARRAY_SIZE(hphl_pa_mix)),
+
+	SND_SOC_DAPM_MIXER("HPHR_PA_MIXER", SND_SOC_NOPM, 0, 0,
+		hphr_pa_mix, ARRAY_SIZE(hphr_pa_mix)),
+
+	SND_SOC_DAPM_MIXER("LINEOUT1_PA_MIXER", SND_SOC_NOPM, 0, 0,
+		lineout1_pa_mix, ARRAY_SIZE(lineout1_pa_mix)),
+
+	SND_SOC_DAPM_MIXER("LINEOUT2_PA_MIXER", SND_SOC_NOPM, 0, 0,
+		lineout2_pa_mix, ARRAY_SIZE(lineout2_pa_mix)),
+
+};
+
+static unsigned long slimbus_value;
+
+static irqreturn_t tapan_slimbus_irq(int irq, void *data)
+{
+	struct tapan_priv *priv = data;
+	struct snd_soc_codec *codec = priv->codec;
+	int i, j;
+	u8 val;
+
+	for (i = 0; i < WCD9XXX_SLIM_NUM_PORT_REG; i++) {
+		slimbus_value = wcd9xxx_interface_reg_read(codec->control_data,
+			TAPAN_SLIM_PGD_PORT_INT_STATUS0 + i);
+		for_each_set_bit(j, &slimbus_value, BITS_PER_BYTE) {
+			val = wcd9xxx_interface_reg_read(codec->control_data,
+				TAPAN_SLIM_PGD_PORT_INT_SOURCE0 + i*8 + j);
+			if (val & 0x1)
+				pr_err_ratelimited(
+				"overflow error on port %x, value %x\n",
+				i*8 + j, val);
+			if (val & 0x2)
+				pr_err_ratelimited(
+				"underflow error on port %x, value %x\n",
+				i*8 + j, val);
+		}
+		wcd9xxx_interface_reg_write(codec->control_data,
+			TAPAN_SLIM_PGD_PORT_INT_CLR0 + i, 0xFF);
+
+	}
+	return IRQ_HANDLED;
+}
+
+static const struct tapan_reg_mask_val tapan_1_0_class_h_ear[] = {
+
+	/* CLASS-H EAR  IDLE_THRESHOLD Table */
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_IDLE_EAR_THSD, 0x26),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_FCLKONLY_EAR_THSD, 0x2C),
+
+	/* CLASS-H EAR I_PA_FACT Table. */
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_I_PA_FACT_EAR_L,	0xA9),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_I_PA_FACT_EAR_U, 0x07),
+
+	/* CLASS-H EAR Voltage Headroom , Voltage Min. */
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_V_PA_HD_EAR, 0x0D),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_V_PA_MIN_EAR, 0x3A),
+
+	/* CLASS-H EAR K values --chnages from load. */
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_K_ADDR, 0x08),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_K_DATA, 0x1B),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_K_DATA, 0x00),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_K_DATA, 0x2D),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_K_DATA, 0x00),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_K_DATA, 0x36),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_K_DATA, 0x00),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_K_DATA, 0x37),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_K_DATA, 0x00),
+	/** end of Ear PA load 32 */
+};
+
+static const struct tapan_reg_mask_val tapan_1_0_class_h_hph[] = {
+
+	/* CLASS-H HPH  IDLE_THRESHOLD Table */
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_IDLE_HPH_THSD, 0x13),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0x19),
+
+	/* CLASS-H HPH I_PA_FACT Table */
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_I_PA_FACT_HPH_L, 0x9A),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_I_PA_FACT_HPH_U, 0x06),
+
+	/* CLASS-H HPH Voltage Headroom , Voltage Min */
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_V_PA_HD_HPH, 0x0D),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_V_PA_MIN_HPH, 0x1D),
+
+	/* CLASS-H HPH K values --chnages from load .*/
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_K_ADDR, 0x00),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_K_DATA, 0xAE),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_K_DATA, 0x01),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_K_DATA, 0x1C),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_K_DATA, 0x00),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_K_DATA, 0x25),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_K_DATA, 0x00),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_K_DATA, 0x27),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_K_DATA, 0x00),
+};
+
+static int tapan_config_ear_class_h(struct snd_soc_codec *codec, u32 ear_load)
+{
+	u32 i;
+
+	if (ear_load  != 32)
+		return -EINVAL;
+
+	for (i = 0; i < ARRAY_SIZE(tapan_1_0_class_h_ear); i++)
+		snd_soc_write(codec, tapan_1_0_class_h_ear[i].reg,
+				tapan_1_0_class_h_ear[i].val);
+	return 0;
+}
+
+static int tapan_config_hph_class_h(struct snd_soc_codec *codec, u32 hph_load)
+{
+	u32 i;
+	if (hph_load  != 16)
+		return -EINVAL;
+
+	for (i = 0; i < ARRAY_SIZE(tapan_1_0_class_h_hph); i++)
+		snd_soc_write(codec, tapan_1_0_class_h_hph[i].reg,
+				tapan_1_0_class_h_hph[i].val);
+	return 0;
+}
+
+static int tapan_handle_pdata(struct tapan_priv *tapan)
+{
+	struct snd_soc_codec *codec = tapan->codec;
+	struct wcd9xxx_pdata *pdata = tapan->resmgr.pdata;
+	int k1, k2, k3, rc = 0;
+	u8 leg_mode, txfe_bypass, txfe_buff, flag;
+	u8 value = 0;
+
+	if (!pdata) {
+		pr_err("%s: NULL pdata\n", __func__);
+		rc = -ENODEV;
+		goto done;
+	}
+
+	leg_mode = pdata->amic_settings.legacy_mode;
+	txfe_bypass = pdata->amic_settings.txfe_enable;
+	txfe_buff = pdata->amic_settings.txfe_buff;
+	flag = pdata->amic_settings.use_pdata;
+
+	/* Make sure settings are correct */
+	if ((pdata->micbias.ldoh_v > WCD9XXX_LDOH_3P0_V) ||
+	    (pdata->micbias.bias1_cfilt_sel > WCD9XXX_CFILT3_SEL) ||
+	    (pdata->micbias.bias2_cfilt_sel > WCD9XXX_CFILT3_SEL) ||
+	    (pdata->micbias.bias3_cfilt_sel > WCD9XXX_CFILT3_SEL)) {
+		rc = -EINVAL;
+		goto done;
+	}
+	/* figure out k value */
+	k1 = wcd9xxx_resmgr_get_k_val(&tapan->resmgr, pdata->micbias.cfilt1_mv);
+	k2 = wcd9xxx_resmgr_get_k_val(&tapan->resmgr, pdata->micbias.cfilt2_mv);
+	k3 = wcd9xxx_resmgr_get_k_val(&tapan->resmgr, pdata->micbias.cfilt3_mv);
+
+	if (IS_ERR_VALUE(k1) || IS_ERR_VALUE(k2) || IS_ERR_VALUE(k3)) {
+		rc = -EINVAL;
+		goto done;
+	}
+	/* Set voltage level and always use LDO */
+	snd_soc_update_bits(codec, TAPAN_A_LDO_H_MODE_1, 0x0C,
+			    (pdata->micbias.ldoh_v << 2));
+
+	snd_soc_update_bits(codec, TAPAN_A_MICB_CFILT_1_VAL, 0xFC, (k1 << 2));
+	snd_soc_update_bits(codec, TAPAN_A_MICB_CFILT_2_VAL, 0xFC, (k2 << 2));
+	snd_soc_update_bits(codec, TAPAN_A_MICB_CFILT_3_VAL, 0xFC, (k3 << 2));
+
+	snd_soc_update_bits(codec, TAPAN_A_MICB_1_CTL, 0x60,
+			    (pdata->micbias.bias1_cfilt_sel << 5));
+	snd_soc_update_bits(codec, TAPAN_A_MICB_2_CTL, 0x60,
+			    (pdata->micbias.bias2_cfilt_sel << 5));
+	snd_soc_update_bits(codec, TAPAN_A_MICB_3_CTL, 0x60,
+			    (pdata->micbias.bias3_cfilt_sel << 5));
+
+	if (flag & 0x40) {
+		value = (leg_mode & 0x40) ? 0x10 : 0x00;
+		value = value | ((txfe_bypass & 0x40) ? 0x02 : 0x00);
+		value = value | ((txfe_buff & 0x40) ? 0x01 : 0x00);
+		snd_soc_update_bits(codec, TAPAN_A_TX_7_MBHC_EN,
+			0x13, value);
+	}
+
+	if (pdata->ocp.use_pdata) {
+		/* not defined in CODEC specification */
+		if (pdata->ocp.hph_ocp_limit == 1 ||
+			pdata->ocp.hph_ocp_limit == 5) {
+			rc = -EINVAL;
+			goto done;
+		}
+		snd_soc_update_bits(codec, TAPAN_A_RX_COM_OCP_CTL,
+			0x0F, pdata->ocp.num_attempts);
+		snd_soc_write(codec, TAPAN_A_RX_COM_OCP_COUNT,
+			((pdata->ocp.run_time << 4) | pdata->ocp.wait_time));
+		snd_soc_update_bits(codec, TAPAN_A_RX_HPH_OCP_CTL,
+			0xE0, (pdata->ocp.hph_ocp_limit << 5));
+	}
+
+	tapan_config_ear_class_h(codec, 32);
+	tapan_config_hph_class_h(codec, 16);
+
+done:
+	return rc;
+}
+
+static const struct tapan_reg_mask_val tapan_reg_defaults[] = {
+
+	/* set MCLk to 9.6 */
+	TAPAN_REG_VAL(TAPAN_A_CHIP_CTL, 0x0A),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLK_POWER_CTL, 0x03),
+
+	/* EAR PA deafults  */
+	TAPAN_REG_VAL(TAPAN_A_RX_EAR_CMBUFF, 0x05),
+
+	/** BUCK and NCP defaults for EAR and HS */
+	TAPAN_REG_VAL(TAPAN_A_BUCK_CTRL_CCL_4, 0x50),
+	TAPAN_REG_VAL(TAPAN_A_BUCK_CTRL_CCL_1, 0x5B),
+
+	/* CLASS-H defaults for EAR and HS */
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_BUCK_NCP_VARS, 0x00),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_BUCK_NCP_VARS, 0x04),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_B2_CTL, 0x01),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_B2_CTL, 0x05),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_B2_CTL, 0x35),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_B3_CTL, 0x30),
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_B3_CTL, 0x3B),
+
+	/*
+	 * For CLASS-H, Enable ANC delay buffer,
+	 * set HPHL and EAR PA ref gain to 0 DB.
+	 */
+	TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_B1_CTL, 0x26),
+
+	/* RX deafults */
+	TAPAN_REG_VAL(TAPAN_A_CDC_RX1_B5_CTL, 0x78),
+	TAPAN_REG_VAL(TAPAN_A_CDC_RX2_B5_CTL, 0x78),
+	TAPAN_REG_VAL(TAPAN_A_CDC_RX3_B5_CTL, 0x78),
+	TAPAN_REG_VAL(TAPAN_A_CDC_RX4_B5_CTL, 0x78),
+
+	/* RX1 and RX2 defaults */
+	TAPAN_REG_VAL(TAPAN_A_CDC_RX1_B6_CTL, 0xA0),
+	TAPAN_REG_VAL(TAPAN_A_CDC_RX2_B6_CTL, 0xA0),
+
+	/* RX3 to RX7 defaults */
+	TAPAN_REG_VAL(TAPAN_A_CDC_RX3_B6_CTL, 0x80),
+	TAPAN_REG_VAL(TAPAN_A_CDC_RX4_B6_CTL, 0x80),
+
+	/*
+	 * The following only need to be written for Taiko 1.0 parts.
+	 * Taiko 2.0 will have appropriate defaults for these registers.
+	 */
+	/* Choose max non-overlap time for NCP */
+	TAPAN_REG_VAL(TAPAN_A_NCP_CLK, 0xFC),
+	/* Use 25mV/50mV for deltap/m to reduce ripple */
+	TAPAN_REG_VAL(TAPAN_A_BUCK_CTRL_VCL_1, 0x08),
+	/*
+	 * Set DISABLE_MODE_SEL<1:0> to 0b10 (disable PWM in auto mode).
+	 * Note that the other bits of this register will be changed during
+	 * Rx PA bring up.
+	 */
+	TAPAN_REG_VAL(TAPAN_A_BUCK_MODE_3, 0xCE),
+	/* Reduce HPH DAC bias to 70% */
+	TAPAN_REG_VAL(TAPAN_A_RX_HPH_BIAS_PA, 0x7A),
+	/*Reduce EAR DAC bias to 70% */
+	TAPAN_REG_VAL(TAPAN_A_RX_EAR_BIAS_PA, 0x76),
+	/* Reduce LINE DAC bias to 70% */
+	TAPAN_REG_VAL(TAPAN_A_RX_LINE_BIAS_PA, 0x78),
+
+	/*
+	 * There is a diode to pull down the micbias while doing
+	 * insertion detection.  This diode can cause leakage.
+	 * Set bit 0 to 1 to prevent leakage.
+	 * Setting this bit of micbias 2 prevents leakage for all other micbias.
+	 */
+	TAPAN_REG_VAL(TAPAN_A_MICB_2_MBHC, 0x41),
+
+	/* Disable TX7 internal biasing path which can cause leakage */
+	TAPAN_REG_VAL(TAPAN_A_TX_SUP_SWITCH_CTRL_1, 0xBF),
+};
+
+static void tapan_update_reg_defaults(struct snd_soc_codec *codec)
+{
+	u32 i;
+
+	for (i = 0; i < ARRAY_SIZE(tapan_reg_defaults); i++)
+		snd_soc_write(codec, tapan_reg_defaults[i].reg,
+				tapan_reg_defaults[i].val);
+}
+
+static const struct tapan_reg_mask_val tapan_codec_reg_init_val[] = {
+	/* Initialize current threshold to 350MA
+	 * number of wait and run cycles to 4096
+	 */
+	{TAPAN_A_RX_HPH_OCP_CTL, 0xE1, 0x61},
+	{TAPAN_A_RX_COM_OCP_COUNT, 0xFF, 0xFF},
+
+	/* Initialize gain registers to use register gain */
+	{TAPAN_A_RX_HPH_L_GAIN, 0x20, 0x20},
+	{TAPAN_A_RX_HPH_R_GAIN, 0x20, 0x20},
+	{TAPAN_A_RX_LINE_1_GAIN, 0x20, 0x20},
+	{TAPAN_A_RX_LINE_2_GAIN, 0x20, 0x20},
+
+	/* CLASS H config */
+	{TAPAN_A_CDC_CONN_CLSH_CTL, 0x3C, 0x14},
+
+	/* Use 16 bit sample size for TX1 to TX6 */
+	{TAPAN_A_CDC_CONN_TX_SB_B1_CTL, 0x30, 0x20},
+	{TAPAN_A_CDC_CONN_TX_SB_B2_CTL, 0x30, 0x20},
+	{TAPAN_A_CDC_CONN_TX_SB_B3_CTL, 0x30, 0x20},
+	{TAPAN_A_CDC_CONN_TX_SB_B4_CTL, 0x30, 0x20},
+	{TAPAN_A_CDC_CONN_TX_SB_B5_CTL, 0x30, 0x20},
+
+	/* Use 16 bit sample size for RX */
+	{TAPAN_A_CDC_CONN_RX_SB_B1_CTL, 0xFF, 0xAA},
+	{TAPAN_A_CDC_CONN_RX_SB_B2_CTL, 0xFF, 0x2A},
+
+	/*enable HPF filter for TX paths */
+	{TAPAN_A_CDC_TX1_MUX_CTL, 0x8, 0x0},
+	{TAPAN_A_CDC_TX2_MUX_CTL, 0x8, 0x0},
+	{TAPAN_A_CDC_TX3_MUX_CTL, 0x8, 0x0},
+	{TAPAN_A_CDC_TX4_MUX_CTL, 0x8, 0x0},
+
+	/* config Decimator for DMIC CLK_MODE_1(3.2Mhz@9.6Mhz mclk) */
+	{TAPAN_A_CDC_TX1_DMIC_CTL, 0x7, 0x1},
+	{TAPAN_A_CDC_TX2_DMIC_CTL, 0x7, 0x1},
+	{TAPAN_A_CDC_TX3_DMIC_CTL, 0x7, 0x1},
+	{TAPAN_A_CDC_TX4_DMIC_CTL, 0x7, 0x1},
+
+	/* config DMIC clk to CLK_MODE_1 (3.2Mhz@9.6Mhz mclk) */
+	{TAPAN_A_CDC_CLK_DMIC_B1_CTL, 0xEE, 0x22},
+	{TAPAN_A_CDC_CLK_DMIC_B2_CTL, 0x0E, 0x02},
+
+};
+
+static void tapan_codec_init_reg(struct snd_soc_codec *codec)
+{
+	u32 i;
+
+	for (i = 0; i < ARRAY_SIZE(tapan_codec_reg_init_val); i++)
+		snd_soc_update_bits(codec, tapan_codec_reg_init_val[i].reg,
+				tapan_codec_reg_init_val[i].mask,
+				tapan_codec_reg_init_val[i].val);
+}
+
+static int tapan_setup_irqs(struct tapan_priv *tapan)
+{
+	int i;
+	int ret = 0;
+	struct snd_soc_codec *codec = tapan->codec;
+
+	ret = wcd9xxx_request_irq(codec->control_data, WCD9XXX_IRQ_SLIMBUS,
+				  tapan_slimbus_irq, "SLIMBUS Slave", tapan);
+	if (ret) {
+		pr_err("%s: Failed to request irq %d\n", __func__,
+		       WCD9XXX_IRQ_SLIMBUS);
+		goto exit;
+	}
+
+	for (i = 0; i < WCD9XXX_SLIM_NUM_PORT_REG; i++)
+		wcd9xxx_interface_reg_write(codec->control_data,
+					    TAPAN_SLIM_PGD_PORT_INT_EN0 + i,
+					    0xFF);
+exit:
+	return ret;
+}
+
+int tapan_hs_detect(struct snd_soc_codec *codec,
+		    struct wcd9xxx_mbhc_config *mbhc_cfg)
+{
+	struct tapan_priv *tapan = snd_soc_codec_get_drvdata(codec);
+	return wcd9xxx_mbhc_start(&tapan->mbhc, mbhc_cfg);
+}
+EXPORT_SYMBOL_GPL(tapan_hs_detect);
+
+static struct wcd9xxx_reg_address tapan_reg_address = {
+};
+
+static int tapan_codec_probe(struct snd_soc_codec *codec)
+{
+	struct wcd9xxx *control;
+	struct tapan_priv *tapan;
+	struct wcd9xxx_pdata *pdata;
+	struct wcd9xxx *wcd9xxx;
+	struct snd_soc_dapm_context *dapm = &codec->dapm;
+	int ret = 0;
+	int i;
+	void *ptr = NULL;
+
+	codec->control_data = dev_get_drvdata(codec->dev->parent);
+	control = codec->control_data;
+
+	dev_info(codec->dev, "%s()\n", __func__);
+
+	tapan = kzalloc(sizeof(struct tapan_priv), GFP_KERNEL);
+	if (!tapan) {
+		dev_err(codec->dev, "Failed to allocate private data\n");
+		return -ENOMEM;
+	}
+	for (i = 0 ; i < NUM_DECIMATORS; i++) {
+		tx_hpf_work[i].tapan = tapan;
+		tx_hpf_work[i].decimator = i + 1;
+		INIT_DELAYED_WORK(&tx_hpf_work[i].dwork,
+			tx_hpf_corner_freq_callback);
+	}
+
+	snd_soc_codec_set_drvdata(codec, tapan);
+
+	/* codec resmgr module init */
+	wcd9xxx = codec->control_data;
+	pdata = dev_get_platdata(codec->dev->parent);
+	ret = wcd9xxx_resmgr_init(&tapan->resmgr, codec, wcd9xxx, pdata,
+				  &tapan_reg_address);
+	if (ret) {
+		pr_err("%s: wcd9xxx init failed %d\n", __func__, ret);
+		goto err_codec;
+	}
+
+	/* init and start mbhc */
+	ret = wcd9xxx_mbhc_init(&tapan->mbhc, &tapan->resmgr, codec);
+	if (ret) {
+		pr_err("%s: mbhc init failed %d\n", __func__, ret);
+		goto err_codec;
+	}
+
+	tapan->codec = codec;
+
+	tapan->intf_type = wcd9xxx_get_intf_type();
+	tapan->aux_pga_cnt = 0;
+	tapan->aux_l_gain = 0x1F;
+	tapan->aux_r_gain = 0x1F;
+	tapan_update_reg_defaults(codec);
+	tapan_codec_init_reg(codec);
+	ret = tapan_handle_pdata(tapan);
+	if (IS_ERR_VALUE(ret)) {
+		pr_err("%s: bad pdata\n", __func__);
+		goto err_codec;
+	}
+
+	ptr = kmalloc((sizeof(tapan_rx_chs) +
+		       sizeof(tapan_tx_chs)), GFP_KERNEL);
+	if (!ptr) {
+		pr_err("%s: no mem for slim chan ctl data\n", __func__);
+		ret = -ENOMEM;
+		goto err_nomem_slimch;
+	}
+
+	if (tapan->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
+		pr_err("%s: I2C interface not supported yet\n",
+			   __func__);
+	} else if (tapan->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
+		for (i = 0; i < NUM_CODEC_DAIS; i++) {
+			INIT_LIST_HEAD(&tapan->dai[i].wcd9xxx_ch_list);
+			init_waitqueue_head(&tapan->dai[i].dai_wait);
+		}
+	}
+
+	control->num_rx_port = TAPAN_RX_MAX;
+	control->rx_chs = ptr;
+	memcpy(control->rx_chs, tapan_rx_chs, sizeof(tapan_rx_chs));
+	control->num_tx_port = TAPAN_TX_MAX;
+	control->tx_chs = ptr + sizeof(tapan_rx_chs);
+	memcpy(control->tx_chs, tapan_tx_chs, sizeof(tapan_tx_chs));
+
+	snd_soc_dapm_sync(dapm);
+
+	(void) tapan_setup_irqs(tapan);
+
+	codec->ignore_pmdown_time = 1;
+	return ret;
+
+err_nomem_slimch:
+	kfree(ptr);
+err_codec:
+	kfree(tapan);
+	return ret;
+}
+
+static int tapan_codec_remove(struct snd_soc_codec *codec)
+{
+	struct tapan_priv *tapan = snd_soc_codec_get_drvdata(codec);
+
+	/* cleanup MBHC */
+	wcd9xxx_mbhc_deinit(&tapan->mbhc);
+	/* cleanup resmgr */
+	wcd9xxx_resmgr_deinit(&tapan->resmgr);
+
+	kfree(tapan);
+	return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_tapan = {
+	.probe	= tapan_codec_probe,
+	.remove	= tapan_codec_remove,
+
+	.read = tapan_read,
+	.write = tapan_write,
+
+	.readable_register = tapan_readable,
+	.volatile_register = tapan_volatile,
+
+	.reg_cache_size = TAPAN_CACHE_SIZE,
+	.reg_cache_default = tapan_reset_reg_defaults,
+	.reg_word_size = 1,
+
+	.controls = tapan_snd_controls,
+	.num_controls = ARRAY_SIZE(tapan_snd_controls),
+	.dapm_widgets = tapan_dapm_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(tapan_dapm_widgets),
+	.dapm_routes = audio_map,
+	.num_dapm_routes = ARRAY_SIZE(audio_map),
+};
+
+#ifdef CONFIG_PM
+static int tapan_suspend(struct device *dev)
+{
+	dev_dbg(dev, "%s: system suspend\n", __func__);
+	return 0;
+}
+
+static int tapan_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct tapan_priv *tapan = platform_get_drvdata(pdev);
+	dev_dbg(dev, "%s: system resume\n", __func__);
+	wcd9xxx_resmgr_notifier_call(&tapan->resmgr, WCD9XXX_EVENT_POST_RESUME);
+	return 0;
+}
+
+static const struct dev_pm_ops tapan_pm_ops = {
+	.suspend	= tapan_suspend,
+	.resume		= tapan_resume,
+};
+#endif
+
+static int __devinit tapan_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+	if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
+		ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tapan,
+			tapan_dai, ARRAY_SIZE(tapan_dai));
+	else if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C)
+		ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tapan,
+			tapan_i2s_dai, ARRAY_SIZE(tapan_i2s_dai));
+	return ret;
+}
+static int __devexit tapan_remove(struct platform_device *pdev)
+{
+	snd_soc_unregister_codec(&pdev->dev);
+	return 0;
+}
+static struct platform_driver tapan_codec_driver = {
+	.probe = tapan_probe,
+	.remove = tapan_remove,
+	.driver = {
+		.name = "tapan_codec",
+		.owner = THIS_MODULE,
+#ifdef CONFIG_PM
+		.pm = &tapan_pm_ops,
+#endif
+	},
+};
+
+static int __init tapan_codec_init(void)
+{
+	return platform_driver_register(&tapan_codec_driver);
+}
+
+static void __exit tapan_codec_exit(void)
+{
+	platform_driver_unregister(&tapan_codec_driver);
+}
+
+module_init(tapan_codec_init);
+module_exit(tapan_codec_exit);
+
+MODULE_DESCRIPTION("Tapan codec driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/wcd9306.h b/sound/soc/codecs/wcd9306.h
new file mode 100644
index 0000000..61d47b5
--- /dev/null
+++ b/sound/soc/codecs/wcd9306.h
@@ -0,0 +1,84 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef WCD9306_H
+#define WCD9306_H
+
+#include <sound/soc.h>
+#include <sound/jack.h>
+#include <linux/mfd/wcd9xxx/wcd9xxx-slimslave.h>
+#include "wcd9xxx-mbhc.h"
+#include "wcd9xxx-resmgr.h"
+
+#define TAPAN_NUM_REGISTERS 0x400
+#define TAPAN_MAX_REGISTER (TAPAN_NUM_REGISTERS-1)
+#define TAPAN_CACHE_SIZE TAPAN_NUM_REGISTERS
+
+#define TAPAN_REG_VAL(reg, val)		{reg, 0, val}
+
+extern const u8 tapan_reg_readable[TAPAN_CACHE_SIZE];
+extern const u8 tapan_reset_reg_defaults[TAPAN_CACHE_SIZE];
+struct tapan_codec_dai_data {
+	u32 rate;
+	u32 *ch_num;
+	u32 ch_act;
+	u32 ch_tot;
+};
+
+enum tapan_pid_current {
+	TAPAN_PID_MIC_2P5_UA,
+	TAPAN_PID_MIC_5_UA,
+	TAPAN_PID_MIC_10_UA,
+	TAPAN_PID_MIC_20_UA,
+};
+
+struct tapan_reg_mask_val {
+	u16	reg;
+	u8	mask;
+	u8	val;
+};
+
+enum tapan_mbhc_analog_pwr_cfg {
+	TAPAN_ANALOG_PWR_COLLAPSED = 0,
+	TAPAN_ANALOG_PWR_ON,
+	TAPAN_NUM_ANALOG_PWR_CONFIGS,
+};
+
+/* Number of input and output Slimbus port */
+enum {
+	TAPAN_RX1 = 0,
+	TAPAN_RX2,
+	TAPAN_RX3,
+	TAPAN_RX4,
+	TAPAN_RX5,
+	TAPAN_RX_MAX,
+};
+
+enum {
+	TAPAN_TX1 = 0,
+	TAPAN_TX2,
+	TAPAN_TX3,
+	TAPAN_TX4,
+	TAPAN_TX5,
+	TAPAN_TX_MAX,
+};
+
+struct anc_header {
+	u32 reserved[3];
+	u32 num_anc_slots;
+};
+
+extern int tapan_mclk_enable(struct snd_soc_codec *codec, int mclk_enable,
+			     bool dapm);
+extern int tapan_hs_detect(struct snd_soc_codec *codec,
+			   struct wcd9xxx_mbhc_config *mbhc_cfg);
+
+#endif
diff --git a/sound/soc/codecs/wcd9310-tables.c b/sound/soc/codecs/wcd9310-tables.c
index 2cba59d..b7cea9b 100644
--- a/sound/soc/codecs/wcd9310-tables.c
+++ b/sound/soc/codecs/wcd9310-tables.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index e672cdb..b8a4a86 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -54,6 +54,7 @@
 #define TABLA_CFILT_SLOW_MODE 0x40
 #define MBHC_FW_READ_ATTEMPTS 15
 #define MBHC_FW_READ_TIMEOUT 2000000
+#define MBHC_VDDIO_SWITCH_WAIT_MS 10
 
 #define SLIM_CLOSE_TIMEOUT 1000
 
@@ -99,7 +100,8 @@
 	RX_MIX1_INP_SEL_RX7,
 };
 
-#define TABLA_COMP_DIGITAL_GAIN_OFFSET 3
+#define TABLA_COMP_DIGITAL_GAIN_HP_OFFSET 3
+#define TABLA_COMP_DIGITAL_GAIN_LINEOUT_OFFSET 6
 
 #define TABLA_MCLK_RATE_12288KHZ 12288000
 #define TABLA_MCLK_RATE_9600KHZ 9600000
@@ -127,7 +129,9 @@
 
 #define TABLA_MBHC_GND_MIC_SWAP_THRESHOLD 2
 
-#define TABLA_ACQUIRE_LOCK(x) do { mutex_lock(&x); } while (0)
+#define TABLA_ACQUIRE_LOCK(x) do { \
+	mutex_lock_nested(&x, SINGLE_DEPTH_NESTING); \
+} while (0)
 #define TABLA_RELEASE_LOCK(x) do { mutex_unlock(&x); } while (0)
 
 static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
@@ -188,6 +192,16 @@
 	COMPANDER_FS_MAX,
 };
 
+enum {
+	COMP_SHUTDWN_TIMEOUT_PCM_1 = 0,
+	COMP_SHUTDWN_TIMEOUT_PCM_240,
+	COMP_SHUTDWN_TIMEOUT_PCM_480,
+	COMP_SHUTDWN_TIMEOUT_PCM_960,
+	COMP_SHUTDWN_TIMEOUT_PCM_1440,
+	COMP_SHUTDWN_TIMEOUT_PCM_2880,
+	COMP_SHUTDWN_TIMEOUT_PCM_5760,
+};
+
 /* Flags to track of PA and DAC state.
  * PA and DAC should be tracked separately as AUXPGA loopback requires
  * only PA to be turned on without DAC being on. */
@@ -203,6 +217,7 @@
 	u32 peak_det_timeout;
 	u32 rms_meter_div_fact;
 	u32 rms_meter_resamp_fact;
+	u32 shutdown_timeout;
 };
 
 /* Data used by MBHC */
@@ -322,10 +337,12 @@
 	enum tabla_mbhc_state mbhc_state;
 	struct tabla_mbhc_config mbhc_cfg;
 	struct mbhc_internal_cal_data mbhc_data;
+	u32 ldo_h_count;
+	u32 micbias_enable_count[TABLA_NUM_MICBIAS];
 
 	struct wcd9xxx_pdata *pdata;
 	u32 anc_slot;
-
+	bool anc_func;
 	bool no_mic_headset_override;
 	/* Delayed work to report long button press */
 	struct delayed_work mbhc_btn_dwork;
@@ -399,7 +416,7 @@
 
 static const u32 comp_shift[] = {
 	0,
-	2,
+	1,
 };
 
 static const int comp_rx_path[] = {
@@ -412,28 +429,43 @@
 	COMPANDER_MAX,
 };
 
-static const struct comp_sample_dependent_params comp_samp_params[] = {
+static const struct comp_sample_dependent_params
+		    comp_samp_params[COMPANDER_FS_MAX] = {
 	{
-		.peak_det_timeout = 0x2,
-		.rms_meter_div_fact = 0x8 << 4,
-		.rms_meter_resamp_fact = 0x21,
-	},
-	{
-		.peak_det_timeout = 0x3,
+		.peak_det_timeout = 0x6,
 		.rms_meter_div_fact = 0x9 << 4,
-		.rms_meter_resamp_fact = 0x28,
+		.rms_meter_resamp_fact = 0x06,
+		.shutdown_timeout = COMP_SHUTDWN_TIMEOUT_PCM_240 << 3,
 	},
-
 	{
-		.peak_det_timeout = 0x5,
+		.peak_det_timeout = 0x7,
+		.rms_meter_div_fact = 0xA << 4,
+		.rms_meter_resamp_fact = 0x0C,
+		.shutdown_timeout = COMP_SHUTDWN_TIMEOUT_PCM_480 << 3,
+	},
+	{
+		.peak_det_timeout = 0x8,
+		.rms_meter_div_fact = 0xB << 4,
+		.rms_meter_resamp_fact = 0x30,
+		.shutdown_timeout = COMP_SHUTDWN_TIMEOUT_PCM_960 << 3,
+	},
+	{
+		.peak_det_timeout = 0x9,
 		.rms_meter_div_fact = 0xB << 4,
 		.rms_meter_resamp_fact = 0x28,
+		.shutdown_timeout = COMP_SHUTDWN_TIMEOUT_PCM_1440 << 3,
 	},
-
 	{
-		.peak_det_timeout = 0x5,
-		.rms_meter_div_fact = 0xB << 4,
-		.rms_meter_resamp_fact = 0x28,
+		.peak_det_timeout = 0xA,
+		.rms_meter_div_fact = 0xC << 4,
+		.rms_meter_resamp_fact = 0x50,
+		.shutdown_timeout = COMP_SHUTDWN_TIMEOUT_PCM_2880 << 3,
+	},
+	{
+		.peak_det_timeout = 0xB,
+		.rms_meter_div_fact = 0xC << 4,
+		.rms_meter_resamp_fact = 0x50,
+		.shutdown_timeout = COMP_SHUTDWN_TIMEOUT_PCM_5760 << 3,
 	},
 };
 
@@ -484,6 +516,8 @@
 		snd_soc_update_bits(codec, TABLA_A_CDC_CLSG_CTL, 0x08, 0x00);
 		snd_soc_update_bits(codec, TABLA_A_CDC_CLK_OTHR_CTL, 0x01,
 			0x00);
+		snd_soc_update_bits(codec, TABLA_A_CDC_CLK_OTHR_RESET_CTL, 0x10,
+			0x00);
 		snd_soc_update_bits(codec, TABLA_A_CP_STATIC, 0x08, 0x00);
 		break;
 	}
@@ -508,6 +542,48 @@
 	return 0;
 }
 
+static int tabla_get_anc_func(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+	ucontrol->value.integer.value[0] = (tabla->anc_func == true ? 1 : 0);
+	return 0;
+}
+
+static int tabla_put_anc_func(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = &codec->dapm;
+
+	mutex_lock(&dapm->codec->mutex);
+
+	tabla->anc_func = (!ucontrol->value.integer.value[0] ? false : true);
+
+	dev_dbg(codec->dev, "%s: anc_func %x", __func__, tabla->anc_func);
+
+	if (tabla->anc_func == true) {
+		snd_soc_dapm_enable_pin(dapm, "ANC HPHR");
+		snd_soc_dapm_enable_pin(dapm, "ANC HPHL");
+		snd_soc_dapm_enable_pin(dapm, "ANC HEADPHONE");
+		snd_soc_dapm_disable_pin(dapm, "HPHR");
+		snd_soc_dapm_disable_pin(dapm, "HPHL");
+		snd_soc_dapm_disable_pin(dapm, "HEADPHONE");
+	} else {
+		snd_soc_dapm_disable_pin(dapm, "ANC HPHR");
+		snd_soc_dapm_disable_pin(dapm, "ANC HPHL");
+		snd_soc_dapm_disable_pin(dapm, "ANC HEADPHONE");
+		snd_soc_dapm_enable_pin(dapm, "HPHR");
+		snd_soc_dapm_enable_pin(dapm, "HPHL");
+		snd_soc_dapm_enable_pin(dapm, "HEADPHONE");
+	}
+	snd_soc_dapm_sync(dapm);
+	mutex_unlock(&dapm->codec->mutex);
+	return 0;
+}
+
 static int tabla_pa_gain_get(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
@@ -726,7 +802,7 @@
 
 static int tabla_compander_gain_offset(
 	struct snd_soc_codec *codec, u32 enable,
-	unsigned int reg, int mask,	int event)
+	unsigned int reg, int mask, int event, u32 comp)
 {
 	int pa_mode = snd_soc_read(codec, reg) & mask;
 	int gain_offset = 0;
@@ -736,10 +812,21 @@
 	 *  if PMD && pa_mode is comp -> offset is -3: PMU compander is on.
 	 */
 
-	if (SND_SOC_DAPM_EVENT_ON(event) && (enable != 0))
-		gain_offset = TABLA_COMP_DIGITAL_GAIN_OFFSET;
-	if (SND_SOC_DAPM_EVENT_OFF(event) && (pa_mode == 0))
-		gain_offset = -TABLA_COMP_DIGITAL_GAIN_OFFSET;
+	if (SND_SOC_DAPM_EVENT_ON(event) && (enable != 0)) {
+		if (comp == COMPANDER_1)
+			gain_offset = TABLA_COMP_DIGITAL_GAIN_HP_OFFSET;
+		if (comp == COMPANDER_2)
+			gain_offset = TABLA_COMP_DIGITAL_GAIN_LINEOUT_OFFSET;
+	}
+	if (SND_SOC_DAPM_EVENT_OFF(event) && (pa_mode == 0)) {
+		if (comp == COMPANDER_1)
+			gain_offset = -TABLA_COMP_DIGITAL_GAIN_HP_OFFSET;
+		if (comp == COMPANDER_2)
+			gain_offset = -TABLA_COMP_DIGITAL_GAIN_LINEOUT_OFFSET;
+
+	}
+	pr_debug("%s: compander #%d gain_offset %d\n",
+		 __func__, comp + 1, gain_offset);
 	return gain_offset;
 }
 
@@ -762,38 +849,38 @@
 
 	if (compander == COMPANDER_1) {
 		gain_offset = tabla_compander_gain_offset(codec, enable,
-				TABLA_A_RX_HPH_L_GAIN, mask, event);
+				TABLA_A_RX_HPH_L_GAIN, mask, event, compander);
 		snd_soc_update_bits(codec, TABLA_A_RX_HPH_L_GAIN, mask, value);
 		gain = snd_soc_read(codec, TABLA_A_CDC_RX1_VOL_CTL_B2_CTL);
 		snd_soc_update_bits(codec, TABLA_A_CDC_RX1_VOL_CTL_B2_CTL,
 				0xFF, gain - gain_offset);
 		gain_offset = tabla_compander_gain_offset(codec, enable,
-				TABLA_A_RX_HPH_R_GAIN, mask, event);
+				TABLA_A_RX_HPH_R_GAIN, mask, event, compander);
 		snd_soc_update_bits(codec, TABLA_A_RX_HPH_R_GAIN, mask, value);
 		gain = snd_soc_read(codec, TABLA_A_CDC_RX2_VOL_CTL_B2_CTL);
 		snd_soc_update_bits(codec, TABLA_A_CDC_RX2_VOL_CTL_B2_CTL,
 				0xFF, gain - gain_offset);
 	} else if (compander == COMPANDER_2) {
 		gain_offset = tabla_compander_gain_offset(codec, enable,
-				TABLA_A_RX_LINE_1_GAIN, mask, event);
+				TABLA_A_RX_LINE_1_GAIN, mask, event, compander);
 		snd_soc_update_bits(codec, TABLA_A_RX_LINE_1_GAIN, mask, value);
 		gain = snd_soc_read(codec, TABLA_A_CDC_RX3_VOL_CTL_B2_CTL);
 		snd_soc_update_bits(codec, TABLA_A_CDC_RX3_VOL_CTL_B2_CTL,
 				0xFF, gain - gain_offset);
 		gain_offset = tabla_compander_gain_offset(codec, enable,
-				TABLA_A_RX_LINE_3_GAIN, mask, event);
+				TABLA_A_RX_LINE_3_GAIN, mask, event, compander);
 		snd_soc_update_bits(codec, TABLA_A_RX_LINE_3_GAIN, mask, value);
 		gain = snd_soc_read(codec, TABLA_A_CDC_RX4_VOL_CTL_B2_CTL);
 		snd_soc_update_bits(codec, TABLA_A_CDC_RX4_VOL_CTL_B2_CTL,
 				0xFF, gain - gain_offset);
 		gain_offset = tabla_compander_gain_offset(codec, enable,
-				TABLA_A_RX_LINE_2_GAIN, mask, event);
+				TABLA_A_RX_LINE_2_GAIN, mask, event, compander);
 		snd_soc_update_bits(codec, TABLA_A_RX_LINE_2_GAIN, mask, value);
 		gain = snd_soc_read(codec, TABLA_A_CDC_RX5_VOL_CTL_B2_CTL);
 		snd_soc_update_bits(codec, TABLA_A_CDC_RX5_VOL_CTL_B2_CTL,
 				0xFF, gain - gain_offset);
 		gain_offset = tabla_compander_gain_offset(codec, enable,
-				TABLA_A_RX_LINE_4_GAIN, mask, event);
+				TABLA_A_RX_LINE_4_GAIN, mask, event, compander);
 		snd_soc_update_bits(codec, TABLA_A_RX_LINE_4_GAIN, mask, value);
 		gain = snd_soc_read(codec, TABLA_A_CDC_RX6_VOL_CTL_B2_CTL);
 		snd_soc_update_bits(codec, TABLA_A_CDC_RX6_VOL_CTL_B2_CTL,
@@ -823,10 +910,11 @@
 	int comp = ((struct soc_multi_mixer_control *)
 					kcontrol->private_value)->max;
 	int value = ucontrol->value.integer.value[0];
-
+	pr_debug("%s: compander #%d enable %d\n",
+		 __func__, comp + 1, value);
 	if (value == tabla->comp_enabled[comp]) {
 		pr_debug("%s: compander #%d enable %d no change\n",
-			    __func__, comp, value);
+			 __func__, comp + 1, value);
 		return 0;
 	}
 	tabla->comp_enabled[comp] = value;
@@ -841,41 +929,51 @@
 	struct snd_soc_codec *codec = w->codec;
 	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
 	u32 rate = tabla->comp_fs[w->shift];
-
+	u32 status;
+	unsigned long timeout;
+	pr_debug("%s: compander #%d enable %d event %d\n",
+		 __func__, w->shift + 1,
+		 tabla->comp_enabled[w->shift], event);
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
 		if (tabla->comp_enabled[w->shift] != 0) {
 			/* Enable both L/R compander clocks */
 			snd_soc_update_bits(codec,
 					TABLA_A_CDC_CLK_RX_B2_CTL,
-					0x03 << comp_shift[w->shift],
-					0x03 << comp_shift[w->shift]);
-			/* Clar the HALT for the compander*/
+					1 << comp_shift[w->shift],
+					1 << comp_shift[w->shift]);
+			/* Clear the HALT for the compander*/
 			snd_soc_update_bits(codec,
 					TABLA_A_CDC_COMP1_B1_CTL +
 					w->shift * 8, 1 << 2, 0);
 			/* Toggle compander reset bits*/
 			snd_soc_update_bits(codec,
 					TABLA_A_CDC_CLK_OTHR_RESET_CTL,
-					0x03 << comp_shift[w->shift],
-					0x03 << comp_shift[w->shift]);
+					1 << comp_shift[w->shift],
+					1 << comp_shift[w->shift]);
 			snd_soc_update_bits(codec,
 					TABLA_A_CDC_CLK_OTHR_RESET_CTL,
-					0x03 << comp_shift[w->shift], 0);
+					1 << comp_shift[w->shift], 0);
 			tabla_config_gain_compander(codec, w->shift, 1, event);
+			/* Compander enable -> 0x370/0x378*/
+			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
+					    w->shift * 8, 0x03, 0x03);
 			/* Update the RMS meter resampling*/
 			snd_soc_update_bits(codec,
 					TABLA_A_CDC_COMP1_B3_CTL +
 					w->shift * 8, 0xFF, 0x01);
+			snd_soc_update_bits(codec,
+					    TABLA_A_CDC_COMP1_B2_CTL +
+					    w->shift * 8, 0xF0, 0x50);
 			/* Wait for 1ms*/
-			usleep_range(1000, 1000);
+			usleep_range(5000, 5000);
 		}
 		break;
 	case SND_SOC_DAPM_POST_PMU:
 		/* Set sample rate dependent paramater*/
 		if (tabla->comp_enabled[w->shift] != 0) {
 			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_FS_CFG +
-			w->shift * 8, 0x03,	rate);
+			w->shift * 8, 0x07,	rate);
 			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B2_CTL +
 			w->shift * 8, 0x0F,
 			comp_samp_params[rate].peak_det_timeout);
@@ -885,31 +983,59 @@
 			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B3_CTL +
 			w->shift * 8, 0xFF,
 			comp_samp_params[rate].rms_meter_resamp_fact);
-			/* Compander enable -> 0x370/0x378*/
 			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
-			w->shift * 8, 0x03, 0x03);
+			w->shift * 8, 0x38,
+			comp_samp_params[rate].shutdown_timeout);
 		}
 		break;
 	case SND_SOC_DAPM_PRE_PMD:
-		/* Halt the compander*/
-		snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
-			w->shift * 8, 1 << 2, 1 << 2);
+		if (tabla->comp_enabled[w->shift] != 0) {
+			status = snd_soc_read(codec,
+					TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS +
+					w->shift * 8);
+			pr_debug("%s: compander #%d shutdown status %d in event %d\n",
+				 __func__, w->shift + 1, status, event);
+			/* Halt the compander*/
+			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
+					    w->shift * 8, 1 << 2, 1 << 2);
+		}
 		break;
 	case SND_SOC_DAPM_POST_PMD:
-		/* Restore the gain */
-		tabla_config_gain_compander(codec, w->shift,
-				tabla->comp_enabled[w->shift], event);
-		/* Disable the compander*/
-		snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
-			w->shift * 8, 0x03, 0x00);
-		/* Turn off the clock for compander in pair*/
-		snd_soc_update_bits(codec, TABLA_A_CDC_CLK_RX_B2_CTL,
-			0x03 << comp_shift[w->shift], 0);
+		if (tabla->comp_enabled[w->shift] != 0) {
+			/* Wait up to a second for shutdown complete */
+			timeout = jiffies + HZ;
+			do {
+				status = snd_soc_read(codec,
+					TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS +
+					w->shift * 8);
+				if (status == 0x3)
+					break;
+				usleep_range(5000, 5000);
+			} while (!(time_after(jiffies, timeout)));
+			/* Restore the gain */
+			tabla_config_gain_compander(codec, w->shift,
+						tabla->comp_enabled[w->shift],
+						event);
+			/* Disable the compander*/
+			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
+					    w->shift * 8, 0x03, 0x00);
+			/* Turn off the clock for compander in pair*/
+			snd_soc_update_bits(codec, TABLA_A_CDC_CLK_RX_B2_CTL,
+					    0x03 << comp_shift[w->shift], 0);
+			/* Clear the HALT for the compander*/
+			snd_soc_update_bits(codec,
+					    TABLA_A_CDC_COMP1_B1_CTL +
+					    w->shift * 8, 1 << 2, 0);
+		}
 		break;
 	}
 	return 0;
 }
 
+static const char *const tabla_anc_func_text[] = {"OFF", "ON"};
+static const struct soc_enum tabla_anc_func_enum =
+	SOC_ENUM_SINGLE_EXT(2, tabla_anc_func_text);
+
 static const char *tabla_ear_pa_gain_text[] = {"POS_6_DB", "POS_2_DB"};
 static const struct soc_enum tabla_ear_pa_gain_enum[] = {
 		SOC_ENUM_SINGLE_EXT(2, tabla_ear_pa_gain_text),
@@ -1053,6 +1179,8 @@
 
 	SOC_SINGLE_EXT("ANC Slot", SND_SOC_NOPM, 0, 0, 100, tabla_get_anc_slot,
 		tabla_put_anc_slot),
+	SOC_ENUM_EXT("ANC Function", tabla_anc_func_enum, tabla_get_anc_func,
+		tabla_put_anc_func),
 	SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
 	SOC_ENUM("TX2 HPF cut off", cf_dec2_enum),
 	SOC_ENUM("TX3 HPF cut off", cf_dec3_enum),
@@ -1244,7 +1372,7 @@
 	"ZERO", "EAR_HPH_L", "EAR_LINE_1",
 };
 
-static const char *iir1_inp1_text[] = {
+static const char *const iir_inp1_text[] = {
 	"ZERO", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6", "DEC7", "DEC8",
 	"DEC9", "DEC10", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7"
 };
@@ -1392,7 +1520,10 @@
 	SOC_ENUM_SINGLE(TABLA_A_CDC_CONN_ANC_B2_CTL, 0, 3, anc1_fb_mux_text);
 
 static const struct soc_enum iir1_inp1_mux_enum =
-	SOC_ENUM_SINGLE(TABLA_A_CDC_CONN_EQ1_B1_CTL, 0, 18, iir1_inp1_text);
+	SOC_ENUM_SINGLE(TABLA_A_CDC_CONN_EQ1_B1_CTL, 0, 18, iir_inp1_text);
+
+static const struct soc_enum iir2_inp1_mux_enum =
+	SOC_ENUM_SINGLE(TABLA_A_CDC_CONN_EQ2_B1_CTL, 0, 18, iir_inp1_text);
 
 static const struct snd_kcontrol_new rx_mix1_inp1_mux =
 	SOC_DAPM_ENUM("RX1 MIX1 INP1 Mux", rx_mix1_inp1_chain_enum);
@@ -1617,6 +1748,9 @@
 static const struct snd_kcontrol_new iir1_inp1_mux =
 	SOC_DAPM_ENUM("IIR1 INP1 Mux", iir1_inp1_mux_enum);
 
+static const struct snd_kcontrol_new iir2_inp1_mux =
+	SOC_DAPM_ENUM("IIR2 INP1 Mux", iir2_inp1_mux_enum);
+
 static const struct snd_kcontrol_new anc1_mux =
 	SOC_DAPM_ENUM("ANC1 MUX Mux", anc1_mux_enum);
 
@@ -2399,111 +2533,6 @@
 	return 0;
 }
 
-static int tabla_codec_enable_anc(struct snd_soc_dapm_widget *w,
-	struct snd_kcontrol *kcontrol, int event)
-{
-	struct snd_soc_codec *codec = w->codec;
-	const char *filename;
-	const struct firmware *fw;
-	int i;
-	int ret;
-	int num_anc_slots;
-	struct anc_header *anc_head;
-	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
-	u32 anc_writes_size = 0;
-	int anc_size_remaining;
-	u32 *anc_ptr;
-	u16 reg;
-	u8 mask, val, old_val;
-
-	pr_debug("%s %d\n", __func__, event);
-	switch (event) {
-	case SND_SOC_DAPM_PRE_PMU:
-
-		filename = "wcd9310/wcd9310_anc.bin";
-
-		ret = request_firmware(&fw, filename, codec->dev);
-		if (ret != 0) {
-			dev_err(codec->dev, "Failed to acquire ANC data: %d\n",
-				ret);
-			return -ENODEV;
-		}
-
-		if (fw->size < sizeof(struct anc_header)) {
-			dev_err(codec->dev, "Not enough data\n");
-			release_firmware(fw);
-			return -ENOMEM;
-		}
-
-		/* First number is the number of register writes */
-		anc_head = (struct anc_header *)(fw->data);
-		anc_ptr = (u32 *)((u32)fw->data + sizeof(struct anc_header));
-		anc_size_remaining = fw->size - sizeof(struct anc_header);
-		num_anc_slots = anc_head->num_anc_slots;
-
-		if (tabla->anc_slot >= num_anc_slots) {
-			dev_err(codec->dev, "Invalid ANC slot selected\n");
-			release_firmware(fw);
-			return -EINVAL;
-		}
-
-		for (i = 0; i < num_anc_slots; i++) {
-
-			if (anc_size_remaining < TABLA_PACKED_REG_SIZE) {
-				dev_err(codec->dev, "Invalid register format\n");
-				release_firmware(fw);
-				return -EINVAL;
-			}
-			anc_writes_size = (u32)(*anc_ptr);
-			anc_size_remaining -= sizeof(u32);
-			anc_ptr += 1;
-
-			if (anc_writes_size * TABLA_PACKED_REG_SIZE
-				> anc_size_remaining) {
-				dev_err(codec->dev, "Invalid register format\n");
-				release_firmware(fw);
-				return -ENOMEM;
-			}
-
-			if (tabla->anc_slot == i)
-				break;
-
-			anc_size_remaining -= (anc_writes_size *
-				TABLA_PACKED_REG_SIZE);
-			anc_ptr += anc_writes_size;
-		}
-		if (i == num_anc_slots) {
-			dev_err(codec->dev, "Selected ANC slot not present\n");
-			release_firmware(fw);
-			return -ENOMEM;
-		}
-
-		for (i = 0; i < anc_writes_size; i++) {
-			TABLA_CODEC_UNPACK_ENTRY(anc_ptr[i], reg,
-				mask, val);
-			old_val = snd_soc_read(codec, reg);
-			snd_soc_write(codec, reg, (old_val & ~mask) |
-				(val & mask));
-		}
-		release_firmware(fw);
-
-		TABLA_ACQUIRE_LOCK(tabla->codec_resource_lock);
-		/* if MBHC polling is active, set TX7_MBHC_EN bit 7 */
-		if (tabla->mbhc_polling_active)
-			snd_soc_update_bits(codec, TABLA_A_TX_7_MBHC_EN, 0x80,
-					    0x80);
-		TABLA_RELEASE_LOCK(tabla->codec_resource_lock);
-		break;
-	case SND_SOC_DAPM_POST_PMD:
-		/* unset TX7_MBHC_EN bit 7 */
-		snd_soc_update_bits(codec, TABLA_A_TX_7_MBHC_EN, 0x80, 0x00);
-
-		snd_soc_write(codec, TABLA_A_CDC_CLK_ANC_RESET_CTL, 0xFF);
-		snd_soc_write(codec, TABLA_A_CDC_CLK_ANC_CLK_EN_CTL, 0);
-		break;
-	}
-	return 0;
-}
 
 /* called under codec_resource_lock acquisition */
 static void tabla_codec_start_hs_polling(struct snd_soc_codec *codec)
@@ -2558,6 +2587,9 @@
 		return;
 	}
 
+	snd_soc_update_bits(codec, tabla->mbhc_bias_regs.ctl_reg, 0x01, 0x01);
+	msleep(250);
+	snd_soc_update_bits(codec, tabla->mbhc_bias_regs.ctl_reg, 0x01, 0x00);
 	snd_soc_update_bits(codec, TABLA_A_CDC_MBHC_CLK_CTL, 0x8, 0x8);
 	pr_debug("%s: leave\n", __func__);
 }
@@ -2838,45 +2870,57 @@
 	char *internal1_text = "Internal1";
 	char *internal2_text = "Internal2";
 	char *internal3_text = "Internal3";
+	const char *micbias1_text = "MIC BIAS1 ";
+	const char *micbias2_text = "MIC BIAS2 ";
+	const char *micbias3_text = "MIC BIAS3 ";
+	const char *micbias4_text = "MIC BIAS4 ";
+	u32 *micbias_enable_count;
+	u16 wreg;
 
 	pr_debug("%s %d\n", __func__, event);
-	switch (w->reg) {
-	case TABLA_A_MICB_1_CTL:
+	if (strnstr(w->name, micbias1_text, strlen(micbias1_text))) {
+		wreg = TABLA_A_MICB_1_CTL;
 		micb_int_reg = TABLA_A_MICB_1_INT_RBIAS;
 		cfilt_sel_val = tabla->pdata->micbias.bias1_cfilt_sel;
 		micb_line = TABLA_MICBIAS1;
-		break;
-	case TABLA_A_MICB_2_CTL:
+	} else if (strnstr(w->name, micbias2_text, strlen(micbias2_text))) {
+		wreg = TABLA_A_MICB_2_CTL;
 		micb_int_reg = TABLA_A_MICB_2_INT_RBIAS;
 		cfilt_sel_val = tabla->pdata->micbias.bias2_cfilt_sel;
 		micb_line = TABLA_MICBIAS2;
-		break;
-	case TABLA_A_MICB_3_CTL:
+	} else if (strnstr(w->name, micbias3_text, strlen(micbias3_text))) {
+		wreg = TABLA_A_MICB_3_CTL;
 		micb_int_reg = TABLA_A_MICB_3_INT_RBIAS;
 		cfilt_sel_val = tabla->pdata->micbias.bias3_cfilt_sel;
 		micb_line = TABLA_MICBIAS3;
-		break;
-	case TABLA_1_A_MICB_4_CTL:
-	case TABLA_2_A_MICB_4_CTL:
+	} else if (strnstr(w->name, micbias4_text, strlen(micbias4_text))) {
+		wreg = tabla->reg_addr.micb_4_ctl;
 		micb_int_reg = tabla->reg_addr.micb_4_int_rbias;
 		cfilt_sel_val = tabla->pdata->micbias.bias4_cfilt_sel;
 		micb_line = TABLA_MICBIAS4;
-		break;
-	default:
+	} else {
 		pr_err("%s: Error, invalid micbias register\n", __func__);
 		return -EINVAL;
 	}
 
+	micbias_enable_count = &tabla->micbias_enable_count[micb_line];
+	pr_debug("%s: counter %d\n", __func__, *micbias_enable_count);
+
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
+		if (++*micbias_enable_count > 1) {
+			pr_debug("%s: do nothing, counter %d\n",
+				 __func__, *micbias_enable_count);
+			break;
+		}
 		/* Decide whether to switch the micbias for MBHC */
-		if (w->reg == tabla->mbhc_bias_regs.ctl_reg) {
+		if (wreg == tabla->mbhc_bias_regs.ctl_reg) {
 			TABLA_ACQUIRE_LOCK(tabla->codec_resource_lock);
 			tabla_codec_switch_micbias(codec, 0);
 			TABLA_RELEASE_LOCK(tabla->codec_resource_lock);
 		}
 
-		snd_soc_update_bits(codec, w->reg, 0x0E, 0x0A);
+		snd_soc_update_bits(codec, wreg, 0x0E, 0x0A);
 		tabla_codec_update_cfilt_usage(codec, cfilt_sel_val, 1);
 
 		if (strnstr(w->name, internal1_text, 30))
@@ -2886,9 +2930,15 @@
 		else if (strnstr(w->name, internal3_text, 30))
 			snd_soc_update_bits(codec, micb_int_reg, 0x3, 0x3);
 
+		snd_soc_update_bits(codec, wreg, 1 << 7, 1 << 7);
+
 		break;
 	case SND_SOC_DAPM_POST_PMU:
-
+		if (*micbias_enable_count > 1) {
+			pr_debug("%s: do nothing, counter %d\n",
+				 __func__, *micbias_enable_count);
+			break;
+		}
 		usleep_range(20000, 20000);
 
 		if (tabla->mbhc_polling_active &&
@@ -2901,7 +2951,15 @@
 		break;
 
 	case SND_SOC_DAPM_POST_PMD:
-		if ((w->reg == tabla->mbhc_bias_regs.ctl_reg) &&
+		if (--*micbias_enable_count > 0) {
+			pr_debug("%s: do nothing, counter %d\n",
+				 __func__, *micbias_enable_count);
+			break;
+		}
+
+		snd_soc_update_bits(codec, wreg, 1 << 7, 0);
+
+		if ((wreg == tabla->mbhc_bias_regs.ctl_reg) &&
 		    tabla_is_hph_pa_on(codec)) {
 			TABLA_ACQUIRE_LOCK(tabla->codec_resource_lock);
 			tabla_codec_switch_micbias(codec, 1);
@@ -2952,6 +3010,35 @@
 #define  CF_MIN_3DB_75HZ		0x1
 #define  CF_MIN_3DB_150HZ		0x2
 
+static int tabla_codec_enable_ldo_h(struct snd_soc_dapm_widget *w,
+				    struct snd_kcontrol *kcontrol, int event);
+
+static int tabla_codec_enable_micbias_power(struct snd_soc_dapm_widget *w,
+					    struct snd_kcontrol *kcontrol,
+					    int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+
+	pr_debug("%s %d\n", __func__, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		tabla->mbhc_cfg.mclk_cb_fn(codec, 1, true);
+		tabla_codec_enable_ldo_h(w, kcontrol, event);
+		tabla_codec_enable_micbias(w, kcontrol, event);
+		break;
+	case SND_SOC_DAPM_POST_PMU:
+		tabla->mbhc_cfg.mclk_cb_fn(codec, 0, true);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		tabla_codec_enable_micbias(w, kcontrol, event);
+		tabla_codec_enable_ldo_h(w, kcontrol, event);
+		break;
+	}
+	return 0;
+}
+
 static int tabla_codec_enable_dec(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
@@ -3101,12 +3188,35 @@
 	return 0;
 }
 
+static void tabla_enable_ldo_h(struct snd_soc_codec *codec, u32  enable)
+{
+	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+
+	if (enable) {
+		if (++tabla->ldo_h_count == 1)
+			snd_soc_update_bits(codec, TABLA_A_LDO_H_MODE_1,
+					 0x80, 0x80);
+	} else {
+		if (--tabla->ldo_h_count == 0)
+			snd_soc_update_bits(codec, TABLA_A_LDO_H_MODE_1,
+				0x80, 0x00);
+	}
+}
+
 static int tabla_codec_enable_ldo_h(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
+	struct snd_soc_codec *codec = w->codec;
+
+	pr_debug("%s %d\n", __func__, event);
+
 	switch (event) {
-	case SND_SOC_DAPM_POST_PMU:
+	case SND_SOC_DAPM_PRE_PMU:
+		tabla_enable_ldo_h(codec, 1);
+		usleep_range(1000, 1000);
+		break;
 	case SND_SOC_DAPM_POST_PMD:
+		tabla_enable_ldo_h(codec, 0);
 		usleep_range(1000, 1000);
 		break;
 	}
@@ -3203,6 +3313,160 @@
 			  WCD9XXX_IRQ_HPH_PA_OCPR_FAULT);
 }
 
+static int tabla_codec_enable_anc(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	const char *filename;
+	const struct firmware *fw;
+	int i;
+	int ret;
+	int num_anc_slots;
+	struct anc_header *anc_head;
+	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+	u32 anc_writes_size = 0;
+	int anc_size_remaining;
+	u32 *anc_ptr;
+	u16 reg;
+	u8 mask, val, old_val;
+	u8 mbhc_micb_ctl_val;
+
+	pr_debug("%s: DAPM Event %d ANC func is %d\n",
+		 __func__, event, tabla->anc_func);
+
+	if (tabla->anc_func == 0)
+		return 0;
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		mbhc_micb_ctl_val = snd_soc_read(codec,
+			tabla->mbhc_bias_regs.ctl_reg);
+
+		if (!(mbhc_micb_ctl_val & 0x80)) {
+			TABLA_ACQUIRE_LOCK(tabla->codec_resource_lock);
+			tabla_codec_switch_micbias(codec, 1);
+			TABLA_RELEASE_LOCK(tabla->codec_resource_lock);
+		}
+
+		filename = "wcd9310/wcd9310_anc.bin";
+
+		ret = request_firmware(&fw, filename, codec->dev);
+		if (ret != 0) {
+			dev_err(codec->dev, "Failed to acquire ANC data: %d\n",
+				ret);
+			return -ENODEV;
+		}
+
+		if (fw->size < sizeof(struct anc_header)) {
+			dev_err(codec->dev, "Not enough data\n");
+			release_firmware(fw);
+			return -ENOMEM;
+		}
+
+		/* First number is the number of register writes */
+		anc_head = (struct anc_header *)(fw->data);
+		anc_ptr = (u32 *)((u32)fw->data + sizeof(struct anc_header));
+		anc_size_remaining = fw->size - sizeof(struct anc_header);
+		num_anc_slots = anc_head->num_anc_slots;
+
+		if (tabla->anc_slot >= num_anc_slots) {
+			dev_err(codec->dev, "Invalid ANC slot selected\n");
+			release_firmware(fw);
+			return -EINVAL;
+		}
+
+		for (i = 0; i < num_anc_slots; i++) {
+
+			if (anc_size_remaining < TABLA_PACKED_REG_SIZE) {
+				dev_err(codec->dev, "Invalid register format\n");
+				release_firmware(fw);
+				return -EINVAL;
+			}
+			anc_writes_size = (u32)(*anc_ptr);
+			anc_size_remaining -= sizeof(u32);
+			anc_ptr += 1;
+
+			if (anc_writes_size * TABLA_PACKED_REG_SIZE
+				> anc_size_remaining) {
+				dev_err(codec->dev, "Invalid register format\n");
+				release_firmware(fw);
+				return -ENOMEM;
+			}
+
+			if (tabla->anc_slot == i)
+				break;
+
+			anc_size_remaining -= (anc_writes_size *
+				TABLA_PACKED_REG_SIZE);
+			anc_ptr += anc_writes_size;
+		}
+		if (i == num_anc_slots) {
+			dev_err(codec->dev, "Selected ANC slot not present\n");
+			release_firmware(fw);
+			return -ENOMEM;
+		}
+
+		for (i = 0; i < anc_writes_size; i++) {
+			TABLA_CODEC_UNPACK_ENTRY(anc_ptr[i], reg,
+				mask, val);
+			old_val = snd_soc_read(codec, reg);
+			snd_soc_write(codec, reg, (old_val & ~mask) |
+				(val & mask));
+		}
+		usleep_range(10000, 10000);
+		snd_soc_update_bits(codec, TABLA_A_RX_HPH_CNP_EN, 0x30, 0x30);
+		msleep(30);
+		release_firmware(fw);
+		TABLA_ACQUIRE_LOCK(tabla->codec_resource_lock);
+		/* if MBHC polling is active, set TX7_MBHC_EN bit 7 */
+		if (tabla->mbhc_polling_active)
+			snd_soc_update_bits(codec, TABLA_A_TX_7_MBHC_EN, 0x80,
+						0x80);
+		TABLA_RELEASE_LOCK(tabla->codec_resource_lock);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		/* schedule work is required because at the time HPH PA DAPM
+		 * event callback is called by DAPM framework, CODEC dapm mutex
+		 * would have been locked while snd_soc_jack_report also
+		 * attempts to acquire same lock.
+		*/
+		if (w->shift == 5) {
+			clear_bit(TABLA_HPHL_PA_OFF_ACK,
+				&tabla->hph_pa_dac_state);
+			clear_bit(TABLA_HPHL_DAC_OFF_ACK,
+				&tabla->hph_pa_dac_state);
+			if (tabla->hph_status & SND_JACK_OC_HPHL)
+				schedule_work(&tabla->hphlocp_work);
+		} else if (w->shift == 4) {
+			clear_bit(TABLA_HPHR_PA_OFF_ACK,
+				&tabla->hph_pa_dac_state);
+			clear_bit(TABLA_HPHR_DAC_OFF_ACK,
+				&tabla->hph_pa_dac_state);
+			if (tabla->hph_status & SND_JACK_OC_HPHR)
+				schedule_work(&tabla->hphrocp_work);
+		}
+
+		TABLA_ACQUIRE_LOCK(tabla->codec_resource_lock);
+		tabla_codec_switch_micbias(codec, 0);
+		TABLA_RELEASE_LOCK(tabla->codec_resource_lock);
+
+		break;
+	case SND_SOC_DAPM_PRE_PMD:
+		snd_soc_update_bits(codec, TABLA_A_RX_HPH_CNP_EN, 0x30, 0x00);
+		msleep(40);
+		/* unset TX7_MBHC_EN bit 7 */
+		snd_soc_update_bits(codec, TABLA_A_TX_7_MBHC_EN, 0x80, 0x00);
+		snd_soc_update_bits(codec, TABLA_A_CDC_ANC1_CTL, 0x01, 0x00);
+		snd_soc_update_bits(codec, TABLA_A_CDC_ANC2_CTL, 0x01, 0x00);
+		msleep(20);
+		snd_soc_write(codec, TABLA_A_CDC_CLK_ANC_RESET_CTL, 0x0F);
+		snd_soc_write(codec, TABLA_A_CDC_CLK_ANC_CLK_EN_CTL, 0);
+		snd_soc_write(codec, TABLA_A_CDC_CLK_ANC_RESET_CTL, 0xFF);
+		break;
+	}
+	return 0;
+}
+
 static int tabla_hph_pa_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
@@ -3361,14 +3625,14 @@
 }
 
 static const struct snd_soc_dapm_widget tabla_1_x_dapm_widgets[] = {
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS4 External", TABLA_1_A_MICB_4_CTL, 7,
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS4 External", SND_SOC_NOPM, 0,
 				0, tabla_codec_enable_micbias,
 				SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
 				SND_SOC_DAPM_POST_PMD),
 };
 
 static const struct snd_soc_dapm_widget tabla_2_higher_dapm_widgets[] = {
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS4 External", TABLA_2_A_MICB_4_CTL, 7,
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS4 External", SND_SOC_NOPM, 0,
 				0, tabla_codec_enable_micbias,
 				SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
 				SND_SOC_DAPM_POST_PMD),
@@ -3512,7 +3776,6 @@
 
 	{"ANC1 FB MUX", "EAR_HPH_L", "RX1 MIX2"},
 	{"ANC1 FB MUX", "EAR_LINE_1", "RX2 MIX2"},
-	{"ANC", NULL, "ANC1 FB MUX"},
 
 	/* Headset (RX MIX1 and RX MIX2) */
 	{"HEADPHONE", NULL, "HPHL"},
@@ -3527,19 +3790,26 @@
 	{"HPHL DAC", NULL, "CP"},
 	{"HPHR DAC", NULL, "CP"},
 
-	{"ANC", NULL, "ANC1 MUX"},
-	{"ANC", NULL, "ANC2 MUX"},
+	{"ANC HEADPHONE", NULL, "ANC HPHL"},
+	{"ANC HEADPHONE", NULL, "ANC HPHR"},
+
+	{"ANC HPHL", NULL, "HPHL_PA_MIXER"},
+	{"ANC HPHR", NULL, "HPHR_PA_MIXER"},
+
 	{"ANC1 MUX", "ADC1", "ADC1"},
 	{"ANC1 MUX", "ADC2", "ADC2"},
 	{"ANC1 MUX", "ADC3", "ADC3"},
 	{"ANC1 MUX", "ADC4", "ADC4"},
+	{"ANC1 MUX", "DMIC1", "DMIC1"},
+	{"ANC1 MUX", "DMIC2", "DMIC2"},
+	{"ANC1 MUX", "DMIC3", "DMIC3"},
+	{"ANC1 MUX", "DMIC4", "DMIC4"},
 	{"ANC2 MUX", "ADC1", "ADC1"},
 	{"ANC2 MUX", "ADC2", "ADC2"},
 	{"ANC2 MUX", "ADC3", "ADC3"},
 	{"ANC2 MUX", "ADC4", "ADC4"},
 
-	{"ANC", NULL, "CDC_CONN"},
-
+	{"ANC HPHR", NULL, "CDC_CONN"},
 	{"DAC1", "Switch", "RX1 CHAIN"},
 	{"HPHL DAC", "Switch", "RX1 CHAIN"},
 	{"HPHR DAC", NULL, "RX2 CHAIN"},
@@ -3566,8 +3836,8 @@
 
 	{"RX1 CHAIN", NULL, "RX1 MIX2"},
 	{"RX2 CHAIN", NULL, "RX2 MIX2"},
-	{"RX1 CHAIN", NULL, "ANC"},
-	{"RX2 CHAIN", NULL, "ANC"},
+	{"RX1 MIX2", NULL, "ANC1 MUX"},
+	{"RX2 MIX2", NULL, "ANC2 MUX"},
 
 	{"CP", NULL, "RX_BIAS"},
 	{"LINEOUT1 DAC", NULL, "RX_BIAS"},
@@ -3649,6 +3919,7 @@
 	{"RX1 MIX1 INP1", "RX6", "SLIM RX6"},
 	{"RX1 MIX1 INP1", "RX7", "SLIM RX7"},
 	{"RX1 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX1 MIX1 INP1", "IIR2", "IIR2"},
 	{"RX1 MIX1 INP2", "RX1", "SLIM RX1"},
 	{"RX1 MIX1 INP2", "RX2", "SLIM RX2"},
 	{"RX1 MIX1 INP2", "RX3", "SLIM RX3"},
@@ -3657,6 +3928,7 @@
 	{"RX1 MIX1 INP2", "RX6", "SLIM RX6"},
 	{"RX1 MIX1 INP2", "RX7", "SLIM RX7"},
 	{"RX1 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX1 MIX1 INP2", "IIR2", "IIR2"},
 	{"RX1 MIX1 INP3", "RX1", "SLIM RX1"},
 	{"RX1 MIX1 INP3", "RX2", "SLIM RX2"},
 	{"RX1 MIX1 INP3", "RX3", "SLIM RX3"},
@@ -3672,6 +3944,7 @@
 	{"RX2 MIX1 INP1", "RX6", "SLIM RX6"},
 	{"RX2 MIX1 INP1", "RX7", "SLIM RX7"},
 	{"RX2 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX2 MIX1 INP1", "IIR2", "IIR2"},
 	{"RX2 MIX1 INP2", "RX1", "SLIM RX1"},
 	{"RX2 MIX1 INP2", "RX2", "SLIM RX2"},
 	{"RX2 MIX1 INP2", "RX3", "SLIM RX3"},
@@ -3680,6 +3953,7 @@
 	{"RX2 MIX1 INP2", "RX6", "SLIM RX6"},
 	{"RX2 MIX1 INP2", "RX7", "SLIM RX7"},
 	{"RX2 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX2 MIX1 INP2", "IIR2", "IIR2"},
 	{"RX3 MIX1 INP1", "RX1", "SLIM RX1"},
 	{"RX3 MIX1 INP1", "RX2", "SLIM RX2"},
 	{"RX3 MIX1 INP1", "RX3", "SLIM RX3"},
@@ -3688,6 +3962,7 @@
 	{"RX3 MIX1 INP1", "RX6", "SLIM RX6"},
 	{"RX3 MIX1 INP1", "RX7", "SLIM RX7"},
 	{"RX3 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX3 MIX1 INP1", "IIR2", "IIR2"},
 	{"RX3 MIX1 INP2", "RX1", "SLIM RX1"},
 	{"RX3 MIX1 INP2", "RX2", "SLIM RX2"},
 	{"RX3 MIX1 INP2", "RX3", "SLIM RX3"},
@@ -3696,6 +3971,7 @@
 	{"RX3 MIX1 INP2", "RX6", "SLIM RX6"},
 	{"RX3 MIX1 INP2", "RX7", "SLIM RX7"},
 	{"RX3 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX3 MIX1 INP2", "IIR2", "IIR2"},
 	{"RX4 MIX1 INP1", "RX1", "SLIM RX1"},
 	{"RX4 MIX1 INP1", "RX2", "SLIM RX2"},
 	{"RX4 MIX1 INP1", "RX3", "SLIM RX3"},
@@ -3704,6 +3980,7 @@
 	{"RX4 MIX1 INP1", "RX6", "SLIM RX6"},
 	{"RX4 MIX1 INP1", "RX7", "SLIM RX7"},
 	{"RX4 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX4 MIX1 INP1", "IIR2", "IIR2"},
 	{"RX4 MIX1 INP2", "RX1", "SLIM RX1"},
 	{"RX4 MIX1 INP2", "RX2", "SLIM RX2"},
 	{"RX4 MIX1 INP2", "RX3", "SLIM RX3"},
@@ -3712,6 +3989,7 @@
 	{"RX4 MIX1 INP2", "RX6", "SLIM RX6"},
 	{"RX4 MIX1 INP2", "RX7", "SLIM RX7"},
 	{"RX4 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX4 MIX1 INP2", "IIR2", "IIR2"},
 	{"RX5 MIX1 INP1", "RX1", "SLIM RX1"},
 	{"RX5 MIX1 INP1", "RX2", "SLIM RX2"},
 	{"RX5 MIX1 INP1", "RX3", "SLIM RX3"},
@@ -3720,6 +3998,7 @@
 	{"RX5 MIX1 INP1", "RX6", "SLIM RX6"},
 	{"RX5 MIX1 INP1", "RX7", "SLIM RX7"},
 	{"RX5 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX5 MIX1 INP1", "IIR2", "IIR2"},
 	{"RX5 MIX1 INP2", "RX1", "SLIM RX1"},
 	{"RX5 MIX1 INP2", "RX2", "SLIM RX2"},
 	{"RX5 MIX1 INP2", "RX3", "SLIM RX3"},
@@ -3728,6 +4007,7 @@
 	{"RX5 MIX1 INP2", "RX6", "SLIM RX6"},
 	{"RX5 MIX1 INP2", "RX7", "SLIM RX7"},
 	{"RX5 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX5 MIX1 INP2", "IIR2", "IIR2"},
 	{"RX6 MIX1 INP1", "RX1", "SLIM RX1"},
 	{"RX6 MIX1 INP1", "RX2", "SLIM RX2"},
 	{"RX6 MIX1 INP1", "RX3", "SLIM RX3"},
@@ -3736,6 +4016,7 @@
 	{"RX6 MIX1 INP1", "RX6", "SLIM RX6"},
 	{"RX6 MIX1 INP1", "RX7", "SLIM RX7"},
 	{"RX6 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX6 MIX1 INP1", "IIR2", "IIR2"},
 	{"RX6 MIX1 INP2", "RX1", "SLIM RX1"},
 	{"RX6 MIX1 INP2", "RX2", "SLIM RX2"},
 	{"RX6 MIX1 INP2", "RX3", "SLIM RX3"},
@@ -3744,6 +4025,7 @@
 	{"RX6 MIX1 INP2", "RX6", "SLIM RX6"},
 	{"RX6 MIX1 INP2", "RX7", "SLIM RX7"},
 	{"RX6 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX6 MIX1 INP2", "IIR2", "IIR2"},
 	{"RX7 MIX1 INP1", "RX1", "SLIM RX1"},
 	{"RX7 MIX1 INP1", "RX2", "SLIM RX2"},
 	{"RX7 MIX1 INP1", "RX3", "SLIM RX3"},
@@ -3752,6 +4034,7 @@
 	{"RX7 MIX1 INP1", "RX6", "SLIM RX6"},
 	{"RX7 MIX1 INP1", "RX7", "SLIM RX7"},
 	{"RX7 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX7 MIX1 INP1", "IIR2", "IIR2"},
 	{"RX7 MIX1 INP2", "RX1", "SLIM RX1"},
 	{"RX7 MIX1 INP2", "RX2", "SLIM RX2"},
 	{"RX7 MIX1 INP2", "RX3", "SLIM RX3"},
@@ -3760,12 +4043,20 @@
 	{"RX7 MIX1 INP2", "RX6", "SLIM RX6"},
 	{"RX7 MIX1 INP2", "RX7", "SLIM RX7"},
 	{"RX7 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX7 MIX1 INP2", "IIR2", "IIR2"},
+
 	{"RX1 MIX2 INP1", "IIR1", "IIR1"},
+	{"RX1 MIX2 INP1", "IIR2", "IIR2"},
 	{"RX1 MIX2 INP2", "IIR1", "IIR1"},
+	{"RX1 MIX2 INP2", "IIR2", "IIR2"},
 	{"RX2 MIX2 INP1", "IIR1", "IIR1"},
+	{"RX2 MIX2 INP1", "IIR2", "IIR2"},
 	{"RX2 MIX2 INP2", "IIR1", "IIR1"},
+	{"RX2 MIX2 INP2", "IIR2", "IIR2"},
 	{"RX3 MIX2 INP1", "IIR1", "IIR1"},
+	{"RX3 MIX2 INP1", "IIR2", "IIR2"},
 	{"RX3 MIX2 INP2", "IIR1", "IIR1"},
+	{"RX3 MIX2 INP2", "IIR2", "IIR2"},
 
 	/* Decimator Inputs */
 	{"DEC1 MUX", "DMIC1", "DMIC1"},
@@ -3863,6 +4154,18 @@
 	{"IIR1 INP1 MUX", "DEC9", "DEC9 MUX"},
 	{"IIR1 INP1 MUX", "DEC10", "DEC10 MUX"},
 
+	{"IIR2", NULL, "IIR2 INP1 MUX"},
+	{"IIR2 INP1 MUX", "DEC1", "DEC1 MUX"},
+	{"IIR2 INP1 MUX", "DEC2", "DEC2 MUX"},
+	{"IIR2 INP1 MUX", "DEC3", "DEC3 MUX"},
+	{"IIR2 INP1 MUX", "DEC4", "DEC4 MUX"},
+	{"IIR2 INP1 MUX", "DEC5", "DEC5 MUX"},
+	{"IIR2 INP1 MUX", "DEC6", "DEC6 MUX"},
+	{"IIR2 INP1 MUX", "DEC7", "DEC7 MUX"},
+	{"IIR2 INP1 MUX", "DEC8", "DEC8 MUX"},
+	{"IIR2 INP1 MUX", "DEC9", "DEC9 MUX"},
+	{"IIR2 INP1 MUX", "DEC10", "DEC10 MUX"},
+
 	{"MIC BIAS1 Internal1", NULL, "LDO_H"},
 	{"MIC BIAS1 Internal2", NULL, "LDO_H"},
 	{"MIC BIAS1 External", NULL, "LDO_H"},
@@ -3972,6 +4275,14 @@
 		(reg <= TABLA_A_CDC_IIR2_COEF_B5_CTL))
 		return 1;
 
+	/* ANC filter registers are not cacheable */
+	if ((reg >= TABLA_A_CDC_ANC1_FILT1_B1_CTL) &&
+		(reg <= TABLA_A_CDC_ANC1_FILT2_B3_CTL))
+		return 1;
+	if ((reg >= TABLA_A_CDC_ANC2_FILT1_B1_CTL) &&
+		(reg <= TABLA_A_CDC_ANC2_FILT2_B3_CTL))
+		return 1;
+
 	/* Digital gain register is not cacheable so we have to write
 	 * the setting even it is the same
 	 */
@@ -3982,6 +4293,10 @@
 	if (reg == TABLA_A_RX_HPH_L_STATUS || reg == TABLA_A_RX_HPH_R_STATUS)
 		return 1;
 
+	if (reg == TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS ||
+	    reg == TABLA_A_CDC_COMP2_SHUT_DOWN_STATUS)
+		return 1;
+
 	return 0;
 }
 
@@ -4192,7 +4507,7 @@
 			tabla_codec_pause_hs_polling(codec);
 			tabla_codec_disable_clock_block(codec);
 			tabla_codec_enable_bandgap(codec,
-						   TABLA_BANDGAP_MBHC_MODE);
+						  TABLA_BANDGAP_MBHC_MODE);
 			tabla_enable_rx_bias(codec, 1);
 			tabla_codec_enable_clock_block(codec, 1);
 			tabla_codec_calibrate_hs_polling(codec);
@@ -5105,8 +5420,9 @@
 	SND_SOC_DAPM_SUPPLY("CDC_CONN", TABLA_A_CDC_CLK_OTHR_CTL, 2, 0, NULL,
 		0),
 
-	SND_SOC_DAPM_SUPPLY("LDO_H", TABLA_A_LDO_H_MODE_1, 7, 0,
-		tabla_codec_enable_ldo_h, SND_SOC_DAPM_POST_PMU),
+	SND_SOC_DAPM_SUPPLY("LDO_H", SND_SOC_NOPM, 0, 0,
+		tabla_codec_enable_ldo_h, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
 
 	SND_SOC_DAPM_SUPPLY("COMP1_CLK", SND_SOC_NOPM, 0, 0,
 		tabla_config_compander, SND_SOC_DAPM_PRE_PMU |
@@ -5116,13 +5432,13 @@
 		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
 
 	SND_SOC_DAPM_INPUT("AMIC1"),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 External", TABLA_A_MICB_1_CTL, 7, 0,
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 External", SND_SOC_NOPM, 0, 0,
 		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
 		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal1", TABLA_A_MICB_1_CTL, 7, 0,
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal1", SND_SOC_NOPM, 0, 0,
 		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
 		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal2", TABLA_A_MICB_1_CTL, 7, 0,
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal2", SND_SOC_NOPM, 0, 0,
 		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
 		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
 	SND_SOC_DAPM_ADC_E("ADC1", NULL, TABLA_A_TX_1_2_EN, 7, 0,
@@ -5200,32 +5516,42 @@
 	SND_SOC_DAPM_MUX("ANC1 MUX", SND_SOC_NOPM, 0, 0, &anc1_mux),
 	SND_SOC_DAPM_MUX("ANC2 MUX", SND_SOC_NOPM, 0, 0, &anc2_mux),
 
-	SND_SOC_DAPM_MIXER_E("ANC", SND_SOC_NOPM, 0, 0, NULL, 0,
-		tabla_codec_enable_anc, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_OUTPUT("ANC HEADPHONE"),
+	SND_SOC_DAPM_PGA_E("ANC HPHL", SND_SOC_NOPM, 0, 0, NULL, 0,
+		tabla_codec_enable_anc,
+		SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_PGA_E("ANC HPHR", SND_SOC_NOPM, 0, 0, NULL, 0,
+		tabla_codec_enable_anc, SND_SOC_DAPM_PRE_PMU),
+
 
 	SND_SOC_DAPM_MUX("ANC1 FB MUX", SND_SOC_NOPM, 0, 0, &anc1_fb_mux),
 
 	SND_SOC_DAPM_INPUT("AMIC2"),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 External", TABLA_A_MICB_2_CTL, 7, 0,
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 External", SND_SOC_NOPM, 0, 0,
 		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMU |	SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal1", TABLA_A_MICB_2_CTL, 7, 0,
+	SND_SOC_DAPM_POST_PMU |	SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Power External",
+	TABLA_A_MICB_2_CTL, 7, 0,
+			       tabla_codec_enable_micbias_power,
+			       SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			       SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal1", SND_SOC_NOPM, 0, 0,
 		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
 		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal2", TABLA_A_MICB_2_CTL, 7, 0,
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal2", SND_SOC_NOPM, 0, 0,
 		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
 		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal3", TABLA_A_MICB_2_CTL, 7, 0,
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal3", SND_SOC_NOPM, 0, 0,
 		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
 		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 External", TABLA_A_MICB_3_CTL, 7, 0,
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 External", SND_SOC_NOPM, 0, 0,
 		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
 		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal1", TABLA_A_MICB_3_CTL, 7, 0,
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal1", SND_SOC_NOPM, 0, 0,
 		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
 		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal2", TABLA_A_MICB_3_CTL, 7, 0,
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal2", SND_SOC_NOPM, 0, 0,
 		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
 		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
 	SND_SOC_DAPM_ADC_E("ADC2", NULL, TABLA_A_TX_1_2_EN, 3, 0,
@@ -5302,6 +5628,9 @@
 	SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux),
 	SND_SOC_DAPM_PGA("IIR1", TABLA_A_CDC_CLK_SD_CTL, 0, 0, NULL, 0),
 
+	SND_SOC_DAPM_MUX("IIR2 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir2_inp1_mux),
+	SND_SOC_DAPM_PGA("IIR2", TABLA_A_CDC_CLK_SD_CTL, 1, 0, NULL, 0),
+
 	/* AUX PGA */
 	SND_SOC_DAPM_ADC_E("AUX_PGA_Left", NULL, TABLA_A_AUX_L_EN, 7, 0,
 		tabla_codec_enable_aux_pga, SND_SOC_DAPM_PRE_PMU |
@@ -5424,7 +5753,7 @@
 {
 	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
 	short bias_value;
-	u8 cfilt_mode;
+	u8 cfilt_mode = 0;
 
 	pr_debug("%s: enter, mclk_enabled %d\n", __func__, tabla->mclk_enabled);
 	if (!tabla->mbhc_cfg.calibration) {
@@ -5440,10 +5769,13 @@
 	}
 
 	snd_soc_update_bits(codec, TABLA_A_CLK_BUFF_EN1, 0x05, 0x01);
-
-	/* Make sure CFILT is in fast mode, save current mode */
-	cfilt_mode = snd_soc_read(codec, tabla->mbhc_bias_regs.cfilt_ctl);
-	snd_soc_update_bits(codec, tabla->mbhc_bias_regs.cfilt_ctl, 0x70, 0x00);
+	if (!tabla->mbhc_cfg.micbias_always_on) {
+		/* Make sure CFILT is in fast mode, save current mode */
+		cfilt_mode = snd_soc_read(codec,
+					  tabla->mbhc_bias_regs.cfilt_ctl);
+		snd_soc_update_bits(codec, tabla->mbhc_bias_regs.cfilt_ctl,
+				    0x70, 0x00);
+	}
 
 	snd_soc_update_bits(codec, tabla->mbhc_bias_regs.ctl_reg, 0x1F, 0x16);
 
@@ -5465,8 +5797,9 @@
 
 	/* don't flip override */
 	bias_value = __tabla_codec_sta_dce(codec, 1, true, true);
-	snd_soc_update_bits(codec, tabla->mbhc_bias_regs.cfilt_ctl, 0x40,
-			    cfilt_mode);
+	if (!tabla->mbhc_cfg.micbias_always_on)
+		snd_soc_update_bits(codec, tabla->mbhc_bias_regs.cfilt_ctl,
+					0x40, cfilt_mode);
 	snd_soc_update_bits(codec, TABLA_A_MBHC_HPH, 0x13, 0x00);
 
 	return bias_value;
@@ -5512,7 +5845,7 @@
 
 	snd_soc_update_bits(codec, TABLA_A_RX_HPH_CNP_EN, 0x30, 0x00);
 	snd_soc_update_bits(codec, TABLA_A_RX_HPH_L_DAC_CTL,
-			    0xC0, 0x00);
+			0x80, 0x00);
 	snd_soc_update_bits(codec, TABLA_A_RX_HPH_R_DAC_CTL,
 			    0xC0, 0x00);
 	usleep_range(wg_time * 1000, wg_time * 1000);
@@ -5563,6 +5896,36 @@
 }
 
 /* called under codec_resource_lock acquisition */
+static void tabla_codec_enable_mbhc_micbias(struct snd_soc_codec *codec,
+					    bool enable)
+{
+	int r;
+	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+
+	if (!tabla->mbhc_cfg.micbias_always_on)
+		return;
+	if (enable) {
+		TABLA_RELEASE_LOCK(tabla->codec_resource_lock);
+		tabla_codec_update_cfilt_usage(codec,
+				tabla->mbhc_bias_regs.cfilt_sel, 1);
+		r = snd_soc_dapm_force_enable_pin(&codec->dapm,
+					    "MIC BIAS2 Power External");
+		snd_soc_dapm_sync(&codec->dapm);
+		TABLA_ACQUIRE_LOCK(tabla->codec_resource_lock);
+		pr_debug("%s: Turning on MICBIAS2 r %d\n", __func__, r);
+	} else {
+		TABLA_RELEASE_LOCK(tabla->codec_resource_lock);
+		r = snd_soc_dapm_disable_pin(&codec->dapm,
+					     "MIC BIAS2 Power External");
+		snd_soc_dapm_sync(&codec->dapm);
+		tabla_codec_update_cfilt_usage(codec,
+				tabla->mbhc_bias_regs.cfilt_sel, 0);
+		TABLA_ACQUIRE_LOCK(tabla->codec_resource_lock);
+		pr_debug("%s: Turning off MICBIAS2 r %d\n", __func__, r);
+	}
+}
+
+/* called under codec_resource_lock acquisition */
 static void tabla_codec_report_plug(struct snd_soc_codec *codec, int insertion,
 				    enum snd_jack_types jack_type)
 {
@@ -5588,6 +5951,8 @@
 				tabla->buttons_pressed &=
 							~TABLA_JACK_BUTTON_MASK;
 			}
+			if (jack_type == SND_JACK_HEADSET)
+				tabla_codec_enable_mbhc_micbias(codec, false);
 			pr_debug("%s: Reporting removal %d(%x)\n", __func__,
 				 jack_type, tabla->hph_status);
 			tabla_snd_soc_jack_report(tabla,
@@ -5625,6 +5990,7 @@
 		else if (jack_type == SND_JACK_HEADSET) {
 			tabla->mbhc_polling_active = true;
 			tabla->current_plug = PLUG_TYPE_HEADSET;
+			tabla_codec_enable_mbhc_micbias(codec, true);
 		} else if (jack_type == SND_JACK_LINEOUT)
 			tabla->current_plug = PLUG_TYPE_HIGH_HPH;
 		if (tabla->mbhc_cfg.headset_jack) {
@@ -6341,8 +6707,8 @@
 		btn = -1;
 		goto done;
 	}
-
-	vddio = (priv->mbhc_data.micb_mv != VDDIO_MICBIAS_MV &&
+	vddio = !priv->mbhc_cfg.micbias_always_on &&
+		(priv->mbhc_data.micb_mv != VDDIO_MICBIAS_MV &&
 		 priv->mbhc_micbias_switched);
 	mv_s = vddio ? tabla_scale_v_micb_vddio(priv, mv, false) : mv;
 
@@ -6695,6 +7061,13 @@
 		 * only report the mic line
 		 */
 		tabla_codec_report_plug(codec, 1, SND_JACK_HEADSET);
+		if (!tabla->mbhc_micbias_switched &&
+			tabla_is_hph_pa_on(codec)) {
+			/*If the headphone path is on, switch the micbias
+			to VDDIO to avoid noise due to button polling */
+			tabla_codec_switch_micbias(codec, 1);
+			pr_debug("%s: HPH path is still up\n", __func__);
+		}
 		msleep(100);
 		tabla_codec_start_hs_polling(codec);
 	} else if (plug_type == PLUG_TYPE_HIGH_HPH) {
@@ -6770,6 +7143,48 @@
 		usleep_range(5000, 5000);
 }
 
+
+static void tabla_codec_onoff_vddio_switch(struct snd_soc_codec *codec, bool on)
+{
+	bool override;
+	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+
+	pr_debug("%s: enter\n", __func__);
+	if (on) {
+		override = snd_soc_read(codec, TABLA_A_CDC_MBHC_B1_CTL) & 0x04;
+		if (!override)
+			tabla_turn_onoff_override(codec, true);
+
+		/* enable the vddio switch */
+		snd_soc_update_bits(codec, tabla->mbhc_bias_regs.mbhc_reg,
+				    0x91, 0x81);
+
+		/* deroute the override from MicBias2 to MicBias4 */
+		snd_soc_update_bits(codec, TABLA_A_MICB_1_MBHC,
+				    0x03, 0x03);
+
+		usleep_range(MBHC_VDDIO_SWITCH_WAIT_MS * 1000,
+				MBHC_VDDIO_SWITCH_WAIT_MS * 1000);
+
+		if (!override)
+			tabla_turn_onoff_override(codec, false);
+		tabla->mbhc_micbias_switched = true;
+		pr_debug("%s: VDDIO switch enabled\n", __func__);
+
+	} else {
+
+		snd_soc_update_bits(codec, tabla->mbhc_bias_regs.mbhc_reg,
+				    0x91, 0x00);
+
+		/* reroute the override to MicBias2 */
+		snd_soc_update_bits(codec, TABLA_A_MICB_1_MBHC,
+				    0x03, 0x01);
+
+		tabla->mbhc_micbias_switched = false;
+		pr_debug("%s: VDDIO switch disabled\n", __func__);
+	}
+}
+
 /* called under codec_resource_lock acquisition and mbhc override = 1 */
 static enum tabla_mbhc_plug_type
 tabla_codec_get_plug_type(struct snd_soc_codec *codec, bool highhph)
@@ -6779,7 +7194,9 @@
 	int scaled;
 	struct tabla_mbhc_plug_type_cfg *plug_type_ptr;
 	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
-	int num_det = MBHC_NUM_DCE_PLUG_DETECT + 1;
+	const bool vddio = !tabla->mbhc_cfg.micbias_always_on &&
+			   (tabla->mbhc_data.micb_mv != VDDIO_MICBIAS_MV);
+	int num_det = (MBHC_NUM_DCE_PLUG_DETECT + vddio);
 	enum tabla_mbhc_plug_type plug_type[num_det];
 	s16 mb_v[num_det];
 	s32 mic_mv[num_det];
@@ -6808,7 +7225,7 @@
 	 * Nth: check voltage range with VDDIO switch */
 	for (i = 0; i < num_det; i++) {
 		gndswitch = (i == (num_det - 2));
-		vddioswitch = (i == (num_det - 1)) || (i == (num_det - 2));
+		vddioswitch = (i == (num_det - 1));
 		if (i == 0) {
 			mb_v[i] = tabla_codec_setup_hs_polling(codec);
 			mic_mv[i] = tabla_codec_sta_dce_v(codec, 1 , mb_v[i]);
@@ -6818,8 +7235,8 @@
 			scaled = mic_mv[i];
 		} else {
 			if (vddioswitch)
-				__tabla_codec_switch_micbias(tabla->codec, 1,
-							     false, false);
+				tabla_codec_onoff_vddio_switch(codec, true);
+
 			if (gndswitch)
 				tabla_codec_hphr_gnd_switch(codec, true);
 			mb_v[i] = __tabla_codec_sta_dce(codec, 1, true, true);
@@ -6843,8 +7260,7 @@
 			if (gndswitch)
 				tabla_codec_hphr_gnd_switch(codec, false);
 			if (vddioswitch)
-				__tabla_codec_switch_micbias(tabla->codec, 0,
-							     false, false);
+				tabla_codec_onoff_vddio_switch(codec, false);
 		}
 		pr_debug("%s: DCE #%d, %04x, V %d, scaled V %d, GND %d, "
 			 "VDDIO %d, inval %d\n", __func__,
@@ -7117,7 +7533,6 @@
 	} else if (plug_type == PLUG_TYPE_HEADSET) {
 		pr_debug("%s: Headset detected\n", __func__);
 		tabla_codec_report_plug(codec, 1, SND_JACK_HEADSET);
-
 		/* avoid false button press detect */
 		msleep(50);
 		tabla_codec_start_hs_polling(codec);
@@ -7474,7 +7889,8 @@
 	pr_debug("%s: enter, removal interrupt\n", __func__);
 
 	TABLA_ACQUIRE_LOCK(priv->codec_resource_lock);
-	vddio = (priv->mbhc_data.micb_mv != VDDIO_MICBIAS_MV &&
+	vddio = !priv->mbhc_cfg.micbias_always_on &&
+		(priv->mbhc_data.micb_mv != VDDIO_MICBIAS_MV &&
 		 priv->mbhc_micbias_switched);
 	if (vddio)
 		__tabla_codec_switch_micbias(priv->codec, 0, false, true);
@@ -7524,6 +7940,7 @@
 {
 	bool insert;
 	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+	struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
 	bool is_removed = false;
 
 	pr_debug("%s: enter\n", __func__);
@@ -7533,6 +7950,7 @@
 	usleep_range(TABLA_GPIO_IRQ_DEBOUNCE_TIME_US,
 		     TABLA_GPIO_IRQ_DEBOUNCE_TIME_US);
 
+	wcd9xxx_nested_irq_lock(core);
 	TABLA_ACQUIRE_LOCK(tabla->codec_resource_lock);
 
 	/* cancel pending button press */
@@ -7599,11 +8017,13 @@
 					    0x08, 0x00);
 			/* Turn off override */
 			tabla_turn_onoff_override(codec, false);
+			tabla_codec_switch_micbias(codec, 0);
 		}
 	}
 
 	tabla->in_gpio_handler = false;
 	TABLA_RELEASE_LOCK(tabla->codec_resource_lock);
+	wcd9xxx_nested_irq_unlock(core);
 	pr_debug("%s: leave\n", __func__);
 }
 
@@ -7832,7 +8252,8 @@
 	tabla_get_mbhc_micbias_regs(codec, &tabla->mbhc_bias_regs);
 
 	/* Put CFILT in fast mode by default */
-	snd_soc_update_bits(codec, tabla->mbhc_bias_regs.cfilt_ctl,
+	if (!tabla->mbhc_cfg.micbias_always_on)
+		snd_soc_update_bits(codec, tabla->mbhc_bias_regs.cfilt_ctl,
 			    0x40, TABLA_CFILT_FAST_MODE);
 	INIT_DELAYED_WORK(&tabla->mbhc_firmware_dwork, mbhc_fw_read);
 	INIT_DELAYED_WORK(&tabla->mbhc_btn_dwork, btn_lpress_fn);
@@ -8438,7 +8859,6 @@
 		snd_soc_dapm_new_controls(dapm, tabla_2_higher_dapm_widgets,
 				    ARRAY_SIZE(tabla_2_higher_dapm_widgets));
 
-
 	ptr = kmalloc((sizeof(tabla_rx_chs) +
 		       sizeof(tabla_tx_chs)), GFP_KERNEL);
 	if (!ptr) {
@@ -8563,6 +8983,12 @@
 		       "tabla_gpio_irq_resend");
 	tabla->gpio_irq_resend = false;
 
+	mutex_lock(&dapm->codec->mutex);
+	snd_soc_dapm_disable_pin(dapm, "ANC HPHL");
+	snd_soc_dapm_disable_pin(dapm, "ANC HPHR");
+	snd_soc_dapm_disable_pin(dapm, "ANC HEADPHONE");
+	snd_soc_dapm_sync(dapm);
+	mutex_unlock(&dapm->codec->mutex);
 
 #ifdef CONFIG_DEBUG_FS
 	if (ret == 0) {
diff --git a/sound/soc/codecs/wcd9310.h b/sound/soc/codecs/wcd9310.h
index 98c1835..5c991e6 100644
--- a/sound/soc/codecs/wcd9310.h
+++ b/sound/soc/codecs/wcd9310.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -44,6 +44,7 @@
 	TABLA_MICBIAS2,
 	TABLA_MICBIAS3,
 	TABLA_MICBIAS4,
+	TABLA_NUM_MICBIAS,
 };
 
 enum tabla_pid_current {
@@ -179,6 +180,7 @@
 	bool detect_extn_cable;
 	/* swap_gnd_mic returns true if extern GND/MIC swap switch toggled */
 	bool (*swap_gnd_mic) (struct snd_soc_codec *);
+	bool micbias_always_on;
 };
 
 extern int tabla_hs_detect(struct snd_soc_codec *codec,
diff --git a/sound/soc/codecs/wcd9320-tables.c b/sound/soc/codecs/wcd9320-tables.c
index c49c276..0885c09 100644
--- a/sound/soc/codecs/wcd9320-tables.c
+++ b/sound/soc/codecs/wcd9320-tables.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index 76623b1..b3d4901 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -36,6 +36,20 @@
 #include <linux/gpio.h>
 #include "wcd9320.h"
 #include "wcd9xxx-resmgr.h"
+#include "wcd9xxx-common.h"
+
+static atomic_t kp_taiko_priv;
+static int spkr_drv_wrnd_param_set(const char *val,
+				   const struct kernel_param *kp);
+static int spkr_drv_wrnd = 1;
+
+static struct kernel_param_ops spkr_drv_wrnd_param_ops = {
+	.set = spkr_drv_wrnd_param_set,
+	.get = param_get_int,
+};
+module_param_cb(spkr_drv_wrnd, &spkr_drv_wrnd_param_ops, &spkr_drv_wrnd, 0644);
+MODULE_PARM_DESC(spkr_drv_wrnd,
+	       "Run software workaround to avoid leakage on the speaker drive");
 
 #define WCD9320_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
 			SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
@@ -56,6 +70,12 @@
 #define TAIKO_SLIM_IRQ_PORT_CLOSED (1 << 2)
 #define TAIKO_MCLK_CLK_12P288MHZ 12288000
 #define TAIKO_MCLK_CLK_9P6HZ 9600000
+
+#define TAIKO_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \
+			SNDRV_PCM_FORMAT_S24_LE)
+
+#define TAIKO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
+
 enum {
 	AIF1_PB = 0,
 	AIF1_CAP,
@@ -185,6 +205,8 @@
 static const u32 vport_i2s_check_table[NUM_CODEC_DAIS] = {
 	0,	/* AIF1_PB */
 	0,	/* AIF1_CAP */
+	0,	/* AIF2_PB */
+	0,	/* AIF2_CAP */
 };
 
 struct taiko_priv {
@@ -212,10 +234,16 @@
 	u8 aux_l_gain;
 	u8 aux_r_gain;
 
+	bool spkr_pa_widget_on;
+
 	/* resmgr module */
 	struct wcd9xxx_resmgr resmgr;
 	/* mbhc module */
 	struct wcd9xxx_mbhc mbhc;
+
+	/* class h specific data */
+	struct wcd9xxx_clsh_cdc_data clsh_d;
+
 };
 
 static const u32 comp_shift[] = {
@@ -298,73 +326,45 @@
 	TAIKO_A_CDC_TX10_VOL_CTL_GAIN,
 };
 
-static int taiko_codec_enable_class_h_clk(struct snd_soc_dapm_widget *w,
-		struct snd_kcontrol *kcontrol, int event)
+static int spkr_drv_wrnd_param_set(const char *val,
+				   const struct kernel_param *kp)
 {
-	struct snd_soc_codec *codec = w->codec;
+	struct snd_soc_codec *codec;
+	int ret, old;
+	struct taiko_priv *priv;
 
-	pr_debug("%s %s  %d\n", __func__, w->name, event);
-
-	switch (event) {
-	case SND_SOC_DAPM_PRE_PMU:
-		snd_soc_update_bits(codec, TAIKO_A_CDC_CLSH_B1_CTL, 0x01, 0x01);
-		break;
-	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_1, 0x80, 0x00);
-		snd_soc_update_bits(codec, TAIKO_A_CDC_CLSH_B1_CTL, 0x01, 0x00);
-		break;
+	priv = (struct taiko_priv *)atomic_read(&kp_taiko_priv);
+	if (!priv) {
+		pr_debug("%s: codec isn't yet registered\n", __func__);
+		return 0;
 	}
+
+	WCD9XXX_BCL_LOCK(&priv->resmgr);
+	old = spkr_drv_wrnd;
+	ret = param_set_int(val, kp);
+	if (ret) {
+		WCD9XXX_BCL_UNLOCK(&priv->resmgr);
+		return ret;
+	}
+
+	pr_debug("%s: spkr_drv_wrnd %d -> %d\n", __func__, old, spkr_drv_wrnd);
+	codec = priv->codec;
+	if (old == 0 && spkr_drv_wrnd == 1) {
+		wcd9xxx_resmgr_get_bandgap(&priv->resmgr,
+					   WCD9XXX_BANDGAP_AUDIO_MODE);
+		snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80, 0x80);
+	} else if (old == 1 && spkr_drv_wrnd == 0) {
+		wcd9xxx_resmgr_put_bandgap(&priv->resmgr,
+					   WCD9XXX_BANDGAP_AUDIO_MODE);
+		if (!priv->spkr_pa_widget_on)
+			snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80,
+					    0x00);
+	}
+
+	WCD9XXX_BCL_UNLOCK(&priv->resmgr);
 	return 0;
 }
 
-static int taiko_codec_enable_class_h(struct snd_soc_dapm_widget *w,
-		struct snd_kcontrol *kcontrol, int event)
-{
-	struct snd_soc_codec *codec = w->codec;
-
-	pr_debug("%s %s  %d\n", __func__, w->name, event);
-
-	switch (event) {
-	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_5, 0x02, 0x02);
-		snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_4, 0xFF, 0xFF);
-		snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_1, 0x04, 0x04);
-		snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_1, 0x04, 0x00);
-		snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_3, 0x04, 0x00);
-		snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_3, 0x08, 0x00);
-		snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_1, 0x80, 0x80);
-		usleep_range(1000, 1000);
-		break;
-	}
-	return 0;
-}
-
-static int taiko_codec_enable_charge_pump(struct snd_soc_dapm_widget *w,
-		struct snd_kcontrol *kcontrol, int event)
-{
-	struct snd_soc_codec *codec = w->codec;
-
-	pr_debug("%s %s %d\n", __func__, w->name, event);
-
-	switch (event) {
-	case SND_SOC_DAPM_PRE_PMU:
-		snd_soc_update_bits(codec, w->reg, 0x01, 0x01);
-		snd_soc_update_bits(codec, w->reg, 0x40, 0x00);
-		break;
-
-	case SND_SOC_DAPM_POST_PMU:
-		usleep_range(1000, 1000);
-		break;
-
-	case SND_SOC_DAPM_PRE_PMD:
-	    snd_soc_update_bits(codec, w->reg, 0x01, 0x00);
-		snd_soc_update_bits(codec, w->reg, 0x40, 0x40);
-		break;
-	}
-	return 0;
-}
-
-
 static int taiko_get_anc_slot(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
@@ -443,8 +443,8 @@
 					kcontrol->private_value)->shift;
 
 	ucontrol->value.integer.value[0] =
-		snd_soc_read(codec, (TAIKO_A_CDC_IIR1_CTL + 16 * iir_idx)) &
-		(1 << band_idx);
+		(snd_soc_read(codec, (TAIKO_A_CDC_IIR1_CTL + 16 * iir_idx)) &
+		(1 << band_idx)) != 0;
 
 	pr_debug("%s: IIR #%d band #%d enable %d\n", __func__,
 		iir_idx, band_idx,
@@ -468,22 +468,52 @@
 		(1 << band_idx), (value << band_idx));
 
 	pr_debug("%s: IIR #%d band #%d enable %d\n", __func__,
-		iir_idx, band_idx, value);
+		iir_idx, band_idx,
+		((snd_soc_read(codec, (TAIKO_A_CDC_IIR1_CTL + 16 * iir_idx)) &
+		(1 << band_idx)) != 0));
 	return 0;
 }
 static uint32_t get_iir_band_coeff(struct snd_soc_codec *codec,
 				int iir_idx, int band_idx,
 				int coeff_idx)
 {
+	uint32_t value = 0;
+
 	/* Address does not automatically update if reading */
 	snd_soc_write(codec,
 		(TAIKO_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
-		(band_idx * BAND_MAX + coeff_idx) & 0x1F);
+		((band_idx * BAND_MAX + coeff_idx)
+		* sizeof(uint32_t)) & 0x7F);
+
+	value |= snd_soc_read(codec,
+		(TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx));
+
+	snd_soc_write(codec,
+		(TAIKO_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
+		((band_idx * BAND_MAX + coeff_idx)
+		* sizeof(uint32_t) + 1) & 0x7F);
+
+	value |= (snd_soc_read(codec,
+		(TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx)) << 8);
+
+	snd_soc_write(codec,
+		(TAIKO_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
+		((band_idx * BAND_MAX + coeff_idx)
+		* sizeof(uint32_t) + 2) & 0x7F);
+
+	value |= (snd_soc_read(codec,
+		(TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx)) << 16);
+
+	snd_soc_write(codec,
+		(TAIKO_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
+		((band_idx * BAND_MAX + coeff_idx)
+		* sizeof(uint32_t) + 3) & 0x7F);
 
 	/* Mask bits top 2 bits since they are reserved */
-	return ((snd_soc_read(codec,
-		(TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx)) << 24)) &
-		0x3FFFFFFF;
+	value |= ((snd_soc_read(codec,
+		(TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx)) & 0x3F) << 24);
+
+	return value;
 }
 
 static int taiko_get_iir_band_audio_mixer(
@@ -527,19 +557,24 @@
 
 static void set_iir_band_coeff(struct snd_soc_codec *codec,
 				int iir_idx, int band_idx,
-				int coeff_idx, uint32_t value)
+				uint32_t value)
 {
-	/* Mask top 3 bits, 6-8 are reserved */
-	/* Update address manually each time */
 	snd_soc_write(codec,
-		(TAIKO_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
-		(band_idx * BAND_MAX + coeff_idx) & 0x1F);
+		(TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx),
+		(value & 0xFF));
+
+	snd_soc_write(codec,
+		(TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx),
+		(value >> 8) & 0xFF);
+
+	snd_soc_write(codec,
+		(TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx),
+		(value >> 16) & 0xFF);
 
 	/* Mask top 2 bits, 7-8 are reserved */
 	snd_soc_write(codec,
 		(TAIKO_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx),
 		(value >> 24) & 0x3F);
-
 }
 
 static int taiko_put_iir_band_audio_mixer(
@@ -552,15 +587,21 @@
 	int band_idx = ((struct soc_multi_mixer_control *)
 					kcontrol->private_value)->shift;
 
-	set_iir_band_coeff(codec, iir_idx, band_idx, 0,
+	/* Mask top bit it is reserved */
+	/* Updates addr automatically for each B2 write */
+	snd_soc_write(codec,
+		(TAIKO_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
+		(band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
+
+	set_iir_band_coeff(codec, iir_idx, band_idx,
 				ucontrol->value.integer.value[0]);
-	set_iir_band_coeff(codec, iir_idx, band_idx, 1,
+	set_iir_band_coeff(codec, iir_idx, band_idx,
 				ucontrol->value.integer.value[1]);
-	set_iir_band_coeff(codec, iir_idx, band_idx, 2,
+	set_iir_band_coeff(codec, iir_idx, band_idx,
 				ucontrol->value.integer.value[2]);
-	set_iir_band_coeff(codec, iir_idx, band_idx, 3,
+	set_iir_band_coeff(codec, iir_idx, band_idx,
 				ucontrol->value.integer.value[3]);
-	set_iir_band_coeff(codec, iir_idx, band_idx, 4,
+	set_iir_band_coeff(codec, iir_idx, band_idx,
 				ucontrol->value.integer.value[4]);
 
 	pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
@@ -788,25 +829,36 @@
 	SOC_ENUM_SINGLE(TAIKO_A_CDC_TX10_MUX_CTL, 4, 3, cf_text);
 
 static const struct soc_enum cf_rxmix1_enum =
-	SOC_ENUM_SINGLE(TAIKO_A_CDC_RX1_B4_CTL, 1, 3, cf_text);
+	SOC_ENUM_SINGLE(TAIKO_A_CDC_RX1_B4_CTL, 0, 3, cf_text);
 
 static const struct soc_enum cf_rxmix2_enum =
-	SOC_ENUM_SINGLE(TAIKO_A_CDC_RX2_B4_CTL, 1, 3, cf_text);
+	SOC_ENUM_SINGLE(TAIKO_A_CDC_RX2_B4_CTL, 0, 3, cf_text);
 
 static const struct soc_enum cf_rxmix3_enum =
-	SOC_ENUM_SINGLE(TAIKO_A_CDC_RX3_B4_CTL, 1, 3, cf_text);
+	SOC_ENUM_SINGLE(TAIKO_A_CDC_RX3_B4_CTL, 0, 3, cf_text);
 
 static const struct soc_enum cf_rxmix4_enum =
-	SOC_ENUM_SINGLE(TAIKO_A_CDC_RX4_B4_CTL, 1, 3, cf_text);
+	SOC_ENUM_SINGLE(TAIKO_A_CDC_RX4_B4_CTL, 0, 3, cf_text);
 
 static const struct soc_enum cf_rxmix5_enum =
-	SOC_ENUM_SINGLE(TAIKO_A_CDC_RX5_B4_CTL, 1, 3, cf_text)
+	SOC_ENUM_SINGLE(TAIKO_A_CDC_RX5_B4_CTL, 0, 3, cf_text)
 ;
 static const struct soc_enum cf_rxmix6_enum =
-	SOC_ENUM_SINGLE(TAIKO_A_CDC_RX6_B4_CTL, 1, 3, cf_text);
+	SOC_ENUM_SINGLE(TAIKO_A_CDC_RX6_B4_CTL, 0, 3, cf_text);
 
 static const struct soc_enum cf_rxmix7_enum =
-	SOC_ENUM_SINGLE(TAIKO_A_CDC_RX7_B4_CTL, 1, 3, cf_text);
+	SOC_ENUM_SINGLE(TAIKO_A_CDC_RX7_B4_CTL, 0, 3, cf_text);
+
+static const char * const class_h_dsm_text[] = {
+	"ZERO", "DSM_HPHL_RX1", "DSM_SPKR_RX7"
+};
+
+static const struct soc_enum class_h_dsm_enum =
+	SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_CLSH_CTL, 4, 3, class_h_dsm_text);
+
+static const struct snd_kcontrol_new class_h_dsm_mux =
+	SOC_DAPM_ENUM("CLASS_H_DSM MUX Mux", class_h_dsm_enum);
+
 
 static const struct snd_kcontrol_new taiko_snd_controls[] = {
 
@@ -827,6 +879,9 @@
 	SOC_SINGLE_TLV("HPHR Volume", TAIKO_A_RX_HPH_R_GAIN, 0, 12, 1,
 		line_gain),
 
+	SOC_SINGLE_TLV("SPK DRV Volume", TAIKO_A_SPKR_DRV_GAIN, 3, 7, 1,
+		line_gain),
+
 	SOC_SINGLE_S8_TLV("RX1 Digital Volume", TAIKO_A_CDC_RX1_VOL_CTL_B2_CTL,
 		-84, 40, digital_gain),
 	SOC_SINGLE_S8_TLV("RX2 Digital Volume", TAIKO_A_CDC_RX2_VOL_CTL_B2_CTL,
@@ -877,12 +932,6 @@
 	SOC_SINGLE_TLV("ADC5 Volume", TAIKO_A_TX_5_6_EN, 5, 3, 0, analog_gain),
 	SOC_SINGLE_TLV("ADC6 Volume", TAIKO_A_TX_5_6_EN, 1, 3, 0, analog_gain),
 
-
-	SOC_SINGLE("MICBIAS1 CAPLESS Switch", TAIKO_A_MICB_1_CTL, 4, 1, 1),
-	SOC_SINGLE("MICBIAS2 CAPLESS Switch", TAIKO_A_MICB_2_CTL, 4, 1, 1),
-	SOC_SINGLE("MICBIAS3 CAPLESS Switch", TAIKO_A_MICB_3_CTL, 4, 1, 1),
-	SOC_SINGLE("MICBIAS4 CAPLESS Switch", TAIKO_A_MICB_4_CTL, 4, 1, 1),
-
 	SOC_SINGLE_EXT("ANC Slot", SND_SOC_NOPM, 0, 0, 100, taiko_get_anc_slot,
 		taiko_put_anc_slot),
 	SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
@@ -1640,7 +1689,7 @@
 	mutex_lock(&codec->mutex);
 
 	if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
-		if (widget->value > 1) {
+		if (widget->value > 2) {
 			dev_err(codec->dev, "%s: invalid AIF for I2C mode\n",
 				__func__);
 			goto err;
@@ -1661,14 +1710,14 @@
 	break;
 	case 2:
 		if (wcd9xxx_rx_vport_validation(port_id + core->num_tx_port,
-			&taiko_p->dai[AIF1_PB].wcd9xxx_ch_list))
+			&taiko_p->dai[AIF2_PB].wcd9xxx_ch_list))
 			goto pr_err;
 		list_add_tail(&core->rx_chs[port_id].list,
 			      &taiko_p->dai[AIF2_PB].wcd9xxx_ch_list);
 	break;
 	case 3:
 		if (wcd9xxx_rx_vport_validation(port_id + core->num_tx_port,
-			&taiko_p->dai[AIF1_PB].wcd9xxx_ch_list))
+			&taiko_p->dai[AIF3_PB].wcd9xxx_ch_list))
 			goto pr_err;
 		list_add_tail(&core->rx_chs[port_id].list,
 			      &taiko_p->dai[AIF3_PB].wcd9xxx_ch_list);
@@ -1742,11 +1791,12 @@
 
 	if (enable) {
 		taiko->adc_count++;
-		snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_OTHR_CTL, 0x2, 0x2);
+		snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLK_OTHR_CTL,
+						0x2, 0x2);
 	} else {
 		taiko->adc_count--;
 		if (!taiko->adc_count)
-			snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_OTHR_CTL,
+			snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLK_OTHR_CTL,
 					    0x2, 0x0);
 	}
 }
@@ -1834,6 +1884,7 @@
 		struct snd_kcontrol *kcontrol, int event)
 {
 	struct snd_soc_codec *codec = w->codec;
+	struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
 	u16 lineout_gain_reg;
 
 	pr_debug("%s %d %s\n", __func__, event, w->name);
@@ -1862,11 +1913,19 @@
 		snd_soc_update_bits(codec, lineout_gain_reg, 0x40, 0x40);
 		break;
 	case SND_SOC_DAPM_POST_PMU:
-		pr_debug("%s: sleeping 16 ms after %s PA turn on\n",
+		wcd9xxx_clsh_fsm(codec, &taiko->clsh_d,
+						 WCD9XXX_CLSH_STATE_LO,
+						 WCD9XXX_CLSH_REQ_ENABLE,
+						 WCD9XXX_CLSH_EVENT_POST_PA);
+		pr_debug("%s: sleeping 3 ms after %s PA turn on\n",
 				__func__, w->name);
-		usleep_range(16000, 16000);
+		usleep_range(3000, 3000);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
+		wcd9xxx_clsh_fsm(codec, &taiko->clsh_d,
+						 WCD9XXX_CLSH_STATE_LO,
+						 WCD9XXX_CLSH_REQ_DISABLE,
+						 WCD9XXX_CLSH_EVENT_POST_PA);
 		snd_soc_update_bits(codec, lineout_gain_reg, 0x40, 0x00);
 		break;
 	}
@@ -1876,7 +1935,22 @@
 static int taiko_codec_enable_spk_pa(struct snd_soc_dapm_widget *w,
 				     struct snd_kcontrol *kcontrol, int event)
 {
-	pr_debug("%s %d %s\n", __func__, event, w->name);
+	struct snd_soc_codec *codec = w->codec;
+	struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
+
+	pr_debug("%s: %d %s\n", __func__, event, w->name);
+	WCD9XXX_BCL_LOCK(&taiko->resmgr);
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		taiko->spkr_pa_widget_on = true;
+		snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80, 0x80);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		taiko->spkr_pa_widget_on = false;
+		snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80, 0x00);
+		break;
+	}
+	WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
 	return 0;
 }
 
@@ -2054,45 +2128,44 @@
 {
 	struct snd_soc_codec *codec = w->codec;
 	struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
-	u16 micb_int_reg;
+	u16 micb_int_reg = 0, micb_ctl_reg = 0;
 	u8 cfilt_sel_val = 0;
 	char *internal1_text = "Internal1";
 	char *internal2_text = "Internal2";
 	char *internal3_text = "Internal3";
 	enum wcd9xxx_notify_event e_post_off, e_pre_on, e_post_on;
 
-	pr_debug("%s %d\n", __func__, event);
-	switch (w->reg) {
-	case TAIKO_A_MICB_1_CTL:
+	pr_debug("%s: w->name %s event %d\n", __func__, w->name, event);
+	if (strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1"))) {
+		micb_ctl_reg = TAIKO_A_MICB_1_CTL;
 		micb_int_reg = TAIKO_A_MICB_1_INT_RBIAS;
 		cfilt_sel_val = taiko->resmgr.pdata->micbias.bias1_cfilt_sel;
 		e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_1_ON;
 		e_post_on = WCD9XXX_EVENT_POST_MICBIAS_1_ON;
 		e_post_off = WCD9XXX_EVENT_POST_MICBIAS_1_OFF;
-		break;
-	case TAIKO_A_MICB_2_CTL:
+	} else if (strnstr(w->name, "MIC BIAS2", sizeof("MIC BIAS2"))) {
+		micb_ctl_reg = TAIKO_A_MICB_2_CTL;
 		micb_int_reg = TAIKO_A_MICB_2_INT_RBIAS;
 		cfilt_sel_val = taiko->resmgr.pdata->micbias.bias2_cfilt_sel;
 		e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_2_ON;
 		e_post_on = WCD9XXX_EVENT_POST_MICBIAS_2_ON;
 		e_post_off = WCD9XXX_EVENT_POST_MICBIAS_2_OFF;
-		break;
-	case TAIKO_A_MICB_3_CTL:
+	} else if (strnstr(w->name, "MIC BIAS3", sizeof("MIC BIAS3"))) {
+		micb_ctl_reg = TAIKO_A_MICB_2_CTL;
 		micb_int_reg = TAIKO_A_MICB_3_INT_RBIAS;
 		cfilt_sel_val = taiko->resmgr.pdata->micbias.bias3_cfilt_sel;
 		e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_3_ON;
 		e_post_on = WCD9XXX_EVENT_POST_MICBIAS_3_ON;
 		e_post_off = WCD9XXX_EVENT_POST_MICBIAS_3_OFF;
-		break;
-	case TAIKO_A_MICB_4_CTL:
+	} else if (strnstr(w->name, "MIC BIAS4", sizeof("MIC BIAS4"))) {
+		micb_ctl_reg = TAIKO_A_MICB_2_CTL;
 		micb_int_reg = taiko->resmgr.reg_addr->micb_4_int_rbias;
 		cfilt_sel_val = taiko->resmgr.pdata->micbias.bias4_cfilt_sel;
 		e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_4_ON;
 		e_post_on = WCD9XXX_EVENT_POST_MICBIAS_4_ON;
 		e_post_off = WCD9XXX_EVENT_POST_MICBIAS_4_OFF;
-		break;
-	default:
-		pr_err("%s: Error, invalid micbias register\n", __func__);
+	} else {
+		pr_err("%s: Error, invalid micbias %s\n", __func__, w->name);
 		return -EINVAL;
 	}
 
@@ -2111,6 +2184,16 @@
 		else if (strnstr(w->name, internal3_text, 30))
 			snd_soc_update_bits(codec, micb_int_reg, 0x3, 0x3);
 
+		if (micb_ctl_reg == TAIKO_A_MICB_2_CTL) {
+			WCD9XXX_BCL_LOCK(&taiko->resmgr);
+			wcd9xxx_resmgr_add_cond_update_bits(&taiko->resmgr,
+						  WCD9XXX_COND_HPH_MIC,
+						  micb_ctl_reg, w->shift,
+						  false);
+			WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
+		} else
+			snd_soc_update_bits(codec, micb_ctl_reg, 1 << w->shift,
+					    1 << w->shift);
 		break;
 	case SND_SOC_DAPM_POST_PMU:
 		usleep_range(20000, 20000);
@@ -2118,6 +2201,16 @@
 		wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_post_on);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
+		if (micb_ctl_reg == TAIKO_A_MICB_2_CTL) {
+			WCD9XXX_BCL_LOCK(&taiko->resmgr);
+			wcd9xxx_resmgr_rm_cond_update_bits(&taiko->resmgr,
+						  WCD9XXX_COND_HPH_MIC,
+						  micb_ctl_reg, 7, false);
+			WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
+		} else
+			snd_soc_update_bits(codec, micb_ctl_reg, 1 << w->shift,
+					    0);
+
 		/* Let MBHC module know so micbias switch to be off */
 		wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_post_off);
 
@@ -2288,6 +2381,42 @@
 	return ret;
 }
 
+static int taiko_codec_enable_vdd_spkr(struct snd_soc_dapm_widget *w,
+				       struct snd_kcontrol *kcontrol, int event)
+{
+	int ret = 0;
+	struct snd_soc_codec *codec = w->codec;
+	struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
+
+	pr_debug("%s: %d %s\n", __func__, event, w->name);
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		if (spkr_drv_wrnd > 0) {
+			WARN_ON(!(snd_soc_read(codec, TAIKO_A_SPKR_DRV_EN) &
+				  0x80));
+			snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80,
+					    0x00);
+		}
+		if (TAIKO_IS_1_0(core->version))
+			snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_DBG_PWRSTG,
+					    0x24, 0x00);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		if (TAIKO_IS_1_0(core->version))
+			snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_DBG_PWRSTG,
+					    0x24, 0x24);
+		if (spkr_drv_wrnd > 0) {
+			WARN_ON(!!(snd_soc_read(codec, TAIKO_A_SPKR_DRV_EN) &
+				   0x80));
+			snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80,
+					    0x80);
+		}
+		break;
+	}
+
+	return ret;
+}
+
 static int taiko_codec_enable_interpolator(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
@@ -2345,18 +2474,52 @@
 	}
 	return 0;
 }
-static int taiko_hphr_dac_event(struct snd_soc_dapm_widget *w,
+
+static int taiko_hphl_dac_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
 	struct snd_soc_codec *codec = w->codec;
+	struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
 
 	pr_debug("%s %s %d\n", __func__, w->name, event);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		snd_soc_update_bits(codec, w->reg, 0x40, 0x40);
+		snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RDAC_CLK_EN_CTL,
+							0x02, 0x02);
+		wcd9xxx_clsh_fsm(codec, &taiko_p->clsh_d,
+						 WCD9XXX_CLSH_STATE_HPHL,
+						 WCD9XXX_CLSH_REQ_ENABLE,
+						 WCD9XXX_CLSH_EVENT_PRE_DAC);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
+		snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RDAC_CLK_EN_CTL,
+							0x02, 0x00);
+	}
+	return 0;
+}
+
+static int taiko_hphr_dac_event(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
+
+	pr_debug("%s %s %d\n", __func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RDAC_CLK_EN_CTL,
+							0x04, 0x04);
+		snd_soc_update_bits(codec, w->reg, 0x40, 0x40);
+		wcd9xxx_clsh_fsm(codec, &taiko_p->clsh_d,
+						 WCD9XXX_CLSH_STATE_HPHR,
+						 WCD9XXX_CLSH_REQ_ENABLE,
+						 WCD9XXX_CLSH_EVENT_PRE_DAC);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RDAC_CLK_EN_CTL,
+							0x04, 0x00);
 		snd_soc_update_bits(codec, w->reg, 0x40, 0x00);
 		break;
 	}
@@ -2369,14 +2532,17 @@
 	struct snd_soc_codec *codec = w->codec;
 	struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
 	enum wcd9xxx_notify_event e_pre_on, e_post_off;
+	u8 req_clsh_state;
 
 	pr_debug("%s: %s event = %d\n", __func__, w->name, event);
 	if (w->shift == 5) {
 		e_pre_on = WCD9XXX_EVENT_PRE_HPHR_PA_ON;
 		e_post_off = WCD9XXX_EVENT_POST_HPHR_PA_OFF;
+		req_clsh_state = WCD9XXX_CLSH_STATE_HPHL;
 	} else if (w->shift == 4) {
 		e_pre_on = WCD9XXX_EVENT_PRE_HPHL_PA_ON;
 		e_post_off = WCD9XXX_EVENT_POST_HPHL_PA_OFF;
+		req_clsh_state = WCD9XXX_CLSH_STATE_HPHR;
 	} else {
 		pr_err("%s: Invalid w->shift %d\n", __func__, w->shift);
 		return -EINVAL;
@@ -2389,29 +2555,27 @@
 		break;
 
 	case SND_SOC_DAPM_POST_PMU:
-		usleep_range(10000, 10000);
+		wcd9xxx_clsh_fsm(codec, &taiko->clsh_d,
+						 req_clsh_state,
+						 WCD9XXX_CLSH_REQ_ENABLE,
+						 WCD9XXX_CLSH_EVENT_POST_PA);
 
-		snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_5, 0x02, 0x00);
-		snd_soc_update_bits(codec, TAIKO_A_NCP_STATIC, 0x20, 0x00);
-		snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_3, 0x04, 0x04);
-		snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_3, 0x08, 0x00);
 
-		usleep_range(10, 10);
+		usleep_range(5000, 5000);
 		break;
 
 	case SND_SOC_DAPM_POST_PMD:
 		/* Let MBHC module know PA turned off */
 		wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_post_off);
 
-		/*
-		 * schedule work is required because at the time HPH PA DAPM
-		 * event callback is called by DAPM framework, CODEC dapm mutex
-		 * would have been locked while snd_soc_jack_report also
-		 * attempts to acquire same lock.
-		 */
+		wcd9xxx_clsh_fsm(codec, &taiko->clsh_d,
+						 req_clsh_state,
+						 WCD9XXX_CLSH_REQ_DISABLE,
+						 WCD9XXX_CLSH_EVENT_POST_PA);
+
 		pr_debug("%s: sleep 10 ms after %s PA disable.\n", __func__,
 			 w->name);
-		usleep_range(10000, 10000);
+		usleep_range(5000, 5000);
 		break;
 	}
 	return 0;
@@ -2428,11 +2592,16 @@
 	struct snd_kcontrol *kcontrol, int event)
 {
 	struct snd_soc_codec *codec = w->codec;
+	struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
 
 	pr_debug("%s %s %d\n", __func__, w->name, event);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
+		wcd9xxx_clsh_fsm(codec, &taiko->clsh_d,
+						 WCD9XXX_CLSH_STATE_LO,
+						 WCD9XXX_CLSH_REQ_ENABLE,
+						 WCD9XXX_CLSH_EVENT_PRE_DAC);
 		snd_soc_update_bits(codec, w->reg, 0x40, 0x40);
 		break;
 
@@ -2451,7 +2620,6 @@
 }
 
 static const struct snd_soc_dapm_route audio_i2s_map[] = {
-	{"RX_I2S_CLK", NULL, "CDC_CONN"},
 	{"SLIM RX1", NULL, "RX_I2S_CLK"},
 	{"SLIM RX2", NULL, "RX_I2S_CLK"},
 	{"SLIM RX3", NULL, "RX_I2S_CLK"},
@@ -2463,6 +2631,14 @@
 	{"SLIM TX10 MUX", NULL, "TX_I2S_CLK"},
 };
 
+static const struct snd_soc_dapm_route audio_i2s_map_1_0[] = {
+	{"RX_I2S_CLK", NULL, "CDC_CONN"},
+};
+
+static const struct snd_soc_dapm_route audio_i2s_map_2_0[] = {
+	{"RX_I2S_CLK", NULL, "CDC_I2S_RX_CONN"},
+};
+
 static const struct snd_soc_dapm_route audio_map[] = {
 	/* SLIMBUS Connections */
 	{"AIF1 CAP", NULL, "AIF1_CAP Mixer"},
@@ -2584,9 +2760,7 @@
 	{"EAR", NULL, "EAR PA"},
 	{"EAR PA", NULL, "EAR_PA_MIXER"},
 	{"EAR_PA_MIXER", NULL, "DAC1"},
-	{"DAC1", NULL, "CP"},
-	{"CP", NULL, "CLASS_H_EAR"},
-	{"CLASS_H_EAR", NULL, "CLASS_H_CLK"},
+	{"DAC1", NULL, "RX_BIAS"},
 
 	{"ANC1 FB MUX", "EAR_HPH_L", "RX1 MIX2"},
 	{"ANC1 FB MUX", "EAR_LINE_1", "RX2 MIX2"},
@@ -2598,17 +2772,11 @@
 
 	{"HPHL", NULL, "HPHL_PA_MIXER"},
 	{"HPHL_PA_MIXER", NULL, "HPHL DAC"},
+	{"HPHL DAC", NULL, "RX_BIAS"},
 
 	{"HPHR", NULL, "HPHR_PA_MIXER"},
 	{"HPHR_PA_MIXER", NULL, "HPHR DAC"},
-
-	{"HPHL DAC", NULL, "CP"},
-	{"CP", NULL, "CLASS_H_HPH_L"},
-	{"CLASS_H_HPH_L", NULL, "CLASS_H_CLK"},
-
-	{"HPHR DAC", NULL, "CP"},
-	{"CP", NULL, "CLASS_H_HPH_R"},
-	{"CLASS_H_HPH_R", NULL, "CLASS_H_CLK"},
+	{"HPHR DAC", NULL, "RX_BIAS"},
 
 	{"ANC", NULL, "ANC1 MUX"},
 	{"ANC", NULL, "ANC2 MUX"},
@@ -2623,8 +2791,8 @@
 
 	{"ANC", NULL, "CDC_CONN"},
 
-	{"DAC1", "Switch", "RX1 CHAIN"},
-	{"HPHL DAC", "Switch", "RX1 CHAIN"},
+	{"DAC1", "Switch", "CLASS_H_DSM MUX"},
+	{"HPHL DAC", "Switch", "CLASS_H_DSM MUX"},
 	{"HPHR DAC", NULL, "RX2 CHAIN"},
 
 	{"LINEOUT1", NULL, "LINEOUT1 PA"},
@@ -2633,30 +2801,20 @@
 	{"LINEOUT4", NULL, "LINEOUT4 PA"},
 	{"SPK_OUT", NULL, "SPK PA"},
 
-	{"LINEOUT1 PA", NULL, "CP"},
 	{"LINEOUT1 PA", NULL, "LINEOUT1_PA_MIXER"},
 	{"LINEOUT1_PA_MIXER", NULL, "LINEOUT1 DAC"},
 
-	{"LINEOUT2 PA", NULL, "CP"},
 	{"LINEOUT2 PA", NULL, "LINEOUT2_PA_MIXER"},
 	{"LINEOUT2_PA_MIXER", NULL, "LINEOUT2 DAC"},
 
-	{"LINEOUT3 PA", NULL, "CP"},
 	{"LINEOUT3 PA", NULL, "LINEOUT3_PA_MIXER"},
 	{"LINEOUT3_PA_MIXER", NULL, "LINEOUT3 DAC"},
 
-	{"LINEOUT4 PA", NULL, "CP"},
 	{"LINEOUT4 PA", NULL, "LINEOUT4_PA_MIXER"},
 	{"LINEOUT4_PA_MIXER", NULL, "LINEOUT4 DAC"},
 
-	{"CP", NULL, "CLASS_H_LINEOUTS_PA"},
-	{"CLASS_H_LINEOUTS_PA", NULL, "CLASS_H_CLK"},
-
-
-
 	{"LINEOUT1 DAC", NULL, "RX3 MIX1"},
 
-
 	{"RDAC5 MUX", "DEM3_INV", "RX3 MIX1"},
 	{"RDAC5 MUX", "DEM4", "RX4 MIX1"},
 
@@ -2671,13 +2829,15 @@
 
 	{"SPK PA", NULL, "SPK DAC"},
 	{"SPK DAC", NULL, "RX7 MIX2"},
+	{"SPK DAC", NULL, "VDD_SPKDRV"},
+
+	{"CLASS_H_DSM MUX", "DSM_HPHL_RX1", "RX1 CHAIN"},
 
 	{"RX1 CHAIN", NULL, "RX1 MIX2"},
 	{"RX2 CHAIN", NULL, "RX2 MIX2"},
 	{"RX1 CHAIN", NULL, "ANC"},
 	{"RX2 CHAIN", NULL, "ANC"},
 
-	{"CLASS_H_CLK", NULL, "RX_BIAS"},
 	{"LINEOUT1 DAC", NULL, "RX_BIAS"},
 	{"LINEOUT2 DAC", NULL, "RX_BIAS"},
 	{"LINEOUT3 DAC", NULL, "RX_BIAS"},
@@ -3019,10 +3179,22 @@
 	if (reg == TAIKO_A_MBHC_INSERT_DET_STATUS)
 		return 1;
 
+	switch (reg) {
+	case TAIKO_A_CDC_SPKR_CLIPDET_VAL0:
+	case TAIKO_A_CDC_SPKR_CLIPDET_VAL1:
+	case TAIKO_A_CDC_SPKR_CLIPDET_VAL2:
+	case TAIKO_A_CDC_SPKR_CLIPDET_VAL3:
+	case TAIKO_A_CDC_SPKR_CLIPDET_VAL4:
+	case TAIKO_A_CDC_SPKR_CLIPDET_VAL5:
+	case TAIKO_A_CDC_SPKR_CLIPDET_VAL6:
+	case TAIKO_A_CDC_SPKR_CLIPDET_VAL7:
+	case TAIKO_A_CDC_VBAT_GAIN_MON_VAL:
+		return 1;
+	}
+
 	return 0;
 }
 
-#define TAIKO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
 static int taiko_write(struct snd_soc_codec *codec, unsigned int reg,
 	unsigned int value)
 {
@@ -3205,8 +3377,8 @@
 		}
 		list_for_each_entry(ch, &taiko_p->dai[dai->id].wcd9xxx_ch_list,
 				    list) {
-			pr_debug("%s: rx_slot[%d] %d, ch->ch_num %d\n",
-				 __func__, i, rx_slot[i], ch->ch_num);
+			pr_debug("%s: slot_num %u ch->ch_num %d\n",
+				 __func__, i, ch->ch_num);
 			rx_slot[i++] = ch->ch_num;
 		}
 		pr_debug("%s: rx_num %d\n", __func__, i);
@@ -3222,8 +3394,8 @@
 		}
 		list_for_each_entry(ch, &taiko_p->dai[dai->id].wcd9xxx_ch_list,
 				    list) {
-			pr_debug("%s: tx_slot[%d] %d, ch->ch_num %d\n",
-				 __func__, i, tx_slot[i], ch->ch_num);
+			pr_debug("%s: slot_num %u ch->ch_num %d\n",
+				 __func__, i,  ch->ch_num);
 			tx_slot[i++] = ch->ch_num;
 		}
 		pr_debug("%s: tx_num %d\n", __func__, i);
@@ -3499,6 +3671,29 @@
 			snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_I2S_CTL,
 					    0x03, (rx_fs_rate >> 0x05));
 		} else {
+			switch (params_format(params)) {
+			case SNDRV_PCM_FORMAT_S16_LE:
+				snd_soc_update_bits(codec,
+					TAIKO_A_CDC_CONN_RX_SB_B1_CTL,
+					0xFF, 0xAA);
+				snd_soc_update_bits(codec,
+					TAIKO_A_CDC_CONN_RX_SB_B2_CTL,
+					0xFF, 0x2A);
+				taiko->dai[dai->id].bit_width = 16;
+				break;
+			case SNDRV_PCM_FORMAT_S24_LE:
+				snd_soc_update_bits(codec,
+					TAIKO_A_CDC_CONN_RX_SB_B1_CTL,
+					0xFF, 0x00);
+				snd_soc_update_bits(codec,
+					TAIKO_A_CDC_CONN_RX_SB_B2_CTL,
+					0xFF, 0x00);
+				taiko->dai[dai->id].bit_width = 24;
+				break;
+			default:
+				dev_err(codec->dev, "Invalid format\n");
+				break;
+			}
 			taiko->dai[dai->id].rate   = params_rate(params);
 		}
 		break;
@@ -3528,7 +3723,7 @@
 		.playback = {
 			.stream_name = "AIF1 Playback",
 			.rates = WCD9320_RATES,
-			.formats = TAIKO_FORMATS,
+			.formats = TAIKO_FORMATS_S16_S24_LE,
 			.rate_max = 192000,
 			.rate_min = 8000,
 			.channels_min = 1,
@@ -3556,7 +3751,7 @@
 		.playback = {
 			.stream_name = "AIF2 Playback",
 			.rates = WCD9320_RATES,
-			.formats = TAIKO_FORMATS,
+			.formats = TAIKO_FORMATS_S16_S24_LE,
 			.rate_min = 8000,
 			.rate_max = 192000,
 			.channels_min = 1,
@@ -3598,7 +3793,7 @@
 		.playback = {
 			.stream_name = "AIF3 Playback",
 			.rates = WCD9320_RATES,
-			.formats = TAIKO_FORMATS,
+			.formats = TAIKO_FORMATS_S16_S24_LE,
 			.rate_min = 8000,
 			.rate_max = 192000,
 			.channels_min = 1,
@@ -3637,6 +3832,34 @@
 		},
 		.ops = &taiko_dai_ops,
 	},
+	{
+		.name = "taiko_i2s_rx2",
+		.id = AIF1_PB,
+		.playback = {
+			.stream_name = "AIF2 Playback",
+			.rates = WCD9320_RATES,
+			.formats = TAIKO_FORMATS,
+			.rate_max = 192000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 4,
+		},
+		.ops = &taiko_dai_ops,
+	},
+	{
+		.name = "taiko_i2s_tx2",
+		.id = AIF1_CAP,
+		.capture = {
+			.stream_name = "AIF2 Capture",
+			.rates = WCD9320_RATES,
+			.formats = TAIKO_FORMATS,
+			.rate_max = 192000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 4,
+		},
+		.ops = &taiko_dai_ops,
+	},
 };
 
 static int taiko_codec_enable_slim_chmask(struct wcd9xxx_codec_dai_data *dai,
@@ -3767,24 +3990,81 @@
 	struct snd_kcontrol *kcontrol, int event)
 {
 	struct snd_soc_codec *codec = w->codec;
+	struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
 
 	pr_debug("%s %s %d\n", __func__, w->name, event);
 
 	switch (event) {
-		break;
 	case SND_SOC_DAPM_POST_PMU:
-
-		snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_5, 0x02, 0x00);
-		snd_soc_update_bits(codec, TAIKO_A_NCP_STATIC, 0x20, 0x00);
-		snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_3, 0x04, 0x04);
-		snd_soc_update_bits(codec, TAIKO_A_BUCK_MODE_3, 0x08, 0x00);
+		wcd9xxx_clsh_fsm(codec, &taiko_p->clsh_d,
+						 WCD9XXX_CLSH_STATE_EAR,
+						 WCD9XXX_CLSH_REQ_ENABLE,
+						 WCD9XXX_CLSH_EVENT_POST_PA);
 
 		usleep_range(5000, 5000);
 		break;
+	case SND_SOC_DAPM_POST_PMD:
+		wcd9xxx_clsh_fsm(codec, &taiko_p->clsh_d,
+						 WCD9XXX_CLSH_STATE_EAR,
+						 WCD9XXX_CLSH_REQ_DISABLE,
+						 WCD9XXX_CLSH_EVENT_POST_PA);
+		usleep_range(5000, 5000);
+	}
+	return 0;
+}
+
+static int taiko_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
+
+	pr_debug("%s %s %d\n", __func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		wcd9xxx_clsh_fsm(codec, &taiko_p->clsh_d,
+						 WCD9XXX_CLSH_STATE_EAR,
+						 WCD9XXX_CLSH_REQ_ENABLE,
+						 WCD9XXX_CLSH_EVENT_PRE_DAC);
+		break;
+	}
+
+	return 0;
+}
+
+static int taiko_codec_dsm_mux_event(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	u8 reg_val, zoh_mux_val = 0x00;
+
+	pr_debug("%s: event = %d\n", __func__, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		reg_val = snd_soc_read(codec, TAIKO_A_CDC_CONN_CLSH_CTL);
+
+		if ((reg_val & 0x30) == 0x10)
+			zoh_mux_val = 0x04;
+		else if ((reg_val & 0x30) == 0x20)
+			zoh_mux_val = 0x08;
+
+		if (zoh_mux_val != 0x00)
+			snd_soc_update_bits(codec,
+					TAIKO_A_CDC_CONN_CLSH_CTL,
+					0x0C, zoh_mux_val);
+		break;
+
+	case SND_SOC_DAPM_POST_PMD:
+		snd_soc_update_bits(codec, TAIKO_A_CDC_CONN_CLSH_CTL,
+							0x0C, 0x00);
+		break;
 	}
 	return 0;
 }
 
+
 /* Todo: Have seperate dapm widgets for I2S and Slimbus.
  * Might Need to have callbacks registered only for slimbus
  */
@@ -3793,10 +4073,12 @@
 	SND_SOC_DAPM_OUTPUT("EAR"),
 
 	SND_SOC_DAPM_PGA_E("EAR PA", TAIKO_A_RX_EAR_EN, 4, 0, NULL, 0,
-			taiko_codec_enable_ear_pa, SND_SOC_DAPM_POST_PMU),
+			taiko_codec_enable_ear_pa, SND_SOC_DAPM_POST_PMU |
+			SND_SOC_DAPM_POST_PMD),
 
-	SND_SOC_DAPM_MIXER("DAC1", TAIKO_A_RX_EAR_EN, 6, 0, dac1_switch,
-		ARRAY_SIZE(dac1_switch)),
+	SND_SOC_DAPM_MIXER_E("DAC1", TAIKO_A_RX_EAR_EN, 6, 0, dac1_switch,
+		ARRAY_SIZE(dac1_switch), taiko_codec_ear_dac_event,
+		SND_SOC_DAPM_PRE_PMU),
 
 	SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM,
 				AIF1_PB, 0, taiko_codec_enable_slimrx,
@@ -3836,8 +4118,9 @@
 	SND_SOC_DAPM_PGA_E("HPHL", TAIKO_A_RX_HPH_CNP_EN, 5, 0, NULL, 0,
 		taiko_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
 		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MIXER("HPHL DAC", TAIKO_A_RX_HPH_L_DAC_CTL, 7, 0,
-		hphl_switch, ARRAY_SIZE(hphl_switch)),
+	SND_SOC_DAPM_MIXER_E("HPHL DAC", TAIKO_A_RX_HPH_L_DAC_CTL, 7, 0,
+		hphl_switch, ARRAY_SIZE(hphl_switch), taiko_hphl_dac_event,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 
 	SND_SOC_DAPM_PGA_E("HPHR", TAIKO_A_RX_HPH_CNP_EN, 4, 0, NULL, 0,
 		taiko_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
@@ -3866,9 +4149,9 @@
 	SND_SOC_DAPM_PGA_E("LINEOUT4 PA", TAIKO_A_RX_LINE_CNP_EN, 3, 0, NULL,
 			0, taiko_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
 			SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_PGA_E("SPK PA", TAIKO_A_SPKR_DRV_EN, 7, 0 , NULL,
-			   0, taiko_codec_enable_spk_pa, SND_SOC_DAPM_PRE_PMU |
-			   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_PGA_E("SPK PA", SND_SOC_NOPM, 0, 0 , NULL,
+			   0, taiko_codec_enable_spk_pa,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 
 	SND_SOC_DAPM_DAC_E("LINEOUT1 DAC", NULL, TAIKO_A_RX_LINE_1_DAC_CTL, 7, 0
 		, taiko_lineout_dac_event,
@@ -3891,6 +4174,10 @@
 			   taiko_spk_dac_event,
 			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 
+	SND_SOC_DAPM_SUPPLY("VDD_SPKDRV", SND_SOC_NOPM, 0, 0,
+			    taiko_codec_enable_vdd_spkr,
+			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
 	SND_SOC_DAPM_MIXER("RX1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
 	SND_SOC_DAPM_MIXER("RX2 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
 	SND_SOC_DAPM_MIXER("RX7 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -3969,33 +4256,20 @@
 	SND_SOC_DAPM_MUX("RDAC7 MUX", SND_SOC_NOPM, 0, 0,
 		&rx_dac7_mux),
 
-	SND_SOC_DAPM_SUPPLY("CLASS_H_CLK", TAIKO_A_CDC_CLK_OTHR_CTL, 0, 0,
-		taiko_codec_enable_class_h_clk, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_PRE_PMD),
-
-	SND_SOC_DAPM_SUPPLY("CLASS_H_EAR", TAIKO_A_CDC_CLSH_B1_CTL, 4, 0,
-		taiko_codec_enable_class_h, SND_SOC_DAPM_POST_PMU),
-
-	SND_SOC_DAPM_SUPPLY("CLASS_H_HPH_L", TAIKO_A_CDC_CLSH_B1_CTL, 3, 0,
-		taiko_codec_enable_class_h, SND_SOC_DAPM_POST_PMU),
-
-	SND_SOC_DAPM_SUPPLY("CLASS_H_HPH_R", TAIKO_A_CDC_CLSH_B1_CTL, 2, 0,
-		taiko_codec_enable_class_h, SND_SOC_DAPM_POST_PMU),
-
-	SND_SOC_DAPM_SUPPLY("CLASS_H_LINEOUTS_PA", SND_SOC_NOPM, 0, 0,
-		taiko_codec_enable_class_h, SND_SOC_DAPM_POST_PMU),
-
-	SND_SOC_DAPM_SUPPLY("CP", TAIKO_A_NCP_EN, 0, 0,
-		taiko_codec_enable_charge_pump, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+	SND_SOC_DAPM_MUX_E("CLASS_H_DSM MUX", SND_SOC_NOPM, 0, 0,
+		&class_h_dsm_mux, taiko_codec_dsm_mux_event,
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
 
 	SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0,
 		taiko_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU |
 		SND_SOC_DAPM_POST_PMD),
 
+	SND_SOC_DAPM_SUPPLY("CDC_I2S_RX_CONN", WCD9XXX_A_CDC_CLK_OTHR_CTL, 5, 0,
+			    NULL, 0),
+
 	/* TX */
 
-	SND_SOC_DAPM_SUPPLY("CDC_CONN", TAIKO_A_CDC_CLK_OTHR_CTL, 2, 0, NULL,
+	SND_SOC_DAPM_SUPPLY("CDC_CONN", WCD9XXX_A_CDC_CLK_OTHR_CTL, 2, 0, NULL,
 		0),
 
 	SND_SOC_DAPM_SUPPLY("LDO_H", TAIKO_A_LDO_H_MODE_1, 7, 0,
@@ -4013,15 +4287,18 @@
 
 
 	SND_SOC_DAPM_INPUT("AMIC1"),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 External", TAIKO_A_MICB_1_CTL, 7, 0,
-		taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal1", TAIKO_A_MICB_1_CTL, 7, 0,
-		taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal2", TAIKO_A_MICB_1_CTL, 7, 0,
-		taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 External", SND_SOC_NOPM, 7, 0,
+			       taiko_codec_enable_micbias,
+			       SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			       SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal1", SND_SOC_NOPM, 7, 0,
+			       taiko_codec_enable_micbias,
+			       SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			       SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal2", SND_SOC_NOPM, 7, 0,
+			       taiko_codec_enable_micbias,
+			       SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			       SND_SOC_DAPM_POST_PMD),
 	SND_SOC_DAPM_ADC_E("ADC1", NULL, TAIKO_A_TX_1_2_EN, 7, 0,
 		taiko_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
 		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
@@ -4104,31 +4381,38 @@
 	SND_SOC_DAPM_MUX("ANC1 FB MUX", SND_SOC_NOPM, 0, 0, &anc1_fb_mux),
 
 	SND_SOC_DAPM_INPUT("AMIC2"),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 External", TAIKO_A_MICB_2_CTL, 7, 0,
-		taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMU |	SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal1", TAIKO_A_MICB_2_CTL, 7, 0,
-		taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal2", TAIKO_A_MICB_2_CTL, 7, 0,
-		taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal3", TAIKO_A_MICB_2_CTL, 7, 0,
-		taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 External", TAIKO_A_MICB_3_CTL, 7, 0,
-		taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal1", TAIKO_A_MICB_3_CTL, 7, 0,
-		taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal2", TAIKO_A_MICB_3_CTL, 7, 0,
-		taiko_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS4 External", TAIKO_A_MICB_4_CTL, 7,
-				0, taiko_codec_enable_micbias,
-				SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
-				SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 External", SND_SOC_NOPM, 7, 0,
+			       taiko_codec_enable_micbias,
+			       SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			       SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal1", SND_SOC_NOPM, 7, 0,
+			       taiko_codec_enable_micbias,
+			       SND_SOC_DAPM_PRE_PMU |
+			       SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal2", SND_SOC_NOPM, 7, 0,
+			       taiko_codec_enable_micbias,
+			       SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			       SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal3", SND_SOC_NOPM, 7, 0,
+			       taiko_codec_enable_micbias,
+			       SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			       SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 External", SND_SOC_NOPM, 7, 0,
+			       taiko_codec_enable_micbias,
+			       SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			       SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal1", SND_SOC_NOPM, 7, 0,
+			       taiko_codec_enable_micbias,
+			       SND_SOC_DAPM_PRE_PMU |
+			       SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal2", SND_SOC_NOPM, 7, 0,
+			       taiko_codec_enable_micbias,
+			       SND_SOC_DAPM_PRE_PMU |
+			       SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS4 External", SND_SOC_NOPM, 7,
+			       0, taiko_codec_enable_micbias,
+			       SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			       SND_SOC_DAPM_POST_PMD),
 
 	SND_SOC_DAPM_ADC_E("ADC2", NULL, TAIKO_A_TX_1_2_EN, 3, 0,
 		taiko_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
@@ -4304,84 +4588,6 @@
 	return IRQ_HANDLED;
 }
 
-static const struct taiko_reg_mask_val taiko_1_0_class_h_ear[] = {
-
-	/* CLASS-H EAR  IDLE_THRESHOLD Table */
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_IDLE_EAR_THSD, 0x26),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_FCLKONLY_EAR_THSD, 0x2C),
-
-	/* CLASS-H EAR I_PA_FACT Table. */
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_I_PA_FACT_EAR_L,	0xA9),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_I_PA_FACT_EAR_U, 0x07),
-
-	/* CLASS-H EAR Voltage Headroom , Voltage Min. */
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_V_PA_HD_EAR, 0x0D),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_V_PA_MIN_EAR, 0x3A),
-
-	/* CLASS-H EAR K values --chnages from load. */
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_ADDR, 0x08),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x1B),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x00),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x2D),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x00),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x36),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x00),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x37),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x00),
-	/** end of Ear PA load 32 */
-};
-
-static const struct taiko_reg_mask_val taiko_1_0_class_h_hph[] = {
-
-	/* CLASS-H HPH  IDLE_THRESHOLD Table */
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_IDLE_HPH_THSD, 0x13),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0x19),
-
-	/* CLASS-H HPH I_PA_FACT Table */
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_I_PA_FACT_HPH_L,	0x9A),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_I_PA_FACT_HPH_U, 0x06),
-
-	/* CLASS-H HPH Voltage Headroom , Voltage Min */
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_V_PA_HD_HPH, 0x0D),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_V_PA_MIN_HPH, 0x1D),
-
-	/* CLASS-H HPH K values --chnages from load .*/
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_ADDR, 0x00),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0xAE),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x01),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x1C),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x00),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x25),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x00),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x27),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_K_DATA, 0x00),
-};
-
-static int taiko_config_ear_class_h(struct snd_soc_codec *codec, u32 ear_load)
-{
-	u32 i;
-
-	if (ear_load  != 32)
-		return -EINVAL;
-
-	for (i = 0; i < ARRAY_SIZE(taiko_1_0_class_h_ear); i++)
-		snd_soc_write(codec, taiko_1_0_class_h_ear[i].reg,
-				taiko_1_0_class_h_ear[i].val);
-	return 0;
-}
-
-static int taiko_config_hph_class_h(struct snd_soc_codec *codec, u32 hph_load)
-{
-	u32 i;
-	if (hph_load  != 16)
-		return -EINVAL;
-
-	for (i = 0; i < ARRAY_SIZE(taiko_1_0_class_h_hph); i++)
-		snd_soc_write(codec, taiko_1_0_class_h_hph[i].reg,
-				taiko_1_0_class_h_hph[i].val);
-	return 0;
-}
-
 static int taiko_handle_pdata(struct taiko_priv *taiko)
 {
 	struct snd_soc_codec *codec = taiko->codec;
@@ -4520,41 +4726,19 @@
 		 0x00 : 0x16);
 	snd_soc_update_bits(codec, TAIKO_A_MICB_4_CTL, 0x1E, value);
 
-	taiko_config_ear_class_h(codec, 32);
-	taiko_config_hph_class_h(codec, 16);
-
 done:
 	return rc;
 }
 
-static const struct taiko_reg_mask_val taiko_reg_defaults[] = {
+static const struct wcd9xxx_reg_mask_val taiko_reg_defaults[] = {
 
 	/* set MCLk to 9.6 */
-	TAIKO_REG_VAL(TAIKO_A_CHIP_CTL, 0x0A),
+	TAIKO_REG_VAL(TAIKO_A_CHIP_CTL, 0x02),
 	TAIKO_REG_VAL(TAIKO_A_CDC_CLK_POWER_CTL, 0x03),
 
 	/* EAR PA deafults  */
 	TAIKO_REG_VAL(TAIKO_A_RX_EAR_CMBUFF, 0x05),
 
-	/** BUCK and NCP defaults for EAR and HS */
-	TAIKO_REG_VAL(TAIKO_A_BUCK_CTRL_CCL_4, 0x50),
-	TAIKO_REG_VAL(TAIKO_A_BUCK_CTRL_CCL_1, 0x5B),
-
-	/* CLASS-H defaults for EAR and HS */
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_BUCK_NCP_VARS, 0x00),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_BUCK_NCP_VARS, 0x04),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_B2_CTL, 0x01),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_B2_CTL, 0x05),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_B2_CTL, 0x35),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_B3_CTL, 0x30),
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_B3_CTL, 0x3B),
-
-	/*
-	 * For CLASS-H, Enable ANC delay buffer,
-	 * set HPHL and EAR PA ref gain to 0 DB.
-	 */
-	TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_B1_CTL, 0x26),
-
 	/* RX deafults */
 	TAIKO_REG_VAL(TAIKO_A_CDC_RX1_B5_CTL, 0x78),
 	TAIKO_REG_VAL(TAIKO_A_CDC_RX2_B5_CTL, 0x78),
@@ -4576,21 +4760,31 @@
 	TAIKO_REG_VAL(TAIKO_A_CDC_RX7_B6_CTL, 0x80),
 };
 
-static const struct taiko_reg_mask_val taiko_1_0_reg_defaults[] = {
+static const struct wcd9xxx_reg_mask_val taiko_1_0_reg_defaults[] = {
 	/*
 	 * The following only need to be written for Taiko 1.0 parts.
 	 * Taiko 2.0 will have appropriate defaults for these registers.
 	 */
+
+	/* BUCK default */
+	TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_4, 0x50),
+
+	/* Required defaults for class H operation */
+	TAIKO_REG_VAL(TAIKO_A_RX_HPH_CHOP_CTL, 0xF4),
+	TAIKO_REG_VAL(TAIKO_A_BIAS_CURR_CTL_2, 0x08),
+	TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_1, 0x5B),
+	TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_3, 0x60),
+
 	/* Choose max non-overlap time for NCP */
 	TAIKO_REG_VAL(TAIKO_A_NCP_CLK, 0xFC),
 	/* Use 25mV/50mV for deltap/m to reduce ripple */
-	TAIKO_REG_VAL(TAIKO_A_BUCK_CTRL_VCL_1, 0x08),
+	TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_VCL_1, 0x08),
 	/*
 	 * Set DISABLE_MODE_SEL<1:0> to 0b10 (disable PWM in auto mode).
 	 * Note that the other bits of this register will be changed during
 	 * Rx PA bring up.
 	 */
-	TAIKO_REG_VAL(TAIKO_A_BUCK_MODE_3, 0xCE),
+	TAIKO_REG_VAL(WCD9XXX_A_BUCK_MODE_3, 0xCE),
 	/* Reduce HPH DAC bias to 70% */
 	TAIKO_REG_VAL(TAIKO_A_RX_HPH_BIAS_PA, 0x7A),
 	/*Reduce EAR DAC bias to 70% */
@@ -4610,6 +4804,63 @@
 	TAIKO_REG_VAL(TAIKO_A_TX_SUP_SWITCH_CTRL_1, 0xBF),
 	/* Enable MICB 4 VDDIO switch to prevent leakage */
 	TAIKO_REG_VAL(TAIKO_A_MICB_4_MBHC, 0x81),
+
+	/* Close leakage on the spkdrv */
+	TAIKO_REG_VAL(TAIKO_A_SPKR_DRV_DBG_PWRSTG, 0x24),
+};
+
+/*
+ * Don't update TAIKO_A_CHIP_CTL, TAIKO_A_BUCK_CTRL_CCL_1 and
+ * TAIKO_A_RX_EAR_CMBUFF as those are updated in taiko_reg_defaults
+ */
+static const struct wcd9xxx_reg_mask_val taiko_2_0_reg_defaults[] = {
+	TAIKO_REG_VAL(TAIKO_A_CDC_TX_1_GAIN, 0x2),
+	TAIKO_REG_VAL(TAIKO_A_CDC_TX_2_GAIN, 0x2),
+	TAIKO_REG_VAL(TAIKO_A_CDC_TX_1_2_ADC_IB, 0x44),
+	TAIKO_REG_VAL(TAIKO_A_CDC_TX_3_GAIN, 0x2),
+	TAIKO_REG_VAL(TAIKO_A_CDC_TX_4_GAIN, 0x2),
+	TAIKO_REG_VAL(TAIKO_A_CDC_TX_3_4_ADC_IB, 0x44),
+	TAIKO_REG_VAL(TAIKO_A_CDC_TX_5_GAIN, 0x2),
+	TAIKO_REG_VAL(TAIKO_A_CDC_TX_6_GAIN, 0x2),
+	TAIKO_REG_VAL(TAIKO_A_CDC_TX_5_6_ADC_IB, 0x44),
+	TAIKO_REG_VAL(WCD9XXX_A_BUCK_MODE_3, 0xCE),
+	TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_VCL_1, 0x8),
+	TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_4, 0x51),
+	TAIKO_REG_VAL(TAIKO_A_NCP_DTEST, 0x10),
+	TAIKO_REG_VAL(TAIKO_A_RX_HPH_CHOP_CTL, 0xA4),
+	TAIKO_REG_VAL(TAIKO_A_RX_HPH_BIAS_PA, 0x7A),
+	TAIKO_REG_VAL(TAIKO_A_RX_HPH_OCP_CTL, 0x69),
+	TAIKO_REG_VAL(TAIKO_A_RX_HPH_CNP_WG_CTL, 0xDA),
+	TAIKO_REG_VAL(TAIKO_A_RX_HPH_CNP_WG_TIME, 0x15),
+	TAIKO_REG_VAL(TAIKO_A_RX_EAR_BIAS_PA, 0x76),
+	TAIKO_REG_VAL(TAIKO_A_RX_EAR_CNP, 0xC0),
+	TAIKO_REG_VAL(TAIKO_A_RX_LINE_BIAS_PA, 0x78),
+	TAIKO_REG_VAL(TAIKO_A_RX_LINE_1_TEST, 0x2),
+	TAIKO_REG_VAL(TAIKO_A_RX_LINE_2_TEST, 0x2),
+	TAIKO_REG_VAL(TAIKO_A_RX_LINE_3_TEST, 0x2),
+	TAIKO_REG_VAL(TAIKO_A_RX_LINE_4_TEST, 0x2),
+	TAIKO_REG_VAL(TAIKO_A_SPKR_DRV_OCP_CTL, 0x97),
+	TAIKO_REG_VAL(TAIKO_A_SPKR_DRV_CLIP_DET, 0x1),
+	TAIKO_REG_VAL(TAIKO_A_SPKR_DRV_IEC, 0x0),
+	TAIKO_REG_VAL(TAIKO_A_CDC_TX1_MUX_CTL, 0x48),
+	TAIKO_REG_VAL(TAIKO_A_CDC_TX2_MUX_CTL, 0x48),
+	TAIKO_REG_VAL(TAIKO_A_CDC_TX3_MUX_CTL, 0x48),
+	TAIKO_REG_VAL(TAIKO_A_CDC_TX4_MUX_CTL, 0x48),
+	TAIKO_REG_VAL(TAIKO_A_CDC_TX5_MUX_CTL, 0x48),
+	TAIKO_REG_VAL(TAIKO_A_CDC_TX6_MUX_CTL, 0x48),
+	TAIKO_REG_VAL(TAIKO_A_CDC_TX7_MUX_CTL, 0x48),
+	TAIKO_REG_VAL(TAIKO_A_CDC_TX8_MUX_CTL, 0x48),
+	TAIKO_REG_VAL(TAIKO_A_CDC_TX9_MUX_CTL, 0x48),
+	TAIKO_REG_VAL(TAIKO_A_CDC_TX10_MUX_CTL, 0x48),
+	TAIKO_REG_VAL(TAIKO_A_CDC_RX1_B4_CTL, 0x8),
+	TAIKO_REG_VAL(TAIKO_A_CDC_VBAT_GAIN_UPD_MON, 0x0),
+	TAIKO_REG_VAL(TAIKO_A_CDC_PA_RAMP_B1_CTL, 0x0),
+	TAIKO_REG_VAL(TAIKO_A_CDC_PA_RAMP_B2_CTL, 0x0),
+	TAIKO_REG_VAL(TAIKO_A_CDC_PA_RAMP_B3_CTL, 0x0),
+	TAIKO_REG_VAL(TAIKO_A_CDC_PA_RAMP_B4_CTL, 0x0),
+	TAIKO_REG_VAL(TAIKO_A_CDC_SPKR_CLIPDET_B1_CTL, 0x0),
+	TAIKO_REG_VAL(TAIKO_A_CDC_COMP0_B4_CTL, 0x37),
+	TAIKO_REG_VAL(TAIKO_A_CDC_COMP0_B5_CTL, 0x7f),
 };
 
 static void taiko_update_reg_defaults(struct snd_soc_codec *codec)
@@ -4619,16 +4870,23 @@
 
 	for (i = 0; i < ARRAY_SIZE(taiko_reg_defaults); i++)
 		snd_soc_write(codec, taiko_reg_defaults[i].reg,
-				taiko_reg_defaults[i].val);
+			      taiko_reg_defaults[i].val);
 
 	if (TAIKO_IS_1_0(taiko_core->version)) {
 		for (i = 0; i < ARRAY_SIZE(taiko_1_0_reg_defaults); i++)
 			snd_soc_write(codec, taiko_1_0_reg_defaults[i].reg,
-				taiko_1_0_reg_defaults[i].val);
+				      taiko_1_0_reg_defaults[i].val);
+		if (spkr_drv_wrnd == 1)
+			snd_soc_write(codec, TAIKO_A_SPKR_DRV_EN, 0xEF);
+	} else {
+		for (i = 0; i < ARRAY_SIZE(taiko_2_0_reg_defaults); i++)
+			snd_soc_write(codec, taiko_2_0_reg_defaults[i].reg,
+				      taiko_2_0_reg_defaults[i].val);
+		spkr_drv_wrnd = -1;
 	}
 }
 
-static const struct taiko_reg_mask_val taiko_codec_reg_init_val[] = {
+static const struct wcd9xxx_reg_mask_val taiko_codec_reg_init_val[] = {
 	/* Initialize current threshold to 350MA
 	 * number of wait and run cycles to 4096
 	 */
@@ -4646,9 +4904,6 @@
 	{TAIKO_A_RX_LINE_4_GAIN, 0x20, 0x20},
 	{TAIKO_A_SPKR_DRV_GAIN, 0x04, 0x04},
 
-	/* CLASS H config */
-	{TAIKO_A_CDC_CONN_CLSH_CTL, 0x3C, 0x14},
-
 	/* Use 16 bit sample size for TX1 to TX6 */
 	{TAIKO_A_CDC_CONN_TX_SB_B1_CTL, 0x30, 0x20},
 	{TAIKO_A_CDC_CONN_TX_SB_B2_CTL, 0x30, 0x20},
@@ -4663,10 +4918,6 @@
 	{TAIKO_A_CDC_CONN_TX_SB_B9_CTL, 0x60, 0x40},
 	{TAIKO_A_CDC_CONN_TX_SB_B10_CTL, 0x60, 0x40},
 
-	/* Use 16 bit sample size for RX */
-	{TAIKO_A_CDC_CONN_RX_SB_B1_CTL, 0xFF, 0xAA},
-	{TAIKO_A_CDC_CONN_RX_SB_B2_CTL, 0xFF, 0x2A},
-
 	/*enable HPF filter for TX paths */
 	{TAIKO_A_CDC_TX1_MUX_CTL, 0x8, 0x0},
 	{TAIKO_A_CDC_TX2_MUX_CTL, 0x8, 0x0},
@@ -4744,12 +4995,78 @@
 }
 EXPORT_SYMBOL_GPL(taiko_hs_detect);
 
+static int taiko_post_reset_cb(struct wcd9xxx *wcd9xxx)
+{
+	int ret = 0;
+	struct snd_soc_codec *codec;
+	struct taiko_priv *taiko;
+
+	codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv);
+	taiko = snd_soc_codec_get_drvdata(codec);
+	mutex_lock(&codec->mutex);
+	WCD9XXX_BCL_LOCK(&taiko->resmgr);
+
+	if (codec->reg_def_copy) {
+		pr_debug("%s: Update ASOC cache", __func__);
+		kfree(codec->reg_cache);
+		codec->reg_cache = kmemdup(codec->reg_def_copy,
+						codec->reg_size, GFP_KERNEL);
+	}
+
+	wcd9xxx_resmgr_post_ssr(&taiko->resmgr);
+	if (spkr_drv_wrnd == 1)
+		snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80, 0x80);
+	WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
+
+	taiko_update_reg_defaults(codec);
+	taiko_codec_init_reg(codec);
+	ret = taiko_handle_pdata(taiko);
+	if (IS_ERR_VALUE(ret))
+		pr_err("%s: bad pdata\n", __func__);
+
+	wcd9xxx_mbhc_deinit(&taiko->mbhc);
+	ret = wcd9xxx_mbhc_init(&taiko->mbhc, &taiko->resmgr, codec);
+	if (ret)
+		pr_err("%s: mbhc init failed %d\n", __func__, ret);
+	else
+		wcd9xxx_mbhc_start(&taiko->mbhc, taiko->mbhc.mbhc_cfg);
+	mutex_unlock(&codec->mutex);
+	return ret;
+}
+
+
 static struct wcd9xxx_reg_address taiko_reg_address = {
 	.micb_4_mbhc = TAIKO_A_MICB_4_MBHC,
 	.micb_4_int_rbias = TAIKO_A_MICB_4_INT_RBIAS,
 	.micb_4_ctl = TAIKO_A_MICB_4_CTL,
 };
 
+static int wcd9xxx_ssr_register(struct wcd9xxx *control,
+		int (*post_reset_cb)(struct wcd9xxx *wcd9xxx), void *priv)
+{
+	control->post_reset = post_reset_cb;
+	control->ssr_priv = priv;
+	return 0;
+}
+
+static int taiko_codec_get_buck_mv(struct snd_soc_codec *codec)
+{
+	int buck_volt = WCD9XXX_CDC_BUCK_UNSUPPORTED;
+	struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
+	struct wcd9xxx_pdata *pdata = taiko->resmgr.pdata;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++) {
+		if (!strncmp(pdata->regulator[i].name,
+					 WCD9XXX_SUPPLY_BUCK_NAME,
+					 sizeof(WCD9XXX_SUPPLY_BUCK_NAME))) {
+			buck_volt = pdata->regulator[i].min_uV;
+			break;
+		}
+	}
+	return buck_volt;
+}
+
 static int taiko_codec_probe(struct snd_soc_codec *codec)
 {
 	struct wcd9xxx *control;
@@ -4760,10 +5077,13 @@
 	int ret = 0;
 	int i;
 	void *ptr = NULL;
+	struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
 
 	codec->control_data = dev_get_drvdata(codec->dev->parent);
 	control = codec->control_data;
 
+	wcd9xxx_ssr_register(control, taiko_post_reset_cb, (void *)codec);
+
 	dev_info(codec->dev, "%s()\n", __func__);
 
 	taiko = kzalloc(sizeof(struct taiko_priv), GFP_KERNEL);
@@ -4778,8 +5098,10 @@
 			tx_hpf_corner_freq_callback);
 	}
 
+
 	snd_soc_codec_set_drvdata(codec, taiko);
 
+
 	/* codec resmgr module init */
 	wcd9xxx = codec->control_data;
 	pdata = dev_get_platdata(codec->dev->parent);
@@ -4790,6 +5112,9 @@
 		return ret;
 	}
 
+	taiko->clsh_d.buck_mv = taiko_codec_get_buck_mv(codec);
+	wcd9xxx_clsh_init(&taiko->clsh_d);
+
 	/* init and start mbhc */
 	ret = wcd9xxx_mbhc_init(&taiko->mbhc, &taiko->resmgr, codec);
 	if (ret) {
@@ -4809,9 +5134,9 @@
 	taiko_update_reg_defaults(codec);
 	pr_debug("%s: MCLK Rate = %x\n", __func__, wcd9xxx->mclk_rate);
 	if (wcd9xxx->mclk_rate == TAIKO_MCLK_CLK_12P288MHZ)
-		snd_soc_write(codec, TAIKO_A_CHIP_CTL, 0x04);
+		snd_soc_update_bits(codec, TAIKO_A_CHIP_CTL, 0x06, 0x0);
 	else if (wcd9xxx->mclk_rate == TAIKO_MCLK_CLK_9P6HZ)
-		snd_soc_write(codec, TAIKO_A_CHIP_CTL, 0x0A);
+		snd_soc_update_bits(codec, TAIKO_A_CHIP_CTL, 0x06, 0x2);
 	taiko_codec_init_reg(codec);
 	ret = taiko_handle_pdata(taiko);
 	if (IS_ERR_VALUE(ret)) {
@@ -4819,6 +5144,13 @@
 		goto err_pdata;
 	}
 
+	if (spkr_drv_wrnd > 0) {
+		WCD9XXX_BCL_LOCK(&taiko->resmgr);
+		wcd9xxx_resmgr_get_bandgap(&taiko->resmgr,
+					   WCD9XXX_BANDGAP_AUDIO_MODE);
+		WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
+	}
+
 	ptr = kmalloc((sizeof(taiko_rx_chs) +
 		       sizeof(taiko_tx_chs)), GFP_KERNEL);
 	if (!ptr) {
@@ -4832,6 +5164,12 @@
 			ARRAY_SIZE(taiko_dapm_i2s_widgets));
 		snd_soc_dapm_add_routes(dapm, audio_i2s_map,
 			ARRAY_SIZE(audio_i2s_map));
+		if (TAIKO_IS_1_0(core->version))
+			snd_soc_dapm_add_routes(dapm, audio_i2s_map_1_0,
+						ARRAY_SIZE(audio_i2s_map_1_0));
+		else
+			snd_soc_dapm_add_routes(dapm, audio_i2s_map_2_0,
+						ARRAY_SIZE(audio_i2s_map_2_0));
 		for (i = 0; i < ARRAY_SIZE(taiko_i2s_dai); i++)
 			INIT_LIST_HEAD(&taiko->dai[i].wcd9xxx_ch_list);
 	} else if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
@@ -4852,6 +5190,8 @@
 
 	(void) taiko_setup_irqs(taiko);
 
+	atomic_set(&kp_taiko_priv, (unsigned long)taiko);
+
 	codec->ignore_pmdown_time = 1;
 	return ret;
 
@@ -4865,6 +5205,14 @@
 {
 	struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
 
+	WCD9XXX_BCL_LOCK(&taiko->resmgr);
+	atomic_set(&kp_taiko_priv, 0);
+
+	if (spkr_drv_wrnd > 0)
+		wcd9xxx_resmgr_put_bandgap(&taiko->resmgr,
+					   WCD9XXX_BANDGAP_AUDIO_MODE);
+	WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
+
 	/* cleanup MBHC */
 	wcd9xxx_mbhc_deinit(&taiko->mbhc);
 	/* cleanup resmgr */
diff --git a/sound/soc/codecs/wcd9320.h b/sound/soc/codecs/wcd9320.h
index 1fff80c..89a0b9f 100644
--- a/sound/soc/codecs/wcd9320.h
+++ b/sound/soc/codecs/wcd9320.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -41,12 +41,6 @@
 	TAIKO_PID_MIC_20_UA,
 };
 
-struct taiko_reg_mask_val {
-	u16	reg;
-	u8	mask;
-	u8	val;
-};
-
 enum taiko_mbhc_analog_pwr_cfg {
 	TAIKO_ANALOG_PWR_COLLAPSED = 0,
 	TAIKO_ANALOG_PWR_ON,
diff --git a/sound/soc/codecs/wcd9xxx-common.c b/sound/soc/codecs/wcd9xxx-common.c
new file mode 100644
index 0000000..dbf2e39
--- /dev/null
+++ b/sound/soc/codecs/wcd9xxx-common.c
@@ -0,0 +1,591 @@
+/* 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 <sound/soc.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
+#include "wcd9xxx-common.h"
+
+#define CLSH_COMPUTE_EAR 0x01
+#define CLSH_COMPUTE_HPH_L 0x02
+#define CLSH_COMPUTE_HPH_R 0x03
+
+#define BUCK_VREF_2V 0xFF
+#define BUCK_VREF_1P8V 0xE6
+
+#define NCP_FCLK_LEVEL_8 0x08
+#define NCP_FCLK_LEVEL_5 0x05
+
+#define BUCK_SETTLE_TIME_US 50
+#define NCP_SETTLE_TIME_US 50
+
+static inline void wcd9xxx_enable_clsh_block(
+	struct snd_soc_codec *codec,
+	bool on)
+{
+	snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLSH_B1_CTL,
+		0x01, on ? 0x01 : 0x00);
+}
+
+static inline void wcd9xxx_enable_anc_delay(
+	struct snd_soc_codec *codec,
+	bool on)
+{
+	snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLSH_B1_CTL,
+		0x02, on ? 0x02 : 0x00);
+}
+
+static inline void wcd9xxx_enable_ncp(
+	struct snd_soc_codec *codec,
+	bool on)
+{
+	snd_soc_update_bits(codec, WCD9XXX_A_NCP_EN,
+		0x01, on ? 0x01 : 0x00);
+}
+
+static inline void wcd9xxx_enable_buck(
+	struct snd_soc_codec *codec,
+	bool on)
+{
+	snd_soc_update_bits(codec, WCD9XXX_A_BUCK_MODE_1,
+		0x80, on ? 0x80 : 0x00);
+}
+
+static int cdc_lo_count;
+
+static void (*clsh_state_fp[NUM_CLSH_STATES])
+			(struct snd_soc_codec *,
+			 struct wcd9xxx_clsh_cdc_data *,
+			 u8 req_state, bool req_type);
+
+static const char *state_to_str(u8 state)
+{
+	if (state == WCD9XXX_CLSH_STATE_IDLE)
+		return "STATE_IDLE";
+	else if (state == WCD9XXX_CLSH_STATE_EAR)
+		return "STATE_EAR";
+	else if (state == WCD9XXX_CLSH_STATE_HPHL)
+		return "STATE_HPH_L";
+	else if (state == WCD9XXX_CLSH_STATE_HPHR)
+		return "STATE_HPH_R";
+	else if (state == (WCD9XXX_CLSH_STATE_HPHL
+				| WCD9XXX_CLSH_STATE_HPHR))
+		return "STATE_HPH_L_R";
+	else if (state == WCD9XXX_CLSH_STATE_LO)
+		return "STATE_LO";
+
+	return "UNKNOWN_STATE";
+}
+
+static void wcd9xxx_cfg_clsh_buck(
+		struct snd_soc_codec *codec)
+{
+	int i;
+	const struct wcd9xxx_reg_mask_val reg_set[] = {
+		{WCD9XXX_A_BUCK_CTRL_CCL_4, 0x0B, 0x00},
+		{WCD9XXX_A_BUCK_CTRL_CCL_1, 0xF0, 0x50},
+		{WCD9XXX_A_BUCK_CTRL_CCL_3, 0x03, 0x00},
+		{WCD9XXX_A_BUCK_CTRL_CCL_3, 0x0B, 0x00},
+	};
+
+	for (i = 0; i < ARRAY_SIZE(reg_set); i++)
+		snd_soc_update_bits(codec, reg_set[i].reg, reg_set[i].mask,
+						    reg_set[i].val);
+
+	dev_dbg(codec->dev, "%s: Programmed buck parameters", __func__);
+}
+
+static void wcd9xxx_cfg_clsh_param_common(
+		struct snd_soc_codec *codec)
+{
+	int i;
+	const struct wcd9xxx_reg_mask_val reg_set[] = {
+		{WCD9XXX_A_CDC_CLSH_BUCK_NCP_VARS, 0x3 << 0, 0},
+		{WCD9XXX_A_CDC_CLSH_BUCK_NCP_VARS, 0x3 << 2, 1 << 2},
+		{WCD9XXX_A_CDC_CLSH_BUCK_NCP_VARS, (0x1 << 4), 0},
+		{WCD9XXX_A_CDC_CLSH_B2_CTL, (0x3 << 0), 0x01},
+		{WCD9XXX_A_CDC_CLSH_B2_CTL, (0x3 << 2), (0x01 << 2)},
+		{WCD9XXX_A_CDC_CLSH_B2_CTL, (0xf << 4), (0x03 << 4)},
+		{WCD9XXX_A_CDC_CLSH_B3_CTL, (0xf << 4), (0x03 << 4)},
+		{WCD9XXX_A_CDC_CLSH_B3_CTL, (0xf << 0), (0x0B)},
+		{WCD9XXX_A_CDC_CLSH_B1_CTL, (0x1 << 5), (0x01 << 5)},
+		{WCD9XXX_A_CDC_CLSH_B1_CTL, (0x1 << 1), (0x01 << 1)},
+	};
+
+	for (i = 0; i < ARRAY_SIZE(reg_set); i++)
+		snd_soc_update_bits(codec, reg_set[i].reg, reg_set[i].mask,
+						    reg_set[i].val);
+
+	dev_dbg(codec->dev, "%s: Programmed class H controller common parameters",
+			 __func__);
+}
+
+static void wcd9xxx_chargepump_request(
+	struct snd_soc_codec *codec, bool on)
+{
+	static int cp_count;
+
+	if (on && (++cp_count == 1)) {
+		snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLK_OTHR_CTL,
+							0x01, 0x01);
+		dev_info(codec->dev, "%s: Charge Pump enabled, count = %d\n",
+				__func__, cp_count);
+	}
+
+	else if (!on) {
+		if (--cp_count < 0) {
+			dev_dbg(codec->dev, "%s: Unbalanced disable for charge pump\n",
+					__func__);
+			if (snd_soc_read(codec, WCD9XXX_A_CDC_CLK_OTHR_CTL)
+					& 0x01) {
+				dev_info(codec->dev, "%s: Actual chargepump is ON\n",
+						__func__);
+			}
+			cp_count = 0;
+			WARN_ON(1);
+		}
+
+		if (cp_count == 0) {
+			snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLK_OTHR_CTL,
+							0x01, 0x00);
+			dev_dbg(codec->dev, "%s: Charge pump disabled, count = %d\n",
+					__func__, cp_count);
+		}
+	}
+}
+
+static inline void wcd9xxx_clsh_computation_request(
+	struct snd_soc_codec *codec, int compute_pa, bool on)
+{
+	u8 reg_val, reg_mask;
+
+	switch (compute_pa) {
+	case CLSH_COMPUTE_EAR:
+		reg_mask = 0x10;
+		reg_val = (on ? 0x10 : 0x00);
+		break;
+	case CLSH_COMPUTE_HPH_L:
+		reg_mask = 0x08;
+		reg_val = (on ? 0x08 : 0x00);
+		break;
+	case CLSH_COMPUTE_HPH_R:
+		reg_mask = 0x04;
+		reg_val = (on ? 0x04 : 0x00);
+		break;
+	default:
+		dev_dbg(codec->dev, "%s: class h computation PA request incorrect\n",
+			   __func__);
+		return;
+	}
+
+	snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLSH_B1_CTL,
+						reg_mask, reg_val);
+
+}
+
+static void wcd9xxx_enable_buck_mode(struct snd_soc_codec *codec,
+		u8 buck_vref)
+{
+	int i;
+	const struct wcd9xxx_reg_mask_val reg_set[] = {
+		{WCD9XXX_A_BUCK_MODE_5, 0x02, 0x03},
+		{WCD9XXX_A_BUCK_MODE_4, 0xFF, buck_vref},
+		{WCD9XXX_A_BUCK_MODE_1, 0x04, 0x04},
+		{WCD9XXX_A_BUCK_MODE_1, 0x08, 0x00},
+		{WCD9XXX_A_BUCK_MODE_3, 0x04, 0x00},
+		{WCD9XXX_A_BUCK_MODE_3, 0x08, 0x00},
+		{WCD9XXX_A_BUCK_MODE_1, 0x80, 0x80},
+	};
+
+	for (i = 0; i < ARRAY_SIZE(reg_set); i++)
+		snd_soc_update_bits(codec, reg_set[i].reg,
+					reg_set[i].mask, reg_set[i].val);
+
+	dev_dbg(codec->dev, "%s: Done\n", __func__);
+	usleep_range(BUCK_SETTLE_TIME_US, BUCK_SETTLE_TIME_US);
+}
+
+static void wcd9xxx_clsh_enable_post_pa(struct snd_soc_codec *codec)
+{
+	int i;
+	const struct wcd9xxx_reg_mask_val reg_set[] = {
+		{WCD9XXX_A_BUCK_MODE_5, 0x02, 0x00},
+		{WCD9XXX_A_NCP_STATIC, 0x20, 0x00},
+		{WCD9XXX_A_BUCK_MODE_3, 0x04, 0x04},
+		{WCD9XXX_A_BUCK_MODE_3, 0x08, 0x08},
+	};
+
+	for (i = 0; i < ARRAY_SIZE(reg_set); i++)
+		snd_soc_update_bits(codec, reg_set[i].reg,
+					reg_set[i].mask, reg_set[i].val);
+
+	dev_dbg(codec->dev, "%s: completed clsh mode settings after PA enable\n",
+		   __func__);
+
+}
+
+static void wcd9xxx_set_fclk_enable_ncp(struct snd_soc_codec *codec,
+		u8 fclk_level)
+{
+	int i;
+	const struct wcd9xxx_reg_mask_val reg_set[] = {
+		{WCD9XXX_A_NCP_STATIC, 0x20, 0x20},
+		{WCD9XXX_A_NCP_EN, 0x01, 0x01},
+	};
+	snd_soc_update_bits(codec, WCD9XXX_A_NCP_STATIC,
+						0x010, 0x00);
+	snd_soc_update_bits(codec, WCD9XXX_A_NCP_STATIC,
+						0x0F, fclk_level);
+	for (i = 0; i < ARRAY_SIZE(reg_set); i++)
+		snd_soc_update_bits(codec, reg_set[i].reg,
+					reg_set[i].mask, reg_set[i].val);
+
+	usleep_range(NCP_SETTLE_TIME_US, NCP_SETTLE_TIME_US);
+
+	dev_dbg(codec->dev, "%s: set ncp done\n", __func__);
+}
+
+static void wcd9xxx_cfg_clsh_param_ear(struct snd_soc_codec *codec)
+{
+	int i;
+	const struct wcd9xxx_reg_mask_val reg_set[] = {
+		{WCD9XXX_A_CDC_CLSH_B1_CTL, (0x1 << 7), 0},
+		{WCD9XXX_A_CDC_CLSH_V_PA_HD_EAR, (0x3f << 0), 0x0D},
+		{WCD9XXX_A_CDC_CLSH_V_PA_MIN_EAR, (0x3f << 0), 0x3A},
+
+		/* Under assumption that EAR load is 10.7ohm */
+		{WCD9XXX_A_CDC_CLSH_IDLE_EAR_THSD, (0x3f << 0), 0x26},
+		{WCD9XXX_A_CDC_CLSH_FCLKONLY_EAR_THSD, (0x3f << 0), 0x2C},
+		{WCD9XXX_A_CDC_CLSH_I_PA_FACT_EAR_L, 0xff, 0xA9},
+		{WCD9XXX_A_CDC_CLSH_I_PA_FACT_EAR_U, 0xff, 0x07},
+		{WCD9XXX_A_CDC_CLSH_K_ADDR, (0x1 << 7), 0},
+		{WCD9XXX_A_CDC_CLSH_K_ADDR, (0xf << 0), 0x08},
+		{WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x1b},
+		{WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+		{WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x2d},
+		{WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+		{WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x36},
+		{WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+		{WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x37},
+		{WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+	};
+
+	for (i = 0; i < ARRAY_SIZE(reg_set); i++)
+		snd_soc_update_bits(codec, reg_set[i].reg,
+					reg_set[i].mask, reg_set[i].val);
+
+	dev_dbg(codec->dev, "%s: Programmed Class H controller EAR specific params\n",
+			 __func__);
+}
+
+static void wcd9xxx_cfg_clsh_param_hph(struct snd_soc_codec *codec)
+{
+	int i;
+	const struct wcd9xxx_reg_mask_val reg_set[] = {
+		{WCD9XXX_A_CDC_CLSH_B1_CTL, (0x1 << 6), 0},
+		{WCD9XXX_A_CDC_CLSH_V_PA_HD_HPH, 0x3f, 0x0D},
+		{WCD9XXX_A_CDC_CLSH_V_PA_MIN_HPH, 0x3f, 0x1D},
+
+		/* Under assumption that HPH load is 16ohm per channel */
+		{WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD, 0x3f, 0x13},
+		{WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0x1f, 0x19},
+		{WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L, 0xff, 0x97},
+		{WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U, 0xff, 0x05},
+		{WCD9XXX_A_CDC_CLSH_K_ADDR, (0x1 << 7), 0},
+		{WCD9XXX_A_CDC_CLSH_K_ADDR, 0x0f, 0},
+		{WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0xAE},
+		{WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+		{WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x1C},
+		{WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+		{WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x24},
+		{WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+		{WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x25},
+		{WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+	};
+
+	for (i = 0; i < ARRAY_SIZE(reg_set); i++)
+		snd_soc_update_bits(codec, reg_set[i].reg, reg_set[i].mask,
+							reg_set[i].val);
+	dev_dbg(codec->dev, "%s: Programmed Class H controller HPH specific params\n",
+			 __func__);
+}
+
+static void wcd9xxx_clsh_turnoff_postpa
+	(struct snd_soc_codec *codec)
+{
+
+	int i;
+
+	const struct wcd9xxx_reg_mask_val reg_set[] = {
+		{WCD9XXX_A_NCP_EN, 0x01, 0x00},
+		{WCD9XXX_A_BUCK_MODE_1, 0x80, 0x00},
+		{WCD9XXX_A_CDC_CLSH_B1_CTL, 0x10, 0x00},
+	};
+
+	wcd9xxx_chargepump_request(codec, false);
+
+	for (i = 0; i < ARRAY_SIZE(reg_set); i++)
+		snd_soc_update_bits(codec, reg_set[i].reg,
+				reg_set[i].mask, reg_set[i].val);
+
+	wcd9xxx_enable_clsh_block(codec, false);
+
+	dev_dbg(codec->dev, "%s: Done\n", __func__);
+}
+
+static void wcd9xxx_clsh_state_idle(struct snd_soc_codec *codec,
+			struct wcd9xxx_clsh_cdc_data *clsh_d,
+			u8 req_state, bool is_enable)
+{
+	if (is_enable) {
+		dev_dbg(codec->dev, "%s: wrong transition, cannot enable IDLE state\n",
+			   __func__);
+	} else {
+		if (req_state == WCD9XXX_CLSH_STATE_EAR) {
+			wcd9xxx_clsh_turnoff_postpa(codec);
+		} else if (req_state == WCD9XXX_CLSH_STATE_HPHL) {
+			wcd9xxx_clsh_computation_request(codec,
+				CLSH_COMPUTE_HPH_L, false);
+			wcd9xxx_clsh_turnoff_postpa(codec);
+		} else if (req_state == WCD9XXX_CLSH_STATE_HPHR) {
+			wcd9xxx_clsh_computation_request(codec,
+				CLSH_COMPUTE_HPH_R, false);
+			wcd9xxx_clsh_turnoff_postpa(codec);
+		} else if (req_state == WCD9XXX_CLSH_STATE_LO) {
+			wcd9xxx_enable_ncp(codec, false);
+			wcd9xxx_enable_buck(codec, false);
+		}
+	}
+}
+
+static void wcd9xxx_clsh_state_ear(struct snd_soc_codec *codec,
+			struct wcd9xxx_clsh_cdc_data *clsh_d,
+			u8 req_state, bool is_enable)
+{
+	if (is_enable) {
+		wcd9xxx_cfg_clsh_buck(codec);
+		wcd9xxx_cfg_clsh_param_common(codec);
+		wcd9xxx_cfg_clsh_param_ear(codec);
+		wcd9xxx_enable_clsh_block(codec, true);
+		wcd9xxx_chargepump_request(codec, true);
+		wcd9xxx_enable_anc_delay(codec, true);
+		wcd9xxx_clsh_computation_request(codec,
+				CLSH_COMPUTE_EAR, true);
+		wcd9xxx_enable_buck_mode(codec, BUCK_VREF_2V);
+		wcd9xxx_set_fclk_enable_ncp(codec, NCP_FCLK_LEVEL_8);
+
+		dev_dbg(codec->dev, "%s: Enabled ear mode class h\n", __func__);
+	} else {
+		dev_dbg(codec->dev, "%s: stub fallback to ear\n", __func__);
+	}
+}
+
+static void wcd9xxx_clsh_state_hph_l(struct snd_soc_codec *codec,
+		struct wcd9xxx_clsh_cdc_data *clsh_d,
+		u8 req_state, bool is_enable)
+{
+	if (is_enable) {
+		wcd9xxx_cfg_clsh_buck(codec);
+		wcd9xxx_cfg_clsh_param_common(codec);
+		wcd9xxx_cfg_clsh_param_hph(codec);
+		wcd9xxx_enable_clsh_block(codec, true);
+		wcd9xxx_chargepump_request(codec, true);
+		wcd9xxx_enable_anc_delay(codec, true);
+		wcd9xxx_clsh_computation_request(codec,
+				CLSH_COMPUTE_HPH_L, true);
+		wcd9xxx_enable_buck_mode(codec, BUCK_VREF_2V);
+		wcd9xxx_set_fclk_enable_ncp(codec, NCP_FCLK_LEVEL_8);
+
+		dev_dbg(codec->dev, "%s: Done\n", __func__);
+	} else {
+		if (req_state == WCD9XXX_CLSH_STATE_HPHR) {
+			wcd9xxx_clsh_computation_request(codec,
+				CLSH_COMPUTE_HPH_R, false);
+		} else {
+			dev_dbg(codec->dev, "%s: stub fallback to hph_l\n",
+					__func__);
+		}
+	}
+}
+
+static void wcd9xxx_clsh_state_hph_r(struct snd_soc_codec *codec,
+		struct wcd9xxx_clsh_cdc_data *clsh_d,
+		u8 req_state, bool is_enable)
+{
+	if (is_enable) {
+
+		wcd9xxx_cfg_clsh_buck(codec);
+		wcd9xxx_cfg_clsh_param_common(codec);
+		wcd9xxx_cfg_clsh_param_hph(codec);
+		wcd9xxx_enable_clsh_block(codec, true);
+		wcd9xxx_chargepump_request(codec, true);
+		wcd9xxx_enable_anc_delay(codec, true);
+		wcd9xxx_clsh_computation_request(codec,
+				CLSH_COMPUTE_HPH_R, true);
+		wcd9xxx_enable_buck_mode(codec, BUCK_VREF_2V);
+		wcd9xxx_set_fclk_enable_ncp(codec, NCP_FCLK_LEVEL_8);
+
+		dev_dbg(codec->dev, "%s: Done\n", __func__);
+	} else {
+		if (req_state == WCD9XXX_CLSH_STATE_HPHL) {
+			wcd9xxx_clsh_computation_request(codec,
+				CLSH_COMPUTE_HPH_L, false);
+		} else {
+			dev_dbg(codec->dev, "%s: stub fallback to hph_r\n",
+					__func__);
+		}
+	}
+}
+
+static void wcd9xxx_clsh_state_hph_st(struct snd_soc_codec *codec,
+		struct wcd9xxx_clsh_cdc_data *clsh_d,
+		u8 req_state, bool is_enable)
+{
+	if (is_enable) {
+		wcd9xxx_clsh_computation_request(codec,
+				CLSH_COMPUTE_HPH_L, true);
+		wcd9xxx_clsh_computation_request(codec,
+				CLSH_COMPUTE_HPH_R, true);
+	} else {
+		dev_dbg(codec->dev, "%s: stub fallback to hph_st\n", __func__);
+	}
+}
+
+static void wcd9xxx_clsh_state_lo(struct snd_soc_codec *codec,
+		struct wcd9xxx_clsh_cdc_data *clsh_d,
+		u8 req_state, bool is_enable)
+{
+	if (is_enable) {
+		if (++cdc_lo_count > 1)
+			return;
+
+		wcd9xxx_enable_buck_mode(codec, BUCK_VREF_1P8V);
+		wcd9xxx_set_fclk_enable_ncp(codec, NCP_FCLK_LEVEL_5);
+
+		if (clsh_d->buck_mv == WCD9XXX_CDC_BUCK_MV_1P8) {
+			wcd9xxx_enable_buck(codec, false);
+			snd_soc_update_bits(codec, WCD9XXX_A_NCP_STATIC,
+							0x20, 0x01);
+			wcd9xxx_enable_ncp(codec, true);
+			msleep(NCP_SETTLE_TIME_US);
+
+		} else {
+			snd_soc_update_bits(codec, WCD9XXX_A_NCP_EN,
+							0x40, 0x00);
+			wcd9xxx_enable_ncp(codec, true);
+			msleep(NCP_SETTLE_TIME_US);
+			snd_soc_update_bits(codec, WCD9XXX_A_BUCK_MODE_5,
+							0x01, 0x01);
+			snd_soc_update_bits(codec, WCD9XXX_A_BUCK_MODE_5,
+							0xFB, (0x02 << 2));
+		}
+		snd_soc_update_bits(codec, WCD9XXX_A_BUCK_MODE_1,
+							0x04, 0x00);
+	} else {
+		dev_dbg(codec->dev, "%s: stub fallback to lineout\n", __func__);
+	}
+}
+
+static void wcd9xxx_clsh_state_err(struct snd_soc_codec *codec,
+		struct wcd9xxx_clsh_cdc_data *clsh_d,
+		u8 req_state, bool is_enable)
+{
+	dev_dbg(codec->dev, "%s Wrong request for class H state machine requested to %s %s"
+			, __func__, is_enable ? "enable" : "disable",
+			state_to_str(req_state));
+	WARN_ON(1);
+}
+
+void wcd9xxx_clsh_fsm(struct snd_soc_codec *codec,
+		struct wcd9xxx_clsh_cdc_data *cdc_clsh_d,
+		u8 req_state, bool req_type, u8 clsh_event)
+{
+	u8 old_state, new_state;
+
+	switch (clsh_event) {
+
+	case WCD9XXX_CLSH_EVENT_PRE_DAC:
+
+		/* PRE_DAC event should be used only for Enable */
+		BUG_ON(req_type != WCD9XXX_CLSH_REQ_ENABLE);
+
+		old_state = cdc_clsh_d->state;
+		new_state = old_state | req_state;
+
+		(*clsh_state_fp[new_state]) (codec, cdc_clsh_d,
+							req_state, req_type);
+		cdc_clsh_d->state = new_state;
+		dev_info(codec->dev, "%s: ClassH state transition from %s to %s\n",
+			__func__, state_to_str(old_state),
+			state_to_str(cdc_clsh_d->state));
+
+		break;
+
+	case WCD9XXX_CLSH_EVENT_POST_PA:
+
+		if (req_type == WCD9XXX_CLSH_REQ_DISABLE) {
+			if (req_state == WCD9XXX_CLSH_STATE_LO
+					&& --cdc_lo_count > 0)
+				break;
+
+			old_state = cdc_clsh_d->state;
+			new_state = old_state & (~req_state);
+
+			if (new_state < NUM_CLSH_STATES) {
+				(*clsh_state_fp[new_state]) (codec, cdc_clsh_d,
+							req_state, req_type);
+				cdc_clsh_d->state = new_state;
+				dev_info(codec->dev, "%s: ClassH state transition from %s to %s\n",
+					__func__, state_to_str(old_state),
+					state_to_str(cdc_clsh_d->state));
+
+			} else {
+				dev_dbg(codec->dev, "%s: wrong new state = %x\n",
+						__func__, new_state);
+			}
+
+
+		} else if (req_state != WCD9XXX_CLSH_STATE_LO) {
+			wcd9xxx_clsh_enable_post_pa(codec);
+		}
+
+		break;
+	}
+
+}
+EXPORT_SYMBOL_GPL(wcd9xxx_clsh_fsm);
+
+void wcd9xxx_clsh_init(struct wcd9xxx_clsh_cdc_data *clsh)
+{
+	int i;
+	clsh->state = WCD9XXX_CLSH_STATE_IDLE;
+
+	for (i = 0; i < NUM_CLSH_STATES; i++)
+		clsh_state_fp[i] = wcd9xxx_clsh_state_err;
+
+	clsh_state_fp[WCD9XXX_CLSH_STATE_IDLE] = wcd9xxx_clsh_state_idle;
+	clsh_state_fp[WCD9XXX_CLSH_STATE_EAR] = wcd9xxx_clsh_state_ear;
+	clsh_state_fp[WCD9XXX_CLSH_STATE_HPHL] =
+						wcd9xxx_clsh_state_hph_l;
+	clsh_state_fp[WCD9XXX_CLSH_STATE_HPHR] =
+						wcd9xxx_clsh_state_hph_r;
+	clsh_state_fp[WCD9XXX_CLSH_STATE_HPH_ST] =
+						wcd9xxx_clsh_state_hph_st;
+	clsh_state_fp[WCD9XXX_CLSH_STATE_LO] = wcd9xxx_clsh_state_lo;
+
+}
+EXPORT_SYMBOL_GPL(wcd9xxx_clsh_init);
+
+MODULE_DESCRIPTION("WCD9XXX Common");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/wcd9xxx-common.h b/sound/soc/codecs/wcd9xxx-common.h
new file mode 100644
index 0000000..743ab0c
--- /dev/null
+++ b/sound/soc/codecs/wcd9xxx-common.h
@@ -0,0 +1,68 @@
+/* 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 WCD9XXX_CODEC_COMMON
+
+#define WCD9XXX_CODEC_COMMON
+
+#define WCD9XXX_CLSH_REQ_ENABLE true
+#define WCD9XXX_CLSH_REQ_DISABLE false
+
+#define WCD9XXX_CLSH_EVENT_PRE_DAC 0x01
+#define WCD9XXX_CLSH_EVENT_POST_PA 0x02
+
+/* Basic states for Class H state machine.
+ * represented as a bit mask within a u8 data type
+ * bit 0: EAR mode
+ * bit 1: HPH Left mode
+ * bit 2: HPH Right mode
+ * bit 3: Lineout mode
+ * bit 4: Ultrasound mode
+ */
+#define	WCD9XXX_CLSH_STATE_IDLE 0x00
+#define	WCD9XXX_CLSH_STATE_EAR (0x01 << 0)
+#define	WCD9XXX_CLSH_STATE_HPHL (0x01 << 1)
+#define	WCD9XXX_CLSH_STATE_HPHR (0x01 << 2)
+#define	WCD9XXX_CLSH_STATE_LO (0x01 << 3)
+#define NUM_CLSH_STATES ((0x01 << 4) - 1)
+
+/* Derived State: Bits 1 and 2 should be set for Headphone stereo */
+#define WCD9XXX_CLSH_STATE_HPH_ST (WCD9XXX_CLSH_STATE_HPHL | \
+						WCD9XXX_CLSH_STATE_HPHR)
+
+
+struct wcd9xxx_reg_mask_val {
+	u16	reg;
+	u8	mask;
+	u8	val;
+};
+
+/* Class H data that the codec driver will maintain */
+struct wcd9xxx_clsh_cdc_data {
+	u8 state;
+	int buck_mv;
+};
+
+
+enum wcd9xxx_buck_volt {
+	WCD9XXX_CDC_BUCK_UNSUPPORTED = 0,
+	WCD9XXX_CDC_BUCK_MV_1P8 = 1800000,
+	WCD9XXX_CDC_BUCK_MV_2P15 = 2150000,
+};
+
+extern void wcd9xxx_clsh_fsm(struct snd_soc_codec *codec,
+		struct wcd9xxx_clsh_cdc_data *cdc_clsh_d,
+		u8 req_state, bool req_type, u8 clsh_event);
+
+extern void wcd9xxx_clsh_init(struct wcd9xxx_clsh_cdc_data *clsh);
+
+#endif
diff --git a/sound/soc/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c
index 0f2a19c..b3549cc 100644
--- a/sound/soc/codecs/wcd9xxx-mbhc.c
+++ b/sound/soc/codecs/wcd9xxx-mbhc.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
@@ -46,6 +46,7 @@
 				  SND_JACK_BTN_6 | SND_JACK_BTN_7)
 
 #define NUM_DCE_PLUG_DETECT 3
+#define NUM_DCE_PLUG_INS_DETECT 4
 #define NUM_ATTEMPTS_INSERT_DETECT 25
 #define NUM_ATTEMPTS_TO_REPORT 5
 
@@ -81,6 +82,30 @@
 
 #define VDDIO_MICBIAS_MV 1800
 
+#define WCD9XXX_HPHL_STATUS_READY_WAIT_US 1000
+#define WCD9XXX_MUX_SWITCH_READY_WAIT_US 100
+#define WCD9XXX_MEAS_DELTA_MAX_MV 50
+#define WCD9XXX_GM_SWAP_THRES_MIN_MV 150
+#define WCD9XXX_GM_SWAP_THRES_MAX_MV 500
+
+#define WCD9XXX_USLEEP_RANGE_MARGIN_US 1000
+
+static bool detect_use_vddio_switch;
+
+struct wcd9xxx_mbhc_detect {
+	u16 dce;
+	u16 sta;
+	u16 hphl_status;
+	bool swap_gnd;
+	bool vddio;
+	bool hwvalue;
+	/* internal purpose from here */
+	bool _above_no_mic;
+	bool _below_v_hs_max;
+	s16 _vdces;
+	enum wcd9xxx_mbhc_plug_type _type;
+};
+
 enum meas_type {
 	STA = 0,
 	DCE,
@@ -349,8 +374,14 @@
 	}
 }
 
-static void wcd9xxx_jack_report(struct snd_soc_jack *jack, int status, int mask)
+static void wcd9xxx_jack_report(struct wcd9xxx_mbhc *mbhc,
+				struct snd_soc_jack *jack, int status, int mask)
 {
+	if (jack == &mbhc->headset_jack)
+		wcd9xxx_resmgr_cond_update_cond(mbhc->resmgr,
+						WCD9XXX_COND_HPH_MIC,
+						status & SND_JACK_MICROPHONE);
+
 	snd_soc_jack_report_no_dapm(jack, status, mask);
 }
 
@@ -363,7 +394,7 @@
 	codec = mbhc->codec;
 	if (mbhc->hph_status & jack_status) {
 		mbhc->hph_status &= ~jack_status;
-		wcd9xxx_jack_report(&mbhc->headset_jack,
+		wcd9xxx_jack_report(mbhc, &mbhc->headset_jack,
 				    mbhc->hph_status, WCD9XXX_JACK_MASK);
 		snd_soc_update_bits(codec, WCD9XXX_A_RX_HPH_OCP_CTL, 0x10,
 				    0x00);
@@ -554,7 +585,7 @@
 		set_bit(WCD9XXX_HPHR_DAC_OFF_ACK, &mbhc->hph_pa_dac_state);
 
 	snd_soc_update_bits(codec, WCD9XXX_A_RX_HPH_CNP_EN, 0x30, 0x00);
-	snd_soc_update_bits(codec, WCD9XXX_A_RX_HPH_L_DAC_CTL, 0xC0, 0x00);
+	snd_soc_update_bits(codec, WCD9XXX_A_RX_HPH_L_DAC_CTL, 0x80, 0x00);
 	snd_soc_update_bits(codec, WCD9XXX_A_RX_HPH_R_DAC_CTL, 0xC0, 0x00);
 	usleep_range(wg_time * 1000, wg_time * 1000);
 }
@@ -593,14 +624,14 @@
 		else if (mbhc->buttons_pressed) {
 			pr_debug("%s: release of button press%d\n",
 				 __func__, jack_type);
-			wcd9xxx_jack_report(&mbhc->button_jack, 0,
+			wcd9xxx_jack_report(mbhc, &mbhc->button_jack, 0,
 					    mbhc->buttons_pressed);
 			mbhc->buttons_pressed &=
 				~WCD9XXX_JACK_BUTTON_MASK;
 		}
 		pr_debug("%s: Reporting removal %d(%x)\n", __func__,
 			 jack_type, mbhc->hph_status);
-		wcd9xxx_jack_report(&mbhc->headset_jack, mbhc->hph_status,
+		wcd9xxx_jack_report(mbhc, &mbhc->headset_jack, mbhc->hph_status,
 				    WCD9XXX_JACK_MASK);
 		wcd9xxx_set_and_turnoff_hph_padac(mbhc);
 		hphrocp_off_report(mbhc, SND_JACK_OC_HPHR);
@@ -610,10 +641,10 @@
 	} else {
 		if (mbhc->mbhc_cfg->detect_extn_cable) {
 			/* Report removal of current jack type */
-			if (mbhc->hph_status != jack_type) {
+			if (mbhc->hph_status && mbhc->hph_status != jack_type) {
 				pr_debug("%s: Reporting removal (%x)\n",
 					 __func__, mbhc->hph_status);
-				wcd9xxx_jack_report(&mbhc->headset_jack,
+				wcd9xxx_jack_report(mbhc, &mbhc->headset_jack,
 						    0, WCD9XXX_JACK_MASK);
 				mbhc->hph_status = 0;
 			}
@@ -633,7 +664,7 @@
 		}
 		pr_debug("%s: Reporting insertion %d(%x)\n", __func__,
 			 jack_type, mbhc->hph_status);
-		wcd9xxx_jack_report(&mbhc->headset_jack,
+		wcd9xxx_jack_report(mbhc, &mbhc->headset_jack,
 				    mbhc->hph_status, WCD9XXX_JACK_MASK);
 		wcd9xxx_clr_and_turnon_hph_padac(mbhc);
 	}
@@ -685,26 +716,6 @@
 	return v_hs_max;
 }
 
-static bool wcd9xxx_is_inval_ins_range(struct wcd9xxx_mbhc *mbhc,
-				     s32 mic_volt, bool highhph, bool *highv)
-{
-	s16 v_hs_max;
-	bool invalid = false;
-
-	/* Perform this check only when the high voltage headphone
-	 * needs to be considered as invalid
-	 */
-	v_hs_max = wcd9xxx_get_current_v_hs_max(mbhc);
-	*highv = mic_volt > v_hs_max;
-	if (!highhph && *highv)
-		invalid = true;
-	else if (mic_volt < mbhc->mbhc_data.v_inval_ins_high &&
-		 (mic_volt > mbhc->mbhc_data.v_inval_ins_low))
-		invalid = true;
-
-	return invalid;
-}
-
 static short wcd9xxx_read_sta_result(struct snd_soc_codec *codec)
 {
 	u8 bias_msb, bias_lsb;
@@ -923,13 +934,6 @@
 		usleep_range(5000, 5000);
 }
 
-static bool wcd9xxx_is_inval_ins_delta(struct snd_soc_codec *codec,
-				       int mic_volt, int mic_volt_prev,
-				       int threshold)
-{
-	return abs(mic_volt - mic_volt_prev) > threshold;
-}
-
 static void wcd9xxx_onoff_vddio_switch(struct wcd9xxx_mbhc *mbhc, bool on)
 {
 	if (on) {
@@ -947,23 +951,117 @@
 		usleep_range(10000, 10000);
 }
 
-/* called under codec_resource_lock acquisition and mbhc override = 1 */
+static int wcd9xxx_hphl_status(struct wcd9xxx_mbhc *mbhc)
+{
+	u16 hph, status;
+	struct snd_soc_codec *codec = mbhc->codec;
+
+	WCD9XXX_BCL_ASSERT_LOCKED(mbhc->resmgr);
+	hph = snd_soc_read(codec, WCD9XXX_A_MBHC_HPH);
+	snd_soc_update_bits(codec, WCD9XXX_A_MBHC_HPH, 0x12, 0x02);
+	usleep_range(WCD9XXX_HPHL_STATUS_READY_WAIT_US,
+		     WCD9XXX_HPHL_STATUS_READY_WAIT_US +
+		     WCD9XXX_USLEEP_RANGE_MARGIN_US);
+	status = snd_soc_read(codec, WCD9XXX_A_RX_HPH_L_STATUS);
+	snd_soc_write(codec, WCD9XXX_A_MBHC_HPH, hph);
+	return status;
+}
+
+/*
+ * wcd9xxx_find_plug_type : Find out and return the best plug type with given
+ *			    list of wcd9xxx_mbhc_detect structure.
+ */
+static enum wcd9xxx_mbhc_plug_type
+wcd9xxx_find_plug_type(struct wcd9xxx_mbhc *mbhc,
+		       struct wcd9xxx_mbhc_detect *dt, const int size)
+{
+	int i;
+	int ch;
+	enum wcd9xxx_mbhc_plug_type type;
+	int vdce;
+	struct wcd9xxx_mbhc_detect *d, *dprev, *dgnd = NULL;
+	int maxv = 0, minv = 0;
+	const struct wcd9xxx_mbhc_plug_type_cfg *plug_type =
+	    WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(mbhc->mbhc_cfg->calibration);
+	const s16 hs_max = plug_type->v_hs_max;
+	const s16 no_mic = plug_type->v_no_mic;
+
+	for (i = 0, d = dt, ch = 0; i < size; i++, d++) {
+		vdce = wcd9xxx_codec_sta_dce_v(mbhc, true, d->dce);
+		if (d->vddio)
+			d->_vdces = scale_v_micb_vddio(mbhc, vdce, false);
+		else
+			d->_vdces = vdce;
+
+		if (d->_vdces >= no_mic && d->_vdces < hs_max)
+			d->_type = PLUG_TYPE_HEADSET;
+		else if (d->_vdces < no_mic)
+			d->_type = PLUG_TYPE_HEADPHONE;
+		else
+			d->_type = PLUG_TYPE_HIGH_HPH;
+
+		ch += d->hphl_status & 0x01;
+		if (!d->swap_gnd && !d->hwvalue) {
+			if (maxv < d->_vdces)
+				maxv = d->_vdces;
+			if (!minv || minv > d->_vdces)
+				minv = d->_vdces;
+		}
+
+		pr_debug("%s: DCE #%d, %04x, V %04d(%04d), GND %d, VDDIO %d, HPHL %d TYPE %d\n",
+			 __func__, i, d->dce, vdce, d->_vdces,
+			 d->swap_gnd, d->vddio, d->hphl_status & 0x01,
+			 d->_type);
+	}
+	if (ch != size && ch > 0) {
+		pr_debug("%s: Invalid, inconsistent HPHL\n", __func__);
+		type = PLUG_TYPE_INVALID;
+		goto exit;
+	}
+
+	for (i = 0, d = dt, ch = 0; i < size; i++, d++) {
+		if ((i > 0) && (d->_type != dprev->_type)) {
+			pr_debug("%s: Invalid, inconsistent types\n", __func__);
+			type = PLUG_TYPE_INVALID;
+			goto exit;
+		}
+
+		if (!d->swap_gnd && !d->hwvalue &&
+		    (abs(minv - d->_vdces) > WCD9XXX_MEAS_DELTA_MAX_MV ||
+		     abs(maxv - d->_vdces) > WCD9XXX_MEAS_DELTA_MAX_MV)) {
+			pr_debug("%s: Invalid, delta %dmv, %dmv and %dmv\n",
+				 __func__, d->_vdces, minv, maxv);
+			type = PLUG_TYPE_INVALID;
+			goto exit;
+		} else if (d->swap_gnd) {
+			dgnd = d;
+		}
+		dprev = d;
+	}
+
+	WARN_ON(i != size);
+	type = dt->_type;
+	if (type == PLUG_TYPE_HEADSET && dgnd) {
+		if ((dgnd->_vdces + WCD9XXX_GM_SWAP_THRES_MIN_MV <
+		     minv) &&
+		    (dgnd->_vdces + WCD9XXX_GM_SWAP_THRES_MAX_MV >
+		     maxv))
+			type = PLUG_TYPE_GND_MIC_SWAP;
+	}
+
+exit:
+	pr_debug("%s: Plug type %d detected\n", __func__, type);
+	return type;
+}
+
 static enum wcd9xxx_mbhc_plug_type
 wcd9xxx_codec_get_plug_type(struct wcd9xxx_mbhc *mbhc, bool highhph)
 {
 	int i;
-	bool gndswitch, vddioswitch;
-	int scaled;
 	struct wcd9xxx_mbhc_plug_type_cfg *plug_type_ptr;
+	struct wcd9xxx_mbhc_detect rt[NUM_DCE_PLUG_INS_DETECT];
+	enum wcd9xxx_mbhc_plug_type type = PLUG_TYPE_INVALID;
 	struct snd_soc_codec *codec = mbhc->codec;
-	const bool vddio = (mbhc->mbhc_data.micb_mv != VDDIO_MICBIAS_MV);
-	int num_det = (NUM_DCE_PLUG_DETECT + vddio);
-	enum wcd9xxx_mbhc_plug_type plug_type[num_det];
-	s16 mb_v[num_det];
-	s32 mic_mv[num_det];
-	bool inval;
-	bool highdelta;
-	bool ahighv = false, highv;
 
 	pr_debug("%s: enter\n", __func__);
 	WCD9XXX_BCL_ASSERT_LOCKED(mbhc->resmgr);
@@ -972,106 +1070,39 @@
 	WARN_ON(!(snd_soc_read(codec, WCD9XXX_A_CDC_MBHC_B1_CTL) & 0x04));
 
 	/* GND and MIC swap detection requires at least 2 rounds of DCE */
-	BUG_ON(num_det < 2);
+	BUG_ON(NUM_DCE_PLUG_INS_DETECT < 2);
 
 	plug_type_ptr =
-		WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(mbhc->mbhc_cfg->calibration);
+	    WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(mbhc->mbhc_cfg->calibration);
 
-	plug_type[0] = PLUG_TYPE_INVALID;
-
-	/* performs DCEs for N times
-	 * 1st: check if voltage is in invalid range
-	 * 2nd - N-2nd: check voltage range and delta
-	 * N-1st: check voltage range, delta with HPHR GND switch
-	 * Nth: check voltage range with VDDIO switch if micbias V != vddio V*/
-	for (i = 0; i < num_det; i++) {
-		gndswitch = (i == (num_det - 1 - vddio));
-		vddioswitch = (vddio && ((i == num_det - 1) ||
-					(i == num_det - 2)));
-		if (i == 0) {
-			mb_v[i] = wcd9xxx_mbhc_setup_hs_polling(mbhc);
-			mic_mv[i] = wcd9xxx_codec_sta_dce_v(mbhc, 1 , mb_v[i]);
-			inval = wcd9xxx_is_inval_ins_range(mbhc, mic_mv[i],
-					highhph, &highv);
-			ahighv |= highv;
-			scaled = mic_mv[i];
-		} else {
-			if (vddioswitch)
-				wcd9xxx_onoff_vddio_switch(mbhc, true);
-			if (gndswitch)
-				wcd9xxx_codec_hphr_gnd_switch(codec, true);
-			mb_v[i] = __wcd9xxx_codec_sta_dce(mbhc, 1, true, true);
-			mic_mv[i] = wcd9xxx_codec_sta_dce_v(mbhc, 1 , mb_v[i]);
-			if (vddioswitch)
-				scaled = scale_v_micb_vddio(mbhc, mic_mv[i],
-							    false);
-			else
-				scaled = mic_mv[i];
-			/* !gndswitch & vddioswitch means the previous DCE
-			 * was done with gndswitch, don't compare with DCE
-			 * with gndswitch */
-			highdelta = wcd9xxx_is_inval_ins_delta(codec, scaled,
-					mic_mv[i - !gndswitch - vddioswitch],
-					FAKE_INS_DELTA_SCALED_MV);
-			inval = (wcd9xxx_is_inval_ins_range(mbhc, mic_mv[i],
-						highhph, &highv) ||
-					highdelta);
-			ahighv |= highv;
-			if (gndswitch)
-				wcd9xxx_codec_hphr_gnd_switch(codec, false);
-			if (vddioswitch)
-				wcd9xxx_onoff_vddio_switch(mbhc, false);
-			/* claim UNSUPPORTED plug insertion when
-			 * good headset is detected but HPHR GND switch makes
-			 * delta difference */
-			if (i == (num_det - 2) && highdelta && !ahighv)
-				plug_type[0] = PLUG_TYPE_GND_MIC_SWAP;
-			else if (i == (num_det - 1) && inval)
-				plug_type[0] = PLUG_TYPE_INVALID;
-		}
-		pr_debug("%s: DCE #%d, %04x, V %d, scaled V %d, GND %d, VDDIO %d, inval %d\n",
-			 __func__, i + 1, mb_v[i] & 0xffff, mic_mv[i], scaled,
-			 gndswitch, vddioswitch, inval);
-		/* don't need to run further DCEs */
-		if (ahighv && inval)
-			break;
-		mic_mv[i] = scaled;
+	rt[0].hphl_status = wcd9xxx_hphl_status(mbhc);
+	rt[0].dce = wcd9xxx_mbhc_setup_hs_polling(mbhc);
+	rt[0].swap_gnd = false;
+	rt[0].vddio = false;
+	rt[0].hwvalue = true;
+	for (i = 1; i < NUM_DCE_PLUG_INS_DETECT; i++) {
+		rt[i].swap_gnd = (i == NUM_DCE_PLUG_INS_DETECT - 2);
+		if (detect_use_vddio_switch)
+			rt[i].vddio = (i == NUM_DCE_PLUG_INS_DETECT - 1);
+		else
+			rt[i].vddio = false;
+		rt[i].hphl_status = wcd9xxx_hphl_status(mbhc);
+		rt[i].hwvalue = false;
+		if (rt[i].swap_gnd)
+			wcd9xxx_codec_hphr_gnd_switch(codec, true);
+		if (rt[i].vddio)
+			wcd9xxx_onoff_vddio_switch(mbhc, true);
+		rt[i].dce = __wcd9xxx_codec_sta_dce(mbhc, 1, true, true);
+		if (rt[i].vddio)
+			wcd9xxx_onoff_vddio_switch(mbhc, false);
+		if (rt[i].swap_gnd)
+			wcd9xxx_codec_hphr_gnd_switch(codec, false);
 	}
 
-	for (i = 0; (plug_type[0] != PLUG_TYPE_GND_MIC_SWAP && !inval) &&
-		    (i < num_det); i++) {
-		/*
-		 * If we are here, means none of the all
-		 * measurements are fake, continue plug type detection.
-		 * If all three measurements do not produce same
-		 * plug type, restart insertion detection
-		 */
-		if (mic_mv[i] < plug_type_ptr->v_no_mic) {
-			plug_type[i] = PLUG_TYPE_HEADPHONE;
-			pr_debug("%s: Detect attempt %d, detected Headphone\n",
-				 __func__, i);
-		} else if (highhph && (mic_mv[i] > plug_type_ptr->v_hs_max)) {
-			plug_type[i] = PLUG_TYPE_HIGH_HPH;
-			pr_debug("%s: Detect attempt %d, detected High Headphone\n",
-				 __func__, i);
-		} else {
-			plug_type[i] = PLUG_TYPE_HEADSET;
-			pr_debug("%s: Detect attempt %d, detected Headset\n",
-					__func__, i);
-		}
+	type = wcd9xxx_find_plug_type(mbhc, rt, ARRAY_SIZE(rt));
 
-		if (i > 0 && (plug_type[i - 1] != plug_type[i])) {
-			pr_err("%s: Detect attempt %d and %d are not same",
-			       __func__, i - 1, i);
-			plug_type[0] = PLUG_TYPE_INVALID;
-			inval = true;
-			break;
-		}
-	}
-
-	pr_debug("%s: Detected plug type %d\n", __func__, plug_type[0]);
 	pr_debug("%s: leave\n", __func__);
-	return plug_type[0];
+	return type;
 }
 
 static bool wcd9xxx_swch_level_remove(struct wcd9xxx_mbhc *mbhc)
@@ -1581,10 +1612,18 @@
 
 	pr_debug("%s: enter, removal interrupt\n", __func__);
 	WCD9XXX_BCL_LOCK(mbhc->resmgr);
+	/*
+	 * While we don't know whether MIC is there or not, let the resmgr know
+	 * so micbias can be disabled temporarily
+	 */
+	if (mbhc->current_plug == PLUG_TYPE_HEADSET)
+		wcd9xxx_resmgr_cond_update_cond(mbhc->resmgr,
+						WCD9XXX_COND_HPH_MIC, false);
+
 	vddio = (mbhc->mbhc_data.micb_mv != VDDIO_MICBIAS_MV &&
 		 mbhc->mbhc_micbias_switched);
 	if (vddio)
-		wcd9xxx_onoff_vddio_switch(mbhc, true);
+		__wcd9xxx_switch_micbias(mbhc, 0, false, true);
 
 	if (mbhc->mbhc_cfg->detect_extn_cable &&
 	    !wcd9xxx_swch_level_remove(mbhc))
@@ -1597,8 +1636,12 @@
 	 * turn on the vddio switch back, if headset is removed then vddio
 	 * switch is off by time now and shouldn't be turn on again from here
 	 */
-	if (vddio && mbhc->current_plug == PLUG_TYPE_HEADSET)
-		wcd9xxx_onoff_vddio_switch(mbhc, true);
+	if (vddio && (mbhc->current_plug == PLUG_TYPE_HEADSET))
+		__wcd9xxx_switch_micbias(mbhc, 1, true, true);
+
+	if (mbhc->current_plug == PLUG_TYPE_HEADSET)
+		wcd9xxx_resmgr_cond_update_cond(mbhc->resmgr,
+						WCD9XXX_COND_HPH_MIC, true);
 	WCD9XXX_BCL_UNLOCK(mbhc->resmgr);
 
 	return IRQ_HANDLED;
@@ -1654,7 +1697,7 @@
 	pr_debug("%s: STA: %d, DCE: %d\n", __func__, sta_mv, dce_mv);
 
 	pr_debug("%s: Reporting long button press event\n", __func__);
-	wcd9xxx_jack_report(&mbhc->button_jack, mbhc->buttons_pressed,
+	wcd9xxx_jack_report(mbhc, &mbhc->button_jack, mbhc->buttons_pressed,
 			    mbhc->buttons_pressed);
 
 	pr_debug("%s: leave\n", __func__);
@@ -2332,7 +2375,7 @@
 		if (ret == 0) {
 			pr_debug("%s: Reporting long button release event\n",
 				 __func__);
-			wcd9xxx_jack_report(&mbhc->button_jack, 0,
+			wcd9xxx_jack_report(mbhc, &mbhc->button_jack, 0,
 					    mbhc->buttons_pressed);
 		} else {
 			if (wcd9xxx_is_fake_press(mbhc)) {
@@ -2345,12 +2388,14 @@
 				} else {
 					pr_debug("%s: Reporting btn press\n",
 						 __func__);
-					wcd9xxx_jack_report(&mbhc->button_jack,
+					wcd9xxx_jack_report(mbhc,
+							 &mbhc->button_jack,
 							 mbhc->buttons_pressed,
 							 mbhc->buttons_pressed);
 					pr_debug("%s: Reporting btn release\n",
 						 __func__);
-					wcd9xxx_jack_report(&mbhc->button_jack,
+					wcd9xxx_jack_report(mbhc,
+						      &mbhc->button_jack,
 						      0, mbhc->buttons_pressed);
 				}
 			}
@@ -2389,7 +2434,7 @@
 					  WCD9XXX_IRQ_HPH_PA_OCPL_FAULT);
 			mbhc->hphlocp_cnt = 0;
 			mbhc->hph_status |= SND_JACK_OC_HPHL;
-			wcd9xxx_jack_report(&mbhc->headset_jack,
+			wcd9xxx_jack_report(mbhc, &mbhc->headset_jack,
 					    mbhc->hph_status,
 					    WCD9XXX_JACK_MASK);
 		}
@@ -2418,7 +2463,7 @@
 				    WCD9XXX_IRQ_HPH_PA_OCPR_FAULT);
 		mbhc->hphrocp_cnt = 0;
 		mbhc->hph_status |= SND_JACK_OC_HPHR;
-		wcd9xxx_jack_report(&mbhc->headset_jack,
+		wcd9xxx_jack_report(mbhc, &mbhc->headset_jack,
 				    mbhc->hph_status, WCD9XXX_JACK_MASK);
 	}
 
@@ -2491,6 +2536,7 @@
 static void wcd9xxx_mbhc_cal(struct wcd9xxx_mbhc *mbhc)
 {
 	u8 cfilt_mode;
+	u16 reg0, reg1;
 	struct snd_soc_codec *codec = mbhc->codec;
 
 	pr_debug("%s: enter\n", __func__);
@@ -2520,15 +2566,28 @@
 	snd_soc_write(codec, WCD9XXX_A_TX_7_MBHC_TEST_CTL, 0x78);
 	snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL, 0x04, 0x04);
 
-	/* DCE measurement for 0 volts */
+	/* Pull down micbias to ground */
+	reg0 = snd_soc_read(codec, mbhc->mbhc_bias_regs.ctl_reg);
+	snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.ctl_reg, 1, 1);
+	/* Disconnect override from micbias */
+	reg1 = snd_soc_read(codec, WCD9XXX_A_MAD_ANA_CTRL);
+	snd_soc_update_bits(codec, WCD9XXX_A_MAD_ANA_CTRL, 1 << 4, 1 << 0);
+	/* Connect the MUX to micbias */
+	snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x82);
+	usleep_range(WCD9XXX_MUX_SWITCH_READY_WAIT_US,
+		     WCD9XXX_MUX_SWITCH_READY_WAIT_US +
+		     WCD9XXX_USLEEP_RANGE_MARGIN_US);
+	/* DCE measurement for 0 voltage */
 	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x0A);
-	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x04);
 	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x02);
-	snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x81);
-	usleep_range(100, 100);
-	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x04);
-	usleep_range(mbhc->mbhc_data.t_dce, mbhc->mbhc_data.t_dce);
-	mbhc->mbhc_data.dce_z = wcd9xxx_read_dce_result(codec);
+	mbhc->mbhc_data.dce_z = __wcd9xxx_codec_sta_dce(mbhc, 1, true, false);
+	/* STA measurement for 0 voltage */
+	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x0A);
+	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x02);
+	mbhc->mbhc_data.sta_z = __wcd9xxx_codec_sta_dce(mbhc, 0, true, false);
+	/* Restore registers */
+	snd_soc_write(codec, mbhc->mbhc_bias_regs.ctl_reg, reg0);
+	snd_soc_write(codec, WCD9XXX_A_MAD_ANA_CTRL, reg1);
 
 	/* DCE measurment for MB voltage */
 	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x0A);
@@ -2539,17 +2598,10 @@
 	usleep_range(mbhc->mbhc_data.t_dce, mbhc->mbhc_data.t_dce);
 	mbhc->mbhc_data.dce_mb = wcd9xxx_read_dce_result(codec);
 
-	/* STA measuremnt for 0 volts */
+	/* STA Measurement for MB Voltage */
 	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x0A);
 	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x02);
 	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x02);
-	snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x81);
-	usleep_range(100, 100);
-	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x02);
-	usleep_range(mbhc->mbhc_data.t_sta, mbhc->mbhc_data.t_sta);
-	mbhc->mbhc_data.sta_z = wcd9xxx_read_sta_result(codec);
-
-	/* STA Measurement for MB Voltage */
 	snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x82);
 	usleep_range(100, 100);
 	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x02);
@@ -3177,23 +3229,28 @@
 	mbhc->resmgr = resmgr;
 	mbhc->resmgr->mbhc = mbhc;
 
-	ret = snd_soc_jack_new(codec, "Headset Jack", WCD9XXX_JACK_MASK,
-			       &mbhc->headset_jack);
-	if (ret) {
-		pr_err("%s: Failed to create new jack\n", __func__);
-		return ret;
-	}
+	if (mbhc->headset_jack.jack == NULL) {
+		ret = snd_soc_jack_new(codec, "Headset Jack", WCD9XXX_JACK_MASK,
+				       &mbhc->headset_jack);
+		if (ret) {
+			pr_err("%s: Failed to create new jack\n", __func__);
+			return ret;
+		}
 
-	ret = snd_soc_jack_new(codec, "Button Jack", WCD9XXX_JACK_BUTTON_MASK,
-			       &mbhc->button_jack);
-	if (ret) {
-		pr_err("Failed to create new jack\n");
-		return ret;
-	}
+		ret = snd_soc_jack_new(codec, "Button Jack",
+				       WCD9XXX_JACK_BUTTON_MASK,
+				       &mbhc->button_jack);
+		if (ret) {
+			pr_err("Failed to create new jack\n");
+			return ret;
+		}
 
-	INIT_DELAYED_WORK(&mbhc->mbhc_firmware_dwork, wcd9xxx_mbhc_fw_read);
-	INIT_DELAYED_WORK(&mbhc->mbhc_btn_dwork, wcd9xxx_btn_lpress_fn);
-	INIT_DELAYED_WORK(&mbhc->mbhc_insert_dwork, wcd9xxx_mbhc_insert_work);
+		INIT_DELAYED_WORK(&mbhc->mbhc_firmware_dwork,
+				  wcd9xxx_mbhc_fw_read);
+		INIT_DELAYED_WORK(&mbhc->mbhc_btn_dwork, wcd9xxx_btn_lpress_fn);
+		INIT_DELAYED_WORK(&mbhc->mbhc_insert_dwork,
+				  wcd9xxx_mbhc_insert_work);
+	}
 
 	/* Register event notifier */
 	mbhc->nblock.notifier_call = wcd9xxx_event_notify;
@@ -3294,6 +3351,11 @@
 	wcd9xxx_free_irq(cdata, WCD9XXX_IRQ_MBHC_REMOVAL, mbhc);
 	wcd9xxx_free_irq(cdata, WCD9XXX_IRQ_MBHC_INSERTION, mbhc);
 
+	wcd9xxx_free_irq(cdata, WCD9XXX_IRQ_MBHC_JACK_SWITCH, mbhc);
+	wcd9xxx_free_irq(cdata, WCD9XXX_IRQ_HPH_PA_OCPL_FAULT, mbhc);
+	wcd9xxx_free_irq(cdata, WCD9XXX_IRQ_HPH_PA_OCPR_FAULT, mbhc);
+	wcd9xxx_free_irq(cdata, WCD9XXX_IRQ_MBHC_RELEASE, mbhc);
+
 	if (mbhc->mbhc_fw)
 		release_firmware(mbhc->mbhc_fw);
 
diff --git a/sound/soc/codecs/wcd9xxx-resmgr.c b/sound/soc/codecs/wcd9xxx-resmgr.c
index 3952dd5..2011346 100644
--- a/sound/soc/codecs/wcd9xxx-resmgr.c
+++ b/sound/soc/codecs/wcd9xxx-resmgr.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
@@ -94,6 +94,14 @@
 	"WCD9XXX_EVENT_LAST",
 };
 
+struct wcd9xxx_resmgr_cond_entry {
+	unsigned short reg;
+	int shift;
+	bool invert;
+	enum wcd9xxx_resmgr_cond cond;
+	struct list_head list;
+};
+
 static enum wcd9xxx_clock_type wcd9xxx_save_clock(struct wcd9xxx_resmgr
 						  *resmgr);
 static void wcd9xxx_restore_clock(struct wcd9xxx_resmgr *resmgr,
@@ -116,7 +124,8 @@
 	/* Notify bg mode change */
 	wcd9xxx_resmgr_notifier_call(resmgr, WCD9XXX_EVENT_PRE_BG_OFF);
 	/* Disable bg */
-	snd_soc_write(resmgr->codec, WCD9XXX_A_BIAS_CENTRAL_BG_CTL, 0x00);
+	snd_soc_update_bits(resmgr->codec, WCD9XXX_A_BIAS_CENTRAL_BG_CTL,
+			    0x03, 0x00);
 	usleep_range(100, 100);
 	/* Notify bg mode change */
 	wcd9xxx_resmgr_notifier_call(resmgr, WCD9XXX_EVENT_POST_BG_OFF);
@@ -194,6 +203,49 @@
 	pr_debug("%s: leave\n", __func__);
 }
 
+void wcd9xxx_resmgr_post_ssr(struct wcd9xxx_resmgr *resmgr)
+{
+	int old_bg_audio_users, old_bg_mbhc_users;
+	int old_clk_rco_users, old_clk_mclk_users;
+
+	pr_debug("%s: enter\n", __func__);
+	WCD9XXX_BCL_ASSERT_LOCKED(resmgr);
+
+	old_bg_audio_users = resmgr->bg_audio_users;
+	old_bg_mbhc_users = resmgr->bg_mbhc_users;
+	old_clk_rco_users = resmgr->clk_rco_users;
+	old_clk_mclk_users = resmgr->clk_mclk_users;
+	resmgr->bg_audio_users = 0;
+	resmgr->bg_mbhc_users = 0;
+	resmgr->bandgap_type = WCD9XXX_BANDGAP_OFF;
+	resmgr->clk_rco_users = 0;
+	resmgr->clk_mclk_users = 0;
+	resmgr->clk_type = WCD9XXX_CLK_OFF;
+
+	if (old_bg_audio_users) {
+		while (old_bg_audio_users--)
+			wcd9xxx_resmgr_get_bandgap(resmgr,
+						  WCD9XXX_BANDGAP_AUDIO_MODE);
+	}
+
+	if (old_bg_mbhc_users) {
+		while (old_bg_mbhc_users--)
+			wcd9xxx_resmgr_get_bandgap(resmgr,
+						  WCD9XXX_BANDGAP_MBHC_MODE);
+	}
+
+	if (old_clk_mclk_users) {
+		while (old_clk_mclk_users--)
+			wcd9xxx_resmgr_get_clk_block(resmgr, WCD9XXX_CLK_MCLK);
+	}
+
+	if (old_clk_rco_users) {
+		while (old_clk_rco_users--)
+			wcd9xxx_resmgr_get_clk_block(resmgr, WCD9XXX_CLK_RCO);
+	}
+	pr_debug("%s: leave\n", __func__);
+}
+
 /*
  * wcd9xxx_resmgr_get_bandgap : Vote for bandgap ref
  * choice : WCD9XXX_BANDGAP_AUDIO_MODE, WCD9XXX_BANDGAP_MBHC_MODE
@@ -596,6 +648,93 @@
 	return rc;
 }
 
+void wcd9xxx_resmgr_cond_trigger_cond(struct wcd9xxx_resmgr *resmgr,
+				      enum wcd9xxx_resmgr_cond cond)
+{
+	struct list_head *l;
+	struct wcd9xxx_resmgr_cond_entry *e;
+	bool set;
+
+	pr_debug("%s: enter\n", __func__);
+	WCD9XXX_BCL_ASSERT_LOCKED(resmgr);
+	set = !!test_bit(cond, &resmgr->cond_flags);
+	list_for_each(l, &resmgr->update_bit_cond_h) {
+		e = list_entry(l, struct wcd9xxx_resmgr_cond_entry, list);
+		if (e->cond == cond)
+			snd_soc_update_bits(resmgr->codec, e->reg,
+					    1 << e->shift,
+					    (set ? !e->invert : e->invert)
+					    << e->shift);
+	}
+	pr_debug("%s: leave\n", __func__);
+}
+
+void wcd9xxx_resmgr_cond_update_cond(struct wcd9xxx_resmgr *resmgr,
+				     enum wcd9xxx_resmgr_cond cond, bool set)
+{
+	WCD9XXX_BCL_ASSERT_LOCKED(resmgr);
+	if ((set && !test_and_set_bit(cond, &resmgr->cond_flags)) ||
+	    (!set && test_and_clear_bit(cond, &resmgr->cond_flags))) {
+		pr_debug("%s: Resource %d condition changed to %s\n", __func__,
+			 cond, set ? "set" : "clear");
+		wcd9xxx_resmgr_cond_trigger_cond(resmgr, cond);
+	}
+}
+
+int wcd9xxx_resmgr_add_cond_update_bits(struct wcd9xxx_resmgr *resmgr,
+					enum wcd9xxx_resmgr_cond cond,
+					unsigned short reg, int shift,
+					bool invert)
+{
+	struct wcd9xxx_resmgr_cond_entry *entry;
+
+	WCD9XXX_BCL_ASSERT_LOCKED(resmgr);
+	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry)
+		return -ENOMEM;
+
+	entry->cond = cond;
+	entry->reg = reg;
+	entry->shift = shift;
+	entry->invert = invert;
+	list_add_tail(&entry->list, &resmgr->update_bit_cond_h);
+
+	wcd9xxx_resmgr_cond_trigger_cond(resmgr, cond);
+
+	return 0;
+}
+
+/*
+ * wcd9xxx_resmgr_rm_cond_update_bits :
+ * Clear bit and remove from the conditional bit update list
+ */
+int wcd9xxx_resmgr_rm_cond_update_bits(struct wcd9xxx_resmgr *resmgr,
+				       enum wcd9xxx_resmgr_cond cond,
+				       unsigned short reg, int shift,
+				       bool invert)
+{
+	struct list_head *l, *next;
+	struct wcd9xxx_resmgr_cond_entry *e = NULL;
+
+	pr_debug("%s: enter\n", __func__);
+	WCD9XXX_BCL_ASSERT_LOCKED(resmgr);
+	list_for_each_safe(l, next, &resmgr->update_bit_cond_h) {
+		e = list_entry(l, struct wcd9xxx_resmgr_cond_entry, list);
+		if (e->reg == reg && e->shift == shift && e->invert == invert) {
+			snd_soc_update_bits(resmgr->codec, e->reg,
+					    1 << e->shift,
+					    e->invert << e->shift);
+			list_del(&e->list);
+			kfree(e);
+			return 0;
+		}
+	}
+	pr_err("%s: Cannot find update bit entry reg 0x%x, shift %d\n",
+	       __func__, e ? e->reg : 0, e ? e->shift : 0);
+
+	return -EINVAL;
+}
+
 int wcd9xxx_resmgr_register_notifier(struct wcd9xxx_resmgr *resmgr,
 				     struct notifier_block *nblock)
 {
@@ -625,6 +764,8 @@
 	resmgr->pdata = pdata;
 	resmgr->reg_addr = reg_addr;
 
+	INIT_LIST_HEAD(&resmgr->update_bit_cond_h);
+
 	BLOCKING_INIT_NOTIFIER_HEAD(&resmgr->notifier);
 
 	mutex_init(&resmgr->codec_resource_lock);
diff --git a/sound/soc/codecs/wcd9xxx-resmgr.h b/sound/soc/codecs/wcd9xxx-resmgr.h
index 2d04102..53c48f6 100644
--- a/sound/soc/codecs/wcd9xxx-resmgr.h
+++ b/sound/soc/codecs/wcd9xxx-resmgr.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
@@ -125,6 +125,9 @@
 	/* Notifier needs mbhc pointer with resmgr */
 	struct wcd9xxx_mbhc *mbhc;
 
+	unsigned long cond_flags;
+	struct list_head update_bit_cond_h;
+
 	/*
 	 * Currently, only used for mbhc purpose, to protect
 	 * concurrent execution of mbhc threaded irq handlers and
@@ -158,6 +161,7 @@
 			      enum wcd9xxx_cfilt_sel cfilt_sel);
 
 void wcd9xxx_resmgr_bcl_lock(struct wcd9xxx_resmgr *resmgr);
+void wcd9xxx_resmgr_post_ssr(struct wcd9xxx_resmgr *resmgr);
 #define WCD9XXX_BCL_LOCK(resmgr)			\
 {							\
 	pr_debug("%s: Acquiring BCL\n", __func__);	\
@@ -188,4 +192,18 @@
 void wcd9xxx_resmgr_notifier_call(struct wcd9xxx_resmgr *resmgr,
 				  const enum wcd9xxx_notify_event e);
 
+enum wcd9xxx_resmgr_cond {
+	WCD9XXX_COND_HPH_MIC = 1,
+};
+int wcd9xxx_resmgr_rm_cond_update_bits(struct wcd9xxx_resmgr *resmgr,
+				       enum wcd9xxx_resmgr_cond cond,
+				       unsigned short reg, int shift,
+				       bool invert);
+int wcd9xxx_resmgr_add_cond_update_bits(struct wcd9xxx_resmgr *resmgr,
+					enum wcd9xxx_resmgr_cond cond,
+					unsigned short reg, int shift,
+					bool invert);
+void wcd9xxx_resmgr_cond_update_cond(struct wcd9xxx_resmgr *resmgr,
+				     enum wcd9xxx_resmgr_cond cond, bool set);
+
 #endif /* __WCD9XXX_COMMON_H__ */
diff --git a/sound/soc/msm/Kconfig b/sound/soc/msm/Kconfig
index c957526..35a9646 100644
--- a/sound/soc/msm/Kconfig
+++ b/sound/soc/msm/Kconfig
@@ -180,6 +180,21 @@
 	 the machine drivers and the corresponding
 	 DAI-links.
 
+config SND_SOC_MSM8226
+	tristate "SoC Machine driver for MSM8226 boards"
+	depends on ARCH_MSM8226
+	select SND_SOC_QDSP6V2
+	select SND_SOC_MSM_STUB
+	select SND_SOC_MSM_HOSTLESS_PCM
+	select SND_SOC_WCD9306
+	select SND_DYNAMIC_MINORS
+	help
+	 To add support for SoC audio on MSM8226.
+	 This will enable sound soc drivers which
+	 interfaces with DSP, also it will enable
+	 the machine drivers and the corresponding
+	 DAI-links.
+
 config SND_SOC_MDM9615
 	tristate "SoC Machine driver for MDM9615 boards"
 	depends on ARCH_MSM9615
@@ -192,6 +207,21 @@
 	help
 	 To add support for SoC audio on MDM9615 boards
 
+config SND_SOC_MSM8X10
+	tristate "SoC Machine driver for MSM8X10 boards"
+	depends on ARCH_MSM8610
+	select SND_SOC_QDSP6V2
+	select SND_SOC_MSM_STUB
+	select SND_SOC_MSM_HOSTLESS_PCM
+	select SND_SOC_MSM8X10_WCD
+	select SND_DYNAMIC_MINORS
+	help
+	 To add support for SoC audio on MSM8X10.
+	 This will enable sound soc drivers which
+	 interfaces with DSP, also it will enable
+	 the machine drivers and the corresponding
+	 DAI-links.
+
 config SND_SOC_MSM8660_APQ
         tristate "Soc Machine driver for APQ8060 WM8903 codec"
         depends on ARCH_MSM8X60
diff --git a/sound/soc/msm/Makefile b/sound/soc/msm/Makefile
index a4c365a..60ffd89 100644
--- a/sound/soc/msm/Makefile
+++ b/sound/soc/msm/Makefile
@@ -58,7 +58,7 @@
 
 snd-soc-qdsp6-objs := msm-dai-q6.o msm-pcm-q6.o msm-multi-ch-pcm-q6.o msm-lowlatency-pcm-q6.o msm-pcm-routing.o msm-dai-fe.o msm-compr-q6.o msm-dai-stub.o
 obj-$(CONFIG_SND_SOC_MSM_QDSP6_HDMI_AUDIO) += msm-dai-q6-hdmi.o
-obj-$(CONFIG_SND_SOC_VOICE) += msm-pcm-voice.o msm-pcm-voip.o msm-pcm-dtmf.o
+obj-$(CONFIG_SND_SOC_VOICE) += msm-pcm-voice.o msm-pcm-voip.o msm-pcm-dtmf.o msm-pcm-host-voice.o
 snd-soc-qdsp6-objs += msm-pcm-lpa.o msm-pcm-afe.o
 obj-$(CONFIG_SND_SOC_QDSP6) += snd-soc-qdsp6.o
 
@@ -87,3 +87,12 @@
 #for MDM9625 sound card driver
 snd-soc-mdm9625-objs := mdm9625.o
 obj-$(CONFIG_SND_SOC_MDM9625) += snd-soc-mdm9625.o
+
+#for MSM 8226 sound card driver
+snd-soc-msm8226-objs := msm8226.o
+obj-$(CONFIG_SND_SOC_MSM8226) += snd-soc-msm8226.o
+
+# for MSM 8x10 sound card driver
+obj-$(CONFIG_SND_SOC_MSM_QDSP6V2_INTF) += qdsp6v2/
+snd-soc-msm8x10-objs := msm8x10.o
+obj-$(CONFIG_SND_SOC_MSM8X10) += snd-soc-msm8x10.o
diff --git a/sound/soc/msm/apq8064-i2s.c b/sound/soc/msm/apq8064-i2s.c
index 795b421..f9e0402 100644
--- a/sound/soc/msm/apq8064-i2s.c
+++ b/sound/soc/msm/apq8064-i2s.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/sound/soc/msm/apq8064.c b/sound/soc/msm/apq8064.c
index a351f7b..fb77c8d 100644
--- a/sound/soc/msm/apq8064.c
+++ b/sound/soc/msm/apq8064.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/sound/soc/msm/lpass-dma.c b/sound/soc/msm/lpass-dma.c
index 66c1836..39a7f7f 100644
--- a/sound/soc/msm/lpass-dma.c
+++ b/sound/soc/msm/lpass-dma.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/sound/soc/msm/lpass-i2s.c b/sound/soc/msm/lpass-i2s.c
index 9583c52..795f4ee 100644
--- a/sound/soc/msm/lpass-i2s.c
+++ b/sound/soc/msm/lpass-i2s.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/sound/soc/msm/lpass-pcm.c b/sound/soc/msm/lpass-pcm.c
index efd7c06..33d5e64 100644
--- a/sound/soc/msm/lpass-pcm.c
+++ b/sound/soc/msm/lpass-pcm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/sound/soc/msm/lpass-pcm.h b/sound/soc/msm/lpass-pcm.h
index 3bec9a7..e7e5597 100644
--- a/sound/soc/msm/lpass-pcm.h
+++ b/sound/soc/msm/lpass-pcm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/sound/soc/msm/mdm9615.c b/sound/soc/msm/mdm9615.c
index 433786d..b140b5b 100644
--- a/sound/soc/msm/mdm9615.c
+++ b/sound/soc/msm/mdm9615.c
@@ -2052,6 +2052,46 @@
 		.codec_dai_name = "msm-stub-tx",
 		.ignore_suspend = 1,
 	},
+	{
+		.name = "CS-VOICE HOST RX CAPTURE",
+		.stream_name = "CS-VOICE HOST RX CAPTURE",
+		.cpu_dai_name = "msm-dai-stub",
+		.platform_name  = "msm-host-pcm-voice",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-tx",
+		.ignore_suspend = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+			    SND_SOC_DPCM_TRIGGER_POST},
+	},
+	{
+		.name = "CS-VOICE HOST RX PLAYBACK",
+		.stream_name = "CS-VOICE HOST RX PLAYBACK",
+		.cpu_dai_name = "msm-dai-stub",
+		.platform_name  = "msm-host-pcm-voice",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-rx",
+		.ignore_suspend = 1,
+	},
+	{
+		.name = "CS-VOICE HOST TX CAPTURE",
+		.stream_name = "CS-VOICE HOST TX CAPTURE",
+		.cpu_dai_name = "msm-dai-stub",
+		.platform_name  = "msm-host-pcm-voice",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-tx",
+		.ignore_suspend = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+			    SND_SOC_DPCM_TRIGGER_POST},
+	},
+	{
+		.name = "CS-VOICE HOST TX PLAYBACK",
+		.stream_name = "CS-VOICE HOST TX PLAYBACK",
+		.cpu_dai_name = "msm-dai-stub",
+		.platform_name  = "msm-host-pcm-voice",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-rx",
+		.ignore_suspend = 1,
+	},
 
 	/* Backend BT DAI Links */
 	{
diff --git a/sound/soc/msm/mdm9625.c b/sound/soc/msm/mdm9625.c
index 4c7b69d..2bef1b7 100644
--- a/sound/soc/msm/mdm9625.c
+++ b/sound/soc/msm/mdm9625.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
@@ -22,18 +22,12 @@
 #include <sound/soc-dapm.h>
 #include <sound/pcm.h>
 #include <sound/jack.h>
+#include <sound/q6afe-v2.h>
 #include <asm/mach-types.h>
 #include <mach/socinfo.h>
 #include <qdsp6v2/msm-pcm-routing-v2.h>
 #include "../codecs/wcd9320.h"
-
-/* MI2S GPIO SECTION */
-
-#define GPIO_MI2S_WS     12
-#define GPIO_MI2S_SCLK   15
-#define GPIO_MI2S_DOUT   14
-#define GPIO_MI2S_DIN    13
-#define GPIO_MI2S_MCLK   71
+#include <linux/io.h>
 
 /* Spk control */
 #define MDM9625_SPK_ON 1
@@ -45,59 +39,73 @@
 #define MDM_MCLK_CLK_12P288MHZ 12288000
 #define MDM_MCLK_CLK_9P6HZ 9600000
 #define MDM_IBIT_CLK_DIV_1P56MHZ 7
+#define MDM_MI2S_AUXPCM_PRIM_INTF 0
+#define MDM_MI2S_AUXPCM_SEC_INTF  1
+
+#define LPAIF_OFFSET 0xFE000000
+#define LPAIF_PRI_MODE_MUXSEL (LPAIF_OFFSET + 0x2B000)
+#define LPAIF_SEC_MODE_MUXSEL (LPAIF_OFFSET + 0x2C000)
+
+#define I2S_SEL 0
+#define I2S_PCM_SEL 1
+#define I2S_PCM_SEL_OFFSET 1
 
 /* Machine driver Name*/
 #define MDM9625_MACHINE_DRV_NAME "mdm9625-asoc-taiko"
 
+/* I2S GPIO */
+struct msm_i2s_gpio {
+	unsigned gpio_no;
+	const char *gpio_name;
+};
+
+struct msm_i2s_ctrl {
+	struct msm_i2s_gpio *pin_data;
+	struct clk *cdc_bit_clk;
+	u32 cnt;
+};
 struct mdm9625_machine_data {
 	u32 mclk_freq;
+	struct msm_i2s_gpio *mclk_pin;
+	struct msm_i2s_ctrl *pri_ctrl;
+	u32 prim_clk_usrs;
 };
 
-/* MI2S clock */
-struct mdm_mi2s_clk {
-	struct clk *cdc_cr_clk;
-	struct clk *cdc_osr_clk;
-	struct clk *cdc_bit_clk;
-	bool clk_enable;
-
+static const struct afe_clk_cfg lpass_default = {
+	AFE_API_VERSION_I2S_CONFIG,
+	Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
+	Q6AFE_LPASS_OSR_CLK_12_P288_MHZ,
+	Q6AFE_LPASS_CLK_SRC_INTERNAL,
+	Q6AFE_LPASS_CLK_ROOT_DEFAULT,
+	Q6AFE_LPASS_MODE_BOTH_VALID,
+	0,
 };
-static struct mdm_mi2s_clk prim_clk;
 
-/* I2S GPIO */
-struct request_gpio {
-	unsigned gpio_no;
-	char *gpio_name;
+
+#define GPIO_NAME_INDEX 0
+#define DT_PARSE_INDEX  1
+
+static int mdm9625_auxpcm_rate = 8000;
+void *lpaif_pri_muxsel_virt_addr;
+
+static char *mdm_i2s_gpio_name[][2] = {
+	 {"PRIM_MI2S_WS",   "prim-i2s-gpio-ws"},
+	 {"PRIM_MI2S_DIN",  "prim-i2s-gpio-din"},
+	 {"PRIM_MI2S_DOUT", "prim-i2s-gpio-dout"},
+	 {"PRIM_MI2S_SCLK", "prim-i2s-gpio-sclk"},
 };
+
+static char *mdm_mclk_gpio[][2] = {
+	 {"MI2S_MCLK",      "prim-i2s-gpio-mclk"},
+};
+
 static struct mutex cdc_mclk_mutex;
 static int mdm9625_mi2s_rx_ch = 1;
 static int mdm9625_mi2s_tx_ch = 1;
 static int msm_spk_control;
+static atomic_t aux_ref_count;
 static atomic_t mi2s_ref_count;
 
-/* MI2S GPIO CONFIG */
-static struct request_gpio mi2s_gpio[] = {
-	{
-		.gpio_no = GPIO_MI2S_WS,
-		.gpio_name = "MI2S_WS",
-	},
-	{
-		.gpio_no = GPIO_MI2S_SCLK,
-		.gpio_name = "MI2S_SCLK",
-	},
-	{
-		.gpio_no = GPIO_MI2S_DOUT,
-		.gpio_name = "MI2S_DOUT",
-	},
-	{
-		.gpio_no = GPIO_MI2S_DIN,
-		.gpio_name = "MI2S_DIN",
-	},
-	{
-		.gpio_no = GPIO_MI2S_MCLK,
-		.gpio_name = "MI2S_MCLK",
-	},
-};
-
 static int mdm9625_enable_codec_ext_clk(struct snd_soc_codec *codec,
 					int enable, bool dapm);
 
@@ -120,132 +128,148 @@
 #define WCD9XXX_MBHC_DEF_BUTTONS 8
 #define WCD9XXX_MBHC_DEF_RLOADS 5
 
-
-static bool gpio_enable;
-
-static int mdm9625_set_mi2s_gpio(void)
+static int mdm9625_set_gpio(struct snd_pcm_substream *substream,
+			    u32 intf)
 {
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_card *card = rtd->card;
+	struct mdm9625_machine_data *pdata = snd_soc_card_get_drvdata(card);
+	struct msm_i2s_ctrl *i2s_ctrl = NULL;
+	struct msm_i2s_gpio *pin_data = NULL;
 	int rtn = 0;
 	int i;
 	int j;
 
-	if (gpio_enable == false) {
-		for (i = 0; i < ARRAY_SIZE(mi2s_gpio); i++) {
-			rtn = gpio_request(mi2s_gpio[i].gpio_no,
-					   mi2s_gpio[i].gpio_name);
-			pr_debug("%s: gpio = %d, gpio name = %s\n"
-				 "rtn = %d\n", __func__,
-				 mi2s_gpio[i].gpio_no,
-				 mi2s_gpio[i].gpio_name,
-				 rtn);
-			if (rtn) {
-				pr_err("%s: Failed to request gpio %d\n",
-					__func__, mi2s_gpio[i].gpio_no);
-				/* Release all the GPIO on failure */
-				for (j = i; j >= 0; j--)
-					gpio_free(mi2s_gpio[j].gpio_no);
-				goto err;
-			}
+	if (pdata == NULL) {
+		pr_err("%s: pdata is NULL\n", __func__);
+		rtn = -EINVAL;
+		goto err;
+	}
+
+	if (intf == MDM_MI2S_AUXPCM_PRIM_INTF) {
+		i2s_ctrl = pdata->pri_ctrl;
+	}
+	else {
+		pr_err("%s: Wrong I2S Interface\n", __func__);
+		rtn = -EINVAL;
+		goto err;
+	}
+	if (i2s_ctrl == NULL || i2s_ctrl->pin_data == NULL) {
+		pr_err("%s: Intf ptr NULL\n", __func__);
+		rtn = -EINVAL;
+		goto err;
+	}
+	pin_data = i2s_ctrl->pin_data;
+	for (i = 0; i < i2s_ctrl->cnt; i++, pin_data++) {
+		rtn = gpio_request(pin_data->gpio_no,
+				   pin_data->gpio_name);
+		pr_debug("%s: gpio = %d, gpio name = %s\n"
+			 "rtn = %d\n", __func__,
+			 pin_data->gpio_no,
+			 pin_data->gpio_name,
+			 rtn);
+		if (rtn) {
+			pr_err("%s: Failed to request gpio %d\n",
+				__func__, pin_data->gpio_no);
+			/* Release all the GPIO on failure */
+			for (j = i; j >= 0; j--)
+				gpio_free(pin_data->gpio_no);
+			goto err;
 		}
-	gpio_enable = true;
 	}
 err:
 	return rtn;
+
 }
 
-static int mdm9625_mi2s_free_gpios(void)
+static int mdm9625_mi2s_free_gpios(struct snd_pcm_substream *substream,
+				   u32 intf)
 {
 	int i;
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_card *card = rtd->card;
+	struct mdm9625_machine_data *pdata = snd_soc_card_get_drvdata(card);
+	struct msm_i2s_ctrl *i2s_ctrl = NULL;
+	struct msm_i2s_gpio *pin_data = NULL;
+	int rtn = 0;
+
 	pr_debug("%s:", __func__);
-	for (i = 0; i < ARRAY_SIZE(mi2s_gpio); i++)
-		gpio_free(mi2s_gpio[i].gpio_no);
-	gpio_enable = false;
-	return 0;
+	if (pdata == NULL) {
+		pr_err("%s: pdata is NULL\n", __func__);
+		rtn = -EINVAL;
+		goto err;
+	}
+	if (intf == MDM_MI2S_AUXPCM_PRIM_INTF) {
+		i2s_ctrl = pdata->pri_ctrl;
+	}
+	else {
+		pr_debug("%s: Wrong Interface\n", __func__);
+		rtn = -EINVAL;
+		goto err;
+	}
+	if (i2s_ctrl == NULL || i2s_ctrl->pin_data == NULL) {
+		pr_err("%s: Intf ptr NULL\n", __func__);
+		rtn = -EINVAL;
+		goto err;
+	}
+	pin_data = i2s_ctrl->pin_data;
+	for (i = 0; i < i2s_ctrl->cnt; i++, pin_data++) {
+		gpio_free(pin_data->gpio_no);
+		pr_debug("%s: gpio = %d, gpio name = %s\n",
+			 __func__, pin_data->gpio_no,
+			 pin_data->gpio_name);
+	}
+err:
+	return rtn;
+
 }
 static int mdm9625_mi2s_clk_ctl(struct snd_soc_pcm_runtime *rtd, bool enable)
 {
-	struct mdm_mi2s_clk *clk = &prim_clk;
-	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	struct snd_soc_card *card = rtd->card;
 	struct mdm9625_machine_data *pdata = snd_soc_card_get_drvdata(card);
+	struct afe_clk_cfg *lpass_clk = NULL;
 	int ret = 0;
 
 	if (pdata == NULL) {
 		pr_err("%s:platform data is null\n", __func__);
-		return -ENODEV;
+		return -ENOMEM;
 	}
-
+	lpass_clk = kzalloc(sizeof(struct afe_clk_cfg), GFP_KERNEL);
+	if (lpass_clk == NULL) {
+		pr_err("%s:Failed to allocate memory\n", __func__);
+			return -ENOMEM;
+	}
+	memcpy(lpass_clk, &lpass_default, sizeof(struct afe_clk_cfg));
+	pr_debug("%s:enable = %x\n", __func__, enable);
 	if (enable) {
-		if (clk->clk_enable == true) {
-			pr_info("%s:Device clock already enabled\n", __func__);
-			return 0;
-		}
-		/* Set up core clock. */
-		clk->cdc_cr_clk = clk_get(cpu_dai->dev, "core_clk");
-		if (IS_ERR(clk->cdc_cr_clk)) {
-			pr_err("%s: Failed to Core clk %ld\n"
-			       "CPU dai name %s\n", __func__,
-			       PTR_ERR(clk->cdc_cr_clk),
-			       cpu_dai->dev->driver->name);
-			return -ENODEV ;
-		}
-		/* osr clock */
-		clk->cdc_osr_clk = clk_get(cpu_dai->dev, "osr_clk");
-		if (IS_ERR(clk->cdc_osr_clk)) {
-			pr_err("%s: Failed to request OSR %ld\n"
-			       "CPU dai name %s\n", __func__,
-			       PTR_ERR(clk->cdc_osr_clk),
-			       cpu_dai->dev->driver->name);
-			clk_put(clk->cdc_cr_clk);
-			return -ENODEV ;
-		}
-		/* ibit clock */
-		clk->cdc_bit_clk = clk_get(cpu_dai->dev, "ibit_clk");
-		if (IS_ERR(clk->cdc_bit_clk)) {
-			pr_err("%s: Failed to request Bit %ld\n"
-			       "CPU dai name %s\n", __func__,
-			       PTR_ERR(clk->cdc_bit_clk),
-			       cpu_dai->dev->driver->name);
-			clk_put(clk->cdc_cr_clk);
-			clk_put(clk->cdc_osr_clk);
-			return -ENODEV ;
-		}
-		/* Set rate core and ibit clock */
-		clk_set_rate(clk->cdc_cr_clk, pdata->mclk_freq);
-		clk_set_rate(clk->cdc_bit_clk, MDM_IBIT_CLK_DIV_1P56MHZ);
-
-		/* Enable clocks. core clock need not be enabled.
-		 * Enabling branch clocks indirectly enables
-		 * core clock.
-		 */
-		ret = clk_prepare_enable(clk->cdc_osr_clk);
-		if (ret != 0) {
-			pr_err("Fail to enable cdc_osr_clk\n");
-			goto exit_osrclk_err;
-		}
-		ret = clk_prepare_enable(clk->cdc_bit_clk);
-		if (ret != 0) {
-			pr_err("Fail to enable cdc_bit_clk\n");
-			goto exit_bclk_err;
-		}
-		clk->clk_enable = true;
-		return ret;
+		if (pdata->prim_clk_usrs == 0) {
+			lpass_clk->clk_val2 = pdata->mclk_freq;
+			lpass_clk->clk_set_mode = Q6AFE_LPASS_MODE_BOTH_VALID;
+		} else
+			lpass_clk->clk_set_mode = Q6AFE_LPASS_MODE_CLK1_VALID;
+		ret = afe_set_lpass_clock(MI2S_RX, lpass_clk);
+		if (ret < 0)
+			pr_err("%s:afe_set_lpass_clock failed\n", __func__);
+		else
+			pdata->prim_clk_usrs++;
 	} else {
-		clk->clk_enable = false;
-		ret = 0;
-		goto exit_bclk_err;
+		if (pdata->prim_clk_usrs > 0)
+			pdata->prim_clk_usrs--;
+		if (pdata->prim_clk_usrs == 0) {
+			lpass_clk->clk_val2 = Q6AFE_LPASS_OSR_CLK_DISABLE;
+			lpass_clk->clk_set_mode = Q6AFE_LPASS_MODE_BOTH_VALID;
+		} else
+			lpass_clk->clk_set_mode = Q6AFE_LPASS_MODE_CLK1_VALID;
+		lpass_clk->clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE;
+		ret = afe_set_lpass_clock(MI2S_RX, lpass_clk);
+		if (ret < 0)
+			pr_err("%s:afe_set_lpass_clock failed\n", __func__);
 	}
-exit_bclk_err:
-	clk_disable_unprepare(clk->cdc_bit_clk);
-	clk_put(clk->cdc_bit_clk);
-exit_osrclk_err:
-	clk_disable_unprepare(clk->cdc_osr_clk);
-	clk_put(clk->cdc_osr_clk);
-	clk_put(clk->cdc_cr_clk);
-	clk->cdc_cr_clk = NULL;
-	clk->cdc_bit_clk = NULL;
-	clk->cdc_osr_clk = NULL;
-	clk->clk_enable = false;
+	pr_debug("%s: clk 1 = %x clk2 = %x mode = %x\n",
+			__func__, lpass_clk->clk_val1,
+			lpass_clk->clk_val2,
+			lpass_clk->clk_set_mode);
+	kfree(lpass_clk);
 	return ret;
 }
 
@@ -254,7 +278,7 @@
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	int ret;
 	if (atomic_dec_return(&mi2s_ref_count) == 0) {
-		mdm9625_mi2s_free_gpios();
+		mdm9625_mi2s_free_gpios(substream, MDM_MI2S_AUXPCM_PRIM_INTF);
 		ret = mdm9625_mi2s_clk_ctl(rtd, false);
 		if (ret < 0)
 			pr_err("%s:clock disable failed\n", __func__);
@@ -269,7 +293,17 @@
 	int ret = 0;
 
 	if (atomic_inc_return(&mi2s_ref_count) == 1) {
-		mdm9625_set_mi2s_gpio();
+		if (lpaif_pri_muxsel_virt_addr != NULL)
+			iowrite32(I2S_SEL << I2S_PCM_SEL_OFFSET,
+				  lpaif_pri_muxsel_virt_addr);
+		else
+			pr_err("%s lpaif_pri_muxsel_virt_addr is NULL\n",
+				__func__);
+		ret = mdm9625_set_gpio(substream, MDM_MI2S_AUXPCM_PRIM_INTF);
+		if (ret < 0) {
+			pr_err("%s, GPIO setup failed\n", __func__);
+			return ret;
+		}
 		ret = mdm9625_mi2s_clk_ctl(rtd, true);
 		if (ret < 0) {
 			pr_err("set format for codec dai failed\n");
@@ -397,14 +431,53 @@
 					int enable, bool dapm)
 {
 	int ret = 0;
-	pr_debug("%s: enable = %d  codec name %s\n", __func__,
-		enable, codec->name);
+	struct mdm9625_machine_data *pdata =
+			snd_soc_card_get_drvdata(codec->card);
+	struct afe_clk_cfg *lpass_clk = NULL;
+
+	pr_debug("%s: enable = %d  codec name %s enable %x\n",
+		   __func__, enable, codec->name, enable);
+	lpass_clk = kzalloc(sizeof(struct afe_clk_cfg), GFP_KERNEL);
+	if (lpass_clk == NULL) {
+		pr_err("%s:Failed to allocate memory\n", __func__);
+		return -ENOMEM;
+	}
 	mutex_lock(&cdc_mclk_mutex);
-	if (enable)
+	memcpy(lpass_clk, &lpass_default, sizeof(struct afe_clk_cfg));
+	if (enable) {
+		if (pdata->prim_clk_usrs == 0) {
+			lpass_clk->clk_val2 = pdata->mclk_freq;
+			lpass_clk->clk_set_mode = Q6AFE_LPASS_MODE_CLK2_VALID;
+			ret = afe_set_lpass_clock(MI2S_RX, lpass_clk);
+			if (ret < 0) {
+				pr_err("%s:afe_set_lpass_clock failed\n",
+				       __func__);
+				goto err;
+			}
+		}
+		pdata->prim_clk_usrs++;
 		taiko_mclk_enable(codec, 1, dapm);
-	else
+	} else {
+		if (pdata->prim_clk_usrs > 0)
+			pdata->prim_clk_usrs--;
+		if (pdata->prim_clk_usrs == 0) {
+			lpass_clk->clk_set_mode = Q6AFE_LPASS_MODE_CLK2_VALID;
+			lpass_clk->clk_val2 = Q6AFE_LPASS_OSR_CLK_DISABLE;
+			ret = afe_set_lpass_clock(MI2S_RX, lpass_clk);
+			if (ret < 0) {
+				pr_err("%s:afe_set_lpass_clock failed\n",
+				       __func__);
+				goto err;
+			}
+		}
 		taiko_mclk_enable(codec, 0, dapm);
+	}
+	pr_debug("%s: clk2 = %x mode = %x\n",
+			 __func__, lpass_clk->clk_val2,
+			 lpass_clk->clk_set_mode);
+err:
 	mutex_unlock(&cdc_mclk_mutex);
+	kfree(lpass_clk);
 	return ret;
 }
 
@@ -421,6 +494,83 @@
 	return 0;
 }
 
+static int mdm9625_auxpcm_startup(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	int ret = 0;
+
+	if (atomic_inc_return(&aux_ref_count) == 1) {
+		if (lpaif_pri_muxsel_virt_addr != NULL)
+			iowrite32(I2S_PCM_SEL << I2S_PCM_SEL_OFFSET,
+				  lpaif_pri_muxsel_virt_addr);
+		else
+			pr_err("%s lpaif_pri_muxsel_virt_addr is NULL\n",
+				__func__);
+		ret = mdm9625_set_gpio(substream, MDM_MI2S_AUXPCM_PRIM_INTF);
+		if (ret < 0) {
+			pr_err("%s, GPIO setup failed\n", __func__);
+			return ret;
+		}
+		ret = mdm9625_mi2s_clk_ctl(rtd, true);
+		if (ret < 0) {
+			pr_err("set format for codec dai failed\n");
+			return ret;
+		}
+	}
+	return ret;
+}
+
+static void mdm9625_auxpcm_snd_shutdown(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	int ret;
+
+	if (atomic_dec_return(&aux_ref_count) == 0) {
+		mdm9625_mi2s_free_gpios(substream, MDM_MI2S_AUXPCM_PRIM_INTF);
+		ret = mdm9625_mi2s_clk_ctl(rtd, false);
+		if (ret < 0)
+			pr_err("%s:clock disable failed\n", __func__);
+	}
+}
+
+static int mdm9625_auxpcm_rate_get(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
+{
+	ucontrol->value.integer.value[0] = mdm9625_auxpcm_rate;
+	return 0;
+}
+
+static int mdm9625_auxpcm_rate_put(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
+{
+	switch (ucontrol->value.integer.value[0]) {
+	case 0:
+		mdm9625_auxpcm_rate = 8000;
+		break;
+	case 1:
+		mdm9625_auxpcm_rate = 16000;
+		break;
+	default:
+		mdm9625_auxpcm_rate = 8000;
+		break;
+	}
+	return 0;
+}
+
+static int mdm9625_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd,
+					  struct snd_pcm_hw_params *params)
+{
+	struct snd_interval *rate =
+		hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+
+	struct snd_interval *channels =
+		hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+
+	rate->min = rate->max = mdm9625_auxpcm_rate;
+	channels->min = channels->max = 1;
+
+	return 0;
+}
 
 static const struct snd_soc_dapm_widget mdm9625_dapm_widgets[] = {
 
@@ -445,23 +595,28 @@
 static const char *const spk_function[] = {"Off", "On"};
 static const char *const mi2s_rx_ch_text[] = {"One", "Two"};
 static const char *const mi2s_tx_ch_text[] = {"One", "Two"};
+static const char *const auxpcm_rate_text[] = {"rate_8000", "rate_16000"};
 
 static const struct soc_enum mdm9625_enum[] = {
 	SOC_ENUM_SINGLE_EXT(2, spk_function),
 	SOC_ENUM_SINGLE_EXT(2, mi2s_rx_ch_text),
 	SOC_ENUM_SINGLE_EXT(2, mi2s_tx_ch_text),
+	SOC_ENUM_SINGLE_EXT(2, auxpcm_rate_text),
 };
 
 static const struct snd_kcontrol_new mdm_snd_controls[] = {
-	SOC_ENUM_EXT("Speaker Function", mdm9625_enum[0],
+	SOC_ENUM_EXT("Speaker Function",   mdm9625_enum[0],
 				 mdm9625_mi2s_get_spk,
 				 mdm9625_mi2s_set_spk),
-	SOC_ENUM_EXT("MI2S_RX Channels", mdm9625_enum[1],
+	SOC_ENUM_EXT("MI2S_RX Channels",   mdm9625_enum[1],
 				 mdm9625_mi2s_rx_ch_get,
 				 mdm9625_mi2s_rx_ch_put),
-	SOC_ENUM_EXT("MI2S_TX Channels", mdm9625_enum[2],
+	SOC_ENUM_EXT("MI2S_TX Channels",   mdm9625_enum[2],
 				 mdm9625_mi2s_tx_ch_get,
 				 mdm9625_mi2s_tx_ch_put),
+	SOC_ENUM_EXT("AUX PCM SampleRate", mdm9625_enum[3],
+				 mdm9625_auxpcm_rate_get,
+				 mdm9625_auxpcm_rate_put),
 };
 
 static int mdm9625_mi2s_audrx_init(struct snd_soc_pcm_runtime *rtd)
@@ -470,7 +625,7 @@
 	struct snd_soc_codec *codec = rtd->codec;
 	struct snd_soc_dapm_context *dapm = &codec->dapm;
 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-	pr_info("%s(), dev_name%s\n", __func__, dev_name(cpu_dai->dev));
+	pr_debug("%s(), dev_name%s\n", __func__, dev_name(cpu_dai->dev));
 
 	rtd->pmdown_time = 0;
 	err = snd_soc_add_codec_controls(codec, mdm_snd_controls,
@@ -490,9 +645,6 @@
 	snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg");
 	snd_soc_dapm_sync(dapm);
 
-	/* start mbhc */
-	 mdm9625_set_mi2s_gpio();
-	mdm9625_mi2s_clk_ctl(rtd, true);
 	mbhc_cfg.calibration = def_taiko_mbhc_cal();
 	if (mbhc_cfg.calibration)
 		err = taiko_hs_detect(codec, &mbhc_cfg);
@@ -585,6 +737,11 @@
 	.shutdown = mdm9625_mi2s_snd_shutdown,
 };
 
+static struct snd_soc_ops mdm9625_auxpcm_be_ops = {
+	.startup = mdm9625_auxpcm_startup,
+	.shutdown = mdm9625_auxpcm_snd_shutdown,
+};
+
 /* Digital audio interface connects codec <---> CPU */
 static struct snd_soc_dai_link mdm9625_dai[] = {
 	/* FrontEnd DAI Links */
@@ -592,7 +749,7 @@
 		.name = "MDM9625 Media1",
 		.stream_name = "MultiMedia1",
 		.cpu_dai_name = "MultiMedia1",
-		.platform_name  = "msm-pcm-dsp",
+		.platform_name  = "msm-pcm-dsp.0",
 		.dynamic = 1,
 		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
 			    SND_SOC_DPCM_TRIGGER_POST},
@@ -649,6 +806,64 @@
 		.codec_dai_name = "snd-soc-dummy-dai",
 		.codec_name = "snd-soc-dummy",
 	},
+	{
+		.name = "VoLTE",
+		.stream_name = "VoLTE",
+		.cpu_dai_name   = "VoLTE",
+		.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_VOLTE,
+	},
+	{	.name = "MSM AFE-PCM RX",
+		.stream_name = "AFE-PROXY RX",
+		.cpu_dai_name = "msm-dai-q6-dev.241",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-rx",
+		.platform_name  = "msm-pcm-afe",
+		.ignore_suspend = 1,
+		/* this dainlink has playback support */
+		.ignore_pmdown_time = 1,
+	},
+	{
+		.name = "MSM AFE-PCM TX",
+		.stream_name = "AFE-PROXY TX",
+		.cpu_dai_name = "msm-dai-q6-dev.240",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-tx",
+		.platform_name  = "msm-pcm-afe",
+		.ignore_suspend = 1,
+	},
+	{
+		.name = "DTMF RX Hostless",
+		.stream_name = "DTMF RX Hostless",
+		.cpu_dai_name	= "DTMF_RX_HOSTLESS",
+		.platform_name	= "msm-pcm-dtmf",
+		.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,
+		.be_id = MSM_FRONTEND_DAI_DTMF_RX,
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+	},
+	{
+		.name = "DTMF TX",
+		.stream_name = "DTMF TX",
+		.cpu_dai_name = "msm-dai-stub",
+		.platform_name = "msm-pcm-dtmf",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-tx",
+		.ignore_suspend = 1,
+	},
 	/* Backend DAI Links */
 	{
 		.name = LPASS_BE_MI2S_RX,
@@ -675,6 +890,52 @@
 		.be_hw_params_fixup = &mdm9625_mi2s_tx_be_hw_params_fixup,
 		.ops = &mdm9625_mi2s_be_ops,
 	},
+	{
+		.name = LPASS_BE_AFE_PCM_RX,
+		.stream_name = "AFE Playback",
+		.cpu_dai_name = "msm-dai-q6-dev.224",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-rx",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_AFE_PCM_RX,
+	},
+	{
+		.name = LPASS_BE_AFE_PCM_TX,
+		.stream_name = "AFE Capture",
+		.cpu_dai_name = "msm-dai-q6-dev.225",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-tx",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_AFE_PCM_TX,
+	},
+	{
+		.name = LPASS_BE_AUXPCM_RX,
+		.stream_name = "AUX PCM Playback",
+		.cpu_dai_name = "msm-dai-q6.4106",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-rx",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_AUXPCM_RX,
+		.be_hw_params_fixup = mdm9625_auxpcm_be_params_fixup,
+		.ops = &mdm9625_auxpcm_be_ops,
+		.ignore_pmdown_time = 1,
+		/* this dainlink has playback support */
+	},
+	{
+		.name = LPASS_BE_AUXPCM_TX,
+		.stream_name = "AUX PCM Capture",
+		.cpu_dai_name = "msm-dai-q6.4107",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-tx",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_AUXPCM_TX,
+		.be_hw_params_fixup = mdm9625_auxpcm_be_params_fixup,
+		.ops = &mdm9625_auxpcm_be_ops,
+	},
 };
 
 static struct snd_soc_card snd_soc_card_mdm9625 = {
@@ -683,14 +944,108 @@
 	.num_links = ARRAY_SIZE(mdm9625_dai),
 };
 
+static int mdm9625_dtparse(struct platform_device *pdev,
+				struct mdm9625_machine_data **pdata)
+{
+	int ret = 0, i = 0;
+	struct msm_i2s_gpio *pin_data = NULL;
+	struct msm_i2s_ctrl *ctrl;
+	struct msm_i2s_gpio *mclk_pin = NULL;
+	unsigned int gpio_no[4];
+	unsigned int dt_mclk = 0;
+	enum of_gpio_flags flags = OF_GPIO_ACTIVE_LOW;
+	int prim_cnt = 0;
+	pin_data = devm_kzalloc(&pdev->dev, (4 *
+				sizeof(struct msm_i2s_gpio)),
+				GFP_KERNEL);
+	mclk_pin = devm_kzalloc(&pdev->dev,
+				sizeof(struct msm_i2s_gpio),
+				GFP_KERNEL);
+
+	if (!pin_data || !mclk_pin) {
+		dev_err(&pdev->dev, "No memory for gpio\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+	for (i = 0; i < ARRAY_SIZE(gpio_no); i++) {
+		gpio_no[i] = of_get_named_gpio_flags(pdev->dev.of_node,
+					  mdm_i2s_gpio_name[i][DT_PARSE_INDEX],
+					  0, &flags);
+		if (gpio_no[i] > 0) {
+			pin_data[i].gpio_name =
+				mdm_i2s_gpio_name[prim_cnt][GPIO_NAME_INDEX];
+			pin_data[i].gpio_no = gpio_no[i];
+			dev_dbg(&pdev->dev, "%s:GPIO gpio[%s] =\n"
+				"0x%x\n", __func__,
+				pin_data[i].gpio_name,
+				pin_data[i].gpio_no);
+			prim_cnt++;
+		} else {
+			dev_err(&pdev->dev, "%s:Invalid I2S GPIO[%s] = %x\n",
+				__func__,
+				mdm_i2s_gpio_name[i][GPIO_NAME_INDEX],
+				gpio_no[i]);
+			ret = -ENODEV;
+			goto err;
+		}
+	}
+	for (i = 0; i < ARRAY_SIZE(mdm_mclk_gpio); i++) {
+		dt_mclk = of_get_named_gpio_flags(pdev->dev.of_node,
+					  mdm_mclk_gpio[i][DT_PARSE_INDEX], 0,
+					  &flags);
+		if (dt_mclk > 0) {
+			mclk_pin->gpio_name =
+					mdm_mclk_gpio[i][GPIO_NAME_INDEX];
+			mclk_pin->gpio_no = dt_mclk;
+			ret = gpio_request(mclk_pin->gpio_no,
+					   mclk_pin->gpio_name);
+			dev_dbg(&pdev->dev, "%s:Request MCLK Gpio\n"
+				"gpio[%s] = 0x%x\n", __func__,
+				mclk_pin->gpio_name,
+				dt_mclk);
+		} else {
+			dev_err(&pdev->dev, "%s:MCLK gpio is incorrect\n",
+				__func__);
+			ret = -ENODEV;
+			goto err;
+		}
+	}
+
+	ctrl = devm_kzalloc(&pdev->dev,
+			    sizeof(struct msm_i2s_ctrl), GFP_KERNEL);
+	if (!ctrl) {
+		dev_err(&pdev->dev, "No memory for gpio\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+	ctrl->pin_data = pin_data;
+	ctrl->cnt = prim_cnt;
+	(*pdata)->pri_ctrl = ctrl;
+	(*pdata)->mclk_pin = mclk_pin;
+	return ret;
+
+err:
+	if (mclk_pin)
+		devm_kfree(&pdev->dev, mclk_pin);
+	if (pin_data)
+		devm_kfree(&pdev->dev, pin_data);
+	return ret;
+}
+
 static __devinit int mdm9625_asoc_machine_probe(struct platform_device *pdev)
 {
 	int ret;
 	struct snd_soc_card *card = &snd_soc_card_mdm9625;
 	struct mdm9625_machine_data *pdata;
+	enum apr_subsys_state q6_state;
 
+	q6_state = apr_get_q6_state();
+	if (q6_state != APR_SUBSYS_LOADED) {
+		dev_dbg(&pdev->dev, "defering %s, adsp_state %d\n",
+				__func__, q6_state);
+		return -EPROBE_DEFER;
+	}
 	mutex_init(&cdc_mclk_mutex);
-	gpio_enable = false;
 	if (!pdev->dev.of_node) {
 		dev_err(&pdev->dev, "No platform supplied from device tree\n");
 		return -EINVAL;
@@ -698,19 +1053,17 @@
 	pdata = devm_kzalloc(&pdev->dev, sizeof(struct mdm9625_machine_data),
 			     GFP_KERNEL);
 	if (!pdata) {
-		dev_err(&pdev->dev, "Can't allocate msm8974_asoc_mach_data\n");
+		dev_err(&pdev->dev, "Can't allocate mdm9625_asoc_mach_data\n");
 		ret = -ENOMEM;
 		goto err;
 	}
-	card->dev = &pdev->dev;
-	platform_set_drvdata(pdev, card);
-	snd_soc_card_set_drvdata(card, pdata);
-	ret = snd_soc_of_parse_card_name(card, "qcom,model");
-	if (ret)
+	ret = mdm9625_dtparse(pdev, &pdata);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"%s: mi2s-aux Pin data parse failed",
+			__func__);
 		goto err;
-	ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing");
-	if (ret)
-		goto err;
+	}
 	ret = of_property_read_u32(pdev->dev.of_node,
 				   "qcom,taiko-mclk-clk-freq",
 				   &pdata->mclk_freq);
@@ -722,18 +1075,36 @@
 		goto err;
 	}
 	/* At present only 12.288MHz is supported on MDM. */
-	if (pdata->mclk_freq != MDM_MCLK_CLK_12P288MHZ) {
+	if (q6afe_check_osr_clk_freq(pdata->mclk_freq)) {
 		dev_err(&pdev->dev, "unsupported taiko mclk freq %u\n",
 			pdata->mclk_freq);
 		ret = -EINVAL;
 		goto err;
 	}
+	pdata->prim_clk_usrs = 0;
+	card->dev = &pdev->dev;
+	platform_set_drvdata(pdev, card);
+	snd_soc_card_set_drvdata(card, pdata);
+	ret = snd_soc_of_parse_card_name(card, "qcom,model");
+	if (ret)
+		goto err;
+	ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing");
+	if (ret)
+		goto err;
 	ret = snd_soc_register_card(card);
 	if (ret) {
 		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
 				ret);
 		goto err;
 	}
+
+	lpaif_pri_muxsel_virt_addr = ioremap(LPAIF_PRI_MODE_MUXSEL, 4);
+	if (lpaif_pri_muxsel_virt_addr == NULL) {
+		pr_err("%s Pri muxsel virt addr is null\n", __func__);
+		ret = -EINVAL;
+		goto err;
+	}
+
 	return 0;
 err:
 	devm_kfree(&pdev->dev, pdata);
diff --git a/sound/soc/msm/mpq8064.c b/sound/soc/msm/mpq8064.c
index cef8659..81435d9 100644
--- a/sound/soc/msm/mpq8064.c
+++ b/sound/soc/msm/mpq8064.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -1441,7 +1441,7 @@
 		.name = "MSM8960 Media3",
 		.stream_name = "MultiMedia3",
 		.cpu_dai_name	= "MultiMedia3",
-		.platform_name  = "msm-pcm-dsp",
+		.platform_name  = "msm-multi-ch-pcm-dsp",
 		.dynamic = 1,
 		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
 				SND_SOC_DPCM_TRIGGER_POST},
diff --git a/sound/soc/msm/msm-compr-q6.c b/sound/soc/msm/msm-compr-q6.c
index d2ccb3e..39afb73 100644
--- a/sound/soc/msm/msm-compr-q6.c
+++ b/sound/soc/msm/msm-compr-q6.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -1137,11 +1137,10 @@
 		pr_debug("SNDRV_COMPRESS_TSTAMP\n");
 
 		memset(&tstamp, 0x0, sizeof(struct snd_compr_tstamp));
-		timestamp = q6asm_get_session_time(prtd->audio_client);
-		if (timestamp < 0) {
-			pr_err("%s: Get Session Time return value =%lld\n",
-				__func__, timestamp);
-			return -EAGAIN;
+		rc = q6asm_get_session_time(prtd->audio_client, &timestamp);
+		if (rc < 0) {
+			pr_err("%s: fail to get session tstamp\n", __func__);
+			return rc;
 		}
 		temp = (timestamp * 2 * runtime->channels);
 		temp = temp * (runtime->rate/1000);
diff --git a/sound/soc/msm/msm-compr-q6.h b/sound/soc/msm/msm-compr-q6.h
index cb7f714..d91854e 100644
--- a/sound/soc/msm/msm-compr-q6.h
+++ b/sound/soc/msm/msm-compr-q6.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * 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
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index cf0d4cd..96709be 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -24,7 +24,8 @@
 
 /* Conventional and unconventional sample rate supported */
 static unsigned int supported_sample_rates[] = {
-	8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
+	8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
+	96000
 };
 
 static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
@@ -52,13 +53,14 @@
 		.playback = {
 			.stream_name = "Multimedia1 Playback",
 			.aif_name = "MM_DL1",
-			.rates = (SNDRV_PCM_RATE_8000_48000|
+			.rates = (SNDRV_PCM_RATE_8000_96000|
 					SNDRV_PCM_RATE_KNOT),
-			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.formats = (SNDRV_PCM_FMTBIT_S16_LE |
+						SNDRV_PCM_FMTBIT_S24_LE),
 			.channels_min = 1,
 			.channels_max = 8,
 			.rate_min =     8000,
-			.rate_max =	48000,
+			.rate_max =	96000,
 		},
 		.capture = {
 			.stream_name = "Multimedia1 Capture",
@@ -78,13 +80,14 @@
 		.playback = {
 			.stream_name = "Multimedia2 Playback",
 			.aif_name = "MM_DL2",
-			.rates = (SNDRV_PCM_RATE_8000_48000|
+			.rates = (SNDRV_PCM_RATE_8000_96000|
 					SNDRV_PCM_RATE_KNOT),
-			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.formats = (SNDRV_PCM_FMTBIT_S16_LE |
+						SNDRV_PCM_FMTBIT_S24_LE),
 			.channels_min = 1,
 			.channels_max = 8,
 			.rate_min =     8000,
-			.rate_max =	48000,
+			.rate_max =	96000,
 		},
 		.capture = {
 			.stream_name = "Multimedia2 Capture",
@@ -154,13 +157,14 @@
 		.playback = {
 			.stream_name = "MultiMedia3 Playback",
 			.aif_name = "MM_DL3",
-			.rates = (SNDRV_PCM_RATE_8000_48000 |
+			.rates = (SNDRV_PCM_RATE_8000_96000 |
 					SNDRV_PCM_RATE_KNOT),
-			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.formats = (SNDRV_PCM_FMTBIT_S16_LE |
+						SNDRV_PCM_FMTBIT_S24_LE),
 			.channels_min = 1,
 			.channels_max = 6,
 			.rate_min =	8000,
-			.rate_max = 48000,
+			.rate_max = 96000,
 		},
 		.ops = &msm_fe_Multimedia_dai_ops,
 		.name = "MultiMedia3",
@@ -169,13 +173,14 @@
 		.playback = {
 			.stream_name = "MultiMedia4 Playback",
 			.aif_name = "MM_DL4",
-			.rates = (SNDRV_PCM_RATE_8000_48000 |
+			.rates = (SNDRV_PCM_RATE_8000_96000 |
 					SNDRV_PCM_RATE_KNOT),
-			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.formats = (SNDRV_PCM_FMTBIT_S16_LE |
+						SNDRV_PCM_FMTBIT_S24_LE),
 			.channels_min = 1,
 			.channels_max = 8,
 			.rate_min =	8000,
-			.rate_max = 48000,
+			.rate_max = 96000,
 		},
 		.capture = {
 			.stream_name = "MultiMedia4 Capture",
@@ -195,13 +200,14 @@
 		.playback = {
 			.stream_name = "MultiMedia5 Playback",
 			.aif_name = "MM_DL5",
-			.rates = (SNDRV_PCM_RATE_8000_48000 |
+			.rates = (SNDRV_PCM_RATE_8000_96000 |
 					SNDRV_PCM_RATE_KNOT),
-			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.formats = (SNDRV_PCM_FMTBIT_S16_LE |
+						SNDRV_PCM_FMTBIT_S24_LE),
 			.channels_min = 1,
 			.channels_max = 8,
 			.rate_min =	8000,
-			.rate_max = 48000,
+			.rate_max = 96000,
 		},
 		.capture = {
 			.stream_name = "MultiMedia5 Capture",
@@ -221,13 +227,14 @@
 		.playback = {
 			.stream_name = "MultiMedia6 Playback",
 			.aif_name = "MM_DL6",
-			.rates = (SNDRV_PCM_RATE_8000_48000 |
+			.rates = (SNDRV_PCM_RATE_8000_96000 |
 					SNDRV_PCM_RATE_KNOT),
-			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.formats = (SNDRV_PCM_FMTBIT_S16_LE |
+						SNDRV_PCM_FMTBIT_S24_LE),
 			.channels_min = 1,
 			.channels_max = 8,
 			.rate_min =	8000,
-			.rate_max = 48000,
+			.rate_max = 96000,
 		},
 		.ops = &msm_fe_Multimedia_dai_ops,
 		.name = "MultiMedia6",
@@ -236,13 +243,14 @@
 		.playback = {
 			.stream_name = "MultiMedia7 Playback",
 			.aif_name = "MM_DL7",
-			.rates = (SNDRV_PCM_RATE_8000_48000 |
+			.rates = (SNDRV_PCM_RATE_8000_96000 |
 					SNDRV_PCM_RATE_KNOT),
-			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.formats = (SNDRV_PCM_FMTBIT_S16_LE |
+						SNDRV_PCM_FMTBIT_S24_LE),
 			.channels_min = 1,
 			.channels_max = 8,
 			.rate_min =	8000,
-			.rate_max = 48000,
+			.rate_max = 96000,
 		},
 		.ops = &msm_fe_Multimedia_dai_ops,
 		.name = "MultiMedia7",
@@ -251,13 +259,14 @@
 		.playback = {
 			.stream_name = "MultiMedia8 Playback",
 			.aif_name = "MM_DL8",
-			.rates = (SNDRV_PCM_RATE_8000_48000 |
+			.rates = (SNDRV_PCM_RATE_8000_96000 |
 					SNDRV_PCM_RATE_KNOT),
-			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.formats = (SNDRV_PCM_FMTBIT_S16_LE |
+						SNDRV_PCM_FMTBIT_S24_LE),
 			.channels_min = 1,
 			.channels_max = 8,
 			.rate_min =	8000,
-			.rate_max = 48000,
+			.rate_max = 96000,
 		},
 		.ops = &msm_fe_Multimedia_dai_ops,
 		.name = "MultiMedia8",
@@ -267,8 +276,9 @@
 		.playback = {
 			.stream_name = "SLIMBUS0 Hostless Playback",
 			.aif_name = "SLIM0_DL_HL",
-			.rates = SNDRV_PCM_RATE_8000_48000,
-			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.rates = SNDRV_PCM_RATE_8000_96000,
+			.formats = (SNDRV_PCM_FMTBIT_S16_LE |
+						SNDRV_PCM_FMTBIT_S24_LE),
 			.channels_min = 1,
 			.channels_max = 8,
 			.rate_min =     8000,
@@ -277,7 +287,7 @@
 		.capture = {
 			.stream_name = "SLIMBUS0 Hostless Capture",
 			.aif_name = "SLIM0_UL_HL",
-			.rates = SNDRV_PCM_RATE_8000_48000,
+			.rates = SNDRV_PCM_RATE_8000_96000,
 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
 			.channels_min = 1,
 			.channels_max = 8,
@@ -291,12 +301,13 @@
 		.playback = {
 			.stream_name = "SLIMBUS1 Hostless Playback",
 			.aif_name = "SLIM1_DL_HL",
-			.rates = SNDRV_PCM_RATE_8000_48000,
-			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.rates = SNDRV_PCM_RATE_8000_96000,
+			.formats = (SNDRV_PCM_FMTBIT_S16_LE |
+						SNDRV_PCM_FMTBIT_S24_LE),
 			.channels_min = 1,
 			.channels_max = 2,
 			.rate_min =     8000,
-			.rate_max =     48000,
+			.rate_max =     96000,
 		},
 		.capture = {
 			.stream_name = "SLIMBUS1 Hostless Capture",
@@ -316,7 +327,8 @@
 			.stream_name = "SLIMBUS3 Hostless Playback",
 			.aif_name = "SLIM3_DL_HL",
 			.rates = SNDRV_PCM_RATE_8000_48000,
-			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.formats = (SNDRV_PCM_FMTBIT_S16_LE |
+						SNDRV_PCM_FMTBIT_S24_LE),
 			.channels_min = 1,
 			.channels_max = 2,
 			.rate_min =     8000,
@@ -339,8 +351,9 @@
 		.playback = {
 			.stream_name = "SLIMBUS4 Hostless Playback",
 			.aif_name = "SLIM4_DL_HL",
-			.rates = SNDRV_PCM_RATE_8000_48000,
-			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.rates = SNDRV_PCM_RATE_8000_96000,
+			.formats = (SNDRV_PCM_FMTBIT_S16_LE |
+						SNDRV_PCM_FMTBIT_S24_LE),
 			.channels_min = 1,
 			.channels_max = 2,
 			.rate_min =     8000,
diff --git a/sound/soc/msm/msm-dai-q6-hdmi.c b/sound/soc/msm/msm-dai-q6-hdmi.c
index 1995f1a..99290a1 100644
--- a/sound/soc/msm/msm-dai-q6-hdmi.c
+++ b/sound/soc/msm/msm-dai-q6-hdmi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/sound/soc/msm/msm-dai-q6.c b/sound/soc/msm/msm-dai-q6.c
index 8cc0eaa..7381677 100644
--- a/sound/soc/msm/msm-dai-q6.c
+++ b/sound/soc/msm/msm-dai-q6.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -743,15 +743,14 @@
 {
 	int rc = 0;
 
+	struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
 	mutex_lock(&aux_pcm_mutex);
-
-	if (aux_pcm_count == 0) {
-		dev_dbg(dai->dev, "%s(): dai->id %d aux_pcm_count is 0. Just"
-				" return\n", __func__, dai->id);
+	dev_dbg(dai->dev, "%s dai->id = %d", __func__, dai->id);
+	if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
 		mutex_unlock(&aux_pcm_mutex);
 		return;
 	}
-
+	clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
 	aux_pcm_count--;
 
 	if (aux_pcm_count > 0) {
@@ -866,24 +865,13 @@
 	unsigned long pcm_clk_rate;
 
 	mutex_lock(&aux_pcm_mutex);
-
-	if (aux_pcm_count == 2) {
-		dev_dbg(dai->dev, "%s(): dai->id %d aux_pcm_count is 2. Just"
-			" return.\n", __func__, dai->id);
-		mutex_unlock(&aux_pcm_mutex);
-		return 0;
-	} else if (aux_pcm_count > 2) {
-		dev_err(dai->dev, "%s(): ERROR: dai->id %d"
-			" aux_pcm_count = %d > 2\n",
-			__func__, dai->id, aux_pcm_count);
-		mutex_unlock(&aux_pcm_mutex);
-		return 0;
-	}
-
+	set_bit(STATUS_PORT_STARTED,
+			dai_data->status_mask);
+	dev_dbg(dai->dev, "%s dai->id = %d", __func__, dai->id);
 	aux_pcm_count++;
-	if (aux_pcm_count == 2)  {
-		dev_dbg(dai->dev, "%s(): dai->id %d aux_pcm_count = %d after "
-			" increment\n", __func__, dai->id, aux_pcm_count);
+	if (aux_pcm_count >= 2) {
+		dev_dbg(dai->dev, "%s(): dai->id %d aux_pcm_count = %d >= 2\n",
+			__func__, dai->id, aux_pcm_count);
 		mutex_unlock(&aux_pcm_mutex);
 		return 0;
 	}
diff --git a/sound/soc/msm/msm-dai-stub.c b/sound/soc/msm/msm-dai-stub.c
index b2bfa2c..c8125e8 100644
--- a/sound/soc/msm/msm-dai-stub.c
+++ b/sound/soc/msm/msm-dai-stub.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/sound/soc/msm/msm-dai.c b/sound/soc/msm/msm-dai.c
index 61e4675..b821814 100644
--- a/sound/soc/msm/msm-dai.c
+++ b/sound/soc/msm/msm-dai.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2011, The Linux Foundation. All rights reserved.
  *
  * Derived from msm-pcm.c and msm7201.c.
  *
diff --git a/sound/soc/msm/msm-lowlatency-pcm-q6.c b/sound/soc/msm/msm-lowlatency-pcm-q6.c
index 98c28aa..6ad1410 100644
--- a/sound/soc/msm/msm-lowlatency-pcm-q6.c
+++ b/sound/soc/msm/msm-lowlatency-pcm-q6.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/sound/soc/msm/msm-multi-ch-pcm-q6.c b/sound/soc/msm/msm-multi-ch-pcm-q6.c
index 6cad0af..10b7e30 100644
--- a/sound/soc/msm/msm-multi-ch-pcm-q6.c
+++ b/sound/soc/msm/msm-multi-ch-pcm-q6.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/sound/soc/msm/msm-mvs.c b/sound/soc/msm/msm-mvs.c
index eca9864..88c0b4e 100644
--- a/sound/soc/msm/msm-mvs.c
+++ b/sound/soc/msm/msm-mvs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. All rights reserved.
  *
  * All source code in this file is licensed under the following license except
  * where indicated.
diff --git a/sound/soc/msm/msm-pcm-afe.c b/sound/soc/msm/msm-pcm-afe.c
index b7b4d51..e01c759 100644
--- a/sound/soc/msm/msm-pcm-afe.c
+++ b/sound/soc/msm/msm-pcm-afe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
@@ -322,8 +322,8 @@
 				(app_cb)q6asm_event_handler, prtd);
 	if (!prtd->audio_client) {
 		pr_debug("%s: Could not allocate memory\n", __func__);
-		kfree(prtd);
 		mutex_unlock(&prtd->lock);
+		kfree(prtd);
 		return -ENOMEM;
 	}
 	hrtimer_init(&prtd->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
diff --git a/sound/soc/msm/msm-pcm-afe.h b/sound/soc/msm/msm-pcm-afe.h
index 9be11f3..674c7b5 100644
--- a/sound/soc/msm/msm-pcm-afe.h
+++ b/sound/soc/msm/msm-pcm-afe.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/sound/soc/msm/msm-pcm-host-voice.c b/sound/soc/msm/msm-pcm-host-voice.c
new file mode 100644
index 0000000..36826cc
--- /dev/null
+++ b/sound/soc/msm/msm-pcm-host-voice.c
@@ -0,0 +1,1318 @@
+/* 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/time.h>
+#include <linux/wait.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <sound/core.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/pcm.h>
+#include <sound/initval.h>
+#include <sound/control.h>
+#include <asm/dma.h>
+
+#include "qdsp6/q6voice.h"
+
+#define HPCM_MAX_Q_LEN 10
+#define HPCM_MIN_VOC_PKT_SIZE 320
+#define HPCM_MAX_VOC_PKT_SIZE 640
+
+#define VOICE_TX_CAPTURE_DAI_ID  "CS-VOICE HOST TX CAPTURE"
+#define VOICE_TX_PLAYBACK_DAI_ID "CS-VOICE HOST TX PLAYBACK"
+#define VOICE_RX_CAPTURE_DAI_ID  "CS-VOICE HOST RX CAPTURE"
+#define VOICE_RX_PLAYBACK_DAI_ID "CS-VOICE HOST RX PLAYBACK"
+
+#define VOLTE_TX_CAPTURE_DAI_ID  "VOLTE HOST TX CAPTURE"
+#define VOLTE_TX_PLAYBACK_DAI_ID "VOLTE HOST TX PLAYBACK"
+#define VOLTE_RX_CAPTURE_DAI_ID  "VOLTE HOST RX CAPTURE"
+#define VOLTE_RX_PLAYBACK_DAI_ID "VOLTE HOST RX PLAYBACK"
+
+enum {
+	RX = 1,
+	TX,
+};
+
+enum {
+	VOICE_INDEX = 0,
+	VOLTE_INDEX,
+	MAX_SESSION
+};
+
+enum hpcm_state {
+	HPCM_STOPPED = 1,
+	HPCM_CLOSED,
+	HPCM_PREPARED,
+	HPCM_STARTED,
+};
+
+struct hpcm_frame {
+	uint32_t len;
+	uint8_t voc_pkt[HPCM_MAX_VOC_PKT_SIZE];
+};
+
+struct hpcm_buf_node {
+	struct list_head list;
+	struct hpcm_frame frame;
+};
+
+struct vocpcm_ion_buffer {
+	/* Physical address */
+	uint32_t paddr;
+	/* Kernel virtual address */
+	uint32_t kvaddr;
+};
+
+struct dai_data {
+	enum  hpcm_state state;
+	struct snd_pcm_substream *substream;
+	struct list_head filled_queue;
+	struct list_head free_queue;
+	wait_queue_head_t queue_wait;
+	spinlock_t dsp_lock;
+	uint32_t pcm_size;
+	uint32_t pcm_count;
+	/* IRQ position */
+	uint32_t pcm_irq_pos;
+	/* Position in buffer */
+	uint32_t pcm_buf_pos;
+	struct vocpcm_ion_buffer vocpcm_ion_buffer;
+};
+
+struct tap_point {
+	struct dai_data playback_dai_data;
+	struct dai_data capture_dai_data;
+	struct ion_handle *ion_handle;
+	int ion_mem_len;
+};
+
+struct session {
+	struct tap_point tx_tap_point;
+	struct tap_point rx_tap_point;
+};
+
+struct tappnt_mxr_data {
+	bool enable;
+	uint16_t direction;
+	uint16_t sample_rate;
+};
+
+/* Values from mixer ctl are cached in this structure */
+struct mixer_conf {
+	uint8_t sess_indx;
+	struct tappnt_mxr_data rx;
+	struct tappnt_mxr_data tx;
+};
+
+struct start_cmd {
+	struct vss_ivpcm_tap_point tap_pnt[2];
+	uint32_t no_of_tapoints;
+};
+
+struct hpcm_drv {
+	struct mutex lock;
+	struct session session[MAX_SESSION];
+	struct mixer_conf mixer_conf;
+	struct ion_client *ion_client;
+	struct start_cmd start_cmd;
+};
+
+static struct hpcm_drv hpcm_drv;
+
+static struct snd_pcm_hardware msm_pcm_hardware = {
+	.info =                 (SNDRV_PCM_INFO_MMAP |
+				SNDRV_PCM_INFO_BLOCK_TRANSFER |
+				SNDRV_PCM_INFO_MMAP_VALID |
+				SNDRV_PCM_INFO_INTERLEAVED),
+	.formats =              SNDRV_PCM_FMTBIT_S16_LE |
+				SNDRV_PCM_FMTBIT_SPECIAL,
+	.rates =                SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
+	.rate_min =             8000,
+	.rate_max =             16000,
+	.channels_min =         1,
+	.channels_max =         1,
+	.buffer_bytes_max =	sizeof(struct hpcm_buf_node) * HPCM_MAX_Q_LEN,
+	.period_bytes_min =	HPCM_MIN_VOC_PKT_SIZE,
+	.period_bytes_max =	HPCM_MAX_VOC_PKT_SIZE,
+	.periods_min =		HPCM_MAX_Q_LEN,
+	.periods_max =		HPCM_MAX_Q_LEN,
+	.fifo_size =            0,
+};
+
+static char *hpcm_get_sess_name(int sess_indx)
+{
+	char *sess_name = NULL;
+
+	if (sess_indx == VOICE_INDEX)
+		sess_name = VOICE_SESSION_NAME;
+	else if (sess_indx == VOLTE_INDEX)
+		sess_name = VOLTE_SESSION_NAME;
+	else
+		pr_err("%s:, Invalid sess_index\n", __func__);
+
+	return sess_name;
+}
+
+static void hpcm_reset_mixer_config(struct hpcm_drv *prtd)
+{
+	prtd->mixer_conf.sess_indx = -1;
+	prtd->mixer_conf.rx.enable = false;
+	prtd->mixer_conf.rx.direction = -1;
+	prtd->mixer_conf.rx.sample_rate = 0;
+
+	prtd->mixer_conf.tx.enable = false;
+	prtd->mixer_conf.tx.direction = -1;
+	prtd->mixer_conf.tx.sample_rate = 0;
+}
+
+/* Check for valid mixer control values */
+static bool hpcm_is_valid_config(int sess_indx, int tap_point,
+				 uint16_t direction, uint16_t samplerate)
+{
+	if (sess_indx < VOICE_INDEX || sess_indx > VOLTE_INDEX) {
+		pr_err("%s: invalid sess_indx :%d\n", __func__, sess_indx);
+		goto error;
+	}
+
+	if (samplerate != VSS_IVPCM_SAMPLING_RATE_8K &&
+	    samplerate != VSS_IVPCM_SAMPLING_RATE_16K) {
+		pr_err("%s: invalid sample rate :%d\n", __func__, samplerate);
+		goto error;
+	}
+
+	if ((tap_point != RX) && (tap_point != TX)) {
+		pr_err("%s: invalid tappoint :%d\n", __func__, tap_point);
+		goto error;
+	}
+
+	if ((direction != VSS_IVPCM_TAP_POINT_DIR_IN) &&
+	    (direction != VSS_IVPCM_TAP_POINT_DIR_OUT) &&
+	    (direction != VSS_IVPCM_TAP_POINT_DIR_OUT_IN)) {
+		pr_err("%s: invalid direction :%d\n", __func__, direction);
+		goto error;
+	}
+
+	return true;
+
+error:
+	return false;
+}
+
+
+static struct dai_data *hpcm_get_dai_data(char *pcm_id, struct hpcm_drv *prtd)
+{
+	struct dai_data *dai_data = NULL;
+	size_t size = 0;
+
+	if (pcm_id) {
+		size = strlen(pcm_id);
+		/* Check for Voice DAI */
+		if (strnstr(pcm_id, VOICE_TX_CAPTURE_DAI_ID, size)) {
+			dai_data =
+		&prtd->session[VOICE_INDEX].tx_tap_point.capture_dai_data;
+		} else if (strnstr(pcm_id, VOICE_TX_PLAYBACK_DAI_ID, size)) {
+			dai_data =
+		&prtd->session[VOICE_INDEX].tx_tap_point.playback_dai_data;
+		} else if (strnstr(pcm_id, VOICE_RX_CAPTURE_DAI_ID, size)) {
+			dai_data =
+		&prtd->session[VOICE_INDEX].rx_tap_point.capture_dai_data;
+		} else if (strnstr(pcm_id, VOICE_RX_PLAYBACK_DAI_ID, size)) {
+			dai_data =
+		&prtd->session[VOICE_INDEX].rx_tap_point.playback_dai_data;
+		/* Check for VoLTE DAI */
+		} else if (strnstr(pcm_id, VOLTE_TX_CAPTURE_DAI_ID, size)) {
+			dai_data =
+		&prtd->session[VOLTE_INDEX].tx_tap_point.capture_dai_data;
+		} else if (strnstr(pcm_id, VOLTE_TX_PLAYBACK_DAI_ID, size)) {
+			dai_data =
+		&prtd->session[VOLTE_INDEX].tx_tap_point.playback_dai_data;
+		} else if (strnstr(pcm_id, VOLTE_RX_CAPTURE_DAI_ID, size)) {
+			dai_data =
+		&prtd->session[VOLTE_INDEX].rx_tap_point.capture_dai_data;
+		} else if (strnstr(pcm_id, VOLTE_RX_PLAYBACK_DAI_ID, size)) {
+			dai_data =
+		&prtd->session[VOLTE_INDEX].rx_tap_point.playback_dai_data;
+		} else {
+			pr_err("%s: Wrong dai id\n", __func__);
+		}
+	}
+
+	return dai_data;
+}
+
+static struct tap_point *hpcm_get_tappoint_data(char *pcm_id,
+						struct hpcm_drv *prtd)
+{
+	struct tap_point *tp = NULL;
+	size_t size = strlen(pcm_id);
+
+	if (pcm_id) {
+		/* Check for Voice DAI */
+		if (strnstr(pcm_id, VOICE_TX_CAPTURE_DAI_ID, size)) {
+			tp = &prtd->session[VOICE_INDEX].tx_tap_point;
+		} else if (strnstr(pcm_id, VOICE_TX_PLAYBACK_DAI_ID, size)) {
+			tp = &prtd->session[VOICE_INDEX].tx_tap_point;
+		} else if (strnstr(pcm_id, VOICE_RX_CAPTURE_DAI_ID, size)) {
+			tp = &prtd->session[VOICE_INDEX].rx_tap_point;
+		} else if (strnstr(pcm_id, VOICE_RX_PLAYBACK_DAI_ID, size)) {
+			tp = &prtd->session[VOICE_INDEX].rx_tap_point;
+		/* Check for VoLTE DAI */
+		} else if (strnstr(pcm_id, VOLTE_TX_CAPTURE_DAI_ID, size)) {
+			tp = &prtd->session[VOLTE_INDEX].tx_tap_point;
+		} else if (strnstr(pcm_id, VOLTE_TX_PLAYBACK_DAI_ID, size)) {
+			tp = &prtd->session[VOLTE_INDEX].tx_tap_point;
+		} else if (strnstr(pcm_id, VOLTE_RX_CAPTURE_DAI_ID, size)) {
+			tp = &prtd->session[VOLTE_INDEX].rx_tap_point;
+		} else if (strnstr(pcm_id, VOLTE_RX_PLAYBACK_DAI_ID, size)) {
+			tp = &prtd->session[VOLTE_INDEX].rx_tap_point;
+		} else {
+			pr_err("%s: wrong dai id\n", __func__);
+		}
+	}
+
+	return tp;
+}
+
+static struct tappnt_mxr_data *hpcm_get_tappnt_mixer_data(char *pcm_id,
+						struct hpcm_drv *prtd)
+{
+
+	if (strnstr(pcm_id, VOICE_TX_CAPTURE_DAI_ID, strlen(pcm_id)) ||
+	    strnstr(pcm_id, VOICE_TX_PLAYBACK_DAI_ID, strlen(pcm_id)) ||
+	    strnstr(pcm_id, VOLTE_TX_CAPTURE_DAI_ID, strlen(pcm_id)) ||
+	    strnstr(pcm_id, VOLTE_TX_PLAYBACK_DAI_ID, strlen(pcm_id))) {
+		return &prtd->mixer_conf.tx;
+	} else {
+		return &prtd->mixer_conf.rx;
+	}
+}
+
+static int get_tappnt_value(char *pcm_id)
+{
+
+	if (strnstr(pcm_id, VOICE_TX_CAPTURE_DAI_ID, strlen(pcm_id)) ||
+	    strnstr(pcm_id, VOICE_TX_PLAYBACK_DAI_ID, strlen(pcm_id)) ||
+	    strnstr(pcm_id, VOLTE_TX_CAPTURE_DAI_ID, strlen(pcm_id)) ||
+	    strnstr(pcm_id, VOLTE_TX_PLAYBACK_DAI_ID, strlen(pcm_id))) {
+		return TX;
+	} else {
+		return RX;
+	}
+}
+
+static bool hpcm_all_dais_are_ready(uint16_t direction, struct tap_point *tp,
+				    enum hpcm_state state)
+{
+	bool dais_started = false;
+
+	/*
+	 * Based on the direction set per tap point in the mixer control,
+	 * all the dais per tap point should meet the required state for the
+	 * commands such as vpcm_map_memory/vpcm_start to be executed.
+	 */
+	switch (direction) {
+	case VSS_IVPCM_TAP_POINT_DIR_OUT_IN:
+		if ((tp->playback_dai_data.state >= state) &&
+		    (tp->capture_dai_data.state >= state)) {
+			dais_started = true;
+		}
+		break;
+
+	case VSS_IVPCM_TAP_POINT_DIR_IN:
+		if (tp->playback_dai_data.state >= state)
+			dais_started = true;
+		break;
+
+	case VSS_IVPCM_TAP_POINT_DIR_OUT:
+		if (tp->capture_dai_data.state >= state)
+			dais_started = true;
+		break;
+
+	default:
+		pr_err("invalid direction\n");
+	}
+
+	return dais_started;
+}
+
+static void hpcm_create_free_queue(struct snd_dma_buffer *dma_buf,
+				   struct dai_data *dai_data)
+{
+	struct hpcm_buf_node *buf_node = NULL;
+	int i = 0, offset = 0;
+
+	for (i = 0; i < HPCM_MAX_Q_LEN; i++) {
+		buf_node = (void *)dma_buf->area + offset;
+		list_add_tail(&buf_node->list,
+				&dai_data->free_queue);
+		offset = offset + sizeof(struct hpcm_buf_node);
+	}
+}
+
+static void hpcm_unmap_and_free_shared_memory(struct hpcm_drv *prtd,
+					      struct tap_point *tp,
+					      uint16_t direction)
+{
+	unsigned long paddr = 0;
+	char *sess = hpcm_get_sess_name(prtd->mixer_conf.sess_indx);
+
+	switch (direction) {
+	case VSS_IVPCM_TAP_POINT_DIR_OUT_IN:
+	case VSS_IVPCM_TAP_POINT_DIR_IN:
+		paddr = tp->playback_dai_data.vocpcm_ion_buffer.paddr;
+		break;
+
+	case VSS_IVPCM_TAP_POINT_DIR_OUT:
+		paddr = tp->capture_dai_data.vocpcm_ion_buffer.paddr;
+		break;
+
+	default:
+		pr_err("Invalid direction\n");
+	}
+
+	if (paddr) {
+		voc_send_cvp_unmap_vocpcm_memory(voc_get_session_id(sess),
+						 paddr);
+		ion_unmap_kernel(prtd->ion_client, tp->ion_handle);
+		ion_free(prtd->ion_client, tp->ion_handle);
+		tp->ion_mem_len = 0;
+		tp->playback_dai_data.vocpcm_ion_buffer.paddr = 0;
+		tp->capture_dai_data.vocpcm_ion_buffer.paddr = 0;
+		tp->playback_dai_data.vocpcm_ion_buffer.kvaddr = 0;
+		tp->capture_dai_data.vocpcm_ion_buffer.kvaddr = 0;
+	}
+
+}
+
+static int hpcm_map_vocpcm_memory(struct hpcm_drv *prtd,
+				  struct tap_point *tp,
+				  struct tappnt_mxr_data *tmd)
+{
+	unsigned long paddr = 0;
+	bool send_cmd = false;
+	int ret = 0;
+	char *sess = hpcm_get_sess_name(prtd->mixer_conf.sess_indx);
+
+	/*
+	 * only one memory map command is sent per tap point, ensure all dais
+	 * for a tap point are in HPCM_PREPARED state.
+	 */
+	send_cmd = hpcm_all_dais_are_ready(tmd->direction, tp, HPCM_PREPARED);
+
+	if (send_cmd == true) {
+		switch (tmd->direction) {
+		case VSS_IVPCM_TAP_POINT_DIR_OUT_IN:
+		case VSS_IVPCM_TAP_POINT_DIR_IN:
+			paddr = tp->playback_dai_data.vocpcm_ion_buffer.paddr;
+			break;
+
+		case VSS_IVPCM_TAP_POINT_DIR_OUT:
+			paddr = tp->capture_dai_data.vocpcm_ion_buffer.paddr;
+			break;
+		}
+
+		ret = voc_send_cvp_map_vocpcm_memory(voc_get_session_id(sess),
+						     paddr, tp->ion_mem_len);
+	}
+
+	return ret;
+
+}
+
+static int hpcm_allocate_shared_memory(struct hpcm_drv *prtd,
+				       struct tap_point *tp,
+				       struct tappnt_mxr_data *tmd)
+{
+	int result;
+	int mem_len;
+	unsigned long paddr;
+	void *kvptr;
+	int ion_mem_reqd = 0;
+	bool create_mem = false;
+
+
+	create_mem = hpcm_all_dais_are_ready(tmd->direction, tp,
+					     HPCM_PREPARED);
+
+	if (create_mem) {
+		if (tmd->direction == VSS_IVPCM_TAP_POINT_DIR_OUT_IN)
+			ion_mem_reqd = HPCM_MAX_VOC_PKT_SIZE * 2;
+		else
+			ion_mem_reqd = HPCM_MAX_VOC_PKT_SIZE;
+
+		tp->ion_handle = ion_alloc(prtd->ion_client,
+					ion_mem_reqd,
+					SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0);
+		if (IS_ERR_OR_NULL((void *) tp->ion_handle)) {
+			pr_err("%s: ION memory allocation failed\n",
+				__func__);
+			goto error;
+		}
+
+		result = ion_phys(prtd->ion_client, tp->ion_handle,
+				&paddr, (size_t *)&mem_len);
+		if (result) {
+			pr_err("%s: ION Get Physical failed, rc = %d\n",
+				__func__, result);
+			goto error;
+		}
+
+		kvptr = ion_map_kernel(prtd->ion_client, tp->ion_handle);
+		if (IS_ERR_OR_NULL(kvptr)) {
+			pr_err("%s: ION memory mapping failed\n", __func__);
+			goto error;
+		}
+
+		switch (tmd->direction)	{
+		case VSS_IVPCM_TAP_POINT_DIR_OUT_IN:
+			tp->playback_dai_data.vocpcm_ion_buffer.paddr =
+							       (uint32_t)paddr;
+			tp->playback_dai_data.vocpcm_ion_buffer.kvaddr =
+						    (uint32_t)(uint8_t *)kvptr;
+			tp->capture_dai_data.vocpcm_ion_buffer.paddr =
+				(uint32_t)paddr + 1 * HPCM_MAX_VOC_PKT_SIZE;
+			tp->capture_dai_data.vocpcm_ion_buffer.kvaddr =
+			(uint32_t)(uint8_t *)kvptr + 1 * HPCM_MAX_VOC_PKT_SIZE;
+			break;
+
+		case VSS_IVPCM_TAP_POINT_DIR_IN:
+			tp->playback_dai_data.vocpcm_ion_buffer.paddr =
+							       (uint32_t)paddr;
+			tp->playback_dai_data.vocpcm_ion_buffer.kvaddr =
+						    (uint32_t)(uint8_t *)kvptr;
+			break;
+
+		case VSS_IVPCM_TAP_POINT_DIR_OUT:
+			tp->capture_dai_data.vocpcm_ion_buffer.paddr =
+							       (uint32_t)paddr;
+			tp->capture_dai_data.vocpcm_ion_buffer.kvaddr =
+						    (uint32_t)(uint8_t *)kvptr;
+			break;
+		}
+
+		tp->ion_mem_len = ion_mem_reqd;
+	}
+
+	return 0;
+
+error:
+	if (tp->ion_handle)
+		ion_free(prtd->ion_client, tp->ion_handle);
+
+	return -ENOMEM;
+}
+
+static int hpcm_start_vocpcm(char *pcm_id, struct hpcm_drv *prtd,
+			     struct tap_point *tp)
+{
+	int indx = prtd->mixer_conf.sess_indx;
+	uint32_t *no_of_tp = &prtd->start_cmd.no_of_tapoints;
+	struct vss_ivpcm_tap_point *tap_pnt = &prtd->start_cmd.tap_pnt[0];
+	uint32_t no_of_tp_req = 0;
+	char *sess = hpcm_get_sess_name(indx);
+
+	if (prtd->mixer_conf.rx.enable)
+		no_of_tp_req++;
+	if (prtd->mixer_conf.tx.enable)
+		no_of_tp_req++;
+
+	if (prtd->mixer_conf.rx.enable && (get_tappnt_value(pcm_id) == RX)) {
+		if (hpcm_all_dais_are_ready(prtd->mixer_conf.rx.direction,
+					    tp, HPCM_PREPARED)) {
+			pr_debug("%s: RX conditions met\n", __func__);
+			tap_pnt[*no_of_tp].tap_point =
+					VSS_IVPCM_TAP_POINT_RX_DEFAULT;
+			tap_pnt[*no_of_tp].direction =
+					prtd->mixer_conf.rx.direction;
+			tap_pnt[*no_of_tp].sampling_rate =
+					prtd->mixer_conf.rx.sample_rate;
+			(*no_of_tp)++;
+		}
+	}
+
+	if (prtd->mixer_conf.tx.enable && (get_tappnt_value(pcm_id) == TX)) {
+		if (hpcm_all_dais_are_ready(prtd->mixer_conf.tx.direction,
+					    tp, HPCM_PREPARED)) {
+			pr_debug("%s: TX conditions met\n", __func__);
+			tap_pnt[*no_of_tp].tap_point =
+						VSS_IVPCM_TAP_POINT_TX_DEFAULT;
+			tap_pnt[*no_of_tp].direction =
+						prtd->mixer_conf.tx.direction;
+			tap_pnt[*no_of_tp].sampling_rate =
+						prtd->mixer_conf.tx.sample_rate;
+			(*no_of_tp)++;
+		}
+	}
+
+	pr_debug("%s: *no_of_tp = %d no_of_tp_req = %d\n",
+		 __func__, *no_of_tp, no_of_tp_req);
+
+	if ((prtd->mixer_conf.tx.enable && prtd->mixer_conf.rx.enable) &&
+	    *no_of_tp == no_of_tp_req) {
+		voc_send_cvp_start_vocpcm(voc_get_session_id(sess),
+					  tap_pnt, *no_of_tp);
+		memset(&prtd->start_cmd, 0, sizeof(struct start_cmd));
+	} else if ((prtd->mixer_conf.tx.enable ||
+		    prtd->mixer_conf.rx.enable) && *no_of_tp == no_of_tp_req) {
+		voc_send_cvp_start_vocpcm(voc_get_session_id(sess),
+					  tap_pnt, *no_of_tp);
+		memset(&prtd->start_cmd, 0, sizeof(struct start_cmd));
+	} else {
+		pr_debug("%s: required pcm handles not opened yet\n", __func__);
+	}
+
+	return 0;
+}
+
+/* Playback path*/
+static void hpcm_copy_playback_data_from_queue(struct dai_data *dai_data,
+					       uint32_t *len)
+{
+	struct hpcm_buf_node *buf_node = NULL;
+	unsigned long dsp_flags;
+
+	if (dai_data->substream == NULL)
+		return;
+
+	spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags);
+
+	if (!list_empty(&dai_data->filled_queue)) {
+		buf_node = list_first_entry(&dai_data->filled_queue,
+				struct hpcm_buf_node, list);
+		list_del(&buf_node->list);
+		*len = buf_node->frame.len;
+		memcpy((uint8_t *)dai_data->vocpcm_ion_buffer.kvaddr,
+		       &buf_node->frame.voc_pkt[0],
+		       buf_node->frame.len);
+
+		list_add_tail(&buf_node->list, &dai_data->free_queue);
+		dai_data->pcm_irq_pos += dai_data->pcm_count;
+		spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags);
+		snd_pcm_period_elapsed(dai_data->substream);
+	} else {
+		*len = 0;
+		spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags);
+		pr_err("IN data not available\n");
+	}
+
+	wake_up(&dai_data->queue_wait);
+}
+
+/* Capture path*/
+static void hpcm_copy_capture_data_to_queue(struct dai_data *dai_data,
+					    uint32_t len)
+{
+	struct hpcm_buf_node *buf_node = NULL;
+	unsigned long dsp_flags;
+
+	if (dai_data->substream == NULL)
+		return;
+
+	/* Copy out buffer packet into free_queue */
+	spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags);
+
+	if (!list_empty(&dai_data->free_queue)) {
+		buf_node = list_first_entry(&dai_data->free_queue,
+					struct hpcm_buf_node, list);
+		list_del(&buf_node->list);
+		buf_node->frame.len = len;
+		memcpy(&buf_node->frame.voc_pkt[0],
+		       (uint8_t *)dai_data->vocpcm_ion_buffer.kvaddr,
+		       buf_node->frame.len);
+		list_add_tail(&buf_node->list, &dai_data->filled_queue);
+		dai_data->pcm_irq_pos += dai_data->pcm_count;
+		spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags);
+		snd_pcm_period_elapsed(dai_data->substream);
+	} else {
+		spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags);
+		pr_err("OUTPUT data dropped\n");
+	}
+
+	wake_up(&dai_data->queue_wait);
+}
+
+void hpcm_notify_evt_processing(uint8_t *data, char *session,
+				void *private_data)
+{
+	struct hpcm_drv *prtd = (struct hpcm_drv *)private_data;
+	struct vss_ivpcm_evt_notify *notify_evt =
+				(struct vss_ivpcm_evt_notify *)data;
+	struct vss_ivpcm_evt_push_buffer push_buff_event;
+	struct tap_point *tp = NULL;
+	int in_buf_len = 0;
+	struct tappnt_mxr_data *tmd = NULL;
+	char *sess = hpcm_get_sess_name(prtd->mixer_conf.sess_indx);
+
+	/* If it's not a timetick, it's a error notification, drop the event */
+	if ((notify_evt->notify_mask & VSS_IVPCM_NOTIFY_MASK_TIMETICK) == 0) {
+		pr_err("%s: Error notification. mask=%d\n", __func__,
+			notify_evt->notify_mask);
+		return;
+	}
+
+	 if (notify_evt->tap_point == VSS_IVPCM_TAP_POINT_TX_DEFAULT) {
+		tp = &prtd->session[prtd->mixer_conf.sess_indx].tx_tap_point;
+		tmd = &prtd->mixer_conf.tx;
+	 } else if (notify_evt->tap_point == VSS_IVPCM_TAP_POINT_RX_DEFAULT) {
+		tp = &prtd->session[prtd->mixer_conf.sess_indx].rx_tap_point;
+		tmd = &prtd->mixer_conf.rx;
+	 }
+
+	 if (notify_evt->notify_mask & VSS_IVPCM_NOTIFY_MASK_OUTPUT_BUFFER) {
+		hpcm_copy_capture_data_to_queue(&tp->capture_dai_data,
+						notify_evt->filled_out_size);
+	 }
+
+	 if (notify_evt->notify_mask & VSS_IVPCM_NOTIFY_MASK_INPUT_BUFFER) {
+		hpcm_copy_playback_data_from_queue(&tp->playback_dai_data,
+						   &in_buf_len);
+	 }
+
+	switch (tmd->direction) {
+	/*
+	 * When the dir is OUT_IN, for the first notify mask, pushbuf mask
+	 * should be set to VSS_IVPCM_PUSH_BUFFER_MASK_OUTPUT_BUFFER since we
+	 * atleast need one buffer's worth data before we can send IN buffer.
+	 * For the consecutive notify evts, the push buf mask will set for both
+	 * VSS_IVPCM_PUSH_BUFFER_MASK_OUTPUT_BUFFER and
+	 * VSS_IVPCM_PUSH_BUFFER_MASK_IN_BUFFER.
+	 */
+	case VSS_IVPCM_TAP_POINT_DIR_OUT_IN:
+		if (notify_evt->notify_mask ==
+		    VSS_IVPCM_NOTIFY_MASK_TIMETICK) {
+			push_buff_event.push_buf_mask =
+				VSS_IVPCM_PUSH_BUFFER_MASK_OUTPUT_BUFFER;
+		} else {
+			push_buff_event.push_buf_mask =
+			   VSS_IVPCM_PUSH_BUFFER_MASK_OUTPUT_BUFFER |
+			   VSS_IVPCM_PUSH_BUFFER_MASK_INPUT_BUFFER;
+		}
+		break;
+
+	case VSS_IVPCM_TAP_POINT_DIR_IN:
+		push_buff_event.push_buf_mask =
+			VSS_IVPCM_PUSH_BUFFER_MASK_INPUT_BUFFER;
+		break;
+
+	case VSS_IVPCM_TAP_POINT_DIR_OUT:
+		push_buff_event.push_buf_mask =
+			 VSS_IVPCM_PUSH_BUFFER_MASK_OUTPUT_BUFFER;
+		break;
+	}
+
+	push_buff_event.tap_point = notify_evt->tap_point;
+	push_buff_event.out_buf_addr =
+				tp->capture_dai_data.vocpcm_ion_buffer.paddr;
+	push_buff_event.in_buf_addr =
+				tp->playback_dai_data.vocpcm_ion_buffer.paddr;
+	push_buff_event.out_buf_size = notify_evt->request_buff_size;
+	push_buff_event.in_buf_size = in_buf_len;
+	push_buff_event.sampling_rate = notify_evt->sampling_rate;
+	push_buff_event.num_in_channels = 1;
+
+	voc_send_cvp_vocpcm_push_buf_evt(voc_get_session_id(sess),
+					 &push_buff_event);
+}
+
+static int msm_hpcm_configure_voice_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+
+	int tap_point = ucontrol->value.integer.value[0];
+	uint16_t direction = ucontrol->value.integer.value[1];
+	uint16_t sample_rate = ucontrol->value.integer.value[2];
+	struct tappnt_mxr_data *tmd = NULL;
+	int ret = 0;
+
+	mutex_lock(&hpcm_drv.lock);
+	pr_debug("%s: tap_point = %d direction = %d sample_rate = %d\n",
+		 __func__, tap_point, direction, sample_rate);
+
+	if (!hpcm_is_valid_config(VOICE_INDEX, tap_point, direction,
+				  sample_rate)) {
+		pr_err("Invalid vpcm mixer control voice values\n");
+		ret = -EINVAL;
+		goto done;
+	}
+
+	if (tap_point == RX)
+		tmd = &hpcm_drv.mixer_conf.rx;
+	else
+		tmd = &hpcm_drv.mixer_conf.tx;
+
+	tmd->enable = true;
+	tmd->direction = direction;
+	tmd->sample_rate = sample_rate;
+	hpcm_drv.mixer_conf.sess_indx = VOICE_INDEX;
+
+done:
+	mutex_unlock(&hpcm_drv.lock);
+	return ret;
+}
+
+static int msm_hpcm_configure_voice_get(struct  snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	pr_debug("%s:\n", __func__);
+	return -EINVAL;
+}
+
+static int msm_hpcm_configure_volte_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+
+	int tap_point = ucontrol->value.integer.value[0];
+	uint16_t direction = ucontrol->value.integer.value[1];
+	uint16_t sample_rate = ucontrol->value.integer.value[2];
+	struct tappnt_mxr_data *tmd = NULL;
+	int ret = 0;
+
+	mutex_lock(&hpcm_drv.lock);
+	pr_debug("%s: tap_point=%d direction=%d sample_rate=%d\n",
+		 __func__, tap_point, direction, sample_rate);
+
+	if (!hpcm_is_valid_config(VOLTE_INDEX, tap_point, direction,
+				  sample_rate)) {
+		pr_err("Invalid vpcm mixer control volte values\n");
+		ret = -EINVAL;
+		goto done;
+	}
+
+	if (tap_point == RX)
+		tmd = &hpcm_drv.mixer_conf.rx;
+	else
+		tmd = &hpcm_drv.mixer_conf.tx;
+
+	tmd->enable = true;
+	tmd->direction = direction;
+	tmd->sample_rate = sample_rate;
+	hpcm_drv.mixer_conf.sess_indx = VOLTE_INDEX;
+
+done:
+	mutex_unlock(&hpcm_drv.lock);
+	return ret;
+
+}
+
+static int msm_hpcm_configure_volte_get(struct  snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	pr_debug("%s:\n", __func__);
+	return -EINVAL;
+}
+
+static struct snd_kcontrol_new msm_hpcm_controls[] = {
+	SOC_SINGLE_MULTI_EXT("HPCM_Voice tappoint direction samplerate",
+			     SND_SOC_NOPM, 0, 16000 , 0, 3,
+			     msm_hpcm_configure_voice_get,
+			     msm_hpcm_configure_voice_put),
+	SOC_SINGLE_MULTI_EXT("HPCM_VoLTE tappoint direction samplerate",
+			     SND_SOC_NOPM, 0, 16000 , 0, 3,
+			     msm_hpcm_configure_volte_get,
+			     msm_hpcm_configure_volte_put),
+};
+
+/* Sample rates supported */
+static unsigned int supported_sample_rates[] = {8000, 16000};
+
+static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
+	.count = ARRAY_SIZE(supported_sample_rates),
+	.list = supported_sample_rates,
+	.mask = 0,
+};
+
+static int msm_pcm_close(struct snd_pcm_substream *substream)
+{
+	int ret = 0;
+	struct list_head *ptr = NULL;
+	struct list_head *next = NULL;
+	struct hpcm_buf_node *buf_node = NULL;
+	struct snd_dma_buffer *dma_buf;
+	struct snd_pcm_runtime *runtime;
+	struct hpcm_drv *prtd;
+	unsigned long dsp_flags;
+	struct dai_data *dai_data = NULL;
+	struct tap_point *tp = NULL;
+	struct tappnt_mxr_data *tmd = NULL;
+	char *sess = NULL;
+
+	if (substream == NULL) {
+		pr_err("substream is NULL\n");
+		return -EINVAL;
+	}
+
+	pr_debug("%s, %s\n", __func__, substream->pcm->id);
+	runtime = substream->runtime;
+	prtd = runtime->private_data;
+	sess = hpcm_get_sess_name(prtd->mixer_conf.sess_indx);
+	dai_data = hpcm_get_dai_data(substream->pcm->id, prtd);
+
+	wake_up(&dai_data->queue_wait);
+	mutex_lock(&prtd->lock);
+
+	tmd = hpcm_get_tappnt_mixer_data(substream->pcm->id, prtd);
+
+	tp = hpcm_get_tappoint_data(substream->pcm->id, prtd);
+	/* Send stop command */
+	voc_send_cvp_stop_vocpcm(voc_get_session_id(sess));
+	/* Unmap will be called twice once for RX and TX each */
+	hpcm_unmap_and_free_shared_memory(prtd, tp, tmd->direction);
+	/* Reset the cached start cmd */
+	memset(&prtd->start_cmd, 0, sizeof(struct start_cmd));
+	/* Release all buffer */
+	pr_debug("%s: Release all buffer\n", __func__);
+	substream = dai_data->substream;
+	if (substream == NULL) {
+		pr_debug("%s: substream is NULL\n", __func__);
+		goto done;
+	}
+	dma_buf = &substream->dma_buffer;
+	if (dma_buf == NULL) {
+		pr_debug("%s: dma_buf is NULL\n", __func__);
+		goto done;
+	}
+	if (dma_buf->area != NULL) {
+		spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags);
+		list_for_each_safe(ptr, next, &dai_data->filled_queue) {
+			buf_node = list_entry(ptr,
+					struct hpcm_buf_node, list);
+			list_del(&buf_node->list);
+		}
+		list_for_each_safe(ptr, next, &dai_data->free_queue) {
+			buf_node = list_entry(ptr,
+					struct hpcm_buf_node, list);
+			list_del(&buf_node->list);
+		}
+		spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags);
+		dma_free_coherent(substream->pcm->card->dev,
+			runtime->hw.buffer_bytes_max, dma_buf->area,
+			dma_buf->addr);
+		dma_buf->area = NULL;
+	}
+	dai_data->substream = NULL;
+	dai_data->pcm_buf_pos = 0;
+	dai_data->pcm_count = 0;
+	dai_data->pcm_irq_pos = 0;
+	dai_data->pcm_size = 0;
+	dai_data->state = HPCM_CLOSED;
+	hpcm_reset_mixer_config(prtd);
+
+done:
+	mutex_unlock(&prtd->lock);
+	return ret;
+}
+
+static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a,
+				 snd_pcm_uframes_t hwoff, void __user *buf,
+				 snd_pcm_uframes_t frames)
+{
+	int ret = 0;
+	struct hpcm_buf_node *buf_node = NULL;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct hpcm_drv *prtd = runtime->private_data;
+	struct dai_data *dai_data = hpcm_get_dai_data(substream->pcm->id, prtd);
+	unsigned long dsp_flags;
+
+	int count = frames_to_bytes(runtime, frames);
+
+	ret = wait_event_interruptible_timeout(dai_data->queue_wait,
+				(!list_empty(&dai_data->free_queue) ||
+				dai_data->state == HPCM_STOPPED),
+				1 * HZ);
+	if (ret > 0) {
+		if (count <= HPCM_MAX_VOC_PKT_SIZE) {
+			spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags);
+			buf_node =
+				list_first_entry(&dai_data->free_queue,
+						struct hpcm_buf_node, list);
+			list_del(&buf_node->list);
+			spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags);
+			ret = copy_from_user(&buf_node->frame, buf, count);
+			buf_node->frame.len = count;
+			spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags);
+			list_add_tail(&buf_node->list, &dai_data->filled_queue);
+			spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags);
+		} else {
+			pr_err("%s: Write cnt %d is > HPCM_MAX_VOC_PKT_SIZE\n",
+				__func__, count);
+			ret = -ENOMEM;
+		}
+	} else if (ret == 0) {
+		pr_err("%s: No free Playback buffer\n", __func__);
+		ret = -ETIMEDOUT;
+	} else {
+		pr_err("%s: playback copy  was interrupted\n", __func__);
+	}
+
+	return  ret;
+}
+static int msm_pcm_capture_copy(struct snd_pcm_substream *substream,
+				int channel, snd_pcm_uframes_t hwoff,
+				void __user *buf, snd_pcm_uframes_t frames)
+{
+	int ret = 0;
+	int count = 0;
+	struct hpcm_buf_node *buf_node = NULL;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct hpcm_drv *prtd = runtime->private_data;
+	struct dai_data *dai_data = hpcm_get_dai_data(substream->pcm->id, prtd);
+	unsigned long dsp_flags;
+
+	count = frames_to_bytes(runtime, frames);
+
+	ret = wait_event_interruptible_timeout(dai_data->queue_wait,
+				(!list_empty(&dai_data->filled_queue) ||
+				dai_data->state == HPCM_STOPPED),
+				1 * HZ);
+
+	if (ret > 0) {
+		if (count <= HPCM_MAX_VOC_PKT_SIZE) {
+			spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags);
+			buf_node = list_first_entry(&dai_data->filled_queue,
+					struct hpcm_buf_node, list);
+			list_del(&buf_node->list);
+			spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags);
+			ret = copy_to_user(buf, &buf_node->frame, count);
+			if (ret) {
+				pr_err("%s: Copy to user retuned %d\n",
+					__func__, ret);
+				ret = -EFAULT;
+			}
+			spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags);
+			list_add_tail(&buf_node->list, &dai_data->free_queue);
+			spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags);
+
+		} else {
+			pr_err("%s: Read count %d > HPCM_MAX_VOC_PKT_SIZE\n",
+				__func__, count);
+			ret = -ENOMEM;
+		}
+
+	} else if (ret == 0) {
+		pr_err("%s: No Caputre data available\n", __func__);
+		ret = -ETIMEDOUT;
+	} else {
+		pr_err("%s: Read was interrupted\n", __func__);
+		ret = -ERESTARTSYS;
+	}
+
+	return ret;
+}
+
+static int msm_pcm_copy(struct snd_pcm_substream *substream, int channel,
+			snd_pcm_uframes_t hwoff, void __user *buf,
+			snd_pcm_uframes_t frames)
+{
+	int ret = 0;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		ret = msm_pcm_playback_copy(substream, channel,
+					    hwoff, buf, frames);
+	else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+		ret = msm_pcm_capture_copy(substream, channel,
+					   hwoff, buf, frames);
+
+	return ret;
+}
+
+static snd_pcm_uframes_t msm_pcm_pointer(struct snd_pcm_substream *substream)
+{
+	struct dai_data *dai_data = NULL;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct hpcm_drv *prtd = runtime->private_data;
+
+	dai_data = hpcm_get_dai_data(substream->pcm->id, prtd);
+
+	if (dai_data->pcm_irq_pos >= dai_data->pcm_size)
+		dai_data->pcm_irq_pos = 0;
+
+	return bytes_to_frames(runtime, (dai_data->pcm_irq_pos));
+}
+
+static int msm_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+	int ret = 0;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct hpcm_drv *prtd = runtime->private_data;
+	struct dai_data *dai_data =
+			hpcm_get_dai_data(substream->pcm->id, prtd);
+
+	pr_debug("%s, %s\n", __func__, substream->pcm->id);
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		pr_debug("SNDRV_PCM_TRIGGER_START\n");
+		dai_data->state = HPCM_STARTED;
+		break;
+
+	case SNDRV_PCM_TRIGGER_STOP:
+		pr_debug("SNDRV_PCM_TRIGGER_STOP\n");
+		dai_data->state = HPCM_STOPPED;
+		break;
+
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+static int msm_pcm_prepare(struct snd_pcm_substream *substream)
+{
+	int ret = 0;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct hpcm_drv *prtd = runtime->private_data;
+	struct dai_data *dai_data = NULL;
+	struct tap_point *tp = NULL;
+	struct tappnt_mxr_data *tmd = NULL;
+
+	pr_debug("%s, %s\n", __func__, substream->pcm->id);
+	mutex_lock(&prtd->lock);
+
+	dai_data = hpcm_get_dai_data(substream->pcm->id, prtd);
+	dai_data->pcm_size  = snd_pcm_lib_buffer_bytes(substream);
+	dai_data->pcm_count = snd_pcm_lib_period_bytes(substream);
+	dai_data->pcm_irq_pos = 0;
+	dai_data->pcm_buf_pos = 0;
+	dai_data->state = HPCM_PREPARED;
+
+	tp = hpcm_get_tappoint_data(substream->pcm->id, prtd);
+	tmd = hpcm_get_tappnt_mixer_data(substream->pcm->id, prtd);
+
+	ret = hpcm_allocate_shared_memory(prtd, tp, tmd);
+	if (ret) {
+		pr_err("error creating shared memory err=%d\n", ret);
+		goto done;
+	}
+	ret = hpcm_map_vocpcm_memory(prtd, tp, tmd);
+	if (ret) {
+		pr_err("error mapping shared memory err=%d\n", ret);
+		goto done;
+	}
+
+	ret = hpcm_start_vocpcm(substream->pcm->id, prtd,
+				hpcm_get_tappoint_data(substream->pcm->id,
+						       prtd));
+	if (ret) {
+		pr_err("error sending start cmd err=%d\n", ret);
+		goto done;
+	}
+
+done:
+	mutex_unlock(&prtd->lock);
+	return ret;
+}
+
+static int msm_pcm_hw_params(struct snd_pcm_substream *substream,
+			     struct snd_pcm_hw_params *params)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_dma_buffer *dma_buf = &substream->dma_buffer;
+	struct hpcm_drv *prtd = (struct hpcm_drv *)runtime->private_data;
+	int ret = 0;
+
+	pr_debug("%s: %s\n", __func__, substream->pcm->id);
+
+	mutex_lock(&prtd->lock);
+
+	dma_buf->dev.type = SNDRV_DMA_TYPE_DEV;
+	dma_buf->dev.dev = substream->pcm->card->dev;
+	dma_buf->private_data = NULL;
+
+	dma_buf->area = dma_alloc_coherent(substream->pcm->card->dev,
+			runtime->hw.buffer_bytes_max,
+			&dma_buf->addr, GFP_KERNEL);
+
+	if (!dma_buf->area) {
+		pr_err("%s:MSM dma_alloc failed\n", __func__);
+		ret = -ENOMEM;
+		goto done;
+	}
+
+	dma_buf->bytes = runtime->hw.buffer_bytes_max;
+	memset(dma_buf->area, 0, runtime->hw.buffer_bytes_max);
+
+	hpcm_create_free_queue(dma_buf,
+		hpcm_get_dai_data(substream->pcm->id, prtd));
+
+	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+
+done:
+	mutex_unlock(&prtd->lock);
+	return ret;
+}
+
+static int msm_pcm_open(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct hpcm_drv *prtd = &hpcm_drv;
+	struct tappnt_mxr_data *tmd = NULL;
+	struct dai_data *dai_data = NULL;
+	int ret = 0;
+	int tp_val = 0;
+
+	pr_debug("%s, %s\n", __func__, substream->pcm->id);
+	mutex_lock(&prtd->lock);
+
+	runtime->hw = msm_pcm_hardware;
+
+	ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+					 &constraints_sample_rates);
+	if (ret < 0)
+		pr_debug("snd_pcm_hw_constraint_list failed\n");
+
+	ret = snd_pcm_hw_constraint_integer(runtime,
+					    SNDRV_PCM_HW_PARAM_PERIODS);
+	if (ret < 0) {
+		pr_debug("snd_pcm_hw_constraint_integer failed\n");
+		goto done;
+	}
+
+	tp_val = get_tappnt_value(substream->pcm->id);
+	tmd = hpcm_get_tappnt_mixer_data(substream->pcm->id, prtd);
+
+	/*Check whehter the kcontrol values set are valid*/
+	if (!tmd ||
+	    !(tmd->enable) ||
+	    !hpcm_is_valid_config(prtd->mixer_conf.sess_indx,
+				  tp_val, tmd->direction,
+				  tmd->sample_rate)) {
+		ret = -EINVAL;
+		goto done;
+	}
+
+	dai_data = hpcm_get_dai_data(substream->pcm->id, prtd);
+	dai_data->substream = substream;
+	runtime->private_data = prtd;
+
+done:
+	mutex_unlock(&prtd->lock);
+	return ret;
+}
+
+static struct snd_pcm_ops msm_pcm_ops = {
+	.open           = msm_pcm_open,
+	.hw_params      = msm_pcm_hw_params,
+	.prepare        = msm_pcm_prepare,
+	.trigger        = msm_pcm_trigger,
+	.pointer        = msm_pcm_pointer,
+	.copy           = msm_pcm_copy,
+	.close          = msm_pcm_close,
+};
+
+static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_card *card = rtd->card->snd_card;
+
+	pr_debug("%s:\n", __func__);
+	if (!card->dev->coherent_dma_mask)
+		card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
+
+	return 0;
+}
+
+static int msm_pcm_hpcm_probe(struct snd_soc_platform *platform)
+{
+	snd_soc_add_platform_controls(platform, msm_hpcm_controls,
+				ARRAY_SIZE(msm_hpcm_controls));
+
+	return 0;
+}
+
+static struct snd_soc_platform_driver msm_soc_platform = {
+	.ops		= &msm_pcm_ops,
+	.pcm_new	= msm_asoc_pcm_new,
+	.probe		= msm_pcm_hpcm_probe,
+};
+
+static __devinit int msm_pcm_probe(struct platform_device *pdev)
+{
+	pr_info("%s: dev name %s\n", __func__, dev_name(&pdev->dev));
+	return snd_soc_register_platform(&pdev->dev, &msm_soc_platform);
+}
+
+static int msm_pcm_remove(struct platform_device *pdev)
+{
+	snd_soc_unregister_platform(&pdev->dev);
+	return 0;
+}
+
+static struct platform_driver msm_pcm_driver = {
+	.driver = {
+		.name = "msm-host-pcm-voice",
+		.owner = THIS_MODULE,
+	},
+	.probe = msm_pcm_probe,
+	.remove = __devexit_p(msm_pcm_remove),
+};
+
+static int __init msm_soc_platform_init(void)
+{
+	int i = 0;
+	struct session *s = NULL;
+
+	memset(&hpcm_drv, 0, sizeof(hpcm_drv));
+	mutex_init(&hpcm_drv.lock);
+
+	hpcm_drv.ion_client = msm_ion_client_create(UINT_MAX, "host_voice_pcm");
+	if (IS_ERR_OR_NULL((void *)hpcm_drv.ion_client)) {
+		pr_err("%s: ION create client failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < MAX_SESSION; i++) {
+		s = &hpcm_drv.session[i];
+		spin_lock_init(&s->rx_tap_point.capture_dai_data.dsp_lock);
+		spin_lock_init(&s->rx_tap_point.playback_dai_data.dsp_lock);
+		spin_lock_init(&s->tx_tap_point.capture_dai_data.dsp_lock);
+		spin_lock_init(&s->tx_tap_point.playback_dai_data.dsp_lock);
+
+		init_waitqueue_head(
+			&s->rx_tap_point.capture_dai_data.queue_wait);
+		init_waitqueue_head(
+			&s->rx_tap_point.playback_dai_data.queue_wait);
+		init_waitqueue_head(
+			&s->tx_tap_point.capture_dai_data.queue_wait);
+		init_waitqueue_head(
+			&s->tx_tap_point.playback_dai_data.queue_wait);
+
+		INIT_LIST_HEAD(&s->rx_tap_point.capture_dai_data.filled_queue);
+		INIT_LIST_HEAD(&s->rx_tap_point.capture_dai_data.free_queue);
+		INIT_LIST_HEAD(&s->rx_tap_point.playback_dai_data.filled_queue);
+		INIT_LIST_HEAD(&s->rx_tap_point.playback_dai_data.free_queue);
+
+		INIT_LIST_HEAD(&s->tx_tap_point.capture_dai_data.filled_queue);
+		INIT_LIST_HEAD(&s->tx_tap_point.capture_dai_data.free_queue);
+		INIT_LIST_HEAD(&s->tx_tap_point.playback_dai_data.filled_queue);
+		INIT_LIST_HEAD(&s->tx_tap_point.playback_dai_data.free_queue);
+	}
+
+	voc_register_hpcm_evt_cb(hpcm_notify_evt_processing, &hpcm_drv);
+
+	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 module platform driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/msm/msm-pcm-hostless.c b/sound/soc/msm/msm-pcm-hostless.c
index c9b23d0..789749f 100644
--- a/sound/soc/msm/msm-pcm-hostless.c
+++ b/sound/soc/msm/msm-pcm-hostless.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/sound/soc/msm/msm-pcm-lpa.c b/sound/soc/msm/msm-pcm-lpa.c
index ff0fb3b..6f1a01d 100644
--- a/sound/soc/msm/msm-pcm-lpa.c
+++ b/sound/soc/msm/msm-pcm-lpa.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -331,7 +331,7 @@
 	atomic_set(&prtd->stop, 1);
 	runtime->private_data = prtd;
 	lpa_audio.prtd = prtd;
-	lpa_set_volume(lpa_audio.volume);
+	lpa_set_volume(0);
 	ret = q6asm_set_softpause(lpa_audio.prtd->audio_client, &softpause);
 	if (ret < 0)
 		pr_err("%s: Send SoftPause Param failed ret=%d\n",
@@ -511,11 +511,10 @@
 		pr_debug("SNDRV_COMPRESS_TSTAMP\n");
 
 		memset(&tstamp, 0x0, sizeof(struct snd_compr_tstamp));
-		timestamp = q6asm_get_session_time(prtd->audio_client);
-		if (timestamp < 0) {
-			pr_err("%s: Get Session Time return value =%lld\n",
-				__func__, timestamp);
-			return -EAGAIN;
+		rc = q6asm_get_session_time(prtd->audio_client, &timestamp);
+		if (rc < 0) {
+			pr_err("%s: fail to get session tstamp\n", __func__);
+			return rc;
 		}
 		temp = (timestamp * 2 * runtime->channels);
 		temp = temp * (runtime->rate/1000);
diff --git a/sound/soc/msm/msm-pcm-q6.c b/sound/soc/msm/msm-pcm-q6.c
index 74136dc..c326437 100644
--- a/sound/soc/msm/msm-pcm-q6.c
+++ b/sound/soc/msm/msm-pcm-q6.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
@@ -97,6 +97,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)
 {
@@ -143,18 +162,33 @@
 			pr_debug("cmd[%d]=0x%08x\n", i, *ptrmem);
 		in_frame_info[token][0] = payload[2];
 		in_frame_info[token][1] = payload[3];
-		prtd->pcm_irq_pos += in_frame_info[token][0];
-		pr_debug("pcm_irq_pos=%d\n", prtd->pcm_irq_pos);
-		if (atomic_read(&prtd->start))
-			snd_pcm_period_elapsed(substream);
-		if (atomic_read(&prtd->in_count) <= prtd->periods)
-			atomic_inc(&prtd->in_count);
-		wake_up(&the_locks.read_wait);
-		if (prtd->mmap_flag
-			&& q6asm_is_cpu_buf_avail_nolock(OUT,
+
+		/* assume data size = 0 during flushing */
+		if (in_frame_info[token][0]) {
+			prtd->pcm_irq_pos += in_frame_info[token][0];
+			pr_debug("pcm_irq_pos=%d\n", prtd->pcm_irq_pos);
+			if (atomic_read(&prtd->start))
+				snd_pcm_period_elapsed(substream);
+			if (atomic_read(&prtd->in_count) <= prtd->periods)
+				atomic_inc(&prtd->in_count);
+			wake_up(&the_locks.read_wait);
+			if (prtd->mmap_flag &&
+			    q6asm_is_cpu_buf_avail_nolock(OUT,
 				prtd->audio_client,
 				&size, &idx))
-			q6asm_read_nolock(prtd->audio_client);
+				q6asm_read_nolock(prtd->audio_client);
+		} else {
+			pr_debug("%s: reclaim flushed buf in_count %x\n",
+				 __func__, atomic_read(&prtd->in_count));
+			atomic_inc(&prtd->in_count);
+			if (atomic_read(&prtd->in_count) == prtd->periods) {
+				pr_info("%s: reclaimed all bufs\n", __func__);
+				if (atomic_read(&prtd->start))
+					snd_pcm_period_elapsed(substream);
+				wake_up(&the_locks.read_wait);
+			}
+		}
+
 		break;
 	}
 	case APR_BASIC_RSP_RESULT: {
@@ -627,6 +661,7 @@
 	struct audio_buffer *buf;
 	int dir, ret;
 	int format = FORMAT_LINEAR_PCM;
+	struct msm_pcm_routing_evt event;
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 		dir = IN;
@@ -650,10 +685,13 @@
 		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,
-			prtd->audio_client->perf_mode,
-			prtd->session_id, substream->stream);
-		}
+		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, event);
+	}
 
 	ret = q6asm_audio_client_buf_alloc_contiguous(dir,
 			prtd->audio_client,
diff --git a/sound/soc/msm/msm-pcm-q6.h b/sound/soc/msm/msm-pcm-q6.h
index 86e5c54..f9c1a12 100644
--- a/sound/soc/msm/msm-pcm-q6.h
+++ b/sound/soc/msm/msm-pcm-q6.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2008-2009,2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009,2011 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 841d313..6cf74d5 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -41,6 +41,12 @@
 	bool perf_mode;
 };
 
+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
@@ -71,6 +77,10 @@
 static const DECLARE_TLV_DB_LINEAR(multimedia5_rx_vol_gain, 0,
 			INT_RX_VOL_MAX_STEPS);
 
+static int msm_route_multimedia3_vol_control;
+static const DECLARE_TLV_DB_LINEAR(multimedia3_rx_vol_gain, 0,
+			INT_RX_VOL_MAX_STEPS);
+
 static int msm_route_compressed_vol_control;
 static const DECLARE_TLV_DB_LINEAR(compressed_rx_vol_gain, 0,
 			INT_RX_VOL_MAX_STEPS);
@@ -78,6 +88,10 @@
 static int msm_route_compressed2_vol_control;
 static const DECLARE_TLV_DB_LINEAR(compressed2_rx_vol_gain, 0,
 			INT_RX_VOL_MAX_STEPS);
+
+static int msm_route_compressed3_vol_control;
+static const DECLARE_TLV_DB_LINEAR(compressed3_rx_vol_gain, 0,
+			INT_RX_VOL_MAX_STEPS);
 static int msm_route_ec_ref_rx;
 
 /* Equal to Frontend after last of the MULTIMEDIA SESSIONS */
@@ -234,25 +248,35 @@
 
 
 /* Track ASM playback & capture sessions of DAI */
-static int fe_dai_map[MSM_FRONTEND_DAI_MM_SIZE][2] = {
+static struct msm_pcm_routing_fdai_data
+	fe_dai_map[MSM_FRONTEND_DAI_MM_SIZE][2] = {
 	/* MULTIMEDIA1 */
-	{INVALID_SESSION, INVALID_SESSION},
+	{{0, INVALID_SESSION, {NULL, NULL} },
+	{0, INVALID_SESSION, {NULL, NULL} } },
 	/* MULTIMEDIA2 */
-	{INVALID_SESSION, INVALID_SESSION},
+	{{0, INVALID_SESSION, {NULL, NULL} },
+	{0, INVALID_SESSION, {NULL, NULL} } },
 	/* MULTIMEDIA3 */
-	{INVALID_SESSION, INVALID_SESSION},
+	{{0, INVALID_SESSION, {NULL, NULL} },
+	{0, INVALID_SESSION, {NULL, NULL} } },
 	/* MULTIMEDIA4 */
-	{INVALID_SESSION, INVALID_SESSION},
+	{{0, INVALID_SESSION, {NULL, NULL} },
+	{0, INVALID_SESSION,  {NULL, NULL} } },
 	/* MULTIMEDIA5 */
-	{INVALID_SESSION, INVALID_SESSION},
+	{{0, INVALID_SESSION, {NULL, NULL} },
+	{0, INVALID_SESSION, {NULL, NULL} } },
 	/* MULTIMEDIA6 */
-	{INVALID_SESSION, INVALID_SESSION},
+	{{0, INVALID_SESSION, {NULL, NULL} },
+	{0, INVALID_SESSION, {NULL, NULL} } },
 	/* MULTIMEDIA7*/
-	{INVALID_SESSION, INVALID_SESSION},
+	{{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} } },
 	/* PSEUDO */
-	{INVALID_SESSION, INVALID_SESSION},
+	{{0, INVALID_SESSION, {NULL, NULL} },
+	{0, INVALID_SESSION, {NULL, NULL} } },
 };
 
 static uint8_t is_be_dai_extproc(int be_dai)
@@ -312,10 +336,12 @@
 	}
 
 	mutex_lock(&routing_lock);
+
 	if (enable)
-		fe_dai_map[fedai_id][session_type] = dspst_id;
+		fe_dai_map[fedai_id][session_type].strm_id = dspst_id;
 	else
-		fe_dai_map[fedai_id][session_type] = INVALID_SESSION;
+		fe_dai_map[fedai_id][session_type].strm_id = INVALID_SESSION;
+
 	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) &&
@@ -414,7 +440,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;
 	/* re-enable EQ if active */
 	if (eq_data[fedai_id].enable)
 		msm_send_eq_values(fedai_id);
@@ -464,6 +490,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_pseudo_stream(int fedai_id, int dspst_id)
 {
@@ -522,8 +561,8 @@
 		}
 	}
 
-	fe_dai_map[fedai_id][session_type] = INVALID_SESSION;
-
+	fe_dai_map[fedai_id][session_type].strm_id = INVALID_SESSION;
+	fe_dai_map[fedai_id][session_type].be_srate = 0;
 	mutex_unlock(&routing_lock);
 }
 
@@ -548,6 +587,7 @@
 {
 	int session_type, path_type;
 	u32 channels;
+	struct msm_pcm_routing_fdai_data *fdai;
 
 	pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
 
@@ -574,11 +614,24 @@
 			voc_start_playback(set);
 
 		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 due 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 ((session_type == SESSION_TYPE_RX) &&
 				((channels == 1) || (channels == 2))
 				&& msm_bedais[reg].perf_mode) {
@@ -606,7 +659,7 @@
 
 
 			msm_pcm_routing_build_matrix(val,
-				fe_dai_map[val][session_type], path_type);
+				fdai->strm_id, path_type);
 			srs_port_id = msm_bedais[reg].port_id;
 			srs_send_params(srs_port_id, 1, 0);
 		}
@@ -615,11 +668,13 @@
 			(msm_bedais[reg].port_id == VOICE_PLAYBACK_TX))
 			voc_start_playback(set);
 		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) {
+			fdai->be_srate = msm_bedais[reg].sample_rate;
 			adm_close(msm_bedais[reg].port_id);
 			msm_pcm_routing_build_matrix(val,
-				fe_dai_map[val][session_type], path_type);
+				fdai->strm_id, path_type);
 		}
 	}
 	if ((msm_bedais[reg].port_id == VOICE_RECORD_RX)
@@ -982,6 +1037,23 @@
 	return 0;
 }
 
+static int msm_routing_get_multimedia3_vol_mixer(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	ucontrol->value.integer.value[0] = msm_route_multimedia3_vol_control;
+	return 0;
+}
+
+static int msm_routing_set_multimedia3_vol_mixer(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	if (!multi_ch_pcm_set_volume(ucontrol->value.integer.value[0]))
+		msm_route_multimedia3_vol_control =
+			ucontrol->value.integer.value[0];
+
+	return 0;
+}
+
 static int msm_routing_get_compressed_vol_mixer(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
@@ -1016,6 +1088,22 @@
 	return 0;
 }
 
+static int msm_routing_get_compressed3_vol_mixer(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	ucontrol->value.integer.value[0] = msm_route_compressed3_vol_control;
+	return 0;
+}
+
+static int msm_routing_set_compressed3_vol_mixer(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	if (!compressed_set_volume(ucontrol->value.integer.value[0]))
+		msm_route_compressed3_vol_control =
+			ucontrol->value.integer.value[0];
+	return 0;
+}
+
 static int msm_routing_get_srs_trumedia_control(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
@@ -1171,12 +1259,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;
 	}
 
@@ -2124,6 +2212,12 @@
 	msm_routing_set_multimedia5_vol_mixer, multimedia5_rx_vol_gain),
 };
 
+static const struct snd_kcontrol_new multimedia3_vol_mixer_controls[] = {
+	SOC_SINGLE_EXT_TLV("HIFI4 RX Volume", SND_SOC_NOPM, 0,
+	INT_RX_VOL_GAIN, 0, msm_routing_get_multimedia3_vol_mixer,
+	msm_routing_set_multimedia3_vol_mixer, multimedia3_rx_vol_gain),
+};
+
 static const struct snd_kcontrol_new compressed_vol_mixer_controls[] = {
 	SOC_SINGLE_EXT_TLV("COMPRESSED RX Volume", SND_SOC_NOPM, 0,
 	INT_RX_VOL_GAIN, 0, msm_routing_get_compressed_vol_mixer,
@@ -2136,6 +2230,12 @@
 	msm_routing_set_compressed2_vol_mixer, compressed2_rx_vol_gain),
 };
 
+static const struct snd_kcontrol_new compressed3_vol_mixer_controls[] = {
+	SOC_SINGLE_EXT_TLV("COMPRESSED3 RX Volume", SND_SOC_NOPM, 0,
+	INT_RX_VOL_GAIN, 0, msm_routing_get_compressed3_vol_mixer,
+	msm_routing_set_compressed3_vol_mixer, compressed3_rx_vol_gain),
+};
+
 static const struct snd_kcontrol_new lpa_SRS_trumedia_controls[] = {
 	{.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "SRS TruMedia",
@@ -3028,7 +3128,9 @@
 	mutex_lock(&routing_lock);
 
 	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);
 			srs_port_id = -1;
 		}
@@ -3051,6 +3153,7 @@
 	struct msm_pcm_routing_bdai_data *bedai;
 	u32 channels;
 	bool playback, capture;
+	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);
@@ -3082,7 +3185,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 due 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->port_id == PSEUDOPORT_01) {
 				adm_multi_ch_copp_pseudo_open_v3(bedai->port_id,
@@ -3116,7 +3233,7 @@
 				DEFAULT_COPP_TOPOLOGY);
 
 			msm_pcm_routing_build_matrix(i,
-				fe_dai_map[i][session_type], path_type);
+				fdai->strm_id, path_type);
 			srs_port_id = bedai->port_id;
 			srs_send_params(srs_port_id, 1, 0);
 		}
@@ -3188,13 +3305,22 @@
 			ARRAY_SIZE(multimedia5_vol_mixer_controls));
 
 	snd_soc_add_platform_controls(platform,
+				multimedia3_vol_mixer_controls,
+			ARRAY_SIZE(multimedia3_vol_mixer_controls));
+
+	snd_soc_add_platform_controls(platform,
 				compressed_vol_mixer_controls,
 			ARRAY_SIZE(compressed_vol_mixer_controls));
+
 	snd_soc_add_platform_controls(platform,
 				compressed2_vol_mixer_controls,
 			ARRAY_SIZE(compressed2_vol_mixer_controls));
 
 	snd_soc_add_platform_controls(platform,
+				compressed3_vol_mixer_controls,
+			ARRAY_SIZE(compressed3_vol_mixer_controls));
+
+	snd_soc_add_platform_controls(platform,
 				lpa_SRS_trumedia_controls,
 			ARRAY_SIZE(lpa_SRS_trumedia_controls));
 
diff --git a/sound/soc/msm/msm-pcm-routing.h b/sound/soc/msm/msm-pcm-routing.h
index 0c0d3b4..b571483 100644
--- a/sound/soc/msm/msm-pcm-routing.h
+++ b/sound/soc/msm/msm-pcm-routing.h
@@ -113,6 +113,10 @@
 	MSM_BACKEND_DAI_MAX,
 };
 
+enum msm_pcm_routing_event {
+	MSM_PCM_RT_EVT_BUF_RECFG,
+	MSM_PCM_RT_EVT_MAX,
+};
 /* dai_id: front-end ID,
  * dspst_id:  DSP audio stream ID
  * stream_type: playback or capture
@@ -128,6 +132,15 @@
 
 void msm_pcm_routing_dereg_pseudo_stream(int fedai_id, int dspst_id);
 
+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 lpa_set_volume(unsigned volume);
diff --git a/sound/soc/msm/msm-pcm-voice.c b/sound/soc/msm/msm-pcm-voice.c
index c5e2f09..ac5bc34 100644
--- a/sound/soc/msm/msm-pcm-voice.c
+++ b/sound/soc/msm/msm-pcm-voice.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -325,6 +325,44 @@
 	return 0;
 }
 
+static int msm_voice_topology_disable_get(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_value *ucontrol)
+{
+	ucontrol->value.integer.value[0] = 0;
+	return 0;
+}
+
+static int msm_voice_topology_disable_put(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_value *ucontrol)
+{
+	int disable = ucontrol->value.integer.value[0];
+
+	pr_debug("%s: disable = %d\n", __func__, disable);
+
+	return voc_disable_topology(voc_get_session_id(VOICE_SESSION_NAME),
+					 disable);
+
+}
+
+static int msm_volte_topology_disable_get(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_value *ucontrol)
+{
+	ucontrol->value.integer.value[0] = 0;
+	return 0;
+}
+
+static int msm_volte_topology_disable_put(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_value *ucontrol)
+{
+	int disable = ucontrol->value.integer.value[0];
+
+	pr_debug("%s: disable = %d\n", __func__, disable);
+
+	return voc_disable_topology(voc_get_session_id(VOLTE_SESSION_NAME),
+					 disable);
+
+}
+
 static int msm_voice_mute_get(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
@@ -546,6 +584,9 @@
 				msm_voice_mute_get, msm_voice_mute_put),
 	SOC_SINGLE_EXT("Voice Rx Volume", SND_SOC_NOPM, 0, 5, 0,
 				msm_voice_volume_get, msm_voice_volume_put),
+	SOC_SINGLE_EXT("Voice Topology Disable", SND_SOC_NOPM, 0, 1, 0,
+		       msm_voice_topology_disable_get,
+		       msm_voice_topology_disable_put),
 	SOC_ENUM_EXT("TTY Mode", msm_tty_mode_enum[0], msm_voice_tty_mode_get,
 				msm_voice_tty_mode_put),
 	SOC_SINGLE_EXT("Widevoice Enable", SND_SOC_NOPM, 0, 1, 0,
@@ -561,6 +602,9 @@
 				msm_volte_mute_get, msm_volte_mute_put),
 	SOC_SINGLE_EXT("VoLTE Rx Volume", SND_SOC_NOPM, 0, 5, 0,
 				msm_volte_volume_get, msm_volte_volume_put),
+	SOC_SINGLE_EXT("VoLTE Topology Disable", SND_SOC_NOPM, 0, 1, 0,
+		       msm_volte_topology_disable_get,
+		       msm_volte_topology_disable_put),
 	SOC_SINGLE_EXT("SGLTE Rx Device Mute", SND_SOC_NOPM, 0, 1, 0,
 				msm_sglte_rx_device_mute_get,
 				msm_sglte_rx_device_mute_put),
diff --git a/sound/soc/msm/msm-pcm-voice.h b/sound/soc/msm/msm-pcm-voice.h
index 41aca89..6eb2060 100644
--- a/sound/soc/msm/msm-pcm-voice.h
+++ b/sound/soc/msm/msm-pcm-voice.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011,2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011,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
diff --git a/sound/soc/msm/msm-pcm-voip.c b/sound/soc/msm/msm-pcm-voip.c
index 4d2b253..22bc9e1 100644
--- a/sound/soc/msm/msm-pcm-voip.c
+++ b/sound/soc/msm/msm-pcm-voip.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -155,7 +155,8 @@
 };
 
 static int voip_get_media_type(uint32_t mode, uint32_t rate_type,
-				unsigned int samp_rate);
+				unsigned int samp_rate,
+				uint32_t *media_type);
 static int voip_get_rate_type(uint32_t mode,
 				uint32_t rate,
 				uint32_t *rate_type);
@@ -934,12 +935,12 @@
 			goto done;
 		}
 		prtd->rate_type = rate_type;
-		media_type = voip_get_media_type(prtd->mode,
-						prtd->rate_type,
-						prtd->play_samp_rate);
-		if (media_type < 0) {
+		ret = voip_get_media_type(prtd->mode,
+					  prtd->rate_type,
+					  prtd->play_samp_rate,
+					  &media_type);
+		if (ret < 0) {
 			pr_err("fail at getting media_type\n");
-			ret = -EINVAL;
 			goto done;
 		}
 		pr_debug(" media_type=%d, rate_type=%d\n", media_type,
@@ -1210,49 +1211,50 @@
 }
 
 static int voip_get_media_type(uint32_t mode, uint32_t rate_type,
-				unsigned int samp_rate)
+				unsigned int samp_rate,
+				uint32_t *media_type)
 {
-	uint32_t media_type;
+	int ret = 0;
 
 	pr_debug("%s: mode=%d, samp_rate=%d\n", __func__,
 		mode, samp_rate);
 	switch (mode) {
 	case MODE_AMR:
-		media_type = VSS_MEDIA_ID_AMR_NB_MODEM;
+		*media_type = VSS_MEDIA_ID_AMR_NB_MODEM;
 		break;
 	case MODE_AMR_WB:
-		media_type = VSS_MEDIA_ID_AMR_WB_MODEM;
+		*media_type = VSS_MEDIA_ID_AMR_WB_MODEM;
 		break;
 	case MODE_PCM:
 		if (samp_rate == 8000)
-			media_type = VSS_MEDIA_ID_PCM_NB;
+			*media_type = VSS_MEDIA_ID_PCM_NB;
 		else
-			media_type = VSS_MEDIA_ID_PCM_WB;
+			*media_type = VSS_MEDIA_ID_PCM_WB;
 		break;
 	case MODE_IS127: /* EVRC-A */
-		media_type = VSS_MEDIA_ID_EVRC_MODEM;
+		*media_type = VSS_MEDIA_ID_EVRC_MODEM;
 		break;
 	case MODE_4GV_NB: /* EVRC-B */
-		media_type = VSS_MEDIA_ID_4GV_NB_MODEM;
+		*media_type = VSS_MEDIA_ID_4GV_NB_MODEM;
 		break;
 	case MODE_4GV_WB: /* EVRC-WB */
-		media_type = VSS_MEDIA_ID_4GV_WB_MODEM;
+		*media_type = VSS_MEDIA_ID_4GV_WB_MODEM;
 		break;
 	case MODE_G711:
 	case MODE_G711A:
 		if (rate_type == MVS_G711A_MODE_MULAW)
-			media_type = VSS_MEDIA_ID_G711_MULAW;
+			*media_type = VSS_MEDIA_ID_G711_MULAW;
 		else
-			media_type = VSS_MEDIA_ID_G711_ALAW;
+			*media_type = VSS_MEDIA_ID_G711_ALAW;
 		break;
 	default:
 		pr_debug(" input mode is not supported\n");
-		media_type = -EINVAL;
+		ret = -EINVAL;
 	}
 
-	pr_debug("%s: media_type is 0x%x\n", __func__, media_type);
+	pr_debug("%s: media_type is 0x%x\n", __func__, *media_type);
 
-	return media_type;
+	return ret;
 }
 
 
diff --git a/sound/soc/msm/msm-pcm.c b/sound/soc/msm/msm-pcm.c
index ea31985..d40ca67 100644
--- a/sound/soc/msm/msm-pcm.c
+++ b/sound/soc/msm/msm-pcm.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2012 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/sound/soc/msm/msm-pcm.h b/sound/soc/msm/msm-pcm.h
index 867116a..eb4a722 100644
--- a/sound/soc/msm/msm-pcm.h
+++ b/sound/soc/msm/msm-pcm.h
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2012 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/sound/soc/msm/msm-voip.c b/sound/soc/msm/msm-voip.c
index b1bb2c4..ec70791 100644
--- a/sound/soc/msm/msm-voip.c
+++ b/sound/soc/msm/msm-voip.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. All rights reserved.
  *
  * All source code in this file is licensed under the following license except
  * where indicated.
diff --git a/sound/soc/msm/msm7201.c b/sound/soc/msm/msm7201.c
index 2a73fd6..154e987 100644
--- a/sound/soc/msm/msm7201.c
+++ b/sound/soc/msm/msm7201.c
@@ -1,6 +1,6 @@
 /* linux/sound/soc/msm/msm7201.c
  *
- * Copyright (c) 2008-2009, 2011, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2011, 2012 The Linux Foundation. All rights reserved.
  *
  * All source code in this file is licensed under the following license except
  * where indicated.
@@ -25,6 +25,7 @@
 #include <linux/time.h>
 #include <linux/wait.h>
 #include <linux/platform_device.h>
+#include <linux/msm_audio.h>
 #include <sound/core.h>
 #include <sound/soc.h>
 #include <sound/soc-dapm.h>
@@ -46,10 +47,27 @@
 struct msm_snd_rpc_ids {
 	unsigned long   prog;
 	unsigned long   vers;
-	unsigned long   vers2;
 	unsigned long   rpc_set_snd_device;
 	unsigned long	rpc_set_device_vol;
-	int device;
+	struct cad_devices_type device;
+};
+
+struct rpc_cad_set_device_args {
+	struct cad_devices_type device;
+	uint32_t ear_mute;
+	uint32_t mic_mute;
+
+	uint32_t cb_func;
+	uint32_t client_data;
+};
+
+struct rpc_cad_set_volume_args {
+	struct cad_devices_type device;
+	uint32_t method;
+	uint32_t volume;
+
+	uint32_t cb_func;
+	uint32_t client_data;
 };
 
 static struct msm_snd_rpc_ids snd_rpc_ids;
@@ -97,7 +115,7 @@
 				struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-	uinfo->count = 3; /* Device */
+	uinfo->count = 4; /* Device */
 
 	/*
 	 * The number of devices supported is 26 (0 to 25)
@@ -110,23 +128,25 @@
 static int snd_msm_device_get(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	ucontrol->value.integer.value[0] = (uint32_t)snd_rpc_ids.device;
-	ucontrol->value.integer.value[1] = snd_mute_ear_mute;
-	ucontrol->value.integer.value[2] = snd_mute_mic_mute;
+	ucontrol->value.integer.value[0]
+		= (uint32_t)snd_rpc_ids.device.rx_device;
+	ucontrol->value.integer.value[1]
+		= (uint32_t)snd_rpc_ids.device.tx_device;
+	ucontrol->value.integer.value[2] = snd_mute_ear_mute;
+	ucontrol->value.integer.value[3] = snd_mute_mic_mute;
 	return 0;
 }
 
 int msm_snd_init_rpc_ids(void)
 {
 	snd_rpc_ids.prog	= 0x30000002;
-	snd_rpc_ids.vers	= 0x00020001;
-	snd_rpc_ids.vers2	= 0x00030001;
+	snd_rpc_ids.vers	= 0x00030003;
 	/*
 	 * The magic number 2 corresponds to the rpc call
 	 * index for snd_set_device
 	 */
-	snd_rpc_ids.rpc_set_snd_device = 2;
-	snd_rpc_ids.rpc_set_device_vol = 3;
+	snd_rpc_ids.rpc_set_snd_device = 40;
+	snd_rpc_ids.rpc_set_device_vol = 39;
 	return 0;
 }
 
@@ -139,7 +159,7 @@
 
 	/* Initialize rpc ids */
 	if (msm_snd_init_rpc_ids()) {
-		printk(KERN_ERR "%s: snd rpc ids initialization failed\n"
+		pr_err("%s: snd rpc ids initialization failed\n"
 			, __func__);
 		return -ENODATA;
 	}
@@ -147,16 +167,8 @@
 	snd_ep = msm_rpc_connect_compatible(snd_rpc_ids.prog,
 				snd_rpc_ids.vers, 0);
 	if (IS_ERR(snd_ep)) {
-		printk(KERN_DEBUG "%s failed (compatible VERS = %ld) \
-				 trying again with another API\n",
+		pr_err("%s: failed (compatible VERS = %ld)\n",
 				__func__, snd_rpc_ids.vers);
-		snd_ep =
-			msm_rpc_connect_compatible(snd_rpc_ids.prog,
-					snd_rpc_ids.vers2, 0);
-	}
-	if (IS_ERR(snd_ep)) {
-		printk(KERN_ERR "%s: failed (compatible VERS = %ld)\n",
-				__func__, snd_rpc_ids.vers2);
 		snd_ep = NULL;
 		return -EAGAIN;
 	}
@@ -168,7 +180,7 @@
 	int rc = 0;
 
 	if (IS_ERR(snd_ep)) {
-		printk(KERN_ERR "%s: snd handle unavailable, rc = %ld\n",
+		pr_err("%s: snd handle unavailable, rc = %ld\n",
 				__func__, PTR_ERR(snd_ep));
 		return -EAGAIN;
 	}
@@ -177,7 +189,7 @@
 	snd_ep = NULL;
 
 	if (rc < 0) {
-		printk(KERN_ERR "%s: close rpc failed! rc = %d\n",
+		pr_err("%s: close rpc failed! rc = %d\n",
 				__func__, rc);
 		return -EAGAIN;
 	} else
@@ -190,47 +202,46 @@
 			struct snd_ctl_elem_value *ucontrol)
 {
 	int rc = 0;
-	struct snd_start_req {
+	struct snd_cad_set_device_msg {
 		struct rpc_request_hdr hdr;
-		uint32_t rpc_snd_device;
-		uint32_t snd_mute_ear_mute;
-		uint32_t snd_mute_mic_mute;
-		uint32_t callback_ptr;
-		uint32_t client_data;
-	} req;
+		struct rpc_cad_set_device_args args;
+	} dmsg;
 
-	snd_rpc_ids.device = (int)ucontrol->value.integer.value[0];
+	snd_rpc_ids.device.rx_device
+		= (int)ucontrol->value.integer.value[0];
+	snd_rpc_ids.device.tx_device
+		= (int)ucontrol->value.integer.value[1];
+	snd_rpc_ids.device.pathtype = CAD_DEVICE_PATH_RX_TX;
 
-	if (ucontrol->value.integer.value[1] > 1)
-		ucontrol->value.integer.value[1] = 1;
-	if (ucontrol->value.integer.value[2] > 1)
-		ucontrol->value.integer.value[2] = 1;
-
-	req.hdr.type = 0;
-	req.hdr.rpc_vers = 2;
-
-	req.rpc_snd_device = cpu_to_be32(snd_rpc_ids.device);
-	req.snd_mute_ear_mute =
-		cpu_to_be32((int)ucontrol->value.integer.value[1]);
-	req.snd_mute_mic_mute =
-		cpu_to_be32((int)ucontrol->value.integer.value[2]);
-	req.callback_ptr = -1;
-	req.client_data = cpu_to_be32(0);
-
-	req.hdr.prog = snd_rpc_ids.prog;
-	req.hdr.vers = snd_rpc_ids.vers;
+	dmsg.args.device.rx_device
+		= cpu_to_be32(snd_rpc_ids.device.rx_device);
+	dmsg.args.device.tx_device
+		= cpu_to_be32(snd_rpc_ids.device.tx_device);
+	dmsg.args.device.pathtype = cpu_to_be32(CAD_DEVICE_PATH_RX_TX);
+	dmsg.args.ear_mute = cpu_to_be32(ucontrol->value.integer.value[2]);
+	dmsg.args.mic_mute = cpu_to_be32(ucontrol->value.integer.value[3]);
+	if (!(dmsg.args.ear_mute == SND_MUTE_MUTED ||
+		dmsg.args.ear_mute == SND_MUTE_UNMUTED) ||
+		(!(dmsg.args.mic_mute == SND_MUTE_MUTED ||
+		dmsg.args.ear_mute == SND_MUTE_UNMUTED))) {
+		pr_err("snd_cad_ioctl set device: invalid mute status\n");
+		rc = -EINVAL;
+		return rc;
+	}
+	dmsg.args.cb_func = -1;
+	dmsg.args.client_data = 0;
 
 	rc = msm_rpc_call(snd_ep, snd_rpc_ids.rpc_set_snd_device ,
-			&req, sizeof(req), 5 * HZ);
+			&dmsg, sizeof(dmsg), 5 * HZ);
 
 	if (rc < 0) {
-		printk(KERN_ERR "%s: snd rpc call failed! rc = %d\n",
+		pr_err("%s: snd rpc call failed! rc = %d\n",
 			__func__, rc);
 	} else {
 		printk(KERN_INFO "snd device connected\n");
-		snd_mute_ear_mute = ucontrol->value.integer.value[1];
-		snd_mute_mic_mute = ucontrol->value.integer.value[2];
-		printk(KERN_ERR "%s: snd_mute_ear_mute =%d, snd_mute_mic_mute = %d\n",
+		snd_mute_ear_mute = ucontrol->value.integer.value[2];
+		snd_mute_mic_mute = ucontrol->value.integer.value[3];
+		pr_err("%s: snd_mute_ear_mute =%d, snd_mute_mic_mute = %d\n",
 				__func__, snd_mute_ear_mute, snd_mute_mic_mute);
 	}
 
@@ -241,13 +252,13 @@
 				struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-	uinfo->count = 2; /* Device/Volume */
+	uinfo->count = 1; /* Device/Volume */
 
 	/*
-	 * The number of devices supported is 37 (0 to 36)
+	 * The volume ranges from (0 to 6)
 	 */
 	uinfo->value.integer.min = 0;
-	uinfo->value.integer.max = 36;
+	uinfo->value.integer.max = 6;
 	return 0;
 }
 
@@ -255,44 +266,34 @@
 			struct snd_ctl_elem_value *ucontrol)
 {
 	int rc = 0;
-	struct snd_vol_req {
+
+	struct snd_cad_set_volume_msg {
 		struct rpc_request_hdr hdr;
-		uint32_t device;
-		uint32_t method;
-		uint32_t volume;
-		uint32_t cb_func;
-		uint32_t client_data;
-	} req;
+		struct rpc_cad_set_volume_args args;
+	} vmsg;
 
-	snd_rpc_ids.device = (int)ucontrol->value.integer.value[0];
-
-	if ((ucontrol->value.integer.value[1] < 0) ||
-		(ucontrol->value.integer.value[1] > 6)) {
-		pr_err("Device volume should be in range of 1 to 6\n");
-		return -EINVAL;
-	}
-	if ((ucontrol->value.integer.value[0] > 36) ||
-		(ucontrol->value.integer.value[0] < 0)) {
-		pr_err("Device range supported is 0 to 36\n");
-		return -EINVAL;
-	}
-
-	req.device = cpu_to_be32((int)ucontrol->value.integer.value[0]);
-	req.method = cpu_to_be32(0);
-	req.volume = cpu_to_be32((int)ucontrol->value.integer.value[1]);
-	req.cb_func = -1;
-	req.client_data = cpu_to_be32(0);
+	vmsg.args.device.rx_device
+		= cpu_to_be32(snd_rpc_ids.device.rx_device);
+	vmsg.args.device.tx_device
+		= cpu_to_be32(snd_rpc_ids.device.tx_device);
+	vmsg.args.method = cpu_to_be32(SND_METHOD_VOICE);
+	vmsg.args.volume = cpu_to_be32(ucontrol->value.integer.value[0]);
+	vmsg.args.cb_func = -1;
+	vmsg.args.client_data = 0;
 
 	rc = msm_rpc_call(snd_ep, snd_rpc_ids.rpc_set_device_vol ,
-			&req, sizeof(req), 5 * HZ);
+			&vmsg, sizeof(vmsg), 5 * HZ);
 
 	if (rc < 0) {
-		printk(KERN_ERR "%s: snd rpc call failed! rc = %d\n",
+		pr_err("%s: snd rpc call failed! rc = %d\n",
 			__func__, rc);
 	} else {
-		printk(KERN_ERR "%s: device [%d] volume set to [%d]\n",
-				__func__, (int)ucontrol->value.integer.value[0],
-				(int)ucontrol->value.integer.value[1]);
+		pr_debug("%s:rx device [%d]", __func__,
+			snd_rpc_ids.device.rx_device);
+		pr_debug("%s:tx device [%d]", __func__,
+			snd_rpc_ids.device.tx_device);
+		pr_debug("%s:volume set to [%ld]\n", __func__,
+			snd_rpc_ids.rpc_set_device_vol);
 	}
 
 	return rc;
@@ -349,7 +350,7 @@
 	struct snd_soc_pcm_runtime *rtd)
 {
 	int ret = 0;
-        struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_codec *codec = rtd->codec;
 
 	mutex_init(&the_locks.lock);
 	mutex_init(&the_locks.write_lock);
diff --git a/sound/soc/msm/msm7k-pcm.c b/sound/soc/msm/msm7k-pcm.c
index 1f23a92..a9193a2 100644
--- a/sound/soc/msm/msm7k-pcm.c
+++ b/sound/soc/msm/msm7k-pcm.c
@@ -1,6 +1,6 @@
 /* linux/sound/soc/msm/msm7k-pcm.c
  *
- * Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2012 The Linux Foundation. All rights reserved.
  *
  * All source code in this file is licensed under the following license except
  * where indicated.
diff --git a/sound/soc/msm/msm7kv2-dai.c b/sound/soc/msm/msm7kv2-dai.c
index e8d51ac..44fdc02 100644
--- a/sound/soc/msm/msm7kv2-dai.c
+++ b/sound/soc/msm/msm7kv2-dai.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2010, The Linux Foundation. All rights reserved.
  *
  * Derived from msm-pcm.c and msm7201.c.
  *
diff --git a/sound/soc/msm/msm7kv2-dsp.c b/sound/soc/msm/msm7kv2-dsp.c
index 50bf6fb..8484a8f 100644
--- a/sound/soc/msm/msm7kv2-dsp.c
+++ b/sound/soc/msm/msm7kv2-dsp.c
@@ -1,6 +1,6 @@
 /* Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2010, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/sound/soc/msm/msm7kv2-pcm.c b/sound/soc/msm/msm7kv2-pcm.c
index c64a3ff..2b7a438 100644
--- a/sound/soc/msm/msm7kv2-pcm.c
+++ b/sound/soc/msm/msm7kv2-pcm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2010, The Linux Foundation. All rights reserved.
  *
  * All source code in this file is licensed under the following license except
  * where indicated.
diff --git a/sound/soc/msm/msm7kv2-pcm.h b/sound/soc/msm/msm7kv2-pcm.h
index fec7cf5..bcf6b4d4 100644
--- a/sound/soc/msm/msm7kv2-pcm.h
+++ b/sound/soc/msm/msm7kv2-pcm.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2010, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/sound/soc/msm/msm7x30.c b/sound/soc/msm/msm7x30.c
index 94e37ca..664baab 100644
--- a/sound/soc/msm/msm7x30.c
+++ b/sound/soc/msm/msm7x30.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2011, The Linux Foundation. All rights reserved.
  *
  * All source code in this file is licensed under the following license except
  * where indicated.
diff --git a/sound/soc/msm/msm8226.c b/sound/soc/msm/msm8226.c
new file mode 100644
index 0000000..328c380
--- /dev/null
+++ b/sound/soc/msm/msm8226.c
@@ -0,0 +1,1065 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/mfd/pm8xxx/pm8921.h>
+#include <sound/core.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/pcm.h>
+#include <sound/jack.h>
+#include <asm/mach-types.h>
+#include <mach/socinfo.h>
+#include <qdsp6v2/msm-pcm-routing-v2.h>
+#include "../codecs/wcd9306.h"
+
+#define DRV_NAME "msm8226-asoc-tapan"
+
+#define MSM_SLIM_0_RX_MAX_CHANNELS		2
+#define MSM_SLIM_0_TX_MAX_CHANNELS		4
+
+#define BTSCO_RATE_8KHZ 8000
+#define BTSCO_RATE_16KHZ 16000
+
+#define GPIO_AUX_PCM_DOUT 43
+#define GPIO_AUX_PCM_DIN 44
+#define GPIO_AUX_PCM_SYNC 45
+#define GPIO_AUX_PCM_CLK 46
+
+#define WCD9XXX_MBHC_DEF_BUTTONS 8
+#define WCD9XXX_MBHC_DEF_RLOADS 5
+#define TAPAN_EXT_CLK_RATE 9600000
+
+void *def_tapan_mbhc_cal(void);
+static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, int enable,
+					bool dapm);
+
+static struct wcd9xxx_mbhc_config mbhc_cfg = {
+	.read_fw_bin = false,
+	.calibration = NULL,
+	.micbias = MBHC_MICBIAS2,
+	.mclk_cb_fn = msm_snd_enable_codec_ext_clk,
+	.mclk_rate = TAPAN_EXT_CLK_RATE,
+	.gpio = 0,
+	.gpio_irq = 0,
+	.gpio_level_insert = 1,
+	.detect_extn_cable = true,
+	.insert_detect = true,
+	.swap_gnd_mic = NULL,
+};
+
+struct msm8226_asoc_mach_data {
+	int mclk_gpio;
+	u32 mclk_freq;
+};
+
+/* Shared channel numbers for Slimbus ports that connect APQ to MDM. */
+enum {
+	SLIM_1_RX_1 = 145, /* BT-SCO and USB TX */
+	SLIM_1_TX_1 = 146, /* BT-SCO and USB RX */
+	SLIM_2_RX_1 = 147, /* HDMI RX */
+	SLIM_3_RX_1 = 148, /* In-call recording RX */
+	SLIM_3_RX_2 = 149, /* In-call recording RX */
+	SLIM_4_TX_1 = 150, /* In-call musid delivery TX */
+};
+
+static int msm_slim_0_rx_ch = 1;
+static int msm_slim_0_tx_ch = 1;
+
+static int msm_btsco_rate = BTSCO_RATE_8KHZ;
+static int msm_btsco_ch = 1;
+
+static struct mutex cdc_mclk_mutex;
+static struct q_clkdiv *codec_clk;
+static int clk_users;
+
+static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, int enable,
+					bool dapm)
+{
+	int ret = 0;
+	pr_debug("%s: enable = %d clk_users = %d\n",
+		__func__, enable, clk_users);
+
+	mutex_lock(&cdc_mclk_mutex);
+	if (enable) {
+		if (!codec_clk) {
+			dev_err(codec->dev, "%s: did not get Taiko MCLK\n",
+				__func__);
+			ret = -EINVAL;
+			goto exit;
+		}
+
+		clk_users++;
+		if (clk_users != 1)
+			goto exit;
+		/* TODO: qpnp_clkdiv_enable */
+		tapan_mclk_enable(codec, 1, dapm);
+	} else {
+		if (clk_users > 0) {
+			clk_users--;
+			if (clk_users == 0) {
+				tapan_mclk_enable(codec, 0, dapm);
+				/* TODO: qpnp_clkdiv_disable */
+			}
+		} else {
+			pr_err("%s: Error releasing Tabla MCLK\n", __func__);
+			ret = -EINVAL;
+			goto exit;
+		}
+	}
+exit:
+	mutex_unlock(&cdc_mclk_mutex);
+	return ret;
+}
+
+static int msm8226_mclk_event(struct snd_soc_dapm_widget *w,
+		struct snd_kcontrol *kcontrol, int event)
+{
+	pr_debug("%s: event = %d\n", __func__, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		return msm_snd_enable_codec_ext_clk(w->codec, 1, true);
+	case SND_SOC_DAPM_POST_PMD:
+		return msm_snd_enable_codec_ext_clk(w->codec, 0, true);
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_dapm_widget msm8226_dapm_widgets[] = {
+
+	SND_SOC_DAPM_SUPPLY("MCLK",  SND_SOC_NOPM, 0, 0,
+	msm8226_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MIC("Handset Mic", NULL),
+	SND_SOC_DAPM_MIC("Headset Mic", NULL),
+	SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL),
+	SND_SOC_DAPM_MIC("ANCLeft Headset Mic", NULL),
+
+	SND_SOC_DAPM_MIC("Digital Mic1", NULL),
+	SND_SOC_DAPM_MIC("Digital Mic2", NULL),
+	SND_SOC_DAPM_MIC("Digital Mic3", NULL),
+	SND_SOC_DAPM_MIC("Digital Mic4", NULL),
+	SND_SOC_DAPM_MIC("Digital Mic5", NULL),
+	SND_SOC_DAPM_MIC("Digital Mic6", NULL),
+};
+
+static const char *const slim0_rx_ch_text[] = {"One", "Two"};
+static const char *const slim0_tx_ch_text[] = {"One", "Two", "Three", "Four"};
+
+static const struct soc_enum msm_enum[] = {
+	SOC_ENUM_SINGLE_EXT(2, slim0_rx_ch_text),
+	SOC_ENUM_SINGLE_EXT(4, slim0_tx_ch_text),
+};
+
+static const char *const btsco_rate_text[] = {"8000", "16000"};
+static const struct soc_enum msm_btsco_enum[] = {
+	SOC_ENUM_SINGLE_EXT(2, btsco_rate_text),
+};
+
+static int msm_slim_0_rx_ch_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	pr_debug("%s: msm_slim_0_rx_ch  = %d\n", __func__,
+		 msm_slim_0_rx_ch);
+	ucontrol->value.integer.value[0] = msm_slim_0_rx_ch - 1;
+	return 0;
+}
+
+static int msm_slim_0_rx_ch_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	msm_slim_0_rx_ch = ucontrol->value.integer.value[0] + 1;
+
+	pr_debug("%s: msm_slim_0_rx_ch = %d\n", __func__,
+		 msm_slim_0_rx_ch);
+	return 1;
+}
+
+static int msm_slim_0_tx_ch_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	pr_debug("%s: msm_slim_0_tx_ch  = %d\n", __func__,
+		 msm_slim_0_tx_ch);
+	ucontrol->value.integer.value[0] = msm_slim_0_tx_ch - 1;
+	return 0;
+}
+
+static int msm_slim_0_tx_ch_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	msm_slim_0_tx_ch = ucontrol->value.integer.value[0] + 1;
+
+	pr_debug("%s: msm_slim_0_tx_ch = %d\n", __func__, msm_slim_0_tx_ch);
+	return 1;
+}
+
+static int msm_btsco_rate_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	pr_debug("%s: msm_btsco_rate  = %d", __func__, msm_btsco_rate);
+	ucontrol->value.integer.value[0] = msm_btsco_rate;
+	return 0;
+}
+
+static int msm_btsco_rate_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	switch (ucontrol->value.integer.value[0]) {
+	case 0:
+		msm_btsco_rate = BTSCO_RATE_8KHZ;
+		break;
+	case 1:
+		msm_btsco_rate = BTSCO_RATE_16KHZ;
+		break;
+	default:
+		msm_btsco_rate = BTSCO_RATE_8KHZ;
+		break;
+	}
+
+	pr_debug("%s: msm_btsco_rate = %d\n", __func__, msm_btsco_rate);
+	return 0;
+}
+
+static const struct snd_kcontrol_new int_btsco_rate_mixer_controls[] = {
+	SOC_ENUM_EXT("Internal BTSCO SampleRate", msm_btsco_enum[0],
+		     msm_btsco_rate_get, msm_btsco_rate_put),
+};
+
+static int msm_btsco_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+					struct snd_pcm_hw_params *params)
+{
+	struct snd_interval *rate = hw_param_interval(params,
+					SNDRV_PCM_HW_PARAM_RATE);
+
+	struct snd_interval *channels = hw_param_interval(params,
+					SNDRV_PCM_HW_PARAM_CHANNELS);
+
+	rate->min = rate->max = msm_btsco_rate;
+	channels->min = channels->max = msm_btsco_ch;
+
+	return 0;
+}
+
+static int msm_proxy_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+			struct snd_pcm_hw_params *params)
+{
+	struct snd_interval *rate = hw_param_interval(params,
+	SNDRV_PCM_HW_PARAM_RATE);
+
+	pr_debug("%s()\n", __func__);
+	rate->min = rate->max = 48000;
+
+	return 0;
+}
+
+static int msm8226_hdmi_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+					struct snd_pcm_hw_params *params)
+{
+	struct snd_interval *rate = hw_param_interval(params,
+					SNDRV_PCM_HW_PARAM_RATE);
+
+	struct snd_interval *channels = hw_param_interval(params,
+					SNDRV_PCM_HW_PARAM_CHANNELS);
+
+	pr_debug("%s channels->min %u channels->max %u ()\n", __func__,
+			channels->min, channels->max);
+
+	rate->min = rate->max = 48000;
+
+	return 0;
+}
+
+static int msm_slim_0_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+					    struct snd_pcm_hw_params *params)
+{
+	struct snd_interval *rate = hw_param_interval(params,
+		SNDRV_PCM_HW_PARAM_RATE);
+
+	struct snd_interval *channels =
+		hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+
+	pr_debug("%s()\n", __func__);
+	rate->min = rate->max = 48000;
+	channels->min = channels->max = msm_slim_0_rx_ch;
+
+	return 0;
+}
+
+static int msm_slim_0_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+					    struct snd_pcm_hw_params *params)
+{
+	struct snd_interval *rate = hw_param_interval(params,
+	SNDRV_PCM_HW_PARAM_RATE);
+
+	struct snd_interval *channels = hw_param_interval(params,
+			SNDRV_PCM_HW_PARAM_CHANNELS);
+
+	pr_debug("%s()\n", __func__);
+	rate->min = rate->max = 48000;
+	channels->min = channels->max = msm_slim_0_tx_ch;
+
+	return 0;
+}
+
+static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+				struct snd_pcm_hw_params *params)
+{
+	struct snd_interval *rate = hw_param_interval(params,
+					SNDRV_PCM_HW_PARAM_RATE);
+
+	pr_debug("%s()\n", __func__);
+	rate->min = rate->max = 48000;
+
+	return 0;
+}
+
+static const struct soc_enum msm_snd_enum[] = {
+	SOC_ENUM_SINGLE_EXT(2, slim0_rx_ch_text),
+	SOC_ENUM_SINGLE_EXT(4, slim0_tx_ch_text),
+};
+
+static const struct snd_kcontrol_new msm_snd_controls[] = {
+	SOC_ENUM_EXT("SLIM_0_RX Channels", msm_snd_enum[1],
+		     msm_slim_0_rx_ch_get, msm_slim_0_rx_ch_put),
+	SOC_ENUM_EXT("SLIM_0_TX Channels", msm_snd_enum[2],
+		     msm_slim_0_tx_ch_get, msm_slim_0_tx_ch_put),
+};
+
+static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
+{
+	int err;
+	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_dapm_context *dapm = &codec->dapm;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+
+	/*
+	 * Tapan SLIMBUS configuration
+	 * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8, RX9, RX10, RX11, RX12, RX13
+	 * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13
+	 * TX14, TX15, TX16
+	 */
+	unsigned int rx_ch[TAPAN_RX_MAX] = {144, 145, 146, 147, 148};
+	unsigned int tx_ch[TAPAN_TX_MAX]  = {128, 129, 130, 131, 132};
+
+
+	pr_debug("%s(), dev_name%s\n", __func__, dev_name(cpu_dai->dev));
+
+	rtd->pmdown_time = 0;
+
+	err = snd_soc_add_codec_controls(codec, msm_snd_controls,
+					 ARRAY_SIZE(msm_snd_controls));
+	if (err < 0)
+		return err;
+
+	snd_soc_dapm_new_controls(dapm, msm8226_dapm_widgets,
+				ARRAY_SIZE(msm8226_dapm_widgets));
+
+	snd_soc_dapm_sync(dapm);
+
+	snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch),
+				    tx_ch, ARRAY_SIZE(rx_ch), rx_ch);
+
+	/* start mbhc */
+	mbhc_cfg.calibration = def_tapan_mbhc_cal();
+	if (mbhc_cfg.calibration)
+		err = tapan_hs_detect(codec, &mbhc_cfg);
+	else
+		err = -ENOMEM;
+
+	return err;
+}
+
+static int msm_snd_startup(struct snd_pcm_substream *substream)
+{
+	pr_debug("%s(): substream = %s  stream = %d\n", __func__,
+		 substream->name, substream->stream);
+	return 0;
+}
+
+void *def_tapan_mbhc_cal(void)
+{
+	void *tapan_cal;
+	struct wcd9xxx_mbhc_btn_detect_cfg *btn_cfg;
+	u16 *btn_low, *btn_high;
+	u8 *n_ready, *n_cic, *gain;
+
+	tapan_cal = kzalloc(WCD9XXX_MBHC_CAL_SIZE(WCD9XXX_MBHC_DEF_BUTTONS,
+						WCD9XXX_MBHC_DEF_RLOADS),
+			    GFP_KERNEL);
+	if (!tapan_cal) {
+		pr_err("%s: out of memory\n", __func__);
+		return NULL;
+	}
+
+#define S(X, Y) ((WCD9XXX_MBHC_CAL_GENERAL_PTR(tapan_cal)->X) = (Y))
+	S(t_ldoh, 100);
+	S(t_bg_fast_settle, 100);
+	S(t_shutdown_plug_rem, 255);
+	S(mbhc_nsa, 4);
+	S(mbhc_navg, 4);
+#undef S
+#define S(X, Y) ((WCD9XXX_MBHC_CAL_PLUG_DET_PTR(tapan_cal)->X) = (Y))
+	S(mic_current, TAPAN_PID_MIC_5_UA);
+	S(hph_current, TAPAN_PID_MIC_5_UA);
+	S(t_mic_pid, 100);
+	S(t_ins_complete, 250);
+	S(t_ins_retry, 200);
+#undef S
+#define S(X, Y) ((WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(tapan_cal)->X) = (Y))
+	S(v_no_mic, 30);
+	S(v_hs_max, 2400);
+#undef S
+#define S(X, Y) ((WCD9XXX_MBHC_CAL_BTN_DET_PTR(tapan_cal)->X) = (Y))
+	S(c[0], 62);
+	S(c[1], 124);
+	S(nc, 1);
+	S(n_meas, 3);
+	S(mbhc_nsc, 11);
+	S(n_btn_meas, 1);
+	S(n_btn_con, 2);
+	S(num_btn, WCD9XXX_MBHC_DEF_BUTTONS);
+	S(v_btn_press_delta_sta, 100);
+	S(v_btn_press_delta_cic, 50);
+#undef S
+	btn_cfg = WCD9XXX_MBHC_CAL_BTN_DET_PTR(tapan_cal);
+	btn_low = wcd9xxx_mbhc_cal_btn_det_mp(btn_cfg, MBHC_BTN_DET_V_BTN_LOW);
+	btn_high = wcd9xxx_mbhc_cal_btn_det_mp(btn_cfg,
+					       MBHC_BTN_DET_V_BTN_HIGH);
+	btn_low[0] = -50;
+	btn_high[0] = 10;
+	btn_low[1] = 11;
+	btn_high[1] = 52;
+	btn_low[2] = 53;
+	btn_high[2] = 94;
+	btn_low[3] = 95;
+	btn_high[3] = 133;
+	btn_low[4] = 134;
+	btn_high[4] = 171;
+	btn_low[5] = 172;
+	btn_high[5] = 208;
+	btn_low[6] = 209;
+	btn_high[6] = 244;
+	btn_low[7] = 245;
+	btn_high[7] = 330;
+	n_ready = wcd9xxx_mbhc_cal_btn_det_mp(btn_cfg, MBHC_BTN_DET_N_READY);
+	n_ready[0] = 80;
+	n_ready[1] = 68;
+	n_cic = wcd9xxx_mbhc_cal_btn_det_mp(btn_cfg, MBHC_BTN_DET_N_CIC);
+	n_cic[0] = 60;
+	n_cic[1] = 47;
+	gain = wcd9xxx_mbhc_cal_btn_det_mp(btn_cfg, MBHC_BTN_DET_GAIN);
+	gain[0] = 11;
+	gain[1] = 9;
+
+	return tapan_cal;
+}
+
+static int msm_snd_hw_params(struct snd_pcm_substream *substream,
+			     struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+	int ret = 0;
+	unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS];
+	unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0;
+	unsigned int user_set_tx_ch = 0;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+		pr_debug("%s: rx_0_ch=%d\n", __func__, msm_slim_0_rx_ch);
+		ret = snd_soc_dai_get_channel_map(codec_dai,
+					&tx_ch_cnt, tx_ch, &rx_ch_cnt , rx_ch);
+		if (ret < 0) {
+			pr_err("%s: failed to get codec chan map\n", __func__);
+			goto end;
+		}
+
+		ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0,
+						  msm_slim_0_rx_ch, rx_ch);
+		if (ret < 0) {
+			pr_err("%s: failed to set cpu chan map\n", __func__);
+			goto end;
+		}
+	} else {
+
+		pr_debug("%s: %s_tx_dai_id_%d_ch=%d\n", __func__,
+			 codec_dai->name, codec_dai->id, user_set_tx_ch);
+
+		ret = snd_soc_dai_get_channel_map(codec_dai,
+					 &tx_ch_cnt, tx_ch, &rx_ch_cnt , rx_ch);
+		if (ret < 0) {
+			pr_err("%s: failed to get codec chan map\n", __func__);
+			goto end;
+		}
+		/* For tabla_tx1 case */
+		if (codec_dai->id == 1)
+			user_set_tx_ch = msm_slim_0_tx_ch;
+		/* For tabla_tx2 case */
+		else if (codec_dai->id == 3)
+			user_set_tx_ch = params_channels(params);
+		else
+			user_set_tx_ch = tx_ch_cnt;
+
+		pr_debug("%s: msm_slim_0_tx_ch(%d)user_set_tx_ch(%d)tx_ch_cnt(%d)\n",
+			 __func__, msm_slim_0_tx_ch, user_set_tx_ch, tx_ch_cnt);
+
+		ret = snd_soc_dai_set_channel_map(cpu_dai,
+						  user_set_tx_ch, tx_ch, 0 , 0);
+		if (ret < 0) {
+			pr_err("%s: failed to set cpu chan map\n", __func__);
+			goto end;
+		}
+	}
+end:
+	return ret;
+}
+
+static void msm_snd_shutdown(struct snd_pcm_substream *substream)
+{
+	pr_debug("%s(): substream = %s stream = %d\n", __func__,
+		 substream->name, substream->stream);
+}
+
+static struct snd_soc_ops msm8226_be_ops = {
+	.startup = msm_snd_startup,
+	.hw_params = msm_snd_hw_params,
+	.shutdown = msm_snd_shutdown,
+};
+
+/* Digital audio interface glue - connects codec <---> CPU */
+static struct snd_soc_dai_link msm8226_dai[] = {
+	/* FrontEnd DAI Links */
+	{
+		.name = "MSM8226 Media1",
+		.stream_name = "MultiMedia1",
+		.cpu_dai_name	= "MultiMedia1",
+		.platform_name  = "msm-pcm-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,
+		/* This dainlink has playback support */
+		.ignore_pmdown_time = 1,
+		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA1
+	},
+	{
+		.name = "MSM8226 Media2",
+		.stream_name = "MultiMedia2",
+		.cpu_dai_name   = "MultiMedia2",
+		.platform_name  = "msm-pcm-dsp",
+		.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,
+		/* This dainlink has playback support */
+		.ignore_pmdown_time = 1,
+		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA2,
+	},
+	{
+		.name = "Circuit-Switch Voice",
+		.stream_name = "CS-Voice",
+		.cpu_dai_name   = "CS-VOICE",
+		.platform_name  = "msm-pcm-voice",
+		.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},
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		/* this dainlink has playback support */
+		.ignore_pmdown_time = 1,
+		.be_id = MSM_FRONTEND_DAI_CS_VOICE,
+	},
+	{
+		.name = "MSM VoIP",
+		.stream_name = "VoIP",
+		.cpu_dai_name	= "VoIP",
+		.platform_name  = "msm-voip-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,
+		/* this dainlink has playback support */
+		.ignore_pmdown_time = 1,
+		.be_id = MSM_FRONTEND_DAI_VOIP,
+	},
+	{
+		.name = "MSM8226 LPA",
+		.stream_name = "LPA",
+		.cpu_dai_name	= "MultiMedia3",
+		.platform_name  = "msm-pcm-lpa",
+		.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,
+		/* this dainlink has playback support */
+		.ignore_pmdown_time = 1,
+		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA3,
+	},
+	/* Hostless PCM purpose */
+	{
+		.name = "SLIMBUS_0 Hostless",
+		.stream_name = "SLIMBUS_0 Hostless",
+		.cpu_dai_name = "SLIMBUS0_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,
+		.ignore_pmdown_time = 1, /* dai link has playback support */
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+	},
+	{
+		.name = "INT_FM Hostless",
+		.stream_name = "INT_FM Hostless",
+		.cpu_dai_name	= "INT_FM_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 dainlink has playback support */
+		.ignore_pmdown_time = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+	},
+	{
+		.name = "MSM AFE-PCM RX",
+		.stream_name = "AFE-PROXY RX",
+		.cpu_dai_name = "msm-dai-q6-dev.241",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-rx",
+		.platform_name  = "msm-pcm-afe",
+		.ignore_suspend = 1,
+		/* this dainlink has playback support */
+		.ignore_pmdown_time = 1,
+	},
+	{
+		.name = "MSM AFE-PCM TX",
+		.stream_name = "AFE-PROXY TX",
+		.cpu_dai_name = "msm-dai-q6-dev.240",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-tx",
+		.platform_name  = "msm-pcm-afe",
+		.ignore_suspend = 1,
+	},
+	{
+		.name = "MSM8226 Compr",
+		.stream_name = "COMPR",
+		.cpu_dai_name	= "MultiMedia4",
+		.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_MULTIMEDIA4,
+	},
+	{
+		.name = "AUXPCM Hostless",
+		.stream_name = "AUXPCM Hostless",
+		.cpu_dai_name   = "AUXPCM_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 dainlink has playback support */
+		.ignore_pmdown_time = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+	},
+	{
+		.name = "SLIMBUS_1 Hostless",
+		.stream_name = "SLIMBUS_1 Hostless",
+		.cpu_dai_name = "SLIMBUS1_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,
+		.ignore_pmdown_time = 1, /* dai link has playback support */
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+	},
+	{
+		.name = "SLIMBUS_3 Hostless",
+		.stream_name = "SLIMBUS_3 Hostless",
+		.cpu_dai_name = "SLIMBUS3_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,
+		.ignore_pmdown_time = 1, /* dai link has playback support */
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+	},
+	{
+		.name = "SLIMBUS_4 Hostless",
+		.stream_name = "SLIMBUS_4 Hostless",
+		.cpu_dai_name = "SLIMBUS4_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,
+		.ignore_pmdown_time = 1, /* dai link has playback support */
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+	},
+	/* Backend BT/FM DAI Links */
+	{
+		.name = LPASS_BE_INT_BT_SCO_RX,
+		.stream_name = "Internal BT-SCO Playback",
+		.cpu_dai_name = "msm-dai-q6-dev.12288",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name	= "msm-stub-rx",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_INT_BT_SCO_RX,
+		.be_hw_params_fixup = msm_btsco_be_hw_params_fixup,
+		/* this dainlink has playback support */
+		.ignore_pmdown_time = 1,
+	},
+	{
+		.name = LPASS_BE_INT_BT_SCO_TX,
+		.stream_name = "Internal BT-SCO Capture",
+		.cpu_dai_name = "msm-dai-q6-dev.12289",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name	= "msm-stub-tx",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_INT_BT_SCO_TX,
+		.be_hw_params_fixup = msm_btsco_be_hw_params_fixup,
+	},
+	{
+		.name = LPASS_BE_INT_FM_RX,
+		.stream_name = "Internal FM Playback",
+		.cpu_dai_name = "msm-dai-q6-dev.12292",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-rx",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_INT_FM_RX,
+		.be_hw_params_fixup = msm_be_hw_params_fixup,
+		/* this dainlink has playback support */
+		.ignore_pmdown_time = 1,
+	},
+	{
+		.name = LPASS_BE_INT_FM_TX,
+		.stream_name = "Internal FM Capture",
+		.cpu_dai_name = "msm-dai-q6-dev.12293",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-tx",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_INT_FM_TX,
+		.be_hw_params_fixup = msm_be_hw_params_fixup,
+	},
+	/* Backend AFE DAI Links */
+	{
+		.name = LPASS_BE_AFE_PCM_RX,
+		.stream_name = "AFE Playback",
+		.cpu_dai_name = "msm-dai-q6-dev.224",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-rx",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_AFE_PCM_RX,
+		.be_hw_params_fixup = msm_proxy_be_hw_params_fixup,
+		/* this dainlink has playback support */
+		.ignore_pmdown_time = 1,
+	},
+	{
+		.name = LPASS_BE_AFE_PCM_TX,
+		.stream_name = "AFE Capture",
+		.cpu_dai_name = "msm-dai-q6-dev.225",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-tx",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_AFE_PCM_TX,
+		.be_hw_params_fixup = msm_proxy_be_hw_params_fixup,
+	},
+	/* HDMI Hostless */
+	{
+		.name = "HDMI_RX_HOSTLESS",
+		.stream_name = "HDMI_RX_HOSTLESS",
+		.cpu_dai_name = "HDMI_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,
+		.ignore_pmdown_time = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+	},
+	/* HDMI BACK END DAI Link */
+	{
+		.name = LPASS_BE_HDMI,
+		.stream_name = "HDMI Playback",
+		.cpu_dai_name = "msm-dai-q6-hdmi.8",
+		.platform_name = "msm-pcm-routing",
+		.codec_name     = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-rx",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_HDMI_RX,
+		.be_hw_params_fixup = msm8226_hdmi_be_hw_params_fixup,
+		.ignore_pmdown_time = 1,
+	},
+	/* Backend DAI Links */
+	{
+		.name = LPASS_BE_SLIMBUS_0_RX,
+		.stream_name = "Slimbus Playback",
+		.cpu_dai_name = "msm-dai-q6-dev.16384",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "tapan_codec",
+		.codec_dai_name	= "tapan_rx1",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_SLIMBUS_0_RX,
+		.init = &msm_audrx_init,
+		.be_hw_params_fixup = msm_slim_0_rx_be_hw_params_fixup,
+		.ops = &msm8226_be_ops,
+		.ignore_pmdown_time = 1, /* dai link has playback support */
+	},
+	{
+		.name = LPASS_BE_SLIMBUS_0_TX,
+		.stream_name = "Slimbus Capture",
+		.cpu_dai_name = "msm-dai-q6-dev.16385",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "tapan_codec",
+		.codec_dai_name	= "tapan_tx1",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_SLIMBUS_0_TX,
+		.be_hw_params_fixup = msm_slim_0_tx_be_hw_params_fixup,
+		.ops = &msm8226_be_ops,
+	},
+	{
+		.name = LPASS_BE_SLIMBUS_1_RX,
+		.stream_name = "Slimbus1 Playback",
+		.cpu_dai_name = "msm-dai-q6-dev.16386",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "tapan_codec",
+		.codec_dai_name	= "tapan_rx1",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_SLIMBUS_1_RX,
+		.be_hw_params_fixup = msm_slim_0_rx_be_hw_params_fixup,
+		.ops = &msm8226_be_ops,
+		/* dai link has playback support */
+		.ignore_pmdown_time = 1,
+	},
+	{
+		.name = LPASS_BE_SLIMBUS_1_TX,
+		.stream_name = "Slimbus1 Capture",
+		.cpu_dai_name = "msm-dai-q6-dev.16387",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "tapan_codec",
+		.codec_dai_name	= "tapan_tx1",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_SLIMBUS_1_TX,
+		.be_hw_params_fixup = msm_slim_0_tx_be_hw_params_fixup,
+		.ops = &msm8226_be_ops,
+	},
+	{
+		.name = LPASS_BE_SLIMBUS_3_RX,
+		.stream_name = "Slimbus3 Playback",
+		.cpu_dai_name = "msm-dai-q6-dev.16390",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "tapan_codec",
+		.codec_dai_name	= "tapan_rx1",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_SLIMBUS_3_RX,
+		.be_hw_params_fixup = msm_slim_0_rx_be_hw_params_fixup,
+		.ops = &msm8226_be_ops,
+		/* dai link has playback support */
+		.ignore_pmdown_time = 1,
+	},
+	{
+		.name = LPASS_BE_SLIMBUS_3_TX,
+		.stream_name = "Slimbus3 Capture",
+		.cpu_dai_name = "msm-dai-q6-dev.16391",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "tapan_codec",
+		.codec_dai_name	= "tapan_tx1",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_SLIMBUS_3_TX,
+		.be_hw_params_fixup = msm_slim_0_tx_be_hw_params_fixup,
+		.ops = &msm8226_be_ops,
+	},
+	{
+		.name = LPASS_BE_SLIMBUS_4_RX,
+		.stream_name = "Slimbus4 Playback",
+		.cpu_dai_name = "msm-dai-q6-dev.16392",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "tapan_codec",
+		.codec_dai_name	= "tapan_rx1",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_SLIMBUS_4_RX,
+		.be_hw_params_fixup = msm_slim_0_rx_be_hw_params_fixup,
+		.ops = &msm8226_be_ops,
+		/* dai link has playback support */
+		.ignore_pmdown_time = 1,
+	},
+	{
+		.name = LPASS_BE_SLIMBUS_4_TX,
+		.stream_name = "Slimbus4 Capture",
+		.cpu_dai_name = "msm-dai-q6-dev.16393",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "tapan_codec",
+		.codec_dai_name	= "tapan_tx1",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_SLIMBUS_4_TX,
+		.be_hw_params_fixup = msm_slim_0_tx_be_hw_params_fixup,
+		.ops = &msm8226_be_ops,
+	},
+};
+
+struct snd_soc_card snd_soc_card_msm8226 = {
+	.name		= "msm8226-tapan-snd-card",
+	.dai_link	= msm8226_dai,
+	.num_links	= ARRAY_SIZE(msm8226_dai),
+};
+
+static int msm8226_prepare_codec_mclk(struct snd_soc_card *card)
+{
+	return 0;
+}
+
+static __devinit int msm8226_asoc_machine_probe(struct platform_device *pdev)
+{
+	struct snd_soc_card *card = &snd_soc_card_msm8226;
+	struct msm8226_asoc_mach_data *pdata;
+	int ret;
+
+	if (!pdev->dev.of_node) {
+		dev_err(&pdev->dev, "No platform supplied from device tree\n");
+		return -EINVAL;
+	}
+
+	pdata = devm_kzalloc(&pdev->dev,
+			sizeof(struct msm8226_asoc_mach_data), GFP_KERNEL);
+	if (!pdata) {
+		dev_err(&pdev->dev, "Can't allocate msm8226_asoc_mach_data\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	card->dev = &pdev->dev;
+	platform_set_drvdata(pdev, card);
+	snd_soc_card_set_drvdata(card, pdata);
+
+	ret = snd_soc_of_parse_card_name(card, "qcom,model");
+	if (ret)
+		goto err;
+
+	ret = snd_soc_of_parse_audio_routing(card,
+			"qcom,audio-routing");
+	if (ret)
+		goto err;
+
+	ret = of_property_read_u32(pdev->dev.of_node,
+			"qcom,tapan-mclk-clk-freq", &pdata->mclk_freq);
+	if (ret) {
+		dev_err(&pdev->dev, "Looking up %s property in node %s failed",
+			"qcom,tapan-mclk-clk-freq",
+			pdev->dev.of_node->full_name);
+		goto err;
+	}
+
+	if (pdata->mclk_freq != 9600000) {
+		dev_err(&pdev->dev, "unsupported tapan mclk freq %u\n",
+			pdata->mclk_freq);
+		ret = -EINVAL;
+		goto err;
+	}
+
+	/* TODO: MCLK GPIO */
+
+	ret = msm8226_prepare_codec_mclk(card);
+	if (ret)
+		goto err;
+
+	ret = snd_soc_register_card(card);
+	if (ret) {
+		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
+			ret);
+		goto err;
+	}
+	mutex_init(&cdc_mclk_mutex);
+
+	return 0;
+err:
+	devm_kfree(&pdev->dev, pdata);
+	return ret;
+}
+
+static int __devexit msm8226_asoc_machine_remove(struct platform_device *pdev)
+{
+	struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+	/* TODO: GPIO MCLK */
+	snd_soc_unregister_card(card);
+
+	return 0;
+}
+
+static const struct of_device_id msm8226_asoc_machine_of_match[]  = {
+	{ .compatible = "qcom,msm8226-audio-tapan", },
+	{},
+};
+
+static struct platform_driver msm8226_asoc_machine_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+		.pm = &snd_soc_pm_ops,
+		.of_match_table = msm8226_asoc_machine_of_match,
+	},
+	.probe = msm8226_asoc_machine_probe,
+	.remove = __devexit_p(msm8226_asoc_machine_remove),
+};
+module_platform_driver(msm8226_asoc_machine_driver);
+
+MODULE_DESCRIPTION("ALSA SoC msm");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_DEVICE_TABLE(of, msm8226_asoc_machine_of_match);
diff --git a/sound/soc/msm/msm8660-apq-wm8903.c b/sound/soc/msm/msm8660-apq-wm8903.c
index e697c3f..f93a269 100644
--- a/sound/soc/msm/msm8660-apq-wm8903.c
+++ b/sound/soc/msm/msm8660-apq-wm8903.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-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
diff --git a/sound/soc/msm/msm8660.c b/sound/soc/msm/msm8660.c
index 4cbfd45..6d7d2ee 100644
--- a/sound/soc/msm/msm8660.c
+++ b/sound/soc/msm/msm8660.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/sound/soc/msm/msm8930.c b/sound/soc/msm/msm8930.c
index bb9f2be..ae9468f 100644
--- a/sound/soc/msm/msm8930.c
+++ b/sound/soc/msm/msm8930.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -170,8 +170,12 @@
 				}
 			} else {
 
-				if (machine_is_msm8930_mtp()
-					|| machine_is_msm8930_fluid()) {
+				/*
+				 * 8930 CDP does not have a 5V speaker boost,
+				 * hence the GPIO enable for speaker boost is
+				 * only required for platforms other than CDP
+				 */
+				if (!machine_is_msm8930_cdp()) {
 					ret = msm8930_cfg_spkr_gpio(
 					  SPKR_BOOST_GPIO, 1, "SPKR_BOOST");
 					if (ret) {
@@ -208,8 +212,7 @@
 			return;
 		}
 
-		if (machine_is_msm8930_mtp()
-			|| machine_is_msm8930_fluid()) {
+		if (!machine_is_msm8930_cdp()) {
 			pr_debug("%s: Free speaker boost gpio %u\n",
 					__func__, SPKR_BOOST_GPIO);
 			gpio_direction_output(SPKR_BOOST_GPIO, 0);
diff --git a/sound/soc/msm/msm8960.c b/sound/soc/msm/msm8960.c
index da62729..f987eb4 100644
--- a/sound/soc/msm/msm8960.c
+++ b/sound/soc/msm/msm8960.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -85,6 +85,10 @@
 static struct snd_soc_jack button_jack;
 static atomic_t auxpcm_rsc_ref;
 
+static bool hs_micbias_always_on;
+module_param(hs_micbias_always_on, bool, 0444);
+MODULE_PARM_DESC(hs_micbias_always_on, "Keep micbias always on if headset is inserted");
+
 static bool hs_detect_use_gpio;
 module_param(hs_detect_use_gpio, bool, 0444);
 MODULE_PARM_DESC(hs_detect_use_gpio, "Use GPIO for headset detection");
@@ -93,7 +97,6 @@
 module_param(hs_detect_extn_cable, bool, 0444);
 MODULE_PARM_DESC(hs_detect_extn_cable, "Enable extension cable feature");
 
-
 static bool hs_detect_use_firmware;
 module_param(hs_detect_use_firmware, bool, 0444);
 MODULE_PARM_DESC(hs_detect_use_firmware, "Use firmware for headset detection");
@@ -115,6 +118,7 @@
 	.gpio_level_insert = 1,
 	.swap_gnd_mic = NULL,
 	.detect_extn_cable = false,
+	.micbias_always_on = false
 };
 
 static u32 us_euro_sel_gpio = PM8921_GPIO_PM_TO_SYS(JACK_US_EURO_SEL_GPIO);
@@ -940,6 +944,9 @@
 	if (machine_is_msm8960_cdp())
 		mbhc_cfg.swap_gnd_mic = msm8960_swap_gnd_mic;
 
+	if (hs_micbias_always_on)
+		mbhc_cfg.micbias_always_on = true;
+
 	if (hs_detect_use_gpio) {
 		mbhc_cfg.gpio = PM8921_GPIO_PM_TO_SYS(JACK_DETECT_GPIO);
 		mbhc_cfg.gpio_irq = JACK_DETECT_INT;
diff --git a/sound/soc/msm/msm8974.c b/sound/soc/msm/msm8974.c
index 633066f..c5cfa11 100644
--- a/sound/soc/msm/msm8974.c
+++ b/sound/soc/msm/msm8974.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -26,8 +26,10 @@
 #include <sound/jack.h>
 #include <asm/mach-types.h>
 #include <mach/socinfo.h>
-#include <qdsp6v2/msm-pcm-routing-v2.h>
+#include <sound/pcm_params.h>
+#include "qdsp6v2/msm-pcm-routing-v2.h"
 #include "../codecs/wcd9320.h"
+#include <linux/io.h>
 
 #define DRV_NAME "msm8974-asoc-taiko"
 
@@ -40,15 +42,26 @@
 #define BTSCO_RATE_8KHZ 8000
 #define BTSCO_RATE_16KHZ 16000
 
+static int slim0_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+
+#define SAMPLING_RATE_48KHZ 48000
+#define SAMPLING_RATE_96KHZ 96000
+
+static int msm8974_auxpcm_rate = 8000;
 #define LO_1_SPK_AMP	0x1
 #define LO_3_SPK_AMP	0x2
 #define LO_2_SPK_AMP	0x4
 #define LO_4_SPK_AMP	0x8
 
-#define GPIO_AUX_PCM_DOUT 43
-#define GPIO_AUX_PCM_DIN 44
-#define GPIO_AUX_PCM_SYNC 45
-#define GPIO_AUX_PCM_CLK 46
+#define LPAIF_OFFSET 0xFE000000
+#define LPAIF_PRI_MODE_MUXSEL (LPAIF_OFFSET + 0x2B000)
+#define LPAIF_SEC_MODE_MUXSEL (LPAIF_OFFSET + 0x2C000)
+#define LPAIF_TER_MODE_MUXSEL (LPAIF_OFFSET + 0x2D000)
+#define LPAIF_QUAD_MODE_MUXSEL (LPAIF_OFFSET + 0x2E000)
+
+#define I2S_PCM_SEL 1
+#define I2S_PCM_SEL_OFFSET 1
+
 
 #define WCD9XXX_MBHC_DEF_BUTTONS 8
 #define WCD9XXX_MBHC_DEF_RLOADS 5
@@ -56,6 +69,38 @@
 
 /* It takes about 13ms for Class-D PAs to ramp-up */
 #define EXT_CLASS_D_EN_DELAY 13000
+#define EXT_CLASS_D_DIS_DELAY 3000
+#define EXT_CLASS_D_DELAY_DELTA 2000
+
+#define NUM_OF_AUXPCM_GPIOS 4
+
+static inline int param_is_mask(int p)
+{
+	return ((p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) &&
+			(p <= SNDRV_PCM_HW_PARAM_LAST_MASK));
+}
+
+static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, int n)
+{
+	return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]);
+}
+
+static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned bit)
+{
+	if (bit >= SNDRV_MASK_MAX)
+		return;
+	if (param_is_mask(n)) {
+		struct snd_mask *m = param_to_mask(p, n);
+		m->bits[0] = 0;
+		m->bits[1] = 0;
+		m->bits[bit >> 5] |= (1 << (bit & 31));
+	}
+}
+
+static const char *const auxpcm_rate_text[] = {"rate_8000", "rate_16000"};
+static const struct soc_enum msm8974_auxpcm_enum[] = {
+		SOC_ENUM_SINGLE_EXT(2, auxpcm_rate_text),
+};
 
 void *def_taiko_mbhc_cal(void);
 static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, int enable,
@@ -75,11 +120,44 @@
 	.swap_gnd_mic = NULL,
 };
 
+struct msm_auxpcm_gpio {
+	unsigned gpio_no;
+	const char *gpio_name;
+};
+
+struct msm_auxpcm_ctrl {
+	struct msm_auxpcm_gpio *pin_data;
+	u32 cnt;
+};
+
 struct msm8974_asoc_mach_data {
 	int mclk_gpio;
 	u32 mclk_freq;
+	struct msm_auxpcm_ctrl *pri_auxpcm_ctrl;
 };
 
+#define GPIO_NAME_INDEX 0
+#define DT_PARSE_INDEX  1
+
+static char *msm_auxpcm_gpio_name[][2] = {
+	{"PRIM_AUXPCM_CLK",       "prim-auxpcm-gpio-clk"},
+	{"PRIM_AUXPCM_SYNC",      "prim-auxpcm-gpio-sync"},
+	{"PRIM_AUXPCM_DIN",       "prim-auxpcm-gpio-din"},
+	{"PRIM_AUXPCM_DOUT",      "prim-auxpcm-gpio-dout"},
+};
+
+void *lpaif_pri_muxsel_virt_addr;
+
+struct msm8974_liquid_dock_dev {
+	int dock_plug_gpio;
+	int dock_plug_irq;
+	int dock_plug_det;
+	struct snd_soc_dapm_context *dapm;
+	struct work_struct irq_work;
+};
+
+static struct msm8974_liquid_dock_dev *msm8974_liquid_dock_dev;
+
 /* Shared channel numbers for Slimbus ports that connect APQ to MDM. */
 enum {
 	SLIM_1_RX_1 = 145, /* BT-SCO and USB TX */
@@ -100,12 +178,15 @@
 
 static int msm_btsco_rate = BTSCO_RATE_8KHZ;
 static int msm_btsco_ch = 1;
+static int msm_hdmi_rx_ch = 2;
+static int slim0_rx_sample_rate = SAMPLING_RATE_48KHZ;
 
 static struct mutex cdc_mclk_mutex;
 static struct q_clkdiv *codec_clk;
 static int clk_users;
 static atomic_t auxpcm_rsc_ref;
 
+
 static int msm8974_liquid_ext_spk_power_amp_init(void)
 {
 	int ret = 0;
@@ -140,23 +221,130 @@
 
 static void msm8974_liquid_ext_spk_power_amp_enable(u32 on)
 {
-	if (on)
+	if (on) {
 		regulator_enable(ext_spk_amp_regulator);
-	else
+		gpio_direction_output(ext_spk_amp_gpio, on);
+		/*time takes enable the external power amplifier*/
+		usleep_range(EXT_CLASS_D_EN_DELAY,
+			     EXT_CLASS_D_EN_DELAY + EXT_CLASS_D_DELAY_DELTA);
+	} else {
+		gpio_direction_output(ext_spk_amp_gpio, on);
 		regulator_disable(ext_spk_amp_regulator);
+		/*time takes disable the external power amplifier*/
+		usleep_range(EXT_CLASS_D_DIS_DELAY,
+			     EXT_CLASS_D_DIS_DELAY + EXT_CLASS_D_DELAY_DELTA);
+	}
 
-	gpio_direction_output(ext_spk_amp_gpio, on);
-	usleep_range(EXT_CLASS_D_EN_DELAY, EXT_CLASS_D_EN_DELAY);
 	pr_debug("%s: %s external speaker PAs.\n", __func__,
 			on ? "Enable" : "Disable");
 }
 
+static void msm8974_liquid_docking_irq_work(struct work_struct *work)
+{
+	struct msm8974_liquid_dock_dev *dock_dev =
+		container_of(work,
+					 struct msm8974_liquid_dock_dev,
+					 irq_work);
+
+	struct snd_soc_dapm_context *dapm = dock_dev->dapm;
+
+
+	mutex_lock(&dapm->codec->mutex);
+	dock_dev->dock_plug_det =
+		gpio_get_value(dock_dev->dock_plug_gpio);
+
+
+	if (0 == dock_dev->dock_plug_det) {
+		if ((msm8974_ext_spk_pamp & LO_1_SPK_AMP) &&
+			(msm8974_ext_spk_pamp & LO_3_SPK_AMP) &&
+			(msm8974_ext_spk_pamp & LO_2_SPK_AMP) &&
+			(msm8974_ext_spk_pamp & LO_4_SPK_AMP))
+			msm8974_liquid_ext_spk_power_amp_enable(1);
+	} else {
+		if ((msm8974_ext_spk_pamp & LO_1_SPK_AMP) &&
+			(msm8974_ext_spk_pamp & LO_3_SPK_AMP) &&
+			(msm8974_ext_spk_pamp & LO_2_SPK_AMP) &&
+			(msm8974_ext_spk_pamp & LO_4_SPK_AMP))
+			msm8974_liquid_ext_spk_power_amp_enable(0);
+	}
+
+	mutex_unlock(&dapm->codec->mutex);
+
+}
+
+
+static irqreturn_t msm8974_liquid_docking_irq_handler(int irq, void *dev)
+{
+	struct msm8974_liquid_dock_dev *dock_dev = dev;
+
+	/* switch speakers should not run in interrupt context */
+	schedule_work(&dock_dev->irq_work);
+
+	return IRQ_HANDLED;
+}
+
+static int msm8974_liquid_init_docking(struct snd_soc_dapm_context *dapm)
+{
+	int ret = 0;
+	int dock_plug_gpio = 0;
+
+	/* plug in docking speaker+plug in device OR unplug one of them */
+	u32 dock_plug_irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
+
+	dock_plug_gpio = of_get_named_gpio(spdev->dev.of_node,
+					   "qcom,dock-plug-det-irq", 0);
+
+	if (dock_plug_gpio >= 0) {
+
+		msm8974_liquid_dock_dev =
+		 kzalloc(sizeof(*msm8974_liquid_dock_dev), GFP_KERNEL);
+
+		if (!msm8974_liquid_dock_dev) {
+			pr_err("msm8974_liquid_dock_dev alloc fail.\n");
+			return -ENOMEM;
+		}
+
+		msm8974_liquid_dock_dev->dock_plug_gpio = dock_plug_gpio;
+
+		ret = gpio_request(msm8974_liquid_dock_dev->dock_plug_gpio,
+					   "dock-plug-det-irq");
+		if (ret) {
+			pr_err("%s:failed request msm8974_liquid_dock_plug_gpio.\n",
+				__func__);
+			return -EINVAL;
+		}
+
+		msm8974_liquid_dock_dev->dock_plug_det =
+			gpio_get_value(msm8974_liquid_dock_dev->dock_plug_gpio);
+
+		msm8974_liquid_dock_dev->dock_plug_irq =
+			gpio_to_irq(msm8974_liquid_dock_dev->dock_plug_gpio);
+
+		msm8974_liquid_dock_dev->dapm = dapm;
+
+		ret = request_irq(msm8974_liquid_dock_dev->dock_plug_irq,
+				  msm8974_liquid_docking_irq_handler,
+				  dock_plug_irq_flags,
+				  "liquid_dock_plug_irq",
+				  msm8974_liquid_dock_dev);
+
+		INIT_WORK(
+			&msm8974_liquid_dock_dev->irq_work,
+			msm8974_liquid_docking_irq_work);
+	}
+
+	return 0;
+}
+
+
+
+
 static void msm8974_ext_spk_power_amp_on(u32 spk)
 {
 	if (spk & (LO_1_SPK_AMP |
-					  LO_3_SPK_AMP |
-					  LO_2_SPK_AMP |
-					  LO_4_SPK_AMP)) {
+		   LO_3_SPK_AMP |
+		   LO_2_SPK_AMP |
+		   LO_4_SPK_AMP)) {
 
 		pr_debug("%s() External Left/Right Speakers already turned on. spk = 0x%08x\n",
 						__func__, spk);
@@ -168,7 +356,9 @@
 			(msm8974_ext_spk_pamp & LO_2_SPK_AMP) &&
 			(msm8974_ext_spk_pamp & LO_4_SPK_AMP)) {
 
-			if (ext_spk_amp_gpio >= 0)
+			if (ext_spk_amp_gpio >= 0 &&
+				msm8974_liquid_dock_dev != NULL &&
+				msm8974_liquid_dock_dev->dock_plug_det == 0)
 				msm8974_liquid_ext_spk_power_amp_enable(1);
 		}
 	} else  {
@@ -182,15 +372,17 @@
 static void msm8974_ext_spk_power_amp_off(u32 spk)
 {
 	if (spk & (LO_1_SPK_AMP |
-					  LO_3_SPK_AMP |
-					  LO_2_SPK_AMP |
-					  LO_4_SPK_AMP)) {
+		   LO_3_SPK_AMP |
+		   LO_2_SPK_AMP |
+		   LO_4_SPK_AMP)) {
 
 		pr_debug("%s Left and right speakers case spk = 0x%08x",
 				  __func__, spk);
 
 		if (!msm8974_ext_spk_pamp) {
-			if (ext_spk_amp_gpio >= 0)
+			if (ext_spk_amp_gpio >= 0 &&
+				msm8974_liquid_dock_dev != NULL &&
+				msm8974_liquid_dock_dev->dock_plug_det == 0)
 				msm8974_liquid_ext_spk_power_amp_enable(0);
 			msm8974_ext_spk_pamp = 0;
 		}
@@ -364,6 +556,9 @@
 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
 	SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL),
 	SND_SOC_DAPM_MIC("ANCLeft Headset Mic", NULL),
+	SND_SOC_DAPM_MIC("Analog Mic4", NULL),
+	SND_SOC_DAPM_MIC("Analog Mic6", NULL),
+	SND_SOC_DAPM_MIC("Analog Mic7", NULL),
 
 	SND_SOC_DAPM_MIC("Digital Mic1", NULL),
 	SND_SOC_DAPM_MIC("Digital Mic2", NULL),
@@ -376,6 +571,10 @@
 static const char *const spk_function[] = {"Off", "On"};
 static const char *const slim0_rx_ch_text[] = {"One", "Two"};
 static const char *const slim0_tx_ch_text[] = {"One", "Two", "Three", "Four"};
+static char const *hdmi_rx_ch_text[] = {"Two", "Three", "Four", "Five",
+					"Six", "Seven", "Eight"};
+static char const *rx_bit_format_text[] = {"S16_LE", "S24_LE"};
+static char const *slim0_rx_sample_rate_text[] = {"KHZ_48", "KHZ_96"};
 
 static const struct soc_enum msm_enum[] = {
 	SOC_ENUM_SINGLE_EXT(2, spk_function),
@@ -388,6 +587,87 @@
 	SOC_ENUM_SINGLE_EXT(2, btsco_rate_text),
 };
 
+static int slim0_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	int sample_rate_val = 0;
+
+	switch (slim0_rx_sample_rate) {
+	case SAMPLING_RATE_96KHZ:
+		sample_rate_val = 1;
+		break;
+
+	case SAMPLING_RATE_48KHZ:
+	default:
+		sample_rate_val = 0;
+		break;
+	}
+
+	ucontrol->value.integer.value[0] = sample_rate_val;
+	pr_debug("%s: slim0_rx_sample_rate = %d\n", __func__,
+				slim0_rx_sample_rate);
+
+	return 0;
+}
+
+static int slim0_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	pr_debug("%s: ucontrol value = %ld\n", __func__,
+			ucontrol->value.integer.value[0]);
+
+	switch (ucontrol->value.integer.value[0]) {
+	case 1:
+		slim0_rx_sample_rate = SAMPLING_RATE_96KHZ;
+		break;
+	case 0:
+	default:
+		slim0_rx_sample_rate = SAMPLING_RATE_48KHZ;
+	}
+
+	pr_debug("%s: slim0_rx_sample_rate = %d\n", __func__,
+			slim0_rx_sample_rate);
+
+	return 0;
+}
+
+static int slim0_rx_bit_format_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+
+	switch (slim0_rx_bit_format) {
+	case SNDRV_PCM_FORMAT_S24_LE:
+		ucontrol->value.integer.value[0] = 1;
+		break;
+
+	case SNDRV_PCM_FORMAT_S16_LE:
+	default:
+		ucontrol->value.integer.value[0] = 0;
+		break;
+	}
+
+	pr_debug("%s: slim0_rx_bit_format = %d, ucontrol value = %ld\n",
+			 __func__, slim0_rx_bit_format,
+			ucontrol->value.integer.value[0]);
+
+	return 0;
+}
+
+static int slim0_rx_bit_format_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	switch (ucontrol->value.integer.value[0]) {
+	case 1:
+		slim0_rx_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+		break;
+	case 0:
+	default:
+		slim0_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+		break;
+	}
+	return 0;
+}
+
 static int msm_slim_0_rx_ch_get(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
@@ -451,6 +731,30 @@
 	return 0;
 }
 
+static int msm_hdmi_rx_ch_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	pr_debug("%s: msm_hdmi_rx_ch  = %d\n", __func__,
+			msm_hdmi_rx_ch);
+	ucontrol->value.integer.value[0] = msm_hdmi_rx_ch - 2;
+
+	return 0;
+}
+
+static int msm_hdmi_rx_ch_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	msm_hdmi_rx_ch = ucontrol->value.integer.value[0] + 2;
+	if (msm_hdmi_rx_ch > 8) {
+		pr_err("%s: channels exceeded 8.Limiting to max channels-8\n",
+			__func__);
+		msm_hdmi_rx_ch = 8;
+	}
+	pr_debug("%s: msm_hdmi_rx_ch = %d\n", __func__, msm_hdmi_rx_ch);
+
+	return 1;
+}
+
 static const struct snd_kcontrol_new int_btsco_rate_mixer_controls[] = {
 	SOC_ENUM_EXT("Internal BTSCO SampleRate", msm_btsco_enum[0],
 		     msm_btsco_rate_get, msm_btsco_rate_put),
@@ -471,6 +775,30 @@
 	return 0;
 }
 
+static int msm8974_auxpcm_rate_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	ucontrol->value.integer.value[0] = msm8974_auxpcm_rate;
+	return 0;
+}
+
+static int msm8974_auxpcm_rate_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	switch (ucontrol->value.integer.value[0]) {
+	case 0:
+		msm8974_auxpcm_rate = 8000;
+		break;
+	case 1:
+		msm8974_auxpcm_rate = 16000;
+		break;
+	default:
+		msm8974_auxpcm_rate = 8000;
+		break;
+	}
+	return 0;
+}
+
 static int msm_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd,
 					struct snd_pcm_hw_params *params)
 {
@@ -480,8 +808,7 @@
 	struct snd_interval *channels =
 	    hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
 
-	/* PCM only supports mono output with 8khz sample rate */
-	rate->min = rate->max = 8000;
+	rate->min = rate->max = msm8974_auxpcm_rate;
 	channels->min = channels->max = 1;
 
 	return 0;
@@ -511,64 +838,94 @@
 	pr_debug("%s channels->min %u channels->max %u ()\n", __func__,
 			channels->min, channels->max);
 
+	if (channels->max < 2)
+		channels->min = channels->max = 2;
 	rate->min = rate->max = 48000;
+	channels->min = channels->max = msm_hdmi_rx_ch;
 
 	return 0;
 }
 
-static int msm_aux_pcm_get_gpios(void)
+static int msm_aux_pcm_get_gpios(struct snd_pcm_substream *substream)
 {
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_card *card = rtd->card;
+	struct msm8974_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+	struct msm_auxpcm_ctrl *auxpcm_ctrl = NULL;
+	struct msm_auxpcm_gpio *pin_data = NULL;
 	int ret = 0;
+	int i;
+	int j;
 
-	pr_debug("%s\n", __func__);
-
-	ret = gpio_request(GPIO_AUX_PCM_DOUT, "AUX PCM DOUT");
-	if (ret < 0) {
-		pr_err("%s: Failed to request gpio(%d): AUX PCM DOUT",
-				__func__, GPIO_AUX_PCM_DOUT);
-		goto fail_dout;
+	if (pdata == NULL) {
+		pr_err("%s: pdata is NULL\n", __func__);
+		ret = -EINVAL;
+		goto err;
 	}
 
-	ret = gpio_request(GPIO_AUX_PCM_DIN, "AUX PCM DIN");
-	if (ret < 0) {
-		pr_err("%s: Failed to request gpio(%d): AUX PCM DIN",
-				__func__, GPIO_AUX_PCM_DIN);
-		goto fail_din;
+	auxpcm_ctrl = pdata->pri_auxpcm_ctrl;
+
+	if (auxpcm_ctrl == NULL || auxpcm_ctrl->pin_data == NULL) {
+		pr_err("%s: Ctrl pointers are NULL\n", __func__);
+		ret = -EINVAL;
+		goto err;
+	}
+	pin_data = auxpcm_ctrl->pin_data;
+	for (i = 0; i < auxpcm_ctrl->cnt; i++, pin_data++) {
+		ret = gpio_request(pin_data->gpio_no,
+				pin_data->gpio_name);
+		pr_debug("%s: gpio = %d, gpio name = %s\n"
+			"ret = %d\n", __func__,
+			pin_data->gpio_no,
+			pin_data->gpio_name,
+			ret);
+		if (ret) {
+			pr_err("%s: Failed to request gpio %d\n",
+				__func__, pin_data->gpio_no);
+			/* Release all GPIOs on failure */
+			for (j = i; j >= 0; j--)
+				gpio_free(pin_data->gpio_no);
+			goto err;
+		}
 	}
 
-	ret = gpio_request(GPIO_AUX_PCM_SYNC, "AUX PCM SYNC");
-	if (ret < 0) {
-		pr_err("%s: Failed to request gpio(%d): AUX PCM SYNC",
-				__func__, GPIO_AUX_PCM_SYNC);
-		goto fail_sync;
-	}
-	ret = gpio_request(GPIO_AUX_PCM_CLK, "AUX PCM CLK");
-	if (ret < 0) {
-		pr_err("%s: Failed to request gpio(%d): AUX PCM CLK",
-				__func__, GPIO_AUX_PCM_CLK);
-		goto fail_clk;
-	}
-
-	return 0;
-
-fail_clk:
-	gpio_free(GPIO_AUX_PCM_SYNC);
-fail_sync:
-	gpio_free(GPIO_AUX_PCM_DIN);
-fail_din:
-	gpio_free(GPIO_AUX_PCM_DOUT);
-fail_dout:
-
+err:
 	return ret;
 }
-static int msm_aux_pcm_free_gpios(void)
-{
-	gpio_free(GPIO_AUX_PCM_DIN);
-	gpio_free(GPIO_AUX_PCM_DOUT);
-	gpio_free(GPIO_AUX_PCM_SYNC);
-	gpio_free(GPIO_AUX_PCM_CLK);
 
-	return 0;
+static int msm_aux_pcm_free_gpios(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_card *card = rtd->card;
+	struct msm8974_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+	struct msm_auxpcm_ctrl *auxpcm_ctrl = NULL;
+	struct msm_auxpcm_gpio *pin_data = NULL;
+	int ret = 0;
+	int i;
+
+	if (pdata == NULL) {
+		pr_err("%s: pdata is NULL\n", __func__);
+		ret = -EINVAL;
+		goto err;
+	}
+
+	auxpcm_ctrl = pdata->pri_auxpcm_ctrl;
+
+	if (auxpcm_ctrl == NULL || auxpcm_ctrl->pin_data == NULL) {
+		pr_err("%s: Ctrl pointers are NULL\n", __func__);
+		ret = -EINVAL;
+		goto err;
+	}
+
+	pin_data = auxpcm_ctrl->pin_data;
+	for (i = 0; i < auxpcm_ctrl->cnt; i++, pin_data++) {
+		gpio_free(pin_data->gpio_no);
+		pr_debug("%s: gpio = %d, gpio_name = %s\n",
+			__func__, pin_data->gpio_no,
+			pin_data->gpio_name);
+	}
+err:
+	return ret;
 }
 
 static int msm_auxpcm_startup(struct snd_pcm_substream *substream)
@@ -577,8 +934,16 @@
 
 	pr_debug("%s(): substream = %s, auxpcm_rsc_ref counter = %d\n",
 		__func__, substream->name, atomic_read(&auxpcm_rsc_ref));
-	if (atomic_inc_return(&auxpcm_rsc_ref) == 1)
-		ret = msm_aux_pcm_get_gpios();
+
+	if (atomic_inc_return(&auxpcm_rsc_ref) == 1) {
+		if (lpaif_pri_muxsel_virt_addr != NULL)
+			iowrite32(I2S_PCM_SEL << I2S_PCM_SEL_OFFSET,
+				lpaif_pri_muxsel_virt_addr);
+		else
+			pr_err("%s lpaif_pri_muxsel_virt_addr is NULL\n",
+				 __func__);
+		ret = msm_aux_pcm_get_gpios(substream);
+	}
 	if (ret < 0) {
 		pr_err("%s: Aux PCM GPIO request failed\n", __func__);
 		return -EINVAL;
@@ -592,7 +957,7 @@
 	pr_debug("%s(): substream = %s, auxpcm_rsc_ref counter = %d\n",
 		__func__, substream->name, atomic_read(&auxpcm_rsc_ref));
 	if (atomic_dec_return(&auxpcm_rsc_ref) == 0)
-		msm_aux_pcm_free_gpios();
+		msm_aux_pcm_free_gpios(substream);
 }
 static struct snd_soc_ops msm_auxpcm_be_ops = {
 	.startup = msm_auxpcm_startup,
@@ -609,9 +974,15 @@
 	    hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
 
 	pr_debug("%s()\n", __func__);
-	rate->min = rate->max = 48000;
+	param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+				   slim0_rx_bit_format);
+	rate->min = rate->max = slim0_rx_sample_rate;
 	channels->min = channels->max = msm_slim_0_rx_ch;
 
+	 pr_debug("%s: format = %d, rate = %d, channels = %d\n",
+			  __func__, params_format(params), params_rate(params),
+			  msm_slim_0_rx_ch);
+
 	return 0;
 }
 
@@ -647,15 +1018,26 @@
 	SOC_ENUM_SINGLE_EXT(2, spk_function),
 	SOC_ENUM_SINGLE_EXT(2, slim0_rx_ch_text),
 	SOC_ENUM_SINGLE_EXT(4, slim0_tx_ch_text),
+	SOC_ENUM_SINGLE_EXT(7, hdmi_rx_ch_text),
+	SOC_ENUM_SINGLE_EXT(2, rx_bit_format_text),
+	SOC_ENUM_SINGLE_EXT(2, slim0_rx_sample_rate_text),
 };
 
 static const struct snd_kcontrol_new msm_snd_controls[] = {
 	SOC_ENUM_EXT("Speaker Function", msm_snd_enum[0], msm8974_get_spk,
-		     msm8974_set_spk),
+			msm8974_set_spk),
 	SOC_ENUM_EXT("SLIM_0_RX Channels", msm_snd_enum[1],
-		     msm_slim_0_rx_ch_get, msm_slim_0_rx_ch_put),
+			msm_slim_0_rx_ch_get, msm_slim_0_rx_ch_put),
 	SOC_ENUM_EXT("SLIM_0_TX Channels", msm_snd_enum[2],
-		     msm_slim_0_tx_ch_get, msm_slim_0_tx_ch_put),
+			msm_slim_0_tx_ch_get, msm_slim_0_tx_ch_put),
+	SOC_ENUM_EXT("AUX PCM SampleRate", msm8974_auxpcm_enum[0],
+			msm8974_auxpcm_rate_get, msm8974_auxpcm_rate_put),
+	SOC_ENUM_EXT("HDMI_RX Channels", msm_snd_enum[3],
+			msm_hdmi_rx_ch_get, msm_hdmi_rx_ch_put),
+	SOC_ENUM_EXT("SLIM_0_RX Format", msm_snd_enum[4],
+			slim0_rx_bit_format_get, slim0_rx_bit_format_put),
+	SOC_ENUM_EXT("SLIM_0_RX SampleRate", msm_snd_enum[5],
+			slim0_rx_sample_rate_get, slim0_rx_sample_rate_put),
 };
 
 static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
@@ -694,6 +1076,13 @@
 		return err;
 	}
 
+	err = msm8974_liquid_init_docking(dapm);
+	if (err) {
+		pr_err("%s: LiQUID 8974 init Docking stat IRQ failed (%d)\n",
+			   __func__, err);
+		return err;
+	}
+
 	snd_soc_dapm_new_controls(dapm, msm8974_dapm_widgets,
 				ARRAY_SIZE(msm8974_dapm_widgets));
 
@@ -718,7 +1107,7 @@
 	return err;
 }
 
-static int msm_snd_startup(struct snd_pcm_substream *substream)
+static int msm8974_snd_startup(struct snd_pcm_substream *substream)
 {
 	pr_debug("%s(): substream = %s  stream = %d\n", __func__,
 		 substream->name, substream->stream);
@@ -775,21 +1164,21 @@
 	btn_high = wcd9xxx_mbhc_cal_btn_det_mp(btn_cfg,
 					       MBHC_BTN_DET_V_BTN_HIGH);
 	btn_low[0] = -50;
-	btn_high[0] = 10;
-	btn_low[1] = 11;
-	btn_high[1] = 52;
-	btn_low[2] = 53;
-	btn_high[2] = 94;
-	btn_low[3] = 95;
-	btn_high[3] = 133;
-	btn_low[4] = 134;
-	btn_high[4] = 171;
-	btn_low[5] = 172;
-	btn_high[5] = 208;
-	btn_low[6] = 209;
-	btn_high[6] = 244;
-	btn_low[7] = 245;
-	btn_high[7] = 330;
+	btn_high[0] = 20;
+	btn_low[1] = 21;
+	btn_high[1] = 61;
+	btn_low[2] = 62;
+	btn_high[2] = 104;
+	btn_low[3] = 105;
+	btn_high[3] = 148;
+	btn_low[4] = 149;
+	btn_high[4] = 189;
+	btn_low[5] = 190;
+	btn_high[5] = 228;
+	btn_low[6] = 229;
+	btn_high[6] = 269;
+	btn_low[7] = 270;
+	btn_high[7] = 500;
 	n_ready = wcd9xxx_mbhc_cal_btn_det_mp(btn_cfg, MBHC_BTN_DET_N_READY);
 	n_ready[0] = 80;
 	n_ready[1] = 68;
@@ -863,16 +1252,83 @@
 	return ret;
 }
 
-static void msm_snd_shutdown(struct snd_pcm_substream *substream)
+static void msm8974_snd_shudown(struct snd_pcm_substream *substream)
 {
 	pr_debug("%s(): substream = %s stream = %d\n", __func__,
 		 substream->name, substream->stream);
+
 }
 
 static struct snd_soc_ops msm8974_be_ops = {
-	.startup = msm_snd_startup,
+	.startup = msm8974_snd_startup,
 	.hw_params = msm_snd_hw_params,
-	.shutdown = msm_snd_shutdown,
+	.shutdown = msm8974_snd_shudown,
+};
+
+
+
+static int msm8974_slimbus_2_hw_params(struct snd_pcm_substream *substream,
+				struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+	int ret = 0;
+	unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS];
+	unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0;
+	unsigned int num_tx_ch = 0;
+	unsigned int num_rx_ch = 0;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+
+		num_rx_ch =  params_channels(params);
+
+		pr_debug("%s: %s rx_dai_id = %d  num_ch = %d\n", __func__,
+			codec_dai->name, codec_dai->id, num_rx_ch);
+
+		ret = snd_soc_dai_get_channel_map(codec_dai,
+				&tx_ch_cnt, tx_ch, &rx_ch_cnt , rx_ch);
+		if (ret < 0) {
+			pr_err("%s: failed to get codec chan map\n", __func__);
+			goto end;
+		}
+
+		ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0,
+				num_rx_ch, rx_ch);
+		if (ret < 0) {
+			pr_err("%s: failed to set cpu chan map\n", __func__);
+			goto end;
+		}
+	} else {
+
+		num_tx_ch =  params_channels(params);
+
+		pr_debug("%s: %s  tx_dai_id = %d  num_ch = %d\n", __func__,
+			codec_dai->name, codec_dai->id, num_tx_ch);
+
+		ret = snd_soc_dai_get_channel_map(codec_dai,
+				&tx_ch_cnt, tx_ch, &rx_ch_cnt , rx_ch);
+		if (ret < 0) {
+			pr_err("%s: failed to get codec chan map\n", __func__);
+			goto end;
+		}
+
+		ret = snd_soc_dai_set_channel_map(cpu_dai,
+				num_tx_ch, tx_ch, 0 , 0);
+		if (ret < 0) {
+			pr_err("%s: failed to set cpu chan map\n", __func__);
+			goto end;
+		}
+	}
+end:
+	return ret;
+}
+
+
+static struct snd_soc_ops msm8974_slimbus_2_be_ops = {
+	.startup = msm8974_snd_startup,
+	.hw_params = msm8974_slimbus_2_hw_params,
+	.shutdown = msm8974_snd_shudown,
 };
 
 /* Digital audio interface glue - connects codec <---> CPU */
@@ -882,7 +1338,7 @@
 		.name = "MSM8974 Media1",
 		.stream_name = "MultiMedia1",
 		.cpu_dai_name	= "MultiMedia1",
-		.platform_name  = "msm-pcm-dsp",
+		.platform_name  = "msm-pcm-dsp.0",
 		.dynamic = 1,
 		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
 			SND_SOC_DPCM_TRIGGER_POST},
@@ -897,7 +1353,7 @@
 		.name = "MSM8974 Media2",
 		.stream_name = "MultiMedia2",
 		.cpu_dai_name   = "MultiMedia2",
-		.platform_name  = "msm-pcm-dsp",
+		.platform_name  = "msm-pcm-dsp.0",
 		.dynamic = 1,
 		.codec_dai_name = "snd-soc-dummy-dai",
 		.codec_name = "snd-soc-dummy",
@@ -1092,6 +1548,21 @@
 		.codec_name = "snd-soc-dummy",
 		.be_id = MSM_FRONTEND_DAI_VOLTE,
 	},
+	{
+		.name = "MSM8974 LowLatency",
+		.stream_name = "MultiMedia5",
+		.cpu_dai_name   = "MultiMedia5",
+		.platform_name  = "msm-pcm-dsp.1",
+		.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,
+		/* this dainlink has playback support */
+		.ignore_pmdown_time = 1,
+		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA5,
+	},
 	/* Backend BT/FM DAI Links */
 	{
 		.name = LPASS_BE_INT_BT_SCO_RX,
@@ -1105,6 +1576,7 @@
 		.be_hw_params_fixup = msm_btsco_be_hw_params_fixup,
 		/* this dainlink has playback support */
 		.ignore_pmdown_time = 1,
+		.ignore_suspend = 1,
 	},
 	{
 		.name = LPASS_BE_INT_BT_SCO_TX,
@@ -1116,6 +1588,7 @@
 		.no_pcm = 1,
 		.be_id = MSM_BACKEND_DAI_INT_BT_SCO_TX,
 		.be_hw_params_fixup = msm_btsco_be_hw_params_fixup,
+		.ignore_suspend = 1,
 	},
 	{
 		.name = LPASS_BE_INT_FM_RX,
@@ -1129,6 +1602,7 @@
 		.be_hw_params_fixup = msm_be_hw_params_fixup,
 		/* this dainlink has playback support */
 		.ignore_pmdown_time = 1,
+		.ignore_suspend = 1,
 	},
 	{
 		.name = LPASS_BE_INT_FM_TX,
@@ -1140,6 +1614,7 @@
 		.no_pcm = 1,
 		.be_id = MSM_BACKEND_DAI_INT_FM_TX,
 		.be_hw_params_fixup = msm_be_hw_params_fixup,
+		.ignore_suspend = 1,
 	},
 	/* Backend AFE DAI Links */
 	{
@@ -1154,6 +1629,7 @@
 		.be_hw_params_fixup = msm_proxy_be_hw_params_fixup,
 		/* this dainlink has playback support */
 		.ignore_pmdown_time = 1,
+		.ignore_suspend = 1,
 	},
 	{
 		.name = LPASS_BE_AFE_PCM_TX,
@@ -1165,6 +1641,7 @@
 		.no_pcm = 1,
 		.be_id = MSM_BACKEND_DAI_AFE_PCM_TX,
 		.be_hw_params_fixup = msm_proxy_be_hw_params_fixup,
+		.ignore_suspend = 1,
 	},
 	/* HDMI Hostless */
 	{
@@ -1194,6 +1671,7 @@
 		.be_hw_params_fixup = msm_auxpcm_be_params_fixup,
 		.ops = &msm_auxpcm_be_ops,
 		.ignore_pmdown_time = 1,
+		.ignore_suspend = 1,
 		/* this dainlink has playback support */
 	},
 	{
@@ -1207,6 +1685,7 @@
 		.be_id = MSM_BACKEND_DAI_AUXPCM_TX,
 		.be_hw_params_fixup = msm_auxpcm_be_params_fixup,
 		.ops = &msm_auxpcm_be_ops,
+		.ignore_suspend = 1,
 	},
 	/* Backend DAI Links */
 	{
@@ -1222,6 +1701,7 @@
 		.be_hw_params_fixup = msm_slim_0_rx_be_hw_params_fixup,
 		.ops = &msm8974_be_ops,
 		.ignore_pmdown_time = 1, /* dai link has playback support */
+		.ignore_suspend = 1,
 	},
 	{
 		.name = LPASS_BE_SLIMBUS_0_TX,
@@ -1234,6 +1714,7 @@
 		.be_id = MSM_BACKEND_DAI_SLIMBUS_0_TX,
 		.be_hw_params_fixup = msm_slim_0_tx_be_hw_params_fixup,
 		.ops = &msm8974_be_ops,
+		.ignore_suspend = 1,
 	},
 	{
 		.name = LPASS_BE_SLIMBUS_1_RX,
@@ -1248,6 +1729,7 @@
 		.ops = &msm8974_be_ops,
 		/* dai link has playback support */
 		.ignore_pmdown_time = 1,
+		.ignore_suspend = 1,
 	},
 	{
 		.name = LPASS_BE_SLIMBUS_1_TX,
@@ -1260,6 +1742,7 @@
 		.be_id = MSM_BACKEND_DAI_SLIMBUS_1_TX,
 		.be_hw_params_fixup = msm_slim_0_tx_be_hw_params_fixup,
 		.ops = &msm8974_be_ops,
+		.ignore_suspend = 1,
 	},
 	{
 		.name = LPASS_BE_SLIMBUS_3_RX,
@@ -1274,6 +1757,7 @@
 		.ops = &msm8974_be_ops,
 		/* dai link has playback support */
 		.ignore_pmdown_time = 1,
+		.ignore_suspend = 1,
 	},
 	{
 		.name = LPASS_BE_SLIMBUS_3_TX,
@@ -1286,6 +1770,7 @@
 		.be_id = MSM_BACKEND_DAI_SLIMBUS_3_TX,
 		.be_hw_params_fixup = msm_slim_0_tx_be_hw_params_fixup,
 		.ops = &msm8974_be_ops,
+		.ignore_suspend = 1,
 	},
 	{
 		.name = LPASS_BE_SLIMBUS_4_RX,
@@ -1300,6 +1785,7 @@
 		.ops = &msm8974_be_ops,
 		/* dai link has playback support */
 		.ignore_pmdown_time = 1,
+		.ignore_suspend = 1,
 	},
 	{
 		.name = LPASS_BE_SLIMBUS_4_TX,
@@ -1312,6 +1798,7 @@
 		.be_id = MSM_BACKEND_DAI_SLIMBUS_4_TX,
 		.be_hw_params_fixup = msm_slim_0_tx_be_hw_params_fixup,
 		.ops = &msm8974_be_ops,
+		.ignore_suspend = 1,
 	},
 	/* Incall Record Uplink BACK END DAI Link */
 	{
@@ -1324,6 +1811,7 @@
 		.no_pcm = 1,
 		.be_id = MSM_BACKEND_DAI_INCALL_RECORD_TX,
 		.be_hw_params_fixup = msm_be_hw_params_fixup,
+		.ignore_suspend = 1,
 	},
 	/* Incall Record Downlink BACK END DAI Link */
 	{
@@ -1336,6 +1824,44 @@
 		.no_pcm = 1,
 		.be_id = MSM_BACKEND_DAI_INCALL_RECORD_RX,
 		.be_hw_params_fixup = msm_be_hw_params_fixup,
+		.ignore_suspend = 1,
+	},
+	/* Incall Music BACK END DAI Link */
+	{
+		.name = LPASS_BE_VOICE_PLAYBACK_TX,
+		.stream_name = "Voice Farend Playback",
+		.cpu_dai_name = "msm-dai-q6-dev.32773",
+		.platform_name = "msm-pcm-routing",
+		.codec_name     = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-rx",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX,
+		.be_hw_params_fixup = msm_be_hw_params_fixup,
+		.ignore_suspend = 1,
+	},
+	/* Ultrasound RX Back End DAI Link */
+	{
+		.name = "SLIMBUS_2 Hostless Playback",
+		.stream_name = "SLIMBUS_2 Hostless Playback",
+		.cpu_dai_name = "msm-dai-q6-dev.16388",
+		.platform_name = "msm-pcm-hostless",
+		.codec_name = "taiko_codec",
+		.codec_dai_name = "taiko_rx2",
+		.ignore_suspend = 1,
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ops = &msm8974_slimbus_2_be_ops,
+	},
+	/* Ultrasound TX Back End DAI Link */
+	{
+		.name = "SLIMBUS_2 Hostless Capture",
+		.stream_name = "SLIMBUS_2 Hostless Capture",
+		.cpu_dai_name = "msm-dai-q6-dev.16389",
+		.platform_name = "msm-pcm-hostless",
+		.codec_name = "taiko_codec",
+		.codec_dai_name = "taiko_tx2",
+		.ignore_suspend = 1,
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ops = &msm8974_slimbus_2_be_ops,
 	},
 };
 
@@ -1352,6 +1878,7 @@
 		.be_id = MSM_BACKEND_DAI_HDMI_RX,
 		.be_hw_params_fixup = msm8974_hdmi_be_hw_params_fixup,
 		.ignore_pmdown_time = 1,
+		.ignore_suspend = 1,
 	},
 };
 
@@ -1363,6 +1890,69 @@
 	.name		= "msm8974-taiko-snd-card",
 };
 
+static int msm8974_dtparse_auxpcm(struct platform_device *pdev,
+				struct msm8974_asoc_mach_data **pdata)
+{
+	int ret = 0;
+	int i = 0;
+	struct msm_auxpcm_gpio *pin_data = NULL;
+	struct msm_auxpcm_ctrl *ctrl;
+	unsigned int gpio_no[NUM_OF_AUXPCM_GPIOS];
+	enum of_gpio_flags flags = OF_GPIO_ACTIVE_LOW;
+	int prim_cnt = 0;
+
+	pin_data = devm_kzalloc(&pdev->dev, (ARRAY_SIZE(gpio_no) *
+				sizeof(struct msm_auxpcm_gpio)),
+				GFP_KERNEL);
+	if (!pin_data) {
+		dev_err(&pdev->dev, "No memory for gpio\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(gpio_no); i++) {
+		gpio_no[i] = of_get_named_gpio_flags(pdev->dev.of_node,
+				msm_auxpcm_gpio_name[i][DT_PARSE_INDEX],
+				0, &flags);
+
+		if (gpio_no[i] > 0) {
+			pin_data[i].gpio_name =
+				msm_auxpcm_gpio_name[prim_cnt][GPIO_NAME_INDEX];
+			pin_data[i].gpio_no = gpio_no[i];
+			dev_dbg(&pdev->dev, "%s:GPIO gpio[%s] =\n"
+				"0x%x\n", __func__,
+				pin_data[i].gpio_name,
+				pin_data[i].gpio_no);
+			prim_cnt++;
+		} else {
+			dev_err(&pdev->dev, "%s:Invalid AUXPCM GPIO[%s]= %x\n",
+				 __func__,
+				msm_auxpcm_gpio_name[i][GPIO_NAME_INDEX],
+				gpio_no[i]);
+			ret = -ENODEV;
+			goto err;
+		}
+	}
+
+	ctrl = devm_kzalloc(&pdev->dev,
+				sizeof(struct msm_auxpcm_ctrl), GFP_KERNEL);
+	if (!ctrl) {
+		dev_err(&pdev->dev, "No memory for gpio\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	ctrl->pin_data = pin_data;
+	ctrl->cnt = prim_cnt;
+	(*pdata)->pri_auxpcm_ctrl = ctrl;
+	return ret;
+
+err:
+	if (pin_data)
+		devm_kfree(&pdev->dev, pin_data);
+	return ret;
+}
+
 static int msm8974_prepare_codec_mclk(struct snd_soc_card *card)
 {
 	struct msm8974_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
@@ -1413,6 +2003,13 @@
 		goto err;
 	}
 
+	ret = msm8974_dtparse_auxpcm(pdev, &pdata);
+	if (ret) {
+		dev_err(&pdev->dev,
+		"%s: Auxpcm pin data parse failed\n", __func__);
+		goto err;
+	}
+
 	card->dev = &pdev->dev;
 	platform_set_drvdata(pdev, card);
 	snd_soc_card_set_drvdata(card, pdata);
@@ -1476,6 +2073,12 @@
 		card->num_links	= ARRAY_SIZE(msm8974_common_dai_links);
 	}
 
+	mutex_init(&cdc_mclk_mutex);
+	atomic_set(&auxpcm_rsc_ref, 0);
+	spdev = pdev;
+	ext_spk_amp_regulator = NULL;
+	msm8974_liquid_dock_dev = NULL;
+
 	ret = snd_soc_register_card(card);
 	if (ret) {
 		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
@@ -1483,12 +2086,12 @@
 		goto err;
 	}
 
-	mutex_init(&cdc_mclk_mutex);
-	atomic_set(&auxpcm_rsc_ref, 0);
-
-	spdev = pdev;
-	ext_spk_amp_regulator = NULL;
-
+	lpaif_pri_muxsel_virt_addr = ioremap(LPAIF_PRI_MODE_MUXSEL, 4);
+	if (lpaif_pri_muxsel_virt_addr == NULL) {
+		pr_err("%s Pri muxsel virt addr is null\n", __func__);
+		ret = -EINVAL;
+		goto err;
+	}
 	return 0;
 err:
 	devm_kfree(&pdev->dev, pdata);
@@ -1507,6 +2110,19 @@
 	if (ext_spk_amp_gpio >= 0)
 		gpio_free(ext_spk_amp_gpio);
 
+	if (msm8974_liquid_dock_dev != NULL) {
+		if (msm8974_liquid_dock_dev->dock_plug_gpio)
+			gpio_free(msm8974_liquid_dock_dev->dock_plug_gpio);
+
+		if (msm8974_liquid_dock_dev->dock_plug_irq)
+			free_irq(msm8974_liquid_dock_dev->dock_plug_irq,
+				 msm8974_liquid_dock_dev);
+
+		kfree(msm8974_liquid_dock_dev);
+		msm8974_liquid_dock_dev = NULL;
+	}
+
+	iounmap(lpaif_pri_muxsel_virt_addr);
 	snd_soc_unregister_card(card);
 
 	return 0;
diff --git a/sound/soc/msm/msm8x10.c b/sound/soc/msm/msm8x10.c
new file mode 100644
index 0000000..4dd85fc
--- /dev/null
+++ b/sound/soc/msm/msm8x10.c
@@ -0,0 +1,202 @@
+ /* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/mfd/pm8xxx/pm8921.h>
+#include <linux/qpnp/clkdiv.h>
+#include <sound/core.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/pcm.h>
+#include <sound/jack.h>
+#include <asm/mach-types.h>
+#include <mach/socinfo.h>
+#include <qdsp6v2/msm-pcm-routing-v2.h>
+#include <linux/module.h>
+#define DRV_NAME "msm8x10-asoc-wcd"
+
+static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+				struct snd_pcm_hw_params *params)
+{
+	struct snd_interval *rate = hw_param_interval(params,
+					SNDRV_PCM_HW_PARAM_RATE);
+
+	pr_debug("%s()\n", __func__);
+	rate->min = rate->max = 48000;
+
+	return 0;
+}
+
+static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
+{
+	pr_info("%s(), dev_name%s\n", __func__, dev_name(rtd->cpu_dai->dev));
+	return 0;
+}
+
+static int msm_snd_hw_params(struct snd_pcm_substream *substream,
+			     struct snd_pcm_hw_params *params)
+{
+	pr_debug("%s(): substream = %s  stream = %d\n", __func__,
+		 substream->name, substream->stream);
+	return 0;
+}
+
+static int msm_snd_startup(struct snd_pcm_substream *substream)
+{
+	pr_debug("%s(): substream = %s  stream = %d\n", __func__,
+		 substream->name, substream->stream);
+	return 0;
+}
+
+
+static void msm_snd_shutdown(struct snd_pcm_substream *substream)
+{
+	pr_debug("%s(): substream = %s stream = %d\n", __func__,
+		 substream->name, substream->stream);
+}
+
+static struct snd_soc_ops msm8x10_be_ops = {
+	.startup = msm_snd_startup,
+	.hw_params = msm_snd_hw_params,
+	.shutdown = msm_snd_shutdown,
+};
+
+/* Digital audio interface glue - connects codec <---> CPU */
+static struct snd_soc_dai_link msm8x10_dai[] = {
+	/* FrontEnd DAI Links */
+	{
+		.name = "MSM8X10 Media1",
+		.stream_name = "MultiMedia1",
+		.cpu_dai_name	= "MultiMedia1",
+		.platform_name  = "msm-pcm-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,
+		/* this dainlink has playback support */
+		.ignore_pmdown_time = 1,
+		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA1
+	},
+	{
+		.name = "MSM8X10 Media2",
+		.stream_name = "MultiMedia2",
+		.cpu_dai_name   = "MultiMedia2",
+		.platform_name  = "msm-pcm-dsp",
+		.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,
+		/* this dainlink has playback support */
+		.ignore_pmdown_time = 1,
+		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA2,
+	},
+	/* Backend I2S DAI Links */
+	{
+		.name = LPASS_BE_MI2S_RX,
+		.stream_name = "Primary MI2S Playback",
+		.cpu_dai_name = "msm-dai-q6-mi2s.0",
+		.platform_name = "msm-pcm-routing",
+		.codec_name     = "msm8x10-wcd-i2c-core.1-000d",
+		.codec_dai_name = "msm8x10_wcd_i2s_rx1",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_MI2S_RX,
+		.init = &msm_audrx_init,
+		.be_hw_params_fixup = msm_be_hw_params_fixup,
+		.ops = &msm8x10_be_ops,
+	},
+	{
+		.name = LPASS_BE_SEC_MI2S_TX,
+		.stream_name = "Secondary MI2S Capture",
+		.cpu_dai_name = "msm-dai-q6-mi2s.1",
+		.platform_name = "msm-pcm-routing",
+		.codec_name     = "msm8x10-wcd-i2c-core.1-000d",
+		.codec_dai_name = "msm8x10_wcd_i2s_tx1",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX,
+		.be_hw_params_fixup = msm_be_hw_params_fixup,
+		.ops = &msm8x10_be_ops,
+	},
+};
+
+struct snd_soc_card snd_soc_card_msm8x10 = {
+	.name		= "msm8x10-snd-card",
+	.dai_link	= msm8x10_dai,
+	.num_links	= ARRAY_SIZE(msm8x10_dai),
+};
+
+
+static __devinit int msm8x10_asoc_machine_probe(struct platform_device *pdev)
+{
+	struct snd_soc_card *card = &snd_soc_card_msm8x10;
+	int ret;
+
+	dev_dbg(&pdev->dev, "%s\n", __func__);
+	if (!pdev->dev.of_node) {
+		dev_err(&pdev->dev, "No platform supplied from device tree\n");
+		return -EINVAL;
+	}
+
+	card->dev = &pdev->dev;
+	platform_set_drvdata(pdev, card);
+
+
+	ret = snd_soc_register_card(card);
+	if (ret) {
+		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
+			ret);
+		goto err;
+	}
+
+	return 0;
+err:
+	return ret;
+}
+
+static int __devexit msm8x10_asoc_machine_remove(struct platform_device *pdev)
+{
+	struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+	snd_soc_unregister_card(card);
+
+	return 0;
+}
+
+static const struct of_device_id msm8x10_asoc_machine_of_match[]  = {
+	{ .compatible = "qcom,msm8x10-audio-codec", },
+	{},
+};
+
+static struct platform_driver msm8x10_asoc_machine_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+		.pm = &snd_soc_pm_ops,
+		.of_match_table = msm8x10_asoc_machine_of_match,
+	},
+	.probe = msm8x10_asoc_machine_probe,
+	.remove = __devexit_p(msm8x10_asoc_machine_remove),
+};
+module_platform_driver(msm8x10_asoc_machine_driver);
+
+MODULE_DESCRIPTION("ALSA SoC msm");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_DEVICE_TABLE(of, msm8x10_asoc_machine_of_match);
diff --git a/sound/soc/msm/msm8x60-dai.c b/sound/soc/msm/msm8x60-dai.c
index 8130f07..6312c2c 100644
--- a/sound/soc/msm/msm8x60-dai.c
+++ b/sound/soc/msm/msm8x60-dai.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, The Linux Foundation. All rights reserved.
  *
  * Derived from msm-pcm.c and msm7201.c.
  *
diff --git a/sound/soc/msm/msm8x60-pcm.c b/sound/soc/msm/msm8x60-pcm.c
index 6f5ad32..7993435 100644
--- a/sound/soc/msm/msm8x60-pcm.c
+++ b/sound/soc/msm/msm8x60-pcm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/sound/soc/msm/msm8x60-pcm.h b/sound/soc/msm/msm8x60-pcm.h
index d7c9ad8..31f0e63 100644
--- a/sound/soc/msm/msm8x60-pcm.h
+++ b/sound/soc/msm/msm8x60-pcm.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/sound/soc/msm/msm8x60.c b/sound/soc/msm/msm8x60.c
index 48ce610..fcc3f32 100644
--- a/sound/soc/msm/msm8x60.c
+++ b/sound/soc/msm/msm8x60.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/sound/soc/msm/msm_audio_mvs.h b/sound/soc/msm/msm_audio_mvs.h
index 2660b77..6ee457c 100644
--- a/sound/soc/msm/msm_audio_mvs.h
+++ b/sound/soc/msm/msm_audio_mvs.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/sound/soc/msm/mvs-dai.c b/sound/soc/msm/mvs-dai.c
index 521c5e5..206afd2 100644
--- a/sound/soc/msm/mvs-dai.c
+++ b/sound/soc/msm/mvs-dai.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/sound/soc/msm/qdsp6/q6adm.c b/sound/soc/msm/qdsp6/q6adm.c
index 2d8d9ca..4c50b53 100644
--- a/sound/soc/msm/qdsp6/q6adm.c
+++ b/sound/soc/msm/qdsp6/q6adm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -16,6 +16,7 @@
 #include <linux/jiffies.h>
 #include <linux/uaccess.h>
 #include <linux/atomic.h>
+#include <linux/err.h>
 
 #include <mach/qdsp6v2/audio_dev_ctl.h>
 #include <mach/qdsp6v2/audio_acdb.h>
@@ -54,6 +55,14 @@
 	int index;
 
 	pr_debug("SRS - %s", __func__);
+
+	index = afe_get_port_index(port_id);
+
+	if (IS_ERR_VALUE(index)) {
+		pr_err("%s: invald port id\n", __func__);
+		return index;
+	}
+
 	switch (srs_tech_id) {
 	case SRS_ID_GLOBAL: {
 		struct srs_trumedia_params_GLOBAL *glb_params = NULL;
@@ -199,7 +208,6 @@
 	open->hdr.src_port = port_id;
 	open->hdr.dest_svc = APR_SVC_ADM;
 	open->hdr.dest_domain = APR_DOMAIN_ADSP;
-	index = afe_get_port_index(port_id);
 	open->hdr.dest_port = atomic_read(&this_adm.copp_id[index]);
 	open->hdr.token = port_id;
 	open->hdr.opcode = ADM_CMD_SET_PARAMS;
@@ -1259,6 +1267,8 @@
 	int ret = 0, i = 0;
 	/* Assumes port_ids have already been validated during adm_open */
 	int index = afe_get_port_index(copp_id);
+	int copp_cnt;
+
 	if (index < 0 || index >= AFE_MAX_PORTS) {
 		pr_err("%s: invalid port idx %d token %d\n",
 					__func__, index, copp_id);
@@ -1281,9 +1291,19 @@
 	route.hdr.opcode = ADM_CMD_MATRIX_MAP_ROUTINGS;
 	route.num_sessions = 1;
 	route.session[0].id = session_id;
-	route.session[0].num_copps = num_copps;
 
-	for (i = 0; i < num_copps; i++) {
+	if (num_copps < ADM_MAX_COPPS) {
+		copp_cnt = num_copps;
+	} else {
+		copp_cnt = ADM_MAX_COPPS;
+		/* print out warning for now as playback/capture to/from
+		 * COPPs more than maximum allowed is extremely unlikely
+		 */
+		pr_warn("%s: max out routable COPPs\n", __func__);
+	}
+
+	route.session[0].num_copps = copp_cnt;
+	for (i = 0; i < copp_cnt; i++) {
 		int tmp;
 		port_id[i] = afe_convert_virtual_to_portid(port_id[i]);
 
@@ -1296,7 +1316,8 @@
 			route.session[0].copp_id[i] =
 					atomic_read(&this_adm.copp_id[tmp]);
 	}
-	if (num_copps % 2)
+
+	if (copp_cnt % 2)
 		route.session[0].copp_id[i] = 0;
 
 	switch (path) {
diff --git a/sound/soc/msm/qdsp6/q6afe.c b/sound/soc/msm/qdsp6/q6afe.c
index 2d44a41..9558fa4 100644
--- a/sound/soc/msm/qdsp6/q6afe.c
+++ b/sound/soc/msm/qdsp6/q6afe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -1587,7 +1587,7 @@
 				goto afe_error;
 			}
 
-			if (param[1] < 0 || param[1] > 100) {
+			if (param[1] > 100) {
 				pr_err("%s: Error, volume shoud be 0 to 100"
 					" percentage param = %lu\n",
 					__func__, param[1]);
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index 52e481a..a55700c 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -1,6 +1,6 @@
 
 /*
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -220,7 +220,7 @@
 	int rc = 0;
 	pr_debug("%s: Session id %d\n", __func__, ac->session);
 	mutex_lock(&ac->cmd_lock);
-	if (ac->io_mode == SYNC_IO_MODE) {
+	if (ac->io_mode & SYNC_IO_MODE) {
 		port = &ac->port[dir];
 		if (!port->buf) {
 			mutex_unlock(&ac->cmd_lock);
@@ -351,7 +351,7 @@
 	if (!ac || !ac->session)
 		return;
 	pr_debug("%s: Session id %d\n", __func__, ac->session);
-	if (ac->io_mode == SYNC_IO_MODE) {
+	if (ac->io_mode & SYNC_IO_MODE) {
 		for (loopcnt = 0; loopcnt <= OUT; loopcnt++) {
 			port = &ac->port[loopcnt];
 			if (!port->buf)
@@ -386,14 +386,20 @@
 		pr_err("%s APR handle NULL\n", __func__);
 		return -EINVAL;
 	}
-	if ((mode == ASYNC_IO_MODE) || (mode == SYNC_IO_MODE)) {
-		ac->io_mode = mode;
-		pr_debug("%s:Set Mode to %d\n", __func__, ac->io_mode);
-		return 0;
+
+	if (mode == ASYNC_IO_MODE) {
+		ac->io_mode &= ~SYNC_IO_MODE;
+		ac->io_mode |= ASYNC_IO_MODE;
+	} else if (mode == SYNC_IO_MODE) {
+		ac->io_mode &= ~ASYNC_IO_MODE;
+		ac->io_mode |= SYNC_IO_MODE;
 	} else {
 		pr_err("%s:Not an valid IO Mode:%d\n", __func__, ac->io_mode);
 		return -EINVAL;
 	}
+
+	pr_debug("%s:Set Mode to %d\n", __func__, ac->io_mode);
+	return 0;
 }
 
 struct audio_client *q6asm_audio_client_alloc(app_cb cb, void *priv)
@@ -498,7 +504,7 @@
 	if (ac->session <= 0 || ac->session > 8)
 		goto fail;
 
-	if (ac->io_mode == SYNC_IO_MODE) {
+	if (ac->io_mode & SYNC_IO_MODE) {
 		if (ac->port[dir].buf) {
 			pr_debug("%s: buffer already allocated\n", __func__);
 			return 0;
@@ -911,7 +917,11 @@
 		case ASM_STREAM_CMD_OPEN_WRITE_COMPRESSED:
 		case ASM_STREAM_CMD_OPEN_READ_COMPRESSED:
 		case ASM_STREAM_CMD_OPEN_TRANSCODE_LOOPBACK:
-			if (atomic_read(&ac->cmd_state) && wakeup_flag) {
+			if (payload[0] == ASM_STREAM_CMD_CLOSE) {
+				atomic_set(&ac->cmd_close_state, 0);
+				wake_up(&ac->cmd_wait);
+			} else if (atomic_read(&ac->cmd_state) &&
+					wakeup_flag) {
 				atomic_set(&ac->cmd_state, 0);
 				pr_debug("response payload[1]:%d",
 							payload[1]);
@@ -942,7 +952,7 @@
 		pr_debug("%s: Rxed opcode[0x%x] status[0x%x] token[%d]",
 				__func__, payload[0], payload[1],
 				data->token);
-		if (ac->io_mode == SYNC_IO_MODE) {
+		if (ac->io_mode & SYNC_IO_MODE) {
 			if (port->buf == NULL) {
 				pr_err("%s: Unexpected Write Done\n",
 								__func__);
@@ -1024,7 +1034,7 @@
 		if (in_enable_flag)
 			in_cont_index++;
 #endif
-		if (ac->io_mode == SYNC_IO_MODE) {
+		if (ac->io_mode & SYNC_IO_MODE) {
 			if (port->buf == NULL) {
 				pr_err("%s: Unexpected Write Done\n", __func__);
 				return -EINVAL;
@@ -1203,7 +1213,7 @@
 	if (!ac || ((dir != IN) && (dir != OUT)))
 		return NULL;
 
-	if (ac->io_mode == SYNC_IO_MODE) {
+	if (ac->io_mode & SYNC_IO_MODE) {
 		port = &ac->port[dir];
 
 		mutex_lock(&port->lock);
@@ -1297,7 +1307,7 @@
 	if (!ac || (dir != OUT))
 		return ret;
 
-	if (ac->io_mode == SYNC_IO_MODE) {
+	if (ac->io_mode & SYNC_IO_MODE) {
 		port = &ac->port[dir];
 
 		mutex_lock(&port->lock);
@@ -1430,6 +1440,9 @@
 			rc);
 		goto fail_cmd;
 	}
+
+	ac->io_mode |= TUN_READ_IO_MODE;
+
 	return 0;
 fail_cmd:
 	return -EINVAL;
@@ -1716,6 +1729,9 @@
 		pr_err("%s: format = %x not supported\n", __func__, format);
 		goto fail_cmd;
 	}
+
+	ac->io_mode |= TUN_WRITE_IO_MODE;
+
 	return 0;
 fail_cmd:
 	return -EINVAL;
@@ -2189,6 +2205,39 @@
 	return -EINVAL;
 }
 
+int q6asm_cfg_aac_sel_mix_coef(struct audio_client *ac, uint32_t mix_coeff)
+{
+	struct asm_aac_stereo_mix_coeff_selection_param aac_mix_coeff;
+	int rc = 0;
+	q6asm_add_hdr(ac, &aac_mix_coeff.hdr, sizeof(aac_mix_coeff), TRUE);
+	aac_mix_coeff.hdr.opcode =
+		ASM_STREAM_CMD_SET_ENCDEC_PARAM;
+	aac_mix_coeff.param_id =
+		ASM_PARAM_ID_AAC_STEREO_MIX_COEFF_SELECTION_FLAG;
+	aac_mix_coeff.param_size =
+		sizeof(struct asm_aac_stereo_mix_coeff_selection_param);
+	aac_mix_coeff.aac_stereo_mix_coeff_flag	= mix_coeff;
+	pr_debug("%s, mix_coeff = %u", __func__, mix_coeff);
+	rc = apr_send_pkt(ac->apr, (uint32_t *) &aac_mix_coeff);
+	if (rc < 0) {
+		pr_err("%s:Command opcode[0x%x]paramid[0x%x] failed\n",
+			__func__, ASM_STREAM_CMD_SET_ENCDEC_PARAM,
+			ASM_PARAM_ID_AAC_STEREO_MIX_COEFF_SELECTION_FLAG);
+		rc = -EINVAL;
+		goto fail_cmd;
+	}
+	rc = wait_event_timeout(ac->cmd_wait,
+			(atomic_read(&ac->cmd_state) == 0), 5*HZ);
+	if (!rc) {
+		pr_err("%s:timeout opcode[0x%x]\n", __func__,
+						aac_mix_coeff.hdr.opcode);
+		goto fail_cmd;
+	}
+	return 0;
+fail_cmd:
+	return -EINVAL;
+}
+
 int q6asm_set_encdec_chan_map(struct audio_client *ac,
 			uint32_t num_channels)
 {
@@ -3440,7 +3489,7 @@
 		pr_err("APR handle NULL\n");
 		return -EINVAL;
 	}
-	if (ac->io_mode == SYNC_IO_MODE) {
+	if (ac->io_mode & SYNC_IO_MODE) {
 		port = &ac->port[OUT];
 
 		q6asm_add_hdr(ac, &read.hdr, sizeof(read), FALSE);
@@ -3492,7 +3541,7 @@
 		pr_err("APR handle NULL\n");
 		return -EINVAL;
 	}
-	if (ac->io_mode == SYNC_IO_MODE) {
+	if (ac->io_mode & SYNC_IO_MODE) {
 		port = &ac->port[OUT];
 
 		q6asm_add_hdr_async(ac, &read.hdr, sizeof(read), FALSE);
@@ -3516,7 +3565,7 @@
 		read.hdr.token = port->dsp_buf;
 
 		port->dsp_buf = (port->dsp_buf + 1) & (port->max_buf_cnt - 1);
-		pr_debug("%s:buf add[0x%x] token[%d] uid[%d]\n", __func__,
+		pr_info("%s:buf add[0x%x] token[%d] uid[%d]\n", __func__,
 					read.buf_add,
 					read.hdr.token,
 					read.uid);
@@ -3677,7 +3726,7 @@
 		return -EINVAL;
 	}
 	pr_debug("%s: session[%d] len=%d", __func__, ac->session, len);
-	if (ac->io_mode == SYNC_IO_MODE) {
+	if (ac->io_mode & SYNC_IO_MODE) {
 		port = &ac->port[IN];
 
 		q6asm_add_hdr(ac, &write.hdr, sizeof(write),
@@ -3759,7 +3808,7 @@
 		return -EINVAL;
 	}
 	pr_debug("%s: session[%d] len=%d", __func__, ac->session, len);
-	if (ac->io_mode == SYNC_IO_MODE) {
+	if (ac->io_mode & SYNC_IO_MODE) {
 		port = &ac->port[IN];
 
 		q6asm_add_hdr_async(ac, &write.hdr, sizeof(write),
@@ -3801,13 +3850,13 @@
 	return -EINVAL;
 }
 
-uint64_t q6asm_get_session_time(struct audio_client *ac)
+int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp)
 {
 	struct apr_hdr hdr;
 	int rc;
 
-	if (!ac || ac->apr == NULL) {
-		pr_err("APR handle NULL\n");
+	if (!ac || ac->apr == NULL || tstamp == NULL) {
+		pr_err("APR handle or tstamp NULL\n");
 		return -EINVAL;
 	}
 	q6asm_add_hdr(ac, &hdr, sizeof(hdr), FALSE);
@@ -3829,7 +3878,9 @@
 			__func__);
 		goto fail_cmd;
 	}
-	return ac->time_stamp;
+
+	*tstamp = ac->time_stamp;
+	return 0;
 
 fail_cmd:
 	return -EINVAL;
@@ -3872,7 +3923,8 @@
 	case CMD_CLOSE:
 		pr_debug("%s:CMD_CLOSE\n", __func__);
 		hdr.opcode = ASM_STREAM_CMD_CLOSE;
-		state = &ac->cmd_state;
+		atomic_set(&ac->cmd_close_state, 1);
+		state = &ac->cmd_close_state;
 		break;
 	default:
 		pr_err("Invalid format[%d]\n", cmd);
@@ -3961,9 +4013,11 @@
 {
 	int cnt = 0;
 	int loopcnt = 0;
+	int used;
 	struct audio_port_data *port = NULL;
 
-	if (ac->io_mode == SYNC_IO_MODE) {
+	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];
@@ -3973,7 +4027,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/qdsp6/q6voice.c b/sound/soc/msm/qdsp6/q6voice.c
index 3b1e722..f04947c 100644
--- a/sound/soc/msm/qdsp6/q6voice.c
+++ b/sound/soc/msm/qdsp6/q6voice.c
@@ -1,4 +1,4 @@
-/*  Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/*  Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -55,8 +55,10 @@
 static int voice_send_set_device_cmd(struct voice_data *v);
 static int voice_send_disable_vocproc_cmd(struct voice_data *v);
 static int voice_send_vol_index_cmd(struct voice_data *v);
-static int voice_send_cvp_map_memory_cmd(struct voice_data *v);
-static int voice_send_cvp_unmap_memory_cmd(struct voice_data *v);
+static int voice_send_cvp_map_memory_cmd(struct voice_data *v,
+					 uint32_t paddr, uint32_t mem_size);
+static int voice_send_cvp_unmap_memory_cmd(struct voice_data *v,
+					   uint32_t paddr);
 static int voice_send_cvs_map_memory_cmd(struct voice_data *v);
 static int voice_send_cvs_unmap_memory_cmd(struct voice_data *v);
 static int voice_send_cvs_register_cal_cmd(struct voice_data *v);
@@ -1295,6 +1297,32 @@
 	return -EINVAL;
 }
 
+static void voc_get_tx_rx_topology(struct voice_data *v,
+				   uint32_t *tx_topology_id,
+				   uint32_t *rx_topology_id)
+{
+
+	uint32_t tx_id = 0;
+	uint32_t rx_id = 0;
+
+	if (v->disable_topology) {
+		tx_id = VSS_IVOCPROC_TOPOLOGY_ID_NONE;
+		rx_id = VSS_IVOCPROC_TOPOLOGY_ID_NONE;
+	} else {
+		/* Use default topology if invalid value in ACDB */
+		tx_id = get_voice_tx_topology();
+		if (tx_id == 0)
+			tx_id = VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
+
+		rx_id = get_voice_rx_topology();
+		if (rx_id == 0)
+			rx_id = VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
+	}
+
+	*tx_topology_id = tx_id;
+	*rx_topology_id = rx_id;
+}
+
 static int voice_send_set_device_cmd(struct voice_data *v)
 {
 	struct cvp_set_device_cmd  cvp_setdev_cmd;
@@ -1327,18 +1355,9 @@
 	cvp_setdev_cmd.hdr.token = 0;
 	cvp_setdev_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_DEVICE;
 
-	/* Use default topology if invalid value in ACDB */
-	cvp_setdev_cmd.cvp_set_device.tx_topology_id =
-				get_voice_tx_topology();
-	if (cvp_setdev_cmd.cvp_set_device.tx_topology_id == 0)
-		cvp_setdev_cmd.cvp_set_device.tx_topology_id =
-				VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
+	voc_get_tx_rx_topology(v, &cvp_setdev_cmd.cvp_set_device.tx_topology_id,
+			       &cvp_setdev_cmd.cvp_set_device.rx_topology_id);
 
-	cvp_setdev_cmd.cvp_set_device.rx_topology_id =
-				get_voice_rx_topology();
-	if (cvp_setdev_cmd.cvp_set_device.rx_topology_id == 0)
-		cvp_setdev_cmd.cvp_set_device.rx_topology_id =
-				VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
 	cvp_setdev_cmd.cvp_set_device.tx_port_id = v->dev_tx.port_id;
 	cvp_setdev_cmd.cvp_set_device.rx_port_id = v->dev_rx.port_id;
 	pr_debug("topology=%d , tx_port_id=%d, rx_port_id=%d\n",
@@ -1548,20 +1567,42 @@
 
 }
 
-static int voice_send_cvp_map_memory_cmd(struct voice_data *v)
+static int voice_get_cal_paddr_size(struct voice_data *v, uint32_t *cal_paddr,
+				    uint32_t *cal_size)
 {
-	struct vss_map_memory_cmd cvp_map_mem_cmd;
-	struct acdb_cal_block cal_block;
 	int ret = 0;
-	void *apr_cvp;
-	u16 cvp_handle;
-	uint32_t cal_paddr = 0;
-
+	struct acdb_cal_block cal_block;
 	/* get all cvp cal data */
 	get_all_cvp_cal(&cal_block);
 	if (cal_block.cal_size == 0)
 		goto fail;
 
+	if (is_volte_session(v->session_id) ||
+	    is_voip_session(v->session_id)) {
+		ret = voice_get_cal_phys_addr(v->session_id, CVP_CAL,
+					      cal_paddr);
+		if (ret < 0)
+			return ret;
+	} else {
+		*cal_paddr = cal_block.cal_paddr;
+	}
+	if (cal_size)
+		*cal_size = cal_block.cal_size;
+
+	return 0;
+
+fail:
+	return -EINVAL;
+}
+
+static int voice_send_cvp_map_memory_cmd(struct voice_data *v,
+					 uint32_t paddr, uint32_t mem_size)
+{
+	struct vss_map_memory_cmd cvp_map_mem_cmd;
+	int ret = 0;
+	void *apr_cvp;
+	u16 cvp_handle;
+
 	if (v == NULL) {
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
@@ -1573,16 +1614,6 @@
 		return -EINVAL;
 	}
 
-	if (is_volte_session(v->session_id) ||
-			is_voip_session(v->session_id)) {
-		ret = voice_get_cal_phys_addr(v->session_id, CVP_CAL,
-						&cal_paddr);
-		if (ret < 0)
-			return ret;
-	} else {
-		cal_paddr = cal_block.cal_paddr;
-	}
-
 	cvp_handle = voice_get_cvp_handle(v);
 
 	/* fill in the header */
@@ -1596,16 +1627,16 @@
 	cvp_map_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_MAP_MEMORY;
 
 	pr_debug("%s, phys_addr: 0x%x, mem_size: %d\n", __func__,
-		cal_paddr, cal_block.cal_size);
-	cvp_map_mem_cmd.vss_map_mem.phys_addr = cal_paddr;
-	cvp_map_mem_cmd.vss_map_mem.mem_size = cal_block.cal_size;
+		paddr, mem_size);
+	cvp_map_mem_cmd.vss_map_mem.phys_addr = paddr;
+	cvp_map_mem_cmd.vss_map_mem.mem_size = mem_size;
 	cvp_map_mem_cmd.vss_map_mem.mem_pool_id =
 				VSS_ICOMMON_MAP_MEMORY_SHMEM8_4K_POOL;
 
 	v->cvp_state = CMD_STATUS_FAIL;
 	ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_map_mem_cmd);
 	if (ret < 0) {
-		pr_err("Fail: sending cvp cal,\n");
+		pr_err("Fail: mapping cvp memory,\n");
 		goto fail;
 	}
 	ret = wait_event_timeout(v->cvp_wait,
@@ -1621,18 +1652,13 @@
 
 }
 
-static int voice_send_cvp_unmap_memory_cmd(struct voice_data *v)
+static int voice_send_cvp_unmap_memory_cmd(struct voice_data *v,
+					   uint32_t paddr)
 {
 	struct vss_unmap_memory_cmd cvp_unmap_mem_cmd;
-	struct acdb_cal_block cal_block;
 	int ret = 0;
 	void *apr_cvp;
 	u16 cvp_handle;
-	uint32_t cal_paddr = 0;
-
-	get_all_cvp_cal(&cal_block);
-	if (cal_block.cal_size == 0)
-		return 0;
 
 	if (v == NULL) {
 		pr_err("%s: v is NULL\n", __func__);
@@ -1645,16 +1671,6 @@
 		return -EINVAL;
 	}
 
-	if (is_volte_session(v->session_id) ||
-			is_voip_session(v->session_id)) {
-		ret = voice_get_cal_phys_addr(v->session_id, CVP_CAL,
-						&cal_paddr);
-		if (ret < 0)
-			return ret;
-	} else {
-		cal_paddr = cal_block.cal_paddr;
-	}
-
 	cvp_handle = voice_get_cvp_handle(v);
 
 	/* fill in the header */
@@ -1667,7 +1683,7 @@
 	cvp_unmap_mem_cmd.hdr.token = 0;
 	cvp_unmap_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_UNMAP_MEMORY;
 
-	cvp_unmap_mem_cmd.vss_unmap_mem.phys_addr = cal_paddr;
+	cvp_unmap_mem_cmd.vss_unmap_mem.phys_addr = paddr;
 
 	v->cvp_state = CMD_STATUS_FAIL;
 	ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_unmap_mem_cmd);
@@ -2210,6 +2226,9 @@
 	struct cvp_create_full_ctl_session_cmd cvp_session_cmd;
 	int ret = 0;
 	void *apr_cvp;
+	uint32_t cal_paddr = 0;
+	uint32_t cal_size = 0;
+
 	if (v == NULL) {
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
@@ -2235,18 +2254,8 @@
 	cvp_session_cmd.hdr.opcode =
 			VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION;
 
-	/* Use default topology if invalid value in ACDB */
-	cvp_session_cmd.cvp_session.tx_topology_id =
-				get_voice_tx_topology();
-	if (cvp_session_cmd.cvp_session.tx_topology_id == 0)
-		cvp_session_cmd.cvp_session.tx_topology_id =
-			VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
-
-	cvp_session_cmd.cvp_session.rx_topology_id =
-				get_voice_rx_topology();
-	if (cvp_session_cmd.cvp_session.rx_topology_id == 0)
-		cvp_session_cmd.cvp_session.rx_topology_id =
-			VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
+	voc_get_tx_rx_topology(v, &cvp_session_cmd.cvp_session.tx_topology_id,
+			       &cvp_session_cmd.cvp_session.rx_topology_id);
 
 	cvp_session_cmd.cvp_session.direction = 2; /*tx and rx*/
 	cvp_session_cmd.cvp_session.network_id = VSS_NETWORK_ID_DEFAULT;
@@ -2280,8 +2289,8 @@
 		voice_send_cvs_register_cal_cmd(v);
 
 	/* send cvp and vol cal */
-	ret = voice_send_cvp_map_memory_cmd(v);
-	if (!ret) {
+	if (!voice_get_cal_paddr_size(v, &cal_paddr, &cal_size) &&
+	    !voice_send_cvp_map_memory_cmd(v, cal_paddr, cal_size)) {
 		voice_send_cvp_register_cal_cmd(v);
 		voice_send_cvp_register_vol_cal_table_cmd(v);
 	}
@@ -2540,6 +2549,7 @@
 	int ret = 0;
 	void *apr_mvm, *apr_cvp;
 	u16 mvm_handle, cvp_handle;
+	uint32_t paddr = 0;
 
 	if (v == NULL) {
 		pr_err("%s: v is NULL\n", __func__);
@@ -2569,6 +2579,9 @@
 	/* Clear mute setting */
 	v->dev_tx.mute = common.default_mute_val;
 
+	/* clear disable topology setting */
+	v->disable_topology = false;
+
 	/* detach VOCPROC and wait for response from mvm */
 	mvm_d_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
 						APR_HDR_LEN(APR_HDR_SIZE),
@@ -2600,7 +2613,8 @@
 	/* deregister cvp and vol cal */
 	voice_send_cvp_deregister_vol_cal_table_cmd(v);
 	voice_send_cvp_deregister_cal_cmd(v);
-	voice_send_cvp_unmap_memory_cmd(v);
+	if (!voice_get_cal_paddr_size(v, &paddr, NULL))
+		voice_send_cvp_unmap_memory_cmd(v, paddr);
 
 	/* deregister cvs cal */
 	voice_send_cvs_deregister_cal_cmd(v);
@@ -3203,6 +3217,7 @@
 int voc_disable_cvp(uint16_t session_id)
 {
 	struct voice_data *v = voice_get_session(session_id);
+	uint32_t paddr = 0;
 	int ret = 0;
 
 	if (v == NULL) {
@@ -3230,7 +3245,8 @@
 		/* deregister cvp and vol cal */
 		voice_send_cvp_deregister_vol_cal_table_cmd(v);
 		voice_send_cvp_deregister_cal_cmd(v);
-		voice_send_cvp_unmap_memory_cmd(v);
+		voice_get_cal_paddr_size(v, &paddr, NULL);
+		voice_send_cvp_unmap_memory_cmd(v, paddr);
 
 		v->voc_state = VOC_CHANGE;
 	}
@@ -3244,6 +3260,8 @@
 {
 	struct voice_data *v = voice_get_session(session_id);
 	struct sidetone_cal sidetone_cal_data;
+	uint32_t cal_paddr = 0;
+	uint32_t cal_size = 0;
 	int ret = 0;
 
 	if (v == NULL) {
@@ -3261,8 +3279,8 @@
 			goto fail;
 		}
 		/* send cvp and vol cal */
-		ret = voice_send_cvp_map_memory_cmd(v);
-		if (!ret) {
+		if (!voice_get_cal_paddr_size(v, &cal_paddr, &cal_size) &&
+		    !voice_send_cvp_map_memory_cmd(v, cal_paddr, cal_size)) {
 			voice_send_cvp_register_cal_cmd(v);
 			voice_send_cvp_register_vol_cal_table_cmd(v);
 		}
@@ -3316,6 +3334,26 @@
 	return ret;
 }
 
+int voc_disable_topology(uint16_t session_id, uint32_t disable)
+{
+	struct voice_data *v = voice_get_session(session_id);
+	int ret = 0;
+
+	if (v == NULL) {
+		pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
+
+		return -EINVAL;
+	}
+
+	mutex_lock(&v->lock);
+
+	v->disable_topology = disable;
+
+	mutex_unlock(&v->lock);
+
+	return ret;
+}
+
 int voc_set_tx_mute(uint16_t session_id, uint32_t dir, uint32_t mute)
 {
 	struct voice_data *v = voice_get_session(session_id);
@@ -3828,6 +3866,13 @@
 	common.dtmf_info.private_data = private_data;
 }
 
+void voc_register_hpcm_evt_cb(hostpcm_cb_fn hostpcm_cb,
+			      void *private_data)
+{
+	common.hostpcm_info.hostpcm_evt_cb = hostpcm_cb;
+	common.hostpcm_info.private_data = private_data;
+}
+
 void voc_config_vocoder(uint32_t media_type,
 			  uint32_t rate,
 			  uint32_t network_type,
@@ -4173,9 +4218,13 @@
 			case VSS_ICOMMON_CMD_MAP_MEMORY:
 			case VSS_ICOMMON_CMD_UNMAP_MEMORY:
 			case VSS_IVOCPROC_CMD_SET_MUTE:
+			case VSS_IVPCM_CMD_START:
+			case VSS_IVPCM_CMD_STOP:
 				v->cvp_state = CMD_STATUS_SUCCESS;
 				wake_up(&v->cvp_wait);
 				break;
+			case VSS_IVPCM_EVT_PUSH_BUFFER:
+				break;
 			case VOICE_CMD_SET_PARAM:
 				rtac_make_voice_callback(RTAC_CVP, ptr,
 							data->payload_size);
@@ -4189,10 +4238,209 @@
 	} else if (data->opcode ==  VOICE_EVT_GET_PARAM_ACK) {
 		rtac_make_voice_callback(RTAC_CVP, data->payload,
 			data->payload_size);
+	} else if (data->opcode == VSS_IVPCM_EVT_NOTIFY) {
+		struct vss_ivpcm_evt_notify *notify_evt;
+		if ((data->payload != NULL) &&
+		   data->payload_size == sizeof(struct vss_ivpcm_evt_notify)) {
+			notify_evt =
+				(struct vss_ivpcm_evt_notify *)data->payload;
+			c->hostpcm_info.hostpcm_evt_cb(data->payload,
+				voc_get_session_name(v->session_id),
+				c->hostpcm_info.private_data);
+		}
 	}
 	return 0;
 }
 
+int voc_send_cvp_vocpcm_push_buf_evt(u16 session_id,
+			struct vss_ivpcm_evt_push_buffer *push_buff_evt)
+{
+	struct cvp_push_buf_cmd vpcm_push_buf_cmd;
+	int ret = 0;
+	void *apr_cvp;
+	u16 cvp_handle;
+	struct voice_data *v = voice_get_session(session_id);
+
+	if (v == NULL) {
+		pr_err("%s: v is NULL\n", __func__);
+		return -EINVAL;
+	}
+	apr_cvp = common.apr_q6_cvp;
+
+	if (!apr_cvp) {
+		pr_err("%s: apr_cvp is NULL.\n", __func__);
+		return -EINVAL;
+	}
+
+	cvp_handle = voice_get_cvp_handle(v);
+
+	/* fill in the header */
+	vpcm_push_buf_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+	vpcm_push_buf_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+				sizeof(vpcm_push_buf_cmd) - APR_HDR_SIZE);
+	vpcm_push_buf_cmd.hdr.src_port = v->session_id;
+	vpcm_push_buf_cmd.hdr.dest_port = cvp_handle;
+	vpcm_push_buf_cmd.hdr.token = 0;
+	vpcm_push_buf_cmd.hdr.opcode = VSS_IVPCM_EVT_PUSH_BUFFER;
+
+	vpcm_push_buf_cmd.vpcm_evt_push_buffer.tap_point =
+					push_buff_evt->tap_point;
+	vpcm_push_buf_cmd.vpcm_evt_push_buffer.push_buf_mask =
+					push_buff_evt->push_buf_mask;
+	vpcm_push_buf_cmd.vpcm_evt_push_buffer.out_buf_addr =
+					push_buff_evt->out_buf_addr;
+	vpcm_push_buf_cmd.vpcm_evt_push_buffer.in_buf_addr =
+					push_buff_evt->in_buf_addr;
+	vpcm_push_buf_cmd.vpcm_evt_push_buffer.out_buf_size =
+					push_buff_evt->out_buf_size;
+	vpcm_push_buf_cmd.vpcm_evt_push_buffer.in_buf_size =
+					push_buff_evt->in_buf_size;
+	vpcm_push_buf_cmd.vpcm_evt_push_buffer.sampling_rate =
+					push_buff_evt->sampling_rate;
+	vpcm_push_buf_cmd.vpcm_evt_push_buffer.num_in_channels =
+					push_buff_evt->num_in_channels;
+
+	ret = apr_send_pkt(apr_cvp, (uint32_t *) &vpcm_push_buf_cmd);
+	if (ret < 0) {
+		pr_err("Fail: sending vocpcm map memory,\n");
+		goto fail;
+	}
+
+	return 0;
+fail:
+	return -EINVAL;
+
+}
+
+int voc_send_cvp_stop_vocpcm(u16 session_id)
+{
+	struct cvp_stop_cmd vpcm_stop_cmd;
+	int ret = 0;
+	void *apr_cvp;
+	u16 cvp_handle;
+	struct voice_data *v = voice_get_session(session_id);
+
+	if (v == NULL) {
+		pr_err("%s: v is NULL\n", __func__);
+		return -EINVAL;
+	}
+	apr_cvp = common.apr_q6_cvp;
+
+	if (!apr_cvp) {
+		pr_err("%s: apr_cvp is NULL.\n", __func__);
+		return -EINVAL;
+	}
+
+	cvp_handle = voice_get_cvp_handle(v);
+
+	/* fill in the header */
+	vpcm_stop_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+	vpcm_stop_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+				sizeof(vpcm_stop_cmd) - APR_HDR_SIZE);
+	vpcm_stop_cmd.hdr.src_port = v->session_id;
+	vpcm_stop_cmd.hdr.dest_port = cvp_handle;
+	vpcm_stop_cmd.hdr.token = 0;
+	vpcm_stop_cmd.hdr.opcode = VSS_IVPCM_CMD_STOP;
+
+	v->cvp_state = CMD_STATUS_FAIL;
+	ret = apr_send_pkt(apr_cvp, (uint32_t *) &vpcm_stop_cmd);
+	if (ret < 0) {
+		pr_err("Fail: sending vocpcm stop,\n");
+		goto fail;
+	}
+	ret = wait_event_timeout(v->cvp_wait,
+			(v->cvp_state == CMD_STATUS_SUCCESS),
+			msecs_to_jiffies(TIMEOUT_MS));
+	if (!ret) {
+		pr_err("%s: wait_event timeout\n", __func__);
+		goto fail;
+	}
+	return 0;
+fail:
+	return -EINVAL;
+}
+
+int voc_send_cvp_start_vocpcm(u16 session_id,
+			      struct vss_ivpcm_tap_point *vpcm_tp,
+			      uint32_t no_of_tp)
+{
+	struct cvp_start_cmd cvp_start_cmd;
+	int ret = 0;
+	void *apr_cvp;
+	u16 cvp_handle;
+	struct voice_data *v = voice_get_session(session_id);
+	int i = 0;
+
+	if (v == NULL) {
+		pr_err("%s: v is NULL\n", __func__);
+		return -EINVAL;
+	}
+	apr_cvp = common.apr_q6_cvp;
+
+	if (!apr_cvp) {
+		pr_err("%s: apr_cvp is NULL.\n", __func__);
+		return -EINVAL;
+	}
+
+	cvp_handle = voice_get_cvp_handle(v);
+
+	/* fill in the header */
+	cvp_start_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+	cvp_start_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+	      sizeof(struct vss_ivpcm_tap_point) * no_of_tp) + sizeof(no_of_tp);
+	cvp_start_cmd.hdr.src_port = v->session_id;
+	cvp_start_cmd.hdr.dest_port = cvp_handle;
+	cvp_start_cmd.hdr.token = 0;
+	cvp_start_cmd.hdr.opcode = VSS_IVPCM_CMD_START;
+
+	for (i = 0; i < no_of_tp; i++) {
+		cvp_start_cmd.vpcm_start_cmd.tap_points[i].tap_point =
+							vpcm_tp[i].tap_point;
+		cvp_start_cmd.vpcm_start_cmd.tap_points[i].direction =
+							vpcm_tp[i].direction;
+		cvp_start_cmd.vpcm_start_cmd.tap_points[i].sampling_rate =
+						    vpcm_tp[i].sampling_rate;
+		cvp_start_cmd.vpcm_start_cmd.tap_points[i].duration = 0;
+	}
+
+	cvp_start_cmd.vpcm_start_cmd.num_tap_points = no_of_tp;
+
+	v->cvp_state = CMD_STATUS_FAIL;
+	ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_start_cmd);
+	if (ret < 0) {
+		pr_err("Fail: sending vocpcm map memory,\n");
+		goto fail;
+	}
+	ret = wait_event_timeout(v->cvp_wait,
+			(v->cvp_state == CMD_STATUS_SUCCESS),
+			msecs_to_jiffies(TIMEOUT_MS));
+	if (!ret) {
+		pr_err("%s: wait_event timeout\n", __func__);
+		goto fail;
+	}
+
+	return 0;
+fail:
+	return -EINVAL;
+
+}
+
+int voc_send_cvp_unmap_vocpcm_memory(u16 session_id, uint32_t paddr)
+{
+	return voice_send_cvp_unmap_memory_cmd(
+			voice_get_session(session_id), paddr);
+}
+
+int voc_send_cvp_map_vocpcm_memory(u16 session_id,
+				   uint32_t paddr, uint32_t bufsize)
+{
+	return voice_send_cvp_map_memory_cmd(voice_get_session(session_id),
+							       paddr,
+							       bufsize);
+}
 
 static void voice_allocate_shared_memory(void)
 {
@@ -4292,6 +4540,7 @@
 		common.voice[i].dev_rx.port_id = 0;
 		common.voice[i].sidetone_gain = 0x512;
 		common.voice[i].dtmf_rx_detect_en = 0;
+		common.voice[i].disable_topology = false;
 
 		common.voice[i].voc_state = VOC_INIT;
 
diff --git a/sound/soc/msm/qdsp6/q6voice.h b/sound/soc/msm/qdsp6/q6voice.h
index 2fc2266..8df6c38 100644
--- a/sound/soc/msm/qdsp6/q6voice.h
+++ b/sound/soc/msm/qdsp6/q6voice.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -576,7 +576,7 @@
  * structure.
  */
 
-#define VSS_ISTREAM_EVT_RX_DTMF_DETECTED (0x0001101A)
+#define VSS_ISTREAM_EVT_RX_DTMF_DETECTED 0x0001101A
 
 struct vss_istream_cmd_set_rx_dtmf_detection {
 	/*
@@ -590,7 +590,7 @@
 	uint32_t enable;
 };
 
-#define VSS_ISTREAM_CMD_SET_RX_DTMF_DETECTION (0x00011027)
+#define VSS_ISTREAM_CMD_SET_RX_DTMF_DETECTION 0x00011027
 
 struct vss_istream_evt_rx_dtmf_detected {
 	uint16_t low_freq;
@@ -616,6 +616,217 @@
 	struct vss_istream_cmd_set_rx_dtmf_detection cvs_dtmf_det;
 } __packed;
 
+
+/* VOCODER PCM APIS */
+#define VSS_IVPCM_CMD_STOP 0x0001100B
+
+#define VSS_IVPCM_CMD_START 0x00011009
+
+/* Default tap point location on the TX path. */
+#define VSS_IVPCM_TAP_POINT_TX_DEFAULT 0x00011289
+
+/* Default tap point location on the RX path. */
+#define VSS_IVPCM_TAP_POINT_RX_DEFAULT 0x0001128A
+
+/*
+ * Vocoder PCM sampling rate IDs.
+ * Sampling rate matches the operating sampling rate
+ * of the post-proc chain on the VDSP at the location
+ * of the tap point.
+ */
+#define VSS_IVPCM_SAMPLING_RATE_AUTO     0
+#define VSS_IVPCM_SAMPLING_RATE_8K       8000
+#define VSS_IVPCM_SAMPLING_RATE_16K      16000
+
+/* Output tap point */
+#define VSS_IVPCM_TAP_POINT_DIR_OUT      0
+/* Input tap point */
+#define VSS_IVPCM_TAP_POINT_DIR_IN       1
+/* Output-input tap point */
+#define VSS_IVPCM_TAP_POINT_DIR_OUT_IN   2
+
+/* RX & TX*/
+#define MAX_TAP_POINTS_SUPPORTED         2
+
+struct vss_ivpcm_tap_point {
+	uint32_t tap_point;
+	/*
+	 * Tap point location GUID. Supported values:
+	 * VSS_IVPCM_TAP_POINT_TX_DEFAULT
+	 * VSS_IVPCM_TAP_POINT_RX_DEFAULT
+	 */
+	uint16_t direction;
+	/*
+	 * Data flow direction of the tap point. Supported values:
+	 * VSS_IVPCM_TAP_POINT_DIR_OUT -- output
+	 * VSS_IVPCM_TAP_POINT_DIR_IN -- input
+	 * VSS_IVPCM_TAP_POINT_DIR_OUT_IN -- Output-input
+	 */
+	uint16_t sampling_rate;
+	/*
+	 * Sampling rate of the tap point. If the tap point is output-input,
+	 * then output sampling rate and the input sampling rate are the same.
+	 * Supported values:
+	 * VSS_IVPCM_SAMPLING_RATE_AUTO
+	 * VSS_IVPCM_SAMPLING_RATE_8K
+	 * VSS_IVPCM_SAMPLING_RATE_16K
+	 */
+	uint16_t duration;
+	/*
+	 * Duration of buffer in milliseconds.
+	 * Unsupported, set to 0.
+	 */
+} __packed;
+
+struct vss_ivpcm_start_cmd {
+	uint32_t num_tap_points;
+	struct vss_ivpcm_tap_point tap_points[MAX_TAP_POINTS_SUPPORTED];
+} __packed;
+
+
+#define VSS_IVPCM_EVT_NOTIFY                0x0001128B
+
+/* Notify event masks. */
+/* output buffer filled. */
+#define VSS_IVPCM_NOTIFY_MASK_OUTPUT_BUFFER  1
+ /* input buffer consumed. */
+#define VSS_IVPCM_NOTIFY_MASK_INPUT_BUFFER   2
+ /* event is a timetick. */
+#define VSS_IVPCM_NOTIFY_MASK_TIMETICK       4
+
+/* error in output buffer operation. */
+#define VSS_IVPCM_NOTIFY_MASK_OUTPUT_ERROR   8
+
+/* error in input buffer operation. */
+#define VSS_IVPCM_NOTIFY_MASK_INPUT_ERROR   16
+
+/*
+ *Payload structure for the #VSS_IVPCM_EVT_NOTIFY command.
+ */
+struct vss_ivpcm_evt_notify {
+	uint32_t tap_point;
+	/*
+	 * GUID indicating tap point location for which this notification is
+	 * being issued.
+	 */
+	uint32_t notify_mask;
+	/*
+	 * Bitmask indicating the notification mode.
+	 * Bitmask description:
+	 * bit 0 -- output buffer filled, VSS_IVPCM_NOTIFY_MASK_OUTPUT_BUFFER
+	 * bit 1 -- input buffer consumed, VSS_IVPCM_NOTIFY_MASK_INPUT_BUFFER
+	 * bit 2 -- notify event is a timetick, VSS_IVPCM_NOTIFY_MASK_TIMETICK
+	 * bit 3 -- error in output buffer, VSS_IVPCM_NOTIFY_MASK_OUTPUT_ERROR
+	 *          This bit will be set if there is an error in output buffer
+	 *          operation.This bit will be set along with "output buffer
+	 *          filled" bit to return the output buffer with error
+	 *          indication
+	 * bit 4 -- error in input buffer operation, use
+	 *          VSS_IVPCM_NOTIFY_MASK_INPUT_ERROR. This bit will be set if
+	 *          there is an error in input buffer operation. This bit will
+	 *          be set along with "input buffer consumed" bit to return the
+	 *          input buffer with error indication.
+	 */
+	uint32_t out_buff_addr;
+	/*
+	 * If bit 0 of the notify_mask is set, this field indicates the
+	 * physical address of the output buffer. Otherwise ignore.
+	 */
+	uint32_t in_buff_addr;
+	/*
+	 * If bit 1 of the notify_mask is set, this field indicates the
+	 * physicaladdress of the input buffer. Otherwise ignore.
+	 */
+	uint16_t filled_out_size;
+	/*
+	 * If bit 0 of the notify_mask is set, this field indicates
+	 * the filled size
+	 * of the output buffer located at the out_buff_addr. Otherwise ignore.
+	 */
+	uint16_t request_buff_size;
+	/* Request size of the input buffer. */
+	uint16_t sampling_rate;
+	/*
+	 * Sampling rate of the input/output buffer. Supported values:
+	 * VSS_IVPCM_SAMPLING_RATE_8K
+	 * VSS_IVPCM_SAMPLING_RATE_16K
+	 */
+	uint16_t num_out_channels;
+	/* Number of output channels contained in the filled output buffer.*/
+} __packed;
+
+#define VSS_IVPCM_EVT_PUSH_BUFFER                0x0001100A
+
+/* Push buffer event masks. */
+/* output buffer filled. */
+#define VSS_IVPCM_PUSH_BUFFER_MASK_OUTPUT_BUFFER  1
+/* input buffer consumed. */
+#define VSS_IVPCM_PUSH_BUFFER_MASK_INPUT_BUFFER   2
+
+struct vss_ivpcm_evt_push_buffer {
+	uint32_t tap_point;
+	/* tap point for which the buffer(s) is(are) provided. */
+	uint32_t push_buf_mask;
+	/*
+	 * Bitmask inticating whether an output buffer is being provided or an
+	 * input buffer or both. Bitmask description:
+	 * bit 0 -- output buffer, use VSS_IVPCM_PUSH_BUFFER_MASK_OUTPUT_BUFFER
+	 * bit 1 -- input buffer, use VSS_IVPCM_PUSH_BUFFER_MASK_INPUT_BUFFER.
+	 */
+	uint32_t out_buf_addr;
+	/*
+	 * If bit 0 of the push_buf_mask is set, this field indicates the
+	 * physical address of the output buffer. Otherwise it is ingored.
+	 */
+	uint32_t in_buf_addr;
+	/*
+	 * If bit 1 of the push_buf_mask is set, this field indicates the
+	 * physical address of the input buffer. Otherwise it is ignored.
+	 */
+	uint16_t out_buf_size;
+	/*
+	 * If bit 0 of the push_buf_mask is set, this field indicates the size
+	 * of the buffer at out_buf_addr. Otherwise it is ignored.
+	 * The client should allocate the output buffer to accommodate the
+	 * maximum expected sampling rate.
+	 */
+	uint16_t in_buf_size;
+	/*
+	 * If bit 1 of the push_buf_mask is set, this field indicates the size
+	 * of the input buffer at in_buff_addr. Otherwise it is ignored.
+	 */
+
+	uint16_t sampling_rate;
+	/*
+	 * If bit 1 of the push_buf_mask is set, this field indicates the
+	 * sampling rate of the input buffer. Otherwise it is ignored.
+	 * Supported values:
+	 * VSS_IVPCM_SAMPLING_RATE_8K
+	 * VSS_IVPCM_SAMPLING_RATE_16K
+	 */
+	uint16_t num_in_channels;
+	/*
+	 * If bit 1 of the push_buf_mask is set, this field indicates the
+	 * number of channels contained in the input buffer. Otherwise it
+	 * is ignored.
+	 * Supported values:1
+	 */
+} __packed;
+
+struct cvp_push_buf_cmd {
+	struct apr_hdr hdr;
+	struct vss_ivpcm_evt_push_buffer vpcm_evt_push_buffer;
+} __packed;
+
+struct cvp_start_cmd {
+	struct apr_hdr hdr;
+	struct vss_ivpcm_start_cmd vpcm_start_cmd;
+} __packed;
+
+struct cvp_stop_cmd {
+	struct apr_hdr hdr;
+} __packed;
+
 struct cvs_create_passive_ctl_session_cmd {
 	struct apr_hdr hdr;
 	struct vss_istream_cmd_create_passive_control_session_t cvs_session;
@@ -912,6 +1123,10 @@
 				  char *session,
 				  void *private_data);
 
+typedef void (*hostpcm_cb_fn)(uint8_t *data,
+				  char *session,
+				  void *private_data);
+
 struct mvs_driver_info {
 	uint32_t media_type;
 	uint32_t rate;
@@ -927,6 +1142,11 @@
 	void *private_data;
 };
 
+struct hostpcm_driver_info {
+	hostpcm_cb_fn hostpcm_evt_cb;
+	void *private_data;
+};
+
 struct incall_rec_info {
 	uint32_t rec_enable;
 	uint32_t rec_mode;
@@ -975,6 +1195,8 @@
 
 	uint32_t dtmf_rx_detect_en;
 
+	bool disable_topology;
+
 	struct voice_dev_route_state voc_route_state;
 
 	u16 session_id;
@@ -1023,6 +1245,8 @@
 
 	struct dtmf_driver_info dtmf_info;
 
+	struct hostpcm_driver_info hostpcm_info;
+
 	struct voice_data voice[MAX_VOC_SESSIONS];
 };
 
@@ -1033,6 +1257,9 @@
 void voc_register_dtmf_rx_detection_cb(dtmf_rx_det_cb_fn dtmf_rx_ul_cb,
 				       void *private_data);
 
+void voc_register_hpcm_evt_cb(dtmf_rx_det_cb_fn dtmf_rx_ul_cb,
+				       void *private_data);
+
 void voc_config_vocoder(uint32_t media_type,
 			uint32_t rate,
 			uint32_t network_type,
@@ -1066,12 +1293,22 @@
 int voc_set_tx_mute(uint16_t session_id, uint32_t dir, uint32_t mute);
 int voc_set_rx_device_mute(uint16_t session_id, uint32_t mute);
 int voc_get_rx_device_mute(uint16_t session_id);
+int voc_disable_topology(uint16_t session_id, uint32_t disable);
 int voc_disable_cvp(uint16_t session_id);
 int voc_enable_cvp(uint16_t session_id);
 int voc_set_route_flag(uint16_t session_id, uint8_t path_dir, uint8_t set);
 uint8_t voc_get_route_flag(uint16_t session_id, uint8_t path_dir);
 int voc_enable_dtmf_rx_detection(uint16_t session_id, uint32_t enable);
 void voc_disable_dtmf_det_on_active_sessions(void);
+int voc_send_cvp_map_vocpcm_memory(u16 session_id, uint32_t paddr,
+				   uint32_t bufsize);
+int voc_send_cvp_unmap_vocpcm_memory(u16 session_id, uint32_t paddr);
+int voc_send_cvp_start_vocpcm(u16 session_id,
+	struct vss_ivpcm_tap_point *vpcm_tp, uint32_t no_of_tp);
+int voc_send_cvp_stop_vocpcm(u16 session_id);
+int voc_send_cvp_vocpcm_push_buf_evt(u16 session_id,
+		struct vss_ivpcm_evt_push_buffer *push_buff_evt);
+
 
 #define MAX_SESSION_NAME_LEN 32
 #define VOICE_SESSION_NAME "Voice session"
diff --git a/sound/soc/msm/qdsp6v2/Makefile b/sound/soc/msm/qdsp6v2/Makefile
index 1d11907..69c0976 100644
--- a/sound/soc/msm/qdsp6v2/Makefile
+++ b/sound/soc/msm/qdsp6v2/Makefile
@@ -1,6 +1,6 @@
 snd-soc-qdsp6v2-objs += msm-dai-q6-v2.o msm-pcm-q6-v2.o msm-pcm-routing-v2.o msm-compr-q6-v2.o  msm-multi-ch-pcm-q6-v2.o
 snd-soc-qdsp6v2-objs += 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
-obj-$(CONFIG_SND_SOC_QDSP6V2) += snd-soc-qdsp6v2.o
-obj-y += q6adm.o q6afe.o q6asm.o q6audio-v2.o q6voice.o q6core.o
+obj-$(CONFIG_SND_SOC_QDSP6V2) += snd-soc-qdsp6v2.o msm-pcm-dtmf-v2.o msm-dai-stub-v2.o
+obj-y += q6adm.o q6afe.o q6asm.o q6audio-v2.o q6voice.o q6core.o audio_acdb.o rtac.o
 ocmem-audio-objs += audio_ocmem.o
 obj-$(CONFIG_AUDIO_OCMEM) += ocmem-audio.o
diff --git a/sound/soc/msm/qdsp6v2/audio_acdb.c b/sound/soc/msm/qdsp6v2/audio_acdb.c
new file mode 100644
index 0000000..b71132e
--- /dev/null
+++ b/sound/soc/msm/qdsp6v2/audio_acdb.c
@@ -0,0 +1,1129 @@
+/* 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.
+ *
+ */
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/miscdevice.h>
+#include <linux/mutex.h>
+#include <linux/uaccess.h>
+#include <linux/msm_ion.h>
+#include <linux/mm.h>
+#include "audio_acdb.h"
+
+
+#define MAX_NETWORKS			15
+#define MAX_IOCTL_DATA			(MAX_NETWORKS * 2)
+#define MAX_COL_SIZE			324
+
+#define ACDB_BLOCK_SIZE			4096
+#define NUM_VOCPROC_BLOCKS		(6 * MAX_NETWORKS)
+#define ACDB_TOTAL_VOICE_ALLOCATION	(ACDB_BLOCK_SIZE * NUM_VOCPROC_BLOCKS)
+
+
+struct sidetone_atomic_cal {
+	atomic_t	enable;
+	atomic_t	gain;
+};
+
+
+struct acdb_data {
+	struct mutex		acdb_mutex;
+
+	/* ANC Cal */
+	struct acdb_atomic_cal_block	anc_cal;
+
+	/* LSM Cal */
+	struct acdb_atomic_cal_block	lsm_cal;
+
+	/* AudProc Cal */
+	atomic_t			asm_topology;
+	atomic_t			adm_topology[MAX_AUDPROC_TYPES];
+	struct acdb_atomic_cal_block	audproc_cal[MAX_AUDPROC_TYPES];
+	struct acdb_atomic_cal_block	audstrm_cal[MAX_AUDPROC_TYPES];
+	struct acdb_atomic_cal_block	audvol_cal[MAX_AUDPROC_TYPES];
+
+	/* VocProc Cal */
+	atomic_t			voice_rx_topology;
+	atomic_t			voice_tx_topology;
+	struct acdb_atomic_cal_block	vocproc_cal;
+	struct acdb_atomic_cal_block	vocstrm_cal;
+	struct acdb_atomic_cal_block	vocvol_cal;
+
+	/* Voice Column data */
+	struct acdb_atomic_cal_block	vocproc_col_cal[MAX_VOCPROC_TYPES];
+	uint32_t			*col_data[MAX_VOCPROC_TYPES];
+
+	/* VocProc dev cfg cal*/
+	struct acdb_atomic_cal_block	vocproc_dev_cal;
+
+	/* Custom topology */
+	struct acdb_atomic_cal_block	adm_custom_topology;
+	struct acdb_atomic_cal_block	asm_custom_topology;
+	atomic_t			valid_adm_custom_top;
+	atomic_t			valid_asm_custom_top;
+
+	/* AFE cal */
+	struct acdb_atomic_cal_block	afe_cal[MAX_AUDPROC_TYPES];
+
+	/* Sidetone Cal */
+	struct sidetone_atomic_cal	sidetone_cal;
+
+	/* Allocation information */
+	struct ion_client		*ion_client;
+	struct ion_handle		*ion_handle;
+	atomic_t			map_handle;
+	atomic64_t			paddr;
+	atomic64_t			kvaddr;
+	atomic64_t			mem_len;
+};
+
+static struct acdb_data		acdb_data;
+static atomic_t usage_count;
+
+uint32_t get_voice_rx_topology(void)
+{
+	return atomic_read(&acdb_data.voice_rx_topology);
+}
+
+void store_voice_rx_topology(uint32_t topology)
+{
+	atomic_set(&acdb_data.voice_rx_topology, topology);
+}
+
+uint32_t get_voice_tx_topology(void)
+{
+	return atomic_read(&acdb_data.voice_tx_topology);
+}
+
+void store_voice_tx_topology(uint32_t topology)
+{
+	atomic_set(&acdb_data.voice_tx_topology, topology);
+}
+
+uint32_t get_adm_rx_topology(void)
+{
+	return atomic_read(&acdb_data.adm_topology[RX_CAL]);
+}
+
+void store_adm_rx_topology(uint32_t topology)
+{
+	atomic_set(&acdb_data.adm_topology[RX_CAL], topology);
+}
+
+uint32_t get_adm_tx_topology(void)
+{
+	return atomic_read(&acdb_data.adm_topology[TX_CAL]);
+}
+
+void store_adm_tx_topology(uint32_t topology)
+{
+	atomic_set(&acdb_data.adm_topology[TX_CAL], topology);
+}
+
+uint32_t get_asm_topology(void)
+{
+	return atomic_read(&acdb_data.asm_topology);
+}
+
+void store_asm_topology(uint32_t topology)
+{
+	atomic_set(&acdb_data.asm_topology, topology);
+}
+
+void reset_custom_topology_flags(void)
+{
+	atomic_set(&acdb_data.valid_adm_custom_top, 1);
+	atomic_set(&acdb_data.valid_asm_custom_top, 1);
+}
+
+void get_adm_custom_topology(struct acdb_cal_block *cal_block)
+{
+	pr_debug("%s\n", __func__);
+
+	if (cal_block == NULL) {
+		pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
+		goto done;
+	}
+
+	if (atomic_read(&acdb_data.valid_adm_custom_top) == 0) {
+		cal_block->cal_size = 0;
+		goto done;
+	}
+	atomic_set(&acdb_data.valid_adm_custom_top, 0);
+
+	cal_block->cal_size =
+		atomic_read(&acdb_data.adm_custom_topology.cal_size);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.adm_custom_topology.cal_paddr);
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.adm_custom_topology.cal_kvaddr);
+done:
+	return;
+}
+
+void store_adm_custom_topology(struct cal_block *cal_block)
+{
+	pr_debug("%s,\n", __func__);
+
+	if (cal_block->cal_offset > atomic64_read(&acdb_data.mem_len)) {
+		pr_err("%s: offset %d is > mem_len %ld\n",
+			__func__, cal_block->cal_offset,
+			(long)atomic64_read(&acdb_data.mem_len));
+		goto done;
+	}
+
+	atomic_set(&acdb_data.adm_custom_topology.cal_size,
+		cal_block->cal_size);
+	atomic_set(&acdb_data.adm_custom_topology.cal_paddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+	atomic_set(&acdb_data.adm_custom_topology.cal_kvaddr,
+		cal_block->cal_offset +
+		atomic64_read(&acdb_data.kvaddr));
+done:
+	return;
+}
+
+void get_asm_custom_topology(struct acdb_cal_block *cal_block)
+{
+	pr_debug("%s\n", __func__);
+
+	if (cal_block == NULL) {
+		pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
+		goto done;
+	}
+
+	if (atomic_read(&acdb_data.valid_asm_custom_top) == 0) {
+		cal_block->cal_size = 0;
+		goto done;
+	}
+	atomic_set(&acdb_data.valid_asm_custom_top, 0);
+
+	cal_block->cal_size =
+		atomic_read(&acdb_data.asm_custom_topology.cal_size);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.asm_custom_topology.cal_paddr);
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.asm_custom_topology.cal_kvaddr);
+done:
+	return;
+}
+
+void store_asm_custom_topology(struct cal_block *cal_block)
+{
+	pr_debug("%s,\n", __func__);
+
+	if (cal_block->cal_offset > atomic64_read(&acdb_data.mem_len)) {
+		pr_err("%s: offset %d is > mem_len %ld\n",
+			__func__, cal_block->cal_offset,
+			(long)atomic64_read(&acdb_data.mem_len));
+		goto done;
+	}
+
+	atomic_set(&acdb_data.asm_custom_topology.cal_size,
+		cal_block->cal_size);
+	atomic_set(&acdb_data.asm_custom_topology.cal_paddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+	atomic_set(&acdb_data.asm_custom_topology.cal_kvaddr,
+		cal_block->cal_offset +
+		atomic64_read(&acdb_data.kvaddr));
+done:
+	return;
+}
+
+void get_voice_cal_allocation(struct acdb_cal_block *cal_block)
+{
+	cal_block->cal_size = ACDB_TOTAL_VOICE_ALLOCATION;
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.vocproc_cal.cal_paddr);
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.vocproc_cal.cal_kvaddr);
+}
+
+void get_lsm_cal(struct acdb_cal_block *cal_block)
+{
+	pr_debug("%s\n", __func__);
+
+	if (cal_block == NULL) {
+		pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
+		goto done;
+	}
+
+	cal_block->cal_size =
+		atomic_read(&acdb_data.lsm_cal.cal_size);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.lsm_cal.cal_paddr);
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.lsm_cal.cal_kvaddr);
+done:
+	return;
+}
+
+void store_lsm_cal(struct cal_block *cal_block)
+{
+	pr_debug("%s,\n", __func__);
+
+	if (cal_block->cal_offset > atomic64_read(&acdb_data.mem_len)) {
+		pr_err("%s: offset %d is > mem_len %ld\n",
+			__func__, cal_block->cal_offset,
+			(long)atomic64_read(&acdb_data.mem_len));
+		goto done;
+	}
+
+	atomic_set(&acdb_data.lsm_cal.cal_size,
+		cal_block->cal_size);
+	atomic_set(&acdb_data.lsm_cal.cal_paddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+	atomic_set(&acdb_data.lsm_cal.cal_kvaddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+done:
+	return;
+}
+
+void get_anc_cal(struct acdb_cal_block *cal_block)
+{
+	pr_debug("%s\n", __func__);
+
+	if (cal_block == NULL) {
+		pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
+		goto done;
+	}
+
+	cal_block->cal_size =
+		atomic_read(&acdb_data.anc_cal.cal_size);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.anc_cal.cal_paddr);
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.anc_cal.cal_kvaddr);
+done:
+	return;
+}
+
+void store_anc_cal(struct cal_block *cal_block)
+{
+	pr_debug("%s,\n", __func__);
+
+	if (cal_block->cal_offset > atomic64_read(&acdb_data.mem_len)) {
+		pr_err("%s: offset %d is > mem_len %ld\n",
+			__func__, cal_block->cal_offset,
+			(long)atomic64_read(&acdb_data.mem_len));
+		goto done;
+	}
+
+	atomic_set(&acdb_data.anc_cal.cal_size,
+		cal_block->cal_size);
+	atomic_set(&acdb_data.anc_cal.cal_paddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+	atomic_set(&acdb_data.anc_cal.cal_kvaddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+done:
+	return;
+}
+
+void store_afe_cal(int32_t path, struct cal_block *cal_block)
+{
+	pr_debug("%s, path = %d\n", __func__, path);
+
+	if (cal_block->cal_offset > atomic64_read(&acdb_data.mem_len)) {
+		pr_err("%s: offset %d is > mem_len %ld\n",
+			__func__, cal_block->cal_offset,
+			(long)atomic64_read(&acdb_data.mem_len));
+		goto done;
+	}
+	if ((path >= MAX_AUDPROC_TYPES) || (path < 0)) {
+		pr_err("ACDB=> Bad path sent to %s, path: %d\n",
+			__func__, path);
+		goto done;
+	}
+
+	atomic_set(&acdb_data.afe_cal[path].cal_size,
+		cal_block->cal_size);
+	atomic_set(&acdb_data.afe_cal[path].cal_paddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+	atomic_set(&acdb_data.afe_cal[path].cal_kvaddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+done:
+	return;
+}
+
+void get_afe_cal(int32_t path, struct acdb_cal_block *cal_block)
+{
+	pr_debug("%s, path = %d\n", __func__, path);
+
+	if (cal_block == NULL) {
+		pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
+		goto done;
+	}
+	if ((path >= MAX_AUDPROC_TYPES) || (path < 0)) {
+		pr_err("ACDB=> Bad path sent to %s, path: %d\n",
+			__func__, path);
+		goto done;
+	}
+
+	cal_block->cal_size =
+		atomic_read(&acdb_data.afe_cal[path].cal_size);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.afe_cal[path].cal_paddr);
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.afe_cal[path].cal_kvaddr);
+done:
+	return;
+}
+
+void store_audproc_cal(int32_t path, struct cal_block *cal_block)
+{
+	pr_debug("%s, path = %d\n", __func__, path);
+
+	if (cal_block->cal_offset > atomic64_read(&acdb_data.mem_len)) {
+		pr_err("%s: offset %d is > mem_len %ld\n",
+			__func__, cal_block->cal_offset,
+			(long)atomic64_read(&acdb_data.mem_len));
+		goto done;
+	}
+	if (path >= MAX_AUDPROC_TYPES) {
+		pr_err("ACDB=> Bad path sent to %s, path: %d\n",
+			__func__, path);
+		goto done;
+	}
+
+	atomic_set(&acdb_data.audproc_cal[path].cal_size,
+		cal_block->cal_size);
+	atomic_set(&acdb_data.audproc_cal[path].cal_paddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+	atomic_set(&acdb_data.audproc_cal[path].cal_kvaddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+done:
+	return;
+}
+
+void get_audproc_cal(int32_t path, struct acdb_cal_block *cal_block)
+{
+	pr_debug("%s, path = %d\n", __func__, path);
+
+	if (cal_block == NULL) {
+		pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
+		goto done;
+	}
+	if (path >= MAX_AUDPROC_TYPES) {
+		pr_err("ACDB=> Bad path sent to %s, path: %d\n",
+			__func__, path);
+		goto done;
+	}
+
+	cal_block->cal_size =
+		atomic_read(&acdb_data.audproc_cal[path].cal_size);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.audproc_cal[path].cal_paddr);
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.audproc_cal[path].cal_kvaddr);
+done:
+	return;
+}
+
+void store_audstrm_cal(int32_t path, struct cal_block *cal_block)
+{
+	pr_debug("%s, path = %d\n", __func__, path);
+
+	if (cal_block->cal_offset > atomic64_read(&acdb_data.mem_len)) {
+		pr_err("%s: offset %d is > mem_len %ld\n",
+			__func__, cal_block->cal_offset,
+			(long)atomic64_read(&acdb_data.mem_len));
+		goto done;
+	}
+	if (path >= MAX_AUDPROC_TYPES) {
+		pr_err("ACDB=> Bad path sent to %s, path: %d\n",
+			__func__, path);
+		goto done;
+	}
+
+	atomic_set(&acdb_data.audstrm_cal[path].cal_size,
+		cal_block->cal_size);
+	atomic_set(&acdb_data.audstrm_cal[path].cal_paddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+	atomic_set(&acdb_data.audstrm_cal[path].cal_kvaddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+done:
+	return;
+}
+
+void get_audstrm_cal(int32_t path, struct acdb_cal_block *cal_block)
+{
+	pr_debug("%s, path = %d\n", __func__, path);
+
+	if (cal_block == NULL) {
+		pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
+		goto done;
+	}
+	if (path >= MAX_AUDPROC_TYPES) {
+		pr_err("ACDB=> Bad path sent to %s, path: %d\n",
+			__func__, path);
+		goto done;
+	}
+
+	cal_block->cal_size =
+		atomic_read(&acdb_data.audstrm_cal[path].cal_size);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.audstrm_cal[path].cal_paddr);
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.audstrm_cal[path].cal_kvaddr);
+done:
+	return;
+}
+
+void store_audvol_cal(int32_t path, struct cal_block *cal_block)
+{
+	pr_debug("%s, path = %d\n", __func__, path);
+
+	if (cal_block->cal_offset > atomic64_read(&acdb_data.mem_len)) {
+		pr_err("%s: offset %d is > mem_len %ld\n",
+			__func__, cal_block->cal_offset,
+			(long)atomic64_read(&acdb_data.mem_len));
+		goto done;
+	}
+	if (path >= MAX_AUDPROC_TYPES) {
+		pr_err("ACDB=> Bad path sent to %s, path: %d\n",
+			__func__, path);
+		goto done;
+	}
+
+	atomic_set(&acdb_data.audvol_cal[path].cal_size,
+		cal_block->cal_size);
+	atomic_set(&acdb_data.audvol_cal[path].cal_paddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+	atomic_set(&acdb_data.audvol_cal[path].cal_kvaddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+done:
+	return;
+}
+
+void get_audvol_cal(int32_t path, struct acdb_cal_block *cal_block)
+{
+	pr_debug("%s, path = %d\n", __func__, path);
+
+	if (cal_block == NULL) {
+		pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
+		goto done;
+	}
+	if (path >= MAX_AUDPROC_TYPES || path < 0) {
+		pr_err("ACDB=> Bad path sent to %s, path: %d\n",
+			__func__, path);
+		goto done;
+	}
+
+	cal_block->cal_size =
+		atomic_read(&acdb_data.audvol_cal[path].cal_size);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.audvol_cal[path].cal_paddr);
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.audvol_cal[path].cal_kvaddr);
+done:
+	return;
+}
+
+void store_voice_col_data(uint32_t vocproc_type, uint32_t cal_size,
+			  uint32_t *cal_block)
+{
+	if (cal_size > MAX_COL_SIZE) {
+		pr_err("%s: col size is to big %d\n", __func__,
+				cal_size);
+		goto done;
+	}
+	if (copy_from_user(acdb_data.col_data[vocproc_type],
+			(void *)((uint8_t *)cal_block + sizeof(cal_size)),
+			cal_size)) {
+		pr_err("%s: fail to copy col size %d\n",
+			__func__, cal_size);
+		goto done;
+	}
+	atomic_set(&acdb_data.vocproc_col_cal[vocproc_type].cal_size,
+		cal_size);
+done:
+	return;
+}
+
+void get_voice_col_data(uint32_t vocproc_type,
+			struct acdb_cal_block *cal_block)
+{
+	if (cal_block == NULL) {
+		pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
+		goto done;
+	}
+
+	cal_block->cal_size = atomic_read(&acdb_data.
+				vocproc_col_cal[vocproc_type].cal_size);
+	cal_block->cal_paddr = atomic_read(&acdb_data.
+				vocproc_col_cal[vocproc_type].cal_paddr);
+	cal_block->cal_kvaddr = atomic_read(&acdb_data.
+				vocproc_col_cal[vocproc_type].cal_kvaddr);
+done:
+	return;
+}
+
+void store_vocproc_dev_cfg_cal(struct cal_block *cal_block)
+{
+	pr_debug("%s\n", __func__);
+
+
+	if (cal_block->cal_offset >
+				atomic64_read(&acdb_data.mem_len)) {
+		pr_err("%s: offset %d is > mem_len %ld\n",
+			__func__, cal_block->cal_offset,
+			(long)atomic64_read(&acdb_data.mem_len));
+		atomic_set(&acdb_data.vocproc_dev_cal.cal_size, 0);
+		goto done;
+	}
+
+	atomic_set(&acdb_data.vocproc_dev_cal.cal_size,
+		cal_block->cal_size);
+	atomic_set(&acdb_data.vocproc_dev_cal.cal_paddr,
+		cal_block->cal_offset +
+	atomic64_read(&acdb_data.paddr));
+			atomic_set(&acdb_data.vocproc_dev_cal.cal_kvaddr,
+			cal_block->cal_offset +
+			atomic64_read(&acdb_data.kvaddr));
+
+done:
+	return;
+}
+
+void get_vocproc_dev_cfg_cal(struct acdb_cal_block *cal_block)
+{
+	pr_debug("%s\n", __func__);
+
+	cal_block->cal_size =
+		atomic_read(&acdb_data.vocproc_dev_cal.cal_size);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.vocproc_dev_cal.cal_paddr);
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.vocproc_dev_cal.cal_kvaddr);
+}
+
+
+
+void store_vocproc_cal(struct cal_block *cal_block)
+{
+	pr_debug("%s\n", __func__);
+
+	if (cal_block->cal_offset >
+				atomic64_read(&acdb_data.mem_len)) {
+		pr_err("%s: offset %d is > mem_len %ld\n",
+			__func__, cal_block->cal_offset,
+			(long)atomic64_read(&acdb_data.mem_len));
+		atomic_set(&acdb_data.vocproc_cal.cal_size, 0);
+		goto done;
+	}
+
+	atomic_set(&acdb_data.vocproc_cal.cal_size,
+		cal_block->cal_size);
+	atomic_set(&acdb_data.vocproc_cal.cal_paddr,
+		cal_block->cal_offset +
+		atomic64_read(&acdb_data.paddr));
+	atomic_set(&acdb_data.vocproc_cal.cal_kvaddr,
+		cal_block->cal_offset +
+		atomic64_read(&acdb_data.kvaddr));
+
+done:
+	return;
+}
+
+void get_vocproc_cal(struct acdb_cal_block *cal_block)
+{
+	pr_debug("%s\n", __func__);
+
+	if (cal_block == NULL) {
+		pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
+		goto done;
+	}
+
+	cal_block->cal_size =
+		atomic_read(&acdb_data.vocproc_cal.cal_size);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.vocproc_cal.cal_paddr);
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.vocproc_cal.cal_kvaddr);
+done:
+	return;
+}
+
+void store_vocstrm_cal(struct cal_block *cal_block)
+{
+	pr_debug("%s\n", __func__);
+
+	if (cal_block->cal_offset >
+			atomic64_read(&acdb_data.mem_len)) {
+		pr_err("%s: offset %d is > mem_len %ld\n",
+			__func__, cal_block->cal_offset,
+			(long)atomic64_read(&acdb_data.mem_len));
+		atomic_set(&acdb_data.vocstrm_cal.cal_size, 0);
+		goto done;
+	}
+
+	atomic_set(&acdb_data.vocstrm_cal.cal_size,
+		cal_block->cal_size);
+	atomic_set(&acdb_data.vocstrm_cal.cal_paddr,
+		cal_block->cal_offset +
+		atomic64_read(&acdb_data.paddr));
+	atomic_set(&acdb_data.vocstrm_cal.cal_kvaddr,
+		cal_block->cal_offset +
+		atomic64_read(&acdb_data.kvaddr));
+
+done:
+	return;
+}
+
+void get_vocstrm_cal(struct acdb_cal_block *cal_block)
+{
+	pr_debug("%s\n", __func__);
+
+	if (cal_block == NULL) {
+		pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
+		goto done;
+	}
+
+	cal_block->cal_size =
+		atomic_read(&acdb_data.vocstrm_cal.cal_size);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.vocstrm_cal.cal_paddr);
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.vocstrm_cal.cal_kvaddr);
+done:
+	return;
+}
+
+void store_vocvol_cal(struct cal_block *cal_block)
+{
+	pr_debug("%s\n", __func__);
+
+	if (cal_block->cal_offset >
+			atomic64_read(&acdb_data.mem_len)) {
+		pr_err("%s: offset %d is > mem_len %ld\n",
+			__func__, cal_block->cal_offset,
+			(long)atomic64_read(&acdb_data.mem_len));
+		atomic_set(&acdb_data.vocvol_cal.cal_size, 0);
+		goto done;
+	}
+
+	atomic_set(&acdb_data.vocvol_cal.cal_size,
+		cal_block->cal_size);
+	atomic_set(&acdb_data.vocvol_cal.cal_paddr,
+		cal_block->cal_offset +
+		atomic64_read(&acdb_data.paddr));
+	atomic_set(&acdb_data.vocvol_cal.cal_kvaddr,
+		cal_block->cal_offset +
+		atomic64_read(&acdb_data.kvaddr));
+
+done:
+	return;
+}
+
+void get_vocvol_cal(struct acdb_cal_block *cal_block)
+{
+	pr_debug("%s\n", __func__);
+
+	if (cal_block == NULL) {
+		pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
+		goto done;
+	}
+
+	cal_block->cal_size =
+		atomic_read(&acdb_data.vocvol_cal.cal_size);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.vocvol_cal.cal_paddr);
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.vocvol_cal.cal_kvaddr);
+done:
+	return;
+}
+
+void store_sidetone_cal(struct sidetone_cal *cal_data)
+{
+	pr_debug("%s\n", __func__);
+
+	atomic_set(&acdb_data.sidetone_cal.enable, cal_data->enable);
+	atomic_set(&acdb_data.sidetone_cal.gain, cal_data->gain);
+}
+
+
+void get_sidetone_cal(struct sidetone_cal *cal_data)
+{
+	pr_debug("%s\n", __func__);
+
+	if (cal_data == NULL) {
+		pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
+		goto done;
+	}
+
+	cal_data->enable = atomic_read(&acdb_data.sidetone_cal.enable);
+	cal_data->gain = atomic_read(&acdb_data.sidetone_cal.gain);
+done:
+	return;
+}
+
+static int acdb_open(struct inode *inode, struct file *f)
+{
+	s32 result = 0;
+	pr_debug("%s\n", __func__);
+
+	if (atomic64_read(&acdb_data.mem_len)) {
+		pr_debug("%s: ACDB opened but memory allocated, using existing allocation!\n",
+			__func__);
+	}
+
+	atomic_set(&acdb_data.valid_adm_custom_top, 1);
+	atomic_set(&acdb_data.valid_asm_custom_top, 1);
+	atomic_inc(&usage_count);
+	return result;
+}
+
+static int deregister_memory(void)
+{
+	int i;
+
+	if (atomic64_read(&acdb_data.mem_len)) {
+		mutex_lock(&acdb_data.acdb_mutex);
+		atomic64_set(&acdb_data.mem_len, 0);
+
+		for (i = 0; i < MAX_VOCPROC_TYPES; i++) {
+			kfree(acdb_data.col_data[i]);
+			acdb_data.col_data[i] = NULL;
+		}
+		ion_unmap_kernel(acdb_data.ion_client, acdb_data.ion_handle);
+		ion_free(acdb_data.ion_client, acdb_data.ion_handle);
+		ion_client_destroy(acdb_data.ion_client);
+		mutex_unlock(&acdb_data.acdb_mutex);
+	}
+	return 0;
+}
+
+static int register_memory(void)
+{
+	int			result;
+	int			i;
+	unsigned long		paddr;
+	void                    *kvptr;
+	unsigned long		kvaddr;
+	unsigned long		mem_len;
+
+	mutex_lock(&acdb_data.acdb_mutex);
+	for (i = 0; i < MAX_VOCPROC_TYPES; i++) {
+		acdb_data.col_data[i] = kmalloc(MAX_COL_SIZE, GFP_KERNEL);
+		atomic_set(&acdb_data.vocproc_col_cal[i].cal_kvaddr,
+			(uint32_t)acdb_data.col_data[i]);
+	}
+
+	acdb_data.ion_client =
+		msm_ion_client_create(UINT_MAX, "audio_acdb_client");
+	if (IS_ERR_OR_NULL(acdb_data.ion_client)) {
+		pr_err("%s: Could not register ION client!!!\n", __func__);
+		result = PTR_ERR(acdb_data.ion_client);
+		goto err;
+	}
+
+	acdb_data.ion_handle = ion_import_dma_buf(acdb_data.ion_client,
+		atomic_read(&acdb_data.map_handle));
+	if (IS_ERR_OR_NULL(acdb_data.ion_handle)) {
+		pr_err("%s: Could not import map handle!!!\n", __func__);
+		result = PTR_ERR(acdb_data.ion_handle);
+		goto err_ion_client;
+	}
+
+	result = ion_phys(acdb_data.ion_client, acdb_data.ion_handle,
+				&paddr, (size_t *)&mem_len);
+	if (result != 0) {
+		pr_err("%s: Could not get phys addr!!!\n", __func__);
+		goto err_ion_handle;
+	}
+
+	kvptr = ion_map_kernel(acdb_data.ion_client,
+		acdb_data.ion_handle);
+	if (IS_ERR_OR_NULL(kvptr)) {
+		pr_err("%s: Could not get kernel virt addr!!!\n", __func__);
+		result = PTR_ERR(kvptr);
+		goto err_ion_handle;
+	}
+	kvaddr = (unsigned long)kvptr;
+	atomic64_set(&acdb_data.paddr, paddr);
+	atomic64_set(&acdb_data.kvaddr, kvaddr);
+	atomic64_set(&acdb_data.mem_len, mem_len);
+	mutex_unlock(&acdb_data.acdb_mutex);
+
+	pr_debug("%s done! paddr = 0x%lx, kvaddr = 0x%lx, len = x%lx\n",
+		 __func__,
+		(long)atomic64_read(&acdb_data.paddr),
+		(long)atomic64_read(&acdb_data.kvaddr),
+		(long)atomic64_read(&acdb_data.mem_len));
+
+	return result;
+err_ion_handle:
+	ion_free(acdb_data.ion_client, acdb_data.ion_handle);
+err_ion_client:
+	ion_client_destroy(acdb_data.ion_client);
+err:
+	atomic64_set(&acdb_data.mem_len, 0);
+	mutex_unlock(&acdb_data.acdb_mutex);
+	return result;
+}
+static long acdb_ioctl(struct file *f,
+		unsigned int cmd, unsigned long arg)
+{
+	int32_t			result = 0;
+	int32_t			size;
+	int32_t			map_fd;
+	uint32_t		topology;
+	uint32_t		data[MAX_IOCTL_DATA];
+	pr_debug("%s\n", __func__);
+
+	switch (cmd) {
+	case AUDIO_REGISTER_PMEM:
+		pr_debug("AUDIO_REGISTER_PMEM\n");
+		if (atomic_read(&acdb_data.mem_len)) {
+			deregister_memory();
+			pr_debug("Remove the existing memory\n");
+		}
+
+		if (copy_from_user(&map_fd, (void *)arg, sizeof(map_fd))) {
+			pr_err("%s: fail to copy memory handle!\n", __func__);
+			result = -EFAULT;
+		} else {
+			atomic_set(&acdb_data.map_handle, map_fd);
+			result = register_memory();
+		}
+		goto done;
+
+	case AUDIO_DEREGISTER_PMEM:
+		pr_debug("AUDIO_DEREGISTER_PMEM\n");
+		deregister_memory();
+		goto done;
+	case AUDIO_SET_VOICE_RX_TOPOLOGY:
+		if (copy_from_user(&topology, (void *)arg,
+				sizeof(topology))) {
+			pr_err("%s: fail to copy topology!\n", __func__);
+			result = -EFAULT;
+		}
+		store_voice_rx_topology(topology);
+		goto done;
+	case AUDIO_SET_VOICE_TX_TOPOLOGY:
+		if (copy_from_user(&topology, (void *)arg,
+				sizeof(topology))) {
+			pr_err("%s: fail to copy topology!\n", __func__);
+			result = -EFAULT;
+		}
+		store_voice_tx_topology(topology);
+		goto done;
+	case AUDIO_SET_ADM_RX_TOPOLOGY:
+		if (copy_from_user(&topology, (void *)arg,
+				sizeof(topology))) {
+			pr_err("%s: fail to copy topology!\n", __func__);
+			result = -EFAULT;
+		}
+		store_adm_rx_topology(topology);
+		goto done;
+	case AUDIO_SET_ADM_TX_TOPOLOGY:
+		if (copy_from_user(&topology, (void *)arg,
+				sizeof(topology))) {
+			pr_err("%s: fail to copy topology!\n", __func__);
+			result = -EFAULT;
+		}
+		store_adm_tx_topology(topology);
+		goto done;
+	case AUDIO_SET_ASM_TOPOLOGY:
+		if (copy_from_user(&topology, (void *)arg,
+				sizeof(topology))) {
+			pr_err("%s: fail to copy topology!\n", __func__);
+			result = -EFAULT;
+		}
+		store_asm_topology(topology);
+		goto done;
+	}
+
+	if (copy_from_user(&size, (void *) arg, sizeof(size))) {
+
+		result = -EFAULT;
+		goto done;
+	}
+
+	if (size <= 0) {
+		pr_err("%s: Invalid size sent to driver: %d\n",
+			__func__, size);
+		result = -EFAULT;
+		goto done;
+	}
+
+	switch (cmd) {
+	case AUDIO_SET_VOCPROC_COL_CAL:
+		store_voice_col_data(VOCPROC_CAL, size, (uint32_t *)arg);
+		goto done;
+	case AUDIO_SET_VOCSTRM_COL_CAL:
+		store_voice_col_data(VOCSTRM_CAL, size, (uint32_t *)arg);
+		goto done;
+	case AUDIO_SET_VOCVOL_COL_CAL:
+		store_voice_col_data(VOCVOL_CAL, size, (uint32_t *)arg);
+		goto done;
+	}
+
+	if (copy_from_user(data, (void *)(arg + sizeof(size)), size)) {
+
+		pr_err("%s: fail to copy table size %d\n", __func__, size);
+		result = -EFAULT;
+		goto done;
+	}
+
+	if (data == NULL) {
+		pr_err("%s: NULL pointer sent to driver!\n", __func__);
+		result = -EFAULT;
+		goto done;
+	}
+
+	if (size > sizeof(struct cal_block))
+		pr_err("%s: More cal data for ioctl 0x%x then expected, size received: %d\n",
+			__func__, cmd, size);
+
+	switch (cmd) {
+	case AUDIO_SET_AUDPROC_TX_CAL:
+		store_audproc_cal(TX_CAL, (struct cal_block *)data);
+		goto done;
+	case AUDIO_SET_AUDPROC_RX_CAL:
+		store_audproc_cal(RX_CAL, (struct cal_block *)data);
+		goto done;
+	case AUDIO_SET_AUDPROC_TX_STREAM_CAL:
+		store_audstrm_cal(TX_CAL, (struct cal_block *)data);
+		goto done;
+	case AUDIO_SET_AUDPROC_RX_STREAM_CAL:
+		store_audstrm_cal(RX_CAL, (struct cal_block *)data);
+		goto done;
+	case AUDIO_SET_AUDPROC_TX_VOL_CAL:
+		store_audvol_cal(TX_CAL, (struct cal_block *)data);
+		goto done;
+	case AUDIO_SET_AUDPROC_RX_VOL_CAL:
+		store_audvol_cal(RX_CAL, (struct cal_block *)data);
+		goto done;
+	case AUDIO_SET_AFE_TX_CAL:
+		store_afe_cal(TX_CAL, (struct cal_block *)data);
+		goto done;
+	case AUDIO_SET_AFE_RX_CAL:
+		store_afe_cal(RX_CAL, (struct cal_block *)data);
+		goto done;
+	case AUDIO_SET_VOCPROC_CAL:
+		store_vocproc_cal((struct cal_block *)data);
+		goto done;
+	case AUDIO_SET_VOCPROC_STREAM_CAL:
+		store_vocstrm_cal((struct cal_block *)data);
+		goto done;
+	case AUDIO_SET_VOCPROC_VOL_CAL:
+		store_vocvol_cal((struct cal_block *)data);
+		goto done;
+	case AUDIO_SET_VOCPROC_DEV_CFG_CAL:
+		store_vocproc_dev_cfg_cal((struct cal_block *)data);
+		goto done;
+	case AUDIO_SET_SIDETONE_CAL:
+		store_sidetone_cal((struct sidetone_cal *)data);
+		goto done;
+	case AUDIO_SET_ANC_CAL:
+		store_anc_cal((struct cal_block *)data);
+		goto done;
+	case AUDIO_SET_LSM_CAL:
+		store_lsm_cal((struct cal_block *)data);
+		goto done;
+	case AUDIO_SET_ADM_CUSTOM_TOPOLOGY:
+		store_adm_custom_topology((struct cal_block *)data);
+		goto done;
+	case AUDIO_SET_ASM_CUSTOM_TOPOLOGY:
+		store_asm_custom_topology((struct cal_block *)data);
+		goto done;
+	default:
+		pr_err("ACDB=> ACDB ioctl not found!\n");
+	}
+
+done:
+	return result;
+}
+
+static int acdb_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	int result = 0;
+	int size = vma->vm_end - vma->vm_start;
+
+	pr_debug("%s\n", __func__);
+
+	if (atomic64_read(&acdb_data.mem_len)) {
+		if (size <= atomic64_read(&acdb_data.mem_len)) {
+			vma->vm_page_prot = pgprot_noncached(
+						vma->vm_page_prot);
+			result = remap_pfn_range(vma,
+				vma->vm_start,
+				atomic64_read(&acdb_data.paddr) >> PAGE_SHIFT,
+				size,
+				vma->vm_page_prot);
+		} else {
+			pr_err("%s: Not enough memory!\n", __func__);
+			result = -ENOMEM;
+		}
+	} else {
+		pr_err("%s: memory is not allocated, yet!\n", __func__);
+		result = -ENODEV;
+	}
+
+	return result;
+}
+
+static int acdb_release(struct inode *inode, struct file *f)
+{
+	s32 result = 0;
+
+	atomic_dec(&usage_count);
+	atomic_read(&usage_count);
+
+	pr_debug("%s: ref count %d!\n", __func__,
+		atomic_read(&usage_count));
+
+	if (atomic_read(&usage_count) >= 1)
+		result = -EBUSY;
+	else
+		result = deregister_memory();
+
+	return result;
+}
+
+static const struct file_operations acdb_fops = {
+	.owner = THIS_MODULE,
+	.open = acdb_open,
+	.release = acdb_release,
+	.unlocked_ioctl = acdb_ioctl,
+	.mmap = acdb_mmap,
+};
+
+struct miscdevice acdb_misc = {
+	.minor	= MISC_DYNAMIC_MINOR,
+	.name	= "msm_acdb",
+	.fops	= &acdb_fops,
+};
+
+static int __init acdb_init(void)
+{
+	memset(&acdb_data, 0, sizeof(acdb_data));
+	mutex_init(&acdb_data.acdb_mutex);
+	atomic_set(&usage_count, 0);
+	atomic_set(&acdb_data.valid_adm_custom_top, 1);
+	atomic_set(&acdb_data.valid_asm_custom_top, 1);
+
+	return misc_register(&acdb_misc);
+}
+
+static void __exit acdb_exit(void)
+{
+}
+
+module_init(acdb_init);
+module_exit(acdb_exit);
+
+MODULE_DESCRIPTION("SoC QDSP6v2 Audio ACDB driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/msm/qdsp6v2/audio_acdb.h b/sound/soc/msm/qdsp6v2/audio_acdb.h
new file mode 100644
index 0000000..0b6110d
--- /dev/null
+++ b/sound/soc/msm/qdsp6v2/audio_acdb.h
@@ -0,0 +1,67 @@
+/* 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.
+ *
+ */
+#ifndef _AUDIO_ACDB_H
+#define _AUDIO_ACDB_H
+
+#include <linux/msm_audio_acdb.h>
+#include <sound/q6adm-v2.h>
+
+enum {
+	RX_CAL,
+	TX_CAL,
+	MAX_AUDPROC_TYPES
+};
+
+enum {
+	VOCPROC_CAL,
+	VOCSTRM_CAL,
+	VOCVOL_CAL,
+	MAX_VOCPROC_TYPES
+};
+
+struct acdb_cal_block {
+	uint32_t		cal_size;
+	uint32_t		cal_kvaddr;
+	uint32_t		cal_paddr;
+};
+
+struct acdb_atomic_cal_block {
+	atomic_t		cal_size;
+	atomic_t		cal_kvaddr;
+	atomic_t		cal_paddr;
+};
+
+uint32_t get_voice_rx_topology(void);
+uint32_t get_voice_tx_topology(void);
+uint32_t get_adm_rx_topology(void);
+uint32_t get_adm_tx_topology(void);
+uint32_t get_asm_topology(void);
+void reset_custom_topology_flags(void);
+void get_adm_custom_topology(struct acdb_cal_block *cal_block);
+void get_asm_custom_topology(struct acdb_cal_block *cal_block);
+void get_voice_cal_allocation(struct acdb_cal_block *cal_block);
+void get_lsm_cal(struct acdb_cal_block *cal_block);
+void get_anc_cal(struct acdb_cal_block *cal_block);
+void get_afe_cal(int32_t path, struct acdb_cal_block *cal_block);
+void get_audproc_cal(int32_t path, struct acdb_cal_block *cal_block);
+void get_audstrm_cal(int32_t path, struct acdb_cal_block *cal_block);
+void get_audvol_cal(int32_t path, struct acdb_cal_block *cal_block);
+void get_voice_col_data(uint32_t vocproc_type,
+	struct acdb_cal_block *cal_block);
+void get_vocproc_dev_cfg_cal(struct acdb_cal_block *cal_block);
+void get_vocproc_cal(struct acdb_cal_block *cal_block);
+void get_vocstrm_cal(struct acdb_cal_block *cal_block);
+void get_vocvol_cal(struct acdb_cal_block *cal_block);
+void get_sidetone_cal(struct sidetone_cal *cal_data);
+
+#endif
diff --git a/sound/soc/msm/qdsp6v2/audio_ocmem.c b/sound/soc/msm/qdsp6v2/audio_ocmem.c
index f151e51..c14cb74 100644
--- a/sound/soc/msm/qdsp6v2/audio_ocmem.c
+++ b/sound/soc/msm/qdsp6v2/audio_ocmem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -30,6 +30,15 @@
 
 #define AUDIO_OCMEM_BUF_SIZE (512 * SZ_1K)
 
+#define _BIT_MASK_\
+		((1 << OCMEM_STATE_EXIT) |\
+		(1 << OCMEM_STATE_GROW) |\
+		(1 << OCMEM_STATE_SHRINK))
+
+#define set_bit_pos(x, y)  (atomic_set(&x, (atomic_read(&x) | (1 << y))))
+#define clear_bit_pos(x, y)  (atomic_set(&x, (atomic_read(&x) & (~(1 << y)))))
+#define test_bit_pos(x, y) ((atomic_read(&x)) & (1 << y))
+
 static int enable_ocmem_audio_voice = 1;
 module_param(enable_ocmem_audio_voice, int,
 			S_IRUGO | S_IWUSR | S_IWGRP);
@@ -48,6 +57,8 @@
 	OCMEM_STATE_MAP_FAIL,
 	OCMEM_STATE_UNMAP_FAIL,
 	OCMEM_STATE_EXIT,
+	OCMEM_STATE_SSR,
+	OCMEM_STATE_DISABLE,
 };
 static void audio_ocmem_process_workdata(struct work_struct *work);
 
@@ -74,6 +85,7 @@
 	atomic_t  audio_cond;
 	atomic_t  audio_exit;
 	spinlock_t audio_lock;
+	struct mutex protect_lock;
 	struct workqueue_struct *audio_ocmem_workqueue;
 	struct workqueue_struct *voice_ocmem_workqueue;
 	bool ocmem_en;
@@ -81,7 +93,6 @@
 
 static struct audio_ocmem_prv audio_ocmem_lcl;
 
-
 static int audio_ocmem_client_cb(struct notifier_block *this,
 		 unsigned long event1, void *data)
 {
@@ -97,7 +108,9 @@
 	switch (event1) {
 	case OCMEM_MAP_DONE:
 		pr_debug("%s: map done\n", __func__);
-		atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_MAP_COMPL);
+		clear_bit_pos(audio_ocmem_lcl.audio_state,
+				OCMEM_STATE_MAP_TRANSITION);
+		set_bit_pos(audio_ocmem_lcl.audio_state, OCMEM_STATE_MAP_COMPL);
 		break;
 	case OCMEM_MAP_FAIL:
 		pr_debug("%s: map fail\n", __func__);
@@ -105,7 +118,9 @@
 		break;
 	case OCMEM_UNMAP_DONE:
 		pr_debug("%s: unmap done\n", __func__);
-		atomic_set(&audio_ocmem_lcl.audio_state,
+		clear_bit_pos(audio_ocmem_lcl.audio_state,
+				OCMEM_STATE_UNMAP_TRANSITION);
+		set_bit_pos(audio_ocmem_lcl.audio_state,
 				OCMEM_STATE_UNMAP_COMPL);
 		break;
 	case OCMEM_UNMAP_FAIL:
@@ -115,13 +130,13 @@
 		break;
 	case OCMEM_ALLOC_GROW:
 		rbuf = data;
-		if (rbuf->len == AUDIO_OCMEM_BUF_SIZE) {
+		if ((rbuf->len == AUDIO_OCMEM_BUF_SIZE)) {
 			audio_ocmem_lcl.buf = data;
 			pr_debug("%s: Alloc grow request received buf->addr: 0x%08lx\n",
 						__func__,
 						(audio_ocmem_lcl.buf)->addr);
-			atomic_set(&audio_ocmem_lcl.audio_state,
-							OCMEM_STATE_GROW);
+			set_bit_pos(audio_ocmem_lcl.audio_state,
+					OCMEM_STATE_GROW);
 		} else {
 			pr_debug("%s: Alloc grow request with size: %ld",
 							__func__,
@@ -132,19 +147,33 @@
 		break;
 	case OCMEM_ALLOC_SHRINK:
 		pr_debug("%s: Alloc shrink request received\n", __func__);
-		atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_SHRINK);
+		set_bit_pos(audio_ocmem_lcl.audio_state, OCMEM_STATE_SHRINK);
 		break;
 	default:
 		pr_err("%s: Invalid event[%ld]\n", __func__, event1);
 		break;
 	}
 	spin_unlock_irqrestore(&audio_ocmem_lcl.audio_lock, flags);
-	if (!vwait && (atomic_read(&audio_ocmem_lcl.audio_cond))) {
 		atomic_set(&audio_ocmem_lcl.audio_cond, 0);
 		wake_up(&audio_ocmem_lcl.audio_wait);
-	}
 	return rc;
 }
+int get_state_to_process(atomic_t *state)
+{
+
+	if (test_bit_pos((*state), OCMEM_STATE_SHRINK)) {
+		pr_debug("%s: returning shrink state\n", __func__);
+		return OCMEM_STATE_SHRINK;
+	} else if (test_bit_pos((*state), OCMEM_STATE_GROW)) {
+		pr_debug("%s: returning grow state\n", __func__);
+		return OCMEM_STATE_GROW;
+	} else if (test_bit_pos((*state), OCMEM_STATE_EXIT)) {
+		pr_debug("%s: returning exit state\n", __func__);
+		return OCMEM_STATE_EXIT;
+	} else
+		return -EINVAL;
+
+}
 
 /**
  * audio_ocmem_enable() - Exercise OCMEM for audio
@@ -159,36 +188,12 @@
 {
 	int ret;
 	int i, j;
+	int state_bit;
 	struct ocmem_buf *buf = NULL;
 	struct avcs_cmd_rsp_get_low_power_segments_info_t *lp_segptr;
 
 	pr_debug("%s\n", __func__);
-	/* Non-blocking ocmem allocate (asynchronous) */
-	buf = ocmem_allocate_nb(cid, AUDIO_OCMEM_BUF_SIZE);
-	if (IS_ERR_OR_NULL(buf)) {
-		pr_err("%s: failed: %d\n", __func__, cid);
-		return -ENOMEM;
-	}
-	atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_ALLOC);
-
-	audio_ocmem_lcl.buf = buf;
-	atomic_set(&audio_ocmem_lcl.audio_exit, 0);
-	atomic_set(&audio_ocmem_lcl.audio_cond, 1);
-	pr_debug("%s: buf->len: %ld\n", __func__, buf->len);
-	if (!buf->len) {
-		pr_debug("%s: buf.len is 0, waiting for ocmem region\n",
-								__func__);
-		wait_event_interruptible(audio_ocmem_lcl.audio_wait,
-			(atomic_read(&audio_ocmem_lcl.audio_cond) == 0)	||
-			(atomic_read(&audio_ocmem_lcl.audio_exit) == 1));
-		if (atomic_read(&audio_ocmem_lcl.audio_exit)) {
-			pr_err("%s: audio playback ended while waiting for ocmem\n",
-					__func__);
-			ret = -EINVAL;
-			goto fail_cmd;
-		}
-	}
-	pr_debug("%s: buf->len: %ld\n", __func__, (audio_ocmem_lcl.buf)->len);
+	atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_DEFAULT);
 	if (audio_ocmem_lcl.lp_memseg_ptr == NULL) {
 		/* Retrieve low power segments */
 		ret = core_get_low_power_segments(
@@ -213,6 +218,42 @@
 			(uint32_t)audio_ocmem_lcl.mlist.chunks[j].ddr_paddr,
 			(uint32_t)audio_ocmem_lcl.mlist.chunks[j].size);
 	}
+	/* Non-blocking ocmem allocate (asynchronous) */
+	buf = ocmem_allocate_nb(cid, AUDIO_OCMEM_BUF_SIZE);
+	if (IS_ERR_OR_NULL(buf)) {
+		pr_err("%s: failed: %d\n", __func__, cid);
+		return -ENOMEM;
+	}
+
+	set_bit_pos(audio_ocmem_lcl.audio_state, OCMEM_STATE_ALLOC);
+
+	audio_ocmem_lcl.buf = buf;
+	atomic_set(&audio_ocmem_lcl.audio_exit, 0);
+	atomic_set(&audio_ocmem_lcl.audio_cond, 1);
+	pr_debug("%s: buf->len: %ld\n", __func__, buf->len);
+	if (!buf->len) {
+		pr_debug("%s: buf.len is 0, waiting for ocmem region\n",
+								__func__);
+		mutex_unlock(&audio_ocmem_lcl.protect_lock);
+		wait_event_interruptible(audio_ocmem_lcl.audio_wait,
+			(atomic_read(&audio_ocmem_lcl.audio_cond) == 0)	||
+			(atomic_read(&audio_ocmem_lcl.audio_exit) == 1));
+		if (atomic_read(&audio_ocmem_lcl.audio_exit)) {
+			ret = ocmem_free(OCMEM_LP_AUDIO, audio_ocmem_lcl.buf);
+			if (ret) {
+				pr_err("%s: ocmem_free failed, state[%d]\n",
+				__func__,
+				atomic_read(&audio_ocmem_lcl.audio_state));
+			}
+			pr_info("%s: audio playback ended while waiting for ocmem\n",
+					__func__);
+			ret = 0;
+			goto fail_cmd;
+		}
+		clear_bit_pos(audio_ocmem_lcl.audio_state, OCMEM_STATE_GROW);
+		mutex_trylock(&audio_ocmem_lcl.protect_lock);
+	}
+	pr_debug("%s: buf->len: %ld\n", __func__, (audio_ocmem_lcl.buf)->len);
 
 	/* vote for ocmem bus bandwidth */
 	ret = msm_bus_scale_client_update_request(
@@ -221,7 +262,7 @@
 	if (ret)
 		pr_err("%s: failed to vote for bus bandwidth\n", __func__);
 
-	atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_MAP_TRANSITION);
+	set_bit_pos(audio_ocmem_lcl.audio_state, OCMEM_STATE_MAP_TRANSITION);
 
 	pr_debug("%s: buf->addr: 0x%08lx, len: %ld, audio_state[0x%x]\n",
 				__func__,
@@ -236,16 +277,25 @@
 		atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_MAP_FAIL);
 	}
 
+	wait_event_interruptible(audio_ocmem_lcl.audio_wait,
+			test_bit_pos(audio_ocmem_lcl.audio_state,
+				OCMEM_STATE_MAP_COMPL) != 0);
+	atomic_set(&audio_ocmem_lcl.audio_cond, 1);
+
+	mutex_unlock(&audio_ocmem_lcl.protect_lock);
 	pr_debug("%s: audio_cond[%d] audio_state[0x%x]\n", __func__,
 				atomic_read(&audio_ocmem_lcl.audio_cond),
 				atomic_read(&audio_ocmem_lcl.audio_state));
-	while ((atomic_read(&audio_ocmem_lcl.audio_state) !=
-						OCMEM_STATE_EXIT)) {
+
+	while ((test_bit_pos(audio_ocmem_lcl.audio_state,
+					OCMEM_STATE_DISABLE)) == 0) {
 
 		wait_event_interruptible(audio_ocmem_lcl.audio_wait,
-				atomic_read(&audio_ocmem_lcl.audio_cond) == 0);
+				(atomic_read(&audio_ocmem_lcl.audio_state) &
+						_BIT_MASK_) != 0);
 
-		switch (atomic_read(&audio_ocmem_lcl.audio_state)) {
+		state_bit = get_state_to_process(&audio_ocmem_lcl.audio_state);
+		switch (state_bit) {
 		case OCMEM_STATE_MAP_COMPL:
 			pr_debug("%s: audio_cond[0x%x], audio_state[0x%x]\n",
 			__func__, atomic_read(&audio_ocmem_lcl.audio_cond),
@@ -258,6 +308,10 @@
 			pr_debug("%s: ocmem shrink request process\n",
 							__func__);
 			atomic_set(&audio_ocmem_lcl.audio_cond, 1);
+			clear_bit_pos(audio_ocmem_lcl.audio_state,
+					OCMEM_STATE_MAP_COMPL);
+			set_bit_pos(audio_ocmem_lcl.audio_state,
+					OCMEM_STATE_UNMAP_TRANSITION);
 			ret = ocmem_unmap(cid, audio_ocmem_lcl.buf,
 					&audio_ocmem_lcl.mlist);
 			if (ret) {
@@ -267,12 +321,9 @@
 				goto fail_cmd;
 			}
 
-			atomic_set(&audio_ocmem_lcl.audio_state,
-					OCMEM_STATE_UNMAP_TRANSITION);
 			wait_event_interruptible(audio_ocmem_lcl.audio_wait,
-				atomic_read(&audio_ocmem_lcl.audio_cond) == 0);
-			atomic_set(&audio_ocmem_lcl.audio_state,
-					OCMEM_STATE_UNMAP_COMPL);
+				test_bit_pos(audio_ocmem_lcl.audio_state,
+					OCMEM_STATE_UNMAP_COMPL) != 0);
 			ret = ocmem_shrink(cid, audio_ocmem_lcl.buf, 0);
 			if (ret) {
 				pr_err("%s: ocmem_shrink failed, state[%d]\n",
@@ -281,11 +332,18 @@
 				goto fail_cmd;
 			}
 			atomic_set(&audio_ocmem_lcl.audio_cond, 1);
+			clear_bit_pos(audio_ocmem_lcl.audio_state,
+					OCMEM_STATE_SHRINK);
+			pr_debug("%s:shrink process complete\n", __func__);
 			break;
 		case OCMEM_STATE_GROW:
 			pr_debug("%s: ocmem grow request process\n",
 							__func__);
 			atomic_set(&audio_ocmem_lcl.audio_cond, 1);
+			clear_bit_pos(audio_ocmem_lcl.audio_state,
+					OCMEM_STATE_UNMAP_COMPL);
+			set_bit_pos(audio_ocmem_lcl.audio_state,
+					OCMEM_STATE_MAP_TRANSITION);
 			ret = ocmem_map(cid, audio_ocmem_lcl.buf,
 						&audio_ocmem_lcl.mlist);
 			if (ret) {
@@ -294,14 +352,102 @@
 				atomic_read(&audio_ocmem_lcl.audio_state));
 				goto fail_cmd;
 			}
-			atomic_set(&audio_ocmem_lcl.audio_state,
-				OCMEM_STATE_MAP_TRANSITION);
 			wait_event_interruptible(audio_ocmem_lcl.audio_wait,
-				atomic_read(&audio_ocmem_lcl.audio_cond) == 0);
-			atomic_set(&audio_ocmem_lcl.audio_state,
-				OCMEM_STATE_MAP_COMPL);
+				test_bit_pos(audio_ocmem_lcl.audio_state,
+					OCMEM_STATE_MAP_COMPL) != 0);
+
+			clear_bit_pos(audio_ocmem_lcl.audio_state,
+					OCMEM_STATE_GROW);
 			atomic_set(&audio_ocmem_lcl.audio_cond, 1);
 			break;
+		case OCMEM_STATE_EXIT:
+			if (test_bit_pos(audio_ocmem_lcl.audio_state,
+						OCMEM_STATE_MAP_COMPL)) {
+				clear_bit_pos(audio_ocmem_lcl.audio_state,
+					OCMEM_STATE_MAP_COMPL);
+				set_bit_pos(audio_ocmem_lcl.audio_state,
+					OCMEM_STATE_UNMAP_TRANSITION);
+				ret = ocmem_unmap(cid, audio_ocmem_lcl.buf,
+						&audio_ocmem_lcl.mlist);
+				if (ret) {
+					pr_err("%s: ocmem_unmap failed, state[0x%x]\n",
+					__func__,
+				atomic_read(&audio_ocmem_lcl.audio_state));
+					goto fail_cmd;
+				}
+				wait_event_interruptible(
+				audio_ocmem_lcl.audio_wait,
+				test_bit_pos(audio_ocmem_lcl.audio_state,
+					OCMEM_STATE_UNMAP_COMPL) != 0);
+			}
+
+			if (test_bit_pos(audio_ocmem_lcl.audio_state,
+						OCMEM_STATE_SHRINK)) {
+				pr_debug("%s: SHRINK while exiting\n",
+								__func__);
+				ret = ocmem_shrink(cid, audio_ocmem_lcl.buf,
+									0);
+				if (ret) {
+					pr_err("%s: ocmem_shrink failed, state[0x%x]\n",
+						__func__,
+				atomic_read(&audio_ocmem_lcl.audio_state));
+					goto fail_cmd;
+				}
+				clear_bit_pos(audio_ocmem_lcl.audio_state,
+						OCMEM_STATE_SHRINK);
+
+			}
+
+			pr_debug("%s: calling ocmem free\n", __func__);
+			ret = ocmem_free(OCMEM_LP_AUDIO, audio_ocmem_lcl.buf);
+			if (ret == -EAGAIN) {
+				pr_debug("%s: received EAGAIN\n", __func__);
+				if (test_bit_pos(audio_ocmem_lcl.audio_state,
+							OCMEM_STATE_SHRINK)) {
+					ret = ocmem_shrink(cid,
+							audio_ocmem_lcl.buf,
+							0);
+					if (ret) {
+						pr_err("%s: ocmem_shrink failed, state[0x%x]\n",
+							__func__,
+				atomic_read(&audio_ocmem_lcl.audio_state));
+							goto fail_cmd;
+					}
+					pr_debug("calling free after EAGAIN");
+					ret = ocmem_free(OCMEM_LP_AUDIO,
+							audio_ocmem_lcl.buf);
+					if (ret) {
+						pr_err("%s: ocmem_free failed\n",
+								__func__);
+						goto fail_cmd;
+					}
+				} else {
+					pr_debug("%s: shrink callback already processed\n",
+								__func__);
+					goto fail_cmd;
+				}
+			} else if (ret) {
+				pr_err("%s: ocmem_free failed, state[0x%x], ret:%d\n",
+					__func__,
+				atomic_read(&audio_ocmem_lcl.audio_state),
+				ret);
+				goto fail_cmd;
+			}
+			pr_debug("%s: ocmem_free success\n", __func__);
+			msm_bus_scale_client_update_request(
+				audio_ocmem_lcl.audio_ocmem_bus_client,
+				0);
+			set_bit_pos(audio_ocmem_lcl.audio_state,
+						OCMEM_STATE_DISABLE);
+			break;
+
+
+		case -EINVAL:
+			pr_info("%s: audio_cond[%d] audio_state[0x%x]\n",
+				__func__,
+				atomic_read(&audio_ocmem_lcl.audio_cond),
+				atomic_read(&audio_ocmem_lcl.audio_state));
+			break;
 		}
 	}
 	ret = 0;
@@ -320,64 +466,17 @@
  */
 int audio_ocmem_disable(int cid)
 {
-	int ret;
-	int cur_state;
-
-	pr_debug("%s: disable\n", __func__);
-	cur_state = atomic_read(&audio_ocmem_lcl.audio_state);
-	if (atomic_cmpxchg(&audio_ocmem_lcl.audio_cond, 1, 0)) {
-		atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_EXIT);
-		wake_up(&audio_ocmem_lcl.audio_wait);
-	}
 
 	pr_debug("%s: audio_cond[0x%x], audio_state[0x%x]\n", __func__,
 			 atomic_read(&audio_ocmem_lcl.audio_cond),
 			 atomic_read(&audio_ocmem_lcl.audio_state));
-	switch (cur_state) {
-	case OCMEM_STATE_MAP_COMPL:
-		atomic_set(&audio_ocmem_lcl.audio_cond, 1);
-		ret = ocmem_unmap(cid, audio_ocmem_lcl.buf,
-					&audio_ocmem_lcl.mlist);
-		if (ret) {
-			pr_err("%s: ocmem_unmap failed, state[%d]\n",
-				__func__,
-				atomic_read(&audio_ocmem_lcl.audio_state));
-			goto fail_cmd;
-		}
+	set_bit_pos(audio_ocmem_lcl.audio_state,
+				OCMEM_STATE_EXIT);
+	wake_up(&audio_ocmem_lcl.audio_wait);
 
-		atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_EXIT);
-
-		wait_event_interruptible(audio_ocmem_lcl.audio_wait,
-				atomic_read(&audio_ocmem_lcl.audio_cond) == 0);
-	case OCMEM_STATE_UNMAP_COMPL:
-	case OCMEM_STATE_MAP_FAIL:
-	case OCMEM_STATE_MAP_TRANSITION:
-	case OCMEM_STATE_ALLOC:
-		ret = ocmem_free(OCMEM_LP_AUDIO, audio_ocmem_lcl.buf);
-		if (ret) {
-			pr_err("%s: ocmem_free failed, state[%d]\n",
-				__func__,
-				atomic_read(&audio_ocmem_lcl.audio_state));
-			goto fail_cmd;
-		}
-		pr_debug("%s: state=%d", __func__,
-			atomic_read(&audio_ocmem_lcl.audio_state));
-		atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_EXIT);
-		pr_debug("%s: ocmem_free success\n", __func__);
-		break;
-
-	default:
-		pr_debug("%s:error: state=%d", __func__,
-			atomic_read(&audio_ocmem_lcl.audio_state));
-		break;
-
-	}
-	msm_bus_scale_client_update_request(
-				audio_ocmem_lcl.audio_ocmem_bus_client,
-				0);
+	mutex_unlock(&audio_ocmem_lcl.protect_lock);
+	pr_debug("%s: exit\n", __func__);
 	return 0;
-fail_cmd:
-	return ret;
 }
 
 static void voice_ocmem_process_workdata(struct work_struct *work)
@@ -404,6 +503,7 @@
 		rc = -EINVAL;
 	}
 
+	kfree(voice_ocm_work);
 	return;
 }
 /**
@@ -497,6 +597,10 @@
 			container_of(work, struct audio_ocmem_workdata, work);
 
 	en = audio_ocm_work->en;
+	mutex_lock(&audio_ocmem_lcl.protect_lock);
+	/* if previous work waiting for ocmem - signal it to exit */
+	atomic_set(&audio_ocmem_lcl.audio_exit, 1);
+	pr_debug("%s: acquired mutex for %d\n", __func__, en);
 	switch (audio_ocm_work->id) {
 	case AUDIO:
 		cid = OCMEM_LP_AUDIO;
@@ -511,6 +615,7 @@
 		rc = -EINVAL;
 	}
 
+	kfree(audio_ocm_work);
 	return;
 }
 
@@ -548,9 +653,6 @@
 		workdata->id = id;
 		workdata->en = enable;
 
-		/* if previous work waiting for ocmem - signal it to exit */
-		atomic_set(&audio_ocmem_lcl.audio_exit, 1);
-
 		INIT_WORK(&workdata->work, audio_ocmem_process_workdata);
 		queue_work(audio_ocmem_lcl.audio_ocmem_workqueue,
 							&workdata->work);
@@ -590,7 +692,7 @@
 	pr_debug("%s\n", __func__);
 	audio_ocmem_lcl.audio_ocmem_workqueue =
 		alloc_workqueue("ocmem_audio_client_driver_audio",
-					WQ_NON_REENTRANT, 0);
+					WQ_NON_REENTRANT | WQ_UNBOUND, 0);
 	if (!audio_ocmem_lcl.audio_ocmem_workqueue) {
 		pr_err("%s: Failed to create ocmem audio work queue\n",
 			__func__);
@@ -611,6 +713,7 @@
 	atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_DEFAULT);
 	atomic_set(&audio_ocmem_lcl.audio_exit, 0);
 	spin_lock_init(&audio_ocmem_lcl.audio_lock);
+	mutex_init(&audio_ocmem_lcl.protect_lock);
 	audio_ocmem_lcl.ocmem_en = true;
 
 	/* populate platform data */
diff --git a/sound/soc/msm/qdsp6v2/audio_ocmem.h b/sound/soc/msm/qdsp6v2/audio_ocmem.h
index e915516..08bb1f3 100644
--- a/sound/soc/msm/qdsp6v2/audio_ocmem.h
+++ b/sound/soc/msm/qdsp6v2/audio_ocmem.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
index 8fb70f8..d0b5500 100644
--- a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -50,7 +50,7 @@
 	unsigned volume;
 	atomic_t audio_ocmem_req;
 };
-static struct snd_msm compressed_audio = {NULL, 0x2000} ;
+static struct snd_msm compressed_audio = {NULL, 0x20002000} ;
 
 static struct audio_locks the_locks;
 
@@ -81,7 +81,7 @@
 				SNDRV_PCM_INFO_MMAP_VALID |
 				SNDRV_PCM_INFO_INTERLEAVED |
 				SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
-	.formats =	      SNDRV_PCM_FMTBIT_S16_LE,
+	.formats =	      SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
 	.rates =		SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT,
 	.rate_min =	     8000,
 	.rate_max =	     48000,
@@ -121,6 +121,7 @@
 	int i = 0;
 	int time_stamp_flag = 0;
 	int buffer_length = 0;
+	int stop_playback = 0;
 
 	pr_debug("%s opcode =%08x\n", __func__, opcode);
 	switch (opcode) {
@@ -141,6 +142,22 @@
 			break;
 		} else
 			atomic_set(&prtd->pending_buffer, 0);
+
+		/*
+		 * check for underrun
+		 */
+		snd_pcm_stream_lock_irq(substream);
+		if (snd_pcm_playback_empty(substream)) {
+			runtime->render_flag |= SNDRV_RENDER_STOPPED;
+			stop_playback = 1;
+		}
+		snd_pcm_stream_unlock_irq(substream);
+
+		if (stop_playback) {
+			pr_err("%s empty buffer, stop writes\n", __func__);
+			break;
+		}
+
 		buf = prtd->audio_client->port[IN].buf;
 		pr_debug("%s:writing %d bytes of buffer[%d] to dsp 2\n",
 				__func__, prtd->pcm_count, prtd->out_head);
@@ -347,6 +364,7 @@
 
 	prtd->enabled = 1;
 	prtd->cmd_ack = 0;
+	prtd->cmd_interrupt = 0;
 
 	return 0;
 }
@@ -452,12 +470,12 @@
 				break;
 			}
 		}
+		atomic_set(&prtd->pending_buffer, 1);
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 		pr_debug("%s: Trigger start\n", __func__);
 		q6asm_run_nowait(prtd->audio_client, 0, 0, 0);
 		atomic_set(&prtd->start, 1);
-		atomic_set(&prtd->pending_buffer, 1);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 		pr_debug("SNDRV_PCM_TRIGGER_STOP\n");
@@ -509,17 +527,6 @@
 	struct compr_audio *compr;
 	struct msm_audio *prtd;
 	int ret = 0;
-	struct asm_softpause_params softpause = {
-		.enable = SOFT_PAUSE_ENABLE,
-		.period = SOFT_PAUSE_PERIOD,
-		.step = SOFT_PAUSE_STEP,
-		.rampingcurve = SOFT_PAUSE_CURVE_LINEAR,
-	};
-	struct asm_softvolume_params softvol = {
-		.period = SOFT_VOLUME_PERIOD,
-		.step = SOFT_VOLUME_STEP,
-		.rampingcurve = SOFT_VOLUME_CURVE_LINEAR,
-	};
 
 	pr_debug("%s\n", __func__);
 	compr = kzalloc(sizeof(struct compr_audio), GFP_KERNEL);
@@ -529,6 +536,7 @@
 	}
 	prtd = &compr->prtd;
 	prtd->substream = substream;
+	runtime->render_flag = SNDRV_DMA_MODE;
 	prtd->audio_client = q6asm_audio_client_alloc(
 				(app_cb)compr_event_handler, compr);
 	if (!prtd->audio_client) {
@@ -537,6 +545,7 @@
 		return -ENOMEM;
 	}
 
+	prtd->audio_client->perf_mode = false;
 	pr_info("%s: session ID %d\n", __func__, prtd->audio_client->session);
 
 	prtd->session_id = prtd->audio_client->session;
@@ -569,20 +578,6 @@
 	atomic_set(&prtd->eos, 0);
 	atomic_set(&compressed_audio.audio_ocmem_req, 0);
 	compressed_audio.prtd =  &compr->prtd;
-	ret = compressed_set_volume(compressed_audio.volume);
-	if (ret < 0)
-		pr_err("%s : Set Volume failed : %d", __func__, ret);
-
-	ret = q6asm_set_softpause(compressed_audio.prtd->audio_client,
-								&softpause);
-	if (ret < 0)
-		pr_err("%s: Send SoftPause Param failed ret=%d\n",
-			__func__, ret);
-	ret = q6asm_set_softvolume(compressed_audio.prtd->audio_client,
-								&softvol);
-	if (ret < 0)
-		pr_err("%s: Send SoftVolume Param failed ret=%d\n",
-			__func__, ret);
 
 	return 0;
 }
@@ -591,8 +586,9 @@
 {
 	int rc = 0;
 	if (compressed_audio.prtd && compressed_audio.prtd->audio_client) {
-		rc = q6asm_set_volume(compressed_audio.prtd->audio_client,
-								 volume);
+		rc = q6asm_set_lrgain(compressed_audio.prtd->audio_client,
+						(volume >> 16) & 0xFFFF,
+						volume & 0xFFFF);
 		if (rc < 0) {
 			pr_err("%s: Send Volume command failed rc=%d\n",
 						__func__, rc);
@@ -697,6 +693,7 @@
 
 	pr_debug("%s\n", __func__);
 	prtd->mmap_flag = 1;
+	runtime->render_flag = SNDRV_NON_DMA_MODE;
 	if (runtime->dma_addr && runtime->dma_bytes) {
 		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 		result = remap_pfn_range(vma, vma->vm_start,
@@ -720,24 +717,57 @@
 	struct snd_dma_buffer *dma_buf = &substream->dma_buffer;
 	struct audio_buffer *buf;
 	int dir, ret;
+	uint16_t bits_per_sample = 16;
+
+	struct asm_softpause_params softpause = {
+		.enable = SOFT_PAUSE_ENABLE,
+		.period = SOFT_PAUSE_PERIOD,
+		.step = SOFT_PAUSE_STEP,
+		.rampingcurve = SOFT_PAUSE_CURVE_LINEAR,
+	};
+	struct asm_softvolume_params softvol = {
+		.period = SOFT_VOLUME_PERIOD,
+		.step = SOFT_VOLUME_STEP,
+		.rampingcurve = SOFT_VOLUME_CURVE_LINEAR,
+	};
 
 	pr_debug("%s\n", __func__);
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 		dir = IN;
 	else
 		dir = OUT;
+
+	if (runtime->format == SNDRV_PCM_FORMAT_S24_LE)
+		bits_per_sample = 24;
+
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-			ret = q6asm_open_write(prtd->audio_client,
-					compr->codec);
-			if (ret < 0) {
-				pr_err("%s: Session out open failed\n",
-					__func__);
-				return -ENOMEM;
-			}
-			msm_pcm_routing_reg_phy_stream(
-				soc_prtd->dai_link->be_id,
-				prtd->session_id,
-				substream->stream);
+		ret = q6asm_open_write_v2(prtd->audio_client,
+				compr->codec, bits_per_sample);
+		if (ret < 0) {
+			pr_err("%s: Session out open failed\n",
+				__func__);
+			return -ENOMEM;
+		}
+		msm_pcm_routing_reg_phy_stream(
+			soc_prtd->dai_link->be_id,
+			prtd->audio_client->perf_mode,
+			prtd->session_id,
+			substream->stream);
+
+		ret = compressed_set_volume(compressed_audio.volume);
+		if (ret < 0)
+			pr_err("%s : Set Volume failed : %d", __func__, ret);
+
+		ret = q6asm_set_softpause(compressed_audio.prtd->audio_client,
+								&softpause);
+		if (ret < 0)
+			pr_err("%s: Send SoftPause Param failed ret=%d\n",
+				__func__, ret);
+		ret = q6asm_set_softvolume(compressed_audio.prtd->audio_client,
+								&softvol);
+		if (ret < 0)
+			pr_err("%s: Send SoftVolume Param failed ret=%d\n",
+				__func__, ret);
 	} else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
 		switch (compr->info.codec_param.codec.id) {
 		case SND_AUDIOCODEC_AMRWB:
@@ -752,6 +782,7 @@
 			pr_debug("msm_pcm_routing_reg_phy_stream\n");
 			msm_pcm_routing_reg_phy_stream(
 					soc_prtd->dai_link->be_id,
+					prtd->audio_client->perf_mode,
 					prtd->session_id, substream->stream);
 			break;
 		default:
@@ -789,6 +820,9 @@
 	}
 	runtime->hw.buffer_bytes_max =
 			runtime->hw.period_bytes_min * runtime->hw.periods_max;
+	pr_debug("allocate %d buffers each of size %d\n",
+		runtime->hw.period_bytes_min,
+		runtime->hw.periods_max);
 	ret = q6asm_audio_client_buf_alloc_contiguous(dir,
 			prtd->audio_client,
 			runtime->hw.period_bytes_min,
@@ -834,8 +868,8 @@
 		pr_debug("SNDRV_COMPRESS_TSTAMP\n");
 
 		memset(&tstamp, 0x0, sizeof(struct snd_compr_tstamp));
-		timestamp = q6asm_get_session_time(prtd->audio_client);
-		if (timestamp < 0) {
+		rc = q6asm_get_session_time(prtd->audio_client, &timestamp);
+		if (rc < 0) {
 			pr_err("%s: Get Session Time return value =%lld\n",
 				__func__, timestamp);
 			return -EAGAIN;
@@ -894,7 +928,7 @@
 			  (substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
 						atomic_read(&prtd->start))) {
 			if (atomic_read(&prtd->eos)) {
-				prtd->cmd_ack = 1;
+				prtd->cmd_interrupt = 1;
 				wake_up(&the_locks.eos_wait);
 				atomic_set(&prtd->eos, 0);
 			}
@@ -917,23 +951,98 @@
 		break;
 	case SNDRV_COMPRESS_DRAIN:
 		pr_debug("%s: SNDRV_COMPRESS_DRAIN\n", __func__);
+		if (atomic_read(&prtd->pending_buffer)) {
+			pr_debug("%s: no pending writes, drain would block\n",
+			 __func__);
+			return -EWOULDBLOCK;
+		}
+
 		atomic_set(&prtd->eos, 1);
 		atomic_set(&prtd->pending_buffer, 0);
 		prtd->cmd_ack = 0;
 		q6asm_cmd_nowait(prtd->audio_client, CMD_EOS);
 		/* Wait indefinitely for  DRAIN. Flush can also signal this*/
 		rc = wait_event_interruptible(the_locks.eos_wait,
-			prtd->cmd_ack);
+			(prtd->cmd_ack || prtd->cmd_interrupt));
+
 		if (rc < 0)
 			pr_err("EOS cmd interrupted\n");
 		pr_debug("%s: SNDRV_COMPRESS_DRAIN  out of wait\n", __func__);
-		return 0;
+
+		if (prtd->cmd_interrupt)
+			rc = -EINTR;
+
+		prtd->cmd_interrupt = 0;
+		return rc;
 	default:
 		break;
 	}
 	return snd_pcm_lib_ioctl(substream, cmd, arg);
 }
 
+static int msm_compr_restart(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct compr_audio *compr = runtime->private_data;
+	struct msm_audio *prtd = &compr->prtd;
+	struct audio_aio_write_param param;
+	struct audio_buffer *buf = NULL;
+	struct output_meta_data_st output_meta_data;
+	int time_stamp_flag = 0;
+	int buffer_length = 0;
+
+	pr_debug("%s, trigger restart\n", __func__);
+
+	if (runtime->render_flag & SNDRV_RENDER_STOPPED) {
+		buf = prtd->audio_client->port[IN].buf;
+		pr_debug("%s:writing %d bytes of buffer[%d] to dsp 2\n",
+				__func__, prtd->pcm_count, prtd->out_head);
+		pr_debug("%s:writing buffer[%d] from 0x%08x\n",
+				__func__, prtd->out_head,
+				((unsigned int)buf[0].phys
+				+ (prtd->out_head * prtd->pcm_count)));
+
+		if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
+			time_stamp_flag = SET_TIMESTAMP;
+		else
+			time_stamp_flag = NO_TIMESTAMP;
+		memcpy(&output_meta_data, (char *)(buf->data +
+			prtd->out_head * prtd->pcm_count),
+			COMPRE_OUTPUT_METADATA_SIZE);
+
+		buffer_length = output_meta_data.frame_size;
+		pr_debug("meta_data_length: %d, frame_length: %d\n",
+			 output_meta_data.meta_data_length,
+			 output_meta_data.frame_size);
+		pr_debug("timestamp_msw: %d, timestamp_lsw: %d\n",
+			 output_meta_data.timestamp_msw,
+			 output_meta_data.timestamp_lsw);
+
+		param.paddr = (unsigned long)buf[0].phys
+				+ (prtd->out_head * prtd->pcm_count)
+				+ output_meta_data.meta_data_length;
+		param.len = buffer_length;
+		param.msw_ts = output_meta_data.timestamp_msw;
+		param.lsw_ts = output_meta_data.timestamp_lsw;
+		param.flags = time_stamp_flag;
+		param.uid =  (unsigned long)buf[0].phys
+				+ (prtd->out_head * prtd->pcm_count
+				+ output_meta_data.meta_data_length);
+		if (q6asm_async_write(prtd->audio_client,
+					&param) < 0)
+			pr_err("%s:q6asm_async_write failed\n",
+				__func__);
+		else
+			prtd->out_head =
+				(prtd->out_head + 1) & (runtime->periods - 1);
+
+		runtime->render_flag &= ~SNDRV_RENDER_STOPPED;
+		return 0;
+	}
+	return 0;
+}
+
+
 static struct snd_pcm_ops msm_compr_ops = {
 	.open	   = msm_compr_open,
 	.hw_params	= msm_compr_hw_params,
@@ -943,6 +1052,7 @@
 	.trigger	= msm_compr_trigger,
 	.pointer	= msm_compr_pointer,
 	.mmap		= msm_compr_mmap,
+	.restart	= msm_compr_restart,
 };
 
 static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd)
diff --git a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.h b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.h
index 9830300..d6e3ec6 100644
--- a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-hdmi-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-hdmi-v2.c
index 48d9e1e..329d293 100644
--- a/sound/soc/msm/qdsp6v2/msm-dai-q6-hdmi-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-hdmi-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -24,11 +24,20 @@
 #include <sound/q6afe-v2.h>
 #include <sound/msm-dai-q6-v2.h>
 
+#define HDMI_RX_CA_MAX 0x32
+
 enum {
 	STATUS_PORT_STARTED, /* track if AFE port has started */
 	STATUS_MAX
 };
 
+struct msm_hdmi_ca {
+	bool set_ca;
+	u32 ca;
+};
+
+static struct msm_hdmi_ca hdmi_ca = { false, 0x0 };
+
 struct msm_dai_q6_hdmi_dai_data {
 	DECLARE_BITMAP(status_mask, STATUS_MAX);
 	u32 rate;
@@ -57,6 +66,20 @@
 	return 0;
 }
 
+static int msm_dai_q6_hdmi_ca_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	hdmi_ca.ca = ucontrol->value.integer.value[0];
+	hdmi_ca.set_ca = true;
+	return 0;
+}
+
+static int msm_dai_q6_hdmi_ca_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	ucontrol->value.integer.value[0] = hdmi_ca.ca;
+	return 0;
+}
 
 /* HDMI format field for AFE_PORT_MULTI_CHAN_HDMI_AUDIO_IF_CONFIG command
  *  0: linear PCM
@@ -75,6 +98,10 @@
 	SOC_ENUM_EXT("HDMI RX Format", hdmi_config_enum[0],
 				 msm_dai_q6_hdmi_format_get,
 				 msm_dai_q6_hdmi_format_put),
+	SOC_SINGLE_MULTI_EXT("HDMI RX CA", SND_SOC_NOPM, 0,
+				 HDMI_RX_CA_MAX, 0, 1,
+				 msm_dai_q6_hdmi_ca_get,
+				 msm_dai_q6_hdmi_ca_put),
 };
 
 /* Current implementation assumes hw_param is called once
@@ -152,6 +179,10 @@
 	struct msm_dai_q6_hdmi_dai_data *dai_data = dev_get_drvdata(dai->dev);
 	int rc = 0;
 
+	if (hdmi_ca.set_ca)
+		dai_data->port_config.hdmi_multi_ch.channel_allocation =
+								 hdmi_ca.ca;
+
 	if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
 		rc = afe_port_start(dai->id, &dai_data->port_config,
 				    dai_data->rate);
@@ -186,6 +217,12 @@
 
 	rc = snd_ctl_add(dai->card->snd_card,
 					 snd_ctl_new1(kcontrol, dai_data));
+
+	kcontrol = &hdmi_config_controls[1];
+
+	rc = snd_ctl_add(dai->card->snd_card,
+					 snd_ctl_new1(kcontrol, dai_data));
+
 	return rc;
 }
 
diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
index 2f4c256..a6dce77 100644
--- a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -28,11 +28,26 @@
 #include <sound/pcm_params.h>
 #include <mach/clk.h>
 
+static const struct afe_clk_cfg lpass_clk_cfg_default = {
+	AFE_API_VERSION_I2S_CONFIG,
+	Q6AFE_LPASS_OSR_CLK_2_P048_MHZ,
+	0,
+	Q6AFE_LPASS_CLK_SRC_INTERNAL,
+	Q6AFE_LPASS_CLK_ROOT_DEFAULT,
+	Q6AFE_LPASS_MODE_CLK1_VALID,
+	0,
+};
 enum {
 	STATUS_PORT_STARTED, /* track if AFE port has started */
 	STATUS_MAX
 };
 
+enum {
+	RATE_8KHZ,
+	RATE_16KHZ,
+	RATE_MAX_NUM_OF_AUX_PCM_RATES,
+};
+
 struct msm_dai_q6_dai_data {
 	DECLARE_BITMAP(status_mask, STATUS_MAX);
 	u32 rate;
@@ -70,11 +85,6 @@
 	SOC_ENUM_SINGLE_EXT(4, mi2s_format),
 };
 
-static struct clk *pcm_src_clk;
-static struct clk *pcm_branch_clk;
-static struct clk *pcm_oe_src_clk;
-static struct clk *pcm_oe_branch_clk;
-
 static DEFINE_MUTEX(aux_pcm_mutex);
 static int aux_pcm_count;
 
@@ -92,25 +102,49 @@
 		return -EINVAL;
 	}
 	dai_data->channels = params_channels(params);
-
-	if (params_rate(params) != 8000) {
-		dev_err(dai->dev, "AUX PCM supports only 8KHz sampling rate\n");
-		return -EINVAL;
-	}
 	dai_data->rate = params_rate(params);
 
-	dai_data->port_config.pcm.pcm_cfg_minor_version =
+	switch (dai_data->rate) {
+	case 8000:
+		dai_data->port_config.pcm.pcm_cfg_minor_version =
 				AFE_API_VERSION_PCM_CONFIG;
-	dai_data->port_config.pcm.aux_mode = auxpcm_pdata->mode;
-	dai_data->port_config.pcm.sync_src = auxpcm_pdata->sync;
-	dai_data->port_config.pcm.frame_setting = auxpcm_pdata->frame;
-	dai_data->port_config.pcm.quantype = auxpcm_pdata->quant;
-	dai_data->port_config.pcm.ctrl_data_out_enable = auxpcm_pdata->data;
-	dai_data->port_config.pcm.sample_rate = dai_data->rate;
-	dai_data->port_config.pcm.num_channels = dai_data->channels;
-	dai_data->port_config.pcm.bit_width = 16;
-	dai_data->port_config.pcm.slot_number_mapping[0] = auxpcm_pdata->slot;
-
+		dai_data->port_config.pcm.aux_mode = auxpcm_pdata->mode_8k.mode;
+		dai_data->port_config.pcm.sync_src = auxpcm_pdata->mode_8k.sync;
+		dai_data->port_config.pcm.frame_setting =
+					auxpcm_pdata->mode_8k.frame;
+		dai_data->port_config.pcm.quantype =
+					 auxpcm_pdata->mode_8k.quant;
+		dai_data->port_config.pcm.ctrl_data_out_enable =
+					 auxpcm_pdata->mode_8k.data;
+		dai_data->port_config.pcm.sample_rate = dai_data->rate;
+		dai_data->port_config.pcm.num_channels = dai_data->channels;
+		dai_data->port_config.pcm.bit_width = 16;
+		dai_data->port_config.pcm.slot_number_mapping[0] =
+					 auxpcm_pdata->mode_8k.slot;
+		break;
+	case 16000:
+		dai_data->port_config.pcm.pcm_cfg_minor_version =
+				AFE_API_VERSION_PCM_CONFIG;
+		dai_data->port_config.pcm.aux_mode =
+					auxpcm_pdata->mode_16k.mode;
+		dai_data->port_config.pcm.sync_src =
+					auxpcm_pdata->mode_16k.sync;
+		dai_data->port_config.pcm.frame_setting =
+					auxpcm_pdata->mode_16k.frame;
+		dai_data->port_config.pcm.quantype =
+					auxpcm_pdata->mode_16k.quant;
+		dai_data->port_config.pcm.ctrl_data_out_enable =
+					auxpcm_pdata->mode_16k.data;
+		dai_data->port_config.pcm.sample_rate = dai_data->rate;
+		dai_data->port_config.pcm.num_channels = dai_data->channels;
+		dai_data->port_config.pcm.bit_width = 16;
+		dai_data->port_config.pcm.slot_number_mapping[0] =
+					auxpcm_pdata->mode_16k.slot;
+		break;
+	default:
+		dev_err(dai->dev, "AUX PCM supports only 8kHz and 16kHz sampling rate\n");
+		return -EINVAL;
+	}
 	return 0;
 }
 
@@ -118,6 +152,9 @@
 				struct snd_soc_dai *dai)
 {
 	int rc = 0;
+	struct afe_clk_cfg *lpass_pcm_src_clk = NULL;
+	struct afe_clk_cfg lpass_pcm_oe_clk;
+	struct msm_dai_auxpcm_pdata *auxpcm_pdata = NULL;
 
 	mutex_lock(&aux_pcm_mutex);
 
@@ -146,6 +183,9 @@
 	pr_debug("%s: dai->id = %d aux_pcm_count = %d\n", __func__,
 			dai->id, aux_pcm_count);
 
+	auxpcm_pdata = (struct msm_dai_auxpcm_pdata *)dai->dev->platform_data;
+	lpass_pcm_src_clk = (struct afe_clk_cfg *)auxpcm_pdata->clk_cfg;
+
 	rc = afe_close(PCM_RX); /* can block */
 	if (IS_ERR_VALUE(rc))
 		dev_err(dai->dev, "fail to close PCM_RX  AFE port\n");
@@ -154,8 +194,14 @@
 	if (IS_ERR_VALUE(rc))
 		dev_err(dai->dev, "fail to close AUX PCM TX port\n");
 
-	clk_disable_unprepare(pcm_branch_clk);
-	clk_disable_unprepare(pcm_oe_branch_clk);
+	lpass_pcm_src_clk->clk_val1 = 0;
+	afe_set_lpass_clock(PCM_TX, lpass_pcm_src_clk);
+	afe_set_lpass_clock(PCM_RX, lpass_pcm_src_clk);
+
+	memcpy(&lpass_pcm_oe_clk, &lpass_clk_cfg_default,
+			 sizeof(struct afe_clk_cfg));
+	lpass_pcm_oe_clk.clk_val1 = 0;
+	afe_set_lpass_clock(PCM_RX, &lpass_pcm_oe_clk);
 
 	mutex_unlock(&aux_pcm_mutex);
 }
@@ -166,8 +212,12 @@
 	struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
 	struct msm_dai_auxpcm_pdata *auxpcm_pdata = NULL;
 	int rc = 0;
+	unsigned long pcm_clk_rate;
+	struct afe_clk_cfg lpass_pcm_oe_clk;
+	struct afe_clk_cfg *lpass_pcm_src_clk = NULL;
 
 	auxpcm_pdata = dai->dev->platform_data;
+	lpass_pcm_src_clk = (struct afe_clk_cfg *)auxpcm_pdata->clk_cfg;
 
 	mutex_lock(&aux_pcm_mutex);
 
@@ -210,27 +260,43 @@
 	 * assert/deasset and afe_open sequence is not followed.
 	 */
 
-	rc = clk_set_rate(pcm_src_clk, auxpcm_pdata->pcm_clk_rate);
+	if (dai_data->rate == 8000) {
+		pcm_clk_rate = auxpcm_pdata->mode_8k.pcm_clk_rate;
+	} else if (dai_data->rate == 16000) {
+		pcm_clk_rate = (auxpcm_pdata->mode_16k.pcm_clk_rate);
+	} else {
+		dev_err(dai->dev, "%s: Invalid AUX PCM rate %d\n", __func__,
+			dai_data->rate);
+		mutex_unlock(&aux_pcm_mutex);
+		return -EINVAL;
+	}
+
+	memcpy(lpass_pcm_src_clk, &lpass_clk_cfg_default,
+			sizeof(struct afe_clk_cfg));
+	lpass_pcm_src_clk->clk_val1 = pcm_clk_rate;
+
+	memcpy(&lpass_pcm_oe_clk, &lpass_clk_cfg_default,
+			sizeof(struct afe_clk_cfg));
+	lpass_pcm_oe_clk.clk_val1 = Q6AFE_LPASS_OSR_CLK_12_P288_MHZ;
+
+	rc = afe_set_lpass_clock(PCM_RX, lpass_pcm_src_clk);
 	if (rc < 0) {
-		pr_err("%s: clk_set_rate failed\n", __func__);
+		pr_err("%s:afe_set_lpass_clock on RX pcm_src_clk failed\n",
+							__func__);
 		goto fail;
 	}
 
-	rc = clk_prepare_enable(pcm_branch_clk);
-	if (rc) {
-		pr_err("%s: clk enable failed\n", __func__);
-		goto fail;
-	}
-
-	rc = clk_set_rate(pcm_oe_src_clk, 24576000>>1);
+	rc = afe_set_lpass_clock(PCM_TX, lpass_pcm_src_clk);
 	if (rc < 0) {
-		pr_err("%s: clk_set_rate on pcm oe failed\n", __func__);
+		pr_err("%s:afe_set_lpass_clock on TX pcm_src_clk failed\n",
+							__func__);
 		goto fail;
 	}
 
-	rc = clk_prepare_enable(pcm_oe_branch_clk);
-	if (rc) {
-		pr_err("%s: clk enable pcm_oe_branch_clk failed\n", __func__);
+	rc = afe_set_lpass_clock(PCM_RX, &lpass_pcm_oe_clk);
+	if (rc < 0) {
+		pr_err("%s:afe_set_lpass_clock on pcm_oe_clk failed\n",
+							__func__);
 		goto fail;
 	}
 
@@ -238,9 +304,8 @@
 
 	afe_open(PCM_TX, &dai_data->port_config, dai_data->rate);
 
-	mutex_unlock(&aux_pcm_mutex);
-
 fail:
+	mutex_unlock(&aux_pcm_mutex);
 	return rc;
 }
 
@@ -284,49 +349,6 @@
 	dai->dev->platform_data = auxpcm_pdata;
 	dai->id = dai->dev->id;
 
-	mutex_lock(&aux_pcm_mutex);
-
-	/*
-	 * The clk name for AUX PCM operation is passed as platform
-	 * data to the cpu driver, since cpu drive is unaware of any
-	 * boarc specific configuration.
-	 */
-	if ((!pcm_src_clk) || (!pcm_branch_clk)) {
-		pcm_src_clk = clk_get(dai->dev, auxpcm_pdata->clk);
-
-		if (IS_ERR(pcm_src_clk)) {
-			pr_err("%s: could not get pcm_src_clk\n", __func__);
-			pcm_src_clk = NULL;
-			return -ENODEV;
-		}
-
-		pcm_branch_clk = clk_get(dai->dev, "ibit_clk");
-
-		if (IS_ERR(pcm_branch_clk)) {
-			pr_err("%s: could not get pcm_branch_clk\n", __func__);
-			pcm_branch_clk = NULL;
-			return -ENODEV;
-		}
-	}
-
-	if ((!pcm_oe_src_clk) || (!pcm_oe_branch_clk)) {
-
-		pcm_oe_src_clk = clk_get(dai->dev, "core_oe_src_clk");
-
-		if (IS_ERR(pcm_oe_src_clk)) {
-			pr_err("%s: could not get pcm_oe_src_clk\n", __func__);
-			pcm_oe_src_clk = NULL;
-			return -ENODEV;
-		}
-
-		pcm_oe_branch_clk = clk_get(dai->dev, "core_oe_clk");
-		if (IS_ERR(pcm_oe_branch_clk)) {
-			pr_err("%s: could not get pcm_oe_clk\n", __func__);
-			pcm_oe_branch_clk = NULL;
-			return -ENODEV;
-		}
-	}
-	mutex_unlock(&aux_pcm_mutex);
 
 	dai_data = kzalloc(sizeof(struct msm_dai_q6_dai_data), GFP_KERNEL);
 
@@ -430,14 +452,8 @@
 	int rc = 0;
 
 	if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
-		switch (dai->id) {
-		case VOICE_PLAYBACK_TX:
-			rc = afe_start_pseudo_port(dai->id);
-			break;
-		default:
-			rc = afe_port_start(dai->id, &dai_data->port_config,
+		rc = afe_port_start(dai->id, &dai_data->port_config,
 					dai_data->rate);
-		}
 
 		if (IS_ERR_VALUE(rc))
 			dev_err(dai->dev, "fail to open AFE port %x\n",
@@ -466,6 +482,18 @@
 		return -EINVAL;
 		break;
 	}
+
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S16_LE:
+		dai_data->port_config.i2s.bit_width = 16;
+		break;
+	case SNDRV_PCM_FORMAT_S24_LE:
+		dai_data->port_config.i2s.bit_width = 24;
+		break;
+	default:
+		return -EINVAL;
+	}
+
 	dai_data->rate = params_rate(params);
 	dai_data->port_config.i2s.sample_rate = dai_data->rate;
 	dai_data->port_config.i2s.i2s_cfg_minor_version =
@@ -474,8 +502,6 @@
 	dev_dbg(dai->dev, " channel %d sample rate %d entered\n",
 	dai_data->channels, dai_data->rate);
 
-	/* Q6 only supports 16 as now */
-	dai_data->port_config.i2s.bit_width = 16;
 	dai_data->port_config.i2s.channel_mode = 1;
 	return 0;
 }
@@ -532,10 +558,19 @@
 	dai_data->channels = params_channels(params);
 	dai_data->rate = params_rate(params);
 
-	/* Q6 only supports 16 as now */
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S16_LE:
+		dai_data->port_config.slim_sch.bit_width = 16;
+		break;
+	case SNDRV_PCM_FORMAT_S24_LE:
+		dai_data->port_config.slim_sch.bit_width = 24;
+		break;
+	default:
+		return -EINVAL;
+	}
+
 	dai_data->port_config.slim_sch.sb_cfg_minor_version =
 				AFE_API_VERSION_SLIMBUS_CONFIG;
-	dai_data->port_config.slim_sch.bit_width = 16;
 	dai_data->port_config.slim_sch.data_format = 0;
 	dai_data->port_config.slim_sch.num_channels = dai_data->channels;
 	dai_data->port_config.slim_sch.sample_rate = dai_data->rate;
@@ -656,10 +691,12 @@
 		break;
 	case SLIMBUS_0_RX:
 	case SLIMBUS_1_RX:
+	case SLIMBUS_2_RX:
 	case SLIMBUS_3_RX:
 	case SLIMBUS_4_RX:
 	case SLIMBUS_0_TX:
 	case SLIMBUS_1_TX:
+	case SLIMBUS_2_TX:
 	case SLIMBUS_3_TX:
 	case SLIMBUS_4_TX:
 		rc = msm_dai_q6_slim_bus_hw_params(params, dai,
@@ -678,8 +715,6 @@
 		rc = msm_dai_q6_afe_rtproxy_hw_params(params, dai);
 		break;
 	case VOICE_PLAYBACK_TX:
-		rc = 0;
-		break;
 	case VOICE_RECORD_RX:
 	case VOICE_RECORD_TX:
 		rc = msm_dai_q6_psuedo_port_hw_params(params,
@@ -701,16 +736,9 @@
 	int rc = 0;
 
 	if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
-		switch (dai->id) {
-		case VOICE_PLAYBACK_TX:
-			pr_debug("%s, stop pseudo port:%d\n",
-						__func__,  dai->id);
-			rc = afe_stop_pseudo_port(dai->id);
-			break;
-		default:
-			rc = afe_close(dai->id); /* can block */
-			break;
-		}
+		pr_debug("%s, stop pseudo port:%d\n", __func__,  dai->id);
+		rc = afe_close(dai->id); /* can block */
+
 		if (IS_ERR_VALUE(rc))
 			dev_err(dai->dev, "fail to close AFE port\n");
 		pr_debug("%s: dai_data->status_mask = %ld\n", __func__,
@@ -772,6 +800,7 @@
 	switch (dai->id) {
 	case SLIMBUS_0_RX:
 	case SLIMBUS_1_RX:
+	case SLIMBUS_2_RX:
 	case SLIMBUS_3_RX:
 	case SLIMBUS_4_RX:
 		/*
@@ -785,17 +814,19 @@
 		for (i = 0; i < rx_num; i++) {
 			dai_data->port_config.slim_sch.shared_ch_mapping[i] =
 			    rx_slot[i];
-			pr_err("%s: find number of channels[%d] ch[%d]\n",
+			pr_debug("%s: find number of channels[%d] ch[%d]\n",
 			       __func__, i, rx_slot[i]);
 		}
 		dai_data->port_config.slim_sch.num_channels = rx_num;
-		pr_debug("%s:SLIMBUS_0_RX cnt[%d] ch[%d %d]\n", __func__,
-		rx_num, dai_data->port_config.slim_sch.shared_ch_mapping[0],
-		dai_data->port_config.slim_sch.shared_ch_mapping[1]);
+		pr_debug("%s:SLIMBUS_%d_RX cnt[%d] ch[%d %d]\n", __func__,
+			(dai->id - SLIMBUS_0_RX) / 2, rx_num,
+			dai_data->port_config.slim_sch.shared_ch_mapping[0],
+			dai_data->port_config.slim_sch.shared_ch_mapping[1]);
 
 		break;
 	case SLIMBUS_0_TX:
 	case SLIMBUS_1_TX:
+	case SLIMBUS_2_TX:
 	case SLIMBUS_3_TX:
 	case SLIMBUS_4_TX:
 		/*
@@ -813,10 +844,10 @@
 				 __func__, i, tx_slot[i]);
 		}
 		dai_data->port_config.slim_sch.num_channels = tx_num;
-		pr_debug("%s:SLIMBUS_0_TX cnt[%d] ch[%d %d]\n", __func__,
-			 tx_num,
-			 dai_data->port_config.slim_sch.shared_ch_mapping[0],
-		dai_data->port_config.slim_sch.shared_ch_mapping[1]);
+		pr_debug("%s:SLIMBUS_%d_TX cnt[%d] ch[%d %d]\n", __func__,
+			(dai->id - SLIMBUS_0_TX) / 2, tx_num,
+			dai_data->port_config.slim_sch.shared_ch_mapping[0],
+			dai_data->port_config.slim_sch.shared_ch_mapping[1]);
 		break;
 	default:
 		dev_err(dai->dev, "invalid cpu_dai id %d\n", dai->id);
@@ -860,15 +891,9 @@
 
 	/* If AFE port is still up, close it */
 	if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
-		switch (dai->id) {
-		case VOICE_PLAYBACK_TX:
-			pr_debug("%s, stop pseudo port:%d\n",
-				 __func__,  dai->id);
-			rc = afe_stop_pseudo_port(dai->id);
-			break;
-		default:
-			rc = afe_close(dai->id); /* can block */
-		}
+		pr_debug("%s, stop pseudo port:%d\n", __func__,  dai->id);
+		rc = afe_close(dai->id); /* can block */
+
 		if (IS_ERR_VALUE(rc))
 			dev_err(dai->dev, "fail to close AFE port\n");
 		clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
@@ -883,7 +908,7 @@
 	.playback = {
 		.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
 		SNDRV_PCM_RATE_16000,
-		.formats = SNDRV_PCM_FMTBIT_S16_LE,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
 		.channels_min = 1,
 		.channels_max = 2,
 		.rate_min =     8000,
@@ -912,12 +937,12 @@
 static struct snd_soc_dai_driver msm_dai_q6_slimbus_1_rx_dai = {
 	.playback = {
 		.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
-		SNDRV_PCM_RATE_48000,
-		.formats = SNDRV_PCM_FMTBIT_S16_LE,
+		SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
 		.channels_min = 1,
 		.channels_max = 2,
 		.rate_min = 8000,
-		.rate_max = 48000,
+		.rate_max = 96000,
 	},
 	.ops = &msm_dai_q6_ops,
 	.probe = msm_dai_q6_dai_probe,
@@ -997,6 +1022,21 @@
 	.remove = msm_dai_q6_dai_remove,
 };
 
+static struct snd_soc_dai_driver msm_dai_q6_voice_playback_tx_dai = {
+	.playback = {
+		.rates = SNDRV_PCM_RATE_48000 | 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 =     48000,
+	},
+	.ops = &msm_dai_q6_ops,
+	.probe = msm_dai_q6_dai_probe,
+	.remove = msm_dai_q6_dai_remove,
+};
+
 static struct snd_soc_dai_driver msm_dai_q6_incall_record_dai = {
 	.capture = {
 		.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
@@ -1060,7 +1100,8 @@
 {
 	int rc = 0;
 	struct msm_dai_auxpcm_pdata *auxpcm_pdata = NULL;
-	u32 property_val;
+	struct afe_clk_cfg *clk_cfg = NULL;
+	uint32_t val_array[RATE_MAX_NUM_OF_AUX_PCM_RATES];
 
 	auxpcm_pdata = kzalloc(sizeof(struct msm_dai_auxpcm_pdata),
 				GFP_KERNEL);
@@ -1070,81 +1111,100 @@
 		return -ENOMEM;
 	}
 
-	rc = of_property_read_string(pdev->dev.of_node,
-			"qcom,msm-cpudai-auxpcm-clk",
-			&auxpcm_pdata->clk);
-	if (rc) {
-		dev_err(&pdev->dev, "%s: qcom,msm-cpudai-auxpcm-clk missing in DT node\n",
-			__func__);
-		goto fail_free_plat;
-	}
-	rc = of_property_read_u32(pdev->dev.of_node,
-			"qcom,msm-cpudai-auxpcm-mode", &property_val);
+	rc = of_property_read_u32_array(pdev->dev.of_node,
+			"qcom,msm-cpudai-auxpcm-mode",
+			val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES);
 	if (rc) {
 		dev_err(&pdev->dev, "%s: qcom,msm-cpudai-auxpcm-mode missing in DT node\n",
 			__func__);
 		goto fail_free_plat;
 	}
-	auxpcm_pdata->mode = (u16)property_val;
-	rc = of_property_read_u32(pdev->dev.of_node,
-			"qcom,msm-cpudai-auxpcm-sync", &property_val);
+	auxpcm_pdata->mode_8k.mode = (u16)val_array[RATE_8KHZ];
+	auxpcm_pdata->mode_16k.mode = (u16)val_array[RATE_16KHZ];
+
+	rc = of_property_read_u32_array(pdev->dev.of_node,
+			"qcom,msm-cpudai-auxpcm-sync",
+			val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES);
 	if (rc) {
 		dev_err(&pdev->dev, "%s: qcom,msm-cpudai-auxpcm-sync missing in DT node\n",
 			__func__);
 		goto fail_free_plat;
 	}
-	auxpcm_pdata->sync = (u16)property_val;
-	rc = of_property_read_u32(pdev->dev.of_node,
-			"qcom,msm-cpudai-auxpcm-frame", &property_val);
+	auxpcm_pdata->mode_8k.sync = (u16)val_array[RATE_8KHZ];
+	auxpcm_pdata->mode_16k.sync = (u16)val_array[RATE_16KHZ];
+
+	rc = of_property_read_u32_array(pdev->dev.of_node,
+			"qcom,msm-cpudai-auxpcm-frame",
+			val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES);
+
 	if (rc) {
 		dev_err(&pdev->dev, "%s: qcom,msm-cpudai-auxpcm-frame missing in DT node\n",
 			__func__);
 		goto fail_free_plat;
 	}
-	auxpcm_pdata->frame = (u16)property_val;
-	rc = of_property_read_u32(pdev->dev.of_node,
-			"qcom,msm-cpudai-auxpcm-quant", &property_val);
+	auxpcm_pdata->mode_8k.frame = (u16)val_array[RATE_8KHZ];
+	auxpcm_pdata->mode_16k.frame = (u16)val_array[RATE_16KHZ];
+
+	rc = of_property_read_u32_array(pdev->dev.of_node,
+			"qcom,msm-cpudai-auxpcm-quant",
+			val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES);
 	if (rc) {
 		dev_err(&pdev->dev, "%s: qcom,msm-cpudai-auxpcm-quant missing in DT node\n",
 			__func__);
 		goto fail_free_plat;
 	}
-	auxpcm_pdata->quant = (u16)property_val;
-	rc = of_property_read_u32(pdev->dev.of_node,
-			"qcom,msm-cpudai-auxpcm-slot", &property_val);
+	auxpcm_pdata->mode_8k.quant = (u16)val_array[RATE_8KHZ];
+	auxpcm_pdata->mode_16k.quant = (u16)val_array[RATE_16KHZ];
+
+	rc = of_property_read_u32_array(pdev->dev.of_node,
+			"qcom,msm-cpudai-auxpcm-slot",
+			val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES);
 	if (rc) {
 		dev_err(&pdev->dev, "%s: qcom,msm-cpudai-auxpcm-slot missing in DT node\n",
 			__func__);
 		goto fail_free_plat;
 	}
-	auxpcm_pdata->slot = (u16)property_val;
-	rc = of_property_read_u32(pdev->dev.of_node,
-			"qcom,msm-cpudai-auxpcm-data", &property_val);
+	auxpcm_pdata->mode_8k.slot = (u16)val_array[RATE_8KHZ];
+	auxpcm_pdata->mode_16k.slot = (u16)val_array[RATE_16KHZ];
+
+	rc = of_property_read_u32_array(pdev->dev.of_node,
+			"qcom,msm-cpudai-auxpcm-data",
+			val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES);
 	if (rc) {
 		dev_err(&pdev->dev, "%s: qcom,msm-cpudai-auxpcm-data missing in DT node\n",
 			__func__);
 		goto fail_free_plat;
 	}
-	auxpcm_pdata->data = (u16)property_val;
-	rc = of_property_read_u32(pdev->dev.of_node,
+	auxpcm_pdata->mode_8k.data = (u16)val_array[RATE_8KHZ];
+	auxpcm_pdata->mode_16k.data = (u16)val_array[RATE_16KHZ];
+
+	rc = of_property_read_u32_array(pdev->dev.of_node,
 			"qcom,msm-cpudai-auxpcm-pcm-clk-rate",
-			&auxpcm_pdata->pcm_clk_rate);
-	if (rc) {
-		dev_err(&pdev->dev, "%s: qcom,msm-cpudai-auxpcm-pcm-clk-rate missing in DT node\n",
-			__func__);
+			val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES);
+
+	auxpcm_pdata->mode_8k.pcm_clk_rate = (int)val_array[RATE_8KHZ];
+	auxpcm_pdata->mode_16k.pcm_clk_rate = (int)val_array[RATE_16KHZ];
+
+	clk_cfg = kzalloc(sizeof(struct afe_clk_cfg), GFP_KERNEL);
+	if (clk_cfg == NULL) {
+		pr_err("%s: Failed to allocate memory for clk cfg\n", __func__);
 		goto fail_free_plat;
 	}
+	auxpcm_pdata->clk_cfg = clk_cfg;
+
 	platform_set_drvdata(pdev, auxpcm_pdata);
 
 	rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
 	if (rc) {
 		dev_err(&pdev->dev, "%s: failed to add child nodes, rc=%d\n",
 				__func__, rc);
-		goto fail_free_plat;
+		goto fail_free_plat1;
 	}
 
 	return rc;
 
+fail_free_plat1:
+	kfree(clk_cfg);
 fail_free_plat:
 	kfree(auxpcm_pdata);
 	return rc;
@@ -1159,9 +1219,12 @@
 static int __devexit msm_auxpcm_resource_remove(
 				struct platform_device *pdev)
 {
-	void *auxpcm_pdata;
+	struct msm_dai_auxpcm_pdata *auxpcm_pdata;
+	struct afe_clk_cfg *clk_cfg;
 
 	auxpcm_pdata = dev_get_drvdata(&pdev->dev);
+	clk_cfg = (struct afe_clk_cfg *)auxpcm_pdata->clk_cfg;
+	kfree(clk_cfg);
 	kfree(auxpcm_pdata);
 
 	return 0;
@@ -1201,12 +1264,13 @@
 static struct snd_soc_dai_driver msm_dai_q6_slimbus_rx_dai = {
 	.playback = {
 		.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
-		SNDRV_PCM_RATE_16000,
-		.formats = SNDRV_PCM_FMTBIT_S16_LE,
+		SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
+		SNDRV_PCM_RATE_192000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
 		.channels_min = 1,
 		.channels_max = 8,
 		.rate_min = 8000,
-		.rate_max = 48000,
+		.rate_max = 192000,
 	},
 	.ops = &msm_dai_q6_ops,
 	.probe = msm_dai_q6_dai_probe,
@@ -1216,12 +1280,13 @@
 static struct snd_soc_dai_driver msm_dai_q6_slimbus_tx_dai = {
 	.capture = {
 		.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
-		SNDRV_PCM_RATE_16000,
+		SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
+		SNDRV_PCM_RATE_192000,
 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
 		.channels_min = 1,
 		.channels_max = 8,
 		.rate_min = 8000,
-		.rate_max = 48000,
+		.rate_max = 192000,
 	},
 	.ops = &msm_dai_q6_ops,
 	.probe = msm_dai_q6_dai_probe,
@@ -1259,6 +1324,12 @@
 	SOC_ENUM_EXT("PRI MI2S TX Format", mi2s_config_enum[0],
 		     msm_dai_q6_mi2s_format_get,
 		     msm_dai_q6_mi2s_format_put),
+	SOC_ENUM_EXT("SEC MI2S RX Format", mi2s_config_enum[0],
+		     msm_dai_q6_mi2s_format_get,
+		     msm_dai_q6_mi2s_format_put),
+	SOC_ENUM_EXT("SEC MI2S TX Format", mi2s_config_enum[0],
+		     msm_dai_q6_mi2s_format_get,
+		     msm_dai_q6_mi2s_format_put),
 };
 
 static int msm_dai_q6_dai_mi2s_probe(struct snd_soc_dai *dai)
@@ -1267,26 +1338,37 @@
 			dev_get_drvdata(dai->dev);
 	struct snd_kcontrol *kcontrol = NULL;
 	int rc = 0;
+	const struct snd_kcontrol_new *ctrl = NULL;
 
 	if (mi2s_dai_data->rx_dai.mi2s_dai_data.port_config.i2s.channel_mode) {
-		kcontrol = snd_ctl_new1(&mi2s_config_controls[0],
+		if (!strncmp(dai->name, "msm-dai-q6-mi2s.0", 17))
+			ctrl = &mi2s_config_controls[0];
+		if (!strncmp(dai->name, "msm-dai-q6-mi2s.1", 17))
+			ctrl = &mi2s_config_controls[3];
+		kcontrol = snd_ctl_new1(ctrl,
 					&mi2s_dai_data->rx_dai.mi2s_dai_data);
 		rc = snd_ctl_add(dai->card->snd_card, kcontrol);
 
 		if (IS_ERR_VALUE(rc)) {
-			dev_err(dai->dev, "%s: err add RX fmt ctl\n", __func__);
+			dev_err(dai->dev, "%s: err add RX fmt ctl DAI = %s\n",
+				__func__, dai->name);
 			goto rtn;
 		}
 	}
 	if (mi2s_dai_data->tx_dai.mi2s_dai_data.port_config.i2s.channel_mode) {
+		if (!strncmp(dai->name, "msm-dai-q6-mi2s.0", 17))
+			ctrl = &mi2s_config_controls[2];
+		if (!strncmp(dai->name, "msm-dai-q6-mi2s.1", 17))
+			ctrl = &mi2s_config_controls[4];
 		rc = snd_ctl_add(dai->card->snd_card,
-				snd_ctl_new1(&mi2s_config_controls[2],
+				snd_ctl_new1(ctrl,
 				&mi2s_dai_data->tx_dai.mi2s_dai_data));
 
 		if (IS_ERR_VALUE(rc)) {
 			if (kcontrol)
 				snd_ctl_remove(dai->card->snd_card, kcontrol);
-			dev_err(dai->dev, "%s: err add TX fmt ctl\n", __func__);
+			dev_err(dai->dev, "%s: err add TX fmt ctl DAI = %s\n",
+				__func__, dai->name);
 		}
 	}
 rtn:
@@ -1881,10 +1963,12 @@
 
 	switch (id) {
 	case SLIMBUS_0_RX:
+	case SLIMBUS_2_RX:
 		rc = snd_soc_register_dai(&pdev->dev,
 					  &msm_dai_q6_slimbus_rx_dai);
 		break;
 	case SLIMBUS_0_TX:
+	case SLIMBUS_2_TX:
 		rc = snd_soc_register_dai(&pdev->dev,
 					  &msm_dai_q6_slimbus_tx_dai);
 		break;
@@ -1922,6 +2006,10 @@
 	case RT_PROXY_DAI_002_TX:
 		rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_afe_tx_dai);
 		break;
+	case VOICE_PLAYBACK_TX:
+		rc = snd_soc_register_dai(&pdev->dev,
+					&msm_dai_q6_voice_playback_tx_dai);
+		break;
 	case VOICE_RECORD_RX:
 	case VOICE_RECORD_TX:
 		rc = snd_soc_register_dai(&pdev->dev,
diff --git a/sound/soc/msm/qdsp6v2/msm-dai-stub-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-stub-v2.c
new file mode 100644
index 0000000..7c1bdb6
--- /dev/null
+++ b/sound/soc/msm/qdsp6v2/msm-dai-stub-v2.c
@@ -0,0 +1,115 @@
+/* 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/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+
+static int msm_dai_stub_set_channel_map(struct snd_soc_dai *dai,
+		unsigned int tx_num, unsigned int *tx_slot,
+		unsigned int rx_num, unsigned int *rx_slot)
+{
+	pr_debug("%s:\n", __func__);
+
+	return 0;
+}
+
+static struct snd_soc_dai_ops msm_dai_stub_ops = {
+	.set_channel_map = msm_dai_stub_set_channel_map,
+};
+
+static struct snd_soc_dai_driver msm_dai_stub_dai = {
+	.playback = {
+		.rates = SNDRV_PCM_RATE_48000 | 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 = 48000,
+	},
+	.capture = {
+		.rates = SNDRV_PCM_RATE_48000 | 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 = 48000,
+	},
+	.ops = &msm_dai_stub_ops,
+};
+
+static __devinit int msm_dai_stub_dev_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	dev_dbg(&pdev->dev, "dev name %s\n", dev_name(&pdev->dev));
+
+	if (pdev->dev.of_node)
+			dev_set_name(&pdev->dev, "%s", "msm-dai-stub");
+	pr_debug("%s: dev name %s\n", __func__, dev_name(&pdev->dev));
+
+	rc = snd_soc_register_dai(&pdev->dev, &msm_dai_stub_dai);
+
+	return rc;
+}
+
+static __devexit int msm_dai_stub_dev_remove(struct platform_device *pdev)
+{
+	pr_debug("%s:\n", __func__);
+
+	snd_soc_unregister_dai(&pdev->dev);
+
+	return 0;
+}
+
+static const struct of_device_id msm_dai_stub_dt_match[] = {
+	{.compatible = "qcom,msm-dai-stub"},
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, msm_dai_stub_dt_match);
+
+
+static struct platform_driver msm_dai_stub_driver = {
+	.probe  = msm_dai_stub_dev_probe,
+	.remove = msm_dai_stub_dev_remove,
+	.driver = {
+		.name = "msm-dai-stub",
+		.owner = THIS_MODULE,
+		.of_match_table = msm_dai_stub_dt_match,
+	},
+};
+
+static int __init msm_dai_stub_init(void)
+{
+	pr_debug("%s:\n", __func__);
+
+	return platform_driver_register(&msm_dai_stub_driver);
+}
+module_init(msm_dai_stub_init);
+
+static void __exit msm_dai_stub_exit(void)
+{
+	pr_debug("%s:\n", __func__);
+
+	platform_driver_unregister(&msm_dai_stub_driver);
+}
+module_exit(msm_dai_stub_exit);
+
+/* Module information */
+MODULE_DESCRIPTION("MSM Stub DSP DAI driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/msm/qdsp6v2/msm-multi-ch-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-multi-ch-pcm-q6-v2.c
index cab689d..d0d573c 100644
--- a/sound/soc/msm/qdsp6v2/msm-multi-ch-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-multi-ch-pcm-q6-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -76,10 +76,11 @@
 				SNDRV_PCM_INFO_MMAP_VALID |
 				SNDRV_PCM_INFO_INTERLEAVED |
 				SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
-	.formats =              SNDRV_PCM_FMTBIT_S16_LE,
-	.rates =                SNDRV_PCM_RATE_8000_48000,
+	.formats =              (SNDRV_PCM_FMTBIT_S16_LE |
+				SNDRV_PCM_FMTBIT_S24_LE),
+	.rates =                SNDRV_PCM_RATE_8000_96000,
 	.rate_min =             8000,
-	.rate_max =             48000,
+	.rate_max =             96000,
 	.channels_min =         1,
 	.channels_max =         6,
 	.buffer_bytes_max =     PLAYBACK_NUM_PERIODS * PLAYBACK_PERIOD_SIZE,
@@ -92,7 +93,8 @@
 
 /* Conventional and unconventional sample rate supported */
 static unsigned int supported_sample_rates[] = {
-	8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
+	8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
+	96000
 };
 
 static uint32_t in_frame_info[CAPTURE_NUM_PERIODS][2];
@@ -172,8 +174,7 @@
 				break;
 			}
 			if (prtd->mmap_flag) {
-				pr_debug("%s:writing %d bytes"
-					" of buffer to dsp\n",
+				pr_debug("%s:writing %d bytes of buffer to dsp\n",
 					__func__,
 					prtd->pcm_count);
 				q6asm_write_nolock(prtd->audio_client,
@@ -181,8 +182,7 @@
 					0, 0, NO_TIMESTAMP);
 			} else {
 				while (atomic_read(&prtd->out_needed)) {
-					pr_debug("%s:writing %d bytes"
-						 " of buffer to dsp\n",
+					pr_debug("%s:writing %d bytes of buffer to dsp\n",
 						__func__,
 						prtd->pcm_count);
 					q6asm_write_nolock(prtd->audio_client,
@@ -210,6 +210,7 @@
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct msm_audio *prtd = runtime->private_data;
 	int ret;
+	uint16_t bits_per_sample = 16;
 
 	pr_debug("%s\n", __func__);
 	prtd->pcm_size = snd_pcm_lib_buffer_bytes(substream);
@@ -221,8 +222,19 @@
 	if (prtd->enabled)
 		return 0;
 
-	ret = q6asm_media_format_block_pcm(prtd->audio_client,
-			runtime->rate, runtime->channels);
+	switch (runtime->format) {
+	case SNDRV_PCM_FORMAT_S16_LE:
+		bits_per_sample = 16;
+		break;
+
+	case SNDRV_PCM_FORMAT_S24_LE:
+		bits_per_sample = 24;
+		break;
+	}
+
+	ret = q6asm_media_format_block_pcm_format_support(
+			prtd->audio_client, runtime->rate,
+			runtime->channels, bits_per_sample);
 	if (ret < 0)
 		pr_info("%s: CMD Format block failed\n", __func__);
 
@@ -230,6 +242,7 @@
 
 	prtd->enabled = 1;
 	prtd->cmd_ack = 0;
+	prtd->cmd_interrupt = 0;
 
 	return 0;
 }
@@ -335,6 +348,7 @@
 		kfree(prtd);
 		return -ENOMEM;
 	}
+	prtd->audio_client->perf_mode = false;
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		runtime->hw = msm_pcm_hardware_playback;
 		ret = q6asm_open_write(prtd->audio_client,
@@ -362,6 +376,7 @@
 
 	prtd->session_id = prtd->audio_client->session;
 	msm_pcm_routing_reg_phy_stream(soc_prtd->dai_link->be_id,
+			prtd->audio_client->perf_mode,
 			prtd->session_id, substream->stream);
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -411,8 +426,8 @@
 		rc = q6asm_set_volume(multi_ch_pcm_audio.prtd->audio_client,
 								volume);
 		if (rc < 0) {
-			pr_err("%s: Send Volume command failed"
-				" rc=%d\n", __func__, rc);
+			pr_err("%s: Send Volume command failed rc=%d\n",
+							__func__, rc);
 		}
 	}
 	multi_ch_pcm_audio.volume = volume;
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
index 1aa12e3..91bb09b 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -33,8 +33,8 @@
 #include <mach/msm_subsystem_map.h>
 #include "msm-pcm-afe-v2.h"
 
-#define MIN_PERIOD_SIZE (128 * 2 * 8)
-#define MAX_PERIOD_SIZE (128 * 2 * 2 * 6 * 8)
+#define MIN_PERIOD_SIZE (128 * 2)
+#define MAX_PERIOD_SIZE (128 * 2 * 2 * 6)
 #define MAX_NUM_PERIODS 384
 #define MIN_NUM_PERIODS 32
 static struct snd_pcm_hardware msm_afe_hardware = {
@@ -42,15 +42,16 @@
 				SNDRV_PCM_INFO_BLOCK_TRANSFER |
 				SNDRV_PCM_INFO_MMAP_VALID |
 				SNDRV_PCM_INFO_INTERLEAVED),
-	.formats =              SNDRV_PCM_FMTBIT_S16_LE,
+	.formats =              SNDRV_PCM_FMTBIT_S16_LE |
+				SNDRV_PCM_FMTBIT_S24_LE,
 	.rates =                (SNDRV_PCM_RATE_8000 |
 				SNDRV_PCM_RATE_16000 |
 				SNDRV_PCM_RATE_48000),
 	.rate_min =             8000,
 	.rate_max =             48000,
 	.channels_min =         1,
-	.channels_max =         8,
-	.buffer_bytes_max =     MAX_PERIOD_SIZE * 32,
+	.channels_max =         6,
+	.buffer_bytes_max =     MAX_PERIOD_SIZE * MIN_NUM_PERIODS,
 	.period_bytes_min =     MIN_PERIOD_SIZE,
 	.period_bytes_max =     MAX_PERIOD_SIZE,
 	.periods_min =          MIN_NUM_PERIODS,
@@ -68,7 +69,7 @@
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	u32 mem_map_handle = 0;
 
-	mem_map_handle = afe_req_mmap_handle();
+	mem_map_handle = afe_req_mmap_handle(prtd->audio_client);
 	if (!mem_map_handle)
 		pr_err("%s: mem_map_handle is NULL\n", __func__);
 
@@ -99,7 +100,7 @@
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	u32 mem_map_handle = 0;
 
-	mem_map_handle = afe_req_mmap_handle();
+	mem_map_handle = afe_req_mmap_handle(prtd->audio_client);
 	if (!mem_map_handle)
 		pr_err("%s: mem_map_handle is NULL\n", __func__);
 
@@ -332,8 +333,8 @@
 	prtd->audio_client = q6afe_audio_client_alloc(prtd);
 	if (!prtd->audio_client) {
 		pr_debug("%s: Could not allocate memory\n", __func__);
-		kfree(prtd);
 		mutex_unlock(&prtd->lock);
+		kfree(prtd);
 		return -ENOMEM;
 	}
 
@@ -355,17 +356,6 @@
 	if (ret < 0)
 		pr_err("snd_pcm_hw_constraint_integer failed\n");
 
-	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
-		ret = snd_pcm_hw_constraint_minmax(runtime,
-			SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
-			MAX_NUM_PERIODS * MIN_PERIOD_SIZE,
-			MIN_NUM_PERIODS * MAX_PERIOD_SIZE);
-		if (ret < 0) {
-			pr_err("constraint for buffer bytes min max ret = %d\n",
-									ret);
-		}
-	}
-
 	return 0;
 }
 
@@ -405,7 +395,7 @@
 	}
 	hrtimer_cancel(&prtd->hrt);
 
-	rc = afe_cmd_memory_unmap(afe_req_mmap_handle());
+	rc = afe_cmd_memory_unmap(afe_req_mmap_handle(prtd->audio_client));
 	if (rc < 0)
 		pr_err("AFE memory unmap failed\n");
 
@@ -510,8 +500,8 @@
 		dir = OUT;
 	rc = q6afe_audio_client_buf_alloc_contiguous(dir,
 			prtd->audio_client,
-			(params_buffer_bytes(params) / params_periods(params)),
-			params_periods(params));
+			runtime->hw.period_bytes_min,
+			runtime->hw.periods_max);
 	if (rc < 0) {
 		pr_err("Audio Start: Buffer Allocation failed rc = %d\n", rc);
 		mutex_unlock(&prtd->lock);
@@ -530,21 +520,21 @@
 	dma_buf->private_data = NULL;
 	dma_buf->area = buf[0].data;
 	dma_buf->addr = buf[0].phys;
-	dma_buf->bytes = params_buffer_bytes(params);
+	dma_buf->bytes = runtime->hw.buffer_bytes_max;
 	if (!dma_buf->area) {
 		pr_err("%s:MSM AFE physical memory allocation failed\n",
 							__func__);
 		mutex_unlock(&prtd->lock);
 		return -ENOMEM;
 	}
-	memset(dma_buf->area, 0, params_buffer_bytes(params));
+	memset(dma_buf->area, 0, runtime->hw.buffer_bytes_max);
 	prtd->dma_addr = (u32) dma_buf->addr;
 
 	mutex_unlock(&prtd->lock);
 
 	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
 
-	rc = afe_cmd_memory_map(dma_buf->addr, dma_buf->bytes);
+	rc = afe_memory_map(dma_buf->addr, dma_buf->bytes, prtd->audio_client);
 	if (rc < 0)
 		pr_err("fail to map memory to DSP\n");
 
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.h
index 446409f..facc941 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-dtmf-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-dtmf-v2.c
new file mode 100644
index 0000000..3fdde7f
--- /dev/null
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-dtmf-v2.c
@@ -0,0 +1,598 @@
+/* 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/module.h>
+#include <linux/time.h>
+#include <linux/wait.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <sound/core.h>
+#include <sound/soc.h>
+#include <sound/pcm.h>
+#include <sound/q6afe-v2.h>
+
+#include "msm-pcm-q6-v2.h"
+#include "msm-pcm-routing-v2.h"
+#include "q6voice.h"
+
+enum {
+	DTMF_IN_RX,
+	DTMF_IN_TX,
+};
+
+enum format {
+	FORMAT_S16_LE = 2
+};
+
+struct dtmf_det_info {
+	char     session[MAX_SESSION_NAME_LEN];
+	uint8_t  dir;
+	uint16_t high_freq;
+	uint16_t low_freq;
+};
+
+struct dtmf_buf_node {
+	struct list_head list;
+	struct dtmf_det_info dtmf_det_pkt;
+};
+
+enum dtmf_state {
+	DTMF_GEN_RX_STOPPED,
+	DTMF_GEN_RX_STARTED,
+};
+
+#define DTMF_MAX_Q_LEN 10
+#define DTMF_PKT_SIZE sizeof(struct dtmf_det_info)
+
+struct dtmf_drv_info {
+	enum  dtmf_state state;
+	struct snd_pcm_substream *capture_substream;
+
+	struct list_head out_queue;
+	struct list_head free_out_queue;
+
+	wait_queue_head_t out_wait;
+
+	struct mutex lock;
+	spinlock_t dsp_lock;
+
+	uint8_t capture_start;
+	uint8_t capture_instance;
+
+	unsigned int pcm_capture_size;
+	unsigned int pcm_capture_count;
+	unsigned int pcm_capture_irq_pos;
+	unsigned int pcm_capture_buf_pos;
+};
+
+static struct snd_pcm_hardware msm_pcm_hardware = {
+	.info =                 (SNDRV_PCM_INFO_MMAP |
+				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
+				 SNDRV_PCM_INFO_MMAP_VALID |
+				 SNDRV_PCM_INFO_INTERLEAVED),
+	.formats =              SNDRV_PCM_FMTBIT_S16_LE,
+	.channels_min =         1,
+	.channels_max =         1,
+	.buffer_bytes_max =	(sizeof(struct dtmf_buf_node) * DTMF_MAX_Q_LEN),
+	.period_bytes_min =	DTMF_PKT_SIZE,
+	.period_bytes_max =	DTMF_PKT_SIZE,
+	.periods_min =		DTMF_MAX_Q_LEN,
+	.periods_max =		DTMF_MAX_Q_LEN,
+	.fifo_size =            0,
+};
+
+static int msm_dtmf_rx_generate_put(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_value *ucontrol)
+{
+	uint16_t low_freq = ucontrol->value.integer.value[0];
+	uint16_t high_freq = ucontrol->value.integer.value[1];
+	int64_t duration = ucontrol->value.integer.value[2];
+	uint16_t gain = ucontrol->value.integer.value[3];
+
+	pr_debug("%s: low_freq=%d high_freq=%d duration=%d gain=%d\n",
+		 __func__, low_freq, high_freq, (int)duration, gain);
+	afe_dtmf_generate_rx(duration, high_freq, low_freq, gain);
+	return 0;
+}
+
+static int msm_dtmf_rx_generate_get(struct  snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_value *ucontrol)
+{
+	pr_debug("%s:\n", __func__);
+	ucontrol->value.integer.value[0] = 0;
+	return 0;
+}
+
+static int msm_dtmf_detect_voice_rx_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	int enable = ucontrol->value.integer.value[0];
+
+	pr_debug("%s: enable=%d\n", __func__, enable);
+	voc_enable_dtmf_rx_detection(voc_get_session_id(VOICE_SESSION_NAME),
+				     enable);
+
+	return 0;
+}
+
+static int msm_dtmf_detect_voice_rx_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	ucontrol->value.integer.value[0] = 0;
+	return 0;
+}
+
+static int msm_dtmf_detect_volte_rx_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	int enable = ucontrol->value.integer.value[0];
+
+	pr_debug("%s: enable=%d\n", __func__, enable);
+	voc_enable_dtmf_rx_detection(voc_get_session_id(VOLTE_SESSION_NAME),
+				     enable);
+
+	return 0;
+}
+
+static int msm_dtmf_detect_volte_rx_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	ucontrol->value.integer.value[0] = 0;
+	return 0;
+}
+
+static struct snd_kcontrol_new msm_dtmf_controls[] = {
+	SOC_SINGLE_MULTI_EXT("DTMF_Generate Rx Low High Duration Gain",
+			     SND_SOC_NOPM, 0, 5000, 0, 4,
+			     msm_dtmf_rx_generate_get,
+			     msm_dtmf_rx_generate_put),
+	SOC_SINGLE_EXT("DTMF_Detect Rx Voice enable", SND_SOC_NOPM, 0, 1, 0,
+				msm_dtmf_detect_voice_rx_get,
+				msm_dtmf_detect_voice_rx_put),
+	SOC_SINGLE_EXT("DTMF_Detect Rx VoLTE enable", SND_SOC_NOPM, 0, 1, 0,
+				msm_dtmf_detect_volte_rx_get,
+				msm_dtmf_detect_volte_rx_put),
+};
+
+static int msm_pcm_dtmf_probe(struct snd_soc_platform *platform)
+{
+	snd_soc_add_platform_controls(platform, msm_dtmf_controls,
+				      ARRAY_SIZE(msm_dtmf_controls));
+	return 0;
+}
+
+static void dtmf_rx_detected_cb(uint8_t *pkt,
+				char *session,
+				void *private_data)
+{
+	struct dtmf_buf_node *buf_node = NULL;
+	struct vss_istream_evt_rx_dtmf_detected *dtmf_det_pkt =
+		(struct vss_istream_evt_rx_dtmf_detected *)pkt;
+	struct dtmf_drv_info *prtd = private_data;
+	unsigned long dsp_flags;
+
+	pr_debug("%s\n", __func__);
+	if (prtd->capture_substream == NULL)
+		return;
+
+	/* Copy dtmf detected info into out_queue. */
+	spin_lock_irqsave(&prtd->dsp_lock, dsp_flags);
+	/* discarding dtmf detection info till start is received */
+	if (!list_empty(&prtd->free_out_queue) && prtd->capture_start) {
+		buf_node = list_first_entry(&prtd->free_out_queue,
+					    struct dtmf_buf_node, list);
+		list_del(&buf_node->list);
+		buf_node->dtmf_det_pkt.high_freq = dtmf_det_pkt->high_freq;
+		buf_node->dtmf_det_pkt.low_freq = dtmf_det_pkt->low_freq;
+		if (session != NULL)
+			strlcpy(buf_node->dtmf_det_pkt.session,
+				session, MAX_SESSION_NAME_LEN);
+
+		buf_node->dtmf_det_pkt.dir = DTMF_IN_RX;
+		pr_debug("high =%d, low=%d session=%s\n",
+			 buf_node->dtmf_det_pkt.high_freq,
+			 buf_node->dtmf_det_pkt.low_freq,
+			 buf_node->dtmf_det_pkt.session);
+		list_add_tail(&buf_node->list, &prtd->out_queue);
+		prtd->pcm_capture_irq_pos += prtd->pcm_capture_count;
+		spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags);
+		snd_pcm_period_elapsed(prtd->capture_substream);
+	} else {
+		spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags);
+		pr_err("DTMF detection pkt in Rx  dropped, no free node available\n");
+	}
+
+	wake_up(&prtd->out_wait);
+}
+
+static int msm_pcm_capture_copy(struct snd_pcm_substream *substream,
+				int channel, snd_pcm_uframes_t hwoff,
+				void __user *buf, snd_pcm_uframes_t frames)
+{
+	int ret = 0;
+	int count = 0;
+	struct dtmf_buf_node *buf_node = NULL;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct dtmf_drv_info *prtd = runtime->private_data;
+	unsigned long dsp_flags;
+
+	count = frames_to_bytes(runtime, frames);
+
+	ret = wait_event_interruptible_timeout(prtd->out_wait,
+				(!list_empty(&prtd->out_queue)),
+				1 * HZ);
+
+	if (ret > 0) {
+		if (count <= DTMF_PKT_SIZE) {
+			spin_lock_irqsave(&prtd->dsp_lock, dsp_flags);
+			buf_node = list_first_entry(&prtd->out_queue,
+					struct dtmf_buf_node, list);
+			list_del(&buf_node->list);
+			spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags);
+			ret = copy_to_user(buf,
+					   &buf_node->dtmf_det_pkt,
+					   count);
+			if (ret) {
+				pr_err("%s: Copy to user retuned %d\n",
+					__func__, ret);
+				ret = -EFAULT;
+			}
+			spin_lock_irqsave(&prtd->dsp_lock, dsp_flags);
+			list_add_tail(&buf_node->list,
+				      &prtd->free_out_queue);
+			spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags);
+
+		} else {
+			pr_err("%s: Read count %d > DTMF_PKT_SIZE\n",
+				__func__, count);
+			ret = -ENOMEM;
+		}
+	} else if (ret == 0) {
+		pr_err("%s: No UL data available\n", __func__);
+		ret = -ETIMEDOUT;
+	} else {
+		pr_err("%s: Read was interrupted\n", __func__);
+		ret = -ERESTARTSYS;
+	}
+	return ret;
+}
+
+static int msm_pcm_copy(struct snd_pcm_substream *substream, int a,
+	 snd_pcm_uframes_t hwoff, void __user *buf, snd_pcm_uframes_t frames)
+{
+	int ret = 0;
+	pr_debug("%s() DTMF\n", __func__);
+
+	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+		ret = msm_pcm_capture_copy(substream, a, hwoff, buf, frames);
+
+	return ret;
+}
+
+static int msm_pcm_open(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct dtmf_drv_info *prtd = NULL;
+	int ret = 0;
+
+	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+		prtd = kzalloc(sizeof(struct dtmf_drv_info), GFP_KERNEL);
+
+		if (prtd == NULL) {
+			pr_err("Failed to allocate memory for msm_audio\n");
+			ret = -ENOMEM;
+			goto done;
+		}
+
+		mutex_init(&prtd->lock);
+		spin_lock_init(&prtd->dsp_lock);
+		init_waitqueue_head(&prtd->out_wait);
+		INIT_LIST_HEAD(&prtd->out_queue);
+		INIT_LIST_HEAD(&prtd->free_out_queue);
+
+		runtime->hw = msm_pcm_hardware;
+
+		ret = snd_pcm_hw_constraint_integer(runtime,
+						    SNDRV_PCM_HW_PARAM_PERIODS);
+		if (ret < 0)
+			pr_info("snd_pcm_hw_constraint_integer failed\n");
+
+		prtd->capture_substream = substream;
+		prtd->capture_instance++;
+		runtime->private_data = prtd;
+	}
+
+done:
+	return ret;
+}
+
+static int msm_pcm_close(struct snd_pcm_substream *substream)
+{
+	int ret = 0;
+	struct list_head *ptr = NULL;
+	struct list_head *next = NULL;
+	struct dtmf_buf_node *buf_node = NULL;
+	struct snd_dma_buffer *c_dma_buf;
+	struct snd_pcm_substream *c_substream;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct dtmf_drv_info *prtd = runtime->private_data;
+	unsigned long dsp_flags;
+
+	pr_debug("%s() DTMF\n", __func__);
+
+	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+		mutex_lock(&prtd->lock);
+		wake_up(&prtd->out_wait);
+
+		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+			prtd->capture_instance--;
+
+		if (!prtd->capture_instance) {
+			if (prtd->state == DTMF_GEN_RX_STARTED) {
+				prtd->state = DTMF_GEN_RX_STOPPED;
+				voc_disable_dtmf_det_on_active_sessions();
+				voc_register_dtmf_rx_detection_cb(NULL, NULL);
+			}
+			/* release all buffer */
+			/* release out_queue and free_out_queue */
+			pr_debug("release all buffer\n");
+			c_substream = prtd->capture_substream;
+			if (c_substream == NULL) {
+				pr_debug("c_substream is NULL\n");
+				mutex_unlock(&prtd->lock);
+				return -EINVAL;
+			}
+
+			c_dma_buf = &c_substream->dma_buffer;
+			if (c_dma_buf == NULL) {
+				pr_debug("c_dma_buf is NULL.\n");
+				mutex_unlock(&prtd->lock);
+				return -EINVAL;
+			}
+
+			if (c_dma_buf->area != NULL) {
+				spin_lock_irqsave(&prtd->dsp_lock, dsp_flags);
+				list_for_each_safe(ptr, next,
+							&prtd->out_queue) {
+					buf_node = list_entry(ptr,
+						   struct dtmf_buf_node, list);
+					list_del(&buf_node->list);
+				}
+
+				list_for_each_safe(ptr, next,
+						   &prtd->free_out_queue) {
+					buf_node = list_entry(ptr,
+						   struct dtmf_buf_node, list);
+					list_del(&buf_node->list);
+				}
+
+				spin_unlock_irqrestore(&prtd->dsp_lock,
+						       dsp_flags);
+				dma_free_coherent(c_substream->pcm->card->dev,
+						  runtime->hw.buffer_bytes_max,
+						  c_dma_buf->area,
+						  c_dma_buf->addr);
+				c_dma_buf->area = NULL;
+			}
+		}
+		prtd->capture_substream = NULL;
+		mutex_unlock(&prtd->lock);
+	}
+
+	return ret;
+}
+
+static int msm_pcm_hw_params(struct snd_pcm_substream *substream,
+			     struct snd_pcm_hw_params *params)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct dtmf_drv_info *prtd = runtime->private_data;
+	struct snd_dma_buffer *dma_buf = &substream->dma_buffer;
+	struct dtmf_buf_node *buf_node = NULL;
+	int i = 0, offset = 0;
+	int ret = 0;
+
+	pr_debug("%s: DTMF\n", __func__);
+	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+		mutex_lock(&prtd->lock);
+		dma_buf->dev.type = SNDRV_DMA_TYPE_DEV;
+		dma_buf->dev.dev = substream->pcm->card->dev;
+		dma_buf->private_data = NULL;
+
+		dma_buf->area = dma_alloc_coherent(substream->pcm->card->dev,
+						runtime->hw.buffer_bytes_max,
+						&dma_buf->addr, GFP_KERNEL);
+		if (!dma_buf->area) {
+			pr_err("%s:MSM DTMF dma_alloc failed\n", __func__);
+			mutex_unlock(&prtd->lock);
+			return -ENOMEM;
+		}
+
+		dma_buf->bytes = runtime->hw.buffer_bytes_max;
+		memset(dma_buf->area, 0, runtime->hw.buffer_bytes_max);
+
+		for (i = 0; i < DTMF_MAX_Q_LEN; i++) {
+			pr_debug("node =%d\n", i);
+			buf_node = (void *) dma_buf->area + offset;
+			list_add_tail(&buf_node->list,
+				      &prtd->free_out_queue);
+			offset = offset + sizeof(struct dtmf_buf_node);
+		}
+
+		snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+		mutex_unlock(&prtd->lock);
+	}
+
+	return ret;
+}
+
+static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct dtmf_drv_info *prtd = runtime->private_data;
+
+	pr_debug("%s: DTMF\n", __func__);
+	prtd->pcm_capture_size  = snd_pcm_lib_buffer_bytes(substream);
+	prtd->pcm_capture_count = snd_pcm_lib_period_bytes(substream);
+	prtd->pcm_capture_irq_pos = 0;
+	prtd->pcm_capture_buf_pos = 0;
+	return 0;
+}
+
+static int msm_pcm_prepare(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct dtmf_drv_info *prtd = runtime->private_data;
+
+	pr_debug("%s: DTMF\n", __func__);
+
+	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+		mutex_lock(&prtd->lock);
+
+		msm_pcm_capture_prepare(substream);
+
+		if (runtime->format != FORMAT_S16_LE) {
+			pr_err("format:%u doesnt match %d\n",
+			       (uint32_t)runtime->format, FORMAT_S16_LE);
+			mutex_unlock(&prtd->lock);
+			return -EINVAL;
+		}
+
+		if (prtd->capture_instance &&
+			(prtd->state != DTMF_GEN_RX_STARTED)) {
+			voc_register_dtmf_rx_detection_cb(dtmf_rx_detected_cb,
+							  prtd);
+			prtd->state = DTMF_GEN_RX_STARTED;
+		}
+		mutex_unlock(&prtd->lock);
+	}
+
+	return 0;
+}
+
+static int msm_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+	int ret = 0;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct dtmf_drv_info *prtd = runtime->private_data;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+		pr_debug("%s: Trigger start\n", __func__);
+		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+			prtd->capture_start = 1;
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		pr_debug("SNDRV_PCM_TRIGGER_STOP\n");
+		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+			prtd->capture_start = 0;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static snd_pcm_uframes_t msm_pcm_pointer(struct snd_pcm_substream *substream)
+{
+	snd_pcm_uframes_t ret = 0;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct dtmf_drv_info *prtd = runtime->private_data;
+
+	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+		if (prtd->pcm_capture_irq_pos >= prtd->pcm_capture_size)
+			prtd->pcm_capture_irq_pos = 0;
+		ret = bytes_to_frames(runtime, (prtd->pcm_capture_irq_pos));
+	}
+
+	return ret;
+}
+
+static struct snd_pcm_ops msm_pcm_ops = {
+	.open           = msm_pcm_open,
+	.copy		= msm_pcm_copy,
+	.hw_params	= msm_pcm_hw_params,
+	.close          = msm_pcm_close,
+	.prepare        = msm_pcm_prepare,
+	.trigger        = msm_pcm_trigger,
+	.pointer        = msm_pcm_pointer,
+};
+
+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);
+	return ret;
+}
+
+static struct snd_soc_platform_driver msm_soc_platform = {
+	.ops		= &msm_pcm_ops,
+	.pcm_new	= msm_asoc_pcm_new,
+	.probe		= msm_pcm_dtmf_probe,
+};
+
+static __devinit int msm_pcm_probe(struct platform_device *pdev)
+{
+	if (pdev->dev.of_node)
+			dev_set_name(&pdev->dev, "%s", "msm-pcm-dtmf");
+	pr_debug("%s: dev name %s\n", __func__, dev_name(&pdev->dev));
+
+	return snd_soc_register_platform(&pdev->dev,
+					 &msm_soc_platform);
+}
+
+static int msm_pcm_remove(struct platform_device *pdev)
+{
+	snd_soc_unregister_platform(&pdev->dev);
+	return 0;
+}
+
+static const struct of_device_id msm_pcm_dtmf_dt_match[] = {
+	{.compatible = "qcom,msm-pcm-dtmf"},
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, msm_pcm_dtmf_dt_match);
+
+
+static struct platform_driver msm_pcm_driver = {
+	.driver = {
+		.name = "msm-pcm-dtmf",
+		.owner = THIS_MODULE,
+		.of_match_table = msm_pcm_dtmf_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("DTMF platform driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c
index 2f0a9d7..3a4a674 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -52,7 +52,8 @@
 				SNDRV_PCM_INFO_MMAP_VALID |
 				SNDRV_PCM_INFO_INTERLEAVED |
 				SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
-	.formats =              SNDRV_PCM_FMTBIT_S16_LE,
+	.formats =              SNDRV_PCM_FMTBIT_S16_LE |
+					SNDRV_PCM_FMTBIT_S24_LE,
 	.rates =                SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT,
 	.rate_min =             8000,
 	.rate_max =             48000,
@@ -196,6 +197,7 @@
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct msm_audio *prtd = runtime->private_data;
 	int ret;
+	uint16_t bits_per_sample = 16;
 
 	pr_debug("%s\n", __func__);
 	prtd->pcm_size = snd_pcm_lib_buffer_bytes(substream);
@@ -208,14 +210,27 @@
 	if (prtd->enabled)
 		return 0;
 
-	ret = q6asm_media_format_block_pcm(prtd->audio_client, runtime->rate,
-				runtime->channels);
+	switch (runtime->format) {
+	case SNDRV_PCM_FORMAT_S16_LE:
+		bits_per_sample = 16;
+		break;
+
+	case SNDRV_PCM_FORMAT_S24_LE:
+		bits_per_sample = 24;
+		break;
+	}
+
+	ret = q6asm_media_format_block_pcm_format_support(
+				prtd->audio_client, runtime->rate,
+				runtime->channels, bits_per_sample);
 	if (ret < 0)
 		pr_debug("%s: CMD Format block failed\n", __func__);
 
 	atomic_set(&prtd->out_count, runtime->periods);
 	prtd->enabled = 1;
 	prtd->cmd_ack = 0;
+	prtd->cmd_interrupt = 0;
+
 	return 0;
 }
 
@@ -291,6 +306,7 @@
 		kfree(prtd);
 		return -ENOMEM;
 	}
+	prtd->audio_client->perf_mode = false;
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		ret = q6asm_open_write(prtd->audio_client, FORMAT_LINEAR_PCM);
 		if (ret < 0) {
@@ -313,6 +329,7 @@
 	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,
+		prtd->audio_client->perf_mode,
 		prtd->session_id, substream->stream);
 
 	ret = snd_pcm_hw_constraint_list(runtime, 0,
@@ -349,7 +366,9 @@
 {
 	int rc = 0;
 	if (lpa_audio.prtd && lpa_audio.prtd->audio_client) {
-		rc = q6asm_set_volume(lpa_audio.prtd->audio_client, volume);
+		rc = q6asm_set_lrgain(lpa_audio.prtd->audio_client,
+						(volume >> 16) & 0xFFFF,
+						volume & 0xFFFF);
 		if (rc < 0) {
 			pr_err("%s: Send Volume command failed rc=%d\n",
 					__func__, rc);
@@ -515,10 +534,10 @@
 		pr_debug("SNDRV_COMPRESS_TSTAMP\n");
 
 		memset(&tstamp, 0x0, sizeof(struct snd_compr_tstamp));
-		timestamp = q6asm_get_session_time(prtd->audio_client);
-		if (timestamp < 0) {
-			pr_err("%s: Get Session Time return value =%lld\n",
-				__func__, timestamp);
+		rc = q6asm_get_session_time(prtd->audio_client, &timestamp);
+		if (rc < 0) {
+			pr_err("%s: Fail to get session time stamp, rc:%d\n",
+							__func__, rc);
 			return -EAGAIN;
 		}
 		temp = (timestamp * 2 * runtime->channels);
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
index 1d6e106..e05e58d 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -29,6 +29,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/android_pmem.h>
 #include <linux/of_device.h>
+#include <sound/pcm_params.h>
 
 #include "msm-pcm-q6-v2.h"
 #include "msm-pcm-routing-v2.h"
@@ -40,11 +41,18 @@
 	struct snd_pcm *pcm;
 };
 
+struct snd_msm_volume {
+	struct msm_audio *prtd;
+	unsigned volume;
+};
+static struct snd_msm_volume pcm_audio = {NULL, 0x2000};
+
 #define PLAYBACK_NUM_PERIODS	8
 #define PLAYBACK_MAX_PERIOD_SIZE    12288
-#define PLAYBACK_MIN_PERIOD_SIZE    2048
+#define PLAYBACK_MIN_PERIOD_SIZE    1024
 #define CAPTURE_NUM_PERIODS	16
-#define CAPTURE_PERIOD_SIZE	512
+#define CAPTURE_MAX_PERIOD_SIZE 4096
+#define CAPTURE_MIN_PERIOD_SIZE 512
 
 static struct snd_pcm_hardware msm_pcm_hardware_capture = {
 	.info =                 (SNDRV_PCM_INFO_MMAP |
@@ -58,9 +66,9 @@
 	.rate_max =             48000,
 	.channels_min =         1,
 	.channels_max =         4,
-	.buffer_bytes_max =     CAPTURE_NUM_PERIODS * CAPTURE_PERIOD_SIZE,
-	.period_bytes_min =	CAPTURE_PERIOD_SIZE,
-	.period_bytes_max =     CAPTURE_PERIOD_SIZE,
+	.buffer_bytes_max =     CAPTURE_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE,
+	.period_bytes_min =	CAPTURE_MIN_PERIOD_SIZE,
+	.period_bytes_max =     CAPTURE_MAX_PERIOD_SIZE,
 	.periods_min =          CAPTURE_NUM_PERIODS,
 	.periods_max =          CAPTURE_NUM_PERIODS,
 	.fifo_size =            0,
@@ -72,10 +80,11 @@
 				SNDRV_PCM_INFO_MMAP_VALID |
 				SNDRV_PCM_INFO_INTERLEAVED |
 				SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
-	.formats =              SNDRV_PCM_FMTBIT_S16_LE,
-	.rates =                SNDRV_PCM_RATE_8000_48000,
+	.formats =              (SNDRV_PCM_FMTBIT_S16_LE |
+				SNDRV_PCM_FMTBIT_S24_LE),
+	.rates =                SNDRV_PCM_RATE_8000_96000,
 	.rate_min =             8000,
-	.rate_max =             48000,
+	.rate_max =             96000,
 	.channels_min =         1,
 	.channels_max =         8,
 	.buffer_bytes_max =     PLAYBACK_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE,
@@ -88,7 +97,8 @@
 
 /* Conventional and unconventional sample rate supported */
 static unsigned int supported_sample_rates[] = {
-	8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
+	8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
+	96000
 };
 
 static uint32_t in_frame_info[CAPTURE_NUM_PERIODS][2];
@@ -202,6 +212,7 @@
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct msm_audio *prtd = runtime->private_data;
 	int ret;
+	uint16_t bits_per_sample = 16;
 
 	pr_debug("%s\n", __func__);
 	prtd->pcm_size = snd_pcm_lib_buffer_bytes(substream);
@@ -213,8 +224,19 @@
 	if (prtd->enabled)
 		return 0;
 
-	ret = q6asm_media_format_block_pcm(prtd->audio_client, runtime->rate,
-				runtime->channels);
+	switch (runtime->format) {
+	case SNDRV_PCM_FORMAT_S16_LE:
+		bits_per_sample = 16;
+		break;
+	case SNDRV_PCM_FORMAT_S24_LE:
+		bits_per_sample = 24;
+		break;
+	}
+
+	ret = q6asm_media_format_block_multi_ch_pcm_v2(
+			prtd->audio_client, runtime->rate,
+			runtime->channels, !prtd->set_channel_map,
+			prtd->channel_map, bits_per_sample);
 	if (ret < 0)
 		pr_info("%s: CMD Format block failed\n", __func__);
 
@@ -222,6 +244,7 @@
 
 	prtd->enabled = 1;
 	prtd->cmd_ack = 0;
+	prtd->cmd_interrupt = 0;
 
 	return 0;
 }
@@ -298,11 +321,9 @@
 static int msm_pcm_open(struct snd_pcm_substream *substream)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
 	struct msm_audio *prtd;
 	int ret = 0;
 
-	pr_debug("%s\n", __func__);
 	prtd = kzalloc(sizeof(struct msm_audio), GFP_KERNEL);
 	if (prtd == NULL) {
 		pr_err("Failed to allocate memory for msm_audio\n");
@@ -316,24 +337,10 @@
 		kfree(prtd);
 		return -ENOMEM;
 	}
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 		runtime->hw = msm_pcm_hardware_playback;
-		ret = q6asm_open_write(prtd->audio_client, FORMAT_LINEAR_PCM);
-		if (ret < 0) {
-			pr_err("%s: pcm out open failed\n", __func__);
-			q6asm_audio_client_free(prtd->audio_client);
-			kfree(prtd);
-			return -ENOMEM;
-		}
 
-		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,
-			prtd->session_id, substream->stream);
-		prtd->cmd_ack = 1;
-
-	}
 	/* Capture path */
 	else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
 		runtime->hw = msm_pcm_hardware_capture;
@@ -364,8 +371,21 @@
 		}
 	}
 
+	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+		ret = snd_pcm_hw_constraint_minmax(runtime,
+			SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
+			CAPTURE_NUM_PERIODS * CAPTURE_MIN_PERIOD_SIZE,
+			CAPTURE_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE);
+		if (ret < 0) {
+			pr_err("constraint for buffer bytes min max ret = %d\n",
+									ret);
+		}
+	}
+
 	prtd->dsp_cnt = 0;
+	prtd->set_channel_map = false;
 	runtime->private_data = prtd;
+	pcm_audio.prtd = prtd;
 
 	return 0;
 }
@@ -449,7 +469,8 @@
 				prtd->audio_client);
 
 	msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->be_id,
-	SNDRV_PCM_STREAM_PLAYBACK);
+						SNDRV_PCM_STREAM_PLAYBACK);
+	pcm_audio.prtd = NULL;
 	q6asm_audio_client_free(prtd->audio_client);
 	kfree(prtd);
 	return 0;
@@ -630,11 +651,49 @@
 	struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
 	struct audio_buffer *buf;
 	int dir, ret;
+	struct msm_plat_data *pdata;
+	uint16_t bits_per_sample = 16;
+
+	pdata = (struct msm_plat_data *)
+				dev_get_drvdata(soc_prtd->platform->dev);
+	if (!pdata) {
+		pr_err("%s: platform data not populated\n", __func__);
+		return -EINVAL;
+	}
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 		dir = IN;
-	else {
+	else
 		dir = OUT;
+
+	prtd->audio_client->perf_mode = pdata->perf_mode;
+	pr_debug("%s: perf: %x\n", __func__, pdata->perf_mode);
+	/* Playback Path */
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+		if (params_format(params) == SNDRV_PCM_FORMAT_S24_LE)
+			bits_per_sample = 24;
+
+		ret = q6asm_open_write_v2(prtd->audio_client,
+				FORMAT_LINEAR_PCM, bits_per_sample);
+		if (ret < 0) {
+			pr_err("%s: q6asm_open_write_v2 failed\n", __func__);
+			q6asm_audio_client_free(prtd->audio_client);
+			kfree(prtd);
+			return -ENOMEM;
+		}
+
+		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,
+				prtd->audio_client->perf_mode,
+				prtd->session_id, substream->stream);
+		prtd->cmd_ack = 1;
+	}
+
+	/* Capture Path */
+	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+
 		pr_debug("%s Opening %d-ch PCM read stream\n",
 			__func__, params_channels(params));
 		ret = q6asm_open_read(prtd->audio_client, FORMAT_LINEAR_PCM);
@@ -644,14 +703,15 @@
 			prtd->audio_client = NULL;
 			return -ENOMEM;
 		}
+
+		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,
+				prtd->audio_client->perf_mode,
+				prtd->session_id, substream->stream);
 	}
 
-	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,
-			prtd->session_id, substream->stream);
-
-
 	ret = q6asm_audio_client_buf_alloc_contiguous(dir,
 			prtd->audio_client,
 			(params_buffer_bytes(params) / params_periods(params)),
@@ -691,13 +751,49 @@
 	.mmap		= msm_pcm_mmap,
 };
 
+static int pcm_chmap_ctl_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	int i;
+	char channel_mapping[PCM_FORMAT_MAX_NUM_CHANNEL];
+
+	pr_debug("%s", __func__);
+	for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++)
+		channel_mapping[i] = (char)(ucontrol->value.integer.value[i]);
+	if (pcm_audio.prtd) {
+		pcm_audio.prtd->set_channel_map = true;
+		memcpy(pcm_audio.prtd->channel_map, channel_mapping,
+			PCM_FORMAT_MAX_NUM_CHANNEL);
+	}
+	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;
+	struct snd_pcm *pcm = rtd->pcm->streams[0].pcm;
+	struct snd_pcm_chmap *chmap_info;
+	struct snd_kcontrol *kctl;
+	char device_num[3];
+	int i, ret = 0;
 
 	if (!card->dev->coherent_dma_mask)
 		card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
+
+	pr_debug("%s, Channel map cntrl add\n", __func__);
+	ret = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+					NULL, PCM_FORMAT_MAX_NUM_CHANNEL, 0,
+					&chmap_info);
+	if (ret < 0)
+		return ret;
+	kctl = chmap_info->kctl;
+	for (i = 0; i < kctl->count; i++)
+		kctl->vd[i].access |= SNDRV_CTL_ELEM_ACCESS_WRITE;
+	snprintf(device_num, sizeof(device_num), "%d", pcm->device);
+	strlcat(kctl->id.name, device_num, sizeof(kctl->id.name));
+	pr_debug("%s, Overwriting channel map control name to: %s",
+		__func__, kctl->id.name);
+	kctl->put = pcm_chmap_ctl_put;
 	return ret;
 }
 
@@ -708,16 +804,46 @@
 
 static __devinit int msm_pcm_probe(struct platform_device *pdev)
 {
-	if (pdev->dev.of_node)
-		dev_set_name(&pdev->dev, "%s", "msm-pcm-dsp");
+	int rc;
+	int id;
+	struct msm_plat_data *pdata;
 
-	pr_info("%s: dev name %s\n", __func__, dev_name(&pdev->dev));
+	rc = of_property_read_u32(pdev->dev.of_node,
+				"qcom,msm-pcm-dsp-id", &id);
+	if (rc) {
+		dev_err(&pdev->dev, "%s: qcom,msm-pcm-dsp-id missing in DT node\n",
+					__func__);
+		return rc;
+	}
+
+	pdata = kzalloc(sizeof(struct msm_plat_data), GFP_KERNEL);
+	if (!pdata) {
+		dev_err(&pdev->dev, "Failed to allocate memory for platform data\n");
+		return -ENOMEM;
+	}
+
+	if (of_property_read_bool(pdev->dev.of_node,
+				"qcom,msm-pcm-low-latency"))
+		pdata->perf_mode = 1;
+	else
+		pdata->perf_mode = 0;
+
+	dev_set_drvdata(&pdev->dev, pdata);
+
+	dev_set_name(&pdev->dev, "%s.%d", "msm-pcm-dsp", id);
+
+	dev_dbg(&pdev->dev, "%s: dev name %s\n",
+				__func__, dev_name(&pdev->dev));
 	return snd_soc_register_platform(&pdev->dev,
 				   &msm_soc_platform);
 }
 
 static int msm_pcm_remove(struct platform_device *pdev)
 {
+	struct msm_plat_data *pdata;
+
+	pdata = dev_get_drvdata(&pdev->dev);
+	kfree(pdata);
 	snd_soc_unregister_platform(&pdev->dev);
 	return 0;
 }
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h
index e25d356..4b3cfe7 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -82,6 +82,9 @@
 	int periods;
 	int mmap_flag;
 	atomic_t pending_buffer;
+	bool set_channel_map;
+	char channel_map[8];
+	int cmd_interrupt;
 };
 
 struct output_meta_data_st {
@@ -92,4 +95,8 @@
 	uint32_t reserved[12];
 };
 
+struct msm_plat_data {
+	int perf_mode;
+};
+
 #endif /*_MSM_PCM_H*/
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 58300c4..02c3457 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -29,6 +29,8 @@
 #include <sound/q6asm-v2.h>
 #include <sound/q6afe-v2.h>
 #include <sound/tlv.h>
+#include <sound/asound.h>
+#include <sound/pcm_params.h>
 
 #include "msm-pcm-routing-v2.h"
 #include "q6voice.h"
@@ -40,6 +42,8 @@
 	unsigned long port_sessions; /* track Tx BE ports -> Rx BE */
 	unsigned int  sample_rate;
 	unsigned int  channel;
+	unsigned int  format;
+	bool perf_mode;
 };
 
 #define INVALID_SESSION -1
@@ -54,14 +58,14 @@
 
 #define INT_RX_VOL_MAX_STEPS 0x2000
 #define INT_RX_VOL_GAIN 0x2000
-
+#define INT_RX_LR_VOL_MAX_STEPS 0x20002000
 static int msm_route_fm_vol_control;
 static const DECLARE_TLV_DB_LINEAR(fm_rx_vol_gain, 0,
 			INT_RX_VOL_MAX_STEPS);
 
 static int msm_route_lpa_vol_control;
 static const DECLARE_TLV_DB_LINEAR(lpa_rx_vol_gain, 0,
-			INT_RX_VOL_MAX_STEPS);
+			INT_RX_LR_VOL_MAX_STEPS);
 
 static int msm_route_multimedia2_vol_control;
 static const DECLARE_TLV_DB_LINEAR(multimedia2_rx_vol_gain, 0,
@@ -69,8 +73,11 @@
 
 static int msm_route_compressed_vol_control;
 static const DECLARE_TLV_DB_LINEAR(compressed_rx_vol_gain, 0,
-			INT_RX_VOL_MAX_STEPS);
+			INT_RX_LR_VOL_MAX_STEPS);
 
+static int msm_route_multimedia5_vol_control;
+static const DECLARE_TLV_DB_LINEAR(multimedia5_rx_vol_gain, 0,
+			INT_RX_VOL_MAX_STEPS);
 
 
 /* Equal to Frontend after last of the MULTIMEDIA SESSIONS */
@@ -188,6 +195,13 @@
 	{ SLIMBUS_EXTPROC_RX, 0, 0, 0, 0, 0},
 	{ AFE_PORT_ID_QUATERNARY_MI2S_RX, 0, 0, 0, 0, 0},
 	{ AFE_PORT_ID_QUATERNARY_MI2S_TX, 0, 0, 0, 0, 0},
+	{ AFE_PORT_ID_SECONDARY_MI2S_RX,  0, 0, 0, 0, 0},
+	{ AFE_PORT_ID_SECONDARY_MI2S_TX,  0, 0, 0, 0, 0},
+	{ AFE_PORT_ID_PRIMARY_MI2S_RX,    0, 0, 0, 0, 0},
+	{ AFE_PORT_ID_PRIMARY_MI2S_TX,    0, 0, 0, 0, 0},
+	{ AFE_PORT_ID_TERTIARY_MI2S_RX,   0, 0, 0, 0, 0},
+	{ AFE_PORT_ID_TERTIARY_MI2S_TX,   0, 0, 0, 0, 0},
+	{ AUDIO_PORT_ID_I2S_RX,           0, 0, 0, 0, 0},
 };
 
 
@@ -201,6 +215,8 @@
 	{INVALID_SESSION, INVALID_SESSION},
 	/* MULTIMEDIA4 */
 	{INVALID_SESSION, INVALID_SESSION},
+	/* MULTIMEDIA5 */
+	{INVALID_SESSION, INVALID_SESSION},
 };
 
 static uint8_t is_be_dai_extproc(int be_dai)
@@ -276,11 +292,13 @@
 	mutex_unlock(&routing_lock);
 }
 
-void msm_pcm_routing_reg_phy_stream(int fedai_id, int dspst_id, int stream_type)
+void msm_pcm_routing_reg_phy_stream(int fedai_id, bool perf_mode,
+					int dspst_id, int stream_type)
 {
 	int i, session_type, path_type, port_type;
 	struct route_payload payload;
 	u32 channels;
+	uint16_t bits_per_sample = 16;
 
 	if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
 		/* bad ID assigned in machine driver */
@@ -306,6 +324,8 @@
 	if (eq_data[fedai_id].enable)
 		msm_send_eq_values(fedai_id);
 	for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
+		if (test_bit(fedai_id, &msm_bedais[i].fe_sessions))
+			msm_bedais[i].perf_mode = perf_mode;
 		if (!is_be_dai_extproc(i) &&
 		   (afe_get_port_type(msm_bedais[i].port_id) == port_type) &&
 		   (msm_bedais[i].active) &&
@@ -313,19 +333,27 @@
 
 			channels = msm_bedais[i].channel;
 
+			if (msm_bedais[i].format == SNDRV_PCM_FORMAT_S16_LE)
+				bits_per_sample = 16;
+			else if (msm_bedais[i].format ==
+						SNDRV_PCM_FORMAT_S24_LE)
+				bits_per_sample = 24;
+
 			if ((stream_type == SNDRV_PCM_STREAM_PLAYBACK) &&
-				(channels > 2))
+				(channels > 0))
 				adm_multi_ch_copp_open(msm_bedais[i].port_id,
 				path_type,
 				msm_bedais[i].sample_rate,
 				msm_bedais[i].channel,
-				DEFAULT_COPP_TOPOLOGY);
+				DEFAULT_COPP_TOPOLOGY, msm_bedais[i].perf_mode,
+				bits_per_sample);
 			else
 				adm_open(msm_bedais[i].port_id,
 				path_type,
 				msm_bedais[i].sample_rate,
 				msm_bedais[i].channel,
-				DEFAULT_COPP_TOPOLOGY);
+				DEFAULT_COPP_TOPOLOGY, false,
+				bits_per_sample);
 
 			payload.copp_ids[payload.num_copps++] =
 				msm_bedais[i].port_id;
@@ -394,6 +422,7 @@
 {
 	int session_type, path_type;
 	u32 channels;
+	uint16_t bits_per_sample = 16;
 
 	pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
 
@@ -418,24 +447,28 @@
 		if (!test_bit(val, &msm_bedais[reg].fe_sessions) &&
 			(msm_bedais[reg].port_id == VOICE_PLAYBACK_TX))
 			voc_start_playback(set);
-
 		set_bit(val, &msm_bedais[reg].fe_sessions);
 		if (msm_bedais[reg].active && fe_dai_map[val][session_type] !=
 			INVALID_SESSION) {
 
 			channels = msm_bedais[reg].channel;
+			if (msm_bedais[reg].format == SNDRV_PCM_FORMAT_S24_LE)
+				bits_per_sample = 24;
 
-			if ((session_type == SESSION_TYPE_RX) && (channels > 2))
+			if ((session_type == SESSION_TYPE_RX) &&
+				(channels > 0)) {
 				adm_multi_ch_copp_open(msm_bedais[reg].port_id,
 				path_type,
 				msm_bedais[reg].sample_rate,
 				channels,
-				DEFAULT_COPP_TOPOLOGY);
-			else
+				DEFAULT_COPP_TOPOLOGY,
+				msm_bedais[reg].perf_mode,
+				bits_per_sample);
+			} else
 				adm_open(msm_bedais[reg].port_id,
 				path_type,
 				msm_bedais[reg].sample_rate, channels,
-				DEFAULT_COPP_TOPOLOGY);
+				DEFAULT_COPP_TOPOLOGY, false, bits_per_sample);
 
 			msm_pcm_routing_build_matrix(val,
 				fe_dai_map[val][session_type], path_type);
@@ -523,6 +556,13 @@
 	else
 		clear_bit(val, &msm_bedais[reg].fe_sessions);
 
+	if (val == MSM_FRONTEND_DAI_DTMF_RX &&
+	    afe_get_port_type(msm_bedais[reg].port_id) ==
+						MSM_AFE_PORT_TYPE_RX) {
+		pr_debug("%s(): set=%d port id=0x%x for dtmf generation\n",
+			 __func__, set, msm_bedais[reg].port_id);
+		afe_set_dtmf_gen_rx_portid(msm_bedais[reg].port_id, set);
+	}
 	mutex_unlock(&routing_lock);
 
 	if (afe_get_port_type(msm_bedais[reg].port_id) ==
@@ -774,6 +814,25 @@
 	return 0;
 }
 
+static int msm_routing_get_multimedia5_vol_mixer(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+
+	ucontrol->value.integer.value[0] = msm_route_multimedia5_vol_control;
+	return 0;
+}
+
+static int msm_routing_set_multimedia5_vol_mixer(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+
+	if (!multi_ch_pcm_set_volume(ucontrol->value.integer.value[0]))
+		msm_route_multimedia5_vol_control =
+			ucontrol->value.integer.value[0];
+
+	return 0;
+}
+
 static int msm_routing_set_multimedia2_vol_mixer(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
@@ -803,6 +862,31 @@
 	return 0;
 }
 
+static int msm_routing_get_channel_map_mixer(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL];
+	int i;
+
+	adm_get_multi_ch_map(channel_map);
+	for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++)
+		ucontrol->value.integer.value[i] = (unsigned) channel_map[i];
+	return 0;
+}
+
+static int msm_routing_put_channel_map_mixer(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL];
+	int i;
+
+	for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++)
+		channel_map[i] = (char)(ucontrol->value.integer.value[i]);
+	adm_set_multi_ch_map(channel_map);
+
+	return 0;
+}
+
 static int msm_routing_get_srs_trumedia_control(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
@@ -1044,6 +1128,9 @@
 	SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_I2S_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_PRI_I2S_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new sec_i2s_rx_mixer_controls[] = {
@@ -1059,6 +1146,9 @@
 	SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SEC_I2S_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SEC_I2S_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = {
@@ -1074,6 +1164,9 @@
 	SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SLIMBUS_0_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SLIMBUS_0_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new mi2s_rx_mixer_controls[] = {
@@ -1089,6 +1182,9 @@
 	SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_MI2S_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_MI2S_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new quaternary_mi2s_rx_mixer_controls[] = {
@@ -1106,6 +1202,36 @@
 	msm_routing_put_audio_mixer),
 };
 
+static const struct snd_kcontrol_new secondary_mi2s_rx_mixer_controls[] = {
+	SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SECONDARY_MI2S_RX ,
+	MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new primary_mi2s_rx_mixer_controls[] = {
+	SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_MI2S_RX ,
+	MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_PRI_MI2S_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_MI2S_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_MI2S_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+};
+
 static const struct snd_kcontrol_new hdmi_mixer_controls[] = {
 	SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_HDMI_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
@@ -1119,6 +1245,9 @@
 	SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_HDMI_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_HDMI_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 	/* incall music delivery mixer */
 static const struct snd_kcontrol_new incall_music_delivery_mixer_controls[] = {
@@ -1152,6 +1281,9 @@
 	SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_BT_SCO_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_INT_BT_SCO_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new int_fm_rx_mixer_controls[] = {
@@ -1167,6 +1299,9 @@
 	SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_FM_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_INT_FM_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = {
@@ -1182,6 +1317,9 @@
 	SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AFE_PCM_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_AFE_PCM_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = {
@@ -1197,6 +1335,9 @@
 	SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AUXPCM_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_AUXPCM_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new mmul1_mixer_controls[] = {
@@ -1209,6 +1350,9 @@
 	SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
 		MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
 		msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_TX,
+		MSM_FRONTEND_DAI_MULTIMEDIA1, 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_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
 		msm_routing_put_audio_mixer),
@@ -1247,6 +1391,27 @@
 	msm_routing_put_audio_mixer),
 };
 
+static const struct snd_kcontrol_new mmul5_mixer_controls[] = {
+	SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("AUX_PCM_TX", MSM_BACKEND_DAI_AUXPCM_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 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,
@@ -1257,6 +1422,9 @@
 	SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_PRI_I2S_RX,
 	MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
+	SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_PRI_I2S_RX,
+	MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer,
+	msm_routing_put_voice_mixer),
 };
 
 static const struct snd_kcontrol_new sec_i2s_rx_voice_mixer_controls[] = {
@@ -1269,6 +1437,9 @@
 	SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_SEC_I2S_RX,
 	MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
+	SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SEC_I2S_RX,
+	MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer,
+	msm_routing_put_voice_mixer),
 };
 
 static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = {
@@ -1281,6 +1452,9 @@
 	SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
 	MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
+	SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
+	MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer,
+	msm_routing_put_voice_mixer),
 };
 
 static const struct snd_kcontrol_new bt_sco_rx_voice_mixer_controls[] = {
@@ -1296,6 +1470,9 @@
 	SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_INT_BT_SCO_RX ,
 	MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
+	SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_INT_BT_SCO_RX ,
+	MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer,
+	msm_routing_put_voice_mixer),
 };
 
 static const struct snd_kcontrol_new mi2s_rx_voice_mixer_controls[] = {
@@ -1308,6 +1485,12 @@
 	SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_MI2S_RX,
 	MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
 	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_MI2S_RX,
+	MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
+	msm_routing_put_voice_mixer),
+	SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_MI2S_RX,
+	MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer,
+	msm_routing_put_voice_mixer),
 };
 
 static const struct snd_kcontrol_new afe_pcm_rx_voice_mixer_controls[] = {
@@ -1323,6 +1506,9 @@
 	SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_AFE_PCM_RX,
 	MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
+	SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_AFE_PCM_RX,
+	MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer,
+	msm_routing_put_voice_mixer),
 };
 
 static const struct snd_kcontrol_new aux_pcm_rx_voice_mixer_controls[] = {
@@ -1338,6 +1524,9 @@
 	SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_AUXPCM_RX,
 	MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
+	SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_AUXPCM_RX,
+	MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer,
+	msm_routing_put_voice_mixer),
 };
 
 static const struct snd_kcontrol_new hdmi_rx_voice_mixer_controls[] = {
@@ -1353,6 +1542,9 @@
 	SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_HDMI_RX,
 	MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
 	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_HDMI_RX,
+	MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer,
+	msm_routing_put_voice_mixer),
 };
 
 static const struct snd_kcontrol_new stub_rx_mixer_controls[] = {
@@ -1410,6 +1602,9 @@
 	SOC_SINGLE_EXT("AUX_PCM_TX_VoLTE", MSM_BACKEND_DAI_AUXPCM_TX,
 	MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
+	SOC_SINGLE_EXT("MI2S_TX_VoLTE", MSM_BACKEND_DAI_MI2S_TX,
+	MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
+	msm_routing_put_voice_mixer),
 };
 
 static const struct snd_kcontrol_new tx_voip_mixer_controls[] = {
@@ -1523,6 +1718,12 @@
 	msm_routing_put_port_mixer),
 };
 
+static const struct snd_kcontrol_new primary_mi2s_rx_port_mixer_controls[] = {
+	SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_RX,
+	MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer,
+	msm_routing_put_port_mixer),
+};
+
 static const struct snd_kcontrol_new fm_switch_mixer_controls =
 	SOC_SINGLE_EXT("Switch", SND_SOC_NOPM,
 	0, 1, 0, msm_routing_get_switch_mixer,
@@ -1551,12 +1752,24 @@
 	msm_routing_set_multimedia2_vol_mixer, multimedia2_rx_vol_gain),
 };
 
+static const struct snd_kcontrol_new multimedia5_vol_mixer_controls[] = {
+	SOC_SINGLE_EXT_TLV("HIFI3 RX Volume", SND_SOC_NOPM, 0,
+	INT_RX_VOL_GAIN, 0, msm_routing_get_multimedia5_vol_mixer,
+	msm_routing_set_multimedia5_vol_mixer, multimedia5_rx_vol_gain),
+};
+
 static const struct snd_kcontrol_new compressed_vol_mixer_controls[] = {
 	SOC_SINGLE_EXT_TLV("COMPRESSED RX Volume", SND_SOC_NOPM, 0,
 	INT_RX_VOL_GAIN, 0, msm_routing_get_compressed_vol_mixer,
 	msm_routing_set_compressed_vol_mixer, compressed_rx_vol_gain),
 };
 
+static const struct snd_kcontrol_new multi_ch_channel_map_mixer_controls[] = {
+	SOC_SINGLE_MULTI_EXT("Playback Channel Map", SND_SOC_NOPM, 0, 16,
+	0, 8, msm_routing_get_channel_map_mixer,
+	msm_routing_put_channel_map_mixer),
+};
+
 static const struct snd_kcontrol_new lpa_SRS_trumedia_controls[] = {
 	{.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "SRS TruMedia",
@@ -1800,9 +2013,11 @@
 	SND_SOC_DAPM_AIF_IN("MM_DL2", "MultiMedia2 Playback", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("MM_DL3", "MultiMedia3 Playback", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("MM_DL4", "MultiMedia4 Playback", 0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_IN("MM_DL5", "MultiMedia5 Playback", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("VOIP_DL", "VoIP Playback", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("MM_UL5", "MultiMedia5 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),
 	SND_SOC_DAPM_AIF_IN("VoLTE_DL", "VoLTE Playback", 0, 0, 0, 0),
@@ -1840,7 +2055,8 @@
 
 	SND_SOC_DAPM_AIF_OUT("MI2S_DL_HL", "MI2S_RX_HOSTLESS Playback",
 		0, 0, 0, 0),
-
+	SND_SOC_DAPM_AIF_IN("DTMF_DL_HL", "DTMF_RX_HOSTLESS Playback",
+		0, 0, 0, 0),
 	/* Backend AIF */
 	/* Stream name equals to backend dai link stream name
 	*/
@@ -1852,11 +2068,16 @@
 	SND_SOC_DAPM_AIF_OUT("MI2S_RX", "MI2S Playback", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_RX", "Quaternary MI2S Playback",
 						0, 0, 0, 0),
-
+	SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX", "Secondary MI2S Playback",
+			     0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("PRI_MI2S_RX", "Primary MI2S Playback",
+			     0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("PRI_I2S_TX", "Primary I2S Capture", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("MI2S_TX", "MI2S Capture", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("QUAT_MI2S_TX", "Quaternary MI2S Capture",
 						0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_IN("SEC_MI2S_TX", "Secondary MI2S Capture",
+			    0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("SLIMBUS_0_TX", "Slimbus Capture", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("INT_BT_SCO_RX", "Internal BT-SCO Playback",
 				0, 0, 0 , 0),
@@ -1919,10 +2140,18 @@
 	SND_SOC_DAPM_MIXER("QUAT_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
 				quaternary_mi2s_rx_mixer_controls,
 				ARRAY_SIZE(quaternary_mi2s_rx_mixer_controls)),
+	SND_SOC_DAPM_MIXER("SEC_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
+			   secondary_mi2s_rx_mixer_controls,
+			   ARRAY_SIZE(secondary_mi2s_rx_mixer_controls)),
+	SND_SOC_DAPM_MIXER("PRI_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
+			   primary_mi2s_rx_mixer_controls,
+			   ARRAY_SIZE(primary_mi2s_rx_mixer_controls)),
 	SND_SOC_DAPM_MIXER("MultiMedia1 Mixer", SND_SOC_NOPM, 0, 0,
 	mmul1_mixer_controls, ARRAY_SIZE(mmul1_mixer_controls)),
 	SND_SOC_DAPM_MIXER("MultiMedia2 Mixer", SND_SOC_NOPM, 0, 0,
 	mmul2_mixer_controls, ARRAY_SIZE(mmul2_mixer_controls)),
+	SND_SOC_DAPM_MIXER("MultiMedia5 Mixer", SND_SOC_NOPM, 0, 0,
+	mmul5_mixer_controls, ARRAY_SIZE(mmul5_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)),
 	/* incall */
@@ -2013,7 +2242,9 @@
 	ARRAY_SIZE(sbus_3_rx_port_mixer_controls)),
 	SND_SOC_DAPM_MIXER("MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0,
 	mi2s_rx_port_mixer_controls, ARRAY_SIZE(mi2s_rx_port_mixer_controls)),
-
+	SND_SOC_DAPM_MIXER("PRI_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0,
+	primary_mi2s_rx_port_mixer_controls,
+	ARRAY_SIZE(primary_mi2s_rx_port_mixer_controls)),
 	/* Virtual Pins to force backends ON atm */
 	SND_SOC_DAPM_OUTPUT("BE_OUT"),
 	SND_SOC_DAPM_INPUT("BE_IN"),
@@ -2025,24 +2256,28 @@
 	{"PRI_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"PRI_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
 	{"PRI_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+	{"PRI_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
 	{"PRI_I2S_RX", NULL, "PRI_RX Audio Mixer"},
 
 	{"SEC_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"SEC_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"SEC_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
 	{"SEC_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+	{"SEC_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
 	{"SEC_I2S_RX", NULL, "SEC_RX Audio Mixer"},
 
 	{"SLIMBUS_0_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"SLIMBUS_0_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"SLIMBUS_0_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
 	{"SLIMBUS_0_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+	{"SLIMBUS_0_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
 	{"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Audio Mixer"},
 
 	{"HDMI Mixer", "MultiMedia1", "MM_DL1"},
 	{"HDMI Mixer", "MultiMedia2", "MM_DL2"},
 	{"HDMI Mixer", "MultiMedia3", "MM_DL3"},
 	{"HDMI Mixer", "MultiMedia4", "MM_DL4"},
+	{"HDMI Mixer", "MultiMedia5", "MM_DL5"},
 	{"HDMI", NULL, "HDMI Mixer"},
 
 		/* incall */
@@ -2056,10 +2291,12 @@
 	{"MultiMedia1 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"},
 	{"MultiMedia1 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"},
 	{"MultiMedia1 Mixer", "SLIM_4_TX", "SLIMBUS_4_TX"},
+	{"MultiMedia5 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
 	{"MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
 	{"MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+	{"MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
 	{"MI2S_RX", NULL, "MI2S_RX Audio Mixer"},
 
 	{"QUAT_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -2068,82 +2305,124 @@
 	{"QUAT_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
 	{"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX Audio Mixer"},
 
+
+	{"SEC_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
+	{"SEC_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
+	{"SEC_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
+	{"SEC_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+	{"SEC_MI2S_RX", NULL, "SEC_MI2S_RX Audio Mixer"},
+
+	{"PRI_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
+	{"PRI_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
+	{"PRI_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
+	{"PRI_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+	{"PRI_MI2S_RX", NULL, "PRI_MI2S_RX Audio Mixer"},
+
 	{"MultiMedia1 Mixer", "PRI_TX", "PRI_I2S_TX"},
 	{"MultiMedia1 Mixer", "MI2S_TX", "MI2S_TX"},
 	{"MultiMedia2 Mixer", "MI2S_TX", "MI2S_TX"},
 	{"MultiMedia1 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
 	{"MultiMedia1 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
 	{"MultiMedia1 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
+	{"MultiMedia5 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"},
 	{"MultiMedia2 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
+	{"MultiMedia1 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"},
 
 	{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
 	{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+	{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
 	{"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX Audio Mixer"},
 
 	{"INTERNAL_FM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"INTERNAL_FM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"INTERNAL_FM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
 	{"INTERNAL_FM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+	{"INTERNAL_FM_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
 	{"INT_FM_RX", NULL, "INTERNAL_FM_RX Audio Mixer"},
 
 	{"AFE_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"AFE_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"AFE_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
 	{"AFE_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+	{"AFE_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
 	{"PCM_RX", NULL, "AFE_PCM_RX Audio Mixer"},
 
 	{"MultiMedia1 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
+	{"MultiMedia5 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
 	{"MultiMedia1 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
+	{"MultiMedia5 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
 
 	{"MultiMedia1 Mixer", "AFE_PCM_TX", "PCM_TX"},
+	{"MultiMedia5 Mixer", "AFE_PCM_TX", "PCM_TX"},
 	{"MM_UL1", NULL, "MultiMedia1 Mixer"},
 	{"MultiMedia2 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
 	{"MM_UL2", NULL, "MultiMedia2 Mixer"},
+	{"MM_UL5", NULL, "MultiMedia5 Mixer"},
 
 	{"AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
 	{"AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+	{"AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
 	{"AUX_PCM_RX", NULL, "AUX_PCM_RX Audio Mixer"},
 
+	{"MI2S_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
+	{"MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"},
+	{"MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
+	{"MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"},
+	{"MI2S_RX", NULL, "MI2S_RX_Voice Mixer"},
+
 	{"PRI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
 	{"PRI_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
 	{"PRI_RX_Voice Mixer", "Voip", "VOIP_DL"},
+	{"PRI_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"},
 	{"PRI_I2S_RX", NULL, "PRI_RX_Voice Mixer"},
 
 	{"SEC_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
 	{"SEC_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
 	{"SEC_RX_Voice Mixer", "Voip", "VOIP_DL"},
+	{"SEC_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"},
 	{"SEC_I2S_RX", NULL, "SEC_RX_Voice Mixer"},
 
 	{"SLIM_0_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
 	{"SLIM_0_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
 	{"SLIM_0_RX_Voice Mixer", "Voip", "VOIP_DL"},
+	{"SLIM_0_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"},
 	{"SLIMBUS_0_RX", NULL, "SLIM_0_RX_Voice Mixer"},
 
 	{"INTERNAL_BT_SCO_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
 	{"INTERNAL_BT_SCO_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
 	{"INTERNAL_BT_SCO_RX_Voice Mixer", "Voip", "VOIP_DL"},
+	{"INTERNAL_BT_SCO_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"},
 	{"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX_Voice Mixer"},
 
 	{"AFE_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
 	{"AFE_PCM_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
 	{"AFE_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
+	{"AFE_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"},
 	{"PCM_RX", NULL, "AFE_PCM_RX_Voice Mixer"},
 
 	{"AUX_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
 	{"AUX_PCM_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
 	{"AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
+	{"AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"},
 	{"AUX_PCM_RX", NULL, "AUX_PCM_RX_Voice Mixer"},
 
 	{"HDMI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
 	{"HDMI_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
 	{"HDMI_RX_Voice Mixer", "Voip", "VOIP_DL"},
+	{"HDMI_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"},
 	{"HDMI", NULL, "HDMI_RX_Voice Mixer"},
 	{"HDMI", NULL, "HDMI_DL_HL"},
 
+	{"MI2S_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
+	{"MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"},
+	{"MI2S_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
+	{"MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
+	{"MI2S_RX", NULL, "MI2S_RX_Voice Mixer"},
+
 	{"Voice_Tx Mixer", "PRI_TX_Voice", "PRI_I2S_TX"},
 	{"Voice_Tx Mixer", "MI2S_TX_Voice", "MI2S_TX"},
 	{"Voice_Tx Mixer", "SLIM_0_TX_Voice", "SLIMBUS_0_TX"},
@@ -2156,6 +2435,7 @@
 	{"VoLTE_Tx Mixer", "INTERNAL_BT_SCO_TX_VoLTE", "INT_BT_SCO_TX"},
 	{"VoLTE_Tx Mixer", "AFE_PCM_TX_VoLTE", "PCM_TX"},
 	{"VoLTE_Tx Mixer", "AUX_PCM_TX_VoLTE", "AUX_PCM_TX"},
+	{"VoLTE_Tx Mixer", "MI2S_TX_VoLTE", "MI2S_TX"},
 	{"VoLTE_UL", NULL, "VoLTE_Tx Mixer"},
 	{"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"},
 	{"Voip_Tx Mixer", "MI2S_TX_Voip", "MI2S_TX"},
@@ -2211,12 +2491,6 @@
 	{"SLIMBUS_1_RX Mixer", "Voice Stub", "VOICE_STUB_DL"},
 	{"SLIMBUS_1_RX", NULL, "SLIMBUS_1_RX Mixer"},
 	{"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
-	{"MI2S_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
-	{"MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"},
-	{"MI2S_RX", NULL, "MI2S_RX_Voice Mixer"},
-	{"MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
-	{"MI2S_RX", NULL, "MI2S_RX_Voice Mixer"},
-
 	{"SLIMBUS_3_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
 	{"SLIMBUS_3_RX", NULL, "SLIMBUS_3_RX_Voice Mixer"},
 
@@ -2238,6 +2512,10 @@
 	{"MI2S_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"},
 	{"MI2S_RX Port Mixer", "MI2S_TX", "MI2S_TX"},
 	{"MI2S_RX", NULL, "MI2S_RX Port Mixer"},
+
+	{"PRI_MI2S_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"},
+	{"PRI_MI2S_RX", NULL, "PRI_MI2S_RX Port Mixer"},
+
 	/* Backend Enablement */
 
 	{"BE_OUT", NULL, "PRI_I2S_RX"},
@@ -2249,10 +2527,18 @@
 	{"BE_OUT", NULL, "HDMI"},
 	{"BE_OUT", NULL, "MI2S_RX"},
 	{"BE_OUT", NULL, "QUAT_MI2S_RX"},
+	{"BE_OUT", NULL, "SEC_MI2S_RX"},
+	{"BE_OUT", NULL, "PRI_MI2S_RX"},
+	{"BE_OUT", NULL, "INT_BT_SCO_RX"},
+	{"BE_OUT", NULL, "INT_FM_RX"},
+	{"BE_OUT", NULL, "PCM_RX"},
+	{"BE_OUT", NULL, "SLIMBUS_3_RX"},
+	{"BE_OUT", NULL, "AUX_PCM_RX"},
 
 	{"PRI_I2S_TX", NULL, "BE_IN"},
 	{"MI2S_TX", NULL, "BE_IN"},
 	{"QUAT_MI2S_TX", NULL, "BE_IN"},
+	{"SEC_MI2S_TX", NULL, "BE_IN"},
 	{"SLIMBUS_0_TX", NULL, "BE_IN" },
 	{"SLIMBUS_1_TX", NULL, "BE_IN" },
 	{"SLIMBUS_3_TX", NULL, "BE_IN" },
@@ -2268,6 +2554,7 @@
 	{"AUX_PCM_TX", NULL, "BE_IN"},
 	{"INCALL_RECORD_TX", NULL, "BE_IN"},
 	{"INCALL_RECORD_RX", NULL, "BE_IN"},
+	{"BE_OUT", NULL, "VOICE_PLAYBACK_TX"}
 };
 
 static int msm_pcm_routing_hw_params(struct snd_pcm_substream *substream,
@@ -2284,6 +2571,7 @@
 	mutex_lock(&routing_lock);
 	msm_bedais[be_id].sample_rate = params_rate(params);
 	msm_bedais[be_id].channel = params_channels(params);
+	msm_bedais[be_id].format = params_format(params);
 	mutex_unlock(&routing_lock);
 	return 0;
 }
@@ -2315,6 +2603,7 @@
 	bedai->active = 0;
 	bedai->sample_rate = 0;
 	bedai->channel = 0;
+	bedai->perf_mode = false;
 	mutex_unlock(&routing_lock);
 
 	return 0;
@@ -2327,6 +2616,8 @@
 	int i, path_type, session_type;
 	struct msm_pcm_routing_bdai_data *bedai;
 	u32 channels;
+	bool playback, capture;
+	uint16_t bits_per_sample = 16;
 
 	if (be_id >= MSM_BACKEND_DAI_MAX) {
 		pr_err("%s: unexpected be_id %d\n", __func__, be_id);
@@ -2354,24 +2645,31 @@
 	 * is started.
 	 */
 	bedai->active = 1;
+	playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+	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) {
 
 			channels = bedai->channel;
-			if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
-				substream->stream == SNDRV_PCM_STREAM_CAPTURE)
-				&& (channels > 2))
+			if (bedai->format == SNDRV_PCM_FORMAT_S24_LE)
+				bits_per_sample = 24;
+
+			if ((playback) && (channels > 0)) {
 				adm_multi_ch_copp_open(bedai->port_id,
-				path_type,
-				bedai->sample_rate,
-				channels,
-				DEFAULT_COPP_TOPOLOGY);
-			else
+					path_type,
+					bedai->sample_rate,
+					channels,
+					DEFAULT_COPP_TOPOLOGY, bedai->perf_mode,
+					bits_per_sample);
+			} else if (capture) {
 				adm_open(bedai->port_id,
 				path_type,
 				bedai->sample_rate,
 				channels,
-				DEFAULT_COPP_TOPOLOGY);
+				DEFAULT_COPP_TOPOLOGY, false,
+				bits_per_sample);
+			}
 
 			msm_pcm_routing_build_matrix(i,
 				fe_dai_map[i][session_type], path_type);
@@ -2442,6 +2740,10 @@
 			ARRAY_SIZE(multimedia2_vol_mixer_controls));
 
 	snd_soc_add_platform_controls(platform,
+				multimedia5_vol_mixer_controls,
+			ARRAY_SIZE(multimedia5_vol_mixer_controls));
+
+	snd_soc_add_platform_controls(platform,
 				compressed_vol_mixer_controls,
 			ARRAY_SIZE(compressed_vol_mixer_controls));
 
@@ -2456,6 +2758,10 @@
 	snd_soc_add_platform_controls(platform,
 				lpa_SRS_trumedia_controls_I2S,
 			ARRAY_SIZE(lpa_SRS_trumedia_controls_I2S));
+
+	snd_soc_add_platform_controls(platform,
+				multi_ch_channel_map_mixer_controls,
+			ARRAY_SIZE(multi_ch_channel_map_mixer_controls));
 	return 0;
 }
 
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
index be646ed..7ecdff3 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -35,6 +35,13 @@
 #define LPASS_BE_MI2S_TX "MI2S_TX"
 #define LPASS_BE_QUAT_MI2S_RX "QUAT_MI2S_RX"
 #define LPASS_BE_QUAT_MI2S_TX "QUAT_MI2S_TX"
+#define LPASS_BE_SEC_MI2S_RX "SEC_MI2S_RX"
+#define LPASS_BE_SEC_MI2S_TX "SEC_MI2S_TX"
+#define LPASS_BE_PRI_MI2S_RX "PRI_MI2S_RX"
+#define LPASS_BE_PRI_MI2S_TX "PRI_MI2S_TX"
+#define LPASS_BE_TERT_MI2S_RX "TERTIARY_MI2S_RX"
+#define LPASS_BE_TERT_MI2S_TX "TERTIARY_MI2S_TX"
+#define LPASS_BE_AUDIO_I2S_RX "AUDIO_I2S_RX"
 #define LPASS_BE_STUB_RX "STUB_RX"
 #define LPASS_BE_STUB_TX "STUB_TX"
 #define LPASS_BE_SLIMBUS_1_RX "SLIMBUS_1_RX"
@@ -56,17 +63,19 @@
 	MSM_FRONTEND_DAI_MULTIMEDIA2,
 	MSM_FRONTEND_DAI_MULTIMEDIA3,
 	MSM_FRONTEND_DAI_MULTIMEDIA4,
+	MSM_FRONTEND_DAI_MULTIMEDIA5,
 	MSM_FRONTEND_DAI_CS_VOICE,
 	MSM_FRONTEND_DAI_VOIP,
 	MSM_FRONTEND_DAI_AFE_RX,
 	MSM_FRONTEND_DAI_AFE_TX,
 	MSM_FRONTEND_DAI_VOICE_STUB,
 	MSM_FRONTEND_DAI_VOLTE,
+	MSM_FRONTEND_DAI_DTMF_RX,
 	MSM_FRONTEND_DAI_MAX,
 };
 
-#define MSM_FRONTEND_DAI_MM_SIZE (MSM_FRONTEND_DAI_MULTIMEDIA4 + 1)
-#define MSM_FRONTEND_DAI_MM_MAX_ID MSM_FRONTEND_DAI_MULTIMEDIA4
+#define MSM_FRONTEND_DAI_MM_SIZE (MSM_FRONTEND_DAI_MULTIMEDIA5 + 1)
+#define MSM_FRONTEND_DAI_MM_MAX_ID MSM_FRONTEND_DAI_MULTIMEDIA5
 
 enum {
 	MSM_BACKEND_DAI_PRI_I2S_RX = 0,
@@ -99,6 +108,13 @@
 	MSM_BACKEND_DAI_EXTPROC_EC_TX,
 	MSM_BACKEND_DAI_QUATERNARY_MI2S_RX,
 	MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
+	MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
+	MSM_BACKEND_DAI_SECONDARY_MI2S_TX,
+	MSM_BACKEND_DAI_PRI_MI2S_RX,
+	MSM_BACKEND_DAI_PRI_MI2S_TX,
+	MSM_BACKEND_DAI_TERTIARY_MI2S_RX,
+	MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
+	MSM_BACKEND_DAI_AUDIO_I2S_RX,
 	MSM_BACKEND_DAI_MAX,
 };
 
@@ -106,7 +122,7 @@
  * dspst_id:  DSP audio stream ID
  * stream_type: playback or capture
  */
-void msm_pcm_routing_reg_phy_stream(int fedai_id, int dspst_id,
+void msm_pcm_routing_reg_phy_stream(int fedai_id, bool perf_mode, int dspst_id,
 	int stream_type);
 void msm_pcm_routing_reg_psthr_stream(int fedai_id, int dspst_id,
 		int stream_type);
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c
index a1e461d..333ee48 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -44,10 +44,10 @@
 	.channels_max =         1,
 
 	.buffer_bytes_max =     4096 * 2,
-	.period_bytes_min =     4096,
+	.period_bytes_min =     2048,
 	.period_bytes_max =     4096,
 	.periods_min =          2,
-	.periods_max =          2,
+	.periods_max =          4,
 
 	.fifo_size =            0,
 };
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.h
index 64c0848..d0b119c 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c
index c7a8031..b5ce28f 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -140,7 +140,8 @@
 };
 
 static int voip_get_media_type(uint32_t mode,
-				unsigned int samp_rate);
+				unsigned int samp_rate,
+				unsigned int *media_type);
 static int voip_get_rate_type(uint32_t mode,
 				uint32_t rate,
 				uint32_t *rate_type);
@@ -782,11 +783,11 @@
 			goto done;
 		}
 		prtd->rate_type = rate_type;
-		media_type = voip_get_media_type(prtd->mode,
-						prtd->play_samp_rate);
-		if (media_type < 0) {
+		ret = voip_get_media_type(prtd->mode,
+						prtd->play_samp_rate,
+						&media_type);
+		if (ret < 0) {
 			pr_err("fail at getting media_type\n");
-			ret = -EINVAL;
 			goto done;
 		}
 		pr_debug(" media_type=%d, rate_type=%d\n", media_type,
@@ -1058,42 +1059,43 @@
 }
 
 static int voip_get_media_type(uint32_t mode,
-				unsigned int samp_rate)
+				unsigned int samp_rate,
+				unsigned int *media_type)
 {
-	uint32_t media_type;
+	int ret = 0;
 
 	pr_debug("%s: mode=%d, samp_rate=%d\n", __func__,
 		mode, samp_rate);
 	switch (mode) {
 	case MODE_AMR:
-		media_type = VSS_MEDIA_ID_AMR_NB_MODEM;
+		*media_type = VSS_MEDIA_ID_AMR_NB_MODEM;
 		break;
 	case MODE_AMR_WB:
-		media_type = VSS_MEDIA_ID_AMR_WB_MODEM;
+		*media_type = VSS_MEDIA_ID_AMR_WB_MODEM;
 		break;
 	case MODE_PCM:
 		if (samp_rate == 8000)
-			media_type = VSS_MEDIA_ID_PCM_NB;
+			*media_type = VSS_MEDIA_ID_PCM_NB;
 		else
-			media_type = VSS_MEDIA_ID_PCM_WB;
+			*media_type = VSS_MEDIA_ID_PCM_WB;
 		break;
 	case MODE_IS127: /* EVRC-A */
-		media_type = VSS_MEDIA_ID_EVRC_MODEM;
+		*media_type = VSS_MEDIA_ID_EVRC_MODEM;
 		break;
 	case MODE_4GV_NB: /* EVRC-B */
-		media_type = VSS_MEDIA_ID_4GV_NB_MODEM;
+		*media_type = VSS_MEDIA_ID_4GV_NB_MODEM;
 		break;
 	case MODE_4GV_WB: /* EVRC-WB */
-		media_type = VSS_MEDIA_ID_4GV_WB_MODEM;
+		*media_type = VSS_MEDIA_ID_4GV_WB_MODEM;
 		break;
 	default:
 		pr_debug(" input mode is not supported\n");
-		media_type = -EINVAL;
+		ret = -EINVAL;
 	}
 
-	pr_debug("%s: media_type is 0x%x\n", __func__, media_type);
+	pr_debug("%s: media_type is 0x%x\n", __func__, *media_type);
 
-	return media_type;
+	return ret;
 }
 
 
diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c
index 1e0ad9e..1f2f307 100644
--- a/sound/soc/msm/qdsp6v2/q6adm.c
+++ b/sound/soc/msm/qdsp6v2/q6adm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -18,7 +18,6 @@
 #include <linux/atomic.h>
 #include <linux/wait.h>
 
-#include <mach/qdsp6v2/audio_acdb.h>
 #include <mach/qdsp6v2/rtac.h>
 
 #include <sound/apr_audio-v2.h>
@@ -27,6 +26,9 @@
 #include <sound/q6audio-v2.h>
 #include <sound/q6afe-v2.h>
 
+#include "audio_acdb.h"
+
+
 #define TIMEOUT_MS 1000
 
 #define RESET_COPP_ID 99
@@ -44,12 +46,24 @@
 
 /* 0 - (MAX_AUDPROC_TYPES -1):				audproc handles */
 /* (MAX_AUDPROC_TYPES -1) - (2 * MAX_AUDPROC_TYPES -1):	audvol handles */
-	atomic_t mem_map_cal_handles[(2 * MAX_AUDPROC_TYPES)];
+/* + 1 for custom ADM topology */
+	atomic_t mem_map_cal_handles[(2 * MAX_AUDPROC_TYPES) + 1];
 	atomic_t mem_map_cal_index;
+
+	int set_custom_topology;
 };
 
 static struct adm_ctl			this_adm;
 
+struct adm_multi_ch_map {
+	bool set_channel_map;
+	char channel_mapping[PCM_FORMAT_MAX_NUM_CHANNEL];
+};
+
+static struct adm_multi_ch_map multi_ch_map = { false,
+						{0, 0, 0, 0, 0, 0, 0, 0}
+					      };
+
 int srs_trumedia_open(int port_id, int srs_tech_id, void *srs_params)
 {
 	struct adm_cmd_set_pp_params_inband_v5 *adm_params = NULL;
@@ -209,6 +223,12 @@
 	adm_params->hdr.dest_svc = APR_SVC_ADM;
 	adm_params->hdr.dest_domain = APR_DOMAIN_ADSP;
 	index = afe_get_port_index(port_id);
+	if (index < 0 || index >= AFE_MAX_PORTS) {
+		pr_err("%s: invalid port idx %d portid %#x\n",
+				__func__, index, port_id);
+		ret = -EINVAL;
+		goto fail_cmd;
+	}
 	adm_params->hdr.dest_port = atomic_read(&this_adm.copp_id[index]);
 	adm_params->hdr.token = port_id;
 	adm_params->hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5;
@@ -264,6 +284,21 @@
 			__func__, data->opcode, data->payload_size);
 }
 
+void adm_set_multi_ch_map(char *channel_map)
+{
+	memcpy(multi_ch_map.channel_mapping, channel_map,
+		PCM_FORMAT_MAX_NUM_CHANNEL);
+	multi_ch_map.set_channel_map = true;
+}
+
+void adm_get_multi_ch_map(char *channel_map)
+{
+	if (multi_ch_map.set_channel_map) {
+		memcpy(channel_map, multi_ch_map.channel_mapping,
+			PCM_FORMAT_MAX_NUM_CHANNEL);
+	}
+}
+
 static int32_t adm_callback(struct apr_client_data *data, void *priv)
 {
 	uint32_t *payload;
@@ -283,6 +318,8 @@
 				atomic_set(&this_adm.copp_stat[i], 0);
 			}
 			this_adm.apr = NULL;
+			reset_custom_topology_flags();
+			this_adm.set_custom_topology = 1;
 		}
 		pr_debug("Resetting calibration blocks");
 		for (i = 0; i < MAX_AUDPROC_TYPES; i++) {
@@ -324,6 +361,7 @@
 			case ADM_CMD_DEVICE_CLOSE_V5:
 			case ADM_CMD_SHARED_MEM_UNMAP_REGIONS:
 			case ADM_CMD_MATRIX_MAP_ROUTINGS_V5:
+			case ADM_CMD_ADD_TOPOLOGIES:
 				pr_debug("%s: Basic callback received, wake up.\n",
 					__func__);
 				atomic_set(&this_adm.copp_stat[index], 1);
@@ -409,6 +447,87 @@
 	return 0;
 }
 
+void send_adm_custom_topology(int port_id)
+{
+	struct acdb_cal_block		cal_block;
+	struct cmd_set_topologies	adm_top;
+	int				index;
+	int				result;
+	int				size = 4096;
+
+	get_adm_custom_topology(&cal_block);
+	if (cal_block.cal_size == 0) {
+		pr_debug("%s: no cal to send addr= 0x%x\n",
+				__func__, cal_block.cal_paddr);
+		goto done;
+	}
+
+	index = afe_get_port_index(port_id);
+	if (index < 0 || index >= AFE_MAX_PORTS) {
+		pr_err("%s: invalid port idx %d portid %#x\n",
+				__func__, index, port_id);
+		goto done;
+	}
+
+	if (this_adm.set_custom_topology) {
+		/* specific index 4 for adm topology memory */
+		atomic_set(&this_adm.mem_map_cal_index, 4);
+
+		/* Only call this once */
+		this_adm.set_custom_topology = 0;
+
+		result = adm_memory_map_regions(port_id, &cal_block.cal_paddr,
+					0, &size, 1);
+		if (result < 0) {
+			pr_err("%s: mmap did not work! addr = 0x%x, size = %d\n",
+				__func__, cal_block.cal_paddr,
+			       cal_block.cal_size);
+			goto done;
+		}
+	}
+
+
+	adm_top.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+		APR_HDR_LEN(20), APR_PKT_VER);
+	adm_top.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+		sizeof(adm_top));
+	adm_top.hdr.src_svc = APR_SVC_ADM;
+	adm_top.hdr.src_domain = APR_DOMAIN_APPS;
+	adm_top.hdr.src_port = port_id;
+	adm_top.hdr.dest_svc = APR_SVC_ADM;
+	adm_top.hdr.dest_domain = APR_DOMAIN_ADSP;
+	adm_top.hdr.dest_port = atomic_read(&this_adm.copp_id[index]);
+	adm_top.hdr.token = port_id;
+	adm_top.hdr.opcode = ADM_CMD_ADD_TOPOLOGIES;
+	adm_top.payload_addr_lsw = cal_block.cal_paddr;
+	adm_top.payload_addr_msw = 0;
+	adm_top.mem_map_handle = atomic_read(&this_adm.mem_map_cal_handles[4]);
+	adm_top.payload_size = cal_block.cal_size;
+
+	atomic_set(&this_adm.copp_stat[index], 0);
+	pr_debug("%s: Sending ADM_CMD_ADD_TOPOLOGIES payload = 0x%x, size = %d\n",
+		__func__, adm_top.payload_addr_lsw,
+		adm_top.payload_size);
+	result = apr_send_pkt(this_adm.apr, (uint32_t *)&adm_top);
+	if (result < 0) {
+		pr_err("%s: Set topologies failed port = 0x%x payload = 0x%x\n",
+			__func__, port_id, cal_block.cal_paddr);
+		goto done;
+	}
+	/* Wait for the callback */
+	result = wait_event_timeout(this_adm.wait[index],
+		atomic_read(&this_adm.copp_stat[index]),
+		msecs_to_jiffies(TIMEOUT_MS));
+	if (!result) {
+		pr_err("%s: Set topologies timed out port = 0x%x, payload = 0x%x\n",
+			__func__, port_id, cal_block.cal_paddr);
+		goto done;
+	}
+
+done:
+	return;
+}
+
 static int send_adm_cal_block(int port_id, struct acdb_cal_block *aud_cal)
 {
 	s32				result = 0;
@@ -627,7 +746,8 @@
 	return ret;
 }
 
-int adm_open(int port_id, int path, int rate, int channel_mode, int topology)
+int adm_open(int port_id, int path, int rate, int channel_mode, int topology,
+			bool perf_mode, uint16_t bits_per_sample)
 {
 	struct adm_cmd_device_open_v5	open;
 	int ret = 0;
@@ -658,6 +778,7 @@
 		rtac_set_adm_handle(this_adm.apr);
 	}
 
+	send_adm_custom_topology(port_id);
 
 	/* Create a COPP if port id are not enabled */
 	if (atomic_read(&this_adm.copp_cnt[index]) == 0) {
@@ -673,10 +794,16 @@
 		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_LOW_LATENCY_DEVICE_SESSION <<
+				ADM_BIT_SHIFT_DEVICE_PERF_MODE_FLAG;
+		} else {
+			open.flags |= ADM_LEGACY_DEVICE_SESSION <<
+				ADM_BIT_SHIFT_DEVICE_PERF_MODE_FLAG;
+		}
 
 		open.mode_of_operation = path;
-		/* Reserved for future use, need to set this to 0 */
-		open.flags = 0x00;
 		open.endpoint_id_1 = tmp_port;
 		open.endpoint_id_2 = 0xFFFF;
 
@@ -696,7 +823,7 @@
 			open.topology_id = topology;
 
 		open.dev_num_channel = channel_mode & 0x00FF;
-		open.bit_width = 16;
+		open.bit_width = bits_per_sample;
 		open.sample_rate  = rate;
 		memset(open.dev_channel_mapping, 0, 8);
 
@@ -741,6 +868,11 @@
 					channel_mode);
 			return -EINVAL;
 		}
+		if ((open.dev_num_channel > 2) &&
+			multi_ch_map.set_channel_map)
+			memcpy(open.dev_channel_mapping,
+				multi_ch_map.channel_mapping,
+				PCM_FORMAT_MAX_NUM_CHANNEL);
 
 		pr_debug("%s: port_id=%#x rate=%d topology_id=0x%X\n",
 			__func__, open.endpoint_id_1, open.sample_rate,
@@ -760,8 +892,8 @@
 			atomic_read(&this_adm.copp_stat[index]),
 			msecs_to_jiffies(TIMEOUT_MS));
 		if (!ret) {
-			pr_err("%s ADM open failed for port %#x"
-			"for [%d]\n", __func__, tmp_port, port_id);
+			pr_err("%s ADM open failed for port %#x for [%d]\n",
+						__func__, tmp_port, port_id);
 			ret = -EINVAL;
 			goto fail_cmd;
 		}
@@ -774,13 +906,13 @@
 	return ret;
 }
 
-
 int adm_multi_ch_copp_open(int port_id, int path, int rate, int channel_mode,
-				int topology)
+			int topology, bool perf_mode, uint16_t bits_per_sample)
 {
 	int ret = 0;
 
-	ret = adm_open(port_id, path, rate, channel_mode, topology);
+	ret = adm_open(port_id, path, rate, channel_mode,
+				   topology, perf_mode, bits_per_sample);
 
 	return ret;
 }
@@ -790,7 +922,7 @@
 {
 	struct adm_cmd_matrix_map_routings_v5	*route;
 	struct adm_session_map_node_v5 *node;
-	uint32_t *copps_list;
+	uint16_t *copps_list;
 	int cmd_size = 0;
 	int ret = 0, i = 0;
 	void *payload = NULL;
@@ -849,7 +981,7 @@
 	node->session_id = session_id;
 	node->num_copps = num_copps;
 	payload = (u8 *)node + sizeof(struct adm_session_map_node_v5);
-	copps_list = (uint32_t *)payload;
+	copps_list = (uint16_t *)payload;
 	for (i = 0; i < num_copps; i++) {
 		int tmp;
 		port_id[i] = q6audio_convert_virtual_to_portid(port_id[i]);
@@ -1123,6 +1255,7 @@
 {
 	int i = 0;
 	this_adm.apr = NULL;
+	this_adm.set_custom_topology = 1;
 
 	for (i = 0; i < AFE_MAX_PORTS; i++) {
 		atomic_set(&this_adm.copp_id[i], RESET_COPP_ID);
diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c
index 9387d21..1b5ad17 100644
--- a/sound/soc/msm/qdsp6v2/q6afe.c
+++ b/sound/soc/msm/qdsp6v2/q6afe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -19,12 +19,12 @@
 #include <linux/jiffies.h>
 #include <linux/sched.h>
 #include <linux/msm_ion.h>
-#include <mach/qdsp6v2/audio_acdb.h>
 #include <sound/apr_audio-v2.h>
 #include <sound/q6afe-v2.h>
-
 #include <sound/q6audio-v2.h>
 
+#include "audio_acdb.h"
+
 
 struct afe_ctl {
 	void *apr;
@@ -43,6 +43,7 @@
 	struct acdb_cal_block afe_cal_addr[MAX_AUDPROC_TYPES];
 	atomic_t mem_map_cal_handles[MAX_AUDPROC_TYPES];
 	atomic_t mem_map_cal_index;
+	u16 dtmf_gen_rx_portid;
 };
 
 static struct afe_ctl this_afe;
@@ -95,6 +96,7 @@
 			case AFE_SERVICE_CMD_SHARED_MEM_MAP_REGIONS:
 			case AFE_SERVICE_CMD_SHARED_MEM_UNMAP_REGIONS:
 			case AFE_SERVICE_CMD_UNREGISTER_RT_PORT_DRIVER:
+			case AFE_PORTS_CMD_DTMF_CTL:
 				atomic_set(&this_afe.state, 0);
 				wake_up(&this_afe.wait[data->token]);
 				break;
@@ -173,6 +175,10 @@
 	case INT_FM_RX:
 	case VOICE_PLAYBACK_TX:
 	case RT_PROXY_PORT_001_RX:
+	case AUDIO_PORT_ID_I2S_RX:
+	case AFE_PORT_ID_PRIMARY_MI2S_RX:
+	case AFE_PORT_ID_SECONDARY_MI2S_RX:
+	case AFE_PORT_ID_TERTIARY_MI2S_RX:
 	case AFE_PORT_ID_QUATERNARY_MI2S_RX:
 		ret = MSM_AFE_PORT_TYPE_RX;
 		break;
@@ -192,6 +198,9 @@
 	case VOICE_RECORD_RX:
 	case INT_BT_SCO_TX:
 	case RT_PROXY_PORT_001_TX:
+	case AFE_PORT_ID_PRIMARY_MI2S_TX:
+	case AFE_PORT_ID_SECONDARY_MI2S_TX:
+	case AFE_PORT_ID_TERTIARY_MI2S_TX:
 	case AFE_PORT_ID_QUATERNARY_MI2S_TX:
 		ret = MSM_AFE_PORT_TYPE_TX;
 		break;
@@ -215,6 +224,7 @@
 	case SECONDARY_I2S_TX:
 	case MI2S_RX:
 	case MI2S_TX:
+	case AFE_PORT_ID_PRIMARY_MI2S_RX:
 		ret_size = SIZEOF_CFG_CMD(afe_param_id_i2s_cfg);
 		break;
 	case HDMI_RX:
@@ -225,8 +235,11 @@
 	case SLIMBUS_0_TX:
 	case SLIMBUS_1_RX:
 	case SLIMBUS_1_TX:
+	case SLIMBUS_2_RX:
+	case SLIMBUS_2_TX:
 		ret_size = SIZEOF_CFG_CMD(afe_param_id_slimbus_cfg);
 		break;
+	case VOICE_PLAYBACK_TX:
 	case VOICE_RECORD_RX:
 	case VOICE_RECORD_TX:
 		ret_size = SIZEOF_CFG_CMD(afe_param_id_pseudo_port_cfg);
@@ -403,6 +416,7 @@
 	case SECONDARY_I2S_TX:
 	case MI2S_RX:
 	case MI2S_TX:
+	case AFE_PORT_ID_PRIMARY_MI2S_RX:
 	case AFE_PORT_ID_SECONDARY_MI2S_RX:
 	case AFE_PORT_ID_SECONDARY_MI2S_TX:
 	case AFE_PORT_ID_TERTIARY_MI2S_RX:
@@ -414,6 +428,7 @@
 	case HDMI_RX:
 		cfg_type = AFE_PARAM_ID_HDMI_CONFIG;
 		break;
+	case VOICE_PLAYBACK_TX:
 	case VOICE_RECORD_RX:
 	case VOICE_RECORD_TX:
 		cfg_type = AFE_PARAM_ID_PSEUDO_PORT_CONFIG;
@@ -560,10 +575,17 @@
 	case RT_PROXY_PORT_001_TX: return IDX_RT_PROXY_PORT_001_TX;
 	case SLIMBUS_4_RX: return IDX_SLIMBUS_4_RX;
 	case SLIMBUS_4_TX: return IDX_SLIMBUS_4_TX;
+	case AFE_PORT_ID_PRIMARY_MI2S_RX:
+		return IDX_AFE_PORT_ID_PRIMARY_MI2S_RX;
 	case AFE_PORT_ID_QUATERNARY_MI2S_RX:
 		return IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX;
 	case AFE_PORT_ID_QUATERNARY_MI2S_TX:
 		return IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX;
+	case AFE_PORT_ID_SECONDARY_MI2S_RX:
+		return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX;
+	case AFE_PORT_ID_SECONDARY_MI2S_TX:
+		return IDX_AFE_PORT_ID_SECONDARY_MI2S_TX;
+
 	default: return -EINVAL;
 	}
 }
@@ -624,6 +646,7 @@
 		break;
 	case SECONDARY_I2S_RX:
 	case SECONDARY_I2S_TX:
+	case AFE_PORT_ID_PRIMARY_MI2S_RX:
 	case MI2S_RX:
 	case MI2S_TX:
 		cfg_type = AFE_PARAM_ID_I2S_CONFIG;
@@ -1027,9 +1050,9 @@
 	return 0;
 }
 
-uint32_t afe_req_mmap_handle(void)
+uint32_t afe_req_mmap_handle(struct afe_audio_client *ac)
 {
-	return this_afe.mmap_handle;
+	return ac->mem_map_handle;
 }
 
 struct afe_audio_client *q6afe_audio_client_alloc(void *priv)
@@ -1154,6 +1177,21 @@
 	q6afe_audio_client_buf_free_contiguous(dir, ac);
 	return -EINVAL;
 }
+
+int afe_memory_map(u32 dma_addr_p, u32 dma_buf_sz, struct afe_audio_client *ac)
+{
+	int ret = 0;
+
+	ac->mem_map_handle = 0;
+	ret = afe_cmd_memory_map(dma_addr_p, dma_buf_sz);
+	if (ret < 0) {
+		pr_err("%s: afe_cmd_memory_map failed\n", __func__);
+		return ret;
+	}
+	ac->mem_map_handle = this_afe.mmap_handle;
+	return ret;
+}
+
 int afe_cmd_memory_map(u32 dma_addr_p, u32 dma_buf_sz)
 {
 	int ret = 0;
@@ -1213,6 +1251,7 @@
 	pr_debug("%s: dma_addr_p 0x%x , size %d\n", __func__,
 					dma_addr_p, dma_buf_sz);
 	atomic_set(&this_afe.state, 1);
+	this_afe.mmap_handle = 0;
 	ret = apr_send_pkt(this_afe.apr, (uint32_t *) mmap_region_cmd);
 	if (ret < 0) {
 		pr_err("%s: AFE memory map cmd failed %d\n",
@@ -1795,6 +1834,84 @@
 	return;
 }
 #endif
+
+void afe_set_dtmf_gen_rx_portid(u16 port_id, int set)
+{
+	if (set)
+		this_afe.dtmf_gen_rx_portid = port_id;
+	else if (this_afe.dtmf_gen_rx_portid == port_id)
+		this_afe.dtmf_gen_rx_portid = -1;
+}
+
+int afe_dtmf_generate_rx(int64_t duration_in_ms,
+			 uint16_t high_freq,
+			 uint16_t low_freq, uint16_t gain)
+{
+	int ret = 0;
+	int index = 0;
+	struct afe_dtmf_generation_command cmd_dtmf;
+
+	pr_debug("%s: DTMF AFE Gen\n", __func__);
+
+	if (afe_validate_port(this_afe.dtmf_gen_rx_portid) < 0) {
+		pr_err("%s: Failed : Invalid Port id = %d\n",
+		       __func__, this_afe.dtmf_gen_rx_portid);
+		ret = -EINVAL;
+		goto fail_cmd;
+	}
+
+	if (this_afe.apr == NULL) {
+		this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
+					    0xFFFFFFFF, &this_afe);
+		pr_debug("%s: Register AFE\n", __func__);
+		if (this_afe.apr == NULL) {
+			pr_err("%s: Unable to register AFE\n", __func__);
+			ret = -ENODEV;
+			return ret;
+		}
+	}
+
+	pr_debug("dur=%lld: hfreq=%d lfreq=%d gain=%d portid=%x\n",
+		duration_in_ms, high_freq, low_freq, gain,
+		this_afe.dtmf_gen_rx_portid);
+
+	cmd_dtmf.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+	cmd_dtmf.hdr.pkt_size = sizeof(cmd_dtmf);
+	cmd_dtmf.hdr.src_port = 0;
+	cmd_dtmf.hdr.dest_port = 0;
+	cmd_dtmf.hdr.token = 0;
+	cmd_dtmf.hdr.opcode = AFE_PORTS_CMD_DTMF_CTL;
+	cmd_dtmf.duration_in_ms = duration_in_ms;
+	cmd_dtmf.high_freq = high_freq;
+	cmd_dtmf.low_freq = low_freq;
+	cmd_dtmf.gain = gain;
+	cmd_dtmf.num_ports = 1;
+	cmd_dtmf.port_ids = q6audio_get_port_id(this_afe.dtmf_gen_rx_portid);
+
+	atomic_set(&this_afe.state, 1);
+	ret = apr_send_pkt(this_afe.apr, (uint32_t *) &cmd_dtmf);
+	if (ret < 0) {
+		pr_err("%s: AFE DTMF failed for num_ports:%d ids:%x\n",
+		       __func__, cmd_dtmf.num_ports, cmd_dtmf.port_ids);
+		ret = -EINVAL;
+		goto fail_cmd;
+	}
+	index = q6audio_get_port_index(this_afe.dtmf_gen_rx_portid);
+	ret = wait_event_timeout(this_afe.wait[index],
+		(atomic_read(&this_afe.state) == 0),
+			msecs_to_jiffies(TIMEOUT_MS));
+	if (ret < 0) {
+		pr_err("%s: wait_event timeout\n", __func__);
+		ret = -EINVAL;
+		goto fail_cmd;
+	}
+	return 0;
+
+fail_cmd:
+	return ret;
+}
+
 int afe_sidetone(u16 tx_port_id, u16 rx_port_id, u16 enable, uint16_t gain)
 {
 	struct afe_loopback_cfg_v1 cmd_sidetone;
@@ -1893,6 +2010,7 @@
 	case RT_PROXY_PORT_001_TX:
 	case SLIMBUS_4_RX:
 	case SLIMBUS_4_TX:
+	case AFE_PORT_ID_PRIMARY_MI2S_RX:
 	{
 		ret = 0;
 		break;
@@ -2012,6 +2130,175 @@
 	return ret;
 }
 
+int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg)
+{
+	struct afe_lpass_clk_config_command clk_cfg;
+	int index = 0;
+	int ret = 0;
+
+	if (!cfg) {
+		pr_err("%s: clock cfg is NULL\n", __func__);
+		ret = -EINVAL;
+		return ret;
+	}
+	index = q6audio_get_port_index(port_id);
+	if (q6audio_is_digital_pcm_interface(port_id) < 0)
+		return -EINVAL;
+
+	ret = afe_q6_interface_prepare();
+	if (ret != 0)
+		return ret;
+
+	clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+	clk_cfg.hdr.pkt_size = sizeof(clk_cfg);
+	clk_cfg.hdr.src_port = 0;
+	clk_cfg.hdr.dest_port = 0;
+	clk_cfg.hdr.token = index;
+
+	clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
+	clk_cfg.param.port_id = q6audio_get_port_id(port_id);
+	clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr)
+						- sizeof(clk_cfg.param);
+	clk_cfg.param.payload_address_lsw = 0x00;
+	clk_cfg.param.payload_address_msw = 0x00;
+	clk_cfg.param.mem_map_handle = 0x00;
+	clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
+	clk_cfg.pdata.param_id = AFE_PARAM_ID_LPAIF_CLK_CONFIG;
+	clk_cfg.pdata.param_size =  sizeof(clk_cfg.clk_cfg);
+	clk_cfg.clk_cfg = *cfg;
+
+	pr_debug("%s: Minor version =%x clk val1 = %d\n"
+		 "clk val2 = %d, clk src = %x\n"
+		 "clk root = %x clk mode = %x resrv = %x\n"
+		 "port id = %x\n",
+		 __func__, cfg->i2s_cfg_minor_version,
+		 cfg->clk_val1, cfg->clk_val2, cfg->clk_src,
+		 cfg->clk_root, cfg->clk_set_mode,
+		 cfg->reserved, q6audio_get_port_id(port_id));
+
+	atomic_set(&this_afe.state, 1);
+	atomic_set(&this_afe.status, 0);
+	ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg);
+	if (ret < 0) {
+		pr_err("%s: AFE enable for port %d\n",
+		       __func__, port_id);
+		ret = -EINVAL;
+		goto fail_cmd;
+	}
+
+	ret = wait_event_timeout(this_afe.wait[index],
+			(atomic_read(&this_afe.state) == 0),
+			msecs_to_jiffies(TIMEOUT_MS));
+	if (!ret) {
+		pr_err("%s: wait_event timeout\n", __func__);
+		ret = -EINVAL;
+		goto fail_cmd;
+	}
+	if (atomic_read(&this_afe.status) != 0) {
+		pr_err("%s: config cmd failed\n", __func__);
+		ret = -EINVAL;
+		goto fail_cmd;
+	}
+
+fail_cmd:
+	return ret;
+}
+
+int afe_set_lpass_internal_digital_codec_clock(u16 port_id,
+			struct afe_digital_clk_cfg *cfg)
+{
+	struct afe_lpass_digital_clk_config_command clk_cfg;
+	int index = 0;
+	int ret = 0;
+
+	if (!cfg) {
+		pr_err("%s: clock cfg is NULL\n", __func__);
+		ret = -EINVAL;
+		return ret;
+	}
+	index = q6audio_get_port_index(port_id);
+	if (q6audio_is_digital_pcm_interface(port_id) < 0)
+		return -EINVAL;
+
+	ret = afe_q6_interface_prepare();
+	if (ret != 0)
+		return ret;
+
+	clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+	clk_cfg.hdr.pkt_size = sizeof(clk_cfg);
+	clk_cfg.hdr.src_port = 0;
+	clk_cfg.hdr.dest_port = 0;
+	clk_cfg.hdr.token = index;
+
+	clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
+	clk_cfg.param.port_id = q6audio_get_port_id(port_id);
+	clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr)
+						- sizeof(clk_cfg.param);
+	clk_cfg.param.payload_address_lsw = 0x00;
+	clk_cfg.param.payload_address_msw = 0x00;
+	clk_cfg.param.mem_map_handle = 0x00;
+	clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
+	clk_cfg.pdata.param_id = AFE_PARAM_ID_INTERNAL_DIGIATL_CDC_CLK_CONFIG;
+	clk_cfg.pdata.param_size =  sizeof(clk_cfg.clk_cfg);
+	clk_cfg.clk_cfg = *cfg;
+
+	pr_debug("%s: Minor version =%x clk val = %d\n"
+		 "clk root = %x resrv = %x port id = %x\n",
+		 __func__, cfg->i2s_cfg_minor_version,
+		 cfg->clk_val, cfg->clk_root, cfg->reserved,
+		 q6audio_get_port_id(port_id));
+
+	atomic_set(&this_afe.state, 1);
+	atomic_set(&this_afe.status, 0);
+	ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg);
+	if (ret < 0) {
+		pr_err("%s: AFE enable for port %d\n",
+		       __func__, port_id);
+		ret = -EINVAL;
+		goto fail_cmd;
+	}
+
+	ret = wait_event_timeout(this_afe.wait[index],
+			(atomic_read(&this_afe.state) == 0),
+			msecs_to_jiffies(TIMEOUT_MS));
+	if (!ret) {
+		pr_err("%s: wait_event timeout\n", __func__);
+		ret = -EINVAL;
+		goto fail_cmd;
+	}
+	if (atomic_read(&this_afe.status) != 0) {
+		pr_err("%s: config cmd failed\n", __func__);
+		ret = -EINVAL;
+		goto fail_cmd;
+	}
+
+fail_cmd:
+	return ret;
+}
+
+int q6afe_check_osr_clk_freq(u32 freq)
+{
+	int ret = 0;
+	switch (freq) {
+	case Q6AFE_LPASS_OSR_CLK_12_P288_MHZ:
+	case Q6AFE_LPASS_OSR_CLK_8_P192_MHZ:
+	case Q6AFE_LPASS_OSR_CLK_6_P144_MHZ:
+	case Q6AFE_LPASS_OSR_CLK_4_P096_MHZ:
+	case Q6AFE_LPASS_OSR_CLK_3_P072_MHZ:
+	case Q6AFE_LPASS_OSR_CLK_2_P048_MHZ:
+	case Q6AFE_LPASS_OSR_CLK_1_P536_MHZ:
+	case Q6AFE_LPASS_OSR_CLK_1_P024_MHZ:
+	case Q6AFE_LPASS_OSR_CLK_768_kHZ:
+	case Q6AFE_LPASS_OSR_CLK_512_kHZ:
+		break;
+	default:
+		ret = -EINVAL;
+	}
+	return ret;
+}
+
 static int __init afe_init(void)
 {
 	int i = 0;
@@ -2019,6 +2306,7 @@
 	atomic_set(&this_afe.status, 0);
 	atomic_set(&this_afe.mem_map_cal_index, -1);
 	this_afe.apr = NULL;
+	this_afe.dtmf_gen_rx_portid = -1;
 	this_afe.mmap_handle = 0;
 	for (i = 0; i < AFE_MAX_PORTS; i++)
 		init_waitqueue_head(&this_afe.wait[i]);
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 0cbd136..5be62cc 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -34,13 +34,15 @@
 
 #include <mach/memory.h>
 #include <mach/debug_mm.h>
-#include <mach/qdsp6v2/audio_acdb.h>
 #include <mach/qdsp6v2/rtac.h>
 #include <mach/msm_subsystem_map.h>
 
 #include <sound/apr_audio-v2.h>
 #include <sound/q6asm-v2.h>
 
+#include "audio_acdb.h"
+
+
 #define TRUE        0x01
 #define FALSE       0x00
 #define READDONE_IDX_STATUS 0
@@ -78,7 +80,8 @@
 static void q6asm_add_hdr_async(struct audio_client *ac, struct apr_hdr *hdr,
 			uint32_t pkt_size, uint32_t cmd_flg);
 static int q6asm_memory_map_regions(struct audio_client *ac, int dir,
-				uint32_t bufsz, uint32_t bufcnt);
+				uint32_t bufsz, uint32_t bufcnt,
+				bool is_contiguous);
 static int q6asm_memory_unmap_regions(struct audio_client *ac, int dir,
 				uint32_t bufsz, uint32_t bufcnt);
 static void q6asm_reset_buf_state(struct audio_client *ac);
@@ -103,6 +106,9 @@
 static int out_cold_index;
 static char *out_buffer;
 static char *in_buffer;
+static int set_custom_topology;
+static int topology_map_handle;
+
 static int audio_output_latency_dbgfs_open(struct inode *inode,
 							struct file *file)
 {
@@ -335,6 +341,91 @@
 	session[ac->session] = 0;
 	mutex_unlock(&session_lock);
 	ac->session = 0;
+	ac->perf_mode = 0;
+	return;
+}
+
+void send_asm_custom_topology(struct audio_client *ac)
+{
+	struct acdb_cal_block		cal_block;
+	struct cmd_set_topologies	asm_top;
+	struct audio_buffer		*buf;
+	struct asm_buffer_node		*buf_node = NULL;
+	struct list_head		*ptr, *next;
+	int				result;
+	int				size = 4096;
+
+	get_asm_custom_topology(&cal_block);
+	if (cal_block.cal_size == 0) {
+		pr_debug("%s: no cal to send addr= 0x%x\n",
+				__func__, cal_block.cal_paddr);
+		goto done;
+	}
+
+	if (set_custom_topology) {
+		/* Only call this once */
+		set_custom_topology = 0;
+
+		/* Use first asm buf to map memory */
+		buf = kzalloc(sizeof(struct audio_buffer), GFP_KERNEL);
+		if (!buf) {
+			pr_debug("%s: could not allocate temp memory\n",
+				__func__);
+			goto done;
+		}
+		buf[0].phys = cal_block.cal_paddr;
+		ac->port[0].buf = buf;
+
+		result = q6asm_memory_map_regions(ac, 0, size, 1, 1);
+		if (result < 0) {
+			pr_err("%s: mmap did not work! addr = 0x%x, size = %d\n",
+				__func__, cal_block.cal_paddr,
+				cal_block.cal_size);
+			goto done;
+		}
+
+		list_for_each_safe(ptr, next, &ac->port[IN].mem_map_handle) {
+			buf_node = list_entry(ptr, struct asm_buffer_node,
+						list);
+			if (buf_node->buf_addr_lsw == cal_block.cal_paddr) {
+				topology_map_handle =  buf_node->mmap_hdl;
+				break;
+			}
+		}
+
+		kfree(buf);
+	}
+
+	q6asm_add_hdr(ac, &asm_top.hdr, APR_PKT_SIZE(APR_HDR_SIZE,
+						sizeof(asm_top)), TRUE);
+
+	asm_top.hdr.opcode = ASM_CMD_ADD_TOPOLOGIES;
+	asm_top.payload_addr_lsw = cal_block.cal_paddr;
+	asm_top.payload_addr_msw = 0;
+	asm_top.mem_map_handle = topology_map_handle;
+	asm_top.payload_size = cal_block.cal_size;
+
+	 pr_debug("%s: Sending ASM_CMD_ADD_TOPOLOGIES payload = 0x%x, size = %d, map handle = 0x%x\n",
+		__func__, asm_top.payload_addr_lsw,
+		asm_top.payload_size, asm_top.mem_map_handle);
+
+	result = apr_send_pkt(ac->apr, (uint32_t *) &asm_top);
+	if (result < 0) {
+		pr_err("%s: Set topologies failed payload = 0x%x\n",
+			__func__, cal_block.cal_paddr);
+		goto done;
+	}
+
+	result = wait_event_timeout(ac->cmd_wait,
+			(atomic_read(&ac->cmd_state) == 0), 5*HZ);
+	if (result < 0) {
+		pr_err("%s: Set topologies failed payload = 0x%x\n",
+			__func__, cal_block.cal_paddr);
+		goto done;
+	}
+
+
+done:
 	return;
 }
 
@@ -532,6 +623,7 @@
 	ac->cb = cb;
 	ac->priv = priv;
 	ac->io_mode = SYNC_IO_MODE;
+	ac->perf_mode = false;
 	ac->apr = apr_register("ADSP", "ASM", \
 				(apr_fn)q6asm_callback,\
 				((ac->session) << 8 | 0x0001),\
@@ -549,6 +641,8 @@
 		goto fail;
 
 	init_waitqueue_head(&ac->cmd_wait);
+	init_waitqueue_head(&ac->time_wait);
+	atomic_set(&ac->time_flag, 1);
 	INIT_LIST_HEAD(&ac->port[0].mem_map_handle);
 	INIT_LIST_HEAD(&ac->port[1].mem_map_handle);
 	pr_debug("%s: mem_map_handle list init'ed\n", __func__);
@@ -560,6 +654,8 @@
 	atomic_set(&ac->cmd_state, 0);
 	atomic_set(&ac->nowait_cmd_cnt, 0);
 
+	send_asm_custom_topology(ac);
+
 	pr_debug("%s: session[%d]\n", __func__, ac->session);
 
 	return ac;
@@ -679,7 +775,7 @@
 		ac->port[dir].max_buf_cnt = cnt;
 
 		mutex_unlock(&ac->cmd_lock);
-		rc = q6asm_memory_map_regions(ac, dir, bufsz, cnt);
+		rc = q6asm_memory_map_regions(ac, dir, bufsz, cnt, 0);
 		if (rc < 0) {
 			pr_err("%s:CMD Memory_map_regions failed\n", __func__);
 			goto fail;
@@ -785,7 +881,7 @@
 	}
 	ac->port[dir].max_buf_cnt = cnt;
 	mutex_unlock(&ac->cmd_lock);
-	rc = q6asm_memory_map_regions(ac, dir, bufsz, cnt);
+	rc = q6asm_memory_map_regions(ac, dir, bufsz, cnt, 1);
 	if (rc < 0) {
 		pr_err("%s:CMD Memory_map_regions failed\n", __func__);
 		goto fail;
@@ -819,6 +915,8 @@
 		apr_reset(this_mmap.apr);
 		atomic_set(&this_mmap.ref_cnt, 0);
 		this_mmap.apr = NULL;
+		reset_custom_topology_flags();
+		set_custom_topology = 1;
 		return 0;
 	}
 	sid = (data->token >> 8) & 0x0F;
@@ -837,6 +935,11 @@
 		switch (payload[0]) {
 		case ASM_CMD_SHARED_MEM_MAP_REGIONS:
 		case ASM_CMD_SHARED_MEM_UNMAP_REGIONS:
+			if (payload[1] != 0) {
+				pr_err("%s: cmd = 0x%x returned error = 0x%x sid:%d\n",
+				__func__, payload[0], payload[1], sid);
+			}
+
 			if (atomic_read(&ac->cmd_state)) {
 				atomic_set(&ac->cmd_state, 0);
 				wake_up(&ac->cmd_wait);
@@ -947,6 +1050,9 @@
 				ac->cb(data->opcode, data->token,
 					(uint32_t *)data->payload, ac->priv);
 		apr_reset(ac->apr);
+		ac->apr = NULL;
+		reset_custom_topology_flags();
+		set_custom_topology = 1;
 		return 0;
 	}
 
@@ -983,11 +1089,12 @@
 					__func__, token, ac->session);
 			return -EINVAL;
 		}
-		case ASM_STREAM_CMD_OPEN_READ_V2:
-		case ASM_STREAM_CMD_OPEN_WRITE_V2:
+		case ASM_STREAM_CMD_OPEN_READ_V3:
+		case ASM_STREAM_CMD_OPEN_WRITE_V3:
 		case ASM_STREAM_CMD_OPEN_READWRITE_V2:
 		case ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2:
 		case ASM_STREAM_CMD_SET_ENCDEC_PARAM:
+		case ASM_CMD_ADD_TOPOLOGIES:
 		pr_debug("%s:Payload = [0x%x]stat[0x%x]\n",
 				__func__, payload[0], payload[1]);
 			if (atomic_read(&ac->cmd_state) && wakeup_flag) {
@@ -1119,10 +1226,8 @@
 				 payload[0], payload[1], payload[2]);
 		ac->time_stamp = (uint64_t)(((uint64_t)payload[2] << 32) |
 				payload[1]);
-		if (atomic_read(&ac->cmd_state)) {
-			atomic_set(&ac->cmd_state, 0);
-			wake_up(&ac->cmd_wait);
-		}
+		if (atomic_cmpxchg(&ac->time_flag, 1, 0))
+			wake_up(&ac->time_wait);
 		break;
 	case ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY:
 	case ASM_DATA_EVENT_ENC_SR_CM_CHANGE_NOTIFY:
@@ -1330,7 +1435,7 @@
 		uint32_t format)
 {
 	int rc = 0x00;
-	struct asm_stream_cmd_open_read_v2 open;
+	struct asm_stream_cmd_open_read_v3 open;
 
 	uint16_t bits_per_sample = 16;
 
@@ -1344,7 +1449,7 @@
 	pr_debug("%s:session[%d]", __func__, ac->session);
 
 	q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE);
-	open.hdr.opcode = ASM_STREAM_CMD_OPEN_READ_V2;
+	open.hdr.opcode = ASM_STREAM_CMD_OPEN_READ_V3;
 	/* Stream prio : High, provide meta info with encoded frames */
 	open.src_endpointype = ASM_END_POINT_DEVICE_MATRIX;
 
@@ -1352,30 +1457,39 @@
 	if (open.preprocopo_id == 0)
 		open.preprocopo_id = ASM_STREAM_POSTPROC_TOPO_ID_DEFAULT;
 	open.bits_per_sample = bits_per_sample;
+	open.mode_flags = 0x0;
+
+	if (ac->perf_mode) {
+		open.mode_flags |= ASM_LOW_LATENCY_STREAM_SESSION <<
+				ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_READ;
+	} else {
+		open.mode_flags |= ASM_LEGACY_STREAM_SESSION <<
+				ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_READ;
+	}
 
 	switch (format) {
 	case FORMAT_LINEAR_PCM:
-		open.mode_flags = 0x00;
+		open.mode_flags |= 0x00;
 		open.enc_cfg_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2;
 		break;
 	case FORMAT_MPEG4_AAC:
-		open.mode_flags = BUFFER_META_ENABLE;
+		open.mode_flags |= BUFFER_META_ENABLE;
 		open.enc_cfg_id = ASM_MEDIA_FMT_AAC_V2;
 		break;
 	case FORMAT_V13K:
-		open.mode_flags = BUFFER_META_ENABLE;
+		open.mode_flags |= BUFFER_META_ENABLE;
 		open.enc_cfg_id = ASM_MEDIA_FMT_V13K_FS;
 		break;
 	case FORMAT_EVRC:
-		open.mode_flags = BUFFER_META_ENABLE;
+		open.mode_flags |= BUFFER_META_ENABLE;
 		open.enc_cfg_id = ASM_MEDIA_FMT_EVRC_FS;
 		break;
 	case FORMAT_AMRNB:
-		open.mode_flags = BUFFER_META_ENABLE ;
+		open.mode_flags |= BUFFER_META_ENABLE ;
 		open.enc_cfg_id = ASM_MEDIA_FMT_AMRNB_FS;
 		break;
 	case FORMAT_AMRWB:
-		open.mode_flags = BUFFER_META_ENABLE ;
+		open.mode_flags |= BUFFER_META_ENABLE ;
 		open.enc_cfg_id = ASM_MEDIA_FMT_AMRWB_FS;
 		break;
 	default:
@@ -1399,10 +1513,12 @@
 fail_cmd:
 	return -EINVAL;
 }
-int q6asm_open_write(struct audio_client *ac, uint32_t format)
+
+static int __q6asm_open_write(struct audio_client *ac, uint32_t format,
+		uint16_t bits_per_sample)
 {
 	int rc = 0x00;
-	struct asm_stream_cmd_open_write_v2 open;
+	struct asm_stream_cmd_open_write_v3 open;
 
 	if ((ac == NULL) || (ac->apr == NULL)) {
 		pr_err("%s: APR handle NULL\n", __func__);
@@ -1413,11 +1529,18 @@
 
 	q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE);
 
-	open.hdr.opcode = ASM_STREAM_CMD_OPEN_WRITE_V2;
+	open.hdr.opcode = ASM_STREAM_CMD_OPEN_WRITE_V3;
 	open.mode_flags = 0x00;
+	if (ac->perf_mode)
+		open.mode_flags |= (ASM_LOW_LATENCY_STREAM_SESSION <<
+				ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_WRITE);
+	else
+		open.mode_flags |= (ASM_LEGACY_STREAM_SESSION <<
+				ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_WRITE);
+
 	/* source endpoint : matrix */
 	open.sink_endpointype = ASM_END_POINT_DEVICE_MATRIX;
-	open.bits_per_sample = 16;
+	open.bits_per_sample = bits_per_sample;
 
 	open.postprocopo_id = get_asm_topology();
 	if (open.postprocopo_id == 0)
@@ -1464,6 +1587,17 @@
 	return -EINVAL;
 }
 
+int q6asm_open_write(struct audio_client *ac, uint32_t format)
+{
+	return __q6asm_open_write(ac, format, 16);
+}
+
+int q6asm_open_write_v2(struct audio_client *ac, uint32_t format,
+		uint16_t bits_per_sample)
+{
+	return __q6asm_open_write(ac, format, bits_per_sample);
+}
+
 int q6asm_open_read_write(struct audio_client *ac,
 			uint32_t rd_format,
 			uint32_t wr_format)
@@ -1849,12 +1983,12 @@
 		lchannel_mapping[3] = PCM_CHANNEL_LB;
 		lchannel_mapping[4] = PCM_CHANNEL_RB;
 	} else if (channels == 6) {
-		channel_mapping[0] = PCM_CHANNEL_FC;
-		channel_mapping[1] = PCM_CHANNEL_FL;
-		channel_mapping[2] = PCM_CHANNEL_FR;
-		channel_mapping[3] = PCM_CHANNEL_LB;
-		channel_mapping[4] = PCM_CHANNEL_RB;
-		channel_mapping[5] = PCM_CHANNEL_LFE;
+		lchannel_mapping[0] = PCM_CHANNEL_FC;
+		lchannel_mapping[1] = PCM_CHANNEL_FL;
+		lchannel_mapping[2] = PCM_CHANNEL_FR;
+		lchannel_mapping[3] = PCM_CHANNEL_LB;
+		lchannel_mapping[4] = PCM_CHANNEL_RB;
+		lchannel_mapping[5] = PCM_CHANNEL_LFE;
 	} else if (channels == 8) {
 		lchannel_mapping[0] = PCM_CHANNEL_FL;
 		lchannel_mapping[1] = PCM_CHANNEL_FR;
@@ -1957,6 +2091,13 @@
 	return -EINVAL;
 }
 
+/* Support for selecting stereo mixing coefficients for B family not done */
+int q6asm_cfg_aac_sel_mix_coef(struct audio_client *ac, uint32_t mix_coeff)
+{
+	/* To Be Done */
+	return 0;
+}
+
 int q6asm_enc_cfg_blk_qcelp(struct audio_client *ac, uint32_t frames_per_buf,
 		uint16_t min_rate, uint16_t max_rate,
 		uint16_t reduced_rate_level, uint16_t rate_modulation_cmd)
@@ -2121,8 +2262,9 @@
 	return q6asm_media_format_block_multi_aac(ac, cfg);
 }
 
-int q6asm_media_format_block_pcm(struct audio_client *ac,
-				uint32_t rate, uint32_t channels)
+static int __q6asm_media_format_block_pcm(struct audio_client *ac,
+				uint32_t rate, uint32_t channels,
+				uint16_t bits_per_sample)
 {
 	struct asm_multi_channel_pcm_fmt_blk_v2 fmt;
 	u8 *channel_mapping;
@@ -2137,7 +2279,7 @@
 	fmt.fmt_blk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) -
 					sizeof(fmt.fmt_blk);
 	fmt.num_channels = channels;
-	fmt.bits_per_sample = 16;
+	fmt.bits_per_sample = bits_per_sample;
 	fmt.sample_rate = rate;
 	fmt.is_signed = 1;
 
@@ -2164,6 +2306,92 @@
 	return -EINVAL;
 }
 
+int q6asm_media_format_block_pcm(struct audio_client *ac,
+				uint32_t rate, uint32_t channels)
+{
+	return __q6asm_media_format_block_pcm(ac, rate,
+				channels, 16);
+}
+
+int q6asm_media_format_block_pcm_format_support(struct audio_client *ac,
+				uint32_t rate, uint32_t channels,
+				uint16_t bits_per_sample)
+{
+	return __q6asm_media_format_block_pcm(ac, rate,
+				channels, bits_per_sample);
+}
+
+static int __q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac,
+				uint32_t rate, uint32_t channels,
+				bool use_default_chmap, char *channel_map,
+				uint16_t bits_per_sample)
+{
+	struct asm_multi_channel_pcm_fmt_blk_v2 fmt;
+	u8 *channel_mapping;
+	int rc = 0;
+
+	pr_debug("%s:session[%d]rate[%d]ch[%d]\n", __func__, ac->session, rate,
+		channels);
+
+	q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE);
+
+	fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2;
+	fmt.fmt_blk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) -
+					sizeof(fmt.fmt_blk);
+	fmt.num_channels = channels;
+	fmt.bits_per_sample = 16;
+	fmt.sample_rate = rate;
+	fmt.is_signed = 1;
+
+	channel_mapping = fmt.channel_mapping;
+
+	memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL);
+
+	if (use_default_chmap) {
+		if (q6asm_map_channels(channel_mapping, channels)) {
+			pr_err("%s: map channels failed", __func__);
+			return -EINVAL;
+		}
+	} else {
+		memcpy(channel_mapping, channel_map,
+			 PCM_FORMAT_MAX_NUM_CHANNEL);
+	}
+
+	rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt);
+	if (rc < 0) {
+		pr_err("%s:Comamnd open failed\n", __func__);
+		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 format update\n", __func__);
+		goto fail_cmd;
+	}
+	return 0;
+fail_cmd:
+	return -EINVAL;
+}
+
+int q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac,
+		uint32_t rate, uint32_t channels,
+		bool use_default_chmap, char *channel_map)
+{
+	return __q6asm_media_format_block_multi_ch_pcm(ac, rate,
+			channels, use_default_chmap, channel_map, 16);
+}
+
+int q6asm_media_format_block_multi_ch_pcm_v2(
+		struct audio_client *ac,
+		uint32_t rate, uint32_t channels,
+		bool use_default_chmap, char *channel_map,
+		uint16_t bits_per_sample)
+{
+	return __q6asm_media_format_block_multi_ch_pcm(ac, rate,
+			channels, use_default_chmap, channel_map,
+			bits_per_sample);
+}
+
 int q6asm_media_format_block_multi_aac(struct audio_client *ac,
 				struct asm_aac_cfg *cfg)
 {
@@ -2439,7 +2667,8 @@
 
 
 static int q6asm_memory_map_regions(struct audio_client *ac, int dir,
-				uint32_t bufsz, uint32_t bufcnt)
+				uint32_t bufsz, uint32_t bufcnt,
+				bool is_contiguous)
 {
 	struct avs_cmd_shared_mem_map_regions *mmap_regions = NULL;
 	struct avs_shared_map_region_payload  *mregions = NULL;
@@ -2451,6 +2680,8 @@
 	int	rc = 0;
 	int    i = 0;
 	int	cmd_size = 0;
+	uint32_t bufcnt_t;
+	uint32_t bufsz_t;
 
 	if (!ac || ac->apr == NULL || ac->mmap_apr == NULL) {
 		pr_err("APR handle NULL\n");
@@ -2458,8 +2689,12 @@
 	}
 	pr_debug("%s: Session[%d]\n", __func__, ac->session);
 
+	bufcnt_t = (is_contiguous) ? 1 : bufcnt;
+	bufsz_t = (is_contiguous) ? (bufsz * bufcnt) : bufsz;
+
 	cmd_size = sizeof(struct avs_cmd_shared_mem_map_regions)
-			+ (sizeof(struct avs_shared_map_region_payload));
+			+ (sizeof(struct avs_shared_map_region_payload)
+							* bufcnt_t);
 
 	buffer_node = kzalloc(sizeof(struct asm_buffer_node) * bufcnt,
 				GFP_KERNEL);
@@ -2479,7 +2714,7 @@
 
 	mmap_regions->hdr.opcode = ASM_CMD_SHARED_MEM_MAP_REGIONS;
 	mmap_regions->mem_pool_id = ADSP_MEMORY_MAP_SHMEM8_4K_POOL;
-	mmap_regions->num_regions = 1; /*bufcnt & 0x00ff; */
+	mmap_regions->num_regions = bufcnt_t; /*bufcnt & 0x00ff; */
 	mmap_regions->property_flag = 0x00;
 	pr_debug("map_regions->nregions = %d\n", mmap_regions->num_regions);
 	payload = ((u8 *) mmap_region_cmd +
@@ -2488,11 +2723,14 @@
 
 	ac->port[dir].tmp_hdl = 0;
 	port = &ac->port[dir];
-	ab = &port->buf[0];
-	mregions->shm_addr_lsw = ab->phys;
+	for (i = 0; i < bufcnt_t; i++) {
+		ab = &port->buf[i];
+		mregions->shm_addr_lsw = ab->phys;
 	/* Using only 32 bit address */
-	mregions->shm_addr_msw = 0;
-	mregions->mem_size_bytes = (bufsz * bufcnt);
+		mregions->shm_addr_msw = 0;
+		mregions->mem_size_bytes = bufsz_t;
+		++mregions;
+	}
 
 	rc = apr_send_pkt(ac->mmap_apr, (uint32_t *) mmap_region_cmd);
 	if (rc < 0) {
@@ -3262,18 +3500,18 @@
 	return -EINVAL;
 }
 
-uint64_t q6asm_get_session_time(struct audio_client *ac)
+int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp)
 {
 	struct apr_hdr hdr;
 	int rc;
 
-	if (!ac || ac->apr == NULL) {
-		pr_err("APR handle NULL\n");
+	if (!ac || ac->apr == NULL || tstamp == NULL) {
+		pr_err("APR handle NULL or tstamp NULL\n");
 		return -EINVAL;
 	}
 	q6asm_add_hdr(ac, &hdr, sizeof(hdr), TRUE);
 	hdr.opcode = ASM_SESSION_CMD_GET_SESSIONTIME_V3;
-	atomic_set(&ac->cmd_state, 1);
+	atomic_set(&ac->time_flag, 1);
 
 	pr_debug("%s: session[%d]opcode[0x%x]\n", __func__,
 						ac->session,
@@ -3283,14 +3521,16 @@
 		pr_err("Commmand 0x%x failed\n", hdr.opcode);
 		goto fail_cmd;
 	}
-	rc = wait_event_timeout(ac->cmd_wait,
-			(atomic_read(&ac->cmd_state) == 0), 5*HZ);
+	rc = wait_event_timeout(ac->time_wait,
+			(atomic_read(&ac->time_flag) == 0), 5*HZ);
 	if (!rc) {
 		pr_err("%s: timeout in getting session time from DSP\n",
 			__func__);
 		goto fail_cmd;
 	}
-	return ac->time_stamp;
+
+	*tstamp = ac->time_stamp;
+	return 0;
 
 fail_cmd:
 	return -EINVAL;
@@ -3493,6 +3733,7 @@
 {
 	pr_debug("%s\n", __func__);
 	memset(session, 0, sizeof(session));
+	set_custom_topology = 1;
 
 	config_debug_fs_init();
 
diff --git a/sound/soc/msm/qdsp6v2/q6audio-v2.c b/sound/soc/msm/qdsp6v2/q6audio-v2.c
index 033cb8e..99cb6a6 100644
--- a/sound/soc/msm/qdsp6v2/q6audio-v2.c
+++ b/sound/soc/msm/qdsp6v2/q6audio-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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
@@ -41,6 +41,8 @@
 	case SLIMBUS_0_TX: return IDX_SLIMBUS_0_TX;
 	case SLIMBUS_1_RX: return IDX_SLIMBUS_1_RX;
 	case SLIMBUS_1_TX: return IDX_SLIMBUS_1_TX;
+	case SLIMBUS_2_RX: return IDX_SLIMBUS_2_RX;
+	case SLIMBUS_2_TX: return IDX_SLIMBUS_2_TX;
 	case INT_BT_SCO_RX: return IDX_INT_BT_SCO_RX;
 	case INT_BT_SCO_TX: return IDX_INT_BT_SCO_TX;
 	case INT_BT_A2DP_RX: return IDX_INT_BT_A2DP_RX;
@@ -48,10 +50,17 @@
 	case INT_FM_TX: return IDX_INT_FM_TX;
 	case RT_PROXY_PORT_001_RX: return IDX_RT_PROXY_PORT_001_RX;
 	case RT_PROXY_PORT_001_TX: return IDX_RT_PROXY_PORT_001_TX;
+	case AFE_PORT_ID_PRIMARY_MI2S_RX:
+		return IDX_AFE_PORT_ID_PRIMARY_MI2S_RX;
 	case AFE_PORT_ID_QUATERNARY_MI2S_RX:
 		return IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX;
 	case AFE_PORT_ID_QUATERNARY_MI2S_TX:
 		return IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX;
+	case AFE_PORT_ID_SECONDARY_MI2S_RX:
+		return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX;
+	case AFE_PORT_ID_SECONDARY_MI2S_TX:
+		return IDX_AFE_PORT_ID_SECONDARY_MI2S_TX;
+
 	default: return -EINVAL;
 	}
 }
@@ -78,6 +87,8 @@
 	case SLIMBUS_0_TX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_TX;
 	case SLIMBUS_1_RX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_RX;
 	case SLIMBUS_1_TX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_TX;
+	case SLIMBUS_2_RX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_RX;
+	case SLIMBUS_2_TX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_TX;
 	case INT_BT_SCO_RX: return AFE_PORT_ID_INTERNAL_BT_SCO_RX;
 	case INT_BT_SCO_TX: return AFE_PORT_ID_INTERNAL_BT_SCO_TX;
 	case INT_BT_A2DP_RX: return AFE_PORT_ID_INTERNAL_BT_A2DP_RX;
@@ -85,10 +96,16 @@
 	case INT_FM_TX: return AFE_PORT_ID_INTERNAL_FM_TX;
 	case RT_PROXY_PORT_001_RX: return AFE_PORT_ID_RT_PROXY_PORT_001_RX;
 	case RT_PROXY_PORT_001_TX: return AFE_PORT_ID_RT_PROXY_PORT_001_TX;
+	case AFE_PORT_ID_PRIMARY_MI2S_RX:
+			     return AFE_PORT_ID_PRIMARY_MI2S_RX;
 	case AFE_PORT_ID_QUATERNARY_MI2S_RX:
 			     return AFE_PORT_ID_QUATERNARY_MI2S_RX;
 	case AFE_PORT_ID_QUATERNARY_MI2S_TX:
 			     return AFE_PORT_ID_QUATERNARY_MI2S_TX;
+	case AFE_PORT_ID_SECONDARY_MI2S_RX:
+			     return AFE_PORT_ID_SECONDARY_MI2S_RX;
+	case AFE_PORT_ID_SECONDARY_MI2S_TX:
+			     return AFE_PORT_ID_SECONDARY_MI2S_TX;
 
 	default: return -EINVAL;
 	}
@@ -114,6 +131,31 @@
 	return ret;
 }
 
+int q6audio_is_digital_pcm_interface(u16 port_id)
+{
+	int ret = 0;
+
+	switch (port_id) {
+	case PRIMARY_I2S_RX:
+	case PRIMARY_I2S_TX:
+	case PCM_RX:
+	case PCM_TX:
+	case SECONDARY_I2S_RX:
+	case SECONDARY_I2S_TX:
+	case MI2S_RX:
+	case MI2S_TX:
+	case AFE_PORT_ID_TERTIARY_MI2S_TX:
+	case AFE_PORT_ID_TERTIARY_MI2S_RX:
+	case AFE_PORT_ID_QUATERNARY_MI2S_RX:
+	case AFE_PORT_ID_QUATERNARY_MI2S_TX:
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
 int q6audio_validate_port(u16 port_id)
 {
 	int ret;
@@ -138,6 +180,8 @@
 	case SLIMBUS_0_TX:
 	case SLIMBUS_1_RX:
 	case SLIMBUS_1_TX:
+	case SLIMBUS_2_RX:
+	case SLIMBUS_2_TX:
 	case INT_BT_SCO_RX:
 	case INT_BT_SCO_TX:
 	case INT_BT_A2DP_RX:
@@ -145,8 +189,11 @@
 	case INT_FM_TX:
 	case RT_PROXY_PORT_001_RX:
 	case RT_PROXY_PORT_001_TX:
+	case AFE_PORT_ID_PRIMARY_MI2S_RX:
 	case AFE_PORT_ID_QUATERNARY_MI2S_RX:
 	case AFE_PORT_ID_QUATERNARY_MI2S_TX:
+	case AFE_PORT_ID_SECONDARY_MI2S_RX:
+	case AFE_PORT_ID_SECONDARY_MI2S_TX:
 	{
 		ret = 0;
 		break;
diff --git a/sound/soc/msm/qdsp6v2/q6core.c b/sound/soc/msm/qdsp6v2/q6core.c
index 2c31d39..557b326 100644
--- a/sound/soc/msm/qdsp6v2/q6core.c
+++ b/sound/soc/msm/qdsp6v2/q6core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/sound/soc/msm/qdsp6v2/q6core.h b/sound/soc/msm/qdsp6v2/q6core.h
index 5cb6098..ff611d5 100644
--- a/sound/soc/msm/qdsp6v2/q6core.h
+++ b/sound/soc/msm/qdsp6v2/q6core.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index 349fcf2..12e83b0 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.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
@@ -18,7 +18,6 @@
 #include <linux/mutex.h>
 
 #include <asm/mach-types.h>
-#include <mach/qdsp6v2/audio_acdb.h>
 #include <mach/qdsp6v2/rtac.h>
 #include <mach/socinfo.h>
 #include <mach/qdsp6v2/apr_tal.h>
@@ -26,8 +25,10 @@
 #include "sound/apr_audio-v2.h"
 #include "sound/q6afe-v2.h"
 
+#include "audio_acdb.h"
 #include "q6voice.h"
 
+
 #define TIMEOUT_MS 200
 
 
@@ -157,6 +158,21 @@
 	v->cvp_handle = cvp_handle;
 }
 
+char *voc_get_session_name(u16 session_id)
+{
+	char *session_name = NULL;
+
+	if (session_id == common.voice[VOC_PATH_PASSIVE].session_id) {
+		session_name = VOICE_SESSION_NAME;
+	} else if (session_id ==
+			common.voice[VOC_PATH_VOLTE_PASSIVE].session_id) {
+		session_name = VOLTE_SESSION_NAME;
+	} else if (session_id == common.voice[VOC_PATH_FULL].session_id) {
+		session_name = VOIP_SESSION_NAME;
+	}
+	return session_name;
+}
+
 uint16_t voc_get_session_id(char *name)
 {
 	u16 session_id = 0;
@@ -1022,6 +1038,106 @@
 fail:
 	return -EINVAL;
 }
+
+static int voice_send_dtmf_rx_detection_cmd(struct voice_data *v,
+					    uint32_t enable)
+{
+	int ret = 0;
+	void *apr_cvs;
+	u16 cvs_handle;
+	struct cvs_set_rx_dtmf_detection_cmd cvs_dtmf_rx_detection;
+
+	if (v == NULL) {
+		pr_err("%s: v is NULL\n", __func__);
+		return -EINVAL;
+	}
+	apr_cvs = common.apr_q6_cvs;
+
+	if (!apr_cvs) {
+		pr_err("%s: apr_cvs is NULL.\n", __func__);
+		return -EINVAL;
+	}
+
+	cvs_handle = voice_get_cvs_handle(v);
+
+	/* Set SET_DTMF_RX_DETECTION */
+	cvs_dtmf_rx_detection.hdr.hdr_field =
+				APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+					      APR_HDR_LEN(APR_HDR_SIZE),
+					      APR_PKT_VER);
+	cvs_dtmf_rx_detection.hdr.pkt_size =
+				APR_PKT_SIZE(APR_HDR_SIZE,
+				sizeof(cvs_dtmf_rx_detection) - APR_HDR_SIZE);
+	cvs_dtmf_rx_detection.hdr.src_port = v->session_id;
+	cvs_dtmf_rx_detection.hdr.dest_port = cvs_handle;
+	cvs_dtmf_rx_detection.hdr.token = 0;
+	cvs_dtmf_rx_detection.hdr.opcode =
+					VSS_ISTREAM_CMD_SET_RX_DTMF_DETECTION;
+	cvs_dtmf_rx_detection.cvs_dtmf_det.enable = enable;
+
+	v->cvs_state = CMD_STATUS_FAIL;
+
+	ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_dtmf_rx_detection);
+	if (ret < 0) {
+		pr_err("%s: Error %d sending SET_DTMF_RX_DETECTION\n",
+		       __func__,
+		       ret);
+		return -EINVAL;
+	}
+
+	ret = wait_event_timeout(v->cvs_wait,
+				 (v->cvs_state == CMD_STATUS_SUCCESS),
+				 msecs_to_jiffies(TIMEOUT_MS));
+
+	if (!ret) {
+		pr_err("%s: wait_event timeout\n", __func__);
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+void voc_disable_dtmf_det_on_active_sessions(void)
+{
+	struct voice_data *v = NULL;
+	int i;
+	for (i = 0; i < MAX_VOC_SESSIONS; i++) {
+		v = &common.voice[i];
+		if ((v->dtmf_rx_detect_en) &&
+			((v->voc_state == VOC_RUN) ||
+			 (v->voc_state == VOC_CHANGE) ||
+			 (v->voc_state == VOC_STANDBY))) {
+			pr_debug("disable dtmf det on ses_id=%d\n",
+				 v->session_id);
+			voice_send_dtmf_rx_detection_cmd(v, 0);
+		}
+	}
+}
+
+int voc_enable_dtmf_rx_detection(uint16_t session_id, uint32_t enable)
+{
+	struct voice_data *v = voice_get_session(session_id);
+	int ret = 0;
+
+	if (v == NULL) {
+		pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
+		return -EINVAL;
+	}
+
+	mutex_lock(&v->lock);
+	v->dtmf_rx_detect_en = enable;
+
+	if ((v->voc_state == VOC_RUN) ||
+	    (v->voc_state == VOC_CHANGE) ||
+	    (v->voc_state == VOC_STANDBY))
+		ret = voice_send_dtmf_rx_detection_cmd(v,
+						       v->dtmf_rx_detect_en);
+
+	mutex_unlock(&v->lock);
+
+	return ret;
+}
+
 static int voice_config_cvs_vocoder(struct voice_data *v)
 {
 	int ret = 0;
@@ -1456,7 +1572,7 @@
 		goto fail;
 	}
 
-	get_all_vocstrm_cal(&cal_block);
+	get_vocstrm_cal(&cal_block);
 	if (cal_block.cal_size == 0) {
 		pr_err("%s: CVS cal size is 0\n", __func__);
 
@@ -1524,7 +1640,7 @@
 		goto fail;
 	}
 
-	get_all_vocstrm_cal(&cal_block);
+	get_vocstrm_cal(&cal_block);
 	if (cal_block.cal_size == 0)
 		return 0;
 
@@ -1714,7 +1830,7 @@
 		goto fail;
 	}
 
-	get_all_vocproc_cal(&cal_block);
+	get_vocproc_cal(&cal_block);
 	if (cal_block.cal_size == 0) {
 		pr_err("%s: CVP cal size is 0\n", __func__);
 
@@ -1782,7 +1898,7 @@
 		goto fail;
 	}
 
-	get_all_vocproc_cal(&cal_block);
+	get_vocproc_cal(&cal_block);
 	if (cal_block.cal_size == 0)
 		return 0;
 
@@ -1843,7 +1959,7 @@
 		goto fail;
 	}
 
-	get_all_vocvol_cal(&cal_block);
+	get_vocvol_cal(&cal_block);
 	if (cal_block.cal_size == 0) {
 		pr_err("%s: CVP vol cal size is 0\n", __func__);
 
@@ -1914,7 +2030,7 @@
 		goto fail;
 	}
 
-	get_all_vocvol_cal(&cal_block);
+	get_vocvol_cal(&cal_block);
 	if (cal_block.cal_size == 0)
 		return 0;
 
@@ -2217,6 +2333,9 @@
 	if (v->rec_info.rec_enable)
 		voice_cvs_start_record(v, v->rec_info.rec_mode);
 
+	if (v->dtmf_rx_detect_en)
+		voice_send_dtmf_rx_detection_cmd(v, v->dtmf_rx_detect_en);
+
 	rtac_add_voice(voice_get_cvs_handle(v),
 		voice_get_cvp_handle(v),
 		v->dev_rx.port_id, v->dev_tx.port_id,
@@ -2510,6 +2629,10 @@
 	/* send stop voice cmd */
 	voice_send_stop_voice_cmd(v);
 
+	/* send stop dtmf detecton cmd */
+	if (v->dtmf_rx_detect_en)
+		voice_send_dtmf_rx_detection_cmd(v, 0);
+
 	/* detach VOCPROC and wait for response from mvm */
 	mvm_d_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
 						APR_HDR_LEN(APR_HDR_SIZE),
@@ -2642,13 +2765,14 @@
 	uint64_t *enc_buf;
 	void *apr_cvs;
 	u16 cvs_handle;
-	dec_buf = (uint64_t *)v->shmem_info.sh_buf.buf[0].phys;
-	enc_buf = (uint64_t *)v->shmem_info.sh_buf.buf[1].phys;
 
 	if (v == NULL) {
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
 	}
+	dec_buf = (uint64_t *)v->shmem_info.sh_buf.buf[0].phys;
+	enc_buf = (uint64_t *)v->shmem_info.sh_buf.buf[1].phys;
+
 	apr_cvs = common.apr_q6_cvs;
 
 	if (!apr_cvs) {
@@ -3157,7 +3281,7 @@
 static int voice_cvs_start_playback(struct voice_data *v)
 {
 	int ret = 0;
-	struct apr_hdr cvs_start_playback;
+	struct cvs_start_playback_cmd cvs_start_playback;
 	void *apr_cvs;
 	u16 cvs_handle;
 
@@ -3175,17 +3299,18 @@
 	cvs_handle = voice_get_cvs_handle(v);
 
 	if (!v->music_info.playing && v->music_info.count) {
-		cvs_start_playback.hdr_field = APR_HDR_FIELD(
+		cvs_start_playback.hdr.hdr_field = APR_HDR_FIELD(
 					APR_MSG_TYPE_SEQ_CMD,
 					APR_HDR_LEN(APR_HDR_SIZE),
 					APR_PKT_VER);
-		cvs_start_playback.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+		cvs_start_playback.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(cvs_start_playback) - APR_HDR_SIZE);
-		cvs_start_playback.src_port = v->session_id;
-		cvs_start_playback.dest_port = cvs_handle;
-		cvs_start_playback.token = 0;
-		cvs_start_playback.opcode = VSS_ISTREAM_CMD_START_PLAYBACK;
-
+		cvs_start_playback.hdr.src_port = v->session_id;
+		cvs_start_playback.hdr.dest_port = cvs_handle;
+		cvs_start_playback.hdr.token = 0;
+		cvs_start_playback.hdr.opcode = VSS_IPLAYBACK_CMD_START;
+		cvs_start_playback.playback_mode.port_id =
+						VSS_IPLAYBACK_PORT_ID_DEFAULT;
 		v->cvs_state = CMD_STATUS_FAIL;
 
 		ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_playback);
@@ -3248,7 +3373,7 @@
 		cvs_stop_playback.dest_port = cvs_handle;
 		cvs_stop_playback.token = 0;
 
-		cvs_stop_playback.opcode = VSS_ISTREAM_CMD_STOP_PLAYBACK;
+		cvs_stop_playback.opcode = VSS_IPLAYBACK_CMD_STOP;
 
 		v->cvs_state = CMD_STATUS_FAIL;
 
@@ -3935,6 +4060,13 @@
 	common.mvs_info.private_data = private_data;
 }
 
+void voc_register_dtmf_rx_detection_cb(dtmf_rx_det_cb_fn dtmf_rx_ul_cb,
+				       void *private_data)
+{
+	common.dtmf_info.dtmf_rx_ul_cb = dtmf_rx_ul_cb;
+	common.dtmf_info.private_data = private_data;
+}
+
 void voc_config_vocoder(uint32_t media_type,
 			  uint32_t rate,
 			  uint32_t network_type,
@@ -4004,7 +4136,7 @@
 		if (data->payload_size) {
 			ptr = data->payload;
 
-			pr_info("%x %x\n", ptr[0], ptr[1]);
+			pr_debug("%x %x\n", ptr[0], ptr[1]);
 			/* ping mvm service ACK */
 			switch (ptr[0]) {
 			case VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION:
@@ -4136,7 +4268,7 @@
 		if (data->payload_size) {
 			ptr = data->payload;
 
-			pr_info("%x %x\n", ptr[0], ptr[1]);
+			pr_debug("%x %x\n", ptr[0], ptr[1]);
 			if (ptr[1] != 0) {
 				pr_err("%s: cmd = 0x%x returned error = 0x%x\n",
 					__func__, ptr[0], ptr[1]);
@@ -4166,12 +4298,13 @@
 			case VSS_ICOMMON_CMD_MAP_MEMORY:
 			case VSS_ICOMMON_CMD_UNMAP_MEMORY:
 			case VSS_ICOMMON_CMD_SET_UI_PROPERTY:
-			case VSS_ISTREAM_CMD_START_PLAYBACK:
-			case VSS_ISTREAM_CMD_STOP_PLAYBACK:
+			case VSS_IPLAYBACK_CMD_START:
+			case VSS_IPLAYBACK_CMD_STOP:
 			case VSS_IRECORD_CMD_START:
 			case VSS_IRECORD_CMD_STOP:
 			case VSS_ISTREAM_CMD_SET_PACKET_EXCHANGE_MODE:
 			case VSS_ISTREAM_CMD_SET_OOB_PACKET_EXCHANGE_CONFIG:
+			case VSS_ISTREAM_CMD_SET_RX_DTMF_DETECTION:
 				pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
 				v->cvs_state = CMD_STATUS_SUCCESS;
 				wake_up(&v->cvs_wait);
@@ -4319,8 +4452,29 @@
 		}
 		rtac_make_voice_callback(RTAC_CVS, data->payload,
 					data->payload_size);
+	}  else if (data->opcode == VSS_ISTREAM_EVT_RX_DTMF_DETECTED) {
+		struct vss_istream_evt_rx_dtmf_detected *dtmf_rx_detected;
+		uint32_t *voc_pkt = data->payload;
+		uint32_t pkt_len = data->payload_size;
+
+		if ((voc_pkt != NULL) &&
+		    (pkt_len ==
+			sizeof(struct vss_istream_evt_rx_dtmf_detected))) {
+
+			dtmf_rx_detected =
+			(struct vss_istream_evt_rx_dtmf_detected *) voc_pkt;
+			pr_debug("RX_DTMF_DETECTED low_freq=%d high_freq=%d\n",
+				 dtmf_rx_detected->low_freq,
+				 dtmf_rx_detected->high_freq);
+			if (c->dtmf_info.dtmf_rx_ul_cb)
+				c->dtmf_info.dtmf_rx_ul_cb((uint8_t *)voc_pkt,
+					voc_get_session_name(v->session_id),
+					c->dtmf_info.private_data);
+		} else {
+			pr_err("Invalid packet\n");
+		}
 	}  else
-		pr_err("Unknown opcode 0x%x\n", data->opcode);
+		pr_debug("Unknown opcode 0x%x\n", data->opcode);
 
 fail:
 	return 0;
@@ -4379,7 +4533,7 @@
 		if (data->payload_size) {
 			ptr = data->payload;
 
-			pr_info("%x %x\n", ptr[0], ptr[1]);
+			pr_debug("%x %x\n", ptr[0], ptr[1]);
 			if (ptr[1] != 0) {
 				pr_err("%s: cmd = 0x%x returned error = 0x%x\n",
 					__func__, ptr[0], ptr[1]);
@@ -4465,6 +4619,10 @@
 	struct voice_data *v = voice_get_session(
 				common.voice[VOC_PATH_FULL].session_id);
 
+	if (v == NULL) {
+		pr_err("%s: v is NULL\n", __func__);
+		return -EINVAL;
+	}
 	v->shmem_info.sh_buf.client = msm_ion_client_create(UINT_MAX,
 							    "voip_client");
 	if (IS_ERR_OR_NULL((void *)v->shmem_info.sh_buf.client)) {
@@ -4533,6 +4691,10 @@
 	struct voice_data *v = voice_get_session(
 				common.voice[VOC_PATH_FULL].session_id);
 
+	if (v == NULL) {
+		pr_err("%s: v is NULL\n", __func__);
+		return -EINVAL;
+	}
 	v->shmem_info.memtbl.client = msm_ion_client_create(UINT_MAX,
 							      "voip_client");
 	if (IS_ERR_OR_NULL((void *)v->shmem_info.memtbl.client)) {
@@ -4680,6 +4842,7 @@
 		common.voice[i].dev_tx.port_id = 0x100B;
 		common.voice[i].dev_rx.port_id = 0x100A;
 		common.voice[i].sidetone_gain = 0x512;
+		common.voice[i].dtmf_rx_detect_en = 0;
 
 		common.voice[i].voc_state = VOC_INIT;
 
diff --git a/sound/soc/msm/qdsp6v2/q6voice.h b/sound/soc/msm/qdsp6v2/q6voice.h
index d19697a..98bd002 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.h
+++ b/sound/soc/msm/qdsp6v2/q6voice.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
@@ -489,12 +489,15 @@
 #define VOICE_PARAM_MOD_ENABLE				0x00010E00
 #define MOD_ENABLE_PARAM_LEN				4
 
-#define VSS_ISTREAM_CMD_START_PLAYBACK                  0x00011238
+#define VSS_IPLAYBACK_CMD_START				0x000112BD
 /* Start in-call music delivery on the Tx voice path. */
 
-#define VSS_ISTREAM_CMD_STOP_PLAYBACK                   0x00011239
+#define VSS_IPLAYBACK_CMD_STOP				0x00011239
 /* Stop the in-call music delivery on the Tx voice path. */
 
+#define VSS_IPLAYBACK_PORT_ID_DEFAULT			0x0000FFFF
+/* Default AFE port ID. */
+
 #define VSS_IRECORD_CMD_START				0x000112BE
 /* Start in-call conversation recording. */
 #define VSS_IRECORD_CMD_STOP				0x00011237
@@ -538,6 +541,15 @@
 
 #define VSS_ISTREAM_CMD_SET_PACKET_EXCHANGE_MODE	0x0001136A
 
+struct vss_iplayback_cmd_start_t {
+	uint16_t port_id;
+	/*
+	 * AFE Port ID from which the audio samples are available.
+	 * To use the default AFE pseudo port (0x8005), set this value to
+	 * #VSS_IPLAYBACK_PORT_ID_DEFAULT.
+	 */
+}  __packed;
+
 struct vss_irecord_cmd_start_t {
 	uint32_t rx_tap_point;
 	/* Tap point to use on the Rx path. Supported values are:
@@ -741,6 +753,56 @@
 	/* Reserved, set to 0. */
 };
 
+/*
+ * Event sent by the stream to the client that enables Rx DTMF
+ * detection whenever DTMF is detected in the Rx path.
+ *
+ * The DTMF detection feature can only be used to detect DTMF
+ * frequencies as listed in the vss_istream_evt_rx_dtmf_detected_t
+ * structure.
+ */
+
+#define VSS_ISTREAM_EVT_RX_DTMF_DETECTED (0x0001101A)
+
+struct vss_istream_cmd_set_rx_dtmf_detection {
+	/*
+	 * Enables/disables Rx DTMF detection
+	 *
+	 * Possible values are
+	 * 0 - disable
+	 * 1 - enable
+	 *
+	 */
+	uint32_t enable;
+};
+
+#define VSS_ISTREAM_CMD_SET_RX_DTMF_DETECTION (0x00011027)
+
+struct vss_istream_evt_rx_dtmf_detected {
+	uint16_t low_freq;
+	/*
+	 * Detected low frequency. Possible values:
+	 * 697 Hz
+	 * 770 Hz
+	 * 852 Hz
+	 * 941 Hz
+	 */
+	uint16_t high_freq;
+	/*
+	 * Detected high frequency. Possible values:
+	 * 1209 Hz
+	 * 1336 Hz
+	 * 1477 Hz
+	 * 1633 Hz
+	 */
+};
+
+struct cvs_set_rx_dtmf_detection_cmd {
+	struct apr_hdr hdr;
+	struct vss_istream_cmd_set_rx_dtmf_detection cvs_dtmf_det;
+} __packed;
+
+
 struct cvs_create_passive_ctl_session_cmd {
 	struct apr_hdr hdr;
 	struct vss_istream_cmd_create_passive_control_session_t cvs_session;
@@ -808,6 +870,11 @@
 	struct vss_irecord_cmd_start_t rec_mode;
 } __packed;
 
+struct cvs_start_playback_cmd {
+	struct apr_hdr hdr;
+	struct vss_iplayback_cmd_start_t playback_mode;
+} __packed;
+
 struct cvs_dec_buffer_ready_cmd {
 	struct apr_hdr hdr;
 } __packed;
@@ -1114,6 +1181,10 @@
 typedef void (*dl_cb_fn)(uint8_t *voc_pkt,
 			 void *private_data);
 
+/* CB for DTMF RX Detection */
+typedef void (*dtmf_rx_det_cb_fn)(uint8_t *pkt,
+				  char *session,
+				  void *private_data);
 
 struct mvs_driver_info {
 	uint32_t media_type;
@@ -1125,6 +1196,11 @@
 	void *private_data;
 };
 
+struct dtmf_driver_info {
+	dtmf_rx_det_cb_fn dtmf_rx_ul_cb;
+	void *private_data;
+};
+
 struct incall_rec_info {
 	uint32_t rec_enable;
 	uint32_t rec_mode;
@@ -1180,6 +1256,8 @@
 	/* FENC enable value */
 	uint32_t fens_enable;
 
+	uint32_t dtmf_rx_detect_en;
+
 	struct voice_dev_route_state voc_route_state;
 
 	u16 session_id;
@@ -1222,6 +1300,8 @@
 
 	struct mvs_driver_info mvs_info;
 
+	struct dtmf_driver_info dtmf_info;
+
 	struct voice_data voice[MAX_VOC_SESSIONS];
 };
 
@@ -1229,6 +1309,9 @@
 			dl_cb_fn dl_cb,
 			void *private_data);
 
+void voc_register_dtmf_rx_detection_cb(dtmf_rx_det_cb_fn dtmf_rx_ul_cb,
+				       void *private_data);
+
 void voc_config_vocoder(uint32_t media_type,
 			uint32_t rate,
 			uint32_t network_type,
@@ -1267,7 +1350,10 @@
 int voc_enable_cvp(uint16_t session_id);
 int voc_set_route_flag(uint16_t session_id, uint8_t path_dir, uint8_t set);
 uint8_t voc_get_route_flag(uint16_t session_id, uint8_t path_dir);
+int voc_enable_dtmf_rx_detection(uint16_t session_id, uint32_t enable);
+void voc_disable_dtmf_det_on_active_sessions(void);
 
+#define MAX_SESSION_NAME_LEN 32
 #define VOICE_SESSION_NAME "Voice session"
 #define VOIP_SESSION_NAME "VoIP session"
 #define VOLTE_SESSION_NAME "VoLTE session"
diff --git a/sound/soc/msm/qdsp6v2/rtac.c b/sound/soc/msm/qdsp6v2/rtac.c
new file mode 100644
index 0000000..1f2a487
--- /dev/null
+++ b/sound/soc/msm/qdsp6v2/rtac.c
@@ -0,0 +1,1049 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/miscdevice.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/msm_audio_acdb.h>
+#include <linux/atomic.h>
+#include <mach/qdsp6v2/rtac.h>
+#include <sound/q6asm-v2.h>
+#include <sound/q6afe-v2.h>
+#include <sound/apr_audio-v2.h>
+
+#include "audio_acdb.h"
+
+
+#ifndef CONFIG_RTAC
+
+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_popp_from_adm_devices(u32 popp_id) {}
+void rtac_set_adm_handle(void *handle) {}
+bool rtac_make_adm_callback(uint32_t *payload, u32 payload_size)
+	{return false; }
+void rtac_set_asm_handle(u32 session_id, void *handle) {}
+bool rtac_make_asm_callback(u32 session_id, uint32_t *payload,
+	u32 payload_size) {return false; }
+void rtac_add_voice(u32 cvs_handle, u32 cvp_handle, u32 rx_afe_port,
+	u32 tx_afe_port, u32 session_id) {}
+void rtac_remove_voice(u32 cvs_handle) {}
+void rtac_set_voice_handle(u32 mode, void *handle) {}
+bool rtac_make_voice_callback(u32 mode, uint32_t *payload,
+		u32 payload_size) {return false; }
+
+#else
+
+/* Max size of payload (buf size - apr header) */
+#define MAX_PAYLOAD_SIZE		4076
+#define RTAC_MAX_ACTIVE_DEVICES		4
+#define RTAC_MAX_ACTIVE_VOICE_COMBOS	2
+#define RTAC_MAX_ACTIVE_POPP		8
+#define RTAC_BUF_SIZE			4096
+
+#define TIMEOUT_MS	1000
+
+/* APR data */
+struct rtac_apr_data {
+	void			*apr_handle;
+	atomic_t		cmd_state;
+	wait_queue_head_t	cmd_wait;
+};
+
+static struct rtac_apr_data	rtac_adm_apr_data;
+static struct rtac_apr_data	rtac_asm_apr_data[SESSION_MAX+1];
+static struct rtac_apr_data	rtac_voice_apr_data[RTAC_VOICE_MODES];
+
+
+/* ADM info & APR */
+struct rtac_adm_data {
+	uint32_t	topology_id;
+	uint32_t	afe_port;
+	uint32_t	copp;
+	uint32_t	num_of_popp;
+	uint32_t	popp[RTAC_MAX_ACTIVE_POPP];
+};
+
+struct rtac_adm {
+	uint32_t		num_of_dev;
+	struct rtac_adm_data	device[RTAC_MAX_ACTIVE_DEVICES];
+};
+static struct rtac_adm		rtac_adm_data;
+static u32			rtac_adm_payload_size;
+static u32			rtac_adm_user_buf_size;
+static u8			*rtac_adm_buffer;
+
+
+/* ASM APR */
+static u32			rtac_asm_payload_size;
+static u32			rtac_asm_user_buf_size;
+static u8			*rtac_asm_buffer;
+
+
+/* Voice info & APR */
+struct rtac_voice_data {
+	uint32_t	tx_topology_id;
+	uint32_t	rx_topology_id;
+	uint32_t	tx_afe_port;
+	uint32_t	rx_afe_port;
+	uint16_t	cvs_handle;
+	uint16_t	cvp_handle;
+};
+
+struct rtac_voice {
+	uint32_t		num_of_voice_combos;
+	struct rtac_voice_data	voice[RTAC_MAX_ACTIVE_VOICE_COMBOS];
+};
+
+static struct rtac_voice	rtac_voice_data;
+static u32			rtac_voice_payload_size;
+static u32			rtac_voice_user_buf_size;
+static u8			*rtac_voice_buffer;
+static u32			voice_session_id[RTAC_MAX_ACTIVE_VOICE_COMBOS];
+
+
+struct mutex			rtac_adm_mutex;
+struct mutex			rtac_adm_apr_mutex;
+struct mutex			rtac_asm_apr_mutex;
+struct mutex			rtac_voice_mutex;
+struct mutex			rtac_voice_apr_mutex;
+
+static int rtac_open(struct inode *inode, struct file *f)
+{
+	pr_debug("%s\n", __func__);
+	return 0;
+}
+
+static int rtac_release(struct inode *inode, struct file *f)
+{
+	pr_debug("%s\n", __func__);
+	return 0;
+}
+
+/* ADM Info */
+void add_popp(u32 dev_idx, u32 port_id, u32 popp_id)
+{
+	u32 i = 0;
+
+	for (; i < rtac_adm_data.device[dev_idx].num_of_popp; i++)
+		if (rtac_adm_data.device[dev_idx].popp[i] == popp_id)
+			goto done;
+
+	if (rtac_adm_data.device[dev_idx].num_of_popp ==
+			RTAC_MAX_ACTIVE_POPP) {
+		pr_err("%s, Max POPP!\n", __func__);
+		goto done;
+	}
+	rtac_adm_data.device[dev_idx].popp[
+		rtac_adm_data.device[dev_idx].num_of_popp++] = popp_id;
+done:
+	return;
+}
+
+void rtac_add_adm_device(u32 port_id, u32 copp_id, u32 path_id, u32 popp_id)
+{
+	u32 i = 0;
+	pr_debug("%s: port_id = %d, popp_id = %d\n", __func__, port_id,
+		popp_id);
+
+	mutex_lock(&rtac_adm_mutex);
+	if (rtac_adm_data.num_of_dev == RTAC_MAX_ACTIVE_DEVICES) {
+		pr_err("%s, Can't add anymore RTAC devices!\n", __func__);
+		goto done;
+	}
+
+	/* 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) {
+				add_popp(i, port_id, popp_id);
+				goto done;
+			}
+			if (rtac_adm_data.device[i].num_of_popp ==
+						RTAC_MAX_ACTIVE_POPP) {
+				pr_err("%s, Max POPP!\n", __func__);
+				goto done;
+			}
+		}
+	}
+
+	/* Add device */
+	rtac_adm_data.num_of_dev++;
+
+	if (path_id == ADM_PATH_PLAYBACK)
+		rtac_adm_data.device[i].topology_id =
+						get_adm_rx_topology();
+	else
+		rtac_adm_data.device[i].topology_id =
+						get_adm_tx_topology();
+	rtac_adm_data.device[i].afe_port = port_id;
+	rtac_adm_data.device[i].copp = copp_id;
+	rtac_adm_data.device[i].popp[
+		rtac_adm_data.device[i].num_of_popp++] = popp_id;
+done:
+	mutex_unlock(&rtac_adm_mutex);
+	return;
+}
+
+static void shift_adm_devices(u32 dev_idx)
+{
+	for (; dev_idx < rtac_adm_data.num_of_dev; dev_idx++) {
+		memcpy(&rtac_adm_data.device[dev_idx],
+			&rtac_adm_data.device[dev_idx + 1],
+			sizeof(rtac_adm_data.device[dev_idx]));
+		memset(&rtac_adm_data.device[dev_idx + 1], 0,
+			   sizeof(rtac_adm_data.device[dev_idx]));
+	}
+}
+
+static void shift_popp(u32 copp_idx, u32 popp_idx)
+{
+	for (; popp_idx < rtac_adm_data.device[copp_idx].num_of_popp;
+							popp_idx++) {
+		memcpy(&rtac_adm_data.device[copp_idx].popp[popp_idx],
+			&rtac_adm_data.device[copp_idx].popp[popp_idx + 1],
+			sizeof(uint32_t));
+		memset(&rtac_adm_data.device[copp_idx].popp[popp_idx + 1], 0,
+			   sizeof(uint32_t));
+	}
+}
+
+void rtac_remove_adm_device(u32 port_id)
+{
+	s32 i;
+	pr_debug("%s: port_id = %d\n", __func__, port_id);
+
+	mutex_lock(&rtac_adm_mutex);
+	/* look for device */
+	for (i = 0; i < rtac_adm_data.num_of_dev; i++) {
+		if (rtac_adm_data.device[i].afe_port == port_id) {
+			memset(&rtac_adm_data.device[i], 0,
+				   sizeof(rtac_adm_data.device[i]));
+			rtac_adm_data.num_of_dev--;
+
+			if (rtac_adm_data.num_of_dev >= 1) {
+				shift_adm_devices(i);
+				break;
+			}
+		}
+	}
+
+	mutex_unlock(&rtac_adm_mutex);
+	return;
+}
+
+void rtac_remove_popp_from_adm_devices(u32 popp_id)
+{
+	s32 i, j;
+	pr_debug("%s: popp_id = %d\n", __func__, popp_id);
+
+	mutex_lock(&rtac_adm_mutex);
+
+	for (i = 0; i < rtac_adm_data.num_of_dev; i++) {
+		for (j = 0; j < rtac_adm_data.device[i].num_of_popp; j++) {
+			if (rtac_adm_data.device[i].popp[j] == popp_id) {
+				rtac_adm_data.device[i].popp[j] = 0;
+				rtac_adm_data.device[i].num_of_popp--;
+				shift_popp(i, j);
+			}
+		}
+	}
+
+	mutex_unlock(&rtac_adm_mutex);
+}
+
+/* Voice Info */
+static void set_rtac_voice_data(int idx, u32 cvs_handle, u32 cvp_handle,
+					u32 rx_afe_port, u32 tx_afe_port,
+					u32 session_id)
+{
+	rtac_voice_data.voice[idx].tx_topology_id = get_voice_tx_topology();
+	rtac_voice_data.voice[idx].rx_topology_id = get_voice_rx_topology();
+	rtac_voice_data.voice[idx].tx_afe_port = tx_afe_port;
+	rtac_voice_data.voice[idx].rx_afe_port = rx_afe_port;
+	rtac_voice_data.voice[idx].cvs_handle = cvs_handle;
+	rtac_voice_data.voice[idx].cvp_handle = cvp_handle;
+
+	/* Store session ID for voice RTAC */
+	voice_session_id[idx] = session_id;
+}
+
+void rtac_add_voice(u32 cvs_handle, u32 cvp_handle, u32 rx_afe_port,
+			u32 tx_afe_port, u32 session_id)
+{
+	u32 i = 0;
+	pr_debug("%s\n", __func__);
+	mutex_lock(&rtac_voice_mutex);
+
+	if (rtac_voice_data.num_of_voice_combos ==
+			RTAC_MAX_ACTIVE_VOICE_COMBOS) {
+		pr_err("%s, Can't add anymore RTAC devices!\n", __func__);
+		goto done;
+	}
+
+	/* Check if device already added */
+	if (rtac_voice_data.num_of_voice_combos != 0) {
+		for (; i < rtac_voice_data.num_of_voice_combos; i++) {
+			if (rtac_voice_data.voice[i].cvs_handle ==
+							cvs_handle) {
+				set_rtac_voice_data(i, cvs_handle, cvp_handle,
+					rx_afe_port, tx_afe_port,
+					session_id);
+				goto done;
+			}
+		}
+	}
+
+	/* Add device */
+	rtac_voice_data.num_of_voice_combos++;
+	set_rtac_voice_data(i, cvs_handle, cvp_handle,
+				rx_afe_port, tx_afe_port,
+				session_id);
+done:
+	mutex_unlock(&rtac_voice_mutex);
+	return;
+}
+
+static void shift_voice_devices(u32 idx)
+{
+	for (; idx < rtac_voice_data.num_of_voice_combos - 1; idx++) {
+		memcpy(&rtac_voice_data.voice[idx],
+			&rtac_voice_data.voice[idx + 1],
+			sizeof(rtac_voice_data.voice[idx]));
+		voice_session_id[idx] = voice_session_id[idx + 1];
+	}
+}
+
+void rtac_remove_voice(u32 cvs_handle)
+{
+	u32 i = 0;
+	pr_debug("%s\n", __func__);
+
+	mutex_lock(&rtac_voice_mutex);
+	/* look for device */
+	for (i = 0; i < rtac_voice_data.num_of_voice_combos; i++) {
+		if (rtac_voice_data.voice[i].cvs_handle == cvs_handle) {
+			shift_voice_devices(i);
+			rtac_voice_data.num_of_voice_combos--;
+			memset(&rtac_voice_data.voice[
+				rtac_voice_data.num_of_voice_combos], 0,
+				sizeof(rtac_voice_data.voice
+				[rtac_voice_data.num_of_voice_combos]));
+			voice_session_id[rtac_voice_data.num_of_voice_combos]
+				= 0;
+			break;
+		}
+	}
+	mutex_unlock(&rtac_voice_mutex);
+	return;
+}
+
+static int get_voice_index_cvs(u32 cvs_handle)
+{
+	u32 i;
+
+	for (i = 0; i < rtac_voice_data.num_of_voice_combos; i++) {
+		if (rtac_voice_data.voice[i].cvs_handle == cvs_handle)
+			return i;
+	}
+
+	pr_err("%s: No voice index for CVS handle %d found returning 0\n",
+	       __func__, cvs_handle);
+	return 0;
+}
+
+static int get_voice_index_cvp(u32 cvp_handle)
+{
+	u32 i;
+
+	for (i = 0; i < rtac_voice_data.num_of_voice_combos; i++) {
+		if (rtac_voice_data.voice[i].cvp_handle == cvp_handle)
+			return i;
+	}
+
+	pr_err("%s: No voice index for CVP handle %d found returning 0\n",
+	       __func__, cvp_handle);
+	return 0;
+}
+
+static int get_voice_index(u32 mode, u32 handle)
+{
+	if (mode == RTAC_CVP)
+		return get_voice_index_cvp(handle);
+	if (mode == RTAC_CVS)
+		return get_voice_index_cvs(handle);
+
+	pr_err("%s: Invalid mode %d, returning 0\n",
+	       __func__, mode);
+	return 0;
+}
+
+
+/* ADM APR */
+void rtac_set_adm_handle(void *handle)
+{
+	pr_debug("%s: handle = %d\n", __func__, (unsigned int)handle);
+
+	mutex_lock(&rtac_adm_apr_mutex);
+	rtac_adm_apr_data.apr_handle = handle;
+	mutex_unlock(&rtac_adm_apr_mutex);
+}
+
+bool rtac_make_adm_callback(uint32_t *payload, u32 payload_size)
+{
+	pr_debug("%s:cmd_state = %d\n", __func__,
+			atomic_read(&rtac_adm_apr_data.cmd_state));
+	if (atomic_read(&rtac_adm_apr_data.cmd_state) != 1)
+		return false;
+
+	/* Offset data for in-band payload */
+	rtac_copy_adm_payload_to_user(payload, payload_size);
+	atomic_set(&rtac_adm_apr_data.cmd_state, 0);
+	wake_up(&rtac_adm_apr_data.cmd_wait);
+	return true;
+}
+
+void rtac_copy_adm_payload_to_user(void *payload, u32 payload_size)
+{
+	pr_debug("%s\n", __func__);
+	rtac_adm_payload_size = payload_size;
+
+	memcpy(rtac_adm_buffer, &payload_size, sizeof(u32));
+	if (payload_size != 0) {
+		if (payload_size > rtac_adm_user_buf_size) {
+			pr_err("%s: Buffer set not big enough for returned data, buf size = %d, ret data = %d\n",
+			 __func__, rtac_adm_user_buf_size, payload_size);
+			rtac_adm_payload_size = 0;
+			goto done;
+		}
+		memcpy(rtac_adm_buffer + sizeof(u32), payload, payload_size);
+	}
+done:
+	return;
+}
+
+u32 send_adm_apr(void *buf, u32 opcode)
+{
+	s32	result;
+	u32	count = 0;
+	u32	bytes_returned = 0;
+	u32	port_index = 0;
+	u32	copp_id;
+	u32	payload_size;
+	struct apr_hdr	adm_params;
+	pr_debug("%s\n", __func__);
+
+	if (copy_from_user(&count, (void *)buf, sizeof(count))) {
+		pr_err("%s: Copy to user failed! buf = 0x%x\n",
+		       __func__, (unsigned int)buf);
+		result = -EFAULT;
+		goto done;
+	}
+
+	if (count <= 0) {
+		pr_err("%s: Invalid buffer size = %d\n", __func__, count);
+		goto done;
+	}
+
+	if (copy_from_user(&payload_size, buf + sizeof(u32), sizeof(u32))) {
+		pr_err("%s: Could not copy payload size from user buffer\n",
+			__func__);
+		goto done;
+	}
+
+
+	if (payload_size > MAX_PAYLOAD_SIZE) {
+		pr_err("%s: Invalid payload size = %d\n",
+			__func__, payload_size);
+		goto done;
+	}
+
+	if (copy_from_user(&copp_id, buf + 2 * sizeof(u32), sizeof(u32))) {
+		pr_err("%s: Could not copy port id from user buffer\n",
+			__func__);
+		goto done;
+	}
+
+	for (port_index = 0; port_index < AFE_MAX_PORTS; port_index++) {
+		if (adm_get_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",
+		       __func__, copp_id);
+		goto done;
+	}
+
+	mutex_lock(&rtac_adm_apr_mutex);
+	if (rtac_adm_apr_data.apr_handle == NULL) {
+		pr_err("%s: APR not initialized\n", __func__);
+		goto err;
+	}
+
+	/* Set globals for copy of returned payload */
+	rtac_adm_user_buf_size = count;
+
+	/* Copy buffer to in-band payload */
+	if (copy_from_user(rtac_adm_buffer + sizeof(adm_params),
+			buf + 3 * sizeof(u32), payload_size)) {
+		pr_err("%s: Could not copy payload from user buffer\n",
+			__func__);
+		goto err;
+	}
+
+	/* Pack header */
+	adm_params.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+		APR_HDR_LEN(20), APR_PKT_VER);
+	adm_params.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+		payload_size);
+	adm_params.src_svc = APR_SVC_ADM;
+	adm_params.src_domain = APR_DOMAIN_APPS;
+	adm_params.src_port = copp_id;
+	adm_params.dest_svc = APR_SVC_ADM;
+	adm_params.dest_domain = APR_DOMAIN_ADSP;
+	adm_params.dest_port = copp_id;
+	adm_params.token = copp_id;
+	adm_params.opcode = opcode;
+
+	memcpy(rtac_adm_buffer, &adm_params, sizeof(adm_params));
+	atomic_set(&rtac_adm_apr_data.cmd_state, 1);
+
+	pr_debug("%s: Sending RTAC command size = %d\n",
+		__func__, adm_params.pkt_size);
+
+	result = apr_send_pkt(rtac_adm_apr_data.apr_handle,
+		(uint32_t *)rtac_adm_buffer);
+	if (result < 0) {
+		pr_err("%s: Set params failed port = %d, copp = %d\n",
+			__func__, port_index, copp_id);
+		goto err;
+	}
+	/* Wait for the callback */
+	result = wait_event_timeout(rtac_adm_apr_data.cmd_wait,
+		(atomic_read(&rtac_adm_apr_data.cmd_state) == 0),
+		msecs_to_jiffies(TIMEOUT_MS));
+	mutex_unlock(&rtac_adm_apr_mutex);
+	if (!result) {
+		pr_err("%s: Set params timed out port = %d, copp = %d\n",
+			__func__, port_index, copp_id);
+		goto done;
+	}
+
+	if (rtac_adm_payload_size != 0) {
+		if (copy_to_user(buf, rtac_adm_buffer,
+			rtac_adm_payload_size + sizeof(u32))) {
+			pr_err("%s: Could not copy buffer to user,size = %d\n",
+				__func__, payload_size);
+			goto done;
+		}
+	}
+
+	/* Return data written for SET & data read for GET */
+	if (opcode == ADM_CMD_GET_PP_PARAMS_V5)
+		bytes_returned = rtac_adm_payload_size;
+	else
+		bytes_returned = payload_size;
+done:
+	return bytes_returned;
+err:
+	mutex_unlock(&rtac_adm_apr_mutex);
+	return bytes_returned;
+}
+
+
+/* ASM APR */
+void rtac_set_asm_handle(u32 session_id, void *handle)
+{
+	pr_debug("%s\n", __func__);
+
+	mutex_lock(&rtac_asm_apr_mutex);
+	rtac_asm_apr_data[session_id].apr_handle = handle;
+	mutex_unlock(&rtac_asm_apr_mutex);
+}
+
+bool rtac_make_asm_callback(u32 session_id, uint32_t *payload,
+	u32 payload_size)
+{
+	if (atomic_read(&rtac_asm_apr_data[session_id].cmd_state) != 1)
+		return false;
+
+	pr_debug("%s\n", __func__);
+	/* Offset data for in-band payload */
+	rtac_copy_asm_payload_to_user(payload, payload_size);
+	atomic_set(&rtac_asm_apr_data[session_id].cmd_state, 0);
+	wake_up(&rtac_asm_apr_data[session_id].cmd_wait);
+	return true;
+}
+
+void rtac_copy_asm_payload_to_user(void *payload, u32 payload_size)
+{
+	pr_debug("%s\n", __func__);
+	rtac_asm_payload_size = payload_size;
+
+	memcpy(rtac_asm_buffer, &payload_size, sizeof(u32));
+	if (payload_size) {
+		if (payload_size > rtac_asm_user_buf_size) {
+			pr_err("%s: Buffer set not big enough for returned data, buf size = %d, ret data = %d\n",
+			 __func__, rtac_asm_user_buf_size, payload_size);
+			rtac_asm_payload_size = 0;
+			goto done;
+		}
+		memcpy(rtac_asm_buffer + sizeof(u32), payload, payload_size);
+	}
+done:
+	return;
+}
+
+u32 send_rtac_asm_apr(void *buf, u32 opcode)
+{
+	s32	result;
+	u32	count = 0;
+	u32	bytes_returned = 0;
+	u32	session_id = 0;
+	u32	payload_size;
+	struct apr_hdr		asm_params;
+	pr_debug("%s\n", __func__);
+
+	if (copy_from_user(&count, (void *)buf, sizeof(count))) {
+		pr_err("%s: Copy to user failed! buf = 0x%x\n",
+		       __func__, (unsigned int)buf);
+		result = -EFAULT;
+		goto done;
+	}
+
+	if (count <= 0) {
+		pr_err("%s: Invalid buffer size = %d\n", __func__, count);
+		goto done;
+	}
+
+	if (copy_from_user(&payload_size, buf + sizeof(u32), sizeof(u32))) {
+		pr_err("%s: Could not copy payload size from user buffer\n",
+			__func__);
+		goto done;
+	}
+
+	if (payload_size > MAX_PAYLOAD_SIZE) {
+		pr_err("%s: Invalid payload size = %d\n",
+			__func__, payload_size);
+		goto done;
+	}
+
+	if (copy_from_user(&session_id, buf + 2 * sizeof(u32), sizeof(u32))) {
+		pr_err("%s: Could not copy session id from user buffer\n",
+			__func__);
+		goto done;
+	}
+
+	if (session_id > (SESSION_MAX + 1)) {
+		pr_err("%s: Invalid Session = %d\n", __func__, session_id);
+		goto done;
+	}
+
+	mutex_lock(&rtac_asm_apr_mutex);
+	if (session_id < SESSION_MAX+1) {
+		if (rtac_asm_apr_data[session_id].apr_handle == NULL) {
+			pr_err("%s: APR not initialized\n", __func__);
+			goto err;
+		}
+	}
+
+	/* Set globals for copy of returned payload */
+	rtac_asm_user_buf_size = count;
+
+	/* Copy buffer to in-band payload */
+	if (copy_from_user(rtac_asm_buffer + sizeof(asm_params),
+			buf + 3 * sizeof(u32), payload_size)) {
+		pr_err("%s: Could not copy payload from user buffer\n",
+			__func__);
+		goto err;
+	}
+
+	/* Pack header */
+	asm_params.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+		APR_HDR_LEN(20), APR_PKT_VER);
+	asm_params.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+		payload_size);
+	asm_params.src_svc = q6asm_get_apr_service_id(session_id);
+	asm_params.src_domain = APR_DOMAIN_APPS;
+	asm_params.src_port = (session_id << 8) | 0x0001;
+	asm_params.dest_svc = APR_SVC_ASM;
+	asm_params.dest_domain = APR_DOMAIN_ADSP;
+	asm_params.dest_port = (session_id << 8) | 0x0001;
+	asm_params.token = session_id;
+	asm_params.opcode = opcode;
+
+	memcpy(rtac_asm_buffer, &asm_params, sizeof(asm_params));
+	if (session_id < SESSION_MAX+1)
+		atomic_set(&rtac_asm_apr_data[session_id].cmd_state, 1);
+
+	pr_debug("%s: Sending RTAC command size = %d, session_id=%d\n",
+		__func__, asm_params.pkt_size, session_id);
+
+	result = apr_send_pkt(rtac_asm_apr_data[session_id].apr_handle,
+				(uint32_t *)rtac_asm_buffer);
+	if (result < 0) {
+		pr_err("%s: Set params failed session = %d\n",
+			__func__, session_id);
+		goto err;
+	}
+
+	/* Wait for the callback */
+	result = wait_event_timeout(rtac_asm_apr_data[session_id].cmd_wait,
+		(atomic_read(&rtac_asm_apr_data[session_id].cmd_state) == 0),
+		5 * HZ);
+	mutex_unlock(&rtac_asm_apr_mutex);
+	if (!result) {
+		pr_err("%s: Set params timed out session = %d\n",
+			__func__, session_id);
+		goto done;
+	}
+
+	if (rtac_asm_payload_size != 0) {
+		if (copy_to_user(buf, rtac_asm_buffer,
+			rtac_asm_payload_size + sizeof(u32))) {
+			pr_err("%s: Could not copy buffer to user,size = %d\n",
+				 __func__, payload_size);
+			goto done;
+		}
+	}
+
+	/* Return data written for SET & data read for GET */
+	if (opcode == ASM_STREAM_CMD_GET_PP_PARAMS_V2)
+		bytes_returned = rtac_asm_payload_size;
+	else
+		bytes_returned = payload_size;
+done:
+	return bytes_returned;
+err:
+	mutex_unlock(&rtac_asm_apr_mutex);
+	return bytes_returned;
+}
+
+
+/* Voice APR */
+void rtac_set_voice_handle(u32 mode, void *handle)
+{
+	pr_debug("%s\n", __func__);
+
+	mutex_lock(&rtac_voice_apr_mutex);
+	rtac_voice_apr_data[mode].apr_handle = handle;
+	mutex_unlock(&rtac_voice_apr_mutex);
+}
+
+bool rtac_make_voice_callback(u32 mode, uint32_t *payload, u32 payload_size)
+{
+	if ((atomic_read(&rtac_voice_apr_data[mode].cmd_state) != 1) ||
+		(mode >= RTAC_VOICE_MODES))
+		return false;
+
+	pr_debug("%s\n", __func__);
+	/* Offset data for in-band payload */
+	rtac_copy_voice_payload_to_user(payload, payload_size);
+	atomic_set(&rtac_voice_apr_data[mode].cmd_state, 0);
+	wake_up(&rtac_voice_apr_data[mode].cmd_wait);
+	return true;
+}
+
+void rtac_copy_voice_payload_to_user(void *payload, u32 payload_size)
+{
+	pr_debug("%s\n", __func__);
+	rtac_voice_payload_size = payload_size;
+
+	memcpy(rtac_voice_buffer, &payload_size, sizeof(u32));
+	if (payload_size) {
+		if (payload_size > rtac_voice_user_buf_size) {
+			pr_err("%s: Buffer set not big enough for returned data, buf size = %d, ret data = %d\n",
+			 __func__, rtac_voice_user_buf_size, payload_size);
+			rtac_voice_payload_size = 0;
+			goto done;
+		}
+		memcpy(rtac_voice_buffer + sizeof(u32), payload, payload_size);
+	}
+done:
+	return;
+}
+
+u32 send_voice_apr(u32 mode, void *buf, u32 opcode)
+{
+	s32	result;
+	u32	count = 0;
+	u32	bytes_returned = 0;
+	u32	payload_size;
+	u32	dest_port;
+	struct apr_hdr		voice_params;
+	pr_debug("%s\n", __func__);
+
+	if (copy_from_user(&count, (void *)buf, sizeof(count))) {
+		pr_err("%s: Copy to user failed! buf = 0x%x\n",
+		       __func__, (unsigned int)buf);
+		result = -EFAULT;
+		goto done;
+	}
+
+	if (count <= 0) {
+		pr_err("%s: Invalid buffer size = %d\n", __func__, count);
+		goto done;
+	}
+
+	if (copy_from_user(&payload_size, buf + sizeof(u32), sizeof(u32))) {
+		pr_err("%s: Could not copy payload size from user buffer\n",
+			__func__);
+		goto done;
+	}
+
+	if (payload_size > MAX_PAYLOAD_SIZE) {
+		pr_err("%s: Invalid payload size = %d\n",
+				__func__, payload_size);
+		goto done;
+	}
+
+	if (copy_from_user(&dest_port, buf + 2 * sizeof(u32), sizeof(u32))) {
+		pr_err("%s: Could not copy port id from user buffer\n",
+			__func__);
+		goto done;
+	}
+
+	if ((mode != RTAC_CVP) && (mode != RTAC_CVS)) {
+		pr_err("%s: Invalid Mode for APR, mode = %d\n",
+			__func__, mode);
+		goto done;
+	}
+
+	mutex_lock(&rtac_voice_apr_mutex);
+	if (rtac_voice_apr_data[mode].apr_handle == NULL) {
+		pr_err("%s: APR not initialized\n", __func__);
+		goto err;
+	}
+
+	/* Set globals for copy of returned payload */
+	rtac_voice_user_buf_size = count;
+
+	/* Copy buffer to in-band payload */
+	if (copy_from_user(rtac_voice_buffer + sizeof(voice_params),
+			buf + 3 * sizeof(u32), payload_size)) {
+		pr_err("%s: Could not copy payload from user buffer\n",
+			__func__);
+		goto err;
+	}
+
+	/* Pack header */
+	voice_params.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+		APR_HDR_LEN(20), APR_PKT_VER);
+	voice_params.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+		payload_size);
+	voice_params.src_svc = 0;
+	voice_params.src_domain = APR_DOMAIN_APPS;
+	voice_params.src_port = voice_session_id[
+					get_voice_index(mode, dest_port)];
+	voice_params.dest_svc = 0;
+	voice_params.dest_domain = APR_DOMAIN_MODEM;
+	voice_params.dest_port = (u16)dest_port;
+	voice_params.token = 0;
+	voice_params.opcode = opcode;
+
+	memcpy(rtac_voice_buffer, &voice_params, sizeof(voice_params));
+	atomic_set(&rtac_voice_apr_data[mode].cmd_state, 1);
+
+	pr_debug("%s: Sending RTAC command size = %d, opcode = %x\n",
+		__func__, voice_params.pkt_size, opcode);
+
+	result = apr_send_pkt(rtac_voice_apr_data[mode].apr_handle,
+					(uint32_t *)rtac_voice_buffer);
+	if (result < 0) {
+		pr_err("%s: apr_send_pkt failed opcode = %x\n",
+			__func__, opcode);
+		goto err;
+	}
+	/* Wait for the callback */
+	result = wait_event_timeout(rtac_voice_apr_data[mode].cmd_wait,
+		(atomic_read(&rtac_voice_apr_data[mode].cmd_state) == 0),
+		msecs_to_jiffies(TIMEOUT_MS));
+	mutex_unlock(&rtac_voice_apr_mutex);
+	if (!result) {
+		pr_err("%s: apr_send_pkt timed out opcode = %x\n",
+			__func__, opcode);
+		goto done;
+	}
+
+	if (rtac_voice_payload_size != 0) {
+		if (copy_to_user(buf, rtac_voice_buffer,
+			rtac_voice_payload_size + sizeof(u32))) {
+			pr_err("%s: Could not copy buffer to user, size = %d\n",
+				 __func__, payload_size);
+			goto done;
+		}
+	}
+
+	/* Return data written for SET & data read for GET */
+	if (opcode == VOICE_CMD_GET_PARAM)
+		bytes_returned = rtac_voice_payload_size;
+	else
+		bytes_returned = payload_size;
+done:
+	return bytes_returned;
+err:
+	mutex_unlock(&rtac_voice_apr_mutex);
+	return bytes_returned;
+}
+
+
+
+static long rtac_ioctl(struct file *f,
+		unsigned int cmd, unsigned long arg)
+{
+	s32 result = 0;
+	pr_debug("%s\n", __func__);
+
+	if (arg == 0) {
+		pr_err("%s: No data sent to driver!\n", __func__);
+		result = -EFAULT;
+		goto done;
+	}
+
+	switch (cmd) {
+	case AUDIO_GET_RTAC_ADM_INFO:
+		if (copy_to_user((void *)arg, &rtac_adm_data,
+						sizeof(rtac_adm_data)))
+			pr_err("%s: Could not copy to userspace!\n", __func__);
+		else
+			result = sizeof(rtac_adm_data);
+		break;
+	case AUDIO_GET_RTAC_VOICE_INFO:
+		if (copy_to_user((void *)arg, &rtac_voice_data,
+						sizeof(rtac_voice_data)))
+			pr_err("%s: Could not copy to userspace!\n", __func__);
+		else
+			result = sizeof(rtac_voice_data);
+		break;
+	case AUDIO_GET_RTAC_ADM_CAL:
+		result = send_adm_apr((void *)arg, ADM_CMD_GET_PP_PARAMS_V5);
+		break;
+	case AUDIO_SET_RTAC_ADM_CAL:
+		result = send_adm_apr((void *)arg, ADM_CMD_SET_PP_PARAMS_V5);
+		break;
+	case AUDIO_GET_RTAC_ASM_CAL:
+		result = send_rtac_asm_apr((void *)arg,
+			ASM_STREAM_CMD_GET_PP_PARAMS_V2);
+		break;
+	case AUDIO_SET_RTAC_ASM_CAL:
+		result = send_rtac_asm_apr((void *)arg,
+			ASM_STREAM_CMD_SET_PP_PARAMS_V2);
+		break;
+	case AUDIO_GET_RTAC_CVS_CAL:
+		result = send_voice_apr(RTAC_CVS, (void *)arg,
+			VOICE_CMD_GET_PARAM);
+		break;
+	case AUDIO_SET_RTAC_CVS_CAL:
+		result = send_voice_apr(RTAC_CVS, (void *)arg,
+			VOICE_CMD_SET_PARAM);
+		break;
+	case AUDIO_GET_RTAC_CVP_CAL:
+		result = send_voice_apr(RTAC_CVP, (void *)arg,
+			VOICE_CMD_GET_PARAM);
+		break;
+	case AUDIO_SET_RTAC_CVP_CAL:
+		result = send_voice_apr(RTAC_CVP, (void *)arg,
+			VOICE_CMD_SET_PARAM);
+		break;
+	default:
+		pr_err("%s: Invalid IOCTL, command = %d!\n",
+		       __func__, cmd);
+	}
+done:
+	return result;
+}
+
+
+static const struct file_operations rtac_fops = {
+	.owner = THIS_MODULE,
+	.open = rtac_open,
+	.release = rtac_release,
+	.unlocked_ioctl = rtac_ioctl,
+};
+
+struct miscdevice rtac_misc = {
+	.minor	= MISC_DYNAMIC_MINOR,
+	.name	= "msm_rtac",
+	.fops	= &rtac_fops,
+};
+
+static int __init rtac_init(void)
+{
+	int i = 0;
+	pr_debug("%s\n", __func__);
+
+	/* ADM */
+	memset(&rtac_adm_data, 0, sizeof(rtac_adm_data));
+	rtac_adm_apr_data.apr_handle = NULL;
+	atomic_set(&rtac_adm_apr_data.cmd_state, 0);
+	init_waitqueue_head(&rtac_adm_apr_data.cmd_wait);
+	mutex_init(&rtac_adm_mutex);
+	mutex_init(&rtac_adm_apr_mutex);
+
+	rtac_adm_buffer = kzalloc(RTAC_BUF_SIZE, GFP_KERNEL);
+	if (rtac_adm_buffer == NULL) {
+		pr_err("%s: Could not allocate payload of size = %d\n",
+			__func__, RTAC_BUF_SIZE);
+		goto nomem;
+	}
+
+	/* ASM */
+	for (i = 0; i < SESSION_MAX+1; i++) {
+		rtac_asm_apr_data[i].apr_handle = NULL;
+		atomic_set(&rtac_asm_apr_data[i].cmd_state, 0);
+		init_waitqueue_head(&rtac_asm_apr_data[i].cmd_wait);
+	}
+	mutex_init(&rtac_asm_apr_mutex);
+
+	rtac_asm_buffer = kzalloc(RTAC_BUF_SIZE, GFP_KERNEL);
+	if (rtac_asm_buffer == NULL) {
+		pr_err("%s: Could not allocate payload of size = %d\n",
+			__func__, RTAC_BUF_SIZE);
+		kzfree(rtac_adm_buffer);
+		goto nomem;
+	}
+
+	/* Voice */
+	memset(&rtac_voice_data, 0, sizeof(rtac_voice_data));
+	for (i = 0; i < RTAC_VOICE_MODES; i++) {
+		rtac_voice_apr_data[i].apr_handle = NULL;
+		atomic_set(&rtac_voice_apr_data[i].cmd_state, 0);
+		init_waitqueue_head(&rtac_voice_apr_data[i].cmd_wait);
+	}
+	mutex_init(&rtac_voice_mutex);
+	mutex_init(&rtac_voice_apr_mutex);
+
+	rtac_voice_buffer = kzalloc(RTAC_BUF_SIZE, GFP_KERNEL);
+	if (rtac_voice_buffer == NULL) {
+		pr_err("%s: Could not allocate payload of size = %d\n",
+			__func__, RTAC_BUF_SIZE);
+		kzfree(rtac_adm_buffer);
+		kzfree(rtac_asm_buffer);
+		goto nomem;
+	}
+
+	return misc_register(&rtac_misc);
+nomem:
+	return -ENOMEM;
+}
+
+module_init(rtac_init);
+
+MODULE_DESCRIPTION("SoC QDSP6v2 Real-Time Audio Calibration driver");
+MODULE_LICENSE("GPL v2");
+
+#endif
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 5ac643416..99047178 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -78,7 +78,7 @@
 	[snd_soc_dapm_pre] = 0,
 	[snd_soc_dapm_aif_in] = 1,
 	[snd_soc_dapm_aif_out] = 1,
-	[snd_soc_dapm_adc] = 1,
+	[snd_soc_dapm_adc] = 5,
 	[snd_soc_dapm_hp] = 2,
 	[snd_soc_dapm_spk] = 2,
 	[snd_soc_dapm_out_drv] = 2,
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 1452312..f453dbd 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -265,7 +265,7 @@
 		break;
 	}
 	}
-
+	switch_set_state(usbaudiosdev, 1);
 	return 0;
 }
 
@@ -421,7 +421,6 @@
 	}
 
 	snd_usb_audio_create_proc(chip);
-	switch_set_state(usbaudiosdev, 1);
 
 	*rchip = chip;
 	return 0;
@@ -723,7 +722,7 @@
 		return -EINVAL;
 	}
 
-	usbaudiosdev = kzalloc(sizeof(usbaudiosdev), GFP_KERNEL);
+	usbaudiosdev = kzalloc(sizeof(*usbaudiosdev), GFP_KERNEL);
 	usbaudiosdev->name = "usb_audio";
 
 	err = switch_dev_register(usbaudiosdev);
diff --git a/tools/perf/builtin-periodic.c b/tools/perf/builtin-periodic.c
index a0785c2..ce9837d 100644
--- a/tools/perf/builtin-periodic.c
+++ b/tools/perf/builtin-periodic.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
diff --git a/tools/perf/util/scripting-engines/trace-event-json-export.c b/tools/perf/util/scripting-engines/trace-event-json-export.c
index 2aec459..b2cf9c2 100644
--- a/tools/perf/util/scripting-engines/trace-event-json-export.c
+++ b/tools/perf/util/scripting-engines/trace-event-json-export.c
@@ -3,7 +3,7 @@
  *
  * derived from: trace-event-python.c
  *
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  * Copyright (C) 2010 Tom Zanussi <tzanussi@gmail.com>
  *
  *  This program is free software; you can redistribute it and/or modify